summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMyungJoo Ham <myungjoo.ham@samsung.com>2017-09-22 10:16:08 +0900
committerMyungJoo Ham <myungjoo.ham@samsung.com>2017-09-22 10:16:08 +0900
commit4cf5243b6381475333152d3f04855526a3e68686 (patch)
tree9367a53521bf79220701ab5ee84b8227452d6270
parent8f57854a0c003ff2d4c278b47d13f8ef6feb6bbc (diff)
parente7561cf69230b39af2296ba285f4489fd1f7917b (diff)
downloadcmake-4cf5243b6381475333152d3f04855526a3e68686.tar.gz
cmake-4cf5243b6381475333152d3f04855526a3e68686.tar.bz2
cmake-4cf5243b6381475333152d3f04855526a3e68686.zip
Merge branch 'upstream' into tizen (to 3.5.1)
Upgrade CMake to Version 3.5.1
-rw-r--r--.gitattributes2
-rw-r--r--Auxiliary/CMakeLists.txt4
-rw-r--r--Auxiliary/bash-completion/CMakeLists.txt (renamed from Docs/bash-completion/CMakeLists.txt)0
-rw-r--r--Auxiliary/bash-completion/cmake158
-rw-r--r--Auxiliary/bash-completion/cpack68
-rw-r--r--Auxiliary/bash-completion/ctest92
-rw-r--r--Auxiliary/cmake-help.vim (renamed from Docs/cmake-help.vim)0
-rw-r--r--Auxiliary/cmake-indent.vim93
-rw-r--r--Auxiliary/cmake-mode.el398
-rw-r--r--Auxiliary/cmake-syntax.vim89
-rw-r--r--Auxiliary/cmake.m4 (renamed from Utilities/cmake.m4)0
-rw-r--r--CMakeCPack.cmake116
-rw-r--r--CMakeCPackOptions.cmake.in247
-rw-r--r--CMakeLists.txt568
-rw-r--r--CONTRIBUTING.rst34
-rw-r--r--CTestConfig.cmake9
-rw-r--r--CTestCustom.cmake.in53
-rw-r--r--CTestCustom.ctest.in3
-rw-r--r--ChangeLog.manual5301
-rw-r--r--ChangeLog.txt86670
-rw-r--r--CompileFlags.cmake48
-rw-r--r--Copyright.txt3
-rw-r--r--DartConfig.cmake4
-rw-r--r--DartLocal.conf.in121
-rw-r--r--Docs/CMakeLists.txt3
-rw-r--r--Docs/bash-completion/cmake151
-rw-r--r--Docs/bash-completion/cpack61
-rw-r--r--Docs/bash-completion/ctest81
-rw-r--r--Docs/cmake-indent.vim93
-rw-r--r--Docs/cmake-mode.el357
-rw-r--r--Docs/cmake-syntax.vim89
-rw-r--r--Example/CMakeLists.txt10
-rw-r--r--Example/Demo/CMakeLists.txt12
-rw-r--r--Example/Demo/demo.cxx10
-rw-r--r--Example/Demo/demo_b.cxx3
-rw-r--r--Example/Hello/CMakeLists.txt3
-rw-r--r--Example/Hello/hello.cxx7
-rw-r--r--Example/Hello/hello.h11
-rw-r--r--Help/command/FIND_XXX.txt119
-rw-r--r--Help/command/FIND_XXX_ORDER.txt12
-rw-r--r--Help/command/FIND_XXX_ROOT.txt29
-rw-r--r--Help/command/add_compile_options.rst23
-rw-r--r--Help/command/add_custom_command.rst208
-rw-r--r--Help/command/add_custom_target.rst111
-rw-r--r--Help/command/add_definitions.rst27
-rw-r--r--Help/command/add_dependencies.rst23
-rw-r--r--Help/command/add_executable.rst80
-rw-r--r--Help/command/add_library.rst162
-rw-r--r--Help/command/add_subdirectory.rst36
-rw-r--r--Help/command/add_test.rst66
-rw-r--r--Help/command/aux_source_directory.rst24
-rw-r--r--Help/command/break.rst12
-rw-r--r--Help/command/build_command.rst45
-rw-r--r--Help/command/build_name.rst15
-rw-r--r--Help/command/cmake_host_system_information.rst25
-rw-r--r--Help/command/cmake_minimum_required.rst41
-rw-r--r--Help/command/cmake_parse_arguments.rst85
-rw-r--r--Help/command/cmake_policy.rst96
-rw-r--r--Help/command/configure_file.rst111
-rw-r--r--Help/command/continue.rst12
-rw-r--r--Help/command/create_test_sourcelist.rst30
-rw-r--r--Help/command/ctest_build.rst73
-rw-r--r--Help/command/ctest_configure.rst39
-rw-r--r--Help/command/ctest_coverage.rst39
-rw-r--r--Help/command/ctest_empty_binary_directory.rst12
-rw-r--r--Help/command/ctest_memcheck.rst29
-rw-r--r--Help/command/ctest_read_custom_files.rst14
-rw-r--r--Help/command/ctest_run_script.rst15
-rw-r--r--Help/command/ctest_sleep.rst16
-rw-r--r--Help/command/ctest_start.rst25
-rw-r--r--Help/command/ctest_submit.rst65
-rw-r--r--Help/command/ctest_test.rst90
-rw-r--r--Help/command/ctest_update.rst27
-rw-r--r--Help/command/ctest_upload.rst18
-rw-r--r--Help/command/define_property.rst45
-rw-r--r--Help/command/else.rst10
-rw-r--r--Help/command/elseif.rst10
-rw-r--r--Help/command/enable_language.rst22
-rw-r--r--Help/command/enable_testing.rst13
-rw-r--r--Help/command/endforeach.rst10
-rw-r--r--Help/command/endfunction.rst10
-rw-r--r--Help/command/endif.rst10
-rw-r--r--Help/command/endmacro.rst10
-rw-r--r--Help/command/endwhile.rst10
-rw-r--r--Help/command/exec_program.rst24
-rw-r--r--Help/command/execute_process.rst76
-rw-r--r--Help/command/export.rst57
-rw-r--r--Help/command/export_library_dependencies.rst28
-rw-r--r--Help/command/file.rst358
-rw-r--r--Help/command/find_file.rst33
-rw-r--r--Help/command/find_library.rst56
-rw-r--r--Help/command/find_package.rst344
-rw-r--r--Help/command/find_path.rst38
-rw-r--r--Help/command/find_program.rst33
-rw-r--r--Help/command/fltk_wrap_ui.rst14
-rw-r--r--Help/command/foreach.rst47
-rw-r--r--Help/command/function.rst36
-rw-r--r--Help/command/get_cmake_property.rst15
-rw-r--r--Help/command/get_directory_property.rst24
-rw-r--r--Help/command/get_filename_component.rst64
-rw-r--r--Help/command/get_property.rst61
-rw-r--r--Help/command/get_source_file_property.rst16
-rw-r--r--Help/command/get_target_property.rst18
-rw-r--r--Help/command/get_test_property.rst15
-rw-r--r--Help/command/if.rst216
-rw-r--r--Help/command/include.rst25
-rw-r--r--Help/command/include_directories.rst35
-rw-r--r--Help/command/include_external_msproject.rst23
-rw-r--r--Help/command/include_regular_expression.rst18
-rw-r--r--Help/command/install.rst360
-rw-r--r--Help/command/install_files.rst39
-rw-r--r--Help/command/install_programs.rst34
-rw-r--r--Help/command/install_targets.rst17
-rw-r--r--Help/command/link_directories.rst19
-rw-r--r--Help/command/link_libraries.rst19
-rw-r--r--Help/command/list.rst61
-rw-r--r--Help/command/load_cache.rst27
-rw-r--r--Help/command/load_command.rst23
-rw-r--r--Help/command/macro.rst76
-rw-r--r--Help/command/make_directory.rst12
-rw-r--r--Help/command/mark_as_advanced.rst19
-rw-r--r--Help/command/math.rst13
-rw-r--r--Help/command/message.rst33
-rw-r--r--Help/command/option.rst15
-rw-r--r--Help/command/output_required_files.rst19
-rw-r--r--Help/command/project.rst64
-rw-r--r--Help/command/qt_wrap_cpp.rst12
-rw-r--r--Help/command/qt_wrap_ui.rst14
-rw-r--r--Help/command/remove.rst12
-rw-r--r--Help/command/remove_definitions.rst11
-rw-r--r--Help/command/return.rst18
-rw-r--r--Help/command/separate_arguments.rst31
-rw-r--r--Help/command/set.rst89
-rw-r--r--Help/command/set_directory_properties.rst12
-rw-r--r--Help/command/set_property.rst69
-rw-r--r--Help/command/set_source_files_properties.rst15
-rw-r--r--Help/command/set_target_properties.rst18
-rw-r--r--Help/command/set_tests_properties.rst14
-rw-r--r--Help/command/site_name.rst8
-rw-r--r--Help/command/source_group.rst44
-rw-r--r--Help/command/string.rst320
-rw-r--r--Help/command/subdir_depends.rst13
-rw-r--r--Help/command/subdirs.rst24
-rw-r--r--Help/command/target_compile_definitions.rst28
-rw-r--r--Help/command/target_compile_features.rst32
-rw-r--r--Help/command/target_compile_options.rst37
-rw-r--r--Help/command/target_include_directories.rst62
-rw-r--r--Help/command/target_link_libraries.rst204
-rw-r--r--Help/command/target_sources.rst28
-rw-r--r--Help/command/try_compile.rst114
-rw-r--r--Help/command/try_run.rst98
-rw-r--r--Help/command/unset.rst25
-rw-r--r--Help/command/use_mangled_mesa.rst15
-rw-r--r--Help/command/utility_source.rst24
-rw-r--r--Help/command/variable_requires.rst22
-rw-r--r--Help/command/variable_watch.rst13
-rw-r--r--Help/command/while.rst17
-rw-r--r--Help/command/write_file.rst20
-rw-r--r--Help/generator/Borland Makefiles.rst4
-rw-r--r--Help/generator/CodeBlocks.rst25
-rw-r--r--Help/generator/CodeLite.rst24
-rw-r--r--Help/generator/Eclipse CDT4.rst25
-rw-r--r--Help/generator/Green Hills MULTI.rst16
-rw-r--r--Help/generator/KDevelop3.rst25
-rw-r--r--Help/generator/Kate.rst26
-rw-r--r--Help/generator/MSYS Makefiles.rst11
-rw-r--r--Help/generator/MinGW Makefiles.rst12
-rw-r--r--Help/generator/NMake Makefiles JOM.rst4
-rw-r--r--Help/generator/NMake Makefiles.rst4
-rw-r--r--Help/generator/Ninja.rst8
-rw-r--r--Help/generator/Sublime Text 2.rst25
-rw-r--r--Help/generator/Unix Makefiles.rst8
-rw-r--r--Help/generator/Visual Studio 10 2010.rst19
-rw-r--r--Help/generator/Visual Studio 11 2012.rst22
-rw-r--r--Help/generator/Visual Studio 12 2013.rst19
-rw-r--r--Help/generator/Visual Studio 14 2015.rst16
-rw-r--r--Help/generator/Visual Studio 6.rst10
-rw-r--r--Help/generator/Visual Studio 7 .NET 2003.rst4
-rw-r--r--Help/generator/Visual Studio 7.rst10
-rw-r--r--Help/generator/Visual Studio 8 2005.rst16
-rw-r--r--Help/generator/Visual Studio 9 2008.rst19
-rw-r--r--Help/generator/Watcom WMake.rst4
-rw-r--r--Help/generator/Xcode.rst4
-rw-r--r--Help/include/COMPILE_DEFINITIONS_DISCLAIMER.txt18
-rw-r--r--Help/include/INTERFACE_INCLUDE_DIRECTORIES_WARNING.txt18
-rw-r--r--Help/include/INTERFACE_LINK_LIBRARIES_WARNING.txt10
-rw-r--r--Help/index.rst59
-rw-r--r--Help/manual/LINKS.txt25
-rw-r--r--Help/manual/OPTIONS_BUILD.txt123
-rw-r--r--Help/manual/OPTIONS_HELP.txt136
-rw-r--r--Help/manual/ccmake.1.rst37
-rw-r--r--Help/manual/cmake-buildsystem.7.rst989
-rw-r--r--Help/manual/cmake-commands.7.rst155
-rw-r--r--Help/manual/cmake-compile-features.7.rst311
-rw-r--r--Help/manual/cmake-developer.7.rst1007
-rw-r--r--Help/manual/cmake-generator-expressions.7.rst284
-rw-r--r--Help/manual/cmake-generators.7.rst112
-rw-r--r--Help/manual/cmake-gui.1.rst35
-rw-r--r--Help/manual/cmake-language.7.rst572
-rw-r--r--Help/manual/cmake-modules.7.rst245
-rw-r--r--Help/manual/cmake-packages.7.rst709
-rw-r--r--Help/manual/cmake-policies.7.rst125
-rw-r--r--Help/manual/cmake-properties.7.rst401
-rw-r--r--Help/manual/cmake-qt.7.rst187
-rw-r--r--Help/manual/cmake-toolchains.7.rst324
-rw-r--r--Help/manual/cmake-variables.7.rst450
-rw-r--r--Help/manual/cmake.1.rst280
-rw-r--r--Help/manual/cpack.1.rst97
-rw-r--r--Help/manual/ctest.1.rst1023
-rw-r--r--Help/module/AddFileDependencies.rst1
-rw-r--r--Help/module/BundleUtilities.rst1
-rw-r--r--Help/module/CMakeAddFortranSubdirectory.rst1
-rw-r--r--Help/module/CMakeBackwardCompatibilityCXX.rst1
-rw-r--r--Help/module/CMakeDependentOption.rst1
-rw-r--r--Help/module/CMakeDetermineVSServicePack.rst1
-rw-r--r--Help/module/CMakeExpandImportedTargets.rst1
-rw-r--r--Help/module/CMakeFindDependencyMacro.rst1
-rw-r--r--Help/module/CMakeFindFrameworks.rst1
-rw-r--r--Help/module/CMakeFindPackageMode.rst1
-rw-r--r--Help/module/CMakeForceCompiler.rst1
-rw-r--r--Help/module/CMakeGraphVizOptions.rst1
-rw-r--r--Help/module/CMakePackageConfigHelpers.rst1
-rw-r--r--Help/module/CMakeParseArguments.rst1
-rw-r--r--Help/module/CMakePrintHelpers.rst1
-rw-r--r--Help/module/CMakePrintSystemInformation.rst1
-rw-r--r--Help/module/CMakePushCheckState.rst1
-rw-r--r--Help/module/CMakeVerifyManifest.rst1
-rw-r--r--Help/module/CPack.rst1
-rw-r--r--Help/module/CPackBundle.rst1
-rw-r--r--Help/module/CPackComponent.rst1
-rw-r--r--Help/module/CPackCygwin.rst1
-rw-r--r--Help/module/CPackDMG.rst1
-rw-r--r--Help/module/CPackDeb.rst1
-rw-r--r--Help/module/CPackIFW.rst1
-rw-r--r--Help/module/CPackNSIS.rst1
-rw-r--r--Help/module/CPackPackageMaker.rst1
-rw-r--r--Help/module/CPackRPM.rst1
-rw-r--r--Help/module/CPackWIX.rst1
-rw-r--r--Help/module/CTest.rst1
-rw-r--r--Help/module/CTestCoverageCollectGCOV.rst1
-rw-r--r--Help/module/CTestScriptMode.rst1
-rw-r--r--Help/module/CTestUseLaunchers.rst1
-rw-r--r--Help/module/CheckCCompilerFlag.rst1
-rw-r--r--Help/module/CheckCSourceCompiles.rst1
-rw-r--r--Help/module/CheckCSourceRuns.rst1
-rw-r--r--Help/module/CheckCXXCompilerFlag.rst1
-rw-r--r--Help/module/CheckCXXSourceCompiles.rst1
-rw-r--r--Help/module/CheckCXXSourceRuns.rst1
-rw-r--r--Help/module/CheckCXXSymbolExists.rst1
-rw-r--r--Help/module/CheckFortranCompilerFlag.rst1
-rw-r--r--Help/module/CheckFortranFunctionExists.rst1
-rw-r--r--Help/module/CheckFortranSourceCompiles.rst1
-rw-r--r--Help/module/CheckFunctionExists.rst1
-rw-r--r--Help/module/CheckIncludeFile.rst1
-rw-r--r--Help/module/CheckIncludeFileCXX.rst1
-rw-r--r--Help/module/CheckIncludeFiles.rst1
-rw-r--r--Help/module/CheckLanguage.rst1
-rw-r--r--Help/module/CheckLibraryExists.rst1
-rw-r--r--Help/module/CheckPrototypeDefinition.rst1
-rw-r--r--Help/module/CheckStructHasMember.rst1
-rw-r--r--Help/module/CheckSymbolExists.rst1
-rw-r--r--Help/module/CheckTypeSize.rst1
-rw-r--r--Help/module/CheckVariableExists.rst1
-rw-r--r--Help/module/Dart.rst1
-rw-r--r--Help/module/DeployQt4.rst1
-rw-r--r--Help/module/Documentation.rst1
-rw-r--r--Help/module/ExternalData.rst1
-rw-r--r--Help/module/ExternalProject.rst1
-rw-r--r--Help/module/FeatureSummary.rst1
-rw-r--r--Help/module/FindALSA.rst1
-rw-r--r--Help/module/FindASPELL.rst1
-rw-r--r--Help/module/FindAVIFile.rst1
-rw-r--r--Help/module/FindArmadillo.rst1
-rw-r--r--Help/module/FindBISON.rst1
-rw-r--r--Help/module/FindBLAS.rst1
-rw-r--r--Help/module/FindBZip2.rst1
-rw-r--r--Help/module/FindBacktrace.rst1
-rw-r--r--Help/module/FindBoost.rst1
-rw-r--r--Help/module/FindBullet.rst1
-rw-r--r--Help/module/FindCABLE.rst1
-rw-r--r--Help/module/FindCUDA.rst1
-rw-r--r--Help/module/FindCURL.rst1
-rw-r--r--Help/module/FindCVS.rst1
-rw-r--r--Help/module/FindCoin3D.rst1
-rw-r--r--Help/module/FindCups.rst1
-rw-r--r--Help/module/FindCurses.rst1
-rw-r--r--Help/module/FindCxxTest.rst1
-rw-r--r--Help/module/FindCygwin.rst1
-rw-r--r--Help/module/FindDCMTK.rst1
-rw-r--r--Help/module/FindDart.rst1
-rw-r--r--Help/module/FindDevIL.rst1
-rw-r--r--Help/module/FindDoxygen.rst1
-rw-r--r--Help/module/FindEXPAT.rst1
-rw-r--r--Help/module/FindFLEX.rst1
-rw-r--r--Help/module/FindFLTK.rst1
-rw-r--r--Help/module/FindFLTK2.rst1
-rw-r--r--Help/module/FindFreetype.rst1
-rw-r--r--Help/module/FindGCCXML.rst1
-rw-r--r--Help/module/FindGDAL.rst1
-rw-r--r--Help/module/FindGIF.rst1
-rw-r--r--Help/module/FindGLEW.rst1
-rw-r--r--Help/module/FindGLUT.rst1
-rw-r--r--Help/module/FindGSL.rst1
-rw-r--r--Help/module/FindGTK.rst1
-rw-r--r--Help/module/FindGTK2.rst1
-rw-r--r--Help/module/FindGTest.rst1
-rw-r--r--Help/module/FindGettext.rst1
-rw-r--r--Help/module/FindGit.rst1
-rw-r--r--Help/module/FindGnuTLS.rst1
-rw-r--r--Help/module/FindGnuplot.rst1
-rw-r--r--Help/module/FindHDF5.rst1
-rw-r--r--Help/module/FindHSPELL.rst1
-rw-r--r--Help/module/FindHTMLHelp.rst1
-rw-r--r--Help/module/FindHg.rst1
-rw-r--r--Help/module/FindITK.rst10
-rw-r--r--Help/module/FindIce.rst1
-rw-r--r--Help/module/FindIcotool.rst1
-rw-r--r--Help/module/FindImageMagick.rst1
-rw-r--r--Help/module/FindIntl.rst1
-rw-r--r--Help/module/FindJNI.rst1
-rw-r--r--Help/module/FindJPEG.rst1
-rw-r--r--Help/module/FindJasper.rst1
-rw-r--r--Help/module/FindJava.rst1
-rw-r--r--Help/module/FindKDE3.rst1
-rw-r--r--Help/module/FindKDE4.rst1
-rw-r--r--Help/module/FindLAPACK.rst1
-rw-r--r--Help/module/FindLATEX.rst1
-rw-r--r--Help/module/FindLibArchive.rst1
-rw-r--r--Help/module/FindLibLZMA.rst1
-rw-r--r--Help/module/FindLibXml2.rst1
-rw-r--r--Help/module/FindLibXslt.rst1
-rw-r--r--Help/module/FindLua.rst1
-rw-r--r--Help/module/FindLua50.rst1
-rw-r--r--Help/module/FindLua51.rst1
-rw-r--r--Help/module/FindMFC.rst1
-rw-r--r--Help/module/FindMPEG.rst1
-rw-r--r--Help/module/FindMPEG2.rst1
-rw-r--r--Help/module/FindMPI.rst1
-rw-r--r--Help/module/FindMatlab.rst1
-rw-r--r--Help/module/FindMotif.rst1
-rw-r--r--Help/module/FindOpenAL.rst1
-rw-r--r--Help/module/FindOpenCL.rst1
-rw-r--r--Help/module/FindOpenGL.rst1
-rw-r--r--Help/module/FindOpenMP.rst1
-rw-r--r--Help/module/FindOpenSSL.rst1
-rw-r--r--Help/module/FindOpenSceneGraph.rst1
-rw-r--r--Help/module/FindOpenThreads.rst1
-rw-r--r--Help/module/FindPHP4.rst1
-rw-r--r--Help/module/FindPNG.rst1
-rw-r--r--Help/module/FindPackageHandleStandardArgs.rst1
-rw-r--r--Help/module/FindPackageMessage.rst1
-rw-r--r--Help/module/FindPerl.rst1
-rw-r--r--Help/module/FindPerlLibs.rst1
-rw-r--r--Help/module/FindPhysFS.rst1
-rw-r--r--Help/module/FindPike.rst1
-rw-r--r--Help/module/FindPkgConfig.rst1
-rw-r--r--Help/module/FindPostgreSQL.rst1
-rw-r--r--Help/module/FindProducer.rst1
-rw-r--r--Help/module/FindProtobuf.rst1
-rw-r--r--Help/module/FindPythonInterp.rst1
-rw-r--r--Help/module/FindPythonLibs.rst1
-rw-r--r--Help/module/FindQt.rst1
-rw-r--r--Help/module/FindQt3.rst1
-rw-r--r--Help/module/FindQt4.rst1
-rw-r--r--Help/module/FindQuickTime.rst1
-rw-r--r--Help/module/FindRTI.rst1
-rw-r--r--Help/module/FindRuby.rst1
-rw-r--r--Help/module/FindSDL.rst1
-rw-r--r--Help/module/FindSDL_image.rst1
-rw-r--r--Help/module/FindSDL_mixer.rst1
-rw-r--r--Help/module/FindSDL_net.rst1
-rw-r--r--Help/module/FindSDL_sound.rst1
-rw-r--r--Help/module/FindSDL_ttf.rst1
-rw-r--r--Help/module/FindSWIG.rst1
-rw-r--r--Help/module/FindSelfPackers.rst1
-rw-r--r--Help/module/FindSquish.rst1
-rw-r--r--Help/module/FindSubversion.rst1
-rw-r--r--Help/module/FindTCL.rst1
-rw-r--r--Help/module/FindTIFF.rst1
-rw-r--r--Help/module/FindTclStub.rst1
-rw-r--r--Help/module/FindTclsh.rst1
-rw-r--r--Help/module/FindThreads.rst1
-rw-r--r--Help/module/FindUnixCommands.rst1
-rw-r--r--Help/module/FindVTK.rst10
-rw-r--r--Help/module/FindWget.rst1
-rw-r--r--Help/module/FindWish.rst1
-rw-r--r--Help/module/FindX11.rst1
-rw-r--r--Help/module/FindXCTest.rst1
-rw-r--r--Help/module/FindXMLRPC.rst1
-rw-r--r--Help/module/FindXalanC.rst1
-rw-r--r--Help/module/FindXercesC.rst1
-rw-r--r--Help/module/FindZLIB.rst1
-rw-r--r--Help/module/Findosg.rst1
-rw-r--r--Help/module/FindosgAnimation.rst1
-rw-r--r--Help/module/FindosgDB.rst1
-rw-r--r--Help/module/FindosgFX.rst1
-rw-r--r--Help/module/FindosgGA.rst1
-rw-r--r--Help/module/FindosgIntrospection.rst1
-rw-r--r--Help/module/FindosgManipulator.rst1
-rw-r--r--Help/module/FindosgParticle.rst1
-rw-r--r--Help/module/FindosgPresentation.rst1
-rw-r--r--Help/module/FindosgProducer.rst1
-rw-r--r--Help/module/FindosgQt.rst1
-rw-r--r--Help/module/FindosgShadow.rst1
-rw-r--r--Help/module/FindosgSim.rst1
-rw-r--r--Help/module/FindosgTerrain.rst1
-rw-r--r--Help/module/FindosgText.rst1
-rw-r--r--Help/module/FindosgUtil.rst1
-rw-r--r--Help/module/FindosgViewer.rst1
-rw-r--r--Help/module/FindosgVolume.rst1
-rw-r--r--Help/module/FindosgWidget.rst1
-rw-r--r--Help/module/Findosg_functions.rst1
-rw-r--r--Help/module/FindwxWidgets.rst1
-rw-r--r--Help/module/FindwxWindows.rst1
-rw-r--r--Help/module/FortranCInterface.rst1
-rw-r--r--Help/module/GNUInstallDirs.rst1
-rw-r--r--Help/module/GenerateExportHeader.rst1
-rw-r--r--Help/module/GetPrerequisites.rst1
-rw-r--r--Help/module/InstallRequiredSystemLibraries.rst1
-rw-r--r--Help/module/MacroAddFileDependencies.rst1
-rw-r--r--Help/module/ProcessorCount.rst1
-rw-r--r--Help/module/SelectLibraryConfigurations.rst1
-rw-r--r--Help/module/SquishTestScript.rst1
-rw-r--r--Help/module/TestBigEndian.rst1
-rw-r--r--Help/module/TestCXXAcceptsFlag.rst1
-rw-r--r--Help/module/TestForANSIForScope.rst1
-rw-r--r--Help/module/TestForANSIStreamHeaders.rst1
-rw-r--r--Help/module/TestForSSTREAM.rst1
-rw-r--r--Help/module/TestForSTDNamespace.rst1
-rw-r--r--Help/module/UseEcos.rst1
-rw-r--r--Help/module/UseJava.rst1
-rw-r--r--Help/module/UseJavaClassFilelist.rst1
-rw-r--r--Help/module/UseJavaSymlinks.rst1
-rw-r--r--Help/module/UsePkgConfig.rst1
-rw-r--r--Help/module/UseSWIG.rst1
-rw-r--r--Help/module/Use_wxWindows.rst1
-rw-r--r--Help/module/UsewxWidgets.rst1
-rw-r--r--Help/module/WriteBasicConfigVersionFile.rst1
-rw-r--r--Help/module/WriteCompilerDetectionHeader.rst1
-rw-r--r--Help/policy/CMP0000.rst32
-rw-r--r--Help/policy/CMP0001.rst21
-rw-r--r--Help/policy/CMP0002.rst28
-rw-r--r--Help/policy/CMP0003.rst104
-rw-r--r--Help/policy/CMP0004.rst25
-rw-r--r--Help/policy/CMP0005.rst26
-rw-r--r--Help/policy/CMP0006.rst24
-rw-r--r--Help/policy/CMP0007.rst17
-rw-r--r--Help/policy/CMP0008.rst34
-rw-r--r--Help/policy/CMP0009.rst21
-rw-r--r--Help/policy/CMP0010.rst20
-rw-r--r--Help/policy/CMP0011.rst24
-rw-r--r--Help/policy/CMP0012.rst27
-rw-r--r--Help/policy/CMP0013.rst21
-rw-r--r--Help/policy/CMP0014.rst17
-rw-r--r--Help/policy/CMP0015.rst19
-rw-r--r--Help/policy/CMP0016.rst15
-rw-r--r--Help/policy/CMP0017.rst21
-rw-r--r--Help/policy/CMP0018.rst34
-rw-r--r--Help/policy/CMP0019.rst22
-rw-r--r--Help/policy/CMP0020.rst27
-rw-r--r--Help/policy/CMP0021.rst20
-rw-r--r--Help/policy/CMP0022.rst39
-rw-r--r--Help/policy/CMP0023.rst35
-rw-r--r--Help/policy/CMP0024.rst24
-rw-r--r--Help/policy/CMP0025.rst29
-rw-r--r--Help/policy/CMP0026.rst28
-rw-r--r--Help/policy/CMP0027.rst27
-rw-r--r--Help/policy/CMP0028.rst25
-rw-r--r--Help/policy/CMP0029.rst12
-rw-r--r--Help/policy/CMP0030.rst13
-rw-r--r--Help/policy/CMP0031.rst15
-rw-r--r--Help/policy/CMP0032.rst15
-rw-r--r--Help/policy/CMP0033.rst16
-rw-r--r--Help/policy/CMP0034.rst13
-rw-r--r--Help/policy/CMP0035.rst12
-rw-r--r--Help/policy/CMP0036.rst14
-rw-r--r--Help/policy/CMP0037.rst28
-rw-r--r--Help/policy/CMP0038.rst18
-rw-r--r--Help/policy/CMP0039.rst19
-rw-r--r--Help/policy/CMP0040.rst21
-rw-r--r--Help/policy/CMP0041.rst27
-rw-r--r--Help/policy/CMP0042.rst21
-rw-r--r--Help/policy/CMP0043.rst47
-rw-r--r--Help/policy/CMP0044.rst21
-rw-r--r--Help/policy/CMP0045.rst19
-rw-r--r--Help/policy/CMP0046.rst19
-rw-r--r--Help/policy/CMP0047.rst30
-rw-r--r--Help/policy/CMP0048.rst24
-rw-r--r--Help/policy/CMP0049.rst25
-rw-r--r--Help/policy/CMP0050.rst20
-rw-r--r--Help/policy/CMP0051.rst26
-rw-r--r--Help/policy/CMP0052.rst26
-rw-r--r--Help/policy/CMP0053.rst46
-rw-r--r--Help/policy/CMP0054.rst52
-rw-r--r--Help/policy/CMP0055.rst19
-rw-r--r--Help/policy/CMP0056.rst34
-rw-r--r--Help/policy/CMP0057.rst16
-rw-r--r--Help/policy/CMP0058.rst110
-rw-r--r--Help/policy/CMP0059.rst19
-rw-r--r--Help/policy/CMP0060.rst65
-rw-r--r--Help/policy/CMP0061.rst26
-rw-r--r--Help/policy/CMP0062.rst29
-rw-r--r--Help/policy/CMP0063.rst28
-rw-r--r--Help/policy/CMP0064.rst17
-rw-r--r--Help/policy/CMP0065.rst27
-rw-r--r--Help/policy/DEPRECATED.txt4
-rw-r--r--Help/policy/DISALLOWED_COMMAND.txt9
-rw-r--r--Help/prop_cache/ADVANCED.rst8
-rw-r--r--Help/prop_cache/HELPSTRING.rst7
-rw-r--r--Help/prop_cache/MODIFIED.rst7
-rw-r--r--Help/prop_cache/STRINGS.rst9
-rw-r--r--Help/prop_cache/TYPE.rst21
-rw-r--r--Help/prop_cache/VALUE.rst7
-rw-r--r--Help/prop_dir/ADDITIONAL_MAKE_CLEAN_FILES.rst7
-rw-r--r--Help/prop_dir/CACHE_VARIABLES.rst7
-rw-r--r--Help/prop_dir/CLEAN_NO_CUSTOM.rst6
-rw-r--r--Help/prop_dir/CMAKE_CONFIGURE_DEPENDS.rst9
-rw-r--r--Help/prop_dir/COMPILE_DEFINITIONS.rst32
-rw-r--r--Help/prop_dir/COMPILE_DEFINITIONS_CONFIG.rst19
-rw-r--r--Help/prop_dir/COMPILE_OPTIONS.rst16
-rw-r--r--Help/prop_dir/DEFINITIONS.rst13
-rw-r--r--Help/prop_dir/EXCLUDE_FROM_ALL.rst9
-rw-r--r--Help/prop_dir/IMPLICIT_DEPENDS_INCLUDE_TRANSFORM.rst34
-rw-r--r--Help/prop_dir/INCLUDE_DIRECTORIES.rst26
-rw-r--r--Help/prop_dir/INCLUDE_REGULAR_EXPRESSION.rst9
-rw-r--r--Help/prop_dir/INTERPROCEDURAL_OPTIMIZATION.rst7
-rw-r--r--Help/prop_dir/INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst8
-rw-r--r--Help/prop_dir/LINK_DIRECTORIES.rst8
-rw-r--r--Help/prop_dir/LISTFILE_STACK.rst9
-rw-r--r--Help/prop_dir/MACROS.rst8
-rw-r--r--Help/prop_dir/PARENT_DIRECTORY.rst8
-rw-r--r--Help/prop_dir/RULE_LAUNCH_COMPILE.rst7
-rw-r--r--Help/prop_dir/RULE_LAUNCH_CUSTOM.rst7
-rw-r--r--Help/prop_dir/RULE_LAUNCH_LINK.rst7
-rw-r--r--Help/prop_dir/TEST_INCLUDE_FILE.rst7
-rw-r--r--Help/prop_dir/VARIABLES.rst7
-rw-r--r--Help/prop_dir/VS_GLOBAL_SECTION_POST_section.rst29
-rw-r--r--Help/prop_dir/VS_GLOBAL_SECTION_PRE_section.rst22
-rw-r--r--Help/prop_gbl/ALLOW_DUPLICATE_CUSTOM_TARGETS.rst19
-rw-r--r--Help/prop_gbl/AUTOGEN_TARGETS_FOLDER.rst9
-rw-r--r--Help/prop_gbl/AUTOMOC_TARGETS_FOLDER.rst11
-rw-r--r--Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst303
-rw-r--r--Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst26
-rw-r--r--Help/prop_gbl/DEBUG_CONFIGURATIONS.rst14
-rw-r--r--Help/prop_gbl/DISABLED_FEATURES.rst11
-rw-r--r--Help/prop_gbl/ECLIPSE_EXTRA_NATURES.rst8
-rw-r--r--Help/prop_gbl/ENABLED_FEATURES.rst11
-rw-r--r--Help/prop_gbl/ENABLED_LANGUAGES.rst6
-rw-r--r--Help/prop_gbl/FIND_LIBRARY_USE_LIB64_PATHS.rst9
-rw-r--r--Help/prop_gbl/FIND_LIBRARY_USE_OPENBSD_VERSIONING.rst9
-rw-r--r--Help/prop_gbl/GLOBAL_DEPENDS_DEBUG_MODE.rst8
-rw-r--r--Help/prop_gbl/GLOBAL_DEPENDS_NO_CYCLES.rst10
-rw-r--r--Help/prop_gbl/IN_TRY_COMPILE.rst6
-rw-r--r--Help/prop_gbl/JOB_POOLS.rst23
-rw-r--r--Help/prop_gbl/PACKAGES_FOUND.rst7
-rw-r--r--Help/prop_gbl/PACKAGES_NOT_FOUND.rst7
-rw-r--r--Help/prop_gbl/PREDEFINED_TARGETS_FOLDER.rst9
-rw-r--r--Help/prop_gbl/REPORT_UNDEFINED_PROPERTIES.rst8
-rw-r--r--Help/prop_gbl/RULE_LAUNCH_COMPILE.rst11
-rw-r--r--Help/prop_gbl/RULE_LAUNCH_CUSTOM.rst11
-rw-r--r--Help/prop_gbl/RULE_LAUNCH_LINK.rst11
-rw-r--r--Help/prop_gbl/RULE_MESSAGES.rst13
-rw-r--r--Help/prop_gbl/TARGET_ARCHIVES_MAY_BE_SHARED_LIBS.rst7
-rw-r--r--Help/prop_gbl/TARGET_MESSAGES.rst20
-rw-r--r--Help/prop_gbl/TARGET_SUPPORTS_SHARED_LIBS.rst9
-rw-r--r--Help/prop_gbl/USE_FOLDERS.rst9
-rw-r--r--Help/prop_inst/CPACK_DESKTOP_SHORTCUTS.rst7
-rw-r--r--Help/prop_inst/CPACK_NEVER_OVERWRITE.rst6
-rw-r--r--Help/prop_inst/CPACK_PERMANENT.rst6
-rw-r--r--Help/prop_inst/CPACK_STARTUP_SHORTCUTS.rst7
-rw-r--r--Help/prop_inst/CPACK_START_MENU_SHORTCUTS.rst7
-rw-r--r--Help/prop_inst/CPACK_WIX_ACL.rst19
-rw-r--r--Help/prop_sf/ABSTRACT.rst9
-rw-r--r--Help/prop_sf/AUTORCC_OPTIONS.rst13
-rw-r--r--Help/prop_sf/AUTOUIC_OPTIONS.rst14
-rw-r--r--Help/prop_sf/COMPILE_DEFINITIONS.rst20
-rw-r--r--Help/prop_sf/COMPILE_DEFINITIONS_CONFIG.rst10
-rw-r--r--Help/prop_sf/COMPILE_FLAGS.rst8
-rw-r--r--Help/prop_sf/EXTERNAL_OBJECT.rst8
-rw-r--r--Help/prop_sf/Fortran_FORMAT.rst9
-rw-r--r--Help/prop_sf/GENERATED.rst8
-rw-r--r--Help/prop_sf/HEADER_FILE_ONLY.rst9
-rw-r--r--Help/prop_sf/KEEP_EXTENSION.rst9
-rw-r--r--Help/prop_sf/LABELS.rst8
-rw-r--r--Help/prop_sf/LANGUAGE.rst10
-rw-r--r--Help/prop_sf/LOCATION.rst7
-rw-r--r--Help/prop_sf/MACOSX_PACKAGE_LOCATION.rst23
-rw-r--r--Help/prop_sf/OBJECT_DEPENDS.rst21
-rw-r--r--Help/prop_sf/OBJECT_OUTPUTS.rst9
-rw-r--r--Help/prop_sf/SYMBOLIC.rst8
-rw-r--r--Help/prop_sf/VS_DEPLOYMENT_CONTENT.rst11
-rw-r--r--Help/prop_sf/VS_DEPLOYMENT_LOCATION.rst8
-rw-r--r--Help/prop_sf/VS_SHADER_ENTRYPOINT.rst5
-rw-r--r--Help/prop_sf/VS_SHADER_FLAGS.rst4
-rw-r--r--Help/prop_sf/VS_SHADER_MODEL.rst5
-rw-r--r--Help/prop_sf/VS_SHADER_TYPE.rst4
-rw-r--r--Help/prop_sf/VS_XAML_TYPE.rst6
-rw-r--r--Help/prop_sf/WRAP_EXCLUDE.rst10
-rw-r--r--Help/prop_sf/XCODE_EXPLICIT_FILE_TYPE.rst8
-rw-r--r--Help/prop_sf/XCODE_LAST_KNOWN_FILE_TYPE.rst9
-rw-r--r--Help/prop_test/ATTACHED_FILES.rst7
-rw-r--r--Help/prop_test/ATTACHED_FILES_ON_FAIL.rst7
-rw-r--r--Help/prop_test/COST.rst7
-rw-r--r--Help/prop_test/DEPENDS.rst6
-rw-r--r--Help/prop_test/ENVIRONMENT.rst9
-rw-r--r--Help/prop_test/FAIL_REGULAR_EXPRESSION.rst15
-rw-r--r--Help/prop_test/LABELS.rst6
-rw-r--r--Help/prop_test/MEASUREMENT.rst8
-rw-r--r--Help/prop_test/PASS_REGULAR_EXPRESSION.rst16
-rw-r--r--Help/prop_test/PROCESSORS.rst8
-rw-r--r--Help/prop_test/REQUIRED_FILES.rst7
-rw-r--r--Help/prop_test/RESOURCE_LOCK.rst7
-rw-r--r--Help/prop_test/RUN_SERIAL.rst8
-rw-r--r--Help/prop_test/SKIP_RETURN_CODE.rst9
-rw-r--r--Help/prop_test/TIMEOUT.rst9
-rw-r--r--Help/prop_test/WILL_FAIL.rst7
-rw-r--r--Help/prop_test/WORKING_DIRECTORY.rst7
-rw-r--r--Help/prop_tgt/ALIASED_TARGET.rst7
-rw-r--r--Help/prop_tgt/ANDROID_ANT_ADDITIONAL_OPTIONS.rst8
-rw-r--r--Help/prop_tgt/ANDROID_API.rst7
-rw-r--r--Help/prop_tgt/ANDROID_API_MIN.rst7
-rw-r--r--Help/prop_tgt/ANDROID_ARCH.rst17
-rw-r--r--Help/prop_tgt/ANDROID_ASSETS_DIRECTORIES.rst9
-rw-r--r--Help/prop_tgt/ANDROID_GUI.rst13
-rw-r--r--Help/prop_tgt/ANDROID_JAR_DEPENDENCIES.rst7
-rw-r--r--Help/prop_tgt/ANDROID_JAR_DIRECTORIES.rst14
-rw-r--r--Help/prop_tgt/ANDROID_JAVA_SOURCE_DIR.rst8
-rw-r--r--Help/prop_tgt/ANDROID_NATIVE_LIB_DEPENDENCIES.rst14
-rw-r--r--Help/prop_tgt/ANDROID_NATIVE_LIB_DIRECTORIES.rst16
-rw-r--r--Help/prop_tgt/ANDROID_PROCESS_MAX.rst8
-rw-r--r--Help/prop_tgt/ANDROID_PROGUARD.rst9
-rw-r--r--Help/prop_tgt/ANDROID_PROGUARD_CONFIG_PATH.rst9
-rw-r--r--Help/prop_tgt/ANDROID_SECURE_PROPS_PATH.rst8
-rw-r--r--Help/prop_tgt/ANDROID_SKIP_ANT_STEP.rst6
-rw-r--r--Help/prop_tgt/ANDROID_STL_TYPE.rst15
-rw-r--r--Help/prop_tgt/ARCHIVE_OUTPUT_DIRECTORY.rst9
-rw-r--r--Help/prop_tgt/ARCHIVE_OUTPUT_DIRECTORY_CONFIG.rst16
-rw-r--r--Help/prop_tgt/ARCHIVE_OUTPUT_NAME.rst8
-rw-r--r--Help/prop_tgt/ARCHIVE_OUTPUT_NAME_CONFIG.rst8
-rw-r--r--Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst17
-rw-r--r--Help/prop_tgt/AUTOMOC.rst37
-rw-r--r--Help/prop_tgt/AUTOMOC_MOC_OPTIONS.rst15
-rw-r--r--Help/prop_tgt/AUTORCC.rst23
-rw-r--r--Help/prop_tgt/AUTORCC_OPTIONS.rst21
-rw-r--r--Help/prop_tgt/AUTOUIC.rst24
-rw-r--r--Help/prop_tgt/AUTOUIC_OPTIONS.rst25
-rw-r--r--Help/prop_tgt/BINARY_DIR.rst6
-rw-r--r--Help/prop_tgt/BUILD_WITH_INSTALL_RPATH.rst11
-rw-r--r--Help/prop_tgt/BUNDLE.rst9
-rw-r--r--Help/prop_tgt/BUNDLE_EXTENSION.rst7
-rw-r--r--Help/prop_tgt/COMPATIBLE_INTERFACE_BOOL.rst20
-rw-r--r--Help/prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MAX.rst18
-rw-r--r--Help/prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MIN.rst18
-rw-r--r--Help/prop_tgt/COMPATIBLE_INTERFACE_STRING.rst16
-rw-r--r--Help/prop_tgt/COMPILE_DEFINITIONS.rst26
-rw-r--r--Help/prop_tgt/COMPILE_DEFINITIONS_CONFIG.rst16
-rw-r--r--Help/prop_tgt/COMPILE_FEATURES.rst12
-rw-r--r--Help/prop_tgt/COMPILE_FLAGS.rst11
-rw-r--r--Help/prop_tgt/COMPILE_OPTIONS.rst17
-rw-r--r--Help/prop_tgt/COMPILE_PDB_NAME.rst11
-rw-r--r--Help/prop_tgt/COMPILE_PDB_NAME_CONFIG.rst10
-rw-r--r--Help/prop_tgt/COMPILE_PDB_NOTE.txt8
-rw-r--r--Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY.rst13
-rw-r--r--Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst16
-rw-r--r--Help/prop_tgt/CONFIG_OUTPUT_NAME.rst8
-rw-r--r--Help/prop_tgt/CONFIG_POSTFIX.rst10
-rw-r--r--Help/prop_tgt/CROSSCOMPILING_EMULATOR.rst6
-rw-r--r--Help/prop_tgt/CXX_EXTENSIONS.rst16
-rw-r--r--Help/prop_tgt/CXX_STANDARD.rst31
-rw-r--r--Help/prop_tgt/CXX_STANDARD_REQUIRED.rst18
-rw-r--r--Help/prop_tgt/C_EXTENSIONS.rst16
-rw-r--r--Help/prop_tgt/C_STANDARD.rst31
-rw-r--r--Help/prop_tgt/C_STANDARD_REQUIRED.rst18
-rw-r--r--Help/prop_tgt/DEBUG_POSTFIX.rst7
-rw-r--r--Help/prop_tgt/DEFINE_SYMBOL.rst11
-rw-r--r--Help/prop_tgt/ENABLE_EXPORTS.rst22
-rw-r--r--Help/prop_tgt/EXCLUDE_FROM_ALL.rst10
-rw-r--r--Help/prop_tgt/EXCLUDE_FROM_DEFAULT_BUILD.rst8
-rw-r--r--Help/prop_tgt/EXCLUDE_FROM_DEFAULT_BUILD_CONFIG.rst9
-rw-r--r--Help/prop_tgt/EXPORT_NAME.rst8
-rw-r--r--Help/prop_tgt/EchoString.rst7
-rw-r--r--Help/prop_tgt/FOLDER.rst10
-rw-r--r--Help/prop_tgt/FRAMEWORK.rst31
-rw-r--r--Help/prop_tgt/FRAMEWORK_VERSION.rst8
-rw-r--r--Help/prop_tgt/Fortran_FORMAT.rst11
-rw-r--r--Help/prop_tgt/Fortran_MODULE_DIRECTORY.rst17
-rw-r--r--Help/prop_tgt/GENERATOR_FILE_NAME.rst9
-rw-r--r--Help/prop_tgt/GNUtoMS.rst17
-rw-r--r--Help/prop_tgt/HAS_CXX.rst7
-rw-r--r--Help/prop_tgt/IMPLICIT_DEPENDS_INCLUDE_TRANSFORM.rst32
-rw-r--r--Help/prop_tgt/IMPORTED.rst8
-rw-r--r--Help/prop_tgt/IMPORTED_CONFIGURATIONS.rst11
-rw-r--r--Help/prop_tgt/IMPORTED_IMPLIB.rst7
-rw-r--r--Help/prop_tgt/IMPORTED_IMPLIB_CONFIG.rst7
-rw-r--r--Help/prop_tgt/IMPORTED_LINK_DEPENDENT_LIBRARIES.rst14
-rw-r--r--Help/prop_tgt/IMPORTED_LINK_DEPENDENT_LIBRARIES_CONFIG.rst8
-rw-r--r--Help/prop_tgt/IMPORTED_LINK_INTERFACE_LANGUAGES.rst14
-rw-r--r--Help/prop_tgt/IMPORTED_LINK_INTERFACE_LANGUAGES_CONFIG.rst8
-rw-r--r--Help/prop_tgt/IMPORTED_LINK_INTERFACE_LIBRARIES.rst16
-rw-r--r--Help/prop_tgt/IMPORTED_LINK_INTERFACE_LIBRARIES_CONFIG.rst13
-rw-r--r--Help/prop_tgt/IMPORTED_LINK_INTERFACE_MULTIPLICITY.rst6
-rw-r--r--Help/prop_tgt/IMPORTED_LINK_INTERFACE_MULTIPLICITY_CONFIG.rst7
-rw-r--r--Help/prop_tgt/IMPORTED_LOCATION.rst21
-rw-r--r--Help/prop_tgt/IMPORTED_LOCATION_CONFIG.rst7
-rw-r--r--Help/prop_tgt/IMPORTED_NO_SONAME.rst9
-rw-r--r--Help/prop_tgt/IMPORTED_NO_SONAME_CONFIG.rst7
-rw-r--r--Help/prop_tgt/IMPORTED_SONAME.rst8
-rw-r--r--Help/prop_tgt/IMPORTED_SONAME_CONFIG.rst7
-rw-r--r--Help/prop_tgt/IMPORT_PREFIX.rst9
-rw-r--r--Help/prop_tgt/IMPORT_SUFFIX.rst9
-rw-r--r--Help/prop_tgt/INCLUDE_DIRECTORIES.rst24
-rw-r--r--Help/prop_tgt/INSTALL_NAME_DIR.rst8
-rw-r--r--Help/prop_tgt/INSTALL_RPATH.rst9
-rw-r--r--Help/prop_tgt/INSTALL_RPATH_USE_LINK_PATH.rst10
-rw-r--r--Help/prop_tgt/INTERFACE_AUTOUIC_OPTIONS.rst14
-rw-r--r--Help/prop_tgt/INTERFACE_BUILD_PROPERTY.txt16
-rw-r--r--Help/prop_tgt/INTERFACE_COMPILE_DEFINITIONS.rst9
-rw-r--r--Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst12
-rw-r--r--Help/prop_tgt/INTERFACE_COMPILE_OPTIONS.rst9
-rw-r--r--Help/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES.rst29
-rw-r--r--Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst24
-rw-r--r--Help/prop_tgt/INTERFACE_POSITION_INDEPENDENT_CODE.rst16
-rw-r--r--Help/prop_tgt/INTERFACE_SOURCES.rst18
-rw-r--r--Help/prop_tgt/INTERFACE_SYSTEM_INCLUDE_DIRECTORIES.rst28
-rw-r--r--Help/prop_tgt/INTERPROCEDURAL_OPTIMIZATION.rst7
-rw-r--r--Help/prop_tgt/INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst8
-rw-r--r--Help/prop_tgt/IOS_INSTALL_COMBINED.rst11
-rw-r--r--Help/prop_tgt/JOB_POOL_COMPILE.rst17
-rw-r--r--Help/prop_tgt/JOB_POOL_LINK.rst16
-rw-r--r--Help/prop_tgt/LABELS.rst6
-rw-r--r--Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst13
-rw-r--r--Help/prop_tgt/LANG_INCLUDE_WHAT_YOU_USE.rst13
-rw-r--r--Help/prop_tgt/LANG_VISIBILITY_PRESET.rst13
-rw-r--r--Help/prop_tgt/LIBRARY_OUTPUT_DIRECTORY.rst9
-rw-r--r--Help/prop_tgt/LIBRARY_OUTPUT_DIRECTORY_CONFIG.rst16
-rw-r--r--Help/prop_tgt/LIBRARY_OUTPUT_NAME.rst8
-rw-r--r--Help/prop_tgt/LIBRARY_OUTPUT_NAME_CONFIG.rst8
-rw-r--r--Help/prop_tgt/LINKER_LANGUAGE.rst14
-rw-r--r--Help/prop_tgt/LINK_DEPENDS.rst12
-rw-r--r--Help/prop_tgt/LINK_DEPENDS_NO_SHARED.rst14
-rw-r--r--Help/prop_tgt/LINK_FLAGS.rst8
-rw-r--r--Help/prop_tgt/LINK_FLAGS_CONFIG.rst6
-rw-r--r--Help/prop_tgt/LINK_INTERFACE_LIBRARIES.rst31
-rw-r--r--Help/prop_tgt/LINK_INTERFACE_LIBRARIES_CONFIG.rst20
-rw-r--r--Help/prop_tgt/LINK_INTERFACE_MULTIPLICITY.rst12
-rw-r--r--Help/prop_tgt/LINK_INTERFACE_MULTIPLICITY_CONFIG.rst8
-rw-r--r--Help/prop_tgt/LINK_LIBRARIES.rst17
-rw-r--r--Help/prop_tgt/LINK_SEARCH_END_STATIC.rst18
-rw-r--r--Help/prop_tgt/LINK_SEARCH_START_STATIC.rst19
-rw-r--r--Help/prop_tgt/LOCATION.rst27
-rw-r--r--Help/prop_tgt/LOCATION_CONFIG.rst20
-rw-r--r--Help/prop_tgt/MACOSX_BUNDLE.rst12
-rw-r--r--Help/prop_tgt/MACOSX_BUNDLE_INFO_PLIST.rst35
-rw-r--r--Help/prop_tgt/MACOSX_FRAMEWORK_INFO_PLIST.rst27
-rw-r--r--Help/prop_tgt/MACOSX_RPATH.rst23
-rw-r--r--Help/prop_tgt/MAP_IMPORTED_CONFIG_CONFIG.rst19
-rw-r--r--Help/prop_tgt/NAME.rst6
-rw-r--r--Help/prop_tgt/NO_SONAME.rst14
-rw-r--r--Help/prop_tgt/NO_SYSTEM_FROM_IMPORTED.rst11
-rw-r--r--Help/prop_tgt/OSX_ARCHITECTURES.rst11
-rw-r--r--Help/prop_tgt/OSX_ARCHITECTURES_CONFIG.rst7
-rw-r--r--Help/prop_tgt/OUTPUT_NAME.rst21
-rw-r--r--Help/prop_tgt/OUTPUT_NAME_CONFIG.rst7
-rw-r--r--Help/prop_tgt/PDB_NAME.rst12
-rw-r--r--Help/prop_tgt/PDB_NAME_CONFIG.rst10
-rw-r--r--Help/prop_tgt/PDB_NOTE.txt12
-rw-r--r--Help/prop_tgt/PDB_OUTPUT_DIRECTORY.rst13
-rw-r--r--Help/prop_tgt/PDB_OUTPUT_DIRECTORY_CONFIG.rst15
-rw-r--r--Help/prop_tgt/POSITION_INDEPENDENT_CODE.rst11
-rw-r--r--Help/prop_tgt/POST_INSTALL_SCRIPT.rst9
-rw-r--r--Help/prop_tgt/PREFIX.rst7
-rw-r--r--Help/prop_tgt/PRE_INSTALL_SCRIPT.rst9
-rw-r--r--Help/prop_tgt/PRIVATE_HEADER.rst11
-rw-r--r--Help/prop_tgt/PROJECT_LABEL.rst7
-rw-r--r--Help/prop_tgt/PUBLIC_HEADER.rst11
-rw-r--r--Help/prop_tgt/RESOURCE.rst61
-rw-r--r--Help/prop_tgt/RULE_LAUNCH_COMPILE.rst7
-rw-r--r--Help/prop_tgt/RULE_LAUNCH_CUSTOM.rst7
-rw-r--r--Help/prop_tgt/RULE_LAUNCH_LINK.rst7
-rw-r--r--Help/prop_tgt/RUNTIME_OUTPUT_DIRECTORY.rst9
-rw-r--r--Help/prop_tgt/RUNTIME_OUTPUT_DIRECTORY_CONFIG.rst16
-rw-r--r--Help/prop_tgt/RUNTIME_OUTPUT_NAME.rst8
-rw-r--r--Help/prop_tgt/RUNTIME_OUTPUT_NAME_CONFIG.rst8
-rw-r--r--Help/prop_tgt/SKIP_BUILD_RPATH.rst9
-rw-r--r--Help/prop_tgt/SOURCES.rst6
-rw-r--r--Help/prop_tgt/SOURCE_DIR.rst6
-rw-r--r--Help/prop_tgt/SOVERSION.rst14
-rw-r--r--Help/prop_tgt/STATIC_LIBRARY_FLAGS.rst6
-rw-r--r--Help/prop_tgt/STATIC_LIBRARY_FLAGS_CONFIG.rst6
-rw-r--r--Help/prop_tgt/SUFFIX.rst7
-rw-r--r--Help/prop_tgt/TYPE.rst9
-rw-r--r--Help/prop_tgt/VERSION.rst16
-rw-r--r--Help/prop_tgt/VISIBILITY_INLINES_HIDDEN.rst13
-rw-r--r--Help/prop_tgt/VS_DESKTOP_EXTENSIONS_VERSION.rst10
-rw-r--r--Help/prop_tgt/VS_DOTNET_REFERENCES.rst7
-rw-r--r--Help/prop_tgt/VS_DOTNET_TARGET_FRAMEWORK_VERSION.rst7
-rw-r--r--Help/prop_tgt/VS_GLOBAL_KEYWORD.rst12
-rw-r--r--Help/prop_tgt/VS_GLOBAL_PROJECT_TYPES.rst15
-rw-r--r--Help/prop_tgt/VS_GLOBAL_ROOTNAMESPACE.rst7
-rw-r--r--Help/prop_tgt/VS_GLOBAL_variable.rst10
-rw-r--r--Help/prop_tgt/VS_IOT_EXTENSIONS_VERSION.rst10
-rw-r--r--Help/prop_tgt/VS_IOT_STARTUP_TASK.rst6
-rw-r--r--Help/prop_tgt/VS_KEYWORD.rst10
-rw-r--r--Help/prop_tgt/VS_MOBILE_EXTENSIONS_VERSION.rst10
-rw-r--r--Help/prop_tgt/VS_SCC_AUXPATH.rst7
-rw-r--r--Help/prop_tgt/VS_SCC_LOCALPATH.rst7
-rw-r--r--Help/prop_tgt/VS_SCC_PROJECTNAME.rst7
-rw-r--r--Help/prop_tgt/VS_SCC_PROVIDER.rst7
-rw-r--r--Help/prop_tgt/VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION.rst10
-rw-r--r--Help/prop_tgt/VS_WINRT_COMPONENT.rst11
-rw-r--r--Help/prop_tgt/VS_WINRT_EXTENSIONS.rst5
-rw-r--r--Help/prop_tgt/VS_WINRT_REFERENCES.rst7
-rw-r--r--Help/prop_tgt/WIN32_EXECUTABLE.rst12
-rw-r--r--Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst18
-rw-r--r--Help/prop_tgt/XCODE_ATTRIBUTE_an-attribute.rst16
-rw-r--r--Help/prop_tgt/XCTEST.rst13
-rw-r--r--Help/prop_tgt/XXX_OUTPUT_DIRECTORY.txt11
-rw-r--r--Help/prop_tgt/XXX_OUTPUT_NAME.txt5
-rw-r--r--Help/release/3.0.rst473
-rw-r--r--Help/release/3.1.rst425
-rw-r--r--Help/release/3.2.rst277
-rw-r--r--Help/release/3.3.rst287
-rw-r--r--Help/release/3.4.rst273
-rw-r--r--Help/release/3.5.rst185
-rw-r--r--Help/release/dev.txt16
-rw-r--r--Help/release/index.rst19
-rw-r--r--Help/variable/APPLE.rst6
-rw-r--r--Help/variable/BORLAND.rst6
-rw-r--r--Help/variable/BUILD_SHARED_LIBS.rst10
-rw-r--r--Help/variable/CMAKE_ABSOLUTE_DESTINATION_FILES.rst9
-rw-r--r--Help/variable/CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS.rst5
-rw-r--r--Help/variable/CMAKE_ANDROID_API.rst5
-rw-r--r--Help/variable/CMAKE_ANDROID_API_MIN.rst5
-rw-r--r--Help/variable/CMAKE_ANDROID_ARCH.rst5
-rw-r--r--Help/variable/CMAKE_ANDROID_ASSETS_DIRECTORIES.rst5
-rw-r--r--Help/variable/CMAKE_ANDROID_GUI.rst5
-rw-r--r--Help/variable/CMAKE_ANDROID_JAR_DEPENDENCIES.rst5
-rw-r--r--Help/variable/CMAKE_ANDROID_JAR_DIRECTORIES.rst5
-rw-r--r--Help/variable/CMAKE_ANDROID_JAVA_SOURCE_DIR.rst5
-rw-r--r--Help/variable/CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES.rst5
-rw-r--r--Help/variable/CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES.rst5
-rw-r--r--Help/variable/CMAKE_ANDROID_PROCESS_MAX.rst5
-rw-r--r--Help/variable/CMAKE_ANDROID_PROGUARD.rst5
-rw-r--r--Help/variable/CMAKE_ANDROID_PROGUARD_CONFIG_PATH.rst5
-rw-r--r--Help/variable/CMAKE_ANDROID_SECURE_PROPS_PATH.rst5
-rw-r--r--Help/variable/CMAKE_ANDROID_SKIP_ANT_STEP.rst5
-rw-r--r--Help/variable/CMAKE_ANDROID_STL_TYPE.rst5
-rw-r--r--Help/variable/CMAKE_APPBUNDLE_PATH.rst6
-rw-r--r--Help/variable/CMAKE_AR.rst7
-rw-r--r--Help/variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY.rst9
-rw-r--r--Help/variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CONFIG.rst9
-rw-r--r--Help/variable/CMAKE_ARGC.rst8
-rw-r--r--Help/variable/CMAKE_ARGV0.rst9
-rw-r--r--Help/variable/CMAKE_AUTOMOC.rst7
-rw-r--r--Help/variable/CMAKE_AUTOMOC_MOC_OPTIONS.rst7
-rw-r--r--Help/variable/CMAKE_AUTOMOC_RELAXED_MODE.rst13
-rw-r--r--Help/variable/CMAKE_AUTORCC.rst7
-rw-r--r--Help/variable/CMAKE_AUTORCC_OPTIONS.rst7
-rw-r--r--Help/variable/CMAKE_AUTOUIC.rst7
-rw-r--r--Help/variable/CMAKE_AUTOUIC_OPTIONS.rst7
-rw-r--r--Help/variable/CMAKE_BACKWARDS_COMPATIBILITY.rst4
-rw-r--r--Help/variable/CMAKE_BINARY_DIR.rst13
-rw-r--r--Help/variable/CMAKE_BUILD_TOOL.rst6
-rw-r--r--Help/variable/CMAKE_BUILD_TYPE.rst20
-rw-r--r--Help/variable/CMAKE_BUILD_WITH_INSTALL_RPATH.rst11
-rw-r--r--Help/variable/CMAKE_CACHEFILE_DIR.rst7
-rw-r--r--Help/variable/CMAKE_CACHE_MAJOR_VERSION.rst8
-rw-r--r--Help/variable/CMAKE_CACHE_MINOR_VERSION.rst8
-rw-r--r--Help/variable/CMAKE_CACHE_PATCH_VERSION.rst8
-rw-r--r--Help/variable/CMAKE_CFG_INTDIR.rst46
-rw-r--r--Help/variable/CMAKE_CL_64.rst6
-rw-r--r--Help/variable/CMAKE_COLOR_MAKEFILE.rst7
-rw-r--r--Help/variable/CMAKE_COMMAND.rst8
-rw-r--r--Help/variable/CMAKE_COMPILER_2005.rst6
-rw-r--r--Help/variable/CMAKE_COMPILER_IS_GNULANG.rst15
-rw-r--r--Help/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY.rst8
-rw-r--r--Help/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst11
-rw-r--r--Help/variable/CMAKE_CONFIGURATION_TYPES.rst10
-rw-r--r--Help/variable/CMAKE_CONFIG_POSTFIX.rst7
-rw-r--r--Help/variable/CMAKE_CROSSCOMPILING.rst8
-rw-r--r--Help/variable/CMAKE_CROSSCOMPILING_EMULATOR.rst12
-rw-r--r--Help/variable/CMAKE_CTEST_COMMAND.rst8
-rw-r--r--Help/variable/CMAKE_CURRENT_BINARY_DIR.rst15
-rw-r--r--Help/variable/CMAKE_CURRENT_LIST_DIR.rst17
-rw-r--r--Help/variable/CMAKE_CURRENT_LIST_FILE.rst15
-rw-r--r--Help/variable/CMAKE_CURRENT_LIST_LINE.rst7
-rw-r--r--Help/variable/CMAKE_CURRENT_SOURCE_DIR.rst12
-rw-r--r--Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst11
-rw-r--r--Help/variable/CMAKE_CXX_EXTENSIONS.rst11
-rw-r--r--Help/variable/CMAKE_CXX_STANDARD.rst11
-rw-r--r--Help/variable/CMAKE_CXX_STANDARD_REQUIRED.rst11
-rw-r--r--Help/variable/CMAKE_C_COMPILE_FEATURES.rst11
-rw-r--r--Help/variable/CMAKE_C_EXTENSIONS.rst11
-rw-r--r--Help/variable/CMAKE_C_STANDARD.rst11
-rw-r--r--Help/variable/CMAKE_C_STANDARD_REQUIRED.rst11
-rw-r--r--Help/variable/CMAKE_DEBUG_POSTFIX.rst7
-rw-r--r--Help/variable/CMAKE_DEBUG_TARGET_PROPERTIES.rst14
-rw-r--r--Help/variable/CMAKE_DISABLE_FIND_PACKAGE_PackageName.rst16
-rw-r--r--Help/variable/CMAKE_DL_LIBS.rst7
-rw-r--r--Help/variable/CMAKE_EDIT_COMMAND.rst8
-rw-r--r--Help/variable/CMAKE_ENABLE_EXPORTS.rst22
-rw-r--r--Help/variable/CMAKE_ERROR_DEPRECATED.rst7
-rw-r--r--Help/variable/CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION.rst10
-rw-r--r--Help/variable/CMAKE_EXECUTABLE_SUFFIX.rst9
-rw-r--r--Help/variable/CMAKE_EXE_LINKER_FLAGS.rst6
-rw-r--r--Help/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG.rst7
-rw-r--r--Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst30
-rw-r--r--Help/variable/CMAKE_EXPORT_NO_PACKAGE_REGISTRY.rst11
-rw-r--r--Help/variable/CMAKE_EXTRA_GENERATOR.rst10
-rw-r--r--Help/variable/CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES.rst9
-rw-r--r--Help/variable/CMAKE_FIND_APPBUNDLE.rst22
-rw-r--r--Help/variable/CMAKE_FIND_FRAMEWORK.rst22
-rw-r--r--Help/variable/CMAKE_FIND_LIBRARY_PREFIXES.rst9
-rw-r--r--Help/variable/CMAKE_FIND_LIBRARY_SUFFIXES.rst9
-rw-r--r--Help/variable/CMAKE_FIND_NO_INSTALL_PREFIX.rst15
-rw-r--r--Help/variable/CMAKE_FIND_PACKAGE_NAME.rst6
-rw-r--r--Help/variable/CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY.rst13
-rw-r--r--Help/variable/CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY.rst13
-rw-r--r--Help/variable/CMAKE_FIND_PACKAGE_WARN_NO_MODULE.rst19
-rw-r--r--Help/variable/CMAKE_FIND_ROOT_PATH.rst8
-rw-r--r--Help/variable/CMAKE_FIND_ROOT_PATH_MODE_INCLUDE.rst6
-rw-r--r--Help/variable/CMAKE_FIND_ROOT_PATH_MODE_LIBRARY.rst6
-rw-r--r--Help/variable/CMAKE_FIND_ROOT_PATH_MODE_PACKAGE.rst6
-rw-r--r--Help/variable/CMAKE_FIND_ROOT_PATH_MODE_PROGRAM.rst6
-rw-r--r--Help/variable/CMAKE_FIND_ROOT_PATH_MODE_XXX.txt8
-rw-r--r--Help/variable/CMAKE_FRAMEWORK_PATH.rst7
-rw-r--r--Help/variable/CMAKE_Fortran_FORMAT.rst7
-rw-r--r--Help/variable/CMAKE_Fortran_MODDIR_DEFAULT.rst8
-rw-r--r--Help/variable/CMAKE_Fortran_MODDIR_FLAG.rst7
-rw-r--r--Help/variable/CMAKE_Fortran_MODOUT_FLAG.rst7
-rw-r--r--Help/variable/CMAKE_Fortran_MODULE_DIRECTORY.rst8
-rw-r--r--Help/variable/CMAKE_GENERATOR.rst7
-rw-r--r--Help/variable/CMAKE_GENERATOR_PLATFORM.rst15
-rw-r--r--Help/variable/CMAKE_GENERATOR_TOOLSET.rst15
-rw-r--r--Help/variable/CMAKE_GNUtoMS.rst8
-rw-r--r--Help/variable/CMAKE_HOME_DIRECTORY.rst6
-rw-r--r--Help/variable/CMAKE_HOST_APPLE.rst6
-rw-r--r--Help/variable/CMAKE_HOST_SYSTEM.rst10
-rw-r--r--Help/variable/CMAKE_HOST_SYSTEM_NAME.rst8
-rw-r--r--Help/variable/CMAKE_HOST_SYSTEM_PROCESSOR.rst8
-rw-r--r--Help/variable/CMAKE_HOST_SYSTEM_VERSION.rst8
-rw-r--r--Help/variable/CMAKE_HOST_UNIX.rst7
-rw-r--r--Help/variable/CMAKE_HOST_WIN32.rst6
-rw-r--r--Help/variable/CMAKE_IGNORE_PATH.rst18
-rw-r--r--Help/variable/CMAKE_IMPORT_LIBRARY_PREFIX.rst9
-rw-r--r--Help/variable/CMAKE_IMPORT_LIBRARY_SUFFIX.rst9
-rw-r--r--Help/variable/CMAKE_INCLUDE_CURRENT_DIR.rst13
-rw-r--r--Help/variable/CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE.rst12
-rw-r--r--Help/variable/CMAKE_INCLUDE_DIRECTORIES_BEFORE.rst9
-rw-r--r--Help/variable/CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE.rst8
-rw-r--r--Help/variable/CMAKE_INCLUDE_PATH.rst7
-rw-r--r--Help/variable/CMAKE_INSTALL_DEFAULT_COMPONENT_NAME.rst9
-rw-r--r--Help/variable/CMAKE_INSTALL_MESSAGE.rst30
-rw-r--r--Help/variable/CMAKE_INSTALL_NAME_DIR.rst8
-rw-r--r--Help/variable/CMAKE_INSTALL_PREFIX.rst35
-rw-r--r--Help/variable/CMAKE_INSTALL_RPATH.rst8
-rw-r--r--Help/variable/CMAKE_INSTALL_RPATH_USE_LINK_PATH.rst9
-rw-r--r--Help/variable/CMAKE_INTERNAL_PLATFORM_ABI.rst6
-rw-r--r--Help/variable/CMAKE_IOS_INSTALL_COMBINED.rst8
-rw-r--r--Help/variable/CMAKE_JOB_POOL_COMPILE.rst6
-rw-r--r--Help/variable/CMAKE_JOB_POOL_LINK.rst6
-rw-r--r--Help/variable/CMAKE_LANG_ARCHIVE_APPEND.rst10
-rw-r--r--Help/variable/CMAKE_LANG_ARCHIVE_CREATE.rst10
-rw-r--r--Help/variable/CMAKE_LANG_ARCHIVE_FINISH.rst10
-rw-r--r--Help/variable/CMAKE_LANG_COMPILER.rst7
-rw-r--r--Help/variable/CMAKE_LANG_COMPILER_ABI.rst6
-rw-r--r--Help/variable/CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN.rst13
-rw-r--r--Help/variable/CMAKE_LANG_COMPILER_ID.rst35
-rw-r--r--Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst6
-rw-r--r--Help/variable/CMAKE_LANG_COMPILER_LOADED.rst7
-rw-r--r--Help/variable/CMAKE_LANG_COMPILER_TARGET.rst11
-rw-r--r--Help/variable/CMAKE_LANG_COMPILER_VERSION.rst8
-rw-r--r--Help/variable/CMAKE_LANG_COMPILE_OBJECT.rst7
-rw-r--r--Help/variable/CMAKE_LANG_CREATE_SHARED_LIBRARY.rst7
-rw-r--r--Help/variable/CMAKE_LANG_CREATE_SHARED_MODULE.rst7
-rw-r--r--Help/variable/CMAKE_LANG_CREATE_STATIC_LIBRARY.rst7
-rw-r--r--Help/variable/CMAKE_LANG_FLAGS.rst6
-rw-r--r--Help/variable/CMAKE_LANG_FLAGS_DEBUG.rst6
-rw-r--r--Help/variable/CMAKE_LANG_FLAGS_MINSIZEREL.rst7
-rw-r--r--Help/variable/CMAKE_LANG_FLAGS_RELEASE.rst6
-rw-r--r--Help/variable/CMAKE_LANG_FLAGS_RELWITHDEBINFO.rst7
-rw-r--r--Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_DEBUG.rst6
-rw-r--r--Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_MINSIZEREL.rst7
-rw-r--r--Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELEASE.rst6
-rw-r--r--Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELWITHDEBINFO.rst7
-rw-r--r--Help/variable/CMAKE_LANG_IGNORE_EXTENSIONS.rst7
-rw-r--r--Help/variable/CMAKE_LANG_IMPLICIT_INCLUDE_DIRECTORIES.rst9
-rw-r--r--Help/variable/CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES.rst17
-rw-r--r--Help/variable/CMAKE_LANG_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES.rst8
-rw-r--r--Help/variable/CMAKE_LANG_IMPLICIT_LINK_LIBRARIES.rst10
-rw-r--r--Help/variable/CMAKE_LANG_INCLUDE_WHAT_YOU_USE.rst6
-rw-r--r--Help/variable/CMAKE_LANG_LIBRARY_ARCHITECTURE.rst8
-rw-r--r--Help/variable/CMAKE_LANG_LINKER_PREFERENCE.rst11
-rw-r--r--Help/variable/CMAKE_LANG_LINKER_PREFERENCE_PROPAGATES.rst9
-rw-r--r--Help/variable/CMAKE_LANG_LINK_EXECUTABLE.rst6
-rw-r--r--Help/variable/CMAKE_LANG_OUTPUT_EXTENSION.rst7
-rw-r--r--Help/variable/CMAKE_LANG_PLATFORM_ID.rst6
-rw-r--r--Help/variable/CMAKE_LANG_SIMULATE_ID.rst9
-rw-r--r--Help/variable/CMAKE_LANG_SIMULATE_VERSION.rst9
-rw-r--r--Help/variable/CMAKE_LANG_SIZEOF_DATA_PTR.rst7
-rw-r--r--Help/variable/CMAKE_LANG_SOURCE_FILE_EXTENSIONS.rst6
-rw-r--r--Help/variable/CMAKE_LANG_VISIBILITY_PRESET.rst5
-rw-r--r--Help/variable/CMAKE_LIBRARY_ARCHITECTURE.rst7
-rw-r--r--Help/variable/CMAKE_LIBRARY_ARCHITECTURE_REGEX.rst7
-rw-r--r--Help/variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY.rst9
-rw-r--r--Help/variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY_CONFIG.rst9
-rw-r--r--Help/variable/CMAKE_LIBRARY_PATH.rst7
-rw-r--r--Help/variable/CMAKE_LIBRARY_PATH_FLAG.rst7
-rw-r--r--Help/variable/CMAKE_LINK_DEF_FILE_FLAG.rst7
-rw-r--r--Help/variable/CMAKE_LINK_DEPENDS_NO_SHARED.rst8
-rw-r--r--Help/variable/CMAKE_LINK_INTERFACE_LIBRARIES.rst8
-rw-r--r--Help/variable/CMAKE_LINK_LIBRARY_FILE_FLAG.rst7
-rw-r--r--Help/variable/CMAKE_LINK_LIBRARY_FLAG.rst7
-rw-r--r--Help/variable/CMAKE_LINK_LIBRARY_SUFFIX.rst6
-rw-r--r--Help/variable/CMAKE_LINK_SEARCH_END_STATIC.rst19
-rw-r--r--Help/variable/CMAKE_LINK_SEARCH_START_STATIC.rst20
-rw-r--r--Help/variable/CMAKE_MACOSX_BUNDLE.rst7
-rw-r--r--Help/variable/CMAKE_MACOSX_RPATH.rst7
-rw-r--r--Help/variable/CMAKE_MAJOR_VERSION.rst5
-rw-r--r--Help/variable/CMAKE_MAKE_PROGRAM.rst66
-rw-r--r--Help/variable/CMAKE_MAP_IMPORTED_CONFIG_CONFIG.rst8
-rw-r--r--Help/variable/CMAKE_MATCH_COUNT.rst8
-rw-r--r--Help/variable/CMAKE_MFC_FLAG.rst16
-rw-r--r--Help/variable/CMAKE_MINIMUM_REQUIRED_VERSION.rst7
-rw-r--r--Help/variable/CMAKE_MINOR_VERSION.rst5
-rw-r--r--Help/variable/CMAKE_MODULE_LINKER_FLAGS.rst6
-rw-r--r--Help/variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG.rst6
-rw-r--r--Help/variable/CMAKE_MODULE_PATH.rst7
-rw-r--r--Help/variable/CMAKE_NOT_USING_CONFIG_FLAGS.rst7
-rw-r--r--Help/variable/CMAKE_NO_BUILTIN_CHRPATH.rst10
-rw-r--r--Help/variable/CMAKE_NO_SYSTEM_FROM_IMPORTED.rst8
-rw-r--r--Help/variable/CMAKE_OBJECT_PATH_MAX.rst16
-rw-r--r--Help/variable/CMAKE_OSX_ARCHITECTURES.rst10
-rw-r--r--Help/variable/CMAKE_OSX_DEPLOYMENT_TARGET.rst13
-rw-r--r--Help/variable/CMAKE_OSX_SYSROOT.rst13
-rw-r--r--Help/variable/CMAKE_OSX_VARIABLE.txt6
-rw-r--r--Help/variable/CMAKE_PARENT_LIST_FILE.rst9
-rw-r--r--Help/variable/CMAKE_PATCH_VERSION.rst5
-rw-r--r--Help/variable/CMAKE_PDB_OUTPUT_DIRECTORY.rst9
-rw-r--r--Help/variable/CMAKE_PDB_OUTPUT_DIRECTORY_CONFIG.rst11
-rw-r--r--Help/variable/CMAKE_POLICY_DEFAULT_CMPNNNN.rst17
-rw-r--r--Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst23
-rw-r--r--Help/variable/CMAKE_POSITION_INDEPENDENT_CODE.rst9
-rw-r--r--Help/variable/CMAKE_PREFIX_PATH.rst15
-rw-r--r--Help/variable/CMAKE_PROGRAM_PATH.rst7
-rw-r--r--Help/variable/CMAKE_PROJECT_NAME.rst7
-rw-r--r--Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE.rst6
-rw-r--r--Help/variable/CMAKE_RANLIB.rst7
-rw-r--r--Help/variable/CMAKE_ROOT.rst8
-rw-r--r--Help/variable/CMAKE_RUNTIME_OUTPUT_DIRECTORY.rst9
-rw-r--r--Help/variable/CMAKE_RUNTIME_OUTPUT_DIRECTORY_CONFIG.rst9
-rw-r--r--Help/variable/CMAKE_SCRIPT_MODE_FILE.rst9
-rw-r--r--Help/variable/CMAKE_SHARED_LIBRARY_PREFIX.rst8
-rw-r--r--Help/variable/CMAKE_SHARED_LIBRARY_SUFFIX.rst9
-rw-r--r--Help/variable/CMAKE_SHARED_LINKER_FLAGS.rst6
-rw-r--r--Help/variable/CMAKE_SHARED_LINKER_FLAGS_CONFIG.rst7
-rw-r--r--Help/variable/CMAKE_SHARED_MODULE_PREFIX.rst8
-rw-r--r--Help/variable/CMAKE_SHARED_MODULE_SUFFIX.rst9
-rw-r--r--Help/variable/CMAKE_SIZEOF_VOID_P.rst8
-rw-r--r--Help/variable/CMAKE_SKIP_BUILD_RPATH.rst10
-rw-r--r--Help/variable/CMAKE_SKIP_INSTALL_ALL_DEPENDENCY.rst11
-rw-r--r--Help/variable/CMAKE_SKIP_INSTALL_RPATH.rst14
-rw-r--r--Help/variable/CMAKE_SKIP_INSTALL_RULES.rst8
-rw-r--r--Help/variable/CMAKE_SKIP_RPATH.rst10
-rw-r--r--Help/variable/CMAKE_SOURCE_DIR.rst13
-rw-r--r--Help/variable/CMAKE_STAGING_PREFIX.rst14
-rw-r--r--Help/variable/CMAKE_STANDARD_LIBRARIES.rst7
-rw-r--r--Help/variable/CMAKE_STATIC_LIBRARY_PREFIX.rst8
-rw-r--r--Help/variable/CMAKE_STATIC_LIBRARY_SUFFIX.rst9
-rw-r--r--Help/variable/CMAKE_STATIC_LINKER_FLAGS.rst6
-rw-r--r--Help/variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG.rst7
-rw-r--r--Help/variable/CMAKE_SYSROOT.rst12
-rw-r--r--Help/variable/CMAKE_SYSTEM.rst10
-rw-r--r--Help/variable/CMAKE_SYSTEM_APPBUNDLE_PATH.rst7
-rw-r--r--Help/variable/CMAKE_SYSTEM_FRAMEWORK_PATH.rst8
-rw-r--r--Help/variable/CMAKE_SYSTEM_IGNORE_PATH.rst18
-rw-r--r--Help/variable/CMAKE_SYSTEM_INCLUDE_PATH.rst8
-rw-r--r--Help/variable/CMAKE_SYSTEM_LIBRARY_PATH.rst8
-rw-r--r--Help/variable/CMAKE_SYSTEM_NAME.rst20
-rw-r--r--Help/variable/CMAKE_SYSTEM_PREFIX_PATH.rst18
-rw-r--r--Help/variable/CMAKE_SYSTEM_PROCESSOR.rst10
-rw-r--r--Help/variable/CMAKE_SYSTEM_PROGRAM_PATH.rst8
-rw-r--r--Help/variable/CMAKE_SYSTEM_VERSION.rst28
-rw-r--r--Help/variable/CMAKE_TOOLCHAIN_FILE.rst9
-rw-r--r--Help/variable/CMAKE_TRY_COMPILE_CONFIGURATION.rst10
-rw-r--r--Help/variable/CMAKE_TWEAK_VERSION.rst11
-rw-r--r--Help/variable/CMAKE_USER_MAKE_RULES_OVERRIDE.rst23
-rw-r--r--Help/variable/CMAKE_USER_MAKE_RULES_OVERRIDE_LANG.rst8
-rw-r--r--Help/variable/CMAKE_USE_RELATIVE_PATHS.rst5
-rw-r--r--Help/variable/CMAKE_VERBOSE_MAKEFILE.rst9
-rw-r--r--Help/variable/CMAKE_VERSION.rst51
-rw-r--r--Help/variable/CMAKE_VISIBILITY_INLINES_HIDDEN.rst5
-rw-r--r--Help/variable/CMAKE_VS_DEVENV_COMMAND.rst14
-rw-r--r--Help/variable/CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD.rst8
-rw-r--r--Help/variable/CMAKE_VS_INTEL_Fortran_PROJECT_VERSION.rst7
-rw-r--r--Help/variable/CMAKE_VS_MSBUILD_COMMAND.rst13
-rw-r--r--Help/variable/CMAKE_VS_MSDEV_COMMAND.rst10
-rw-r--r--Help/variable/CMAKE_VS_NsightTegra_VERSION.rst7
-rw-r--r--Help/variable/CMAKE_VS_PLATFORM_NAME.rst7
-rw-r--r--Help/variable/CMAKE_VS_PLATFORM_TOOLSET.rst10
-rw-r--r--Help/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION.rst12
-rw-r--r--Help/variable/CMAKE_WARN_DEPRECATED.rst10
-rw-r--r--Help/variable/CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION.rst9
-rw-r--r--Help/variable/CMAKE_WIN32_EXECUTABLE.rst7
-rw-r--r--Help/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.rst6
-rw-r--r--Help/variable/CMAKE_XCODE_ATTRIBUTE_an-attribute.rst16
-rw-r--r--Help/variable/CMAKE_XCODE_PLATFORM_TOOLSET.rst9
-rw-r--r--Help/variable/CPACK_ABSOLUTE_DESTINATION_FILES.rst10
-rw-r--r--Help/variable/CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY.rst8
-rw-r--r--Help/variable/CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION.rst11
-rw-r--r--Help/variable/CPACK_INCLUDE_TOPLEVEL_DIRECTORY.rst20
-rw-r--r--Help/variable/CPACK_INSTALL_SCRIPT.rst8
-rw-r--r--Help/variable/CPACK_PACKAGING_INSTALL_PREFIX.rst15
-rw-r--r--Help/variable/CPACK_SET_DESTDIR.rst31
-rw-r--r--Help/variable/CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION.rst9
-rw-r--r--Help/variable/CTEST_BINARY_DIRECTORY.rst5
-rw-r--r--Help/variable/CTEST_BUILD_COMMAND.rst5
-rw-r--r--Help/variable/CTEST_BUILD_NAME.rst5
-rw-r--r--Help/variable/CTEST_BZR_COMMAND.rst5
-rw-r--r--Help/variable/CTEST_BZR_UPDATE_OPTIONS.rst5
-rw-r--r--Help/variable/CTEST_CHANGE_ID.rst9
-rw-r--r--Help/variable/CTEST_CHECKOUT_COMMAND.rst5
-rw-r--r--Help/variable/CTEST_CONFIGURATION_TYPE.rst5
-rw-r--r--Help/variable/CTEST_CONFIGURE_COMMAND.rst5
-rw-r--r--Help/variable/CTEST_COVERAGE_COMMAND.rst60
-rw-r--r--Help/variable/CTEST_COVERAGE_EXTRA_FLAGS.rst5
-rw-r--r--Help/variable/CTEST_CURL_OPTIONS.rst5
-rw-r--r--Help/variable/CTEST_CUSTOM_COVERAGE_EXCLUDE.rst7
-rw-r--r--Help/variable/CTEST_CUSTOM_ERROR_EXCEPTION.rst7
-rw-r--r--Help/variable/CTEST_CUSTOM_ERROR_MATCH.rst7
-rw-r--r--Help/variable/CTEST_CUSTOM_ERROR_POST_CONTEXT.rst7
-rw-r--r--Help/variable/CTEST_CUSTOM_ERROR_PRE_CONTEXT.rst7
-rw-r--r--Help/variable/CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE.rst8
-rw-r--r--Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS.rst8
-rw-r--r--Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS.rst8
-rw-r--r--Help/variable/CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE.rst8
-rw-r--r--Help/variable/CTEST_CUSTOM_MEMCHECK_IGNORE.rst7
-rw-r--r--Help/variable/CTEST_CUSTOM_POST_MEMCHECK.rst6
-rw-r--r--Help/variable/CTEST_CUSTOM_POST_TEST.rst6
-rw-r--r--Help/variable/CTEST_CUSTOM_PRE_MEMCHECK.rst7
-rw-r--r--Help/variable/CTEST_CUSTOM_PRE_TEST.rst6
-rw-r--r--Help/variable/CTEST_CUSTOM_TEST_IGNORE.rst7
-rw-r--r--Help/variable/CTEST_CUSTOM_WARNING_EXCEPTION.rst7
-rw-r--r--Help/variable/CTEST_CUSTOM_WARNING_MATCH.rst7
-rw-r--r--Help/variable/CTEST_CUSTOM_XXX.txt2
-rw-r--r--Help/variable/CTEST_CVS_CHECKOUT.rst4
-rw-r--r--Help/variable/CTEST_CVS_COMMAND.rst5
-rw-r--r--Help/variable/CTEST_CVS_UPDATE_OPTIONS.rst5
-rw-r--r--Help/variable/CTEST_DROP_LOCATION.rst5
-rw-r--r--Help/variable/CTEST_DROP_METHOD.rst5
-rw-r--r--Help/variable/CTEST_DROP_SITE.rst5
-rw-r--r--Help/variable/CTEST_DROP_SITE_CDASH.rst5
-rw-r--r--Help/variable/CTEST_DROP_SITE_PASSWORD.rst5
-rw-r--r--Help/variable/CTEST_DROP_SITE_USER.rst5
-rw-r--r--Help/variable/CTEST_EXTRA_COVERAGE_GLOB.rst7
-rw-r--r--Help/variable/CTEST_GIT_COMMAND.rst5
-rw-r--r--Help/variable/CTEST_GIT_UPDATE_CUSTOM.rst5
-rw-r--r--Help/variable/CTEST_GIT_UPDATE_OPTIONS.rst5
-rw-r--r--Help/variable/CTEST_HG_COMMAND.rst5
-rw-r--r--Help/variable/CTEST_HG_UPDATE_OPTIONS.rst5
-rw-r--r--Help/variable/CTEST_MEMORYCHECK_COMMAND.rst5
-rw-r--r--Help/variable/CTEST_MEMORYCHECK_COMMAND_OPTIONS.rst5
-rw-r--r--Help/variable/CTEST_MEMORYCHECK_SANITIZER_OPTIONS.rst5
-rw-r--r--Help/variable/CTEST_MEMORYCHECK_SUPPRESSIONS_FILE.rst5
-rw-r--r--Help/variable/CTEST_MEMORYCHECK_TYPE.rst8
-rw-r--r--Help/variable/CTEST_NIGHTLY_START_TIME.rst5
-rw-r--r--Help/variable/CTEST_P4_CLIENT.rst5
-rw-r--r--Help/variable/CTEST_P4_COMMAND.rst5
-rw-r--r--Help/variable/CTEST_P4_OPTIONS.rst5
-rw-r--r--Help/variable/CTEST_P4_UPDATE_OPTIONS.rst5
-rw-r--r--Help/variable/CTEST_SCP_COMMAND.rst5
-rw-r--r--Help/variable/CTEST_SITE.rst5
-rw-r--r--Help/variable/CTEST_SOURCE_DIRECTORY.rst5
-rw-r--r--Help/variable/CTEST_SVN_COMMAND.rst5
-rw-r--r--Help/variable/CTEST_SVN_OPTIONS.rst5
-rw-r--r--Help/variable/CTEST_SVN_UPDATE_OPTIONS.rst5
-rw-r--r--Help/variable/CTEST_TEST_LOAD.rst7
-rw-r--r--Help/variable/CTEST_TEST_TIMEOUT.rst5
-rw-r--r--Help/variable/CTEST_TRIGGER_SITE.rst5
-rw-r--r--Help/variable/CTEST_UPDATE_COMMAND.rst5
-rw-r--r--Help/variable/CTEST_UPDATE_OPTIONS.rst5
-rw-r--r--Help/variable/CTEST_UPDATE_VERSION_ONLY.rst5
-rw-r--r--Help/variable/CTEST_USE_LAUNCHERS.rst5
-rw-r--r--Help/variable/CYGWIN.rst6
-rw-r--r--Help/variable/ENV.rst7
-rw-r--r--Help/variable/EXECUTABLE_OUTPUT_PATH.rst8
-rw-r--r--Help/variable/GHS-MULTI.rst4
-rw-r--r--Help/variable/LIBRARY_OUTPUT_PATH.rst9
-rw-r--r--Help/variable/MINGW.rst6
-rw-r--r--Help/variable/MSVC.rst6
-rw-r--r--Help/variable/MSVC10.rst6
-rw-r--r--Help/variable/MSVC11.rst6
-rw-r--r--Help/variable/MSVC12.rst6
-rw-r--r--Help/variable/MSVC14.rst6
-rw-r--r--Help/variable/MSVC60.rst6
-rw-r--r--Help/variable/MSVC70.rst6
-rw-r--r--Help/variable/MSVC71.rst6
-rw-r--r--Help/variable/MSVC80.rst6
-rw-r--r--Help/variable/MSVC90.rst6
-rw-r--r--Help/variable/MSVC_IDE.rst7
-rw-r--r--Help/variable/MSVC_VERSION.rst16
-rw-r--r--Help/variable/PROJECT-NAME_BINARY_DIR.rst8
-rw-r--r--Help/variable/PROJECT-NAME_SOURCE_DIR.rst8
-rw-r--r--Help/variable/PROJECT-NAME_VERSION.rst11
-rw-r--r--Help/variable/PROJECT-NAME_VERSION_MAJOR.rst5
-rw-r--r--Help/variable/PROJECT-NAME_VERSION_MINOR.rst5
-rw-r--r--Help/variable/PROJECT-NAME_VERSION_PATCH.rst5
-rw-r--r--Help/variable/PROJECT-NAME_VERSION_TWEAK.rst5
-rw-r--r--Help/variable/PROJECT_BINARY_DIR.rst6
-rw-r--r--Help/variable/PROJECT_NAME.rst6
-rw-r--r--Help/variable/PROJECT_SOURCE_DIR.rst6
-rw-r--r--Help/variable/PROJECT_VERSION.rst11
-rw-r--r--Help/variable/PROJECT_VERSION_MAJOR.rst5
-rw-r--r--Help/variable/PROJECT_VERSION_MINOR.rst5
-rw-r--r--Help/variable/PROJECT_VERSION_PATCH.rst5
-rw-r--r--Help/variable/PROJECT_VERSION_TWEAK.rst5
-rw-r--r--Help/variable/UNIX.rst7
-rw-r--r--Help/variable/WIN32.rst6
-rw-r--r--Help/variable/WINCE.rst5
-rw-r--r--Help/variable/WINDOWS_PHONE.rst5
-rw-r--r--Help/variable/WINDOWS_STORE.rst5
-rw-r--r--Help/variable/XCODE_VERSION.rst7
-rw-r--r--Licenses/LGPLv2.1.txt502
-rw-r--r--Licenses/README.rst7
-rw-r--r--Modules/AddFileDependencies.cmake8
-rw-r--r--Modules/AutogenInfo.cmake.in26
-rw-r--r--Modules/AutomocInfo.cmake.in14
-rw-r--r--Modules/BasicConfigVersion-AnyNewerVersion.cmake.in8
-rw-r--r--Modules/BasicConfigVersion-ExactVersion.cmake.in12
-rw-r--r--Modules/BasicConfigVersion-SameMajorVersion.cmake.in10
-rw-r--r--Modules/BundleUtilities.cmake453
-rw-r--r--Modules/CMakeASMInformation.cmake20
-rw-r--r--Modules/CMakeASM_MASMInformation.cmake2
-rw-r--r--Modules/CMakeAddFortranSubdirectory.cmake60
-rw-r--r--Modules/CMakeBackwardCompatibilityCXX.cmake27
-rw-r--r--Modules/CMakeCCompiler.cmake.in19
-rw-r--r--Modules/CMakeCCompilerId.c.in228
-rw-r--r--Modules/CMakeCInformation.cmake24
-rw-r--r--Modules/CMakeCXXCompiler.cmake.in19
-rw-r--r--Modules/CMakeCXXCompilerId.cpp.in221
-rw-r--r--Modules/CMakeCXXInformation.cmake25
-rw-r--r--Modules/CMakeCheckCompilerFlagCommonPatterns.cmake45
-rw-r--r--Modules/CMakeClDeps.cmake34
-rw-r--r--Modules/CMakeCommonLanguageInclude.cmake24
-rw-r--r--Modules/CMakeCompilerIdDetection.cmake158
-rw-r--r--Modules/CMakeConfigurableFile.in1
-rw-r--r--Modules/CMakeDependentOption.cmake30
-rw-r--r--Modules/CMakeDetermineASMCompiler.cmake27
-rw-r--r--Modules/CMakeDetermineASM_MASMCompiler.cmake3
-rw-r--r--Modules/CMakeDetermineCCompiler.cmake67
-rw-r--r--Modules/CMakeDetermineCXXCompiler.cmake66
-rw-r--r--Modules/CMakeDetermineCompileFeatures.cmake94
-rw-r--r--Modules/CMakeDetermineCompiler.cmake61
-rw-r--r--Modules/CMakeDetermineCompilerABI.cmake24
-rw-r--r--Modules/CMakeDetermineCompilerId.cmake384
-rw-r--r--Modules/CMakeDetermineFortranCompiler.cmake110
-rw-r--r--Modules/CMakeDetermineJavaCompiler.cmake8
-rw-r--r--Modules/CMakeDetermineRCCompiler.cmake4
-rw-r--r--Modules/CMakeDetermineSwiftCompiler.cmake53
-rw-r--r--Modules/CMakeDetermineSystem.cmake19
-rw-r--r--Modules/CMakeDetermineVSServicePack.cmake91
-rw-r--r--Modules/CMakeExpandImportedTargets.cmake59
-rw-r--r--Modules/CMakeExportBuildSettings.cmake4
-rw-r--r--Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake15
-rw-r--r--Modules/CMakeFindBinUtils.cmake21
-rw-r--r--Modules/CMakeFindDependencyMacro.cmake85
-rw-r--r--Modules/CMakeFindEclipseCDT4.cmake48
-rw-r--r--Modules/CMakeFindFrameworks.cmake6
-rw-r--r--Modules/CMakeFindJavaCommon.cmake41
-rw-r--r--Modules/CMakeFindKate.cmake31
-rw-r--r--Modules/CMakeFindPackageMode.cmake43
-rw-r--r--Modules/CMakeFindXCode.cmake8
-rw-r--r--Modules/CMakeForceCompiler.cmake71
-rw-r--r--Modules/CMakeFortranCompiler.cmake.in4
-rw-r--r--Modules/CMakeFortranCompilerABI.F8
-rw-r--r--Modules/CMakeFortranCompilerId.F.in91
-rw-r--r--Modules/CMakeFortranInformation.cmake24
-rw-r--r--Modules/CMakeGenericSystem.cmake5
-rw-r--r--Modules/CMakeGraphVizOptions.cmake178
-rw-r--r--Modules/CMakeIOSInstallCombined.cmake307
-rw-r--r--Modules/CMakeImportBuildSettings.cmake3
-rw-r--r--Modules/CMakeLanguageInformation.cmake37
-rw-r--r--Modules/CMakeNinjaFindMake.cmake3
-rw-r--r--Modules/CMakePackageConfigHelpers.cmake351
-rw-r--r--Modules/CMakeParseArguments.cmake131
-rw-r--r--Modules/CMakeParseImplicitLinkInfo.cmake13
-rw-r--r--Modules/CMakePlatformId.h.in57
-rw-r--r--Modules/CMakePrintHelpers.cmake47
-rw-r--r--Modules/CMakePrintSystemInformation.cmake12
-rw-r--r--Modules/CMakePushCheckState.cmake58
-rw-r--r--Modules/CMakeRCCompiler.cmake.in2
-rw-r--r--Modules/CMakeRCInformation.cmake13
-rw-r--r--Modules/CMakeSwiftCompiler.cmake.in5
-rw-r--r--Modules/CMakeSwiftInformation.cmake41
-rw-r--r--Modules/CMakeSystemSpecificInitialize.cmake20
-rw-r--r--Modules/CMakeTestCCompiler.cmake5
-rw-r--r--Modules/CMakeTestCXXCompiler.cmake5
-rw-r--r--Modules/CMakeTestFortranCompiler.cmake2
-rw-r--r--Modules/CMakeTestSwiftCompiler.cmake65
-rw-r--r--Modules/CMakeVS10FindMake.cmake54
-rw-r--r--Modules/CMakeVS11FindMake.cmake53
-rw-r--r--Modules/CMakeVS12FindMake.cmake27
-rw-r--r--Modules/CMakeVS6FindMake.cmake25
-rw-r--r--Modules/CMakeVS71FindMake.cmake26
-rw-r--r--Modules/CMakeVS7FindMake.cmake25
-rw-r--r--Modules/CMakeVS8FindMake.cmake34
-rw-r--r--Modules/CMakeVS9FindMake.cmake39
-rw-r--r--Modules/CMakeVerifyManifest.cmake23
-rw-r--r--Modules/CPack.cmake725
-rw-r--r--Modules/CPackBundle.cmake94
-rw-r--r--Modules/CPackComponent.cmake604
-rw-r--r--Modules/CPackCygwin.cmake44
-rw-r--r--Modules/CPackDMG.cmake150
-rw-r--r--Modules/CPackDeb.cmake1067
-rw-r--r--Modules/CPackIFW.cmake614
-rw-r--r--Modules/CPackNSIS.cmake252
-rw-r--r--Modules/CPackPackageMaker.cmake44
-rw-r--r--Modules/CPackRPM.cmake2434
-rw-r--r--Modules/CPackWIX.cmake289
-rw-r--r--Modules/CTest.cmake102
-rw-r--r--Modules/CTestCoverageCollectGCOV.cmake204
-rw-r--r--Modules/CTestScriptMode.cmake6
-rw-r--r--Modules/CTestTargets.cmake3
-rw-r--r--Modules/CTestUseLaunchers.cmake60
-rw-r--r--Modules/CheckCCompilerFlag.cmake45
-rw-r--r--Modules/CheckCSourceCompiles.cmake49
-rw-r--r--Modules/CheckCSourceRuns.cmake49
-rw-r--r--Modules/CheckCXXCompilerFlag.cmake47
-rw-r--r--Modules/CheckCXXSourceCompiles.cmake49
-rw-r--r--Modules/CheckCXXSourceRuns.cmake49
-rw-r--r--Modules/CheckCXXSymbolExists.cmake43
-rw-r--r--Modules/CheckForPthreads.c6
-rw-r--r--Modules/CheckFortranCompilerFlag.cmake66
-rw-r--r--Modules/CheckFortranFunctionExists.cmake26
-rw-r--r--Modules/CheckFortranSourceCompiles.cmake111
-rw-r--r--Modules/CheckFunctionExists.c3
-rw-r--r--Modules/CheckFunctionExists.cmake55
-rw-r--r--Modules/CheckIncludeFile.cmake56
-rw-r--r--Modules/CheckIncludeFileCXX.cmake53
-rw-r--r--Modules/CheckIncludeFiles.cmake55
-rw-r--r--Modules/CheckLanguage.cmake33
-rw-r--r--Modules/CheckLibraryExists.cmake60
-rw-r--r--Modules/CheckPrototypeDefinition.cmake61
-rw-r--r--Modules/CheckStructHasMember.cmake67
-rw-r--r--Modules/CheckSymbolExists.cmake67
-rw-r--r--Modules/CheckTypeSize.cmake165
-rw-r--r--Modules/CheckVariableExists.cmake48
-rw-r--r--Modules/Compiler/ADSP-DetermineCompiler.cmake10
-rw-r--r--Modules/Compiler/ARMCC-ASM.cmake7
-rw-r--r--Modules/Compiler/ARMCC-C.cmake2
-rw-r--r--Modules/Compiler/ARMCC-CXX.cmake2
-rw-r--r--Modules/Compiler/ARMCC-DetermineCompiler.cmake16
-rw-r--r--Modules/Compiler/ARMCC.cmake36
-rw-r--r--Modules/Compiler/AppleClang-ASM.cmake1
-rw-r--r--Modules/Compiler/AppleClang-C-FeatureTests.cmake11
-rw-r--r--Modules/Compiler/AppleClang-C.cmake42
-rw-r--r--Modules/Compiler/AppleClang-CXX-FeatureTests.cmake52
-rw-r--r--Modules/Compiler/AppleClang-CXX.cmake56
-rw-r--r--Modules/Compiler/AppleClang-DetermineCompiler.cmake7
-rw-r--r--Modules/Compiler/Borland-DetermineCompiler.cmake7
-rw-r--r--Modules/Compiler/CCur-Fortran.cmake1
-rw-r--r--Modules/Compiler/Clang-C-FeatureTests.cmake11
-rw-r--r--Modules/Compiler/Clang-C.cmake49
-rw-r--r--Modules/Compiler/Clang-CXX-FeatureTests.cmake34
-rw-r--r--Modules/Compiler/Clang-CXX-TestableFeatures.cmake54
-rw-r--r--Modules/Compiler/Clang-CXX.cmake59
-rw-r--r--Modules/Compiler/Clang-DetermineCompiler.cmake4
-rw-r--r--Modules/Compiler/Clang-DetermineCompilerInternal.cmake15
-rw-r--r--Modules/Compiler/Clang.cmake27
-rw-r--r--Modules/Compiler/Comeau-CXX-DetermineCompiler.cmake7
-rw-r--r--Modules/Compiler/Compaq-C-DetermineCompiler.cmake8
-rw-r--r--Modules/Compiler/Compaq-CXX-DetermineCompiler.cmake8
-rw-r--r--Modules/Compiler/Cray-DetermineCompiler.cmake6
-rw-r--r--Modules/Compiler/CrayPrgEnv-C.cmake11
-rw-r--r--Modules/Compiler/CrayPrgEnv-CXX.cmake11
-rw-r--r--Modules/Compiler/CrayPrgEnv-Cray-C.cmake7
-rw-r--r--Modules/Compiler/CrayPrgEnv-Cray-CXX.cmake7
-rw-r--r--Modules/Compiler/CrayPrgEnv-Cray-Fortran.cmake7
-rw-r--r--Modules/Compiler/CrayPrgEnv-Fortran.cmake11
-rw-r--r--Modules/Compiler/CrayPrgEnv-GNU-C.cmake7
-rw-r--r--Modules/Compiler/CrayPrgEnv-GNU-CXX.cmake7
-rw-r--r--Modules/Compiler/CrayPrgEnv-GNU-Fortran.cmake7
-rw-r--r--Modules/Compiler/CrayPrgEnv-Intel-C.cmake7
-rw-r--r--Modules/Compiler/CrayPrgEnv-Intel-CXX.cmake7
-rw-r--r--Modules/Compiler/CrayPrgEnv-Intel-Fortran.cmake7
-rw-r--r--Modules/Compiler/CrayPrgEnv-PGI-C.cmake7
-rw-r--r--Modules/Compiler/CrayPrgEnv-PGI-CXX.cmake7
-rw-r--r--Modules/Compiler/CrayPrgEnv-PGI-Fortran.cmake7
-rw-r--r--Modules/Compiler/CrayPrgEnv.cmake91
-rw-r--r--Modules/Compiler/Embarcadero-DetermineCompiler.cmake7
-rw-r--r--Modules/Compiler/Fujitsu-DetermineCompiler.cmake2
-rw-r--r--Modules/Compiler/GHS-C.cmake27
-rw-r--r--Modules/Compiler/GHS-CXX.cmake31
-rw-r--r--Modules/Compiler/GHS-DetermineCompiler.cmake6
-rw-r--r--Modules/Compiler/GNU-C-FeatureTests.cmake17
-rw-r--r--Modules/Compiler/GNU-C.cmake57
-rw-r--r--Modules/Compiler/GNU-CXX-FeatureTests.cmake109
-rw-r--r--Modules/Compiler/GNU-CXX.cmake54
-rw-r--r--Modules/Compiler/GNU-DetermineCompiler.cmake11
-rw-r--r--Modules/Compiler/GNU-Fortran.cmake6
-rw-r--r--Modules/Compiler/GNU.cmake5
-rw-r--r--Modules/Compiler/HP-C-DetermineCompiler.cmake8
-rw-r--r--Modules/Compiler/HP-C.cmake4
-rw-r--r--Modules/Compiler/HP-CXX-DetermineCompiler.cmake8
-rw-r--r--Modules/Compiler/HP-CXX.cmake13
-rw-r--r--Modules/Compiler/HP-Fortran.cmake3
-rw-r--r--Modules/Compiler/IAR-ASM.cmake2
-rw-r--r--Modules/Compiler/IAR-C.cmake6
-rw-r--r--Modules/Compiler/IAR-CXX.cmake6
-rw-r--r--Modules/Compiler/IAR-DetermineCompiler.cmake4
-rw-r--r--Modules/Compiler/IAR.cmake4
-rw-r--r--Modules/Compiler/IBMCPP-C-DetermineVersionInternal.cmake6
-rw-r--r--Modules/Compiler/IBMCPP-CXX-DetermineVersionInternal.cmake6
-rw-r--r--Modules/Compiler/Intel-C.cmake8
-rw-r--r--Modules/Compiler/Intel-CXX.cmake8
-rw-r--r--Modules/Compiler/Intel-DetermineCompiler.cmake26
-rw-r--r--Modules/Compiler/Intel-Fortran.cmake3
-rw-r--r--Modules/Compiler/MIPSpro-DetermineCompiler.cmake15
-rw-r--r--Modules/Compiler/MSVC-CXX-FeatureTests.cmake111
-rw-r--r--Modules/Compiler/MSVC-CXX.cmake9
-rw-r--r--Modules/Compiler/MSVC-DetermineCompiler.cmake19
-rw-r--r--Modules/Compiler/OpenWatcom-DetermineCompiler.cmake10
-rw-r--r--Modules/Compiler/PGI-DetermineCompiler.cmake9
-rw-r--r--Modules/Compiler/PGI-Fortran.cmake5
-rw-r--r--Modules/Compiler/PGI.cmake4
-rw-r--r--Modules/Compiler/PathScale-DetermineCompiler.cmake9
-rw-r--r--Modules/Compiler/QCC-C.cmake2
-rw-r--r--Modules/Compiler/QCC-CXX.cmake12
-rw-r--r--Modules/Compiler/QCC.cmake24
-rw-r--r--Modules/Compiler/SCO-DetermineCompiler.cmake2
-rw-r--r--Modules/Compiler/SDCC-C-DetermineCompiler.cmake10
-rw-r--r--Modules/Compiler/SunPro-C-DetermineCompiler.cmake15
-rw-r--r--Modules/Compiler/SunPro-C.cmake5
-rw-r--r--Modules/Compiler/SunPro-CXX-DetermineCompiler.cmake15
-rw-r--r--Modules/Compiler/SunPro-CXX-FeatureTests.cmake52
-rw-r--r--Modules/Compiler/SunPro-CXX.cmake36
-rw-r--r--Modules/Compiler/SunPro-Fortran.cmake4
-rw-r--r--Modules/Compiler/TI-ASM.cmake2
-rw-r--r--Modules/Compiler/TI-C.cmake6
-rw-r--r--Modules/Compiler/TI-CXX.cmake6
-rw-r--r--Modules/Compiler/TI-DetermineCompiler.cmake8
-rw-r--r--Modules/Compiler/TinyCC-C-DetermineCompiler.cmake2
-rw-r--r--Modules/Compiler/VisualAge-C-DetermineCompiler.cmake4
-rw-r--r--Modules/Compiler/VisualAge-CXX-DetermineCompiler.cmake4
-rw-r--r--Modules/Compiler/Watcom-DetermineCompiler.cmake10
-rw-r--r--Modules/Compiler/XL-ASM.cmake3
-rw-r--r--Modules/Compiler/XL-C-DetermineCompiler.cmake4
-rw-r--r--Modules/Compiler/XL-C.cmake3
-rw-r--r--Modules/Compiler/XL-CXX-DetermineCompiler.cmake4
-rw-r--r--Modules/Compiler/XL-CXX.cmake2
-rw-r--r--Modules/Compiler/XL-Fortran.cmake2
-rw-r--r--Modules/Compiler/XL.cmake4
-rw-r--r--Modules/Compiler/zOS-C-DetermineCompiler.cmake4
-rw-r--r--Modules/Compiler/zOS-CXX-DetermineCompiler.cmake4
-rw-r--r--Modules/CompilerId/VS-10.vcxproj.in4
-rw-r--r--Modules/CompilerId/VS-Intel.vfproj.in42
-rw-r--r--Modules/CompilerId/VS-NsightTegra.vcxproj.in56
-rw-r--r--Modules/CompilerId/Xcode-3.pbxproj.in6
-rw-r--r--Modules/CompilerId/main.swift.in1
-rw-r--r--Modules/Dart.cmake24
-rw-r--r--Modules/DartConfiguration.tcl.in17
-rw-r--r--Modules/DeployQt4.cmake205
-rw-r--r--Modules/Documentation.cmake11
-rw-r--r--Modules/ExternalData.cmake649
-rw-r--r--Modules/ExternalData_config.cmake.in2
-rw-r--r--Modules/ExternalProject.cmake1196
-rw-r--r--Modules/FeatureSummary.cmake460
-rw-r--r--Modules/FindALSA.cmake26
-rw-r--r--Modules/FindASPELL.cmake19
-rw-r--r--Modules/FindAVIFile.cmake25
-rw-r--r--Modules/FindArmadillo.cmake38
-rw-r--r--Modules/FindBISON.cmake186
-rw-r--r--Modules/FindBLAS.cmake172
-rw-r--r--Modules/FindBZip2.cmake29
-rw-r--r--Modules/FindBacktrace.cmake101
-rw-r--r--Modules/FindBoost.cmake960
-rw-r--r--Modules/FindBullet.cmake37
-rw-r--r--Modules/FindCABLE.cmake24
-rw-r--r--Modules/FindCUDA.cmake855
-rw-r--r--Modules/FindCUDA/make2cmake.cmake5
-rw-r--r--Modules/FindCUDA/parse_cubin.cmake15
-rw-r--r--Modules/FindCUDA/run_nvcc.cmake8
-rw-r--r--Modules/FindCURL.cmake17
-rw-r--r--Modules/FindCVS.cmake25
-rw-r--r--Modules/FindCoin3D.cmake20
-rw-r--r--Modules/FindCups.cmake30
-rw-r--r--Modules/FindCurses.cmake198
-rw-r--r--Modules/FindCxxTest.cmake196
-rw-r--r--Modules/FindCygwin.cmake5
-rw-r--r--Modules/FindDCMTK.cmake278
-rw-r--r--Modules/FindDart.cmake10
-rw-r--r--Modules/FindDevIL.cmake43
-rw-r--r--Modules/FindDoxygen.cmake53
-rw-r--r--Modules/FindEXPAT.cmake20
-rw-r--r--Modules/FindFLEX.cmake192
-rw-r--r--Modules/FindFLTK.cmake84
-rw-r--r--Modules/FindFLTK2.cmake47
-rw-r--r--Modules/FindFreetype.cmake117
-rw-r--r--Modules/FindGCCXML.cmake13
-rw-r--r--Modules/FindGDAL.cmake24
-rw-r--r--Modules/FindGIF.cmake22
-rw-r--r--Modules/FindGLEW.cmake32
-rw-r--r--Modules/FindGLUT.cmake100
-rw-r--r--Modules/FindGSL.cmake238
-rw-r--r--Modules/FindGTK.cmake17
-rw-r--r--Modules/FindGTK2.cmake587
-rw-r--r--Modules/FindGTest.cmake196
-rw-r--r--Modules/FindGettext.cmake79
-rw-r--r--Modules/FindGit.cmake41
-rw-r--r--Modules/FindGnuTLS.cmake18
-rw-r--r--Modules/FindGnuplot.cmake18
-rw-r--r--Modules/FindHDF5.cmake154
-rw-r--r--Modules/FindHSPELL.cmake27
-rw-r--r--Modules/FindHTMLHelp.cmake15
-rw-r--r--Modules/FindHg.cmake76
-rw-r--r--Modules/FindITK.cmake57
-rw-r--r--Modules/FindIce.cmake521
-rw-r--r--Modules/FindIcotool.cmake21
-rw-r--r--Modules/FindImageMagick.cmake144
-rw-r--r--Modules/FindIntl.cmake69
-rw-r--r--Modules/FindJNI.cmake186
-rw-r--r--Modules/FindJPEG.cmake27
-rw-r--r--Modules/FindJasper.cmake17
-rw-r--r--Modules/FindJava.cmake180
-rw-r--r--Modules/FindKDE3.cmake157
-rw-r--r--Modules/FindKDE4.cmake29
-rw-r--r--Modules/FindLAPACK.cmake157
-rw-r--r--Modules/FindLATEX.cmake196
-rw-r--r--Modules/FindLibArchive.cmake17
-rw-r--r--Modules/FindLibLZMA.cmake32
-rw-r--r--Modules/FindLibXml2.cmake21
-rw-r--r--Modules/FindLibXslt.cmake30
-rw-r--r--Modules/FindLua.cmake171
-rw-r--r--Modules/FindLua50.cmake36
-rw-r--r--Modules/FindLua51.cmake40
-rw-r--r--Modules/FindMFC.cmake19
-rw-r--r--Modules/FindMPEG.cmake24
-rw-r--r--Modules/FindMPEG2.cmake24
-rw-r--r--Modules/FindMPI.cmake207
-rw-r--r--Modules/FindMatlab.cmake1517
-rw-r--r--Modules/FindMotif.cmake16
-rw-r--r--Modules/FindOpenAL.cmake31
-rw-r--r--Modules/FindOpenCL.cmake136
-rw-r--r--Modules/FindOpenGL.cmake71
-rw-r--r--Modules/FindOpenMP.cmake92
-rw-r--r--Modules/FindOpenSSL.cmake219
-rw-r--r--Modules/FindOpenSceneGraph.cmake117
-rw-r--r--Modules/FindOpenThreads.cmake30
-rw-r--r--Modules/FindPHP4.cmake20
-rw-r--r--Modules/FindPNG.cmake86
-rw-r--r--Modules/FindPackageHandleStandardArgs.cmake283
-rw-r--r--Modules/FindPackageMessage.cmake38
-rw-r--r--Modules/FindPerl.cmake19
-rw-r--r--Modules/FindPerlLibs.cmake50
-rw-r--r--Modules/FindPhysFS.cmake19
-rw-r--r--Modules/FindPike.cmake18
-rw-r--r--Modules/FindPkgConfig.cmake423
-rw-r--r--Modules/FindPostgreSQL.cmake80
-rw-r--r--Modules/FindProducer.cmake41
-rw-r--r--Modules/FindProtobuf.cmake174
-rw-r--r--Modules/FindPythonInterp.cmake92
-rw-r--r--Modules/FindPythonLibs.cmake193
-rw-r--r--Modules/FindQt.cmake59
-rw-r--r--Modules/FindQt3.cmake48
-rw-r--r--Modules/FindQt4.cmake804
-rw-r--r--Modules/FindQuickTime.cmake14
-rw-r--r--Modules/FindRTI.cmake37
-rw-r--r--Modules/FindRuby.cmake76
-rw-r--r--Modules/FindSDL.cmake109
-rw-r--r--Modules/FindSDL_image.cmake51
-rw-r--r--Modules/FindSDL_mixer.cmake51
-rw-r--r--Modules/FindSDL_net.cmake50
-rw-r--r--Modules/FindSDL_sound.cmake120
-rw-r--r--Modules/FindSDL_ttf.cmake50
-rw-r--r--Modules/FindSWIG.cmake40
-rw-r--r--Modules/FindSelfPackers.cmake17
-rw-r--r--Modules/FindSquish.cmake151
-rw-r--r--Modules/FindSubversion.cmake79
-rw-r--r--Modules/FindTCL.cmake72
-rw-r--r--Modules/FindTIFF.cmake90
-rw-r--r--Modules/FindTclStub.cmake60
-rw-r--r--Modules/FindTclsh.cmake25
-rw-r--r--Modules/FindThreads.cmake221
-rw-r--r--Modules/FindUnixCommands.cmake16
-rw-r--r--Modules/FindVTK.cmake141
-rw-r--r--Modules/FindWget.cmake17
-rw-r--r--Modules/FindWish.cmake19
-rw-r--r--Modules/FindX11.cmake91
-rw-r--r--Modules/FindXCTest.cmake196
-rw-r--r--Modules/FindXMLRPC.cmake53
-rw-r--r--Modules/FindXalanC.cmake162
-rw-r--r--Modules/FindXercesC.cmake140
-rw-r--r--Modules/FindZLIB.cmake108
-rw-r--r--Modules/Findosg.cmake60
-rw-r--r--Modules/FindosgAnimation.cmake52
-rw-r--r--Modules/FindosgDB.cmake52
-rw-r--r--Modules/FindosgFX.cmake52
-rw-r--r--Modules/FindosgGA.cmake52
-rw-r--r--Modules/FindosgIntrospection.cmake39
-rw-r--r--Modules/FindosgManipulator.cmake39
-rw-r--r--Modules/FindosgParticle.cmake44
-rw-r--r--Modules/FindosgPresentation.cmake43
-rw-r--r--Modules/FindosgProducer.cmake44
-rw-r--r--Modules/FindosgQt.cmake57
-rw-r--r--Modules/FindosgShadow.cmake52
-rw-r--r--Modules/FindosgSim.cmake52
-rw-r--r--Modules/FindosgTerrain.cmake52
-rw-r--r--Modules/FindosgText.cmake52
-rw-r--r--Modules/FindosgUtil.cmake52
-rw-r--r--Modules/FindosgViewer.cmake52
-rw-r--r--Modules/FindosgVolume.cmake52
-rw-r--r--Modules/FindosgWidget.cmake57
-rw-r--r--Modules/Findosg_functions.cmake8
-rw-r--r--Modules/FindwxWidgets.cmake216
-rw-r--r--Modules/FindwxWindows.cmake104
-rw-r--r--Modules/FortranCInterface.cmake167
-rw-r--r--Modules/FortranCInterface/CMakeLists.txt4
-rw-r--r--Modules/FortranCInterface/Detect.cmake9
-rw-r--r--Modules/FortranCInterface/Verify/CMakeLists.txt2
-rw-r--r--Modules/GNUInstallDirs.cmake254
-rw-r--r--Modules/GenerateExportHeader.cmake282
-rw-r--r--Modules/GetPrerequisites.cmake365
-rw-r--r--Modules/InstallRequiredSystemLibraries.cmake183
-rw-r--r--Modules/IntelVSImplicitPath/CMakeLists.txt2
-rw-r--r--Modules/Internal/FeatureTesting.cmake60
-rw-r--r--Modules/MacroAddFileDependencies.cmake18
-rw-r--r--Modules/MatlabTestsRedirect.cmake91
-rw-r--r--Modules/NSIS.template.in2
-rw-r--r--Modules/Platform/AIX-GNU.cmake12
-rw-r--r--Modules/Platform/AIX-XL.cmake12
-rw-r--r--Modules/Platform/ARTOS-GNU-C.cmake9
-rw-r--r--Modules/Platform/ARTOS.cmake17
-rw-r--r--Modules/Platform/Android.cmake15
-rw-r--r--Modules/Platform/BlueGeneQ-base.cmake177
-rw-r--r--Modules/Platform/BlueGeneQ-dynamic-GNU-C.cmake16
-rw-r--r--Modules/Platform/BlueGeneQ-dynamic-GNU-CXX.cmake16
-rw-r--r--Modules/Platform/BlueGeneQ-dynamic-GNU-Fortran.cmake16
-rw-r--r--Modules/Platform/BlueGeneQ-dynamic-XL-C.cmake16
-rw-r--r--Modules/Platform/BlueGeneQ-dynamic-XL-CXX.cmake16
-rw-r--r--Modules/Platform/BlueGeneQ-dynamic-XL-Fortran.cmake16
-rw-r--r--Modules/Platform/BlueGeneQ-dynamic.cmake17
-rw-r--r--Modules/Platform/BlueGeneQ-static-GNU-C.cmake16
-rw-r--r--Modules/Platform/BlueGeneQ-static-GNU-CXX.cmake16
-rw-r--r--Modules/Platform/BlueGeneQ-static-GNU-Fortran.cmake16
-rw-r--r--Modules/Platform/BlueGeneQ-static-XL-C.cmake16
-rw-r--r--Modules/Platform/BlueGeneQ-static-XL-CXX.cmake16
-rw-r--r--Modules/Platform/BlueGeneQ-static-XL-Fortran.cmake16
-rw-r--r--Modules/Platform/BlueGeneQ-static.cmake17
-rw-r--r--Modules/Platform/CYGWIN-GNU.cmake7
-rw-r--r--Modules/Platform/CYGWIN-windres.cmake2
-rw-r--r--Modules/Platform/CrayLinuxEnvironment.cmake143
-rw-r--r--Modules/Platform/Darwin-AppleClang-C.cmake6
-rw-r--r--Modules/Platform/Darwin-AppleClang-CXX.cmake6
-rw-r--r--Modules/Platform/Darwin-Clang.cmake3
-rw-r--r--Modules/Platform/Darwin-GNU-Fortran.cmake2
-rw-r--r--Modules/Platform/Darwin-GNU.cmake4
-rw-r--r--Modules/Platform/Darwin-Initialize.cmake155
-rw-r--r--Modules/Platform/Darwin-Intel-C.cmake2
-rw-r--r--Modules/Platform/Darwin-Intel-CXX.cmake2
-rw-r--r--Modules/Platform/Darwin-Intel-Fortran.cmake3
-rw-r--r--Modules/Platform/Darwin-Intel.cmake29
-rw-r--r--Modules/Platform/Darwin-NAG-Fortran.cmake2
-rw-r--r--Modules/Platform/Darwin-icc.cmake131
-rw-r--r--Modules/Platform/Darwin-icpc.cmake3
-rw-r--r--Modules/Platform/Darwin.cmake172
-rw-r--r--Modules/Platform/Euros.cmake19
-rw-r--r--Modules/Platform/GHS-MULTI-Initialize.cmake51
-rw-r--r--Modules/Platform/GHS-MULTI.cmake27
-rw-r--r--Modules/Platform/Generic-SDCC-C.cmake2
-rw-r--r--Modules/Platform/HP-UX-GNU-ASM.cmake2
-rw-r--r--Modules/Platform/HP-UX-GNU.cmake4
-rw-r--r--Modules/Platform/HP-UX-HP-C.cmake6
-rw-r--r--Modules/Platform/HP-UX-HP-CXX.cmake4
-rw-r--r--Modules/Platform/HP-UX-HP-Fortran.cmake3
-rw-r--r--Modules/Platform/HP-UX-HP.cmake4
-rw-r--r--Modules/Platform/HP-UX.cmake25
-rw-r--r--Modules/Platform/Haiku.cmake134
-rw-r--r--Modules/Platform/IRIX.cmake8
-rw-r--r--Modules/Platform/IRIX64.cmake8
-rw-r--r--Modules/Platform/Linux-CCur-Fortran.cmake1
-rw-r--r--Modules/Platform/Linux-GNU-Fortran.cmake1
-rw-r--r--Modules/Platform/Linux-Intel-C.cmake1
-rw-r--r--Modules/Platform/Linux-Intel-CXX.cmake1
-rw-r--r--Modules/Platform/Linux-Intel-Fortran.cmake4
-rw-r--r--Modules/Platform/Linux-Intel.cmake4
-rw-r--r--Modules/Platform/Linux-PGI.cmake2
-rw-r--r--Modules/Platform/Linux-XL-C.cmake1
-rw-r--r--Modules/Platform/Linux-XL-CXX.cmake1
-rw-r--r--Modules/Platform/Linux-XL-Fortran.cmake1
-rw-r--r--Modules/Platform/Linux.cmake2
-rw-r--r--Modules/Platform/MirBSD.cmake1
-rw-r--r--Modules/Platform/OSF1.cmake4
-rw-r--r--Modules/Platform/OpenBSD.cmake18
-rw-r--r--Modules/Platform/QNX.cmake18
-rw-r--r--Modules/Platform/SunOS.cmake16
-rw-r--r--Modules/Platform/UnixPaths.cmake17
-rw-r--r--Modules/Platform/Windows-Clang-C.cmake2
-rw-r--r--Modules/Platform/Windows-Clang-CXX.cmake2
-rw-r--r--Modules/Platform/Windows-Clang.cmake32
-rw-r--r--Modules/Platform/Windows-Embarcadero.cmake14
-rw-r--r--Modules/Platform/Windows-GNU.cmake25
-rw-r--r--Modules/Platform/Windows-Intel-CXX.cmake1
-rw-r--r--Modules/Platform/Windows-Intel-Fortran.cmake2
-rw-r--r--Modules/Platform/Windows-Intel.cmake93
-rw-r--r--Modules/Platform/Windows-MSVC.cmake142
-rw-r--r--Modules/Platform/Windows-df.cmake5
-rw-r--r--Modules/Platform/Windows-wcl386.cmake88
-rw-r--r--Modules/Platform/Windows-windres.cmake2
-rw-r--r--Modules/Platform/Windows.cmake8
-rw-r--r--Modules/Platform/WindowsCE-MSVC.cmake1
-rw-r--r--Modules/Platform/WindowsPaths.cmake80
-rw-r--r--Modules/Platform/WindowsPhone-MSVC-C.cmake1
-rw-r--r--Modules/Platform/WindowsPhone-MSVC-CXX.cmake1
-rw-r--r--Modules/Platform/WindowsPhone.cmake1
-rw-r--r--Modules/Platform/WindowsStore-MSVC-C.cmake1
-rw-r--r--Modules/Platform/WindowsStore-MSVC-CXX.cmake1
-rw-r--r--Modules/Platform/WindowsStore.cmake1
-rw-r--r--Modules/Platform/eCos.cmake2
-rw-r--r--Modules/ProcessorCount.cmake108
-rw-r--r--Modules/Qt4ConfigDependentSettings.cmake6
-rw-r--r--Modules/Qt4Macros.cmake80
-rw-r--r--Modules/SelectLibraryConfigurations.cmake36
-rwxr-xr-xModules/Squish4RunTestCase.sh4
-rw-r--r--Modules/SquishTestScript.cmake19
-rw-r--r--Modules/TestBigEndian.cmake17
-rw-r--r--Modules/TestCXXAcceptsFlag.cmake20
-rw-r--r--Modules/TestForANSIForScope.cmake16
-rw-r--r--Modules/TestForANSIStreamHeaders.cmake14
-rw-r--r--Modules/TestForSSTREAM.cmake13
-rw-r--r--Modules/TestForSTDNamespace.cmake13
-rw-r--r--Modules/UseEcos.cmake35
-rw-r--r--Modules/UseJava.cmake690
-rw-r--r--Modules/UseJavaClassFilelist.cmake12
-rw-r--r--Modules/UseJavaSymlinks.cmake8
-rw-r--r--Modules/UsePkgConfig.cmake18
-rw-r--r--Modules/UseQt4.cmake27
-rw-r--r--Modules/UseSWIG.cmake176
-rw-r--r--Modules/UseVTK40.cmake29
-rw-r--r--Modules/UseVTKBuildSettings40.cmake38
-rw-r--r--Modules/UseVTKConfig40.cmake409
-rw-r--r--Modules/Use_wxWindows.cmake35
-rw-r--r--Modules/UsewxWidgets.cmake46
-rw-r--r--Modules/WIX.template.in5
-rw-r--r--Modules/WriteBasicConfigVersionFile.cmake21
-rw-r--r--Modules/WriteCompilerDetectionHeader.cmake664
-rw-r--r--Modules/exportheader.cmake.in10
-rw-r--r--Modules/readme.txt174
-rw-r--r--Packaging/CMakeDMGBackground.tifbin0 -> 95690 bytes
-rw-r--r--Packaging/CMakeDMGSetup.scpt42
-rw-r--r--README.rst99
-rw-r--r--Readme.txt53
-rw-r--r--Source/CMakeInstallDestinations.cmake43
-rw-r--r--Source/CMakeLists.txt303
-rw-r--r--Source/CMakeSourceDir.txt.in1
-rwxr-xr-xSource/CMakeVersion.bash2
-rw-r--r--Source/CMakeVersion.cmake7
-rw-r--r--Source/CMakeVersionCompute.cmake20
-rw-r--r--Source/CMakeVersionSource.cmake4
-rw-r--r--Source/CPack/IFW/cmCPackIFWGenerator.cxx628
-rw-r--r--Source/CPack/IFW/cmCPackIFWGenerator.h155
-rw-r--r--Source/CPack/IFW/cmCPackIFWInstaller.cxx541
-rw-r--r--Source/CPack/IFW/cmCPackIFWInstaller.h121
-rw-r--r--Source/CPack/IFW/cmCPackIFWPackage.cxx566
-rw-r--r--Source/CPack/IFW/cmCPackIFWPackage.h141
-rw-r--r--Source/CPack/OSXScriptLauncher.cxx23
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.cxx1058
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.h127
-rw-r--r--Source/CPack/WiX/cmWIXAccessControlList.cxx149
-rw-r--r--Source/CPack/WiX/cmWIXAccessControlList.h46
-rw-r--r--Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx95
-rw-r--r--Source/CPack/WiX/cmWIXDirectoriesSourceWriter.h44
-rw-r--r--Source/CPack/WiX/cmWIXFeaturesSourceWriter.cxx102
-rw-r--r--Source/CPack/WiX/cmWIXFeaturesSourceWriter.h39
-rw-r--r--Source/CPack/WiX/cmWIXFilesSourceWriter.cxx183
-rw-r--r--Source/CPack/WiX/cmWIXFilesSourceWriter.h60
-rw-r--r--Source/CPack/WiX/cmWIXPatch.cxx111
-rw-r--r--Source/CPack/WiX/cmWIXPatch.h48
-rw-r--r--Source/CPack/WiX/cmWIXPatchParser.cxx181
-rw-r--r--Source/CPack/WiX/cmWIXPatchParser.h100
-rw-r--r--Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx127
-rw-r--r--Source/CPack/WiX/cmWIXRichTextFormatWriter.h18
-rw-r--r--Source/CPack/WiX/cmWIXShortcut.cxx125
-rw-r--r--Source/CPack/WiX/cmWIXShortcut.h73
-rw-r--r--Source/CPack/WiX/cmWIXSourceWriter.cxx127
-rw-r--r--Source/CPack/WiX/cmWIXSourceWriter.h32
-rw-r--r--Source/CPack/cmCPack7zGenerator.cxx25
-rw-r--r--Source/CPack/cmCPack7zGenerator.h36
-rw-r--r--Source/CPack/cmCPackArchiveGenerator.cxx27
-rw-r--r--Source/CPack/cmCPackArchiveGenerator.h4
-rw-r--r--Source/CPack/cmCPackBundleGenerator.cxx155
-rw-r--r--Source/CPack/cmCPackBundleGenerator.h2
-rw-r--r--Source/CPack/cmCPackComponentGroup.cxx7
-rw-r--r--Source/CPack/cmCPackComponentGroup.h4
-rw-r--r--Source/CPack/cmCPackCygwinBinaryGenerator.cxx1
-rw-r--r--Source/CPack/cmCPackCygwinSourceGenerator.cxx1
-rw-r--r--Source/CPack/cmCPackDebGenerator.cxx419
-rw-r--r--Source/CPack/cmCPackDocumentMacros.cxx16
-rw-r--r--Source/CPack/cmCPackDocumentMacros.h21
-rw-r--r--Source/CPack/cmCPackDocumentVariables.cxx122
-rw-r--r--Source/CPack/cmCPackDocumentVariables.h21
-rw-r--r--Source/CPack/cmCPackDragNDropGenerator.cxx587
-rw-r--r--Source/CPack/cmCPackDragNDropGenerator.h19
-rw-r--r--Source/CPack/cmCPackGenerator.cxx315
-rw-r--r--Source/CPack/cmCPackGenerator.h63
-rw-r--r--Source/CPack/cmCPackGeneratorFactory.cxx41
-rw-r--r--Source/CPack/cmCPackGeneratorFactory.h10
-rw-r--r--Source/CPack/cmCPackLog.cxx22
-rw-r--r--Source/CPack/cmCPackLog.h2
-rw-r--r--Source/CPack/cmCPackNSISGenerator.cxx127
-rw-r--r--Source/CPack/cmCPackNSISGenerator.h8
-rw-r--r--Source/CPack/cmCPackOSXX11Generator.cxx21
-rw-r--r--Source/CPack/cmCPackOSXX11Generator.h5
-rw-r--r--Source/CPack/cmCPackPackageMakerGenerator.cxx97
-rw-r--r--Source/CPack/cmCPackPackageMakerGenerator.h23
-rw-r--r--Source/CPack/cmCPackRPMGenerator.cxx8
-rw-r--r--Source/CPack/cmCPackSTGZGenerator.cxx15
-rw-r--r--Source/CPack/cmCPackTGZGenerator.cxx2
-rw-r--r--Source/CPack/cmCPackTXZGenerator.cxx25
-rw-r--r--Source/CPack/cmCPackTXZGenerator.h35
-rw-r--r--Source/CPack/cmCPackTarBZip2Generator.cxx2
-rw-r--r--Source/CPack/cmCPackTarCompressGenerator.cxx2
-rw-r--r--Source/CPack/cmCPackZIPGenerator.cxx2
-rw-r--r--Source/CPack/cpack.cxx225
-rw-r--r--Source/CTest/cmCTestBZR.cxx41
-rw-r--r--Source/CTest/cmCTestBatchTestHandler.cxx10
-rw-r--r--Source/CTest/cmCTestBatchTestHandler.h5
-rw-r--r--Source/CTest/cmCTestBuildAndTestHandler.cxx151
-rw-r--r--Source/CTest/cmCTestBuildAndTestHandler.h5
-rw-r--r--Source/CTest/cmCTestBuildCommand.cxx46
-rw-r--r--Source/CTest/cmCTestBuildCommand.h28
-rw-r--r--Source/CTest/cmCTestBuildHandler.cxx241
-rw-r--r--Source/CTest/cmCTestBuildHandler.h30
-rw-r--r--Source/CTest/cmCTestCVS.cxx21
-rw-r--r--Source/CTest/cmCTestCVS.h8
-rw-r--r--Source/CTest/cmCTestConfigureCommand.cxx20
-rw-r--r--Source/CTest/cmCTestConfigureCommand.h30
-rw-r--r--Source/CTest/cmCTestConfigureHandler.cxx62
-rw-r--r--Source/CTest/cmCTestCoverageCommand.cxx6
-rw-r--r--Source/CTest/cmCTestCoverageCommand.h30
-rw-r--r--Source/CTest/cmCTestCoverageHandler.cxx1283
-rw-r--r--Source/CTest/cmCTestCoverageHandler.h40
-rw-r--r--Source/CTest/cmCTestCurl.cxx288
-rw-r--r--Source/CTest/cmCTestCurl.h54
-rw-r--r--Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx6
-rw-r--r--Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h22
-rw-r--r--Source/CTest/cmCTestGIT.cxx18
-rw-r--r--Source/CTest/cmCTestGenericHandler.cxx31
-rw-r--r--Source/CTest/cmCTestGenericHandler.h14
-rw-r--r--Source/CTest/cmCTestGlobalVC.cxx20
-rw-r--r--Source/CTest/cmCTestGlobalVC.h12
-rw-r--r--Source/CTest/cmCTestHG.cxx26
-rw-r--r--Source/CTest/cmCTestHandlerCommand.cxx34
-rw-r--r--Source/CTest/cmCTestHandlerCommand.h1
-rw-r--r--Source/CTest/cmCTestLaunch.cxx211
-rw-r--r--Source/CTest/cmCTestLaunch.h16
-rw-r--r--Source/CTest/cmCTestMemCheckCommand.cxx14
-rw-r--r--Source/CTest/cmCTestMemCheckCommand.h36
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.cxx821
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.h56
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.cxx458
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.h24
-rw-r--r--Source/CTest/cmCTestP4.cxx562
-rw-r--r--Source/CTest/cmCTestP4.h71
-rw-r--r--Source/CTest/cmCTestReadCustomFilesCommand.cxx1
-rw-r--r--Source/CTest/cmCTestReadCustomFilesCommand.h21
-rw-r--r--Source/CTest/cmCTestRunScriptCommand.cxx4
-rw-r--r--Source/CTest/cmCTestRunScriptCommand.h26
-rw-r--r--Source/CTest/cmCTestRunTest.cxx174
-rw-r--r--Source/CTest/cmCTestRunTest.h9
-rw-r--r--Source/CTest/cmCTestSVN.cxx32
-rw-r--r--Source/CTest/cmCTestSVN.h4
-rw-r--r--Source/CTest/cmCTestScriptHandler.cxx233
-rw-r--r--Source/CTest/cmCTestScriptHandler.h34
-rw-r--r--Source/CTest/cmCTestSleepCommand.h22
-rw-r--r--Source/CTest/cmCTestStartCommand.cxx32
-rw-r--r--Source/CTest/cmCTestStartCommand.h28
-rw-r--r--Source/CTest/cmCTestSubmitCommand.cxx152
-rw-r--r--Source/CTest/cmCTestSubmitCommand.h49
-rw-r--r--Source/CTest/cmCTestSubmitHandler.cxx652
-rw-r--r--Source/CTest/cmCTestSubmitHandler.h65
-rw-r--r--Source/CTest/cmCTestTestCommand.cxx36
-rw-r--r--Source/CTest/cmCTestTestCommand.h42
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx821
-rw-r--r--Source/CTest/cmCTestTestHandler.h63
-rw-r--r--Source/CTest/cmCTestUpdateCommand.cxx44
-rw-r--r--Source/CTest/cmCTestUpdateCommand.h24
-rw-r--r--Source/CTest/cmCTestUpdateHandler.cxx181
-rw-r--r--Source/CTest/cmCTestUpdateHandler.h9
-rw-r--r--Source/CTest/cmCTestUploadCommand.cxx11
-rw-r--r--Source/CTest/cmCTestUploadCommand.h21
-rw-r--r--Source/CTest/cmCTestUploadHandler.cxx53
-rw-r--r--Source/CTest/cmCTestVC.cxx59
-rw-r--r--Source/CTest/cmCTestVC.h7
-rw-r--r--Source/CTest/cmParseBlanketJSCoverage.cxx164
-rw-r--r--Source/CTest/cmParseBlanketJSCoverage.h48
-rw-r--r--Source/CTest/cmParseCacheCoverage.cxx27
-rw-r--r--Source/CTest/cmParseCoberturaCoverage.cxx200
-rw-r--r--Source/CTest/cmParseCoberturaCoverage.h51
-rw-r--r--Source/CTest/cmParseDelphiCoverage.cxx254
-rw-r--r--Source/CTest/cmParseDelphiCoverage.h46
-rw-r--r--Source/CTest/cmParseGTMCoverage.cxx33
-rw-r--r--Source/CTest/cmParseJacocoCoverage.cxx209
-rw-r--r--Source/CTest/cmParseJacocoCoverage.h59
-rw-r--r--Source/CTest/cmParseMumpsCoverage.cxx17
-rw-r--r--Source/CTest/cmParseMumpsCoverage.h2
-rw-r--r--Source/CTest/cmParsePHPCoverage.cxx19
-rw-r--r--Source/CTest/cmParsePHPCoverage.h10
-rw-r--r--Source/CTest/cmProcess.cxx23
-rw-r--r--Source/CTest/cmProcess.h7
-rw-r--r--Source/Checks/cm_c11_thread_local.c2
-rw-r--r--Source/Checks/cm_c11_thread_local.cmake33
-rw-r--r--Source/Checks/cm_cxx11_unordered_map.cmake25
-rw-r--r--Source/Checks/cm_cxx11_unordered_map.cpp6
-rw-r--r--Source/Checks/cm_cxx14_cstdio.cmake33
-rw-r--r--Source/Checks/cm_cxx14_cstdio.cpp2
-rw-r--r--Source/CursesDialog/CMakeLists.txt22
-rw-r--r--Source/CursesDialog/ccmake.cxx69
-rw-r--r--Source/CursesDialog/cmCursesBoolWidget.cxx2
-rw-r--r--Source/CursesDialog/cmCursesBoolWidget.h6
-rw-r--r--Source/CursesDialog/cmCursesCacheEntryComposite.cxx65
-rw-r--r--Source/CursesDialog/cmCursesCacheEntryComposite.h14
-rw-r--r--Source/CursesDialog/cmCursesDummyWidget.cxx2
-rw-r--r--Source/CursesDialog/cmCursesDummyWidget.h6
-rw-r--r--Source/CursesDialog/cmCursesFilePathWidget.cxx2
-rw-r--r--Source/CursesDialog/cmCursesFilePathWidget.h6
-rw-r--r--Source/CursesDialog/cmCursesForm.cxx2
-rw-r--r--Source/CursesDialog/cmCursesForm.h9
-rw-r--r--Source/CursesDialog/cmCursesLabelWidget.cxx2
-rw-r--r--Source/CursesDialog/cmCursesLabelWidget.h6
-rw-r--r--Source/CursesDialog/cmCursesLongMessageForm.cxx9
-rw-r--r--Source/CursesDialog/cmCursesLongMessageForm.h6
-rw-r--r--Source/CursesDialog/cmCursesMainForm.cxx220
-rw-r--r--Source/CursesDialog/cmCursesMainForm.h10
-rw-r--r--Source/CursesDialog/cmCursesOptionsWidget.cxx105
-rw-r--r--Source/CursesDialog/cmCursesOptionsWidget.h39
-rw-r--r--Source/CursesDialog/cmCursesPathWidget.cxx10
-rw-r--r--Source/CursesDialog/cmCursesPathWidget.h6
-rw-r--r--Source/CursesDialog/cmCursesStandardIncludes.h42
-rw-r--r--Source/CursesDialog/cmCursesStringWidget.cxx29
-rw-r--r--Source/CursesDialog/cmCursesStringWidget.h8
-rw-r--r--Source/CursesDialog/cmCursesWidget.cxx4
-rw-r--r--Source/CursesDialog/cmCursesWidget.h14
-rw-r--r--Source/CursesDialog/form/fld_attr.c8
-rw-r--r--Source/CursesDialog/form/form.h10
-rw-r--r--Source/CursesDialog/form/form.priv.h6
-rw-r--r--Source/CursesDialog/form/frm_driver.c19
-rw-r--r--Source/CursesDialog/form/frm_post.c5
-rw-r--r--Source/CursesDialog/form/frm_req_name.c6
-rw-r--r--Source/Modules/FindJsonCpp.cmake117
-rw-r--r--Source/QtDialog/AddCacheEntry.cxx38
-rw-r--r--Source/QtDialog/AddCacheEntry.h11
-rw-r--r--Source/QtDialog/CMake.desktop2
-rw-r--r--Source/QtDialog/CMakeLists.txt152
-rw-r--r--Source/QtDialog/CMakeSetup.cxx146
-rw-r--r--Source/QtDialog/CMakeSetupDialog.cxx177
-rw-r--r--Source/QtDialog/CMakeSetupDialog.h7
-rw-r--r--Source/QtDialog/CMakeSetupDialog.ui2
-rw-r--r--Source/QtDialog/FirstConfigure.cxx70
-rw-r--r--Source/QtDialog/FirstConfigure.h15
-rw-r--r--Source/QtDialog/Info.plist.in34
-rw-r--r--Source/QtDialog/MacInstallDialog.ui103
-rw-r--r--Source/QtDialog/QCMake.cxx226
-rw-r--r--Source/QtDialog/QCMake.h40
-rw-r--r--Source/QtDialog/QCMakeWidgets.cxx6
-rw-r--r--Source/QtDialog/QMacInstallDialog.cxx121
-rw-r--r--Source/QtDialog/QMacInstallDialog.h20
-rw-r--r--Source/QtDialog/QtDialogCPack.cmake.in3
-rw-r--r--Source/QtDialog/RegexExplorer.cxx166
-rw-r--r--Source/QtDialog/RegexExplorer.h48
-rw-r--r--Source/QtDialog/RegexExplorer.ui155
-rw-r--r--Source/QtDialog/WarningMessagesDialog.cxx99
-rw-r--r--Source/QtDialog/WarningMessagesDialog.h75
-rw-r--r--Source/QtDialog/WarningMessagesDialog.ui173
-rwxr-xr-xSource/QtDialog/postflight.sh.in3
-rwxr-xr-xSource/QtDialog/postupgrade.sh.in2
-rw-r--r--Source/QtIFW/CMake.Dialogs.QtGUI.qs21
-rw-r--r--Source/QtIFW/CMake.Documentation.SphinxHTML.qs.in21
-rw-r--r--Source/QtIFW/CMake.qs.in22
-rw-r--r--Source/QtIFW/cmake.org.html7
-rw-r--r--Source/QtIFW/controlscript.qs6
-rw-r--r--Source/QtIFW/installscript.qs.in24
-rw-r--r--Source/bindexplib.cxx460
-rw-r--r--Source/bindexplib.h29
-rw-r--r--Source/cmAddCompileOptionsCommand.h30
-rw-r--r--Source/cmAddCustomCommandCommand.cxx103
-rw-r--r--Source/cmAddCustomCommandCommand.h142
-rw-r--r--Source/cmAddCustomTargetCommand.cxx135
-rw-r--r--Source/cmAddCustomTargetCommand.h59
-rw-r--r--Source/cmAddDefinitionsCommand.h31
-rw-r--r--Source/cmAddDependenciesCommand.cxx11
-rw-r--r--Source/cmAddDependenciesCommand.h31
-rw-r--r--Source/cmAddExecutableCommand.cxx80
-rw-r--r--Source/cmAddExecutableCommand.h82
-rw-r--r--Source/cmAddLibraryCommand.cxx262
-rw-r--r--Source/cmAddLibraryCommand.h113
-rw-r--r--Source/cmAddSubDirectoryCommand.cxx32
-rw-r--r--Source/cmAddSubDirectoryCommand.h49
-rw-r--r--Source/cmAddTestCommand.cxx26
-rw-r--r--Source/cmAddTestCommand.h55
-rw-r--r--Source/cmAlgorithms.h372
-rw-r--r--Source/cmArchiveWrite.cxx204
-rw-r--r--Source/cmArchiveWrite.h109
-rw-r--r--Source/cmAuxSourceDirectoryCommand.cxx17
-rw-r--r--Source/cmAuxSourceDirectoryCommand.h34
-rw-r--r--Source/cmBootstrapCommands1.cxx9
-rw-r--r--Source/cmBootstrapCommands2.cxx5
-rw-r--r--Source/cmBreakCommand.cxx66
-rw-r--r--Source/cmBreakCommand.h20
-rw-r--r--Source/cmBuildCommand.cxx50
-rw-r--r--Source/cmBuildCommand.h43
-rw-r--r--Source/cmBuildNameCommand.cxx17
-rw-r--r--Source/cmBuildNameCommand.h58
-rw-r--r--Source/cmCLocaleEnvironmentScope.cxx67
-rw-r--r--Source/cmCLocaleEnvironmentScope.h32
-rw-r--r--Source/cmCMakeHostSystemInformationCommand.cxx8
-rw-r--r--Source/cmCMakeHostSystemInformationCommand.h37
-rw-r--r--Source/cmCMakeMinimumRequired.cxx33
-rw-r--r--Source/cmCMakeMinimumRequired.h33
-rw-r--r--Source/cmCMakePolicyCommand.cxx40
-rw-r--r--Source/cmCMakePolicyCommand.h84
-rw-r--r--Source/cmCPackPropertiesGenerator.cxx47
-rw-r--r--Source/cmCPackPropertiesGenerator.h40
-rw-r--r--Source/cmCPluginAPI.cxx78
-rw-r--r--Source/cmCTest.cxx744
-rw-r--r--Source/cmCTest.h96
-rw-r--r--Source/cmCacheManager.cxx423
-rw-r--r--Source/cmCacheManager.h188
-rw-r--r--Source/cmCallVisualStudioMacro.cxx21
-rw-r--r--Source/cmCommand.h46
-rw-r--r--Source/cmCommandArgumentLexer.cxx6
-rw-r--r--Source/cmCommandArgumentParser.cxx6
-rw-r--r--Source/cmCommandArgumentParser.y6
-rw-r--r--Source/cmCommandArgumentParserHelper.cxx48
-rw-r--r--Source/cmCommandArgumentParserHelper.h14
-rw-r--r--Source/cmCommandArgumentsHelper.cxx9
-rw-r--r--Source/cmCommands.cxx86
-rw-r--r--Source/cmCommands.cxx.in19
-rw-r--r--Source/cmCommands.h8
-rw-r--r--Source/cmCommandsForBootstrap.cxx16
-rw-r--r--Source/cmCommonTargetGenerator.cxx428
-rw-r--r--Source/cmCommonTargetGenerator.h94
-rw-r--r--Source/cmComputeComponentGraph.h4
-rw-r--r--Source/cmComputeLinkDepends.cxx228
-rw-r--r--Source/cmComputeLinkDepends.h58
-rw-r--r--Source/cmComputeLinkInformation.cxx355
-rw-r--r--Source/cmComputeLinkInformation.h77
-rw-r--r--Source/cmComputeTargetDepends.cxx239
-rw-r--r--Source/cmComputeTargetDepends.h33
-rw-r--r--Source/cmConditionEvaluator.cxx854
-rw-r--r--Source/cmConditionEvaluator.h107
-rw-r--r--Source/cmConfigure.cmake.h.in10
-rw-r--r--Source/cmConfigureFileCommand.cxx61
-rw-r--r--Source/cmConfigureFileCommand.h61
-rw-r--r--Source/cmContinueCommand.cxx39
-rw-r--r--Source/cmContinueCommand.h55
-rw-r--r--Source/cmCoreTryCompile.cxx280
-rw-r--r--Source/cmCoreTryCompile.h2
-rw-r--r--Source/cmCreateTestSourceList.cxx14
-rw-r--r--Source/cmCreateTestSourceList.h44
-rw-r--r--Source/cmCryptoHash.cxx11
-rw-r--r--Source/cmCryptoHash.h4
-rw-r--r--Source/cmCurl.cxx69
-rw-r--r--Source/cmCurl.h21
-rw-r--r--Source/cmCustomCommand.cxx97
-rw-r--r--Source/cmCustomCommand.h32
-rw-r--r--Source/cmCustomCommandGenerator.cxx112
-rw-r--r--Source/cmCustomCommandGenerator.h17
-rw-r--r--Source/cmDefinePropertyCommand.cxx14
-rw-r--r--Source/cmDefinePropertyCommand.h49
-rw-r--r--Source/cmDefinitions.cxx188
-rw-r--r--Source/cmDefinitions.h88
-rw-r--r--Source/cmDepends.cxx30
-rw-r--r--Source/cmDepends.h6
-rw-r--r--Source/cmDependsC.cxx82
-rw-r--r--Source/cmDependsC.h19
-rw-r--r--Source/cmDependsFortran.cxx689
-rw-r--r--Source/cmDependsFortran.h19
-rw-r--r--Source/cmDependsFortranLexer.cxx2414
-rw-r--r--Source/cmDependsFortranLexer.h348
-rw-r--r--Source/cmDependsFortranLexer.in.l190
-rw-r--r--Source/cmDependsFortranParser.cxx2094
-rw-r--r--Source/cmDependsFortranParser.h96
-rw-r--r--Source/cmDependsFortranParser.y288
-rw-r--r--Source/cmDependsFortranParserTokens.h122
-rw-r--r--Source/cmDependsJavaLexer.cxx6
-rw-r--r--Source/cmDependsJavaParser.cxx6
-rw-r--r--Source/cmDependsJavaParser.y6
-rw-r--r--Source/cmDependsJavaParserHelper.cxx45
-rw-r--r--Source/cmDependsJavaParserHelper.h20
-rw-r--r--Source/cmDocumentCompileDefinitions.h34
-rw-r--r--Source/cmDocumentGeneratorExpressions.h98
-rw-r--r--Source/cmDocumentLocationUndefined.h24
-rw-r--r--Source/cmDocumentVariables.cxx2030
-rw-r--r--Source/cmDocumentVariables.h21
-rw-r--r--Source/cmDocumentation.cxx1789
-rw-r--r--Source/cmDocumentation.h183
-rw-r--r--Source/cmDocumentationFormatter.cxx228
-rw-r--r--Source/cmDocumentationFormatter.h40
-rw-r--r--Source/cmDocumentationFormatterDocbook.cxx254
-rw-r--r--Source/cmDocumentationFormatterDocbook.h43
-rw-r--r--Source/cmDocumentationFormatterHTML.cxx288
-rw-r--r--Source/cmDocumentationFormatterHTML.h42
-rw-r--r--Source/cmDocumentationFormatterMan.cxx102
-rw-r--r--Source/cmDocumentationFormatterMan.h43
-rw-r--r--Source/cmDocumentationFormatterText.cxx180
-rw-r--r--Source/cmDocumentationFormatterText.h40
-rw-r--r--Source/cmDocumentationFormatterUsage.cxx63
-rw-r--r--Source/cmDocumentationFormatterUsage.h31
-rw-r--r--Source/cmDocumentationSection.cxx48
-rw-r--r--Source/cmDocumentationSection.h18
-rw-r--r--Source/cmDynamicLoader.cxx8
-rw-r--r--Source/cmDynamicLoader.h8
-rw-r--r--Source/cmELF.cxx64
-rw-r--r--Source/cmElseCommand.h20
-rw-r--r--Source/cmElseIfCommand.h20
-rw-r--r--Source/cmEnableLanguageCommand.h33
-rw-r--r--Source/cmEnableTestingCommand.cxx1
-rw-r--r--Source/cmEnableTestingCommand.h23
-rw-r--r--Source/cmEndForEachCommand.h20
-rw-r--r--Source/cmEndFunctionCommand.h20
-rw-r--r--Source/cmEndIfCommand.h20
-rw-r--r--Source/cmEndMacroCommand.h20
-rw-r--r--Source/cmEndWhileCommand.h20
-rw-r--r--Source/cmExecProgramCommand.cxx212
-rw-r--r--Source/cmExecProgramCommand.h45
-rw-r--r--Source/cmExecuteProcessCommand.cxx56
-rw-r--r--Source/cmExecuteProcessCommand.h60
-rw-r--r--Source/cmExecutionStatus.h32
-rw-r--r--Source/cmExpandedCommandArgument.cxx51
-rw-r--r--Source/cmExpandedCommandArgument.h45
-rw-r--r--Source/cmExportBuildFileGenerator.cxx258
-rw-r--r--Source/cmExportBuildFileGenerator.h44
-rw-r--r--Source/cmExportCommand.cxx275
-rw-r--r--Source/cmExportCommand.h60
-rw-r--r--Source/cmExportFileGenerator.cxx473
-rw-r--r--Source/cmExportFileGenerator.h94
-rw-r--r--Source/cmExportInstallFileGenerator.cxx217
-rw-r--r--Source/cmExportInstallFileGenerator.h28
-rw-r--r--Source/cmExportLibraryDependencies.cxx204
-rw-r--r--Source/cmExportLibraryDependencies.h100
-rw-r--r--Source/cmExportLibraryDependenciesCommand.cxx204
-rw-r--r--Source/cmExportLibraryDependenciesCommand.h36
-rw-r--r--Source/cmExportSet.cxx12
-rw-r--r--Source/cmExportSet.h3
-rw-r--r--Source/cmExportSetMap.cxx14
-rw-r--r--Source/cmExportSetMap.h3
-rw-r--r--Source/cmExportTryCompileFileGenerator.cxx85
-rw-r--r--Source/cmExportTryCompileFileGenerator.h34
-rw-r--r--Source/cmExprLexer.cxx6
-rw-r--r--Source/cmExprParser.cxx6
-rw-r--r--Source/cmExprParser.y6
-rw-r--r--Source/cmExprParserHelper.cxx2
-rw-r--r--Source/cmExprParserHelper.h4
-rw-r--r--Source/cmExternalMakefileProjectGenerator.cxx30
-rw-r--r--Source/cmExternalMakefileProjectGenerator.h13
-rw-r--r--Source/cmExtraCodeBlocksGenerator.cxx318
-rw-r--r--Source/cmExtraCodeBlocksGenerator.h25
-rw-r--r--Source/cmExtraCodeLiteGenerator.cxx474
-rw-r--r--Source/cmExtraCodeLiteGenerator.h54
-rw-r--r--Source/cmExtraEclipseCDT4Generator.cxx295
-rw-r--r--Source/cmExtraEclipseCDT4Generator.h12
-rw-r--r--Source/cmExtraKateGenerator.cxx351
-rw-r--r--Source/cmExtraKateGenerator.h61
-rw-r--r--Source/cmExtraSublimeTextGenerator.cxx147
-rw-r--r--Source/cmExtraSublimeTextGenerator.h16
-rw-r--r--Source/cmFLTKWrapUICommand.cxx66
-rw-r--r--Source/cmFLTKWrapUICommand.h24
-rw-r--r--Source/cmFileCommand.cxx998
-rw-r--r--Source/cmFileCommand.h210
-rw-r--r--Source/cmFileLock.cxx78
-rw-r--r--Source/cmFileLock.h74
-rw-r--r--Source/cmFileLockPool.cxx188
-rw-r--r--Source/cmFileLockPool.h104
-rw-r--r--Source/cmFileLockResult.cxx111
-rw-r--r--Source/cmFileLockResult.h85
-rw-r--r--Source/cmFileLockUnix.cxx106
-rw-r--r--Source/cmFileLockWin32.cxx129
-rw-r--r--Source/cmFileTimeComparison.cxx60
-rw-r--r--Source/cmFindBase.cxx442
-rw-r--r--Source/cmFindBase.h29
-rw-r--r--Source/cmFindCommon.cxx269
-rw-r--r--Source/cmFindCommon.h74
-rw-r--r--Source/cmFindFileCommand.cxx12
-rw-r--r--Source/cmFindFileCommand.h12
-rw-r--r--Source/cmFindLibraryCommand.cxx121
-rw-r--r--Source/cmFindLibraryCommand.h10
-rw-r--r--Source/cmFindPackageCommand.cxx950
-rw-r--r--Source/cmFindPackageCommand.h76
-rw-r--r--Source/cmFindPathCommand.cxx74
-rw-r--r--Source/cmFindPathCommand.h12
-rw-r--r--Source/cmFindProgramCommand.cxx208
-rw-r--r--Source/cmFindProgramCommand.h21
-rw-r--r--Source/cmForEachCommand.cxx44
-rw-r--r--Source/cmForEachCommand.h53
-rw-r--r--Source/cmFortranLexer.cxx2431
-rw-r--r--Source/cmFortranLexer.h352
-rw-r--r--Source/cmFortranLexer.in.l191
-rw-r--r--Source/cmFortranParser.cxx1916
-rw-r--r--Source/cmFortranParser.h177
-rw-r--r--Source/cmFortranParser.y287
-rw-r--r--Source/cmFortranParserImpl.cxx434
-rw-r--r--Source/cmFortranParserTokens.h131
-rw-r--r--Source/cmFunctionBlocker.h2
-rw-r--r--Source/cmFunctionCommand.cxx113
-rw-r--r--Source/cmFunctionCommand.h42
-rw-r--r--Source/cmGeneratedFileStream.cxx17
-rw-r--r--Source/cmGeneratedFileStream.h19
-rw-r--r--Source/cmGeneratorExpression.cxx140
-rw-r--r--Source/cmGeneratorExpression.h70
-rw-r--r--Source/cmGeneratorExpressionContext.cxx35
-rw-r--r--Source/cmGeneratorExpressionContext.h57
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.cxx122
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.h45
-rw-r--r--Source/cmGeneratorExpressionEvaluationFile.cxx95
-rw-r--r--Source/cmGeneratorExpressionEvaluationFile.h16
-rw-r--r--Source/cmGeneratorExpressionEvaluator.cxx1479
-rw-r--r--Source/cmGeneratorExpressionEvaluator.h36
-rw-r--r--Source/cmGeneratorExpressionLexer.cxx76
-rw-r--r--Source/cmGeneratorExpressionLexer.h6
-rw-r--r--Source/cmGeneratorExpressionNode.cxx1906
-rw-r--r--Source/cmGeneratorExpressionNode.h69
-rw-r--r--Source/cmGeneratorExpressionParser.cxx12
-rw-r--r--Source/cmGeneratorExpressionParser.h2
-rw-r--r--Source/cmGeneratorTarget.cxx6102
-rw-r--r--Source/cmGeneratorTarget.h682
-rw-r--r--Source/cmGetCMakePropertyCommand.cxx46
-rw-r--r--Source/cmGetCMakePropertyCommand.h27
-rw-r--r--Source/cmGetDirectoryPropertyCommand.cxx53
-rw-r--r--Source/cmGetDirectoryPropertyCommand.h38
-rw-r--r--Source/cmGetFilenameComponentCommand.cxx52
-rw-r--r--Source/cmGetFilenameComponentCommand.h39
-rw-r--r--Source/cmGetPropertyCommand.cxx152
-rw-r--r--Source/cmGetPropertyCommand.h55
-rw-r--r--Source/cmGetSourceFilePropertyCommand.cxx10
-rw-r--r--Source/cmGetSourceFilePropertyCommand.h26
-rw-r--r--Source/cmGetTargetPropertyCommand.cxx55
-rw-r--r--Source/cmGetTargetPropertyCommand.h28
-rw-r--r--Source/cmGetTestPropertyCommand.cxx12
-rw-r--r--Source/cmGetTestPropertyCommand.h25
-rw-r--r--Source/cmGhsMultiGpj.cxx44
-rw-r--r--Source/cmGhsMultiGpj.h34
-rw-r--r--Source/cmGhsMultiTargetGenerator.cxx616
-rw-r--r--Source/cmGhsMultiTargetGenerator.h119
-rw-r--r--Source/cmGlobalBorlandMakefileGenerator.cxx23
-rw-r--r--Source/cmGlobalBorlandMakefileGenerator.h15
-rw-r--r--Source/cmGlobalCommonGenerator.cxx21
-rw-r--r--Source/cmGlobalCommonGenerator.h27
-rw-r--r--Source/cmGlobalGenerator.cxx2218
-rw-r--r--Source/cmGlobalGenerator.h418
-rw-r--r--Source/cmGlobalGeneratorFactory.h17
-rw-r--r--Source/cmGlobalGhsMultiGenerator.cxx547
-rw-r--r--Source/cmGlobalGhsMultiGenerator.h134
-rw-r--r--Source/cmGlobalJOMMakefileGenerator.cxx53
-rw-r--r--Source/cmGlobalJOMMakefileGenerator.h14
-rw-r--r--Source/cmGlobalKdevelopGenerator.cxx91
-rw-r--r--Source/cmGlobalKdevelopGenerator.h6
-rw-r--r--Source/cmGlobalMSYSMakefileGenerator.cxx28
-rw-r--r--Source/cmGlobalMSYSMakefileGenerator.h11
-rw-r--r--Source/cmGlobalMinGWMakefileGenerator.cxx48
-rw-r--r--Source/cmGlobalMinGWMakefileGenerator.h11
-rw-r--r--Source/cmGlobalNMakeMakefileGenerator.cxx53
-rw-r--r--Source/cmGlobalNMakeMakefileGenerator.h14
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx584
-rw-r--r--Source/cmGlobalNinjaGenerator.h146
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx610
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.h78
-rw-r--r--Source/cmGlobalVisualStudio10Generator.cxx577
-rw-r--r--Source/cmGlobalVisualStudio10Generator.h113
-rw-r--r--Source/cmGlobalVisualStudio11Generator.cxx284
-rw-r--r--Source/cmGlobalVisualStudio11Generator.h28
-rw-r--r--Source/cmGlobalVisualStudio12Generator.cxx242
-rw-r--r--Source/cmGlobalVisualStudio12Generator.h25
-rw-r--r--Source/cmGlobalVisualStudio14Generator.cxx302
-rw-r--r--Source/cmGlobalVisualStudio14Generator.h53
-rw-r--r--Source/cmGlobalVisualStudio6Generator.cxx210
-rw-r--r--Source/cmGlobalVisualStudio6Generator.h66
-rw-r--r--Source/cmGlobalVisualStudio71Generator.cxx76
-rw-r--r--Source/cmGlobalVisualStudio71Generator.h28
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx610
-rw-r--r--Source/cmGlobalVisualStudio7Generator.h133
-rw-r--r--Source/cmGlobalVisualStudio8Generator.cxx226
-rw-r--r--Source/cmGlobalVisualStudio8Generator.h38
-rw-r--r--Source/cmGlobalVisualStudio9Generator.cxx64
-rw-r--r--Source/cmGlobalVisualStudio9Generator.h11
-rw-r--r--Source/cmGlobalVisualStudioGenerator.cxx399
-rw-r--r--Source/cmGlobalVisualStudioGenerator.h98
-rw-r--r--Source/cmGlobalWatcomWMakeGenerator.cxx32
-rw-r--r--Source/cmGlobalWatcomWMakeGenerator.h14
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx1845
-rw-r--r--Source/cmGlobalXCodeGenerator.h162
-rw-r--r--Source/cmGraphVizWriter.cxx147
-rw-r--r--Source/cmGraphVizWriter.h38
-rw-r--r--Source/cmHexFileConverter.cxx6
-rw-r--r--Source/cmIDEFlagTable.h2
-rw-r--r--Source/cmIDEOptions.cxx114
-rw-r--r--Source/cmIDEOptions.h27
-rw-r--r--Source/cmIfCommand.cxx767
-rw-r--r--Source/cmIfCommand.h195
-rw-r--r--Source/cmIncludeCommand.cxx74
-rw-r--r--Source/cmIncludeCommand.h41
-rw-r--r--Source/cmIncludeDirectoryCommand.cxx14
-rw-r--r--Source/cmIncludeDirectoryCommand.h40
-rw-r--r--Source/cmIncludeExternalMSProjectCommand.cxx4
-rw-r--r--Source/cmIncludeExternalMSProjectCommand.h34
-rw-r--r--Source/cmIncludeRegularExpressionCommand.cxx2
-rw-r--r--Source/cmIncludeRegularExpressionCommand.h26
-rw-r--r--Source/cmInstallCommand.cxx371
-rw-r--r--Source/cmInstallCommand.h303
-rw-r--r--Source/cmInstallCommandArguments.cxx5
-rw-r--r--Source/cmInstallDirectoryGenerator.cxx76
-rw-r--r--Source/cmInstallDirectoryGenerator.h13
-rw-r--r--Source/cmInstallExportGenerator.cxx63
-rw-r--r--Source/cmInstallExportGenerator.h12
-rw-r--r--Source/cmInstallFilesCommand.cxx38
-rw-r--r--Source/cmInstallFilesCommand.h47
-rw-r--r--Source/cmInstallFilesGenerator.cxx85
-rw-r--r--Source/cmInstallFilesGenerator.h16
-rw-r--r--Source/cmInstallGenerator.cxx66
-rw-r--r--Source/cmInstallGenerator.h29
-rw-r--r--Source/cmInstallProgramsCommand.cxx26
-rw-r--r--Source/cmInstallProgramsCommand.h43
-rw-r--r--Source/cmInstallScriptGenerator.cxx8
-rw-r--r--Source/cmInstallTargetGenerator.cxx335
-rw-r--r--Source/cmInstallTargetGenerator.h59
-rw-r--r--Source/cmInstallTargetsCommand.cxx7
-rw-r--r--Source/cmInstallTargetsCommand.h32
-rw-r--r--Source/cmInstalledFile.cxx142
-rw-r--r--Source/cmInstalledFile.h77
-rw-r--r--Source/cmLinkDirectoriesCommand.cxx11
-rw-r--r--Source/cmLinkDirectoriesCommand.h29
-rw-r--r--Source/cmLinkItem.h145
-rw-r--r--Source/cmLinkLibrariesCommand.cxx10
-rw-r--r--Source/cmLinkLibrariesCommand.h33
-rw-r--r--Source/cmLinkedTree.h216
-rw-r--r--Source/cmListCommand.cxx263
-rw-r--r--Source/cmListCommand.h66
-rw-r--r--Source/cmListFileCache.cxx209
-rw-r--r--Source/cmListFileCache.h67
-rw-r--r--Source/cmListFileLexer.c483
-rw-r--r--Source/cmListFileLexer.h17
-rw-r--r--Source/cmListFileLexer.in.l209
-rw-r--r--Source/cmLoadCacheCommand.cxx30
-rw-r--r--Source/cmLoadCacheCommand.h37
-rw-r--r--Source/cmLoadCommandCommand.cxx54
-rw-r--r--Source/cmLoadCommandCommand.h50
-rw-r--r--Source/cmLocalCommonGenerator.cxx39
-rw-r--r--Source/cmLocalCommonGenerator.h37
-rw-r--r--Source/cmLocalGenerator.cxx2366
-rw-r--r--Source/cmLocalGenerator.h372
-rw-r--r--Source/cmLocalGhsMultiGenerator.cxx41
-rw-r--r--Source/cmLocalGhsMultiGenerator.h38
-rw-r--r--Source/cmLocalNinjaGenerator.cxx336
-rw-r--r--Source/cmLocalNinjaGenerator.h72
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx918
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.h212
-rw-r--r--Source/cmLocalVisualStudio10Generator.cxx36
-rw-r--r--Source/cmLocalVisualStudio10Generator.h4
-rw-r--r--Source/cmLocalVisualStudio6Generator.cxx768
-rw-r--r--Source/cmLocalVisualStudio6Generator.h46
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx887
-rw-r--r--Source/cmLocalVisualStudio7Generator.h73
-rw-r--r--Source/cmLocalVisualStudioGenerator.cxx90
-rw-r--r--Source/cmLocalVisualStudioGenerator.h38
-rw-r--r--Source/cmLocalXCodeGenerator.cxx63
-rw-r--r--Source/cmLocalXCodeGenerator.h14
-rw-r--r--Source/cmLocale.h31
-rw-r--r--Source/cmMachO.cxx419
-rw-r--r--Source/cmMachO.h51
-rw-r--r--Source/cmMacroCommand.cxx174
-rw-r--r--Source/cmMacroCommand.h46
-rw-r--r--Source/cmMakeDepend.cxx364
-rw-r--r--Source/cmMakeDepend.h150
-rw-r--r--Source/cmMakeDirectoryCommand.cxx2
-rw-r--r--Source/cmMakeDirectoryCommand.h28
-rw-r--r--Source/cmMakefile.cxx4496
-rw-r--r--Source/cmMakefile.h865
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx162
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.h2
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx377
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.h7
-rw-r--r--Source/cmMakefileTargetGenerator.cxx1268
-rw-r--r--Source/cmMakefileTargetGenerator.h119
-rw-r--r--Source/cmMakefileUtilityTargetGenerator.cxx28
-rw-r--r--Source/cmMakefileUtilityTargetGenerator.h2
-rw-r--r--Source/cmMarkAsAdvancedCommand.cxx18
-rw-r--r--Source/cmMarkAsAdvancedCommand.h29
-rw-r--r--Source/cmMathCommand.cxx6
-rw-r--r--Source/cmMathCommand.h24
-rw-r--r--Source/cmMessageCommand.cxx39
-rw-r--r--Source/cmMessageCommand.h41
-rw-r--r--Source/cmNewLineStyle.cxx4
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx647
-rw-r--r--Source/cmNinjaNormalTargetGenerator.h5
-rw-r--r--Source/cmNinjaTargetGenerator.cxx674
-rw-r--r--Source/cmNinjaTargetGenerator.h76
-rw-r--r--Source/cmNinjaUtilityTargetGenerator.cxx70
-rw-r--r--Source/cmNinjaUtilityTargetGenerator.h2
-rw-r--r--Source/cmOSXBundleGenerator.cxx91
-rw-r--r--Source/cmOSXBundleGenerator.h18
-rw-r--r--Source/cmOptionCommand.cxx27
-rw-r--r--Source/cmOptionCommand.h25
-rw-r--r--Source/cmOrderDirectories.cxx91
-rw-r--r--Source/cmOrderDirectories.h27
-rw-r--r--Source/cmOutputConverter.cxx1065
-rw-r--r--Source/cmOutputConverter.h183
-rw-r--r--Source/cmOutputRequiredFilesCommand.cxx609
-rw-r--r--Source/cmOutputRequiredFilesCommand.h60
-rw-r--r--Source/cmParseArgumentsCommand.cxx200
-rw-r--r--Source/cmParseArgumentsCommand.h54
-rw-r--r--Source/cmPathLabel.cxx41
-rw-r--r--Source/cmPathLabel.h44
-rw-r--r--Source/cmPolicies.cxx1007
-rw-r--r--Source/cmPolicies.h319
-rw-r--r--Source/cmProcessTools.cxx2
-rw-r--r--Source/cmProcessTools.h6
-rw-r--r--Source/cmProjectCommand.cxx192
-rw-r--r--Source/cmProjectCommand.h37
-rw-r--r--Source/cmProperty.cxx6
-rw-r--r--Source/cmProperty.h9
-rw-r--r--Source/cmPropertyDefinition.cxx16
-rw-r--r--Source/cmPropertyDefinition.h21
-rw-r--r--Source/cmPropertyDefinitionMap.cxx85
-rw-r--r--Source/cmPropertyDefinitionMap.h12
-rw-r--r--Source/cmPropertyMap.cxx76
-rw-r--r--Source/cmPropertyMap.h24
-rw-r--r--Source/cmQTWrapCPPCommand.cxx28
-rw-r--r--Source/cmQTWrapCPPCommand.h23
-rw-r--r--Source/cmQTWrapUICommand.cxx38
-rw-r--r--Source/cmQTWrapUICommand.h26
-rw-r--r--Source/cmQtAutoGeneratorInitializer.cxx1072
-rw-r--r--Source/cmQtAutoGeneratorInitializer.h36
-rw-r--r--Source/cmQtAutoGenerators.cxx1385
-rw-r--r--Source/cmQtAutoGenerators.h123
-rw-r--r--Source/cmQtAutomoc.cxx1299
-rw-r--r--Source/cmQtAutomoc.h96
-rw-r--r--Source/cmRST.cxx499
-rw-r--r--Source/cmRST.h100
-rw-r--r--Source/cmRemoveCommand.cxx7
-rw-r--r--Source/cmRemoveCommand.h28
-rw-r--r--Source/cmRemoveDefinitionsCommand.h21
-rw-r--r--Source/cmReturnCommand.h28
-rw-r--r--Source/cmScriptGenerator.cxx35
-rw-r--r--Source/cmScriptGenerator.h15
-rw-r--r--Source/cmSearchPath.cxx274
-rw-r--r--Source/cmSearchPath.h57
-rw-r--r--Source/cmSeparateArgumentsCommand.cxx10
-rw-r--r--Source/cmSeparateArgumentsCommand.h39
-rw-r--r--Source/cmSetCommand.cxx58
-rw-r--r--Source/cmSetCommand.h110
-rw-r--r--Source/cmSetDirectoryPropertiesCommand.cxx4
-rw-r--r--Source/cmSetDirectoryPropertiesCommand.h25
-rw-r--r--Source/cmSetPropertyCommand.cxx151
-rw-r--r--Source/cmSetPropertyCommand.h55
-rw-r--r--Source/cmSetSourceFilesPropertiesCommand.cxx6
-rw-r--r--Source/cmSetSourceFilesPropertiesCommand.h27
-rw-r--r--Source/cmSetTargetPropertiesCommand.cxx40
-rw-r--r--Source/cmSetTargetPropertiesCommand.h125
-rw-r--r--Source/cmSetTestsPropertiesCommand.cxx40
-rw-r--r--Source/cmSetTestsPropertiesCommand.h38
-rw-r--r--Source/cmSiteNameCommand.cxx12
-rw-r--r--Source/cmSiteNameCommand.h19
-rw-r--r--Source/cmSourceFile.cxx290
-rw-r--r--Source/cmSourceFile.h35
-rw-r--r--Source/cmSourceFileLocation.cxx197
-rw-r--r--Source/cmSourceFileLocation.h17
-rw-r--r--Source/cmSourceGroup.cxx12
-rw-r--r--Source/cmSourceGroup.h6
-rw-r--r--Source/cmSourceGroupCommand.cxx12
-rw-r--r--Source/cmSourceGroupCommand.h32
-rw-r--r--Source/cmStandardIncludes.cxx16
-rw-r--r--Source/cmStandardIncludes.h292
-rw-r--r--Source/cmStandardLexer.h25
-rw-r--r--Source/cmState.cxx2010
-rw-r--r--Source/cmState.h364
-rw-r--r--Source/cmStringCommand.cxx372
-rw-r--r--Source/cmStringCommand.h140
-rw-r--r--Source/cmSubdirCommand.cxx25
-rw-r--r--Source/cmSubdirCommand.h42
-rw-r--r--Source/cmSubdirDependsCommand.cxx4
-rw-r--r--Source/cmSubdirDependsCommand.h54
-rw-r--r--Source/cmSystemTools.cxx1426
-rw-r--r--Source/cmSystemTools.h154
-rw-r--r--Source/cmTarget.cxx7028
-rw-r--r--Source/cmTarget.h663
-rw-r--r--Source/cmTargetCompileDefinitionsCommand.cxx11
-rw-r--r--Source/cmTargetCompileDefinitionsCommand.h39
-rw-r--r--Source/cmTargetCompileFeaturesCommand.cxx64
-rw-r--r--Source/cmTargetCompileFeaturesCommand.h41
-rw-r--r--Source/cmTargetCompileOptionsCommand.cxx25
-rw-r--r--Source/cmTargetCompileOptionsCommand.h41
-rw-r--r--Source/cmTargetDepend.h13
-rw-r--r--Source/cmTargetExport.h5
-rw-r--r--Source/cmTargetIncludeDirectoriesCommand.cxx48
-rw-r--r--Source/cmTargetIncludeDirectoriesCommand.h51
-rw-r--r--Source/cmTargetLinkLibrariesCommand.cxx129
-rw-r--r--Source/cmTargetLinkLibrariesCommand.h155
-rw-r--r--Source/cmTargetPropCommandBase.cxx50
-rw-r--r--Source/cmTargetPropCommandBase.h8
-rw-r--r--Source/cmTargetSourcesCommand.cxx57
-rw-r--r--Source/cmTargetSourcesCommand.h55
-rw-r--r--Source/cmTest.cxx159
-rw-r--r--Source/cmTest.h31
-rw-r--r--Source/cmTestGenerator.cxx106
-rw-r--r--Source/cmTestGenerator.h6
-rw-r--r--Source/cmTimestamp.cxx8
-rw-r--r--Source/cmTryCompileCommand.h77
-rw-r--r--Source/cmTryRunCommand.cxx112
-rw-r--r--Source/cmTryRunCommand.h59
-rw-r--r--Source/cmUnsetCommand.cxx10
-rw-r--r--Source/cmUnsetCommand.h26
-rw-r--r--Source/cmUseMangledMesaCommand.cxx17
-rw-r--r--Source/cmUseMangledMesaCommand.h61
-rw-r--r--Source/cmUtilitySourceCommand.cxx25
-rw-r--r--Source/cmUtilitySourceCommand.h69
-rw-r--r--Source/cmUuid.cxx214
-rw-r--r--Source/cmUuid.h55
-rw-r--r--Source/cmVS10LinkFlagTable.h8
-rw-r--r--Source/cmVS10MASMFlagTable.h96
-rw-r--r--Source/cmVS10RCFlagTable.h7
-rw-r--r--Source/cmVS11CLFlagTable.h9
-rw-r--r--Source/cmVS11LinkFlagTable.h8
-rw-r--r--Source/cmVS11MASMFlagTable.h96
-rw-r--r--Source/cmVS11RCFlagTable.h7
-rw-r--r--Source/cmVS12CLFlagTable.h9
-rw-r--r--Source/cmVS12LinkFlagTable.h8
-rw-r--r--Source/cmVS12MASMFlagTable.h96
-rw-r--r--Source/cmVS12RCFlagTable.h7
-rw-r--r--Source/cmVS14CLFlagTable.h296
-rw-r--r--Source/cmVS14LibFlagTable.h102
-rw-r--r--Source/cmVS14LinkFlagTable.h343
-rw-r--r--Source/cmVS14MASMFlagTable.h96
-rw-r--r--Source/cmVS14RCFlagTable.h7
-rw-r--r--Source/cmVariableRequiresCommand.cxx19
-rw-r--r--Source/cmVariableRequiresCommand.h60
-rw-r--r--Source/cmVariableWatch.cxx28
-rw-r--r--Source/cmVariableWatch.h5
-rw-r--r--Source/cmVariableWatchCommand.cxx28
-rw-r--r--Source/cmVariableWatchCommand.h23
-rw-r--r--Source/cmVersion.cxx2
-rw-r--r--Source/cmVersion.h7
-rw-r--r--Source/cmVersionConfig.h.in1
-rw-r--r--Source/cmVersionMacros.h4
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx2816
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h84
-rw-r--r--Source/cmVisualStudioGeneratorOptions.cxx129
-rw-r--r--Source/cmVisualStudioGeneratorOptions.h14
-rw-r--r--Source/cmVisualStudioSlnParser.cxx3
-rw-r--r--Source/cmVisualStudioWCEPlatformParser.cxx20
-rw-r--r--Source/cmVisualStudioWCEPlatformParser.h4
-rw-r--r--Source/cmWhileCommand.cxx51
-rw-r--r--Source/cmWhileCommand.h33
-rw-r--r--Source/cmWin32ProcessExecution.cxx884
-rw-r--r--Source/cmWin32ProcessExecution.h169
-rw-r--r--Source/cmWriteFileCommand.cxx9
-rw-r--r--Source/cmWriteFileCommand.h34
-rw-r--r--Source/cmXCode21Object.cxx8
-rw-r--r--Source/cmXCodeObject.cxx39
-rw-r--r--Source/cmXCodeObject.h68
-rw-r--r--Source/cmXMLParser.cxx22
-rw-r--r--Source/cmXMLParser.h13
-rw-r--r--Source/cmXMLSafe.cxx12
-rw-r--r--Source/cmXMLSafe.h12
-rw-r--r--Source/cmXMLWriter.cxx134
-rw-r--r--Source/cmXMLWriter.h120
-rw-r--r--Source/cm_get_date.c16
-rw-r--r--Source/cm_get_date.h28
-rw-r--r--Source/cm_sha2.c40
-rw-r--r--Source/cm_sha2.h10
-rw-r--r--Source/cmake.cxx3633
-rw-r--r--Source/cmake.h499
-rw-r--r--Source/cmake.version.manifest18
-rw-r--r--Source/cmakemain.cxx437
-rw-r--r--Source/cmaketest.h.in16
-rw-r--r--Source/cmakewizard.cxx155
-rw-r--r--Source/cmakewizard.h42
-rw-r--r--Source/cmcldeps.cxx16
-rw-r--r--Source/cmcmd.cxx1782
-rw-r--r--Source/cmcmd.h40
-rwxr-xr-xSource/cmparseMSBuildXML.py3
-rw-r--r--Source/cmw9xcom.cxx45
-rw-r--r--Source/ctest.cxx315
-rw-r--r--Source/kwsys/.gitattributes12
-rw-r--r--Source/kwsys/Base64.c24
-rw-r--r--Source/kwsys/Base64.h.in18
-rw-r--r--Source/kwsys/CMakeEmptyInputFile.in1
-rw-r--r--Source/kwsys/CMakeLists.txt536
-rw-r--r--Source/kwsys/CONTRIBUTING.rst35
-rw-r--r--Source/kwsys/CPU.h.in125
-rw-r--r--Source/kwsys/CTestCustom.cmake.in14
-rw-r--r--Source/kwsys/CommandLineArguments.cxx111
-rw-r--r--Source/kwsys/CommandLineArguments.hxx.in56
-rw-r--r--Source/kwsys/Configure.h.in5
-rw-r--r--Source/kwsys/Configure.hxx.in150
-rw-r--r--Source/kwsys/Directory.cxx92
-rw-r--r--Source/kwsys/Directory.hxx.in5
-rw-r--r--Source/kwsys/DynamicLoader.cxx85
-rw-r--r--Source/kwsys/DynamicLoader.hxx.in7
-rw-r--r--Source/kwsys/Encoding.h.in79
-rw-r--r--Source/kwsys/Encoding.hxx.in77
-rw-r--r--Source/kwsys/EncodingC.c85
-rw-r--r--Source/kwsys/EncodingCXX.cxx185
-rw-r--r--Source/kwsys/FStream.cxx78
-rw-r--r--Source/kwsys/FStream.hxx.in194
-rw-r--r--Source/kwsys/FundamentalType.h.in146
-rw-r--r--Source/kwsys/Glob.cxx219
-rw-r--r--Source/kwsys/Glob.hxx.in79
-rw-r--r--Source/kwsys/IOStream.cxx88
-rw-r--r--Source/kwsys/IOStream.hxx.in32
-rw-r--r--Source/kwsys/MD5.c13
-rw-r--r--Source/kwsys/Process.h.in138
-rw-r--r--Source/kwsys/ProcessUNIX.c719
-rw-r--r--Source/kwsys/ProcessWin32.c1168
-rw-r--r--Source/kwsys/README.txt2
-rw-r--r--Source/kwsys/RegularExpression.cxx7
-rw-r--r--Source/kwsys/RegularExpression.hxx.in91
-rw-r--r--Source/kwsys/SharedForward.h.in34
-rw-r--r--Source/kwsys/String.hxx.in10
-rw-r--r--Source/kwsys/System.c559
-rw-r--r--Source/kwsys/System.h.in93
-rw-r--r--Source/kwsys/SystemInformation.cxx625
-rw-r--r--Source/kwsys/SystemInformation.hxx.in39
-rw-r--r--Source/kwsys/SystemTools.cxx2299
-rw-r--r--Source/kwsys/SystemTools.hxx.in493
-rw-r--r--Source/kwsys/Terminal.c19
-rw-r--r--Source/kwsys/hash_fun.hxx.in46
-rw-r--r--Source/kwsys/hash_map.hxx.in124
-rw-r--r--Source/kwsys/hash_set.hxx.in122
-rw-r--r--Source/kwsys/hashtable.hxx.in392
-rw-r--r--Source/kwsys/kwsysPlatformTests.cmake96
-rw-r--r--Source/kwsys/kwsysPlatformTestsCXX.cxx415
-rw-r--r--Source/kwsys/kwsys_cstddef.hxx.in35
-rw-r--r--Source/kwsys/kwsys_ios_fstream.h.in46
-rw-r--r--Source/kwsys/kwsys_ios_iosfwd.h.in49
-rw-r--r--Source/kwsys/kwsys_ios_iostream.h.in99
-rw-r--r--Source/kwsys/kwsys_ios_sstream.h.in199
-rw-r--r--Source/kwsys/kwsys_stl.hxx.in49
-rw-r--r--Source/kwsys/kwsys_stl_string.hxx.in123
-rw-r--r--Source/kwsys/testCommandLineArguments.cxx70
-rw-r--r--Source/kwsys/testCommandLineArguments1.cxx36
-rw-r--r--Source/kwsys/testDynamicLoader.cxx35
-rw-r--r--Source/kwsys/testEncoding.cxx198
-rw-r--r--Source/kwsys/testFStream.cxx138
-rw-r--r--Source/kwsys/testHashSTL.cxx14
-rw-r--r--Source/kwsys/testIOS.cxx73
-rw-r--r--Source/kwsys/testProcess.c310
-rw-r--r--Source/kwsys/testSystemInformation.cxx23
-rw-r--r--Source/kwsys/testSystemTools.cxx908
-rw-r--r--Source/kwsys/testSystemTools.h.in5
-rw-r--r--Templates/CPack.GenericDescription.txt2
-rw-r--r--Templates/CPack.GenericLicense.txt2
-rw-r--r--Templates/CPackConfig.cmake.in8
-rw-r--r--Templates/TestDriver.cxx.in18
-rw-r--r--Templates/Windows/ApplicationIcon.pngbin0 -> 3392 bytes
-rw-r--r--Templates/Windows/Logo.pngbin0 -> 801 bytes
-rw-r--r--Templates/Windows/SmallLogo.pngbin0 -> 329 bytes
-rw-r--r--Templates/Windows/SmallLogo44x44.pngbin0 -> 554 bytes
-rw-r--r--Templates/Windows/SplashScreen.pngbin0 -> 2146 bytes
-rw-r--r--Templates/Windows/StoreLogo.pngbin0 -> 429 bytes
-rw-r--r--Templates/Windows/Windows_TemporaryKey.pfxbin0 -> 2560 bytes
-rw-r--r--Tests/AliasTarget/CMakeLists.txt39
-rw-r--r--Tests/AliasTarget/subdir/CMakeLists.txt3
-rw-r--r--Tests/AliasTarget/subdir/empty.cpp7
-rw-r--r--Tests/Assembler/CMakeLists.txt5
-rw-r--r--Tests/BootstrapTest.cmake10
-rw-r--r--Tests/BuildDepends/CMakeLists.txt155
-rw-r--r--Tests/BuildDepends/Project/CMakeLists.txt55
-rw-r--r--Tests/BuildDepends/Project/External/CMakeLists.txt14
-rw-r--r--Tests/BuildDepends/Project/bar.cxx6
-rw-r--r--Tests/BuildDepends/Project/object_depends.cxx1
-rw-r--r--Tests/BuildDepends/Project/object_depends_check.cmake7
-rw-r--r--Tests/BundleTest/BundleLib.cxx2
-rw-r--r--Tests/BundleTest/BundleSubDir/CMakeLists.txt4
-rw-r--r--Tests/BundleTest/CMakeLists.txt4
-rw-r--r--Tests/BundleUtilities/CMakeLists.txt21
-rw-r--r--Tests/CFBundleTest/CMakeLists.txt8
-rw-r--r--Tests/CFBundleTest/VerifyResult.cmake9
-rw-r--r--Tests/CMakeBuildTest.cmake.in5
-rw-r--r--Tests/CMakeCommands/add_compile_options/CMakeLists.txt7
-rw-r--r--Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt22
-rw-r--r--Tests/CMakeCommands/target_compile_definitions/consumer.c23
-rw-r--r--Tests/CMakeCommands/target_compile_definitions/consumer.cpp18
-rw-r--r--Tests/CMakeCommands/target_compile_features/CMakeLists.txt45
-rw-r--r--Tests/CMakeCommands/target_compile_features/dummy.cpp5
-rw-r--r--Tests/CMakeCommands/target_compile_features/lib_auto_type.cpp6
-rw-r--r--Tests/CMakeCommands/target_compile_features/lib_auto_type.h8
-rw-r--r--Tests/CMakeCommands/target_compile_features/lib_restrict.c9
-rw-r--r--Tests/CMakeCommands/target_compile_features/lib_restrict.h7
-rw-r--r--Tests/CMakeCommands/target_compile_features/lib_user.cpp7
-rw-r--r--Tests/CMakeCommands/target_compile_features/main.c12
-rw-r--r--Tests/CMakeCommands/target_compile_features/main.cpp6
-rw-r--r--Tests/CMakeCommands/target_compile_features/restrict_user.c14
-rw-r--r--Tests/CMakeCommands/target_compile_options/CMakeLists.txt15
-rw-r--r--Tests/CMakeCommands/target_compile_options/consumer.c23
-rw-r--r--Tests/CMakeCommands/target_compile_options/consumer.cpp18
-rw-r--r--Tests/CMakeCommands/target_include_directories/CMakeLists.txt24
-rw-r--r--Tests/CMakeCommands/target_include_directories/c_only/c_only.h2
-rw-r--r--Tests/CMakeCommands/target_include_directories/consumer.c10
-rw-r--r--Tests/CMakeCommands/target_include_directories/consumer.cpp14
-rw-r--r--Tests/CMakeCommands/target_include_directories/cxx_only/cxx_only.h2
-rw-r--r--Tests/CMakeCommands/target_include_directories/relative_dir/consumer/consumer.h2
-rw-r--r--Tests/CMakeCommands/target_link_libraries/CMakeLists.txt6
-rw-r--r--Tests/CMakeCommands/target_link_libraries/cmp0022/CMakeLists.txt12
-rw-r--r--Tests/CMakeCopyright.cmake22
-rw-r--r--Tests/CMakeInstall.cmake22
-rw-r--r--Tests/CMakeLib/CMakeLists.txt9
-rw-r--r--Tests/CMakeLib/PseudoMemcheck/CMakeLists.txt41
-rw-r--r--Tests/CMakeLib/PseudoMemcheck/NoLog/CMakeLists.txt22
-rw-r--r--Tests/CMakeLib/PseudoMemcheck/memtester.cxx.in58
-rw-r--r--Tests/CMakeLib/run_compile_commands.cxx10
-rw-r--r--Tests/CMakeLib/testRST.cxx101
-rw-r--r--Tests/CMakeLib/testRST.expect92
-rw-r--r--Tests/CMakeLib/testRST.rst99
-rw-r--r--Tests/CMakeLib/testRSTinclude1.rst6
-rw-r--r--Tests/CMakeLib/testRSTinclude2.rst3
-rw-r--r--Tests/CMakeLib/testRSTmod.cmake11
-rw-r--r--Tests/CMakeLib/testRSTtoc1.rst2
-rw-r--r--Tests/CMakeLib/testRSTtoc2.rst2
-rw-r--r--Tests/CMakeLib/testVisualStudioSlnParser.cxx60
-rw-r--r--Tests/CMakeLib/testXMLParser.cxx4
-rw-r--r--Tests/CMakeLib/testXMLSafe.cxx2
-rw-r--r--Tests/CMakeLists.txt1428
-rw-r--r--Tests/CMakeOnly/AllFindModules/CMakeLists.txt18
-rw-r--r--Tests/CMakeOnly/CMakeLists.txt2
-rw-r--r--Tests/CMakeOnly/CheckCXXCompilerFlag/CMakeLists.txt7
-rw-r--r--Tests/CMakeOnly/CheckStructHasMember/CMakeLists.txt93
-rw-r--r--Tests/CMakeOnly/CheckStructHasMember/cm_cshm.h9
-rw-r--r--Tests/CMakeOnly/CheckStructHasMember/cm_cshm.hxx16
-rw-r--r--Tests/CMakeOnly/CompilerIdC/CMakeLists.txt7
-rw-r--r--Tests/CMakeOnly/CompilerIdCXX/CMakeLists.txt7
-rw-r--r--Tests/CMakeOnly/CompilerIdFortran/CMakeLists.txt15
-rw-r--r--Tests/CMakeOnly/MajorVersionSelection/CMakeLists.txt6
-rw-r--r--Tests/CMakeOnly/Test.cmake.in11
-rw-r--r--Tests/CMakeTestBadCommandLines/RunCMake.cmake79
-rw-r--r--Tests/CMakeTests/CMakeLists.txt16
-rw-r--r--Tests/CMakeTests/CheckCMakeTest.cmake4
-rw-r--r--Tests/CMakeTests/CheckSourceTreeTest.cmake.in16
-rw-r--r--Tests/CMakeTests/ConfigureFile-DirOutput.cmake5
-rw-r--r--Tests/CMakeTests/ConfigureFile-NewLineStyle-COPYONLY.cmake3
-rw-r--r--Tests/CMakeTests/ConfigureFile-NewLineStyle-NoArg.cmake3
-rw-r--r--Tests/CMakeTests/ConfigureFile-NewLineStyle-ValidArg.cmake17
-rw-r--r--Tests/CMakeTests/ConfigureFile-NewLineStyle-WrongArg.cmake3
-rw-r--r--Tests/CMakeTests/ConfigureFile-Relative.cmake4
-rw-r--r--Tests/CMakeTests/ConfigureFileTest.cmake.in28
-rw-r--r--Tests/CMakeTests/ELFTest.cmake.in2
-rw-r--r--Tests/CMakeTests/ExecuteScriptTests.cmake4
-rw-r--r--Tests/CMakeTests/FileDownloadBadHashTest.cmake.in10
-rw-r--r--Tests/CMakeTests/FileDownloadTest.cmake.in13
-rw-r--r--Tests/CMakeTests/GetPropertyTest.cmake.in107
-rw-r--r--Tests/CMakeTests/IfTest.cmake.in11
-rw-r--r--Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in7
-rw-r--r--Tests/CMakeTests/List-Get-CMP0007-Warn.cmake6
-rw-r--r--Tests/CMakeTests/ListTest.cmake.in53
-rw-r--r--Tests/CMakeTests/PolicyCheckTest.cmake.in154
-rw-r--r--Tests/CMakeTests/StringTest.cmake.in4
-rw-r--r--Tests/CMakeTests/StringTestScript.cmake11
-rw-r--r--Tests/CMakeTests/VersionTest.cmake.in88
-rw-r--r--Tests/CMakeTests/WhileTest.cmake.in40
-rw-r--r--Tests/CMakeWizardTest.cmake52
-rw-r--r--Tests/CPackComponents/CMakeLists.txt2
-rw-r--r--Tests/CPackComponentsDEB/CMakeLists.txt135
-rw-r--r--Tests/CPackComponentsDEB/MyLibCPackConfig-components-depend1.cmake.in20
-rw-r--r--Tests/CPackComponentsDEB/MyLibCPackConfig-components-depend2.cmake.in29
-rw-r--r--Tests/CPackComponentsDEB/MyLibCPackConfig-components-description1.cmake.in22
-rw-r--r--Tests/CPackComponentsDEB/MyLibCPackConfig-components-description2.cmake.in26
-rw-r--r--Tests/CPackComponentsDEB/MyLibCPackConfig-components-lintian-dpkgdeb-checks.cmake.in15
-rw-r--r--Tests/CPackComponentsDEB/MyLibCPackConfig-components-shlibdeps1.cmake.in24
-rw-r--r--Tests/CPackComponentsDEB/MyLibCPackConfig-components-source.cmake.in33
-rw-r--r--Tests/CPackComponentsDEB/MyLibCPackConfig-compression.cmake.in11
-rw-r--r--Tests/CPackComponentsDEB/RunCPackVerifyResult-components-depend1.cmake85
-rw-r--r--Tests/CPackComponentsDEB/RunCPackVerifyResult-components-depend2.cmake97
-rw-r--r--Tests/CPackComponentsDEB/RunCPackVerifyResult-components-description1.cmake85
-rw-r--r--Tests/CPackComponentsDEB/RunCPackVerifyResult-components-description2.cmake85
-rw-r--r--Tests/CPackComponentsDEB/RunCPackVerifyResult-components-lintian-dpkgdeb-checks.cmake78
-rw-r--r--Tests/CPackComponentsDEB/RunCPackVerifyResult-components-shlibdeps1.cmake75
-rw-r--r--Tests/CPackComponentsDEB/RunCPackVerifyResult-components-source.cmake75
-rw-r--r--Tests/CPackComponentsDEB/RunCPackVerifyResult-compression.cmake54
-rw-r--r--Tests/CPackComponentsDEB/RunCPackVerifyResult.cmake203
-rw-r--r--Tests/CPackComponentsDEB/license.txt3
-rw-r--r--Tests/CPackComponentsDEB/mylib.cpp7
-rw-r--r--Tests/CPackComponentsDEB/mylib.h1
-rw-r--r--Tests/CPackComponentsDEB/mylibapp.cpp6
-rw-r--r--Tests/CPackComponentsForAll/CMakeLists.txt57
-rw-r--r--Tests/CPackComponentsForAll/MyLibCPackConfig-IgnoreGroup.cmake.in30
-rw-r--r--Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake238
-rw-r--r--Tests/CPackComponentsForAll/license.txt3
-rw-r--r--Tests/CPackComponentsForAll/mylib17
-rw-r--r--Tests/CPackComponentsForAll/symlink_postinstall_expected.txt57
-rw-r--r--Tests/CPackComponentsPrefix/CMakeLists.txt14
-rw-r--r--Tests/CPackComponentsPrefix/file-development.txt1
-rw-r--r--Tests/CPackComponentsPrefix/file-runtime.txt1
-rw-r--r--Tests/CPackWiXGenerator/CMakeLists.txt49
-rw-r--r--Tests/CPackWiXGenerator/RunCPackVerifyResult.cmake5
-rw-r--r--Tests/CPackWiXGenerator/license.txt9
-rw-r--r--Tests/CPackWiXGenerator/myotherapp.cpp1
-rw-r--r--Tests/CPackWiXGenerator/patch.xml7
-rw-r--r--Tests/CTestBuildCommandProjectInSubdir/CTestBuildCommandProjectInSubdir.cmake.in4
-rw-r--r--Tests/CTestConfig/dashboard.cmake.in5
-rw-r--r--Tests/CTestConfig/script.cmake.in5
-rw-r--r--Tests/CTestCoverageCollectGCOV/TestProject/3rdparty/foo.cpp1
-rw-r--r--Tests/CTestCoverageCollectGCOV/TestProject/CMakeLists.txt41
-rw-r--r--Tests/CTestCoverageCollectGCOV/TestProject/extra/extra.cpp1
-rw-r--r--Tests/CTestCoverageCollectGCOV/TestProject/fake_compile_time_gcno.cmake7
-rw-r--r--Tests/CTestCoverageCollectGCOV/TestProject/fake_run_time_gcda.cmake12
-rw-r--r--Tests/CTestCoverageCollectGCOV/TestProject/main.cpp1
-rw-r--r--Tests/CTestCoverageCollectGCOV/fakegcov.cmake14
-rw-r--r--Tests/CTestCoverageCollectGCOV/test.cmake.in50
-rw-r--r--Tests/CTestTest/test.cmake.in3
-rw-r--r--Tests/CTestTest2/test.cmake.in16
-rw-r--r--Tests/CTestTestBadExe/CTestConfig.cmake4
-rw-r--r--Tests/CTestTestBadExe/test.cmake.in7
-rw-r--r--Tests/CTestTestBadGenerator/CMakeLists.txt3
-rw-r--r--Tests/CTestTestBadGenerator/CTestConfig.cmake7
-rw-r--r--Tests/CTestTestBadGenerator/test.cmake.in21
-rw-r--r--Tests/CTestTestChecksum/test.cmake.in7
-rw-r--r--Tests/CTestTestConfigFileInBuildDir/CMakeLists.txt3
-rw-r--r--Tests/CTestTestConfigFileInBuildDir/CTestConfig.cmake7
-rw-r--r--Tests/CTestTestConfigFileInBuildDir/test1.cmake.in18
-rw-r--r--Tests/CTestTestConfigFileInBuildDir/test2.cmake.in18
-rw-r--r--Tests/CTestTestCostSerial/CTestConfig.cmake4
-rw-r--r--Tests/CTestTestCostSerial/test.cmake.in7
-rw-r--r--Tests/CTestTestCrash/CTestConfig.cmake4
-rw-r--r--Tests/CTestTestCrash/test.cmake.in7
-rw-r--r--Tests/CTestTestCycle/CTestConfig.cmake4
-rw-r--r--Tests/CTestTestCycle/test.cmake.in7
-rw-r--r--Tests/CTestTestDepends/CTestConfig.cmake4
-rw-r--r--Tests/CTestTestDepends/test.cmake.in7
-rw-r--r--Tests/CTestTestEmptyBinaryDirectory/test.cmake.in66
-rw-r--r--Tests/CTestTestFailedSubmits/test.cmake.in48
-rw-r--r--Tests/CTestTestFailure/CTestConfig.cmake4
-rw-r--r--Tests/CTestTestFailure/testNoBuild.cmake.in7
-rw-r--r--Tests/CTestTestFailure/testNoExe.cmake.in7
-rw-r--r--Tests/CTestTestFdSetSize/test.cmake.in5
-rw-r--r--Tests/CTestTestLabelRegExp/CTestTestfile.cmake.in8
-rw-r--r--Tests/CTestTestLabelRegExp/test.cmake.in37
-rw-r--r--Tests/CTestTestLaunchers/launcher_test_project/CMakeLists.txt19
-rw-r--r--Tests/CTestTestLaunchers/launcher_test_project/CTestConfig.cmake8
-rw-r--r--Tests/CTestTestLaunchers/launcher_test_project/command.cmake5
-rw-r--r--Tests/CTestTestLaunchers/test.cmake.in40
-rw-r--r--Tests/CTestTestMemcheck/CMakeLists.txt173
-rw-r--r--Tests/CTestTestMemcheck/CMakeLists.txt.in7
-rw-r--r--Tests/CTestTestMemcheck/CTestConfig.cmake.in9
-rw-r--r--Tests/CTestTestMemcheck/NoLogDummyChecker/CMakeLists.txt17
-rw-r--r--Tests/CTestTestMemcheck/memtester.cxx.in52
-rw-r--r--Tests/CTestTestMemcheck/test.cmake.in24
-rw-r--r--Tests/CTestTestMissingDependsExe/CMakeLists.txt10
-rw-r--r--Tests/CTestTestParallel/CTestConfig.cmake4
-rw-r--r--Tests/CTestTestParallel/test.cmake.in7
-rw-r--r--Tests/CTestTestResourceLock/CTestConfig.cmake4
-rw-r--r--Tests/CTestTestResourceLock/test.cmake.in7
-rw-r--r--Tests/CTestTestScheduler/CTestConfig.cmake4
-rw-r--r--Tests/CTestTestScheduler/test.cmake.in7
-rw-r--r--Tests/CTestTestSerialInDepends/CMakeLists.txt23
-rw-r--r--Tests/CTestTestSerialInDepends/test.ctest16
-rw-r--r--Tests/CTestTestSerialOrder/CMakeLists.txt40
-rw-r--r--Tests/CTestTestSerialOrder/test.cmake31
-rw-r--r--Tests/CTestTestSkipReturnCode/CMakeLists.txt8
-rw-r--r--Tests/CTestTestSkipReturnCode/CTestConfig.cmake7
-rw-r--r--Tests/CTestTestSkipReturnCode/test.cmake.in23
-rw-r--r--Tests/CTestTestStopTime/CTestConfig.cmake4
-rw-r--r--Tests/CTestTestStopTime/GetDate.cmake163
-rw-r--r--Tests/CTestTestStopTime/test.cmake.in7
-rw-r--r--Tests/CTestTestSubdir/CTestConfig.cmake4
-rw-r--r--Tests/CTestTestSubdir/test.cmake.in7
-rw-r--r--Tests/CTestTestTimeout/CMakeLists.txt19
-rw-r--r--Tests/CTestTestTimeout/CTestConfig.cmake4
-rw-r--r--Tests/CTestTestTimeout/check.cmake9
-rw-r--r--Tests/CTestTestTimeout/sleep.c21
-rw-r--r--Tests/CTestTestTimeout/test.cmake.in20
-rw-r--r--Tests/CTestTestTimeout/timeout.c18
-rw-r--r--Tests/CTestTestTimeout/timeout.cmake2
-rw-r--r--Tests/CTestTestUpload/CTestConfig.cmake4
-rw-r--r--Tests/CTestTestUpload/test.cmake.in7
-rw-r--r--Tests/CTestTestVerboseOutput/CMakeLists.txt11
-rw-r--r--Tests/CTestTestVerboseOutput/CTestConfig.cmake7
-rw-r--r--Tests/CTestTestVerboseOutput/nop.c4
-rw-r--r--Tests/CTestTestVerboseOutput/test.cmake.in20
-rw-r--r--Tests/CTestTestZeroTimeout/CTestConfig.cmake4
-rw-r--r--Tests/CTestTestZeroTimeout/test.cmake.in7
-rw-r--r--Tests/CTestUpdateCVS.cmake.in19
-rw-r--r--Tests/CTestUpdateCommon.cmake105
-rw-r--r--Tests/CTestUpdateGIT.cmake.in91
-rw-r--r--Tests/CTestUpdateHG.cmake.in19
-rw-r--r--Tests/CTestUpdateP4.cmake.in261
-rw-r--r--Tests/CTestUpdateSVN.cmake.in19
-rw-r--r--Tests/CheckCompilerRelatedVariables/CMakeLists.txt4
-rw-r--r--Tests/CoberturaCoverage/DartConfiguration.tcl.in8
-rw-r--r--Tests/CoberturaCoverage/coverage.xml.in112
-rw-r--r--Tests/CoberturaCoverage/src/main/java/org/cmake/CoverageTest.java52
-rw-r--r--Tests/CompatibleInterface/CMakeLists.txt50
-rw-r--r--Tests/CompatibleInterface/bar.cpp7
-rw-r--r--Tests/CompatibleInterface/foo.cpp4
-rw-r--r--Tests/CompatibleInterface/main.cpp23
-rw-r--r--Tests/CompileDefinitions/CMakeLists.txt6
-rw-r--r--Tests/CompileDefinitions/add_def_cmd/CMakeLists.txt12
-rw-r--r--Tests/CompileDefinitions/add_def_cmd_tprop/CMakeLists.txt16
-rw-r--r--Tests/CompileDefinitions/add_definitions_command/CMakeLists.txt15
-rw-r--r--Tests/CompileDefinitions/add_definitions_command_with_target_prop/CMakeLists.txt19
-rw-r--r--Tests/CompileDefinitions/compiletest.c4
-rw-r--r--Tests/CompileDefinitions/target_prop/CMakeLists.txt8
-rw-r--r--Tests/CompileDefinitions/target_prop/usetgt.c10
-rw-r--r--Tests/CompileFeatures/CMakeLists.txt337
-rw-r--r--Tests/CompileFeatures/c_function_prototypes.c9
-rw-r--r--Tests/CompileFeatures/c_restrict.c7
-rw-r--r--Tests/CompileFeatures/c_static_assert.c2
-rw-r--r--Tests/CompileFeatures/c_variadic_macros.c15
-rw-r--r--Tests/CompileFeatures/cxx_aggregate_default_initializers.cpp9
-rw-r--r--Tests/CompileFeatures/cxx_alias_templates.cpp11
-rw-r--r--Tests/CompileFeatures/cxx_alignas.cpp4
-rw-r--r--Tests/CompileFeatures/cxx_alignof.cpp5
-rw-r--r--Tests/CompileFeatures/cxx_attribute_deprecated.cpp11
-rw-r--r--Tests/CompileFeatures/cxx_attributes.cpp2
-rw-r--r--Tests/CompileFeatures/cxx_auto_type.cpp12
-rw-r--r--Tests/CompileFeatures/cxx_binary_literals.cpp6
-rw-r--r--Tests/CompileFeatures/cxx_constexpr.cpp5
-rw-r--r--Tests/CompileFeatures/cxx_contextual_conversions.cpp33
-rw-r--r--Tests/CompileFeatures/cxx_decltype.cpp7
-rw-r--r--Tests/CompileFeatures/cxx_decltype_auto.cpp6
-rw-r--r--Tests/CompileFeatures/cxx_decltype_incomplete_return_types.cpp14
-rw-r--r--Tests/CompileFeatures/cxx_default_function_template_args.cpp12
-rw-r--r--Tests/CompileFeatures/cxx_defaulted_functions.cpp9
-rw-r--r--Tests/CompileFeatures/cxx_defaulted_move_initializers.cpp7
-rw-r--r--Tests/CompileFeatures/cxx_delegating_constructors.cpp15
-rw-r--r--Tests/CompileFeatures/cxx_deleted_functions.cpp6
-rw-r--r--Tests/CompileFeatures/cxx_digit_separators.cpp6
-rw-r--r--Tests/CompileFeatures/cxx_enum_forward_declarations.cpp8
-rw-r--r--Tests/CompileFeatures/cxx_explicit_conversions.cpp10
-rw-r--r--Tests/CompileFeatures/cxx_extended_friend_declarations.cpp25
-rw-r--r--Tests/CompileFeatures/cxx_extern_templates.cpp12
-rw-r--r--Tests/CompileFeatures/cxx_final.cpp2
-rw-r--r--Tests/CompileFeatures/cxx_func_identifier.cpp6
-rw-r--r--Tests/CompileFeatures/cxx_generalized_initializers.cpp28
-rw-r--r--Tests/CompileFeatures/cxx_generic_lambdas.cpp6
-rw-r--r--Tests/CompileFeatures/cxx_inheriting_constructors.cpp18
-rw-r--r--Tests/CompileFeatures/cxx_inline_namespaces.cpp26
-rw-r--r--Tests/CompileFeatures/cxx_lambda_init_captures.cpp6
-rw-r--r--Tests/CompileFeatures/cxx_lambdas.cpp5
-rw-r--r--Tests/CompileFeatures/cxx_local_type_template_args.cpp21
-rw-r--r--Tests/CompileFeatures/cxx_long_long_type.cpp5
-rw-r--r--Tests/CompileFeatures/cxx_noexcept.cpp5
-rw-r--r--Tests/CompileFeatures/cxx_nonstatic_member_init.cpp4
-rw-r--r--Tests/CompileFeatures/cxx_nullptr.cpp10
-rw-r--r--Tests/CompileFeatures/cxx_override.cpp7
-rw-r--r--Tests/CompileFeatures/cxx_range_for.cpp10
-rw-r--r--Tests/CompileFeatures/cxx_raw_string_literals.cpp7
-rw-r--r--Tests/CompileFeatures/cxx_reference_qualified_functions.cpp11
-rw-r--r--Tests/CompileFeatures/cxx_relaxed_constexpr.cpp23
-rw-r--r--Tests/CompileFeatures/cxx_return_type_deduction.cpp10
-rw-r--r--Tests/CompileFeatures/cxx_right_angle_brackets.cpp12
-rw-r--r--Tests/CompileFeatures/cxx_rvalue_references.cpp5
-rw-r--r--Tests/CompileFeatures/cxx_sizeof_member.cpp10
-rw-r--r--Tests/CompileFeatures/cxx_static_assert.cpp2
-rw-r--r--Tests/CompileFeatures/cxx_strong_enums.cpp7
-rw-r--r--Tests/CompileFeatures/cxx_template_template_parameters.cpp18
-rw-r--r--Tests/CompileFeatures/cxx_thread_local.cpp2
-rw-r--r--Tests/CompileFeatures/cxx_trailing_return_types.cpp5
-rw-r--r--Tests/CompileFeatures/cxx_unicode_literals.cpp3
-rw-r--r--Tests/CompileFeatures/cxx_uniform_initialization.cpp9
-rw-r--r--Tests/CompileFeatures/cxx_unrestricted_unions.cpp11
-rw-r--r--Tests/CompileFeatures/cxx_user_literals.cpp7
-rw-r--r--Tests/CompileFeatures/cxx_variable_templates.cpp10
-rw-r--r--Tests/CompileFeatures/cxx_variadic_macros.cpp12
-rw-r--r--Tests/CompileFeatures/cxx_variadic_templates.cpp74
-rw-r--r--Tests/CompileFeatures/default_dialect.c22
-rw-r--r--Tests/CompileFeatures/default_dialect.cpp25
-rw-r--r--Tests/CompileFeatures/feature_test.c10
-rw-r--r--Tests/CompileFeatures/feature_test.cpp10
-rw-r--r--Tests/CompileFeatures/genex_test.c38
-rw-r--r--Tests/CompileFeatures/genex_test.cpp72
-rw-r--r--Tests/CompileFeatures/main.cpp6
-rw-r--r--Tests/CompileOptions/CMakeLists.txt6
-rw-r--r--Tests/CompileOptions/main.cpp3
-rw-r--r--Tests/Complex/CMakeLists.txt57
-rw-r--r--Tests/Complex/Executable/CMakeLists.txt17
-rw-r--r--Tests/Complex/Executable/complex.cxx28
-rw-r--r--Tests/Complex/Library/CMakeLists.txt2
-rw-r--r--Tests/ComplexOneConfig/CMakeLists.txt50
-rw-r--r--Tests/ComplexOneConfig/Executable/CMakeLists.txt17
-rw-r--r--Tests/ComplexOneConfig/Executable/complex.cxx28
-rw-r--r--Tests/ComplexOneConfig/Library/CMakeLists.txt2
-rw-r--r--Tests/ConfigSources/CMakeLists.txt17
-rw-r--r--Tests/ConfigSources/iface_debug.h4
-rw-r--r--Tests/ConfigSources/iface_debug_src.cpp7
-rw-r--r--Tests/ConfigSources/iface_src.cpp5
-rw-r--r--Tests/ConfigSources/main.cpp7
-rw-r--r--Tests/Contracts/Trilinos-10-6/CMakeLists.txt103
-rw-r--r--Tests/Contracts/Trilinos-10-6/Dashboard.cmake.in63
-rw-r--r--Tests/Contracts/Trilinos-10-6/RunTest.cmake7
-rw-r--r--Tests/Contracts/Trilinos-10-6/ValidateBuild.cmake.in39
-rw-r--r--Tests/Contracts/Trilinos/CMakeLists.txt103
-rw-r--r--Tests/Contracts/Trilinos/Dashboard.cmake.in63
-rw-r--r--Tests/Contracts/Trilinos/EnvScript.cmake (renamed from Tests/Contracts/Trilinos-10-6/EnvScript.cmake)0
-rw-r--r--Tests/Contracts/Trilinos/Patch.cmake (renamed from Tests/Contracts/Trilinos-10-6/Patch.cmake)0
-rw-r--r--Tests/Contracts/Trilinos/RunTest.cmake7
-rw-r--r--Tests/Contracts/Trilinos/ValidateBuild.cmake.in39
-rw-r--r--Tests/Contracts/VTK/CMakeLists.txt47
-rw-r--r--Tests/Contracts/VTK/Dashboard.cmake.in37
-rw-r--r--Tests/Contracts/VTK/RunTest.cmake3
-rw-r--r--Tests/Contracts/vtk542/CMakeLists.txt30
-rw-r--r--Tests/Contracts/vtk542/RunTest.cmake1
-rw-r--r--Tests/CustomCommand/CMakeLists.txt96
-rw-r--r--Tests/CustomCommand/config.h.in1
-rw-r--r--Tests/CustomCommand/foo.in8
-rw-r--r--Tests/CustomCommand/source_in_custom_target.cpp0
-rw-r--r--Tests/CustomCommand/subdir.h.in1
-rw-r--r--Tests/CustomCommandByproducts/CMakeLists.txt148
-rw-r--r--Tests/CustomCommandByproducts/CustomCommandByproducts.c23
-rw-r--r--Tests/CustomCommandByproducts/External/CMakeLists.txt4
-rw-r--r--Tests/CustomCommandByproducts/External/ExternalLibrary.c1
-rw-r--r--Tests/CustomCommandByproducts/ProducerExe.c1
-rw-r--r--Tests/CustomCommandByproducts/byproduct1.c.in1
-rw-r--r--Tests/CustomCommandByproducts/byproduct2.c.in1
-rw-r--r--Tests/CustomCommandByproducts/byproduct3.c.in1
-rw-r--r--Tests/CustomCommandByproducts/byproduct4.c.in1
-rw-r--r--Tests/CustomCommandByproducts/byproduct5.c.in1
-rw-r--r--Tests/CustomCommandByproducts/byproduct6.c.in1
-rw-r--r--Tests/CustomCommandByproducts/byproduct7.c.in1
-rw-r--r--Tests/CustomCommandByproducts/byproduct8.c.in1
-rw-r--r--Tests/CustomCommandByproducts/ninja-check.cmake20
-rw-r--r--Tests/CxxDialect/CMakeLists.txt28
-rw-r--r--Tests/CxxDialect/use_constexpr.cxx10
-rw-r--r--Tests/CxxDialect/use_constexpr_and_typeof.cxx11
-rw-r--r--Tests/CxxDialect/use_typeof.cxx6
-rw-r--r--Tests/CxxSubdirC/CMakeLists.txt4
-rw-r--r--Tests/CxxSubdirC/Cdir/CMakeLists.txt2
-rw-r--r--Tests/CxxSubdirC/Cdir/Cobj.c1
-rw-r--r--Tests/CxxSubdirC/main.cxx2
-rw-r--r--Tests/DelphiCoverage/DartConfiguration.tcl.in8
-rw-r--r--Tests/DelphiCoverage/UTCovTest(UTCovTest.pas).html.in117
-rw-r--r--Tests/DelphiCoverage/src/UTCovTest.pas75
-rw-r--r--Tests/Dependency/CMakeLists.txt1
-rw-r--r--Tests/Dependency/Case5/CMakeLists.txt8
-rw-r--r--Tests/Dependency/Case5/bar.c12
-rw-r--r--Tests/Dependency/Case5/foo.c9
-rw-r--r--Tests/Dependency/Case5/main.c7
-rw-r--r--Tests/DocTest/CMakeLists.txt7
-rw-r--r--Tests/DocTest/DocTest.cxx33
-rw-r--r--Tests/ExportImport/CMakeLists.txt7
-rw-r--r--Tests/ExportImport/Export/CMakeLists.txt167
-rw-r--r--Tests/ExportImport/Export/Interface/CMakeLists.txt72
-rw-r--r--Tests/ExportImport/Export/Interface/headeronly/headeronly.h7
-rw-r--r--Tests/ExportImport/Export/Interface/sharedlib.cpp7
-rw-r--r--Tests/ExportImport/Export/Interface/sharedlib/sharedlib.h7
-rw-r--r--Tests/ExportImport/Export/Interface/source_target.cpp13
-rw-r--r--Tests/ExportImport/Export/Interface/source_target_for_install.cpp13
-rw-r--r--Tests/ExportImport/Export/include/abs/1a/testLibAbs1a.h1
-rw-r--r--Tests/ExportImport/Export/include/abs/1b/testLibAbs1b.h1
-rw-r--r--Tests/ExportImport/Export/include/abs/testLibAbs1.h1
-rw-r--r--Tests/ExportImport/Export/systemlib.cpp7
-rw-r--r--Tests/ExportImport/Export/systemlib.h22
-rw-r--r--Tests/ExportImport/Export/testExe4.c24
-rw-r--r--Tests/ExportImport/Export/testLib1file1.txt1
-rw-r--r--Tests/ExportImport/Export/testLib1file2.txt1
-rw-r--r--Tests/ExportImport/Export/testLib7.c1
-rw-r--r--Tests/ExportImport/Export/testLibAbs1.c1
-rw-r--r--Tests/ExportImport/Export/testLibDepends.c7
-rw-r--r--Tests/ExportImport/Export/testLibNoSONAME.c7
-rw-r--r--Tests/ExportImport/Export/testLibPerConfigDest.c1
-rw-r--r--Tests/ExportImport/Export/testStaticLibRequiredPrivate.c1
-rw-r--r--Tests/ExportImport/Import/A/CMakeLists.txt154
-rw-r--r--Tests/ExportImport/Import/A/check_lib_nosoname.cmake7
-rw-r--r--Tests/ExportImport/Import/A/check_lib_soname.cmake7
-rw-r--r--Tests/ExportImport/Import/A/check_testLib1_genex.cmake11
-rw-r--r--Tests/ExportImport/Import/A/deps_iface.c6
-rw-r--r--Tests/ExportImport/Import/A/imp_testExe1.c8
-rw-r--r--Tests/ExportImport/Import/A/imp_testExeAbs1.c15
-rw-r--r--Tests/ExportImport/Import/A/test_system.cpp9
-rw-r--r--Tests/ExportImport/Import/CMakeLists.txt4
-rw-r--r--Tests/ExportImport/Import/Interface/CMakeLists.txt112
-rw-r--r--Tests/ExportImport/Import/Interface/headeronlytest.cpp17
-rw-r--r--Tests/ExportImport/Import/Interface/interfacetest.cpp20
-rw-r--r--Tests/ExportImport/Import/Interface/source_target_test.cpp7
-rw-r--r--Tests/ExportImport/InitialCache.cmake.in1
-rw-r--r--Tests/ExternalProject/CMakeLists.txt322
-rw-r--r--Tests/ExternalProject/Example/CMakeLists.txt2
-rw-r--r--Tests/ExternalProject/TryCheckout.cmake54
-rw-r--r--Tests/ExternalProject/gitrepo-sub.tgzbin0 -> 1911 bytes
-rw-r--r--Tests/ExternalProjectLocal/CMakeLists.txt255
-rw-r--r--Tests/ExternalProjectLocal/Step1.tar (renamed from Tests/ExternalProject/Step1.tar)bin5632 -> 5632 bytes
-rw-r--r--Tests/ExternalProjectLocal/Step1.tar.bz2 (renamed from Tests/ExternalProject/Step1.tar.bz2)bin904 -> 904 bytes
-rw-r--r--Tests/ExternalProjectLocal/Step1.tgz (renamed from Tests/ExternalProject/Step1.tgz)bin791 -> 791 bytes
-rw-r--r--Tests/ExternalProjectLocal/Step1.zip (renamed from Tests/ExternalProject/Step1.zip)bin1074 -> 1074 bytes
-rw-r--r--Tests/ExternalProjectLocal/Step1NoDir.tar (renamed from Tests/ExternalProject/Step1NoDir.tar)bin5120 -> 5120 bytes
-rw-r--r--Tests/ExternalProjectLocal/Step1NoDir.tar.bz2 (renamed from Tests/ExternalProject/Step1NoDir.tar.bz2)bin852 -> 852 bytes
-rw-r--r--Tests/ExternalProjectLocal/Step1NoDir.tgz (renamed from Tests/ExternalProject/Step1NoDir.tgz)bin770 -> 770 bytes
-rw-r--r--Tests/ExternalProjectLocal/Step1NoDir.zip (renamed from Tests/ExternalProject/Step1NoDir.zip)bin1038 -> 1038 bytes
-rw-r--r--Tests/ExternalProjectLocal/Step1Patch.cmake (renamed from Tests/ExternalProject/Step1Patch.cmake)0
-rw-r--r--Tests/ExternalProjectSubdir/CMakeLists.txt29
-rw-r--r--Tests/ExternalProjectSubdir/Subdir1/CMakeLists.txt14
-rw-r--r--Tests/ExternalProjectUpdate/CMakeLists.txt15
-rw-r--r--Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake99
-rw-r--r--Tests/FindBoost/CMakeLists.txt10
-rw-r--r--Tests/FindBoost/Test/CMakeLists.txt18
-rw-r--r--Tests/FindBoost/Test/main.cxx26
-rw-r--r--Tests/FindGSL/CMakeLists.txt9
-rw-r--r--Tests/FindGSL/rng/CMakeLists.txt14
-rw-r--r--Tests/FindGSL/rng/main.cc24
-rw-r--r--Tests/FindGTK2/CMakeLists.txt320
-rw-r--r--Tests/FindGTK2/atk/CMakeLists.txt10
-rw-r--r--Tests/FindGTK2/atk/main.c7
-rw-r--r--Tests/FindGTK2/atkmm/CMakeLists.txt10
-rw-r--r--Tests/FindGTK2/atkmm/main.cpp8
-rw-r--r--Tests/FindGTK2/cairo/CMakeLists.txt10
-rw-r--r--Tests/FindGTK2/cairo/main.c52
-rw-r--r--Tests/FindGTK2/cairomm/CMakeLists.txt10
-rw-r--r--Tests/FindGTK2/cairomm/main.cpp62
-rw-r--r--Tests/FindGTK2/gdk/CMakeLists.txt10
-rw-r--r--Tests/FindGTK2/gdk/main.c7
-rw-r--r--Tests/FindGTK2/gdk_pixbuf/CMakeLists.txt10
-rw-r--r--Tests/FindGTK2/gdk_pixbuf/main.c10
-rw-r--r--Tests/FindGTK2/gdkmm/CMakeLists.txt10
-rw-r--r--Tests/FindGTK2/gdkmm/main.cpp7
-rw-r--r--Tests/FindGTK2/gio/CMakeLists.txt10
-rw-r--r--Tests/FindGTK2/gio/main.c8
-rw-r--r--Tests/FindGTK2/giomm/CMakeLists.txt10
-rw-r--r--Tests/FindGTK2/giomm/main.cpp7
-rw-r--r--Tests/FindGTK2/glib/CMakeLists.txt10
-rw-r--r--Tests/FindGTK2/glib/main.c11
-rw-r--r--Tests/FindGTK2/glibmm/CMakeLists.txt10
-rw-r--r--Tests/FindGTK2/glibmm/main.cpp7
-rw-r--r--Tests/FindGTK2/gmodule/CMakeLists.txt10
-rw-r--r--Tests/FindGTK2/gmodule/main.c7
-rw-r--r--Tests/FindGTK2/gobject/CMakeLists.txt10
-rw-r--r--Tests/FindGTK2/gobject/main.c72
-rw-r--r--Tests/FindGTK2/gthread/CMakeLists.txt10
-rw-r--r--Tests/FindGTK2/gthread/main.c7
-rw-r--r--Tests/FindGTK2/gtk/CMakeLists.txt14
-rw-r--r--Tests/FindGTK2/gtk/main.c15
-rw-r--r--Tests/FindGTK2/gtkmm/CMakeLists.txt14
-rw-r--r--Tests/FindGTK2/gtkmm/helloworld.cpp29
-rw-r--r--Tests/FindGTK2/gtkmm/helloworld.h20
-rw-r--r--Tests/FindGTK2/gtkmm/main.cpp13
-rw-r--r--Tests/FindGTK2/pango/CMakeLists.txt10
-rw-r--r--Tests/FindGTK2/pango/main.c7
-rw-r--r--Tests/FindGTK2/pangocairo/CMakeLists.txt10
-rw-r--r--Tests/FindGTK2/pangocairo/main.c72
-rw-r--r--Tests/FindGTK2/pangoft2/CMakeLists.txt10
-rw-r--r--Tests/FindGTK2/pangoft2/main.c8
-rw-r--r--Tests/FindGTK2/pangomm/CMakeLists.txt10
-rw-r--r--Tests/FindGTK2/pangomm/main.cpp8
-rw-r--r--Tests/FindGTK2/pangoxft/CMakeLists.txt10
-rw-r--r--Tests/FindGTK2/pangoxft/main.c7
-rw-r--r--Tests/FindGTK2/sigc++/CMakeLists.txt10
-rw-r--r--Tests/FindGTK2/sigc++/main.cpp30
-rw-r--r--Tests/FindGTest/CMakeLists.txt10
-rw-r--r--Tests/FindGTest/Test/CMakeLists.txt17
-rw-r--r--Tests/FindGTest/Test/main.cxx6
-rw-r--r--Tests/FindJsonCpp/CMakeLists.txt10
-rw-r--r--Tests/FindJsonCpp/Test/CMakeLists.txt17
-rw-r--r--Tests/FindJsonCpp/Test/main.cxx8
-rw-r--r--Tests/FindMatlab/basic_checks/CMakeLists.txt57
-rw-r--r--Tests/FindMatlab/cmake_matlab_unit_tests1.m33
-rw-r--r--Tests/FindMatlab/cmake_matlab_unit_tests2.m6
-rw-r--r--Tests/FindMatlab/cmake_matlab_unit_tests3.m5
-rw-r--r--Tests/FindMatlab/cmake_matlab_unit_tests_timeout.m16
-rw-r--r--Tests/FindMatlab/help_text1.m.txt2
-rw-r--r--Tests/FindMatlab/matlab_wrapper1.cpp26
-rw-r--r--Tests/FindMatlab/versions_checks/CMakeLists.txt52
-rw-r--r--Tests/FindOpenSSL/CMakeLists.txt9
-rw-r--r--Tests/FindOpenSSL/rand/CMakeLists.txt14
-rw-r--r--Tests/FindOpenSSL/rand/main.cc22
-rw-r--r--Tests/FindPNG/CMakeLists.txt10
-rw-r--r--Tests/FindPNG/Test/CMakeLists.txt16
-rw-r--r--Tests/FindPNG/Test/main.c20
-rw-r--r--Tests/FindPackageModeMakefileTest/CMakeLists.txt14
-rw-r--r--Tests/FindPackageModeMakefileTest/Makefile.in13
-rw-r--r--Tests/FindPackageTest/CMakeLists.txt92
-rw-r--r--Tests/FindPackageTest/Exporter/CMakeTestExportPackageConfigVersion.cmake.in2
-rw-r--r--Tests/FindPackageTest/FindLotsOfComponents.cmake2
-rw-r--r--Tests/FindPackageTest/FindSomePackage.cmake5
-rw-r--r--Tests/FindPackageTest/FindUpperCasePackage.cmake5
-rw-r--r--Tests/FindTIFF/CMakeLists.txt10
-rw-r--r--Tests/FindTIFF/Test/CMakeLists.txt17
-rw-r--r--Tests/FindTIFF/Test/main.c12
-rw-r--r--Tests/FindThreads/C-only/CMakeLists.txt10
-rw-r--r--Tests/FindThreads/CMakeLists.txt11
-rw-r--r--Tests/FindThreads/CXX-only/CMakeLists.txt13
-rw-r--r--Tests/FindXalanC/CMakeLists.txt10
-rw-r--r--Tests/FindXalanC/Test/CMakeLists.txt17
-rw-r--r--Tests/FindXalanC/Test/main.cxx10
-rw-r--r--Tests/FindXercesC/CMakeLists.txt10
-rw-r--r--Tests/FindXercesC/Test/CMakeLists.txt17
-rw-r--r--Tests/FindXercesC/Test/main.cxx7
-rw-r--r--Tests/ForceInclude/CMakeLists.txt2
-rw-r--r--Tests/Fortran/CMakeLists.txt30
-rw-r--r--Tests/Fortran/Executable/CMakeLists.txt2
-rw-r--r--Tests/Fortran/Executable/main.f901
-rw-r--r--Tests/Fortran/Subdir/CMakeLists.txt2
-rw-r--r--Tests/Fortran/Subdir/subdir.f902
-rw-r--r--Tests/Fortran/test_preprocess.F902
-rw-r--r--Tests/Fortran/test_preprocess_module.F905
-rw-r--r--Tests/FortranC/CMakeLists.txt2
-rw-r--r--Tests/FortranC/Flags.cmake.in11
-rw-r--r--Tests/FortranOnly/CMakeLists.txt72
-rw-r--r--Tests/FortranOnly/preprocess.F5
-rw-r--r--Tests/FortranOnly/test_preprocess.cmake7
-rw-r--r--Tests/FunctionTest/CMakeLists.txt2
-rw-r--r--Tests/GeneratorExpression/CMP0044/CMakeLists.txt19
-rw-r--r--Tests/GeneratorExpression/CMP0044/cmp0044-check.cpp26
-rw-r--r--Tests/GeneratorExpression/CMakeLists.txt98
-rw-r--r--Tests/GeneratorExpression/check-common.cmake4
-rw-r--r--Tests/GeneratorExpression/check-part1.cmake3
-rw-r--r--Tests/GeneratorExpression/check-part3.cmake34
-rw-r--r--Tests/GeneratorExpression/check-part4.cmake15
-rw-r--r--Tests/GeneratorExpression/echo.c8
-rw-r--r--Tests/GeneratorExpression/pwd.c34
-rw-r--r--Tests/GhsMulti/CMakeLists.txt4
-rw-r--r--Tests/GhsMulti/ReturnNum/App/CMakeLists.txt4
-rw-r--r--Tests/GhsMulti/ReturnNum/App/Main.c8
-rw-r--r--Tests/GhsMulti/ReturnNum/CMakeLists.txt3
-rw-r--r--Tests/GhsMulti/ReturnNum/Int/AppDD.int12
-rw-r--r--Tests/GhsMulti/ReturnNum/Int/CMakeLists.txt1
-rw-r--r--Tests/GhsMulti/ReturnNum/Int/Default.bsp35
-rw-r--r--Tests/GhsMulti/ReturnNum/Lib/CMakeLists.txt1
-rw-r--r--Tests/GhsMulti/ReturnNum/Lib/HelperFun.c4
-rw-r--r--Tests/GhsMulti/ReturnNum/Lib/HelperFun.h1
-rw-r--r--Tests/IncludeDirectories/CMakeLists.txt2
-rw-r--r--Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt50
-rw-r--r--Tests/IncludeDirectories/SystemIncludeDirectories/config_specific/config_iface.h14
-rw-r--r--Tests/IncludeDirectories/SystemIncludeDirectories/consumer.cpp2
-rw-r--r--Tests/IncludeDirectories/SystemIncludeDirectories/imported_consumer.cpp7
-rw-r--r--Tests/IncludeDirectories/SystemIncludeDirectories/systemlib_header_only/systemlib.h16
-rw-r--r--Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt6
-rw-r--r--Tests/InterfaceLibrary/CMakeLists.txt61
-rw-r--r--Tests/InterfaceLibrary/broken.cpp2
-rw-r--r--Tests/InterfaceLibrary/definetestexe.cpp24
-rw-r--r--Tests/InterfaceLibrary/dummy.cpp5
-rw-r--r--Tests/InterfaceLibrary/headerdir/CMakeLists.txt13
-rw-r--r--Tests/InterfaceLibrary/headerdir/iface_header.h1
-rw-r--r--Tests/InterfaceLibrary/headerdir/iface_header_builddir.h.in1
-rw-r--r--Tests/InterfaceLibrary/ifacedir/CMakeLists.txt8
-rw-r--r--Tests/InterfaceLibrary/ifacedir/sub.cpp1
-rw-r--r--Tests/InterfaceLibrary/libsdir/CMakeLists.txt28
-rw-r--r--Tests/InterfaceLibrary/libsdir/shareddependlib.cpp7
-rw-r--r--Tests/InterfaceLibrary/libsdir/shareddependlib/shareddependlib.h12
-rw-r--r--Tests/InterfaceLibrary/libsdir/sharedlib.cpp12
-rw-r--r--Tests/InterfaceLibrary/libsdir/sharedlib/sharedlib.h15
-rw-r--r--Tests/InterfaceLibrary/map_config.cpp15
-rw-r--r--Tests/InterfaceLibrary/obj.cpp1
-rw-r--r--Tests/InterfaceLibrary/sharedlibtestexe.cpp19
-rw-r--r--Tests/InterfaceLinkLibraries/CMakeLists.txt12
-rw-r--r--Tests/InterfaceLinkLibraries/main.cpp8
-rw-r--r--Tests/InterfaceLinkLibraries/zot.cpp6
-rw-r--r--Tests/InterfaceLinkLibraries/zot.h7
-rw-r--r--Tests/InterfaceLinkLibraries/zot_vs6_1.cpp1
-rw-r--r--Tests/InterfaceLinkLibraries/zot_vs6_2.cpp1
-rw-r--r--Tests/InterfaceLinkLibraries/zot_vs6_3.cpp1
-rw-r--r--Tests/InterfaceLinkLibraries/zot_vs6_4.cpp1
-rw-r--r--Tests/JacocoCoverage/Coverage/src/main/java/org/cmake/CoverageTest.java52
-rw-r--r--Tests/JacocoCoverage/Coverage/target/site/jacoco.xml.in1
-rw-r--r--Tests/JacocoCoverage/DartConfiguration.tcl.in8
-rw-r--r--Tests/Java/CMakeLists.txt4
-rw-r--r--Tests/JavaJavah/B.cpp10
-rw-r--r--Tests/JavaJavah/B.java19
-rw-r--r--Tests/JavaJavah/C.cpp10
-rw-r--r--Tests/JavaJavah/C.java19
-rw-r--r--Tests/JavaJavah/CMakeLists.txt23
-rw-r--r--Tests/JavaJavah/HelloWorld2.java15
-rw-r--r--Tests/JavascriptCoverage/DartConfiguration.tcl.in8
-rw-r--r--Tests/JavascriptCoverage/output.json.in448
-rw-r--r--Tests/JavascriptCoverage/test.js53
-rw-r--r--Tests/JavascriptCoverage/test3.js37
-rw-r--r--Tests/LinkDirectory/CMakeLists.txt4
-rw-r--r--Tests/LinkStatic/CMakeLists.txt2
-rw-r--r--Tests/LoadCommand/CMakeLists.txt4
-rw-r--r--Tests/LoadCommand/LoadedCommand.cxx.in9
-rw-r--r--Tests/LoadCommand/LoadedCommand.h.in4
-rw-r--r--Tests/LoadCommandOneConfig/CMakeLists.txt4
-rw-r--r--Tests/LoadCommandOneConfig/LoadedCommand.cxx.in9
-rw-r--r--Tests/LoadCommandOneConfig/LoadedCommand.h.in4
-rw-r--r--Tests/MSManifest/CMakeLists.txt5
-rw-r--r--Tests/MSManifest/Subdir/CMakeLists.txt11
-rw-r--r--Tests/MSManifest/Subdir/check.cmake6
-rw-r--r--Tests/MSManifest/Subdir/main.c1
-rw-r--r--Tests/MSManifest/Subdir/test.manifest.in4
-rw-r--r--Tests/MacRuntimePath/A/CMakeLists.txt6
-rw-r--r--Tests/MacRuntimePath/CMakeLists.txt8
-rw-r--r--Tests/MacRuntimePath/InitialCache.cmake.in1
-rw-r--r--Tests/MacroTest/CMakeLists.txt2
-rw-r--r--Tests/MakeClean/CMakeLists.txt13
-rw-r--r--Tests/MakeClean/ToClean/CMakeLists.txt15
-rw-r--r--Tests/MissingInstall/CMakeLists.txt25
-rw-r--r--Tests/MissingInstall/ExpectInstallFail.cmake18
-rw-r--r--Tests/MissingInstall/mybin.cpp1
-rw-r--r--Tests/Module/CheckTypeSize/CMakeLists.txt15
-rw-r--r--Tests/Module/CheckTypeSize/CheckTypeSize.cxx172
-rw-r--r--Tests/Module/CheckTypeSize/config.hxx.in23
-rw-r--r--Tests/Module/CheckTypeSize/someclass.hxx14
-rw-r--r--Tests/Module/ExternalData/Alt/MyAlgoMap1-md5/dded55e43cd6529ee35d24113dfc87a31
-rw-r--r--Tests/Module/ExternalData/Alt/SHA1/85158f0c1996837976e858c42a9a7634bfe91b931
-rw-r--r--Tests/Module/ExternalData/CMakeLists.txt12
-rw-r--r--Tests/Module/ExternalData/Data1Check.cmake40
-rw-r--r--Tests/Module/ExternalData/Data4/CMakeLists.txt15
-rw-r--r--Tests/Module/ExternalData/Data4/Data.dat.md51
-rw-r--r--Tests/Module/ExternalData/Data4/Data4Check.cmake26
-rw-r--r--Tests/Module/ExternalData/Data4/Other.dat.md51
-rw-r--r--Tests/Module/ExternalData/DataAlgoMapA.dat.md51
-rw-r--r--Tests/Module/ExternalData/DataAlgoMapB.dat.sha11
-rw-r--r--Tests/Module/ExternalData/DataNoSymlinks/CMakeLists.txt8
-rw-r--r--Tests/Module/ExternalData/DataNoSymlinks/Data.dat.md51
-rw-r--r--Tests/Module/ExternalData/DataNoSymlinks/DataNoSymlinksCheck.cmake6
-rw-r--r--Tests/Module/ExternalData/DataScript.dat.md51
-rw-r--r--Tests/Module/ExternalData/DirRecurse/A.dat.md51
-rw-r--r--Tests/Module/ExternalData/DirRecurse/B.dat.md51
-rw-r--r--Tests/Module/ExternalData/DirRecurse/C.dat.md51
-rw-r--r--Tests/Module/ExternalData/DirRecurse/Sub1/A.dat.md51
-rw-r--r--Tests/Module/ExternalData/DirRecurse/Sub1/B.dat.md51
-rw-r--r--Tests/Module/ExternalData/DirRecurse/Sub1/C.dat.md51
-rw-r--r--Tests/Module/ExternalData/DirRecurse/Sub2/Dir/A.dat.md51
-rw-r--r--Tests/Module/ExternalData/DirRecurse/Sub2/Dir/B.dat.md51
-rw-r--r--Tests/Module/ExternalData/DirRecurse/Sub2/Dir/C.dat.md51
-rw-r--r--Tests/Module/ExternalData/MyScript1.cmake5
-rw-r--r--Tests/Module/FindDependency/CMakeLists.txt11
-rw-r--r--Tests/Module/FindDependency/main.cpp29
-rw-r--r--Tests/Module/FindDependency/packages/Pack1/Pack1Config.cmake9
-rw-r--r--Tests/Module/FindDependency/packages/Pack1/Pack1ConfigVersion.cmake11
-rw-r--r--Tests/Module/FindDependency/packages/Pack2/Pack2Config.cmake5
-rw-r--r--Tests/Module/FindDependency/packages/Pack2/Pack2ConfigVersion.cmake11
-rw-r--r--Tests/Module/FindDependency/packages/Pack3/Pack3Config.cmake5
-rw-r--r--Tests/Module/FindDependency/packages/Pack3/Pack3ConfigVersion.cmake11
-rw-r--r--Tests/Module/FindDependency/packages/Pack4/Pack4Config.cmake9
-rw-r--r--Tests/Module/FindDependency/packages/Pack4/Pack4ConfigVersion.cmake11
-rw-r--r--Tests/Module/FindDependency/packages/Pack5/Pack5Config.cmake3
-rw-r--r--Tests/Module/FindDependency/packages/Pack5/Pack5ConfigVersion.cmake11
-rw-r--r--Tests/Module/FindDependency/packages/Pack6/Pack6Config.cmake3
-rw-r--r--Tests/Module/FindDependency/packages/Pack6/Pack6ConfigVersion.cmake11
-rw-r--r--Tests/Module/GenerateExportHeader/CMakeLists.txt120
-rw-r--r--Tests/Module/GenerateExportHeader/exportheader_test.cpp66
-rw-r--r--Tests/Module/GenerateExportHeader/lib_shared_and_static/CMakeLists.txt16
-rw-r--r--Tests/Module/GenerateExportHeader/lib_shared_and_static/libshared_and_static.h26
-rw-r--r--Tests/Module/GenerateExportHeader/lib_shared_and_statictest/CMakeLists.txt33
-rw-r--r--Tests/Module/GenerateExportHeader/libsharedtest/CMakeLists.txt45
-rw-r--r--Tests/Module/GenerateExportHeader/libstatictest/CMakeLists.txt18
-rw-r--r--Tests/Module/GenerateExportHeader/override_symbol/CMakeLists.txt11
-rw-r--r--Tests/Module/GenerateExportHeader/override_symbol/main.cpp9
-rw-r--r--Tests/Module/GenerateExportHeader/override_symbol/someclass.cpp7
-rw-r--r--Tests/Module/GenerateExportHeader/override_symbol/someclass.h8
-rw-r--r--Tests/Module/GenerateExportHeader/prefix/CMakeLists.txt15
-rw-r--r--Tests/Module/GenerateExportHeader/prefix/main.cpp8
-rw-r--r--Tests/Module/GenerateExportHeader/prefix/useprefixclass.cpp7
-rw-r--r--Tests/Module/GenerateExportHeader/prefix/useprefixclass.h13
-rw-r--r--Tests/Module/GenerateExportHeader/reference/Empty/libshared_export.h41
-rw-r--r--Tests/Module/GenerateExportHeader/reference/Empty/libstatic_export.h41
-rw-r--r--Tests/Module/GenerateExportHeader/reference/MinGW/libshared_export.h41
-rw-r--r--Tests/Module/GenerateExportHeader/reference/MinGW/libstatic_export.h41
-rw-r--r--Tests/Module/GenerateExportHeader/reference/UNIX/libshared_export.h41
-rw-r--r--Tests/Module/GenerateExportHeader/reference/UNIX/libstatic_export.h41
-rw-r--r--Tests/Module/GenerateExportHeader/reference/UNIX_DeprecatedOnly/libshared_export.h41
-rw-r--r--Tests/Module/GenerateExportHeader/reference/UNIX_DeprecatedOnly/libstatic_export.h41
-rw-r--r--Tests/Module/GenerateExportHeader/reference/Win32/libshared_export.h41
-rw-r--r--Tests/Module/GenerateExportHeader/reference/Win32/libstatic_export.h41
-rw-r--r--Tests/Module/GenerateExportHeader/reference/WinEmpty/libshared_export.h41
-rw-r--r--Tests/Module/GenerateExportHeader/reference/WinEmpty/libstatic_export.h41
-rw-r--r--Tests/Module/GenerateExportHeader/visibility_preset/CMakeLists.txt17
-rw-r--r--Tests/Module/GenerateExportHeader/visibility_preset/main.cpp9
-rw-r--r--Tests/Module/GenerateExportHeader/visibility_preset/visibility_preset.cpp7
-rw-r--r--Tests/Module/GenerateExportHeader/visibility_preset/visibility_preset.h13
-rw-r--r--Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt154
-rw-r--r--Tests/Module/WriteCompilerDetectionHeader/c_undefined.c7
-rw-r--r--Tests/Module/WriteCompilerDetectionHeader/compile_tests.h25
-rw-r--r--Tests/Module/WriteCompilerDetectionHeader/main.c29
-rw-r--r--Tests/Module/WriteCompilerDetectionHeader/main.cpp14
-rw-r--r--Tests/Module/WriteCompilerDetectionHeader/main_multi.c29
-rw-r--r--Tests/Module/WriteCompilerDetectionHeader/multi_files.cpp14
-rw-r--r--Tests/ModuleDefinition/CMakeLists.txt2
-rw-r--r--Tests/MumpsCoverage/Accounts_ReceivableTest.cmcov304
-rw-r--r--Tests/MumpsCoverage/Accounts_ReceivableTest.mcov1445
-rw-r--r--Tests/MumpsCoverage/VistA-FOIA/Packages/Toolkit/Routines/XINDEX.m144
-rw-r--r--Tests/MumpsCoverage/VistA-FOIA/Packages/Uncategorized/ZZCOVTST.m43
-rw-r--r--Tests/MumpsCoverage/ZZCOVTST.cmcov45
-rw-r--r--Tests/MumpsCoverage/ZZCOVTST.mcov38
-rw-r--r--Tests/ObjectLibrary/A/CMakeLists.txt20
-rw-r--r--Tests/ObjectLibrary/B/CMakeLists.txt5
-rw-r--r--Tests/ObjectLibrary/CMakeLists.txt9
-rw-r--r--Tests/ObjectLibrary/ExportLanguages/CMakeLists.txt15
-rw-r--r--Tests/ObjectLibrary/ExportLanguages/ExportLanguagesTest/CMakeLists.txt14
-rw-r--r--Tests/ObjectLibrary/ExportLanguages/a.c1
-rw-r--r--Tests/ObjectLibrary/ExportLanguages/a.cxx (renamed from Tests/RunCMake/ObjectLibrary/a.cxx)0
-rw-r--r--Tests/OutDir/OutDir.cmake10
-rw-r--r--Tests/OutOfBinary/CMakeLists.txt2
-rw-r--r--Tests/OutOfBinary/outexe.c2
-rw-r--r--Tests/OutOfSource/SubDir/CMakeLists.txt2
-rw-r--r--Tests/OutOfSource/SubDir/subdir.c1
-rw-r--r--Tests/PDBDirectoryAndName/CMakeLists.txt32
-rw-r--r--Tests/PerConfig/perconfig.cmake4
-rw-r--r--Tests/Plugin/CMakeLists.txt55
-rw-r--r--Tests/Plugin/PluginTest/CMakeLists.txt27
-rw-r--r--Tests/Plugin/check_mod_soname.cmake17
-rw-r--r--Tests/Plugin/src/example_exe.cxx20
-rw-r--r--Tests/PositionIndependentTargets/CMakeLists.txt1
-rw-r--r--Tests/PositionIndependentTargets/interface/CMakeLists.txt27
-rw-r--r--Tests/PrecompiledHeader/CMakeLists.txt2
-rw-r--r--Tests/Preprocess/CMakeLists.txt27
-rw-r--r--Tests/Properties/CMakeLists.txt2
-rw-r--r--Tests/Properties/SubDir2/CMakeLists.txt5
-rw-r--r--Tests/Properties/subdirtest.cxx9
-rw-r--r--Tests/PythonCoverage/DartConfiguration.tcl.in8
-rw-r--r--Tests/PythonCoverage/coverage.xml.in35
-rw-r--r--Tests/PythonCoverage/coveragetest/foo.py8
-rw-r--r--Tests/PythonCoverage/coveragetest/test_foo.py11
-rw-r--r--Tests/Qt4And5Automoc/CMakeLists.txt24
-rw-r--r--Tests/Qt4And5Automoc/main.cpp.in (renamed from Tests/Qt4And5Automoc/main.cpp)0
-rw-r--r--Tests/Qt4And5Automoc/main_qt4.cpp4
-rw-r--r--Tests/Qt4And5Automoc/main_qt5.cpp4
-rw-r--r--Tests/Qt4Targets/CMakeLists.txt42
-rw-r--r--Tests/Qt4Targets/IncrementalMoc/CMakeLists.txt21
-rw-r--r--Tests/Qt4Targets/IncrementalMoc/foo.cpp8
-rw-r--r--Tests/Qt4Targets/IncrementalMoc/foo.h9
-rw-r--r--Tests/QtAutoUicInterface/CMakeLists.txt70
-rw-r--r--Tests/QtAutoUicInterface/klocalizedstring.cpp12
-rw-r--r--Tests/QtAutoUicInterface/klocalizedstring.h17
-rw-r--r--Tests/QtAutoUicInterface/libwidget.cpp9
-rw-r--r--Tests/QtAutoUicInterface/libwidget.h24
-rw-r--r--Tests/QtAutoUicInterface/libwidget.ui32
-rw-r--r--Tests/QtAutoUicInterface/main.cpp75
-rw-r--r--Tests/QtAutoUicInterface/mywidget.cpp9
-rw-r--r--Tests/QtAutoUicInterface/mywidget.h24
-rw-r--r--Tests/QtAutoUicInterface/mywidget.ui32
-rw-r--r--Tests/QtAutogen/Adir/CMakeLists.txt (renamed from Tests/QtAutomoc/Adir/CMakeLists.txt)0
-rw-r--r--Tests/QtAutogen/Adir/libA.cpp (renamed from Tests/QtAutomoc/Adir/libA.cpp)0
-rw-r--r--Tests/QtAutogen/Adir/libA.h (renamed from Tests/QtAutomoc/Adir/libA.h)0
-rw-r--r--Tests/QtAutogen/Bdir/CMakeLists.txt (renamed from Tests/QtAutomoc/Bdir/CMakeLists.txt)0
-rw-r--r--Tests/QtAutogen/Bdir/libB.cpp (renamed from Tests/QtAutomoc/Bdir/libB.cpp)0
-rw-r--r--Tests/QtAutogen/Bdir/libB.h (renamed from Tests/QtAutomoc/Bdir/libB.h)0
-rw-r--r--Tests/QtAutogen/CMakeLists.txt199
-rw-r--r--Tests/QtAutogen/abc.cpp (renamed from Tests/QtAutomoc/abc.cpp)0
-rw-r--r--Tests/QtAutogen/abc.h (renamed from Tests/QtAutomoc/abc.h)0
-rw-r--r--Tests/QtAutogen/abc_p.h (renamed from Tests/QtAutomoc/abc_p.h)0
-rw-r--r--Tests/QtAutogen/automoc_rerun/CMakeLists.txt27
-rw-r--r--Tests/QtAutogen/automoc_rerun/input.txt1
-rw-r--r--Tests/QtAutogen/automoc_rerun/res1.qrc5
-rw-r--r--Tests/QtAutogen/automoc_rerun/test1.cpp5
-rw-r--r--Tests/QtAutogen/automoc_rerun/test1.h.in18
-rw-r--r--Tests/QtAutogen/automoc_rerun/test1.h.in27
-rw-r--r--Tests/QtAutogen/autorcc_depends/CMakeLists.txt27
-rw-r--r--Tests/QtAutogen/autorcc_depends/res1.qrc.in5
-rw-r--r--Tests/QtAutogen/autorcc_depends/res1/input.txt.in1
-rw-r--r--Tests/QtAutogen/autorcc_depends/test_res1.cpp5
-rw-r--r--Tests/QtAutogen/bar.cpp (renamed from Tests/QtAutomoc/bar.cpp)0
-rw-r--r--Tests/QtAutogen/blub.cpp (renamed from Tests/QtAutomoc/blub.cpp)0
-rw-r--r--Tests/QtAutogen/blub.h (renamed from Tests/QtAutomoc/blub.h)0
-rw-r--r--Tests/QtAutogen/calwidget.cpp437
-rw-r--r--Tests/QtAutogen/calwidget.h128
-rw-r--r--Tests/QtAutogen/calwidget.ui32
-rw-r--r--Tests/QtAutogen/codeeditor.cpp (renamed from Tests/QtAutomoc/codeeditor.cpp)0
-rw-r--r--Tests/QtAutogen/codeeditor.h (renamed from Tests/QtAutomoc/codeeditor.h)0
-rw-r--r--Tests/QtAutogen/debug_class.cpp9
-rw-r--r--Tests/QtAutogen/debug_class.h20
-rw-r--r--Tests/QtAutogen/debug_class.ui45
-rw-r--r--Tests/QtAutogen/debug_resource.qrc5
-rw-r--r--Tests/QtAutogen/defines_test/CMakeLists.txt (renamed from Tests/QtAutomoc/defines_test/CMakeLists.txt)0
-rw-r--r--Tests/QtAutogen/defines_test/defines_test.cpp (renamed from Tests/QtAutomoc/defines_test/defines_test.cpp)0
-rw-r--r--Tests/QtAutogen/empty.cpp (renamed from Tests/QtAutomoc/empty.cpp)0
-rw-r--r--Tests/QtAutogen/empty.h (renamed from Tests/QtAutomoc/empty.h)0
-rw-r--r--Tests/QtAutogen/foo.cpp (renamed from Tests/QtAutomoc/foo.cpp)0
-rw-r--r--Tests/QtAutogen/foo.h (renamed from Tests/QtAutomoc/foo.h)0
-rw-r--r--Tests/QtAutogen/gadget.cpp4
-rw-r--r--Tests/QtAutogen/gadget.h18
-rw-r--r--Tests/QtAutogen/generated.cpp10
-rw-r--r--Tests/QtAutogen/generated.h18
-rw-r--r--Tests/QtAutogen/generated.txt.in1
-rw-r--r--Tests/QtAutogen/generated_resource.qrc.in5
-rw-r--r--Tests/QtAutogen/libC.cpp (renamed from Tests/QtAutomoc/libC.cpp)0
-rw-r--r--Tests/QtAutogen/libC.h (renamed from Tests/QtAutomoc/libC.h)0
-rw-r--r--Tests/QtAutogen/main.cpp94
-rw-r--r--Tests/QtAutogen/multiplewidgets.cpp19
-rw-r--r--Tests/QtAutogen/multiplewidgets.h33
-rw-r--r--Tests/QtAutogen/myinterface.h.in14
-rw-r--r--Tests/QtAutogen/myotherinterface.h.in14
-rw-r--r--Tests/QtAutogen/not_generated_file.qrc5
-rw-r--r--Tests/QtAutogen/private_slot.cpp (renamed from Tests/QtAutomoc/private_slot.cpp)0
-rw-r--r--Tests/QtAutogen/private_slot.h (renamed from Tests/QtAutomoc/private_slot.h)0
-rw-r--r--Tests/QtAutogen/rcconly.cpp9
-rw-r--r--Tests/QtAutogen/resourcetester.cpp27
-rw-r--r--Tests/QtAutogen/resourcetester.h17
-rw-r--r--Tests/QtAutogen/second_resource.qrc5
-rw-r--r--Tests/QtAutogen/second_widget.cpp14
-rw-r--r--Tests/QtAutogen/second_widget.h19
-rw-r--r--Tests/QtAutogen/second_widget.ui32
-rw-r--r--Tests/QtAutogen/sub/bar.h (renamed from Tests/QtAutomoc/sub/bar.h)0
-rw-r--r--Tests/QtAutogen/sub/uiconly.cpp13
-rw-r--r--Tests/QtAutogen/sub/uiconly.h20
-rw-r--r--Tests/QtAutogen/sub/uiconly.ui24
-rw-r--r--Tests/QtAutogen/targetObjectsTest.cpp5
-rw-r--r--Tests/QtAutogen/test.qrc5
-rw-r--r--Tests/QtAutogen/widget1.ui45
-rw-r--r--Tests/QtAutogen/widget2.ui29
-rw-r--r--Tests/QtAutogen/xyz.cpp (renamed from Tests/QtAutomoc/xyz.cpp)0
-rw-r--r--Tests/QtAutogen/xyz.h (renamed from Tests/QtAutomoc/xyz.h)0
-rw-r--r--Tests/QtAutogen/yaf.cpp (renamed from Tests/QtAutomoc/yaf.cpp)0
-rw-r--r--Tests/QtAutogen/yaf.h (renamed from Tests/QtAutomoc/yaf.h)0
-rw-r--r--Tests/QtAutogen/yaf_p.h (renamed from Tests/QtAutomoc/yaf_p.h)0
-rw-r--r--Tests/QtAutomoc/CMakeLists.txt68
-rw-r--r--Tests/QtAutomoc/calwidget.cpp431
-rw-r--r--Tests/QtAutomoc/calwidget.h121
-rw-r--r--Tests/QtAutomoc/main.cpp86
-rw-r--r--Tests/RegexEscapeString.cmake4
-rw-r--r--Tests/RunCMake/AutoExportDll/AutoExport.cmake7
-rw-r--r--Tests/RunCMake/AutoExportDll/AutoExportBuild-stderr.txt1
-rw-r--r--Tests/RunCMake/AutoExportDll/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake26
-rw-r--r--Tests/RunCMake/AutoExportDll/foo.c15
-rw-r--r--Tests/RunCMake/AutoExportDll/hello.cxx13
-rw-r--r--Tests/RunCMake/AutoExportDll/hello.h18
-rw-r--r--Tests/RunCMake/AutoExportDll/say.cxx37
-rw-r--r--Tests/RunCMake/AutoExportDll/sub/CMakeLists.txt5
-rw-r--r--Tests/RunCMake/AutoExportDll/sub/sub.cxx6
-rw-r--r--Tests/RunCMake/AutoExportDll/world.cxx6
-rw-r--r--Tests/RunCMake/BuildDepends/C-Exe-Manifest.cmake19
-rw-r--r--Tests/RunCMake/BuildDepends/C-Exe-Manifest.step1.cmake6
-rw-r--r--Tests/RunCMake/BuildDepends/C-Exe-Manifest.step2.cmake6
-rw-r--r--Tests/RunCMake/BuildDepends/C-Exe.cmake12
-rw-r--r--Tests/RunCMake/BuildDepends/C-Exe.step1.cmake3
-rw-r--r--Tests/RunCMake/BuildDepends/C-Exe.step2.cmake3
-rw-r--r--Tests/RunCMake/BuildDepends/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/BuildDepends/Custom-Always.cmake24
-rw-r--r--Tests/RunCMake/BuildDepends/RunCMakeTest.cmake42
-rw-r--r--Tests/RunCMake/BuildDepends/check.cmake37
-rw-r--r--Tests/RunCMake/BuildDepends/main.c1
-rw-r--r--Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt6
-rw-r--r--Tests/RunCMake/CMP0019/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared.cmake2
-rw-r--r--Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-NEW.cmake14
-rw-r--r--Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-link_libraries-stderr.txt1
-rw-r--r--Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-stderr.txt1
-rw-r--r--Tests/RunCMake/CMP0022/CMP0022-NOWARN-static.cmake6
-rw-r--r--Tests/RunCMake/CMP0022/CMP0022-WARN.cmake2
-rw-r--r--Tests/RunCMake/CMP0022/CMP0022-export-exe-stderr.txt1
-rw-r--r--Tests/RunCMake/CMP0022/CMP0022-export-stderr.txt2
-rw-r--r--Tests/RunCMake/CMP0022/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-NEW-result.txt (renamed from Tests/RunCMake/ExternalData/Directory3-result.txt)0
-rw-r--r--Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-NEW-stderr.txt7
-rw-r--r--Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-NEW.cmake7
-rw-r--r--Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-OLD-result.txt1
-rw-r--r--Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-OLD.cmake7
-rw-r--r--Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-WARN-result.txt1
-rw-r--r--Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-WARN-stderr.txt12
-rw-r--r--Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-WARN.cmake5
-rw-r--r--Tests/RunCMake/CMP0026/CMP0026-IMPORTED-result.txt1
-rw-r--r--Tests/RunCMake/CMP0026/CMP0026-IMPORTED.cmake6
-rw-r--r--Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-NEW-result.txt (renamed from Tests/RunCMake/ExternalData/MissingData-result.txt)0
-rw-r--r--Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-NEW-stderr.txt7
-rw-r--r--Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-NEW.cmake7
-rw-r--r--Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-OLD-result.txt1
-rw-r--r--Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-OLD.cmake7
-rw-r--r--Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-WARN-result.txt1
-rw-r--r--Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-WARN-stderr.txt12
-rw-r--r--Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-WARN.cmake5
-rw-r--r--Tests/RunCMake/CMP0026/CMP0026-NEW-result.txt (renamed from Tests/RunCMake/build_command/BeforeProject-result.txt)0
-rw-r--r--Tests/RunCMake/CMP0026/CMP0026-NEW-stderr.txt7
-rw-r--r--Tests/RunCMake/CMP0026/CMP0026-NEW.cmake7
-rw-r--r--Tests/RunCMake/CMP0026/CMP0026-WARN-Dir/CMakeLists.txt1
-rw-r--r--Tests/RunCMake/CMP0026/CMP0026-WARN-result.txt1
-rw-r--r--Tests/RunCMake/CMP0026/CMP0026-WARN-stderr.txt25
-rw-r--r--Tests/RunCMake/CMP0026/CMP0026-WARN.cmake8
-rw-r--r--Tests/RunCMake/CMP0026/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS-result.txt1
-rw-r--r--Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS-stderr.txt12
-rw-r--r--Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS.cmake6
-rw-r--r--Tests/RunCMake/CMP0026/ObjlibNotDefined-result.txt1
-rw-r--r--Tests/RunCMake/CMP0026/ObjlibNotDefined-stderr.txt12
-rw-r--r--Tests/RunCMake/CMP0026/ObjlibNotDefined.cmake13
-rw-r--r--Tests/RunCMake/CMP0026/RunCMakeTest.cmake14
-rw-r--r--Tests/RunCMake/CMP0026/clear-cached-information-dir/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/CMP0026/clear-cached-information.cmake14
-rw-r--r--Tests/RunCMake/CMP0026/empty.cpp7
-rw-r--r--Tests/RunCMake/CMP0027/CMP0027-NEW-result.txt (renamed from Tests/RunCMake/include_directories/BinaryDirectoryInInterface-result.txt)0
-rw-r--r--Tests/RunCMake/CMP0027/CMP0027-NEW-stderr.txt13
-rw-r--r--Tests/RunCMake/CMP0027/CMP0027-NEW.cmake10
-rw-r--r--Tests/RunCMake/CMP0027/CMP0027-OLD-result.txt1
-rw-r--r--Tests/RunCMake/CMP0027/CMP0027-OLD-stderr.txt13
-rw-r--r--Tests/RunCMake/CMP0027/CMP0027-OLD.cmake10
-rw-r--r--Tests/RunCMake/CMP0027/CMP0027-WARN-result.txt1
-rw-r--r--Tests/RunCMake/CMP0027/CMP0027-WARN-stderr.txt18
-rw-r--r--Tests/RunCMake/CMP0027/CMP0027-WARN.cmake8
-rw-r--r--Tests/RunCMake/CMP0027/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0027/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/CMP0027/empty.cpp0
-rw-r--r--Tests/RunCMake/CMP0028/CMP0028-NEW-iface-result.txt (renamed from Tests/RunCMake/include_directories/RelativePathInGenex-result.txt)0
-rw-r--r--Tests/RunCMake/CMP0028/CMP0028-NEW-iface-stderr.txt6
-rw-r--r--Tests/RunCMake/CMP0028/CMP0028-NEW-iface.cmake7
-rw-r--r--Tests/RunCMake/CMP0028/CMP0028-NEW-result.txt (renamed from Tests/RunCMake/include_directories/RelativePathInInterface-result.txt)0
-rw-r--r--Tests/RunCMake/CMP0028/CMP0028-NEW-stderr.txt6
-rw-r--r--Tests/RunCMake/CMP0028/CMP0028-NEW.cmake5
-rw-r--r--Tests/RunCMake/CMP0028/CMP0028-OLD-iface-result.txt1
-rw-r--r--Tests/RunCMake/CMP0028/CMP0028-OLD-iface.cmake7
-rw-r--r--Tests/RunCMake/CMP0028/CMP0028-OLD-result.txt1
-rw-r--r--Tests/RunCMake/CMP0028/CMP0028-OLD.cmake5
-rw-r--r--Tests/RunCMake/CMP0028/CMP0028-WARN-iface-result.txt1
-rw-r--r--Tests/RunCMake/CMP0028/CMP0028-WARN-iface-stderr.txt11
-rw-r--r--Tests/RunCMake/CMP0028/CMP0028-WARN-iface.cmake5
-rw-r--r--Tests/RunCMake/CMP0028/CMP0028-WARN-result.txt1
-rw-r--r--Tests/RunCMake/CMP0028/CMP0028-WARN-stderr.txt11
-rw-r--r--Tests/RunCMake/CMP0028/CMP0028-WARN.cmake3
-rw-r--r--Tests/RunCMake/CMP0028/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0028/RunCMakeTest.cmake8
-rw-r--r--Tests/RunCMake/CMP0028/empty.cpp0
-rw-r--r--Tests/RunCMake/CMP0037/CMP0037-NEW-colon-result.txt (renamed from Tests/RunCMake/include_directories/SourceDirectoryInInterface-result.txt)0
-rw-r--r--Tests/RunCMake/CMP0037/CMP0037-NEW-colon-stderr.txt20
-rw-r--r--Tests/RunCMake/CMP0037/CMP0037-NEW-colon.cmake6
-rw-r--r--Tests/RunCMake/CMP0037/CMP0037-NEW-reserved-result.txt1
-rw-r--r--Tests/RunCMake/CMP0037/CMP0037-NEW-reserved-stderr.txt18
-rw-r--r--Tests/RunCMake/CMP0037/CMP0037-NEW-reserved.cmake6
-rw-r--r--Tests/RunCMake/CMP0037/CMP0037-NEW-space-result.txt1
-rw-r--r--Tests/RunCMake/CMP0037/CMP0037-NEW-space-stderr.txt20
-rw-r--r--Tests/RunCMake/CMP0037/CMP0037-NEW-space.cmake6
-rw-r--r--Tests/RunCMake/CMP0037/CMP0037-OLD-reserved-result.txt1
-rw-r--r--Tests/RunCMake/CMP0037/CMP0037-OLD-reserved.cmake6
-rw-r--r--Tests/RunCMake/CMP0037/CMP0037-OLD-space-result.txt1
-rw-r--r--Tests/RunCMake/CMP0037/CMP0037-OLD-space.cmake6
-rw-r--r--Tests/RunCMake/CMP0037/CMP0037-WARN-colon-result.txt1
-rw-r--r--Tests/RunCMake/CMP0037/CMP0037-WARN-colon-stderr.txt38
-rw-r--r--Tests/RunCMake/CMP0037/CMP0037-WARN-colon.cmake4
-rw-r--r--Tests/RunCMake/CMP0037/CMP0037-WARN-space-result.txt1
-rw-r--r--Tests/RunCMake/CMP0037/CMP0037-WARN-space-stderr.txt37
-rw-r--r--Tests/RunCMake/CMP0037/CMP0037-WARN-space.cmake4
-rw-r--r--Tests/RunCMake/CMP0037/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0037/RunCMakeTest.cmake13
-rw-r--r--Tests/RunCMake/CMP0037/empty.cpp7
-rw-r--r--Tests/RunCMake/CMP0038/CMP0038-NEW-result.txt1
-rw-r--r--Tests/RunCMake/CMP0038/CMP0038-NEW-stderr.txt4
-rw-r--r--Tests/RunCMake/CMP0038/CMP0038-NEW.cmake4
-rw-r--r--Tests/RunCMake/CMP0038/CMP0038-OLD-result.txt1
-rw-r--r--Tests/RunCMake/CMP0038/CMP0038-OLD.cmake4
-rw-r--r--Tests/RunCMake/CMP0038/CMP0038-WARN-result.txt1
-rw-r--r--Tests/RunCMake/CMP0038/CMP0038-WARN-stderr.txt9
-rw-r--r--Tests/RunCMake/CMP0038/CMP0038-WARN.cmake3
-rw-r--r--Tests/RunCMake/CMP0038/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0038/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/CMP0038/empty.cpp7
-rw-r--r--Tests/RunCMake/CMP0039/CMP0039-NEW-result.txt1
-rw-r--r--Tests/RunCMake/CMP0039/CMP0039-NEW-stderr.txt5
-rw-r--r--Tests/RunCMake/CMP0039/CMP0039-NEW.cmake7
-rw-r--r--Tests/RunCMake/CMP0039/CMP0039-OLD-result.txt1
-rw-r--r--Tests/RunCMake/CMP0039/CMP0039-OLD.cmake7
-rw-r--r--Tests/RunCMake/CMP0039/CMP0039-WARN-result.txt1
-rw-r--r--Tests/RunCMake/CMP0039/CMP0039-WARN-stderr.txt10
-rw-r--r--Tests/RunCMake/CMP0039/CMP0039-WARN.cmake5
-rw-r--r--Tests/RunCMake/CMP0039/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0039/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/CMP0040/CMP0040-NEW-existing-target-result.txt1
-rw-r--r--Tests/RunCMake/CMP0040/CMP0040-NEW-existing-target.cmake7
-rw-r--r--Tests/RunCMake/CMP0040/CMP0040-NEW-missing-target-result.txt1
-rw-r--r--Tests/RunCMake/CMP0040/CMP0040-NEW-missing-target-stderr.txt4
-rw-r--r--Tests/RunCMake/CMP0040/CMP0040-NEW-missing-target.cmake5
-rw-r--r--Tests/RunCMake/CMP0040/CMP0040-OLD-existing-target-result.txt1
-rw-r--r--Tests/RunCMake/CMP0040/CMP0040-OLD-existing-target.cmake7
-rw-r--r--Tests/RunCMake/CMP0040/CMP0040-OLD-missing-target-result.txt1
-rw-r--r--Tests/RunCMake/CMP0040/CMP0040-OLD-missing-target.cmake5
-rw-r--r--Tests/RunCMake/CMP0040/CMP0040-WARN-missing-target-result.txt1
-rw-r--r--Tests/RunCMake/CMP0040/CMP0040-WARN-missing-target-stderr.txt10
-rw-r--r--Tests/RunCMake/CMP0040/CMP0040-WARN-missing-target.cmake4
-rw-r--r--Tests/RunCMake/CMP0040/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0040/RunCMakeTest.cmake8
-rw-r--r--Tests/RunCMake/CMP0040/empty.cpp7
-rw-r--r--Tests/RunCMake/CMP0041/CMP0041-NEW-result.txt1
-rw-r--r--Tests/RunCMake/CMP0041/CMP0041-NEW-stderr.txt20
-rw-r--r--Tests/RunCMake/CMP0041/CMP0041-NEW.cmake12
-rw-r--r--Tests/RunCMake/CMP0041/CMP0041-OLD-result.txt1
-rw-r--r--Tests/RunCMake/CMP0041/CMP0041-OLD.cmake12
-rw-r--r--Tests/RunCMake/CMP0041/CMP0041-WARN-result.txt1
-rw-r--r--Tests/RunCMake/CMP0041/CMP0041-WARN-stderr.txt32
-rw-r--r--Tests/RunCMake/CMP0041/CMP0041-WARN.cmake10
-rw-r--r--Tests/RunCMake/CMP0041/CMP0041-tid-NEW-result.txt1
-rw-r--r--Tests/RunCMake/CMP0041/CMP0041-tid-NEW-stderr.txt22
-rw-r--r--Tests/RunCMake/CMP0041/CMP0041-tid-NEW.cmake11
-rw-r--r--Tests/RunCMake/CMP0041/CMP0041-tid-OLD-result.txt1
-rw-r--r--Tests/RunCMake/CMP0041/CMP0041-tid-OLD.cmake11
-rw-r--r--Tests/RunCMake/CMP0041/CMP0041-tid-WARN-result.txt1
-rw-r--r--Tests/RunCMake/CMP0041/CMP0041-tid-WARN-stderr.txt34
-rw-r--r--Tests/RunCMake/CMP0041/CMP0041-tid-WARN.cmake9
-rw-r--r--Tests/RunCMake/CMP0041/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0041/RunCMakeTest.cmake11
-rw-r--r--Tests/RunCMake/CMP0041/empty.cpp7
-rw-r--r--Tests/RunCMake/CMP0042/CMP0042-NEW-result.txt1
-rw-r--r--Tests/RunCMake/CMP0042/CMP0042-NEW.cmake4
-rw-r--r--Tests/RunCMake/CMP0042/CMP0042-OLD-result.txt1
-rw-r--r--Tests/RunCMake/CMP0042/CMP0042-OLD.cmake4
-rw-r--r--Tests/RunCMake/CMP0042/CMP0042-WARN-result.txt1
-rw-r--r--Tests/RunCMake/CMP0042/CMP0042-WARN-stderr.txt10
-rw-r--r--Tests/RunCMake/CMP0042/CMP0042-WARN.cmake9
-rw-r--r--Tests/RunCMake/CMP0042/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0042/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/CMP0042/empty.cpp7
-rw-r--r--Tests/RunCMake/CMP0043/CMP0043-NEW-result.txt1
-rw-r--r--Tests/RunCMake/CMP0043/CMP0043-NEW.cmake7
-rw-r--r--Tests/RunCMake/CMP0043/CMP0043-OLD-result.txt1
-rw-r--r--Tests/RunCMake/CMP0043/CMP0043-OLD.cmake7
-rw-r--r--Tests/RunCMake/CMP0043/CMP0043-WARN-result.txt1
-rw-r--r--Tests/RunCMake/CMP0043/CMP0043-WARN-stderr.txt5
-rw-r--r--Tests/RunCMake/CMP0043/CMP0043-WARN.cmake5
-rw-r--r--Tests/RunCMake/CMP0043/CMakeLists.txt7
-rw-r--r--Tests/RunCMake/CMP0043/RunCMakeTest.cmake7
-rw-r--r--Tests/RunCMake/CMP0043/empty.cpp7
-rw-r--r--Tests/RunCMake/CMP0045/CMP0045-NEW-result.txt1
-rw-r--r--Tests/RunCMake/CMP0045/CMP0045-NEW-stderr.txt4
-rw-r--r--Tests/RunCMake/CMP0045/CMP0045-NEW.cmake4
-rw-r--r--Tests/RunCMake/CMP0045/CMP0045-OLD-result.txt1
-rw-r--r--Tests/RunCMake/CMP0045/CMP0045-OLD.cmake4
-rw-r--r--Tests/RunCMake/CMP0045/CMP0045-WARN-result.txt1
-rw-r--r--Tests/RunCMake/CMP0045/CMP0045-WARN-stderr.txt9
-rw-r--r--Tests/RunCMake/CMP0045/CMP0045-WARN.cmake2
-rw-r--r--Tests/RunCMake/CMP0045/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0045/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/CMP0045/empty.cpp7
-rw-r--r--Tests/RunCMake/CMP0046/CMP0046-Duplicate-result.txt1
-rw-r--r--Tests/RunCMake/CMP0046/CMP0046-Duplicate-stderr.txt10
-rw-r--r--Tests/RunCMake/CMP0046/CMP0046-Duplicate.cmake9
-rw-r--r--Tests/RunCMake/CMP0046/CMP0046-NEW-existing-dependency.cmake5
-rw-r--r--Tests/RunCMake/CMP0046/CMP0046-NEW-missing-dependency-result.txt1
-rw-r--r--Tests/RunCMake/CMP0046/CMP0046-NEW-missing-dependency-stderr.txt4
-rw-r--r--Tests/RunCMake/CMP0046/CMP0046-NEW-missing-dependency.cmake4
-rw-r--r--Tests/RunCMake/CMP0046/CMP0046-OLD-existing-dependency.cmake5
-rw-r--r--Tests/RunCMake/CMP0046/CMP0046-OLD-missing-dependency.cmake4
-rw-r--r--Tests/RunCMake/CMP0046/CMP0046-WARN-missing-dependency-stderr.txt9
-rw-r--r--Tests/RunCMake/CMP0046/CMP0046-WARN-missing-dependency.cmake2
-rw-r--r--Tests/RunCMake/CMP0046/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0046/RunCMakeTest.cmake9
-rw-r--r--Tests/RunCMake/CMP0046/empty.cpp7
-rw-r--r--Tests/RunCMake/CMP0049/CMP0049-NEW-result.txt1
-rw-r--r--Tests/RunCMake/CMP0049/CMP0049-NEW-stderr.txt6
-rw-r--r--Tests/RunCMake/CMP0049/CMP0049-NEW.cmake5
-rw-r--r--Tests/RunCMake/CMP0049/CMP0049-OLD-result.txt1
-rw-r--r--Tests/RunCMake/CMP0049/CMP0049-OLD.cmake5
-rw-r--r--Tests/RunCMake/CMP0049/CMP0049-WARN-result.txt1
-rw-r--r--Tests/RunCMake/CMP0049/CMP0049-WARN-stderr.txt11
-rw-r--r--Tests/RunCMake/CMP0049/CMP0049-WARN.cmake3
-rw-r--r--Tests/RunCMake/CMP0049/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0049/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/CMP0049/empty.cpp7
-rw-r--r--Tests/RunCMake/CMP0050/CMP0050-NEW-result.txt1
-rw-r--r--Tests/RunCMake/CMP0050/CMP0050-NEW-stderr.txt4
-rw-r--r--Tests/RunCMake/CMP0050/CMP0050-NEW.cmake13
-rw-r--r--Tests/RunCMake/CMP0050/CMP0050-OLD-result.txt1
-rw-r--r--Tests/RunCMake/CMP0050/CMP0050-OLD.cmake13
-rw-r--r--Tests/RunCMake/CMP0050/CMP0050-WARN-result.txt1
-rw-r--r--Tests/RunCMake/CMP0050/CMP0050-WARN-stderr.txt9
-rw-r--r--Tests/RunCMake/CMP0050/CMP0050-WARN.cmake11
-rw-r--r--Tests/RunCMake/CMP0050/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0050/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/CMP0050/empty.cpp10
-rw-r--r--Tests/RunCMake/CMP0050/input.h.in2
-rw-r--r--Tests/RunCMake/CMP0051/CMP0051-NEW-result.txt1
-rw-r--r--Tests/RunCMake/CMP0051/CMP0051-NEW-stderr.txt1
-rw-r--r--Tests/RunCMake/CMP0051/CMP0051-NEW.cmake10
-rw-r--r--Tests/RunCMake/CMP0051/CMP0051-OLD-result.txt1
-rw-r--r--Tests/RunCMake/CMP0051/CMP0051-OLD-stderr.txt1
-rw-r--r--Tests/RunCMake/CMP0051/CMP0051-OLD.cmake10
-rw-r--r--Tests/RunCMake/CMP0051/CMP0051-WARN-Dir/CMakeLists.txt1
-rw-r--r--Tests/RunCMake/CMP0051/CMP0051-WARN-result.txt1
-rw-r--r--Tests/RunCMake/CMP0051/CMP0051-WARN-stderr.txt31
-rw-r--r--Tests/RunCMake/CMP0051/CMP0051-WARN.cmake14
-rw-r--r--Tests/RunCMake/CMP0051/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0051/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/CMP0051/empty.cpp7
-rw-r--r--Tests/RunCMake/CMP0053/CMP0053-NEW-stderr.txt2
-rw-r--r--Tests/RunCMake/CMP0053/CMP0053-NEW.cmake8
-rw-r--r--Tests/RunCMake/CMP0053/CMP0053-OLD-stderr.txt2
-rw-r--r--Tests/RunCMake/CMP0053/CMP0053-OLD.cmake8
-rw-r--r--Tests/RunCMake/CMP0053/CMP0053-WARN-stderr.txt2
-rw-r--r--Tests/RunCMake/CMP0053/CMP0053-WARN.cmake6
-rw-r--r--Tests/RunCMake/CMP0053/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0053/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/CMP0054/CMP0054-NEW-stderr.txt1
-rw-r--r--Tests/RunCMake/CMP0054/CMP0054-NEW.cmake47
-rw-r--r--Tests/RunCMake/CMP0054/CMP0054-OLD-stderr.txt1
-rw-r--r--Tests/RunCMake/CMP0054/CMP0054-OLD.cmake47
-rw-r--r--Tests/RunCMake/CMP0054/CMP0054-WARN-stderr.txt23
-rw-r--r--Tests/RunCMake/CMP0054/CMP0054-WARN.cmake7
-rw-r--r--Tests/RunCMake/CMP0054/CMP0054-duplicate-warnings-stderr.txt24
-rw-r--r--Tests/RunCMake/CMP0054/CMP0054-duplicate-warnings.cmake12
-rw-r--r--Tests/RunCMake/CMP0054/CMP0054-keywords-NEW-result.txt1
-rw-r--r--Tests/RunCMake/CMP0054/CMP0054-keywords-NEW-stderr.txt8
-rw-r--r--Tests/RunCMake/CMP0054/CMP0054-keywords-NEW.cmake25
-rw-r--r--Tests/RunCMake/CMP0054/CMP0054-keywords-OLD-stderr.txt1
-rw-r--r--Tests/RunCMake/CMP0054/CMP0054-keywords-OLD.cmake9
-rw-r--r--Tests/RunCMake/CMP0054/CMP0054-keywords-WARN-stderr.txt25
-rw-r--r--Tests/RunCMake/CMP0054/CMP0054-keywords-WARN.cmake5
-rw-r--r--Tests/RunCMake/CMP0054/CMP0054-policy-command-scope-stderr.txt1
-rw-r--r--Tests/RunCMake/CMP0054/CMP0054-policy-command-scope.cmake53
-rw-r--r--Tests/RunCMake/CMP0054/CMP0054-policy-foreach-scope-stderr.txt1
-rw-r--r--Tests/RunCMake/CMP0054/CMP0054-policy-foreach-scope.cmake49
-rw-r--r--Tests/RunCMake/CMP0054/CMP0054-policy-nested-if-stderr.txt1
-rw-r--r--Tests/RunCMake/CMP0054/CMP0054-policy-nested-if.cmake41
-rw-r--r--Tests/RunCMake/CMP0054/CMP0054-policy-while-scope-stderr.txt1
-rw-r--r--Tests/RunCMake/CMP0054/CMP0054-policy-while-scope.cmake65
-rw-r--r--Tests/RunCMake/CMP0054/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0054/RunCMakeTest.cmake13
-rw-r--r--Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope-result.txt1
-rw-r--r--Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope-stderr.txt4
-rw-r--r--Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope.cmake4
-rw-r--r--Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments-result.txt1
-rw-r--r--Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments-stderr.txt4
-rw-r--r--Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments.cmake6
-rw-r--r--Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope-result.txt1
-rw-r--r--Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope.cmake4
-rw-r--r--Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments-result.txt1
-rw-r--r--Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments.cmake6
-rw-r--r--Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope-result.txt1
-rw-r--r--Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope-stderr.txt9
-rw-r--r--Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope.cmake2
-rw-r--r--Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments-result.txt1
-rw-r--r--Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments-stderr.txt9
-rw-r--r--Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments.cmake4
-rw-r--r--Tests/RunCMake/CMP0055/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0055/RunCMakeTest.cmake9
-rw-r--r--Tests/RunCMake/CMP0057/CMP0057-NEW.cmake31
-rw-r--r--Tests/RunCMake/CMP0057/CMP0057-OLD-result.txt1
-rw-r--r--Tests/RunCMake/CMP0057/CMP0057-OLD-stderr.txt8
-rw-r--r--Tests/RunCMake/CMP0057/CMP0057-OLD.cmake7
-rw-r--r--Tests/RunCMake/CMP0057/CMP0057-WARN-result.txt1
-rw-r--r--Tests/RunCMake/CMP0057/CMP0057-WARN-stderr.txt19
-rw-r--r--Tests/RunCMake/CMP0057/CMP0057-WARN.cmake5
-rw-r--r--Tests/RunCMake/CMP0057/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0057/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/CMP0059/CMP0059-NEW-result.txt1
-rw-r--r--Tests/RunCMake/CMP0059/CMP0059-NEW-stderr.txt2
-rw-r--r--Tests/RunCMake/CMP0059/CMP0059-NEW.cmake17
-rw-r--r--Tests/RunCMake/CMP0059/CMP0059-OLD-result.txt1
-rw-r--r--Tests/RunCMake/CMP0059/CMP0059-OLD-stderr.txt2
-rw-r--r--Tests/RunCMake/CMP0059/CMP0059-OLD.cmake17
-rw-r--r--Tests/RunCMake/CMP0059/CMP0059-WARN-result.txt1
-rw-r--r--Tests/RunCMake/CMP0059/CMP0059-WARN-stderr.txt18
-rw-r--r--Tests/RunCMake/CMP0059/CMP0059-WARN.cmake17
-rw-r--r--Tests/RunCMake/CMP0059/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0059/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/CMP0060/CMP0060-Common.cmake35
-rw-r--r--Tests/RunCMake/CMP0060/CMP0060-NEW.cmake2
-rw-r--r--Tests/RunCMake/CMP0060/CMP0060-OLD-Build-result.txt1
-rw-r--r--Tests/RunCMake/CMP0060/CMP0060-OLD-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/CMP0060/CMP0060-OLD.cmake2
-rw-r--r--Tests/RunCMake/CMP0060/CMP0060-WARN-OFF-Build-result.txt1
-rw-r--r--Tests/RunCMake/CMP0060/CMP0060-WARN-OFF-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/CMP0060/CMP0060-WARN-OFF.cmake1
-rw-r--r--Tests/RunCMake/CMP0060/CMP0060-WARN-ON-Build-result.txt1
-rw-r--r--Tests/RunCMake/CMP0060/CMP0060-WARN-ON-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/CMP0060/CMP0060-WARN-ON-stderr.txt16
-rw-r--r--Tests/RunCMake/CMP0060/CMP0060-WARN-ON.cmake2
-rw-r--r--Tests/RunCMake/CMP0060/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0060/RunCMakeTest.cmake19
-rw-r--r--Tests/RunCMake/CMP0060/cmp0060.c4
-rw-r--r--Tests/RunCMake/CMP0060/main.c5
-rw-r--r--Tests/RunCMake/CMP0064/CMP0064-NEW.cmake5
-rw-r--r--Tests/RunCMake/CMP0064/CMP0064-OLD.cmake7
-rw-r--r--Tests/RunCMake/CMP0064/CMP0064-WARN-stderr.txt10
-rw-r--r--Tests/RunCMake/CMP0064/CMP0064-WARN.cmake7
-rw-r--r--Tests/RunCMake/CMP0064/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0064/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/CMP0065/BuildTargetInSubProject.cmake15
-rw-r--r--Tests/RunCMake/CMP0065/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0065/NEWBad.cmake4
-rw-r--r--Tests/RunCMake/CMP0065/NEWGood.cmake4
-rw-r--r--Tests/RunCMake/CMP0065/OLDBad1.cmake4
-rw-r--r--Tests/RunCMake/CMP0065/OLDBad2.cmake4
-rw-r--r--Tests/RunCMake/CMP0065/RunCMakeTest.cmake8
-rw-r--r--Tests/RunCMake/CMP0065/WARN-OFF.cmake3
-rw-r--r--Tests/RunCMake/CMP0065/WARN-ON-stderr.txt10
-rw-r--r--Tests/RunCMake/CMP0065/WARN-ON.cmake3
-rw-r--r--Tests/RunCMake/CMP0065/subproject/CMakeLists.txt22
-rw-r--r--Tests/RunCMake/CMP0065/subproject/main.c7
-rw-r--r--Tests/RunCMake/CMakeLists.txt304
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-result.txt1
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-VS.txt8
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-Xcode.txt9
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions.cmake5
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions-result.txt1
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions-stderr-VS.txt8
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions.cmake5
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-result.txt1
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-VS.txt8
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-Xcode.txt9
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories.cmake5
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake20
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/main.cpp5
-rw-r--r--Tests/RunCMake/CPack/CMakeLists.txt12
-rw-r--r--Tests/RunCMake/CPack/COMPONENTS_EMPTY_DIR.cmake5
-rw-r--r--Tests/RunCMake/CPack/CPackTestHelpers.cmake41
-rw-r--r--Tests/RunCMake/CPack/DEB/COMPONENTS_EMPTY_DIR-ExpectedFiles.cmake5
-rw-r--r--Tests/RunCMake/CPack/DEB/COMPONENTS_EMPTY_DIR-specifics.cmake2
-rw-r--r--Tests/RunCMake/CPack/DEB/DEB_EXTRA-ExpectedFiles.cmake9
-rw-r--r--Tests/RunCMake/CPack/DEB/DEB_EXTRA-VerifyResult.cmake17
-rw-r--r--Tests/RunCMake/CPack/DEB/DEPENDENCIES-ExpectedFiles.cmake14
-rw-r--r--Tests/RunCMake/CPack/DEB/DEPENDENCIES-VerifyResult.cmake34
-rw-r--r--Tests/RunCMake/CPack/DEB/DEPENDENCIES-specifics.cmake21
-rw-r--r--Tests/RunCMake/CPack/DEB/EMPTY_DIR-ExpectedFiles.cmake5
-rw-r--r--Tests/RunCMake/CPack/DEB/EMPTY_DIR-specifics.cmake1
-rw-r--r--Tests/RunCMake/CPack/DEB/Helpers.cmake51
-rw-r--r--Tests/RunCMake/CPack/DEB/MINIMAL-ExpectedFiles.cmake5
-rw-r--r--Tests/RunCMake/CPack/DEB/MINIMAL-specifics.cmake1
-rw-r--r--Tests/RunCMake/CPack/DEB/PER_COMPONENT_FIELDS-ExpectedFiles.cmake9
-rw-r--r--Tests/RunCMake/CPack/DEB/PER_COMPONENT_FIELDS-VerifyResult.cmake18
-rw-r--r--Tests/RunCMake/CPack/DEB/PER_COMPONENT_FIELDS-specifics.cmake6
-rw-r--r--Tests/RunCMake/CPack/DEB/Prerequirements.cmake8
-rw-r--r--Tests/RunCMake/CPack/DEB_EXTRA.cmake38
-rw-r--r--Tests/RunCMake/CPack/DEPENDENCIES.cmake20
-rw-r--r--Tests/RunCMake/CPack/EMPTY_DIR.cmake4
-rw-r--r--Tests/RunCMake/CPack/MINIMAL.cmake3
-rw-r--r--Tests/RunCMake/CPack/PARTIALLY_RELOCATABLE_WARNING.cmake6
-rw-r--r--Tests/RunCMake/CPack/PER_COMPONENT_FIELDS.cmake5
-rw-r--r--Tests/RunCMake/CPack/README.txt99
-rw-r--r--Tests/RunCMake/CPack/RPM/COMPONENTS_EMPTY_DIR-ExpectedFiles.cmake5
-rw-r--r--Tests/RunCMake/CPack/RPM/COMPONENTS_EMPTY_DIR-stderr.txt1
-rw-r--r--Tests/RunCMake/CPack/RPM/DEPENDENCIES-ExpectedFiles.cmake13
-rw-r--r--Tests/RunCMake/CPack/RPM/DEPENDENCIES-VerifyResult.cmake45
-rw-r--r--Tests/RunCMake/CPack/RPM/DEPENDENCIES-specifics.cmake22
-rw-r--r--Tests/RunCMake/CPack/RPM/EMPTY_DIR-ExpectedFiles.cmake5
-rw-r--r--Tests/RunCMake/CPack/RPM/EMPTY_DIR-stderr.txt1
-rw-r--r--Tests/RunCMake/CPack/RPM/Helpers.cmake19
-rw-r--r--Tests/RunCMake/CPack/RPM/MINIMAL-ExpectedFiles.cmake5
-rw-r--r--Tests/RunCMake/CPack/RPM/MINIMAL-stderr.txt1
-rw-r--r--Tests/RunCMake/CPack/RPM/PARTIALLY_RELOCATABLE_WARNING-ExpectedFiles.cmake5
-rw-r--r--Tests/RunCMake/CPack/RPM/PARTIALLY_RELOCATABLE_WARNING-stderr.txt1
-rw-r--r--Tests/RunCMake/CPack/RPM/PER_COMPONENT_FIELDS-ExpectedFiles.cmake9
-rw-r--r--Tests/RunCMake/CPack/RPM/PER_COMPONENT_FIELDS-VerifyResult.cmake18
-rw-r--r--Tests/RunCMake/CPack/RPM/PER_COMPONENT_FIELDS-specifics.cmake5
-rw-r--r--Tests/RunCMake/CPack/RPM/Prerequirements.cmake16
-rw-r--r--Tests/RunCMake/CPack/RunCMakeTest.cmake13
-rw-r--r--Tests/RunCMake/CPack/TGZ/COMPONENTS_EMPTY_DIR-ExpectedFiles.cmake3
-rw-r--r--Tests/RunCMake/CPack/TGZ/COMPONENTS_EMPTY_DIR-specifics.cmake1
-rw-r--r--Tests/RunCMake/CPack/TGZ/EMPTY_DIR-ExpectedFiles.cmake3
-rw-r--r--Tests/RunCMake/CPack/TGZ/Helpers.cmake10
-rw-r--r--Tests/RunCMake/CPack/TGZ/MINIMAL-ExpectedFiles.cmake5
-rw-r--r--Tests/RunCMake/CPack/TGZ/Prerequirements.cmake4
-rw-r--r--Tests/RunCMake/CPack/VerifyResult.cmake92
-rw-r--r--Tests/RunCMake/CPackConfig/CMakeLists.txt6
-rw-r--r--Tests/RunCMake/CPackConfig/Default-check.cmake7
-rw-r--r--Tests/RunCMake/CPackConfig/Default.cmake3
-rw-r--r--Tests/RunCMake/CPackConfig/RunCMakeTest.cmake6
-rw-r--r--Tests/RunCMake/CPackConfig/Simple-check.cmake3
-rw-r--r--Tests/RunCMake/CPackConfig/Simple.cmake1
-rw-r--r--Tests/RunCMake/CPackConfig/Special-check.cmake5
-rw-r--r--Tests/RunCMake/CPackConfig/Special.cmake3
-rw-r--r--Tests/RunCMake/CPackConfig/Verbatim-check.cmake10
-rw-r--r--Tests/RunCMake/CPackConfig/Verbatim.cmake5
-rw-r--r--Tests/RunCMake/CPackConfig/check.cmake10
-rw-r--r--Tests/RunCMake/CPackInstallProperties/Append-check.cmake3
-rw-r--r--Tests/RunCMake/CPackInstallProperties/Append.cmake2
-rw-r--r--Tests/RunCMake/CPackInstallProperties/CMakeLists.txt6
-rw-r--r--Tests/RunCMake/CPackInstallProperties/FilenameGenex-check.cmake3
-rw-r--r--Tests/RunCMake/CPackInstallProperties/FilenameGenex.cmake7
-rw-r--r--Tests/RunCMake/CPackInstallProperties/MultipleValues-check.cmake3
-rw-r--r--Tests/RunCMake/CPackInstallProperties/MultipleValues.cmake1
-rw-r--r--Tests/RunCMake/CPackInstallProperties/PerConfigValue-check.cmake13
-rw-r--r--Tests/RunCMake/CPackInstallProperties/PerConfigValue.cmake14
-rw-r--r--Tests/RunCMake/CPackInstallProperties/Replace-check.cmake3
-rw-r--r--Tests/RunCMake/CPackInstallProperties/Replace.cmake2
-rw-r--r--Tests/RunCMake/CPackInstallProperties/RunCMakeTest.cmake9
-rw-r--r--Tests/RunCMake/CPackInstallProperties/Simple-check.cmake3
-rw-r--r--Tests/RunCMake/CPackInstallProperties/Simple.cmake1
-rw-r--r--Tests/RunCMake/CPackInstallProperties/ValueGenex-check.cmake3
-rw-r--r--Tests/RunCMake/CPackInstallProperties/ValueGenex.cmake7
-rw-r--r--Tests/RunCMake/CPackInstallProperties/check.cmake12
-rw-r--r--Tests/RunCMake/CPackInstallProperties/test.cpp1
-rw-r--r--Tests/RunCMake/CPackSymlinks/RunCMakeTest.cmake20
-rw-r--r--Tests/RunCMake/CPackSymlinks/SrcSymlinksTar-stdout.txt10
-rw-r--r--Tests/RunCMake/CPackSymlinks/testcpacksym.tarbin0 -> 10240 bytes
-rw-r--r--Tests/RunCMake/CTest/BeforeProject-stderr.txt10
-rw-r--r--Tests/RunCMake/CTestCommandLine/BadCTestTestfile-stderr.txt4
-rw-r--r--Tests/RunCMake/CTestCommandLine/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CTestCommandLine/LabelCount-stdout.txt7
-rw-r--r--Tests/RunCMake/CTestCommandLine/MergeOutput-stdout.txt13
-rw-r--r--Tests/RunCMake/CTestCommandLine/MergeOutput.cmake4
-rw-r--r--Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake142
-rw-r--r--Tests/RunCMake/CTestCommandLine/SerialFailed-result.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/SerialFailed-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/SerialFailed-stdout.txt10
-rw-r--r--Tests/RunCMake/CTestCommandLine/TestOutputSize-check.cmake17
-rw-r--r--Tests/RunCMake/CTestCommandLine/TestOutputSize-result.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/TestOutputSize-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/init.cmake3
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-until-fail-bad1-result.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-until-fail-bad1-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-until-fail-bad2-result.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-until-fail-bad2-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-until-fail-cmake.cmake15
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-until-fail-ctest-result.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-until-fail-ctest-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-until-fail-ctest-stdout.txt30
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-until-fail-good-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/test-load-fail-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/test-load-fail-stdout.txt2
-rw-r--r--Tests/RunCMake/CTestCommandLine/test-load-invalid-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/test-load-invalid-stdout.txt7
-rw-r--r--Tests/RunCMake/CTestCommandLine/test-load-pass-stderr.txt (renamed from Tests/RunCMake/CMP0022/CMP0022-NOWARN-exe-stderr.txt)0
-rw-r--r--Tests/RunCMake/CTestCommandLine/test-load-pass-stdout.txt7
-rw-r--r--Tests/RunCMake/CTestCommandLine/test1.cmake13
-rw-r--r--Tests/RunCMake/CheckModules/CMakeLists.txt4
-rw-r--r--Tests/RunCMake/CheckModules/CheckStructHasMemberMissingKey-result.txt1
-rw-r--r--Tests/RunCMake/CheckModules/CheckStructHasMemberMissingKey-stderr.txt8
-rw-r--r--Tests/RunCMake/CheckModules/CheckStructHasMemberMissingKey.cmake2
-rw-r--r--Tests/RunCMake/CheckModules/CheckStructHasMemberMissingLanguage-result.txt1
-rw-r--r--Tests/RunCMake/CheckModules/CheckStructHasMemberMissingLanguage-stderr.txt8
-rw-r--r--Tests/RunCMake/CheckModules/CheckStructHasMemberMissingLanguage.cmake2
-rw-r--r--Tests/RunCMake/CheckModules/CheckStructHasMemberOk.cmake6
-rw-r--r--Tests/RunCMake/CheckModules/CheckStructHasMemberTooManyArguments-result.txt1
-rw-r--r--Tests/RunCMake/CheckModules/CheckStructHasMemberTooManyArguments-stderr.txt8
-rw-r--r--Tests/RunCMake/CheckModules/CheckStructHasMemberTooManyArguments.cmake2
-rw-r--r--Tests/RunCMake/CheckModules/CheckStructHasMemberUnknownLanguage-result.txt1
-rw-r--r--Tests/RunCMake/CheckModules/CheckStructHasMemberUnknownLanguage-stderr.txt10
-rw-r--r--Tests/RunCMake/CheckModules/CheckStructHasMemberUnknownLanguage.cmake2
-rw-r--r--Tests/RunCMake/CheckModules/CheckStructHasMemberWrongKey-result.txt1
-rw-r--r--Tests/RunCMake/CheckModules/CheckStructHasMemberWrongKey-stderr.txt8
-rw-r--r--Tests/RunCMake/CheckModules/CheckStructHasMemberWrongKey.cmake2
-rw-r--r--Tests/RunCMake/CheckModules/CheckTypeSizeMissingLanguage-result.txt1
-rw-r--r--Tests/RunCMake/CheckModules/CheckTypeSizeMissingLanguage-stderr.txt8
-rw-r--r--Tests/RunCMake/CheckModules/CheckTypeSizeMissingLanguage.cmake2
-rw-r--r--Tests/RunCMake/CheckModules/CheckTypeSizeMixedArgs-result.txt1
-rw-r--r--Tests/RunCMake/CheckModules/CheckTypeSizeMixedArgs-stderr.txt10
-rw-r--r--Tests/RunCMake/CheckModules/CheckTypeSizeMixedArgs.cmake2
-rw-r--r--Tests/RunCMake/CheckModules/CheckTypeSizeOk.cmake12
-rw-r--r--Tests/RunCMake/CheckModules/CheckTypeSizeOkNoC.cmake4
-rw-r--r--Tests/RunCMake/CheckModules/CheckTypeSizeUnknownArgument-result.txt1
-rw-r--r--Tests/RunCMake/CheckModules/CheckTypeSizeUnknownArgument-stderr.txt8
-rw-r--r--Tests/RunCMake/CheckModules/CheckTypeSizeUnknownArgument.cmake2
-rw-r--r--Tests/RunCMake/CheckModules/CheckTypeSizeUnknownLanguage-result.txt1
-rw-r--r--Tests/RunCMake/CheckModules/CheckTypeSizeUnknownLanguage-stderr.txt10
-rw-r--r--Tests/RunCMake/CheckModules/CheckTypeSizeUnknownLanguage.cmake2
-rw-r--r--Tests/RunCMake/CheckModules/RunCMakeTest.cmake16
-rw-r--r--Tests/RunCMake/CommandLine/Build-ninja-v-stdout.txt1
-rw-r--r--Tests/RunCMake/CommandLine/Build.cmake5
-rw-r--r--Tests/RunCMake/CommandLine/BuildDir.cmake1
-rw-r--r--Tests/RunCMake/CommandLine/BuildDir/CMakeLists.txt5
-rw-r--r--Tests/RunCMake/CommandLine/C-no-arg-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/C-no-arg-stderr.txt2
-rw-r--r--Tests/RunCMake/CommandLine/C-no-file-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/C-no-file-stderr.txt3
-rw-r--r--Tests/RunCMake/CommandLine/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CommandLine/D-no-arg-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/D-no-arg-stderr.txt2
-rw-r--r--Tests/RunCMake/CommandLine/D_nested_cache-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/D_nested_cache.cmake1
-rw-r--r--Tests/RunCMake/CommandLine/D_typed_nested_cache-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/D_typed_nested_cache.cmake1
-rw-r--r--Tests/RunCMake/CommandLine/DeprecateVS6-WARN-OFF.cmake0
-rw-r--r--Tests/RunCMake/CommandLine/DeprecateVS6-WARN-ON-stderr.txt5
-rw-r--r--Tests/RunCMake/CommandLine/DeprecateVS6-WARN-ON.cmake0
-rw-r--r--Tests/RunCMake/CommandLine/DeprecateVS70-WARN-OFF.cmake0
-rw-r--r--Tests/RunCMake/CommandLine/DeprecateVS70-WARN-ON-stderr.txt5
-rw-r--r--Tests/RunCMake/CommandLine/DeprecateVS70-WARN-ON.cmake0
-rw-r--r--Tests/RunCMake/CommandLine/E-no-arg-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E-no-arg-stderr.txt3
-rw-r--r--Tests/RunCMake/CommandLine/E___run_iwyu-bad-iwyu-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E___run_iwyu-bad-iwyu-stderr.txt2
-rw-r--r--Tests/RunCMake/CommandLine/E___run_iwyu-no----result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E___run_iwyu-no----stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E___run_iwyu-no-cc-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E___run_iwyu-no-cc-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E___run_iwyu-no-iwyu-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E___run_iwyu-no-iwyu-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_copy-one-source-directory-target-is-directory-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_copy-one-source-directory-target-is-directory-stderr.txt0
-rw-r--r--Tests/RunCMake/CommandLine/E_copy-one-source-file-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_copy-one-source-file-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-directory-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-directory-stderr.txt0
-rw-r--r--Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-file-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-file-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_copy-two-good-and-one-bad-source-files-target-is-directory-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_copy-two-good-and-one-bad-source-files-target-is-directory-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-directory-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-directory-stderr.txt0
-rw-r--r--Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-file-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-file-stderr.txt3
-rw-r--r--Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-not-exist-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-not-exist-stderr.txt0
-rw-r--r--Tests/RunCMake/CommandLine/E_copy_if_different-one-source-directory-target-is-directory-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_copy_if_different-one-source-directory-target-is-directory-stderr.txt0
-rw-r--r--Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-directory-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-directory-stderr.txt0
-rw-r--r--Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-file-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-file-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_create_symlink-broken-create-check.cmake6
-rw-r--r--Tests/RunCMake/CommandLine/E_create_symlink-broken-replace-check.cmake3
-rw-r--r--Tests/RunCMake/CommandLine/E_create_symlink-missing-dir-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_create_symlink-missing-dir-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_create_symlink-no-arg-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_create_symlink-no-arg-stderr.txt3
-rw-r--r--Tests/RunCMake/CommandLine/E_create_symlink-no-replace-dir-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_create_symlink-no-replace-dir-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_env-bad-arg1-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_env-bad-arg1-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_env-no-command0-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_env-no-command0-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_env-no-command1-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_env-no-command1-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_env-set-stdout.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_env-set.cmake5
-rw-r--r--Tests/RunCMake/CommandLine/E_env-unset-stdout.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_env-unset.cmake5
-rw-r--r--Tests/RunCMake/CommandLine/E_make_directory-directory-with-parent-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_make_directory-directory-with-parent-stderr.txt0
-rw-r--r--Tests/RunCMake/CommandLine/E_make_directory-three-directories-and-file-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_make_directory-three-directories-and-file-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_make_directory-three-directories-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_make_directory-three-directories-stderr.txt0
-rw-r--r--Tests/RunCMake/CommandLine/E_rename-no-arg-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_rename-no-arg-stderr.txt3
-rw-r--r--Tests/RunCMake/CommandLine/E_sleep-bad-arg1-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_sleep-bad-arg1-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_sleep-bad-arg2-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_sleep-bad-arg2-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_sleep-no-args-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_sleep-no-args-stderr.cmake2
-rw-r--r--Tests/RunCMake/CommandLine/E_time-no-arg-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_time-no-arg-stderr.txt3
-rw-r--r--Tests/RunCMake/CommandLine/E_time-stdout.txt3
-rw-r--r--Tests/RunCMake/CommandLine/E_touch_nocreate-no-arg-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_touch_nocreate-no-arg-stderr.txt3
-rw-r--r--Tests/RunCMake/CommandLine/G_bad-arg-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/G_bad-arg-stderr.txt3
-rw-r--r--Tests/RunCMake/CommandLine/G_no-arg-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/G_no-arg-stderr.txt3
-rw-r--r--Tests/RunCMake/CommandLine/NoArgs-stdout.txt10
-rw-r--r--Tests/RunCMake/CommandLine/P_directory-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/P_directory-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/P_no-arg-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/P_no-arg-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/P_no-file-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/P_no-file-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/P_working-dir.cmake14
-rw-r--r--Tests/RunCMake/CommandLine/RunCMakeTest.cmake298
-rw-r--r--Tests/RunCMake/CommandLine/U-no-arg-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/U-no-arg-stderr.txt2
-rw-r--r--Tests/RunCMake/CommandLine/W_bad-arg1-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/W_bad-arg1-stderr.txt2
-rw-r--r--Tests/RunCMake/CommandLine/W_bad-arg2-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/W_bad-arg2-stderr.txt2
-rw-r--r--Tests/RunCMake/CommandLine/W_bad-arg3-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/W_bad-arg3-stderr.txt2
-rw-r--r--Tests/RunCMake/CommandLine/Wdeprecated-stderr.txt4
-rw-r--r--Tests/RunCMake/CommandLine/Wdeprecated.cmake1
-rw-r--r--Tests/RunCMake/CommandLine/Wdev-stderr.txt11
-rw-r--r--Tests/RunCMake/CommandLine/Wdev.cmake6
-rw-r--r--Tests/RunCMake/CommandLine/Werror_deprecated-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/Werror_deprecated-stderr.txt4
-rw-r--r--Tests/RunCMake/CommandLine/Werror_deprecated.cmake1
-rw-r--r--Tests/RunCMake/CommandLine/Werror_dev-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/Werror_dev-stderr.txt11
-rw-r--r--Tests/RunCMake/CommandLine/Werror_dev.cmake7
-rw-r--r--Tests/RunCMake/CommandLine/Wno-deprecated.cmake1
-rw-r--r--Tests/RunCMake/CommandLine/Wno-dev.cmake6
-rw-r--r--Tests/RunCMake/CommandLine/Wno-error_deprecated-stderr.txt4
-rw-r--r--Tests/RunCMake/CommandLine/Wno-error_deprecated.cmake2
-rw-r--r--Tests/RunCMake/CommandLine/Wno-error_dev-stderr.txt11
-rw-r--r--Tests/RunCMake/CommandLine/Wno-error_dev.cmake7
-rw-r--r--Tests/RunCMake/CommandLine/build-bad-dir-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/build-bad-dir-stderr.txt2
-rw-r--r--Tests/RunCMake/CommandLine/build-bad-generator-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/build-bad-generator-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/build-no-cache-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/build-no-cache-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/build-no-dir-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/build-no-dir-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/build-no-generator-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/build-no-generator-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/cache-bad-entry-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/cache-bad-entry-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/cache-bad-entry/CMakeCache.txt10
-rw-r--r--Tests/RunCMake/CommandLine/cache-bad-generator/CMakeCache.txt1
-rw-r--r--Tests/RunCMake/CommandLine/cache-empty-entry-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/cache-empty-entry-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/cache-empty-entry/CMakeCache.txt7
-rw-r--r--Tests/RunCMake/CommandLine/cache-no-file-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/cache-no-file-stderr.txt2
-rw-r--r--Tests/RunCMake/CommandLine/cache-no-generator/CMakeCache.txt0
-rw-r--r--Tests/RunCMake/CommandLine/cmake_depends-check.cmake13
-rw-r--r--Tests/RunCMake/CommandLine/cmake_depends-stdout.txt1
-rw-r--r--Tests/RunCMake/CommandLine/cmake_depends/test.c2
-rw-r--r--Tests/RunCMake/CommandLine/cmake_depends/test.h1
-rw-r--r--Tests/RunCMake/CommandLine/cmake_depends/test_UTF-16LE.hbin0 -> 58 bytes
-rw-r--r--Tests/RunCMake/CommandLine/copy_input/d1/d1.txt0
-rw-r--r--Tests/RunCMake/CommandLine/copy_input/d2/d2.txt0
-rw-r--r--Tests/RunCMake/CommandLine/copy_input/d3/d3.txt0
-rw-r--r--Tests/RunCMake/CommandLine/copy_input/f1.txt0
-rw-r--r--Tests/RunCMake/CommandLine/copy_input/f2.txt0
-rw-r--r--Tests/RunCMake/CommandLine/copy_input/f3.txt0
-rw-r--r--Tests/RunCMake/CommandLine/debug-output-stdout.txt1
-rw-r--r--Tests/RunCMake/CommandLine/debug-output.cmake0
-rw-r--r--Tests/RunCMake/CommandLine/debug-trycompile.cmake5
-rw-r--r--Tests/RunCMake/CommandLine/lists-no-file-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/lists-no-file-stderr.txt2
-rw-r--r--Tests/RunCMake/CommandLine/trace-expand-stderr.txt2
-rw-r--r--Tests/RunCMake/CommandLine/trace-expand.cmake0
-rw-r--r--Tests/RunCMake/CommandLine/trace-stderr.txt2
-rw-r--r--Tests/RunCMake/CommandLine/trace.cmake0
-rw-r--r--Tests/RunCMake/CommandLineTar/7zip-gz-result.txt1
-rw-r--r--Tests/RunCMake/CommandLineTar/7zip-gz-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLineTar/7zip.cmake10
-rw-r--r--Tests/RunCMake/CommandLineTar/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CommandLineTar/RunCMakeTest.cmake28
-rw-r--r--Tests/RunCMake/CommandLineTar/bad-format-result.txt1
-rw-r--r--Tests/RunCMake/CommandLineTar/bad-format-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLineTar/bad-from1-result.txt1
-rw-r--r--Tests/RunCMake/CommandLineTar/bad-from1-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLineTar/bad-from2-result.txt1
-rw-r--r--Tests/RunCMake/CommandLineTar/bad-from2-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLineTar/bad-from3-result.txt1
-rw-r--r--Tests/RunCMake/CommandLineTar/bad-from3-stderr.txt2
-rw-r--r--Tests/RunCMake/CommandLineTar/bad-from3.txt1
-rw-r--r--Tests/RunCMake/CommandLineTar/bad-from4-result.txt1
-rw-r--r--Tests/RunCMake/CommandLineTar/bad-from4-stderr.txt2
-rw-r--r--Tests/RunCMake/CommandLineTar/bad-from4.txt2
-rw-r--r--Tests/RunCMake/CommandLineTar/bad-from5-result.txt1
-rw-r--r--Tests/RunCMake/CommandLineTar/bad-from5-stderr.txt2
-rw-r--r--Tests/RunCMake/CommandLineTar/bad-from5.txt2
-rw-r--r--Tests/RunCMake/CommandLineTar/bad-mtime1-result.txt1
-rw-r--r--Tests/RunCMake/CommandLineTar/bad-mtime1-stderr.txt2
-rw-r--r--Tests/RunCMake/CommandLineTar/bad-opt1-result.txt1
-rw-r--r--Tests/RunCMake/CommandLineTar/bad-opt1-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLineTar/end-opt1-result.txt1
-rw-r--r--Tests/RunCMake/CommandLineTar/end-opt1-stderr.txt2
-rw-r--r--Tests/RunCMake/CommandLineTar/gnutar-gz.cmake10
-rw-r--r--Tests/RunCMake/CommandLineTar/gnutar.cmake10
-rw-r--r--Tests/RunCMake/CommandLineTar/pax-xz.cmake10
-rw-r--r--Tests/RunCMake/CommandLineTar/pax.cmake10
-rw-r--r--Tests/RunCMake/CommandLineTar/paxr-bz2.cmake10
-rw-r--r--Tests/RunCMake/CommandLineTar/paxr.cmake10
-rw-r--r--Tests/RunCMake/CommandLineTar/roundtrip.cmake81
-rw-r--r--Tests/RunCMake/CommandLineTar/zip-bz2-result.txt1
-rw-r--r--Tests/RunCMake/CommandLineTar/zip-bz2-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLineTar/zip.cmake10
-rw-r--r--Tests/RunCMake/CompatibleInterface/AutoUic-result.txt1
-rw-r--r--Tests/RunCMake/CompatibleInterface/AutoUic-stderr.txt11
-rw-r--r--Tests/RunCMake/CompatibleInterface/AutoUic.cmake19
-rw-r--r--Tests/RunCMake/CompatibleInterface/DebugProperties-result.txt1
-rw-r--r--Tests/RunCMake/CompatibleInterface/DebugProperties-stderr.txt101
-rw-r--r--Tests/RunCMake/CompatibleInterface/DebugProperties.cmake74
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceNumber-mismatched-use-result.txt1
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceNumber-mismatched-use-stderr.txt4
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceNumber-mismatched-use.cmake9
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-stderr.txt3
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict.cmake3
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Min-Conflict-result.txt1
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Min-Conflict-stderr.txt7
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Min-Conflict.cmake9
-rw-r--r--Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake8
-rw-r--r--Tests/RunCMake/CompatibleInterface/empty.cpp1
-rw-r--r--Tests/RunCMake/CompileDefinitions/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CompileDefinitions/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/CompileDefinitions/SetEmpty-result.txt1
-rw-r--r--Tests/RunCMake/CompileDefinitions/SetEmpty-stderr.txt3
-rw-r--r--Tests/RunCMake/CompileDefinitions/SetEmpty.cmake12
-rw-r--r--Tests/RunCMake/CompileFeatures/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycle-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycle-stderr.txt7
-rw-r--r--Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycle.cmake15
-rw-r--r--Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycleSolved-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycleSolved.cmake14
-rw-r--r--Tests/RunCMake/CompileFeatures/NoSupportedCFeatures-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/NoSupportedCFeatures-stderr.txt8
-rw-r--r--Tests/RunCMake/CompileFeatures/NoSupportedCFeatures.cmake5
-rw-r--r--Tests/RunCMake/CompileFeatures/NoSupportedCFeaturesGenex-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/NoSupportedCFeaturesGenex-stderr.txt6
-rw-r--r--Tests/RunCMake/CompileFeatures/NoSupportedCFeaturesGenex.cmake5
-rw-r--r--Tests/RunCMake/CompileFeatures/NoSupportedCxxFeatures-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/NoSupportedCxxFeatures-stderr.txt8
-rw-r--r--Tests/RunCMake/CompileFeatures/NoSupportedCxxFeatures.cmake3
-rw-r--r--Tests/RunCMake/CompileFeatures/NoSupportedCxxFeaturesGenex-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/NoSupportedCxxFeaturesGenex-stderr.txt6
-rw-r--r--Tests/RunCMake/CompileFeatures/NoSupportedCxxFeaturesGenex.cmake3
-rw-r--r--Tests/RunCMake/CompileFeatures/NonValidTarget1-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/NonValidTarget1-stderr.txt9
-rw-r--r--Tests/RunCMake/CompileFeatures/NonValidTarget1.cmake17
-rw-r--r--Tests/RunCMake/CompileFeatures/NonValidTarget2-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/NonValidTarget2-stderr.txt9
-rw-r--r--Tests/RunCMake/CompileFeatures/NonValidTarget2.cmake10
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature-stderr.txt2
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature.cmake3
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeatureGenex-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeatureGenex-stderr.txt2
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeatureGenex.cmake3
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeatureTransitive-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeatureTransitive-stderr.txt2
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeatureTransitive.cmake6
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug-stderr.txt11
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug.cmake4
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugCommand-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugCommand-stderr.txt5
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugCommand.cmake4
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex-stderr.txt11
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex.cmake4
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive-stderr.txt11
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive.cmake6
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAStandard-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAStandard-stderr.txt4
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAStandard.cmake2
-rw-r--r--Tests/RunCMake/CompileFeatures/RequireCXX11-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/RequireCXX11-stderr.txt3
-rw-r--r--Tests/RunCMake/CompileFeatures/RequireCXX11.cmake5
-rw-r--r--Tests/RunCMake/CompileFeatures/RequireCXX11Ext-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/RequireCXX11Ext-stderr.txt3
-rw-r--r--Tests/RunCMake/CompileFeatures/RequireCXX11Ext.cmake4
-rw-r--r--Tests/RunCMake/CompileFeatures/RequireCXX11ExtVariable-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/RequireCXX11ExtVariable-stderr.txt3
-rw-r--r--Tests/RunCMake/CompileFeatures/RequireCXX11ExtVariable.cmake4
-rw-r--r--Tests/RunCMake/CompileFeatures/RequireCXX11Variable-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/RequireCXX11Variable-stderr.txt3
-rw-r--r--Tests/RunCMake/CompileFeatures/RequireCXX11Variable.cmake5
-rw-r--r--Tests/RunCMake/CompileFeatures/RequireCXX98-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/RequireCXX98-stderr.txt3
-rw-r--r--Tests/RunCMake/CompileFeatures/RequireCXX98.cmake5
-rw-r--r--Tests/RunCMake/CompileFeatures/RequireCXX98Ext-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/RequireCXX98Ext-stderr.txt3
-rw-r--r--Tests/RunCMake/CompileFeatures/RequireCXX98Ext.cmake4
-rw-r--r--Tests/RunCMake/CompileFeatures/RequireCXX98ExtVariable-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/RequireCXX98ExtVariable-stderr.txt3
-rw-r--r--Tests/RunCMake/CompileFeatures/RequireCXX98ExtVariable.cmake4
-rw-r--r--Tests/RunCMake/CompileFeatures/RequireCXX98Variable-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/RequireCXX98Variable-stderr.txt3
-rw-r--r--Tests/RunCMake/CompileFeatures/RequireCXX98Variable.cmake5
-rw-r--r--Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake62
-rw-r--r--Tests/RunCMake/CompileFeatures/empty.c7
-rw-r--r--Tests/RunCMake/CompileFeatures/empty.cpp7
-rw-r--r--Tests/RunCMake/CompileFeatures/generate_feature_list.cmake43
-rw-r--r--Tests/RunCMake/CompilerChange/EmptyCompiler-override.cmake2
-rw-r--r--Tests/RunCMake/CompilerChange/EmptyCompiler-stderr.txt12
-rw-r--r--Tests/RunCMake/CompilerChange/EmptyCompiler.cmake3
-rw-r--r--Tests/RunCMake/CompilerChange/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/CompilerLauncher/C-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/CompilerLauncher/C-launch-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/CompilerLauncher/C-launch.cmake3
-rw-r--r--Tests/RunCMake/CompilerLauncher/C.cmake4
-rw-r--r--Tests/RunCMake/CompilerLauncher/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CompilerLauncher/CXX-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/CompilerLauncher/CXX-launch-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/CompilerLauncher/CXX-launch.cmake3
-rw-r--r--Tests/RunCMake/CompilerLauncher/CXX.cmake4
-rw-r--r--Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake23
-rw-r--r--Tests/RunCMake/CompilerLauncher/main.c3
-rw-r--r--Tests/RunCMake/CompilerLauncher/main.cxx1
-rw-r--r--Tests/RunCMake/CompilerNotFound/BadCompilerC-result.txt1
-rw-r--r--Tests/RunCMake/CompilerNotFound/BadCompilerC-stderr-JOM.txt17
-rw-r--r--Tests/RunCMake/CompilerNotFound/BadCompilerC-stderr-NMake.txt17
-rw-r--r--Tests/RunCMake/CompilerNotFound/BadCompilerC-stderr.txt12
-rw-r--r--Tests/RunCMake/CompilerNotFound/BadCompilerC.cmake3
-rw-r--r--Tests/RunCMake/CompilerNotFound/BadCompilerCXX-result.txt1
-rw-r--r--Tests/RunCMake/CompilerNotFound/BadCompilerCXX-stderr-JOM.txt17
-rw-r--r--Tests/RunCMake/CompilerNotFound/BadCompilerCXX-stderr-NMake.txt17
-rw-r--r--Tests/RunCMake/CompilerNotFound/BadCompilerCXX-stderr.txt12
-rw-r--r--Tests/RunCMake/CompilerNotFound/BadCompilerCXX.cmake3
-rw-r--r--Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-result.txt1
-rw-r--r--Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-stderr-JOM.txt35
-rw-r--r--Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-stderr-NMake.txt35
-rw-r--r--Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-stderr.txt25
-rw-r--r--Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX.cmake4
-rw-r--r--Tests/RunCMake/CompilerNotFound/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE-result.txt1
-rw-r--r--Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE-stderr.txt5
-rw-r--r--Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE.cmake3
-rw-r--r--Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE-result.txt1
-rw-r--r--Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE-stderr.txt5
-rw-r--r--Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE.cmake3
-rw-r--r--Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE-result.txt1
-rw-r--r--Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE-stderr.txt11
-rw-r--r--Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE.cmake4
-rw-r--r--Tests/RunCMake/CompilerNotFound/RunCMakeTest.cmake25
-rw-r--r--Tests/RunCMake/Configure/CustomTargetAfterError-result.txt1
-rw-r--r--Tests/RunCMake/Configure/CustomTargetAfterError-stderr.txt9
-rw-r--r--Tests/RunCMake/Configure/CustomTargetAfterError.cmake3
-rw-r--r--Tests/RunCMake/Configure/FailCopyFileABI-stdout.txt2
-rw-r--r--Tests/RunCMake/Configure/RerunCMake-build1-check.cmake9
-rw-r--r--Tests/RunCMake/Configure/RerunCMake-build2-check.cmake9
-rw-r--r--Tests/RunCMake/Configure/RerunCMake.cmake11
-rw-r--r--Tests/RunCMake/Configure/RerunCMake.txt1
-rw-r--r--Tests/RunCMake/Configure/RunCMakeTest.cmake21
-rw-r--r--Tests/RunCMake/CrosscompilingEmulator/AddTest-check.cmake12
-rw-r--r--Tests/RunCMake/CrosscompilingEmulator/AddTest.cmake8
-rw-r--r--Tests/RunCMake/CrosscompilingEmulator/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CrosscompilingEmulator/CrosscompilingEmulatorProperty.cmake28
-rw-r--r--Tests/RunCMake/CrosscompilingEmulator/InitialCache.txt.in1
-rw-r--r--Tests/RunCMake/CrosscompilingEmulator/RunCMakeTest.cmake8
-rw-r--r--Tests/RunCMake/CrosscompilingEmulator/TryRun-stdout.txt1
-rw-r--r--Tests/RunCMake/CrosscompilingEmulator/TryRun.cmake18
-rw-r--r--Tests/RunCMake/CrosscompilingEmulator/simple_src.cxx4
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0029-NEW-result.txt1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0029-NEW-stderr.txt4
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0029-NEW.cmake2
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0029-OLD.cmake2
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0029-WARN-stderr.txt7
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0029-WARN.cmake1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0030-NEW-result.txt1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0030-NEW-stderr.txt4
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0030-NEW.cmake2
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0030-OLD-result.txt1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0030-OLD-stderr.txt4
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0030-OLD.cmake2
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0030-WARN-result.txt1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0030-WARN-stderr.txt12
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0030-WARN.cmake1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0031-NEW-result.txt1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0031-NEW-stderr.txt4
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0031-NEW.cmake2
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0031-OLD-result.txt1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0031-OLD-stderr.txt4
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0031-OLD.cmake2
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0031-WARN-result.txt1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0031-WARN-stderr.txt12
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0031-WARN.cmake1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0032-NEW-result.txt1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0032-NEW-stderr.txt4
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0032-NEW.cmake2
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0032-OLD-result.txt1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0032-OLD-stderr.txt4
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0032-OLD.cmake2
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0032-WARN-result.txt1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0032-WARN-stderr.txt12
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0032-WARN.cmake1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0033-NEW-result.txt1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0033-NEW-stderr.txt4
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0033-NEW.cmake2
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0033-OLD-result.txt1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0033-OLD-stderr.txt4
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0033-OLD.cmake2
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0033-WARN-result.txt1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0033-WARN-stderr.txt12
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0033-WARN.cmake1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0034-NEW-result.txt1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0034-NEW-stderr.txt4
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0034-NEW.cmake2
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0034-OLD-result.txt1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0034-OLD-stderr.txt4
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0034-OLD.cmake2
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0034-WARN-result.txt1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0034-WARN-stderr.txt12
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0034-WARN.cmake1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0035-NEW-result.txt1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0035-NEW-stderr.txt4
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0035-NEW.cmake2
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0035-OLD-result.txt1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0035-OLD-stderr.txt4
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0035-OLD.cmake2
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0035-WARN-result.txt1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0035-WARN-stderr.txt12
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0035-WARN.cmake1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0036-NEW-result.txt1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0036-NEW-stderr.txt4
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0036-NEW.cmake2
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0036-OLD-result.txt1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0036-OLD-stderr.txt4
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0036-OLD.cmake2
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0036-WARN-result.txt1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0036-WARN-stderr.txt12
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMP0036-WARN.cmake1
-rw-r--r--Tests/RunCMake/DisallowedCommands/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/DisallowedCommands/RunCMakeTest.cmake16
-rw-r--r--Tests/RunCMake/ExportWithoutLanguage/NoLanguage-stderr.txt4
-rw-r--r--Tests/RunCMake/ExportWithoutLanguage/header.h2
-rw-r--r--Tests/RunCMake/ExternalData/BadAlgoMap1-result.txt1
-rw-r--r--Tests/RunCMake/ExternalData/BadAlgoMap1-stderr.txt9
-rw-r--r--Tests/RunCMake/ExternalData/BadAlgoMap1.cmake5
-rw-r--r--Tests/RunCMake/ExternalData/BadAlgoMap2-result.txt1
-rw-r--r--Tests/RunCMake/ExternalData/BadAlgoMap2-stderr.txt9
-rw-r--r--Tests/RunCMake/ExternalData/BadAlgoMap2.cmake5
-rw-r--r--Tests/RunCMake/ExternalData/BadCustom1-result.txt1
-rw-r--r--Tests/RunCMake/ExternalData/BadCustom1-stderr.txt9
-rw-r--r--Tests/RunCMake/ExternalData/BadCustom1.cmake5
-rw-r--r--Tests/RunCMake/ExternalData/BadCustom2-result.txt1
-rw-r--r--Tests/RunCMake/ExternalData/BadCustom2-stderr.txt9
-rw-r--r--Tests/RunCMake/ExternalData/BadCustom2.cmake5
-rw-r--r--Tests/RunCMake/ExternalData/BadCustom3-result.txt1
-rw-r--r--Tests/RunCMake/ExternalData/BadCustom3-stderr.txt7
-rw-r--r--Tests/RunCMake/ExternalData/BadCustom3.cmake5
-rw-r--r--Tests/RunCMake/ExternalData/BadCustom4-result.txt1
-rw-r--r--Tests/RunCMake/ExternalData/BadCustom4-stderr.txt7
-rw-r--r--Tests/RunCMake/ExternalData/BadCustom4.cmake6
-rw-r--r--Tests/RunCMake/ExternalData/BadRecurse1-result.txt1
-rw-r--r--Tests/RunCMake/ExternalData/BadRecurse1-stderr.txt6
-rw-r--r--Tests/RunCMake/ExternalData/BadRecurse1.cmake2
-rw-r--r--Tests/RunCMake/ExternalData/BadRecurse2-result.txt1
-rw-r--r--Tests/RunCMake/ExternalData/BadRecurse2-stderr.txt6
-rw-r--r--Tests/RunCMake/ExternalData/BadRecurse2.cmake2
-rw-r--r--Tests/RunCMake/ExternalData/BadRecurse3-result.txt1
-rw-r--r--Tests/RunCMake/ExternalData/BadRecurse3-stderr.txt9
-rw-r--r--Tests/RunCMake/ExternalData/BadRecurse3.cmake2
-rw-r--r--Tests/RunCMake/ExternalData/Directory1-stderr.txt2
-rw-r--r--Tests/RunCMake/ExternalData/Directory3-stderr.txt3
-rw-r--r--Tests/RunCMake/ExternalData/MissingData-stderr.txt5
-rw-r--r--Tests/RunCMake/ExternalData/MissingData-stdout.txt1
-rw-r--r--Tests/RunCMake/ExternalData/MissingData.cmake13
-rw-r--r--Tests/RunCMake/ExternalData/MissingDataWithAssociated-stderr.txt15
-rw-r--r--Tests/RunCMake/ExternalData/MissingDataWithAssociated-stdout.txt1
-rw-r--r--Tests/RunCMake/ExternalData/MissingDataWithAssociated.cmake10
-rw-r--r--Tests/RunCMake/ExternalData/NoURLTemplates-stderr.txt2
-rw-r--r--Tests/RunCMake/ExternalData/ObjectStoreOnly.cmake3
-rw-r--r--Tests/RunCMake/ExternalData/RunCMakeTest.cmake11
-rw-r--r--Tests/RunCMake/ExternalProject/Add_StepDependencies.cmake20
-rw-r--r--Tests/RunCMake/ExternalProject/Add_StepDependencies_iface-result.txt1
-rw-r--r--Tests/RunCMake/ExternalProject/Add_StepDependencies_iface-stderr.txt5
-rw-r--r--Tests/RunCMake/ExternalProject/Add_StepDependencies_iface.cmake4
-rw-r--r--Tests/RunCMake/ExternalProject/Add_StepDependencies_iface_step-result.txt1
-rw-r--r--Tests/RunCMake/ExternalProject/Add_StepDependencies_iface_step-stderr.txt5
-rw-r--r--Tests/RunCMake/ExternalProject/Add_StepDependencies_iface_step.cmake11
-rw-r--r--Tests/RunCMake/ExternalProject/Add_StepDependencies_no_target.cmake10
-rw-r--r--Tests/RunCMake/ExternalProject/CMAKE_CACHE_ARGS-check.cmake17
-rw-r--r--Tests/RunCMake/ExternalProject/CMAKE_CACHE_ARGS.cmake8
-rw-r--r--Tests/RunCMake/ExternalProject/CMAKE_CACHE_DEFAULT_ARGS-check.cmake17
-rw-r--r--Tests/RunCMake/ExternalProject/CMAKE_CACHE_DEFAULT_ARGS.cmake8
-rw-r--r--Tests/RunCMake/ExternalProject/CMAKE_CACHE_mix-check.cmake26
-rw-r--r--Tests/RunCMake/ExternalProject/CMAKE_CACHE_mix.cmake9
-rw-r--r--Tests/RunCMake/ExternalProject/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/ExternalProject/NO_DEPENDS-stderr.txt36
-rw-r--r--Tests/RunCMake/ExternalProject/NO_DEPENDS.cmake18
-rw-r--r--Tests/RunCMake/ExternalProject/NoOptions-result.txt1
-rw-r--r--Tests/RunCMake/ExternalProject/NoOptions-stderr.txt18
-rw-r--r--Tests/RunCMake/ExternalProject/NoOptions.cmake2
-rw-r--r--Tests/RunCMake/ExternalProject/RunCMakeTest.cmake14
-rw-r--r--Tests/RunCMake/ExternalProject/SourceEmpty-result.txt1
-rw-r--r--Tests/RunCMake/ExternalProject/SourceEmpty-stderr.txt18
-rw-r--r--Tests/RunCMake/ExternalProject/SourceEmpty.cmake5
-rw-r--r--Tests/RunCMake/ExternalProject/SourceMissing-result.txt1
-rw-r--r--Tests/RunCMake/ExternalProject/SourceMissing-stderr.txt18
-rw-r--r--Tests/RunCMake/ExternalProject/SourceMissing.cmake2
-rw-r--r--Tests/RunCMake/ExternalProject/UsesTerminal-check.cmake97
-rw-r--r--Tests/RunCMake/ExternalProject/UsesTerminal.cmake45
-rw-r--r--Tests/RunCMake/FPHSA/FindPseudo.cmake6
-rw-r--r--Tests/RunCMake/FPHSA/RunCMakeTest.cmake27
-rw-r--r--Tests/RunCMake/FPHSA/any_version.cmake1
-rw-r--r--Tests/RunCMake/FPHSA/exact_0-result.txt1
-rw-r--r--Tests/RunCMake/FPHSA/exact_0.cmake1
-rw-r--r--Tests/RunCMake/FPHSA/exact_0_matching.cmake1
-rw-r--r--Tests/RunCMake/FPHSA/exact_1.1-result.txt1
-rw-r--r--Tests/RunCMake/FPHSA/exact_1.1.cmake1
-rw-r--r--Tests/RunCMake/FPHSA/exact_1.2.2-result.txt1
-rw-r--r--Tests/RunCMake/FPHSA/exact_1.2.2.cmake1
-rw-r--r--Tests/RunCMake/FPHSA/exact_1.2.3.3-result.txt1
-rw-r--r--Tests/RunCMake/FPHSA/exact_1.2.3.3.cmake1
-rw-r--r--Tests/RunCMake/FPHSA/exact_1.2.3.4.cmake1
-rw-r--r--Tests/RunCMake/FPHSA/exact_1.2.3.5-result.txt1
-rw-r--r--Tests/RunCMake/FPHSA/exact_1.2.3.5.cmake1
-rw-r--r--Tests/RunCMake/FPHSA/exact_1.2.3.cmake1
-rw-r--r--Tests/RunCMake/FPHSA/exact_1.2.4-result.txt1
-rw-r--r--Tests/RunCMake/FPHSA/exact_1.2.4.cmake1
-rw-r--r--Tests/RunCMake/FPHSA/exact_1.2.cmake1
-rw-r--r--Tests/RunCMake/FPHSA/exact_1.3-result.txt1
-rw-r--r--Tests/RunCMake/FPHSA/exact_1.3.cmake1
-rw-r--r--Tests/RunCMake/FPHSA/exact_1.cmake1
-rw-r--r--Tests/RunCMake/FPHSA/exact_2-result.txt1
-rw-r--r--Tests/RunCMake/FPHSA/exact_2.cmake1
-rw-r--r--Tests/RunCMake/FeatureSummary/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryWhatAll-stdout.txt7
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryWhatAll.cmake9
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryWhatList-stdout.txt7
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryWhatList.cmake9
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryWhatListAll-result.txt1
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryWhatListAll-stderr.txt6
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryWhatListAll.cmake9
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryWhatListUnknown-result.txt1
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryWhatListUnknown-stderr.txt6
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryWhatListUnknown.cmake9
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryWhatOnce-stdout.txt4
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryWhatOnce.cmake8
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryWhatSingle-stdout.txt1
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryWhatSingle.cmake9
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryWhatSingleUnknown-result.txt1
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryWhatSingleUnknown-stderr.txt6
-rw-r--r--Tests/RunCMake/FeatureSummary/FeatureSummaryWhatSingleUnknown.cmake9
-rw-r--r--Tests/RunCMake/FeatureSummary/RunCMakeTest.cmake9
-rw-r--r--Tests/RunCMake/File_Generate/CMakeLists.txt5
-rw-r--r--Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex-result.txt1
-rw-r--r--Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex.cmake12
-rw-r--r--Tests/RunCMake/File_Generate/CarryPermissions-result.txt1
-rw-r--r--Tests/RunCMake/File_Generate/CarryPermissions.cmake5
-rw-r--r--Tests/RunCMake/File_Generate/CommandConflict-stderr.txt2
-rw-r--r--Tests/RunCMake/File_Generate/EmptyCondition1-stderr.txt2
-rw-r--r--Tests/RunCMake/File_Generate/EmptyCondition2-stderr.txt2
-rw-r--r--Tests/RunCMake/File_Generate/GenerateSource-result.txt1
-rw-r--r--Tests/RunCMake/File_Generate/GenerateSource.cmake12
-rw-r--r--Tests/RunCMake/File_Generate/OutputConflict-stderr.txt2
-rw-r--r--Tests/RunCMake/File_Generate/OutputNameMatchesObjects-result.txt1
-rw-r--r--Tests/RunCMake/File_Generate/OutputNameMatchesObjects-stderr.txt9
-rw-r--r--Tests/RunCMake/File_Generate/OutputNameMatchesObjects.cmake10
-rw-r--r--Tests/RunCMake/File_Generate/OutputNameMatchesOtherSources-result.txt1
-rw-r--r--Tests/RunCMake/File_Generate/OutputNameMatchesOtherSources.cmake14
-rw-r--r--Tests/RunCMake/File_Generate/OutputNameMatchesSources-result.txt1
-rw-r--r--Tests/RunCMake/File_Generate/OutputNameMatchesSources-stderr.txt7
-rw-r--r--Tests/RunCMake/File_Generate/OutputNameMatchesSources.cmake12
-rw-r--r--Tests/RunCMake/File_Generate/ReRunCMake-result.txt1
-rw-r--r--Tests/RunCMake/File_Generate/ReRunCMake.cmake5
-rw-r--r--Tests/RunCMake/File_Generate/RunCMakeTest.cmake98
-rw-r--r--Tests/RunCMake/File_Generate/WriteIfDifferent-result.txt1
-rw-r--r--Tests/RunCMake/File_Generate/WriteIfDifferent.cmake5
-rw-r--r--Tests/RunCMake/File_Generate/empty.c8
-rw-r--r--Tests/RunCMake/File_Generate/empty.cpp7
-rwxr-xr-xTests/RunCMake/File_Generate/input_script.sh3
-rw-r--r--Tests/RunCMake/FindMatlab/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/FindMatlab/MatlabTest1-result.txt1
-rw-r--r--Tests/RunCMake/FindMatlab/MatlabTest1-stderr.txt2
-rw-r--r--Tests/RunCMake/FindMatlab/MatlabTest1.cmake22
-rw-r--r--Tests/RunCMake/FindMatlab/MatlabTest2-result.txt1
-rw-r--r--Tests/RunCMake/FindMatlab/MatlabTest2-stderr.txt1
-rw-r--r--Tests/RunCMake/FindMatlab/MatlabTest2.cmake9
-rw-r--r--Tests/RunCMake/FindMatlab/RunCMakeTest.cmake51
-rw-r--r--Tests/RunCMake/FindMatlab/cmake_matlab_unit_tests2.m6
-rw-r--r--Tests/RunCMake/FindMatlab/matlab_wrapper1.cpp26
-rw-r--r--Tests/RunCMake/FindPkgConfig/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/FindPkgConfig/FindPkgConfig_CMAKE_APPBUNDLE_PATH.cmake51
-rw-r--r--Tests/RunCMake/FindPkgConfig/FindPkgConfig_CMAKE_FRAMEWORK_PATH.cmake51
-rw-r--r--Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_VARIABLE-stdout.txt1
-rw-r--r--Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_VARIABLE.cmake9
-rw-r--r--Tests/RunCMake/FindPkgConfig/FindPkgConfig_NO_PKGCONFIG_PATH.cmake41
-rw-r--r--Tests/RunCMake/FindPkgConfig/FindPkgConfig_PKGCONFIG_PATH.cmake51
-rw-r--r--Tests/RunCMake/FindPkgConfig/FindPkgConfig_PKGCONFIG_PATH_NO_CMAKE_ENVIRONMENT_PATH.cmake51
-rw-r--r--Tests/RunCMake/FindPkgConfig/FindPkgConfig_PKGCONFIG_PATH_NO_CMAKE_PATH.cmake51
-rw-r--r--Tests/RunCMake/FindPkgConfig/FindPkgConfig_cache_variables.cmake17
-rw-r--r--Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake18
-rwxr-xr-xTests/RunCMake/FindPkgConfig/dummy-pkg-config.bat18
-rwxr-xr-xTests/RunCMake/FindPkgConfig/dummy-pkg-config.sh21
-rw-r--r--Tests/RunCMake/FindPkgConfig/pc-bar/lib/i386-linux-gnu/pkgconfig/.placeholder0
-rw-r--r--Tests/RunCMake/FindPkgConfig/pc-bar/lib/pkgconfig/.placeholder0
-rw-r--r--Tests/RunCMake/FindPkgConfig/pc-bar/lib/x86_64-linux-gnu/pkgconfig/.placeholder0
-rw-r--r--Tests/RunCMake/FindPkgConfig/pc-bar/lib64/pkgconfig/.placeholder0
-rw-r--r--Tests/RunCMake/FindPkgConfig/pc-foo/lib/i386-linux-gnu/pkgconfig/.placeholder0
-rw-r--r--Tests/RunCMake/FindPkgConfig/pc-foo/lib/pkgconfig/.placeholder0
-rw-r--r--Tests/RunCMake/FindPkgConfig/pc-foo/lib/x86_64-linux-gnu/pkgconfig/.placeholder0
-rw-r--r--Tests/RunCMake/FindPkgConfig/pc-foo/lib64/pkgconfig/.placeholder0
-rw-r--r--Tests/RunCMake/Framework/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/Framework/FrameworkLayout.cmake11
-rw-r--r--Tests/RunCMake/Framework/OSXFrameworkLayout-build-check.cmake35
-rw-r--r--Tests/RunCMake/Framework/RunCMakeTest.cmake33
-rw-r--r--Tests/RunCMake/Framework/foo.c1
-rw-r--r--Tests/RunCMake/Framework/foo.h1
-rw-r--r--Tests/RunCMake/Framework/iOSFrameworkLayout-build-check.cmake35
-rw-r--r--Tests/RunCMake/Framework/ios.cmake25
-rw-r--r--Tests/RunCMake/Framework/osx.cmake18
-rw-r--r--Tests/RunCMake/Framework/res.txt0
-rw-r--r--Tests/RunCMake/GNUInstallDirs/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/GNUInstallDirs/Common.cmake28
-rw-r--r--Tests/RunCMake/GNUInstallDirs/Opt-stderr.txt28
-rw-r--r--Tests/RunCMake/GNUInstallDirs/Opt.cmake2
-rw-r--r--Tests/RunCMake/GNUInstallDirs/Root-stderr.txt28
-rw-r--r--Tests/RunCMake/GNUInstallDirs/Root.cmake2
-rw-r--r--Tests/RunCMake/GNUInstallDirs/RunCMakeTest.cmake6
-rw-r--r--Tests/RunCMake/GNUInstallDirs/Usr-stderr.txt28
-rw-r--r--Tests/RunCMake/GNUInstallDirs/Usr.cmake2
-rw-r--r--Tests/RunCMake/GNUInstallDirs/UsrLocal-stderr.txt28
-rw-r--r--Tests/RunCMake/GNUInstallDirs/UsrLocal.cmake2
-rw-r--r--Tests/RunCMake/GeneratorExpression/BadCONFIG-stderr.txt11
-rw-r--r--Tests/RunCMake/GeneratorExpression/BadCONFIG.cmake1
-rw-r--r--Tests/RunCMake/GeneratorExpression/BadSHELL_PATH-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/BadSHELL_PATH-stderr.txt17
-rw-r--r--Tests/RunCMake/GeneratorExpression/BadSHELL_PATH.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/BadTargetTypeInterface-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/BadTargetTypeInterface-stderr.txt26
-rw-r--r--Tests/RunCMake/GeneratorExpression/BadTargetTypeInterface.cmake6
-rw-r--r--Tests/RunCMake/GeneratorExpression/CMP0044-WARN-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/CMP0044-WARN-stderr.txt7
-rw-r--r--Tests/RunCMake/GeneratorExpression/CMP0044-WARN.cmake17
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-stderr.txt10
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command.cmake8
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-stderr.txt10
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target.cmake6
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-stderr.txt10
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-stderr.txt10
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-stderr.txt10
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test.cmake5
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-stderr.txt8
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install.cmake5
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-stderr.txt10
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources.cmake5
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-stderr.txt8
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE-stderr.txt8
-rw-r--r--Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE.cmake2
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidCompiler-TARGET_PDB_FILE-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidCompiler-TARGET_PDB_FILE-stderr.txt8
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidCompiler-TARGET_PDB_FILE.cmake9
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidTarget-CXX_COMPILER_ID-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidTarget-CXX_COMPILER_ID-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidTarget-CXX_COMPILER_ID.cmake8
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidTarget-CXX_COMPILER_VERSION-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidTarget-CXX_COMPILER_VERSION-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidTarget-CXX_COMPILER_VERSION.cmake8
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidTarget-C_COMPILER_ID-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidTarget-C_COMPILER_ID-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidTarget-C_COMPILER_ID.cmake8
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidTarget-C_COMPILER_VERSION-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidTarget-C_COMPILER_VERSION-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidTarget-C_COMPILER_VERSION.cmake8
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PDB_FILE-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PDB_FILE-stderr.txt8
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PDB_FILE.cmake9
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_POLICY-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_POLICY-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_POLICY.cmake8
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PROPERTY-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PROPERTY-stderr.txt11
-rw-r--r--Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PROPERTY.cmake8
-rw-r--r--Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-stderr.txt4
-rw-r--r--Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion.cmake3
-rw-r--r--Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake27
-rw-r--r--Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion-stderr.txt4
-rw-r--r--Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/ValidTarget-TARGET_PDB_FILE-check.cmake17
-rw-r--r--Tests/RunCMake/GeneratorExpression/ValidTarget-TARGET_PDB_FILE.cmake19
-rw-r--r--Tests/RunCMake/GeneratorPlatform/BadPlatform-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorPlatform/BadPlatform-stderr.txt10
-rw-r--r--Tests/RunCMake/GeneratorPlatform/BadPlatform-toolchain.cmake1
-rw-r--r--Tests/RunCMake/GeneratorPlatform/BadPlatform.cmake1
-rw-r--r--Tests/RunCMake/GeneratorPlatform/BadPlatformToolchain-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorPlatform/BadPlatformToolchain-stderr.txt10
-rw-r--r--Tests/RunCMake/GeneratorPlatform/BadPlatformToolchain.cmake1
-rw-r--r--Tests/RunCMake/GeneratorPlatform/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/GeneratorPlatform/NoPlatform-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorPlatform/NoPlatform-stderr.txt4
-rw-r--r--Tests/RunCMake/GeneratorPlatform/NoPlatform.cmake7
-rw-r--r--Tests/RunCMake/GeneratorPlatform/RunCMakeTest.cmake28
-rw-r--r--Tests/RunCMake/GeneratorPlatform/TestPlatform-toolchain.cmake1
-rw-r--r--Tests/RunCMake/GeneratorPlatform/TestPlatformToolchain-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorPlatform/TestPlatformToolchain-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorPlatform/TestPlatformToolchain.cmake16
-rw-r--r--Tests/RunCMake/GeneratorPlatform/TwoPlatforms-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorPlatform/TwoPlatforms-stderr.txt1
-rw-r--r--Tests/RunCMake/GeneratorPlatform/TwoPlatforms.cmake1
-rw-r--r--Tests/RunCMake/GeneratorPlatform/x64Platform-stdout.txt2
-rw-r--r--Tests/RunCMake/GeneratorPlatform/x64Platform.cmake7
-rw-r--r--Tests/RunCMake/GeneratorToolset/BadToolset-stderr.txt2
-rw-r--r--Tests/RunCMake/GeneratorToolset/BadToolset-toolchain.cmake1
-rw-r--r--Tests/RunCMake/GeneratorToolset/BadToolsetToolchain-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorToolset/BadToolsetToolchain-stderr.txt10
-rw-r--r--Tests/RunCMake/GeneratorToolset/BadToolsetToolchain.cmake1
-rw-r--r--Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake13
-rw-r--r--Tests/RunCMake/GeneratorToolset/TestToolset-toolchain.cmake1
-rw-r--r--Tests/RunCMake/GeneratorToolset/TestToolsetToolchain-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorToolset/TestToolsetToolchain-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorToolset/TestToolsetToolchain.cmake25
-rw-r--r--Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-NEW-result.txt1
-rw-r--r--Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-NEW-stderr_INCLUDE_DIRECTORIES.txt6
-rw-r--r--Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-OLD-result.txt1
-rw-r--r--Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-WARN-result.txt1
-rw-r--r--Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-WARN-stderr_INCLUDE_DIRECTORIES.txt20
-rw-r--r--Tests/RunCMake/IfacePaths/BinInInstallPrefix-result.txt1
-rw-r--r--Tests/RunCMake/IfacePaths/BinInInstallPrefix-stderr_SOURCES.txt6
-rw-r--r--Tests/RunCMake/IfacePaths/BinaryDirectoryInInterface-result.txt1
-rw-r--r--Tests/RunCMake/IfacePaths/BinaryDirectoryInInterface-stderr_INCLUDE_DIRECTORIES.txt6
-rw-r--r--Tests/RunCMake/IfacePaths/BinaryDirectoryInInterface-stderr_SOURCES.txt6
-rw-r--r--Tests/RunCMake/IfacePaths/BinaryDirectoryInInterface.cmake15
-rw-r--r--Tests/RunCMake/IfacePaths/CMakeLists.txt6
-rw-r--r--Tests/RunCMake/IfacePaths/DirInInstallPrefix-result.txt1
-rw-r--r--Tests/RunCMake/IfacePaths/DirInInstallPrefix.cmake14
-rw-r--r--Tests/RunCMake/IfacePaths/InstallInBinDir-result.txt1
-rw-r--r--Tests/RunCMake/IfacePaths/InstallInBinDir-stderr_INCLUDE_DIRECTORIES.txt6
-rw-r--r--Tests/RunCMake/IfacePaths/InstallInBinDir-stderr_SOURCES.txt6
-rw-r--r--Tests/RunCMake/IfacePaths/InstallInSrcDir-result.txt1
-rw-r--r--Tests/RunCMake/IfacePaths/InstallInSrcDir-stderr_INCLUDE_DIRECTORIES.txt6
-rw-r--r--Tests/RunCMake/IfacePaths/InstallInSrcDir-stderr_SOURCES.txt6
-rw-r--r--Tests/RunCMake/IfacePaths/InstallPrefixInInterface-result.txt1
-rw-r--r--Tests/RunCMake/IfacePaths/InstallPrefixInInterface.cmake11
-rw-r--r--Tests/RunCMake/IfacePaths/InstallToPrefixInSrcDirInSource-result.txt1
-rw-r--r--Tests/RunCMake/IfacePaths/InstallToPrefixInSrcDirOutOfSource-result.txt1
-rw-r--r--Tests/RunCMake/IfacePaths/RelativePathInGenex-result.txt1
-rw-r--r--Tests/RunCMake/IfacePaths/RelativePathInGenex-stderr_INCLUDE_DIRECTORIES.txt (renamed from Tests/RunCMake/include_directories/RelativePathInGenex-stderr.txt)0
-rw-r--r--Tests/RunCMake/IfacePaths/RelativePathInGenex-stderr_SOURCES.txt4
-rw-r--r--Tests/RunCMake/IfacePaths/RelativePathInGenex.cmake13
-rw-r--r--Tests/RunCMake/IfacePaths/RelativePathInInterface-result.txt1
-rw-r--r--Tests/RunCMake/IfacePaths/RelativePathInInterface-stderr_INCLUDE_DIRECTORIES.txt (renamed from Tests/RunCMake/include_directories/RelativePathInInterface-stderr.txt)0
-rw-r--r--Tests/RunCMake/IfacePaths/RelativePathInInterface-stderr_SOURCES.txt4
-rw-r--r--Tests/RunCMake/IfacePaths/RelativePathInInterface.cmake14
-rw-r--r--Tests/RunCMake/IfacePaths/RunCMakeTest.cmake159
-rw-r--r--Tests/RunCMake/IfacePaths/SourceDirectoryInInterface-result.txt1
-rw-r--r--Tests/RunCMake/IfacePaths/SourceDirectoryInInterface-stderr_INCLUDE_DIRECTORIES.txt6
-rw-r--r--Tests/RunCMake/IfacePaths/SourceDirectoryInInterface-stderr_SOURCES.txt6
-rw-r--r--Tests/RunCMake/IfacePaths/SourceDirectoryInInterface.cmake15
-rw-r--r--Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-NEW-result.txt1
-rw-r--r--Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-NEW-stderr_INCLUDE_DIRECTORIES.txt6
-rw-r--r--Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-OLD-result.txt1
-rw-r--r--Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-WARN-result.txt1
-rw-r--r--Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-WARN-stderr_INCLUDE_DIRECTORIES.txt20
-rw-r--r--Tests/RunCMake/IfacePaths/SrcInInstallPrefix-result.txt1
-rw-r--r--Tests/RunCMake/IfacePaths/SrcInInstallPrefix-stderr_SOURCES.txt6
-rw-r--r--Tests/RunCMake/IfacePaths/empty.cpp0
-rw-r--r--Tests/RunCMake/IfacePaths/export-NOWARN-result.txt1
-rw-r--r--Tests/RunCMake/IfacePaths/export-NOWARN.cmake77
-rw-r--r--Tests/RunCMake/IncludeWhatYouUse/C-Build-stdout.txt4
-rw-r--r--Tests/RunCMake/IncludeWhatYouUse/C-launch-Build-stdout.txt4
-rw-r--r--Tests/RunCMake/IncludeWhatYouUse/C-launch.cmake3
-rw-r--r--Tests/RunCMake/IncludeWhatYouUse/C.cmake3
-rw-r--r--Tests/RunCMake/IncludeWhatYouUse/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/IncludeWhatYouUse/CXX-Build-stdout.txt4
-rw-r--r--Tests/RunCMake/IncludeWhatYouUse/CXX-launch-Build-stdout.txt4
-rw-r--r--Tests/RunCMake/IncludeWhatYouUse/CXX-launch.cmake3
-rw-r--r--Tests/RunCMake/IncludeWhatYouUse/CXX.cmake3
-rw-r--r--Tests/RunCMake/IncludeWhatYouUse/RunCMakeTest.cmake22
-rw-r--r--Tests/RunCMake/IncludeWhatYouUse/main.c1
-rw-r--r--Tests/RunCMake/IncludeWhatYouUse/main.cxx1
-rw-r--r--Tests/RunCMake/Languages/CMakeLists.txt1
-rw-r--r--Tests/RunCMake/Languages/DetermineFail-result.txt1
-rw-r--r--Tests/RunCMake/Languages/DetermineFail-stderr.txt5
-rw-r--r--Tests/RunCMake/Languages/DetermineFail.cmake2
-rw-r--r--Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt6
-rw-r--r--Tests/RunCMake/Languages/Modules/CMakeDetermineFailCompiler.cmake1
-rw-r--r--Tests/RunCMake/Languages/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-stderr.txt4
-rw-r--r--Tests/RunCMake/LinkStatic/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/LinkStatic/LINK_SEARCH_STATIC.cmake73
-rw-r--r--Tests/RunCMake/LinkStatic/LinkStatic.c5
-rw-r--r--Tests/RunCMake/LinkStatic/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/Make/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/Make/RunCMakeTest.cmake17
-rw-r--r--Tests/RunCMake/Make/TargetMessages-OFF-build-stdout.txt5
-rw-r--r--Tests/RunCMake/Make/TargetMessages-OFF.cmake2
-rw-r--r--Tests/RunCMake/Make/TargetMessages-ON-build-stdout.txt8
-rw-r--r--Tests/RunCMake/Make/TargetMessages-ON.cmake2
-rw-r--r--Tests/RunCMake/Make/TargetMessages-VAR-OFF-build-stdout.txt5
-rw-r--r--Tests/RunCMake/Make/TargetMessages-VAR-OFF.cmake1
-rw-r--r--Tests/RunCMake/Make/TargetMessages-VAR-ON-build-stdout.txt8
-rw-r--r--Tests/RunCMake/Make/TargetMessages-VAR-ON.cmake1
-rw-r--r--Tests/RunCMake/Ninja/CMP0058-NEW-by-build-stdout.txt4
-rw-r--r--Tests/RunCMake/Ninja/CMP0058-NEW-by.cmake3
-rw-r--r--Tests/RunCMake/Ninja/CMP0058-NEW-no-build-result.txt1
-rw-r--r--Tests/RunCMake/Ninja/CMP0058-NEW-no-build-stderr.txt1
-rw-r--r--Tests/RunCMake/Ninja/CMP0058-NEW-no.cmake2
-rw-r--r--Tests/RunCMake/Ninja/CMP0058-OLD-by-build-stdout.txt4
-rw-r--r--Tests/RunCMake/Ninja/CMP0058-OLD-by.cmake3
-rw-r--r--Tests/RunCMake/Ninja/CMP0058-OLD-no-build-stdout.txt4
-rw-r--r--Tests/RunCMake/Ninja/CMP0058-OLD-no.cmake2
-rw-r--r--Tests/RunCMake/Ninja/CMP0058-WARN-by-build-stdout.txt4
-rw-r--r--Tests/RunCMake/Ninja/CMP0058-WARN-by.cmake2
-rw-r--r--Tests/RunCMake/Ninja/CMP0058-WARN-no-build-stdout.txt4
-rw-r--r--Tests/RunCMake/Ninja/CMP0058-WARN-no-stderr.txt19
-rw-r--r--Tests/RunCMake/Ninja/CMP0058-WARN-no.cmake1
-rw-r--r--Tests/RunCMake/Ninja/CMP0058-common.cmake17
-rw-r--r--Tests/RunCMake/Ninja/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/Ninja/RunCMakeTest.cmake18
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadObjSource1-stderr.txt3
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadObjSource2-stderr.txt3
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadSourceExpression1-stderr.txt4
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadSourceExpression2-stderr.txt4
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadSourceExpression3-stderr.txt4
-rw-r--r--Tests/RunCMake/ObjectLibrary/ExportLanguages.cmake15
-rw-r--r--Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/ObsoleteQtMacros/AutomocMacro-WARN-stderr.txt2
-rw-r--r--Tests/RunCMake/ObsoleteQtMacros/UseModulesMacro-WARN-stderr.txt2
-rw-r--r--Tests/RunCMake/PolicyScope/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/PolicyScope/NotClosed-result.txt1
-rw-r--r--Tests/RunCMake/PolicyScope/NotClosed-stderr.txt4
-rw-r--r--Tests/RunCMake/PolicyScope/NotClosed.cmake1
-rw-r--r--Tests/RunCMake/PolicyScope/NotOpened-result.txt1
-rw-r--r--Tests/RunCMake/PolicyScope/NotOpened-stderr.txt4
-rw-r--r--Tests/RunCMake/PolicyScope/NotOpened.cmake1
-rw-r--r--Tests/RunCMake/PolicyScope/RunCMakeTest.cmake6
-rw-r--r--Tests/RunCMake/PolicyScope/dir-in-macro-generate-time-result.txt1
-rw-r--r--Tests/RunCMake/PolicyScope/dir-in-macro-generate-time-stderr.txt5
-rw-r--r--Tests/RunCMake/PolicyScope/dir-in-macro-generate-time.cmake2
-rw-r--r--Tests/RunCMake/PolicyScope/dir-in-macro-include.cmake6
-rw-r--r--Tests/RunCMake/PolicyScope/dir1/CMakeLists.txt5
-rw-r--r--Tests/RunCMake/PolicyScope/dir1/foo.cpp5
-rw-r--r--Tests/RunCMake/PolicyScope/parent-dir-generate-time-result.txt1
-rw-r--r--Tests/RunCMake/PolicyScope/parent-dir-generate-time.cmake7
-rw-r--r--Tests/RunCMake/PositionIndependentCode/Conflict4-result.txt1
-rw-r--r--Tests/RunCMake/PositionIndependentCode/Conflict4-stderr.txt4
-rw-r--r--Tests/RunCMake/PositionIndependentCode/Conflict4.cmake8
-rw-r--r--Tests/RunCMake/PositionIndependentCode/Conflict5-result.txt1
-rw-r--r--Tests/RunCMake/PositionIndependentCode/Conflict5-stderr.txt3
-rw-r--r--Tests/RunCMake/PositionIndependentCode/Conflict5.cmake9
-rw-r--r--Tests/RunCMake/PositionIndependentCode/Conflict6-result.txt1
-rw-r--r--Tests/RunCMake/PositionIndependentCode/Conflict6-stderr.txt4
-rw-r--r--Tests/RunCMake/PositionIndependentCode/Conflict6.cmake8
-rw-r--r--Tests/RunCMake/PositionIndependentCode/Debug-result.txt1
-rw-r--r--Tests/RunCMake/PositionIndependentCode/Debug-stderr.txt6
-rw-r--r--Tests/RunCMake/PositionIndependentCode/Debug.cmake8
-rw-r--r--Tests/RunCMake/PositionIndependentCode/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/README.rst67
-rw-r--r--Tests/RunCMake/RunCMake.cmake97
-rw-r--r--Tests/RunCMake/RunCTest.cmake17
-rw-r--r--Tests/RunCMake/Swift/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/Swift/NotSupported-result.txt1
-rw-r--r--Tests/RunCMake/Swift/NotSupported-stderr.txt5
-rw-r--r--Tests/RunCMake/Swift/NotSupported.cmake1
-rw-r--r--Tests/RunCMake/Swift/RunCMakeTest.cmake9
-rw-r--r--Tests/RunCMake/Swift/XcodeTooOld-result.txt1
-rw-r--r--Tests/RunCMake/Swift/XcodeTooOld-stderr.txt5
-rw-r--r--Tests/RunCMake/Swift/XcodeTooOld.cmake1
-rw-r--r--Tests/RunCMake/Syntax/.gitattributes2
-rw-r--r--Tests/RunCMake/Syntax/AtWithVariable-stderr.txt1
-rw-r--r--Tests/RunCMake/Syntax/AtWithVariable.cmake9
-rw-r--r--Tests/RunCMake/Syntax/AtWithVariableAtOnly-stderr.txt1
-rw-r--r--Tests/RunCMake/Syntax/AtWithVariableAtOnly.cmake8
-rw-r--r--Tests/RunCMake/Syntax/AtWithVariableAtOnlyFile-stderr.txt5
-rw-r--r--Tests/RunCMake/Syntax/AtWithVariableAtOnlyFile.cmake9
-rw-r--r--Tests/RunCMake/Syntax/AtWithVariableEmptyExpansion-stderr.txt1
-rw-r--r--Tests/RunCMake/Syntax/AtWithVariableEmptyExpansion.cmake8
-rw-r--r--Tests/RunCMake/Syntax/AtWithVariableEmptyExpansionAtOnly-stderr.txt1
-rw-r--r--Tests/RunCMake/Syntax/AtWithVariableEmptyExpansionAtOnly.cmake8
-rw-r--r--Tests/RunCMake/Syntax/AtWithVariableFile-stderr.txt5
-rw-r--r--Tests/RunCMake/Syntax/AtWithVariableFile.cmake8
-rw-r--r--Tests/RunCMake/Syntax/BOM-UTF-16-BE-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/BOM-UTF-16-BE-stderr.txt8
-rw-r--r--Tests/RunCMake/Syntax/BOM-UTF-16-BE.cmakebin0 -> 54 bytes
-rw-r--r--Tests/RunCMake/Syntax/BOM-UTF-16-LE-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/BOM-UTF-16-LE-stderr.txt8
-rw-r--r--Tests/RunCMake/Syntax/BOM-UTF-16-LE.cmakebin0 -> 54 bytes
-rw-r--r--Tests/RunCMake/Syntax/BOM-UTF-32-BE-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/BOM-UTF-32-BE-stderr.txt8
-rw-r--r--Tests/RunCMake/Syntax/BOM-UTF-32-BE.cmakebin0 -> 108 bytes
-rw-r--r--Tests/RunCMake/Syntax/BOM-UTF-32-LE-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/BOM-UTF-32-LE-stderr.txt8
-rw-r--r--Tests/RunCMake/Syntax/BOM-UTF-32-LE.cmakebin0 -> 108 bytes
-rw-r--r--Tests/RunCMake/Syntax/BOM-UTF-8-stdout.txt1
-rw-r--r--Tests/RunCMake/Syntax/BOM-UTF-8.cmake1
-rw-r--r--Tests/RunCMake/Syntax/Bracket0-stderr.txt1
-rw-r--r--Tests/RunCMake/Syntax/Bracket0.cmake1
-rw-r--r--Tests/RunCMake/Syntax/Bracket1-stderr.txt1
-rw-r--r--Tests/RunCMake/Syntax/Bracket1.cmake2
-rw-r--r--Tests/RunCMake/Syntax/Bracket2-stdout.txt2
-rw-r--r--Tests/RunCMake/Syntax/Bracket2.cmake2
-rw-r--r--Tests/RunCMake/Syntax/BracketBackslash-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/BracketBackslash-stderr.txt6
-rw-r--r--Tests/RunCMake/Syntax/BracketBackslash.cmake2
-rw-r--r--Tests/RunCMake/Syntax/BracketCRLF-stderr.txt1
-rw-r--r--Tests/RunCMake/Syntax/BracketCRLF.cmake8
-rw-r--r--Tests/RunCMake/Syntax/BracketComment0-stdout.txt1
-rw-r--r--Tests/RunCMake/Syntax/BracketComment0.cmake5
-rw-r--r--Tests/RunCMake/Syntax/BracketComment1-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/BracketComment1-stderr.txt4
-rw-r--r--Tests/RunCMake/Syntax/BracketComment1.cmake3
-rw-r--r--Tests/RunCMake/Syntax/BracketComment2-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/BracketComment2-stderr.txt4
-rw-r--r--Tests/RunCMake/Syntax/BracketComment2.cmake3
-rw-r--r--Tests/RunCMake/Syntax/BracketComment3-stdout.txt1
-rw-r--r--Tests/RunCMake/Syntax/BracketComment3.cmake4
-rw-r--r--Tests/RunCMake/Syntax/BracketComment4-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/BracketComment4-stderr.txt7
-rw-r--r--Tests/RunCMake/Syntax/BracketComment4.cmake3
-rw-r--r--Tests/RunCMake/Syntax/BracketComment5-stdout.txt1
-rw-r--r--Tests/RunCMake/Syntax/BracketComment5.cmake11
-rw-r--r--Tests/RunCMake/Syntax/BracketNoSpace0-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/BracketNoSpace0-stderr.txt8
-rw-r--r--Tests/RunCMake/Syntax/BracketNoSpace0.cmake1
-rw-r--r--Tests/RunCMake/Syntax/BracketNoSpace1-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/BracketNoSpace1-stderr.txt8
-rw-r--r--Tests/RunCMake/Syntax/BracketNoSpace1.cmake1
-rw-r--r--Tests/RunCMake/Syntax/BracketNoSpace2-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/BracketNoSpace2-stderr.txt8
-rw-r--r--Tests/RunCMake/Syntax/BracketNoSpace2.cmake1
-rw-r--r--Tests/RunCMake/Syntax/BracketNoSpace3-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/BracketNoSpace3-stderr.txt8
-rw-r--r--Tests/RunCMake/Syntax/BracketNoSpace3.cmake1
-rw-r--r--Tests/RunCMake/Syntax/BracketNoSpace4-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/BracketNoSpace4-stderr.txt8
-rw-r--r--Tests/RunCMake/Syntax/BracketNoSpace4.cmake1
-rw-r--r--Tests/RunCMake/Syntax/BracketNoSpace5-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/BracketNoSpace5-stderr.txt8
-rw-r--r--Tests/RunCMake/Syntax/BracketNoSpace5.cmake1
-rw-r--r--Tests/RunCMake/Syntax/BracketWarn-stderr.txt35
-rw-r--r--Tests/RunCMake/Syntax/BracketWarn-stdout.txt1
-rw-r--r--Tests/RunCMake/Syntax/BracketWarn.cmake1
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-At-NEW-stderr.txt1
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-At-NEW.cmake9
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-At-OLD-stderr.txt1
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-At-OLD.cmake9
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-At-WARN-newlines-stderr.txt27
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-At-WARN-newlines.cmake6
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-At-WARN-stderr.txt21
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-At-WARN.cmake4
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NUL-stderr.txt56
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NUL.cmake6
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithCarriageReturn-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithCarriageReturn-stderr.txt4
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithCarriageReturn.cmake2
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithCarriageReturnQuoted.cmake2
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithEscapedSpaces-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithEscapedSpaces-stderr.txt4
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithEscapedSpaces.cmake2
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithEscapedSpacesQuoted.cmake2
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithEscapedTabs-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithEscapedTabs-stderr.txt4
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithEscapedTabs.cmake2
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithEscapedTabsQuoted.cmake2
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithNewline-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithNewline-stderr.txt4
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithNewline.cmake2
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithNewlineQuoted.cmake2
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithSpaces-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithSpaces-stderr.txt12
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithSpaces.cmake2
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithSpacesQuoted-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithSpacesQuoted-stderr.txt12
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithSpacesQuoted.cmake2
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithTabs-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithTabs-stderr.txt12
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithTabs.cmake2
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithTabsQuoted-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithTabsQuoted-stderr.txt12
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-NameWithTabsQuoted.cmake2
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-ParenInENV-stderr.txt1
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-ParenInENV.cmake3
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-ParenInQuotedENV-stderr.txt1
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-ParenInQuotedENV.cmake3
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-WARN-stderr.txt28
-rw-r--r--Tests/RunCMake/Syntax/CMP0053-WARN.cmake5
-rw-r--r--Tests/RunCMake/Syntax/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/Syntax/CommandError2-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/CommandError2-stderr.txt7
-rw-r--r--Tests/RunCMake/Syntax/CommandError2.cmake1
-rw-r--r--Tests/RunCMake/Syntax/Escape1-stderr.txt3
-rw-r--r--Tests/RunCMake/Syntax/Escape1.cmake3
-rw-r--r--Tests/RunCMake/Syntax/Escape2-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/Escape2-stderr.txt13
-rw-r--r--Tests/RunCMake/Syntax/Escape2.cmake7
-rw-r--r--Tests/RunCMake/Syntax/EscapeChar-char-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/EscapeChar-char-stderr.txt.in12
-rw-r--r--Tests/RunCMake/Syntax/EscapeChar-char.cmake.in3
-rw-r--r--Tests/RunCMake/Syntax/EscapeCharsAllowed-stderr.txt12
-rw-r--r--Tests/RunCMake/Syntax/EscapeCharsAllowed.cmake26
-rw-r--r--Tests/RunCMake/Syntax/EscapeCharsDisallowed.cmake42
-rw-r--r--Tests/RunCMake/Syntax/EscapeQuotes-stderr.txt1
-rw-r--r--Tests/RunCMake/Syntax/EscapeQuotes.cmake9
-rw-r--r--Tests/RunCMake/Syntax/EscapedAt-stderr.txt1
-rw-r--r--Tests/RunCMake/Syntax/EscapedAt.cmake5
-rw-r--r--Tests/RunCMake/Syntax/ExpandInAt-stderr.txt1
-rw-r--r--Tests/RunCMake/Syntax/ExpandInAt.cmake6
-rw-r--r--Tests/RunCMake/Syntax/ForEachBracket1-stderr.txt2
-rw-r--r--Tests/RunCMake/Syntax/ForEachBracket1.cmake3
-rw-r--r--Tests/RunCMake/Syntax/FunctionBracket1-stderr.txt2
-rw-r--r--Tests/RunCMake/Syntax/FunctionBracket1.cmake6
-rw-r--r--Tests/RunCMake/Syntax/FunctionUnmatched-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/FunctionUnmatched-stderr.txt6
-rw-r--r--Tests/RunCMake/Syntax/FunctionUnmatched.cmake2
-rw-r--r--Tests/RunCMake/Syntax/FunctionUnmatchedForeach-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/FunctionUnmatchedForeach-stderr.txt8
-rw-r--r--Tests/RunCMake/Syntax/FunctionUnmatchedForeach.cmake5
-rw-r--r--Tests/RunCMake/Syntax/MacroBracket1-stderr.txt2
-rw-r--r--Tests/RunCMake/Syntax/MacroBracket1.cmake6
-rw-r--r--Tests/RunCMake/Syntax/MacroUnmatched-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/MacroUnmatched-stderr.txt6
-rw-r--r--Tests/RunCMake/Syntax/MacroUnmatched.cmake2
-rw-r--r--Tests/RunCMake/Syntax/MacroUnmatchedForeach-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/MacroUnmatchedForeach-stderr.txt8
-rw-r--r--Tests/RunCMake/Syntax/MacroUnmatchedForeach.cmake5
-rw-r--r--Tests/RunCMake/Syntax/NameWithCarriageReturn-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/NameWithCarriageReturn-stderr.txt12
-rw-r--r--Tests/RunCMake/Syntax/NameWithCarriageReturn.cmake1
-rw-r--r--Tests/RunCMake/Syntax/NameWithCarriageReturnQuoted-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/NameWithCarriageReturnQuoted-stderr.txt12
-rw-r--r--Tests/RunCMake/Syntax/NameWithCarriageReturnQuoted.cmake1
-rw-r--r--Tests/RunCMake/Syntax/NameWithEscapedSpaces-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/NameWithEscapedSpaces-stderr.txt12
-rw-r--r--Tests/RunCMake/Syntax/NameWithEscapedSpaces.cmake1
-rw-r--r--Tests/RunCMake/Syntax/NameWithEscapedSpacesQuoted-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/NameWithEscapedSpacesQuoted-stderr.txt12
-rw-r--r--Tests/RunCMake/Syntax/NameWithEscapedSpacesQuoted.cmake1
-rw-r--r--Tests/RunCMake/Syntax/NameWithEscapedTabs-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/NameWithEscapedTabs-stderr.txt12
-rw-r--r--Tests/RunCMake/Syntax/NameWithEscapedTabs.cmake1
-rw-r--r--Tests/RunCMake/Syntax/NameWithEscapedTabsQuoted-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/NameWithEscapedTabsQuoted-stderr.txt12
-rw-r--r--Tests/RunCMake/Syntax/NameWithEscapedTabsQuoted.cmake1
-rw-r--r--Tests/RunCMake/Syntax/NameWithNewline-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/NameWithNewline-stderr.txt12
-rw-r--r--Tests/RunCMake/Syntax/NameWithNewline.cmake1
-rw-r--r--Tests/RunCMake/Syntax/NameWithNewlineQuoted-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/NameWithNewlineQuoted-stderr.txt12
-rw-r--r--Tests/RunCMake/Syntax/NameWithNewlineQuoted.cmake1
-rw-r--r--Tests/RunCMake/Syntax/NameWithSpaces-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/NameWithSpaces-stderr.txt12
-rw-r--r--Tests/RunCMake/Syntax/NameWithSpaces.cmake1
-rw-r--r--Tests/RunCMake/Syntax/NameWithSpacesQuoted-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/NameWithSpacesQuoted-stderr.txt12
-rw-r--r--Tests/RunCMake/Syntax/NameWithSpacesQuoted.cmake1
-rw-r--r--Tests/RunCMake/Syntax/NameWithTabs-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/NameWithTabs-stderr.txt12
-rw-r--r--Tests/RunCMake/Syntax/NameWithTabs.cmake1
-rw-r--r--Tests/RunCMake/Syntax/NameWithTabsQuoted-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/NameWithTabsQuoted-stderr.txt12
-rw-r--r--Tests/RunCMake/Syntax/NameWithTabsQuoted.cmake1
-rw-r--r--Tests/RunCMake/Syntax/OneLetter-stderr.txt1
-rw-r--r--Tests/RunCMake/Syntax/OneLetter.cmake7
-rw-r--r--Tests/RunCMake/Syntax/ParenInENV-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/ParenInENV-stderr.txt22
-rw-r--r--Tests/RunCMake/Syntax/ParenInENV.cmake2
-rw-r--r--Tests/RunCMake/Syntax/ParenInQuotedENV-stderr.txt1
-rw-r--r--Tests/RunCMake/Syntax/ParenInQuotedENV.cmake2
-rw-r--r--Tests/RunCMake/Syntax/ParenInVarName0-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/ParenInVarName0-stderr.txt12
-rw-r--r--Tests/RunCMake/Syntax/ParenInVarName0.cmake4
-rw-r--r--Tests/RunCMake/Syntax/ParenInVarName1-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/ParenInVarName1-stderr.txt12
-rw-r--r--Tests/RunCMake/Syntax/ParenInVarName1.cmake4
-rw-r--r--Tests/RunCMake/Syntax/ParenNoSpace-stderr.txt1
-rw-r--r--Tests/RunCMake/Syntax/ParenNoSpace-stdout.txt2
-rw-r--r--Tests/RunCMake/Syntax/ParenNoSpace.cmake2
-rw-r--r--Tests/RunCMake/Syntax/ParenNoSpace0-stdout.txt3
-rw-r--r--Tests/RunCMake/Syntax/ParenNoSpace0.cmake3
-rw-r--r--Tests/RunCMake/Syntax/ParenNoSpace1-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/ParenNoSpace1-stderr.txt28
-rw-r--r--Tests/RunCMake/Syntax/ParenNoSpace1.cmake3
-rw-r--r--Tests/RunCMake/Syntax/ParenNoSpace2-stdout.txt3
-rw-r--r--Tests/RunCMake/Syntax/ParenNoSpace2.cmake3
-rw-r--r--Tests/RunCMake/Syntax/RunCMakeTest.cmake102
-rw-r--r--Tests/RunCMake/Syntax/StringBackslash-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/StringBackslash-stderr.txt6
-rw-r--r--Tests/RunCMake/Syntax/StringBackslash.cmake2
-rw-r--r--Tests/RunCMake/Syntax/StringCRLF-stderr.txt1
-rw-r--r--Tests/RunCMake/Syntax/StringCRLF.cmake6
-rw-r--r--Tests/RunCMake/Syntax/StringContinuation1-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/StringContinuation1-stderr.txt4
-rw-r--r--Tests/RunCMake/Syntax/StringContinuation1.cmake2
-rw-r--r--Tests/RunCMake/Syntax/StringContinuation2-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/StringContinuation2-stderr.txt4
-rw-r--r--Tests/RunCMake/Syntax/StringContinuation2.cmake2
-rw-r--r--Tests/RunCMake/Syntax/StringNoSpace-stderr.txt8
-rw-r--r--Tests/RunCMake/Syntax/Unquoted1-stderr.txt2
-rw-r--r--Tests/RunCMake/Syntax/Unquoted1.cmake2
-rw-r--r--Tests/RunCMake/Syntax/Unquoted2-stderr.txt1
-rw-r--r--Tests/RunCMake/Syntax/Unquoted2.cmake3
-rw-r--r--Tests/RunCMake/Syntax/UnterminatedBrace0-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/UnterminatedBrace0-stderr.txt12
-rw-r--r--Tests/RunCMake/Syntax/UnterminatedBrace0.cmake2
-rw-r--r--Tests/RunCMake/Syntax/UnterminatedBrace1-stderr.txt13
-rw-r--r--Tests/RunCMake/Syntax/UnterminatedBrace1.cmake3
-rw-r--r--Tests/RunCMake/Syntax/UnterminatedBrace2-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/UnterminatedBrace2-stderr.txt12
-rw-r--r--Tests/RunCMake/Syntax/UnterminatedBrace2.cmake4
-rw-r--r--Tests/RunCMake/Syntax/UnterminatedBracket0-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/UnterminatedBracket0-stderr.txt8
-rw-r--r--Tests/RunCMake/Syntax/UnterminatedBracket0.cmake1
-rw-r--r--Tests/RunCMake/Syntax/UnterminatedBracket1-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/UnterminatedBracket1-stderr.txt8
-rw-r--r--Tests/RunCMake/Syntax/UnterminatedBracket1.cmake1
-rw-r--r--Tests/RunCMake/Syntax/UnterminatedBracketComment-result.txt1
-rw-r--r--Tests/RunCMake/Syntax/UnterminatedBracketComment-stderr.txt8
-rw-r--r--Tests/RunCMake/Syntax/UnterminatedBracketComment.cmake2
-rw-r--r--Tests/RunCMake/Syntax/atfile.txt.in4
-rw-r--r--Tests/RunCMake/TargetObjects/BadContext-result.txt1
-rw-r--r--Tests/RunCMake/TargetObjects/BadContext-stderr.txt27
-rw-r--r--Tests/RunCMake/TargetObjects/BadContext.cmake7
-rw-r--r--Tests/RunCMake/TargetObjects/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/TargetObjects/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt12
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference1-stderr.txt2
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference2-stderr.txt2
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference3-stderr.txt2
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference4-stderr.txt2
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference5-stderr.txt2
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference6-stderr.txt2
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1-result.txt1
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1-stderr.txt10
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1.cmake8
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2-result.txt1
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2-stderr.txt10
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2.cmake8
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3-result.txt1
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3.cmake10
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4-result.txt1
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4-stderr.txt8
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4.cmake14
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5-result.txt1
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5-stderr.txt8
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5.cmake10
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6-result.txt1
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6-stderr.txt8
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6.cmake14
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/RunCMakeTest.cmake6
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/empty.cpp7
-rw-r--r--Tests/RunCMake/TargetSources/CMP0026-LOCATION-result.txt1
-rw-r--r--Tests/RunCMake/TargetSources/CMP0026-LOCATION.cmake13
-rw-r--r--Tests/RunCMake/TargetSources/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/TargetSources/ConfigNotAllowed-result.txt1
-rw-r--r--Tests/RunCMake/TargetSources/ConfigNotAllowed-stderr.txt14
-rw-r--r--Tests/RunCMake/TargetSources/ConfigNotAllowed.cmake2
-rw-r--r--Tests/RunCMake/TargetSources/ExportBuild-result.txt1
-rw-r--r--Tests/RunCMake/TargetSources/ExportBuild.cmake5
-rw-r--r--Tests/RunCMake/TargetSources/OriginDebug-result.txt1
-rw-r--r--Tests/RunCMake/TargetSources/OriginDebug-stderr.txt31
-rw-r--r--Tests/RunCMake/TargetSources/OriginDebug.cmake20
-rw-r--r--Tests/RunCMake/TargetSources/OriginDebugIDE-result.txt1
-rw-r--r--Tests/RunCMake/TargetSources/OriginDebugIDE-stderr.txt40
-rw-r--r--Tests/RunCMake/TargetSources/OriginDebugIDE.cmake4
-rw-r--r--Tests/RunCMake/TargetSources/RelativePathInInterface-result.txt1
-rw-r--r--Tests/RunCMake/TargetSources/RelativePathInInterface-stderr.txt4
-rw-r--r--Tests/RunCMake/TargetSources/RelativePathInInterface.cmake6
-rw-r--r--Tests/RunCMake/TargetSources/RunCMakeTest.cmake12
-rw-r--r--Tests/RunCMake/TargetSources/empty_1.cpp7
-rw-r--r--Tests/RunCMake/TargetSources/empty_2.cpp7
-rw-r--r--Tests/RunCMake/TargetSources/empty_3.cpp7
-rw-r--r--Tests/RunCMake/TargetSources/empty_4.cpp7
-rw-r--r--Tests/RunCMake/TargetSources/main.cpp5
-rw-r--r--Tests/RunCMake/VisibilityPreset/CMP0063-Common.cmake7
-rw-r--r--Tests/RunCMake/VisibilityPreset/CMP0063-NEW.cmake8
-rw-r--r--Tests/RunCMake/VisibilityPreset/CMP0063-OLD.cmake8
-rw-r--r--Tests/RunCMake/VisibilityPreset/CMP0063-WARN-exe-stderr.txt15
-rw-r--r--Tests/RunCMake/VisibilityPreset/CMP0063-WARN-exe.cmake11
-rw-r--r--Tests/RunCMake/VisibilityPreset/CMP0063-WARN-no.cmake8
-rw-r--r--Tests/RunCMake/VisibilityPreset/CMP0063-WARN-obj-stderr.txt15
-rw-r--r--Tests/RunCMake/VisibilityPreset/CMP0063-WARN-obj.cmake11
-rw-r--r--Tests/RunCMake/VisibilityPreset/CMP0063-WARN-sta-stderr.txt15
-rw-r--r--Tests/RunCMake/VisibilityPreset/CMP0063-WARN-sta.cmake11
-rw-r--r--Tests/RunCMake/VisibilityPreset/CMakeLists.txt9
-rw-r--r--Tests/RunCMake/VisibilityPreset/PropertyTypo.cmake5
-rw-r--r--Tests/RunCMake/VisibilityPreset/RunCMakeTest.cmake6
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/EmptyPrefix-result.txt1
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/EmptyPrefix-stderr.txt5
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/EmptyPrefix.cmake10
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/ExtraArgs-result.txt1
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/ExtraArgs-stderr.txt5
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/ExtraArgs.cmake10
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/FileTypo-result.txt1
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/FileTypo-stderr.txt5
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/FileTypo.cmake7
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/InvalidArgs-result.txt1
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/InvalidArgs-stderr.txt11
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/InvalidArgs.cmake6
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/InvalidCXXFeature-result.txt1
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/InvalidCXXFeature-stderr.txt5
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/InvalidCXXFeature.cmake10
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/InvalidCompiler-result.txt1
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/InvalidCompiler-stderr.txt5
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/InvalidCompiler.cmake10
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/InvalidFeature-result.txt1
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/InvalidFeature-stderr.txt5
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/InvalidFeature.cmake10
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/InvalidPrefix-result.txt1
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/InvalidPrefix-stderr.txt5
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/InvalidPrefix.cmake10
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/MultiBadOutDir-result.txt1
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/MultiBadOutDir-stderr.txt6
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/MultiBadOutDir.cmake12
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutFileVar-result.txt1
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutFileVar-stderr.txt5
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutFileVar.cmake11
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutdir-result.txt1
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutdir-stderr.txt5
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutdir.cmake11
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/NoCompiler-result.txt1
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/NoCompiler-stderr.txt6
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/NoCompiler.cmake10
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/NoFeature-result.txt1
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/NoFeature-stderr.txt6
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/NoFeature.cmake10
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/OldVersion-result.txt1
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/OldVersion-stderr.txt9
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/OldVersion.cmake10
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/PrefixTypo-result.txt1
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/PrefixTypo-stderr.txt5
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/PrefixTypo.cmake7
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/RunCMakeTest.cmake18
-rw-r--r--Tests/RunCMake/XcodeProject/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/XcodeProject/RunCMakeTest.cmake153
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeAttributeGenex-check.cmake55
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeAttributeGenex.cmake16
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeAttributeGenexError-result.txt1
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeAttributeGenexError-stderr.txt6
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeAttributeGenexError.cmake4
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeBundles.cmake63
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeFileType-check.cmake10
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeFileType.cmake4
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined-install-check.cmake30
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined.cmake27
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune-install-check.cmake26
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune-install-stdout.txt2
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune.cmake36
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedSingleArch-install-check.cmake25
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedSingleArch.cmake19
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeInstallIOS-install-stdout.txt2
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeInstallIOS.cmake12
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeObjectNeedsEscape-check.cmake7
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeObjectNeedsEscape.cmake3
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeObjectNeedsQuote-check.cmake7
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeObjectNeedsQuote.cmake3
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeOptimizationFlags-check.cmake7
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeOptimizationFlags.cmake20
-rw-r--r--Tests/RunCMake/XcodeProject/XcodePlatformFrameworks.cmake6
-rw-r--r--Tests/RunCMake/XcodeProject/XcodePreserveNonOptimizationFlags-check.cmake8
-rw-r--r--Tests/RunCMake/XcodeProject/XcodePreserveNonOptimizationFlags.cmake12
-rw-r--r--Tests/RunCMake/XcodeProject/XcodePreserveObjcFlag-check.cmake7
-rw-r--r--Tests/RunCMake/XcodeProject/XcodePreserveObjcFlag.cmake6
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeTbdStub-stdout.txt1
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeTbdStub.cmake2
-rw-r--r--Tests/RunCMake/XcodeProject/foo.cpp1
-rw-r--r--Tests/RunCMake/XcodeProject/main.c0
-rw-r--r--Tests/RunCMake/XcodeProject/main.cpp3
-rw-r--r--Tests/RunCMake/XcodeProject/main.m3
-rw-r--r--Tests/RunCMake/XcodeProject/osx.cmake18
-rw-r--r--Tests/RunCMake/XcodeProject/someFileWithoutSpecialChars0
-rw-r--r--Tests/RunCMake/XcodeProject/src-default0
-rw-r--r--Tests/RunCMake/XcodeProject/src-explicit0
-rw-r--r--Tests/RunCMake/XcodeProject/src-lastKnown0
-rw-r--r--Tests/RunCMake/add_custom_command/AppendNoOutput-result.txt1
-rw-r--r--Tests/RunCMake/add_custom_command/AppendNoOutput-stderr.txt4
-rw-r--r--Tests/RunCMake/add_custom_command/AppendNoOutput.cmake1
-rw-r--r--Tests/RunCMake/add_custom_command/AppendNotOutput-result.txt1
-rw-r--r--Tests/RunCMake/add_custom_command/AppendNotOutput-stderr.txt5
-rw-r--r--Tests/RunCMake/add_custom_command/AppendNotOutput.cmake1
-rw-r--r--Tests/RunCMake/add_custom_command/BadArgument-result.txt1
-rw-r--r--Tests/RunCMake/add_custom_command/BadArgument-stderr.txt4
-rw-r--r--Tests/RunCMake/add_custom_command/BadArgument.cmake1
-rw-r--r--Tests/RunCMake/add_custom_command/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/add_custom_command/NoArguments-result.txt1
-rw-r--r--Tests/RunCMake/add_custom_command/NoArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/add_custom_command/NoArguments.cmake1
-rw-r--r--Tests/RunCMake/add_custom_command/NoOutputOrTarget-result.txt1
-rw-r--r--Tests/RunCMake/add_custom_command/NoOutputOrTarget-stderr.txt4
-rw-r--r--Tests/RunCMake/add_custom_command/NoOutputOrTarget.cmake1
-rw-r--r--Tests/RunCMake/add_custom_command/OutputAndTarget-result.txt1
-rw-r--r--Tests/RunCMake/add_custom_command/OutputAndTarget-stderr.txt5
-rw-r--r--Tests/RunCMake/add_custom_command/OutputAndTarget.cmake1
-rw-r--r--Tests/RunCMake/add_custom_command/RunCMakeTest.cmake12
-rw-r--r--Tests/RunCMake/add_custom_command/SourceByproducts-result.txt1
-rw-r--r--Tests/RunCMake/add_custom_command/SourceByproducts-stderr.txt4
-rw-r--r--Tests/RunCMake/add_custom_command/SourceByproducts.cmake1
-rw-r--r--Tests/RunCMake/add_custom_command/SourceUsesTerminal-result.txt1
-rw-r--r--Tests/RunCMake/add_custom_command/SourceUsesTerminal-stderr.txt4
-rw-r--r--Tests/RunCMake/add_custom_command/SourceUsesTerminal.cmake1
-rw-r--r--Tests/RunCMake/add_custom_command/TargetImported-result.txt1
-rw-r--r--Tests/RunCMake/add_custom_command/TargetImported-stderr.txt4
-rw-r--r--Tests/RunCMake/add_custom_command/TargetImported.cmake2
-rw-r--r--Tests/RunCMake/add_custom_command/TargetNotInDir-result.txt1
-rw-r--r--Tests/RunCMake/add_custom_command/TargetNotInDir-stderr.txt4
-rw-r--r--Tests/RunCMake/add_custom_command/TargetNotInDir.cmake2
-rw-r--r--Tests/RunCMake/add_custom_command/TargetNotInDir/CMakeLists.txt1
-rw-r--r--Tests/RunCMake/add_custom_target/BadTargetName-result.txt1
-rw-r--r--Tests/RunCMake/add_custom_target/BadTargetName-stderr.txt17
-rw-r--r--Tests/RunCMake/add_custom_target/BadTargetName.cmake3
-rw-r--r--Tests/RunCMake/add_custom_target/ByproductsNoCommand-result.txt1
-rw-r--r--Tests/RunCMake/add_custom_target/ByproductsNoCommand-stderr.txt4
-rw-r--r--Tests/RunCMake/add_custom_target/ByproductsNoCommand.cmake1
-rw-r--r--Tests/RunCMake/add_custom_target/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/add_custom_target/NoArguments-result.txt1
-rw-r--r--Tests/RunCMake/add_custom_target/NoArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/add_custom_target/NoArguments.cmake1
-rw-r--r--Tests/RunCMake/add_custom_target/RunCMakeTest.cmake6
-rw-r--r--Tests/RunCMake/add_custom_target/UsesTerminalNoCommand-result.txt1
-rw-r--r--Tests/RunCMake/add_custom_target/UsesTerminalNoCommand-stderr.txt4
-rw-r--r--Tests/RunCMake/add_custom_target/UsesTerminalNoCommand.cmake1
-rw-r--r--Tests/RunCMake/add_subdirectory/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/add_subdirectory/DoesNotExist-result.txt1
-rw-r--r--Tests/RunCMake/add_subdirectory/DoesNotExist-stderr.txt5
-rw-r--r--Tests/RunCMake/add_subdirectory/DoesNotExist.cmake1
-rw-r--r--Tests/RunCMake/add_subdirectory/Function-stdout.txt10
-rw-r--r--Tests/RunCMake/add_subdirectory/Function.cmake17
-rw-r--r--Tests/RunCMake/add_subdirectory/Function/CMakeLists.txt5
-rw-r--r--Tests/RunCMake/add_subdirectory/Missing-result.txt1
-rw-r--r--Tests/RunCMake/add_subdirectory/Missing-stderr.txt8
-rw-r--r--Tests/RunCMake/add_subdirectory/Missing.cmake1
-rw-r--r--Tests/RunCMake/add_subdirectory/Missing/Missing.txt0
-rw-r--r--Tests/RunCMake/add_subdirectory/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/build_command/BeforeProject-stderr.txt10
-rw-r--r--Tests/RunCMake/build_command/BeforeProject.cmake1
-rw-r--r--Tests/RunCMake/build_command/CMP0061-NEW-stderr.txt10
-rw-r--r--Tests/RunCMake/build_command/CMP0061-NEW.cmake2
-rw-r--r--Tests/RunCMake/build_command/CMP0061-OLD-make-stderr.txt10
-rw-r--r--Tests/RunCMake/build_command/CMP0061-OLD-make.cmake2
-rw-r--r--Tests/RunCMake/build_command/CMP0061-OLD-other-stderr.txt10
-rw-r--r--Tests/RunCMake/build_command/CMP0061-OLD-other.cmake2
-rw-r--r--Tests/RunCMake/build_command/CMP0061Common.cmake10
-rw-r--r--Tests/RunCMake/build_command/ErrorsCommon.cmake4
-rw-r--r--Tests/RunCMake/build_command/RunCMakeTest.cmake8
-rw-r--r--Tests/RunCMake/cmake_minimum_required/Before24-stderr.txt5
-rw-r--r--Tests/RunCMake/cmake_minimum_required/Before24.cmake1
-rw-r--r--Tests/RunCMake/cmake_minimum_required/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/cmake_minimum_required/CompatBefore24-result.txt1
-rw-r--r--Tests/RunCMake/cmake_minimum_required/CompatBefore24-stderr.txt5
-rw-r--r--Tests/RunCMake/cmake_minimum_required/CompatBefore24.cmake2
-rw-r--r--Tests/RunCMake/cmake_minimum_required/PolicyBefore24-result.txt1
-rw-r--r--Tests/RunCMake/cmake_minimum_required/PolicyBefore24-stderr.txt6
-rw-r--r--Tests/RunCMake/cmake_minimum_required/PolicyBefore24.cmake2
-rw-r--r--Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/cmake_parse_arguments/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/cmake_parse_arguments/CornerCases.cmake34
-rw-r--r--Tests/RunCMake/cmake_parse_arguments/Errors-result.txt1
-rw-r--r--Tests/RunCMake/cmake_parse_arguments/Errors-stderr.txt44
-rw-r--r--Tests/RunCMake/cmake_parse_arguments/Errors.cmake14
-rw-r--r--Tests/RunCMake/cmake_parse_arguments/Initialization.cmake68
-rw-r--r--Tests/RunCMake/cmake_parse_arguments/Mix.cmake24
-rw-r--r--Tests/RunCMake/cmake_parse_arguments/RunCMakeTest.cmake7
-rw-r--r--Tests/RunCMake/cmake_parse_arguments/Utils.cmake20
-rw-r--r--Tests/RunCMake/cmake_parse_arguments/test_utils.cmake20
-rw-r--r--Tests/RunCMake/configure_file/BadArg-result.txt1
-rw-r--r--Tests/RunCMake/configure_file/BadArg-stderr.txt4
-rw-r--r--Tests/RunCMake/configure_file/BadArg.cmake (renamed from Tests/CMakeTests/ConfigureFile-BadArg.cmake)0
-rw-r--r--Tests/RunCMake/configure_file/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/configure_file/DirInput-result.txt1
-rw-r--r--Tests/RunCMake/configure_file/DirInput-stderr.txt8
-rw-r--r--Tests/RunCMake/configure_file/DirInput.cmake (renamed from Tests/CMakeTests/ConfigureFile-DirInput.cmake)0
-rw-r--r--Tests/RunCMake/configure_file/DirOutput-stderr.txt1
-rw-r--r--Tests/RunCMake/configure_file/DirOutput.cmake4
-rw-r--r--Tests/RunCMake/configure_file/DirOutput.txt1
-rw-r--r--Tests/RunCMake/configure_file/NO-BOM.cmake2
-rw-r--r--Tests/RunCMake/configure_file/NO-BOM.txt.in1
-rw-r--r--Tests/RunCMake/configure_file/NewLineStyle-COPYONLY-result.txt1
-rw-r--r--Tests/RunCMake/configure_file/NewLineStyle-COPYONLY-stderr.txt4
-rw-r--r--Tests/RunCMake/configure_file/NewLineStyle-COPYONLY.cmake3
-rw-r--r--Tests/RunCMake/configure_file/NewLineStyle-NoArg-result.txt1
-rw-r--r--Tests/RunCMake/configure_file/NewLineStyle-NoArg-stderr.txt5
-rw-r--r--Tests/RunCMake/configure_file/NewLineStyle-NoArg.cmake3
-rw-r--r--Tests/RunCMake/configure_file/NewLineStyle-ValidArg.cmake17
-rw-r--r--Tests/RunCMake/configure_file/NewLineStyle-WrongArg-result.txt1
-rw-r--r--Tests/RunCMake/configure_file/NewLineStyle-WrongArg-stderr.txt5
-rw-r--r--Tests/RunCMake/configure_file/NewLineStyle-WrongArg.cmake3
-rw-r--r--Tests/RunCMake/configure_file/Relative-In.txt1
-rw-r--r--Tests/RunCMake/configure_file/Relative-stderr.txt1
-rw-r--r--Tests/RunCMake/configure_file/Relative.cmake3
-rw-r--r--Tests/RunCMake/configure_file/RerunCMake-rerun-stderr.txt1
-rw-r--r--Tests/RunCMake/configure_file/RerunCMake-rerun-stdout.txt3
-rw-r--r--Tests/RunCMake/configure_file/RerunCMake-stderr.txt1
-rw-r--r--Tests/RunCMake/configure_file/RerunCMake-stdout.txt3
-rw-r--r--Tests/RunCMake/configure_file/RerunCMake.cmake8
-rw-r--r--Tests/RunCMake/configure_file/RunCMakeTest.cmake51
-rw-r--r--Tests/RunCMake/configure_file/UTF16BE-BOM-result.txt1
-rw-r--r--Tests/RunCMake/configure_file/UTF16BE-BOM-stderr.txt6
-rw-r--r--Tests/RunCMake/configure_file/UTF16BE-BOM.cmake2
-rw-r--r--Tests/RunCMake/configure_file/UTF16BE-BOM.txt.inbin0 -> 26 bytes
-rw-r--r--Tests/RunCMake/configure_file/UTF16LE-BOM-result.txt1
-rw-r--r--Tests/RunCMake/configure_file/UTF16LE-BOM-stderr.txt6
-rw-r--r--Tests/RunCMake/configure_file/UTF16LE-BOM.cmake2
-rw-r--r--Tests/RunCMake/configure_file/UTF16LE-BOM.txt.inbin0 -> 26 bytes
-rw-r--r--Tests/RunCMake/configure_file/UTF32BE-BOM-result.txt1
-rw-r--r--Tests/RunCMake/configure_file/UTF32BE-BOM-stderr.txt6
-rw-r--r--Tests/RunCMake/configure_file/UTF32BE-BOM.cmake2
-rw-r--r--Tests/RunCMake/configure_file/UTF32BE-BOM.txt.inbin0 -> 52 bytes
-rw-r--r--Tests/RunCMake/configure_file/UTF32LE-BOM-result.txt1
-rw-r--r--Tests/RunCMake/configure_file/UTF32LE-BOM-stderr.txt6
-rw-r--r--Tests/RunCMake/configure_file/UTF32LE-BOM.cmake2
-rw-r--r--Tests/RunCMake/configure_file/UTF32LE-BOM.txt.inbin0 -> 52 bytes
-rw-r--r--Tests/RunCMake/configure_file/UTF8-BOM.cmake2
-rw-r--r--Tests/RunCMake/configure_file/UTF8-BOM.txt.in1
-rw-r--r--Tests/RunCMake/configure_file/UnknownArg-stderr.txt10
-rw-r--r--Tests/RunCMake/configure_file/UnknownArg.cmake2
-rw-r--r--Tests/RunCMake/continue/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/continue/ContinueForEachInLists.cmake10
-rw-r--r--Tests/RunCMake/continue/ContinueForeach-stdout.txt4
-rw-r--r--Tests/RunCMake/continue/ContinueForeach.cmake8
-rw-r--r--Tests/RunCMake/continue/ContinueNestedForeach-stdout.txt6
-rw-r--r--Tests/RunCMake/continue/ContinueNestedForeach.cmake13
-rw-r--r--Tests/RunCMake/continue/ContinueWhile-stdout.txt6
-rw-r--r--Tests/RunCMake/continue/ContinueWhile.cmake10
-rw-r--r--Tests/RunCMake/continue/NoArgumentsToContinue-result.txt1
-rw-r--r--Tests/RunCMake/continue/NoArgumentsToContinue-stderr.txt4
-rw-r--r--Tests/RunCMake/continue/NoArgumentsToContinue.cmake3
-rw-r--r--Tests/RunCMake/continue/NoEnclosingBlock-result.txt1
-rw-r--r--Tests/RunCMake/continue/NoEnclosingBlock-stderr.txt5
-rw-r--r--Tests/RunCMake/continue/NoEnclosingBlock.cmake1
-rw-r--r--Tests/RunCMake/continue/NoEnclosingBlockInFunction-result.txt1
-rw-r--r--Tests/RunCMake/continue/NoEnclosingBlockInFunction-stderr.txt6
-rw-r--r--Tests/RunCMake/continue/NoEnclosingBlockInFunction.cmake8
-rw-r--r--Tests/RunCMake/continue/RunCMakeTest.cmake9
-rw-r--r--Tests/RunCMake/ctest_build/BuildChangeId-check.cmake12
-rw-r--r--Tests/RunCMake/ctest_build/BuildFailure-CMP0061-OLD-result.txt1
-rw-r--r--Tests/RunCMake/ctest_build/BuildFailure-CMP0061-OLD-stderr.txt2
-rw-r--r--Tests/RunCMake/ctest_build/BuildFailure-result.txt1
-rw-r--r--Tests/RunCMake/ctest_build/BuildFailure-stderr.txt2
-rw-r--r--Tests/RunCMake/ctest_build/BuildQuiet-stdout.txt12
-rw-r--r--Tests/RunCMake/ctest_build/CMakeLists.txt.in5
-rw-r--r--Tests/RunCMake/ctest_build/CTestConfig.cmake.in1
-rw-r--r--Tests/RunCMake/ctest_build/RunCMakeTest.cmake42
-rw-r--r--Tests/RunCMake/ctest_build/test.cmake.in17
-rw-r--r--Tests/RunCMake/ctest_configure/CMakeLists.txt.in4
-rw-r--r--Tests/RunCMake/ctest_configure/CTestConfig.cmake.in1
-rw-r--r--Tests/RunCMake/ctest_configure/ConfigureQuiet-stdout.txt9
-rw-r--r--Tests/RunCMake/ctest_configure/RunCMakeTest.cmake10
-rw-r--r--Tests/RunCMake/ctest_configure/test.cmake.in14
-rw-r--r--Tests/RunCMake/ctest_coverage/CMakeLists.txt.in4
-rw-r--r--Tests/RunCMake/ctest_coverage/CTestConfig.cmake.in1
-rw-r--r--Tests/RunCMake/ctest_coverage/CoverageQuiet-stdout.txt1
-rw-r--r--Tests/RunCMake/ctest_coverage/RunCMakeTest.cmake10
-rw-r--r--Tests/RunCMake/ctest_coverage/test.cmake.in18
-rw-r--r--Tests/RunCMake/ctest_memcheck/CMakeLists.txt.in7
-rw-r--r--Tests/RunCMake/ctest_memcheck/CTestConfig.cmake.in9
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyAddressSanitizer-result.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyAddressSanitizer-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyAddressSanitizer-stdout.txt2
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyBC-result.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyBC-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyBC-stdout.txt3
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyBCNoLogFile-result.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyBCNoLogFile-stderr.txt2
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyBCNoLogFile-stdout.txt3
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyLeakSanitizer-result.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyLeakSanitizer-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyLeakSanitizer-stdout.txt3
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyMemorySanitizer-result.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyMemorySanitizer-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyMemorySanitizer-stdout.txt2
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyPurify-result.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyPurify-stdout.txt6
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyPurifyNoLogFile-result.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyPurifyNoLogFile-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyPurifyNoLogFile-stdout.txt3
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyQuiet-stdout.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyThreadSanitizer-result.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyThreadSanitizer-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyThreadSanitizer-stdout.txt13
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyUndefinedBehaviorSanitizer-result.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyUndefinedBehaviorSanitizer-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyUndefinedBehaviorSanitizer-stdout.txt2
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyValgrind-result.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyValgrind-stdout.txt6
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyValgrindCustomOptions-result.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyValgrindCustomOptions-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyValgrindCustomOptions-stdout.txt6
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyValgrindFailPost-result.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyValgrindFailPost-stderr.txt2
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyValgrindFailPost-stdout.txt6
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyValgrindFailPre-result.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyValgrindFailPre-stderr.txt2
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyValgrindFailPre-stdout.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyValgrindIgnoreMemcheck-result.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyValgrindIgnoreMemcheck-stdout.txt7
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyValgrindInvalidSupFile-result.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyValgrindInvalidSupFile-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyValgrindInvalidSupFile-stdout.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyValgrindNoLogFile-result.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyValgrindNoLogFile-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyValgrindNoLogFile-stdout.txt3
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyValgrindPrePost-result.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyValgrindPrePost-stdout.txt6
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyValgrindTwoTargets-result.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyValgrindTwoTargets-stdout.txt8
-rw-r--r--Tests/RunCMake/ctest_memcheck/NotExist-result.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/NotExist-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/NotExist-stdout.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake135
-rw-r--r--Tests/RunCMake/ctest_memcheck/Unknown-result.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/Unknown-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/Unknown-stdout.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/test.cmake.in24
-rw-r--r--Tests/RunCMake/ctest_memcheck/testAddressSanitizer.cmake58
-rw-r--r--Tests/RunCMake/ctest_memcheck/testLeakSanitizer.cmake47
-rw-r--r--Tests/RunCMake/ctest_memcheck/testMemorySanitizer.cmake27
-rw-r--r--Tests/RunCMake/ctest_memcheck/testThreadSanitizer.cmake47
-rw-r--r--Tests/RunCMake/ctest_memcheck/testUndefinedBehaviorSanitizer.cmake21
-rw-r--r--Tests/RunCMake/ctest_start/CMakeLists.txt.in4
-rw-r--r--Tests/RunCMake/ctest_start/CTestConfig.cmake.in1
-rw-r--r--Tests/RunCMake/ctest_start/ConfigInBuild-stdout.txt7
-rw-r--r--Tests/RunCMake/ctest_start/ConfigInSource-stdout.txt7
-rw-r--r--Tests/RunCMake/ctest_start/RunCMakeTest.cmake23
-rw-r--r--Tests/RunCMake/ctest_start/StartQuiet-stdout.txt (renamed from Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared-stderr.txt)0
-rw-r--r--Tests/RunCMake/ctest_start/test.cmake.in13
-rw-r--r--Tests/RunCMake/ctest_submit/BadArg-result.txt1
-rw-r--r--Tests/RunCMake/ctest_submit/BadArg-stderr.txt2
-rw-r--r--Tests/RunCMake/ctest_submit/BadFILES-result.txt1
-rw-r--r--Tests/RunCMake/ctest_submit/BadFILES-stderr.txt2
-rw-r--r--Tests/RunCMake/ctest_submit/BadPARTS-result.txt1
-rw-r--r--Tests/RunCMake/ctest_submit/BadPARTS-stderr.txt2
-rw-r--r--Tests/RunCMake/ctest_submit/CDashSubmitQuiet-result.txt1
-rw-r--r--Tests/RunCMake/ctest_submit/CDashSubmitQuiet-stderr.txt3
-rw-r--r--Tests/RunCMake/ctest_submit/CDashSubmitQuiet-stdout.txt3
-rw-r--r--Tests/RunCMake/ctest_submit/CDashUploadFILES-result.txt1
-rw-r--r--Tests/RunCMake/ctest_submit/CDashUploadFILES-stderr.txt2
-rw-r--r--Tests/RunCMake/ctest_submit/CDashUploadFTP-result.txt1
-rw-r--r--Tests/RunCMake/ctest_submit/CDashUploadFTP-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_submit/CDashUploadNone-result.txt1
-rw-r--r--Tests/RunCMake/ctest_submit/CDashUploadNone-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_submit/CDashUploadPARTS-result.txt1
-rw-r--r--Tests/RunCMake/ctest_submit/CDashUploadPARTS-stderr.txt2
-rw-r--r--Tests/RunCMake/ctest_submit/CDashUploadRETRY_COUNT-result.txt1
-rw-r--r--Tests/RunCMake/ctest_submit/CDashUploadRETRY_COUNT-stderr.txt2
-rw-r--r--Tests/RunCMake/ctest_submit/CDashUploadRETRY_DELAY-result.txt1
-rw-r--r--Tests/RunCMake/ctest_submit/CDashUploadRETRY_DELAY-stderr.txt2
-rw-r--r--Tests/RunCMake/ctest_submit/CMakeLists.txt.in4
-rw-r--r--Tests/RunCMake/ctest_submit/CTestConfig.cmake.in6
-rw-r--r--Tests/RunCMake/ctest_submit/FailDrop-cp-result.txt1
-rw-r--r--Tests/RunCMake/ctest_submit/FailDrop-cp-stderr.txt3
-rw-r--r--Tests/RunCMake/ctest_submit/FailDrop-cp-stdout.txt1
-rw-r--r--Tests/RunCMake/ctest_submit/FailDrop-ftp-result.txt1
-rw-r--r--Tests/RunCMake/ctest_submit/FailDrop-ftp-stderr.txt2
-rw-r--r--Tests/RunCMake/ctest_submit/FailDrop-ftp-stdout.txt3
-rw-r--r--Tests/RunCMake/ctest_submit/FailDrop-http-result.txt1
-rw-r--r--Tests/RunCMake/ctest_submit/FailDrop-http-stderr.txt2
-rw-r--r--Tests/RunCMake/ctest_submit/FailDrop-http-stdout.txt3
-rw-r--r--Tests/RunCMake/ctest_submit/FailDrop-https-result.txt1
-rw-r--r--Tests/RunCMake/ctest_submit/FailDrop-https-stderr.txt2
-rw-r--r--Tests/RunCMake/ctest_submit/FailDrop-https-stdout.txt3
-rw-r--r--Tests/RunCMake/ctest_submit/FailDrop-scp-result.txt1
-rw-r--r--Tests/RunCMake/ctest_submit/FailDrop-scp-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_submit/FailDrop-scp-stdout.txt1
-rw-r--r--Tests/RunCMake/ctest_submit/FailDrop-xmlrpc-result.txt1
-rw-r--r--Tests/RunCMake/ctest_submit/FailDrop-xmlrpc-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_submit/FailDrop-xmlrpc-stdout.txt1
-rw-r--r--Tests/RunCMake/ctest_submit/PARTSCDashUpload-result.txt1
-rw-r--r--Tests/RunCMake/ctest_submit/PARTSCDashUpload-stderr.txt2
-rw-r--r--Tests/RunCMake/ctest_submit/PARTSCDashUploadType-result.txt1
-rw-r--r--Tests/RunCMake/ctest_submit/PARTSCDashUploadType-stderr.txt2
-rw-r--r--Tests/RunCMake/ctest_submit/RepeatRETURN_VALUE-result.txt1
-rw-r--r--Tests/RunCMake/ctest_submit/RepeatRETURN_VALUE-stderr.txt2
-rw-r--r--Tests/RunCMake/ctest_submit/RunCMakeTest.cmake47
-rw-r--r--Tests/RunCMake/ctest_submit/test.cmake.in16
-rw-r--r--Tests/RunCMake/ctest_test/CMakeLists.txt.in5
-rw-r--r--Tests/RunCMake/ctest_test/CTestConfig.cmake.in1
-rw-r--r--Tests/RunCMake/ctest_test/CTestTestLoadFail-result.txt1
-rw-r--r--Tests/RunCMake/ctest_test/CTestTestLoadFail-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_test/CTestTestLoadFail-stdout.txt2
-rw-r--r--Tests/RunCMake/ctest_test/CTestTestLoadInvalid-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_test/CTestTestLoadInvalid-stdout.txt7
-rw-r--r--Tests/RunCMake/ctest_test/CTestTestLoadPass-stdout.txt7
-rw-r--r--Tests/RunCMake/ctest_test/RunCMakeTest.cmake77
-rw-r--r--Tests/RunCMake/ctest_test/TestChangeId-check.cmake12
-rw-r--r--Tests/RunCMake/ctest_test/TestLoadFail-result.txt1
-rw-r--r--Tests/RunCMake/ctest_test/TestLoadFail-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_test/TestLoadFail-stdout.txt2
-rw-r--r--Tests/RunCMake/ctest_test/TestLoadInvalid-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_test/TestLoadInvalid-stdout.txt7
-rw-r--r--Tests/RunCMake/ctest_test/TestLoadOrder-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_test/TestLoadOrder-stdout.txt7
-rw-r--r--Tests/RunCMake/ctest_test/TestLoadPass-stdout.txt7
-rw-r--r--Tests/RunCMake/ctest_test/TestOutputSize-check.cmake17
-rw-r--r--Tests/RunCMake/ctest_test/TestQuiet-stdout.txt2
-rw-r--r--Tests/RunCMake/ctest_test/test.cmake.in18
-rw-r--r--Tests/RunCMake/ctest_upload/CMakeLists.txt.in4
-rw-r--r--Tests/RunCMake/ctest_upload/CTestConfig.cmake.in1
-rw-r--r--Tests/RunCMake/ctest_upload/RunCMakeTest.cmake10
-rw-r--r--Tests/RunCMake/ctest_upload/UploadQuiet-stdout.txt1
-rw-r--r--Tests/RunCMake/ctest_upload/test.cmake.in14
-rw-r--r--Tests/RunCMake/execute_process/MergeOutput-stdout.txt10
-rw-r--r--Tests/RunCMake/execute_process/MergeOutput.cmake4
-rw-r--r--Tests/RunCMake/execute_process/MergeOutputFile-stderr.txt10
-rw-r--r--Tests/RunCMake/execute_process/MergeOutputFile.cmake7
-rw-r--r--Tests/RunCMake/execute_process/MergeOutputVars-stderr.txt10
-rw-r--r--Tests/RunCMake/execute_process/MergeOutputVars.cmake6
-rw-r--r--Tests/RunCMake/execute_process/RunCMakeTest.cmake8
-rw-r--r--Tests/RunCMake/export/AppendExport-result.txt1
-rw-r--r--Tests/RunCMake/export/AppendExport-stderr.txt4
-rw-r--r--Tests/RunCMake/export/AppendExport.cmake9
-rw-r--r--Tests/RunCMake/export/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/export/CustomTarget-result.txt1
-rw-r--r--Tests/RunCMake/export/CustomTarget-stderr.txt4
-rw-r--r--Tests/RunCMake/export/CustomTarget.cmake2
-rw-r--r--Tests/RunCMake/export/NoExportSet-result.txt1
-rw-r--r--Tests/RunCMake/export/NoExportSet-stderr.txt4
-rw-r--r--Tests/RunCMake/export/NoExportSet.cmake2
-rw-r--r--Tests/RunCMake/export/OldIface-result.txt1
-rw-r--r--Tests/RunCMake/export/OldIface-stderr.txt5
-rw-r--r--Tests/RunCMake/export/OldIface.cmake11
-rw-r--r--Tests/RunCMake/export/RunCMakeTest.cmake7
-rw-r--r--Tests/RunCMake/export/TargetNotFound-result.txt1
-rw-r--r--Tests/RunCMake/export/TargetNotFound-stderr.txt4
-rw-r--r--Tests/RunCMake/export/TargetNotFound.cmake1
-rw-r--r--Tests/RunCMake/file/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/file/FileOpenFailRead-result.txt1
-rw-r--r--Tests/RunCMake/file/FileOpenFailRead-stderr.txt6
-rw-r--r--Tests/RunCMake/file/FileOpenFailRead.cmake1
-rw-r--r--Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-no-arg-result.txt1
-rw-r--r--Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-no-arg-stderr.txt1
-rw-r--r--Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-no-arg.cmake1
-rw-r--r--Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-not-boolean-result.txt1
-rw-r--r--Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-not-boolean-stderr.txt1
-rw-r--r--Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-not-boolean.cmake1
-rw-r--r--Tests/RunCMake/file/GLOB-stderr.txt6
-rw-r--r--Tests/RunCMake/file/GLOB.cmake28
-rw-r--r--Tests/RunCMake/file/GLOB_RECURSE-cyclic-recursion-stderr.txt15
-rw-r--r--Tests/RunCMake/file/GLOB_RECURSE-cyclic-recursion.cmake23
-rw-r--r--Tests/RunCMake/file/GLOB_RECURSE-stderr.txt6
-rw-r--r--Tests/RunCMake/file/GLOB_RECURSE.cmake28
-rw-r--r--Tests/RunCMake/file/INSTALL-DIRECTORY-stdout.txt8
-rw-r--r--Tests/RunCMake/file/INSTALL-DIRECTORY.cmake10
-rw-r--r--Tests/RunCMake/file/INSTALL-MESSAGE-bad-result.txt1
-rw-r--r--Tests/RunCMake/file/INSTALL-MESSAGE-bad-stderr.txt32
-rw-r--r--Tests/RunCMake/file/INSTALL-MESSAGE-bad.cmake6
-rw-r--r--Tests/RunCMake/file/LOCK-error-file-create-fail-result.txt1
-rw-r--r--Tests/RunCMake/file/LOCK-error-file-create-fail-stderr.txt8
-rw-r--r--Tests/RunCMake/file/LOCK-error-file-create-fail.cmake3
-rw-r--r--Tests/RunCMake/file/LOCK-error-guard-incorrect-result.txt1
-rw-r--r--Tests/RunCMake/file/LOCK-error-guard-incorrect-stderr.txt6
-rw-r--r--Tests/RunCMake/file/LOCK-error-guard-incorrect.cmake1
-rw-r--r--Tests/RunCMake/file/LOCK-error-incorrect-timeout-result.txt1
-rw-r--r--Tests/RunCMake/file/LOCK-error-incorrect-timeout-stderr.txt4
-rw-r--r--Tests/RunCMake/file/LOCK-error-incorrect-timeout-trail-result.txt1
-rw-r--r--Tests/RunCMake/file/LOCK-error-incorrect-timeout-trail-stderr.txt4
-rw-r--r--Tests/RunCMake/file/LOCK-error-incorrect-timeout-trail.cmake1
-rw-r--r--Tests/RunCMake/file/LOCK-error-incorrect-timeout.cmake1
-rw-r--r--Tests/RunCMake/file/LOCK-error-lock-fail-result.txt1
-rw-r--r--Tests/RunCMake/file/LOCK-error-lock-fail-stderr.txt6
-rw-r--r--Tests/RunCMake/file/LOCK-error-lock-fail.cmake6
-rw-r--r--Tests/RunCMake/file/LOCK-error-negative-timeout-result.txt1
-rw-r--r--Tests/RunCMake/file/LOCK-error-negative-timeout-stderr.txt4
-rw-r--r--Tests/RunCMake/file/LOCK-error-negative-timeout.cmake1
-rw-r--r--Tests/RunCMake/file/LOCK-error-no-function-result.txt1
-rw-r--r--Tests/RunCMake/file/LOCK-error-no-function-stderr.txt8
-rw-r--r--Tests/RunCMake/file/LOCK-error-no-function.cmake1
-rw-r--r--Tests/RunCMake/file/LOCK-error-no-guard-result.txt1
-rw-r--r--Tests/RunCMake/file/LOCK-error-no-guard-stderr.txt4
-rw-r--r--Tests/RunCMake/file/LOCK-error-no-guard.cmake1
-rw-r--r--Tests/RunCMake/file/LOCK-error-no-path-result.txt1
-rw-r--r--Tests/RunCMake/file/LOCK-error-no-path-stderr.txt4
-rw-r--r--Tests/RunCMake/file/LOCK-error-no-path.cmake1
-rw-r--r--Tests/RunCMake/file/LOCK-error-no-result-variable-result.txt1
-rw-r--r--Tests/RunCMake/file/LOCK-error-no-result-variable-stderr.txt4
-rw-r--r--Tests/RunCMake/file/LOCK-error-no-result-variable.cmake1
-rw-r--r--Tests/RunCMake/file/LOCK-error-no-timeout-result.txt1
-rw-r--r--Tests/RunCMake/file/LOCK-error-no-timeout-stderr.txt4
-rw-r--r--Tests/RunCMake/file/LOCK-error-no-timeout.cmake1
-rw-r--r--Tests/RunCMake/file/LOCK-error-timeout-result.txt1
-rw-r--r--Tests/RunCMake/file/LOCK-error-timeout-stderr.txt12
-rw-r--r--Tests/RunCMake/file/LOCK-error-timeout-stdout.txt1
-rw-r--r--Tests/RunCMake/file/LOCK-error-timeout.cmake17
-rw-r--r--Tests/RunCMake/file/LOCK-error-unknown-option-result.txt1
-rw-r--r--Tests/RunCMake/file/LOCK-error-unknown-option-stderr.txt6
-rw-r--r--Tests/RunCMake/file/LOCK-error-unknown-option.cmake1
-rw-r--r--Tests/RunCMake/file/LOCK-stdout.txt11
-rw-r--r--Tests/RunCMake/file/LOCK.cmake40
-rw-r--r--Tests/RunCMake/file/RunCMakeTest.cmake29
-rw-r--r--Tests/RunCMake/file/dir/empty.txt0
-rw-r--r--Tests/RunCMake/file/subdir_test_unlock/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/file/timeout-script.cmake5
-rw-r--r--Tests/RunCMake/find_dependency/CMakeLists.txt4
-rw-r--r--Tests/RunCMake/find_dependency/EXACT-no-version-result.txt1
-rw-r--r--Tests/RunCMake/find_dependency/EXACT-no-version-stderr.txt6
-rw-r--r--Tests/RunCMake/find_dependency/EXACT-no-version.cmake4
-rw-r--r--Tests/RunCMake/find_dependency/Pack1/Pack1Config.cmake2
-rw-r--r--Tests/RunCMake/find_dependency/Pack1/Pack1ConfigVersion.cmake11
-rw-r--r--Tests/RunCMake/find_dependency/RunCMakeTest.cmake7
-rw-r--r--Tests/RunCMake/find_dependency/empty-arg-3-result.txt1
-rw-r--r--Tests/RunCMake/find_dependency/empty-arg-3-stderr.txt5
-rw-r--r--Tests/RunCMake/find_dependency/empty-arg-3.cmake4
-rw-r--r--Tests/RunCMake/find_dependency/empty-version-result.txt1
-rw-r--r--Tests/RunCMake/find_dependency/empty-version-stderr.txt5
-rw-r--r--Tests/RunCMake/find_dependency/empty-version.cmake4
-rw-r--r--Tests/RunCMake/find_dependency/extra-args-result.txt1
-rw-r--r--Tests/RunCMake/find_dependency/extra-args-stderr.txt5
-rw-r--r--Tests/RunCMake/find_dependency/extra-args.cmake4
-rw-r--r--Tests/RunCMake/find_dependency/invalid-arg-3-result.txt1
-rw-r--r--Tests/RunCMake/find_dependency/invalid-arg-3-stderr.txt5
-rw-r--r--Tests/RunCMake/find_dependency/invalid-arg-3.cmake4
-rw-r--r--Tests/RunCMake/find_file/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/find_file/PrefixInPATH-stdout.txt4
-rw-r--r--Tests/RunCMake/find_file/PrefixInPATH.cmake8
-rw-r--r--Tests/RunCMake/find_file/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/find_file/include/PrefixInPATH.h0
-rw-r--r--Tests/RunCMake/find_library/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/find_library/Created-stderr.txt2
-rw-r--r--Tests/RunCMake/find_library/Created.cmake16
-rw-r--r--Tests/RunCMake/find_library/PrefixInPATH-stdout.txt4
-rw-r--r--Tests/RunCMake/find_library/PrefixInPATH.cmake11
-rw-r--r--Tests/RunCMake/find_library/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/find_library/lib/libPrefixInPATH.a0
-rw-r--r--Tests/RunCMake/find_package/PolicyPop-result.txt1
-rw-r--r--Tests/RunCMake/find_package/PolicyPop-stderr.txt5
-rw-r--r--Tests/RunCMake/find_package/PolicyPop.cmake1
-rw-r--r--Tests/RunCMake/find_package/PolicyPop/PolicyPopConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/PolicyPop/PolicyPopConfigVersion.cmake3
-rw-r--r--Tests/RunCMake/find_package/PolicyPush-result.txt1
-rw-r--r--Tests/RunCMake/find_package/PolicyPush-stderr.txt5
-rw-r--r--Tests/RunCMake/find_package/PolicyPush.cmake1
-rw-r--r--Tests/RunCMake/find_package/PolicyPush/PolicyPushConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/PolicyPush/PolicyPushConfigVersion.cmake3
-rw-r--r--Tests/RunCMake/find_package/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/find_path/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/find_path/PrefixInPATH-stdout.txt4
-rw-r--r--Tests/RunCMake/find_path/PrefixInPATH.cmake8
-rw-r--r--Tests/RunCMake/find_path/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/find_path/include/PrefixInPATH.h0
-rwxr-xr-xTests/RunCMake/find_program/A/testA1
-rwxr-xr-xTests/RunCMake/find_program/A/testAandB1
-rwxr-xr-xTests/RunCMake/find_program/B/testAandB1
-rwxr-xr-xTests/RunCMake/find_program/B/testB1
-rw-r--r--Tests/RunCMake/find_program/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/find_program/DirsPerName-stdout.txt2
-rw-r--r--Tests/RunCMake/find_program/DirsPerName.cmake12
-rw-r--r--Tests/RunCMake/find_program/EnvAndHints-stdout.txt1
-rw-r--r--Tests/RunCMake/find_program/EnvAndHints.cmake8
-rw-r--r--Tests/RunCMake/find_program/NamesPerDir-stdout.txt2
-rw-r--r--Tests/RunCMake/find_program/NamesPerDir.cmake12
-rw-r--r--Tests/RunCMake/find_program/RunCMakeTest.cmake10
-rwxr-xr-xTests/RunCMake/find_program/Win/testCom.com0
-rwxr-xr-xTests/RunCMake/find_program/Win/testCom.exe0
-rwxr-xr-xTests/RunCMake/find_program/Win/testExe.exe0
-rw-r--r--Tests/RunCMake/find_program/WindowsCom-stdout.txt1
-rw-r--r--Tests/RunCMake/find_program/WindowsCom.cmake6
-rw-r--r--Tests/RunCMake/find_program/WindowsExe-stdout.txt1
-rw-r--r--Tests/RunCMake/find_program/WindowsExe.cmake6
-rw-r--r--Tests/RunCMake/get_filename_component/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/get_filename_component/KnownComponents.cmake110
-rw-r--r--Tests/RunCMake/get_property/BadArgument-result.txt1
-rw-r--r--Tests/RunCMake/get_property/BadArgument-stderr.txt4
-rw-r--r--Tests/RunCMake/get_property/BadArgument.cmake (renamed from Tests/CMakeTests/GetProperty-Bad-Argument.cmake)0
-rw-r--r--Tests/RunCMake/get_property/BadDirectory-result.txt1
-rw-r--r--Tests/RunCMake/get_property/BadDirectory-stderr.txt6
-rw-r--r--Tests/RunCMake/get_property/BadDirectory.cmake (renamed from Tests/CMakeTests/GetProperty-Bad-Directory.cmake)0
-rw-r--r--Tests/RunCMake/get_property/BadScope-result.txt1
-rw-r--r--Tests/RunCMake/get_property/BadScope-stderr.txt5
-rw-r--r--Tests/RunCMake/get_property/BadScope.cmake (renamed from Tests/CMakeTests/GetProperty-Bad-Scope.cmake)0
-rw-r--r--Tests/RunCMake/get_property/BadTarget-result.txt1
-rw-r--r--Tests/RunCMake/get_property/BadTarget-stderr.txt5
-rw-r--r--Tests/RunCMake/get_property/BadTarget.cmake (renamed from Tests/CMakeTests/GetProperty-Bad-Target.cmake)0
-rw-r--r--Tests/RunCMake/get_property/BadTest-result.txt1
-rw-r--r--Tests/RunCMake/get_property/BadTest-stderr.txt4
-rw-r--r--Tests/RunCMake/get_property/BadTest.cmake (renamed from Tests/CMakeTests/GetProperty-Bad-Test.cmake)0
-rw-r--r--Tests/RunCMake/get_property/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/get_property/DebugConfigurations-stderr.txt11
-rw-r--r--Tests/RunCMake/get_property/DebugConfigurations.cmake41
-rw-r--r--Tests/RunCMake/get_property/GlobalName-result.txt1
-rw-r--r--Tests/RunCMake/get_property/GlobalName-stderr.txt4
-rw-r--r--Tests/RunCMake/get_property/GlobalName.cmake (renamed from Tests/CMakeTests/GetProperty-Global-Name.cmake)0
-rw-r--r--Tests/RunCMake/get_property/MissingArgument-result.txt1
-rw-r--r--Tests/RunCMake/get_property/MissingArgument-stderr.txt4
-rw-r--r--Tests/RunCMake/get_property/MissingArgument.cmake (renamed from Tests/CMakeTests/GetProperty-Missing-Argument.cmake)0
-rw-r--r--Tests/RunCMake/get_property/NoCache-result.txt1
-rw-r--r--Tests/RunCMake/get_property/NoCache-stderr.txt4
-rw-r--r--Tests/RunCMake/get_property/NoCache.cmake (renamed from Tests/CMakeTests/GetProperty-No-Cache.cmake)0
-rw-r--r--Tests/RunCMake/get_property/NoProperty-result.txt1
-rw-r--r--Tests/RunCMake/get_property/NoProperty-stderr.txt4
-rw-r--r--Tests/RunCMake/get_property/NoProperty.cmake (renamed from Tests/CMakeTests/GetProperty-No-Property.cmake)0
-rw-r--r--Tests/RunCMake/get_property/NoSource-result.txt1
-rw-r--r--Tests/RunCMake/get_property/NoSource-stderr.txt4
-rw-r--r--Tests/RunCMake/get_property/NoSource.cmake (renamed from Tests/CMakeTests/GetProperty-No-Source.cmake)0
-rw-r--r--Tests/RunCMake/get_property/NoTarget-result.txt1
-rw-r--r--Tests/RunCMake/get_property/NoTarget-stderr.txt4
-rw-r--r--Tests/RunCMake/get_property/NoTarget.cmake (renamed from Tests/CMakeTests/GetProperty-No-Target.cmake)0
-rw-r--r--Tests/RunCMake/get_property/NoTest-result.txt1
-rw-r--r--Tests/RunCMake/get_property/NoTest-stderr.txt4
-rw-r--r--Tests/RunCMake/get_property/NoTest.cmake (renamed from Tests/CMakeTests/GetProperty-No-Test.cmake)0
-rw-r--r--Tests/RunCMake/get_property/RunCMakeTest.cmake24
-rw-r--r--Tests/RunCMake/get_property/VariableName-result.txt1
-rw-r--r--Tests/RunCMake/get_property/VariableName-stderr.txt4
-rw-r--r--Tests/RunCMake/get_property/VariableName.cmake (renamed from Tests/CMakeTests/GetProperty-Variable-Name.cmake)0
-rw-r--r--Tests/RunCMake/get_property/cache_properties-stderr.txt3
-rw-r--r--Tests/RunCMake/get_property/cache_properties.cmake15
-rw-r--r--Tests/RunCMake/get_property/directory_properties-stderr.txt6
-rw-r--r--Tests/RunCMake/get_property/directory_properties.cmake15
-rw-r--r--Tests/RunCMake/get_property/global_properties-stderr.txt6
-rw-r--r--Tests/RunCMake/get_property/global_properties.cmake16
-rw-r--r--Tests/RunCMake/get_property/install_properties-stderr.txt3
-rw-r--r--Tests/RunCMake/get_property/install_properties.cmake18
-rw-r--r--Tests/RunCMake/get_property/source_properties-stderr.txt6
-rw-r--r--Tests/RunCMake/get_property/source_properties.cmake15
-rw-r--r--Tests/RunCMake/get_property/target_properties-stderr.txt10
-rw-r--r--Tests/RunCMake/get_property/target_properties.cmake18
-rw-r--r--Tests/RunCMake/get_property/test_properties-stderr.txt6
-rw-r--r--Tests/RunCMake/get_property/test_properties.cmake17
-rw-r--r--Tests/RunCMake/if/InvalidArgument1-result.txt1
-rw-r--r--Tests/RunCMake/if/InvalidArgument1-stderr.txt8
-rw-r--r--Tests/RunCMake/if/InvalidArgument1.cmake (renamed from Tests/CMakeTests/If-Invalid-Argument.cmake)0
-rw-r--r--Tests/RunCMake/if/MatchesSelf.cmake4
-rw-r--r--Tests/RunCMake/if/RunCMakeTest.cmake7
-rw-r--r--Tests/RunCMake/if/TestNameThatDoesNotExist-stdout.txt1
-rw-r--r--Tests/RunCMake/if/TestNameThatDoesNotExist.cmake6
-rw-r--r--Tests/RunCMake/if/TestNameThatExists-stdout.txt1
-rw-r--r--Tests/RunCMake/if/TestNameThatExists.cmake7
-rw-r--r--Tests/RunCMake/if/elseif-message-result.txt1
-rw-r--r--Tests/RunCMake/if/elseif-message-stderr.txt8
-rw-r--r--Tests/RunCMake/if/elseif-message.cmake4
-rw-r--r--Tests/RunCMake/include/CMP0024-NEW-result.txt1
-rw-r--r--Tests/RunCMake/include/CMP0024-NEW-stderr.txt8
-rw-r--r--Tests/RunCMake/include/CMP0024-NEW.cmake9
-rw-r--r--Tests/RunCMake/include/CMP0024-WARN-result.txt1
-rw-r--r--Tests/RunCMake/include/CMP0024-WARN-stderr.txt14
-rw-r--r--Tests/RunCMake/include/CMP0024-WARN.cmake7
-rw-r--r--Tests/RunCMake/include/ExportExportInclude-result.txt1
-rw-r--r--Tests/RunCMake/include/ExportExportInclude-stderr.txt6
-rw-r--r--Tests/RunCMake/include/ExportExportInclude.cmake6
-rw-r--r--Tests/RunCMake/include/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/include/empty.cpp7
-rw-r--r--Tests/RunCMake/include/subdir1/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/include/subdir2/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/include_directories/BinaryDirectoryInInterface-stderr.txt6
-rw-r--r--Tests/RunCMake/include_directories/BinaryDirectoryInInterface.cmake11
-rw-r--r--Tests/RunCMake/include_directories/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/include_directories/DebugIncludes-stderr.txt12
-rw-r--r--Tests/RunCMake/include_directories/DebugIncludes.cmake2
-rw-r--r--Tests/RunCMake/include_directories/DirectoryBefore-stdout.txt1
-rw-r--r--Tests/RunCMake/include_directories/DirectoryBefore.cmake4
-rw-r--r--Tests/RunCMake/include_directories/ImportedTarget.cmake2
-rw-r--r--Tests/RunCMake/include_directories/RelativePathInGenex.cmake8
-rw-r--r--Tests/RunCMake/include_directories/RelativePathInInterface.cmake11
-rw-r--r--Tests/RunCMake/include_directories/RunCMakeTest.cmake9
-rw-r--r--Tests/RunCMake/include_directories/SourceDirectoryInInterface-stderr.txt6
-rw-r--r--Tests/RunCMake/include_directories/SourceDirectoryInInterface.cmake11
-rw-r--r--Tests/RunCMake/include_directories/TID-bad-target-stderr.txt2
-rw-r--r--Tests/RunCMake/include_directories/incomplete-genex.cmake23
-rw-r--r--Tests/RunCMake/include_external_msproject/check_utils.cmake4
-rw-r--r--Tests/RunCMake/install/CMP0062-NEW-result.txt1
-rw-r--r--Tests/RunCMake/install/CMP0062-NEW-stderr.txt11
-rw-r--r--Tests/RunCMake/install/CMP0062-NEW.cmake6
-rw-r--r--Tests/RunCMake/install/CMP0062-OLD-result.txt1
-rw-r--r--Tests/RunCMake/install/CMP0062-OLD.cmake6
-rw-r--r--Tests/RunCMake/install/CMP0062-WARN-result.txt1
-rw-r--r--Tests/RunCMake/install/CMP0062-WARN-stderr.txt16
-rw-r--r--Tests/RunCMake/install/CMP0062-WARN.cmake5
-rw-r--r--Tests/RunCMake/install/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/install/DIRECTORY-DESTINATION-bad-result.txt1
-rw-r--r--Tests/RunCMake/install/DIRECTORY-DESTINATION-bad-stderr.txt6
-rw-r--r--Tests/RunCMake/install/DIRECTORY-DESTINATION-bad.cmake1
-rw-r--r--Tests/RunCMake/install/DIRECTORY-DIRECTORY-bad-result.txt1
-rw-r--r--Tests/RunCMake/install/DIRECTORY-DIRECTORY-bad-stderr.txt6
-rw-r--r--Tests/RunCMake/install/DIRECTORY-DIRECTORY-bad.cmake1
-rw-r--r--Tests/RunCMake/install/DIRECTORY-MESSAGE_NEVER-check.cmake13
-rw-r--r--Tests/RunCMake/install/DIRECTORY-MESSAGE_NEVER.cmake3
-rw-r--r--Tests/RunCMake/install/DIRECTORY-PATTERN-MESSAGE_NEVER-result.txt1
-rw-r--r--Tests/RunCMake/install/DIRECTORY-PATTERN-MESSAGE_NEVER-stderr.txt4
-rw-r--r--Tests/RunCMake/install/DIRECTORY-PATTERN-MESSAGE_NEVER.cmake1
-rw-r--r--Tests/RunCMake/install/DIRECTORY-message-check.cmake28
-rw-r--r--Tests/RunCMake/install/DIRECTORY-message-lazy-check.cmake24
-rw-r--r--Tests/RunCMake/install/DIRECTORY-message-lazy.cmake3
-rw-r--r--Tests/RunCMake/install/DIRECTORY-message.cmake3
-rw-r--r--Tests/RunCMake/install/EXPORT-OldIFace.cmake7
-rw-r--r--Tests/RunCMake/install/EXPORT-OldIFace/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/install/FILES-DESTINATION-bad-result.txt1
-rw-r--r--Tests/RunCMake/install/FILES-DESTINATION-bad-stderr.txt6
-rw-r--r--Tests/RunCMake/install/FILES-DESTINATION-bad.cmake1
-rw-r--r--Tests/RunCMake/install/RunCMakeTest.cmake16
-rw-r--r--Tests/RunCMake/install/SkipInstallRulesNoWarning1-check.cmake9
-rw-r--r--Tests/RunCMake/install/SkipInstallRulesNoWarning1.cmake1
-rw-r--r--Tests/RunCMake/install/SkipInstallRulesNoWarning2-check.cmake9
-rw-r--r--Tests/RunCMake/install/SkipInstallRulesNoWarning2.cmake1
-rw-r--r--Tests/RunCMake/install/SkipInstallRulesWarning-check.cmake9
-rw-r--r--Tests/RunCMake/install/SkipInstallRulesWarning-stderr.txt3
-rw-r--r--Tests/RunCMake/install/SkipInstallRulesWarning.cmake2
-rw-r--r--Tests/RunCMake/install/TARGETS-DESTINATION-bad-result.txt1
-rw-r--r--Tests/RunCMake/install/TARGETS-DESTINATION-bad-stderr.txt6
-rw-r--r--Tests/RunCMake/install/TARGETS-DESTINATION-bad.cmake3
-rw-r--r--Tests/RunCMake/install/dir/empty.txt0
-rw-r--r--Tests/RunCMake/install/empty.c0
-rw-r--r--Tests/RunCMake/interface_library/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/interface_library/RunCMakeTest.cmake10
-rw-r--r--Tests/RunCMake/interface_library/add_custom_command-TARGET-result.txt1
-rw-r--r--Tests/RunCMake/interface_library/add_custom_command-TARGET-stderr.txt5
-rw-r--r--Tests/RunCMake/interface_library/add_custom_command-TARGET.cmake6
-rw-r--r--Tests/RunCMake/interface_library/genex_link-result.txt1
-rw-r--r--Tests/RunCMake/interface_library/genex_link.cmake22
-rw-r--r--Tests/RunCMake/interface_library/global-interface-result.txt1
-rw-r--r--Tests/RunCMake/interface_library/global-interface-stderr.txt9
-rw-r--r--Tests/RunCMake/interface_library/global-interface.cmake2
-rw-r--r--Tests/RunCMake/interface_library/invalid_name-result.txt1
-rw-r--r--Tests/RunCMake/interface_library/invalid_name-stderr.txt15
-rw-r--r--Tests/RunCMake/interface_library/invalid_name.cmake6
-rw-r--r--Tests/RunCMake/interface_library/invalid_signature-result.txt1
-rw-r--r--Tests/RunCMake/interface_library/invalid_signature-stderr.txt89
-rw-r--r--Tests/RunCMake/interface_library/invalid_signature.cmake20
-rw-r--r--Tests/RunCMake/interface_library/no_shared_libs.cmake5
-rw-r--r--Tests/RunCMake/interface_library/target_commands-result.txt1
-rw-r--r--Tests/RunCMake/interface_library/target_commands-stderr.txt47
-rw-r--r--Tests/RunCMake/interface_library/target_commands.cmake13
-rw-r--r--Tests/RunCMake/interface_library/whitelist-result.txt1
-rw-r--r--Tests/RunCMake/interface_library/whitelist-stderr.txt19
-rw-r--r--Tests/RunCMake/interface_library/whitelist.cmake6
-rw-r--r--Tests/RunCMake/list/GET-CMP0007-WARN-stderr.txt8
-rw-r--r--Tests/RunCMake/list/GET-CMP0007-WARN.cmake7
-rw-r--r--Tests/RunCMake/list/GET-InvalidIndex-result.txt1
-rw-r--r--Tests/RunCMake/list/GET-InvalidIndex-stderr.txt4
-rw-r--r--Tests/RunCMake/list/GET-InvalidIndex.cmake (renamed from Tests/CMakeTests/List-Get-Invalid-Index.cmake)0
-rw-r--r--Tests/RunCMake/list/INSERT-InvalidIndex-result.txt1
-rw-r--r--Tests/RunCMake/list/INSERT-InvalidIndex-stderr.txt4
-rw-r--r--Tests/RunCMake/list/INSERT-InvalidIndex.cmake (renamed from Tests/CMakeTests/List-Insert-Invalid-Index.cmake)0
-rw-r--r--Tests/RunCMake/list/InvalidSubcommand-result.txt1
-rw-r--r--Tests/RunCMake/list/InvalidSubcommand-stderr.txt4
-rw-r--r--Tests/RunCMake/list/InvalidSubcommand.cmake (renamed from Tests/CMakeTests/List-Invalid-Subcommand.cmake)0
-rw-r--r--Tests/RunCMake/list/LENGTH-TooManyArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/LENGTH-TooManyArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/LENGTH-TooManyArguments.cmake (renamed from Tests/CMakeTests/List-Length-Too-Many-Arguments.cmake)0
-rw-r--r--Tests/RunCMake/list/NoArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/NoArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/NoArguments.cmake (renamed from Tests/CMakeTests/List-No-Arguments.cmake)0
-rw-r--r--Tests/RunCMake/list/REMOVE_AT-InvalidIndex-result.txt1
-rw-r--r--Tests/RunCMake/list/REMOVE_AT-InvalidIndex-stderr.txt4
-rw-r--r--Tests/RunCMake/list/REMOVE_AT-InvalidIndex.cmake (renamed from Tests/CMakeTests/List-Remove_At-Invalid-Index.cmake)0
-rw-r--r--Tests/RunCMake/list/REMOVE_AT-NotList-result.txt1
-rw-r--r--Tests/RunCMake/list/REMOVE_AT-NotList-stderr.txt4
-rw-r--r--Tests/RunCMake/list/REMOVE_AT-NotList.cmake (renamed from Tests/CMakeTests/List-Remove_At-Nonexistent-List.cmake)0
-rw-r--r--Tests/RunCMake/list/REMOVE_DUPLICATES-NotList-result.txt1
-rw-r--r--Tests/RunCMake/list/REMOVE_DUPLICATES-NotList-stderr.txt4
-rw-r--r--Tests/RunCMake/list/REMOVE_DUPLICATES-NotList.cmake (renamed from Tests/CMakeTests/List-Remove_Duplicates-Nonexistent-List.cmake)0
-rw-r--r--Tests/RunCMake/list/REMOVE_DUPLICATES-TooManyArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/REMOVE_DUPLICATES-TooManyArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/REMOVE_DUPLICATES-TooManyArguments.cmake (renamed from Tests/CMakeTests/List-Remove_Duplicates-Too-Many-Arguments.cmake)0
-rw-r--r--Tests/RunCMake/list/REMOVE_ITEM-NotList-result.txt1
-rw-r--r--Tests/RunCMake/list/REMOVE_ITEM-NotList-stderr.txt4
-rw-r--r--Tests/RunCMake/list/REMOVE_ITEM-NotList.cmake (renamed from Tests/CMakeTests/List-Remove_Item-Nonexistent-List.cmake)0
-rw-r--r--Tests/RunCMake/list/REVERSE-NotList-result.txt1
-rw-r--r--Tests/RunCMake/list/REVERSE-NotList-stderr.txt4
-rw-r--r--Tests/RunCMake/list/REVERSE-NotList.cmake (renamed from Tests/CMakeTests/List-Reverse-Nonexistent-List.cmake)0
-rw-r--r--Tests/RunCMake/list/REVERSE-TooManyArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/REVERSE-TooManyArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/REVERSE-TooManyArguments.cmake (renamed from Tests/CMakeTests/List-Reverse-Too-Many-Arguments.cmake)0
-rw-r--r--Tests/RunCMake/list/RunCMakeTest.cmake19
-rw-r--r--Tests/RunCMake/list/SORT-NotList-result.txt1
-rw-r--r--Tests/RunCMake/list/SORT-NotList-stderr.txt4
-rw-r--r--Tests/RunCMake/list/SORT-NotList.cmake (renamed from Tests/CMakeTests/List-Sort-Nonexistent-List.cmake)0
-rw-r--r--Tests/RunCMake/list/SORT-TooManyArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/SORT-TooManyArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/SORT-TooManyArguments.cmake (renamed from Tests/CMakeTests/List-Sort-Too-Many-Arguments.cmake)0
-rw-r--r--Tests/RunCMake/message/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/message/RunCMakeTest.cmake10
-rw-r--r--Tests/RunCMake/message/defaultmessage-result.txt1
-rw-r--r--Tests/RunCMake/message/defaultmessage-stderr.txt11
-rw-r--r--Tests/RunCMake/message/defaultmessage.cmake4
-rw-r--r--Tests/RunCMake/message/errormessage_deprecated-result.txt1
-rw-r--r--Tests/RunCMake/message/errormessage_deprecated-stderr.txt4
-rw-r--r--Tests/RunCMake/message/errormessage_deprecated.cmake3
-rw-r--r--Tests/RunCMake/message/errormessage_dev-result.txt1
-rw-r--r--Tests/RunCMake/message/errormessage_dev-stderr.txt5
-rw-r--r--Tests/RunCMake/message/errormessage_dev.cmake3
-rw-r--r--Tests/RunCMake/message/nomessage-result.txt1
-rw-r--r--Tests/RunCMake/message/nomessage.cmake8
-rw-r--r--Tests/RunCMake/message/warnmessage-result.txt1
-rw-r--r--Tests/RunCMake/message/warnmessage-stderr.txt11
-rw-r--r--Tests/RunCMake/message/warnmessage.cmake8
-rw-r--r--Tests/RunCMake/no_install_prefix/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/no_install_prefix/RunCMakeTest.cmake15
-rw-r--r--Tests/RunCMake/no_install_prefix/do_test.cmake2
-rw-r--r--Tests/RunCMake/no_install_prefix/no_install_prefix-result.txt1
-rw-r--r--Tests/RunCMake/no_install_prefix/no_install_prefix-stderr.txt18
-rw-r--r--Tests/RunCMake/no_install_prefix/no_install_prefix.cmake2
-rw-r--r--Tests/RunCMake/no_install_prefix/with_install_prefix-result.txt1
-rw-r--r--Tests/RunCMake/no_install_prefix/with_install_prefix.cmake2
-rw-r--r--Tests/RunCMake/project/CMP0048-NEW-stdout.txt30
-rw-r--r--Tests/RunCMake/project/CMP0048-NEW.cmake19
-rw-r--r--Tests/RunCMake/project/CMP0048-OLD-VERSION-result.txt1
-rw-r--r--Tests/RunCMake/project/CMP0048-OLD-VERSION-stderr.txt4
-rw-r--r--Tests/RunCMake/project/CMP0048-OLD-VERSION.cmake2
-rw-r--r--Tests/RunCMake/project/CMP0048-OLD-stdout.txt2
-rw-r--r--Tests/RunCMake/project/CMP0048-OLD.cmake6
-rw-r--r--Tests/RunCMake/project/CMP0048-WARN-stderr.txt12
-rw-r--r--Tests/RunCMake/project/CMP0048-WARN.cmake3
-rw-r--r--Tests/RunCMake/project/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/project/LanguagesEmpty-stdout.txt1
-rw-r--r--Tests/RunCMake/project/LanguagesEmpty.cmake3
-rw-r--r--Tests/RunCMake/project/LanguagesImplicit-stdout.txt1
-rw-r--r--Tests/RunCMake/project/LanguagesImplicit.cmake3
-rw-r--r--Tests/RunCMake/project/LanguagesNONE-stdout.txt1
-rw-r--r--Tests/RunCMake/project/LanguagesNONE.cmake3
-rw-r--r--Tests/RunCMake/project/LanguagesTwice-result.txt1
-rw-r--r--Tests/RunCMake/project/LanguagesTwice-stderr.txt4
-rw-r--r--Tests/RunCMake/project/LanguagesTwice.cmake2
-rw-r--r--Tests/RunCMake/project/RunCMakeTest.cmake17
-rw-r--r--Tests/RunCMake/project/VersionAndLanguagesEmpty-stdout.txt2
-rw-r--r--Tests/RunCMake/project/VersionAndLanguagesEmpty.cmake5
-rw-r--r--Tests/RunCMake/project/VersionEmpty-stdout.txt2
-rw-r--r--Tests/RunCMake/project/VersionEmpty.cmake6
-rw-r--r--Tests/RunCMake/project/VersionInvalid-result.txt1
-rw-r--r--Tests/RunCMake/project/VersionInvalid-stderr.txt4
-rw-r--r--Tests/RunCMake/project/VersionInvalid.cmake3
-rw-r--r--Tests/RunCMake/project/VersionMissingLanguages-result.txt1
-rw-r--r--Tests/RunCMake/project/VersionMissingLanguages-stderr.txt4
-rw-r--r--Tests/RunCMake/project/VersionMissingLanguages.cmake3
-rw-r--r--Tests/RunCMake/project/VersionMissingValueOkay-stdout.txt2
-rw-r--r--Tests/RunCMake/project/VersionMissingValueOkay.cmake6
-rw-r--r--Tests/RunCMake/project/VersionTwice-result.txt1
-rw-r--r--Tests/RunCMake/project/VersionTwice-stderr.txt4
-rw-r--r--Tests/RunCMake/project/VersionTwice.cmake3
-rw-r--r--Tests/RunCMake/pseudo_emulator.c15
-rw-r--r--Tests/RunCMake/pseudo_iwyu.c7
-rw-r--r--Tests/RunCMake/return/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/return/ReturnFromForeach-result.txt1
-rw-r--r--Tests/RunCMake/return/ReturnFromForeach.cmake10
-rw-r--r--Tests/RunCMake/return/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/set/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/set/ParentPulling-stderr.txt3
-rw-r--r--Tests/RunCMake/set/ParentPulling.cmake13
-rw-r--r--Tests/RunCMake/set/ParentPullingRecursive-stderr.txt144
-rw-r--r--Tests/RunCMake/set/ParentPullingRecursive.cmake104
-rw-r--r--Tests/RunCMake/set/ParentScope-result.txt1
-rw-r--r--Tests/RunCMake/set/ParentScope.cmake33
-rw-r--r--Tests/RunCMake/set/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/set_property/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/set_property/COMPILE_DEFINITIONS-stdout.txt2
-rw-r--r--Tests/RunCMake/set_property/COMPILE_DEFINITIONS.cmake3
-rw-r--r--Tests/RunCMake/set_property/COMPILE_FEATURES-stdout.txt1
-rw-r--r--Tests/RunCMake/set_property/COMPILE_FEATURES.cmake2
-rw-r--r--Tests/RunCMake/set_property/COMPILE_OPTIONS-stdout.txt2
-rw-r--r--Tests/RunCMake/set_property/COMPILE_OPTIONS.cmake3
-rw-r--r--Tests/RunCMake/set_property/Common.cmake28
-rw-r--r--Tests/RunCMake/set_property/INCLUDE_DIRECTORIES-stdout.txt2
-rw-r--r--Tests/RunCMake/set_property/INCLUDE_DIRECTORIES.cmake3
-rw-r--r--Tests/RunCMake/set_property/LINK_LIBRARIES-stdout.txt1
-rw-r--r--Tests/RunCMake/set_property/LINK_LIBRARIES.cmake2
-rw-r--r--Tests/RunCMake/set_property/RunCMakeTest.cmake9
-rw-r--r--Tests/RunCMake/set_property/SOURCES-stdout.txt1
-rw-r--r--Tests/RunCMake/set_property/SOURCES.cmake2
-rw-r--r--Tests/RunCMake/set_property/USER_PROP-stdout.txt2
-rw-r--r--Tests/RunCMake/set_property/USER_PROP.cmake3
-rw-r--r--Tests/RunCMake/string/Append.cmake58
-rw-r--r--Tests/RunCMake/string/AppendNoArgs-result.txt1
-rw-r--r--Tests/RunCMake/string/AppendNoArgs-stderr.txt4
-rw-r--r--Tests/RunCMake/string/AppendNoArgs.cmake1
-rw-r--r--Tests/RunCMake/string/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/string/Concat.cmake19
-rw-r--r--Tests/RunCMake/string/ConcatNoArgs-result.txt1
-rw-r--r--Tests/RunCMake/string/ConcatNoArgs-stderr.txt4
-rw-r--r--Tests/RunCMake/string/ConcatNoArgs.cmake1
-rw-r--r--Tests/RunCMake/string/RegexClear-stderr.txt54
-rw-r--r--Tests/RunCMake/string/RegexClear.cmake54
-rw-r--r--Tests/RunCMake/string/RunCMakeTest.cmake22
-rw-r--r--Tests/RunCMake/string/UTF-16BE-stderr.txt2
-rw-r--r--Tests/RunCMake/string/UTF-16BE.cmake4
-rw-r--r--Tests/RunCMake/string/UTF-16BE.txtbin0 -> 83 bytes
-rw-r--r--Tests/RunCMake/string/UTF-16LE-stderr.txt2
-rw-r--r--Tests/RunCMake/string/UTF-16LE.cmake4
-rw-r--r--Tests/RunCMake/string/UTF-16LE.txtbin0 -> 83 bytes
-rw-r--r--Tests/RunCMake/string/UTF-32BE-stderr.txt2
-rw-r--r--Tests/RunCMake/string/UTF-32BE.cmake4
-rw-r--r--Tests/RunCMake/string/UTF-32BE.txtbin0 -> 165 bytes
-rw-r--r--Tests/RunCMake/string/UTF-32LE-stderr.txt2
-rw-r--r--Tests/RunCMake/string/UTF-32LE.cmake4
-rw-r--r--Tests/RunCMake/string/UTF-32LE.txtbin0 -> 165 bytes
-rw-r--r--Tests/RunCMake/string/Uuid.cmake17
-rw-r--r--Tests/RunCMake/string/UuidBadNamespace-result.txt1
-rw-r--r--Tests/RunCMake/string/UuidBadNamespace-stderr.txt4
-rw-r--r--Tests/RunCMake/string/UuidBadNamespace.cmake4
-rw-r--r--Tests/RunCMake/string/UuidBadType-result.txt1
-rw-r--r--Tests/RunCMake/string/UuidBadType-stderr.txt4
-rw-r--r--Tests/RunCMake/string/UuidBadType.cmake4
-rw-r--r--Tests/RunCMake/string/UuidMissingNameValue-result.txt1
-rw-r--r--Tests/RunCMake/string/UuidMissingNameValue-stderr.txt4
-rw-r--r--Tests/RunCMake/string/UuidMissingNameValue.cmake4
-rw-r--r--Tests/RunCMake/string/UuidMissingNamespace-result.txt1
-rw-r--r--Tests/RunCMake/string/UuidMissingNamespace-stderr.txt4
-rw-r--r--Tests/RunCMake/string/UuidMissingNamespace.cmake4
-rw-r--r--Tests/RunCMake/string/UuidMissingNamespaceValue-result.txt1
-rw-r--r--Tests/RunCMake/string/UuidMissingNamespaceValue-stderr.txt4
-rw-r--r--Tests/RunCMake/string/UuidMissingNamespaceValue.cmake4
-rw-r--r--Tests/RunCMake/string/UuidMissingTypeValue-result.txt1
-rw-r--r--Tests/RunCMake/string/UuidMissingTypeValue-stderr.txt4
-rw-r--r--Tests/RunCMake/string/UuidMissingTypeValue.cmake4
-rw-r--r--Tests/RunCMake/string/cmake/Finddummy.cmake4
-rw-r--r--Tests/RunCMake/string/subdir/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/target_compile_features/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/target_compile_features/RunCMakeTest.cmake13
-rw-r--r--Tests/RunCMake/target_compile_features/alias_target-result.txt1
-rw-r--r--Tests/RunCMake/target_compile_features/alias_target-stderr.txt4
-rw-r--r--Tests/RunCMake/target_compile_features/alias_target.cmake4
-rw-r--r--Tests/RunCMake/target_compile_features/empty.c7
-rw-r--r--Tests/RunCMake/target_compile_features/empty.cpp7
-rw-r--r--Tests/RunCMake/target_compile_features/imported_target-result.txt1
-rw-r--r--Tests/RunCMake/target_compile_features/imported_target-stderr.txt4
-rw-r--r--Tests/RunCMake/target_compile_features/imported_target.cmake3
-rw-r--r--Tests/RunCMake/target_compile_features/invalid_args-result.txt1
-rw-r--r--Tests/RunCMake/target_compile_features/invalid_args-stderr.txt4
-rw-r--r--Tests/RunCMake/target_compile_features/invalid_args.cmake3
-rw-r--r--Tests/RunCMake/target_compile_features/invalid_args_on_interface-result.txt1
-rw-r--r--Tests/RunCMake/target_compile_features/invalid_args_on_interface-stderr.txt5
-rw-r--r--Tests/RunCMake/target_compile_features/invalid_args_on_interface.cmake3
-rw-r--r--Tests/RunCMake/target_compile_features/no_matching_c_feature-result.txt1
-rw-r--r--Tests/RunCMake/target_compile_features/no_matching_c_feature-stderr.txt8
-rw-r--r--Tests/RunCMake/target_compile_features/no_matching_c_feature.cmake15
-rw-r--r--Tests/RunCMake/target_compile_features/no_matching_cxx_feature-result.txt1
-rw-r--r--Tests/RunCMake/target_compile_features/no_matching_cxx_feature-stderr.txt8
-rw-r--r--Tests/RunCMake/target_compile_features/no_matching_cxx_feature.cmake26
-rw-r--r--Tests/RunCMake/target_compile_features/no_target-result.txt1
-rw-r--r--Tests/RunCMake/target_compile_features/no_target-stderr.txt5
-rw-r--r--Tests/RunCMake/target_compile_features/no_target.cmake2
-rw-r--r--Tests/RunCMake/target_compile_features/not_a_c_feature-result.txt1
-rw-r--r--Tests/RunCMake/target_compile_features/not_a_c_feature-stderr.txt5
-rw-r--r--Tests/RunCMake/target_compile_features/not_a_c_feature.cmake6
-rw-r--r--Tests/RunCMake/target_compile_features/not_a_cxx_feature-result.txt1
-rw-r--r--Tests/RunCMake/target_compile_features/not_a_cxx_feature-stderr.txt5
-rw-r--r--Tests/RunCMake/target_compile_features/not_a_cxx_feature.cmake6
-rw-r--r--Tests/RunCMake/target_compile_features/not_enough_args-result.txt1
-rw-r--r--Tests/RunCMake/target_compile_features/not_enough_args-stderr.txt4
-rw-r--r--Tests/RunCMake/target_compile_features/not_enough_args.cmake3
-rw-r--r--Tests/RunCMake/target_compile_features/utility_target-result.txt1
-rw-r--r--Tests/RunCMake/target_compile_features/utility_target-stderr.txt4
-rw-r--r--Tests/RunCMake/target_compile_features/utility_target.cmake4
-rw-r--r--Tests/RunCMake/target_link_libraries/CMP0023-NEW-2-stderr.txt5
-rw-r--r--Tests/RunCMake/target_link_libraries/CMP0023-NEW-stderr.txt5
-rw-r--r--Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/target_link_libraries/SharedDepNotTarget.cmake10
-rw-r--r--Tests/RunCMake/target_link_libraries/StaticPrivateDepNotExported-result.txt1
-rw-r--r--Tests/RunCMake/target_link_libraries/StaticPrivateDepNotExported-stderr.txt1
-rw-r--r--Tests/RunCMake/target_link_libraries/StaticPrivateDepNotExported.cmake7
-rw-r--r--Tests/RunCMake/target_link_libraries/StaticPrivateDepNotTarget.cmake6
-rw-r--r--Tests/RunCMake/target_link_libraries/SubDirTarget-result.txt1
-rw-r--r--Tests/RunCMake/target_link_libraries/SubDirTarget-stderr.txt5
-rw-r--r--Tests/RunCMake/target_link_libraries/SubDirTarget.cmake3
-rw-r--r--Tests/RunCMake/target_link_libraries/SubDirTarget/CMakeLists.txt1
-rw-r--r--Tests/RunCMake/target_link_libraries/empty.c0
-rw-r--r--Tests/RunCMake/try_compile/BadLinkLibraries-stderr.txt4
-rw-r--r--Tests/RunCMake/try_compile/CMP0056-stderr.txt13
-rw-r--r--Tests/RunCMake/try_compile/CMP0056-stdout.txt4
-rw-r--r--Tests/RunCMake/try_compile/CMP0056.cmake67
-rw-r--r--Tests/RunCMake/try_compile/RerunCMake-nowork-ninja-no-console-stdout.txt1
-rw-r--r--Tests/RunCMake/try_compile/RerunCMake-rerun-ninja-no-console-stdout.txt5
-rw-r--r--Tests/RunCMake/try_compile/RerunCMake-rerun-stderr.txt2
-rw-r--r--Tests/RunCMake/try_compile/RerunCMake-rerun-stdout.txt3
-rw-r--r--Tests/RunCMake/try_compile/RerunCMake-stderr.txt2
-rw-r--r--Tests/RunCMake/try_compile/RerunCMake-stdout.txt3
-rw-r--r--Tests/RunCMake/try_compile/RerunCMake.cmake7
-rw-r--r--Tests/RunCMake/try_compile/RunCMakeTest.cmake35
-rw-r--r--Tests/RunCMake/try_run/BadLinkLibraries-result.txt1
-rw-r--r--Tests/RunCMake/try_run/BadLinkLibraries-stderr.txt5
-rw-r--r--Tests/RunCMake/try_run/BadLinkLibraries.cmake4
-rw-r--r--Tests/RunCMake/try_run/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/try_run/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/try_run/src.c1
-rw-r--r--Tests/RunCMake/while/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/while/EndAlone-result.txt1
-rw-r--r--Tests/RunCMake/while/EndAlone-stderr.txt5
-rw-r--r--Tests/RunCMake/while/EndAlone.cmake (renamed from Tests/CMakeTests/While-Endwhile-Alone.cmake)0
-rw-r--r--Tests/RunCMake/while/EndAloneArgs-result.txt1
-rw-r--r--Tests/RunCMake/while/EndAloneArgs-stderr.txt5
-rw-r--r--Tests/RunCMake/while/EndAloneArgs.cmake (renamed from Tests/CMakeTests/While-Endwhile-Alone-Args.cmake)0
-rw-r--r--Tests/RunCMake/while/EndMismatch-stderr.txt13
-rw-r--r--Tests/RunCMake/while/EndMismatch.cmake (renamed from Tests/CMakeTests/While-Endwhile-Mismatch.cmake)0
-rw-r--r--Tests/RunCMake/while/EndMissing-result.txt1
-rw-r--r--Tests/RunCMake/while/EndMissing-stderr.txt6
-rw-r--r--Tests/RunCMake/while/EndMissing.cmake (renamed from Tests/CMakeTests/While-Missing-Endwhile.cmake)0
-rw-r--r--Tests/RunCMake/while/MissingArgument-result.txt1
-rw-r--r--Tests/RunCMake/while/MissingArgument-stderr.txt4
-rw-r--r--Tests/RunCMake/while/MissingArgument.cmake (renamed from Tests/CMakeTests/While-Missing-Argument.cmake)0
-rw-r--r--Tests/RunCMake/while/RunCMakeTest.cmake7
-rw-r--r--Tests/SimpleInstall/CMakeLists.txt35
-rw-r--r--Tests/SimpleInstallS2/CMakeLists.txt35
-rw-r--r--Tests/SourceFileProperty/CMakeLists.txt19
-rw-r--r--Tests/SourceFileProperty/ICaseTest.c7
-rw-r--r--Tests/SourceFileProperty/main.c13
-rw-r--r--Tests/SourcesProperty/CMakeLists.txt14
-rw-r--r--Tests/SourcesProperty/iface.cpp5
-rw-r--r--Tests/SourcesProperty/iface.h4
-rw-r--r--Tests/SourcesProperty/main.cpp7
-rw-r--r--Tests/SourcesProperty/prop.cpp5
-rw-r--r--Tests/StagingPrefix/CMakeLists.txt91
-rw-r--r--Tests/StagingPrefix/Consumer/CMakeLists.txt22
-rw-r--r--Tests/StagingPrefix/Consumer/cmake/FindBar.cmake6
-rw-r--r--Tests/StagingPrefix/Consumer/main.cpp10
-rw-r--r--Tests/StagingPrefix/Producer/CMakeLists.txt26
-rw-r--r--Tests/StagingPrefix/Producer/bar.cpp7
-rw-r--r--Tests/StagingPrefix/Producer/bar.h10
-rw-r--r--Tests/StagingPrefix/Producer/foo.cpp7
-rw-r--r--Tests/StagingPrefix/Producer/foo.h10
-rw-r--r--Tests/StagingPrefix/main.cpp5
-rw-r--r--Tests/StringFileTest/CMakeLists.txt33
-rw-r--r--Tests/StringFileTest/test.utf83
-rw-r--r--Tests/SubDir/CMakeLists.txt4
-rw-r--r--Tests/SubDir/Executable/CMakeLists.txt12
-rw-r--r--Tests/SubDirSpaces/CMakeLists.txt2
-rw-r--r--Tests/SubProject/CMakeLists.txt11
-rw-r--r--Tests/SubProject/bar.cxx5
-rw-r--r--Tests/SubProject/gen.cxx.in4
-rw-r--r--Tests/SwiftMix/CMain.c4
-rw-r--r--Tests/SwiftMix/CMakeLists.txt5
-rw-r--r--Tests/SwiftMix/ObjC-Swift.h0
-rw-r--r--Tests/SwiftMix/ObjCMain.m4
-rw-r--r--Tests/SwiftMix/SwiftMain.swift12
-rw-r--r--Tests/SwiftOnly/CMakeLists.txt4
-rw-r--r--Tests/SwiftOnly/main.swift1
-rw-r--r--Tests/SystemInformation/CMakeLists.txt4
-rw-r--r--Tests/SystemInformation/SystemInformation.in18
-rw-r--r--Tests/TarTest/CMakeLists.txt69
-rw-r--r--Tests/TarTest/TestTarExec.cxx5
-rwxr-xr-xTests/TestInstall.sh.in63
-rw-r--r--Tests/TryCompile/CMakeLists.txt4
-rw-r--r--Tests/Tutorial/Step2/tutorial.cxx8
-rw-r--r--Tests/Tutorial/Step3/tutorial.cxx8
-rw-r--r--Tests/Tutorial/Step4/tutorial.cxx8
-rw-r--r--Tests/Tutorial/Step5/tutorial.cxx8
-rw-r--r--Tests/Tutorial/Step6/MathFunctions/CMakeLists.txt4
-rw-r--r--Tests/Tutorial/Step6/tutorial.cxx8
-rw-r--r--Tests/Tutorial/Step7/MathFunctions/CMakeLists.txt4
-rw-r--r--Tests/Tutorial/Step7/tutorial.cxx8
-rw-r--r--Tests/Unset/CMakeLists.txt27
-rw-r--r--Tests/VSExcludeFromDefaultBuild/CMakeLists.txt4
-rw-r--r--Tests/VSExcludeFromDefaultBuild/ClearExes.cmake4
-rw-r--r--Tests/VSExcludeFromDefaultBuild/ResultTest.cmake6
-rw-r--r--Tests/VSExternalInclude/CMakeLists.txt12
-rw-r--r--Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt6
-rw-r--r--Tests/VSMASM/CMakeLists.txt10
-rw-r--r--Tests/VSMASM/foo.asm7
-rw-r--r--Tests/VSMASM/include/foo-proc.asm4
-rw-r--r--Tests/VSMASM/main.c2
-rw-r--r--Tests/VSNsightTegra/AndroidManifest.xml16
-rw-r--r--Tests/VSNsightTegra/CMakeLists.txt57
-rw-r--r--Tests/VSNsightTegra/build.xml4
-rw-r--r--Tests/VSNsightTegra/jni/first.c22
-rw-r--r--Tests/VSNsightTegra/jni/first.h22
-rw-r--r--Tests/VSNsightTegra/jni/second.c27
-rw-r--r--Tests/VSNsightTegra/proguard-android.txt57
-rw-r--r--Tests/VSNsightTegra/res/values/strings.xml4
-rw-r--r--Tests/VSNsightTegra/src/com/example/twolibs/TwoLibs.java46
-rw-r--r--Tests/VSResource/CMakeLists.txt17
-rw-r--r--Tests/VSResource/include.rc.in1
-rw-r--r--Tests/VSResource/lib.cpp1
-rw-r--r--Tests/VSResource/lib.rc4
-rw-r--r--Tests/VSResource/main.cpp4
-rw-r--r--Tests/VSResource/test.rc3
-rw-r--r--Tests/VSWinStorePhone/CMakeLists.txt140
-rw-r--r--Tests/VSWinStorePhone/Direct3DApp1/Assets/ApplicationIcon.pngbin0 -> 3392 bytes
-rw-r--r--Tests/VSWinStorePhone/Direct3DApp1/Assets/Logo.pngbin0 -> 801 bytes
-rw-r--r--Tests/VSWinStorePhone/Direct3DApp1/Assets/SmallLogo.pngbin0 -> 329 bytes
-rw-r--r--Tests/VSWinStorePhone/Direct3DApp1/Assets/SmallLogo44x44.pngbin0 -> 554 bytes
-rw-r--r--Tests/VSWinStorePhone/Direct3DApp1/Assets/SplashScreen.pngbin0 -> 2146 bytes
-rw-r--r--Tests/VSWinStorePhone/Direct3DApp1/Assets/StoreLogo.pngbin0 -> 429 bytes
-rw-r--r--Tests/VSWinStorePhone/Direct3DApp1/Assets/Tiles/FlipCycleTileLarge.pngbin0 -> 9930 bytes
-rw-r--r--Tests/VSWinStorePhone/Direct3DApp1/Assets/Tiles/FlipCycleTileMedium.pngbin0 -> 9070 bytes
-rw-r--r--Tests/VSWinStorePhone/Direct3DApp1/Assets/Tiles/FlipCycleTileSmall.pngbin0 -> 3674 bytes
-rw-r--r--Tests/VSWinStorePhone/Direct3DApp1/Assets/Tiles/IconicTileMediumLarge.pngbin0 -> 4937 bytes
-rw-r--r--Tests/VSWinStorePhone/Direct3DApp1/Assets/Tiles/IconicTileSmall.pngbin0 -> 3724 bytes
-rw-r--r--Tests/VSWinStorePhone/Direct3DApp1/BasicTimer.h76
-rw-r--r--Tests/VSWinStorePhone/Direct3DApp1/CubeRenderer.cpp260
-rw-r--r--Tests/VSWinStorePhone/Direct3DApp1/CubeRenderer.h44
-rw-r--r--Tests/VSWinStorePhone/Direct3DApp1/Direct3DApp1.cpp153
-rw-r--r--Tests/VSWinStorePhone/Direct3DApp1/Direct3DApp1.h40
-rw-r--r--Tests/VSWinStorePhone/Direct3DApp1/Direct3DApp1_TemporaryKey.pfxbin0 -> 2560 bytes
-rw-r--r--Tests/VSWinStorePhone/Direct3DApp1/Direct3DBase.cpp384
-rw-r--r--Tests/VSWinStorePhone/Direct3DApp1/Direct3DBase.h39
-rw-r--r--Tests/VSWinStorePhone/Direct3DApp1/DirectXHelper.h45
-rw-r--r--Tests/VSWinStorePhone/Direct3DApp1/SimplePixelShader.csobin0 -> 12796 bytes
-rw-r--r--Tests/VSWinStorePhone/Direct3DApp1/SimplePixelShader.hlsl14
-rw-r--r--Tests/VSWinStorePhone/Direct3DApp1/SimpleVertexShader.csobin0 -> 16336 bytes
-rw-r--r--Tests/VSWinStorePhone/Direct3DApp1/SimpleVertexShader.hlsl39
-rw-r--r--Tests/VSWinStorePhone/Direct3DApp1/pch.cpp1
-rw-r--r--Tests/VSWinStorePhone/Direct3DApp1/pch.h7
-rw-r--r--Tests/VSWinStorePhone/cmake/Package_vc11.store.appxmanifest.in24
-rw-r--r--Tests/VSWinStorePhone/cmake/Package_vc11.wp.appxmanifest.in35
-rw-r--r--Tests/VSWinStorePhone/cmake/Package_vc12.store.appxmanifest.in34
-rw-r--r--Tests/VSWinStorePhone/cmake/Package_vc12.wp.appxmanifest.in36
-rw-r--r--Tests/VSWinStorePhone/cmake/Package_vc14.store.appxmanifest.in36
-rw-r--r--Tests/VSWindowsFormsResx/CMakeLists.txt2
-rw-r--r--Tests/VSXaml/App.xaml7
-rw-r--r--Tests/VSXaml/App.xaml.cpp125
-rw-r--r--Tests/VSXaml/App.xaml.h27
-rw-r--r--Tests/VSXaml/Assets/Logo.scale-100.pngbin0 -> 801 bytes
-rw-r--r--Tests/VSXaml/Assets/SmallLogo.scale-100.pngbin0 -> 329 bytes
-rw-r--r--Tests/VSXaml/Assets/SplashScreen.scale-100.pngbin0 -> 2146 bytes
-rw-r--r--Tests/VSXaml/Assets/StoreLogo.scale-100.pngbin0 -> 429 bytes
-rw-r--r--Tests/VSXaml/CMakeLists.txt52
-rw-r--r--Tests/VSXaml/MainPage.xaml14
-rw-r--r--Tests/VSXaml/MainPage.xaml.cpp27
-rw-r--r--Tests/VSXaml/MainPage.xaml.h21
-rw-r--r--Tests/VSXaml/Package.appxmanifest41
-rw-r--r--Tests/VSXaml/VSXaml_TemporaryKey.pfxbin0 -> 2560 bytes
-rw-r--r--Tests/VSXaml/pch.cpp6
-rw-r--r--Tests/VSXaml/pch.h11
-rw-r--r--Tests/Visibility/CMakeLists.txt66
-rw-r--r--Tests/Visibility/bar.c1
-rw-r--r--Tests/Visibility/foo.cpp11
-rw-r--r--Tests/Visibility/hidden.c4
-rw-r--r--Tests/Visibility/shared.c3
-rw-r--r--Tests/Visibility/shared.cpp8
-rw-r--r--Tests/Visibility/verify.cmake14
-rw-r--r--Tests/Wrapping/CMakeLists.txt17
-rw-r--r--Tests/Wrapping/fltk2.fl0
-rw-r--r--Tests/Wrapping/wrapFLTK.c1
-rw-r--r--Tests/XCTest/CMakeLists.txt57
-rw-r--r--Tests/XCTest/CocoaExample/AppDelegate.h6
-rw-r--r--Tests/XCTest/CocoaExample/AppDelegate.m18
-rw-r--r--Tests/XCTest/CocoaExample/Info.plist30
-rw-r--r--Tests/XCTest/CocoaExample/MainMenu.xib680
-rw-r--r--Tests/XCTest/CocoaExample/main.m5
-rw-r--r--Tests/XCTest/CocoaExampleTests/CocoaExampleTests.m13
-rw-r--r--Tests/XCTest/FrameworkExample/FrameworkExample.c6
-rw-r--r--Tests/XCTest/FrameworkExample/FrameworkExample.h1
-rw-r--r--Tests/XCTest/FrameworkExample/Info.plist28
-rw-r--r--Tests/XCTest/FrameworkExampleTests/FrameworkExampleTests.m16
-rw-r--r--Tests/XCTest/FrameworkExampleTests/Info.plist24
-rw-r--r--Tests/iOSNavApp/CMakeLists.txt1
-rw-r--r--Utilities/CMakeLists.txt172
-rwxr-xr-xUtilities/Doxygen/doc_makeall.sh.in26
-rw-r--r--Utilities/Doxygen/doxyfile.in5
-rw-r--r--Utilities/KWIML/.gitattributes1
-rw-r--r--Utilities/KWIML/ABI.h.in492
-rw-r--r--Utilities/KWIML/CMakeLists.txt145
-rw-r--r--Utilities/KWIML/Copyright.txt2
-rw-r--r--Utilities/KWIML/INT.h.in861
-rw-r--r--Utilities/KWIML/README.md36
-rw-r--r--Utilities/KWIML/README.txt29
-rw-r--r--Utilities/KWIML/include/kwiml/abi.h562
-rw-r--r--Utilities/KWIML/include/kwiml/int.h1069
-rw-r--r--Utilities/KWIML/src/kwiml-config.cmake.in1
-rw-r--r--Utilities/KWIML/src/version.h.in59
-rw-r--r--Utilities/KWIML/test/CMakeLists.txt50
-rw-r--r--Utilities/KWIML/test/test.c32
-rw-r--r--Utilities/KWIML/test/test.cxx16
-rw-r--r--Utilities/KWIML/test/test.h31
-rw-r--r--Utilities/KWIML/test/test_ABI_C.c22
-rw-r--r--Utilities/KWIML/test/test_ABI_CXX.cxx22
-rw-r--r--Utilities/KWIML/test/test_ABI_endian.h.in47
-rw-r--r--Utilities/KWIML/test/test_INT_C.c22
-rw-r--r--Utilities/KWIML/test/test_INT_CXX.cxx22
-rw-r--r--Utilities/KWIML/test/test_INT_format.h.in200
-rw-r--r--Utilities/KWIML/test/test_abi_C.c19
-rw-r--r--Utilities/KWIML/test/test_abi_CXX.cxx19
-rw-r--r--Utilities/KWIML/test/test_abi_endian.h41
-rw-r--r--Utilities/KWIML/test/test_include_C.c20
-rw-r--r--Utilities/KWIML/test/test_include_CXX.cxx20
-rw-r--r--Utilities/KWIML/test/test_int_C.c19
-rw-r--r--Utilities/KWIML/test/test_int_CXX.cxx19
-rw-r--r--Utilities/KWIML/test/test_int_format.h203
-rw-r--r--Utilities/Release/Cygwin/CMakeLists.txt4
-rw-r--r--Utilities/Release/Cygwin/README.cygwin.in2
-rw-r--r--Utilities/Release/WiX/CMakeLists.txt12
-rw-r--r--Utilities/Release/WiX/CustomAction/CMakeLists.txt13
-rw-r--r--Utilities/Release/WiX/CustomAction/detect_nsis_overwrite.cpp45
-rw-r--r--Utilities/Release/WiX/CustomAction/exports.def2
-rw-r--r--Utilities/Release/WiX/WIX.template.in46
-rw-r--r--Utilities/Release/WiX/cmake_extra_dialog.wxs36
-rw-r--r--Utilities/Release/WiX/cmake_nsis_overwrite_dialog.wxs21
-rw-r--r--Utilities/Release/WiX/custom_action_dll.wxs.in6
-rw-r--r--Utilities/Release/WiX/install_dir.wxs72
-rw-r--r--Utilities/Release/WiX/patch_desktop_shortcut.xml5
-rw-r--r--Utilities/Release/WiX/patch_path_env.xml26
-rw-r--r--Utilities/Release/WiX/ui_banner.jpgbin0 -> 2607 bytes
-rw-r--r--Utilities/Release/WiX/ui_dialog.jpgbin0 -> 13369 bytes
-rw-r--r--Utilities/Release/create-cmake-release.cmake54
-rw-r--r--Utilities/Release/dash2win64_cygwin.cmake8
-rw-r--r--Utilities/Release/dash2win64_release.cmake20
-rw-r--r--Utilities/Release/dash3win7_release.cmake28
-rw-r--r--Utilities/Release/dashmacmini2_release.cmake22
-rw-r--r--Utilities/Release/dashmacmini5_release.cmake23
-rw-r--r--Utilities/Release/ferrari_sgi64_release.cmake16
-rw-r--r--Utilities/Release/ferrari_sgi_release.cmake11
-rw-r--r--Utilities/Release/linux64_release.cmake25
-rw-r--r--Utilities/Release/magrathea_release.cmake9
-rw-r--r--Utilities/Release/release_cmake.cmake54
-rwxr-xr-xUtilities/Release/release_cmake.sh.in30
-rw-r--r--Utilities/Release/upload_release.cmake15
-rw-r--r--Utilities/Release/v20n250_aix_release.cmake22
-rw-r--r--Utilities/Scripts/BoostScanDeps.cmake217
-rwxr-xr-xUtilities/Scripts/update-kwiml.bash20
-rwxr-xr-xUtilities/Scripts/update-kwsys.bash22
-rw-r--r--Utilities/Scripts/update-third-party.bash146
-rw-r--r--Utilities/Sphinx/.gitignore1
-rw-r--r--Utilities/Sphinx/CMakeLists.txt198
-rw-r--r--Utilities/Sphinx/apply_qthelp_css_workaround.cmake15
-rw-r--r--Utilities/Sphinx/cmake.py392
-rw-r--r--Utilities/Sphinx/conf.py.in69
-rwxr-xr-xUtilities/Sphinx/create_identifiers.py46
-rw-r--r--Utilities/Sphinx/fixup_qthelp_names.cmake32
-rw-r--r--Utilities/Sphinx/static/cmake-favicon.icobin0 -> 1150 bytes
-rw-r--r--Utilities/Sphinx/static/cmake-logo-16.pngbin0 -> 761 bytes
-rw-r--r--Utilities/Sphinx/static/cmake.css8
-rw-r--r--Utilities/Sphinx/templates/layout.html19
-rw-r--r--Utilities/cmThirdParty.h.in8
-rw-r--r--Utilities/cm_bzlib.h4
-rw-r--r--Utilities/cm_curl.h6
-rw-r--r--Utilities/cm_expat.h4
-rw-r--r--Utilities/cm_jsoncpp_reader.h23
-rw-r--r--Utilities/cm_jsoncpp_value.h23
-rw-r--r--Utilities/cm_jsoncpp_writer.h23
-rw-r--r--Utilities/cm_kwiml.h25
-rw-r--r--Utilities/cm_libarchive.h4
-rw-r--r--Utilities/cm_lzma.h23
-rw-r--r--Utilities/cm_xmlrpc.h4
-rw-r--r--Utilities/cm_zlib.h4
-rw-r--r--Utilities/cmbzip2/compress.c2
-rw-r--r--Utilities/cmcompress/cmcompress.h6
-rw-r--r--Utilities/cmcurl/.gitattributes (renamed from Utilities/xml/.gitattributes)0
-rw-r--r--Utilities/cmcurl/CMake/CurlCheckCSourceCompiles.cmake75
-rw-r--r--Utilities/cmcurl/CMake/CurlCheckCSourceRuns.cmake83
-rw-r--r--Utilities/cmcurl/CMake/CurlTests.c565
-rw-r--r--Utilities/cmcurl/CMake/FindCARES.cmake42
-rw-r--r--Utilities/cmcurl/CMake/FindGSS.cmake289
-rw-r--r--Utilities/cmcurl/CMake/FindLibSSH2.cmake35
-rw-r--r--Utilities/cmcurl/CMake/Macros.cmake95
-rw-r--r--Utilities/cmcurl/CMake/OtherTests.cmake409
-rw-r--r--Utilities/cmcurl/CMake/Platforms/WindowsCache.cmake122
-rw-r--r--Utilities/cmcurl/CMake/Utilities.cmake31
-rw-r--r--Utilities/cmcurl/CMakeLists.txt1819
-rw-r--r--Utilities/cmcurl/COPYING2
-rw-r--r--Utilities/cmcurl/Platforms/WindowsCache.cmake120
-rw-r--r--Utilities/cmcurl/Platforms/config-aix.h483
-rw-r--r--Utilities/cmcurl/README-CMake.txt66
-rw-r--r--Utilities/cmcurl/Testing/CMakeLists.txt19
-rw-r--r--Utilities/cmcurl/Testing/curlgtk.c95
-rw-r--r--Utilities/cmcurl/Testing/ftpget.c84
-rw-r--r--Utilities/cmcurl/Testing/ftpgetresp.c64
-rw-r--r--Utilities/cmcurl/Testing/ftpupload.c93
-rw-r--r--Utilities/cmcurl/Testing/getinmemory.c83
-rw-r--r--Utilities/cmcurl/Testing/http-post.c35
-rw-r--r--Utilities/cmcurl/Testing/httpput.c100
-rw-r--r--Utilities/cmcurl/Testing/multithread.c70
-rw-r--r--Utilities/cmcurl/Testing/persistant.c53
-rw-r--r--Utilities/cmcurl/Testing/postit2.c92
-rw-r--r--Utilities/cmcurl/Testing/sepheaders.c80
-rw-r--r--Utilities/cmcurl/Testing/simple.c28
-rw-r--r--Utilities/cmcurl/Testing/simplessl.c120
-rw-r--r--Utilities/cmcurl/Testing/testconfig.h.in7
-rw-r--r--Utilities/cmcurl/Testing/win32sockets.c49
-rw-r--r--Utilities/cmcurl/amigaos.c74
-rw-r--r--Utilities/cmcurl/amigaos.h58
-rw-r--r--Utilities/cmcurl/arpa_telnet.h101
-rw-r--r--Utilities/cmcurl/base64.c366
-rw-r--r--Utilities/cmcurl/base64.h28
-rw-r--r--Utilities/cmcurl/ca-bundle.h1
-rw-r--r--Utilities/cmcurl/config.h.in720
-rw-r--r--Utilities/cmcurl/connect.c905
-rw-r--r--Utilities/cmcurl/connect.h46
-rw-r--r--Utilities/cmcurl/content_encoding.c424
-rw-r--r--Utilities/cmcurl/content_encoding.h41
-rw-r--r--Utilities/cmcurl/cookie.c1019
-rw-r--r--Utilities/cmcurl/cookie.h107
-rw-r--r--Utilities/cmcurl/curl/curl.h1644
-rw-r--r--Utilities/cmcurl/curl/curlver.h56
-rw-r--r--Utilities/cmcurl/curl/easy.h81
-rw-r--r--Utilities/cmcurl/curl/mprintf.h80
-rw-r--r--Utilities/cmcurl/curl/multi.h327
-rw-r--r--Utilities/cmcurl/curl/stdcheaders.h34
-rw-r--r--Utilities/cmcurl/curl/types.h1
-rw-r--r--Utilities/cmcurl/curltest.c (renamed from Utilities/cmcurl/Testing/curltest.c)0
-rw-r--r--Utilities/cmcurl/curlx.h107
-rw-r--r--Utilities/cmcurl/dict.c280
-rw-r--r--Utilities/cmcurl/dict.h30
-rw-r--r--Utilities/cmcurl/easy.c895
-rw-r--r--Utilities/cmcurl/easyif.h40
-rw-r--r--Utilities/cmcurl/escape.c181
-rw-r--r--Utilities/cmcurl/escape.h30
-rw-r--r--Utilities/cmcurl/file.c407
-rw-r--r--Utilities/cmcurl/file.h31
-rw-r--r--Utilities/cmcurl/formdata.c1694
-rw-r--r--Utilities/cmcurl/formdata.h97
-rw-r--r--Utilities/cmcurl/ftp.c3865
-rw-r--r--Utilities/cmcurl/ftp.h43
-rw-r--r--Utilities/cmcurl/getenv.c69
-rw-r--r--Utilities/cmcurl/getinfo.c234
-rw-r--r--Utilities/cmcurl/getinfo.h28
-rw-r--r--Utilities/cmcurl/gtls.c640
-rw-r--r--Utilities/cmcurl/gtls.h46
-rw-r--r--Utilities/cmcurl/hash.c315
-rw-r--r--Utilities/cmcurl/hash.h61
-rw-r--r--Utilities/cmcurl/hostares.c307
-rw-r--r--Utilities/cmcurl/hostasyn.c174
-rw-r--r--Utilities/cmcurl/hostip.c636
-rw-r--r--Utilities/cmcurl/hostip.h271
-rw-r--r--Utilities/cmcurl/hostip4.c389
-rw-r--r--Utilities/cmcurl/hostip6.c306
-rw-r--r--Utilities/cmcurl/hostsyn.c138
-rw-r--r--Utilities/cmcurl/hostthre.c840
-rw-r--r--Utilities/cmcurl/http.c2422
-rw-r--r--Utilities/cmcurl/http.h85
-rw-r--r--Utilities/cmcurl/http_chunks.c360
-rw-r--r--Utilities/cmcurl/http_chunks.h104
-rw-r--r--Utilities/cmcurl/http_digest.c504
-rw-r--r--Utilities/cmcurl/http_digest.h58
-rw-r--r--Utilities/cmcurl/http_negotiate.c327
-rw-r--r--Utilities/cmcurl/http_negotiate.h39
-rw-r--r--Utilities/cmcurl/http_ntlm.c1111
-rw-r--r--Utilities/cmcurl/http_ntlm.h146
-rw-r--r--Utilities/cmcurl/if2ip.c134
-rw-r--r--Utilities/cmcurl/if2ip.h67
-rw-r--r--Utilities/cmcurl/include/curl/curl.h2382
-rw-r--r--Utilities/cmcurl/include/curl/curlbuild.h.cmake218
-rw-r--r--Utilities/cmcurl/include/curl/curlrules.h262
-rw-r--r--Utilities/cmcurl/include/curl/curlver.h77
-rw-r--r--Utilities/cmcurl/include/curl/easy.h102
-rw-r--r--Utilities/cmcurl/include/curl/mprintf.h74
-rw-r--r--Utilities/cmcurl/include/curl/multi.h435
-rw-r--r--Utilities/cmcurl/include/curl/stdcheaders.h33
-rw-r--r--Utilities/cmcurl/include/curl/typecheck-gcc.h612
-rw-r--r--Utilities/cmcurl/inet_ntoa_r.h44
-rw-r--r--Utilities/cmcurl/inet_ntop.c224
-rw-r--r--Utilities/cmcurl/inet_ntop.h37
-rw-r--r--Utilities/cmcurl/inet_pton.c241
-rw-r--r--Utilities/cmcurl/inet_pton.h42
-rw-r--r--Utilities/cmcurl/krb4.c425
-rw-r--r--Utilities/cmcurl/krb4.h70
-rw-r--r--Utilities/cmcurl/ldap.c702
-rw-r--r--Utilities/cmcurl/ldap.h29
-rw-r--r--Utilities/cmcurl/lib/CMakeLists.txt129
-rw-r--r--Utilities/cmcurl/lib/Makefile.inc73
-rw-r--r--Utilities/cmcurl/lib/amigaos.c77
-rw-r--r--Utilities/cmcurl/lib/amigaos.h39
-rw-r--r--Utilities/cmcurl/lib/arpa_telnet.h104
-rw-r--r--Utilities/cmcurl/lib/asyn-ares.c691
-rw-r--r--Utilities/cmcurl/lib/asyn-thread.c698
-rw-r--r--Utilities/cmcurl/lib/asyn.h168
-rw-r--r--Utilities/cmcurl/lib/base64.c309
-rw-r--r--Utilities/cmcurl/lib/conncache.c364
-rw-r--r--Utilities/cmcurl/lib/conncache.h68
-rw-r--r--Utilities/cmcurl/lib/connect.c1383
-rw-r--r--Utilities/cmcurl/lib/connect.h122
-rw-r--r--Utilities/cmcurl/lib/content_encoding.c435
-rw-r--r--Utilities/cmcurl/lib/content_encoding.h48
-rw-r--r--Utilities/cmcurl/lib/cookie.c1363
-rw-r--r--Utilities/cmcurl/lib/cookie.h104
-rw-r--r--Utilities/cmcurl/lib/curl_addrinfo.c558
-rw-r--r--Utilities/cmcurl/lib/curl_addrinfo.h101
-rw-r--r--Utilities/cmcurl/lib/curl_base64.h35
-rw-r--r--Utilities/cmcurl/lib/curl_config.h.cmake961
-rw-r--r--Utilities/cmcurl/lib/curl_des.c63
-rw-r--r--Utilities/cmcurl/lib/curl_des.h34
-rw-r--r--Utilities/cmcurl/lib/curl_endian.c236
-rw-r--r--Utilities/cmcurl/lib/curl_endian.h70
-rw-r--r--Utilities/cmcurl/lib/curl_fnmatch.c424
-rw-r--r--Utilities/cmcurl/lib/curl_fnmatch.h44
-rw-r--r--Utilities/cmcurl/lib/curl_gethostname.c100
-rw-r--r--Utilities/cmcurl/lib/curl_gethostname.h31
-rw-r--r--Utilities/cmcurl/lib/curl_gssapi.c120
-rw-r--r--Utilities/cmcurl/lib/curl_gssapi.h75
-rw-r--r--Utilities/cmcurl/lib/curl_hmac.h67
-rw-r--r--Utilities/cmcurl/lib/curl_ldap.h35
-rw-r--r--Utilities/cmcurl/lib/curl_md4.h35
-rw-r--r--Utilities/cmcurl/lib/curl_md5.h63
-rw-r--r--Utilities/cmcurl/lib/curl_memory.h143
-rw-r--r--Utilities/cmcurl/lib/curl_memrchr.c58
-rw-r--r--Utilities/cmcurl/lib/curl_memrchr.h44
-rw-r--r--Utilities/cmcurl/lib/curl_multibyte.c82
-rw-r--r--Utilities/cmcurl/lib/curl_multibyte.h92
-rw-r--r--Utilities/cmcurl/lib/curl_ntlm.c239
-rw-r--r--Utilities/cmcurl/lib/curl_ntlm.h40
-rw-r--r--Utilities/cmcurl/lib/curl_ntlm_core.c765
-rw-r--r--Utilities/cmcurl/lib/curl_ntlm_core.h106
-rw-r--r--Utilities/cmcurl/lib/curl_ntlm_msgs.c817
-rw-r--r--Utilities/cmcurl/lib/curl_ntlm_msgs.h143
-rw-r--r--Utilities/cmcurl/lib/curl_ntlm_wb.c431
-rw-r--r--Utilities/cmcurl/lib/curl_ntlm_wb.h38
-rw-r--r--Utilities/cmcurl/lib/curl_printf.h56
-rw-r--r--Utilities/cmcurl/lib/curl_rtmp.c306
-rw-r--r--Utilities/cmcurl/lib/curl_rtmp.h33
-rw-r--r--Utilities/cmcurl/lib/curl_sasl.c1669
-rw-r--r--Utilities/cmcurl/lib/curl_sasl.h254
-rw-r--r--Utilities/cmcurl/lib/curl_sasl_gssapi.c392
-rw-r--r--Utilities/cmcurl/lib/curl_sasl_sspi.c1281
-rw-r--r--Utilities/cmcurl/lib/curl_sec.h51
-rw-r--r--Utilities/cmcurl/lib/curl_setup.h745
-rw-r--r--Utilities/cmcurl/lib/curl_setup_once.h551
-rw-r--r--Utilities/cmcurl/lib/curl_sspi.c257
-rw-r--r--Utilities/cmcurl/lib/curl_sspi.h346
-rw-r--r--Utilities/cmcurl/lib/curl_threads.c136
-rw-r--r--Utilities/cmcurl/lib/curl_threads.h62
-rw-r--r--Utilities/cmcurl/lib/curlx.h118
-rw-r--r--Utilities/cmcurl/lib/dict.c279
-rw-r--r--Utilities/cmcurl/lib/dict.h29
-rw-r--r--Utilities/cmcurl/lib/dotdot.c170
-rw-r--r--Utilities/cmcurl/lib/dotdot.h25
-rw-r--r--Utilities/cmcurl/lib/easy.c1130
-rw-r--r--Utilities/cmcurl/lib/easyif.h33
-rw-r--r--Utilities/cmcurl/lib/escape.c231
-rw-r--r--Utilities/cmcurl/lib/escape.h33
-rw-r--r--Utilities/cmcurl/lib/file.c586
-rw-r--r--Utilities/cmcurl/lib/file.h41
-rw-r--r--Utilities/cmcurl/lib/fileinfo.c50
-rw-r--r--Utilities/cmcurl/lib/fileinfo.h33
-rw-r--r--Utilities/cmcurl/lib/formdata.c1551
-rw-r--r--Utilities/cmcurl/lib/formdata.h98
-rw-r--r--Utilities/cmcurl/lib/ftp.c4599
-rw-r--r--Utilities/cmcurl/lib/ftp.h159
-rw-r--r--Utilities/cmcurl/lib/ftplistparser.c1048
-rw-r--r--Utilities/cmcurl/lib/ftplistparser.h41
-rw-r--r--Utilities/cmcurl/lib/getenv.c53
-rw-r--r--Utilities/cmcurl/lib/getinfo.c382
-rw-r--r--Utilities/cmcurl/lib/getinfo.h27
-rw-r--r--Utilities/cmcurl/lib/gopher.c165
-rw-r--r--Utilities/cmcurl/lib/gopher.h29
-rw-r--r--Utilities/cmcurl/lib/hash.c368
-rw-r--r--Utilities/cmcurl/lib/hash.h100
-rw-r--r--Utilities/cmcurl/lib/hmac.c129
-rw-r--r--Utilities/cmcurl/lib/hostasyn.c153
-rw-r--r--Utilities/cmcurl/lib/hostcheck.c147
-rw-r--r--Utilities/cmcurl/lib/hostcheck.h32
-rw-r--r--Utilities/cmcurl/lib/hostip.c880
-rw-r--r--Utilities/cmcurl/lib/hostip.h250
-rw-r--r--Utilities/cmcurl/lib/hostip4.c307
-rw-r--r--Utilities/cmcurl/lib/hostip6.c221
-rw-r--r--Utilities/cmcurl/lib/hostsyn.c107
-rw-r--r--Utilities/cmcurl/lib/http.c3738
-rw-r--r--Utilities/cmcurl/lib/http.h251
-rw-r--r--Utilities/cmcurl/lib/http2.c1562
-rw-r--r--Utilities/cmcurl/lib/http2.h61
-rw-r--r--Utilities/cmcurl/lib/http_chunks.c381
-rw-r--r--Utilities/cmcurl/lib/http_chunks.h91
-rw-r--r--Utilities/cmcurl/lib/http_digest.c179
-rw-r--r--Utilities/cmcurl/lib/http_digest.h42
-rw-r--r--Utilities/cmcurl/lib/http_negotiate.c210
-rw-r--r--Utilities/cmcurl/lib/http_negotiate.h42
-rw-r--r--Utilities/cmcurl/lib/http_negotiate_sspi.c300
-rw-r--r--Utilities/cmcurl/lib/http_proxy.c596
-rw-r--r--Utilities/cmcurl/lib/http_proxy.h42
-rw-r--r--Utilities/cmcurl/lib/idn_win32.c108
-rw-r--r--Utilities/cmcurl/lib/if2ip.c271
-rw-r--r--Utilities/cmcurl/lib/if2ip.h83
-rw-r--r--Utilities/cmcurl/lib/imap.c2142
-rw-r--r--Utilities/cmcurl/lib/imap.h96
-rw-r--r--Utilities/cmcurl/lib/inet_ntop.c198
-rw-r--r--Utilities/cmcurl/lib/inet_ntop.h38
-rw-r--r--Utilities/cmcurl/lib/inet_pton.c234
-rw-r--r--Utilities/cmcurl/lib/inet_pton.h37
-rw-r--r--Utilities/cmcurl/lib/krb5.c332
-rw-r--r--Utilities/cmcurl/lib/ldap.c1013
-rw-r--r--Utilities/cmcurl/lib/libcurl.rc63
-rw-r--r--Utilities/cmcurl/lib/llist.c212
-rw-r--r--Utilities/cmcurl/lib/llist.h57
-rw-r--r--Utilities/cmcurl/lib/md4.c304
-rw-r--r--Utilities/cmcurl/lib/md5.c560
-rw-r--r--Utilities/cmcurl/lib/memdebug.c489
-rw-r--r--Utilities/cmcurl/lib/memdebug.h176
-rw-r--r--Utilities/cmcurl/lib/mprintf.c1138
-rw-r--r--Utilities/cmcurl/lib/multi.c2824
-rw-r--r--Utilities/cmcurl/lib/multihandle.h152
-rw-r--r--Utilities/cmcurl/lib/multiif.h97
-rw-r--r--Utilities/cmcurl/lib/netrc.c203
-rw-r--r--Utilities/cmcurl/lib/netrc.h36
-rw-r--r--Utilities/cmcurl/lib/non-ascii.c338
-rw-r--r--Utilities/cmcurl/lib/non-ascii.h63
-rw-r--r--Utilities/cmcurl/lib/nonblock.c91
-rw-r--r--Utilities/cmcurl/lib/nonblock.h31
-rw-r--r--Utilities/cmcurl/lib/nwlib.c325
-rw-r--r--Utilities/cmcurl/lib/nwos.c88
-rw-r--r--Utilities/cmcurl/lib/openldap.c684
-rw-r--r--Utilities/cmcurl/lib/parsedate.c583
-rw-r--r--Utilities/cmcurl/lib/parsedate.h31
-rw-r--r--Utilities/cmcurl/lib/pingpong.c507
-rw-r--r--Utilities/cmcurl/lib/pingpong.h150
-rw-r--r--Utilities/cmcurl/lib/pipeline.c433
-rw-r--r--Utilities/cmcurl/lib/pipeline.h56
-rw-r--r--Utilities/cmcurl/lib/pop3.c1601
-rw-r--r--Utilities/cmcurl/lib/pop3.h95
-rw-r--r--Utilities/cmcurl/lib/progress.c492
-rw-r--r--Utilities/cmcurl/lib/progress.h73
-rw-r--r--Utilities/cmcurl/lib/rawstr.c142
-rw-r--r--Utilities/cmcurl/lib/rawstr.h47
-rw-r--r--Utilities/cmcurl/lib/rtsp.c805
-rw-r--r--Utilities/cmcurl/lib/rtsp.h69
-rw-r--r--Utilities/cmcurl/lib/security.c580
-rw-r--r--Utilities/cmcurl/lib/select.c578
-rw-r--r--Utilities/cmcurl/lib/select.h114
-rw-r--r--Utilities/cmcurl/lib/sendf.c710
-rw-r--r--Utilities/cmcurl/lib/sendf.h92
-rw-r--r--Utilities/cmcurl/lib/setup-os400.h223
-rw-r--r--Utilities/cmcurl/lib/setup-vms.h442
-rw-r--r--Utilities/cmcurl/lib/share.c247
-rw-r--r--Utilities/cmcurl/lib/share.h61
-rw-r--r--Utilities/cmcurl/lib/sigpipe.h78
-rw-r--r--Utilities/cmcurl/lib/slist.c143
-rw-r--r--Utilities/cmcurl/lib/slist.h40
-rw-r--r--Utilities/cmcurl/lib/smb.c976
-rw-r--r--Utilities/cmcurl/lib/smb.h271
-rw-r--r--Utilities/cmcurl/lib/smtp.c1671
-rw-r--r--Utilities/cmcurl/lib/smtp.h91
-rw-r--r--Utilities/cmcurl/lib/sockaddr.h43
-rw-r--r--Utilities/cmcurl/lib/socks.c755
-rw-r--r--Utilities/cmcurl/lib/socks.h77
-rw-r--r--Utilities/cmcurl/lib/socks_gssapi.c522
-rw-r--r--Utilities/cmcurl/lib/socks_sspi.c601
-rw-r--r--Utilities/cmcurl/lib/speedcheck.c74
-rw-r--r--Utilities/cmcurl/lib/speedcheck.h33
-rw-r--r--Utilities/cmcurl/lib/splay.c288
-rw-r--r--Utilities/cmcurl/lib/splay.h66
-rw-r--r--Utilities/cmcurl/lib/ssh.c3344
-rw-r--r--Utilities/cmcurl/lib/ssh.h195
-rw-r--r--Utilities/cmcurl/lib/strdup.c73
-rw-r--r--Utilities/cmcurl/lib/strdup.h31
-rw-r--r--Utilities/cmcurl/lib/strequal.c79
-rw-r--r--Utilities/cmcurl/lib/strequal.h31
-rw-r--r--Utilities/cmcurl/lib/strerror.c1139
-rw-r--r--Utilities/cmcurl/lib/strerror.h37
-rw-r--r--Utilities/cmcurl/lib/strtok.c66
-rw-r--r--Utilities/cmcurl/lib/strtok.h34
-rw-r--r--Utilities/cmcurl/lib/strtoofft.c188
-rw-r--r--Utilities/cmcurl/lib/strtoofft.h75
-rw-r--r--Utilities/cmcurl/lib/telnet.c1675
-rw-r--r--Utilities/cmcurl/lib/telnet.h29
-rw-r--r--Utilities/cmcurl/lib/tftp.c1376
-rw-r--r--Utilities/cmcurl/lib/tftp.h29
-rw-r--r--Utilities/cmcurl/lib/timeval.c142
-rw-r--r--Utilities/cmcurl/lib/timeval.h58
-rw-r--r--Utilities/cmcurl/lib/transfer.c2006
-rw-r--r--Utilities/cmcurl/lib/transfer.h71
-rw-r--r--Utilities/cmcurl/lib/url.c6242
-rw-r--r--Utilities/cmcurl/lib/url.h86
-rw-r--r--Utilities/cmcurl/lib/urldata.h1703
-rw-r--r--Utilities/cmcurl/lib/version.c362
-rw-r--r--Utilities/cmcurl/lib/vtls/axtls.c690
-rw-r--r--Utilities/cmcurl/lib/vtls/axtls.h71
-rw-r--r--Utilities/cmcurl/lib/vtls/cyassl.c786
-rw-r--r--Utilities/cmcurl/lib/vtls/cyassl.h75
-rw-r--r--Utilities/cmcurl/lib/vtls/darwinssl.c2484
-rw-r--r--Utilities/cmcurl/lib/vtls/darwinssl.h76
-rw-r--r--Utilities/cmcurl/lib/vtls/gskit.c1069
-rw-r--r--Utilities/cmcurl/lib/vtls/gskit.h71
-rw-r--r--Utilities/cmcurl/lib/vtls/gtls.c1589
-rw-r--r--Utilities/cmcurl/lib/vtls/gtls.h88
-rw-r--r--Utilities/cmcurl/lib/vtls/nss.c2074
-rw-r--r--Utilities/cmcurl/lib/vtls/nssg.h102
-rw-r--r--Utilities/cmcurl/lib/vtls/openssl.c3209
-rw-r--r--Utilities/cmcurl/lib/vtls/openssl.h120
-rw-r--r--Utilities/cmcurl/lib/vtls/polarssl.c753
-rw-r--r--Utilities/cmcurl/lib/vtls/polarssl.h75
-rw-r--r--Utilities/cmcurl/lib/vtls/polarssl_threadlock.c153
-rw-r--r--Utilities/cmcurl/lib/vtls/polarssl_threadlock.h53
-rw-r--r--Utilities/cmcurl/lib/vtls/schannel.c1501
-rw-r--r--Utilities/cmcurl/lib/vtls/schannel.h118
-rw-r--r--Utilities/cmcurl/lib/vtls/vtls.c962
-rw-r--r--Utilities/cmcurl/lib/vtls/vtls.h157
-rw-r--r--Utilities/cmcurl/lib/warnless.c486
-rw-r--r--Utilities/cmcurl/lib/warnless.h107
-rw-r--r--Utilities/cmcurl/lib/wildcard.c69
-rw-r--r--Utilities/cmcurl/lib/wildcard.h58
-rw-r--r--Utilities/cmcurl/lib/x509asn1.c1188
-rw-r--r--Utilities/cmcurl/lib/x509asn1.h132
-rw-r--r--Utilities/cmcurl/llist.c138
-rw-r--r--Utilities/cmcurl/llist.h60
-rw-r--r--Utilities/cmcurl/md5.c352
-rw-r--r--Utilities/cmcurl/md5.h29
-rw-r--r--Utilities/cmcurl/memdebug.c298
-rw-r--r--Utilities/cmcurl/memdebug.h125
-rw-r--r--Utilities/cmcurl/memory.h50
-rw-r--r--Utilities/cmcurl/mprintf.c1218
-rw-r--r--Utilities/cmcurl/multi.c1988
-rw-r--r--Utilities/cmcurl/multiif.h46
-rw-r--r--Utilities/cmcurl/netrc.c247
-rw-r--r--Utilities/cmcurl/netrc.h34
-rw-r--r--Utilities/cmcurl/nwlib.c300
-rw-r--r--Utilities/cmcurl/parsedate.c425
-rw-r--r--Utilities/cmcurl/parsedate.h28
-rw-r--r--Utilities/cmcurl/progress.c424
-rw-r--r--Utilities/cmcurl/progress.h70
-rw-r--r--Utilities/cmcurl/security.c493
-rw-r--r--Utilities/cmcurl/select.c315
-rw-r--r--Utilities/cmcurl/select.h60
-rw-r--r--Utilities/cmcurl/sendf.c663
-rw-r--r--Utilities/cmcurl/sendf.h72
-rw-r--r--Utilities/cmcurl/setup.h390
-rw-r--r--Utilities/cmcurl/setup_once.h153
-rw-r--r--Utilities/cmcurl/share.c219
-rw-r--r--Utilities/cmcurl/share.h56
-rw-r--r--Utilities/cmcurl/sockaddr.h38
-rw-r--r--Utilities/cmcurl/socks.c592
-rw-r--r--Utilities/cmcurl/socks.h41
-rw-r--r--Utilities/cmcurl/speedcheck.c75
-rw-r--r--Utilities/cmcurl/speedcheck.h34
-rw-r--r--Utilities/cmcurl/splay.c425
-rw-r--r--Utilities/cmcurl/splay.h54
-rw-r--r--Utilities/cmcurl/ssh.c979
-rw-r--r--Utilities/cmcurl/ssh.h49
-rw-r--r--Utilities/cmcurl/sslgen.c618
-rw-r--r--Utilities/cmcurl/sslgen.h84
-rw-r--r--Utilities/cmcurl/ssluse.c1950
-rw-r--r--Utilities/cmcurl/ssluse.h71
-rw-r--r--Utilities/cmcurl/strdup.c46
-rw-r--r--Utilities/cmcurl/strdup.h34
-rw-r--r--Utilities/cmcurl/strequal.c101
-rw-r--r--Utilities/cmcurl/strequal.h38
-rw-r--r--Utilities/cmcurl/strerror.c751
-rw-r--r--Utilities/cmcurl/strerror.h34
-rw-r--r--Utilities/cmcurl/strtok.c68
-rw-r--r--Utilities/cmcurl/strtok.h38
-rw-r--r--Utilities/cmcurl/strtoofft.c165
-rw-r--r--Utilities/cmcurl/strtoofft.h73
-rw-r--r--Utilities/cmcurl/telnet.c1403
-rw-r--r--Utilities/cmcurl/telnet.h30
-rw-r--r--Utilities/cmcurl/tftp.c816
-rw-r--r--Utilities/cmcurl/tftp.h31
-rw-r--r--Utilities/cmcurl/timeval.c116
-rw-r--r--Utilities/cmcurl/timeval.h76
-rw-r--r--Utilities/cmcurl/transfer.c2494
-rw-r--r--Utilities/cmcurl/transfer.h51
-rw-r--r--Utilities/cmcurl/url.c4252
-rw-r--r--Utilities/cmcurl/url.h85
-rw-r--r--Utilities/cmcurl/urldata.h1340
-rw-r--r--Utilities/cmcurl/version.c249
-rw-r--r--Utilities/cmjsoncpp/.gitattributes1
-rw-r--r--Utilities/cmjsoncpp/CMakeLists.txt26
-rw-r--r--Utilities/cmjsoncpp/LICENSE55
-rw-r--r--Utilities/cmjsoncpp/README-CMake.txt66
-rw-r--r--Utilities/cmjsoncpp/include/json/assertions.h41
-rw-r--r--Utilities/cmjsoncpp/include/json/config.h119
-rw-r--r--Utilities/cmjsoncpp/include/json/features.h57
-rw-r--r--Utilities/cmjsoncpp/include/json/forwards.h43
-rw-r--r--Utilities/cmjsoncpp/include/json/json.h14
-rw-r--r--Utilities/cmjsoncpp/include/json/reader.h274
-rw-r--r--Utilities/cmjsoncpp/include/json/value.h1088
-rw-r--r--Utilities/cmjsoncpp/include/json/version.h14
-rw-r--r--Utilities/cmjsoncpp/include/json/writer.h213
-rw-r--r--Utilities/cmjsoncpp/src/lib_json/json_batchallocator.h121
-rw-r--r--Utilities/cmjsoncpp/src/lib_json/json_internalarray.inl360
-rw-r--r--Utilities/cmjsoncpp/src/lib_json/json_internalmap.inl473
-rw-r--r--Utilities/cmjsoncpp/src/lib_json/json_reader.cpp885
-rw-r--r--Utilities/cmjsoncpp/src/lib_json/json_tool.h87
-rw-r--r--Utilities/cmjsoncpp/src/lib_json/json_value.cpp1482
-rw-r--r--Utilities/cmjsoncpp/src/lib_json/json_valueiterator.inl241
-rw-r--r--Utilities/cmjsoncpp/src/lib_json/json_writer.cpp724
-rw-r--r--Utilities/cmlibarchive/.gitattributes3
-rw-r--r--Utilities/cmlibarchive/CMakeLists.txt173
-rw-r--r--Utilities/cmlibarchive/COPYING5
-rw-r--r--Utilities/cmlibarchive/README-CMake.txt8
-rw-r--r--Utilities/cmlibarchive/build/cmake/CheckFuncs.cmake2
-rw-r--r--Utilities/cmlibarchive/build/cmake/CreatePkgConfigFile.cmake33
-rw-r--r--Utilities/cmlibarchive/build/cmake/LibarchiveCodeCoverage.cmake68
-rw-r--r--Utilities/cmlibarchive/build/cmake/config.h.in49
-rw-r--r--Utilities/cmlibarchive/libarchive/CMakeLists.txt25
-rw-r--r--Utilities/cmlibarchive/libarchive/archive.h258
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_crypto.c1429
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_crypto_private.h376
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_cryptor.c435
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_cryptor_private.h152
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_digest.c1429
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_digest_private.h376
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry.c171
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry.h64
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_acl.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_paths.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_perms.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_private.h5
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_sparse.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_stat.34
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_time.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_xattr.c5
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_getdate.c17
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_hmac.c234
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_hmac_private.h95
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_match.c11
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_pack_dev.c329
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_pack_dev.h49
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_pathmatch.c8
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_platform.h7
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_private.h19
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_random.c269
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_random_private.h36
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read.34
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read.c140
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.374
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.c186
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_append_filter.c6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_data.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c30
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c25
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk_private.h5
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk_set_standard_lookup.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c27
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_extract.c147
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_extract2.c156
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_filter.317
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_open.34
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_open_fd.c29
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_open_memory.c12
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_private.h76
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_set_options.322
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_set_options.c39
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_all.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_compress.c24
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c728
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c16
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_uu.c3
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c212
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_all.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_ar.c25
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c26
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_empty.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c76
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c484
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c566
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c113
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_raw.c4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c218
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c794
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c52
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c3506
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_string.c91
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_util.c152
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_virtual.c16
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_windows.c10
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_windows.h16
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write.315
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write.c27
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_by_name.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_lrzip.c7
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_lz4.c646
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_lzop.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_xz.c46
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_data.314
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk.310
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk_acl.c16
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c116
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk_set_standard_lookup.c7
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c8
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_filter.318
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_finish_entry.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_format.321
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_open.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_open_filename.c5
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_private.h15
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format.c4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_by_name.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_filter_by_ext.c142
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_gnutar.c12
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c10
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c43
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_raw.c125
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_shar.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_warc.c439
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c65
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c1646
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_options.344
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_passphrase.374
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_passphrase.c95
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_xxhash.h47
-rw-r--r--Utilities/cmlibarchive/libarchive/filter_fork_windows.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/libarchive.34
-rw-r--r--Utilities/cmlibarchive/libarchive/libarchive_internals.32
-rw-r--r--Utilities/cmlibarchive/libarchive/mtree.596
-rw-r--r--Utilities/cmlibarchive/libarchive/tar.52
-rw-r--r--Utilities/cmlibarchive/libarchive/xxhash.c500
-rw-r--r--Utilities/cmliblzma/.gitattributes1
-rw-r--r--Utilities/cmliblzma/CMakeLists.txt224
-rw-r--r--Utilities/cmliblzma/COPYING65
-rw-r--r--Utilities/cmliblzma/README-CMake.txt66
-rw-r--r--Utilities/cmliblzma/common/common_w32res.rc50
-rw-r--r--Utilities/cmliblzma/common/sysdefs.h202
-rw-r--r--Utilities/cmliblzma/common/tuklib_integer.h514
-rw-r--r--Utilities/cmliblzma/config.h.in289
-rw-r--r--Utilities/cmliblzma/liblzma/api/lzma.h313
-rw-r--r--Utilities/cmliblzma/liblzma/api/lzma/base.h601
-rw-r--r--Utilities/cmliblzma/liblzma/api/lzma/bcj.h90
-rw-r--r--Utilities/cmliblzma/liblzma/api/lzma/block.h530
-rw-r--r--Utilities/cmliblzma/liblzma/api/lzma/check.h150
-rw-r--r--Utilities/cmliblzma/liblzma/api/lzma/container.h424
-rw-r--r--Utilities/cmliblzma/liblzma/api/lzma/delta.h77
-rw-r--r--Utilities/cmliblzma/liblzma/api/lzma/filter.h424
-rw-r--r--Utilities/cmliblzma/liblzma/api/lzma/hardware.h50
-rw-r--r--Utilities/cmliblzma/liblzma/api/lzma/index.h682
-rw-r--r--Utilities/cmliblzma/liblzma/api/lzma/index_hash.h107
-rw-r--r--Utilities/cmliblzma/liblzma/api/lzma/lzma.h420
-rw-r--r--Utilities/cmliblzma/liblzma/api/lzma/stream_flags.h223
-rw-r--r--Utilities/cmliblzma/liblzma/api/lzma/version.h121
-rw-r--r--Utilities/cmliblzma/liblzma/api/lzma/vli.h166
-rw-r--r--Utilities/cmliblzma/liblzma/check/check.c174
-rw-r--r--Utilities/cmliblzma/liblzma/check/check.h95
-rw-r--r--Utilities/cmliblzma/liblzma/check/crc32_fast.c86
-rw-r--r--Utilities/cmliblzma/liblzma/check/crc32_small.c61
-rw-r--r--Utilities/cmliblzma/liblzma/check/crc32_table.c19
-rw-r--r--Utilities/cmliblzma/liblzma/check/crc32_table_be.h525
-rw-r--r--Utilities/cmliblzma/liblzma/check/crc32_table_le.h525
-rw-r--r--Utilities/cmliblzma/liblzma/check/crc32_tablegen.c117
-rw-r--r--Utilities/cmliblzma/liblzma/check/crc32_x86.S304
-rw-r--r--Utilities/cmliblzma/liblzma/check/crc64_fast.c74
-rw-r--r--Utilities/cmliblzma/liblzma/check/crc64_small.c53
-rw-r--r--Utilities/cmliblzma/liblzma/check/crc64_table.c19
-rw-r--r--Utilities/cmliblzma/liblzma/check/crc64_table_be.h521
-rw-r--r--Utilities/cmliblzma/liblzma/check/crc64_table_le.h521
-rw-r--r--Utilities/cmliblzma/liblzma/check/crc64_tablegen.c88
-rw-r--r--Utilities/cmliblzma/liblzma/check/crc64_x86.S287
-rw-r--r--Utilities/cmliblzma/liblzma/check/crc_macros.h30
-rw-r--r--Utilities/cmliblzma/liblzma/check/sha256.c204
-rw-r--r--Utilities/cmliblzma/liblzma/common/alone_decoder.c236
-rw-r--r--Utilities/cmliblzma/liblzma/common/alone_decoder.h23
-rw-r--r--Utilities/cmliblzma/liblzma/common/alone_encoder.c155
-rw-r--r--Utilities/cmliblzma/liblzma/common/auto_decoder.c186
-rw-r--r--Utilities/cmliblzma/liblzma/common/block_buffer_decoder.c82
-rw-r--r--Utilities/cmliblzma/liblzma/common/block_buffer_encoder.c315
-rw-r--r--Utilities/cmliblzma/liblzma/common/block_decoder.c242
-rw-r--r--Utilities/cmliblzma/liblzma/common/block_decoder.h22
-rw-r--r--Utilities/cmliblzma/liblzma/common/block_encoder.c217
-rw-r--r--Utilities/cmliblzma/liblzma/common/block_encoder.h47
-rw-r--r--Utilities/cmliblzma/liblzma/common/block_header_decoder.c121
-rw-r--r--Utilities/cmliblzma/liblzma/common/block_header_encoder.c137
-rw-r--r--Utilities/cmliblzma/liblzma/common/block_util.c95
-rw-r--r--Utilities/cmliblzma/liblzma/common/common.c390
-rw-r--r--Utilities/cmliblzma/liblzma/common/common.h305
-rw-r--r--Utilities/cmliblzma/liblzma/common/easy_buffer_encoder.c27
-rw-r--r--Utilities/cmliblzma/liblzma/common/easy_decoder_memusage.c24
-rw-r--r--Utilities/cmliblzma/liblzma/common/easy_encoder.c25
-rw-r--r--Utilities/cmliblzma/liblzma/common/easy_encoder_memusage.c24
-rw-r--r--Utilities/cmliblzma/liblzma/common/easy_preset.c27
-rw-r--r--Utilities/cmliblzma/liblzma/common/easy_preset.h32
-rw-r--r--Utilities/cmliblzma/liblzma/common/filter_buffer_decoder.c91
-rw-r--r--Utilities/cmliblzma/liblzma/common/filter_buffer_encoder.c57
-rw-r--r--Utilities/cmliblzma/liblzma/common/filter_common.c342
-rw-r--r--Utilities/cmliblzma/liblzma/common/filter_common.h48
-rw-r--r--Utilities/cmliblzma/liblzma/common/filter_decoder.c185
-rw-r--r--Utilities/cmliblzma/liblzma/common/filter_decoder.h23
-rw-r--r--Utilities/cmliblzma/liblzma/common/filter_encoder.c297
-rw-r--r--Utilities/cmliblzma/liblzma/common/filter_encoder.h27
-rw-r--r--Utilities/cmliblzma/liblzma/common/filter_flags_decoder.c48
-rw-r--r--Utilities/cmliblzma/liblzma/common/filter_flags_encoder.c57
-rw-r--r--Utilities/cmliblzma/liblzma/common/hardware_physmem.c25
-rw-r--r--Utilities/cmliblzma/liblzma/common/index.c1276
-rw-r--r--Utilities/cmliblzma/liblzma/common/index.h73
-rw-r--r--Utilities/cmliblzma/liblzma/common/index_decoder.c347
-rw-r--r--Utilities/cmliblzma/liblzma/common/index_encoder.c257
-rw-r--r--Utilities/cmliblzma/liblzma/common/index_encoder.h23
-rw-r--r--Utilities/cmliblzma/liblzma/common/index_hash.c336
-rw-r--r--Utilities/cmliblzma/liblzma/common/stream_buffer_decoder.c93
-rw-r--r--Utilities/cmliblzma/liblzma/common/stream_buffer_encoder.c140
-rw-r--r--Utilities/cmliblzma/liblzma/common/stream_decoder.c459
-rw-r--r--Utilities/cmliblzma/liblzma/common/stream_decoder.h21
-rw-r--r--Utilities/cmliblzma/liblzma/common/stream_encoder.c338
-rw-r--r--Utilities/cmliblzma/liblzma/common/stream_encoder.h23
-rw-r--r--Utilities/cmliblzma/liblzma/common/stream_flags_common.c47
-rw-r--r--Utilities/cmliblzma/liblzma/common/stream_flags_common.h33
-rw-r--r--Utilities/cmliblzma/liblzma/common/stream_flags_decoder.c86
-rw-r--r--Utilities/cmliblzma/liblzma/common/stream_flags_encoder.c90
-rw-r--r--Utilities/cmliblzma/liblzma/common/vli_decoder.c86
-rw-r--r--Utilities/cmliblzma/liblzma/common/vli_encoder.c69
-rw-r--r--Utilities/cmliblzma/liblzma/common/vli_size.c31
-rw-r--r--Utilities/cmliblzma/liblzma/delta/delta_common.c72
-rw-r--r--Utilities/cmliblzma/liblzma/delta/delta_common.h20
-rw-r--r--Utilities/cmliblzma/liblzma/delta/delta_decoder.c79
-rw-r--r--Utilities/cmliblzma/liblzma/delta/delta_decoder.h25
-rw-r--r--Utilities/cmliblzma/liblzma/delta/delta_encoder.c124
-rw-r--r--Utilities/cmliblzma/liblzma/delta/delta_encoder.h23
-rw-r--r--Utilities/cmliblzma/liblzma/delta/delta_private.h37
-rw-r--r--Utilities/cmliblzma/liblzma/liblzma.pc.in19
-rw-r--r--Utilities/cmliblzma/liblzma/liblzma_w32res.rc14
-rw-r--r--Utilities/cmliblzma/liblzma/lz/lz_decoder.c307
-rw-r--r--Utilities/cmliblzma/liblzma/lz/lz_decoder.h236
-rw-r--r--Utilities/cmliblzma/liblzma/lz/lz_encoder.c594
-rw-r--r--Utilities/cmliblzma/liblzma/lz/lz_encoder.h328
-rw-r--r--Utilities/cmliblzma/liblzma/lz/lz_encoder_hash.h105
-rw-r--r--Utilities/cmliblzma/liblzma/lz/lz_encoder_hash_table.h68
-rw-r--r--Utilities/cmliblzma/liblzma/lz/lz_encoder_mf.c814
-rw-r--r--Utilities/cmliblzma/liblzma/lzma/fastpos.h142
-rw-r--r--Utilities/cmliblzma/liblzma/lzma/fastpos_table.c519
-rw-r--r--Utilities/cmliblzma/liblzma/lzma/fastpos_tablegen.c56
-rw-r--r--Utilities/cmliblzma/liblzma/lzma/lzma2_decoder.c305
-rw-r--r--Utilities/cmliblzma/liblzma/lzma/lzma2_decoder.h28
-rw-r--r--Utilities/cmliblzma/liblzma/lzma/lzma2_encoder.c399
-rw-r--r--Utilities/cmliblzma/liblzma/lzma/lzma2_encoder.h41
-rw-r--r--Utilities/cmliblzma/liblzma/lzma/lzma_common.h226
-rw-r--r--Utilities/cmliblzma/liblzma/lzma/lzma_decoder.c1075
-rw-r--r--Utilities/cmliblzma/liblzma/lzma/lzma_decoder.h52
-rw-r--r--Utilities/cmliblzma/liblzma/lzma/lzma_encoder.c695
-rw-r--r--Utilities/cmliblzma/liblzma/lzma/lzma_encoder.h54
-rw-r--r--Utilities/cmliblzma/liblzma/lzma/lzma_encoder_optimum_fast.c185
-rw-r--r--Utilities/cmliblzma/liblzma/lzma/lzma_encoder_optimum_normal.c925
-rw-r--r--Utilities/cmliblzma/liblzma/lzma/lzma_encoder_presets.c63
-rw-r--r--Utilities/cmliblzma/liblzma/lzma/lzma_encoder_private.h148
-rw-r--r--Utilities/cmliblzma/liblzma/rangecoder/price.h92
-rw-r--r--Utilities/cmliblzma/liblzma/rangecoder/price_table.c22
-rw-r--r--Utilities/cmliblzma/liblzma/rangecoder/price_tablegen.c87
-rw-r--r--Utilities/cmliblzma/liblzma/rangecoder/range_common.h74
-rw-r--r--Utilities/cmliblzma/liblzma/rangecoder/range_decoder.h179
-rw-r--r--Utilities/cmliblzma/liblzma/rangecoder/range_encoder.h232
-rw-r--r--Utilities/cmliblzma/liblzma/simple/arm.c69
-rw-r--r--Utilities/cmliblzma/liblzma/simple/armthumb.c74
-rw-r--r--Utilities/cmliblzma/liblzma/simple/ia64.c116
-rw-r--r--Utilities/cmliblzma/liblzma/simple/powerpc.c73
-rw-r--r--Utilities/cmliblzma/liblzma/simple/simple_coder.c283
-rw-r--r--Utilities/cmliblzma/liblzma/simple/simple_coder.h60
-rw-r--r--Utilities/cmliblzma/liblzma/simple/simple_decoder.c41
-rw-r--r--Utilities/cmliblzma/liblzma/simple/simple_decoder.h22
-rw-r--r--Utilities/cmliblzma/liblzma/simple/simple_encoder.c38
-rw-r--r--Utilities/cmliblzma/liblzma/simple/simple_encoder.h23
-rw-r--r--Utilities/cmliblzma/liblzma/simple/simple_private.h75
-rw-r--r--Utilities/cmliblzma/liblzma/simple/sparc.c82
-rw-r--r--Utilities/cmliblzma/liblzma/simple/x86.c161
-rw-r--r--Utilities/cmzlib/CMakeLists.txt18
-rw-r--r--Utilities/cmzlib/zconf.h2
-rw-r--r--Utilities/cmzlib/zutil.h6
-rw-r--r--Utilities/xml/docbook-4.5/ChangeLog106
-rw-r--r--Utilities/xml/docbook-4.5/README8
-rw-r--r--Utilities/xml/docbook-4.5/calstblx.dtd215
-rw-r--r--Utilities/xml/docbook-4.5/catalog.xml124
-rw-r--r--Utilities/xml/docbook-4.5/dbcentx.mod384
-rw-r--r--Utilities/xml/docbook-4.5/dbgenent.mod41
-rw-r--r--Utilities/xml/docbook-4.5/dbhierx.mod2193
-rw-r--r--Utilities/xml/docbook-4.5/dbnotnx.mod101
-rw-r--r--Utilities/xml/docbook-4.5/dbpoolx.mod8701
-rw-r--r--Utilities/xml/docbook-4.5/docbook.cat113
-rw-r--r--Utilities/xml/docbook-4.5/docbookx.dtd170
-rw-r--r--Utilities/xml/docbook-4.5/ent/README14
-rw-r--r--Utilities/xml/docbook-4.5/ent/isoamsa.ent97
-rw-r--r--Utilities/xml/docbook-4.5/ent/isoamsb.ent83
-rw-r--r--Utilities/xml/docbook-4.5/ent/isoamsc.ent51
-rw-r--r--Utilities/xml/docbook-4.5/ent/isoamsn.ent103
-rw-r--r--Utilities/xml/docbook-4.5/ent/isoamso.ent59
-rw-r--r--Utilities/xml/docbook-4.5/ent/isoamsr.ent125
-rw-r--r--Utilities/xml/docbook-4.5/ent/isobox.ent81
-rw-r--r--Utilities/xml/docbook-4.5/ent/isocyr1.ent108
-rw-r--r--Utilities/xml/docbook-4.5/ent/isocyr2.ent67
-rw-r--r--Utilities/xml/docbook-4.5/ent/isodia.ent55
-rw-r--r--Utilities/xml/docbook-4.5/ent/isogrk1.ent90
-rw-r--r--Utilities/xml/docbook-4.5/ent/isogrk2.ent61
-rw-r--r--Utilities/xml/docbook-4.5/ent/isogrk3.ent84
-rw-r--r--Utilities/xml/docbook-4.5/ent/isogrk4.ent84
-rw-r--r--Utilities/xml/docbook-4.5/ent/isolat1.ent103
-rw-r--r--Utilities/xml/docbook-4.5/ent/isolat2.ent162
-rw-r--r--Utilities/xml/docbook-4.5/ent/isonum.ent117
-rw-r--r--Utilities/xml/docbook-4.5/ent/isopub.ent125
-rw-r--r--Utilities/xml/docbook-4.5/ent/isotech.ent103
-rw-r--r--Utilities/xml/docbook-4.5/htmltblx.mod245
-rw-r--r--Utilities/xml/docbook-4.5/soextblx.dtd321
-rw-r--r--Utilities/xml/xhtml1/xhtml-lat1.ent196
-rw-r--r--Utilities/xml/xhtml1/xhtml-special.ent80
-rw-r--r--Utilities/xml/xhtml1/xhtml-symbol.ent237
-rw-r--r--Utilities/xml/xhtml1/xhtml1-strict.dtd977
-rwxr-xr-xbootstrap599
-rw-r--r--cmake_uninstall.cmake.in2
7178 files changed, 342921 insertions, 252201 deletions
diff --git a/.gitattributes b/.gitattributes
index d21f1dda0..d3f7280e2 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -12,6 +12,8 @@ configure crlf=input
*.dsp -crlf
*.dsptemplate -crlf
*.dsw -crlf
+*.pfx -crlf
+*.png -crlf
*.sln -crlf
*.vcproj -crlf
diff --git a/Auxiliary/CMakeLists.txt b/Auxiliary/CMakeLists.txt
new file mode 100644
index 000000000..c003b28e7
--- /dev/null
+++ b/Auxiliary/CMakeLists.txt
@@ -0,0 +1,4 @@
+install(FILES cmake-help.vim cmake-indent.vim cmake-syntax.vim DESTINATION ${CMAKE_DATA_DIR}/editors/vim)
+install(FILES cmake-mode.el DESTINATION ${CMAKE_DATA_DIR}/editors/emacs)
+install(FILES cmake.m4 DESTINATION share/aclocal)
+add_subdirectory (bash-completion)
diff --git a/Docs/bash-completion/CMakeLists.txt b/Auxiliary/bash-completion/CMakeLists.txt
index c0a88999e..c0a88999e 100644
--- a/Docs/bash-completion/CMakeLists.txt
+++ b/Auxiliary/bash-completion/CMakeLists.txt
diff --git a/Auxiliary/bash-completion/cmake b/Auxiliary/bash-completion/cmake
new file mode 100644
index 000000000..557f243e3
--- /dev/null
+++ b/Auxiliary/bash-completion/cmake
@@ -0,0 +1,158 @@
+# bash completion for cmake(1) -*- shell-script -*-
+
+_cmake()
+{
+ local cur prev words cword split=false
+ if type -t _init_completion >/dev/null; then
+ _init_completion -n = || return
+ else
+ # manual initialization for older bash completion versions
+ COMPREPLY=()
+ cur="${COMP_WORDS[COMP_CWORD]}"
+ prev="${COMP_WORDS[COMP_CWORD-1]}"
+ fi
+
+ # Workaround for options like -DCMAKE_BUILD_TYPE=Release
+ local prefix=
+ if [[ $cur == -D* ]]; then
+ prev=-D
+ prefix=-D
+ cur="${cur#-D}"
+ elif [[ $cur == -U* ]]; then
+ prev=-U
+ prefix=-U
+ cur="${cur#-U}"
+ fi
+
+ case "$prev" in
+ -D)
+ if [[ $cur == *=* ]]; then
+ # complete values for variables
+ local var type value
+ var="${cur%%[:=]*}"
+ value="${cur#*=}"
+
+ if [[ $cur == CMAKE_BUILD_TYPE* ]]; then # most widely used case
+ COMPREPLY=( $( compgen -W 'Debug Release RelWithDebInfo
+ MinSizeRel' -- "$value" ) )
+ return
+ fi
+
+ if [[ $cur == *:* ]]; then
+ type="${cur#*:}"
+ type="${type%%=*}"
+ else # get type from cache if it's not set explicitly
+ type=$( cmake -LA -N 2>/dev/null | grep "$var:" \
+ 2>/dev/null )
+ type="${type#*:}"
+ type="${type%%=*}"
+ fi
+ case "$type" in
+ FILEPATH)
+ cur="$value"
+ _filedir
+ return
+ ;;
+ PATH)
+ cur="$value"
+ _filedir -d
+ return
+ ;;
+ BOOL)
+ COMPREPLY=( $( compgen -W 'ON OFF TRUE FALSE' -- \
+ "$value" ) )
+ return
+ ;;
+ STRING|INTERNAL)
+ # no completion available
+ return
+ ;;
+ esac
+ elif [[ $cur == *:* ]]; then
+ # complete types
+ local type="${cur#*:}"
+ COMPREPLY=( $( compgen -W 'FILEPATH PATH STRING BOOL INTERNAL'\
+ -S = -- "$type" ) )
+ compopt -o nospace
+ else
+ # complete variable names
+ COMPREPLY=( $( compgen -W '$( cmake -LA -N | tail -n +2 |
+ cut -f1 -d: )' -P "$prefix" -- "$cur" ) )
+ compopt -o nospace
+ fi
+ return
+ ;;
+ -U)
+ COMPREPLY=( $( compgen -W '$( cmake -LA -N | tail -n +2 |
+ cut -f1 -d: )' -P "$prefix" -- "$cur" ) )
+ return
+ ;;
+ esac
+
+ _split_longopt && split=true
+
+ case "$prev" in
+ -C|-P|--graphviz|--system-information)
+ _filedir
+ return
+ ;;
+ --build)
+ _filedir -d
+ return
+ ;;
+ -E)
+ COMPREPLY=( $( compgen -W "$( cmake -E help |& sed -n \
+ '/^ /{s|^ \([^ ]\{1,\}\) .*$|\1|;p}' 2>/dev/null )" \
+ -- "$cur" ) )
+ return
+ ;;
+ -G)
+ local IFS=$'\n'
+ local quoted
+ printf -v quoted %q "$cur"
+ COMPREPLY=( $( compgen -W '$( cmake --help 2>/dev/null | sed -n \
+ -e "1,/^Generators/d" \
+ -e "/^ *[^ =]/{s|^ *\([^=]*[^ =]\).*$|\1|;s| |\\\\ |g;p}" \
+ 2>/dev/null )' -- "$quoted" ) )
+ return
+ ;;
+ --help-command)
+ COMPREPLY=( $( compgen -W '$( cmake --help-command-list 2>/dev/null|
+ grep -v "^cmake version " )' -- "$cur" ) )
+ return
+ ;;
+ --help-module)
+ COMPREPLY=( $( compgen -W '$( cmake --help-module-list 2>/dev/null|
+ grep -v "^cmake version " )' -- "$cur" ) )
+ return
+ ;;
+ --help-policy)
+ COMPREPLY=( $( compgen -W '$( cmake --help-policies 2>/dev/null |
+ grep "^ CMP" 2>/dev/null )' -- "$cur" ) )
+ return
+ ;;
+ --help-property)
+ COMPREPLY=( $( compgen -W '$( cmake --help-property-list \
+ 2>/dev/null | grep -v "^cmake version " )' -- "$cur" ) )
+ return
+ ;;
+ --help-variable)
+ COMPREPLY=( $( compgen -W '$( cmake --help-variable-list \
+ 2>/dev/null | grep -v "^cmake version " )' -- "$cur" ) )
+ return
+ ;;
+ esac
+
+ $split && return
+
+ if [[ "$cur" == -* ]]; then
+ COMPREPLY=( $(compgen -W '$( _parse_help "$1" --help )' -- ${cur}) )
+ [[ $COMPREPLY == *= ]] && compopt -o nospace
+ [[ $COMPREPLY ]] && return
+ fi
+
+ _filedir
+} &&
+complete -F _cmake cmake
+
+# ex: ts=4 sw=4 et filetype=sh
diff --git a/Auxiliary/bash-completion/cpack b/Auxiliary/bash-completion/cpack
new file mode 100644
index 000000000..05e0e93ec
--- /dev/null
+++ b/Auxiliary/bash-completion/cpack
@@ -0,0 +1,68 @@
+# bash completion for cpack(1) -*- shell-script -*-
+
+_cpack()
+{
+ local cur prev words cword
+ if type -t _init_completion >/dev/null; then
+ _init_completion -n = || return
+ else
+ # manual initialization for older bash completion versions
+ COMPREPLY=()
+ cur="${COMP_WORDS[COMP_CWORD]}"
+ prev="${COMP_WORDS[COMP_CWORD-1]}"
+ fi
+
+ case "$prev" in
+ -G)
+ COMPREPLY=( $( compgen -W '$( cpack --help 2>/dev/null |
+ sed -e "1,/^Generators/d" -e "s|^ *\([^ ]*\) .*$|\1|" \
+ 2>/dev/null )' -- "$cur" ) )
+ return
+ ;;
+ -C)
+ COMPREPLY=( $( compgen -W 'Debug Release RelWithDebInfo
+ MinSizeRel' -- "$cur" ) )
+ return
+ ;;
+ -D)
+ [[ $cur == *=* ]] && return # no completion for values
+ COMPREPLY=( $( compgen -W '$( cpack --help-variable-list \
+ 2>/dev/null | grep -v "^cpack version " )' -S = -- "$cur" ) )
+ compopt -o nospace
+ return
+ ;;
+ -P|-R|--vendor)
+ # argument required but no completions available
+ return
+ ;;
+ -B)
+ _filedir -d
+ return
+ ;;
+ --config)
+ _filedir
+ return
+ ;;
+ --help-command)
+ COMPREPLY=( $( compgen -W '$( cpack --help-command-list 2>/dev/null|
+ grep -v "^cpack version " )' -- "$cur" ) )
+ return
+ ;;
+ --help-variable)
+ COMPREPLY=( $( compgen -W '$( cpack --help-variable-list \
+ 2>/dev/null | grep -v "^cpack version " )' -- "$cur" ) )
+ return
+ ;;
+ esac
+
+ if [[ "$cur" == -* ]]; then
+ COMPREPLY=( $(compgen -W '$( _parse_help "$1" --help )' -- ${cur}) )
+ [[ $COMPREPLY == *= ]] && compopt -o nospace
+ [[ $COMPREPLY ]] && return
+ fi
+
+ _filedir
+} &&
+complete -F _cpack cpack
+
+# ex: ts=4 sw=4 et filetype=sh
diff --git a/Auxiliary/bash-completion/ctest b/Auxiliary/bash-completion/ctest
new file mode 100644
index 000000000..387672adf
--- /dev/null
+++ b/Auxiliary/bash-completion/ctest
@@ -0,0 +1,92 @@
+# bash completion for ctest(1) -*- shell-script -*-
+
+_ctest()
+{
+ local cur prev words cword
+ if type -t _init_completion >/dev/null; then
+ _init_completion -n = || return
+ else
+ # manual initialization for older bash completion versions
+ COMPREPLY=()
+ cur="${COMP_WORDS[COMP_CWORD]}"
+ prev="${COMP_WORDS[COMP_CWORD-1]}"
+ fi
+
+ case "$prev" in
+ -C|--build-config)
+ COMPREPLY=( $( compgen -W 'Debug Release RelWithDebInfo
+ MinSizeRel' -- "$cur" ) )
+ return
+ ;;
+ -j|--parallel)
+ COMPREPLY=( $( compgen -W "{1..$(( $(_ncpus)*2 ))}" -- "$cur" ) )
+ return
+ ;;
+ -O|--output-log|-A|--add-notes|--extra-submit)
+ _filedir
+ return
+ ;;
+ -L|--label-regex|-LE|--label-exclude)
+ COMPREPLY=( $( compgen -W '$( ctest --print-labels 2>/dev/null |
+ grep "^ " 2>/dev/null | cut -d" " -f 3 )' -- "$cur" ) )
+ return
+ ;;
+ --track|-I|--tests-information|--max-width|--timeout|--stop-time)
+ # argument required but no completions available
+ return
+ ;;
+ -R|--tests-regex|-E|--exclude-regex)
+ COMPREPLY=( $( compgen -W '$( ctest -N 2>/dev/null |
+ grep "^ Test" 2>/dev/null | cut -d: -f 2 )' -- "$cur" ) )
+ return
+ ;;
+ -D|--dashboard)
+ if [[ $cur == @(Experimental|Nightly|Continuous)* ]]; then
+ local model action
+ action=${cur#@(Experimental|Nightly|Continuous)}
+ model=${cur%"$action"}
+ COMPREPLY=( $( compgen -W 'Start Update Configure Build Test
+ Coverage Submit MemCheck' -P "$model" -- "$action" ) )
+ else
+ COMPREPLY=( $( compgen -W 'Experimental Nightly Continuous' \
+ -- "$cur" ) )
+ compopt -o nospace
+ fi
+ return
+ ;;
+ -M|--test-model)
+ COMPREPLY=( $( compgen -W 'Experimental Nightly Continuous' -- \
+ "$cur" ) )
+ return
+ ;;
+ -T|--test-action)
+ COMPREPLY=( $( compgen -W 'Start Update Configure Build Test
+ Coverage Submit MemCheck' -- "$cur" ) )
+ return
+ ;;
+ -S|--script|-SP|--script-new-process)
+ _filedir '@(cmake|ctest)'
+ return
+ ;;
+ --interactive-debug-mode)
+ COMPREPLY=( $( compgen -W '0 1' -- "$cur" ) )
+ return
+ ;;
+ --help-command)
+ COMPREPLY=( $( compgen -W '$( ctest --help-command-list 2>/dev/null|
+ grep -v "^ctest version " )' -- "$cur" ) )
+ return
+ ;;
+ esac
+
+ if [[ "$cur" == -* ]]; then
+ COMPREPLY=( $(compgen -W '$( _parse_help "$1" --help )' -- ${cur}) )
+ [[ $COMPREPLY == *= ]] && compopt -o nospace
+ [[ $COMPREPLY ]] && return
+ fi
+
+ _filedir
+} &&
+complete -F _ctest ctest
+
+# ex: ts=4 sw=4 et filetype=sh
diff --git a/Docs/cmake-help.vim b/Auxiliary/cmake-help.vim
index 17cfa838e..17cfa838e 100644
--- a/Docs/cmake-help.vim
+++ b/Auxiliary/cmake-help.vim
diff --git a/Auxiliary/cmake-indent.vim b/Auxiliary/cmake-indent.vim
new file mode 100644
index 000000000..fa088e4dd
--- /dev/null
+++ b/Auxiliary/cmake-indent.vim
@@ -0,0 +1,93 @@
+" =============================================================================
+"
+" Program: CMake - Cross-Platform Makefile Generator
+" Module: $RCSfile$
+" Language: VIM
+" Date: $Date$
+" Version: $Revision$
+"
+" =============================================================================
+
+" Vim indent file
+" Language: CMake (ft=cmake)
+" Author: Andy Cedilnik <andy.cedilnik@kitware.com>
+" Maintainer: Karthik Krishnan <karthik.krishnan@kitware.com>
+" Last Change: $Date$
+" Version: $Revision$
+"
+" Licence: The CMake license applies to this file. See
+" https://cmake.org/licensing
+" This implies that distribution with Vim is allowed
+
+if exists("b:did_indent")
+ finish
+endif
+let b:did_indent = 1
+
+setlocal indentexpr=CMakeGetIndent(v:lnum)
+setlocal indentkeys+==ENDIF(,ENDFOREACH(,ENDMACRO(,ELSE(,ELSEIF(,ENDWHILE(
+
+" Only define the function once.
+if exists("*CMakeGetIndent")
+ finish
+endif
+
+fun! CMakeGetIndent(lnum)
+ let this_line = getline(a:lnum)
+
+ " Find a non-blank line above the current line.
+ let lnum = a:lnum
+ let lnum = prevnonblank(lnum - 1)
+ let previous_line = getline(lnum)
+
+ " Hit the start of the file, use zero indent.
+ if lnum == 0
+ return 0
+ endif
+
+ let ind = indent(lnum)
+
+ let or = '\|'
+ " Regular expressions used by line indentation function.
+ let cmake_regex_comment = '#.*'
+ let cmake_regex_identifier = '[A-Za-z][A-Za-z0-9_]*'
+ let cmake_regex_quoted = '"\([^"\\]\|\\.\)*"'
+ let cmake_regex_arguments = '\(' . cmake_regex_quoted .
+ \ or . '\$(' . cmake_regex_identifier . ')' .
+ \ or . '[^()\\#"]' . or . '\\.' . '\)*'
+
+ let cmake_indent_comment_line = '^\s*' . cmake_regex_comment
+ let cmake_indent_blank_regex = '^\s*$'
+ let cmake_indent_open_regex = '^\s*' . cmake_regex_identifier .
+ \ '\s*(' . cmake_regex_arguments .
+ \ '\(' . cmake_regex_comment . '\)\?$'
+
+ let cmake_indent_close_regex = '^' . cmake_regex_arguments .
+ \ ')\s*' .
+ \ '\(' . cmake_regex_comment . '\)\?$'
+
+ let cmake_indent_begin_regex = '^\s*\(IF\|MACRO\|FOREACH\|ELSE\|ELSEIF\|WHILE\|FUNCTION\)\s*('
+ let cmake_indent_end_regex = '^\s*\(ENDIF\|ENDFOREACH\|ENDMACRO\|ELSE\|ELSEIF\|ENDWHILE\|ENDFUNCTION\)\s*('
+
+ " Add
+ if previous_line =~? cmake_indent_comment_line " Handle comments
+ let ind = ind
+ else
+ if previous_line =~? cmake_indent_begin_regex
+ let ind = ind + &sw
+ endif
+ if previous_line =~? cmake_indent_open_regex
+ let ind = ind + &sw
+ endif
+ endif
+
+ " Subtract
+ if this_line =~? cmake_indent_end_regex
+ let ind = ind - &sw
+ endif
+ if previous_line =~? cmake_indent_close_regex
+ let ind = ind - &sw
+ endif
+
+ return ind
+endfun
diff --git a/Auxiliary/cmake-mode.el b/Auxiliary/cmake-mode.el
new file mode 100644
index 000000000..08ac4905e
--- /dev/null
+++ b/Auxiliary/cmake-mode.el
@@ -0,0 +1,398 @@
+;;; cmake-mode.el --- major-mode for editing CMake sources
+
+;=============================================================================
+; CMake - Cross Platform Makefile Generator
+; Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+;
+; Distributed under the OSI-approved BSD License (the "License");
+; see accompanying file Copyright.txt for details.
+;
+; This software is distributed WITHOUT ANY WARRANTY; without even the
+; implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+; See the License for more information.
+;=============================================================================
+
+;------------------------------------------------------------------------------
+
+;;; Commentary:
+
+;; Provides syntax highlighting and indentation for CMakeLists.txt and
+;; *.cmake source files.
+;;
+;; Add this code to your .emacs file to use the mode:
+;;
+;; (setq load-path (cons (expand-file-name "/dir/with/cmake-mode") load-path))
+;; (require 'cmake-mode)
+
+;------------------------------------------------------------------------------
+
+;;; Code:
+;;
+;; cmake executable variable used to run cmake --help-command
+;; on commands in cmake-mode
+;;
+;; cmake-command-help Written by James Bigler
+;;
+
+(defcustom cmake-mode-cmake-executable "cmake"
+ "*The name of the cmake executable.
+
+This can be either absolute or looked up in $PATH. You can also
+set the path with these commands:
+ (setenv \"PATH\" (concat (getenv \"PATH\") \";C:\\\\Program Files\\\\CMake 2.8\\\\bin\"))
+ (setenv \"PATH\" (concat (getenv \"PATH\") \":/usr/local/cmake/bin\"))"
+ :type 'file
+ :group 'cmake)
+
+;; Keywords
+(defconst cmake-keywords-block-open '("IF" "MACRO" "FOREACH" "ELSE" "ELSEIF" "WHILE" "FUNCTION"))
+(defconst cmake-keywords-block-close '("ENDIF" "ENDFOREACH" "ENDMACRO" "ELSE" "ELSEIF" "ENDWHILE" "ENDFUNCTION"))
+(defconst cmake-keywords
+ (let ((kwds (append cmake-keywords-block-open cmake-keywords-block-close nil)))
+ (delete-dups kwds)))
+
+;; Regular expressions used by line indentation function.
+;;
+(defconst cmake-regex-blank "^[ \t]*$")
+(defconst cmake-regex-comment "#.*")
+(defconst cmake-regex-paren-left "(")
+(defconst cmake-regex-paren-right ")")
+(defconst cmake-regex-argument-quoted
+ (rx ?\" (* (or (not (any ?\" ?\\)) (and ?\\ anything))) ?\"))
+(defconst cmake-regex-argument-unquoted
+ (rx (or (not (any space "()#\"\\\n")) (and ?\\ nonl))
+ (* (or (not (any space "()#\\\n")) (and ?\\ nonl)))))
+(defconst cmake-regex-token
+ (rx-to-string `(group (or (regexp ,cmake-regex-comment)
+ ?( ?)
+ (regexp ,cmake-regex-argument-unquoted)
+ (regexp ,cmake-regex-argument-quoted)))))
+(defconst cmake-regex-indented
+ (rx-to-string `(and bol (* (group (or (regexp ,cmake-regex-token) (any space ?\n)))))))
+(defconst cmake-regex-block-open
+ (rx-to-string `(and symbol-start (or ,@(append cmake-keywords-block-open
+ (mapcar 'downcase cmake-keywords-block-open))) symbol-end)))
+(defconst cmake-regex-block-close
+ (rx-to-string `(and symbol-start (or ,@(append cmake-keywords-block-close
+ (mapcar 'downcase cmake-keywords-block-close))) symbol-end)))
+(defconst cmake-regex-close
+ (rx-to-string `(and bol (* space) (regexp ,cmake-regex-block-close)
+ (* space) (regexp ,cmake-regex-paren-left))))
+
+;------------------------------------------------------------------------------
+
+;; Line indentation helper functions
+
+(defun cmake-line-starts-inside-string ()
+ "Determine whether the beginning of the current line is in a string."
+ (save-excursion
+ (beginning-of-line)
+ (let ((parse-end (point)))
+ (goto-char (point-min))
+ (nth 3 (parse-partial-sexp (point) parse-end))
+ )
+ )
+ )
+
+(defun cmake-find-last-indented-line ()
+ "Move to the beginning of the last line that has meaningful indentation."
+ (let ((point-start (point))
+ region)
+ (forward-line -1)
+ (setq region (buffer-substring-no-properties (point) point-start))
+ (while (and (not (bobp))
+ (or (looking-at cmake-regex-blank)
+ (cmake-line-starts-inside-string)
+ (not (and (string-match cmake-regex-indented region)
+ (= (length region) (match-end 0))))))
+ (forward-line -1)
+ (setq region (buffer-substring-no-properties (point) point-start))
+ )
+ )
+ )
+
+;------------------------------------------------------------------------------
+
+;;
+;; Line indentation function.
+;;
+(defun cmake-indent ()
+ "Indent current line as CMake code."
+ (interactive)
+ (unless (cmake-line-starts-inside-string)
+ (if (bobp)
+ (cmake-indent-line-to 0)
+ (let (cur-indent)
+ (save-excursion
+ (beginning-of-line)
+ (let ((point-start (point))
+ (case-fold-search t) ;; case-insensitive
+ token)
+ ; Search back for the last indented line.
+ (cmake-find-last-indented-line)
+ ; Start with the indentation on this line.
+ (setq cur-indent (current-indentation))
+ ; Search forward counting tokens that adjust indentation.
+ (while (re-search-forward cmake-regex-token point-start t)
+ (setq token (match-string 0))
+ (when (or (string-match (concat "^" cmake-regex-paren-left "$") token)
+ (and (string-match cmake-regex-block-open token)
+ (looking-at (concat "[ \t]*" cmake-regex-paren-left))))
+ (setq cur-indent (+ cur-indent cmake-tab-width)))
+ (when (string-match (concat "^" cmake-regex-paren-right "$") token)
+ (setq cur-indent (- cur-indent cmake-tab-width)))
+ )
+ (goto-char point-start)
+ ;; If next token closes the block, decrease indentation
+ (when (looking-at cmake-regex-close)
+ (setq cur-indent (- cur-indent cmake-tab-width))
+ )
+ )
+ )
+ ; Indent this line by the amount selected.
+ (cmake-indent-line-to (max cur-indent 0))
+ )
+ )
+ )
+ )
+
+(defun cmake-point-in-indendation ()
+ (string-match "^[ \\t]*$" (buffer-substring (point-at-bol) (point))))
+
+(defun cmake-indent-line-to (column)
+ "Indent the current line to COLUMN.
+If point is within the existing indentation it is moved to the end of
+the indentation. Otherwise it retains the same position on the line"
+ (if (cmake-point-in-indendation)
+ (indent-line-to column)
+ (save-excursion (indent-line-to column))))
+
+;------------------------------------------------------------------------------
+
+;;
+;; Helper functions for buffer
+;;
+(defun cmake-unscreamify-buffer ()
+ "Convert all CMake commands to lowercase in buffer."
+ (interactive)
+ (save-excursion
+ (goto-char (point-min))
+ (while (re-search-forward "^\\([ \t]*\\)\\_<\\(\\(?:\\w\\|\\s_\\)+\\)\\_>\\([ \t]*(\\)" nil t)
+ (replace-match
+ (concat
+ (match-string 1)
+ (downcase (match-string 2))
+ (match-string 3))
+ t))
+ )
+ )
+
+;------------------------------------------------------------------------------
+
+;;
+;; Keyword highlighting regex-to-face map.
+;;
+(defconst cmake-font-lock-keywords
+ `((,(rx-to-string `(and symbol-start
+ (or ,@cmake-keywords
+ ,@(mapcar #'downcase cmake-keywords))
+ symbol-end))
+ . font-lock-keyword-face)
+ (,(rx symbol-start (group (+ (or word (syntax symbol)))) (* blank) ?\()
+ 1 font-lock-function-name-face)
+ (,(rx "${" (group (+(any alnum "-_+/."))) "}")
+ 1 font-lock-variable-name-face t)
+ )
+ "Highlighting expressions for CMake mode.")
+
+;------------------------------------------------------------------------------
+
+;; Syntax table for this mode.
+(defvar cmake-mode-syntax-table nil
+ "Syntax table for CMake mode.")
+(or cmake-mode-syntax-table
+ (setq cmake-mode-syntax-table
+ (let ((table (make-syntax-table)))
+ (modify-syntax-entry ?\( "()" table)
+ (modify-syntax-entry ?\) ")(" table)
+ (modify-syntax-entry ?# "<" table)
+ (modify-syntax-entry ?\n ">" table)
+ (modify-syntax-entry ?$ "'" table)
+ table)))
+
+;;
+;; User hook entry point.
+;;
+(defvar cmake-mode-hook nil)
+
+;;
+;; Indentation increment.
+;;
+(defvar cmake-tab-width 2)
+
+;------------------------------------------------------------------------------
+
+;; For compatibility with Emacs < 24
+(defalias 'cmake--parent-mode
+ (if (fboundp 'prog-mode) 'prog-mode 'fundamental-mode))
+
+;;------------------------------------------------------------------------------
+;; Mode definition.
+;;
+;;;###autoload
+(define-derived-mode cmake-mode cmake--parent-mode "CMake"
+ "Major mode for editing CMake source files."
+
+ ; Setup font-lock mode.
+ (set (make-local-variable 'font-lock-defaults) '(cmake-font-lock-keywords))
+ ; Setup indentation function.
+ (set (make-local-variable 'indent-line-function) 'cmake-indent)
+ ; Setup comment syntax.
+ (set (make-local-variable 'comment-start) "#"))
+
+; Help mode starts here
+
+
+;;;###autoload
+(defun cmake-command-run (type &optional topic buffer)
+ "Runs the command cmake with the arguments specified. The
+optional argument topic will be appended to the argument list."
+ (interactive "s")
+ (let* ((bufname (if buffer buffer (concat "*CMake" type (if topic "-") topic "*")))
+ (buffer (if (get-buffer bufname) (get-buffer bufname) (generate-new-buffer bufname)))
+ (command (concat cmake-mode-cmake-executable " " type " " topic))
+ ;; Turn of resizing of mini-windows for shell-command.
+ (resize-mini-windows nil)
+ )
+ (shell-command command buffer)
+ (save-selected-window
+ (select-window (display-buffer buffer 'not-this-window))
+ (cmake-mode)
+ (toggle-read-only t))
+ )
+ )
+
+;;;###autoload
+(defun cmake-help-list-commands ()
+ "Prints out a list of the cmake commands."
+ (interactive)
+ (cmake-command-run "--help-command-list")
+ )
+
+(defvar cmake-commands '() "List of available topics for --help-command.")
+(defvar cmake-help-command-history nil "Command read history.")
+(defvar cmake-modules '() "List of available topics for --help-module.")
+(defvar cmake-help-module-history nil "Module read history.")
+(defvar cmake-variables '() "List of available topics for --help-variable.")
+(defvar cmake-help-variable-history nil "Variable read history.")
+(defvar cmake-properties '() "List of available topics for --help-property.")
+(defvar cmake-help-property-history nil "Property read history.")
+(defvar cmake-help-complete-history nil "Complete help read history.")
+(defvar cmake-string-to-list-symbol
+ '(("command" cmake-commands cmake-help-command-history)
+ ("module" cmake-modules cmake-help-module-history)
+ ("variable" cmake-variables cmake-help-variable-history)
+ ("property" cmake-properties cmake-help-property-history)
+ ))
+
+(defun cmake-get-list (listname)
+ "If the value of LISTVAR is nil, run cmake --help-LISTNAME-list
+and store the result as a list in LISTVAR."
+ (let ((listvar (car (cdr (assoc listname cmake-string-to-list-symbol)))))
+ (if (not (symbol-value listvar))
+ (let ((temp-buffer-name "*CMake Temporary*"))
+ (save-window-excursion
+ (cmake-command-run (concat "--help-" listname "-list") nil temp-buffer-name)
+ (with-current-buffer temp-buffer-name
+ (set listvar (cdr (split-string (buffer-substring-no-properties (point-min) (point-max)) "\n" t))))))
+ (symbol-value listvar)
+ ))
+ )
+
+(require 'thingatpt)
+(defun cmake-symbol-at-point ()
+ (let ((symbol (symbol-at-point)))
+ (and (not (null symbol))
+ (symbol-name symbol))))
+
+(defun cmake-help-type (type)
+ (let* ((default-entry (cmake-symbol-at-point))
+ (history (car (cdr (cdr (assoc type cmake-string-to-list-symbol)))))
+ (input (completing-read
+ (format "CMake %s: " type) ; prompt
+ (cmake-get-list type) ; completions
+ nil ; predicate
+ t ; require-match
+ default-entry ; initial-input
+ history
+ )))
+ (if (string= input "")
+ (error "No argument given")
+ input))
+ )
+
+;;;###autoload
+(defun cmake-help-command ()
+ "Prints out the help message for the command the cursor is on."
+ (interactive)
+ (cmake-command-run "--help-command" (cmake-help-type "command") "*CMake Help*"))
+
+;;;###autoload
+(defun cmake-help-module ()
+ "Prints out the help message for the module the cursor is on."
+ (interactive)
+ (cmake-command-run "--help-module" (cmake-help-type "module") "*CMake Help*"))
+
+;;;###autoload
+(defun cmake-help-variable ()
+ "Prints out the help message for the variable the cursor is on."
+ (interactive)
+ (cmake-command-run "--help-variable" (cmake-help-type "variable") "*CMake Help*"))
+
+;;;###autoload
+(defun cmake-help-property ()
+ "Prints out the help message for the property the cursor is on."
+ (interactive)
+ (cmake-command-run "--help-property" (cmake-help-type "property") "*CMake Help*"))
+
+;;;###autoload
+(defun cmake-help ()
+ "Queries for any of the four available help topics and prints out the approriate page."
+ (interactive)
+ (let* ((default-entry (cmake-symbol-at-point))
+ (command-list (cmake-get-list "command"))
+ (variable-list (cmake-get-list "variable"))
+ (module-list (cmake-get-list "module"))
+ (property-list (cmake-get-list "property"))
+ (all-words (append command-list variable-list module-list property-list))
+ (input (completing-read
+ "CMake command/module/variable/property: " ; prompt
+ all-words ; completions
+ nil ; predicate
+ t ; require-match
+ default-entry ; initial-input
+ 'cmake-help-complete-history
+ )))
+ (if (string= input "")
+ (error "No argument given")
+ (if (member input command-list)
+ (cmake-command-run "--help-command" input "*CMake Help*")
+ (if (member input variable-list)
+ (cmake-command-run "--help-variable" input "*CMake Help*")
+ (if (member input module-list)
+ (cmake-command-run "--help-module" input "*CMake Help*")
+ (if (member input property-list)
+ (cmake-command-run "--help-property" input "*CMake Help*")
+ (error "Not a know help topic.") ; this really should not happen
+ ))))))
+ )
+
+;;;###autoload
+(progn
+ (add-to-list 'auto-mode-alist '("CMakeLists\\.txt\\'" . cmake-mode))
+ (add-to-list 'auto-mode-alist '("\\.cmake\\'" . cmake-mode)))
+
+; This file provides cmake-mode.
+(provide 'cmake-mode)
+
+;;; cmake-mode.el ends here
diff --git a/Auxiliary/cmake-syntax.vim b/Auxiliary/cmake-syntax.vim
new file mode 100644
index 000000000..624a8c4f3
--- /dev/null
+++ b/Auxiliary/cmake-syntax.vim
@@ -0,0 +1,89 @@
+" =============================================================================
+"
+" Program: CMake - Cross-Platform Makefile Generator
+" Module: $RCSfile$
+" Language: VIM
+" Date: $Date$
+" Version: $Revision$
+"
+" =============================================================================
+
+" Vim syntax file
+" Language: CMake
+" Author: Andy Cedilnik <andy.cedilnik@kitware.com>
+" Maintainer: Karthik Krishnan <karthik.krishnan@kitware.com>
+" Last Change: $Date$
+" Version: $Revision$
+"
+" Licence: The CMake license applies to this file. See
+" https://cmake.org/licensing
+" This implies that distribution with Vim is allowed
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+ syntax clear
+elseif exists("b:current_syntax")
+ finish
+endif
+
+syn case ignore
+syn match cmakeEscaped /\(\\\\\|\\"\|\\n\|\\t\)/ contained
+syn region cmakeComment start="#" end="$" contains=cmakeTodo
+syn region cmakeRegistry start=/\[/ end=/]/
+ \ contained oneline contains=CONTAINED,cmakeTodo,cmakeEscaped
+syn region cmakeVariableValue start=/\${/ end=/}/
+ \ contained oneline contains=CONTAINED,cmakeTodo
+syn region cmakeEnvironment start=/\$ENV{/ end=/}/
+ \ contained oneline contains=CONTAINED,cmakeTodo
+syn region cmakeString start=/"/ end=/"/
+ \ contains=CONTAINED,cmakeTodo,cmakeOperators
+syn region cmakeArguments start=/(/ end=/)/
+ \ contains=ALLBUT,cmakeArguments,cmakeTodo
+syn keyword cmakeSystemVariables
+ \ WIN32 UNIX APPLE CYGWIN BORLAND MINGW MSVC MSVC_IDE MSVC60 MSVC70 MSVC71 MSVC80 MSVC90
+syn keyword cmakeOperators
+ \ ABSOLUTE AND BOOL CACHE COMMAND DEFINED DOC EQUAL EXISTS EXT FALSE GREATER INTERNAL LESS MATCHES NAME NAMES NAME_WE NOT OFF ON OR PATH PATHS PROGRAM STREQUAL STRGREATER STRING STRLESS TRUE
+ \ contained
+syn keyword cmakeDeprecated ABSTRACT_FILES BUILD_NAME SOURCE_FILES SOURCE_FILES_REMOVE VTK_MAKE_INSTANTIATOR VTK_WRAP_JAVA VTK_WRAP_PYTHON VTK_WRAP_TCL WRAP_EXCLUDE_FILES
+ \ nextgroup=cmakeArguments
+
+" The keywords are generated as: cmake --help-command-list | tr "\n" " " | tr "[:lower:]" "[:upper:]"
+syn keyword cmakeStatement
+ \ ADD_COMPILE_OPTIONS ADD_CUSTOM_COMMAND ADD_CUSTOM_TARGET ADD_DEFINITIONS ADD_DEPENDENCIES ADD_EXECUTABLE ADD_LIBRARY ADD_SUBDIRECTORY ADD_TEST AUX_SOURCE_DIRECTORY BREAK BUILD_COMMAND BUILD_NAME CMAKE_HOST_SYSTEM_INFORMATION CMAKE_MINIMUM_REQUIRED CMAKE_POLICY CONFIGURE_FILE CREATE_TEST_SOURCELIST CTEST_BUILD CTEST_CONFIGURE CTEST_COVERAGE CTEST_EMPTY_BINARY_DIRECTORY CTEST_MEMCHECK CTEST_READ_CUSTOM_FILES CTEST_RUN_SCRIPT CTEST_SLEEP CTEST_START CTEST_SUBMIT CTEST_TEST CTEST_UPDATE CTEST_UPLOAD DEFINE_PROPERTY ELSE ELSEIF ENABLE_LANGUAGE ENABLE_TESTING ENDFOREACH ENDFUNCTION ENDIF ENDMACRO ENDWHILE EXEC_PROGRAM EXECUTE_PROCESS EXPORT EXPORT_LIBRARY_DEPENDENCIES FILE FIND_FILE FIND_LIBRARY FIND_PACKAGE FIND_PATH FIND_PROGRAM FLTK_WRAP_UI FOREACH FUNCTION GET_CMAKE_PROPERTY GET_DIRECTORY_PROPERTY GET_FILENAME_COMPONENT GET_PROPERTY GET_SOURCE_FILE_PROPERTY GET_TARGET_PROPERTY GET_TEST_PROPERTY IF INCLUDE INCLUDE_DIRECTORIES INCLUDE_EXTERNAL_MSPROJECT INCLUDE_REGULAR_EXPRESSION INSTALL INSTALL_FILES INSTALL_PROGRAMS INSTALL_TARGETS LINK_DIRECTORIES LINK_LIBRARIES LIST LOAD_CACHE LOAD_COMMAND MACRO MAKE_DIRECTORY MARK_AS_ADVANCED MATH MESSAGE OPTION OUTPUT_REQUIRED_FILES PROJECT QT_WRAP_CPP QT_WRAP_UI REMOVE REMOVE_DEFINITIONS RETURN SEPARATE_ARGUMENTS SET SET_DIRECTORY_PROPERTIES SET_PROPERTY SET_SOURCE_FILES_PROPERTIES SET_TARGET_PROPERTIES SET_TESTS_PROPERTIES SITE_NAME SOURCE_GROUP STRING SUBDIR_DEPENDS SUBDIRS TARGET_COMPILE_DEFINITIONS TARGET_COMPILE_FEATURES TARGET_COMPILE_OPTIONS TARGET_INCLUDE_DIRECTORIES TARGET_LINK_LIBRARIES TARGET_SOURCES TRY_COMPILE TRY_RUN UNSET USE_MANGLED_MESA UTILITY_SOURCE VARIABLE_REQUIRES VARIABLE_WATCH WHILE WRITE_FILE
+ \ nextgroup=cmakeArguments
+syn keyword cmakeTodo
+ \ TODO FIXME XXX
+ \ contained
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_cmake_syntax_inits")
+ if version < 508
+ let did_cmake_syntax_inits = 1
+ command -nargs=+ HiLink hi link <args>
+ else
+ command -nargs=+ HiLink hi def link <args>
+ endif
+
+ HiLink cmakeStatement Statement
+ HiLink cmakeComment Comment
+ HiLink cmakeString String
+ HiLink cmakeVariableValue Type
+ HiLink cmakeRegistry Underlined
+ HiLink cmakeArguments Identifier
+ HiLink cmakeArgument Constant
+ HiLink cmakeEnvironment Special
+ HiLink cmakeOperators Operator
+ HiLink cmakeMacro PreProc
+ HiLink cmakeError Error
+ HiLink cmakeTodo TODO
+ HiLink cmakeEscaped Special
+
+ delcommand HiLink
+endif
+
+let b:current_syntax = "cmake"
+
+"EOF"
diff --git a/Utilities/cmake.m4 b/Auxiliary/cmake.m4
index a374a3bfb..a374a3bfb 100644
--- a/Utilities/cmake.m4
+++ b/Auxiliary/cmake.m4
diff --git a/CMakeCPack.cmake b/CMakeCPack.cmake
index 2495c4476..320327999 100644
--- a/CMakeCPack.cmake
+++ b/CMakeCPack.cmake
@@ -22,39 +22,37 @@ if(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS ON)
endif()
- include(${CMake_SOURCE_DIR}/Modules/InstallRequiredSystemLibraries.cmake)
+ if(CMake_INSTALL_DEPENDENCIES)
+ include(${CMake_SOURCE_DIR}/Modules/InstallRequiredSystemLibraries.cmake)
+ endif()
endif()
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "CMake is a build tool")
set(CPACK_PACKAGE_VENDOR "Kitware")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/Copyright.txt")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/Copyright.txt")
+ set(CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}")
set(CPACK_PACKAGE_VERSION "${CMake_VERSION}")
- set(CPACK_PACKAGE_INSTALL_DIRECTORY "CMake ${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}")
+ set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}")
set(CPACK_SOURCE_PACKAGE_FILE_NAME "cmake-${CMake_VERSION}")
- # Make this explicit here, rather than accepting the CPack default value,
- # so we can refer to it:
- set(CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}")
-
# Installers for 32- vs. 64-bit CMake:
# - Root install directory (displayed to end user at installer-run time)
# - "NSIS package/display name" (text used in the installer GUI)
# - Registry key used to store info about the installation
if(CMAKE_CL_64)
set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64")
- set(CPACK_NSIS_PACKAGE_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} (Win64)")
- set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION} (Win64)")
+ set(CPACK_NSIS_PACKAGE_NAME "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION} (Win64)")
else()
set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES")
- set(CPACK_NSIS_PACKAGE_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}")
- set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION}")
+ set(CPACK_NSIS_PACKAGE_NAME "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION}")
endif()
+ set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CPACK_NSIS_PACKAGE_NAME}")
if(NOT DEFINED CPACK_SYSTEM_NAME)
# make sure package is not Cygwin-unknown, for Cygwin just
# cygwin is good for the system name
- if("${CMAKE_SYSTEM_NAME}" STREQUAL "CYGWIN")
+ if("x${CMAKE_SYSTEM_NAME}" STREQUAL "xCYGWIN")
set(CPACK_SYSTEM_NAME Cygwin)
else()
set(CPACK_SYSTEM_NAME ${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR})
@@ -63,11 +61,96 @@ if(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
if(${CPACK_SYSTEM_NAME} MATCHES Windows)
if(CMAKE_CL_64)
set(CPACK_SYSTEM_NAME win64-x64)
+ set(CPACK_IFW_TARGET_DIRECTORY "@RootDir@/Program Files/${CMAKE_PROJECT_NAME}")
else()
set(CPACK_SYSTEM_NAME win32-x86)
endif()
endif()
+ # Components
+ if(CMake_INSTALL_COMPONENTS)
+ set(_CPACK_IFW_COMPONENTS_ALL cmake ctest cpack)
+ if(APPLE)
+ list(APPEND _CPACK_IFW_COMPONENTS_ALL cmakexbuild)
+ endif()
+ if(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME)
+ set(_CPACK_IFW_COMPONENT_UNSPECIFIED_NAME
+ ${CMAKE_INSTALL_DEFAULT_COMPONENT_NAME})
+ else()
+ set(_CPACK_IFW_COMPONENT_UNSPECIFIED_NAME Unspecified)
+ endif()
+ list(APPEND _CPACK_IFW_COMPONENTS_ALL ${_CPACK_IFW_COMPONENT_UNSPECIFIED_NAME})
+ string(TOUPPER "${_CPACK_IFW_COMPONENT_UNSPECIFIED_NAME}"
+ _CPACK_IFW_COMPONENT_UNSPECIFIED_UNAME)
+ if(BUILD_CursesDialog)
+ list(APPEND _CPACK_IFW_COMPONENTS_ALL ccmake)
+ endif()
+ if(BUILD_QtDialog)
+ list(APPEND _CPACK_IFW_COMPONENTS_ALL cmake-gui)
+ set(_CPACK_IFW_COMPONENT_CMAKE-GUI_LICENSES "set(CPACK_IFW_COMPONENT_CMAKE-GUI_LICENSES
+ \"LGPLv2.1\" \"${CMake_SOURCE_DIR}/Licenses/LGPLv2.1.txt\")")
+ endif()
+ if(SPHINX_MAN)
+ list(APPEND _CPACK_IFW_COMPONENTS_ALL sphinx-man)
+ endif()
+ if(SPHINX_HTML)
+ list(APPEND _CPACK_IFW_COMPONENTS_ALL sphinx-html)
+ endif()
+ if(SPHINX_SINGLEHTML)
+ list(APPEND _CPACK_IFW_COMPONENTS_ALL sphinx-singlehtml)
+ endif()
+ if(SPHINX_QTHELP)
+ list(APPEND _CPACK_IFW_COMPONENTS_ALL sphinx-qthelp)
+ endif()
+ set(_CPACK_IFW_COMPONENTS_CONFIGURATION "
+ # Components
+ set(CPACK_COMPONENTS_ALL \"${_CPACK_IFW_COMPONENTS_ALL}\")
+ set(CPACK_COMPONENTS_GROUPING IGNORE)
+")
+ else()
+ if(BUILD_QtDialog AND CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL)
+ set(_CPACK_IFW_ADDITIONAL_LICENSES
+ "\"LGPLv2.1\" \"${CMake_SOURCE_DIR}/Licenses/LGPLv2.1.txt\"")
+ endif()
+ endif()
+
+ # Components scripts configuration
+ foreach(_script
+ CMake
+ CMake.Documentation.SphinxHTML)
+ configure_file("${CMake_SOURCE_DIR}/Source/QtIFW/${_script}.qs.in"
+ "${CMake_BINARY_DIR}/${_script}.qs" @ONLY)
+ endforeach()
+
+ if(${CMAKE_SYSTEM_NAME} MATCHES Windows)
+ set(_CPACK_IFW_PACKAGE_ICON
+ "set(CPACK_IFW_PACKAGE_ICON \"${CMake_SOURCE_DIR}/Source/QtDialog/CMakeSetup.ico\")")
+ if(BUILD_QtDialog)
+ set(_CPACK_IFW_SHORTCUT_OPTIONAL "${_CPACK_IFW_SHORTCUT_OPTIONAL}component.addOperation(\"CreateShortcut\", \"@TargetDir@/bin/cmake-gui.exe\", \"@StartMenuDir@/CMake (cmake-gui).lnk\");\n")
+ endif()
+ if(SPHINX_HTML)
+ set(_CPACK_IFW_SHORTCUT_OPTIONAL "${_CPACK_IFW_SHORTCUT_OPTIONAL}component.addOperation(\"CreateShortcut\", \"@TargetDir@/doc/cmake-${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}/html/index.html\", \"@StartMenuDir@/CMake Documentation.lnk\");\n")
+ endif()
+ configure_file("${CMake_SOURCE_DIR}/Source/QtIFW/installscript.qs.in"
+ "${CMake_BINARY_DIR}/installscript.qs" @ONLY
+ )
+ install(FILES "${CMake_SOURCE_DIR}/Source/QtIFW/cmake.org.html"
+ DESTINATION "${CMAKE_DOC_DIR}"
+ )
+ if(CMake_INSTALL_COMPONENTS)
+ set(_CPACK_IFW_PACKAGE_SCRIPT "${CMake_BINARY_DIR}/CMake.qs")
+ else()
+ set(_CPACK_IFW_PACKAGE_SCRIPT "${CMake_BINARY_DIR}/installscript.qs")
+ endif()
+ endif()
+
+ if(${CMAKE_SYSTEM_NAME} MATCHES Linux)
+ set(CPACK_IFW_TARGET_DIRECTORY "@HomeDir@/${CMAKE_PROJECT_NAME}")
+ set(CPACK_IFW_ADMIN_TARGET_DIRECTORY "@ApplicationsDir@/${CMAKE_PROJECT_NAME}")
+ endif()
+
+ set(_CPACK_IFW_PACKAGE_VERSION ${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}.${CMake_VERSION_PATCH})
+
if(NOT DEFINED CPACK_PACKAGE_FILE_NAME)
# if the CPACK_PACKAGE_FILE_NAME is not defined by the cache
# default to source package - system, on cygwin system is not
@@ -115,6 +198,17 @@ if(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
set(CPACK_WIX_UPGRADE_GUID "8ffd1d72-b7f1-11e2-8ee5-00238bca4991")
+ if(MSVC AND NOT "$ENV{WIX}" STREQUAL "")
+ set(WIX_CUSTOM_ACTION_ENABLED TRUE)
+ if(CMAKE_CONFIGURATION_TYPES)
+ set(WIX_CUSTOM_ACTION_MULTI_CONFIG TRUE)
+ else()
+ set(WIX_CUSTOM_ACTION_MULTI_CONFIG FALSE)
+ endif()
+ else()
+ set(WIX_CUSTOM_ACTION_ENABLED FALSE)
+ endif()
+
# Set the options file that needs to be included inside CMakeCPackOptions.cmake
set(QT_DIALOG_CPACK_OPTIONS_FILE ${CMake_BINARY_DIR}/Source/QtDialog/QtDialogCPack.cmake)
configure_file("${CMake_SOURCE_DIR}/CMakeCPackOptions.cmake.in"
diff --git a/CMakeCPackOptions.cmake.in b/CMakeCPackOptions.cmake.in
index 008a102b5..59ae224ea 100644
--- a/CMakeCPackOptions.cmake.in
+++ b/CMakeCPackOptions.cmake.in
@@ -13,22 +13,15 @@ if(CPACK_GENERATOR MATCHES "NSIS")
set(CPACK_PACKAGE_ICON "@CMake_SOURCE_DIR@/Utilities/Release\\CMakeInstall.bmp")
# tell cpack to create links to the doc files
set(CPACK_NSIS_MENU_LINKS
- "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake-gui.html" "cmake-gui Help"
- "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake.html" "CMake Help"
- "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake-properties.html"
- "CMake Properties and Variables Help"
- "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/ctest.html" "CTest Help"
- "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake-modules.html" "CMake Modules Help"
- "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake-commands.html" "CMake Commands Help"
- "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cpack.html" "CPack Help"
- "http://www.cmake.org" "CMake Web Site"
+ "@CMAKE_DOC_DIR@/html/index.html" "CMake Documentation"
+ "https://cmake.org" "CMake Web Site"
)
# Use the icon from cmake-gui for add-remove programs
set(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\cmake-gui.exe")
set(CPACK_NSIS_PACKAGE_NAME "@CPACK_NSIS_PACKAGE_NAME@")
set(CPACK_NSIS_DISPLAY_NAME "@CPACK_NSIS_PACKAGE_NAME@, a cross-platform, open-source build system")
- set(CPACK_NSIS_HELP_LINK "http://www.cmake.org")
+ set(CPACK_NSIS_HELP_LINK "https://cmake.org")
set(CPACK_NSIS_URL_INFO_ABOUT "http://www.kitware.com")
set(CPACK_NSIS_CONTACT @CPACK_PACKAGE_CONTACT@)
set(CPACK_NSIS_MODIFY_PATH ON)
@@ -38,6 +31,144 @@ endif()
# they might not if qt was not enabled for the build
include("@QT_DIALOG_CPACK_OPTIONS_FILE@" OPTIONAL)
+if(CPACK_GENERATOR MATCHES "IFW")
+
+ # Installer configuration
+ set(CPACK_IFW_PACKAGE_TITLE "CMake Build Tool")
+ set(CPACK_IFW_PRODUCT_URL "https://cmake.org")
+ @_CPACK_IFW_PACKAGE_ICON@
+ set(CPACK_IFW_PACKAGE_WINDOW_ICON
+ "@CMake_SOURCE_DIR@/Source/QtDialog/CMakeSetup128.png")
+ set(CPACK_IFW_PACKAGE_CONTROL_SCRIPT
+ "@CMake_SOURCE_DIR@/Source/QtIFW/controlscript.qs")
+
+ # Uninstaller configuration
+ set(CPACK_IFW_PACKAGE_MAINTENANCE_TOOL_NAME "cmake-maintenance")
+ @_CPACK_IFW_COMPONENTS_CONFIGURATION@
+ # Unspecified
+ set(CPACK_IFW_COMPONENT_@_CPACK_IFW_COMPONENT_UNSPECIFIED_UNAME@_VERSION
+ "@_CPACK_IFW_PACKAGE_VERSION@")
+
+ # Package configuration group
+ set(CPACK_IFW_PACKAGE_GROUP CMake)
+
+ # Group configuration
+
+ # CMake
+ set(CPACK_COMPONENT_GROUP_CMAKE_DISPLAY_NAME
+ "@CPACK_PACKAGE_NAME@")
+ set(CPACK_COMPONENT_GROUP_CMAKE_DESCRIPTION
+ "@CPACK_PACKAGE_DESCRIPTION_SUMMARY@")
+ set(CPACK_IFW_COMPONENT_GROUP_CMAKE_VERSION
+ "@_CPACK_IFW_PACKAGE_VERSION@")
+ set(CPACK_IFW_COMPONENT_GROUP_CMAKE_LICENSES
+ "@CPACK_PACKAGE_NAME@ Copyright" "@CPACK_RESOURCE_FILE_LICENSE@"
+ @_CPACK_IFW_ADDITIONAL_LICENSES@)
+ set(CPACK_IFW_COMPONENT_GROUP_CMAKE_SCRIPT "@_CPACK_IFW_PACKAGE_SCRIPT@")
+ set(CPACK_IFW_COMPONENT_GROUP_CMAKE_PRIORITY 100)
+
+ # Tools
+ set(CPACK_COMPONENT_GROUP_TOOLS_DISPLAY_NAME "Command-Line Tools")
+ set(CPACK_COMPONENT_GROUP_TOOLS_DESCRIPTION
+ "Command-Line Tools: cmake, ctest and cpack")
+ set(CPACK_COMPONENT_GROUP_TOOLS_PARENT_GROUP CMake)
+ set(CPACK_IFW_COMPONENT_GROUP_TOOLS_PRIORITY 90)
+ set(CPACK_IFW_COMPONENT_GROUP_TOOLS_VERSION "@_CPACK_IFW_PACKAGE_VERSION@")
+
+ set(CPACK_COMPONENT_CMAKE_DISPLAY_NAME "cmake")
+ set(CPACK_COMPONENT_CMAKE_DESCRIPTION
+ "The \"cmake\" executable is the CMake command-line interface")
+ set(CPACK_COMPONENT_CMAKE_REQUIRED TRUE)
+ set(CPACK_COMPONENT_CMAKE_GROUP Tools)
+ set(CPACK_IFW_COMPONENT_CMAKE_NAME "CMake")
+ set(CPACK_IFW_COMPONENT_CMAKE_PRIORITY 89)
+ set(CPACK_IFW_COMPONENT_CMAKE_VERSION "@_CPACK_IFW_PACKAGE_VERSION@")
+
+ set(CPACK_COMPONENT_CTEST_DISPLAY_NAME "ctest")
+ set(CPACK_COMPONENT_CTEST_DESCRIPTION
+ "The \"ctest\" executable is the CMake test driver program")
+ set(CPACK_COMPONENT_CTEST_REQUIRED TRUE)
+ set(CPACK_COMPONENT_CTEST_GROUP Tools)
+ set(CPACK_IFW_COMPONENT_CTEST_NAME "CTest")
+ set(CPACK_IFW_COMPONENT_CTEST_PRIORITY 88)
+ set(CPACK_IFW_COMPONENT_CTEST_VERSION "@_CPACK_IFW_PACKAGE_VERSION@")
+
+ set(CPACK_COMPONENT_CPACK_DISPLAY_NAME "cpack")
+ set(CPACK_COMPONENT_CPACK_DESCRIPTION
+ "The \"cpack\" executable is the CMake packaging program")
+ set(CPACK_COMPONENT_CPACK_REQUIRED TRUE)
+ set(CPACK_COMPONENT_CPACK_GROUP Tools)
+ set(CPACK_IFW_COMPONENT_CPACK_NAME "CPack")
+ set(CPACK_IFW_COMPONENT_CPACK_PRIORITY 87)
+ set(CPACK_IFW_COMPONENT_CPACK_VERSION "@_CPACK_IFW_PACKAGE_VERSION@")
+
+ set(CPACK_COMPONENT_CMAKEXBUILD_DISPLAY_NAME "cmakexbuild")
+ set(CPACK_COMPONENT_CMAKEXBUILD_DESCRIPTION
+ "The \"cmakexbuild\" executable is a wrapper program for \"xcodebuild\"")
+ set(CPACK_COMPONENT_CMAKEXBUILD_REQUIRED TRUE)
+ set(CPACK_COMPONENT_CMAKEXBUILD_GROUP Tools)
+ set(CPACK_IFW_COMPONENT_CMAKEXBUILD_NAME "CMakeXBuild")
+ set(CPACK_IFW_COMPONENT_CMAKEXBUILD_PRIORITY 86)
+ set(CPACK_IFW_COMPONENT_CMAKEXBUILD_VERSION "@_CPACK_IFW_PACKAGE_VERSION@")
+
+ # Dialogs
+ set(CPACK_COMPONENT_GROUP_DIALOGS_DISPLAY_NAME "Interactive Dialogs")
+ set(CPACK_COMPONENT_GROUP_DIALOGS_DESCRIPTION
+ "Interactive Dialogs with Console and GUI interfaces")
+ set(CPACK_COMPONENT_GROUP_DIALOGS_PARENT_GROUP CMake)
+ set(CPACK_IFW_COMPONENT_GROUP_DIALOGS_PRIORITY 80)
+ set(CPACK_IFW_COMPONENT_GROUP_DIALOGS_VERSION "@_CPACK_IFW_PACKAGE_VERSION@")
+
+ set(CPACK_COMPONENT_CMAKE-GUI_DISPLAY_NAME "cmake-gui")
+ set(CPACK_COMPONENT_CMAKE-GUI_GROUP Dialogs)
+ set(CPACK_IFW_COMPONENT_CMAKE-GUI_NAME "QtGUI")
+ set(CPACK_IFW_COMPONENT_CMAKE-GUI_SCRIPT
+ "@CMake_SOURCE_DIR@/Source/QtIFW/CMake.Dialogs.QtGUI.qs")
+ set(CPACK_IFW_COMPONENT_CMAKE-GUI_VERSION "@_CPACK_IFW_PACKAGE_VERSION@")
+ @_CPACK_IFW_COMPONENT_CMAKE-GUI_LICENSES@
+
+ set(CPACK_COMPONENT_CCMAKE_DISPLAY_NAME "ccmake")
+ set(CPACK_COMPONENT_CCMAKE_GROUP Dialogs)
+ set(CPACK_IFW_COMPONENT_CCMAKE_NAME "CursesGUI")
+ set(CPACK_IFW_COMPONENT_CCMAKE_VERSION "@_CPACK_IFW_PACKAGE_VERSION@")
+
+ # Documentation
+ set(CPACK_COMPONENT_GROUP_DOCUMENTATION_DISPLAY_NAME "Documentation")
+ set(CPACK_COMPONENT_GROUP_DOCUMENTATION_DESCRIPTION
+ "CMake Documentation in different formats (html, man, qch)")
+ set(CPACK_COMPONENT_GROUP_DOCUMENTATION_PARENT_GROUP CMake)
+ set(CPACK_IFW_COMPONENT_GROUP_DOCUMENTATION_PRIORITY 60)
+ set(CPACK_IFW_COMPONENT_GROUP_DOCUMENTATION_VERSION
+ "@_CPACK_IFW_PACKAGE_VERSION@")
+
+ set(CPACK_COMPONENT_SPHINX-MAN_DISPLAY_NAME "man")
+ set(CPACK_COMPONENT_SPHINX-MAN_GROUP Documentation)
+ set(CPACK_COMPONENT_SPHINX-MAN_DISABLED TRUE)
+ set(CPACK_IFW_COMPONENT_SPHINX-MAN_NAME "SphinxMan")
+ set(CPACK_IFW_COMPONENT_SPHINX-MAN_VERSION "@_CPACK_IFW_PACKAGE_VERSION@")
+
+ set(CPACK_COMPONENT_SPHINX-HTML_DISPLAY_NAME "HTML")
+ set(CPACK_COMPONENT_SPHINX-HTML_GROUP Documentation)
+ set(CPACK_IFW_COMPONENT_SPHINX-HTML_NAME "SphinxHTML")
+ set(CPACK_IFW_COMPONENT_SPHINX-HTML_SCRIPT
+ "@CMake_BINARY_DIR@/CMake.Documentation.SphinxHTML.qs")
+ set(CPACK_IFW_COMPONENT_SPHINX-HTML_VERSION "@_CPACK_IFW_PACKAGE_VERSION@")
+
+ set(CPACK_COMPONENT_SPHINX-SINGLEHTML_DISPLAY_NAME "Single HTML")
+ set(CPACK_COMPONENT_SPHINX-SINGLEHTML_GROUP Documentation)
+ set(CPACK_COMPONENT_SPHINX-SINGLEHTML_DISABLED TRUE)
+ set(CPACK_IFW_COMPONENT_SPHINX-SINGLEHTML_NAME "SphinxSingleHTML")
+ set(CPACK_IFW_COMPONENT_SPHINX-SINGLEHTML_VERSION
+ "@_CPACK_IFW_PACKAGE_VERSION@")
+
+ set(CPACK_COMPONENT_SPHINX-QTHELP_DISPLAY_NAME "Qt Compressed Help")
+ set(CPACK_COMPONENT_SPHINX-QTHELP_GROUP Documentation)
+ set(CPACK_COMPONENT_SPHINX-QTHELP_DISABLED TRUE)
+ set(CPACK_IFW_COMPONENT_SPHINX-QTHELP_NAME "SphinxQtHelp")
+ set(CPACK_IFW_COMPONENT_SPHINX-QTHELP_VERSION "@_CPACK_IFW_PACKAGE_VERSION@")
+
+endif()
+
if(CPACK_GENERATOR MATCHES "CygwinSource")
# when packaging source make sure the .build directory is not included
set(CPACK_SOURCE_IGNORE_FILES
@@ -52,26 +183,108 @@ if("${CPACK_GENERATOR}" STREQUAL "PackageMaker")
endif()
endif()
+if("${CPACK_GENERATOR}" STREQUAL "DragNDrop")
+ set(CPACK_DMG_BACKGROUND_IMAGE
+ "@CMake_SOURCE_DIR@/Packaging/CMakeDMGBackground.tif")
+ set(CPACK_DMG_DS_STORE_SETUP_SCRIPT
+ "@CMake_SOURCE_DIR@/Packaging/CMakeDMGSetup.scpt")
+endif()
+
if("${CPACK_GENERATOR}" STREQUAL "WIX")
# Reset CPACK_PACKAGE_VERSION to deal with WiX restriction.
# But the file names still use the full CMake_VERSION value:
set(CPACK_PACKAGE_FILE_NAME
- "${CPACK_PACKAGE_NAME}-@CMake_VERSION@-${CPACK_SYSTEM_NAME}")
+ "cmake-@CMake_VERSION@-${CPACK_SYSTEM_NAME}")
set(CPACK_SOURCE_PACKAGE_FILE_NAME
- "${CPACK_PACKAGE_NAME}-@CMake_VERSION@-Source")
+ "cmake-@CMake_VERSION@")
if(NOT CPACK_WIX_SIZEOF_VOID_P)
set(CPACK_WIX_SIZEOF_VOID_P "@CMAKE_SIZEOF_VOID_P@")
endif()
set(CPACK_PACKAGE_VERSION
- "@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@.@CMake_VERSION_PATCH@")
+ "@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@")
# WIX installers require at most a 4 component version number, where
# each component is an integer between 0 and 65534 inclusive
- set(tweak "@CMake_VERSION_TWEAK@")
- if(tweak MATCHES "^[0-9]+$")
- if(tweak GREATER 0 AND tweak LESS 65535)
- set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}.${tweak}")
+ set(patch "@CMake_VERSION_PATCH@")
+ if(patch MATCHES "^[0-9]+$" AND patch LESS 65535)
+ set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}.${patch}")
+ endif()
+
+ set(CPACK_WIX_PROPERTY_ARPURLINFOABOUT "https://cmake.org")
+
+ set(CPACK_WIX_PROPERTY_ARPCONTACT "@CPACK_PACKAGE_CONTACT@")
+
+ set(CPACK_WIX_PROPERTY_ARPCOMMENTS
+ "CMake is a cross-platform, open-source build system."
+ )
+
+ set(CPACK_WIX_PRODUCT_ICON
+ "@CMake_SOURCE_DIR@/Utilities/Release/CMakeLogo.ico"
+ )
+
+ set_property(INSTALL "@CMAKE_DOC_DIR@/html/index.html" PROPERTY
+ CPACK_START_MENU_SHORTCUTS "CMake Documentation"
+ )
+
+ set_property(INSTALL "cmake.org.html" PROPERTY
+ CPACK_START_MENU_SHORTCUTS "CMake Web Site"
+ )
+
+ set(CPACK_WIX_LIGHT_EXTRA_FLAGS "-dcl:high")
+
+ set(CPACK_WIX_UI_BANNER
+ "@CMake_SOURCE_DIR@/Utilities/Release/WiX/ui_banner.jpg"
+ )
+
+ set(CPACK_WIX_UI_DIALOG
+ "@CMake_SOURCE_DIR@/Utilities/Release/WiX/ui_dialog.jpg"
+ )
+
+ set(CPACK_WIX_EXTRA_SOURCES
+ "@CMake_SOURCE_DIR@/Utilities/Release/WiX/install_dir.wxs"
+ "@CMake_SOURCE_DIR@/Utilities/Release/WiX/cmake_extra_dialog.wxs"
+ )
+
+ set(_WIX_CUSTOM_ACTION_ENABLED "@WIX_CUSTOM_ACTION_ENABLED@")
+ if(_WIX_CUSTOM_ACTION_ENABLED)
+ list(APPEND CPACK_WIX_EXTRA_SOURCES
+ "@CMake_SOURCE_DIR@/Utilities/Release/WiX/cmake_nsis_overwrite_dialog.wxs"
+ )
+ list(APPEND CPACK_WIX_CANDLE_EXTRA_FLAGS -dCHECK_NSIS=1)
+
+ set(_WIX_CUSTOM_ACTION_MULTI_CONFIG "@WIX_CUSTOM_ACTION_MULTI_CONFIG@")
+ if(_WIX_CUSTOM_ACTION_MULTI_CONFIG)
+ if(CPACK_BUILD_CONFIG)
+ set(_WIX_CUSTOM_ACTION_CONFIG "${CPACK_BUILD_CONFIG}")
+ else()
+ set(_WIX_CUSTOM_ACTION_CONFIG "Release")
+ endif()
+
+ list(APPEND CPACK_WIX_EXTRA_SOURCES
+ "@CMake_BINARY_DIR@/Utilities/Release/WiX/custom_action_dll-${_WIX_CUSTOM_ACTION_CONFIG}.wxs")
+ else()
+ list(APPEND CPACK_WIX_EXTRA_SOURCES
+ "@CMake_BINARY_DIR@/Utilities/Release/WiX/custom_action_dll.wxs")
endif()
endif()
+
+ set(CPACK_WIX_UI_REF "CMakeUI_InstallDir")
+
+ set(CPACK_WIX_PATCH_FILE
+ "@CMake_SOURCE_DIR@/Utilities/Release/WiX/patch_path_env.xml"
+ )
+
+ set(CPACK_WIX_TEMPLATE
+ "@CMake_SOURCE_DIR@/Utilities/Release/WiX/WIX.template.in"
+ )
+
+ set(BUILD_QtDialog "@BUILD_QtDialog@")
+
+ if(BUILD_QtDialog)
+ list(APPEND CPACK_WIX_PATCH_FILE
+ "@CMake_SOURCE_DIR@/Utilities/Release/WiX/patch_desktop_shortcut.xml"
+ )
+ list(APPEND CPACK_WIX_CANDLE_EXTRA_FLAGS -dBUILD_QtDialog=1)
+ endif()
endif()
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1fbbe08a1..9381f357f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,8 +9,13 @@
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
-cmake_minimum_required(VERSION 2.8.2 FATAL_ERROR)
-set(CMAKE_LEGACY_CYGWIN_WIN32 0) # Remove when CMake >= 2.8.4 is required
+cmake_minimum_required(VERSION 2.8.4 FATAL_ERROR)
+if(POLICY CMP0025)
+ cmake_policy(SET CMP0025 NEW)
+endif()
+if(POLICY CMP0053)
+ cmake_policy(SET CMP0053 NEW)
+endif()
project(CMake)
if(CMAKE_BOOTSTRAP)
@@ -19,7 +24,9 @@ if(CMAKE_BOOTSTRAP)
unset(CMAKE_BOOTSTRAP CACHE)
endif()
-set(CMake_BIN_DIR ${CMake_BINARY_DIR}/bin)
+if(NOT CMake_TEST_EXTERNAL_CMAKE)
+ set(CMake_BIN_DIR ${CMake_BINARY_DIR}/bin)
+endif()
if("${CMake_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}")
# Disallow architecture-specific try_run. It may not run on the host.
@@ -32,6 +39,50 @@ if("${CMake_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}")
endmacro()
endif()
+# Use most-recent available language dialects with GNU and Clang
+if(NOT DEFINED CMAKE_C_STANDARD AND NOT CMake_NO_C_STANDARD)
+ include(${CMake_SOURCE_DIR}/Source/Checks/cm_c11_thread_local.cmake)
+ if(NOT CMake_C11_THREAD_LOCAL_BROKEN)
+ set(CMAKE_C_STANDARD 11)
+ else()
+ set(CMAKE_C_STANDARD 99)
+ endif()
+endif()
+if(NOT DEFINED CMAKE_CXX_STANDARD AND NOT CMake_NO_CXX_STANDARD)
+ include(${CMake_SOURCE_DIR}/Source/Checks/cm_cxx14_cstdio.cmake)
+ if(NOT CMake_CXX14_CSTDIO_BROKEN)
+ set(CMAKE_CXX_STANDARD 14)
+ else()
+ set(CMAKE_CXX_STANDARD 11)
+ endif()
+endif()
+if(NOT CMake_TEST_EXTERNAL_CMAKE)
+ include(${CMake_SOURCE_DIR}/Source/Checks/cm_cxx11_unordered_map.cmake)
+endif()
+
+# option to set the internal encoding of CMake to UTF-8
+option(CMAKE_ENCODING_UTF8 "Use UTF-8 encoding internally." ON)
+mark_as_advanced(CMAKE_ENCODING_UTF8)
+if(CMAKE_ENCODING_UTF8)
+ set(KWSYS_ENCODING_DEFAULT_CODEPAGE CP_UTF8)
+endif()
+
+# option to use COMPONENT with install command
+option(CMake_INSTALL_COMPONENTS "Using components when installing" OFF)
+mark_as_advanced(CMake_INSTALL_COMPONENTS)
+macro(CMake_OPTIONAL_COMPONENT NAME)
+ if(CMake_INSTALL_COMPONENTS)
+ set(COMPONENT COMPONENT ${NAME})
+ else()
+ set(COMPONENT)
+ endif()
+endmacro()
+
+# option to disable installing 3rd-party dependencies
+option(CMake_INSTALL_DEPENDENCIES
+ "Whether to install 3rd-party runtime dependencies" OFF)
+mark_as_advanced(CMake_INSTALL_DEPENDENCIES)
+
#-----------------------------------------------------------------------
# a macro to deal with system libraries, implemented as a macro
# simply to improve readability of the main script
@@ -46,7 +97,7 @@ macro(CMAKE_HANDLE_SYSTEM_LIBRARIES)
# Allow the user to enable/disable all system utility library options by
# defining CMAKE_USE_SYSTEM_LIBRARIES or CMAKE_USE_SYSTEM_LIBRARY_${util}.
- set(UTILITIES BZIP2 CURL EXPAT LIBARCHIVE ZLIB)
+ set(UTILITIES BZIP2 CURL EXPAT FORM JSONCPP LIBARCHIVE LIBLZMA ZLIB)
foreach(util ${UTILITIES})
if(NOT DEFINED CMAKE_USE_SYSTEM_LIBRARY_${util}
AND DEFINED CMAKE_USE_SYSTEM_LIBRARIES)
@@ -82,9 +133,18 @@ macro(CMAKE_HANDLE_SYSTEM_LIBRARIES)
"${CMAKE_USE_SYSTEM_LIBRARY_ZLIB}" "NOT CMAKE_USE_SYSTEM_LIBARCHIVE;NOT CMAKE_USE_SYSTEM_CURL" ON)
CMAKE_DEPENDENT_OPTION(CMAKE_USE_SYSTEM_BZIP2 "Use system-installed bzip2"
"${CMAKE_USE_SYSTEM_LIBRARY_BZIP2}" "NOT CMAKE_USE_SYSTEM_LIBARCHIVE" ON)
+ CMAKE_DEPENDENT_OPTION(CMAKE_USE_SYSTEM_LIBLZMA "Use system-installed liblzma"
+ "${CMAKE_USE_SYSTEM_LIBRARY_LIBLZMA}" "NOT CMAKE_USE_SYSTEM_LIBARCHIVE" ON)
+ option(CMAKE_USE_SYSTEM_FORM "Use system-installed libform" "${CMAKE_USE_SYSTEM_LIBRARY_FORM}")
+ option(CMAKE_USE_SYSTEM_JSONCPP "Use system-installed jsoncpp" "${CMAKE_USE_SYSTEM_LIBRARY_JSONCPP}")
+
+ # For now use system KWIML only if explicitly requested rather
+ # than activating via the general system libs options.
+ option(CMAKE_USE_SYSTEM_KWIML "Use system-installed KWIML" OFF)
+ mark_as_advanced(CMAKE_USE_SYSTEM_KWIML)
# Mention to the user what system libraries are being used.
- foreach(util ${UTILITIES})
+ foreach(util ${UTILITIES} KWIML)
if(CMAKE_USE_SYSTEM_${util})
message(STATUS "Using system-installed ${util}")
endif()
@@ -97,49 +157,12 @@ macro(CMAKE_HANDLE_SYSTEM_LIBRARIES)
endmacro()
-
-
-
-set(CMAKE_BUILD_ON_VISUAL_STUDIO 0)
-if(WIN32 AND NOT UNIX AND NOT BORLAND AND NOT MINGW )
- set(CMAKE_BUILD_ON_VISUAL_STUDIO 1)
-endif()
-
-
#-----------------------------------------------------------------------
# a macro to determine the generator and ctest executable to use
# for testing. Simply to improve readability of the main script.
#-----------------------------------------------------------------------
macro(CMAKE_SETUP_TESTING)
- if (NOT DART_ROOT)
- set(MAKEPROGRAM ${CMAKE_MAKE_PROGRAM})
- endif ()
-
if(BUILD_TESTING)
- set(CMAKE_TEST_GENERATOR "" CACHE STRING
- "Generator used when running tests")
- set(CMAKE_TEST_MAKEPROGRAM "" CACHE FILEPATH
- "Generator used when running tests")
- if(NOT CMAKE_TEST_GENERATOR)
- set(CMAKE_TEST_GENERATOR "${CMAKE_GENERATOR}")
- set(CMAKE_TEST_GENERATOR_TOOLSET "${CMAKE_GENERATOR_TOOLSET}")
- set(CMAKE_TEST_MAKEPROGRAM "${MAKEPROGRAM}")
- else()
- set(CMAKE_TEST_DIFFERENT_GENERATOR TRUE)
- set(CMAKE_TEST_GENERATOR_TOOLSET "")
- endif()
-
- # Are we testing with the MSVC compiler?
- set(CMAKE_TEST_MSVC 0)
- if(MSVC AND NOT CMAKE_TEST_DIFFERENT_GENERATOR)
- set(CMAKE_TEST_MSVC 1)
- else()
- if("${CMAKE_TEST_GENERATOR}" MATCHES "NMake" OR
- "${CMAKE_TEST_GENERATOR}" MATCHES "Visual Studio")
- set(CMAKE_TEST_MSVC 1)
- endif()
- endif()
-
set(CMAKE_TEST_SYSTEM_LIBRARIES 0)
foreach(util CURL EXPAT XMLRPC ZLIB)
if(CMAKE_USE_SYSTEM_${util})
@@ -152,9 +175,19 @@ macro(CMAKE_SETUP_TESTING)
# the ctest from this cmake is used for testing
# and not the ctest from the cmake building and testing
# cmake.
- set(CMAKE_CTEST_COMMAND "${CMake_BIN_DIR}/ctest")
- set(CMAKE_CMAKE_COMMAND "${CMake_BIN_DIR}/cmake")
- set(CMAKE_CPACK_COMMAND "${CMake_BIN_DIR}/cpack")
+ if(CMake_TEST_EXTERNAL_CMAKE)
+ set(CMAKE_CTEST_COMMAND "${CMake_TEST_EXTERNAL_CMAKE}/ctest")
+ set(CMAKE_CMAKE_COMMAND "${CMake_TEST_EXTERNAL_CMAKE}/cmake")
+ set(CMAKE_CPACK_COMMAND "${CMake_TEST_EXTERNAL_CMAKE}/cpack")
+ foreach(exe cmake ctest cpack)
+ add_executable(${exe} IMPORTED)
+ set_property(TARGET ${exe} PROPERTY IMPORTED_LOCATION ${CMake_TEST_EXTERNAL_CMAKE}/${exe})
+ endforeach()
+ else()
+ set(CMAKE_CTEST_COMMAND "${CMake_BIN_DIR}/ctest")
+ set(CMAKE_CMAKE_COMMAND "${CMake_BIN_DIR}/cmake")
+ set(CMAKE_CPACK_COMMAND "${CMake_BIN_DIR}/cpack")
+ endif()
endif()
# configure some files for testing
@@ -167,8 +200,6 @@ macro(CMAKE_SETUP_TESTING)
${CMake_BINARY_DIR}/Modules/.NoDartCoverage)
configure_file(${CMake_SOURCE_DIR}/CTestCustom.cmake.in
${CMake_BINARY_DIR}/CTestCustom.cmake @ONLY)
- configure_file(${CMake_SOURCE_DIR}/CTestCustom.ctest.in
- ${CMake_BINARY_DIR}/CTestCustom.ctest @ONLY)
if(BUILD_TESTING AND DART_ROOT)
configure_file(${CMake_SOURCE_DIR}/CMakeLogo.gif
${CMake_BINARY_DIR}/Testing/HTML/TestingResults/Icons/Logo.gif COPYONLY)
@@ -193,15 +224,8 @@ mark_as_advanced(CMAKE_USE_FOLDERS)
macro(CMAKE_SET_TARGET_FOLDER tgt folder)
if(CMAKE_USE_FOLDERS)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
-
- # Really, I just want this to be an "if(TARGET ${tgt})" ...
- # but I'm not sure that our min req'd., CMake 2.4.5 can handle
- # that... so I'm just activating this for now, with a version
- # compare, and only for MSVC builds.
- if(MSVC)
- if(NOT ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} LESS 2.8)
- set_property(TARGET "${tgt}" PROPERTY FOLDER "${folder}")
- endif()
+ if(MSVC AND TARGET ${tgt})
+ set_property(TARGET "${tgt}" PROPERTY FOLDER "${folder}")
endif()
else()
set_property(GLOBAL PROPERTY USE_FOLDERS OFF)
@@ -215,12 +239,6 @@ endmacro()
#-----------------------------------------------------------------------
macro (CMAKE_BUILD_UTILITIES)
#---------------------------------------------------------------------
- # Create the KWIML library for CMake.
- set(KWIML cmIML)
- set(KWIML_HEADER_ROOT ${CMake_BINARY_DIR}/Utilities)
- add_subdirectory(Utilities/KWIML)
-
- #---------------------------------------------------------------------
# Create the kwsys library for CMake.
set(KWSYS_NAMESPACE cmsys)
set(KWSYS_USE_SystemTools 1)
@@ -257,6 +275,20 @@ macro (CMAKE_BUILD_UTILITIES)
# (a macro defined in this file)
CMAKE_HANDLE_SYSTEM_LIBRARIES()
+ if(CMAKE_USE_SYSTEM_KWIML)
+ find_package(KWIML 1.0)
+ if(NOT KWIML_FOUND)
+ message(FATAL_ERROR "CMAKE_USE_SYSTEM_KWIML is ON but KWIML is not found!")
+ endif()
+ set(CMake_KWIML_LIBRARIES kwiml::kwiml)
+ else()
+ set(CMake_KWIML_LIBRARIES "")
+ if(BUILD_TESTING)
+ set(KWIML_TEST_ENABLE 1)
+ endif()
+ add_subdirectory(Utilities/KWIML)
+ endif()
+
#---------------------------------------------------------------------
# Build zlib library for Curl, CMake, and CTest.
set(CMAKE_ZLIB_HEADER "cm_zlib.h")
@@ -289,15 +321,19 @@ macro (CMAKE_BUILD_UTILITIES)
set(CURL_SPECIAL_ZLIB_H ${CMAKE_ZLIB_HEADER})
set(CURL_SPECIAL_LIBZ_INCLUDES ${CMAKE_ZLIB_INCLUDES})
set(CURL_SPECIAL_LIBZ ${CMAKE_ZLIB_LIBRARIES})
- option(CMAKE_BUILD_CURL_SHARED "Should curl be built shared" FALSE)
- if(NOT CMAKE_BUILD_CURL_SHARED)
- add_definitions(-DCURL_STATICLIB)
- endif()
+ add_definitions(-DCURL_STATICLIB)
set(CMAKE_CURL_INCLUDES)
set(CMAKE_CURL_LIBRARIES cmcurl)
if(CMAKE_TESTS_CDASH_SERVER)
set(CMAKE_CURL_TEST_URL "${CMAKE_TESTS_CDASH_SERVER}/user.php")
endif()
+ option(CMAKE_USE_OPENSSL "Use OpenSSL." OFF)
+ mark_as_advanced(CMAKE_USE_OPENSSL)
+ if(CMAKE_USE_OPENSSL)
+ set(CURL_CA_BUNDLE "" CACHE FILEPATH "Path to SSL CA Certificate Bundle")
+ set(CURL_CA_PATH "" CACHE PATH "Path to SSL CA Certificate Directory")
+ mark_as_advanced(CURL_CA_BUNDLE CURL_CA_PATH)
+ endif()
add_subdirectory(Utilities/cmcurl)
CMAKE_SET_TARGET_FOLDER(cmcurl "Utilities/3rdParty")
CMAKE_SET_TARGET_FOLDER(LIBCURL "Utilities/3rdParty")
@@ -321,13 +357,26 @@ macro (CMAKE_BUILD_UTILITIES)
endif()
#---------------------------------------------------------------------
+ # Build or use system liblzma for libarchive.
+ if(CMAKE_USE_SYSTEM_LIBLZMA)
+ find_package(LibLZMA)
+ if(NOT LIBLZMA_FOUND)
+ message(FATAL_ERROR "CMAKE_USE_SYSTEM_LIBLZMA is ON but LibLZMA is not found!")
+ endif()
+ set(LZMA_INCLUDE_DIR ${LIBLZMA_INCLUDE_DIRS})
+ set(LZMA_LIBRARY ${LIBLZMA_LIBRARIES})
+ else()
+ add_subdirectory(Utilities/cmliblzma)
+ CMAKE_SET_TARGET_FOLDER(cmliblzma "Utilities/3rdParty")
+ set(LZMA_INCLUDE_DIR
+ "${CMAKE_CURRENT_SOURCE_DIR}/Utilities/cmliblzma/liblzma/api")
+ set(LZMA_LIBRARY cmliblzma)
+ endif()
+
+ #---------------------------------------------------------------------
# Build or use system libarchive for CMake and CTest.
if(CMAKE_USE_SYSTEM_LIBARCHIVE)
- if(EXISTS ${CMAKE_ROOT}/Modules/FindLibArchive.cmake) # added in 2.8.3
- find_package(LibArchive)
- else()
- include(${CMake_SOURCE_DIR}/Modules/FindLibArchive.cmake)
- endif()
+ find_package(LibArchive 3.0.0)
if(NOT LibArchive_FOUND)
message(FATAL_ERROR "CMAKE_USE_SYSTEM_LIBARCHIVE is ON but LibArchive is not found!")
endif()
@@ -339,9 +388,17 @@ macro (CMAKE_BUILD_UTILITIES)
add_definitions(-DLIBARCHIVE_STATIC)
set(ENABLE_NETTLE OFF CACHE INTERNAL "Enable use of Nettle")
set(ENABLE_OPENSSL ${CMAKE_USE_OPENSSL} CACHE INTERNAL "Enable use of OpenSSL")
+ set(ENABLE_LZMA ON CACHE INTERNAL "Enable the use of the system found LZMA library if found")
+ set(ENABLE_ZLIB ON CACHE INTERNAL "Enable the use of the system found ZLIB library if found")
+ set(ENABLE_BZip2 ON CACHE INTERNAL "Enable the use of the system found BZip2 library if found")
+ set(ENABLE_LIBXML2 OFF CACHE INTERNAL "Enable the use of the system found libxml2 library if found")
+ set(ENABLE_EXPAT OFF CACHE INTERNAL "Enable the use of the system found EXPAT library if found")
+ set(ENABLE_PCREPOSIX OFF CACHE INTERNAL "Enable the use of the system found PCREPOSIX library if found")
+ set(ENABLE_LibGCC OFF CACHE INTERNAL "Enable the use of the system found LibGCC library if found")
set(ENABLE_XATTR OFF CACHE INTERNAL "Enable extended attribute support")
set(ENABLE_ACL OFF CACHE INTERNAL "Enable ACL support")
set(ENABLE_ICONV OFF CACHE INTERNAL "Enable iconv support")
+ set(ENABLE_CNG OFF CACHE INTERNAL "Enable the use of CNG(Crypto Next Generation)")
add_subdirectory(Utilities/cmlibarchive)
CMAKE_SET_TARGET_FOLDER(cmlibarchive "Utilities/3rdParty")
set(CMAKE_TAR_LIBRARIES cmlibarchive ${BZIP2_LIBRARIES})
@@ -365,6 +422,25 @@ macro (CMAKE_BUILD_UTILITIES)
endif()
#---------------------------------------------------------------------
+ # Build jsoncpp library.
+ if(CMAKE_USE_SYSTEM_JSONCPP)
+ if(NOT CMAKE_VERSION VERSION_LESS 3.0)
+ include(${CMake_SOURCE_DIR}/Source/Modules/FindJsonCpp.cmake)
+ else()
+ message(FATAL_ERROR "CMAKE_USE_SYSTEM_JSONCPP requires CMake >= 3.0")
+ endif()
+ if(NOT JsonCpp_FOUND)
+ message(FATAL_ERROR
+ "CMAKE_USE_SYSTEM_JSONCPP is ON but a JsonCpp is not found!")
+ endif()
+ set(CMAKE_JSONCPP_LIBRARIES JsonCpp::JsonCpp)
+ else()
+ set(CMAKE_JSONCPP_LIBRARIES cmjsoncpp)
+ add_subdirectory(Utilities/cmjsoncpp)
+ CMAKE_SET_TARGET_FOLDER(cmjsoncpp "Utilities/3rdParty")
+ endif()
+
+ #---------------------------------------------------------------------
# Build XMLRPC library for CMake and CTest.
if(CTEST_USE_XMLRPC)
find_package(XMLRPC QUIET REQUIRED libwww-client)
@@ -380,7 +456,7 @@ macro (CMAKE_BUILD_UTILITIES)
# Use curses?
if (UNIX)
# there is a bug in the Syllable libraries which makes linking ccmake fail, Alex
- if(NOT "${CMAKE_SYSTEM_NAME}" MATCHES syllable)
+ if(NOT CMAKE_SYSTEM_NAME MATCHES syllable)
set(CURSES_NEED_NCURSES TRUE)
find_package(Curses QUIET)
if (CURSES_LIBRARY)
@@ -396,23 +472,29 @@ macro (CMAKE_BUILD_UTILITIES)
set(BUILD_CursesDialog 0)
endif ()
if(BUILD_CursesDialog)
- add_subdirectory(Source/CursesDialog/form)
+ if(NOT CMAKE_USE_SYSTEM_FORM)
+ add_subdirectory(Source/CursesDialog/form)
+ elseif(NOT CURSES_FORM_LIBRARY)
+ message( FATAL_ERROR "CMAKE_USE_SYSTEM_FORM in ON but CURSES_FORM_LIBRARY is not set!" )
+ endif()
endif()
endmacro ()
#-----------------------------------------------------------------------
-if(CMAKE_CXX_PLATFORM_ID MATCHES "OpenBSD")
- execute_process(COMMAND ${CMAKE_CXX_COMPILER}
- ${CMAKE_CXX_COMPILER_ARG1} -dumpversion
- OUTPUT_VARIABLE _GXX_VERSION
- )
- string(REGEX REPLACE "([0-9])\\.([0-9])(\\.[0-9])?" "\\1\\2"
- _GXX_VERSION_SHORT ${_GXX_VERSION})
- if(_GXX_VERSION_SHORT EQUAL 33)
- message(FATAL_ERROR
- "GXX 3.3 on OpenBSD is known to cause CPack to Crash.\n"
- "Please use GXX 4.2 or greater to build CMake on OpenBSD\n"
- "${CMAKE_CXX_COMPILER} version is: ${_GXX_VERSION}")
+if(NOT CMake_TEST_EXTERNAL_CMAKE)
+ if(CMAKE_CXX_PLATFORM_ID MATCHES "OpenBSD")
+ execute_process(COMMAND ${CMAKE_CXX_COMPILER}
+ ${CMAKE_CXX_COMPILER_ARG1} -dumpversion
+ OUTPUT_VARIABLE _GXX_VERSION
+ )
+ string(REGEX REPLACE "([0-9])\\.([0-9])(\\.[0-9])?" "\\1\\2"
+ _GXX_VERSION_SHORT ${_GXX_VERSION})
+ if(_GXX_VERSION_SHORT EQUAL 33)
+ message(FATAL_ERROR
+ "GXX 3.3 on OpenBSD is known to cause CPack to Crash.\n"
+ "Please use GXX 4.2 or greater to build CMake on OpenBSD\n"
+ "${CMAKE_CXX_COMPILER} version is: ${_GXX_VERSION}")
+ endif()
endif()
endif()
@@ -420,27 +502,8 @@ endif()
# The main section of the CMakeLists file
#
#-----------------------------------------------------------------------
-include(Source/CMakeVersion.cmake)
-# Releases define a small tweak level.
-if("${CMake_VERSION_TWEAK}" VERSION_LESS 20000000)
- set(CMake_VERSION_IS_RELEASE 1)
- set(CMake_VERSION_SOURCE "")
-else()
- set(CMake_VERSION_IS_RELEASE 0)
- include(${CMake_SOURCE_DIR}/Source/CMakeVersionSource.cmake)
-endif()
-
-# Compute the full version string.
-set(CMake_VERSION ${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}.${CMake_VERSION_PATCH})
-if(${CMake_VERSION_TWEAK} GREATER 0)
- set(CMake_VERSION ${CMake_VERSION}.${CMake_VERSION_TWEAK})
-endif()
-if(CMake_VERSION_RC)
- set(CMake_VERSION ${CMake_VERSION}-rc${CMake_VERSION_RC})
-endif()
-if(CMake_VERSION_SOURCE)
- set(CMake_VERSION ${CMake_VERSION}-${CMake_VERSION_SOURCE})
-endif()
+# Compute CMake_VERSION, etc.
+include(Source/CMakeVersionCompute.cmake)
# Include the standard Dart testing module
enable_testing()
@@ -450,54 +513,37 @@ include (${CMAKE_ROOT}/Modules/Dart.cmake)
set_directory_properties(PROPERTIES
TEST_INCLUDE_FILE "${CMake_BINARY_DIR}/Tests/EnforceConfig.cmake")
-# where to write the resulting executables and libraries
-set(BUILD_SHARED_LIBS OFF)
-set(EXECUTABLE_OUTPUT_PATH "" CACHE INTERNAL "No configurable exe dir.")
-set(LIBRARY_OUTPUT_PATH "" CACHE INTERNAL
- "Where to put the libraries for CMake")
-
-# The CMake executables usually do not need any rpath to run in the build or
-# install tree.
-set(CMAKE_SKIP_RPATH ON CACHE INTERNAL "CMake does not need RPATHs.")
-
-set(CMAKE_DATA_DIR "share/cmake-${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}" CACHE STRING
- "Install location for data (relative to prefix).")
-set(CMAKE_DOC_DIR "doc/cmake-${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}" CACHE STRING
- "Install location for documentation (relative to prefix).")
-set(CMAKE_MAN_DIR "man" CACHE STRING
- "Install location for man pages (relative to prefix).")
-mark_as_advanced(CMAKE_DATA_DIR CMAKE_DOC_DIR CMAKE_MAN_DIR)
-if(CYGWIN AND EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
- # Force doc, data and man dirs to conform to cygwin layout.
- set(CMAKE_DOC_DIR "share/doc/cmake-${CMake_VERSION}")
- set(CMAKE_DATA_DIR "share/cmake-${CMake_VERSION}")
- set(CMAKE_MAN_DIR "share/man")
- # let the user know we just forced these values
- message(STATUS "Setup for Cygwin packaging")
- message(STATUS "Override cache CMAKE_DOC_DIR = ${CMAKE_DOC_DIR}")
- message(STATUS "Override cache CMAKE_DATA_DIR = ${CMAKE_DATA_DIR}")
- message(STATUS "Override cache CMAKE_MAN_DIR = ${CMAKE_MAN_DIR}")
-endif()
-string(REGEX REPLACE "^/" "" CMAKE_DATA_DIR "${CMAKE_DATA_DIR}")
-string(REGEX REPLACE "^/" "" CMAKE_DOC_DIR "${CMAKE_DOC_DIR}")
-string(REGEX REPLACE "^/" "" CMAKE_MAN_DIR "${CMAKE_MAN_DIR}")
+if(NOT CMake_TEST_EXTERNAL_CMAKE)
+ # where to write the resulting executables and libraries
+ set(BUILD_SHARED_LIBS OFF)
+ set(EXECUTABLE_OUTPUT_PATH "" CACHE INTERNAL "No configurable exe dir.")
+ set(LIBRARY_OUTPUT_PATH "" CACHE INTERNAL
+ "Where to put the libraries for CMake")
-if(BUILD_TESTING)
- include(${CMake_SOURCE_DIR}/Tests/CMakeInstall.cmake)
-endif()
+ # The CMake executables usually do not need any rpath to run in the build or
+ # install tree.
+ set(CMAKE_SKIP_RPATH ON CACHE INTERNAL "CMake does not need RPATHs.")
-# include special compile flags for some compilers
-include(CompileFlags.cmake)
+ # Load install destinations.
+ include(Source/CMakeInstallDestinations.cmake)
-# no clue why we are testing for this here
-include(CheckSymbolExists)
-CHECK_SYMBOL_EXISTS(unsetenv "stdlib.h" HAVE_UNSETENV)
-CHECK_SYMBOL_EXISTS(environ "stdlib.h" HAVE_ENVIRON_NOT_REQUIRE_PROTOTYPE)
+ if(BUILD_TESTING)
+ include(${CMake_SOURCE_DIR}/Tests/CMakeInstall.cmake)
+ endif()
+
+ # include special compile flags for some compilers
+ include(CompileFlags.cmake)
+
+ # no clue why we are testing for this here
+ include(CheckSymbolExists)
+ CHECK_SYMBOL_EXISTS(unsetenv "stdlib.h" HAVE_UNSETENV)
+ CHECK_SYMBOL_EXISTS(environ "stdlib.h" HAVE_ENVIRON_NOT_REQUIRE_PROTOTYPE)
+endif()
# CMAKE_TESTS_CDASH_SERVER: CDash server used by CMake/Tests.
#
# If not defined or "", this variable defaults to the server at
-# http://www.cdash.org/CDash.
+# "http://open.cdash.org".
#
# If set explicitly to "NOTFOUND", curl tests and ctest tests that use
# the network are skipped.
@@ -508,149 +554,143 @@ CHECK_SYMBOL_EXISTS(environ "stdlib.h" HAVE_ENVIRON_NOT_REQUIRE_PROTOTYPE)
# should be run first.
#
if("x${CMAKE_TESTS_CDASH_SERVER}" STREQUAL "x")
- set(CMAKE_TESTS_CDASH_SERVER "http://www.cdash.org/CDash")
+ set(CMAKE_TESTS_CDASH_SERVER "http://open.cdash.org")
endif()
-# build the utilities (a macro defined in this file)
-CMAKE_BUILD_UTILITIES()
-
-# On NetBSD ncurses is required, since curses doesn't have the wsyncup()
-# function. ncurses is installed via pkgsrc, so the library is in /usr/pkg/lib,
-# which isn't in the default linker search path. So without RPATH ccmake
-# doesn't run and the build doesn't succeed since ccmake is executed for
-# generating the documentation.
-if(BUILD_CursesDialog)
- get_filename_component(_CURSES_DIR "${CURSES_LIBRARY}" PATH)
- set(CURSES_NEED_RPATH FALSE)
- if(NOT "${_CURSES_DIR}" STREQUAL "/lib" AND NOT "${_CURSES_DIR}" STREQUAL "/usr/lib" AND NOT "${_CURSES_DIR}" STREQUAL "/lib64" AND NOT "${_CURSES_DIR}" STREQUAL "/usr/lib64")
- set(CURSES_NEED_RPATH TRUE)
- endif()
+if(CMake_TEST_EXTERNAL_CMAKE)
+ set(KWIML_TEST_ENABLE 1)
+ add_subdirectory(Utilities/KWIML)
endif()
-if(BUILD_QtDialog)
- if(APPLE)
- set(CMAKE_BUNDLE_NAME
- "CMake ${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}-${CMake_VERSION_PATCH}")
- set(CMAKE_BUNDLE_LOCATION "${CMAKE_INSTALL_PREFIX}")
- # make sure CMAKE_INSTALL_PREFIX ends in /
- string(LENGTH "${CMAKE_INSTALL_PREFIX}" LEN)
- math(EXPR LEN "${LEN} -1" )
- string(SUBSTRING "${CMAKE_INSTALL_PREFIX}" ${LEN} 1 ENDCH)
- if(NOT "${ENDCH}" STREQUAL "/")
- set(CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/")
+if(NOT CMake_TEST_EXTERNAL_CMAKE)
+ # build the utilities (a macro defined in this file)
+ CMAKE_BUILD_UTILITIES()
+
+ # On NetBSD ncurses is required, since curses doesn't have the wsyncup()
+ # function. ncurses is installed via pkgsrc, so the library is in /usr/pkg/lib,
+ # which isn't in the default linker search path. So without RPATH ccmake
+ # doesn't run and the build doesn't succeed since ccmake is executed for
+ # generating the documentation.
+ if(BUILD_CursesDialog)
+ get_filename_component(_CURSES_DIR "${CURSES_LIBRARY}" PATH)
+ set(CURSES_NEED_RPATH FALSE)
+ if(NOT "${_CURSES_DIR}" STREQUAL "/lib" AND NOT "${_CURSES_DIR}" STREQUAL "/usr/lib" AND NOT "${_CURSES_DIR}" STREQUAL "/lib64" AND NOT "${_CURSES_DIR}" STREQUAL "/usr/lib64")
+ set(CURSES_NEED_RPATH TRUE)
endif()
- set(CMAKE_INSTALL_PREFIX
- "${CMAKE_INSTALL_PREFIX}${CMAKE_BUNDLE_NAME}.app/Contents")
endif()
- set(QT_NEED_RPATH FALSE)
- if(NOT "${QT_LIBRARY_DIR}" STREQUAL "/lib" AND NOT "${QT_LIBRARY_DIR}" STREQUAL "/usr/lib" AND NOT "${QT_LIBRARY_DIR}" STREQUAL "/lib64" AND NOT "${QT_LIBRARY_DIR}" STREQUAL "/usr/lib64")
- set(QT_NEED_RPATH TRUE)
+ if(BUILD_QtDialog)
+ if(APPLE)
+ set(CMAKE_BUNDLE_VERSION
+ "${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}.${CMake_VERSION_PATCH}")
+ set(CMAKE_BUNDLE_LOCATION "${CMAKE_INSTALL_PREFIX}")
+ # make sure CMAKE_INSTALL_PREFIX ends in /
+ if(NOT CMAKE_INSTALL_PREFIX MATCHES "/$")
+ set(CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/")
+ endif()
+ set(CMAKE_INSTALL_PREFIX
+ "${CMAKE_INSTALL_PREFIX}CMake.app/Contents")
+ endif()
+
+ set(QT_NEED_RPATH FALSE)
+ if(NOT "${QT_LIBRARY_DIR}" STREQUAL "/lib" AND NOT "${QT_LIBRARY_DIR}" STREQUAL "/usr/lib" AND NOT "${QT_LIBRARY_DIR}" STREQUAL "/lib64" AND NOT "${QT_LIBRARY_DIR}" STREQUAL "/usr/lib64")
+ set(QT_NEED_RPATH TRUE)
+ endif()
endif()
-endif()
-# The same might be true on other systems for other libraries.
-# Then only enable RPATH if we have are building at least with cmake 2.4,
-# since this one has much better RPATH features than cmake 2.2.
-# The executables are then built with the RPATH for the libraries outside
-# the build tree, which is both the build and the install RPATH.
-if (UNIX)
- if( CMAKE_USE_SYSTEM_CURL OR CMAKE_USE_SYSTEM_ZLIB
- OR CMAKE_USE_SYSTEM_EXPAT OR CTEST_USE_XMLRPC OR CURSES_NEED_RPATH OR QT_NEED_RPATH)
- set(CMAKE_SKIP_RPATH OFF CACHE INTERNAL "CMake built with RPATH.")
- set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
- set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
- endif()
-endif ()
+ # The same might be true on other systems for other libraries.
+ # Then only enable RPATH if we have are building at least with cmake 2.4,
+ # since this one has much better RPATH features than cmake 2.2.
+ # The executables are then built with the RPATH for the libraries outside
+ # the build tree, which is both the build and the install RPATH.
+ if (UNIX)
+ if( CMAKE_USE_SYSTEM_CURL OR CMAKE_USE_SYSTEM_ZLIB
+ OR CMAKE_USE_SYSTEM_EXPAT OR CTEST_USE_XMLRPC OR CURSES_NEED_RPATH OR QT_NEED_RPATH)
+ set(CMAKE_SKIP_RPATH OFF CACHE INTERNAL "CMake built with RPATH.")
+ set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+ set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
+ endif()
+ endif ()
-# add the uninstall support
-configure_file(
- "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
- "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
- @ONLY)
-add_custom_target(uninstall
- "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
+ # add the uninstall support
+ configure_file(
+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
+ @ONLY)
+ add_custom_target(uninstall
+ "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
+
+ include (CMakeCPack.cmake)
-include (CMakeCPack.cmake)
+endif()
# setup some Testing support (a macro defined in this file)
CMAKE_SETUP_TESTING()
-configure_file(
- "${CMAKE_CURRENT_SOURCE_DIR}/DartLocal.conf.in"
- "${CMAKE_CURRENT_BINARY_DIR}/DartLocal.conf"
- COPYONLY)
-
-option(CMAKE_STRICT
- "Perform strict testing to record property and variable access. Can be used to report any undefined properties or variables" OFF)
-mark_as_advanced(CMAKE_STRICT)
-
-if(NOT CMake_VERSION_IS_RELEASE)
- if("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" AND
- NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS 4.2)
- set(C_FLAGS_LIST -Wcast-align -Werror-implicit-function-declaration -Wchar-subscripts
- -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security
- -Wmissing-format-attribute -fno-common -Wundef
- )
- set(CXX_FLAGS_LIST -Wnon-virtual-dtor -Wcast-align -Wchar-subscripts -Wall -W
- -Wshadow -Wpointer-arith -Wformat-security -Wundef
- )
- foreach(FLAG_LANG C CXX)
- foreach(FLAG ${${FLAG_LANG}_FLAGS_LIST})
- if(NOT " ${CMAKE_${FLAG_LANG}_FLAGS} " MATCHES " ${FLAG} ")
- set(CMAKE_${FLAG_LANG}_FLAGS "${CMAKE_${FLAG_LANG}_FLAGS} ${FLAG}")
- endif()
+if(NOT CMake_TEST_EXTERNAL_CMAKE)
+ if(NOT CMake_VERSION_IS_RELEASE)
+ if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND
+ NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS 4.2)
+ set(C_FLAGS_LIST -Wcast-align -Werror-implicit-function-declaration -Wchar-subscripts
+ -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security
+ -Wmissing-format-attribute -fno-common -Wundef
+ )
+ set(CXX_FLAGS_LIST -Wnon-virtual-dtor -Wcast-align -Wchar-subscripts -Wall -W
+ -Wshadow -Wpointer-arith -Wformat-security -Wundef
+ )
+
+ foreach(FLAG_LANG C CXX)
+ foreach(FLAG ${${FLAG_LANG}_FLAGS_LIST})
+ if(NOT " ${CMAKE_${FLAG_LANG}_FLAGS} " MATCHES " ${FLAG} ")
+ set(CMAKE_${FLAG_LANG}_FLAGS "${CMAKE_${FLAG_LANG}_FLAGS} ${FLAG}")
+ endif()
+ endforeach()
endforeach()
- endforeach()
- unset(C_FLAGS_LIST)
- unset(CXX_FLAGS_LIST)
+ unset(C_FLAGS_LIST)
+ unset(CXX_FLAGS_LIST)
+ endif()
endif()
+
+ # build the remaining subdirectories
+ add_subdirectory(Source)
+ add_subdirectory(Utilities)
endif()
-# build the remaining subdirectories
-add_subdirectory(Source)
-add_subdirectory(Utilities)
add_subdirectory(Tests)
-if(BUILD_TESTING)
- CMAKE_SET_TARGET_FOLDER(CMakeLibTests "Tests")
+if(NOT CMake_TEST_EXTERNAL_CMAKE)
+ if(BUILD_TESTING)
+ CMAKE_SET_TARGET_FOLDER(CMakeLibTests "Tests")
+ endif()
+ if(TARGET documentation)
+ CMAKE_SET_TARGET_FOLDER(documentation "Documentation")
+ endif()
endif()
-CMAKE_SET_TARGET_FOLDER(cmw9xcom "Utilities/Win9xCompat")
-CMAKE_SET_TARGET_FOLDER(documentation "Documentation")
# add a test
add_test(SystemInformationNew "${CMAKE_CMAKE_COMMAND}"
- --system-information -G "${CMAKE_TEST_GENERATOR}" )
-
-# Install license file as it requires.
-install(FILES Copyright.txt DESTINATION ${CMAKE_DOC_DIR})
-
-# Install script directories.
-install(
- DIRECTORY Modules Templates
- DESTINATION ${CMAKE_DATA_DIR}
- FILE_PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
- DIRECTORY_PERMISSIONS OWNER_READ OWNER_EXECUTE OWNER_WRITE
- GROUP_READ GROUP_EXECUTE
- WORLD_READ WORLD_EXECUTE
- PATTERN "*.sh*" PERMISSIONS OWNER_READ OWNER_EXECUTE OWNER_WRITE
- GROUP_READ GROUP_EXECUTE
- WORLD_READ WORLD_EXECUTE
- )
-
-# process docs related install
-add_subdirectory(Docs)
-
-#-----------------------------------------------------------------------
-# End of the main section of the CMakeLists file
-#-----------------------------------------------------------------------
+ --system-information -G "${CMAKE_GENERATOR}" )
+
+if(NOT CMake_TEST_EXTERNAL_CMAKE)
+ # Install license file as it requires.
+ install(FILES Copyright.txt DESTINATION ${CMAKE_DOC_DIR})
+
+ # Install script directories.
+ install(
+ DIRECTORY Help Modules Templates
+ DESTINATION ${CMAKE_DATA_DIR}
+ FILE_PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
+ DIRECTORY_PERMISSIONS OWNER_READ OWNER_EXECUTE OWNER_WRITE
+ GROUP_READ GROUP_EXECUTE
+ WORLD_READ WORLD_EXECUTE
+ PATTERN "*.sh*" PERMISSIONS OWNER_READ OWNER_EXECUTE OWNER_WRITE
+ GROUP_READ GROUP_EXECUTE
+ WORLD_READ WORLD_EXECUTE
+ )
-# As a special case when building CMake itself, CMake 2.8.0 and below
-# look up EXECUTABLE_OUTPUT_PATH in the top-level CMakeLists.txt file
-# to compute the location of the "cmake" executable. We set it here
-# so that those CMake versions can find it. We wait until after all
-# the add_subdirectory() calls to avoid affecting the subdirectories.
-set(EXECUTABLE_OUTPUT_PATH ${CMake_BIN_DIR})
+ # Install auxiliary files integrating with other tools.
+ add_subdirectory(Auxiliary)
+endif()
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
new file mode 100644
index 000000000..0e5c7e144
--- /dev/null
+++ b/CONTRIBUTING.rst
@@ -0,0 +1,34 @@
+Contributing to CMake
+*********************
+
+Community
+=========
+
+CMake is maintained and supported by `Kitware`_ and developed in
+collaboration with a productive community of contributors.
+
+.. _`Kitware`: http://www.kitware.com/cmake
+
+The preferred entry point for new contributors is the mailing list.
+Please subscribe and post to the `CMake Developers List`_ to offer
+contributions. Regular and productive contributors may be invited
+to gain direct push access.
+
+.. _`CMake Developers List`: https://cmake.org/mailman/listinfo/cmake-developers
+
+Patches
+=======
+
+Please base all new work on the ``master`` branch. Then use
+``git format-patch`` to produce patches suitable to post to
+the mailing list.
+
+License
+=======
+
+We do not require any formal copyright assignment or contributor license
+agreement. Any contributions intentionally sent upstream are presumed
+to be offered under terms of the OSI-approved BSD 3-clause License.
+See `Copyright.txt`_ for details.
+
+.. _`Copyright.txt`: Copyright.txt
diff --git a/CTestConfig.cmake b/CTestConfig.cmake
index 92eacd8e3..df2f94c2a 100644
--- a/CTestConfig.cmake
+++ b/CTestConfig.cmake
@@ -13,13 +13,8 @@ set(CTEST_PROJECT_NAME "CMake")
set(CTEST_NIGHTLY_START_TIME "1:00:00 UTC")
set(CTEST_DROP_METHOD "http")
-set(CTEST_DROP_SITE "www.cdash.org")
-set(CTEST_DROP_LOCATION "/CDash/submit.php?project=CMake")
+set(CTEST_DROP_SITE "open.cdash.org")
+set(CTEST_DROP_LOCATION "/submit.php?project=CMake")
set(CTEST_DROP_SITE_CDASH TRUE)
set(CTEST_CDASH_VERSION "1.6")
set(CTEST_CDASH_QUERY_VERSION TRUE)
-
-# use old trigger stuff so that cmake 2.4 and below will not
-# get errors on trigger
-set (TRIGGER_SITE
- "http://public.kitware.com/cgi-bin/Submit-CMake-TestingResults.cgi")
diff --git a/CTestCustom.cmake.in b/CTestCustom.cmake.in
index 495d156cc..abef69214 100644
--- a/CTestCustom.cmake.in
+++ b/CTestCustom.cmake.in
@@ -1,9 +1,7 @@
-set(CTEST_CUSTOM_ERROR_MATCH
- ${CTEST_CUSTOM_ERROR_MATCH}
+list(APPEND CTEST_CUSTOM_ERROR_MATCH
"ERROR:")
-set(CTEST_CUSTOM_WARNING_EXCEPTION
- ${CTEST_CUSTOM_WARNING_EXCEPTION}
+list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
"xtree.[0-9]+. : warning C4702: unreachable code"
"warning LNK4221"
"warning LNK4204" # Occurs by race condition with objects in small libs
@@ -19,10 +17,12 @@ set(CTEST_CUSTOM_WARNING_EXCEPTION
"Utilities.cmbzip2."
"Source.CTest.Curl"
"Source.CursesDialog.form"
+ "Source.cm_sha2.*warning.*cast increases required alignment of target type"
"Utilities.cmcurl"
"Utilities.cmexpat."
"Utilities.cmlibarchive"
- "/usr/include.*warning.*shadowed declaration is here"
+ "warning: declaration of .single. shadows a global declaration"
+ "/usr/include.*(warning|note).*shadowed declaration is here"
"/usr/bin/ld.*warning.*-..*directory.name.*bin.*does not exist"
"Redeclaration of .send..... with a different storage class specifier"
"is not used for resolving any symbol"
@@ -31,49 +31,70 @@ set(CTEST_CUSTOM_WARNING_EXCEPTION
"remark: .*LOOP WAS VECTORIZED"
"warning .980: wrong number of actual arguments to intrinsic function .std::basic_"
"LINK : warning LNK4089: all references to.*ADVAPI32.dll.*discarded by /OPT:REF"
+ "LINK : warning LNK4089: all references to.*CRYPT32.dll.*discarded by /OPT:REF"
"LINK : warning LNK4089: all references to.*PSAPI.DLL.*discarded by /OPT:REF"
+ "LINK : warning LNK4089: all references to.*RPCRT4.dll.*discarded by /OPT:REF"
+ "LINK : warning LNK4089: all references to.*SHELL32.dll.*discarded by /OPT:REF"
"LINK : warning LNK4089: all references to.*USER32.dll.*discarded by /OPT:REF"
+ "LINK : warning LNK4089: all references to.*ole32.dll.*discarded by /OPT:REF"
+ "Warning.*: .*/Utilities/KWIML/test/test_int_format.h.* # Redundant preprocessing concatenation"
"Warning: library was too large for page size.*"
"Warning: public.*_archive_.*in module.*archive_*clashes with prior module.*archive_.*"
"Warning: public.*BZ2_bz.*in module.*bzlib.*clashes with prior module.*bzlib.*"
"Warning: public.*_archive.*clashes with prior module.*"
"Warning: LINN32: Last line.*is less.*"
+ "Warning: Olimit was exceeded on function.*"
+ "Warning: To override Olimit for all functions in file.*"
"warning.*directory name.*CMake-Xcode.*/bin/.*does not exist.*"
"stl_deque.h:1051"
"(Lexer|Parser).*warning.*conversion.*may (alter its value|change the sign)"
- "(Lexer|Parser).*warning.*statement is unreachable"
+ "(Lexer|Parser).*warning.*(statement is unreachable|will never be executed)"
"PGC-W-0095-Type cast required for this conversion.*ProcessUNIX.c"
- "[Qq]t([Cc]ore|[Gg]ui).*warning.*conversion.*may alter its value"
+ "[Qq]t([Cc]ore|[Gg]ui|[Ww]idgets).*warning.*conversion.*may alter its value"
"warning:.*is.*very unsafe.*consider using.*"
"warning:.*is.*misused, please use.*"
"CMakeSetupManifest.xml.*manifest authoring warning.*Unrecognized Element"
"cc-3968 CC: WARNING File.*" # "implicit" truncation by static_cast
"ld: warning: directory not found for option .-(F|L)"
+ "ld: warning .*/libgcc.a archive's cputype"
+ "ld: warning: ignoring file .*/libgcc.a, file was built for archive which is not the architecture being linked"
+ "ld: warning: in .*/libgcc.a, file is not of required architecture"
"warning.*This version of Mac OS X is unsupported"
"clang.*: warning: argument unused during compilation: .-g"
+ "note: in expansion of macro" # diagnostic context note
+ "cm(StringCommand|CTestTestHandler)\\.cxx.*warning.*rand.*isn.*t random" # we do not do crypto
+ "cm(StringCommand|CTestTestHandler)\\.cxx.*warning.*srand.*seed choices are.*poor" # we do not do crypto
# Ignore clang's summary warning, assuming prior text has matched some
# other warning expression:
"[0-9,]+ warnings? generated."
+
+# scanbuild exceptions
+ "char_traits.h:.*: warning: Null pointer argument in call to string length function"
+ "stl_construct.h:.*: warning: Forming reference to null pointer"
+ ".*stl_uninitialized.h:75:19: warning: Forming reference to null pointer.*"
+ ".*stl_vector.h:.*: warning: Returning null reference.*"
+ "warning: Value stored to 'yymsg' is never read"
+ "warning: Value stored to 'yytoken' is never read"
+ "index_encoder.c.241.2. warning: Value stored to .out_start. is never read"
+ "index.c.*warning: Access to field.*results in a dereference of a null pointer.*loaded from variable.*"
+ "cm_sha2.*warning: Value stored to.*is never read"
+ "testProcess.*warning: Dereference of null pointer .loaded from variable .invalidAddress.."
)
if(NOT "@CMAKE_GENERATOR@" MATCHES "Xcode")
- set(CTEST_CUSTOM_COVERAGE_EXCLUDE
- ${CTEST_CUSTOM_COVERAGE_EXCLUDE}
+ list(APPEND CTEST_CUSTOM_COVERAGE_EXCLUDE
"XCode"
)
endif ()
if(NOT "@CMAKE_GENERATOR@" MATCHES "KDevelop")
- set(CTEST_CUSTOM_COVERAGE_EXCLUDE
- ${CTEST_CUSTOM_COVERAGE_EXCLUDE}
+ list(APPEND CTEST_CUSTOM_COVERAGE_EXCLUDE
"Kdevelop"
)
endif ()
-set(CTEST_CUSTOM_COVERAGE_EXCLUDE
- ${CTEST_CUSTOM_COVERAGE_EXCLUDE}
-
+list(APPEND CTEST_CUSTOM_COVERAGE_EXCLUDE
# Exclude kwsys files from coverage results. They are reported
# (with better coverage results) on kwsys dashboards...
"/Source/(cm|kw)sys/"
@@ -84,3 +105,7 @@ set(CTEST_CUSTOM_COVERAGE_EXCLUDE
# Exclude Qt source files from coverage results:
"[A-Za-z]./[Qq]t/qt-.+-opensource-src"
)
+
+list(APPEND CTEST_CUSTOM_MEMCHECK_IGNORE
+ kwsys.testProcess-10 # See Source/kwsys/CTestCustom.cmake.in
+ )
diff --git a/CTestCustom.ctest.in b/CTestCustom.ctest.in
deleted file mode 100644
index 6127843f6..000000000
--- a/CTestCustom.ctest.in
+++ /dev/null
@@ -1,3 +0,0 @@
-# This file is provided for compatibility with CMake 2.2 and lower.
-# Just include the custom file by its new name.
-INCLUDE("CTestCustom.cmake")
diff --git a/ChangeLog.manual b/ChangeLog.manual
deleted file mode 100644
index b389d8bdb..000000000
--- a/ChangeLog.manual
+++ /dev/null
@@ -1,5301 +0,0 @@
-Changes in CMake 2.8.12.2 (since 2.8.12.1)
-------------------------------------------
-Brad King (4):
- VS: Map /Fd to ProgramDataBaseFileName for VS 7,8,9 (#14577)
- Replace <OBJECT_DIR> rule placeholder consistently (#14667)
- VS: Convert include path to backslashes for VS >= 10
- Revert "Ninja: Track configured files so we can regenerate them."
-
-Rolf Eike Beer (1):
- FindOpenMP: fix detecting compilers that do not need any special flag (#14567)
-
-Ruslan Baratov (1):
- Xcode: Fix storyboard view
-
-Ted Kremenek (1):
- CMakeDetermineCompilerId: Fix compiler line match for Xcode 5.1
-
-Changes in CMake 2.8.12.1 (since 2.8.12)
-----------------------------------------
-Brad King (9):
- MSVC: Add /FS flag for cl >= 18 to allow parallel compilation (#14492)
- Genex: Reject $<TARGET_FILE:...> for object libraries (#14532)
- Check for OBJECT_LIBRARY source files at start of generation
- CMP0022: Plain target_link_libraries must populate link interface
- Do not export INTERFACE_LINK_LIBRARIES from non-linkable targets
- CMP0022: Warn about a given target at most once
- Fix summary documentation of INTERFACE_LINK_LIBRARIES
- file(GENERATE): Clear internal records between configures
- cmake: Validate -E cmake_automoc argument count (#14545)
-
-Modestas Vainius (1):
- Fix spelling in INTERFACE_LINK_LIBRARIES documentation (#14542)
-
-Stephen Kelly (5):
- CMP0022: Output link interface mismatch for static library warning
- Don't add invalid content to static lib INTERFACE_LINK_LIBRARIES.
- CMP0022: Add unit test for null pointer check and message.
- CMP0022: Add test for target_link_libraries plain signature
- Automoc: Add directory-level COMPILE_DEFINITIONS to command line (#14535)
-
-Vladislav Vinogradov (1):
- FindCUDA: Fix NPP library search for CUDA 5.5
-
-Changes in CMake 2.8.12 (since 2.8.12-rc4)
-------------------------------------------
-Brad King (4):
- Xcode: Fix test architecture selection for Xcode >= 5
- Xcode: Teach Tests/BuildDepends to allow LINK_DEPENDS_NO_SHARED failure
- Xcode: Drop XCODE_DEPEND_HELPER for Xcode >= 5
- Xcode: Fix OBJECT library support for Xcode 5 (#14254)
-
-Stephen Kelly (1):
- Genex: Fix processing multiple include directories for relative paths
-
-Changes in CMake 2.8.12-rc4 (since 2.8.12-rc3)
-----------------------------------------------
-Brad King (8):
- VS: Future-proof Intel project format selection
- MSVC: Drop /link from executable link lines with Ninja
- FindCUDA: Always list custom command outputs in their targets
- FindPNG: Honor old PNG_LIBRARY if provided (#14398)
- FindHDF5: Fix regression in per-configuration library selection
- bash-completion: Future-proof --help-*-list "cXXXX version" filtering
- OS X: Search system SDKs for frameworks
- Use first custom command for the same output (#14446)
-
-Patrick Gansterer (3):
- MSVC: Fix version test for linking corelibc on Windows CE (#14420)
- MSVC: Fix WinCE arch family preprocessor symbol (#14436)
- VS: Use version-specific subsystem for WinCE compiler id (#14440)
-
-Rolf Eike Beer (1):
- bootstrap: try better workaround for builds on Linux/HPPA
-
-Stephen Kelly (3):
- Add differing target property content to policy CMP0022 warning
- Fix CMP0022 warning when no old-style property is set
- genex: Fix preprocessing with incomplete content (#14410).
-
-Changes in CMake 2.8.12-rc3 (since 2.8.12-rc2)
-----------------------------------------------
-Robert Maynard (1):
- cmMakefile: Do not track CMake temporary files.
-
-Changes in CMake 2.8.12-rc2 (since 2.8.12-rc1)
-----------------------------------------------
-Brad King (2):
- Fix RunCMake.Configure test expectation newline matching
- Clean up install rules of CMake itself (#14371)
-
-Clinton Stimpson (1):
- OSX: Allow an empty INSTALL_NAME_DIR to override MACOSX_RPATH.
-
-Eric Bélanger (1):
- FindImageMagick: Find libraries named with HDRI support (#14348)
-
-Raphael Kubo da Costa (1):
- FindTCL: Add BSD paths for Tcl/Tk 8.6
-
-Robert Maynard (2):
- VS: Generate ToolsVersion matching each VS version
- cmMakefile: Do not track configured files known to be temporary
-
-Rolf Eike Beer (1):
- CheckC*CompilerFlag: add documentation what to expect from a positive result
-
-Stephen Kelly (6):
- Fix OLD behavior of CMP0021.
- try_compile: Extract IMPORTED targets from LINK_DEPENDENT_LIBRARIES
- try_compile: Extract IMPORTED targets from INTERFACE_LINK_LIBRARIES
- Genex: Fix evaluation of MAP_IMPORTED_CONFIG_<CONFIG>
- Fix some whitespace errors in docs.
- Normalize system directories from the interface target property
-
-Yury G. Kudryashov (1):
- CPack: Fix a typo in documentation
-
-Zack Galbreath (1):
- CTest: Fix GTM coverage parsing line offset bug
-
-Changes in CMake 2.8.12-rc1 (since 2.8.11.2)
---------------------------------------------
-Adam J. Weigold (1):
- CPackWIX: Add support for custom WiX templates
-
-Alex Neundorf (12):
- CMakeSystem: include toolchain file after setting CMAKE_HOST_ (#13796)
- Add support files for C, C++ and ASM for the IAR toolchain.
- Add regexps for the IAR toolchain to the vendor list.
- Add IAR to the CMakeDetectC(XX)CompilerID.c(pp).in
- cmake-gui: use shortcut F only for "Find in Output"
- Eclipse: fix #14204 and #14205: no file links to directories
- automoc: add a global AUTOMOC_TARGETS_FOLDER property
- install: do not strip dll import libraries (#14123)
- ExportTargets: add one more comment to the generated file.
- Add documentation for the --graphviz support
- graphvizoptions: add copyright notice
- add macros cmake_print_properties() and cmake_print_variables()
-
-Alexander Mohr (1):
- VS: Detect MSVC compiler id on ARM toolchain
-
-Andreas Mohr (10):
- Fix spelling and typos (affecting users)
- Fix spelling and typos (affecting binary data / module messages)
- Fix spelling and typos (non-binary)
- Fix spelling and typos (product names)
- FindwxWidgets: add DOC strings with usual style
- Explain distribution of Win9x binary on all Windows versions.
- VS10: add detailed comment about MIDL processing
- Docs: Update description of CMAKE_(BUILD_TYPE|CONFIGURATION_TYPES)
- Docs: Clarify that CMAKE_*_(PREFIX|SUFFIX) affect filenames
- Docs: Clarify wording "flag used" => "flag (to|will) be used"
-
-Ben Boeckel (12):
- set_property: Do not remove a property when APPENDing nothing
- Tests/RunCMake: Document stripping of expected output
- export: Error when exporting a target without a language
- variable_watch: Store client data as pointers
- variable_watch: Add a deleter for the client data
- variable_watch: Match client_data when finding duplicates
- variable_watch: Allow specifying the data to match in RemoveWatch
- variable_watch: Prevent making extra entries in the watch map
- variable_watch: Fix a typo in the error message
- variable_watch: Don't share memory for callbacks
- variable_watch: Check newValue for NULL
- variable_watch: Add test for watching a variable multiple times
-
-Bill Hoffman (1):
- Do not set CMAKE_MATCH_ variables when not neeeded
-
-Bjoern Thiel (1):
- SelectLibraryConfigurations: Fix for cached <base>_LIBRARY
-
-Brad King (91):
- VS: Separate compiler and linker PDB files (#11899, #14062)
- MSVC: Invoke 'link' directly for executables
- Ninja: Fix OBJECT_DIR placeholder path conversion
- VS 10: Escape ; as %3B in preprocessor definitions (#14073)
- CTest: Simplify ctest_* command source/build dir lookup
- get_filename_component: Add explicit unit tests
- get_filename_component: Add DIRECTORY option (#14091)
- Xcode: Use explicitFileType to mark source types (#14093)
- Check{C,CXX}CompilerFlag: Test using C locale (#14102)
- Windows: Search '/' prefix only when cross compiling (#10994)
- Recognize ld with toolchain prefix (#13960)
- VS: Always initialize CMAKE_CONFIGURATION_TYPES in IDE generators
- Begin post-2.8.11 development
- Sanitize linker name to parse implicit link line (#14154)
- VS: Allow /Fa to set AssemblerListingLocation (#14153)
- Tests/IncludeDirectories: Avoid shared library with no symbols
- if: Add test for IS_DIRECTORY
- try_compile: Add test for bad call error cases
- try_compile: Refactor argument processing
- variable_watch: Add test for MODIFIED_ACCESS report
- bootstrap: Compile KWSys SystemTools with UTIME(S|NSAT) values
- variable_watch: Remove leftover debugging code (#14187)
- variable_watch: Print accesses as "CMake Debug Log" messages
- Docs: Clarify CMAKE_PARENT_LIST_FILE (#14194)
- get_filename_component: Test ABSOLUTE of .. after root component
- try_compile: Add signature to allow multiple SOURCES
- enable_language: Clarify documentation
- Split cmBootstrapCommands.cxx into two sources
- Document CMAKE_INSTALL_PREFIX in CMAKE_SYSTEM_PREFIX_PATH
- cmake: Document "-E tar" support for .zip (#14225)
- FindBoost: Clarify failure on missing 'static' libs (#14235)
- CMakeDetermineVSServicePack: Improve documentation
- CMakeDetermineVSServicePack: Add VS 11 update 1 and 2 (#14239)
- Document ENV syntax as a "variable" (#14245)
- Embarcadero: Use response files only for includes, objects, and libs
- Escape target flags taken from COMPILE_OPTIONS
- Refactor target COMPILE_OPTIONS and COMPILE_FLAGS handling
- CMakeDetermineVSServicePack: Add VS 11 update 3
- Document removal of 'register' from flex/bison output
- VS12: Find proper MSBuild for VSProjectInSubdir test
- Fortran: Use explicit type in Fortran 90 check
- project: Document top-level CMakeLists.txt requirement
- ExternalProject: Document multiple COMMAND lines
- include: Clarify variable access scope for included file
- VS: Fix /MAP:mapfile flag mapping (#14282)
- cmake: On configure error suggest looking at CMake*.log files
- try_compile: Escape CMAKE_<lang>_FLAGS in test projects (#14268)
- try_compile: Add COPY_FILE_ERROR option to capture failure
- FindPNG: Add versioned library names for 1.6 (#14289)
- cmake: Fix resource leak reported by cppcheck
- VS,Xcode: Drop incorrect legacy dependency trace (#14291)
- OS X: Add copyright notices to Darwin-*-Fortran.cmake
- VS: Avoid leaking child process output back to IDE (#14266)
- Fix ExportImport test cmp0022NEW build on Watcom
- add_test: Document test name restrictions (#14298)
- UseJava: Update notice of copyright by Kitware
- add_custom_command: Manage backtrace memory correctly (#14299)
- Teach compiler ABI check to tolerate try_compile COPY_FILE failure
- Test COMPILE_DEFINITIONS target property get/set/get round-trip
- Check*CompilerFlag: Document use of CMAKE_REQUIRED_DEFINITIONS (#14309)
- sha2: Avoid type-punned pointer dereference (#14314)
- VS 6: Tell BuildDepends test to tolerate ninjadep failure
- cmMakefile: Do not track configured files known to be temporary
- libarchive: Update README-CMake.txt for new snapshot
- libarchive: Include cm_zlib.h to get zlib used by CMake
- libarchive: Silence API deprecation warnings
- libarchive: Avoid struct init with variable
- libarchive: Remove build options not used by CMake
- libarchive: Backport to CMake 2.8.2
- VS10: Honor user-specified /SUBSYSTEM: flag (#14326)
- VS10: Escape include paths in XML project files (#14331)
- OS X: Search for SDK based on deployment target (#14324)
- bootstrap: Do not suppress CMAKE_OSX_SYSROOT if CFLAGS have -isysroot (#14324)
- OS X: Enable command-line build without tools in PATH
- VS 6,7: Refactor local generators to avoid GetSourceFileWithOutput
- cmake-gui: Fix build rules for Qt5 on Windows
- Include cmMakefile.h before cm*Lexer.h to get stdint.h first
- Skip CTestLimitDashJ test on Borland
- Add RunCMake.Syntax test to cover argument parsing
- cmListFileLexer: Fix line number after backslash in string
- cmListFileLexer: Split normal and legacy unquoted arguments
- cmListFileArgument: Generalize 'Quoted' bool to 'Delimeter' enum
- Add RunCMake.Syntax test cases for command invocation styles
- cmListFileCache: Convert CMake language parser to class
- Warn about arguments not separated by whitespace
- Warn about unquoted arguments that look like long brackets
- cmListFileLexer: Modify flex output to avoid Borland warning
- Cygwin: Avoid legacy warnings in RunCMake.* tests
- Update version introducing CMP0021, CMP0022, and CMP0023
- OS X: Do not default to non-existent deployment target SDK
- Do not warn about left paren not separated by a space
-
-Christian Maaser (1):
- VS: Add support for .NET target framework version
-
-Clinton Stimpson (12):
- Improve documentation for CPACK_PACKAGE_INSTALL_REGISTRY_KEY.
- Refactor how bundles and frameworks are supported.
- Xcode: Add support for shared library versioning
- OS X: Fix getting of CFBundle LOCATION property.
- OS X: Add RPATH support for Mac.
- Xcode: Add rpath support in Xcode generator.
- OS X: Add support for @rpath in export files.
- OS X: Add test for rpaths on Mac.
- OS X: Improvements for getting install name of dylib.
- OS X: Enable rpath support on Mac OS X when find_library() is used.
- OS X: Fix regression handling frameworks for Ninja
- OS X: If necessary, use xcrun to help find otool used to query install names.
-
-Cédric OCHS (1):
- Xcode: Support XCODE_ATTRIBUTE_ with [variant=<config>] (#12532)
-
-Daniele E. Domenichelli (15):
- FindGTK2: Move check for pangocairo in gtk module
- FindGTK2: Detect gthread library
- FindFreetype: Detect Freetype installed by GtkMM installer for win
- FindGTK2: Do not fail on MSVC11 if vc100 libraries are available
- FindGTK2: Add GTK2_DEFINITIONS variable
- SelectLibraryConfigurations: Do not cache the _LIBRARY variable
- SelectLibraryConfigurations: Use -NOTFOUND instead of copying the vars
- FindGTK2: Use GTK_XXX_LIBRARY_DEBUG libraries in debug mode
- FindGTK2: Append _LIBRARY to var name in _GTK2_FIND_LIBRARY
- FindGTK2: Append _INCLUDE_DIR to var name in _GTK2_FIND_INCLUDE_DIR
- FindGTK2: Update local changelog
- FindGTK2: Remove GTK2_SKIP_MARK_AS_ADVANCED option
- FindGTK2: gthread-2.0 folder does not exist
- FindGTK2: Detect gmodule library
- FindGTK2: Detect pangoft2 and pangoxft libraries
-
-David Coppa (1):
- OpenBSD: Enable ELF parsing and editing (#14241)
-
-David Golub (1):
- CPack/NSIS: Obtain path from which to uninstall from registry (#14124)
-
-Eric NOULARD (5):
- Add support for componentized USER spec file
- CPackRPM add mechanism to remove path from generated list of file in RPM spec.
- CPackRPM add /usr/lib64 to the list of builtin to-be-excluded path
- CPackRPM protect '@' character in filename processed in the spec file.
- CPackRPM make the changelog line conform to expected format
-
-Fredrik Axelsson (1):
- CPackWIX: Handle CPACK_PACKAGE_EXECUTABLES (#13967)
-
-Funda Wang (1):
- FindImageMagick: Find v6 include dir (#14174)
-
-Graham Markall (2):
- OS X: Add Fortran library version flags (#14249)
- UseJava: Pass sources to javac using response file (#13028)
-
-Gregoire Lejeune (1):
- Allow using Java in a cross-compilation toolchain
-
-Ian Monroe (2):
- Ninja: use cd /D to set directory on Windows
- CPackWIX: Fix MSI package layout regression from parent
-
-Igor Murzov (2):
- bash-completion: Add -S,-SP options arguments completion
- bash-completion: Fix/improve generator names extraction
-
-Jack O'Connor (1):
- Eclipse: Add a missing space in the documentation
-
-Jason Spiro (1):
- MinGW: Find mingw32-make included with Code::Blocks IDE (#14302)
-
-John Farrier (2):
- VS: Add Windows Forms Support
- VS: Add VS_GLOBAL_ROOTNAMESPACE target property
-
-Jonas Andersen (1):
- VS: Add Resx configuration to the vcxproj file
-
-LibArchive Upstream (1):
- libarchive 3.1.2 (reduced)
-
-Marc Bartholomaeus (4):
- cmake-gui: Add search functions for Output window (#9733)
- cmake-gui: Add search functions to the context menu of the Output widget
- cmake-gui: Change shortcut of the search field from Ctrl-F to Alt-E
- cmake-gui: Add function for going to next error message in Output window
-
-Marcel Loose (1):
- FindCUDA: Remove duplicate entries from INCLUDE_DIRECTORIES.
-
-Marius Schamschula (1):
- FindX11: Search in /opt/X11 for OS X 10.8 (#14232)
-
-Mathias Gaunard (1):
- FindCUDA: CUDA_COMPUTE_BUILD_PATH uses relative paths to binary dir.
-
-Matt McCormick (1):
- ExternalProject: Allow blank SVN_USERNAME/SVN_PASSWORD (#14128)
-
-Matthew Bentham (1):
- Xcode: Honor CMAKE_(MODULE|SHARED)_LINKER_FLAGS_<CONFIG> (#14161)
-
-Matthew Woehlke (3):
- UseJava.cmake: fully use cmake_parse_arguments in add_jar
- FindProtobuf: also find pthread
- UseJava.cmake: document add_jar compat shim
-
-Nicolas Despres (1):
- Optimize custom command full-path dependency lookup
-
-Nils Gladitz (1):
- Add cmake_host_system_information command
-
-Patrick Gansterer (20):
- Add option to use stdout/stderr of original terminal in cmake --build
- Unify the way the flags of a static library are read
- Add support for CMAKE_STATIC_LINKER_FLAGS
- Add CMAKE_STATIC_LINKER_FLAGS to CMakeCommonLanguageInclude
- Add documentation for the missing CMAKE_*_LINKER_FLAGS_* variables
- Add additonal tests for the linker flags
- VS6: Add handling of CMAKE_*_LINKER_FLAGS_<CONFIG> variables
- VS6: Hardcode id_machine_6 for compiler detection
- VS10: Do not set the TargetMachine when detecting the compiler
- VS: Set CMAKE_VS_PLATFORM_NAME for VS7 and VS71 too
- VS: Replace ArchitectureId with PlatformName
- VS12: Remove duplicated overload of UseFolderProperty()
- Fix detection of WinCE SDKs with 64bit verion of CMake
- VS: Unify how the name of the generator is specified
- VS10: Add support for assembler code (#11536)
- WIN: Use COFF file header header for architecture detection (#14083)
- Improve const-correctness in cmVisualStudioGeneratorOptions
- Fix setting of the entry point symbol for Windows CE (#14088)
- Add support for new Windows CE compiler
- VS11: Add support for Windows CE SDKs
-
-Paul Kunysch (1):
- CTest: Add test for running many tests in parallel
-
-Pavel Shramov (1):
- cmDependsC: Collapse relative include paths
-
-Petr Kmoch (5):
- Add projectDir parameter to GenerateBuildCommand
- VS: Create parser for Visual Studio .sln files
- VS: Use .sln parser to build targets in subdirs with msbuild (#13623)
- VS: Add test for building MSBuild project in subdir
- ctest_build: Pass projectDir to GenerateBuildCommand
-
-Reid Kleckner (1):
- Ninja: Make cmcldeps depfile output more consistent with 'ninja -t msvc'
-
-Richard Ulrich (3):
- CPackWIX: Handle multiple shortcuts in the start menu
- CPackWIX: Add option to specify the language(s) of the installer
- CMakeCPack: Provide an upgrade guid for WiX
-
-Robert Maynard (9):
- cmMakefile: Refactor AddCMakeDependFile and AddCMakeOutputFile.
- Ninja: Track configured files so we can regenerate them.
- cmMakefile: Track configured files so we can regenerate them (#13582)
- Add a test to expose a bug with add_custom_command and ninja.
- Ninja: GlobalNinjaGenerator WriteBuild and WritePhonyBuild non static
- Ninja: Custom Command file depends don't need to exist before building
- FindCUDA: Search for libraries in <prefix>/lib/<arch>/nvidida-current.
- Ninja: Properly convert all paths to unix style before we do set intersection.
- Ninja: Update BuildDepends test to verify cmcldeps depfiles.
-
-Robin Lee (1):
- FindOpenSSL: Fix spelling of CMAKE_CROSSCOMPILING (#14075)
-
-Rolf Eike Beer (25):
- FindOpenGL: simplify OS selection code
- FindOpenGL: require headers to be found on non-Windows platforms (#13746)
- Tests: create output files for all memory checkers
- CTest: use an output file for Valgrind (#14110)
- CTest: remove unreachable code and CTestTestMemcheckUnknown test
- Tests: remove code duplication in CTestTestMemCheck tests
- Tests: verify that memory checker output files are always present
- CTest: drop suppression for gcc 2.9.6 errors from default Valgrind flags
- Tests: add test for non-existent Valgrind suppression file
- CTest: fix comment documenting cmBoundsCheckerParser class
- Tests: add a test with custom options passed to valgrind
- CTest: make sure never to report negative test times (#14132)
- Doc: fix example for FAIL_REGULAR_EXPRESSION
- CTest: break after first regex match on output
- Tests: ignore Guard Malloc messages in MemChecker tests
- CTest: avoid useless changing of directory
- Tests: fix build of dummy memtester on AIX
- wizard: fix warnings
- wizard: simplify control flow
- cmTarget: drop the unused local typedef LinkLine
- Tests: ignore GuardMalloc messages on all Apple build, not just XCode ones
- replace string(... MATCHES "^const$) with string(... STREQUAL "const")
- Revert "CTest: fix pre and post test commands with spaces" (#13887)
- FindPNG: improve library detection (#14301)
- CTest: create one output file per memcheck (#14303)
-
-Sean McBride (1):
- Remove some uses of obsolete 'register' storage specifier
-
-Sebastian Leske (1):
- Document CMAKE_<LANG>_FLAGS variable (#14305)
-
-Stephen Kelly (126):
- Make the QtAutomoc test compile with either Qt 4 or Qt 5
- Add a test for Qt5Automoc
- Remove an endif() followed by an if() for the same condition.
- Fix some copyastos in the DetermineRCCompiler file.
- Test transitive includes from setting the LINK_LIBRARIES property.
- Test the use of target transitive compile definitions with moc.
- Fix handling of commas in arbitrary content in genexes.
- Fix style.
- Remove unused marker for a variable which is now used.
- Extract the ProcessArbitraryContent method.
- Rename the method determining if a genex accepts arbitrary content.
- Make it possible for any genex to have arbitrary content at the end.
- Add the JOIN generator expression.
- Test that linking using the debug keyword to tll works.
- automoc: Read target defines unconditionally
- Remove unused typedef.
- Fix brace indentation.
- Add EXPORT_NAME property.
- Remove unused vector population.
- Sublime: Honor source-level COMPILE_FLAGS property
- Docs: cmake -G selects a "build system" generator
- Recognize shared library files with a numerical suffix
- FindQt4: Fix QUIET failure with Qt 5 but not Qt 4
- Error on relative path in INCLUDE_DIRECTORIES target property.
- include_directories: Fix handling of empty or space-only entries
- CTest: Read CTEST_PARALLEL_LEVEL from environment
- string: Add MAKE_C_IDENTIFIER subcommand
- GenerateExportHeader: Add newlines to separate the compiler output.
- GenerateExportHeader: Allow use of of this macro with MODULEs.
- file: Add GENERATE command to produce files at generate time
- Tests/Module/GenerateExportHeader: Test exported free-function
- Add $<LINK_LANGUAGE> generator expression
- GenerateExportHeader: Generate only C identifiers as defines
- Tests/CompileDefinitions: Avoid spaces in defines on VS 6
- Use the qt5::moc imported target instead of a variable.
- QtAutomoc: Get the Qt version through the target link interface
- Fix indentation.
- VS6: Rename some variables to correspond to config values.
- Add cmLocalGenerator::GetCompileOptions.
- Add <LANG>_COMPILER_ID generator expressions.
- cmTarget: Rename struct to be more re-usable.
- cmTarget: Rename LinkInterfaceIncludeDirectoriesEntries
- Add COMPILE_OPTIONS target property.
- Add target_compile_options command.
- Introduce target property <LANG>_VISIBILITY_PRESET
- Add a COMPILE_OPTION for a VISIBILITY_INLINES_HIDDEN target property.
- Qt4Macros: Allow specifying a TARGET in invokations of macros.
- Introduce add_compile_options command.
- Remove unused cmAddDefinitionsCommand::ParseDefinition method.
- Add some spaces to the INCLUDE_DIRECTORIES documentation.
- CLI: Suppress the unused warning if the key value pair is cached.
- Use --sysroot when cross compiling.
- Add missing 'seen' check for evaluating COMPILE_OPTIONS.
- Find targets in INTERFACE_COMPILE_OPTIONS when exporting for try_compile.
- Use a preprocessor loop to manage the valid transitive properties.
- Generate INTERFACE_COMPILE_OPTIONS on export.
- Genex: Fix indentation in docs.
- cmSystemTools: Fix typo in comment.
- Style: Don't put an else after a return.
- Add compiler target compile options.
- QtAutomoc: Fix handling of list separator for compile definitions.
- QtAutomoc: Use config-dependent compile definitions and includes.
- De-duplicate version comparison code.
- Add generator expressions for version comparision.
- Don't run the WarnUnusedCliUnused test on Windows.
- Add whitespace after colons in error messages.
- Add missing return after error report.
- Genex: Make LINK_LANGUAGE report an error when evaluating link libraries.
- Genex: Extend EvaluatingLinkLibraries to also check the top target name.
- Genex: Report error if a target file is needed to evaluate link libraries.
- Add generator expressions for compiler versions.
- Split the GeneratorExpression test into a third part.
- Remove unused variable.
- Add Target API to determine if an include is a system include.
- Store system include directories in the cmTarget.
- Extend the cmTargetPropCommandBase interface property handling.
- Add a SYSTEM parameter to target_include_directories (#14180)
- Add entire link interface transitive closure as target depends.
- Test non-IMPORTED libraries in the INTERFACE of IMPORTED libraries.
- GenexEval: Add abstracted access to link interface for a target.
- Introduce the LINK_ONLY generator expression.
- Introduce the INTERFACE_LINK_LIBRARIES property.
- Export: Generate INTERFACE_LINK_LIBRARIES property on targets.
- TLL: Don't populate old link interface if CMP0022 is NEW.
- Overload cmLocalGenerator::AppendDefines to add a list.
- Add an overload of cmIDEOptions::AddDefines taking a vector of strings.
- Refactor cmTarget::GetCompileDefinitions to use an out-vector, not a string.
- Document some variables for deprecation control.
- Genex: Make CMP0021 and CMP0022 usable with TARGET_POLICY
- Revert "Use --sysroot when cross compiling."
- Add target property debugging for COMPILE_DEFINITIONS
- Mark qt4_use_modules and qt4_automoc as obsolete.
- Add the INTERFACE_SYSTEM_INCLUDE_DIRECTORIES target property.
- Don't add trailing whitespace to error message.
- Remove TODO to uniq COMPILE_OPTIONS
- Remove the LINK_LANGUAGE generator expression.
- Genex: Fix $<CONFIG> with IMPORTED targets and multiple locations.
- FindQt4: Don't use Qt component _FOUND vars before they're defined (#14286)
- Add a convenient way to add the includes install dir to the INTERFACE.
- Use linked frameworks as a source of include directories.
- target_link_libraries: Add PUBLIC/PRIVATE/INTERFACE keyword signature
- FindQt4: Re-add QAxServer to the QT_MODULES.
- FindQt4: Populate the INTERFACE_LINK_LIBRARIES of IMPORTED targets.
- Genex: Allow relative paths in INSTALL_INTERFACE.
- cmTarget: Fix property name typo in docs.
- Docs: Document file(GENERATE) CONDITION as optional.
- Qt4Macros: Remove unneeded generate CONDITION.
- Qt4Macros: Remove undefined varible use.
- Qt4Macros: Simplify some variable population.
- Docs: Document existing target property debugging options.
- Docs: Trim trailing whitespace in generated doc.
- Docs: Generalize and de-duplicate VISIBILITY_PREFIX docs.
- Docs: Document variables for default visibility values.
- Export: Fix typo of LINK_INTERFACE_LIBRARIES.
- cmTarget: Remove duplicates when printing traces of tll signatures
- cmTarget: Fix iface libraries and languages for static libraries.
- Genex: Disallow LINKER_LANGUAGE only when used on a static library.
- install: Remove error condition using INCLUDES DESTINATION without EXPORT.
- Fix crash on export of target with empty INTERFACE_INCLUDE_DIRECTORIES.
- Allow target commands to be invoked with no items (#14325).
- Docs: Fix typo in CMAKE_DEBUG_TARGET_PROPERTIES
- cmTarget: Add NAME property
- Export: Process generator expressions from INCLUDES DESTINATION.
- Add the ALIAS target concept for libraries and executables.
- Revert "Add compiler target compile options."
- Genex: Fix segfault when parsing ends with parameter expectation.
-
-Vadim Zhukov (1):
- Add cmake_reset_check_state() macro
-
-Victor Zverovich (1):
- Use GmakeErrorParser instead of deprecated MakeErrorParser (fixes bug 0013699)
-
-Yichao Yu (1):
- variable_watch: Add missing string enumeration entry (#14188)
-
-Ömer Fadıl USTA (3):
- ccmake: Add missing initializers reported by cppcheck
- libarchive: Fix free() order to avoid accessing freed memory
- cmcurl: Fix resource leak reported by cppcheck
-
-Changes in CMake 2.8.11.2 (since 2.8.11.1)
-------------------------------------------
-Alex Neundorf (1):
- asm support: adapt to changes in CMakeDetectCompiler in 2.8.10
-
-Bjoern Thiel (1):
- SelectLibraryConfigurations: Fix for cached <base>_LIBRARY
-
-Brad King (5):
- cmCryptoHash: Increase alignment of HashFile buffer
- cmcurl: Backport curl bug 1192 fix (#14250)
- VS12: Add Visual Studio 12 generator (#14251)
- VS12: Generate flag tables from MSBuild v120 tool files
- FindBoost: Add -vc120 mangling for VS 12
-
-Robert Maynard (1):
- VS: Clarify Visual Studio product year for each version
-
-Changes in CMake 2.8.11.1 (since 2.8.11)
-----------------------------------------
-Brad King (5):
- ExternalData: Do not re-stage staged object files
- try_compile: Fix quoting of libraries in generated CMakeLists.txt
- KWSys: Fix SystemTools::FileIsDirectory with long paths (#14176)
- FindBoost: Fix handling of \ in input paths (#14179)
- Xcode: Fix framework search paths in STATIC library targets (#14191)
-
-Modestas Vainius (1):
- Fix test failures caused by regexp-sensitive characters in the build paths
-
-Stephen Kelly (9):
- include_directories: Fix handling of empty or space-only entries
- try_compile: Trim whitespace from LINK_LIBRARIES entries
- cmTarget: Remove some hardcoding of transitive property names.
- GenexEval: Extract a getLinkedTargetsContent from TargetPropertyNode.
- GenexEval: Fix evaluation of INCLUDE_DIRECTORIES target property.
- GenexEval: Test evaluation of INCLUDE_DIRECTORIES target property.
- FindQt4: Don't fail if certain Qt modules are unavailable.
- Qt4Macros: Handle Qt ActiveX libraries in qt4_use_modules.
- Genex: Fix the HEAD target used for evaluated expressions
-
-Changes in CMake 2.8.11 (since 2.8.11-rc4)
-----------------------------------------
-None
-
-Changes in CMake 2.8.11-rc4 (since 2.8.11-rc3)
-----------------------------------------------
-Brad King (1):
- target_link_libraries: Update usage requirements documentation
-
-Stephen Kelly (3):
- Centralize maintenance of usage requirement include directories
- Fix include dir propagation from conditionally linked targets
- Memoize usage requirement include directories in a config-specific map
-
-Changes in CMake 2.8.11-rc3 (since 2.8.11-rc2)
-----------------------------------------------
-Brad King (1):
- get_filename_component: Document path components more clearly (#14091)
-
-Rolf Eike Beer (1):
- try_compile: add missing fclose() to recently added error case
-
-Stephen Kelly (1):
- Fix clearing of the INCLUDE_DIRECTORIES DIRECTORY property.
-
-Changes in CMake 2.8.11-rc2 (since 2.8.11-rc1)
-----------------------------------------------
-Alex Neundorf (6):
- Determine C/CXX/Fortran compiler: minor restructuring
- Determine C/CXX/Fortran compiler: fix indentation
- rename TI_DSP toolchain to TI, since it works also for the ARM compiler
- TI compiler: add automatic detection of prefix and suffixes
- Modules/readme.txt: switch from "XXX" to "Xxx"
- Modules/readme.txt: make lines a bit shorter for easier readability
-
-Ben Boeckel (1):
- Clang: Add -isystem flag support everywhere
-
-Bill Hoffman (1):
- ExternalProject: Retry on a failed git clone
-
-Brad King (8):
- string: Fix regex documentation of '^' and '$' (#14028)
- Rename variable for including current directory in interfaces
- Replace <TARGET> in CMAKE_<LANG>_COMPILE_OBJECT rule variables
- Test evaluation of per-config COMPILE_DEFINITIONS (#14037)
- VS: Fix VS 10/11 .sln headers (#14038)
- add_dependencies: Distinguish target v. file dependencies in error (#14050)
- automoc: Use a pre-build event in VS >= 7
- Handle usr-move without forcing absolute paths (#14041)
-
-Clinton Stimpson (2):
- FindQt4: If Qt5 is in CMAKE_PREFIX_PATH, be sure to find Qt4 includes.
- Qt4: Fix typo setting a variable for FindThreads.
-
-James Bigler (1):
- FindCUDA: Use the PRE_LINK mode only for MSVC >= 10
-
-Matthew Woehlke (4):
- UseJava.cmake: simplify path logic
- UseJava.cmake: fix passing jars to add_jar
- UseJava.cmake: accept jar targets in add_jar
- UseJava.cmake: require explicit request to include jars
-
-Paul Kunysch (1):
- CPack: Avoid "format expects 'unsigned int'" warnings
-
-Petr Kmoch (1):
- cmSystemTools: Generalize TrimWhitespace to all whitespace
-
-Rex Dieter (1):
- FindImageMagick: Search versioned suffixes (#14012)
-
-Rolf Eike Beer (1):
- FindRuby: improve version selection
-
-Stephen Kelly (13):
- FindQt4: Set the Qt4_FOUND variable if Qt4 is found
- FindQt4: Set the INTERFACE_QT_MAJOR_VERSION for Qt4::QtCore
- Document that CMAKE_AUTOMOC works with Qt 5.
- FPHSA: Fix FOUND_VAR check to work with if() auto-dereference
- Fix cmGeneratorExpression::Preprocess for interleaved inputs.
- cmake-gui: Use the QStandardItemModel workaround until 5.1.0.
- Automoc: append implicit includes after user-specified dirs
- Fix the evaluation of per-config COMPILE_DEFINITIONS (#14037)
- Fix new target commands documentation.
- install(EXPORT): Ensure clean INTERFACE_INCLUDE_DIRECTORIES
- Report an error on IMPORTED targets with a faulty INTERFACE
- Error if linked target has relative paths in INTERFACE_INCLUDE_DIRECTORIES
- Fix the Qt 5 version required to run the IncompatibleQt test.
-
-Changes in CMake 2.8.11-rc1 (since 2.8.10.2)
-----------------------------------------------
-Alan Witkowski (1):
- FindBullet: Search in per-config dirs on Windows (#13738)
-
-Aleksey Avdeev (1):
- Add module FindIcotool
-
-Alex Neundorf (30):
- Eclipse: add switch to disable linked resources (#13189)
- Eclipse: set source path once to fix Eclipse indexer (#13596)
- cmDependsC: remove unused member variable
- cmDependsC: remove code duplication
- cmDependsC: fix indentation
- cmDepends: allow multiple dependees per depender
- AddCustomCommand: Handle multiple IMPLICIT_DEPENDS files (#10048)
- Add support for Texas Instruments DSP compiler (#12405)
- Squish: detect version
- Squish: use FPHSA
- Squish: find executables also under Windows
- Squish: rename squish_add_test() to squish_v3_add_test() and fix docs a bit
- Squish: use ${CMAKE_CURRENT_LIST_DIR}
- Squish: add support for squish 4 (#9734)
- Squish: fix new squish_v4_add_test() macro
- Automoc: "inherit" FOLDER target property from target (#13688)
- FPHSA: don't succeed if only checking for XX_FOUND (#13755)
- CONFIGURE_PACKAGE_CONFIG_FILE(): improve generated comments
- Automoc: get include dirs without stripping implicit include dirs off
- configure_package_config_file: force absolute paths for usr-move
- configure_package_config_file(): fix indentation
- configure_package_config_file(): extend documentation
- documentation: handling of relative paths by include- and link_directories()
- automoc: use a std::vector<> instead a std::list
- automoc: use the header extensions from cmMakefile
- Eclipse: also detect include dirs and macro for clang (#13823)
- cmLocalGenerator: remove "virtual" where not used
- export files: rewrite the code for checking required targets
- FPHSA: Add FOUND_VAR option to specify _FOUND variable name
- FPHSA: improve documentation
-
-Alexander Chehovsky (2):
- Xcode: Fix nested source group handling (#12943)
- Xcode: Sort source files
-
-Amine Chadly (2):
- file: remove dead code
- Add test to secure the file(GLOB empty) behavior.
-
-Amit Kulkarni (6):
- OpenBSD: Install shared libraries without executable permission
- OpenBSD: Add paths for Java 1.6.0/1.7.0 JRE/JDK
- OpenBSD: Add path for Freetype under X.org
- OpenBSD: Add paths for Tcl/Tk 8.4/8.5
- OpenBSD: Add path for Lua 5.1
- OpenBSD: Add paths for Qt3/Qt4
-
-Andreas Mohr (4):
- Documentation: Correct typos and grammar
- Documentation: Clarify some command descriptions
- Correct string literal typo (have "(NULL)" like all other cases).
- Remove seemingly bogus duplicate CPACK_PACKAGE_FILE_NAME call.
-
-Anton Helwart (1):
- VS: Avoid empty source groups in some cases (#3474)
-
-Benjamin Eikel (2):
- Swap linking order of SDLmain and SDL (#0013769)
- FindSDL_...: Restore dropped search paths (#13819)
-
-Brad King (109):
- find_library: Refactor internal name iteration
- find_library: Simplify framework search logic
- find_library: Generalize helper macro in test case
- find_library: Optionally consider all names in each directory
- FindBoost: Remove extra indentation level
- FindBoost: Mark Boost_DIR cache entry as advanced
- FindBoost: Use PATH_SUFFIXES to look in "Program Files"
- FindBoost: Overhaul caching and search repeat behavior
- FindBoost: Construct a clean Boost_LIBRARIES value
- FindBoost: Refactor Boost_FOUND computation and version check
- FindBoost: Rewrite documentation
- BSD: Do not require dlfcn.h to build shared libs (#13573)
- Xcode: Fix ReRunCMake.make path to cmake.check_cache (#13603)
- VS10: Refactor link options collection
- VS10: Honor /DELAYSIGN and /KEYFILE flags (#13601)
- Document external language support policy
- CTest: Allow SUBMIT_INDEX with CDash
- KWSys: Submit dashboard builds to PublicDashboard
- pre-commit: Update KWSys rejection message for new workflow
- CTestCustom: Suppress LNK4089 warning about PSAPI
- load_command: Deprecate and document pending removal
- Documentation: Clarify configure_file behavior
- OS X: Warn about known SDK breakage by Xcode 3.2.6
- Optionally skip link dependencies on shared library files
- Teach BuildDepends test to cover LINK_DEPENDS_NO_SHARED
- Serialize tests for EXCLUDE_FROM_DEFAULT_BUILD
- MSVC: Drop default use of /Zm1000 for VS >= 7.1
- Teach find_(path|file) about Linux multiarch (#13742)
- Test find_path multiarch support (#13742)
- Add policy CMP0019 to skip include/link variable re-expansion
- Xcode: Add frameworks search paths from link dependeny closure (#13397)
- Makefile: Use modern link information for framework search paths
- Documentation: Clarify handling of implicit link directories
- Remove references to KWSys Process Win9x support
- add_library: Document object library portability suggestion
- OS X: Link with all framework search paths, not just the last
- OS X: Detect implicit link directories on modern toolchains
- OS X: Detect implicit linker framework search paths
- Revert "load_command: Deprecate and document pending removal"
- VS11: Simplify external object file handling (#13831)
- KWIML: Teach ABI about 'long long' on older GNU
- CMake: Skip empty link.txt lines (#13845)
- ExternalProject: Allow DEPENDS on normal targets (#13849)
- VS11: Fix VSExternalInclude test
- target_link_libraries: Document that new sigs privatize old (#13876)
- Tests: Avoid CTestLimitDashJ crash on Borland 5.8 builds
- Fix use of cmTypeMacro in new command classes
- Fix cmSystemTools::RenameFile race on Windows
- VS 6: Create .rule file directory before file
- Add ExternalData module
- ExternalData: Remove compatibility with CMake < 2.8.5
- ExternalData: Do not match directory names when resolving DATA{}
- ExternalData: Cleanup stray TODO and typo in comments
- ExternalData: Remove unused private interface
- ExternalData: Improve series matching using an explicit syntax
- ExternalData: Add tests covering interfaces and errors
- ExternalData: Allow ()-groups in series match regex
- ExternalData: Allow DATA{} syntax to reference directories
- ExternalData: Generalize hash algo/ext handling
- ExternalData: Add support for SHA 1 and 2 hash algorithms
- ExternalData: Collapse ../ components in DATA{} paths
- Fix Module.ExternalData test on Cygwin
- Fix Module.ExternalData test on VS 6
- ExternalData: Attach download rules to content links in IDEs
- find_package: Reword <package>_NO_INTERFACES documentation
- Normalize full paths in implicit link library list
- Fail early if no current working directory exists
- MSVC: Fix CMAKE_CL_64 in CXX-only projects (#13896)
- ExternalProject: Simplify CMake command line generation
- Tests: Run ctest custom commands with VERBATIM
- CMake: Add -T option to choose a generator toolset
- VS: Implement generator toolset selection (#10722, #13774)
- Xcode: Implement generator toolset selection (#9831, #13802)
- CTest: Add options to set generator toolset
- ExternalProject: Propagate the generator toolset
- Tests: Consolidate ctest --build-and-test generator options
- Tests: Add generator toolset support
- Fix crash on empty CMAKE_<lang>_COMPILER value (#13901)
- file: Do not remove symlinked directories recursively (#10538)
- Embarcadero: Fix default link stack/heap flags (#13912)
- Avoid duplicate RPATH entries
- AIX-GNU: Put implicit link directories in runtime libpath (#13909)
- VS: Replace generation timestamp file atomically
- VS,Xcode: Remove unused CMAKE_GENERATOR_* variables
- Delete entire CMakeFiles directory when deleting CMakeCache.txt (#13756)
- Tests/RunCMake: Allow tests to control build tree behavior
- Test Unix Makefiles generator support for changing compilers
- Xcode: Drop check for circular target dependencies
- Xcode: Each target dependency edge needs a unique object (#13935)
- Tests: Replace exec_program with execute_process
- Tests: Generalize decision for 'make' tool supporting spaces
- ExternalData: Test content link with a space in its name
- FPHSA: Convert FOUND_VAR failure test to RunCMake
- VS: Restore CMAKE_GENERATOR_FC variable
- Xcode: Generate recommended artwork setting (#13954)
- CTest: Fix ctest_update with 'HEAD' file in source tree
- VS 10: Fix CMAKE_<LANG>_STACK_SIZE implementation (#13968)
- install(EXPORT): Force absolute paths for usr-move
- AIX: Do not use -brtl to create shared libraries (#13997)
- add_subdirectory: Compute output dir with consistent slashes (#10072)
- ExternalData: Preserve escaped semicolons during argument expansion
- Avoid crash when checking property link dependencies without link info
- Avoid crash when checking property compatibility without link info
- Refactor RunCMake.build_command test to allow more cases
- build_command: Fail early without CMAKE_MAKE_PROGRAM (#14005)
- CTest: Fail early without PROJECT_BINARY_DIR (#14005)
- FindQt4: Fix QT_QMAKE{_QMAKE => }_EXECUTABLE typo
- XL: Use -qpic for position independent code (#14010)
- Configure Tests/CMakeTests only with BUILD_TESTING ON
-
-Casey Goodlett (1):
- CTest: Prevent creation of unbounded number of tests in ctest (#12904)
-
-Clemens Heppner (1):
- CMake: source_group needs to check its own regex after its children (#13611)
-
-Clinton Stimpson (5):
- Fix for possible Rez errors when creating dmg.
- PackageMaker: Enable postflight script in component mode (#12375)
- CPack: Fix RPM/Deb package names to not include "ALL_COMPONENTS_IN_ONE"
- Qt4: Add SYSTEM option to include_directories.
- FindQt4: set QT_VERSION_* variables sooner.
-
-David Cole (19):
- Begin post-2.8.10 development
- CPack: Add automatic detection of the Unicode makensis (#9629)
- BundleUtilities: Use a more inclusive REGEX for frameworks (#13600)
- VS: Avoid empty, unreferenced solution folders... (#13571)
- NMake: Add a test to demonstrate EmptyDepends issue (#13392)
- NMake: Fix problem with empty DEPENDS args (#13392)
- CMake: Remove "/STACK:10000000" from default linker flags (#12437)
- Watcom: Avoid prompt from wmake about dll with no exports...
- Tests: Use the right path to CPack value for running CPack tests
- VS11: Allow using folders with the VS11 Express Edition (#13770)
- CPack: Fix dashboard errors (#11575)
- CPack: Fix dashboard warnings (#11575)
- CPack: Fix dashboard errors and warnings (#11575)
- CMake: Stylistic changes and documentation tweaks
- CMake: Fix dashboard warnings
- CMake: Fix dashboard test failure
- CMake: Fix dashboard build errors and warnings
- CTest: Coverage handler: expect certain output lines from gcov 4.7 (#13657)
- Add CTestLimitDashJ test (#12904)
-
-David Golub (2):
- CPack/NSIS: Fix compatibility issues with prerelease NSIS (#13202)
- CPack/NSIS: Add support for 64-bit NSIS (#13203)
-
-Eric LaFranchi (1):
- CPack: WIX Product Icon, UI Banner, UI Dialog support (#13789)
-
-Eric NOULARD (1):
- CPackRPM fix #13898 uses IF(DEFINED var) to avoid wrong var value logic
-
-Gerald Hofmann (1):
- CPack: Fix NSIS version check without release version (#9721)
-
-James Bigler (4):
- Use PRE_LINK instead of PRE_BUILD when testing PRE_LINK.
- FindCUDA: Remove linkage against CUDA driver library (#13084)
- FindCUDA: Add support for separable compilation
- FindCUDA: Added cupti library.
-
-Janne Rönkkö (1):
- FindQt4: Do not use qmake from Qt5
-
-Jean-Christophe Fillion-Robin (1):
- Add $<SEMICOLON> generator expression.
-
-Marcus D. Hanwell (1):
- Removed GenerateExportHeader warnings about old compilers
-
-Mark Salisbury (2):
- VS: Specify WinCE subsystem also for DLLs
- VS: Specify WinCE subsystems correctly in VS 9 2008
-
-Mathias Gaunard (2):
- enable CTEST_USE_LAUNCHERS with Ninja too
- Ninja: fix usage of cldeps with ctest launchers
-
-Matt McCormick (7):
- ExternalProject: Only run 'git fetch' when required.
- ExternalProject: Do smoke tests for Git Tutorial builds.
- ExternalProject: Add tests for UPDATE_COMMAND.
- ExternalProject: Always do a git fetch for a remote ref.
- ExternalProject: Make sure the ExternalProjectUpdate setup is available.
- ExternalProject: Verify when a fetch occurs during update test.
- ExternalProjectUpdateTest: Only support Git 1.6.5 and greater.
-
-Matthew Woehlke (1):
- ccmake: Allow DEL key in first column
-
-Michael Tänzer (4):
- GetPrerequisites: Move tool search paths up
- GetPrerequisites: Add support for objdump
- GetPrerequisites: Enable test for BundleUtilities on MinGW
- GetPrerequisites: Add documentation for objdump
-
-Michael Wild (1):
- cmDepends: No dependency-vector erasure in CheckDependencies
-
-Morné Chamberlain (15):
- Added a generator for Sublime Text 2 project files.
- Added some support for sublimeclang_options in the generated project file.
- Changed SublimeClang include path generation to expand to absolute paths.
- Cleaned up the Sublime Text 2 Generator code a bit.
- Fixed support for the Ninja build system.
- Added and cleaned up some comments.
- The generator no longer generates an explicit list of source files.
- The generator no longer generates absolute paths to the ninja.build/Makefiles.
- Added a CMAKE_SUBLIMECLANG_DISABLED variable that disables SublimeClang.
- Fixed Sublime Text project generation for in-source builds
- Define flags in CMAKE_C(XX)_FLAGS are now included in SublimeClang settings.
- SublimeText2 Gen: Improved use of define, include flags from CMAKE_C(XX)_FLAGS
- SublimeText2 Gen: Fixed the issue where include directory flags used -D
- Sublime Text 2 Gen: Per-source Compile flags are now saved in a separate file.
- SublimeText 2 Gen: Set the sublimeclang_options_script property.
-
-Neil Carlson (1):
- NAG: Use -PIC for Fortran position-independent code (#13932)
-
-Nils Gladitz (2):
- CPack: Add a WiX Generator (#11575)
- CMake: Add TIMESTAMP subcommand to string and file commands
-
-Patrick Gansterer (28):
- Introduce the abstract class cmGlobalGeneratorFactory
- Add cmGlobalGeneratorFactory::GetGenerators()
- Search generator in cmake::ExtraGenerators before in cmake::Generators
- Allow a GeneratorFactory handling of more than one generator
- Make cmGlobalGenerator::GetDocumentation() a static function
- VS: Remove AddPlatformDefinitions from platform-specific generators
- VS: Fix ArchitectureId of Visual Studio 10 IA64 generator
- VS: Remove GetPlatformName from platform-specific generators
- VS: Remove EnableLanguage from platform-specific generators
- VS: Remove platform specific generator files
- FindBISON: Add support for the Win flex-bison distribution
- FindFLEX: Add support for the Win flex-bison distribution
- VS: Remove TargetMachine for linker when checking compiler id
- VS: Add CMAKE_VS_PLATFORM_NAME definition to cmMakefile
- VS: Add static method to get the base of the registry
- VS: Change variable type of ArchitectureId from const char* to string
- VS: Change variable type of Name from const char* to string
- VS: Support setting correct subsystem and entry point for WinCE
- VS: Add parser for WCE.VCPlatform.config to read WinCE platforms
- VS: Allow setting the name of the target platform
- VS: Make DetermineCompilerId working with WinCE too
- VS: Added "Deploy" at project configuration for WindowsCE targets
- Add command to generate environment for a Windows CE SDK
- VS: Set the correct SubSystem when determinating the CompilerId
- VS: Add the entry point when compiling for WindowsCE
- VS: Ignore LIBC.lib when linking the CompilerId executables
- Set WINCE to 1 when building for WindowsCE
- Ninja: Avoid LNK1170 linker error
-
-Peter Kümmel (6):
- Ninja: encode LINK_FLAGS to handle bash variables
- Ninja: fix building from Codeblocks GUI
- Ninja: remove implicit dependency on custom command outputs
- Ninja: use MinGW generator code in EnableLanguage()
- Ninja: the Ninja generator does not support Fortran yet.
- Ninja: escape line breaks in literals
-
-Petr Kmoch (11):
- Add tests for list() argument count
- Add tests for list() invalid arguments
- Consolidate list() argument count testing
- Add several get_property() tests
- Add tests for EXCLUDE_FROM_DEFAULT_BUILD
- Add property EXCLUDE_FROM_DEFAULT_BUILD_<CONFIG>
- Define property EXCLUDE_FROM_DEFAULT_BUILD
- Add tests for VS_SOLUTION_GLOBAL_SECTIONS
- Implement properties VS_GLOBAL_SECTION_*
- Define properties VS_GLOBAL_SECTION_*
- Documentation: Clarify a few subtleties
-
-Riku Voipio (1):
- KWIML: Teach ABI.h about Aarch64
-
-Robert Maynard (4):
- XCode generator won't infinitely parse compiler flags (bug #13354).
- Correct missing parameter to CMP0018Flags call.
- Remove ability to generate sublime clang files.
- Update generator to use new cmGeneratorTarget api.
-
-Rodolfo Schulz de Lima (1):
- FindGTK2: Fix GTK2_LIBRARIES order for static gtk libraries
-
-Rolf Eike Beer (21):
- FindQt: improve version selection
- FindQt: add some more places to look for Qt3
- Tests: add MajorVersionSelection tests
- Linux/PA-RISC: Link with --unique=.text.* to help binutils
- FindQt: add to MajorVersionSelection test
- CMakeTests: allow to call the check_cmake_test macro with a given file
- list: add tests for CMP0007 behavior
- GetProperty test: move doc property tests into main process
- Find* (and some other): use ${CMAKE_CURRENT_LIST_DIR} in include()
- bootstrap: use better defaults for Haiku
- Haiku no longer defines __BEOS__
- check for Haiku only with __HAIKU__
- FindLua51: do not try to link libm on BeOS
- FindGLUT: BeOS does not have libXi and libXmu
- FindOpenGL: add Haiku paths
- doc: fix linebreaks in generator expression documentation
- ProcessorCount test: fix path to cmsysTestsCxx executable
- ProcessorCount test: require SystemInformation process to work
- FindOpenMP: improve documentation (#13895)
- properly detect processor architecture on Windows
- fix Windows processor detection
-
-Sean McBride (1):
- libarchive: fixed undefined left shift with signed ints
-
-Slava Sysoltsev (1):
- FindImageMagick: Search quantum depth suffixes (#13859)
-
-Stephen Kelly (158):
- GenEx: Test early determination of AND and OR
- Enable some compiler warnings when building CMake.
- Resolve warnings about unused variables.
- Resolve warnings about used enum values in switch blocks.
- Resolve warnings about shadowing parameters and local variables.
- Resolve ambiguity warning regarding use of && and ||.
- Remove references to ancient and removed parts of the code.
- Always use the auto_ptr from cmsys.
- Port cmGeneratorExpression to cmTarget from cmGeneratorTarget.
- Split link information processing into two steps.
- Revert "Move GetLinkInformation to cmGeneratorTarget"
- Genex: Extract a method to parse parameters.
- Genex: Ensure that $<0:...> has a parameter.
- Genex: Don't segfault on $<FOO,>
- Generate an early-return guard in target Export files.
- Fix some warnings from -Wundef
- Make targets depend on the link interface of their dependees.
- Use cmsys::auto_ptr to manage cmCompiledGeneratorExpressions
- Keep track of INCLUDE_DIRECTORIES as a vector of structs.
- Add a way to print the origins of used include directories.
- Tests: Fix warning about unused variable
- Qt4: Add module dependencies to the IMPORTED targets
- Don't crash when a target is expected but is not available.
- Add test for custom command with a genex referring to a target.
- GenEx: Add expressions to specify build- or install-only values
- Allow generator expressions to require literals.
- Add the TARGET_NAME generator expression.
- Add API to extract target names from a genex string.
- Add API to populate INTERFACE properties in exported targets.
- Make all relevant targets available in the genex context.
- Use mapped config properties to evaluate $<CONFIG>
- Make cycles in target properties ignored, not an error.
- Populate the ExportedTargets member early in GenerateMainFile
- Handle INTERFACE properties transitively for includes and defines.
- Add CMAKE_BUILD_INTERFACE_INCLUDES build-variable.
- Make linking APIs aware of 'head' target
- Add LINK_LIBRARIES property for direct target link dependencies
- Allow target_link_libraries with IMPORTED targets.
- Add the -Wundef flag when compiling CMake.
- FindQt4: Add INTERFACE includes and defines to Qt4 targets
- Add the target_include_directories command.
- Add the target_compile_definitions command.
- Keep track of properties used to determine linker libraries.
- Add API to calculate link-interface-dependent bool properties or error.
- Process the INTERFACE_PIC property from linked dependencies
- Fix linking to imported libraries test.
- Add cmGeneratorExpression::Split() API.
- Don't pass a position when determining if a target name is a literal.
- Extract the AddTargetNamespace method.
- Split the generator expression before extracting targets.
- Split LINK_INTERFACE_LIBRARIES export handling into dedicated method.
- Allow generator expressions in LINK_INTERFACE_LIBRARIES.
- Add a way to check INTERFACE user property compatibility.
- Don't include generator expressions in old-style link handling.
- Document the use of generator expressions in new commands.
- Add the TARGET_DEFINED generator expression
- Strip consecutive semicolons when preprocessing genex strings.
- Don't write a comment in the export file without the code.
- Only generate one check per missing target.
- Move the exported check for dependencies of targets
- Move the exported check for file existence.
- Add a test for the interfaces in targets exported from the build tree.
- Make the BUILD_INTERFACE of export()ed targets work.
- Export the INTERFACE_PIC property.
- Test evaluation target via export for generator expressions
- Make sure generator expressions can be used with target_include_directories.
- Populate the link information cache before checking dependent properties.
- Exit early if we find an inconsistent property.
- Make INTERFACE determined properties readable in generator expressions.
- Clear the link information in ClearLinkMaps.
- Export the COMPATIBLE_INTERFACE_BOOL content properties
- Add the $<TARGET_POLICY> expression
- Automatically link to the qtmain library when linking to QtCore.
- Don't wrap all targets in LINK_LIBRARIES in a TARGET_NAME genex.
- Generate new-style cmake code during export.
- Store includes from the same include_directories call together.
- Only output includes once after the start of 'generate-time' when debugging.
- Specify the target whose includes are being listed.
- Output include directories as LOG messages, not warnings.
- Revert "Allow target_link_libraries with IMPORTED targets."
- Disallow porcelain to populate includes and defines of IMPORTED targets.
- Exclude the LINK_LIBRARIES related properties from INTERFACE evaluation.
- Make calculation of link-interface-dependent properties type-sensitive.
- Add the COMPATIBLE_INTERFACE_STRING property.
- Move GetCompileDefinitions to cmTarget.
- Process COMPILE_DEFINITIONS as generator expressions in QtAutomoc.
- Generate the _IMPORT_PREFIX in the non-config export file.
- Add the INSTALL_PREFIX genex.
- Fix TARGET_PROPERTY target extractions.
- Make the Property name protected so that subclasses can use it.
- Don't allow targets args in the new target commands.
- Make subclasses responsible for joining content.
- Use the result of converting to a unix path.
- Handle reading empty properties defined by the link interface.
- Advance more when preprocessing exported strings.
- Make it an error for INSTALL_PREFIX to be evaluated.
- Export targets to a targets file, not a Config file.
- Add a way to exclude INTERFACE properties from exported targets.
- Add API to check if we're reading a includes or defines property.
- Add the $<LINKED:...> generator expression.
- Add includes and compile definitions with target_link_libraries.
- Test workaround of bad interface include directories from depends.
- Optimize genex evaluation for includes and defines.
- Cache context-independent includes on evaluation.
- Style: Use this-> when invoking member functions.
- Process generator expressions for 'system' include directories.
- Deduplicate the isGeneratorExpression method.
- De-duplicate validation of genex target names.
- Test printing origin of include dirs from tll().
- The COMPATIBLE_INTERFACE does not affect the target it is set on.
- Ensure type specific compatible interface properties do not intersect.
- Fix generation of COMPILE_DEFINITIONS in DependInfo.cmake.
- Fix determination of evaluating link libraries.
- Only use early evaluation termination for transitive properties.
- Move a special case for PIC from the genex to the cmTarget code.
- Don't keep track of content determined by target property values.
- Only append build interface include dirs to particular targets.
- Ensure that the build interface includes have been added.
- Whitelist target types in target_{include_directories,compile_definitions}
- Make sure INTERFACE properties work with OBJECT libraries.
- Don't allow utility or global targets in the LINKED expression.
- Generate config-specific interface link libraries propeties.
- Fix determination of when we're evaluating compile definitions.
- Rename the IncludeDirectoriesEntry to be more generic.
- Don't use LINKED where not needed.
- Use the link information as a source of compile definitions and includes.
- Revert "Don't allow utility or global targets in the LINKED expression."
- Don't populate INTERFACE includes and defines properties in tll.
- Revert "Add the $<LINKED:...> generator expression."
- Revert "find_package: Reword <package>_NO_INTERFACES documentation"
- Revert "Add a way to exclude INTERFACE properties from exported targets."
- Don't add target-specific interface includes and defines to Qt 4 targets.
- Fix GenerateExportHeader documentation #13936
- automoc: Add source file to target early to set the linker language
- Keep track of all targets seen while evaluating a genex.
- Add a new Export generator for IMPORTED targets.
- Handle targets in the LINK_LIBRARIES of try_compile.
- Strip stray semicolons when evaluating generator expressions.
- Workaround broken code where a target has itself in its link iface.
- Fix DAG checker finding cycling dependencies.
- Expand includes and defines transitively in 'external' genexes.
- Fix constness of accessors.
- Fix the tests for evaluating includes and defines.
- Memoize includes and defines from interface libraries.
- Remove use of TARGET_DEFINED from target_include_directories test.
- Remove use of TARGET_DEFINED from the ExportImport test.
- Remove use of TARGET_DEFINED from the target_link_libraries test.
- Revert "Add the TARGET_DEFINED generator expression"
- Only add existing targets to the Qt4 target depends properties.
- Fix the cmGeneratorExpression::Split when leading chars are present.
- Fix RPATH information when only a genex is used as a link library.
- Mention that IMPORTED targets may be created by a find_package call.
- Remove unused parameters from target_link_libraries tests.
- Only process transitive interface properties for valid target names.
- Restore support for target names with '+' (#13986)
- Automoc: Don't create automoc targets if Qt is not used (#13999)
- cmake-gui: Use -fPIE if required by Qt.
- cmake-gui: Workaround bug in Qt 5.0.0 to 5.0.3 QStandardItemModel
-
-Thomas Klausner (1):
- KWIML: Teach ABI.h that VAX is big endian
-
-Yury G. Kudryashov (3):
- Automoc: Fix automoc for OBJECT libraries.
- Automoc: add OBJECT library to QtAutomoc test
- spell: fix a few typos in comments
-
-Changes in CMake 2.8.10.2 (since 2.8.10.1)
-----------------------------------------------
-Alex Neundorf (1):
- Automoc: fix regression #13667, broken build in phonon
-
-Brad King (1):
- Initialize IMPORTED GLOBAL targets on reconfigure (#13702)
-
-David Cole (1):
- CMake: Fix infinite loop untarring corrupt tar file
-
-Rolf Eike Beer (1):
- FindGettext: fix overwriting result with empty variable (#13691)
-
-Changes in CMake 2.8.10.1 (since 2.8.10)
-----------------------------------------------
-Brad King (5):
- Fix default PDB output directory (#13644)
- Fix PathScale compiler id for Clang-based upstream
- Update programmatically-reported copyright year (#13638)
- FindSDL: Restore accidentally dropped search paths (#13651)
- OS X: Fix default CMAKE_OSX_SYSROOT with deployment target
-
-Rolf Eike Beer (2):
- FindOpenSSL: fix library selection on Windows (#13645)
- FindOpenSSL: also find the non-MD debug libraries for MSVC
-
-Stephen Kelly (1):
- GenEx: Use case insensitive comparison for $<CONFIG:...>
-
-Changes in CMake 2.8.10 (since 2.8.10-rc3)
-----------------------------------------------
-None
-
-Changes in CMake 2.8.10-rc3 (since 2.8.10-rc2)
-----------------------------------------------
-Rolf Eike Beer (2):
- SelectLibraryConfigurations: add testcase
- SelectLibraryConfigurations: fix for release and debug libs being the same
-
-Stephen Kelly (5):
- BasicConfigVersion: Make docs refer to the macro, not the module name
- Document LOCATION undefined behavior with use of LINKER_LANGUAGE.
- GenEx: Add an accessor for imported targets in a makefile.
- GenEx: Create cmGeneratorTargets for imported targets.
- GexEx: Validate Target names and property names differently.
-
-Thomas Arcila (1):
- SelectLibraryConfigurations: Fix foreach(x IN LISTS ...) syntax
-
-Changes in CMake 2.8.10-rc2 (since 2.8.10-rc1)
-----------------------------------------------
-Alex Neundorf (2):
- Document CMAKE_FIND_PACKAGE_NAME
- Automoc: fix #13572: issue with symbolic links
-
-Brad King (4):
- cmCTestSVN: Fix compilation with Sun CC 5.1
- if: Document that plain 'NOTFOUND' is a false constant
- string: Clarify regex documentation of '-' behavior
- FortranCInterface: Pass all flags to VERIFY project (#13579)
-
-David Cole (1):
- NSIS: Fix incorrect uninstall registry key name (#13578)
-
-Eric NOULARD (3):
- CPACK_XX_ON_ABSOLUTE_INSTALL_DESTINATION is now properly checked for ON/OFF
- Document CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY and fix some typo.
- Make CPACK_SET_DESTDIR work with archive generator + component-based packaging
-
-Jean-Christophe Fillion-Robin (1):
- CTest: Ensure CTEST_USE_LAUNCHERS behaves nicely in Superbuild setup
-
-Pere Nubiola i Radigales (1):
- Find PostgreSQL headers on Debian
-
-Peter Kümmel (4):
- Ninja: also set OBJECT_DIR when compiling
- Ninja: don't pollute current dir when using gui (#13495)
- Ninja: implicit dependency for custom command files
- Fix regression: write compile definitions if any
-
-Philip Lowman (4):
- FindGTK2: Rollback lib64 changes which broke header file finding
- FindGTK2: #12049 fix detection of header files on multiarch systems
- FindGTK2: #12596 Missing paths for FindGTK2 on NetBSD
- FindGTK2: Update local changelog
-
-Rolf Eike Beer (6):
- CTest: fix usage of memory checker with spaces in path
- CTest: fix pre and post test commands with spaces
- CTest: add tests that simulate memcheck runs
- CTest: improve memory checker type detection
- CTest: add a test for CTEST_CUSTOM_MEMCHECK_IGNORE
- CTest: add a check with a quoted memory checker
-
-Stephen Kelly (18):
- GenEx: It is not an error to specify an empty parameter
- GenEx: Return after error reported.
- GenEx: Report actual target name not found, not "0" each time.
- GenEx: Parse comma after colon tokens specially
- GenEx: Validate target and property names.
- GenEx: Ensure that the empty CONFIGURATION can be used conditionally.
- GenEx: Add test for $<BOOL:> with empty parameter.
- GenEx: Add tests for "0" and "1" expressions with literal commas.
- GenEx: Don't use std::vector::at(int).
- Attempt to fix the compile of cmake on Sun CC.
- GenEx: Parse colon after arguments separator colon specially.
- GenEx: Test the use of generator expressions to generate lists.
- GenEx: Fix termination bugs in generator expression parser.
- GenEx: Break if there are no more commas in the container
- GenEx: Add some more asserts to verify code-sanity.
- GenEx: Replace some failing tests with Borland and NMake makefiles.
- GenEx: Fix reporting about not-found include directories and libraries.
- Fix config-specific INCLUDE_DIRECTORIES in multi-config generators
-
-Changes in CMake 2.8.10-rc1 (since 2.8.9)
------------------------------------------
-Scripted Changes (3):
- Remove trailing whitespace from most CMake and C/C++ code
- Convert CMake-language commands to lower case
- Remove CMake-language block-end command arguments
-
-Alex Neundorf (27):
- Eclipse: add support for the 4.2 Juno release (#13367)
- Eclipse: improve (fix ?) version detection on OSX
- Eclipse: fix #13358: don't create bad linked resources
- Eclipse: fix #13358: don't create bad linked resources
- remove non-working KDE4 test
- Eclipse on OSX: fix handling of framework include dirs (#13464)
- Eclipse on OSX: improve handling of framework include dirs (#13367)
- -fix line length
- fix #13474: also rescan dependencies if the depender does not exist
- -fix line length
- -fix Java dependency scanning, broken in previous commit
- error out if CTEST_USE_LAUNCHERS is TRUE but RULE_LAUNCH_* are not set
- fix #13494: rerun automoc also if include dirs or moc options change
- CMakeDetermineFortranCompiler: add support for cross-compiling (#13379)
- Automoc: fix #13493, use target properties for include dirs
- Automoc: do not use DEFINITIONS, but only COMPILE_DEFINITIONS
- Automoc: also the makefile-COMPILE_DEFINITIONS
- cmGlobalGenerator.h: some minor coding style fixes
- Modules/readme.txt: fix typo
- find_package: add support for a <package>_NOT_FOUND_MESSAGE variable
- exports: store pointers to all installations of each export set
- exports: accept a missing target if it is exported exactly once
- exports: first try at error handling if a target is missing
- exports: fix build with MSVC6
- exports: move the handling of missing targets into subclasses
- exports: define a CMAKE_FIND_PACKAGE_NAME var set by find_package()
- exports: add a test for exporting dependent targets
-
-Andreas Mohr (1):
- FindCURL: Find older MSVC prebuilts
-
-Andy Piper (1):
- Do not include directories which are part of the package install prefix.
-
-Benjamin Eikel (21):
- Initial version of find module
- FindSDL: Add version support for FindSDL_net
- FindSDL: Version support for FindSDL_image
- FindSDL: Use prefix SDL_NET, because it matches the file name.
- FindSDL: Use SDL_IMAGE prefix for varibales
- FindSDL: Add "cmake_minimum_required" to "try_compile" project
- FindSDL: Format the documentation
- FindSDL: Version support for FindSDL_sound
- FindSDL: Use same capitalization for FPHSA as file name
- FindSDL: Pass SDL_SOUND_LIBRARY to FIND_PACKAGE_HANDLE_STANDARD_ARGS
- FindSDL: Use SDL_MIXER prefix for variables
- FindSDL: Add version support for FindSDL_mixer
- FindSDL: Update documentation
- FindSDL: Use SDL_TTF prefix for variables
- FindSDL: Add version support for FindSDL_ttf
- FindSDL: Update documentation
- FindSDL: Format documentation
- FindSDL: Add version support
- FindSDL: Add my copyright tag to all FindSDL_* modules
- FindSDL: Remove from find_... calls PATHS that are set by default
- FindSDL: Stay compatible with old input variables
-
-Bill Hoffman (8):
- Use OUTPUT_NORMAL instead of OUTPUT_MERGE for cmake -E chdir.
- curl: Use find_package(OpenSSL)
- curl: Make OpenSSL DLLs available to CMake on Windows
- file(DOWNLOAD): Generalize EXPECTED_MD5 to EXPECTED_HASH
- file(DOWNLOAD): Add options for SSL
- Utilities/Release: Enable CMAKE_USE_OPENSSL in nightly binaries
- Add SSL_VERIFYPEER and CAINFO file options to ExternalProject_Add.
- Revert "Ninja: don't expand any rsp files"
-
-Brad King (83):
- find_library: Add test covering lib->lib64 cases
- find_library: Refactor lib->lib64 conversion
- find_library: Simplify lib->lib<arch> expansion
- find_library: Fix mixed lib->lib64 (non-)conversion cases (#13419)
- CMakeDetermine(C|CXX)Compiler: Consider Clang compilers
- Factor common code out of CMakeDetermine(ASM|C|CXX|Fortran)Compiler
- Prefer generic system compilers by default for C, C++, and Fortran
- Xcode: Fix object library references in multi-project trees (#13452)
- Xcode: Run xcode-select to find Xcode version file (#13463)
- Watcom: Simplify compiler version detection (#11866)
- Remove trailing TAB from NSIS.template.in
- Fix WarnUnusedUnusedViaUnset test pass/fail regex
- CMakeVersion.bash: Update sed expression for lower-case 'set'
- GetPrerequisites: Mark file_cmd as advanced cache entry
- Add boolean generator expressions
- Add $<CONFIG:...> boolean query generator expression
- Recognize Clang ASM support (#13473)
- Xcode: Set ASM source language in project file (#13472)
- Tests/Assembler: Do not use assembler in universal binaries
- Add FindHg module to find Mercurial
- ExternalProject: Add Mercurial (hg) repository support
- Qt4Macros: Fix recently broken resource file parsing
- Tests/ObjectLibrary: Do not enable CXX in subdirectories
- VS11: Rename 'Immersive' to 'WindowsAppContainer' (#12930)
- VS: Disable precompiled headers unless enabled by project (#12930)
- VS11: Generate flag tables from MSBuild V110 tool files
- Detect Compaq compiler version with its id
- Detect PathScale compiler version with its id
- Detect TI compiler version with its id
- Detect Comeau compiler version with its id
- Detect SDCC compiler version with its id
- Detect Cray compiler version with its id
- Detect Analog VisualDSP++ compiler version with its id
- Re-order C/C++/Fortran compiler determination logic
- CMakeDetermineCompilerId: Prepare to detect IDE compiler id
- Xcode: Detect the compiler id and tool location
- VS10: Define CMAKE_VS_PLATFORM_TOOLSET variable
- VS: Detect the compiler id and tool location
- Cleanly enable a language in multiple subdirectories
- Test variables CMAKE_(C|CXX|Fortran)_COMPILER(|_ID|_VERSION)
- Document CMAKE_<LANG>_COMPILER_(ID|VERSION) values
- Make platform information files specific to the CMake version
- Move CMAKE_<LANG>_COMPILER_WORKS to compiler information files
- Store ABI detection results in compiler information files
- VS: Remove support for "free" version 2003 tools
- VS: Simplify MSVC version reporting
- Modernize MSVC compiler information files
- VS: Fix MSVC_IDE definition recently broken by refactoring
- add_library: Document POSITION_INDEPENDENT_CODE default (#13479)
- magrathea: Tell cmELF about DT_RUNPATH (#13497)
- Utilities/Release: Link AIX binary with large maxdata
- Utilities/xml: Add .gitattributes to disable whitespace checks
- Utilities/xml: Add docbook-4.5 DTD (#13508)
- docbook: Fix formatter naming convention to avoid shadow
- docbook: Fix Sun CC warning on ptr_fun(isalnum)
- curl: Honor OPENSSL_NO_SSL2
- if: Compare up to 8 components in VERSION tests
- ExternalProject: Generalize URL_MD5 option to URL_HASH
- Rename SSL terminology to TLS
- file(DOWNLOAD): Make TLS options behave as documented
- OS X: Add platform-specific Clang compiler info files (#13536)
- VS11: Detect VS 2012 Express for default generator (#13348)
- VS11: Add VS 2012 Express support (#13348)
- file(DOWNLOAD): Add HTTP User-Agent string
- ExternalProject: Add DOWNLOAD_NAME option
- file(DOWNLOAD): Change EXPECTED_HASH to take ALGO=value
- VS8: Remove '.NET' from generator description (#10158)
- Clang: Split Compiler/Clang* modules out from GNU (#13550)
- Clang: All versions know about -fPIE (#13550)
- Xcode: Remove unused code reading CMAKE_OSX_SYSROOT_DEFAULT
- OS X: Always generate -isysroot if any SDK is in use
- OS X: Improve default CMAKE_OSX_SYSROOT selection
- bootstrap: Suppress CMAKE_OSX_SYSROOT if CFLAGS have -isysroot
- Tests/Assembler: Use CMAKE_OSX_SYSROOT to generate .s file
- OS X: Allow CMAKE_OSX_SYSROOT to be a logical SDK name
- OS X: Simplify selection of CMAKE_OSX_ARCHITECTURES
- OS X: If CMAKE_OSX_SYSROOT is already set do not compute default
- OS X: Further improve default CMAKE_OSX_SYSROOT selection
- OS X: Teach deployment target sanity check about SDK names
- OS X: Ignore MACOSX_DEPLOYMENT_TARGET during Xcode compiler id
- Verify that PDB_(NAME|OUTPUT_DIRECTORY) are honored in test
- Document that PDB_(NAME|OUTPUT_DIRECTORY) are ignored for VS 6
- Run PDBDirectoryAndName test on MSVC and Intel
-
-Clinton Stimpson (8):
- fphsa: clarify message about minimum required version found.
- DeployQt4: Include DESTDIR for some cpack generators.
- Add -DNDEBUG to RelWithDebInfo flags where where Release flags had it.
- Fix regex for qt minor version.
- FindQt4: Give precedence to QTDIR environment variable, if set.
- FindQt4: Give precedence to QTDIR environment variable, if set.
- Fix errors detecting Qt4 on Windows 8.
- cmake-gui: Fix error status when interrupted.
-
-Daniel Pfeifer (8):
- Simplify CMake.HTML documentation test command line
- docbook: Remove table of contents
- docbook: Factor out code to write valid DocBook IDs
- docbook: Fix the DocBook section output
- docbook: Cleanup formatter and generated DocBook
- docbook: Add support for <abstract> at section level 1
- docbook: Add CMake.DocBook test to validate xml (#13508)
- docbook: Remove redundant docs that cause invalid DocBook
-
-David Cole (9):
- Begin post-2.8.9 development
- Release: Temporarily exclude ExternalProject test on cygwin
- Add ability to run as a ctest -S script also
- CMake: Clarify the documentation for if(f1 IS_NEWER_THAN f2)
- Convert the CPACK_CYGWIN_PATCH_NUMBER variable to a cache variable
- InstallRequiredSystemLibraries: Use correct file names (#13315)
- ProcessorCount: Mark find_program vars as advanced (#13236)
- FindQt4: Avoid "finding" non-existent library in a .framework
- FindMPI: Set correct variables for calls to FPHSA
-
-Eric NOULARD (2):
- Enhance DESTDIR documentation. Fixes #0012374.
- Handles %attr(nnn,-,-) /path/to/file in CPACK_RPM_USER_FILELIST properly.
-
-James Bigler (3):
- Replace -g3 with -g for CUDA 4.1 and 4.2 in addition to CUDA < 3.0.
- Added CUDA_SOURCE_PROPERTY_FORMAT. Allows setting per file format (OBJ or PTX)
- FindCUDA: Added CUDA_HOST_COMPILER variable.
-
-Marcin Wojdyr (1):
- Remove CMake multiline block-end command arguments
-
-Nils Gladitz (1):
- ctest_update: Tell svn not to prompt interactively (#13024)
-
-Patrick Gansterer (4):
- VS: Cleanup AddPlatformDefinitions() of Visual Studio generators
- Add additional architectures to CMakePlatformId.h.in
- Add WindowsCE platform information files
- VS: Remove duplicated implementations of CreateLocalGenerator()
-
-Peter Kuemmel (1):
- Ninja: don't expand any rsp files
-
-Peter Kümmel (15):
- Ninja: cmcldeps needs a compiler
- Ninja: don't crash on returned 0 pointer
- Ninja: prepare msvc pdb cleanup
- Ninja:split out setting of msvc TARGET_PDB
- Ninja: remove GetTargetPDB because it is used only once
- Ninja: also detect /showInclude prefix for icl
- Find mingw's windres also when Unix Makefiles are used
- Ninja: don't suppress warning about compiler options
- Ninja: suppress cmcldeps only for source file signature try_compiles
- Ninja: filter target specific compile flags with language specific regex
- Ninja: OBJECT_DEPENDS should set an implicit dependency
- Ninja: don't confuse ninja's rsp files with nmake's
- Ninja: move -LIBPATH behind -link option
- Ninja: move <OBJECTS> in front of the first linker option
- Ninja: add option to enforce usage of response files
-
-Philip Lowman (3):
- FindOpenSceneGraph: CMake variable OSG_DIR influences detection now too
- FindGTK2: Add GTK2_CAIROMMCONFIG_INCLUDE_DIR for cairommconfig.h
- CMakeDetermineVSServicePack: Visual Studio 2012 added
-
-Rolf Eike Beer (25):
- remove lib64 Unix paths if the respective lib path is also given
- FindOpenSSL: find cross-compiled OpenSSL from MinGW (#13431)
- FindOpenSSL: use SelectLibraryConfigurations
- FindOpenSSL: let CMake handle environment variable HINTS
- FindOpenSSL: cleanup path hints
- FindOpenSSL: remove leftover comment
- SelectLibraryConfiguration: generate correct output when input vars are lists
- Fix typo direcotry -> directory (and similar) [#13444]
- FindSelfPackers: fix typo (#13456)
- CheckTypeSize: show in documentation how to get struct member size (#10579)
- CheckTypeSize: add a test for size of struct members
- FindX11: remove duplicates from X11 include path list (#13316)
- FindX11: avoid calling list(REMOVE_DUPLICATES) on an empty list
- list command: error on too many arguments
- CMake.List test: explicitely test with lists containing only an empty string
- use the find_* functions ENV parameter
- use PATH_SUFFIXES to simplify find_* calls
- do not escape spaces in regular expressions
- read less from version headers into variables
- FindFLEX: fix version extraction on Apple
- FindGettext: remove code duplicating FPHSA checks
- include FPHSA from current directory in all modules
- FindOpenSceneGraph: simplify by using more features of FPHSA
- FindSDL: add SDLMAIN_LIBRARY only once (#13262)
- add documentation for all MSVCxxx version variables (#12567)
-
-Sergei Nikulov (1):
- fix for discovering ft2build.h using FREETYPE_DIR environment var (#13502)
-
-Stephen Kelly (60):
- Add new qt4_use_modules function.
- Add missing whitespace to docs.
- Fix some typos in the docs.
- Remove incorrect doc string for link type enum
- Remove duplicate 'of' from docs.
- Fix unfortunate documentation error for PIC feature.
- Don't duplicate -D defines sent to the compiler.
- Fix CompileDefinitions test on Visual Studio.
- Fix the test setting COMPILE_DEFINITIONS target property
- Rename files from main.cpp to more meaningful names.
- Fix casing of 'Qt' in docs, comments and user-visible strings.
- Read entire Qt4 qrc file when parsing for depends info.
- Add a return-after-error if an old Qt is found.
- Use CMake platform variables instead of Qt ones.
- Move variable setting down to where it relates to.
- Remove an if which is always true.
- Use add_subdirectory instead of the obsolete subdirs.
- Replace two include_directories with a setting.
- Compile with both Qt4 and Qt5.
- Build with Qt5 if it is found.
- cmGeneratorExpression: Re-write for multi-stage evaluation
- cmGeneratorExpression: Port users to two-stage processing
- Fix the regular expression validator for target names.
- Handle colons as a special case in the generator expression parser.
- Enable deprecated API when using Qt 5.
- Add more forwarding API to cmGeneratorTarget.
- Store cmGeneratorTargets with the makefile.
- Move GenerateTargetManifest to cmGeneratorTarget.
- Move GetLinkInformation to cmGeneratorTarget
- Make cmLocalGenerator::AddArchitectureFlags take a cmGeneratorTarget.
- Move GetCreateRuleVariable to cmGeneratorTarget.
- Port cmLocalGenerator::GetTargetFlags to cmGeneratorTarget.
- Move GetIncludeDirectories to cmGeneratorTarget.
- Append the COMPILE_DEFINITIONS from the Makefile to all targets.
- Add a wrapper for accessing config-specific compile-definitions.
- Add convenience for getting a cmGeneratorTarget to use.
- Fix compiler warning with initialization order.
- Revert "Move GenerateTargetManifest to cmGeneratorTarget."
- Use the cmGeneratorTarget for the include directories API.
- Fix indentation in the code blocks generator.
- Port remaining code to GetCompileDefinitions().
- Add include guard for cmGeneratorExpression.
- Don't prepend a path before generator expressions in include_directories.
- Convert paths in INCLUDE_DIRECTORIES property to Unix slashes.
- Add an AppendDefines std::string overload.
- Return a std::string from GetCompileDefinitions.
- Refactor GetCompileDefinitions a bit.
- Extend the generator expression language with more logic.
- Add a generator expression for target properties.
- Add API to check that dependent target properties form a DAG.
- Add a self-reference check for target properties.
- Early return if there is no target.
- Process generator expressions in the INCLUDE_DIRECTORIES property.
- Process generator expressions in the COMPILE_DEFINITIONS target property.
- Fix the layout of the generator expression documentation.
- Fix punctuation in some variables documentation.
- Document that generator expressions can be used in target properties.
- Remove unused parameter marker and the unused parameter.
- Fix minor typos.
- Remove period at the end of the check message.
-
-Tom Schutter (2):
- cmake-mode.el: Use more readable regex and case-fold-search
- cmake-mode.el: add local keybindings
-
-Xavier Besseron (7):
- cmCTestSVN: Add the new SVNInfo structure
- cmCTestSVN: Extend Revision struct with SVN repo information
- cmCTestSVN: Add the Repositories list and the RootInfo pointer
- cmCTestSVN: Create the SVNInfo for the root repository
- cmCTestSVN: Use the SVNInfo structure
- cmCTestSVN: Add a LoadExternal() function and an ExternalParser class
- cmCTestSVN: Load and process information from externals
-
-Yuchen Deng (1):
- Add PDB_OUTPUT_DIRECTORY and PDB_NAME target properties (#10830)
-
-Yury G. Kudryashov (7):
- exports: Move cmTargetExport to a dedicated header file
- exports: Remove cmTargetExport constructor
- exports: Rename cmGlobalGenerator::AddTargetToExport{s,}
- exports: Create class cmExportSet
- exports: Add cmExportSetMap class
- exports: Hold an ExportSet pointer in cm*Export*Generator
- exports: cmGlobalGenerator::ExportSets destructor will clear it
-
-Zack Galbreath (2):
- Clean up documentation formatting so that it is rendered properly in HTML.
- cmparseMSBuildXML: Include DisplayName in the output
-
-Changes in CMake 2.8.9 (since 2.8.9-rc3)
-----------------------------------------
-None
-
-Changes in CMake 2.8.9-rc3 (since 2.8.9-rc2)
---------------------------------------------
-Alexey Ozeritsky (1):
- Fixed: FindLAPACK does not find MKL 10.3 when using gcc 4.x
-
-Brad King (3):
- pre-commit: Reject C++ code with lines too long
- Tests/X11: Add missing include <stdlib.h> for 'rand'
- Tests/ObjC++: Use standard <iostream> header
-
-David Cole (1):
- CPack: Use bin subdir when looking for dpkg and rpmbuild
-
-Eric NOULARD (2):
- Do not run cpack at CMake time it is not available.
- Find dpkg and rpmbuild in usual Fink and MacPort paths
-
-Nicolas Despres (17):
- Ninja: Cannot pass a reference to an anonymous object.
- Ninja: Add support for OS X app bundles.
- Ninja: Add support for OX X library framework.
- Ensure 3rd party libraries are writable.
- Remove trailing white-spaces.
- Re-factor OS X bundle and framework generation.
- Ninja: Copy resource files in the bundle.
- Ninja: Add support for CFBundle.
- Enable BundleTest with CLang too.
- Re-factor CFBundle generation.
- Ninja: Use same echo message as makefiles.
- Re-factor bundle content copying rules generation.
- Re-factor Mac OS X content directory computation.
- Re-factor framework directory computation.
- Re-factor OS X content generator start up.
- Fix memory leak in Makefile generator.
- Add missing this->.
-
-Peter Kuemmel (1):
- Ninja: dep files and multiple -arch flags not possible on mac
-
-Peter Kümmel (24):
- Ninja: windres is also used for cross-compiling
- Ninja: search for windres with prefix
- Ninja: there could be null pointers
- Ninja: more searching for windres
- Ninja: path is already declared
- Ninja: fix GCC 4.7 warning -Wconversion
- Ninja: fix sytle
- Ninja: also stop when .rc's .d file couldn't be generated
- Ninja: readd quotes to src file path before patching it
- Ninja: cmcldeps needs absolute paths for RCs
- Ninja: on Mac no multiple -arch because of -M
- Ninja: fix mis-matching endif() argument
- Ninja: also mingw needs TARGET_PDB
- Ninja: line length
- Ninja: make TARGET_PDB a real .gdb file name
- Ninja: make debug symbol suffix configurable by CMAKE_DEBUG_SYMBOL_SUFFIX
- Ninja: remove 'friend' in ninja code
- Ninja: remove warnings
- Ninja: remove 'this' from member initializer list
- Ninja: fixes for bcc
- Ninja: enable ninja on Mac so all Mac CDash-builds are tested, cleanup later
- Ninja: void function can't return a value
- Ninja: enable ninja support everywhere
- Ninja: also bootstrap ninja files
-
-Changes in CMake 2.8.9-rc2 (since 2.8.9-rc1)
---------------------------------------------
-Alex Neundorf (4):
- -remove trailing whitespace
- documentation: preparation for making the man section configurable
- man documentation: detect man section from the given filename
- Eclipse: fix #13313, always set LANG to C, also if unset
-
-Bill Hoffman (1):
- Remove process execution code from cmcldeps and have it use cmake code.
-
-Brad King (12):
- KWIML: Generalize interface to report broken integer literal macros
- KWIML: Teach ABI.h about 'long long' and 'char' on old HP
- KWIML: Teach INT.h that no HP platform implements SCN*8 formats
- KWIML: Teach INT about broken UINT32_C on old HP
- Fix project command documentation typo (#13384)
- CTestUpdateSVN: Do not create repo directory first (#13349)
- Tests/CustomCommand: Do not use 'main' in a library
- AIX-GNU: Link shared libs with -brtl,-bnoipath (#13352)
- include: Ignore empty string as file name (#13388)
- Add ASM platform information for GNU compiler on AIX (#13390)
- if: Document that macro arguments are not variables (#13393)
- install: Fix COMPONENT option
-
-Clinton Stimpson (3):
- GetPrerequisites.cmake: detect executables built with the -pie linker flag.
- cmake-gui: Fix code to respect current locale.
- DeployQt4: workaround bug 13258 where ARGV1 is leaked into a sub function.
-
-David Cole (7):
- STYLE: Fix line length, remove extra blank line
- CTest: Refactor error output into ErrorMessageUnknownDashDValue
- CTest: Rename local variable for clarity
- CTest: Extend -D command line arg handling for variable definitions
- CTest: Allow -Dvar=value with no space between the D and the var
- CTest: Add test to verify -D variable definitions work
- Ninja: Fix typo: tagets -> targets
-
-Eric NOULARD (3):
- Enhance documentation of install command w.r.t. the "Undefined" component.
- CPack fix regression between 2.8.7 and 2.8.8 when running cpack with no arg.
- Do not provide defaul value for CPACK_PACKAGE_DIRECTORY if found in config.
-
-Nicolas Despres (1):
- Ninja: Clean all symlink created for libraries.
-
-Peter Kuemmel (6):
- Ninja: print error message when command failed
- Ninja: also consider variables when checking command line length
- Ninja: also consider rule command length for rsp file
- Ninja: remove int/size_t warning
- Ninja: add soname test case
- Ninja: don't shadow 'outputs' variable
-
-Peter Kümmel (6):
- Ninja: also write link libraries to rsp file
- Ninja: remove some unused default arguments
- Ninja: error on missing rspfile_content
- Ninja: disable work around when linking with mingw
- Ninja: enable response file support on Mac (length 262144)
- Ninja: sysconf() is declared in unistd.h
-
-Philip Lowman (2):
- FindBoost: Fix bug where Boost_FOUND could be false when version specified
- FindBoost: Future proof to 1.56
-
-Rolf Eike Beer (2):
- FindJava: improve version matching (#12878)
- fix 2 space bugs in variable documentation
-
-Stephen Kelly (3):
- Use full paths in compile_commands.json for out of source builds.
- Construct the full path before escaping it.
- Fix PositionIndependentTargets test with clang trunk.
-
-Changes in CMake 2.8.9-rc1 (since 2.8.8)
-----------------------------------------
-Alex Neundorf (12):
- -fix #13081: support OBJECT libraries in CodeBlocks/QtCreator projects
- CodeBlocks: improve support for OBJECT libraries
- fix #13195: avoid multiple mentions of found packages
- FeatureSummary.cmake: nicer formatting
- -strip trailing whitespace
- make default install component name configurable
- -add docs for ${CMAKE_INSTALL_DEFAULT_COMPONENT_NAME}
- write_basic_package_version_file() now works with unset CMAKE_SIZEOF_VOID_P
- add test for #13241: empty SIZEOF_VOIDP in write_basic_package_version_file
- ASM compiler detection: remove debug output (#13270)
- Eclipse: parallel build also for "Build project" #13287
- automoc: better error handling (#13299)
-
-Anthony J. Bentley (1):
- FindwxWidgets: Do not use -isystem on OpenBSD (#13219)
-
-Ben Boeckel (2):
- Don't put legacy variables back into the cache
- Search for other ABIFLAGS builds of Python
-
-Bill Hoffman (15):
- Add support to ctest for GTM mumps coverage.
- Fix warning about char* instead of const char*.
- Fix line length.
- Add test for mumps coverage. Also refactor code to prepare for cache coverage.
- Add virutal destructor to silence warning.
- Add support for Cache coverage.
- Fix some warnings and a bug where it went past the length of a vector.
- Use a script to run the test because WORKING_DIRECTORY is not in 2.8.2.
- Use <TARGET_FILE> expression to run ctest so it works with Xcode and VS IDE.
- Add ability to specify more than one package directory or coverage directory.
- Remove uncovered files from cache coverage data.
- Disable bullseye coverage for mumps coverage test.
- Update test data to match new coverage format.
- Do not try to run bullseye coverage if COVFILE env is empty.
- CDash now supports lots of files in coverage. So, show all files.
-
-Brad King (59):
- Add LICENSE and NOTICE
- Add 'tips' script to suggest local configuration
- Add 'setup-user' script to configure authorship information
- Add 'setup-hooks' script to install local hooks
- Add 'setup-gerrit' script to configure Gerrit access
- Add 'setup-stage' script to configure topic stage remote
- Add 'setup-ssh' script to configure ssh push access
- Add README instructions and sample configuration
- Add and configure developer setup helper scripts
- Exclude from source archives files specific to Git work tree
- Exclude from CMake source archives files specific to Git work tree
- Refactor CMake version handling
- Document behavior of multiple target_link_libraries calls (#13113)
- ctest_coverage: Save/restore LC_ALL around gcov (#13136)
- Cleanup custom command .rule file internal handling
- Factor out custom command .rule file path generation
- VS10: Avoid creating .rule files next to outputs (#13141)
- find_package: Document <package>_FIND_* variables (#13142)
- find_package: Fix components signature documentation (#13142)
- Teach RunCMake tests to allow custom checks
- list: Handle errors on empty lists more gracefully (#13138)
- include_external_msproject: Test TYPE, GUID, PLATFORM options (#13120)
- VS: Fix line-too-long style errors
- libarchive: Avoid 'inline' keyword on XL C v6 (#13148)
- Intel: On Windows use /EHsc instead of deprecated /GX (#13163)
- KWSys: Remove DateStamp
- try_compile: Cleanup temporary directories (#13160)
- setup-stage: Optionally reconfigure topic stage
- CTest: Escape MemCheck test output for XML (#13124)
- Documentation: Fix HTML anchor ranges
- Require CMake 2.8.2 or higher to build CMake
- CTest: Simplify environment save/restore
- KWSys: Fix SystemTools environment memory handling (#13156)
- VS10: Refactor custom commands to use WriteSource
- VS10: Simplify vcxproj.filter file generation
- VS10: Convert paths normally unless forced to relative
- VS11: Do not use source path conversion workaround specific to VS 10
- VS10: Generate relative source paths when possible (#12570)
- Intel: On Windows use /RTC1 instead of deprecated /GZ (#13174)
- Test NO_SONAME property (#13155)
- KWSys: Remove dependencies on FundamentalType
- Documentation: Improve HTML section index format
- VS: Restore header files marked as OS X Framework content (#13196)
- VS11: Fix ARM architecture hint typo (#13077)
- Fortran: Follow <>-style includes (#13239)
- bootstrap: Port back to old shells (#13199)
- KWSys: Remove unused environ declaration from SystemTools
- FindBZip2: Search locations in GnuWin32 registry
- cmArchiveWrite: Clear fflags from archive entries
- Makefile: Support directory names containing '=' (#12934)
- libarchive: Avoid 'inline' on SunPro < 5.9 (#13277)
- Avoid direct use of std::(o|)stringstream (#13272)
- KWIML: Add interface to report broken integer format macros
- KWIML: Report broken integer format macros on AIX 4.3
- add_library: Allow OBJECT library without dynamic linking (#13289)
- install: Fix FILES_MATCHING on case-sensitive Mac filesystems (#13177)
- Make CTest.UpdateGIT robust to Git safecrlf on Windows
- Do not crash on SHARED library without language (#13324)
- CMakeDetermineCCompiler: Fix typo "_CXX_" -> "_C_" (#13330)
-
-Brian Helba (1):
- Print any evaluated 'elseif'/'else' commands in trace mode (#13220)
-
-Charlie Sharpsteen (1):
- Mac: Add guards to CMAKE_FIND_FRAMEWORK and CMAKE_FIND_APPBUNDLE defaults
-
-Clinton Stimpson (1):
- cmake-gui: Wait for configure/generate thread to complete before exiting.
-
-Daniel R. Gomez (6):
- KWSys: Fix hashtable prime list on g++ 2.9 (#13273)
- Tests/IncludeDirectories: Files must end in a newline (#13314)
- Tests/VSGNUFortran: Avoid C++ comment in C code (#13314)
- Tests/Assembler: Assemble and link with same flags (#13314)
- Fix FindPackageMode test Makefile (#13314)
- Avoid string.clear and string.push_back (#13319)
-
-David Cole (12):
- Begin post-2.8.8 development
- CPack/NSIS: Add CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS (#13085)
- ExternalProject: Add missing COMMAND keyword
- ExternalProject: Avoid unnecessary git clones (#12564)
- ExternalProject: Refactor repeated code into function (#12564)
- ExternalProject: Avoid repeated git clone operations (#12564)
- CTest: Modify reg ex so it also works with gcov 4.7 output (#13121)
- BZip2: Remove unnecessary *.bz2 files from CMake source tree
- Ninja: Enable the ninja generator by default on Windows.
- Revert "Millenium update: 79 * (16/9)/(4/3) = 105"
- Ninja: Restructure code to work with the Borland compilers
- Remove unused ivars to eliminate compiler warnings
-
-David Faure (1):
- Abort FindQt4.cmake if Qt 5 is found.
-
-Eric NOULARD (12):
- Use fakeroot for control.tar.gz as well
- Enhancement of bash completion scripts given by Igor Murzov.
- Install editors helper files
- CPack - preserve timestamp for CPACK_INSTALLED_DIRECTORIES. fixes: #0013193
- CPack add easy possibility to warn about CPACK_SET_DESTDIR
- CPack add necessary check to detect/warns/error on ABSOLUTE DESTINATION
- Fix KWStyle warning
- Use CPACK_xxx and CMAKE_xxx in a consistent way.
- CPack allow RPM and DEB generator to be used on OSX.
- Calm down Borland compiler warning about "always true"
- CPackRPM: avoid leakage of RPM directive from one component to another.
- CPackDeb add missing documentation for some CPACK_DEBIAN_xx variables.
-
-Fraser Hutchison (1):
- CPack: Fixed incorrect error log for CPACK_NSIS_MENU_LINKS.
-
-Jan Schaffmeister (1):
- Xcode: Recognize storyboard source files (#13214)
-
-Jim Hague (2):
- libarchive: Avoid trailing , in enum for XL v6 (#13148)
- Workaround IBM XL v6 streams seekg bug (#13149)
-
-Jonathan Klein (1):
- FindBullet: Add missing math library name (#13309)
-
-Joseph Snyder (1):
- Change GT.M Coverage Parser global
-
-Konstantin Tokarev (1):
- [OSX] Fixed undefined symbol when linking CMakeLib into shared library
-
-Kurtis Nusbaum (1):
- Added conditional for the phonon backend plugin.
-
-Leonid Yurchenko (1):
- include_external_msproject: Add TYPE, GUID, PLATFORM options (#13120)
-
-Mario Bensi (1):
- Add FindLibLZMA Module
-
-Mariusz Plucinski (1):
- Do not crash on unknown source language (#13323)
-
-Matt McCormick (1):
- ExternalProject: Fix 'make' builds with Ninja (#13159)
-
-Minmin Gong (1):
- VS11: Add ARM architecture generator (#13077)
-
-Modestas Vainius (3):
- Fix CPack RPM man page typo detected by lintian.
- Support building shared libraries or modules without soname (#13155)
- Fix a few typos in NO_SONAME property description.
-
-Nicolas Despres (2):
- Ninja: Add a convenient 'clean' target.
- Ninja: Add a convenient 'help' target.
-
-Patrick Gansterer (1):
- Added CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL
-
-Peter Collingbourne (2):
- Ninja: apply CMAKE_<LANG>_FLAGS_<TYPE> to executable targets (#13069)
- Ninja: mark rules/build file streams failed if error occurred (#13067, #13105)
-
-Peter Kuemmel (61):
- Ninja: ensure output directories exist
- Ninja: no 16:9 screens for the cmake team ;)
- Ninja: add option to enable ninja where it is not enabled by default
- Ninja: remove GCC -Wshadow warning
- Ninja: enable Ninja for CodeBlocks
- Ninja: no additional variable needed to enable ninja
- Ninja: CMAKE_USE_NINJA is the name of the macro
- VC Express doesn't support folders, ignore USE_FOLDER property
- Ninja: add response file support on Windows
- Ninja: 30000 is too long for windows cmd
- Ninja: check for valid pointer
- Ninja: also create rspfile rules
- Ninja: don't break because of empty commands
- Ninja: find mingw's resource compiler
- Ninja: add dependency tracking for msvc with cldeps
- Ninja: add wrapper for cl to extract dependencies
- Ninja: allow spaces in source path
- Ninja: assume cmcldeps in the same dir as cmake
- Ninja: add copyright and description
- Ninja: don't set cmcldeps vars to empty string when they are not defined
- Ninja: fix ModuleNoticies test
- Ninja: don't use cmcldeps for try_compile
- Ninja: allow spaces in cldeps's .d file
- Ninja: fix line length
- Ninja: don't pollute the rules file with useless comments
- Ninja: use slahes in .d files
- Line Length: <79
- Millenium update: 79 * (16/9)/(4/3) = 105
- Ninja: complete MinGW support
- Ninja: use slashes for include dirs, so also slahes are in the .d files
- Ninja: ninja can't read dep. pathes with parentheses
- Ninja: work with ninja/master, don't compile rc files with cl
- Ninja: extract dependencies for .rc files with msvc tools
- Ninja: remove unused CommentStream
- Ninja: onyl use pre processor for rc file parsing
- Ninja: suppress startup logos
- Ninja: cmcldeps
- Ninja: don't use shell when cmake is called directly
- Ninja: ninja now also could read parentheses in .d files
- Ninja: fix Linux build
- Ninja: sh needs something befor and after &&
- Ninja: build with old vc versions
- Ninja: remove nop line
- Ninja: undo all the NOSHELL patches
- Ninja: be more accurate when estimating the command line length
- Ninja: don't pollute build dir with preprocessed rc files
- Ninja: Eclipse and KDevelop fixes for ninja
- Ninja: no /nologo option in old rc.exe
- Ninja: but cl supports /nologo ...
- Ninja: try to make GetProcessId visible
- Ninja: build cmcldeps with mingw
- Ninja: don't remove space between command and parameters
- Ninja: some bytes of the rc files couldn't be piped correctly
- Ninja: build server fixes
- Ninja: build with old msvc versions
- Ninja: msvc6 for-scoping
- Ninja: maybe this fixes the bcc32 build
- remove warning about unused parameter
- Ninja: build server fixes
- Ninja: try work around for bcc32 bug
- Ninja: disable cldeps for bcc32, it's too old, and ninja would also not build
-
-Rolf Eike Beer (12):
- FindPkgConfig.cmake: fix documented output variable not set (#13125,#13132)
- UseJava: fix typo in variable name (#13135)
- Check{C,CXX}CompilerFlag: catch more Intel warning types (#12576)
- FindPythonLibs: honor EXACT version specification (#13216)
- UseJava: fix find_jar() called with multiple files (#13281)
- fix some typos
- do not explicitely specify /usr and /usr/local as search paths
- replace open coded versions of file(TO_CMAKE_PATH)
- FindDevIL: clean up documentation formatting
- FindQt4: extend documentation
- Qt4Macros: improve basename extraction in QT4_ADD_DBUS_INTERFACES
- Qt4Macros: add some quotes to prevent damage from spaces in the paths
-
-Sean McBride (1):
- Remove unused ivars to eliminate compiler warnings
-
-Sebastian Leske (1):
- Improve documentation of set command (#13269)
-
-Stephen Kelly (10):
- Fix the number variable comparison when Qt is not found.
- Update the docs of IMPORTED_LOCATION_CONFIG to match the code.
- Move the EscapeJSON method to a sharable location.
- Add newline to the output.
- Make the CMAKE_EXPORT_COMPILE_COMMANDS option work with Ninja.
- Escape the source file to be compiled if required.
- Exclude the CompileCommandOutput test on WIN32.
- Add platform variables for position independent code flags
- Add platform variable for flags specific to shared libraries
- Refactor generation of shared library flags
-
-Tobias Bieniek (1):
- Qt4Macros: Added support for generated resource files
-
-Zack Galbreath (1):
- FindPythonLibs: Document cache variables (#13240)
-
-Zaheer Chothia (1):
- VS: Set Intel Fortran 13 project version
-
-Changes in CMake 2.8.8 (since 2.8.8-rc2)
-----------------------------------------
-Brad King (1):
- CheckIncludeFiles: Shorten check description message
-
-David Cole (3):
- CPackNSIS: Rewrite variable documentation to make it more readable.
- OS X: Use correct extra path when searching for applicaton bundles (#13066)
- OS X: Mark find_program results as advanced
-
-Eric NOULARD (1):
- Fix some doc typo and add an undocumented var.
-
-Kashif Rasul (1):
- OS X: Use OSX_DEVELOPER_ROOT for app search path (#13066)
-
-Rolf Eike Beer (1):
- FindBoost: add support for 1.49 and 1.50
-
-Changes in CMake 2.8.8-rc2 (since 2.8.8-rc1)
---------------------------------------------
-Alex Neundorf (4):
- make cmLocalGenerator::EscapeForCMake() static
- automoc: fix #13018, proper cmake escaping to avoid false rebuilds
- automoc: add define to test which caused bug #13018
- fix #13054: support OBJECT libraries in Eclipse
-
-Ben Boeckel (1):
- Create granular targets for Ninja generators too
-
-Brad King (6):
- CTest.UpdateHG: Fix repo URL for leading slash
- Always compile sources with known language
- Classify known header file extensions as headers
- VS: Add CMakeLists.txt re-run rules at start of generation
- Test generated module .def files
- Ninja: Fix module .def file path conversion
-
-David Cole (2):
- CMake: Clarify SUFFIX target property documentation.
- Xcode: Pay attention to custom configuration types (#13082)
-
-Peter Collingbourne (1):
- Ninja: Substitute <OBJECT> and <CMAKE_C_COMPILER> in depfile flags
-
-Rolf Eike Beer (2):
- FILE: mention that TO_CMAKE_PATH also handles list delimiters
- FIND_LIBRARY: document FIND_LIBRARY_USE_LIB64_PATHS
-
-Sean McBride (1):
- automoc: include <unistd.h> on Apple to get pathconf
-
-Tom Hughes (1):
- Override topdir from rpm command line seems necessary on Amazon linux.
-
-Changes in CMake 2.8.8-rc1 (since 2.8.7)
-----------------------------------------
-Aaron C. Meadows (1):
- Visual Studio: Allow setting Single Byte Character Set (#12189)
-
-Alex Neundorf (34):
- GNUInstallDirs: add support for Debian multiarch
- FindRuby: fix usage of RUBY_VERSION_MAJOR (#12172)
- FindRuby: add more possible library names (for ubuntu, #12172)
- FindRuby.cmake: add more debug output
- fix FeatureSummary for REQUIRED packages, they were reported as OPTIONAL
- FindGetText: fix multiple targets with the same name problem (CMP0002)
- fix #6976: FindX11 also searches for X11_Xxf86vm_LIB
- GenerateExportHeader: use double quotes around _gcc_version
- -remove trailing whitespace
- -don't pull in CheckTypeSize.cmake from the cmake which is being built
- bootstrap: move while() and endwhile() into the bootstrap build
- Check*.cmake: Expand imported targets in CMAKE_REQUIRED_LIBRARIES
- find_package: print error if an invalid CONFIGS name is used
- find_package: rename NoModule to UseFindModules
- find_package: improve error message when no Find module is present
- find_package: add MODULE mode to use only Find-modules
- find_package: add CONFIG mode keyword alias for NO_MODULE
- find_package: mention requested version number in error message
- add CMakePackageConfigHelpers: configure_package_config_file()
- wrap write_basic_config_version_file as write_basic_package_version_file()
- find_package: error out if REQUIRED Config has not been found
- write_basic_package_version_file(): improve documentation
- write_basic_package_version_file: add ExactVersion mode
- WriteBasicConfigVersionFile: add test for ExactVersion mode
- find_package: allow <pkg>Config.cmake to set <pkg>_FOUND to FALSE
- find_package: add test for setting Foo_FOUND to FALSE in a Config file
- find_package: additional test for checking the error message
- find_package: add OPTIONAL_COMPONENTS keyword
- FPHSA(): add missing "]" to documentation
- find_package: add documentation for OPTIONAL_COMPONENTS
- FPHSA(): add HANDLE_COMPONENTS option
- add macro check_required_components() to configure_package_config_file()
- Eclipse: fix #13036, make version detection work with symlinks
- guard eCos.cmake against multiple inclusion (#12987)
-
-Alexandru Ciobanu (2):
- CTest: Detect Xcode error "Command ... failed with exit code"
- CTest: Match valgrind errors with "points to" (#12922)
-
-Alexey Ozeritsky (1):
- FindBLAS/FindLAPACK: Work with MKL version 10.3 (#12924, #12925)
-
-Artur Kedzierski (1):
- Add CURL_CA_BUNDLE option for SSL support (#12946)
-
-Bill Hoffman (12):
- Add CMakeAddFortranSubdirectory to use MinGW gfortran in VS
- VSGNUFortran: Add special case for SunPro Fortran runtime library
- VSGNUFortran: Disable test in special cases
- CMakeAddFortranSubdirectory: Make IMPORTED targets GLOBAL
- Use upgraded qt on linux build machine.
- Teach CTest what a ninja error looks like.
- Allow two cmake_add_fortran_subdirectory calls in the same project.
- Add ability to include a file in a project via a cache variable.
- Fix typo in error message, and remove redundent test.
- Ninja: Add a cache option CMAKE_ENABLE_NINJA to enable the ninja generator.
- Ninja: Fix for PDB files with spaces in the path.
- Fix FindMPI for the intel compiler on linux by looking in implict directories.
-
-Bjoern Ricks (1):
- Fix crash if app bundle executeable couldn't be found
-
-Brad King (138):
- CheckCCompilerFlag: Generalize "but not for C" case (#12633)
- complex: Remove ancient unused ComplexRelativePaths test
- complex: Sync Tests/ComplexOneConfig with Tests/Complex
- complex: Remove dynamic loader tests
- complex: Move GeneratedFileStream test to CMakeLibTests
- complex: Simplify test for single-character exe name
- complex: Move cmSystemTools::UpperCase test to CMakeLibTests
- complex: Remove test dependence on cmSystemTools
- complex: Remove unused option to test CMakeLib
- Intel: Fix Windows per-config Fortran flags (#12642)
- libarchive: Remove our copy to make room for new import
- libarchive: Add .gitattributes for indentation with tab
- libarchive: Add README-CMake.txt
- libarchive: Do not build subdirectories not in reduced snapshot
- libarchive: Remove -Wall -Werror from build with GNU
- libarchive: Build one static cmlibarchive for CMake
- libarchive: Include cm_zlib.h to get zlib used by CMake
- Handle libarchive API change in archive_read_data_block
- Configure libarchive build within CMake
- libarchive: Install COPYING with CMake documentation
- libarchive: Port to OSF operating system
- libarchive: Fix typo in CheckFileOffsetBits
- libarchive: Implement custom lseek for Borland
- libarchive: Declare mbstate_t and wcrtomb for Borland
- libarchive: Cast constants to int64_t instead of using LL suffix
- libarchive: Workaround case-insensitive symbols on Borland
- libarchive: Clean up configuration within CMake build
- libarchive: Cast mode constants to mode_t in case it is signed
- libarchive: Fix Windows NT API usage in VS 6
- libarchive: Suppress compiler warnings
- libarchive: Fix var decl after statement in archive_string.c
- libarchive: Do not use ST_NOATIME if not defined
- libarchive: Check for 'struct statvfs' member 'f_iosize'
- libarchive: Do not use MNT_NOATIME if not defined
- libarchive: Use Apple copyfile.h API only if available
- libarchive: Remove hard-coded build configuration
- libarchive: Cleanup after ZLIB_WINAPI check
- libarchive: Define _XOPEN_SOURCE=500 on HP-UX
- libarchive: Include linux/types.h before linux/fiemap.h
- libarchive: Rename isoent_rr_move_dir parameter isoent => curent
- libarchive: Suppress PathScale compiler warnings
- libarchive: Avoid bogus conversion warning from PGI compiler
- libarchive: Set .gitattributes to allow trailing whitespace
- libarchive: Update README-CMake.txt for new snapshot
- libarchive: Restore CMake 2.6.3 as minimum version
- bootstrap: Update copyright year in version report
- bootstrap: Re-implement command line option processing
- bootstrap: Forward options after '--' to cmake
- VS10: Fix /pdb option vcxproj element name (#12328)
- Add framework to detect compiler version with its id (#12408)
- Detect GNU compiler version with its id (#6251)
- Detect MSVC compiler version with its id
- Detect Intel compiler version with its id (#11937)
- Detect Borland compiler version with its id
- Detect IBM XL compiler version with its id
- Detect PGI compiler version with its id
- Detect Clang compiler version with its id
- Detect Watcom compiler version with its id
- Detect SunPro compiler version with its id
- Detect HP compiler version with its id
- Document compiler version macro formats used for detection
- Detect SGI MIPSpro compiler version with its id
- ExternalProject: Fix git.cmd version detection
- ExternalProject: Update copyright year
- Include bzlib.h consistently across CMake build (#10950)
- FindMPI: Append MPI C++ library correctly in non-compiler case (#12874)
- Add infrastructure for CMake-only tests
- Tolerate cycles in shared library link interfaces (#12647)
- cmInstallCommand: Fix line length for style
- cmake-mode.el: Indent after multiline argument (#12908)
- Clarify IMPORTED_ target property documentation
- Optionally allow IMPORTED targets to be globally visible
- Add test covering imported target scope rules
- VS: Simplify ;-separated attribute value parsing
- Fix CXX/Fortran MODULE flags when enabled before C (#12929)
- Remove unused test code
- Allow directory names containing '=' and warn if necessary (#12934)
- Add CheckLanguage module
- CMakeAddFortranSubdirectory: Allow full paths to directories
- CMakeAddFortranSubdirectory: Fix documentation format and typos
- CMakeAddFortranSubdirectory: Find gfortran in PATH
- CMakeAddFortranSubdirectory: Validate gfortran architecture
- CMakeAddFortranSubdirectory: Always parse arguments
- CMakeAddFortranSubdirectory: Add NO_EXTERNAL_INSTALL option
- libarchive: Workaround mbsnrtowcs assertion failure on old glibc
- Recognize OpenBSD versioned .so names (#12954)
- try_compile: Use random executable file name (#12957)
- Rename Modules/Platform/Windows-{Borland => Embarcadero}.cmake
- Recognize Embarcadero compiler (#12604)
- Factor cmInstallType out of cmTarget::TargetType
- Add infrastructure for CMakeCommands tests
- find_package: Reject mixed use of MODULE- and CONFIG-only options
- find_package: Optionally warn when implicitly using Config mode
- find_package: Test error and warning messages in failure cases
- bootstrap: Convert MSYS paths to Windows format (#13001)
- CTest.UpdateHG: Fix repo URL for local filesystem (#13001)
- cmcurl: Do not hard-coded Windows check results for MinGW (#13001)
- CheckSourceTree: Remove CVS checkout support (#13001)
- Fix MSYS CVS local test repo path format (#13001)
- find_package: Test that REQUIRED aborts processing correctly
- Remove unused partial OBJECT_FILES property implementation
- VS: Simplify object name computation
- Hide Makefile local object info inside local generator
- KWIML: Make test_INT robust to #define-d int#_t and INT#_C
- Add stronger infrastructure for CMake-only tests
- Use generalized RunCMake test infrastrucure for find_package test
- Use generalized RunCMake test infrastrucure for build_command test
- Document Fortran_MODULE_DIRECTORY as OUTPUT only (#13034)
- Ninja: Constify use of cmCustomCommand
- Ninja: Avoid using 'this' in member initializers
- Write CMakeCache.txt atomically (#13040)
- Add cmGeneratorTarget to represent a target during generation
- Create a cmGeneratorTarget for each cmTarget during generation
- Simplify cmMakefileTargetGenerator using cmGeneratorTarget
- Simplify cmVisualStudio10TargetGenerator using cmGeneratorTarget
- Pre-compute object file names before Makefile generation
- Pre-compute object file names before VS project generation
- Remove unused cmSourceGroup method
- Rename/constify build-time config placeholder lookup
- Pre-compute and store target object directory in cmGeneratorTarget
- Add OBJECT_LIBRARY target type
- Build object library targets in Makefiles
- Build object library targets in VS
- Add $<TARGET_OBJECTS:...> expression to use an object library
- Test OBJECT library success cases
- Test OBJECT library failure cases
- Test OBJECT library language propagation
- Test OBJECT library use without other sources
- Document OBJECT library type in add_library command
- Simplify cmNinjaTargetGenerator using cmGeneratorTarget
- Pre-compute object file names before Ninja generation
- Build object library targets in Ninja
- Ninja: Honor $<TARGET_OBJECTS:...> source expressions
- find_package: Test rejection of required+optional components
- Simplify cmVisualStudio10TargetGenerator source classification
- VS10: Fix external objects generated outside target (#13047)
- Fix ObjectLibrary test on Watcom
- KWIML: Avoid conflict with C++11 user-defined literals
-
-Christian Andersson (1):
- FindPythonLibs: Search for single-user installs on Windows
-
-Christopher Sean Morrison (1):
- cmake-mode.el: Make indentation case-insensitive (#12995)
-
-Clinton Stimpson (14):
- GetPrerequisites: Add support for @rpath on Mac OS X.
- GetPrerequisites: Add support for @rpath on Mac OS X.
- GetPrerequisites: Add test for @rpath support.
- Fix new BundleUtilities test failure on Mac 10.4.x
- Fix BundleUtilities test failure with space in build path.
- cmake-gui: Improve interrupt granularity to fix bug 12649.
- FindQt4: clarify warning message about incorrect Qt installation.
- FindQt4: Add include directories for lupdate.
- Fix paths/hints for finding qtmain.
- DragNDrop: Fix problem with relocated files in Xcode 4.3
- Add test for DeployQt4.cmake
- Fix for Qt4Deploy on some test machines.
- Remove QtGui dependency in Qt4Deploy test and verify QtSql existance.
- DeployQt4: Add path to Qt dlls on Windows.
-
-Daniel Nelson (1):
- CPack Add top level directory in component install for Archive Generators
-
-David Cole (33):
- Begin post-2.8.7 development
- Release: Increase timeout for slow-testing cygwin build
- Update dashmacmini2 release script to use Qt 4.6.3
- Update dashmacmini2 release script to use Qt 4.8.0
- Tests: Update drop site value for the Trilinos contract test
- Update version of Qt for dashmacmini5 produced release binaries
- CTestCustom: Suppress clang warning on the dashboard
- CMake: Eliminate cmMakefile::IncludeDirectories
- Remove cmMakefile::GetIncludeDirectories
- Make search paths ordered and unique
- Call ExpandVariablesInString for each target's INCLUDE_DIRECTORIES
- Update the documentation regarding INCLUDE_DIRECTORIES.
- Fix compiler error reported on older Borland dashboard.
- Fix compiler warning reported on older Borland dashboard.
- Fix shadowed variable warning on dashboard results
- Remove trailing white space
- Use correct "requires" line in cygwin setup hint file
- VS6: Avoid _MBCS define when _SBCS is defined (#12189)
- VS6: Avoid SBCS test on VS6 (#12189)
- Suppress warnings occurring on the dashboards using the PGI compiler.
- CPack: Fix retry logic when calls to hdiutil fail
- Ninja: CMake: Adapt Ninja generator for per-target include dirs
- Ninja: Add friend struct so it can access the private ConvertToNinjaPath.
- Xcode: Detect new default locations of Xcode 4.3 bits and pieces (#12621)
- CPack: Use real path to PackageMaker to find its version file (#12621)
- Xcode: Re-factor code into GetObjectsNormalDirectory method
- Xcode: Re-factor some existing methods into "FromPath" variants
- Add a default source group for object files.
- Allow txt files as ExtraSources in object library targets
- Pre-compute object file names before Xcode generation
- Build object library targets in Xcode
- Xcode: Honor $<TARGET_OBJECTS:...> source expressions
- Tests: Relax restrictions on version variable contents
-
-Deborah Pickett (1):
- CPackRPM flag direcories with %dir in the generated spec file
-
-Droscy (1):
- FindCxxTest: Add support for CxxTest 4 (#13022)
-
-Eric NOULARD (41):
- Document undocumented (but existing) cpack options (fix #0010134)
- Enhance bash completion file for cmake and ctest
- Do not add the content of a file if it's a symlink.
- CPackArchive restore default behavior and provide new variable.
- CPackNSIS fix #0012935 switch from LOG_WARNING to avoid final error.
- CPack begin the implementation of --help-command* and --help-variables*
- Implement simple CMake script comment markup language.
- CPack Documentation extraction from CMake script begins to work
- Update bash completion file in order to handle new CPack doc options.
- Suppress unused var, beautify code, avoid 1 extra newline.
- Fix potential bad memory access, thanks to Eike
- Calm down compiler warning about unused var
- Really avoid compiler warning about unused vars
- Fix another compiler warning due to a typo
- Make the load of script documentation more efficient and dynamic.
- Example of builtin variable documentation (i.e. only used in C++ source code).
- Add missing section markup for CPackComponent
- Create getDocumentedModulesListInDir which may be used in other context.
- Fix non existent std::string::clear on VS6
- Avoid discovering system infos for documentation. Adding some path is enough.
- Dynamically add documentation section specified in documented script.
- Add structured documentation for NSIS
- Add structure documentation for CPack Bundle generator
- Suppress unecessary (now empty) doc sections
- Correct copy/paste section name mistake
- Put CPack DMG and PackageMaker doc in separate files
- More documentation concerning CPack Components
- Fix typo in end markup
- Try to fix compile error on Win32-vs70
- Do not build RPM if path of the build tree contains space
- Fix layout of the CPack Bundle documentation
- Fix CPack Drag and Drop generator documentation layout.
- Review and update CPack variable documentation.
- Update CPackConfig template.
- Provide template for CPack Cygwin generator specific variables.
- Update CPack PackageMaker variable doc layout
- Typo: Add missing ##end for ##module
- Fix some typos in CPACK_SET_DESTDIR doc
- Add some missing CPACK_NSIS_xxx doc and move some to common CPack section.
- CPack STGZ put execute permission on all packages files (component case)
- Handle CPACK_MONOLITHIC_INSTALL in some rare use cases.
-
-Eugene Golushkov (1):
- VS: Add support for WinRT project properties (#12930)
-
-James Bigler (1):
- Added support for curand, cusparse, npp, nvcuenc and nvcuvid libraries.
-
-Jason Erb (1):
- FindwxWidgets: Add webview library (#12636)
-
-LibArchive Upstream (2):
- libarchive 3.0.1-r3950 (reduced)
- libarchive 3.0.2-r4051 (reduced)
-
-Matthias Kretz (1):
- Improve checks for Open64 and g++ incompatible flags (#12119)
-
-Mattias Helsing (1):
- CPack: Fix NSIS handling of privileged users (#12923)
-
-Michael Wild (1):
- GenerateExportHeader: Fix wrong use of IS_ABSOLUTE (#12645)
-
-Mike McQuaid (5):
- Don't use QT_LIBRARIES_PLUGINS by default.
- Fix mismatched arguments.
- Fix bad plugin paths.
- Ensure libs are passed to BundleUtilities.
- Fix plugin installation issues.
-
-Modestas Vainius (3):
- various typo and formatting fixes in manual pages (#12975)
- KWIML: Teach ABI.h that MIPS is biendian
- Tests: Escape metachars before embedding paths into the regex (#12999)
-
-Nicolas Despres (5):
- ccmake: Factor clear line.
- ccmake: Extend clear line.
- java: Factor jar output path.
- java: Add CMAKE_JAVA_TARGET_OUTPUT_DIR optional variable.
- java: Add CMAKE_JAVA_JAR_ENTRY_POINT optional variable.
-
-Peter Collingbourne (19):
- Add cmSystemTools::TrimWhitespace function
- Add executable with exports flag support to cmLocalGenerator::GetTargetFlags
- Provide dependency file flags to generator
- Ninja: Add the Ninja generator
- Ninja: Fix a 79-col violation
- Ninja: Remove some default arguments
- Ninja: Appease various compilers
- Ninja: Partially revert "win fixes: escape back slash/colon, use cd. as cmd.exe nop"
- Ninja: Identifier encoding rules for ' ' and ':'
- Ninja: Backslash rules for Windows
- Ninja: Shell encode paths used in "cd" commands
- Ninja: Shell encode various CMake invocations
- Ninja: Shell encode the command used in custom commands
- Ninja: Import library support for Windows
- Ninja: Add a missed license header
- Ninja: Use cmSystemTools::ExpandListArgument to split compile/link commands
- Ninja: Remove an unnecessary variable
- Ninja: add support for OBJECT_OUTPUTS, fix PrecompiledHeader test case
- Ninja: shell escape $(CMAKE_SOURCE_DIR) and $(CMAKE_BINARY_DIR)
-
-Peter Kuemmel (12):
- Find VC Express during default generator selection (#12917)
- Ninja: win fixes: escape back slash/colon, use cd. as cmd.exe nop
- Ninja: don't define MSVC_IDE when using the ninja generator
- Ninja: also build ninja support on Windows
- Ninja: add some hacks for Windows
- Ninja: disable unfinished Windows ninja support
- Ninja: mark the Windows specific hacks with a comment only
- Ninja: windows msvc: create for each target a .pdb file
- Ninja: ensure the output dir exists at compile time
- Ninja: add .def file support
- Ninja: add /DEF: flag to linker call
- Ninja: Fix <OBJECT_DIR> substitution
-
-Philip Lowman (5):
- FindProtobuf: Merge patch that allows extra import dirs
- FindProtobuf: Update documentation comment for 2.8.8
- Findosg: New modules for osgQt and osgPresentation
- FindALSA: Fix incorrect include path detection
- FindALSA: Fix version detection after last commit
-
-Rolf Eike Beer (95):
- remove reference to CVS directory when installing files
- CheckSymbolExists: force the compiler to keep the referenced symbol
- add a test for Check{,CXX}SymbolExists
- FindOpenSSL: improve version number handling
- FindOpenSSL: only try to parse opensslv.h if it exists
- FindOpenSSL: also parse version number define with uppercase letters
- GenerateExportHeader test: add newlines before end of file
- add a test that loops through most Find* modules
- AllFindModules test: keep complete output
- AllFindModules test: also check Qt3 modules if Qt4 is not found
- FindPythonInterp: make version selectable
- FindPythonInterp: fix version parsing
- LoadCommand test: cleanup
- FindThreads: Try pthreads with no special option first (#11333)
- fix uninitialized var in if(NOT foo bar STREQUAL "foo bar")
- use pkg_check_modules() quiet in other modules
- FindLibXml2: support version selection
- FindGnuTLS: partly support version selection
- FindGit: support version number
- FindCups: major overhaul
- FindEXPAT: support version number
- FindCURL: support version selection
- FindFLEX: fix version parsing for old flex versions
- FindFLEX: fix version parsing when the executable is quoted
- FindJasper: find debug libraries
- FindJasper: support version number
- FindBZip2: add support for version checking
- FindBZip2: add support for debug libraries (#12867)
- FindImageMagick: make use of more FPHSA features
- FindPNG: support version selection
- FindRuby: do not blindly set version to 1.8.0
- FindTclsh: support version selection
- SelectLibraryConfigurations: do not output identical configurations
- FindLua51: add version support
- FindTIFF: support version selection
- FindCURL: detect version number also for older versions
- FindLibXml2: detect version when PkgConfig is not used
- FindPostgreSQL: support version selection
- FindOpenSSL: properly parse the hex version components
- FindBISON: add a version expression for GNU Bison 1.x
- FindPythonInterp: try harder to get a version number
- FindJasper: fix library name
- FindGnuplot: add version selection
- FindALSA: support version selection
- FindGettext: support version selection
- CheckCXXCompilerFlag test: make it a CMakeOnly test
- CMakeOnly.AllFindModules: clean up the Qt3/Qt4 code
- CMakeOnly.AllFindModules: always check FindQt
- CMakeOnly.AllFindModules: suppress two modules from testing
- CMakeOnly.AllFindModules: require version for some modules
- CheckIncludeFiles: fix status output
- FindPerl{,Libs}: move version detection into FindPerl
- FindLibArchive: support version selection
- FindX11: also search for Xmu (#12447)
- detect "pgfortran" as PGI Fortran compiler (#12425)
- FindSDL*: use FPHSA (#12467)
- AllFindModules test: do not enforce GNUPLOT version
- FindPerlLibs: properly detect libperl on Windows (#12224)
- CTest: mark all gcov covered files as covered
- FindGLUT: honor REQUIRED (#12466)
- FindRuby: clean up querying variables from Ruby
- FindLibXslt: support version selection
- Tests: document where to put tests
- FindPkgConfig: support version selection of pkg-config itself
- fix the same typos as found by Debian in other places, too
- Find_library(): allow searching for versioned shared objects
- FindFreetype: support version selection
- AllFindModules test: expect more modules to have a version number available
- FindOpenMP: do not fail if only C or CXX is enabled (#11910)
- FindOpenMP: try the most likely flags first
- FindOpenMP: simplify check for enabled languages
- UseSWIG: clean up string compares
- FindPython{Interp,Libs}: document Python_ADDITIONAL_VERSIONS as input
- FindPythonLibs: make the version selection work as for PythonInterp
- FindPythonLibs: get the exact version of the found library (#3080)
- FindPythonLibs: put debug libraries into PYTHON_LIBRARIES
- FindPythonLibs: stop scanning when libraries are found
- Check{C,CXX}CompilerFlag: detect ICC error messages
- GenerateExportHeader: remove unneeded code
- GenerateExportHeader: improve compiler identification
- FindOpenSceneGraph: give every message() with an explicit level
- FindHSPELL: set HSPELL_VERSION_STRING
- FindImageMagick: fix fail if no components were given
- FindPythonInterp: rework the version detection
- document when version detection will not work
- AllFindModules test: once again expand version checking
- improve error message on a stray "endwhile()"
- add testcases for while()/endwhile() errors
- reflect that the QtAutomoc depends on QtGui
- FindQt3: fix warning when Qt3 is not found
- FindQt3: fix version extraction for versions with letters
- FindQt3: let FPHSA handle the version selection
- FindQt3: fix detection of Qt3 include directory
- AllFindModules test: do not require TCLSH version
- add test for get_property() errors
-
-Stephen Kelly (13):
- Fix typos arguement -> argument.
- Exit the loop when we have determined the language.
- Add whitespace after '.' in CMAKE_SKIP_RPATH docs.
- Fix documented function signature to match reality.
- Add default initializers for WIN32_EXECUTABLE and MACOSX_BUNDLE
- Add an option to skip RPATH during installation.
- Refactor GetIncludeFlags to take includes instead of fetching them
- Make it safe to call this method without creating duplicates.
- Remove include flags memoization.
- Add API to get the ordered includes for a target.
- Keep the INCLUDE_DIRECTORIES target property up to date.
- Extract and use the INCLUDE_DIRECTORIES target properties.
- Fix some typos in the docs comments.
-
-Yury G. Kudryashov (23):
- FindDoxygen: add DOXYGEN_VERSION variable
- cmInstallCommand: Fix indentation error
- cmInstallCommand: Remove duplicated sentence from docs
- FindPkgConfig: respect REQUIRED (#12620)
- FindPackageHandleStandardArgs: fix documentation
- Remove unused file cmake.1
- Fix typo in documentation
- Drop if(...) check because condition is always true
- CMakeFindPackageMode: fix 32/64bit detection if 'file' is a symlink
- Run vim spellcheck on some files
- cmPropertyDefinition::IsChained is const
- Add 'const' qualifier to some cmCommand members
- doxygen: cmPropertyDefinition
- doxygen: Improve API docs of GetRealDependency
- doxygen: Use proper syntax to document enum
- doxygen: Small fixes in cmake.h apidocs
- doxygen: fix some comments in cmPolicies.h
- doxygen: remove a few comments
- doxygen: review cmake.h
- doxygen: MathCommand is not about string operators
- Rename UsedCommands to FinalPassCommands
- Remove UnionsAvailable member from 2 classes
- Remove cmExprParserHelper::SetLineFile()
-
-Changes in CMake 2.8.7 (since 2.8.7-rc2)
---------------------------------------------
-None
-
-Changes in CMake 2.8.7-rc2 (since 2.8.7-rc1)
---------------------------------------------
-Alex Neundorf (5):
- automoc: default to strict mode, use CMAKE_AUTOMOC_RELAXED_MODE
- automoc: improved warning message in relaxed mode
- Remove trailing whitespace
- Add comment about one more problem of the C depency scanner.
- fix #12262: dependency scanning for ASM files
-
-Bill Hoffman (1):
- Fix the case where cmake --build failed with two project cmds in one file.
-
-Brad King (11):
- KWSys: Correctly handle empty environment variables
- FortranCInterface: Work around mingw32-make trouble with parens
- Xcode: Create separate rerun dependencies for subprojects (#12616)
- Fix Intel Fortran .vfproj files for VS 10
- HP: Drive shared library linking with compiler front end
- Follow all dependencies of shared library private dependencies
- Do not link private dependent shared libraries on OS X > 10.4
- Avoid clobbering variable 'OUTPUT' in compiler tests (#12628)
- Fix and simplify Fortran test compiler compatibility check
- CTest: Recognize Intel errors without space before colon (#12627)
- Windows-GNU: Remove extra quotes in GNUtoMS rule variable
-
-David Cole (4):
- Release: Increase timeout for slow-testing cygwin build
- Modules: Use "windres" as rc compiler base name for cross-compiles (#12480)
- Tests: Only really run MFC test if we can build MFC apps (#11213)
- FindBoost: Quote possibly empty string argument (#12273)
-
-Eric NOULARD (1):
- CPackRPM fix #0012608 and unoticed related bug
-
-Johan Fänge (1):
- CMake: Fix progress reporting for custom targets (#12441)
-
-Mike McQuaid (2):
- Unset configurations variable when no build type.
- Improve component support and output indentation.
-
-Raphael Kubo da Costa (2):
- Remove the apparently outdated README in Source/QtDialog.
- QtDialog: Set Ctrl+Q as the shortcut for quitting the program.
-
-Tim Gallagher (2):
- FindLAPACK: Correct CMAKE_FIND_LIBRARY_SUFFIXES spelling (#12624)
- FindLAPACK: List thread libs to avoid link errors (#12625)
-
-Valat Sébastien (1):
- CTest: Do not get CDash version without drop site (#12618)
-
-Changes in CMake 2.8.7-rc1 (since 2.8.6)
-----------------------------------------
-Aaron Ten Clay (1):
- VS: Add support for three new project properties (#12586)
-
-Alex Neundorf (60):
- fix #12392: handle CMAKE_CXX_COMPILER_ARG1 for Eclipse projects
- fix #12262: use the C dependency scanner also for ASM files
- fix #12465: detect the masm compiler ID ("MSVC")
- Silence make on OpenBSD in FindPackageModeTest(#12508)
- Remove trailing whitespace
- Find Ruby on OpenBSD when installed from ports (#12507)
- Eclipse generator: detect Eclipse version
- Detect whether the current Eclipse version supports VirtualFolders
- Eclipse: don't create VirtualFolders if not supported
- Eclipse: better message when Eclipse version could not be determined
- automoc:run moc on the header if the source file contains include "foo.moc"
- Add copyright notices
- automoc: always run moc on the cpp file if there is a foo.moc included
- Eclipse: add virtual folder for each target
- Eclipse: move code for generating links to projects into separate function
- Eclipse: move code for generating links to targets into separate function
- Eclipse: add Build and Clean targets to targets
- Eclipse: detect number of CPUs, set CMAKE_ECLIPSE_MAKE_ARGUMENTS accordigly
- Eclipse: fix #12417, don't create wrong src pathentries
- FindLibXslt: also search libexslt and xsltproc
- don't crash in automoc with empty COMPILE_DEFINITIONS property
- Automoc: fix the fix, need to use std::string, not just char* pointer
- automoc: fix #12541, support moc options
- add documentation for the AUTOMOC_MOC_OPTIONS property
- Eclipse: warn if CMAKE_BINARY_DIR is subdir of CMAKE_SOURCE_DIR
- Eclipse: make targets work from any directory
- Eclipse: quote the build dir (to make it work with spaces)
- make automoc work when using ccmake via PATH (#12551)
- Strip trailing whitespace
- -make GETTEXT_PROCESS_PO_FILES() work with files with multiple dots
- FindGettext: two more fixes for files with multiple dots
- FindPNG: provide PNG_INCLUDE_DIRS, as the readme.txt says (#11312)
- Eclipse: create links to subprojects also in the source-project (#12579)
- Eclipse: use new variable CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT
- install(EXPORT): Enforce existence of imported target files
- Remove trailing whitespace
- cmake-gui: add completion for the names when adding cache entries
- automoc: stricter checking for what file is included
- automoc: rework the checking for the matching header, to give better warnings
- automoc: handle the case when the developer includes the wrong mocfile
- automoc: add more test cases
- automoc: improved diagnostics
- automoc: minor optimization
- automoc: another runtime optimization
- Automoc: modified handling of included .moc files
- automoc: add a test for including both abc.moc and moc_abc.cpp
- automoc: add test for including the moc file from another header
- automoc: add test for including a moc_abc_p.cpp file
- automoc: move some code from the big parsing loop into separate functions
- automoc: add special handling for including basename_p.moc, with test
- automoc: add extra check whether the header contains Q_PRIVATE_SLOT
- automoc: some more linebreaks for the warnings for better readability
- automoc: fix handling of included _p.moc files
- automoc: move the code for finding headers into separate function
- automoc: add a StrictParseCppFile(), which is only qmake-compatible
- automoc: also accept other files when .moc is included in non-strict mode
- automoc: accept even more .moc files in non-strict mode
- automoc: add variable CMAKE_AUTOMOC_STRICT_MODE, to enable strict parsing
- automoc: fix line length
- automoc: add documentation for CMAKE_AUTOMOC_STRICT_MODE
-
-Alexey Ozeritsky (1):
- FindLAPACK: Fix linking to static LAPACK on Unix (#12477)
-
-Bernhard Walle (1):
- Source/cmCTest.cxx: Add missing newline (#12538)
-
-Brad King (65):
- Refactor find_* command final path list computation
- Constify XCode generator getters to match cmGlobalGenerator
- Fix line-too-long style violations
- KWSys: Fix Doxygen warnings
- Add pre-commit|commit-msg|prepare-commit-msg hook placeholders
- pre-commit: Reject changes to KWSys through Git
- Fix CTest.UpdateSVN with Subversion 1.7 (#12535)
- Teach CTest.UpdateSVN to detect svn add --depth before using it
- KWSys: Address Intel compiler remarks
- Fix linking to OS X Frameworks named with spaces (#12550)
- Watcom: Use shortpath to CMake if full path has parens (#12548)
- KWSys: Remove trailing whitespace in SystemTools.cxx
- KWSys: Fix wrong spelling of __INTEL_COMPILER
- Update main Copyright.txt year range for 2011
- KWIML: The Kitware Information Macro Library
- Configure KWIML inside CMake as cmIML
- KWIML: Avoid redefining _CRT_SECURE_NO_DEPRECATE in test.h
- KWIML: Suppress printf/scanf format warnings in test
- KWIML: No INT_SCN*8 on SunPro compiler
- KWIML: No INT_SCN*8 on Intel for Windows
- KWIML: Create test output dir for Xcode
- Order VS local generator Version ivar values consistently
- Enumerate VS11 version explicitly in local generators
- KWIML: Test header inclusion after system headers
- KWIML: Ignore _LONGLONG on MS compiler
- KWIML: Teach ABI.h about PGI compiler
- KWIML: Avoid MSVC linker warning about not using C++ runtime
- Factor Compute(File|String)MD5 into cmCryptoHash helper
- Add file(MD5) command to compute cryptographic hash
- Import sha2 implementation 1.0 from Aaron D. Gifford
- Import sha2 implementation 1.1 from Aaron D. Gifford
- sha2: Use KWIML fixed-size integer types and endian-ness
- sha2: Build as part of CMakeLib
- Add file(SHA*) commands to compute cryptographic hashes
- sha2: Use "static const" instead of "const static" declarations
- cmCryptoHash: Provide factory "New" method
- Add string(MD5) and string(SHA*) commands to compute hashes
- sha2: Use KWIML fixed-size integer constant macros
- sha2: Suppress Borland warnings in third-party code
- Disable file() and string() hash commands during bootstrap
- sha2: Wrap long lines in third-party declarations
- Fix CMake.File hash test for CRLF checkouts
- cmCryptoHash: Add virtual destructor
- sha2: Cast safe conversions to smaller integer types
- sha2: Suppress -Wcast-align warning from Clang
- sha2: Zero entire SHA_CTX structure during cleanup
- target_link_libraries: Add missing space in documentation
- target_link_libraries: Simplify argument processing state tests
- install(EXPORT): Improve target import failure message format
- Remove trailing whitespace from cmLocalGenerator
- bootstrap: Include cmNewLineStyle in build
- cmNewLineStyle: Remove trailing comma in enum
- cmNewLineStyle: Use cmStandardIncludes.h
- Provide std::ios_base typedef on GCC < 3
- FindZLIB: Search under ZLIB_ROOT if it is set
- Factor out target location undefined behavior helper macro
- export(): Document undefined behavior of location properties
- Recognize the Tiny C Compiler (#12605)
- TinyCC: Add compiler info for shared libs on Linux (#12605)
- Fortran: Detect pointer size in gfortran on MinGW
- Load platform files that need to know the ABI when possible
- Factor makefile generator link rule lookup into helper function
- Add CMAKE_GNUtoMS option to convert GNU .dll.a to MS .lib
- Test CMAKE_GNUtoMS option in ExportImport on MinGW and MSys
- cmTarget: Create helper method for versioned library names
-
-Clinton Stimpson (2):
- Fix XML safety issue with adding preprocessor defines in CodeBlocks project.
- Qt4: Fix dependencies of QtDeclartive.
-
-Dan Kegel (1):
- Modules: Add XRes to FindX11.cmake
-
-David Cole (17):
- Begin post-2.8.6 development
- CTest: Fix crash when variables are not defined
- VS11: Fix comment generated at the top of *.sln files
- CTest: Add COVERAGE_EXTRA_FLAGS cache variable (#12490)
- CTest: Clear custom vectors before populating (#12383)
- Tests: Add the MFC test (#11213)
- Tests: Avoid MFC test automatically for VCExpress builds (#11213)
- Tests: Fix MFC test w/ Make-based generators (#11213)
- Tests: Fix MFC test for old vs6 dashboards (#11213)
- Tests: Avoid MFC test automatically for Watcom WMake builds (#11213)
- Tests: Fix MFC test to work with VS 10 and later (#11213)
- VS10: Use expected values for UseOfMfc (#11213)
- Tests: Add environment logging to the MFC test (#11213)
- VS11: Update InstallRequiredSystemLibraries.cmake for VS11 (#11213)
- Tests: Nudge MFC test to pass on VS 6 dashboards (#11213)
- VS: Use "call " keyword with .cmd and .bat file custom commands (#12445)
- CTest: Disallow problem chars in build and site names (#11792)
-
-Eric NOULARD (3):
- CPackRPM support component specific variables for spec files
- Fix old reference to CMAKE_MAKE_PROGRAM inside CMAKE_BUILD_TOOL doc.
- CPackRPM fix #12556 and enhance documentation
-
-James Bigler (6):
- Added support for CUDA_PATH which is present in the CUDA toolkit 3.2 onward.
- Reset dependency file list when a dependency disappeared.
- Add work around for CUDA in UNC paths.
- Fixes for handling quotes in args and other places (Fix Bug 11726 and 12099).
- Make CUDA working directory unique for each target.
- Miscellaneous fixes.
-
-Jean-Christophe Fillion-Robin (1):
- CTest: Look for CTestConfig.cmake in build dir first, then source dir
-
-Johan Bjork (1):
- Xcode: Avoid spewing the environment on every script run (#12522)
-
-Mateusz Loskot (1):
- FindBoost: Use MSVC11 to find Boost on Windows (#12568)
-
-Mathieu Malaterre (1):
- TinyCC: Add default compilation flags (#12605)
-
-Mike McQuaid (6):
- Add QT_LIBRARIES_PLUGINS variable to UseQt4.
- Add DeployQt4 module.
- Match fixup_qt4_executable with documentation.
- Don't resolve directories; are never relative.
- Check plugin variables are defined before warning.
- Check QtCore without warning.
-
-Nicolas Despres (17):
- Refactor TargetTypeNames.
- Add const versions of some getters.
- Constify many getters of cmGlobalGenerator.
- Remove trailing white-spaces.
- Fix typo.
- Doxygen: Improve code documentation.
- Doxygen: Generate call graph and relationships.
- Doxygen: Fix warnings.
- Doxygen: Remove dependency on VTK when building doxygen.
- Usage: Document -j|--parallel option in help message.
- Usage: Document all options printing usage information.
- Usage: Document all options printing the version number.
- Usage: Print help, version and copyright options in usage information.
- Usage: Add missing exepath argument in get_prerequisites documentation.
- ccmake: Align 'g' and 'q' key instructions.
- ccmake: Document '/' key.
- ccmake: Factor toggle key help instructions.
-
-Niels Dekker (1):
- Fix CMAKE_VERBOSE_MAKEFILE for VS10 vcxproj files (#12504)
-
-Ondrej Balaz (1):
- FindBISON: Fix bison++ version parsing to avoid "Offending entry"
-
-Peter Collingbourne (4):
- Make cmLocalGenerator::ConvertToLinkReference virtual
- Introduce a cmLocalGenerator::ConvertToIncludeReference function
- Introduce a cmGlobalGenerator::ResolveLanguageCompiler function
- Fix configuration-dependent flag lookup in cmLocalGenerator::GetTargetFlags
-
-Peter Kuemmel (1):
- Add NEWLINE_STYLE option to configure_file (#3957)
-
-Philip Lowman (1):
- FindProtoBuf: Documented limitation of the public macro
-
-Pierre-Francois Laquerre (1):
- Fix path quoting in Qt4 macros
-
-Robert Dailey (1):
- VS: Add VS_SCC_AUXPATH target property (#12549)
-
-Rolf Eike Beer (4):
- libarchive: fix typo in CheckFileOffsetBits.cmake
- Tell people that link_directories() is not what they are searching for
- FindBISON: Fix matching output of "bison --version"
- Tests: ExternalProject: Remove unnecessary 'svn --version' call
-
-Stephen Kelly (13):
- Add features from KDE for arguments to qdbusxml2cpp.
- Remove unused define.
- Build each library only once instead of once for each test.
- Initialize LINK_INTERFACE_LIBRARIES target property with a variable
- Also run moc automatically with Qt5.
- Fix typo.
- Don't assume the existence of QT_MAJOR_VERSION.
- Update comments and method names to not be Qt4 specific.
- Fix style.
- target_link_libraries: Trim trailing whitespace
- target_link_libraries: Add LINK_(PUBLIC|PRIVATE) options
- moc is now part of the Qt5Core module
- Add a test case for the use of Q_PRIVATE_SLOT.
-
-Changes in CMake 2.8.6 (since 2.8.6-rc4)
-----------------------------------------
-Alex Neundorf (5):
- Remove trailing whitespace
- Minor improvements to the UsePkgConfig.cmake docs
- Remove trailing whitespace
- Improve behaviour of --find-package mode with try_run/try_compile
- Use makefile->IssueMessage() for better error messages
-
-Bill Hoffman (2):
- Use version 11.0 for 12.x and 9.10 for 10.x intel versions to fix 12.1 vsIDE.
- Also, check for 11.x as an intel fortran version.
-
-Brad King (2):
- Add Visual Studio 11 generator for x86 and x64 tools
- Teach our tests about special cases for VS 11
-
-David Cole (1):
- CTestCustom.cmake: Ignore clang's summary warning
-
-Philip Lowman (1):
- FindBullet: Also search for _Debug postfixed library names
-
-Raphael Kubo da Costa (1):
- Fix typo in set_target_properties' documentation.
-
-Rolf Eike Beer (1):
- Fix typo in UsePkgConfig.cmake
-
-Changes in CMake 2.8.6-rc4 (since 2.8.6-rc3)
---------------------------------------------
-Alex Neundorf (3):
- FindFLEX.cmake: also search the include dir
- Fix typos in FeatureSummary.cmake (#12462)
- Don't warn when setting a property multiple times to the same value #12464
-
-Bill Hoffman (2):
- For VS Intel Fortran IDE builds, add a check to find the Fortran library PATH.
- Enable Fortran tests for IDE builds.
-
-Brad King (5):
- FortranCInterface: Compile separate Fortran lib in VerifyC[XX]
- Move IntelVSImplicitPath project to better location
- Simplify IntelVSImplicitPath detection project
- libarchive: Fix ssize_t detection with mingwrt 3.20
- Make file(DOWNLOAD) fail on http error
-
-David Cole (8):
- Tests: Add a KWStyle test, equivalent to the make StyleCheck target
- KWStyle Test: Activate by default if KWStyle is found
- Xcode: Use EFFECTIVE_PLATFORM_NAME reference in ComputeOutputDir
- Xcode: Add test to demonstrate iOS project in Xcode
- CMake: Reference test targets only when BUILD_TESTING is ON
- Tests: Add the more modern Mac64 nightly build
- Release Scripts: Use Qt 4.7.4 on dashmacmini5 (#12460)
- Revert "FindThreads: Try pthreads with no special option first (#11333)"
-
-Eric NOULARD (4):
- CPack fix #12449 doc mispelled
- CPack fix template too
- CPackDeb fix #10325 automagically use fakeroot for DEB if fakeroot is found
- CPackRPM authorize per-component pre/post-[un]install scripts (#0012063)
-
-Marcus D. Hanwell (4):
- Just code style changes.
- Don't warn when nothing to do in visibility function.
- Made ADD_COMPILER_EXPORT_FLAGS into a macro.
- Make add_compiler_export_flags a function again.
-
-Rolf Eike Beer (1):
- remove stray brace in CPackDeb documentation
-
-Changes in CMake 2.8.6-rc3 (since 2.8.6-rc2)
---------------------------------------------
-Alexey Ozeritsky (2):
- FindBLAS/LAPACK fixes
- FindBLAS/LAPACK fixes
-
-Andreas Schneider (1):
- Modules: Add support for more java archives in add_jar().
-
-Björn Ricks (4):
- Search for the installed python interpreter first
- Determine python version
- Update documentation of FindPythonInterp.cmake
- Use FIND_PACKAGE_HANDLE_STANDARD_ARGS second mode
-
-Brad King (5):
- VS: Map per-source Fortran flags to IDE options
- VS: Map Fortran free- and fixed-format flags to IDE options
- Fortran: Add support for free- and fixed-form flags
- Xcode: Honor Fortran_FORMAT target and source file property
- Set CMAKE_<lang>_COMPILER_ID for VS generators
-
-David Cole (8):
- KWSys: Remove always-true dir_only parameter
- KWSys: Add symlinks to directories as files (#12284)
- FindPackageMessage: Eliminate new lines in cache entries
- FindPackageMessage: Eliminate new lines using REGEX REPLACE
- CMake: Add SaveCache at the end of successful Generate calls
- Suppress Qt warning for dashmacmini5 builds
- Suppress Qt warning for dashmacmini5 builds
- Tests: Look for "Illegal" or "SegFault" in the output
-
-Eric NOULARD (2):
- CPack fix #12366 components RPM packages have the same package name
- CPackRPM fix #12305, include directories in RPM package
-
-Johan Björk (5):
- Xcode: No spaces in makefile target names (#12370)
- CMake: Write symlinks to directories as files in archives (#12284)
- CPack: Do not recurse through directory symlinks (#12284)
- Xcode: Do not emit the ZERO_CHECK target more than once
- Xcode: Honor -g0 to disable debugging (#12377)
-
-Johannes Stallkamp (1):
- CTest: Fixed valgrind output parsing (#12260)
-
-Matt McCormick (1):
- CMake: Remove documentation for -E build (#12446)
-
-Stephen Kelly (2):
- Add some more unit tests.
- Don't put what some compilers consider junk at the end of the line.
-
-Thomas Jarosch (3):
- CTest: Fix memory leaks on error
- Fix file() command descriptor leak on error
- ccmake: Fix off-by-one memory access error
-
-Changes in CMake 2.8.6-rc2 (since 2.8.6-rc1)
---------------------------------------------
-Brad King (2):
- KWSys: Add hash function for std::string
- KWSys: Fix std::string hash function for Borland
-
-Clinton Stimpson (1):
- qt4: also find QtUiTools when cross compiling with mingw.
-
-David Cole (3):
- Xcode4: Requires more quoting of single quote char
- cmake.m4: Use modern signature of install(FILES ...)
- CMake Release Scripts: Changes for next release candidate...
-
-David Faure (1):
- Don't use a variable name that might be used in other files.
-
-Stephen Kelly (73):
- Create moc files in the current binary dir, not the top level.
- Make the formatting of feature_summary output a little better.
- Add the GenerateExportMacro with unit tests.
- Handle the case where the user changes the DEFINE_SYMBOL property.
- Add a newline at the end of the file.
- Add a newline at the end of the file.
- Add missing licence header.
- Remove the fatal_warnings option which is no longer used.
- Test for features, not specific compilers.
- Simplify. We already know we have hidden visibility at this point.
- Simplify the compiler feature check
- Add some debug output.
- Short-circuit the tests on unsupported compilers.
- Test expected no-op instead of aborting the build.
- Fix tests with clang.
- Fix typo and tests failing as a result.
- Only run the failure tests with gcc >= 4.2
- Set the CMAKE_RUNTIME_OUTPUT_DIRECTORY for windows builds.
- Only set the COMPILER_HAS_HIDDEN_VISIBILITY if GCC >= 4.2
- Disable all export macros on Borland.
- Another attempt to fix the tests on Borland.
- Use the correct project name compiletest not compilefail
- Fix off-by-not in test for Borland.
- Another attempt at fixing Borland.
- Add some debug output to narrow down deprecation test issues
- Export deprecated free methods too.
- Remember to surround the other deprecated test in the Borland check.
- Only set the deprecated attribute if hidden visibilty is enabled.
- Make sure the hidden visibility variables never get set on MINGW.
- Don't use hidden visibility on non-mingw windows either.
- Don't export methods on already exported classes.
- Split the deprecated available check from setting macro values.
- Test for compiler features, instead of for specific platforms.
- Exclude the XL compiler from the hidden-visibility test.
- Add the COMPILER_HAS_DEPRECATED only if it has a declspec variant
- Don't change the expected build result based on the platform.
- Expect the tests to pass if hidden visibilty is not enabled.
- Test -Werror instead of enabling it per compiler.
- Add some messaging output to make remaining issues findable.
- Perform the -Werror test only once.
- Test for deprecated attribute before declspec.
- Try to error on deprecated on Intel and SunCC.
- Borland can't do deprecated.
- Fixup forgotten part of aed84517c942a4c40f493fcf997cdf6a047349f8
- Disable testing of deprecated macros.
- Don't enable deprecated on HP.
- Don't enable deprecated on old GCC
- Exclude cygwin from the hidden visibility feature.
- Exclude PGI from exports and deprecated.
- Start testing expected values for compiler flags.
- Exclude win32 from hidden visibility checks.
- Comment the test assertion for now
- Test the correct cxx variable.
- Fix the version extraction regex for clang.
- Hopefully add version extraction for Intel.
- Add some settings for non-truncation of test output.
- Fix up the regex command for Intel.
- Test for too-old-intel compilers.
- Possibly fix test on HPUX.
- Possibly fix configuration test on AIX.
- Try to make the macros do almost nothing for Watcom.
- More consistency in the macro options.
- Add missing NO_EXPORT macro variant.
- Look for errors reported by PGI too.
- Quote paths in case there is a space in one of them.
- Disable the tests for Watcom.
- Fix Compiler id variable name.
- Add quotes in case cmake is installed in a prefix with a space.
- Fix the feature of using a specific prefix for macros.
- Add documentation about the prefix and no_deprecated options.
- Remove blank line at the start of the file.
- Don't start a line with a dash(-)
- Fix up verbatim code sections of the dox.
-
-Todd Gamblin (3):
- FindBoost: Call find_package with NO_MODULE first
- Fix XL compilers on non-AIX machines.
- Fixed link bugs in BlueGeneP build.
-
-Changes in CMake 2.8.6-rc1 (since 2.8.5)
---------------------------------------------
-Aaron C. Meadows (1):
- FindSubversion: Invoke svn non-interactively (#12304)
-
-Alex Neundorf (92):
- Add a switch to disable a find_package() call completely
- Add documentation for the CMAKE_DISABLE_FIND_PACKAGE_<Name> switch
- Add a basic test for CMAKE_DISABLE_FIND_PACKAGE_<package>
- Add macros cmake_push/pop_check_state() as discussed on the list.
- Fix copyright notice test
- Add CheckCXXSymbolExists.cmake, so this can be used also for C++
- Minor fix to try_compile() docs (#12333)
- Fix #12342: Add APPEND_STRING option to set_property()
- Extend FeatureSummary: add PURPOSE of package and TYPE
- FeatureSummary.cmake: remove "comment" field
- FeatureSummary.cmake: add INCLUDE_QUIET_PACKAGES keyword
- FeatureSummary.cmake: error out when a REQUIRED package is missing
- FeatureSummary.cmake: only higher TYPEs can override previous TYPEs
- FeatureSummary.cmake: cosmetics
- FeatureSummary.cmake: update documentation
- Remove debug output from CheckSymbolExists
- Don't put files from CMAKE_ROOT into CodeBlocks projects (#12110)
- More PATH_SUFFIXES for finding Postgresql and also search catalog/pg_type.h
- Use FPHSA(), remove unnecessary stuff and don't recommend link_directories()
- Mark the results from find() as advanced
- FindPostgreSQL: fix PATH_SUFFIXES, better output for FPHSA
- Strip trailing whitespace
- FindGIF/FindFreetype.cmake: remove standard search paths from find-calls
- FindGif: add giflib4 as one more name for the library under Windows
- Add basic version check for giflib
- Patch by Campbell Barton: puts definitions into C::B project file
- Remove useless line of code
- Also put builtin include dirs into CodeBlocks project file
- Remove trailing whitespace
- Also search for libxkbfile, XSync and SM include dir
- Provide macro write_basic_config_version_file()
- Add example to documentation
- Add some tests for write_basic_config_version_file()
- Fix copyright notice
- Really fix copyright notice
- Set UNSUITABLE instead of not COMPATIBLE
- Improve documentation for WriteBasicConfigVersionFile.cmake
- Add macros GETTEXT_PROCESS_POT() and GETTEXT_PROCESS_PO_FILES()
- Support REQUIRED in FindGettext.cmake (using FPHSA.cmake)
- Fix #12358: make optionally enabling ASM work again
- Start work on automoc: add empty cmQtAutomoc class
- Start implementing skeleton for automoc in cmake
- Add actual automoc code from automoc
- Remove the need to check for .h/.cxx during buildtime
- Add the cmake module required currently for automoc
- Add AUTOMOC to the add_library() command
- Fix line lengths
- Move code for parsing a cpp-file from the big loop to separate function
- Initialize verbose based onb the env.var.
- Color output when running moc
- Add the generated automoc.cpp file to the cleaned files
- Use cout instead of printf()
- Remove trailing whitespace
- Refactor SetupAutomocTarget() so it can be run after creating the target
- Remove trailing whitespace
- Move automoc processing from add_executable/library to cmGlobalGenerator
- Nicer progress message for the automoc target
- Add a test for automoc
- Add documentation for AUTOMOC, add initialization via CMAKE_AUTOMOC
- Fix logic which decides when to execute automoc test
- Automoc.cmake is not needed anymore
- Fix build: non-void function must return a value
- Fix warnings
- Fix bootstrap test with automoc
- Only enable the automoc test after checking that Qt4 works
- Fix build: use std::ios::out|ios::trunc instead of std::ios_base::out
- Silence warning in automoc: use long instead of int
- Fix automoc with VS builds: apply patch from Bill
- Make clLocalGenerator::GetTargetFlags() public
- Add find-package mode, which does nothing yet
- Implement find-package mode of cmake
- Replace cmake::GetScriptMode() with GetWorkingMode()
- Fix copyright notice in new CMakeFindPackageMode.cmake
- Better support for lib64 and Debian multiarch
- Use the file-utility to test for 64bit if there is no /usr/lib64
- Add a cmake.m4 for using cmake in autoconf projects instead of pkgconfig
- Improve documentation for --find-package mode
- Add a test for the new --find-package mode
- Only run the test if we are using a makefile generator under UNIX
- The makefile for the test was kindof wrong
- Fix test on OpenBSD with BSD make
- Rename helper macros print_compile_flags() to set_compile_flags_var()
- Dont check for -isysroot and -mmacosx-version on OSX in --find-package mode
- Disable any STATUS output in --find-package mode
- Much improved test, should now be executed on all UNIXes
- Make the --find-package test harder
- Make the test harder by always having a space in the include dirs
- Only enable the test when using GNU make
- Fix line length
- Use $(CXXFLAGS) and $(LDFLAGS) in the --find-package test Makefile
- Require the current cmake version in --find-package mode
- Fix --find-package mode on Cygwin, where enable_language(RC) is called
-
-Alexey Ozeritsky (5):
- fixed: search of acml libraries
- gotoblas supported
- ACML-GPU supported
- ACML-GPU supportede
- fixed: search of ATLAS library for C/C++-only projects
-
-Andreas Schneider (6):
- FindJava: Find missing java development executables.
- Modules: Added CMake Java support.
- Tests: Java tests should test UseJava.cmake
- Tests: Check for the new Java exeutable variables.
- Java: Use set_property/get_property for target variables.
- Java: Fix documentation format and indentation
-
-Arnaud Gelas (1):
- Search for the ASPELL executable
-
-Bill Hoffman (5):
- Only pay for unused variable checking if it is on.
- Initial support for Intel Fortran VS2010.
- Fix custom commands in VS2010 Fortran projects using CFG_INTDIR and test.
- Use MSBuild when devenv is not around, since VCExpress seems broken.
- Fix for bug #12413, nmake did not handle targets with + in the name.
-
-Brad King (13):
- MinGW: Remove old workaround and use native echo (#12283)
- Document caveat of custom commands in multiple targets (#12311)
- cmSystemTools: Remove trailing whitespace
- RunSingleCommand: Fix indentation
- RunSingleCommand: Avoid assignment in condition
- Documentation: WIN32 not defined on Cygwin (#12334)
- KWSys: Simplify SystemTools::GetTime implementation (#12261)
- KWSys: Avoid conversion warning in SystemTools::GetTime
- KWSys: Fix using long long and __int64 with hash_(set|map)
- KWSys: __int64 and long long may be same type in specialization
- XL: Fix old VisualAge branding of Fortran compiler
- Do not crash when an imported target depends on a missing target
- Fix CHECK_(C|CXX)_COMPILER_FLAG for Clang (#12394)
-
-Clinton Stimpson (5):
- Add -DQT_NO_DEBUG if no build type is specified so Qt plugins will work.
- Add qt4/QtCore to help find Qt headers when cross-compiling.
- Qt4: Fix reference of undefined variable when detecting frameworks on Mac OS X
- Remove C compiler requirement from FindQt4.cmake
- CPack/NSIS: Fix reinstall and multiple install issues when using components.
-
-David Cole (26):
- Begin post-2.8.5 development
- Fix Architecture test to work with Xcode 4
- Fix BuildDepends test to work with Xcode 4
- Base architecture choice logic on Xcode version
- Use correct default multiple architecture values in test
- Add use of EFFECTIVE_PLATFORM_NAME to generated Xcode projects.
- Correct KWStyle line too long error
- Add fail regex to detect supported warning flags correctly.
- Add support for Visual Studio project-specific globals (#8707)
- Fix machine-specific UpdateGIT test failures
- Ensure libgmp-10.dll is in the PATH for CMakeTestAllGenerators
- Watcom: Add -c flag to wlib calls (#12245)
- Add Watcom support to InstallRequiredSystemLibraries (#11866)
- Watcom: Use correct args for execute_process call (#11866)
- CTest: print failed tests in index order (#11746)
- Fix line too long style violation
- Documentation: Fix comments in the source code (#10941)
- Add more find_path locations for DCMTK header files (#12323)
- VS9: Add include_directories to midl command lines
- KWSys: Remove translation path for "/tmp_mnt/" (#10595)
- VS10: Avoid unnecessary rebuilds for custom commands
- QtAutomoc test: Pass QT_QMAKE_EXECUTABLE
- QtAutomoc: Eliminate compiler warning
- CheckSymbolExists: Use IMMEDIATE flag for configure_file (#11333)
- Xcode: Suppress same-old warning again.
- Xcode: Save object id values in CMakeCache.txt (#11690)
-
-Johan Björk (5):
- Xcode: Remove PREBINDING attribute for Xcode 4 and above
- RunSingleCommand: Replace verbose boolean with enum
- RunSingleCommand: Add a OUTPUT_NORMAL flag.
- Xcode: Quote ',' in Xcode string values (#12259)
- Xcode: Rearrange CMakeReRun to enable parallel builds
-
-Matej Hribernik (2):
- VS: Factor Find64BitTools out of Win64 generator to parent
- Add VisualStudio 9 and 10 generators for Itanium platform
-
-Modestas Vainius (1):
- multiarch: Treat lib/<arch> as implicit link dir (#12326)
-
-Oliver Buchtala (3):
- Java: Create java_class_filelist only if it does't exist.
- Java: Added some dependency magic to avoid recompilations.
- Java: Create correct jar archive dependencies.
-
-Rolf Eike Beer (2):
- remove extra output message from FindJava.cmake
- FindThreads: Try pthreads with no special option first (#11333)
-
-Steven Velez (1):
- VS10: Add SCC support
-
-Todd Gamblin (2):
- Try regular compiler when no MPI compiler.
- Fix issues with removing try_compile input file.
-
-Will Dicharry (1):
- Added HDF5 high level Fortran bindings to available components.
-
-Changes in CMake 2.8.5 (since 2.8.5-rc3)
---------------------------------------------
-Brad King (1):
- Revert "Add a new function SWIG_GET_WRAPPER_DEPENDENCIES to UseSWIG.cmake"
- (this revert means that issue #4147 has been re-opened)
-
-Changes in CMake 2.8.5-rc3 (since 2.8.5-rc2)
---------------------------------------------
-Bill Hoffman (4):
- Use devenv instead of msbuild for vs2010.
- Revert "With very long file names, VS 2010 was unable to compile files."
- Use relative paths for custom command inputs.
- Look for VCExpress as a possible build tool as well as devenv.
-
-Brad King (3):
- KWSys: Recognize color TERM=screen-256color-bce (#12287)
- find_library: Use lib->lib64 conversion in CXX-only projects (#12247,#12248)
- libarchive: Install COPYING with CMake documentation
-
-Christoph Höger (1):
- FindJNI: Search in Fedora arch-specific JVM location (#12276)
-
-Julien Malik (1):
- FindSWIG: Use NAMES in find_program directives (#12280)
-
-Modestas Vainius (1):
- Documentation: Fix spelling / formatting errors (#12287)
-
-Philip Lowman (3):
- FindBoost: Fixes #12188
- FindBoost: Also search for 1.46.1
- Detect VS 2010 SP1, faster and more robust detection
-
-Changes in CMake 2.8.5-rc2 (since 2.8.5-rc1)
---------------------------------------------
-Bill Hoffman (6):
- Fix a memory leak.
- Fix for bug#10798. VS10 did not append -I flags with COMPILE_FLAGS prop.
- Append and do not clobber CMAKE_CXX_FLAGS in the test.
- Use bin tree for inclues to avoid -I with spaces in the path.
- One more try. Use full path by default, and relative on broken compilers.
- Fix for bug #11927, external project git clone step always runs vs10.
-
-Brad King (9):
- XL: Place Fortran modules with -qmoddir= flag (#12246)
- Teach file(DOWNLOAD|UPLOAD) to timeout after inactivity
- Xcode: Fix parallel build depends with universal binaries (#11844)
- Fix style errors added by parent and grandparent
- Use cascading-if for per-config test and install code
- CTest: Report tests not run due to unknown configuration
- GNU: Fix CMAKE_INCLUDE_SYSTEM_FLAG_<lang> value (#12258)
- Teach find_(library|package) about Linux multiarch (#12037)
- Test find_package multiarch support (#12037)
-
-Clinton Stimpson (11):
- BundleUtilities: Work w/ non .app exes on Mac (#12034)
- BundleUtilities: Fix regex to extract dependents from ldd (#12034)
- BundleUtilities: Fix test when using xcode (#12034)
- BundleUtilities: Fix issues with custom target DEPENDS in test (#12034)
- BundleUtilities: Disable running test on Windows unless using MSVC.
- BundleUtilities: Run test on Windows if either MSVC or dumpbin was found.
- BundleUtilities: Print reason for not loading module.so
- BundleUtilities: Add rpath to loadable modules in test.
- Revert "BundleUtilities: Run test on Windows if either MSVC or dumpbin was found."
- Qt4: complete module dependencies in UseQt4.cmake
- Add imported targets support for frameworks on Mac.
-
-Daniel R. Gomez (1):
- Fix plugin API for gcc 2.9-aix51-020209 (#12233)
-
-David Cole (3):
- BundleUtilities: Avoid a cryptic and unhelpful error message
- BundleUtilities: Avoid test on Watcom dashboards (#12034)
- CMake: eliminate use of cvs in the Release scripts
-
-Eric NOULARD (2):
- CPackRPM: Enhance documentation
- Add some more Specs file tag handling.
-
-Johan Björk (3):
- CMake: Move tokenize to cmSystemTools
- Xcode: Support multiple level nesting of XCode folders (#10039)
- XCode: Support target folders on XCode.
-
-Modestas Vainius (1):
- multiarch: Set CMAKE_LIBRARY_ARCHITECTURE_REGEX for Linux|Hurd|kFreeBSD
-
-Philip Lowman (3):
- FindProtobuf: Better MSVC support, Searching for protobuf lite
- Fix , to - in Copyright message so it passes CMake.ModuleNotices test
- 10997: PROTOBUF_GENERATE_CPP now supports proto files outside current dir
-
-Rolf Eike Beer (1):
- CMake: Update documentation of STRING(SUBSTRING) for length -1 (#10740)
-
-Sean McBride (1):
- Fix XCode -> Xcode typos, notably in man page (#12231)
-
-Tim Gallagher (1):
- Modified the FindHDF5.cmake file to locate the Fortran bindings.
-
-Will Dicharry (7):
- HDF5 high level library is a find COMPONENT now.
- Add logic for CMake built HDF5 install.
- Use CMAKE_CURRENT_LIST_DIR to locate FindPackageHandleStandardArgs.
- Use HDF5_FOUND to control autoconf and CMake built FindHDF5.
- Fix for bug 11752, mixed debug and release libraries.
- FindHDF5 ensures good link lines when libraries are duplicated.
- Remove unnecessary mark_as_advanced from FindHDF5.
-
-Zach Mullen (3):
- Dynamic analysis test output should not be compressed.
- We will actually compress memcheck output if the server supports it.
- Fix type conversion warning
-
-Changes in CMake 2.8.5-rc1 (since 2.8.4)
-----------------------------------------
-Alex Neundorf (33):
- Rework the way assembler is handled, use the C/CXX compiler by default
- Make it possible to exlude external libs from dot files
- GRAPHVIZ_IGNORE_TARGETS is now a list of regular expressions
- Also generate dependers-graphviz files.
- Fix XML escaping for the project() name in Eclipse projects (#11658)
- Fix XML escaping for target names in Eclipse project files (#11658)
- Add XML escaping for directory name in Eclipse projects (#11658)
- Eclipse projects: created one linked resource for each subproject
- Also add the SOURCES from add_custom_target() to CodeBlocks projects (#11736)
- Add ASM support for the Intel compiler
- Actually use CMAKE_ASM_COMPILER for asm, instead of CMAKE_C_COMPILER
- Add support for ASM for the SunPro compiler
- Add suport for ASM for the IBM XL compiler
- Add support for ASm for the HP compiler.
- Set the HP asm file suffix
- Change the default rules so they fit better to the new ASM handling
- Fix the default CMAKE_ASM_COMPILE_OBJECT, make XL-ASM use it
- Add assemble- and preprocess commands for HP
- The Assembler test now tests ASM for GNU, Intel, HP, XL and SunPro
- Use a regexp instead a lot of ORs for checking the compiler ID
- Only try assembler support for Makefile-based generators
- Fix bad comparison in the detect assembler-code
- It's ELSEIF(), not ELSIF()
- Add temporary debug output for compiler ID detection for ASM
- Add more regex for gcc, always print the ASM compiler ID
- Add support for the Intel compiler used for ASM under Windows
- -use CMAKE_C_FLAGS when generating the assembler file
- -only enable the asm test for the Intel compiler if we are under UNIX
- Remove trailing whitespace
- Make use_mangled_mesa() available in cmake script mode (#11926)
- Fix parsing include dirs and builtin macros for CXX-only projects
- Don't skip the last builtin include dir for the Eclipse project file
- -fix VirtualFolders in Eclipse under Windows
-
-Alexey Ozeritsky (1):
- ACML search improvement
-
-Andreas Schneider (6):
- Modules: Added CheckPrototypeDefinition module.
- Tests: Added test for check_prototype_definition.
- FindOpenSSL: Added support for pkg-config.
- FindOpenSSL: We should only use hints to find OpenSSL.
- FindOpenSSL: Fixed crypto und ssl variable names.
- FindOpenSSL: Use find_package_handle_standard_args for version check.
-
-Bill Hoffman (2):
- With very long file names, VS 2010 was unable to compile files.
- Fix for bug where VS2010 did not use .obj files as part of the build.
-
-Brad King (94):
- Reject directory names containing '=' (#11689)
- FindQt4: Include builtin FindPackageHandleStandardArgs directly
- Handle trailing slashes on add_custom_command DEPENDS
- Handle relative WORKING_DIRECTORY in add_custom_(command|target)
- Pass -o after -c for Fortran to avoid mpif77 ordering bug
- Add link flag table entries for VS 7,8,9
- VS: Create a Fortran DLL's import library directory
- Fix linker flag initialization from LDFLAGS (#11840)
- ccmake: Remove extra parens around comparison
- Avoid direct use of std::stringstream
- Honor module .def files with MinGW tools (#9997)
- CTest: Update Git submodules with --recursive
- libarchive: Remove unused build/windows directory (#11885)
- Pass .def files directly to MinGW tools (#9997)
- Fix Fortran test .def file symbol mangling
- Require at least CMake 2.6.3 to build current CMake
- GNUInstallDirs: Simplify and clarify documentation
- KWSys: Require at least CMake 2.6.3
- Remove unused CMAKE_BACKWARDS_COMPATIBILITY mark
- Factor AIX and XL compiler flags into common module
- Move RPATH flags to AIX per-compiler information files
- Initialize ASM rpath flags for executables with those for shared libs
- Add ASM platform information for XL compiler on AIX
- Factor HP compiler flags into per-platform/per-compiler files
- Add ASM platform information for HP compiler on HP
- Add target property LINK_SEARCH_START_STATIC to aid static linking
- Test static linking with LINK_SEARCH_START_STATIC
- Fix Assembler test to parse C flags string before using
- Teach Assembler test to generate main.s at build time
- Do not bother enabling C++ in Assembler test
- The link interface of MODULE libraries is empty (#11945)
- CTest: Do not fail with submodules and Git < 1.6.5.0
- Remove trailing whitespace
- Add parens in cmTarget::ComputeLinkInterface logic
- Validate custom command arguments (#11963)
- Factor old-style -D flags out from -I flag generation
- FindMPI: Fix documentation formatting
- Generate target-wide flags before individual build rules
- Optionally pass include directories with response files
- Pass include directories with response files to GNU on Windows
- Enable Java test more carefully on Apple
- Disable Java test with Xcode generator
- Allow '.' in target names in generator expressions (#12002)
- GNUInstallDirs: Propagate DATAROOTDIR changes to dependent defaults
- KWSys: Do not trust EXECUTABLE_OUTPUT_PATH for ProcessFwd9x encoding
- Refine unused cache variable warning
- Fix unused cache warning after multiple configure iterations
- FortranCInterface: Fix mangling detection with Cray Fortran >= 7.3.2
- Fix typo in include_directories documentation (#12020)
- KWSys: Recognize rxvt-unicode-256color terminal (#12013)
- Normalize slashes of add_custom_(command|target) DEPENDS (#11973)
- COMP: Fix build against non-standard outside libarchive
- Modules: Add comment and copyright notice validation to readme.txt
- cmArchiveWrite: Clear xattr and acl from entries (#11958)
- find_package: Forward component list for recursive calls in modules
- XL: Set C++ and Fortran flags consistently with C
- XL: Consolidate compiler flag information
- XL: Avoid copying archives into shared libraries that link them
- VS10: Fix working directory of consecutive custom commands (#11938)
- Fix working drive of make rules on Windows
- Change working drive only in MinGW Makefiles
- VS: Use setlocal/endlocal only in VS 10 custom commands
- VS10: Fix exit code of custom commands with setlocal/endlocal (#11938)
- KWSys: Remove unused CheckCXXSourceRuns cmake module
- find_package: Rename implementation of user package registry
- find_package: Cleanup user package registry less aggressively
- find_package: Document user package registry locations
- find_package: Search a "system package registry"
- find_package: Check both 32-bit and 64-bit registry views
- find_package: Test system package registry when possible
- find_package: Fix system package registry test path conversion
- FindITK: Use passthru find_package config mode for messages
- OpenBSD: Use 'arch -s' for host processor (#12143)
- Fix case typo in CMAKE_BUILD_TYPE docs (#12148)
- KWSys: Fix leaked FILE in EncodeExecutable error case
- ENH: Fix Intel 12 plugin project generation for VS < 10
- Revert "Honor RULE_MESSAGES property for build target messages" (#12190)
- Fix signed/unsigned comparison in EscapeJSON
- Fix run_compile_commands build on Apple GCC 3.3
- Make std::map usage more portable in language=>flags/defines maps
- Provide std::map<>::at for use in run_compile_commands
- run_compile_commands: Avoid shadow in std::map<>::at workaround
- Improve string(RANDOM) default seed
- run_compile_commands: Avoid extra stl vector conversion
- VS 6: Define _WIN32_WINNT to load wincrypt.h correctly
- run_compile_commands: Cast istream::get() result to char
- Fix CompileCommandOutput test for Make tools not supporting spaces
- Explicitly cast time value in cmSystemTools::RandomSeed
- Fix CompileCommandOutput test build on Windows
- Add Absoft Fortran compiler id and basic flags
- Absoft: Detect implicit link libraries on Linux and Mac
- Absoft: Enable FortranCInterface check in Fortran test
- Document status of output_required_files command (#12214)
- Fix forced-seed argument type in string(RANDOM)
-
-Clement Creusot (2):
- Add new module Armadillo
- Corrected copyright format in FindArmadillo.cmake
-
-Clinton Stimpson (8):
- Change to use fphsa to check required variables and version.
- Fix grouping bug where "Ungrouped Entries" showed up as a child.
- When checking find_package() components, special case qtmain.
- Fix issues with find_path() for QtCore include dir on Mac. Fixes 11868.
- Fix regression in 43cb9b8.
- Speed up creation of parameters file for moc custom command.
- Combine component packaging methods into an enum.
- Add component support to DragNDrop generator.
-
-David Cole (34):
- ExternalProject Test: Increase test timeout value
- CFBundle Test: Add PATHS for finding Rez (#11295)
- CTest: Mark DART_TESTING_TIMEOUT as advanced (#10150)
- Xcode: Allow override of CMAKE_CONFIGURATION_TYPES (#8914)
- Tests: Eliminate unnecessary files and variables.
- VS9: Map enable/disable PREfast flags (#10638)
- Strip trailing space from xcode-select output (#10723)
- CTest: Add alias for make test target (#4564)
- Add CMAKE_SCRIPT_MODE_FILE variable (#2828)
- Add CMAKE_ARGC and CMAKE_ARGV0..N-1 variables (#2828)
- Fix KWStyle line-too-long complaint (#2828)
- Documentation: Sync two differing copies of -E docs (#10446)
- Clarify list subcommand documentation (#8154)
- VS2010: Fixed GenerateManifest flag (#10704)
- VS: Only use /MANIFEST if hasManifest is true (#11216)
- Make file DOWNLOAD less noisy (#11761)
- Begin post-2.8.4 development
- Use stable_sort to preserve test order (#11877)
- Implement file(UPLOAD (#11286)
- Fix KWStyle line too long error (#11286)
- ExternalProject: Extract file names from more urls
- InstallRequiredSystemLibraries: Read reg values with get_filename_component
- Add correct module notice header.
- If getconf returns empty output, try cpuinfo. (#11302)
- Add ProcessorCount support for QNX via pidin. (#11302)
- Compare ProcessorCount to SystemInformation count. (#11302)
- ProcessorCount test: more output, do not fail. (#11302)
- ProcessorCount: Add support for remaining platforms (#11302)
- ProcessorCount: Test fails if count is 0 (#11302)
- ProcessorCount: Use ERROR_QUIET with execute_process (#11302)
- ExternalProject: Add SVN_TRUST_CERT argument
- CMake: Clarify the --debug-trycompile help text
- ExternalProject: Always use --non-interactive with svn
- VS10: Write header-only files in correct xml element (#11925)
-
-Eric NOULARD (25):
- CPackRPM honors all the different ways of packaging components
- CPackRPM fix IRIX compiler warning (variable never used)
- CPack remove "-ALL" suffix for ALL-IN-ONE packages
- CPack Authorize DISPLAY_NAME usage in component package
- CPack fix KWStyle warning
- CPack remove previously CPack generated files (if any) before running CPack
- CPackRPM Replace space in some CPACK_ vars (Fix bug 9932)
- CPackRPM activate CPackRPM test on Linux systems where rpmbuild is found
- CPackArchive package all components specified in CPACK_COMPONENTS_ALL
- CPack more robust way to collect files belonging to a component
- CPackRPM do not run test if build dir contains space
- CPack fix compile error on VS70 and avoid KWStyle warnings
- CPackRPM add more trace output in order to help failing diagnostics
- CPackRPM even more trace in debug mode or in case of failure
- CPackRPM non matching ENDIF
- CPack try to please SUSE 64 bits and install lib in lib64 and not lib.
- Remove debbuging typo
- CPack fix CPackDeb crash when CPackDeb.cmake ends with a FATAL_ERROR
- CPack fix #11930 and simplifies component packaging options
- Fix #11964 Handle lib64 library on Linux
- Fix KWStyle warnings
- Split CPack.cmake in more manageable parts
- Fix KWStyle warnings
- CPackRPM Fix #12096: handle absolute install path with component install
- CPack make RPM work on AIX. fix #0012183 merge patch from Pasi Valminen
-
-James Bigler (1):
- Add FloatingPointModel to the list of known VS7 generator flags.
-
-Johan Björk (1):
- XCode: Also qoute [] as needed to set build-configurations.
-
-Kovarththanan Rajaratnam (1):
- Documentation: document platform specific -E commands (#10446)
-
-M. Konrad (1):
- CPackDeb add Component Support to DEB generator fix #0011655
-
-Manuel Klimek (6):
- refactor flags and defines
- cache flags and defines
- implement cxx command output
- make compile command output optional
- Adds a test for the compile command line output.
- Only offer the compile command output feature on unix systems
-
-Marco Craveiro (1):
- CTest: Use the gcov --preserve-paths flag (#11717)
-
-Markus Rathgeb (1):
- When cross compiling, don't double-root paths when using find_*.
-
-Martin Konrad (2):
- CPackDeb: Fix #12006 broken package names
- CPackDeb: Handle dirs for CONTROL_EXTRA correctly when packaging components
-
-Mathieu Malaterre (8):
- This commit fixes bug #0010316
- Add a new function SWIG_GET_WRAPPER_DEPENDENCIES to UseSWIG.cmake
- Add support for Java on HP
- Add support for java on fedora
- UseSWIG.cmake does not expand $(OutDir)
- Add support for new swig 2.0 application
- UseSWIG.cmake did not support multiple modules and parallel builds
- Add support for FindJava on HP-UX and alpha
-
-Michael Wild (1):
- Add module ProcessorCount.cmake (#11302)
-
-Modestas Vainius (1):
- Documentation: Fix a few typos (#11883)
-
-Nikita Krupen'ko (1):
- Add GNUInstallDirs module to define GNU layout (#3976)
-
-Philip Lowman (1):
- VS7/8/9: Map whole program optimization flags (#10263)
-
-Richard Bateman (1):
- Add support for CFBundle targets on the Mac (#11295)
-
-Rolf Eike Beer (2):
- CTest: catch warning output of Apache Maven
- FindZLIB: print library instead of include directory
-
-Sean McBride (1):
- Removed most usage of Carbon in favour of CoreFoundation
-
-Sebastian Herbst (2):
- VS8/9: Add flag map entries for /Zc:wchar_t (#10397)
- VS7/8/9: Add flag map for string pooling option (#10397)
-
-Tim Hütz (1):
- Add a string(FIND) sub-command (#11795)
-
-Todd Gamblin (2):
- FindMPI: Handle multiple languages
- Added backward compatibility for input as well as output vars.
-
-Wesley Turner (1):
- Ensure executable files have executable permissions.
-
-Zach Mullen (5):
- Implement ctest_upload command
- Change 'Files' tag to 'Upload' in Upload.xml
- Don't tar/gz ctest_upload() files
- Add the FILES keyword to ctest_upload command
- cmCTestUploadCommand::CheckArgumentKeyword should return false if not FILES
-
-Changes in CMake 2.8.4 (since 2.8.4-rc2)
-----------------------------------------
-Alex Neundorf (1):
- Fix crash in GraphVizWriter when GRAPHVIZ_TARGET_IGNORE_REGEX is used
-
-Andreas Schneider (1):
- FindPerlLibs: Add notice of copyright
-
-Brad King (3):
- libarchive: Define major/minor/makedev only where needed (#11648)
- libarchive: Use OpenSSL only if CMAKE_USE_OPENSSL (#11815)
- Fix documentation of MSVC_VERSION (#11833)
-
-David Cole (1):
- Silence the may be used uninitialized warnings: initialize stuff.
-
-Eric NOULARD (2):
- CPack Tests the different ways of packaging components
- Avoid foreach IN LISTS syntax which is not supported by CMake 2.6
-
-Changes in CMake 2.8.4-rc2 (since 2.8.4-rc1)
---------------------------------------------
-Alex Neundorf (3):
- Make cmake build again with cmake < 2.6.3
- Strip trailing whitespace.
- Fix parsing of compiler name with a version number
-
-Ben Boeckel (86):
- ... 86 commit messages summarized as:
- Fix ADD_TEST regression when WORKING_DIRECTORY not given
- Add new "strict-mode" CMake variable checking
- Activate / avoid using new command line arguments:
- --warn-uninitialized
- --warn-unused-vars
- --no-warn-unused-cli
- --check-system-vars
-
-Bill Hoffman (3):
- For macros make sure the FilePath points to a valid pointer in the args.
- Add a warning when variables are used uninitialized.
- Make --strict-mode option, and integrate with cmake-gui
-
-Brad King (34):
- bootstrap: Granular system library selection (#11431)
- bootstrap: Clarify --init flag documentation (#11431)
- bootstrap: --verbose implies verbose Makefiles (#11708)
- Combine duplicate COMPILE_DEFINITIONS disclaimer
- Document COMPILE_DEFINITIONS known limitations (#11660, #11712)
- Document try_compile behavior more clearly (#11688)
- Document Check(C|CXX)SourceCompiles behavior more clearly (#11688)
- Fix get_(cmake|test)_property documentation (#11703)
- Reference get_property() from old get_*_property() commands
- Replace misleading example in the if() documentation (#10773)
- Clarify auto-dereference cases in if() command (#11701)
- Document CheckFunctionExists more clearly (#10044)
- Document CheckSymbolExists more clearly (#11685)
- Update CheckSymbolExists copyright year
- Report directory with missing source file (#11677)
- Test that missing source mentions directory (#11677)
- Teach Simple_Mingw_Linux2Win test to use windres
- Disable SubDirSpaces parens with GNU Make 3.82 (#11654)
- libarchive: Fix major() check for LSB 4.0 (#11648)
- Xcode: Make generation depend on all input directories
- Recognize SCO UnixWare C/C++ compilers (#11700)
- Factor SCO compiler info out of platform file (#11700)
- Honor CMAKE_TRY_COMPILE_CONFIGURATION in Makefile generators (#10809)
- Document CMAKE_TRY_COMPILE_CONFIGURATION variable
- Honor VS_SCC_* properties in Fortran targets (#10237)
- Normalize slashes in scanned #include lines (#10281)
- Improve try_compile and try_run error messages
- Use shortest extension to verify try_compile language (#11731)
- Modules: Include builtin FindPackageHandleStandardArgs directly
- Fix relative CMAKE_USER_MAKE_RULES_OVERRIDE (#11725)
- Clarify CMAKE_USER_MAKE_RULES_OVERRIDE documentation (#11724)
- Always place try_compile executables predictably (#11724)
- try_compile: Allow only languages loaded in caller (#11469)
- Fix ArgumentExpansion test expected results
-
-Clinton Stimpson (1):
- Replace exec_program with execute_process for qmake queries.
-
-David Cole (16):
- Update script with new machine name
- VS10: Fix problems with InstallRequiredSystemLibraries.
- Add CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS variable
- Add CPACK_NSIS_INSTALL_ROOT for CMake's own installer (#9148)
- Xcode: Disable implicit make rules in custom rules makefiles.
- Add freeglut as library name (#10031)
- Add new names for PNG and ZLIB libraries
- Avoid exceptions when ccmake terminal window is too small (#11668)
- VS10: Load projects with obj "source" files (#11147)
- VS10: Enable using devenv as CMAKE_MAKE_PROGRAM (#11459)
- Xcode: Fix crash: avoid strlen call on NULL char *
- CTestTest2: Avoid running purify unless requested
- VS10: Escape double quote chars in defines for rc files (#11695)
- Fix line too long KWStyle issue (#11695)
- Avoid space in rc /D values for VS6 and Cygwin (#11695)
- VSResource: Avoid windres /D with quoted spaces (#11695)
-
-Marcus D. Hanwell (1):
- Bug #11715 - generate header in the build tree.
-
-Nicolas Despres (1):
- bootstrap: Add --enable-ccache option (#11707)
-
-Changes in CMake 2.8.4-rc1 (since 2.8.3)
-----------------------------------------
-Alex Neundorf (32):
- Add support for nasm assembler, patch by Peter Collingbourne (see #10069)
- Improve misleading comments.
- Add missing copyright headers
- We already have 2010, fix copyright year.
- Make FindBISON work properly with non-C locales (#11326)
- Add support for yasm, a nasm compatible assembler
- Use CMAKE_ASM_NASM_FLAGS for nasm instead of FLAGS
- Remove trailing whitespace and minor formatting changes for the dot-code
- Move the code for collecting targets and libraries into separate functions
- Properly insert all targets, also those which don't link to anything.
- Generate separate dot files for each target, and a big one with everything.
- Move the code for generating dot-files into separate class cmGraphVizWriter
- Fix #11421: FindQt3.cmake doesn't honor the REQUIRED keyword
- Remove trailing whitespace
- Don't enforce VERBOSE makefiles for the CodeBlocks generator
- Remove the "early alpha stage" comments about Eclipse and C::B
- Don't disable colors in the CodeBlocks generator and minor cleanup.
- Some more fixes for nasm support, from Etienne (#10069)
- Enable/disable generating graphs depending on the target type
- Use std::cout instead of fprintf
- Collect targets and libs on demand instead of in the ctor
- Exclude targets from the graphviz file based on a regex
- Include CMakeDetermineCompilerId in CMakeDetermineASMCompiler.cmake (#11467)
- Fix typos in the doc
- Add cache var CMAKE_ECLIPSE_MAKE_ARGUMENTS when using the Eclipse generator
- Add ECLIPSE_CDT4_GENERATE_SOURCE_PROJECT as a ADVANCED cache variable (#9631)
- Fix crash in Eclipse generator with empty project (#11616)
- Fix indentation in cmPolicies::ApplyPolicyVersion()
- Remove trailing whitespace
- Prefer files from CMAKE_ROOT when including from CMAKE_ROOT
- Improve documentation and messages for the new CMP0017
- Remove usage of CMAKE_CURRENT_LIST_DIR now that we have CMP0017
-
-Alexey Ozeritsky (5):
- FindBLAS works in C/C++ projects without Fortran
- ACML find fixes (issue 0011219)
- find ACML fixes
- fix for Fortran-only projects
- FindLAPACK works with C/C++ only projects (issue 0009976)
-
-Andrius Å tikonas (1):
- Modules: Fix spelling 'becase' -> 'because'.
-
-Ben Boeckel (25):
- Fix parsing of cache variables without a type
- Use cmCacheManager to load entries from the cache
- Support manual cache entries
- Condense parsing of cache entries
- Use FPHSA in FindOpenGL
- Ignore strerror_r since CMake isn't threaded
- Use _POLL_EMUL_H_ instead of HAVE_POLL_FINE
- Rename WorkingDirectory test
- Add WORKING_DIRECTORY argument to add_test
- Add tests for WORKING_DIRECTORY arg to add_test
- Rename the project to match the test
- Fix header includes for C++ and Visual Studio
- Add ctype.h include for toupper()
- Flip slashes around on Windows
- Use --><-- markers to denote the path
- Simplify the _default_cwd derivation
- Only test the default cwd with Makefiles
- Group adding tests with its properties
- Fully specify the path to old-signature add_test
- Use iostream to make Borland happy
- Check for poll when looking for _POLL_EMUL_H_
- Toss out strerror_r macros
- Fix missed _POLL_EMUL_H_ and HAVE_POLL combo
- Make TestsWorkingDirectory test a C file
- Pass the expected value as the first argument
-
-Bill Hoffman (17):
- Fixes for the OSF operating system build.
- Add a fix for the inline keyword on the osf os.
- Add a "Contract" test for VTK. The test downloads and builds VTK.
- Fix contract test so it is not hard coded to the vtk542 test.
- Fix incremental linking for VS2010 with nmake or make.
- Change cpack run and verify script to work with multi-config generators.
- Fix vs2010 project generation error when HEADER_FILE_ONLY is set.
- Add more documentation for LANGUAGE property.
- Add flags to resource builds on vs 2010 with a test.
- Disable incremental testing for this test, it crashes vs9 linker.
- Only run resource test for MSVC compilers.
- Add support for windows resources with mingw/msys.
- Add support for windres to cygwin.
- Add testing for windows resources for mingw/msys/cygwin and remove for watcom.
- Enable resource building with the intel compiler on windows.
- Add support for source files in custom targets for VS 10 (Bug#11330).
- Change the nightly tests to build from the nightly branch and not next.
-
-Brad King (90):
- Store direct dependencies in solutions for VS >= 8
- BUG: Fix compiler flag test for non-English MSVC (#11336)
- Document custom command behavior without DEPENDS (#11407)
- Consolidate duplicate link rule make dependency code
- Define LINK_DEPENDS target property (#11406)
- KWSys: Teach SystemInformation about WinXP Pro and Win7
- Fix Intel .vfproj SubSystem attribute values
- Set Intel .vfproj RuntimeLibrary attribute
- Create Fortran info variables for .mod behavior
- Teach CMake about Cray C, C++, and Fortran compilers
- Speedup find_* commands (#11412)
- Prefer non-empty prefixes when matching lib names (#11468)
- Record edge type in global dependency graph
- Use modern global dependency graph for VS < 8 deps
- Allow add_dependencies() on imported targets (#10395)
- Pass Mac linker flag through PGI compiler using "-Wl,"
- Modernize FindITK module (#11494)
- Fix find_* argument parsing crash (#11513)
- Skip VS <= 7.1 dependency analysis for VS >= 8
- Enable 64-bit tools with VS 2010 Express (#9981, #10722)
- KWSys: Associate installed library with an EXPORT
- Fix try_compile RemoveFile anti-virus loop (#11503)
- Fix Fortran .mod timestamps with Cray compiler
- Make Fortran $obj.provides.build targets not .PHONY
- Honor custom command dependencies on imported targets (#10395)
- Improve signature of cmLocalGenerator::GetRealDependency
- Skip file-level dependencies on custom targets (#11332)
- Simplify VS generator ConstructScript interface
- Factor out common custom command generator
- Remove cmLocalGenerator::GetRealLocation
- KWSys: Remove realpath from SystemTools::GetPath (#10335)
- Fix parallel "make install" of CMake itself
- CTest: Fix ctest_sleep documentation (#11554)
- Fix soname in cross-compiled targets with Mac host (#11547)
- Detect object files in implicit link information
- Allow Fortran platform files to set empty values
- Recognize the NAG Fortran compiler
- Add NAG Fortran compiler information files
- FortranCInterface: Recognize NAG Fortran module symbols
- Remove unused variable "rootdir" in VS generators
- Avoid msbuild idiosyncrasy that builds multiple configs (#11594)
- Remove unused parameter "root" in some VS generator methods
- Fix dependency tracing of INSTALL and PACKAGE (#11598)
- Remove unused GLOBAL_TARGET generation code
- KWSys: Use EXPORT name only if installing library
- Write full version into try_compile CMakeLists
- KWSys: Do not mangle UNC paths in ConvertToUnixOutputPath (#10206)
- Normalize add_custom_command OUTPUT names (#10485)
- Make link rule depend on ".def" file (#11014)
- Document target_link_libraries target scope (#11058)
- Record backtrace in cmCustomCommand
- Factor generator expression docs out of add_test
- Factor per-config sample targets out of 'Testing' test
- Optionally suppress errors in cmGeneratorExpression
- Record set of targets used in cmGeneratorExpression
- Introduce "generator expression" syntax to custom commands (#11209)
- CTest: Fix test DEPEND cycle detection
- Make Intel defines consistent with MSVC on Windows (#9904)
- CTest: Fix line-too-long style in DEPEND cycle error
- Detect Fortran target architecture on Windows
- Modernize Intel compiler info on Windows
- Remove unused old-style g++ info file
- CheckCCompilerFlag: Strict signature of 'main' (#11615)
- Warn in find(GLOB) docs about bad use case (#11617)
- Remove call to SystemTools::GetMaximumFilePathLength
- Xcode: Generate native 3.2 projects
- Declare min CMake version in --system-information project
- Cygwin: Fix tests to check CYGWIN instead of WIN32
- Cygwin: Do not define 'WIN32' (#10122)
- Revert "Remove unused parameter "root" in some VS generator methods"
- Revert "Avoid msbuild idiosyncrasy that builds multiple configs" (#11633)
- Avoid msbuild ".\" idiosyncrasy that builds multiple configs (#11594)
- Mark CustomCommand test perconfig.out as SYMBOLIC
- CTest: Factor out duplicate Git author/committer code
- KWSys: Avoid buffer overflow in SystemInformation (#11018)
- Fix sentence break in add_test documentation
- Pass Mac linker flag through all compilers with -Wl,
- KWSys: Avoid passing string literal as char*
- Avoid passing string literal to char* type
- Fix constness in compiler id detection
- Build enable_language command during bootstrap
- Map multiple /FI flags for VS < 10 (#11649)
- KWSys: Remove useless include <sys/procfs.h> (#11648)
- Allow users to specify defaults for unset policies
- ccmake: Use LSB 4.0 curses API conditionally
- CTest: Do not truncate UTF-8 test output too early (#10656)
- ccmake: Use LSB 4.0 getmaxyx conditionally
- Allow platform files to set large archive rules (#11674)
- Document reading LOCATION early as undefined (#11671)
- Document reading LOCATION_<CONFIG> early as undefined (#11671)
-
-Brian Bassett (1):
- VS: Fix linking of Fortran-only DLL projects (#10803)
-
-Campbell Barton (1):
- Honor RULE_MESSAGES property for build target messages
-
-Chuck Atkins (1):
- CTest: Teach launcher to ignore empty/no-op make commands
-
-Clinton Stimpson (11):
- Fix regex for moc includes when looking for frameworks.
- cmake-gui: use BundleUtilities in place of custom script.
- Fix regression in 2dae2f1 which added find of Qt imports dir.
- Force cmake to run again when qrc dependency scanning needs to happen.
- Fix regression to allow specifying a CMakeCache.txt file on the command line.
- BundleUtilities: only do rpath strip on copied prerequisites.
- Fix build issues cross compiling with static Qt.
- CTest: multiple ctest_test calls w/LABEL regexs (#11487)
- cmake-gui: always enable generate button.
- allow absolute paths for dbus interface.
- Add support for using static/dynamic Qt plugins.
-
-Craig Scott (1):
- ccmake: Port for LSB 4.0 (#11648)
-
-Dave Abrahams (1):
- FindPerlLibs: Fix for Mac locally applied patches
-
-David Cole (31):
- Add a contract test for building the CSE.
- Enable overriding contract test timeout values.
- Update tag in the Contracts/cse-snapshot test.
- Make HTML test fail when --nonet arg is not available.
- Begin post-2.8.3 development
- No CMake.HTML test if xmllint has no --nonet.
- Suppress "loop was vectorized" "warnings."
- Add contract test for Trilinos 10.6.1 snapshot.
- Honor FOLDER on include_external_msproject targets (#11436)
- Correct misspelling in error message text.
- BundleUtilities: error if fixup_bundle_item called on non-embedded item
- VS10: stop build on custom command error (#11533)
- CPack: look for makensis in the PATH (#8210)
- VS10: avoid warning, no nologo when verbose (#10587)
- Use m prefix in shorttag value to indicate "md5 of tarball"
- Establish pass criteria for the Trilinos contract test.
- Suppress erroneous warnings from Intel compiler
- Avoid running CMake.Install test simultaneously with other tests
- VS10: Finish Midl support (#11461)
- Prohibit space in HOME value for VSMidl test.
- KWSys: Fix CPU speed calculations (#9963)
- KWSys: Retrieve QNX specific memory and processor info (#11329)
- Improve build error detection.
- VSMidl Test: Use correct include_directories with VS6 (#11461)
- Add PATH_SUFFIXES for finding git.
- ExternalProject: Avoid bleed-through output when logging.
- Fix WOW64 registry mode on Windows 2000 (#10759)
- ExternalProject: Replace location tags in CMAKE_CACHE_ARGS
- CPack: Detect more URLs in CPACK_NSIS_MENU_LINKS (#10644)
- KWSys: Fix WOW64 registry mode on Windows 2000 (#10759)
- CPack: Add CPACK_NSIS_INSTALL_ROOT variable (#9148)
-
-Eric NOULARD (13):
- CPackRPM add basic component support to CPackRPM
- CPack fix kwstyle breakage and make CPackRPM backward compatible
- CPack backward compatibility fix 2.8.3-2.8.2 (bug 11452)
- CPack Fix KWStyle error
- CPack Honor CPACK_MONOLITHIC_INSTALL at CPack time too
- CPack use IsOn when it's better than IsSet
- CPackRPM fix bug 0011595 : Can't generate RPMs (on FC11...)
- CPack new tests for component install
- CPack Default component test for ZIP should be OK
- CPackTest spit out more output in case of failure
- Arrange output in a better way
- Precise the project config type when invoking cpack
- CPackSTGZ quote here-doc, fix bug10518
-
-Kai Wasserbäch (1):
- FindTCL: Fix TCL and TK version variable references (#11528)
-
-Marcus D. Hanwell (5):
- BUG 11451 - pass CMAKE_EXTRA_GENERATOR down.
- Added CMAKE_CACHE_ARGS to ExternalProject.
- Escape file write expansion, and build up lists.
- Fixed bug where last entry would be lost.
- Python additional version support, bug #10279.
-
-Matthias Kretz (1):
- Inline help in vim with vertical split.
-
-Mike McQuaid (6):
- Fix incorrect variable documentation (#11127)
- Add variable for InstallRequiredSystemLibraries dir (#11140)
- InstallRequiredSystemLibraries debug-only (#11141)
- Allow NSIS package or uninstall icon (#11143)
- Add CPACK_NSIS_EXECUTABLES_DIRECTORY (#7828)
- Add CPack NSIS MUI_FINISHPAGE_RUN support (#11144)
-
-Philip Lowman (8):
- 11363: FindBoost.cmake fails to find debug libraries in tagged layout install
- 11429: FindGTK2 does not find libraries built for Visual Studio 2010
- 11430: FindBullet doesn't find header files installed by Bullet >= 2.77
- 11384: FindCxxTest now includes test code in VS project
- [patch] Add Boost 1.45 to search, simplify a check removing VERSION_LESS
- Add Boost 1.46
- Fix spelling BOOST_LIBRARYDIR message. Add error for common misspellings.
- Lowercase all function names and improve consistency
-
-Rolf Eike Beer (2):
- allow STRING(SUBSTRING) work with length -1 as "rest of the string"
- Add the WORKING_DIRECTORY property to tests
-
-Wojciech Migda (1):
- Recognize the Texas Instruments DSP compiler (#11645)
-
-Yaakov Selkowitz (2):
- Cygwin: Use 'cyg' prefix for module DLLs (#10122)
- Cygwin: Fix release script libncurses search patterns (#10766)
-
-Zach Mullen (4):
- Remove debugging message from parallel ctest
- CTest git update should pass the committer as well as the author
- Support explicitly set test costs in non-parallel testing.
- Test TIMEOUT property explicitly set to zero should be honored
-
-No changes in CMake 2.8.3 since 2.8.3-rc4.
-
-Changes in CMake 2.8.3-rc4 (since 2.8.3-rc3)
---------------------------------------------
-Bill Hoffman (1):
- When processing DartMeasurements use the tests working directory.
-
-David Cole (2):
- ExternalProject: No svn --username if empty (#11173)
- Avoid problem reading jni.h on Macs.
-
-David Partyka (5):
- Fixed appending PATH to dumpbin tool from growing without bounds.
- Switch to CMAKE_PATH when doing PATH comparisons on Windows.
- Remove unecessary TO_CMAKE_PATH for gp_cmd_dir.
- Append the gp_tool path to the system PATH using native slashes.
- Fixes to GetPrerequisites for cygwin
-
-Eric NOULARD (1):
- CPackDeb Added several optional debian binary package fields
-
-Marcus D. Hanwell (2):
- ENH: Added case for Python 2.7.
- Fixed parallel build for generators with EXTRA.
-
-Changes in CMake 2.8.3-rc3 (since 2.8.3-rc2)
---------------------------------------------
-Alex Neundorf (4):
- Remove trailing whitespace
- Add automatic variable CMAKE_CURRENT_LIST_DIR(dir of CMAKE_CURRENT_LIST_FILE)
- Use absolute path to FindPackageHandleStandardArgs.cmake everywhere
- CodeBlocks Generator: Do not omit files in the project file listing.
-
-Brad King (4):
- VS10: Order .vcxproj dependencies deterministically (#10502)
- Document ENABLE_EXPORTS behavior on Mac (#11295)
- FindHDF5: Fix typo in parallel-IO support check (#11291)
- Xcode: Recognize .hh as C++ (#11307)
-
-Clinton Stimpson (1):
- Find imports dir in Qt 4.7
-
-David Partyka (1):
- Update module to locate newely released MS MPI HPC Pack R2.
-
-Philip Lowman (1):
- Remove superfluous variable Boost_COMPAT_STATIC_RUNTIME.
-
-Rolf Eike Beer (2):
- FindSubversion: Fix for German localized client (#11273)
- FindSubversion: Use C locale to detect version (#11273)
-
-Changes in CMake 2.8.3-rc2 (since 2.8.3-rc1)
---------------------------------------------
-Alex Neundorf (5):
- APPEND and not-APPEND mode of feature_summary() were swapped
- Set a default DESCRIPTION if none is given for ALL mode of feature_summary()
- Close ENDFUNCTION() properly with the same name as FUNCTION()
- Make cmake-gui remember whether the "Advanced" checkbox was checked or not
- Also store the required version number in the details message.
-
-Ben Boeckel (3):
- Add test that CMake errors with empty libs
- Fix which string is checked for in the test
- XCode generation should fail if lang isn't known
-
-Bill Hoffman (5):
- Fix the name of the variable being tested.
- Fix KWStyle line length issues.
- Add a delay after untar on windows to make external project work on windows 7
- Add a new line to the end of the generated main.cxx for the hpux compiler.
- Fix for bug #11274, VS10 custom commands that create files in INTDIR fix.
-
-Brad King (12):
- Evaluate <OBJECT_DIR> rule variable for executables
- ccmake: Fix search with '/'
- MinGW: Support long object file lists
- Document IMPORTED_NO_SONAME target property
- FindMPI: Recoginze -f flags from mpicc (#10771)
- Add module-dir flag for Compaq Visual Fortran (#11248)
- FindPythonInterp: Look for python2.7 interpreter
- VS10: Use $(IntDir) for per-source output directory (#11270)
- Reset platform/compiler info status for each language
- Remove trailing whitespace from Xcode generator source
- VS10: Skip targets with no linker language (#11230)
- VS10: Encode custom command comments for echo (#11283)
-
-Clinton Stimpson (1):
- Fix regression in cross-compile patches with finding Qt libs.
-
-David Cole (7):
- Enable calling commands with : in argv[1] (#9963)
- No extra spaces in CustomCommand test (#9963)
- Avoid CustomCommand test failure on VS71 (#9963)
- Update release scripts.
- Avoid CustomCommand test failure on VS71 (#9963)
- Honor MAKECOMMAND value saved in cache (#11026)
- New USE_FOLDERS property OFF by default. (#3796)
-
-David Gobbi (1):
- Set the module prefix, updated Windows suffix.
-
-Eric NOULARD (2):
- InstallGen/CPack fix handling absolute installed file regression
- CPackRPM Handle parenthesis in CPACK_SYSTEM_NAME (fix bug 10737)
-
-James Bigler (2):
- Fix for bug 0011263.
- Allow -g3 for CUDA v3.0+.
-
-Mikkel Krautz (2):
- Xcode: Avoid trailing space in ARCHS list (#11244)
- Xcode: Quote string values containing '$' (#11244)
-
-Philip Lowman (12):
- FindBoost.cmake fixes for issues 11204 & 8529
- FindBoost.cmake: Miscellaneous changes and refactoring
- FindBoost.cmake: Add Boost_NO_SYSTEM_PATHS option
- FindBoost.cmake: Fix compiling against a boost source tree
- FindBoost.cmake: Fixes 11246
- FindBoost.cmake: Fixes 11121
- FindBoost.cmake: Fixes 10436
- FindBoost.cmake: Implements 11160
- Fix 11136: [patch] FindThreads.cmake documents the wrong variable
- FindBoost.cmake: Fix library search path glitch introduced in earlier commit
- FindFLEX.cmake: Fix issue 11249
- Fixes issue 11279: CMakeDetermineVSServicePack support for VS10
-
-Yaakov Selkowitz (2):
- FindFLTK*: Use Cygwin fltk on Cygwin (#11290)
- Use 'uname -m' for processor on Cygwin (#10774)
-
-Changes in CMake 2.8.3-rc1 (since 2.8.2)
-----------------------------------------
-Alex Neundorf (39):
- fix build on SUSE 11.2 in cmcurl due to ssize_t
- -add an additional name for finding libtiff on Windows
- -fix typo in docs of deprecated MacroAddFileDependencies.cmake
- add 2nd, more powerful mode to find_package_handle_standard_args()
- -fix indentation of the documentation
- Add version checking support to FindFlex and FindPerlLibs
- FindSquish doesn't detect the version, remove that from the documentation
- Improved version checking for FindRuby using the new mode of FPHSA()
- Improved version checking for FindJava using the new FPHSA() mode
- Fix DETAILS string with version number in FHPSA()
- Improved version checking for FindSubversion using the new mode of FPHSA()
- Improved version checking for FindCUDA using the new mode of FPHSA
- Use FPHSA() in FindSWIG, including version checking.
- Change documentation of Subversion_FOUND and SUBVERSION_FOUND.
- Add macro CMakeParseArguments() and use it in FPHSA()
- Fix ZLIB version parsing if no TWEAK version exists
- Fix EclipseCDT include path parsing with spaces (#10868)
- Fix EclipseCDT parsing of builtin macros with spaces (#10868)
- Remove trailing spaces
- Detect a COMPILER_ID also for ASM.
- Add timeout to execute_process() in CMAKE_DETERMINE_COMPILER_ID().
- Fix parsing of builtin macros so Eclipse handles them properly (#10868)
- Log the required package version and major improvement to FeatureSummary
- Improve documentation.
- Improve wording of the documentation.
- Add macro ADD_FEATURE_INFO() and improve docs.
- Remove trailing whitespace
- Make target_link_libraries() complain if bad target name is used
- Just warn in case of a bad target as only argument for t_l_l()
- Remove trailing whitespace
- New CMP0016 for deciding whether an unknown target in TLL() is an error.
- Record all considered Config files and their versions.
- Improve error message in Config-mode when no appropriate version was found
- Replace the two vector<string,string> with one vector<struct{string,string}>
- Small cleanup of FindPackageHandleStandardArgs.cmake
- Don't create an empty element at the end of Foo_CONSIDERED_CONFIGS/VERSIONS
- Add option CONFIG_MODE to FPHSA()
- Improve version notice in the generated message
- Improve wording of the error message of find_package() in config-mode
-
-Andrew Maclean (3):
- Adding a FindPostgreSQL.cmake module
- Forgot the copyright notice.
- Changed ADDITIONAL_SEARCH_PATHS to PostgreSQL_ADDITIONAL_SEARCH_PATHS.
-
-Arjen Verweij (1):
- Pass objects to Intel linker using a response file
-
-Bill Hoffman (9):
- Disable gcc 33 on OpenBSD because it crashes CPack by default.
- Fix for bug#10483, INCLUDE_EXTERNAL_MSPROJECT: ProjectGUID now ProjectGuid
- Remove the ctest submit larget output test.
- Let CMake recognize .CPP .CXX and .C++ as c++ files.
- Fix for bug 10388, fix various default flags.
- Only use .CPP .CXX and .C++ do not work by default with g+++.
- Fix targets with . in the name for VS 10 IDE.
- Only test for .CPP on Microsoft compilers which will handle .CPP as c++.
- Allow testing of .CPP on WIN32 as it is a case insensitive OS and should work.
-
-Brad King (69):
- ExternalProject: Add LOG_* options to hide step output
- FindMPI: Do not parse -l in middle of library name
- FindMPI: Parse mpicc flags more carefully (#9093)
- Fix or cast integer conversions in cmake
- Begin post-2.8.2 development
- FindMPI: Failure is not an error if not REQUIRED
- FindMPI: Trust mpicc -showme on BlueGene/L
- VS: Always separate preprocessor defs by semicolon (#10902)
- KWSys: Cleanup putenv leak option implementation
- KWSys: Pass ptrdiff_t check result to System.c
- Fix or cast more integer conversions in cmake
- Use same type in both cases of '?:' operator
- FindMPI: Fix parsing of mpicc -Wl,-L link flags (#9093)
- Fix signed/unsigned comparison warnings in ccmake
- Fix integer conversions in cpack
- bootstrap: Detect known C/C++ compiler toolchains
- KWSys: Use short fallback timeout for Process tests
- KWSys: Optionally suppress consistent test failures
- KWSys: Avoid Clang optimizer bug in testProcess-[45]
- Poison GCC 3.3 on OpenBSD a bit later
- KWSys: Avoid undefined behavior in Process crash tests
- Optionally use system bzip2 library (#10932)
- ctest_update: Abort if Git FETCH_HEAD has no candidates
- ctest_update: Support ".git file" work trees
- ctest_update: Run 'git submodule' at top level
- FindBoost: Search for Boost 1.42
- Add FindLibArchive module (#10923)
- Add option CMAKE_USE_SYSTEM_LIBARCHIVE (#10923)
- Refer to self with CMake_(SOURCE|BINARY)_DIR (#10046)
- ExternalProject: Fix $(MAKE) with cygpath on Windows
- FindBoost: Search for Boost 1.43 and 1.44
- Include headers from chosen libarchive (#10923)
- No response files with GNU ld <= 2.16 (#10913)
- Create class cmArchiveWrite to wrap libarchive (#11020)
- Include entries for directories in tarballs (#11020)
- cmArchiveWrite: Fix signed/unsigned compare/convert
- cmArchiveWrite: Fix signed/unsigned again
- CPack: Avoid member shadowing after API refactor
- KWSys: Fix SplitPath for leading '\' on Windows
- KWSys: Fix GetActualCaseForPath for UNC paths
- ModuleNoticesTest: Do not require "Kitware" copyright
- Modules: Fix CMakeParseArguments copyright notice
- FortranCInterface: Fix doc typo FC.h -> FCMangle.h
- CTest: Avoid use of old EscapeSpaces method
- Remove cmSystemTools::EscapeSpaces method
- Clarify install(TARGETS) docs for EXPORT option
- Factor out global generator ComputeTargetDepends method
- Factor out duplicate VS target dependency code
- Refactor VS <= 7.1 utility-depends workaround
- Restore GetTargetDirectDepends const return
- Split notion of node lists and edge lists
- Distinguish "strong" and "weak" target dependency edges
- Honor strong intra-component target dependencies
- libarchive: Remove SCHILY dev,ino,nlink attributes (#11176)
- Fix unused parameter warning in VS 7.1 generator
- KWSys: Avoid empty string dereference in SplitString
- KWSys: Improve SplitPath method documentation
- KWSys: Use SplitPath in GetActualCaseForPath
- Add whitespace=tab-in-indent attribute for sources
- Search MacPorts /opt/local prefix on Mac
- HP-UX: Always add /usr/lib to rpath (#10571)
- No CMAKE_CONFIGURATION_TYPES in single-config generators (#10202)
- KWSys: Suppress -Wcast-align warning in MD5.c
- Suppress -Wcast-align in curl and bzip2
- libarchive: Fix purposeful crash
- bootstrap: Honor CFLAGS during "make" test (#10545)
- file(DOWNLOAD): Fix error message formatting
- Fix line-too-long style errors
- Report missing source files with context of target
-
-Clinton Stimpson (10):
- Fix performance issue with getting version from zlib.h
- Fix bug 10418 - GetPrerequisites returning "not" as a dependency.
- Fix regression in 5e6634fd77969433a87c150a2fb3f2079131484f for Windows.
- Change Qt4ConfigDependentSettings to use more standard find modules.
- Add cross-compiling support to FindQt4.cmake
- Tweak for cygwin, don't convert : to ;
- Fix some issues with refinding when qmake executable is changed.
- Find correct Qt plugins for cross-compiling.
- Fix mingw/VS warning message with cross compile re-org.
- Make sure moc parameters file goes in binary directory.
-
-David Cole (20):
- CheckSourceTree test: read UpdateCommand from Update.xml.
- Eliminate -Wconversion warnings.
- Detect CMake warnings and errors in build output.
- Activate retry code on any curl submit failure.
- Add another expected output for the failed submit tests.
- ExternalProject: Use $(MAKE) whenever possible.
- Copy Resources in Frameworks during fixup_bundle (#10020)
- Update path to git. dashmacmini2 was "upgraded."
- ExternalProject: Remove 'unknown keyword' warning (#11034)
- Add documentation for CPACK_PROJECT_CONFIG_FILE.
- Add STEP_TARGETS to ExternalProject module.
- Refine formatting for cmake --help-module output.
- Improve documentation of OPTION command.
- Add FOLDER target property, for IDEs (#3796)
- Avoid adding self as prerequisite. (#10417)
- Correct CMAKE_INSTALL_PREFIX value for Win64 apps (#9992)
- Preserve timestamps on files on tar extract.
- Use QUIET to avoid Java status messages.
- VS2010: Honor PROJECT_LABEL target property (#10611)
- VS2010: Set IntDir for utility and global targets.
-
-David Genest (1):
- Honor CMAKE_USER_MAKE_RULES_OVERRIDE in try_compile (#10902)
-
-Eric NOULARD (20):
- CPackRPM:: Replace - with _ in RPM Version (fix bug 0010934)
- Provides default changelog if no file is provided
- CPackRPM:: Quote every filenames in %file section (see bugs 10701,10871,10345)
- CPackRPM:: [partially] support relocatable package
- CPackDEB: merge wrong installed size patch. see bugs 10296 (and 10292)
- CPackDeb optionally generates auto-dependency list part fix of bug 10292
- Proposal for bash-completion support file
- CPack: Refactor API in order to handle multi-file packages
- CPack: Avoid member shadowing after API refactor (part2)
- Improve cmake-completion (install doc, ctest -R completion)
- Add ZIP archive format and LZMA compress support to libarchive-wrapper
- Add XZ compress support to libarchive-wrapper
- Add Compress compress support to libarchive-wrapper
- CPack Backward-compatibly enforce DESTDIR for DEB and RPM
- CPack Enable better handling of absolute installed files
- CPackArchiveGenerator use cmArchiveWrite wrapper
- CPackArchiveGenerator add component supports
- CPackArchiveGenerator improve usability and robustness
- CPack fix broken compilation for CygwinSource generator
- CPack handle symlinks in CPACK_INSTALLED_DIRECTORIES fix for bug5430
-
-James Bigler (1):
- Added CUDA 3.2 directory changes. Disable emulation mode for CUDA 3.1+.
-
-Kai Wasserbäch (1):
- Fix spelling errors reported by Lintian.
-
-Kovarththanan Rajaratnam (4):
- FindZLIB: optimize zlib.h version parsing
- FindCygwin: add new registry entry for Cygwin 1.7 (#10951)
- FindZLIB: use the FPHSA version mode
- FindSubversion: set compatibility variables based on FPHSA()
-
-Marcel Loose (1):
- Issue 10199: Fixed code documentation and now set <prefix>_WC_ROOT
-
-Marcus D. Hanwell (1):
- Bug with default library type of Python modules.
-
-Mathieu Malaterre (3):
- Add missing PATHS to find_path commands to fix openssl searching
- BUG: 0009611 Fix Arch independent FindJNI.cmake on Linux
- Fix 11035 : debug/release library configuration mistake
-
-Michael Wild (2):
- Improve documentation of BundleUtilities.cmake
- Improve documentation of GetPrerequisites.cmake
-
-Miguel A. Figueroa-Villanueva (7):
- ENH: #9775 Added support for new wxWidgets 2.9 libraries.
- BUG: #9775 Fixed patch FindwxWidgets-fixed-bug-9775.
- BUG #10658: FindwxWidgets USE_FILE should not include .cmake extension.
- STYLE: Clarified/Fixed documentation of UsewxWidgets.
- BUG #11123: Generic include dir should come after config specific one.
- BUG #8184: Fixed FindwxWidgets wrong order of default libs for MinGW.
- ENH #8993: FindwxWidgets add support for wx-config custom options.
-
-Mike McQuaid (1):
- Make bundle items writable before fixup (#9284)
-
-Modestas Vainius (1):
- CTestTestFailedSubmit-xmlrpc: Pass with "Submission problem"
-
-Patrick Gansterer (4):
- VS: Convert PlatformName member to a virtual method
- VS: Add more TargetMachine option values
- VS: Map /ENTRY linker option to EntryPointSymbol
- VS: Add ArchitectureId to VS 8 and 9 generators
-
-Philip Lowman (7):
- Fixes problem finding libraries under Boost (#9510)
- Add detection for new pangommconfig.h header file
- Several fixes needed to improve Windows support
- 11041: Improve FindCxxTest to use Python or Perl automatically; custom flags
- 10241: FindBISON.cmake clears wrong variable
- 10688: FindGTK2.cmake doesn't auto-detect macports
- Merge patch for detecting gdk-pixbuf library
-
-Pino Toscano (1):
- GNU/Hurd platform support fixes (#9873)
-
-Robert Goulet (1):
- VS2010: Disable PDBs when there is no debug info
-
-Rolf Eike Beer (2):
- clean up some stuff in CPack RPM script
- Set MSVC_VERSION for MSVC 6, 7, 7.1 (#7944)
-
-Todd Gamblin (3):
- Modules: Fix spelling 'To distributed' -> 'To distribute'
- Teach find_* commands to ignore some paths
- Add platform files for BlueGene/P systems
-
-Zach Mullen (12):
- Checksums on CTest submit files, and retry timed out submissions.
- Cross-platform fixes for checksum/retry code
- Fix subscript out of range crash
- CTest should resubmit in the checksum failed case
- Testing for CTest checksum
- Mock checksum failure output for old CDash versions
- Checksum test should use CMAKE_TESTS_CDASH_SERVER
- Fix cycle detection for test dependencies
- More robust cost-based scheduling impl
- Fix hard-coded CDash URI in version query
- Added CTest command --print-labels
- We shouldn't ask CDash for its version info until/unless we actually need it.
-
-No changes in CMake 2.8.2 since 2.8.2-rc4.
-
-Changes in CMake 2.8.2-rc4 (since 2.8.2-rc3)
---------------------------------------------
-Bill Hoffman (1):
- Fix for bug #10859, ctest exit exception incorrectly reported.
-
-Brad King (3):
- Run CMake.HTML test without net access (#10857)
- Run CMake.HTML test with older xmllint (#10857)
- CTest: Parse empty Git commits correctly
-
-David Cole (2):
- Qualify name of extraction location with ExternalProject name.
- For VS10: Really use full path file names.
-
-James Bigler (1):
- Add support for the emulation version of the cudart library.
-
-Mathieu Malaterre (1):
- Cleanup FindOpenSSL. Add support for win64 installation.
-
-Zach Mullen (1):
- Parallel CTest hangs if serial test has depends
-
-Changes in CMake 2.8.2-rc3 (since 2.8.2-rc2)
---------------------------------------------
-Brad King (1):
- Preserve ENV{MAKEFLAGS} in CMake script mode
-
-David Cole (4):
- Remove "Microsoft Visual Studio .NET" from VS8 and VS9 find modules.
- Use full path file names in generate.stamp.list.
- Use full path file names to express dependencies.
- Look in the ctest ini file for GitCommand.
-
-James Bigler (2):
- Fixed: CUDA_VERSION_MAJOR/MINOR now computed after first run.
- CUDA_VERSION variable passed to REGEX needs quotes to work when not defined.
-
-Mathieu Malaterre (1):
- Cleanup FindDCMTK (using foreach). Fix linking on win32 static libs.
-
-Zach Mullen (2):
- Do not exit if stoptime is passed.
- Document ctest_build() TARGET option
-
-Changes in CMake 2.8.2-rc2 (since 2.8.2-rc1)
---------------------------------------------
-
-Bill Hoffman (1):
- Make sure libarchive uses cmzlib and not the system libz if found.
-
-Brad King (12):
- Use forward slashes for objects in response files
- Use platform variable for response file flag
- Use response file for objects on MinGW and MSYS
- Generalize CTest.Update* test dashboard script helpers
- ctest_update: Support custom Git update command
- ctest_update: Support Git upstream branch rewrites
- Fix CMake data and doc paths in Cygwin package
- Document scope of source file properties
- Run CTest.NoNewline test using built CMake
- Tru64: Place cmOStringStream vtable uniquely (#10541)
- Enable BootstrapTest on MSYS
- Tru64: Use full-path include directives in Makefiles (#10569)
-
-Christoph Watzl (1):
- Fix nested source groups with VS 10 (#9863)
-
-Clinton Stimpson (2):
- Support pthreads on irix.
- Remove macro for querying qmake for qmake variables.
-
-David Cole (2):
- Fix issue #10346. Error if SOURCE_DIR is empty.
- Remove CTestTest3.
-
-Zach Mullen (1):
- Extra coverage glob should subtract the explicitly defined excluded files
-
-Changes in CMake 2.8.2-rc1 (since 2.8.1):
-- Build on Tru64 (#10542)
-- Build on mingw-w64
-- Build on old Sun (#10550, #10543)
-- CPack: Add native BZip2 support
-- CPack: Set compression type in RPM spec (#10363)
-- CPack: Try harder to initialize staging directory (#10793)
-- CTest: Add --stop-time argument
-- CTest: Cost data with '-j'
-- CTest: Fix memory report
-- CTest: Glob for uncovered files during coverage tests
-- CTest: Option to specify cdash server
-- CTest: PHP Coverage support
-- CTest: Process tree kill for OpenBSD, FreeBSD, kFreeBSD, GNU/Hurd
-- CTest: Report failure in Update.xml
-- CTest: Submit author email in Update.xml
-- CTest: Teach ctest_update about Git submodules
-- CTest: Teach ctest_update to handle Git upstream branch rewrites
-- Cygwin: Export all symbols with ENABLE_EXPORTS (#10122)
-- Do not list file names during 'cmake -E tar xz'
-- Documentation: Comply with "XHTML 1.0 Strict"
-- Documentation: Fix typo in CMAKE_LIBRARY_PATH (#10291)
-- Documentation: Fix typo in HAS_CXX docs (#10578)
-- Documentation: More consistent command signatures
-- Eclipse: Do not add INCLUDE to environment twice
-- Enable extra CodeBlocks generator on Cygwin
-- ExternalProject: Support .zip and .bz2 archives, MD5 verification
-- ExternalProject: Reconfigure when args change (#10258)
-- ExternalProject: Support Git, SVN username/password
-- FindCurses: Fix for cygwin ncurses package
-- FindHSPELL: Version support
-- FindJava: Error if version is not found only when REQUIRED
-- FindJava: Support runtime and development components (#9840)
-- FindKDE4: Prefer kdeconfig results over system paths
-- FindMPEG: Check for 'vo' library
-- FindPNG: Support png 1.4 versioned lib names (#10551)
-- FindPkgConfig: Add QUIET keyword to pkgconfig macros (see #10469)
-- FindZLIB: GnuWin32 support, version support (#5588)
-- FindwxWidget: Fix CXX flag parsing (#10209)
-- Fix .pdb name attribute in VS project files (#10614)
-- Fix CodeBlocks to work with Fortran-only
-- Fix VS 2010 custom commands (#10503)
-- Fix VS 6 support for COMPILE_DEFINITIONS_MINSIZEREL (#10700)
-- Fix cross-compiling from Linux to iPhone (#10526)
-- Fix documentation typos
-- Fix g95 Fortran compiler support
-- Fix uname masking in file(WRITE) and write_file (#10789)
-- GetPrerequisites: Provide an override hook
-- Handle non-ASCII terminators in file(STRINGS)
-- Module fixes: FindPythonLibs, FindQt4, FindX11, FindwxWidgets
-- PathScale Fortran compiler tool detection
-- Qt4 OpenGL framework fix
-- Qt4ConfigDependentSettings.cmake Qt4Macros.cmake UseQt4.cmake
-- Recognize ARM ABI/EABI with GNU compilers
-- Recognize Clang compiler
-- Search basic directories on "Generic" platform
-- Set MSVC* variables consistently on all generators, and test
-- Support SunPro C++ 5.11 on Linux (new compiler)
-- Support VS 10 Express (related to #10670)
-- Support compression with 'cmake -E tar'
-- Support multiple arguments in CC,CXX,FC environment variables
-- Support per-configuration librarian flags (#10768)
-- Support per-platform initial ASM language flags (#10577)
-- Use Fortran ABI detection results conservatively
-- Use libarchive to replace the unmaintained libtar
-- UseQt4: Support QtMultimedia (#10675)
-- bootstrap: Fix make tool detection (#10544)
-- cmake-gui: Add simple grouped view
-- cmake-gui: Support build tree under symlink (#9975)
-- Cleanup modules FindASPELL, FindAVIFile, FindBZip2, FindDart,
- FindEXPAT, FindGCCXML, FindGLU, FindHSPELL, FindJasper, FindLibXml2,
- FindLibXslt, FindMPEG, FindOpenAL, FindPhysFS, FindQuickTime,
- FindSubversion, FindZLIB.
-
-Changes in CMake 2.8.1
-- Fix failing test on cygwin
-- Add a new serach path for MPICH2
-
-Changes in CMake 2.8.1 RC 5
-- Fix FindQt4 to work with OpenGL on the mac
-- Add .git .bzr and .hg to the list of default CPack ignore directories.
-
-Changes in CMake 2.8.1 RC 4
-- CTest: Do not hide test GUI windows (fixes 2.8.0 regression)
-- Documentation: Clarify CMAKE_MODULE_PATH variable
-- FindQt4: Add support for QtDeclartive module
-- FortranCInterface: Fix PathScale detection
-- Suppress GNU flag -fPIC on Windows (fixes 2.8.1-rc1 regression)
-
-Changes in CMake 2.8.1 RC 3
-- Add CMAKE_XCODE_ATTRIBUTE_<attr> interface to set compiler (#9125)
-- Fix Eclipse files for targets in subdirectories (#9978)
-- Fix custom command rule hashes to avoid extra rebuilds
-- Print non-make generator name in initial compiler test
-
-Changes in CMake 2.8.1 RC 2
-- CPack: Avoid deleting long PATH values with NSIS (#10257)
-- CTest: Fix and test cost-based test scheduler
-- CTest: Fix and test git updates for case of out-dated index
-- CTest: Fix regression caused by fix for (#2336) in rc1
-- CTest: Setup command-line dashboard support with Git
-- FindCUDA: Improve docs, use -rpath on Apple, fix dependency scanning
-- Fix OS X deployment-target and sysroot defaults (#9959,#9898,#10155)
-- Recognize the Compaq Fortran compiler
-
-Changes in CMake 2.8.1 RC 1
-- Add "NMake Makefiles JOM" generator
-- Add PathScale compiler support
-- Add per-configuration OUTPUT_DIRECTORY properties
-- Add per-target OSX_ARCHITECTURES property
-- check_type_size(): Handle mixed-size universal binaries
-- CPack: Document Mac generators
-- CPack: Improve RPM spec files
-- Create CMAKE_FORCE_Fortran_COMPILER for cross-compiling
-- CTest: Add --http1.0 command-line option
-- CTest: Add --timeout command-line option
-- CTest: Do not munge UTF-8 output in XML files
-- CTest: Document CTEST_USE_LAUNCHERS option
-- CTest: Fix killing of whole test process trees
-- CTest: Handle failure of running invalid executables
-- CTest: Honor the -C arg to ctest (#2336)
-- CTest: Improve host system introspection
-- CTest: Optionally randomize test order (--schedule-random)
-- CTest: Skip tests with unsatisfied REQUIRED_FILES test property
-- CTest: Submit arbitrary results with ATTACHED_FILES test property
-- ctest_build(): Enhance signature
-- ctest_start(): Add APPEND option
-- ctest_start(): Move CTEST_CHECKOUT_COMMAND from ctest_update
-- ctest_update(): Submit global tree revision in Update.xml
-- Cygwin: Do not export all symbols from DLLs (#10122)
-- Cygwin: Name DLLs with SOVERSION, not VERSION (#10122)
-- Detect 32/64-bit Windows with Intel compiler
-- Eclipse generator enhancements
-- ExternalProject: Add TIMEOUT parameter
-- FindCUDA: Respect CUDA version differences
-- FindCURL: Find import libraries on Windows
-- FindDCMTK: Look in more places
-- FindGTest: Handle spaces better (#10065)
-- FindGTK2: Look in fink locations on Mac OS X
-- FindHDF5: Follow find-module API conventions
-- FindJava: Support for versioned find
-- FindJNI: Honor find_package() REQUIRED and QUIET options
-- FindMPI: Improve Windows support
-- FindOpenSSL: Fix MinGW support
-- FindPythonLibs: Look in config for static library
-- FindQt4: Misc enhancements, sync with KDE vesion
-- FindRuby: Fix version convention on Windows
-- FindX11: Improve documentation
-- Fortran: Detect address size (#10119)
-- FortranCInterface: Honor user flags
-- Improve VS 2010 beta2 support
-- link_directories(): Treat relative paths consistently (CMP0015)
-- Modernize FindLibXslt and FindLibXml.cmake
-- Refactor platform info to simplify adding new compilers
-- Support cross-compiling versioned DLLs
-- UseQt4: Provide dependencies only for static Qt (#10021)
-- Address issues:
- #2336, #3571, #5041, #7541, #8725, #9011, #9042, #9054, #9163,
- #9171, #9450, #9697, #9764, #9782, #9792, #9862, #9894, #9913,
- #9916, #9917, #9918, #9949, #9965, #9970, #9982, #9985, #10003,
- #10014, #10021, #10032, #10055, #10060, #10065, #10114, #10119,
- #10122, #10126, #10136.
-
-Changes in CMake 2.8.0 Release
-- CPack: Honor CPACK_NSIS_DISPLAY_NAME (fixes regression)
-
-Changes in CMake 2.8.0 RC 7
-- Partially sync FindQt4 with KDE version
-- Improve implementation of fix for #9090
-- Fix CTest infinite loop when test executable could not be found
-- Fix #9833: Document ctest --help-command
-- FindCUDA: Fix -fPIC from being used on executable object files
-- Fix #9654: %files section in spec file should not list directories
-- Fix #9851: Better STRING(RANDOM) seeding
-- Fix double bootstrap build for in source builds
-- Fix CTest to use allowed value for valgrind --num-callers
-- Remove non-language implicit link dependencies
-- Implement LINK_FLAGS_<CONFIG> property on Xcode
-
-Changes in CMake 2.8.0 RC 6
-- Partially sync FindQt4 with KDE version
-- Fix #9090: Teach CTest subdirs() command to handle absolute paths
-- Fix CTest bug that could start a test twice
-
-Changes in CMake 2.8.0 RC 5
-- CTest now detects cycles in test dependency graph
-- Warn on set(PARENT_SCOPE) at top scope
-- Fix Xcode <= 2.0 projects with CMAKE_BUILD_TYPE
-- Fix flags for Intel Fortran on Windows
-- Fix #2199: UseSWIG documentation for swig_generated_file_fullname
-- Fix #7915: UseSWIG interaction with JNI
-- Fix #8971: FindOpenSSL now works on windows
-- Fix #9124: CPackDeb documentation
-- Fix #9722: cmake-gui reports error when not able to create build directory
-- Fix #9767: Match more valgrind-reported leaks in CTest memcheck
-- Fix #9777: Sync CMakeDetermineJavaCompiler paths with FindJava
-- Fix #9793: FindJNI should find matching jni.h and jni_md.h
-- Fix #9817: FindJNI on Solaris
-- Fix FindHDF5 when hdf5.h exists without H5pubconf.h
-- Fix FindZLIB to follow variable name conventions
-- Fix invalid use of auto_ptr on array
-- Mention temp var convention in Modules/readme.txt documentation
-
-Changes in CMake 2.8.0 RC 4
-- Fix try_compile when file cannot be found
-- Add new module to test manifest installation issues on windows.
-- Add more test coverage
--Improvements in finding MPI on windows. ENH: reorganized searching mpi for mpi components (include,lib,bin) using a single set of search paths instead of seperately mainted lists of paths for each.
-- Look for nvcc in the 32 bit bin directory before the 64 bin directory.
-- BUG: hardcore some values so output matches cmVS10CLFlagTable.h (addresses bug #9753)
-- Avoid Intel linker crash in BuildDepends test
-- Fix Intel Fortran SHARED libraries on Linux
-- Fix working dir issue for ctest
-- Fix if() command and CMP0012 OLD/NEW behavior
-- Allow for /D to change install directory on the command line for NSIS
-- Move SetErrorMode around calls to generate and configure instead of setting it for the whole application for cmake-gui on windows. Allows for bad installs of windows shell programs to not break file completion.
-- Fix Intel and MinGW Fortran DLL import libraries
-- Fix Xcode dylib version default
-- Fix the showing of non-cpp files in the IDE for VS 10
-- Fix optionally-valued booleans in VS 10 flag table
-- Detect and set Unicode character set in VS 10
-- Add support for the g95 Fortran compiler
-- Test all target types in Fortran
-- Add Xcode file association for Fortran
-- Fix VS 10 flag table for precompiled headers
-- Fix VS 10 .sln files for Windows Explorer
-- Fix Microsoft.Cpp.$(Platform).user.props in VS10b2
-- Fix up file(DOWNLOAD ) a bit, better error checking and uses of long not double for timeout as curl needs, bug# 9748
-- Add a VS 10 Win64 generator
-- Fix for bug#9686 convert java_home to a cmake path before using.
-- fix for bug# 9751, add check for MSVC10
-- Fix for bugs #9756, #9690 and #9755, header files were not included, and link_directories we incorrect
-- Add a module to test an install tree to verify that the MS CRT version is correct.
-- Fix seg fault for empty ENV{} call bug #9747
-- Better fix for finding the MSBuild that matches the VS 10 install.
-- make testing the CodeBlocks and Eclipse generators easier by not requiring the CMAKE_EDIT_COMMAND variable
-- Do not link library dependencies in VS solutions
-- Ctest was broken for subdirs. Restored working directory state for tests so that their executables could be found.
-- Fixes version detection using osg/Version on Mac OSX when OSG is installed as a framework
-- Avoid C++ linker language in VS Fortran project
-- Avoid duplicate ZERO_CHECK in VS solutions
-- Fixed bug 8319, search for the Python shared library in the standard locations.
-- Fix bug#9714, should not crash when version file is not where it should be...
-- Fix ctest output alignment for cases where total tests run is not the same width as max test index.
-- make it more robust wrt. #9621
-- Add another possible error message that curl might emit with an empty drop location.
-- Fix issue #5668 - use CollapseFullPath when determining if covered file is within source or binary tree. Allows gcc/gcov coverage analysis using MinGW on Windows.
-- CTest-side support for compiler name and compiler version information. Requires CDash update to show on CDash.
-- Add a bunch more testing coverage.
-
-Changes in CMake 2.8.0 RC 3
-- CTest Added OS Platform (cpu architecture) detection support to windows system
-- Several minor FindBoost changes to address posts on mailing list
-- Resolve #9685: Fix include dir to be correct path for gnutils
-- Fix color check for dependency scanning
-- Remove CMP00015 for now as it breaks more things than it fixes
-- Reduce duration of ctest_sleep arguments. Add SmallAndFast project. Replace kwsys with SmallAndFast to make CTestTest faster. (I will keep an eye on coverage results after this commit and make sure we still have equivalent ctest coverage.)
-- Do not use -fPIC to link executables
-- Split Borland compiler information files
-- Trimmed off the newline from sw_vers output on mac, it could cause xml parsing errors if left in
-- Check for openssl-linked option with Qt 4.4+ before making ssl a dependency.
-- Make Complex test of CMakeLib more optional
-- Modernize FindVTK module
-- Fix find_package() when <pkg>_DIR is wrong
-- Do not collapse path of NOTFOUND values
-- More robust implicit link line detection regex
-- fix Xcode 30 generator
-- Use the correct CMake (the freshly built one) to drive the CMakeWizardTest.
-- Support more special characters in file(STRINGS)
-- Log implicit link line detection regex
-- speedup C dependency scanning even more
-- Avoid non-root copies of root-only targets
-- Added better OS information for Mac OS X
-- Use work-around from bug 4772 for C++ and Fortran
-- FortranCInterface: Mangling for Intel on Windows
-- cmake-gui don't allow consecutive generates without a configure.
-- Fix Preprocess test for Intel on Windows
-- Teach intel compiler on windows to place .lib files and .pdb files.
-- CPack: Fix bash-isms in launch script
-- BUG: #0009648 Change "The following tests FAILED" message to print on stdout rather than stderr
-- Avoid (Unix|Windows)Paths.cmake multiple include
-- When getting include dirs for moc, also watch for framework includes and use -F instead of -I.
-- Find locally installed software first
-- Add '#!/bin/sh' to cygwin-package.sh
-- Fix permsissions of installed SquishRunTestCase.sh
-- Fix module docs to be manpage (groff) friendly
-- Support GNU/kFreeBSD
-- Remove old Encoding field from CMake.desktop
-- FindQt3: Prefer (moc|uic)-qt3 names over (moc|uic)
-- Match width of ctest "Start xx: " line to line up with the end test line
-- Remove old license from FindPkgConfig.cmake module
-- Test target link information invalidation
-- Invalidate target link info when necessary
-- Use new style header generation and get rid of OBJECT_DEPENDS in tutorial
-- Fix issue #8649 - move the location of CPACK_NSIS_EXTRA_INSTALL_COMMANDS so that it is not excluded from execution when 'Do not create shortcuts' is checked.
-- add the additional features for the dbus macros from KDE's FindQt4.cmake
-fc9f7a5 Fix warnings in CMake source code.
-- Correct some typos in error messages in the string command. Add a test that covers more of the code implemented in cmStringCommand.cxx, especially the error handlers.
-- Create INTERPROCEDURAL_OPTIMIZATION build feature
-- Document CMAKE_CURRENT_LIST_FILE more precisely
-- Fix the documentation to say what it really does. Bug #9638
-- document how the minimum version can be specified
-- Fix warnings in CMake source code. Suppress rampant warnings emanating from Qt files.
-- Add documentation for Cocoa flag and move Motif under X11 flag.
-
-Changes in CMake 2.8.0 RC 2
-- Fix FindQt4 so that QtHelp depends on QtNetwork
-- Add missing copyright notice to CMake.cmake module
-- Add alternative _UTILITY targets to all VS solutions
-- FindGTest.cmake some bugfixes, also added public function for closer integration btwn GoogleTest & CTest, contributed by Dan Blezek.
-- Eliminate ExternalProject's use of CMAKE_CFG_INTDIR subdir for Makefile generators. It was causing problems with parallel make -j invocations. Keep it for multi-configuration build systems so that Debug and Release stamp files remain separate.
-- Fix for bug #9611, some more paths for OpenJDK.
-- Fix get_filename_component() registry view with wow64
-- Fix warnings in CMake source code.
-- Fix module definition file reference for VS6 NMake
-- Fix for bug #9611 do not hard code archs for search paths of java, look at the machine type.
-- Fix bug#9619 add a link to module maintainers page in readme.txt for Modules
-- Add cmake-help-command function to emacs-mode
-- Add initial XL C compiler flags for safer builds
-- Split XL compiler information files
-- Fix default install prefix on Haiku
-- Fix use of module .def files for MS tools
-- Add StringProperty options includeing /def: for VS 10 flag table
-- Convert copyright to OSI BSD and clean up licenses
-- ENH: Added ctest test coverage for a test timeout
-- CTest honors test timeouts again.
-- Remove ctest_submit from CTestTestParallel
-- Fix shared library creation flag for XL on Linux
-- Fix BUG: 0009612: --output-on-failure option doesn't work with
- the new parallel CTest handler
-- Removed support for cutil library and header file.
-- Fixed CUDA_PROPAGATE_HOST_FLAGS, added path for Mac SDK.
-- Make sure LINK_FLAGS are seen by generator, fix for part of bug#9613
-- Fix issue #9412 - remove RPATH from files copied by
- BundleUtilities.cmake on Linux. Thank
-- Fix support for OLD behavior of policy CMP0002
-- Fix issue #8818 - escape quotes in the license file when using the
- DragNDrop cpack genera
-- Fix .vfproj file version for Intel Fortran 10.1
-- Use BeAPI for per-user package registry on Haiku
-- Correct comments and use ASM${ASM_DIALECT} env. var instead of ASM
- env. var to initialize
-- Fix bug #9529.
-- Fix Windows GUI implib and image version in VS 6
-- Convert newlines from CRLF to LF
-- Oops. Last commit did not create subdir before doing a touch on a
- file in it. So it fails of a type that is expected to have a
- location...
-- Policies 14 and 15 will be first released in 2.8.0
-- Document full version number with policy default
-- Simplify bootstrap script source dir detection
-- Documentation fixes, new CUDA_PROPAGATE_HOST_FLAGS, changed output
- directory.
-
-Changes in CMake 2.8.0 RC 1
-
-- Qt based GUI cmake-gui is now the default GUI, MFC CMakeSetup is no
- longer included in CMake. ccmake is still supported.
-- cmake-gui supports multi-state values options.
-- CMake now has cmake --build command that can build any CMake generated
- project from the command line.
-- Visual Studio 2010 beta support has been added.
-- KDevelop generator now has color output for builds.
-- CTest supports running tests in parallel with a -j N option.
-- A new CTest CTEST_USE_LAUNCHERS option can be used to get better
- dashboard error reports with make based tools.
-- CTest has support for sub-projects and labels which can interact
- with CDash.
-- CTest now supports Git, Mercurial, and Bazaar.
-- It is now possible to use DESTDIR in CPack for any CMake based projects
- giving more flexibility on the final path names.
-- The CPack Deb generator now computes the arch instead of hard coding it.
-- Fortran/C mixed language projects made much easier. CMake now
- automatically can compute the run time libraries for a compiler. In
- addition, a new FortranCInterface module can determine the correct
- name mangling needed to mix C and Fortran.
-- Intel compiler support added to OSX, and support for embedded
- manifests in the windows intel compiler was added.
-- Depend scanning is now much faster with makefiles.
-- Many FindQt4 improvements to stay working with current Qt releases
-- FindMPI has improvements for windows.
-- FindBoost has been updated to work with the most recent boost releases.
-- New External Project Module. The 'ExternalProject_Add' function
- creates a custom target to drive download, update/patch, configure,
- build, install and test steps of an external project.
-- xmlrpc dependancy has been removed
-- CMAKE_OSX_DEPLOYMENT_TARGET cache variable has been created to set the
- deployment OS for a build on OSX.
-- Several new policies were added:
- CMP0012
- The if() command can recognize named boolean constants.
- CMP0013
- Duplicate binary directories are not allowed.
- CMP0014
- Input directories must have CMakeLists.txt.
- CMP0015
- The set() CACHE mode and option() command make the cache value
- visible.
-- Lots of bug fixes.
diff --git a/ChangeLog.txt b/ChangeLog.txt
deleted file mode 100644
index 81b90e0c6..000000000
--- a/ChangeLog.txt
+++ /dev/null
@@ -1,86670 +0,0 @@
-2009-09-23 14:13 zach.mullen
-
- * Tests/CMakeLists.txt: Uncommented the dependency of
- CTestTestNoExe on CTestTestNoBuild so that it will work in
- parallel now.
-
-2009-09-23 14:10 king
-
- * Source/cmGlobalXCodeGenerator.cxx: Add Xcode SYMROOT setting for
- custom targets
-
- Xcode 1.5 writes helper scripts at the projectDirPath location
- for targets that do not set SYMROOT. We now add SYMROOT to
- custom targets so that all targets set it. This prevents Xcode
- 1.5 from touching the source directory now that we always set
- projectDirPath.
-
- See issue #8481.
-
-2009-09-23 14:07 zach.mullen
-
- * Tests/CTestTestParallel/lockFile.c: Make portable c for Parallel
- test
-
-2009-09-23 14:01 alex
-
- * Source/: cmDepends.cxx, cmDepends.h, cmDependsC.cxx,
- cmDependsC.h, cmDependsJava.cxx, cmDependsJava.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: Major optimization of C/C++
- dependency scanning.
-
- Now only the dependencies for the file where the dependencies
- actually may have changed are rescanned, before that this was
- done for all source files even if only one source file had
- changed. This reduces e.g. on my machine the time for scanning
- the dependencies of kdelibs/khtml/ when only one file
- (khtml_global.cpp) has changed from around 7.5 seconds to 1.2
- seconds.
-
- The tests succeed, it does what I expected it to do on kdelibs,
- and Brad also reviewed the patch, so I think it should be ok.
-
- Alex
-
-2009-09-23 13:09 clinton
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, QCMakeCacheView.cxx,
- QCMakeCacheView.h: fix compile warnings
-
-2009-09-23 12:46 hoffman
-
- * Utilities/Release/: magrathea_release.cmake, release_cmake.cmake:
- Handle older cvs clients that do not allow for the password to be
- in the CVSROOT.
-
-2009-09-23 12:45 hoffman
-
- * Tests/CMakeLists.txt: Add nightly builds for linux windows and
- mac.
-
-2009-09-23 11:38 zach.mullen
-
- * Tests/: CMakeLists.txt, CTestTestParallel/CMakeLists.txt,
- CTestTestParallel/lockFile.c, CTestTestParallel/lockFile.cxx: Set
- new ctest tests to always run, whether CTEST_TEST_CTEST is
- enabled or not. Changed parallel test to be portable.
-
-2009-09-23 10:45 king
-
- * Source/kwsys/SystemTools.cxx: Fix KWSys SystemTools build on
- cygwin with -mwin32
-
- Commit "Optimize KWSys SystemTools::FileExists on Windows"
- accidentally added "#undef _WIN32" when including <windows.h> on
- cygwin, which breaks builds using the -mwin32 flag. This commit
- removes that line and fixes the real error it was intended to
- avoid.
-
-2009-09-23 09:00 zach.mullen
-
- * Tests/CTestTestParallel/test.cmake.in: CTestTestParallel now
- submits to public dashboard for easier debugging
-
-2009-09-23 08:48 king
-
- * Source/cmDocumentVariables.cxx,
- Source/cmGlobalXCodeGenerator.cxx,
- Source/cmGlobalXCodeGenerator.h,
- Tests/SystemInformation/SystemInformation.in: Teach Xcode
- generator to set XCODE_VERSION
-
- We set the variable 'XCODE_VERSION' in the CMake language to the
- Xcode version string (e.g. "3.1.2"). Platform config files may
- use it later.
-
-2009-09-23 01:01 bigler
-
- * Modules/FindCUDA.cmake: Updated formatting of documentation plus
- a little reorganization.
-
-2009-09-23 00:50 bigler
-
- * Modules/FindCUDA/run_nvcc.cmake: Added a command to make the
- output directory. This is to fix the XCode build that uses a
- different output directory than other systems, and rather than
- try to match that we'll just make it.
-
-2009-09-23 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-09-22 18:44 clinton
-
- * Modules/FindQt4.cmake: add support for finding
- qcollectiongenerator executable. fixes #9248.
-
-2009-09-22 18:29 clinton
-
- * Source/QtDialog/: CMakeSetup.cxx, CMakeSetupDialog.cxx: fix issue
- 9346. add binary directory to window title to make it easier to
- deal with multiple cmake-gui instances
-
-2009-09-22 17:08 hoffman
-
- * Utilities/Release/dash2win64_release.cmake: new windows build
- machine for cmake
-
-2009-09-22 17:07 hoffman
-
- * Utilities/Release/vogon_cygwin.cmake: disable svn
-
-2009-09-22 16:28 clinton
-
- * Modules/FindQt4.cmake: Add support for Qt configured with custom
- qtlibinfix (see issue 9571). Also fix CMP 15 warnings.
-
-2009-09-22 16:18 king
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h:
- Fix Xcode project references to the source tree
-
- Xcode project source file references need to always be relative
- to the top of the source tree in order for SCM and debug symbols
- to work right. We must even allow the relative paths to cross
- outside of the top source or build directories.
-
- For subdirectory project() command Xcode projects we use the
- source directory containing the project() command as the top.
- Relative paths are generated accordingly for each subproject.
-
- See issue #8481.
-
-2009-09-22 16:16 king
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h: Optionally
- force conversion to relative path
-
- In cmLocalGenerator::ConvertToRelativePath we normally convert to
- relative path only if the local and remote paths both lie inside
- the source tree or both lie inside the build tree. This commit
- adds an optional 'force' argument to allow conversion even when
- this rule is violated.
-
-2009-09-22 16:12 hoffman
-
- * bootstrap: Make sure KWSYS_DO_NOT_CLEAN_PUTENV is defined at
- bootstrap time for cmake in the bootstrap script.
-
-2009-09-22 16:02 king
-
- * Modules/CMakeDetermineCompilerABI.cmake: Skip implicit link info
- for multiple OS X archs
-
- Implicit link information contains architecture-specific
- libraries and directories. The link information cannot be
- explicitly specified safely when CMAKE_OSX_ARCHITECTURES contains
- more than one architecture.
-
- As a result, we currently cannot support mixed-language
- C++/Fortran targets and OS X universal binaries simultaneously.
- In order to avoid conflicts for simple C/C++ cases, we now simply
- skip detection of implicit link information in this case.
-
-2009-09-22 15:58 hoffman
-
- * Source/kwsys/: CMakeLists.txt, Configure.hxx.in: Can not use
- cmakedefine in kwsys because bootstrap of cmake does not support
- it.
-
-2009-09-22 14:56 hoffman
-
- * Source/kwsys/: Configure.hxx.in, SystemTools.cxx: Put a flag in
- that will stop system tools from deleting system environment
- memory on exit, as it can cause gcov to crash the programs.
-
-2009-09-22 14:40 alex
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.cxx: Rescan dependencies also if
- CMakeDirectoryInformation.cmake has changed.
-
- If CMakeDirectoryInformation.cmake is newer than depend.internal
- the include directories may have changed, so dependencies need to
- be scanned again. Ok by Brad.
-
- Alex
-
-2009-09-22 13:02 king
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: Optimize
- KWSys SystemTools::FileExists on Windows
-
- We optimize this method by using the GetFileAttributesExA native
- Windows API to check for file existence when possible. For real
- Windows builds we always use it. For Cygwin we use
- cygwin_conv_to_win32_path to get a native Windows path if
- possible and otherwise fall back to 'access'.
-
- Cygwin-to-Windows path conversion and cache by Wojciech Migda.
- See issue #8826.
-
-2009-09-22 12:05 zach.mullen
-
- * Tests/: CMakeLists.txt, CTestTestParallel/CMakeLists.txt,
- CTestTestParallel/CTestConfig.cmake,
- CTestTestParallel/lockFile.cxx, CTestTestParallel/test.cmake.in:
- Added tests for ctest parallel options (PARALLEL_LEVEL,
- PROCESSORS, RUN_SERIAL)
-
-2009-09-22 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-09-21 23:42 lowman
-
- * Modules/FindBoost.cmake: Make Boost easier to find
-
-2009-09-21 23:07 clinton
-
- * Modules/FindQt4.cmake: Fix issue 9581. Qt 4.5+ needs
- gobject-2.0.
-
-2009-09-21 22:38 lowman
-
- * Modules/: FindCxxTest.cmake, FindGTK2.cmake,
- FindOpenSceneGraph.cmake, FindProtobuf.cmake: Add a blank line to
- my contributed find modules to prevent copyright info from
- showing up in CMake docs
-
-2009-09-21 22:21 lowman
-
- * Modules/FindBoost.cmake: Fix Bug #9158: FindBoost.cmake does not
- work properly with nmake and icl
-
-2009-09-21 17:22 hoffman
-
- * Utilities/Release/release_cmake.sh.in: Use ctest -j to speed up
- tests for release builds.
-
-2009-09-21 17:19 hoffman
-
- * Utilities/Release/release_cmake.cmake: Do not require a cvs login
- for checkout.
-
-2009-09-21 15:29 zach.mullen
-
- * Source/CTest/cmCTestBatchTestHandler.cxx: More SLURM
- experimentation (ctest batch mode)
-
-2009-09-21 15:26 hoffman
-
- * Tests/CMakeLists.txt: For the complex tests since they link to
- the CMake library make sure that they are built with the type of
- build.
-
-2009-09-21 14:58 zach.mullen
-
- * Source/CTest/cmCTestBatchTestHandler.cxx: Fixed a slurm batch
- argument identifier.
-
-2009-09-21 14:21 zach.mullen
-
- * Source/CTest/: cmCTestBatchTestHandler.cxx,
- cmCTestBatchTestHandler.h: Need to quote args when generating
- batch scripts from ctest
-
-2009-09-21 13:40 zach.mullen
-
- * Source/CTest/cmCTestBuildHandler.cxx, Tests/CMakeLists.txt:
- Re-enabled failing tests; fixed ctest_build output to be
- consistent in the error condition across different make programs
- so that these tests would pass.
-
-2009-09-21 13:18 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: Fix Bug #8332, add support for
- .pch files for Xcode.
-
-2009-09-21 13:15 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: Fix Bug #8928, add support for
- .xib files for Xcode.
-
-2009-09-21 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-09-20 23:55 lowman
-
- * Modules/FindProtobuf.cmake: Fix glitch where we were accidently
- unsetting CMAKE_FIND_LIBRARY_PREFIXES
-
-2009-09-20 21:15 lowman
-
- * Modules/FindProtobuf.cmake: Forgot to mark Protobuf cache
- variables as advanced
-
-2009-09-20 20:20 lowman
-
- * Modules/FindALSA.cmake: [NEW Module] FindAlsa audio library
- (Advanced Linux Sound Architecture)
-
-2009-09-20 20:12 lowman
-
- * Modules/FindProtobuf.cmake: [NEW Module] Find and use Google's
- Protocol Buffers library & compiler
-
-2009-09-20 11:33 lowman
-
- * Modules/FindBoost.cmake: Fix boost library detection with Sun
- Studio compiler (Issue #9153)
-
-2009-09-20 09:42 hoffman
-
- * Tests/CMakeLists.txt: Disable test as it fails on every system.
-
-2009-09-20 08:03 lowman
-
- * Modules/FindThreads.cmake: Improve readability
-
-2009-09-20 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-09-19 13:02 alex
-
- * Source/cmDepends.cxx: Minor optimization in dependency checking.
-
- When reading the depend.internal file, check only once for every
- depender whether it exists, instead of repeatedly in a loop for
- each dependee. Within that function it can only change of the
- depender is removed. This is taken care of. This reduces the
- number of access() calls in kdelibs/khtml from 180000 to 90000
- (i.e. 50%), and reduces the time for that (without the actual
- scanning) from 0.3 s to 0.21 s on my system.
-
- Alex
-
-2009-09-19 12:00 king
-
- * Source/: CMakeLists.txt, cmGlobalXCode21Generator.cxx,
- cmGlobalXCode21Generator.h, cmGlobalXCodeGenerator.cxx,
- cmGlobalXCodeGenerator.h: Remove cmGlobalXCode21Generator
- subclass
-
- This subclass of cmGlobalXCodeGenerator only provided two virtual
- method overrides, and it made construction of the Xcode generator
- instance complicated. This commit removes it and replaces the
- virtual methods with tests of the Xcode version. The change
- removes duplicate code.
-
-2009-09-19 10:14 king
-
- * Modules/CMakeCCompiler.cmake.in,
- Modules/CMakeCXXCompiler.cmake.in,
- Modules/Platform/Darwin-GNU-C.cmake,
- Modules/Platform/Darwin-GNU-CXX.cmake,
- Modules/Platform/Darwin-GNU.cmake, Modules/Platform/Darwin.cmake,
- Source/cmLocalGenerator.cxx: Fix check for -isysroot on OS X
-
- Previously we checked for this flag by parsing the version number
- of GCC out of 'gcc --version', but this is not reliable because
- the format can vary greatly. Now we run 'gcc -v --help' and look
- for '-isysroot' in the list of options.
-
- We also now store the result on a per-language basis in the
- per-compiler info file "CMake<LANG>Compiler.cmake". This is
- necessary to make it accessible from try-compile projects so that
- they generate correctly.
-
-2009-09-19 04:33 alex
-
- * Modules/Compiler/: Intel-C.cmake, Intel-CXX.cmake: The
- preprocessing and assembly rules also need the <DEFINES>,
- otherwise different reults are created.
-
- Alex
-
-2009-09-19 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-09-18 15:16 hoffman
-
- * Source/cmLocalGenerator.cxx: Only do the OSX arch stuff on OSX.
-
-2009-09-18 15:01 zach.mullen
-
- * Tests/CMakeLists.txt: Disabling CTestTestNoBuild pending
- investigation of odd g++ output issues.
-
-2009-09-18 14:22 hoffman
-
- * Modules/Platform/Darwin.cmake, Source/cmLocalGenerator.cxx: Add
- detection of gcc versions that do not support isysroot option and
- do not use it for them.
-
-2009-09-18 14:02 zach.mullen
-
- * Tests/CMakeLists.txt: Apparently, on FarAway the presence of
- errors during ctest_build does not cause the calling ctest to
- return an error condition.
-
-2009-09-18 13:34 zach.mullen
-
- * Tests/CMakeLists.txt: Cosmetic change to test CMakeLists
-
-2009-09-18 12:56 david.cole
-
- * Modules/ExternalProject.cmake: Better error message tells user
- possible ways to resolve the error.
-
-2009-09-18 12:16 zach.mullen
-
- * Tests/: CMakeLists.txt, CTestTestCrash/CMakeLists.txt,
- CTestTestCrash/CTestConfig.cmake, CTestTestCrash/crash.cxx,
- CTestTestCrash/test.cmake.in, CTestTestFailure/CMakeLists.txt,
- CTestTestFailure/CTestConfig.cmake, CTestTestFailure/badCode.cxx,
- CTestTestFailure/testNoBuild.cmake.in,
- CTestTestFailure/testNoExe.cmake.in: Added test coverage for
- ctest. Covers WILL_FAIL condition, tests that do not build,
- tests that segfault, and test executable not found (bad command),
- as well as some pass and fail regular expressions.
-
-2009-09-18 10:28 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: Fix the build for version 2.5
- of Xcode.
-
-2009-09-18 09:49 king
-
- * Tests/TryCompile/CMakeLists.txt: Fix CHECK_(C|CXX)_COMPILER_FLAG
- macro test
-
- The flag "-_this_is_not_a_flag_" was not rejected by GCC 4.0 on
- older Mac OS X. We now use "---_this_is_not_a_flag_" instead,
- which will hopefully be rejected by all compilers.
-
-2009-09-18 09:49 king
-
- * Modules/: CheckCCompilerFlag.cmake, CheckCXXCompilerFlag.cmake:
- Fix CHECK_(C|CXX)_COMPILER_FLAG for XL and SunPro
-
- These compilers warn and return 0 for unrecognized flags. We fix
- the compiler flag check macros by looking for a warning in the
- output. We also update the regex for GNU on older Macs. See
- issue #9516.
-
-2009-09-18 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-09-17 17:16 king
-
- * Modules/: CheckCCompilerFlag.cmake, CheckCXXCompilerFlag.cmake:
- Fix CHECK_(C|CXX)_COMPILER_FLAG for HP
-
- This compiler warns and returns 0 for unrecognized flags. We fix
- the compiler flag check macros by looking for a warning in the
- output. See issue #9516.
-
-2009-09-17 16:09 hoffman
-
- * Source/cmLocalGenerator.cxx: Fix case where no archs are found on
- older macs.
-
-2009-09-17 15:33 king
-
- * Tests/TryCompile/CMakeLists.txt: Test CHECK_(C|CXX)_COMPILER_FLAG
- macros
-
- This teaches the TryCompile test to check that the compiler flag
- check macros correctly reject a bad flag. See issue #9516.
-
-2009-09-17 15:32 king
-
- * Modules/: CheckCCompilerFlag.cmake, CheckCXXCompilerFlag.cmake:
- Fix CHECK_(C|CXX)_COMPILER_FLAG for GNU and MSVC
-
- These compilers warn and return 0 for unrecognized flags. We fix
- the compiler flag check macros by looking for a warning in the
- output. See issue #9516.
-
-2009-09-17 15:29 king
-
- * Modules/: CheckCSourceCompiles.cmake,
- CheckCXXSourceCompiles.cmake: Add FAIL_REGEX to
- CHECK_(C|CXX)_SOURCE_COMPILES
-
- This teaches the CHECK_C_SOURCE_COMPILES and
- CHECK_CXX_SOURCE_COMPILES macros to recognize a FAIL_REGEX
- option. If they see the regular expression in the output of the
- test compilation, the check fails.
-
-2009-09-17 15:28 king
-
- * Modules/: CheckCCompilerFlag.cmake, CheckCSourceCompiles.cmake,
- CheckCSourceRuns.cmake, CheckCXXCompilerFlag.cmake,
- CheckCXXSourceCompiles.cmake, CheckCXXSourceRuns.cmake: Cleanup
- generic compiler check macro documentation
-
- This commit improves formatting and style of the documentation
- for the general-purpose compiler check macros:
-
- CHECK_C_COMPILER_FLAG
- CHECK_C_SOURCE_COMPILES
- CHECK_C_SOURCE_RUNS
- CHECK_CXX_COMPILER_FLAG
- CHECK_CXX_SOURCE_COMPILES
- CHECK_CXX_SOURCE_RUNS
-
- This sytle is more consistent with CMake command documentation.
- It also looks nicer in the generated documentation text files.
-
-2009-09-17 13:08 alex
-
- * Modules/CMakeFindEclipseCDT4.cmake: The check for include dirs
- and builtin macros also works with the Intel compiler
-
- Alex
-
-2009-09-17 11:52 hoffman
-
- * Modules/Platform/Darwin.cmake, Source/cmGlobalXCodeGenerator.cxx,
- Source/cmLocalGenerator.cxx: Fix for bug #9466. Change the
- implementation of OSX arch lists. If no ARCHs are specified by
- the user then no flags are set. We no longer use
- CMAKE_OSX_ARCHITECTURES_DEFAULT.
-
-2009-09-17 09:18 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: Bug #9430, recognize
- the FR flag
-
-2009-09-17 08:42 king
-
- * Source/: cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx: Do not call CollapseFullPath for
- PDB file names
-
- Some vendor tools convert PDB file names given on the command
- line to lower-case before creating the file. When CMake places a
- mixed-case PDB file name into the build system, the file does not
- exist the first time and it is written with mixed case. After
- the first build though the native tool has created a lower-case
- version of the file. If CMake does CollapseFullPath again, the
- file exists so the actual-case lookup gets the lower-case name.
- This causes the build files to change so the project rebuilds.
-
- The solution is to avoid calling CollapseFullPath for files
- generated by the build. In the case of PDB files we already
- construct them from paths that have been collapsed, so we can
- just skip the call altogether. See issue #9350.
-
-2009-09-17 08:25 king
-
- * Source/cmMakefile.cxx: Remove old check for duplicate
- subdirectories
-
- In cmMakefile::AddSubDirectory we were checking for addition of
- the same source directory multiple times. However, the check
- code was incorrect because it compared pointers instetad of
- pointed-to strings. Since the check was written, a better check
- was added right after it to enforce unique binary directories (in
- which case duplicate sources are fine). This commit simply
- removes the old-style check code.
-
-2009-09-17 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-09-16 21:02 hoffman
-
- * Source/cmake.cxx: Fix typo in name
-
-2009-09-16 18:01 alex
-
- * Source/: cmExtraEclipseCDT4Generator.h,
- cmExtraEclipseCDT4Generator.cxx,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: Major improvement of the
- generated targets in Eclipse.
-
- Before this change all targets were displayed in the top level
- directory of the project. Now the targets are displayed in the
- correct directory. The targets "clean" and "all" are now created
- in every subdirectory. Also now the targets for just compiling
- one file, preprocessing one file, assembling one file are are
- created for Eclipse. Additionally all targets get a prefix now
- in eclipse, so that they are sorted in a way which makes sense
- (global targets first, then executable and libraries, then object
- files, then preprocessed, then assembly). Also this prefix gives
- the user a hint what the target is, i.e. whether it's a library
- or an executable or something else.
-
- Alex
-
-2009-09-16 15:09 king
-
- * Tests/CMakeTests/: CMakeLists.txt, ConfigureFile-BadArg.cmake,
- ConfigureFile-DirInput.cmake, ConfigureFile-DirOutput.cmake,
- ConfigureFile-Relative.cmake, ConfigureFileTest.cmake.in: Create
- CMake.ConfigureFile test for configure_file
-
- This test checks that configure_file() handles input and output
- file arguments as documented.
-
-2009-09-16 15:09 king
-
- * Source/: cmConfigureFileCommand.cxx, cmConfigureFileCommand.h:
- Teach configure_file to handle directory names
-
- This commit teaches configure_file how to handle directories for
- input and output. It is an error if the input is a directory.
- If the output is a directory we put the configured copy of the
- input file in it with the same name. See issue #9537.
-
-2009-09-16 15:09 king
-
- * Source/: cmConfigureFileCommand.cxx, cmConfigureFileCommand.h:
- Teach configure_file to handle relative paths
-
- The configure_file() command now converts relative output paths
- to full paths using the current binary directory. Input relative
- paths were already converted using the current source directory,
- but this behavior was not previously documented.
-
-2009-09-16 15:09 king
-
- * Source/: cmConfigureFileCommand.cxx, cmConfigureFileCommand.h:
- Fix typo in cmConfigureFileCommand ivar name
-
- Rename 'OuputFile' to 'OutputFile'.
-
-2009-09-16 15:09 king
-
- * Tests/CMakeTests/: CheckCMakeTest.cmake, FileTest.cmake.in:
- Factor out CMake.File test result check for re-use
-
- The CMake.File test runs several scripts through "cmake -P" and
- checks the output and result against known good values. This
- commit factors out the checking code into a separate
- CMakeCheckTest module. The module may be used by new tests.
-
-2009-09-16 14:37 alex
-
- * Source/cmExtraEclipseCDT4Generator.cxx,
- Modules/CMakeFindEclipseCDT4.cmake: Put compiler defined macros
- into eclipse project files
-
- Now gcc is queried also for the builtin definitions, and they are
- then added to the .cproject file. This should make the
- preprocessor highlighting in eclipse work better (#9272) Patch
- mostly from Miguel.
-
- Alex
-
-2009-09-16 14:20 hoffman
-
- * Modules/FindJNI.cmake: Bug #09476, add more search paths for jni.
-
-2009-09-16 12:40 hoffman
-
- * Modules/UsePkgConfig.cmake: Fix for bug#9553, print a warning if
- pkg-config is not found.
-
-2009-09-16 12:33 king
-
- * Modules/Platform/: Linux-VisualAge-CXX.cmake, Linux-XL-CXX.cmake:
- Fix XL C++ compiler flags on Linux
-
- In Platform/Linux.cmake we add GNU flags as default for the
- platform which breaks non-GNU compilers. Later we should
- refactor these flag files to put compiler-specific flags only in
- files loaded for each compiler. Until then this commit fixes the
- XL C++ compiler flags on Linux by erasing the GNU flags. See
- issue #9469.
-
-2009-09-16 11:49 hoffman
-
- * Source/CTest/cmCTestRunTest.cxx: Fix uninitialized errors.
-
-2009-09-16 11:44 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: Generate proper Intel
- Fortran project version
-
- The Intel Visual Fortran compiler plugin for MS Visual Studio may
- be one of several versions of the Intel compiler. This commit
- teaches CMake to detect the plugin version and set the version
- number in .vfproj files. See issue #9169.
-
-2009-09-16 11:44 king
-
- * Source/: cmGlobalVisualStudio10Generator.h,
- cmGlobalVisualStudio6Generator.h,
- cmGlobalVisualStudio71Generator.h,
- cmGlobalVisualStudio7Generator.h,
- cmGlobalVisualStudio8Generator.h,
- cmGlobalVisualStudio9Generator.h,
- cmGlobalVisualStudioGenerator.cxx,
- cmGlobalVisualStudioGenerator.h: Create VS generator
- GetRegistryBase method
-
- This method returns the registry key
-
- HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\<version>
-
- A protected GetIDEVersion method retrieves the version-specific
- part of the key name.
-
-2009-09-16 09:52 king
-
- * Tests/FunctionTest/CMakeLists.txt: Test add_subdirectory inside
- function
-
- This commit teaches the FunctionTest to check variable scope
- behavior when a subdirectory is added inside a function call.
- Any PARENT_SCOPE sets in the subdirectory should affect only the
- function scope which called add_subdirectory and not its parent
- scope.
-
-2009-09-16 09:51 king
-
- * Source/cmMakefile.cxx: Initialize directory scope with closure of
- parent
-
- The commit "Improve dynamic variable scope implementation"
- optimized function scopes using an efficient parent scope
- pointer. However, the parent scope used to initialize a new
- directory might not exist later (like add_subdirectory called
- inside a function of the parent scope). This caused CMake to
- crash when following the dangling pointer to the original parent
- scope.
-
- We fix the problem in this commit by always computing the closure
- of the parent scope at directory initialization time so that no
- parent scope pointer is needed. See issue #9538.
-
-2009-09-16 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-09-15 02:38 bigler
-
- * Modules/: FindCUDA.cmake, FindCUDA/make2cmake.cmake,
- FindCUDA/parse_cubin.cmake, FindCUDA/run_nvcc.cmake: Initial
- version of FindCUDA script. Still needs documentation
- formatting.
-
-2009-09-15 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-09-14 22:16 hoffman
-
- * Source/cmake.cxx: Fix for bug #8969, pick a better default
- version for VS, and make it easier to add new versions of VS to
- look for.
-
-2009-09-14 20:54 hoffman
-
- * Source/cmDocumentationFormatterHTML.cxx: Fix for bug# 5373,
- include CMake verison in generated docs.
-
-2009-09-14 15:53 alex
-
- * Modules/FindPNG.cmake: fix #9152: find ZLIB quietly if PNG is
- searched QUIETLY
-
- Alex
-
-2009-09-14 15:20 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: Bug #8356, add support for
- image types in Xcode files.
-
-2009-09-14 14:59 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: Fix for bug #8807, add support
- for CMAKE_EXE_LINKER_FLAGS_(config) to Xcode generator.
-
-2009-09-14 13:45 hoffman
-
- * Source/: cmake.cxx, kwsys/Glob.cxx, kwsys/Glob.hxx.in: Fix for
- Bug #9190, -U did not work on case insensitive file systems
- because of call to glob convert to regex that expected to work
- with files.
-
-2009-09-14 13:42 hoffman
-
- * Source/cmIfCommand.h: Clarify documentation for if.
-
-2009-09-14 11:23 zach.mullen
-
- * Source/CTest/: cmCTestBatchTestHandler.cxx, cmCTestRunTest.cxx:
- Removed fork-and-continue option from ctest generated batch
- script entries
-
-2009-09-14 10:31 hoffman
-
- * Source/: cmDependsJavaParserHelper.cxx,
- cmDependsJavaParserHelper.h: Fix open solaris build issue with
- concept checking that breaks std vector for a class of itself.
- Bug #9523.
-
-2009-09-14 09:34 hoffman
-
- * Modules/FindPythonLibs.cmake: Change FindPythonLibs to use the
- standard _DIR instead of _PATH but stay backwards compatible
-
-2009-09-14 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-09-13 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-09-12 10:20 king
-
- * Source/CTest/cmProcess.cxx: Avoid shadowing std::vector member
-
- The cmProcess::Buffer class derives from std::vector. We were
- using local variable 'data' in the GetLine method but this name
- shadowed a member of vector with GNU. This renames it to 'text'.
-
-2009-09-12 06:25 alex
-
- * Modules/FindRuby.cmake: major improvement of FindRuby.cmake
-
- -now supports specifying minimum required version -now supports
- ruby 1.8 and 1.9 -uses find_package_handle_standard_args() now
- -fix #6212 and using a lot of ideas from the file attached there
-
- Alex
-
-2009-09-12 04:38 alex
-
- * Modules/FindRuby.cmake: use HINTS instead of PATHS and also look
- for libruby-static.a (which is built by default)
-
- Alex
-
-2009-09-12 02:15 alex
-
- * Modules/CMakeASM-ATTInformation.cmake: Don't pass *.S files to
- the assembler, they must go through gcc, because they must be
- preprocessed
-
- Alex
-
-2009-09-12 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-09-11 17:15 hoffman
-
- * Source/CTest/cmCTestHandlerCommand.cxx: Fix for bug#9442, ctest
- crash if CTEST_SOURCE_DIRECTORY was not set.
-
-2009-09-11 16:39 king
-
- * Tests/CMakeLists.txt: Test that CTest can handle missing newlines
-
- We create test 'CTest.NoNewline' to print output with no newline.
- This tests CTest's ability to handle a missing newline.
-
-2009-09-11 16:20 king
-
- * Source/CTest/cmProcess.cxx: Fix new CTest output handling for no
- newline
-
- When we clear the buffer for an output pipe after returning the
- last partial line (without a newline) we need to set the partial
- line range to empty. Otherwise the buffer object is left in an
- inconsistent state.
-
-2009-09-11 13:34 hoffman
-
- * Source/: cmCTest.cxx, cmCTest.h, ctest.cxx,
- CTest/cmCTestTestHandler.cxx: Add label summary times to ctest
- default output. Also, remove parallel time output. Add flag to
- disable label summary.
-
-2009-09-11 12:26 king
-
- * Source/CTest/: cmCTestMultiProcessHandler.cxx,
- cmCTestRunTest.cxx, cmCTestRunTest.h, cmProcess.cxx, cmProcess.h:
- Rewrite CTest child output handling
-
- This commit fixes cmCTestRunTest and cmProcess to more
- efficiently handle child output. We now use the buffer for each
- child output pipe to hold at most a partial line plus one new
- block of data at a time. All complete lines are scanned
- in-place, and then only the partial line at the end of the buffer
- is moved back to the beginning before appending new data.
-
- We also simplify the cmProcess interface by making
- GetNextOutputLine the only method that needs to be called while
- the process is running. This simplifies cmCTestRunTest so that
- CheckOutput can be called until it returns false when the process
- is done.
-
-2009-09-11 10:09 king
-
- * Source/CTest/: cmCTestMultiProcessHandler.cxx,
- cmCTestRunTest.cxx, cmCTestRunTest.h: Initialize cmCTestRunTest
- instances robustly
-
- All instances of this class need a cmCTestTestHandler, so we now
- require one to construct it. The instance also provides the
- cmCTest instance too.
-
-2009-09-11 10:04 king
-
- * Source/: cmCacheManager.cxx, cmCacheManager.h, cmake.cxx: Remove
- barely-used cmCacheManager::AddCacheEntry
-
- The commit "Remove barely-used cmMakefile::AddCacheDefinition"
- removed all but one use of the cmCacheManager method 'bool'
- overload. This commit removes the other use and the entire
- method, thus reducing code duplication.
-
-2009-09-11 10:03 king
-
- * Source/cmOptionCommand.cxx: Fix option() interpretation of
- non-boolean values
-
- The commit "Remove barely-used cmMakefile::AddCacheDefinition"
- broke option() calls that pass a non-boolean default value. We
- restore the old behavior by always coercing the value to 'ON' or
- 'OFF'.
-
-2009-09-11 08:17 king
-
- * Source/: CPack/cpack.cxx, CTest/cmCTestBuildHandler.cxx,
- CursesDialog/cmCursesMainForm.cxx, cmCMakeMinimumRequired.cxx,
- cmExecuteProcessCommand.cxx, cmFileCommand.cxx,
- cmFindPackageCommand.cxx, cmPolicies.cxx, cmSetCommand.cxx,
- cmSystemTools.cxx, cmUtilitySourceCommand.cxx: Add parentheses
- around '&&' between '||' for gcc
-
- The GNU compiler warns about possible operator precedence
- mistakes and asks for explicit parentheses (-Wparentheses). We
- add the parentheses to silence the warning. This also fixes one
- real logic error in the find_package() implementation by
- correcting expression evaluation order.
-
-2009-09-11 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-09-10 16:59 king
-
- * Source/: cmMakefile.cxx, cmMakefile.h, cmOptionCommand.cxx,
- cmPolicies.cxx, cmPolicies.h, cmSetCommand.cxx, cmSetCommand.h:
- Create CMake Policy CMP0015 to fix set(CACHE)
-
- The set(CACHE) and option() commands should always expose the
- cache value. Previously we failed to expose the value when it
- was already set if a local variable definition hid it. When set
- to NEW, this policy tells the commands to always remove the local
- variable definition to expose the cache value. See issue #9008.
-
-2009-09-10 16:59 king
-
- * Source/: cmMakefile.cxx, cmMakefile.h, cmOptionCommand.cxx:
- Remove barely-used cmMakefile::AddCacheDefinition
-
- The boolean overload of this method was used only to implement
- option(). We re-implement option() in terms of the main method
- and removes the now-unused signature. This removes some
- duplicate code that had already fallen behind on changes (it was
- not removing the local definition instead of setting it).
-
-2009-09-10 13:49 alex
-
- * Source/: cmExtraEclipseCDT4Generator.cxx,
- cmExtraEclipseCDT4Generator.h: sync target generation with the
- CodeBlocks generator
-
- Basically the code is now a copy of the one from the CodeBlocks
- generator, maybe this could move into a common helper function
- somewhere: -only insert GLOBAL targets from the toplevel
- directory -don't insert the edit_cache target if it calls ccmake,
- since this doesn't work in the output tab of Eclipse -add the
- /fast targets
-
- Alex
-
-2009-09-10 13:44 alex
-
- * Source/cmExtraCodeBlocksGenerator.cxx: As in the Eclipse
- generator: don't insert the edit_cache target if it is ccmake,
- since this doesn't work in the output tab of the IDE
-
-2009-09-10 11:18 zach.mullen
-
- * Source/CTest/: cmCTestBatchTestHandler.cxx,
- cmCTestBatchTestHandler.h: Added some ctest batch capabilities
-
-2009-09-10 11:16 zach.mullen
-
- * Source/: CMakeLists.txt, CTest/cmCTestMultiProcessHandler.cxx,
- CTest/cmCTestMultiProcessHandler.h, CTest/cmCTestRunTest.cxx,
- CTest/cmCTestTestHandler.cxx, CTest/cmCTestTestHandler.h: BUG:
- Fixed segfault and bad reporting if a ctest executable could not
- be found. Also added some batch testing code that is not yet
- complete.
-
-2009-09-10 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-09-09 16:39 king
-
- * Tests/Fortran/CMakeLists.txt: Enable C and C++ first in Fortran
- test
-
- CMake now looks for a Fortran compiler matching any C or C++
- compiler already enabled. We test this by enabling C and C++
- first in the Fortran test, which is what user projects will
- likely do.
-
-2009-09-09 16:39 king
-
- * Modules/CMakeDetermineFortranCompiler.cmake: Bias Fortran
- compiler search with C/C++ compilers
-
- When CMAKE_Fortran_COMPILER and ENV{FC} are not defined CMake
- searches for an available Fortran compiler. This commit teaches
- the search code to look for compiler executables next to the C
- and C++ compilers if they are already found. Furthermore, we
- bias the compiler executable name preference order based on the
- vendor of the C and C++ compilers, which increases the chance of
- finding a compatible compiler by default.
-
-2009-09-09 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-09-08 17:28 david.cole
-
- * Modules/ExternalProject.cmake: Missed another CMAKE_CFG_INTDIR
- reference in the previously previous commit.
-
-2009-09-08 17:10 zach.mullen
-
- * Source/CTest/: cmCTestMultiProcessHandler.cxx,
- cmCTestMultiProcessHandler.h, cmCTestTestHandler.cxx: ENH: ctest
- now writes time cost data to a file after a test set is run, and
- uses these time costs to schedule the processes the next time
- ctest is run in that build tree.
-
-2009-09-08 16:11 david.cole
-
- * Modules/ExternalProject.cmake: Missed a CMAKE_CFG_INTDIR
- reference in the previous commit.
-
-2009-09-08 15:55 king
-
- * Modules/: CMakeBuildSettings.cmake.in,
- CMakeExportBuildSettings.cmake, CMakeImportBuildSettings.cmake,
- UseVTK40.cmake: Drop old CMake "build settings" export/import
-
- The CMakeExportBuildSettings and CMakeImportBuildSettings modules
- used to export compiler paths and flags from one project and
- import them into another. The import process would force the
- settings on the including project.
-
- Forcing settings helped long ago when compiler ABIs changed
- frequently but is now just a nuisance. We've deemed the behavior
- harmful so this commit simply removes it. The modules and macros
- now error out if included or called from a project that requires
- CMake 2.8 or higher.
-
-2009-09-08 15:37 david.cole
-
- * Modules/ExternalProject.cmake,
- Tests/ExternalProject/CMakeLists.txt: Use more
- verbose/descriptive names for the "public API" functions in the
- ExternalProject.cmake module. Follow the cmake function naming
- convention, using a ModuleFileName_ prefix. Locate stamp files
- under a CMAKE_CFG_INTDIR subdir of the stamp dir so that debug
- and release builds have separate stamp files for Visual Studio
- builds. If no CMAKE_GENERATOR argument is given to
- ExternalProject_Add, default to using the parent project's cmake
- generator.
-
-2009-09-08 14:48 zach.mullen
-
- * Source/CTest/: cmCTestMultiProcessHandler.cxx, cmProcess.cxx:
- BUG: Fixed extraneous newlines from ctest process output
-
-2009-09-08 13:39 zach.mullen
-
- * Source/: CTest/cmCTestMultiProcessHandler.cxx,
- cmSetTestsPropertiesCommand.h,
- CTest/cmCTestMultiProcessHandler.h, CTest/cmCTestTestHandler.cxx,
- CTest/cmCTestTestHandler.h: ENH: Replaced the EXPENSIVE test
- property with a COST test property taking a floating point value.
- Tests are now started in descending order of their cost, which
- defaults to 0 if none is specified.
-
-2009-09-08 10:16 zach.mullen
-
- * Source/CTest/: cmCTestRunTest.cxx, cmProcess.cxx, cmProcess.h:
- BUG: Fixed issue where ctest would hang if a process terminated
- with output in its buffers but no newline
-
-2009-09-08 09:12 zach.mullen
-
- * Source/CTest/cmCTestRunTest.h: Fixed warning
-
-2009-09-08 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-09-07 10:26 zach.mullen
-
- * Source/: CTest/cmCTestMultiProcessHandler.cxx,
- CTest/cmCTestMultiProcessHandler.h, CTest/cmCTestRunTest.cxx,
- CTest/cmCTestTestHandler.cxx, CTest/cmCTestTestHandler.h,
- cmSetTestsPropertiesCommand.h: ENH: Added ctest test options
- PROCESSORS and RUN_SERIAL. These allow specification of resource
- allocation for given tests running with the ctest -j N option.
- RUN_SERIAL ensures that a given test does not run in parallel
- with any other test. Also forced appending of "..." to the
- longest test name in ctest.
-
-2009-09-07 10:12 king
-
- * Source/cmVisualStudio10TargetGenerator.cxx,
- Source/cmVisualStudio10TargetGenerator.h, Tests/CMakeLists.txt:
- Put custom commands in topological order for VS 10
-
- Visual Studio 10 uses MSBuild to drive the build. Custom
- commands appear in MSBuild files inside CustomBuild elements,
- which appear inside ItemGroup elements. The Outputs and
- AdditionalInputs elements of each CustomBuild element are
- evaluated according to timestamps on disk.
-
- MSBuild does not use inputs/outputs to order CustomBuild steps
- within a single ItemGroup or across multiple ItemGroup elements.
- Instead we must put only unrelated CustomBuild elements in a
- single ItemGroup and order the item groups from top to bottom
- using a topological order of the custom command dependency graph.
-
- This fixes CustomCommand and ExternalProject test failures, so we
- remove the expectation of these failures.
-
-2009-09-07 10:11 king
-
- * Source/: cmTarget.cxx, cmTarget.h: Save source dependencies from
- custom command trace
-
- In each target we trace dependencies among custom commands to
- pull in all source files and build rules necessary to complete
- the target. This commit teaches cmTarget to save the
- inter-source dependencies found during its analysis. Later this
- can be used by generators that need to topologically order custom
- command rules.
-
-2009-09-07 10:11 king
-
- * Source/: cmLocalVisualStudio10Generator.cxx,
- cmLocalVisualStudioGenerator.cxx, cmLocalVisualStudioGenerator.h,
- cmVisualStudio10TargetGenerator.cxx: Do Windows command line
- escapes for VS 10 too
-
- Until now the VS 10 generator did no Windows command-line
- escaping and just did XML escapes. This commit teaches the
- generator to use the same command-line escape addition code used
- by other generators. The script construction method
- cmLocalVisualStudioGenerator::ConstructScript need not do XML
- escapes. Each VS generator version adds the XML escapes
- necessary for that version.
-
-2009-09-07 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-09-06 13:24 alex
-
- * Source/cmFileCommand.cxx: Try to fix the failing new
- StringFileTest on HP-UX
-
- It seems that while(i=file.get(), file) iterates one character
- too much on HP-UX, let's see whether while(file.get(c)) works, at
- least this is given as example on
- http://h30097.www3.hp.com/cplus/ifstream_3c__std.htm
-
- Alex
-
-2009-09-06 10:26 alex
-
- * Tests/StringFileTest/: CMakeLists.txt, test.bin: Add a test for
- FILE(READ ... HEX) together with a tiny binary file.
-
- Alex
-
-2009-09-06 09:49 alex
-
- * Source/cmFileCommand.cxx: fix #9316: when converting binary data
- to hex, also print the leading 0's
-
- Alex
-
-2009-09-06 05:43 alex
-
- * Source/cmExtraCodeBlocksGenerator.cxx: Improve the algorithm
- which skips targets so they are not added to the codeblocks GUI.
-
- -add all global targets from CMAKE_BINARY_DIR to the menu, but
- not from the subdirs -add all utility targets to the menu, except
- the Nightly/Experimental/Continuous-"sub"targets as e.
-
- Alex
-
-2009-09-06 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-09-05 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-09-04 18:19 david.cole
-
- * Modules/FindMPI.cmake: Oops. Close strings with double quotes.
- Where they're supposed to be.
-
-2009-09-04 18:02 david.cole
-
- * Modules/FindMPI.cmake: Add MPICH2 and Microsoft HPC paths, add
- paths to find mpiexec. Now it works better automatically on
- Windows. Thanks to Dave Partyka for developing the patch.
-
-2009-09-04 17:01 hoffman
-
- * Source/CTest/cmCTestScriptHandler.cxx: Fix memory and process
- leak in ctest_run_script.
-
-2009-09-04 16:43 clinton
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, CMakeSetupDialog.h: fix
- focus fighting between search field and cache value editors
-
-2009-09-04 14:00 david.cole
-
- * Source/CTest/cmCTestSubmitHandler.cxx: Increase curl submit
- timeout. A submit will timeout if there are 120 seconds of very
- little activity. 30 seconds was too short.
-
-2009-09-04 13:50 zach.mullen
-
- * Source/CTest/: cmCTestRunTest.cxx, cmProcess.cxx, cmProcess.h:
- Fixed ctest output processing. Should now display output as it
- occurs, as well as be able to consume multiple lines if they
- exist within the timeout.
-
-2009-09-04 13:24 hoffman
-
- * Source/CTest/: cmCTestRunScriptCommand.cxx,
- cmCTestRunScriptCommand.h, cmCTestScriptHandler.cxx,
- cmCTestScriptHandler.h: Change run_ctest_script in ctest to not
- stop processing when there is an error in the script being run.
- Also, add a RETURN_VALUE option so that you can find out if the
- script failed
-
-2009-09-04 12:39 king
-
- * Source/cmTarget.cxx: Cleanup source file dependency tracing logic
-
- In cmTarget we trace the dependencies of source files in the
- target to bring in all custom commands needed to generate them.
- We clean up the implementation to use simpler logic and better
- method names. The new approach is based on the observation that
- a source file is actually an input (dependency) of the rule that
- it runs (compiler or custom) even in the case that it is
- generated (another .rule file has the rule to generate it).
-
-2009-09-04 12:39 king
-
- * Source/: cmTarget.cxx, cmTarget.h: Cleanup cmTarget source file
- list representation
-
- This teaches cmTarget to use a set of cmSourceFile pointers to
- guarantee unique insertion of source files in a target. The
- order of insertion is still preserved in the SourceFiles vector.
-
-2009-09-04 12:38 king
-
- * Source/cmake.cxx: Simplify VS CMake re-run check
-
- When CMake is invoked by the VS IDE re-run rule we compute
- whether or not CMake really needs to re-run based on some
- timestamp helper files. Previously we assumed that if the main
- generate.stamp file exists then VS has correctly detected that
- the file is out of date. However, this assumption is too
- aggressive and re-runs CMake unnecessarily sometimes.
-
- This commit removes the assumption and always checks timestamps
- itself. The change breaks the explicit user re-run request
- (R-click -> Compile) but only in cases when the build system is
- already up to date.
-
-2009-09-04 12:37 king
-
- * Source/: cmGlobalVisualStudio8Generator.cxx,
- cmGlobalVisualStudio8Generator.h: Simplify VS generator
- ZERO_CHECK dependency
-
- The VS generators use a ZERO_CHECK target on which all other
- targets depend to check whether CMake needs to re-run. This
- commit simplifies the addition of a dependency on the target to
- all other targets.
-
- We also move addition of dependencies to the beginning of the
- Generate step. This allows the dependency on ZERO_CHECK to be
- included in the global inter-target dependency analysis.
-
-2009-09-04 11:23 zach.mullen
-
- * Source/CTest/cmProcess.cxx: Fixed output as-it-happens issue.
- Now displays output as it receives each newline.
-
-2009-09-04 10:16 zach.mullen
-
- * Source/CTest/: cmCTestMultiProcessHandler.cxx,
- cmCTestMultiProcessHandler.h, cmCTestTestHandler.cxx,
- cmProcess.cxx: Added the test property EXPENSIVE, which denotes
- that the given test(s) should be started prior to tests that are
- not marked as such. Also fixed test dependencies, and a few
- uninitialized variables in cmProcess.
-
-2009-09-04 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-09-03 17:01 hoffman
-
- * CMakeCPackOptions.cmake.in, CMakeLists.txt,
- Source/CMakeLists.txt, Source/cmDocumentVariables.cxx,
- Source/cmake.cxx: Remove CMakeSetup. Long live cmake-gui, start
- building Qt now.
-
-2009-09-03 15:58 martink
-
- * Source/cmSubdirCommand.h: some white space fixes for the book
-
-2009-09-03 15:50 zach.mullen
-
- * Source/CTest/cmProcess.cxx: Fixed 2 unused variable warnings
-
-2009-09-03 15:33 zach.mullen
-
- * Source/CTest/: cmCTestMultiProcessHandler.cxx,
- cmCTestRunTest.cxx, cmCTestRunTest.h, cmProcess.cxx, cmProcess.h:
- Allowed tests to pull more than one line of output in their
- quantum. Fixed uninitialized variables in the case that the test
- process could not start.
-
-2009-09-03 15:29 martink
-
- * Modules/CPack.cmake, Modules/FeatureSummary.cmake,
- Source/cmAddExecutableCommand.h, Source/cmAddLibraryCommand.h,
- Source/cmDefinePropertyCommand.h, Source/cmDocumentVariables.cxx,
- Source/cmEnableLanguageCommand.h, Source/cmFindCommon.cxx,
- Source/cmListCommand.h, Source/cmSetCommand.h,
- Source/cmSetDirectoryPropertiesCommand.h,
- Source/cmSubdirCommand.h, Source/cmTryRunCommand.h: some white
- space fixes for the book
-
-2009-09-03 12:11 david.cole
-
- * Modules/ExternalProject.cmake,
- Tests/ExternalProject/CMakeLists.txt: Add test step to
- ExternalProject builds. Rename SVN_TAG to SVN_REVISION since it
- is a more accurate name.
-
-2009-09-03 11:14 zach.mullen
-
- * Source/: CTest/cmCTestMultiProcessHandler.cxx,
- CTest/cmCTestTestCommand.h, CTest/cmCTestTestHandler.cxx,
- CTest/cmCTestTestHandler.h, cmSetTestsPropertiesCommand.h: Fixed
- warnings
-
-2009-09-03 11:10 king
-
- * Source/kwsys/RegularExpression.hxx.in: COMP: Silence useless
- Borland inlining warning
-
- KWSys tries not to force anything on source files that include
- its headers, but Borland warning 8027 leaves us no choice when we
- want to have inline function definitions. This commit disables
- the warning for the RegularExpression header and any file that
- includes it.
-
-2009-09-03 10:47 zach.mullen
-
- * Source/cmSetTestsPropertiesCommand.h,
- Source/CTest/cmCTestMemCheckCommand.h,
- Source/CTest/cmCTestMultiProcessHandler.cxx,
- Source/CTest/cmCTestRunTest.cxx,
- Source/CTest/cmCTestTestHandler.cxx,
- Source/CTest/cmCTestTestHandler.h,
- Tests/CTestTest3/test.cmake.in: ENH: Added PARALLEL_LEVEL option
- for ctest_memcheck(). Added PROCESSORS option to
- set_tests_properties (implementation to come).
-
-2009-09-03 08:27 king
-
- * Source/: cmLocalGenerator.cxx, cmPolicies.cxx, cmPolicies.h:
- Create CMP0014 to require CMakeLists.txt files
-
- Until now CMake accidentally accepted add_subdirectory() and
- subdirs() calls referring to directories that do not contain a
- CMakeLists.txt file. We introduce CMake Policy CMP0014 to make
- this case an error.
-
-2009-09-03 08:26 king
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h: Factor
- cmLocalGenerator::Configure input file read
-
- This method tells the cmMakefile to read the input CMakeLists.txt
- file. We factor out the call into a ReadInputFile method so it
- can be extended without polluting the Configure method.
-
-2009-09-03 08:26 king
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h: Factor
- cmLocalGenerator::Configure object max path
-
- Much of the code in this method was dedicated to computing
- ObjectMaxPath after configuring the directory. We move this last
- step into its own ComputeObjectMaxPath method for better
- organization.
-
-2009-09-03 08:26 king
-
- * Source/cmLocalGenerator.cxx: Manage current local generator with
- automatic var
-
- The cmLocalGenerator::Configure method sets its cmLocalGenerator
- instance as the global generator's current local generator during
- configuration. This commit refactors management of the current
- local generator to use an automatic variable. This will allow
- early returns from the method.
-
-2009-09-03 08:26 king
-
- * Source/cmPolicies.cxx: Fix typo in REQUIRED_ALWAYS policy error
- message
-
-2009-09-03 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-09-02 16:32 zach.mullen
-
- * Source/CTest/cmCTestMultiProcessHandler.cxx: STYLE: line length
-
-2009-09-02 16:07 king
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: Silence VS generator for
- missing CMakeLists.txt
-
- CMake Makefile generators silently ignore missing CMakeLists.txt
- files and just treat the source directory as if it had an empty
- input file. This will be addressed with a new CMake Policy, but
- for now we make the VS generator consistent with the Makefile
- generator behavior. The VS generator will need to handle the OLD
- behavior of the policy anyway.
-
-2009-09-02 16:06 king
-
- * Source/cmGlobalGenerator.cxx: Speed up graph traversal for
- project->targets map
-
- The cmGlobalGenerator::AddTargetDepends method traces the
- dependencies of targets recursively to collect the complete set
- of targets needed for a given project (for VS .sln files). This
- commit teaches the method to avoid tracing its dependencies more
- than once. Otherwise the code does an all-paths walk needlessly.
-
-2009-09-02 12:35 zach.mullen
-
- * Source/CTest/: cmCTestTestCommand.cxx, cmCTestTestCommand.h,
- cmCTestTestHandler.cxx: ENH: Added PARALLEL_LEVEL option to
- ctest_test() command.
-
-2009-09-02 10:08 zach.mullen
-
- * Modules/CTest.cmake, Modules/DartConfiguration.tcl.in,
- Source/cmCTest.cxx, Source/CTest/cmCTestMultiProcessHandler.cxx,
- Source/CTest/cmCTestMultiProcessHandler.h,
- Source/CTest/cmCTestRunTest.cxx, Source/CTest/cmCTestRunTest.h,
- Source/CTest/cmCTestTestHandler.h, Source/cmCTest.h: Fixed ctest
- output where max test index is not the same width as the total
- number of tests. Also some preliminary changes for batching
- ctest jobs
-
-2009-09-02 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-09-01 17:23 david.cole
-
- * Source/CTest/cmCTestSubmitHandler.cxx: Add curl timeout options
- to the SubmitUsingHTTP method. They were only in the
- SubmitUsingFTP method.
-
-2009-09-01 16:33 hoffman
-
- * Modules/Platform/: Windows-icl.cmake, Windows-ifort.cmake: Add
- support for embeded manifests for Intel C/C++/Fortran compilers
-
-2009-09-01 16:23 hoffman
-
- * Modules/Platform/Windows-Intel.cmake: Add a module to determine
- if the intel linker supports manifest creation
-
-2009-09-01 15:41 king
-
- * Tests/CTestUpdateGIT.cmake.in: Make CTest.UpdateGIT robust to
- user git config
-
- Part of this test does "git pull" on a dirty work tree. We need
- to make sure that 'branch.master.rebase' is false for the test
- repository. Otherwise if it is true in the user configuration
- then pull will refuse to rebase and the test will fail.
-
-2009-09-01 15:21 clinton
-
- * Modules/FindQt4.cmake: use -o flag instead of > for qdbuscpp2xml
-
-2009-09-01 15:08 hoffman
-
- * Source/cmake.cxx: Use the MANIFEST flag for non incremental
- linking as well.
-
-2009-09-01 14:33 hoffman
-
- * Modules/Platform/Windows-cl.cmake, Source/cmake.cxx: Move
- /MANIFEST flag into -E vs_link. This is so it can be used by the
- intel compilers without having to specifiy it in the intel
- compiler files
-
-2009-09-01 14:10 hoffman
-
- * Source/cmake.cxx: Handle embeded manifests with ifort.
-
-2009-09-01 14:05 king
-
- * Tests/FindPackageTest/: CMakeLists.txt, Exporter/CMakeLists.txt,
- Exporter/CMakeTestExportPackageConfig.cmake.in,
- Exporter/CMakeTestExportPackageConfigVersion.cmake.in,
- Exporter/dummy.c: Test the user package registry
-
- We teach the FindPackageTest to build a sample project that
- stores its build tree in the user package registry using
- export(PACKAGE), and then find it with find_package.
-
-2009-09-01 14:04 king
-
- * Source/: cmExportCommand.cxx, cmExportCommand.h: Teach
- export(PACKAGE) to fill the package registry
-
- We define the export(PACKAGE) command mode to store the location
- of the build tree in the user package registry. This will help
- find_package locate the package in the build tree. It simplies
- user workflow for manually building a series of dependent
- projects.
-
-2009-09-01 14:04 king
-
- * Source/: cmFindPackageCommand.cxx, cmFindPackageCommand.h: Teach
- find_package to search a "package registry"
-
- A common user workflow is to build a series of dependent projects
- in order. Each project locates its dependencies with
- find_package. We introduce a "user package registry" to help
- find_package locate packages built in non-standard search
- locations.
-
- The registry explicitly stores locations of build trees providing
- instances of a given package. There is no defined order among
- the locations specified. These locations should provide package
- configuration files (<package>-config.cmake) and package version
- files (<package>-config-version.cmake) so that find_package will
- recognize the packages and test version numbers.
-
-2009-09-01 13:55 king
-
- * Modules/: Compiler/Intel-C.cmake, Compiler/Intel-CXX.cmake,
- Compiler/Intel-Fortran.cmake, Compiler/Intel.cmake,
- Platform/Linux-Intel-C.cmake, Platform/Linux-Intel-CXX.cmake,
- Platform/Linux-Intel-Fortran.cmake, Platform/Linux-Intel.cmake:
- Use Intel for Linux flags only on Linux
-
- The commit "Split Intel compiler information files" moved some
- Linux specific flags into the platform-independent Intel compiler
- info files. This moves them back.
-
-2009-09-01 13:03 king
-
- * Modules/FortranCInterface/Verify/CMakeLists.txt: Fix
- FortranCInterface_VERIFY for non-C++ case
-
- The verification program entry point (main) is defined in a C
- source file, so the C compiler should be used to link when only
- Fortran and C are involved. The C++ compiler should still be
- used when the CXX option is enabled.
-
-2009-09-01 11:58 zach.mullen
-
- * Source/CTest/cmCTestRunTest.cxx: ENH: Improved test reporting
- output
-
-2009-09-01 10:38 king
-
- * Tests/ExportImport/: Export/CMakeLists.txt,
- Export/testLibCycleA1.c, Export/testLibCycleA2.c,
- Export/testLibCycleA3.c, Export/testLibCycleB1.c,
- Export/testLibCycleB2.c, Export/testLibCycleB3.c,
- Import/A/CMakeLists.txt, Import/A/imp_testExe1.c: Test link
- multiplicity export/import
-
- We test that LINK_INTERFACE_MULTIPLICITY propagates through
- export() and install(EXPORT) into dependent projects. A simple
- cycle of two archives that need to be scanned three times ensures
- that the importing project uses the multiplicity correctly.
-
-2009-09-01 10:38 king
-
- * Tests/Dependency/Case2/: CMakeLists.txt, foo1c.c, foo2c.c,
- foo3b.c, foo3c.c: Test link multiplicity
-
- This tests the LINK_INTERFACE_MULTIPLICITY property for a cycle
- of three static libraries that must be scanned three times to
- link properly.
-
-2009-09-01 10:37 king
-
- * Source/: cmComputeLinkDepends.cxx, cmComputeLinkDepends.h,
- cmExportFileGenerator.cxx, cmTarget.cxx, cmTarget.h: Define
- 'multiplicity' for cyclic dependencies
-
- We create target property "LINK_INTERFACE_MULTIPLICITY" and a
- per-config version "LINK_INTERFACE_MULTIPLICITY_<CONFIG>". It
- sets the number of times a linker should scan through a mutually
- dependent group of static libraries. The largest value of this
- property on any target in the group is used. This will help
- projects link even for extreme cases of cyclic inter-target
- dependencies.
-
-2009-09-01 08:52 king
-
- * Modules/FortranCInterface.cmake: Make FortranCInterface_VERIFY
- verbose on failure
-
- We enable verbose build output in the try_compile of the simple
- project. This makes valuable information available in the case
- of failure.
-
-2009-09-01 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-31 18:18 wdicharry
-
- * Modules/FindHDF5.cmake: Fixed link order dependence in FindHDF5
- module for static link.
-
-2009-08-31 13:25 king
-
- * bootstrap: Test KWSYS_IOS_HAVE_BINARY during bootstrap
-
- We need to do this KWSys configuration test in the CMake
- bootstrap script to create a proper cmsys/Configure.hxx file.
- This fixes the bootstrap script which was broken by the addition
- of the test to KWSys.
-
-2009-08-31 13:00 king
-
- * Source/kwsys/: CMakeLists.txt, Configure.hxx.in,
- kwsysPlatformTestsCXX.cxx, testIOS.cxx: Define kwsys_ios_binary
- macro for std::ios::binary
-
- The 'binary' openmode does not exist on all compilers. We define
- macro <kwsys>_ios_binary, where <kwsys> is the KWSys namespace,
- to refer to std::ios::binary if it exists and 0 otherwise.
- Sample usage:
-
- kwsys_ios::ifstream fin(fn, kwsys_ios::ios::in |
- kwsys_ios_binary);
-
-2009-08-31 11:32 zach.mullen
-
- * Source/CTest/cmCTestMemCheckCommand.h: Fixed ctest_memcheck docs
- (http://www.cmake.org/Bug/view.php?id=9242)
-
-2009-08-31 10:32 wdicharry
-
- * Modules/FindHDF5.cmake: In FindHDF5, added C library names to CXX
- search libraries.
-
-2009-08-31 10:28 zach.mullen
-
- * Source/CTest/cmCTestTestHandler.cxx: Fixed Dart time recording
- for ctest
-
-2009-08-31 09:50 zach.mullen
-
- * Source/CTest/: cmCTestMultiProcessHandler.h, cmCTestRunTest.cxx,
- cmCTestRunTest.h, cmCTestTestHandler.cxx: Fixed conversion
- warning on 64 bit machines
-
-2009-08-31 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-30 10:57 zach.mullen
-
- * Source/CTest/cmCTestRunTest.cxx: Fixed line length issue
-
-2009-08-30 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-29 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-28 15:08 zach.mullen
-
- * Source/CTest/: cmCTestMemCheckHandler.cxx,
- cmCTestMemCheckHandler.h, cmCTestMultiProcessHandler.cxx,
- cmCTestRunTest.cxx, cmCTestRunTest.h, cmCTestTestHandler.cxx,
- cmCTestTestHandler.h: MemCheck should now work again in ctest
-
-2009-08-28 11:40 zach.mullen
-
- * Source/CTest/cmCTestRunTest.cxx: Replaced std::stringstream with
- cmOStringStream
-
-2009-08-28 11:08 zach.mullen
-
- * Source/CTest/cmCTestMemCheckHandler.cxx,
- Source/CTest/cmCTestMultiProcessHandler.cxx,
- Source/CTest/cmCTestMultiProcessHandler.h,
- Source/CTest/cmCTestRunTest.cxx, Source/CTest/cmCTestRunTest.h,
- Source/CTest/cmCTestTestHandler.cxx,
- Source/CTest/cmCTestTestHandler.h, Tests/CMakeLists.txt: Added
- ctest -N test. Fixed ctest working directory bug. MemCheck fix
- coming soon...
-
-2009-08-28 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-27 10:37 zach.mullen
-
- * Source/: CTest/cmCTestGenericHandler.cxx,
- CTest/cmCTestMultiProcessHandler.cxx,
- CTest/cmCTestMultiProcessHandler.h, CTest/cmCTestRunTest.cxx,
- CTest/cmCTestRunTest.h, CTest/cmCTestTestHandler.cxx,
- CTest/cmCTestTestHandler.h, cmCTest.cxx, cmCTest.h, ctest.cxx:
- Fixed ctest -N segfault issue. Further refactored ctest.
- Enabled failover for ctest
-
-2009-08-27 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-26 12:09 zach.mullen
-
- * Source/: CTest/cmCTestMultiProcessHandler.cxx,
- CTest/cmCTestMultiProcessHandler.h, CTest/cmCTestRunTest.cxx,
- cmCTest.cxx, cmCTest.h, CTest/cmCTestRunTest.h,
- CTest/cmCTestTestHandler.cxx, CTest/cmCTestTestHandler.h: ENH:
- refactored ctest. All testing is now parallel. If no -j option
- is specified, defaults to a MP level of 1 (non parallel)
-
-2009-08-26 06:52 david.cole
-
- * Modules/ExternalProject.cmake: Add missing argument to
- _ep_write_downloadfile_script.
-
-2009-08-26 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-25 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-24 13:24 wdicharry
-
- * Modules/FindHDF5.cmake: Fixed HDF5 Find module error that caused
- no list to be passed into remove duplicates when HDF5 is not
- found.
-
-2009-08-24 13:15 king
-
- * Source/: cmComputeLinkInformation.cxx,
- cmComputeLinkInformation.h: Factor implicit link info addition
- into methods
-
- In cmComputeLinkInformation::Compute we add implicit link
- information from languages other than the linker language to the
- end of the link line. This factors out that code into separate
- methods to improve readability and organization.
-
-2009-08-24 13:07 king
-
- * Tests/Fortran/CMakeLists.txt: Enforce FortranCInterface_VERIFY in
- Fortran test
-
- This removes the QUIET option from FortranCInterface_VERIFY in
- the Fortran test to really test the detected interface
- everywhere.
-
-2009-08-24 12:04 wdicharry
-
- * Modules/: SelectLibraryConfigurations.cmake, FindHDF5.cmake: Add
- HDF5 find module and select_library_configurations module.
-
-2009-08-24 09:54 king
-
- * Source/: cmComputeTargetDepends.cxx, cmComputeTargetDepends.h,
- cmake.cxx: Create GLOBAL_DEPENDS_NO_CYCLES property
-
- This global property disallows cycles in the inter-target
- dependency graph even among STATIC libraries. See issue #9444.
-
-2009-08-24 08:49 king
-
- * Modules/FortranCInterface.cmake,
- Modules/FortranCInterface/Detect.cmake,
- Modules/FortranCInterface/Verify/CMakeLists.txt,
- Modules/FortranCInterface/Verify/VerifyC.c,
- Modules/FortranCInterface/Verify/VerifyCXX.cxx,
- Modules/FortranCInterface/Verify/VerifyFortran.f,
- Modules/FortranCInterface/Verify/main.c,
- Tests/Fortran/CMakeLists.txt: Create FortranCInterface_VERIFY
- function
-
- This function builds a simple test project using a combination of
- Fortran and C (and optionally C++) to verify that the compilers
- are compatible. The idea is to help projects report very early
- to users that the compilers specified cannot mix languages.
-
-2009-08-24 08:49 king
-
- * Modules/: FortranCInterface.cmake,
- FortranCInterface/Detect.cmake: Teach FortranCInterface to load
- outside results
-
- We split the main detection logic into a Detect.cmake support
- module and load it only when detection results are not already
- available. This allows results computed by the main project to
- be used in try-compile projects without recomputing them. The
- call to try_compile() need only to pass
- FortranCInterface_BINARY_DIR through the CMAKE_FLAGS option.
-
-2009-08-24 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-23 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-22 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-21 10:32 king
-
- * Modules/: Compiler/SunPro-C.cmake, Compiler/SunPro-CXX.cmake,
- Compiler/SunPro-Fortran.cmake, Platform/Linux-SunPro-C.cmake,
- Platform/Linux-SunPro-CXX.cmake,
- Platform/Linux-SunPro-Fortran.cmake,
- Platform/SunOS-SunPro-Fortran.cmake, Platform/SunOS.cmake: Split
- SunPro compiler information files
-
- This moves platform-independent SunPro compiler flags into
- separate "Compiler/SunPro-<lang>.cmake" modules.
- Platform-specific flags are left untouched.
-
-2009-08-21 09:54 king
-
- * Modules/: Compiler/Intel-C.cmake, Compiler/Intel-CXX.cmake,
- Compiler/Intel-Fortran.cmake, Compiler/Intel.cmake,
- Platform/Linux-Intel-C.cmake, Platform/Linux-Intel-CXX.cmake,
- Platform/Linux-Intel-Fortran.cmake: Split Intel compiler
- information files
-
- This moves platform-independent Intel compiler flags into
- separate "Compiler/Intel-<lang>.cmake" modules.
- Platform-specific flags are left untouched.
-
-2009-08-21 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-20 16:21 king
-
- * Modules/FortranCInterface.cmake: Teach FortranCInterface to
- verify languages
-
- This module requires both C and Fortran to be enabled, so
- error-out if they are not.
-
-2009-08-20 16:21 king
-
- * Source/cmDocumentVariables.cxx: Document
- CMAKE_<LANG>_COMPILER_LOADED variable
-
-2009-08-20 09:46 zach.mullen
-
- * Source/CTest/cmCTestRunTest.cxx: Fixed line length over 80
-
-2009-08-20 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-19 22:28 lowman
-
- * Modules/FindBoost.cmake: Add Boost 1.39 & 1.40. Move
- ${Boost_INCLUDE_DIR}/lib to front of library search.
-
-2009-08-19 12:19 david.cole
-
- * Modules/: DownloadFile.cmake, ExternalProject.cmake,
- UntarFile.cmake: Remove DownloadFile.cmake and UntarFile.cmake
- from the Modules directory. Put functionality directly into
- ExternalProject.cmake itself so that these modules do not end up
- in the upcoming release of CMake.
-
-2009-08-19 09:24 zach.mullen
-
- * Source/: cmCTest.cxx, CTest/cmCTestTestHandler.cxx,
- CTest/cmCTestTestHandler.h: Fixed overwriting of a previous
- change set
-
-2009-08-19 08:58 zach.mullen
-
- * Source/: CMakeLists.txt, cmCTest.cxx, cmCTest.h,
- CTest/cmCTestRunTest.cxx, CTest/cmCTestRunTest.h,
- CTest/cmCTestTestHandler.cxx, CTest/cmCTestTestHandler.h: ENH:
- Refactored CTest test execution code into an object
-
-2009-08-19 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-18 14:03 hoffman
-
- * Source/CTest/cmCTestTestHandler.cxx: Add test times to log file
- as well as the stdout.
-
-2009-08-18 13:34 hoffman
-
- * Source/CTest/: cmCTestTestHandler.cxx, cmCTestTestHandler.h: If
- labels are found on the tests, then print a time summary for all
- the tests run with each label.
-
-2009-08-18 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-17 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-16 23:07 lowman
-
- * Modules/FindBullet.cmake: Find module for the Bullet physics
- engine
-
-2009-08-16 22:12 lowman
-
- * Modules/FindGTest.cmake: A find module for the Google C++ Testing
- Framework
-
-2009-08-16 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-15 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-14 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-13 00:11 lowman
-
- * Modules/: FindBISON.cmake, FindFLEX.cmake: Checking in the
- FindFLEX.cmake & FindBISON.cmake attached to Issue #4018 after
- some minor improvements
-
- * Improved examples * Switched to FindPackageHandleStandardArgs *
- Cleaned up indentation * Sanitized else()/endif() blocks
-
-2009-08-13 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-12 22:40 lowman
-
- * Modules/FindDevIL.cmake: Fixes Issue #8994
-
-2009-08-12 22:25 lowman
-
- * Modules/FindGnuTLS.cmake: Find module for GnuTLS, the GNU
- Transport Layer Security library (Issue #9228)
-
-2009-08-12 21:58 lowman
-
- * Modules/FindOpenSceneGraph.cmake: Improved error output and
- documentation
-
- * Fixed errant output when version number not found * Improved
- error output when REQUIRED is passed * Improved docs and example
-
-2009-08-12 09:09 king
-
- * Modules/Platform/Windows-bcc32.cmake: Quote the target name for
- Borland tlib tool
-
- The Borland librarian tool "tlib" requires that the output target
- name be quoted if it contains the character '-' (and perhaps a
- few others). This commit restores the use of the TARGET_QUOTED
- rule variable replacement for this purpose. Otherwise no static
- library can have a '-' in its name.
-
- This problem was exposed by the 'Testing' test when it builds the
- pcStatic library with the '-dbg' suffix.
-
-2009-08-12 08:06 king
-
- * Source/CTest/cmCTestSVN.cxx: Fix classification of externals in
- svn status
-
- CTest runs 'svn status' to identify modified and conflicting
- files in the working directory. This commit fixes the
- interpretation of the 'X' status, which corresponds to svn
- eXternals. This status should be ignored rather than treated as
- a local modification.
-
-2009-08-12 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-11 22:02 hoffman
-
- * Source/CTest/: cmCTestMultiProcessHandler.cxx,
- cmCTestTestHandler.cxx, cmProcess.h: Output total time when using
- -j N
-
-2009-08-11 22:01 hoffman
-
- * Tests/CTestUpdateCommon.cmake: Output command that failed, if it
- fails.
-
-2009-08-11 16:25 hoffman
-
- * Source/CTest/cmCTestCVS.cxx: Fix failing test on release build
- for VS 10 cmSystemTools::GetLineFromStream crashes if the stream
- is not open in that case.
-
-2009-08-11 09:55 king
-
- * Tests/Testing/: CMakeLists.txt, driver.cmake, pcShared.c,
- pcShared.h, pcStatic.c, perconfig.c: Test add_test() generator
- expressions
-
- This teaches the 'testing' test to try generator expressions in
- arguments to add_test(NAME). This test case mimics a common
- use-case of passing executables to test driver scripts. We
- excercise the syntax for per-configuration target file names.
-
-2009-08-11 09:54 king
-
- * Source/CMakeLists.txt, Source/cmAddTestCommand.h,
- Source/cmGeneratorExpression.cxx, Source/cmGeneratorExpression.h,
- Source/cmTestGenerator.cxx, bootstrap: Introduce "generator
- expressions" to add_test()
-
- This introduces a new syntax called "generator expressions" to
- the test COMMAND option of the add_test(NAME) command mode.
- These expressions have a syntax like $<TARGET_FILE:mytarget> and
- are evaluated during build system generation. This syntax allows
- per-configuration target output files to be referenced in test
- commands and arguments.
-
-2009-08-11 09:07 king
-
- * Source/: cmTarget.cxx, cmTarget.h: Create cmTarget DLL query
- methods
-
- We creates methods IsDLLPlatform() and HasImportLibrary(). The
- former returns true on Windows. The latter returns whether the
- target has a DLL import library. It is true on Windows for
- shared libraries and executables with exports.
-
-2009-08-11 09:07 king
-
- * Source/: cmMakefile.cxx, cmTest.cxx, cmTest.h: Record backtrace
- for every add_test command
-
- We teach cmTest to hold a backtrace for the add_test command that
- created it. This will be used later to report context for errors
- at generate time.
-
-2009-08-11 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-10 14:32 clinton
-
- * Source/QtDialog/QCMake.cxx: ENH: Patch from Alexander Neundorf
- to remove "KDevelop3" from list of generators. "KDevelop3 - Unix
- Makefiles" should be used instead.
-
-2009-08-10 13:25 clinton
-
- * Source/QtDialog/: QCMakeCacheView.cxx, QCMakeCacheView.h: ENH:
- Allow edit on single click. Fixes #9393. Also fix row heights
- to be consistent.
-
-2009-08-10 09:07 king
-
- * Source/cmTestGenerator.cxx: Cleanup test property script code
- generation
-
- We teach cmTestGenerator::GenerateScriptConfigs to use the
- general cmLocalGenerator::EscapeForCMake method to write escaped
- test property values into test scripts. This eliminates the
- previous hand-coded escaping implementation.
-
-2009-08-10 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-09 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-08 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-07 10:13 king
-
- * Modules/: CMakeCCompilerId.c.in, CMakeCXXCompilerId.cpp.in,
- CMakeFortranCompilerId.F.in, Compiler/VisualAge-C.cmake,
- Compiler/VisualAge-CXX.cmake, Compiler/VisualAge-Fortran.cmake,
- Compiler/XL-C.cmake, Compiler/XL-CXX.cmake,
- Compiler/XL-Fortran.cmake, Platform/Linux-VisualAge-C.cmake,
- Platform/Linux-VisualAge-Fortran.cmake,
- Platform/Linux-XL-C.cmake, Platform/Linux-XL-Fortran.cmake: Teach
- compiler id about VisualAge -> XL rebranding
-
- IBM rebranded its VisualAge compiler to XL starting at version
- 8.0. We use the compiler id "XL" for newer versions and
- "VisualAge" for older versions. We now also recognize the "z/OS"
- compiler, which is distinct from XL.
-
-2009-08-07 10:12 king
-
- * Modules/: Compiler/VisualAge-Fortran.cmake,
- Platform/AIX-VisualAge-Fortran.cmake,
- Platform/Linux-VisualAge-Fortran.cmake, Platform/xlf.cmake: Move
- flag to Compiler/VisualAge-Fortran module
-
- The CMAKE_Fortran_DEFINE_FLAG value applies to the IBM Fortran
- compilers on all platforms. This moves the setting to the
- platform-independent compiler information file.
-
-2009-08-07 09:56 king
-
- * Modules/Platform/OpenBSD.cmake: Use NetBSD to initialize OpenBSD
- configuration
-
- We teach Modules/Platform/OpenBSD.cmake to load NetBSD first
- since the platforms are so similar. This enables RPATH support
- on OpenBSD.
-
-2009-08-07 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-06 19:01 partyd
-
- * Source/kwsys/SystemTools.cxx: COMP: attempt to fix more 'hidden
- by' warnings.
-
-2009-08-06 07:53 king
-
- * Modules/FortranCInterface/CMakeLists.txt: Teach FortranCInterface
- about g77 mangling
-
- The old GNU g77 Fortran compiler uses the suffix '__' for symbols
- containing an underscore in their name.
-
-2009-08-06 07:53 king
-
- * Modules/FortranCInterface/CMakeLists.txt: Sort FortranCInterface
- global mangling symbols
-
- This just cleans up the list ordering so more entries can be
- added while keeping everything organized.
-
-2009-08-06 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-05 17:07 king
-
- * Modules/FortranCInterface/: CMakeLists.txt, my_module_.c,
- mymodule_.c: Cleanup FortranCInterface for PGI and GCC 4.2
-
- This documents the purpose of the extra my_module_.c and
- mymodule.c source files, and sorts the symbols.
-
-2009-08-05 16:55 hoffman
-
- * Modules/FortranCInterface/: CMakeLists.txt, my_module_.c,
- mymodule_.c: Teach FortranC interface for Intel, PGI, and gcc 4.2
-
-2009-08-05 15:39 david.cole
-
- * Modules/AddExternalProject.cmake: Remove
- AddExternalProject.cmake. ExternalProject.cmake
- supercedes/replaces it.
-
-2009-08-05 14:59 david.cole
-
- * Modules/: BundleUtilities.cmake, GetPrerequisites.cmake: Overhaul
- GetPrerequisites and BundleUtilities: make fixup_bundle do
- something useful on Windows and Linux.
-
- Formerly, fixup_bundle was useful only on the Mac for making
- standalone bundle applications that could be drag-n-drop moved to
- anyplace in the file system. fixup_bundle is not just for the Mac
- any more. It will now analyze executable files on Windows and
- Linux, too, and copy necessary non-system dlls to the same folder
- that the executable is in. This should work with dlls that you
- build as part of your build and also with 3rd-party dlls as long
- as you give fixup_bundle the right list of directories to search
- for those dlls. Many thanks to Clinton Stimpson for his help in
- ironing out the details involved in making this work.
-
-2009-08-05 13:40 king
-
- * Modules/FortranCInterface.cmake, Modules/FortranCInterface.h.in,
- Modules/FortranCInterface/CMakeLists.txt,
- Modules/FortranCInterface/Input.cmake.in,
- Modules/FortranCInterface/Macro.h.in,
- Modules/FortranCInterface/Output.cmake.in,
- Modules/FortranCInterface/call_mod.f90,
- Modules/FortranCInterface/call_sub.f,
- Modules/FortranCInterface/main.F,
- Modules/FortranCInterface/my_module.f90,
- Modules/FortranCInterface/my_sub.f,
- Modules/FortranCInterface/mymodule.f90,
- Modules/FortranCInterface/mysub.f,
- Modules/FortranCInterface/symbol.c.in,
- Tests/Fortran/CMakeLists.txt, Tests/Fortran/myc.c: Rewrite
- FortranCInterface module
-
- This is a new FortranCInterface.cmake module to replace the
- previous prototype. All module support files lie in a
- FortranCInterface directory next to it.
-
- This module uses a new approach to detect Fortran symbol
- mangling. We build a single test project which defines symbols
- in a Fortran library (one per object-file) and calls them from a
- Fortran executable. The executable links to a C library which
- defines symbols encoding all known manglings (one per
- object-file). The C library falls back to the Fortran library
- for symbols it cannot provide. Therefore the executable will
- always link, but prefers the C-implemented symbols when they
- match. These symbols store string literals of the form
- INFO:symbol[<name>] so we can parse them out of the executable.
-
- This module also provides a simpler interface. It always detects
- the mangling as soon as it is included. A single macro is
- provided to generate mangling macros and optionally pre-mangled
- symbols.
-
-2009-08-05 10:45 hoffman
-
- * Source/cmVisualStudio10TargetGenerator.cxx: Allow for static
- libraries to depend on other targets so that the MSBuild runs
- build things in the correct order
-
-2009-08-05 10:14 king
-
- * Source/CMakeLists.txt, Tests/CMakeLists.txt,
- Utilities/Doxygen/doxyfile.in: Remove WXDialog source code
-
- The QtDialog is our supported cross-platform GUI, so the WXDialog
- source is no longer needed.
-
-2009-08-05 10:13 king
-
- * Source/CMakeLists.txt: Remove FLTKDialog source code
-
- The QtDialog is our supported cross-platform GUI, so the
- FLTKDialog source is no longer needed.
-
-2009-08-05 09:56 king
-
- * Source/cmFindPackageCommand.cxx: Fix find_package for cmake-gui
- registry entry
-
- The find_package commands looks at the "WhereBuild" registry
- entries created by CMakeSetup and cmake-gui hoping that the
- project was recently built. CMakeSetup created
- WhereBuild1..WhereBuild10 but cmake-gui creates
- WhereBuild0-WhereBuild9.
-
- This fixes find_package to look at WhereBuild0 so that the most
- recently configured project can be found. It is important in the
- case that the package to be found was the last one configured in
- cmake-gui but the current project that is finding it is
- configured from the command line.
-
-2009-08-05 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-04 15:41 martink
-
- * Source/cmLocalGenerator.cxx: ENH: minor cleanup of test
-
-2009-08-04 14:37 king
-
- * Source/cmCoreTryCompile.cxx, Source/cmGlobalGenerator.cxx,
- Source/cmGlobalGenerator.h, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Tests/TryCompile/CMakeLists.txt,
- Tests/TryCompile/Inner/CMakeLists.txt,
- Tests/TryCompile/Inner/innerexe.c,
- Tests/TryCompile/Inner/innerlib.c: No /fast targets in
- try_compile project mode
-
- The try_compile command builds the cmTryCompileExec executable
- using the cmTryCompileExec/fast target with Makefile generators
- in order to save time since dependencies are not needed.
- However, in project mode the command builds an entire source tree
- that may have dependencies. Therefore we can use the /fast
- target approach only in one-source mode.
-
-2009-08-04 14:06 king
-
- * Tests/Fortran/: CMakeLists.txt, foo.c, foo.cxx, mainc.c,
- maincxx.c, myc.c, mycxx.cxx: Test C, C++, Fortran interface
- combinations
-
- Previously the Fortran test created a single executable
- containing C, C++, and Fortran sources. This commit divides the
- executable into three libraries corresponding to each language,
- and two executables testing Fortran/C only and Fortran/C/C++
- together. The result tests more combinations of using the
- languages together, and that language requirements propagate
- through linking.
-
-2009-08-04 13:16 martink
-
- * Source/cmTest.cxx: ENH: change to CDASH
-
-2009-08-04 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-03 13:37 king
-
- * Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Tests/TryCompile/Inner/CMakeLists.txt: Fix recursive try_compile
- calls
-
- When building an entire source tree with try_compile instead of
- just a single source file, it is possible that the CMakeLists.txt
- file in the try-compiled project invokes try_compile. This
- commit fixes propagation of language-initialization results from
- the outer-most project into any number of try-compile levels.
-
-2009-08-03 13:37 king
-
- * Tests/TryCompile/: CMakeLists.txt, Inner/CMakeLists.txt: Test
- try_compile project mode
-
- The try_compile command project mode builds an entire source tree
- instead of one source file. It uses an existing CMakeLists.txt
- file in the given source tree instead of generating one. This
- commit creates a test for the mode in the TryCompile test.
-
-2009-08-03 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-02 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-08-01 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-07-31 16:11 alex
-
- * Source/cmake.cxx: DOCS: fix typo (#9231)
-
- Alex
-
-2009-07-31 09:19 king
-
- * Source/CTest/cmCTestScriptHandler.cxx: Set current directory
- variables in CTest scripts
-
- The commit "Fix get_filename_component ABSOLUTE mode" broke the
- code
-
- get_filename_component(cwd . ABSOLUTE)
-
- because CTest scripts did not make
- cmMakefile::GetCurrentDirectory() available. This commit fixes
- the problem by setting the proper information on CTest script
- instances of cmMakefile.
-
- This also makes CMAKE_CURRENT_SOURCE_DIR and
- CMAKE_CURRENT_BINARY_DIR available to CTest scripts. They are
- set to the working directory at script startup.
-
-2009-07-31 08:27 king
-
- * CMakeLists.txt, Source/QtDialog/CMakeLists.txt: Fix installation
- when built by CMake 2.4
-
- CMake 2.4 generates old-style cmake_install.cmake code including
- calls to the file(INSTALL) command with the COMPONENTS argument.
- We need to set CMAKE_INSTALL_SELF_2_4 for the whole install tree
- to prevent the command from complaining in this special case.
- Previously this was needed only in the QtDialog directory, but
- now it is needed in the entire tree.
-
-2009-07-31 06:22 alex
-
- * Source/: cmFunctionCommand.h, cmMacroCommand.h: DOCS: fix typo
- (see #9308)
-
- Alex
-
-2009-07-31 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: KWSys Nightly Date Stamp
-
-2009-07-30 13:46 king
-
- * Modules/: CMakeFortranCompiler.cmake.in,
- CMakeTestFortranCompiler.cmake: Pass Fortran90 test result to
- try-compile
-
- This stores CMAKE_Fortran_COMPILER_SUPPORTS_F90 in the Fortran
- compiler information file CMakeFiles/CMakeFortranCompiler.cmake
- instead of in CMakeCache.txt. This file makes the result
- available to try-compile projects.
-
-2009-07-30 10:59 king
-
- * Modules/CMakeCXXCompiler.cmake.in,
- Source/cmDocumentVariables.cxx, Source/cmTarget.cxx: Do not
- always propagate linker language preference
-
- The commit "Consider link dependencies for link language" taught
- CMake to propagate linker language preference from languages
- compiled into libraries linked by a target. It turns out this
- should only be done for some languages, such as C++, because
- normally the language of the program entry point (main) should be
- used.
-
- We introduce variable CMAKE_<LANG>_LINKER_PREFERENCE_PROPAGATES
- to tell CMake whether a language should propagate its linker
- preference across targets. Currently it is true only for C++.
-
-2009-07-30 10:59 king
-
- * Source/cmTarget.cxx: Refactor target linker language selection
-
- This factors the decision logic out of
- cmTarget::ComputeLinkClosure into dedicated class
- cmTargetSelectLinker. We replace several local variables with a
- single object instance, and organize code into methods.
-
-2009-07-30 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-29 16:40 king
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h:
- Separate Xcode flag escaping code from defines
-
- Generalize the core Xcode generator preprocessor flag escaping
- code to be useful for escaping all flags.
-
-2009-07-29 16:39 king
-
- * Source/cmGlobalXCodeGenerator.cxx: Re-order
- cmGlobalXCodeGenerator implementation
-
- This defines class
- cmGlobalXCodeGenerator::BuildObjectListOrString early in the
- source file so it can be used in more places.
-
-2009-07-29 16:38 king
-
- * Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in: Check PGI linker
- lines in ImplicitLinkInfo test
-
- This adds sample linker invocation lines for the PGI compiler on
- Linux.
-
-2009-07-29 16:38 king
-
- * Modules/Compiler/: PGI-C.cmake, PGI-CXX.cmake, PGI-Fortran.cmake:
- Set CMAKE_<LANG>_VERBOSE_FLAG variables for PGI
-
- We set the variables to contain "-v", the verbose front-end
- output option for PGI compilers. This enables detection of
- implicit link libraries and directories for these compilers.
-
-2009-07-29 16:07 king
-
- * Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in: Check Intel
- linker lines in ImplicitLinkInfo test
-
- This adds sample linker invocation lines for the Intel compiler
- on Linux. In particular, this exercises the case when "ld"
- appears without a full path.
-
-2009-07-29 16:07 king
-
- * Modules/Compiler/: Intel-C.cmake, Intel-CXX.cmake,
- Intel-Fortran.cmake: Set CMAKE_<LANG>_VERBOSE_FLAG variables for
- Intel
-
- We set the variables to contain "-v", the verbose front-end
- output option for Intel compilers. This enables detection of
- implicit link libraries and directories for these compilers.
-
-2009-07-29 16:07 king
-
- * Modules/CMakeParseImplicitLinkInfo.cmake: Recognize linker
- commands without paths
-
- This teaches the implicit link line parsing code to recognize
- link lines that do not have a full path to the linker executable.
- At least one version of the Intel compiler on Linux invokes the
- linker as just "ld" instead of "/usr/bin/ld".
-
-2009-07-29 11:29 king
-
- * Source/: CMakeLists.txt, cmIDEOptions.cxx, cmIDEOptions.h,
- cmVisualStudioGeneratorOptions.cxx,
- cmVisualStudioGeneratorOptions.h: ENH: Separate option mapping
- from VS generators
-
- Split cmVisualStudioGeneratorOptions core functionality out into
- a base class cmIDEOptions. It will be useful for other
- generators.
-
-2009-07-29 11:28 king
-
- * Source/: CMakeLists.txt, cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h,
- cmGlobalVisualStudio8Generator.cxx,
- cmGlobalVisualStudio8Generator.h, cmIDEFlagTable.h,
- cmLocalVisualStudio7Generator.h,
- cmVisualStudioGeneratorOptions.h: ENH: Separate VS flag table
- type
-
- Move the cmVS7FlagTable type out of the VS generators and rename
- it to cmIDEFlagTable. It will be useful for other generators.
-
-2009-07-29 08:39 king
-
- * Tests/Properties/CMakeLists.txt: Test cache entry property
- "STRINGS"
-
- The STRINGS property tells cmake-gui to create a drop-down
- selection list. This teaches the Properties test to set and
- verify its value.
-
-2009-07-29 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-28 14:30 hoffman
-
- * Source/: cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h: ENH: remove code duplication and
- use cmVisualStudioGeneratorOptions for all versions of vs 7 and
- greater.
-
-2009-07-28 10:46 king
-
- * Source/: CPack/cmCPackGenerator.cxx,
- CTest/cmCTestScriptHandler.cxx, CTest/cmCTestTestHandler.cxx,
- cmCTest.cxx, cmake.cxx: BUG: Do not double-initialize local
- generators
-
- All global generator CreateLocalGenerator methods automatically
- initialize the local generator instances with SetGlobalGenerator.
- In several places we were calling SetGlobalGenerator again after
- receiving the return value from CreateLocalGenerator. The
- double-initializations leaked the resources allocated by the
- first call to SetGlobalGenerator. This fix removes the
- unnecessary calls.
-
-2009-07-28 08:36 king
-
- * Source/cmComputeLinkInformation.cxx: BUG: Do not filter
- non-library implicit link items
-
- We list implicit link items of languages linked into a target but
- filter them by the implicit libraries known to be passed by the
- main linker language. Implicit link flags like "-z..." should
- not be filtered out because they are not libraries.
-
-2009-07-28 08:36 king
-
- * Modules/CMakeParseImplicitLinkInfo.cmake,
- Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in: BUG: Parse
- implicit link editor -z*extract options
-
- The Sun Fortran compiler passes -zallextract and -zdefaultextract
- to the linker so that all objects from one of its archives are
- included in the link. This teaches the implicit options parser
- to recognize the flags. We need to pass them explicitly on C++
- link lines when Fortran code is linked.
-
-2009-07-28 08:08 king
-
- * Source/cmComputeLinkInformation.cxx: BUG: Always pass linker
- flags untouched
-
- In cmComputeLinkInformation we recognize link options that look
- like library file names, but pass flags starting in '-' through
- untouched. This fixes the ordering of the check to recognize '-'
- flags first in case the rest of the option looks like a library
- file name, as in the case of "-l:libfoo.a".
-
-2009-07-28 08:07 king
-
- * Source/cmComputeLinkInformation.cxx: BUG: Do not recognize ':' in
- a library name
-
- In cmComputeLinkInformation we construct regular expressions to
- recognize library file names. This fixes the expressions to not
- allow a colon (':') in the file name so that "-l:libfoo.a" is
- left alone.
-
-2009-07-28 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-27 16:45 king
-
- * Source/kwsys/: CMakeLists.txt, kwsysPlatformTestsCXX.cxx: BUG:
- Enable large files only if <cstdio> works
-
- Some AIX/gcc version combinations the <cstdio> header breaks when
- large file support is enabled. See this GCC issue for details:
-
- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20366
-
- We work around the problem by enhancing the configuration check
- for large file support to include <cstdio> when available. This
- will cause LFS to be disabled when the above problem occurs.
-
-2009-07-27 14:17 hoffman
-
- * Source/CTest/cmCTestTestHandler.cxx: ENH: add test times and a
- total time to the output of command line ctest
-
-2009-07-27 12:43 king
-
- * Tests/Fortran/: CMakeLists.txt, foo.c, foo.cxx: ENH: Test Fortran
- and C++ in one executable
-
- This extends the Fortran-to-C interface test to add a C++ source
- file. The executable can only link with the C++ linker and with
- the proper Fortran runtime libraries. These libraries should be
- detected by CMake automatically, so this tests verifies the
- detection functionality.
-
-2009-07-27 12:43 king
-
- * Tests/Fortran/CMakeLists.txt: ENH: Remove EXTRA_FORTRAN_C_LIBS
- Fortran test hack
-
- This hack was created to help the Fortran test executables link
- to the implicit C libraries added by BullsEye. Now that implicit
- libraries from all languages are detected and included
- automatically the hack is no longer needed.
-
-2009-07-27 12:43 king
-
- * Source/: cmComputeLinkInformation.cxx,
- cmComputeLinkInformation.h, cmOrderDirectories.cxx,
- cmOrderDirectories.h: ENH: Link runtime libraries of all
- languages
-
- This adds implicit libraries and search directories for languages
- linked into a target other than the linker language to its link
- line. For example, when linking an executable containing both
- C++ and Fortran code the C++ linker is used but we need to add
- the Fortran libraries.
-
- The variables
-
- CMAKE_<LANG>_IMPLICIT_LINK_LIBRARIES
- CMAKE_<LANG>_IMPLICIT_LINK_DIRECTORIES
-
- contain the implicit libraries and directories for each language.
- Entries for the linker language are known to be implicit in the
- generated link line. Entries for other languages that do not
- appear in the known implicit set are listed explicitly at the end
- of the link line.
-
-2009-07-27 12:35 king
-
- * Tests/SystemInformation/DumpInformation.cxx: ENH: Report CMake
- logs in SystemInformation test
-
- This teaches the SystemInformation test to report the CMake log
- files CMakeOutput.log and CMakeError.log from the CMake build
- tree and from the SystemInformation test build tree. These logs
- may help diagnose dashboard problems remotely.
-
-2009-07-27 12:04 david.cole
-
- * Tests/CMakeTests/: CMakeLists.txt, CheckSourceTreeTest.cmake.in:
- ENH: Make the CheckSourceTree test emit a warning (but pass
- instead of fail) when there is an in-source build on a dashboard
- machine.
-
-2009-07-27 11:56 king
-
- * Tests/Fortran/mysub.f: ENH: Require language libs in Fortran/C
- test
-
- This extends the Fortran/C interface test to require that the
- executable link to the fortran language runtime libraries. We
- must verify that the proper linker is chosen.
-
-2009-07-27 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-26 01:01 partyd
-
- * Source/kwsys/SystemTools.cxx: ENH: try and see if using
- string.append instead of += will make valgrind not complaing that
- JoinPath is leaking.
-
-2009-07-26 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-25 13:32 david.cole
-
- * Tests/CMakeTests/CheckSourceTreeTest.cmake.in: ENH: Improvements
- to the new CheckSourceTree test: ignore Thumbs.db and .DS_Store
- files. Force all output to stderr by not using STATUS with
- message. Better error text.
-
-2009-07-25 08:11 king
-
- * Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in: BUG: Further
- avoid ImplicitLinkInfo case change
-
- The commit "Avoid case change in ImplicitLinkInfo test" did not
- change all of the paths to mingw, so some case change still
- occurs. This changes more of them.
-
-2009-07-25 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-24 18:30 david.cole
-
- * Tests/CMakeLists.txt: BUG: One last attempt for today to get the
- new CheckSourceTree test running on dashboards driven by CMake
- 2.4... Good night now.
-
-2009-07-24 17:33 king
-
- * CMakeLists.txt: ENH: Allow empty endif() and such with CMake 2.4
-
- This allows us to use empty endif() and similar block terminators
- when building with CMake 2.4. It is allowed by default with 2.6
- already.
-
-2009-07-24 17:28 david.cole
-
- * Tests/CMakeTests/CMakeLists.txt: BUG: Close endif statements with
- same string as if so that it still configures with CMake 2.4. One
- more time. Encore, encore.
-
-2009-07-24 17:12 david.cole
-
- * Tests/CMakeTests/CheckSourceTreeTest.cmake.in: BUG: Improve
- CheckSourceTree test so that it ignores 'U ' output from cvs
- update. Also: improve failure logic for dashboard runs and
- developer runs.
-
-2009-07-24 16:57 king
-
- * Tests/CMakeTests/VariableWatchTest.cmake.in: BUG: Teach
- VariableWatch test to check results
-
- Previously this test was only a smoke test for manual
- verification. This teaches the test to actually check that the
- variable watch succeeds.
-
-2009-07-24 16:53 king
-
- * Source/cmVariableWatchCommand.h: BUG: Keep variable_watch()
- commands in memory
-
- The "Keep only FinalPass commands in memory" commit caused
- instances of this command to be deleted after the InitialPass.
- Even though the variable_watch command does not have a final
- pass, it does need to stay alive because it owns the callback
- information.
-
-2009-07-24 16:31 david.cole
-
- * Tests/CMakeLists.txt: BUG: Close endif statements with same
- string as if so that it still configures with CMake 2.4 -- also
- check for existence of FindCVS.cmake before doing
- find_package(CVS QUIET) also for CMake 2.4 sake...
-
-2009-07-24 16:15 david.cole
-
- * Tests/CMakeLists.txt: BUG: Oops. Left chunk of junk at the bottom
- of the main Tests CMakeLists.txt file with the last commit...
- Sorry.
-
-2009-07-24 15:58 david.cole
-
- * Source/cmGlobalXCodeGenerator.cxx, Tests/CMakeLists.txt,
- Tests/CMakeTests/CMakeLists.txt,
- Tests/CMakeTests/CheckSourceTreeTest.cmake.in: BUG: Additional
- fix necessary for issue #8481 so that Xcode builds do not write
- files into the source tree. Also add a test that runs last to
- check for local modifications in CMake_SOURCE_DIR based on
- whether 'cvs -q -n up -dP' output is empty. Test fails on
- dashboard runs when there are local modifications. Test passes on
- non-dashboard runs with local modifications so that CMake
- developers may have mods when running the test locally.
-
-2009-07-24 13:31 king
-
- * Source/: cmCommand.h, cmConfigureFileCommand.h,
- cmExportLibraryDependencies.h, cmFLTKWrapUICommand.h,
- cmInstallFilesCommand.h, cmInstallProgramsCommand.h,
- cmLoadCommandCommand.cxx, cmMakefile.cxx: ENH: Keep only
- FinalPass commands in memory
-
- In cmMakefile we save all invoked commands so that FinalPass can
- be called on them later. Most commands have no final pass, so we
- should keep only the few that do.
-
-2009-07-24 13:17 king
-
- * CMakeLists.txt, Modules/CMakeLists.txt,
- Modules/Platform/CMakeLists.txt, Templates/CMakeLists.txt: ENH:
- Install all Modules and Templates
-
- This removes the file-wise installation rules for Modules and
- Templates and instead installs the whole directories. This
- approach is much less error-prone. The old approach was left
- from before CMake had the install(DIRECTORY) command.
-
-2009-07-24 12:55 king
-
- * Modules/CMakeLists.txt: BUG: Install new fortran compiler id
- source.
-
- The extension of the id source file was changed from .F90 to .F
- so this fixes the install rule.
-
-2009-07-24 12:15 malaterre
-
- * Source/kwsys/SharedForward.h.in: COMP: Fix compilation of VTK on
- debian/sparc (sparc is a CPU not an OS)
-
-2009-07-24 07:34 king
-
- * Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in: BUG: Avoid case
- change in ImplicitLinkInfo test
-
- Since "get_filename_component(... ABSOLUTE)" retrieves the actual
- case for existing paths on windows, we need to use an obscure
- path for mingw. Otherwise the test can fail just because the
- case of the paths changes.
-
-2009-07-24 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-23 16:19 king
-
- * Modules/CMakeDetermineCompilerABI.cmake: BUG: Skip implicit link
- information on Xcode
-
- Xcode adds extra link directories that point at the build tree,
- so detection of implicit link directories is not reliable. Since
- Fortran is not supported in Xcode we will not need implicit link
- information yet anyway.
-
-2009-07-23 10:07 king
-
- * Tests/CMakeTests/: CMakeLists.txt, ImplicitLinkInfoTest.cmake.in:
- ENH: Create ImplicitLinkInfo test
-
- This tests the internal CMakeParseImplicitLinkInfo.cmake module
- to ensure that implicit link information is extracted correctly.
- The test contains many manually verified examples from a variety
- of systems.
-
-2009-07-23 10:07 king
-
- * Modules/CMakeCCompiler.cmake.in,
- Modules/CMakeCXXCompiler.cmake.in,
- Modules/CMakeDetermineCompilerABI.cmake,
- Modules/CMakeFortranCompiler.cmake.in,
- Modules/CMakeParseImplicitLinkInfo.cmake,
- Modules/Compiler/GNU-C.cmake, Modules/Compiler/GNU-CXX.cmake,
- Modules/Compiler/GNU-Fortran.cmake, Modules/Compiler/HP-C.cmake,
- Modules/Compiler/HP-CXX.cmake, Modules/Compiler/HP-Fortran.cmake,
- Modules/Compiler/MIPSpro-C.cmake,
- Modules/Compiler/MIPSpro-CXX.cmake,
- Modules/Compiler/MIPSpro-Fortran.cmake,
- Modules/Compiler/SunPro-C.cmake,
- Modules/Compiler/SunPro-CXX.cmake,
- Modules/Compiler/SunPro-Fortran.cmake,
- Modules/Compiler/VisualAge-C.cmake,
- Modules/Compiler/VisualAge-CXX.cmake,
- Modules/Compiler/VisualAge-Fortran.cmake,
- Source/cmDocumentVariables.cxx,
- Tests/SystemInformation/SystemInformation.in: ENH: Implicit link
- info for C, CXX, and Fortran
-
- This teaches CMake to detect implicit link information for C,
- C++, and Fortran compilers. We detect the implicit linker search
- directories and implicit linker options for UNIX-like
- environments using verbose output from compiler front-ends. We
- store results in new variables called
-
- CMAKE_<LANG>_IMPLICIT_LINK_LIBRARIES
- CMAKE_<LANG>_IMPLICIT_LINK_DIRECTORIES
-
- The implicit libraries can contain linker flags as well as
- library names.
-
-2009-07-23 10:06 king
-
- * Modules/: CMakeCInformation.cmake, CMakeCXXInformation.cmake,
- CMakeFortranInformation.cmake: ENH: Load platform-independent
- per-compiler files
-
- This teaches the language configuration modules to load
- per-compiler information for each language using the compiler id
- but no system name. They look for modules named
- "Compiler/<id>-<lang>.cmake". Such modules may specify compiler
- flags that do not depend on the platform.
-
-2009-07-23 08:10 king
-
- * Source/cmGetFilenameComponentCommand.cxx: BUG: Fix
- get_filename_component ABSOLUTE mode
-
- This teaches the command to recognize full windows paths when
- built on UNIX. CollapseFullPath knows when the input path is
- relative better than FileIsFullPath because the latter is only
- meant for paths from the host platform.
-
-2009-07-23 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-22 14:22 king
-
- * bootstrap, Source/CMakeLists.txt, Source/cmDefinitions.cxx,
- Source/cmDefinitions.h, Source/cmMakefile.cxx,
- Source/cmMakefile.h: ENH: Improve dynamic variable scope
- implementation
-
- Previously each new variable scope (subdirectory or function
- call) in the CMake language created a complete copy of the
- key->value definition map. This avoids the copy using transitive
- lookups up the scope stack. Results of queries answered by
- parents are stored locally to maintain locality of reference.
-
- The class cmDefinitions replaces cmMakefile::DefinitionsMap, and
- is aware of its enclosing scope. Each scope stores only the
- definitions set (or unset!) inside it relative to the enclosing
- scope.
-
-2009-07-22 13:42 king
-
- * Tests/FunctionTest/SubDirScope/CMakeLists.txt: ENH: Improve
- strictness of Function test
-
- The command "set(... PARENT_SCOPE)" should never affect the
- calling scope. This improves the Function test to check that
- such calls in a subdirectory scope affect the parent but not the
- child.
-
-2009-07-22 12:06 david.cole
-
- * Source/cmCTest.cxx: BUG: Fix typo pointed out by Monsieur
- Francois Bertel. Merci, Francois.
-
-2009-07-22 11:14 david.cole
-
- * Source/cmGlobalXCodeGenerator.cxx: BUG: Fix issue #8481 -
- generate Xcode projects such that breakpoints may be used from
- the Xcode debugger without adjusting any settings within the
- Xcode GUI first... Thanks to Doug Gregor for the patch.
-
-2009-07-22 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-21 12:45 martink
-
- * Modules/FindPNG.cmake: ENH: just converted case to lower for the
- book
-
-2009-07-21 11:58 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Disable color
- makefile inside try-compile
-
- Generated makefiles for try-compile projects should never use
- color output. On MSYS the color escapes end up in the
- try-compile output text because there is no way to identify
- whether the output is going to a color-capable terminal. Instead
- we should just always skip color for try-compile projects.
-
-2009-07-21 10:56 king
-
- * Tests/SystemInformation/DumpInformation.h.in: BUG: Fix
- SystemInformation dump output
-
- When this test was renamed from DumpInformation to
- SystemInformation the configured header that points the dump
- executable to the directory containing information files was
- broken. No information has been dumped by this test for 2 years!
- This fixes it.
-
-2009-07-21 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-20 12:08 david.cole
-
- * CMakeCPackOptions.cmake.in: BUG: Add CPACK_NSIS_PACKAGE_NAME to
- the list of CPack variables that CMake overrides. We use the same
- value as the CPack-provided default, but do it here such that
- configuring with an older CMake will still give us this new
- variable. Necessary so that the CMake release process works with
- the new variable: CMake is configured with a previous CMake, but
- packaged with the freshly built CPack. (This fix is necessary
- because the fix for issue #8682 caused the side effect of having
- an empty CPACK_NSIS_PACKAGE_NAME for the CMake nightly package.)
-
-2009-07-20 10:58 hoffman
-
- * Tests/CMakeLists.txt: ENH: set expected failure for tests
-
-2009-07-20 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-19 13:40 hoffman
-
- * Source/CTest/cmCTestTestHandler.cxx: ENH: fix warning
-
-2009-07-19 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-18 01:05 lowman
-
- * Modules/FindSDL.cmake: BUG: Fix include path detection with
- SDLDIR env var (issue #9086). Also removed some superfluous
- search paths.
-
-2009-07-18 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-17 23:51 lowman
-
- * Modules/FindPerlLibs.cmake: ENH: Also add ARCHLIB/CORE to include
- search paths so perl.h can be found on non-standard install
- prefixes
-
-2009-07-17 23:31 lowman
-
- * Modules/FindPerlLibs.cmake: ENH: Improve detection of
- perl.h/libperl, issue #7898
-
-2009-07-17 16:15 hoffman
-
- * Source/CTest/cmCTestTestHandler.cxx: ENH: fix warning
-
-2009-07-17 14:51 clinton
-
- * Source/QtDialog/CMakeSetupDialog.cxx: ENH: Edit button label for
- new changes dialog.
-
-2009-07-17 14:38 clinton
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, CMakeSetupDialog.h,
- QCMakeCacheView.cxx, QCMakeCacheView.h:
- ENH: Add a "Show my changes" to the Tools menu. Changes
- by the user are recorded and when requested, it shows -D
- arguments for commandline or contents for a cache file.
-
-2009-07-17 10:06 hoffman
-
- * Source/CTest/cmCTestTestHandler.cxx: ENH: compute the max test
- name width based on the length of the tests
-
-2009-07-17 10:05 hoffman
-
- * Source/: cmGlobalGenerator.h, cmGlobalVisualStudioGenerator.h,
- cmLocalGenerator.cxx, cmMakefile.cxx: ENH: make sure GUIDs for
- filters are cached
-
-2009-07-17 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-16 18:53 clinton
-
- * Modules/FindQt4.cmake: BUG: fix relative paths from different
- drives on Windows
-
-2009-07-16 11:48 david.cole
-
- * Modules/: CPack.cmake, NSIS.template.in: BUG: Re-fix issue #8682.
- Use new variable CPACK_NSIS_PACKAGE_NAME in appropriate places
- rather than CPACK_NSIS_DISPLAY_NAME. CPACK_NSIS_DISPLAY_NAME is
- the Add/Remove control panel's description string for the
- installed package. Using it as the "Name" of the NSIS installer
- package made the CMake installer itself use really long strings
- in the installer GUI. This fix still allows for the original
- intent of the first fix for #8682 -- the ability to separate the
- installer name from the default install directory, but it uses a
- new/different variable to achieve the separation.
-
-2009-07-16 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-15 12:43 hoffman
-
- * Modules/Platform/Windows-cl.cmake: ENH: remove debug message
-
-2009-07-15 12:18 hoffman
-
- * Modules/Platform/Windows-cl.cmake: ENH: do not use
- /INCREMENTAL:YES with VS 10 compiler
-
-2009-07-15 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-14 19:34 clinton
-
- * Source/QtDialog/CMakeSetup.cxx:
- BUG: Don't let Qt suppress error dialogs. Add call to
- SetErrorMode(0); See #9258.
-
-2009-07-14 16:06 hoffman
-
- * Source/cmIncludeExternalMSProjectCommand.cxx: ENH: fix vsexternal
- test on vs 71
-
-2009-07-14 15:17 king
-
- * Modules/: CMakeCCompilerId.c.in, CMakeCXXCompilerId.cpp.in,
- CMakeFortranCompilerId.F.in: ENH: Check _SGI_COMPILER_VERSION for
- compiler id
-
- Some SGI compilers define _SGI_COMPILER_VERSION in addition to
- the old _COMPILER_VERSION preprocessor symbol. It is more
- distinctive, so we should check it in case the old one is ever
- removed.
-
-2009-07-14 15:16 king
-
- * Modules/CMakeFortranCompilerId.F.in: BUG: Avoid SGI preprocessor
- bug for Fortran Id
-
- The SGI preprocessor /usr/lib/cpp produces bad output on this
- code:
-
- #if 1
- A
- #elif 1
- B
- #else
- C
- #endif
-
- Both 'A' and 'C' appear in the output! We work around the
- problem by using '#elif 1' instead of '#else'.
-
- This fixes detection of the SGI Fortran compiler id in -o32 mode.
-
-2009-07-14 14:44 alex
-
- * Modules/MacroAddFileDependencies.cmake: STYLE: add documentation
- for MACRO_ADD_FILE_DEPENDENCIES()
-
- Alex
-
-2009-07-14 14:16 hoffman
-
- * Source/cmGlobalVisualStudio6Generator.cxx,
- Source/cmGlobalVisualStudio6Generator.h,
- Source/cmGlobalVisualStudio71Generator.cxx,
- Source/cmGlobalVisualStudio71Generator.h,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.h,
- Source/cmGlobalVisualStudioGenerator.cxx,
- Source/cmGlobalVisualStudioGenerator.h,
- Source/cmIncludeExternalMSProjectCommand.cxx,
- Source/cmLocalGenerator.cxx,
- Source/cmLocalVisualStudio10Generator.cxx,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmVisualStudio10TargetGenerator.cxx,
- Tests/VSExternalInclude/CMakeLists.txt: ENH: remove
- INCLUDE_EXTERNAL_MSPROJECT name hack, and use target properties
- instead, fix VXExternalInclude test for VS10
-
-2009-07-14 10:15 king
-
- * Source/cmSeparateArgumentsCommand.cxx,
- Source/cmSeparateArgumentsCommand.h,
- Tests/CMakeTests/CMakeLists.txt,
- Tests/CMakeTests/SeparateArgumentsTest.cmake.in: ENH: Teach
- separate_arguments() to parse commands
-
- This adds UNIX_COMMAND and WINDOWS_COMMAND modes to the command.
- These modes parse unix- and windows-style command lines.
-
-2009-07-14 10:14 king
-
- * Source/: cmComputeLinkInformation.cxx,
- cmComputeLinkInformation.h: STYLE: Factor
- cmComputeLinkInformation constructor
-
- This factors some code out of the constructor into a new method
- cmComputeLinkInformation::LoadImplicitLinkInfo for readability.
-
-2009-07-14 10:14 king
-
- * Source/: cmOrderDirectories.cxx, cmOrderDirectories.h: STYLE:
- Factor CollectOriginalDirectories code
-
- This factors code out of
- cmOrderDirectories::CollectOriginalDirectories into
- cmOrderDirectories::AddOriginalDirectories. Later a new call
- will be added, and this is more readable anyway.
-
-2009-07-14 08:38 king
-
- * Tests/ExportImport/: CMakeLists.txt, InitialCache.cmake.in: COMP:
- Shorten ExportImport test command lines
-
- The ExportImport test drives its Export and Import projects using
- the same compiler and flags. This converts the ctest
- --build-and-test command lines to use an initial cache file
- instead of passing all settings on the command line.
-
- We need a shorter command line to pass through VS 6 on Win98.
- This approach reduces duplicate code anyway.
-
-2009-07-14 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-13 17:35 king
-
- * Source/kwsys/System.c: BUG: Parse escapes in single-quoted unix
- arguments
-
- This fixes KWSys's unix-style command-line parsing to interpret
- backslash escapes inside single-quoted strings.
-
-2009-07-13 17:08 king
-
- * Source/cmSystemTools.cxx: COMP: Include <malloc.h> for 'free' on
- QNX
-
-2009-07-13 16:58 hoffman
-
- * Source/cmLocalVisualStudio10Generator.cxx,
- Source/cmLocalVisualStudio10Generator.h,
- Source/cmLocalVisualStudio7Generator.h,
- Source/cmVisualStudio10TargetGenerator.cxx,
- Source/cmVisualStudio10TargetGenerator.h,
- Source/cmVisualStudioGeneratorOptions.cxx,
- Tests/PrecompiledHeader/CMakeLists.txt,
- Tests/Preprocess/CMakeLists.txt,
- Tests/VSExternalInclude/CMakeLists.txt: ENH: almost all tests
- passing in vs 10, commit fixes preprocess and starts vs external
- project
-
-2009-07-13 16:46 king
-
- * Source/cmSystemTools.cxx: COMP: Include <stdlib.h> for 'free'
-
-2009-07-13 16:22 king
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Add
- cmSystemTools::ParseUnixCommandLine
-
- This method is a C++ wrapper around the KWSys System library
- function to parse unix-style command lines.
-
-2009-07-13 16:22 king
-
- * Source/kwsys/: ProcessUNIX.c, System.c, System.h.in: ENH: Provide
- unix-sytle command line parsing
-
- Add System_Parse_CommandForUnix to the KWSys System interface as
- a utility to parse a unix-style command line. Move the existing
- implementation out of ProcessUNIX. Add a flags argument reserved
- for future use in providing additional behavior.
-
-2009-07-13 11:24 king
-
- * Modules/: CMakeFortranCompilerABI.F,
- CMakeTestFortranCompiler.cmake: ENH: Create Fortran ABI detection
- framework
-
- This invokes CMakeDetermineCompilerABI.cmake for Fortran at the
- same place it is already done for C and CXX.
-
-2009-07-13 10:46 king
-
- * Modules/ExternalProject.cmake: ENH: Check tarball filename in
- ep_add
-
- This teaches the ExternalProject module to check the download URL
- file name. If it is not a tarball (.tar, .tgz, .tar.gz) it is an
- error because UntarFile does not yet understand other archive
- formats.
-
-2009-07-13 10:46 king
-
- * Modules/UntarFile.cmake: BUG: Teach UntarFile to delete dir on
- error
-
- When tarball extraction fails we should still cleanup the
- temporary extraction directory. Otherwise the next attempt will
- create a new directory and the first one will never be removed.
-
-2009-07-13 10:40 king
-
- * Modules/Platform/Linux-SunPro-CXX.cmake: BUG: Fix rpath-link flag
- for SunPro C++ on Linux
-
- This teaches Modules/Platform/Linux-SunPro-CXX.cmake the
- -rpath-link flag. The SunPro C++ compiler does not have a '-Wl,'
- option, so we just pass the flag directly.
-
- This problem was exposed by the ExportImport test now that it
- links an executable through the C++ compiler with the -rpath-link
- flag.
-
-2009-07-13 09:20 king
-
- * Tests/ExportImport/Export/: CMakeLists.txt, testLib6.c,
- testLib6c.c: COMP: Fix ExportImport testLib6 on VS6
-
- The compiler does not support multiple source files differing
- only by extension in one target. This renames the C source file
- in the test.
-
-2009-07-13 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-12 14:52 alex
-
- * Tests/CMakeLists.txt: BUG: disable the test for now, will make it
- work correctly later
-
- Alex
-
-2009-07-12 04:51 alex
-
- * Source/CTest/cmCTestScriptHandler.cxx, Tests/CMakeLists.txt,
- Modules/CTestScriptMode.cmake,
- Tests/CTestScriptMode/CTestTestScriptMode.cmake.in: STYLE: don't
- load CMakeDetermineSystem and CMakeSystemSpecific directly from
- cmCTestScriptHandler, but have it load the new script
- CTestScriptMode.cmake -> that makes it more flexible, also add a
- simple test that the system name has been determined correctly
-
- Alex
-
-2009-07-12 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-11 16:30 alex
-
- * Source/CTest/: cmCTestScriptHandler.cxx, cmCTestScriptHandler.h:
- STYLE: move the code for writing the initial cache into its own
- separate function, makes the long ProcessHandler() a little bit
- shorter
-
- Alex
-
-2009-07-11 16:27 alex
-
- * Source/CTest/: cmCTestScriptHandler.cxx, cmCTestScriptHandler.h:
- STYLE: rename InitCache to InitialCache, since it contains the
- contents for the initial cache and is not e.g. a flag which shows
- whether the cache should be initialized
-
- Alex
-
-2009-07-11 10:12 king
-
- * Source/: cmExportFileGenerator.cxx, cmTarget.cxx: ENH: Export and
- import link interface languages
-
- Now that languages are part of the link interface of a target we
- need to export/import the information. A new
- IMPORTED_LINK_INTERFACE_LANGUAGES property and per-config
- IMPORTED_LINK_INTERFACE_LANGUAGES_<CONFIG> property specify the
- information for imported targets. The export() and
- install(EXPORT) commands automatically set the properties.
-
-2009-07-11 10:10 king
-
- * Tests/ExportImport/: CMakeLists.txt, Export/CMakeLists.txt,
- Export/testLib6.c, Export/testLib6.cxx, Import/CMakeLists.txt,
- Import/A/CMakeLists.txt, Import/A/imp_testExe1.c: ENH: Test
- export/import of link interface languages
-
- This extends the ExportImport test. The Export project creates a
- C++ static library and exports it. Then the Import project links
- the library into a C executable. On most platforms the
- executable will link only if the C++ linker is chosen correctly.
-
-2009-07-11 00:05 hoffman
-
- * Source/cmLocalGenerator.h, Source/cmMakefile.cxx,
- Source/cmSourceGroup.cxx, Source/cmSourceGroup.h,
- Source/cmVisualStudio10TargetGenerator.cxx,
- Source/cmVisualStudio10TargetGenerator.h,
- Tests/SourceGroups/CMakeLists.txt, Tests/SourceGroups/README.txt:
- ENH: add group support and fix borland error
-
-2009-07-11 00:01 kwrobot
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-10 16:51 king
-
- * Source/: cmGlobalGenerator.h, cmGlobalXCodeGenerator.cxx,
- cmGlobalXCodeGenerator.h: BUG: Fix Xcode linker language
-
- Xcode does not seem to support direct requests for using the
- linker for a particular language. It always infers the linker
- using the languages in the source files. When no user source
- files compile with target's linker language we add one to help
- Xcode pick the linker.
-
- A typical use case is when a C executable links to a C++ archive.
- The executable has no C++ source files but we need to use the
- C++ linker.
-
-2009-07-10 13:53 king
-
- * Source/cmTarget.cxx: ENH: Update LINKER_LANGUAGE and HAS_CXX docs
-
- This updates the documentation of these properties to account for
- the new automatic linker language computation.
-
-2009-07-10 13:53 king
-
- * Tests/: CMakeLists.txt, LinkLanguage/CMakeLists.txt,
- LinkLanguage/LinkLanguage.c, LinkLanguage/foo.cxx: ENH: Test
- transitive link languages
-
- This test creates a C executable that links to a C++ static
- library. On most platforms the executable will not link unless
- the C++ linker is chosen correctly.
-
-2009-07-10 13:53 king
-
- * Source/: cmTarget.cxx, cmTarget.h: ENH: Consider link
- dependencies for link language
-
- This teaches cmTarget to account for the languages compiled into
- link dependencies when determining the linker language for its
- target.
-
- We list the languages compiled into a static archive in its link
- interface. Any target linking to it knows that the runtime
- libraries for the static archive's languages must be available at
- link time. For now this affects only the linker language
- selection, but later it will allow CMake to automatically list
- the language runtime libraries.
-
-2009-07-10 13:08 king
-
- * Source/CTest/cmCTestHG.cxx: COMP: Fix cmCTestHG for old HP
- compiler
-
- The compiler does not have a fully compliant std::string.
-
-2009-07-10 12:26 hoffman
-
- * Source/cmVisualStudio10TargetGenerator.cxx: ENH: change so rules
- show up in GUI, must be windows path
-
-2009-07-10 11:07 king
-
- * Modules/CTest.cmake, Source/CMakeLists.txt,
- Source/CTest/cmCTestHG.cxx, Source/CTest/cmCTestHG.h,
- Source/CTest/cmCTestUpdateCommand.cxx,
- Source/CTest/cmCTestUpdateHandler.cxx,
- Source/CTest/cmCTestUpdateHandler.h, Tests/CMakeLists.txt,
- Tests/CTestUpdateHG.cmake.in: ENH: Teach CTest to handle
- Mercurial repositories
-
- This creates cmCTestHG to drive CTest Update handling on hg-based
- work trees. Currently we always update to the head of the remote
- tracking branch (hg pull), so the nightly start time is ignored
- for Nightly builds. A later change will address this.
-
- See issue #7879. Patch from Emmanuel Christophe. I modified the
- patch slightly for code style, to finish up some parsing details,
- and to fix the test.
-
-2009-07-10 11:07 king
-
- * Source/cmProcessTools.h: ENH: New OutputParser::Process()
- signature
-
- This overload accepts a null-terminated string instead of
- requiring a length. It is useful to pass some fake process
- output before and after the real process output.
-
-2009-07-10 09:53 david.cole
-
- * CTestCustom.cmake.in: COMP: Mask out shadowed declaration
- warnings that always follow already masked Utilities/cmtar
- warnings.
-
-2009-07-10 09:12 hoffman
-
- * Modules/CMakeVS10FindMake.cmake, Source/cmCTest.cxx,
- Source/cmGlobalVisualStudio10Generator.cxx,
- Source/cmGlobalVisualStudio10Generator.h,
- Source/cmGlobalVisualStudio71Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.h,
- Source/cmGlobalVisualStudioGenerator.cxx,
- Source/cmLocalVisualStudio10Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h,
- Source/cmLocalVisualStudioGenerator.cxx,
- Source/cmLocalVisualStudioGenerator.h, Source/cmTarget.cxx,
- Source/cmVisualStudio10TargetGenerator.cxx,
- Source/cmVisualStudio10TargetGenerator.h,
- Tests/Complex/Library/CMakeLists.txt,
- Tests/ComplexOneConfig/Library/CMakeLists.txt,
- Tests/ComplexRelativePaths/Library/CMakeLists.txt: ENH: only 5
- failing tests for VS 10
-
-2009-07-10 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-09 14:15 king
-
- * Source/kwsys/SharedForward.h.in: COMP: More KWSys SharedForward
- pointer const-ness
-
- This adds another cast to avoid pointer conversion warnings.
- Unfortunately C does not recognize implicit conversions that add
- cv-qualifiers as well as C++ does.
-
-2009-07-09 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-08 16:18 david.cole
-
- * Source/kwsys/MD5.c: COMP: Eliminate "conversion may change sign
- of result" warnings by using size_t where appropriate. (Missed
- one warning with last commit: add a cast to md5_word_t.)
-
-2009-07-08 16:15 david.cole
-
- * Source/kwsys/MD5.c: COMP: Eliminate "conversion may change sign
- of result" warnings by using size_t where appropriate.
-
-2009-07-08 15:09 king
-
- * Source/kwsys/SharedForward.h.in: COMP: Fix KWSys SharedForward
- sign conversion
-
- This uses size_t where necessary to avoid size_t/int conversion
- warnings.
-
-2009-07-08 15:09 king
-
- * Source/kwsys/SharedForward.h.in: COMP: Fix KWSys SharedForward
- pointer const-ness
-
- This adds const-ness and casts where necessary to avoid pointer
- conversion warnings.
-
-2009-07-08 14:43 david.cole
-
- * CTestCustom.cmake.in: COMP: Suppress warnings from the
- Utilities/cmtar code in dashboard results.
-
-2009-07-08 14:33 king
-
- * Source/: cmDocumentVariables.cxx, cmTarget.cxx: BUG: Use link
- language for target name computation
-
- The commit "Do not compute link language for LOCATION" was wrong.
- The variables
-
- CMAKE_STATIC_LIBRARY_PREFIX_Java
- CMAKE_STATIC_LIBRARY_SUFFIX_Java
-
- are used for building Java .jar files. This commit re-enables
- the feature and documents the variables:
-
- CMAKE_EXECUTABLE_SUFFIX_<LANG>
- CMAKE_IMPORT_LIBRARY_PREFIX_<LANG>
- CMAKE_IMPORT_LIBRARY_SUFFIX_<LANG>
- CMAKE_SHARED_LIBRARY_PREFIX_<LANG>
- CMAKE_SHARED_LIBRARY_SUFFIX_<LANG>
- CMAKE_SHARED_MODULE_PREFIX_<LANG>
- CMAKE_SHARED_MODULE_SUFFIX_<LANG>
- CMAKE_STATIC_LIBRARY_PREFIX_<LANG>
- CMAKE_STATIC_LIBRARY_SUFFIX_<LANG>
-
- Instead of making separate, repetitive entries for the _<LANG>
- variable documentation, we just mention the per-language name in
- the text of the platform-wide variable documentation. Internally
- we keep undocumented definitions of these properties to satisfy
- CMAKE_STRICT mode.
-
-2009-07-08 13:03 king
-
- * Source/: cmComputeLinkInformation.cxx,
- cmGlobalXCodeGenerator.cxx, cmLocalVisualStudio7Generator.cxx,
- cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx, cmTarget.cxx, cmTarget.h,
- cmVisualStudio10TargetGenerator.cxx: ENH: Pass config to
- cmTarget::GetLinkerLanguage
-
- This passes the build configuration to most GetLinkerLanguage
- calls. In the future the linker language will account for
- targets linked in each configuration.
-
-2009-07-08 13:03 king
-
- * Source/: cmComputeLinkInformation.cxx,
- cmGlobalUnixMakefileGenerator3.cxx, cmInstallTargetGenerator.cxx,
- cmLocalUnixMakefileGenerator3.cxx,
- cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx, cmTarget.cxx, cmTarget.h:
- ENH: Pass config to cmTarget RPATH install methods
-
- This passes the build configuration to cmTarget methods
- IsChrpathUsed and NeedRelinkBeforeInstall. Later these methods
- will use the value.
-
-2009-07-08 13:03 king
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: Use fixed header file
- type mapping for Xcode
-
- This simplifies computation of the lastKnownFileType attribute
- for header files in Xcode projects. We now use a fixed mapping
- from header file extension to attribute value. The value is just
- a hint to the Xcode editor, so computing the target linker
- language is overkill.
-
-2009-07-08 13:03 king
-
- * Source/: cmDocumentVariables.cxx, cmTarget.cxx: ENH: Do not
- compute link language for LOCATION
-
- The LOCATION property requires the full file name of a target to
- be computed. Previously we computed the linker language for a
- target to look up variables such as
- CMAKE_SHARED_LIBRARY_SUFFIX_<LANG>. This led to locating all the
- source files immediately instead of delaying the search to
- generation time. In the future even more computation will be
- needed to get the linker language, so it is better to avoid it.
-
- The _<LANG> versions of these variables are undocumented, not set
- in any platform file we provide, and do not produce hits in
- google. This change just removes the unused feature outright.
-
-2009-07-08 12:04 king
-
- * Source/: cmComputeLinkDepends.cxx, cmTarget.cxx, cmTarget.h: ENH:
- Introduce cmTarget::LinkImplementation API
-
- The new method centralizes loops that process raw
- OriginalLinkLibraries to extract the link implementation
- (libraries linked into the target) for each configuration.
- Results are computed on demand and then cached. This simplifies
- link interface computation because the default case trivially
- copies the link implementation.
-
-2009-07-08 11:41 king
-
- * Tests/: Complex/CMakeLists.txt, ComplexOneConfig/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt,
- Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt,
- CustomCommand/CMakeLists.txt, Dependency/CMakeLists.txt,
- Dependency/Case4/CMakeLists.txt,
- ExportImport/Export/CMakeLists.txt,
- ExportImport/Import/CMakeLists.txt, FunctionTest/CMakeLists.txt,
- LoadCommand/CMakeCommands/CMakeLists.txt,
- LoadCommandOneConfig/CMakeCommands/CMakeLists.txt,
- MacroTest/CMakeLists.txt, MakeClean/CMakeLists.txt,
- Plugin/CMakeLists.txt, Preprocess/CMakeLists.txt,
- ReturnTest/CMakeLists.txt, RuntimePath/CMakeLists.txt,
- SourceGroups/CMakeLists.txt: ENH: Remove CMAKE_ANSI_CFLAGS from
- tests
-
- As of CMake 2.6 this variable is not defined, and the ANSI flags
- for the HP compiler are simply hard-coded in the default C flags.
-
-2009-07-08 09:14 king
-
- * Modules/CMakeDetermineCCompiler.cmake: ENH: Identify HP C
- compiler
-
- This compiler does not enable ANSI mode by default. When
- identifying the C compiler we try passing -Aa in case it is the
- HP compiler.
-
-2009-07-08 08:31 king
-
- * Source/: cmTarget.cxx, cmTarget.h: COMP: Pimplize cmTarget
- ImportInfo and OutputInfo
-
- These member structures are accessed only in the cmTarget
- implementation so they do not need to be defined in the header.
- This cleanup also aids Visual Studio 6 in compiling them.
-
-2009-07-08 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-07 14:02 alex
-
- * Source/cmExtraCodeBlocksGenerator.cxx: ENH: get the build type
- specific location
-
- Alex
-
-2009-07-07 11:30 king
-
- * Source/cmTarget.cxx: BUG: Do not recompute link interfaces
-
- The config-to-interface map in cmTarget should use
- case-insensitive configuration names. The change avoids
- repeating work if the given configuration has a different case
- than one already computed.
-
-2009-07-07 10:57 king
-
- * Source/cmTarget.cxx: BUG: Fix CMP0003 wrong-config link dir
- support
-
- This fixes a dumb logic error introduced by the centralization of
- link interface computation. It prevented link directories from
- alternate configurations from getting listed by the OLD behavior
- of CMP0003 for targets linked as transitive dependencies.
-
-2009-07-07 10:56 king
-
- * Source/cmTarget.h: STYLE: Fix comment on cmTarget::LinkInterface
-
- The comment had a typo and was longer than necessary.
-
-2009-07-07 09:45 king
-
- * Source/: cmComputeLinkDepends.cxx, cmExportFileGenerator.cxx,
- cmTarget.cxx, cmTarget.h: ENH: Simplify cmTarget link interface
- storage
-
- This makes the LinkInterface struct a member of cmTarget,
- pimplizes the config-to-interface map, and stores interface
- instances by value.
-
-2009-07-07 07:44 king
-
- * Source/: cmComputeLinkInformation.cxx,
- cmGlobalXCodeGenerator.cxx, cmLocalGenerator.cxx,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx,
- cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx, cmTarget.cxx, cmTarget.h,
- cmVisualStudio10TargetGenerator.cxx: ENH: Simpler
- cmTarget::GetLinkerLanguage signature
-
- This method previously required the global generator to be
- passed, but that was left from before cmTarget had its Makefile
- member. Now the global generator can be retrieved automatically,
- so we can drop the method argument.
-
-2009-07-07 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-06 16:25 king
-
- * Source/: cmComputeLinkDepends.cxx, cmComputeLinkDepends.h,
- cmExportFileGenerator.cxx, cmExportFileGenerator.h, cmTarget.cxx,
- cmTarget.h: ENH: Centralize default link interface computation
-
- When LINK_INTERFACE_LIBRARIES is not set we use the link
- implementation to implicitly define the link interface. These
- changes centralize the decision so that all linkable targets
- internally have a link interface.
-
-2009-07-06 16:24 king
-
- * Source/: cmComputeLinkDepends.cxx, cmComputeLinkDepends.h,
- cmTarget.cxx, cmTarget.h: ENH: Move CMP0004 check into cmTarget
-
- This moves code implementing policy CMP0004 into
- cmTarget::CheckCMP0004. The implementation is slightly simpler
- and can be re-used outside of cmComputeLinkDepends.
-
-2009-07-06 16:24 king
-
- * Source/: cmTarget.cxx, cmTarget.h: ENH: Exception safe link
- interface computation
-
- This fixes cmTarget::GetLinkInterface to compute and return the
- link interface in an exception-safe manner. We manage the link
- interface returned by cmTarget::ComputeLinkInterface using
- auto_ptr.
-
-2009-07-06 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-05 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-04 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-03 10:34 king
-
- * Source/: cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx: ENH: Pass config to
- cmTarget::GetDirectory()
-
- This teaches the makefile generators to always pass the
- configuration name to the cmTarget::GetDirectory method. Later
- this will allow per-configuration target output directories, and
- it cleans up use of the current API.
-
-2009-07-03 10:33 king
-
- * Source/: cmTarget.cxx, cmTarget.h: ENH: Refactor target output
- dir computation
-
- This creates cmTarget::GetOutputInfo to compute, cache, and
- lookup target output directory information on a per-configuration
- basis. It avoids re-computing the information every time it is
- needed.
-
-2009-07-03 10:33 king
-
- * Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Templates/UtilityHeader.dsptemplate: BUG: Avoid
- cmTarget::GetDirectory for utilities
-
- Since utility targets have no main output files like executables
- or libraries, they do not define an output directory. This
- removes a call to cmTarget::GetDirectory from
- cmLocalVisualStudio{6,7}Generator for such targets.
-
-2009-07-03 10:33 king
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: STYLE: Replace large if() with
- named boolean
-
- In cmLocalVisualStudio{6,7}Generator this replaces a large if()
- test with a re-usable result stored in a boolean variable named
- accordingly.
-
-2009-07-03 08:41 king
-
- * Source/: cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx, cmMakefileTargetGenerator.h: ENH:
- Create cmMakefileTargetGenerator::ConfigName
-
- This member stores the build configuration for which Makefiles
- are being generated. It saves repeated lookup of the equivalent
- member from cmLocalUnixMakefileGenerator3, making code shorter
- and more readable.
-
-2009-07-03 08:40 king
-
- * Source/: cmInstallTargetGenerator.cxx,
- cmInstallTargetGenerator.h: ENH: Cleanup per-config target
- install generation
-
- This cleans up cmInstallTargetGenerator's code that computes the
- build tree location of a target under each configuration.
-
-2009-07-03 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-02 17:38 david.cole
-
- * Modules/ExternalProject.cmake: BUG: Allow arbitrary text in
- values for some keywords. (And avoid warning that the arbitrary
- text is an unknown keyword.)
-
-2009-07-02 16:13 king
-
- * Source/CTest/cmCTestTestHandler.cxx: ENH: Reports "Passed" for
- WILL_FAIL tests
-
- Previously tests marked with WILL_FAIL have been reported by
- CTest as
-
- ...............***Failed - supposed to fail
-
- when they correctly failed. Now we just report ".....Passed"
- because there is no reason to draw attention to something that
- works as expected.
-
-2009-07-02 14:14 king
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h:
- BUG: Do not generate "global" Xcode config
-
- Xcode 2.0 and below supported only one configuration, but 2.1 and
- above support multiple configurations. In projects for the
- latter version we have been generating a "global" set of
- buildSettings for each target in addition to the
- per-configuration settings. These global settings are not used
- by Xcode 2.1 and above, so we should not generate them.
-
-2009-07-02 14:13 king
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h:
- ENH: Simplify Xcode CreateBuildSettings method
-
- The cmGlobalXCodeGenerator::CreateBuildSettings had the three
- arguments productName, productType, and fileType that returned
- information used by only one of the call sites. This change
- refactors that information into separate methods named
- accordingly.
-
-2009-07-02 14:13 king
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: Use logical target names
- in Xcode projects
-
- Previously we named Xcode targets using the output file name from
- one of the configurations. This is not very friendly, especially
- because it changes with CMAKE_BUILD_TYPE. Instead we should use
- the original logical target names for the Xcode target names.
- This is also consistent with the way the other IDE generators
- work.
-
-2009-07-02 13:17 david.cole
-
- * Modules/ExternalProject.cmake: BUG: cmd_set logic was missing
- from update and patch steps. Fix it so that UPDATE_COMMAND ""
- means "no update step even though this is a CVS/SVN
- repository..."
-
-2009-07-02 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-07-01 14:29 king
-
- * Tests/CMakeLists.txt: BUG: Skip CTest.Update* for cygwin tools on
- Windows
-
- These tests cannot run with cygwin tools unless testing cygwin
- CTest. The version control tools do not understand all Windows
- paths.
-
-2009-07-01 13:48 david.cole
-
- * Tests/ExternalProject/CMakeLists.txt: BUG: Exclude svn portions
- of ExternalProject test when: svn client version is less than 1.2
- or cygwin/non-cygwin mismatch detected -- avoids ExternalProject
- test failures on dash5 and dash22-cygwin. Also, non-code change:
- allow cvslock through Windows firewall to prevent ExternalProject
- test failure on dash1vista32.
-
-2009-07-01 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-30 09:10 king
-
- * Source/cmVS10CLFlagTable.h: STYLE: Fix line-too-long style
- violation.
-
-2009-06-30 09:05 king
-
- * Source/cmDocumentVariables.cxx: BUG: Fix documentation of
- CMAKE_CFG_INTDIR
-
- The documentation of this variable was out-dated and misleading.
- See issue #9219.
-
-2009-06-30 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-29 14:27 alex
-
- * Source/cmExtraCodeBlocksGenerator.cxx: COMP: don't use
- vector::at(), this doesn't seem to exist everyhwere
- (http://www.cdash.org/CDash/viewBuildError.php?buildid=366375)
-
- Alex
-
-2009-06-29 13:02 king
-
- * Source/: cmGlobalXCode21Generator.cxx,
- cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h: ENH:
- Generate native Xcode 3.0 and 3.1 projects
-
- CMake previously generated Xcode project files labeled as
- 2.4-compatible by recent versions of Xcode (3.0 and 3.1). It is
- better to generate native Xcode 3.0 and 3.1 projects. In
- particular, this can improve build times by using the "Build
- independent targets in parallel" feature.
-
- Patch from Doug Gregor. See issue #9216.
-
-2009-06-29 10:46 david.cole
-
- * Tests/ExternalProject/CMakeLists.txt: BUG: Avoid running the cvs
- portions of the ExternalProject test on non-cygwin builds that
- are using cygwin cvs.exe.
-
-2009-06-29 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-28 09:46 hoffman
-
- * Source/cmVisualStudio10TargetGenerator.h: ENH: add rest of lib
- check
-
-2009-06-28 08:59 hoffman
-
- * Source/cmVisualStudio10TargetGenerator.cxx: ENH: fix line length
-
-2009-06-28 08:06 alex
-
- * Source/cmConfigureFileCommand.h: STYLE: document #cmakedefine01
- (see #9189 , there's also a test for it in Tests/Complex/ )
-
- Alex
-
-2009-06-28 08:05 alex
-
- * Source/cmDocumentationFormatterText.cxx: STYLE: don't print the
- section name "SingleItem" if the documentation for just a single
- item is printed
-
- Alex
-
-2009-06-28 05:59 alex
-
- * Modules/CMakeFindEclipseCDT4.cmake: BUG: recognize system include
- paths also when the languages are set to something different from
- "C", by resetting them to "C" (#9122)
-
- Alex
-
-2009-06-28 04:58 alex
-
- * Source/cmExtraCodeBlocksGenerator.cxx: ENH: create a "Virtual
- Folder" in CodeBlocks, which contains all the cmake files of the
- project, i.e. there is now a "CMake Files" folder additionally to
- the "Sources", "Headers" and "Others" folders which already
- existed. Patch by Daniel Teske.
-
- Alex
-
-2009-06-28 04:30 alex
-
- * Source/cmExtraCodeBlocksGenerator.cxx: ENH: also support nmake
- and msvc for use with CodeBlocks under Windows, patch by Daniel
- Teske
-
- Alex
-
-2009-06-28 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-27 11:17 alex
-
- * Source/cmDocumentVariables.cxx: STYLE: document
- CMAKE_SKIP_INSTALL_ALL_DEPENDENCY variable
-
- Alex
-
-2009-06-27 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-26 13:00 david.cole
-
- * Tests/ExternalProject/: CMakeLists.txt, svnrepo.tgz: BUG:
- Downgrade svn repository to be created with an svn 1.2
- installation (rather than 1.4) so that it works (hopefully) with
- more svn clients in the wild. Change time stamps of test projects
- in CMakeLists.txt to reflect times available in newly created
- repository. Add UPDATE_COMMAND "" for checkouts that are
- tag-based or date-stamp-based to avoid unnecessary update steps.
-
-2009-06-26 11:50 hoffman
-
- * Source/: cmGlobalVisualStudio10Generator.h, cmVS10CLFlagTable.h,
- cmVS10LibFlagTable.h, cmVS10LinkFlagTable.h,
- cmVisualStudio10TargetGenerator.cxx, cmparseMSBuildXML.py: ENH:
- fix line length issues
-
-2009-06-26 11:32 david.cole
-
- * Tests/ExternalProject/CMakeLists.txt: ENH: Do not unzip the local
- repositories unless CVS and SVN executables are available. Add
- 'configure' step to the repository extraction 'projects' to print
- the version number of CVS and SVN in the dashboard test/build
- output.
-
-2009-06-26 10:18 hoffman
-
- * CMakeCPackOptions.cmake.in,
- Source/QtDialog/QtDialogCPack.cmake.in: ENH: do not create a
- desktop link for CMakeSetup
-
-2009-06-26 10:00 hoffman
-
- * Utilities/KWStyle/CMake.kws.xml.in: ENH: 80 is fine, i guess not
-
-2009-06-26 09:59 hoffman
-
- * Utilities/KWStyle/CMake.kws.xml.in: ENH: 80 is fine
-
-2009-06-26 09:55 david.cole
-
- * Tests/ExternalProject/CMakeLists.txt: ENH: Revise the
- ExternalProject test to use local CVS and SVN repositories to
- avoid network activity. Also: stop building KWStyle and kwsys as
- part of this test to reduce the amount of time spent running the
- test. Instead, build TutorialStep1 as retrieved from the new
- local repositories with various tags, date stamps and revision
- numbers.
-
-2009-06-26 00:07 hoffman
-
- * Source/cmVisualStudio10TargetGenerator.cxx: ENH: remove debug
- print
-
-2009-06-26 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-25 22:53 hoffman
-
- * Source/: cmVisualStudio10TargetGenerator.cxx,
- cmVisualStudio10TargetGenerator.h: ENH: add obj file support and
- remove a warning
-
-2009-06-25 16:41 hoffman
-
- * CompileFlags.cmake, Modules/CMakeVS10FindMake.cmake,
- Source/CMakeLists.txt, Source/cmGlobalGenerator.cxx,
- Source/cmGlobalVisualStudio10Generator.cxx,
- Source/cmGlobalVisualStudio10Generator.h,
- Source/cmGlobalVisualStudio71Generator.cxx,
- Source/cmListFileLexer.c, Source/cmLocalGenerator.h,
- Source/cmLocalVisualStudio10Generator.cxx,
- Source/cmLocalVisualStudio10Generator.h,
- Source/cmLocalVisualStudio7Generator.h,
- Source/cmLocalVisualStudioGenerator.h, Source/cmMakefile.cxx,
- Source/cmVS10CLFlagTable.h, Source/cmVS10LibFlagTable.h,
- Source/cmVS10LinkFlagTable.h,
- Source/cmVisualStudio10TargetGenerator.cxx,
- Source/cmVisualStudio10TargetGenerator.h,
- Source/cmVisualStudioGeneratorOptions.cxx,
- Source/cmVisualStudioGeneratorOptions.h, Source/cmake.cxx,
- Source/cmparseMSBuildXML.py, Source/kwsys/ProcessWin32.c: ENH:
- first pass at VS 10, can bootstrap CMake, but many tests still
- fail
-
-2009-06-25 16:39 hoffman
-
- * Source/CTest/cmCTestScriptHandler.cxx: ENH: add reminder comment
-
-2009-06-25 16:38 hoffman
-
- * Source/CTest/cmCTestSubmitHandler.cxx: ENH: set an upload speed
- limit for ctest
-
-2009-06-25 12:03 david.cole
-
- * Tests/ExternalProject/: cvsrepo.tgz, svnrepo.tgz: ENH: Add *.tgz
- files of cvs and svn repositories containing the TutorialStep1
- project to test cvs and svn capabilities of ExternalProject
- without requiring network activity.
-
-2009-06-25 10:51 king
-
- * Tests/CMakeLists.txt: BUG: Fix CTest.UpdateBZR tests to run in
- parallel
-
- The UpdateBZR and UpdateBZR.CLocale tests should run in different
- directories so that they can be executed in parallel.
-
-2009-06-25 09:58 king
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h, cmMakefileTargetGenerator.cxx,
- cmMakefileTargetGenerator.h: ENH: Cleanup make progress rule
- generation code
-
- This cleans up the Makefile generator's progress rule code.
- Instead of keeping every cmMakefileTargetGenerator instance alive
- to generate progress, we keep only the information necessary in a
- single table. This approach keeps most of the code in
- cmGlobalUnixMakefileGenerator3, thus simplifying its public
- interface.
-
-2009-06-25 09:43 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: STYLE: Remove unused
- variable
-
-2009-06-25 08:45 king
-
- * Modules/: CMakeDetermineFortranCompiler.cmake,
- CMakeFortranCompilerId.F.in, CMakeFortranCompilerId.F90.in: ENH:
- Identify Fortran compilers with fixed format
-
- This enhances the Fortran compiler id detection by using a source
- that can compile either as free or fixed format. As long as the
- compiler knows it should preprocess the source file (.F) the
- identification can work. Even free-format compilers may try
- fixed-format parsing if the user specifies certain flags, so we
- must support both.
-
-2009-06-25 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-24 16:50 clinton
-
- * Source/QtDialog/CMakeSetupDialog.cxx:
- ENH: Save/restore splitter sizes. Fixes #9070.
-
-2009-06-24 15:09 king
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Remove unused
- cmSystemTools::RemoveEscapes
-
- The RemoveEscapes method is no longer used anywhere. All uses of
- it have been replaced by a real lexer. We can remove the method.
-
-2009-06-24 15:03 king
-
- * Modules/ExternalProject.cmake,
- Tests/ExternalProject/CMakeLists.txt: ENH: New
- ExternalProject.cmake module interface
-
- This creates new module ExternalProject.cmake to replace the
- prototype AddExternalProject.cmake module. The interface is more
- refined, more flexible, and better documented than the prototype.
-
- This also converts the ExternalProject test to use the new
- module. The old module will be removed (it was never in a CMake
- release) after projects using it have been converted to the new
- module.
-
-2009-06-24 14:48 king
-
- * Tests/CMakeLists.txt: BUG: Extend timeout of ExternalProject test
-
- This test requires a long time on slower machines, so we need to
- extend its timeout. It is an important test, so it does not fall
- under the CMAKE_RUN_LONG_TESTS option. In the future we should
- try to shorten the test by building simpler external projects.
-
-2009-06-24 13:24 king
-
- * Source/cmTargetLinkLibrariesCommand.h: ENH: Mention cycles in
- target_link_libraries docs
-
- This documents CMake's support for cycles in the dependency graph
- of STATIC libraries.
-
-2009-06-24 09:36 king
-
- * Source/: cmMakefile.cxx, cmSourceFile.cxx, cmTarget.cxx: ENH:
- Clarify COMPILE_DEFINITIONS separator in docs
-
- The COMPILE_DEFINITIONS properties are semicolon-separated lists.
- Make this clear in the documentation. See issue #9199.
-
-2009-06-24 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-23 16:40 hoffman
-
- * Modules/FindBoost.cmake: ENH: boost lib is often found under the
- boost include dir
-
-2009-06-23 16:31 hoffman
-
- * Modules/FindBoost.cmake: ENH: add additional place to look for
- boost so it works out of the box on windows
-
-2009-06-23 12:58 martink
-
- * Tests/Tutorial/: Step5/MathFunctions/MakeTable.cxx,
- Step6/MathFunctions/MakeTable.cxx,
- Step7/MathFunctions/MakeTable.cxx: ENH: fix spelling mistake
-
-2009-06-23 09:06 king
-
- * Source/CTest/cmCTestCVS.cxx: BUG: Fix CVS update parsing for
- TortoiseCVS
-
- The TortoiseCVS version of cvs.exe includes the '.exe' in cvs
- update messages for files removed from the repository. This
- change accounts for it in the regular expressions that match such
- lines. Now removed files are properly reported by ctest_update()
- when using TortoiseCVS.
-
-2009-06-23 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-22 16:25 king
-
- * Tests/: CMakeLists.txt, CTestUpdateCVS.cmake.in: ENH: Auto-enable
- CTest.UpdateCVS test on Windows
-
- The test needs to create a cvs repository with 'cvs init', but
- the CVSNT client on Windows needs 'cvs init -n' to avoid
- administrator access. Previously we required users to explicitly
- enable CTEST_TEST_UPDATE_CVS to activate the test on Windows.
-
- This teaches the test to use the '-n' option when necessary. Now
- we can enable the test in all cases except when trying to use a
- cygwin cvs.exe without cygwin paths.
-
-2009-06-22 14:19 king
-
- * Source/kwsys/Configure.h.in: COMP: Quiet aggressive Borland
- warnings in KWSys
-
- This disables Borland warning 8027 while compiling KWSys source
- files. It provides no useful information.
-
-2009-06-22 14:19 king
-
- * Source/kwsys/SystemTools.cxx: COMP: Remove useless variable
- assignment
-
- This removes an assignment whose result is never used, thus
- quieting a warning from Borland.
-
-2009-06-22 10:02 hoffman
-
- * Modules/CMakeTestCCompiler.cmake: BUG: remove warning in test of
- compiler so -Werror does not fail
-
-2009-06-22 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-21 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-20 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-19 17:09 king
-
- * Modules/Platform/HP-UX.cmake: BUG: Look in arch-specific HPUX
- implicit link dirs
-
- On HP-UX machines some system libraries appear in
- architecture-specific implicit linker search paths. We need to
- add these paths to our system library search path. However, at
- the time we construct the search path we do not know the target
- architecture.
-
- A full solution requires re-organizing platform configuration
- files so that the target architecture can be known when needed.
- Until that happens we can avoid the problem by searching in both
- 32-bit and 64-bit implicit link directories. By telling CMake
- that they are implicit directories the generated link lines will
- never pass the paths, leaving the linker free to find the library
- of the proper architecture even if the find_library call finds
- the wrong one.
-
-2009-06-19 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-18 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-17 14:18 king
-
- * Source/cmPolicies.cxx: ENH: Improve CMP0012 doc and message
- formatting
-
- This fixes the CMP0012 description to have a one-line summary in
- the 'brief' section and the rest of the explanation in the 'full'
- section. It makes the warning message shorter and improves
- formatting of the policy documentation, especially in the HTML
- pages. The convention is already used by all other policies.
-
-2009-06-17 14:18 king
-
- * Source/cmIfCommand.cxx: ENH: Improve format of if() command
- messages
-
- Errors and warnings from the if() command always display the
- argument list given to the command followed by an explanation of
- the problem. This moves the argument list into a pre-formatted
- block and follows it with a paragraph-form explanation. The
- result looks cleaner.
-
-2009-06-17 13:40 king
-
- * Source/: cmMakefile.cxx, cmMakefile.h, cmPolicies.cxx,
- cmPolicies.h: ENH: Create CMP0013 to disallow duplicate dirs
-
- In CMake 2.6.3 and below we silently accepted duplicate build
- directories whose build files would then conflict. At first this
- was considured purely a bug that confused beginners but would not
- be used in a real project. In CMake 2.6.4 we explicitly made it
- an error.
-
- However, some real projects took advantage of this as a "feature"
- and got lucky that the subtle build errors it can cause did not
- occur. Therefore we need a policy to deal with the case more
- gracefully. See issue #9173.
-
-2009-06-17 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-16 11:57 king
-
- * Source/cmLocalVisualStudio6Generator.cxx: BUG: Create an exe's
- implib output dir for VS 6
-
- VS 6 forgets to create the output directory for an executable's
- import library in case the exe dllexport-s symbols. We work
- around this VS bug by creating a pre-link event on the executable
- target to make the directory.
-
-2009-06-16 11:57 king
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio6Generator.h: ENH: Refactor VS 6 build event
- generation
-
- In cmLocalVisualStudio6Generator we generate pre-build, pre-link,
- and post-build events into project files. This refactors the
- generation code for the three event types into a private
- EventWriter class to avoid duplicate code.
-
-2009-06-16 11:44 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: ENH: Create exe implib
- dir in VS pre-link rule
-
- This moves creation of an executable's import library directory
- in VS projects from the pre-build step to the pre-link step. It
- makes sense to create the directory at the last moment.
-
-2009-06-16 11:44 king
-
- * Source/: cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h,
- cmLocalVisualStudioGenerator.cxx, cmLocalVisualStudioGenerator.h:
- ENH: Generalize exe implib dir creation for VS
-
- In VS 7,8,9 executable targets we generate a build event to
- create the output directory for the import library in case the
- executable marks symbols with dllexport (VS forgets to create
- this directory). This generalizes computation of the custom
- command line to support future use with other VS versions.
-
-2009-06-16 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-15 16:12 king
-
- * Source/: cmDefinePropertyCommand.cxx, cmDefinePropertyCommand.h:
- ENH: Simplify docs args for define_property
-
- This teaches the define_property command signature to accept
- multiple arguments after the BRIEF_DOCS and FULL_DOCS keywords.
- We append the arguments together, making specification of long
- documentation easier.
-
-2009-06-15 14:22 hoffman
-
- * Source/CTest/cmCTestBuildAndTestHandler.cxx: STYLE: fix warning
-
-2009-06-15 13:51 hoffman
-
- * Source/CTest/cmCTestBuildAndTestHandler.cxx: BUG: fix crash when
- running ctest coverage for VTK
-
-2009-06-15 13:22 hoffman
-
- * Modules/FindOpenGL.cmake: ENH: add path for 64 bit on old hp
-
-2009-06-15 13:17 hoffman
-
- * Modules/Platform/HP-UX.cmake: ENH: put the 64 bit paths first
-
-2009-06-15 12:39 hoffman
-
- * Modules/: Platform/HP-UX.cmake, FindOpenGL.cmake: ENH: add more
- search paths on HPUX
-
-2009-06-15 12:33 martink
-
- * Source/cmPolicies.cxx: COMP: fix line length
-
-2009-06-15 10:55 king
-
- * Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h,
- Tests/Plugin/CMakeLists.txt: BUG: Create an exe's implib output
- dir for VS
-
- If an executable marks symbols with __declspec(dllexport) then VS
- creates an import library for it. However, it forgets to create
- the directory that will contain the import library if it is
- different from the location of the executable. We work around
- this VS bug by creating a pre-build event on the executable
- target to make the directory.
-
-2009-06-15 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-14 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-13 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-12 15:44 king
-
- * Source/kwsys/ProcessUNIX.c: COMP: Do not compile VMS-specific
- code on non-VMS
-
- This helps avoid fixing VMS-specific code for non-VMS compilers
- where it isn't needed anyway.
-
-2009-06-12 15:28 king
-
- * Source/: cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h: ENH: Refactor VS 7,8,9 build
- event generation
-
- In cmLocalVisualStudio7Generator we generate pre-build, pre-link,
- and post-build events into project files. This refactors the
- generation code for the three event types into a private
- EventWriter class to avoid duplicate code.
-
-2009-06-12 13:33 fbertel
-
- * Source/kwsys/ProcessUNIX.c: COMP:Fixed warning with gcc 4.3.3:
- passing argument 1 of kwsysProcessSetVMSFeature discards
- qualifiers from pointer target type.
-
-2009-06-12 13:25 martink
-
- * Source/: cmIfCommand.h, cmPolicies.cxx: ENH: clean up some help
- text
-
-2009-06-12 11:10 martink
-
- * Source/cmIfCommand.cxx: ENH: warning fix
-
-2009-06-12 11:05 king
-
- * Source/cmStandardIncludes.h: COMP: Block warnings in Borland
- system headers
-
- In Release builds the Borland compiler warns about code in its
- own system headers. This blocks the warnings by disabling them
- where the headers are included.
-
-2009-06-12 10:46 king
-
- * Source/: cmDependsFortranParser.cxx, cmDependsFortranParser.y,
- cmDependsFortranParserTokens.h: ENH: Use KWSys String strcasecmp
- to parse Fortran
-
- This replaces the Fortran dependency parser source's custom
- strcasecmp implementation with one from KWSys String. It removes
- duplicate code and avoids a Borland warning about inlining
- functions with 'while'.
-
-2009-06-12 10:46 king
-
- * Source/kwsys/String.c: COMP: Avoid double-initialization in KWSys
- String
-
- The KWSys String implementation of strcasecmp initialized
- 'result' immediately before assigning to it. Borland produces a
- warning in this case, so this commit removes the extra
- initialization.
-
-2009-06-12 10:46 king
-
- * Source/: cmDependsFortranLexer.cxx, cmDependsFortranLexer.in.l:
- COMP: Remove useless assignment in Fortran lexer
-
- The generated Fortran dependency scanning lexer includes an
- assignment to a local variable that is unused. Borland warns, so
- we remove the assignment.
-
-2009-06-12 10:07 martink
-
- * Source/: cmIfCommand.cxx, cmIfCommand.h, cmPolicies.cxx,
- cmPolicies.h, cmWhileCommand.cxx: ENH: modified the if command to
- address bug 9123 some
-
-2009-06-12 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-11 15:25 hoffman
-
- * Modules/Platform/OpenVMS.cmake, Source/kwsys/SystemTools.cxx:
- ENH: use .exe on vms
-
-2009-06-11 15:18 king
-
- * CMakeLists.txt: COMP: We now require CMake 2.4.5 or higher to
- build
-
- We use the CMakeDependentOption module unconditionally, so we
- must require a version of CMake new enough to provide it.
-
-2009-06-11 14:57 king
-
- * Source/cmComputeLinkInformation.cxx: BUG: Do not create empty
- build-tree RPATH
-
- The fix for issue #9130 appends ':' to the end of the build-tree
- RPATH unconditionally. This changes the fix to add ':' only when
- the RPATH is not empty so that we do not create a build-tree
- RPATH with just ':'. An empty RPATH produces no string at all,
- so there is no chance of merging with a symbol name anyway.
-
-2009-06-11 11:24 king
-
- * CMakeLists.txt, CTestCustom.cmake.in,
- Source/CTest/cmCTestSubmitHandler.cxx,
- Utilities/cmThirdParty.h.in, Utilities/cm_xmlrpc.h: ENH: Disable
- the xmlrpc drop method by default
-
- We've chosen to drop our default dependence on xmlrpc. Thus we
- disable the corresponding CTest submission method and remove the
- sources for building xmlrpc locally. Users can re-enable the
- method by setting the CTEST_USE_XMLRPC option to use a
- system-installed xmlrpc library.
-
-2009-06-11 09:04 king
-
- * CMakeLists.txt, Utilities/cmThirdParty.h.in, Utilities/cm_curl.h:
- ENH: Remove option to build cmcurl-7.19.0
-
- This version of curl was added experimentally but does not
- address the problem we were hoping it fixed (an occasional upload
- hang). Importing a new curl can wait until the problem is fully
- diagnosed and addressed.
-
-2009-06-11 09:04 king
-
- * CMakeLists.txt: ENH: Simplify decision to use system libraries
-
- Previously we disallowed use of system libraries if
- FindXMLRPC.cmake was not available. Now that CMake 2.4 is
- required to build, the module is always available. This change
- simplifies the logic accordingly.
-
-2009-06-11 09:03 king
-
- * Source/cmXMLParser.cxx: COMP: Fix build with system-installed
- expat 2.0.1
-
- In cmXMLParser::ReportXmlParseError we were accidentally passing
- a value of type 'XML_Parser*' to expat methods instead of
- 'XML_Parser'. It was not caught because XML_Parser was just
- 'void*' in the cmexpat version. Newer system-installed expat
- versions catch the error because XML_Parser is now a pointer to a
- real type. This correct the type.
-
-2009-06-11 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-10 14:11 king
-
- * Source/cmComputeLinkInformation.cxx: BUG: Do not mangle symbols
- when editing RPATHs
-
- In ELF binaries the .dynstr string table is used both for the
- RPATH string and for program symbols. If a symbol name happens
- to match the end of the build-tree RPATH string the linker is
- allowed to merge the symbols.
-
- We must not allow this when the RPATH string will be replaced
- during installation because it will mangle the symbol. Therefore
- we always pad the end of the build-tree RPATH with ':' if it will
- be replaced. Tools tend not to use ':' at the end of symbol
- names, so it is unlikely to conflict. See issue #9130.
-
-2009-06-10 14:11 king
-
- * Source/cmDocumentVariables.cxx: ENH: Document variable
- CMAKE_NO_BUILTIN_CHRPATH
-
- This adds documentation for the variable which was previously
- missing. See issue #9130.
-
-2009-06-10 13:39 king
-
- * bootstrap: BUG: Fix bootstrap for Debian Almquist Shell
-
- The Debian Almquist Shell (dash) provides minimal POSIX
- compliance instead of the power of bash. It converts literal
- '\n' to a real newline even in a single-quoted string. This
- works around the problem by avoiding the literal. We can no
- longer use HEREDOC.
-
-2009-06-10 13:04 king
-
- * bootstrap: ENH: Make bootstrap script work on VMS bash
-
- A few sweeping changes were needed:
-
- - Avoid use of HEREDOC, which does not seem to work.
- - Avoid extra '.' in paths by using '_cmk' and '_tmp'
- instead of '.cmk' and '.tmp'.
-
-2009-06-10 13:04 king
-
- * Modules/Platform/OpenVMS.cmake,
- Source/cmGlobalUnixMakefileGenerator3.cxx: ENH: Enable basic
- OpenVMS platform support
-
- This adds the Modules/Platform/OpenVMS.cmake platform file for
- OpenVMS. We just use Unix-like rules to work with the GNV
- compiler front-end.
-
- A problem with process execution currently prevents CMake link
- scripts from working, so we avoid using them.
-
-2009-06-10 13:03 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: Skip 'SHELL =
- /bin/sh' in Makefiles on VMS
-
- This shell does not exist on VMS, so we leave it out.
-
-2009-06-10 13:03 king
-
- * Source/: cmGeneratedFileStream.cxx,
- cmLocalUnixMakefileGenerator3.cxx, cmTarget.cxx: ENH: On VMS use
- _dir and _tmp, not .dir and .tmp
-
- The VMS posix path emulation does not handle multiple '.'
- characters in file names in all cases. This avoids adding extra
- '.'s to file and directory names for target directories and
- generated files.
-
-2009-06-10 13:02 king
-
- * Source/kwsys/SystemTools.cxx: ENH: Teach KWSys SystemTools about
- VMS paths
-
- This teaches ConvertToUnixSlashes to convert VMS paths into
- posix-style paths. We also set the DECC$FILENAME_UNIX_ONLY
- feature so the process always sees posix-style paths on disk.
-
-2009-06-10 13:02 king
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: BUG: Avoid std::unique
- algorithm on VMS
-
- The Compaq compiler's std::unique algorithm followed by deletion
- of the extra elements seems to crash. For now we'll accept the
- duplicate dependencies on this platform.
-
-2009-06-10 11:49 king
-
- * Utilities/cmtar/extract.c: COMP: Fix cmtar build on VMS
-
- The mknod and mkfifo functions are not available on VMS.
-
-2009-06-10 11:49 king
-
- * Utilities/cmcurl/setup.h: COMP: Fix cmcurl build on VMS
-
- This defines IOCTL_3_ARGS in 'cmcurl/setup.h' to teach curl
- sources about the three-argument ioctl() on VMS.
-
-2009-06-10 11:49 king
-
- * Utilities/cmtar/: append.c, decode.c, extract.c, libtar.c,
- util.c, wrapper.c: COMP: Use HAVE_SYS_PARAM_H properly in libtar
-
- The value is computed by a try-compile for libtar. This teaches
- the sources to actually use the result.
-
-2009-06-10 11:48 king
-
- * Source/kwsys/ProcessUNIX.c: ENH: Teach KWSys Process basic VMS
- support
-
- This achieves basic process execution on OpenVMS. We use
- work-arounds for different fork()/exec() behavior and a lack of
- select().
-
- VMS emulates fork/exec using setjmp/longjmp to evaluate the child
- and parent return cases from fork. Therefore both must be
- invoked from the same function.
-
- Since select() works only for sockets we use the BeOS-style
- polling implementation. However, non-blocking reads on empty
- pipes cannot be distinguished easily from the last read on a
- closed pipe. Therefore we identify end of data by an empty read
- after the child terminates.
-
-2009-06-10 11:46 king
-
- * Source/kwsys/ProcessUNIX.c: BUG: Fix non-select process impl
- without timeout
-
- This avoids use of an uninitialized value in the KWSys
- ProcessUNIX polling implementation when no timeout is given.
-
-2009-06-10 11:46 king
-
- * Source/kwsys/CMakeLists.txt, bootstrap, Source/kwsys/String.c,
- Source/kwsys/kwsysPrivate.h: COMP: Avoid String.c inclusion by
- Compaq templates
-
- The Compaq compiler (on VMS) includes 'String.c' in source files
- that use the stl string while looking for template definitions.
- This was the true cause of double-inclusion of the
- 'kwsysPrivate.h' header. We work around the problem by
- conditionally compiling the entire source file on a condition
- only true when really building the source.
-
-2009-06-10 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-09 15:58 hoffman
-
- * Source/cmStandardIncludes.h: STYLE: suppress warnings for borland
-
-2009-06-09 15:44 hoffman
-
- * Source/kwsys/testAutoPtr.cxx: STYLE: suppress warnings for
- borland
-
-2009-06-09 15:18 hoffman
-
- * Source/: cmStandardIncludes.h, kwsys/hashtable.hxx.in,
- kwsys/testAutoPtr.cxx: STYLE: suppress warnings for borland
-
-2009-06-09 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-08 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-07 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-06 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-05 14:59 partyd
-
- * Source/kwsys/hashtable.hxx.in: COMP: Hopefully fix hashmap on
- VS6, Thanks Brad K!
-
-2009-06-05 13:17 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: fix warning on borland
-
-2009-06-05 12:01 hoffman
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h,
- kwsys/SystemTools.hxx.in, kwsys/SystemTools.cxx: ENH: move PutEnv
- to SystemTools
-
-2009-06-05 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-04 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-03 15:08 king
-
- * Modules/Platform/HP-UX.cmake,
- Source/cmComputeLinkInformation.cxx,
- Source/cmDocumentVariables.cxx: BUG: Recognize .so shared
- libraries on HP-UX
-
- HP-UX uses both .sl and .so as extensions for shared libraries.
- This teaches CMake to recognize .so shared libraries so they are
- treated properly during link dependency analysis.
-
-2009-06-03 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-02 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-06-01 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-31 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-30 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-29 16:09 alex
-
- * Modules/CPackRPM.cmake: BUG: fix #9031: newer rpm versions
- complain about the "#%" lines
-
- Alex
-
-2009-05-29 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-28 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-27 11:33 king
-
- * Modules/Platform/CYGWIN.cmake, bootstrap: ENH: Auto-import
- symbols for cygwin executables
-
- This enables the --enable-auto-import linker flag on Cygwin when
- linking executables. It works with the old gcc 3.x compiler and
- is necessary for the new gcc 4.x compiler. See issue #9071.
-
-2009-05-27 11:14 hoffman
-
- * Source/CTest/cmCTestMemCheckHandler.cxx: BUG: fix for bug #8153
- add purify suppression file and fix output to not be one big line
-
-2009-05-27 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-26 09:55 david.cole
-
- * Modules/: CMakeVS8FindMake.cmake, CMakeVS9FindMake.cmake: BUG:
- Rearrange paths to find correct installations of Visual Studio.
- Patch devenv.modified_search_order.patch came from issue #7919.
-
-2009-05-26 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-25 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-24 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-23 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-22 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-21 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-20 09:50 hoffman
-
- * Source/kwsys/SystemInformation.cxx: ENH: make this work for older
- versions of OSX
-
-2009-05-20 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-19 21:50 hoffman
-
- * Source/kwsys/SystemInformation.cxx: ENH: revert back because it
- does not build on older macs for now
-
-2009-05-19 16:56 hoffman
-
- * Source/kwsys/SystemInformation.cxx: ENH: remove warning
-
-2009-05-19 16:46 hoffman
-
- * Source/kwsys/SystemInformation.cxx: ENH: make this build on other
- machines besides the mac
-
-2009-05-19 16:35 hoffman
-
- * Source/kwsys/: SystemInformation.cxx, testSystemInformation.cxx:
- ENH: fix system info for mac
-
-2009-05-19 11:38 clinton
-
- * Modules/FindQt4.cmake: ENH: Better error message for those who
- switch from Qt3 to Qt4 and don't clean their cache file.
-
-2009-05-19 11:25 hoffman
-
- * Source/cmCoreTryCompile.cxx: BUG: fix for #0009051 CMake does not
- pass CMAKE_OSX_SYSROOT and CMAKE_OSX_DEPLOYMENT_TARGET when
- running TRY_COMPILE
-
-2009-05-19 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-18 15:27 alex
-
- * Source/cmFindFileCommand.cxx: STYLE: fix docs: it must replace
- "find_path" instead of "FIND_PATH" with "find_file", otherwise
- the docs talk about find_path() instead of find_file (patch from
- Michael Wild, #9047)
-
- Alex
-
-2009-05-18 10:34 king
-
- * Source/CTest/cmCTestBZR.cxx, Tests/CMakeLists.txt: BUG: Parse
- more bzr xml output encodings
-
- The BZR xml output plugin can use some encodings that are not
- recognized by expat, which leads to "Error parsing bzr log xml:
- unknown encoding". This works around the problem by giving expat
- a mapping, and adds a test. Patch from Tom Vercauteren. See
- issue #6857.
-
-2009-05-18 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-17 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-16 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-15 15:39 king
-
- * Modules/CTest.cmake, Source/CTest/cmCTestSubmitCommand.cxx: ENH:
- Remove CTest public.kitware.com drop default
-
- Previously CTest would drop dashboard submissions at
- public.kitware.com on the PublicDashboard project if there was no
- configuration. The server no longer supports forwarding to
- cdash.org, so there is no point in this default. Furthermore,
- there should be no default at all because it could leak
- information about proprietary projects that are not configured
- correctly.
-
-2009-05-15 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-14 16:13 king
-
- * Modules/CTest.cmake, Source/CMakeLists.txt,
- Source/CTest/cmCTestBZR.cxx, Source/CTest/cmCTestBZR.h,
- Source/CTest/cmCTestUpdateCommand.cxx,
- Source/CTest/cmCTestUpdateHandler.cxx,
- Source/CTest/cmCTestUpdateHandler.h, Tests/CMakeLists.txt,
- Tests/CTestUpdateBZR.cmake.in: ENH: Teach CTest to handle Bazaar
- repositories
-
- This creates cmCTestBZR to drive CTest Update handling on
- bzr-based work trees. Currently we always update to the head of
- the remote tracking branch (bzr pull), so the nightly start time
- is ignored for Nightly builds. A later change will address this.
- Patch from Tom Vercauteren. See issue #6857.
-
-2009-05-14 15:31 alex
-
- * Modules/CPackRPM.cmake: STYLE: add documentation for CPackRPM
- (#9029)
-
- Alex
-
-2009-05-14 09:27 king
-
- * Source/cmDocumentVariables.cxx: ENH: Make
- CMAKE_<LANG>_SIZEOF_DATA_PTR public
-
- The variable was previously documented for internal-use only.
- This officially documents it for general use by projects.
-
-2009-05-14 09:27 king
-
- * Source/kwsys/kwsysPrivate.h: STYLE: Simplify and document VMS
- workarounds
-
- The kwsysPrivate header double-inclusion check hits a false
- positive on VMS for an undetermined reason. This simplifies the
- workaround and documents it.
-
-2009-05-14 09:26 king
-
- * Source/kwsys/kwsysPrivate.h: STYLE: Remove trailing whitespace
-
-2009-05-14 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-13 11:08 hoffman
-
- * Source/: cmForEachCommand.cxx, cmWhileCommand.cxx: BUG: fix for
- #9014, FATAL_ERROR not ending loops
-
-2009-05-13 10:30 king
-
- * Source/kwsys/SystemTools.cxx: BUG: Fix removal of read-only
- directories
-
- Read-only directories must be given write permission before we
- can remove files and subdirectories from them.
-
-2009-05-13 10:30 king
-
- * Tests/StringFileTest/CMakeLists.txt: BUG: file(COPY) test should
- not make read-only dir
-
- CMake directory removal code cannot remove content from read-only
- directories (a separate bug which will be fixed). Therefore we
- should not create them in the StringFileTest. This tweaks the
- file(COPY) call to test not giving OWNER_WRITE to files rather
- than directories.
-
-2009-05-13 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-12 15:17 alex
-
- * Modules/: CMakeEclipseCDT4.cmake, CMakeCodeBlocks.cmake,
- CMakeKDevelop3.cmake: STYLE: remove these files now that I added
- them with a more consistent name as CMakeFind<GENERATOR>.cmake
- (should have been in the same commit...)
-
- Alex
-
-2009-05-12 15:13 alex
-
- * Modules/CPackRPM.cmake: BUG: apply patch from Eric Noulard, so
- cpack works with rpmbuild 4.6.0, #8967
-
- Alex
-
-2009-05-12 15:11 alex
-
- * Modules/: CMakeFindCodeBlocks.cmake, CMakeFindEclipseCDT4.cmake,
- CMakeFindKDevelop3.cmake, CMakeLists.txt,
- CMakeSystemSpecificInformation.cmake: STYLE: rename the files
- from CMake<GENERATOR>.cmake to CMakeFind<GENERATOR>.cmake, so it
- is more consistent e.g. with CMakeFindXcode.cmake
-
- Alex
-
-2009-05-12 15:06 king
-
- * Readme.txt: STYLE: Remove trailing whitespace
-
-2009-05-12 15:03 king
-
- * cmake.1: BUG: Remove manual man-page from CMake-SourceFile2-b
- branch
-
-2009-05-12 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-11 13:58 king
-
- * Source/cmCTest.cxx: COMP: Avoid operator precedence warning
-
- GCC warns that parens should be used for nested and/or operators.
-
-2009-05-11 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-10 16:07 alex
-
- * Source/cmSetCommand.cxx: STYLE: cacheStart is used only locally
- in the if-branch
-
- Alex
-
-2009-05-10 06:01 alex
-
- * Modules/CTest.cmake: STYLE: first lower-casing the string makes
- comparing its contents easier
-
- Alex
-
-2009-05-10 06:00 alex
-
- * Modules/: CMakeCodeBlocks.cmake, CMakeEclipseCDT4.cmake,
- CMakeKDevelop3.cmake, CMakeSystemSpecificInformation.cmake: ENH:
- move the code which queries gcc for the system include dirs from
- CMakeSystemSpecificInformation.cmake into a separate file,
- CMakeEclipseCDT4.cmake -if CMAKE_EXTRA_GENERATOR is set, i.e.
- either CodeBlocks or KDevelop3 or EclipseCDT4, load a matching
- cmake script file, which can do things specific for this
- generator - added such files for Eclipse, KDevelop and
- CodeBlocks, one thing they all do is they try to find the
- respective IDE and store it in the
- CMAKE_(KDEVELOP3|CODEBLOCKS|ECLIPSE)_EXECUTABLE variable. This
- could be used by cmake-gui to open the project it just generated
- with the gui (not sure this is possible with eclipse).
-
- Alex
-
-2009-05-10 05:29 alex
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: BUG: don't report
- changed compiler variables if the path to the compiler differs
- only e.g. a double slash somewhere instead only one slash as
- directory separator (#8890)
-
- Alex
-
-2009-05-10 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-09 17:25 alex
-
- * Source/cmDocumentVariables.cxx: STYLE: document
- CMAKE_INCLUDE_CURRENT_DIR
-
- Alex
-
-2009-05-09 08:15 alex
-
- * Modules/: CMakeVS8FindMake.cmake, CMakeVS9FindMake.cmake: ENH:
- when cross compiling, e.g. for WinCE, don't use VCExpress, since
- this doesn't support it This is the first patch to add support
- for WinCE to cmake (#7919)
-
- Alex
-
-2009-05-09 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-08 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-07 18:22 hoffman
-
- * Source/ctest.cxx: ENH: add docs for command line ctest
-
-2009-05-07 18:20 hoffman
-
- * Source/cmCTest.cxx: BUG: 8898 fix date in ctest nightly time
-
-2009-05-07 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-06 11:21 clinton
-
- * Modules/FindQt4.cmake: BUG: Fix spaces in file paths for lupdate
- command
-
-2009-05-06 09:42 clinton
-
- * Modules/: FindQt4.cmake, UseQt4.cmake:
- ENH: Add support for QtScriptTools in Qt 4.5.
-
-2009-05-06 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-05 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-04 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-03 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-02 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-05-01 10:39 king
-
- * Source/: cmTarget.cxx, cmTarget.h: ENH: Remove cmTarget internal
- type arguments
-
- Internally cmTarget was passing the target type in several name
- computation signatures to support computation of both shared and
- static library names for one target. We no longer need to
- compute both names, so this change simplifies the internals by
- using the GetType method and dropping the type from method
- signatures.
-
-2009-05-01 10:39 king
-
- * Source/: cmMakefileExecutableTargetGenerator.cxx, cmTarget.cxx,
- cmTarget.h: ENH: Remove cmTarget::GetExecutableCleanNames
-
- This method was redundant with GetExecutableNames.
-
-2009-05-01 10:38 king
-
- * Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmSetTargetPropertiesCommand.h, Source/cmTarget.cxx,
- Source/cmTarget.h, Tests/Complex/Library/CMakeLists.txt,
- Tests/ComplexOneConfig/Library/CMakeLists.txt,
- Tests/ComplexRelativePaths/Library/CMakeLists.txt: ENH: Always
- imply CLEAN_DIRECT_OUTPUT target prop
-
- This property was left from before CMake always linked using full
- path library names for targets it builds. In order to safely
- link with "-lfoo" we needed to avoid having both shared and
- static libraries in the build tree for targets that switch on
- BUILD_SHARED_LIBS. This meant cleaning both shared and static
- names before creating the library, which led to the creation of
- CLEAN_DIRECT_OUTPUT to disable the behavior.
-
- Now that we always link with a full path we do not need to clean
- old library names left from an alternate setting of
- BUILD_SHARED_LIBS. This change removes the CLEAN_DIRECT_OUTPUT
- property and instead uses its behavior always. It removes some
- complexity from cmTarget internally.
-
-2009-05-01 09:45 king
-
- * Source/cmTarget.cxx, Source/cmTarget.h,
- Tests/ExportImport/Export/CMakeLists.txt,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: Allow more
- specification of target file names
-
- This creates target properties ARCHIVE_OUTPUT_NAME,
- LIBRARY_OUTPUT_NAME, and RUNTIME_OUTPUT_NAME, and
- per-configuration equivalent properties
- ARCHIVE_OUTPUT_NAME_<CONFIG>, LIBRARY_OUTPUT_NAME_<CONFIG>, and
- RUNTIME_OUTPUT_NAME_<CONFIG>. They allow specification of target
- output file names on a per-type, per-configuration basis. For
- example, a .dll and its .lib import library may have different
- base names.
-
- For consistency and to avoid ambiguity, the old
- <CONFIG>_OUTPUT_NAME property is now also available as
- OUTPUT_NAME_<CONFIG>.
-
- See issue #8920.
-
-2009-05-01 09:45 king
-
- * Source/: cmTarget.cxx, cmTarget.h: ENH: Refactor target output
- file type computation
-
- This creates method cmTarget::GetOutputTargetType to compute the
- output file type 'ARCHIVE', 'LIBRARY', or 'RUNTIME' from the
- platform and target type. It factors out logic from the target
- output directory computation code for later re-use.
-
-2009-05-01 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-30 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-29 15:07 king
-
- * Modules/UntarFile.cmake: ENH: Teach UntarFile to preserve file
- timestamps
-
- After extracting the tarball in a temporary directory we copy the
- tree to the destination directory. The 'cmake -E copy_directory'
- command does not preserve file timestamps, so we use file(COPY)
- instead.
-
-2009-04-29 14:50 king
-
- * Source/cmFileCommand.cxx: COMP: Avoid unused arg warnings in
- cmFileCommand
-
- The default cmFileCopier::ReportCopy implementation is empty, so
- we should leave out the argument names.
-
-2009-04-29 14:20 king
-
- * Source/CTest/cmCTestCVS.cxx: BUG: Remove '-d<now' from 'cvs log'
- commands
-
- When CTest runs 'cvs log' to get revision information for updated
- files, we were passing '-d<now'. The option seems useless since
- revisions cannot be created in the future, and can lose revisions
- if the client machine clock is behind the server.
-
-2009-04-29 14:02 king
-
- * Tests/CMakeTests/FileTest.cmake.in: BUG: Fix CMake.File test for
- deep dir name
-
- This fixes the regex checking expected output of Copy-NoFile to
- account for line wrapping when the input directory name is long.
-
-2009-04-29 13:57 king
-
- * Source/cmFileCommand.cxx: COMP: Fix nested class member access
-
- Nested classes have no special access to other members of their
- enclosing class. In cmFileCopier the nested class MatchRule must
- use MatchProperties, so we grant friendship to it.
-
-2009-04-29 13:33 king
-
- * Source/cmFileCommand.cxx: COMP: Fix non-virtual destructor
- warning
-
- This gives cmFileCopier a virtual destructor since it has virtual
- methods. While we never actually delete through a base pointer
- (or dynamically at all), the compiler doesn't know and warns
- anyway.
-
-2009-04-29 13:13 king
-
- * Tests/CMakeTests/: CMakeLists.txt, File-Copy-BadArg.cmake,
- File-Copy-BadPerm.cmake, File-Copy-BadRegex.cmake,
- File-Copy-EarlyArg.cmake, File-Copy-LateArg.cmake,
- File-Copy-NoDest.cmake, File-Copy-NoFile.cmake,
- FileTest.cmake.in: ENH: Test file(COPY) failure cases
-
- This tests some cases of bad arguments to the file(COPY)
- signature. It checks that the proper error messages are
- produced.
-
-2009-04-29 13:13 king
-
- * Source/cmFileCommand.cxx, Source/cmFileCommand.h,
- Tests/StringFileTest/CMakeLists.txt: ENH: Create file(COPY)
- command signature
-
- The file(INSTALL) command has long been undocumented and used
- only to implement install() scripts. We now document it and
- provide a similar file(COPY) signature which is useful in
- general-purpose scripts. It provides the capabilities of
- install(DIRECTORY) and install(FILES) but operates immediately
- instead of contributing to install scripts.
-
-2009-04-29 13:13 king
-
- * Source/cmFileCommand.cxx: ENH: Teach file(INSTALL) relative paths
-
- This teaches the undocumented file(INSTALL) command to deal with
- relative paths. Relative input file paths are evaluated with
- respect to the current source directory. Relative output file
- paths are evaluated with respect to the current binary directory.
-
- While this command is currently used only in cmake_install.cmake
- scripts (in -P script mode), this cleans up its interface in
- preparation for a documented signature.
-
-2009-04-29 13:12 king
-
- * Source/: cmFileCommand.cxx, cmFileCommand.h: ENH: Refactor
- file(INSTALL) implementation
-
- The undocumented file(INSTALL) is implemented by a
- cmFileInstaller class inside cmFileCommand. This refactors the
- class to split out code not specific to installation into a
- cmFileCopier base class.
-
-2009-04-29 08:47 king
-
- * Source/: cmFileCommand.cxx, cmFileCommand.h: ENH: Send all file
- installations through one path
-
- This creates a single cmFileInstaller method to dispatch
- installation of symlinks, directories, and files. The change
- removes duplicate tests of input file type and makes the decision
- more consistent.
-
-2009-04-29 08:47 king
-
- * Source/cmFileCommand.cxx: ENH: Better error on file perm or time
- failure
-
- This improves the error message produced during installation when
- CMake cannot set file modification time or permissions.
-
-2009-04-29 08:46 king
-
- * Source/cmFileCommand.cxx: BUG: Error when install dir cannot be
- created
-
- This teaches the undocumented file(INSTALL) command to report an
- error when it cannot create the destination directory.
-
-2009-04-29 08:46 king
-
- * Source/cmFileCommand.cxx: ENH: Simplify CMAKE_INSTALL_ALWAYS
- implementation
-
- This simplifies cmFileInstaller internally by storing the
- 'always' mark as an instance variable instead of passing it
- through all method signatures.
-
-2009-04-29 08:46 king
-
- * Source/cmFileCommand.cxx: ENH: Simplify construction of
- cmFileInstaller
-
- This cleans up the cmFileInstaller constructor signature.
-
-2009-04-29 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-28 14:58 hoffman
-
- * CMakeLists.txt: ENH: final 2.6.4 release
-
-2009-04-28 08:19 king
-
- * Source/cmFileCommand.cxx: BUG: Fix required permissions check
- again
-
- While copying a directory the destination must have owner rwx
- permissions. This corrects our check, this time with correct
- operator precedence using parenthesis.
-
-2009-04-28 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-27 13:20 king
-
- * Source/: cmFileCommand.cxx, cmFileCommand.h,
- cmInstallDirectoryGenerator.cxx, cmInstallExportGenerator.cxx,
- cmInstallFilesGenerator.cxx, cmInstallGenerator.cxx,
- cmInstallGenerator.h, cmInstallTargetGenerator.cxx: ENH: Remove
- unused PROPERTIES from file(INSTALL)
-
- The undocumented file(INSTALL) command used to support a
- PROPERTIES option, but no install code still uses it. This
- removes the option.
-
-2009-04-27 13:20 king
-
- * Source/cmFileCommand.cxx: BUG: Fix required permissions check for
- dir copy
-
- While copying a directory the destination must have owner rwx
- permissions. This corrects our check.
-
-2009-04-27 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-26 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-25 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-24 11:44 hoffman
-
- * Source/cmSystemTools.cxx: ENH: vms fix
-
-2009-04-24 11:21 king
-
- * Tests/Preprocess/CMakeLists.txt: ENH: Test spaces in non-string
- preprocessor values
-
- This extends the Preprocessor test to put spaces in the value of
- a definition that is not a quoted string. In particular this
- tests that VS6 supports values with spaces if they do not have
- '"', '$', or ';'. See issue #8779.
-
-2009-04-24 11:17 king
-
- * Source/cmLocalGenerator.cxx,
- Source/cmLocalVisualStudio6Generator.cxx, Source/cmMakefile.cxx,
- Tests/Preprocess/CMakeLists.txt: ENH: Support more preprocessor
- values in VS6
-
- Previously we rejected all preprocessor definition values
- containing spaces for the VS6 IDE generator. In fact VS6 does
- support spaces but not in combination with '"', '$', or ';', and
- only if we use the sytnax '-DNAME="value with spaces"' instead of
- '-D"NAME=value with spaces"'. Now we support all definition
- values that do not have one of these invalid pairs. See issue
- #8779.
-
-2009-04-24 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-23 11:09 hoffman
-
- * Source/kwsys/: ProcessUNIX.c, System.h.in, SystemTools.cxx,
- kwsysPrivate.h: ENH: check in almost building VMS stuff with
- VMSBuild directory since the bootstrap script will not work on
- VMS
-
-2009-04-23 09:10 king
-
- * Tests/CTestUpdateGIT.cmake.in: BUG: Fix CTest.UpdateGIT test for
- older git
-
- Older git versions do not support 'git init --bare', so we
- instead use the more proper 'git --bare init'.
-
-2009-04-23 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-22 10:22 king
-
- * Source/CTest/cmCTestGIT.cxx: COMP: Fix class reference for HP aCC
-
-2009-04-22 09:18 king
-
- * Source/CMakeLists.txt, Source/CTest/cmCTestGIT.cxx,
- Source/CTest/cmCTestGIT.h, Source/CTest/cmCTestUpdateCommand.cxx,
- Source/CTest/cmCTestUpdateHandler.cxx,
- Source/CTest/cmCTestUpdateHandler.h, Tests/CMakeLists.txt,
- Tests/CTestUpdateGIT.cmake.in: ENH: Teach CTest to handle git
- repositories
-
- This creates cmCTestGIT to drive CTest Update handling on
- git-based work trees. Currently we always update to the head of
- the remote tracking branch (git pull), so the nightly start time
- is ignored for Nightly builds. A later change will address this.
- See issue #6994.
-
-2009-04-22 09:18 king
-
- * Source/: CMakeLists.txt, CTest/cmCTestGlobalVC.cxx,
- CTest/cmCTestGlobalVC.h, CTest/cmCTestSVN.cxx,
- CTest/cmCTestSVN.h: ENH: Factor global-VC parts out of cmCTestSVN
-
- This factors parts of the svn update implementation that are
- useful for any globally-versioning vcs tool into cmCTestGlobalVC.
- It will allow the code to be shared among the support classes
- for most vcs tools.
-
-2009-04-22 09:11 king
-
- * Source/cmSystemTools.cxx: COMP: Fix calls to superclass methods
- for Borland
-
- The superclass of cmSystemTools is cmsys::SystemTools, which
- should be referencable by just SystemTools from inside the class.
- Borland C++ does not seem to support this, so we use
- cmSystemTools instead.
-
-2009-04-22 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-21 18:23 alex
-
- * Source/kwsys/Terminal.c: ENH: also recognize rxvt-256color as a
- color terminal (#8913, patch from Deewiant)
-
- Alex
-
-2009-04-21 18:18 alex
-
- * Modules/FindMPEG2.cmake: ENH: search also for mpeg2dec/mpeg2.h,
- as the documentation says, and as it is also installed by plain
- libmpeg2 (#8455) Also mark the variables as advanced.
-
- Alex
-
-2009-04-21 17:18 hoffman
-
- * Tests/X11/CMakeLists.txt: ENH: sneak a test into RC 5
-
-2009-04-21 17:15 hoffman
-
- * Tests/X11/CMakeLists.txt: ENH: make sure tests for cpack are run
- correctly
-
-2009-04-21 17:12 hoffman
-
- * Tests/X11/: CMakeLists.txt: ENH: make sure tests for cpack are
- run correctly
-
-2009-04-21 17:12 alex
-
- * Modules/FindJNI.cmake: ENH: add even more search directories for
- debian-like systems (see #8821)
-
- Alex
-
-2009-04-21 17:09 alex
-
- * Modules/FindJNI.cmake: ENH: add one more search directory (see
- #8919)
-
- Alex
-
-2009-04-21 16:48 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Modules/CPack.OSXScriptLauncher.in,
- Modules/CPack.OSXScriptLauncher.rsrc.in,
- Modules/CPack.OSXX11.main.scpt.in,
- Modules/CPack.background.png.in, Modules/CPack.cmake: ENH: move
- over more CPack files into 2.6
-
-2009-04-21 14:12 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Modules/CPack.OSXX11.main.scpt.in,
- Source/QtDialog/CMakeSetupDialog.ui: ENH: merge in changes and
- create RC 5
-
-2009-04-21 11:37 king
-
- * Source/cmSystemTools.cxx: BUG: Avoid infinite loop at directory
- tree root
-
- The system tools GetParentDirectory method no longer removes the
- root path component. This fixes
- cmSystemTools::FileExistsInParentDirectories to not infinitely
- loop at when GetParentDirectory stops at the root.
-
-2009-04-21 11:36 king
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h,
- kwsys/SystemTools.cxx, kwsys/SystemTools.hxx.in: ENH: Remove
- obscure method from KWSys SystemTools
-
- This removes SystemTools::FileExistsInParentDirectories from
- KWSys since it is a special-purpose method that is not generally
- useful.
-
-2009-04-21 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-20 08:42 king
-
- * Source/kwsys/SystemTools.cxx: BUG: Fix
- SystemTools::IsSubDirectory on bad input
-
- When SystemTools::GetParentDirectory was fixed to never remove
- the root path component from a full path we violated an
- assumption made by IsSubDirectory that eventually
- GetParentDirectory returns an empty string. This led to an
- infinite loop if the potential parent directory is empty, so we
- explicitly avoid that case.
-
-2009-04-20 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-19 12:46 alex
-
- * Modules/FindBLAS.cmake, Modules/FindBoost.cmake,
- Modules/FindLAPACK.cmake, Modules/FindMotif.cmake,
- Modules/FindRTI.cmake, Modules/FindwxWidgets.cmake,
- Modules/SquishTestScript.cmake, Modules/Use_wxWindows.cmake,
- Source/cmDocumentVariables.cxx, Source/cmFindPackageCommand.cxx,
- Source/cmake.cxx, Source/cmakemain.cxx: STYLE: fix typos in the
- docs
-
- Alex
-
-2009-04-19 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-18 14:37 hoffman
-
- * Modules/: CMakeTestCCompiler.cmake, CMakeTestCXXCompiler.cmake:
- BUG: fix cmake so that if you configure with a bad env for cl,
- then with a good path, it will configure correctly
-
-2009-04-18 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-17 14:44 hoffman
-
- * Modules/DartConfiguration.tcl.in,
- Source/CTest/cmCTestSubmitCommand.cxx: ENH: make sure
- CTEST_CURL_OPTIONS work from script mode
-
-2009-04-17 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-16 12:25 clinton
-
- * Source/QtDialog/CMakeSetupDialog.ui:
- BUG: Path lengths in combo box for binary directory was forcing
- a minimum size on the main window. Fixed that.
-
-2009-04-16 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-15 13:03 king
-
- * Source/kwsys/SystemTools.cxx: BUG: Replace brittle
- GetParentDirectory impl
-
- The previous change to this method broke cases where the input
- path does not exist. The SystemTools::GetParentDirectory method
- is redundant with the more robust SystemTools::GetFilenamePath.
- This replaces its implementation to just call GetFilenamePath.
-
-2009-04-15 11:00 king
-
- * Source/cmSystemTools.cxx: COMP: Fix BOOL to bool conversion
- warning
-
- The cmSystemTools::RenameFile method returns type bool, but its
- implementation on Windows returns the result of an API function
- that returns BOOL. This change avoids the compiler warning.
-
-2009-04-15 10:45 yumin
-
- * Source/kwsys/SystemTools.cxx: BUG:
- SystemTools::GetParentDirectory() will crash if "/" is passed in
- as argement. Valid check is added to make sure the input argment
- exists, and if "/" is passed in, empty string will be returned.
-
-2009-04-15 09:58 king
-
- * Source/cmake.cxx: ENH: Create command line api "cmake -E rename"
-
- This extends the "-E" command line mode with a "rename old new"
- signature. The new command atomically renames a file or
- directory within a single disk volume.
-
-2009-04-15 09:58 king
-
- * Source/cmFileCommand.cxx, Source/cmFileCommand.h,
- Tests/StringFileTest/CMakeLists.txt: ENH: Create file(RENAME)
- command mode
-
- This creates command "file(RENAME <oldname> <newname>)" to rename
- a file or directory within a single disk volume.
-
-2009-04-15 09:57 king
-
- * Source/: cmGeneratedFileStream.cxx, cmSystemTools.cxx,
- cmSystemTools.h: ENH: Move RenameFile to cmSystemTools
-
- This moves the cmGeneratedFileStream::RenameFile method
- implementation into cmSystemTools. It works only within a single
- filesystem volume, but is atomic when the operating system
- permits.
-
-2009-04-15 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-14 09:35 king
-
- * Source/kwsys/: Base64.h.in, Configure.h.in, Configure.hxx.in,
- FundamentalType.h.in, MD5.h.in, Process.h.in, String.h.in,
- System.h.in, Terminal.h.in: ENH: Skip KWSys name maros in case of
- identity
-
- All KWSys C symbol names begin with the KWSYS_NAMESPACE defined
- at configuration time. For ease of editing we write canonical
- names with the prefix 'kwsys' and use macros to map them to the
- configured prefix at preprocessing time. In the case of
- standalone KWSys, the prefix is 'kwsys', so the macros were
- previously defined to their own names.
-
- We now skip defining the macros in the identity case so that the
- final symbol names are never themselves macros. This will allow
- the symbols to be further transformed behind the scenes to help
- linkers in special cases on some platforms.
-
-2009-04-14 00:50 lowman
-
- * Modules/CMakeDetermineVSServicePack.cmake: ENH: New function for
- determining Visual Studio service pack
-
-2009-04-14 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-13 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-12 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-11 09:29 hoffman
-
- * Source/CTest/cmCTestSubmitHandler.cxx: ENH: remove warning and
- improve message
-
-2009-04-11 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-10 13:00 hoffman
-
- * Source/CTest/cmCTestSubmitHandler.cxx: ENH: remove cerr call
-
-2009-04-10 12:15 hoffman
-
- * Modules/DartConfiguration.tcl.in,
- Source/CTest/cmCTestSubmitHandler.cxx: ENH: add ability to
- control ssl cert checking
-
-2009-04-10 11:59 hoffman
-
- * CMakeLists.txt, Utilities/cmcurl/CMakeLists.txt: ENH: allow for
- shared build of libcurl and fix build with openssl option (ssl
- tested on linux and windows
-
-2009-04-10 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-09 13:56 king
-
- * Modules/AddExternalProject.cmake,
- Tests/ExternalProject/CMakeLists.txt,
- Tests/ExternalProject/Step1Patch.cmake: ENH: Allow lists in
- AddExternalProject arguments
-
- The add_external_project function separates its arguments with
- ';' separators, so previously no command line argument could
- contain one. When specifying CMAKE_ARGS, some -D argument values
- may need to contain a semicolon to form lists in the external
- project cache.
-
- This adds add_external_project argument LIST_SEPARATOR to specify
- a list separator string. The separator is replaced by ';' in
- arguments to any command created to drive the external project.
- For example:
-
- add_external_project(...
- LIST_SEPARATOR ::
- CMAKE_ARGS -DSOME_LIST:STRING=A::B::C
- ...)
-
- passes "-DSOME_LIST:STRING=A;B;C" to CMake for the external
- project.
-
-2009-04-09 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-08 16:29 king
-
- * Source/cmTarget.cxx, Tests/ExportImport/Export/CMakeLists.txt,
- Tests/ExportImport/Export/testLib5.c,
- Tests/ExportImport/Import/A/CMakeLists.txt,
- Tests/ExportImport/Import/A/imp_testExe1.c: ENH: Allow
- IMPORTED_IMPLIB w/o IMPORTED_LOCATION
-
- Linking to a Windows shared library (.dll) requires only its
- import library (.lib). This teaches CMake to recognize SHARED
- IMPORTED library targets that set only IMPORTED_IMPLIB and not
- IMPORTED_LOCATION.
-
-2009-04-08 16:28 king
-
- * Source/cmTarget.cxx: BUG: Fix imported target config guess
-
- When an IMPORTED target provides no generic configuration and no
- match for a desired configuration then we choose any available
- configuration. This change corrects the choice when the first
- listed available configuration does not really have a location.
-
-2009-04-08 09:22 king
-
- * Tests/: CTestUpdateCVS.cmake.in, CTestUpdateSVN.cmake.in: ENH:
- Teach Update* tests to report local mod step
-
- The CTest.UpdateCVS/SVN tests report every step with a message.
- This adds a message for the local modification step.
-
-2009-04-08 09:21 king
-
- * Tests/CTestUpdateCVS.cmake.in: ENH: Make UpdateCVS test robust to
- 1s file time res
-
- CVS clients recognize file modifications only if a file's
- timestamp is newer than its CVS/Entries line. This fixes
- intermittent failure of the test on filesystems with low
- timestamp resolution by delaying before creating a local
- modification.
-
-2009-04-08 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-07 15:32 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Source/cmAddCustomCommandCommand.h,
- Source/cmAddCustomTargetCommand.h,
- Source/cmComputeLinkDepends.cxx, Source/cmComputeLinkDepends.h,
- Source/kwsys/SystemInformation.cxx,
- Tests/ExportImport/Import/CMakeLists.txt,
- Tests/ExportImport/Import/imp_mod1.c,
- Tests/ExportImport/Import/imp_testExe1.c,
- Tests/ExportImport/Import/imp_testTransExe1.c,
- Tests/ExportImport/Import/A/CMakeLists.txt,
- Tests/ExportImport/Import/A/imp_lib1.c,
- Tests/ExportImport/Import/A/imp_mod1.c,
- Tests/ExportImport/Import/A/imp_testExe1.c: ENH: merge in changes
- for RC 4
-
-2009-04-07 15:31 david.cole
-
- * Modules/NSIS.template.in: BUG: Fix issue #8682. Use
- CPACK_NSIS_DISPLAY_NAME in appropriate places rather than
- CPACK_PACKAGE_INSTALL_DIRECTORY. Clean separation of these two
- variables (which have the same value by default) allows an easy
- workaround for issue #7881, too.
-
-2009-04-07 15:13 david.cole
-
- * Source/cmLocalGenerator.cxx: BUG: Fix invalid array access
- discovered during investigation of issue #7832.
-
-2009-04-07 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-06 14:55 king
-
- * Source/kwsys/SystemInformation.cxx: BUG: Fix parsing of linux 2.6
- /proc/meminfo format
-
- Previously KWSys SystemInformation parsed this file assuming a
- strict order and set of fields, but the order is not reliable.
- This generalizes the implementation to support any order and
- extra fields.
-
-2009-04-06 11:11 hoffman
-
- * Tests/ExportImport/Import/imp_testTransExe1.c: file
- imp_testTransExe1.c was added on branch CMake-2-6 on 2009-04-07
- 19:32:08 +0000
-
-2009-04-06 11:11 hoffman
-
- * Tests/ExportImport/Import/A/imp_testExe1.c: file imp_testExe1.c
- was added on branch CMake-2-6 on 2009-04-07 19:32:08 +0000
-
-2009-04-06 11:11 hoffman
-
- * Tests/ExportImport/Import/A/imp_mod1.c: file imp_mod1.c was added
- on branch CMake-2-6 on 2009-04-07 19:32:08 +0000
-
-2009-04-06 11:11 hoffman
-
- * Tests/ExportImport/Import/A/imp_lib1.c: file imp_lib1.c was added
- on branch CMake-2-6 on 2009-04-07 19:32:08 +0000
-
-2009-04-06 11:11 hoffman
-
- * Tests/ExportImport/Import/A/CMakeLists.txt: file CMakeLists.txt
- was added on branch CMake-2-6 on 2009-04-07 19:32:08 +0000
-
-2009-04-06 11:11 king
-
- * Tests/ExportImport/Import/: A/CMakeLists.txt, A/imp_lib1.c,
- A/imp_mod1.c, A/imp_testExe1.c, CMakeLists.txt, imp_mod1.c,
- imp_testExe1.c, imp_testTransExe1.c: ENH: Test transitive link to
- subdir-imported lib
-
- This tests linking to an imported target that is not visible but
- is a transitive dependency of a target that is visible. See
- issue #8843.
-
-2009-04-06 11:10 king
-
- * Source/: cmComputeLinkDepends.cxx, cmComputeLinkDepends.h: BUG:
- Lookup transitive link deps in depender scope
-
- The transitive link dependencies of a linked target must be
- followed in its own scope, not in the scope of the original
- target that depends on it. This is necessary since imported
- targets do not have global scope. See issue #8843.
-
-2009-04-06 03:39 malaterre
-
- * Source/kwsys/testIOS.cxx: BUG: comment out faulty seekp which
- make kwsys::*stringstream fails on platform with no
- std::*stringstream implementation
-
-2009-04-06 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-05 06:55 malaterre
-
- * Source/kwsys/testIOS.cxx: ENH: hopefully seekp is the call making
- kwsys::stringstream behaves oddly on sunos
-
-2009-04-05 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-04 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-03 13:12 david.cole
-
- * Source/CPack/cmCPackDragNDropGenerator.cxx: BUG: Fix issue #8759
- - add support for setting dmg volume name and compression type by
- CPack variables. Also add custom .DS_Store and background image
- support. Thanks to Mike Arthur for the patches.
-
-2009-04-03 11:41 david.cole
-
- * Source/cmTest.cxx: BUG: Fix documentation deficiency noted in
- issue #7885. Thanks to Philip Lowman for the gist of the patch.
-
-2009-04-03 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-02 06:12 malaterre
-
- * Source/kwsys/testIOS.cxx: ENH: trying to reproduce issue on sunos
-
-2009-04-02 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-04-01 10:31 king
-
- * Source/: cmAddCustomCommandCommand.h, cmAddCustomTargetCommand.h:
- ENH: Clarify VERBATIM option documentation
-
- The previous wording of the VERBATIM option documentation in the
- add_custom_command and add_custom_target commands was confusing.
- It could be interpreted as the opposite of what the option means
- (no escaping instead of escaping). This clarifies the
- documentation to explicitly state that it escapes.
-
-2009-04-01 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-31 16:15 david.cole
-
- * Modules/FindVTK.cmake: BUG: Fix issue #8804. Add vtk-5.4 lib path
- to the FindVTK.cmake module.
-
-2009-03-31 15:30 hoffman
-
- * Source/CTest/cmCTestSubmitHandler.cxx: ENH: use 0 not FALSE
-
-2009-03-31 15:24 hoffman
-
- * Source/CTest/: cmCTestSubmitHandler.cxx, cmCTestSubmitHandler.h:
- ENH: add submit via cp mode
-
-2009-03-31 13:50 david.cole
-
- * Tests/CMakeTests/GetPrerequisitesTest.cmake.in: STYLE: White
- space only change to see if continuous is working on new
- dashboard machine...
-
-2009-03-31 13:16 david.cole
-
- * Tests/CMakeTests/GetPrerequisitesTest.cmake.in: STYLE: White
- space only change to see if continuous is working on new
- dashboard machine...
-
-2009-03-31 10:28 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/FindQt4.cmake,
- Source/cmAddCustomCommandCommand.h,
- Source/cmAddCustomTargetCommand.h,
- Source/CTest/cmCTestSubmitCommand.cxx,
- Source/QtDialog/CMakeSetupDialog.cxx,
- Source/QtDialog/QCMakeCacheView.cxx: ENH: next RC
-
-2009-03-31 10:27 hoffman
-
- * Utilities/Release/vogon_release.cmake: ENH: use a newer cmake
-
-2009-03-31 10:13 king
-
- * Modules/AddExternalProject.cmake: BUG: Fix AddExternalProject
- config command id
-
- This fixes the get_configure_command_id function to not mistake
- CONFIGURE_COMMAND values that run "cmake -P" or "cmake -E" for a
- CMake project configuration. These values just help run scripts.
-
-2009-03-31 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-30 16:34 clinton
-
- * Source/QtDialog/QCMake.cxx:
- BUG: Fix inconsistency with lowercase drive letters on Windows.
-
-2009-03-30 11:38 king
-
- * Modules/AddExternalProject.cmake: ENH: Simpler AddExternalProject
- install step
-
- This simplifies the implementation with
- add_external_project_step.
-
-2009-03-30 11:38 king
-
- * Modules/AddExternalProject.cmake: ENH: Simpler AddExternalProject
- build step
-
- This simplifies the implementation with
- add_external_project_step.
-
-2009-03-30 11:38 king
-
- * Modules/AddExternalProject.cmake: ENH: Simpler AddExternalProject
- configure step
-
- This simplifies the implementation with
- add_external_project_step.
-
-2009-03-30 11:37 king
-
- * Modules/AddExternalProject.cmake: ENH: Simpler AddExternalProject
- patch step
-
- This simplifies the implementation with
- add_external_project_step.
-
-2009-03-30 11:37 king
-
- * Modules/AddExternalProject.cmake: ENH: Simpler AddExternalProject
- update step
-
- This simplifies the implementation with
- add_external_project_step.
-
-2009-03-30 11:37 king
-
- * Modules/AddExternalProject.cmake: ENH: Simpler AddExternalProject
- download step
-
- This simplifies the implementation with
- add_external_project_step.
-
-2009-03-30 11:36 king
-
- * Modules/AddExternalProject.cmake,
- Tests/ExternalProject/CMakeLists.txt: ENH: Generalize
- AddExternalProject step creation
-
- This creates function 'add_external_project_step' to centralize
- creation of external project steps. Users may call it to add
- custom steps to external project builds.
-
-2009-03-30 11:35 king
-
- * Modules/AddExternalProject.cmake: ENH: Factor argument parsing in
- AddExternalProject
-
- The add_external_project function parses its arguments and puts
- them in properties of the target it creates. This factors out
- implementation of the behavior for use by other functions in the
- module.
-
-2009-03-30 11:35 king
-
- * Modules/AddExternalProject.cmake: ENH: Teach AddExternalProject a
- 'complete' step
-
- This separates creation of the project completion sentinel file
- from the 'install' step to allow more steps to be added in
- between later.
-
-2009-03-30 10:56 clinton
-
- * Source/QtDialog/CMakeSetupDialog.cxx:
- ENH: Add version info to about dialog, including Qt version.
-
-2009-03-30 08:27 malaterre
-
- * Source/kwsys/testIOS.cxx: COMP: missing string.h header for
- strlen.
-
-2009-03-30 08:27 king
-
- * Source/: cmAddCustomCommandCommand.h, cmAddCustomTargetCommand.h:
- ENH: Document scope of add_custom_command outputs
-
- This explicitly states the scope of add_custom_command rules in
- the documentation of add_custom_command and add_custom_target.
- See issue #8815.
-
-2009-03-30 04:10 malaterre
-
- * Source/kwsys/testIOS.cxx: ENH: remote debugging of sunos
-
-2009-03-30 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-29 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-28 13:02 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: STYLE: fix line lenght
-
-2009-03-28 10:23 hoffman
-
- * Utilities/Release/: vogon_release.cmake, vogon_release_qt.cmake:
- ENH: change qt to 4.5
-
-2009-03-28 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-27 21:57 hoffman
-
- * Tests/MacroTest/context.cmake: ENH: add missing file to branch
-
-2009-03-27 17:11 alex
-
- * Modules/FindAVIFile.cmake: ENH: mark the two variables as
- advanced -remove unnecessary deault search dirs
-
- Alex
-
-2009-03-27 12:33 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: fix for #8686 add
- some more compiler flags
-
-2009-03-27 11:55 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Modules/CMakeSystemSpecificInformation.cmake,
- Modules/CheckCSourceCompiles.cmake,
- Modules/CheckCSourceRuns.cmake,
- Modules/CheckCXXSourceCompiles.cmake,
- Modules/CheckCXXSourceRuns.cmake, Modules/FindBoost.cmake,
- Source/cmCommandArgumentParserHelper.cxx,
- Source/cmExtraCodeBlocksGenerator.cxx,
- Source/cmExtraEclipseCDT4Generator.cxx,
- Source/cmExtraEclipseCDT4Generator.h,
- Source/cmGlobalNMakeMakefileGenerator.cxx,
- Source/cmGlobalUnixMakefileGenerator3.h,
- Source/cmIncludeDirectoryCommand.cxx,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalUnixMakefileGenerator3.h,
- Source/cmLocalVisualStudio6Generator.cxx, Source/cmMakefile.cxx,
- Source/cmProjectCommand.h, Source/cmSourceFile.cxx,
- Source/cmStringCommand.h, Source/cmTarget.cxx,
- Tests/MacroTest/CMakeLists.txt, Tests/Preprocess/CMakeLists.txt,
- Tests/Preprocess/preprocess.c, Tests/Preprocess/preprocess.cxx:
- ENH: merge in from main tree to create RC 2
-
-2009-03-27 11:18 hoffman
-
- * Source/cmGlobalNMakeMakefileGenerator.cxx: ENH: LIBPATH is not
- required for cl to work
-
-2009-03-27 10:49 hoffman
-
- * Utilities/Release/vogon_release.cmake: ENH: fix spaces in path
- escape
-
-2009-03-27 10:37 hoffman
-
- * Utilities/Release/vogon_release.cmake: ENH: use a different cmake
-
-2009-03-27 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-26 11:42 clinton
-
- * Source/QtDialog/QCMakeCacheView.cxx:
- BUG: Don't return checkable flag for item when in the middle of
- configure/generate.
-
-2009-03-26 11:04 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Do a recheck of QT_MAC_USE_COCOA when qmake executable
- changes.
-
-2009-03-26 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-25 15:29 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Support OUTPUT_LOCATION property for qm files. Fixes
- #8492.
-
-2009-03-25 10:37 hoffman
-
- * Tests/MacroTest/context.cmake: file context.cmake was added on
- branch CMake-2-6 on 2009-03-28 01:57:34 +0000
-
-2009-03-25 10:36 king
-
- * Source/cmCommandArgumentParserHelper.cxx,
- Tests/MacroTest/CMakeLists.txt, Tests/MacroTest/context.cmake:
- BUG: Fix CMAKE_CURRENT_LIST_FILE in macros
-
- The value of CMAKE_CURRENT_LIST_FILE is supposed to be the list
- file currently being executed. Before macros were introduced
- this was always the context of the argument referencing the
- variable.
-
- Our original implementation of macros replaced the context of
- command arguments inside the macro with that of the arguments of
- the calling context. This worked recursively, but only worked
- when macros had at least one argument. Furthermore, it caused
- parsing errors of the arguments to report the wrong location
- (calling context instead of line with error).
-
- The commit "Improve context for errors in macros" fixed the
- latter bug by keeping the lexical context of command arguments in
- macros. It broke evaluation of CMAKE_CURRENT_LIST_FILE because
- the calling context was no longer preserved in the argument
- referencing the variable. However, since our list file
- processing now maintains the proper value of
- CMAKE_CURRENT_LIST_FILE with dynamic scope we no longer need the
- context of the argument and can just evaluate the variable
- normally.
-
-2009-03-25 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-24 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-23 15:46 hoffman
-
- * CMakeLists.txt: ENH: put an rc number other than 0 in
-
-2009-03-23 14:48 king
-
- * Source/cmLocalVisualStudio6Generator.cxx, Source/cmMakefile.cxx,
- Source/cmSourceFile.cxx, Source/cmTarget.cxx,
- Tests/Preprocess/CMakeLists.txt, Tests/Preprocess/preprocess.c,
- Tests/Preprocess/preprocess.cxx: ENH: Support preprocessor def
- values in VS6
-
- The add_definitions() command and COMPILE_DEFINITIONS dir/tgt/src
- properties support preprocessor definitions with values.
- Previously values were not supported in the VS6 generator even
- though the native tool supports them. It is only values with
- spaces that VS6 does not support. This enables support and
- instead complains only for values with spaces. See issue #8779.
-
-2009-03-23 14:04 hoffman
-
- * Tests/: CMakeTests/GetFilenameComponentRealpathTest.cmake.in,
- Fortran/include/test_preprocess.h: ENH: add missing files
-
-2009-03-23 13:58 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Docs/cmake-mode.el,
- Modules/CMakeASMInformation.cmake,
- Modules/Platform/Darwin-icc.cmake, Modules/Platform/Darwin.cmake,
- Modules/Platform/UnixPaths.cmake, Source/cmCPluginAPI.cxx,
- Source/cmDependsFortran.cxx, Source/cmDependsFortranParser.cxx,
- Source/cmDependsFortranParser.y, Source/cmDocumentVariables.cxx,
- Source/cmDocumentationFormatterMan.cxx, Source/cmFileCommand.cxx,
- Source/cmGetFilenameComponentCommand.cxx,
- Source/cmGetFilenameComponentCommand.h,
- Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmGlobalXCodeGenerator.cxx,
- Source/cmGlobalXCodeGenerator.h, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmMakeDepend.cxx, Source/cmMakeDepend.h,
- Source/cmMakefile.cxx, Source/cmMakefileTargetGenerator.cxx,
- Source/cmSourceFile.cxx, Source/cmTarget.cxx, Source/cmake.cxx,
- Source/CTest/cmCTestUpdateHandler.cxx,
- Source/kwsys/SystemTools.cxx, Source/kwsys/SystemTools.hxx.in,
- Tests/CMakeTests/CMakeLists.txt, Tests/Fortran/CMakeLists.txt,
- Tests/Fortran/test_preprocess.F90: ENH: check in changes to
- branch, most importantly the header file do not compile fix
-
-2009-03-23 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-22 17:13 lowman
-
- * Modules/FindGTK2.cmake: ENH: NEW: FindGTK2 module
-
-2009-03-22 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-21 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-20 23:52 lowman
-
- * Modules/FindBoost.cmake: BUG: LIST(REMOVE_ITEM...) was being
- called on a variable that could be empty.
-
-2009-03-20 14:19 king
-
- * Source/CTest/: cmCTestUpdateCommand.h, cmCTestUpdateHandler.cxx:
- BUG: Fix return value of ctest_update
-
- The CTest version control refactoring broke the value returned
- for the ctest_update command's RETURN_VALUE argument. The value
- is supposed to be the number of files updated, but the
- refactoring accidentally made it the number of locally modified
- files after the update.
-
-2009-03-20 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-19 22:48 fbertel
-
- * Source/kwsys/: SystemInformation.cxx, SystemInformation.hxx.in:
- COMP:Fixed warnings with gcc 4.3.2.
-
-2009-03-19 15:44 clinton
-
- * Modules/FindQt4.cmake:
- BUG: Need to fix find of qtmain library when qmake executable is
- changed.
-
-2009-03-19 11:48 fbertel
-
- * Source/kwsys/CommandLineArguments.cxx: COMP:Try to fix error on
- HP.
-
-2009-03-19 10:53 king
-
- * Source/cmTarget.cxx: ENH: Mention CMAKE_* variables in RPATH
- properties
-
- The RPATH target properties are initialized by CMAKE_<prop>
- variables at target creation time. This notes the feature in the
- property documentation. It is already noted in the variable
- documentation.
-
-2009-03-19 10:03 fbertel
-
- * Source/kwsys/RegularExpression.hxx.in: COMP:try to fix error on
- qnx-V3.3.5-gcc_ntox86.
-
-2009-03-19 09:20 fbertel
-
- * Source/kwsys/CommandLineArguments.cxx: COMP:Fixed warnings.
-
-2009-03-19 09:09 fbertel
-
- * Source/kwsys/RegularExpression.hxx.in: COMP:Fixed VS 64-bit
- warning C4267 line 432 of RegularExpression.cxx
-
-2009-03-19 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-18 11:01 king
-
- * Modules/AddExternalProject.cmake: STYLE: Reminder note for
- add_external_project work
-
-2009-03-18 11:00 king
-
- * Modules/AddExternalProject.cmake,
- Tests/ExternalProject/CMakeLists.txt,
- Tests/ExternalProject/Step1Patch.cmake: ENH: Add patch step for
- add_external_project
-
- The patch step runs parallel to the update step since it does not
- make sense to have both. Configuration of the step requires
- specification of a PATCH_COMMAND argument to
- add_external_project.
-
-2009-03-18 11:00 king
-
- * Modules/AddExternalProject.cmake,
- Tests/ExternalProject/CMakeLists.txt: ENH: Improve
- add_external_project interface
-
- This rewrites the keyword/argument parsing and handling in the
- AddExternalProject module to use arguments more literally:
-
- - The strict keyword-value pairing is gone in favor of keywords
- with
- arbitrary non-keyword values. This avoids requiring users to
- escape
- spaces and quotes in command lines.
-
- - Customized step command lines are now specified with a single
- keyword <step>_COMMAND instead of putting the arguments in a
- separate entry (previously called <step>_ARGS).
-
- - Build step custom commands now use VERBATIM mode so that
- arguments
- are correctly escaped on the command line during builds.
-
-2009-03-18 08:50 fbertel
-
- * Source/kwsys/SystemTools.cxx: COMP:Fixed warnings.
-
-2009-03-18 07:57 fbertel
-
- * Source/kwsys/RegularExpression.cxx: STYLE:Empty commit just add
- information about rev 1.15: the reason is that long is 64-bit on
- gcc on Linux because it uses the LP64 data model whereas long is
- 32-bit on VS 64-bit because it uses the LLP64 model (ref:
- http://en.wikipedia.org/wiki/64-bit#64-bit_data_models )
-
-2009-03-18 07:32 fbertel
-
- * Source/kwsys/RegularExpression.cxx: COMP:Fix warning on VS 64bit.
- Don't why gcc 4.3.2 didn't catch this one on a 64bit machine with
- -Wconversion on.
-
-2009-03-18 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-17 15:11 king
-
- * Source/cmLocalGenerator.cxx: BUG: Allow more shell ops in custom
- commands
-
- This extends the set of common shell operators to include "||",
- "&&", "1>", and "2>". See issue #6868.
-
-2009-03-17 15:10 king
-
- * Source/cmForEachCommand.cxx, Source/cmForEachCommand.h,
- Tests/StringFileTest/CMakeLists.txt: ENH: New foreach(<var> IN
- ...) mode
-
- This creates a new mode of the foreach command which allows
- precise iteration even over empty elements. This mode may be
- safely extended with more keyword arguments in the future. The
- cost now is possibly breaking scripts that iterate over a list of
- items beginning with 'IN', but there is no other way to extend
- the syntax in a readable way.
-
-2009-03-17 10:48 fbertel
-
- * Source/kwsys/: Glob.cxx, RegularExpression.cxx,
- RegularExpression.hxx.in: COMP:Fixed warnings.
-
-2009-03-17 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-16 22:28 lowman
-
- * Modules/FindBoost.cmake: BUG: Eliminates detection of Boost
- system library prior to 1.35 (see issue #8734)
-
-2009-03-16 17:38 fbertel
-
- * Source/kwsys/ProcessUNIX.c: COMP:Try to fix compile error with
- qnx gcc.
-
-2009-03-16 17:13 fbertel
-
- * Source/kwsys/ProcessUNIX.c: COMP:Fixed gcc 4.3.2 warning with -O1
- and above: ignoring return value of read'), declared with
- attribute warn_unused_result
-
-2009-03-16 16:55 king
-
- * Modules/CMakeGenericSystem.cmake,
- Source/cmMakefileExecutableTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.h, Source/cmake.cxx,
- Tests/Complex/CMakeLists.txt,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexRelativePaths/CMakeLists.txt: ENH: Allow projects to
- disable per-rule echo lines
-
- This creates global property RULE_MESSAGES which can be set to
- disbale per-rule progress and action reporting. On Windows,
- these reports may cause a noticable delay due to the cost of
- starting extra processes. This feature will allow scripted
- builds to avoid the cost since they do not need detailed
- information anyway. This replaces the RULE_PROGRESS property
- created earlier as it is more complete. See issue #8726.
-
-2009-03-16 16:55 king
-
- * Source/cmMakefileLibraryTargetGenerator.cxx: STYLE: Separate
- unrelated logic
-
- This separates unrelated uses of a library-type switch into
- separate switches. An upcoming commit will conditionally enter
- one of the switches.
-
-2009-03-16 16:22 king
-
- * Modules/CMakeGenericSystem.cmake,
- Source/cmMakefileTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.h, Source/cmake.cxx,
- Tests/Complex/CMakeLists.txt,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexRelativePaths/CMakeLists.txt: ENH: Allow projects to
- disable per-rule progress
-
- This creates global property RULE_PROGRESS which can be set to
- disbale per-rule progress reporting. On Windows, progress
- reports may cause a noticable delay due to the cost of starting
- an extra process. This feature will allow scripted builds to
- avoid the cost since they do not need detailed progress anyway.
- See issue #8726.
-
-2009-03-16 16:22 king
-
- * Source/: cmMakefileTargetGenerator.cxx,
- cmMakefileTargetGenerator.h: ENH: Factor out makefile progress
- rule commands
-
- This factors duplicate progress rule code into a common method.
-
-2009-03-16 15:02 fbertel
-
- * Source/kwsys/ProcessUNIX.c: COMP:Fixed warnings.
-
-2009-03-16 14:30 king
-
- * Source/: cmCPluginAPI.cxx, cmGlobalXCodeGenerator.cxx,
- cmGlobalXCodeGenerator.h, cmSourceFile.cxx: BUG: Do not
- automatically set HEADER_FILE_ONLY
-
- Long ago the native build system generators needed
- HEADER_FILE_ONLY to be set on header files to stop them from
- building. The modern generators correctly handle headers without
- the help of this property. This removes automatic setting of the
- property so that it can be used reliably as an indicator of
- project author intention. It fixes VS IDE project files to show
- header files normally instead of excluded (broken by the fix for
- issue #7845).
-
-2009-03-16 14:30 king
-
- * Source/: cmMakeDepend.cxx, cmMakeDepend.h: ENH: Remove unused
- code from cmMakeDepend
-
- This class is the old-style dependency scanner. It is needed
- only to implement the output_required_files command. This change
- removes some code not needed for that purpose, including a
- reference to the HEADER_FILE_ONLY property.
-
-2009-03-16 10:51 king
-
- * Source/cmAddTestCommand.cxx, Source/cmAddTestCommand.h,
- Source/cmTest.cxx, Source/cmTest.h, Source/cmTestGenerator.cxx,
- Source/cmTestGenerator.h, Tests/Testing/CMakeLists.txt,
- Tests/Testing/perconfig.c: ENH: Add NAME mode to ADD_TEST command
-
- This creates command mode add_test(NAME ...). This signature is
- extensible with more keyword arguments later. The main purpose
- is to enable automatic replacement of target names with built
- target file locations. A side effect of this feature is support
- for tests that only run under specific configurations.
-
-2009-03-16 10:42 king
-
- * Source/: cmAddTestCommand.cxx, cmTest.cxx, cmTest.h,
- cmTestGenerator.cxx: ENH: Refactor storage of test command lines
-
- We used to separate the command executable from its argument
- vector. It is simpler to just store the whole command line in
- one vector.
-
-2009-03-16 10:40 king
-
- * Source/CMakeLists.txt, Source/cmAddTestCommand.cxx,
- Source/cmLocalGenerator.cxx, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmTestGenerator.cxx,
- Source/cmTestGenerator.h, bootstrap: ENH: Refactor generation of
- CTestTestfile content
-
- This moves code which generates ADD_TEST and SET_TESTS_PROPERTIES
- calls into CTestTestfile.cmake files out of cmLocalGenerator and
- into a cmTestGenerator class. This will allow more advanced
- generation without cluttering cmLocalGenerator. The
- cmTestGenerator class derives from cmScriptGenerator to get
- support for per-configuration script generation (not yet
- enabled).
-
-2009-03-16 10:39 king
-
- * Source/CMakeLists.txt, Source/cmInstallGenerator.cxx,
- Source/cmInstallGenerator.h, Source/cmInstallTargetGenerator.cxx,
- Source/cmInstallTargetGenerator.h, Source/cmScriptGenerator.cxx,
- Source/cmScriptGenerator.h, bootstrap: ENH: Refactor
- cmInstallGenerator for re-use
-
- A new cmScriptGenerator base class factors out the
- non-install-specific part of cmInstallGenerator. This will be
- useful for other generators that want per-configuration
- functionality.
-
-2009-03-16 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-15 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-14 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-13 17:04 alex
-
- * Source/cmExtraEclipseCDT4Generator.cxx: ENH: don't enforce
- VERBOSE Makefiles, but set the env. var VERBOSE to 1 in when make
- is executed from within Eclipse. This way when building from the
- command line one can build also in non-verbose mode.
-
- Alex
-
-2009-03-13 16:52 alex
-
- * Modules/CMakeSystemSpecificInformation.cmake,
- Source/cmExtraEclipseCDT4Generator.cxx,
- Source/cmExtraEclipseCDT4Generator.h: ENH: when using the Eclipse
- project generator, run gcc so that it tells us its system include
- directories. These are catched in
- CMakeSystemSpecificInformation.cmake (only with the Eclipse
- generator) and then written by the Eclipse generator in the
- Eclipse project file. This way Eclipse can find the standard
- headers (#7585) Not sure CMakeSystemSpecificInformation.cmake is
- the best place to do this.
-
- Alex
-
-2009-03-13 14:58 alex
-
- * Source/cmStringCommand.h: STYLE: add line breaks to the
- documentation for CMAKE_MATCH_(0..9), otherwise one might miss
- this information
-
- Alex
-
-2009-03-13 10:53 king
-
- * Source/cmCacheManager.cxx: BUG: Document internal cache property
- MODIFIED
-
- All cmake-defined properties should be documented, even if they
- are internal. This fixes the DocTest when CMAKE_STRICT is
- enabled.
-
-2009-03-13 10:53 king
-
- * Source/: cmCacheManager.cxx, cmCacheManager.h, cmake.cxx: BUG:
- Fix cache properties for CMAKE_STRICT build
-
- All cmPropertyMap instances must have CMakeInstance set. This
- teaches cmCacheManager to set it on cache entries.
-
-2009-03-13 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-12 21:06 lowman
-
- * Modules/FindBoost.cmake: STYLE: Moved functions/macros to top of
- file so main is more readable.
-
-2009-03-12 19:24 alex
-
- * Source/cmIncludeDirectoryCommand.cxx: BUG: fix #8704, sometimes
- crash if include_directories() is called with a whitespace string
-
- Alex
-
-2009-03-12 18:43 alex
-
- * Source/cmProjectCommand.h: STYLE: document NONE for disabling any
- languages, slightly change wording of the rest of the
- documentation, so it is more similar to ENABLE_LANGUAGE() (#8718)
-
- Alex
-
-2009-03-12 14:54 hoffman
-
- * Source/CTest/cmCTestSubmitHandler.cxx: ENH: allow for https
- submission if ctest is built with a curl that supports it
-
-2009-03-12 13:11 king
-
- * Source/cmCacheManager.cxx: COMP: Do not use void returns
-
- VS 6 does not support the C++ void returns feature. This removes
- an accidental use of it.
-
-2009-03-12 11:19 clinton
-
- * Source/QtDialog/: QCMake.cxx, QCMake.h, QCMakeCacheView.cxx,
- QCMakeCacheView.h, QCMakeWidgets.h:
- ENH: Add support for showing combo box for choosing from a list
- of strings that a cache property can have.
-
-2009-03-12 10:52 king
-
- * Source/: cmCacheManager.cxx, cmSetPropertyCommand.cxx: ENH:
- Define STRINGS cache entry property
-
- This property defines a list of values for a cache entry of type
- STRING. A CMake GUI may optionally use a drop-down selection
- widget for the entry instead of a generic text entry field. We
- do not enforce that the value of the entry match one of the
- strings listed.
-
-2009-03-12 10:49 king
-
- * Source/: cmCacheManager.cxx, cmCacheManager.h: ENH: Refactor
- cache entry writing and reading
-
- This factors out duplicated code into reusable methods, thus
- simplifying writing and reading of cache entry help strings,
- keys, values, and properties.
-
-2009-03-12 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-11 18:13 alex
-
- * Modules/: CheckCSourceCompiles.cmake, CheckCSourceRuns.cmake,
- CheckCXXSourceCompiles.cmake, CheckCXXSourceRuns.cmake: STYLE:
- fix documentation: the second short description discarded the
- first one, but the first one was the correct one (i.e. the one
- which mentioned that CheckC[XX]SourceRuns.cmake also tries to run
- the executable)
-
- Alex
-
-2009-03-11 13:31 king
-
- * Source/CTest/cmCTestCoverageHandler.cxx: BUG: Do not produce
- empty coverage log files
-
- This moves the filtering of source files to before the production
- of coverage log files in order to avoid producing a
- CoverageLog-*.xml file for 100 filtered-out files. The change
- greatly reduces the number of submitted coverage files when using
- label filters.
-
-2009-03-11 13:31 king
-
- * Source/: CTest/cmCTestCoverageHandler.cxx, cmCTest.h: BUG: Do not
- carry over file list between coverage
-
- When performing multiple ctest_coverage() commands in a single
- CTest instance we need to clear the list of CoverageLog-*.xml
- files for submission. Otherwise if the current coverage run
- produces fewer log files than the previous run CTest will attempt
- to submit non-existing files.
-
-2009-03-11 12:03 king
-
- * Source/CTest/: cmCTestCoverageHandler.cxx,
- cmCTestCoverageHandler.h: BUG: Avoid duplicate CTest coverage
- submission
-
- This teaches ctest_coverage() to remove any existing
- CoverageLog-*.xml when it creates new coverage results.
- Otherwise the next ctest_submit() may submit old coverage log
- files which unnecessarily.
-
-2009-03-11 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-10 17:34 alex
-
- * Source/cmExtraCodeBlocksGenerator.cxx: ENH: only check for the
- existance of a header file if: -the original file is a C/C++
- implementation file -the header file is not already part of the
- sources
-
- Alex
-
-2009-03-10 11:11 king
-
- * Source/: cmCacheManager.cxx, cmCacheManager.h,
- cmDocumentation.cxx, cmake.cxx: ENH: Document CACHE entry
- properties
-
- This adds a property documentation section for CACHE properties.
- We document the ADVANCED, HELPSTRING, TYPE, and VALUE properties.
-
-2009-03-10 11:10 king
-
- * Source/cmCacheManager.cxx, Source/cmCacheManager.h,
- Source/cmGetPropertyCommand.cxx, Source/cmGetPropertyCommand.h,
- Source/cmSetPropertyCommand.cxx, Source/cmSetPropertyCommand.h,
- Tests/Properties/CMakeLists.txt: ENH: Teach set/get_property
- about CACHE properties
-
- This adds the CACHE option to set_property and get_property
- commands. This allows full control over cache entry information,
- so advanced users can tweak their project cache as desired. The
- set_property command allows only pre-defined CACHE properties to
- be set since others would not persist anyway.
-
-2009-03-10 11:10 king
-
- * Source/: cmCacheManager.cxx, cmCacheManager.h, cmProperty.h,
- cmPropertyDefinitionMap.cxx: ENH: Use cmPropertyMap for cache
- properties
-
- This re-implements cache entry property storage in cmCacheManager
- to use cmPropertyMap so it can share the standard property
- implementation.
-
-2009-03-10 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-09 17:57 king
-
- * Source/cmGetPropertyCommand.cxx: BUG: Fix get_property result for
- bad property
-
- When a property does not exist we are supposed to return an empty
- value. Previously if a property did not exist we just left the
- value of the output variable unchanged. This teaches CMake to
- remove the definition of the output variable in this case.
-
-2009-03-09 12:19 king
-
- * Source/CTest/: cmCTestCoverageHandler.cxx,
- cmCTestCoverageHandler.h: ENH: Efficiently filter CTest coverage
- by label
-
- This teaches CTest to process coverage information only for
- object files in targets containing labels of interest. This
- change also improves loading of global coverage information by
- globbing only in each target support directory instead of the
- entire build tree.
-
-2009-03-09 12:19 king
-
- * Source/: CTest/cmCTestCoverageHandler.cxx, cmGlobalGenerator.cxx,
- cmGlobalGenerator.h, CTest/cmCTestCoverageHandler.h: ENH:
- Generate a central list of target directories
-
- This generalizes the previous CMakeFiles/LabelFiles.txt created
- at the top of the build tree to a
- CMakeFiles/TargetDirectories.txt file. It lists the target
- support directories for all targets in the project. Labels can
- still be loaded by looking for Labels.txt files in each target
- directory.
-
-2009-03-09 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-08 15:33 alex
-
- * Source/cmExtraCodeBlocksGenerator.cxx:
- ENH: automatically add headers of implementation file to the
- codeblocks project file
-
- Alex
-
-2009-03-08 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-07 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-06 14:29 david.cole
-
- * Tests/CMakeTests/GetPrerequisitesTest.cmake.in: STYLE: White
- space only change to see if continuous is working on new
- dashboard machine...
-
-2009-03-06 12:06 king
-
- * Source/: cmMessageCommand.cxx, cmMessageCommand.h: BUG: Fix
- message(SEND_ERROR) to continue
-
- During testing of the new message() signatures I mistakenly
- concluded that SEND_ERROR stops processing. The corresponding
- commit enforced this wrong behavior. This restores the correct
- behavior and fixes the documentation accordingly.
-
-2009-03-06 10:04 king
-
- * Source/cmMessageCommand.cxx, Source/cmMessageCommand.h,
- Tests/CMakeTests/CMakeLists.txt,
- Tests/CMakeTests/MessageTest.cmake.in,
- Tests/CMakeTests/MessageTestScript.cmake: ENH: Teach message()
- how to display warnings
-
- This adds message(WARNING) and message(AUTHOR_WARNING) command
- modes and fully documents the command behavior in all modes.
-
-2009-03-06 10:01 king
-
- * Source/cmDocumentationFormatterMan.cxx: BUG: Fix man-page
- preformatted text paragraphing
-
- Man page preformatted text needs an extra newline after the
- ending marker to create a paragraph break. This bug was
- introduced by the patch from issue #7797 to place explicit ".nf"
- and ".fi" markers around preformatted blocks.
-
-2009-03-06 09:14 king
-
- * Source/cmFileCommand.cxx: ENH: Teach file(REMOVE) how to use
- relative paths
-
- This teaches the command to interpret relative paths with respect
- to the location of the invoking CMakeLists.txt file. The
- convention is already used by most commands and won't change the
- behavior in script mode.
-
-2009-03-06 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-05 15:17 king
-
- * CMakeCPack.cmake, CMakeLists.txt, bootstrap,
- Source/CMakeLists.txt, Source/cmCTest.cxx,
- Source/cmCacheManager.cxx, Source/cmConfigure.cmake.h.in,
- Source/cmDocumentVariables.cxx, Source/cmLocalGenerator.cxx,
- Source/cmStandardIncludes.h, Source/cmVersion.cxx,
- Source/cmVersion.h, Source/cmVersionConfig.h.in,
- Source/cmVersionMacros.h, Source/cmake.cxx,
- Source/CursesDialog/cmCursesLongMessageForm.cxx,
- Source/CursesDialog/cmCursesMainForm.cxx,
- Source/QtDialog/CMakeSetup.cxx, Tests/CMakeTests/CMakeLists.txt,
- Tests/CMakeTests/VersionTest.cmake.in: ENH: Overhaul CMake
- version numbering
-
- This moves the version numbers into an isolated configured header
- so that not all of CMake needs to rebuild when the version
- changes.
-
- Previously we had spaces, dashes and/or the word 'patch' randomly
- chosen before the patch number. Now we always report version
- numbers in the traditional format
- "<major>.<minor>.<patch>[-rc<rc>]".
-
- We still use odd minor numbers for development versions. Now we
- also use the CCYYMMDD date as the patch number of development
- versions, thus allowing tests for exact CMake versions.
-
-2009-03-05 13:57 king
-
- * Source/: cmake.cxx, cmake.h: STYLE: Remove unused
- cmake::CacheVersionMatches
-
- This remove the method completely since nothing uses it.
-
-2009-03-05 10:17 king
-
- * Source/CTest/: cmCTestCoverageCommand.cxx,
- cmCTestCoverageCommand.h: BUG: Initialize ctest_coverage command
- ivar
-
- This initializes the LabelsMentioned ivar in
- cmCTestCoverageCommand.
-
-2009-03-05 10:08 david.cole
-
- * Modules/CPack.cmake: STYLE: Use $ style variable dereference
- instead of @ style.
-
-2009-03-05 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-04 15:39 king
-
- * Source/cmake.cxx, Source/cmake.h, Source/cmakemain.cxx,
- Tests/CMakeBuildTest.cmake.in: ENH: Cleanup cmake --build
- interface.
-
- This cleans up the 'cmake --build' command-line interface: -
- Rename --clean to --clean-first to better describe it. -
- Replace --extra-options with a -- separator to simplify passing
- of multiple native build tool options. - Document the
- options in the main CMake man page description of the
- --build option, and shares this with the usage message. -
- Require --build to be the first argument when present. - Move
- implementation into cmakemain where it belongs.
-
-2009-03-04 15:38 king
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h: ENH: Extend
- GG::Build method for pre-parsed args
-
- This adds an argument to the cmGlobalGenerator::Build method to
- pass a vector of arguments for the native build tool
- programatically.
-
-2009-03-04 12:30 hoffman
-
- * Modules/CPack.background.png.in: ENH: add file back bug use cmake
- image
-
-2009-03-04 11:45 king
-
- * Modules/AddExternalProject.cmake,
- Tests/ExternalProject/CMakeLists.txt: ENH: Better recursive make
- in AddExternalProject
-
- This teaches AddExternalProject to run "$(MAKE)" for build and
- install steps of CMake-based external projects when using a
- Makefile generator. It allows the external project to
- participate in a parallel make invoked on the superproject.
-
-2009-03-04 11:24 hoffman
-
- * Source/CTest/cmCTestScriptHandler.cxx: BUG: make sure error
- condition is reset before loading scripts
-
-2009-03-04 09:21 king
-
- * Modules/AddExternalProject.cmake: ENH: Allow empty arguments in
- external project API
-
- This uses the get_property command to simplify property lookup in
- the AddExternalProject module. It distinguishes for build and
- install argument properties the cases of unset and set to empty.
-
-2009-03-04 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-03 07:56 hoffman
-
- * Modules/CPack.background.png.in: ENH: remove unused file
-
-2009-03-03 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-02 21:09 lowman
-
- * Modules/FindBoost.cmake: STYLE: Fix documentation bug regarding
- Boost_<COMPONENT>_LIBRARY (COMPONENT should be uppercase).
-
-2009-03-02 20:29 lowman
-
- * Modules/FindCxxTest.cmake: ENH: Detect perl & python scripts
- based on CXXTEST_INCLUDE_DIR (patch from Tyler Roscoe on mailing
- list).
-
-2009-03-02 16:27 king
-
- * Source/cmXMLSafe.cxx: BUG: Avoid encoding invalid XML chars in
- CTest
-
- CTest encodes test and tool output in XML for dashboard
- submission. This fixes the XML encoding implementation to not
- encode an invalid character and instead put a human-readable tag
- in its place. See issue #8647.
-
-2009-03-02 16:02 king
-
- * Source/cmake.cxx: BUG: Gracefully handle broken version symlinks
-
- This teaches the helper commands 'cmake -E
- cmake_symlink_executable' and 'cmake -E cmake_symlink_library' to
- remove broken symlinks before creating a symlink and report an
- error when the symlink cannot be created. See issue #8654.
-
-2009-03-02 15:33 king
-
- * Source/CTest/: cmCTestCoverageCommand.cxx,
- cmCTestCoverageCommand.h, cmCTestCoverageHandler.cxx,
- cmCTestCoverageHandler.h: ENH: Teach ctest_coverage to filter
- with LABELS
-
- This teaches ctest_coverage() to report only coverage of files
- labeled with at least one label given by a new LABELS option.
-
-2009-03-02 15:33 king
-
- * Source/CTest/cmCTestCoverageHandler.cxx: BUG: Fix coverage label
- reports for Bullseye
-
- This teaches CTest to report Labels elements in the Coverage.xml
- file for Bullseye coverage results.
-
-2009-03-02 15:32 king
-
- * Source/CTest/cmCTestCoverageHandler.cxx: BUG: Fix coverage
- handler initialization
-
- This resets coverage handler internal state on initialization so
- that multiple coverage runs are independent.
-
-2009-03-02 09:59 king
-
- * Source/cmXMLSafe.cxx: BUG: Hack for issue #8647
-
-2009-03-02 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-03-01 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-28 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-27 16:28 hoffman
-
- * Source/CTest/cmCTestTestHandler.cxx: BUG: #8611 add pass fail
- reasons into log file
-
-2009-02-27 13:08 king
-
- * Modules/CMakeASMInformation.cmake: BUG: Fix ASM source file
- extension default list
-
- This replaces @ASM_DIALECT@ syntax with ${ASM_DIALECT} syntax so
- it will be replaced correctly. Patch from Derek Bruening. See
- issue #8639.
-
-2009-02-27 12:59 king
-
- * Source/cmMakefileTargetGenerator.cxx: BUG: Pass shared library
- export symbol in DEFINES
-
- The <target>_EXPORTS macro defined for object files when built in
- a shared library <target> should be put in the <DEFINES> make
- rule replacement and not <FLAGS>. Also, it should honor the
- platform variable CMAKE_<LANG>_DEFINE_FLAG. See issue #8107.
-
-2009-02-27 11:23 king
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmMakefile.cxx: ENH: Enforce unique binary directories
-
- The second argument of add_subdirectory must name a unique binary
- directory or the build files will clobber each other. This
- enforces uniqueness with an error message.
-
-2009-02-27 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-26 13:28 king
-
- * Docs/cmake-mode.el: BUG: Fix cmake-mode.el indentation cursor
- motion
-
- This makes cursor motion in the indent function consistent with
- emacs conventions. Patch from Mike Wittman. See issue #8625.
-
-2009-02-26 09:22 king
-
- * Source/CTest/: cmCTestUpdateHandler.cxx, cmCTestVC.cxx,
- cmCTestVC.h: ENH: Refactor initial checkout into cmCTestVC
-
- This adds cmCTestVC::InitialCheckout and uses it in
- cmCTestUpdateHandler to run the initial checkout command. The
- new implementation logs the command in the update log
- consistently with the rest of the new update implementation.
-
-2009-02-26 09:22 king
-
- * Tests/: CTestUpdateCVS.cmake.in, CTestUpdateCommon.cmake,
- CTestUpdateSVN.cmake.in: ENH: Extend CTest.UpdateSVN to test
- local mods
-
- This teaches the test to create local modifications in the work
- tree before updating.
-
-2009-02-26 09:16 king
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h: BUG: Use new
- include dir suppresson for all gens
-
- This fixes CMAKE_<LANG>_IMPLICIT_INCLUDE_DIRECTORIES to be used
- for all generators instead of just those that construct their own
- compiler command lines directly. See issue #8598.
-
-2009-02-26 08:49 king
-
- * Source/cmLocalGenerator.cxx: ENH: Simplify reverse
- cmLocalGenerator::Convert
-
- It does not make sense to call the reverse Convert signature (for
- remote paths corresponding to CMake-managed directories) with
- NONE or FULL since they have no path. Patch from Modestas
- Vainius. See issue #7779.
-
-2009-02-26 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-25 17:17 miguelf
-
- * Modules/FindwxWidgets.cmake: BUG: Fix copy/paste error in
- previous commit that references wrong variable
- (wxWidgets_INCLUDE_DIRS instead of wxWidgets_DEFINITIONS).
-
-2009-02-25 16:29 alex
-
- * Modules/FindQt4.cmake: ENH: add patch from Debian, which adds
- support lrelease-qt4 and lupdate-qt4
- http://patch-tracking.debian.net/patch/series/view/cmake/2.6.3-1/FindQt4_qt4_lupdate_lrelease.diff
-
- Alex
-
-2009-02-25 15:45 king
-
- * Source/CTest/: cmCTestSVN.cxx, cmCTestVC.h: COMP: Fix cmCTestVC
- member access for HP compiler
-
- The HP C++ compiler needs some help to allow access to some
- member classes of cmCTestVC.
-
-2009-02-25 14:42 king
-
- * Source/CTest/: cmCTestCVS.cxx, cmCTestCVS.h, cmCTestSVN.cxx,
- cmCTestSVN.h, cmCTestUpdateHandler.cxx, cmCTestVC.cxx,
- cmCTestVC.h: ENH: Rewrite CTest Update implementation
-
- This adds a new VCS update implementation to the cmCTestVC
- hierarchy and removes it from cmCTestUpdateHandler. The new
- implementation has the following advantages:
-
- - Factorized implementation instead of monolithic function
- - Logs vcs tool output as it is parsed (less memory, inline
- messages)
- - Uses one global svn log instead of one log per file
- - Reports changes on cvs branches (instead of latest trunk
- change)
- - Generates simpler Update.xml (only one Directory element per
- dir)
-
- Shared components of the new implementation appear in cmCTestVC
- and may be re-used by subclasses for other VCS tools in the
- future.
-
-2009-02-25 11:44 king
-
- * Modules/Platform/UnixPaths.cmake, Source/cmDocumentVariables.cxx,
- Source/cmLocalGenerator.cxx: ENH: Re-enable system include dir
- suppression
-
- This creates variable CMAKE_<LANG>_IMPLICIT_INCLUDE_DIRECTORIES
- to specify implicit include directories on a per-language basis.
- This replaces the previous platform-wide variable. It is
- necessary to avoid explicit specification of -I/usr/include on
- some compilers (such as HP aCC) because:
-
- 1.) It may break ordering among system include directories
- defined
- internally by the compiler, thus getting wrong system
- headers.
- 2.) It tells the compiler to treat the system include directory
- as a user include directory, enabling warnings in the
- headers.
-
- See issue #8598.
-
-2009-02-25 09:20 king
-
- * Source/CTest/cmCTestVC.cxx: COMP: Fix cmCTestVC char[]->string
- Borland warning
-
- The Borland compiler warns about returning a char[] from a
- function with return type std::string without an explicit
- construction.
-
-2009-02-25 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-24 17:23 hoffman
-
- * Source/CTest/: cmCTestMultiProcessHandler.cxx,
- cmCTestTestHandler.cxx, cmCTestTestHandler.h: ENH: add a CDash
- measured value showing the reason for passed and failed tests
- based on regular expressions
-
-2009-02-24 17:07 king
-
- * Utilities/CMakeLists.txt: BUG: Fix cmake-gui docs generation PATH
- feature
-
- Automatic addition of the Qt DLL location to PATH can be done
- only for generators that use a Windows shell.
-
-2009-02-24 16:49 miguelf
-
- * Modules/: FindwxWidgets.cmake, UsewxWidgets.cmake: BUG: Using
- PROPERTY COMPILE_DEFINITIONS_DEBUG to support Debug only
- preprocessor options (e.g., _DEBUG __WXDEBUG__).
-
-2009-02-24 15:43 king
-
- * Source/: cmXMLParser.cxx, cmXMLParser.h: ENH: Added
- cmXMLParser::FindAttribute method
-
- This method will help subclasses look for element attributes in
- their StartElement methods.
-
-2009-02-24 15:43 king
-
- * Source/: cmXMLParser.cxx, cmXMLParser.h: ENH: Allow cmXMLParser
- subclasses to report errors
-
- This tells cmXMLParser to report error messages through virtual
- method cmXMLParser::ReportError so that subclasses can override
- the default report.
-
-2009-02-24 15:43 king
-
- * Source/CTest/: cmCTestSVN.cxx, cmCTestSVN.h: ENH: Teach
- cmCTestSVN to load repo/tree relation
-
- This teaches cmCTestSVN::NoteNewRevision to save the repository
- URL checked out in the work tree, the repository root, and the
- path below the root to reach the full URL.
-
-2009-02-24 15:43 king
-
- * Source/: cmCTest.cxx, cmCTest.h: ENH: Add cmCTest::DecodeURL
- method
-
- This new method decodes the "percent-encoding" used in URL
- syntax.
-
-2009-02-24 15:37 king
-
- * Modules/Platform/Darwin-icc.cmake, Modules/Platform/Darwin.cmake,
- Source/cmLocalGenerator.cxx, Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Remove implicit
- include dir suppression
-
- We used to suppress generation of -I/usr/include (and on OSX also
- -I/usr/local/include). This behavior seems to cause more trouble
- than it's worth, so I'm removing it until someone encounters the
- original problem it fixed. See issue #8598.
-
-2009-02-24 14:32 hoffman
-
- * Tests/Fortran/include/test_preprocess.h: file test_preprocess.h
- was added on branch CMake-2-6 on 2009-03-23 18:04:12 +0000
-
-2009-02-24 14:32 king
-
- * Tests/Fortran/: CMakeLists.txt, test_preprocess.F90,
- include/test_preprocess.h: ENH: Test included header in Fortran
- preprocessing
-
- This extends the Fortran preprocessing test to include a header
- file through a preprocessor directive.
-
-2009-02-24 14:32 king
-
- * Source/cmDependsFortran.cxx: BUG: Fix Fortran implicit dependency
- include path
-
- The previous change to Source/cmDependsFortran.cxx while
- refactoring implicit dependency scanning configuration rules
- completely broke loading of the include file search path while
- scanning Fortran dependencies. This adds the line that should
- have been added during the previous change to load the include
- path correctly.
-
-2009-02-24 12:52 king
-
- * Source/CTest/: cmCTestSVN.cxx, cmCTestSVN.h,
- cmCTestUpdateHandler.cxx, cmCTestVC.cxx, cmCTestVC.h: ENH: Factor
- out VCS work tree revision checks
-
- This moves checks of the work tree revision before and after
- update from cmCTestUpdateHandler::ProcessHandler into the
- cmCTestVC hierarchy.
-
-2009-02-24 12:50 king
-
- * Source/CTest/: cmCTestUpdateHandler.cxx, cmCTestVC.cxx,
- cmCTestVC.h: ENH: Factor out nightly start time computation
-
- Move generation of the nightly start time string from
- cmCTestUpdateHandler::ProcessHandler into cmCTestVC.
-
-2009-02-24 12:50 king
-
- * Source/CTest/: cmCTestSVN.cxx, cmCTestSVN.h,
- cmCTestUpdateHandler.cxx, cmCTestVC.cxx, cmCTestVC.h: ENH: Factor
- out svn work tree cleanup
-
- This removes work tree cleanup from cmCTestUpdateHandler and adds
- an interface for it in cmCTestVC with an implementation in
- cmCTestSVN.
-
-2009-02-24 12:49 king
-
- * Source/CTest/: cmCTestVC.cxx, cmCTestVC.h: ENH: Create
- cmCTestVC::RunChild and parse helpers
-
- This method will help VCS tool subclasses run child processes and
- log the output while parsing it.
-
-2009-02-24 11:41 king
-
- * Source/cmInstallCommand.cxx, Source/cmInstallCommand.h,
- Source/cmInstallDirectoryGenerator.cxx,
- Source/cmInstallDirectoryGenerator.h,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: Add install(DIRECTORY)
- option 'OPTIONAL'
-
- This adds the OPTIONAL option to the install(DIRECTORY) command.
- It tells the installation rule that it is not an error if the
- source directory does not exist. See issue #8394.
-
-2009-02-24 11:41 king
-
- * Source/cmInstallCommand.cxx: ENH: Refactor install(DIRECTORY)
- argument parsing
-
- We previously used several booleans with at most one set to true
- at a time to track argument parsing state. This refactors it to
- use one enumeration.
-
-2009-02-24 11:08 king
-
- * Source/cmProcessTools.h: COMP: cmProcessTools::OutputParser
- virtual dtor
-
- This class has virtual methods and therefore should have a
- virtual destructor.
-
-2009-02-24 10:40 king
-
- * Source/: CMakeLists.txt, cmProcessTools.cxx, cmProcessTools.h:
- ENH: Create cmProcessTools to parse child output
-
- This class provides a RunProcess method to run a child process
- and send its output to an abstract parsing interface. This also
- provides a simple line parser and logger implementing the parsing
- interface.
-
-2009-02-24 10:39 king
-
- * Source/: CMakeLists.txt, CTest/cmCTestCVS.cxx,
- CTest/cmCTestCVS.h, CTest/cmCTestSVN.cxx, CTest/cmCTestSVN.h,
- CTest/cmCTestUpdateHandler.cxx: ENH: Add cmCTestCVS and
- cmCTestSVN
-
- These cmCTestVC subclasses will implement interaction with CVS
- and SVN tools.
-
-2009-02-24 10:39 king
-
- * Source/: CMakeLists.txt, CTest/cmCTestVC.cxx, CTest/cmCTestVC.h:
- ENH: Create cmCTestVC for VCS interaction
-
- This creates cmCTestVC, the base for a forthcoming class
- hierarchy to interact with version control systems.
-
-2009-02-24 09:34 david.cole
-
- * Source/CPack/cmCPackDragNDropGenerator.cxx: STYLE: Fix line
- length violation.
-
-2009-02-24 09:09 king
-
- * Source/CTest/: cmCTestUpdateHandler.cxx, cmCTestUpdateHandler.h:
- ENH: Factor out VCS tool detection
-
- In cmCTestUpdateHandler, this factors out version control tool
- detection from the monolithic
- cmCTestUpdateHandler::ProcessHandler to separate methods. This
- also places priority on detection of the tool managing the source
- tree since using any other tool will cause errors.
-
-2009-02-24 09:09 king
-
- * Source/CTest/: cmCTestUpdateHandler.cxx, cmCTestUpdateHandler.h:
- ENH: Factor out initial checkout method
-
- This moves the initial checkout code from the monolithic
- cmCTestUpdateHandler::ProcessHandler to a separate method
- cmCTestUpdateHandler::InitialCheckout.
-
-2009-02-24 09:00 king
-
- * Utilities/CMakeLists.txt: ENH: Help cmake-gui docs generation on
- Windows
-
- We use a custom command to run 'cmake-gui --help...' to generate
- the documentation for the application. Since this is a Qt
- application, the executable must find the Qt DLLs in order to
- run. As a convenience, if QtCore4.dll appears next to qmake.exe,
- we put its location in the PATH environment variable when running
- the custom command on Windows.
-
-2009-02-24 00:49 lowman
-
- * Modules/FindBoost.cmake: BUG: Fix issue #8576 FindBoost
- regression finding static libs, impacts MinGW and Intel/Windows
- compilers.
-
-2009-02-24 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-23 16:54 king
-
- * Tests/CTestUpdateCommon.cmake: BUG: Fix CTest.UpdateCVS/SVN tests
- for win slashes
-
- This fixes the tests to allow windows slashes in reported file
- names in the generated Update.xml file.
-
-2009-02-23 15:59 king
-
- * Source/CTest/cmCTestUpdateHandler.cxx: ENH: Refactor quoting of
- VCS tool command
-
- Previously we pre-quoted the command line tool path. This avoids
- it by quoting the command everywhere it is used, thus preserving
- access to the original, unquoted command.
-
-2009-02-23 15:59 king
-
- * Tests/CTestUpdateSVN.cmake.in: ENH: Test svn updates with space
- in author name
-
- This enhances the CTest.UpdateSVN test with a space in the test
- author name. It will check that author name parsing works
- correctly.
-
-2009-02-23 15:59 king
-
- * Tests/: CTestUpdateCVS.cmake.in, CTestUpdateCommon.cmake,
- CTestUpdateSVN.cmake.in: ENH: Enhance CTest.UpdateCVS/SVN tests
-
- This adds a source tree subdirectory to the content of the test
- projects. It also smoke tests more than one revision worth of
- changes.
-
-2009-02-23 15:58 king
-
- * Tests/CTestUpdateCommon.cmake: ENH: Better failure output from
- CTest.Update*
-
- This teaches CTestUpdateCommon to report the process exit
- condition from failed child processes executed during tests.
-
-2009-02-23 13:25 david.cole
-
- * Source/CPack/cmCPackDragNDropGenerator.cxx: ENH: Add license file
- presentation to the Drag-N-Drop dmg file CPack generator. Fixes
- issue #8442. Thanks to Clinton Stimpson for the patch.
-
-2009-02-23 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-22 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-21 14:43 hoffman
-
- * Source/QtDialog/CMakeSetup.cxx: BUG: make sure you can build
- cmake without an X server
-
-2009-02-21 14:38 hoffman
-
- * Source/QtDialog/CMakeSetup.cxx: BUG: make sure the gui still
- runs...
-
-2009-02-21 14:23 hoffman
-
- * Source/QtDialog/CMakeSetup.cxx: BUG: make sure an x server is not
- required for the build
-
-2009-02-21 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-20 15:51 king
-
- * Source/CTest/: cmCTestBuildCommand.h, cmCTestConfigureCommand.h,
- cmCTestCoverageCommand.h, cmCTestHandlerCommand.h,
- cmCTestMemCheckCommand.h, cmCTestTestCommand.h: ENH: Document
- APPEND option in ctest_* commands
-
- This adds documentation of the APPEND option to the configure,
- build, test, memcheck, and coverage commands. The docs leave
- specific semantics for the dashboard server to define.
-
-2009-02-20 15:50 king
-
- * Source/CTest/: cmCTestBuildCommand.h, cmCTestConfigureCommand.h,
- cmCTestCoverageCommand.h, cmCTestMemCheckCommand.h,
- cmCTestTestCommand.h, cmCTestUpdateCommand.h: ENH: Improve
- ctest_* command documentation
-
- This corrects the terse documentation and adds detail to the full
- documentation of some commands. It also normalizes the layout of
- the documentation string endings to make adding lines easier.
-
-2009-02-20 15:50 king
-
- * Source/CTest/cmCTestSubmitCommand.h: ENH: More documentation for
- ctest_submit command
-
- This clarifies the terse documentation and lists valid values for
- PARTS.
-
-2009-02-20 14:03 king
-
- * Source/cmDocumentVariables.cxx: ENH: Clarify docs of old
- *_OUTPUT_PATH vars
-
- This clarifies the documentation of EXECUTABLE_OUTPUT_PATH and
- LIBRARY_OUTPUT_PATH to sound less like deprecation.
-
-2009-02-20 11:10 hoffman
-
- * CMakeLists.txt, ChangeLog.manual: ENH: final 2.6.3 commit remove
- RC and clean changelog a bit
-
-2009-02-20 10:14 david.cole
-
- * Source/CPack/: cmCPackDragNDropGenerator.cxx,
- cmCPackDragNDropGenerator.h: STYLE: Fix style line-too-long
- violations.
-
-2009-02-20 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-19 16:04 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Support COMPONENTS argument to find_package(). See
- bug #8542.
-
-2009-02-19 16:02 hoffman
-
- * Tests/BuildDepends/Project/CMakeLists.txt: ENH: merge in fix for
- test on older macs
-
-2009-02-19 15:51 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Support version argument in find_package(). See bug
- #8542.
-
-2009-02-19 15:24 hoffman
-
- * Tests/BuildDepends/Project/CMakeLists.txt: ENH: make sure
- multiple archs are only tested when the work
-
-2009-02-19 11:53 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Source/cmGlobalXCodeGenerator.cxx,
- Tests/BuildDepends/Project/CMakeLists.txt: BUG: fix xcode depend
- issue again with a test
-
-2009-02-19 11:51 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx,
- Tests/BuildDepends/Project/CMakeLists.txt: BUG: fix xcode depend
- issue and add a test for it
-
-2009-02-19 11:20 david.cole
-
- * Source/cmGlobalXCodeGenerator.cxx: BUG: Fix issue #8253 - handle
- xib file extension in Xcode projects so that double clicking on
- xib files opens them up in Interface Builder. Thanks to
- baron_roberts for the patch.
-
-2009-02-19 11:17 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Source/cmGlobalXCodeGenerator.cxx: BUG: fix xcode depend issue
- again on branch
-
-2009-02-19 10:39 david.cole
-
- * Source/CPack/: cmCPackBundleGenerator.cxx,
- cmCPackDragNDropGenerator.cxx, cmCPackDragNDropGenerator.h: BUG:
- A little bit more refactoring from BundleGenerator to
- DragNDropGenerator. See issue #8556. Thanks for Clinton Stimpson
- for the patch.
-
-2009-02-19 10:31 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: BUG: fix depend bug again for
- Xcode
-
-2009-02-19 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-18 12:40 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Source/cmGlobalXCodeGenerator.cxx: ENH: put in fix for Xcode
- rebuild issue on branch
-
-2009-02-18 12:09 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: BUG: use the top level project
- name for the xcode depend helper directory names
-
-2009-02-18 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-17 16:59 david.cole
-
- * Modules/Platform/Darwin.cmake: BUG: Allow third component of Mac
- OSX sw_vers output to be empty. Mac OSX 10.5 was recently
- reinstalled on dashmacmini3 and pointed out the fact that this
- expression is faulty when the reported version is simply 10.5
- rather than 10.5.x... for example. This fixes it.
-
-2009-02-17 11:53 king
-
- * Source/: cmDependsFortranParser.cxx, cmDependsFortranParser.y:
- BUG: Do not use 'char' type as array subscript
-
- This converts uses of 'char' as an array subscript to 'unsigned
- char' to heed the warning from gcc. The subscript must be an
- unsigned type to avoid indexing before the beginning of the
- array. This change avoids a potential crash if input text
- contains a byte value beyond 0x7f.
-
-2009-02-17 11:37 king
-
- * Source/CTest/: cmCTestUpdateHandler.cxx, cmCTestUpdateHandler.h:
- ENH: Remove generation of unused Update.xml parts
-
- This removes generation of some Update.xml content that is not
- used by any Dart1, Dart2, or CDash servers: - Revisions
- elements - Directory attribute of File elements - File
- elements within Author elements The content was generated only
- because the original Dart1 Tcl client generated it, but the
- content was never used.
-
-2009-02-17 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-16 18:09 hoffman
-
- * Utilities/CMakeLists.txt: ENH: add missiong install docs for
- cmake-gui
-
-2009-02-16 14:06 hoffman
-
- * CMakeCPackOptions.cmake.in, CMakeLists.txt, ChangeLog.manual,
- Source/QtDialog/CMakeLists.txt,
- Source/QtDialog/QtDialogCPack.cmake.in: ENH: merge in a few more
- changes for installer on windows and cmake-gui
-
-2009-02-16 13:56 martink
-
- * Source/cmIfCommand.h: ENH: fix style
-
-2009-02-16 11:17 hoffman
-
- * Source/QtDialog/QtDialogCPack.cmake.in: ENH: change name for
- start menu entry
-
-2009-02-16 10:33 king
-
- * Modules/readme.txt: STYLE: Note find_package COMPONENTS in
- modules doc
-
- This mentions the COMPONENTS option of find_package in the module
- author documentation file "Modules/readme.txt". See issue #8539.
-
-2009-02-16 10:01 king
-
- * Source/CTest/cmCTestUpdateHandler.cxx: BUG: Fix svn update logic
- for modified files
-
- The main svn update parsing loop in cmCTestUpdateHandler
- previously had a logic error because the variable 'res' was not
- reset for each iteration. For a locally modified file it would
- report the update info for the previous non-modified file, or
- nothing if there was no previous file. This fixes the logic by
- setting variable 'res' in both control paths for each iteration.
- See issue #8168.
-
-2009-02-16 10:00 king
-
- * Source/CTest/cmCTestUpdateHandler.cxx: STYLE: Fix spelling in
- cmCTestUpdateHandler
-
- This renames the variable 'numModiefied' to 'numModified' to fix
- its spelling. It also renames 'modifiedOrConflict' to
- 'notLocallyModified' to describe its purpose (rather than the
- opposite of its purpose). See issue #8168.
-
-2009-02-16 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-15 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-14 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-13 21:51 hoffman
-
- * Utilities/CMakeLists.txt, CMakeCPackOptions.cmake.in: ENH: add
- cmake gui docs
-
-2009-02-13 18:52 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Allowing finding a relocated Qt installation which contains
- a qt.conf to override the hardcoded paths in qmake. Fixes
- #8532.
-
-2009-02-13 16:29 hoffman
-
- * CMakeCPackOptions.cmake.in: ENH: deprecate CMakeSetup
-
-2009-02-13 16:28 hoffman
-
- * Source/QtDialog/: CMakeLists.txt, QtDialogCPack.cmake.in: ENH:
- take cmake-gui out of beta
-
-2009-02-13 15:49 king
-
- * Source/kwsys/CMakeLists.txt: ENH: Optionally label KWSys targets
- and tests
-
- This provides an API for parent projects to use to specify values
- to be set in the LABELS properties of KWSys libraries,
- executables, and tests.
-
-2009-02-13 15:49 king
-
- * Source/kwsys/CMakeLists.txt: ENH: Add KWSys header files to
- library targets
-
- This adds the configured KWSys header files to the library
- targets that implement their APIs so that they show up in IDE
- project files.
-
-2009-02-13 15:17 king
-
- * Source/CTest/: cmCTestCoverageHandler.cxx,
- cmCTestCoverageHandler.h: ENH: Teach CTest to put labels in
- coverage results
-
- This teaches CTest to include source file labels in coverage
- dashboard submissions. The labels for each source are the union
- of the LABELS property from the source file and all the targets
- in which it is built.
-
-2009-02-13 15:16 king
-
- * Source/CTest/cmCTestCoverageHandler.cxx: STYLE: Remove unused
- variable
-
-2009-02-13 11:49 king
-
- * Source/CTest/cmCTestBuildCommand.cxx: BUG: Fix
- CTEST_USE_LAUNCHERS in dashboard scripts
-
- Since CTest does not currently load configuration settings
- computed at CMake Configure time while running dashboard scripts,
- the ctest_build command must honor the CTEST_USE_LAUNCHERS option
- directly.
-
-2009-02-13 11:49 king
-
- * Source/cmCTest.h: STYLE: Add TODO comment about CTest
- configuration
-
- Currently CTest does not load configuration settings computed at
- CMake Configure time when running a dashboard script. This adds
- a comment describing refactoring that might help resolve the
- problem.
-
-2009-02-13 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-12 13:25 king
-
- * Source/cmGlobalGenerator.cxx: BUG: Fix logic of LabelFiles.txt
- generation
-
- This fixes a dumb logic error which causes generation of
- LabelFiles.txt to try to open the file once for every target with
- labels.
-
-2009-02-12 13:00 king
-
- * Source/CTest/: cmCTestBuildHandler.cxx, cmCTestLaunch.cxx,
- cmCTestLaunch.h: ENH: Report file names relative to source dir
-
- This teaches cmCTestLaunch to report source files that lie under
- the top source directory relative to the top.
-
-2009-02-12 12:50 martink
-
- * Source/cmIfCommand.h: ENH: fix documentation and add docs on
- parenthetical expressions
-
-2009-02-12 10:08 hoffman
-
- * Source/kwsys/SystemInformation.cxx: BUG: #8496 add support for
- system info on haiku
-
-2009-02-12 10:01 king
-
- * Source/CTest/cmCTestBuildHandler.cxx: BUG: Do not drop build
- fragments with same time
-
- When we collect Build.xml fragments generated by 'ctest
- --launch', this lexicographically orders fragments with the same
- time stamp on disk instead of incorrectly dropping duplicates.
-
-2009-02-12 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-11 15:18 king
-
- * Modules/: CTest.cmake, DartConfiguration.tcl.in: ENH: Create
- include(CTest) launcher interface
-
- This defines a new CTest configuration variable
- CTEST_USE_LAUNCHERS. When set to true it puts 'ctest --launch'
- in RULE_LAUNCH_* properties and enables the CTest configuration
- option 'UseLaunchers'. Currently this works only for Makefile
- generators.
-
-2009-02-11 15:18 king
-
- * Source/CTest/: cmCTestBuildHandler.cxx, cmCTestBuildHandler.h:
- ENH: Teach CTest dashboard builds to use launchers
-
- This defines a 'UseLaunchers' CTest configuration option. When
- enabled, CTest skips log scraping from the Build step output.
- Instead it defines the environment variable CTEST_LAUNCH_LOGS to
- a log directory during the build. After the build it looks for
- error-*.xml and warning-*.xml files containing fragments for
- inclusion in Build.xml and submission.
-
- This is useful in conjuction with 'ctest --launch' and the
- RULE_LAUNCH_* properties to get reliable, highly-granular build
- failure reports.
-
-2009-02-11 13:05 hoffman
-
- * Utilities/Release/: ferrari_sgi64_release.cmake,
- release_cmake.sh.in: ENH: add FFLAGS back into release script
-
-2009-02-11 11:57 king
-
- * Source/CTest/cmCTestLaunch.cxx: COMP: Do not use modern empty
- init list syntax
-
- cmCTestLaunch first used an empty initializer list to
- zero-initialize a buffer, but this is not supported on older
- compilers. Instead we avoid the need for initialization
- altogether.
-
-2009-02-11 11:31 king
-
- * Source/: CMakeLists.txt, ctest.cxx, CTest/cmCTestLaunch.cxx,
- CTest/cmCTestLaunch.h: ENH: Create internal 'ctest --launch' tool
-
- This creates an undocumented 'ctest --launch' mode. It launches
- a specified command and optionally records a failure in an xml
- fragment. We will optionally use this in CTest's Build stage to
- record per-rule build failure information when using Makefile
- generators.
-
-2009-02-11 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-10 18:13 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Change FILEPATH to STRING for a list of libraries.
-
-2009-02-10 17:28 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/FindBoost.cmake,
- Modules/FindQt4.cmake, Source/cmCacheManager.cxx,
- Source/cmSystemTools.cxx: ENH: merge in some more fixes for RC 13
-
-2009-02-10 17:25 hoffman
-
- * Source/cmCacheManager.cxx: ENH: fix fix for unc paths
-
-2009-02-10 16:08 hoffman
-
- * Source/cmCTest.cxx: ENH: add label global property to ctest
- scripts
-
-2009-02-10 14:24 hoffman
-
- * Source/: cmCTest.cxx, CTest/cmCTestTestCommand.cxx,
- CTest/cmCTestTestCommand.h, CTest/cmCTestTestHandler.cxx,
- CTest/cmCTestTestHandler.h: ENH: add the ability to run tests by
- labels
-
-2009-02-10 14:19 hoffman
-
- * Source/CTest/cmCTestMultiProcessHandler.cxx: BUG: partial fix for
- 8056 -W now works with -j
-
-2009-02-10 12:56 hoffman
-
- * Modules/FindFLTK.cmake: ENH: change include command
-
-2009-02-10 08:52 king
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h,
- cmLocalUnixMakefileGenerator3.cxx: ENH: Add rule substitutions
- useful for launchers
-
- This defines make rule substitutions <LANGUAGE>, <TARGET_NAME>,
- <TARGET_TYPE>, and <OUTPUT>. They will be useful for
- RULE_LAUNCH_* property values.
-
-2009-02-10 08:51 king
-
- * Modules/CTestTargets.cmake, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalUnixMakefileGenerator3.h, Source/cmMakefile.cxx,
- Source/cmMakefileExecutableTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.cxx, Source/cmTarget.cxx,
- Source/cmake.cxx: ENH: Define RULE_LAUNCH_* properties
-
- This defines global, directory, and target properties
- RULE_LAUNCH_COMPILE, RULE_LAUNCH_LINK, and RULE_LAUNCH_CUSTOM.
- Their values specify 'launcher' command lines which are prefixed
- to compile, link, and custom build rules by Makefile generators.
-
-2009-02-10 08:50 king
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h,
- cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx,
- cmMakefileUtilityTargetGenerator.cxx: ENH: Give target in which
- custom commands build
-
- This gives the cmTarget instance for which custom command rules
- are being generated to
- cmLocalUnixMakefileGenerator3::AppendCustomCommands. It will be
- useful in the future.
-
-2009-02-10 08:50 king
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmSourceFile.cxx, cmTarget.cxx: ENH: Define target and source
- property LABELS
-
- This creates a new LABELS property for targets and source files.
- We write the labels of each target and its source files in
- target-specific locations in the build tree for future use.
-
-2009-02-10 08:50 king
-
- * Source/: cmTarget.cxx, cmTarget.h: ENH: Define target-specific
- support directories
-
- This creates method cmTarget::GetSupportDirectory to compute a
- target-specific support directory in the build tree. It uses the
- "CMakeFiles/<name>.dir" convention already used by the Makefile
- generators. The method will be useful for any code that needs to
- generate per-target information into the build tree for use by
- CMake tools that do not run at generate time.
-
-2009-02-10 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-09 23:05 lowman
-
- * Modules/FindCxxTest.cmake: STYLE: Clarified example to illustrate
- need to call target_link_libraries() in response to Issue #8485.
- Changed CMake commands to lowercase. Added licensing info to
- copyright
-
-2009-02-09 22:39 lowman
-
- * Modules/FindBoost.cmake: BUG: Resolves Issue #8393, Remove
- workarounds in FindBoost once UNC-Path bug is fixed
-
-2009-02-09 22:34 lowman
-
- * Modules/FindBoost.cmake: STYLE: Improved examples, spelling &
- grammar in documentation
-
-2009-02-09 16:45 alex
-
- * Source/cmGlobalUnixMakefileGenerator3.h: COMP: remove unused
- variable TargetSourceFileCount, it seems it is unused since
- version 1.88 of cmGlobalUnixMakefileGenerator3.cxx patch by
- Daniel DOT Teske AT Nokia DOT com
-
- Alex
-
-2009-02-09 16:45 king
-
- * Source/kwsys/SystemTools.cxx: BUG: Work around broken
- GetLongPathName case
-
- On Windows the GetLongPathName API function does not work on some
- filesystems even if the file exists. In this case we should just
- use the original long path name and not the GetShortPathName
- result. See issue #8480.
-
-2009-02-09 16:42 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Support .hpp with automoc.
-
-2009-02-09 16:36 alex
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: STYLE: fix two typos in the
- comments, patch from Daniel DOT Teske AT Nokia DOT com, QtCreator
- developer
-
- Alex
-
-2009-02-09 16:25 chris
-
- * Modules/FindDevIL.cmake: ENH: Made the documentation for
- FindDevIL.cmake cleaner. Changed the XXX_LIBRARYs to
- XXX_LIBRARIES.
-
-2009-02-09 09:23 hoffman
-
- * Tests/CMakeTests/GetFilenameComponentRealpathTest.cmake.in: file
- GetFilenameComponentRealpathTest.cmake.in was added on branch
- CMake-2-6 on 2009-03-23 18:04:12 +0000
-
-2009-02-09 09:23 king
-
- * Source/cmGetFilenameComponentCommand.cxx,
- Source/cmGetFilenameComponentCommand.h,
- Tests/CMakeTests/CMakeLists.txt,
- Tests/CMakeTests/GetFilenameComponentRealpathTest.cmake.in: ENH:
- Add get_filename_component(... REALPATH)
-
- This patch from Philip Lowman creates a REALPATH mode in the
- get_filename_component command. It is like ABSOLUTE, but will
- also resolve symlinks (which ABSOLUTE once did but was broken
- long ago). See issue #8423.
-
-2009-02-09 09:23 king
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: BUG: Fix
- GetRealPath when realpath fails
-
- This patch from Philip Lowman teaches SystemTools::GetRealPath to
- deal with paths that do not exist by dealing with the case that
- realpath returns NULL. See issue #8423.
-
-2009-02-09 08:25 hoffman
-
- * Source/cmCacheManager.cxx: BUG: fix for 0008378, lists with
- FILEPATH and UNC //server/path fail
-
-2009-02-09 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-08 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-07 12:23 clinton
-
- * Modules/FindQt4.cmake:
- BUG: When detecting if qmake executable is changed, don't error
- if path contains regex chars.
-
-2009-02-07 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-06 16:16 hoffman
-
- * ChangeLog.manual: ENH: fix comment
-
-2009-02-06 16:15 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/FindQt4.cmake,
- Modules/UseQt4.cmake, Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmMakefileExecutableTargetGenerator.cxx, Source/cmake.cxx:
- ENH: fix osx bundle re-config issue on branch RC 12
-
-2009-02-06 11:49 king
-
- * Source/cmake.cxx: BUG: Fix OS X FW symlink byproduct dependencies
-
- When testing whether to re-run CMake, a byproduct may be a
- symlink. If so, the existence of the link is important rather
- than the link's target. See issue #8465.
-
-2009-02-06 11:18 king
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx, cmake.cxx: BUG: Fix
- OS X AppBundle/FW byproducts dependencies
-
- App Bundle and Framework directories, symlinks, and Info.plist
- files we create during generation are byproducts, not outputs.
- We should re-run CMake only when they are missing, not when they
- are old. See issue #8465.
-
-2009-02-06 09:08 king
-
- * Source/: cmXMLSafe.cxx, cmXMLSafe.h: COMP: Avoid parameter/member
- shadow in cmXMLSafe
-
- A cmXMLSafe constructor named its parameter 'str' which shadowed
- the name of the 'str' method. This renames the parameter to
- avoid the conflict warning.
-
-2009-02-06 09:03 king
-
- * Source/cmMakefileExecutableTargetGenerator.cxx: BUG: Do not
- re-generate after a AppBundle build
-
- A previous change accidentally added the MacOS content directory
- and Info.plist files created for MACOSX_BUNDLE executables to the
- list of CMake input files. This causes CMake to re-generate the
- project too often. These items should be added to the list of
- CMake output files.
-
-2009-02-06 08:33 king
-
- * Source/cmGetFilenameComponentCommand.cxx,
- Source/cmGetFilenameComponentCommand.h,
- Tests/CMakeTests/CMakeLists.txt,
- Tests/CMakeTests/GetFilenameComponentSymlinksTest.cmake.in: BUG:
- Alternative fix to bug #8423
-
- The patch used to fix this bug used SystemTools::GetRealPath
- which works only for existing files. It broke the case of using
- the command get_filename_component for a non-existing file.
- Also, it changed long-standing behavior in a possibly
- incompatible way even for existing files. This reverts the
- original fix and instead updates the documentation to be
- consistent with the behavior.
-
-2009-02-06 08:15 king
-
- * Source/cmCMakePolicyCommand.h: ENH: Clarify cmake_policy(VERSION)
- documentation
-
- The previous documentation could be interpreted as setting
- policies newer than the given version to OLD instead of unset.
- This clarifies it.
-
-2009-02-06 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-05 23:01 clinton
-
- * Modules/: FindQt4.cmake, UseQt4.cmake:
- ENH: Add support for building with Qt's ActiveX support on
- Windows.
-
-2009-02-05 17:09 king
-
- * Source/cmXMLSafe.cxx: COMP: Avoid warning about signed-char
- comparison
-
- On some compilers 'char' is signed and is therefore always equal
- to or less than 0x7f. In order to avoid the compiler warning we
- perform the comparison with an unsigned char type.
-
-2009-02-05 16:31 king
-
- * Source/: CMakeLists.txt, cmCTest.cxx, cmCTest.h,
- cmSystemTools.cxx, cmSystemTools.h, cmXMLSafe.cxx, cmXMLSafe.h,
- CPack/cmCPackGenerator.cxx, CTest/cmCTestBuildHandler.cxx,
- CTest/cmCTestConfigureHandler.cxx,
- CTest/cmCTestCoverageHandler.cxx,
- CTest/cmCTestMemCheckHandler.cxx, CTest/cmCTestTestHandler.cxx,
- CTest/cmCTestUpdateHandler.cxx: ENH: Create cmXMLSafe to help
- escapes in XML
-
- This class provides easy syntax to efficiently insert blocks of
- data into XML documents with proper escapes. It replaces the old
- cmCTest::MakeXMLSafe and cmSystemTools::MakeXMLSafe methods which
- allocated extra memory instead of directly streaming the data.
-
-2009-02-05 11:04 hoffman
-
- * Source/CMakeLists.txt: ENH: merge in cmakelist file that uses
- drag n drop
-
-2009-02-05 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-04 22:04 hoffman
-
- * Source/CPack/: cmCPackDragNDropGenerator.cxx,
- cmCPackDragNDropGenerator.h: ENH: add missing files
-
-2009-02-04 18:24 david.cole
-
- * Modules/UntarFile.cmake: BUG: Add debug message calls to figure
- out ExternalProject test failure on AIX dashboard.
-
-2009-02-04 17:04 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/FindDoxygen.cmake,
- Modules/FindGDAL.cmake, Modules/FindLua50.cmake,
- Modules/FindLua51.cmake, Modules/FindMPEG2.cmake,
- Modules/FindOpenSceneGraph.cmake, Modules/FindOpenThreads.cmake,
- Modules/FindProducer.cmake, Modules/FindQt4.cmake,
- Modules/Findosg.cmake, Modules/FindosgAnimation.cmake,
- Modules/FindosgDB.cmake, Modules/FindosgFX.cmake,
- Modules/FindosgGA.cmake, Modules/FindosgIntrospection.cmake,
- Modules/FindosgManipulator.cmake, Modules/FindosgParticle.cmake,
- Modules/FindosgProducer.cmake, Modules/FindosgShadow.cmake,
- Modules/FindosgSim.cmake, Modules/FindosgTerrain.cmake,
- Modules/FindosgText.cmake, Modules/FindosgUtil.cmake,
- Modules/FindosgViewer.cmake, Modules/FindosgVolume.cmake,
- Modules/FindosgWidget.cmake, Modules/Findosg_functions.cmake,
- Modules/Platform/Darwin.cmake, Modules/Platform/Haiku.cmake,
- Source/cmInstallFilesCommand.cxx,
- Source/cmInstallProgramsCommand.cxx,
- Source/cmLinkDirectoriesCommand.h, Source/cmLocalGenerator.cxx,
- Source/kwsys/DynamicLoader.cxx,
- Source/kwsys/DynamicLoader.hxx.in: ENH: merge in a few more
- changes for RC 11
-
-2009-02-04 14:34 king
-
- * Source/CTest/cmCTestBuildHandler.cxx: ENH: Re-order generation of
- build summary and xml
-
- This moves the error/warning count summary printed by
- cmCTestBuildHandler to after Build.xml is generated. Later we
- will compute the counts during generation of the xml.
-
-2009-02-04 14:34 king
-
- * Source/CTest/: cmCTestBuildHandler.cxx, cmCTestBuildHandler.h:
- ENH: Refactor Build.xml generation
-
- This divides cmCTestBuildHandler::GenerateDartBuildOutput into
- three methods to generate the header, content, and footer
- components of Build.xml files. It will allow the content
- generation to be replaced later.
-
-2009-02-04 12:38 david.cole
-
- * Source/CTest/cmCTestSubmitHandler.cxx: COMP: Iterator version of
- std::set not available with vs6 implementation of STL. Use
- explicit iteration to insert individual elements one at a time.
- Sigh.
-
-2009-02-04 11:44 hoffman
-
- * CMakeLists.txt, CTestConfig.cmake, CTestCustom.cmake.in,
- ChangeLog.manual, Modules/CPack.OSXX11.Info.plist.in,
- Modules/CPack.RuntimeScript.in, Modules/CPack.cmake,
- Modules/FindBoost.cmake, Modules/FindCxxTest.cmake,
- Modules/FindDevIL.cmake, Modules/FindDoxygen.cmake,
- Modules/FindFLTK.cmake, Modules/FindKDE3.cmake,
- Modules/FindKDE4.cmake, Modules/FindOpenMP.cmake,
- Modules/FindOpenThreads.cmake, Modules/FindQt4.cmake,
- Modules/FindRTI.cmake, Modules/Findosg.cmake,
- Modules/FindosgAnimation.cmake, Modules/FindosgDB.cmake,
- Modules/FindosgFX.cmake, Modules/FindosgGA.cmake,
- Modules/FindosgIntrospection.cmake,
- Modules/FindosgManipulator.cmake, Modules/FindosgParticle.cmake,
- Modules/FindosgProducer.cmake, Modules/FindosgShadow.cmake,
- Modules/FindosgSim.cmake, Modules/FindosgTerrain.cmake,
- Modules/FindosgText.cmake, Modules/FindosgUtil.cmake,
- Modules/FindosgViewer.cmake, Modules/FindosgVolume.cmake,
- Modules/FindosgWidget.cmake, Modules/Findosg_functions.cmake,
- Modules/UseQt4.cmake, Source/cmBootstrapCommands.cxx,
- Source/cmCMakePolicyCommand.cxx, Source/cmCMakePolicyCommand.h,
- Source/cmCoreTryCompile.cxx,
- Source/cmExportBuildFileGenerator.cxx,
- Source/cmFindPackageCommand.cxx, Source/cmFindPackageCommand.h,
- Source/cmForEachCommand.cxx, Source/cmForEachCommand.h,
- Source/cmFunctionBlocker.h, Source/cmFunctionCommand.cxx,
- Source/cmFunctionCommand.h,
- Source/cmGlobalVisualStudio71Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.h,
- Source/cmGlobalXCodeGenerator.cxx, Source/cmIfCommand.cxx,
- Source/cmIfCommand.h, Source/cmIncludeCommand.cxx,
- Source/cmIncludeCommand.h,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmMacroCommand.cxx, Source/cmMacroCommand.h,
- Source/cmMakefile.cxx, Source/cmMakefile.h,
- Source/cmPolicies.cxx, Source/cmPolicies.h, Source/cmTarget.cxx,
- Source/cmUnsetCommand.cxx, Source/cmUnsetCommand.h,
- Source/cmWhileCommand.cxx, Source/cmWhileCommand.h,
- Source/CPack/cmCPackBundleGenerator.cxx,
- Source/CPack/cmCPackBundleGenerator.h,
- Source/CPack/cmCPackGeneratorFactory.cxx,
- Source/CPack/cmCPackLog.cxx,
- Source/CPack/cmCPackNSISGenerator.cxx,
- Source/CPack/cmCPackOSXX11Generator.cxx, Source/CPack/cpack.cxx,
- Tests/CMakeLists.txt, Tests/PolicyScope/Bar.cmake,
- Tests/PolicyScope/CMakeLists.txt,
- Tests/PolicyScope/FindFoo.cmake, Tests/PolicyScope/main.c,
- Tests/Unset/CMakeLists.txt, Tests/Unset/unset.c: ENH: merge in
- changes to 2.6 RC 10
-
-2009-02-04 10:34 king
-
- * Source/: cmInstallFilesCommand.cxx, cmInstallProgramsCommand.cxx,
- cmLocalGenerator.cxx: BUG: Fix old-style install to prefix top
-
- The old install_files, install_programs, and install_targets
- commands used to permit installation to the top of the prefix by
- specifying destination '/'. This was broken in 2.6.0 to 2.6.2 by
- changes to enforce valid destinations that did not account for
- this case. This change fixes the case by converting the install
- destination to '.' which is the new-style way to specify the top
- of the installation prefix.
-
-2009-02-04 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-03 11:52 david.cole
-
- * Source/CTest/: cmCTestSubmitCommand.cxx, cmCTestSubmitCommand.h,
- cmCTestSubmitHandler.cxx, cmCTestSubmitHandler.h: ENH: Add FILES
- arg to the ctest_submit command. BUG: Propagate the IsCDash
- setting properly to the ctest configuration during a submit.
- Also, do not propagate TriggerSite for projects submitting to
- CDash. No triggers are necessary with CDash.
-
-2009-02-03 11:27 hoffman
-
- * Source/kwsys/: DynamicLoader.cxx, DynamicLoader.hxx.in: ENH: fix
- dynamic loading on haiku
-
-2009-02-03 08:38 hoffman
-
- * Modules/FindKDE3.cmake: BUG: fix potential issue with empty
- strings
-
-2009-02-03 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-02 16:30 hoffman
-
- * Modules/FindMPEG2.cmake: BUG: include should not have .cmake
-
-2009-02-02 14:36 king
-
- * Source/cmMakefileTargetGenerator.cxx: BUG: Fix preprocess and
- assembly rule expansion
-
- The recent change to avoid expanding rule variables in
- informational and 'cd' commands broke the logical order in
- generation of preprocess and assembly rules. This corrects the
- order.
-
-2009-02-02 14:36 king
-
- * Source/cmGlobalGenerator.cxx: COMP: Fix rule hash code during
- bootstrap
-
- During bootstrap we do not bother with rule hashing. This
- updates the dummy implementation to account for the recent change
- in rule hash method signatures.
-
-2009-02-02 13:28 king
-
- * Source/cmMakefileTargetGenerator.cxx: BUG: Do not expand rule
- variables in info rules
-
- Previously the makefile generator would expand rule variables
- even on its progress and echo commands for object compilation
- rules (but not for link rules). This fixes the implementation to
- only expand rule variables on user-specified rules.
-
-2009-02-02 13:28 king
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h, cmMakefileTargetGenerator.cxx:
- ENH: Refactor custom command rule hashing
-
- This simplifies computation of custom command rule hashes to hash
- content exactly chosen as the custom commands are generated.
- Unfortunately this will change the hashes of existing build trees
- from earlier CMake versions, but this is not a big deal. The
- change is necessary so that in the future we can make optional
- adjustments to custom command lines at generate time without
- changing the hashes every time the option is changed.
-
-2009-02-02 13:27 king
-
- * Source/: cmMakefile.cxx, cmake.cxx: ENH: More robust property
- lookup
-
- This teaches cmMakefile::GetProperty and cmake::GetProperty
- methods to return NULL when the property name is NULL, making
- them more robust and consistent with the behavior of
- cmTarget::GetProperty.
-
-2009-02-02 13:24 king
-
- * Source/CTest/: cmCTestMemCheckHandler.cxx,
- cmCTestTestHandler.cxx, cmCTestTestHandler.h: ENH: Put test
- labels in MemCheck results
-
- This refactors generation of <Test> element headers and footers
- in cmCTestTestHandler and re-uses it in cmCTestMemCheckHandler.
- The change removes duplicate code and enables the new <Labels>
- element for MemCheck results.
-
-2009-02-02 09:42 king
-
- * Source/cmTargetLinkLibrariesCommand.h: ENH: Clarify
- target_link_libraries docs
-
- The target_link_libraries command supports flags as well as
- libraries. This makes the support explicit in the documentation.
-
-2009-02-02 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-02-01 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-31 13:57 hoffman
-
- * Modules/FindOpenSceneGraph.cmake: file FindOpenSceneGraph.cmake
- was added on branch CMake-2-6 on 2009-02-04 22:04:48 +0000
-
-2009-01-31 13:57 lowman
-
- * Modules/FindOpenSceneGraph.cmake: BUG: Fixes configure error if
- you don't specify a version with find_package()
-
-2009-01-31 01:50 lowman
-
- * Modules/FindGDAL.cmake: BUG: Fix library detection for GDAL on
- most Linux distributions (Issue #7445)
-
-2009-01-31 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-30 20:09 hoffman
-
- * Modules/Findosg_functions.cmake: file Findosg_functions.cmake was
- added on branch CMake-2-6 on 2009-02-04 16:44:16 +0000
-
-2009-01-30 20:09 lowman
-
- * Modules/: FindOpenSceneGraph.cmake, Findosg.cmake,
- Findosg_functions.cmake: ENH: Added FindOpenSceneGraph.cmake
- which is intended to wrap any of the existing Findosg* modules
- (or even user specified modules in CMAKE_MODULE_PATH) and
- aggregate the include dirs & libraries while providing a
- COMPONENT frontend and version checking (Fixes Issue #6973).
- Also added a note to Findosg.cmake to refer new users to the
- module.
-
-2009-01-30 16:55 lowman
-
- * Modules/: FindOpenThreads.cmake, Findosg_functions.cmake: ENH:
- Added OSG_ROOT as supported env var (it's in the wild already).
- Cleaned up FindOpenThreads to support PATH_SUFFIXES. Removed
- superfluous WIN32 registry checks which should have been $ENV{}
- checks.
-
-2009-01-30 15:13 lowman
-
- * Modules/: FindDoxygen.cmake, FindOpenThreads.cmake,
- FindProducer.cmake: BUG: Fix other modules not respecting QUIET
- and REQUIRED
-
-2009-01-30 14:33 hoffman
-
- * Modules/FindosgVolume.cmake: file FindosgVolume.cmake was added
- on branch CMake-2-6 on 2009-02-04 16:44:16 +0000
-
-2009-01-30 14:33 hoffman
-
- * Modules/FindosgWidget.cmake: file FindosgWidget.cmake was added
- on branch CMake-2-6 on 2009-02-04 16:44:16 +0000
-
-2009-01-30 14:33 hoffman
-
- * Modules/FindosgAnimation.cmake: file FindosgAnimation.cmake was
- added on branch CMake-2-6 on 2009-02-04 16:44:13 +0000
-
-2009-01-30 14:33 lowman
-
- * Modules/: Findosg.cmake, FindosgAnimation.cmake, FindosgDB.cmake,
- FindosgFX.cmake, FindosgGA.cmake, FindosgIntrospection.cmake,
- FindosgManipulator.cmake, FindosgParticle.cmake,
- FindosgProducer.cmake, FindosgShadow.cmake, FindosgSim.cmake,
- FindosgTerrain.cmake, FindosgText.cmake, FindosgUtil.cmake,
- FindosgViewer.cmake, FindosgVolume.cmake, FindosgWidget.cmake:
- BUG: The QUIET and REQUIRED find attributes on each Findosg*
- module were not being respected.
-
-2009-01-30 14:29 lowman
-
- * Modules/Findosg_functions.cmake: ENH: Added a mark_as_advanced()
- wrapper function.
-
-2009-01-30 03:02 lowman
-
- * Modules/: FindLua50.cmake, FindLua51.cmake: BUG: Fixes detection
- of lua libraries installed from FreeBSD ports (Issue #8421)
-
-2009-01-30 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-29 15:23 david.cole
-
- * Source/cmCoreTryCompile.cxx: ENH: Emit a little more information
- in the error message when the output file is not found during a
- core try compile.
-
-2009-01-29 14:57 david.cole
-
- * Modules/Platform/Darwin.cmake: BUG: Remove unnecessary double
- quotes from SET statements. Hopefully resolves the strange and
- difficult to diagnose (or reproduce) test failures on the
- dashmacmini2 Continuous dashboard.
-
-2009-01-29 14:31 hoffman
-
- * Source/cmake.cxx: BUG: fix for #8418 -E chdir should return fail
- of dir does not exist
-
-2009-01-29 14:14 king
-
- * Source/cmLinkDirectoriesCommand.h: ENH: Docs for relative paths
- in link_directories
-
- The link_directories command treats relative paths differently
- from most CMake commands. This notes the difference in the
- documentation. See issue #8377.
-
-2009-01-29 13:41 king
-
- * Modules/Platform/Darwin.cmake: BUG: Fix OS X dylib version flags
- for more linkers
-
- Some OS X linkers want a 'dylib_' prefix on the
- -compatiblity_version and -current_version flags while others do
- not. This passes the flags through gcc instead since it never
- wants the prefix and translates the flags for the linker
- correctly.
-
-2009-01-29 13:26 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Also find .moc files if there are spaces between # and
- include. Fixes #8433.
-
-2009-01-29 11:57 hoffman
-
- * Tests/CMakeTests/GetFilenameComponentSymlinksTest.cmake.in: ENH:
- add missing file
-
-2009-01-29 11:42 hoffman
-
- * Modules/Platform/Haiku.cmake: BUG: fix for # 8413 add more haiku
- searching
-
-2009-01-29 11:39 hoffman
-
- * Source/cmGetFilenameComponentCommand.cxx,
- Tests/CMakeTests/CMakeLists.txt: BUG: fix for #8423
-
-2009-01-29 09:26 hoffman
-
- * Source/CTest/cmCTestCoverageHandler.cxx: STYLE: fix warning
-
-2009-01-29 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-28 22:56 lowman
-
- * Modules/FindDoxygen.cmake: STYLE: Reworded some of the OS-X code
- comments
-
-2009-01-28 16:56 hoffman
-
- * Source/CTest/cmCTestCoverageHandler.cxx: STYLE: fix warning
-
-2009-01-28 15:04 clinton
-
- * Modules/UseQt4.cmake:
- ENH: Better way to add framework includes.
-
-2009-01-28 12:55 hoffman
-
- * Modules/FindOpenMP.cmake: ENH: clean up status and change order
- for more common compilers first
-
-2009-01-28 12:55 hoffman
-
- * Modules/FindOpenMP.cmake: file FindOpenMP.cmake was added on
- branch CMake-2-6 on 2009-02-04 16:44:02 +0000
-
-2009-01-28 12:45 hoffman
-
- * Modules/FindOpenMP.cmake: ENH: add openmp support
-
-2009-01-28 06:10 david.cole
-
- * Modules/Platform/Darwin.cmake: BUG: Fix careless typo that only
- caused test failures on clean builds...
-
-2009-01-28 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-27 15:51 david.cole
-
- * Modules/Platform/Darwin.cmake: BUG: Try to fix the universal
- binary continuous dashboard on dashmacmini2. I am deducing that
- the value of CMAKE_OSX_ARCHITECTURES_DEFAULT is responsible for
- the failure, although I cannot reproduce it on other builds or
- even by running the test via ctest interactively *on* the
- continuous dashboard's build...
-
-2009-01-27 11:50 david.cole
-
- * Modules/Platform/Darwin.cmake: BUG: Only set
- CMAKE_OSX_DEPLOYMENT_TARGET on Mac OSX 10.4 or later. The gcc
- that runs on 10.3 and earlier does not understand the compiler
- flag it maps to...
-
-2009-01-27 11:35 david.cole
-
- * Source/cmCoreTryCompile.cxx: STYLE: Emit filenames in try_compile
- error message to get more information from the Continuous
- dashboard test that is failing.
-
-2009-01-27 10:58 king
-
- * Source/: cmCTest.cxx, cmCTest.h: BUG: Reset file submission list
- on test restart
-
- When running in script mode it is possible to run multiple
- separate dashboard submissions in one cmCTest instance. The
- recent refactoring of file submission lists into parts failed to
- clear the submission lists when starting a new dashboard
- (ctest_start or ctest_update). Only the unused old submission
- set was cleared. This fixes the refactored version to remove the
- old submission set completely and also clear the part-wise lists.
-
-2009-01-27 10:58 king
-
- * Source/CTest/cmCTestSubmitHandler.cxx: BUG: Fix CTest submit-only
- operation
-
- We need to initialize cmCTestSubmitHandler on construction to
- make sure all parts get enabled by default. The recent fix to
- re-enable all parts on initialization broke submit-only
- operations because the handler did not initialize on
- construction. This also removes duplicate initialization code.
-
-2009-01-27 10:34 hoffman
-
- * Utilities/Release/README,
- Utilities/Release/create-cmake-release.cmake,
- Utilities/Release/release_cmake.cmake,
- Utilities/Release/release_cmake.sh.in, Tests/CMakeLists.txt: ENH:
- change to use CMAKE_CREATE_VERSION from CMAKE_VERSION as
- CMAKE_VERSION is auto-defined now
-
-2009-01-27 10:30 david.cole
-
- * Modules/Platform/Darwin.cmake, Source/cmGlobalXCodeGenerator.cxx,
- Source/cmLocalGenerator.cxx: BUG: Fix issue #6195. Add
- CMAKE_OSX_DEPLOYMENT_TARGET cache variable to specify the target
- deployment runtime OS version of the built executables on Mac
- OSX. Thanks to Mike Jackson for the patch.
-
-2009-01-27 10:26 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: fix for 7845, idl
- files compile even with headerfile only on
-
-2009-01-27 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-26 10:12 clinton
-
- * Modules/FindQt4.cmake:
- BUG: Fixed recent regression when finding some includes.
-
-2009-01-26 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-25 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-24 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-23 17:37 clinton
-
- * Modules/UseQt4.cmake:
- ENH: Should have a -F for framework includes on Mac. Fixes
- ParaView build with Qt 4.5 on Mac.
-
-2009-01-23 16:52 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Add convenience for identifying Cocoa based Qt.
-
-2009-01-23 13:36 david.cole
-
- * Modules/CPack.cmake: ENH: Turn off CPACK_BINARY_TBZ2 and
- CPACK_BINARY_ZIP by default. Strictly speaking, this changes
- behavior from cpack 2.6, but now that cpack returns a non-zero
- exit code when it encounters an error, and it is an error to try
- to use a generator that is not available... It makes sense to
- turn these off by default since not everybody has these
- generators installed. It is easy for a project to turn these
- options back on if they need to: simply set(CPACK_BINARY_TBZ2 ON)
- or set(CPACK_BINARY_ZIP ON) before include(CPack) in your
- CMakeLists.txt...
-
-2009-01-23 12:20 hoffman
-
- * Source/cmPolicies.h: ENH: try to fix vs6 build
-
-2009-01-23 00:30 lowman
-
- * Modules/FindFLTK.cmake: ENH: Better support for "fltk-config"
- binary, added options so the user doesn't have to have everything
- in order for FLTK_FOUND to be true. #7809
-
-2009-01-23 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-22 14:23 david.cole
-
- * Source/CPack/cmCPackBundleGenerator.h: BUG: Forgot to change
- parent class in cmCPackTypeMacro when I added
- cmCPackDragNDropGenerator. Fix it now that it really matters.
- (The BundleGenerator test started failing after the last commit.
- This fixes it.)
-
-2009-01-22 13:56 david.cole
-
- * Source/CPack/: cmCPackBundleGenerator.cxx,
- cmCPackBundleGenerator.h, cmCPackLog.cxx, cpack.cxx: BUG: Fix
- issue #8383. Avoid crashing when using the Bundle CPack generator
- and CPACK_BUNDLE_NAME is not set. Instead, fail gracefully giving
- an informative error message and non-zero exit code.
-
-2009-01-22 13:18 hoffman
-
- * Tests/PolicyScope/Bar.cmake: file Bar.cmake was added on branch
- CMake-2-6 on 2009-02-04 16:44:18 +0000
-
-2009-01-22 13:18 hoffman
-
- * Tests/PolicyScope/CMakeLists.txt: file CMakeLists.txt was added
- on branch CMake-2-6 on 2009-02-04 16:44:18 +0000
-
-2009-01-22 13:18 hoffman
-
- * Tests/PolicyScope/FindFoo.cmake: file FindFoo.cmake was added on
- branch CMake-2-6 on 2009-02-04 16:44:19 +0000
-
-2009-01-22 13:18 king
-
- * Source/cmCMakePolicyCommand.h, Source/cmFindPackageCommand.cxx,
- Source/cmFindPackageCommand.h, Source/cmIncludeCommand.cxx,
- Source/cmIncludeCommand.h, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmPolicies.cxx, Source/cmPolicies.h,
- Tests/PolicyScope/Bar.cmake, Tests/PolicyScope/CMakeLists.txt,
- Tests/PolicyScope/FindFoo.cmake: ENH: Isolate policy changes in
- included scripts
-
- Isolation of policy changes inside scripts is important for
- protecting the including context. This teaches include() and
- find_package() to imply a cmake_policy(PUSH) and
- cmake_policy(POP) around the scripts they load, with a
- NO_POLICY_SCOPE option to disable the behavior. This also
- creates CMake Policy CMP0011 to provide compatibility. See issue
- #8192.
-
-2009-01-22 13:16 hoffman
-
- * Tests/PolicyScope/main.c: file main.c was added on branch
- CMake-2-6 on 2009-02-04 16:44:19 +0000
-
-2009-01-22 13:16 king
-
- * Source/cmCMakePolicyCommand.h, Source/cmFunctionCommand.cxx,
- Source/cmFunctionCommand.h, Source/cmMacroCommand.cxx,
- Source/cmMacroCommand.h, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Tests/CMakeLists.txt,
- Tests/PolicyScope/CMakeLists.txt, Tests/PolicyScope/main.c: ENH:
- Better policies for functions and macros
-
- This teaches functions and macros to use policies recorded at
- creation time when they are invoked. It restores the policies as
- a weak policy stack entry so that any policies set by a function
- escape to its caller as before.
-
-2009-01-22 13:16 king
-
- * Source/cmCMakePolicyCommand.h: ENH: Improve stack discussion in
- cmake_policy
-
- This re-organizes the discussion of the policy stack in
- documentation of the cmake_policy() command. The new
- organization clearer and easier to extend with new information.
-
-2009-01-22 13:16 king
-
- * Source/: cmMakefile.cxx, cmMakefile.h: ENH: Create notion of a
- 'weak' policy stack entry
-
- A 'weak' poilcy stack entry responds normally to queries.
- However, setting a policy in a weak entry will recursively set
- the policy in the next entry too. This also gives the internal
- interface to create a weak entry the option to provide an initial
- PolicyMap for it.
-
-2009-01-22 12:12 hoffman
-
- * Source/CPack/cmCPackDragNDropGenerator.cxx: file
- cmCPackDragNDropGenerator.cxx was added on branch CMake-2-6 on
- 2009-02-05 03:04:09 +0000
-
-2009-01-22 12:12 hoffman
-
- * Source/CPack/cmCPackDragNDropGenerator.h: file
- cmCPackDragNDropGenerator.h was added on branch CMake-2-6 on
- 2009-02-05 03:04:18 +0000
-
-2009-01-22 12:12 david.cole
-
- * Modules/CPack.cmake, Source/CMakeLists.txt,
- Source/CPack/cmCPackBundleGenerator.cxx,
- Source/CPack/cmCPackBundleGenerator.h,
- Source/CPack/cmCPackDragNDropGenerator.cxx,
- Source/CPack/cmCPackDragNDropGenerator.h,
- Source/CPack/cmCPackGeneratorFactory.cxx, Tests/CMakeLists.txt:
- BUG: Fix issue #8402. Add a drag and drop bundle generator to the
- Mac build of CPack. Add a test of it in the CPackComponents test.
- Thanks to Clinton Stimpson for the patch.
-
-2009-01-22 10:57 king
-
- * Source/: cmCMakePolicyCommand.cxx, cmMakefile.cxx, cmMakefile.h:
- ENH: Create policy scope barriers
-
- This creates a barrier mechanism to prevent user code from using
- cmake_policy(POP) to pop a scope it didn't push with
- cmake_policy(PUSH).
-
-2009-01-22 10:57 king
-
- * Source/cmMakefile.h: ENH: Make policy push/pop methods private
-
- This makes cmMakefile::PushPolicy and cmMakefile::PopPolicy
- private so that any outside place that uses them needs to use the
- PolicyPushPop helper in an automatic variable. We grant an
- exception to cmCMakePolicyCommand so it can implement
- cmake_policy(PUSH) and cmake_policy(POP).
-
-2009-01-22 10:56 king
-
- * Source/cmFindPackageCommand.cxx: ENH: Refactor find_package
- version file scoping
-
- This converts the variable and policy scope protection
- find_package() uses when loading version files to use automatic
- variables.
-
-2009-01-22 10:56 king
-
- * Source/: cmMakefile.cxx, cmMakefile.h: ENH: Create automatic
- policy push/pop helper
-
- This creates cmMakefile::PolicyPushPop to push and pop policy
- scope automatically. It also enforces balanced push/pop pairs
- inside the scope it handles.
-
-2009-01-22 10:56 king
-
- * Source/: cmMakefile.cxx, cmMakefile.h, cmPolicies.h: ENH:
- Refactor policy stack representation
-
- This defines PolicyMap as a public member of cmPolicies. Its
- previous role as a policy stack entry is now called
- PolicyStackEntry and represented as a class to which more
- information can be added later.
-
-2009-01-22 10:22 david.cole
-
- * Tests/CMakeLists.txt: BUG: Avoid trying to package the X11 test
- on Windows when there is no NSIS installer available.
-
-2009-01-22 07:16 david.cole
-
- * Source/CTest/cmCTestTestHandler.cxx: BUG: Fix issue #8363. Wrap
- output with MakeXMLSafe calls so that the generated XML files are
- valid, parse-able XML.
-
-2009-01-22 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-21 23:52 lowman
-
- * Modules/FindFLTK.cmake: BUG: Fixes detection of FLTK on Gentoo
- (Issue #7809)
-
-2009-01-21 22:43 lowman
-
- * Modules/FindFLTK.cmake: BUG: Fixes #8376: FindFLTK fails because
- include file can be FL/Fl.H and CMake only looks for FL/Fl.h.
- Verified: all FLTK header files in 1.1.9 are .H ... how bizarre.
-
-2009-01-21 17:36 king
-
- * Source/cmGlobalVisualStudio7Generator.h: BUG: Fix VS IDE solution
- files order again
-
- The previous change to order projects in the VS IDE did not
- account for duplicate target names (such as ALL_BUILD and
- ZERO_CHECK) among the input set. While we suppress generation of
- the duplicate project entries, we need to use a multiset to store
- ordered duplicates.
-
-2009-01-21 17:24 king
-
- * Source/cmGlobalVisualStudio7Generator.cxx: BUG: Fix ALL_BUILD
- ordering enforcement
-
- The previous change to make ALL_BUILD come first among targets
- did not account for comparing the target name against itself.
- This led to an invalid ordering of the target set. This change
- fixes it.
-
-2009-01-21 17:06 king
-
- * Source/cmGlobalVisualStudio7Generator.cxx: ENH: Make ALL_BUILD
- always the default project
-
- This teaches the VS IDE generators to write ALL_BUILD into
- solution files first so that it is always the default active
- project. Previously it was first only if no target name sorted
- lexicographically earlier. See issue #8172.
-
-2009-01-21 16:39 king
-
- * Source/: cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h: BUG: Fix VS IDE project order
-
- Our implementation of the feature to pull in dependent targets in
- VS solution files for subprojects caused the order of project
- files in the solution to be arbitrary (based on pointer value in
- the representation). Target ordering in solution files is
- important to prevent unnecessary changing of the files and
- because the VS IDE selects the first project listed as the
- default active target. This change restores lexicographic order
- by target name.
-
-2009-01-21 13:39 david.cole
-
- * Source/CPack/cmCPackBundleGenerator.cxx,
- Source/CPack/cmCPackBundleGenerator.h,
- Tests/BundleGeneratorTest/CMakeLists.txt,
- Tests/BundleGeneratorTest/CustomVolumeIcon.icns: BUG: Fix issue
- #7523: Analyze output of 'hdiutil attach' to get the name of the
- volume that was mounted. Eliminates the need to use the
- -mountpoint arg of hdiutil which has a silly 90 character limit
- on the name of the mount point. Also add a custom volume icon to
- the BundleGeneratorTest to cover this code.
-
-2009-01-21 13:20 david.cole
-
- * Source/QtDialog/CMakeSetup.icns: ENH: Use the latest
- CMake-logo-triangle-high-res.png to improve the look of
- CMakeSetup.icns on the Mac.
-
-2009-01-21 11:54 hoffman
-
- * Modules/CPack.OSXScriptLauncher.rsrc.in: file
- CPack.OSXScriptLauncher.rsrc.in was added on branch CMake-2-6 on
- 2009-04-21 20:48:54 +0000
-
-2009-01-21 11:54 hoffman
-
- * Modules/CPack.OSXX11.main.scpt.in: file CPack.OSXX11.main.scpt.in
- was added on branch CMake-2-6 on 2009-04-21 18:12:47 +0000
-
-2009-01-21 11:54 david.cole
-
- * Modules/CPack.OSXScriptLauncher.in,
- Modules/CPack.OSXScriptLauncher.rsrc.in,
- Modules/CPack.OSXX11.Info.plist.in,
- Modules/CPack.OSXX11.main.scpt.in,
- Modules/CPack.RuntimeScript.in,
- Source/CPack/OSXLauncherScript.scpt,
- Source/CPack/cmCPackOSXX11Generator.cxx, Tests/CMakeLists.txt,
- Tests/X11/CMakeLists.txt: BUG: Fix issue #7833: Add file
- extension handling to CPack generated installers for OSXX11
- applications. Also modify the X11 test to build such an installer
- on Mac builds that test CPack and have X11 available. Thanks to
- Wes Turner for the patch.
-
-2009-01-21 09:49 king
-
- * Modules/FindKDE4.cmake: STYLE: Fix if/endif mismatch in FindKDE4
-
-2009-01-21 09:49 king
-
- * Source/: cmFunctionCommand.cxx, cmMacroCommand.cxx: ENH: Enforce
- logical blocks in functions/macros
-
- This teaches function() and macro() to enforce matching logical
- blocks inside the recorded bodies. This makes the error message
- more specific.
-
-2009-01-21 09:49 king
-
- * Source/: cmForEachCommand.cxx, cmFunctionCommand.cxx,
- cmIfCommand.cxx, cmMacroCommand.cxx, cmMakefile.cxx,
- cmMakefile.h, cmWhileCommand.cxx: ENH: Better handling of
- mismatched blocks
-
- If a logical block terminates with mismatching arguments we
- previously failed to remove the function blocker but replayed the
- commands anyway, which led to cases in which we failed to report
- the mismatch (return shortly after the ending command). The
- recent refactoring of function blocker deletion changed this
- behavior to produce an error on the ending line by not blocking
- the command. Furthermore, the function blocker would stay in
- place and complain at the end of every equal-level block of the
- same type.
-
- This teaches CMake to treat the begin/end commands (if/endif,
- etc.) as correct and just warns when the arguments mismatch. The
- change allows cases in which CMake 2.6.2 silently ignored a
- mismatch to run as before but with a warning.
-
-2009-01-21 09:48 king
-
- * Source/: cmForEachCommand.cxx, cmForEachCommand.h,
- cmFunctionBlocker.h, cmFunctionCommand.cxx, cmFunctionCommand.h,
- cmIfCommand.cxx, cmIfCommand.h, cmMacroCommand.cxx,
- cmMacroCommand.h, cmMakefile.cxx, cmMakefile.h,
- cmWhileCommand.cxx, cmWhileCommand.h: ENH: Better error message
- for unclosed blocks
-
- This centralizes construction of the error message for an
- unclosed logical block (if, foreach, etc.). We record the line
- at which each block is opened so it can be reported in the error
- message.
-
-2009-01-21 09:48 king
-
- * Source/: cmMakefile.cxx, cmMakefile.h: ENH: Refactor logical
- block enforcement
-
- This uses a stack of 'barriers' to efficiently divide function
- blockers into groups corresponding to each input file. It
- simplifies detection of missing block close commands and factors
- it out of ReadListFile.
-
-2009-01-21 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-20 15:49 king
-
- * Source/: cmExportBuildFileGenerator.cxx,
- cmGlobalXCodeGenerator.cxx, cmTarget.cxx: BUG: Fix LOCATION
- property for Mac AppBundles
-
- Previously cmTarget::GetLocation and cmTarget::GetFullPath would
- return for Mac AppBundles the top-level bundle directory but
- without the .app extension. We worked around this at the call
- sites. This fixes the methods and removes the work-arounds. See
- issue #8406.
-
-2009-01-20 14:36 king
-
- * Source/: cmForEachCommand.cxx, cmForEachCommand.h,
- cmIfCommand.cxx, cmIfCommand.h, cmMakefile.cxx, cmMakefile.h,
- cmWhileCommand.cxx, cmWhileCommand.h: ENH: Refactor function
- blocker deletion
-
- When a function blocker decides to remove itself we previously
- removed it at every return point from the C++ scope in which its
- removal is needed. This teaches function blockers to transfer
- ownership of themselves from cmMakefile to an automatic variable
- for deletion on return. Since this removes blockers before they
- replay their commands, we no longer need to avoid running
- blockers on their own commands.
-
-2009-01-20 14:35 king
-
- * Source/: cmIfCommand.cxx, cmMakefile.cxx, cmMakefile.h: ENH:
- Improve response to bad if or elseif
-
- Previously bad arguments to an if() or elseif() would cause some
- subsequent statements in the corresponding block to execute.
- This teaches CMake to stop processing commands with a fatal
- error. It also provides context to bad elseif() error messages.
-
-2009-01-20 14:29 david.cole
-
- * Source/CPack/cmCPackNSISGenerator.cxx,
- Tests/CPackComponents/CMakeLists.txt, Tests/CPackComponents/Issue
- 7470.html: BUG: Fix for issue #7470. Allow spaces in the path
- names of installed files with the NSIS CPack generator and
- component-based installs. Add an installed file to the
- CPackComponents test: it failed before the fix; now it passes.
-
-2009-01-20 10:06 hoffman
-
- * Source/cmSystemTools.cxx: BUG: fix crash with cmd.exe shell and
- cmake in the path
-
-2009-01-20 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-19 22:51 lowman
-
- * Modules/FindBoost.cmake: BUG: Fix detection of boost libraries
- without any compiler encoding (e.g. Gentoo 1.37 system installed
- boost). Fixes issue #8404 reported on mailing list.
-
-2009-01-19 22:28 lowman
-
- * Modules/FindDoxygen.cmake: BUG: Fixes Issue #8054 and more.
- DOXYGEN_DOT_FOUND now exists, errant mark_as_advanced variables
- removed, documentation cleaned up and OSX stuff isolated to it's
- own section, support added for DOXYGEN_SKIP_DOT, support added to
- call FindPackageHandleStandardArgs to avoid output on every CMake
- run.
-
-2009-01-19 21:30 lowman
-
- * Modules/FindBoost.cmake: BUG: Missing "icpc" as a possible CXX
- compiler for Intel C++. Also refactored gcc -dumpversion code
- and regex to a function.
-
-2009-01-19 19:21 lowman
-
- * Modules/FindBoost.cmake: BUG: Switch FindBoost.cmake to use
- CMAKE_COMPILER_IS_GNUCXX (Issue #8398)
-
-2009-01-19 13:33 lowman
-
- * Modules/: FindOpenThreads.cmake, Findosg.cmake,
- FindosgAnimation.cmake, FindosgDB.cmake, FindosgFX.cmake,
- FindosgGA.cmake, FindosgIntrospection.cmake,
- FindosgManipulator.cmake, FindosgParticle.cmake,
- FindosgProducer.cmake, FindosgShadow.cmake, FindosgSim.cmake,
- FindosgTerrain.cmake, FindosgText.cmake, FindosgUtil.cmake,
- FindosgViewer.cmake, FindosgVolume.cmake, FindosgWidget.cmake,
- Findosg_functions.cmake: BUG: Fixed Issue #7331 Bugs in
- Findosg*.cmake. Also added OPENTHREADS_LIBRARIES.
-
-2009-01-19 05:14 lowman
-
- * Modules/FindBoost.cmake: BUG: Reverted change made in 1.27,
- should be unnecessary (Issue #7508)
-
-2009-01-19 02:35 lowman
-
- * Modules/FindBoost.cmake: BUG: Resolve Issue #7508, FindBoost
- fails to find boost on SuSE 10.3
-
-2009-01-19 02:27 lowman
-
- * Modules/FindBoost.cmake: ENH: Added 1.38 since it'll be out soon.
- More documentation and clarified examples, addressed autolinking
- issue on MSVC
-
-2009-01-19 01:02 lowman
-
- * Modules/FindBoost.cmake: BUG: Do not check for GCC version
- encoding in filenames on Boost libraries prior to 1.35.
- Eliminate "lib" prefix except on MSVC.
-
-2009-01-19 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-18 17:19 lowman
-
- * Modules/FindBoost.cmake: BUG: Fixed additional issues with
- autodetecting compiler tags properly including Issue #6926
-
-2009-01-18 16:40 lowman
-
- * Modules/FindBoost.cmake: BUG: Fixes problem with _boost_ABI_TAG
- appending to itself if FindBoost is called more than once (Issue
- #7460)
-
-2009-01-18 15:53 lowman
-
- * Modules/FindBoost.cmake: STYLE: minor cleanup
-
-2009-01-18 15:41 lowman
-
- * Modules/FindBoost.cmake: BUG: Removed some code which was
- squashing Boost_LIBRARIES on WIN32 under the auspices of forcing
- the user to use autolinking, but it only did this squashing on
- the first call to FindBoost. Subsequent calls to FindBoost would
- not have Boost_LIBRARIES squashed so this code was doing nothing.
- If you link your target_link_libraries() against dynamic boost
- libraries it appears from tools like Dependency Walker that the
- pragma calls to autolink to the static boost libraries are
- ignored. It's therefore too late to make this squash apply to
- all calls to FindBoost because that would break users that have
- not setup autolinking properly. For now this fix is largely
- cosmetic since the original code never worked anyways (see
- version 1.5 introduced on 4/22/08).
-
-2009-01-18 15:17 lowman
-
- * Modules/FindBoost.cmake: BUG: Fixed documentation bug with
- Boost_USE_MULTITHREADED, removed OPTION() call since it would be
- useless and confusing after an initial configure.
-
-2009-01-18 14:40 lowman
-
- * Modules/FindBoost.cmake: BUG: Fixed superfluous and duplicate
- dirs in Boost_LIBRARY_DIR. Employed workaround for Issue #8378.
- Resolves Issue #8099
-
-2009-01-18 13:03 hoffman
-
- * Source/: cmCTest.h, cmCTest.cxx, ctest.cxx: BUG: add output on
- failure to ctest #8255
-
-2009-01-18 12:05 hoffman
-
- * Source/cmMakefile.cxx: BUG: fix crash with empty properties
-
-2009-01-18 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-17 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-16 04:07 lowman
-
- * Modules/FindBoost.cmake: BUG: Fixed issues using FindBoost with
- BoostPro packaged releases. Fixed regression for bjam users on
- Win32 introduced in 1.4.2.4 (7/13/08). This commit partially or
- completely resolves Issues #8173, #8326, #7943, #7725!
-
-2009-01-16 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-15 16:16 king
-
- * Source/cmFindPackageCommand.cxx: BUG: Fix find_package docs for
- refind feature
-
- Recently we taught find_package to re-find a package
- configuration file if it is given a wrong answer. This fixes the
- documentation to reflect the change.
-
-2009-01-15 14:37 king
-
- * Source/: cmMakefile.cxx, cmMakefile.h: BUG: Enforce matching
- policy PUSH/POP in all files
-
- The documentation of cmake_policy PUSH and POP states that they
- must always match. Previously we enforced this only for the top
- scope of each CMakeLists.txt file. This enforces the requirement
- for all files.
-
-2009-01-15 13:24 hoffman
-
- * Source/CTest/: cmCTestGenericHandler.cxx,
- cmCTestSubmitHandler.cxx: ENH: fix part submission to not have
- memory of the last part submission
-
-2009-01-15 10:32 hoffman
-
- * Source/CTest/: cmCTestTestHandler.cxx, cmCTestTestHandler.h: BUG:
- fix for bug #8174
-
-2009-01-15 09:17 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Source/cmDocumentVariables.cxx,
- Source/cmExtraEclipseCDT4Generator.cxx,
- Source/cmFunctionCommand.cxx, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Tests/FindPackageTest/CMakeLists.txt: ENH:
- merge in changes from main tree, fix borland build
-
-2009-01-15 08:57 king
-
- * Source/: cmDocumentVariables.cxx, cmMakefile.cxx: ENH: Provide
- variable CMAKE_VERSION
-
- This creates the variable CMAKE_VERSION containing the full
- version of cmake in "major.minor.patch" format. It is
- particularly useful with the component-wise version comparison
- provided by the if() command.
-
-2009-01-15 08:57 king
-
- * Source/cmDocumentVariables.cxx: ENH: Document variable
- CMAKE_PATCH_VERSION
-
- This adds documentation of CMAKE_PATCH_VERSION to the generated
- variables documentation.
-
-2009-01-15 02:07 lowman
-
- * Modules/FindBoost.cmake: BUG: fixed bug #7529: FindBoost fails to
- find boost on SuSE 11.0 due to GCC reporting version x.y and not
- x.y.z
-
-2009-01-15 01:22 lowman
-
- * Modules/FindBoost.cmake: BUG: Fixes bug #8059. Also added
- Boost_DEBUG variable for troubleshooting.
-
-2009-01-15 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-14 15:14 king
-
- * Source/: cmFunctionCommand.cxx, cmMakefile.h: BUG: Pop a function
- scope even on error
-
- This uses an automatic variable to push and pop variable scope
- inside a function call. Previously if the function failed its
- scope would not be popped. This approach guarantees a balanced
- push/pop.
-
-2009-01-14 13:48 hoffman
-
- * Source/CTest/: cmCTestBuildHandler.cxx, cmProcess.cxx: ENH: fix
- return value to ctest_build and remove debug print in cmProcess
-
-2009-01-14 13:01 hoffman
-
- * Source/CTest/: cmCTestBuildCommand.cxx, cmCTestBuildCommand.h,
- cmCTestBuildHandler.cxx, cmCTestBuildHandler.h, cmProcess.cxx:
- ENH: allow ctest_build to return error and warning counts
-
-2009-01-14 09:51 king
-
- * Source/: cmExtraEclipseCDT4Generator.cxx,
- CTest/cmCTestSubmitHandler.cxx: COMP: Fix const set find for
- Borland 5.5
-
- The Borland 5.5 compiler's STL set does not define correct
- signatures for its find() members, leading to build errors. This
- works around the problem.
-
-2009-01-14 09:34 king
-
- * Tests/FindPackageTest/CMakeLists.txt: ENH: Test find_package
- re-find feature
-
- Recently we taught find_package to re-find a package if its
- <package>_DIR result variable was set to a location not
- containing the package (instead of reporting an error as before).
- This tests the feature.
-
-2009-01-14 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-13 13:03 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Modules/CMakeGenericSystem.cmake,
- Modules/CMakeSystemSpecificInformation.cmake,
- Modules/FindGettext.cmake, Modules/FindPythonInterp.cmake,
- Source/cmCMakeMinimumRequired.cxx,
- Source/cmCMakeMinimumRequired.h, Source/cmComputeLinkDepends.cxx,
- Source/cmComputeLinkDepends.h, Source/cmDocumentVariables.cxx,
- Source/cmDocumentationFormatterDocbook.cxx,
- Source/cmExportFileGenerator.cxx,
- Source/cmExportInstallFileGenerator.cxx,
- Source/cmExportInstallFileGenerator.h,
- Source/cmExtraCodeBlocksGenerator.cxx,
- Source/cmExtraEclipseCDT4Generator.cxx,
- Source/cmExtraEclipseCDT4Generator.h, Source/cmFileCommand.cxx,
- Source/cmFileCommand.h, Source/cmFindPackageCommand.cxx,
- Source/cmFindPackageCommand.h,
- Source/cmGetTargetPropertyCommand.h,
- Source/cmGlobalVisualStudio6Generator.cxx,
- Source/cmInstallExportGenerator.cxx,
- Source/cmInstallExportGenerator.h, Source/cmInstallGenerator.cxx,
- Source/cmInstallTargetGenerator.h, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmSetCommand.cxx, Source/cmTarget.cxx, Source/cmTarget.h,
- Source/cmTargetLinkLibrariesCommand.cxx,
- Source/cmTargetLinkLibrariesCommand.h, Source/cmake.cxx,
- Source/cmake.h, Source/CTest/cmCTestBuildAndTestHandler.cxx,
- Source/CTest/cmCTestBuildHandler.cxx,
- Source/CTest/cmCTestUpdateHandler.cxx,
- Source/QtDialog/CMakeLists.txt, Source/QtDialog/CrossCompiler.ui,
- Source/kwsys/SystemTools.cxx, Source/kwsys/SystemTools.hxx.in,
- Source/kwsys/testProcess.c, Templates/DLLHeader.dsptemplate,
- Templates/EXEHeader.dsptemplate,
- Templates/EXEWinHeader.dsptemplate,
- Templates/staticLibHeader.dsptemplate,
- Tests/CustomCommand/CMakeLists.txt,
- Tests/ExportImport/Export/CMakeLists.txt,
- Tests/ExportImport/Import/CMakeLists.txt,
- Tests/FindPackageTest/CMakeLists.txt, Tests/FindPackageTest/Baz
- 1.1/BazConfig.cmake, Tests/FindPackageTest/Baz
- 1.1/BazConfigVersion.cmake, Tests/FindPackageTest/Baz
- 1.2/CMake/BazConfig.cmake, Tests/FindPackageTest/Baz
- 1.2/CMake/BazConfigVersion.cmake,
- Tests/FindPackageTest/lib/cmake/zot-4.0/zot-config-version.cmake,
- Tests/FindPackageTest/lib/cmake/zot-4.0/zot-config.cmake,
- Tests/StringFileTest/CMakeLists.txt: ENH: merge in changes from
- CVS to branch for 2.6.3 RC 8
-
-2009-01-13 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-12 11:10 king
-
- * Source/cmCTest.cxx: COMP: Remove unused variable
-
-2009-01-12 10:38 king
-
- * Source/CTest/cmCTestSubmitCommand.cxx,
- Source/CTest/cmCTestSubmitCommand.h,
- Source/CTest/cmCTestSubmitHandler.cxx,
- Source/CTest/cmCTestSubmitHandler.h,
- Tests/CTestTest2/test.cmake.in: ENH: Teach ctest_submit about
- parts
-
- This adds a PARTS option to the ctest_submit command which tells
- it to submit only parts whose names are listed with the option.
-
-2009-01-12 10:37 king
-
- * Source/: cmCTest.cxx, cmCTest.h, CTest/cmCTestBuildHandler.cxx,
- CTest/cmCTestConfigureHandler.cxx,
- CTest/cmCTestCoverageHandler.cxx,
- CTest/cmCTestGenericHandler.cxx, CTest/cmCTestGenericHandler.h,
- CTest/cmCTestSubmitHandler.cxx, CTest/cmCTestTestHandler.cxx,
- CTest/cmCTestUpdateHandler.cxx: ENH: Divide CTest file submission
- list by part
-
- This splits the list of files for CTest to submit into those
- belonging to each part. The set is recombined just before
- submission. Later this will allow piecewise submissions.
-
-2009-01-12 10:37 king
-
- * Source/: cmCTest.cxx, cmCTest.h: ENH: Refactor cmCTest test part
- representation
-
- This introduces the name "part" to denote a portion of the
- testing and submission process performed by ctest. We generalize
- the boolean indicating whether each part is enabled into a
- structure to which more information can be added later. We
- provide bi-directional mapping between part id and part names.
-
-2009-01-12 09:11 king
-
- * Source/: cmCTest.cxx, cmCTest.h, CTest/cmCTestBuildHandler.cxx,
- CTest/cmCTestConfigureHandler.cxx,
- CTest/cmCTestCoverageHandler.cxx,
- CTest/cmCTestGenericHandler.cxx, CTest/cmCTestGenericHandler.h,
- CTest/cmCTestHandlerCommand.cxx, CTest/cmCTestHandlerCommand.h,
- CTest/cmCTestMemCheckHandler.cxx, CTest/cmCTestTestHandler.cxx:
- ENH: Teach ctest_* to create appending XML files
-
- This adds an APPEND option to the ctest_* commands which tells
- them to put the Append="true" attribute in the Site element of
- their XML file.
-
-2009-01-12 09:10 king
-
- * Source/CTest/: cmCTestHandlerCommand.cxx,
- cmCTestHandlerCommand.h: ENH: Refactor CTest command argument
- handling
-
- The previous approach to handling of arguments to ctest_*
- commands worked only for keyword/value arguments with a single
- value. This refactors the approach to allow some commands to
- define alternative argument forms.
-
-2009-01-12 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-11 12:18 alex
-
- * Source/: cmExtraEclipseCDT4Generator.cxx,
- cmExtraEclipseCDT4Generator.h: ENH: patch from Miguel, As it is
- today the generator creates linked resources to
- LIBRARY_OUTPUT_PATH and EXECUTABLE_OUTPUT_PATH if they are not a
- subdirectory of the binary dir, so that the IDE can detect the
- Binaries (this was addressed previously as a result of a bug
- report).
-
- Reduces code redundancy by encapsulating common behaviour for
- LIBRARY_OUTPUT_PATH and EXECUTABLE_OUTPUT_PATH in
- AppendLinkedResource.
-
- Addresses the two new variable names for these locations,
- CMAKE_LIBRARY_OUTPUT_DIRECTORY and CMAKE_RUNTIME_OUTPUT_DIRECTORY
- respectively.
-
- Finally, it is addressing a bug in the current code for relative
- paths in these variables. If it is a relative path to the binary
- dir, the IsSubdirectory call returns false and so it creates the
- linked resource. The created linked resource produces an error in
- the Eclipse IDE because the IDE expects it to be a full path. The
- patch now addresses this by concatenating the binary dir if it is
- a relative path.
-
-2009-01-11 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-10 09:01 alex
-
- * Source/cmDocumentationFormatterDocbook.cxx: BUG: don't create
- empty <itemizedlist>s (#7289), dblatex didn't like that
-
- Alex
-
-2009-01-10 08:46 alex
-
- * Modules/FindPythonInterp.cmake: ENH: fix #7913: find also python
- 2.6 on windows
-
- Alex
-
-2009-01-10 08:39 alex
-
- * Modules/FindGettext.cmake: BUG: fix #8122, _firstPoFile was not
- empty because it was no real variable but just a macro argument
- -> make it a real variable
-
- Alex
-
-2009-01-10 08:16 alex
-
- * Source/cmDocumentVariables.cxx: STYLE: document
- CMAKE_COLOR_MAKEFILE (#7878)
-
- Alex
-
-2009-01-10 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-09 20:35 alex
-
- * Source/cmExtraEclipseCDT4Generator.h: COMP: forgot to commit this
- file
-
- Alex
-
-2009-01-09 20:26 alex
-
- * Modules/CMakeSystemSpecificInformation.cmake: STYLE: fix typo
-
- Alex
-
-2009-01-09 20:18 alex
-
- * Modules/CMakeGenericSystem.cmake: STYLE: this is not necessary
- anymore for kdevelop, the kdevelop generator now generates the
- project so that the environment variable VERBOSE is set to 1 when
- make is executed by kdevelop (and additionally this didn't work,
- since CMAKE_GENERATOR never matches KDevelop3, this is now in
- CMAKE_EXTRA_GENERATOR)
-
- Alex
-
-2009-01-09 20:09 alex
-
- * Source/cmExtraEclipseCDT4Generator.cxx: STYLE: remove debug
- output
-
- Alex
-
-2009-01-09 19:52 alex
-
- * Source/cmExtraEclipseCDT4Generator.cxx: BUG: fix #8073: also show
- targets created using add_custom_targets() -additionally also
- create the target/fast targets for Eclipse -skip preinstall and
- install/local, they should be only rarely used
-
- Alex
-
-2009-01-09 19:08 alex
-
- * Source/cmExtraEclipseCDT4Generator.cxx: BUG: remove the call to
- EnableInstallTarget(), don't know why it was there. This caused
- that always an install target was created which installed
- nothing, even if there was no install rule in the project.
-
- Alex
-
-2009-01-09 18:58 alex
-
- * Source/: cmExtraEclipseCDT4Generator.cxx,
- cmExtraEclipseCDT4Generator.h: BUG: fix #8105: don't hardcode
- "gcc" and "make" but use CMAKE_C_COMPILER and CMAKE_MAKE_PROGRAM
- instead
-
- Alex
-
-2009-01-09 18:04 alex
-
- * Source/cmExtraCodeBlocksGenerator.cxx: BUG: fix #8203: codeblocks
- + mingw doesn't like the extra quotes around the path to the
- makefile if it contains spaces, under Linux it works with spaces
-
- Alex
-
-2009-01-09 16:44 king
-
- * Source/cmCTest.cxx: ENH: Add missing newline to CTest-generated
- xml
-
- The Generator="ctest..." attribute of Site elements in
- CTest-generated XML files was missing a newline, causing the next
- attribute to appear on the same line. This adds the newline.
-
-2009-01-09 12:56 hoffman
-
- * Source/cmCTest.cxx: ENH: fix crash for old style scripts
-
-2009-01-09 12:32 hoffman
-
- * Source/cmCTest.h: ENH: fix return type
-
-2009-01-09 12:05 hoffman
-
- * Source/: cmCTest.cxx, cmCTest.h, CTest/cmCTestScriptHandler.h:
- ENH: add subproject tag property for ctest
-
-2009-01-09 11:44 king
-
- * Source/kwsys/testProcess.c: ENH: Extend kwsys.testProcess-4
- timeout
-
- The test is supposed to terminate quickly when its child crashes,
- but that seems to take over 10s on busy systems. This extends
- the test's timeout to 30s to help it pass when running on a busy
- system.
-
-2009-01-09 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-08 18:09 alex
-
- * Source/: cmExtraEclipseCDT4Generator.h,
- cmExtraEclipseCDT4Generator.cxx: BUG: apply patch from #8205,
- also fixes #8212: escape characters for XML when writing the
- eclipse project files
-
- Alex
-
-2009-01-08 17:57 alex
-
- * Source/: cmFindPackageCommand.cxx, cmFindPackageCommand.h: ENH:
- when trying to find a FooConfig.cmake file, if in the directory
- pointed to by the Foo_DIR variable there is no FooConfig.cmake
- file, then instead of abort and complain that the user should set
- or clear the Foo_DIR variables, just search for the file and
- discard the old Foo_DIR contents
-
- The tests succeed, ok by Brad.
-
- Alex
-
-2009-01-08 04:47 hoffman
-
- * Modules/FindCxxTest.cmake: file FindCxxTest.cmake was added on
- branch CMake-2-6 on 2009-02-04 16:44:01 +0000
-
-2009-01-08 04:47 lowman
-
- * Modules/FindCxxTest.cmake: BUG: Fixed CXXTEST_INCLUDE_DIRS so it
- will work properly with NOTFOUND.
-
- Also eliminated superfluous CXXTEST_FOUND assignment and cleaned
- up the code and added additional documentation. Tagged v1.0.
-
-2009-01-08 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-07 17:28 clinton
-
- * Source/QtDialog/CrossCompiler.ui:
- ENH: Tweak System Name field for cross compiling, so it doesn't
- have a file chooser button.
-
-2009-01-07 14:16 king
-
- * Source/cmInstallExportGenerator.cxx: ENH: Clean per-config export
- files during install
-
- When installing the main export file the install tree may be
- dirty. If out-dated per-config files exist they may break the
- newly installed main file which when it globs them. This teaches
- the installation script to detect when it is about to replace the
- main export file with a different one and cleans out any existing
- per-config files.
-
-2009-01-07 14:16 king
-
- * Source/: cmFileCommand.cxx, cmFileCommand.h: ENH: Add
- undocumented file(DIFFERENT) command
-
- This new command will be used by generated installation scripts
- to determine whether an already-installed export file has
- changed.
-
-2009-01-07 14:16 king
-
- * Source/: cmExportInstallFileGenerator.cxx,
- cmExportInstallFileGenerator.h: ENH: Refactor computation of
- import file glob
-
- New method cmExportInstallFileGenerator::GetConfigImportFileGlob
- computes the globbing expression that an installed export file
- uses to load its per-configuration support files.
-
-2009-01-07 10:41 king
-
- * Source/: cmTest.cxx, CTest/cmCTestTestHandler.cxx,
- CTest/cmCTestTestHandler.h: ENH: Teach CTest to submit test
- property LABELS
-
- This teaches CTest to send the test property "LABELS" in Test.xml
- dashboard submissions as Label elements inside a Labels element.
-
-2009-01-07 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-06 15:05 king
-
- * CTestCustom.cmake.in: COMP: Ignore warning LNK4204 for CMake
- dashboard
-
- This warning appears for libtar.obj, curltest.obj, and
- synch_client.obj regularly on CMake dashboard submissions from VS
- builds. They seem to occur due to some kind of race condition
- for objects in small targets. There is nothing wrong with the
- code, so this just suppresses the warnings.
-
-2009-01-06 14:58 king
-
- * Source/CTest/cmCTestUpdateHandler.cxx: BUG: Manage LC_MESSAGES
- with an object
-
- This moves management of the LC_MESSAGES environment variable
- into an automatic variable. Previously if an error occurred the
- original environment value was not restored. This makes the fix
- to issue #5936 more robust.
-
-2009-01-06 14:41 king
-
- * Source/CTest/cmCTestUpdateHandler.cxx: STYLE: Remove trailing
- whitespace
-
-2009-01-06 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-05 15:00 king
-
- * Source/: cmGetPropertyCommand.cxx, cmMakefile.cxx, cmMakefile.h,
- cmSetPropertyCommand.cxx, cmSetTestsPropertiesCommand.cxx: ENH:
- Improve test property speed with a map
-
- Previously we stored a vector of tests to preserve their order.
- Property set/get operations would do a linear search for matching
- tests. This uses a map to efficiently look up tests while
- keeping the original order with a vector for test file
- generation.
-
-2009-01-05 14:14 king
-
- * Tests/: CMakeLists.txt, EnforceConfig.cmake,
- EnforceConfig.cmake.in: ENH: Re-enable new 'testing' test mode
-
- This fixes selection of a configuration when none is specified to
- find an available configuration of the ctest test-command.
-
-2009-01-05 14:14 king
-
- * Source/: cmCTest.cxx, cmCTest.h: BUG: Capture cout and cerr from
- internal ctest
-
- When CTest detects that a test is running its own executable it
- optimizes the test by using an internal instance of cmCTest
- instead of creating a new process. However, the internal
- instance was using cout and cerr directly. This redirects the
- output to a string stream to avoid direct display of the internal
- test's output.
-
-2009-01-05 11:05 king
-
- * Source/: cmFileCommand.cxx, QtDialog/CMakeLists.txt: COMP: Fix
- installation of cmake-gui by CMake 2.4
-
- When CMake 2.4 generates the build tree for CMake itself it asks
- the built CMake to install itself using the rules that 2.4
- generated. Since the install rules use undocumented commands
- that are not compatible from 2.4 to 2.6 we need a special case to
- avoid failure. This sets a special indicator variable in the
- install rules that enables a compatibility hack to support the
- old install rule format.
-
-2009-01-05 11:03 king
-
- * Source/cmFileCommand.cxx: ENH: Refactor internal file(INSTALL)
- arg parsing
-
- The internal file(INSTALL) command argument parsing used several
- booleans with at most one set to true at a time to track argument
- parsing state. This refactors it to use one enumeration.
-
-2009-01-05 09:53 king
-
- * Source/cmGetTargetPropertyCommand.h: BUG: Remove old
- get_target_property docs
-
- The get_target_property command contained some outdated
- documentation of the LOCATION and TYPE properties. This removes
- it since they are now documented in the properties list section
- of the documentation.
-
-2009-01-05 09:53 king
-
- * Source/cmTarget.cxx: ENH: Enable LOCATION property for imported
- targets
-
- Previously we left the LOCATION property undefined for imported
- targets since it should no longer be used for non-imported
- targets. However, in the case we do not know the name of an
- available imported configuration, it is more readable to get the
- LOCATION property than LOCATION_<CONFIG> for a bogus
- configuration <CONFIG>. This enables LOCATION for imported
- targets and returns an unspecified available imported
- configuration.
-
-2009-01-05 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-04 04:12 alex
-
- * Source/cmCMakeMinimumRequired.h: STYLE: changed "one may" into
- "it should" to make it stronger
-
- Alex
-
-2009-01-04 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-03 15:48 king
-
- * Source/cmCMakeMinimumRequired.h: ENH: Clarify FATAL_ERROR option
- to min-req command
-
- The FATAL_ERROR to cmake_minimum_required is useful for projects
- that require 2.6 to convince CMake 2.4 to error out. This
- clarifies its usefulness in the documentation.
-
-2009-01-03 15:47 king
-
- * Source/: cmCMakeMinimumRequired.cxx, cmCMakeMinimumRequired.h:
- ENH: Ignore unknown cmake_minimum_required args
-
- When cmake_minimum_required is called with an unknown argument it
- should not complain about it if the version specified is in the
- future. This allows the proper error to be shown about the
- current CMake being too old.
-
-2009-01-03 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-02 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2009-01-01 12:49 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Source/cmCTest.cxx,
- Source/cmCommandArgumentLexer.cxx,
- Source/cmCommandArgumentLexer.h,
- Source/cmCommandArgumentLexer.in.l,
- Source/cmCommandArgumentParser.cxx,
- Source/cmCommandArgumentParser.y,
- Source/cmCommandArgumentParserHelper.cxx,
- Source/cmCommandArgumentParserHelper.h,
- Source/cmCommandArgumentParserTokens.h: ENH: RC 7 merge fix
- missing stuff from RC 6 and fix change log
-
-2009-01-01 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-31 10:14 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Modules/CMakeASM_MASMInformation.cmake,
- Modules/CMakeDetermineASM_MASMCompiler.cmake,
- Modules/CMakeTestASM_MASMCompiler.cmake, Modules/CPackRPM.cmake,
- Modules/FindCurses.cmake, Modules/FindDoxygen.cmake,
- Modules/FindEXPAT.cmake, Modules/FindLibXml2.cmake,
- Modules/FindQt4.cmake, Modules/FindSquish.cmake,
- Modules/FindwxWidgets.cmake, Modules/GetPrerequisites.cmake,
- Modules/SquishRunTestCase.bat, Modules/SquishRunTestCase.sh,
- Modules/SquishTestScript.cmake, Modules/Platform/Darwin.cmake,
- Modules/Platform/Haiku.cmake,
- Modules/Platform/WindowsPaths.cmake, Source/cmFileCommand.h,
- Source/cmFindPackageCommand.cxx, Source/cmFindPackageCommand.h,
- Source/cmGlobalMSYSMakefileGenerator.cxx,
- Source/cmOrderDirectories.cxx,
- Source/CPack/cmCPackBundleGenerator.cxx,
- Source/QtDialog/CMake.desktop, Source/QtDialog/CMakeLists.txt,
- Source/QtDialog/CMakeSetupDialog.cxx,
- Source/QtDialog/Compilers.h, Source/QtDialog/Compilers.ui,
- Source/QtDialog/CrossCompiler.ui,
- Source/QtDialog/FirstConfigure.cxx,
- Source/QtDialog/FirstConfigure.h,
- Source/QtDialog/QCMakeWidgets.cxx, Source/kwsys/ProcessUNIX.c,
- Source/kwsys/System.c, Source/kwsys/SystemInformation.cxx,
- Templates/TestDriver.cxx.in: ENH: merge fixes for RC 6
-
-2008-12-31 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-30 09:13 david.cole
-
- * Source/CTest/: cmCTestConfigureCommand.cxx,
- cmCTestConfigureCommand.h, cmCTestConfigureHandler.cxx,
- cmCTestGenericHandler.cxx: ENH: Add OPTIONS argument to the
- ctest_configure command so that you can pass -D arguments to the
- cmake configure step from a ctest -S script. Also clarify/correct
- some not so helpful error messages.
-
-2008-12-30 09:11 david.cole
-
- * Modules/Platform/Darwin.cmake: BUG: Fix install_name_tool problem
- on the Mac when a PROJECT(... NONE) is followed by multiple calls
- to ENABLE_LANGUAGE. Use find_program to set the
- CMAKE_INSTALL_NAME_TOOL variable so it gets saved in the cache as
- a full path to the install_name_tool executable rather than a
- simple set which eventually goes out of scope.
-
-2008-12-30 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-29 18:11 hoffman
-
- * Tests/JCTest/CMakeLists.txt: ENH: make it take longer
-
-2008-12-29 17:49 hoffman
-
- * Source/CTest/: cmProcess.cxx, cmProcess.h: ENH: add start end
- time for procs
-
-2008-12-29 17:43 hoffman
-
- * Tests/JCTest/: CMakeLists.txt, TestTime.cxx: ENH: add test for -j
- N ctest stuff
-
-2008-12-29 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-28 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-27 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-26 15:27 david.cole
-
- * Source/CTest/cmCTestHandlerCommand.cxx: STYLE: Fix line length
- violation.
-
-2008-12-26 13:28 king
-
- * Source/cmOrderDirectories.cxx: BUG: Fix same-file check for
- directory ordering
-
- When computing runtime search path ordering a constraint exists
- when a file that may be found by the runtime search exists in a
- directory other than that containing the desired file. We test
- whether a potential conflict is really the same due to a symlink.
- Recently the change to cmFindLibraryCommand to load directory
- content created a case in which the same-file check would be
- incorrectly skipped. This avoids skipping the check.
-
-2008-12-26 12:06 david.cole
-
- * Modules/FindDoxygen.cmake: ENH: New location to look for "dot"
-
-2008-12-26 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-25 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-24 10:10 david.cole
-
- * Modules/AddExternalProject.cmake,
- Tests/ExternalProject/CMakeLists.txt: ENH: Re-work of fix
- committed yesterday for the Watcom WMake dashboard. Fix it
- properly by using the SYMBOLIC source file property to indicate
- to WMake when the sentinel file is not actually written by the
- update step.
-
-2008-12-24 04:31 miguelf
-
- * Modules/FindwxWidgets.cmake: BUG: Fixed placement of initial
- wxWidgets_FOUND=TRUE statement, which allowed some cases to
- breakaway from tests without resetting to FALSE (BUG: 8188).
-
-2008-12-24 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-23 10:01 david.cole
-
- * Tests/ExternalProject/CMakeLists.txt: BUG: Workaround for Watcom
- WMake not handling "always out of date" custom commands to fix
- the failing ExternalProject test on the CMake nightly dashboard.
-
-2008-12-23 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-22 03:00 alex
-
- * Modules/FindLibXml2.cmake: BUG: use FindPkgConfig.cmake instead
- of UsePkgConfig.cmake, sync with KDE svn and fix bug #8290
-
- Alex
-
-2008-12-22 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-21 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-20 00:04 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-19 10:35 david.cole
-
- * Modules/AddExternalProject.cmake: ENH: Add the update step in
- between download and build. Add UPDATE_ARGS and UPDATE_COMMAND
- handling. Output a -complete sentinel in synch with the -install
- sentinel, but do not list it as an OUTPUT of the custom command.
- That breaks the chaining of add_custom_commands between custom
- targets, but allows for a file-level dependency expression that
- will cause proper incremental rebuilds. When earlier targets
- rebuild, subsequent dependent targets will also rebuild. CVS and
- SVN update commands are always out-of-date so that they always
- run to get the latest source. To suppress that behavior on a
- per-external project basis use an explicit empty string for
- UPDATE_COMMAND. The source will still be checked out from the
- repository prior to the update step by the download step.
-
-2008-12-19 10:19 hoffman
-
- * Source/CTest/cmCTestTestHandler.cxx: STYLE: fix shadow warning
-
-2008-12-19 00:04 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-18 21:59 hoffman
-
- * Source/CTest/: cmCTestTestHandler.cxx, cmCTestTestHandler.h: BUG:
- partial fix for #8056
-
-2008-12-18 21:57 hoffman
-
- * Source/CTest/: cmCTestHandlerCommand.cxx,
- cmCTestScriptHandler.cxx: BUG: fix for bug #8224 fix crash
-
-2008-12-18 21:53 hoffman
-
- * Modules/FindEXPAT.cmake: BUG: fix for #8298 look for libexpat as
- well
-
-2008-12-18 21:52 hoffman
-
- * Source/cmFileCommand.h: BUG: fix spelling
-
-2008-12-18 17:15 king
-
- * Tests/CMakeLists.txt: BUG: Disable new 'testing' test mode for
- now
-
- The new 'testing' test behavior of actually running the tests
- generated by the project still fails when the test script guesses
- the Debug configuration but the CMake build tree was only built
- Release. The inner ctest needs to find the ctest executable but
- is given the wrong configuration.
-
-2008-12-18 14:56 king
-
- * Source/: cmBootstrapCommands.cxx, cmCommands.cxx: COMP: Add
- set_directory_properties to bootstrap
-
- We now need this command in the Tests/CMakeLists.txt file.
-
-2008-12-18 14:26 king
-
- * Tests/: CMakeLists.txt, EnforceConfig.cmake: BUG: Fix new
- 'testing' test for CMake releases
-
- The recent change of the 'testing' test to actually drive the
- tests within it does not work on Windows with released CMakes
- 2.6.2 and lower if no configuration is given to ctest with a -C
- option. This works around the problem by detecting the case and
- changing the empty configuration to Debug.
-
-2008-12-18 13:36 king
-
- * Source/kwsys/System.c, Tests/CustomCommand/CMakeLists.txt: BUG:
- Fix windows command line escape for empty arg
-
- On Windows the KWSys System package generates escapes for
- command-line arguments. This fix enables quoting of the empty
- string as an argument. This also adds a test to pass an empty
- argument to a custom command.
-
-2008-12-18 12:28 king
-
- * Tests/: CMakeLists.txt, Testing/CMakeLists.txt,
- Testing/Sub/Sub2/CMakeLists.txt: ENH: Improve 'testing' test to
- actually test
-
- The 'testing' CMake test builds a project that uses add_test.
- This strengthens the test to actually run CTest on the project
- build tree after building it.
-
-2008-12-18 12:27 king
-
- * Source/CTest/cmCTestBuildAndTestHandler.cxx: ENH: Minor
- readability improvement in CTest output
-
- When ctest --build-and-test runs the --test-command its output
- did not quote the arguments of the command being tested making it
- difficult to read. This adds the quotes. This also changes the
- wording of the failure case to not sound like CTest could not run
- the executable when in fact it ran and returned failure.
-
-2008-12-18 12:27 king
-
- * Source/cmCTest.cxx: BUG: Fix crash when running internal CTest
-
- When CTest encounters a test whose executable is the ctest
- executable iteslf, it just invokes code inside itself to avoid
- starting a new process. This fixes a null-pointer dereference in
- the logging code of that case.
-
-2008-12-18 10:43 david.cole
-
- * Source/: cmFileCommand.cxx, kwsys/SystemTools.cxx,
- kwsys/SystemTools.hxx.in: BUG: Do not copy permissions of files
- when making the copy in an install rule. If the source file was
- read-only, this prevents the subsequent set of the destination
- file's modification time, making the copied file always different
- in time-stamp than the original and always installing a new file
- with a new time stamp (but the same content) causing unnecessary
- downstream incremental rebuilds. As part of this fix, add an
- optional copyPermissions parameter to the SystemTools routines
- CopyFileIfDifferent, CopyFileAlways, CopyAFile and
- CopyADirectory. The copyPermissions parameter defaults to true to
- preserve the behavior of these routines for existing callers.
-
-2008-12-18 10:06 king
-
- * Source/: cmInstallDirectoryGenerator.h,
- cmInstallExportGenerator.h, cmInstallFilesGenerator.h,
- cmInstallTargetGenerator.h: STYLE: Remove useless install
- generator typedefs
-
- The cmInstall*Generator classes all derive from
- cmInstallGenerator which provides the Indent typedef so they do
- not need to provide it
-
-2008-12-18 09:58 king
-
- * Source/: cmCommandArgumentLexer.cxx, cmCommandArgumentLexer.in.l:
- COMP: Restore fixes to generated lexer
-
- The command argument lexer was recently regenerated which erased
- some fixes that had been applied directly to the output. This
- restores the fixes and adds reminder notes in the generation
- instructions.
-
-2008-12-18 09:58 king
-
- * Source/: cmCommandArgumentParser.cxx, cmCommandArgumentParser.y:
- BUG: Move previous parser bugfixes into input file
-
- The command argument parser code is generated by bison. This
- change restores some fixes previously applied to the generated
- output that were destroyed by regenerating the parser source.
- This time the fixes have been put in the input file so
- regenerating the parser will not destroy them again.
-
-2008-12-18 09:37 clinton
-
- * Source/QtDialog/CMake.desktop:
- ENH: Remove Application category. See #8151.
-
-2008-12-18 00:04 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-17 09:33 king
-
- * Source/: cmCommandArgumentLexer.cxx, cmCommandArgumentLexer.in.l:
- COMP: Fix unused yyunput warning in lexer
-
- This adds the "nounput" option to the flex input file so that
- yyunput is not generated. The function is static but not used so
- some compilers warn.
-
-2008-12-17 09:24 hoffman
-
- * Tests/FindPackageTest/Baz 1.1/BazConfig.cmake: file
- BazConfig.cmake was added on branch CMake-2-6 on 2009-01-13
- 18:03:55 +0000
-
-2008-12-17 09:24 hoffman
-
- * Tests/FindPackageTest/Baz 1.2/CMake/BazConfig.cmake: file
- BazConfig.cmake was added on branch CMake-2-6 on 2009-01-13
- 18:03:56 +0000
-
-2008-12-17 09:24 hoffman
-
- * Tests/FindPackageTest/Baz 1.1/BazConfigVersion.cmake: file
- BazConfigVersion.cmake was added on branch CMake-2-6 on
- 2009-01-13 18:03:55 +0000
-
-2008-12-17 09:24 hoffman
-
- * Tests/FindPackageTest/Baz 1.2/CMake/BazConfigVersion.cmake: file
- BazConfigVersion.cmake was added on branch CMake-2-6 on
- 2009-01-13 18:03:56 +0000
-
-2008-12-17 09:24 king
-
- * Source/cmFindPackageCommand.cxx,
- Tests/FindPackageTest/CMakeLists.txt, Tests/FindPackageTest/Baz
- 1.1/BazConfig.cmake, Tests/FindPackageTest/Baz
- 1.1/BazConfigVersion.cmake, Tests/FindPackageTest/Baz
- 1.2/CMake/BazConfig.cmake, Tests/FindPackageTest/Baz
- 1.2/CMake/BazConfigVersion.cmake: ENH: Teach find_package about
- more install dirs
-
- We now search in
-
- <prefix>/<name>*/
- <prefix>/<name>*/(cmake|CMake)
-
- when looking for package configuration files. This is useful on
- Windows since the Program Files folder is in
- CMAKE_SYSTEM_PREFIX_PATH. These paths are the Windows equivalent
- to the Apple convention application and framework paths we
- already search. See issue #8264.
-
-2008-12-17 09:23 king
-
- * Modules/Platform/WindowsPaths.cmake: ENH: Use 32-bit and 64-bit
- Program Files folders
-
- On 64-bit Windows there may be two Program Files folders, one for
- 32-bit binaries and one for 64-bit binaries. When we compute
- CMAKE_SYSTEM_PREFIX_PATH we should put both folders in the path.
-
-2008-12-17 08:24 king
-
- * Source/cmCommandArgumentLexer.cxx,
- Source/cmCommandArgumentLexer.h,
- Source/cmCommandArgumentLexer.in.l,
- Source/cmCommandArgumentParser.cxx,
- Source/cmCommandArgumentParser.y,
- Source/cmCommandArgumentParserTokens.h,
- Tests/StringFileTest/CMakeLists.txt: ENH: Allow most characters
- in ENV variable refs
-
- The $ENV{VAR} syntax permits access to environment variables.
- This teaches CMake to recognize most characters in the VAR name
- since some environments may have variables with non-C-identifier
- characters.
-
-2008-12-17 00:04 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-16 15:15 clinton
-
- * Source/QtDialog/QCMakeWidgets.cxx:
- ENH: Improve performance with file completion. Fix for #8292.
-
-2008-12-16 15:00 hoffman
-
- * Source/QtDialog/Compilers.h: file Compilers.h was added on branch
- CMake-2-6 on 2008-12-31 15:14:30 +0000
-
-2008-12-16 15:00 hoffman
-
- * Source/QtDialog/Compilers.ui: file Compilers.ui was added on
- branch CMake-2-6 on 2008-12-31 15:14:30 +0000
-
-2008-12-16 15:00 hoffman
-
- * Source/QtDialog/CrossCompiler.ui: file CrossCompiler.ui was added
- on branch CMake-2-6 on 2008-12-31 15:14:30 +0000
-
-2008-12-16 15:00 hoffman
-
- * Source/QtDialog/FirstConfigure.cxx: file FirstConfigure.cxx was
- added on branch CMake-2-6 on 2008-12-31 15:14:30 +0000
-
-2008-12-16 15:00 hoffman
-
- * Source/QtDialog/FirstConfigure.h: file FirstConfigure.h was added
- on branch CMake-2-6 on 2008-12-31 15:14:30 +0000
-
-2008-12-16 15:00 clinton
-
- * Source/QtDialog/: CMakeFirstConfigure.cxx, CMakeFirstConfigure.h,
- CMakeFirstConfigure.ui, CMakeLists.txt, CMakeSetupDialog.cxx,
- Compilers.h, Compilers.ui, CrossCompiler.ui, FirstConfigure.cxx,
- FirstConfigure.h:
- ENH:
-
- For bug #7191. Improvements to the dialog that sets up the first
- configure. Fixing the large size of it by breaking it up into a
- wizard. Also incorporated suggestions from bug report.
-
-2008-12-16 09:23 king
-
- * Source/cmFindPackageCommand.cxx: BUG: find_package must push/pop
- policies
-
- When the find_package command loads a <name>-version.cmake file
- to test the package version it must prevent the version file from
- affecting policy settings. Therefore the policy settings must be
- pushed and popped.
-
-2008-12-16 09:20 king
-
- * Source/cmInstallGenerator.cxx: BUG: Fix component-name test on
- installation
-
- Generated cmake_install.cmake script code used MATCHES to compare
- component names. This does not support characters considered
- special by regular expression syntax in component names. This
- change uses STREQUAL instead. See issue #8256.
-
-2008-12-16 09:15 king
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h: ENH: Warn if
- build dir is too long for filesystem
-
- When an object file directory is too deep to place an object file
- without exceeding CMAKE_OBJECT_PATH_MAX, this issues a warning.
- Previously we silently ignored the problem. See issue #7860.
-
-2008-12-16 09:14 king
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: ENH: Refactor passing of max
- length object dir
-
- When computing the maximum length full path to the build
- directory under which object files will be placed, pass the
- actual path instead of just its length. This will be useful for
- error message generation.
-
-2008-12-16 09:13 hoffman
-
- * Tests/FindPackageTest/lib/cmake/zot-4.0/zot-config-version.cmake:
- file zot-config-version.cmake was added on branch CMake-2-6 on
- 2009-01-13 18:03:56 +0000
-
-2008-12-16 09:13 hoffman
-
- * Tests/FindPackageTest/lib/cmake/zot-4.0/zot-config.cmake: file
- zot-config.cmake was added on branch CMake-2-6 on 2009-01-13
- 18:03:56 +0000
-
-2008-12-16 09:13 king
-
- * Tests/FindPackageTest/: CMakeLists.txt,
- lib/cmake/zot-4.0/zot-config-version.cmake,
- lib/cmake/zot-4.0/zot-config.cmake,
- lib/zot-3.1/zot-config-version.cmake,
- lib/zot-3.1/zot-config.cmake: ENH: Strengthen FindPackageTest
- version check
-
- The previous change to test finding in lib/cmake/<name>* weakened
- the versioned find tests. Since the lib/cmake paths are searched
- before lib/<name>* paths the previous change skipped requiring
- the command to ignore zot-3.0 when finding zot-3.1. This change
- restores that and adds zot-4.0 to test the lib/cmake path.
-
-2008-12-16 00:04 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-15 18:48 clinton
-
- * Modules/FindQt4.cmake:
- BUG: Fix for #8247. Add QT_TRANSLATIONS_DIR pointing to
- the Qt translation files, and docs for it. Also add docs
- for QT_BINARY_DIR.
-
-2008-12-15 17:19 fbertel
-
- * Source/kwsys/: ProcessUNIX.c, SystemInformation.cxx: COMP:Fixed
- warnings.
-
-2008-12-15 13:30 king
-
- * Source/: cmDocumentVariables.cxx, cmTarget.cxx: BUG: Fix
- <CONFIG>_POSTFIX property/variable docs
-
- The CMAKE_<CONFIG>_POSTFIX variable and <CONFIG>_POSTFIX property
- were not documented. This updates the CMAKE_DEBUG_POSTFIX and
- DEBUG_POSTFIX documentation to refer to the more general
- variable/property. It also clarifies that the variable is used
- as the property default only for non-executable targets. See
- issue #7868.
-
-2008-12-14 00:04 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-12 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-11 22:05 lowman
-
- * Modules/FindCxxTest.cmake: ENH: Added FindCxxTest module to
- assist others in using the CxxTest unit testing framework within
- CTest
-
-2008-12-11 15:55 david.cole
-
- * Tests/ExternalProject/CMakeLists.txt: BUG: One more conditional
- in the ExternalProject test to prevent build errors of Tutorial
- Step5 on Win98 using Visual Studio 6 when the path length of its
- build tree exceeds 72 characters. Crazy, perhaps. But this fixes
- the last real dashboard failure of the ExternalProject test.
-
-2008-12-11 14:35 hoffman
-
- * Tests/CMakeLists.txt: ENH: remove some verbosity to reduce test
- time
-
-2008-12-11 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-10 11:30 david.cole
-
- * Tests/ExternalProject/CMakeLists.txt: BUG: Prevent KWStyle
- portion of ExternalProject test from configuring, building,
- installing and testing on WATCOM dashboards. WATCOM STL support
- is still under development.
-
-2008-12-10 10:50 david.cole
-
- * Source/: cmGlobalVisualStudio6Generator.cxx,
- cmLocalVisualStudio6Generator.cxx: STYLE: Fix line length style
- violations.
-
-2008-12-10 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-09 16:07 david.cole
-
- * Source/: cmGlobalVisualStudio6Generator.cxx,
- cmLocalVisualStudio6Generator.cxx, cmake.cxx: COMP: Fix the
- ExternalProject test for Visual Studio 6. Visual Studio 6 *.dsp
- files cannot have hyphens in them. Add utility function
- GetVS6TargetName to replace hyphens with underscores when
- generating *.dsp file names. Use the function everywhere
- necessary in the VS6 generators. And, a workaround: VS6 uses
- ".\Debug" (for example) as an "$(IntDir)" value - strip any
- leading ".\" when processing a --config argument in the cmake
- --build handling code.
-
-2008-12-09 15:31 david.cole
-
- * Modules/AddExternalProject.cmake: ENH: Default to the same cmake
- used for configuring when building and installing. If none
- specified default to the cmake used to configure the
- outer/aggregating project.
-
-2008-12-09 14:07 king
-
- * Source/cmFindPackageCommand.cxx,
- Tests/FindPackageTest/CMakeLists.txt,
- Tests/FindPackageTest/lib/zot-3.1/zot-config-version.cmake,
- Tests/FindPackageTest/lib/zot-3.1/zot-config.cmake: ENH: Add
- useful search locations to find_package
-
- This teaches find_package to search
-
- <prefix>/(share|lib)/cmake/<name>*/
-
- for package configuration files. Packages that do not already
- have files in a <prefix>/lib/<name>* directory can use this
- location to avoid cluttering the lib directory.
-
-2008-12-09 14:07 king
-
- * Source/cmFindPackageCommand.cxx: STYLE: Remove old TODO comment
- in find_package
-
- Versioning has been introduced to find_package, so the comment
- about it is out of date.
-
-2008-12-09 10:56 david.cole
-
- * Templates/TestDriver.cxx.in: COMP: Don't emit old style cast
- warning when configured as C++ but still allow being configured
- as C. Thanks to Monsieur Francois Bertel for the patch.
-
-2008-12-09 10:08 king
-
- * Source/: cmFindPackageCommand.cxx, cmFindPackageCommand.h: ENH:
- Preserve <pkg>_FIND_XXX vars in find_package
-
- When the find_package command loads a module it sets several
- <pkg>_FIND_XXX variables to communicate information about the
- command invocation to the module. This restores the original
- state of the variables when the command returns. This behavior
- is useful when a find-module recursively calls find_package with
- NO_MODULE so that the inner call does not change the values in
- the find-module.
-
-2008-12-09 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-08 17:39 hoffman
-
- * Modules/FindSquish.cmake: file FindSquish.cmake was added on
- branch CMake-2-6 on 2008-12-31 15:14:25 +0000
-
-2008-12-08 17:39 hoffman
-
- * Modules/SquishRunTestCase.bat: file SquishRunTestCase.bat was
- added on branch CMake-2-6 on 2008-12-31 15:14:28 +0000
-
-2008-12-08 17:39 hoffman
-
- * Modules/SquishRunTestCase.sh: file SquishRunTestCase.sh was added
- on branch CMake-2-6 on 2008-12-31 15:14:29 +0000
-
-2008-12-08 17:39 hoffman
-
- * Modules/SquishTestScript.cmake: file SquishTestScript.cmake was
- added on branch CMake-2-6 on 2008-12-31 15:14:29 +0000
-
-2008-12-08 17:39 davisb
-
- * Modules/: FindSquish.cmake, SquishRunTestCase.bat,
- SquishRunTestCase.sh, SquishTestScript.cmake: ENH: adding
- functionality for finding Squish, adding Squish tests from CMake,
- and running Squish tests from ctest
-
-2008-12-08 14:58 david.cole
-
- * Modules/AddExternalProject.cmake: BUG: Make sure all directories
- used as working directories exist at CMake configure time as well
- as having custom commands that create them. Necessary for the
- Borland Makefiles generator to generate short path names in the
- makefile build rules. Also, make sure all custom commands chain
- together properly through the use of the sentinel files.
-
-2008-12-08 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-07 19:36 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx: STYLE: fix link length
- issues
-
-2008-12-07 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-06 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-05 17:54 david.cole
-
- * Tests/ExternalProject/CMakeLists.txt: COMP: No-op. White space
- only change to trigger a re-run of the ExternalProject test on
- the QNX continuous dashboard to pick up the latest KWStyle
- changes.
-
-2008-12-05 17:18 david.cole
-
- * Tests/ExternalProject/CMakeLists.txt: COMP: No-op. White space
- only change to trigger a re-run of the ExternalProject test on
- the QNX continuous dashboard to pick up the latest KWStyle
- changes.
-
-2008-12-05 16:46 david.cole
-
- * Tests/ExternalProject/CMakeLists.txt: COMP: No-op. White space
- only change to trigger a re-run of the ExternalProject test on
- the QNX continuous dashboard to pick up the latest KWStyle
- changes.
-
-2008-12-05 16:13 david.cole
-
- * Tests/ExternalProject/CMakeLists.txt: COMP: No-op. White space
- only change to trigger a re-run of the ExternalProject test on
- the QNX continuous dashboard to pick up the latest KWStyle
- changes.
-
-2008-12-05 15:18 david.cole
-
- * Modules/AddExternalProject.cmake,
- Tests/ExternalProject/CMakeLists.txt: ENH: Make it easier to use
- configure/make/make-install as the build steps for an external
- project. Add capability of customizing the download step. Add
- tests of empty projects. Better comments and error checking in
- AddExternalProject.cmake. In tests, use KWStyle from CVSHEAD to
- see if QNX continuous can build the latest KWStyle. Make KWStyle
- test depend on all previous test external projects so it builds
- last to catch other issues before any KWStyle compile errors.
-
-2008-12-05 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-04 15:30 david.cole
-
- * Tests/ExternalProject/: CMakeLists.txt, TryCheckout.cmake: ENH:
- Use a TryCheckout technique to decide whether or not to attempt
- building the projects that depend on a cvs or svn download
- method.
-
-2008-12-04 13:27 david.cole
-
- * Modules/AddExternalProject.cmake, Modules/DownloadFile.cmake,
- Modules/RepositoryInfo.txt.in, Modules/UntarFile.cmake,
- Tests/CMakeLists.txt, Tests/ExternalProject/CMakeLists.txt,
- Tests/ExternalProject/Step1.tar, Tests/ExternalProject/Step1.tgz,
- Tests/ExternalProject/Step1NoDir.tar,
- Tests/ExternalProject/Step1NoDir.tgz: ENH: First draft of
- add_external_project functionality. Tweaks, dashboard fixing,
- more tests and documentation certain to follow as it gets used by
- others...
-
-2008-12-04 10:51 hoffman
-
- * Source/kwsys/SystemInformation.cxx: BUG: fix cpu info string
-
-2008-12-04 09:12 hoffman
-
- * Modules/GetPrerequisites.cmake: BUG: make sure list is not size 0
- before sort
-
-2008-12-04 09:09 hoffman
-
- * Source/CPack/cmCPackBundleGenerator.cxx: ENH: allow startup
- command to be optional
-
-2008-12-04 08:57 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx: BUG: fix for bug #8216
-
-2008-12-04 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-03 16:13 hoffman
-
- * Modules/: FindCurses.cmake, Platform/Haiku.cmake: ENH: fix curses
- on haiku
-
-2008-12-03 15:35 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx,
- Templates/DLLHeader.dsptemplate, Templates/EXEHeader.dsptemplate,
- Templates/EXEWinHeader.dsptemplate,
- Templates/staticLibHeader.dsptemplate: BUG: fix for rc and vs6
-
-2008-12-03 14:37 hoffman
-
- * Modules/CPackRPM.cmake: BUG: #7904 add rpm package depend
-
-2008-12-03 11:21 hoffman
-
- * Utilities/cmcurl/Testing/curltest.c: ENH: disable ftp test on
- branch
-
-2008-12-03 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-02 21:44 hoffman
-
- * Tests/Fortran/: foo.c, foo.f, mysub.f: ENH: add missing files
-
-2008-12-02 16:40 hoffman
-
- * Utilities/cmcurl/Testing/curltest.c: ENH: disable ftp check
- because it is no longer active on public
-
-2008-12-02 07:07 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Modules/CMakeASM-ATTInformation.cmake,
- Modules/CMakeDetermineASM-ATTCompiler.cmake,
- Modules/CMakeDetermineASMCompiler.cmake,
- Modules/CMakeDetermineFortranCompiler.cmake,
- Modules/CMakeTestASM-ATTCompiler.cmake, Modules/CTest.cmake,
- Modules/FindQt4.cmake, Modules/FortranCInterface.cmake,
- Modules/FortranCInterface.h.in,
- Modules/InstallRequiredSystemLibraries.cmake,
- Modules/Platform/SunOS-SunPro-Fortran.cmake,
- Modules/Platform/Windows-g77.cmake,
- Source/cmIncludeExternalMSProjectCommand.h,
- Source/cmInstallTargetGenerator.cxx, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmake.cxx,
- Source/CTest/cmCTestScriptHandler.cxx,
- Source/CTest/cmCTestTestCommand.cxx,
- Source/CTest/cmCTestTestCommand.h,
- Source/kwsys/CTestConfig.cmake, Templates/TestDriver.cxx.in,
- Tests/Fortran/CMakeLists.txt, Utilities/cmcurl/CMakeLists.txt:
- ENH: merge in RC 5
-
-2008-12-02 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-12-01 14:41 david.cole
-
- * Source/cmGlobalMSYSMakefileGenerator.cxx: BUG: Do not require
- CMAKE_AR in the MSYS Makefiles generator when enabling language
- "NONE".
-
-2008-12-01 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-30 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-29 00:05 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-28 10:50 david.cole
-
- * Source/cmCTest.h: STYLE: Fix line length style violation.
-
-2008-11-28 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-27 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-26 16:19 hoffman
-
- * Utilities/cmcurl/CMakeLists.txt: ENH: fix warning on HPUX
-
-2008-11-26 15:41 david.cole
-
- * Source/cmSystemTools.cxx: COMP: Using the proper type for local
- variables can eliminate compiler warnings.
-
-2008-11-26 14:38 david.cole
-
- * Source/cmCTest.cxx, Source/cmCTest.h, Source/cmSystemTools.cxx,
- Source/cmSystemTools.h,
- Source/CTest/cmCTestBuildAndTestHandler.cxx,
- Source/CTest/cmCTestTestHandler.cxx,
- Source/CTest/cmCTestTestHandler.h, Tests/CMakeLists.txt,
- Tests/Environment/CMakeLists.txt, Tests/Environment/main.cxx:
- ENH: Implement feature request from issue 7885. Allow setting
- environment variables on a per-test basis for ctest using
- set_test_properties ENVIRONMENT.
-
-2008-11-26 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-25 16:56 clinton
-
- * Modules/FindQt4.cmake:
- BUG: Revert 1.138.
-
-2008-11-25 16:50 king
-
- * Source/cmInstallTargetGenerator.cxx: BUG: Do not map install_name
- of imported targets
-
- When we install a target on Mac, we generate a call to
- install_name_tool to fix install_name entries in the target for
- shared libraries it links. This change makes the step ignore
- entries for imported targets since their install_name will not
- change and cmTarget cannot produce a mapping for them. This
- fixes the error
-
- GetLibraryNamesInternal called on imported target: kdelibs
-
- seen by kde folks.
-
-2008-11-25 09:52 perera
-
- * Templates/TestDriver.cxx.in: BUG: the return value of scanf
- should not be ignored
-
-2008-11-25 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-24 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-23 22:07 hoffman
-
- * Source/kwsys/CTestConfig.cmake: ENH: make it submit to cdash
-
-2008-11-23 10:49 hoffman
-
- * Source/cmCTest.cxx, Source/CTest/cmCTestCoverageHandler.cxx,
- Source/CTest/cmCTestScriptHandler.cxx, Tests/CMakeLists.txt: ENH:
- add more debug stuff to CTestCTest2 so I can figure out redwall
-
-2008-11-23 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-22 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-21 16:37 hoffman
-
- * Tests/CMakeLists.txt: ENH: make ctest more verbose so that we can
- see failure on redwall
-
-2008-11-21 16:32 hoffman
-
- * Source/: cmMakefile.cxx, cmMakefile.h, cmSetCommand.cxx: BUG: fix
- issue with -D and cache force
-
-2008-11-21 16:10 hoffman
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt: ENH: make this
- test pass if new curl is on
-
-2008-11-21 14:57 hoffman
-
- * Source/cmIncludeExternalMSProjectCommand.h: BUG: fix for 8123
- documentation issue
-
-2008-11-21 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-20 14:06 hoffman
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt: ENH: only link in
- curl directories that exist, this will help with vs6 nmake
-
-2008-11-20 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-19 01:15 hoffman
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt: ENH: make it work
- if new curl is on
-
-2008-11-19 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-18 09:37 hoffman
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt: ENH: make it work
- if new curl is on
-
-2008-11-18 09:37 hoffman
-
- * Tests/CMakeLists.txt: ENH: add gfortran-4
-
-2008-11-18 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-17 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-16 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-15 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-14 17:45 hoffman
-
- * Modules/CMakeDetermineFortranCompiler.cmake: BUG: fix for #8089,
- fix rebuild with fortran and -D
-
-2008-11-14 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-13 17:12 david.cole
-
- * Modules/InstallRequiredSystemLibraries.cmake: BUG: Because of
- Windows registry madness, we could not find the redistributables
- directory on Win64 builds... Add a search directory based on
- devenv (CMAKE_MAKE_PROGRAM) location so we can find it despite
- the madness.
-
-2008-11-13 16:46 hoffman
-
- * Modules/FindDevIL.cmake: file FindDevIL.cmake was added on branch
- CMake-2-6 on 2009-02-04 16:44:01 +0000
-
-2008-11-13 16:46 alex
-
- * Modules/FindDevIL.cmake: BUG: the modules shipped with cmake
- don't need CMAKE_MINIMUM_REQUIRED(VERSION), because the cmake
- they are shipped with is always ok. Additionally, if a
- Find-module does CMAKE_MINIMUM_REQUIRED(), it changes the
- policies as they may be set up by the project. So this shouldn't
- be done in a Find-module (or surrounded by policy-push/pop
- commands)
-
- Alex
-
-2008-11-13 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-12 12:26 chris
-
- * Modules/FindDevIL.cmake: ENH: Added First revision of
- FindDevIL.cmake
-
-2008-11-12 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-11 16:52 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/GetPrerequisites.cmake,
- Modules/UseQt4.cmake, Source/cmGlobalGenerator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/kwsys/DynamicLoader.hxx.in: ENH: merge in fixes from head
- RC 4
-
-2008-11-11 14:03 hoffman
-
- * Tests/Fortran/CMakeLists.txt: ENH: fix gcc sun fortran mix
-
-2008-11-11 13:58 hoffman
-
- * Modules/Platform/Windows-g77.cmake: ENH: fix fortran flags on g77
- windows
-
-2008-11-11 13:58 hoffman
-
- * Modules/Platform/SunOS-SunPro-Fortran.cmake: ENH: fix fortran
- flags on sun
-
-2008-11-11 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-10 13:42 hoffman
-
- * Source/cmGlobalGenerator.cxx: BUG: fix package_source target
-
-2008-11-10 10:53 hoffman
-
- * Tests/Fortran/CMakeLists.txt: ENH: put a check in for the gnu
- sunpro case
-
-2008-11-10 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-09 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-08 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-07 16:40 hoffman
-
- * Source/kwsys/DynamicLoader.hxx.in: BUG: fix for bug 8060 Haiku
- build
-
-2008-11-07 15:56 alex
-
- * Source/CTest/cmCTestScriptHandler.cxx: ENH: load
- CMakeDetermineSystem and CMakeSystemSpecificInformation when
- executing a ctest script so the search paths are fully set up and
- variables like CMAKE_SYSTEM are available. This is useful e.g.
- for new-style ctest scripting. (these files are also loaded on
- startup by cpack, so now they behave similar). Hmmm, maybe they
- should be also loaded by cmake -P ?
-
- Alex
-
-2008-11-07 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-06 17:33 hoffman
-
- * Tests/Fortran/CMakeLists.txt: ENH: make the test pass when
- fortran is gnu and c is cl
-
-2008-11-06 10:54 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Utilities/cmcurl/CMakeLists.txt: ENH: merge in haiku build change
- from head, again...
-
-2008-11-06 09:41 hoffman
-
- * Tests/Fortran/CMakeLists.txt: ENH: add a way to fix bullseye link
- with fortran
-
-2008-11-06 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-05 18:51 alex
-
- * Modules/CMakeASM-ATTInformation.cmake: STYLE: add some comment,
- so it says at least a bit what it is good for
-
- Alex
-
-2008-11-05 17:56 clinton
-
- * Modules/FindQt4.cmake:
- BUG: Fix #7969. Fix moc output files if source dir contains
- regex characters.
-
-2008-11-05 17:27 hoffman
-
- * Modules/CMakeASM_MASMInformation.cmake: file
- CMakeASM_MASMInformation.cmake was added on branch CMake-2-6 on
- 2008-12-31 15:14:18 +0000
-
-2008-11-05 17:27 hoffman
-
- * Modules/CMakeDetermineASM_MASMCompiler.cmake: file
- CMakeDetermineASM_MASMCompiler.cmake was added on branch
- CMake-2-6 on 2008-12-31 15:14:18 +0000
-
-2008-11-05 17:27 hoffman
-
- * Modules/CMakeTestASM_MASMCompiler.cmake: file
- CMakeTestASM_MASMCompiler.cmake was added on branch CMake-2-6 on
- 2008-12-31 15:14:19 +0000
-
-2008-11-05 17:27 alex
-
- * Modules/: CMakeASM_MASMInformation.cmake,
- CMakeDetermineASM-ATTCompiler.cmake,
- CMakeDetermineASMCompiler.cmake,
- CMakeDetermineASM_MASMCompiler.cmake,
- CMakeTestASM-ATTCompiler.cmake, CMakeTestASM_MASMCompiler.cmake:
- ENH: add support for the MS masm and masm64 assemblers, works
- with nmake, not (yet) with the Visual Studio generators
-
- Alex
-
-2008-11-05 16:54 clinton
-
- * Modules/UseQt4.cmake:
- BUG: Fix #7934. phonon doesn't always depend on QtDBus.
-
-2008-11-05 10:20 hoffman
-
- * Tests/Fortran/CMakeLists.txt: ENH: only call the fortran c
- interface test when compilers match
-
-2008-11-05 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-04 15:16 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Utilities/cmcurl/select.c,
- Utilities/cmcurl/CMake/CurlTests.c, Utilities/cmcurl/curl/curl.h,
- Utilities/cmtar/util.c, Utilities/cmzlib/zconf.h,
- Utilities/cmzlib/zutil.h: ENH: merge in the rest of the haiku
- changes
-
-2008-11-04 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-03 16:23 alex
-
- * Modules/CTest.cmake: STYLE: mention cdash (not only dart)
-
- Alex
-
-2008-11-03 12:15 hoffman
-
- * Tests/Fortran/CMakeLists.txt: ENH: only allow matching fortran a
- c compilers to be used
-
-2008-11-03 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-02 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-11-01 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-31 16:08 hoffman
-
- * Tests/Fortran/: CMakeLists.txt: ENH: do not error when sunpro or
- mipspro fortran used
-
-2008-10-31 07:50 hoffman
-
- * Modules/FortranCInterface.cmake: ENH: fix for intel module on
- linux
-
-2008-10-31 07:50 hoffman
-
- * Modules/FortranCInterface.cmake: file FortranCInterface.cmake was
- added on branch CMake-2-6 on 2008-12-02 12:07:37 +0000
-
-2008-10-31 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-30 17:48 hoffman
-
- * Modules/FortranCInterface.cmake: ENH: better output if module
- linkage is not found
-
-2008-10-30 17:32 hoffman
-
- * Tests/Fortran/CMakeLists.txt: ENH: add some debug stuff for the
- dashboards
-
-2008-10-30 16:50 hoffman
-
- * Modules/FortranCInterface.cmake: ENH: fix uppercase version so
- defines are not upper as well
-
-2008-10-30 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-29 19:49 hoffman
-
- * Modules/FortranCInterface.cmake: ENH: fix check for intel windows
- module mangling
-
-2008-10-29 19:34 hoffman
-
- * Modules/FortranCInterface.cmake: ENH: fix check for intel windows
- module mangling
-
-2008-10-29 17:40 hoffman
-
- * Modules/: FortranCInterface.cmake: ENH: add check for intel
- windows module mangling
-
-2008-10-29 17:37 hoffman
-
- * Modules/FortranCInterface.cmake: ENH: fix upper case
-
-2008-10-29 12:27 david.cole
-
- * Tests/: CMakeLists.txt, CPackComponents/CMakeLists.txt: ENH: Use
- settings for CPackComponents test to make it fail if the recent
- fix of cmCPackGenerator.cxx revision 1.16 ever encounters another
- regression.
-
-2008-10-29 12:24 hoffman
-
- * Modules/FortranCInterface.cmake: ENH: only check for module
- linkage if f90 is available
-
-2008-10-29 11:50 hoffman
-
- * Modules/FortranCInterface.cmake: ENH: fix for xlf module linkage
-
-2008-10-29 10:58 hoffman
-
- * Modules/FortranCInterface.cmake, Tests/Fortran/CMakeLists.txt,
- Tests/Fortran/foo.c, Tests/Fortran/foo.f, Tests/Fortran/mysub.f:
- ENH: add test for FortranCInterface
-
-2008-10-29 10:58 hoffman
-
- * Tests/Fortran/foo.c: file foo.c was added on branch CMake-2-6 on
- 2008-12-03 02:44:25 +0000
-
-2008-10-29 10:58 hoffman
-
- * Tests/Fortran/foo.f: file foo.f was added on branch CMake-2-6 on
- 2008-12-03 02:44:25 +0000
-
-2008-10-29 10:58 hoffman
-
- * Tests/Fortran/mysub.f: file mysub.f was added on branch CMake-2-6
- on 2008-12-03 02:44:25 +0000
-
-2008-10-29 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-28 19:53 hoffman
-
- * Modules/FortranCInterface.cmake: ENH: add support for g77 extra _
- at the end of functions that have an _ in the name...
-
-2008-10-28 00:03 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-27 21:42 hoffman
-
- * Modules/FortranCInterface.cmake: ENH: add support for module
- functions
-
-2008-10-27 15:31 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: ENH: make the scc
- optional
-
-2008-10-27 15:23 hoffman
-
- * Modules/: FortranCInterface.cmake, FortranCInterface.h.in: ENH:
- add fortran link discovery module
-
-2008-10-27 15:23 hoffman
-
- * Modules/FortranCInterface.h.in: file FortranCInterface.h.in was
- added on branch CMake-2-6 on 2008-12-02 12:07:37 +0000
-
-2008-10-27 13:51 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: fix for 7839 and
- 4524
-
-2008-10-27 05:23 hoffman
-
- * Modules/FindRTI.cmake: file FindRTI.cmake was added on branch
- CMake-2-6 on 2009-02-04 16:44:12 +0000
-
-2008-10-27 05:23 gotthardp
-
- * Modules/FindRTI.cmake: BUG: Fixed CMAKE_FIND_LIBRARY_PREFIXES
- related error on Win32 systems.
-
-2008-10-25 14:25 gotthardp
-
- * Modules/FindRTI.cmake: BUG: removed unused CMakeFindFrameworks
- include
-
-2008-10-25 12:20 gotthardp
-
- * Modules/FindRTI.cmake: ENH: added a module to find M&S HLA RTI
-
-2008-10-24 23:53 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-24 17:48 clinton
-
- * Modules/FindQt4.cmake:
- BUG: Fix find of assistant on Mac.
-
-2008-10-24 11:39 david.cole
-
- * Modules/GetPrerequisites.cmake, Tests/CMakeTests/CMakeLists.txt:
- ENH: Activate GetPrerequisites code on Linux. Thanks to Mike
- Arthur for finishing it off.
-
-2008-10-24 11:18 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, bootstrap,
- Modules/CMakeASMInformation.cmake,
- Modules/CMakeCInformation.cmake,
- Modules/CMakeCXXInformation.cmake,
- Modules/CMakeFortranCompilerId.F90.in,
- Modules/CMakeFortranInformation.cmake,
- Modules/CMakePlatformId.h.in, Modules/CMakeRCInformation.cmake,
- Modules/CheckForPthreads.c, Modules/FindBoost.cmake,
- Modules/FindGLUT.cmake, Modules/FindMFC.cmake,
- Modules/FindPerlLibs.cmake, Modules/FindQt4.cmake,
- Modules/FindTclStub.cmake, Modules/FindwxWidgets.cmake,
- Modules/Platform/Linux.cmake, Modules/Platform/OpenBSD.cmake,
- Modules/Platform/Windows-gcc.cmake, Source/CMakeLists.txt,
- Source/cmAddCustomTargetCommand.cxx,
- Source/cmAddCustomTargetCommand.h, Source/cmCTest.cxx,
- Source/cmCallVisualStudioMacro.cxx, Source/cmCommand.h,
- Source/cmComputeLinkInformation.cxx,
- Source/cmComputeLinkInformation.h, Source/cmDependsJavaLexer.cxx,
- Source/cmDependsJavaLexer.h, Source/cmDocumentation.cxx,
- Source/cmDocumentation.h, Source/cmDocumentationFormatter.cxx,
- Source/cmDocumentationFormatter.h,
- Source/cmDocumentationFormatterDocbook.cxx,
- Source/cmDocumentationFormatterDocbook.h,
- Source/cmDocumentationFormatterHTML.cxx,
- Source/cmDocumentationFormatterHTML.h,
- Source/cmDocumentationFormatterMan.cxx,
- Source/cmDocumentationFormatterMan.h,
- Source/cmEnableLanguageCommand.cxx, Source/cmFindBase.cxx,
- Source/cmFindCommon.cxx, Source/cmFindLibraryCommand.cxx,
- Source/cmFindPackageCommand.cxx, Source/cmGlobalGenerator.cxx,
- Source/cmGlobalGenerator.h,
- Source/cmGlobalNMakeMakefileGenerator.cxx,
- Source/cmGlobalVisualStudio71Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalXCodeGenerator.cxx,
- Source/cmGlobalXCodeGenerator.h, Source/cmIfCommand.cxx,
- Source/cmIfCommand.h, Source/cmInstallCommand.cxx,
- Source/cmInstallTargetGenerator.cxx,
- Source/cmInstallTargetGenerator.h, Source/cmListFileCache.cxx,
- Source/cmListFileCache.h, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalUnixMakefileGenerator3.h,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmMacroCommand.cxx, Source/cmMakefile.cxx,
- Source/cmMakefile.h,
- Source/cmMakefileExecutableTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.h,
- Source/cmOutputRequiredFilesCommand.cxx, Source/cmPolicies.cxx,
- Source/cmPolicies.h, Source/cmSetTargetPropertiesCommand.h,
- Source/cmSourceFile.cxx, Source/cmSystemTools.cxx,
- Source/cmTarget.cxx, Source/cmWhileCommand.cxx, Source/cmake.cxx,
- Source/cmakemain.cxx, Source/CPack/cmCPackBundleGenerator.cxx,
- Source/CPack/cmCPackGenerator.cxx,
- Source/CPack/cmCPackGenerator.h,
- Source/CPack/cmCPackNSISGenerator.cxx,
- Source/CPack/cmCPackNSISGenerator.h,
- Source/CPack/cmCPackPackageMakerGenerator.cxx,
- Source/CTest/cmCTestUpdateHandler.cxx,
- Source/CursesDialog/cmCursesMainForm.cxx,
- Source/kwsys/DynamicLoader.cxx,
- Source/kwsys/DynamicLoader.hxx.in, Source/kwsys/ProcessUNIX.c,
- Source/kwsys/SystemInformation.cxx, Source/kwsys/SystemTools.cxx,
- Source/kwsys/testDynamicLoader.cxx, Source/kwsys/testProcess.c,
- Tests/CMakeLists.txt, Tests/CTestUpdateCVS.cmake.in,
- Tests/CTestUpdateCommon.cmake, Tests/CTestUpdateSVN.cmake.in,
- Tests/Complex/CMakeLists.txt, Tests/Complex/cmTestConfigure.h.in,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexOneConfig/cmTestConfigure.h.in,
- Tests/ComplexRelativePaths/CMakeLists.txt,
- Tests/ComplexRelativePaths/cmTestConfigure.h.in,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/complex.cxx,
- Tests/CustomCommand/CMakeLists.txt,
- Tests/FindPackageTest/CMakeLists.txt,
- Tests/FindPackageTest/lib/RecursiveA/recursivea-config.cmake,
- Tests/FindPackageTest/lib/zot/zot-config-version.cmake,
- Tests/FindPackageTest/lib/zot/zot-config.cmake,
- Modules/FindCoin3D.cmake, Modules/Platform/Haiku.cmake,
- Tests/FindPackageTest/FindRecursiveA.cmake,
- Tests/FindPackageTest/FindRecursiveB.cmake,
- Tests/FindPackageTest/FindRecursiveC.cmake: ENH: merge in changes
- for 2.6.3 RC 1
-
-2008-10-23 23:53 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-22 23:53 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-21 23:54 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-20 23:54 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-20 13:31 clinton
-
- * Modules/FindQt4.cmake:
- BUG: Fix regression in finding QtAssistant
-
-2008-10-20 11:50 miguelf
-
- * Modules/FindwxWidgets.cmake: BUG: Fix to find wxWidgets_LIB_DIR
- for windows platform more generally; supports gcc, nmake,
- and visual studio in all configurations.
-
-2008-10-19 23:54 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-19 21:14 miguelf
-
- * Modules/FindwxWidgets.cmake: BUG: Added unicode paths for
- wxWidgets_LIB_DIR search and the 2.8.9 suffix for
- wxWidgets_ROOT_DIR search.
-
-2008-10-19 16:16 king
-
- * Tests/CMakeLists.txt: ENH: Enable cvs update test with CMake
- before 2.6
-
- When CMake is built by CMake 2.4 or lower the FindCVS module is
- not available. In that case we activiate CTest.UpdateCVS by
- searching for the cvs command directly.
-
-2008-10-19 11:53 hoffman
-
- * Tests/CTestUpdateCVS.cmake.in: file CTestUpdateCVS.cmake.in was
- added on branch CMake-2-6 on 2008-10-24 15:18:56 +0000
-
-2008-10-19 11:53 hoffman
-
- * Tests/CTestUpdateCommon.cmake: file CTestUpdateCommon.cmake was
- added on branch CMake-2-6 on 2008-10-24 15:18:56 +0000
-
-2008-10-19 11:53 hoffman
-
- * Tests/CTestUpdateSVN.cmake.in: file CTestUpdateSVN.cmake.in was
- added on branch CMake-2-6 on 2008-10-24 15:18:56 +0000
-
-2008-10-19 11:53 king
-
- * Tests/: CMakeLists.txt, CTestUpdateCVS.cmake.in,
- CTestUpdateCommon.cmake, CTestUpdateSVN.cmake.in: ENH: Test CTest
- update logic with VCS tools
-
- This creates new tests "CTest.UpdateSVN" and "CTest.UpdateCVS".
- They test that the Update.xml produced by CTest for a
- version-controlled project contains entries for files added,
- changed, and removed.
-
-2008-10-19 10:44 hoffman
-
- * Source/CTest/cmCTestUpdateHandler.cxx: BUG: use LC_MESSAGES = C
- instead of en_EN
-
-2008-10-18 23:54 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-18 12:07 king
-
- * Source/CTest/cmCTestUpdateHandler.cxx: BUG: Fix recognition of
- files deleted from CVS
-
- The output of "cvs update" contains a line such as one of
-
- cvs update: `foo.txt' is no longer in the repository
- cvs update: foo.txt is no longer in the repository
- cvs update: warning: foo.txt is not (any longer) pertinent
-
- when file "foo.txt" has been removed in the version to which the
- update occurs. Previously only the first case would be
- recognized. This fixes the regular expression to match all these
- cases.
-
-2008-10-18 10:31 hoffman
-
- * Tests/CMakeBuildTest.cmake.in: ENH: fix test to work with
- in-source testing of CMake
-
-2008-10-17 23:54 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-17 12:52 king
-
- * Source/kwsys/CMakeLists.txt: BUG: Fix KWSys SystemInformation
- dependencies
-
- The SystemInformation component of KWSys requires Process and
- FundamentalType.
-
-2008-10-17 12:51 king
-
- * Source/kwsys/CMakeLists.txt: BUG: Enforce KWSys component
- dependencies early
-
- KWSys component dependencies must be enforced before any tests
- for enabled components are done. This moves the dependency
- enforcement code to be as early as possible.
-
-2008-10-17 11:29 barre
-
- * Source/kwsys/: SystemInformation.cxx: ENH: fix for VS6 and Cygwin
-
-2008-10-16 23:54 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-16 19:30 barre
-
- * Source/kwsys/: SystemInformation.cxx, SystemTools.cxx,
- SystemTools.hxx.in: ENH: fix for Vista
-
-2008-10-16 11:34 barre
-
- * Source/kwsys/: SystemTools.cxx: ENH: oops
-
-2008-10-15 23:54 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-15 23:24 barre
-
- * Source/kwsys/: SystemTools.cxx: ENH: fix for Windows Vista
-
-2008-10-15 18:05 clinton
-
- * Modules/FindQt4.cmake:
- ENH: better way to find uic and moc.
-
-2008-10-15 16:56 hoffman
-
- * Tests/CMakeBuildTest.cmake.in: ENH: run the right cmake
-
-2008-10-15 16:50 hoffman
-
- * Tests/CMakeBuildTest.cmake.in: ENH: run the right cmake
-
-2008-10-15 15:13 hoffman
-
- * Source/cmake.cxx: ENH: fix bootstrap test and warning
-
-2008-10-15 13:56 hoffman
-
- * Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmProjectCommand.cxx, Source/cmake.cxx, Source/cmake.h,
- Source/cmakemain.cxx, Tests/CMakeBuildTest.cmake.in,
- Tests/CMakeLists.txt: BUG: 4244, add a --build option to cmake
- that can build projects configured by CMake
-
-2008-10-15 10:49 hoffman
-
- * Modules/CMakeDetermineRCCompiler.cmake: ENH: remove extra set
-
-2008-10-15 10:40 king
-
- * Source/: cmLocalUnixMakefileGenerator3.h,
- cmMakefileTargetGenerator.cxx: BUG: Fix color check for
- dependency scanning
-
- Generation of color rules for dependency scanning messages did
- not account for disabling color at generation time. See issue
- #7814.
-
-2008-10-15 10:21 king
-
- * Source/cmMakefileTargetGenerator.cxx: ENH: Support object lists
- longer than 128K on MSVC
-
- We use response files to list object files for the MSVC linker.
- The linker complains if any response file is greater than 128K,
- so we split the object file lists into multiple response files.
-
-2008-10-15 10:21 king
-
- * Source/: cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx, cmMakefileTargetGenerator.h: ENH:
- Factor out listing of objects on command line
-
- Previously generation of object file lists for linker and
- cleaning command lines was duplicated for library and executable
- target generators. This combines the implementations.
-
-2008-10-15 10:21 king
-
- * Source/: cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx: STYLE: Remove computed but
- unused variable.
-
- An old list of object files for cleaning seems to have been left
- behind. This removes it.
-
-2008-10-15 09:35 david.cole
-
- * Source/CPack/cmCPackGenerator.cxx: BUG: Use the DESTDIR prefix
- when creating the directory in CPack when CPACK_SET_DESTDIR is
- ON. Thanks to Petri Hodju for reporting this regression to the
- CMake mailing list:
- http://www.cmake.org/pipermail/cmake/2008-October/024563.html.
-
-2008-10-14 23:54 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-14 16:07 hoffman
-
- * Modules/: CMakeASMInformation.cmake, CMakeCInformation.cmake,
- CMakeCXXInformation.cmake, CMakeDetermineRCCompiler.cmake,
- CMakeFortranInformation.cmake, CMakeRCInformation.cmake,
- Platform/Windows-cl.cmake: ENH: fix problem where rc language
- recursively included itself because CMAKE_BASE_NAME was used from
- c compiler, do the same fix for other uses of CMAKE_BASE_NAME
-
-2008-10-14 13:56 hoffman
-
- * Source/cmEnableLanguageCommand.cxx: ENH: revert last change, as
- it fails tests
-
-2008-10-14 11:42 hoffman
-
- * Modules/Platform/Windows-cl.cmake,
- Source/cmGlobalNMakeMakefileGenerator.cxx,
- Source/cmEnableLanguageCommand.cxx: ENH: better error message for
- mis-configured nmake environment
-
-2008-10-14 08:43 king
-
- * Source/cmFindBase.cxx: ENH: Clarify PATH_SUFFIXES documentation
-
- This clarifies documentation of the find_* commands'
- PATH_SUFFIXES option. The option adds paths with the suffixes
- but does not remove the paths without the suffixes.
-
-2008-10-13 23:54 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-13 22:12 clinton
-
- * Modules/FindQt4.cmake:
- ENH: When changing the qmake pointed to, re-find all of Qt's
- includes, libraries, etc... This makes it much easier to
- switch between Qt versions.
-
-2008-10-13 19:39 clinton
-
- * Modules/FindQt4.cmake:
- BUG: Fix find of dbus dependency in Qt 4.4
-
-2008-10-13 09:58 king
-
- * Source/cmFindBase.cxx: BUG: Fix find_* search order with path
- suffixes
-
- In cmFindBase we were searching all path suffixes appended to all
- paths before considering the paths without any suffixes. Instead
- we should consider each path with and without suffixes before
- moving to the next path. See issue #7783.
-
-2008-10-12 23:54 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-11 23:55 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-11 15:35 king
-
- * Source/cmDocumentation.cxx: COMP: Fix assignment inside condition
-
-2008-10-11 12:02 king
-
- * Source/cmListFileCache.h: BUG: Make sure context info is always
- initialized
-
- This adds a missing default constructor to cmListFileContext that
- makes sure the line number is initialized to zero. A zero line
- number will indicate a generated context.
-
-2008-10-10 23:55 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-10 17:43 david.cole
-
- * Modules/FindMFC.cmake: BUG: Fix for issue #5193. Base result of
- FindMFC.cmake mostly on a TRY_COMPILE result. Gives accurate
- answer about whether MFC is available.
-
-2008-10-10 17:08 david.cole
-
- * Source/CPack/cmCPackNSISGenerator.cxx: BUG: Fix issue #7800.
- Enable CPack to find the NSIS installer on Windows 2000.
-
-2008-10-10 11:23 king
-
- * Source/: cmDocumentation.cxx, cmDocumentation.h,
- cmDocumentationFormatter.cxx, cmDocumentationFormatter.h,
- cmDocumentationFormatterDocbook.cxx,
- cmDocumentationFormatterDocbook.h,
- cmDocumentationFormatterHTML.cxx, cmDocumentationFormatterHTML.h,
- cmDocumentationFormatterMan.cxx, cmDocumentationFormatterMan.h:
- ENH: Improve generated documentation formatting
-
- Applying patch provided in issue #7797.
-
- Fixes to man-pages: - Character '-' must be espaced as '\-' -
- Surround preformatted text with '.nf' and '.fi' to adjust filling
- - Give every page a NAME section for indexing by mandb - Pass
- the man page filename without extension to .TH in its header
-
- Also added a title to the HTML header.
-
-2008-10-10 11:23 king
-
- * Source/cmDocumentation.cxx: BUG: Fix help type for filenames with
- many dots
-
- The help page type should be determined using only the extension
- after the last dot. See issue #7797.
-
-2008-10-10 11:23 king
-
- * Source/kwsys/SystemTools.cxx: STYLE: Fix typo in
- GetFilenameLastExtension docs
-
- See issue #7797.
-
-2008-10-10 10:48 hoffman
-
- * Source/cmOutputRequiredFilesCommand.cxx: BUG: fix for 5071,
- report error if output file can not be opened
-
-2008-10-10 10:20 hoffman
-
- * Source/cmakemain.cxx: BUG: fix for 3778, better docs for -E
-
-2008-10-10 09:36 hoffman
-
- * Source/CTest/cmCTestUpdateHandler.cxx: ENH: play it safe and
- restore the value of LC_MESSAGES
-
-2008-10-10 09:23 hoffman
-
- * Source/CTest/cmCTestUpdateHandler.cxx: ENH: make sure LC_MESSAGES
- is en_EN so that we can parse the output of svn and cvs
-
-2008-10-10 08:11 king
-
- * Source/cmGlobalXCodeGenerator.h: STYLE: Fix line-too-long
-
-2008-10-09 23:55 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-09 17:04 king
-
- * Modules/FindBoost.cmake: BUG: Avoid boost versions less than
- required
-
- Construction of a list of candidate versions used to produce
- search paths now discards versions less than requested by the
- user. See issue #7783.
-
-2008-10-09 15:30 king
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h,
- cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx: ENH: Fix optional use of relative
- paths.
-
- These changes refactor cmLocalGenerator methods Convert and
- ConvertToOutputForExisting to support references inside the build
- tree using relative paths. After this commit, all tests pass
- with Makefile generators when relative paths are enabled by
- default. See issue #7779.
-
-2008-10-09 15:08 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: Simplify makefile
- ref to interactive editor
-
- The CMAKE_EDIT_COMMAND make variable need not be constructed with
- ConvertToOutputForExisting. The CMAKE_COMMAND variable works
- fine without it.
-
-2008-10-09 15:07 king
-
- * Source/: cmLocalGenerator.cxx, cmMakefileTargetGenerator.cxx:
- ENH: Simplify framework -F flag generation
-
- This removes an unnecessary use of ConvertToOutputForExisting
- which is needed only on Windows to consider short-pathing.
-
-2008-10-09 13:52 king
-
- * Modules/CMakeRCInformation.cmake: BUG: Pass definitions to rc
- with Makefiles
-
- The build rule to run the resource compiler on Windows with a
- Makefiles generator should include the placeholder to add the
- definition flags. See issue #7769.
-
-2008-10-09 13:52 king
-
- * Source/cmMakefile.cxx: BUG: Finish fix to old DEFINITIONS
- property
-
- The cmMakefile::DefineFlagsOrig ivar was created to help preserve
- the old DEFINITIONS property behavior now that definitions are
- moved from DefineFlags to the COMPILE_DEFINITIONS directory
- property. This fixes propagation of the original value into
- subdirectories.
-
-2008-10-09 13:00 hoffman
-
- * Source/CTest/cmCTestBuildHandler.cxx: BUG: fix for 5218 Error
- message pattern match for VS8
-
-2008-10-09 12:49 hoffman
-
- * Source/CursesDialog/cmCursesMainForm.cxx: BUG: fix for 4026,
- display a message if ccmake has errors
-
-2008-10-09 11:01 king
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h:
- ENH: Put custom target sources in Xcode projects
-
- Source files in custom targets are now placed in the Xcode
- project for convenient editing. See issue #5848.
-
-2008-10-09 11:01 king
-
- * Source/cmAddCustomTargetCommand.cxx,
- Source/cmAddCustomTargetCommand.h,
- Tests/CustomCommand/CMakeLists.txt: ENH: Allow custom sources in
- custom targets
-
- This adds a SOURCES option to ADD_CUSTOM_TARGET, enabling users
- to specify extra sources for inclusion in the target. Such
- sources may not build, but will show up in the IDE project files
- for convenient editing. See issue #5848.
-
-2008-10-09 11:00 king
-
- * Source/: cmMakefile.cxx, cmMakefile.h: ENH: Return utility target
- after creation
-
- After creating a utility target with AddUtilityCommand, return a
- pointer to the cmTarget instance so the caller may further modify
- the target as needed.
-
-2008-10-08 23:55 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-08 17:58 alex
-
- * Source/CTest/cmCTestTestCommand.h: STYLE: lowercase ctest_test()
- in the documentation
-
- Alex
-
-2008-10-08 14:19 david.cole
-
- * Source/: CMakeLists.txt, cmCallVisualStudioMacro.cxx: BUG: Fix
- issue #7533. Revise fix for issue #7058 to use pragma comment
- libs in the source file rather than using TARGET_LINK_LIBRARIES
- in CMakeLists.txt because of the complex ifdef logic used in
- correct copies of comdef.h.
-
-2008-10-08 10:56 hoffman
-
- * Tests/FindPackageTest/FindRecursiveA.cmake: file
- FindRecursiveA.cmake was added on branch CMake-2-6 on 2008-10-24
- 15:20:35 +0000
-
-2008-10-08 10:56 king
-
- * Source/cmFindPackageCommand.cxx,
- Tests/FindPackageTest/FindRecursiveA.cmake: ENH: Remove implicit
- NO_MODULE when recursing
-
- Recently we taught find_package that the NO_MODULE option is
- implied when it is recursively invoked in a find-module. This
- behavior may be confusing because two identical calls may enter
- different modes depending on context. It also disallows the
- possibility that one find-module defers to another find-module by
- changing CMAKE_MODULE_PATH and recursively invoking find_package.
- This change reverts the feature.
-
-2008-10-07 23:55 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-07 16:46 hoffman
-
- * Source/cmTarget.cxx: ENH: add missing property definitions
-
-2008-10-07 16:23 hoffman
-
- * Source/: cmLocalVisualStudio7Generator.cxx,
- cmSetTargetPropertiesCommand.h: BUG: fix for 4524, add support
- for target properties to set vs source code control information
-
-2008-10-07 10:35 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Fix #7784. Fix link of glib when needed.
-
-2008-10-06 23:55 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-06 11:04 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Fix convenience
- rule working directory
-
- We generate convenience rules to build object files, preprocessed
- outputs, and assembly outputs of source files individually with
- make rules. This removes a redundant working directory change
- when more than one target builds the same source file.
-
-2008-10-05 23:55 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-04 23:55 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-03 23:55 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-03 10:41 hoffman
-
- * Tests/FindPackageTest/lib/zot/zot-config-version.cmake: file
- zot-config-version.cmake was added on branch CMake-2-6 on
- 2008-10-24 15:19:03 +0000
-
-2008-10-03 10:41 hoffman
-
- * Tests/FindPackageTest/lib/zot/zot-config.cmake: file
- zot-config.cmake was added on branch CMake-2-6 on 2008-10-24
- 15:19:06 +0000
-
-2008-10-03 10:41 king
-
- * Source/cmFindPackageCommand.cxx,
- Tests/FindPackageTest/lib/zot/zot-config-version.cmake,
- Tests/FindPackageTest/lib/zot/zot-config.cmake: ENH: Add
- UNSUITABLE result to package version test
-
- Package version test files may now declare that they are
- unsuitable for use with the project testing them. This is
- important when the version being tested does not provide a
- compatible ABI with the project target environment.
-
-2008-10-03 10:40 hoffman
-
- * Tests/FindPackageTest/lib/RecursiveA/recursivea-config.cmake:
- file recursivea-config.cmake was added on branch CMake-2-6 on
- 2008-10-24 15:19:01 +0000
-
-2008-10-03 10:40 hoffman
-
- * Tests/FindPackageTest/FindRecursiveB.cmake: file
- FindRecursiveB.cmake was added on branch CMake-2-6 on 2008-10-24
- 15:20:35 +0000
-
-2008-10-03 10:40 hoffman
-
- * Tests/FindPackageTest/FindRecursiveC.cmake: file
- FindRecursiveC.cmake was added on branch CMake-2-6 on 2008-10-24
- 15:20:35 +0000
-
-2008-10-03 10:40 king
-
- * Source/cmFindPackageCommand.cxx,
- Tests/FindPackageTest/CMakeLists.txt,
- Tests/FindPackageTest/FindRecursiveA.cmake,
- Tests/FindPackageTest/FindRecursiveB.cmake,
- Tests/FindPackageTest/FindRecursiveC.cmake,
- Tests/FindPackageTest/lib/RecursiveA/recursivea-config.cmake:
- ENH: Help recursive find_package calls in modules
-
- These changes teach find_package to behave nicely when invoked
- recursively inside a find-module for the same package. The
- module will never be recursively loaded again. Version arguments
- are automatically forwarded.
-
-2008-10-03 10:39 king
-
- * Source/cmFindPackageCommand.cxx: ENH: Warn and ignore EXACT
- without version
-
- If the find_package command is invoked with the EXACT option but
- without a version, warn and ignore the option.
-
-2008-10-03 10:11 king
-
- * Source/: cmInstallTargetGenerator.cxx,
- cmInstallTargetGenerator.h: BUG: Fix config test for target
- install rules
-
- In single-configuration generators a target installation rule
- should apply to all configurations for which the INSTALL command
- was specified. The configuration in which the target is built
- does not matter.
-
- In multi-configuration generators each installation rule must be
- associated with a particular build configuration to install the
- proper file. The set of configurations for which rules are
- generated is the intersection of the build configurations and
- those for which the INSTALL command was specified.
-
-2008-10-03 08:16 hoffman
-
- * Source/cmFindCommon.cxx: ENH: undo bad checkin
-
-2008-10-02 23:55 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-02 18:48 alex
-
- * Source/cmTarget.cxx: STYLE: add documentation for the "TYPE"
- target property
-
- Alex
-
-2008-10-02 13:49 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: BUG: 7763 fix, OPTIMIZATION
- was not set right. Also fix for BUG 7764, put XCODE_ATTRIBUTES_
- last
-
-2008-10-02 12:11 hoffman
-
- * Modules/Platform/Windows-gcc.cmake: BUG: fix for 5705, link in
- standard libs for mingw
-
-2008-10-02 09:18 hoffman
-
- * Source/: cmFindCommon.cxx, CPack/cmCPackBundleGenerator.cxx,
- CPack/cmCPackGenerator.cxx, CTest/cmProcess.cxx: STYLE: fix line
- length issues
-
-2008-10-01 23:56 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-10-01 16:16 hoffman
-
- * Source/cmake.cxx: BUG: fix for 6280, -E time was not sending back
- return value
-
-2008-10-01 16:10 hoffman
-
- * Modules/FindPerlLibs.cmake: ENH: find perl with FindPerl not
- find_program, bug: 6243
-
-2008-10-01 14:19 hoffman
-
- * Modules/FindTclStub.cmake: BUG: fix for 7451
-
-2008-10-01 13:24 hoffman
-
- * Modules/: CMakeCInformation.cmake, Platform/Linux.cmake: BUG: fix
- for bug 4772, enable_language should now work on linux with
- correct flags
-
-2008-10-01 13:13 hoffman
-
- * Utilities/Release/: ferrari_sgi64_release.cmake,
- ferrari_sgi_release.cmake: ENH: add new sgi release scripts
-
-2008-10-01 12:46 hoffman
-
- * Source/CTest/cmCTestUpdateHandler.cxx: BUG: undo fix for 7292
- because a switched file should show up as an odd thing on the
- dashbaord
-
-2008-10-01 12:45 hoffman
-
- * Source/cmGlobalGenerator.cxx: STYLE: fix hidden variable warning
-
-2008-10-01 09:50 hoffman
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h: BUG: fix for
- 7738, allow for spaces in the package target path to CPackConfig
- files
-
-2008-10-01 09:04 hoffman
-
- * Source/: cmCTest.cxx, cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx, cmIfCommand.cxx,
- cmInstallCommand.cxx, cmLocalVisualStudio7Generator.cxx,
- cmMakefile.cxx, cmake.cxx, CPack/cmCPackBundleGenerator.cxx,
- CPack/cmCPackGenerator.cxx, CPack/cmCPackGenerator.h,
- CPack/cmCPackNSISGenerator.cxx, CPack/cmCPackNSISGenerator.h,
- CPack/cmCPackPackageMakerGenerator.cxx,
- CTest/cmCTestTestHandler.cxx: STYLE: fix line length stuff for
- KWStyle
-
-2008-09-30 23:56 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-29 23:56 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-29 16:09 hoffman
-
- * Utilities/cm_curl.h: ENH: fix syntax error
-
-2008-09-29 15:47 hoffman
-
- * CMakeLists.txt, Utilities/cmThirdParty.h.in, Utilities/cm_curl.h:
- ENH: check in ability to build with new curl -f
- -DCMAKE_USE_NEW_CURL is set
-
-2008-09-28 23:56 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-27 23:56 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-27 08:04 king
-
- * Source/kwsys/SharedForward.h.in: COMP: Avoid incompatible pointer
- warning
-
- In SharedForward, the call to execvp warned on MinGW because the
- signature declared in process.h has an extra const. We use an
- explicit cast to convert the pointer type.
-
-2008-09-26 23:56 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-26 20:09 hoffman
-
- * Modules/FindGLUT.cmake: BUG: fix for 7746
-
-2008-09-26 12:08 barre
-
- * Source/kwsys/SharedForward.h.in: ENH: fix bug where sharedforward
- would not work if there was a space in the path (it would but
- would interpret the space as the separation between two
- arguments, and would therefore pass an extra arg that would throw
- some apps off). Thanks to Brad King.
-
-2008-09-26 08:24 king
-
- * Source/kwsys/: CMakeLists.txt, testSharedForward.c.in: ENH: Add
- test for KWSys SharedForward
-
- This tests the basic capability of running another executable
- from the build tree.
-
-2008-09-26 08:24 king
-
- * Source/kwsys/SharedForward.h.in: BUG: Fix SharedForward with
- spaces on windows
-
- The windows execvp function does not re-escape arguments
- correctly. Instead we generate the escape sequences before
- calling it.
-
-2008-09-26 08:24 king
-
- * Source/kwsys/SharedForward.h.in: BUG: Fix SharedForward in-tree
- detection
-
- To detect when the launcher is running from the build tree we now
- test if the directory containing it is the same as the build-tree
- directory using an inode test instead of string comparison. This
- makes it more robust on case-insensitive filesystems and other
- quirky situations.
-
-2008-09-26 08:24 king
-
- * Source/kwsys/SharedForward.h.in: COMP: Avoid 64-to-32-bit integer
- conversion warning
-
- In SharedForward we are only dealing with command-line-length
- strings so we need not worry about integer overflow.
-
-2008-09-25 23:56 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-25 17:02 hoffman
-
- * Modules/Platform/Windows-gcc.cmake: BUG: fix for 7704
-
-2008-09-25 16:52 hoffman
-
- * Source/cmakemain.cxx: BUG: fix for bug 7733, document that debug
- try compile may break the build
-
-2008-09-25 10:21 hoffman
-
- * Tests/Unset/CMakeLists.txt: file CMakeLists.txt was added on
- branch CMake-2-6 on 2009-02-04 16:44:19 +0000
-
-2008-09-25 10:21 king
-
- * Source/cmCommandArgumentParserHelper.cxx,
- Tests/Unset/CMakeLists.txt: ENH: Create $CACHE{VAR} syntax
-
- This syntax allows reading of cache entries even when variables
- of the same name have been defined in the local scope. See issue
- #7715.
-
-2008-09-24 23:56 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-24 13:53 hoffman
-
- * Utilities/Release/README: ENH: add comment about fixing RC
-
-2008-09-24 13:52 hoffman
-
- * CMakeLists.txt: ENH: remove RC 2.6.2 is ready
-
-2008-09-24 10:07 hoffman
-
- * Source/CPack/: cmCPackGenerator.cxx, cmCPackGenerator.h,
- cpack.cxx: STYLE: remove warning from branch
-
-2008-09-24 10:01 hoffman
-
- * Source/CPack/cpack.cxx: ENH: missed one
-
-2008-09-24 09:57 hoffman
-
- * Source/CPack/: cmCPackGenerator.cxx, cmCPackGenerator.h: STYLE:
- fix compiler warning
-
-2008-09-24 08:51 king
-
- * Source/: cmCommand.h, cmMakefile.cxx, cmMakefile.h: BUG: Skip a
- command if its arguments fail to parse
-
- If the arguments to a command fail to parse correctly due to a
- syntax error, the command should not be invoked. This avoids
- problems created by processing of commands with bad arguments.
- Even though the build system will not be generated, the command
- may affect files on disk that persist across CMake runs.
-
-2008-09-24 08:51 king
-
- * Source/cmMacroCommand.cxx: ENH: Improve context for errors in
- macros
-
- We now properly report the source location of command arguments
- inside macros instead of using the macro invocation site. No
- information is lost because full call-stack information is
- already reported.
-
-2008-09-24 08:51 king
-
- * Source/: cmCommandArgumentParserHelper.cxx,
- cmCommandArgumentParserHelper.h, cmMakefile.cxx, cmPolicies.cxx,
- cmPolicies.h: ENH: Improve argument parsing error messages
-
- Previously error messages produced by parsing of command argument
- variable references, such as bad $KEY{VAR} syntax or a bad escape
- sequence, did not provide good context information. Errors
- parsing arguments inside macro invocations gave no context at
- all. Furthermore, some errors such as a missing close curly
- "${VAR" would be reported but build files would still be
- generated.
-
- These changes teach CMake to report errors with good context
- information for all command argument parsing problems. Policy
- CMP0010 is introduced so that existing projects that built
- despite such errors will continue to work.
-
-2008-09-23 23:56 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-23 13:34 king
-
- * Source/cmFindLibraryCommand.cxx: BUG: Fix lib/ to lib/64/ search
- path conversion
-
- Automatic generation of 64-bit library search paths must preserve
- trailing slashes. This fixes a failure case exposed by the
- recent rewrite of find_library, which assumes trailing slashes
- occur on all search paths.
-
-2008-09-23 12:04 hoffman
-
- * Source/kwsys/testDynamicLoader.cxx: ENH: one more fix for HAIKU
-
-2008-09-23 11:32 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Source/CPack/cmCPackGenerator.cxx,
- Source/CPack/cmCPackGenerator.h: ENH: merge in changes for RC 6,
- fix cpack working from symlink is the only change
-
-2008-09-23 10:15 hoffman
-
- * Source/CPack/: cmCPackGenerator.cxx, cmCPackGenerator.h: STYLE:
- fix warning and rename method
-
-2008-09-22 23:56 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-22 18:12 hoffman
-
- * Source/CPack/cmCPackGenerator.cxx: BUG: fix 7669, cpack did not
- work with symlinks
-
-2008-09-22 15:00 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Fix #7433. Put list of files in a .pro file and call
- lupdate on it, instead of putting the list of
- files on the command line.
-
-2008-09-22 14:05 hoffman
-
- * Source/kwsys/: DynamicLoader.hxx.in, ProcessUNIX.c,
- testProcess.c: ENH: a few more haiku fixes, stop the debugger
- from coming up for tests
-
-2008-09-22 14:04 hoffman
-
- * Source/: cmCTest.cxx, cmCTest.h, ctest.cxx,
- CTest/cmCTestTestHandler.cxx: ENH: add max width option to ctest
- ouptut
-
-2008-09-22 14:00 clinton
-
- * Modules/FindQt4.cmake:
- BUG: remove debug statements.
-
-2008-09-22 11:08 king
-
- * Modules/Platform/OpenBSD.cmake, Source/cmFindLibraryCommand.cxx,
- Source/cmake.cxx: ENH: Teach find_library to find OpenBSD-style
- libs
-
- OpenBSD shared libraries use a ".so.<major>.<minor>" extension
- and do not have a symlink with just a ".so" extension. Its "ld"
- is capable of finding the library with the best version. This
- change adds support for finding such libraries. See issue #3470.
-
-2008-09-22 10:59 king
-
- * Source/cmFindLibraryCommand.cxx: ENH: Refactor find_library
- search logic
-
- Previously we searched for library files by enumerating every
- possible combination of prefix and suffix. Now we load (and
- cache) directory content from disk and search for matching file
- names. This should reduce disk access. It will also allow more
- advanced matching rules in the future. See issue #3470.
-
-2008-09-22 10:56 king
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h: ENH: Make
- dir content cache work during configure
-
- Previously the cmGlobalGenerator::GetDirectoryContent method
- would work safely only during build system generation. These
- changes make it safe to use during each configure step by
- flushing it at the beginning.
-
-2008-09-22 10:05 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/BundleUtilities.cmake,
- Modules/CPackRPM.cmake, Modules/FindBoost.cmake,
- Modules/FindCurses.cmake, Modules/FindQt4.cmake,
- Modules/GetPrerequisites.cmake: ENH: merge in changes for RC 5
-
-2008-09-22 09:56 hoffman
-
- * Modules/CPackRPM.cmake: BUG: 7435, remove warning for not setting
- DESTDIR
-
-2008-09-22 09:42 king
-
- * Source/cmSourceFile.cxx: ENH: Improve docs of OBJECT_DEPENDS
- property
-
- Specify exactly what the value of the property should contain and
- the resulting behavior. Note alternatives for a common out-dated
- usage.
-
-2008-09-21 23:56 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-20 23:57 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-19 23:57 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-19 17:45 hoffman
-
- * Modules/CPackRPM.cmake: BUG: 7435 fixes to add optional
- post-install
-
-2008-09-18 23:57 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-18 15:23 hoffman
-
- * Modules/FindCurses.cmake: ENH: try to make this work if ncurses
- lib is found bug not the ncurses header
-
-2008-09-18 10:56 clinton
-
- * Modules/FindQt4.cmake:
- ENH: For #7433, add a bit more documentation and add ability
- to specify extra flags to lupdate.
-
-2008-09-17 23:57 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-17 14:29 hoffman
-
- * Modules/FindCoin3D.cmake: file FindCoin3D.cmake was added on
- branch CMake-2-6 on 2008-10-24 15:20:35 +0000
-
-2008-09-17 14:29 mleotta
-
- * Modules/FindCoin3D.cmake: ENH: added a module to find Coin3D
-
-2008-09-16 23:57 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-16 17:40 barre
-
- * Utilities/cmtar/util.c: ENH: wow. On some Windows machine, trying
- to mkdir("C:") would fail miserably. WHy not in debug mode? Why
- not on other win32 machines. Who knows.
-
-2008-09-16 10:30 king
-
- * Modules/FindBoost.cmake: BUG: Fix FindBoost versioned find
-
- To locate the boost include directory, all search paths and
- versioned path suffixes should be passed to one call of
- FIND_PATH. Previously the test for one version would find an
- unversioned system boost even when the user set BOOST_ROOT (since
- the NO_DEFAULT_PATH option is not used). See issue #7456.
-
-2008-09-15 23:57 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-15 18:23 hoffman
-
- * Utilities/cmcurl/select.c: ENH: missed this one, cmake now
- bootstraps on HAIKU
-
-2008-09-15 17:53 hoffman
-
- * bootstrap, Modules/CMakeFortranCompilerId.F90.in,
- Modules/CMakePlatformId.h.in, Modules/CheckForPthreads.c,
- Modules/Platform/Haiku.cmake, Source/cmCTest.cxx,
- Source/cmDependsJavaLexer.cxx, Source/cmDependsJavaLexer.h,
- Source/cmSystemTools.cxx, Source/CTest/cmCTestTestHandler.cxx,
- Source/kwsys/DynamicLoader.cxx, Source/kwsys/ProcessUNIX.c,
- Source/kwsys/SystemTools.cxx, Source/kwsys/testDynamicLoader.cxx,
- Source/kwsys/testProcess.c, Utilities/cmcurl/CMakeLists.txt,
- Utilities/cmcurl/CMake/CurlTests.c, Utilities/cmcurl/curl/curl.h,
- Utilities/cmzlib/zconf.h, Utilities/cmzlib/zutil.h: ENH: add
- initial support for HAIKU OS from bug# 7425
-
-2008-09-15 17:53 hoffman
-
- * Modules/Platform/Haiku.cmake: file Haiku.cmake was added on
- branch CMake-2-6 on 2008-10-24 15:20:35 +0000
-
-2008-09-15 13:46 king
-
- * Source/cmGlobalGenerator.cxx: ENH: Simplify NOTFOUND variable
- check
-
- When looking for NOTFOUND libraries, use the direct dependencies
- of a target instead of all dependencies. At least one target
- will trigger the NOTFOUND error anyway because at least one must
- directly link it. This removes another use of the old-style link
- line computation.
-
-2008-09-15 13:30 king
-
- * Source/cmMakefileTargetGenerator.cxx: ENH: Use new link info
- during dependency scanning
-
- This removes another use of the old-style link line computation.
-
-2008-09-15 13:30 king
-
- * Source/cmTarget.cxx: ENH: Allow link line computation for static
- libs
-
- In some cases it may be useful to compute a "link" line for a
- static library even though it will not be put in the generated
- build system. This removes the assertion which previously
- diallowed the case.
-
-2008-09-15 13:30 king
-
- * Source/: cmComputeLinkInformation.cxx,
- cmComputeLinkInformation.h: ENH: Keep target information in final
- link line
-
- In cmComputeLinkInformation items in the final link line returned
- by GetItems now contain a pointer to their corresponding cmTarget
- if they were produced by a target. This makes available the set
- of all targets linked.
-
-2008-09-15 09:51 king
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: Use improved target
- dependencies for Xcode
-
- In cmGlobalGenerator we use cmComputeTargetDepends to construct a
- safe, non-circular set of inter-target dependencies. This change
- enables use of the results by the Xcode generator. It also
- removes a lot of old code and another use of the old-style
- linking logic. See issue #7652.
-
-2008-09-14 23:57 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-13 23:57 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-12 23:57 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-12 13:29 hoffman
-
- * Tests/CMakeTests/ToolchainTest.cmake.in: ENH: merge in from main
- tree
-
-2008-09-12 10:56 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Modules/CheckCCompilerFlag.cmake, Modules/FindThreads.cmake,
- Modules/readme.txt, Source/cmFileCommand.cxx,
- Source/cmFileCommand.h, Source/cmFindPackageCommand.cxx,
- Source/cmFindPackageCommand.h, Source/cmGlobalXCodeGenerator.cxx,
- Source/cmIfCommand.cxx, Source/cmIfCommand.h,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx, Source/cmPolicies.cxx,
- Source/cmPolicies.h, Source/CPack/cmCPackDebGenerator.cxx,
- Source/kwsys/Glob.cxx, Source/kwsys/Glob.hxx.in,
- Templates/DLLHeader.dsptemplate, Templates/EXEHeader.dsptemplate,
- Templates/EXEWinHeader.dsptemplate,
- Tests/FindPackageTest/CMakeLists.txt,
- Tests/FindPackageTest/FindVersionTestA.cmake,
- Tests/FindPackageTest/FindVersionTestB.cmake,
- Tests/FindPackageTest/FindVersionTestC.cmake,
- Tests/FindPackageTest/FindVersionTestD.cmake,
- Tests/Framework/CMakeLists.txt,
- Tests/Framework/fooExtensionlessResource,
- Tests/Framework/fooPrivateExtensionlessHeader,
- Tests/Framework/fooPublicExtensionlessHeader: ENH: 2.6.2 RC 4
- merge into main tree
-
-2008-09-11 23:57 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-11 14:50 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: BUG: make sure flag is found
- even with extra spaces at the start
-
-2008-09-11 14:34 david.cole
-
- * Source/: cmFileCommand.cxx, cmFileCommand.h, cmPolicies.cxx,
- cmPolicies.h, kwsys/Glob.cxx, kwsys/Glob.hxx.in: ENH: Improve
- FILE GLOB_RECURSE handling of symlinks with a new CMake policy.
- CMP0009 establishes NEW default behavior of not recursing through
- symlinks. OLD default behavior or explicit FOLLOW_SYMLINKS
- argument to FILE GLOB_RECURSE will still recurse through
- symlinks.
-
-2008-09-11 11:41 hoffman
-
- * Modules/FindThreads.cmake: BUG: fix for 6586, set THREADS_FOUND
-
-2008-09-11 10:48 hoffman
-
- * Source/CPack/cmCPackDebGenerator.cxx: ENH: add installed size to
- deb package
-
-2008-09-10 23:58 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-10 11:58 king
-
- * Source/cmIfCommand.cxx, Source/cmIfCommand.h,
- Tests/FindPackageTest/CMakeLists.txt: ENH: Add version comparison
- to if() command
-
- Provide VERSION_LESS, VERSION_EQUAL, and VERSION_GREATER
- operators in the if() command. This simplifies component-wise
- comparison of version numbers in the form
- "major[.minor[.patch[.tweak]]]".
-
-2008-09-10 10:36 hoffman
-
- * Templates/DLLHeader.dsptemplate: ENH: fix failing tests
-
-2008-09-10 10:11 hoffman
-
- * Tests/FindPackageTest/FindVersionTestD.cmake: file
- FindVersionTestD.cmake was added on branch CMake-2-6 on
- 2008-09-12 14:56:21 +0000
-
-2008-09-10 10:11 king
-
- * Modules/readme.txt, Source/cmFindPackageCommand.cxx,
- Source/cmFindPackageCommand.h,
- Tests/FindPackageTest/CMakeLists.txt,
- Tests/FindPackageTest/FindVersionTestA.cmake,
- Tests/FindPackageTest/FindVersionTestB.cmake,
- Tests/FindPackageTest/FindVersionTestC.cmake,
- Tests/FindPackageTest/FindVersionTestD.cmake: ENH: Improve
- find_package version numbering
-
- Make the number of version components specified explicitly
- available. Set variables for unspecified version components to
- "0" instead of leaving them unset. This simplifies version
- number handling for find- and config-modules. Also support a
- fourth "tweak" version component since some packages use them.
-
-2008-09-10 10:10 hoffman
-
- * Templates/: DLLHeader.dsptemplate, EXEWinHeader.dsptemplate: BUG:
- fix bug OUTPUT_LIBNAME_EXPORTS done differently now
-
-2008-09-09 23:58 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-09 14:12 hoffman
-
- * Modules/CheckCCompilerFlag.cmake: ENH: fix docs, bug 7590
-
-2008-09-09 13:12 hoffman
-
- * Source/CTest/cmCTestUpdateHandler.cxx: BUG: fix for bug 7292, svn
- parsing flagged errors or conflicts for switched or locked files
-
-2008-09-09 13:04 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx,
- Templates/EXEHeader.dsptemplate: BUG: fix empty /D option for
- vs6, fix for 7580
-
-2008-09-09 13:01 hoffman
-
- * CTestConfig.cmake: ENH: support old cmake for dashboards
-
-2008-09-09 12:48 david.cole
-
- * Tests/CMakeTests/GetPrerequisitesTest.cmake.in: PERF: Test takes
- too long when recursing for executable files and when doing
- recursive prerequisite analysis. Put it back the way it was. Add
- another test later to do the recursive prerequisite analysis.
-
-2008-09-09 11:44 hoffman
-
- * Source/CTest/: cmCTestTestCommand.cxx, cmCTestTestCommand.h: BUG:
- 0007569 add ability to do -R/-E in ctest_test command
-
-2008-09-08 23:58 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-08 20:21 hoffman
-
- * Tests/CMakeTests/ToolchainTest.cmake.in: BUG: fix test to work
- with new restrictions that cross compiling must be on
-
-2008-09-08 17:53 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: fix for 7624, vs7
- flag table missing /MAP
-
-2008-09-08 17:43 alex
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeDetermineCXXCompiler.cmake: BUG: only check for a toolchain
- prefix (e.g. "arm-linux-" in "arm-linux-gcc") if we are cross
- compiling and the compiler is gcc
-
- Alex
-
-2008-09-08 11:23 hoffman
-
- * Modules/GetPrerequisites.cmake: ENH: do not add the same thing to
- the PATH again and again
-
-2008-09-08 10:08 king
-
- * Source/cmFindPackageCommand.cxx: ENH: Improve message for bad
- find_package call
-
- Use the new-style error reporting mechanism to provide more
- context information for a find_package call with a bad package
- name. When the package is not required, issue a warning instead
- of an error.
-
-2008-09-07 23:58 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-07 16:54 alex
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeDetermineCXXCompiler.cmake: BUG: #7359 make llvm-gcc work,
- by explicitely excluding "llvm-" from _CMAKE_TOOLCHAIN_PREFIX
- (use the (relatively) new CMAKE_MATCH_x variables set by all
- regex operations)
-
- Alex
-
-2008-09-07 06:52 alex
-
- * Source/: cmFindPackageCommand.cxx, cmFindPackageCommand.h: COMP:
- fix compile warning/error (non-void function returning void)
-
- Alex
-
-2008-09-06 23:58 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-06 19:10 alex
-
- * Source/: cmFindPackageCommand.cxx, cmFindPackageCommand.h: ENH:
- provide the xxx_FIND_QUIETLY, xxx_FIND_REQUIRED and
- xxx_FIND_VERSION_ variables also in Config mode, so the
- xxxConfig.cmake files can e.g. test the QUIETLY parameter and
- print something or not
-
- Alex
-
-2008-09-06 12:20 hoffman
-
- * Modules/BundleUtilities.cmake: file BundleUtilities.cmake was
- added on branch CMake-2-6 on 2008-09-22 14:05:16 +0000
-
-2008-09-06 12:20 david.cole
-
- * Modules/BundleUtilities.cmake, Modules/GetPrerequisites.cmake,
- Tests/CMakeTests/GetPrerequisitesTest.cmake.in: ENH: Add
- BundleUtilities.cmake and supporting changes to
- GetPrerequisites.cmake. Function copy_and_fixup_bundle in
- BundleUtilities helps to make standalone bundle applications on
- the Mac by pulling in prerequisite non-system libraries and
- frameworks as needed. Uses otool and install_name_tool to do
- analysis and fixups. Project-specific hooks for deciding where to
- embed libraries and for resolving item names into full path file
- names are also provided.
-
-2008-09-05 23:58 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-05 15:51 hoffman
-
- * Tests/Framework/fooExtensionlessResource: file
- fooExtensionlessResource was added on branch CMake-2-6 on
- 2008-09-12 14:56:21 +0000
-
-2008-09-05 15:51 hoffman
-
- * Tests/Framework/fooPrivateExtensionlessHeader: file
- fooPrivateExtensionlessHeader was added on branch CMake-2-6 on
- 2008-09-12 14:56:21 +0000
-
-2008-09-05 15:51 hoffman
-
- * Tests/Framework/fooPublicExtensionlessHeader: file
- fooPublicExtensionlessHeader was added on branch CMake-2-6 on
- 2008-09-12 14:56:21 +0000
-
-2008-09-05 15:51 david.cole
-
- * Source/cmGlobalXCodeGenerator.cxx,
- Tests/Framework/CMakeLists.txt,
- Tests/Framework/fooExtensionlessResource,
- Tests/Framework/fooPrivateExtensionlessHeader,
- Tests/Framework/fooPublicExtensionlessHeader: BUG: Fix issue
- #7046 - make sure extensionless headers and resource files work
- with the Xcode generator. Also fix incorrect mappings in the
- lastKnownFileType code. Add some extensionless files to the
- Framework test.
-
-2008-09-04 23:58 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-04 17:34 king
-
- * Source/cmComputeLinkDepends.cxx, Source/cmComputeLinkDepends.h,
- Source/cmExportFileGenerator.cxx, Source/cmTarget.cxx,
- Source/cmTarget.h, Source/cmTargetLinkLibrariesCommand.cxx,
- Source/cmTargetLinkLibrariesCommand.h, Source/cmake.cxx,
- Source/cmake.h, Tests/ExportImport/Export/CMakeLists.txt,
- Tests/ExportImport/Import/CMakeLists.txt: ENH: Allow a custom
- list of debug configurations
-
- Create a DEBUG_CONFIGURATIONS global property as a way for
- projects to specify which configuration names are considered to
- be 'debug' configurations.
-
-2008-09-04 17:10 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Source/cmGetPropertyCommand.h,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmWin32ProcessExecution.cxx, Source/cmake.cxx,
- Source/CTest/cmCTestBuildAndTestHandler.cxx: ENH: 2.6.2 RC 3,
- merge in changes from main tree
-
-2008-09-04 17:02 hoffman
-
- * Source/cmWin32ProcessExecution.cxx: BUG: fix extra close that
- killed cmake when being debugged
-
-2008-09-04 13:15 king
-
- * Source/cmGetPropertyCommand.h: BUG: Fix typo in get_property
- documentation
-
- Add some missing whitespace to fix formatting of the
- documentation.
-
-2008-09-04 13:15 king
-
- * Source/cmake.cxx: BUG: Fix unsetting of global properties
-
- The set_property command unsets a property if it is given no
- value. In the case of GLOBAL properties, the cmake::SetProperty
- method would replace a NULL value with "NOTFOUND". Instead it
- should be left as NULL so that the property is unset as expected.
- Once it is unset the get_cmake_property command will still
- report NOTFOUND while the get_property command will return the
- empty string as documented.
-
-2008-09-04 11:31 king
-
- * Source/CTest/cmCTestBuildAndTestHandler.cxx: BUG: Make CTest
- honor user-specified config
-
- When the -C or --build-config option is used to specify the
- configuration to be tested by CTest, do not override it with the
- configuration in which CTest is built.
-
-2008-09-03 23:58 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-03 16:22 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: fix for 7519 extra
- closing > in fortran projects
-
-2008-09-03 09:43 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Docs/cmake-syntax.vim,
- Modules/CMakeCCompilerABI.c, Modules/CMakeCCompilerId.c.in,
- Modules/CMakeCXXCompilerABI.cpp,
- Modules/CMakeCXXCompilerId.cpp.in, Modules/CheckTypeSizeC.c.in,
- Modules/FindKDE3.cmake, Modules/FindKDE4.cmake,
- Modules/FindLibXml2.cmake, Modules/FindLua50.cmake,
- Modules/FindLua51.cmake, Modules/FindOpenGL.cmake,
- Modules/FindPHP4.cmake, Modules/FindPNG.cmake,
- Modules/FindQt3.cmake, Modules/FindQt4.cmake,
- Modules/FindTIFF.cmake, Modules/FindX11.cmake,
- Modules/MacOSXFrameworkInfo.plist.in, Modules/NSIS.template.in,
- Modules/TestEndianess.c.in, Modules/UsePkgConfig.cmake,
- Modules/Platform/Darwin.cmake,
- Modules/Platform/Windows-icl.cmake,
- Source/cmAddLibraryCommand.cxx, Source/cmAddLibraryCommand.h,
- Source/cmAddSubDirectoryCommand.h,
- Source/cmCMakePolicyCommand.cxx, Source/cmCMakePolicyCommand.h,
- Source/cmCacheManager.cxx, Source/cmComputeLinkDepends.cxx,
- Source/cmComputeLinkDepends.h,
- Source/cmComputeLinkInformation.cxx,
- Source/cmComputeTargetDepends.cxx,
- Source/cmComputeTargetDepends.h, Source/cmDocumentVariables.cxx,
- Source/cmDocumentation.cxx, Source/cmDocumentation.h,
- Source/cmExtraCodeBlocksGenerator.cxx, Source/cmFileCommand.cxx,
- Source/cmFileCommand.h, Source/cmFindPackageCommand.cxx,
- Source/cmFindPackageCommand.h, Source/cmGlobalGenerator.cxx,
- Source/cmGlobalKdevelopGenerator.cxx,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalXCodeGenerator.cxx, Source/cmIfCommand.cxx,
- Source/cmIfCommand.h, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h, Source/cmMakefile.cxx,
- Source/cmMakefile.h,
- Source/cmMakefileExecutableTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.h, Source/cmPolicies.cxx,
- Source/cmPolicies.h, Source/cmReturnCommand.h,
- Source/cmSetPropertyCommand.cxx,
- Source/cmSetTargetPropertiesCommand.cxx,
- Source/cmStringCommand.cxx, Source/cmSystemTools.cxx,
- Source/cmSystemTools.h, Source/cmTarget.cxx, Source/cmTarget.h,
- Source/cmTargetLinkLibrariesCommand.cxx,
- Source/cmTargetLinkLibrariesCommand.h, Source/cmXCodeObject.cxx,
- Source/cmXCodeObject.h, Source/cmake.cxx, Source/cmakemain.cxx,
- Source/CTest/cmCTestCoverageHandler.cxx,
- Source/CursesDialog/cmCursesStringWidget.cxx,
- Source/kwsys/Glob.cxx, Source/kwsys/Glob.hxx.in,
- Source/kwsys/ProcessUNIX.c, Tests/BundleTest/BundleLib.cxx,
- Tests/BundleTest/BundleTest.cxx, Tests/BundleTest/CMakeLists.txt,
- Tests/BundleTest/BundleSubDir/CMakeLists.txt,
- Tests/Complex/CMakeLists.txt,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexRelativePaths/CMakeLists.txt,
- Tests/Complex/Executable/CMakeLists.txt,
- Tests/Complex/Library/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Library/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Library/CMakeLists.txt,
- Tests/CustomCommand/CMakeLists.txt,
- Tests/Dependency/CMakeLists.txt,
- Tests/Dependency/Case4/CMakeLists.txt,
- Tests/Dependency/Case4/bar.c, Tests/Dependency/Case4/foo.c,
- Tests/ExportImport/Export/CMakeLists.txt,
- Tests/ExportImport/Export/testLib4lib.c,
- Tests/ExportImport/Export/testLib4libdbg.c,
- Tests/ExportImport/Export/testLib4libdbg1.c,
- Tests/ExportImport/Export/testLib4libopt.c,
- Tests/ExportImport/Export/testLib4libopt1.c,
- Tests/ExportImport/Import/CMakeLists.txt,
- Tests/ExportImport/Import/imp_testExe1.c,
- Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt,
- Tests/ReturnTest/CMakeLists.txt,
- Tests/ReturnTest/include_return.cmake,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: 2.6.2 rc 2 merge from
- main tree
-
-2008-09-02 23:58 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-09-02 14:47 hoffman
-
- * Modules/Platform/Windows-icl.cmake: BUG: make sure the intel
- compiler uses the intel linker
-
-2008-09-02 14:46 hoffman
-
- * Modules/NSIS.template.in: BUG: remove Catalan as 2.29 does not
- have it
-
-2008-09-02 12:43 david.cole
-
- * Source/cmMakefileExecutableTargetGenerator.cxx: BUG: Fix issue
- #3648 - make sure CMake reruns if a Bundle application's
- directory is removed or if it's Info.plist file disappears since
- those elements are put in place at CMake configure time.
-
-2008-09-02 12:06 hoffman
-
- * Modules/MacOSXFrameworkInfo.plist.in: file
- MacOSXFrameworkInfo.plist.in was added on branch CMake-2-6 on
- 2008-09-03 13:43:16 +0000
-
-2008-09-02 12:06 king
-
- * Modules/MacOSXFrameworkInfo.plist.in,
- Source/cmGlobalXCodeGenerator.cxx, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.h, Source/cmTarget.cxx:
- ENH: Create Info.plist files in OS X Frameworks
-
- A Mac OS X Framework should provide a Resources/Info.plist file
- containing meta-data about the framework. This change generates
- a default Info.plist for frameworks and provides an interface for
- users to customize it.
-
-2008-09-02 11:06 david.cole
-
- * Tests/BundleTest/: BundleLib.cxx, BundleTest.cxx, CMakeLists.txt:
- ENH: Add indirect dependency to Carbon and call a Carbon function
- from executable. This will allow detecting broken dependency
- chaining for '-framework blah' style lib dependencies.
-
-2008-09-02 10:27 king
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmXCodeObject.cxx,
- cmXCodeObject.h: ENH: Simplify string attributes in Xcode
- generator
-
- This change cleans up the implementation of cmXCodeObject to
- avoid un-escaping and re-escaping string values. There is no
- need to store the string in escaped form. It can be escaped once
- when it is printed out to the generated project file.
-
-2008-09-01 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-31 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-30 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-30 10:32 hoffman
-
- * Tests/Unset/unset.c: file unset.c was added on branch CMake-2-6
- on 2009-02-04 16:44:19 +0000
-
-2008-08-30 10:32 king
-
- * Tests/Unset/: CMakeLists.txt, unset.c, unset.cc: BUG: Fix Unset
- test on VS 6
-
- Visual Studio 6 does not recognize .cc as a C++ extension by
- default. Simplify the test to be C-only and use a .c extension.
-
-2008-08-30 09:39 clinton
-
- * Modules/FindQt4.cmake:
- ENH: For #7433, add documentation that directories also can be
- specified to update the translation files.
-
-2008-08-29 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-29 13:22 king
-
- * Source/cmComputeLinkDepends.cxx: BUG: Link flags should still be
- chained
-
- The recent fix to avoid including flags in dependency inferral
- also dropped them from chaining of dependencies through targets.
- This fix restores chaining of flags through known dependency
- lists while still leaving them out of inferred dependency lists.
-
-2008-08-28 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-28 22:25 king
-
- * Source/cmComputeLinkDepends.cxx: BUG: A -framework Foo is also a
- lib
-
-2008-08-28 22:12 king
-
- * Source/cmComputeLinkDepends.cxx: BUG: Fix previous fix.
-
-2008-08-28 22:07 king
-
- * Source/cmComputeLinkDepends.cxx: BUG: When recognizing flags on
- link lines, we must still treat -l as a library.
-
-2008-08-27 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-27 12:53 david.cole
-
- * Tests/BundleTest/: CMakeLists.txt, BundleSubDir/CMakeLists.txt:
- ENH: Changes that allow configuring/building BundleTest test
- separately from the main CMake build. (Eliminate reference to
- CMake_SOURE_DIR.)
-
-2008-08-27 10:35 king
-
- * Source/cmComputeLinkDepends.h: COMP: Do not use private typedef
- from outside class.
-
-2008-08-27 10:21 king
-
- * Source/: cmComputeLinkDepends.cxx, cmComputeLinkDepends.h: ENH:
- New link line item ordering algorithm
-
- This change introduces a new algorithm for link line
- construction. The order it computes always begins with the exact
- link line specified by the user. Dependencies of items specified
- by the user are tracked, and those that are not already
- satisified by the line are appended to it at the end with minimal
- repeats. This restores the behavior of CMake 2.4 and below while
- still fixing some of its bugs. See issue #7546.
-
-2008-08-27 10:21 king
-
- * Source/: cmComputeLinkDepends.cxx, cmComputeLinkDepends.h: BUG:
- Do not infer dependencies of link flags
-
- In cmComputeLinkDepends link items that look like flags (starting
- in '-') should not be included in dependency inferral. They are
- not libraries and therefore have no dependencies. They should
- just be passed through to the final link line unchanged. See
- issue #7546.
-
-2008-08-27 10:21 king
-
- * Source/cmComputeLinkDepends.cxx: BUG: Treat empty config name as
- no configuration
-
- In cmComputeLinkDepends we should treat an empty configuration
- name as equivalent to no specific configuration at all.
-
-2008-08-26 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-26 16:43 david.cole
-
- * Modules/NSIS.template.in: BUG: Do not use "Default" as a
- language, remove 2nd occurence of "English", and remove three
- other languages not supported by older versions of NSIS. Tested
- with version 2.18 of NSIS on gaia.kitware.
-
-2008-08-26 16:04 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Add comments about pre-processor defines and moc.
-
-2008-08-26 12:54 david.cole
-
- * Source/cmStringCommand.cxx: BUG: Correct typo in error message.
-
-2008-08-26 11:50 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Use COMPILE_DEFINTIONS instead of DEFINITIONS.
-
-2008-08-26 11:22 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Add -DWIN32 for moc on Windows. Final fix for #7465.
-
-2008-08-25 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-25 19:41 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Add -D preprocessor defines to the moc commands.
- Needed to fix #7465.
-
-2008-08-25 10:31 hoffman
-
- * Source/cmUnsetCommand.cxx: file cmUnsetCommand.cxx was added on
- branch CMake-2-6 on 2009-02-04 16:44:17 +0000
-
-2008-08-25 10:31 hoffman
-
- * Source/cmUnsetCommand.h: file cmUnsetCommand.h was added on
- branch CMake-2-6 on 2009-02-04 16:44:17 +0000
-
-2008-08-25 10:31 king
-
- * Docs/cmake-syntax.vim, Source/cmBootstrapCommands.cxx,
- Source/cmCacheManager.cxx, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmSetCommand.h,
- Source/cmUnsetCommand.cxx, Source/cmUnsetCommand.h,
- Tests/CMakeLists.txt, Tests/Unset/CMakeLists.txt,
- Tests/Unset/unset.cc: ENH: Add unset() command.
-
- This introduces the unset() command to make it easy to unset
- CMake variables, environment variables, and CMake cache
- variables. Previously it was not even possible to unset ENV or
- CACHE variables (as in completely remove them). Changes based on
- patch from Philip Lowman. See issue #7507.
-
-2008-08-24 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-23 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-23 13:47 david.cole
-
- * Source/cmFileCommand.h: BUG: Correct typo in documentation: or ->
- of
-
-2008-08-23 13:33 david.cole
-
- * Source/: cmFileCommand.cxx, cmFileCommand.h: ENH: Add the
- RECURSE_SYMLINKS_OFF flag to the FILE GLOB_RECURSE command.
- Exposes the recently added kwsys capability that prevents
- recursing through symlinks to CMake scripts.
-
-2008-08-22 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-22 06:56 hoffman
-
- * Modules/NSIS.template.in: BUG: remove extension from inserts
-
-2008-08-22 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-21 15:13 hoffman
-
- * Modules/NSIS.template.in: ENH: sort languages and use list from
- NSIS 2.22
-
-2008-08-21 13:55 hoffman
-
- * Modules/NSIS.template.in: BUG: remove some languages that are not
- supported in older versions of NSIS
-
-2008-08-21 09:54 king
-
- * Source/cmDocumentVariables.cxx, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt: ENH: Allow
- custom limit on object file path length
-
- Some native build tools, particularly those for cross compiling,
- may have a limit on the length of the full path to an object file
- name that is lower than the platform otherwise supports. This
- change allows the limit to be set by the project toolchain file
- through the variable CMAKE_OBJECT_PATH_MAX.
-
-2008-08-21 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-20 18:00 hoffman
-
- * Modules/NSIS.template.in: ENH: try to fix error
-
-2008-08-20 13:24 david.cole
-
- * Source/: CTest/cmCTestCoverageHandler.cxx, kwsys/Glob.cxx,
- kwsys/Glob.hxx.in: ENH: Add RecurseThroughSymlinks data member to
- kwsys::Glob. Allows recursive globs to skip symlinks when
- necessary. Default to true for backwards compatible behavior.
- Used from the ctest coverage handler to avoid recursing through
- the '/Applications' directory on the Mac looking for *.da
- files... Should fix the hangs reported recently by Mac CMake
- dashboard submitters.
-
-2008-08-20 11:45 king
-
- * Source/cmIfCommand.cxx, Source/cmIfCommand.h,
- Tests/Complex/Executable/CMakeLists.txt,
- Tests/Complex/Library/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Library/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Library/CMakeLists.txt: ENH: Add
- if(TARGET) command
-
- It is useful to be able to test if a target has been created.
- Often targets are created only inside conditions. Rather than
- storing the result of the condition manually for testing by other
- parts of the project, it is much easier for the other parts to
- just test for the target's existence. This will also be useful
- when find-modules start reporting results with IMPORTED targets
- and projects want to test if a certain target is available.
-
-2008-08-20 09:57 king
-
- * Source/kwsys/ProcessUNIX.c: BUG: Handle case when select() lies
-
- According to "man select" on Linux it is possible that select()
- lies about data being ready on a pipe in some subtle cases. We
- deal with this by switching to non-blocking i/o and checking for
- EAGAIN. See issue #7180.
-
-2008-08-20 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-19 16:40 hoffman
-
- * Source/CursesDialog/cmCursesStringWidget.cxx: BUG: fix for 6462,
- delete key should delete the current char
-
-2008-08-19 15:59 hoffman
-
- * Modules/FindOpenGL.cmake: BUG: fix for bug 7104 look for GL in
- X11R6 dirs
-
-2008-08-19 15:55 hoffman
-
- * Source/cmSystemTools.cxx: BUG: fix for 7045, use gcc for .m
-
-2008-08-19 15:42 hoffman
-
- * Source/: cmDocumentation.cxx, cmDocumentation.h, cmakemain.cxx:
- BUG: fix 6647 arguments after -E should not be parsed by CMake
-
-2008-08-19 15:07 hoffman
-
- * Source/cmGlobalVisualStudio7Generator.cxx: BUG: fix for 6794
- support for LTCG WholeProgramOptimization, which is not available
- in VS 8 and newer.
-
-2008-08-19 14:28 hoffman
-
- * Modules/FindPHP4.cmake: BUG: fix for bug 6775, FindPHP4 did not
- honor required
-
-2008-08-19 14:23 hoffman
-
- * Modules/Platform/Darwin.cmake: BUG: fix for 6710
- CMAKE_OSX_SYSROOT should be a PATH
-
-2008-08-19 14:07 hoffman
-
- * Modules/NSIS.template.in: BUG: fix for 7446 NSIS support for
- other languages
-
-2008-08-19 13:59 hoffman
-
- * Utilities/Release/: create-cmake-release.cmake,
- magrathea_release.cmake, upload_release.cmake,
- v20n17_aix_release.cmake: ENH: check in current build scripts
-
-2008-08-19 13:48 hoffman
-
- * Source/cmGlobalGenerator.cxx: BUG: fix for 7496, do not just
- report configure done when there is an error during configure
-
-2008-08-19 13:31 hoffman
-
- * Source/cmake.cxx: BUG: 7448 fix crash in ccmake when compiler is
- changed
-
-2008-08-19 11:43 king
-
- * Tests/: CMakeLists.txt, test_clean.cmake.in: ENH: Add test_clean
- target to wipe out tests
-
- We frequently need to wipe out all the CMake test build
- directories in order to run tests from scratch. This change adds
- a test_clean custom target to remove all these directories for
- out-of-source builds.
-
-2008-08-19 11:43 king
-
- * Source/: cmSetPropertyCommand.cxx,
- cmSetTargetPropertiesCommand.cxx, cmTarget.cxx, cmTarget.h: ENH:
- Disallow link-type keywords in link interface
-
- The LINK_INTERFACE_LIBRARIES target property may not contain the
- "debug", "optimized", or "general" keywords. These keywords are
- supported only by the target_link_libraries (and link_libraries)
- command and are not a generic library list feature in CMake.
- When a user attempts to add one of these keywords to the property
- value, we now produce an error message that refers users to
- alternative means.
-
-2008-08-19 10:29 king
-
- * Source/cmTarget.cxx: ENH: Clarify link interface documentation
-
- The LINK_INTERFACE_LIBRARIES property does not apply for STATIC
- libraries. The IMPORTED_LINK_INTERFACE_LIBRARIES property does
- apply for STATIC libraries. State both explicitly in the
- documentation. Also, clarify that the per-configuration version
- of these properties completely overrids the generic version.
-
-2008-08-19 10:28 king
-
- * Source/cmMakefile.cxx: BUG: Linking to modules is for 2.2 compat
- only
-
- The compatibility check to allow linking to modules should test
- for CMake 2.2, not the unreleased 2.3. See issue #7500.
- Furthermore, the message should be more clear about fixing the
- code instead of setting CMAKE_BACKWARDS_COMPATIBILITY unless one
- is just trying to build an existing project.
-
-2008-08-19 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-18 16:29 king
-
- * Source/: cmMakefile.cxx, cmMakefile.h, cmPolicies.cxx,
- cmPolicies.h: ENH: Improve errors when a policy is REQUIRED
-
- In the future some policies may be set to REQUIRED_IF_USED or
- REQUIRED_ALWAYS. This change clarifies the error messages users
- receive when violating the requirements.
-
-2008-08-18 11:39 king
-
- * Source/cmAddLibraryCommand.cxx, Source/cmAddLibraryCommand.h,
- Source/cmComputeLinkDepends.cxx,
- Source/cmComputeLinkInformation.cxx, Source/cmLocalGenerator.cxx,
- Source/cmTarget.cxx, Source/cmTarget.h,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: Add UNKNOWN type for
- IMPORTED libraries
-
- When creating an IMPORTED target for a library that has been
- found on disk, it may not be known whether the library is STATIC
- or SHARED. However, the library may still be linked using the
- file found from disk. Use of an IMPORTED target is still
- important to allow per-configuration files to be specified for
- the library.
-
- This change creates an UNKNOWN type for IMPORTED library targets.
- The IMPORTED_LOCATION property (and its per-config equivalents)
- specifies the location of the library. CMake makes no
- assumptions about the library that cannot be inferred from the
- file on disk. This will help projects and find-modules import
- targets found on disk or specified by the user.
-
-2008-08-18 11:26 king
-
- * Source/: cmLocalGenerator.cxx, cmTarget.cxx: STYLE: Convert
- unused target type cases to default
-
- In switch statements that deal with only a few target types, use
- a 'default' case for the remaining target types instead of
- listing them explicitly. This will make it easier to add more
- types in the future.
-
-2008-08-18 10:11 king
-
- * Source/cmTargetLinkLibrariesCommand.cxx,
- Source/cmTargetLinkLibrariesCommand.h,
- Tests/ExportImport/Export/CMakeLists.txt: ENH: Make link
- interface mode more distinct
-
- Rename the recently added INTERFACE mode of the
- target_link_libraries() command to LINK_INTERFACE_LIBRARIES.
- This makes it much more distinct from a normal call to the
- command, and clearly states its connection to the property of the
- same name. Also require the option to appear immediately after
- the target name to make it a mode rather than an option.
-
-2008-08-18 09:53 king
-
- * Source/cmCMakePolicyCommand.cxx, Source/cmCMakePolicyCommand.h,
- Tests/Complex/CMakeLists.txt,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexRelativePaths/CMakeLists.txt: ENH: Add
- cmake_policy(GET) command mode
-
- It is likely that projects or CMake modules in the future will
- need to check the value of a policy setting. For example, if we
- add a policy that affects the results of FindXYZ.cmake modules,
- the module code will need to be able to check the policy.
-
-2008-08-18 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-17 05:38 alex
-
- * Modules/FindKDE4.cmake: BUG: fix closing ENDIF()
-
- Alex
-
-2008-08-17 05:11 alex
-
- * Modules/FindQt4.cmake: BUG: fix closing IF()
-
- Alex
-
-2008-08-17 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-16 19:11 alex
-
- * Modules/: FindKDE3.cmake, FindKDE4.cmake, FindQt3.cmake,
- FindQt4.cmake: BUG: fix #7447, FindModulesExecuteAll test fails
- if both Qt3 and KDE4 can be found in the system
-
- Qt3 and Qt4 cannot be used together in one project. Now Qt3/KDE3
- and Qt4/KDE4 handle the case that this is done nevertheless
- properly, i.e. they fail with FATAL_ERROR if it was REQUIRED and
- they fail with just MESSAGE(STATUS ...) and RETURN() if it was
- not REQUIRED
-
- BUG: make FindQt4 error out with FATAL_ERROR also if it was
- searched QUIET
-
- Alex
-
-2008-08-16 18:06 hoffman
-
- * Tests/ReturnTest/include_return.cmake: file include_return.cmake
- was added on branch CMake-2-6 on 2008-09-03 13:43:31 +0000
-
-2008-08-16 18:06 alex
-
- * Source/cmReturnCommand.h, Tests/ReturnTest/CMakeLists.txt,
- Tests/ReturnTest/include_return.cmake: STYLE: extend
- documentation for RETURN() a bit ENH: add a test for calling
- RETURN() in an included file
-
- Alex
-
-2008-08-16 17:14 alex
-
- * Modules/FindQt3.cmake: STYLE: remove some unnecessary lines
- STYLE: everything uppercase in this file
-
- Alex
-
-2008-08-16 16:58 alex
-
- * Source/cmGlobalKdevelopGenerator.cxx: BUG: fix #7477, set
- VERBOSE=1 in the kdevelop setting for the environment, not
- together with the make executable
-
- Alex
-
-2008-08-16 16:48 alex
-
- * Source/cmExtraCodeBlocksGenerator.cxx: STYLE: remove some
- commented code
-
- Alex
-
-2008-08-16 16:33 alex
-
- * Source/cmGlobalKdevelopGenerator.cxx: BUG: fix #7471, only put
- build directories and CMakeFiles/ in the blacklist
-
- Alex
-
-2008-08-16 07:38 alex
-
- * Modules/FindX11.cmake: ENH: also search in /usr/X11R7, remove
- /usr/lib and /usr/local/lib, they are part of the standard search
- paths (partly sync wih KDE)
-
- Alex
-
-2008-08-16 07:29 alex
-
- * Modules/FindTIFF.cmake: ENH: add more names for libtiff, mark
- TIFF_INCLUDE_DIR and TIFF_LIBRARY as advanced (sync with KDE)
-
- Alex
-
-2008-08-16 07:22 alex
-
- * Modules/FindLibXml2.cmake: ENH: also search for xmllint, which
- comes with libxml2 (sync with FindLibXml2.cmake from KDE)
-
- Alex
-
-2008-08-16 07:10 alex
-
- * Modules/FindPNG.cmake: ENH: add more names of linpng (sync with
- the KDE version)
-
- Alex
-
-2008-08-16 07:01 alex
-
- * Modules/UsePkgConfig.cmake: STYLE: /usr/local/bin is in the path
- anyway STYLE: this file is mostly uppercase commands, so make all
- commands uppercase ENH: add a status message in case pkgconfig
- didn't find the package (sync with the one from KDE)
-
- Alex
-
-2008-08-16 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-15 15:07 hoffman
-
- * Modules/Platform/Windows-NMcl.cmake: ENH: add platform file for
- bounds checker
-
-2008-08-15 09:47 king
-
- * Source/cmSystemTools.cxx: COMP: Work-around bogus compiler
- warning.
-
-2008-08-15 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-14 15:34 alex
-
- * Modules/: FindLua50.cmake, FindLua51.cmake: BUG: fix
- documentation, the variables are named LUA50_FOUND and
- LUA51_FOUND (in all released versions)
-
- Alex
-
-2008-08-14 09:53 king
-
- * Source/: cmFileCommand.cxx, cmSystemTools.cxx, cmSystemTools.h:
- ENH: Inform user when RPATH or RUNPATH is removed
-
-2008-08-14 09:53 king
-
- * Source/cmSystemTools.cxx: BUG: Update both RPATH and RUNPATH
- entries
-
- During installation the RPATH and RUNPATH entries of ELF binaries
- are edited to match the user specification. Usually either one
- entry is present or both entries refer to the same string
- literal. In the case that they are both present and refer to
- separate string literals we need to update both. I have never
- seen this case in practice, but we should do this just in case.
-
-2008-08-14 09:53 king
-
- * Source/cmSystemTools.cxx: BUG: Remove both RPATH and RUNPATH
- entries
-
- Removal of the RPATH and RUNPATH from ELF binaries must work when
- both entries are present. Both entries should be removed.
- Previously only one would be removed and the other would be
- blanked because it pointed at the same string which was zeroed.
- This fixes gentoo bug number 224901.
-
-2008-08-14 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-13 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-12 19:01 king
-
- * Source/: cmFindPackageCommand.cxx, cmFindPackageCommand.h: ENH:
- Teach find_package about lib64 paths
-
- When find_package is about to look in <prefix>/lib, search first
- in <prefix>/lib64 in cases that find_library would use lib64
- paths.
-
-2008-08-12 17:27 hoffman
-
- * Tests/ExportImport/Export/testLib4libdbg1.c: file
- testLib4libdbg1.c was added on branch CMake-2-6 on 2008-09-03
- 13:43:28 +0000
-
-2008-08-12 17:27 hoffman
-
- * Tests/ExportImport/Export/testLib4libopt1.c: file
- testLib4libopt1.c was added on branch CMake-2-6 on 2008-09-03
- 13:43:28 +0000
-
-2008-08-12 17:27 king
-
- * Tests/ExportImport/Export/: CMakeLists.txt, testLib4libdbg1.c,
- testLib4libopt1.c: BUG: Fix ExportImport test on VS6
-
- Visual Studio 6 does not support per-target object files, so just
- use two separate source file names in this case.
-
-2008-08-12 07:01 alex
-
- * Source/cmakemain.cxx: STYLE: one ifdef block less, the
- documentation object can be created a bit later
-
- Alex
-
-2008-08-12 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-11 16:23 hoffman
-
- * Tests/ExportImport/Export/testLib4lib.c: file testLib4lib.c was
- added on branch CMake-2-6 on 2008-09-03 13:43:28 +0000
-
-2008-08-11 16:23 hoffman
-
- * Tests/ExportImport/Export/testLib4libdbg.c: file testLib4libdbg.c
- was added on branch CMake-2-6 on 2008-09-03 13:43:28 +0000
-
-2008-08-11 16:23 hoffman
-
- * Tests/ExportImport/Export/testLib4libopt.c: file testLib4libopt.c
- was added on branch CMake-2-6 on 2008-09-03 13:43:28 +0000
-
-2008-08-11 16:23 king
-
- * Tests/ExportImport/: Export/CMakeLists.txt, Export/testLib4lib.c,
- Export/testLib4libdbg.c, Export/testLib4libopt.c,
- Import/CMakeLists.txt, Import/imp_testExe1.c: ENH: Test
- target_link_libraries INTERFACE option
-
-2008-08-11 16:23 king
-
- * Source/: cmTargetLinkLibrariesCommand.cxx,
- cmTargetLinkLibrariesCommand.h: ENH: Simple specification of link
- interfaces
-
- Create an INTERFACE option to the target_link_libraries command
- to help set the LINK_INTERFACE_LIBRARIES and
- LINK_INTERFACE_LIBRARIES_DEBUG properties. This will help users
- specify link interfaces using variables from Find*.cmake modules
- that include the 'debug' and 'optimized' keywords.
-
-2008-08-11 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-10 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-09 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-08 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-07 17:51 king
-
- * Source/: cmTargetLinkLibrariesCommand.cxx,
- cmTargetLinkLibrariesCommand.h: ENH: Tolerate repeated link
- library types
-
- The "debug", "optimized", and "general" link library type
- specifier arguments to the target_link_library commands are
- sometimes repeated in user code due to variable expansion and
- other complications. Instead of silently accepting the
- duplicates and trying to link to a bogus library like
- "optimized.lib", warn and ignore the earlier specifiers.
-
-2008-08-07 17:12 king
-
- * Source/cmAddSubDirectoryCommand.h: ENH: Clarify documentation of
- EXCLUDE_FROM_ALL
-
- The add_subdirectory() command's EXCLUDE_FROM_ALL option does not
- override inter-target dependencies. This change clarifies the
- documentation accordingly.
-
-2008-08-07 10:13 hoffman
-
- * Tests/Dependency/Case4/CMakeLists.txt: file CMakeLists.txt was
- added on branch CMake-2-6 on 2008-09-03 13:43:27 +0000
-
-2008-08-07 10:13 hoffman
-
- * Tests/Dependency/Case4/bar.c: file bar.c was added on branch
- CMake-2-6 on 2008-09-03 13:43:27 +0000
-
-2008-08-07 10:13 hoffman
-
- * Tests/Dependency/Case4/foo.c: file foo.c was added on branch
- CMake-2-6 on 2008-09-03 13:43:27 +0000
-
-2008-08-07 10:13 king
-
- * Tests/Dependency/: CMakeLists.txt, Case4/CMakeLists.txt,
- Case4/bar.c, Case4/foo.c: ENH: Test fake circular dependency case
-
- A recent change fixed a case in which CMake incorrectly diagnosed
- a circular dependency involving a non-linkable executable target.
- This adds a test for that case.
-
-2008-08-07 09:09 king
-
- * Modules/: CMakeCCompilerABI.c, CMakeCCompilerId.c.in,
- CMakeCXXCompilerABI.cpp, CMakeCXXCompilerId.cpp.in,
- CheckTypeSizeC.c.in, TestEndianess.c.in: ENH: Improve robustness
- of compiler INFO strings
-
- Compiler INFO strings built at preprocessing time encode
- information that must appear as a string literal in the resulting
- binary. We must make sure the strings appear in the final binary
- no matter what compiler and flags are used. The previous
- implementation worked in most places but failed with the GNU
- linker's --gc-sections option which managed to discard the
- string. Instead we make the program return value depend on an
- element of the string indexed by a runtime program parameter,
- which absolutely requires the string to be present.
-
-2008-08-07 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-06 17:48 king
-
- * Source/: cmComputeLinkDepends.cxx, cmComputeLinkDepends.h,
- cmComputeTargetDepends.cxx, cmComputeTargetDepends.h: BUG: Avoid
- bogus dependency on executable targets
-
- When an executable target within the project is named in
- target_link_libraries for another target, but the executable does
- not have the ENABLE_EXPORTS property set, then the executable
- cannot really be linked. This is probably a case where the user
- intends to link to a third-party library that happens to have the
- same name as an executable target in the project (or else will
- get an error at build time). We need to avoid making the other
- target depend on the executable target incorrectly, since the
- executable may actually want to link to that target and this is
- not a circular depenency.
-
-2008-08-06 17:48 king
-
- * Source/cmComputeTargetDepends.cxx: ENH: Improve readability of
- circular depends error
-
- When reporting the dependencies in a strongly connected component
- quote the target names to make the message more readable no
- matter the target name.
-
-2008-08-06 17:48 king
-
- * Source/cmGlobalGenerator.cxx: BUG: Fix crash on circular target
- dependencies
-
- After reporting an error about circular target dependencies do
- not try to continue generation because the dependency computation
- object is not in a useful state.
-
-2008-08-06 17:43 alex
-
- * Tests/CMakeLists.txt: BUG: fix endif()
-
- Alex
-
-2008-08-06 17:04 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Modules/CMakeCInformation.cmake,
- Modules/CMakeCXXInformation.cmake,
- Modules/CMakeFortranInformation.cmake,
- Modules/FindImageMagick.cmake, Modules/FindKDE3.cmake,
- Modules/Platform/Darwin.cmake,
- Modules/Platform/Linux-Intel-C.cmake,
- Modules/Platform/Linux-Intel-CXX.cmake, Source/CMakeLists.txt,
- Source/cmELF.cxx, Source/cmExtraEclipseCDT4Generator.cxx,
- Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmGlobalXCodeGenerator.cxx, Source/cmLocalGenerator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx, Source/cmMakefile.cxx,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.h,
- Source/cmSourceFileLocation.cxx, Source/cmSourceFileLocation.h,
- Source/cmTarget.cxx, Source/cmTarget.h, Source/cmake.cxx,
- Source/cmake.h, Source/cmakemain.cxx,
- Source/CTest/cmCTestCoverageHandler.cxx,
- Tests/CustomCommand/CMakeLists.txt: ENH: merge in fixes from main
- tree 2.6.2 RC 1
-
-2008-08-06 16:16 alex
-
- * Tests/CMakeLists.txt: ENH: add simple tests to test that the
- extra generators don't crash
-
- Alex
-
-2008-08-06 16:05 king
-
- * Modules/Platform/: Linux-Intel-C.cmake, Linux-Intel-CXX.cmake:
- ENH: Add preprocessor and assembly rules for Intel
-
-2008-08-06 15:35 alex
-
- * Source/cmExtraEclipseCDT4Generator.cxx: BUG: don't crash in the
- generator is EXECUTABLE_OUTPUT_PATH or LIBRARY_OUTPUT_PATH are
- empty
-
- Alex
-
-2008-08-06 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-05 16:06 alex
-
- * Modules/FindKDE3.cmake: BUG: fix #7452, bad closing ENDIF()
- statement
-
- Alex
-
-2008-08-05 13:27 king
-
- * Tests/CustomCommand/CMakeLists.txt: ENH: Test relative path
- custom command output
-
- As of CMake 2.6 a custom command output specified by relative
- path is placed in the build tree. This adds a test to make sure
- other references to the output are hooked up correctly, fixing a
- bug in CMake 2.6.1.
-
-2008-08-05 13:27 king
-
- * Source/cmLocalGenerator.cxx: BUG: Custom command depends may
- match sources
-
- Custom command dependencies that are not full paths or targets
- may also match source files. When one does, the full information
- about the source file's location and name may be used. This
- fixes the case when a custom commands depends by relative path on
- a source file generated by another custom command specifying its
- output by relative path.
-
-2008-08-05 13:27 king
-
- * Source/: cmSourceFileLocation.cxx, cmSourceFileLocation.h: BUG:
- Fix matching of ambiguous sf extensions.
-
- A name with an ambiguous extension may only match an unambiguous
- name that is extended by one of the fixed set of extensions tried
- when finding the source file on disk. This rule makes matching
- of source files with ambiguous extensions much less aggressive
- but still sufficient.
-
-2008-08-05 09:55 king
-
- * Source/cmLocalGenerator.cxx: BUG: Do not convert RPATH entries to
- full path.
-
- When generating RPATH entries on the link line using a repeated
- linker flag (-R ... -R ... style) do not convert individual
- entries to a full path. We need to preserve what the user
- requested.
-
-2008-08-05 09:55 king
-
- * Source/cmLocalGenerator.cxx: BUG: Fix escaping in link scripts
-
- When generating escape sequences for the native build tool do not
- put in Makefile escapes for paths generated into link scripts.
- This fixes putting "$ORIGIN" into the RPATH, and probably some
- other subtle problems.
-
-2008-08-05 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-04 11:37 king
-
- * Modules/CMakeCInformation.cmake,
- Modules/CMakeCXXInformation.cmake,
- Modules/CMakeFortranInformation.cmake,
- Source/cmMakefileLibraryTargetGenerator.cxx: ENH: Build large
- archives incrementally
-
- Creation of archive libraries with the unix 'ar' tool should be
- done incrementally when the number of object files is large.
- This avoids problems with the command line getting too many
- arguments.
-
-2008-08-04 09:38 king
-
- * Source/cmELF.cxx: BUG: Fix operator precedence error in cmELF
-
- When attempting to load the RPATH out of a non-ELF file cmELF
- would crash because the check for a valid file was done with in
- correct operator precedence. See bug#7392.
-
-2008-08-04 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-03 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-02 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-08-01 20:38 miguelf
-
- * Modules/FindImageMagick.cmake: STYLE: Fixed module list in
- documentation; Magick should be MagickCore.
-
-2008-08-01 12:10 david.cole
-
- * Source/CMakeLists.txt: BUG: Improve fix for issue #7058 -
- comsuppd did not yet exist in VC6.
-
-2008-08-01 11:03 hoffman
-
- * CMakeLists.txt: ENH: final 2.6.1
-
-2008-08-01 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-31 14:16 david.cole
-
- * Source/CTest/cmCTestCoverageHandler.cxx: BUG: Fix issue#4792 -
- improve verbose and log output when ctest cannot find a file
- during coverage analysis.
-
-2008-07-31 13:46 david.cole
-
- * Source/CMakeLists.txt: BUG: Fix issue #7058 - link the commsup
- lib explicitly for use on some Visual Studio + SDK combinations
-
-2008-07-31 13:36 hoffman
-
- * Source/cmake.cxx: BUG: fix for 7426 bad check for cpack
-
-2008-07-31 12:54 david.cole
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: Fix issue #5773 -
- add table entry to map /W0 to WarningLevel="0"
-
-2008-07-31 12:00 hoffman
-
- * Tests/BundleGeneratorTest/CMakeLists.txt: ENH: fix for branch
-
-2008-07-31 11:52 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Modules/InstallRequiredSystemLibraries.cmake,
- Source/cmCallVisualStudioMacro.cxx,
- Source/cmCallVisualStudioMacro.h, Source/cmGlobalGenerator.cxx,
- Source/cmGlobalVisualStudioGenerator.cxx, Source/cmake.cxx,
- Tests/CMakeLists.txt, Tests/BundleGeneratorTest/BundleIcon.icns,
- Tests/BundleGeneratorTest/CMakeLists.txt,
- Tests/BundleGeneratorTest/Executable.cxx,
- Tests/BundleGeneratorTest/Info.plist,
- Tests/BundleGeneratorTest/Library.cxx,
- Tests/BundleGeneratorTest/StartupCommand: ENH: merge in stuff
- from cvs head RC 16
-
-2008-07-31 11:28 david.cole
-
- * Source/CTest/cmCTestCoverageHandler.cxx: BUG: Fix issue #4971 -
- use lower case when comparing file names from gcov output on
- _WIN32 since sometimes the drive letters have different case.
-
-2008-07-31 10:54 hoffman
-
- * Tests/CMakeLists.txt: ENH: fix build with Xcode project was
- missing
-
-2008-07-31 10:33 hoffman
-
- * Source/: cmMakefile.cxx, cmake.cxx, cmake.h, cmakemain.cxx: ENH:
- add a --trace option
-
-2008-07-31 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-30 16:36 hoffman
-
- * Tests/BundleGeneratorTest/BundleIcon.icns: file BundleIcon.icns
- was added on branch CMake-2-6 on 2008-07-31 15:52:24 +0000
-
-2008-07-30 16:36 hoffman
-
- * Tests/BundleGeneratorTest/CMakeLists.txt: file CMakeLists.txt was
- added on branch CMake-2-6 on 2008-07-31 15:52:25 +0000
-
-2008-07-30 16:36 hoffman
-
- * Tests/BundleGeneratorTest/Executable.cxx: file Executable.cxx was
- added on branch CMake-2-6 on 2008-07-31 15:52:25 +0000
-
-2008-07-30 16:36 hoffman
-
- * Tests/BundleGeneratorTest/Info.plist: file Info.plist was added
- on branch CMake-2-6 on 2008-07-31 15:52:25 +0000
-
-2008-07-30 16:36 hoffman
-
- * Tests/BundleGeneratorTest/Library.cxx: file Library.cxx was added
- on branch CMake-2-6 on 2008-07-31 15:52:25 +0000
-
-2008-07-30 16:36 hoffman
-
- * Tests/BundleGeneratorTest/StartupCommand: file StartupCommand was
- added on branch CMake-2-6 on 2008-07-31 15:52:25 +0000
-
-2008-07-30 16:36 david.cole
-
- * Tests/: CMakeLists.txt, BundleGeneratorTest/BundleIcon.icns,
- BundleGeneratorTest/CMakeLists.txt,
- BundleGeneratorTest/Executable.cxx,
- BundleGeneratorTest/Info.plist, BundleGeneratorTest/Library.cxx,
- BundleGeneratorTest/StartupCommand: ENH: Add test for the new
- CPack BundleGenerator. Thanks to Tim Shead for the patch. See
- issue #7170 for more details.
-
-2008-07-30 15:43 david.cole
-
- * Modules/InstallRequiredSystemLibraries.cmake: BUG: Fix issue
- #6610. Use 64-bit system binaries when using the 64-bit MSVC
- compiler. Thanks to Clinton Stimpson for the patch.
-
-2008-07-30 15:26 david.cole
-
- * Source/: cmCallVisualStudioMacro.cxx, cmCallVisualStudioMacro.h,
- cmGlobalVisualStudioGenerator.cxx, cmake.cxx: BUG: Fix issue
- #7088 - do not emit error messages when attempts to run Visual
- Studio macros fail. You can still get the error output as
- messages if you want using --debug-output from the cmake command
- line.
-
-2008-07-30 15:18 hoffman
-
- * Source/cmGlobalGenerator.cxx: BUG: fix for bug 7427, preinstall
- target name hard coded
-
-2008-07-30 14:54 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/FindBoost.cmake,
- Modules/FindImageMagick.cmake, Modules/FindJPEG.cmake,
- Source/cmComputeLinkDepends.cxx, Source/cmComputeLinkDepends.h,
- Source/cmComputeLinkInformation.cxx, Source/cmLocalGenerator.cxx,
- Source/cmOrderDirectories.cxx, Source/cmOrderDirectories.h,
- Source/cmSourceFileLocation.cxx,
- Source/CPack/cmCPackPackageMakerGenerator.cxx,
- Source/CPack/cmCPackPackageMakerGenerator.h: ENH: merge in from
- main tree RC 15
-
-2008-07-30 13:28 david.cole
-
- * Source/CPack/: cmCPackPackageMakerGenerator.cxx,
- cmCPackPackageMakerGenerator.h: BUG: Fix issue #7414 - do not
- crash when given components with circular dependencies. Thanks to
- Doug Gregor for the patch.
-
-2008-07-30 11:06 king
-
- * Source/cmSourceFileLocation.cxx: ENH: Recognize src extensions of
- all enabled langs
-
- For historical reasons we still support naming of source files
- without their extension. Sources without known extensions are
- located on disk by iterating through a fixed set of possible
- extensions. We now want users to always specify the extension,
- so the fixed set will not be expanded and is preserved for
- compatibility with older projects.
-
- This change adds recognition of extensions of all enabled
- languages to avoid checking the disk for files whose extensions
- are unambiguous but not in the original fixed set.
-
-2008-07-30 11:06 king
-
- * Source/cmSourceFileLocation.cxx: BUG: Avoid double-slash in check
- for source file
-
-2008-07-30 10:44 hoffman
-
- * Source/cmLocalGenerator.cxx: BUG: fix for bug 7421, fortran did
- not get arch flags on the mac
-
-2008-07-30 10:23 king
-
- * Source/: cmComputeLinkDepends.cxx, cmComputeLinkDepends.h,
- cmComputeLinkInformation.cxx: BUG: Preserve all non-targets on
- user link lines
-
- In CMake 2.4 the generated link line for a target always
- preserved the originally specified libraries in their original
- order. Dependencies were satisfied by inserting extra libraries
- into the line, though it had some bugs. In CMake 2.6.0 we
- preserved only the items on the link line that are not known to
- be shared libraries. This reduced excess libraries on the link
- line. However, since we link to system libraries (such as
- /usr/lib/libm.so) by asking the linker to search (-lm), some
- linkers secretly replace the library with a static library in
- another implicit search directory (developers can override this
- by using an imported target to force linking by full path). When
- this happens the order still matters.
-
- To avoid this and other potential subtle issues this commit
- restores preservation of all non-target items and static library
- targets. This will create cases of unnecessary, duplicate shared
- libraries on the link line if the user specifies them, but at
- least it will work. In the future we can attempt a more advanced
- analysis to safely remove duplicate shared libraries from the
- link line.
-
-2008-07-30 09:25 king
-
- * Source/cmComputeLinkDepends.cxx: BUG: Preserve shared lib order
- for 2.4 compatibility
-
- We preserve the order and multiplicity of libraries directly
- linked by a target as specified by the user. Items known to be
- shared libraries may be safely skipped because order preservation
- is only needed for static libraries. However, CMake 2.4 did not
- skip shared libs, so we do the same when in 2.4 compatibility
- mode.
-
-2008-07-30 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-29 16:41 hoffman
-
- * Modules/FindJPEG.cmake: BUG: #7416 fix error when jpeg is not
- found
-
-2008-07-29 14:57 king
-
- * Source/: cmComputeLinkInformation.cxx, cmOrderDirectories.cxx,
- cmOrderDirectories.h: ENH: Warn when system libraries may be
- hidden.
-
- We never explicitly specify system library directories in linker
- or runtime search paths. Furthermore, libraries in these
- directories are always linked by asking the linker to search for
- them. We need to generate a warning when explicitly specified
- search directories contain files that may hide the system
- libraries during the search.
-
-2008-07-29 14:01 king
-
- * Source/: cmComputeLinkInformation.cxx, cmOrderDirectories.cxx,
- cmOrderDirectories.h: ENH: Provide context in path ordering
- warnings
-
-2008-07-29 14:00 king
-
- * Source/cmOrderDirectories.cxx: STYLE: Fix typo in comment in
- cmOrderDirectories
-
-2008-07-29 10:51 hoffman
-
- * Source/cmComputeLinkInformation.cxx: ENH: do not depend on files
- that do not exist
-
-2008-07-29 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-28 15:40 dgregor
-
- * Modules/FindBoost.cmake: BUG: Be more careful with
- Boost_MINOR_VERSION in FindBoost module
-
-2008-07-28 14:33 dgregor
-
- * Modules/FindBoost.cmake: BUG: Work around Boost 1.36.0 bug fix on
- Darwin by setting the mangled compiler name to -xgccVERSION
-
-2008-07-28 11:31 hoffman
-
- * CMakeLists.txt, CTestConfig.cmake, ChangeLog.manual,
- DartConfig.cmake, Source/cmComputeLinkInformation.cxx,
- Source/cmComputeLinkInformation.h, Source/cmPolicies.cxx,
- Source/cmPolicies.h, Source/cmTarget.cxx, Source/cmTarget.h: ENH:
- merge in policy 0008 and cdash direct submission
-
-2008-07-28 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-27 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-26 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-25 23:23 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/FindJNI.cmake,
- Source/cmSourceFileLocation.cxx: ENH: merge in from main tree and
- fix bug for flex and yacc stuff in SecondLife
-
-2008-07-25 18:00 hoffman
-
- * Source/cmSourceFileLocation.cxx: BUG: fix source file extension
- bug that broke Second life build
-
-2008-07-25 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-24 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-23 12:59 king
-
- * Source/: cmComputeLinkInformation.cxx,
- cmComputeLinkInformation.h, cmPolicies.cxx, cmPolicies.h,
- cmTarget.cxx, cmTarget.h: ENH: Support full-path libs w/out valid
- names.
-
- This change introduces policy CMP0008 to decide how to treat full
- path libraries that do not appear to be valid library file names.
- Such libraries worked by accident in the VS IDE and Xcode
- generators with CMake 2.4 and below. We support them in CMake
- 2.6 by introducing this policy. See policy documentation added
- by this change for details.
-
-2008-07-23 12:19 king
-
- * Source/: cmComputeLinkInformation.cxx,
- cmComputeLinkInformation.h: ENH: Skip libs in known dirs for
- CMP0003 warnings.
-
- Sometimes we ask the linker to search for a library for which the
- path is known but for some reason cannot be specified by full
- path. In these cases do not include the library in CMP0003
- warnings because we know the extra paths are not needed for it.
-
-2008-07-23 02:47 miguelf
-
- * Modules/FindImageMagick.cmake: ENH: Updated FindImageMagick to: -
- Find newer additions such as animate, compare, etc. - Find
- development api: Magick++, MagickCore, MagickWand - Use
- FindPackageHandleStandardArgs to output standard messages.
-
-2008-07-23 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-22 14:04 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Modules/CheckFortranFunctionExists.cmake, Modules/FindBLAS.cmake,
- Modules/FindLAPACK.cmake, Modules/FindMPI.cmake,
- Modules/FindwxWidgets.cmake, Source/cmComputeLinkInformation.cxx,
- Source/cmDocumentVariables.cxx, Source/cmDocumentation.cxx,
- Source/cmDocumentationFormatter.cxx,
- Source/cmDocumentationFormatterHTML.cxx,
- Source/cmLocalGenerator.cxx,
- Source/CPack/cmCPackBundleGenerator.cxx: ENH: merge in changes
- from main tree for RC12
-
-2008-07-22 13:34 hoffman
-
- * Modules/: FindBLAS.cmake, FindLAPACK.cmake, FindOpenSSL.cmake:
- ENH: change to correct line feed
-
-2008-07-22 13:32 hoffman
-
- * Source/cmLocalGenerator.cxx: COMP: fix compiler warning and
- follow style
-
-2008-07-22 07:15 alin.elena
-
- * Modules/: CheckFortranFunctionExists.cmake, FindBLAS.cmake,
- FindLAPACK.cmake:
- ENH: FindBLAS.cmake, FindLAPACK.cmake modules were redesigned so
- now you have three new variables BLA_VENDOR (you can specify the
- VENDOR), BLA_STATIC (gets the static version of libs), BLA_F95
- (gets the fortran 95 interface). BLA_VENDOR can be specified as
- an environment variable. Intel mkls libs need FindThreads to be
- found correctly so you will need to enable the C/CXX
-
-2008-07-22 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-21 17:52 alex
-
- * Source/: cmDocumentation.cxx, cmDocumentationFormatter.cxx,
- cmDocumentationFormatterHTML.cxx: ENH: handle HTML documentation
- for single items better: no warning about
- ComputeSectionLinkPrefix, don't create an index for only one item
-
- Alex
-
-2008-07-21 15:44 hoffman
-
- * CTestConfig.cmake, DartConfig.cmake: ENH: switch to using cdash
- for submissions
-
-2008-07-21 15:34 hoffman
-
- * Modules/: FindBLAS.cmake, FindLAPACK.cmake: ENH: get out of
- module if no fortran
-
-2008-07-21 15:11 hoffman
-
- * Modules/: FindBLAS.cmake, FindLAPACK.cmake: ENH: this should fail
- only if required is sent to find package
-
-2008-07-21 13:40 alin.elena
-
- * Modules/: FindBLAS.cmake, FindLAPACK.cmake:
- ENH: checks if Fortran is enbaled. If not an error message is
- produced.
-
-2008-07-21 10:07 king
-
- * Source/cmComputeLinkInformation.cxx: ENH: Support full-path libs
- w/out extension in VS IDE.
-
- - This case worked accidentally in CMake 2.4, though not in
- Makefiles.
- - Some projects build only with the VS IDE on windows and have
- this
- mistake.
- - Support them when 2.4 compatibility is enabled by adding the
- extension.
-
-2008-07-21 04:56 alin.elena
-
- * Modules/: CheckFortranFunctionExists.cmake, FindLAPACK.cmake:
- ENH: Modules/CheckFortranFunctionExists.cmake helps gfortran to
- check the existence of a file ENH: Modules/FindLAPACK.cmake
- returns the full list of libraries required to link against
- Lapack
-
-2008-07-21 00:02 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-20 17:14 alex
-
- * Source/cmDocumentVariables.cxx: STYLE: fix #7146, add
- documentation for
- CMAKE[_SYSTEM]_(LIBRARY|PROGRAM|INCLUDE|PREFIX)_PATH variables
- -moved CMAKE_CROSSCOMPILING from "Variables that modify
- behaviour" to "variables that Provide Information", since it
- should be used only for testing whether we are currently in cross
- compiling mode, not for switching between the modes.
-
- Alex
-
-2008-07-20 15:50 alex
-
- * Modules/FindJNI.cmake: BUG: #7333, search dirs for Fedora
-
- Alex
-
-2008-07-20 15:45 alex
-
- * Modules/FindJNI.cmake: BUG: #7360: add support for FreeBSD BUG:
- #7345: add support for ppc
-
- Alex
-
-2008-07-20 15:39 alex
-
- * Modules/FindJNI.cmake: BUG: fix #6416: provide JNI_LIBRARIES and
- JNI_INCLUDE_DIRS
-
- Alex
-
-2008-07-19 23:52 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-18 23:52 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-18 16:12 david.cole
-
- * Source/CPack/cmCPackBundleGenerator.cxx: ENH: Improvements to the
- bundle cpack generator from second patch attached to feature
- request #7170. Thanks to Tim Shead.
-
-2008-07-18 11:24 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Utilities/cmcurl/CMakeLists.txt,
- Utilities/cmcurl/CMake/CheckCSourceCompiles.cmake,
- Utilities/cmcurl/CMake/CheckCSourceRuns.cmake,
- Utilities/cmcurl/CMake/CurlCheckCSourceCompiles.cmake,
- Utilities/cmcurl/CMake/CurlCheckCSourceRuns.cmake,
- Utilities/cmcurl/CMake/OtherTests.cmake: ENH: merge in fix for
- xcode 3.1 build from main tree
-
-2008-07-18 08:17 dgregor
-
- * Modules/FindMPI.cmake: ENH: Use the HINTS feature of find_library
- to find the right libraries for MPI, and act a bit more
- intelligently when MPI cannot be found.
-
-2008-07-17 23:52 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-17 15:19 king
-
- * Utilities/cmcurl/CMakeLists.txt: COMP: Check for -Wno-long-double
- before using
-
- Older GCC on the Mac warns for use of long double, so we use
- -Wno-long-double. Newer GCC on the Mac does not have this flag
- and gives an error. We now check for the flag before using it.
- See bug #7357.
-
-2008-07-17 15:19 hoffman
-
- * Utilities/cmcurl/CMake/CurlCheckCSourceCompiles.cmake: file
- CurlCheckCSourceCompiles.cmake was added on branch CMake-2-6 on
- 2008-07-18 15:24:26 +0000
-
-2008-07-17 15:19 hoffman
-
- * Utilities/cmcurl/CMake/CurlCheckCSourceRuns.cmake: file
- CurlCheckCSourceRuns.cmake was added on branch CMake-2-6 on
- 2008-07-18 15:24:26 +0000
-
-2008-07-17 15:19 king
-
- * Utilities/cmcurl/CMake/: CheckCSourceCompiles.cmake,
- CheckCSourceRuns.cmake, CurlCheckCSourceCompiles.cmake,
- CurlCheckCSourceRuns.cmake, OtherTests.cmake: ENH: Avoid cmcurl
- CMake macro name conflicts
-
- Utilities/cmcurl/CMake provides macros with the same file names
- and macro names as others in Modules, but with different
- interfaces. We rename the curl ones to avoid conflict.
-
-2008-07-17 10:14 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Source/cmGlobalGenerator.cxx,
- Source/cmGlobalGenerator.h, Tests/TryCompile/CMakeLists.txt: ENH:
- merge in two bug fixes to 26
-
-2008-07-16 23:52 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-16 11:03 king
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h: BUG: Fix
- try_compile during EnableLanguage
-
- - The source-file signature of try_compile looks up the
- language
- of the source file using the extension-to-language map so
- that
- it knows what language to enable in the generated project.
- - This map needs to be filled before loading a file specified
- by
- CMAKE_USER_MAKE_RULES_OVERRIDE
- CMAKE_USER_MAKE_RULES_OVERRIDE_<LANG>
- so that the user file may call the try_compile() source-file
- signature.
- - It must still be re-filled after loading
- CMake<LANG>Information.cmake
- in case the compiler- or platform-specific files added
- anything.
- - See bug #7340.
-
-2008-07-16 09:29 hoffman
-
- * Tests/TryCompile/CMakeLists.txt: ENH: remove test that does not
- work on all compilers
-
-2008-07-15 23:52 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-15 11:35 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/FindBoost.cmake,
- Source/cmGlobalXCodeGenerator.cxx,
- Tests/TryCompile/CMakeLists.txt: ENH: merge in fix for xcode and
- new version of find boost
-
-2008-07-15 10:04 hoffman
-
- * Tests/TryCompile/CMakeLists.txt: ENH: add a test for bug 7316
-
-2008-07-14 23:53 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-14 18:51 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: BUG: fix for bug 7316
-
-2008-07-14 13:52 dgregor
-
- * Modules/FindBoost.cmake: ENH: FindBoost can now find the upcoming
- Boost 1.46
-
-2008-07-14 12:24 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Source/CMakeLists.txt: ENH: add
- cmCPackComponentGroup to build
-
-2008-07-14 09:22 hoffman
-
- * Source/CPack/cmCPackComponentGroup.cxx: ENH: add missing merged
- file
-
-2008-07-13 23:53 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-13 18:06 miguelf
-
- * Modules/FindwxWidgets.cmake: ENH: Improved support for finding
- wxWidgets in MinGW environment.
-
-2008-07-13 17:55 hoffman
-
- * CMakeCPackOptions.cmake.in, CMakeLists.txt, ChangeLog.manual,
- Modules/CPack.Info.plist.in, Modules/CPack.cmake,
- Modules/FindBoost.cmake, Modules/FindQt4.cmake,
- Modules/FindwxWidgets.cmake, Modules/NSIS.template.in,
- Source/cmBootstrapCommands.cxx, Source/cmCommands.cxx,
- Source/cmGetCMakePropertyCommand.cxx,
- Source/cmGetCMakePropertyCommand.h, Source/cmGlobalGenerator.h,
- Source/cmGlobalXCodeGenerator.cxx,
- Source/cmGlobalXCodeGenerator.h, Source/cmInstallCommand.cxx,
- Source/cmInstallFilesCommand.cxx,
- Source/cmInstallProgramsCommand.cxx,
- Source/cmInstallTargetGenerator.h,
- Source/cmInstallTargetsCommand.cxx, Source/cmake.cxx,
- Source/CPack/cmCPackComponentGroup.h,
- Source/CPack/cmCPackGenerator.cxx,
- Source/CPack/cmCPackNSISGenerator.cxx,
- Source/CPack/cmCPackNSISGenerator.h,
- Source/CPack/cmCPackPackageMakerGenerator.cxx,
- Source/CPack/cmCPackPackageMakerGenerator.h,
- Source/QtDialog/CMakeSetupDialog.cxx,
- Source/QtDialog/CMakeSetupDialog.h,
- Source/QtDialog/CMakeSetupDialog.ui,
- Source/QtDialog/QCMakeCacheView.cxx,
- Source/kwsys/RegularExpression.cxx,
- Tests/CPackComponents/CMakeLists.txt: ENH: Merge from head create
- RC7
-
-2008-07-12 23:53 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-11 23:53 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-10 23:53 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-10 17:20 hoffman
-
- * Source/kwsys/RegularExpression.cxx: COMP: remove warning and
- check for assignment to itself in operator=
-
-2008-07-09 23:53 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-09 17:45 king
-
- * Modules/Platform/Darwin.cmake: BUG: Fix dylib versioning flags
- for old OSX.
-
- - ld flags -dylib_compatibility_version and
- -dylib_current_version
- are libtool flags -compatibility_version and -current_version
- - OSX 10.3 does not like the dylib_ prefixes.
-
-2008-07-09 16:30 david.cole
-
- * Source/CPack/cmCPackComponentGroup.h: COMP: Fix HP continuous.
- Pull stl headers into CMake header files using
- cmStandardIncludes.h
-
-2008-07-09 13:38 hoffman
-
- * Source/CPack/cmCPackComponentGroup.cxx: file
- cmCPackComponentGroup.cxx was added on branch CMake-2-6 on
- 2008-07-14 13:22:45 +0000
-
-2008-07-09 13:38 david.cole
-
- * Modules/CPack.Info.plist.in, Modules/CPack.cmake,
- Source/CMakeLists.txt, Source/CPack/cmCPackComponentGroup.cxx,
- Source/CPack/cmCPackComponentGroup.h,
- Source/CPack/cmCPackPackageMakerGenerator.cxx,
- Source/CPack/cmCPackPackageMakerGenerator.h: ENH: One more patch
- from Doug Gregor including PackageMaker functionality for
- componentized-for-the-end-user and download-some-bit-on-demand
- installers.
-
-2008-07-09 11:46 hoffman
-
- * Source/kwsys/RegularExpression.cxx: ENH: fix memory leak
-
-2008-07-09 10:09 king
-
- * Modules/Platform/Darwin.cmake, Source/cmGlobalXCodeGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.h: ENH: Set version info
- for shared libs on OSX.
-
- - Map SOVERSION major.minor.patch to compatibility_version
- - Map VERSION major.minor.patch to current_version
- - See issue #4383.
-
-2008-07-09 10:09 king
-
- * Source/: cmTarget.cxx, cmTarget.h: ENH: Add full target version
- signature cmTarget::GetTargetVersion.
-
-2008-07-08 23:53 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-08 17:47 david.cole
-
- * Tests/CPackComponents/CMakeLists.txt: ENH: Use new
- cpack_add_component macro (and friends) from the CPackComponents
- test. Thanks again to Doug Gregor!
-
-2008-07-08 11:52 david.cole
-
- * Modules/CPack.cmake, Modules/NSIS.template.in,
- Source/CPack/cmCPackComponentGroup.h,
- Source/CPack/cmCPackGenerator.cxx,
- Source/CPack/cmCPackNSISGenerator.cxx,
- Source/CPack/cmCPackNSISGenerator.h,
- Source/CPack/cmCPackPackageMakerGenerator.cxx,
- Source/cmGetCMakePropertyCommand.cxx,
- Source/cmGetCMakePropertyCommand.h, Source/cmGlobalGenerator.h,
- Source/cmInstallCommand.cxx, Source/cmInstallFilesCommand.cxx,
- Source/cmInstallProgramsCommand.cxx,
- Source/cmInstallTargetGenerator.h,
- Source/cmInstallTargetsCommand.cxx: ENH: Further refinement of
- the CPack components functionality from Doug Gregor.
-
- Details: ==========
-
- - New cpack_add_component, cpack_add_component_group, and
- cpack_add_install_type "commands" defined as macros in the CPack
- module. - Documentation for all of the variables and commands
- in the CPack module. - Added get_cmake_property(... COMPONENTS)
- to CMake to ask for the names of all components. Used in the
- CPack module to automatically build component-based installers.
- (Set CPACK_MONOLITHIC_INSTALL to turn off component-based
- installation). - A group can declare its PARENT_GROUP, to build
- an arbitrary hierarchy of groups. - New CPack command
- cpack_configure_downloads, which creates an installer that
- downloads only the selected components on-the-fly. Those
- components marked DOWNLOADED will be separate packages downloaded
- on-the-fly (or, all packages can be marked as such with the ALL
- option to cpack_configure_downloads). Individual components are
- compressed with ZIP at installer-creation time and
- downloaded/uncompressed by the installer as needed. This feature
- is only available on Windows with NSIS at the moment. - NSIS
- installers can install themselves and enable the "Change" button
- in Add/Remove programs, allowing users to go back and install or
- remove components. This can be disabled through
- cpack_configure_downloads, because it's only really useful is
- most of the application's functionality is in downloaded
- components. - Bug fix: automatically install everything whose
- COMPONENT was not specified (it's a hidden, required group) -
- Bug fix: fixed removal of components when re-running the NSIS
- installer and unchecking components - Bug fix: NSIS installers
- now only install/remove the minimal number of files when re-run
- to update the installation (or by clicking "Change" in Add/Remove
- programs)
-
-2008-07-07 23:53 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-07 15:07 hoffman
-
- * Source/cmBootstrapCommands.cxx, Source/cmCommands.cxx,
- Tests/CMakeLists.txt: ENH: add get_test_property to bootstrap so
- bootstrap builds test the same as non-bootstrap builds
-
-2008-07-07 13:12 king
-
- * Source/cmGlobalXCodeGenerator.cxx: BUG: Do not build
- human-reference files in Xcode
-
- - The Info.plist file in app bundles should not be built.
- - User-specified files such as foo.txt should not be built.
- - Only files with a recognized language should be built,
- just as in the Makefiles generators.
- - See bug #7277.
-
-2008-07-07 10:57 king
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: Add projectRoot to Xcode
- projects
-
- - This attribute points Xcode at the source tree.
- - Xcode 3 wants this to be set always.
- - See bug #7044.
-
-2008-07-07 10:05 king
-
- * Source/cmGlobalXCodeGenerator.cxx: BUG: Fix AppBundle=>Library
- depends in Xcode
-
- - The Xcode generator xcode-depend-helper needs to account
- for the paths of executables within application bundles.
- - See bug #7278.
-
-2008-07-06 23:54 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-06 22:06 hoffman
-
- * Source/CTest/cmCTestTestHandler.cxx: COMP: fix warning
-
-2008-07-06 20:03 hoffman
-
- * Source/CTest/cmCTestMultiProcessHandler.h: COMP: fix some more
- warnings
-
-2008-07-06 19:58 hoffman
-
- * Source/CTest/: cmCTestTestHandler.cxx, cmCTestTestHandler.h:
- COMP: fix a few more warnings
-
-2008-07-06 04:57 miguelf
-
- * Modules/FindwxWidgets.cmake: BUG: Add new library richtext.
- Reported in #7284 thanks to earith.
-
-2008-07-05 23:54 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-05 13:25 clinton
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, CMakeSetupDialog.h,
- CMakeSetupDialog.ui:
- ENH: Replace Advanced checkbox and group option in menu with a
- combo box to choose view type.
-
-2008-07-05 11:57 clinton
-
- * Modules/FindQt4.cmake:
- BUG: Watch for empty qconfig.pri files. Fixes #7287.
-
-2008-07-05 09:29 hoffman
-
- * Source/cmGlobalGenerator.cxx: COMP: fix warning
-
-2008-07-04 23:54 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-04 10:28 hoffman
-
- * Source/CTest/: cmCTestMultiProcessHandler.cxx,
- cmCTestMultiProcessHandler.h, cmCTestTestHandler.cxx: COMP: try
- to fix sgi compiler problem with set and also shorten symbol
- lengths for set class
-
-2008-07-04 10:10 hoffman
-
- * Source/CTest/cmCTestTestHandler.cxx: COMP: fix more warnings
-
-2008-07-04 09:55 hoffman
-
- * Source/CTest/cmCTestTestHandler.cxx: COMP: fix warning
-
-2008-07-04 09:50 hoffman
-
- * Source/: cmCTest.cxx, CTest/cmCTestTestHandler.cxx: COMP: fix
- some warnings
-
-2008-07-03 23:54 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-03 18:19 dgregor
-
- * Modules/FindBoost.cmake: COMP: Find Boost as installed by the
- BoostPro/Boost Consulting installers on Windows
-
-2008-07-03 16:26 hoffman
-
- * Source/CTest/cmCTestMultiProcessHandler.cxx: ENH: one more fix
- for the old hp c++ compiler
-
-2008-07-03 15:49 dgregor
-
- * Modules/FindBoost.cmake: ENH: Cleanup FindBoost module, fixing
- several small bugs and providing better diagnostic information
- when things go wrong
-
-2008-07-03 15:46 king
-
- * Tests/CMakeLists.txt: BUG: Replace non-bootstrap command with
- macro
-
- - The GET_TEST_PROPERTY command does not exist during
- bootstrap.
- - Instead of lots of conditionals, replace it with a macro.
-
-2008-07-03 15:02 hoffman
-
- * Source/CTest/cmProcess.cxx: ENH: one more fix for hp
-
-2008-07-03 14:38 king
-
- * Tests/CMakeLists.txt: ENH: Remove condition on use of CMake 2.4
- commands
-
- - Commands SET_TESTS_PROPERTIES and GET_TEST_PROPERTY exist
- in CMake 2.4, which is now required.
- - Therefore we need not check before using them.
-
-2008-07-03 14:34 king
-
- * Tests/CMakeLists.txt: COMP: Don't set properties on a
- non-existing test
-
- - Test SubProject-Stage2 is conditionally created.
- - Set properties on it only if it exists.
-
-2008-07-03 13:55 hoffman
-
- * Source/CTest/cmProcess.h: ENH: fix for old hp compiler
-
-2008-07-03 13:55 king
-
- * Source/cmake.cxx: ENH: Do not auto-create out-dated cache
- variables
-
- - We used to always put LIBRARY_OUTPUT_PATH and
- EXECUTABLE_OUTPUT_PATH
- in the cache if the project did not.
- - In CMake 2.6 these variables should no longer be used.
- - Now add them only if CMAKE_BACKWARDS_COMPATIBILITY is also
- cached.
- - This happens only when CMP0001 is set to OLD or WARN or if
- the user or project sets it. In any case compatibility is
- needed.
- - Reported by Miguel A. Figueroa-Villanueva and Philip Lowman.
-
-2008-07-03 13:28 king
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h:
- BUG: Fix Xcode reference to Info.plist resource
-
- - Generated Xcode projects for application bundles list the
- CMake-generated Info.plist input file as a resource.
- - The location of the input file was moved by a previous
- commit,
- but the reference to it as a resource file was not updated.
- - This change moves the file to CMakeFiles/<tgt>.dir/Info.plist
- to give it a more intuitive name in the Xcode project.
- - We also update the reference to point at the correct
- location.
- - See bug #7277.
-
-2008-07-03 13:28 king
-
- * Source/cmGlobalXCodeGenerator.cxx: BUG: Fix Xcode per-config
- bundle name in Info.plist
-
- - The Xcode generator creates one Info.plist input file which
- is
- converted at build time by Xcode and placed in the final
- bundle.
- - The <CONFIG>_OUTPUT_NAME target property can place different
- content
- for the exe name in Info.plist on a per-configuration basis.
- - Instead of generating a per-config Info.plist input file just
- let
- Xcode put the name in at build time using the
- $(EXECUTABLE_NAME) var.
-
-2008-07-03 09:49 hoffman
-
- * Source/CTest/: cmProcess.cxx, cmProcess.h: ENH: add missing file
-
-2008-07-03 09:31 hoffman
-
- * Source/CMakeLists.txt, Source/cmCTest.cxx, Source/cmCTest.h,
- Source/cmGlobalGenerator.cxx,
- Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/CTest/cmCTestGenericHandler.cxx,
- Source/CTest/cmCTestMultiProcessHandler.cxx,
- Source/CTest/cmCTestMultiProcessHandler.h,
- Source/CTest/cmCTestTestHandler.cxx,
- Source/CTest/cmCTestTestHandler.h, Tests/CMakeLists.txt: ENH: add
- initial ctest -j feature
-
-2008-07-02 23:54 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-01 23:54 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-07-01 10:58 hoffman
-
- * CMakeCPackOptions.cmake.in: ENH: fix install in add/remove
- programs, again...
-
-2008-06-30 23:55 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-30 16:10 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/FindGettext.cmake,
- Modules/FindKDE4.cmake, Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmMakefile.cxx, Source/cmMakefile.h: ENH: check in RC 6
- merges from trunk
-
-2008-06-30 14:29 clinton
-
- * Source/QtDialog/QCMakeCacheView.cxx:
- BUG: Fix column widths on some systems.
-
-2008-06-30 09:57 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: Do not escape make
- variable references in VS additional options.
-
-2008-06-29 23:55 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-29 18:58 alex
-
- * Modules/FindGettext.cmake: BUG: fix 7230: don't ignore first
- parameter if it's not ALL
-
- Alex
-
-2008-06-28 23:55 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-28 11:16 martink
-
- * Source/: cmIfCommand.cxx, cmIfCommand.h, cmWhileCommand.cxx: BUG:
- fix memory leak and cleanup error string code
-
-2008-06-27 23:55 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-26 23:55 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-26 13:30 king
-
- * Source/: cmMakefile.cxx, cmMakefile.h: BUG: Fix computed
- directory property DEFINITIONS.
-
- - The property tracks the value formed by add_definitions
- and remove_definitions command invocations.
- - The string should be maintained for use in returning for the
- DEFINITIONS property value.
- - It is no longer used for any other purpose.
- - The DEFINITIONS property was recently documented as
- deprecated.
- - See bug #7239.
-
-2008-06-26 13:14 hoffman
-
- * Modules/FindKDE4.cmake: BUG: don't run KDE4_KDECONFIG_EXECUTABLE
- if it is notfound
-
-2008-06-26 13:01 martink
-
- * Source/cmIfCommand.cxx, Source/cmListFileCache.cxx,
- Tests/Complex/CMakeLists.txt, Tests/Complex/cmTestConfigure.h.in,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexOneConfig/cmTestConfigure.h.in,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/CMakeLists.txt,
- Tests/ComplexRelativePaths/cmTestConfigure.h.in,
- Tests/ComplexRelativePaths/Executable/complex.cxx: ENH: support
- parenthesis as arguments and in conditionals feature request
- #6191
-
-2008-06-26 10:58 king
-
- * Source/: cmGetDirectoryPropertyCommand.h, cmMakefile.cxx: ENH:
- Update documentation of computed directory properites.
-
- - Fix documentation of get_directory_property command.
- - Convert its list of computed directory properties to be
- defined/documented directory properties.
-
-2008-06-26 10:58 king
-
- * Source/cmMakefile.cxx: BUG: Fix PARENT_DIRECTORY property in
- top-level to not crash.
-
-2008-06-25 23:55 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-25 09:51 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/CPack.Info.plist.in,
- Modules/CPack.cmake, Modules/CPack.distribution.dist.in,
- Modules/FindBLAS.cmake, Modules/FindFLTK.cmake,
- Modules/FindKDE3.cmake, Modules/FindMatlab.cmake,
- Modules/FindOpenSSL.cmake, Modules/FindQt3.cmake,
- Modules/FindSWIG.cmake, Modules/FindwxWidgets.cmake,
- Modules/NSIS.template.in, Source/CMakeLists.txt,
- Source/cmFLTKWrapUICommand.cxx, Source/cmFindPackageCommand.cxx,
- Source/cmLocalVisualStudio7Generator.cxx, Source/cmake.cxx,
- Source/cmake.h, Source/CPack/cmCPackBundleGenerator.cxx,
- Source/CPack/cmCPackBundleGenerator.h,
- Source/CPack/cmCPackComponentGroup.h,
- Source/CPack/cmCPackGenerator.cxx,
- Source/CPack/cmCPackGenerator.h,
- Source/CPack/cmCPackGeneratorFactory.cxx,
- Source/CPack/cmCPackNSISGenerator.cxx,
- Source/CPack/cmCPackNSISGenerator.h,
- Source/CPack/cmCPackPackageMakerGenerator.cxx,
- Source/CPack/cmCPackPackageMakerGenerator.h,
- Source/CTest/cmCTestBuildAndTestHandler.cxx,
- Source/CTest/cmCTestTestHandler.cxx,
- Source/QtDialog/CMakeSetupDialog.cxx,
- Source/QtDialog/CMakeSetupDialog.h,
- Source/QtDialog/CMakeSetupDialog.ui,
- Source/QtDialog/QCMakeCacheView.cxx,
- Source/QtDialog/QCMakeCacheView.h, Tests/CMakeLists.txt,
- Tests/CPackComponents/CMakeLists.txt,
- Tests/CPackComponents/VerifyResult.cmake,
- Tests/CPackComponents/mylib.cpp, Tests/CPackComponents/mylib.h,
- Tests/CPackComponents/mylibapp.cpp,
- Tests/FindModulesExecuteAll/CMakeLists.txt,
- Tests/FindModulesExecuteAll/main.c,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: merge in changes from
- main tree
-
-2008-06-25 09:44 hoffman
-
- * Source/cmMakefile.cxx: BUG: fix for bug 7239, DEFINITIONS
- property not backwards compatible to 2.4
-
-2008-06-24 23:56 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-24 16:47 hoffman
-
- * Modules/Platform/Windows-cl.cmake: ENH: undo optional because we
- need it
-
-2008-06-24 15:50 hoffman
-
- * Modules/Platform/Windows-cl.cmake: ENH: rc is not so optional at
- least with 2005 and newer, as it is used to embed the manifest
- files
-
-2008-06-24 00:00 clinton
-
- * Source/QtDialog/QCMakeCacheView.cxx:
- BUG: Don't create empty property. Fixes bug #7193.
-
-2008-06-23 23:55 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-23 13:37 hoffman
-
- * Modules/Platform/Windows-cl.cmake: ENH: make rc optional
-
-2008-06-23 11:08 hoffman
-
- * Source/cmFLTKWrapUICommand.cxx: BUG: fix for bug 7228
- FLTK_WRAP_UI segfault fixed
-
-2008-06-22 23:55 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-21 23:56 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-20 23:56 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-20 16:25 hoffman
-
- * Source/: cmake.h, cmake.cxx: BUG: fix for bug 7222 manifest:no
- not working for makefiles
-
-2008-06-19 23:56 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-19 11:08 david.cole
-
- * Tests/CMakeLists.txt: BUG: Avoid running the new CPackComponents
- test on Windows unless the NSIS installer is available.
-
-2008-06-19 06:17 hoffman
-
- * Source/CPack/cmCPackBundleGenerator.cxx: file
- cmCPackBundleGenerator.cxx was added on branch CMake-2-6 on
- 2008-06-25 13:51:32 +0000
-
-2008-06-19 06:17 david.cole
-
- * Source/CPack/cmCPackBundleGenerator.cxx: COMP: Eliminate
- unreferenced variable warning
-
-2008-06-18 23:56 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-18 19:02 alex
-
- * Modules/FindKDE3.cmake: BUG: modify the compiler flags only if
- KDE3 has actually been found
-
- Alex
-
-2008-06-18 18:57 alex
-
- * Modules/FindKDE3.cmake: STYLE: use uppercase to be consistent
- with the rest of the file
-
- Alex
-
-2008-06-18 16:39 alex
-
- * Modules/FindKDE3.cmake: BUG: the variable is _KDE4_USE_FLAGS ENH:
- I guess this is also true for gcc 2.95 ?
-
- Alex
-
-2008-06-18 16:00 david.cole
-
- * Source/CPack/cmCPackGenerator.cxx: COMP: Eliminate compiler
- warning on 64-bit build.
-
-2008-06-18 14:25 david.cole
-
- * Source/CPack/cmCPackNSISGenerator.cxx: BUG: Always look for the
- NSIS reg value in the 32-bit hive even in 64-bit builds of CPack.
-
-2008-06-18 13:28 hoffman
-
- * Source/cmake.cxx: ENH: support large object file lists with
- incremental visual studio linking
-
-2008-06-18 12:23 hoffman
-
- * Modules/FindKDE3.cmake: ENH: use correct variable
-
-2008-06-18 09:53 hoffman
-
- * Source/CPack/cmCPackBundleGenerator.h: file
- cmCPackBundleGenerator.h was added on branch CMake-2-6 on
- 2008-06-25 13:51:33 +0000
-
-2008-06-18 09:53 david.cole
-
- * Modules/CPack.cmake, Source/CMakeLists.txt,
- Source/CPack/cmCPackBundleGenerator.cxx,
- Source/CPack/cmCPackBundleGenerator.h,
- Source/CPack/cmCPackGeneratorFactory.cxx: ENH: Apply patch for
- feature request #7170. Thanks to Tim Shead for contributing...
-
-2008-06-18 09:28 hoffman
-
- * Tests/CPackComponents/VerifyResult.cmake: file VerifyResult.cmake
- was added on branch CMake-2-6 on 2008-06-25 13:51:58 +0000
-
-2008-06-18 09:28 david.cole
-
- * Tests/CPackComponents/VerifyResult.cmake: BUG: Be more specific
- about the expected file name of the installer. (So we don't get
- mylibapp.exe in our GLOB results in make based build trees where
- the built exes end up in the same directory as the CPack
- installers...)
-
-2008-06-18 09:22 hoffman
-
- * Modules/FindKDE3.cmake: ENH: fix for findall
-
-2008-06-18 09:07 hoffman
-
- * Source/CTest/cmCTestBuildAndTestHandler.cxx: BUG: make sure ctest
- sees the output of the cmake run in build and test cases, it was
- not...
-
-2008-06-18 08:42 hoffman
-
- * Modules/FindKDE3.cmake: ENH: try to module run test
-
-2008-06-18 08:37 hoffman
-
- * Modules/: FindKDE3.cmake, FindQt3.cmake: ENH: try to module run
- test
-
-2008-06-18 07:08 hoffman
-
- * Modules/CPack.distribution.dist.in: file
- CPack.distribution.dist.in was added on branch CMake-2-6 on
- 2008-06-25 13:51:31 +0000
-
-2008-06-18 07:08 david.cole
-
- * Modules/CPack.distribution.dist.in,
- Source/CPack/cmCPackPackageMakerGenerator.cxx,
- Source/CPack/cmCPackPackageMakerGenerator.h: BUG: Workaround
- PackageMaker 3.0 issue for new CPack components feature. Thanks
- again to Doug Gregor for the patch.
-
-2008-06-17 23:56 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-17 21:46 hoffman
-
- * Modules/FindSWIG.cmake: ENH: no fatal error if not required
-
-2008-06-17 18:02 miguelf
-
- * Modules/FindwxWidgets.cmake: ENH: Added support for MSYS as a
- unix style search.
-
-2008-06-17 14:07 david.cole
-
- * Source/CPack/cmCPackNSISGenerator.cxx: COMP: Use cmOStringStream
- instead of std::ostringstream for the HP compiler.
-
-2008-06-17 14:03 hoffman
-
- * Source/CTest/cmCTestTestHandler.cxx: BUG: fix for bug 7136
-
-2008-06-17 13:27 hoffman
-
- * Modules/FindBLAS.cmake: ENH: make find blas work if there is no
- fortran compiler
-
-2008-06-17 13:13 hoffman
-
- * Source/cmake.cxx: ENH: add an enabled language property
-
-2008-06-17 12:44 david.cole
-
- * Source/CPack/: cmCPackGenerator.cxx, cmCPackNSISGenerator.cxx:
- COMP: Fix errors and warnings from continuous dashboards running
- different compilers...
-
-2008-06-17 12:09 david.cole
-
- * Source/CPack/cmCPackGenerator.h: COMP: Include full class
- definitions of classes used in std::map data members.
-
-2008-06-17 11:39 hoffman
-
- * Tests/CPackComponents/CMakeLists.txt: file CMakeLists.txt was
- added on branch CMake-2-6 on 2008-06-25 13:51:58 +0000
-
-2008-06-17 11:39 hoffman
-
- * Source/CPack/cmCPackComponentGroup.h: file
- cmCPackComponentGroup.h was added on branch CMake-2-6 on
- 2008-06-25 13:51:35 +0000
-
-2008-06-17 11:39 hoffman
-
- * Tests/CPackComponents/mylib.cpp: file mylib.cpp was added on
- branch CMake-2-6 on 2008-06-25 13:51:58 +0000
-
-2008-06-17 11:39 hoffman
-
- * Tests/CPackComponents/mylib.h: file mylib.h was added on branch
- CMake-2-6 on 2008-06-25 13:51:58 +0000
-
-2008-06-17 11:39 hoffman
-
- * Tests/CPackComponents/mylibapp.cpp: file mylibapp.cpp was added
- on branch CMake-2-6 on 2008-06-25 13:51:58 +0000
-
-2008-06-17 11:39 david.cole
-
- * Modules/CPack.Info.plist.in, Modules/CPack.distribution.dist.in,
- Modules/NSIS.template.in, Source/CPack/cmCPackGenerator.cxx,
- Source/CPack/cmCPackGenerator.h,
- Source/CPack/cmCPackComponentGroup.h,
- Source/CPack/cmCPackNSISGenerator.cxx,
- Source/CPack/cmCPackNSISGenerator.h,
- Source/CPack/cmCPackPackageMakerGenerator.cxx,
- Source/CPack/cmCPackPackageMakerGenerator.h,
- Tests/CMakeLists.txt, Tests/CPackComponents/CMakeLists.txt,
- Tests/CPackComponents/VerifyResult.cmake,
- Tests/CPackComponents/mylib.cpp, Tests/CPackComponents/mylib.h,
- Tests/CPackComponents/mylibapp.cpp,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: Add patch for feature
- request #6847 - CPack components for NSIS and PackageMaker
- installers. Thanks to Doug Gregor for all the hard work involved
- with implementing this patch! Also added new test CPackComponents
- that is conditionally executed only when NSIS or PackageMaker
- installer builders are available.
-
-2008-06-17 11:29 hoffman
-
- * Modules/FindBLAS.cmake: STYLE: fix indent for file
-
-2008-06-17 10:58 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: fix for bug 6619
-
-2008-06-17 10:51 hoffman
-
- * Tests/CMakeLists.txt: ENH: try turning this on again
-
-2008-06-16 23:56 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-16 20:10 hoffman
-
- * Tests/CMakeLists.txt: ENH: turn this off until it passes on all
- systems
-
-2008-06-16 20:05 hoffman
-
- * Tests/FindModulesExecuteAll/CMakeLists.txt: ENH: add a project
- name
-
-2008-06-16 20:05 hoffman
-
- * Tests/FindModulesExecuteAll/CMakeLists.txt: file CMakeLists.txt
- was added on branch CMake-2-6 on 2008-06-25 13:51:58 +0000
-
-2008-06-16 18:37 alex
-
- * Modules/FindOpenSSL.cmake: BUG: don't fail with FATAL_ERROR if
- REQUIRED was not used
-
- Alex
-
-2008-06-16 15:19 hoffman
-
- * Modules/FindFLTK.cmake, Modules/FindKDE3.cmake,
- Modules/FindMatlab.cmake,
- Tests/FindModulesExecuteAll/CMakeLists.txt: ENH: fix find module
- stuff for test
-
-2008-06-16 14:15 miguelf
-
- * Modules/FindwxWidgets.cmake: BUG: Fix so that MinGW use
- win32_find_style (6478). Also, consolidated search styles
- selection into a single variable, so that they are mutually
- exclusive.
-
-2008-06-16 14:03 hoffman
-
- * Tests/FindModulesExecuteAll/main.c: file main.c was added on
- branch CMake-2-6 on 2008-06-25 13:52:00 +0000
-
-2008-06-16 14:03 alex
-
- * Tests/: CMakeLists.txt, FindModulesExecuteAll/CMakeLists.txt,
- FindModulesExecuteAll/main.c: ENH: add test which executes all
- FindXXX.cmake modules
-
- Alex
-
-2008-06-15 23:56 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-14 23:56 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-13 23:56 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-13 16:57 clinton
-
- * Source/QtDialog/QCMakeCacheView.cxx:
- ENH: remove red blending. It didn't look good on some systems.
-
-2008-06-13 16:33 miguelf
-
- * Modules/FindwxWidgets.cmake: BUG: Fixed incorrectly matched
- FOREACH (7008).
-
-2008-06-13 15:29 clinton
-
- * Source/QtDialog/QCMakeCacheView.cxx:
- ENH: instead of solid red for new entries, blend it with the
- alternating white/gray (depending on style).
-
-2008-06-13 11:19 clinton
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, CMakeSetupDialog.h,
- QCMakeCacheView.cxx, QCMakeCacheView.h:
- ENH: Make original flat view the default. Add option to
- switch to grouped view (and remember it).
-
-2008-06-13 10:15 hoffman
-
- * Source/cmVersion.cxx: ENH: remove beta stuff from version
-
-2008-06-13 08:55 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Modules/CMakeFindBinUtils.cmake, Modules/CPack.RuntimeScript.in,
- Modules/FindCurses.cmake, Modules/FindFreetype.cmake,
- Modules/FindGDAL.cmake, Modules/FindGIF.cmake,
- Modules/FindKDE3.cmake, Modules/FindKDE4.cmake,
- Modules/FindLua50.cmake, Modules/FindLua51.cmake,
- Modules/FindOpenAL.cmake, Modules/FindOpenThreads.cmake,
- Modules/FindPhysFS.cmake, Modules/FindProducer.cmake,
- Modules/FindQt3.cmake, Modules/FindQt4.cmake,
- Modules/FindQuickTime.cmake, Modules/FindSDL.cmake,
- Modules/FindSDL_image.cmake, Modules/FindSDL_mixer.cmake,
- Modules/FindSDL_net.cmake, Modules/FindSDL_sound.cmake,
- Modules/FindSDL_ttf.cmake, Modules/FindTCL.cmake,
- Modules/FindTclsh.cmake, Modules/FindWish.cmake,
- Modules/FindXMLRPC.cmake, Modules/Findosg.cmake,
- Modules/FindosgDB.cmake, Modules/FindosgFX.cmake,
- Modules/FindosgGA.cmake, Modules/FindosgIntrospection.cmake,
- Modules/FindosgManipulator.cmake, Modules/FindosgParticle.cmake,
- Modules/FindosgProducer.cmake, Modules/FindosgShadow.cmake,
- Modules/FindosgSim.cmake, Modules/FindosgTerrain.cmake,
- Modules/FindosgText.cmake, Modules/FindosgUtil.cmake,
- Modules/FindosgViewer.cmake,
- Source/cmAddCustomCommandCommand.cxx,
- Source/cmAddCustomCommandCommand.h, Source/cmCustomCommand.cxx,
- Source/cmCustomCommand.h, Source/cmFindBase.cxx,
- Source/cmFindBase.h, Source/cmFindCommon.cxx,
- Source/cmFindCommon.h, Source/cmFindLibraryCommand.cxx,
- Source/cmFindLibraryCommand.h, Source/cmFindPackageCommand.cxx,
- Source/cmFindPackageCommand.h, Source/cmFindPathCommand.cxx,
- Source/cmFindPathCommand.h, Source/cmFindProgramCommand.cxx,
- Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmGlobalUnixMakefileGenerator3.h,
- Source/cmGlobalXCodeGenerator.cxx, Source/cmMakefile.cxx,
- Source/cmMakefileTargetGenerator.cxx, Source/cmake.cxx,
- Source/CTest/cmCTestTestHandler.cxx,
- Source/kwsys/DynamicLoader.cxx,
- Source/kwsys/SystemInformation.cxx, Source/kwsys/Terminal.c,
- Tests/CMakeTests/FindBaseTest.cmake.in,
- Tests/CMakeTests/A/include/cmake_i_do_not_exist_in_the_system.h,
- Tests/CustomCommand/CMakeLists.txt, Tests/CustomCommand/foo.in,
- Tests/CustomCommand/gen_once.c.in,
- Tests/CustomCommand/wrapper.cxx,
- Tests/FindPackageTest/CMakeLists.txt,
- Tests/FindPackageTest/A/wibble-config.cmake,
- Tests/FindPackageTest/B/wibble-config.cmake: ENH: merge in
- changes from head
-
-2008-06-12 23:57 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-11 23:57 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-11 15:08 clinton
-
- * Source/QtDialog/QCMakeCacheView.cxx: ENH: better name for
- ungrouped entries.
-
-2008-06-11 14:47 clinton
-
- * Source/QtDialog/QCMakeCacheView.cxx:
- BUG: need to invalidate filtering when using Qt 4.3+.
-
-2008-06-10 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-10 22:19 clinton
-
- * Source/QtDialog/CMakeSetupDialog.cxx:
- ENH: Add items under the Options menu for collapsing and
- expanding the variable tree.
-
-2008-06-10 20:17 clinton
-
- * Source/QtDialog/QCMakeCacheView.cxx: ENH: Give a label for the
- group of properties that didn't get put into another group.
-
-2008-06-10 18:53 clinton
-
- * Source/QtDialog/QCMakeCacheView.cxx:
- ENH: group together items with no prefix and items that won't be
- grouped with others.
-
-2008-06-10 18:28 alex
-
- * Source/cmGlobalGenerator.cxx: BUG: -fail with error if the
- CMake<LANG>Information.cmake file wasn't found ENH: -if no
- compiler has been found, don't test it, and also remove the
- compiler information file again. This makes optionally enabling a
- language work better.
-
- Alex
-
-2008-06-10 13:22 king
-
- * Source/cmFindBase.cxx: BUG: In find_* commands support NO_*
- options in short-hand
-
- - The short-hand forms do not document the NO_* options.
- - CMake 2.4 and 2.6.0 accepted them accidentally, but also
- treated the options as paths.
- - Now the options are accepted but do not become paths.
-
-2008-06-10 00:17 clinton
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, CMakeSetupDialog.ui,
- QCMakeCacheView.cxx, QCMakeCacheView.h:
- ENH: Use a tree view of the properties instead of a flat list
- view. Properties are grouped by a prefix (up to first "_")
- and can be expanded or collapsed.
-
- Fixes #6359.
-
-2008-06-09 23:57 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-09 16:04 king
-
- * Modules/: CMakeFindBinUtils.cmake, FindCurses.cmake,
- FindFreetype.cmake, FindGDAL.cmake, FindGIF.cmake,
- FindKDE3.cmake, FindKDE4.cmake, FindLua50.cmake, FindLua51.cmake,
- FindOpenAL.cmake, FindOpenThreads.cmake, FindPhysFS.cmake,
- FindProducer.cmake, FindQt3.cmake, FindQuickTime.cmake,
- FindSDL.cmake, FindSDL_image.cmake, FindSDL_mixer.cmake,
- FindSDL_net.cmake, FindSDL_sound.cmake, FindSDL_ttf.cmake,
- FindTCL.cmake, FindTclsh.cmake, FindWish.cmake, FindXMLRPC.cmake,
- Findosg.cmake, FindosgDB.cmake, FindosgFX.cmake, FindosgGA.cmake,
- FindosgIntrospection.cmake, FindosgManipulator.cmake,
- FindosgParticle.cmake, FindosgProducer.cmake,
- FindosgShadow.cmake, FindosgSim.cmake, FindosgTerrain.cmake,
- FindosgText.cmake, FindosgUtil.cmake, FindosgViewer.cmake: ENH:
- Cleanup Find* modules with new HINTS feature
-
- - The find_* commands now provide a HINTS option.
- - The option specifies paths to be preferred over the system
- paths.
- - Many Find* modules were using two find calls with
- NO_DEFAULT_PATH
- to approximate the behavior, but that blocked users from
- overriding
- things with CMAKE_PREFIX_PATH.
- - This commit uses the HINTS feature to get desired behavior in
- only one find command call.
-
-2008-06-09 15:50 alex
-
- * Modules/CPack.RuntimeScript.in: STYLE: apply patch from Thomas
- Klausner (NetBSD): use "=" for testing strings for equality
- instead of "=="
-
- This also matches what the man page for test says "s1 = s2
- True if the strings s1 and s2 are identical."
-
- Alex
-
-2008-06-09 15:22 king
-
- * Source/: cmFindBase.cxx, cmFindPackageCommand.cxx: ENH: Make
- find_* command search order more intuitive.
-
- - The CMAKE_PREFIX_PATH and similar variables have both
- environment and CMake cache versions.
- - Previously the environment value was checked before the
- cache value.
- - Now the cache value is favored because it is more specific.
-
-2008-06-09 15:09 hoffman
-
- * Tests/FindPackageTest/: A/wibble-config.cmake,
- B/wibble-config.cmake: file wibble-config.cmake was added on
- branch CMake-2-6 on 2008-06-13 12:55:19 +0000
-
-2008-06-09 15:09 hoffman
-
- * Tests/CMakeTests/A/include/cmake_i_do_not_exist_in_the_system.h:
- file cmake_i_do_not_exist_in_the_system.h was added on branch
- CMake-2-6 on 2008-06-13 12:55:18 +0000
-
-2008-06-09 15:09 king
-
- * Tests/:
- CMakeTests/A/include/cmake_i_do_not_exist_in_the_system.h,
- CMakeTests/FindBaseTest.cmake.in, FindPackageTest/CMakeLists.txt,
- FindPackageTest/A/wibble-config.cmake,
- FindPackageTest/B/wibble-config.cmake: ENH: Add test for new
- find_* command HINTS option.
-
-2008-06-09 15:08 king
-
- * Source/: cmFindBase.cxx, cmFindBase.h, cmFindCommon.cxx,
- cmFindCommon.h, cmFindPackageCommand.cxx, cmFindPackageCommand.h:
- ENH: Add HINTS option to find_* commands.
-
- - Hints are searched after user locations but before system
- locations
- - The HINTS option should have paths provided by system
- introspection
- - The PATHS option should have paths that are hard-coded
- guesses
-
-2008-06-09 12:51 king
-
- * Source/cmFindPathCommand.cxx: ENH: Improve framework search speed
- for find_file and find_path
-
- - Locating a header inside a framework often requires globbing
- - Previously the glob was <dir>/*/Headers/<name>
- - Now the glob is <dir>/*.framework/Headers/<name>
- - This is much faster when <dir> is not really a framework dir
-
-2008-06-09 11:58 king
-
- * Source/: cmFindBase.cxx, cmFindBase.h, cmFindLibraryCommand.cxx,
- cmFindLibraryCommand.h, cmFindPathCommand.cxx,
- cmFindPathCommand.h, cmFindProgramCommand.cxx: ENH: Refactor
- find_* command framework/appbundle search order impl.
-
- - CMAKE_FIND_FRAMEWORK and CMAKE_FIND_APPBUNDLE are supposed to
- specify
- whether to find frameworks/appbundles FIRST, LAST, ONLY, or
- NEVER.
- - Previously this affected only the placement of
- CMAKE_FRAMEWORK_PATH
- and CMAKE_APPBUNDLE_PATH with respect to the other path
- specifiers.
- - Now it behaves as documented. The entire search path is
- inspected for
- each kind of program, library, or header before trying the
- next kind.
- - Additionally the ONLY mode is now honored for headers so that
- users
- do not end up with a library in framework and a header from
- elsewhere.
-
-2008-06-09 11:57 king
-
- * Source/: cmFindBase.cxx, cmFindCommon.cxx, cmFindCommon.h,
- cmFindLibraryCommand.cxx, cmFindPackageCommand.cxx,
- cmFindPathCommand.cxx: ENH: In find_* implementation centralize
- addition of trailing slashes
-
- - Create cmFindCommon::AddTrailingSlashes
- - Use it in cmFindBase and cmFindPackageCommand
- - Remove duplication from other find commands
-
-2008-06-08 23:57 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-08 11:41 king
-
- * Source/cmake.cxx: ENH: Whenever CMake re-runs from inside the VS
- IDE inform the user why.
-
-2008-06-08 11:41 king
-
- * Tests/CMakeTests/FindBaseTest.cmake.in: BUG: Fix CMake.FindBase
- test to normalize paths before comparing.
-
- - Previously the find_* commands did not normalize the search
- paths
- - The recent refactoring enabled such normalization
- - The FindBase test must also normalize before comparing paths
-
-2008-06-08 11:41 king
-
- * Source/cmFindBase.cxx: BUG: Fix find_* command calls with no
- PATHS but new-style options.
-
- - In cmFindBase when CheckCommonArgument returns true, set
- newStyle
- - Otherwise if there are no PATHS then the ancient-style
- compatibility
- mode is enabled and the common argument is treated as a path.
-
-2008-06-07 23:57 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-06 23:58 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-06 11:52 king
-
- * Source/kwsys/Terminal.c: ENH: Recognize more color terminals.
-
- - Patch from Matthew McCormick, slightly tweaked
- - See issue #6833
-
-2008-06-06 11:49 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: fix for flags that have
- sub-string matches
-
-2008-06-06 10:22 martink
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: ENH: fix for bug 6364,
- extra help targets when there are subdirectories of the top level
-
-2008-06-06 09:06 king
-
- * Source/cmFindBase.cxx: BUG: Fix cmFindBase::AddMacPath to
- actually use its arguments after previous refactoring commit.
-
-2008-06-06 01:36 clinton
-
- * Modules/FindQt4.cmake:
- BUG: Fix for #7118. Relative paths going outside the
- current source dir resulted in badly placed moc source
- files in the build dir (or out of the build dir).
-
-2008-06-05 23:57 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-05 18:20 king
-
- * Source/: cmFindBase.cxx, cmFindBase.h, cmFindCommon.cxx,
- cmFindCommon.h, cmFindPackageCommand.cxx, cmFindPackageCommand.h:
- ENH: Refactor cmFindCommon, cmFindBase, and cmFindPackageCommand
-
- - Add each part of the search order in a separate method.
- - Collect added paths in an ivar in cmFindCommon.
- - Move user path storage up to cmFindCommon and share
- between cmFindBase and cmFindPackageCommand.
- - Expand user path registry values up in cmFindCommon
- - Enables 32-/64-bit registry view for find_package
- - Disables registry expansion for paths not specified
- with the PATHS argument, which is not expected.
-
-2008-06-05 10:01 king
-
- * Tests/CustomCommand/wrapper.cxx: BUG: Fix new custom command with
- make-var expansion test on VS6. The VS6 IDE adds some extra
- characters to the variable value during expansion.
-
-2008-06-05 09:54 king
-
- * Source/cmFindBase.cxx: BUG: Fix 64-bit build of CMake so it can
- find 32-bit VS install.
-
- - cmFindBase should search both 32-bit and 64-bit registry
- views
- for FIND_PROGRAM even if CMAKE_SIZEOF_VOID_P is not set.
- - Needed because the variable is not available when
- CMAKE_MAKE_PROGRAM
- is to be found.
-
-2008-06-04 23:58 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-04 12:10 king
-
- * Tests/CustomCommand/: CMakeLists.txt, wrapper.cxx: ENH: Add test
- for make variable replacement in a custom command with the
- VERBATIM option.
-
-2008-06-04 12:10 king
-
- * Source/cmMakefile.cxx: ENH: Allow custom commands with VERBATIM
- option to have $(SomeVar) make variable replacement.
-
-2008-06-03 23:58 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-03 10:29 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Some Linux distros don't install xorg-devel, png-devel,
- etc... when qt4-devel is installed. Finding them was
- required to support building against static Qt. Changing
- it so they are ignored if not found.
-
-2008-06-03 10:02 king
-
- * Source/cmGlobalGenerator.cxx: COMP: Fix bootstrap build after
- previous change to signature of AddRuleHash.
-
-2008-06-03 09:55 king
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmMakefileTargetGenerator.cxx: BUG: Include less content as input
- to "rule hash" computation.
-
- - The rule hash should use only commands specified by the user.
- - No make output (echo and progress) rules should be included.
- - No outputs or dependencies need be included. The native
- build tool
- will take care of them.
-
-2008-06-02 23:58 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-02 19:44 clinton
-
- * Source/kwsys/DynamicLoader.cxx:
- BUG: FormatMessage can return a NULL message. Add check for
- NULL pointer.
-
-2008-06-02 16:45 king
-
- * Source/cmAddCustomCommandCommand.cxx,
- Source/cmAddCustomCommandCommand.h, Source/cmCustomCommand.cxx,
- Source/cmCustomCommand.h, Tests/CustomCommand/CMakeLists.txt,
- Tests/CustomCommand/foo.in, Tests/CustomCommand/gen_once.c.in:
- ENH: Remove SKIP_RULE_DEPENDS option from add_custom_command()
-
- - Option was recently added but never released.
- - Custom commands no longer depend on build.make so we do
- not need the option.
- - Rule hashes now take care of rebuilding when rules change
- so the dependency is not needed.
-
-2008-06-02 16:44 king
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmMakefileTargetGenerator.cxx: ENH: Introduce "rule hashes" to
- help rebuild files when rules change.
-
- - In CMake 2.4 custom commands would not rebuild when rules
- changed.
- - In CMake 2.6.0 custom commands have a dependency on
- build.make
- which causes them to rebuild when changed, but also when any
- source is added or removed. This is too often.
- - We cannot have a per-rule file because Windows filesystems
- do not deal well with lots of small files.
- - Instead we add a persistent CMakeFiles/CMakeRuleHashes.txt
- file
- at the top of the build tree that is updated during each
- CMake Generate step. It records a hash of the build rule for
- each file to be built. When the hash changes the file is
- removed so that it will be rebuilt.
-
-2008-06-02 14:53 ewing
-
- * Modules/FindLua51.cmake: BUG: fixed Lua50 to be Lua51 in
- FIND_PACKAGE_HANDLE_STANDARD_ARGS call.
-
-2008-06-02 09:39 martink
-
- * Source/cmMakefile.cxx: COMP: fix warning
-
-2008-06-01 23:58 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-06-01 23:40 hoffman
-
- * Source/kwsys/SystemInformation.cxx: ENH: fix crash on dash17
- linux where the parsing of the proc file must not have worked
- right
-
-2008-06-01 16:11 hoffman
-
- * Source/kwsys/SystemInformation.cxx: ENH: fix crash on cygwin
-
-2008-06-01 14:40 fbertel
-
- * Source/kwsys/SystemInformation.cxx: BUG:cpuinfo format are
- different between Linux and Cygwin. Cygwin does not have physical
- id tag or cpu cores tag.
-
-2008-06-01 11:23 hoffman
-
- * Source/kwsys/SystemInformation.cxx: ENH: avoid divide by zero,
- temporary fix until cygwin cpu file is read better, bad cpu info
- is better than a crash
-
-2008-05-31 23:58 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-31 11:23 fbertel
-
- * Source/kwsys/SystemInformation.cxx: BUG:Fixed NumberOfLogicalCPU,
- NumberOfPhysicalCPU and LogicalProcessorsPerPhysical under Linux.
- Some part was just wrong. Some other part missed to take the
- multicore value into account.
-
-2008-05-31 08:15 martink
-
- * Source/cmMakefile.cxx: ENH: make end of file checking for close
- if, foreach, macro, functions etc enabled. Not sure why it was
- disabled to start with, but I suspect I will find out. In reponse
- to Bill email about a ctest -S script with a function that waqs
- not closed. Closure was only checked for regular listfiles not
- other files.
-
-2008-05-30 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-30 09:14 martink
-
- * Source/CTest/cmCTestTestHandler.cxx: ENH: make tes test finding
- logic also try full paths as relative paths because some folks
- have been doing that and 2.4 handled it
-
-2008-05-29 23:58 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-29 11:50 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h: BUG: improve progress reporting
- when there are multiple targets with the same name, bug# 7042
-
-2008-05-29 09:15 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/FindQt4.cmake,
- Source/cmFileCommand.cxx, Source/cmFindBase.cxx,
- Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmInstallTargetGenerator.cxx, Source/cmSourceFile.cxx,
- Source/cmSystemTools.cxx, Source/cmSystemTools.h,
- Source/kwsys/SystemTools.cxx, Source/kwsys/SystemTools.hxx.in:
- ENH: merge in changes from head for RC 3
-
-2008-05-28 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-27 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-27 16:50 king
-
- * Source/cmFindBase.cxx: BUG: Fix previous registry lookup change
- for executables.
-
- - The target platform does not matter for finding executables
- so find_program should expand to both 32-bit and 64-bit
- registry
- values.
- - See issue #7095.
-
-2008-05-27 14:47 king
-
- * Source/cmFindBase.cxx: BUG: Fix registry lookups for FIND
- commands to use view of target platform.
-
- - See issue #7095.
-
-2008-05-27 14:46 king
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h,
- kwsys/SystemTools.cxx, kwsys/SystemTools.hxx.in: ENH: Added WOW64
- key view support to KWSys SystemTools' windows registry API.
-
- - Add an argument to registry read/write/delete methods to
- specify
- a 32-bit or 64-bit view.
- - Default is the bit-ness of the running program.
- - See issue #7095.
-
-2008-05-27 13:10 king
-
- * Source/cmSourceFile.cxx: ENH: Catch missing source files
- specified by full path earlier.
-
- - Revert previous change to trust user-provided full paths.
- - Instead trust them only far enough to determine the source
- language
- but still check for existence for non-generated sources.
-
-2008-05-27 11:18 king
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h: BUG: Fix
- crash on repeated configure steps and exported targets.
-
- - In cmGlobalGenerator the ExportSets ivar must be cleared at
- the beginning of each Configure.
- - See issue #7101.
-
-2008-05-27 10:22 king
-
- * Source/: cmFileCommand.cxx, cmSystemTools.cxx, cmSystemTools.h:
- ENH: Inform user when RPATH is set during installation.
-
- - Original patch from Alex.
- - Modified to print only when RPATH is actually set.
-
-2008-05-27 10:21 king
-
- * Source/cmInstallTargetGenerator.cxx: BUG: RPATH adjustment of
- versioned executables should operate on the file and not the
- symlink.
-
-2008-05-26 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-26 11:17 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Find debug libs from static Qt on Windows.
-
-2008-05-25 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-24 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-23 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-23 16:09 hoffman
-
- * CMakeCPack.cmake, CMakeLists.txt, ChangeLog.manual,
- Modules/CMakeDetermineASMCompiler.cmake,
- Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Modules/CMakeFortranCompilerId.F90.in,
- Modules/CMakeImportBuildSettings.cmake, Modules/FindQt4.cmake,
- Modules/FindSubversion.cmake, Modules/MacOSXBundleInfo.plist.in,
- Modules/UseQt4.cmake, Modules/Platform/Linux-PGI-Fortran.cmake,
- Source/cmFileCommand.cxx, Source/cmFindBase.cxx,
- Source/cmListCommand.cxx, Source/cmLocalGenerator.cxx,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmMakefileTargetGenerator.cxx, Source/cmSourceGroup.cxx,
- Source/cmSourceGroup.h, Source/cmTarget.cxx,
- Source/CTest/cmCTestTestHandler.cxx,
- Source/QtDialog/AddCacheEntry.cxx,
- Source/QtDialog/AddCacheEntry.h,
- Source/QtDialog/AddCacheEntry.ui,
- Source/QtDialog/CMakeFirstConfigure.cxx,
- Source/QtDialog/CMakeFirstConfigure.h,
- Source/QtDialog/CMakeFirstConfigure.ui,
- Source/QtDialog/CMakeLists.txt,
- Source/QtDialog/CMakeSetupDialog.cxx,
- Source/QtDialog/CMakeSetupDialog.h, Source/QtDialog/QCMake.cxx,
- Source/QtDialog/QCMake.h, Source/QtDialog/QCMakeCacheView.cxx,
- Source/QtDialog/QCMakeCacheView.h,
- Source/QtDialog/QCMakeWidgets.cxx,
- Source/QtDialog/QCMakeWidgets.h,
- Source/kwsys/RegularExpression.cxx,
- Source/kwsys/RegularExpression.hxx.in: ENH: push in changes from
- head
-
-2008-05-23 15:52 hoffman
-
- * Source/cmFindBase.cxx: ENH: better fix for not adding /
-
-2008-05-23 15:25 hoffman
-
- * Modules/FindQt4.cmake: ENH: use PATHS keyword
-
-2008-05-23 15:25 hoffman
-
- * Source/cmFindBase.cxx: BUG: 7011 findqt hangs because of glob
- with find_path and framework header serach
-
-2008-05-23 11:47 hoffman
-
- * CMakeCPack.cmake: ENH: do not put system name into cygwin package
-
-2008-05-23 11:28 hoffman
-
- * Source/CTest/cmCTestTestHandler.cxx: BUG: fix for bug 7077 handle
- DartMeasurement tags with tyep text/html
-
-2008-05-22 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-21 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-21 19:57 king
-
- * Source/cmMakefileTargetGenerator.cxx: BUG: Fix makefile generator
- to have link rules depend on all full path libraries that appear
- on the link line. This allows projects to relink when imported
- targets have changed.
-
-2008-05-21 14:02 king
-
- * Modules/CMakeImportBuildSettings.cmake: ENH: Extend previous
- patch from Mathieu Malaterre to apply override to the build tool
- also.
-
-2008-05-21 13:36 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Make Qt not found if the QtCore library can't be found.
- Also report an error when trying to use MSVC with Qt built by
- mingw.
-
-2008-05-21 10:50 hoffman
-
- * Source/cmVersion.cxx: ENH: fix version to not report beta for 1
-
-2008-05-21 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-20 12:35 hoffman
-
- * CMakeCPack.cmake: ENH: make sure Cygwin-Unknown is not the name
- for the package
-
-2008-05-20 12:15 hoffman
-
- * Source/cmListCommand.cxx: BUG: fix failing test
-
-2008-05-20 11:30 hoffman
-
- * Source/cmListCommand.cxx: BUG: fix bugs in new style list command
- that handles empty stuff
-
-2008-05-20 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-19 18:07 clinton
-
- * Modules/UseQt4.cmake:
- ENH: Similar to how qmake does it... Don't add compile
- flags for dependent modules the user didn't specify. But
- still add the link libs. This reduces the number of
- unecessary compile flags.
-
-2008-05-19 10:03 king
-
- * Modules/FindSubversion.cmake: BUG: Fixes for FindSubversion
-
- - Split log out from Subversion_WC_INFO into Subversion_WC_LOG
- - Fix report of log info to be in
- <var-prefix>_WC_LAST_CHANGED_LOG
- as documented (instead of Subversion_LAST_CHANGED_LOG)
- - Fix setting of LC_ALL environment variable to be inside macro
- - Patch from Tanguy Krotoff
- - See issue #7047
-
-2008-05-19 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-18 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-17 17:35 hoffman
-
- * Modules/Platform/Linux-PGI-Fortran.cmake: file
- Linux-PGI-Fortran.cmake was added on branch CMake-2-6 on
- 2008-05-23 20:09:35 +0000
-
-2008-05-17 17:35 king
-
- * Modules/Platform/Linux-PGI-Fortran.cmake: ENH: Add basic flags
- for Portland Group fortran compiler.
-
-2008-05-17 12:53 hoffman
-
- * Modules/MacOSXBundleInfo.plist.in: file MacOSXBundleInfo.plist.in
- was added on branch CMake-2-6 on 2008-05-23 20:09:35 +0000
-
-2008-05-17 12:53 king
-
- * Modules/MacOSXBundleInfo.plist.in, Source/cmLocalGenerator.cxx,
- Source/cmTarget.cxx: ENH: Allow users to specify a custom
- Info.plist template
-
- - Create MACOSX_BUNDLE_INFO_PLIST target property to specify
- template.
- - Look for MacOSXBundleInfo.plist.in in CMAKE_MODULE_PATH by
- default.
- - See issue #6983.
-
-2008-05-17 11:42 king
-
- * Source/cmFileCommand.cxx: BUG: Fix previous change to
- file(STRINGS) command.
-
- - Previous change added form-feed as a string terminator.
- - Instead it should just be recognized as a valid string
- character.
-
-2008-05-17 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-16 17:56 king
-
- * Modules/Platform/Linux-PGI-Fortran.cmake: ENH: Add
- Linux-PGI-Fortran platform file to support the Portland Group
- Fortran compiler (PGI).
-
-2008-05-16 17:50 king
-
- * Modules/CMakeFortranCompilerId.F90.in, Source/cmFileCommand.cxx:
- ENH: Teach Fortran compiler identification about the Portland
- Group compiler (PGI).
-
-2008-05-16 16:56 king
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx, cmSourceGroup.cxx,
- cmSourceGroup.h: COMP: Fix build with concept checking of STL.
-
- - Fix cmSourceGroup to not use std::vector with an incomplete
- type.
-
-2008-05-16 11:06 king
-
- * Source/kwsys/: RegularExpression.cxx, RegularExpression.hxx.in:
- ENH: Add assignment operator to KWSys RegularExpression.
-
-2008-05-16 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-15 19:21 hoffman
-
- * Source/QtDialog/CMakeFirstConfigure.cxx: file
- CMakeFirstConfigure.cxx was added on branch CMake-2-6 on
- 2008-05-23 20:09:42 +0000
-
-2008-05-15 19:21 hoffman
-
- * Source/QtDialog/CMakeFirstConfigure.h: file CMakeFirstConfigure.h
- was added on branch CMake-2-6 on 2008-05-23 20:09:43 +0000
-
-2008-05-15 19:21 hoffman
-
- * Source/QtDialog/CMakeFirstConfigure.ui: file
- CMakeFirstConfigure.ui was added on branch CMake-2-6 on
- 2008-05-23 20:09:43 +0000
-
-2008-05-15 19:21 hoffman
-
- * Source/QtDialog/QCMakeWidgets.cxx: file QCMakeWidgets.cxx was
- added on branch CMake-2-6 on 2008-05-23 20:09:44 +0000
-
-2008-05-15 19:21 hoffman
-
- * Source/QtDialog/QCMakeWidgets.h: file QCMakeWidgets.h was added
- on branch CMake-2-6 on 2008-05-23 20:09:44 +0000
-
-2008-05-15 19:21 clinton
-
- * Source/QtDialog/: AddCacheEntry.cxx, AddCacheEntry.h,
- AddCacheEntry.ui, CMakeFirstConfigure.cxx, CMakeFirstConfigure.h,
- CMakeFirstConfigure.ui, CMakeLists.txt, CMakeSetupDialog.cxx,
- CMakeSetupDialog.h, QCMake.cxx, QCMake.h, QCMakeCacheView.cxx,
- QCMakeCacheView.h, QCMakeWidgets.cxx, QCMakeWidgets.h:
- ENH: Add cross compiling support in the GUI in the same dialog
- that prompts for the generator on the first configure. It
- either ask for a toolchain file or asks for all the
- information a toolchain file might contain.
-
- Also added option for setting non-default compilers if not
- cross compiling.
- Fixes #6849.
-
- Also a bit of code cleanup and re-organizing.
-
-2008-05-15 15:39 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Modules/CMakeTestFortranCompiler.cmake, Modules/FindBoost.cmake,
- Modules/FindCurses.cmake,
- Modules/FindPackageHandleStandardArgs.cmake,
- Modules/FindQt4.cmake, Modules/NSIS.template.in,
- Source/cmAddCustomCommandCommand.cxx,
- Source/cmAddCustomCommandCommand.h, Source/cmCustomCommand.cxx,
- Source/cmCustomCommand.h, Source/cmDepends.cxx,
- Source/cmDepends.h, Source/cmDependsC.cxx, Source/cmDependsC.h,
- Source/cmDependsFortran.cxx, Source/cmDependsFortran.h,
- Source/cmDocumentationFormatterDocbook.cxx, Source/cmELF.cxx,
- Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmListCommand.cxx,
- Source/cmLocalUnixMakefileGenerator3.cxx, Source/cmMakefile.cxx,
- Source/cmMakefileTargetGenerator.cxx,
- Source/cmSetSourceFilesPropertiesCommand.cxx,
- Source/cmTarget.cxx, Source/cmTarget.h, Source/cmXCodeObject.cxx,
- Source/cmake.cxx, Source/cmakemain.cxx,
- Source/CTest/cmCTestBuildCommand.h,
- Source/CTest/cmCTestConfigureCommand.h,
- Source/CTest/cmCTestCoverageCommand.h,
- Source/CTest/cmCTestCoverageHandler.cxx,
- Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h,
- Source/CTest/cmCTestMemCheckCommand.h,
- Source/CTest/cmCTestReadCustomFilesCommand.h,
- Source/CTest/cmCTestRunScriptCommand.h,
- Source/CTest/cmCTestSleepCommand.h,
- Source/CTest/cmCTestStartCommand.h,
- Source/CTest/cmCTestSubmitCommand.h,
- Source/CTest/cmCTestUpdateCommand.h, Source/kwsys/CMakeLists.txt,
- Source/kwsys/CPU.h.in, Source/kwsys/ProcessUNIX.c,
- Source/kwsys/ProcessWin32.c, Source/kwsys/SystemInformation.cxx,
- Source/kwsys/SystemTools.cxx, Tests/BuildDepends/CMakeLists.txt,
- Tests/BuildDepends/Project/CMakeLists.txt,
- Tests/BuildDepends/Project/zot.cxx,
- Tests/BuildDepends/Project/zot_macro_dir.cxx,
- Tests/BuildDepends/Project/zot_macro_tgt.cxx,
- Tests/CustomCommand/CMakeLists.txt, Tests/CustomCommand/foo.in,
- Tests/CustomCommand/gen_once.c.in, Utilities/CMakeLists.txt,
- Utilities/cmtar/CMakeLists.txt: ENH: merge in from main tree
-
-2008-05-15 12:07 alex
-
- * Modules/: CMakeDetermineASMCompiler.cmake,
- CMakeDetermineCCompiler.cmake, CMakeDetermineCXXCompiler.cmake:
- BUG: make the toolchain-prefix recognition work with prefixes
- which contain dots (as in arm-unknown-nto-qnx6.3.0-gcc.exe),
- NAME_WE returns only up to the 6, instead of everything in front
- of the .exe
-
- Alex
-
-2008-05-15 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-14 11:55 king
-
- * Source/kwsys/CMakeLists.txt: ENH: In KWSys set the
- IMPLICIT_DEPENDS_INCLUDE_TRANSFORM property.
-
- - Tells CMake about the KWSYS_HEADER macro.
- - Enables implicit dependencies of private source files.
- - When a CMake new enough to support the property is required
- the "#if 0" hack can be removed from the source files.
-
-2008-05-14 11:55 hoffman
-
- * Tests/BuildDepends/Project/zot_macro_dir.cxx: file
- zot_macro_dir.cxx was added on branch CMake-2-6 on 2008-05-15
- 19:40:01 +0000
-
-2008-05-14 11:55 hoffman
-
- * Tests/BuildDepends/Project/zot_macro_tgt.cxx: file
- zot_macro_tgt.cxx was added on branch CMake-2-6 on 2008-05-15
- 19:40:01 +0000
-
-2008-05-14 11:55 king
-
- * Tests/BuildDepends/: CMakeLists.txt, Project/CMakeLists.txt,
- Project/zot.cxx, Project/zot_macro_dir.cxx,
- Project/zot_macro_tgt.cxx: ENH: Update BuildDepends test to check
- #include lines with macros.
-
- - Tests IMPLICIT_DEPENDS_INCLUDE_TRANSFORM properties.
- - See issue #6648.
- - Works without help in VS IDEs due to native dependency
- handling.
- - Xcode needs help to rebuild correctly.
-
-2008-05-14 11:54 king
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx, cmMakefile.cxx,
- cmTarget.cxx: ENH: Allow users to specify macro-like #include
- line transforms for dependency scanning.
-
- - Define IMPLICIT_DEPENDS_INCLUDE_TRANSFORM property on targets
- and directories.
- - Make the directory version inherited.
- - See issue #6648.
-
-2008-05-14 11:54 king
-
- * Source/: cmDependsC.cxx, cmDependsC.h: ENH: Teach cmDependsC
- about user-configured macro transformations.
-
- - Syntax is SOME_MACRO(%)=value-with-%
- - Later we will configure these with target and directory
- properties.
- - See issue #6648.
-
-2008-05-14 11:38 hoffman
-
- * Tests/CustomCommand/gen_once.c.in: file gen_once.c.in was added
- on branch CMake-2-6 on 2008-05-15 19:40:01 +0000
-
-2008-05-14 11:38 king
-
- * Source/cmAddCustomCommandCommand.cxx,
- Source/cmAddCustomCommandCommand.h, Source/cmCustomCommand.cxx,
- Source/cmCustomCommand.h, Source/cmMakefileTargetGenerator.cxx,
- Tests/CustomCommand/CMakeLists.txt, Tests/CustomCommand/foo.in,
- Tests/CustomCommand/gen_once.c.in: ENH: Add SKIP_RULE_DEPENDS
- option for add_custom_command()
-
- - Allows make rules to be created with no dependencies.
- - Such rules will not re-run even if the commands themselves
- change.
- - Useful to create rules that run only if the output is
- missing.
-
-2008-05-14 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-13 16:57 hoffman
-
- * Modules/NSIS.template.in: BUG: if CPACK_NSIS_MODIFY_PATH was OFF
- then the PATH was automatically modified
-
-2008-05-13 15:43 alex
-
- * Source/cmakemain.cxx, Utilities/CMakeLists.txt: STYLE: add
- "--help-policy" and "--help-policies" to the documentation
- -generate and install the policy documentation files -generate
- and install the docbook files for cmake, ctest, cpack, ccmake
- (cmake-gui not yet ?)
-
- Alex
-
-2008-05-13 10:34 king
-
- * Source/cmELF.cxx: BUG: When byte order is not known at compile
- time make sure NeedSwap in cmELF is still initialized.
-
-2008-05-13 10:24 king
-
- * Source/cmELF.cxx: ENH: In cmELF it is okay if the byte order is
- not known at compile time.
-
- - We perform a runtime check of the input file anyway.
-
-2008-05-13 10:24 king
-
- * Source/kwsys/CPU.h.in: ENH: Add ARM support to KWSys CPU header.
-
- - Patch from Pierre Habouzit
-
-2008-05-13 05:18 malaterre
-
- * Source/kwsys/ProcessUNIX.c: ENH: all ctype function have the same
- issue: char can be signed or unsigned, since isspace only deal
- with >=0 value (except EOF) one has to first cast it to unsigned
- char
-
-2008-05-13 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-12 18:33 alex
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: BUG: make
- ENABLE_LANGUAGE(ASM-ATT OPTIONAL) work again: if it didn't work
- but was optional, don't delete the cache
-
- Alex
-
-2008-05-12 18:11 alex
-
- * Modules/CMakeTestFortranCompiler.cmake: STYLE: use IF(NOT ...)
- instead of IF() ELSE() ... ENDIF()
-
- Alex
-
-2008-05-12 17:43 king
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmTarget.cxx, cmTarget.h: BUG: Make sure all source files are
- found before generating.
-
- - Previously this was done implicitly by the check for a target
- link language which checked all source full paths.
- - The recent change to support computing a link language
- without
- finding all the source files skipped the implicit check.
- - This change adds an explicit check to find all source files.
-
-2008-05-12 16:54 alex
-
- * Source/cmake.cxx: BUG: make "cmake -Wno-dev ../srcdir" work,
- advancing i had the effect that the argument after -Wno-dev was
- skipped, which happened to be the source directory, and so the
- current working directory was assumed as source directory,
- although it was the build directory (maybe this didn't have an
- effect if there was already a CMakeCache.txt in the build dir)
-
- Alex
-
-2008-05-12 12:01 lorensen
-
- * Source/kwsys/ProcessUNIX.c: COMP: warning, isprint and isspace
- take int args.
-
-2008-05-12 09:11 alex
-
- * Source/CTest/: cmCTestBuildCommand.h, cmCTestConfigureCommand.h,
- cmCTestCoverageCommand.h, cmCTestEmptyBinaryDirectoryCommand.h,
- cmCTestMemCheckCommand.h, cmCTestReadCustomFilesCommand.h,
- cmCTestRunScriptCommand.h, cmCTestSleepCommand.h,
- cmCTestStartCommand.h, cmCTestSubmitCommand.h,
- cmCTestUpdateCommand.h: STYLE: use lower case also for the
- ctest-specific commands, as in cmake
-
- I hope I didn't make a typo anywhere, at least the tests still
- succeed
-
- Alex
-
-2008-05-12 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-11 05:12 alex
-
- * Modules/FindPackageHandleStandardArgs.cmake: BUG: fix #6375:
- print the variables which were not found, so it's easier to see
- what went wrong
-
- Alex
-
-2008-05-11 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-10 22:48 lorensen
-
- * Source/kwsys/: ProcessWin32.c, SystemInformation.cxx,
- SystemTools.cxx: COMP: sprintf warnings. DWORD should use %ld
- rather than %d. Also, const char *p, a shadowed variable warning.
-
-2008-05-10 19:07 alex
-
- * Modules/FindCurses.cmake: BUG: fix #6993 FindCurses.cmake is now
- almost exactly reverted back to the state when CURSES_LIBRARY and
- CURSES_INCLUDE_PATH where set for compatibility but not in the
- cache. It is important that CURSES_CURSES_LIBRARY and
- CURSES_NCURSES_LIBRARY really contain the path to these files.
- Later on CURSES_LIBRARY is set to the one of the two which will
- be used as curses library. This is now done in the cache, without
- FORCE. So preloading the cache still seems to work (at least
- what I tested).
-
- Alex
-
-2008-05-10 18:39 king
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx,
- cmMakefileTargetGenerator.cxx: BUG: Fix generation of some paths
- into .cmake files in the build tree to escape strings for the
- CMake language. This fix allows users to put double quotes in
- the SOVERSION of a shared library.
-
-2008-05-10 18:39 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Fix logic that
- loops over multiple output pairs to not loop beyond the vector
- when there are an odd number of entries.
-
-2008-05-10 11:12 hoffman
-
- * Source/CTest/cmCTestCoverageHandler.cxx: ENH: make sure english
- is used for output of gcov
-
-2008-05-10 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-09 21:26 dgregor
-
- * Modules/FindBoost.cmake: BUG: Fix FindBoost version variable
- names to correct bug in Boost version detection
-
-2008-05-09 17:50 alex
-
- * Source/cmDocumentationFormatterDocbook.cxx: STYLE: insert
- newlines after listitem so the generated lines don't get several
- thousand characters long
-
- Alex
-
-2008-05-09 11:50 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Qt/Mac binary install puts QtCLucene library in a different
- place than the normal Qt frameworks. Let's find it.
-
-2008-05-09 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-08 21:14 hoffman
-
- * Source/cmXCodeObject.cxx: ENH: fix for 64 bit cmake on mac
-
-2008-05-08 15:49 hoffman
-
- * Source/cmSetSourceFilesPropertiesCommand.cxx: BUG:6990 fix crash
- with set_source_files_properties
-
-2008-05-08 12:47 hoffman
-
- * Source/CTest/cmCTestCoverageHandler.cxx: BUG: 0006988 do not set
- coverage to false when it is not
-
-2008-05-08 10:09 king
-
- * Source/: cmDepends.cxx, cmDepends.h, cmDependsC.cxx,
- cmDependsC.h, cmDependsFortran.cxx, cmDependsFortran.h,
- cmLocalUnixMakefileGenerator3.cxx: ENH: Light refactoring of
- implicit dependency scanning configuration implementation.
-
- - Move lookup of config variables from
- cmLocalUnixMakefileGenerator3 to cmDepends hierarchy.
-
-2008-05-08 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-07 17:25 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Fix repeated
- re-scanning of dependencies when the results do not change.
-
- - We re-scan deps when DependInfo.cmake is newer than
- depend.internal
- - Therefore depend.internal should not be copy-if-different
-
-2008-05-07 14:57 hoffman
-
- * Source/cmListCommand.cxx: ENH: fix sort to work with CMP0007
-
-2008-05-07 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-06 12:56 barre
-
- * Utilities/cmtar/CMakeLists.txt: ENH: update for CMake 2.6
-
-2008-05-06 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-05 13:38 hoffman
-
- * ChangeLog.manual, Source/cmDocumentationFormatter.cxx,
- Source/cmDocumentationFormatter.h,
- Source/cmDocumentationFormatterDocbook.cxx,
- Source/cmDocumentationFormatterHTML.cxx: ENH: merge in changes
- for generated docs
-
-2008-05-05 12:38 hoffman
-
- * CMakeLists.txt: ENH: try for 2.6.0
-
-2008-05-05 12:02 king
-
- * Source/: cmDocumentationFormatter.cxx,
- cmDocumentationFormatter.h, cmDocumentationFormatterDocbook.cxx,
- cmDocumentationFormatterHTML.cxx: ENH: Fix generated
- documentation internal links.
-
- - Previously all links started in 'command_' which led to
- conflicts
- and was confusing for non-command items.
- - Use a per-section name that is meaningful to humans.
- - Fix link id names to be valid HTML.
-
-2008-05-05 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-04 18:07 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/CTest.cmake,
- Modules/FindQt4.cmake, Modules/FindX11.cmake,
- Modules/GetPrerequisites.cmake,
- Source/kwsys/SystemInformation.cxx: ENH: merge from main tree
-
-2008-05-04 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-03 17:55 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Allow finding phonon and QtDBus on Mac. Fixes #6950.
-
-2008-05-03 15:27 barre
-
- * Modules/FindX11.cmake: ENH: X11_SM_LIB should be advanced as well
-
-2008-05-03 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-02 17:36 hoffman
-
- * Source/kwsys/SystemInformation.cxx: BUG: really fix build on vs6
-
-2008-05-02 17:22 hoffman
-
- * Source/kwsys/SystemInformation.cxx: BUG: fix build on vs6
-
-2008-05-02 11:44 hoffman
-
- * Source/kwsys/SystemInformation.cxx: ENH: use GlobalMemoryStatusEx
- as it is able to report more than 2gigs
-
-2008-05-02 11:25 hoffman
-
- * Modules/CTest.cmake: ENH: recognize vs 9 and possible 10 or
- greater when they come out...
-
-2008-05-02 09:14 king
-
- * Source/kwsys/SystemInformation.cxx: COMP: Fix warnings in KWSys
- SystemInformation on Borland compiler.
-
- - Remove two unused variables.
- - Replace dynamically allocated array with static.
-
-2008-05-02 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-05-01 18:49 king
-
- * Modules/GetPrerequisites.cmake: ENH: When GetPrerequisites.cmake
- runs dumpbin while running inside the VS IDE environment make
- sure the tool does not produce extra output.
-
-2008-05-01 12:35 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/CheckTypeSize.cmake,
- Modules/FindBoost.cmake, Modules/FindCurses.cmake,
- Modules/FindKDE.cmake, Modules/FindSDL.cmake,
- Modules/FindSDL_sound.cmake, Modules/FindVTK.cmake,
- Modules/Platform/Darwin.cmake,
- Modules/Platform/Linux-Intel-C.cmake,
- Modules/Platform/Linux-Intel-CXX.cmake,
- Modules/Platform/Linux-Intel-Fortran.cmake,
- Modules/Platform/SunOS.cmake,
- Modules/Platform/Windows-ifort.cmake,
- Source/cmAuxSourceDirectoryCommand.cxx,
- Source/cmComputeLinkDepends.cxx, Source/cmComputeLinkDepends.h,
- Source/cmComputeLinkInformation.cxx,
- Source/cmComputeLinkInformation.h,
- Source/cmExportFileGenerator.cxx,
- Source/cmExportLibraryDependencies.cxx, Source/cmFileCommand.cxx,
- Source/cmFileCommand.h, Source/cmGlobalGenerator.cxx,
- Source/cmGlobalVisualStudio71Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalVisualStudioGenerator.cxx,
- Source/cmGlobalVisualStudioGenerator.h,
- Source/cmGlobalXCodeGenerator.cxx, Source/cmListFileCache.cxx,
- Source/cmLocalGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmSourceFile.cxx,
- Source/cmSourceFile.h, Source/cmWriteFileCommand.cxx,
- Source/cmake.cxx, Source/cmake.h, Source/kwsys/System.c,
- Source/kwsys/SystemInformation.cxx,
- Tests/CustomCommand/CMakeLists.txt,
- Tests/CustomCommand/gen_redirect_in.c,
- Tests/CustomCommand/generator.cxx, Tests/CustomCommand/tcat.cxx,
- Tests/CustomCommand/GeneratorInExtraDir/CMakeLists.txt: ENH:
- merge from cvs create yikes RC 10! (I hope this is the last
- RC...)
-
-2008-05-01 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-30 22:17 hoffman
-
- * Source/cmGlobalVisualStudioGenerator.cxx: STYLE: fix warning
-
-2008-04-30 18:04 king
-
- * Source/: cmComputeLinkDepends.cxx, cmComputeLinkDepends.h,
- cmComputeLinkInformation.cxx, cmComputeLinkInformation.h: ENH:
- When preserving potentially static portions of original user link
- lines recognize shared library names by their extension and skip
- them.
-
-2008-04-30 15:58 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: For Watcom WMake
- use the short path to avoid quoting problems in custom commands
- with shell redirections.
-
-2008-04-30 15:58 king
-
- * Source/kwsys/System.c, Tests/CustomCommand/CMakeLists.txt: BUG:
- Fix escaping of more characters on Windows shells.
-
-2008-04-30 15:53 hoffman
-
- * Modules/FindCurses.cmake: BUG: remove typo
-
-2008-04-30 15:42 hoffman
-
- * Modules/FindCurses.cmake: BUG: fix for 6918 ncurses should work
- without curses
-
-2008-04-30 14:13 king
-
- * Modules/Platform/SunOS.cmake: ENH: Make /opt/SUNWspro/lib,
- /opt/SUNWspro/prod/lib, and /usr/ccs/lib implicit link
- directories on the Sun when using the SunPro compiler.
-
-2008-04-30 13:42 king
-
- * Source/: cmFileCommand.cxx, cmFileCommand.h,
- cmGlobalGenerator.cxx, cmMakefile.cxx, cmMakefile.h,
- cmWriteFileCommand.cxx, cmake.cxx, cmake.h: BUG: Remove check for
- files written by file(WRITE) being loaded.
-
- - CMake 1.8 and below did not do the check but could get in
- infinite loops due to the local generate step.
- - CMake 2.0 added the check but failed to perform it in
- directories
- with no targets (see bug #678).
- - CMake 2.2 removed the local generate which fixed the problem
- but
- did not remove the check.
- - Between CMake 2.4 and 2.6.0rc6 the check was fixed to work
- even
- when no targets appear in a directory (see bug #6923).
- - Bottom line: the check is no longer needed.
-
-2008-04-30 13:26 hoffman
-
- * Source/: cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudioGenerator.cxx,
- cmGlobalVisualStudioGenerator.h, cmLocalGenerator.cxx,
- cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h, cmMakefile.cxx: ENH: add support
- for Intel Fortran Visual studio IDE
-
-2008-04-30 11:33 hoffman
-
- * Modules/Platform/Windows-ifort.cmake: ENH: add more fortran flags
-
-2008-04-30 10:02 king
-
- * Source/kwsys/System.c: BUG: Fix
- kwsysSystem_Shell_GetArgumentForWindows to reset the windows
- trailing backslash count to zero when a make variable reference
- is encountered.
-
-2008-04-30 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-29 15:34 hoffman
-
- * Tests/CustomCommand/tcat.cxx: file tcat.cxx was added on branch
- CMake-2-6 on 2008-05-01 16:35:40 +0000
-
-2008-04-29 15:34 hoffman
-
- * Tests/CustomCommand/gen_redirect_in.c: file gen_redirect_in.c was
- added on branch CMake-2-6 on 2008-05-01 16:35:40 +0000
-
-2008-04-29 15:34 king
-
- * Source/cmLocalGenerator.cxx, Tests/CustomCommand/CMakeLists.txt,
- Tests/CustomCommand/gen_redirect_in.c,
- Tests/CustomCommand/generator.cxx, Tests/CustomCommand/tcat.cxx,
- Tests/CustomCommand/GeneratorInExtraDir/CMakeLists.txt: BUG: Do
- not escape shell operators when generating command lines.
-
- - See bug#6868.
- - Update CustomCommand test to check.
-
-2008-04-29 14:17 king
-
- * Source/: cmSourceFile.cxx, cmSourceFile.h: ENH: In
- cmSourceFile::GetLanguage use the file extension (if not
- ambiguous) to determine the language without requiring the source
- file to exist.
-
-2008-04-29 14:17 king
-
- * Source/cmSourceFile.cxx: ENH: Add context information when a
- source file cannot be found.
-
-2008-04-29 14:17 king
-
- * Source/cmMakefile.cxx: ENH: In cmMakefile::IssueMessage report
- the directory-level context even if no list file is currently
- being processed.
-
-2008-04-29 12:10 hoffman
-
- * Source/cmLocalGenerator.cxx: BUG: move this back out of the if
- statemtn
-
-2008-04-29 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-28 13:53 hoffman
-
- * Modules/Platform/Darwin.cmake, Source/cmGlobalXCodeGenerator.cxx,
- Source/cmLocalGenerator.cxx: ENH: allow users to set sysroot
-
-2008-04-28 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-27 11:41 alex
-
- * Modules/FindKDE.cmake: ENH: remove FindKDE.cmake, which was
- obsolete (i.e. disabled using SEND_ERROR) since cmake 2.4.0,
- agreed by Bill
-
- Alex
-
-2008-04-27 07:35 alex
-
- * Modules/FindVTK.cmake: BUG: don't fail with FATAL_ERROR if
- REQUIRED was not used
-
- Alex
-
-2008-04-27 07:30 alex
-
- * Source/cmExportFileGenerator.cxx: ENH: protect the export files
- against inclusion with cmake 2.4
-
- Alex
-
-2008-04-27 07:01 alex
-
- * Source/: cmExportLibraryDependencies.cxx, cmListFileCache.cxx:
- ENH: write the cmake version into the file created by
- EXPORT_LIBRARY_DEPENDENCIES() to help with debugging later on.
- The same should be done in the import target files (but I didn't
- have time to do it yet). STYLE: fix line length in
- cmListFileCache.cxx
-
- Alex
-
-2008-04-27 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-26 13:25 alex
-
- * Modules/FindBoost.cmake: BUG: don't use CMAKE_MINIMUM_REQUIRED()
- in find modules, it can change the policy settings done in the
- projects cmake files (and it doesn't make sense since it is
- always part of the correct cmake version)
-
- Alex
-
-2008-04-26 08:39 hoffman
-
- * Source/cmAuxSourceDirectoryCommand.cxx: BUG: fix for bug 6911,
- aux source dir was broken from a previous fix
-
-2008-04-26 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-25 15:30 king
-
- * Source/cmSourceFile.cxx: BUG: Trust user-provided source file
- full paths.
-
-2008-04-25 10:47 hoffman
-
- * Modules/CheckTypeSize.cmake: ENH: allow users to turn off extra
- checks
-
-2008-04-25 09:49 hoffman
-
- * Modules/Platform/Linux-Intel-CXX.cmake: ENH: remove c flags from
- cxx config file
-
-2008-04-25 09:49 hoffman
-
- * Modules/Platform/Linux-Intel-CXX.cmake: file
- Linux-Intel-CXX.cmake was added on branch CMake-2-6 on 2008-05-01
- 16:35:39 +0000
-
-2008-04-25 09:43 hoffman
-
- * Modules/Platform/: Linux-Intel-Fortran.cmake, Linux-ifort.cmake:
- ENH: rename Linux-ifort to Linux-Intel-Fortran
-
-2008-04-25 09:43 hoffman
-
- * Modules/Platform/Linux-Intel-Fortran.cmake: file
- Linux-Intel-Fortran.cmake was added on branch CMake-2-6 on
- 2008-05-01 16:35:39 +0000
-
-2008-04-25 09:09 hoffman
-
- * Modules/CheckTypeSize.cmake: ENH: make sure all required headers
- are checked before checking type size
-
-2008-04-25 09:07 hoffman
-
- * Modules/: FindSDL.cmake, FindSDL_sound.cmake: ENH: do not clear
- find variables
-
-2008-04-25 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-24 22:00 hoffman
-
- * Modules/Platform/Linux-Intel-CXX.cmake: ENH: do not force the
- intel ar on C from CXX
-
-2008-04-24 21:54 hoffman
-
- * Modules/Platform/: Linux-Intel-C.cmake, Linux-Intel-CXX.cmake,
- Linux-icpc.cmake: ENH: support intel compiler on linux
-
-2008-04-24 21:54 hoffman
-
- * Modules/Platform/Linux-Intel-C.cmake: file Linux-Intel-C.cmake
- was added on branch CMake-2-6 on 2008-05-01 16:35:38 +0000
-
-2008-04-24 15:47 hoffman
-
- * Source/kwsys/SystemInformation.cxx: ENH: remove odd chars from
- file
-
-2008-04-24 14:57 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: merge in changes from main
- tree, fortran mod stuff
-
-2008-04-24 12:56 hoffman
-
- * ChangeLog.manual, Source/cmDependsFortranLexer.cxx,
- Source/cmDependsFortranLexer.in.l,
- Source/cmDependsFortranParser.cxx,
- Source/cmDependsFortranParser.y,
- Source/cmDependsFortranParserTokens.h: ENH: merge in changes from
- main tree, fortran mod stuff
-
-2008-04-24 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-23 23:53 king
-
- * Source/: cmDependsFortranLexer.cxx, cmDependsFortranLexer.in.l,
- cmDependsFortranParser.cxx, cmDependsFortranParser.y,
- cmDependsFortranParserTokens.h: ENH: Patch from Maik to add
- Fortran03 USE syntax support.
-
- - I tweaked the patch to add 'other' production rules for COMMA
- and DCOLON
- - See issue #6884.
-
-2008-04-23 15:02 hoffman
-
- * CMakeLists.txt, ChangeLog.manual: ENH: rc9 ready
-
-2008-04-23 12:51 jeff
-
- * Source/kwsys/SystemTools.cxx: ENH: Allow numbers in username in
- URL regex.
-
-2008-04-23 12:14 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Source/cmInstallCommand.cxx,
- Source/cmListCommand.cxx, Source/QtDialog/QMacInstallDialog.cxx:
- ENH: merge in some fixes from head
-
-2008-04-23 11:13 king
-
- * Source/cmInstallCommand.cxx: BUG: Fix implementation of CMP0006
- to not override the BUNDLE destination with the RUNTIME
- destination.
-
-2008-04-23 09:58 hoffman
-
- * Source/QtDialog/QMacInstallDialog.cxx: ENH: add better error
- checks to symlink create stuff
-
-2008-04-23 09:56 hoffman
-
- * Source/cmListCommand.cxx: ENH: handle empty lists correctly
-
-2008-04-23 08:50 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Source/cmComputeLinkDepends.cxx, Source/cmComputeLinkDepends.h,
- Tests/Dependency/CMakeLists.txt,
- Tests/Dependency/Case3/CMakeLists.txt,
- Tests/Dependency/Case3/bar.c, Tests/Dependency/Case3/foo1.c,
- Tests/Dependency/Case3/foo1b.c, Tests/Dependency/Case3/foo2.c:
- ENH: merge from main tree
-
-2008-04-23 00:40 hoffman
-
- * Tests/Dependency/Case3/CMakeLists.txt: file CMakeLists.txt was
- added on branch CMake-2-6 on 2008-04-23 12:50:37 +0000
-
-2008-04-23 00:40 hoffman
-
- * Tests/Dependency/Case3/bar.c: file bar.c was added on branch
- CMake-2-6 on 2008-04-23 12:50:37 +0000
-
-2008-04-23 00:40 hoffman
-
- * Tests/Dependency/Case3/foo1.c: file foo1.c was added on branch
- CMake-2-6 on 2008-04-23 12:50:37 +0000
-
-2008-04-23 00:40 hoffman
-
- * Tests/Dependency/Case3/foo1b.c: file foo1b.c was added on branch
- CMake-2-6 on 2008-04-23 12:50:37 +0000
-
-2008-04-23 00:40 hoffman
-
- * Tests/Dependency/Case3/foo2.c: file foo2.c was added on branch
- CMake-2-6 on 2008-04-23 12:50:37 +0000
-
-2008-04-23 00:40 king
-
- * Tests/Dependency/: CMakeLists.txt, Case3/CMakeLists.txt,
- Case3/bar.c, Case3/foo1.c, Case3/foo1b.c, Case3/foo2.c: ENH: Add
- test of preservation of static libraries on original link lines.
-
-2008-04-23 00:40 king
-
- * Source/: cmComputeLinkDepends.cxx, cmComputeLinkDepends.h: BUG:
- Fix preservation of static libraries on original link lines.
-
-2008-04-23 00:40 king
-
- * Source/cmComputeLinkDepends.cxx: ENH: Simplify link lines in some
- cases by not allowing targets to be inferred dependees of items
- with unknown dependencies.
-
-2008-04-23 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-22 22:05 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Modules/CMakeDetermineASMCompiler.cmake,
- Modules/CMakeFortranInformation.cmake,
- Modules/CMakeRCInformation.cmake, Modules/FindBoost.cmake,
- Modules/FindMPI.cmake, Modules/Platform/Linux-icpc.cmake,
- Source/cmListCommand.cxx,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmMakefileTargetGenerator.cxx, Source/cmPolicies.cxx,
- Source/cmPolicies.h: ENH: merge into main tree
-
-2008-04-22 13:32 dgregor
-
- * Modules/FindBoost.cmake: ENH: FindBoost always sets
- Boost_LIBRARY_DIRS when it finds the Boost libraries
-
-2008-04-22 13:14 dgregor
-
- * Modules/FindBoost.cmake: ENH: Integrated FindBoost improvements
- changes from Andreas Pakulat, Mike Jackson, and myself
-
-2008-04-22 11:10 hoffman
-
- * Modules/CMakeRCInformation.cmake,
- Source/cmMakefileTargetGenerator.cxx: BUG: fix for bug 6834 RC
- should not get all COMPILE_FLAGS from a target and should work
- the same way as it does in the vs ide
-
-2008-04-22 09:54 dgregor
-
- * Modules/FindMPI.cmake: BUG: As a last resort, FindMPI will look
- for mpi.h in the path
-
-2008-04-22 09:41 dgregor
-
- * Modules/FindMPI.cmake: BUG: Use -showme:incdirs and
- -showme:libdirs when we need them
-
-2008-04-22 09:35 hoffman
-
- * Modules/CMakeFortranInformation.cmake: ENH: fix FFFLAGS to be
- FLAGS
-
-2008-04-22 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-21 18:51 alex
-
- * Modules/CMakeDetermineASMCompiler.cmake: BUG: fix handling of
- assembler executable (with path) #6858
-
- Alex
-
-2008-04-21 18:26 hoffman
-
- * Modules/Platform/Linux-icpc.cmake: ENH: use xiar for the intel
- compiler
-
-2008-04-21 18:24 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx: BUG: fix for 6720,
- source groups on vs6 not working
-
-2008-04-21 16:57 hoffman
-
- * Source/: cmListCommand.cxx, cmPolicies.cxx, cmPolicies.h: ENH:
- fix list command with empty elements
-
-2008-04-21 15:21 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Modules/CMakeCInformation.cmake,
- Modules/CMakeCXXInformation.cmake,
- Modules/CMakeFortranInformation.cmake,
- Source/cmComputeLinkInformation.cxx, Source/cmDependsFortran.cxx,
- Source/cmDependsFortranLexer.cxx, Source/cmDependsFortranLexer.h,
- Source/cmDependsFortranLexer.in.l,
- Source/cmDependsFortranParser.cxx,
- Source/cmDependsFortranParser.y, Tests/CMakeLists.txt: ENH: merge
- in from main tree
-
-2008-04-21 13:04 hoffman
-
- * Modules/: CMakeCInformation.cmake, CMakeCXXInformation.cmake,
- CMakeFortranInformation.cmake: ENH: fix init flags getting
- stuffed into the compile line by force.
-
-2008-04-21 11:28 king
-
- * Source/: cmDependsFortranLexer.cxx, cmDependsFortranLexer.in.l,
- cmDependsFortranParser.cxx, cmDependsFortranParser.y: STYLE: Fix
- reference to makedepf90 project.
-
-2008-04-21 11:15 king
-
- * Source/: cmDependsFortran.cxx, cmDependsFortranLexer.cxx,
- cmDependsFortranLexer.h, cmDependsFortranLexer.in.l: BUG: Fix
- Fortran dependency parser preprocessor handling crash.
-
- - Do not crash if a #elseif occurs out of order
- - Recognize preprocessor directives only at the beginning of
- lines.
- - See issue #6855
-
-2008-04-21 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-20 20:44 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Modules/CMakeDetermineCompilerABI.cmake,
- Modules/CPack.RuntimeScript.in, Modules/CPack.cmake,
- Modules/FindMPI.cmake, Modules/FindwxWidgets.cmake,
- Source/cmELF.cxx, Source/cmELF.h, Source/cmFileCommand.cxx,
- Source/cmFileCommand.h, Source/cmInstallCommand.cxx,
- Source/cmInstallCommand.h, Source/cmInstallTargetGenerator.cxx,
- Source/cmInstallTargetGenerator.h,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.cxx,
- Source/cmMessageCommand.cxx, Source/cmPolicies.cxx,
- Source/cmPolicies.h, Source/cmSystemTools.cxx,
- Source/cmSystemTools.h, Source/cmTarget.cxx,
- Source/CPack/cpack.cxx, Source/QtDialog/CMakeSetupDialog.cxx,
- Source/QtDialog/CMakeSetupDialog.h,
- Tests/Framework/CMakeLists.txt,
- Tests/Tutorial/Step7/CMakeLists.txt, Tests/X11/CMakeLists.txt,
- Tests/X11/HelloWorldX11.cxx: ENH: merge in from main tree
-
-2008-04-20 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-19 13:37 david.cole
-
- * Tests/CMakeLists.txt: BUG: Allow timeouts larger than 1500 for
- tests that may take longer than 25 minutes on really slow/busy
- machines. bootstrap has been timing out on tiamat, a very old
- machine, this should help it...
-
-2008-04-19 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-18 17:32 hoffman
-
- * Source/cmComputeLinkInformation.cxx: ENH: only complain about -l
- stuff for CMP0003
-
-2008-04-18 10:55 david.cole
-
- * Source/CPack/cpack.cxx: COMP: auto_ptr will not compile without
- including memory on some platforms
-
-2008-04-18 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-17 17:23 alex
-
- * Modules/CPack.cmake, Tests/Tutorial/Step7/CMakeLists.txt: ENH:
- use a common CPACK_BINARY_ prefix for the binary package
- generators
-
- Alex
-
-2008-04-17 12:06 david.cole
-
- * Source/CPack/cpack.cxx: BUG: Fix mem leak. Thanks, Mathieu.
-
-2008-04-17 11:16 david.cole
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: Fix for issue
- #6440. Use 0 instead of FALSE for ExceptionHandling with Visual
- Studio 2005 and later.
-
-2008-04-17 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-16 11:31 david.cole
-
- * Modules/FindwxWidgets.cmake: BUG: There are compiler problems
- with wxWidgets and INCLUDE_DIRECTORIES(SYSTEM ...) use on the
- Mac. Set variable wxWidgets_INCLUDE_DIRS_NO_SYSTEM on the Mac in
- FindwxWidgets.cmake to avoid these problems.
-
-2008-04-16 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-15 09:00 king
-
- * Source/cmELF.cxx: COMP: Fix signed/unsigned comparison warning in
- cmELF.
-
-2008-04-15 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-14 18:03 king
-
- * Source/cmInstallCommand.h: ENH: Clarify documentation of
- install(TARGETS) command to refer to install target types by the
- upper-case keywords used when invoking the command.
-
-2008-04-14 17:53 king
-
- * Source/: cmInstallCommand.cxx, cmInstallCommand.h,
- cmPolicies.cxx, cmPolicies.h: BUG: Fix compatibility with CMake
- 2.4 for installation of MACOSX_BUNDLE targets
-
- - Add policy CMP0006 to decide whether to use compatibility
- - OLD behavior is to fall back to RUNTIME rules
- - NEW behavior is to produce an error
-
-2008-04-14 16:15 clinton
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, CMakeSetupDialog.h:
- BUG: Fix issue when non-error messages were incorrectly colored
- red.
-
-2008-04-14 15:27 king
-
- * Source/cmTarget.cxx, Tests/Framework/CMakeLists.txt: BUG: A
- per-config target name postfix should be ignored for Mac bundle
- and framework names.
-
-2008-04-14 15:25 king
-
- * Modules/CMakeDetermineCompilerABI.cmake: ENH: Clarify message
- about checking for compiler ABI information.
-
-2008-04-14 15:02 king
-
- * Source/: cmFileCommand.cxx, cmFileCommand.h,
- cmInstallTargetGenerator.cxx, cmInstallTargetGenerator.h: ENH:
- Improve RPATH behavior during installation.
-
- - If new RPATH is empty then remove the entry completely
- - Preserve file modification time so installation is not
- repeated
- - If installed file already exists remove it if its RPATH
- does not match that expected
-
-2008-04-14 15:02 king
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Added RPATH
- methods to cmSystemTools
-
- - RemoveRPath to remove the RPATH from a binary
- - CheckRPath to check for an existing RPATH in a binary
-
-2008-04-14 15:02 king
-
- * Source/: cmELF.cxx, cmELF.h: ENH: Added cmELF methods to get
- information about DYNAMIC section entries.
-
-2008-04-14 12:44 king
-
- * Source/cmSystemTools.cxx: COMP: Fix new cmSystemTools file time
- methods on Windows.
-
-2008-04-14 11:43 king
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Added methods
- to cmSystemTools to save and restore file modification times.
-
-2008-04-14 09:20 king
-
- * Source/cmMessageCommand.cxx: ENH: Make message(SEND_ERROR) report
- context.
-
-2008-04-14 09:08 king
-
- * Source/cmMakefileTargetGenerator.cxx: BUG: When
- MACOSX_PACKAGE_LOCATION specifies Headers/foo we must still
- create the Headers symlink.
-
-2008-04-14 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-13 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-12 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-11 13:13 hoffman
-
- * Source/: cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx: BUG: make sure OBJECT_DIR is in
- the path of the SHELL
-
-2008-04-11 10:41 hoffman
-
- * Modules/CPack.RuntimeScript.in: ENH: fix x11 launch script for
- leopord x11 is auto-started for us on that os.
-
-2008-04-11 10:23 hoffman
-
- * Tests/X11/: CMakeLists.txt, HelloWorldX11.cxx: ENH: add a simple
- x11 test for packaging
-
-2008-04-11 10:23 hoffman
-
- * Tests/X11/HelloWorldX11.cxx: file HelloWorldX11.cxx was added on
- branch CMake-2-6 on 2008-04-21 00:44:59 +0000
-
-2008-04-11 09:52 hoffman
-
- * Tests/X11/HelloWorldX11.cxx: ENH: add a simple x11 program
-
-2008-04-11 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-10 16:54 dgregor
-
- * Modules/FindMPI.cmake: ENH: Deal with 32-bit and 64-bit variants
- of Microsoft's MPI properly
-
-2008-04-10 12:50 hoffman
-
- * ChangeLog.manual: ENH: change to RC 8
-
-2008-04-10 12:43 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/FindQt4.cmake,
- Source/cmLocalUnixMakefileGenerator3.cxx: ENH: merge in from main
- tree
-
-2008-04-10 11:55 hoffman
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: the sun make goes
- into some odd n squared thing with this sccs and rcs stuff for
- gmake, so I am removing them.
-
-2008-04-10 10:01 clinton
-
- * Modules/FindQt4.cmake: BUG: Fix typo reported in #6790.
-
-2008-04-10 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-09 14:57 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/FindJNI.cmake,
- Source/cmSystemTools.cxx: ENH: merge from head for RC7
-
-2008-04-09 08:41 hoffman
-
- * Tests/Framework/fooDeepPublic.h,
- Modules/Platform/Darwin-icc.cmake,
- Modules/Platform/Darwin-icpc.cmake: ENH: add missing file
-
-2008-04-09 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-08 17:37 hoffman
-
- * Source/cmSystemTools.cxx: BUG: undo change as it breaks
- preprocess test for some reason??
-
-2008-04-08 16:26 hoffman
-
- * Source/cmTarget.h: ENH: merge from main tree
-
-2008-04-08 16:13 hoffman
-
- * Source/cmTarget.h: ENH: remove qualifier from .h file
-
-2008-04-08 16:09 hoffman
-
- * Modules/FindJNI.cmake: ENH: have jni look more places on linux
-
-2008-04-08 16:06 hoffman
-
- * Source/cmSystemTools.cxx: BUG: half fix for 6688, expand registry
- stuff on unix just like it was not found on windows
-
-2008-04-08 16:05 hoffman
-
- * Source/cmSystemTools.cxx: ENH: half fix for 6688, don't let [
- count go negative
-
-2008-04-08 13:42 king
-
- * Source/cmSystemTools.cxx: ENH: Update cmSystemTools::ChangeRPath
- to support replacing rpath values from the middle of the string.
-
-2008-04-08 12:22 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/FindQt4.cmake,
- Modules/InstallRequiredSystemLibraries.cmake,
- Source/cmComputeLinkInformation.cxx,
- Source/cmExtraEclipseCDT4Generator.cxx, Source/cmFileCommand.cxx,
- Source/cmFindBase.cxx, Source/cmGlobalXCodeGenerator.cxx,
- Source/cmInstallTargetGenerator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmMakefileExecutableTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.h,
- Source/cmMakefileTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.h, Source/cmSystemTools.cxx,
- Source/cmTarget.cxx, Source/cmTarget.h, Source/cmake.cxx,
- Source/cmake.h, Source/QtDialog/CMakeLists.txt,
- Source/QtDialog/CMakeSetup.cxx,
- Source/QtDialog/CMakeSetupDialog.cxx,
- Source/QtDialog/CMakeSetupDialog.h,
- Source/QtDialog/CMakeSetupDialog.ui, Source/QtDialog/QCMake.cxx,
- Source/QtDialog/QCMake.h, Source/QtDialog/QCMakeCacheView.cxx,
- Source/QtDialog/QCMakeCacheView.h,
- Source/QtDialog/QMacInstallDialog.cxx,
- Source/QtDialog/postflight.sh.in, Tests/Framework/CMakeLists.txt:
- ENH: merge in changes from main tree
-
-2008-04-08 11:30 hoffman
-
- * Source/QtDialog/CMakeLists.txt: ENH: make sure cmake-gui builds
- with cmake 2.4.X
-
-2008-04-08 00:06 hoffman
-
- * Tests/Framework/fooDeepPublic.h: file fooDeepPublic.h was added
- on branch CMake-2-6 on 2008-04-09 12:41:34 +0000
-
-2008-04-08 00:06 king
-
- * Source/cmComputeLinkInformation.cxx,
- Source/cmGlobalXCodeGenerator.cxx,
- Source/cmInstallTargetGenerator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.h,
- Source/cmMakefileTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.h, Source/cmTarget.cxx,
- Source/cmTarget.h, Tests/Framework/CMakeLists.txt,
- Tests/Framework/fooDeepPublic.h: BUG: Correct Mac OS X framework
- behavior
-
- - Place the built library in foo.framework/Versions/A/foo
- - Do not create unused content symlinks (like PrivateHeaders)
- - Do not use VERSION/SOVERSION properties for frameworks
- - Make cmTarget::GetDirectory return by value
- - Remove the foo.framework part from cmTarget::GetDirectory
- - Correct install_name construction and conversion on install
- - Fix MACOSX_PACKAGE_LOCATION under Xcode to use the
- Versions/<version> directory for frameworks
- - Update the Framework test to try these things
-
-2008-04-07 23:56 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-07 19:43 clinton
-
- * Modules/FindQt4.cmake:
- BUG: Fix problem with last patch when trying to take substr of
- shorter strings than expected. Fixes #6730.
-
-2008-04-07 19:19 clinton
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, CMakeSetupDialog.h,
- QCMake.cxx, QCMake.h: BUG: Fix #6733. Always convert "\" to "/"
- in source & binary directory fields on Windows.
-
-2008-04-07 13:39 king
-
- * Source/: cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx, cmTarget.cxx, cmTarget.h:
- BUG: Do not create target output directory in cmTarget. Let the
- generators do it.
-
-2008-04-07 11:23 clinton
-
- * Modules/FindQt4.cmake: BUG: Fix 6726. Create correct moc rule
- for configured headers in binary dir.
-
-2008-04-07 10:55 king
-
- * Source/: cmFileCommand.cxx, cmSystemTools.cxx: ENH: Improve error
- message when installation file(CHRPATH) cannot change the RPATH.
-
-2008-04-06 23:57 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-06 22:19 hoffman
-
- * Source/cmFindBase.cxx: BUG: fix network path by mistake in search
-
-2008-04-05 23:57 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-04 23:57 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-04 16:02 hoffman
-
- * CMakeLists.txt, Source/cmFileCommand.cxx, Source/cmake.cxx,
- Source/QtDialog/CMakeLists.txt, Source/QtDialog/CMakeSetup.cxx,
- Source/QtDialog/QMacInstallDialog.cxx,
- Source/QtDialog/postflight.sh.in: ENH: install the mac
- application bundle into /Applications directly with no enclosing
- folder
-
-2008-04-03 23:57 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-03 18:43 alex
-
- * Source/cmExtraEclipseCDT4Generator.cxx: ENH: add edit_cache
- target for Eclipse (if it's not ccmake, because this doesn't work
- inside the log view)
-
- Alex
-
-2008-04-03 18:35 clinton
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, CMakeSetupDialog.ui: ENH:
- Fix exit shortcut to be more standard, and add shortcut for
- advanced checkbox.
-
-2008-04-03 17:02 hoffman
-
- * Source/QtDialog/QMacInstallDialog.cxx: ENH: do not link . and ..
- during install
-
-2008-04-03 16:49 clinton
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, CMakeSetupDialog.ui: ENH:
- Add more shortcuts. Fixes 6357.
-
-2008-04-03 16:18 hoffman
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, CMakeSetupDialog.h,
- QMacInstallDialog.cxx: ENH: add ability to create symlinks for
- command line on mac from gui
-
-2008-04-03 12:29 hoffman
-
- * Modules/InstallRequiredSystemLibraries.cmake: ENH: add vs9 mfc
- libraries
-
-2008-04-03 11:11 hoffman
-
- * Source/cmMakefileTargetGenerator.cxx: BUG: response file must be
- a copy if different or you get relinks every time you run cmake
-
-2008-04-02 23:57 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-02 17:41 clinton
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, CMakeSetupDialog.h,
- QCMake.cxx, QCMake.h:
- ENH: Add debug output option to a new Options menu. Move
- dev warnings option to the new Options menu. Fixes #6335.
-
-2008-04-02 17:29 alex
-
- * Source/: cmake.cxx, cmake.h: ENH: make it possible to disable
- debug output again
-
- Alex
-
-2008-04-02 15:28 clinton
-
- * Source/QtDialog/: QCMakeCacheView.cxx, QCMakeCacheView.h:
- BUG: Keep editor alive when file dialog comes up to pick another
- file or path. The editor going away prematurely Seems to
- only happen on Mac OS X.
-
-2008-04-02 14:01 clinton
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, CMakeSetupDialog.h:
- ENH: Allow cancelling the dialog that prompts for the generator.
-
-2008-04-02 11:07 hoffman
-
- * ChangeLog.manual, Modules/FindQt4.cmake: ENH: merge in findqt
- change from main tree
-
-2008-04-02 11:05 hoffman
-
- * Modules/FindQt4.cmake: BUG: make sure all paths extracted from
- qmake are converted to cmake paths because on windows they will
- have \ instead of / and you can get odd escaping errors
-
-2008-04-02 09:16 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/CPackDeb.cmake,
- Modules/FindQt4.cmake, Source/cmGetPropertyCommand.cxx,
- Source/cmGetPropertyCommand.h,
- Source/cmGlobalVisualStudio8Generator.cxx,
- Source/cmSetPropertyCommand.cxx, Source/cmSetPropertyCommand.h,
- Source/cmSourceFile.cxx, Source/cmTarget.cxx, Source/cmTest.cxx,
- Source/CPack/cmCPackDebGenerator.cxx, Source/kwsys/Process.h.in,
- Source/kwsys/ProcessUNIX.c, Tests/Properties/CMakeLists.txt: ENH:
- merge in main tree for RC 6
-
-2008-04-02 08:36 malaterre
-
- * Source/kwsys/: Process.h.in, ProcessUNIX.c: STYLE: minor comments
-
-2008-04-01 23:57 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-04-01 17:59 alex
-
- * Modules/FindQt4.cmake: STYLE: add documentation for
- QT4_CREATE_MOC and QT4_AUTOMOC (#6687)
-
- Alex
-
-2008-04-01 17:51 hoffman
-
- * Source/CPack/cmCPackDebGenerator.cxx, Modules/CPackDeb.cmake:
- ENH: add CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA variable
-
-2008-04-01 17:39 hoffman
-
- * Source/cmGlobalVisualStudio8Generator.cxx: BUG: fix location of
- tmp file to use the full path, caused error on vista not running
- as admin
-
-2008-04-01 15:22 martink
-
- * Source/cmGetPropertyCommand.cxx: COMP: fix warning
-
-2008-04-01 14:22 martink
-
- * Source/cmGetPropertyCommand.cxx, Source/cmGetPropertyCommand.h,
- Source/cmSetPropertyCommand.cxx, Source/cmSetPropertyCommand.h,
- Source/cmSourceFile.cxx, Source/cmTarget.cxx, Source/cmTest.cxx,
- Tests/Properties/CMakeLists.txt: ENH: support unset of properties
-
-2008-04-01 09:56 hoffman
-
- * Modules/CPackDeb.cmake: ENH: remove trailing space
-
-2008-03-31 23:57 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-31 17:57 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/FindMPI.cmake,
- Source/cmComputeLinkDepends.cxx, Source/cmComputeLinkDepends.h,
- Source/cmComputeLinkInformation.cxx,
- Source/cmExportFileGenerator.cxx, Source/cmListFileCache.cxx,
- Source/cmLocalVisualStudio7Generator.cxx, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmPolicies.cxx: ENH: merge changes
- from head to 26 branch
-
-2008-03-31 13:48 king
-
- * Source/cmExportFileGenerator.cxx: BUG: Generated target export
- files should set the policy version to 2.6 instead of the
- currently running version because they are 2.6 compatible.
-
-2008-03-31 13:33 king
-
- * Source/: cmListFileCache.cxx, cmMakefile.cxx, cmMakefile.h,
- cmPolicies.cxx: ENH: Allow policy CMP0000 to be set explicitly
-
- - Message for missing cmake_minimum_required is not issued
- until the end of processing the top CMakeLists.txt file
- - During processing a cmake_policy command may set behavior
- - OLD behavior is to silently ignore the problem
- - NEW behavior is to issue an error instead of a warning
-
-2008-03-31 12:47 king
-
- * Source/: cmComputeLinkDepends.cxx, cmComputeLinkDepends.h,
- cmComputeLinkInformation.cxx: BUG: Fix bug 6605 more completely
-
- - CMake 2.4 added link directories for targets linked
- in the optimized configuration even when building debug
- - Old behavior for policy CMP0003 must account for this
-
-2008-03-31 10:59 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: ENH: Improve speed of
- manifest tool on VS8 and VS9.
-
- - Detect filesystem type where target will be linked
- - Use FAT32 workaround only when fs is FAT or FAT32
-
-2008-03-31 10:55 dgregor
-
- * Modules/FindMPI.cmake: ENH: Enhance FindMPI module by properly
- handling backward compatibility with the older module, adding
- documentation, and coping with multiple include and linker paths
-
-2008-03-31 08:04 hoffman
-
- * Modules/Platform/Darwin-icpc.cmake: file Darwin-icpc.cmake was
- added on branch CMake-2-6 on 2008-04-09 12:41:47 +0000
-
-2008-03-31 08:04 hoffman
-
- * Modules/Platform/Darwin-icc.cmake: file Darwin-icc.cmake was
- added on branch CMake-2-6 on 2008-04-09 12:41:46 +0000
-
-2008-03-31 08:04 david.cole
-
- * Modules/Platform/: Darwin-icc.cmake, Darwin-icpc.cmake: ENH: Add
- Intel compiler module files for the Mac. Thanks to Mike Jackson
- for contributing.
-
-2008-03-30 23:57 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-30 09:08 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, ChangeLog.txt,
- Modules/CMakeImportBuildSettings.cmake, Modules/CPackDeb.cmake,
- Modules/FindCurses.cmake, Modules/FindQt4.cmake,
- Source/CMakeLists.txt, Source/cmGlobalKdevelopGenerator.cxx,
- Source/cmGlobalKdevelopGenerator.h, Source/cmLocalGenerator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmSystemTools.cxx, Source/cmTarget.cxx, Source/cmake.cxx,
- Source/cmake.h, Source/CPack/cmCPackDebGenerator.cxx,
- Source/QtDialog/CMakeSetupDialog.cxx,
- Source/kwsys/SystemTools.cxx, Source/kwsys/SystemTools.hxx.in,
- Tests/Fortran/test_use_in_comment_fixedform.f: ENH: merge from
- main tree
-
-2008-03-29 23:58 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-29 13:16 hoffman
-
- * Source/cmake.h: ENH: make sure gui no-dev workis
-
-2008-03-28 23:58 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-28 20:23 alex
-
- * Source/CPack/cmCPackDebGenerator.cxx: BUG: fix packaging of files
- installed to absolute paths, works only when used with
- SET(CPACK_SET_DESTDIR "ON")
-
- Alex
-
-2008-03-28 19:09 alex
-
- * Modules/CPackDeb.cmake: STYLE: add a comma to make it better
- understandable, also use STATUS as the other MESSAGE() calls do
-
- Alex
-
-2008-03-28 15:59 hoffman
-
- * Source/cmake.h: ENH: remove dangerous access to ivar that should
- not be used
-
-2008-03-28 15:54 hoffman
-
- * Source/cmLocalGenerator.cxx: ENH: fix for the correct path to
- cmake
-
-2008-03-28 14:29 hoffman
-
- * Source/: cmSystemTools.cxx, cmake.cxx: ENH: try to fix mac
- symlinks to the executable
-
-2008-03-28 14:08 hoffman
-
- * Modules/CPackDeb.cmake: ENH: allow deb to work without dpkg
-
-2008-03-28 14:07 king
-
- * Modules/CMakeImportBuildSettings.cmake: ENH: Patch from Mathieu
- Malaterre to add documentation for his previous patch for
- CMakeImportBuildSettings.
-
-2008-03-28 14:04 king
-
- * Tests/Fortran/test_use_in_comment_fixedform.f: BUG: Fix Fortran
- test to use more portable comment syntax in fixed format source.
-
-2008-03-28 13:26 king
-
- * Modules/CMakeImportBuildSettings.cmake: ENH: Patch from Mathieu
- Malaterre to allow users to tell CMakeImportBuildSettings to not
- force compiler settings.
-
-2008-03-28 13:22 king
-
- * Source/CMakeLists.txt: COMP: Add missing module for
- CHECK_INCLUDE_FILE macro.
-
-2008-03-28 13:07 king
-
- * Source/cmTarget.cxx: ENH: Add note to Fortran_MODULE_DIRECTORY
- property documentation about using CMAKE_Fortran_MODULE_DIRECTORY
- to initialize it.
-
-2008-03-28 12:53 clinton
-
- * Source/QtDialog/CMakeSetupDialog.cxx: ENH: Better default size
- for help dialog.
-
-2008-03-28 11:47 hoffman
-
- * Modules/: CPackDeb.cmake: ENH: remove hard codeded arch
-
-2008-03-28 10:12 hoffman
-
- * Modules/FindCurses.cmake: ENH: make this backwards compatible
- with older FindCurses
-
-2008-03-28 10:08 hoffman
-
- * Modules/FindCurses.cmake: ENH: make this backwards compatible
- with older FindCurses
-
-2008-03-27 23:58 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-27 22:00 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: fix for 6619
-
-2008-03-27 21:54 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: fix for bug 6660
-
-2008-03-27 21:51 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: fix for bug 6661
-
-2008-03-27 17:40 alex
-
- * Source/: cmGlobalKdevelopGenerator.cxx,
- cmGlobalKdevelopGenerator.h: COMP: fix warning about unused mf
- -"make VERBOSE=1 <target>" should be more portable than
- "VERBOSE=1 make <target>", since it doesn't rely on the shell,
- shouldn't it ?
-
- Alex
-
-2008-03-27 17:05 hoffman
-
- * Source/: cmake.cxx, kwsys/SystemTools.cxx,
- kwsys/SystemTools.hxx.in: BUG: fix install problem on make and
- allow symlinks to cmake bin directory
-
-2008-03-27 15:33 alex
-
- * Source/cmGlobalKdevelopGenerator.cxx: ENH: -enable colored output
- with the kdevelop generator -create non-verbose makefiles and
- have kdevelop call "VERBOSE=1 make" instead
-
- Alex
-
-2008-03-27 15:18 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Add QT_VERSION_MAJOR, QT_VERSION_MINOR, QT_VERSION_PATCH
- variables.
-
-2008-03-27 13:30 hoffman
-
- * ChangeLog.txt: ENH: remove DashboardScripts and CMakeWeb from the
- change log
-
-2008-03-27 13:27 hoffman
-
- * ChangeLog.txt: ENH: check in new change log for 2.6
-
-2008-03-27 11:16 hoffman
-
- * CMakeLists.txt, Modules/CPack.cmake,
- Source/cmInstallCommandArguments.cxx, Source/cmake.cxx: ENH:
- merge in from main tree
-
-2008-03-26 23:58 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-26 22:34 hoffman
-
- * Source/cmake.cxx: ENH: clean up annoying output from rc tool in
- VS9
-
-2008-03-26 20:12 alex
-
- * Modules/CPack.cmake: ENH: use CPACK_PACKAGE_VERSION instead of
- CPACK_PACKAGE_VERSION_MAJOR.CPACK_PACKAGE_VERSION_MINOR.CPACK_PACKAGE_VERSION_PATCH
- for creating the package file name
-
- Alex
-
-2008-03-26 18:30 alex
-
- * Source/cmInstallCommandArguments.cxx: BUG: fix the default
- "Unspecified" component when only the generic (i.e. not RUNTIME,
- ARCHIVE, LIBRARY, etc.) arguments are given.
-
- If the component of a part of a target is queried, return the
- specific one, if a specific one hasn't been set, return the
- generic one, if that hasn't been set, return "Unspecified".
-
- Alex
-
-2008-03-26 15:55 hoffman
-
- * Utilities/Release/: v20n17_aix_release.cmake,
- vogon_release_qt.cmake: ENH:
-
-2008-03-26 14:08 hoffman
-
- * CMakeLists.txt, Modules/CMakeJavaInformation.cmake,
- Modules/FindSubversion.cmake, Source/cmCoreTryCompile.cxx: ENH:
- merge in from main tree
-
-2008-03-26 13:50 hoffman
-
- * Source/cmCoreTryCompile.cxx: ENH: make sure numAttempts is
- incremented
-
-2008-03-26 13:14 hoffman
-
- * Source/cmCoreTryCompile.cxx: ENH: try to fix dashboard issue with
- not being able to remove try compile code
-
-2008-03-25 23:58 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-25 19:58 hoffman
-
- * CMakeLists.txt, Source/cmLocalUnixMakefileGenerator3.cxx,
- Tests/Assembler/CMakeLists.txt,
- Tests/BuildDepends/CMakeLists.txt,
- Tests/BundleTest/CMakeLists.txt, Tests/COnly/CMakeLists.txt,
- Tests/CTestTest/CMakeLists.txt, Tests/CTestTest2/CMakeLists.txt,
- Tests/CommandLineTest/CMakeLists.txt,
- Tests/ConvLibrary/CMakeLists.txt,
- Tests/CustComDepend/CMakeLists.txt,
- Tests/CustomCommand/CMakeLists.txt,
- Tests/CustomCommandWorkingDirectory/CMakeLists.txt,
- Tests/Dependency/CMakeLists.txt, Tests/DocTest/CMakeLists.txt,
- Tests/ExportImport/CMakeLists.txt,
- Tests/ExportImport/Export/CMakeLists.txt,
- Tests/ExportImport/Import/CMakeLists.txt,
- Tests/ExternalOBJ/CMakeLists.txt,
- Tests/ExternalOBJ/Object/CMakeLists.txt,
- Tests/FindPackageTest/CMakeLists.txt,
- Tests/Fortran/CMakeLists.txt, Tests/Framework/CMakeLists.txt,
- Tests/FunctionTest/CMakeLists.txt, Tests/Java/CMakeLists.txt,
- Tests/Jump/CMakeLists.txt, Tests/LoadCommand/CMakeLists.txt,
- Tests/LoadCommandOneConfig/CMakeLists.txt,
- Tests/LoadCommand/CMakeCommands/CMakeLists.txt,
- Tests/LoadCommandOneConfig/CMakeCommands/CMakeLists.txt,
- Tests/MacroTest/CMakeLists.txt, Tests/MakeClean/CMakeLists.txt,
- Tests/MathTest/CMakeLists.txt, Tests/NewlineArgs/CMakeLists.txt,
- Tests/OutOfSource/CMakeLists.txt, Tests/Plugin/CMakeLists.txt,
- Tests/PrecompiledHeader/CMakeLists.txt,
- Tests/Properties/CMakeLists.txt, Tests/ReturnTest/CMakeLists.txt,
- Tests/RuntimePath/CMakeLists.txt, Tests/SameName/CMakeLists.txt,
- Tests/SetLang/CMakeLists.txt, Tests/SimpleExclude/CMakeLists.txt,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt,
- Tests/SourceGroups/CMakeLists.txt,
- Tests/StringFileTest/CMakeLists.txt, Tests/SubDir/CMakeLists.txt,
- Tests/SubDir/Examples/CMakeLists.txt,
- Tests/SubDir/Examples/example1/CMakeLists.txt,
- Tests/SubDirSpaces/CMakeLists.txt, Tests/SubDirSpaces/Some
- Examples/CMakeLists.txt, Tests/SubDirSpaces/Some
- Examples/example1/CMakeLists.txt,
- Tests/SubProject/CMakeLists.txt, Tests/SwigTest/CMakeLists.txt,
- Tests/SystemInformation/CMakeLists.txt,
- Tests/TarTest/CMakeLists.txt, Tests/TargetName/CMakeLists.txt,
- Tests/TestDriver/CMakeLists.txt, Tests/Testing/CMakeLists.txt,
- Tests/TryCompile/CMakeLists.txt,
- Tests/Tutorial/Step1/CMakeLists.txt,
- Tests/Tutorial/Step2/CMakeLists.txt,
- Tests/Tutorial/Step3/CMakeLists.txt,
- Tests/Tutorial/Step4/CMakeLists.txt,
- Tests/Tutorial/Step5/CMakeLists.txt,
- Tests/Tutorial/Step6/CMakeLists.txt,
- Tests/Tutorial/Step7/CMakeLists.txt,
- Tests/VSExternalInclude/CMakeLists.txt,
- Tests/Wrapping/CMakeLists.txt, Tests/X11/CMakeLists.txt: ENH:
- merge in from main tree
-
-2008-03-25 14:37 martink
-
- * Tests/ExternalOBJ/CMakeLists.txt: BUG: make test more robust
-
-2008-03-25 14:15 martink
-
- * Tests/ExternalOBJ/CMakeLists.txt: BUG: add debugging into to
- check out a problem
-
-2008-03-25 11:26 martink
-
- * Tests/: Assembler/CMakeLists.txt, BuildDepends/CMakeLists.txt,
- BundleTest/CMakeLists.txt, COnly/CMakeLists.txt,
- CTestTest/CMakeLists.txt, CTestTest2/CMakeLists.txt,
- CommandLineTest/CMakeLists.txt, ConvLibrary/CMakeLists.txt,
- CustComDepend/CMakeLists.txt, CustomCommand/CMakeLists.txt,
- CustomCommandWorkingDirectory/CMakeLists.txt,
- Dependency/CMakeLists.txt, DocTest/CMakeLists.txt,
- ExportImport/CMakeLists.txt, ExportImport/Export/CMakeLists.txt,
- ExportImport/Import/CMakeLists.txt, ExternalOBJ/CMakeLists.txt,
- ExternalOBJ/Object/CMakeLists.txt,
- FindPackageTest/CMakeLists.txt, Fortran/CMakeLists.txt,
- Framework/CMakeLists.txt, FunctionTest/CMakeLists.txt,
- Java/CMakeLists.txt, Jump/CMakeLists.txt,
- LoadCommand/CMakeLists.txt, LoadCommandOneConfig/CMakeLists.txt,
- LoadCommand/CMakeCommands/CMakeLists.txt,
- LoadCommandOneConfig/CMakeCommands/CMakeLists.txt,
- MacroTest/CMakeLists.txt, MakeClean/CMakeLists.txt,
- MathTest/CMakeLists.txt, NewlineArgs/CMakeLists.txt,
- OutOfSource/CMakeLists.txt, Plugin/CMakeLists.txt,
- PrecompiledHeader/CMakeLists.txt, Properties/CMakeLists.txt,
- ReturnTest/CMakeLists.txt, RuntimePath/CMakeLists.txt,
- SameName/CMakeLists.txt, SetLang/CMakeLists.txt,
- SimpleExclude/CMakeLists.txt, SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt, SourceGroups/CMakeLists.txt,
- StringFileTest/CMakeLists.txt, SubDir/CMakeLists.txt,
- SubDir/Examples/CMakeLists.txt,
- SubDir/Examples/example1/CMakeLists.txt,
- SubDirSpaces/CMakeLists.txt, SubDirSpaces/Some
- Examples/CMakeLists.txt, SubDirSpaces/Some
- Examples/example1/CMakeLists.txt, SubProject/CMakeLists.txt,
- SwigTest/CMakeLists.txt, SystemInformation/CMakeLists.txt,
- TarTest/CMakeLists.txt, TargetName/CMakeLists.txt,
- TestDriver/CMakeLists.txt, Testing/CMakeLists.txt,
- TryCompile/CMakeLists.txt, Tutorial/Step1/CMakeLists.txt,
- Tutorial/Step2/CMakeLists.txt, Tutorial/Step3/CMakeLists.txt,
- Tutorial/Step4/CMakeLists.txt, Tutorial/Step5/CMakeLists.txt,
- Tutorial/Step6/CMakeLists.txt, Tutorial/Step7/CMakeLists.txt,
- VSExternalInclude/CMakeLists.txt, Wrapping/CMakeLists.txt,
- X11/CMakeLists.txt: ENH: preclean some warnings
-
-2008-03-25 10:11 hoffman
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: fix for watcom
- can't use phony
-
-2008-03-24 23:58 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-24 18:23 hoffman
-
- * CMakeLists.txt, Modules/FindBLAS.cmake, Modules/FindKDE4.cmake,
- Modules/FindLAPACK.cmake, Modules/FindMPI.cmake,
- Modules/FindQt4.cmake, Modules/FindSubversion.cmake,
- Source/cmCMakeMinimumRequired.cxx,
- Source/cmCMakePolicyCommand.cxx,
- Source/cmComputeLinkInformation.cxx, Source/cmCoreTryCompile.cxx,
- Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmIfCommand.cxx, Source/cmIfCommand.h,
- Source/cmListFileCache.cxx,
- Source/cmLocalUnixMakefileGenerator3.cxx, Source/cmPolicies.cxx,
- Source/cmake.cxx, Source/cmake.h,
- Source/CTest/cmCTestBuildHandler.cxx,
- Tests/Complex/CMakeLists.txt,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexRelativePaths/CMakeLists.txt,
- Tests/MakeClean/ToClean/CMakeLists.txt,
- Tests/Preprocess/CMakeLists.txt: ENH: merge in from CVS
-
-2008-03-24 15:41 hoffman
-
- * Modules/FindMPI.cmake: ENH: remove use of undefined cdr
-
-2008-03-24 15:40 hoffman
-
- * Modules/FindQt4.cmake: ENH: fix if
-
-2008-03-24 11:49 alin.elena
-
- * Modules/: FindBLAS.cmake, FindLAPACK.cmake: ENH:
- FindBLAS.cmake&FindLAPACK updated to support intel mkl 10
-
-2008-03-24 10:56 king
-
- * Source/: cmCMakeMinimumRequired.cxx, cmCMakePolicyCommand.cxx,
- cmPolicies.cxx: ENH: Cleanup policy version interface presented
- to user.
-
- - In cmake_minimum_required do not set policy version if
- current
- CMake is too old
- - In cmPolicies::ApplyPolicyVersion report error if version is
- too
- new or cannot be parsed
-
-2008-03-24 10:26 hoffman
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.cxx: ENH: add PHONY targets
-
-2008-03-23 23:58 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-22 23:58 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-22 10:24 hoffman
-
- * Source/: cmake.h, cmake.cxx: ENH: make sure -Wno-dev sticks so
- make rebuild_cache will work
-
-2008-03-21 23:58 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-20 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-20 21:11 king
-
- * Source/: cmComputeLinkInformation.cxx,
- cmComputeLinkInformation.h, cmPolicies.cxx: ENH: Yet another
- attempt at warning for CMP0003.
-
- - Give example code to avoid the warning
- - Make explanation more consise
- - Explicitly state this is for compatibility
- - Issue the warning for at most one target
-
-2008-03-20 18:25 king
-
- * Source/cmIfCommand.cxx, Source/cmIfCommand.h,
- Tests/Complex/CMakeLists.txt,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexRelativePaths/CMakeLists.txt: ENH: Add "if(POLICY
- policy-id)" option for IF command.
-
- - This will help projects support multiple CMake versions.
- - In order to set a policy when using a newer CMake but still
- working with an older CMake one may write
- if(POLICY CMP1234)
- cmake_policy(SET CMP1234 NEW)
- endif(POLICY CMP1234)
- - Note that since CMake 2.4 does not have if(POLICY) supporting
- it will also require using "if(COMMAND cmake_policy)"
-
-2008-03-20 18:25 king
-
- * Tests/: MakeClean/ToClean/CMakeLists.txt,
- Preprocess/CMakeLists.txt: BUG: Convert cmake_policy(VERSION) to
- cmake_minimum_required(VERSION) in
- Tests/MakeClean/ToClean/CMakeLists.txt and
- Tests/Preprocess/CMakeLists.txt. CMP0000 now requires the
- cmake_minimum_required command.
-
-2008-03-20 11:44 david.cole
-
- * Modules/FindSubversion.cmake: BUG: Remove reference to
- PROJECT_SOURCE_DIR so that the Subversion_WC_INFO macro may be
- called from a ctest or cmake script.
-
-2008-03-20 10:46 martink
-
- * Source/cmListFileCache.cxx: ENH: tiny performance improvement
-
-2008-03-20 10:40 martink
-
- * Source/cmListFileCache.cxx: ENH: small simple projects do not
- need to specify cmake minimum required
-
-2008-03-20 10:11 king
-
- * Source/cmake.cxx: ENH: Clarify end of (dev) warnings to
- explicitly state they are meant for project developers.
-
-2008-03-19 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-19 16:14 clinton
-
- * Modules/FindQt4.cmake:
- BUG: Fix issue when Qt from Linux distro is used and glib
- and dbus development packages aren't installed.
-
-2008-03-19 15:44 king
-
- * Source/cmCoreTryCompile.cxx: BUG: Change generated try-compile
- projects to use cmake_minimum_required instead of cmake_policy to
- set the version now that CMP0000 requires it.
-
-2008-03-19 15:27 clinton
-
- * Modules/FindQt4.cmake: BUG: Don't clear output strings before
- using.
-
-2008-03-19 15:18 king
-
- * Source/: cmListFileCache.cxx, cmPolicies.cxx: ENH: Improve
- warning about specifying a cmake version
-
- - Update policy CMP0000 to require use of the command
- cmake_minimum_required and not cmake_policy
- so there is only one way to avoid it.
- - Explicitly specify the line users should add.
- - Reference policy CMP0000 only at the end.
- - Fix policy CMP0000 documentation to not suggest
- use of the cmake_policy command.
-
-2008-03-19 14:32 king
-
- * Source/cmComputeLinkInformation.cxx: ENH: Clarify warning for
- policy CMP0003 further.
-
-2008-03-19 11:18 david.cole
-
- * Source/CTest/cmCTestBuildHandler.cxx: BUG: Missing a linker
- crashed error matching string.
-
-2008-03-19 09:14 hoffman
-
- * Source/cmComputeLinkInformation.cxx: ENH: do not warn about
- frameworks as they are not affected by -L anyway
-
-2008-03-18 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-18 21:22 hoffman
-
- * CMakeLists.txt: ENH: forgot to check this in, need to change the
- version in CVS
-
-2008-03-18 18:37 clinton
-
- * Modules/FindQt4.cmake:
- STYLE: Improve documentation by expanding on how UseQt4.cmake
- fits in.
-
-2008-03-18 17:54 alex
-
- * Modules/FindQt4.cmake: STYLE: fix documentation again:
- QT_LIBRARIES exists if you use Qt4 via UseQt4.cmake
-
- Alex
-
-2008-03-18 17:32 hoffman
-
- * Source/: cmComputeLinkInformation.cxx,
- cmComputeLinkInformation.h: ENH: try to reduce the number of
- CMP0003 warnings that people see. Only report them for unique
- sets of libraries with no full path. Also add a message
- explaining the course of action that should be taken
-
-2008-03-18 17:26 alex
-
- * Modules/FindQt4.cmake: STYLE: fix documentation, QT_LIBRARIES
- doesn't exist, and also didn't exist in cmake 2.4.3, the first
- stable cmake 2.4.x release
-
- Alex
-
-2008-03-18 16:30 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Satisfy QtDBus dependencies for builds with static Qt.
- Finish fix for #6607.
-
-2008-03-18 11:51 hoffman
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: exclude borland
- make as well
-
-2008-03-18 11:28 hoffman
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: turn off extra
- rules for nmake and wmake
-
-2008-03-18 11:11 hoffman
-
- * CMakeLists.txt: ENH: set the version on 2.6
-
-2008-03-18 10:23 hoffman
-
- * CMakeLists.txt, Modules/CTest.cmake, Modules/FindKDE4.cmake,
- Modules/FindPackageHandleStandardArgs.cmake,
- Modules/FindPackageMessage.cmake, Modules/FindQt4.cmake,
- Modules/FindX11.cmake, Modules/UseQt4.cmake,
- Modules/VTKCompatibility.cmake,
- Modules/Platform/Linux-GNU-Fortran.cmake,
- Modules/Platform/Linux-ifort.cmake,
- Modules/Platform/Windows-cl.cmake,
- Source/cmCMakeMinimumRequired.h, Source/cmCMakePolicyCommand.h,
- Source/cmComputeLinkDepends.cxx, Source/cmComputeLinkDepends.h,
- Source/cmComputeLinkInformation.cxx,
- Source/cmComputeLinkInformation.h,
- Source/cmDocumentVariables.cxx, Source/cmExportFileGenerator.cxx,
- Source/cmListCommand.cxx,
- Source/cmLocalUnixMakefileGenerator3.cxx, Source/cmMakefile.cxx,
- Source/cmPolicies.cxx, Source/cmPolicies.h,
- Source/cmSourceFileLocation.cxx, Source/cmTarget.cxx,
- Source/cmTarget.h, Source/QtDialog/CMakeSetup.cxx,
- Source/QtDialog/CMakeSetupDialog.cxx,
- Source/kwsys/CMakeLists.txt, Source/kwsys/kwsysDateStamp.cmake,
- Utilities/cmcurl/CMakeLists.txt: ENH: move head to branch
-
-2008-03-18 10:02 hoffman
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: try to improve
- make speed by getting rid of some implicit rules that were still
- around.
-
-2008-03-17 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-17 20:30 king
-
- * Source/cmCMakePolicyCommand.h: ENH: Improve documentation of
- cmake_policy command.
-
- - Add a paragraph introducing the policy mechanism
- - Explicitly introduce the CMP<NNNN>, OLD, and NEW notation
- - Note that setting policies by CMake version is preferred
- - Fix SET signature to use CMP<NNNN> notation
- - Add more details about the policy stack
-
-2008-03-17 16:22 king
-
- * CMakeLists.txt, Source/kwsys/CMakeLists.txt,
- Utilities/cmcurl/CMakeLists.txt: ENH: Set CMake Policy CMP0003 to
- NEW behavior to build without warnings with the upcoming CMake
- 2.6 release.
-
-2008-03-17 14:53 clinton
-
- * Modules/FindQt4.cmake:
- ENH: For Mac OS X, remove QuickTime link for Qt 4.3+ and add
- AppKit link for Qt 4.2+.
-
-2008-03-17 11:10 hoffman
-
- * Modules/FindPackageMessage.cmake: file FindPackageMessage.cmake
- was added on branch CMake-2-6 on 2008-03-18 14:23:52 +0000
-
-2008-03-17 11:10 king
-
- * Modules/: FindPackageHandleStandardArgs.cmake,
- FindPackageMessage.cmake, FindQt4.cmake, FindX11.cmake: ENH:
- Added FindPackageMessage module
-
- - Defines FIND_PACKAGE_MESSAGE function to help display
- find result messages only once
- - Added use of it to FindPackageHandleStandardArgs
- - Added use of it to FindQt4, and FindX11
- - This cleans up repeated messages in big projects
-
-2008-03-17 11:10 king
-
- * Modules/CTest.cmake: ENH: Avoid printing message about unknown
- repository type repeatedly in CTest.
-
-2008-03-17 08:55 king
-
- * Modules/Platform/: Linux-GNU-Fortran.cmake, Linux-ifort.cmake:
- ENH: Patch from Maik to add per-configuration default flags to
- GCC and Intel Fortran compilers on Linux.
-
-2008-03-16 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-15 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-15 20:10 david.cole
-
- * Modules/CMakeJavaInformation.cmake: BUG: Go back to using "." so
- the Java test passes on the nightly nmake dashboards again. Still
- need a solution that works with both nmake and Visual Studio
- builds.
-
-2008-03-15 10:00 king
-
- * Source/cmComputeLinkInformation.cxx: COMP: Fix unreachable code
- warning for break after return in switch in CMP0003 impl.
-
-2008-03-15 10:00 king
-
- * Source/: cmTarget.cxx, cmSourceFileLocation.cxx: STYLE: Fix
- line-too-long for new INTERNAL_ERROR messages.
-
-2008-03-14 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-14 18:16 alex
-
- * Modules/FindKDE4.cmake: ENH: preparations for cross compiling
- KDE4
-
- Alex
-
-2008-03-14 16:39 barre
-
- * Source/cmListCommand.cxx: STYLE: yeah yeah.
-
-2008-03-14 15:18 clinton
-
- * Source/QtDialog/CMakeSetup.cxx:
- ENH: Prevent loading standard qt plugins at runtime (which we
- dont' care about). This can cause problems if a Mac bundle
- doesn't contain the plugins.
-
-2008-03-14 14:28 clinton
-
- * Modules/FindQt4.cmake: BUG: Fix typo to find QAssistantClient
- header.
-
-2008-03-14 14:21 king
-
- * Source/cmComputeLinkInformation.cxx: ENH: Improve CMP0003 to
- provide more compatibility
-
- - Targets built in the tree now add compatibility paths too
- - The warning message's first list includes at most one item
- for each unique compatibility path
- - Clarified error message further
-
-2008-03-14 13:29 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Satisfy QtNetwork and QtOpenGL dependencies for builds with
- static Qt. Partial fix for #6607.
-
-2008-03-14 13:16 clinton
-
- * Modules/: FindQt4.cmake, UseQt4.cmake:
- ENH: Automatically add dependent modules. For example, if
- QT_USE_QTXMLPATTERNS is on, QT_USE_QTNETWORK is turned on.
- The equivalent happens in a qmake .pro file when QT +=
- xmlpatterns is specified.
-
-2008-03-14 12:11 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Support static Qt 4.4 builds using QtHelp module.
-
-2008-03-13 19:12 clinton
-
- * Modules/: FindQt4.cmake, UseQt4.cmake:
- ENH: Add support for Qt 4.4's phonon module. Add new Qt
- 4.4 modules in UseQt4.cmake
-
-2008-03-13 17:38 king
-
- * Source/cmMakefile.cxx: BUG: Fix impl of CMP0005 regex to match
- value-less definitions.
-
-2008-03-13 17:32 king
-
- * Source/: cmCMakeMinimumRequired.h, cmPolicies.cxx: ENH: Clarify
- documentation of policy CMP0000 and its relationship with
- cmake_minimum_required.
-
-2008-03-13 17:11 king
-
- * Source/: cmMakefile.cxx, cmPolicies.cxx, cmPolicies.h: ENH: Add
- policy CMP0005 to decide whether add_definitions should escape
- defs.
-
-2008-03-13 17:04 king
-
- * Source/cmExportFileGenerator.cxx: ENH: Add cmake_policy
- push/version/pop to import/export files.
-
-2008-03-13 16:42 hoffman
-
- * Modules/Platform/Windows-cl.cmake: ENH: fix c flags for 2003 free
- command line tools
-
-2008-03-13 16:35 king
-
- * Source/: cmComputeLinkDepends.cxx, cmComputeLinkDepends.h,
- cmPolicies.cxx, cmPolicies.h, cmTarget.cxx, cmTarget.h: ENH: Add
- policy CMP_0004 to require library names to have no leading or
- trailing whitespace. Replace previous check of
- CMAKE_BACKWARDS_COMPATIBILITY against version 2.4 with the
- policy.
-
-2008-03-13 16:23 king
-
- * Modules/VTKCompatibility.cmake,
- Source/cmComputeLinkInformation.cxx,
- Source/cmComputeLinkInformation.h,
- Source/cmDocumentVariables.cxx, Source/cmPolicies.cxx,
- Source/cmPolicies.h, Source/cmTarget.cxx, Source/cmTarget.h: ENH:
- Convert CMAKE_LINK_OLD_PATHS to policy CMP0003.
-
- - Policy is WARN by default so projects will build
- as they did in 2.4 without user intervention
- - Remove CMAKE_LINK_OLD_PATHS variable since it was
- never in a release and the policy supercedes it
- - Report target creation backtrace in warning message
- since policy should be set by that point
-
-2008-03-13 16:21 hoffman
-
- * Source/QtDialog/CMakeSetupDialog.cxx: ENH: make menu item match
- -Wno-dev command line
-
-2008-03-13 16:13 clinton
-
- * Source/QtDialog/CMakeSetupDialog.cxx: ENH: Preserve white spaces
- when printing messages.
-
-2008-03-13 15:34 hoffman
-
- * Source/cmake.cxx: ENH: move the clear to before things are added
- to the maps
-
-2008-03-13 15:29 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Add support for new modules in Qt 4.4. Fixes #6316.
- Simplify and clarify some documentation.
-
- BUG: Fix order of include paths (from KDE's FindQt4) Fix
- find of Designer components debug library on Windows.
-
-2008-03-13 15:06 king
-
- * Source/cmake.cxx: ENH: Make (dev) warnings show note about
- -Wno-dev option. Fix -Wdev and -Wno-dev options to not be
- mistaken for the source directory specification.
-
-2008-03-13 15:03 david.cole
-
- * Modules/CMakeJavaInformation.cmake: COMP: Conditionalize the last
- change so that the fix only applies to WIN32. Leave it the way it
- was elsewhere, the new way does not work on the Mac continuous
- dashboard...
-
-2008-03-13 15:01 king
-
- * Source/cmPolicies.cxx: ENH: Reduce whitespace in policy
- warning/error messages.
-
-2008-03-13 14:29 david.cole
-
- * Modules/CMakeJavaInformation.cmake: BUG: Fix the Java test for
- Visual Studio builds. Before this, it had been trying to include
- "BuildLog.htm" in the .jar file because it was using "." as the
- list of files to include in the .jar file. Use "*.class" instead
- of "." to prevent this silliness.
-
-2008-03-13 14:13 king
-
- * Source/cmMakefile.cxx: ENH: Improve error message when invalid
- policy is given.
-
-2008-03-13 13:52 king
-
- * Source/cmSetCommand.cxx: ENH: Simplify error message for invalid
- set(... CACHE) calls to make it look nicer with new message
- format.
-
-2008-03-13 13:48 king
-
- * Source/: cmListFileCache.cxx, cmListFileCache.h, cmMakefile.cxx,
- cmMakefile.h, cmTarget.cxx, cmTarget.h, cmake.cxx, cmake.h: ENH:
- Improve new error/warning message generation
-
- - Add cmListFileBacktrace to record stack traces
- - Move main IssueMessage method to the cmake class instance
- (make the backtrace an explicit argument)
- - Change cmMakefile::IssueMessage to construct a backtrace
- and call the cmake instance version
- - Record a backtrace at the point a target is created
- (useful later for messages issued by generators)
-
-2008-03-13 11:38 martink
-
- * Source/: cmCMakePolicyCommand.h, cmListFileCache.cxx,
- cmLocalGenerator.cxx, cmMakefile.cxx, cmPolicies.cxx,
- cmPolicies.h, cmake.cxx: ENH: change CMP_ to CMP
-
-2008-03-13 10:56 hoffman
-
- * Modules/FindGLUT.cmake: BUG: fix bug 6594 look for glut in more
- places on windows
-
-2008-03-13 09:28 barre
-
- * Source/cmFileCommand.cxx: BUG: the directory the FILE DOWNLOAD
- command is writing to might not exist.
-
-2008-03-12 23:59 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-12 21:54 hoffman
-
- * CMakeCPackOptions.cmake.in,
- Source/CPack/cmCPackCygwinBinaryGenerator.cxx,
- Source/CPack/cmCPackCygwinSourceGenerator.cxx,
- Source/CPack/cmCPackGenerator.cxx: ENH: fix crash in cpack when
- CPACK_CYGWIN_PATCH_NUMBER not specified
-
-2008-03-12 21:06 hoffman
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx, cmMakefile.cxx,
- cmSourceFileLocation.cxx, cmTarget.cxx, cmake.h: ENH: remove
- abort calls and replace with an IssueMessage INTERANL_ERROR,
- better to not crash on the end user.
-
-2008-03-12 17:02 hoffman
-
- * Source/: cmake.cxx, cmake.h: ENH: make sure properties are re-set
- on each configure
-
-2008-03-12 17:02 barre
-
- * Source/cmListCommand.cxx, Source/cmListCommand.h,
- Tests/CMakeTests/ListTest.cmake.in: ENH: add REMOVE_DUPLICATES
- subcommand to LIST command (and test). Remove duplicates from a
- list (keep the ordering)
-
-2008-03-12 14:37 martink
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: BUG: fix some bad
- changes in progress calc
-
-2008-03-12 09:25 hoffman
-
- * Source/cmMakefile.cxx: STYLE: fix line len
-
-2008-03-12 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-11 22:52 hoffman
-
- * Source/QtDialog/CMakeSetupDialog.cxx: ENH: remove iostream, not
- used
-
-2008-03-11 22:50 hoffman
-
- * Source/: cmake.cxx, cmake.h, QtDialog/CMakeSetupDialog.cxx,
- QtDialog/CMakeSetupDialog.h, QtDialog/QCMake.cxx,
- QtDialog/QCMake.h: ENH: add ability to suppress dev warnings to
- gui code
-
-2008-03-11 17:53 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Fix subtle bug
- that prevented Makefile generators from rescanning dependencies
- when a new source file is added but no other sources are touched.
-
-2008-03-11 17:37 king
-
- * Source/kwsys/SystemInformation.hxx.in: COMP: Fix shared lib build
- on windows for KWSys's SystemInformation by adding export macro.
-
-2008-03-11 17:27 hoffman
-
- * Source/QtDialog/: CMake.desktop, CMakeLists.txt, cmakecache.xml:
- ENH: add KDE desktop stuff
-
-2008-03-11 17:27 hoffman
-
- * Source/cmMakefile.cxx: ENH: fix warning message a bit
-
-2008-03-11 17:25 king
-
- * Source/: cmGlobalVisualStudio8Generator.cxx, cmake.cxx, cmake.h:
- BUG: Fixes to VS8/VS9 project regeneration rules
-
- - ZERO_CHECK should check all stamps in case
- of parallel build (fixes complex test failure)
- - ZERO_CHECK should not appear when
- CMAKE_SUPPRESS_REGENERATION is on (fixes bug 6490)
-
-2008-03-11 16:02 hoffman
-
- * Source/: cmake.h, cmakemain.cxx: ENH: fix -Wno-dev for ccmake
-
-2008-03-11 15:17 hoffman
-
- * Source/: cmMakefile.cxx, cmake.cxx, cmakemain.cxx: ENH: add a way
- to suppress the new policy warnings, still need ccmake and gui's
-
-2008-03-11 10:54 barre
-
- * Docs/cmake-mode.el: ENH: add simple function to convert all CMake
- commands to lowercase
-
-2008-03-11 10:29 hoffman
-
- * Source/: cmListFileCache.cxx, cmMakefile.cxx, cmMakefile.h,
- cmPolicies.cxx, cmake.h: ENH: add enum to IssueMessage
-
-2008-03-11 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-10 18:48 barre
-
- * Modules/: FindCVS.cmake: ENH: for some reasons there was never a
- FindCVS module?
-
-2008-03-10 15:41 king
-
- * Source/cmMakefile.cxx: ENH: Enforce matching PUSH/POP calls for
- cmake_policy.
-
-2008-03-10 15:40 king
-
- * Source/cmMakefile.cxx: ENH: Add directory-level context
- information to error/warning messages when no call stack is
- present.
-
-2008-03-10 13:26 alex
-
- * Modules/: FindLua50.cmake, FindLua51.cmake: ENH: use the standard
- find_package_handle_standard_args() for lua 5.0 and 5.1
-
- Alex
-
-2008-03-10 09:32 king
-
- * Modules/: CMakeCCompilerId.c.in, CMakeCXXCompilerId.cpp.in,
- CMakePlatformId.h.in: ENH: Make compiler id detection more robust
-
- - Split INFO strings in source into multiple pieces
- to make sure assembly or other listings produced
- by the compiler are never matched by the regex
- - Store INFO strings via pointer instead of array
- to convince some compilers to store the string
- literally in the binary
- - This should help make it work for sdcc 2.8.0 RC1
-
-2008-03-10 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-09 19:20 alex
-
- * Modules/CMakeDetermineCompilerId.cmake: BUG: make compiler id
- detection (almost) work again with sdcc 2.8.0 RC1, mail sent to
- Brad for the remaining issue don't match INFO:compiler["
- COMPILER_ID "] which appears in the assembler file generated from
- the C file by sdcc, but make sure the first character after the [
- is no double quote
-
- Alex
-
-2008-03-09 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-08 09:50 king
-
- * Source/cmIncludeDirectoryCommand.cxx: BUG: Fix
- include_directories command to produce an immediately whether or
- not 2.4 compatibility is enabled. CMake 2.4 already produced an
- error, just not immediately.
-
-2008-03-08 09:27 king
-
- * Source/cmIncludeCommand.cxx: ENH: Improve formatting of include
- command error message.
-
-2008-03-08 09:21 king
-
- * Source/cmMakefile.cxx: COMP: Avoid using operator-> on
- const_reverse_iterator to help old compilers.
-
-2008-03-08 09:13 king
-
- * Source/: cmMakefile.cxx, cmPolicies.cxx: ENH: Cleanup policy
- generic documentation. Cleanup some policy error/warning
- messages.
-
-2008-03-08 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-07 19:58 hoffman
-
- * Modules/FindMPI.cmake: ENH: add new version of FindMPI, fix it to
- work with MPICH2 on windows
-
-2008-03-07 17:05 king
-
- * Source/cmAddCustomTargetCommand.cxx: COMP: Fix unused parameter
- warning in cmAddCustomTargetCommand.
-
-2008-03-07 16:36 king
-
- * Source/: cmMakefile.cxx, cmPolicies.cxx, cmPolicies.h, cmake.cxx:
- ENH: Finish creating, documenting, and enforcing policy CMP_0002.
-
-2008-03-07 16:32 hoffman
-
- * Source/CursesDialog/: cmCursesCacheEntryComposite.cxx,
- cmCursesMainForm.cxx: ENH: fix it for working with an empty cache
-
-2008-03-07 16:26 king
-
- * bootstrap: COMP: Fix bootstrap build after using
- cmDocumentationFormatterText in cmMakefile.
-
-2008-03-07 16:01 king
-
- * Source/: cmDocumentationFormatterText.cxx, cmMakefile.cxx: ENH:
- In cmMakefile::IssueMessage use cmDocumentationFormatterText to
- format the message nicely.
-
-2008-03-07 15:30 king
-
- * Source/cmAddCustomTargetCommand.cxx,
- Source/cmCMakeMinimumRequired.h, Source/cmCMakePolicyCommand.h,
- Source/cmConfigureFileCommand.cxx, Source/cmFindBase.cxx,
- Source/cmListFileCache.cxx, Source/cmLocalGenerator.cxx,
- Source/cmMakefile.cxx, Source/cmPolicies.cxx,
- Source/cmPolicies.h, Source/cmake.cxx,
- Tests/MakeClean/ToClean/CMakeLists.txt,
- Tests/Preprocess/CMakeLists.txt: ENH: Improve handling of
- old-style compatibility.
-
- - Remove CMP_0001 (no slash in target name) and restore
- old CMAKE_BACKWARDS_COMPATIBILITY check for it
- - Replace all checks of CMAKE_BACKWARDS_COMPATIBILITY
- with cmLocalGenerator::NeedBackwardsCompatibility calls
- - Create new CMP_0001 to determine whether or not
- CMAKE_BACKWARDS_COMPATIBILITY is used.
- (old = use, new = ignore)
- - Show CMAKE_BACKWARDS_COMPATIBILITY in cache only when
- CMP_0001 is set to OLD or WARN
- - Update documentation of cmake_policy and
- cmake_minimum_required
- to indicate their relationship and the 2.4 version boundary
- - When no cmake policy version is set in top level makefile
- implicitly call cmake_policy(VERSION 2.4) which restores
- CMAKE_BACKWARDS_COMPATIBILITY and other 2.4 compatibility
- - Fix tests MakeClean and Preprocess to call
- cmake_policy(VERSION 2.6) because they depend on new policies
-
-2008-03-07 14:03 hoffman
-
- * Utilities/Release/: create-cmake-release.cmake,
- dashmacmini2_release.cmake, magrathea_release.cmake,
- release_cmake.sh.in: ENH: qtgui stuff
-
-2008-03-07 11:50 clinton
-
- * Source/QtDialog/CMakeSetupDialog.cxx: ENH: Use fixed pitch font
- in output window.
-
-2008-03-07 11:43 martink
-
- * Source/: cmCMakeMinimumRequired.cxx, cmCacheManager.h,
- cmListFileCache.cxx, cmPolicies.cxx, cmake.cxx: ENH: clean up
- some policy stuff and interactions with
- CMAKE_BACKWARDS_COMPATIBILITY and CMAKE_MINIMUM_REQUIRED
-
-2008-03-07 11:06 hoffman
-
- * Source/CPack/: cmCPackCygwinBinaryGenerator.cxx,
- cmCPackGenerator.cxx: ENH: fix crash in cygwin package stuff
-
-2008-03-07 09:41 martink
-
- * Source/cmListFileCache.cxx: STYLE: fix line length issue
-
-2008-03-07 09:09 king
-
- * Source/cmMakefile.cxx: BUG: Do not produce whitespace-only lines
- when indenting messages in new error/warning format.
-
-2008-03-07 08:53 king
-
- * Source/cmCoreTryCompile.cxx: BUG: Generated try-compile
- CMakeLists.txt file should call cmake_policy with the current
- version of CMake, not just 2.6.
-
-2008-03-07 08:40 king
-
- * Source/: cmAddCustomTargetCommand.cxx, cmExecutionStatus.h,
- cmFunctionCommand.cxx, cmListFileCache.cxx, cmListFileCache.h,
- cmMacroCommand.cxx, cmMakefile.cxx, cmMakefile.h, cmPolicies.cxx:
- ENH: New format for warning and error messages
-
- - Add cmMakefile methods IssueError and IssueWarning
- - Maintain an explicit call stack in cmMakefile
- - Include context/call-stack info in messages
- - Nested errors now unwind the call stack
- - Use new mechanism for policy warnings and errors
- - Improve policy error message
- - Include cmExecutionStatus pointer in call stack
- so that errors deeper in the C++ stack under
- a command invocation will become errors for the
- command
-
-2008-03-07 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-06 16:03 martink
-
- * Source/cmListFileCache.cxx: BUG: keep CMAKE_BACKWARDS_COMP as
- internal
-
-2008-03-06 15:51 martink
-
- * Source/cmListFileCache.cxx: BUG: make default
- CMAKE_BACKWARDS_COMPATIBILITY 2.5
-
-2008-03-06 15:20 hoffman
-
- * Source/cmCoreTryCompile.cxx: ENH: make sure policy is set in
- generated cmakelist files
-
-2008-03-06 15:08 martink
-
- * Source/: cmConfigureFileCommand.cxx, cmListFileCache.cxx,
- cmPolicies.cxx: BUG: change in handling of cmake_minimum_required
-
-2008-03-06 11:34 hoffman
-
- * Source/cmDocumentationFormatterHTML.cxx: STYLE: fix line length
-
-2008-03-06 10:57 martink
-
- * Source/: cmCMakeMinimumRequired.cxx, cmConfigureFileCommand.cxx,
- cmListFileCache.cxx, cmListFileCache.h, cmMakefile.cxx,
- cmPolicies.cxx: BUG: change the handling of
- CMAKE_MINIMUM_REQUIRED and BACKWARDS_COMPATIBILITY and extend the
- documentaiton quite a bit
-
-2008-03-06 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-05 18:42 king
-
- * Source/cmPolicies.cxx: ENH: Fix policy warning message to not
- give wrong code as example.
-
-2008-03-05 18:21 king
-
- * Source/: cmCMakePolicyCommand.cxx, cmCMakePolicyCommand.h,
- cmMakefile.cxx, cmMakefile.h: ENH: Improve cmake_policy command
- signature
-
- - Replace NEW and OLD modes with a SET mode for clarity
- - Enforce VERSION argument validity (major.minor[.patch])
-
-2008-03-05 18:20 king
-
- * Source/cmPolicies.cxx: BUG: Require policy version to specify at
- least major.minor. Do not store CMAKE_BACKWARDS_COMPATIBILITY
- with an invalid version value.
-
-2008-03-05 17:26 king
-
- * Source/cmPolicies.cxx: BUG: Fix parsing of policy version number
- in cmPolicies.
-
-2008-03-05 15:55 king
-
- * Modules/CMakeFortranCompiler.cmake.in: ENH: Patch from Maik to
- add more fortran extensions.
-
-2008-03-05 12:53 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Allow users to recover from trying to use an improperly
- installed Qt without removing their cache, fixing their
- environment and trying again.
-
-2008-03-05 11:41 martink
-
- * Source/: cmConfigureFileCommand.cxx, cmMakefile.cxx,
- cmPolicies.cxx, cmPolicies.h: BUG: some fixes, still a few to go
-
-2008-03-05 11:05 hoffman
-
- * Source/: cmDocumentation.cxx, cmDocumentationFormatter.h,
- cmDocumentationFormatterHTML.cxx, cmDocumentationFormatterHTML.h:
- ENH: add master index into html full help
-
-2008-03-05 03:11 ewing
-
- * Modules/FindOpenAL.cmake: BUG: Fixed PATH_SUFFIXES copy/paste bug
- (0006201)
-
-2008-03-05 00:00 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-04 18:57 king
-
- * Source/cmMakefile.cxx: BUG: Make sure at least one policy stack
- entry is created for every cmMakefile instance.
-
-2008-03-04 18:42 king
-
- * Source/: cmCMakeMinimumRequired.cxx, cmCMakeMinimumRequired.h:
- ENH: Make CMAKE_MINIMUM_REQUIRED command FATAL_ERROR option
- implicit (always on). Accept but ignore the existing option.
-
-2008-03-04 18:41 king
-
- * Source/: cmGlobalGenerator.cxx, cmIncludeDirectoryCommand.cxx:
- BUG: Fix crash when CMAKE_BACKWARDS_COMPATIBILITY is not set.
-
-2008-03-04 14:51 martink
-
- * Source/: cmCMakeMinimumRequired.cxx, cmPolicies.cxx, cmake.cxx:
- ENH: more policy changes
-
-2008-03-04 13:51 king
-
- * Source/cmTarget.cxx: BUG: Fix memory leak when cmTarget instances
- are assigned. We really need to get rid of global targets and
- their associated assignments.
-
-2008-03-04 13:34 hoffman
-
- * Source/CTest/cmCTestSubmitHandler.cxx: STYLE: fix line len
-
-2008-03-04 09:40 king
-
- * Source/cmDocumentVariables.cxx: BUG: Fix typo in documentation of
- LIBRARY_OUTPUT_PATH.
-
-2008-03-04 09:16 martink
-
- * Source/: cmDocumentation.cxx, cmDocumentation.h,
- cmDocumentationFormatter.h, cmPolicies.cxx, cmPolicies.h,
- cmake.cxx, cmake.h, cmakemain.cxx: ENH: add --help-policies and
- --help-policy command line options
-
-2008-03-04 09:10 martink
-
- * CMakeLists.txt: BUG: undo accidental commit
-
-2008-03-04 08:18 david.cole
-
- * Tests/CMakeTests/CMakeLists.txt,
- Tests/CMakeTests/GetPrerequisitesTest.cmake.in,
- Modules/GetPrerequisites.cmake: ENH: Add script
- GetPrerequisites.cmake to help analyze what shared libraries
- executable files depend on. Primary uses are to determine what
- shared libraries should be copied into Mac OSX bundle
- applications to create standalone bundles apps and to determine
- what shared library files need to be installed for an executable
- to run on any platform. Requires native platform tools dumpbin,
- otool and ldd to generate results.
-
-2008-03-04 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-03 20:31 king
-
- * Modules/UsewxWidgets.cmake: STYLE: Remove trailing whitespace.
-
-2008-03-03 20:24 king
-
- * Modules/CMakeASMInformation.cmake: STYLE: Remove trailing
- whitespace.
-
-2008-03-03 15:56 king
-
- * Modules/Use_wxWindows.cmake: STYLE: Remove trailing whitespace.
-
-2008-03-03 11:57 king
-
- * Modules/VTKCompatibility.cmake: STYLE: Remove trailing
- whitespace.
-
-2008-03-03 11:28 hoffman
-
- * Source/cmAddCustomTargetCommand.cxx: ENH: fix ICE with gcc in
- dash8
-
-2008-03-03 11:18 king
-
- * Modules/CMakeForceCompiler.cmake: STYLE: Fixed docs of new
- CMakeForceCompiler
-
-2008-03-03 11:16 king
-
- * Modules/CMakeForceCompiler.cmake: ENH: Restore
- CMAKE_FORCE_C_COMPILER and CMAKE_FORCE_CXX_COMPILER macros in
- CMakeForceCompiler module.
-
-2008-03-03 08:48 king
-
- * Source/cmELF.cxx: COMP: Fix cmELF to build when ET_LOOS, ET_HIOS,
- ET_LOPROC, ET_HIPROC may not be defined.
-
-2008-03-03 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-02 16:48 king
-
- * Source/cmInstallTargetGenerator.cxx: ENH: During installation do
- not use builtin chrpath if the rpath will not change.
-
-2008-03-02 16:37 king
-
- * Source/cmTarget.cxx: ENH: Allow users to work around problems
- with the builtin chrpath by setting CMAKE_NO_BUILTIN_CHRPATH.
-
-2008-03-02 16:31 king
-
- * Source/cmELF.cxx: BUG: Fix bug introduced by workaround to
- warning.
-
-2008-03-02 16:19 king
-
- * Source/: cmELF.cxx, cmELF.h: BUG: A few more corrections for
- cmELF
-
- - Add os-specific and processor-specific file types
- - Add more error strings for invalid files.
- - Byte order of header fields does not always match encoding
-
-2008-03-02 16:19 king
-
- * Source/cmSystemTools.cxx: ENH: In cmSystemTools::ChangeRPath
- check for the RUNPATH if RPATH does not exist.
-
-2008-03-02 14:35 king
-
- * Source/: cmComputeLinkInformation.cxx, cmFileCommand.cxx,
- cmInstallTargetGenerator.cxx, cmLocalGenerator.cxx,
- cmSystemTools.cxx, cmSystemTools.h, cmTarget.cxx: ENH: Cleanup
- builtin chrpath support
-
- - Move computation of extended build-tree rpath
- to cmComputeLinkInformation
- - Only enable the extended build-tree rpath if
- the target will be installed
- - Generalize the interface of file(CHRPATH)
- - When changing the rpath on installation only
- replace the part generated by CMake because
- the native tools (ex SunCC on Linux) might have
- added their own part to the rpath
-
-2008-03-02 14:35 king
-
- * CMakeLists.txt: ENH: Simplify tests for building CMake itself
- with rpath support now that 2.4 is required to build.
-
-2008-03-02 09:12 martink
-
- * Source/cmPolicies.h: COMP: possible fix for VS6, but probably
- not, probably need tomake it internal
-
-2008-03-02 09:11 martink
-
- * Source/cmMakefile.cxx: COMP: fix warning
-
-2008-03-02 09:03 martink
-
- * Source/: cmPolicies.cxx, cmPolicies.h: ENH: revert dumb change
-
-2008-03-02 08:36 martink
-
- * Source/: cmAddCustomTargetCommand.cxx, cmPolicies.cxx,
- cmPolicies.h: COMP: fix compile errors on vs6 and a warning
-
-2008-03-02 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-03-01 16:21 martink
-
- * Source/cmMakefile.cxx: BUG: bad loop index unsigned compared to
- zero
-
-2008-03-01 15:44 martink
-
- * Source/: cmAddCustomTargetCommand.cxx, cmMakefile.cxx: COMP: fix
- some warnings
-
-2008-03-01 15:26 martink
-
- * Source/: cmPolicies.cxx, cmPolicies.h: STYLE: fix some line
- lengths
-
-2008-03-01 15:20 martink
-
- * CMakeLists.txt, bootstrap, Source/CMakeLists.txt,
- Source/cmAddCustomTargetCommand.cxx,
- Source/cmBootstrapCommands.cxx, Source/cmCommand.h,
- Source/cmIncludeDirectoryCommand.cxx, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmake.cxx, Source/cmake.h: ENH: add
- first cut and policies still need to add the doc support
-
-2008-03-01 15:16 king
-
- * Source/cmSystemTools.cxx: COMP: Fix unused parameter warning when
- cmSystemTools::ChangeRPath is built without ELF support.
-
-2008-03-01 13:17 king
-
- * Source/cmSystemTools.cxx: BUG: Fix cmSystemTools::ChangeRPath to
- not complain if there is no RPATH entry in the file but the
- requested new rpath is empty.
-
-2008-03-01 13:02 king
-
- * Source/cmTarget.cxx: BUG: Do not try to change the RPATH when
- installing a target if CMAKE_SKIP_RPATH is on or the path does
- not need to be changed.
-
-2008-03-01 12:51 king
-
- * Modules/CMakeFindBinUtils.cmake,
- Source/cmComputeLinkInformation.cxx,
- Source/cmComputeLinkInformation.h, Source/cmFileCommand.cxx,
- Source/cmFileCommand.h, Source/cmInstallTargetGenerator.cxx,
- Source/cmSystemTools.cxx, Source/cmSystemTools.h,
- Source/cmTarget.cxx, Source/cmTarget.h: ENH: Use builtin chrpath
- instead of relinking ELF targets
-
- - Add cmSystemTools::ChangeRPath method
- - Add undocumented file(CHRPATH) command
- - When installing use file(CHRPATH) to change the rpath
- instead of relinking
- - Remove CMAKE_CHRPATH lookup from CMakeFindBinUtils
- - Remove CMAKE_USE_CHRPATH option since this should
- always work
-
-2008-03-01 12:50 king
-
- * Source/: cmELF.cxx, cmELF.h: ENH: Add Size member to
- cmELF::StringEntry to return the amount of space in the string
- entry.
-
-2008-03-01 10:56 king
-
- * Tests/Preprocess/CMakeLists.txt: BUG: Fix typo XCode -> Xcode in
- Preprocess test.
-
-2008-03-01 09:08 king
-
- * Tests/Preprocess/CMakeLists.txt: ENH: Update Preprocess test to
- distinguish between the make tool or compiler tool that is at
- fault for not supporting a particular character in definitions.
- Make it skip the % character when the compiler is MSVC and it is
- a non-nmake tool.
-
-2008-03-01 09:08 king
-
- * Modules/Platform/Windows-cl.cmake, Source/cmLocalGenerator.cxx:
- BUG: Do not place $(CMAKE_COMMAND) in link scripts.
-
-2008-03-01 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-29 21:33 hoffman
-
- * Source/: cmIfCommand.cxx, cmWhileCommand.cxx: ENH: fix warnings
-
-2008-02-29 21:33 hoffman
-
- * Source/cmSetSourceFilesPropertiesCommand.h: ENH: fix docs
-
-2008-02-29 15:42 martink
-
- * Source/cmCMakePolicyCommand.cxx: ENH: just getting somethng
- checked in, still work to do
-
-2008-02-29 15:41 martink
-
- * Source/cmCmakePolicyCOmmand.cxx: ENH: case
-
-2008-02-29 15:28 martink
-
- * Source/: cmCMakePolicyCommand.h, cmCmakePolicyCOmmand.cxx,
- cmPolicies.cxx, cmPolicies.h: ENH: just getting somethng checked
- in, still work to do
-
-2008-02-29 14:58 hoffman
-
- * Modules/DartConfiguration.tcl.in,
- Source/CTest/cmCTestSubmitHandler.cxx,
- Source/CTest/cmCTestSubmitHandler.h: ENH: allow cdash not to
- trigger
-
-2008-02-29 14:36 hoffman
-
- * Modules/InstallRequiredSystemLibraries.cmake: ENH: add vs9 stuff,
- still need msvc9 mfc
-
-2008-02-29 12:18 hoffman
-
- * Source/: cmForEachCommand.cxx, cmFunctionCommand.cxx,
- cmIfCommand.cxx, cmMacroCommand.cxx, cmMakefile.cxx,
- cmWhileCommand.cxx: ENH: make CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS
- the default and remove the property. If any value is specified
- in an endif, endforeach, endwhile, etc then make sure it matches
- the start string. If no values are given then it is no longer an
- error.
-
-2008-02-29 11:12 king
-
- * Source/: cmELF.cxx, cmELF.h: ENH: Make cmELF parser more general
- and powerful
-
- - Add support to get RPATH and RUNPATH entries.
- - Add support to get file offsets to strings.
- - Add more DT_* tags to byte swapping.
-
-2008-02-29 09:15 king
-
- * Source/cmComputeLinkInformation.cxx: BUG:
- cmComputeLinkInformation::CheckImplicitDirItem needs to extract
- the filename portion of the link item to test against the library
- regex.
-
-2008-02-29 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-28 08:43 king
-
- * Source/cmELF.cxx: COMP: cmELF needs to include sys/link.h to get
- dynamic section structures on the Sun.
-
-2008-02-28 08:32 king
-
- * Source/cmELF.cxx: COMP: Fix warnings in cmELF.
-
-2008-02-28 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-27 17:10 king
-
- * Modules/Platform/Windows-ifort.cmake, Modules/Platform/cl.cmake,
- Source/cmDocumentVariables.cxx,
- Source/cmMakefileExecutableTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.h: ENH: Handle large object file
- lists on some platforms
-
- - Use a response file when enabled by
- CMAKE_<LANG>_USE_RESPONSE_FILE_FOR_OBJECTS
- - Enable for C and CXX with cl (MSVC)
- - Enable for Fortran with ifort (Intel Fortran)
-
-2008-02-27 16:26 king
-
- * Source/: CMakeLists.txt, cmConfigure.cmake.h.in, cmELF.cxx,
- cmELF.h, cmSystemTools.cxx: ENH: Add ELF file parsing
-
- - Enabled when system provides elf.h
- - Introduce cmELF class to parse ELF files
- - Use in cmSystemTools::GuessLibrarySOName to really get soname
-
-2008-02-27 16:11 king
-
- * Source/kwsys/CPU.h.in: BUG: Fixed typo in previous commit of
- kwsys/CPU.h.in
-
-2008-02-27 16:07 king
-
- * Source/kwsys/: CMakeLists.txt, CPU.h.in: ENH: Added CPU.h to
- KWSys to identify the target CPU and its byte order.
-
-2008-02-27 14:31 king
-
- * Modules/Platform/: HP-UX.cmake, IRIX64.cmake, Linux-PGI-C.cmake,
- Linux-PGI-CXX.cmake, SunOS.cmake, Windows-bcc32.cmake, gcc.cmake:
- BUG: Apply patch from bug#6445. Add preprocessor definitions to
- assembly and preprocessing build rules.
-
-2008-02-27 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-26 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-25 18:47 king
-
- * Modules/CMakeCCompilerId.c.in: ENH: Add support to C compiler
- identification for void return type from main. Cross-compilers
- for embedded platforms may require it.
-
-2008-02-25 15:07 clinton
-
- * Source/QtDialog/CMakeSetupDialog.cxx:
- ENH: Adjust when log is cleared. Its kept doing generate,
- and cleared when changing the source directory. #6358.
-
-2008-02-25 14:23 alex
-
- * Modules/CPackRPM.cmake: BUG: fix rpmbuild bug, which expands
- variables in comments :-/ apparently rpmbuild can't handle paths
- with spaces and can't handle variables in comments...
-
- Alex
-
-2008-02-25 10:17 david.cole
-
- * CTestCustom.cmake.in: BUG: Exclude try_compile sources and kwsys
- files from CMake coverage results.
-
-2008-02-25 09:23 king
-
- * Modules/: CMakeCCompilerId.c, CMakeCCompilerId.c.in,
- CMakeCXXCompilerId.cpp, CMakeCXXCompilerId.cpp.in,
- CMakeDetermineCCompiler.cmake, CMakeDetermineCXXCompiler.cmake,
- CMakeDetermineCompilerId.cmake,
- CMakeDetermineFortranCompiler.cmake, CMakeFortranCompilerId.F90,
- CMakeFortranCompilerId.F90.in, CMakePlatformId.h,
- CMakePlatformId.h.in: ENH: Improvied compiler identification
- robustness
-
- - Write a single source file into the compiler id directory
- - This avoid requiring the compiler to behave correctly with
- respect to include rules and the current working directory
- - Helps to identify cross-compiling toolchains with unusual
- default behavior
-
-2008-02-25 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-24 14:05 king
-
- * Modules/Platform/Windows-bcc32.cmake,
- Source/cmMakefileTargetGenerator.cxx: ENH: Simplify make build
- rule generation by removing use of OBJECTS_QUOTED and
- TARGET_QUOTED rule variables and updating the generation of
- OBJECTS to always use the newer cmLocalGenerator::Convert method.
-
-2008-02-24 14:05 king
-
- * Source/: cmComputeLinkDepends.cxx, cmExportFileGenerator.cxx,
- cmStandardIncludes.h, cmTarget.cxx: COMP: Fix Borland 5.5 build
-
- - Its <iosfwd> header includes windows.h which
- defines GetCurrentDirectory
- - It defines 'interface' so we cannot use it as
- a variable name.
-
-2008-02-24 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-23 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-22 09:44 king
-
- * Source/cmOrderDirectories.cxx: COMP: Fix unreachable code warning
- in cmOrderDirectories.
-
-2008-02-22 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-21 13:59 king
-
- * Source/cmOrderDirectories.cxx: COMP: Remove unused local variable
- from cmOrderDirectories.
-
-2008-02-21 13:58 king
-
- * Source/: cmComputeLinkInformation.cxx, cmOrderDirectories.cxx,
- cmSystemTools.cxx, cmSystemTools.h: ENH: Improve linking to
- third-party shared libraries on soname platforms
-
- - Reduce false positives in cases of unknown soname
- - Make library extension regular expressions match only at end
- of string
- - When linking to libraries in implicit dirs convert to the -l
- option
- only if the file name is one that can be found by the linker
- (ex. /usr/lib/libfoo.so.1 should be linked by full path)
- - Add cmSystemTools::GuessLibrarySOName to guess the soname of
- a
- library based on presence of a symlink
- - In cmComputeLinkInformation try to guess an soname before
- assuming
- that a third-party library is built without an soname
- - In cmOrderDirectories guess the soname of shared libraries in
- cases
- it is otherwise unknown
-
-2008-02-21 11:41 king
-
- * bootstrap, Modules/Platform/FreeBSD.cmake,
- Modules/Platform/HP-UX.cmake, Modules/Platform/Linux.cmake,
- Modules/Platform/QNX.cmake, Modules/Platform/SunOS.cmake,
- Source/CMakeLists.txt, Source/cmComputeLinkInformation.cxx,
- Source/cmComputeLinkInformation.h, Source/cmOrderDirectories.cxx,
- Source/cmOrderDirectories.h,
- Source/cmOrderRuntimeDirectories.cxx,
- Source/cmOrderRuntimeDirectories.h, Source/cmTarget.cxx,
- Source/cmTarget.h: ENH: Better linker search path computation.
-
- - Use linker search path -L.. -lfoo for lib w/out soname
- when platform sets CMAKE_PLATFORM_USES_PATH_WHEN_NO_SONAME
- - Rename cmOrderRuntimeDirectories to cmOrderDirectories
- and generalize it for both soname constraints and link
- library constraints
- - Use cmOrderDirectories to order -L directories based
- on all needed constraints
- - Avoid processing implicit link directories
- - For CMAKE_OLD_LINK_PATHS add constraints from libs
- producing them to produce old ordering
-
-2008-02-21 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-20 14:56 king
-
- * Source/: cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx, cmMakefileTargetGenerator.h: BUG:
- Link scripts should be generated with copy-if-different and
- included as a dependency of the link rule.
-
-2008-02-20 13:36 king
-
- * Source/: cmExportLibraryDependencies.cxx,
- cmExportLibraryDependencies.h: ENH: Deprecate
- export_library_dependencies
-
- - Reference export() and install(EXPORT)
- - Fix to support OUTPUT_NAME in simple cases
-
-2008-02-20 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-19 18:50 ibanez
-
- * Source/kwsys/testSystemInformation.cxx: ENH: Missing copyright
- header.
-
-2008-02-19 16:34 alex
-
- * Source/cmExtraEclipseCDT4Generator.cxx: STYLE: patch part 3 from
- Miguel: follow naming style for variables
-
- Alex
-
-2008-02-19 16:27 alex
-
- * Source/: cmExtraEclipseCDT4Generator.cxx,
- cmExtraEclipseCDT4Generator.h: ENH: patch from Miguel part 2: if
- ECLIPSE_CDT4_GENERATE_SOURCE_PROJECT is true, then the generator
- additionally generates eclipse project files in the source dir,
- since this is the only way to get cvs/svn working with eclipse
-
- This is off by default and the user has to enable it explicitely.
- If cmake can't write there it still continues.
-
- Alex
-
-2008-02-19 15:07 alex
-
- * Source/: cmExtraEclipseCDT4Generator.cxx,
- cmExtraEclipseCDT4Generator.h: ENH: patch part 1 from Miguel: use
- the cmake project name for the eclipse project name
-
- Alex
-
-2008-02-19 14:47 hoffman
-
- * Source/QtDialog/MacInstallDialog.ui: ENH: better ui
-
-2008-02-19 14:33 alex
-
- * Source/: CMakeLists.txt, cmDocumentation.cxx, cmDocumentation.h,
- cmDocumentationFormatter.h, cmDocumentationFormatterDocbook.cxx,
- cmDocumentationFormatterDocbook.h,
- cmDocumentationFormatterHTML.cxx, cmakemain.cxx: ENH: add support
- for creating the documentation in docbook format
- (http://www.oasis-open.org/docbook/xml/4.2/), which users can
- then convert to other formats. Tested with meinproc from KDE,
- which generates HTML pages which look good.
-
- Alex
-
-2008-02-19 14:26 hoffman
-
- * Source/: CPack/cmCPackPackageMakerGenerator.cxx,
- CPack/cmCPackPackageMakerGenerator.h, QtDialog/CMakeLists.txt,
- QtDialog/QtDialogCPack.cmake.in, QtDialog/postflight.sh.in,
- QtDialog/postupgrade.sh.in: ENH: install working with symlink qt
- tool
-
-2008-02-19 14:06 hoffman
-
- * Source/QtDialog/: CMakeLists.txt, CMakeSetup.cxx,
- MacInstallDialog.ui, QMacInstallDialog.cxx, QMacInstallDialog.h:
- ENH: add mac install symlink option to dialog
-
-2008-02-19 09:09 king
-
- * Source/cmTarget.cxx: COMP: Fix HP warning about
- cmTargetInternalPointer::operator= checking for self-assignment.
-
-2008-02-19 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-18 16:38 king
-
- * Source/: cmGlobalXCodeGenerator.cxx,
- cmLocalUnixMakefileGenerator3.cxx,
- cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileExecutableTargetGenerator.h,
- cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.h,
- cmMakefileTargetGenerator.cxx, cmMakefileTargetGenerator.h,
- cmMakefileUtilityTargetGenerator.cxx,
- cmMakefileUtilityTargetGenerator.h, cmSourceFile.cxx,
- cmTarget.cxx, cmTarget.h: ENH: Cleanup impl of PUBLIC_HEADER,
- PRIVATE_HEADER, and RESOURCE properties
-
-2008-02-18 15:50 hoffman
-
- * CMakeCPackOptions.cmake.in, CMakeLists.txt: ENH: install seems to
- be working for cmake-gui
-
-2008-02-18 15:42 hoffman
-
- * Source/cmFileCommand.cxx: ENH: add more information to message
-
-2008-02-18 14:51 hoffman
-
- * Source/QtDialog/CMakeIngestOSXBundleLibraries.cmake: ENH: make
- sure fixup has right paths
-
-2008-02-18 13:11 hoffman
-
- * Source/QtDialog/CMakeIngestOSXBundleLibraries.cmake: STYLE: use
- lowercase
-
-2008-02-18 13:03 hoffman
-
- * Source/: cmConfigure.cmake.h.in, cmake.cxx: ENH: remove
- CMAKE_PREFIX so changing it does not rebuild all
-
-2008-02-18 12:01 king
-
- * Modules/Platform/HP-UX.cmake: BUG: Fix passing of nodefaultrpath
- flag to linker through c++ compiler.
-
-2008-02-18 11:10 hoffman
-
- * CMakeLists.txt: ENH: require 2.4 to build cmake
-
-2008-02-18 10:26 hoffman
-
- * Modules/CMakeIngestOSXBundleLibraries.cmake,
- Source/CPack/cmCPackGenerator.cxx,
- Source/QtDialog/CMakeIngestOSXBundleLibraries.cmake,
- Source/QtDialog/CMakeLists.txt: ENH: have cpack work with DESTDIR
- install and ingest qt framework libs into cmake-gui
-
-2008-02-18 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-17 17:40 hoffman
-
- * Modules/CheckIncludeFiles.cmake: BUG: fix double cmakefiles
- directory
-
-2008-02-17 14:04 alex
-
- * Source/cmDocumentation.cxx: BUG: actually print the docs for
- custom modules if this was requested
-
- Alex
-
-2008-02-17 12:31 alex
-
- * Source/cmDocumentationFormatterHTML.cxx: PERF: reduce time for
- full docs as HTML from 1.4 s to 0.2 s, the map is now created and
- filled only once instead for every character I guess a simple
- case-switch would be still faster.
-
- Alex
-
-2008-02-17 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-16 16:33 hoffman
-
- * Modules/CMakeIngestOSXBundleLibraries.cmake: ENH: add script to
- ingest library depends into a bundle
-
-2008-02-16 13:05 hoffman
-
- * CMakeLists.txt, bootstrap, Source/cmBootstrapCommands.cxx,
- Source/cmCommands.cxx, Source/cmInstallProgramsCommand.cxx,
- Source/QtDialog/CMakeLists.txt, Source/QtDialog/QCMake.cxx,
- Source/QtDialog/QtDialogCPack.cmake.in: ENH: support for cpack
- and install of cmake-gui as mac app bundle
-
-2008-02-16 13:02 hoffman
-
- * Source/CPack/cmCPackGenerator.cxx: ENH: fix DESTDIR install
-
-2008-02-16 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-15 18:26 alex
-
- * Modules/FindPythonLibs.cmake: STYLE: use global property instead
- of helper target to collect all python modules from a source tree
-
- Alex
-
-2008-02-15 15:36 clinton
-
- * Source/QtDialog/QCMake.cxx: ENH: remove unused code.
-
-2008-02-15 12:12 hoffman
-
- * Source/QtDialog/QCMake.cxx: ENH: use package name on mac for edit
- cache
-
-2008-02-15 11:56 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Apply patch from
- bug #6180 to make CMAKE_ADDITIONAL_MAKE_CLEAN_FILES work for
- directories.
-
-2008-02-15 11:49 david.cole
-
- * Source/cmCallVisualStudioMacro.cxx,
- Source/cmGlobalVisualStudio71Generator.cxx,
- Source/cmGlobalVisualStudio71Generator.h,
- Source/cmGlobalVisualStudio8Generator.cxx,
- Source/cmGlobalVisualStudio8Generator.h,
- Source/cmGlobalVisualStudio9Generator.cxx,
- Source/cmGlobalVisualStudio9Generator.h,
- Source/cmGlobalVisualStudioGenerator.cxx,
- Source/cmGlobalVisualStudioGenerator.h,
- Templates/CMakeVSMacros2.vsmacros: ENH: Add code to support
- calling the VS reload macro from Visual Studio 7.1 and 9.0 in
- addition to 8.0 sp1... Make new macros file with VS 7.1 so that
- it can be read by 7.1 and later. VS 7.1 does not appear to run
- the macros while a build is in progress, but does not return any
- errors either, so for now, the reload macro is not called when
- using 7.1. If I can figure out how to get 7.1 to execute the
- macro, I will uncomment the code in
- cmGlobalVisualStudio71Generator::GetUserMacrosDirectory() to
- activate executing the macros in VS 7.1, too.
-
-2008-02-15 11:22 king
-
- * Modules/Platform/Darwin.cmake,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmMakefileExecutableTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.h,
- Source/cmSetPropertyCommand.cxx,
- Source/cmSetSourceFilesPropertiesCommand.cxx,
- Source/cmSourceFile.cxx: ENH: Cleanup building of OS X bundle
- content
-
- - Fixes repeated rebuild of bundles by Makefile generators
- - Add special rules to copy sources to their
- MACOSX_PACKAGE_LOCATION bundle directory
- - Remove MacOSX_Content language hack
- - Remove EXTRA_CONTENT property
- - Remove MACOSX_CONTENT
- - Remove corresponding special cases in object names
-
-2008-02-15 10:40 hoffman
-
- * Source/CPack/cmCPackNSISGenerator.cxx: BUG: fix for bug 6294,
- correct url for nsis
-
-2008-02-15 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-14 20:18 alex
-
- * Source/cmExtraEclipseCDT4Generator.cxx: ENH: enable color in the
- eclipse generator, there doesn't seem to be problems
-
- Alex
-
-2008-02-14 19:58 clinton
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, QCMakeCacheView.cxx,
- QCMakeCacheView.h:
- ENH: Convert native paths from QFileDialog and
- QDirModel/QCompleter. BUG: Block possible completion loop.
-
-2008-02-14 18:18 clinton
-
- * Source/QtDialog/: CMakeSetup.cxx, CMakeSetupDialog.cxx,
- CMakeSetupDialog.h, QCMake.cxx, QCMakeCacheView.cxx:
- ENH: Add shortcut to start search/filter. A bit of
- cleanup. Disable tab navigation in cache variable list.
- Enable home/end keys.
-
- BUG: Ensure currently edited values are saved before doing
- configure.
-
-2008-02-14 16:42 king
-
- * Source/: cmAddCustomTargetCommand.cxx, cmGlobalGenerator.cxx,
- cmGlobalGenerator.h, cmGlobalUnixMakefileGenerator3.h,
- cmMakefile.cxx, cmMakefile.h, cmake.cxx: ENH: Add global property
- ALLOW_DUPLICATE_CUSTOM_TARGETS to help existing projects that
- depend on having duplicate custom targets. It is allowed only
- for Makefile generators. See bug#6348.
-
-2008-02-14 15:31 king
-
- * Modules/MacOSXBundleInfo.plist.in,
- Modules/MacOSXFrameworkInfo.plist.in,
- Source/cmGlobalXCodeGenerator.cxx, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmMakefileExecutableTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.cxx, Source/cmTarget.cxx:
- ENH: Allow multiple OS X applications bundles to be created in a
- single build directory. Converted Info.plist files to be
- generated directly instead of configured with make variables.
- The MACOSX_BUNDLE_* variables are now properties (and vars for
- compatibility).
-
-2008-02-14 15:06 hoffman
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, CMakeSetupDialog.h: ENH:
- make sure html < > & stuff is escaped for the output window
-
-2008-02-14 13:36 king
-
- * Modules/CTestTargets.cmake, Source/cmDefinePropertyCommand.cxx,
- Source/cmDefinePropertyCommand.h,
- Tests/Complex/Library/CMakeLists.txt,
- Tests/ComplexOneConfig/Library/CMakeLists.txt,
- Tests/ComplexRelativePaths/Library/CMakeLists.txt,
- Tests/Properties/CMakeLists.txt: ENH: Updated DEFINE_PROPERTY
- command to be more extendible and more consistent with new
- SET_PROPERTY and GET_PROPERTY signatures.
-
-2008-02-14 11:58 king
-
- * Modules/CTestTargets.cmake, Source/cmBootstrapCommands.cxx,
- Source/cmCommands.cxx, Source/cmMakefile.cxx: ENH: Re-enable
- diagnosis of non-unique target names.
-
- - Re-enable enforcement in cmMakefile::EnforceUniqueName
- - Improve error message to help user resolve the problem
- - Fix Modules/CTestTargets.cmake to not duplicate testing
- targets
- - Move commands used by the changes to
- Modules/CTestTargets.cmake
- to build during bootstrap: DEFINE_PROPERTY, GET_PROPERTY
-
-2008-02-14 10:50 king
-
- * Modules/: CMakeForceCompiler.cmake, CMakeTestCCompiler.cmake,
- CMakeTestCXXCompiler.cmake: ENH: Remove unnecessary compiler
- force macros. The compiler ID can now be detected without
- linking an executable.
-
-2008-02-14 09:14 hoffman
-
- * Source/QtDialog/CMakeSetupDialog.cxx: ENH: add a check before
- delete cache
-
-2008-02-14 08:55 hoffman
-
- * Source/QtDialog/QCMake.cxx: ENH: do not show unititialized
- entries
-
-2008-02-14 01:11 clinton
-
- * Modules/FindQt4.cmake:
- BUG: Fix error when paths have + in them. (special regex
- characters)
-
-2008-02-14 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-13 17:00 barre
-
- * Modules/FindTCL.cmake: ENH: fix advanced bug
-
-2008-02-13 15:29 king
-
- * Source/: cmComputeLinkDepends.cxx, cmComputeLinkDepends.h: BUG:
- Update cmComputeLinkDepends to support leading/trailing
- whitespace stripping off link items for compatibility.
-
-2008-02-13 14:47 king
-
- * bootstrap, Source/cmBootstrapCommands.cxx, Source/cmCommands.cxx:
- ENH: Add option to bootstrap script to enable Qt dialog.
-
- - Add --qt-gui and --no-qt-gui options
- - Add --qt-qmake=<qmake> option to help locate Qt
- - Build more commands during bootstrap to help FindQt4.cmake:
- MATH, GET_DIRECTORY_PROPERTY, EXECUTE_PROCESS,
- SEPARATE_ARGUMENTS
- - Bootstrapping with the cmake-gui is now possible in MSys
-
-2008-02-13 14:35 king
-
- * Modules/FindQt4.cmake: BUG: Fix FindQt4.cmake
- QT4_CREATE_MOC_COMMAND macro to work with spaces in the path
- while using the @ syntax on MSYS builds.
-
-2008-02-13 13:58 clinton
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, QCMakeCacheView.cxx:
- ENH: Remove CurrentChanged from the table view's edit triggers.
- It results in editor issues when modifying the view.
- Remove workarounds for some of those issues.
-
-2008-02-13 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-12 17:22 hoffman
-
- * Source/QtDialog/CMakeLists.txt: ENH: do not expand regular vars
- here
-
-2008-02-12 10:19 king
-
- * Source/cmMakefile.cxx: BUG: Disable enforcement of unique target
- names until CTestTargets can be fixed.
-
-2008-02-12 09:49 hoffman
-
- * Source/: cmake.cxx, cmake.h, CursesDialog/cmCursesMainForm.cxx,
- QtDialog/CMakeSetup.cxx, QtDialog/QCMake.cxx: ENH: fix make
- edit_cache for cmake-gui
-
-2008-02-12 09:18 king
-
- * Source/cmExportLibraryDependencies.cxx: STYLE: Fix line-too-long
- in cmExportLibraryDependencies.
-
-2008-02-12 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-11 20:13 king
-
- * Source/cmDocumentVariables.cxx: ENH: Update documentation of
- EXECUTABLE_OUTPUT_PATH and LIBRARY_OUTPUT_PATH to reference their
- replacements.
-
-2008-02-11 17:33 king
-
- * Source/: cmAddCustomTargetCommand.cxx,
- cmAddExecutableCommand.cxx, cmAddLibraryCommand.cxx: COMP: Fix
- shadowed local variable warning.
-
-2008-02-11 17:01 king
-
- * Modules/Platform/eCos.cmake: ENH: Fix eCos.cmake to not require a
- forced compiler
-
- - Search for libtarget.a explicitly
- - Do not complain about compiler id during try-compile
-
-2008-02-11 17:00 king
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeDetermineCXXCompiler.cmake,
- CMakeDetermineFortranCompiler.cmake: ENH: When detecting the
- compiler id try compiling only to an object file.
-
-2008-02-11 17:00 king
-
- * Source/cmFindLibraryCommand.cxx: BUG: FIND_LIBRARY should not
- require CMAKE_SIZEOF_VOID_P to be set.
-
-2008-02-11 17:00 king
-
- * Source/cmake.cxx: ENH: Add global computed property
- IN_TRY_COMPILE.
-
-2008-02-11 15:31 king
-
- * Modules/Platform/HP-UX.cmake: ENH: Remove CMAKE_ANSI_CFLAGS
- variable and instead always add ansi flags to
- CMAKE_C_COMPILE_OBJECT. We should not require every project to
- reference CMAKE_ANSI_CFLAGS.
-
-2008-02-11 13:35 king
-
- * Source/: cmAddCustomTargetCommand.cxx,
- cmAddExecutableCommand.cxx, cmAddExecutableCommand.h,
- cmAddLibraryCommand.cxx, cmAddLibraryCommand.h, cmMakefile.cxx,
- cmMakefile.h, cmTarget.cxx: ENH: Enforce global target name
- uniqueness.
-
- - Error if imported target is involved in conflict
- - Error for non-imported target conflict unless
- CMAKE_BACKWARDS_COMPATIBILITY <= 2.4
- - Include OUTPUT_NAME property in error message
- - Update add_executable and add_library command documentation
-
-2008-02-11 13:35 king
-
- * Source/: cmMakefile.cxx, cmMakefile.h: ENH: Add
- cmMakefile::NeedBackwardsCompatibility method to pass through to
- cmLocalGenerator::NeedBackwardsCompatibility for convenience.
-
-2008-02-11 10:31 king
-
- * Source/cmExportLibraryDependencies.cxx: BUG: Fix
- export_library_dependencies command to produce a file that is
- compatible with CMake 2.4.
-
-2008-02-11 10:31 king
-
- * Source/cmComputeLinkDepends.cxx: BUG: Fix
- cmComputeLinkDepends::AddVarLinkEntries
-
- - Track link type correctly
- - Use _LINK_TYPE variables exported by CMake 2.4
-
-2008-02-11 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-10 17:19 alex
-
- * Source/cmIfCommand.h: STYLE: document that if(COMMAND) works also
- for macros and functions
-
- Alex
-
-2008-02-10 11:37 king
-
- * Source/cmFindLibraryCommand.cxx: BUG: Fix recent find_library
- change to look for user-specified name first to do so only if the
- name matches a valid library extension.
-
-2008-02-10 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-09 10:05 hoffman
-
- * Utilities/Release/vogon_release.cmake: ENH: build the qt gui
-
-2008-02-09 09:53 hoffman
-
- * CMakeCPack.cmake, CMakeCPackOptions.cmake.in,
- Source/QtDialog/CMakeLists.txt,
- Source/QtDialog/QtDialogCPack.cmake.in: ENH: make it so cmake-gui
- only installs if qt is static on windows
-
-2008-02-09 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-08 13:47 clinton
-
- * Source/QtDialog/CMakeSetupDialog.cxx: BUG: Make sure editor
- closes when deleting cache entries.
-
-2008-02-08 12:01 clinton
-
- * Modules/FindQt4.cmake: ENH: Better way to have escaping done
- correctly for all generators.
-
-2008-02-08 11:26 clinton
-
- * Source/QtDialog/QCMake.cxx: ENH: Need to pick up the
- PreLoad.cmake files.
-
-2008-02-08 10:42 clinton
-
- * Source/QtDialog/: CMakeSetup.cxx, QCMakeCacheView.cxx: COMP: Fix
- build with Qt 4.2. BUG: Fix new editors stealing focus while
- typing search text. ENH: Look for translation in data dir, not
- bin dir.
-
-2008-02-08 09:24 king
-
- * Tests/Dependency/CMakeLists.txt: BUG: Need ANSI C.
-
-2008-02-08 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-07 23:26 clinton
-
- * Modules/FindQt4.cmake:
- BUG: Fix arg for moc parameter file so it works with unix
- makefiles, when the build dir has a space in it.
-
-2008-02-07 18:24 alex
-
- * Source/cmExtraEclipseCDT4Generator.cxx: patch from Miguel BUG:
- fix #5496: eclipse can't load projects where the build dir is a
- subdir of the src dir
-
- Alex
-
-2008-02-07 17:58 clinton
-
- * Source/QtDialog/: QCMakeCacheView.cxx, QCMakeCacheView.h:
- ENH: Show cache variable name in title of file dialogs.
-
-2008-02-07 16:49 king
-
- * Source/: cmGlobalXCodeGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx, cmTarget.cxx: ENH: Avoid
- computing link information for static library targets. They do
- not link.
-
-2008-02-07 16:26 alex
-
- * Source/cmExtraEclipseCDT4Generator.cxx: two patches from Miguel:
- BUG: fix #5819: put compile definitions into the eclipse project
- files so eclipse handles ifdef blcoks correctly STYLE: make the
- code for filtering some global targets out nicer
-
- Alex
-
-2008-02-07 16:24 king
-
- * Source/cmComputeLinkDepends.cxx: COMP: Add missing assert
- include.
-
-2008-02-07 16:22 alex
-
- * Source/cmInstallCommand.cxx: STYLE: add some comments
-
- Alex
-
-2008-02-07 16:14 king
-
- * Tests/Dependency/Case2/: CMakeLists.txt, foo1.c, foo1b.c,
- foo2b.c, foo3.c, foo3b.c: ENH: Make Dependency test Case2 require
- two traversals of a static library loop.
-
-2008-02-07 16:14 king
-
- * bootstrap, Source/CMakeLists.txt,
- Source/cmComputeComponentGraph.cxx,
- Source/cmComputeComponentGraph.h,
- Source/cmComputeLinkDepends.cxx, Source/cmComputeLinkDepends.h,
- Source/cmComputeTargetDepends.cxx,
- Source/cmComputeTargetDepends.h, Source/cmGraphAdjacencyList.h:
- ENH: Improve link line generation for static library cycles.
-
- - Move Tarjan algorithm from cmComputeTargetDepends
- into its own class cmComputeComponentGraph
- - Use cmComputeComponentGraph to identify the component DAG
- of link dependencies in cmComputeLinkDepends
- - Emit non-trivial component members more than once but always
- in a contiguous group on the link line
-
-2008-02-07 13:26 hoffman
-
- * Source/: cmFileCommand.cxx, cmFileCommand.h: ENH: make sure files
- are binary for download and make status a pair of value string
-
-2008-02-07 13:19 hoffman
-
- * Modules/FindPkgConfig.cmake: BUG: fix for bug 6117 pkgconfig
-
-2008-02-07 11:43 hoffman
-
- * CMakeCPackOptions.cmake.in, Source/QtDialog/CMakeLists.txt: ENH:
- for windows only allow a static qt for install and NSIS of
- cmake-gui
-
-2008-02-07 08:55 hoffman
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt: ENH: complex must
- link to curl now
-
-2008-02-07 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-06 20:14 king
-
- * Source/cmComputeLinkInformation.cxx: BUG: Fix
- cmComputeLinkInformation to include the target's user link
- directories in the runtime path computation. This bug was
- introduced when cmOrderRuntimeDirectories was introduced.
-
-2008-02-06 17:02 alex
-
- * Modules/FindPackageHandleStandardArgs.cmake: STYLE: use a
- function instead of a macro, to keep FAIL_MESSAGE local patch
- from Miguel
-
- Alex
-
-2008-02-06 15:26 king
-
- * Source/cmFindLibraryCommand.cxx: ENH: Make find_library test for
- the library file as named before trying prefixes and suffixes.
- This will allow users to explicitly search for static libraries
- on unix. See bug #1643.
-
-2008-02-06 15:23 king
-
- * Source/cmTargetLinkLibrariesCommand.h: STYLE: Improve
- documentation of target_link_libraries command to make
- target-level dependency explicit. See bug #6043.
-
-2008-02-06 15:10 clinton
-
- * Source/QtDialog/CMakeSetup.cxx: ENH: Update some strings to
- match program name.
-
-2008-02-06 14:52 king
-
- * Tests/: CMakeLists.txt, Dependency/CMakeLists.txt,
- Dependency/Case1/CMakeLists.txt, Dependency/Case1/a.c,
- Dependency/Case1/b.c, Dependency/Case1/b2.c,
- Dependency/Case1/c.c, Dependency/Case1/c2.c,
- Dependency/Case1/d.c, Dependency/Case1/main.c,
- Dependency/Case2/CMakeLists.txt, Dependency/Case2/bar1.c,
- Dependency/Case2/bar2.c, Dependency/Case2/bar3.c,
- Dependency/Case2/foo1.c, Dependency/Case2/foo2.c,
- Dependency/Case2/foo3.c, Dependency/Case2/zot.c: ENH: Combine all
- dependency* tests into one Dependency test. Add more difficult
- test cases.
-
-2008-02-06 14:45 clinton
-
- * Source/QtDialog/CMakeSetup.cxx: BUG: On Mac OS X, give the CMake
- library the correct path to the cmake exectuables. Fixes
- #6286.
-
-2008-02-06 14:20 king
-
- * Source/cmExportBuildFileGenerator.cxx,
- Source/cmExportCommand.cxx,
- Source/cmExportInstallFileGenerator.cxx,
- Source/cmInstallCommand.cxx, Source/cmInstallTargetGenerator.cxx,
- Source/cmInstallTargetGenerator.h,
- Tests/ExportImport/Export/CMakeLists.txt: ENH: Improve
- exporting/importing of targets
-
- - Use real name instead of link for location of versioned
- targets
- - Error when a target is exported multiple times
-
-2008-02-06 14:19 king
-
- * Source/cmTarget.cxx: BUG: Make sure linking to a shared lib on
- windows uses import library and not the new realname.
-
-2008-02-06 14:06 king
-
- * Source/cmTarget.cxx: BUG: Do not create versioned executable
- names on Xcode where they are not supported.
-
-2008-02-06 13:34 king
-
- * Source/: cmComputeLinkInformation.cxx,
- cmComputeLinkInformation.h, cmTarget.cxx, cmTarget.h: ENH: When
- linking to versioned targets whose real file name is known pass
- the real name to the linker instead of the symlink name.
-
-2008-02-06 09:46 hoffman
-
- * Source/cmFileCommand.cxx: ENH: remove debug print stuff
-
-2008-02-06 09:35 hoffman
-
- * Source/: CMakeLists.txt, cmFileCommand.cxx, cmFileCommand.h: ENH:
- add DOWNLOAD option to FILE command
-
-2008-02-06 09:17 hoffman
-
- * Source/QtDialog/CMakeLists.txt: ENH: change name of qt-dialog
-
-2008-02-06 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-05 23:10 king
-
- * bootstrap, Source/CMakeLists.txt,
- Source/cmComputeTargetDepends.cxx,
- Source/cmComputeTargetDepends.h, Source/cmGlobalGenerator.cxx,
- Source/cmGlobalGenerator.h, Source/cmake.cxx: ENH: Analyze
- inter-target dependencies to safely fix cycles
-
- - Cycles may be formed among static libraries
- - Native build system should not have cycles in target deps
- - Create cmComputeTargetDepends to analyze dependencies
- - Identify conneced components and use them to fix deps
- - Diagnose cycles containing non-STATIC targets
- - Add debug mode property GLOBAL_DEPENDS_DEBUG_MODE
- - Use results in cmGlobalGenerator as target direct depends
-
-2008-02-05 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-04 19:00 king
-
- * Source/cmInstallTargetGenerator.cxx: COMP: Add missing include
- for assert.
-
-2008-02-04 17:03 king
-
- * Source/: cmInstallCommand.cxx, cmInstallCommand.h,
- cmInstallCommandArguments.cxx, cmInstallCommandArguments.h,
- cmInstallTargetGenerator.cxx, cmInstallTargetGenerator.h: ENH:
- Allow separate installation of shared libs and their links.
-
- - Add NAMELINK_ONLY and NAMELINK_SKIP to INSTALL command
- - Options select a \"namelink\" mode
- - cmInstallTargetGenerator selects files/link based on mode
- - See bug #4419
-
-2008-02-04 16:05 hoffman
-
- * Source/cmGlobalVisualStudio7Generator.cxx: ENH: make sure
- ALL_BUILD only shows up once
-
-2008-02-04 15:22 king
-
- * Modules/Platform/AIX.cmake, Source/cmComputeLinkInformation.cxx,
- Source/cmComputeLinkInformation.h, Source/cmake.cxx: BUG: Added
- TARGET_ARCHIVES_MAY_BE_SHARED_LIBS global property to help
- compute proper rpath information on AIX when shared libraries
- have names like "libfoo.a".
-
-2008-02-04 10:04 king
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeDetermineCXXCompiler.cmake,
- CMakeDetermineFortranCompiler.cmake, CMakeTestCCompiler.cmake,
- CMakeTestCXXCompiler.cmake: BUG: When configuring compiler
- information files into the CMakeFiles directory in the project
- build tree, use IMMEDIATE option for CONFIGURE_FILE explicitly.
- It is needed in case the user sets CMAKE_BACKWARDS_COMPATIBILITY
- to 2.0 or lower.
-
-2008-02-04 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-03 17:24 king
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeDetermineCXXCompiler.cmake,
- CMakeDetermineFortranCompiler.cmake, CMakeForceCompiler.cmake,
- CMakeTestCCompiler.cmake, CMakeTestCXXCompiler.cmake: BUG: When
- forcing the C and CXX compilers do not try to detect the ABI
- information. Cleanup configured language compiler info files by
- always using @ONLY. This addresses bug#6297.
-
-2008-02-03 08:58 king
-
- * Source/kwsys/IOStream.cxx: COMP: Avoid warning in kwsys
- IOStream.cxx when the helper functions are not needed. Define
- one public symbol to avoid complaints from archivers about empty
- object files.
-
-2008-02-03 08:57 king
-
- * Tests/ExportImport/Export/: testExe1.c, testExe1lib.c,
- testLib1.c, testLib2.c: COMP: Convert C function prototypes to
- use (void) instead of ().
-
-2008-02-03 08:57 king
-
- * Source/: cmCTest.cxx, cmCTest.h: BUG: cmCTest::GetConfigType
- should return the string by reference-to-const so that callers
- may use .c_str() safely.
-
-2008-02-03 08:20 king
-
- * Source/kwsys/SystemInformation.cxx: COMP: Fix warning in
- SystemInformation.cxx about possibly incorrect assignment in if
- condition.
-
-2008-02-03 08:14 king
-
- * Source/kwsys/SystemInformation.cxx: COMP: Fix unreachable code
- warning. Remove runtime test of constant information.
-
-2008-02-03 08:07 king
-
- * Source/kwsys/hash_set.hxx.in: COMP: Remove inline keyword from
- forward declaration for VS9.
-
-2008-02-03 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-02 16:18 hoffman
-
- * Source/kwsys/SystemInformation.cxx: ENH: fix infinite loop from
- size_t change
-
-2008-02-02 08:58 king
-
- * Modules/Platform/: NetBSD.cmake, kFreeBSD.cmake: ENH: Enable
- dependent library search paths on more platforms
-
- - NetBSD needs dependent library paths in -rpath-link option.
- - kFreeBSD needs dependent library paths in -rpath-link option.
-
-2008-02-02 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-02-01 16:17 martink
-
- * Tests/CMakeLists.txt: ENH: disable test for vs 70 as devenv
- randomly segfaults when building the sub-project
-
-2008-02-01 16:05 martink
-
- * Source/cmGlobalGenerator.cxx: ENH: really Bill, using Ken's
- checkout, fix output in ctest so clean output in build and test
- is not lost, also display the command lines used
-
-2008-02-01 14:35 king
-
- * Source/cmExportInstallFileGenerator.cxx: BUG: Fixed typo
- resulting in confusing error message from
- cmExportInstallFileGenerator.
-
-2008-02-01 13:52 clinton
-
- * Modules/FindQt4.cmake:
- BUG: When preserving relative paths for moc generated files,
- also consider paths to headers in the build directory.
-
-2008-02-01 13:18 david.cole
-
- * Source/kwsys/CMakeLists.txt: ENH: Merge changes from main tree
- into VTK-5-0 branch. (cvs -q up -j1.135 -j1.136
- Utilities/kwsys/CMakeLists.txt)
-
-2008-02-01 13:08 king
-
- * Source/cmInstallTargetGenerator.cxx, Source/cmTarget.h,
- Tests/ExportImport/Export/CMakeLists.txt: BUG: Remove
- InstallNameFixupPath from cmTarget and cmInstallTargetGenerator.
-
- - Motivation:
- - It depended on the order of installation
- - It supported only a single destination for each target
- - It created directory portions of an install name without
- user request
- - Updated ExportImport test to install targets in an order that
- expoed
- this bug
-
-2008-02-01 12:35 hoffman
-
- * Source/kwsys/SystemInformation.cxx: ENH: fix warnings
-
-2008-02-01 12:02 clinton
-
- * Modules/UseQt4.cmake: ENH: Use new COMPILE_DEFINITIONS_* with
- set_property to add Qt release/debug defines.
-
-2008-02-01 11:48 clinton
-
- * Source/QtDialog/: CMakeSetup.cxx, CMakeSetupDialog.cxx: ENH:
- Show version number in window title.
-
-2008-02-01 11:40 hoffman
-
- * Source/kwsys/SystemInformation.cxx: ENH: fix more warnings
-
-2008-02-01 11:33 hoffman
-
- * Source/kwsys/: SystemInformation.cxx: ENH: fix more warnings
-
-2008-02-01 11:30 hoffman
-
- * Source/kwsys/SystemInformation.cxx: ENH: fix some warnings and 64
- bit build windows
-
-2008-02-01 11:09 hoffman
-
- * Source/kwsys/SystemInformation.cxx: ENH: fix win64 build and a
- warning
-
-2008-02-01 10:41 clinton
-
- * Source/QtDialog/: CMakeSetup.cxx, CMakeSetupDialog.cxx,
- CMakeSetupDialog.h, QCMake.cxx: ENH: Use translation file if it
- exists for the locale. Consolidate some strings.
-
- More responsive interrupting. Prompt user if they try to
- close during
- configure, and allow them to close.
-
-2008-02-01 09:57 king
-
- * Tests/ExportImport/: CMakeLists.txt, Export/CMakeLists.txt: ENH:
- Update ExportImport test to enforce dependent library paths
-
- - Build without rpaths
- - Place implementation libs in separate directories
-
-2008-02-01 09:57 king
-
- * Modules/Platform/: FreeBSD.cmake, HP-UX.cmake, IRIX.cmake,
- IRIX64.cmake, SunOS.cmake: ENH: Enable dependent library search
- paths on more platforms
-
- - HP-UX needs dependent library paths as -L options.
- - IRIX needs dependent library paths as -L options.
- - Sun needs dependent library paths as -L options.
- - FreeBSD needs dependent library paths in -rpath-link option.
-
-2008-02-01 09:36 king
-
- * Tests/CMakeLists.txt: BUG: Fix commit 1.41 of
- Tests/CMakeLists.txt to place fake target before --version flag
- instead of after.
-
-2008-02-01 08:56 king
-
- * bootstrap, Modules/CMakeCInformation.cmake,
- Modules/CMakeCXXInformation.cmake,
- Modules/CMakeFortranInformation.cmake,
- Modules/Platform/Darwin.cmake, Modules/Platform/Linux.cmake,
- Modules/Platform/QNX.cmake, Source/CMakeLists.txt,
- Source/cmComputeLinkDepends.cxx,
- Source/cmComputeLinkInformation.cxx,
- Source/cmComputeLinkInformation.h,
- Source/cmDocumentVariables.cxx,
- Source/cmExportBuildFileGenerator.cxx,
- Source/cmExportBuildFileGenerator.h,
- Source/cmExportFileGenerator.cxx, Source/cmExportFileGenerator.h,
- Source/cmExportInstallFileGenerator.cxx,
- Source/cmExportInstallFileGenerator.h,
- Source/cmLocalGenerator.cxx,
- Source/cmOrderRuntimeDirectories.cxx,
- Source/cmOrderRuntimeDirectories.h, Source/cmTarget.cxx: ENH:
- Pass dependent library search path to linker on some platforms.
-
- - Move runtime path ordering out of cmComputeLinkInformation
- into its own class cmOrderRuntimeDirectories.
- - Create an instance of cmOrderRuntimeDirectories for runtime
- path ordering and another instance for dependent library
- path ordering.
- - Replace CMAKE_DEPENDENT_SHARED_LIBRARY_MODE with explicit
- CMAKE_LINK_DEPENDENT_LIBRARY_FILES boolean.
- - Create CMAKE_LINK_DEPENDENT_LIBRARY_DIRS boolean.
- - Create variables to specify -rpath-link flags:
- CMAKE_SHARED_LIBRARY_RPATH_LINK_<LANG>_FLAG
- CMAKE_EXECUTABLE_RPATH_LINK_<LANG>_FLAG
- - Enable -rpath-link flag on Linux and QNX.
- - Documentation and error message updates
-
-2008-02-01 08:55 king
-
- * Source/cmTarget.cxx: COMP: Fix shadowed local warning.
-
-2008-02-01 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-31 21:33 hoffman
-
- * Source/kwsys/SystemInformation.cxx: ENH: try to fix hp and vs 6,
- again...
-
-2008-01-31 16:38 hoffman
-
- * Source/: CTest/cmCTestUpdateHandler.cxx,
- cmGlobalVisualStudio7Generator.h: STYLE: line length
-
-2008-01-31 16:37 hoffman
-
- * Source/kwsys/SystemInformation.cxx: ENH: fixes for borland
-
-2008-01-31 16:33 martink
-
- * Source/CTest/cmCTestTestHandler.cxx: BUG: minor fix for ctest
-
-2008-01-31 16:10 hoffman
-
- * Source/cmCTest.cxx: ENH: remove extra junk
-
-2008-01-31 15:45 king
-
- * Modules/Platform/Darwin.cmake, Source/cmComputeLinkDepends.cxx,
- Source/cmComputeLinkDepends.h,
- Source/cmComputeLinkInformation.cxx,
- Source/cmComputeLinkInformation.h,
- Source/cmDocumentVariables.cxx, Source/cmExportFileGenerator.cxx,
- Source/cmExportFileGenerator.h, Source/cmTarget.cxx,
- Source/cmTarget.h, Tests/ExportImport/Export/CMakeLists.txt: ENH:
- Support linking to shared libs with dependent libs
-
- - Split IMPORTED_LINK_LIBRARIES into two parts:
- IMPORTED_LINK_INTERFACE_LIBRARIES
- IMPORTED_LINK_DEPENDENT_LIBRARIES
- - Add CMAKE_DEPENDENT_SHARED_LIBRARY_MODE to select behavior
- - Set mode to LINK for Darwin (fixes universal binary problem)
- - Update ExportImport test to account for changes
-
-2008-01-31 15:34 hoffman
-
- * Source/kwsys/SystemInformation.cxx: ENH: fix for qnx, I hope, and
- fix indent stuff
-
-2008-01-31 15:10 hoffman
-
- * Source/kwsys/SystemInformation.cxx: ENH: fix build errors with
- asm stuff on mingw and hopefully win64
-
-2008-01-31 14:50 hoffman
-
- * Source/kwsys/SystemInformation.cxx: ENH: fix build for mingw
-
-2008-01-31 14:34 hoffman
-
- * Source/kwsys/: SystemInformation.cxx, SystemInformation.hxx.in:
- ENH: split into implementation and interface class to clean up
- namespace issues with #define stuff
-
-2008-01-31 13:23 martink
-
- * Modules/Dart.cmake: ENH: use ctest to drive dashboards for make
- targets as opposed to tclsh
-
-2008-01-31 12:56 king
-
- * Source/kwsys/CMakeLists.txt: BUG: Need to install cstddef header.
-
-2008-01-31 12:19 hoffman
-
- * Source/cmGlobalGenerator.cxx: ENH: remove a const cast
-
-2008-01-31 11:43 martink
-
- * Source/: ctest.cxx, CTest/cmCTestTestHandler.cxx: ENH: read in
- old file formats Dart as well
-
-2008-01-31 08:32 king
-
- * Source/kwsys/kwsysPlatformTestsCXX.cxx: STYLE: Work-around std::
- check since this is a platform test.
-
-2008-01-31 08:21 king
-
- * Source/kwsys/: String.hxx.in, SystemTools.hxx.in,
- kwsys_ios_sstream.h.in: STYLE: Remove references to std:: inside
- KWSys, even in comments. This will allow a commit check to be
- added.
-
-2008-01-31 08:21 king
-
- * Source/kwsys/SystemInformation.cxx: COMP: Replace kwsys_stl::
- with kwsys_ios:: for streams access.
-
-2008-01-31 08:05 king
-
- * Source/: cmComputeLinkInformation.cxx, cmTarget.cxx: ENH: Add
- target property LINK_SEARCH_END_STATIC to help people building
- static binaries on some platforms.
-
-2008-01-31 07:50 king
-
- * Modules/Platform/IRIX.cmake, Modules/Platform/IRIX64.cmake,
- Source/cmComputeLinkInformation.cxx,
- Source/cmComputeLinkInformation.h,
- Source/cmFindLibraryCommand.cxx, Source/cmFindLibraryCommand.h:
- BUG: Move decision to switch library paths found in implicit link
- directories to use -l options from cmFindLibraryCommand to
- cmComputeLinkInformation. Existing projects may depend on
- find_library returning a full path. This slightly weakens
- cmComputeLinkInformation but is necessary for compatibility.
-
-2008-01-31 06:51 king
-
- * Source/: cmExportFileGenerator.cxx, cmExportFileGenerator.h:
- COMP: Remove unused parameter.
-
-2008-01-31 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-30 22:56 hoffman
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h: ENH: remove const
-
-2008-01-30 21:40 hoffman
-
- * Source/kwsys/: SystemInformation.cxx, SystemInformation.hxx.in:
- COMP: use kwsys_stl and not std::
-
-2008-01-30 17:57 king
-
- * Source/cmExportFileGenerator.cxx: BUG: Fixed previous commit in
- cmExportFileGenerator to separate libraries correctly in the
- import link list.
-
-2008-01-30 17:26 king
-
- * Tests/ExportImport/: CMakeLists.txt, Export/CMakeLists.txt,
- Export/testExe2lib.c, Export/testExe2libImp.c, Export/testLib3.c,
- Export/testLib3Imp.c, Import/imp_mod1.c: ENH: Updated
- ExportImport test to try LINK_INTERFACE_LIBRARIES.
-
-2008-01-30 17:25 king
-
- * Source/: cmComputeLinkDepends.cxx,
- cmExportBuildFileGenerator.cxx, cmExportBuildFileGenerator.h,
- cmExportCommand.cxx, cmExportCommand.h,
- cmExportFileGenerator.cxx, cmExportFileGenerator.h,
- cmExportInstallFileGenerator.cxx, cmTarget.cxx, cmTarget.h: ENH:
- Implemented link-interface specification feature.
-
- - Shared libs and executables with exports may now have
- explicit transitive link dependencies specified
- - Created LINK_INTERFACE_LIBRARIES and related properties
- - Exported targets get the interface libraries as their
- IMPORTED_LINK_LIBRARIES property.
- - The export() and install(EXPORT) commands now give
- an error when a linked target is not included since
- the user can change the interface libraries instead
- of adding the target.
-
-2008-01-30 16:22 hoffman
-
- * Source/cmGlobalVisualStudio7Generator.cxx: ENH: make sure global
- targets are in the right projects
-
-2008-01-30 13:02 hoffman
-
- * Tests/SubProject/foo/: CMakeLists.txt, foo.cxx: ENH: add missing
- files
-
-2008-01-30 12:55 hoffman
-
- * Source/kwsys/SystemInformation.hxx.in: ENH: fix for vs 70
-
-2008-01-30 12:15 king
-
- * Source/cmComputeLinkDepends.cxx: BUG: cmComputeLinkDepends should
- not follow the dependencies of executables.
-
-2008-01-30 12:04 hoffman
-
- * Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmGlobalVisualStudio71Generator.cxx,
- Source/cmGlobalVisualStudio71Generator.h,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.h,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h, Tests/CMakeLists.txt,
- Tests/SubProject/CMakeLists.txt, Tests/SubProject/bar.cxx,
- Tests/SubProject/car.cxx: ENH: fix for bug 3218 dependant
- projects are written out automatically if they are in the
- project. Also fix bug 5829, remove hard coded
- CMAKE_CONFIGURATION_TYPES from vs 7 generator
-
-2008-01-30 11:54 hoffman
-
- * Source/CTest/: cmCTestTestHandler.cxx, cmCTestUpdateHandler.cxx:
- ENH: remove warnings
-
-2008-01-30 11:22 king
-
- * Source/: cmAddCustomCommandCommand.cxx,
- cmAddCustomCommandCommand.h: ENH: Make add_custom_command
- interpret relative OUTPUT locations with respect to the build tre
- instead of the source tree. This can greatly simplify user code
- since generating a file will not need to reference
- CMAKE_CURRENT_BINARY_DIR. The new behavior is what users expect
- 99% of the time.
-
-2008-01-30 11:21 king
-
- * Source/: cmGetPropertyCommand.cxx,
- cmGetSourceFilePropertyCommand.cxx, cmSourceFile.cxx,
- cmSourceFile.h: BUG: Add cmSourceFile::GetPropertyForUser to
- centralize the LOCATION property hack. This fixes the LOCATION
- property when retrieved via the get_property command.
-
-2008-01-30 11:17 hoffman
-
- * Source/: cmCTest.cxx, CTest/cmCTestBuildHandler.cxx,
- CTest/cmCTestBuildHandler.h, CTest/cmCTestConfigureHandler.cxx,
- CTest/cmCTestCoverageHandler.cxx,
- CTest/cmCTestMemCheckHandler.cxx, CTest/cmCTestTestHandler.cxx,
- CTest/cmCTestTestHandler.h, CTest/cmCTestUpdateHandler.cxx,
- kwsys/CMakeLists.txt, kwsys/SystemInformation.hxx.in: ENH:
- enhancements for cdash, include system information and better
- time entries
-
-2008-01-30 08:37 king
-
- * Source/cmMakefile.cxx: BUG: Fix misuse of stl vector that caused
- definitions to be dropped by cmMakefile::PushScope.
-
-2008-01-30 07:44 king
-
- * CompileFlags.cmake, Source/kwsys/hash_map.hxx.in: COMP: Fix
- warnings on VS9.
-
-2008-01-30 07:17 king
-
- * Utilities/cmtar/CMakeLists.txt: COMP: Fix warning about tolower
- by making sure ctype.h is included in cmtar.
-
-2008-01-30 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-29 21:16 king
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h,
- cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx: ENH: Enable use of link
- script whenever incremental archive construction rules are
- available. Enable use of archive construction rules on MSYS.
-
-2008-01-29 20:46 king
-
- * Modules/Platform/Windows-gcc.cmake,
- Source/cmDocumentVariables.cxx,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.h: ENH: Added build rule
- variables CMAKE_<LANG>_ARCHIVE_CREATE,
- CMAKE_<LANG>_ARCHIVE_APPEND, and CMAKE_<LANG>_ARCHIVE_FINISH to
- support creation of static archive libraries out of a large
- number of objects. See bug #6284.
-
-2008-01-29 17:30 king
-
- * Source/: cmCacheManager.cxx, cmCacheManager.h: BUG: Fix
- uninitialzed members of cmCacheManager.
-
-2008-01-29 17:30 king
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio6Generator.h,
- cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h, cmTarget.cxx, cmTarget.h: BUG:
- cmTarget instances should not be copied. Removed pass-by-value
- arguments from cmLocalVisualStudio7Generator::WriteGroup and
- cmLocalVisualStudio6Generator::WriteGroup. Updated cmTarget to
- make this easier to find.
-
-2008-01-29 17:01 clinton
-
- * Modules/FindQt4.cmake: ENH: Make lupdate and lrelease
- executables advanced variables.
-
-2008-01-29 15:54 clinton
-
- * Source/QtDialog/CMakeSetupDialog.cxx: ENH: Correctly format
- multi-line error messages.
-
-2008-01-29 15:47 king
-
- * Source/: cmComputeLinkInformation.cxx,
- cmComputeLinkInformation.h, cmInstallTargetGenerator.cxx: ENH:
- Update cmInstallTargetGenerator to get the shared libraries
- linked by a target from cmComputeLinkInformation instead of
- duplicating the computation.
-
-2008-01-29 15:10 barre
-
- * Modules/FindHTMLHelp.cmake: ENH: need quotes
-
-2008-01-29 15:07 king
-
- * Source/: cmComputeLinkInformation.cxx,
- cmComputeLinkInformation.h, cmGlobalXCodeGenerator.cxx,
- cmInstallTargetGenerator.cxx, cmInstallTargetGenerator.h,
- cmLocalGenerator.cxx, cmLocalGenerator.h,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx, cmTarget.cxx, cmTarget.h: ENH:
- Add cmTarget::GetLinkInformation method to allow several places
- in the generators to share link information while only computing
- it once per configuration for a target. Use it to simplify the
- chrpath feature.
-
-2008-01-29 13:07 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Allow QT4_WRAP_CPP to work with dir1/myobject.h
- dir2/myobject.h Fixes #5067.
-
-2008-01-29 09:57 king
-
- * Source/cmFindPackageCommand.cxx: ENH: Added not to find_package
- documentation about unspecified choice among multiple versions.
-
-2008-01-29 08:03 king
-
- * Tests/ExportImport/CMakeLists.txt: BUG: Custom command driver
- outputs must be SYMBOLIC since no corresponding file is created.
-
-2008-01-29 07:57 king
-
- * Tests/ExportImport/CMakeLists.txt: BUG: Make sure
- CMAKE_INSTALL_PREFIX stays in subproject caches.
-
-2008-01-29 07:48 king
-
- * Modules/Platform/Linux-SunPro-C.cmake: BUG: Fix dynamic exports
- executable link option for Sun C compiler on Linux.
-
-2008-01-29 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-28 20:38 king
-
- * Modules/readme.txt, Source/cmFindPackageCommand.cxx,
- Source/cmFindPackageCommand.h,
- Tests/FindPackageTest/CMakeLists.txt,
- Tests/FindPackageTest/lib/suffix/test/SuffixTestConfigVersion.cmake,
- Tests/FindPackageTest/lib/zot-1.0/zot-config.cmake,
- Tests/FindPackageTest/lib/zot-2.0/zot-config-version.cmake,
- Tests/FindPackageTest/lib/zot-2.0/zot-config.cmake,
- Tests/FindPackageTest/lib/zot-3.0/zot-config-version.cmake,
- Tests/FindPackageTest/lib/zot-3.0/zot-config.cmake,
- Tests/FindPackageTest/lib/zot-3.1/zot-config-version.cmake,
- Tests/FindPackageTest/lib/zot-3.1/zot-config.cmake: ENH: Added
- version support to Config mode of find_package command.
-
- - Added EXACT option to request an exact version.
- - Enforce version using check provided by package.
- - Updated FindPackageTest to test versioning in config mode.
-
-2008-01-28 19:20 clinton
-
- * Modules/FindQt4.cmake:
- ENH: Improve find for glib/gthread when Qt is configured to use
- it. Fixes #6220.
-
-2008-01-28 15:22 king
-
- * Source/: cmExportBuildFileGenerator.cxx,
- cmExportInstallFileGenerator.cxx: STYLE: Updated TODO comment for
- PUBLIC_HEADER_LOCATION export.
-
-2008-01-28 15:12 king
-
- * Source/: cmInstallCommand.h, cmTarget.cxx: ENH: Document
- PRIVATE_HEADER, PUBLIC_HEADER, and RESOURCE target properties and
- corresponding arguments to INSTALL(TARGETS).
-
-2008-01-28 14:46 king
-
- * Tests/Framework/CMakeLists.txt: BUG: Fix Framework test after
- fixing FRAMEWORK targets to not install like frameworks on
- non-Apple systems.
-
-2008-01-28 14:46 king
-
- * Source/cmExportBuildFileGenerator.cxx,
- Source/cmExportFileGenerator.cxx,
- Source/cmExportInstallFileGenerator.cxx,
- Source/cmInstallCommand.cxx, Source/cmInstallCommand.h,
- Source/cmInstallTargetGenerator.cxx, Source/cmTarget.cxx,
- Source/cmTarget.h, Tests/ExportImport/Export/CMakeLists.txt,
- Tests/ExportImport/Export/testExe3.c,
- Tests/ExportImport/Import/CMakeLists.txt,
- Tests/ExportImport/Import/imp_testExe1.c: ENH: Support
- exporting/importing of AppBundle targets.
-
- - Imported bundles have the MACOSX_BUNDLE property set
- - Added cmTarget::IsAppBundleOnApple method to simplify checks
- - Document BUNDLE keyword in INSTALL command
- - Updated IMPORTED_LOCATION property documentation for bundles
- - Updated ExportImport test to test bundles
-
-2008-01-28 13:37 king
-
- * Source/cmExportFileGenerator.cxx, Source/cmExportFileGenerator.h,
- Tests/ExportImport/Export/CMakeLists.txt,
- Tests/ExportImport/Export/testExe1.c,
- Tests/ExportImport/Export/testExe1lib.c: BUG: Fix export/import
- file generation to not store link dependencies of executables or
- modules.
-
-2008-01-28 13:21 king
-
- * Source/cmExportBuildFileGenerator.h, Source/cmExportCommand.cxx,
- Source/cmExportCommand.h, Source/cmExportFileGenerator.cxx,
- Source/cmExportFileGenerator.h,
- Tests/ExportImport/Export/CMakeLists.txt: ENH: Restored APPEND
- option to EXPORT() command in new implementation.
-
-2008-01-28 13:06 king
-
- * Tests/ExportImport/: Export/CMakeLists.txt, Export/testLib4.c,
- Import/CMakeLists.txt, Import/imp_testExe1.c: ENH: Added
- framework to ExportImport test.
-
-2008-01-28 13:05 king
-
- * Source/: cmComputeLinkInformation.cxx, cmExportFileGenerator.cxx,
- cmExportInstallFileGenerator.cxx, cmGlobalGenerator.cxx,
- cmGlobalXCodeGenerator.cxx, cmInstallCommand.cxx,
- cmInstallCommand.h, cmInstallTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx, cmTarget.cxx, cmTarget.h:
- ENH: Support exporting/importing of Framework targets.
-
- - Imported frameworks have the FRAMEWORK property set
- - Added cmTarget::IsFrameworkOnApple method to simplify checks
- - Also remove separate IMPORTED_ENABLE_EXPORTS property and
- just use ENABLE_EXPORTS since, like FRAMEWORK, it just represents
- the target type.
- - Document FRAMEWORK keyword in INSTALL command.
- - Updated IMPORTED_LOCATION property documentation for
- Frameworks
-
-2008-01-28 09:53 king
-
- * Source/cmExportFileGenerator.h: COMP: Add virtual destructor to
- cmExportFileGenerator to avoid warnings about other virtual
- functions.
-
-2008-01-28 08:40 king
-
- * Tests/: CMakeLists.txt, ExportImport/CMakeLists.txt,
- ExportImport/main.c, ExportImport/Export/CMakeLists.txt,
- ExportImport/Export/testExe1.c, ExportImport/Export/testExe2.c,
- ExportImport/Export/testLib1.c, ExportImport/Export/testLib2.c,
- ExportImport/Export/testLib3.c,
- ExportImport/Import/CMakeLists.txt,
- ExportImport/Import/imp_mod1.c,
- ExportImport/Import/imp_testExe1.c: ENH: Added ExportImport test
- to test new export/import features.
-
-2008-01-28 08:39 king
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: BUG: Updated SimpleInstall tests
- for new export/import interface.
-
-2008-01-28 08:38 king
-
- * Source/: CMakeLists.txt, cmAddDependenciesCommand.cxx,
- cmAddExecutableCommand.cxx, cmAddExecutableCommand.h,
- cmAddLibraryCommand.cxx, cmAddLibraryCommand.h,
- cmComputeLinkDepends.cxx, cmComputeLinkDepends.h,
- cmComputeLinkInformation.cxx, cmExportBuildFileGenerator.cxx,
- cmExportBuildFileGenerator.h, cmExportCommand.cxx,
- cmExportCommand.h, cmExportFileGenerator.cxx,
- cmExportFileGenerator.h, cmExportInstallFileGenerator.cxx,
- cmExportInstallFileGenerator.h, cmGetPropertyCommand.cxx,
- cmGetTargetPropertyCommand.cxx, cmGlobalGenerator.cxx,
- cmGlobalGenerator.h, cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio8Generator.cxx,
- cmGlobalVisualStudioGenerator.cxx, cmGlobalXCodeGenerator.cxx,
- cmIncludeExternalMSProjectCommand.cxx, cmInstallCommand.cxx,
- cmInstallCommand.h, cmInstallCommandArguments.cxx,
- cmInstallCommandArguments.h, cmInstallDirectoryGenerator.cxx,
- cmInstallExportGenerator.cxx, cmInstallExportGenerator.h,
- cmInstallFilesCommand.cxx, cmInstallFilesGenerator.cxx,
- cmInstallGenerator.cxx, cmInstallGenerator.h,
- cmInstallProgramsCommand.cxx, cmInstallTargetGenerator.cxx,
- cmInstallTargetGenerator.h, cmLocalGenerator.cxx,
- cmLocalVisualStudio6Generator.cxx, cmMakefile.cxx, cmMakefile.h,
- cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx, cmSetPropertyCommand.cxx,
- cmSetTargetPropertiesCommand.cxx, cmTarget.cxx, cmTarget.h: ENH:
- Updated exporting and importing of targets to support libraries
- and configurations.
-
- - Created cmExportFileGenerator hierarchy to implement export
- file generation
- - Installed exports use per-config import files loaded by a
- central one.
- - Include soname of shared libraries in import information
- - Renamed PREFIX to NAMESPACE in INSTALL(EXPORT) and EXPORT()
- commands
- - Move addition of CMAKE_INSTALL_PREFIX to destinations to
- install generators
- - Import files compute the installation prefix relative to
- their location when loaded
- - Add mapping of importer configurations to importee
- configurations
- - Rename IMPORT targets to IMPORTED targets to distinguish from
- windows import libraries
- - Scope IMPORTED targets within directories to isolate them
- - Place all properties created by import files in the IMPORTED
- namespace
- - Document INSTALL(EXPORT) and EXPORT() commands.
- - Document IMPORTED signature of add_executable and add_library
- - Enable finding of imported targets in cmComputeLinkDepends
-
-2008-01-28 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-27 15:09 king
-
- * bootstrap, Source/cmComputeLinkDepends.cxx: COMP: Use kwsys to
- get STL set_intersection algorithm.
-
-2008-01-27 13:42 king
-
- * bootstrap, Source/CMakeLists.txt,
- Source/cmComputeLinkDepends.cxx, Source/cmComputeLinkDepends.h,
- Source/cmComputeLinkInformation.cxx,
- Source/cmComputeLinkInformation.h, Source/cmTarget.cxx: ENH:
- Created cmComputeLinkDepends to compute link dependencies.
-
- - This will be useful for imported library dependencies
- - Replaces old cmTarget analyze-lib-depends stuff for linking
- - Formalizes graph construction and dump
- - Explicitly represents dependency inferral sets
- - Use BFS of initial dependencies to preserve order
-
-2008-01-27 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-26 01:11 barre
-
- * Modules/: FindTCL.cmake, FindTclStub.cmake, FindTclsh.cmake,
- FindWish.cmake: ENH: Update Tcl/Tk 8.5
-
-2008-01-26 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-25 13:07 barre
-
- * Modules/: FindPerl.cmake, FindTCL.cmake, FindTclStub.cmake,
- FindTclsh.cmake, FindWish.cmake: ENH: update for Tcl/Tk 8.5
-
-2008-01-25 08:11 king
-
- * Source/cmSystemTools.cxx: COMP: Need to return a value from fake
- MD5 method under bootstrap.
-
-2008-01-25 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-24 19:42 barre
-
- * Modules/FindTclsh.cmake: ENH: typo
-
-2008-01-24 19:31 barre
-
- * Modules/: FindTCL.cmake, FindTclsh.cmake, FindWish.cmake: ENH:
- update for Tcl/Tk 8.5
-
-2008-01-24 16:11 king
-
- * Source/cmSystemTools.cxx: COMP: Cannot do MD5 from KWSys during
- CMake bootstrap.
-
-2008-01-24 14:41 king
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Add
- cmSystemTools::ComputeStringMD5 method.
-
-2008-01-24 14:37 king
-
- * Source/cmake.cxx: BUG: Make cmake -E remove_directory work when
- directory is not present.
-
-2008-01-24 07:37 king
-
- * Source/cmFindLibraryCommand.cxx: ENH: Apply new implicit link
- directory find_library policy when loading a cache from an
- earlier CMake.
-
-2008-01-24 07:37 king
-
- * Source/: cmCacheManager.cxx, cmCacheManager.h, cmMakefile.cxx,
- cmMakefile.h: ENH: Added cmMakefile::NeedCacheCompatibility
- method and support for it in cmCacheManager. This will allow
- commands to modify their behavior when running with a cache
- loaded from an earlier CMake version.
-
-2008-01-24 07:31 king
-
- * Source/CPack/cmCPackDebGenerator.cxx: COMP: Add include of
- <limits.h> to get USHRT_MAX constant.
-
-2008-01-24 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-23 18:34 alex
-
- * Source/cmReturnCommand.h: STYLE: fix typo
-
- Alex
-
-2008-01-23 17:53 king
-
- * Modules/CMakeCompilerABI.h, Source/cmFindLibraryCommand.cxx: ENH:
- Remove sparcv9 architecture subdir added earlier. The new
- implicit link directory policy takes care of the problem.
-
-2008-01-23 17:43 king
-
- * bootstrap: BUG: Do not have variable and function of the same
- name. Old shells do not likeit.
-
-2008-01-23 16:53 king
-
- * Source/CursesDialog/CMakeLists.txt: ENH: Simplify code by
- removing unnecessary LINK_DIRECTORIES call.
-
-2008-01-23 16:35 king
-
- * Modules/CMakeCXXInformation.cmake: BUG:
- CMAKE_EXECUTABLE_RUNTIME_CXX_FLAG should get its default value
- from CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG, not
- CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG.
-
-2008-01-23 16:27 barre
-
- * Modules/: FindTCL.cmake, FindTclStub.cmake, FindTclsh.cmake,
- FindWish.cmake: ENH: update for Tcl/Tk 8.5
-
-2008-01-23 16:21 king
-
- * Source/: cmFindLibraryCommand.cxx, cmFindLibraryCommand.h: ENH:
- Teach find_library to avoid returning library paths in system
- directories that may be converted to architecture-specific
- directories by the compiler when it invokes the linker.
-
-2008-01-23 15:56 king
-
- * Source/: cmComputeLinkInformation.cxx,
- cmComputeLinkInformation.h: BUG: Fix cmComputeLinkInformation
- cycle detection.
-
-2008-01-23 15:22 king
-
- * Modules/VTKCompatibility.cmake,
- Source/cmComputeLinkInformation.cxx,
- Source/cmComputeLinkInformation.h,
- Source/cmDocumentVariables.cxx: ENH: Added CMAKE_LINK_OLD_PATHS
- compatibility mode for linker search paths.
-
-2008-01-23 14:07 barre
-
- * Modules/: FindTCL.cmake, FindTclStub.cmake: ENH: keep cleaning up
- Tcl/Tk modules
-
-2008-01-23 13:37 king
-
- * Source/cmComputeLinkInformation.cxx: COMP: Fix build on Borland
- 5.5.
-
-2008-01-23 13:30 king
-
- * Modules/Platform/Windows-wcl386.cmake,
- Source/cmComputeLinkInformation.cxx,
- Source/cmComputeLinkInformation.h,
- Source/cmDocumentVariables.cxx, Source/cmLocalGenerator.cxx: BUG:
- Fix generation of Watcom link lines.
-
- - Work-around bug in Watcom command line parsing for spaces in
- paths.
- - Add 'library' option before libraries specified by file path.
-
-2008-01-23 13:03 king
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h: BUG:
- Work-around bug in MSVC 6 command line parsing.
-
-2008-01-23 12:51 martink
-
- * Source/cmCTest.cxx: ENH: look for CTestConfiguration.ini first
-
-2008-01-23 10:29 martink
-
- * Tests/: CMakeLists.txt, ReturnTest/CMakeLists.txt,
- ReturnTest/returnTest.c, ReturnTest/subdir/CMakeLists.txt: ENH:
- add testing for return and break commands
-
-2008-01-23 10:27 martink
-
- * Source/: cmAddCustomCommandCommand.cxx,
- cmAddCustomCommandCommand.h, cmAddCustomTargetCommand.cxx,
- cmAddCustomTargetCommand.h, cmAddDefinitionsCommand.cxx,
- cmAddDefinitionsCommand.h, cmAddDependenciesCommand.cxx,
- cmAddDependenciesCommand.h, cmAddExecutableCommand.cxx,
- cmAddExecutableCommand.h, cmAddLibraryCommand.cxx,
- cmAddLibraryCommand.h, cmAddSubDirectoryCommand.cxx,
- cmAddSubDirectoryCommand.h, cmAddTestCommand.cxx,
- cmAddTestCommand.h, cmAuxSourceDirectoryCommand.cxx,
- cmAuxSourceDirectoryCommand.h, cmBootstrapCommands.cxx,
- cmBuildCommand.cxx, cmBuildCommand.h, cmBuildNameCommand.cxx,
- cmBuildNameCommand.h, cmCMakeMinimumRequired.cxx,
- cmCMakeMinimumRequired.h, cmCPluginAPI.cxx, cmCommand.h,
- cmConfigureFileCommand.cxx, cmConfigureFileCommand.h,
- cmCreateTestSourceList.cxx, cmCreateTestSourceList.h,
- cmDefinePropertyCommand.cxx, cmDefinePropertyCommand.h,
- cmElseCommand.cxx, cmElseCommand.h, cmElseIfCommand.cxx,
- cmElseIfCommand.h, cmEnableLanguageCommand.cxx,
- cmEnableLanguageCommand.h, cmEnableTestingCommand.cxx,
- cmEnableTestingCommand.h, cmEndForEachCommand.cxx,
- cmEndForEachCommand.h, cmEndFunctionCommand.cxx,
- cmEndFunctionCommand.h, cmEndIfCommand.cxx, cmEndIfCommand.h,
- cmEndMacroCommand.cxx, cmEndMacroCommand.h,
- cmEndWhileCommand.cxx, cmEndWhileCommand.h,
- cmExecProgramCommand.cxx, cmExecProgramCommand.h,
- cmExecuteProcessCommand.cxx, cmExecuteProcessCommand.h,
- cmExportCommand.cxx, cmExportCommand.h,
- cmExportLibraryDependencies.cxx, cmExportLibraryDependencies.h,
- cmFLTKWrapUICommand.cxx, cmFLTKWrapUICommand.h,
- cmFileCommand.cxx, cmFileCommand.h, cmFindLibraryCommand.cxx,
- cmFindLibraryCommand.h, cmFindPackageCommand.cxx,
- cmFindPackageCommand.h, cmFindPathCommand.cxx,
- cmFindPathCommand.h, cmFindProgramCommand.cxx,
- cmFindProgramCommand.h, cmForEachCommand.cxx, cmForEachCommand.h,
- cmFunctionBlocker.h, cmFunctionCommand.cxx, cmFunctionCommand.h,
- cmGetCMakePropertyCommand.cxx, cmGetCMakePropertyCommand.h,
- cmGetDirectoryPropertyCommand.cxx,
- cmGetDirectoryPropertyCommand.h,
- cmGetFilenameComponentCommand.cxx,
- cmGetFilenameComponentCommand.h, cmGetPropertyCommand.cxx,
- cmGetPropertyCommand.h, cmGetSourceFilePropertyCommand.cxx,
- cmGetSourceFilePropertyCommand.h, cmGetTargetPropertyCommand.cxx,
- cmGetTargetPropertyCommand.h, cmGetTestPropertyCommand.cxx,
- cmGetTestPropertyCommand.h, cmIfCommand.cxx, cmIfCommand.h,
- cmIncludeCommand.cxx, cmIncludeCommand.h,
- cmIncludeDirectoryCommand.cxx, cmIncludeDirectoryCommand.h,
- cmIncludeExternalMSProjectCommand.cxx,
- cmIncludeExternalMSProjectCommand.h,
- cmIncludeRegularExpressionCommand.cxx,
- cmIncludeRegularExpressionCommand.h, cmInstallCommand.cxx,
- cmInstallCommand.h, cmInstallFilesCommand.cxx,
- cmInstallFilesCommand.h, cmInstallProgramsCommand.cxx,
- cmInstallProgramsCommand.h, cmInstallTargetsCommand.cxx,
- cmInstallTargetsCommand.h, cmLinkDirectoriesCommand.cxx,
- cmLinkDirectoriesCommand.h, cmLinkLibrariesCommand.cxx,
- cmLinkLibrariesCommand.h, cmListCommand.cxx, cmListCommand.h,
- cmLoadCacheCommand.cxx, cmLoadCacheCommand.h,
- cmLoadCommandCommand.cxx, cmLoadCommandCommand.h,
- cmMacroCommand.cxx, cmMacroCommand.h, cmMakeDirectoryCommand.cxx,
- cmMakeDirectoryCommand.h, cmMakefile.cxx, cmMakefile.h,
- cmMarkAsAdvancedCommand.cxx, cmMarkAsAdvancedCommand.h,
- cmMathCommand.cxx, cmMathCommand.h, cmMessageCommand.cxx,
- cmMessageCommand.h, cmOptionCommand.cxx, cmOptionCommand.h,
- cmOutputRequiredFilesCommand.cxx, cmOutputRequiredFilesCommand.h,
- cmProjectCommand.cxx, cmProjectCommand.h, cmQTWrapCPPCommand.cxx,
- cmQTWrapCPPCommand.h, cmQTWrapUICommand.cxx, cmQTWrapUICommand.h,
- cmRemoveCommand.cxx, cmRemoveCommand.h,
- cmRemoveDefinitionsCommand.cxx, cmRemoveDefinitionsCommand.h,
- cmSeparateArgumentsCommand.cxx, cmSeparateArgumentsCommand.h,
- cmSetCommand.cxx, cmSetCommand.h,
- cmSetDirectoryPropertiesCommand.cxx,
- cmSetDirectoryPropertiesCommand.h, cmSetPropertyCommand.cxx,
- cmSetPropertyCommand.h, cmSetSourceFilesPropertiesCommand.cxx,
- cmSetSourceFilesPropertiesCommand.h,
- cmSetTargetPropertiesCommand.cxx, cmSetTargetPropertiesCommand.h,
- cmSetTestsPropertiesCommand.cxx, cmSetTestsPropertiesCommand.h,
- cmSiteNameCommand.cxx, cmSiteNameCommand.h,
- cmSourceGroupCommand.cxx, cmSourceGroupCommand.h,
- cmStringCommand.cxx, cmStringCommand.h, cmSubdirCommand.cxx,
- cmSubdirCommand.h, cmSubdirDependsCommand.cxx,
- cmSubdirDependsCommand.h, cmTargetLinkLibrariesCommand.cxx,
- cmTargetLinkLibrariesCommand.h, cmTryCompileCommand.cxx,
- cmTryCompileCommand.h, cmTryRunCommand.cxx, cmTryRunCommand.h,
- cmUseMangledMesaCommand.cxx, cmUseMangledMesaCommand.h,
- cmUtilitySourceCommand.cxx, cmUtilitySourceCommand.h,
- cmVariableRequiresCommand.cxx, cmVariableRequiresCommand.h,
- cmVariableWatchCommand.cxx, cmVariableWatchCommand.h,
- cmWhileCommand.cxx, cmWhileCommand.h, cmWriteFileCommand.cxx,
- cmWriteFileCommand.h,
- CTest/cmCTestEmptyBinaryDirectoryCommand.cxx,
- CTest/cmCTestEmptyBinaryDirectoryCommand.h,
- CTest/cmCTestHandlerCommand.cxx, CTest/cmCTestHandlerCommand.h,
- CTest/cmCTestReadCustomFilesCommand.cxx,
- CTest/cmCTestReadCustomFilesCommand.h,
- CTest/cmCTestRunScriptCommand.cxx,
- CTest/cmCTestRunScriptCommand.h, CTest/cmCTestScriptHandler.cxx,
- CTest/cmCTestSleepCommand.cxx, CTest/cmCTestSleepCommand.h,
- CTest/cmCTestStartCommand.cxx, CTest/cmCTestStartCommand.h,
- CTest/cmCTestTestHandler.cxx, cmBreakCommand.cxx,
- cmBreakCommand.h, cmExecutionStatus.h, cmReturnCommand.cxx,
- cmReturnCommand.h: ENH: add return and break support to cmake,
- also change basic command invocation signature to be able to
- return extra informaiton via the cmExecutionStatus class
-
-2008-01-23 10:21 king
-
- * Source/cmComputeLinkInformation.cxx: BUG: Be less aggressive
- about finding conflicts in the runtime path when the real soname
- is not known.
-
-2008-01-23 09:53 king
-
- * Modules/CMakeCompilerABI.h, Source/cmFindLibraryCommand.cxx,
- Source/cmFindLibraryCommand.h: ENH: Enable library search path
- suffix for sparcv9 architecture. This should be generalized to a
- platform file later.
-
-2008-01-23 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-22 10:11 clinton
-
- * Modules/FindQt4.cmake: ENH: Add macros to handle translations.
- Fixes #6229.
-
-2008-01-22 10:05 king
-
- * Source/: cmComputeLinkInformation.cxx,
- cmComputeLinkInformation.h: BUG: When a library file name is
- linked without a path make sure the link type is restored after
- the -l option.
-
-2008-01-22 09:15 king
-
- * Tests/: CMakeLists.txt, RuntimePath/CMakeLists.txt,
- RuntimePath/bar1.c, RuntimePath/bar2.c, RuntimePath/foo1.c,
- RuntimePath/foo2.c, RuntimePath/main.c: ENH: Added RuntimePath
- test to make sure rpath gets correct order.
-
-2008-01-22 09:13 king
-
- * bootstrap, Modules/CMakeCInformation.cmake,
- Modules/CMakeCXXInformation.cmake,
- Modules/CMakeFortranInformation.cmake,
- Modules/Platform/AIX.cmake, Modules/Platform/HP-UX.cmake,
- Source/CMakeLists.txt, Source/cmComputeLinkInformation.cxx,
- Source/cmComputeLinkInformation.h,
- Source/cmDocumentVariables.cxx, Source/cmGlobalGenerator.cxx,
- Source/cmGlobalGenerator.h, Source/cmGlobalXCodeGenerator.cxx,
- Source/cmLocalGenerator.cxx, Source/cmLocalGenerator.h,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h,
- Source/cmOrderLinkDirectories.cxx,
- Source/cmOrderLinkDirectories.h, Source/cmTarget.cxx,
- Source/cmTarget.h, Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/complex.cxx: ENH: Implement
- linking with paths to library files instead of -L and -l
- separation. See bug #3832
-
- - This is purely an implementation improvement. No interface
- has changed.
- - Create cmComputeLinkInformation class
- - Move and re-implement logic from:
- cmLocalGenerator::ComputeLinkInformation
- cmOrderLinkDirectories
- - Link libraries to targets with their full path (if it is
- known)
- - Dirs specified with link_directories command still added with
- -L
- - Make link type specific to library names without paths
- (name libfoo.a without path becomes -Wl,-Bstatic -lfoo)
- - Make directory ordering specific to a runtime path
- computation feature
- (look for conflicting SONAMEs instead of library names)
- - Implement proper rpath support on HP-UX and AIX.
-
-2008-01-22 08:52 king
-
- * Source/kwsys/hash_map.hxx.in: COMP: Remove inline keyword from
- forward declaration for VS9.
-
-2008-01-22 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-21 22:48 king
-
- * Source/cmFindPackageCommand.cxx: ENH: Updated find_package
- documentation to describe common usage first.
-
-2008-01-21 20:57 king
-
- * Modules/: CMakeDetermineCompilerId.cmake,
- CMakeFindBinUtils.cmake: ENH: Cleanup chrpath feature by not
- displaying exe format or placing non-advanced options in cache.
-
-2008-01-21 18:30 king
-
- * Source/: cmFindLibraryCommand.cxx, cmFindLibraryCommand.h: ENH:
- Add support to find_library to transform /lib to /lib32 on some
- architectures.
-
-2008-01-21 18:30 king
-
- * Modules/CMakeCCompiler.cmake.in, Modules/CMakeCCompilerABI.c,
- Modules/CMakeCXXCompiler.cmake.in,
- Modules/CMakeCXXCompilerABI.cpp, Modules/CMakeCompilerABI.h,
- Modules/CMakeDetermineCompilerABI.cmake,
- Modules/CMakeTestCCompiler.cmake,
- Modules/CMakeTestCXXCompiler.cmake,
- Source/cmDocumentVariables.cxx: ENH: Generalize the check for
- sizeof void* to detect more ABI information.
-
-2008-01-21 17:29 king
-
- * Tests/CMakeLists.txt: BUG: Do not get in infinite loop when
- checking make tool version in cmake build tree.
-
-2008-01-21 13:59 king
-
- * Source/cmTarget.cxx: BUG: Added missing documentation of
- LINK_FLAGS_<CONFIG> property.
-
-2008-01-21 13:04 king
-
- * Source/cmFindPackageCommand.cxx: COMP: snprintf is not portable.
-
-2008-01-21 12:56 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Modules/Platform/Windows-cl.cmake,
- Modules/Platform/Windows-cl.cmake.in,
- Source/cmGlobalVisualStudio9Generator.cxx,
- Source/cmGlobalVisualStudio9Generator.h: ENH: final 2.4.8
-
-2008-01-21 08:48 king
-
- * Modules/readme.txt, Source/cmFindPackageCommand.cxx,
- Source/cmFindPackageCommand.h,
- Tests/FindPackageTest/CMakeLists.txt,
- Tests/FindPackageTest/FindVersionTestA.cmake,
- Tests/FindPackageTest/FindVersionTestB.cmake,
- Tests/FindPackageTest/FindVersionTestC.cmake: ENH: Implement
- version support in the find_package command module mode. Version
- numbers provided to the command are converted to variable
- settings to tell the FindXXX.cmake module what version is
- requested. This addresses issue #1645.
-
-2008-01-21 08:01 king
-
- * Source/kwsys/SystemTools.cxx: COMP: Fix VS6 and old HP build.
- This source does not have the #define for hack.
-
-2008-01-21 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-20 19:29 king
-
- * Source/: cmFindLibraryCommand.cxx, cmFindPathCommand.cxx,
- kwsys/SystemTools.cxx: BUG: Fix previous commit to not access
- empty strings out of bounds.
-
-2008-01-20 17:41 king
-
- * Source/cmFindLibraryCommand.cxx: BUG: Make sure search paths
- never have double-slashes. Leading with two slashes (//) on
- cygwin looks like a network path and delays while waiting for a
- non-existent machine. This file was left out of the previous
- checkin for this problem.
-
-2008-01-20 17:24 king
-
- * Source/: cmFindPathCommand.cxx, kwsys/SystemTools.cxx: BUG: Make
- sure search paths never have double-slashes. Leading with two
- slashes (//) on cygwin looks like a network path and delays while
- waiting for a non-existent machine.
-
-2008-01-20 16:02 king
-
- * Modules/FindX11.cmake: BUG: FindX11 module should search for SM
- library instead of returning -lSM.
-
-2008-01-20 13:36 king
-
- * Source/cmake.cxx: COMP: Fix build during bootstrap on MSys.
-
-2008-01-20 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-19 15:09 martink
-
- * Source/: cmLocalGenerator.cxx, CTest/cmCTestTestHandler.cxx: ENH:
- improve backwards compatibility
-
-2008-01-19 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-18 19:02 barre
-
- * Modules/: FindTCL.cmake, FindTclsh.cmake, FindWish.cmake: ENH:
- Tcl/Tk 8.6 alpha schedule for May 2008.
-
-2008-01-18 18:40 king
-
- * Source/cmDependsFortran.cxx: COMP: Fix build on Borland 5.5.
-
-2008-01-18 17:11 alex
-
- * Source/cmMakefile.cxx: BUG: don't crash if
- cmMakefile::RaiseScope() is called from a cmake file in the top
- level directory in normal code (i.e. not within a function)
-
- Alex
-
-2008-01-18 16:06 hoffman
-
- * Modules/Platform/Windows-cl.cmake.in: ENH: make sure msvc90 gets
- set
-
-2008-01-18 15:52 alex
-
- * Modules/CMakeDetermineCompilerId.cmake,
- Modules/FindwxWidgets.cmake, Source/cmBootstrapCommands.cxx,
- Source/cmRaiseScopeCommand.cxx, Source/cmRaiseScopeCommand.h,
- Source/cmSetCommand.cxx, Source/cmSetCommand.h,
- Tests/FunctionTest/CMakeLists.txt, Tests/FunctionTest/Util.cmake,
- Tests/FunctionTest/SubDirScope/CMakeLists.txt: ENH: remove
- RAISE_SCOPE() again and instead add SET(<var> <value>
- PARENT_SCOPE)
-
- Alex
-
-2008-01-18 15:19 hoffman
-
- * Modules/Platform/Windows-cl.cmake: ENH: make sure MSVC90 is set
-
-2008-01-18 14:34 hoffman
-
- * Source/: cmGlobalVisualStudio9Generator.cxx,
- cmGlobalVisualStudio9Generator.h: ENH: add MSVC90 define to vs9
- ide
-
-2008-01-18 14:02 barre
-
- * Modules/: FindTCL.cmake, FindTclsh.cmake, FindWish.cmake: ENH:
- cleanup FindPerl and FindTcl (use ActiveState CurrentVersion, and
- support Tcl/Tk 8.5)
-
-2008-01-18 13:51 barre
-
- * Modules/: FindTclsh.cmake, FindWish.cmake: ENH: cleanup FindPerl
- and FindTcl (use ActiveState CurrentVersion, and support Tcl/Tk
- 8.5)
-
-2008-01-18 13:46 barre
-
- * Modules/: FindTCL.cmake, FindTclsh.cmake, FindWish.cmake: ENH:
- cleanup FindPerl and FindTcl (use ActiveState CurrentVersion, and
- support Tcl/Tk 8.5)
-
-2008-01-18 13:15 barre
-
- * Modules/: FindPerl.cmake, FindTCL.cmake, FindTclsh.cmake,
- FindWish.cmake: ENH: cleanup FindPerl and FindTcl (use
- ActiveState CurrentVersion, and support Tcl/Tk 8.5)
-
-2008-01-18 12:26 martink
-
- * Source/cmMacroCommand.h: STYLE: fix bug 5682
-
-2008-01-18 10:25 martink
-
- * Source/: cmLocalGenerator.cxx, cmLocalUnixMakefileGenerator3.cxx,
- cmake.cxx, CTest/cmCTestTestHandler.cxx: BUG: fix bugs 5539
- (progress going beyond 100% when new files are added) and 5889
- (tests are not found in some cases when using add_subdirectory to
- .. etc)
-
-2008-01-18 08:35 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Construction of
- COMPILE_DEFINITIONS_<CONFIG> property name must use upper-case
- config name.
-
-2008-01-18 08:19 king
-
- * Source/cmFindPackageCommand.cxx: STYLE: Fix line-too-long.
-
-2008-01-18 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-17 20:59 king
-
- * Source/cmFindPackageCommand.cxx: ENH: Clarify documentation of
- find_package command.
-
-2008-01-17 20:34 king
-
- * Source/cmMakefile.cxx, Tests/Complex/CMakeLists.txt,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/complex.cxx: ENH: Make
- per-configuration COMPILE_DEFINITIONS_<CONFIG> directory property
- initialized from parent.
-
-2008-01-17 19:58 king
-
- * Modules/CMakeFortranInformation.cmake,
- Modules/Platform/Windows-ifort.cmake,
- Source/cmDependsFortran.cxx, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx: ENH: Enable use of
- COMPILE_DEFINITIONS property for Fortran sources.
-
-2008-01-17 19:50 king
-
- * Source/cmMakefile.cxx: BUG: COMPILE_DEFINITIONS directory
- property needs to be inherited from parent when a directory is
- created.
-
-2008-01-17 19:29 king
-
- * Source/cmAddDefinitionsCommand.h,
- Source/cmGlobalXCodeGenerator.cxx, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmMakefileTargetGenerator.cxx,
- Source/cmRemoveDefinitionsCommand.h,
- Tests/Preprocess/CMakeLists.txt, Tests/Preprocess/preprocess.c,
- Tests/Preprocess/preprocess.cxx: ENH: Converted cmMakefile
- DefineFlags added by ADD_DEFINITIONS command into a
- COMPILE_DEFINITIONS directory property.
-
-2008-01-17 18:13 king
-
- * Source/: cmMakefile.cxx, cmMakefile.h, cmProperty.cxx,
- cmProperty.h, cmPropertyMap.cxx, cmPropertyMap.h,
- cmSetPropertyCommand.cxx, cmSetPropertyCommand.h,
- cmSourceFile.cxx, cmSourceFile.h, cmTarget.cxx, cmTarget.h,
- cmTest.cxx, cmTest.h, cmake.cxx, cmake.h: ENH: Add AppendProperty
- methods for use by C++ code in CMake. Simplify implementation of
- SET_PROPERTY command by using them.
-
-2008-01-17 17:49 alex
-
- * Source/cmFindBase.cxx: STYLE: PATHS is optional (#6253)
-
- Alex
-
-2008-01-17 17:43 alex
-
- * Source/cmFindBase.cxx: STYLE: fix typo (#6252)
-
- Alex
-
-2008-01-17 17:34 king
-
- * Tests/Preprocess/CMakeLists.txt: ENH: Use new set_property
- signature to set COMPILE_DEFINITIONS properties in Preprocess
- test.
-
-2008-01-17 17:19 king
-
- * Modules/CPackDeb.cmake, Modules/FeatureSummary.cmake,
- Modules/FindPythonLibs.cmake, Source/cmGetPropertyCommand.cxx,
- Source/cmGetPropertyCommand.h, Tests/Properties/CMakeLists.txt:
- ENH: Changed signature of GET_PROPERTY command to be more
- powerful and extendible.
-
-2008-01-17 16:24 king
-
- * Source/cmSetPropertyCommand.cxx: COMP: Fix VS build.
-
-2008-01-17 15:54 king
-
- * Modules/CMakeGenericSystem.cmake, Modules/FeatureSummary.cmake,
- Modules/Platform/BlueGeneL.cmake,
- Modules/Platform/Catamount.cmake, Modules/Platform/Generic.cmake,
- Modules/Platform/Linux.cmake, Modules/Platform/UnixPaths.cmake,
- Modules/Platform/eCos.cmake, Source/cmBootstrapCommands.cxx,
- Source/cmSetPropertiesCommand.cxx,
- Source/cmSetPropertiesCommand.h, Source/cmSetPropertyCommand.cxx,
- Source/cmSetPropertyCommand.h, Tests/DocTest/CMakeLists.txt,
- Tests/Properties/CMakeLists.txt: ENH: Rename SET_PROPERITES
- command to SET_PROPERTY and give it a more powerful signature.
-
-2008-01-17 12:44 martink
-
- * Source/: cmLocalGenerator.cxx, ctest.cxx,
- CTest/cmCTestTestHandler.cxx: ENH: use CTestTestfile.txt
-
-2008-01-17 12:35 martink
-
- * Source/cmEnableTestingCommand.h: ENH: remove unused prototype
-
-2008-01-17 10:35 king
-
- * bootstrap: COMP: The find_package command needs more of kwsys.
- Added String.h, String.c, and auto_ptr.hxx to bootstrapping
- kwsys.
-
-2008-01-17 10:32 king
-
- * Source/cmFindPackageCommand.cxx: COMP: Fix warning about missing
- virtual destructor.
-
-2008-01-17 10:26 martink
-
- * Tests/Tutorial/Step7/: CMakeLists.txt, CTestConfig.cmake: STYLE:
- change case to match book
-
-2008-01-17 10:00 king
-
- * Modules/Platform/xlf.cmake, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmMakefileTargetGenerator.cxx: ENH: Enable
- CMAKE_<lang>_DEFINE_FLAG for COMPILE_DEFINITIONS property
- implementation.
-
-2008-01-17 09:06 king
-
- * Tests/FindPackageTest/: CMakeLists.txt,
- TApp.app/Contents/Resources/TAppConfig.cmake,
- TApp.app/Contents/Resources/cmake/tapp-config.cmake,
- TFramework.framework/Versions/A/Resources/tframework-config.cmake,
- TFramework.framework/Versions/A/Resources/CMake/TFrameworkConfig.cmake,
- lib/Bar/BarConfig.cmake, lib/Bar/cmake/bar-config.cmake,
- lib/TApp/TAppConfig.cmake, lib/foo-1.2/foo-config.cmake,
- lib/foo-1.2/CMake/FooConfig.cmake,
- lib/suffix/test/SuffixTestConfig.cmake: ENH: Updated
- FindPackageTest to test new find_package command features.
-
-2008-01-17 09:02 king
-
- * Source/: cmBootstrapCommands.cxx, cmFindBase.cxx, cmFindBase.h,
- cmFindCommon.cxx, cmFindCommon.h, cmFindLibraryCommand.cxx,
- cmFindPackageCommand.cxx, cmFindPackageCommand.h,
- cmFindPathCommand.cxx, cmFindProgramCommand.cxx: ENH: Major
- improvements to the FIND_PACKAGE command. See bug #3659.
-
- - Use CMAKE_PREFIX_PATH and CMAKE_SYSTEM_PREFIX_PATH among
- other means
- to locate package configuration files.
- - Create cmFindCommon as base for cmFindBase and
- cmFindPackageCommand
- - Move common functionality up to cmFindCommon
- - Improve documentation of FIND_* commands.
- - Fix FIND_* commands to not add framework/app paths in wrong
- place.
-
-2008-01-17 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-16 11:53 karthik
-
- * Docs/: cmake-indent.vim, cmake-syntax.vim: ENH:
-
-
- ~/CMake/src/Docs * Additions for cmake-command
- highligting. * Additions for operator-highlighting
-
-2008-01-16 11:24 king
-
- * Source/cmListCommand.cxx: ENH: Allow LIST(APPEND) command to
- append nothing.
-
-2008-01-16 10:04 david.cole
-
- * Modules/FindJNI.cmake: BUG: Eliminate message - it pops up an
- annoying dialog whenever you run CMakeSetup in a project with
- java wrapping turned on.
-
-2008-01-16 09:51 king
-
- * Modules/Platform/: Darwin.cmake, UnixPaths.cmake,
- WindowsPaths.cmake, syllable.cmake: ENH: Convert Modules/Platform
- specification of system search paths to use
- CMAKE_SYSTEM_PREFIX_PATH when possible.
-
-2008-01-16 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-15 21:20 king
-
- * Modules/: FindFreetype.cmake, FindGDAL.cmake, FindGIF.cmake,
- FindLua50.cmake, FindLua51.cmake, FindOpenAL.cmake,
- FindOpenThreads.cmake, FindPhysFS.cmake, FindProducer.cmake,
- FindQuickTime.cmake, FindSDL.cmake, FindSDL_image.cmake,
- FindSDL_mixer.cmake, FindSDL_net.cmake, FindSDL_ttf.cmake,
- Findosg.cmake, FindosgDB.cmake, FindosgFX.cmake, FindosgGA.cmake,
- FindosgIntrospection.cmake, FindosgManipulator.cmake,
- FindosgParticle.cmake, FindosgProducer.cmake,
- FindosgShadow.cmake, FindosgSim.cmake, FindosgTerrain.cmake,
- FindosgText.cmake, FindosgUtil.cmake, FindosgViewer.cmake: BUG:
- Remove references to CMAKE_PREFIX_PATH variable. It should not
- be referenced directly by FIND_* command calls. The commands
- search it automatically.
-
-2008-01-15 21:02 king
-
- * Source/cmGlobalXCodeGenerator.cxx,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmMakefileTargetGenerator.cxx, Source/cmSourceFile.cxx,
- Source/cmTarget.cxx, Tests/Preprocess/CMakeLists.txt: ENH:
- Renamed <CONFIG>_COMPILE_DEFINITIONS to
- COMPILE_DEFINITIONS_<CONFIG> for better documentation clarity.
-
-2008-01-15 19:56 alex
-
- * Modules/CMakeFindBinUtils.cmake: STYLE: fix infinished comment
-
- Alex
-
-2008-01-15 17:02 hoffman
-
- * CMakeCPackOptions.cmake.in: ENH: fix add/remove program name
-
-2008-01-15 16:02 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudioGenerator.cxx: ENH: move more stuff
- over and get vs 9 working
-
-2008-01-15 14:19 hoffman
-
- * Modules/Platform/SunOS.cmake: BUG: fix for bug 6231, bad regex
- for sunos, worked by chance, but better to have it right
-
-2008-01-15 14:00 hoffman
-
- * Source/: cmGlobalVisualStudio7Generator.cxx,
- cmLocalVisualStudioGenerator.cxx, QtDialog/README: ENH: remove
- patch as directory change was already fixed
-
-2008-01-15 11:56 hoffman
-
- * Source/cmLocalVisualStudioGenerator.cxx: BUG: fix for bug 6234,
- use cd /d so that drives can be changed.
-
-2008-01-15 10:49 king
-
- * Source/cmake.cxx: ENH: Added partial implementation of
- recognizing per-configration properties.
-
-2008-01-15 10:49 king
-
- * Source/: cmSourceFile.cxx, cmTarget.cxx: ENH: Add explicit
- documentation entry for configuration-specific
- <CONFIG>_COMPILE_DEFINITIONS.
-
-2008-01-15 10:38 king
-
- * Tests/DocTest/DocTest.cxx: BUG: Add newline between properties.
-
-2008-01-15 09:09 king
-
- * Tests/Preprocess/CMakeLists.txt: BUG: Test needs ansi C code
- support.
-
-2008-01-15 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-14 19:20 alex
-
- * Docs/: cmake-indent.vim, cmake-syntax.vim: BUG: fix vim
- highlighting, see #6238
-
- Alex
-
-2008-01-14 19:02 alex
-
- * Modules/CMakeFindBinUtils.cmake: BUG: according to the binutils
- mailing list chrpath doesn't work when cross compiling
-
- Alex
-
-2008-01-14 17:19 alex
-
- * Modules/FindSubversion.cmake: BUG: set LC_ALL to C, so message
- from svn are not translated, which can lead to problems (since
- the output is parsed, which fails then)
-
- Brad, Bill, can you think of any reasons this change might create
- problems ?
-
- Alex
-
-2008-01-14 17:05 alex
-
- * Source/cmDocumentation.cxx: BUG: make -help-module-list work by
- filling the modules section first, also for custom modules
-
- Alex
-
-2008-01-14 11:21 king
-
- * Tests/Preprocess/CMakeLists.txt: BUG: Disable semicolon test on
- VS 7.0.
-
-2008-01-14 11:07 king
-
- * Source/cmGlobalXCodeGenerator.cxx: COMP: Fix warning about
- backslash at end of c++ comment.
-
-2008-01-14 09:20 king
-
- * Modules/CMakeCInformation.cmake,
- Modules/CMakeCXXInformation.cmake, Modules/Platform/AIX.cmake,
- Modules/Platform/Generic-SDCC-C.cmake,
- Modules/Platform/QNX.cmake, Modules/Platform/Windows-bcc32.cmake,
- Modules/Platform/Windows-icl.cmake,
- Modules/Platform/Windows-wcl386.cmake, Modules/Platform/cl.cmake,
- Source/cmGlobalXCodeGenerator.cxx,
- Source/cmGlobalXCodeGenerator.h, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio6Generator.h,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h,
- Source/cmMakefileTargetGenerator.cxx, Source/cmSourceFile.cxx,
- Source/cmTarget.cxx, Tests/CMakeLists.txt,
- Tests/Preprocess/CMakeLists.txt, Tests/Preprocess/file_def.h,
- Tests/Preprocess/preprocess.c, Tests/Preprocess/preprocess.cxx,
- Tests/Preprocess/preprocess.h.in,
- Tests/Preprocess/preprocess_vs6.cxx,
- Tests/Preprocess/target_def.h: ENH: Create COMPILE_DEFINITIONS
- property for targets and source files. Create
- <config>_COMPILE_DEFINITIONS property as per-configuration
- version. Add Preprocess test to test the feature. Document
- limitations on Xcode and VS6 generators.
-
-2008-01-14 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-13 16:59 king
-
- * Source/cmLocalGenerator.cxx: BUG: Removed stray debugging
- statement.
-
-2008-01-13 16:36 king
-
- * Source/: cmGlobalNMakeMakefileGenerator.cxx,
- cmLocalGenerator.cxx, cmLocalGenerator.h,
- cmLocalUnixMakefileGenerator3.h,
- cmLocalVisualStudio7Generator.cxx, kwsys/System.c,
- kwsys/System.h.in: ENH: Improved escaping in kwsys/System. Added
- escape of % for NMake. Added escape of ; for the VS IDE.
-
-2008-01-13 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-12 09:52 king
-
- * Source/kwsys/SystemTools.cxx: COMP: Fix build on borland.
-
-2008-01-12 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-11 17:37 hoffman
-
- * Modules/Platform/: AIX-VisualAge-Fortran.cmake,
- Linux-VisualAge-Fortran.cmake, xlf.cmake: ENH: add support for
- xlf with -WF,-D for -D
-
-2008-01-11 13:00 hoffman
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h: ENH: add
- CMAKE_DEFINE_FLAG_(LANG) that can replace -D flags with what the
- compiler actually uses
-
-2008-01-11 12:40 clinton
-
- * Modules/FindQt4.cmake: ENH: For moc commands on Windows, use
- @param_file method to allow arguments longer than Windows'
- command length limitation. Fixes #6221.
-
-2008-01-11 10:36 david.cole
-
- * Source/kwsys/SystemTools.cxx: ENH: Merge changes from main tree
- into VTK-5-0 branch. (Selected Utilities/kwsys/SystemTools.cxx
- fixes for KWWidgets file browser dialog)
-
-2008-01-11 08:33 king
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH: Add
- SystemTools::SplitPathRootComponent and re-implement SplitPath to
- use it. Add better treatment of user home directory paths.
-
-2008-01-11 08:30 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/CMakeVS9FindMake.cmake,
- Source/cmInstallTargetGenerator.cxx: ENH: push a few more changes
- to 2.4.8
-
-2008-01-11 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-10 21:42 david.cole
-
- * Source/kwsys/SystemTools.cxx: ENH: Merge changes from main tree
- into VTK-5-0 branch. (cvs -q up -j1.205 -j1.206
- Utilities/kwsys/SystemTools.cxx)
-
-2008-01-10 18:52 alex
-
- * Modules/FindBoost.cmake: BUG: it seems on some installations
- boost is installed under boost-1_34 , see #5030
-
- FindBoost.cmake recommends using LINK_DIRECTORIES(), is this
- really good ?
-
- Alex
-
-2008-01-10 18:32 king
-
- * Source/kwsys/ProcessUNIX.c: BUG: Fix hang in Process_Kill on OS X
- caused by an OS bug in which a pipe read end cannot be closed if
- the pipe write end is open, the pipe is full, and another process
- is blocking waiting to write. Work around the problem by killing
- the children before closing the pipes.
-
-2008-01-10 16:22 hoffman
-
- * Modules/FindSWIG.cmake: BUG: fix for bug 4145 much better
- findSwig
-
-2008-01-10 15:17 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx,
- cmInstallTargetGenerator.cxx: BUG: fix for bug 6193, fix xcode
- depend helper
-
-2008-01-10 14:47 king
-
- * Modules/Platform/Linux-VisualAge-C.cmake: BUG: Removed stray
- debugging message.
-
-2008-01-10 14:47 king
-
- * Modules/CMakeLists.txt: BUG: Need to install fortran compiler id
- source.
-
-2008-01-10 11:58 king
-
- * Modules/CMakeFortranCompilerId.F90: STYLE: Move VisualAge id
- macro to correct block.
-
-2008-01-10 10:50 hoffman
-
- * Modules/: CMakeFortranCompilerId.F90,
- Platform/Linux-VisualAge-C.cmake,
- Platform/Linux-VisualAge-Fortran.cmake: ENH: add support for
- visual age fortran on linux
-
-2008-01-10 09:46 king
-
- * Source/cmDependsFortran.cxx: COMP: Fix build on VS6.
-
-2008-01-10 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-09 22:09 perera
-
- * Source/: cmAddExecutableCommand.h, cmConfigureFileCommand.h,
- cmDocumentation.cxx, cmEnableLanguageCommand.h, cmFindBase.cxx,
- cmMakefile.cxx, cmSourceFile.cxx, cmStringCommand.h,
- cmTarget.cxx, cmTest.cxx, cmTryCompileCommand.h,
- cmVariableWatchCommand.h, cmWhileCommand.h: STYLE: Spelling fixes
- on documentation
-
-2008-01-09 16:59 alex
-
- * Source/cmDocumentation.cxx: ENH: sort the module files
- alphabetically when generating the documentation of rht modules
-
- Alex
-
-2008-01-09 10:30 king
-
- * Modules/Platform/Windows-ifort.cmake,
- Source/cmDependsFortran.cxx, Source/cmDependsFortran.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Tests/Fortran/CMakeLists.txt, Tests/Fortran/test_preprocess.F90:
- ENH: Patch from Maik to add preprocessor directive handling to
- Fortran dependency scanning. Also added -fpp flag to Intel
- Fortran compiler on Windows by default.
-
-2008-01-09 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-08 17:51 hoffman
-
- * Source/kwsys/: SystemInformation.cxx, SystemInformation.hxx.in:
- ENH: figure out long long value
-
-2008-01-08 17:20 hoffman
-
- * Source/kwsys/SystemInformation.cxx: ENH: fix lots of warnings
-
-2008-01-08 16:40 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/CPack.cmake: ENH:
- remove relocate option in mac installer as it is broken
-
-2008-01-08 16:28 hoffman
-
- * Source/kwsys/CMakeLists.txt: ENH: turn off for now
-
-2008-01-08 14:59 hoffman
-
- * Source/kwsys/: CMakeLists.txt, SystemInformation.cxx,
- SystemInformation.hxx.in: ENH: fix leaks and turn on by default
-
-2008-01-08 11:43 hoffman
-
- * Source/kwsys/: CMakeLists.txt, testSystemInformation.cxx: ENH:
- add missing file
-
-2008-01-08 11:38 hoffman
-
- * Source/kwsys/: CMakeLists.txt, SystemInformation.cxx,
- SystemInformation.hxx.in: ENH: add new system information class
- for use in ctest
-
-2008-01-08 11:06 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/FindQt4.cmake: ENH:
- last change for 2.4.8 branch, I hope, fix for findqt
-
-2008-01-08 08:25 hoffman
-
- * Source/cmDependsFortran.cxx: BUG: make it compile on vs 6
-
-2008-01-08 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-07 23:08 king
-
- * Source/: cmDependsFortranParser.cxx, cmDependsFortranParser.y:
- BUG: Fix parsing of fortran include directives during dependency
- scanning. Previously only #include worked but not just include.
-
-2008-01-07 16:12 king
-
- * Modules/CMakeJavaCompiler.cmake.in, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalUnixMakefileGenerator3.h,
- Source/cmMakefileTargetGenerator.cxx: BUG: Restore old interface
- of "make foo.o" and "make foo.i" even though object file names
- now include source extensions. For Java we also need to always
- remove the source extension (.java -> .class). This fixes the
- re-opening of bug #6169.
-
-2008-01-07 14:52 alex
-
- * Source/cmFileCommand.cxx: BUG: with cmake 2.4 INSTALL_FILES()
- with no files was accepted by cmake, with cmake cvs without this
- patch an invalid cmake_install.cmake script was generated in this
- case, it failed with an error if no files were given. So just do
- nothing if no files are listed to make it compatible.
-
- http://lists.kde.org/?l=kde-commits&m=119965185114478&w=2
-
- Alex
-
-2008-01-07 11:36 king
-
- * Source/cmDependsFortran.cxx: ENH: Changes based on patch from
- Maik for better cmDependsFortran::ModulesDiffer.
-
-2008-01-07 10:27 king
-
- * Modules/: CMakeDetermineCompilerId.cmake,
- CMakeDetermineFortranCompiler.cmake: ENH: Add support to
- CMAKE_DETERMINE_COMPILER_ID macro to try building the id source
- more than once with different extra flags added to the compiler.
- Use the support to correctly identify the Intel Fortran compiler
- on windows which does not preprocess by default without special
- flags.
-
-2008-01-07 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-06 17:18 alex
-
- * Source/cmFindBase.cxx: BUG: fix #6105, if a directory inside
- CMAKE_FIND_ROOT_PATH is given to a FIND_XXX() command, don't
- prepend the root to it (since it is already in this root)
-
- Alex
-
-2008-01-06 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-05 20:37 miguelf
-
- * Modules/FindwxWidgets.cmake: BUG: Support cross-compiling;
- wx-config should be searched for in target platform ONLY (bug
- 6187).
-
-2008-01-05 11:19 miguelf
-
- * Modules/FindwxWidgets.cmake: ENH: Generalized the
- WXWIDGETS_ADD_RESOURCES to support header generation, xrs file
- generation, and other options (BUG: 6162).
-
-2008-01-05 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-04 14:22 king
-
- * Source/cmFileCommand.cxx: BUG: File installation should overwrite
- the destination if the file times differ at all rather than only
- if the source file is newer. Users expect installation to
- overwrite destination files. This addresses the re-opening of
- bug#3349.
-
-2008-01-04 12:38 alex
-
- * Modules/: FindFreetype.cmake, FindGIF.cmake: ENH: rename
- variables from GIFLIB_* to GIF_* -add standard QUIET and REQUIRED
- handling -add GIF_LIBRARIES variable as readme.txt says -add name
- giflib to the names for the gif library -remove some unnecessary
- search paths for the lib (they are already part of the standard
- search paths, see Modules/Platform/UnixPaths.cmake)
- -FindFreetype.cmake: use PATH_SUFFIXES include again for the
- headers with the CMAKE_PREFIX_PATH variable
-
- Alex
-
-2008-01-04 12:29 alex
-
- * Modules/: FindGIF.cmake, FindGIFLIB.cmake: STYLE: rename
- FindGIFLIB.cmake to FindGIF.cmake, as discussed with Eric
-
- Alex
-
-2008-01-04 11:56 alex
-
- * Modules/FindX11.cmake: BUG: fix spelling of the xf86misc and
- xf86vmode variables
-
- Alex
-
-2008-01-04 11:42 ewing
-
- * Modules/FindOpenAL.cmake: ENH: Added all lowercase 'openal' to
- library search names in hopes of addressing bug 6201 (won't
- detect on Gentoo).
-
-2008-01-04 07:29 alex
-
- * Modules/FindFreetype.cmake: STYLE: use
- FIND_PACKAGE_HANDLE_STANDARD_ARGS() to handle QUIET and REQUIRED
- -remove some unnecessary search paths (they are part of the
- default paths) -don't use PATH_SUFFIXES for include/ when
- searching for a header, that's very uncommon style -add
- FREETYPE_LIBRARIES as the variable which should be used by the
- user (as documented in readme.txt)
-
- Alex
-
-2008-01-04 07:25 alex
-
- * Modules/: FindFreeType.cmake, FindFreetype.cmake: STYLE: renamed
- FindFreeType.cmake to FindFreetype.cmake to make it more
- compatible with the one in KDE4
-
- Alex
-
-2008-01-04 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-03 11:21 martink
-
- * Source/cmMakefile.cxx, Source/cmMakefile.h,
- Source/cmRaiseScopeCommand.cxx, Source/cmRaiseScopeCommand.h,
- Tests/FunctionTest/CMakeLists.txt,
- Tests/FunctionTest/SubDirScope/CMakeLists.txt,
- Tests/FunctionTest/Util.cmake: ENH: change raise_scope signature
- to be safer for returned varuables
-
-2008-01-03 09:40 king
-
- * Source/cmFileCommand.cxx: STYLE: Fix line-too-long.
-
-2008-01-03 07:28 hoffman
-
- * Source/cmake.cxx: BUG: fix resource file with a full path
-
-2008-01-03 04:19 alex
-
- * Source/cmFileCommand.cxx: COMP: fix build on Windows with gcc,
- patch from Maik Beckmann
-
- Alex
-
-2008-01-03 00:01 king
-
- * Source/: cmFileTimeComparison.cxx, cmFileTimeComparison.h: ENH:
- Add method cmFileTimeComparison::FileTimesDiffer to check if file
- times differ by 1 second or more.
-
-2008-01-03 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-02 18:30 king
-
- * Source/cmDependsFortran.cxx: ENH: Cleanup Fortran build
- directories by placing module stamp files in the target directory
- that builds them. This is actually a simpler implementation
- anyway.
-
-2008-01-02 18:00 king
-
- * Tests/StringFileTest/CMakeLists.txt: ENH: Add test for FILE(READ
- ...HEX).
-
-2008-01-02 17:49 king
-
- * Source/cmMakefile.cxx, Tests/FunctionTest/CMakeLists.txt,
- Tests/FunctionTest/SubDirScope/CMakeLists.txt: BUG: Make
- RAISE_SCOPE function work when variable is not defined.
-
-2008-01-02 17:32 king
-
- * Docs/cmake-mode.el: ENH: Enable indentation of
- FUNCTION/ENDFUNCTION blocks in emacs.
-
-2008-01-02 17:12 hoffman
-
- * Modules/UseSWIG.cmake: BUG: fix for bug 6151
-
-2008-01-02 16:53 alex
-
- * Source/cmTarget.cxx: ENH: only allow usage of chrpath if the
- executable file format is ELF
-
- Alex
-
-2008-01-02 16:52 alex
-
- * Modules/: CMakeDetermineCompilerId.cmake,
- CMakeFindBinUtils.cmake: ENH: check the magic code of the
- executable file to determine the executable file format. Tested
- for ELF on x86 Linux, COFF and Mach-O prepared but commented out
- since I don't have such systems available. Please have a look a
- CMakeDetermineCompilerId.cmake and enable the test for them too.
-
- Only add the option for using chrpath if the executable format is
- ELF
-
- Alex
-
-2008-01-02 16:46 alex
-
- * Source/: cmFileCommand.cxx, cmFileCommand.h: ENH: add the
- keywords OFFSET and HEX to the FILE() command, using OFFSET an
- offset can be specified where the reading starts, and using HEX
- the data can be converted into a hex string, so binary data can
- be compared with text functions -add docs for LIMIT, OFFSET and
- HEX
-
- Alex
-
-2008-01-02 15:55 king
-
- * Source/cmGlobalVisualStudio8Generator.cxx: STYLE: Fixed
- line-too-long.
-
-2008-01-02 15:53 king
-
- * Source/cmGlobalVisualStudio8Generator.cxx: BUG: Do not use
- VSMacros stuff for VS8sp0 because macros do not work in that
- version.
-
-2008-01-02 15:17 king
-
- * Source/cmFileCommand.cxx, Source/cmInstallCommand.cxx,
- Source/cmInstallCommand.h, Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: Added FILES_MATCHING
- option to INSTALL(DIRECTORY). This will help install a tree of
- header files while ignoring non-headers.
-
-2008-01-02 12:32 alex
-
- * Modules/FindRuby.cmake: ENH: add more ruby paths: sitearch,
- sitelib, vendorarch, vendorlib (#5531) -make these variables
- cached and ADVANCED -remove unused QUIETLY code -document
- RUBY_LIBRARY
-
- Alex
-
-2008-01-02 11:43 alex
-
- * Modules/FindRuby.cmake: BUG: make FindRuby work with the libs for
- MSVC, which can have additional pre- and suffixes (#5642)
-
- Alex
-
-2008-01-02 11:08 hoffman
-
- * Source/cmAuxSourceDirectoryCommand.cxx: BUG: fix for bug 6197,
- absolute paths were not supported
-
-2008-01-02 11:04 king
-
- * Source/: cmDependsFortran.cxx, cmDependsFortran.h,
- cmLocalUnixMakefileGenerator3.cxx: ENH: Make the Fortran compiler
- id available to cmDependsFortran at scanning and module timestamp
- copy time.
-
-2008-01-02 10:56 hoffman
-
- * Source/cmListCommand.h: BUG: fix for bug 6207 explain list index
- values better
-
-2008-01-02 09:32 hoffman
-
- * Source/cmake.cxx: ENH: fix new incremental link stuff to work
- with nmake @ files
-
-2008-01-02 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2008-01-01 17:19 hoffman
-
- * Source/cmake.cxx: ENH: remove warning
-
-2008-01-01 15:13 hoffman
-
- * Modules/CMakeVCManifest.cmake, Modules/CMakeVCManifestExe.cmake,
- Modules/Platform/Windows-cl.cmake, Source/cmMakefile.cxx,
- Source/cmSystemTools.cxx, Source/cmSystemTools.h,
- Source/cmake.cxx, Source/cmake.h: ENH: add ability to have
- manifest files and incremental linking with make and nmake
-
-2008-01-01 10:54 king
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: BUG: Fix SimpleInstall test to
- work with new dependency of package on all.
-
-2008-01-01 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-31 17:29 david.cole
-
- * Source/cmGlobalGenerator.cxx: ENH: Add a dependency from the
- PACKAGE target to the ALL target so that "make package" will
- first (essentially) do a "make all"... A similar chunk of code
- already existed for the make install target. This change makes it
- easy to build an installer package as part of a dashboard run
- simply by setting CTEST_BUILD_TARGET to "package".
-
-2007-12-31 11:25 king
-
- * Source/: cmDependsFortran.cxx, cmDependsFortran.h: ENH: Changes
- based on patch from Maik Beckmann to copy fortran modules to
- timestamps only if they have really changed. This optimization
- should reduce extra rebuilds caused by dependencies on modules
- whose providers have recompiled but whose interfaces have not
- changed.
-
-2007-12-31 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-30 16:34 king
-
- * Modules/Platform/SunOS-SunPro-Fortran.cmake: ENH: Add SunPro
- fortran module flags on SunOS.
-
-2007-12-30 16:11 king
-
- * Modules/Platform/Linux-GNU-Fortran.cmake,
- Modules/Platform/Linux-SunPro-Fortran.cmake,
- Modules/Platform/Linux-ifort.cmake, Source/cmDependsFortran.cxx,
- Source/cmDependsFortran.h, Source/cmDocumentVariables.cxx,
- Source/cmMakefileTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.h, Source/cmTarget.cxx,
- Tests/Fortran/CMakeLists.txt,
- Tests/Fortran/Executable/CMakeLists.txt,
- Tests/Fortran/Library/CMakeLists.txt: ENH: Implemented Fortran
- module output directory and search path flags.
-
-2007-12-30 12:23 king
-
- * Source/cmDependsFortran.cxx: ENH: Simplify Fortran module proxy
- dependency implementation by removing unnecessary target.
-
-2007-12-30 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-29 11:53 alex
-
- * Source/cmDocumentation.cxx: BUG: create modules documentation not
- only for the first documentation creation step in cmake (the set
- ModulesFound wasn't cleared at the beginning of each
- PrintDocumentation() function, so when documentation for modules
- was executed the second time, ModulesFound already contained all
- modules and so no module was documented)
-
- Alex
-
-2007-12-29 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-28 23:07 king
-
- * Source/cmLocalGenerator.cxx, Tests/ExternalOBJ/CMakeLists.txt,
- Tests/MakeClean/ToClean/CMakeLists.txt: BUG: Do not remove the
- source file extension when computing an object file name. This
- addresses bug #6169. If CMAKE_BACKWARDS_COMPATIBILITY is 2.4 or
- lower maintain the old behavior so that existing build trees and
- old project releases are not affected.
-
-2007-12-28 23:07 king
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h,
- cmStandardIncludes.h: ENH: Added method
- cmLocalGenerator::GetBackwardsCompatibility to reduce parsing of
- CMAKE_BACKWARDS_COMPATIBILITY variable. Add
- cmLocalGenerator::NeedBackwardsCompatibility to simplify checks
- for compatibility requirements.
-
-2007-12-28 22:53 king
-
- * Tests/Fortran/CMakeLists.txt: BUG: Disable test of fortran module
- dependencies except on GNU for now. A module path feature is
- needed for Sun support because it uses -M instead of -I for the
- module search path.
-
-2007-12-28 22:29 king
-
- * Source/cmDependsFortran.cxx: COMP: Fix uninitialized variable and
- unused parameter warnings.
-
-2007-12-28 14:59 king
-
- * Source/: cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx, cmMakefileTargetGenerator.h: ENH:
- Simplified and moved link script implementation up from
- cmMakefileLibraryTargetGenerator to cmMakefileTargetGenerator and
- use for cmMakefileExecutableTargetGenerator too. This addresses
- bug #6192.
-
-2007-12-28 13:20 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, MacInstallReadme.txt: ENH: add
- some descriptive text for mac installer
-
-2007-12-28 12:01 king
-
- * Source/cmFindBase.cxx: ENH: Make FIND_* commands look in the
- CMAKE_PREFIX_PATH directories directly after looking in each
- command's specific subdirectory (/include, /lib, or /bin). This
- may be useful on Windows where projects could be installed in a
- single directory. See issue #4947.
-
-2007-12-28 11:50 king
-
- * Tests/Fortran/: CMakeLists.txt, Executable/CMakeLists.txt,
- Executable/main.f90, External/CMakeLists.txt, External/a.f90:
- ENH: Add tests of Fortran module dependencies across directories
- and on external modules. Tests based on cases provided by Maik
- in issue #5809.
-
-2007-12-28 11:50 king
-
- * Source/: cmDependsFortran.cxx, cmLocalUnixMakefileGenerator3.cxx:
- ENH: Add per-language clean rule generation to cmake_clean.cmake
- files to include cmake_clean_<lang>.cmake files generated by
- dependency scanning. Add Fortran module file and timestamp
- cleaning rules.
-
-2007-12-28 11:49 king
-
- * Source/: cmDepends.cxx, cmDepends.h, cmDependsFortran.cxx,
- cmDependsFortran.h: ENH: Implement Fortran module dependencies
- across targets and directories. - See issue #5809 - Keep
- information about all sources in the target until deps are
- written - Create a fortran.internal file after scanning that
- lists modules provided - Load fortran.internal files from
- linked targets to find modules - Search the include path for
- external modules - Create file-level deps on in-project module
- timestamps or external mods
-
-2007-12-28 11:49 king
-
- * Source/cmMakefileTargetGenerator.cxx: ENH: Store in
- DependInfo.cmake files a list of the corresponding files for the
- targets to which a target links. This is useful for locating
- Fortran modules provided by linked targets. See issue #5809.
-
-2007-12-28 09:49 hoffman
-
- * ChangeLog.manual, Modules/CPack.Info.plist.in,
- Modules/CPack.cmake: ENH: move over mac package change
-
-2007-12-28 09:34 hoffman
-
- * CMakeLists.txt, ChangeLog.manual: ENH: ooppss there is no 2.4.9
-
-2007-12-28 09:11 hoffman
-
- * CMakeLists.txt, ChangeLog.manual: ENH: make a new version number
-
-2007-12-28 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-27 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-26 16:57 david.cole
-
- * CMakeCPackOptions.cmake.in, Modules/CPack.Info.plist.in,
- Modules/CPack.cmake: ENH: Give Mac installers package relocation
- capability. Default location is still the same for backwards
- compatibility, but packages will now be relocatable by default
- like they are on Windows via the NSIS installer. New CPack
- variables for controlling this functionality are
- CPACK_PACKAGE_DEFAULT_LOCATION and CPACK_PACKAGE_RELOCATABLE.
-
-2007-12-26 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-25 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-24 11:15 king
-
- * Source/cmGlobalGenerator.cxx: COMP: Fix build on VS6.
-
-2007-12-24 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-23 19:03 king
-
- * Source/cmLinkDirectoriesCommand.h: ENH: Clarify documentation of
- link_directories command for bug#6199.
-
-2007-12-23 15:03 king
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h, cmTarget.h: ENH: Moved global
- inter-target dependency analysis and cycle-prevention code up
- from cmGlobalUnixMakefileGenerator3 to cmGlobalGenerator.
- Simplified cmGlobalUnixMakefileGenerator3 to use it. Later other
- generators may be modified to use it also.
-
-2007-12-23 13:16 king
-
- * Source/cmGlobalXCodeGenerator.cxx: BUG: Revert previous change
- until it works on all OSX versions.
-
-2007-12-23 13:13 king
-
- * Source/cmGlobalVisualStudio71Generator.cxx: BUG: Disable static
- lib deps until a global cycle removal can be done.
-
-2007-12-23 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-22 22:41 king
-
- * Source/: cmDepends.cxx, cmDepends.h, cmDependsFortran.cxx,
- cmDependsFortran.h, cmLocalUnixMakefileGenerator3.cxx: ENH:
- Convert cmDepends object interface to scan an entire target at
- once.
-
-2007-12-22 14:17 king
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: Simplify target-level
- dependencies by depending only on directly linked targets instead
- of those chained.
-
-2007-12-22 13:08 king
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h: BUG: Support cyclic
- dependencies among STATIC libraries by removing one from the
- generated Makefile rules.
-
-2007-12-22 10:15 miguelf
-
- * Modules/FindwxWidgets.cmake: STYLE: Refactored common libs into a
- variable, modified comments, and cleaned use of monolithic build.
-
-2007-12-22 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-21 20:19 king
-
- * Tests/BuildDepends/CMakeLists.txt: BUG: Enable
- CMAKE_SUPPRESS_REGENERATION because the entire test runs during
- the inital configuration.
-
-2007-12-21 18:32 king
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h: COMP: Remove unused parameter
- of method.
-
-2007-12-21 16:46 ibanez
-
- * Source/kwsys/SystemTools.cxx: BUG: Fix bug#5590. When
- converting a relative path between two full paths on different
- windows drive letters do not create a ../../d:/foo/bar path
- and just return the full path to the destination.
-
-2007-12-21 15:04 king
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio8Generator.h,
- cmGlobalVisualStudioGenerator.cxx,
- cmGlobalVisualStudioGenerator.h, cmGlobalXCodeGenerator.cxx: ENH:
- Make static library targets depend on targets to which they
- "link" for the purpose of build ordering. This makes the build
- order consistent for static and shared library builds. It is
- also useful when custom command inputs of one library are
- generated as custom commands outputs of another. It may be
- useful in the future for Fortran module dependencies.
- Implemented for Makefiles, Xcode, and VS 8 and above. Added
- sample code to do it for VS 7.1 and below, but left it disabled
- with comments explaining why. Likely it will never be needed on
- VS 7.1 or below anyway.
-
-2007-12-21 13:10 king
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: BUG: Now that custom
- targets have dependencies their DependInfo files should be listed
- in Makefile.cmake.
-
-2007-12-21 12:22 king
-
- * Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmGlobalUnixMakefileGenerator3.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalUnixMakefileGenerator3.h,
- Source/cmMakefileExecutableTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.h,
- Source/cmMakefileUtilityTargetGenerator.cxx, Source/cmake.cxx,
- Tests/BuildDepends/CMakeLists.txt,
- Tests/BuildDepends/Project/CMakeLists.txt,
- Tests/BuildDepends/Project/dep_custom.cxx,
- Tests/BuildDepends/Project/zot.cxx: ENH: Add a depends check step
- to custom targets. Add support for the IMPLICIT_DEPENDS feature
- of custom commands when building in custom targets. Convert
- multiple-output pair checks to be per-target instead of global.
-
-2007-12-21 11:00 king
-
- * Source/cmMakefileTargetGenerator.cxx: BUG: The dependency
- scanning target should be symbolic.
-
-2007-12-21 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-20 20:59 ewing
-
- * Modules/: FindFreeType.cmake, FindGDAL.cmake, FindGIFLIB.cmake,
- FindLua50.cmake, FindLua51.cmake, FindOpenAL.cmake,
- FindOpenThreads.cmake, FindPhysFS.cmake, FindProducer.cmake,
- FindQuickTime.cmake, FindSDL.cmake, FindSDL_image.cmake,
- FindSDL_mixer.cmake, FindSDL_net.cmake, FindSDL_sound.cmake,
- FindSDL_ttf.cmake, Findosg.cmake, FindosgDB.cmake,
- FindosgFX.cmake, FindosgGA.cmake, FindosgIntrospection.cmake,
- FindosgManipulator.cmake, FindosgParticle.cmake,
- FindosgProducer.cmake, FindosgShadow.cmake, FindosgSim.cmake,
- FindosgTerrain.cmake, FindosgText.cmake, FindosgUtil.cmake,
- FindosgViewer.cmake: BUG: Fixed modules to set FOO_FOUND when
- both headers and libraries are found. BUG: FindSDL now has flag
- it responds to so it will not find/link against SDLmain. This is
- required to build libraries instead of applications since they
- don't have main(). ENH: All modules have a predictable search
- order, where environmental variables are searched before system
- paths. This is designed to make automation easier for those that
- need to automatically build projects without intervention but may
- be using alternative install locations for isolated testing.
- ENH: New modules for OpenSceneGraph, Freetype, GDAL, Lua,
- QuickTime, GIFLIB, Producer, OpenThreads. STYLE: Added
- documentation explaining peculuar SDL_LIBRARY_TEMP variable in
- SDL module when library find is incomplete.
-
-2007-12-20 17:49 alex
-
- * Source/: cmAuxSourceDirectoryCommand.h, cmBuildCommand.h,
- cmCreateTestSourceList.h, cmExportCommand.h,
- cmExportLibraryDependencies.h, cmOptionCommand.h, cmSetCommand.h:
- STYLE: make formatting of help a bit more consistent
-
- Alex
-
-2007-12-20 10:05 martink
-
- * Source/cmFunctionCommand.cxx: BUG: fix issue with
- CMAKE_CURENT_LIST_FILE reporting in funcitons
-
-2007-12-20 09:35 king
-
- * Source/cmSystemTools.h: COMP: Fixed error on HP due to newline
- macro.
-
-2007-12-20 09:27 king
-
- * Source/cmLocalGenerator.cxx: COMP: Fixed data loss warning.
-
-2007-12-20 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-19 17:54 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Fix make depend
- target in subdirectory Makefile interface.
-
-2007-12-19 17:15 king
-
- * Source/: cmLocalGenerator.h, cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h, cmMakefileTargetGenerator.cxx,
- cmSystemTools.cxx, cmSystemTools.h, cmake.cxx: ENH: Enabled color
- printing of "Scanning dependencies of target ..." message.
-
-2007-12-19 16:53 alex
-
- * Source/cmOptionCommand.h: ENH: options() is now scriptable, set()
- is scriptable too, I don't see a big difference
-
- Alex
-
-2007-12-19 16:48 clinton
-
- * Modules/FindQt4.cmake: ENH: Better QT4_EXTRACT_OPTIONS macro.
-
-2007-12-19 16:46 alex
-
- * Source/cmMakefile.cxx: STYLE: nicer error message: "Command
- options() is not scriptable" is IMO better to understand than
- "Command options not scriptable" (with all uppercase commands it
- was easier to see)
-
- Alex
-
-2007-12-19 16:36 king
-
- * Source/: cmDepends.cxx, cmDepends.h, cmLocalGenerator.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h, cmMakefileTargetGenerator.cxx,
- cmake.cxx: ENH: Moved dependency integrity check from
- CheckBuildSystem over to a per-target UpdateDependencies step.
- This greatly reduces the startup time for make processes and
- allows individual targets to be built without a global dependency
- check.
-
-2007-12-19 16:35 king
-
- * Source/cmDependsFortran.cxx: BUG: cmDependsFortran should store
- the source file as a dependency of the object file when scanning
- for dependencies.
-
-2007-12-19 14:28 king
-
- * Source/: cmDependsFortran.cxx, cmDependsFortran.h,
- cmLocalUnixMakefileGenerator3.cxx: ENH: Pass target directory to
- cmDependsFortran scanning instances.
-
-2007-12-19 11:51 king
-
- * Source/cmake.cxx: ENH: Improved speed of cmake::CheckBuildSystem
- when checking build system outputs versus dependencies. Instead
- of doing an O(m*n) comparison of every pair, just locate the
- oldest output and the newest input and compare them which is now
- O(m+n).
-
-2007-12-19 11:06 king
-
- * Source/cmFindBase.cxx, Tests/FindPackageTest/CMakeLists.txt: ENH:
- Renamed CMAKE_FIND_PREFIX_PATH to CMAKE_PREFIX_PATH for brevity
- and consistency with other find path variable names.
-
-2007-12-19 10:43 hoffman
-
- * Source/: cmListCommand.cxx, cmListCommand.h: ENH: merge in list
- find to support Findqt
-
-2007-12-19 10:34 king
-
- * Source/cmFindBase.cxx: ENH: Added CMAKE_SYSTEM_PREFIX_PATH
- variable.
-
-2007-12-19 03:56 alex
-
- * Source/: cmInstallTargetGenerator.cxx,
- cmInstallTargetGenerator.h, cmLocalGenerator.cxx,
- cmLocalGenerator.h:
- STYLE: fix warnings: comparison signed/unsigned, unused variable
-
- Alex
-
-2007-12-19 03:55 alex
-
- * Modules/CMakeFindBinUtils.cmake:
- BUG: make CMAKE_USE_CHRPATH a simple variable instead an option,
- since an option is not scriptable and so breaks the toolchain
- test or maybe option() should be made scriptable ?
-
- Alex
-
-2007-12-19 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-18 17:50 alex
-
- * Modules/CMakeFindBinUtils.cmake,
- Source/cmInstallTargetGenerator.cxx,
- Source/cmInstallTargetGenerator.h, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h, Source/cmTarget.cxx,
- Source/cmTarget.h: ENH: add support for chrpath, so the RPATH in
- ELF files can be changed when installing without having to link
- the target again -> can save a lot of time
-
- chrpath is handled very similar to install_name_tool on the mac.
- If the RPATH in the build tree file is to short, it is padded
- using the separator character. This is currently disabled by
- default, it can be enabled using the option CMAKE_USE_CHRPATH.
- There are additional checks whether it is safe to enable it. I
- will rework them and use FILE(READ) instead to detect whether the
- binaries are actually ELF files.
-
- chrpath is available here
- http://www.tux.org/pub/X-Windows/ftp.hungry.com/chrpath/ or kde
- svn (since a few days):
- http://websvn.kde.org/trunk/kdesupport/chrpath/
-
- Alex
-
-2007-12-18 15:58 hoffman
-
- * Source/: cmGlobalVisualStudio9Generator.cxx,
- cmGlobalVisualStudio9Generator.h,
- cmGlobalVisualStudio9Win64Generator.cxx,
- cmGlobalVisualStudio9Win64Generator.h: ENH: merge from main tree
-
-2007-12-18 15:02 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/FindPkgConfig.cmake,
- Modules/Platform/Linux-ifort.cmake, Source/CMakeLists.txt,
- Source/cmLocalVisualStudio7Generator.h, Source/cmake.cxx,
- Utilities/cmtar/encode.c: ENH: merge in from main tree
-
-2007-12-18 14:50 clinton
-
- * Modules/FindQt4.cmake: ENH: should define QT_DLL instead of
- QT_SHARED
-
-2007-12-18 13:05 clinton
-
- * Modules/FindQt4.cmake: ENH: Improve documentation of new
- features.
-
-2007-12-18 10:02 hoffman
-
- * Modules/FindBoost.cmake: BUG: fix for bug 5464 better find boost
- for windows
-
-2007-12-18 09:57 hoffman
-
- * Source/cmGetSourceFilePropertyCommand.cxx,
- Tests/COnly/CMakeLists.txt: BUG: fix for bug 6172 add get source
- file prop LANGUAGE
-
-2007-12-18 09:50 king
-
- * Source/cmGlobalXCodeGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalUnixMakefileGenerator3.h,
- Source/cmLocalVisualStudio7Generator.cxx,
- Tests/CustomCommand/CMakeLists.txt: ENH: Implemented generation
- of display for pre-build, pre-link, and post-build custom command
- comments during the build. This addresses issue #5353.
-
-2007-12-18 08:53 hoffman
-
- * Source/cmGlobalVisualStudio8Generator.cxx: STYLE: fix line len
-
-2007-12-18 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-17 21:37 hoffman
-
- * Modules/FindPkgConfig.cmake: BUG: fix for 5722
-
-2007-12-17 19:48 king
-
- * Source/cmGlobalXCodeGenerator.cxx: BUG: Remove stray debugging
- message.
-
-2007-12-17 18:38 king
-
- * Source/cmLocalVisualStudioGenerator.cxx: BUG: When the working
- directory for a custom command is on another drive letter we need
- to change to that drive letter after changing its working
- directory. Fixes issue #6150.
-
-2007-12-17 17:57 hoffman
-
- * Modules/TestForANSIForScope.cmake: STYLE: fix doc string
-
-2007-12-17 17:55 king
-
- * Source/: cmDependsFortranParser.cxx, cmDependsFortranParser.y:
- BUG: Fixed memory-leaks in fortran parser.
-
-2007-12-17 17:55 king
-
- * Source/: cmDependsFortranParser.cxx, cmDependsFortranParser.y:
- BUG: Fix parsing of #include preprocessor directives.
-
-2007-12-17 17:54 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: Fortran include
- path is the same as C and CXX include paths.
-
-2007-12-17 17:50 hoffman
-
- * Utilities/cmtar/encode.c: BUG: fix for bug 5837, libtar and long
- path names
-
-2007-12-17 17:40 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/FindPkgConfig.cmake,
- Modules/FindQt3.cmake, Modules/FindQt4.cmake,
- Modules/UseQt4.cmake, Source/cmDependsFortran.cxx,
- Source/cmInstallCommand.cxx, Source/cmMakefile.cxx,
- Source/cmake.cxx, Source/kwsys/SystemTools.cxx,
- Source/kwsys/SystemTools.hxx.in,
- Source/kwsys/SystemTools.hxx.in.bak: ENH: move changes from main
- tree
-
-2007-12-17 17:28 hoffman
-
- * Source/cmGlobalVisualStudio8Generator.cxx: BUG: fix for bug 5931
- add some more flags for the gui
-
-2007-12-17 17:22 hoffman
-
- * Modules/FindJNI.cmake: BUG: fix for 5933, look for java in more
- reg entries
-
-2007-12-17 17:05 alex
-
- * Modules/CTest.cmake: STYLE: use IF(NOT ) instead of IF() ELSE()
- with empty IF() branch
-
- Alex
-
-2007-12-17 16:15 alex
-
- * Docs/cmake-syntax.vim: STYLE: apply patch from #6166, better
- cmake syntax highlighting in vim, seems to fix the issues
- mentioned in the bug report and the rest also still seems to be
- ok
-
- Alex
-
-2007-12-17 15:27 hoffman
-
- * Source/CPack/cmCPackPackageMakerGenerator.cxx: ENH: try to fix
- dashboard
-
-2007-12-17 15:20 king
-
- * Source/cmInstallCommand.cxx: BUG: Apply patch from issue #6006.
-
-2007-12-17 14:43 hoffman
-
- * Source/: CMakeLists.txt, cmGlobalVisualStudio9Win64Generator.cxx,
- cmGlobalVisualStudio9Win64Generator.h, cmake.cxx: ENH: add
- support for vs 9 win64
-
-2007-12-17 12:04 hoffman
-
- * Modules/: CMakeCInformation.cmake, CMakeCXXInformation.cmake,
- CMakeFortranInformation.cmake: BUG: fix for bug 6167 get rid of
- extra space in flags
-
-2007-12-17 10:12 king
-
- * Source/cmTarget.cxx, Tests/Properties/CMakeLists.txt: ENH: Added
- SOURCES property to targets. This is based on patch from issues
- #6137.
-
-2007-12-17 10:12 king
-
- * Source/: cmSourceFile.cxx, cmSourceFile.h: ENH: Added
- cmSourceFile::GetLocation method to get a read-only reference to
- the Location ivar. This partially addresses issue #6137.
-
-2007-12-17 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-16 07:56 alex
-
- * Source/cmStringCommand.cxx: BUG: fix STRING(STRIP ...) if no
- non-space is contained in the input string, this should fix the
- dashboard
-
- Alex
-
-2007-12-16 05:49 alex
-
- * Modules/FindQt4.cmake: STYLE: some whitespace syncing with
- FindQt4.cmake in KDE svn
-
- Alex
-
-2007-12-16 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-15 16:03 king
-
- * Modules/CMakeDetermineCompilerId.cmake: BUG: Need to strip
- leading and trailing whitespace off the compiler 'ARG1'. This
- fixes bug#6141.
-
-2007-12-15 15:36 king
-
- * Tests/Fortran/: CMakeLists.txt, Library/CMakeLists.txt,
- Library/a.f90, Library/b.f90, Library/main.f90: ENH: Added test
- for Fortran90 modules in subdirectories.
-
-2007-12-15 15:35 king
-
- * Source/cmDependsFortran.cxx: ENH: Make module timestamps work for
- modules in subdirectories. Make sure timestamps for all modules
- provided by a target are created when the target is done
- building.
-
-2007-12-15 14:16 king
-
- * Source/: cmFindPackageCommand.cxx, cmFindPackageCommand.h: STYLE:
- Removed trailing whitespace.
-
-2007-12-15 14:14 king
-
- * Source/cmFindBase.cxx: STYLE: Fixed terminology to avoid
- confusion between roots and prefixes.
-
-2007-12-15 14:13 king
-
- * Source/cmake.cxx: STYLE: Fixed line-too-long.
-
-2007-12-15 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-14 20:46 hoffman
-
- * Source/: cmFindLibraryCommand.cxx, cmFindPathCommand.cxx: BUG:
- fix for bug 6039 LIB and INCLUDE not used for find stuff
-
-2007-12-14 20:31 hoffman
-
- * Source/: cmDependsC.cxx, cmDependsFortran.cxx, cmMakeDepend.cxx,
- kwsys/SystemTools.cxx, kwsys/SystemTools.hxx.in: BUG: fix for bug
- 6136 make sure includes are not directories
-
-2007-12-14 16:56 clinton
-
- * Modules/FindQt4.cmake: ENH: Add OPTIONS argument to some Qt4
- macros. Addresses #6125.
-
-2007-12-14 15:50 hoffman
-
- * Source/cmListCommand.h: BUG: fix bug 6081
-
-2007-12-14 14:58 hoffman
-
- * Source/CPack/cmCPackNSISGenerator.cxx: BUG: fix for 6086
- uninstall icon not set right
-
-2007-12-14 12:51 hoffman
-
- * Modules/FindPkgConfig.cmake: BUG: fix for 6117, fix for second
- run
-
-2007-12-14 12:49 hoffman
-
- * Source/cmCreateTestSourceList.h: STYLE: line length
-
-2007-12-14 11:00 hoffman
-
- * Utilities/cmcurl/curl/mprintf.h: BUG: fix for bug 6054 remove
- some warnings
-
-2007-12-14 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-13 18:30 king
-
- * Source/cmake.cxx: COMP: Add missing return value from Bill's
- change.
-
-2007-12-13 17:56 king
-
- * Source/: cmCTest.cxx, cmCTest.h, cmDumpDocumentation.cxx,
- cmSystemTools.cxx, cmSystemTools.h, cmake.cxx, cmake.h,
- cmakemain.cxx, ctest.cxx, CPack/cpack.cxx,
- CTest/cmCTestScriptHandler.cxx, CursesDialog/ccmake.cxx,
- QtDialog/CMakeSetup.cxx: ENH: Centralized and globalized
- computation of CMake program locations. This eliminates startup
- paths that failed to produce this information.
-
-2007-12-13 17:39 king
-
- * Source/cmake.cxx: BUG: Fixed typo introduced by previous commit.
-
-2007-12-13 15:54 hoffman
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmMakefileTargetGenerator.cxx, cmake.cxx, cmake.h: ENH: fix for
- bug 6102, allow users to change the compiler
-
-2007-12-13 15:42 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: STYLE: fix indent
-
-2007-12-13 15:41 hoffman
-
- * Source/cmCreateTestSourceList.h: ENH: fix docs
-
-2007-12-13 15:11 hoffman
-
- * Source/cmakemain.cxx: ENH: fix docs
-
-2007-12-13 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-12 13:25 clinton
-
- * Source/QtDialog/CMakeSetupDialog.cxx: BUG: Fix logic to accept
- drop events.
-
-2007-12-12 07:26 hoffman
-
- * Modules/FindPerlLibs.cmake: BUG: Fix bug 6106 FindPerlLibs.cmake
- missing escaped $
-
-2007-12-12 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-11 22:28 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/FindJNI.cmake,
- Modules/FindPerlLibs.cmake,
- Modules/InstallRequiredSystemLibraries.cmake,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h,
- Source/cmTryCompileCommand.cxx: ENH: changes for RC5
-
-2007-12-11 12:57 clinton
-
- * Modules/FindQt4.cmake: ENH: Correctly find UiTools library on
- Mac w/ binary install of Qt. Fixes #4554.
-
-2007-12-11 11:36 king
-
- * Source/kwsys/: CMakeLists.txt, String.c, String.h.in: ENH: Added
- C String utilities to KWSys. Implemented strcasecmp and
- strncasecmp.
-
-2007-12-11 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-10 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-09 19:58 hoffman
-
- * Source/cmLocalVisualStudio7Generator.h: STYLE: fix line len error
-
-2007-12-09 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-08 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-07 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-06 22:38 hoffman
-
- * Tests/COnly/CMakeLists.txt: ENH: change to libs that are not real
-
-2007-12-06 16:43 pppebay
-
- * Source/kwsys/SystemTools.cxx: BUG: fixed an incomplete regexp
-
-2007-12-06 14:07 clinton
-
- * Source/QtDialog/CMakeSetupDialog.cxx: BUG: Prevent mapping of
- Configure to Preferences when Qt merges menu items with the
- standard Mac OS X application menu.
-
-2007-12-06 09:56 hoffman
-
- * Source/cmCoreTryCompile.cxx: ENH: for try compile do not put the
- rules to rebuild the project with cmake inside it. This has
- caused infinite loops of builds in some cases, and it is just a
- waste of time anyway.
-
-2007-12-06 08:40 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h,
- Tests/COnly/CMakeLists.txt: BUG: fix for bug 5455, handle
- nodefaultlib with more than one lib
-
-2007-12-06 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-05 13:13 king
-
- * Source/kwsys/SystemTools.cxx: COMP: Remove reference to vtksys.
- The unmangled kwsys name should be used in this source.
-
-2007-12-05 12:24 pppebay
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH: added
- two functions for URL parsing: 1. an "abridged" version that
- separates protocol from dataglom in an expression with
- the form protocol://dataglom 2. a "full" version that parses
- protocol, username, password, hostname, port, and path in
- a standard URL (all of these variables are optional,
- except for protocol and hostname).
-
-2007-12-05 10:40 hoffman
-
- * CMakeLists.txt: ENH: move up to rc 4
-
-2007-12-05 10:40 hoffman
-
- * ChangeLog.manual, Modules/NSIS.template.in: ENH: move fix for
- nsis to branch
-
-2007-12-05 09:17 hoffman
-
- * Source/cmDependsFortran.cxx: STYLE: fix line len
-
-2007-12-05 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-04 17:14 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Source/cmCTest.cxx,
- Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalVisualStudio8Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx, Source/cmTarget.cxx:
- ENH: merge in fixes from main tree
-
-2007-12-04 17:00 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: remove warning
-
-2007-12-04 16:09 hoffman
-
- * Source/cmDependsFortran.cxx: ENH: do not depend on touch being on
- the system
-
-2007-12-04 16:03 hoffman
-
- * Source/: cmake.cxx, kwsys/SystemTools.cxx,
- kwsys/SystemTools.hxx.in: ENH: add a touch -E command to cmake
-
-2007-12-04 10:43 martink
-
- * Source/: cmFunctionCommand.cxx, cmFunctionCommand.h: COMP: fix
- style and work around old compilers
-
-2007-12-04 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-03 20:44 hoffman
-
- * DartLocal.conf.in: ENH: remove superior dean i, no longer uses
- borland
-
-2007-12-03 13:35 martink
-
- * Source/cmBootstrapCommands.cxx, Source/cmCommands.cxx,
- Source/cmMakefile.cxx, Source/cmMakefile.h, Source/cmake.cxx,
- Tests/CMakeLists.txt: ENH: add functions and raise scope
-
-2007-12-03 12:47 martink
-
- * Source/: cmEndFunctionCommand.cxx, cmEndFunctionCommand.h: ENH:
- add functions
-
-2007-12-03 12:43 martink
-
- * Source/cmFunctionCommand.cxx, Source/cmFunctionCommand.h,
- Source/cmRaiseScopeCommand.cxx, Source/cmRaiseScopeCommand.h,
- Tests/FunctionTest/CMakeLists.txt,
- Tests/FunctionTest/functionTest.c: ENH: add functions and raise
- scope to cmake
-
-2007-12-03 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-02 11:51 hoffman
-
- * DartLocal.conf.in: ENH: fix up some stuff
-
-2007-12-02 09:15 miguelf
-
- * Modules/FindwxWidgets.cmake: STYLE: Clarified usage documentation
- for cmake --help-module FindwxWidgets.
-
-2007-12-02 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-12-01 22:51 miguelf
-
- * Modules/FindwxWidgets.cmake: STYLE: Use LIST(APPEND ...) instead
- of SET(...)
-
-2007-12-01 20:58 miguelf
-
- * Modules/FindwxWidgets.cmake: ENH: Added search entry for the new
- release: wxWidgets-2.8.7.
-
-2007-12-01 20:35 miguelf
-
- * Modules/FindwxWidgets.cmake: ENH: Added support for selecting
- different configurations in UNIX_STYLE: debug/release,
- static/shared, unicode/ansi, and regular/universal.
-
-2007-12-01 19:30 miguelf
-
- * Modules/FindwxWidgets.cmake: ENH: Added macro support for
- compiling xrc resources to cpp code.
-
-2007-12-01 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-11-30 19:11 clinton
-
- * Modules/UseQt4.cmake: ENH: Define QT_NO_DEBUG when building with
- release Qt libs. Fixes #6104.
-
-2007-11-30 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-11-29 10:23 martink
-
- * Source/cmDocumentation.cxx: BUG: fix single module generation
-
-2007-11-29 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-11-28 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-11-27 15:59 hoffman
-
- * Source/cmDocumentationFormatterHTML.cxx: ENH: better output for
- qt assistant
-
-2007-11-27 01:04 clinton
-
- * Source/QtDialog/CMakeSetup.cxx: ENH: Add handling of --help and
- related arguments.
-
-2007-11-27 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-11-26 17:57 alex
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h: STYLE:
- restructure OutputLinkLibraries() a bit, so that new there is a
- function which returns the RPATH, so e.g. the install rpath can
- be queried when the command for the build rpath is created. This
- is a first step for supporting chrpath.
-
- Alex
-
-2007-11-26 13:21 barre
-
- * CMakeLogo.gif: ENH: fancier logo
-
-2007-11-26 10:01 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Fixed computation
- of 'object' name for MACOSX_PACKAGE_LOCATION source files.
-
-2007-11-26 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-11-25 17:11 hoffman
-
- * Tests/CMakeLists.txt: BUG: try to fix configure error on
- dashboard
-
-2007-11-25 08:20 alex
-
- * Modules/FindEXPAT.cmake: BUG: use the correct variable for
- checking the success (#6062)
-
- Alex
-
-2007-11-25 07:45 alex
-
- * Source/: cmExtraCodeBlocksGenerator.cxx,
- cmExtraCodeBlocksGenerator.h: STYLE: move the code for generating
- the XML for one target in a separate function AppendTarget() -add
- "all" target -some syncing with the Eclipse generator
-
- Alex
-
-2007-11-25 07:40 alex
-
- * Source/cmExtraEclipseCDT4Generator.cxx: ENH: add the "clean"
- target don't add *all existing* targets as Eclipse targets, but
- only a subset (the same as for CodeBlocks), e.g. exclude the
- subtargets of Experimental, and also edit_cache, ccmake doesn't
- work from within an IDE
-
- Alex
-
-2007-11-25 07:34 alex
-
- * Source/: cmGlobalGenerator.h, cmGlobalUnixMakefileGenerator3.h:
- ENH: add GetCleanTargetName() which returns "clean" for
- makefiles, so it can be used by the eclipse generator
-
- Alex
-
-2007-11-25 06:21 alex
-
- * Source/cmExtraCodeBlocksGenerator.cxx: ENH: also add the
- experimental, nightly, package_source, preinstall and
- rebuild_cache targets
-
- Alex
-
-2007-11-25 05:26 alex
-
- * Source/cmExtraCodeBlocksGenerator.cxx: STYLE: add some comments
-
- Alex
-
-2007-11-25 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-11-24 03:51 alex
-
- * Source/: cmQTWrapCPPCommand.h, cmQTWrapUICommand.h: STYLE: QT ->
- Qt in the docs
-
- Alex
-
-2007-11-24 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-11-23 20:45 alex
-
- * CMakeLists.txt, Modules/Platform/syllable.cmake,
- Source/kwsys/SystemTools.cxx, Source/kwsys/testDynamicLoader.cxx,
- Tests/CMakeLists.txt, Utilities/cmtar/CMakeLists.txt: ENH: add
- support for the Syllable OS (http://www.syllable.org) major
- issues: -access() doesn't return false for an empty string
- (#ifdefed in cmake) -dlopen() doesn't return 0 on failure
- (#ifdefed in cmake and fixed now in Syllable) -the kwsys and
- Bootstrap tests fail with timeout due to the fact that I'm doing
- all that in qemu, which is quite slow -RPATH is now supported, so
- without modifying the test adapting DLL_PATH in Syllable is
- required for the tests to succeed -the Plugin test fails with an
- undefined reference to example_exe_function() in example_mod_1,
- it seems this isn't supported under Syllable
-
- Alex
-
-2007-11-23 14:53 king
-
- * Source/cmMakefileTargetGenerator.cxx: STYLE: Fixed line-too-long.
-
-2007-11-23 11:30 alex
-
- * Source/cmQTWrapCPPCommand.cxx: STYLE: QT is quicktime, Qt is Qt,
- as pointed out by David Faure
-
- Alex
-
-2007-11-23 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-11-22 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-11-21 17:09 david.cole
-
- * DartLocal.conf.in: STYLE: Updated and alphabetized expected
- builds list. Many new Mac Leopard entries from Rogue -- thanks
- guys!
-
-2007-11-21 15:33 david.cole
-
- * Templates/CMakeLists.txt: BUG: Install the vsmacros file.
-
-2007-11-21 13:37 king
-
- * Source/cmMakefileTargetGenerator.cxx: ENH: Change compiler
- working directory to the local build tree location when compiling
- object files. This simplifies the compiler command line and the
- usage of the <objBase>.s and <objBase>.i targets. It also helps
- fortran compilers put their modules in the correct place.
-
-2007-11-21 12:55 king
-
- * CMakeLists.txt: BUG: Fixed construction of CMake_VERSION_DATE to
- use KWSys DateStamp feature now that cmVersion.cxx is not updated
- nightly anymore.
-
-2007-11-21 10:07 king
-
- * Source/cmCTest.cxx: BUG: Do not require a nightly start time for
- an experimental or continuous test model.
-
-2007-11-21 08:59 king
-
- * Source/cmTarget.cxx: BUG: For imported target directory, do not
- return pointer to freed memory.
-
-2007-11-21 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-11-20 11:18 king
-
- * Source/cmLocalVisualStudio6Generator.cxx: BUG: Need to honor
- HEADER_FILE_ONLY source file property and exclude the source from
- the build.
-
-2007-11-20 11:10 king
-
- * Source/: cmCallVisualStudioMacro.cxx, cmGlobalGenerator.cxx,
- cmGlobalVisualStudio8Generator.cxx,
- cmGlobalVisualStudio9Generator.cxx,
- cmGlobalVisualStudioGenerator.cxx: STYLE: Fixed line-too-long.
- COMP: Fixed warnings about lossy conversions.
-
-2007-11-20 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-11-19 14:27 king
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- Complex/Executable/complex_nobuild.cxx,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/complex_nobuild.cxx,
- ComplexRelativePaths/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/complex_nobuild.cxx: ENH: Adding
- test for using HEADER_FILE_ONLY to avoid building a .cxx file.
-
-2007-11-19 14:27 king
-
- * Source/cmSourceFile.cxx: BUG: Do not force HEADER_FILE_ONLY off
- if the user has already set it on.
-
-2007-11-19 14:22 king
-
- * Source/cmake.cxx: COMP: Do not build VS-specific code when
- generators are not included.
-
-2007-11-19 14:08 clinton
-
- * Source/QtDialog/CMakeLists.txt: ENH: Add install command for
- executable.
-
-2007-11-19 13:45 king
-
- * Source/: cmake.cxx, cmake.h: ENH: Added call to StopBuild VS
- macro when projects fail to regenerate during a build.
-
-2007-11-19 13:44 king
-
- * Source/: cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio8Generator.cxx,
- cmGlobalVisualStudioGenerator.cxx,
- cmGlobalVisualStudioGenerator.h: ENH: Renamed
- cmGlobalVisualStudioGenerator::CallVisualStudioReloadMacro method
- to CallVisualStudioMacro and added arguments to select which
- macro to call and optionally pass the solution file name. Added
- option to call to new StopBuild macro. Updated logic for
- replacing the macro file in user directories when the distributed
- version is newer.
-
-2007-11-19 13:44 king
-
- * Templates/CMakeVSMacros1.vsmacros: ENH: Added StopBuild macro.
-
-2007-11-19 13:42 king
-
- * Source/cmakemain.cxx: BUG: Always return positive integers to the
- OS on error. Windows error encoding is confused by negative
- return values.
-
-2007-11-19 13:42 king
-
- * Source/cmListFileCache.cxx: BUG: ParseFile should return false if
- there was a parse error.
-
-2007-11-19 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-11-18 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-11-17 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-11-16 21:18 clinton
-
- * Source/QtDialog/AddCacheEntry.cxx: ENH: Remove debug printf
-
-2007-11-16 13:54 david.cole
-
- * Source/cmGlobalVisualStudioGenerator.cxx: ENH: Add more
- conditions for attempting to call the new Visual Studio macros.
- Only try to call them if the vsmacros file exists and is
- registered. Count VS instances again after warning about running
- instances. If user closed them in response to the warning, it's
- OK to register the macros now rather than waiting till the next
- CMake generate.
-
-2007-11-16 11:32 hoffman
-
- * Source/CTest/cmCTestCoverageHandler.cxx: ENH: add support for
- CDash bullseye coverage
-
-2007-11-16 11:01 king
-
- * Source/: cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio8Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: BUG: Fix exception handling
- flag translation to be specific to each VS version. This allows
- /EHa to be handled correctly for VS 2003.
-
-2007-11-16 10:40 clinton
-
- * Source/QtDialog/QCMakeCacheView.cxx: ENH: more robust search
- filter.
-
-2007-11-16 07:01 david.cole
-
- * Source/CMakeLists.txt, Source/cmCallVisualStudioMacro.cxx,
- Source/cmCallVisualStudioMacro.h,
- Source/cmGeneratedFileStream.cxx, Source/cmGeneratedFileStream.h,
- Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalVisualStudio8Generator.cxx,
- Source/cmGlobalVisualStudio8Generator.h,
- Source/cmGlobalVisualStudio9Generator.cxx,
- Source/cmGlobalVisualStudio9Generator.h,
- Source/cmGlobalVisualStudioGenerator.cxx,
- Source/cmGlobalVisualStudioGenerator.h,
- Source/cmLocalVisualStudio7Generator.cxx, Source/cmake.cxx,
- Source/kwsys/SystemTools.cxx, Templates/CMakeVSMacros1.vsmacros:
- ENH: Add ability to call Visual Studio macros from CMake. Add a
- CMake Visual Studio macro to reload a solution file automatically
- if CMake makes changes to .sln files or .vcproj files. Add code
- to call the macro automatically for any running Visual Studio
- instances with the .sln file open at the end of the Visual Studio
- Generate call. Only call the macro if some .sln or .vcproj file
- changed during Generate. Also, add handling for REG_EXPAND_SZ
- type to SystemTools::ReadRegistryValue - returned string has
- environment variable references expanded.
-
-2007-11-16 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-11-15 13:14 hoffman
-
- * Modules/Platform/Darwin.cmake: ENH: add support for env var and
- better default for CMAKE_OSX_SYSROOT
-
-2007-11-15 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: STYLE: Nightly Date Stamp
-
-2007-11-14 23:30 clinton
-
- * Source/QtDialog/QCMakeCacheView.cxx: COMP: Fix warning.
-
-2007-11-14 21:17 king
-
- * bootstrap, Source/cmVersion.cxx: ENH: Simplified CMake version
- information using KWSys DateStamp feature. Reduced duplicate
- code in bootstrap script.
-
-2007-11-14 18:08 clinton
-
- * Modules/FindQt4.cmake: ENH: Fix case of windows library names to
- support cross compiling w/ Qt on case sensitive platforms.
-
-2007-11-14 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: daily version number
-
-2007-11-13 23:13 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-11-13 16:25 alex
-
- * Source/QtDialog/CMakeSetupDialog.cxx: ENH: add completer for the
- source and binary dir lineedits
-
- Clinton: do I actually have to create separate models for each
- completer, and a separate completer for each widget, or could the
- models/completers be used for multiple widgets ?
-
- Alex
-
-2007-11-13 12:53 clinton
-
- * Source/QtDialog/QCMakeCacheView.cxx: ENH: single click can start
- editing cache values.
-
-2007-11-13 11:21 martink
-
- * Tests/Tutorial/Step6/CMakeLists.txt: ENH: switch to new install
- commands to match book text
-
-2007-11-13 11:18 clinton
-
- * Source/QtDialog/QCMakeCacheView.cxx: BUG: The search is set to
- apply to all columns, but in Qt 4.2, that breaks the search
- entirely. Search on the first column only when using Qt 4.2.
-
-2007-11-13 11:11 martink
-
- * Tests/Tutorial/: Step3/CMakeLists.txt,
- Step3/MathFunctions/CMakeLists.txt, Step4/CMakeLists.txt,
- Step4/MathFunctions/CMakeLists.txt, Step5/CMakeLists.txt,
- Step5/MathFunctions/CMakeLists.txt, Step6/CMakeLists.txt,
- Step6/MathFunctions/CMakeLists.txt, Step7/CMakeLists.txt,
- Step7/MathFunctions/CMakeLists.txt: ENH: switch to new install
- commands to match book text
-
-2007-11-13 00:33 clinton
-
- * Source/QtDialog/: CMakeSetup.cxx, CMakeSetupDialog.cxx: ENH:
- support specifying build or source directory at command line.
-
-2007-11-13 00:17 clinton
-
- * Source/QtDialog/: QCMakeCacheView.cxx, QCMakeCacheView.h: ENH:
- Allow clicking anywhere in field to toggle check boxes.
-
-2007-11-13 00:01 king
-
- * Source/kwsys/kwsysDateStamp.cmake: daily version number
-
-2007-11-12 23:59 clinton
-
- * Source/QtDialog/: AddCacheEntry.cxx, AddCacheEntry.h: STYLE: add
- license.
-
-2007-11-12 23:54 clinton
-
- * Source/QtDialog/: AddCacheEntry.cxx, AddCacheEntry.h,
- AddCacheEntry.ui, CMakeLists.txt, CMakeSetup.qrc,
- CMakeSetupDialog.cxx, CMakeSetupDialog.h, CMakeSetupDialog.ui,
- Plus16.png, QCMake.cxx, QCMakeCacheView.cxx, QCMakeCacheView.h:
- ENH: Add ability to add cache entries (even before first
- configure).
-
-2007-11-12 23:03 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-11-12 22:36 hoffman
-
- * Source/cmGlobalGenerator.cxx: ENH: add f stuff to avoid warnings
-
-2007-11-12 22:33 hoffman
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h: ENH: add
- guess progress for first time configuring a project.
-
-2007-11-12 18:22 king
-
- * Source/kwsys/kwsysDateStamp.cmake: daily version number
-
-2007-11-12 18:22 king
-
- * Source/kwsys/: DateStamp.h.in, kwsysDateStamp.py: ENH: Created
- better names and a more convenient set of version date stamp
- macros.
-
-2007-11-12 18:06 clinton
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, CMakeSetupDialog.ui: ENH:
- Fix layout with Qt 4.2. BUG: Fix help comments to match what
- this GUI does.
-
-2007-11-12 17:51 clinton
-
- * Source/QtDialog/CMakeSetupDialog.cxx: BUG: Fix prompt for
- changes if they haven't been saved.
-
-2007-11-12 17:41 clinton
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, CMakeSetupDialog.h,
- CMakeSetupDialog.ui:
- BUG: Fix pause at shutdown. ENH: Remove interrupt button and
- make configure/generate turn to stop during runs. ENH: Add text
- to remove cache entry button.
-
-2007-11-12 17:38 king
-
- * Source/kwsys/CMakeLists.txt: BUG: Fixed typo in previous commit.
-
-2007-11-12 17:34 king
-
- * Source/kwsys/: CMakeLists.txt, DateStamp.h.in,
- kwsysDateStamp.cmake, kwsysDateStamp.py: ENH: Adding DateStamp
- feature to KWSys. This provides a header file giving
- preprocessor access to a dated version. The 'datestamp' will be
- updated automatically every day by a script.
-
-2007-11-12 16:58 king
-
- * Source/cmake.cxx: BUG: Fix messages for time stamp file
- recreation.
-
-2007-11-12 15:42 king
-
- * Source/: cmGlobalVisualStudio8Generator.cxx,
- cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h: BUG: Converted per-vcproj
- timestamp to a single directory-level CMakeFiles/generate.stamp
- file shared by all targets in each directory. This avoids having
- all targets overwrite each others timestamp check rules and
- instead has one single rule.
-
-2007-11-12 13:54 clinton
-
- * Source/QtDialog/: CMakeLists.txt, CMakeSetupDialog.ui: ENH:
- Allow build with Qt 4.2.
-
- 4.3 dependence fell out when errors go to output
- window instead of message box blocking cmake thread.
-
-2007-11-12 13:52 miguelf
-
- * Modules/FindwxWidgets.cmake: BUG: Fix to support arch and
- isysroot compilation options on MAC (Bug 5007).
-
-2007-11-12 12:04 martink
-
- * Source/cmCPluginAPI.cxx: BUG: better setup of properties for
- loaded commands
-
-2007-11-11 23:05 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-11-10 23:11 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-11-10 17:31 king
-
- * Tests/Wrapping/: CMakeLists.txt, fakefluid.cxx: BUG: Fixed fake
- generation of files to behave more like fluid.
-
-2007-11-10 11:36 clinton
-
- * Source/QtDialog/: CMakeSetup.qrc, CMakeSetupDialog.cxx,
- CMakeSetupDialog.h, CMakeSetupDialog.ui, Delete16.png,
- QCMakeCacheView.cxx, QCMakeCacheView.h:
- ENH: Re-arrange UI a bit. BUG: Properly update when values
- that changed since the last configure.
-
-2007-11-10 08:15 king
-
- * Source/: cmGlobalVisualStudio8Generator.cxx,
- cmLocalVisualStudio7Generator.cxx, cmake.cxx, cmake.h: ENH: Allow
- VS 7 project Rebuild and Solution Rebuild to work without
- re-running CMake for every project during the rebuild.
-
-2007-11-10 08:14 king
-
- * Source/cmDocumentVariables.cxx: STYLE: Fixed line-too-long for
- undocumented variable entries.
-
-2007-11-10 06:54 david.cole
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: BUG: Need extra regex to parse
- sw_vers output on Mac OSX 10.2 (and presumably earlier) to avoid
- running PackageMaker during the SimpleInstall* tests. See comment
- in CMake/Tests/SimpleInstall/CMakeLists.txt for more info.
-
-2007-11-09 23:16 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-11-09 15:18 clinton
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, CMakeSetupDialog.h,
- QCMake.cxx, QCMake.h, QCMakeCacheView.cxx, QCMakeCacheView.h:
- BUG: Don't prompt for unsaved changes if no changes were made.
- ENH: Error messages go to output window instead of message
- boxes.
-
-2007-11-09 15:08 king
-
- * Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Templates/CMakeWindowsSystemConfig.cmake: ENH: Removed dependency
- on Templates/CMakeWindowsSystemConfig.cmake which is no longer
- used. Also removed the file itself.
-
-2007-11-09 12:18 hoffman
-
- * Modules/InstallRequiredSystemLibraries.cmake: ENH: change name
-
-2007-11-09 12:05 king
-
- * Source/: cmGlobalVisualStudio8Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: ENH: Converted vcproj file
- generation to use cmGeneratedFileStream for atomic replacement.
- Replaced the vcproj.cmake copy of the file with a simple
- vcproj.stamp timestamp file to preserve previous
- rerun-without-reload behavior.
-
-2007-11-09 01:14 clinton
-
- * Source/QtDialog/QCMakeCacheView.cxx: ENH: Add completion to
- editor for files and file paths.
-
-2007-11-08 23:03 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-11-08 20:37 hoffman
-
- * Modules/InstallRequiredSystemLibraries.cmake: ENH: add ability to
- use your own install directories
-
-2007-11-08 16:47 clinton
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, QCMake.cxx: BUG: Don't
- enable generate if configure completed with errors. ENH: Allow
- build w/ Qt configured with no STL support.
-
-2007-11-08 15:54 david.cole
-
- * Source/QtDialog/CMakeSetup.ico, Utilities/Release/CMakeLogo.ico:
- ENH: Put black outline around all resolutions of the new ico
- files. Looks better on a dark background than the lighter
- outline...
-
-2007-11-08 14:31 hoffman
-
- * Modules/Platform/Darwin.cmake: ENH: fix bug in default arch, it
- was using the environment variable which is not a default
-
-2007-11-08 13:03 hoffman
-
- * Source/CTest/cmCTestTestHandler.cxx: BUG: try to fix crash
-
-2007-11-08 12:27 clinton
-
- * Modules/FindQt4.cmake: BUG: handle qmake returning multiple
- paths for mkspecs. Fixes #5935
-
-2007-11-08 10:56 clinton
-
- * Modules/FindQt4.cmake: ENH: Add support for static Qt 4.3
- builds.
-
-2007-11-08 10:38 david.cole
-
- * Tests/: CMakeLists.txt, Tutorial/Step6/CMakeLists.txt,
- Tutorial/Step6/License.txt, Tutorial/Step6/TutorialConfig.h.in,
- Tutorial/Step6/tutorial.cxx,
- Tutorial/Step6/MathFunctions/CMakeLists.txt,
- Tutorial/Step6/MathFunctions/MakeTable.cxx,
- Tutorial/Step6/MathFunctions/MathFunctions.h,
- Tutorial/Step6/MathFunctions/mysqrt.cxx,
- Tutorial/Step7/CMakeLists.txt, Tutorial/Step7/CTestConfig.cmake,
- Tutorial/Step7/License.txt, Tutorial/Step7/TutorialConfig.h.in,
- Tutorial/Step7/build1.cmake, Tutorial/Step7/build2.cmake,
- Tutorial/Step7/tutorial.cxx,
- Tutorial/Step7/MathFunctions/CMakeLists.txt,
- Tutorial/Step7/MathFunctions/MakeTable.cxx,
- Tutorial/Step7/MathFunctions/MathFunctions.h,
- Tutorial/Step7/MathFunctions/mysqrt.cxx: ENH: Add new Tutorial
- steps. Diff between Step5 and Step6 shows how to add a cpack
- driven installer to your project. Diff between Step6 and Step7
- shows how to add ctest dashboard scripting capability.
-
-2007-11-08 10:22 clinton
-
- * Source/QtDialog/QCMakeCacheView.cxx: COMP: Fix warnings.
-
-2007-11-08 10:17 clinton
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, CMakeSetupDialog.ui,
- QCMake.cxx, QCMakeCacheView.cxx, QCMakeCacheView.h:
- ENH: add context menu for deleting, ignoring, and getting help
- for cache entries. ENH: add delete cache button ENH: add
- information string above configure/generate buttons ENH: change
- search to search both columns, and from regex to plain string
- search ENH: add buddy info in cache entry view, so double
- clicking in the left column starts editing the associated
- value. BUG: fix file path editor so it goes away when focus is
- lost
-
-2007-11-08 09:09 david.cole
-
- * Modules/Platform/Darwin.cmake: BUG: Do not us the
- search_paths_first flag on older Mac OSX (10.2 and earlier)
- systems.
-
-2007-11-07 23:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-11-07 17:43 hoffman
-
- * Utilities/Release/vogon_release.cmake: ENH: add mt to vogon
- release
-
-2007-11-07 14:35 hoffman
-
- * Utilities/cmcurl/CMakeLists.txt: ENH: remove memdebug.c from list
-
-2007-11-07 13:11 hoffman
-
- * CMakeCPack.cmake, CMakeCPackOptions.cmake.in,
- Source/CPack/cmCPackNSISGenerator.cxx: ENH: change
- CPACK_CREATE_DESKTOP_LINKS to something that can handle spaces in
- the name of the exectuable
-
-2007-11-07 11:31 clinton
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, CMakeSetupDialog.h,
- CMakeSetupDialog.ui:
- ENH: remove status bar and move interrupt/progress next to
- configure/generate.
-
-2007-11-07 10:09 clinton
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, CMakeSetupDialog.h,
- CMakeSetupDialog.ui, QCMakeCacheView.cxx, QCMakeCacheView.h:
- BUG: Fix behavior of
- CMakeSetupDialog::set{Binary|Source}Directory so they work
- right when called externally. Disable the generate button
- when one hits configure again. ENH: Some UI tweaks for spacing.
- Allow viewing cache values while configure/generate (but
- not edit).
-
-2007-11-07 09:12 king
-
- * Source/CTest/cmCTestSubmitHandler.cxx: COMP: Fix check for
- file-too-big to avoid warnings.
-
-2007-11-07 08:59 king
-
- * Source/kwsys/SystemTools.cxx: COMP: Fix warning when gcount
- stream method does not really return std::streamsize.
-
-2007-11-06 23:00 clinton
-
- * Source/QtDialog/: CMakeLists.txt, CMakeSetup.icns, QCMake.cxx:
- ENH: For Mac OSX -- add app icon, and implement find of cmake
- executable.
-
-2007-11-06 22:55 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-11-06 22:27 clinton
-
- * Source/QtDialog/CMakeSetupDialog.cxx: BUG: disable drag & drop
- while busy.
-
-2007-11-06 21:51 clinton
-
- * Source/QtDialog/CMakeSetupDialog.cxx: BUG: only handle drop
- events if they'll really change something.
-
-2007-11-06 21:27 clinton
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, CMakeSetupDialog.h:
- BUG: Put back read/write of original WhereBuild* settings. ENH:
- Make public a couple functions to support command line args.
- Try removing exit after generate to see if others like it.
- COMP: Fix warnings.
-
-2007-11-06 19:25 clinton
-
- * Source/QtDialog/: CMakeSetup.cxx, CMakeSetupDialog.cxx,
- CMakeSetupDialog.h, CMakeSetupDialog.ui, QCMake.cxx,
- QCMakeCacheView.cxx, QCMakeCacheView.h:
- ENH: Disable menu/buttons when doing configure. Also
- disable generate until configure is done. Save more
- settings (last 10 binary directories, exit after generate,
- last generator) Some UI tweaks for
- better layout. Support drag & drop of
- CMakeLists.txt/CMakeCache.txt files.
-
-2007-11-06 14:16 martink
-
- * Source/: cmDocumentVariables.cxx, cmMakefile.cxx,
- cmPropertyMap.cxx, cmake.cxx, cmake.h: ENH: different way of
- testing properties
-
-2007-11-06 14:14 martink
-
- * CMakeLists.txt, Source/CMakeLists.txt: ENH: move CMAKE_STRICT
- option to the top
-
-2007-11-06 14:11 martink
-
- * Tests/CMakeLists.txt: ENH: add doc test for strict builds
-
-2007-11-06 14:10 martink
-
- * Tests/DocTest/: CMakeLists.txt, DocTest.cxx: ENH: add a etst to
- verify props are documented
-
-2007-11-06 08:28 hoffman
-
- * Source/CPack/: cmCPackGenerator.cxx, cmCPackGenerator.h,
- cpack.cxx: ENH: changne ProcessGenertor to DoPackage
-
-2007-11-06 08:27 hoffman
-
- * Source/CPack/cmCPackDebGenerator.cxx: STYLE: fix line length
- issue
-
-2007-11-06 01:16 clinton
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, CMakeSetupDialog.h,
- CMakeSetupDialog.ui, QCMake.cxx, QCMake.h: ENH: Add menus in
- menu bar. Add reload & delete cache options. Add
- option to quit after generation step (not yet remembered between
- sessions). Add Help -> About Remove Help button (in
- menu now) Remove Cancel button (File -> Exit and the
- Window 'X' button exist)
-
-2007-11-06 00:04 clinton
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, CMakeSetupDialog.ui: ENH:
- clarify label for current generator.
-
-2007-11-06 00:02 clinton
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, CMakeSetupDialog.h,
- CMakeSetupDialog.ui, QCMakeCacheView.cxx: ENH: search is case
- insensitive ENH: put back prompt for generator, and change combo
- to label showing current generator.
-
-2007-11-05 22:32 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-11-05 19:26 clinton
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, CMakeSetupDialog.h,
- CMakeSetupDialog.ui, QCMakeCacheView.cxx, QCMakeCacheView.h:
- ENH: Replace prompt for generator with combobox in UI. ENH:
- Make "Show Advanced" toggle work. ENH: Add regex search
- capabilities. ENH: Read existing registry entries from MFC
- CMakeSetup.exe (will save later).
-
-2007-11-05 18:06 alex
-
- * CMakeLists.txt: COMP: use RPATH is building QtDialog and the Qt
- libs are not in /lib or /usr/lib (same logic as for ccmake)
-
- Alex
-
-2007-11-05 17:44 king
-
- * Source/kwsys/kwsys_ios_iostream.h.in: COMP: Add streamsize and
- streamoff to kwsys_ios namespace for ancient streams.
-
-2007-11-05 16:57 david.cole
-
- * DartLocal.conf.in: STYLE: Trade in expected arrakis dashboards
- for resurrected equivalent ones on dash14.
-
-2007-11-05 16:55 hoffman
-
- * Source/: CMakeLists.txt, CPack/cmCPackDebGenerator.h,
- CPack/cmCPackGenerator.cxx, CPack/cmCPackGenerator.h,
- CPack/cmCPackGeneratorFactory.cxx,
- CPack/cmCPackGeneratorFactory.h,
- CPack/cmCPackGenericGenerator.cxx,
- CPack/cmCPackGenericGenerator.h, CPack/cmCPackNSISGenerator.h,
- CPack/cmCPackOSXX11Generator.h,
- CPack/cmCPackPackageMakerGenerator.h,
- CPack/cmCPackRPMGenerator.h, CPack/cmCPackTGZGenerator.h,
- CPack/cmCPackZIPGenerator.h, CPack/cpack.cxx: ENH: change name
-
-2007-11-05 16:33 hoffman
-
- * Source/: CMakeLists.txt, CPack/cmCPackGeneratorFactory.cxx,
- CPack/cmCPackGeneratorFactory.h, CPack/cmCPackGenerators.cxx,
- CPack/cmCPackGenerators.h, CPack/cpack.cxx: ENH: change name of
- class
-
-2007-11-05 14:34 king
-
- * Source/cmake.cxx, Source/CPack/cmCPackDebGenerator.cxx,
- Source/CPack/cmCPackNSISGenerator.cxx,
- Source/CPack/cmCPackPackageMakerGenerator.cxx,
- Source/CPack/cmCPackPackageMakerGenerator.h,
- Source/CTest/cmCTestCoverageHandler.cxx,
- Source/CTest/cmCTestSubmitHandler.cxx,
- Source/kwsys/SystemTools.cxx, Utilities/cmcurl/ftp.c: COMP: Fix
- warnings on 64-bit Mac OS X build. Patch from issue #3697.
-
-2007-11-05 13:20 clinton
-
- * Source/QtDialog/: CMakeSetup.cxx, CMakeSetupDialog.cxx,
- CMakeSetupDialog.h, QCMake.cxx, QCMake.h, QCMakeCacheView.cxx,
- QCMakeCacheView.h:
- ENH: Prompt user for generator when there is none. Many
- minor improvements, bug fixes, and style fixes.
-
-2007-11-04 22:00 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-11-04 01:20 miguelf
-
- * Modules/FindwxWidgets.cmake: BUG: Fixed error related to missing
- quotes around variable.
-
-2007-11-03 23:04 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-11-03 19:48 clinton
-
- * Source/QtDialog/: CMakeSetupDialog.cxx, CMakeSetupDialog.h,
- CMakeSetupDialog.ui, QCMake.cxx, QCMake.h, QCMakeCacheView.cxx,
- QCMakeCacheView.h:
- ENH: Allow working with empty build directories. Make
- output window a bit smaller compared to cache view. Prompt
- on X'ing window as well as hitting cancel. Color new cache
- values red, and put them first.
-
-2007-11-03 13:28 clinton
-
- * Source/QtDialog/QCMakeCacheView.cxx: COMP: Fix some compile
- warnings. STYLE: Make style a bit more consistent.
-
-2007-11-03 12:50 hoffman
-
- * Source/QtDialog/: CMakeSetup.cxx, CMakeSetupDialog.h, QCMake.h,
- QCMakeCacheView.h: ENH: remove qt warnings from qt with MS
- compiler
-
-2007-11-03 12:07 hoffman
-
- * Source/QtDialog/QCMakeCacheView.h: ENH: fix compile error on
- windows
-
-2007-11-03 10:30 clinton
-
- * Source/QtDialog/: CMakeLists.txt, CMakeSetup.cxx, CMakeSetup.ico,
- CMakeSetup.png, CMakeSetup.qrc, CMakeSetup.rc,
- CMakeSetupDialog.cxx, CMakeSetupDialog.h, CMakeSetupDialog.png,
- CMakeSetupDialog.ui, QCMake.cxx, QCMake.h, QCMakeCacheView.cxx,
- QCMakeCacheView.h:
- ENH: Add interrupt button near progress bar. Implement
- help button. Implement cancel button. Add
- scrollable output window. Replace ON/OFF & combobox
- editors with checkboxes. Tab/backtab in cache table jumps
- between values (not names and values) Add tooltips to show
- help strings. Add application icon and qtmain for Windows.
-
- BUG: Fix save of cache values on configure.
-
-2007-11-02 23:00 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-11-02 14:12 clinton
-
- * Source/QtDialog/CMakeLists.txt: COMP: Fix build on Windows.
-
-2007-11-02 12:03 hoffman
-
- * Source/CMakeLists.txt: ENH: add option for qt dialog
-
-2007-11-02 11:55 clinton
-
- * Source/QtDialog/: CMakeSetup.cxx, CMakeSetupDialog.cxx,
- CMakeSetupDialog.h, QCMake.cxx, QCMake.h, QCMakeCacheView.cxx,
- QCMakeCacheView.h: STYLE: Add license info to code.
-
-2007-11-02 11:50 clinton
-
- * Source/QtDialog/: CMakeLists.txt, CMakeSetup.cxx, CMakeSetup.qrc,
- CMakeSetupDialog.cxx, CMakeSetupDialog.h, CMakeSetupDialog.png,
- CMakeSetupDialog.ui, QCMake.cxx, QCMake.h, QCMakeCacheView.cxx,
- QCMakeCacheView.h: ENH: Beginnings of a Qt UI for CMake.
-
-2007-11-02 10:46 hoffman
-
- * Tests/: CMakeLists.txt, Wrapping/CMakeLists.txt,
- Wrapping/qtnoqtmain.cxx: ENH: remove findqt3 from cmake's
- cmakelist files
-
-2007-11-01 22:50 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-11-01 16:21 hoffman
-
- * Source/QtDialog/README: ENH: create a directory for qt interface
- to cmake
-
-2007-11-01 09:52 hoffman
-
- * Modules/CPackRPM.cmake: ENH: fix for RPM generator from Eric
-
-2007-11-01 08:36 david.cole
-
- * Utilities/Release/CMakeLogo.ico: ENH: Add more resolutions for
- CMake icons to avoid that bloated chunky blown up icon look...
-
-2007-10-31 22:48 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-31 13:57 martink
-
- * Source/cmDocumentVariables.cxx: ENH: minor fix
-
-2007-10-31 13:38 martink
-
- * Source/cmDocumentVariables.cxx: ENH: added documentation for more
- variables
-
-2007-10-31 12:55 hoffman
-
- * CMakeCPack.cmake, CMakeCPackOptions.cmake.in,
- CPackConfig.cmake.in, CPackSourceConfig.cmake.in,
- Source/CPack/cmCPackGenericGenerator.cxx: ENH: add
- CPACK_PROJECT_CONFIG_FILE option to CPack
-
-2007-10-31 10:49 hoffman
-
- * Utilities/Release/CMakeLogo.ico: ENH: add icon for installer
-
-2007-10-31 09:39 king
-
- * Source/kwsys/SystemTools.cxx: BUG: Merge changes from 1.205-1.207
- from trunk to gccxml-gcc42 branch.
-
-2007-10-31 09:37 king
-
- * Source/kwsys/SystemTools.hxx.in: STYLE: Fix documentation (merge
- from trunk)
-
-2007-10-31 09:03 hoffman
-
- * Source/CPack/cmCPackNSISGenerator.cxx: ENH: fix line length
-
-2007-10-31 08:50 david.cole
-
- * Modules/CPack.cmake,
- Source/CPack/cmCPackCygwinBinaryGenerator.cxx,
- Source/CPack/cmCPackCygwinBinaryGenerator.h,
- Source/CPack/cmCPackCygwinSourceGenerator.cxx,
- Source/CPack/cmCPackCygwinSourceGenerator.h,
- Source/CPack/cmCPackDebGenerator.cxx,
- Source/CPack/cmCPackDebGenerator.h,
- Source/CPack/cmCPackGenericGenerator.cxx,
- Source/CPack/cmCPackGenericGenerator.h,
- Source/CPack/cmCPackOSXX11Generator.cxx,
- Source/CPack/cmCPackOSXX11Generator.h,
- Source/CPack/cmCPackPackageMakerGenerator.cxx,
- Source/CPack/cmCPackPackageMakerGenerator.h,
- Source/CPack/cmCPackRPMGenerator.cxx,
- Source/CPack/cmCPackRPMGenerator.h: ENH: Add CPACK_SET_DESTDIR
- handling to enable packaging of installed files in absolute
- locations. With this setting on, cpack will set the DESTDIR env
- var when building the package so that files end up in their
- intended locations. Default behavior is not to set DESTDIR for
- backwards compatibility. Helps address issue #4993 and issue
- #5257. Also, remove unused CPACK_USE_DESTDIR variable. ENH: Add
- variable CPACK_PACKAGING_INSTALL_PREFIX to allow overriding the
- CPack GetPackagingInstallPrefix from a project's CMakeLists file
- if necessary. Could be used to remove the annoying /usr prefix
- still used by default in the Mac PackageMaker generator.
-
-2007-10-30 23:04 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-30 23:02 hoffman
-
- * CMakeCPack.cmake, CPackConfig.cmake.in,
- CPackSourceConfig.cmake.in, Modules/CPack.cmake,
- Source/CPack/cmCPackNSISGenerator.cxx,
- Source/CPack/cmCPackRPMGenerator.cxx: ENH: cpack changes, remove
- the escape variable stuff as it is not needed if you provide a
- config file for cpack
-
-2007-10-30 11:03 martink
-
- * Source/cmTarget.cxx: BUG: fix undefined property FRAMEWORK
-
-2007-10-30 10:57 martink
-
- * Source/cmake.cxx: BUG: fix bad set property code in cmake
-
-2007-10-30 10:16 hoffman
-
- * Modules/CPackRPM.cmake: ENH: use cpack generic variable if rpm
- one is not set
-
-2007-10-30 10:16 hoffman
-
- * CMakeCPack.cmake: ENH: fix for cygwin package
-
-2007-10-29 22:58 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-29 21:10 hoffman
-
- * Templates/cygwin-package.sh.in: ENH: add package script for cmake
- project
-
-2007-10-29 12:21 hoffman
-
- * Source/: cmBootstrapCommands.cxx, cmCommands.cxx: ENH: move list
- command to bootstrap commands
-
-2007-10-29 08:11 hoffman
-
- * CMakeCPack.cmake, Modules/CPack.cmake, Modules/NSIS.template.in,
- Source/CPack/cmCPackNSISGenerator.cxx: ENH: add ability to set
- installer icons, links to web pages, nsis code in the icon
- section of the template, and ability to escape variables
- correctly
-
-2007-10-28 22:58 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-27 23:05 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-26 23:11 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-26 22:57 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Source/cmSystemTools.cxx,
- Source/CPack/cmCPackTGZGenerator.cxx,
- Source/CPack/cmCPackTarCompressGenerator.cxx,
- Source/kwsys/SystemTools.cxx: ENH: move changes from head
-
-2007-10-26 13:36 alex
-
- * Source/cmFindBase.cxx: STYLE: change wording of FIND_XXX() docs
- to be more correct
-
- Alex
-
-2007-10-26 12:13 seanmcbride
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: STYLE: fixed
- misspellings of Mac OS X
-
-2007-10-26 09:55 alex
-
- * Source/cmFindBase.cxx, Source/cmFindBase.h,
- Source/cmFindLibraryCommand.cxx, Source/cmFindPathCommand.cxx,
- Source/cmFindProgramCommand.cxx,
- Tests/FindPackageTest/CMakeLists.txt,
- Tests/FindPackageTest/include/foo.h: ENH: add support for
- CMAKE_FIND_PREFIX_PATH as discussed with Brad.
- CMAKE_FIND_PREFIX_PATH is both an environment variable and a
- cmake variable, which is a list of base directories where
- FIND_PATH, FIND_FILE, FIND_PROGRAM and FIND_LIBRARY will search
- in the respective subdirectories
-
- Alex
-
-2007-10-25 22:53 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-25 14:03 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Modules/CPack.STGZ_Header.sh.in, Modules/FindKDE3.cmake,
- Modules/FindKDE4.cmake, Modules/FindPythonInterp.cmake,
- Modules/KDE3Macros.cmake, Modules/Platform/DragonFly.cmake,
- Modules/Platform/GNU.cmake, Modules/Platform/NetBSD.cmake,
- Modules/Platform/UnixPaths.cmake,
- Modules/Platform/Windows-cl.cmake,
- Modules/Platform/Windows.cmake,
- Modules/Platform/WindowsPaths.cmake, Source/cmDependsFortran.cxx,
- Source/cmFileCommand.h, Source/cmFindPackageCommand.h,
- Source/cmIfCommand.cxx, Source/cmIfCommand.h,
- Source/cmInstallCommand.cxx, Source/cmInstallCommand.h,
- Source/cmMakefile.cxx, Source/cmRemoveDefinitionsCommand.h,
- Source/cmSystemTools.cxx, Source/cmTryRunCommand.h,
- Source/cmake.cxx, Source/cmakemain.cxx,
- Source/CPack/cmCPackTGZGenerator.cxx,
- Source/CPack/cmCPackTarCompressGenerator.cxx,
- Source/CPack/cpack.cxx: ENH: merge in stuff from head
-
-2007-10-25 13:29 king
-
- * Source/kwsys/SystemTools.cxx: BUG: Fix bug#5590. When converting
- a relative path between two full paths on different windows drive
- letters do not create a ../../d:/foo/bar path and just return the
- full path to the destination.
-
-2007-10-25 13:26 alex
-
- * Modules/CPackDeb.cmake, Source/CPack/cmCPackDebGenerator.cxx:
- BUG: rename DEBIAN_PACKAGE_* variables to CPACK_DEBIAN_PACKAGE_*
- variables to make them actually work
-
- Alex
-
-2007-10-24 23:20 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-24 14:43 martink
-
- * Source/: cmGetPropertyCommand.cxx, cmGetPropertyCommand.h,
- cmPropertyDefinition.h, cmake.cxx, cmake.h: ENH: add ability to
- get documentaiton of a property from a script
-
-2007-10-24 11:36 martink
-
- * Source/cmDocumentation.cxx, Source/cmDocumentation.h,
- Source/cmDocumentationFormatter.h,
- Source/cmDocumentationFormatterHTML.cxx,
- Source/cmDocumentationSection.h, Source/cmakemain.cxx,
- Utilities/CMakeLists.txt: ENH: some more cleanup, fixes, and
- patch for HTML output
-
-2007-10-23 23:07 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-23 10:40 martink
-
- * Source/: cmMakefile.cxx, cmPropertyDefinitionMap.cxx: COMP: fix
- for when STRICT is defined, and fix for props that have no docs
-
-2007-10-23 10:08 martink
-
- * Source/cmDocumentVariables.cxx: STYLE: fix some long lines
-
-2007-10-23 10:07 martink
-
- * Source/cmDocumentation.cxx: COMP: fix a problem with a shadowed
- var
-
-2007-10-22 23:10 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-22 17:16 hoffman
-
- * Modules/CPack.cmake: ENH: fix bitmap escapes
-
-2007-10-22 16:41 martink
-
- * Source/: cmDocumentation.cxx, cmakemain.cxx: COMP: fix some
- warnings and add some doc strings back in
-
-2007-10-22 15:33 martink
-
- * Source/: cmDocumentation.cxx, cmDocumentation.h,
- cmDocumentationSection.cxx, cmDocumentationSection.h,
- cmakemain.cxx: COMP: fix some warnings and add some doc strings
- back in
-
-2007-10-22 14:01 hoffman
-
- * Modules/Platform/Darwin.cmake, Source/cmLocalGenerator.cxx: ENH:
- fix spelling error
-
-2007-10-22 13:28 martink
-
- * Source/: cmGlobalKdevelopGenerator.cxx,
- cmGlobalXCodeGenerator.cxx: ENH: change to make the documentation
- class more generic, about halfway there, also provides secitons
- for Variables now
-
-2007-10-22 12:48 martink
-
- * Source/: CMakeLists.txt, cmDocumentVariables.cxx,
- cmDocumentation.cxx, cmDocumentation.h,
- cmDocumentationFormatter.h, cmDocumentationFormatterHTML.cxx,
- cmDocumentationFormatterHTML.h, cmDocumentationFormatterMan.cxx,
- cmDocumentationFormatterMan.h, cmDocumentationFormatterText.cxx,
- cmDocumentationFormatterText.h,
- cmDocumentationFormatterUsage.cxx,
- cmDocumentationFormatterUsage.h, cmDumpDocumentation.cxx,
- cmExtraCodeBlocksGenerator.cxx, cmExtraEclipseCDT4Generator.cxx,
- cmGlobalBorlandMakefileGenerator.cxx, cmGlobalGenerator.cxx,
- cmGlobalMSYSMakefileGenerator.cxx,
- cmGlobalMinGWMakefileGenerator.cxx,
- cmGlobalNMakeMakefileGenerator.cxx,
- cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio8Generator.cxx,
- cmGlobalVisualStudio8Win64Generator.cxx,
- cmGlobalVisualStudio9Generator.cxx,
- cmGlobalWatcomWMakeGenerator.cxx, cmMakefile.cxx,
- cmPropertyDefinition.cxx, cmPropertyDefinition.h,
- cmPropertyDefinitionMap.cxx, cmPropertyDefinitionMap.h,
- cmStandardIncludes.h, cmake.cxx, cmake.h, cmakemain.cxx,
- ctest.cxx, CPack/cpack.cxx, CursesDialog/ccmake.cxx,
- cmDocumentationSection.cxx, cmDocumentationSection.h: ENH: change
- to make the documentation class more generic, about halfway
- there, also provides secitons for Variables now
-
-2007-10-22 11:40 hoffman
-
- * Modules/: CPack.cmake, NSIS.template.in: ENH: allow
- CPACK_PACKAGE_ICON to be not set
-
-2007-10-22 10:17 hoffman
-
- * Modules/Platform/Darwin.cmake: ENH: try to fix boostrap on 10.5
-
-2007-10-21 23:39 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-20 23:04 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-19 23:03 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-19 22:24 hoffman
-
- * Modules/Platform/Darwin.cmake, Source/cmLocalGenerator.cxx: ENH:
- do not always add -arch flags
-
-2007-10-19 12:03 hoffman
-
- * Source/CPack/cmCPackNSISGenerator.cxx: ENH: fix line length error
-
-2007-10-18 22:59 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-18 11:11 king
-
- * Source/kwsys/SystemTools.cxx: BUG: Merge bug fixes from HEAD.
-
-2007-10-18 09:40 hoffman
-
- * CMakeCPack.cmake, Modules/NSIS.template.in,
- Source/CPack/cmCPackNSISGenerator.cxx,
- Source/CPack/cmCPackNSISGenerator.h: ENH: add ability to create
- links on the start menu
-
-2007-10-18 09:39 hoffman
-
- * bootstrap: ENH: add new file
-
-2007-10-18 09:38 hoffman
-
- * Source/: cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx: ENH: do not remove
- executables and dll's before linking them so that incremental
- links work, incremental links are still broken for vs 2005 and
- greater because of the manifest stuff
-
-2007-10-18 09:10 hoffman
-
- * Source/: CMakeLists.txt, cmDocumentVariables.cxx,
- cmDocumentVariables.h, cmake.cxx: ENH: add docs for variables
-
-2007-10-17 22:55 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-17 09:38 miguelf
-
- * Modules/FindwxWidgets.cmake: ENH: Added support for finding
- wxWidgets-2.9. Thanks to Joshua Jensen and Steven.
-
-2007-10-16 22:51 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-16 14:27 martink
-
- * Source/: CMakeLists.txt, cmConfigure.cmake.h.in,
- cmPropertyMap.cxx: ENH: added CMAKE_STRICT option for var and
- property checking
-
-2007-10-16 10:19 king
-
- * Source/: cmDependsFortran.cxx, cmInstallCommand.cxx: STYLE: Fixed
- line-too-long.
-
-2007-10-15 22:43 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-15 17:38 king
-
- * Source/cmExecuteProcessCommand.cxx: BUG: Work around bug when
- calling insert on an empty vector of char on midworld. Should
- eliminate the sporadic failure of EXECUTE_PROCESS during the
- SimpleInstall-Stage2 test. (david.cole from Brad's checkout on
- midworld)
-
-2007-10-15 14:50 martink
-
- * Modules/TestForSSTREAM.cmake, Source/cmForEachCommand.h,
- Source/cmWhileCommand.h, Source/cmake.cxx: ENH: minor doc
- cleanups and an example of documenting a variable
-
-2007-10-15 07:08 david.cole
-
- * Source/cmInstallCommand.cxx, Source/cmInstallScriptGenerator.cxx,
- Source/cmInstallScriptGenerator.h, Source/cmLocalGenerator.cxx,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstall/InstallScript3.cmake,
- Tests/SimpleInstall/InstallScript4.cmake,
- Tests/SimpleInstallS2/CMakeLists.txt,
- Tests/SimpleInstallS2/InstallScript3.cmake,
- Tests/SimpleInstallS2/InstallScript4.cmake: BUG: Fix #5868 - add
- COMPONENT handling to the SCRIPT and CODE signatures of the
- INSTALL command.
-
-2007-10-14 22:40 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-14 08:15 alex
-
- * Source/cmExportCommand.cxx:
- BUG: fix #5806, wrong quotes used in the exported file
-
- Alex
-
-2007-10-13 22:48 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-12 22:45 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-12 21:30 miguelf
-
- * Modules/FindwxWidgets.cmake: BUG: Added support for the AUI
- library module (bug 4338). Also applied some STYLE changes
- including: deprecation of wxWidgets_USE_LIBS in favor of using
- standard FIND_PACKAGE COMPONENTS, removed some CMake 2.4.2
- compatibility patches, use of execute_process instead of
- exec_program, etc.
-
-2007-10-12 19:33 hoffman
-
- * Modules/CPackRPM.cmake: BUG: fix for bug 5878
-
-2007-10-12 11:43 david.cole
-
- * Source/cmTarget.cxx: BUG: Fix the dashboards! Put it back the way
- it was so it always creates the target directory at configure
- time. Figure out how to avoid it for the framework case on the
- Mac/Xcode later...
-
-2007-10-12 11:34 hoffman
-
- * Modules/FindFLTK2.cmake: ENH: add from bug 0004219
-
-2007-10-12 11:00 hoffman
-
- * Modules/FindASPELL.cmake: BUG: fix for bug 0005871
-
-2007-10-12 10:58 hoffman
-
- * Source/cmLocalGenerator.cxx: BUG: fix for bug 0003618 , allow one
- arch in OSX_ARCHS to work
-
-2007-10-12 09:58 hoffman
-
- * Source/kwsys/SystemTools.cxx: BUG: fix for bug 0005767 hang for
- replace string with empty
-
-2007-10-12 09:51 king
-
- * Source/cmDependsFortran.cxx: ENH: When an object file requires a
- module add the file-level dependency between the object file and
- the module timestamp file. Create a dummy timestamp file in case
- nothing in the project actually creates the module. See
- bug#5809.
-
-2007-10-12 09:32 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Dependency
- scanners should have local generators set always.
-
-2007-10-11 22:45 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-10 22:32 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-10 17:47 alin.elena
-
- * Modules/: CheckFortranFunctionExists.cmake, FindBLAS.cmake,
- FindLAPACK.cmake, Platform/Linux-ifort.cmake:
- ENH: FindBLAS.cmake and FindLAPACK.cmake modules added. They
- locate various implementations of blas and lapack libraries.
- CheckFortranFunctionExists.cmake provides a test function to
- check if the library is usabale. I have also changed the -KPIC
- flag to -fPIC in Linux-ifort.cmake.
-
-2007-10-10 11:47 martink
-
- * Source/cmAddCustomCommandCommand.h,
- Source/cmAddCustomTargetCommand.h,
- Source/cmAddDefinitionsCommand.h,
- Source/cmAddDependenciesCommand.h,
- Source/cmAddExecutableCommand.h, Source/cmAddLibraryCommand.h,
- Source/cmAddSubDirectoryCommand.h, Source/cmAddTestCommand.h,
- Source/cmAuxSourceDirectoryCommand.h, Source/cmBuildCommand.h,
- Source/cmBuildNameCommand.h, Source/cmCMakeMinimumRequired.h,
- Source/cmConfigureFileCommand.h, Source/cmCreateTestSourceList.h,
- Source/cmDefinePropertyCommand.h, Source/cmDocumentation.cxx,
- Source/cmElseCommand.h, Source/cmElseIfCommand.h,
- Source/cmEnableLanguageCommand.h,
- Source/cmEnableTestingCommand.h, Source/cmEndForEachCommand.h,
- Source/cmEndIfCommand.h, Source/cmEndMacroCommand.h,
- Source/cmEndWhileCommand.h, Source/cmExecProgramCommand.h,
- Source/cmExecuteProcessCommand.h, Source/cmExportCommand.h,
- Source/cmExportLibraryDependencies.h,
- Source/cmFLTKWrapUICommand.h, Source/cmFileCommand.h,
- Source/cmFindFileCommand.cxx, Source/cmFindFileCommand.h,
- Source/cmFindLibraryCommand.cxx, Source/cmFindLibraryCommand.h,
- Source/cmFindPackageCommand.h, Source/cmFindPathCommand.cxx,
- Source/cmFindPathCommand.h, Source/cmFindProgramCommand.cxx,
- Source/cmFindProgramCommand.h, Source/cmForEachCommand.h,
- Source/cmGetCMakePropertyCommand.h,
- Source/cmGetDirectoryPropertyCommand.h,
- Source/cmGetFilenameComponentCommand.h,
- Source/cmGetPropertyCommand.h,
- Source/cmGetSourceFilePropertyCommand.h,
- Source/cmGetTargetPropertyCommand.h,
- Source/cmGetTestPropertyCommand.h, Source/cmIfCommand.h,
- Source/cmIncludeCommand.h, Source/cmIncludeDirectoryCommand.h,
- Source/cmIncludeExternalMSProjectCommand.h,
- Source/cmIncludeRegularExpressionCommand.h,
- Source/cmInstallCommand.h, Source/cmInstallFilesCommand.h,
- Source/cmInstallProgramsCommand.h,
- Source/cmInstallTargetsCommand.h,
- Source/cmLinkDirectoriesCommand.h,
- Source/cmLinkLibrariesCommand.h, Source/cmListCommand.h,
- Source/cmLoadCacheCommand.h, Source/cmLoadCommandCommand.h,
- Source/cmMacroCommand.h, Source/cmMakeDirectoryCommand.h,
- Source/cmMarkAsAdvancedCommand.h, Source/cmMathCommand.h,
- Source/cmMessageCommand.h, Source/cmOptionCommand.h,
- Source/cmOutputRequiredFilesCommand.h, Source/cmProjectCommand.h,
- Source/cmQTWrapCPPCommand.h, Source/cmQTWrapUICommand.h,
- Source/cmRemoveCommand.h, Source/cmRemoveDefinitionsCommand.h,
- Source/cmSeparateArgumentsCommand.h, Source/cmSetCommand.h,
- Source/cmSetDirectoryPropertiesCommand.h,
- Source/cmSetPropertiesCommand.h,
- Source/cmSetSourceFilesPropertiesCommand.h,
- Source/cmSetTargetPropertiesCommand.h,
- Source/cmSetTestsPropertiesCommand.h, Source/cmSiteNameCommand.h,
- Source/cmSourceGroupCommand.h, Source/cmStringCommand.h,
- Source/cmSubdirCommand.h, Source/cmSubdirDependsCommand.h,
- Source/cmTargetLinkLibrariesCommand.h,
- Source/cmTryCompileCommand.h, Source/cmTryRunCommand.h,
- Source/cmUseMangledMesaCommand.h,
- Source/cmUtilitySourceCommand.h,
- Source/cmVariableRequiresCommand.h,
- Source/cmVariableWatchCommand.h, Source/cmWhileCommand.h,
- Source/cmWriteFileCommand.h,
- Tests/CommandLineTest/CMakeLists.txt: ENH: make commands lower
- case by default
-
-2007-10-10 11:06 david.cole
-
- * Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmGlobalXCodeGenerator.cxx, Source/cmInstallCommand.cxx,
- Source/cmInstallTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.cxx,
- Source/cmOrderLinkDirectories.cxx, Source/cmTarget.cxx,
- Source/cmTarget.h, Tests/CMakeLists.txt,
- Tests/Framework/CMakeLists.txt: ENH: Finish up the Framework
- creation code restructuring. Frameworks build and install now.
- More work needed on the packaging step. See Tests/Framework for
- example use.
-
-2007-10-10 09:09 king
-
- * Tests/Fortran/: CMakeLists.txt, test_use_in_comment_fixedform.f,
- test_use_in_comment_freeform.f90, in_interface/main.f90,
- in_interface/module.f90: ENH: Added test for 'use' keyword in a
- comment. Patch from Maik Beckmann. See bug#5809.
-
-2007-10-10 09:07 king
-
- * Source/cmDependsFortran.cxx: BUG: Fix in-interface mode. Patch
- from Maik Beckmann. See bug#5809.
-
-2007-10-09 22:36 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-09 15:20 barre
-
- * Source/kwsys/SystemTools.cxx: ENH: bad bug bad
-
-2007-10-09 14:35 martink
-
- * Source/: cmDocumentation.cxx, cmDocumentationFormatterHTML.cxx,
- cmDocumentationFormatterMan.cxx,
- cmDocumentationFormatterText.cxx,
- cmDocumentationFormatterUsage.cxx, cmDumpDocumentation.cxx,
- cmPropertyDefinition.cxx, cmPropertyDefinitionMap.cxx,
- cmStandardIncludes.h, cmake.cxx, cmake.h, cmakemain.cxx,
- ctest.cxx, CPack/cpack.cxx: BUG: revert doc changes since VS7
- cannot compile them, will implement them in a different manner
-
-2007-10-09 09:55 martink
-
- * Source/: cmDocumentation.cxx, cmDocumentationFormatterHTML.cxx,
- cmDocumentationFormatterMan.cxx,
- cmDocumentationFormatterText.cxx,
- cmDocumentationFormatterUsage.cxx, cmDumpDocumentation.cxx,
- cmPropertyDefinition.cxx, cmPropertyDefinitionMap.cxx,
- cmStandardIncludes.h, cmake.cxx, cmake.h, cmakemain.cxx,
- ctest.cxx, CPack/cpack.cxx: ENH: make documentation entries
- actually store their data
-
-2007-10-08 22:39 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-08 10:05 king
-
- * Source/cmSystemTools.cxx: STYLE: Fixed line-too-long.
-
-2007-10-08 10:03 king
-
- * Source/cmSystemTools.cxx: COMP: Added inadvertantly removed
- include.
-
-2007-10-07 22:35 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-07 16:22 king
-
- * Source/cmSystemTools.cxx: COMP: Simplified include file logic.
- The windows.h header should be included for all compilers on
- windows.
-
-2007-10-06 22:42 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-05 22:31 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-05 15:51 martink
-
- * Source/cmSystemTools.cxx: COMP: fix to compile on VS 8
-
-2007-10-05 13:15 hoffman
-
- * Modules/Platform/Windows-bcc32.cmake: ENH: add support for
- preprocessed files in borland
-
-2007-10-05 13:14 hoffman
-
- * Utilities/KWStyle/CMakeFiles.txt.in: ENH: add more exclusions for
- kwstyle
-
-2007-10-05 10:03 king
-
- * Source/cmSystemTools.cxx: BUG: Fix call to SetFileTime to set it
- on the proper file.
-
-2007-10-05 10:02 king
-
- * Source/: cmDependsFortranParser.cxx, cmDependsFortranParser.y:
- COMP: Disable some warnings in generated code. Disable
- compilation of unused goto block.
-
-2007-10-05 09:46 king
-
- * Source/: cmFileCommand.cxx, cmSystemTools.cxx, cmSystemTools.h:
- ENH: During file installation treat the source file as a
- dependency of the installed file. Install the file only if the
- destination is older than the source. Set the file times on the
- installed file to match those of the source file. This should
- greatly improve the speed of repeated installations because it
- removes the comparison of file contents. This addresses
- bug#3349.
-
-2007-10-04 22:43 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-04 15:31 hoffman
-
- * Source/: cmDependsFortranParser.cxx, cmDependsFortranParser.y:
- ENH: update .y file with borland fix, and use a table based
- strcasecmp
-
-2007-10-04 14:47 david.cole
-
- * Source/cmDependsFortranParser.cxx: COMP: Get it to compile on
- Borland 5.5, too. Including stl headers here does not work,
- because with Borland 5.5 stl headers pull in windef.h which
- typedefs WORD which is in the fortran tokens list...
-
-2007-10-04 09:49 king
-
- * Source/cmDependsFortranParser.cxx: STYLE: Removed reference to my
- home directory from #line calls.
-
-2007-10-03 22:36 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-03 17:01 king
-
- * Source/: cmDependsFortranParser.cxx, cmDependsFortranParser.y:
- COMP: Do not use non-portable strcasecmp.
-
-2007-10-03 16:19 king
-
- * Source/cmDependsFortran.cxx: BUG: When requiring a module through
- a .proxy rule add an empty .proxy rule in case no other source in
- the target provides it. Since it is not a file-level dependency
- there does not need to be a rule to create the .proxy as a file.
- This addresses bug#3984.
-
-2007-10-03 15:41 king
-
- * Source/: cmDependsFortran.cxx, cmDependsFortranLexer.cxx,
- cmDependsFortranLexer.h, cmDependsFortranLexer.in.l,
- cmDependsFortranParser.cxx, cmDependsFortranParser.h,
- cmDependsFortranParser.y, cmDependsFortranParserTokens.h: BUG:
- Fix for bug#5809. Applied patch supplied in the bug report.
- Updated pre-generated lexer and parser sources. This updates the
- makedepf90 version to 2.8.8. The parser actions have been
- updated to ignore "use" in comments properly.
-
-2007-10-03 15:23 king
-
- * Source/CMakeLists.txt: ENH: Updated CMAKE_REGENERATE_YACCLEX
- option to support cmDependsFortran. Fixed to work with spaces in
- path.
-
-2007-10-02 22:27 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-02 15:48 hoffman
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH: speed up
- actual path name by cache on windows
-
-2007-10-01 22:31 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-10-01 15:57 david.cole
-
- * Tests/: CMakeLists.txt, SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: COMP: Rename the executables for
- the SimpleInstall tests so that the executable files that run
- during the test do not have the word install in their file names.
- This allows running the tests on Windows Vista without admin
- privileges and without adding a manifest containing the asInvoker
- requestedExecutionLevel element.
-
-2007-09-30 22:28 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-09-29 22:36 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-09-28 22:49 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-09-27 23:02 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-09-27 14:44 hoffman
-
- * Source/cmGeneratedFileStream.cxx, Source/cmSystemTools.cxx,
- Source/CPack/cmCPackTGZGenerator.cxx, Utilities/cmtar/libtar.c:
- COMP: remove warnings
-
-2007-09-27 14:20 hoffman
-
- * Modules/FindQt4.cmake: ENH: set QT_EDITION_DESKTOPLIGHT and do
- not disable modules
-
-2007-09-27 14:18 hoffman
-
- * DartLocal.conf.in: ENH: fix space
-
-2007-09-27 14:16 hoffman
-
- * Source/cmWin32ProcessExecution.cxx: ENH: remove junk from output
-
-2007-09-27 08:53 hoffman
-
- * Utilities/cmcurl/CMakeLists.txt: ENH: add a check for basename to
- cmcurl
-
-2007-09-26 22:59 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-09-26 20:53 hoffman
-
- * Modules/FindQt4.cmake: ENH: look for qt in a beter registry place
- and disable modules that won't work with DesktopLight, also set
- QT_EDITION variable
-
-2007-09-25 23:06 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-09-25 10:57 hoffman
-
- * Source/cmSystemTools.cxx: BUG: fix problem with stdout and stderr
- not showing up in ms dos shells
-
-2007-09-25 08:36 hoffman
-
- * Tests/CMakeLists.txt: ENH: increase timeout
-
-2007-09-25 08:30 hoffman
-
- * DartLocal.conf.in: ENH: remove extra space
-
-2007-09-24 23:13 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-09-24 13:19 hoffman
-
- * DartLocal.conf.in, Source/cmSystemTools.cxx: ENH: add new
- machines
-
-2007-09-24 11:18 hoffman
-
- * CTestCustom.cmake.in: COMP: exclude some warnings on hp
-
-2007-09-24 11:16 hoffman
-
- * Source/: cmCommandArgumentLexer.cxx, cmDependsJavaLexer.cxx,
- cmExprLexer.cxx: COMP: fix warnings on hp
-
-2007-09-24 11:10 hoffman
-
- * Source/CTest/: cmCTestTestHandler.cxx, cmCTestTestHandler.h: ENH:
- fix line length issues
-
-2007-09-24 09:53 king
-
- * Modules/FindThreads.cmake: BUG: Enable CMAKE_HP_PTHREADS only
- when the old CMA threads are available. Modern HP pthreads are
- just normal pthreads.
-
-2007-09-23 23:09 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-09-22 22:47 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-09-21 22:46 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-09-21 13:37 alex
-
- * Source/CPack/cmCPackDebGenerator.cxx:
- STYLE: use %-10lld instead of %-10qd for printing a 64bit int,
- maybe this silences the warning of the HP compiler
-
- Alex
-
-2007-09-21 11:42 alex
-
- * Source/cmFindPackageCommand.cxx:
- STYLE: improved error message for the case that neither
- FindFoo.cmake nor FooConfig.cmake were found
-
- Alex
-
-2007-09-21 11:42 hoffman
-
- * Modules/InstallRequiredSystemLibraries.cmake: ENH: remove message
-
-2007-09-20 22:44 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-09-20 17:21 king
-
- * Modules/FindThreads.cmake: BUG: Do not use CMA threads on HP if
- they do not exist.
-
-2007-09-20 16:48 hoffman
-
- * Tests/CMakeLists.txt: ENH: VV make too much data for the
- dashboard
-
-2007-09-20 11:57 hoffman
-
- * Source/kwsys/testRegistry.cxx: COMP: remove warning on new HPUX
- compiler
-
-2007-09-20 10:56 king
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ENH: Disable package test only on
- OSX < 10.4. Added comment explaining reason for timeout.
-
-2007-09-20 10:47 king
-
- * Tests/CMakeLists.txt: ENH: Restore shorter timeout for
- SimpleInstall-Stage2.
-
-2007-09-20 09:36 alex
-
- * Source/kwsys/SystemTools.cxx:
- COMP: TIOCGWINSZ and struct winsize also doesn't exist on Cray
- Catamount
-
- Alex
-
-2007-09-20 09:30 alex
-
- * Source/kwsys/SystemTools.cxx:
- COMP: make SystemTools.cxx build on Cray Xt3
-
- Alex
-
-2007-09-20 08:33 alex
-
- * Source/cmDocumentation.cxx:
- STYLE: fix line lengths
-
- Alex
-
-2007-09-19 22:33 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-09-19 13:14 alex
-
- * Source/: cmDocumentation.cxx, cmDocumentation.h,
- cmDocumentationFormatter.h, cmakemain.cxx:
- ENH: add new help option --help-custom-modules, which generates
- documentation for all modules found in CMAKE_MODULE_PATH, which
- currently has to be specified via -D, this can later on be
- improved e.g. by reading a special (to-be-created) file like
- CMakeFiles/ModulePath.cmake in the build tree so that running
- cmake help in the build tree of a project will always give you
- the current module path. (This could actually also help IDEs
- which would like to support cmake for projects...)
-
- Alex
-
-2007-09-19 11:42 hoffman
-
- * Utilities/cmcurl/CMakeLists.txt: ENH: add test for HAVE_BASENAME
- since it is used
-
-2007-09-19 11:16 hoffman
-
- * Source/CTest/cmCTestTestHandler.cxx,
- Source/CTest/cmCTestTestHandler.h, Source/kwsys/CMakeLists.txt,
- Tests/CMakeLists.txt: ENH: fix failing test when valgrind is on
-
-2007-09-19 11:10 king
-
- * Tests/: CMakeLists.txt, SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ENH: Re-enable packaging part of
- SimpleInstall-Stage2 test on Apple. Give it a long timeout to
- see what is going on.
-
-2007-09-19 10:46 alex
-
- * Source/: cmDocumentationFormatter.h,
- cmDocumentationFormatterHTML.cxx:
- COMP: fix warning about unused parameters
-
- Alex
-
-2007-09-19 09:59 alex
-
- * Source/cmDocumentationFormatterMan.cxx:
- BUG: correct name for the man page
-
- Alex
-
-2007-09-19 09:35 alex
-
- * Modules/FindQt4.cmake:
- BUG: if Qt is installed as a framework, add -F to the command
- line so Q_WS_MAC can be detected correctly
-
- Alex
-
-2007-09-19 09:05 alex
-
- * Source/: CMakeLists.txt, cmDocumentation.cxx, cmDocumentation.h,
- cmDocumentationFormatter.cxx, cmDocumentationFormatter.h,
- cmDocumentationFormatterHTML.cxx, cmDocumentationFormatterHTML.h,
- cmDocumentationFormatterMan.cxx, cmDocumentationFormatterMan.h,
- cmDocumentationFormatterText.cxx, cmDocumentationFormatterText.h,
- cmDocumentationFormatterUsage.cxx,
- cmDocumentationFormatterUsage.h:
- STYLE: move the code for the different formats of the generated
- help into their own classes, making cmDocumentation smaller and
- also making it easier to eventually add another format
-
- Alex
-
-2007-09-19 09:04 alex
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt:
- COMP: reenable the installation of the PUBLIC_HEADERs
-
- Alex
-
-2007-09-18 22:43 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-09-18 17:05 alex
-
- * Source/cmExtraCodeBlocksGenerator.cxx:
- STYLE: fix line lengths
-
- Alex
-
-2007-09-18 15:16 hoffman
-
- * CMakeCPack.cmake, Modules/NSIS.InstallOptions.ini.in,
- Modules/NSIS.template.in, Source/CPack/cmCPackNSISGenerator.cxx:
- ENH: allow for desktop link to be created and fix chop of last
- char in PATH on uninstall
-
-2007-09-18 15:13 alex
-
- * Modules/FindPythonLibs.cmake:
- BUG: make the string static, otherwise the contents are gone when
- we exit the function (same fix as in VTK/CMake/)
-
- Alex
-
-2007-09-18 11:35 hoffman
-
- * Tests/CMakeLists.txt: ENH: increase timeout for long test
-
-2007-09-18 11:34 hoffman
-
- * Source/cmCTest.cxx: ENH: allow test properties to set a timeout
- that is longer than the default timeout, but not longer than
- CTEST_TIME_LIMIT for a script
-
-2007-09-18 09:54 alex
-
- * Source/cmExtraCodeBlocksGenerator.cxx:
- ENH: use the oubject_output option to try to tell CodeBlocks
- where the object files are located (to make "compile file" work).
- Doesn't work yet, but at least the .objs/ is now removed from the
- path.
-
- Alex
-
-2007-09-17 22:38 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-09-17 16:21 alex
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt:
- COMP: disable packaging test on Apple, see if this fixes the
- timeouts
-
- Alex
-
-2007-09-17 15:59 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: ENH: fix for vs 8
-
-2007-09-17 15:55 alex
-
- * CMakeLists.txt, Modules/CMakeCCompilerId.c,
- Modules/CMakeCXXCompilerId.cpp,
- Modules/Platform/Linux-PGI-C.cmake,
- Modules/Platform/Linux-PGI-CXX.cmake, Source/kwsys/Directory.cxx:
-
- ENH: add support for the Portland Compiler to CMake, can build
- cmake and the tests pass (except the wrapping tests, which fail
- to link to the g++-compiled Qt)
-
- Alex
-
-2007-09-17 15:40 alex
-
- * Utilities/cmtar/libtar.c:
- COMP: use C-style comments in C code
-
- Alex
-
-2007-09-17 15:27 hoffman
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ENH: test install of debug libs
-
-2007-09-17 15:26 hoffman
-
- * Modules/InstallRequiredSystemLibraries.cmake: ENH: allow for
- installation of debug libs
-
-2007-09-17 15:20 hoffman
-
- * Modules/CMakeVS8FindMake.cmake,
- Modules/Platform/Windows-cl.cmake, Source/CMakeLists.txt,
- Source/cmGlobalVisualStudio9Generator.cxx,
- Source/cmGlobalVisualStudio9Generator.h,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h, Source/cmake.cxx,
- Utilities/cmcurl/select.h, Utilities/cmcurl/CMake/CurlTests.c,
- Utilities/cmcurl/Platforms/WindowsCache.cmake,
- Modules/CMakeVS9FindMake.cmake: ENH: add support for vs 2008 beta
- 2
-
-2007-09-17 15:18 alex
-
- * Utilities/cmtar/: CMakeLists.txt, config.h.in, internal.h:
- COMP: add a check for makedev, which isn't available with the PGI
- compiler on Cray XT3
-
- Alex
-
-2007-09-17 11:17 hoffman
-
- * Source/cmSystemTools.cxx: ENH: fix warning
-
-2007-09-17 10:53 alex
-
- * Source/cmTryRunCommand.cxx:
- STYLE: copy the executables from TRY_RUN() to
- ${CMAKE_BINARY_DIR}/CMakeFiles/ instead to ${CMAKE_BINARY_DIR}
-
- Alex
-
-2007-09-17 10:51 king
-
- * Tests/BuildDepends/: CMakeLists.txt, Project/CMakeLists.txt,
- Project/dep.cxx, Project/zot.cxx: ENH: Adding test for
- ADD_CUSTOM_COMMAND's new IMPLICIT_DEPENDS feature.
-
-2007-09-17 10:50 king
-
- * Source/: cmAddCustomCommandCommand.cxx,
- cmAddCustomCommandCommand.h, cmCustomCommand.cxx,
- cmCustomCommand.h, cmMakefileTargetGenerator.cxx: ENH: Added
- IMPLICIT_DEPENDS option to ADD_CUSTOM_COMMAND. It currently
- works only for Makefile generators. It allows a custom command
- to have implicit dependencies in the form of C or CXX sources.
-
-2007-09-17 10:40 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx,
- CTest/cmCTestBuildAndTestHandler.cxx,
- CTest/cmCTestBuildCommand.cxx, CTest/cmCTestTestHandler.cxx: ENH:
- fix build issue with config type not being specified by ctest
-
-2007-09-16 22:46 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-09-15 22:58 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-09-14 22:59 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-09-13 22:53 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-09-13 13:37 king
-
- * Source/cmMakefileTargetGenerator.cxx, Source/cmSourceFile.cxx,
- Tests/PrecompiledHeader/CMakeLists.txt: ENH: Added OBJECT_OUTPUTS
- source file property. Updated PrecompiledHeader test to use it
- (making the test simpler).
-
-2007-09-13 09:14 king
-
- * Source/cmGlobalXCodeGenerator.cxx: COMP: Fix shadowed local
- warning by scoping the previous decl properly.
-
-2007-09-12 22:54 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-09-11 22:49 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-09-11 15:21 david.cole
-
- * CTestCustom.cmake.in: ENH: Avoid prompting for admin privileges
- when running CMakeSetup.exe on Vista by adding a
- requestedExecutionLevel element to its manifest.
-
-2007-09-11 14:43 hoffman
-
- * Source/CTest/cmCTestBuildAndTestHandler.cxx: ENH: for build and
- test default the config type to the one that ctest was built
- with, it is good for the current ctest setup, and other projects
- can always specify a value on the command line
-
-2007-09-11 12:23 hoffman
-
- * Source/cmSystemTools.cxx: ENH: opps
-
-2007-09-11 11:22 david.cole
-
- * Utilities/cmzlib/: CMakeLists.txt, ChangeLog, FAQ, INDEX, README,
- README.Kitware.txt, adler32.c, cm_zlib_mangle.h, compress.c,
- crc32.c, crc32.h, deflate.c, deflate.h, example.c, gzio.c,
- infblock.c, infblock.h, infcodes.c, infcodes.h, inffast.c,
- inffast.h, inffixed.h, inflate.c, inflate.h, inftrees.c,
- inftrees.h, infutil.c, infutil.h, maketree.c, minigzip.c,
- trees.c, uncompr.c, zconf.h, zlib.def, zlib.h, zlib.rc, zutil.c,
- zutil.h: ENH: Update zlib to 1.2.3. Addresses bugs #5445 and
- #3473.
-
-2007-09-11 11:21 hoffman
-
- * Source/: cmCTest.cxx, cmSystemTools.cxx, cmSystemTools.h,
- ctest.cxx, CTest/cmCTestTestHandler.cxx: ENH: fix 2 ctest issues,
- do not use the build type of ctest to look for config types, do
- not inherit pipes in child procs for ctest so it can kill them
-
-2007-09-11 10:01 hoffman
-
- * Source/cmMathCommand.h: ENH: improve docs
-
-2007-09-10 22:50 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-09-10 17:39 hoffman
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ENH: turn this stuff off to see
- if it fixes the dashboard on midworld
-
-2007-09-10 17:10 hoffman
-
- * Tests/Plugin/src/example_exe.cxx: ENH: fix memory leak
-
-2007-09-10 10:49 hoffman
-
- * Tests/CMakeLists.txt, Utilities/Release/README,
- Utilities/Release/create-cmake-release.cmake,
- Utilities/Release/upload_release.cmake: ENH: add test that builds
- a nightly windows cmake binary
-
-2007-09-10 10:22 king
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmTarget.cxx: ENH: Added
- XCODE_ATTRIBUTE_<an-attribute> property to allow direct setting
- of Xcode target attributes in generated projects. For example,
- one may set the prefix header property and the corresponding
- precompiled option to do precompiled headers.
-
-2007-09-09 23:03 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-09-09 13:18 hoffman
-
- * CMakeLists.txt: ENH: remove debug print
-
-2007-09-08 23:09 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-09-07 22:49 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-09-07 17:00 hoffman
-
- * CMakeLists.txt: ENH: MATH is not in bootstrap cmake
-
-2007-09-07 14:20 hoffman
-
- * CMakeCPack.cmake, CMakeLists.txt: ENH: for CVS CMake have cpack
- use the version date in the name of the package
-
-2007-09-07 11:10 hoffman
-
- * Source/cmCacheManager.cxx: ENH: fix spelling error
-
-2007-09-06 22:57 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-09-06 17:47 david.cole
-
- * Utilities/Release/CMakeInstall.bmp: BUG: Put back
- CMakeInstall.bmp in order to build a package with NSIS on
- Windows. It was inadvertently removed.
-
-2007-09-06 10:06 hoffman
-
- * DartLocal.conf.in: ENH: acdc is dead
-
-2007-09-05 23:01 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-09-04 11:45 zack.galbreath
-
- * Source/temp.txt: ENH: removing temporary testing file
-
-2007-09-04 11:05 zack.galbreath
-
- * Source/temp.txt: ENH: testing branchRestrict
-
-2007-08-31 16:52 alex
-
- * Source/: cmInstallCommand.cxx, cmInstallCommandArguments.h:
- STYLE: fix line lengths
-
- Alex
-
-2007-08-31 16:27 alex
-
- * Modules/CPack.cmake:
- STYLE: mark the generator options as advanced
-
- Alex
-
-2007-08-31 15:05 alex
-
- * Utilities/KWStyle/CMake.kws.xml.in:
- STYLE: disable header check
-
- Alex
-
-2007-08-31 14:51 king
-
- * CMakeLists.txt, CTestCustom.cmake.in, CTestCustom.ctest.in: ENH:
- Create CTestCustom.cmake instead of CTestCustom.ctest. Create
- the old file to include the new one for compatibility. This
- should prevent the long delays of CTest traversing the whole tree
- looking for CTestCustom.ctest files.
-
-2007-08-31 14:07 alex
-
- * Utilities/KWStyle/: CMakeLists.txt, CMakeMoreChecks.kws.xml.in:
- STYLE: add makefile target MoreStyleChecks, which runs KWStyle
- with more checks enabled and creates the html files.
-
- Alex
-
-2007-08-31 13:45 alex
-
- * Source/cmGlobalGenerator.cxx:
- STYLE: the temporary variable is not necessary
-
- Alex
-
-2007-08-31 13:42 alex
-
- * Source/: cmExtraCodeBlocksGenerator.cxx, cmGlobalGenerator.cxx,
- cmGlobalGenerator.h, cmGlobalKdevelopGenerator.cxx:
- ENH: add support for Fortran to the KDevelop generator -minor
- optimization for GetLanguageEnabled()
-
- Alex
-
-2007-08-31 09:14 king
-
- * Source/CPack/cmCPackDebGenerator.cxx: BUG: Another space-in-path
- fix.
-
-2007-08-31 09:09 king
-
- * Source/cmake.cxx: BUG: Fix path to CMake executables when run
- from bootstrap build.
-
-2007-08-30 16:23 alex
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt:
- STYLE: adapt the test to the change from FILENAME to FILE -add a
- call to the EXPORT() command
-
- Alex
-
-2007-08-30 16:22 alex
-
- * Source/: cmInstallCommand.cxx, cmInstallExportGenerator.cxx:
- STYLE: rename FILENAME keyword to FILE, because FILENAME is used
- in no other place
-
- Alex
-
-2007-08-30 13:35 alex
-
- * Modules/: FindPythonInterp.cmake, FindPythonLibs.cmake:
- ENH: add support for the next python release, python 2.6
-
- Alex
-
-2007-08-30 11:36 alex
-
- * Source/cmExtraCodeBlocksGenerator.cxx:
- STYLE: "Build file" still doesn't work, but now it is at least a
- bit closer, it needs some more support from CB
-
- Alex
-
-2007-08-30 10:26 alex
-
- * Source/cmStringCommand.h:
- STYLE: add the | to the docs
-
- Alex
-
-2007-08-29 16:32 alex
-
- * Source/CPack/cmCPackDebGenerator.cxx:
- BUG: work if there are spaces in the path to cmake
-
- Alex
-
-2007-08-29 16:31 alex
-
- * Modules/CPackRPM.cmake:
- ENH: fail with error if trying to create a RPM stating that
- rpmbuild can't handle spaces
-
- Alex
-
-2007-08-29 15:19 alex
-
- * Source/cmExtraCodeBlocksGenerator.cxx:
- BUG: make paths with spaces work in CodeBlocks -gcc is always gcc
- and not mingw
-
- Alex
-
-2007-08-29 14:35 alex
-
- * Source/cmIfCommand.cxx: BUG: this seems to fix the regexp
- result-storage problem, now it seems the actual result is tored
- instead of "1" , as it happened for StringFileTest on Windows
-
- Alex
-
-2007-08-29 14:05 alex
-
- * Source/cmStringCommand.h:
- STYLE: add docs about the supported regexp characters and
- CMAKE_MATCH_(0..9)
-
- Alex
-
-2007-08-29 12:01 alex
-
- * Tests/StringFileTest/CMakeLists.txt:
- ENH: added tests for the CMAKE_MATCH_(0..9) variables, which get
- set by regex matches (STRING(REGEX), IF(MATCHES))
-
- Alex
-
-2007-08-29 11:58 alex
-
- * Source/: cmIfCommand.cxx, cmIfCommand.h, cmStringCommand.cxx,
- cmStringCommand.h:
- ENH: also store the group matches from IF( MATCHES) in
- CMAKE_MATCH_(0..9)
-
- Alex
-
-2007-08-29 11:30 king
-
- * Source/cmDependsFortran.cxx: BUG: Do not write symbolic make
- dependencies into depends.internal.
-
-2007-08-29 10:12 alex
-
- * Source/: cmExtraCodeBlocksGenerator.cxx,
- cmExtraCodeBlocksGenerator.h:
- ENH: don't hardcode gcc -put the include dirs in the project file
- to enable autocompletion -prepare for nmake
-
- Alex
-
-2007-08-28 16:27 alex
-
- * Source/cmMakefile.cxx:
- COMP: explicitely cast to int to silence warning with msvc8
-
- Alex
-
-2007-08-28 16:19 alex
-
- * Modules/CMakeGenericSystem.cmake, Source/cmLocalGenerator.cxx:
- ENH: add flag so a terminating slash for the link path can be
- specified (needed by the Digital Mars D compiler)
-
- Alex
-
-2007-08-28 15:13 alex
-
- * Source/cmExtraCodeBlocksGenerator.cxx:
- STYLE: add links to docs
-
- Alex
-
-2007-08-28 13:46 alex
-
- * Source/CTest/cmCTestGenericHandler.cxx:
- STYLE: fix typo
-
- Alex
-
-2007-08-28 11:02 alex
-
- * CMakeLists.txt:
- COMP: enable RPATH if any of the CMAKE_USE_SYSTEM_XXX variables
- is enabled or if the curses library is neither in /lib nor in
- /usr/lib . This makes it build on NetBSD. For more comments see
- CMakeLists.txt
-
- Alex
-
-2007-08-28 10:59 alex
-
- * Tests/SourceGroups/: CMakeLists.txt, main.c:
- COMP: enable ANSI C, this should make it work with the HP-UX
- compiler
-
- Alex
-
-2007-08-28 10:52 alex
-
- * Modules/: CheckCSourceRuns.cmake, CheckCXXSourceRuns.cmake:
- ENH: use the same CMAKE_SKIP_RPATH setting in
- CHECK_C/CXX_SOURCE_RUNS as in the main project. I think it
- doesn't make sense if a project disables RPATH, uses
- CHECK_C_SOURCE_RUNS() to see if something is able to run, and
- this succeeds because it has been built with RPATH, but an
- executable built within the project won't be able to run since it
- has been built without RPATH.
-
- Alex
-
-2007-08-28 08:36 alex
-
- * Tests/SourceGroups/main.c:
- COMP: maybe it compiles this way with the HP-UX compiler
-
- Alex
-
-2007-08-27 23:12 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-08-27 17:05 alex
-
- * Source/: cmLocalVisualStudioGenerator.cxx,
- cmLocalVisualStudioGenerator.h: BUG: fix #5326: source files with
- the same name in different groups lead to colliding object file
- names
-
- Alex
-
-2007-08-27 16:05 alex
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt:
- ENH: add test for installing a header marked as PUBLIC_HEADER of
- a library
-
- Alex
-
-2007-08-27 16:04 alex
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmInstallCommand.cxx, cmInstallCommand.h,
- cmInstallExportGenerator.cxx, cmInstallExportGenerator.h:
- ENH: add install files generators for targets which have
- PUBLIC_HEADER, PRIVATE_HEADER or RESOURCE_FILES property, use the
- destination for the public headers as include directory property
- for exported libraries
-
- Alex
-
-2007-08-27 15:15 alex
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt:
- COMP: add a test for exporting and importing targets
-
- Alex
-
-2007-08-27 14:44 alex
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt:
- COMP: the SimpleInstall test also succeeds on the Mac, so maybe
- Andys comment is not valid anymore
-
- Alex
-
-2007-08-27 14:17 alex
-
- * Tests/: CMakeLists.txt, SourceGroups/CMakeLists.txt:
- ENH: add the source_group() demo to the tests
-
- Alex
-
-2007-08-27 13:23 alex
-
- * Source/cmExtraCodeBlocksGenerator.cxx:
- COMP: disable nmake support until somebody tests it
-
- Alex
-
-2007-08-27 09:01 alex
-
- * Modules/FindCurses.cmake, Source/CursesDialog/CMakeLists.txt,
- Source/CursesDialog/ccmake.cxx,
- Source/CursesDialog/cmCursesStandardIncludes.h,
- Source/CursesDialog/form/CMakeLists.txt,
- Source/CursesDialog/form/cmFormConfigure.h.in,
- Source/CursesDialog/form/form.h:
- COMP: make it build on NetBSD, which has separate curses and
- ncurses, so it has to be detected that curses isn't good enough,
- but ncurses is, and that ncurses.h instead of curses.h is
- included
-
- Alex
-
-2007-08-27 08:49 alex
-
- * Source/cmGlobalKdevelopGenerator.cxx:
- COMP: remove unused variable
-
- Alex
-
-2007-08-26 23:20 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-08-26 19:27 alex
-
- * Source/: cmGlobalKdevelopGenerator.cxx,
- cmGlobalKdevelopGenerator.h:
- ENH: add all subdirs of the project to the kdevelop blacklist, so
- kdevelop doesn't watch these dirs for added or remved files
- everytime it is started
-
- Alex
-
-2007-08-26 03:29 alex
-
- * Modules/FindKDE4.cmake:
- BUG: KDEDIRS contains the kde install locations, not the binary
- dirs, so make KDEDIRS actually work in FindKDE4.cmake
-
- Alex
-
-2007-08-26 03:17 alex
-
- * Source/: cmMakefile.cxx, cmMakefile.h, cmSourceGroupCommand.cxx:
- COMP: parent is not used anymore with this patch, since now the
- name is given as a vector of components
-
- Alex
-
-2007-08-26 02:42 alex
-
- * Modules/FindPkgConfig.cmake:
- STYLE: fix typo
-
- Alex
-
-2007-08-25 23:37 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-08-24 23:15 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-08-24 14:39 alex
-
- * Tests/SourceGroups/: CMakeLists.txt, baz.c, main.c: BUG: demo
- (not really test) for the source_group() command
-
- Alex
-
-2007-08-24 14:27 alex
-
- * Source/: cmInstallCommand.cxx, cmInstallCommandArguments.cxx,
- cmInstallCommandArguments.h:
- STYLE: fix MSVC warnings by making the cmCommandArgumentsHelper a
- member of cmInstallCommandArguments instead of deriving from it
-
- Alex
-
-2007-08-24 14:21 alex
-
- * Source/: cmMakefile.cxx, cmMakefile.h, cmSourceGroup.cxx,
- cmSourceGroupCommand.cxx: BUG: fix #4057 (which had several
- duplicates): handle recursivew source groups better, i.e.
- multiple sourcegroups with the same end component work now
-
- Alex
-
-2007-08-24 13:30 david.cole
-
- * Source/cmInstallCommand.cxx, Source/cmInstallTargetGenerator.cxx,
- Source/cmInstallTargetGenerator.h, Source/cmTarget.h,
- Tests/CMakeLists.txt, Tests/BundleTest/CMakeLists.txt,
- Tests/BundleTest/BundleSubDir/CMakeLists.txt,
- Tests/Framework/CMakeLists.txt: ENH: Add InstallNameFixupPath to
- support installing built frameworks on the Mac. Change
- Application to Applications in the BundleTest. Also correct small
- typo (tcl->Tcl) noted in bug 4572.
-
-2007-08-24 10:58 alex
-
- * Source/cmSourceGroupCommand.cxx: BUG: handle source_group names
- which consist only of the delimiter the same was as empty source
- group names
-
- Alex
-
-2007-08-24 10:39 alex
-
- * Tests/SourceGroups/: CMakeLists.txt, bar.c, foo.c, main.c,
- sub1/foo.c, sub1/foobar.c:
- ENH: add test for source_group
-
- Alex
-
-2007-08-24 08:55 alex
-
- * Source/cmInstallCommand.cxx:
- ENH: use cmCommandArgumentHelper for INSTALL(TARGETS, FILES,
- PROGRAMS, EXPORTS), saves a lot of code. INSTALL(DIRECTORY) is
- still done the old way, since this seems to be quite complicated
- -for INSTALL(TARGETS ): also parse PUBLIC_HEADER, PRIVATE_HEADER,
- RESOURCE
-
- Alex
-
-2007-08-24 08:40 alex
-
- * Modules/CMakeForceCompiler.cmake:
- STYLE: fix typo in the docs
-
- Alex
-
-2007-08-23 23:21 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-08-23 16:14 alex
-
- * Source/: cmCommands.cxx, cmInstallCommandArguments.cxx,
- cmInstallCommandArguments.h:
- ENH: class for parsing the arguments for INSTALL()
-
- Alex
-
-2007-08-23 16:13 alex
-
- * Source/: cmCommandArgumentsHelper.cxx,
- cmCommandArgumentsHelper.h:
- ENH: add support for a default value, fix case when there is no
- item except the own group
-
- Alex
-
-2007-08-22 23:17 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-08-22 11:32 david.cole
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmInstallCommand.cxx, cmInstallExportGenerator.cxx,
- cmInstallExportGenerator.h: ENH: Handle FRAMEWORK and BUNDLE
- arguments in the INSTALL TARGETS command. Work in progress...
- More to come.
-
-2007-08-22 09:25 alex
-
- * Source/kwsys/RegularExpression.hxx.in:
- BUG: if there is no match, don't construct the stl string from a
- NULL pointer
-
- Alex
-
-2007-08-21 23:15 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-08-21 16:51 alex
-
- * Modules/UseQt4.cmake:
- ENH: support QtScript
-
- Alex
-
-2007-08-21 16:50 alex
-
- * Modules/FindQt4.cmake:
- ENH: support QtScript (since Qt 4.3), #4632
-
- Alex
-
-2007-08-21 16:22 alex
-
- * Source/cmLocalGenerator.cxx:
- STYLE: more space in the cmake_install.cmake script (easier to
- read)
-
- Alex
-
-2007-08-21 16:21 alex
-
- * Source/CMakeLists.txt:
- COMP: make it build on Linux
-
- Alex
-
-2007-08-21 15:30 alex
-
- * Source/kwsys/Glob.cxx:
- BUG: fix segfault if FindFiles() is called without actual match
- pattern (e.g. FILE(GLOB /usr/include) instead of FILE(GLOB
- /usr/include/* ) #4620
-
- Alex
-
-2007-08-21 13:47 alex
-
- * Source/cmGlobalKdevelopGenerator.cxx:
- ENH: also check for .hpp and .cxx files
-
- Alex
-
-2007-08-21 12:34 alex
-
- * Source/cmStringCommand.h:
- COMP: header was missing...
-
- Alex
-
-2007-08-21 12:31 hoffman
-
- * Tests/: Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/complex.cxx: ENH: fix leak
-
-2007-08-21 11:30 alex
-
- * Source/cmStringCommand.cxx:
- ENH: store the matches for paren-delimited subexpression in
- CMAKE_MATCH_[0..9] variables, so to get multiple subexpressions
- from one string STRING(REGEX MATCH) has to be executed only once
-
- Alex
-
-2007-08-21 10:56 alex
-
- * Source/cmStringCommand.h:
- STYLE: fix documentation for STRING(REPLACE) #5536
-
- Alex
-
-2007-08-20 23:17 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-08-20 16:59 alex
-
- * Source/: cmFindLibraryCommand.cxx, cmInstallGenerator.cxx,
- cmInstallTargetGenerator.cxx:
- STYLE: add some newlines to cmake_install.cmake, so it's easier
- to read -move the array behind the if, it's unused before it
-
- Alex
-
-2007-08-20 11:03 david.cole
-
- * Source/cmGlobalXCodeGenerator.cxx: STYLE: Fix line length style
- errors introduced last week.
-
-2007-08-20 08:49 alex
-
- * Source/cmFindPackageCommand.cxx:
- ENH: also process "~" and paths relative to
- CMAKE_CURRENT_SOURCE_DIR in Foo_DIR
-
- Alex
-
-2007-08-19 23:17 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-08-18 23:15 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-08-17 23:17 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-08-17 10:41 alex
-
- * Modules/Platform/BlueGeneL.cmake:
- COMP: also use -Wl,-relax and -lc -lnss etc. when using the IBM
- compiler
-
- Alex
-
-2007-08-17 10:14 alex
-
- * Source/cmGlobalGenerator.cxx:
- COMP: include windows.h first, as it is done in the other source
- files
-
- Alex
-
-2007-08-17 10:05 alex
-
- * Source/: cmExtraEclipseCDT4Generator.cxx,
- cmExtraEclipseCDT4Generator.h:
- ENH: patch from Miguel - cleaning up a bit: static helper
- functions, remove unused scanner profiles, remove unused
- variables, etc. - correct <name> entry in .project file -
- converts the make command and other paths obtained from cygwin
- cmake to windows style paths - provide environment setup for
- compiling with nmake - create linked resources and path entries
- for executable/library_output_path's not subdirs of binary path -
- fixes incorrect exclusions of output dirs when named the same as
- source dir - excludes the CMakeFiles subdirs from the directories
- to scan for output targets - removes possible redundant entries
- in <pathentry include ...> - adds the all and preinstall targets
- to the target list - removes the linked resources for non
- out-of-source builds and conflicting dirs
-
- Alex
-
-2007-08-17 09:33 alex
-
- * Source/CPack/: cmCPackRPMGenerator.cxx, cmCPackRPMGenerator.h:
- STYLE: InitializeInternal() is unused
-
- Alex
-
-2007-08-17 09:13 alex
-
- * Modules/CPackRPM.cmake, Source/CPack/cmCPackRPMGenerator.cxx,
- Source/CPack/cmCPackRPMGenerator.h:
- ENH: patch from Eric Noulard for an RPM package generator It
- seems rpmbuild can't handle paths with spaces, it complains that
- Buildroot takes only one tag (or something like this), quoting
- and escaping don't seem to help.
-
- Alex
-
-2007-08-17 09:00 hoffman
-
- * Modules/Platform/Darwin.cmake: ENH: use the correct flag for the
- linker
-
-2007-08-16 23:24 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-08-16 16:50 alex
-
- * Source/cmGlobalGenerator.cxx: COMP: quick windows name mangling
- fix (otherwise the compiler complains about
- cmMakefile::GetCurrentDirectoryA(), which doesn't exist)
-
- Alex
-
-2007-08-16 15:33 alex
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h:
- ENH: move the code for the NOTFOUND checking into its own
- function, so Configure() gets easier to overview -improve the
- error message, now it also says in which directories and for
- which targets the missing variables are used -minor speedup: the
- include directories don't have to be checked per target, per
- directory is enough
-
- Alex
-
-2007-08-16 15:03 alex
-
- * Modules/FindPythonLibs.cmake:
- STYLE: this wasn't intended to be committed
-
- Alex
-
-2007-08-16 15:02 alex
-
- * Modules/: FindPythonLibs.cmake, Platform/BlueGeneL.cmake:
- ENH: add -Wl,-relax to the default linker flags for BlueGene,
- otherwise you can get "relocation truncated to fit" errors
-
- Alex
-
-2007-08-16 10:14 king
-
- * DartLocal.conf.in: ENH: Added dash1win98 expected nightly.
-
-2007-08-16 09:22 hoffman
-
- * Modules/Platform/Darwin.cmake: ENH: make sure osx searches static
- and shared libs like other platforms
-
-2007-08-16 08:37 alex
-
- * Modules/Platform/Generic-SDCC-C.cmake:
- COMP: fix arguments
-
- Alex
-
-2007-08-16 07:38 malaterre
-
- * Source/kwsys/: Directory.hxx.in, Glob.hxx.in: COMP: Directory and
- Glob have pointer data members
-
-2007-08-15 23:09 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-08-15 14:26 alex
-
- * Modules/: CMakeDetermineSystem.cmake, CMakeFindBinUtils.cmake,
- CMakeSystem.cmake.in, CMakeSystemWithToolchainFile.cmake.in:
- STYLE: don't use an extra file to generate CMakeSystem.cmake but
- instead configure the toolchain file into it if required -also
- search for nm, objdump and objcpy, so these can be used in macros
-
- Alex
-
-2007-08-15 14:22 alex
-
- * Modules/Platform/Generic-SDCC-C.cmake:
- STYLE: explicitely set default options for sdcc, so it is visible
- for which processor it currently compiles, use --out-fmt-ihx to
- enforce .ihx files
-
- Alex
-
-2007-08-15 11:38 david.cole
-
- * Source/kwsys/: CMakeLists.txt, Configure.h.in: COMP: Second try
- getting rid of Microsoft deprecation warnings. This time tested
- from KWStyle with vs8 to make sure the warnings are really gone.
- Remove the deprecation defs from CMakeLists and guard the defs in
- the header so we do not redefine them if they are already
- defined.
-
-2007-08-15 10:26 alex
-
- * Source/cmListCommand.cxx, Source/cmListCommand.h,
- Tests/CMakeTests/ListTest.cmake.in:
- ENH: change LIST(CONTAINS ...) TO LIST(FIND ...), which returns
- the index and which is more useful, because then you can also
- access the item behind the one you were looking, useful for
- writing macros with optional keywords with parameters
-
- Alex
-
-2007-08-15 09:43 alex
-
- * CMakeLists.txt, Modules/FindCurses.cmake:
- COMP: ccmake requires ncurses, according to Berk and since it
- doesn't build on NetBSD where there are separate curses and
- ncurses libraries, and where the curses library is found, which
- doesn't work for ccmake while the existing ncurses library would
- work. With this change it should be possible to test whether the
- found curses lib provides ncurses functionality.
-
- Alex
-
-2007-08-15 09:25 david.cole
-
- * Source/kwsys/Configure.h.in: COMP: Suppress Microsoft deprecation
- warnings when building kwsys .c and .cxx files. This way, other
- projects that include kwsys will not see the warnings in kwsys .c
- and .cxx files, but they can still see the warnings in their own
- source files if they want to...
-
-2007-08-15 08:47 alex
-
- * Source/CPack/cmCPackDebGenerator.cxx:
- COMP: fix warning about comparison signed - unsigned
-
- Alex
-
-2007-08-15 08:28 alex
-
- * Source/CPack/cmCPackDebGenerator.cxx:
- COMP: fix build on HPUX, snprintf apparently doesn't work there
-
- Alex
-
-2007-08-14 23:15 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-08-14 14:12 david.cole
-
- * Source/: cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.h: ENH: Improve framework
- support in the makefile generator to match the support just added
- to the Xcode generator. BUG: Remove spurious warning and
- eliminate empty Libraries subdir inside built framework.
-
-2007-08-14 11:58 alex
-
- * Source/cmUtilitySourceCommand.h:
- STYLE: document the behaviour of UTILITY_SOURCE in cross
- compiling mode
-
- Alex
-
-2007-08-14 11:45 david.cole
-
- * Source/cmGlobalXCode21Generator.cxx,
- Source/cmGlobalXCodeGenerator.cxx,
- Source/cmGlobalXCodeGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalXCodeGenerator.cxx, Source/cmXCode21Object.cxx,
- Source/cmXCode21Object.h, Source/cmXCodeObject.cxx,
- Tests/Framework/CMakeLists.txt, Tests/Framework/fooBoth.h,
- Tests/Framework/fooNeither.h, Tests/Framework/fooPrivate.h,
- Tests/Framework/fooPublic.h, Tests/Framework/test.lua: ENH:
- Improvements to the Xcode generator. Build frameworks using
- native Copy Headers and Copy Bundle Resources phases. Fix bugs:
- eliminate folders with no names, ensure source files show up in
- multiple targets, remove empty utility targets from Sources
- subtrees, ensure that fileRefs only show up once in each grouping
- folder.
-
-2007-08-14 10:27 alex
-
- * Source/cmSystemTools.cxx:
- COMP: patch from Mathieu: fix warning about unused variables in
- bootstrap mode
-
- Alex
-
-2007-08-14 10:25 alex
-
- * Source/CPack/cmCPackDebGenerator.cxx:
- STYLE: another patch from Mathieu with some comments
-
- Alex
-
-2007-08-14 10:20 alex
-
- * Modules/CPackDeb.cmake:
- BUG: fix typo
-
- Alex
-
-2007-08-14 08:40 alex
-
- * Modules/CPackDeb.cmake, Source/CMakeLists.txt,
- Source/CPack/cmCPackDebGenerator.cxx,
- Source/CPack/cmCPackDebGenerator.h:
- ENH: deb generator: don't use the system provided ar, but do it
- yourself using the code from OpenBSD ar COMP: don't build all
- package generators on all platforms
-
- Alex
-
-2007-08-13 23:11 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-08-13 11:04 alex
-
- * Modules/TestBigEndian.cmake:
- ENH: for universal binaries return the endianess based on the
- processor
-
- Alex
-
-2007-08-12 23:11 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-08-12 21:08 alex
-
- * Modules/TestBigEndian.cmake:
- COMP: turn error into warning for now
-
- Alex
-
-2007-08-11 23:21 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-08-10 23:17 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-08-10 16:28 hoffman
-
- * Source/CTest/cmCTestMemCheckHandler.cxx: ENH: fix output and
- valgrind truncation issue
-
-2007-08-10 15:02 alex
-
- * Source/cmUtilitySourceCommand.cxx:
- ENH: print a warning if UTILITY_SOURCE is used in cross compiling
- mode -make it possible to preload the cache with the command in
- cross compiling mode
-
- Alex
-
-2007-08-10 13:14 alex
-
- * Modules/: CheckTypeSize.c.in, CheckTypeSize.cmake,
- TestBigEndian.c, TestBigEndian.cmake, TestEndianess.c.in:
- STYLE: remove unused CheckTypeSize.c.in ENH: change test for
- endianess from TRY_RUN() to TRY_COMPILE() by testing the binary
- image of a 16bit integer array, tested on Linux x86, Intel Mac
- and Sun (big endian)
-
- Alex
-
-2007-08-10 13:02 king
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio6Generator.h: BUG: Fixed passing of
- configuration names to GetRealDependency and ConstructScript.
- Added GetConfigName helper method to do this.
-
-2007-08-10 11:37 alex
-
- * Modules/FindOpenGL.cmake:
- STYLE: remove unnecessary default search paths
-
- Alex
-
-2007-08-10 11:15 hoffman
-
- * Source/cmake.cxx: ENH: fix memory leak
-
-2007-08-10 09:20 alex
-
- * Modules/CMakeDetermineCompilerId.cmake:
- BUG: fix compiler id test on cygwin
-
- Alex
-
-2007-08-10 09:07 alex
-
- * Source/cmMakefile.cxx, Modules/CMakeDetermineSystem.cmake,
- Modules/CMakeSystemSpecificInformation.cmake:
- ENH: set UNIX, WIN32 and APPLE in cmMakefile.cxx as it was
- before, so it works for scripts, then reset them in
- CMakeSystemSpecificInformation.cxx, so the platform modules can
- set them again for the target system
-
- Alex
-
-2007-08-10 08:54 alex
-
- * Modules/Platform/: AIX.cmake, BSDOS.cmake, BeOS.cmake,
- MP-RAS.cmake, QNX.cmake, RISCos.cmake:
- BUG: also include UnixPaths.cmake on these platforms, this also
- sets UNIX to 1
-
- Alex
-
-2007-08-09 23:17 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-08-09 16:54 alex
-
- * Tests/CMakeLists.txt:
- STYLE: mark these variables as advanced, they are only used for
- testing whether the tests should be added or not
-
- Alex
-
-2007-08-09 16:47 alex
-
- * Modules/CMakeGenericSystem.cmake:
- BUG: use CMAKE_HOST_UNIX here instead of UNIX
-
- Alex
-
-2007-08-09 15:57 alex
-
- * Source/: cmExportCommand.cxx, cmGlobalMSYSMakefileGenerator.h,
- cmGlobalMinGWMakefileGenerator.h,
- cmGlobalNMakeMakefileGenerator.h, cmGlobalWatcomWMakeGenerator.h:
-
- STYLE: use correct case for cmGlobalUnixMakefileGenerator3 make
- export() work with spaces in the path
-
- Alex
-
-2007-08-09 15:31 hoffman
-
- * Source/cmSetSourceFilesPropertiesCommand.h: ENH: merge in doc
- change from head
-
-2007-08-09 14:55 alex
-
- * Utilities/cmcurl/: CMakeLists.txt, CMake/CurlTests.c,
- CMake/OtherTests.cmake:
- STYLE: HAVE_LONG_LONG_CONST was completely unused here (it was
- used in the (unused) copy of curl under CMake/CTest/Curl/ )
-
- Alex
-
-2007-08-09 14:45 alex
-
- * Modules/CMakeDetermineCompilerId.cmake,
- Modules/CMakeDetermineSystem.cmake,
- Modules/CMakeSystemSpecificInformation.cmake,
- Modules/Platform/BeOS.cmake, Modules/Platform/CYGWIN.cmake,
- Modules/Platform/Darwin.cmake, Modules/Platform/QNX.cmake,
- Modules/Platform/UnixPaths.cmake, Modules/Platform/Windows.cmake,
- Source/cmMakefile.cxx:
- ENH: UNIX, CYGWIN, WIN32, APPLE, QNXNTO and BEOS are not longer
- set in cmMakefile.cxx, but now in the platform files and are now
- valid for the target platform, not the host platform. New
- variables CMAKE_HOST_WIN32, CMAKE_HOST_UNIX, CMAKE_HOST_APPLE and
- CMAKE_HOST_CYGWIN have been added in cmMakefile.cxx (...and have
- now to be used in all cmake files which are executed before
- CMakeSystemSpecificInformation.cmake is loaded). For
- compatibility the old set is set to the new one in
- CMakeDetermineSystem.cmake and reset before the system platform
- files are loaded, so custom language or compiler modules which
- use these should still work.
-
- Alex
-
-2007-08-09 14:26 alex
-
- * Source/: CMakeLists.txt, CTest/CMakeLists.txt:
- COMP: this copy of curl is unused, the one in Utilities/cmcurl/
- is used
-
- Alex
-
-2007-08-09 11:05 alex
-
- * Modules/CMakeSystemWithToolchainFile.cmake.in:
- BUG: work with spaces in the path
-
- Alex
-
-2007-08-09 09:57 alex
-
- * Tests/CMakeLists.txt:
- COMP: lets see if this sets the timeout back to 5400
-
- Alex
-
-2007-08-09 09:03 alex
-
- * Source/kwsys/CommandLineArguments.hxx.in:
- STYLE: fix typo
-
- Alex
-
-2007-08-09 08:49 alex
-
- * Source/cmTarget.cxx:
- STYLE: fix typo
-
- Alex
-
-2007-08-09 08:48 alex
-
- * Source/cmDocumentation.cxx:
- BUG: properties and module names are case sensitive
-
- Alex
-
-2007-08-08 23:15 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-08-08 15:44 alex
-
- * Source/CPack/cmCPackRPMGenerator.cxx:
- COMP: silence warnings
-
- Alex
-
-2007-08-08 14:44 alex
-
- * Source/CPack/cmCPackGenerators.cxx:
- BUG: register the rpm generator for RPM
-
- Alex
-
-2007-08-08 14:18 alex
-
- * Modules/CPackDeb.cmake, Source/CPack/cmCPackDebGenerator.cxx:
- ENH: patch from Mathieu: more entries in the debian control file
-
- Alex
-
-2007-08-08 13:05 alex
-
- * Source/cmFindPackageCommand.cxx,
- Tests/FindPackageTest/CMakeLists.txt:
- ENH: remove the watch for the upper case variable name, it breaks
- the feature summary, which needs to check for both the upper case
- and original case _FOUND variables
-
- Alex
-
-2007-08-08 11:33 alex
-
- * Source/CMakeLists.txt, Modules/CPack.cmake,
- Modules/CPackRPM.cmake, Source/CPack/cmCPackGenerators.cxx,
- Source/CPack/cmCPackRPMGenerator.cxx,
- Source/CPack/cmCPackRPMGenerator.h:
- ENH: add empty RPM package generator, Eric Noulard wants to work
- on it
-
- Alex
-
-2007-08-08 10:05 alex
-
- * Tests/CMakeLists.txt:
- COMP: change the order of the tests, so maybe the timeout works
-
- Alex
-
-2007-08-08 09:32 alex
-
- * Tests/CMakeLists.txt:
- ENH: also specify the C++ compiler for mingw
-
- Alex
-
-2007-08-08 08:41 malaterre
-
- * Source/kwsys/CommandLineArguments.cxx: ENH: Remove extra ;
-
-2007-08-07 23:10 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-08-07 18:02 alex
-
- * Tests/FindPackageTest/CMakeLists.txt:
- BUG: disable this test temporarily
-
- Alex
-
-2007-08-07 16:26 alex
-
- * Source/cmFindPackageCommand.h:
- COMP: also commit the header...
-
- Alex
-
-2007-08-07 15:42 alex
-
- * Modules/Dart.cmake:
- STYLE: find Dart quietly (so it doesn't go in the feature log)
-
- Alex
-
-2007-08-07 15:41 alex
-
- * Modules/FeatureSummary.cmake, Source/cmFindPackageCommand.cxx,
- Source/cmake.cxx:
- ENH: add global properties for collecting enabled/disabled
- features during the cmake run and add macros
- print_enabled/disabled_features() and set_feature_info(), so
- projects can get a nice overview at the end of the cmake run what
- has been found and what hasn't FIND_PACKAGE() automatically adds
- the packages to these global properties, except when used with
- QUIET Maybe this can also be useful for packagers to find out
- dependencies of projects.
-
- Alex
-
-2007-08-07 15:36 hoffman
-
- * DartLocal.conf.in: ENH: change ibm machine again
-
-2007-08-07 15:09 alex
-
- * Source/cmGlobalGenerator.cxx:
- STYLE: I think the comment (and the book) were wrong about the
- naming of this file
-
- Alex
-
-2007-08-07 13:57 king
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h, cmMakefileTargetGenerator.cxx:
- ENH: Replaced dependency integrity map with an explicit map from
- object file to source file for each language in each target.
- This simplifies creation of implicit dependency scanning rules
- and allows more than one object file in a target to start
- dependency scanning with the same source file.
-
-2007-08-07 10:13 alex
-
- * Tests/CMakeLists.txt:
- BUG: the test for chicken should be named Chicken, not plplot
-
- Alex
-
-2007-08-07 00:00 alex
-
- * Source/cmExtraCodeBlocksGenerator.cxx:
- ENH: don't create a CodeBlocks workspace, the CodeBlocks projects
- cover everything what's needed
-
- Alex
-
-2007-08-06 23:16 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-08-06 22:08 alex
-
- * Modules/FindPackageHandleStandardArgs.cmake:
- STYLE: fix typo
-
- Alex
-
-2007-08-06 17:09 hoffman
-
- * Source/cmCTest.cxx: ENH: change error to warning so ctesttest3
- passes
-
-2007-08-06 14:45 alex
-
- * Tests/CMakeLists.txt:
- ENH: add plplot and Chicken Scheme build tests
-
- Alex
-
-2007-08-06 13:31 alex
-
- * Source/CPack/cmCPackDebGenerator.cxx:
- ENH: another fix for the deb generator by Mathieu
-
- Alex
-
-2007-08-06 13:24 alex
-
- * Source/: cmExtraCodeBlocksGenerator.cxx,
- cmExtraCodeBlocksGenerator.h, cmExtraEclipseCDT4Generator.cxx:
- STYLE: fix line lengths
-
- Alex
-
-2007-08-06 11:02 alex
-
- * Modules/: FindMPI.cmake, FindThreads.cmake:
- STYLE: use FIND_PACKAGE_HANDLE_STANDARD_ARGS() also in
- FindMPI.cmake -remove unnecessary ELSE() in FindThreads.cmake
-
- Alex
-
-2007-08-06 10:42 hoffman
-
- * Modules/FLTKCompatibility.cmake: ENH: threads used to include
- this
-
-2007-08-06 09:03 alex
-
- * Source/CPack/cmCPackDebGenerator.cxx:
- BUG: patch from Mathieu: the md5sums were not correct
-
- Alex
-
-2007-08-05 23:17 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-08-04 23:10 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-08-03 23:07 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-08-03 16:44 hoffman
-
- * Source/CTest/cmCTestGenericHandler.cxx: ENH: make sure there is
- an error and notify user if nightly start time not set
-
-2007-08-03 16:44 hoffman
-
- * Source/CTest/cmCTestCoverageHandler.cxx: ENH: show files as
- untested if no lines are covered
-
-2007-08-03 16:42 hoffman
-
- * Source/CTest/cmCTestUpdateHandler.cxx: ENH: fatal error if cvs
- update fails
-
-2007-08-03 16:41 hoffman
-
- * Source/cmCTest.cxx: ENH: add a check to make sure nightly start
- time was specified
-
-2007-08-03 16:35 hoffman
-
- * Source/CTest/cmCTestMemCheckHandler.cxx: ENH: add another
- valgrind error type
-
-2007-08-03 16:31 king
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx, cmInstallCommand.h,
- cmInstallTargetGenerator.cxx, cmLocalUnixMakefileGenerator3.cxx,
- cmTarget.cxx: ENH: Added warning when an install rule is created
- from an EXCLUDE_FROM_ALL target. Added a foo/preinstall version
- of targets that need relinking so that exclude-from-all targets
- can be manually relinked for installation.
-
-2007-08-03 15:44 king
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h, cmMakefile.cxx, cmTarget.cxx:
- BUG: Target exclusion-from-all tests should always use the root
- local generator associated with the all target being tested.
-
-2007-08-03 15:43 seanmcbride
-
- * Source/kwsys/CommandLineArguments.cxx: COMP: fixed compiler
- warning in sprintf usage
-
-2007-08-03 15:26 alex
-
- * Modules/CPack.cmake, Modules/CPackDeb.cmake,
- Source/CPack/cmCPackGenericGenerator.cxx, Source/CPack/cpack.cxx:
-
- ENH: better error messages from the debian package generator
- -don't display the cpack help if a generator failed with some
- problem -check for cmSystemTools::GetErrorOccuredFlag()
-
- Alex
-
-2007-08-03 09:39 king
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h: ENH: Added
- cmTarget::GetLanguages method to centralize computation of the
- list of languages compiled in a target. Transformed
- NeedRequiresStep to use it.
-
-2007-08-02 23:18 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-08-02 15:48 alex
-
- * Modules/FindPythonLibs.cmake:
- ENH: make the python modules usable for C and C++ and only write
- the header if it has changed
-
- Alex
-
-2007-08-02 14:28 king
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h: BUG: Removing accidental
- commit.
-
-2007-08-02 14:28 king
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: BUG: Quick-fix for
- accidental commit.
-
-2007-08-02 14:23 king
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h: ENH: Added
- cmTarget::GetLanguages method to centralize computation of the
- list of languages compiled in a target.
-
-2007-08-02 13:38 king
-
- * Source/: cmMakefileTargetGenerator.cxx, cmTarget.cxx, cmTarget.h:
- ENH: Added cmTarget::GetLanguages method to centralize
- computation of the list of languages compiled in a target.
-
-2007-08-02 11:17 alex
-
- * Modules/Platform/: Windows-cl.cmake, Windows.cmake,
- WindowsPaths.cmake:
- ENH: use WindowsPaths.cmake on all Windows platforms, not only
- for cl, makes the mingw cross compiler work out of the box and
- should help mingw users on windows with a common install dir
-
- Alex
-
-2007-08-02 09:37 king
-
- * Source/: cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx: ENH: Simplify makefile target
- generator listing of object files to clean.
-
-2007-08-02 08:24 alex
-
- * Source/cmExtraEclipseCDT4Generator.cxx:
- COMP: fix warning
-
- Alex
-
-2007-08-01 23:12 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-08-01 17:10 alex
-
- * Source/: cmInstallCommand.cxx, cmTryRunCommand.cxx:
- ENH: if no COMPONENT is specified, make this install item part of
- the "Unspecified" component -> if no components are used at all,
- no change in behaviour, if components are used completely, no
- change in behaviour, since this default will be overridden
- everywhere, if components where used partly, it is now possible
- to install only the unspecified items (e.g. everything which
- wasn't marked as "Development")
-
- Alex
-
- Alex
-
-2007-08-01 16:15 david.cole
-
- * Tests/Framework/: bar.cxx, foo.cxx: BUG: Fix test that broke on
- Windows - sharing sources between SHARED and STATIC libraries
- requires correct export and import decorations in the source
- code...
-
-2007-08-01 15:25 king
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio6Generator.h,
- cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h, cmLocalXCodeGenerator.cxx,
- cmLocalXCodeGenerator.h: ENH: Moved GetTargetDirectory method up
- to cmLocalGenerator. This provides a common interface to
- something that was implemented in most local generators anyway.
-
-2007-08-01 14:58 alex
-
- * Source/: cmExtraCodeBlocksGenerator.cxx, cmake.cxx: BUG: also
- offer the extra generators in CMakeSetup
-
- Alex
-
-2007-08-01 13:04 david.cole
-
- * Source/cmGlobalXCodeGenerator.cxx, Source/cmLocalGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.cxx, Source/cmTarget.cxx,
- Tests/Framework/CMakeLists.txt: BUG: Only pay attention to the
- FRAMEWORK target property for SHARED library targets
-
-2007-08-01 11:59 alex
-
- * Source/cmTryRunCommand.cxx:
- STYLE: some more tuning for the comment text
-
- Alex
-
-2007-08-01 11:50 alex
-
- * Source/cmExtraEclipseCDT4Generator.cxx:
- ENH: works also with nmake, tested by Jeff
-
- Alex
-
-2007-08-01 11:39 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: Do not recognize
- preprocessor definition flags for the linker which has no
- preprocessor but does have flags starting with /D.
-
-2007-08-01 11:36 king
-
- * Source/cmTarget.cxx: BUG: <CONFIG>_LOCATION property should use
- the config name in the directory and not $(OutDir). This
- addresses bug#5363.
-
-2007-08-01 10:53 king
-
- * Source/cmGeneratedFileStream.h: COMP: Fix warning about not being
- able to automatically generate a copy constructor.
-
-2007-08-01 10:07 alex
-
- * Source/kwsys/DynamicLoader.cxx:
- COMP: also build the static dummy loader on Cray Catamount
-
- Alex
-
-2007-08-01 09:18 alex
-
- * Source/: CMakeLists.txt, cmExtraEclipseCDT4Generator.cxx,
- cmExtraEclipseCDT4Generator.h, cmake.cxx:
- ENH: add Eclipse CDT4 generator, patch from Miguel A.
- Figueroa-Villanueva
-
- Alex
-
-2007-08-01 09:14 alex
-
- * Modules/Platform/Catamount.cmake:
- ENH: add support for Catamount, the OS running on the compute
- nodes of Cray super computers
-
- Alex
-
-2007-07-31 23:16 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-07-31 14:52 alex
-
- * Source/cmTryRunCommand.cxx, Tests/TryCompile/CMakeLists.txt:
- ENH: add tests for check_c_source_runs(),
- check_cxx_source_runs(), check_c_source_compiles() and
- check_cxx_source_compiles() -TRY_RUN in crosscompiling mode: copy
- the created executables to CMAKE_BINARY_DIR so the user can run
- them manually on the target
-
- Alex
-
-2007-07-31 13:30 alex
-
- * Modules/: CheckCSourceRuns.cmake, CheckCXXSourceRuns.cmake,
- FindThreads.cmake:
- STYLE: don't use FIND_INCLUDE_FILE() but only
- FIND_INCLUDE_FILES() in FindThreads.h
-
- BUG: improve CheckC(XX)SourceRuns.cmake so that it works with
- cross compiling, the return value has to go in the cache but
- shouldn't overwrite the actual return value, and it should go
- only in the cache if we have a result from try_run() otherwise we
- won't get here again if we have a result later on
-
- Alex
-
-2007-07-31 11:23 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: fix DLL and DEF
- being lost and add real support for /DEF: /DLL does not have an
- entry so just let it pass to advanced command line
-
-2007-07-30 23:07 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-07-30 22:51 hoffman
-
- * Source/: cmSystemTools.cxx, CPack/cmCPackTGZGenerator.cxx,
- CPack/cmCPackTarCompressGenerator.cxx: ENH: use gnu tar for
- cygwin
-
-2007-07-30 21:38 hoffman
-
- * Source/cmXMLParser.cxx: STYLE: fix warning
-
-2007-07-30 15:52 alex
-
- * Source/kwsys/DynamicLoader.cxx:
- COMP: add a dynamic loader for systems which don't support
- dynamic loading, so this is handled in kwsys and not every
- project using this has to care for it
-
- Alex
-
-2007-07-30 14:46 alex
-
- * Source/cmTryRunCommand.cxx:
- ENH: FORCE the values in the cache, otherwise the file is useless
-
- Alex
-
-2007-07-29 23:13 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-07-28 23:32 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-07-28 00:33 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-07-27 13:12 alex
-
- * Source/CPack/cmCPackDebGenerator.cxx:
- STYLE: fix line length
-
- Alex
-
-2007-07-27 11:57 alex
-
- * Modules/Platform/: UnixPaths.cmake, WindowsPaths.cmake:
- ENH: -add /usr/openwin/include and /usr/openwin/lib to the
- default search paths -add
- /${CMAKE_INSTALL_PREFIX}/(lib|bin|include) to the default cmake
- search paths -> this should help users who install stuff in their
- home
-
- Alex
-
-2007-07-27 10:55 hoffman
-
- * Source/: cmCommandArgumentLexer.h, cmCommandArgumentParser.cxx,
- cmCommandArgumentParserTokens.h, cmConfigure.cmake.h.in,
- cmCoreTryCompile.cxx, cmDependsFortranLexer.h,
- cmDependsJavaLexer.h, cmExprLexer.h, cmXCodeObject.cxx,
- cmXCodeObject.h, cmaketest.h.in, cmakexbuild.cxx,
- CPack/OSXScriptLauncher.cxx, CPack/cmCPackConfigure.h.in,
- CPack/cmCPackGenerators.cxx, CPack/cmCPackZIPGenerator.cxx,
- CPack/cpack.cxx, CTest/cmCTestCoverageHandler.cxx,
- CTest/cmCTestMemCheckHandler.cxx: STYLE: fix some kwstyle errors
-
-2007-07-27 08:59 alex
-
- * CMakeCPack.cmake, Source/cmSetPropertiesCommand.h,
- Source/cmake.cxx, Source/cmake.h, Modules/CPackDeb.cmake,
- Modules/FindPythonLibs.cmake,
- Source/CPack/cmCPackDebGenerator.cxx, Source/CPack/cpack.cxx,
- Source/CTest/cmCTestScriptHandler.cxx:
- ENH: deb generator can now generate deb packages -remove the
- unscriptable commands also from the cpack cmake -use
- CPACK_PACKAGE_CONTACT in CMakeCPack.cmake, it's used in the nsis
- and the deb generator -make set_properties() scriptable -use a
- non-const char array for adding the python modules
-
- Alex
-
-2007-07-27 04:22 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-07-26 16:38 hoffman
-
- * Source/CTest/cmCTestMemCheckHandler.cxx: ENH: add test output to
- valgrind output and truncate output for valgrind
-
-2007-07-26 14:36 hoffman
-
- * Source/: cmXMLParser.cxx, cmXMLParser.h: ENH: fix warning on
- win64
-
-2007-07-26 11:21 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-07-26 08:40 alex
-
- * Source/: cmTryRunCommand.cxx, CPack/cmCPackGenerators.cxx,
- CPack/cmCPackZIPGenerator.cxx, CPack/cpack.cxx:
- STYLE: fix line lengths
-
- Alex
-
-2007-07-26 00:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-07-25 16:37 hoffman
-
- * Source/CTest/cmCTestTestHandler.cxx: ENH: fix bug with valgrind
- output being truncated
-
-2007-07-25 15:08 alex
-
- * Modules/FindPythonLibs.cmake:
- COMP: same as in VTK, build modules by default as shared if the
- platform supports this, don't include shared modules in the
- generated header
-
- Alex
-
-2007-07-25 13:08 alex
-
- * Source/CPack/: cmCPackDebGenerator.cxx, cmCPackGenerators.cxx:
- ENH: apply patch from Mathieu which creates a deb file (not
- finishsed yet)
-
- Alex
-
-2007-07-25 11:41 alex
-
- * Source/CPack/cmCPackDebGenerator.cxx:
- COMP: silence warnings
-
- Alex
-
-2007-07-25 10:57 alex
-
- * Modules/CPackDeb.cmake, Source/CMakeLists.txt, Source/cmake.cxx,
- Source/CPack/cmCPackDebGenerator.cxx,
- Source/CPack/cmCPackDebGenerator.h,
- Source/CPack/cmCPackGenerators.cxx:
- ENH: add an empty debian package generator, Mathieu volunteered
- to fill it :-)
-
- Alex
-
-2007-07-25 09:22 hoffman
-
- * Source/: cmXMLParser.cxx, cmXMLParser.h: STYLE: fix compiler
- warning
-
-2007-07-25 04:18 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-07-24 15:55 hoffman
-
- * Source/cmWin32ProcessExecution.cxx: ENH: fix resource leak
-
-2007-07-24 15:27 hoffman
-
- * DartLocal.conf.in: ENH: clean up some missing dashboards
-
-2007-07-24 14:50 alex
-
- * Source/kwsys/ProcessUNIX.c:
- COMP: sync with HEAD
-
- Alex
-
-2007-07-24 14:43 hoffman
-
- * Source/CTest/: cmCTestMemCheckHandler.cxx,
- cmCTestMemCheckHandler.h, cmCTestTestHandler.h: ENH: add support
- for bounds checker
-
-2007-07-24 14:14 alex
-
- * Source/kwsys/DynamicLoader.cxx:
- ENH: disable dynamic loader if shared libraries are not supported
- instead of hacking around it
-
- Alex
-
-2007-07-24 12:52 alex
-
- * Source/CPack/cmCPackGenericGenerator.cxx,
- Source/CPack/cmCPackGenericGenerator.h,
- Source/CPack/cmCPackZIPGenerator.cxx,
- Source/CPack/cmCPackZIPGenerator.h, Modules/CPackZIP.cmake,
- Modules/Platform/BlueGeneL.cmake:
- ENH: add ReadListFile() to cmCPackGenericGenerator, so cmMakefile
- can be private again -convert the ZIP generator to use a cmake
- script instead of hardcoding everything (CPackZIP.cmake)
-
- Alex
-
-2007-07-24 10:05 hoffman
-
- * Source/kwsys/ProcessWin32.c: ENH: fix resource leak
-
-2007-07-24 10:00 alex
-
- * Modules/CMakeDetermineSystem.cmake,
- Source/CPack/cmCPackGenericGenerator.cxx,
- Source/CPack/cmCPackGenericGenerator.h, Source/CPack/cpack.cxx:
- ENH: determine the current system also in cpack, so the search
- paths are loaded Additionally the makefile in
- cmCPackGenericGenerator is now protected instead of private, so
- with these two changes the cpack generators should now be able to
- find their tools and how to call these tools from cmake scripts,
- instead of hardcoding the search order and command line (as done
- e.g. in cmCPackZIPGenerator.cxx)
-
- Alex
-
-2007-07-24 02:28 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-07-23 13:13 alex
-
- * Source/cmTryRunCommand.cxx:
- STYLE: put a lot of comments into the generated cmake-cache
- preloading file to aid the user with using it
-
- Alex
-
-2007-07-23 11:22 alex
-
- * Modules/FindPythonInterp.cmake:
- STYLE: mark the variable as advanced
-
- Alex
-
-2007-07-23 10:47 alex
-
- * Source/cmTryRunCommand.cxx:
- ENH: try to create a file which can be used for presetting the
- cache values of the TRY_RUN() results when crosscompiling
-
- Alex
-
-2007-07-23 09:49 alex
-
- * Modules/: FindASPELL.cmake, FindBZip2.cmake, FindBoost.cmake,
- FindCURL.cmake, FindCurses.cmake, FindEXPAT.cmake,
- FindGnuplot.cmake, FindHSPELL.cmake, FindJPEG.cmake,
- FindJasper.cmake, FindLibXml2.cmake, FindLibXslt.cmake,
- FindMPEG.cmake, FindMPEG2.cmake, FindMotif.cmake,
- FindOpenAL.cmake, FindPNG.cmake,
- FindPackageHandleStandardArgs.cmake, FindPerl.cmake,
- FindPerlLibs.cmake, FindPhysFS.cmake, FindPythonInterp.cmake,
- FindPythonLibs.cmake, FindSDL.cmake, FindTCL.cmake,
- FindTIFF.cmake, FindTclsh.cmake, FindWget.cmake, FindZLIB.cmake:
- ENH: add second failure message parameter to
- FIND_PACKAGE_HANDLE_STANDARD_ARGS(), so cmake modules can specify
- their own better failure messages. If the default is ok use
- "DEFAULT_MSG". Do this also for FindBoost.cmake (#5349)
-
- Alex
-
-2007-07-23 09:06 alex
-
- * Source/: cmLocalGenerator.cxx, kwsys/SystemTools.cxx:
- PERF: micro optimization: the (*pos1) && (*pos1=='/') were
- redundant, and hasDoubleSlash is false in most cases, so in most
- cases 3 comparisons were done, now only one
-
- Alex
-
-2007-07-23 00:41 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-07-21 23:26 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-07-20 22:46 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-07-20 16:31 alex
-
- * Utilities/KWStyle/CMakeFiles.txt.in:
- ENH: add quotes around the file names, so kwstyle can handle it
- if there are spaces in the path
-
- Alex
-
-2007-07-20 14:08 hoffman
-
- * Source/cmCommandArgumentParser.cxx, Tests/Complex/CMakeLists.txt,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexRelativePaths/CMakeLists.txt: ENH: user more memory
- for parser and add test to complex that sets a huge string
-
-2007-07-20 13:03 hoffman
-
- * Source/CTest/cmCTestCoverageHandler.cxx: ENH: fix div by 0
-
-2007-07-20 12:25 hoffman
-
- * Utilities/cmcurl/CMake/OtherTests.cmake: ENH: change order so
- windows functions are found first since try compile is slow on
- windows
-
-2007-07-20 10:07 hoffman
-
- * DartLocal.conf.in: ENH: change name
-
-2007-07-20 08:48 alex
-
- * Source/cmMakefile.cxx:
- STYLE: even more output when --debug-output is used
-
- Alex
-
-2007-07-20 08:36 alex
-
- * Source/: cmDocumentation.cxx, cmExportCommand.h,
- cmExtraCodeBlocksGenerator.cxx, cmExtraCodeBlocksGenerator.h,
- cmFileCommand.cxx, cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmHexFileConverter.cxx, cmIncludeExternalMSProjectCommand.cxx,
- cmMakefile.cxx, cmMakefile.h, cmTryCompileCommand.h,
- cmTryRunCommand.h, cmake.h, CTest/cmCTestScriptHandler.cxx:
- STYLE: fix line lengths
-
- Alex
-
-2007-07-19 21:02 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-07-19 15:39 alex
-
- * Modules/CPack.STGZ_Header.sh.in:
- ENH: try if tail works with the -n +<number> syntax, if not use
- only "+<number>" (GNU tail warns that this is deprecated)
-
- Alex
-
-2007-07-19 13:40 alex
-
- * Modules/FindTCL.cmake:
- ENH: add TK_FOUND and TCLTK_FOUND TCL_FOUND is now TRUE if Tcl
- was found, before it was only TRUE if Tcl and Tk were found
-
- Alex
-
-2007-07-19 11:59 alex
-
- * Modules/FindPythonLibs.cmake:
- BUG: fix typo
-
- Alex
-
-2007-07-19 11:47 alex
-
- * Modules/FindPythonLibs.cmake:
- ENH: make the list of modules global
-
- Alex
-
-2007-07-19 11:13 alex
-
- * Source/: cmFindPackageCommand.h, cmMakefile.cxx, cmakemain.cxx,
- CPack/cpack.cxx:
- STYLE: fix some typos, nicer debug output
-
- Alex
-
-2007-07-19 10:20 alex
-
- * Modules/FindPythonLibs.cmake:
- ENH: only load the static modules in the LoadAll function
-
- Alex
-
-2007-07-19 09:42 alex
-
- * Modules/: CPack.STGZ_Header.sh.in, FindPHP4.cmake:
- BUG: fix #5329, if /usr/xpg4/bin/tail exists, use this one -> on
- SunOS /usr/bin/tail doesn't understand the -n +<number> syntax
- -remove standard searchd dirs from FindPHP4.cmake
-
- Alex
-
-2007-07-19 09:00 alex
-
- * Modules/: FindASPELL.cmake, FindCURL.cmake, FindCurses.cmake,
- FindDCMTK.cmake, FindEXPAT.cmake, FindGLUT.cmake, FindGTK.cmake,
- FindGnuplot.cmake, FindHSPELL.cmake, FindMPEG.cmake,
- FindMPEG2.cmake, FindMotif.cmake, FindPerl.cmake,
- FindPhysFS.cmake, FindPike.cmake, FindPythonLibs.cmake,
- FindSDL.cmake, FindTCL.cmake, FindTclsh.cmake, FindWget.cmake,
- readme.txt:
- ENH: use the new FIND_PACKAGE_HANDLE_STANDARD_ARGS() macro in
- most of the not-too-complicated modules -remove unnecessary
- default search paths used in the FIND_XXX() calls
-
- Alex
-
-2007-07-18 14:38 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-07-18 13:56 alex
-
- * Modules/: FindBZip2.cmake, FindCups.cmake, FindJPEG.cmake,
- FindJasper.cmake, FindLibXslt.cmake, FindOpenAL.cmake,
- FindPNG.cmake, FindPerlLibs.cmake, FindPythonInterp.cmake,
- FindTCL.cmake, FindTIFF.cmake, FindZLIB.cmake:
- ENH: use the new FIND_PACKAGE_HANDLE_STANDARD_ARGS in some of the
- FindXXX modules, remove some of the extra search paths which are
- also searched by default
-
- Alex
-
-2007-07-18 13:26 alex
-
- * Modules/: CMakeLists.txt, FindLibXml2.cmake,
- FindPackageHandleStandardArgs.cmake, FindPythonLibs.cmake:
- ENH: add a macro FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2
- LIBXML2_LIBRARIES LIBXML2_INCLUDE_DIR) which handles the required
- and QUIET arguments and sets <NAME>_FOUND
-
- Alex
-
-2007-07-18 10:52 alex
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeDetermineCXXCompiler.cmake:
- ENH: if CMAKE_(C|CXX)_COMPILER is preset to a list of two
- elements, use the first one as the compiler and the second one as
- ARG1 for the compiler
-
- Alex
-
-2007-07-18 10:19 alex
-
- * Source/: CMakeLists.txt, cmExtraCodeBlocksGenerator.cxx,
- cmake.cxx:
- ENH: build codeblocks generator also on Windows
-
- Alex
-
-2007-07-17 13:43 hoffman
-
- * Source/cmAddCustomCommandCommand.h: STYLE: add more docs
-
-2007-07-17 13:10 alex
-
- * Source/cmakemain.cxx:
- COMP: fix warning about unused variable
-
- Alex
-
-2007-07-17 12:01 alex
-
- * Source/: cmake.cxx, cmakemain.cxx:
- COMP: fix build on Windows, where GetCurrentDirecty() is
- redefined to GetCurrentDirectoryA() -correct return value for
- md5sum
-
- Alex
-
-2007-07-17 10:44 alex
-
- * Source/: cmLocalGenerator.cxx, cmake.cxx, cmakemain.cxx:
- STYLE: fix line lengths and add "remove -f" to the docs
-
- Alex
-
-2007-07-17 09:25 alex
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmLocalGenerator.cxx, cmMakefile.cxx, cmMessageCommand.cxx,
- cmakemain.cxx:
- ENH: produce a lot more output when running with --debug-output
- -try to fix build error on HPUX
-
- Alex
-
-2007-07-17 08:51 alex
-
- * Modules/Platform/WindowsPaths.cmake:
- ENH: also look in the include/, lib/ and bin/ directories in the
- cmake install dir under windows, this will help e.g. people using
- kdewininstaller and similar setups
-
- Alex
-
-2007-07-17 08:41 alex
-
- * Modules/: KDE3Macros.cmake, FindKDE3.cmake:
- ENH: don't hardcode the /lib/kde3/ directory for the libtool
- files, but make it adjustable and detect if libkdecore.so is a
- 64bit library
-
- Alex
-
-2007-07-16 15:10 alex
-
- * Source/cmSystemTools.cxx:
- BUG: fix bootstrapping, md5sum disabled in bootstrapping mode
-
- Alex
-
-2007-07-16 13:29 alex
-
- * Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt:
- STYLE: remove debug output
-
-2007-07-16 13:26 alex
-
- * Source/cmMakefile.cxx,
- Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt:
- BUG: GET_DIRECTORY_PROPERTY(INCLUDE_DIRECTORIES|LINK_DIRECTORIES)
- wasn't working, for both the result was always empty, since
- cmMakefile::GetProperty() recognized it as a special property,
- constructed a correct return value and called
- cmMakefile::SetProperty() with this list of directories, which
- then didn't actually set the property, but applied it to the
- internal vector of include/link directories. The following
- getPropertyValue in cmMakefile::GetProperty() then still didn't
- find it and returned nothing. Now for all special property the
- static string output is used and its content is returned. I'm not
- sure it is the right way to fix this problem but at least it
- seems to work and it fixes the Paraview3 build
-
- Alex
-
-2007-07-16 10:59 hoffman
-
- * CMakeLists.txt, Readme.txt: ENH: final 2.4.7 commit
-
-2007-07-16 10:54 alex
-
- * Source/: cmake.cxx, cmSystemTools.h, cmSystemTools.cxx:
- ENH: apply patch from Mathieu, add argument -E md5sum to compute
- md5sums of files, compatible to md5sum output
-
- Alex
-
-2007-07-16 10:54 hoffman
-
- * Readme.txt: ENH:
-
-2007-07-16 10:53 hoffman
-
- * Readme.txt: ENH: clean up a bit
-
-2007-07-16 10:13 alex
-
- * Modules/Platform/NetBSD.cmake:
- BUG: the Plugin test fails on NetBSD, let's see if this fixes it
-
- Alex
-
-2007-07-16 09:08 alex
-
- * Modules/Platform/UnixPaths.cmake:
- ENH: also add the install base dir of the running cmake to the
- search directories for the FIND_XXX() commands, for the case that
- somebody has its own install tree
-
- Alex
-
-2007-07-13 12:03 alex
-
- * Source/cmAddLibraryCommand.cxx, Utilities/CMakeLists.txt:
- STYLE: better error message, name the new manpages cmakecommands,
- cmakecompat, cmakeprops and cmakemodules
-
- Alex
-
-2007-07-13 11:20 alex
-
- * Modules/Platform/DragonFly.cmake:
- ENH: add DragonFly BSD, which is very close to FreeBSD (#4500)
-
- Alex
-
-2007-07-13 10:29 alex
-
- * Modules/: CheckCSourceRuns.cmake, CheckCXXSourceRuns.cmake:
- BUG: the SET( ... CACHE INTERNAL) didn't work as expected, since
- the variable is already added to the cache inside
- cmTryRunCommand.cxx, so the value used here was ignored.
- Additionally the INTERNAL made it internal, which shouldn't be
- done when cross compiling, since here the user is required to
- edit this variable manually e.g. using ccmake.
-
- Alex
-
-2007-07-13 00:58 alex
-
- * Source/: CMakeLists.txt, cmExtraCodeBlocksGenerator.cxx,
- cmExtraCodeBlocksGenerator.h, cmake.cxx:
- ENH: add a simple CodeBlocks extra generator, early alpha stage,
- there seems to be interest in it
-
- Alex
-
-2007-07-12 16:15 alex
-
- * Modules/Platform/BlueGeneL.cmake:
- ENH: add the static libs always to the link libs, if they are not
- used it shouldn't hurt
-
- Alex
-
-2007-07-12 15:00 alex
-
- * Modules/: CMakeLists.txt, CheckStructHasMember.cmake:
- ENH: add macro to test if a member has specified struct, e.g.
- check_struct_has_member("struct stat" st_rdev "${CFG_HEADERS}"
- HAVE_STRUCT_STAT_ST_RDEV)
-
- Alex
-
-2007-07-12 13:41 alex
-
- * Modules/: CMakeCCompilerId.c, CMakeCXXCompilerId.cpp,
- Platform/Generic-ADSP-ASM.cmake, Platform/Generic-ADSP-C.cmake,
- Platform/Generic-ADSP-CXX.cmake,
- Platform/Generic-ADSP-Common.cmake:
- ENH: add support for the ADSP toolchains for Blackfin, Shark and
- TigerShark DSPs, patch from Raphael Cotty
-
- Alex
-
-2007-07-12 11:56 alex
-
- * Source/cmListCommand.cxx, Source/cmListCommand.h,
- Tests/CMakeTests/ListTest.cmake.in:
- ENH: add LIST(CONTAINS ...) patch from "Miguel A.
- Figueroa-Villanueva, miguelf (AT) ieee.org added tests for
- LIST(CONTAINS, SORT, REVERSE)
-
- Alex
-
-2007-07-12 11:05 alex
-
- * Modules/FindCURL.cmake:
- BUG: honor REQUIRED and QUIETLY (#5312)
-
- Alex
-
-2007-07-12 10:38 alex
-
- * Readme.txt:
- STYLE: add Readme.txt with instructions how to build cmake, fix
- #5296
-
- Alex
-
-2007-07-12 10:17 martink
-
- * Source/cmGetDirectoryPropertyCommand.cxx: BUG: fix screwup in
- GetDirectoryProp...
-
-2007-07-12 08:37 alex
-
- * Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmTarget.cxx, Modules/CMakeASMCompiler.cmake.in,
- Modules/CMakeCCompiler.cmake.in,
- Modules/CMakeCXXCompiler.cmake.in,
- Modules/CMakeForceCompiler.cmake,
- Modules/CMakeFortranCompiler.cmake.in,
- Modules/CMakeJavaCompiler.cmake.in: ENH: second try for handling
- the linker language with integer priority values (returning a
- pointer to a string on the stack is no good idea)
-
- Alex
-
-2007-07-11 17:29 alex
-
- * Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmTarget.cxx, Modules/CMakeASMCompiler.cmake.in,
- Modules/CMakeCCompiler.cmake.in,
- Modules/CMakeCXXCompiler.cmake.in,
- Modules/CMakeForceCompiler.cmake,
- Modules/CMakeFortranCompiler.cmake.in,
- Modules/CMakeJavaCompiler.cmake.in: COMP: revert last commit for
- now, broke Visual Studio
-
- Alex
-
-2007-07-11 16:22 alex
-
- * Modules/CMakeASMCompiler.cmake.in,
- Modules/CMakeCCompiler.cmake.in,
- Modules/CMakeCXXCompiler.cmake.in,
- Modules/CMakeForceCompiler.cmake,
- Modules/CMakeFortranCompiler.cmake.in,
- Modules/CMakeJavaCompiler.cmake.in, Modules/CMakeLists.txt,
- Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmTarget.cxx:
- ENH: CMAKE_<LANG>_LINKER_PREFERENCE is now an integer priority,
- not a two-step priority (None or Prefered) Current order: ASM 0,
- C 10, Fortran 20, CXX 30, Java 40 This is the same order as
- automake choses:
- http://www.gnu.org/software/automake/manual/html_node/How-the-Linker-is-Chosen.html
-
- This change should be backward compatible: if there is a project
- using fortran and CXX, they had to set the LINKER_LANGUAGE
- explicitely, otherwise cmake complained (but still generated the
- project files). Explicitely setting the linker language still
- overrides automatic detection. If somebody has a custom language
- for cmake and the PREFERENCE starts with "P", its changed to 100,
- which gives it preference over all other languages (except the
- other custom languages which have also "Prefered"). "None" is
- converted to 0.
-
- Alex
-
-2007-07-11 15:53 alex
-
- * Source/: cmDocumentation.cxx, cmDocumentation.h,
- cmPropertyDefinition.cxx, cmPropertyDefinition.h, cmake.cxx,
- cmake.h, cmakemain.cxx:
- STYLE: sort the property documentation into
- global/directory/target/test/sourcefile and variable sections
-
- Alex
-
-2007-07-11 15:50 alex
-
- * Source/cmMakefile.cxx:
- ENH: change the way #cmakedefine is changed to #undef, so it is
- similar to what autoconf does. This makes porting software from
- autoconf to cmake easier, since it's easier to diff the resulting
- config headers.
-
- Now the following #cmakedefine HAVE_STRING_H 1 #cmakedefine
- HAVE_STRLCAT 1
-
- produce:
-
- #define HAVE_STRING_H 1 /* #undef HAVE_STRLCAT */
-
- whereas before they produced:
-
- #define HAVE_STRING_H 1 /* #undef HAVE_STRLCAT 1 */
-
- Since it's commented out anyway, it's now change in behaviour.
-
- Alex
-
-2007-07-11 13:39 alex
-
- * Modules/CMakeASMInformation.cmake:
- ENH: add CMAKE_INCLUDE_FLAG_ASM${ASM_DIALECT} and don't allow
- preset CMAKE_xxx_INFORMATION files
-
- Alex
-
-2007-07-10 21:38 alex
-
- * Modules/FindKDE4.cmake:
- STYLE: use EXECUTE_PROCESS() instead of EXEC_PROGRAM()
-
- Alex
-
-2007-07-10 17:11 alex
-
- * Modules/Platform/eCos.cmake:
- ENH: add the ecos include dir and the ecos definitions by default
-
- Alex
-
-2007-07-10 14:05 martink
-
- * Source/cmGetSourceFilePropertyCommand.cxx: ENH: added some
- documentation to explain a section of code a bit better
-
-2007-07-10 13:52 martink
-
- * Source/: cmMakefile.cxx, cmGetDirectoryPropertyCommand.cxx: ENH:
- some cleanup of get property commands
-
-2007-07-09 14:30 king
-
- * Source/cmLocalVisualStudioGenerator.h: STYLE: Removed stray
- comment.
-
-2007-07-09 13:07 alex
-
- * Modules/Platform/eCos.cmake:
- ENH: add support for building eCos applications natively
-
- Alex
-
-2007-07-09 08:16 alex
-
- * Tests/Assembler/main.c: COMP: hopefully fix test, finally
-
- Alex
-
-2007-07-09 05:50 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-07-09 00:44 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-07-08 22:06 alex
-
- * Tests/Assembler/main.c: COMP: fix test
-
- Alex
-
-2007-07-07 17:23 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-07-06 19:09 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-07-06 14:02 alex
-
- * Tests/Assembler/CMakeLists.txt:
- BUG: fix test
-
- Alex
-
-2007-07-06 13:08 alex
-
- * Utilities/CMakeLists.txt:
- BUG: the cmake deps depend on cmake
-
- Alex
-
-2007-07-06 08:53 alex
-
- * Tests/Assembler/: CMakeLists.txt, main.c:
- COMP: OPTIONAL was missing in ENABLE_LANGUAGE() -the assembler
- file seems to work for Linux and FreeBSD -try to fix main() for
- HP-UX compiler
-
- Alex
-
-2007-07-05 16:38 alex
-
- * Tests/Assembler/CMakeLists.txt:
- STYLE: some more output
-
- Alex
-
-2007-07-05 16:32 alex
-
- * Tests/Assembler/: CMakeLists.txt, main-linux-x86-gas.s:
- COMP: skip APPLE, since there with universal binaries the
- assembler file would be built for both architectures
-
- Alex
-
-2007-07-05 16:11 alex
-
- * Tests/Assembler/CMakeLists.txt:
- COMP: let's see if this assembler file works also on other
- platforms than linux...
-
- Alex
-
-2007-07-05 15:50 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-07-05 09:05 alex
-
- * Tests/: CMakeLists.txt, Assembler/CMakeLists.txt,
- Assembler/main-linux-x86-gas.s, Assembler/main.c:
- ENH: add a simple assembler test
-
- Alex
-
-2007-07-04 08:21 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-07-03 16:10 alex
-
- * Source/: cmCommandArgumentsHelper.cxx,
- cmExternalMakefileProjectGenerator.cxx, cmake.cxx:
- STYLE: name the external generator "KDevelop3 - Unix Makefiles"
- instead of "Unix Makefiles - KDevelop3" -initialize Ignore to 0,
- crashes otherwise
-
- Alex
-
-2007-07-03 11:41 alex
-
- * Modules/FindOpenGL.cmake:
- STYLE: don't test twice for APPLE
-
- Alex
-
-2007-07-03 09:45 king
-
- * DartLocal.conf.in: ENH: Adding hythloth expected nightly
- submissions.
-
-2007-07-03 08:26 alex
-
- * Source/: cmDocumentation.cxx, cmDocumentation.h:
- COMP: fix compile on HP-UX with aCC, reusing the same identifier
- for a variable as for the enum type doesn't work here
-
- Alex
-
-2007-07-03 03:58 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-07-02 16:46 alex
-
- * Source/: cmCommandArgumentsHelper.cxx, cmExportCommand.cxx:
- COMP: fix warnings
-
- Alex
-
-2007-07-02 16:04 king
-
- * Source/: cmFileCommand.cxx, cmFileCommand.h: COMP: Remove unused
- argument.
-
-2007-07-02 16:04 king
-
- * Source/cmInstallTargetGenerator.cxx: COMP: Remove shadowed local.
-
-2007-07-02 15:54 alex
-
- * Modules/CMakeFindBinUtils.cmake:
- COMP: with visual studio it's no error if link isn't found
-
- Alex
-
-2007-07-02 15:43 alex
-
- * Source/: cmBootstrapCommands.cxx, cmCommand.h,
- cmCommandArgumentsHelper.cxx, cmCommandArgumentsHelper.h,
- cmExportCommand.cxx, cmExportCommand.h:
- ENH: add framework for unified handling of arguments to cmake
- commands, example see cmExportCommand.cxx
-
- Alex
-
-2007-07-02 14:56 king
-
- * Source/: cmFileCommand.cxx, cmFileCommand.h,
- cmInstallCommand.cxx, cmInstallDirectoryGenerator.cxx,
- cmInstallDirectoryGenerator.h, cmInstallExportGenerator.cxx,
- cmInstallExportGenerator.h, cmInstallFilesGenerator.cxx,
- cmInstallFilesGenerator.h, cmInstallGenerator.cxx,
- cmInstallGenerator.h, cmInstallScriptGenerator.cxx,
- cmInstallTargetGenerator.cxx, cmInstallTargetGenerator.h: ENH:
- Further cleanup of installation script generation. The
- per-component and per-configuration testing is now done in cmake
- code instead of in the FILE(INSTALL) command. The generation of
- the cmake code to do these tests is centralized in
- cmInstallGenerator. Old-style shared library versioning and
- component/config support code has been removed from
- FILE(INSTALL). This commit is surrounded by the tags
- CMake-InstallGeneratorCleanup2-pre and
- CMake-InstallGeneratorCleanup2-post.
-
-2007-07-02 14:18 alex
-
- * Modules/CMakeForceCompiler.cmake:
- ENH: make supporting embedded compilers need a user specific
- linker file for compiling an executable (amd thus cannot build
- the compiler-id program) easier by providing CMAKE_FORCE_XXX()
- macros which force cmake to use the given compilers anyway
-
- Alex
-
-2007-07-02 13:32 king
-
- * Source/: cmTarget.cxx, cmTarget.h: STYLE: Fixed line-too-long,
- fixed indentation, removed trailing whitespace, added function
- separator comment lines.
-
-2007-07-02 13:29 alex
-
- * Modules/CMakeCInformation.cmake,
- Modules/CMakeCXXInformation.cmake,
- Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Modules/CMakeSystemSpecificInformation.cmake,
- Tests/CMakeTests/DummyToolchain.cmake,
- Tests/CMakeTests/ToolchainTest.cmake.in:
- ENH: remove support for presetting CMAKE_SYSTEM_INFO_FILE,
- CMAKE_SYSTEM_AND_C_COMPILER_INFO_FILE,
- CMAKE_SYSTEM_AND_CXX_COMPILER_INFO_FILE,
- CMAKE_SYSTEM_AND_C_COMPILER_AND_PROCESSOR_INFO_FILE and
- CMAKE_SYSTEM_AND_CXX_COMPILER_AND_PROCESSOR_INFO_FILE
-
- Instead of presetting these variables to arbitrary filenames,
- users should set up CMAKE_SYSTEM_NAME and the compilers correctly
- and also create a Platform/ directory so these files will all
- follow the official cmake style, which should make it easier to
- understand and debug project which have their own
- platform/toolchain support files.
-
- -remove support for a suffix to MS crosscompilers, since this is
- not (yet) supported by cmake and might confuse users
-
- Alex
-
-2007-07-02 12:46 alex
-
- * Modules/CMakeFindBinUtils.cmake:
- BUG: with MS Visual Studio currently there is no compiler id, so
- check the generator too
-
- Alex
-
-2007-07-02 11:31 king
-
- * Source/cmInstallTargetGenerator.cxx: BUG: Fix install_name_tool
- update of the executable in an installed bundle on OSX. This
- addresses bug#4534.
-
-2007-07-02 11:24 alex
-
- * Source/cmDocumentation.h:
- COMP: fix build with msvc 6, the enums are now part of a class
- which is already completely parsed
-
- Alex
-
-2007-07-02 11:05 alex
-
- * Utilities/CMakeLists.txt:
- BUG: fix build with cmake < 2.4
-
- Alex
-
-2007-07-02 11:02 king
-
- * Source/: cmInstallGenerator.cxx, cmInstallGenerator.h,
- cmInstallTargetGenerator.cxx, cmInstallTargetGenerator.h: ENH:
- Improved indentation of generated cmake_install.cmake code.
-
-2007-07-02 09:58 king
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ENH: Enable versioned executable
- test everywhere but XCode.
-
-2007-07-01 22:55 hoffman
-
- * Source/: cmCommandArgumentParserHelper.cxx,
- cmCommandArgumentParserHelper.h: COMP: fix warning in release
- branch
-
-2007-07-01 16:53 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-30 22:33 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-30 21:06 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-29 16:29 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-29 12:58 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/Platform/Linux.cmake,
- Source/cmCommandArgumentParserHelper.cxx,
- Source/cmCommandArgumentParserHelper.h, Source/cmFileCommand.cxx,
- Source/cmFileCommand.h, Source/cmLocalGenerator.cxx,
- Source/cmMakefile.cxx, Source/cmMakefile.h, Source/cmake.cxx,
- Tests/StringFileTest/InputFile.h.in,
- Tests/StringFileTest/StringFile.cxx: ENH: RC 11
-
-2007-06-29 11:30 hoffman
-
- * DartLocal.conf.in: ENH: remove more machines
-
-2007-06-29 11:18 hoffman
-
- * CMakeLists.txt, DartLocal.conf.in: ENH: make DartLocal.conf part
- of project
-
-2007-06-28 16:11 king
-
- * Source/: cmInstallDirectoryGenerator.cxx,
- cmInstallExportGenerator.cxx, cmInstallFilesGenerator.cxx,
- cmInstallGenerator.cxx, cmInstallGenerator.h,
- cmInstallTargetGenerator.cxx, cmInstallTargetGenerator.h: ENH:
- First step of install script generator cleanup. Each
- configuration to be installed is now separately handled instead
- of using variables to store per-configuration names. For targets
- the component and configuration install-time tests are now done
- in the install script instead of in the FILE(INSTALL) command.
- This cleans things up like not trying to strip a file that was
- optionally not installed. It also simplifies the code for
- install_name adjustment on OSX. This commit is surrounded by the
- tags CMake-InstallGeneratorCleanup1-pre and
- CMake-InstallGeneratorCleanup1-post.
-
-2007-06-28 15:28 alex
-
- * Source/cmGlobalGenerator.cxx:
- COMP: fix warning about unused parameter
-
- Alex
-
-2007-06-28 15:04 alex
-
- * Source/cmDocumentation.cxx, Source/cmDocumentation.h,
- Source/cmakemain.cxx, Utilities/CMakeLists.txt:
- ENH: generate separate documentation for the commands,
- compatiblity commands, modules and properties as html, text and
- man pages. The names of the man pages are cmcommands, cmcompat,
- cmprops and cmmodules, so they are easy to type.
-
- Alex
-
-2007-06-28 13:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-28 11:00 alex
-
- * Source/cmDocumentation.cxx, Source/cmDocumentation.h,
- Source/cmDumpDocumentation.cxx, Source/cmakemain.cxx,
- Source/CursesDialog/ccmake.cxx, Utilities/CMakeLists.txt:
- ENH: -in the full documentation there is now an extra section for
- compatibility commands, so users see which commands they
- shouldn't use -cmake -h <command> now also works with lower case
- commands --help-fullm --help-command, --help-module and
- --help-property now determine the output format from the
- extension of the given filename
-
- Let me know if there are some things I overlooked.
-
- Alex
-
-2007-06-28 10:22 alex
-
- * Source/cmGlobalVisualStudio6Generator.cxx:
- COMP: fix typo
-
- Alex
-
-2007-06-28 09:14 alex
-
- * Modules/: CMakeASM-ATTInformation.cmake,
- CMakeASMCompiler.cmake.in, CMakeASMInformation.cmake,
- CMakeDetermineASM-ATTCompiler.cmake,
- CMakeDetermineASMCompiler.cmake, CMakeTestASM-ATTCompiler.cmake,
- CMakeTestASMCompiler.cmake, Platform/gas.cmake:
- ENH: initial support for assembler in cmake, needs testing by our
- users
-
- Alex
-
-2007-06-28 09:09 alex
-
- * Source/: cmGlobalBorlandMakefileGenerator.cxx,
- cmEnableLanguageCommand.cxx, cmEnableLanguageCommand.h,
- cmGlobalBorlandMakefileGenerator.h, cmGlobalGenerator.cxx,
- cmGlobalGenerator.h, cmGlobalMSYSMakefileGenerator.cxx,
- cmGlobalMSYSMakefileGenerator.h,
- cmGlobalMinGWMakefileGenerator.cxx,
- cmGlobalMinGWMakefileGenerator.h,
- cmGlobalNMakeMakefileGenerator.cxx,
- cmGlobalNMakeMakefileGenerator.h,
- cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio6Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h,
- cmGlobalVisualStudio8Win64Generator.cxx,
- cmGlobalVisualStudio8Win64Generator.h,
- cmGlobalWatcomWMakeGenerator.cxx, cmGlobalWatcomWMakeGenerator.h,
- cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h,
- cmLocalVisualStudio6Generator.cxx, cmMakefile.cxx, cmMakefile.h,
- cmProjectCommand.cxx:
- ENH: add OPTIONAL keyword to ENABLE_LANGUAGE, so it will be
- possible to do something like this:
-
- ENABLE_LANGUAGE(ASM-ATT) IF(CMAKE_ASM-ATT_COMPILER_WORKS) ...
- do assembler stufff ELSE(CMAKE_ASM-ATT_COMPILER_WORKS) ...
- fallback to generic C/C++ ENDIF(CMAKE_ASM-ATT_COMPILER_WORKS)
-
- Alex
-
-2007-06-27 16:28 alex
-
- * Source/kwsys/: DynamicLoader.cxx, ProcessUNIX.c:
- ENH: build on BlueGene/L: -add static resolv, nss_files and
- nss_dns libs to the default set of libs, otherwise we get
- undefined references out of libc to several functions -add a
- dummy DynamicLoader in kwsys for systems without shared libs
- -BlueGene doesn't have SA_SIGINFO
-
- Alex
-
-2007-06-27 16:14 king
-
- * Source/cmInstallCommand.cxx: BUG: Do not install the import
- library for an executable that does not have ENABLE_EXPORTS set.
-
-2007-06-27 16:10 king
-
- * Source/: cmFileCommand.cxx, cmFileCommand.h: BUG: Need to compute
- the correct versioned name for executables on cygwin. This
- addresses bug#5238.
-
-2007-06-27 15:42 alex
-
- * Source/cmTarget.cxx:
- ENH: here we really want only non-imported targets, as discussed
- with Brad
-
- Alex
-
-2007-06-27 14:55 alex
-
- * Modules/CMakeDetermineCompilerId.cmake:
- BUG: use ${LANG}_COMPILER_ARG1 also here, otherwise some
- compilers won't be able to compile e.g. the C++ source file (e.g.
- the ADSP compiler needs -c++ for compiling C++ files)
-
- Alex
-
-2007-06-27 13:22 king
-
- * Tests/Java/CMakeLists.txt: BUG: For in-source version do not use
- a custom command output and custom target with the same name.
- This accidentally worked before but with a circular dependency.
-
-2007-06-27 12:07 king
-
- * Modules/Platform/Linux.cmake, Modules/Platform/UnixPaths.cmake,
- Source/cmFindLibraryCommand.cxx, Source/cmake.cxx: ENH: Added
- global property FIND_LIBRARY_USE_LIB64_PATHS to allow lib64 paths
- to be searched optionally. Turn off the feature on debian
- systems. This addresses debian report 419007.
-
-2007-06-27 12:05 king
-
- * Source/cmPropertyDefinition.cxx: BUG: Fixed spelling of globally
- in global property names.
-
-2007-06-27 11:42 king
-
- * Modules/Platform/GNU.cmake: ENH: Added GNU/Hurd platform. Taken
- from debian patch 407155.
-
-2007-06-27 11:39 king
-
- * Source/kwsys/ProcessUNIX.c: COMP: Fix for platforms that do not
- have siginfo on their signal handlers.
-
-2007-06-27 08:43 alex
-
- * Tests/CMakeLists.txt:
- COMP: fix tests where the building cmake doesn't have
- GET_TEST_PROPERTY
-
- Alex
-
-2007-06-27 04:49 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-26 19:54 alex
-
- * Source/cmGlobalGenerator.cxx:
- ENH: use CMAKE_SYSTEM instead of CMAKE_SYSTEM_NAME, since
- CMAKE_SYSTEM_NAME may already have been set when crosscompiling
-
- Alex
-
-2007-06-26 17:14 alex
-
- * Source/cmGlobalGenerator.cxx:
- COMP: fix broken tests for now
-
- Alex
-
-2007-06-26 17:08 alex
-
- * Source/: cmBootstrapCommands.cxx, cmCommands.cxx:
- COMP: fix bootstrapping
-
- Alex
-
-2007-06-26 15:30 alex
-
- * Tests/: CMakeLists.txt, SimpleCOnly/CMakeLists.txt,
- SimpleCOnly/bar.c, SimpleCOnly/foo.c, SimpleCOnly/main.c:
- ENH: add a SimpleCOnly test, this is needed e.g. for testing sdcc
- since this doesn't support C++ and also doesn't have a printf()
- implementation by default -add a test for mingw cross compiler
-
- Alex
-
-2007-06-26 15:15 alex
-
- * Tests/CMakeLists.txt, Modules/Platform/Generic-SDCC-C.cmake:
- ENH:
-
-2007-06-26 14:48 martink
-
- * Source/: cmBootstrapCommands.cxx, cmCommands.cxx: ENH: add
- SetProperties into bootstrap
-
-2007-06-26 13:50 alex
-
- * Source/: cmDefinePropertyCommand.h, cmGetPropertyCommand.h,
- cmSetPropertiesCommand.h:
- STYLE: rename chain to inherit in the docs
-
- Alex
-
-2007-06-26 13:19 alex
-
- * Modules/: CMakeCCompilerId.c, Platform/Generic-SDCC-C.cmake:
- ENH: add basic support for sdcc (http://sdcc.sourceforge.net),
- needs sdcc (sdcclib) cvs for creating libraries)
-
- Alex
-
-2007-06-26 13:05 alex
-
- * Modules/Platform/Generic.cmake, Source/cmAddLibraryCommand.cxx,
- Source/cmake.cxx, Source/cmake.h,
- Modules/CMakeGenericSystem.cmake,
- Modules/Platform/BlueGeneL.cmake:
- STYLE: change global cmake variable
- CMAKE_TARGET_SUPPORTS_ONLY_STATIC_LIBS to the first global cmake
- property TARGET_SUPPORTS_SHARED_LIBS
-
- Alex
-
-2007-06-26 13:00 alex
-
- * Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Source/cmGlobalGenerator.cxx:
- ENH: check for CMAKE_HOST_SYSTEM_NAME to decide whether to load
- CMakeDetermineSystem.cmake, since CMAKE_SYSTEM_NAME might already
- be preset when using cmake for cross compiling use type STRING
- instead of FILEPATH since otherwise a strange filename was
- generated
-
- Alex
-
-2007-06-26 04:55 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-25 12:50 martink
-
- * Source/: cmGetPropertyCommand.cxx, cmSetPropertiesCommand.cxx:
- COMP: fix warnings
-
-2007-06-25 12:07 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-25 10:34 martink
-
- * Source/: cmDefinePropertyCommand.cxx, cmDefinePropertyCommand.h,
- cmProperty.h, cmPropertyDefinition.cxx, cmPropertyMap.cxx,
- cmake.cxx, cmake.h: ENH: added the ability to document variables
- and cached_variables
-
-2007-06-25 10:33 martink
-
- * Source/: cmGetPropertyCommand.cxx, cmGetPropertyCommand.h: ENH:
- added cmGetPropertyCommand
-
-2007-06-25 09:51 martink
-
- * Source/cmCommands.cxx, Source/cmGetCMakePropertyCommand.cxx,
- Source/cmMakefile.cxx,
- Source/cmSetDirectoryPropertiesCommand.cxx,
- Source/cmSetPropertiesCommand.cxx, Source/cmake.cxx,
- Tests/Properties/CMakeLists.txt: ENH: some property cleanup and
- added GetProperty
-
-2007-06-24 06:38 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-23 01:02 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-22 11:31 hoffman
-
- * CMakeLists.txt, Utilities/Release/CMake.nsi.in,
- Utilities/Release/CMakeInstall.bmp,
- Utilities/Release/MakeRelease.cmake.in, Utilities/Release/README,
- Utilities/Release/Release.cmake, Utilities/Release/cmake_login,
- Utilities/Release/cmake_release.sh.in,
- Utilities/Release/config_AIX,
- Utilities/Release/config_CYGWIN_NT-5.1,
- Utilities/Release/config_Darwin, Utilities/Release/config_HP-UX,
- Utilities/Release/config_IRIX64, Utilities/Release/config_Linux,
- Utilities/Release/config_OSF1, Utilities/Release/config_SunOS,
- Utilities/Release/cygwin-package.sh.in,
- Utilities/Release/release_dispatch.sh: ENH: remove old style
- release stuff
-
-2007-06-22 10:22 alex
-
- * Modules/: CMakeLists.txt, FindMPI.cmake,
- Platform/BlueGeneL.cmake:
- ENH: add support for BlueGene/L
-
- Alex
-
-2007-06-22 09:58 alex
-
- * Source/: cmAddLibraryCommand.cxx, cmAddLibraryCommand.h,
- cmCPluginAPI.cxx, cmMakefile.cxx, cmMakefile.h:
- ENH: add IMPORT keyword to ADD_LIBRARY, dependencies are not yet
- working STYLE: fix line lengths and indentation, use enum as
- argument to AddLibrary() instead of int (which was initialized
- from a bool in some cases)
-
- Alex
-
-2007-06-22 08:44 alex
-
- * Source/: cmDocumentation.cxx, cmDocumentation.h, cmake.cxx,
- cmake.h:
- ENH: put compatibility commands in extra section and prepare for
- creating separate man pages for properties, modules, commands and
- compatibility commands
-
- Alex
-
-2007-06-21 16:23 alex
-
- * Modules/CMakeGenericSystem.cmake, Modules/Platform/Generic.cmake,
- Source/cmAddLibraryCommand.cxx:
- ENH: print a warning if ADD_LIBRARY( SHARED/MODULE ) is used and
- the target platform doesn't support shared libraries
-
- Alex
-
-2007-06-21 14:06 alex
-
- * Tests/Java/CMakeLists.txt:
- STYLE: add some more output, so it is easier to understand
-
- Alex
-
-2007-06-21 13:08 alex
-
- * Source/: cmLocalGenerator.cxx, cmTarget.cxx:
- BUG: handle dependencies to imported targets better: don't create
- a dependency if the target name was not listed in DEPENDS, if it
- was listed in DEPENDS, create a dependency to the file
-
- Seems to work, but have to check with Brad.
-
- Alex
-
-2007-06-21 06:32 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-21 04:47 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-20 23:01 alex
-
- * Source/cmMakefile.h:
- STYLE: GetProjectName() is const
-
- Alex
-
-2007-06-20 03:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-19 14:57 alex
-
- * Source/cmInstallExportGenerator.cxx:
- COMP: fix build under windows
-
- Alex
-
-2007-06-19 13:10 alex
-
- * Source/: CMakeLists.txt, cmGlobalGenerator.cxx,
- cmGlobalGenerator.h, cmInstallCommand.cxx, cmInstallCommand.h,
- cmInstallExportGenerator.cxx, cmInstallExportGenerator.h:
- ENH: add INSTALL(EXPORT ...) mode and INSTALL( TARGETS ... EXPORT
- <set> ) , tests still have to be added
-
- Alex
-
-2007-06-19 11:11 alex
-
- * Source/: cmInstallCommand.cxx, cmInstallCommand.h,
- cmInstallDirectoryGenerator.cxx, cmInstallDirectoryGenerator.h,
- cmInstallFilesGenerator.cxx, cmInstallFilesGenerator.h,
- cmInstallGenerator.h, cmInstallTargetGenerator.cxx,
- cmInstallTargetGenerator.h:
- STYLE: preparations for the INSTALL(EXPORT ...) generator -move
- std::string Destination to cmInstallGenerator, since all (except
- the script one) have it and add a const accessor so it can be
- queried -use temporary variables in cmInstallCommand for the
- generators so they can be reused easier -some more const
-
- Alex
-
-2007-06-19 09:18 king
-
- * Source/cmCPluginAPI.cxx: COMP: Work-around warning about static
- specifier on HP compiler.
-
-2007-06-18 18:01 alex
-
- * Modules/CMakeDetermineJavaCompiler.cmake:
- STYLE: use IF(NOT ...) and remove MARK_AS_ADVANCED() for
- variables which are not defined here
-
- Alex
-
-2007-06-18 17:14 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-18 11:59 king
-
- * bootstrap, Source/CMakeLists.txt,
- Source/cmAuxSourceDirectoryCommand.cxx, Source/cmCPluginAPI.cxx,
- Source/cmCommands.cxx, Source/cmCreateTestSourceList.cxx,
- Source/cmFLTKWrapUICommand.cxx,
- Source/cmGetSourceFilePropertyCommand.cxx,
- Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmGlobalXCodeGenerator.cxx, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h,
- Source/cmLocalVisualStudioGenerator.cxx,
- Source/cmLocalXCodeGenerator.cxx, Source/cmLocalXCodeGenerator.h,
- Source/cmMakeDepend.cxx, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.cxx,
- Source/cmOutputRequiredFilesCommand.cxx,
- Source/cmQTWrapCPPCommand.cxx, Source/cmQTWrapCPPCommand.h,
- Source/cmQTWrapUICommand.cxx, Source/cmQTWrapUICommand.h,
- Source/cmSourceFile.cxx, Source/cmSourceFile.h,
- Source/cmSourceFileLocation.cxx, Source/cmSourceFileLocation.h,
- Source/cmTarget.cxx, Source/cmTarget.h: ENH: Merging changes from
- branch CMake-SourceFile2-b between tags CMake-SourceFile2-bp and
- CMake-SourceFile2-b-mp1 to trunk. This commit is surrounded by
- tags CMake-SourceFile2-b-mp1-pre and CMake-SourceFile2-b-mp1-post
- on the trunk.
-
- The changes re-implement cmSourceFile and the use of it to allow
- instances to be created much earlier. The use of
- cmSourceFileLocation allows locating a source file referenced by
- a user to be much simpler and more robust. The two SetName
- methods are no longer needed so some duplicate code has been
- removed. The strange "SourceName" stuff is gone. Code that
- created cmSourceFile instances on the stack and then sent them to
- cmMakefile::AddSource has been simplified and converted to
- getting cmSourceFile instances from cmMakefile. The CPluginAPI
- has preserved the old API through a compatibility interface.
-
- Source lists are gone. Targets now get real instances of
- cmSourceFile right away instead of storing a list of strings
- until the final pass.
-
- TraceVSDependencies has been re-written to avoid the use of
- SourceName. It is now called TraceDependencies since it is not
- just for VS. It is now implemented with a helper object which
- makes the code simpler.
-
-2007-06-18 09:00 alex
-
- * Source/CPack/: cmCPackGenerators.cxx, cmCPackNSISGenerator.cxx:
- ENH: NSIS exists also for Linux, not only Windows, so enable it
- there too patch by Michal ÄŒihaÅ™ <michal (AT) cihar.com>
-
- Alex
-
-2007-06-17 20:50 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-17 08:24 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-16 17:35 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-15 16:09 alex
-
- * Source/cmake.cxx:
- COMP: include cmExternalMakefileProjectGenerator.h
-
- Alex
-
-2007-06-15 16:07 alex
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmMakefile.h, cmake.cxx:
- STYLE: minor fixes
-
- Alex
-
-2007-06-15 15:33 alex
-
- * Source/cmInstallTargetGenerator.h:
- COMP: forgot to commit this one
-
- Alex
-
-2007-06-15 14:27 alex
-
- * Source/cmInstallTargetGenerator.cxx:
- STYLE: remove code duplication between PrepareScriptReference and
- GetScriptReference, and make the logic for getting the filename
- public, so it can be used e.g. for exporting
-
- Alex
-
-2007-06-15 13:00 alex
-
- * Source/: cmInstallTargetGenerator.cxx,
- cmInstallTargetGenerator.h:
- BUG: don't strip static libraries, it removes their symbol table,
- dynamic libs have an extra symbol table so they still work
- stripped
-
- Alex
-
-2007-06-15 11:12 alex
-
- * Source/: cmInstallTargetGenerator.h,
- cmInstallTargetGenerator.cxx:
- BUG: don't run strip on OPTIONAL install targets if the file
- doesn't exist
-
- Alex
-
-2007-06-15 10:34 alex
-
- * Source/cmInstallCommand.h:
- STYLE: add some more line breaks so it should be easier to read
-
- Alex
-
-2007-06-15 10:10 alex
-
- * Source/: cmExportLibraryDependencies.cxx,
- cmExportLibraryDependencies.h, cmGlobalGenerator.h,
- cmLocalGenerator.h, cmMakefile.h, cmTarget.h, cmake.cxx, cmake.h:
-
- STYLE: remove duplicate non-const accessors
- GetLocalGenerator(int) and GetLocaGenerators(cmLocalGenerators)
- from cmGlobalGenerator(). Now there is one const accessor which
- is even faster since it returns a reference (instead of copying a
- vector) -more const to ensure that this the returned local
- generators don't actually get modified -removed duplicated code
- in GetCTestCommand() and GetCPackCommand() -added some const
- accessors
-
- Alex
-
-2007-06-15 08:53 alex
-
- * Utilities/CMakeLists.txt:
- STYLE: use a macro for generating the documentation
-
- Alex
-
-2007-06-15 08:42 alex
-
- * Tests/CMakeLists.txt:
- COMP: big timeout for building kdelibs
-
- Alex
-
-2007-06-15 08:19 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-14 13:57 alex
-
- * Source/CPack/cmCPackZIPGenerator.cxx:
- STYLE: fix typo
-
- Alex
-
-2007-06-14 13:55 alex
-
- * Tests/CMakeLists.txt:
- ENH: add test for buildingn kdelibs alpha1
- (http://websvn.kde.org/tags/KDE/3.90.1) with cmake requires Qt >=
- 4.3.0, DBus, kdesupport (http://websvn.kde.org/trunk/kdesupport/)
- and the EasyDashboard scripts.
-
- Alex
-
-2007-06-14 13:05 hoffman
-
- * Source/: cmCTest.cxx, CTest/cmCTestBuildCommand.cxx,
- CTest/cmCTestBuildHandler.cxx: ENH: add more verbose output
-
-2007-06-14 12:03 alex
-
- * Source/CPack/: cmCPackZIPGenerator.cxx, cmCPackZIPGenerator.h:
- ENH: support 7zip for creating zip files (not 7z files)
-
- Alex
-
-2007-06-14 11:17 alex
-
- * Utilities/CMakeLists.txt:
- STYLE: add man page for cpack
-
- Alex
-
-2007-06-14 08:49 alex
-
- * Source/: cmRemoveDefinitionsCommand.h, cmakemain.cxx:
- STYLE: add comment about the -D -P order and fix typo in doc
-
- Alex
-
-2007-06-14 08:33 alex
-
- * Tests/BuildDepends/CMakeLists.txt:
- COMP: removing the directory at the beginning breaks the test for
- in-source builds
-
- Alex
-
-2007-06-14 07:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-14 01:21 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-13 17:06 king
-
- * Source/: cmSourceFile.cxx, cmSourceFile.h: ENH: Make sure
- FindFullPath does not complain more than once about not finding
- the file if it fails.
-
-2007-06-13 16:58 king
-
- * Source/: cmSourceFile.cxx, cmSourceFile.h: ENH: Use
- non-const==>locate policy for GetLanguage() method.
-
-2007-06-13 16:33 king
-
- * Source/cmSourceFileLocation.h: STYLE: Added interface
- documentation.
-
-2007-06-13 16:26 alex
-
- * Tests/BuildDepends/: CMakeLists.txt, Project/bar.cxx:
- COMP: fix test, in some cases stdout from bar was not captured
- correctly, probably because the process was killed before the
- fflush() worked because the busy loop blocked the processor
- (failing midworld test)
-
- Alex
-
-2007-06-13 16:22 king
-
- * Source/cmSourceFile.cxx: BUG: Do not abort when file cannot be
- found.
-
-2007-06-13 16:12 king
-
- * Source/: cmGetSourceFilePropertyCommand.cxx, cmSourceFile.cxx,
- cmSourceFile.h: ENH: Improved const-correctness of cmSourceFile
- API. On-demand computation of the full path is now done only for
- non-const cmSourceFile instances.
-
-2007-06-13 15:32 king
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmLocalGenerator.cxx,
- cmLocalVisualStudio7Generator.cxx, cmMakeDepend.cxx,
- cmMakefileLibraryTargetGenerator.cxx, cmSourceFile.cxx,
- cmSourceFile.h: ENH: Changed signature of
- cmSourceFile::GetFullPath() back to returning a reference to a
- string.
-
-2007-06-13 15:21 king
-
- * Source/: cmMakefile.cxx, cmMakefile.h, cmSourceFile.h: STYLE:
- Removed commented-out code that is no longer needed.
-
-2007-06-13 15:21 king
-
- * Source/cmGlobalXCodeGenerator.cxx: COMP: Fixed for new
- cmSourceFile interface.
-
-2007-06-13 15:20 king
-
- * Source/cmSourceFile.cxx: BUG: Never return a null pointer from
- GetFullPath. Too many places construct a string with the result.
-
-2007-06-13 14:36 alex
-
- * Source/cmFileCommand.h:
- STYLE: add documentation for FILE(REMOVE ...) and
- FILE(REMOVE_RECURSE ...) FILE(REMOVE ...) works only for files,
- not for directories, REMOVE_RECURSE works for both, it seems
- having both is not necessary
-
- Alex
-
-2007-06-13 13:44 king
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudioGenerator.cxx: COMP: Fix for new cmSourceFile
- interface.
-
-2007-06-13 13:44 king
-
- * Source/cmMakefile.cxx: COMP: Fix for build on VS.
-
-2007-06-13 12:52 alex
-
- * Source/cmExternalMakefileProjectGenerator.h:
- COMP: include cmStandardIncludes.h instead of <vector> and
- <string>, this should fix the build problem on AIX
-
- Alex
-
-2007-06-13 11:55 king
-
- * Source/cmSourceFileLocation.cxx: BUG: When updating the directory
- or extension from an unambiguous location we need to mark the new
- copy as unambiguous too.
-
-2007-06-13 11:17 king
-
- * Source/: cmCPluginAPI.cxx, cmCommands.cxx: ENH: Implemented
- compatibility interface in cmCPluginAPI to preserve old API for
- loaded commadns.
-
-2007-06-13 10:54 alex
-
- * Source/cmMarkAsAdvancedCommand.h:
- BUG: make MARK_AS_ADVANCED() scriptable, because this is the only
- reason many cmake FindXXX.cmake modules can't be used in script
- mode and also FindUnixMake.cmake, which is required by the
- CTEST_BUILD() command
-
- Alex
-
-2007-06-12 17:02 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-12 16:41 alex
-
- * Modules/: CMakeCInformation.cmake, CMakeCXXInformation.cmake:
- ENH: first include the processor specific file, then the compiler
- file, this way the specific hardware file can set variables which
- can be used in the toolchain rules (like CMAKE_C_COMPILE_OBJECT
- etc.)
-
- Alex
-
-2007-06-12 11:11 david.cole
-
- * Source/cmCTest.cxx: BUG: Never return a string containing a space
- " " from cmCTest::GetShortPathToFile - replace them with "_".
- DART cannot construct valid file names during dashboard rollup
- with space " " in the short path.
-
-2007-06-12 10:56 alex
-
- * Source/: cmake.cxx, cmake.h, CTest/cmCTestScriptHandler.cxx:
- ENH: remove non/scriptable cmake commands from the script handler
- in ctest, as discussed with David. This also gives a better ctest
- man page with just the commands you should actually use in ctest
- scripts. Until now these commands were more or less executed,
- but e.g. add_executable() didn't create an executable, project()
- failed with an error. Now you get an error instantly if using one
- of these commands.
-
- Alex
-
-2007-06-12 10:19 hoffman
-
- * Source/CTest/cmCTestCoverageHandler.cxx: ENH: make sure working
- directory is set
-
-2007-06-12 09:40 alex
-
- * Source/: cmCTest.cxx, cmCTest.h:
- STYLE: remove argument bool fast, it was unused
-
- Alex
-
-2007-06-12 08:23 alex
-
- * Source/cmGlobalGenerator.cxx:
- COMP: remove warning about unused variable
-
- Alex
-
-2007-06-11 18:23 king
-
- * bootstrap, Source/CMakeLists.txt,
- Source/cmAuxSourceDirectoryCommand.cxx, Source/cmCommands.cxx,
- Source/cmCreateTestSourceList.cxx,
- Source/cmFLTKWrapUICommand.cxx, Source/cmGlobalGenerator.cxx,
- Source/cmGlobalGenerator.h, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h,
- Source/cmLocalXCodeGenerator.cxx, Source/cmLocalXCodeGenerator.h,
- Source/cmMakeDepend.cxx, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.cxx,
- Source/cmOutputRequiredFilesCommand.cxx,
- Source/cmQTWrapCPPCommand.cxx, Source/cmQTWrapCPPCommand.h,
- Source/cmQTWrapUICommand.cxx, Source/cmQTWrapUICommand.h,
- Source/cmSourceFile.cxx, Source/cmSourceFile.h,
- Source/cmSourceFileLocation.cxx, Source/cmSourceFileLocation.h,
- Source/cmTarget.cxx, Source/cmTarget.h: ENH: Initial sweep for
- new-sytle creation of cmSourceFile instances. Committing on
- branch CMake-SourceFile2-b.
-
-2007-06-11 17:15 hoffman
-
- * Tests/CMakeLists.txt: ENH: remove test
-
-2007-06-11 17:00 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-11 15:47 alex
-
- * Modules/Platform/Generic.cmake, Source/cmGlobalGenerator.cxx:
- STYLE: add a comment about SetLanguageEnabled() -add a
- Generic.cmake for target platforms without operating system
-
- Alex
-
-2007-06-11 15:36 david.cole
-
- * Source/: cmCTest.cxx, CTest/cmCTestCoverageHandler.cxx: BUG:
- Never return a string containing a ":" from
- cmCTest::GetShortPathToFile - replace them with "_". DART cannot
- construct valid file names during dashboard rollup with ":" in
- the short path. Also, fix the Bullseye coverage handler so that
- the file names and paths match in both the coverage summary and
- the individual coverage logs.
-
-2007-06-11 15:31 alex
-
- * Modules/CMakeCCompiler.cmake.in, Modules/CMakeCInformation.cmake,
- Modules/CMakeCXXCompiler.cmake.in,
- Modules/CMakeCXXInformation.cmake,
- Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h:
- ENH: split cmGlobalGenerator::SetLanguageEnabled() in two parts,
- where the second part copies the values from the cmake variables
- into internal maps. So this can now be done after the
- compiler-specific information has been loaded, which can now
- overwrite more settings.
-
- Alex
-
-2007-06-11 15:02 king
-
- * Modules/FindQt3.cmake: BUG: Fixed name of variable used to check
- version of uic executable.
-
-2007-06-11 15:00 hoffman
-
- * Tests/CMakeLists.txt: ENH: add ConvLib test back for some time
-
-2007-06-11 14:28 alex
-
- * Source/cmGlobalGenerator.cxx:
- STYLE: determineLanguageCalled removed, now the conditional code
- is directly called in the only place where it could be set to
- true
-
- Alex
-
-2007-06-11 13:22 king
-
- * Tests/CustomCommand/CMakeLists.txt: ENH: Re-arranged code to test
- adding a custom command to generate a source file after the file
- has been added to a target. This is supported by the current
- implementation because of the use of source lists in the target
- implementation. When we later convert to creating cmSourceFile
- instances immediately for the target we need to make sure the
- mentioned case still works.
-
-2007-06-11 12:40 king
-
- * Source/: cmIncludeRegularExpressionCommand.h,
- cmLocalUnixMakefileGenerator3.h, cmLocalVisualStudio6Generator.h,
- cmLocalVisualStudio7Generator.h, cmMakefileTargetGenerator.h:
- STYLE: Removed unused reference to cmMakeDepend.
-
-2007-06-11 10:25 king
-
- * Source/: cmMakefile.cxx, cmMakefile.h: BUG: More problems with
- cmMakefile copy-constructor. It seems the regular expression
- class cannot be assigned but does not enforce this limitation at
- compile time.
-
-2007-06-10 19:51 alex
-
- * Source/cmGlobalKdevelopGenerator.cxx:
- ENH: enable cvs or svn support if the source has the CVS/.svn
- subdirs
-
- Alex
-
-2007-06-10 15:56 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-09 02:39 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-08 17:44 king
-
- * Source/cmMakefile.cxx: BUG: Copy constructor needs to copy
- regular expression members.
-
-2007-06-08 16:19 alex
-
- * Source/cmExportCommand.cxx:
- ENH: fail if an unknown target is listed
-
- Alex
-
-2007-06-08 16:06 alex
-
- * Source/: cmDocumentation.cxx, ctest.cxx,
- CTest/cmCTestScriptHandler.cxx, CTest/cmCTestScriptHandler.h:
- STYLE: create command documentation for ctest
-
- I think some of the cmake commands should be removed from ctest
- if possible, like add_executable etc.
-
- Alex
-
-2007-06-08 14:16 martink
-
- * Source/cmCTest.cxx: BUG: fix timeout bug with global timeouts
- such as DART_TESTING_TIMEOUT
-
-2007-06-08 13:43 king
-
- * Source/cmFindBase.cxx: BUG: Fixed spelling and formatting of new
- documentation.
-
-2007-06-08 12:42 alex
-
- * Source/: cmExternalMakefileProjectGenerator.h,
- cmGlobalGenerator.h:
- COMP: less warnings
-
- Alex
-
-2007-06-08 12:29 hoffman
-
- * Source/CTest/: cmCTestCoverageHandler.cxx,
- cmCTestCoverageHandler.h: ENH: use new covbr that does not stop
- on error
-
-2007-06-08 11:57 alex
-
- * Source/: cmBootstrapCommands.cxx, cmCommands.cxx,
- cmExportCommand.cxx, cmExportCommand.h,
- cmExternalMakefileProjectGenerator.cxx,
- cmExternalMakefileProjectGenerator.h, cmFindLibraryCommand.cxx,
- cmFindPathCommand.cxx, cmFindProgramCommand.cxx,
- cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalKdevelopGenerator.cxx, cmGlobalKdevelopGenerator.h,
- cmMakefile.cxx, cmake.cxx, cmake.h:
- ENH: add cmExternalMakefileProjectGenerator, which should make it
- easier to write generators for IDE projects, which use already
- existing makefiles (current the kdevelop generator) -first stept
- of the export interface, iniitial export() command -more
- replacements for the FIND_XXX docs
-
- Alex
-
-2007-06-08 10:28 alex
-
- * Modules/FindX11.cmake:
- ENH: more consistence among the X11 components
-
- Alex
-
-2007-06-08 09:29 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-08 09:28 alex
-
- * Modules/FindQt4.cmake:
- ENH: patch from #5054: also search for QtUitoolsd lib
-
- Alex
-
-2007-06-08 09:19 alex
-
- * Source/cmExecProgramCommand.h:
- STYLE: fix typo (bug #5115)
-
- Alex
-
-2007-06-07 14:57 alex
-
- * Source/cmFindBase.cxx:
- STYLE: add documentation for CMAKE_FIND_ROOT_PATH
-
- Alex
-
-2007-06-07 14:31 alex
-
- * Source/: cmBootstrapCommands.cxx, cmCommands.cxx:
- BUG: fix Bootstrap test
-
- Alex
-
-2007-06-07 13:51 alex
-
- * Modules/CMakeDetermineCompilerId.cmake,
- Modules/CheckTypeSize.cmake, Source/cmFileCommand.cxx,
- Source/cmFileCommand.h:
- STYLE: remove out commented code
-
- Alex
-
-2007-06-07 13:05 alex
-
- * Utilities/CMakeLists.txt:
- STYLE: use GET_TARGET_PROPERTY(LOCATION) instead of manually
- building the path to the executables (tested with cmake 2.2.3)
-
- Alex
-
-2007-06-07 10:41 alex
-
- * Source/cmake.cxx:
- ENH: also remove uninitialized from the cache
-
- Alex
-
-2007-06-07 09:37 alex
-
- * Source/cmGlobalGenerator.cxx:
- BUG: fix #5137, now with the modified CMakeDetermineSystem.cmake
- the CMAKE_HOST_SYSTEM_xxx variables have to be preset, not the
- CMAKE_SYSTEM_xxx ones
-
- Alex
-
-2007-06-07 08:29 alex
-
- * Source/cmExportLibraryDependencies.cxx:
- STYLE: remove wrong comments
-
- Alex
-
-2007-06-06 16:20 king
-
- * Source/cmCommandArgumentParserHelper.cxx,
- Source/cmCommandArgumentParserHelper.h, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Tests/StringFileTest/InputFile.h.in,
- Tests/StringFileTest/StringFile.cxx: BUG: Fixed @ONLY
- configuration to not try to parse ${} syntax at all. This fixes
- the original fix to bug#4393 and adds a test.
-
-2007-06-06 15:05 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-06 13:43 hoffman
-
- * Tests/CMakeTests/: IncludeTest.cmake.in, ToolchainTest.cmake.in:
- ENH: fix it
-
-2007-06-06 13:32 hoffman
-
- * Tests/CMakeTests/: IncludeTest.cmake.in, ToolchainTest.cmake.in:
- ENH: use lower case for file compare on windows
-
-2007-06-06 11:46 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-06 11:26 hoffman
-
- * Source/kwsys/: DynamicLoader.cxx, DynamicLoader.hxx.in: ENH:
- remove some stuff to improve coverage
-
-2007-06-06 11:02 martink
-
- * Source/: cmCTest.cxx, CTest/cmCTestBuildAndTestHandler.cxx: BUG:
- better passing of global TIMEOUT to internal ctest invocaitons
-
-2007-06-06 10:44 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: fix case problem with drive
- letters and cmake vs CMakeSetup build.make changing
-
-2007-06-06 10:41 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Source/kwsys/SystemTools.cxx:
- ENH: move to RC 10
-
-2007-06-06 08:49 alex
-
- * Source/: cmIfCommand.cxx, cmIfCommand.h:
- ENH: add IF(IS_ABSOLUTE path), so no regex matching is required
- in the cmake scripts
-
- Alex
-
-2007-06-05 16:37 alex
-
- * Source/cmGlobalUnixMakefileGenerator3.h:
- STYLE: fix comment
-
- Alex
-
-2007-06-05 16:35 alex
-
- * Source/: cmGlobalKdevelopGenerator.cxx,
- cmGlobalKdevelopGenerator.h, cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h:
- STYLE: move ForceVerboseMakefiles to
- cmGlobalUnixMakefileGenerator3, so the kdevelop generator doesn't
- need its own CreateLocalGenerator() anymore
-
- Alex
-
-2007-06-05 10:28 alex
-
- * Modules/: CMakeCCompilerId.c, CMakeCInformation.cmake,
- CMakeCXXInformation.cmake, CMakeDetermineSystem.cmake,
- CMakeSystemWithToolchainFile.cmake.in:
- ENH: also load a processor-specific file if exists -also try the
- basename file if the compiler id file doesn't exist -don't rely
- so much on the CMAKE_TOOLCHAIN_FILE
-
- Alex
-
-2007-06-05 10:20 alex
-
- * Modules/CheckTypeSizeC.c.in:
- COMP: don't use stdio, it can fail on some embedded targets
- (sdcc)
-
- Alex
-
-2007-06-05 09:30 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Source/cmCommandArgumentLexer.cxx,
- Source/cmCommandArgumentLexer.h,
- Source/cmCommandArgumentLexer.in.l,
- Source/cmCommandArgumentParserHelper.cxx: ENH: merge in changes
- from main tree that fix at only parsing
-
-2007-06-05 09:19 hoffman
-
- * Source/: cmCommandArgumentLexer.cxx, cmCommandArgumentLexer.in.l:
- ENH: fix for aix
-
-2007-06-05 09:05 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-05 08:30 alex
-
- * Modules/CheckTypeSizeC.c.in:
- COMP: make the new check_type_size work with the HPUX cc
- compiler: const doesn't exist there
-
- Alex
-
-2007-06-04 17:18 hoffman
-
- * Tests/Framework/test.lua: ENH: add missing file
-
-2007-06-04 17:17 hoffman
-
- * Source/cmMakefileLibraryTargetGenerator.cxx: ENH: prevent crash
-
-2007-06-04 17:16 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-04 17:08 alex
-
- * Modules/CheckTypeSize.cmake, Modules/CheckTypeSizeC.c.in,
- Modules/Platform/Darwin.cmake, Source/cmCoreTryCompile.cxx,
- Source/cmLocalGenerator.cxx: ENH: determine typesize by compiling
- a file and reading strings from the compiled output. Tested with
- various gcc, XCode, MSVC7, sdcc For OSX when doing TRY_COMPILE()
- CMAKE_OSX_ARCHITECTURES is used, if there are different results
- an error is generated. CMAKE_OSX_ARCHITECTURES can be overwritten
- for the TRY_COMPILES with CMAKE_TRY_COMPILE_OSX_ARCHITECTURES.
-
- Alex
-
-2007-06-04 15:57 king
-
- * Source/: cmCommandArgumentLexer.cxx, cmCommandArgumentLexer.h,
- cmCommandArgumentLexer.in.l, cmCommandArgumentParserHelper.cxx:
- BUG: Fixed cmCommandArgumentLexer no-escape mode to not match
- backslash-escape sequences as lexical tokens at all. Needed to
- configure files with backslashes preceding an @VAR@ replacement.
- This fixes bug#5130.
-
-2007-06-04 15:28 hoffman
-
- * Tests/Framework/CMakeLists.txt: ENH: add one of the headers to
- the regular sources
-
-2007-06-04 13:50 alex
-
- * Source/cmake.cxx:
- STYLE: fix typo: now double space after -D
-
- Alex
-
-2007-06-04 13:48 alex
-
- * Source/: cmCacheManager.cxx, cmake.cxx, cmake.h:
- ENH: -U for removing variables now uses globbing expressions
- -cmCacheManager: now also variables with type UNINITIALIZED are
- saved in CMakeCache.txt, these are the vars defined using
- -DFOO=foo but without type
-
- Alex
-
-2007-06-04 13:39 martink
-
- * Source/: cmCTest.cxx, CTest/cmCTestBuildAndTestHandler.cxx: ENH:
- fix passing of time limit to some ctest invocations that also use
- build-options
-
-2007-06-03 10:48 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-02 16:15 hoffman
-
- * Source/CTest/cmCTestCoverageHandler.cxx: ENH: remove debug that
- caused tests to fail
-
-2007-06-02 06:33 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-06-01 23:06 hoffman
-
- * Source/CTest/cmCTestCoverageHandler.cxx: ENH: opps
-
-2007-06-01 15:40 hoffman
-
- * Source/CTest/: cmCTestCoverageHandler.cxx,
- cmCTestCoverageHandler.h: ENH: initial bullseye stuff
-
-2007-06-01 14:16 alex
-
- * Source/: cmake.cxx, cmake.h:
- BUG: also put a variable into the cache when defined using -D if
- no type is given, then STRING is used. Also add command line
- option -U as suggested for undefining cache variables. This fixes
- #4896 and #4264.
-
- Alex
-
-2007-06-01 13:17 alex
-
- * Modules/FindX11.cmake:
- COMP: fix warnings on some machines where some X libs apparently
- don't really work by reverting X11_LIBRARIES back to the old
- version -add some more X11_xxx_FOUND variables -reformat comments
- at the top -always use IF(INCLUDE_DIR and LIB) for setting FOUND
- to TRUE
-
- Alex
-
-2007-06-01 11:18 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Source/cmAddLibraryCommand.cxx,
- Source/cmGlobalGenerator.cxx: ENH: merge in a few more fixes from
- the main tree
-
-2007-06-01 11:16 alex
-
- * Modules/CheckCSourceRuns.cmake, Modules/CheckCXXSourceRuns.cmake,
- Modules/FindThreads.cmake, Modules/TestBigEndian.cmake,
- Source/cmTryRunCommand.cxx, Source/cmTryRunCommand.h,
- Tests/TryCompile/CMakeLists.txt, Tests/TryCompile/exit_success.c,
- Tests/TryCompile/exit_with_error.c:
- ENH: improve TRY_RUN() for crosscompiling: instead of just
- failing, it now creates two cache variables, one for the
- RUN_RESULT, one for the RUN_OUTPUT (if required), which can be
- set or preset by the user. It has now also two new arguments:
- RUN_OUTPUT_VARIABLE and COMPILE_OUTPUT_VARIABLE (the old
- OUTPUT_VARIABLE merges both), so if only COMPILE_OUTPUT_VARIABLE
- is used the run time output of the TRY_RUN is unused and the user
- doesn't have to care about the output when crosscompiling. This
- is now used in FindThreads.cmake, CheckC/CXXSourceRuns.cmake and
- TestBigEndian.cmake, which used the output only for the logfile
- (compile output is still there). Test/TryCompile/ now also tests
- the behaviour of OUTPUT_VARIABLE, RUN_OUTPUT_VARIABLE and
- COMPILE_OUTPUT_VARIABLE.
-
- Alex
-
-2007-06-01 11:06 alex
-
- * Source/cmCacheManager.cxx:
- ENH: also handle comments for variables which contain newlines
-
- Alex
-
-2007-06-01 09:18 hoffman
-
- * Source/cmGlobalGenerator.cxx: BUG: fix crash, bug 5121
-
-2007-05-31 22:06 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-31 16:18 alex
-
- * Source/kwsys/kwsysPlatformTests.cmake:
- COMP: revert some of the changes for crosscompiling, not required
- anymore with recent changes in cmake
-
- Alex
-
-2007-05-31 12:03 alex
-
- * Source/cmGetTargetPropertyCommand.cxx:
- ENH: if get_target_property() doesn't find a target with the
- given name, it returns now "<NAME_OF_VAR>-NOTFOUND" instead of
- just "NOTFOUND", which can help in finding problems
-
- Alex
-
-2007-05-31 10:29 martink
-
- * Tests/: CMakeLists.txt, Properties/CMakeLists.txt,
- Properties/properties.h.in, Properties/properties2.h,
- Properties/SubDir/properties3.cxx: ENH: added new test for
- SourceFile objects and properties
-
-2007-05-30 12:09 alex
-
- * Modules/FindX11.cmake:
- ENH: mostly synced with FindX11.cmake from KDE svn: now also
- searches for a lot of additional X11 libs, like Xv, Xau, Xrandr
- and others
-
- Alex
-
-2007-05-30 10:40 alex
-
- * Source/kwsys/kwsysPlatformTests.cmake:
- COMP: start crosscompiling Paraview3 (requires cmake cvs,
- currently to scratchbox)
-
- Alex
-
-2007-05-30 05:28 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-29 11:36 alex
-
- * Modules/CMakeDetermineSystem.cmake, Modules/CMakeSystem.cmake.in,
- Modules/CMakeSystemWithToolchainFile.cmake.in,
- Tests/CMakeTests/ToolchainTest.cmake.in:
- ENH: always provide CMAKE_SYSTEM_XXX() and MAKE_HOST_SYSTEM_XXX()
- variables, so when cross compiling the build host platform can be
- tested
-
- Alex
-
-2007-05-29 08:42 alex
-
- * Source/cmHexFileConverter.cxx:
- COMP: less warnings with msvc8
-
- Alex
-
-2007-05-29 05:26 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-28 17:49 king
-
- * Source/cmGlobalXCodeGenerator.cxx: BUG: Finished previous fix.
-
-2007-05-28 13:46 king
-
- * Source/cmGlobalXCodeGenerator.cxx: COMP: Fixed shadowed local
- warning.
-
-2007-05-28 13:32 king
-
- * Source/cmSourceFile.h: ENH: Removed unused methods that should
- never be used anyway.
-
-2007-05-28 12:23 king
-
- * Source/cmake.h: STYLE: Fixed comment for Generate() method.
-
-2007-05-28 12:05 king
-
- * Source/cmTarget.cxx: ENH: Moved link library related code from
- GenerateSourceFilesFromSourceLists to AnalyzeLibDependencies to
- make the former do no more than what its name says.
-
-2007-05-28 11:41 king
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ENH: Added more install rules to
- increase coverage of the command.
-
-2007-05-28 11:18 king
-
- * Source/: cmCustomCommand.cxx, cmCustomCommand.h, cmTarget.cxx:
- ENH: Removed "Used" mark from custom commands. It is no longer
- needed or checked by any generators.
-
-2007-05-28 11:16 king
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: Remove unused build rules
- from Xcode. This change was made in the VS generators on
- 2006-03-23 and should have been made for the Xcode generator too.
- Also commented out some debug print statements.
-
-2007-05-28 11:03 king
-
- * Source/cmMakefileExecutableTargetGenerator.cxx: COMP: Fix build
- on mac after change to GetSourceFiles signature.
-
-2007-05-28 11:02 king
-
- * Source/cmGlobalXCodeGenerator.cxx: COMP: Fix build of XCode
- generator after change to GetSourceFiles signature.
-
-2007-05-28 11:02 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-28 11:00 king
-
- * Source/: cmGlobalVisualStudio8Generator.cxx,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: COMP: Fix build for
- windows-only generators after change to GetSourceFiles signature.
-
-2007-05-28 10:25 king
-
- * Source/: cmFLTKWrapUICommand.cxx, cmLocalGenerator.cxx,
- cmTarget.cxx, cmTarget.h: ENH: Made cmTarget::GetSourceFiles
- method return reference to const so addition of cmSourceFile
- pointers must be done with an access method in cmTarget.
-
-2007-05-28 10:11 king
-
- * Source/: cmCPluginAPI.cxx, cmFLTKWrapUICommand.cxx,
- cmQTWrapCPPCommand.cxx, cmQTWrapUICommand.cxx, cmSourceFile.h:
- ENH: Made cmSourceFile::GetDepends return reference to const so
- dependencies can be added only by an access method in
- cmSourceFile.
-
-2007-05-28 10:07 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/FindPkgConfig.cmake,
- Modules/UsePkgConfig.cmake, Modules/UseSWIG.cmake,
- Modules/Platform/UnixPaths.cmake, Source/cmFileCommand.cxx,
- Source/cmListCommand.h, Source/cmLocalGenerator.cxx,
- Source/cmTryCompileCommand.h, Source/cmXCodeObject.cxx,
- Source/kwsys/SystemTools.cxx, Source/kwsys/SystemTools.hxx.in:
- ENH: merge in changes from branch RC 7
-
-2007-05-28 09:59 king
-
- * Source/: cmFLTKWrapUICommand.cxx, cmMakefile.cxx, cmTarget.h:
- ENH: Made cmTarget::GetSourceLists return a reference to const so
- that all additions of sources must go through access methods in
- cmTarget.
-
-2007-05-28 08:31 alex
-
- * Source/cmHexFileConverter.cxx:
- COMP: fix warning on MSVC 8: conversion from 'size_t' to
- 'unsigned int', possible loss of data
-
- Alex
-
-2007-05-27 18:47 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-27 10:32 hoffman
-
- * Source/cmXCodeObject.cxx: ENH: @ must be escaped in xcode
- projects
-
-2007-05-27 04:31 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-26 14:26 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-25 16:46 alex
-
- * Modules/CMakeDetermineCompilerId.cmake, Source/cmFileCommand.cxx,
- Source/cmFileCommand.h:
- ENH: add option to FILE(STRINGS NO_HEX_CONVERSION) to disable
- automatic conversion of hex and srec files to binary. Without
- this automatic conversion, everywhere where a compiled file is
- parsed for strings the a file(HEX2BIN somefile binfile) command
- has to be added otherwise it will not work for these compilers. I
- tried this with DetermineCompiler and CheckTypeSize and nobody
- will do this except the users who work with such compilers. For
- them it will break if they don't add this conversion command in
- all these places. If FILE(STRINGS) is used with a text file, it
- will in most cases still work as expected, since it will only
- convert hex and srec files. If a user actually wants to get text
- out of hex files, he knows what he's doing and will see the hint
- in the documentation.
-
- Anyway, it should work without having to create a temporary file,
- will work on this later.
-
- Alex
-
-2007-05-25 16:23 alex
-
- * Source/cmHexFileConverter.cxx:
- COMP: less warnings (signed vs. unsigned)
-
- Alex
-
-2007-05-25 15:51 king
-
- * Source/cmGlobalGenerator.cxx: BUG: Need to create global targets
- before AddHelperCommands is called. We should investigate
- creating global targets at the beginning of the configure step
- even if their commands are not populated or if they will not
- actually be generated later.
-
-2007-05-25 15:22 alex
-
- * Modules/CMakeCCompilerId.c,
- Modules/CMakeDetermineCompilerId.cmake, Modules/CMakeLists.txt,
- Source/cmBootstrapCommands.cxx, Source/cmFileCommand.cxx,
- Source/cmFileCommand.h, Source/cmHexFileConverter.cxx,
- Source/cmHexFileConverter.h, Tests/StringFileTest/CMakeLists.txt,
- Tests/StringFileTest/main.ihx, Tests/StringFileTest/main.srec:
- ENH: make the compiler id detection work, even if the output file
- name of the compiler is completely unknown and even if it
- produces intel hex or motorola s-record files, with test
-
- Alex
-
-2007-05-25 12:05 alex
-
- * Source/cmTryRunCommand.cxx:
- BUG: remove debug output
-
- Alex
-
-2007-05-25 11:41 king
-
- * Tests/: SimpleInstall/CMakeLists.txt, SimpleInstall/inst.cxx,
- SimpleInstall/scripts/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt, SimpleInstallS2/inst.cxx,
- SimpleInstallS2/scripts/CMakeLists.txt: ENH: Added testing of
- REGEX option to INSTALL(DIRECTORY). Added tests to cover all
- forms of old-style install commands.
-
-2007-05-25 11:09 king
-
- * Tests/: SimpleInstall/inst.cxx, SimpleInstallS2/inst.cxx: ENH:
- Add test to see if INSTALL_FILES actually worked.
-
-2007-05-25 11:08 king
-
- * Source/: cmInstallFilesCommand.cxx, cmInstallFilesCommand.h: BUG:
- Fix FILES mode after recent changes.
-
-2007-05-25 11:01 king
-
- * Source/: cmInstallFilesCommand.cxx, cmInstallProgramsCommand.cxx:
- BUG: Fixed INSTALL_FILES and INSTALL_PROGRAMS commands to install
- under the prefix like they did before the recent changes.
-
-2007-05-25 06:55 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-24 17:06 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h:
- ENH: add copy header stuff
-
-2007-05-24 16:03 alex
-
- * Modules/CMakeCCompilerId.c, Modules/CheckTypeSize.cmake,
- Source/cmTryRunCommand.cxx:
- STYLE: remove debug output, fix indentation the tests run again
- successfully, but since CheckTypeSize will switch to a
- TRY_COMPILE soon I will look at it again after this change
-
- Alex
-
-2007-05-24 14:30 alex
-
- * Modules/CheckTypeSize.cmake, Source/cmTryRunCommand.cxx:
- COMP: try to fix the test failures on dash2
-
- Alex
-
-2007-05-24 12:06 alex
-
- * Source/cmCoreTryCompile.cxx, Source/cmTryCompileCommand.h,
- Source/cmTryRunCommand.cxx, Tests/TryCompile/CMakeLists.txt:
- ENH: add COPY_FILE argument to TRY_COMPILE, so the compiled
- executable can be used e.g. for getting strings out of it.
-
- Alex
-
-2007-05-24 11:27 alex
-
- * Source/cmBootstrapCommands.cxx, Source/cmCoreTryCompile.cxx,
- Source/cmCoreTryCompile.h, Source/cmTryCompileCommand.cxx,
- Source/cmTryCompileCommand.h, Source/cmTryRunCommand.cxx,
- Source/cmTryRunCommand.h, Tests/TryCompile/CMakeLists.txt,
- Tests/TryCompile/exit_success.c,
- Tests/TryCompile/exit_with_error.c:
- ENH: add two simple tests for TRY_RUN() STYLE: create a new base
- class cmCoreTryCompile, from which cmTryCompileCommand and
- cmTryRunCommand are derived, so there are no public static
- functions with lots of arguments anymore
-
- Alex
-
-2007-05-24 09:35 alex
-
- * Modules/CMakeCCompilerId.c:
- ENH: add compiler id for sdcc
-
- Alex
-
-2007-05-24 08:56 alex
-
- * Source/: cmTryCompileCommand.cxx, cmTryCompileCommand.h,
- cmTryRunCommand.cxx:
- ENH: move output file search to cmTryCompileCommand.cxx, so it
- can be used there too... many public static functions with lots
- of arguments... :-/
-
- Alex
-
-2007-05-24 08:43 alex
-
- * Source/: cmLocalGenerator.cxx, cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx, cmTarget.cxx:
- BUG: don't use non-imported target when cross compiling as
- commands in custom commands STYLE: remove now invalid comments,
- use this->
-
- Alex
-
-2007-05-24 08:33 alex
-
- * Modules/: CMakeCCompilerId.c, CMakeDetermineCCompiler.cmake,
- TestBigEndian.cmake:
- ENH: add compiler id for IAR compiler (http://www.iar.com/) ENH:
- don't run endian test again if the variable is already set
-
- Alex
-
-2007-05-24 08:18 alex
-
- * Source/cmListCommand.h:
- STYLE: use "items" instead od "item"
-
- Alex
-
-2007-05-24 05:26 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-23 18:22 king
-
- * Source/: cmLocalGenerator.cxx: ENH: Removed unused code now that
- INSTALL_FILES and INSTALL_PROGRAMS are not targets.
-
-2007-05-23 17:58 king
-
- * Tests/BuildDepends/CMakeLists.txt: BUG: Report proper error
- message when project does not build the first time. Also added
- hack to rebuild subproject several times for Xcode. The
- generator should be fixed and the hack removed.
-
-2007-05-23 17:21 king
-
- * Source/cmGlobalXCodeGenerator.cxx: BUG: Need to use
- GetRealDependency for custom command file-level dependencies.
-
-2007-05-23 17:01 king
-
- * Tests/BuildDepends/Project/CMakeLists.txt: ENH: Executable bar
- should rebuild when its generated header changes. It does not
- need to link to the foo library anymore.
-
-2007-05-23 15:40 king
-
- * Source/: cmExportLibraryDependencies.cxx,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx, cmGlobalXCodeGenerator.cxx,
- cmInstallFilesCommand.cxx, cmInstallFilesCommand.h,
- cmInstallProgramsCommand.cxx, cmInstallProgramsCommand.h,
- cmLocalGenerator.cxx, cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx, cmMakefile.cxx, cmTarget.cxx:
- ENH: Fixed INSTALL_FILES and INSTALL_PROGRAMS commands to not
- create targets. No targets of type cmTarget::INSTALL_FILES or
- cmTarget::INSTALL_PROGRAMS are created, so we do not need to
- check for them everywhere anymore.
-
-2007-05-23 13:30 king
-
- * Tests/BuildDepends/Project/generator.cxx: BUG: Target names in
- the COMMAND part of a custom command should not create a
- file-level dependency that forces the command to rerun when the
- executable target rebuilds, but the target-level dependency
- should still be created. Target names in a DEPENDS should do
- both a target-level and file-level dependency. Updated the
- BuildDepends test to check that this works.
-
-2007-05-23 13:27 king
-
- * Source/cmAddCustomCommandCommand.h, Source/cmTarget.cxx,
- Source/cmTarget.h, Tests/BuildDepends/CMakeLists.txt,
- Tests/BuildDepends/Project/CMakeLists.txt,
- Tests/BuildDepends/Project/bar.cxx: BUG: Target names in the
- COMMAND part of a custom command should not create a file-level
- dependency that forces the command to rerun when the executable
- target rebuilds, but the target-level dependency should still be
- created. Target names in a DEPENDS should do both a target-level
- and file-level dependency. Updated the BuildDepends test to
- check that this works.
-
-2007-05-23 12:05 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Add ./ to custom
- command executables in the top of the build tree even when the
- path is generated by target name replacement.
-
-2007-05-23 11:00 king
-
- * Modules/: CMakeCCompilerId.c, CMakeCXXCompilerId.cpp,
- CMakePlatformId.h: ENH: Unify design of CMakeCCompilerId.c,
- CMakeCXXCompilerId.cpp, and CMakePlatformId.h. BUG: Do not
- violate system-reserved symbol namespace _[A-Z].
-
-2007-05-23 08:24 alex
-
- * Source/cmTarget.cxx:
- COMP: don't user string::clear(), fix warnings about unused
- variables
-
- Alex
-
-2007-05-22 17:10 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-22 12:48 alex
-
- * Modules/: CMakeCCompilerId.c, CMakeDetermineSystem.cmake,
- CMakePlatformId.h, CMakeSystemWithToolchainFile.cmake.in:
- BUG: now the toolchain file is configured into the buildtree,
- otherwise e.g. CMAKE_SOURCE_DIR can't be used there ENH: modify
- CMakeCCompilerId.c and .h so that sdcc can compile them. As they
- were the preprocessor produced:
-
- 9 "test.c"
- static char const info_compiler[] = "INFO:compiler[" # 40
- "test.c" ""
-
- "]";
-
- and the mixing of the preprocessing directives and the string
- constants didn't work.
-
- Alex
-
-2007-05-22 11:05 alex
-
- * Source/cmIncludeExternalMSProjectCommand.cxx: COMP: compile fix
-
- Alex
-
-2007-05-22 10:42 alex
-
- * Source/: cmAddExecutableCommand.cxx,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx:
- COMP: compile fix and remove warning
-
- Alex
-
-2007-05-22 10:24 alex
-
- * Source/: cmAddDependenciesCommand.cxx,
- cmAddExecutableCommand.cxx, cmGetTargetPropertyCommand.cxx,
- cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio8Generator.cxx,
- cmGlobalVisualStudioGenerator.cxx, cmGlobalXCodeGenerator.cxx,
- cmIncludeExternalMSProjectCommand.cxx, cmInstallCommand.cxx,
- cmInstallTargetGenerator.cxx, cmLocalGenerator.cxx,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalVisualStudio6Generator.cxx, cmMakefile.cxx, cmMakefile.h,
- cmMakefileTargetGenerator.cxx, cmSetTargetPropertiesCommand.cxx,
- cmTarget.cxx, cmTarget.h:
- ENH: add the IMPORT keyword to ADD_EXECUTABLE(), which generates
- an "imported" executable target. This can then be used e.g. with
- ADD_CUSTOM_COMMAND() to generate stuff. It adds a second
- container for "imported" targets, and FindTarget() now takes an
- additional argument bool useImportedTargets to specify whether
- you also want to search in the imported targets or only in the
- "normal" targets.
-
- Alex
-
-2007-05-22 09:15 alex
-
- * Modules/: CMakeGenericSystem.cmake, Platform/gcc.cmake:
- STYLE: move the two CMAKE_SHARED_LIBRARYC/CXX_FLAGS for gcc from
- CMakeGenericSystem.cmake to gcc.cmake
-
- Alex
-
-2007-05-22 04:14 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-21 11:26 alex
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeDetermineSystem.cmake, CMakeLists.txt, CMakeSystem.cmake.in,
- CMakeSystemWithToolchainFile.cmake.in:
- STYLE: use a separate source file for generating
- CMakeSystem.cmake if CMAKE_TOOLCHAIN_FILE is used
-
- Alex
-
-2007-05-21 10:58 alex
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeDetermineCXXCompiler.cmake:
- BUG: don't fail if a compiler is given in CMAKE_C/CXX_COMPILER
- but it can't be found in the path
-
- Alex
-
-2007-05-21 10:15 alex
-
- * Modules/CMakeFindBinUtils.cmake, Tests/CMakeLists.txt:
- BUG: always search for ar, ranlib, etc. except under MSVC -> this
- should fix the mingw fortran test -also generate the fortran test
- with the kdevelop generator
-
- Alex
-
-2007-05-21 05:03 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-20 10:11 king
-
- * Tests/CMakeLists.txt: BUG: Fix name of project to build for
- LoadCommandOneConfig now that it has been renamed for new name of
- LoadCommand test.
-
-2007-05-20 10:08 king
-
- * Modules/CMakeDetermineSystem.cmake: BUG: Use @ONLY substitution
- to configure CMakeSystem.cmake.
-
-2007-05-20 02:39 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-19 10:15 king
-
- * Tests/: LoadCommand/CMakeLists.txt,
- LoadCommandOneConfig/CMakeLists.txt: BUG: Finish fixing test for
- new name.
-
-2007-05-19 10:11 hoffman
-
- * Utilities/KWStyle/CMake.kws.xml.in: ENH: try to tone down kwstyle
-
-2007-05-19 10:10 hoffman
-
- * Tests/: LoadCommand/CMakeLists.txt,
- LoadCommandOneConfig/CMakeLists.txt: BUG: fix project name for
- test
-
-2007-05-19 09:55 king
-
- * Source/cmFileCommand.cxx: COMP: Fix for borland now that
- components list check is const.
-
-2007-05-18 20:51 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-18 15:11 martink
-
- * Tests/: CMakeLists.txt, ExternalOBJ/CMakeLists.txt,
- LinkLine/CMakeLists.txt, MacroTest/CMakeLists.txt: ENH: some
- cleanup, condensing some tests, removing arguments that were not
- needed but rather were cut and paste copies etc
-
-2007-05-18 14:41 alex
-
- * Source/CPack/: bills-comments.txt, cmCPackGenericGenerator.cxx:
- ENH: 2nd try to move stripping out of cpack and to install time,
- now if CPACK_STRIP_FILES is true (or contains a list of files),
- everything will be stripped, if it's empty or false they won't be
- stripped
-
- Alex
-
-2007-05-18 13:43 alex
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalUnixMakefileGenerator3.h,
- cmLocalUnixMakefileGenerator3.cxx:
- ENH: add install/strip target for makefile generators if strip
- was found
-
- Alex
-
-2007-05-18 11:57 alex
-
- * Modules/Platform/Darwin.cmake,
- Source/cmInstallTargetGenerator.cxx: ENH: move hack to fix "new
- cmake on old build tree on OSX doesn't have
- CMAKE_INSTALL_NAME_TOOL in the cache" from
- cmInstallTargetGenerator.cxx to Darwin.cmake
-
- Alex
-
-2007-05-18 11:45 alex
-
- * Source/CPack/cpack.cxx:
- COMP: force a recompile on VS71
-
- Alex
-
-2007-05-18 11:36 king
-
- * Modules/Platform/UnixPaths.cmake, Source/cmLocalGenerator.cxx:
- ENH: Use CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES from platform
- files to block link directories.
-
-2007-05-18 10:55 alex
-
- * Modules/: CMakeFindBinUtils.cmake, Platform/cl.cmake: COMP: if a
- new cmake runs on an old build tree, set CMAKE_LINKER to link to
- make it link
-
- Alex
-
-2007-05-18 10:32 alex
-
- * Modules/Platform/cl.cmake, Source/cmLocalGenerator.cxx: COMP: fix
- link rules with nmake, the linker command has to be converted to
- shortpath form for nmake
-
- Alex
-
-2007-05-18 09:33 king
-
- * Tests/CustomCommand/CMakeLists.txt: BUG: Replace "with space" in
- custom command argument tests with "w s" to still have whitespace
- but be shorter. The test was failing because the custom command
- line length was simply too long for the VS IDE.
-
-2007-05-18 09:30 hoffman
-
- * Source/cmTryCompileCommand.h: STYLE: fix documentation for
- command
-
-2007-05-18 09:18 king
-
- * Tests/CustomCommand/: CMakeLists.txt, check_command_line.c.in:
- ENH: Added quick means to turn on verbose output for debugging
- this test.
-
-2007-05-18 09:17 king
-
- * Source/kwsys/System.c: BUG: Added carrot (^) to characters that
- need quoting. The solaris shell needs it.
-
-2007-05-18 09:16 alex
-
- * Modules/CMakeDetermineFortranCompiler.cmake: STYLE: fdcorrect
- comments about FC/CC
-
- Alex
-
-2007-05-18 09:08 king
-
- * Modules/: CMakeDetermineCompilerId.cmake,
- CMakeDetermineFortranCompiler.cmake: BUG: If the Fortran
- CompilerId source fails to compile it should not be a failure.
- It is only expected to work for Fortran90 compilers.
-
-2007-05-18 08:49 alex
-
- * Source/: cmFileCommand.cxx, cmFindBase.cxx, cmFindBase.h,
- cmInstallTargetGenerator.cxx, cmTryRunCommand.cxx:
- STYLE: fix line lengths
-
- Alex
-
-2007-05-17 17:43 king
-
- * Source/cmInstallTargetGenerator.cxx: BUG: Need to use
- GetSafeDefinition when assigning to a string.
-
-2007-05-17 17:40 king
-
- * Source/: cmIfCommand.cxx, cmMakefile.cxx, cmMakefile.h,
- cmVariableWatch.h: BUG: All variable accesses should produce
- watch callbacks, including IF(DEFINED <var>) ones. Instead we
- define a new access type for IF(DEFINED) so that the error does
- not show up for backward compatibility variables.
-
-2007-05-17 17:21 alex
-
- * Source/cmInstallTargetGenerator.cxx: STYLE: fix indentation ENH:
- add hack to make new cmake work with older existing cmake build
- trees
-
- Alex
-
-2007-05-17 16:50 alex
-
- * Source/cmGlobalKdevelopGenerator.cxx:
- STYLE: use braces
-
- Alex
-
-2007-05-17 16:49 alex
-
- * Modules/CMakeFindBinUtils.cmake: ENH: fail if install_name_tool
- wasn't found
-
- Alex
-
-2007-05-17 15:17 king
-
- * Modules/CheckTypeSize.cmake,
- Utilities/cmcurl/CMake/CheckTypeSize.cmake: ENH: Use IF(NOT
- DEFINED) check to short-circuit size test.
-
-2007-05-17 15:12 king
-
- * Source/: cmIfCommand.cxx, cmMakefile.cxx, cmMakefile.h: BUG: Do
- not complain about missing watched variables when they are
- accessd with IF(DEFINED VAR).
-
-2007-05-17 14:47 king
-
- * Source/cmMakefile.cxx: COMP: GCC 2.95 does not have
- std::string::clear() method.
-
-2007-05-17 14:41 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Source/cmCTest.cxx,
- Source/cmIfCommand.h, Source/cmListFileCache.h,
- Source/cmLocalGenerator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx, Source/cmMakefile.cxx,
- Source/CPack/cmCPackTarCompressGenerator.cxx: ENH: merge in
- changes from main tree
-
-2007-05-17 14:32 king
-
- * Tests/CustomCommand/CMakeLists.txt: ENH: Add testing of * and /
- character arguments except on MinGW.
-
-2007-05-17 14:03 king
-
- * Tests/CustomCommand/CMakeLists.txt: ENH: Added test for custom
- command lines with special single-character arguments.
-
-2007-05-17 14:01 king
-
- * Source/kwsys/System.c: BUG: Some single-character arguments need
- quoting on windows.
-
-2007-05-17 13:28 king
-
- * Tests/CustomCommand/CMakeLists.txt: BUG: Disable test of angle
- bracket escapes until it works everywhere.
-
-2007-05-17 13:20 alex
-
- * Modules/CMakeCCompiler.cmake.in, Modules/CMakeCInformation.cmake,
- Modules/CMakeCXXCompiler.cmake.in,
- Modules/CMakeCXXInformation.cmake,
- Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Modules/CMakeDetermineFortranCompiler.cmake,
- Modules/CMakeDetermineSystem.cmake,
- Modules/CMakeFindBinUtils.cmake, Modules/CMakeLists.txt,
- Modules/CMakeSystem.cmake.in,
- Modules/CMakeSystemSpecificInformation.cmake,
- Modules/CMakeTestCCompiler.cmake, Modules/CTest.cmake,
- Modules/CheckTypeSize.cmake, Modules/Platform/Windows-cl.cmake,
- Modules/Platform/cl.cmake, Source/cmFileCommand.cxx,
- Source/cmFileCommand.h, Source/cmFindBase.cxx,
- Source/cmFindBase.h, Source/cmIncludeCommand.cxx,
- Source/cmIncludeCommand.h, Source/cmInstallTargetGenerator.cxx,
- Source/cmInstallTargetGenerator.h, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmTryRunCommand.cxx,
- Source/cmUtilitySourceCommand.cxx,
- Source/cmUtilitySourceCommand.h,
- Source/CTest/cmCTestTestHandler.cxx,
- Source/CTest/cmCTestTestHandler.h,
- Tests/CMakeTests/CMakeLists.txt,
- Tests/CMakeTests/DummyToolchain.cmake,
- Tests/CMakeTests/FindBaseTest.cmake.in,
- Tests/CMakeTests/IncludeTest.cmake.in,
- Tests/CMakeTests/ToolchainTest.cmake.in,
- Tests/CMakeTests/include/cmake_i_do_not_exist_in_the_system.h:
- ENH: merge CMake-CrossCompileBasic to HEAD -add a RESULT_VARIABLE
- to INCLUDE() -add CMAKE_TOOLCHAIN_FILE for specifiying your
- (potentially crosscompiling) toolchain -have TRY_RUN() complain
- if you try to use it in crosscompiling mode (which were compiled
- but cannot run on this system) -use CMAKE_EXECUTABLE_SUFFIX in
- TRY_RUN(), probably TRY_RUN won't be able to run the executables
- if they have a different suffix because they are probably
- crosscompiled, but nevertheless it should be able to find them
- -make several cmake variables presettable by the user:
- CMAKE_C/CXX_COMPILER, CMAKE_C/CXX_OUTPUT_EXTENSION,
- CMAKE_SYSTEM_NAME, CMAKE_SYSTEM_INFO_FILE -support prefix for GNU
- toolchains (arm-elf-gcc, arm-elf-ar, arm-elf-strip etc.) -move
- ranlib on OSX from the file command to a command in executed in
- cmake_install.cmake -add support for stripping during install in
- cmake_install.cmake -split out cl.cmake from Windows-cl.cmake,
- first (very incomplete) step to support MS crosscompiling tools
- -remove stdio.h from the simple C program which checks if the
- compiler works, since this may not exist for some embedded
- platforms -create a new CMakeFindBinUtils.cmake which collects
- the search fro ar, ranlib, strip, ld, link, install_name_tool and
- other tools like these -add support for CMAKE_FIND_ROOT_PATH for
- all FIND_XXX commands, which is a list of directories which will
- be prepended to all search directories, right now as a cmake
- variable, turning it into a global cmake property may need some
- more work -remove cmTestTestHandler::TryExecutable(), it's unused
- -split cmFileCommand::HandleInstall() into slightly smaller
- functions
-
- Alex
-
-2007-05-17 11:27 king
-
- * Source/cmSystemTools.cxx: BUG: Fix ExpandListArgument when the
- string ends in a backslash.
-
-2007-05-17 11:18 king
-
- * Source/cmTarget.cxx: BUG: An empty configuration name is
- equivalent to no configuration.
-
-2007-05-17 11:12 alex
-
- * Source/: cmFileCommand.h, cmIncludeCommand.cxx,
- cmInstallTargetGenerator.cxx: COMP: less warnings with msvc7
-
- Alex
-
-2007-05-17 11:09 alex
-
- * Tests/CMakeTests/: FindBaseTest.cmake.in, ToolchainTest.cmake.in:
- BUG: correct quoting in the tests so that the new tests pass
-
- Alex
-
-2007-05-17 10:53 king
-
- * Source/cmGlobalBorlandMakefileGenerator.cxx,
- Source/cmGlobalMinGWMakefileGenerator.cxx,
- Source/cmLocalGenerator.cxx, Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalUnixMakefileGenerator3.h,
- Tests/CustomCommand/CMakeLists.txt: ENH: Added testing for custom
- command line arguments containing all special characters on the
- US keyboard. Fixed curly brace arguments on borland and %
- arguments in mingw32-make.
-
-2007-05-17 10:53 king
-
- * Source/kwsys/: System.c, System.h.in: ENH: Added more special
- unix shell characters that require quoting. Added escaping of %
- as %% for shells inside mingw32-make.
-
-2007-05-17 10:24 alex
-
- * Modules/CMakeCCompiler.cmake.in, Modules/CMakeCCompilerId.c,
- Modules/CMakeCInformation.cmake,
- Modules/CMakeCXXCompiler.cmake.in,
- Modules/CMakeCXXCompilerId.cpp,
- Modules/CMakeCXXInformation.cmake,
- Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Modules/CMakeDetermineCompilerId.cmake,
- Modules/CMakeDetermineFortranCompiler.cmake,
- Modules/CMakeDetermineSystem.cmake,
- Modules/CMakeFindBinUtils.cmake,
- Modules/CMakeFortranCompiler.cmake.in,
- Modules/CMakeFortranInformation.cmake,
- Modules/CMakeGenericSystem.cmake,
- Modules/CMakeSystemSpecificInformation.cmake,
- Modules/CPack.cmake, Modules/CTest.cmake, Modules/Dart.cmake,
- Modules/DartConfiguration.tcl.in, Modules/Platform/Darwin.cmake,
- Modules/Platform/Linux.cmake, Modules/Platform/Windows-cl.cmake,
- Modules/Platform/cl.cmake, Source/CMakeLists.txt,
- Source/cmBootstrapCommands.cxx, Source/cmCommands.cxx,
- Source/cmCustomCommand.h, Source/cmFindBase.cxx,
- Source/cmFindBase.h, Source/cmGlobalGenerator.cxx,
- Source/cmGlobalGenerator.h,
- Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmGlobalUnixMakefileGenerator3.h,
- Source/cmGlobalVisualStudio6Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalWatcomWMakeGenerator.cxx,
- Source/cmGlobalXCodeGenerator.cxx,
- Source/cmGlobalXCodeGenerator.h, Source/cmIncludeCommand.cxx,
- Source/cmIncludeCommand.h, Source/cmListFileCache.h,
- Source/cmLocalGenerator.cxx, Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalUnixMakefileGenerator3.h,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio6Generator.h,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h,
- Source/cmLocalVisualStudioGenerator.cxx,
- Source/cmLocalVisualStudioGenerator.h, Source/cmMakefile.cxx,
- Source/cmMakefileExecutableTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.h,
- Source/cmMakefileTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.h,
- Source/cmMakefileUtilityTargetGenerator.cxx, Source/cmTarget.cxx,
- Source/cmTarget.h, Source/cmTryRunCommand.cxx,
- Source/cmTryRunCommand.h, Source/cmVersion.cxx,
- Source/CPack/cmCPackGenericGenerator.cxx,
- Source/CTest/cmCTestTestHandler.cxx, Source/kwsys/ProcessUNIX.c,
- Source/kwsys/System.c, Templates/DLLHeader.dsptemplate,
- Templates/EXEHeader.dsptemplate,
- Templates/EXEWinHeader.dsptemplate,
- Templates/UtilityHeader.dsptemplate,
- Templates/staticLibHeader.dsptemplate,
- Tests/CMakeTests/CMakeLists.txt,
- Tests/CMakeTests/DummyToolchain.cmake,
- Tests/CMakeTests/FindBaseTest.cmake.in,
- Tests/CMakeTests/IncludeTest.cmake.in,
- Tests/CMakeTests/ToolchainTest.cmake.in,
- Tests/CMakeTests/include/cmake_i_do_not_exist_in_the_system.h:
- ENH: merge changes from HEAD into the branch -change INCLUDE(file
- [OPTIONAL] [VAR]) to INCLUDE(file [OPTIONAL] [RESULT_VARIABLE
- VAR]) -add tests for INCLUDE(), CMAKE_TOOLCHAIN_FILE and
- FIND_XXX() -keep the stripping in CPack for now -support a MS
- toolchain suffix
-
- Alex
-
-2007-05-17 10:07 hoffman
-
- * Modules/: CMakeCCompilerId.c, CMakeCXXCompilerId.cpp,
- CMakeDetermineCompilerId.cmake: ENH: fix up compiler id to be
- more robust
-
-2007-05-17 08:38 hoffman
-
- * Modules/CMakeCXXCompilerId.cpp: BUG: make sure this thing
- compiles on 64 bit machines
-
-2007-05-17 07:27 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-16 19:59 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-16 16:19 king
-
- * Source/kwsys/System.c: BUG: Shell escaping needs to write % as %%
- for VS IDE.
-
-2007-05-16 13:26 king
-
- * Modules/Platform/Windows-wcl386.cmake: ENH: Enabled preprocessor
- make rules for Watcom.
-
-2007-05-16 13:24 king
-
- * Source/: cmGlobalUnixMakefileGenerator3.h,
- cmGlobalWatcomWMakeGenerator.cxx,
- cmLocalUnixMakefileGenerator3.cxx, cmMakefileTargetGenerator.cxx:
- BUG: Watcom WMake needs empty rule commands even for symbolic
- targets. This fixes the cmake_force target.
-
-2007-05-16 13:10 king
-
- * Source/kwsys/ProcessUNIX.c: BUG: Do not send both SIGSTOP and
- SIGKILL when killing a process. The SIGSTOP seems to be able to
- block the SIGKILL occasionally. Also the SIGKILL is sufficient
- since the process table entry will still exist until it is reaped
- with waitpid.
-
-2007-05-16 11:40 king
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/complex.cxx: BUG: Disable test of
- feature that is not documented or implemented everywhere.
-
-2007-05-16 10:36 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-16 09:07 king
-
- * Source/cmLocalGenerator.cxx: BUG: Do not emit /usr/lib32 or
- /usr/lib64 as linker paths. Submitted by David Faure.
-
-2007-05-16 07:56 andy
-
- * Tests/BuildDepends/Project/CMakeLists.txt: BUG: check in the rest
- of the changes to move from c to cxx
-
-2007-05-16 07:54 andy
-
- * Tests/BuildDepends/: CMakeLists.txt, Project/bar.c,
- Project/bar.cxx: BUG: fix test for hp move to c++ to avoid ansi
- issues and produce a message if the compile fails, (really
- checked in by Bill H.)
-
-2007-05-15 16:55 alex
-
- * Modules/Platform/Windows-cl.cmake: BUG: let INCLUDE() actually
- find cl.cmake
-
- Alex
-
-2007-05-15 16:53 alex
-
- * Modules/Platform/: Windows-cl.cmake, cl.cmake:
- ENH: create a separate cl.cmake as preparation for supporting the
- cross-compiling cl's
-
- Alex
-
-2007-05-15 16:06 alex
-
- * Source/cmTarget.cxx:
- BUG: fix segfault when trying to get the object file for a
- sourcefile in an unknown language via GET_TARGET_PROPERTY(), as
- reported by Trevor Kellaway
-
- Alex
-
-2007-05-15 13:30 alex
-
- * Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Modules/CMakeFindBinUtils.cmake,
- Modules/CMakeGenericSystem.cmake,
- Modules/Platform/Windows-cl.cmake, Modules/Platform/gcc.cmake,
- Source/cmIncludeCommand.cxx, Source/cmIncludeCommand.h,
- Source/cmInstallTargetGenerator.cxx, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h:
- ENH: some adjustments as suggested by Brad: only check for the
- various "binutils" on the respective platform, hardcode the strip
- command, make the return variable of include() available also
- without OPTIONAL, honor DESTDIR for strip and ranlib -use
- FIND_PROGRAM(CMAKE_LINKER link) for the MSVC linker
-
- Alex
-
-2007-05-15 10:23 king
-
- * Modules/: CTest.cmake, Dart.cmake: STYLE: Added basic usage
- documentation.
-
-2007-05-15 03:59 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-14 17:02 alex
-
- * Source/: cmFileCommand.cxx, cmInstallTargetGenerator.cxx,
- cmInstallTargetGenerator.h:
- ENH: move ranlib handling on _APPLE_CC_ from the file command to
- the InstallTargetGenerator
-
- Alex
-
-2007-05-14 16:28 alex
-
- * CMakeLists.txt, Modules/CMakeGenericSystem.cmake,
- Modules/CPack.cmake, Modules/Platform/gcc.cmake,
- Source/cmGlobalGenerator.cxx,
- Source/cmInstallTargetGenerator.cxx,
- Source/cmInstallTargetGenerator.h, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/CPack/cmCPackGenericGenerator.cxx:
- ENH: move stripping from cpack to cmake/install time, fully
- configurable via the CMAKE_STRIP_FILE rule, currently only
- implemented for the GNU toolchain. Now cpack should work also
- for cross compiling (since it doesn't have to know the executable
- suffix anymore).
-
- stripping can be enabled/disabled via the cache variable
- CMAKE_INSTALL_DO_STRIP.
-
- Even if this is disabled, the cmake_install.cmake files still
- contain the strip rules, so by running cmake
- -DCMAKE_INSTALL_DO_STRIP=1 cmake_install.cmake you can install
- with stripping also in this case.
-
- Alex
-
-2007-05-14 13:46 alex
-
- * Source/: cmFileCommand.cxx, cmFileCommand.h:
- STYLE: split the HandleInstallCommand() into shorter functions
- (which are still quite long)
-
- Alex
-
-2007-05-14 11:23 alex
-
- * Source/: cmGlobalXCodeGenerator.cxx,
- cmLocalVisualStudio6Generator.cxx, cmTarget.cxx:
- STYLE: fix line lengths
-
- Alex
-
-2007-05-14 11:07 alex
-
- * Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Modules/CMakeDetermineFortranCompiler.cmake,
- Modules/CMakeFindBinUtils.cmake, Modules/CMakeLists.txt,
- Source/cmInstallTargetGenerator.cxx:
- ENH: -added new CMakeFindBinUtils.cmake to have less code
- duplication in CMakeDetermineC/C++?FortranCompiler.cmake, -added
- CMAKE_INSTALL_NAME_TOOL variable, only run install_name_tool
- handling if this was found
-
- Alex
-
-2007-05-14 09:46 alex
-
- * Source/CTest/: cmCTestTestHandler.cxx, cmCTestTestHandler.h:
- ENH: use GetCTestConfiguration("ExecutableSuffix") instead
- instead of cmSystemTools::GetExecutableExtension() -rmove the
- unused TryExecutable()
-
- Alex
-
-2007-05-14 08:59 martink
-
- * Tests/CMakeLists.txt: ENH: revert back to SUBDIRS so that CMake
- can be built with 2.2
-
-2007-05-14 08:33 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-13 10:59 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-13 09:11 hoffman
-
- * CMakeLists.txt: ENH: revert to SUBDIRS to make sure cmake can be
- built with 2.2
-
-2007-05-13 07:16 king
-
- * CMakeLists.txt, Source/cmBootstrapCommands.cxx,
- Source/cmCommands.cxx: COMP: Need CMake 2.4 or a bootstrap cmake
- that has ADD_SUBDIRECTORY to build.
-
-2007-05-12 02:58 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-11 16:25 alex
-
- * Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Modules/CMakeDetermineSystem.cmake, Source/cmFindBase.cxx,
- Source/cmIncludeCommand.cxx, Source/cmMakefile.cxx,
- Source/cmMakefile.h:
- ENH: -search CMAKE_TOOLCHAIN_FILE at first relative to the
- CMAKE_BINARY_DIR -if in CMAKE_C_COMPILER only the basename of the
- compiler without path was given then find the path
- -CMAKE_FIND_PREFIX can now be a list of directories -via
- CMAKE_PROGRAM_FIND_PREFIX_MODE, CMAKE_LIBRARY_FIND_PREFIX_MODE
- and CMAKE_INCLUDE_FIND_PREFIX_MODE the default behaviour for
- these 3 types can be adjusted: *at first the directories with the
- prefixes, then without prefixes (default, unset) *only the
- prefixes (useful for libs and headers, "ONLY") *only without the
- prefixes (useful for programs, "NEVER")
-
- Alex
-
-2007-05-11 14:03 alex
-
- * Source/: cmListFileCache.h, cmTryRunCommand.cxx,
- cmUtilitySourceCommand.cxx:
- BUG: same as HEAD: use a std::string instead a const char* for
- storing the filename
-
- ENH: use CMAKE_EXECUTABLE_SUFFIX() in try_run and utility_source,
- although usually they won't be able to run the executables (but
- IMO they shouldn't complain they can't find the executables)
-
- ENH: try_run now fails with "cant run executables if used with
- this toolchain" if used with a user defined toolchain which
- didn't reset the CMAKE_ALIEN_EXECUTABLES flag
-
- Alex
-
-2007-05-11 13:52 king
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h:
- BUG: Fixed generation of XCODE_DEPEND_HELPER.make into proper
- directory. Cleaned up duplicate code created by recent changes.
-
-2007-05-11 13:46 alex
-
- * Modules/CTest.cmake, Modules/DartConfiguration.tcl.in,
- Source/CPack/cmCPackGenericGenerator.cxx,
- Source/CTest/cmCTestTestHandler.cxx:
- ENH: allow it to set UPDATE_TYPE via CTEST_UPDATE_TYPE from
- CTestConfig.cmake -add EXECUTABLE_SUFFIX to DartConfig.tcl so it
- can be used in ctest -use CPACK_EXECUTABLE_SUFFIX for cpack
- (strip, which doesn't work because of the install dir)
-
- Alex
-
-2007-05-11 13:06 alex
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeDetermineCXXCompiler.cmake,
- CMakeSystemSpecificInformation.cmake, CPack.cmake:
- ENH: also use the target platform strip and executable suffix in
- cpack use the new include() parameter to handle both full-path
- and module-name-only SYSTEM_INFO files
-
- Alex
-
-2007-05-11 12:17 martink
-
- * CMakeLists.txt, Tests/CMakeLists.txt: ENH: minor fixes
-
-2007-05-11 11:55 alex
-
- * Source/: cmIncludeCommand.cxx, cmIncludeCommand.h:
- ENH: if OPTIONAL is used, give the user a way to check whether
- the file was included or not (by setting a variable to the full
- path or NOTFOUND) Additionally now fail if a second argument is
- used and this is not "OPTIONAL"
-
- Alex
-
-2007-05-11 10:34 alex
-
- * Modules/: CMakeDetermineSystem.cmake, CMakeSystem.cmake.in,
- CMakeSystemSpecificInformation.cmake, CheckTypeSize.cmake:
- ENH: only check for the type size if it hasn't already been set,
- put a bit more information in the CMakeSystemInformation.cmake
- file if it has been used with a toolchain file, use the file
- given in the toolchain file as CMake_SYSTEM_INFO_FILE
-
- Alex
-
-2007-05-11 10:22 martink
-
- * CMakeLists.txt, Tests/CMakeLists.txt, Tests/COnly/CMakeLists.txt,
- Tests/CxxOnly/CMakeLists.txt, Tests/MathTest/CMakeLists.txt,
- Tests/NewlineArgs/CMakeLists.txt, Tests/ObjC++/CMakeLists.txt,
- Tests/PreOrder/CMakeLists.txt, Tests/SetLang/CMakeLists.txt,
- Tests/Simple/CMakeLists.txt,
- Tests/SystemInformation/CMakeLists.txt,
- Tests/TarTest/CMakeLists.txt: ENH: some more CMakeList cleanups
-
-2007-05-11 09:02 martink
-
- * CMakeLists.txt, Source/CMakeLists.txt, Tests/CMakeLists.txt: ENH:
- more cleanup of some CMakeLists files
-
-2007-05-11 08:36 alex
-
- * Source/cmListFileCache.h:
- BUG: const char* FilePath could point to a non-existent
- std::string for commands used in a macro, using a std::string
- instead copies the contents so this works (correct error message)
-
- Alex
-
-2007-05-11 08:11 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-10 15:18 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-10 15:13 hoffman
-
- * Utilities/: CMakeLists.txt, KWStyle/CMake.kws.xml.in,
- KWStyle/CMakeFiles.txt.in, KWStyle/CMakeLists.txt,
- KWStyle/CMakeOverwrite.txt, KWStyle/Headers/CMakeHeader.h: ENH:
- add KWStyle support
-
-2007-05-10 14:43 hoffman
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: BUG: fix -D escaped quotes for
- watcom
-
-2007-05-10 14:08 martink
-
- * CMakeCPack.cmake, CMakeLists.txt, CompileFlags.cmake: ENH: start
- trying to cleanup CMakeLists files
-
-2007-05-10 13:03 alex
-
- * Source/: cmTarget.cxx, cmTarget.h:
- ENH: return the default location for imported targets if the
- config-dependent locations are not set
-
- Alex
-
-2007-05-10 11:41 alex
-
- * Source/: cmAddDependenciesCommand.cxx,
- cmAddExecutableCommand.cxx, cmGetTargetPropertyCommand.cxx,
- cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio8Generator.cxx,
- cmGlobalVisualStudioGenerator.cxx, cmGlobalXCodeGenerator.cxx,
- cmIncludeExternalMSProjectCommand.cxx, cmInstallCommand.cxx,
- cmInstallFilesCommand.cxx, cmInstallTargetGenerator.cxx,
- cmLocalGenerator.cxx, cmLocalGenerator.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio6Generator.h,
- cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h, cmMakefile.cxx, cmMakefile.h,
- cmMakefileTargetGenerator.cxx, cmSetTargetPropertiesCommand.cxx,
- cmTarget.cxx, cmTarget.h:
- ENH: first try at "importing" targets (from other build trees),
- now done using a separate container for the imported targets -as
- in HEAD: move TraceVSDependencies() to one central place,
- GlobalGenerator::Generate()
-
- Alex
-
-2007-05-10 11:38 alex
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h,
- cmLocalVisualStudio7Generator.cxx, cmTarget.cxx:
- STYLE: fix line length
-
- Alex
-
-2007-05-10 11:16 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: make sure escaping is
- done for strings on the command line
-
-2007-05-10 10:31 hoffman
-
- * Source/CMakeLists.txt: ENH: add test for a simple depend test,
- does an exe re-link if a library that it uses changes
-
-2007-05-10 10:05 hoffman
-
- * Tests/BuildDepends/: CMakeLists.txt, Project/bar.c: ENH: add test
- for build depends
-
-2007-05-10 10:05 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: fix for move of trace
- depends
-
-2007-05-09 15:10 hoffman
-
- * Tests/BuildDepends/: CMakeLists.txt, Project/CMakeLists.txt,
- Project/bar.c: ENH: add a test to make sure Xcode does not break
- again
-
-2007-05-09 14:41 alex
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmLocalGenerator.h, cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio6Generator.h,
- cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h:
- BUG: fix problem for non-C/CXX languages with Visual Studio, the
- dependencies for the custom commands added for java were not
- handled correctly. Needs more work.
-
- Alex
-
-2007-05-09 11:44 alex
-
- * Source/: cmAddExecutableCommand.cxx,
- cmGlobalUnixMakefileGenerator3.cxx,
- cmIncludeExternalMSProjectCommand.cxx,
- cmLocalUnixMakefileGenerator3.cxx, cmMakefile.cxx, cmMakefile.h,
- cmMakefileTargetGenerator.cxx, cmTarget.cxx, cmTarget.h:
- ENH: initial try for support for "importing" targets into cmake,
- so e.g. the support for libs in release- and debug mode can be
- done much better and importeed executable targets can be used in
- custom commands (-> cross compiling)
-
- Alex
-
-2007-05-09 10:28 andy
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: fix for older xcode and
- framework create
-
-2007-05-09 10:18 king
-
- * Source/cmLocalVisualStudio7Generator.cxx,
- Tests/Complex/Executable/CMakeLists.txt,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/complex.cxx: BUG: Fixed
- cmLocalVisualStudio7Generator to deal with quotes in macro
- definitions properly. This addresses bug#4983.
-
-2007-05-09 09:35 alex
-
- * Source/: cmTarget.cxx, cmTarget.h:
- STYLE: functions use upper case for the first letter
-
- Alex
-
-2007-05-09 09:10 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-09 08:25 alex
-
- * Source/cmCustomCommand.h, Source/cmGlobalGenerator.cxx,
- Source/cmGlobalGenerator.h,
- Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmGlobalVisualStudio6Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalXCodeGenerator.cxx,
- Source/cmGlobalXCodeGenerator.h, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio6Generator.h,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h,
- Source/cmLocalVisualStudioGenerator.cxx,
- Source/cmLocalVisualStudioGenerator.h, Source/cmMakefile.cxx,
- Source/cmTarget.cxx, Source/cmTarget.h,
- Templates/DLLHeader.dsptemplate, Templates/EXEHeader.dsptemplate,
- Templates/EXEWinHeader.dsptemplate,
- Templates/UtilityHeader.dsptemplate,
- Templates/staticLibHeader.dsptemplate,
- Tests/CustomCommand/CMakeLists.txt, Tests/CustomCommand/main.cxx,
- Tests/CustomCommand/GeneratorInExtraDir/CMakeLists.txt:
- ENH: now target names can be used in add_custom_command() and
- add_custom_target() as COMMAND, and cmake will recognize them and
- replace them with the actual output path of these executables.
- Also the dependency will be added automatically. Test included.
- ENH: moved TraceVSDependencies() to the end of
- GlobalGenerator::Configure(), so it is done now in one central
- place
-
- Alex
-
-2007-05-08 16:58 alex
-
- * Tests/CustomCommand/: CMakeLists.txt,
- GeneratorInExtraDir/CMakeLists.txt:
- ENH: also test if the dependency to a target works with POSTBUILD
-
- Alex
-
-2007-05-08 16:37 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: getting closer
-
-2007-05-08 15:49 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: add initial xcode
- framework stuff
-
-2007-05-08 15:29 alex
-
- * Source/cmLocalVisualStudio7Generator.cxx: COMP: a closing brace
- was missing
-
- Alex
-
-2007-05-08 14:47 alex
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx, cmGlobalXCodeGenerator.cxx,
- cmLocalGenerator.cxx, cmLocalGenerator.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx:
- ENH: move TraceVSDependencies() from every generator to the end
- of GlobalGenerator::Configure(), removes some code duplication
- and makes it easier to add support for "importing" targets
-
- Alex
-
-2007-05-08 14:28 alex
-
- * Source/: cmGlobalVisualStudio6Generator.cxx,
- cmGlobalGenerator.cxx, cmGlobalVisualStudio7Generator.cxx,
- cmGlobalXCodeGenerator.cxx:
- STYLE: standard for-loop-initialization in the MSVC generator,
- one level less deep if-statement in XCode generator, one level
- less deep function call in the global generator -> makes it
- easier to understand IMO
-
- Alex
-
-2007-05-08 14:10 alex
-
- * Source/cmTarget.h:
- STYLE: GetName() is const, comment updated
-
- Alex
-
-2007-05-08 12:43 hoffman
-
- * Tests/Framework/: bar.cxx, foo.cxx: ENH: make it work on non
- windows
-
-2007-05-08 11:53 hoffman
-
- * Source/cmLocalGenerator.cxx, Tests/Framework/CMakeLists.txt,
- Tests/Framework/bar.cxx, Tests/Framework/foo.cxx: ENH: fix it so
- that the FRAMEWORK property does not break the building of normal
- shared libs on non-mac platforms
-
-2007-05-08 11:31 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-08 10:58 hoffman
-
- * Source/CMakeLists.txt, Tests/Framework/CMakeLists.txt,
- Tests/Framework/bar.cxx, Tests/Framework/foo.cxx,
- Tests/Framework/foo.h, Tests/Framework/foo2.h: ENH: add a very
- simple framework test
-
-2007-05-08 10:32 hoffman
-
- * Modules/MacOSXFrameworkInfo.plist.in,
- Modules/Platform/Darwin.cmake, Source/cmLocalGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.h, Source/cmTarget.cxx:
- ENH: initial support for creation of frameworks on Mac
-
-2007-05-08 10:05 alex
-
- * Source/: cmMakefile.cxx, cmTarget.cxx:
- ENH: also detect targetnames-used-as-commands for
- PREBUILD/PRELINK/POSTBUILD custom commands
-
- Alex
-
-2007-05-07 18:17 king
-
- * Modules/Platform/Linux.cmake: BUG: Detect debian with existence
- of /etc/debian_version so things work in a chroot install. This
- is suggested in bug#4805.
-
-2007-05-07 14:50 alex
-
- * Tests/CustomCommand/: CMakeLists.txt,
- GeneratorInExtraDir/CMakeLists.txt:
- ENH: also test the automatic dependency. To make it a bit harder
- also use SET_TARGET_PROPERTIES(OUTPUT_NAME) for the generator
- executable
-
- Alex
-
-2007-05-07 14:42 alex
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx, cmTarget.cxx:
- ENH: if a target name is used as command in add_custom_command,
- automatically add the dependency to this target
-
- Alex
-
-2007-05-07 14:27 alex
-
- * Source/cmCustomCommand.h:
- STYLE: IsUsed() is const, semicolons are not required
-
- Alex
-
-2007-05-07 11:43 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-07 09:48 alex
-
- * Tests/CustomCommand/CMakeLists.txt:
- ENH: add test for the target-to-location translation for
- ADD_CUSTOM_TARGET
-
- Alex
-
-2007-05-07 08:48 alex
-
- * Source/cmLocalVisualStudio6Generator.cxx,
- Templates/DLLHeader.dsptemplate, Templates/EXEHeader.dsptemplate,
- Templates/EXEWinHeader.dsptemplate,
- Templates/UtilityHeader.dsptemplate,
- Templates/staticLibHeader.dsptemplate:
- ENH: also support target-as-command with the MSVC6 generator
-
- Alex
-
-2007-05-06 09:05 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-05 08:58 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-04 17:17 alex
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio6Generator.h:
- ENH: add configName argument to CreateTargetRules so it can
- create the rules correctly for the different configtypes. Has to
- be used for configuring the project file templates.
-
- Alex
-
-2007-05-04 17:09 alex
-
- * Source/cmLocalVisualStudio7Generator.cxx:
- STYLE: remove the commented code, wasn't intended to be committed
-
- Alex
-
-2007-05-04 16:43 alex
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmGlobalXCodeGenerator.cxx,
- Source/cmGlobalXCodeGenerator.h, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio6Generator.h,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h,
- Source/cmLocalVisualStudioGenerator.cxx,
- Source/cmLocalVisualStudioGenerator.h, Source/cmTarget.cxx,
- Tests/CustomCommand/CMakeLists.txt, Tests/CustomCommand/main.cxx,
- Tests/CustomCommand/GeneratorInExtraDir/CMakeLists.txt:
- ENH: you can now use the target name of a executable target in
- cmake as command in add_custom_command, it should also honor the
- buildtypes. A testcase in Tests/CustomCommand/ is also coming
- soon. Tested on Linux with Makefiles, OSX with XCode and MSVC 7.
- MSVC 6 and 8 are not tested. Next will be to also automatically
- add the dependencies to this target automatically.
-
- Alex
-
-2007-05-04 14:08 alex
-
- * Source/cmLocalVisualStudio7Generator.cxx: COMP: removed unused
- variable temp
-
- Alex
-
-2007-05-04 09:50 alex
-
- * Source/cmMakefile.cxx:
- COMP: fix warning on VS8: conversion unsigned int -> size_t
-
- Alex
-
-2007-05-03 20:42 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-03 15:25 martink
-
- * Source/cmTryRunCommand.cxx: ENH: look at
- CMAKE_TRY_COMPILE_CONFIGURATION var for TryRun as well
-
-2007-05-03 13:03 king
-
- * Source/kwsys/ProcessUNIX.c, Utilities/cmcurl/url.c: COMP: Fix
- code-not-reached warnings for SunCC.
-
-2007-05-03 08:24 king
-
- * Modules/: CMakeCInformation.cmake, CMakeCXXInformation.cmake,
- CMakeDetermineCCompiler.cmake, CMakeDetermineCXXCompiler.cmake,
- CMakeDetermineCompilerId.cmake,
- CMakeDetermineFortranCompiler.cmake,
- CMakeFortranCompiler.cmake.in, CMakeFortranCompilerId.F90,
- CMakeFortranInformation.cmake, Platform/Linux-SunPro-C.cmake,
- Platform/Linux-SunPro-CXX.cmake,
- Platform/Linux-SunPro-Fortran.cmake: ENH: Merging CompilerId
- updates from branch CMake-Modules-CompilerId to the main tree.
- Changes between CMake-Modules-CompilerId-mp1 and
- CMake-Modules-CompilerId-mp2 are included.
-
-2007-05-03 07:11 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-02 14:13 alex
-
- * Modules/CMakeDetermineCCompiler.cmake:
- BUG: fix typo, use TOOLCHAIN_PREFIX as prefix instead of location
-
- Alex
-
-2007-05-02 11:56 alex
-
- * Modules/: CMakeCCompiler.cmake.in, CMakeCXXCompiler.cmake.in,
- CMakeDetermineCCompiler.cmake, CMakeDetermineCXXCompiler.cmake:
- ENH: make it possible to set the object file extension
- independent from the build platform at build time
-
- Alex
-
-2007-05-02 01:09 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-05-01 18:28 king
-
- * Modules/: CMakeDetermineFortranCompiler.cmake,
- CMakeFortranCompiler.cmake.in, CMakeFortranCompilerId.F90,
- CMakeFortranInformation.cmake: ENH: Using
- CMAKE_DETERMINE_COMPILER_ID to determine the Fortran compiler.
- This works only for Fortran90+ compilers that run the
- preprocessor. Otherwise we fall back to the old behavior.
-
-2007-05-01 18:27 king
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeDetermineCXXCompiler.cmake, CMakeDetermineCompilerId.cmake:
- ENH: Added flagvar argument to CMAKE_DETERMINE_COMPILER_ID to
- choose the environment variable from which to get flags. Made
- parsing of INFO blocks robust to having more than one in a single
- string.
-
-2007-05-01 18:26 king
-
- * Modules/: CMakeCInformation.cmake, CMakeCXXInformation.cmake:
- ENH: Added code to load CompilerId version of platform file if it
- exists. Set CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS only if it is
- not already defined.
-
-2007-05-01 18:24 king
-
- * Modules/Platform/: Linux-SunPro-C.cmake, Linux-SunPro-CXX.cmake,
- Linux-SunPro-Fortran.cmake: ENH: Adding platform file for Sun
- Studio Express on Linux.
-
-2007-05-01 18:22 king
-
- * Modules/: CMakeCCompilerId.c, CMakeCXXCompilerId.cpp,
- CMakeDetermineCompilerId.cmake, CMakeLists.txt, FindMPI.cmake,
- Platform/UnixPaths.cmake: ENH: Merging modules changes in range
- CMake-Modules-CompilerId-mp1-post to
- CMake-Modules-CompilerId-trunk-mp1 from trunk to
- CMake-Modules-CompilerId branch.
-
-2007-05-01 17:02 alex
-
- * Source/cmTryRunCommand.h:
- STYLE: fix typo
-
- Alex
-
-2007-05-01 17:00 alex
-
- * Source/cmUtilitySourceCommand.h:
- STYLE: according to Brad this one is ancient and shouldn't be
- used for any new stuff
-
- Alex
-
-2007-05-01 16:37 alex
-
- * Modules/CMakeTestCCompiler.cmake:
- BUG: don't use stdio in the test for a simple executable, for
- some embedded targets/toolchains/platforms this might already be
- too much
-
- Alex
-
-2007-05-01 16:25 alex
-
- * Source/: cmFindBase.cxx, cmFindBase.h:
- ENH: add support for CMAKE_FIND_PREFIX, for prepending a prefix
- before all directories searched by FIND_XXX(), useful for
- defining a different root directory for the base directory of the
- target platform
-
- Alex
-
-2007-05-01 14:35 king
-
- * Modules/: CMakeCCompilerId.c, CMakeCXXCompilerId.cpp: ENH:
- Changed GNUC compiler id name to GNU.
-
-2007-05-01 14:23 alex
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeDetermineCXXCompiler.cmake:
- ENH: add two new variables: CMAKE_TOOLCHAIN_PREFIX: will be
- prepended to gcc, ar, g++, cc, c++ and ranlib if defined (gives
- e.g. arm-elf-gcc etc.) CMAKE_TOOLCHAIN_LOCATION: if defined, the
- compilers will be searched only there, the other tools at first
- there, after that in other locations
-
- If not already defined, both of them will be set by
- CMakeDetermineXXXCompiler.cmake and used by the other one. If
- mixing the environment variable CC/CXX and these variables this
- can give weird mixtures.
-
- change order of compiler names for CXX: from c++, g++ to g++, c++
- (same order as for C)
-
- Alex
-
-2007-05-01 14:12 king
-
- * Tests/CustomCommand/: CMakeLists.txt, check_mark.cmake: ENH:
- Added test to make sure custom commands are not built more than
- once in a single build. This tests for a bug introduced by one
- fix and fixed by another fix for bug#4377.
-
-2007-05-01 13:51 king
-
- * Source/: cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx, cmMakefileTargetGenerator.h,
- cmMakefileUtilityTargetGenerator.cxx: BUG: A utility target
- should not run the custom commands from its source files
- directly. The target-level rule must add dependencies on the
- file-level custom commands to drive them. This bug was
- introduced by the "fix" to bug 4377. This also restores the
- documented behavior that PRE_BUILD rules are treated as PRE_LINK
- rules on non-VS generators. Also fixed custom command
- dependencies on the rule file build.make so that custom commands
- re-run when the commands themselves change.
-
-2007-05-01 13:13 alex
-
- * Modules/CMakeDetermineSystem.cmake:
- STYLE: the second check for uname wasn't intended to be committed
-
- Alex
-
-2007-05-01 13:11 alex
-
- * Modules/CMakeDetermineSystem.cmake:
- ENH: new variable CMAKE_TOOLCHAIN_FILE which can be used to
- specify a cmake file which will be loaded even before cmake tries
- to detect the system, so people can set e.g. CMAKE_SYSTEM to the
- value for their target platform. Only detect CMAKE_SYSTEM if it
- isn't set yet.
-
- Alex
-
-2007-05-01 13:07 alex
-
- * Modules/: CMakeCInformation.cmake, CMakeCXXInformation.cmake:
- ENH: use CMAKE_SYSTEM_AND_C[XX]_COMPILER_INFO_FILE for loading
- the file info file, but don't overwrite it if it has already been
- specified. This is needed for cross compiling so people can
- explicitely say which file to use depending on their target
- platform
-
- Alex
-
-2007-05-01 11:46 alex
-
- * Source/cmMakefile.cxx:
- BUG: fix cmake listfile stack: if a file could not be opened,
- remove it from the stack (usually CMakeCInformation.cmake and
- CMakeCXXInformation.cmake which both put Linux-gcc.cmake on the
- stack without removing it again: INCLUDE(... OPTIONAL) ) STYLE:
- better readable output formatting of the listfile stack, now in
- the same order as in gdb or with include files
-
- Alex
-
-2007-05-01 04:20 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-30 18:10 king
-
- * Modules/CMakeCXXCompilerId.cpp: STYLE: Added comment explaining
- choice of file extension.
-
-2007-04-30 18:09 king
-
- * Modules/CMakeLists.txt: BUG: Need to install
- CMakeCXXCompilerId.cpp so that C++ compiler identification works
- in an install tree.
-
-2007-04-30 17:05 alex
-
- * Modules/CMakeDetermineCompilerId.cmake:
- STYLE: comment which says which variables this macro sets
-
- Alex
-
-2007-04-30 17:03 alex
-
- * Modules/FindMPI.cmake:
- STYLE: use the newer FIND_XXX syntax, which should find MPI in
- even more directories and doesn't require to list standard
- directories like /usr/lib, etc.
-
- Alex
-
-2007-04-30 16:05 alex
-
- * Modules/CMakeLists.txt:
- BUG: also install CMakePlatformId.h, otherwise the check for the
- compiler id works only when building cmake itself, but not with
- an installed cmake
-
- Alex
-
-2007-04-30 10:57 alex
-
- * Modules/Platform/UnixPaths.cmake:
- BUG: if /opt/lib and /opt/csw/lib are searched for libs, then
- /opt/include and /opt/csw/include should also be searched for
- headers (according to google they also exist)
-
- Alex
-
-2007-04-29 23:33 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-29 03:05 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-28 12:35 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-28 09:35 king
-
- * Modules/: CMakeCCompiler.cmake.in, CMakeCCompilerId.c,
- CMakeCXXCompiler.cmake.in, CMakeCXXCompilerId.cpp,
- CMakeDetermineCCompiler.cmake, CMakeDetermineCXXCompiler.cmake,
- CMakeDetermineCompilerId.cmake, CMakePlatformId.h: ENH: Merging
- CompilerId implementation from branch CMake-Modules-CompilerId to
- the main tree. Changes between CMake-Modules-CompilerId-bp and
- CMake-Modules-CompilerId-mp1 are included.
-
-2007-04-28 08:25 king
-
- * Source/CTest/cmCTestCoverageHandler.cxx: STYLE: Fixed line too
- long.
-
-2007-04-27 10:44 king
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeDetermineCXXCompiler.cmake: ENH: Hard-coded platform for
- Visual Studio generators. Added TODO comment about setting the
- compiler id.
-
-2007-04-27 10:29 king
-
- * Modules/CMakeDetermineCompilerId.cmake: BUG: When passing the
- compiler id source file to the compiler, the native file path
- format should be used on the command line.
-
-2007-04-27 10:26 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-27 10:19 king
-
- * Modules/: CMakeCCompilerId.c, CMakeCXXCompilerId.cpp: ENH: Added
- Watcom compiler identifier.
-
-2007-04-27 09:46 king
-
- * Modules/: CMakeCCompilerId.c, CMakeCXXCompilerId.cpp: BUG: Fixed
- for HP compilers.
-
-2007-04-27 09:20 king
-
- * Modules/CMakeDetermineCompilerId.cmake: BUG: Need to strip all
- text before and after the INFO block because the binary may
- contain string data leading up to the beginning of the strings.
-
-2007-04-27 09:09 king
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeDetermineCXXCompiler.cmake: BUG: Still need to identify
- compiler using command line for Xcode generator.
-
-2007-04-27 09:01 andy
-
- * Source/CTest/cmCTestCoverageHandler.h: STYLE: Add somme comments
-
-2007-04-27 08:57 king
-
- * Modules/: CMakeCCompiler.cmake.in, CMakeCCompilerId.c,
- CMakeCXXCompiler.cmake.in, CMakeCXXCompilerId.cpp,
- CMakeDetermineCCompiler.cmake, CMakeDetermineCXXCompiler.cmake,
- CMakeDetermineCompilerId.cmake, CMakePlatformId.h: ENH: Initial
- checkin of CompilerId feature on CMake-Modules-CompilerId branch.
- This helps identify compilers and platforms by actually building
- a source file and using the preprocessor definitions to recognize
- known compilers.
-
-2007-04-26 23:20 andy
-
- * Source/CTest/: cmCTestCoverageHandler.cxx,
- cmCTestCoverageHandler.h: ENH: Initial attempt to do python
- coverage. Hopefully will not break coverage on GCov
-
-2007-04-26 21:50 andy
-
- * Source/cmStringCommand.cxx, Source/cmStringCommand.h,
- Tests/StringFileTest/CMakeLists.txt: ENH: Add STRING STRIP
- command
-
-2007-04-26 09:56 king
-
- * Source/cmFileCommand.cxx: COMP: Avoid warning.
-
-2007-04-26 07:58 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-25 17:48 king
-
- * Source/cmStringCommand.h: STYLE: Fixed line-too-long.
-
-2007-04-25 17:22 king
-
- * Source/cmFileCommand.cxx, Source/cmFileCommand.h,
- Tests/StringFileTest/CMakeLists.txt: ENH: Added FILE(STRINGS)
- command.
-
-2007-04-25 16:22 alex
-
- * Modules/CMakeDetermineCXXCompiler.cmake:
- STYLE: fix typo "CCC" -> "CC", add comments which variables it
- sets
-
- Alex
-
-2007-04-25 05:01 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-24 14:03 hoffman
-
- * Source/cmEnableLanguageCommand.h: ENH: fix docs
-
-2007-04-24 12:30 hoffman
-
- * Source/cmGlobalGenerator.cxx: ENH: fix seg fault in ccmake when
- hitting configure twice
-
-2007-04-24 01:52 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-23 16:48 king
-
- * Source/cmStringCommand.cxx: COMP: Added missing include for time.
-
-2007-04-23 11:04 martink
-
- * Source/: cmStringCommand.cxx, cmStringCommand.h: ENH: Add command
- to generate random strings
-
-2007-04-22 23:55 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-21 18:37 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-20 11:53 king
-
- * Source/kwsys/kwsysPlatformTestsCXX.cxx: COMP: Make sure gcc 2.96
- sstream header is not used.
-
-2007-04-20 09:50 king
-
- * Source/kwsys/kwsys_ios_sstream.h.in: COMP: Added
- istringstream::clear() method to disambiguate the call from using
- string::clear or istrstream::clear.
-
-2007-04-20 09:49 king
-
- * Source/cmLoadCommandCommand.cxx: BUG: Reverting previous change.
- It did not account for the possibility that the loaded command
- was built with a different compiler.
-
-2007-04-20 04:33 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-19 12:56 king
-
- * Source/kwsys/testIOS.cxx: BUG: Need to clear read failure when
- string is reset.
-
-2007-04-19 12:53 king
-
- * Source/kwsys/testIOS.cxx: ENH: Added testing for istringstream
- and stringstream.
-
-2007-04-19 12:44 king
-
- * Source/kwsys/kwsys_stl_string.hxx.in: BUG: Fix stream state on
- successfully reading a string.
-
-2007-04-19 12:12 king
-
- * Source/kwsys/: String.hxx.in, kwsys_ios_sstream.h.in: COMP: Fixes
- for Watcom.
-
-2007-04-19 12:11 king
-
- * Source/kwsys/CMakeLists.txt: COMP: Skip testAutoPtr and
- testHashSTL on Watcom. They are hopeless.
-
-2007-04-19 12:11 king
-
- * Source/kwsys/EncodeExecutable.c: COMP: Need to include header for
- unlink function.
-
-2007-04-19 11:32 king
-
- * Tests/Plugin/src/: example_exe.cxx, example_mod_1.c: ENH: Added
- function call argument to module function to make sure calling
- convention matches on lookup. Fixed for Watcom.
-
-2007-04-19 11:31 king
-
- * Source/kwsys/DynamicLoader.cxx: ENH: Added support for Watcom
- compiler. Added TODO comment about calling conventions.
-
-2007-04-19 11:23 king
-
- * Source/cmLoadCommandCommand.cxx: ENH: Removed code unnecessary
- now that DynamicLoader is implemented better.
-
-2007-04-19 11:21 king
-
- * Source/kwsys/: CMakeLists.txt, kwsys_stl_string.hxx.in: ENH:
- Fixed stl string streaming operators for Watcom.
-
-2007-04-19 04:01 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-18 09:56 king
-
- * Source/cmLocalGenerator.cxx: BUG: Fix ComputeLinkInformation.
- When using a loader_flag link item the full per-configuration
- path should be used. The fullPathLibs returned should refer to
- the import library if it was used. Since the full paths are used
- for dependencies the executable used with loader_flag should be
- returned also.
-
-2007-04-18 04:12 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-18 00:12 king
-
- * Source/CMakeLists.txt: ENH: Plugin test should now work on QNX.
-
-2007-04-18 00:11 king
-
- * Modules/Platform/QNX.cmake: ENH: Add CMAKE_EXE_EXPORTS_C_FLAG and
- CMAKE_EXE_EXPORTS_CXX_FLAG to support executables that export
- symbols.
-
-2007-04-18 00:04 king
-
- * Source/cmLocalGenerator.cxx: BUG: Cannot escape link items
- because some need the spaces to separate arguments. Instead just
- escape the argument to the loader flag.
-
-2007-04-17 23:40 king
-
- * Modules/Platform/: Linux.cmake, FreeBSD.cmake: ENH: Added
- CMAKE_EXE_EXPORTS_C_FLAG and CMAKE_EXE_EXPORTS_CXX_FLAG to
- support executables that export symbols.
-
-2007-04-17 23:39 king
-
- * Source/cmMakefileExecutableTargetGenerator.cxx: ENH: Added
- platform variable CMAKE_EXE_EXPORTS_<lang>_FLAG to add a linker
- flag when building executables that have the ENABLE_EXPORTS
- property set.
-
-2007-04-17 23:27 king
-
- * Tests/Plugin/CMakeLists.txt: COMP: Need to enable ansi C
- features.
-
-2007-04-17 23:16 king
-
- * Source/cmLocalGenerator.cxx: BUG: Fix ComputeLinkInformation for
- non-linked targets. Why is it called for utility targets anyway?
-
-2007-04-17 18:18 king
-
- * Source/CMakeLists.txt, Tests/Plugin/include/example.h: ENH: Fixed
- Plugin test on Cygwin.
-
-2007-04-17 16:42 king
-
- * Source/CMakeLists.txt: BUG: Disable Plugin test on Cygwin until
- it is implemented.
-
-2007-04-17 16:34 king
-
- * Source/CMakeLists.txt: ENH: Re-enabling Plugin test now that it
- should work on MacOSX. I will let it run one night to see what
- platforms are still not implemented. Currently it is not run on
- QNX because it is known to not be implemented there.
-
-2007-04-17 16:19 king
-
- * Modules/Platform/Darwin.cmake: ENH: Added
- CMAKE_SHARED_MODULE_LOADER_C_FLAG and
- CMAKE_SHARED_MODULE_LOADER_CXX_FLAG to support linking plugins to
- executables.
-
-2007-04-17 16:11 king
-
- * Source/cmLocalGenerator.cxx: ENH: Added use of platform variable
- CMAKE_SHARED_MODULE_LOADER_<lang>_FLAG to add a special flag when
- linking a plugin to an executable that loads it.
-
-2007-04-17 15:06 king
-
- * Source/CMakeLists.txt: BUG: Disable Plugin test until it works
- everywhere.
-
-2007-04-17 14:08 king
-
- * Source/CMakeLists.txt: ENH: Added test for executables with
- plugins that use an API exported by the executable itself.
-
-2007-04-17 13:52 king
-
- * Tests/Plugin/: CMakeLists.txt, src/example_exe.cxx,
- src/example_exe.h.in: ENH: Configure location of plugin files so
- that the executable can run with any current working directory.
-
-2007-04-17 13:43 king
-
- * Tests/Plugin/: CMakeLists.txt, include/example.h,
- src/example_exe.cxx, src/example_mod_1.c: ENH: Added test for
- executables with plugins that use an API exported by the
- executable itself.
-
-2007-04-17 04:48 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-16 04:03 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-15 11:56 andy
-
- * Utilities/cmcurl/Testing/sepheaders.c: ENH: Fix old api
-
-2007-04-15 03:46 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-14 02:53 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-13 10:22 martink
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: ENH: better progress
- for any directory that is a project
-
-2007-04-13 01:06 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-12 15:50 andy
-
- * Source/cmVariableWatchCommand.cxx: STYLE: Fix line lengths
-
-2007-04-12 15:46 martink
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h: ENH: some code consolidation
- and cleanup
-
-2007-04-12 14:21 martink
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: BUG: fix progress for
- ENCLUDE_FORM_ALL cases using new project to target map. Only
- fixes it for the top level all target
-
-2007-04-12 10:56 king
-
- * Source/kwsys/ProcessWin32.c: ENH: Added KWSYSPE_DEBUG macro to
- print debugging trace information. Added TODO comment explaining
- why process execution can still hang when a grandchild keeps the
- output pipes open.
-
-2007-04-11 17:22 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-11 15:13 andy
-
- * Source/cmCommands.cxx, Source/cmFindPackageCommand.cxx,
- Source/cmMakefile.cxx, Source/cmVariableWatch.cxx,
- Source/cmVariableWatch.h, Source/cmVariableWatchCommand.cxx,
- Source/cmVariableWatchCommand.h, Source/cmake.cxx,
- Tests/CMakeTests/CMakeLists.txt,
- Tests/CMakeTests/VariableWatchTest.cmake.in: ENH: Add variable
- watch command
-
-2007-04-11 10:00 king
-
- * Source/cmMarkAsAdvancedCommand.cxx: STYLE: Fixed line-too-long.
-
-2007-04-10 21:47 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-10 17:12 utkarsh1
-
- * Utilities/cmcurl/CMakeLists.txt: ENH: Merging branch
- PVEE-ERDC-Setup-4-3-2007 to main tree. Changes between
- PVEE-ERDC-Setup-4-3-2007-bp and PVEE-ERDC-Setup-4-3-2007-mp1 are
- included.
-
-2007-04-10 16:03 king
-
- * Source/cmCacheManager.h: BUG: When a non-cache variable is marked
- as advance do not use the cmMakefile implementation of
- AddCacheDefinition to avoid removing the makefile definition.
-
-2007-04-10 15:55 king
-
- * Source/cmMarkAsAdvancedCommand.cxx: BUG: When a non-cache
- variable is marked as advance do not use the cmMakefile
- implementation of AddCacheDefinition to avoid removing the
- makefile definition.
-
-2007-04-10 14:54 barre
-
- * Modules/Dart.cmake: ENH: this variable overrides all PROJECT_URL.
- Check the dashboard, all projects have the wrong URL in their
- "Home" button. Other variables (like ROLLUP_URL) were moved a
- while ago, for some reasons this one is still here.
-
-2007-04-10 13:09 king
-
- * Source/: cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudioGenerator.cxx,
- cmGlobalVisualStudioGenerator.h: BUG: The ALL_BUILD target should
- not have any command lines so that it is not always considered
- out of date. Moved the 'Build all projects' message into the
- description field instead of an echo in the command field. Moved
- common implementation of Generate for VS6 and VS7 into the
- superclass to avoid duplicate code for the ALL_BUILD target.
- This addresses bug#4556.
-
-2007-04-10 11:26 andy
-
- * Utilities/cmcurl/CMakeLists.txt: ENH: No reason to search for
- UCB. Let me know if anybody still has ucb
-
-2007-04-10 11:22 king
-
- * Modules/Platform/Linux.cmake, Source/cmFileCommand.cxx,
- Source/cmLocalGenerator.cxx: ENH: Added option
- CMAKE_INSTALL_SO_NO_EXE on linux to choose whether the default
- permissions for shared libraries include the executable bit.
- This is necessary to support the conflicting policies of Debian
- and Fedora. These changes address bug#4805.
-
-2007-04-10 09:54 martink
-
- * Source/: cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio8Generator.cxx,
- cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h, cmTarget.cxx: ENH: added
- internal target property for the name of the project file
-
-2007-04-10 08:49 king
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: STYLE: Added comment
- about why dependencies need to be chained to clarify code.
-
-2007-04-10 08:36 king
-
- * Modules/Platform/NetBSD.cmake: ENH: Enabled use of soname and
- therefore versioning symlinks. Patch is from bug#4558.
-
-2007-04-09 21:25 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-08 21:44 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-07 21:23 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-06 21:42 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-05 21:57 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-05 09:19 king
-
- * Source/cmMakefile.cxx: STYLE: Fix line-too-long.
-
-2007-04-04 17:02 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-04 16:28 andy
-
- * Utilities/Doxygen/doxyfile.in: STYLE: Do doxygen for CPack
-
-2007-04-04 15:58 andy
-
- * Modules/CheckCSourceCompiles.cmake: BUG: Revert back to 1.14
-
-2007-04-04 15:57 andy
-
- * Modules/: CheckCSourceCompiles.cmake, CheckCSourceRuns.cmake:
- BUG: Revert back to 1.4
-
-2007-04-04 14:49 king
-
- * Source/cmGlobalVisualStudio6Generator.cxx,
- Source/cmGlobalVisualStudio71Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalVisualStudio8Generator.h,
- Source/cmGlobalVisualStudioGenerator.cxx,
- Source/cmGlobalVisualStudioGenerator.h,
- Tests/Dependency/Two/CMakeLists.txt,
- Tests/Dependency/Two/TwoSrc.c,
- Tests/Dependency/Two/TwoCustomSrc.c,
- Tests/Dependency/Two/two-test.h.in: BUG: Fix utility dependencies
- for static libraries in VS generators. This addresses bug#4789.
-
-2007-04-04 13:43 hoffman
-
- * Modules/FindJNI.cmake: BUG: fix for bug 4605
-
-2007-04-04 13:41 andy
-
- * bootstrap: ENH: Fix copyright year
-
-2007-04-04 13:06 andy
-
- * Source/CTest/cmCTestBuildHandler.cxx: COMP: Fix kwstyle
-
-2007-04-04 13:06 andy
-
- * Modules/: CheckCSourceCompiles.cmake, CheckCSourceRuns.cmake:
- COMP: Fix kwstyleSource/CTest/cmCTestBuildHandler.cxx
-
-2007-04-04 12:05 andy
-
- * Source/cmConfigureFileCommand.cxx: BUG: No need for the backward
- compatibility variable warning
-
-2007-04-04 12:05 andy
-
- * Source/cmMakefile.cxx: ENH: Add variable for the current list
- file
-
-2007-04-04 11:22 king
-
- * Source/: CMakeLists.txt, cmGlobalVisualStudio6Generator.h,
- cmGlobalVisualStudio7Generator.h,
- cmGlobalVisualStudioGenerator.cxx,
- cmGlobalVisualStudioGenerator.h: ENH: Added
- cmGlobalVisualStudioGenerator as superclass to all VS global
- generators.
-
-2007-04-03 23:18 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-03 03:07 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-02 02:44 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-04-01 02:41 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-31 02:45 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-30 10:53 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmLocalGenerator.cxx,
- cmMakefileTargetGenerator.cxx: ENH: make sure default /System
- framework is not added with -F
-
-2007-03-30 02:37 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-29 02:41 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-28 11:06 martink
-
- * Source/CTest/: cmCTestBuildHandler.cxx: BUG: even safer checking
- of return value
-
-2007-03-28 10:58 martink
-
- * Source/CTest/cmCTestBuildHandler.cxx: BUG: fix checking of the
- return value for a build
-
-2007-03-28 02:51 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-27 23:15 king
-
- * Source/cmGlobalXCodeGenerator.cxx: COMP: Restored shared local
- variable removed by previous change.
-
-2007-03-27 23:13 king
-
- * Source/: cmGlobalXCodeGenerator.cxx,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx, cmMakefileTargetGenerator.cxx,
- cmTarget.cxx, cmTarget.h: ENH: Created method
- cmTarget::GetExportMacro to centralize computation of the export
- symbol name. This removes duplicate code from all the
- generators. Also enabled the export definition for executable
- targets with the ENABLE_EXPORTS property set.
-
-2007-03-27 02:45 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-26 02:43 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-25 02:51 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-24 14:12 barre
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH: need
- kwsys' Glob in VTK 5.0
-
-2007-03-24 14:04 barre
-
- * Source/kwsys/: CMakeLists.txt, Glob.cxx, Glob.hxx.in: ENH: need
- kwsys' Glob in VTK 5.0
-
-2007-03-24 02:47 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-23 16:33 hoffman
-
- * Source/cmCTest.cxx: BUG: fix problem with new curl_getdate and
- ctest
-
-2007-03-23 02:33 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-22 09:45 king
-
- * Source/cmLocalGenerator.cxx, Source/cmMakefile.cxx,
- Source/cmMakefileExecutableTargetGenerator.cxx,
- Source/cmTarget.cxx, Modules/Platform/Windows-bcc32.cmake,
- Modules/Platform/Windows-wcl386.cmake: ENH: Added target property
- ENABLE_EXPORTS for executable targets. It enables the
- executables for linking by loadable modules that import symbols
- from the executable. This finishes the executable import library
- support mentioned in bug #4210.
-
-2007-03-22 02:34 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-21 13:49 martink
-
- * Source/CMakeLists.txt: BUG: typo in if test
-
-2007-03-21 07:16 king
-
- * Tests/OutOfSource/OutOfSourceSubdir/: CMakeLists.txt, simple.cxx:
- BUG: Disable deep-source test on Watcom until it can be fixed.
- This is a new feature for other generators anyway.
-
-2007-03-21 02:39 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-20 15:51 hoffman
-
- * Utilities/cmcurl/strequal.c: ENH: second try to fix qnx build
- problem
-
-2007-03-20 15:49 hoffman
-
- * Utilities/cmcurl/strequal.c: ENH: try to fix qnx build problem
-
-2007-03-20 14:52 martink
-
- * Source/CTest/cmCTestBuildHandler.cxx: ENH: try markign non zero
- return values as warnings for make programs
-
-2007-03-20 14:31 martink
-
- * Source/CTest/cmCTestBuildHandler.cxx: ENH: try markign non zero
- return values as warnings for make programs
-
-2007-03-20 14:11 martink
-
- * Source/CTest/cmCTestBuildHandler.cxx: ENH: add another error
- regexp
-
-2007-03-20 13:34 king
-
- * Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt: BUG: Reduce
- long source file name length for WMake.
-
-2007-03-20 12:44 hoffman
-
- * Source/CPack/cmCPackTarCompressGenerator.cxx: BUG: fix coverity
- error, null check after usage fix
-
-2007-03-20 12:32 hoffman
-
- * Modules/Platform/: AIX.cmake, QNX.cmake: ENH: add c++ flag when
- compiling c++ code merge from main tree
-
-2007-03-20 11:52 martink
-
- * Source/cmCTest.cxx: ENH: minor additional error output
-
-2007-03-20 09:51 martink
-
- * Utilities/cmcurl/: CMakeLists.txt, config.h.in,
- Platforms/WindowsCache.cmake: BUG: was not setting HAVE_PROCESS_H
- properly
-
-2007-03-20 09:14 king
-
- * Modules/Platform/Windows-bcc32.cmake: BUG: Disable creation of
- import libraries for executables on Borland until it can be made
- optional. Otherwise all executables get a .lib with the same
- name which is unexpected behavior for users.
-
-2007-03-20 08:16 king
-
- * Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt: BUG: Work
- around VS8 conversion to a relative path for the long source
- name. It takes the nice full path we give it, converts to
- relative, and then repacks relative on top of the build directory
- resulting in a path longer than its own maxpath even though the
- original path given was short enough. Even VS6 dealt with it
- better.
-
-2007-03-20 02:50 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-19 13:04 martink
-
- * Source/: CMakeLists.txt, ctest.cxx,
- CTest/cmCTestBuildAndTestHandler.cxx,
- CTest/cmCTestBuildAndTestHandler.h, CTest/cmCTestTestHandler.cxx,
- CTest/cmCTestTestHandler.h: ENH: support for
- --build-config-sample feature #1022
-
-2007-03-19 10:00 king
-
- * Modules/Platform/CYGWIN.cmake,
- Modules/Platform/Windows-bcc32.cmake,
- Modules/Platform/Windows-cl.cmake,
- Modules/Platform/Windows-gcc.cmake, Source/cmInstallCommand.cxx,
- Source/cmInstallTargetGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmMakefileExecutableTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.cxx, Source/cmTarget.cxx,
- Source/cmTarget.h, Templates/EXEHeader.dsptemplate: ENH: Added
- support for import libraries created by executable and module
- targets. The module import libraries should never be used but
- some windows compilers always create them for .dll files since
- there is no distinction from shared libraries on that platform.
- The executable import libraries may be used to create modules
- that when loaded bind to symbols from the executables. This is
- an enhancement related to bug#4210 though not requested by it
- explicitly.
-
-2007-03-19 02:35 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-18 16:18 andy
-
- * Utilities/cmcurl/: tftp.c, transfer.c: COMP: Remove some warnings
-
-2007-03-18 02:03 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-17 13:23 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx: ENH: fix for crash from
- main tree
-
-2007-03-17 13:18 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx: ENH: remove seg fault I
- hope
-
-2007-03-17 00:20 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-16 18:44 king
-
- * Utilities/cmcurl/curl/curl.h: COMP: Do not #include files inside
- extern "C" {} blocks.
-
-2007-03-16 18:05 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Modules/Platform/Windows-bcc32.cmake, Modules/Platform/gcc.cmake,
- Source/CMakeLists.txt, Source/cmFileCommand.h,
- Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmGlobalVisualStudio6Generator.cxx,
- Source/cmGlobalVisualStudio71Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.h,
- Source/cmGlobalVisualStudio8Generator.cxx,
- Source/cmGlobalVisualStudio8Generator.h,
- Source/cmGlobalVisualStudio8Win64Generator.cxx,
- Source/cmLocalGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h,
- Source/cmLocalVisualStudioGenerator.cxx,
- Source/kwsys/SystemTools.cxx,
- Tests/PrecompiledHeader/CMakeLists.txt,
- Tests/PrecompiledHeader/foo1.c, Tests/PrecompiledHeader/foo2.c,
- Tests/PrecompiledHeader/foo_precompile.c,
- Tests/PrecompiledHeader/include/foo.h,
- Tests/PrecompiledHeader/include/foo_precompiled.h,
- Tests/SetLang/CMakeLists.txt, Tests/SetLang/bar.c,
- Tests/SetLang/foo.c: ENH: check in fixes from main tree to create
- 2.4.7 RC 5
-
-2007-03-16 16:48 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Need to include
- relative path top information in directory information so that
- relative path conversion during dependency generation works with
- the same rules as project generation.
-
-2007-03-16 16:28 king
-
- * Source/cmInstallTargetGenerator.cxx: BUG: Use GetExecutableNames
- instead of GetLibraryNames to compute the installation file name
- for executable targets.
-
-2007-03-16 16:04 king
-
- * Source/CTest/cmCTestBuildHandler.cxx: COMP: Fix bad escape
- sequence.
-
-2007-03-16 14:51 andy
-
- * Source/CTest/cmCTestBuildHandler.cxx: ENH: More regular
- expressions for visual studio 6
-
-2007-03-16 14:28 king
-
- * Utilities/cmcurl/CMakeLists.txt: COMP: Ignore windows sockets on
- cygwin. Remove duplicate source entry.
-
-2007-03-16 10:34 king
-
- * Source/cmLocalGenerator.cxx, Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt,
- Tests/OutOfSource/OutOfSourceSubdir/simple.cxx,
- Tests/OutOfSource/OutOfSourceSubdir/simple.cxx.in: ENH: Added
- computation of object file names that are almost always short
- enough to not exceed the filesystem path length limitation. This
- is useful when a source file from outside the tree is referenced
- with a long full path. The object file name previously would
- contain the entire path which when combined with the build output
- directory could exceed the filesystem limit. Now CMake
- recognizes this case and replaces enough of the beginning of the
- full path to the source file with an md5sum of the replaced
- portion to make the name fit on disk. This addresses bug#4520.
-
-2007-03-16 09:34 andy
-
- * Utilities/cmcurl/CMake/: CMakeConfigurableFile.in,
- CheckCSourceCompiles.cmake, CheckCSourceRuns.cmake: COMP: Fix
- support for old CMake (2.0 and 2.2)
-
-2007-03-15 17:22 andy
-
- * Utilities/cmcurl/CMake/CheckCSourceRuns.cmake: ENH: Unify with
- the compile one
-
-2007-03-15 15:22 andy
-
- * Utilities/cmcurl/: CMakeLists.txt, amigaos.c, amigaos.h,
- arpa_telnet.h, base64.c, base64.h, config.h.in, connect.c,
- connect.h, content_encoding.c, content_encoding.h, cookie.c,
- cookie.h, curl.copyright, curl_memory.h, curlx.h, dict.c, dict.h,
- easy.c, easyif.h, escape.c, escape.h, file.c, file.h, formdata.c,
- formdata.h, ftp.c, ftp.h, getdate.c, getdate.h, getenv.c,
- getinfo.c, getinfo.h, gtls.c, gtls.h, hash.c, hash.h, hostares.c,
- hostasyn.c, hostip.c, hostip.h, hostip4.c, hostip6.c, hostsyn.c,
- hostthre.c, http.c, http.h, http_chunks.c, http_chunks.h,
- http_digest.c, http_digest.h, http_negotiate.c, http_negotiate.h,
- http_ntlm.c, http_ntlm.h, if2ip.c, if2ip.h, inet_ntoa_r.h,
- inet_ntop.c, inet_ntop.h, inet_pton.c, inet_pton.h, krb4.c,
- krb4.h, ldap.c, ldap.h, llist.c, llist.h, md5.c, md5.h,
- memdebug.c, memdebug.h, memory.h, mprintf.c, multi.c, multiif.h,
- netrc.c, netrc.h, nwlib.c, parsedate.c, parsedate.h, progress.c,
- progress.h, security.c, security.h, select.c, select.h, sendf.c,
- sendf.h, setup.h, setup_once.h, share.c, share.h, sockaddr.h,
- socks.c, socks.h, speedcheck.c, speedcheck.h, splay.c, splay.h,
- ssh.c, ssh.h, sslgen.c, sslgen.h, ssluse.c, ssluse.h, strdup.c,
- strdup.h, strequal.c, strequal.h, strerror.c, strerror.h,
- strtok.c, strtok.h, strtoofft.c, strtoofft.h, telnet.c, telnet.h,
- tftp.c, tftp.h, timeval.c, timeval.h, transfer.c, transfer.h,
- url.c, url.h, urldata.h, version.c,
- CMake/CheckCSourceCompiles.cmake, CMake/CheckCSourceRuns.cmake,
- CMake/OtherTests.cmake, Platforms/WindowsCache.cmake,
- curl/curl.h, curl/curlver.h, curl/easy.h, curl/mprintf.h,
- curl/multi.h, curl/stdcheaders.h: ENH: Update Curl to 7.16.1
-
-2007-03-15 13:48 martink
-
- * Source/cmMakefile.cxx: BUG: change in how set cache overrides
- local definitions. Should mainly be a NOP change for most cases
-
-2007-03-14 21:51 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-14 16:30 king
-
- * CMakeLists.txt: ENH: Enable use of kwsys MD5 implementation.
-
-2007-03-14 16:29 king
-
- * Source/: cmLocalGenerator.cxx, cmLocalUnixMakefileGenerator3.cxx,
- cmLocalVisualStudio7Generator.cxx: BUG: Reverting previous
- changes related to using an empty string for a relative path to
- the current directory. Too many places want the . version.
- Instead we can just convert the . to an empty string in the one
- place that motiviated the original change.
-
-2007-03-14 15:35 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: When the current
- output directory is a link directory we need to reference it with
- the relative path "." instead of an empty relative path.
-
-2007-03-14 15:12 king
-
- * Source/kwsys/: CMakeLists.txt, MD5.c, MD5.h.in, testEncode.c:
- ENH: Added MD5 implementation to KWSys.
-
-2007-03-14 13:36 king
-
- * Source/cmLocalGenerator.cxx: BUG: During relative path conversion
- if the remote and target paths are the same return the empty
- string instead of ".".
-
-2007-03-14 09:34 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: All executable and
- library project types should specify a program database file name
- for all configurations. Even when debug information is not used
- the .pdb file specified is used to construct the name of a .idb
- file that exists for all configurations when building with the VS
- IDE.
-
-2007-03-13 15:18 martink
-
- * Source/: cmAddCustomTargetCommand.cxx, cmCPluginAPI.cxx,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio8Generator.cxx, cmGlobalXCodeGenerator.cxx,
- cmMakefile.cxx, cmMakefile.h: ENH: some more cleanup
-
-2007-03-13 14:23 hoffman
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmMakefile.cxx, cmPropertyMap.cxx, cmTarget.cxx: ENH: add project
- to target map, not used yet, but created
-
-2007-03-13 11:58 king
-
- * Source/cmLocalGenerator.cxx: BUG: Fix check of EXCLUDE_FROM_ALL
- property to use boolean type. This is required for installation
- of subdirectories to work.
-
-2007-03-13 03:57 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-12 23:36 king
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: BUG: Remove spaces from test
- output paths. Not all make tools can handle it. Ths
- SubDirSpaces test is meant for that purpose anyway.
-
-2007-03-12 16:10 martink
-
- * Source/cmake.cxx: ENH: added remove_directory bug 2937
-
-2007-03-12 14:15 king
-
- * Source/cmFileCommand.cxx: BUG: Preserve symlinks during
- installation. This addresses bug#4384.
-
-2007-03-12 13:50 king
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h,
- kwsys/SystemTools.cxx, kwsys/SystemTools.hxx.in: ENH: Added kwsys
- SystemTools::CreateSymlink and SystemTools::ReadSymlink.
-
-2007-03-12 13:30 martink
-
- * Source/cmake.cxx: ENH: typo
-
-2007-03-12 13:28 king
-
- * Tests/PrecompiledHeader/CMakeLists.txt: BUG: Do not use /I mode
- in VS6.
-
-2007-03-12 12:44 king
-
- * Tests/PrecompiledHeader/CMakeLists.txt: BUG: Clean the pch during
- make clean so that the test passes when run more than once.
-
-2007-03-12 12:40 martink
-
- * Source/cmake.cxx: ENH: small enchancement for bug 3776.
-
-2007-03-12 12:35 king
-
- * Source/cmGlobalVisualStudio71Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.h,
- Source/cmGlobalVisualStudio8Generator.cxx,
- Source/cmGlobalVisualStudio8Generator.h,
- Source/cmGlobalVisualStudio8Win64Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h,
- Tests/PrecompiledHeader/CMakeLists.txt: BUG: Split precompiled
- header flags into a separate per-global-generator flag map. This
- is needed because the flag mappings differ across VS IDE
- versions. This fixes bug#3512 for VS8 where as the previous fix
- only worked for VS7.
-
-2007-03-12 11:32 martink
-
- * Source/cmGlobalXCodeGenerator.cxx: COMP: XCode fix
-
-2007-03-12 10:26 martink
-
- * Source/: cmAddExecutableCommand.cxx, cmAddLibraryCommand.cxx,
- cmAddSubDirectoryCommand.cxx, cmGlobalGenerator.cxx,
- cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx,
- cmIncludeExternalMSProjectCommand.cxx, cmInstallFilesCommand.cxx,
- cmInstallProgramsCommand.cxx, cmLocalGenerator.cxx,
- cmLocalGenerator.h, cmMakefile.cxx, cmMakefile.h,
- cmSubdirCommand.cxx, cmTarget.h: ENH: some code cleanup
-
-2007-03-12 10:23 king
-
- * Tests/: Complex/CMakeLists.txt, Complex/Executable/complex.cxx,
- ComplexOneConfig/CMakeLists.txt,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/CMakeLists.txt,
- ComplexRelativePaths/Executable/complex.cxx,
- Complex/Library/CMakeLists.txt,
- ComplexOneConfig/Library/CMakeLists.txt,
- ComplexRelativePaths/Library/CMakeLists.txt,
- SimpleInstall/CMakeLists.txt, SimpleInstallS2/CMakeLists.txt:
- ENH: Testing new target properties RUNTIME_OUTPUT_DIRECTORY,
- LIBRARY_OUTPUT_DIRECTORY, and ARCHIVE_OUTPUT_DIRECTORY. This is
- an incremental fix for bug#2240 and bug#4210.
-
-2007-03-11 01:50 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-10 07:49 king
-
- * Modules/Platform/Windows-wcl386.cmake: BUG: Do not create import
- library for MODULEs. This is an incremental fix for bug#4210.
-
-2007-03-10 07:37 king
-
- * Modules/Platform/Windows-cl.cmake: BUG: Fixed MSVC8 module build
- rule to not use /implib option. This is an incremental fix for
- bug#4210.
-
-2007-03-10 06:56 king
-
- * Source/cmLocalVisualStudio6Generator.cxx: STYLE: Fix
- line-too-long.
-
-2007-03-10 01:31 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-09 17:15 king
-
- * Source/cmLocalGenerator.cxx: BUG: Use real path subdirectory
- check instead of substring comparison to identify when paths are
- below the relative path tops. Otherwise when the build tree is
- next to the source tree with the same name plus a suffix the
- relative path from the binary to source tree is allowed even
- though it goes outside cmake-managed directories.
-
-2007-03-09 16:58 king
-
- * Source/kwsys/auto_ptr.hxx.in: COMP: Fix warning about binding
- reference-to-non-const to an rvalue on VS6. It does not seem to
- be doing the proper auto_ptr_ref conversions. Instead use the
- const_cast work-around on this platform.
-
-2007-03-09 16:27 king
-
- * Source/kwsys/hashtable.hxx.in: COMP: Fixed unreferenced parameter
- warning for VS6 with /W4.
-
-2007-03-09 16:26 king
-
- * Source/cmLocalVisualStudio6Generator.cxx: BUG: Re-enable backward
- compatibility replacements in user-provided VS6 DSP template
- files.
-
-2007-03-09 16:25 king
-
- * Source/cmLocalVisualStudio6Generator.cxx,
- Templates/DLLHeader.dsptemplate, Templates/EXEHeader.dsptemplate,
- Templates/EXEWinHeader.dsptemplate,
- Templates/UtilityHeader.dsptemplate,
- Templates/staticLibHeader.dsptemplate: ENH: Implemented use of
- cmTarget::GetDirectory() in Visual Studio 6 generator. This is
- an incremental fix for bug#4210.
-
-2007-03-09 15:14 king
-
- * Source/: cmTarget.cxx, cmTarget.h: ENH: Added target properties
- ARCHIVE_OUTPUT_DIRECTORY, LIBRARY_OUTPUT_DIRECTORY, and
- RUNTIME_OUTPUT_DIRECTORY. If set these override
- EXECUTABLE_OUTPUT_PATH and LIBRARY_OUTPUT_PATH for a specific
- target. They can be used to distribute target files in the build
- tree with the same granularity that the INSTALL command provides
- for the install tree. This addresses bug#2240 and bug#4210.
-
-2007-03-09 14:50 king
-
- * Source/cmMakefileExecutableTargetGenerator.cxx: BUG: Fixed OSX
- bundles to be built in the directory specified by
- cmTarget::GetDirectory(). This is an incremental step for
- bug#2240.
-
-2007-03-09 13:59 king
-
- * Modules/Platform/Windows-cl.cmake: BUG: Shared library creation
- should use /implib option to specify the name of the import
- library explicitly. This is an incremental step for bug #4210.
-
-2007-03-09 13:56 king
-
- * Source/cmMakefileLibraryTargetGenerator.cxx: ENH: Do not compute
- a path name for the import library if there is no import library.
- This simplifies tracking down problems with trying to create
- import libraries for MODULEs.
-
-2007-03-09 11:35 andy
-
- * CMakeLists.txt: ENH: Prepare for the new curl. Curl is build
- static, so set define to on
-
-2007-03-09 11:35 andy
-
- * Utilities/cmcurl/: CMakeLists.txt, setup.h,
- CMake/OtherTests.cmake, Platforms/WindowsCache.cmake: ENH:
- Several windows fixes
-
-2007-03-09 11:29 king
-
- * Source/: cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx, cmMakefileTargetGenerator.h: ENH:
- Added cmMakefileTargetGenerator::GenerateExtraOutput to wrap up
- creation of rules to drive creation of extra outputs generated as
- side effects of another rule. Reimplemented generation of custom
- command multiple output rules to use it. Reimplemented soname
- symlink output dependencies to use it. Now if a symlink is
- deleted the library will be recreated with the symlink.
-
-2007-03-09 11:26 king
-
- * Source/cmMakefileLibraryTargetGenerator.cxx: BUG: Need to account
- for import library directory when constructing the clean rule for
- the import library. This is an incremental fix for bug #4210.
-
-2007-03-09 10:30 king
-
- * Source/cmLocalGenerator.cxx: ENH: Implemented new policy to
- choose the directory part of the object file name. This should
- keep the names looking as nice and short as possible. This
- partially addresses bug#4520.
-
-2007-03-09 09:30 king
-
- * Source/: cmInstallTargetGenerator.cxx, cmLocalGenerator.cxx,
- cmLocalVisualStudio7Generator.cxx,
- cmMakefileLibraryTargetGenerator.cxx, cmTarget.cxx, cmTarget.h:
- ENH: Added implib option to cmTarget::GetDirectory to support a
- separate directory containing the import library. This is an
- incremental step for bug#4210.
-
-2007-03-08 23:56 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-08 15:33 king
-
- * Source/: cmLocalVisualStudio7Generator.cxx,
- cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx, cmTarget.cxx, cmTarget.h: ENH:
- Combined cmTarget::GetDirectory and cmTarget::GetOutputDir since
- they are nearly the same. This is another step for bug#2240.
-
-2007-03-08 15:24 king
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h:
- ENH: Removed unused variables LibraryOutputPath and
- ExecutableOutputPath. Each target is asked for its own output
- directory. This is a step towards bug#2240.
-
-2007-03-08 15:10 king
-
- * Source/cmTarget.cxx: COMP: Fixed enumeration-not-used warning in
- switch.
-
-2007-03-08 14:57 king
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h,
- cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h,
- cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx, cmTarget.cxx, cmTarget.h: ENH:
- Replaced LibraryOutputPath and ExecutableOutputPath variables in
- Makefile and VS generators to instead ask each target for its
- output path. This significantly reduces total code size and
- centralizes previously duplicate code. It is also a step towards
- bug#2240.
-
-2007-03-08 14:15 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: Ask the target for
- its own directory in case of bundle instead of directly using
- ExecutableOutputPath.
-
-2007-03-08 14:11 andy
-
- * Utilities/cmcurl/: CMakeLists.txt, CMake/OtherTests.cmake: ENH:
- Add some missing headers and fix OtherTests.cmake macros
-
-2007-03-08 13:19 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Compute
- HomeRelativeOutputPath following the rules of
- RelativePathTopBinary by going through the Convert() method.
- This supports out-of-binary build trees without using relative
- paths that go outside trees managed by CMake.
-
-2007-03-08 13:13 king
-
- * Source/CMakeLists.txt: ENH: Enable SubDirSpaces test when
- building with bootstrapped cmake.
-
-2007-03-08 13:05 king
-
- * Source/: CMakeLists.txt, cmGlobalBorlandMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: Fixed recursive make call
- target escaping for Borland to support SubDirSpaces test.
-
-2007-03-08 11:49 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: Updated
- GetRecursiveMakeCall to use EscapeForShell instead of MAKEFILE
- conversion. This code is special because it is the only place
- that a make target name is passed on a command line.
-
-2007-03-08 11:49 king
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Added
- ConvertToOutputSlashes method to convert slashes with the same
- policy as ConvertToOutputPath but without escaping.
-
-2007-03-08 11:10 king
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: Removed useless method
- ConvertToMakeTarget and all calls to it. It had a buggy
- implementation that caused it to do nothing.
-
-2007-03-08 10:31 king
-
- * Source/: cmLocalGenerator.cxx,
- cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx: BUG: Some calls to Convert() were
- converting for MAKEFILE but then passing the output to the build
- shell. The calls have now been converted to call Convert() with
- SHELL.
-
-2007-03-08 10:19 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: STYLE: Removed unused
- calls to Convert.
-
-2007-03-08 09:48 king
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: STYLE: Removing
- unused methods ConvertToShellPath and EscapeForUnixShell.
-
-2007-03-08 08:50 andy
-
- * Utilities/cmcurl/: CMakeLists.txt, amigaos.c, amigaos.h,
- arpa_telnet.h, base64.c, base64.h, config.h.in, connect.c,
- connect.h, content_encoding.c, content_encoding.h, cookie.c,
- cookie.h, curl.copyright, curlx.h, dict.c, dict.h, easy.c,
- easyif.h, escape.c, escape.h, file.c, file.h, formdata.c,
- formdata.h, ftp.c, ftp.h, getenv.c, getinfo.c, getinfo.h, gtls.c,
- gtls.h, hash.c, hash.h, hostares.c, hostasyn.c, hostip.c,
- hostip.h, hostip4.c, hostip6.c, hostsyn.c, hostthre.c, http.c,
- http.h, http_chunks.c, http_chunks.h, http_digest.c,
- http_digest.h, http_negotiate.c, http_negotiate.h, http_ntlm.c,
- http_ntlm.h, if2ip.c, if2ip.h, inet_ntoa_r.h, inet_ntop.c,
- inet_ntop.h, inet_pton.c, inet_pton.h, krb4.c, krb4.h, ldap.c,
- ldap.h, llist.c, llist.h, md5.c, md5.h, memdebug.c, memdebug.h,
- memory.h, mprintf.c, multi.c, multiif.h, netrc.c, netrc.h,
- nwlib.c, parsedate.c, parsedate.h, progress.c, progress.h,
- security.c, select.c, select.h, sendf.c, sendf.h, setup.h,
- setup_once.h, share.c, share.h, sockaddr.h, socks.c, socks.h,
- speedcheck.c, speedcheck.h, splay.c, splay.h, ssh.c, ssh.h,
- sslgen.c, sslgen.h, ssluse.c, ssluse.h, strdup.c, strdup.h,
- strequal.c, strequal.h, strerror.c, strerror.h, strtok.c,
- strtok.h, strtoofft.c, strtoofft.h, telnet.c, telnet.h, tftp.c,
- tftp.h, timeval.c, timeval.h, transfer.c, transfer.h, url.c,
- url.h, urldata.h, version.c, CMake/CheckCSourceCompiles.cmake,
- CMake/CheckCSourceRuns.cmake, CMake/OtherTests.cmake,
- curl/curl.h, curl/curlver.h, curl/easy.h, curl/mprintf.h,
- curl/multi.h, curl/stdcheaders.h: ENH: Update to 7.16.1
-
-2007-03-08 08:46 king
-
- * Source/cmIncludeDirectoryCommand.cxx: STYLE: Fix line-too-long.
-
-2007-03-08 08:38 king
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalGenerator.cxx, cmLocalGenerator.h, cmake.cxx: ENH:
- SetupPathConversions is now called automatically on demand.
-
-2007-03-07 22:12 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-07 17:39 king
-
- * Source/cmLocalGenerator.cxx: ENH: Modified
- GetObjectFileNameWithoutTarget to use relative paths for object
- file names with sources above the current directory so long as
- the relative path conversion works.
-
-2007-03-07 17:32 king
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h: ENH: Improved
- computation of RelativePathTopSource and RelativePathTopBinary to
- use higher relative path tops when the source directories jump
- around in a tree below the original source top.
-
-2007-03-07 16:35 king
-
- * Source/cmLocalGenerator.cxx: ENH: Set RelativePathTopSource and
- RelativePathTopBinary independently for each local generator.
- Relative path conversion is safe within a tree as long as it does
- not go above the highest parent directory still managed by CMake.
-
-2007-03-07 16:32 king
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmLocalGenerator.h: COMP:
- Fix ConvertToRelativePath change for Xcode generator.
-
-2007-03-07 16:00 king
-
- * Source/kwsys/hashtable.hxx.in: STYLE: Move warning disable pragma
- into push/pop block.
-
-2007-03-07 15:57 king
-
- * Modules/Platform/Windows-cl.cmake,
- Source/cmLocalVisualStudio7Generator.cxx: BUG: Get rid of ancient
- variables CMAKE_CXX_WARNING_LEVEL, CMAKE_CXX_USE_RTTI,
- CMAKE_CXX_STACK_SIZE which are only partially implemented and now
- taken care of by flag mapping anyway.
-
-2007-03-07 15:36 martink
-
- * Modules/UsePkgConfig.cmake: BUG: untested fix for newlines in the
- output of pkg config
-
-2007-03-07 15:30 king
-
- * Source/cmLocalGenerator.cxx: COMP: Add missing include for
- assert.
-
-2007-03-07 15:15 king
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmLocalGenerator.cxx, cmLocalGenerator.h: ENH: Moved
- ConvertToRelativePath from cmGlobalGenerator to cmLocalGenerator.
- This is in preparation for setting up each local generator to
- have its own RelativePathTopSource and RelativePathTopBinary
- based on its ancestor directories.
-
-2007-03-07 13:52 king
-
- * Source/kwsys/: testDynamicLoader.cxx, testSystemTools.cxx: BUG:
- Use angle-brackets to include testSystemTools.h to avoid problems
- with in-source builds.
-
-2007-03-07 13:01 martink
-
- * Source/CMakeLists.txt: BUG: oops bad arg for new test
-
-2007-03-07 11:03 martink
-
- * Source/CMakeLists.txt, Source/cmIncludeDirectoryCommand.cxx,
- Source/cmIncludeDirectoryCommand.h, Source/cmMakefile.cxx,
- Source/cmSeparateArgumentsCommand.cxx,
- Tests/NewlineArgs/CMakeLists.txt: BUG: improve bad argument
- handling for INCLUDE_DIRECTORIES and ADD_DEFINITIONS bug 4364
-
-2007-03-07 09:26 king
-
- * Source/kwsys/: auto_ptr.hxx.in, testAutoPtr.cxx: ENH: Enabled
- support for use_auto_ptr(get_auto_ptr()) syntax on HP compiler.
-
-2007-03-06 21:22 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-06 14:52 martink
-
- * Tests/NewlineArgs/: CMakeLists.txt, cxxonly.cxx, libcxx1.cxx,
- libcxx1.h, libcxx2.h.in: ENH: added a tets for newlines in some
- commands
-
-2007-03-06 10:56 martink
-
- * Source/kwsys/hashtable.hxx.in: COMP: shut up w4 warning
-
-2007-03-06 09:16 andy
-
- * Modules/CPack.STGZ_Header.sh.in: STYLE: Defautl answer for the
- license is no
-
-2007-03-05 21:23 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-05 15:21 martink
-
- * Modules/UseSWIG.cmake: ENH: patch applied for bug 4517
-
-2007-03-05 13:01 king
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx: BUG: Removed legacy
- SetupTests method that was causing RUN_TESTS to test twice.
-
-2007-03-05 10:36 martink
-
- * Source/: cmCommandArgumentParser.cxx, cmDependsFortranParser.cxx,
- cmDependsJavaParser.cxx, cmExprParser.cxx: COMP: shut up warnings
-
-2007-03-05 09:50 martink
-
- * Source/cmTryCompileCommand.cxx: STYLE: long line
-
-2007-03-04 21:31 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-03 23:46 king
-
- * Source/kwsys/testAutoPtr.cxx: COMP: Disable function call with
- function return test for HP until it is implemented.
-
-2007-03-03 21:26 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-03 15:43 king
-
- * Source/kwsys/: CMakeLists.txt, auto_ptr.hxx.in: COMP: All kwsys
- .hxx headers should include Configure.hxx. Re-enabling
- testAutoPtr.
-
-2007-03-03 15:32 king
-
- * Source/kwsys/CMakeLists.txt: COMP: Disable auto_ptr test for now.
-
-2007-03-03 15:05 king
-
- * Source/kwsys/: auto_ptr.hxx.in, testAutoPtr.cxx: ENH: Implemented
- auto_ptr_ref in a way that allows conversion of the pointed-to
- type.
-
-2007-03-03 14:51 king
-
- * Source/kwsys/testAutoPtr.cxx: COMP: Remove one conversion test
- until it is implemented.
-
-2007-03-03 14:48 king
-
- * Source/kwsys/: CMakeLists.txt, auto_ptr.hxx.in, testAutoPtr.cxx:
- ENH: Added test for auto_ptr. Documented aut_ptr template
- implementation.
-
-2007-03-03 12:16 king
-
- * Source/: cmBootstrapCommands.cxx, cmCommands.cxx: BUG:
- cmCreateTestSourceList command is needed at boostrap time because
- KWSys now uses test drivers.
-
-2007-03-03 10:47 king
-
- * Source/: kwsys/CMakeLists.txt,
- kwsys/testCommandLineArguments.cxx,
- kwsys/testCommandLineArguments1.cxx, kwsys/testDynamicLoader.cxx,
- kwsys/testFail.c, kwsys/testHashSTL.cxx, kwsys/testIOS.cxx,
- kwsys/testRegistry.cxx, kwsys/testSystemTools.cxx,
- kwsys/testTerminal.c, CMakeLists.txt: ENH: Cleaned up KWSys tests
- to use test drivers.
-
-2007-03-03 10:09 king
-
- * Modules/Platform/Windows-bcc32.cmake: BUG: Do not create import
- library for MODULEs. The TARGET_IMPLIB name is not set correctly
- for MODULE rules anyway.
-
-2007-03-02 21:12 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-02 14:31 martink
-
- * Source/: cmMakefileUtilityTargetGenerator.cxx,
- cmMakefileUtilityTargetGenerator.h: BUG: fix for build order
-
-2007-03-02 11:33 andy
-
- * Modules/Platform/Darwin.cmake, Source/cmTryCompileCommand.cxx:
- BUG: Propagate platform settings such as CMAKE_OSX_ARCHITECTURES
- to the try compile
-
-2007-03-02 10:57 martink
-
- * Modules/SystemInformation.cmake: ENH: limit the output of system
- information to no more than 50K per file
-
-2007-03-02 10:50 martink
-
- * Source/: cmLocalVisualStudio7Generator.cxx,
- cmWin32ProcessExecution.cxx: COMP: fix some w4 warnings
-
-2007-03-02 10:49 martink
-
- * Source/cmake.cxx: ENH: fix compiler warning
-
-2007-03-02 10:48 martink
-
- * Source/: kwsys/SystemTools.cxx, cmFileCommand.cxx: COMP: fix
- warnings
-
-2007-03-01 23:28 king
-
- * Source/kwsys/auto_ptr.hxx.in: COMP: More workarounds for Borland.
-
-2007-03-01 21:15 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-03-01 16:44 king
-
- * Modules/FindQt4.cmake: BUG: Fix bug introduced by revision 1.67.
- The qmake query mode prints information to stderr on some
- platforms. The OUTPUT_VARIABLE and ERROR_VARIABLE must be the
- same variable to get all the output.
-
-2007-03-01 16:23 martink
-
- * Source/cmFileCommand.cxx: COMP: fix a compiel warning
-
-2007-03-01 15:53 martink
-
- * Source/: cmFileCommand.cxx, cmFileCommand.h: ENH: added LIMIT on
- file read
-
-2007-03-01 14:52 martink
-
- * Source/kwsys/SystemTools.cxx: COMP: fix warning
-
-2007-03-01 14:30 martink
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH: added a
- limit to the getline method
-
-2007-03-01 10:53 martink
-
- * Source/cmake.cxx: BUG: a couple bugs in system informaiton
-
-2007-03-01 10:33 martink
-
- * CMakeLists.txt: BUG: bad command line
-
-2007-02-28 21:07 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-02-28 17:26 hoffman
-
- * Source/cmLocalGenerator.cxx: ENH: remove qnx special stuff that
- does not work
-
-2007-02-28 14:45 martink
-
- * Source/cmMakefile.cxx: BUG: cleanup paths in GetSourceFile to
- handle bug 2724
-
-2007-02-28 14:29 hoffman
-
- * Source/: cmLocalGenerator.cxx, cmLocalUnixMakefileGenerator3.cxx:
- ENH: one more pass at paths with spaces and parens
-
-2007-02-28 12:25 martink
-
- * CMakeLists.txt, Source/CMakeLists.txt, Source/cmake.cxx: BUG:
- allow system information to accept the -G option
-
-2007-02-28 09:36 king
-
- * Source/kwsys/auto_ptr.hxx.in: BUG: Assignment should always use
- reset().
-
-2007-02-28 09:35 king
-
- * Source/kwsys/auto_ptr.hxx.in: COMP: Fix for auto_ptr_ref on
- Borland 5.8.
-
-2007-02-28 09:33 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Fix for
- cmake_force target in Borland Makefiles.
-
-2007-02-27 16:41 martink
-
- * Source/cmake.cxx: BUG: fix to naming of results file
-
-2007-02-27 15:11 hoffman
-
- * Tests/SubDirSpaces/: CMakeLists.txt,
- ThirdSubDir/testfromauxsubdir.c: ENH: watcom wmake can not handle
- () in the path with cd command
-
-2007-02-27 13:34 hoffman
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: add a fix for
- spaces in the path again...
-
-2007-02-27 13:04 martink
-
- * CMakeLists.txt, Source/CMakeLists.txt: BUG: possible fix for new
- SystemInfo test
-
-2007-02-27 12:47 martink
-
- * Source/cmake.cxx: BUG: fix for unused variable
-
-2007-02-27 12:10 hoffman
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: fix for spaces in
- the path and mingw
-
-2007-02-27 11:59 martink
-
- * Source/CMakeLists.txt: BUG: possible fix for new SystemInfo test
-
-2007-02-27 10:10 martink
-
- * Source/: CMakeLists.txt, cmake.cxx, cmake.h, cmakemain.cxx: ENH:
- added --system-information option to CMake
-
-2007-02-27 09:43 martink
-
- * Modules/: SystemInformation.cmake, SystemInformation.in: ENH:
- improvements
-
-2007-02-26 13:40 martink
-
- * Modules/: SystemInformation.cmake, SystemInformation.in: ENH:
- added for system information command line option
-
-2007-02-26 12:08 king
-
- * Source/kwsys/auto_ptr.hxx.in: COMP: Added line accidentally
- removed.
-
-2007-02-26 12:06 king
-
- * Source/kwsys/auto_ptr.hxx.in: BUG: Fixed implementation of
- auto_ptr_ref.
-
-2007-02-26 11:56 hoffman
-
- * Source/cmLocalGenerator.cxx: ENH: go back to \ escapes for qnx
-
-2007-02-26 11:41 hoffman
-
- * Source/cmLocalGenerator.cxx: ENH: go back to EscapeForShell
- version
-
-2007-02-26 10:46 king
-
- * Tests/SubDirSpaces/CMakeLists.txt: COMP: Disable rpath with
- spaces on some systems.
-
-2007-02-25 21:02 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-02-25 19:22 alex
-
- * Modules/FindGettext.cmake: BUG: fix typo reported by Duncan Mac
- Vicar
-
- Alex
-
-2007-02-25 16:13 hoffman
-
- * Source/cmLocalGenerator.cxx: ENH: try and use \ for space and ()
- escapes
-
-2007-02-23 20:37 hoffman
-
- * Source/cmLocalGenerator.cxx: ENH: try another thing 3
-
-2007-02-23 17:38 hoffman
-
- * Source/cmLocalGenerator.cxx: ENH: try another thing
-
-2007-02-23 17:07 hoffman
-
- * Source/cmLocalGenerator.cxx: ENH: add some debug stuff
-
-2007-02-23 16:44 hoffman
-
- * Source/cmLocalGenerator.cxx: ENH: add some debug stuff
-
-2007-02-23 14:37 andy
-
- * Source/CMakeLists.txt: COMP: Disable test until generators are
- fixed
-
-2007-02-23 11:30 andy
-
- * Source/CMakeLists.txt: ENH: Try to fix spaces in the path problem
-
-2007-02-23 11:17 andy
-
- * Tests/SimpleExclude/run.cmake.in: ENH: Try to fix spaces in the
- path problem
-
-2007-02-23 10:31 andy
-
- * Tests/SimpleExclude/: dirC/dirA/CMakeLists.txt,
- dirC/dirB/CMakeLists.txt, dirD/CMakeLists.txt: ENH: Force
- libraries to be static
-
-2007-02-23 09:54 martink
-
- * Source/cmGetTestPropertyCommand.h: ENH: added some documentation
- on how to find the default properties of a test
-
-2007-02-23 09:46 andy
-
- * Source/: CMakeLists.txt, cmLocalGenerator.cxx,
- cmLocalGenerator.h, cmMakefile.cxx, cmTarget.cxx, cmTarget.h:
- ENH: Make EXCLUDE_FROM_ALL a target and directory properties.
- Also, make IsInAll use EXCLUDE_FROM_ALL. Also, enable the test
- that tests this
-
-2007-02-23 09:45 andy
-
- * Source/cmIncludeDirectoryCommand.cxx: BUG: Produce error when
- include directories is invoked with an empty list
-
-2007-02-22 17:34 hoffman
-
- * Source/cmLocalGenerator.cxx: ENH: hack put the hack back for qnx
- to try and fix spaces in the path
-
-2007-02-22 17:26 hoffman
-
- * Source/cmLocalGenerator.cxx: ENH: undo hack and try to get
- dashboard back
-
-2007-02-22 17:15 hoffman
-
- * Tests/SubDirSpaces/CMakeLists.txt: ENH: add a comment
-
-2007-02-22 16:23 king
-
- * Source/cmLocalGenerator.cxx: BUG: Hack to try working around a
- problem with spaces in an rpath on QNX.
-
-2007-02-22 15:43 hoffman
-
- * Tests/SubDirSpaces/CMakeLists.txt: ENH: show make results on the
- dashboard
-
-2007-02-22 15:33 hoffman
-
- * Source/cmLocalGenerator.cxx: ENH: add new escape stuff
-
-2007-02-22 15:27 king
-
- * Source/kwsys/SystemTools.cxx: BUG: Fix bug#4482.
-
-2007-02-22 15:16 andy
-
- * Tests/SimpleExclude/run.cmake.in: COMP: Use exec_program instead
- of execute_process
-
-2007-02-22 11:42 andy
-
- * Tests/SimpleExclude/: CMakeLists.txt, run.cmake.in: ENH: Improve
- test
-
-2007-02-22 10:31 hoffman
-
- * Source/CMakeLists.txt: ENH: actually keep the output
-
-2007-02-22 10:05 hoffman
-
- * Source/CMakeLists.txt: ENH: make sure EXECUTE_PROCESS is there
- because in bootstrap it is not
-
-2007-02-22 09:48 hoffman
-
- * Source/kwsys/SystemTools.cxx: COMP: remove warning
-
-2007-02-22 09:44 martink
-
- * Source/CPack/cmCPackOSXX11Generator.cxx: STYLE: fix someones line
- length
-
-2007-02-22 09:10 andy
-
- * Source/cmake.cxx: BUG: Produce an error when the script is not
- found
-
-2007-02-22 08:39 andy
-
- * Tests/SimpleExclude/: CMakeLists.txt, dirC/CMakeLists.txt,
- dirC/dirA/CMakeLists.txt, dirC/dirA/t1.c, dirC/dirA/t2.c,
- dirC/dirA/t3.c, dirC/dirA/t4.c, dirC/dirA/t5.c,
- dirC/dirB/CMakeLists.txt, dirC/dirB/t6.c, dirC/dirB/t7.c,
- dirD/CMakeLists.txt, dirD/t8.c, dirD/t9.c: ENH: Add simple
- exclusion test for subdirectories
-
-2007-02-21 21:24 hoffman
-
- * Source/CMakeLists.txt, Source/cmLocalGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmSystemTools.cxx, Source/cmSystemTools.h,
- Source/kwsys/SystemTools.cxx, Tests/SubDirSpaces/CMakeLists.txt,
- Tests/SubDirSpaces/Some(x86) Sources/CMakeLists.txt,
- Tests/SubDirSpaces/Some(x86) Sources/test.c,
- Tests/SubDirSpaces/ThirdSubDir/testfromauxsubdir.c: ENH: fix
- parens in the path with spaces in the path
-
-2007-02-21 14:58 martink
-
- * Source/CMakeLists.txt: ENH: turn on spaces test for more
- platforms
-
-2007-02-21 14:07 hoffman
-
- * Source/cmGlobalGenerator.cxx: ENH: get rid of some extra erase
- calls
-
-2007-02-21 14:07 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: STYLE: fix line length
-
-2007-02-21 14:01 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmXCodeObject.cxx: BUG: fix
- for quotes in strings for flags #4022
-
-2007-02-21 13:33 king
-
- * Source/kwsys/CMakeLists.txt: COMP: Disable LFS on AIX.
-
-2007-02-21 12:19 martink
-
- * Source/cmGlobalWatcomWMakeGenerator.cxx: ENH: remove unused
- variable
-
-2007-02-21 11:58 martink
-
- * Source/CMakeLists.txt: ENH: turn on spaces test for more
- platforms
-
-2007-02-21 11:45 hoffman
-
- * Modules/Platform/AIX.cmake: ENH: force c++ when building c++
- objects
-
-2007-02-21 10:29 hoffman
-
- * Modules/CMakeDetermineSystem.cmake: ENH: better processor
- detection on linux
-
-2007-02-21 10:03 hoffman
-
- * Modules/CMakeDetermineFortranCompiler.cmake: ENH: remove df
- because df is a unix utilitiy
-
-2007-02-20 16:43 hoffman
-
- * Modules/: CMakeDetermineFortranCompiler.cmake,
- Platform/Windows-df.cmake: BUG: fix for bug 3950 add support for
- df compiler on windows
-
-2007-02-20 16:35 hoffman
-
- * Modules/FindQt4.cmake: BUG: fix for bug # 3954 glib with qt
-
-2007-02-20 16:05 alex
-
- * Modules/FindKDE4.cmake: STYLE: fix docs for FindKDE4.cmake
-
- Alex
-
-2007-02-20 16:02 alex
-
- * Modules/: FindKDE3.cmake, KDE3Macros.cmake: BUG: remove
- KDE3_ENABLE_FINAL (#4140): it doesn't work currently and I don't
- have the time to fix this since it would require bigger changes.
- Maybe I'll do this if the KDE3 support of CMake becomes more
- widely used.
-
- Alex
-
-2007-02-20 16:00 alex
-
- * Modules/FindLibXml2.cmake: STYLE: don't put the copyright notice
- twice in the file
-
- Alex
-
-2007-02-20 15:15 hoffman
-
- * Modules/FindQt4.cmake: BUG: fix for bug 4187 fix typo in docs
-
-2007-02-20 15:14 hoffman
-
- * Modules/CMakeUnixFindMake.cmake: BUG: fix for 4188 look for smake
- as well as gmake and make
-
-2007-02-20 15:09 hoffman
-
- * Source/cmFileCommand.h: ENH: fix spelling error bug # 4233
-
-2007-02-20 15:03 martink
-
- * Source/CMakeLists.txt: ENH: only add the test for some platforms
-
-2007-02-20 13:52 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: fix source extensions
- fror txt on xcode
-
-2007-02-20 12:28 martink
-
- * Source/cmMakefileTargetGenerator.cxx: ENH: fix for Watcom
-
-2007-02-20 11:33 hoffman
-
- * Modules/Platform/QNX.cmake: ENH: try to force c++ on qnx
-
-2007-02-20 11:14 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: fix for force language
- stuff
-
-2007-02-20 10:57 hoffman
-
- * Tests/SetLang/CMakeLists.txt: ENH: verbose
-
-2007-02-20 10:52 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx: ENH: fix crash
-
-2007-02-20 09:54 hoffman
-
- * Modules/InstallRequiredSystemLibraries.cmake: BUG: fix for bug
- 4420 add language dll's to mfc install
-
-2007-02-20 09:35 hoffman
-
- * Source/CMakeLists.txt, Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Tests/SetLang/CMakeLists.txt, Tests/SetLang/bar.c,
- Tests/SetLang/foo.c: BUG: fix for bug 4423 set language fixes
-
-2007-02-19 16:34 hoffman
-
- * Source/CMakeLists.txt: ENH: remove ConvLib test for now
-
-2007-02-19 15:12 hoffman
-
- * Source/CMakeLists.txt: ENH: use correct name
-
-2007-02-19 15:07 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: use project not target
- name
-
-2007-02-19 14:48 martink
-
- * Source/CMakeLists.txt, Tests/SubDirSpaces/CMakeLists.txt: ENH:
- make the test really test targets with spaces
-
-2007-02-19 14:32 martink
-
- * Source/: cmTarget.cxx, cmTarget.h: BUG: fix accidental checkin
-
-2007-02-19 14:26 martink
-
- * Tests/SubDirSpaces/Executable Sources/: CMakeLists.txt, test.cxx:
- ENH: added used sources with a path that has spaces
-
-2007-02-19 14:25 martink
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx,
- cmMakefileTargetGenerator.cxx: ENH: fixed more bugs with spaces
- in the path
-
-2007-02-19 13:53 king
-
- * Modules/Platform/gcc.cmake: BUG: Applied patch from bug#4462.
-
-2007-02-19 13:44 hoffman
-
- * Modules/FindQt4.cmake: BUG: fix for bug 4464 handle qmake errors
- better
-
-2007-02-19 13:26 hoffman
-
- * Source/CMakeLists.txt, Tests/ConvLibrary/CMakeLists.txt: ENH: add
- test for conv libraries
-
-2007-02-19 13:20 martink
-
- * Source/: CMakeLists.txt, cmTarget.cxx, cmTarget.h: ENH: turn on
- spaces in path test
-
-2007-02-19 12:25 martink
-
- * Source/: cmMakefileTargetGenerator.cxx,
- cmLocalUnixMakefileGenerator3.cxx: BUG: fix for spaces in path
- for nmake
-
-2007-02-19 12:21 martink
-
- * Tests/SubDirSpaces/: CMakeLists.txt,
- vcl_algorithm+vcl_pair+double.foo.c,
- vcl_algorithm_vcl_pair_double.foo.c, Another
- Subdir/pair+int.int.c, Another Subdir/pair_int.int.c, Another
- Subdir/secondone.c, Another Subdir/testfromsubdir.c,
- Executable/CMakeLists.txt, Executable/test.cxx, Some
- Examples/CMakeLists.txt, Some Examples/example1/CMakeLists.txt,
- Some Examples/example1/example1.cxx, Some
- Examples/example2/CMakeLists.txt, Some
- Examples/example2/example2.cxx, ThirdSubDir/pair+int.int1.c,
- ThirdSubDir/pair_int.int1.c, ThirdSubDir/pair_p_int.int1.c,
- ThirdSubDir/testfromauxsubdir.c, ThirdSubDir/thirdone.c: ENH: new
- test for spaces in the tree structure
-
-2007-02-18 21:44 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-02-18 09:31 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx: STYLE: fix warning
-
-2007-02-17 22:43 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-02-17 11:43 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: fix for external object
- test
-
-2007-02-17 08:46 hoffman
-
- * Source/: cmLocalGenerator.cxx, cmLocalVisualStudio7Generator.cxx,
- cmLocalXCodeGenerator.cxx, cmTarget.cxx,
- CPack/cmCPackOSXX11Generator.cxx: STYLE: fix line length issues
-
-2007-02-17 08:38 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmLocalGenerator.cxx: ENH:
- remove warnings and debug statement
-
-2007-02-16 16:45 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h,
- Tests/ConvLibrary/bartest.cxx: ENH: fix for vs ide
-
-2007-02-16 16:12 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx,
- Source/cmGlobalXCodeGenerator.h, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalUnixMakefileGenerator3.h,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio6Generator.h,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h,
- Source/cmLocalVisualStudioGenerator.cxx,
- Source/cmLocalVisualStudioGenerator.h,
- Source/cmLocalXCodeGenerator.cxx, Source/cmLocalXCodeGenerator.h,
- Source/cmMakefileTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.h, Source/cmTarget.cxx,
- Source/cmTarget.h, Tests/ConvLibrary/CMakeLists.txt,
- Tests/ConvLibrary/bar.c, Tests/ConvLibrary/bartest.cxx,
- Tests/ConvLibrary/foo.cxx, Tests/ConvLibrary/sub1/car.cxx: ENH:
- check in initial conv library stuff
-
-2007-02-16 15:24 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-02-15 15:07 andy
-
- * Source/cmake.cxx: BUG: Overwrite the symlink if it already
- exists. Close Bug #4418 - cmake -create-symlink doesn't overwrite
- existing symlinks
-
-2007-02-15 13:36 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Source/cmCommandArgumentParserHelper.cxx,
- Source/cmCommandArgumentParserHelper.h, Source/cmMakefile.cxx:
- ENH: move @@ fix from main tree
-
-2007-02-15 12:45 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/FindQt4.cmake,
- Modules/InstallRequiredSystemLibraries.cmake,
- Source/cmAddDependenciesCommand.cxx, Source/cmIfCommand.cxx,
- Source/cmIfCommand.h, Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmSetTargetPropertiesCommand.cxx,
- Source/kwsys/SystemTools.cxx, Source/kwsys/SystemTools.cxx.bak:
- ENH: merge in changes from main tree, including fix for exception
- stuff in vs 7
-
-2007-02-15 12:23 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: Do not hack the
- exception handling default for linker flags or for
- per-source-file flags.
-
-2007-02-14 22:24 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-02-13 22:44 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-02-13 14:12 andy
-
- * Source/CPack/cmCPackOSXX11Generator.cxx,
- Source/CPack/cmCPackOSXX11Generator.h, Modules/CPack.DS_Store.in,
- Modules/CPack.VolumeIcon.icns.in,
- Modules/CPack.background.png.in, Modules/CPack.cmake: ENH: More
- work on the packaging. Add Applicaitons, add icons, etc
-
-2007-02-12 23:16 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-02-12 12:06 hoffman
-
- * Utilities/Release/: create-cmake-release.cmake,
- release_cmake.cmake: ENH: add cygwin cpack stuff to release
- scripts
-
-2007-02-12 09:15 hoffman
-
- * Utilities/Release/vogon_cygwin.cmake: ENH: add cygwin on vogon
-
-2007-02-11 22:34 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-02-10 22:23 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-02-10 09:52 alex
-
- * Modules/FindPNG.cmake: STYLE: remove empty line, so the
- documentation for the module is complete again
-
- Alex
-
-2007-02-09 22:14 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-02-09 13:44 hoffman
-
- * Source/: cmCommandArgumentParserHelper.cxx,
- cmCommandArgumentParserHelper.h, cmMakefile.cxx: ENH: add atonly
- support to cmCommandArgumentParserHelper.cxx and remove old
- non-yacc parser code from cmMakefile.cxx
-
-2007-02-08 22:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-02-08 16:18 king
-
- * Source/CMakeLists.txt, Tests/PrecompiledHeader/CMakeLists.txt,
- Tests/PrecompiledHeader/foo1.c, Tests/PrecompiledHeader/foo2.c,
- Tests/PrecompiledHeader/foo_precompile.c,
- Tests/PrecompiledHeader/include/foo.h,
- Tests/PrecompiledHeader/include/foo_precompiled.h: ENH: Added
- PrecompiledHeader test for MSVC compilers.
-
-2007-02-07 22:02 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-02-07 14:50 alex
-
- * Modules/: UseEcos.cmake, ecos_clean.cmake: ENH: now also the
- "ecosclean" target works with MS nmake
-
- Alex
-
-2007-02-07 11:50 hoffman
-
- * Modules/FindQt4.cmake: BUG: fix for bug 4399
-
-2007-02-07 11:49 hoffman
-
- * Source/: cmAddDependenciesCommand.cxx,
- cmSetTargetPropertiesCommand.cxx: BUG: fix for bug 4414, find
- targets in the global generator for set_target_properties and
- add_dependencies
-
-2007-02-07 10:26 hoffman
-
- * Modules/InstallRequiredSystemLibraries.cmake: BUG: fix for 4420
- Unicode and MBC versions of the MFC
-
-2007-02-07 09:23 king
-
- * Source/cmDependsC.cxx: STYLE: Fixed line-too-long.
-
-2007-02-06 21:56 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-02-06 16:03 hoffman
-
- * Source/cmSetSourceFilesPropertiesCommand.h: ENH: fix
- documentation to include source language property
-
-2007-02-06 15:05 king
-
- * Source/cmDocumentation.cxx: BUG: Patch from Alex to fix
- single-command help broken by previous patch.
-
-2007-02-06 10:01 hoffman
-
- * CMakeLists.txt, Source/CPack/cmCPackGenerators.cxx: ENH: fix
- release tree to build on mac
-
-2007-02-05 21:53 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-02-05 14:05 hoffman
-
- * Source/cmLocalUnixMakefileGenerator3.h: ENH: merge changes from
- main trunk
-
-2007-02-05 13:21 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, cmake_uninstall.cmake.in,
- Modules/CPack.cmake, Modules/FindKDE4.cmake,
- Modules/FindXMLRPC.cmake, Source/CMakeLists.txt,
- Source/cmGlobalKdevelopGenerator.cxx,
- Source/cmInstallTargetGenerator.cxx,
- Source/cmLocalKdevelopGenerator.cxx,
- Source/cmLocalKdevelopGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h,
- Source/cmLocalVisualStudioGenerator.cxx,
- Source/cmMakefileExecutableTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.cxx, Source/cmSystemTools.cxx,
- Source/cmSystemTools.h, Source/cmTarget.cxx, Source/cmTarget.h,
- Source/CPack/cmCPackGenerators.cxx,
- Source/CPack/cmCPackGenericGenerator.cxx,
- Source/CPack/cmCPackGenericGenerator.h,
- Source/CPack/cmCPackNSISGenerator.h,
- Source/CPack/cmCPackPackageMakerGenerator.h,
- Source/CPack/cmCPackSTGZGenerator.h,
- Source/CPack/cmCPackTGZGenerator.h,
- Source/CPack/cmCPackTarBZip2Generator.cxx,
- Source/CPack/cmCPackTarBZip2Generator.h,
- Source/CPack/cmCPackTarCompressGenerator.h,
- Source/CPack/cmCPackZIPGenerator.h, Source/kwsys/System.h.in,
- Source/kwsys/SystemTools.cxx,
- Tests/Complex/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt,
- Utilities/Release/Cygwin/CMakeLists.txt,
- Utilities/Release/Cygwin/README.cygwin.in,
- Utilities/Release/Cygwin/cygwin-package.sh.in,
- Utilities/Release/Cygwin/cygwin-patch.diff.in,
- Utilities/Release/Cygwin/cygwin-setup.hint.in,
- Source/CPack/cmCPackCygwinBinaryGenerator.cxx,
- Source/CPack/cmCPackCygwinBinaryGenerator.h,
- Source/CPack/cmCPackCygwinSourceGenerator.cxx,
- Source/CPack/cmCPackCygwinSourceGenerator.h: ENH: merge in
- changes from branch
-
-2007-02-05 11:13 martink
-
- * Source/CMakeLists.txt: ENH: add more time to bootstrap test
-
-2007-02-05 09:48 king
-
- * Source/: cmDependsC.cxx, cmDependsC.h: BUG: Patch from Alex to
- recompute dependencies when the include regex changes. This
- addresses bug#4168.
-
-2007-02-04 21:47 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-02-03 21:41 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-02-02 21:28 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-02-02 16:52 hoffman
-
- * Source/CPack/: cmCPackCygwinSourceGenerator.cxx,
- cmCPackTarBZip2Generator.cxx: STYLE: fix warnings
-
-2007-02-02 16:51 hoffman
-
- * Modules/FindQt4.cmake: ENH: fix depend bug in qt
-
-2007-02-02 14:40 hoffman
-
- * CMakeLists.txt, Modules/CPack.cmake, Source/CMakeLists.txt,
- Source/CPack/bills-comments.txt,
- Source/CPack/cmCPackCygwinBinaryGenerator.cxx,
- Source/CPack/cmCPackCygwinBinaryGenerator.h,
- Source/CPack/cmCPackCygwinSourceGenerator.cxx,
- Source/CPack/cmCPackCygwinSourceGenerator.h,
- Source/CPack/cmCPackGenerators.cxx,
- Source/CPack/cmCPackGenericGenerator.cxx,
- Source/CPack/cmCPackGenericGenerator.h,
- Source/CPack/cmCPackNSISGenerator.h,
- Source/CPack/cmCPackOSXX11Generator.h,
- Source/CPack/cmCPackPackageMakerGenerator.h,
- Source/CPack/cmCPackSTGZGenerator.h,
- Source/CPack/cmCPackTGZGenerator.h,
- Source/CPack/cmCPackTarBZip2Generator.cxx,
- Source/CPack/cmCPackTarBZip2Generator.h,
- Source/CPack/cmCPackTarCompressGenerator.h,
- Source/CPack/cmCPackZIPGenerator.h, Source/CPack/cygwin.readme,
- Utilities/Release/create-cmake-release.cmake,
- Utilities/Release/release_cmake.cmake,
- Utilities/Release/Cygwin/CMakeLists.txt,
- Utilities/Release/Cygwin/README.cygwin.in,
- Utilities/Release/Cygwin/cygwin-package.sh.in: ENH: add support
- for cygwin source and binary packaging
-
-2007-02-02 14:13 king
-
- * Source/cmDocumentation.h: COMP: Fix void return failure.
-
-2007-02-02 12:46 alex
-
- * Modules/FindGettext.cmake: BUG: add gettext module for working
- with GNU gettext (#4081)
-
- Alex
-
-2007-02-02 10:14 martink
-
- * Source/CMakeLists.txt: ENH: allow the dashboard to override the
- timeouts for CTestTest
-
-2007-02-02 09:11 king
-
- * Source/cmDocumentation.h: STYLE: Fixed line length and this->
- convention violations from yesterday's patch.
-
-2007-02-02 09:11 king
-
- * Source/CTest/cmCTestBuildCommand.cxx: STYLE: Fixed line-too-long.
-
-2007-02-01 20:38 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-02-01 17:06 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: STYLE: fix line length
-
-2007-02-01 16:56 king
-
- * Source/cmMakefileTargetGenerator.cxx: BUG: Use the exe/lib output
- path for .pdb file location. This addresses bug#3277 and
- bug#4287.
-
-2007-02-01 16:54 king
-
- * Source/: cmLocalVisualStudio7Generator.cxx, cmTarget.cxx,
- cmTarget.h: ENH: Added cmTarget::GetPDBName method to simplify
- computation of .pdb file name for a target.
-
-2007-02-01 16:52 king
-
- * Source/: cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx: BUG: Do not clean the .pdb
- file for a target just before it is linked! This finishes
- addressing bug#4341.
-
-2007-02-01 16:07 king
-
- * Source/cmMakefileExecutableTargetGenerator.cxx: BUG: Clean rule
- for exe pdb file should use full path.
-
-2007-02-01 15:44 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: Do not use bitwise
- OR on bool.
-
-2007-02-01 15:22 king
-
- * Source/cmLocalVisualStudio7Generator.h: STYLE: Removed unused
- method declarations.
-
-2007-02-01 15:02 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: ENH: Added a special
- flags integer field to the flag map entries. Added flags for
- user values and other special cases. Added precompiled header
- flag translation entries. This addresses bug#3512.
-
-2007-02-01 14:45 king
-
- * Source/kwsys/SystemTools.cxx: STYLE: Removed one more stray
- comment.
-
-2007-02-01 14:43 martink
-
- * Source/kwsys/SystemTools.cxx: STYLE: removed code accidently
- checked in
-
-2007-02-01 14:11 martink
-
- * Source/kwsys/SystemTools.cxx: BUG: fix for bug number 3320
-
-2007-02-01 13:04 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: COMP: Removed unused
- variable.
-
-2007-02-01 12:02 king
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt: ENH: Added smoke
- test for user-value flag mapping for VS IDE.
-
-2007-02-01 12:00 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: ENH: Added mapping of
- /NODEFAULTLIB flag when no values are provided.
-
-2007-02-01 11:49 king
-
- * Source/: cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h: ENH: Reimplemented parsing and
- mapping of flags into vcproj file attribute options. This cleans
- up and centralizes a few things. It is in preparation for
- dealing with precompiled header flags for bug #3512 since they
- require some special handling.
-
-2007-02-01 11:45 king
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Added
- EscapeWindowsShellArgument and ParseWindowsCommandLine methods to
- cmSystemTools.
-
-2007-02-01 11:33 martink
-
- * Source/cmMakefileTargetGenerator.cxx: BUG: fix for bug number
- 3964
-
-2007-02-01 10:38 king
-
- * Source/: cmDocumentation.cxx, cmDocumentation.h: ENH: Patch from
- Alex to improve implementation and prepare for splitting the man
- page into more sections.
-
-2007-02-01 09:57 king
-
- * Source/: cmInstallTargetGenerator.cxx,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h,
- cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx, cmTarget.cxx, cmTarget.h:
- BUG: The .pdb file generated for a library or executable should
- match the real file name used for the target. This addresses
- bug#3277.
-
-2007-01-31 20:07 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-01-31 16:50 hoffman
-
- * Source/CPack/: cmCPackCygwinSourceGenerator.cxx,
- cmCPackCygwinSourceGenerator.h: ENH: commit cygwin source
- generator files, not used yet
-
-2007-01-31 16:49 hoffman
-
- * Source/cmLocalGenerator.cxx: ENH: do not use crazy long paths to
- object files for try compile
-
-2007-01-31 16:48 hoffman
-
- * Utilities/Release/Cygwin/: CMakeLists.txt, README.cygwin.in,
- cygwin-package.sh.in, cygwin-patch.diff.in, cygwin-setup.hint.in:
- ENH: add support files for cpack cygwin setup package stuff
-
-2007-01-31 15:06 alex
-
- * Modules/FindQt4.cmake: BUG: finally fix #4331, the previous
- version just caught the tag, the filename not at all
-
- Alex
-
-2007-01-31 14:00 hoffman
-
- * Tests/TryCompile/CMakeLists.txt: ENH: add more output when test
- fails
-
-2007-01-31 13:54 andy
-
- * Source/CMakeLists.txt: COMP: Remove osx bundle from
- OSXScriptLauncher
-
-2007-01-31 13:53 andy
-
- * Source/CPack/OSXScriptLauncher.cxx: COMP: Use new API
-
-2007-01-31 13:37 andy
-
- * Source/CMakeLists.txt: COMP: Add missing file in the installation
-
-2007-01-31 13:34 hoffman
-
- * Source/: cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h: BUG: make sure external vs
- projects use the GUID in the project if it has one.
-
-2007-01-30 20:14 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-01-30 15:43 alex
-
- * Modules/FindKDE4.cmake: STYLE: KDEDIR is deprecated and not used,
- so also document that KDEDIRS is used instead
-
- Alex
-
-2007-01-30 11:48 andy
-
- * Source/CTest/cmCTestBuildCommand.cxx: ENH: Allow to specify build
- target
-
-2007-01-30 11:48 andy
-
- * Source/CMakeLists.txt: COMP: Fix bootstrap
-
-2007-01-30 11:35 martink
-
- * Source/: CMakeLists.txt, cmGlobalGenerator.cxx,
- cmGlobalGenerator.h, ctest.cxx,
- CTest/cmCTestBuildAndTestHandler.cxx: BUG: fixes so that
- --build-and-test will honor timeouts
-
-2007-01-30 11:32 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: allow copy if different from a
- file to a directory to work
-
-2007-01-29 20:30 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-01-29 12:42 martink
-
- * Source/cmCTest.cxx: BUG: fix in the timeout code
-
-2007-01-28 20:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-01-27 20:09 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-01-27 15:29 malaterre
-
- * Source/kwsys/System.h.in: STYLE: Fix typo
-
-2007-01-26 20:14 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-01-26 15:06 martink
-
- * Source/cmIfCommand.h: STYLE: improve IF documentation to cover
- elseif
-
-2007-01-26 14:26 king
-
- * Source/kwsys/CMakeLists.txt: BUG: Added use of
- KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT for header file install
- rules.
-
-2007-01-26 09:31 martink
-
- * Source/CTest/cmCTestTestHandler.cxx: COMP: fix warning
-
-2007-01-25 17:05 hoffman
-
- * Source/cmSubdirCommand.h: BUG: remove early ;
-
-2007-01-25 15:44 hoffman
-
- * Source/: CMakeLists.txt, cmGlobalKdevelopGenerator.cxx,
- cmLocalKdevelopGenerator.cxx, cmLocalKdevelopGenerator.h,
- cmLocalUnixMakefileGenerator3.h: BUG: fix for 4186, kdevelop
- adding file twice
-
-2007-01-25 11:16 martink
-
- * Source/: cmCTest.cxx, cmCTest.h, cmTest.cxx, ctest.cxx,
- CTest/cmCTestBuildAndTestHandler.cxx,
- CTest/cmCTestBuildAndTestHandler.h, CTest/cmCTestTestHandler.cxx,
- CTest/cmCTestTestHandler.h: ENH: added per test timeout support
-
-2007-01-24 13:45 king
-
- * Source/: cmExecProgramCommand.h, cmInstallFilesCommand.h,
- cmInstallProgramsCommand.h, cmInstallTargetsCommand.h,
- cmLinkLibrariesCommand.h, cmMakeDirectoryCommand.h,
- cmRemoveCommand.h, cmSubdirCommand.h, cmSubdirDependsCommand.h,
- cmVariableRequiresCommand.h, cmWriteFileCommand.h: ENH: Patch
- from Alex to make deprecated command documentation more
- consistent.
-
-2007-01-24 13:40 king
-
- * Source/: cmUseMangledMesaCommand.h, cmVariableRequiresCommand.h:
- ENH: Patch from Alex to document this command as discouraged.
-
-2007-01-24 07:46 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-01-23 14:28 hoffman
-
- * Source/cmLocalGenerator.cxx: ENH: this does not need to be safe
- as the value is checked
-
-2007-01-23 14:07 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-01-23 13:41 alex
-
- * Modules/UseEcos.cmake: BUG: reent.c wasn't intended to be
- committed, too special
-
- Alex
-
-2007-01-23 13:29 alex
-
- * Modules/UseEcos.cmake: STYLE: use even more absolute paths, can't
- hurt for out-of-source builds STYLE: use
- SET_SOURCE_FILES_PROPERTIES() on multiple files at once instead
- of interating over each one of them STYLE: no need to add
- target.ld to the clean-files, this is done now automatically by
- add_custom_command() ENH: now also MS nmake can be used to build
- ecos apps
-
- Alex
-
-2007-01-23 13:08 hoffman
-
- * Source/cmLocalGenerator.cxx: ENH: avoid crash, but do not make it
- an error if include flags is missing from a language
-
-2007-01-23 11:39 hoffman
-
- * Source/cmLocalGenerator.cxx: ENH: make the include flag required
- for a language avoids seg fault
-
-2007-01-23 11:25 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx: ENH: undo bug fix
- because of failed test
-
-2007-01-23 10:50 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx: ENH: add link flags for
- debug/release etc
-
-2007-01-22 20:14 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-01-22 10:52 king
-
- * Source/cmWriteFileCommand.h: ENH: Patch from Alex to document
- WRITE_FILE as a discouraged command.
-
-2007-01-22 10:52 king
-
- * Source/: cmDocumentation.cxx, cmDocumentation.h: COMP: Patch from
- Alex for const correctness.
-
-2007-01-22 10:39 king
-
- * cmake_uninstall.cmake.in: BUG: Patch from bug#4312 to make
- uninstall work with DESTDIR.
-
-2007-01-21 20:07 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-01-20 21:05 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-01-20 10:05 andy
-
- * Modules/FindQt4.cmake: COMP: Fix typo that makes all Qt4 builds
- break
-
-2007-01-19 20:10 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-01-19 11:55 hoffman
-
- * Modules/FindQt4.cmake: BUG: fix for bug 4331
-
-2007-01-18 20:35 hoffman
-
- * Modules/FindQt4.cmake: BUG: fix for bug 4331
-
-2007-01-18 20:10 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-01-18 16:10 hoffman
-
- * Source/cmLocalVisualStudioGenerator.cxx: ENH: do not use relative
- paths for custom command commands if they working directory is
- used
-
-2007-01-17 14:06 alex
-
- * Modules/UseEcos.cmake: ENH: the ecos headers are always in the
- binary dir
-
- Alex
-
-2007-01-17 13:57 alex
-
- * Modules/UseEcos.cmake: ENH: building ecos apps now seems to work
- also out-of-source
-
- Alex
-
-2007-01-17 13:45 alex
-
- * Modules/UseEcos.cmake: BUG: also check that tclsh is available,
- otherwise you can't build any eCos stuff ENH: make the name of
- the config file ecos.ecc adjustable via the new variable
- ECOS_CONFIG_FILE
-
- Alex
-
-2007-01-16 14:37 clinton
-
- * Source/kwsys/SystemTools.cxx: ENH: Add support for "~otheruser/"
-
-2007-01-15 12:31 andy
-
- * Source/CPack/cmCPackGenericGenerator.cxx: STYLE: Fix kwstyle
-
-2007-01-15 12:12 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: STYLE: fix link lenght
- issue
-
-2007-01-14 20:10 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-01-13 20:12 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-01-12 20:40 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-01-12 16:47 clinton
-
- * Source/kwsys/SystemTools.cxx: ENH: Handle "~" in SplitPath.
-
-2007-01-12 09:53 hoffman
-
- * Utilities/Release/cygwin-package.sh.in: ENH: break it again
-
-2007-01-12 09:46 hoffman
-
- * Utilities/Release/cygwin-package.sh.in: ENH: fix for newer cygwin
-
-2007-01-12 09:18 hoffman
-
- * Utilities/Release/cmake_release.sh: ENH: change version of curses
-
-2007-01-11 21:02 hoffman
-
- * Source/: cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h: BUG: fix for bug 4239,
- NODEFAULTLIB flag support in ide
-
-2007-01-11 20:54 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-01-11 10:49 andy
-
- * Source/CPack/: cmCPackGenericGenerator.cxx,
- cmCPackGenericGenerator.h: STYLE: Fix kwstyle issues
-
-2007-01-10 20:54 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-01-10 19:59 hoffman
-
- * Source/CPack/OSXScriptLauncher.cxx: ENH: fix warning and code
- style
-
-2007-01-10 18:33 andy
-
- * Modules/CPack.RuntimeScript.in: ENH: Change permission for
- getdisplay.sh to make the runtimescript work
-
-2007-01-10 15:41 hoffman
-
- * Utilities/Release/cygwin-package.sh.in: ENH: remove old docs
-
-2007-01-10 15:30 andy
-
- * Modules/CPack.OSXScriptLauncher.in,
- Modules/CPack.OSXX11.Info.plist.in,
- Modules/CPack.RuntimeScript.in, Source/CMakeLists.txt,
- Source/CPack/OSXScriptLauncher.cxx,
- Source/CPack/cmCPackGenerators.cxx,
- Source/CPack/cmCPackGenericGenerator.cxx,
- Source/CPack/cmCPackGenericGenerator.h,
- Source/CPack/cmCPackOSXX11Generator.cxx,
- Source/CPack/cmCPackOSXX11Generator.h: ENH: First pass at CPack
- generator for OSX X11 applications. This are applications that
- require X11 to work. This is not really installed but a bundle
- packager
-
-2007-01-10 14:27 hoffman
-
- * Utilities/Release/cmake_release.sh: ENH: create cygwin
-
-2007-01-10 12:39 hoffman
-
- * CMakeLists.txt: ENH: make this the final 2.4.6
-
-2007-01-09 21:02 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-01-08 21:01 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-01-08 15:12 king
-
- * Source/kwsys/SharedForward.h.in: STYLE: Fixed documentation of
- how to produce forwarding executables for multi-configuration
- builds with CMAKE_INTDIR.
-
-2007-01-07 21:05 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-01-06 22:56 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-01-06 00:49 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-01-04 17:29 alex
-
- * Modules/FindQt4.cmake: ENH: if a wrong qmake has been found, mark
- it as invalid in the cache, so that it is searched again the next
- time cmake runs Tested in KDE since Jul 5th:
- http://websvn.kde.org/trunk/KDE/kdelibs/cmake/modules/FindQt4.cmake?rev=558318&view=rev
-
- Alex
-
-2007-01-04 16:50 alex
-
- * Modules/: FindQt4.cmake, UseQt4.cmake: ENH: add QT_USE_QTDBUS as
- it exists for all other modules too
-
- Alex
-
-2007-01-04 16:35 alex
-
- * Modules/FindQt4.cmake: BUG: also look for qmake4, as it is named
- on OpenBSD
-
- Alex
-
-2007-01-04 16:03 martink
-
- * Source/cmAddLibraryCommand.cxx: BUG: fix for bad argument
- handling
-
-2007-01-04 14:54 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-01-04 13:02 martink
-
- * Source/cmPropertyMap.cxx: ENH: change STRICT to CMAKE_STRICT
-
-2007-01-04 10:18 hoffman
-
- * CMakeLists.txt: ENH: add RC stuff to main tree
-
-2007-01-04 03:53 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-01-03 18:20 alex
-
- * Modules/FindQt4.cmake: ENH: partly sync with KDE svn: add the
- macros for generating the dbus files
-
- Alex
-
-2007-01-03 17:50 alex
-
- * Modules/FindQt4.cmake: ENH: mark more variables ADVANCED
-
- Alex
-
-2007-01-03 17:32 alex
-
- * Modules/FindQt4.cmake: ENH: partly sync with KDE svn: handle
- QtMain more like the other libs
-
- Alex
-
-2007-01-03 17:00 alex
-
- * Modules/FindQt4.cmake: BUG: argument names in macros are not real
- variables, which can lead to problems, which we fixed for KDE in
- Trysil:
- http://websvn.kde.org/trunk/KDE/kdelibs/cmake/modules/FindQt4.cmake?rev=557470&r1=557241&r2=557470
-
- Alex
-
-2007-01-03 16:48 alex
-
- * Modules/FindQt4.cmake: STYLE: some more space to make it easier
- to read
-
- Alex
-
-2007-01-03 16:38 alex
-
- * Modules/FindQt4.cmake: ENH: partly sync with KDE svn: also find
- the QtDBus and the QtDesignerComponents libraries
-
- Alex
-
-2007-01-03 16:09 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Modules/CPack.STGZ_Header.sh.in, Modules/FindDoxygen.cmake,
- Modules/FindJNI.cmake, Modules/FindRuby.cmake,
- Source/cmFindBase.cxx, Source/cmFindBase.h,
- Tests/CTestTest3/test.cmake.in,
- Tests/CustComDepend/CMakeLists.txt, Tests/CustComDepend/bar.h,
- Tests/CustComDepend/foo.cxx: ENH: merge from main tree
-
-2007-01-03 16:01 alex
-
- * Modules/FindQt4.cmake: ENH: partly sync with the KDE vesion: find
- the dbus tools coming with Qt since 4.2
-
- Alex
-
-2007-01-03 10:19 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Source/CMakeLists.txt,
- Source/cmGlobalUnixMakefileGenerator3.h,
- Source/cmLocalGenerator.cxx,
- Source/cmMakefileExecutableTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.h,
- Source/cmMakefileUtilityTargetGenerator.cxx, Source/cmTarget.cxx:
- ENH: merge in fixes from main tree
-
-2007-01-03 04:20 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-01-02 00:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2007-01-01 04:02 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-31 03:29 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-30 03:24 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-29 19:20 hoffman
-
- * Tests/CustComDepend/: CMakeLists.txt, bar.h, foo.cxx: ENH: try to
- fix test on watcom
-
-2006-12-29 03:29 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-28 15:31 hoffman
-
- * Source/: cmFindBase.cxx, cmFindBase.h: BUG: fix problem with path
- suffix and mac frameworks and find stuff, showed up in
- FindPythonLibs.cmake
-
-2006-12-28 03:23 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-27 03:27 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-26 08:47 andy
-
- * Modules/FindJNI.cmake: ENH: Support JVM on Mac
-
-2006-12-26 03:27 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-25 03:25 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-24 03:24 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-23 03:38 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-22 03:36 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-21 10:24 utkarsh
-
- * Source/kwsys/CommandLineArguments.cxx: BUG: reverting previous
- change.
-
-2006-12-21 09:52 utkarsh
-
- * Source/kwsys/CommandLineArguments.cxx: BUG: When a "wrong
- argument" was detected, we call the WrongArgument handler. If the
- handler returns success, the argument parsing should continue.
- Currently, it was stopping parsing immediately after the wrong
- argument was processed, irrespective of the WrongArgument handler
- status. Fixed that.
-
-2006-12-21 04:12 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-20 03:28 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-19 03:29 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-18 11:30 utkarsh
-
- * Source/kwsys/SystemTools.cxx: BUG: FileIsDirectory would remove
- the trailing '/' even when the path is indeed the root i.e. '/'.
- Hence the test would be incorrect for root directory. Fixed that.
-
-2006-12-18 11:04 malaterre
-
- * Source/kwsys/kwsys_ios_sstream.h.in: COMP: Fix compilation when
- VS6 is using the new ANSI stdlib
-
-2006-12-18 03:24 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-17 03:25 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-16 03:26 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-15 10:30 malaterre
-
- * Source/kwsys/kwsys_ios_sstream.h.in: COMP: Try to get
- stringstream emulation working
-
-2006-12-15 03:32 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-14 14:30 king
-
- * Source/: cmGlobalUnixMakefileGenerator3.h,
- cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileUtilityTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx, cmMakefileTargetGenerator.h: ENH:
- Made cmMakefileTargetGenerator::GlobalGenerator have full type
- cmGlobalUnixMakefileGenerator3 to give access to all methods.
- Fixed broken custom targets with no commands for Borland
- makefiles when CMAKE_SKIP_RULE_DEPENDENCY is set.
-
-2006-12-14 13:18 king
-
- * Source/kwsys/kwsys_ios_sstream.h.in: ENH: Adding stringstream
- compatibility implementation. It is currently identical to
- ostringstream. Fixed local variable pcount hiding method
- warning.
-
-2006-12-14 11:41 malaterre
-
- * Source/kwsys/: kwsys_ios_sstream.h.in, testIOS.cxx: BUG: Remove
- stringstream implementation, this was a wrong interface anyway.
-
-2006-12-14 11:02 malaterre
-
- * Source/kwsys/testIOS.cxx: BUG: disable test for now
-
-2006-12-14 10:03 king
-
- * Source/cmSystemTools.cxx: ENH: Changes from Ryan C. Gordon to fix
- old process execution on BeOS.
-
-2006-12-14 03:26 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-13 16:44 andy
-
- * Modules/CPack.STGZ_Header.sh.in: BUG: Fixes for dash
-
-2006-12-13 13:24 martink
-
- * Source/cmPropertyMap.cxx: COMP: oops really did not mean to check
- in that change
-
-2006-12-13 12:19 martink
-
- * Source/: cmAuxSourceDirectoryCommand.cxx, cmCPluginAPI.cxx,
- cmCreateTestSourceList.cxx, cmFLTKWrapUICommand.cxx,
- cmMakefile.cxx, cmPropertyMap.cxx, cmSourceFile.cxx,
- cmSourceFile.h: ENH: allow source file properties to chain to
- Directories and up
-
-2006-12-13 12:11 martink
-
- * Modules/VTKCompatibility.cmake: ENH: fix for back VTK error
- message
-
-2006-12-13 08:52 malaterre
-
- * Source/kwsys/: kwsys_ios_sstream.h.in, testIOS.cxx: ENH: provide
- stringstream too. FIX: warning shadow var
-
-2006-12-13 03:23 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-12 14:39 martink
-
- * Source/: cmCommands.cxx, cmVTKMakeInstantiatorCommand.cxx,
- cmVTKMakeInstantiatorCommand.h, cmVTKWrapJavaCommand.cxx,
- cmVTKWrapJavaCommand.h, cmVTKWrapPythonCommand.cxx,
- cmVTKWrapPythonCommand.h, cmVTKWrapTclCommand.cxx,
- cmVTKWrapTclCommand.h: ENH: remove old commands
-
-2006-12-12 13:59 martink
-
- * Modules/VTKCompatibility.cmake: ENH: put in a better error
- message for VTK 4.0
-
-2006-12-12 13:59 martink
-
- * Tests/Wrapping/CMakeLists.txt: ENH: removed old VTK tests
-
-2006-12-12 11:17 martink
-
- * Modules/VTKCompatibility.cmake: ENH: minor cleanup
-
-2006-12-12 11:06 hoffman
-
- * Tests/CTestTest3/test.cmake.in: ENH: do not use svn until it is
- working again
-
-2006-12-12 10:07 martink
-
- * Source/: cmIfCommand.cxx, cmIfCommand.h,
- cmSetPropertiesCommand.cxx: ENH: fix a warning and a nice fix to
- the IF command
-
-2006-12-12 03:29 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-11 10:26 martink
-
- * Source/: cmSetPropertiesCommand.cxx, cmSetPropertiesCommand.h,
- cmSetSourceFilesPropertiesCommand.cxx,
- cmSetSourceFilesPropertiesCommand.h, cmake.cxx: ENH: improve
- SetProperties and fix a couple warnings
-
-2006-12-11 03:20 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-10 03:19 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-09 15:02 hoffman
-
- * Modules/: FindPkgConfig.cmake, UsePkgConfig.cmake: ENH: better
- backwards compatibility, and deprecate PKGCONFIG
-
-2006-12-09 11:25 malaterre
-
- * Source/kwsys/: CMakeLists.txt, DynamicLoader.cxx,
- DynamicLoader.hxx.in: BUG: revert yesterday patch. The
- implementation was correct. The problem was that _WIN32 was
- forced to be #define on cygwin when included from ITK, which was
- miss matching the implementation from the declaration. Put extra
- condition for CYGWIN system
-
-2006-12-09 03:32 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-08 15:52 malaterre
-
- * Source/kwsys/: CMakeLists.txt, DynamicLoader.cxx,
- DynamicLoader.hxx.in: BUG: Make sure to use the Win32 interface
- (HINSTANCE) for handling shared lib on cygwin and mingw system
-
-2006-12-08 09:27 martink
-
- * Source/: cmDocumentation.cxx, cmSetPropertiesCommand.cxx,
- cmTarget.cxx, cmake.cxx: COMP: fix some warnings and style issues
-
-2006-12-08 03:26 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-07 17:37 alex
-
- * Modules/FindRuby.cmake: BUG: fix 4164, also search for
- libruby1.8.so, I guess it should be synced with the KDE version
- of FindRUBY.cmake
-
- Alex
-
-2006-12-07 16:31 martink
-
- * Source/cmSetTestsPropertiesCommand.cxx: BUG: fix bad comparison
-
-2006-12-07 16:14 hoffman
-
- * Modules/Platform/BeOS.cmake: ENH: add beos file
-
-2006-12-07 15:23 martink
-
- * Source/cmSetTestsPropertiesCommand.cxx: COMP: fix a warning
-
-2006-12-07 14:54 martink
-
- * Source/: cmSetPropertiesCommand.cxx, cmSetPropertiesCommand.h,
- cmSetTestsPropertiesCommand.cxx, cmSetTestsPropertiesCommand.h:
- ENH: implements SetProperties for TEST
-
-2006-12-07 11:38 hoffman
-
- * Tests/CustComDepend/CMakeLists.txt: ENH: fix test for config dir
- based stuff
-
-2006-12-07 10:48 martink
-
- * bootstrap: COMP: fix bootstrap maybe
-
-2006-12-07 10:33 martink
-
- * Source/: cmPropertyMap.cxx, cmSetPropertiesCommand.cxx: COMP: fix
- warning
-
-2006-12-07 10:26 martink
-
- * Source/cmSetPropertiesCommand.cxx: COMP: fix warning right now
-
-2006-12-07 10:22 martink
-
- * Source/cmTest.cxx: BUG: fix missing return value
-
-2006-12-07 10:15 hoffman
-
- * Source/CMakeLists.txt: ENH: add test I removed by mistake
-
-2006-12-07 09:51 martink
-
- * Source/cmCPluginAPI.cxx: COMP: fix warning
-
-2006-12-07 09:44 martink
-
- * Source/CMakeLists.txt, Source/cmAuxSourceDirectoryCommand.cxx,
- Source/cmCPluginAPI.cxx, Source/cmCPluginAPI.h,
- Source/cmCommands.cxx, Source/cmCreateTestSourceList.cxx,
- Source/cmDocumentation.cxx, Source/cmDocumentation.h,
- Source/cmFLTKWrapUICommand.cxx, Source/cmForEachCommand.cxx,
- Source/cmGlobalGenerator.cxx, Source/cmIfCommand.cxx,
- Source/cmInstallFilesCommand.cxx,
- Source/cmInstallProgramsCommand.cxx, Source/cmLocalGenerator.cxx,
- Source/cmMacroCommand.cxx, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmPropertyMap.cxx,
- Source/cmSetDirectoryPropertiesCommand.cxx,
- Source/cmSetDirectoryPropertiesCommand.h,
- Source/cmSetTargetPropertiesCommand.cxx,
- Source/cmSetTargetPropertiesCommand.h, Source/cmSourceFile.cxx,
- Source/cmSourceFile.h, Source/cmTarget.cxx, Source/cmTarget.h,
- Source/cmTest.cxx, Source/cmTest.h,
- Source/cmVTKMakeInstantiatorCommand.cxx,
- Source/cmVTKWrapJavaCommand.cxx,
- Source/cmVTKWrapPythonCommand.cxx,
- Source/cmVTKWrapTclCommand.cxx, Source/cmWhileCommand.cxx,
- Source/cmake.cxx, Source/cmake.h, Source/cmakemain.cxx,
- Tests/Complex/Library/CMakeLists.txt,
- Tests/ComplexOneConfig/Library/CMakeLists.txt,
- Tests/ComplexRelativePaths/Library/CMakeLists.txt,
- Tests/LoadCommand/CMakeCommands/cmTestCommand.c,
- Tests/LoadCommandOneConfig/CMakeCommands/cmTestCommand.c,
- Source/cmDefinePropertyCommand.cxx,
- Source/cmDefinePropertyCommand.h: ENH: make properties a bit more
- formal with documentation and chaining
-
-2006-12-07 02:04 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-06 23:05 hoffman
-
- * Source/CMakeLists.txt, Source/cmLocalGenerator.cxx,
- Source/cmTarget.cxx, Tests/CustComDepend/CMakeLists.txt,
- Tests/CustComDepend/foo.cxx: ENH: fix bug in full path to target
- depends stuff
-
-2006-12-06 00:43 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-05 10:36 martink
-
- * Source/: cmPropertyDefinition.cxx: ENH: fix compiler warning
-
-2006-12-05 09:14 hoffman
-
- * Source/: cmSystemTools.cxx, CTest/cmCTestSubmitHandler.cxx: COMP:
- fix line length style error
-
-2006-12-05 09:02 hoffman
-
- * Source/kwsys/ProcessUNIX.c: COMP: remove warning
-
-2006-12-05 08:47 hoffman
-
- * bootstrap: ENH: fix bootstrap for mac
-
-2006-12-05 08:39 hoffman
-
- * Source/kwsys/ProcessUNIX.c: ENH: fix build error on IRIX
-
-2006-12-04 19:37 hoffman
-
- * Modules/FindDoxygen.cmake: ENH: fix for backwards compatibility
-
-2006-12-04 17:26 hoffman
-
- * bootstrap, Modules/CMakeDetermineCXXCompiler.cmake,
- Modules/CheckForPthreads.c, Source/cmCTest.cxx,
- Source/cmDependsJavaLexer.cxx, Source/cmDependsJavaLexer.h,
- Source/cmMakefile.cxx, Source/cmSystemTools.cxx,
- Source/kwsys/DynamicLoader.cxx,
- Source/kwsys/DynamicLoader.hxx.in, Source/kwsys/SystemTools.cxx,
- Source/kwsys/testDynamicLoader.cxx,
- Tests/Complex/Library/CMakeLists.txt,
- Tests/ComplexOneConfig/Library/CMakeLists.txt,
- Tests/ComplexRelativePaths/Library/CMakeLists.txt,
- Utilities/cmcurl/CMakeLists.txt, Utilities/cmtar/encode.c,
- Utilities/cmtar/extract.c, Utilities/cmtar/libtar.c,
- Utilities/cmtar/util.c: ENH: merge in changes for beos support
-
-2006-12-04 14:42 king
-
- * Source/kwsys/: ProcessUNIX.c, testProcess.c: ENH: Changes based
- on patch from Ryan C. Gordon to enable process execution on BeOS.
- There seems to be no way to implement it without polling (or
- threads).
-
-2006-12-04 13:54 king
-
- * Source/cmLocalGenerator.cxx: BUG: Do not print empty install
- configuration repeatedly.
-
-2006-12-04 11:52 hoffman
-
- * Modules/FindDoxygen.cmake: BUG: fix for bug 4102
-
-2006-12-04 11:44 hoffman
-
- * Modules/FindXMLRPC.cmake: BUG: fix for bug 4123, find xmlrpc in
- standard locations
-
-2006-12-04 11:19 martink
-
- * Source/CMakeLists.txt: ENH: added properties into the compile,
- but not that many
-
-2006-12-04 11:05 martink
-
- * Source/CMakeLists.txt: ENH: added properties into the compile
-
-2006-12-04 11:04 martink
-
- * Source/cmPropertyDefinitionMap.h: STYLE: fix line length
-
-2006-12-04 09:58 hoffman
-
- * CMakeLists.txt: ENH: move to actual release
-
-2006-12-02 13:17 hoffman
-
- * Source/CTest/cmCTestSubmitHandler.cxx: ENH: put checks on vector
- before referencing begin iterator
-
-2006-12-01 22:54 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-12-01 15:32 hoffman
-
- * Source/cmMacroCommand.cxx: ENH: fix warning
-
-2006-12-01 15:28 hoffman
-
- * Source/cmMacroCommand.cxx: ENH: fix warning
-
-2006-12-01 13:35 martink
-
- * Source/: cmProperty.cxx, cmProperty.h, cmPropertyDefinition.cxx,
- cmPropertyDefinition.h, cmPropertyDefinitionMap.cxx,
- cmPropertyDefinitionMap.h, cmPropertyMap.cxx, cmPropertyMap.h,
- cmSetPropertiesCommand.cxx, cmSetPropertiesCommand.h: ENH:
- getting some of the property changed chewcked into CVS at least
-
-2006-12-01 11:04 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Source/cmMacroCommand.cxx: ENH:
- merge in fix for seg fault and move to RC 4
-
-2006-12-01 10:30 hoffman
-
- * Source/cmMacroCommand.cxx: BUG: fix for 3815 seg fault
-
-2006-12-01 01:40 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-30 18:27 ibanez
-
- * Source/kwsys/: DynamicLoader.cxx, DynamicLoader.hxx.in: BUG:
- 4100. Fixing the Mac OS/X version in the Dynamic loader in kwsys,
- and replacing copy/pasted code in the itkDynamicLoader with
- usage of the kwsys loader. This was fixed in the HEAD by
- Mathieu Malaterre and Neil Weisenfeld. This changes in the
- branch are just the port of the bug fix from the HEAD.
-
-2006-11-30 18:13 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Source/cmOrderLinkDirectories.cxx, Source/cmTarget.cxx,
- Tests/LibName/CMakeLists.txt: ENH: move to RC 3 and add a fix for
- -L/path in link commands that was broken by the .dll.lib fix
-
-2006-11-30 17:50 hoffman
-
- * Source/cmOrderLinkDirectories.cxx: ENH: clean up comment and
- avoid some vector access calles
-
-2006-11-30 17:32 hoffman
-
- * Source/cmOrderLinkDirectories.cxx, Source/cmTarget.cxx,
- Tests/LibName/CMakeLists.txt: BUG: better fix for .dll.lib
- problem
-
-2006-11-30 16:23 alex
-
- * Modules/FindCups.cmake: ENH: add a module to find Cups (#3081),
- taken from KDE svn
-
- Alex
-
-2006-11-30 10:12 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Source/CMakeLists.txt,
- Source/cmOrderLinkDirectories.cxx, Tests/LibName/CMakeLists.txt,
- Tests/LibName/bar.c, Tests/LibName/foo.c, Tests/LibName/foobar.c:
- ENH: put fix for foo.dll.lib problem on branch with test
-
-2006-11-30 09:51 hoffman
-
- * Tests/LibName/foobar.c: ENH: make it work for hp
-
-2006-11-30 01:29 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-29 21:53 hoffman
-
- * Tests/LibName/: bar.c, foo.c, foobar.c: ENH: add extern for hp c
- compiler
-
-2006-11-29 21:36 hoffman
-
- * Source/CMakeLists.txt, Tests/LibName/CMakeLists.txt: ENH: fix
- test to run with debug or release and put the exe next to the
- dll, still shows the bug this is testing for
-
-2006-11-29 17:45 hoffman
-
- * bootstrap, Source/CMakeLists.txt, Source/cmake.cxx,
- Tests/LibName/bar.c, Tests/LibName/foo.c, Tests/LibName/foobar.c:
- ENH: fix errors for unix builds
-
-2006-11-29 17:25 hoffman
-
- * Source/CursesDialog/cmCursesLongMessageForm.cxx: ENH: fix warning
-
-2006-11-29 17:17 hoffman
-
- * Source/CursesDialog/: cmCursesLongMessageForm.cxx,
- cmCursesMainForm.cxx: ENH: there can be only one version
-
-2006-11-29 17:10 martink
-
- * Source/: cmMakefile.cxx, cmTarget.cxx: COMP: fix compile issue on
- Sun hopefully
-
-2006-11-29 17:02 hoffman
-
- * Source/CMakeLists.txt: ENH: fix test for configuration type
- builds
-
-2006-11-29 16:43 hoffman
-
- * Source/cmOrderLinkDirectories.cxx: ENH: fix compile error on mac
-
-2006-11-29 16:12 hoffman
-
- * Modules/: FindPkgConfig.cmake, UsePkgConfig.cmake: ENH: maintain
- backwards compatibility in UsePkgConfig
-
-2006-11-29 15:59 hoffman
-
- * Source/: cmCMakeMinimumRequired.cxx, cmCPluginAPI.cxx,
- cmCacheManager.cxx, cmGlobalGenerator.cxx, cmLocalGenerator.cxx,
- cmLocalUnixMakefileGenerator3.cxx, cmMakefile.cxx, cmMakefile.h,
- cmake.cxx, cmake.h: ENH: unify version stuff, get rid of it out
- of cmake and cmMakefile and only use cmVersion
-
-2006-11-29 15:57 hoffman
-
- * Source/cmOrderLinkDirectories.cxx, Tests/LibName/CMakeLists.txt,
- Tests/LibName/bar.c, Tests/LibName/foo.c, Tests/LibName/foobar.c,
- Source/CMakeLists.txt: BUG: fix a problem where it tried to link
- .dll.lib files
-
-2006-11-29 15:45 martink
-
- * Source/: cmMakefile.cxx, cmTarget.cxx: COMP: fix compile issue on
- Sun
-
-2006-11-29 12:56 malaterre
-
- * Source/kwsys/: DynamicLoader.cxx, DynamicLoader.hxx.in: BUG: Fix
- problem with loading dylib on Tiger (10.4) x86. We need to be
- using the dlopen/dlclose instead of the old NSModule
-
-2006-11-29 11:00 martink
-
- * Source/: cmMakefile.cxx, cmTarget.cxx, cmTarget.h,
- cmTargetLinkLibrariesCommand.cxx, cmTargetLinkLibrariesCommand.h:
- ENH: updated handling of debug and optimized target link
- libraries
-
-2006-11-28 16:09 hoffman
-
- * Source/: cmConfigure.cmake.h.in, cmMakefile.cxx, cmVersion.cxx:
- ENH: add rc to version stuff
-
-2006-11-28 16:03 hoffman
-
- * CMakeLists.txt, Source/cmConfigure.cmake.h.in,
- Source/cmMakefile.cxx, Source/cmVersion.cxx: ENH: add release
- candidate to versions
-
-2006-11-28 14:45 hoffman
-
- * Utilities/Release/: create-cmake-release.cmake,
- r15n65_aix_release.cmake: ENH: use older os for AIX release
-
-2006-11-28 14:19 hoffman
-
- * ChangeLog.manual, Modules/FindKDE4.cmake, Modules/FindQt3.cmake,
- Source/CMakeLists.txt, Source/cmLocalGenerator.cxx,
- Source/cmMakefileTargetGenerator.cxx, Source/cmTarget.cxx,
- Tests/Simple/CMakeLists.txt, Tests/TargetName/CMakeLists.txt,
- Tests/TargetName/executables/CMakeLists.txt,
- Tests/TargetName/executables/hello_world.c,
- Tests/TargetName/scripts/CMakeLists.txt,
- Tests/TargetName/scripts/hello_world,
- Tests/Wrapping/CMakeLists.txt, Utilities/cmcurl/CMakeLists.txt:
- ENH: merge in changes from the main tree
-
-2006-11-28 09:49 hoffman
-
- * Source/CMakeLists.txt: ENH: use the built cmake for file compare
- as older versions of cmake may not support this
-
-2006-11-28 00:05 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-27 16:15 hoffman
-
- * Source/CMakeLists.txt: ENH: use correct project name
-
-2006-11-27 16:13 hoffman
-
- * Source/cmMakefileTargetGenerator.cxx,
- Tests/Simple/CMakeLists.txt: ENH: make sure things do not depend
- on optimized libraries if they are debug, and the other way
- around as well
-
-2006-11-27 15:14 hoffman
-
- * Source/CMakeLists.txt, Tests/TargetName/CMakeLists.txt,
- Tests/TargetName/executables/CMakeLists.txt,
- Tests/TargetName/executables/hello_world.c,
- Tests/TargetName/scripts/CMakeLists.txt,
- Tests/TargetName/scripts/hello_world: ENH: add a test for a
- target name with the same name as the output of a custom command
-
-2006-11-27 12:14 hoffman
-
- * Source/cmTarget.cxx: ENH: fix line length problem
-
-2006-11-27 12:11 hoffman
-
- * Source/cmTarget.cxx: ENH: fix crash in plplot build
-
-2006-11-27 10:42 hoffman
-
- * Utilities/cmcurl/CMakeLists.txt: ENH: save logs of passed try
- compile stuff as well
-
-2006-11-26 07:12 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-25 21:43 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-25 21:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-25 10:59 hoffman
-
- * Source/: cmLocalGenerator.cxx, cmTarget.cxx: BUG: fix problem
- when a target name is the same as the output of a custom command
-
-2006-11-25 07:59 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-23 07:37 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-22 19:28 alex
-
- * Modules/FindKDE4.cmake: ENH: kde-config has been renamed to
- kde4-config several weeks ago, so it's not necessary anymore to
- use "kde-config" as fallback, since this will surely be a wrong
- version
-
- Alex
-
-2006-11-22 14:26 hoffman
-
- * Source/CMakeLists.txt: ENH: make sure it is qt3 before running
- test
-
-2006-11-22 14:22 hoffman
-
- * Tests/Wrapping/CMakeLists.txt: ENH: make sure it is qt3 before
- running test
-
-2006-11-22 13:44 hoffman
-
- * Modules/: FindPkgConfig.cmake, UsePkgConfig.cmake: ENH: check in
- new pkgconfig stuff from Enrico Scholz
-
-2006-11-22 13:30 hoffman
-
- * Modules/FindQt3.cmake, Tests/Wrapping/CMakeLists.txt: ENH: make
- sure findqt3 finds qt3 and not qt4
-
-2006-11-22 09:58 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-21 13:25 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-21 07:07 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-20 14:23 hoffman
-
- * Source/cmMakefile.cxx: ENH: fix from main tree
-
-2006-11-20 13:57 hoffman
-
- * Source/cmMakefile.cxx: ENH: fix for when a library is tagged both
- debug and optimized
-
-2006-11-20 08:16 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-19 08:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-18 08:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-17 15:55 hoffman
-
- * Source/: cmMakefile.cxx, CPack/cmCPackNSISGenerator.cxx: ENH:
- move fix for replace of @var@ in cmake files from main tree and a
- better message for cpack and nsis
-
-2006-11-17 15:35 hoffman
-
- * Source/cmMakefile.cxx: BUG: undo bug fix 2722, still replace
- @foo@ in cmake files
-
-2006-11-17 11:14 martink
-
- * Source/CPack/cmCPackNSISGenerator.cxx: STYLE: fix a long line
-
-2006-11-17 08:11 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-16 15:57 hoffman
-
- * ChangeLog.manual, Source/cmMakefile.cxx: ENH: move fix from main
- tree
-
-2006-11-16 15:31 martink
-
- * Source/cmIfCommand.cxx: ENH: remove old hack now that project
- level compatibility files are supported
-
-2006-11-16 15:29 martink
-
- * Modules/VTKCompatibility.cmake: ENH: added to handle case in very
- old odd versions of VTK
-
-2006-11-16 15:28 martink
-
- * Modules/ITKCompatibility.cmake: ENH: added to handle case in ITK
- 2.8 and earlier
-
-2006-11-16 10:57 martink
-
- * Source/: cmMakefile.cxx, cmTarget.cxx: ENH: fix a bug with useing
- debuf optimized libs from other builds
-
-2006-11-16 08:10 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-15 08:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-14 09:03 hoffman
-
- * CMakeLists.txt: ENH: try again for 2.4.4
-
-2006-11-14 08:09 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-13 22:08 andy
-
- * Source/CPack/cmCPackNSISGenerator.cxx: ENH: Expand comment
-
-2006-11-13 15:25 hoffman
-
- * ChangeLog.manual, Modules/FindQt4.cmake: ENH: move from main tree
-
-2006-11-13 14:22 hoffman
-
- * Modules/FindQt4.cmake: ENH: add depend information from qrc files
-
-2006-11-13 12:59 hoffman
-
- * ChangeLog.manual, Modules/CMakeVCManifestExe.cmake,
- Modules/FindSubversion.cmake, Modules/Platform/Windows-cl.cmake,
- Source/cmFindBase.cxx: ENH: merge changes in from main tree
-
-2006-11-13 08:11 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-12 08:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-11 14:06 hoffman
-
- * Source/cmFindBase.cxx: BUG: fix for 4009 lib64 should work with
- path suffix
-
-2006-11-11 14:04 hoffman
-
- * Modules/: CMakeVCManifestExe.cmake, Platform/Windows-cl.cmake:
- BUG: use different commands for shared libraries and exe for
- manifest stuff fix for bug#4039
-
-2006-11-11 08:11 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-10 10:54 hoffman
-
- * Source/cmGlobalGenerator.cxx: ENH: move from main tree
-
-2006-11-10 10:12 hoffman
-
- * Modules/FindMPI.cmake, Modules/FindQt4.cmake, Modules/readme.txt,
- Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmGlobalVisualStudio71Generator.cxx,
- Source/cmGlobalVisualStudio71Generator.h,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.h,
- Source/cmGlobalVisualStudio8Generator.cxx,
- Source/cmGlobalVisualStudio8Generator.h,
- Source/cmSetTargetPropertiesCommand.h, Source/cmake.cxx,
- Source/cmake.h, Source/CTest/cmCTestBuildHandler.cxx,
- Tests/Complex/CMakeLists.txt,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexRelativePaths/CMakeLists.txt: ENH: merge from main
- tree fix for vs all build qt and mpi2
-
-2006-11-10 09:32 hoffman
-
- * Source/cmGlobalGenerator.cxx: ENH: remove warning
-
-2006-11-10 08:11 hoffman
-
- * Source/cmGlobalGenerator.cxx: BUG: fix for broken borland
- compiler
-
-2006-11-10 08:07 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-09 16:07 hoffman
-
- * Source/CTest/cmCTestBuildHandler.cxx: ENH: fix it to work with
- stl debug mode on mac
-
-2006-11-09 09:57 hoffman
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio71Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h,
- cmGlobalVisualStudio8Generator.cxx,
- cmGlobalVisualStudio8Generator.h, cmSetTargetPropertiesCommand.h:
- ENH: commit fix for putting everything in the build on vs
-
-2006-11-09 08:09 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-08 08:10 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-07 08:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-06 08:09 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-05 08:07 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-04 08:06 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-03 08:07 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-02 19:58 hoffman
-
- * Modules/FindMPI.cmake: ENH: add support for finding mpich2 on
- windows
-
-2006-11-02 17:51 hoffman
-
- * Modules/FindQt4.cmake: ENH: look for QtAssistantClient4
-
-2006-11-02 17:16 hoffman
-
- * CMakeLists.txt: ENH: abort 2.4.4 for now
-
-2006-11-02 08:09 hoffman
-
- * CMakeLists.txt: ENH: this is 2.4.4
-
-2006-11-02 08:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-11-01 09:06 king
-
- * Modules/readme.txt: ENH: Added XXX_RUNTIME_LIBRARY_DIRS as a
- suggested variable.
-
-2006-11-01 08:07 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-10-31 14:28 andy
-
- * Source/: cmGlobalGenerator.cxx, cmInstallTargetGenerator.cxx,
- cmake.cxx, cmake.h: ENH: Cleanup of install component list. There
- was already the list in the global generator. Use that one
-
-2006-10-31 06:43 andy
-
- * Source/cmInstallTargetGenerator.cxx: STYLE: Fix kwstyle
-
-2006-10-30 15:59 andy
-
- * Source/: cmGlobalGenerator.cxx, cmInstallTargetGenerator.cxx,
- cmake.cxx, cmake.h: ENH: Add support for displaying the list of
- components
-
-2006-10-30 15:30 king
-
- * Modules/FindSubversion.cmake: ENH: Adding FindSubversion module
- from Tristan Carel. This addresses bug#3987.
-
-2006-10-30 11:36 hoffman
-
- * Source/CPack/: cmCPackGenericGenerator.cxx,
- cmCPackPackageMakerGenerator.cxx, cmCPackTGZGenerator.cxx,
- cmCPackTarBZip2Generator.cxx, cmCPackTarCompressGenerator.cxx:
- ENH: merge fix for cpack crash into main tree
-
-2006-10-30 11:22 hoffman
-
- * Source/CPack/: cmCPackGenericGenerator.cxx,
- cmCPackPackageMakerGenerator.cxx, cmCPackTGZGenerator.cxx,
- cmCPackTarBZip2Generator.cxx, cmCPackTarCompressGenerator.cxx:
- ENH: make sure null const char* is not put into ossttringstream
- to avoid seg faults
-
-2006-10-30 10:38 king
-
- * Tests/: Complex/CMakeLists.txt, ComplexOneConfig/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt: ENH: Added test case for
- bug#3966.
-
-2006-10-30 09:54 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-10-30 09:17 hoffman
-
- * Modules/FindJNI.cmake: ENH: move from main tree
-
-2006-10-27 17:30 andy
-
- * Modules/FindJNI.cmake: ENH: More documentation
-
-2006-10-27 17:29 andy
-
- * Modules/FindJNI.cmake: ENH: Add support for libjvm
-
-2006-10-27 16:03 hoffman
-
- * Utilities/cmThirdParty.h.in, Utilities/cm_curl.h,
- Utilities/cm_expat.h, Utilities/cm_xmlrpc.h, Utilities/cm_zlib.h,
- Modules/CMakeDependentOption.cmake, Modules/FindCURL.cmake,
- Modules/FindEXPAT.cmake, Modules/FindXMLRPC.cmake,
- Tests/SimpleInstall/PackageScript.cmake,
- Tests/SimpleInstallS2/PackageScript.cmake: ENH: move from main
- tree
-
-2006-10-27 16:01 hoffman
-
- * CMakeLists.txt, CTestCustom.ctest.in, ChangeLog.manual,
- bootstrap, doxygen.config, Modules/CMakeGenericSystem.cmake,
- Modules/CPack.cmake, Modules/CTestTargets.cmake,
- Modules/FindDoxygen.cmake, Modules/FindJNI.cmake,
- Modules/FindJava.cmake, Modules/FindKDE3.cmake,
- Modules/FindPerl.cmake, Modules/FindQt4.cmake,
- Modules/FindTclsh.cmake, Modules/FindWish.cmake,
- Modules/FindwxWidgets.cmake, Modules/NSIS.template.in,
- Modules/UsewxWidgets.cmake, Modules/Platform/CYGWIN.cmake,
- Modules/Platform/Windows-cl.cmake,
- Modules/Platform/Windows-gcc.cmake, Source/CMakeLists.txt,
- Source/cmCTest.cxx, Source/cmCTest.h, Source/cmDocumentation.cxx,
- Source/cmExecuteProcessCommand.cxx,
- Source/cmExecuteProcessCommand.h, Source/cmFindBase.cxx,
- Source/cmFindPackageCommand.cxx, Source/cmFindPackageCommand.h,
- Source/cmGeneratedFileStream.cxx,
- Source/cmGetDirectoryPropertyCommand.cxx,
- Source/cmGlobalGenerator.cxx,
- Source/cmGlobalMinGWMakefileGenerator.cxx,
- Source/cmGlobalWatcomWMakeGenerator.cxx,
- Source/cmGlobalXCodeGenerator.cxx, Source/cmIfCommand.cxx,
- Source/cmIfCommand.h, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalUnixMakefileGenerator3.h,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h,
- Source/cmLocalVisualStudioGenerator.cxx,
- Source/cmMakefileExecutableTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmSetTargetPropertiesCommand.h, Source/cmSystemTools.cxx,
- Source/cmTarget.cxx, Source/cmTarget.h, Source/cmXMLParser.cxx,
- Source/cmake.cxx, Source/CPack/cmCPackGenericGenerator.cxx,
- Source/CPack/cmCPackGenericGenerator.h,
- Source/CPack/cmCPackNSISGenerator.cxx,
- Source/CPack/cmCPackTGZGenerator.cxx, Source/CPack/cpack.cxx,
- Source/CTest/cmCTestBuildHandler.cxx,
- Source/CTest/cmCTestCoverageHandler.cxx,
- Source/CTest/cmCTestMemCheckHandler.cxx,
- Source/CTest/cmCTestScriptHandler.cxx,
- Source/CTest/cmCTestScriptHandler.h,
- Source/CTest/cmCTestSubmitHandler.cxx,
- Source/CTest/cmCTestTestHandler.cxx,
- Source/CTest/cmCTestTestHandler.h,
- Source/CTest/cmCTestUpdateHandler.cxx,
- Source/kwsys/CMakeLists.txt, Source/kwsys/System.c,
- Source/kwsys/System.h.in, Source/kwsys/SystemTools.cxx,
- Source/kwsys/SystemTools.cxx.bak,
- Source/kwsys/kwsysPlatformCxxTests.cmake,
- Source/kwsys/kwsysPlatformCxxTests.cxx,
- Templates/DLLHeader.dsptemplate, Templates/EXEHeader.dsptemplate,
- Tests/CTestTest2/test.cmake.in, Tests/CTestTest3/test.cmake.in,
- Tests/Complex/CMakeLists.txt, Tests/Complex/cmTestConfigure.h.in,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexOneConfig/cmTestConfigure.h.in,
- Tests/ComplexRelativePaths/CMakeLists.txt,
- Tests/ComplexRelativePaths/cmTestConfigure.h.in,
- Tests/Complex/Executable/CMakeLists.txt,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/complex.cxx,
- Tests/CustomCommand/CMakeLists.txt,
- Tests/MacroTest/CMakeLists.txt, Tests/OutOfSource/CMakeLists.txt,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt,
- Tests/StringFileTest/CMakeLists.txt,
- Utilities/cmtar/CMakeLists.txt, Utilities/cmtar/config.h.in,
- Utilities/cmtar/libtar.c: ENH: move changes from main tree
-
-2006-10-27 15:59 hoffman
-
- * Modules/FindJNI.cmake: ENH: remove JavaEmbedding
-
-2006-10-27 15:55 hoffman
-
- * CTestCustom.ctest.in: ENH: fix warnings on windows paths
-
-2006-10-26 11:39 king
-
- * Source/: cmFindPackageCommand.cxx, cmFindPackageCommand.h: ENH:
- Added NO_MODULE and COMPONENTS options to improve flexibility of
- the command. Re-implemented argument parsing to be simpler and
- more robust.
-
-2006-10-26 11:01 andy
-
- * Source/CTest/cmCTestUpdateHandler.cxx: STYLE: Fix typo
-
-2006-10-26 10:49 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: When writing
- newlines between script portions in prebuild, prelink, and
- postbuild command lines they must be escaped for XML so that the
- IDE receives them. This fixes the fix for bug #3977.
-
-2006-10-25 14:03 king
-
- * Source/cmLocalVisualStudio6Generator.cxx: COMP: Remove unused
- variable.
-
-2006-10-25 12:49 king
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: BUG: Adjust
- prebuild/prelink/postbuild script construction to account for
- ConstructScript no longer producing trailing newlines. This
- addresses bug#3977.
-
-2006-10-25 12:27 king
-
- * Source/cmLocalVisualStudioGenerator.cxx: BUG: Avoid leading and
- trailing newlines in custom command scripts because some VS6
- versions do not like the trailing backslash this produces. This
- addresses bug#3977.
-
-2006-10-25 11:23 king
-
- * Tests/CustomCommand/CMakeLists.txt: ENH: Re-enabling # escape
- test now that it is implemented everywhere.
-
-2006-10-25 11:23 king
-
- * Source/: cmGlobalWatcomWMakeGenerator.cxx, cmLocalGenerator.cxx,
- cmLocalGenerator.h, cmLocalUnixMakefileGenerator3.h,
- kwsys/System.c, kwsys/System.h.in: ENH: Adding support for #
- escape in Watcom WMake.
-
-2006-10-25 10:58 king
-
- * Tests/MacroTest/CMakeLists.txt: BUG: EQUAL -> STREQUAL for string
- comparison.
-
-2006-10-25 10:57 king
-
- * Source/cmIfCommand.cxx: BUG: It cannot be an error if the values
- do not convert. The docs say that if the values do not convert
- the test is false.
-
-2006-10-25 10:31 king
-
- * Source/cmIfCommand.cxx: BUG: For LESS, GREATER, and EQUAL check
- that the arguments can actually be converted to numbers. Also
- force the conversion results to be stored in memory to make sure
- they both use the same precision. This addresses bug#3966.
-
-2006-10-25 09:54 andy
-
- * Source/CMakeLists.txt: COMP: Remove unnecessary provocation
-
-2006-10-25 09:54 andy
-
- * Tests/CTestTest3/test.cmake.in: BUG: Attempt to fix the test
-
-2006-10-25 08:56 andy
-
- * Source/CTest/cmCTestCoverageHandler.cxx: STYLE: Fix line length
-
-2006-10-24 17:56 alex
-
- * Modules/FindPerl.cmake: BUG: honor the REQUIRED flag for Perl,
- please backport to 2.4 branch so that it will be in 2.4.4
-
- Alex
-
-2006-10-24 12:44 andy
-
- * Source/CTest/cmCTestCoverageHandler.cxx: BUG: Looks like gcov
- produces lines with string /*EOF*/ on them if there is no line at
- the end of the file. This will fix the coverage code complaining
- about it
-
-2006-10-24 11:06 hoffman
-
- * Source/CMakeLists.txt: ENH: remove failing test
-
-2006-10-24 10:03 hoffman
-
- * Modules/FindDoxygen.cmake: ENH: fix more doxygen issues
-
-2006-10-24 10:03 hoffman
-
- * Modules/FindJNI.cmake: ENH: remove JavaEmbedding framework
-
-2006-10-24 09:47 king
-
- * Tests/CustomCommand/CMakeLists.txt: BUG: Disable testing of #
- escapes until it can be implemented for Watcom WMake.
-
-2006-10-23 19:04 alex
-
- * Modules/FindKDE3.cmake: BUG: fix #3955: add -O2 by default but
- only if no special buildtype is set
-
- Alex
-
-2006-10-23 17:20 king
-
- * Source/kwsys/System.c, Tests/CustomCommand/CMakeLists.txt: ENH:
- Added # character for shell escaping.
-
-2006-10-23 17:14 king
-
- * Source/cmIfCommand.cxx, Source/cmIfCommand.h,
- Tests/StringFileTest/CMakeLists.txt: ENH: Remove old
- IF(FILE_IS_NEWER) syntax. It was never in a release anyway.
-
-2006-10-23 16:16 king
-
- * Source/cmake.cxx: BUG: Do not display cmake -E usage when any old
- command line error occurs.
-
-2006-10-23 14:51 hoffman
-
- * Modules/FindDoxygen.cmake: ENH: put in backwards compatibility
- for older cmake
-
-2006-10-23 13:36 king
-
- * Tests/StringFileTest/CMakeLists.txt, Source/cmIfCommand.cxx,
- Source/cmIfCommand.h: ENH: Patch from Alex to provide nicer
- syntax for FILE_IS_NEWER. Using name IS_NEWER_THAN so old syntax
- will continue to work.
-
-2006-10-22 19:21 hoffman
-
- * Source/CMakeLists.txt: ENH: remove broken test
-
-2006-10-22 11:57 king
-
- * Tests/: Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/complex.cxx: COMP: Fixed typo:
- CMAKE_TEST_CMAKELIB -> COMPLEX_TEST_CMAKELIB.
-
-2006-10-19 15:45 king
-
- * Utilities/cmtar/CMakeLists.txt: ENH: Remove old include dirs.
-
-2006-10-19 15:17 king
-
- * bootstrap: ENH: Adding option to use system-installed third-party
- libraries. This addresses bug#3653.
-
-2006-10-19 15:00 king
-
- * CMakeLists.txt, Source/CMakeLists.txt, Source/cmCTest.cxx,
- Source/cmGeneratedFileStream.cxx, Source/cmSystemTools.cxx,
- Source/cmXMLParser.cxx, Source/CPack/cmCPackTGZGenerator.cxx,
- Source/CTest/cmCTestSubmitHandler.cxx,
- Utilities/cmThirdParty.h.in, Utilities/cm_curl.h,
- Utilities/cm_expat.h, Utilities/cm_xmlrpc.h, Utilities/cm_zlib.h,
- Utilities/cmtar/CMakeLists.txt, Utilities/cmtar/config.h.in,
- Utilities/cmtar/libtar.c: ENH: Add options to build with system
- utility libraries. Organize inclusion of third party libraries
- into a single header per library. This addresses bug#3653.
-
-2006-10-19 14:48 king
-
- * Modules/CMakeDependentOption.cmake: ENH: Adding
- CMAKE_DEPENDENT_OPTION macro.
-
-2006-10-19 14:45 king
-
- * Tests/: Complex/CMakeLists.txt, Complex/cmTestConfigure.h.in,
- ComplexOneConfig/CMakeLists.txt,
- ComplexOneConfig/cmTestConfigure.h.in,
- ComplexRelativePaths/CMakeLists.txt,
- ComplexRelativePaths/cmTestConfigure.h.in,
- Complex/Executable/CMakeLists.txt,
- Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/complex.cxx: ENH: Added explicit
- name for option to test CMakeLib. Added option to disable
- testing of CMakeLib if system utility libraries are used until
- linking made easier.
-
-2006-10-19 12:58 king
-
- * Modules/FindXMLRPC.cmake: ENH: Find module for XMLRPC libraries.
-
-2006-10-19 12:57 king
-
- * Modules/FindEXPAT.cmake: ENH: Find module for EXPAT library.
-
-2006-10-19 12:55 king
-
- * Modules/FindCURL.cmake: ENH: Find module for CURL library.
-
-2006-10-19 10:45 martink
-
- * Source/: cmCTest.cxx, cmCTest.h, CTest/cmCTestBuildHandler.cxx,
- CTest/cmCTestCoverageHandler.cxx, CTest/cmCTestScriptHandler.cxx,
- CTest/cmCTestScriptHandler.h, CTest/cmCTestTestHandler.cxx: ENH:
- added total time limit for a CTest run bug 1207
-
-2006-10-19 10:07 king
-
- * Modules/: FindwxWidgets.cmake, UsewxWidgets.cmake: ENH: Patch
- from Jan for bug#3453. Cleans up find script and enables
- -isystem feature for use script.
-
-2006-10-19 09:18 king
-
- * Source/cmFindBase.cxx: ENH: Clarified search behavior when the
- objective is not found.
-
-2006-10-18 23:27 david.cole
-
- * Source/kwsys/SystemTools.cxx: BUG: Correct the
- SystemReportDebugHook function. It should not call exit. It gets
- called multiple times at shutdown in a memory leak reporting
- scenario... This is the source of the long standing KWWidgetsTour
- debug build dashboard failure.
-
-2006-10-17 09:34 king
-
- * Source/CPack/cpack.cxx: STYLE: Fixed line-too-long.
-
-2006-10-16 18:17 king
-
- * Modules/Platform/CYGWIN.cmake, Modules/Platform/Windows-cl.cmake,
- Modules/Platform/Windows-gcc.cmake, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h,
- Source/cmMakefileExecutableTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmSetTargetPropertiesCommand.h, Source/cmTarget.cxx,
- Source/cmTarget.h, Templates/DLLHeader.dsptemplate,
- Templates/EXEHeader.dsptemplate: ENH: Adding image version number
- (major.minor) property to windows binaries. Default is 0.0, but
- the VERSION target property may change the value. Windows now
- has first-class support for dll and exe versioning. This
- addresses bug#1219.
-
-2006-10-16 15:18 king
-
- * Source/cmGetDirectoryPropertyCommand.cxx,
- Tests/OutOfSource/CMakeLists.txt: BUG: Need to collapse path
- argument to get_directory_property. This addresses bug#3847.
-
-2006-10-16 14:52 king
-
- * Source/cmDocumentation.cxx: ENH: Make hyperlinks in documentation
- active when generated into HTML documents. This addresses
- bug#3906.
-
-2006-10-16 13:58 king
-
- * Modules/CMakeGenericSystem.cmake: ENH: Allow user project code to
- distinguish between an install prefix set on the command line and
- one set by CMake as a default. This is useful for changing the
- default prefix while still allowing the user to override it.
-
-2006-10-16 12:49 martink
-
- * Source/cmake.cxx: BUG: partial fix for the progress after install
- bug
-
-2006-10-16 12:47 hoffman
-
- * Utilities/Release/: create-cmake-release.cmake,
- magrathea_release.cmake, r36n11_aix_release.cmake,
- release_cmake.sh.in, upload_release.cmake: ENH: update for
- release
-
-2006-10-16 11:32 king
-
- * Source/: cmExecuteProcessCommand.cxx, cmExecuteProcessCommand.h:
- ENH: Added OUTPUT_STRIP_TRAILING_WHITESPACE and
- ERROR_STRIP_TRAILING_WHITESPACE options to EXECUTE_PROCESS
- command. These allow it to behave more like the old EXEC_PROGRAM
- command that it is supposed to replace.
-
-2006-10-16 10:47 hoffman
-
- * Modules/FindDoxygen.cmake: BUG: fix for bug# 3310
-
-2006-10-15 07:54 andy
-
- * Source/: cmCTest.cxx, CPack/cmCPackGenericGenerator.cxx,
- CTest/cmCTestCoverageHandler.cxx: STYLE: Fix kwstyle
-
-2006-10-13 17:10 andy
-
- * Source/cmCTest.cxx, Source/cmCTest.h,
- Tests/CTestTest2/test.cmake.in: ENH: Properly propagate config
- type to test
-
-2006-10-13 16:13 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: fix for bug#3908
- if header_file_only is set on cxx files in visual studio do not
- compile them
-
-2006-10-13 15:04 king
-
- * Modules/NSIS.template.in: BUG: Compression must be set before any
- output is created.
-
-2006-10-13 14:44 andy
-
- * Source/CTest/cmCTestTestHandler.h: COMP: Fix Sun build
-
-2006-10-13 13:59 king
-
- * Source/cmMakefileLibraryTargetGenerator.cxx: BUG: When using link
- scripts use native shell escapes instead of makefile shell
- escapes because the script is not interpreted by a make tool.
-
-2006-10-13 11:53 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: allow for -gdwarf-2 to be
- in cflags or cxxflags for xcode
-
-2006-10-13 11:26 hoffman
-
- * doxygen.config: BUG: fix for bug# 3921 INPUT wrong
-
-2006-10-13 11:25 hoffman
-
- * Modules/: FindTclsh.cmake, FindWish.cmake: BUG: fix for bug #3846
- more advanced stuff
-
-2006-10-13 11:23 hoffman
-
- * Modules/FindQt4.cmake: BUG: fix for bug#3898 find qt plugin dir
-
-2006-10-13 10:57 hoffman
-
- * CMake.pdf, CMake.rtf, Docs/CMake12p2.rtf, Docs/CMake14.rtf,
- Docs/CMake16.rtf, Modules/CMakeVCManifest.cmake,
- Modules/COPYING-CMAKE-SCRIPTS, Modules/CheckCCompilerFlag.cmake,
- Modules/CheckCSourceRuns.cmake,
- Modules/CheckCXXCompilerFlag.cmake,
- Modules/CheckCXXSourceRuns.cmake, Modules/FindASPELL.cmake,
- Modules/FindBZip2.cmake, Modules/FindHSPELL.cmake,
- Modules/FindJasper.cmake, Modules/FindLibXml2.cmake,
- Modules/FindLibXslt.cmake, Modules/FindOpenSSL.cmake,
- Source/cmElseIfCommand.cxx, Source/cmElseIfCommand.h,
- Source/cmEndMacroCommand.cxx, Source/cmEndMacroCommand.h,
- Source/cmInstallDirectoryGenerator.cxx,
- Source/cmInstallDirectoryGenerator.h, Source/cmStandardLexer.h,
- Source/kwsys/CMakeEmptyInputFile.in,
- Source/kwsys/CheckCXXSourceRuns.cmake, Source/kwsys/IOStream.cxx,
- Source/kwsys/IOStream.hxx.in, Source/kwsys/System.c,
- Source/kwsys/System.h.in, Source/kwsys/SystemTools.cxx.bak,
- Source/kwsys/SystemTools.hxx.in.bak,
- Source/kwsys/kwsysPlatformCxxTests.cmake.bak,
- Source/kwsys/kwsysPlatformCxxTests.cxx.bak,
- Source/kwsys/kwsysPlatformTests.cmake,
- Source/kwsys/kwsysPlatformTestsC.c,
- Source/kwsys/kwsysPlatformTestsCXX.cxx,
- Tests/Complex/Executable/A.cxx.bak, Tests/Complex/Executable/A.h,
- Tests/Complex/Executable/A.hh, Tests/Complex/Executable/A.txt,
- Tests/Complex/Executable/notInAllExe.cxx,
- Tests/Complex/Executable/testSystemDir.cxx,
- Tests/Complex/Library/TestLink.c,
- Tests/Complex/Library/notInAllLib.cxx,
- Tests/Complex/Library/test_preprocess.cmake,
- Tests/Complex/Library/SystemDir/testSystemDir.h,
- Tests/ComplexOneConfig/Executable/A.cxx.bak,
- Tests/ComplexOneConfig/Executable/A.h,
- Tests/ComplexOneConfig/Executable/A.hh,
- Tests/ComplexOneConfig/Executable/A.txt,
- Tests/ComplexOneConfig/Executable/notInAllExe.cxx,
- Tests/ComplexOneConfig/Executable/testSystemDir.cxx,
- Tests/ComplexOneConfig/Library/TestLink.c,
- Tests/ComplexOneConfig/Library/notInAllLib.cxx,
- Tests/ComplexOneConfig/Library/test_preprocess.cmake,
- Tests/ComplexOneConfig/Library/SystemDir/testSystemDir.h,
- Tests/ComplexRelativePaths/Executable/A.cxx.bak,
- Tests/ComplexRelativePaths/Executable/A.h,
- Tests/ComplexRelativePaths/Executable/A.hh,
- Tests/ComplexRelativePaths/Executable/A.txt,
- Tests/ComplexRelativePaths/Executable/notInAllExe.cxx,
- Tests/ComplexRelativePaths/Executable/testSystemDir.cxx,
- Tests/ComplexRelativePaths/Library/TestLink.c,
- Tests/ComplexRelativePaths/Library/notInAllLib.cxx,
- Tests/ComplexRelativePaths/Library/test_preprocess.cmake,
- Tests/ComplexRelativePaths/Library/SystemDir/testSystemDir.h,
- Tests/CustomCommand/check_command_line.c.in,
- Tests/OutOfBinary/CMakeLists.txt, Tests/OutOfBinary/outlib.c,
- Tests/SimpleInstall/scripts/sample_script,
- Tests/SimpleInstall/scripts/sample_script.bat,
- Tests/SimpleInstallS2/scripts/sample_script,
- Tests/SimpleInstallS2/scripts/sample_script.bat,
- Utilities/cmcompress/CMakeLists.txt,
- Utilities/cmcompress/cmcompress.c,
- Utilities/cmcompress/cmcompress.h: ENH: merge files from main
- tree to 2.4
-
-2006-10-13 10:52 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, bootstrap,
- Docs/cmake-indent.vim, Docs/cmake-mode.el, Docs/cmake-syntax.vim,
- Modules/CMakeCXXInformation.cmake,
- Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Modules/CMakeDetermineFortranCompiler.cmake,
- Modules/CMakeDetermineRCCompiler.cmake,
- Modules/CMakeFortranInformation.cmake,
- Modules/CMakeSystemSpecificInformation.cmake,
- Modules/CheckCSourceCompiles.cmake,
- Modules/CheckCXXSourceCompiles.cmake, Modules/FindDoxygen.cmake,
- Modules/FindGLUT.cmake, Modules/FindKDE3.cmake,
- Modules/FindPNG.cmake, Modules/FindPythonInterp.cmake,
- Modules/FindPythonLibs.cmake, Modules/FindQt3.cmake,
- Modules/FindQt4.cmake, Modules/FindRuby.cmake,
- Modules/FindSDL.cmake, Modules/FindTCL.cmake,
- Modules/FindwxWidgets.cmake,
- Modules/InstallRequiredSystemLibraries.cmake,
- Modules/KDE3Macros.cmake, Modules/UseEcos.cmake,
- Modules/UseQt4.cmake, Modules/UseSWIG.cmake,
- Modules/kde3uic.cmake, Modules/readme.txt,
- Modules/Platform/AIX.cmake, Modules/Platform/CYGWIN.cmake,
- Modules/Platform/Darwin.cmake, Modules/Platform/FreeBSD.cmake,
- Modules/Platform/HP-UX.cmake, Modules/Platform/IRIX.cmake,
- Modules/Platform/IRIX64.cmake, Modules/Platform/Linux.cmake,
- Modules/Platform/QNX.cmake, Modules/Platform/SunOS.cmake,
- Modules/Platform/UnixPaths.cmake,
- Modules/Platform/Windows-cl.cmake,
- Modules/Platform/Windows-gcc.cmake, Modules/Platform/gcc.cmake,
- Source/CMakeLists.txt, Source/cmAddCustomCommandCommand.cxx,
- Source/cmAddCustomCommandCommand.h,
- Source/cmAddCustomTargetCommand.cxx,
- Source/cmAddCustomTargetCommand.h,
- Source/cmAddExecutableCommand.cxx,
- Source/cmAddExecutableCommand.h, Source/cmAddLibraryCommand.cxx,
- Source/cmAddLibraryCommand.h,
- Source/cmAddSubDirectoryCommand.cxx, Source/cmAddTestCommand.h,
- Source/cmBuildNameCommand.h, Source/cmCPluginAPI.cxx,
- Source/cmCommand.h, Source/cmCommandArgumentLexer.cxx,
- Source/cmCommandArgumentLexer.h,
- Source/cmCommandArgumentLexer.in.l,
- Source/cmCommandArgumentParser.cxx,
- Source/cmCommandArgumentParser.y,
- Source/cmCommandArgumentParserHelper.cxx,
- Source/cmCommandArgumentParserHelper.h, Source/cmCommands.cxx,
- Source/cmCustomCommand.cxx, Source/cmCustomCommand.h,
- Source/cmDependsC.cxx, Source/cmDependsC.h,
- Source/cmDependsFortranLexer.cxx,
- Source/cmDependsFortranLexer.in.l,
- Source/cmDependsFortranParser.cxx,
- Source/cmDependsFortranParser.y, Source/cmDependsJavaLexer.cxx,
- Source/cmDependsJavaLexer.in.l, Source/cmDependsJavaParser.cxx,
- Source/cmDependsJavaParser.y, Source/cmDocumentation.cxx,
- Source/cmExecProgramCommand.h, Source/cmExprLexer.cxx,
- Source/cmExprLexer.in.l, Source/cmExprParser.cxx,
- Source/cmExprParser.y, Source/cmFileCommand.cxx,
- Source/cmGetTargetPropertyCommand.h,
- Source/cmGlobalBorlandMakefileGenerator.cxx,
- Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmGlobalKdevelopGenerator.cxx,
- Source/cmGlobalMSYSMakefileGenerator.cxx,
- Source/cmGlobalMinGWMakefileGenerator.cxx,
- Source/cmGlobalNMakeMakefileGenerator.cxx,
- Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmGlobalUnixMakefileGenerator3.h,
- Source/cmGlobalVisualStudio6Generator.cxx,
- Source/cmGlobalVisualStudio71Generator.cxx,
- Source/cmGlobalVisualStudio71Generator.h,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.h,
- Source/cmGlobalVisualStudio8Generator.cxx,
- Source/cmGlobalVisualStudio8Generator.h,
- Source/cmGlobalWatcomWMakeGenerator.cxx,
- Source/cmGlobalXCodeGenerator.cxx, Source/cmIfCommand.cxx,
- Source/cmIfCommand.h, Source/cmIncludeDirectoryCommand.cxx,
- Source/cmIncludeDirectoryCommand.h,
- Source/cmIncludeExternalMSProjectCommand.cxx,
- Source/cmInstallCommand.cxx, Source/cmInstallCommand.h,
- Source/cmInstallFilesCommand.cxx, Source/cmInstallFilesCommand.h,
- Source/cmInstallFilesGenerator.cxx,
- Source/cmInstallFilesGenerator.h, Source/cmInstallGenerator.cxx,
- Source/cmInstallGenerator.h, Source/cmInstallProgramsCommand.cxx,
- Source/cmInstallProgramsCommand.h,
- Source/cmInstallTargetGenerator.cxx,
- Source/cmInstallTargetGenerator.h,
- Source/cmInstallTargetsCommand.cxx,
- Source/cmInstallTargetsCommand.h,
- Source/cmLinkLibrariesCommand.h, Source/cmListCommand.cxx,
- Source/cmListCommand.h, Source/cmListFileCache.cxx,
- Source/cmListFileLexer.c, Source/cmListFileLexer.in.l,
- Source/cmLoadCommandCommand.cxx, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalUnixMakefileGenerator3.h,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h,
- Source/cmLocalVisualStudioGenerator.cxx,
- Source/cmLocalVisualStudioGenerator.h, Source/cmMacroCommand.cxx,
- Source/cmMakeDirectoryCommand.h, Source/cmMakefile.cxx,
- Source/cmMakefile.h,
- Source/cmMakefileExecutableTargetGenerator.cxx,
- Source/cmMakefileExecutableTargetGenerator.h,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.h,
- Source/cmMakefileTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.h, Source/cmMessageCommand.cxx,
- Source/cmOrderLinkDirectories.cxx,
- Source/cmOrderLinkDirectories.h, Source/cmRemoveCommand.h,
- Source/cmSetCommand.cxx,
- Source/cmSetSourceFilesPropertiesCommand.h,
- Source/cmSetTargetPropertiesCommand.h,
- Source/cmStandardIncludes.h, Source/cmSubdirCommand.h,
- Source/cmSubdirDependsCommand.h, Source/cmTarget.cxx,
- Source/cmTryCompileCommand.cxx,
- Source/cmVTKMakeInstantiatorCommand.h,
- Source/cmVTKWrapJavaCommand.cxx, Source/cmVTKWrapJavaCommand.h,
- Source/cmVTKWrapPythonCommand.h, Source/cmVTKWrapTclCommand.h,
- Source/cmWin32ProcessExecution.cxx, Source/cmake.cxx,
- Source/cmake.h, Source/cmakemain.cxx,
- Source/CPack/cmCPackNSISGenerator.cxx,
- Source/CPack/cmCPackTarCompressGenerator.cxx,
- Source/CPack/cmCPackTarCompressGenerator.h,
- Source/CPack/cmCPackZIPGenerator.cxx, Source/CPack/cpack.cxx,
- Source/CTest/cmCTestBuildAndTestHandler.cxx,
- Source/CTest/cmCTestBuildHandler.cxx,
- Source/CTest/cmCTestCoverageHandler.cxx,
- Source/CTest/cmCTestHandlerCommand.cxx,
- Source/CTest/cmCTestScriptHandler.cxx,
- Source/CTest/cmCTestStartCommand.cxx,
- Source/CTest/cmCTestTestHandler.cxx,
- Source/CursesDialog/ccmake.cxx,
- Source/CursesDialog/cmCursesMainForm.cxx,
- Source/kwsys/CMakeLists.txt,
- Source/kwsys/CommandLineArguments.cxx,
- Source/kwsys/Configure.h.in, Source/kwsys/Directory.cxx,
- Source/kwsys/Glob.cxx, Source/kwsys/Glob.hxx.in,
- Source/kwsys/Process.h.in, Source/kwsys/ProcessUNIX.c,
- Source/kwsys/ProcessWin32.c, Source/kwsys/Registry.cxx,
- Source/kwsys/SharedForward.h.in, Source/kwsys/SystemTools.cxx,
- Source/kwsys/SystemTools.hxx.in, Source/kwsys/Terminal.c,
- Source/kwsys/testCommandLineArguments.cxx,
- Source/kwsys/testCommandLineArguments1.cxx,
- Source/kwsys/testProcess.c, Source/kwsys/testSystemTools.cxx,
- Tests/Complex/CMakeLists.txt, Tests/Complex/cmTestConfigure.h.in,
- Tests/Complex/Executable/A.cxx,
- Tests/Complex/Executable/CMakeLists.txt,
- Tests/Complex/Executable/complex.cxx,
- Tests/Complex/Library/CMakeLists.txt,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexOneConfig/cmTestConfigure.h.in,
- Tests/ComplexOneConfig/Executable/A.cxx,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexOneConfig/Library/CMakeLists.txt,
- Tests/ComplexRelativePaths/CMakeLists.txt,
- Tests/ComplexRelativePaths/cmTestConfigure.h.in,
- Tests/ComplexRelativePaths/Executable/A.cxx,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Library/CMakeLists.txt,
- Tests/CustomCommand/CMakeLists.txt,
- Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt,
- Tests/OutOfSource/OutOfSourceSubdir/simple.cxx,
- Tests/OutOfSource/SubDir/CMakeLists.txt,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt,
- Tests/StringFileTest/CMakeLists.txt,
- Tests/SystemInformation/SystemInformation.in,
- Utilities/Release/README, Utilities/cmcurl/CMakeLists.txt,
- Utilities/cmtar/CMakeLists.txt, Utilities/cmzlib/CMakeLists.txt:
- ENH: merge changes from the main tree to the 2.4 branch
-
-2006-10-13 10:27 andy
-
- * Source/CTest/: cmCTestMemCheckHandler.cxx,
- cmCTestUpdateHandler.cxx: BUG: Replace some errors with warnings
-
-2006-10-13 10:22 king
-
- * Source/: cmGlobalMinGWMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: BUG: Juse use cmake -E echo
- instead of the native echo on MinGW makefiles. The echo; hack
- did not work when running from ctest.
-
-2006-10-13 10:03 king
-
- * Source/cmLocalGenerator.cxx: BUG: Do not try to compute the
- location of a non-library target for linking.
-
-2006-10-13 09:30 andy
-
- * Source/: CTest/cmCTestTestHandler.cxx,
- CTest/cmCTestTestHandler.h, kwsys/CMakeLists.txt: ENH: Report
- command line as a measurement and allow user to add custom
- measurements
-
-2006-10-12 17:19 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: undo bad changes
-
-2006-10-12 16:31 andy
-
- * Source/: cmCTest.cxx, CTest/cmCTestCoverageHandler.cxx: BUG: Use
- BuildDirectory from the DartConfiguration information. Also, Make
- missing coverage information not make ctest fail
-
-2006-10-12 15:30 andy
-
- * Source/cmGlobalGenerator.cxx: BUG: Use variable instead of
- retrieving again. Fixes bug: Bug #3476
-
-2006-10-12 15:10 andy
-
- * Source/CTest/cmCTestScriptHandler.cxx: BUG: Report and error when
- ctest -S script fails... Fixes: Bug #3540
-
-2006-10-12 14:59 andy
-
- * Modules/NSIS.template.in, Source/CPack/cmCPackNSISGenerator.cxx:
- ENH: Add NSIS compression
-
-2006-10-12 14:47 andy
-
- * Source/CTest/cmCTestBuildHandler.cxx: ENH: Handle more regular
- expressions
-
-2006-10-12 13:30 andy
-
- * Tests/: SimpleInstall/PackageScript.cmake,
- SimpleInstallS2/PackageScript.cmake: ENH: Several CPack fixes.
- First, allow user to set CMAKE_MODULE_PATH for CPack; make
- SetOptionIfNotSet more robust to handle empty options; do test
- TGZ, STGZ, and TZ, Add handling (and test) of Install Script; set
- environment variable CMAKE_INSTALL_PREFIX
-
-2006-10-12 13:15 andy
-
- * Modules/CTestTargets.cmake: ENH: On Visual Studio and Xcode
- handle config type
-
-2006-10-12 13:12 andy
-
- * Modules/: FindJNI.cmake, FindJava.cmake: ENH: More locations for
- Java
-
-2006-10-12 13:05 andy
-
- * Modules/CPack.cmake, Source/CPack/cmCPackGenericGenerator.cxx,
- Source/CPack/cmCPackGenericGenerator.h, Source/CPack/cpack.cxx,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: Several CPack fixes.
- First, allow user to set CMAKE_MODULE_PATH for CPack; make
- SetOptionIfNotSet more robust to handle empty options; do test
- TGZ, STGZ, and TZ, Add handling (and test) of Install Script; set
- environment variable CMAKE_INSTALL_PREFIX
-
-2006-10-12 12:51 martink
-
- * Source/: cmCTest.cxx, cmCTest.h: ENH: some cleanup and commenting
- of code
-
-2006-10-12 10:57 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: fix for bug -gdwarf
- getting removed
-
-2006-10-11 12:41 king
-
- * Source/cmMakefileLibraryTargetGenerator.cxx,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: BUG: Do not collapse the
- INSTALL_NAME_DIR setting because users may intend to have .. in
- the path. This makes the makefile generator consistent with the
- already working Xcode implementation of this feature. Also added
- a test for @executable_path/.. style settings for this property.
-
-2006-10-11 12:41 king
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: Simplify code by removing
- redundant check against BUILD_WITH_INSTALL_RPATH.
-
-2006-10-10 16:03 king
-
- * Modules/readme.txt: STYLE: Fixed typo: INCLUDE_DIR->INCLUDE_DIRS.
-
-2006-10-10 14:13 king
-
- * Source/cmLocalGenerator.cxx: BUG: TARGET_QUOTED should always be
- replaced if Target is set in the rule variables.
-
-2006-10-10 13:47 king
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.cxx: BUG: Avoid duplicate
- conversion to output path.
-
-2006-10-10 12:24 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-10-09 21:48 king
-
- * Source/: cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h: BUG: Fixed references to
- projects outside the build tree and in other locations with
- spaces in the path. This is needed for
- out-of-source/out-of-binary subdirectories in the build.
-
-2006-10-09 21:25 king
-
- * Source/cmMakefileTargetGenerator.cxx,
- Tests/OutOfBinary/CMakeLists.txt, Tests/OutOfBinary/outlib.c,
- Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt,
- Tests/OutOfSource/OutOfSourceSubdir/simple.cxx,
- Tests/OutOfSource/SubDir/CMakeLists.txt: BUG: Fixed out-of-source
- subdirectories to work when they are also out-of-binary. Updated
- the OutOfSource test to test this feature.
-
-2006-10-09 11:03 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-10-09 10:06 david.cole
-
- * Source/kwsys/ProcessWin32.c: COMP: Fix or suppress warnings on
- Borland and Mac dashboards. Definitely fix "may be used
- uninitialized" warnings.
-
-2006-10-08 09:23 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-10-07 06:15 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-10-06 15:33 martink
-
- * Source/CursesDialog/cmCursesMainForm.cxx: ENH: remove old unused
- code
-
-2006-10-06 14:00 martink
-
- * Source/cmDocumentation.cxx: BUG: potential segfault
-
-2006-10-06 11:13 david.cole
-
- * Source/kwsys/CMakeLists.txt: STYLE: Make the set of supported STL
- headers the same in vtkstd and vtksys/stl. (The union of the
- present values of the two sets.)
-
-2006-10-06 11:11 hoffman
-
- * Source/: cmMessageCommand.cxx, cmake.cxx, cmake.h, cmakemain.cxx:
- ENH: do not print a call stack if the user does a message error
- unless --debug-output is used
-
-2006-10-06 09:16 king
-
- * Modules/Platform/Darwin.cmake: BUG: Do not enable -isystem
- support for Xcode generator until it is implemented.
-
-2006-10-06 03:32 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-10-05 17:53 hoffman
-
- * Source/CTest/: cmCTestCoverageHandler.cxx,
- cmCTestTestHandler.cxx: BUG: fix bug where converage was required
- to get valgrind output because of bad current directory
-
-2006-10-05 16:59 king
-
- * Source/: cmLocalGenerator.cxx, cmOrderLinkDirectories.cxx: BUG:
- Need to match shared library names before static because some
- platforms have static name patterns that match their shared
- patterns but not vice versa. This is needed for implementing
- bug#1644 on cygwin.
-
-2006-10-05 16:30 king
-
- * Modules/Platform/CYGWIN.cmake, Source/cmTarget.cxx: ENH: Adding
- version number to the name of a DLL built in cygwin but not the
- import library. This addresses bug#3571.
-
-2006-10-05 15:08 king
-
- * Modules/Platform/: CYGWIN.cmake, Windows-gcc.cmake: ENH: Enabling
- link-type selection flags on Cygwin, MSYS, and MinGW. This
- addresses bug#1644 on these platforms.
-
-2006-10-05 15:08 king
-
- * Source/cmLocalGenerator.cxx, Source/cmOrderLinkDirectories.cxx,
- Source/cmOrderLinkDirectories.h,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/complex.cxx: BUG: Fix link
- flags on cygwin shared libraries. This requires that the shared
- library prefix be supported in the link library regex.
-
-2006-10-05 14:51 king
-
- * Source/: cmGlobalMinGWMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: BUG: Hack to make echo command
- work properly in mingw32-make.
-
-2006-10-05 13:43 king
-
- * Source/cmWin32ProcessExecution.cxx: BUG: Robustly handle failure
- of FormatMessage. See bug#3471.
-
-2006-10-05 12:04 king
-
- * Tests/: Complex/CMakeLists.txt, Complex/Library/testSystemDir.h,
- ComplexOneConfig/CMakeLists.txt,
- ComplexOneConfig/Library/testSystemDir.h,
- ComplexRelativePaths/CMakeLists.txt,
- ComplexRelativePaths/Library/testSystemDir.h,
- Complex/Library/SystemDir/testSystemDir.h,
- ComplexOneConfig/Library/SystemDir/testSystemDir.h,
- ComplexRelativePaths/Library/SystemDir/testSystemDir.h: BUG: Test
- -isystem without affecting other tests. Made separate
- Library/SystemDir for this purpose.
-
-2006-10-05 11:31 king
-
- * Source/cmInstallCommand.cxx, Source/cmInstallCommand.h,
- Source/cmInstallFilesGenerator.cxx,
- Source/cmInstallFilesGenerator.h,
- Source/cmInstallTargetGenerator.cxx,
- Source/cmInstallTargetGenerator.h,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: Added OPTIONAL option
- to INSTALL command to allow installation of files if they exist
- while ignoring them otherwise. This addresses bug#2922.
-
-2006-10-05 11:30 king
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt: BUG: Run
- testSystemDir test only if -isystem flag is available.
-
-2006-10-05 10:55 king
-
- * Source/cmDocumentation.cxx: ENH: Adding links to web resources
- and FAQ to SEE ALSO section. This addresses bug #3757.
-
-2006-10-05 09:33 king
-
- * Modules/Platform/QNX.cmake: BUG: QNX GCC does not have -isystem.
-
-2006-10-05 08:55 king
-
- * Modules/Platform/gcc.cmake, Source/cmIncludeDirectoryCommand.cxx,
- Source/cmIncludeDirectoryCommand.h, Source/cmLocalGenerator.cxx,
- Source/cmMakefile.cxx, Source/cmMakefile.h,
- Tests/Complex/CMakeLists.txt,
- Tests/Complex/Executable/CMakeLists.txt,
- Tests/Complex/Executable/testSystemDir.cxx,
- Tests/Complex/Library/testSystemDir.h,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/testSystemDir.cxx,
- Tests/ComplexOneConfig/Library/testSystemDir.h,
- Tests/ComplexRelativePaths/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/testSystemDir.cxx,
- Tests/ComplexRelativePaths/Library/testSystemDir.h: ENH: Adding
- SYSTEM option to INCLUDE_DIRECTORIES command. This addresses bug
- #3462.
-
-2006-10-05 03:57 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-10-04 19:21 king
-
- * Source/CursesDialog/ccmake.cxx: BUG: The --help option should
- list generators. This addresses bug #2494.
-
-2006-10-04 18:57 king
-
- * Tests/CustomCommand/CMakeLists.txt: ENH: Adding test of special
- characters in custom command and custom target comments.
-
-2006-10-04 18:52 king
-
- * Source/: cmGlobalBorlandMakefileGenerator.cxx,
- cmGlobalNMakeMakefileGenerator.cxx,
- cmGlobalWatcomWMakeGenerator.cxx, cmLocalGenerator.cxx,
- cmLocalGenerator.h, cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: BUG: Fixed display of custom
- command comments with quotes, dollars, and other special
- characters in them.
-
-2006-10-04 18:52 king
-
- * Source/kwsys/: System.c, System.h.in: ENH: Adding
- Shell_Flag_EchoWindows option to setup escapes for arguments to
- the native echo command in a shell. This special case is needed
- to avoid adding quotes when passing text to echo in a native
- windows shell which does no command line parsing at all.
-
-2006-10-04 18:10 king
-
- * Source/cmAddCustomTargetCommand.cxx,
- Source/cmAddCustomTargetCommand.h, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Tests/CustomCommand/CMakeLists.txt: ENH:
- Added COMMENT option to ADD_CUSTOM_TARGET. This addresses
- bug#3461.
-
-2006-10-04 18:09 king
-
- * Source/cmAddCustomCommandCommand.h: BUG: COMMENT was missing from
- docs.
-
-2006-10-04 17:27 king
-
- * Source/kwsys/: CMakeLists.txt, ProcessUNIX.c,
- kwsysPlatformTestsC.c: ENH: Adding tests KWSYS_C_HAS_PTRDIFF_T
- and KWSYS_C_HAS_SSIZE_T to help ProcessUNIX.c build everywhere
- without warnings.
-
-2006-10-04 17:24 king
-
- * bootstrap: ENH: Renamed kwsysPlatformCxxTests to
- kwsysPlatformTests and generalized it for multiple language tests
- (C and CXX).
-
-2006-10-04 17:08 king
-
- * Source/kwsys/kwsysPlatformTests.cmake: BUG: Name of C test file
- ends in .c not .cxx.
-
-2006-10-04 16:56 king
-
- * Source/kwsys/: CMakeLists.txt, kwsysPlatformCxxTests.cmake,
- kwsysPlatformCxxTests.cxx, kwsysPlatformTests.cmake,
- kwsysPlatformTestsC.c, kwsysPlatformTestsCXX.cxx: ENH: Renamed
- kwsysPlatformCxxTests to kwsysPlatformTests and generalized it
- for multiple language tests (C and CXX).
-
-2006-10-04 16:31 hoffman
-
- * Modules/FindDoxygen.cmake: ENH: remove paths that cmake already
- looks at
-
-2006-10-04 15:54 alex
-
- * Modules/FindRuby.cmake: ENH: apply patch so that the config
- values from ruby are used to determine the additional locations
- (see #3297)
-
- Alex
-
-2006-10-04 15:24 king
-
- * Source/cmAddCustomCommandCommand.cxx,
- Source/cmAddCustomCommandCommand.h, Source/cmCustomCommand.cxx,
- Source/cmCustomCommand.h, Tests/CustomCommand/CMakeLists.txt:
- ENH: Added APPEND option to ADD_CUSTOM_COMMAND to allow extra
- dependencies to be connected later. This is useful to create one
- rule and then have a macro add things to it later. This
- addresses bug#2151.
-
-2006-10-04 14:37 king
-
- * Source/cmCommandArgumentParser.cxx,
- Source/cmCommandArgumentParser.y,
- Source/cmCommandArgumentParserHelper.cxx,
- Source/cmCommandArgumentParserHelper.h, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Tests/CustomCommand/CMakeLists.txt: BUG: Do
- not replace @VAR@ syntax in list files. This addresses bug
- #2722.
-
-2006-10-04 14:02 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: fix for fat file
- systems and vs8 #2617
-
-2006-10-04 14:00 king
-
- * Modules/UseQt4.cmake: BUG: Patch from Clinton to restore proper
- QT3_SUPPORT macro definition.
-
-2006-10-04 13:27 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: fix for bug#3362
- xml escapes on -D stuff for visual studio
-
-2006-10-04 13:05 hoffman
-
- * Modules/FindTCL.cmake: BUG: fix for bug# 3313 same advanced for
- tcl win and unix
-
-2006-10-04 11:33 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: fix for bug# 3664
-
-2006-10-04 11:11 hoffman
-
- * Source/cmGlobalGenerator.cxx: BUG: fix for bug #3517 seg fault
- with enable language before project command
-
-2006-10-04 11:04 hoffman
-
- * Modules/FindDoxygen.cmake: BUG: fix for bug#3520 - better find
- doxygen
-
-2006-10-04 10:54 hoffman
-
- * Modules/Platform/Darwin.cmake: BUG: fix for bug# 3584 missing
- SONAME for fortran on darwin
-
-2006-10-04 10:33 hoffman
-
- * Modules/FindQt4.cmake: ENH: make qmake-qt4 really work if qmake
- is qt3 also fix indent in file, for diff use cvs diff -w
-
-2006-10-04 05:20 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-10-03 17:53 hoffman
-
- * Source/cmGlobalGenerator.cxx: ENH: fix dashbaord error do not
- exclude root project from itself.
-
-2006-10-03 16:18 hoffman
-
- * Modules/FindGLUT.cmake: BUG: fix for bug#3646 GLUT not Glut for
- framework name
-
-2006-10-03 16:12 hoffman
-
- * Modules/Platform/Windows-cl.cmake: BUG: fix for bug#3652 use link
- /lib instead of lib
-
-2006-10-03 15:25 hoffman
-
- * Source/CMakeLists.txt: ENH: use core and not all of carbon
-
-2006-10-03 15:12 hoffman
-
- * Source/cmGlobalGenerator.cxx: BUG: fix for bug#3714
- execlude_from_all not working on vs
-
-2006-10-03 14:40 martink
-
- * Source/: cmCommands.cxx, cmEndMacroCommand.cxx,
- cmEndMacroCommand.h: ENH: added endmacro command
-
-2006-10-03 14:39 hoffman
-
- * Modules/FindQt4.cmake: BUG: fix for bug#3720
-
-2006-10-03 14:03 alex
-
- * Modules/KDE3Macros.cmake: BUG: fix #3827, the name of the var is
- _tmp_FILE instead of tmp_FILE, so the dcop stuff should work now
-
- Alex
-
-2006-10-03 14:03 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: fix for bug#3738
-
-2006-10-03 13:48 hoffman
-
- * Modules/FindSDL.cmake: BUG: fix for 3765
-
-2006-10-03 13:45 hoffman
-
- * Source/cmAddTestCommand.h: BUG: fix for bug#3775
-
-2006-10-03 13:35 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: check for empty path
-
-2006-10-03 13:35 hoffman
-
- * Modules/Platform/AIX.cmake: ENH: disable static shared stuff on
- AIX, see comment
-
-2006-10-03 13:35 hoffman
-
- * Source/cmGlobalMSYSMakefileGenerator.cxx: BUG: bug#3789 add msys
- for the msys generator
-
-2006-10-03 13:22 hoffman
-
- * Source/cmTryCompileCommand.cxx: ENH: make sure file is closed
-
-2006-10-03 12:09 hoffman
-
- * Source/cmMacroCommand.cxx: ENH: fix compile error
-
-2006-10-03 11:55 hoffman
-
- * Source/cmake.cxx: ENH: do not allow null pointer access
-
-2006-10-03 11:55 hoffman
-
- * Source/kwsys/Registry.cxx: ENH: make sure value is set before
- using it
-
-2006-10-03 10:57 hoffman
-
- * Source/cmMacroCommand.cxx: BUG: fix for seg fault bug #3815
-
-2006-10-03 10:26 king
-
- * Source/kwsys/ProcessUNIX.c: BUG: Need to initialize to not use
- native pipes.
-
-2006-10-03 09:12 king
-
- * Source/cmGlobalKdevelopGenerator.cxx: STYLE: Fixed line-too-long
- warning.
-
-2006-10-03 09:10 king
-
- * Source/kwsys/: Process.h.in, ProcessUNIX.c, ProcessWin32.c: ENH:
- Added Process_SetPipeNative method to allow user code to override
- the pipes connected to the child pipeline.
-
-2006-10-03 05:59 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-10-02 12:01 king
-
- * Source/cmAddExecutableCommand.cxx,
- Source/cmAddExecutableCommand.h, Source/cmAddLibraryCommand.cxx,
- Source/cmAddLibraryCommand.h,
- Tests/Complex/Executable/CMakeLists.txt,
- Tests/Complex/Library/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Library/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Library/CMakeLists.txt: ENH: Renamed
- NOT_IN_ALL to EXCLUDE_FROM_ALL.
-
-2006-10-02 11:13 king
-
- * Source/cmAddExecutableCommand.cxx,
- Source/cmAddExecutableCommand.h, Source/cmAddLibraryCommand.cxx,
- Source/cmAddLibraryCommand.h, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Tests/Complex/Executable/CMakeLists.txt,
- Tests/Complex/Executable/notInAllExe.cxx,
- Tests/Complex/Library/CMakeLists.txt,
- Tests/Complex/Library/notInAllLib.cxx,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/notInAllExe.cxx,
- Tests/ComplexOneConfig/Library/CMakeLists.txt,
- Tests/ComplexOneConfig/Library/notInAllLib.cxx,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/notInAllExe.cxx,
- Tests/ComplexRelativePaths/Library/CMakeLists.txt,
- Tests/ComplexRelativePaths/Library/notInAllLib.cxx: ENH: Added
- NOT_IN_ALL option for ADD_LIBRARY and ADD_EXECUTABLE to avoid
- building the targets by default.
-
-2006-10-02 10:49 king
-
- * Source/cmGlobalKdevelopGenerator.cxx: ENH: Patch from Alex to
- help with KDevelop code completion in generated projects.
-
-2006-10-02 10:20 king
-
- * Source/: cmAddCustomCommandCommand.h, cmGlobalGenerator.cxx,
- cmGlobalGenerator.h, cmGlobalWatcomWMakeGenerator.cxx,
- cmMakefile.cxx, cmMakefileTargetGenerator.cxx,
- cmSetSourceFilesPropertiesCommand.h: ENH: Added SYMBOLIC source
- file property to mark custom command outputs that are never
- actually created on disk. This is used by the Watcom WMake
- generator to generate the .SYMBOLIC mark on the files in the make
- system.
-
-2006-10-02 10:17 king
-
- * Tests/CustomCommand/: CMakeLists.txt, check_command_line.c.in:
- COMP: Fix command line check test implementation for Watcom.
-
-2006-10-02 09:03 hoffman
-
- * Modules/FindQt4.cmake: ENH: fix from clinton
-
-2006-10-02 04:26 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-10-01 04:35 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-30 03:55 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-29 16:42 king
-
- * Source/: cmGetTargetPropertyCommand.h, cmTarget.cxx: ENH: Added
- support for getting a target's location on a per-configuration
- basis (ex. DEBUG_LOCATION). This does not fix but helps with
- bug#3250.
-
-2006-09-29 16:14 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: fix failing tests on mac
-
-2006-09-29 09:11 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Fixed inclusion of
- progress.make from subdirectory makefiles.
-
-2006-09-29 03:53 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-28 17:35 king
-
- * Source/cmIncludeExternalMSProjectCommand.cxx: BUG: Move hack from
- old cmMakefile::AddUtilityTarget to this command directly. There
- really needs to be a better way to represent external project
- targets.
-
-2006-09-28 17:21 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Moved
- progress.make file into CMakeFiles subdirectory to keep things
- clean.
-
-2006-09-28 16:40 king
-
- * Source/: cmAddCustomCommandCommand.cxx, cmCustomCommand.cxx,
- cmCustomCommand.h, cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio71Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h,
- cmGlobalVisualStudio8Generator.cxx,
- cmGlobalVisualStudio8Generator.h, cmLocalGenerator.cxx,
- cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h, cmMakefile.cxx,
- cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileExecutableTargetGenerator.h,
- cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.h,
- cmMakefileTargetGenerator.cxx, cmMakefileTargetGenerator.h: BUG:
- Fix/cleanup custom commands and custom targets. Make empty
- comment strings work. Fix ZERO_CHECK target always out of date
- for debugging. Fix Makefile driving of custom commands in a
- custom target. Fix dependencies on custom targets not in ALL in
- VS generators.
-
-2006-09-28 13:55 king
-
- * Source/: cmAddCustomTargetCommand.cxx, cmCPluginAPI.cxx,
- cmGlobalGenerator.cxx, cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio8Generator.cxx, cmGlobalXCodeGenerator.cxx,
- cmIncludeExternalMSProjectCommand.cxx, cmMakefile.cxx,
- cmMakefile.h, cmVTKWrapJavaCommand.cxx: ENH: Cleaned up signature
- of cmMakefile::AddUtilityCommand. It is not valid to have an
- output from a utility rule and no calls to the method asked for
- an output anyway. The argument has been removed.
-
-2006-09-28 11:42 king
-
- * Modules/Platform/UnixPaths.cmake: BUG: Header and library search
- path ordering should be consistent.
-
-2006-09-28 11:30 king
-
- * Source/cmAddCustomCommandCommand.cxx,
- Source/cmAddCustomCommandCommand.h,
- Source/cmAddCustomTargetCommand.cxx,
- Source/cmAddCustomTargetCommand.h, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Tests/CustomCommand/CMakeLists.txt,
- Tests/CustomCommand/check_command_line.c.in: ENH: Added VERBATIM
- option to ADD_CUSTOM_COMMAND and ADD_CUSTOM_TARGET commands.
- This option enables full escaping of custom command arguments on
- all platforms. See bug#3786.
-
-2006-09-28 10:41 king
-
- * Tests/: Complex/Library/CMakeLists.txt,
- ComplexOneConfig/Library/CMakeLists.txt,
- ComplexRelativePaths/Library/CMakeLists.txt: ENH: Re-enabling .i
- rule test on MSYS now that it works.
-
-2006-09-28 10:37 king
-
- * Source/: cmGlobalMSYSMakefileGenerator.cxx, cmLocalGenerator.cxx,
- cmLocalGenerator.h, cmLocalUnixMakefileGenerator3.h: BUG: MSYS
- makefile shell needs posix paths to executables in some cases and
- it does not hurt to do it always.
-
-2006-09-28 09:49 king
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h,
- cmLocalUnixMakefileGenerator3.cxx: BUG: Do not filter system
- directories for include file dependencies.
-
-2006-09-28 02:33 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-27 16:20 king
-
- * Source/cmCustomCommand.cxx: COMP: Fix init order.
-
-2006-09-27 16:14 king
-
- * Source/cmCommandArgumentParserHelper.cxx: BUG: One should be able
- to escape the @ symbol.
-
-2006-09-27 15:26 king
-
- * Source/cmCustomCommand.cxx: BUG: The copy constructor should copy
- the escape settings.
-
-2006-09-27 14:27 king
-
- * Tests/: Complex/Library/CMakeLists.txt,
- ComplexOneConfig/Library/CMakeLists.txt,
- ComplexRelativePaths/Library/CMakeLists.txt: ENH: Re-enable
- preprocessing target test but specifically disable it on broken
- platforms.
-
-2006-09-27 13:43 king
-
- * Source/: cmCustomCommand.cxx, cmCustomCommand.h,
- cmGlobalXCodeGenerator.cxx, cmLocalGenerator.cxx,
- cmLocalGenerator.h, cmLocalUnixMakefileGenerator3.cxx,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudioGenerator.cxx, cmLocalVisualStudioGenerator.h,
- kwsys/ProcessWin32.c, kwsys/System.c, kwsys/System.h.in: ENH:
- Re-implemented command line argument shell quoting to support
- several platforms with one code base.
-
-2006-09-27 13:30 alex
-
- * Modules/: FindPythonInterp.cmake, FindPythonLibs.cmake:
- ENH: apply patch from Dirk Mueller to support Python 2.5
-
- Alex
-
-2006-09-27 12:55 king
-
- * Source/cmDependsC.cxx: STYLE: Fixed line-too-long.
-
-2006-09-26 08:04 andy
-
- * Source/cmDependsC.cxx: BUG: Handle header file dependencies for
- objective C
-
-2006-09-26 02:30 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-25 18:33 king
-
- * Source/cmCommandArgumentLexer.cxx: COMP: Removed yyunput function
- to avoid warning.
-
-2006-09-25 14:01 king
-
- * Source/cmCommandArgumentLexer.cxx: COMP: Restoring previous AIX
- fix.
-
-2006-09-25 10:22 king
-
- * Source/cmLocalGenerator.cxx, Tests/CustomCommand/CMakeLists.txt:
- BUG: Disable new shell escape code until backward compatibility
- can be established in the new implementation.
-
-2006-09-25 10:05 king
-
- * Source/cmCommandArgumentLexer.cxx,
- Source/cmCommandArgumentLexer.h,
- Source/cmCommandArgumentLexer.in.l,
- Tests/StringFileTest/CMakeLists.txt: BUG: Character + should be
- valid in a variable name.
-
-2006-09-25 02:39 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-24 10:28 king
-
- * Tests/: Complex/Library/CMakeLists.txt,
- ComplexOneConfig/Library/CMakeLists.txt,
- ComplexRelativePaths/Library/CMakeLists.txt: BUG: Disable new
- test_preprocess target until it is fixed on OSX universal
- binaries and mingw.
-
-2006-09-24 02:40 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-23 17:09 king
-
- * Docs/: cmake-indent.vim, cmake-syntax.vim: ENH: Adding elseif to
- VIM syntax and indentation files. See bug #3781.
-
-2006-09-23 16:55 king
-
- * Tests/: Complex/Library/CMakeLists.txt,
- Complex/Library/test_preprocess.cmake,
- ComplexOneConfig/Library/CMakeLists.txt,
- ComplexOneConfig/Library/test_preprocess.cmake,
- ComplexRelativePaths/Library/CMakeLists.txt,
- ComplexRelativePaths/Library/test_preprocess.cmake: ENH: Adding
- test for running preprocessor rules.
-
-2006-09-23 16:32 king
-
- * Docs/cmake-mode.el: ENH: Adding elseif indentation. See
- bug#3781.
-
-2006-09-23 14:41 andy
-
- * Source/CPack/cmCPackZIPGenerator.cxx: BUG: Attempt to fix winzip
- problems
-
-2006-09-23 02:33 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-22 11:49 martink
-
- * Tests/: Complex/CMakeLists.txt, Complex/cmTestConfigure.h.in,
- Complex/Executable/complex.cxx, ComplexOneConfig/CMakeLists.txt,
- ComplexOneConfig/cmTestConfigure.h.in,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/CMakeLists.txt,
- ComplexRelativePaths/cmTestConfigure.h.in,
- ComplexRelativePaths/Executable/complex.cxx: ENH: added test for
- elseif
-
-2006-09-22 11:23 martink
-
- * Source/: cmCommands.cxx, cmElseIfCommand.cxx, cmElseIfCommand.h,
- cmIfCommand.cxx, cmIfCommand.h: ENH: added elseif
-
-2006-09-22 08:42 king
-
- * Tests/CustomCommand/CMakeLists.txt: COMP: Need ANSI C flags to
- build check_command_line.c.
-
-2006-09-22 02:19 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-21 17:21 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: COMP: Fix shadowed
- local variable created by previous cmake_force change.
-
-2006-09-21 16:11 king
-
- * Tests/CustomCommand/: CMakeLists.txt, check_command_line.c.in:
- ENH: Adding test for non-trivial custom command line arguments.
- This is for bug#3786.
-
-2006-09-21 16:10 king
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmLocalGenerator.h: BUG:
- Enabled use of EscapeForShell to properly escape custom command
- lines. This addresses bug#3786 for Xcode.
-
-2006-09-21 15:35 king
-
- * Source/cmLocalGenerator.cxx: BUG: Need to escape spaces in custom
- command line arguments.
-
-2006-09-21 15:30 king
-
- * Source/cmLocalGenerator.cxx: BUG: Do not escape parens because we
- need to be able to reference make variables in the scripts.
-
-2006-09-21 15:14 king
-
- * Source/: cmGlobalVisualStudio8Generator.cxx,
- cmLocalGenerator.cxx, cmLocalGenerator.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudioGenerator.cxx, cmLocalVisualStudioGenerator.h:
- BUG: Centralized generation of command line arguments in escaped
- form. This addresses bug#3786 for several platforms.
-
-2006-09-21 15:09 andy
-
- * Source/CPack/cmCPackZIPGenerator.cxx: ENH: Handle zip (command
- line was too long)
-
-2006-09-21 14:46 king
-
- * Source/kwsys/System.c: BUG: Windows_ShellArgument: need to escape
- if the string contains one of a set of special characters as well
- as spaces. Moved test for needing escapes to a separate method
- kwsysSystemWindowsShellArgumentNeedsEscape.
-
-2006-09-21 13:47 king
-
- * bootstrap: ENH: Added System component of kwsys.
-
-2006-09-21 11:49 king
-
- * Source/kwsys/: CMakeLists.txt, ProcessWin32.c, System.c,
- System.h.in: ENH: Adding 'System' component of C sources to hold
- system tools written in C. Moved windows shell command line
- argument escaping code to kwsysSystem_Windows_ShellArgument and
- kwsysSystem_Windows_ShellArgumentSize.
-
-2006-09-21 10:04 king
-
- * Source/kwsys/SharedForward.h.in: ENH: Added
- KWSYS_SHARED_FORWARD_OPTION_COMMAND option to allow users to
- replace the command executed. Extended documentation at top of
- file.
-
-2006-09-21 02:11 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-20 12:13 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: cmake_force needs
- to be written into build.make as well as Makefile.
-
-2006-09-20 02:13 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-19 16:11 alex
-
- * Modules/: COPYING-CMAKE-SCRIPTS, FindASPELL.cmake,
- FindBZip2.cmake, FindHSPELL.cmake, FindJasper.cmake,
- FindLibXml2.cmake, FindLibXslt.cmake, FindOpenSSL.cmake: ENH: add
- cmake modules for some common libraries: aspell, hspell, bzip2,
- jasper (jpeg2000), libxml2 and libxslt and openssl and the
- accompanying license (BSD)
-
- Alex
-
-2006-09-19 02:17 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-18 17:55 alex
-
- * Modules/: CheckCCompilerFlag.cmake, CheckCXXCompilerFlag.cmake:
- ENH: two macros to check whether the C/CXX compiler supports a
- given flag: CHECK_CXX_COMPILER_FLAG("-Wall"
- COMPILER_SUPPORTS_WALL)
-
- Alex
-
-2006-09-18 09:40 king
-
- * Modules/Platform/QNX.cmake: ENH: Enabling link type selection
- flags for this platform. See bug#1644 for details.
-
-2006-09-18 02:36 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-17 09:24 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-16 11:54 king
-
- * Source/cmDependsC.cxx: STYLE: Fixed line-too-long.
-
-2006-09-16 11:52 king
-
- * Source/cmLocalGenerator.cxx: BUG: Do not look for linker language
- unless it is needed.
-
-2006-09-16 11:47 king
-
- * Modules/Platform/SunOS.cmake: BUG: Need -Wl, to pass linker flags
- when using gcc on Sun.
-
-2006-09-16 09:19 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-15 15:19 king
-
- * Modules/Platform/AIX.cmake: ENH: Enabling link type selection
- flags for this platform. See bug#1644 for details.
-
-2006-09-15 15:18 king
-
- * Modules/Platform/HP-UX.cmake: STYLE: Updated comment about link
- type flags and passing directly to ld.
-
-2006-09-15 15:14 king
-
- * Modules/Platform/HP-UX.cmake: BUG: Fix
- CMAKE_SHARED_*_LINK_*_C_FLAGS to pass link type selection flags
- directly to the linker.
-
-2006-09-15 15:05 king
-
- * Modules/Platform/SunOS.cmake: ENH: Enabling link type selection
- flags for this platform. See bug#1644 for details.
-
-2006-09-15 14:58 king
-
- * Modules/Platform/: FreeBSD.cmake, HP-UX.cmake: ENH: Enabling link
- type selection flags for this platform. See bug#1644 for
- details.
-
-2006-09-15 14:31 king
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/complex.cxx,
- Complex/Library/CMakeLists.txt, Complex/Library/TestLink.c,
- ComplexOneConfig/Library/CMakeLists.txt,
- ComplexOneConfig/Library/TestLink.c,
- ComplexRelativePaths/Library/CMakeLists.txt,
- ComplexRelativePaths/Library/TestLink.c: ENH: Added test for
- linking to a static library that is next to a shared library.
- See bug#1644 for related changes.
-
-2006-09-15 14:08 king
-
- * Modules/CMakeCXXInformation.cmake,
- Modules/CMakeSystemSpecificInformation.cmake,
- Modules/Platform/Linux.cmake, Source/cmLocalGenerator.cxx,
- Source/cmOrderLinkDirectories.cxx,
- Source/cmOrderLinkDirectories.h,
- Tests/SystemInformation/SystemInformation.in: ENH: Adding support
- to link specifically to an archive or a shared library based on
- the file name specified. This fixes the problem of having -lfoo
- linking to libfoo.so even when it came from libfoo.a being
- specified.
-
-2006-09-15 14:02 king
-
- * Modules/CMakeFortranInformation.cmake: STYLE: Removing unused
- platform variable CMAKE_SHARED_MODULE_LINK_Fortran_FLAGS. It
- does not make sense because nothing links to shared modules.
-
-2006-09-15 09:23 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-14 09:09 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-13 12:43 king
-
- * Source/: cmDependsC.cxx, cmDependsC.h: ENH: Patch from Alex to
- speed dependency scanning approximately 2x.
-
-2006-09-13 11:39 king
-
- * Source/cmAddCustomTargetCommand.cxx: ENH: Added diagnosis of bad
- target names.
-
-2006-09-13 11:22 king
-
- * Modules/FindwxWidgets.cmake: BUG: Patch from Peter Visser to run
- wx-config from an MSYS prompt.
-
-2006-09-13 08:55 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-12 10:21 hoffman
-
- * Source/cmMakefileTargetGenerator.cxx: ENH: put the if in the
- right place
-
-2006-09-12 10:03 hoffman
-
- * Source/cmMakefileTargetGenerator.cxx: ENH: fix for BUG: #739
- again, makefiles did not depend on external full path libraries
-
-2006-09-12 09:18 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-10 22:26 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-09 21:06 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-08 22:51 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-08 10:42 king
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.cxx, cmMakefileTargetGenerator.cxx:
- BUG: Fixed ordering of code generated in Makefile and build.make
- files to make sure .SUFFIXES rule comes as early as possible.
- Also cleaned up documentation in generated files.
-
-2006-09-08 10:39 king
-
- * Source/cmInstallCommand.cxx: STYLE: Fixed line-too-long.
-
-2006-09-08 09:58 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-07 10:05 king
-
- * Source/cmInstallCommand.cxx: ENH: Patch from Toni Timonen to
- allow cross-compiling of DLLs.
-
-2006-09-07 08:58 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-06 09:10 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-06 08:31 hoffman
-
- * Modules/: FindQt4.cmake, UseQt4.cmake: ENH: fixes from Clinton to
- allow qt to work with static libs
-
-2006-09-05 09:01 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-04 09:04 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-03 09:00 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-02 10:51 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Patch from Alex to
- fix name of includecache files to not look like source files.
-
-2006-09-02 09:03 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-09-01 09:51 king
-
- * Source/: cmBuildNameCommand.h, cmExecProgramCommand.h,
- cmGlobalGenerator.cxx, cmInstallFilesCommand.h,
- cmInstallProgramsCommand.h, cmInstallTargetsCommand.h,
- cmLinkLibrariesCommand.h, cmMakeDirectoryCommand.h,
- cmRemoveCommand.h, cmSubdirCommand.h, cmSubdirDependsCommand.h,
- cmVTKMakeInstantiatorCommand.h, cmVTKWrapJavaCommand.h,
- cmVTKWrapPythonCommand.h, cmVTKWrapTclCommand.h: STYLE: Fixed
- line-too-long warning.
-
-2006-09-01 08:58 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-31 16:40 king
-
- * Source/cmAddSubDirectoryCommand.cxx: BUG: Fix automatic
- computation of binary path to work for subdirectories of out of
- source directories. This addresses bug#3592.
-
-2006-08-31 14:09 king
-
- * Source/: cmDependsC.cxx, cmDependsC.h,
- cmLocalUnixMakefileGenerator3.cxx, cmMakefileTargetGenerator.cxx:
- ENH: Make sure all custom command outputs are up to date before
- scanning dependencies. This avoids the need to pass a list of
- generated files to the dependency scanning code and to rescan
- after the files have been generated. Currently there is no
- notion of implicit dependencies of the custom commands themselves
- so this design is safe. We only need to make sure implicit
- dependencies are up to date before the make process for the
- /build part of a target is executed because only this process
- loads them. This is a step towards fixing bug#3658.
-
-2006-08-31 13:20 king
-
- * Source/: cmBuildNameCommand.h, cmCommand.h,
- cmExecProgramCommand.h, cmInstallFilesCommand.h,
- cmInstallProgramsCommand.h, cmInstallTargetsCommand.h,
- cmLinkLibrariesCommand.h, cmMakeDirectoryCommand.h,
- cmRemoveCommand.h, cmSubdirCommand.h, cmSubdirDependsCommand.h,
- cmVTKMakeInstantiatorCommand.h, cmVTKWrapJavaCommand.h,
- cmVTKWrapPythonCommand.h, cmVTKWrapTclCommand.h: ENH: Patch from
- Alex to add IsDiscouraged method for future use in generating
- separate documentation for old commands. Also modified
- documentation of MAKE_DIRECTORY and REMOVE commands to indicate
- they should not be used.
-
-2006-08-31 10:47 king
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmInstallCommand.cxx, cmInstallFilesCommand.cxx,
- cmInstallProgramsCommand.cxx, cmInstallTargetsCommand.cxx: ENH:
- Do not generate install target unless some INSTALL or INSTALL_*
- commands have been used. This addresses bug#2827.
-
-2006-08-31 10:46 king
-
- * Modules/CMakeDetermineRCCompiler.cmake: BUG: Need to search for
- rc by default, not c++ compilers.
-
-2006-08-31 09:03 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-30 13:59 king
-
- * Source/kwsys/: CMakeLists.txt, kwsysPlatformCxxTests.cmake: COMP:
- Fix try-compile to fail properly on HP.
-
-2006-08-30 13:51 alex
-
- * Modules/FindQt3.cmake: ENH: automatically find Qt3 on SUSE, patch
- from Dirk Mueller and Stephan Kulow
-
- Alex
-
-2006-08-30 13:47 alex
-
- * Modules/FindPNG.cmake: ENH: also look in
- /usr/local/include/libpng (OpenBSD) ENH: error out with
- FATAL_ERROR if REQUIRED was given but png hasn't been found
-
- Alex
-
-2006-08-30 10:00 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-29 16:08 king
-
- * Source/cmGlobalKdevelopGenerator.cxx: ENH: Patch from Alex to fix
- current working directory when running executables built in
- KDevelop.
-
-2006-08-29 15:08 king
-
- * Source/cmInstallCommand.h: ENH: Add support to INSTALL(DIRECTORY)
- to install an empty directory. This addresses bug#3572.
-
-2006-08-29 15:04 king
-
- * Source/cmFileCommand.cxx, Source/cmInstallCommand.cxx,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: Add support to
- INSTALL(DIRECTORY) to install an empty directory. This addresses
- bug#3572.
-
-2006-08-29 13:59 king
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeDetermineCXXCompiler.cmake,
- CMakeDetermineFortranCompiler.cmake,
- CMakeDetermineRCCompiler.cmake: BUG: Search for the compiler only
- once and store a full path to it in the cache. This avoids
- problems with the case of locations in the PATH variable on
- Windows that change the compiler name when CMake is re-run.
- CMakeFiles/CMake*Compiler.cmake files should hold the full path
- to the compiler always.
-
-2006-08-29 12:55 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h: BUG: bad progress for named top
- level targets
-
-2006-08-29 10:27 king
-
- * Source/cmStandardIncludes.h: COMP: Fix warnings in system headers
- on VS6.
-
-2006-08-29 10:03 king
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalUnixMakefileGenerator3.h, cmLocalGenerator.cxx,
- cmLocalUnixMakefileGenerator3.cxx: ENH: Adding install/local
- global target for Makefile generators. This runs installation
- only in the current directory and not subdirectories.
-
-2006-08-29 09:40 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-28 08:55 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-27 15:52 alex
-
- * Modules/: KDE3Macros.cmake, kde3uic.cmake: BUG: fix #3324:
- KDE3Macros.cmake didn't find Qt designer plugins when running uic
- (the kde plugin dir wasn't used)
-
- Alex
-
-2006-08-27 15:34 alex
-
- * Modules/FindKDE3.cmake: STYLE: remove unnecessary
- /usr/local/include search path
-
- Alex
-
-2006-08-27 13:59 alex
-
- * Modules/FindQt3.cmake: BUG: #3514: qt-mt3.lib wasn't found on
- windows STYLE: remove some (now) unnecessary /usr/lib,
- /usr/local/lib, /usr/include and /usr/local/include search paths
-
- Alex
-
-2006-08-27 13:23 king
-
- * Source/cmStandardIncludes.h: COMP: Use new KWSys IOStream
- component to help print large file size integer types to streams.
-
-2006-08-27 13:17 king
-
- * Source/kwsys/: CMakeLists.txt, IOStream.cxx, IOStream.hxx.in,
- kwsysPlatformCxxTests.cxx: ENH: Adding KWSys component IOStream
- to provide help with broken C++ stream libraries.
-
-2006-08-27 13:15 king
-
- * Source/: cmFileCommand.cxx, CPack/cmCPackNSISGenerator.cxx: COMP:
- Need to use cmsys_stl when in CMake code, not kwsys_stl.
-
-2006-08-27 12:35 king
-
- * Source/kwsys/Glob.hxx.in: BUG: Need to undefine temporary macros
- defined at top of file.
-
-2006-08-27 11:25 king
-
- * Source/kwsys/kwsysPlatformCxxTests.cmake: BUG: When a try-run
- fails to compile create the run result cache entry with a bogus
- non-zero return value to avoid running the test again.
-
-2006-08-27 11:19 alex
-
- * Modules/: CheckCSourceCompiles.cmake,
- CheckCXXSourceCompiles.cmake: STYLE: fix #3519 (incorrect
- comment)
-
- Alex
-
-2006-08-27 11:14 alex
-
- * Modules/FindKDE3.cmake: BUG: fix comment (#3511)
-
- Alex
-
-2006-08-27 10:19 alex
-
- * Modules/KDE3Macros.cmake: BUG: apply patch from bero (#3518) so
- that DESTDIR is supported for installing icons
-
- Alex
-
-2006-08-27 09:57 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-27 09:34 alex
-
- * Modules/FindKDE3.cmake: ENH: #3225: first check the special
- paths, the the default path, also for searching kde-config
-
- Alex
-
-2006-08-26 16:14 king
-
- * Source/kwsys/SystemTools.cxx: BUG: GetLineFromStream should
- remove carriage return characters to make sure newlines do not
- get duplicates.
-
-2006-08-26 15:17 king
-
- * Source/kwsys/kwsysPlatformCxxTests.cmake: BUG: Fix location of
- CMakeOutput.log and CMakeError.log.
-
-2006-08-26 14:43 king
-
- * Source/cmMakefile.cxx: BUG: Reverting previous change until it is
- further tested.
-
-2006-08-26 14:37 king
-
- * Source/cmMakefile.cxx: BUG: ConfigureFile must read/write in
- binary mode to avoid windows newline trouble. The problem
- occurred when configuring a file in cygwin from a path starting
- with a windows drive letter instead of a posix path.
-
-2006-08-26 10:28 king
-
- * Source/: cmIfCommand.cxx, cmListCommand.cxx: STYLE: Fixed
- line-too-long.
-
-2006-08-26 10:22 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: STYLE: Fixed
- line-too-long.
-
-2006-08-26 09:42 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-25 22:56 king
-
- * Source/: cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h: BUG: Fix for VS.NET 2003 SP1 to
- make sure global target and utility target rules run every time.
-
-2006-08-25 22:56 king
-
- * Source/cmGlobalGenerator.cxx: BUG: Make sure targets of type
- GLOBAL_TARGET have a makefile set.
-
-2006-08-25 21:21 king
-
- * CMakeLists.txt, bootstrap: ENH: Changing default data and doc
- directories to share/cmake-V.v and doc/cmake-V.v instead of
- share/CMake and doc/CMake for consistency with many linux
- distribution conventions.
-
-2006-08-25 20:52 king
-
- * bootstrap: COMP: Fix for new kwsys Configure.h.in.
-
-2006-08-25 16:32 king
-
- * Source/kwsys/Configure.h.in: COMP: Disable _FILE_OFFSET_BITS
- check until sys/types.h check is enabled.
-
-2006-08-25 16:31 king
-
- * Source/cmIfCommand.cxx, Source/cmIfCommand.h,
- Tests/StringFileTest/CMakeLists.txt: ENH: Patch from Alex for
- adding IF(FILE_IS_NEWER). I also added a test.
-
-2006-08-25 16:07 king
-
- * Source/kwsys/Configure.h.in: ENH: Separate the notion of a
- request for LFS and its availability. Allow user code to block
- definitions of LFS macros. Added framework to give error if
- sys/types.h is included before this header when LFS is requested
- (currently disabled).
-
-2006-08-25 16:00 king
-
- * Source/kwsys/: CMakeLists.txt, Configure.h.in,
- RequireLargeFilesSupport.cxx, kwsysPlatformCxxTests.cxx: ENH:
- Moved test for large file support into kwsysPlatformCxxTests.cxx
- with name KWSYS_LFS_WORKS.
-
-2006-08-25 15:53 king
-
- * Source/kwsys/: CMakeLists.txt, kwsysPlatformCxxTests.cxx: ENH:
- Switching KWSYS_CHAR_IS_SIGNED test to use
- KWSYS_PLATFORM_CXX_TEST_RUN macro.
-
-2006-08-25 15:50 king
-
- * Source/kwsys/kwsysPlatformCxxTests.cmake: ENH: Added
- KWSYS_PLATFORM_CXX_TEST_RUN macro.
-
-2006-08-25 12:13 king
-
- * Source/kwsys/Glob.cxx: ENH: Globbing patterns should not match a
- slash inside a filename component.
-
-2006-08-25 12:11 king
-
- * Source/cmFileCommand.cxx: BUG: Avoid putting double-slashes in
- fromFile during installation. Also added regex debugging copy of
- the expression in string form.
-
-2006-08-25 09:14 king
-
- * Modules/UseSWIG.cmake: ENH: Added interface to add extra
- dependencies.
-
-2006-08-25 05:35 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-24 14:58 king
-
- * Source/: cmCommandArgumentParser.cxx, cmCommandArgumentParser.y:
- COMP: Added missing include for malloc on QNX.
-
-2006-08-24 10:57 andy
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ENH: Always do tar.Z since we do
- have compress now builtin
-
-2006-08-24 09:47 king
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ENH: Added code to remove any bad
- installations of CVS directories before running the test so that
- one failure does not need manual adjustment to get it to pass
- again.
-
-2006-08-24 09:34 king
-
- * Source/cmStandardLexer.h: COMP: Add missing malloc.h include for
- QNX.
-
-2006-08-24 09:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-23 18:11 alex
-
- * Modules/UseEcos.cmake: ENH: add i386 toolchain and some minor
- improvement of the comments
-
-2006-08-23 12:02 andy
-
- * Source/: cmCommandArgumentLexer.cxx, cmCommandArgumentParser.cxx,
- cmCommandArgumentParser.y, cmDependsJavaLexer.cxx,
- cmExprLexer.cxx: COMP: Attempt to fix aix build
-
-2006-08-23 10:21 martink
-
- * Source/cmIncludeDirectoryCommand.cxx: ENH: fix bad error
- reporting with not found paths
-
-2006-08-23 10:00 andy
-
- * Source/cmStandardIncludes.h: COMP: Add large files support to
- CMake
-
-2006-08-23 09:47 king
-
- * Source/kwsys/Terminal.c: ENH: Added '256color' terminal names.
- Patch applied from bug#3651.
-
-2006-08-23 09:45 king
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: Centralized generation of
- targets listed in the help to be done by the code that actually
- writes the targets.
-
-2006-08-23 09:04 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-23 08:07 andy
-
- * Source/kwsys/CMakeLists.txt: COMP: Support cmake older than 2.4
-
-2006-08-22 18:33 alex
-
- * Modules/UseEcos.cmake: STYLE: don't use the hack to copy and
- rename the created executable under cygwin but instead use the
- SUFFIX target property (I'll publish a short article about
- ecos+cmake RSN)
-
- Alex
-
-2006-08-22 16:07 andy
-
- * Source/CTest/cmCTestBuildHandler.cxx: ENH: Handle more warnings
- properly on AIX
-
-2006-08-22 15:51 andy
-
- * Source/kwsys/CheckCXXSourceRuns.cmake: COMP: On some project
- configure may not copy right away
-
-2006-08-22 15:46 andy
-
- * Source/kwsys/: CMakeLists.txt, CheckCXXSourceRuns.cmake,
- CMakeEmptyInputFile.in: COMP: Add missing cmake file
-
-2006-08-22 15:34 andy
-
- * bootstrap, Source/kwsys/CMakeLists.txt,
- Source/kwsys/Configure.h.in,
- Source/kwsys/RequireLargeFilesSupport.cxx: ENH: Support large
- file systems in kwsys
-
-2006-08-22 10:38 king
-
- * Source/: cmDocumentation.cxx, cmInstallCommand.h: BUG: Fixed man
- page formatting for INSTALL command documentation. Fixed
- line-too-long warning.
-
-2006-08-22 10:16 andy
-
- * Source/: cmListCommand.cxx, cmListCommand.h: BUG: Add missing API
-
-2006-08-22 09:52 andy
-
- * Source/cmListCommand.cxx: BUG: Fix error messages and fix remove
- item to actually remove all instances of the item
-
-2006-08-22 09:20 andy
-
- * Source/CPack/cmCPackTarCompressGenerator.cxx: COMP: Remove
- warnings
-
-2006-08-22 08:58 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-21 22:39 king
-
- * Source/kwsys/Glob.cxx: BUG: Fixed #if test for case-insensitive
- glob on OSX.
-
-2006-08-21 17:52 king
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ENH: Added check for bad
- installation of a CVS directory to test.
-
-2006-08-21 17:47 king
-
- * Source/: cmFileCommand.cxx, cmInstallCommand.cxx: BUG: Directory
- installation pattern matching should be case insensitive on some
- platforms.
-
-2006-08-21 17:37 king
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: BUG: Need to execute
- sample_script.bat on windows and sample_script otherwise.
-
-2006-08-21 17:34 king
-
- * Source/kwsys/SystemTools.cxx: BUG: FileIsDirectory should work
- when the name contains a trailing slash.
-
-2006-08-21 16:55 king
-
- * Source/cmFileCommand.cxx, Source/cmInstallCommand.cxx,
- Source/cmInstallCommand.h,
- Source/cmInstallDirectoryGenerator.cxx,
- Source/cmInstallDirectoryGenerator.h,
- Source/cmInstallGenerator.cxx, Source/cmInstallGenerator.h,
- Source/cmInstallTargetGenerator.cxx,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstall/scripts/sample_script,
- Tests/SimpleInstall/scripts/sample_script.bat,
- Tests/SimpleInstallS2/CMakeLists.txt,
- Tests/SimpleInstallS2/scripts/sample_script,
- Tests/SimpleInstallS2/scripts/sample_script.bat: ENH: Implemented
- INSTALL(DIRECTORY) command and added a test. Re-organized
- cmFileCommand's implementation of FILE(INSTALL) a bit to help
- out. This addresses bug#1694 and partially addresses bug#2691.
-
-2006-08-21 14:17 king
-
- * Source/kwsys/: Glob.cxx, Glob.hxx.in: ENH: Exposed pattern->regex
- API. Cleaned up and commented implementation of pattern->regex
- conversion.
-
-2006-08-21 12:37 andy
-
- * Source/: CMakeLists.txt, CPack/cmCPackTarCompressGenerator.cxx,
- CPack/cmCPackTarCompressGenerator.h: ENH: Implement TarCompress
- generator using compress library
-
-2006-08-21 10:49 king
-
- * Source/cmFileCommand.cxx: BUG: RENAME option should be allowd for
- INSTALL(PROGRAMS) too.
-
-2006-08-21 10:10 hoffman
-
- * Modules/: CheckCSourceCompiles.cmake, CheckCSourceRuns.cmake,
- CheckCXXSourceCompiles.cmake, CheckCXXSourceRuns.cmake: ENH: fixs
- for check compile stuff from Oswald B.
-
-2006-08-21 08:29 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-20 06:53 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-19 06:53 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-18 08:57 king
-
- * Source/: cmAddCustomTargetCommand.h, cmStandardLexer.h: STYLE:
- Fixed line-too-long style errors.
-
-2006-08-18 08:51 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-17 16:40 hoffman
-
- * Source/CMakeLists.txt: ENH: fix project names to be case
- sensitive and change name to linkline from inkline
-
-2006-08-17 15:42 king
-
- * Source/cmFileCommand.cxx: BUG: Bundle installation needs all file
- permissions to be preserved from the build tree.
-
-2006-08-17 15:06 king
-
- * Source/cmAddCustomTargetCommand.h: ENH: Making documentation even
- less ambiguous since some users still think this command can
- generate a file with dependencies.
-
-2006-08-17 14:48 king
-
- * Source/: CMakeLists.txt, cmFileCommand.cxx, cmInstallCommand.cxx,
- cmInstallCommand.h, cmInstallDirectoryGenerator.cxx,
- cmInstallDirectoryGenerator.h, cmInstallFilesGenerator.cxx,
- cmInstallFilesGenerator.h, cmInstallGenerator.cxx,
- cmInstallGenerator.h, cmInstallTargetGenerator.cxx,
- cmInstallTargetGenerator.h: ENH: Started implementing
- INSTALL(DIRECTORY) command mode. This is not yet finished so it
- is undocumented and there is no test. These changes also
- separate the notions of file and directory permissions.
-
-2006-08-17 12:07 king
-
- * Source/cmFileCommand.cxx: ENH: Fix directory installation to
- properly deal with trailing slash names (using the rsync
- convention for whether the last directory name is included in
- naming the destination directory).
-
-2006-08-17 12:04 martink
-
- * Utilities/cmcompress/cmcompress.c: ENH: reorder code to remove
- forward declarations
-
-2006-08-17 12:02 king
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH: Added
- JoinPath overload that accepts an iterator range.
-
-2006-08-17 09:45 king
-
- * Utilities/cmcompress/cmcompress.c: COMP: Fixed linkage specifier
- consistency warning.
-
-2006-08-17 09:36 king
-
- * Modules/InstallRequiredSystemLibraries.cmake: ENH: Implemented
- support for installing VC8 runtime libraries.
-
-2006-08-17 09:35 king
-
- * Utilities/Release/Release.cmake: BUG: Removed code that is now in
- Modules/InstallRequiredSystemLibraries.cmake.
-
-2006-08-17 07:28 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-16 14:22 hoffman
-
- * Source/: cmDependsFortranLexer.cxx, cmDependsFortranLexer.h,
- cmDependsFortranLexer.in.l: ENH: revert change in parser as it
- sent the parser into an infinite loop
-
-2006-08-16 08:12 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-15 15:33 king
-
- * Modules/CMakeVCManifest.cmake, Modules/Platform/Windows-cl.cmake,
- Source/cmLocalVisualStudio7Generator.cxx: ENH: Adding flags to
- force generation of manifest files when building with VC 8.
-
-2006-08-15 15:28 king
-
- * Source/: cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx: BUG: Need to clean manifest
- files that may have been generated for .exe and .dll files.
-
-2006-08-15 12:00 king
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h, cmMakefileTargetGenerator.cxx:
- BUG: Added object language to list of object files in a local
- generator's directory. Fixed generation of preprocessing and
- assembly rules to be done only for C and C++ objects.
-
-2006-08-15 10:56 hoffman
-
- * Source/: cmDependsFortranLexer.cxx, cmDependsFortranLexer.h,
- cmDependsFortranLexer.in.l: ENH: change comment for fortran
- depend parsing
-
-2006-08-15 07:56 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-14 17:30 hoffman
-
- * Utilities/cmcompress/cmcompress.c: ENH: remove c++ comments from
- c code
-
-2006-08-14 17:02 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: do not use OBJROOT or you
- can get two copies of executables
-
-2006-08-14 14:16 andy
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: add newline for
- some versions of make
-
-2006-08-14 11:32 andy
-
- * Utilities/cmcompress/cmcompress.c: COMP: Remove warnings
-
-2006-08-14 10:59 andy
-
- * Utilities/cmcompress/cmcompress.c: COMP: Remove more warnings
-
-2006-08-14 10:51 andy
-
- * Source/: cmMakefileTargetGenerator.cxx,
- CTest/cmCTestScriptHandler.cxx, CTest/cmCTestStartCommand.cxx:
- ENH: fix for no newline on some makes fix for ctest and some
- symlinks
-
-2006-08-14 09:58 andy
-
- * Utilities/cmcompress/: cmcompress.c, cmcompress.h: COMP: Remove
- some warnings and make library report an error instead of call
- exit
-
-2006-08-14 09:50 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: still escape () but do not
- escape
-
-2006-08-14 08:54 andy
-
- * CMakeLists.txt: ENH: Start building compress library
-
-2006-08-14 07:56 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-13 07:52 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-12 07:53 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-11 10:54 martink
-
- * Source/kwsys/SystemTools.cxx: ENH: fix for AddKeepPath not
- calling realpath
-
-2006-08-11 09:56 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: escape ( and ) in unix paths
-
-2006-08-11 07:59 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-10 23:20 hoffman
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ENH: fix error in if statement
-
-2006-08-10 15:17 david.cole
-
- * Source/kwsys/SystemTools.cxx: BUG: strlen logic was backwards
- resulting in function body never actually executing... when
- called with valid strings, it was always doing nothing and
- returning false... now it works as expected.
-
-2006-08-10 11:05 hoffman
-
- * Source/CursesDialog/cmCursesMainForm.cxx: ENH: only change the
- cache if the value was really changed
-
-2006-08-10 09:38 hoffman
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ENH: fix failing tests
-
-2006-08-10 08:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-09 13:59 king
-
- * Modules/Platform/AIX.cmake: ENH: Enabling preprocessed source and
- asembly source generation rules on AIX compilers.
-
-2006-08-09 13:45 king
-
- * Modules/Platform/Windows-cl.cmake: ENH: Enabled generation of
- preprocessed and assembly source rules for MSVC with NMake.
-
-2006-08-09 13:14 king
-
- * Modules/Platform/: IRIX.cmake, IRIX64.cmake: ENH: Enabling
- preprocessed source and asembly source generation rules on SGI
- MIPSpro compilers.
-
-2006-08-09 13:10 king
-
- * Modules/Platform/HP-UX.cmake: ENH: Enabling preprocessed source
- and asembly source generation rules on HP aCC and cc.
-
-2006-08-09 11:48 king
-
- * Modules/Platform/SunOS.cmake: ENH: Enabling preprocessed source
- and asembly source generation rules on Sun CC.
-
-2006-08-09 11:43 king
-
- * Modules/Platform/gcc.cmake,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmMakefileTargetGenerator.cxx: ENH: Changed preprocessed
- source extension to .i and assembly extension to .s for more
- portability.
-
-2006-08-09 11:32 hoffman
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ENH: try to fix compress failure
-
-2006-08-09 09:56 king
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: Added options
- CMAKE_SKIP_PREPROCESSED_SOURCE_RULES and
- CMAKE_SKIP_ASSEMBLY_SOURCE_RULES to allow projects to disable
- generation of .E and .S rules.
-
-2006-08-09 09:45 king
-
- * Source/: cmListFileLexer.c, cmListFileLexer.in.l,
- cmStandardLexer.h: COMP: Fix warnings produced by the change in
- include order from the re-organization of lexer code.
-
-2006-08-09 07:47 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-08 15:55 hoffman
-
- * Source/CTest/cmCTestBuildAndTestHandler.cxx: ENH: add cmake
- output to build and test
-
-2006-08-08 14:00 king
-
- * Source/: cmCommandArgumentLexer.cxx, cmCommandArgumentLexer.in.l,
- cmDependsFortranLexer.cxx, cmDependsFortranLexer.in.l,
- cmDependsJavaLexer.cxx, cmDependsJavaLexer.in.l, cmExprLexer.cxx,
- cmExprLexer.in.l, cmListFileLexer.c, cmListFileLexer.in.l,
- cmStandardLexer.h: COMP: Moved duplicate flex-generated lexer
- warning suppression and cross-platform support code to a single
- cmStandardLexer.h included by all lexer sources. Added fix for
- macro redefinitions on Borland 5.8 compiler.
-
-2006-08-08 13:44 hoffman
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h: ENH: make sure
- RuleVariable struct is initialized correctly, also make sure
- custom command targets do not crash cmake
-
-2006-08-08 13:02 king
-
- * Source/cmMakefileLibraryTargetGenerator.cxx: STYLE: Fixed line
- length.
-
-2006-08-08 11:26 king
-
- * Source/cmLocalVisualStudioGenerator.cxx: BUG: Duplicate object
- name detection should not be case sensitive since this code is
- used on Windows file systems. This addresses bug#3589.
-
-2006-08-08 07:39 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-07 23:25 king
-
- * Modules/Platform/gcc.cmake, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalUnixMakefileGenerator3.h,
- Source/cmMakefileTargetGenerator.cxx: ENH: Added generation of
- rules to manually request preprocessed or generated assembly
- sources.
-
-2006-08-07 17:22 king
-
- * Source/cmake.cxx: ENH: Added undocumented option -E
- cmake_unimplemented_variable to help print useful error messages
- for unimplemented features on a given platform.
-
-2006-08-07 10:10 hoffman
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ENH: finally fix the failing test
- on the dashboard for the past month or so
-
-2006-08-07 08:11 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-06 07:57 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-05 08:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-04 10:35 hoffman
-
- * Utilities/cmtar/CMakeLists.txt: ENH: give up on try run
-
-2006-08-04 08:12 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-03 15:20 hoffman
-
- * Modules/CheckCXXSourceRuns.cmake: ENH: add a try run source code
- macro
-
-2006-08-03 14:38 hoffman
-
- * Modules/CheckCSourceRuns.cmake: ENH: fix error
-
-2006-08-03 14:36 hoffman
-
- * Modules/CheckCSourceRuns.cmake, Utilities/cmtar/CMakeLists.txt:
- ENH: fix for makedev three args test
-
-2006-08-03 13:51 hoffman
-
- * Utilities/cmtar/CMakeLists.txt: ENH: use try run source
-
-2006-08-03 13:41 hoffman
-
- * Utilities/cmtar/CMakeLists.txt: ENH: change to a try run so that
- it will fail on the sun
-
-2006-08-03 13:41 hoffman
-
- * Modules/: CheckCSourceCompiles.cmake, CheckCSourceRuns.cmake:
- ENH: add a crun macro and fix the output log for compile c
-
-2006-08-03 09:42 king
-
- * Source/: cmMakefileLibraryTargetGenerator.cxx,
- cmSetTargetPropertiesCommand.h, cmTarget.cxx: ENH: Added target
- property CLEAN_DIRECT_OUTPUT to not clean all forms of a library
- name so that static and shared libraries of the same name can
- coexist in a single build directory.
-
-2006-08-03 09:26 king
-
- * Source/cmLocalVisualStudioGenerator.cxx,
- Tests/Complex/Executable/A.txt,
- Tests/Complex/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/A.txt,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/A.txt,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt: BUG: Make
- sure sources with unknown extensions are not compiled by VS.
-
-2006-08-03 09:26 king
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: Moved GetSourceFileLanguage
- up to cmLocalGenerator.
-
-2006-08-03 08:11 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-02 21:30 king
-
- * Source/cmInstallTargetGenerator.cxx: STYLE: Fixed long line.
-
-2006-08-02 21:24 hoffman
-
- * Utilities/cmtar/CMakeLists.txt: ENH: use dev_t instead of major_t
- and minor_t
-
-2006-08-02 12:51 david.cole
-
- * Utilities/cmtar/CMakeLists.txt: COMP: libtar should build when
- included in non-CMake projects...
-
-2006-08-02 11:06 king
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: Restoring previous change
- with a fix.
-
-2006-08-02 07:51 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-08-01 19:52 hoffman
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: undo change that broke
- borland 5.6 cont
-
-2006-08-01 16:16 king
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: Moved generation of
- directory-level object convenience rules to a separate method.
- This will aid generation of more such rules later.
-
-2006-08-01 16:01 hoffman
-
- * Utilities/cmtar/CMakeLists.txt: ENH: make cmake build with older
- versions of cmake
-
-2006-08-01 15:48 hoffman
-
- * Modules/FindQt4.cmake: ENH: fix for qtmain
-
-2006-08-01 15:36 king
-
- * Modules/Platform/Linux.cmake,
- Source/cmInstallTargetGenerator.cxx: BUG: Fixed shared library
- version support for Fortran. This addresses bug#3558.
-
-2006-08-01 15:26 hoffman
-
- * Utilities/cmtar/CMakeLists.txt: ENH: add a try compile test for
- makedev_three_args
-
-2006-08-01 15:24 hoffman
-
- * Modules/: CheckCSourceCompiles.cmake, FindQt4.cmake: ENH: fix for
- location of error log
-
-2006-08-01 15:16 glehmann
-
- * Source/kwsys/Directory.cxx: BUG: #3563. Segmentation fault with
- non initialized input or NULL pointers.
-
-2006-08-01 14:45 king
-
- * Source/kwsys/: Registry.cxx, testCommandLineArguments.cxx,
- testCommandLineArguments1.cxx, testSystemTools.cxx: COMP: Added
- missing headers. This partially addresses bug#3556.
-
-2006-08-01 14:34 hoffman
-
- * Modules/FindQt4.cmake: ENH: add QtCored as a possible name for
- qtcore debug
-
-2006-08-01 14:33 king
-
- * Source/cmMakefile.cxx: ENH: Added platform identifier for QNXNTO.
- This partially addresses bug#3556.
-
-2006-08-01 14:31 king
-
- * Source/: cmCPluginAPI.cxx, cmLoadCommandCommand.cxx: COMP: Added
- missing includes. This partially addresses bug#3556.
-
-2006-08-01 14:28 king
-
- * Source/kwsys/ProcessUNIX.c: COMP: Use SA_RESTART only if it is
- defined for the current platform. This partially addresses
- bug#3556.
-
-2006-08-01 14:10 king
-
- * Modules/FindKDE3.cmake: BUG: Fix usage of FIND_PROGRAM command.
-
-2006-08-01 12:27 hoffman
-
- * Modules/: FindQt4.cmake, UseQt4.cmake: ENH: fix for optimized
- debug stuff
-
-2006-08-01 11:38 king
-
- * Source/cmCommandArgumentLexer.cxx,
- Source/cmCommandArgumentLexer.in.l,
- Source/cmCommandArgumentParser.cxx,
- Source/cmCommandArgumentParser.y,
- Source/cmDependsFortranLexer.cxx,
- Source/cmDependsFortranLexer.in.l,
- Source/cmDependsFortranParser.cxx,
- Source/cmDependsFortranParser.y, Source/cmDependsJavaLexer.cxx,
- Source/cmDependsJavaLexer.in.l, Source/cmDependsJavaParser.cxx,
- Source/cmDependsJavaParser.y, Source/cmExprLexer.cxx,
- Source/cmExprLexer.in.l, Source/cmExprParser.cxx,
- Source/cmExprParser.y, Source/cmListFileCache.cxx,
- Source/cmListFileLexer.c, Source/cmListFileLexer.in.l,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmMakefileTargetGenerator.cxx, Source/cmSetCommand.cxx,
- Source/cmStandardIncludes.h, Source/cmTarget.cxx,
- Source/cmWin32ProcessExecution.cxx,
- Source/CTest/cmCTestBuildHandler.cxx,
- Source/kwsys/CommandLineArguments.cxx,
- Source/kwsys/SystemTools.cxx, Source/kwsys/testProcess.c,
- Utilities/cmcurl/CMakeLists.txt, Utilities/cmtar/CMakeLists.txt,
- Utilities/cmzlib/CMakeLists.txt: COMP: Fix and/or disable
- warnings for Borland 5.6 build.
-
-2006-08-01 11:26 hoffman
-
- * Modules/: FindQt4.cmake, UseQt4.cmake: ENH: fix qtmain for
- release
-
-2006-08-01 10:51 hoffman
-
- * Modules/: FindQt4.cmake, UseQt4.cmake: ENH: fix qtmain for
- release
-
-2006-08-01 10:49 king
-
- * Tests/: Complex/Executable/A.cxx, Complex/Executable/A.h,
- Complex/Executable/A.hh, Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/A.cxx,
- ComplexOneConfig/Executable/A.h,
- ComplexOneConfig/Executable/A.hh,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/A.cxx,
- ComplexRelativePaths/Executable/A.h,
- ComplexRelativePaths/Executable/A.hh,
- ComplexRelativePaths/Executable/CMakeLists.txt: ENH: Adding test
- for source files and header files with the same base name in the
- same target.
-
-2006-08-01 10:48 king
-
- * Source/: cmLocalVisualStudioGenerator.cxx,
- cmLocalVisualStudioGenerator.h, cmMakefile.cxx: ENH: Adding .hh
- file as a C++ header file extension. Remove duplicate code from
- implementation of unique object name computation for VS
- generators. This addresses bug#3565.
-
-2006-08-01 09:12 hoffman
-
- * Modules/FindQt4.cmake: ENH: put back find qtmain
-
-2006-08-01 07:42 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-31 16:59 andy
-
- * Utilities/cmcompress/: CMakeLists.txt, cmcompress.c,
- cmcompress.h, compress.c.original: ENH: Initial import
-
-2006-07-31 13:50 martink
-
- * Source/kwsys/: SystemTools.hxx.in, testSystemTools.cxx: ENH:
- better coverage
-
-2006-07-31 11:00 hoffman
-
- * Utilities/Release/cmake_release.sh: ENH: move release branch
-
-2006-07-31 10:28 martink
-
- * Source/CPack/cpack.cxx: ENH: fix line lengths
-
-2006-07-31 07:19 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-30 07:17 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-29 07:21 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-28 14:47 martink
-
- * Source/kwsys/testSystemTools.cxx: BUG: fix some bad code and add
- a couple more tests
-
-2006-07-28 14:20 martink
-
- * Docs/: CMake12p2.rtf, CMake14.rtf, CMake16.rtf: ENH: remove old
- files
-
-2006-07-28 12:00 hoffman
-
- * ChangeLog.manual, Source/cmLocalVisualStudio7Generator.cxx: ENH:
- move stuff from main tree
-
-2006-07-28 11:21 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: fix for 3557
- TargetEnvironment for MIDL Compiler set correctly for 64 bit
-
-2006-07-28 11:13 hoffman
-
- * ChangeLog.manual: ENH: changes on branch
-
-2006-07-28 09:22 andy
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ENH: Add test for bz2 and check
- for compress
-
-2006-07-28 09:14 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: move from main tree
-
-2006-07-28 09:14 andy
-
- * Source/CPack/cpack.cxx: BUG: Bail out on generator initialization
- failure
-
-2006-07-28 08:57 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: move from main tree
-
-2006-07-28 08:19 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-27 15:02 king
-
- * Source/cmGlobalXCodeGenerator.cxx: BUG: Set
- GCC_SYMBOLS_PRIVATE_EXTERN and GCC_INLINES_ARE_PRIVATE_EXTERN
- attributes on all projects to prevent -fvisibility=hidden flags.
- This is needed to make RTTI work by default.
-
-2006-07-27 11:55 andy
-
- * Source/CPack/cpack.cxx: BUG: Fix executing and help
-
-2006-07-27 11:27 king
-
- * Source/kwsys/SystemTools.cxx: BUG: Do not block signals during
- sleep. Leave that up to the application.
-
-2006-07-27 11:26 andy
-
- * Source/CPack/cpack.cxx: BUG: Prevent crash when no input file or
- generator specified
-
-2006-07-27 10:37 hoffman
-
- * ChangeLog.manual, bootstrap,
- Modules/CMakeCommonLanguageInclude.cmake,
- Modules/CMakeTestCCompiler.cmake,
- Modules/Platform/Windows-cl.cmake,
- Source/cmCommandArgumentParserHelper.cxx,
- Source/cmGlobalUnixMakefileGenerator3.cxx, Source/cmMakefile.cxx,
- Source/cmSystemTools.cxx, Source/CTest/cmCTestTestHandler.cxx,
- Tests/LoadCommand/LoadedCommand.cxx,
- Tests/LoadCommand/CMakeCommands/cmTestCommand.c,
- Tests/LoadCommandOneConfig/LoadedCommand.cxx,
- Tests/LoadCommandOneConfig/CMakeCommands/cmTestCommand.c: ENH:
- move changes from main tree to branch
-
-2006-07-27 09:40 king
-
- * Source/CTest/cmCTestHandlerCommand.cxx: BUG: Fix error message
- when handler cannot be created.
-
-2006-07-27 08:10 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-26 14:46 martink
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: BUG: fix comment
-
-2006-07-26 14:10 andy
-
- * bootstrap, Modules/CMakeTestCCompiler.cmake: COMP: More warnings
- and hp issues
-
-2006-07-26 13:19 hoffman
-
- * Modules/CMakeCommonLanguageInclude.cmake: BUG: fix for 3550
- again
-
-2006-07-26 11:46 andy
-
- * bootstrap, Modules/CMakeTestCCompiler.cmake,
- Source/cmCommandArgumentParserHelper.cxx,
- Source/cmIncludeDirectoryCommand.cxx, Source/cmMakefile.cxx,
- Source/cmSystemTools.cxx, Source/CTest/cmCTestTestHandler.cxx:
- COMP: Handle both ansi and non-ansi C
-
-2006-07-26 11:15 hoffman
-
- * Modules/Platform/Windows-cl.cmake: BUG: fix for bug 3550, for
- release builds do not build incremental
-
-2006-07-26 10:11 hoffman
-
- * bootstrap: ENH: put back so it works on hp
-
-2006-07-26 09:11 hoffman
-
- * Tests/: LoadCommand/CMakeCommands/cmTestCommand.c,
- LoadCommandOneConfig/CMakeCommands/cmTestCommand.c: ENH: do not
- use c++ comments in c code
-
-2006-07-26 08:35 hoffman
-
- * CTestCustom.ctest.in, ChangeLog.manual, bootstrap,
- Modules/CMakeImportBuildSettings.cmake,
- Modules/Platform/Windows-cl.cmake,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/kwsys/SystemTools.cxx, Source/kwsys/SystemTools.hxx.in,
- Source/kwsys/testSystemTools.cxx,
- Tests/LoadCommand/CMakeCommands/cmTestCommand.c,
- Tests/LoadCommandOneConfig/CMakeCommands/cmTestCommand.c: ENH:
- move changes from main tree
-
-2006-07-26 07:53 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-25 15:18 king
-
- * Source/kwsys/SystemTools.cxx: BUG: Mask signals during
- SystemTools::Delay to avoid interrupted sleep.
-
-2006-07-25 14:32 martink
-
- * Tests/: LoadCommand/CMakeCommands/cmTestCommand.c,
- LoadCommandOneConfig/CMakeCommands/cmTestCommand.c: BUG: remove
- command causing issues with mid build reruns of cmake on vs70
-
-2006-07-25 14:15 martink
-
- * Source/kwsys/testSystemTools.cxx: COMP: fix compile issue
-
-2006-07-25 12:38 martink
-
- * Tests/: LoadCommand/CMakeCommands/cmTestCommand.c,
- LoadCommandOneConfig/CMakeCommands/cmTestCommand.c: ENH: trying a
- slight change
-
-2006-07-25 12:08 martink
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in,
- testSystemTools.cxx: BUG: some bug fixes, better docs, and more
- coverage
-
-2006-07-25 11:00 andy
-
- * bootstrap: COMP: Remove warning
-
-2006-07-25 10:46 martink
-
- * Tests/: LoadCommand/CMakeCommands/cmTestCommand.c,
- LoadCommandOneConfig/CMakeCommands/cmTestCommand.c: BUG: remove
- c++comments
-
-2006-07-25 10:01 hoffman
-
- * Source/CPack/cmCPackGenerators.cxx: ENH: remove uncompiled header
-
-2006-07-25 08:27 hoffman
-
- * CTestCustom.ctest.in: ENH: try to get rid of clock skew warning
-
-2006-07-25 08:13 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-24 16:58 hoffman
-
- * Modules/CMakeImportBuildSettings.cmake: ENH: fix for case
- difference with nmake
-
-2006-07-24 16:35 martink
-
- * Tests/: LoadCommand/CMakeCommands/cmTestCommand.c,
- LoadCommandOneConfig/CMakeCommands/cmTestCommand.c: BUG: temp fix
-
-2006-07-24 16:13 martink
-
- * Modules/Platform/Windows-cl.cmake: BUG: fix for CXX only projects
-
-2006-07-24 15:40 martink
-
- * Tests/: LoadCommand/CMakeCommands/cmTestCommand.c,
- LoadCommandOneConfig/CMakeCommands/cmTestCommand.c: ENH: add
- more coverage
-
-2006-07-24 11:27 hoffman
-
- * Source/: cmLocalVisualStudio7Generator.cxx,
- kwsys/SystemTools.cxx: ENH: allow for source tree to be in root
- directory
-
-2006-07-24 11:19 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Modules/CMakeFortranCompiler.cmake.in, Modules/CPack.cmake,
- Modules/FindBoost.cmake, Modules/FindKDE4.cmake,
- Modules/FindOpenGL.cmake, Modules/FindwxWidgets.cmake,
- Modules/FindwxWindows.cmake, Modules/Use_wxWindows.cmake,
- Modules/UsewxWidgets.cmake, Modules/readme.txt,
- Source/CMakeLists.txt, Source/cmBuildCommand.cxx,
- Source/cmCTest.cxx, Source/cmFindBase.cxx, Source/cmFindBase.h,
- Source/cmFindLibraryCommand.cxx, Source/cmFindPackageCommand.cxx,
- Source/cmFindPathCommand.cxx, Source/cmFindProgramCommand.cxx,
- Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmGlobalUnixMakefileGenerator3.h,
- Source/cmLocalGenerator.cxx, Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalUnixMakefileGenerator3.h,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio6Generator.h,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h,
- Source/cmLocalVisualStudioGenerator.cxx,
- Source/cmLocalVisualStudioGenerator.h, Source/cmMakefile.cxx,
- Source/cmMakefile.h,
- Source/cmMakefileExecutableTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.h,
- Source/cmSetSourceFilesPropertiesCommand.cxx,
- Source/cmStandardIncludes.h, Source/cmake.cxx,
- Source/CPack/cmCPackGenericGenerator.cxx,
- Source/CPack/cmCPackGenericGenerator.h, Source/CPack/cpack.cxx,
- Source/CTest/cmCTestBuildHandler.cxx,
- Source/CTest/cmCTestConfigureCommand.cxx,
- Source/CTest/cmCTestHandlerCommand.cxx,
- Source/CTest/cmCTestScriptHandler.cxx,
- Source/CTest/cmCTestStartCommand.cxx,
- Source/CTest/cmCTestTestHandler.cxx,
- Source/CTest/cmCTestUpdateCommand.cxx,
- Source/kwsys/CMakeLists.txt,
- Source/kwsys/CommandLineArguments.cxx,
- Source/kwsys/CommandLineArguments.hxx.in, Source/kwsys/Glob.cxx,
- Source/kwsys/ProcessWin32.c, Source/kwsys/Registry.cxx,
- Source/kwsys/SystemTools.cxx, Source/kwsys/Terminal.c,
- Source/kwsys/kwsys_ios_iostream.h.in,
- Source/kwsys/testCommandLineArguments.cxx,
- Source/kwsys/testCommandLineArguments1.cxx,
- Tests/BundleTest/BundleLib.cxx, Tests/BundleTest/CMakeLists.txt,
- Tests/BundleTest/BundleSubDir/CMakeLists.txt,
- Tests/CTestTest/test.cmake.in, Tests/CxxOnly/CMakeLists.txt,
- Tests/CxxOnly/cxxonly.cxx, Tests/CxxOnly/libcxx1.cxx,
- Tests/CxxOnly/libcxx1.h, Tests/CxxOnly/libcxx2.cxx,
- Tests/CxxOnly/libcxx2.h, Tests/LoadCommand/CMakeLists.txt,
- Tests/LoadCommand/LoadedCommand.cxx.in,
- Tests/LoadCommand/CMakeCommands/cmTestCommand.c,
- Tests/LoadCommandOneConfig/CMakeLists.txt,
- Tests/LoadCommandOneConfig/LoadedCommand.cxx.in,
- Tests/LoadCommandOneConfig/CMakeCommands/cmTestCommand.c,
- Tests/OutOfSource/simple.cxx,
- Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt,
- Tests/OutOfSource/OutOfSourceSubdir/simple.cxx,
- Utilities/cmcurl/Testing/ftpget.c,
- Utilities/cmcurl/Testing/ftpgetresp.c,
- Utilities/cmcurl/Testing/ftpupload.c, Utilities/cmtar/block.c,
- Utilities/cmtar/libtar.c, Utilities/cmtar/compat/strlcpy.c,
- Utilities/cmtar/listhash/list.c.in: ENH: move changes from main
- tree to release branch
-
-2006-07-24 09:43 martink
-
- * Tests/CTestTest/test.cmake.in: ENH: more coverage
-
-2006-07-24 08:01 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-23 07:49 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-22 08:11 king
-
- * Modules/CMakeDetermineCXXCompiler.cmake: BUG: CMAKE_AR should be
- advanced.
-
-2006-07-22 08:04 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-21 15:43 king
-
- * Modules/FindwxWidgets.cmake, Modules/FindwxWindows.cmake,
- Modules/Use_wxWindows.cmake, Modules/UsewxWidgets.cmake,
- Source/CMakeLists.txt: ENH: Applying patch from bug#3443 to
- implement FindwxWidgets.cmake properly. It also updates the
- UseWX test and WXDialog sources to use the new find script.
-
-2006-07-21 15:20 king
-
- * Utilities/Release/config_Darwin: ENH: Do not include experimental
- WXDialog in release.
-
-2006-07-21 15:16 king
-
- * Modules/readme.txt: ENH: Added documentation about
- XXX_FIND_COMPONENTS for FIND_PACKAGE.
-
-2006-07-21 14:58 martink
-
- * Source/: cmCTest.cxx, cmake.cxx: ENH: fix color output inside of
- ctest runs
-
-2006-07-21 14:02 martink
-
- * Tests/: LoadCommand/CMakeLists.txt,
- LoadCommand/LoadedCommand.cxx.in,
- LoadCommandOneConfig/CMakeLists.txt,
- LoadCommandOneConfig/LoadedCommand.cxx.in,
- LoadCommand/LoadedCommand.cxx,
- LoadCommandOneConfig/LoadedCommand.cxx,
- LoadCommand/CMakeCommands/cmTestCommand.c,
- LoadCommandOneConfig/CMakeCommands/cmTestCommand.c: BUG: work
- around XCode issue
-
-2006-07-21 13:05 andy
-
- * Source/cmake.cxx: ENH: Cleanup. Replace c-style cast with
- static_cast and replace sprintf with cmOStringStream
-
-2006-07-21 12:04 king
-
- * Modules/FindBoost.cmake: ENH: Adding FindBoost.cmake module from
- Andrew Maclean. This addresses bug#3447.
-
-2006-07-21 11:53 king
-
- * Modules/CMakeDetermineCXXCompiler.cmake, Source/CMakeLists.txt:
- BUG: Fixed building of C++-only projects and added a test.
-
-2006-07-21 11:43 king
-
- * Tests/CxxOnly/: CMakeLists.txt, cxxonly.cxx, libcxx1.cxx,
- libcxx1.h, libcxx2.cxx, libcxx2.h: ENH: Adding C++-only test.
-
-2006-07-21 10:26 martink
-
- * Tests/: CTestTest/test.cmake.in, LoadCommand/CMakeLists.txt,
- LoadCommand/CMakeCommands/cmTestCommand.c,
- LoadCommandOneConfig/CMakeLists.txt,
- LoadCommandOneConfig/CMakeCommands/cmTestCommand.c: ENH: increase
- coverage in a couple places
-
-2006-07-21 08:05 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-20 09:35 king
-
- * Source/kwsys/Terminal.c: BUG: Do not display VT100 escapes inside
- emacs even if TERM is set to xterm.
-
-2006-07-20 08:18 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-19 08:21 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-18 15:21 king
-
- * Source/: cmFindBase.cxx, cmFindBase.h, cmFindLibraryCommand.cxx,
- cmFindPathCommand.cxx, cmFindProgramCommand.cxx: BUG: If the user
- specifies a cache entry on the command line without a type, the
- FIND_* commands should add the type and docstring to the given
- value and put it back in the cache.
-
-2006-07-18 13:16 king
-
- * Modules/readme.txt: STYLE: Added note about singular versus
- plural name for XXX_INCLUDE_DIRS. Added XXX_LIBRARY_DIRS and
- XXX_YY_INCLUDE_DIR conventions.
-
-2006-07-18 13:02 king
-
- * Source/kwsys/kwsys_ios_iostream.h.in: COMP: Fix references to
- cin, cout, cerr, and clog in case of HP aCC compiler with -mt
- flag.
-
-2006-07-18 09:32 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalVisualStudioGenerator.cxx: STYLE: fix long lines
-
-2006-07-18 08:12 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-17 13:34 king
-
- * Source/kwsys/ProcessWin32.c: BUG: When handing the child stdin
- pipe a file, allow another process to be writing to the file at
- the same time. This allows children such as tail -f to function
- properly.
-
-2006-07-17 11:07 martink
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: COMP: fix warning
-
-2006-07-17 09:15 andy
-
- * Source/kwsys/testCommandLineArguments1.cxx: COMP: Only delete
- once
-
-2006-07-17 08:14 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-16 21:11 andy
-
- * Source/kwsys/: testCommandLineArguments.cxx,
- testCommandLineArguments1.cxx: COMP: Remove some warnings
-
-2006-07-16 08:13 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-15 08:21 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-14 15:02 andy
-
- * Source/kwsys/: CMakeLists.txt, CommandLineArguments.cxx,
- CommandLineArguments.hxx.in, testCommandLineArguments.cxx,
- testCommandLineArguments1.cxx: ENH: Add a way to get unused
- arguments and add a test
-
-2006-07-14 13:59 andy
-
- * Source/kwsys/CommandLineArguments.hxx.in: COMP: Remove warning
-
-2006-07-14 13:32 andy
-
- * Source/kwsys/: CommandLineArguments.cxx,
- CommandLineArguments.hxx.in: ENH: It does not really makes sense
- to have Boolean Argument List
-
-2006-07-14 09:13 andy
-
- * Source/kwsys/: CMakeLists.txt, CommandLineArguments.cxx,
- CommandLineArguments.hxx.in, SystemTools.cxx,
- testCommandLineArguments.cxx: ENH: Add support for
- multi-arguments: -f arg1 arg2 arg3 ... and support for lists: -f
- arg1 -f arg2 -f arg3 ... and for boolean to be stored as strings
- and doubles
-
-2006-07-14 08:01 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-13 14:03 martink
-
- * Source/cmMakefileTargetGenerator.cxx: ENH: added progress to
- custom commands with comments
-
-2006-07-13 11:30 andy
-
- * Utilities/cmtar/listhash/list.c.in: COMP: Remove warning
-
-2006-07-13 09:26 andy
-
- * Utilities/cmtar/libtar.c, Utilities/cmtar/compat/strlcpy.c,
- Utilities/cmtar/listhash/list.c.in, Source/cmStandardIncludes.h,
- Source/kwsys/SystemTools.cxx: COMP: Remove warnings
-
-2006-07-13 09:13 andy
-
- * Source/CTest/cmCTestTestHandler.cxx: STYLE: Fix kwstyle
-
-2006-07-13 09:07 andy
-
- * Source/kwsys/Registry.cxx: COMP: Remove warnings
-
-2006-07-13 07:46 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-12 16:30 andy
-
- * Source/CTest/: cmCTestBuildHandler.cxx, cmCTestTestHandler.cxx:
- ENH: Remove debug
-
-2006-07-12 16:21 andy
-
- * Source/kwsys/Registry.cxx: BUG: Fix error conditions
-
-2006-07-12 14:41 martink
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: COMP: fix old compiler
- issue
-
-2006-07-12 14:15 martink
-
- * Source/: cmMakefileTargetGenerator.cxx,
- cmMakefileTargetGenerator.h: BUG: reduce the number of file
- handles kept open
-
-2006-07-12 13:11 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: added progress for subdir
- all targets and fixed compiler waring
-
-2006-07-12 09:21 andy
-
- * Source/CTest/cmCTestTestHandler.cxx: STYLE: Remove debug
-
-2006-07-12 09:20 andy
-
- * Source/kwsys/CommandLineArguments.cxx, Source/kwsys/Glob.cxx,
- Source/kwsys/Registry.cxx, Source/kwsys/SystemTools.cxx,
- Utilities/cmtar/block.c, Utilities/cmtar/libtar.c,
- Utilities/cmtar/compat/strlcpy.c,
- Utilities/cmtar/listhash/list.c.in: COMP: Remove warnings
-
-2006-07-12 08:06 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-11 17:10 king
-
- * Source/cmFindPackageCommand.cxx: ENH: Added creation of
- XXX_FIND_COMPONENTS list of all components requested with
- REQUIRED option. This addresses the feature request in bug#3494.
-
-2006-07-11 16:08 andy
-
- * Source/cmCTest.cxx: COMP: Fix stl string access
-
-2006-07-11 15:58 andy
-
- * Source/: cmCTest.cxx, CTest/cmCTestConfigureCommand.cxx,
- CTest/cmCTestHandlerCommand.cxx, CTest/cmCTestStartCommand.cxx,
- CTest/cmCTestTestHandler.cxx, CTest/cmCTestUpdateCommand.cxx:
- BUG: Try to fix the problem of bad test names
-
-2006-07-11 13:23 king
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio6Generator.h: ENH: Made
- cmLocalVisualStudioGenerator a superclass of
- cmLocalVisualStudio6Generator. Implemented object file unique
- naming when multiple sources share the same name.
-
-2006-07-11 11:41 king
-
- * Source/: CMakeLists.txt, cmLocalGenerator.cxx,
- cmLocalGenerator.h, cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h,
- cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h,
- cmLocalVisualStudioGenerator.cxx, cmLocalVisualStudioGenerator.h:
- ENH: Moved unique object file name computation from
- cmLocalUnixMakefileGenerator3 up to cmLocalGenerator for use by
- all generators. Created cmLocalVisualStudioGenerator as
- superclass for all VS generators. Implemented on-demand unique
- object file name computation for VS 7 generator to avoid slow
- compiles when all sources are in subdirectories.
-
-2006-07-11 11:08 martink
-
- * Source/cmMakefileTargetGenerator.cxx: ENH: fix compile warning
-
-2006-07-11 09:55 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h, cmMakefileTargetGenerator.cxx,
- cmMakefileTargetGenerator.h: BUG: changed to progress to make it
- more flexible and to no relink targets as often
-
-2006-07-11 07:56 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-10 07:59 andy
-
- * Source/CPack/cmCPackGenericGenerator.cxx: COMP: Remove warnings
- and style problems
-
-2006-07-10 07:53 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-10 07:52 andy
-
- * Source/: cmMakefileTargetGenerator.cxx, CPack/cpack.cxx: STYLE:
- Fix some style errors
-
-2006-07-09 13:48 andy
-
- * Utilities/cmcurl/Testing/: ftpget.c, ftpgetresp.c, ftpupload.c:
- COMP: Remove errors
-
-2006-07-09 13:20 andy
-
- * Modules/CPack.cmake, Source/CPack/cmCPackGenericGenerator.cxx,
- Source/CPack/cmCPackGenericGenerator.h, Source/CPack/cpack.cxx:
- ENH: Several cleanups and support for multiple generators
-
-2006-07-09 13:19 andy
-
- * Source/: cmMakefile.cxx, cmMakefile.h: ENH: Add a copy
- constructor to copy the values
-
-2006-07-09 13:18 andy
-
- * Source/: cmBuildCommand.cxx, cmCTest.cxx: ENH: Pass -C flag to
- cmake to generate the apropriate build command
-
-2006-07-09 07:51 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-08 07:56 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-07 13:59 andy
-
- * Source/CTest/cmCTestScriptHandler.cxx: ENH: Be more verbose
-
-2006-07-07 09:54 king
-
- * Tests/OutOfSource/: simple.cxx, OutOfSourceSubdir/CMakeLists.txt,
- OutOfSourceSubdir/simple.cxx: ENH: Adding test for multiple
- source files with the same name but different full paths.
-
-2006-07-07 08:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-06 16:05 andy
-
- * Source/CMakeLists.txt, Tests/BundleTest/CMakeLists.txt,
- Tests/BundleTest/BundleSubDir/CMakeLists.txt: ENH: Improve the
- test to create a bundle in the subdirectory
-
-2006-07-06 16:04 andy
-
- * Source/: cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx,
- cmSetSourceFilesPropertiesCommand.cxx: BUG: Several fixes to
- handle bundle content on Mac OSX
-
-2006-07-06 13:52 andy
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Make the path
- change more localized to bundles only
-
-2006-07-06 11:35 andy
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Revert the change
- 1.152
-
-2006-07-06 07:45 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-05 16:27 andy
-
- * Source/cmLocalUnixMakefileGenerator3.cxx, Source/CMakeLists.txt,
- Tests/BundleTest/BundleLib.cxx, Tests/BundleTest/CMakeLists.txt:
- BUG: If the source file specified is not in a source tree, do not
- use full path to the file
-
-2006-07-05 16:21 andy
-
- * Modules/FindOpenGL.cmake: ENH: On apple do not look for X11
-
-2006-07-05 10:06 king
-
- * Source/kwsys/CMakeLists.txt: ENH: Updated installation options
- and implementation to use INSTALL command if it is available.
- This will allow installation component assignment and separate
- installation of the .dll and .lib on windows.
-
-2006-07-05 08:26 berk
-
- * Source/kwsys/CMakeLists.txt: ENH: Adding cmake 2.4 style
- installation. NOTE: These changes will work on a paraview build
- only. This file has to updated to be general
-
-2006-07-05 07:47 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-04 11:06 andy
-
- * Modules/CMakeFortranCompiler.cmake.in: ENH: Merge debian changes.
- Support more fortran extensions
-
-2006-07-04 08:38 alex
-
- * Modules/FindKDE4.cmake:
- ENH: prefer kde4-config over kde-config, since for KDE 4
- kde-config will be renamed to kde-config, and so cmake has to
- prefer this one over the old version
-
- Alex
-
-2006-07-04 07:55 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-03 07:28 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-02 07:30 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-07-01 07:27 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-06-30 13:51 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: ENH: add EHa option
-
-2006-06-30 13:50 hoffman
-
- * Modules/MacroAddFileDependencies.cmake,
- Tests/CustomCommand/config.h.in: ENH: add files from main tree
-
-2006-06-30 13:48 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, cmake_uninstall.cmake.in,
- Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Modules/CMakeDetermineFortranCompiler.cmake,
- Modules/CMakeDetermineJavaCompiler.cmake,
- Modules/CMakeDetermineRCCompiler.cmake,
- Modules/CMakeDetermineSystem.cmake,
- Modules/CMakeGenericSystem.cmake,
- Modules/CMakeTestCCompiler.cmake,
- Modules/CMakeTestCXXCompiler.cmake,
- Modules/CMakeTestFortranCompiler.cmake, Modules/CPack.cmake,
- Modules/CTest.cmake, Modules/CheckCSourceCompiles.cmake,
- Modules/CheckCXXSourceCompiles.cmake,
- Modules/CheckFunctionExists.cmake, Modules/CheckIncludeFile.c.in,
- Modules/CheckIncludeFile.cmake,
- Modules/CheckIncludeFileCXX.cmake,
- Modules/CheckIncludeFiles.cmake,
- Modules/CheckLibraryExists.cmake,
- Modules/CheckSymbolExists.cmake, Modules/CheckTypeSize.cmake,
- Modules/CheckVariableExists.cmake, Modules/FindOpenGL.cmake,
- Modules/FindQt4.cmake, Modules/FindSDL_sound.cmake,
- Modules/FindThreads.cmake, Modules/FindVTK.cmake,
- Modules/FindZLIB.cmake, Modules/KDE3Macros.cmake,
- Modules/TestBigEndian.cmake, Modules/TestCXXAcceptsFlag.cmake,
- Modules/TestForANSIForScope.cmake, Modules/TestForSSTREAM.cmake,
- Modules/TestForSTDNamespace.cmake, Modules/kde3uic.cmake,
- Modules/Platform/Windows-cl.cmake,
- Source/cmAddCustomCommandCommand.h,
- Source/cmAddCustomTargetCommand.h,
- Source/cmAddSubDirectoryCommand.cxx, Source/cmBuildCommand.cxx,
- Source/cmCacheManager.cxx, Source/cmDepends.cxx,
- Source/cmDepends.h, Source/cmDependsC.cxx,
- Source/cmFileCommand.cxx, Source/cmFileCommand.h,
- Source/cmForEachCommand.cxx, Source/cmForEachCommand.h,
- Source/cmGlobalBorlandMakefileGenerator.cxx,
- Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmGlobalKdevelopGenerator.cxx,
- Source/cmGlobalMSYSMakefileGenerator.cxx,
- Source/cmGlobalMinGWMakefileGenerator.cxx,
- Source/cmGlobalNMakeMakefileGenerator.cxx,
- Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmGlobalUnixMakefileGenerator3.h,
- Source/cmGlobalVisualStudio6Generator.cxx,
- Source/cmGlobalVisualStudio6Generator.h,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.h,
- Source/cmGlobalXCodeGenerator.cxx,
- Source/cmGlobalXCodeGenerator.h, Source/cmIfCommand.cxx,
- Source/cmIfCommand.h, Source/cmInstallTargetGenerator.cxx,
- Source/cmLocalGenerator.cxx, Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalUnixMakefileGenerator3.h,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmMacroCommand.cxx, Source/cmMacroCommand.h,
- Source/cmMakefile.cxx, Source/cmMakefile.h,
- Source/cmMakefileExecutableTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.h,
- Source/cmMakefileUtilityTargetGenerator.cxx,
- Source/cmMessageCommand.cxx,
- Source/cmSetTargetPropertiesCommand.h, Source/cmTarget.cxx,
- Source/cmTarget.h, Source/cmTryCompileCommand.cxx,
- Source/cmTryRunCommand.cxx, Source/cmWhileCommand.cxx,
- Source/cmWhileCommand.h, Source/cmake.cxx, Source/cmake.h,
- Source/cmakemain.cxx, Source/CPack/cmCPackGenericGenerator.cxx,
- Source/CPack/cmCPackGenericGenerator.h,
- Source/CTest/cmCTestBuildAndTestHandler.cxx,
- Source/CTest/cmCTestBuildCommand.cxx,
- Source/CursesDialog/form/form.priv.h,
- Source/kwsys/CommandLineArguments.cxx,
- Source/kwsys/Directory.cxx, Source/kwsys/Directory.hxx.in,
- Source/kwsys/Process.h.in, Source/kwsys/ProcessUNIX.c,
- Source/kwsys/ProcessWin32.c, Source/kwsys/Terminal.c,
- Source/kwsys/kwsysPlatformCxxTests.cmake,
- Source/kwsys/testProcess.c,
- Tests/Complex/Executable/CMakeLists.txt,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/complex.cxx,
- Tests/CustomCommand/CMakeLists.txt, Tests/CustomCommand/foo.in,
- Tests/MakeClean/ToClean/CMakeLists.txt,
- Tests/TryCompile/CMakeLists.txt, Tests/Wrapping/Wrap.c,
- Tests/Wrapping/fakefluid.cxx, Utilities/cmcurl/CMakeLists.txt,
- Utilities/cmcurl/mprintf.c,
- Utilities/cmcurl/CMake/CheckTypeSize.cmake,
- Utilities/cmtar/CMakeLists.txt, Utilities/cmtar/append.c,
- Utilities/cmtar/config.h.in, Utilities/cmtar/extract.c,
- Utilities/cmtar/handle.c, Utilities/cmtar/compat/fnmatch.c: ENH:
- merge main tree into branch
-
-2006-06-30 07:16 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-06-29 07:10 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-06-28 17:00 king
-
- * Modules/: CheckCSourceCompiles.cmake,
- CheckCXXSourceCompiles.cmake: BUG: Make sure try-compile source
- ends in a newline.
-
-2006-06-28 16:16 hoffman
-
- * Source/CPack/cmCPackGenericGenerator.cxx: ENH: remove cerr output
-
-2006-06-28 15:15 martink
-
- * Modules/CTest.cmake: BUG: fix typo
-
-2006-06-28 07:21 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-06-27 14:26 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: COMP: warning fix
-
-2006-06-27 10:24 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: fix for subdir all
- target after control c
-
-2006-06-27 09:57 hoffman
-
- * Source/CursesDialog/form/form.priv.h: ENH: fix ia64 build with
- aCC
-
-2006-06-27 09:56 hoffman
-
- * Source/cmFileCommand.cxx: ENH: fix crash when glob has wrong
- number of arguments
-
-2006-06-27 07:11 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-06-26 15:27 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: When using a
- working directory for the custom command do not convert paths to
- be relative to the build directory.
-
-2006-06-26 12:06 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: fix for bug 3444,
- remove trailing . in lib names
-
-2006-06-26 11:27 martink
-
- * Source/cmMakefile.cxx: ENH: fix subdir issue
-
-2006-06-26 10:57 king
-
- * Source/cmIfCommand.h: ENH: Clarified documentation of EXISTS and
- IS_DIRECTORY modes.
-
-2006-06-26 09:46 king
-
- * Utilities/Release/README: BUG: Added missing release steps.
-
-2006-06-26 07:15 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-06-25 15:18 karthik
-
- * Source/kwsys/CommandLineArguments.cxx: BUG: The operator
- precedence is [] followed by *. Calling this method was causing
- out of array index segfaults bounds
-
-2006-06-25 07:14 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-06-24 07:19 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-06-23 07:08 andy
-
- * Modules/CTest.cmake: ENH: Default drop method http
-
-2006-06-22 15:37 andy
-
- * Source/cmMessageCommand.cxx: ENH: Use CMake's error reporting
- mechanism
-
-2006-06-22 15:31 andy
-
- * Source/: cmMakefile.cxx, cmMakefile.h: ENH: DIsplay the list file
- stack when displaying errors
-
-2006-06-22 10:35 martink
-
- * Source/: cmake.cxx, kwsys/Directory.cxx, kwsys/Directory.hxx.in:
- ENH: add a higher performance method to get the number of files
- in a directory
-
-2006-06-22 08:01 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-06-21 07:56 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-06-20 13:13 hoffman
-
- * Source/cmake.cxx: ENH: avoid crash in sprintf
-
-2006-06-20 09:50 martink
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: ENH: fix line length
- and warning
-
-2006-06-19 14:57 king
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h: BUG: Delay
- relative path configuration until as late as possible to make
- sure the source/binary dir are set. This is a work-around for
- lack of a more structured way of creating the global generator.
-
-2006-06-19 11:34 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h: ENH: fix for dependent targets
-
-2006-06-19 10:07 king
-
- * Modules/FindOpenGL.cmake: ENH: Do not search for X11 if it is
- already found.
-
-2006-06-19 09:49 king
-
- * Source/kwsys/ProcessWin32.c: COMP: Fix conversion warning.
-
-2006-06-18 20:05 hoffman
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: ENH: do not use the
- link script on windows
-
-2006-06-18 11:50 king
-
- * Source/cmMakefileLibraryTargetGenerator.cxx: BUG: Do not write
- link script lines that use the ':' command which is supposed to
- be a no-op anyway.
-
-2006-06-18 09:23 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-06-17 19:32 king
-
- * Source/cmMakefileLibraryTargetGenerator.cxx: BUG: Need to use
- different link script name when relinking.
-
-2006-06-17 07:55 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-06-16 16:29 martink
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: ENH: warning fix
-
-2006-06-16 15:29 martink
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: ENH: cleanup how
- progress is reported for individual targets to fix an integer
- math issue
-
-2006-06-16 14:45 andy
-
- * Modules/: FindQt4.cmake, MacroAddFileDependencies.cmake: ENH:
- Updates from KDE
-
-2006-06-16 14:19 martink
-
- * Source/cmSetTargetPropertiesCommand.h: ENH: fix line length
-
-2006-06-16 14:02 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: BUG: fix for bug 3417
-
-2006-06-16 07:44 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-06-15 21:43 hoffman
-
- * Modules/CPack.cmake: ENH: add a comment
-
-2006-06-15 16:42 king
-
- * Source/cmMakefile.cxx: ENH: Provide access to CMAKE_PATCH_VERSION
- in CMake code.
-
-2006-06-15 16:37 king
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: BUG: Pre-install rules
- for a target should not have target-level dependencies. Each
- target can be re-linked independently as long as the original
- targets are up to date.
-
-2006-06-15 16:17 king
-
- * Source/: cmGlobalBorlandMakefileGenerator.cxx,
- cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalMSYSMakefileGenerator.cxx,
- cmGlobalMinGWMakefileGenerator.cxx,
- cmGlobalNMakeMakefileGenerator.cxx,
- cmGlobalUnixMakefileGenerator3.cxx,
- cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx, cmMakefileTargetGenerator.h,
- cmake.cxx, cmake.h: ENH: Added generation of link rules into
- script files executed by a cmake -E command in order to support
- longer link lines. This is needed only on platforms without
- response file support and that may have weak shells.
-
-2006-06-15 14:40 king
-
- * Source/kwsys/: Process.h.in, ProcessUNIX.c, ProcessWin32.c: ENH:
- Added Option_Verbatim to run whole command lines directly.
-
-2006-06-15 11:51 martink
-
- * Source/: cmGlobalKdevelopGenerator.cxx,
- cmLocalUnixMakefileGenerator3.cxx, cmake.h: ENH: fix linelength
-
-2006-06-15 10:51 king
-
- * Source/: cmAddCustomCommandCommand.h, cmAddCustomTargetCommand.h:
- BUG: Clarified documentation about custom command outputs and
- custom target dependencies.
-
-2006-06-15 10:24 king
-
- * Source/cmMakefile.cxx: ENH: Unknown command invocations should be
- fatal errors.
-
-2006-06-15 10:12 king
-
- * Source/: cmLocalGenerator.cxx, cmSetTargetPropertiesCommand.h,
- cmTarget.cxx: ENH: Added target property
- INSTALL_RPATH_USE_LINK_PATH to append the linker search path
- directories not inside the project to the INSTALL_RPATH
- automatically. The property is initialized by the variable
- CMAKE_INSTALL_RPATH_USE_LINK_PATH when the target is created.
-
-2006-06-15 09:45 king
-
- * Source/cmake.cxx: BUG: Always check dependency integrity whether
- or not CMake will re-run because the generator no longer checks
- integrity during generation.
-
-2006-06-15 07:47 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-06-14 13:41 hoffman
-
- * DartConfig.cmake: ENH: handle the fact the public can no longer
- do ftp
-
-2006-06-14 12:28 martink
-
- * CMakeLists.txt, Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Modules/CMakeDetermineFortranCompiler.cmake,
- Modules/CMakeDetermineJavaCompiler.cmake,
- Modules/CMakeDetermineRCCompiler.cmake,
- Modules/CMakeDetermineSystem.cmake,
- Modules/CMakeTestCCompiler.cmake,
- Modules/CMakeTestCXXCompiler.cmake,
- Modules/CMakeTestFortranCompiler.cmake,
- Modules/CheckCSourceCompiles.cmake,
- Modules/CheckCXXSourceCompiles.cmake,
- Modules/CheckFunctionExists.cmake,
- Modules/CheckIncludeFile.cmake,
- Modules/CheckIncludeFileCXX.cmake,
- Modules/CheckIncludeFiles.cmake,
- Modules/CheckLibraryExists.cmake,
- Modules/CheckSymbolExists.cmake, Modules/CheckTypeSize.cmake,
- Modules/CheckVariableExists.cmake, Modules/FindQt4.cmake,
- Modules/FindSDL_sound.cmake, Modules/FindThreads.cmake,
- Modules/TestBigEndian.cmake, Modules/TestCXXAcceptsFlag.cmake,
- Modules/TestForANSIForScope.cmake, Modules/TestForSSTREAM.cmake,
- Modules/TestForSTDNamespace.cmake,
- Modules/Platform/Windows-cl.cmake, Source/cmCacheManager.cxx,
- Source/cmGlobalGenerator.cxx,
- Source/cmGlobalKdevelopGenerator.cxx,
- Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmGlobalXCodeGenerator.cxx,
- Source/cmInstallTargetGenerator.cxx, Source/cmLocalGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator3.cxx, Source/cmMakefile.cxx,
- Source/cmMakefileExecutableTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.cxx,
- Source/cmTryCompileCommand.cxx, Source/cmTryRunCommand.cxx,
- Source/cmake.h, Source/kwsys/kwsysPlatformCxxTests.cmake,
- Tests/MakeClean/ToClean/CMakeLists.txt,
- Tests/TryCompile/CMakeLists.txt, Utilities/cmcurl/CMakeLists.txt,
- Utilities/cmcurl/CMake/CheckTypeSize.cmake: ENH: centralized
- locaiton of CMakeFiles setting
-
-2006-06-13 10:28 martink
-
- * CMake.pdf, CMake.rtf: ENH: removed old out of date files, online
- and command line help is better
-
-2006-06-13 09:46 martink
-
- * Source/cmLocalVisualStudio7Generator.cxx: ENH: fix line length
-
-2006-06-13 08:04 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-06-12 15:44 martink
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx,
- cmLocalVisualStudio7Generator.cxx: ENH: fix line length
-
-2006-06-12 14:21 andy
-
- * Modules/CPack.cmake: ENH: Add support for overwriting the name of
- the file CPackConfig.cmake and CPackSourceConfig.cmake
-
-2006-06-12 13:17 martink
-
- * Modules/Platform/Windows-cl.cmake: ENH: removed logo info from
- the manifest tool
-
-2006-06-12 13:05 king
-
- * Source/cmIfCommand.h: BUG: Patch from Miguel A.
- Figueroa-Villanueva for fixing documentation.
-
-2006-06-12 12:18 martink
-
- * Source/cmMakefileTargetGenerator.cxx: ENH: cleanup
-
-2006-06-12 11:40 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmMakefileTargetGenerator.cxx, cmake.cxx: ENH: some cleanup to
- progress
-
-2006-06-12 10:22 andy
-
- * DartConfig.cmake: ENH: Switch to http submission
-
-2006-06-12 07:59 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-06-11 07:58 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-06-10 08:12 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-06-09 15:49 alex
-
- * Modules/FindZLIB.cmake: BUG: don't append to ZLIB_NAMES ENH: also
- check for zdll on windows ENH: honor REQUIRED and QUIETLY
-
- Alex
-
-2006-06-09 13:45 hoffman
-
- * Source/CPack/: bills-comments.txt,
- cmCPackCygwinBinaryGenerator.cxx, cmCPackCygwinBinaryGenerator.h,
- cmCPackGenerators.cxx, cmCPackGenericGenerator.cxx,
- cmCPackGenericGenerator.h, cygwin.readme: ENH: check in partial
- cygwin generator
-
-2006-06-09 08:28 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-06-08 07:49 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-06-07 08:47 hoffman
-
- * Source/cmakemain.cxx: ENH: add docs for debug trycompile
-
-2006-06-06 12:01 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: ENH: fix /TP for c code
-
-2006-06-06 09:39 hoffman
-
- * Source/cmMakefile.cxx: ENH: fix for replacement of @var @ only
- legal variable names should be replaced
-
-2006-06-06 07:59 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-06-05 15:28 king
-
- * Source/cmAddSubDirectoryCommand.cxx: COMP: Removed unused
- variable.
-
-2006-06-05 14:38 king
-
- * Source/cmAddSubDirectoryCommand.cxx: BUG: Always check whether a
- subdirectory is below the top of the source before computing the
- binary tree automatically. Even when the source is a relative
- path it may contain ../ which would allow it to be outside the
- source tree.
-
-2006-06-05 14:32 martink
-
- * Source/: cmDependsC.cxx, cmGlobalUnixMakefileGenerator3.cxx,
- cmMakefileTargetGenerator.cxx: ENH: line lengths
-
-2006-06-05 14:13 king
-
- * cmake_uninstall.cmake.in: BUG: Use proper signature for
- EXEC_PROGRAM to get return value of cmake -E remove. Also fixed
- spelling error in message, and made non-existing files not a
- fatal error so that the rest of the files are removed.
-
-2006-06-05 13:45 king
-
- * Source/: cmFileCommand.cxx, cmFileCommand.h, cmTarget.cxx: ENH:
- Changing shared library versioned file names on OSX to conform to
- that platform's convention.
-
-2006-06-05 11:22 king
-
- * Source/kwsys/Terminal.c: ENH: Added rxvt-unicode and cygwin
- terminals for color support.
-
-2006-06-05 07:25 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-06-04 07:22 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-06-03 18:43 andy
-
- * Source/kwsys/Terminal.c: ENH: Handle 'screen' terminal. Thank you
- Thomas Z.
-
-2006-06-03 18:43 andy
-
- * Source/CPack/cmCPackGenericGenerator.cxx: COMP: Remove warning
-
-2006-06-03 09:48 king
-
- * Tests/Wrapping/Wrap.c: COMP: More fixes for non-ANSI C compilers.
-
-2006-06-03 09:42 king
-
- * Tests/Wrapping/Wrap.c: COMP: Fix for non-ANSI C compilers.
-
-2006-06-03 07:22 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-06-02 12:19 king
-
- * Tests/Wrapping/: Wrap.c, fakefluid.cxx: BUG: Custom commands
- should actually generate the files they claim to generate.
-
-2006-06-02 11:26 andy
-
- * Source/CPack/: cmCPackGenericGenerator.cxx,
- cmCPackGenericGenerator.h: ENH: Display cmake install information
- when in verbose mode
-
-2006-06-01 15:51 king
-
- * Source/: cmBuildCommand.cxx, cmGlobalGenerator.cxx,
- cmGlobalGenerator.h, cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio6Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h, cmGlobalXCodeGenerator.cxx,
- cmGlobalXCodeGenerator.h, CPack/cmCPackGenericGenerator.cxx,
- CTest/cmCTestBuildAndTestHandler.cxx,
- CTest/cmCTestBuildCommand.cxx: BUG: cmGlobalGenerator::Build
- should not always use the /fast target name because dependency
- checking is often required. It now takes an argument specifying
- whether to use the /fast target name, and the argument is
- currently only true for try-compiles.
-
-2006-06-01 15:08 king
-
- * Source/cmInstallTargetGenerator.cxx: BUG: Adjustment of
- install_name with install_name_tool should account for DESTDIR
- when specifying the file to be changed.
-
-2006-06-01 14:43 king
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.cxx: ENH: Moved generation of the
- /fast version of GLOBAL_TARGET targets to the proper place in the
- local generator instead of in the global generator. Also made
- the install/fast target not depend on the all target.
-
-2006-06-01 14:09 king
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.cxx: BUG: Added /fast targets in
- subdirectory makefiles. Removed bogus INSTALL_*/fast targets.
- Also fixed preinstall/fast target.
-
-2006-06-01 13:01 king
-
- * Tests/CustomCommand/: CMakeLists.txt, config.h.in, foo.in: ENH:
- Added test for generation of files listed explicitly as sources
- but not used during the build of a target.
-
-2006-06-01 11:45 king
-
- * Source/: cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx, cmMakefileTargetGenerator.h,
- cmMakefileUtilityTargetGenerator.cxx: BUG: Custom command outputs
- listed explicitly as source files in a target should be generated
- whether or not an object file in the target needs them. This
- useful and makes Makefile builds more consistent with VS IDE
- builds.
-
-2006-06-01 09:38 hoffman
-
- * Utilities/Release/cmake_release.sh: ENH: change the version
- number to match the release for cygwin
-
-2006-06-01 08:17 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-31 11:19 martink
-
- * Source/: cmForEachCommand.cxx, cmIfCommand.cxx,
- cmMacroCommand.cxx, cmWhileCommand.cxx: ENH: reduce string
- construct delete ops
-
-2006-05-31 08:10 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-30 16:23 king
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.cxx: BUG: Fix progress when total
- number of source files is less than 100.
-
-2006-05-30 11:15 king
-
- * Source/cmake.cxx: BUG: Fixed cmake -E remove return code.
-
-2006-05-30 08:03 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-29 08:09 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-28 07:29 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-27 07:45 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-26 07:32 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-25 14:16 king
-
- * Modules/CMakeGenericSystem.cmake: ENH: Adding advanced option
- CMAKE_COLOR_MAKEFILE for makefile generators with default ON.
-
-2006-05-25 14:16 king
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: Slight improvement in
- genreation time by recording the setting of CMAKE_COLOR_MAKEFILE
- in an ivar of each local generator at the beginning of
- generation. This avoids many repeated table lookups.
-
-2006-05-25 11:56 hoffman
-
- * Modules/FindQt4.cmake: ENH: add qtmain to findqt
-
-2006-05-25 10:55 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h,
- cmLocalUnixMakefileGenerator3.cxx: BUG: fix to progress for small
- projects
-
-2006-05-25 10:21 martink
-
- * Modules/CTest.cmake: ENH: remove debugging output
-
-2006-05-25 09:47 king
-
- * Source/: cmDepends.cxx, cmDepends.h, cmDependsC.cxx,
- cmGlobalGenerator.cxx, cmGlobalGenerator.h, cmLocalGenerator.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h, cmMakefileTargetGenerator.cxx,
- cmake.cxx: BUG: Updated Makefile dependency scanning to provide a
- full local generator to the dependency scanner to do proper path
- conversions. This allows the rules written into the depend.make
- files to use the same relative path conversion as those written
- into the build.make files. Several previous changes added more
- and more information for use by the dependency scanner and it was
- converging to having the full local generator anyway.
-
-2006-05-25 07:34 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-24 10:13 king
-
- * Source/kwsys/ProcessUNIX.c: BUG: Do not leak global table of
- processes.
-
-2006-05-24 10:09 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h: ENH: fix compiler warnings and
- posibly java test
-
-2006-05-24 07:36 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-23 15:27 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: COMP: Added missing
- include for isspace.
-
-2006-05-23 15:01 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: Fix parsing of
- definitions to support REMOVE_DEFINITIONS.
-
-2006-05-23 12:51 king
-
- * Source/cmMakefile.cxx, Tests/Complex/Executable/CMakeLists.txt,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/complex.cxx: BUG: Fix
- REMOVE_DEFINITIONS command to not remove substrings.
-
-2006-05-23 12:38 david.cole
-
- * Utilities/cmtar/: CMakeLists.txt, append.c, config.h.in,
- extract.c, handle.c, compat/fnmatch.c: COMP: Fix warnings on
- Borland dashboards...
-
-2006-05-23 11:48 king
-
- * Source/kwsys/ProcessUNIX.c: ENH: Re-enabling SIGCHLD handling
- implementation with a fix for Cygwin.
-
-2006-05-23 10:40 king
-
- * Modules/FindVTK.cmake: ENH: Add ability to find VTK 5 without
- user help.
-
-2006-05-23 09:58 king
-
- * Source/cmMakefileExecutableTargetGenerator.cxx: BUG: Finished fix
- to bug#3229 and bug#3272.
-
-2006-05-23 09:58 king
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.cxx, cmMakefileTargetGenerator.cxx:
- BUG: Fix for spaces in path to build directory with new progress
- stuff.
-
-2006-05-23 09:11 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h, cmMacroCommand.cxx,
- cmMacroCommand.h, cmMakefileTargetGenerator.cxx, cmake.cxx: ENH:
- always compile progress
-
-2006-05-23 07:40 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-22 16:10 martink
-
- * Source/cmake.cxx: COMP: fix bootstrap
-
-2006-05-22 16:07 martink
-
- * Source/cmake.cxx: COMP: fix mac warning
-
-2006-05-22 15:41 martink
-
- * Source/cmake.cxx: ENH: part of the progress reporting checkin
-
-2006-05-22 15:11 king
-
- * Source/kwsys/ProcessUNIX.c: BUG: Reverting previous change until
- it can be fixed on Cygwin.
-
-2006-05-21 14:06 hoffman
-
- * Source/cmMakefile.cxx: ENH: fix line length
-
-2006-05-21 10:28 king
-
- * Source/kwsys/testProcess.c: ENH: Added test 8 to test
- grandchildren running after children exit.
-
-2006-05-21 10:27 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-21 10:27 king
-
- * Source/kwsys/ProcessWin32.c: BUG: Fixed deadlock condition when
- grandchildren are running after the children exit.
-
-2006-05-21 10:26 king
-
- * Source/kwsys/ProcessUNIX.c: ENH: Implemented handling of SIGCHLD
- to detect the termination of immediate children. This allows
- grandchildren to remain running after the children exit.
-
-2006-05-20 18:50 king
-
- * Source/kwsys/ProcessUNIX.c: ENH: Enabling process tree killing on
- Cygwin.
-
-2006-05-20 08:06 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-19 16:57 alex
-
- * Modules/: FindQt4.cmake, KDE3Macros.cmake, kde3uic.cmake: BUG:
- kde3: use QT_UIC_EXECUTABLE instead of simply uic BUG: use
- qouting for the path to Qt4 moc and uic, should help with paths
- with spaces
-
- Alex
-
-2006-05-19 15:53 hoffman
-
- * Utilities/Release/: create-cmake-release.cmake,
- dashmacmini2_release.cmake: ENH: release scripts
-
-2006-05-19 15:51 hoffman
-
- * Utilities/cmcurl/mprintf.c: ENH: fix for uclibc
-
-2006-05-19 13:02 hoffman
-
- * Source/: cmMakefile.cxx, cmTarget.cxx, cmTarget.h: ENH: fix for
- vtk 4.4 and other projects that may try to link to a module
-
-2006-05-19 09:36 martink
-
- * Source/cmIfCommand.cxx: COMP: fix warning
-
-2006-05-19 08:15 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-18 23:24 hoffman
-
- * Source/: cmake.cxx, cmakemain.cxx: ENH: fix crashes when command
- line arguments are not followed by the correct number of
- arguments
-
-2006-05-18 14:35 martink
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: BUG: fix issue with
- too many fast targets being listed
-
-2006-05-18 13:50 martink
-
- * Source/: cmForEachCommand.cxx, cmForEachCommand.h,
- cmIfCommand.cxx, cmWhileCommand.cxx, cmWhileCommand.h: ENH: allow
- loose loop constructs
-
-2006-05-18 10:28 king
-
- * Modules/CheckIncludeFile.c.in: BUG: Fix signature of main to work
- on both strict ANSI and non-ANSI C compilers.
-
-2006-05-18 08:00 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-17 08:07 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-16 14:04 hoffman
-
- * ChangeLog.manual, Source/cmGlobalXCodeGenerator.cxx,
- Source/cmGlobalXCodeGenerator.h, Source/cmListCommand.cxx,
- Source/cmListCommand.h, Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmMakefileExecutableTargetGenerator.cxx: ENH: move changes
- from main tree to branch
-
-2006-05-16 13:41 king
-
- * Source/cmMakefileExecutableTargetGenerator.cxx: BUG: Added
- missing cd command before running executable version symlink
- rule. This addresses bug#3229.
-
-2006-05-16 13:23 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: fix warning
-
-2006-05-16 09:54 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h:
- ENH: fix rebuild problem with xcode and universal binaries
-
-2006-05-16 08:42 andy
-
- * Source/: cmListCommand.cxx, cmListCommand.h: STYLE: Fix style
-
-2006-05-16 08:03 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-15 18:05 hoffman
-
- * ChangeLog.manual, Source/cmDependsFortranParser.h,
- Source/cmDependsJavaParser.cxx, Source/cmExprParser.cxx,
- Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmListCommand.cxx, Source/cmListCommand.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmQTWrapCPPCommand.h, Source/cmake.cxx,
- Tests/CMakeTests/ListTest.cmake.in: ENH: merge from main tree
-
-2006-05-15 13:47 martink
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: PERF: performance
- improvement
-
-2006-05-15 13:02 andy
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.cxx, cmake.cxx: ENH: Add simple
- progress reporting during make
-
-2006-05-15 10:19 martink
-
- * Source/: cmDependsFortranParser.h, cmDependsJavaParser.cxx,
- cmExprParser.cxx, cmLocalUnixMakefileGenerator3.cxx,
- cmQTWrapCPPCommand.h: STYLE: fix line length
-
-2006-05-15 10:14 andy
-
- * Source/cmListCommand.cxx, Tests/CMakeTests/ListTest.cmake.in:
- ENH: Fix INSERT to allow inserting to empty list
-
-2006-05-15 09:57 andy
-
- * Source/cmListCommand.cxx, Source/cmListCommand.h,
- Tests/CMakeTests/ListTest.cmake.in: ENH: Change REMOVE and
- REMOVE_ITEM to REMOVE_AT and REMOVE_ITEM
-
-2006-05-15 09:25 andy
-
- * Source/cmListCommand.cxx, Source/cmListCommand.h,
- Tests/CMakeTests/ListTest.cmake.in: ENH: Remove some errors, fix
- append to work on nonexisting lists
-
-2006-05-14 20:20 hoffman
-
- * Modules/CMakeDetermineSystem.cmake: ENH: fix module
-
-2006-05-14 20:17 hoffman
-
- * Modules/CMakeDetermineSystem.cmake: ENH: check return value for
- uname -p
-
-2006-05-14 19:17 hoffman
-
- * Modules/CMakeDetermineSystem.cmake: ENH: move from main tree
- handle uname without -p correctly
-
-2006-05-14 17:42 hoffman
-
- * Modules/CMakeDetermineSystem.cmake: ENH: check return value for
- uname -p
-
-2006-05-14 15:24 hoffman
-
- * Utilities/Release/: release_cmake.cmake,
- v60n177_aix_release.cmake: ENH: extra path
-
-2006-05-14 15:22 hoffman
-
- * CMakeLists.txt, Modules/FindJPEG.cmake, Modules/FindKDE4.cmake,
- Modules/FindQt4.cmake, Source/cmGlobalGenerator.cxx,
- Source/cmGlobalMSYSMakefileGenerator.h,
- Source/cmIncludeDirectoryCommand.cxx,
- Source/cmLinkDirectoriesCommand.cxx,
- Source/cmLinkLibrariesCommand.cxx, Source/cmListCommand.cxx,
- Source/cmListFileCache.cxx, Source/cmLoadCacheCommand.cxx,
- Source/cmLoadCommandCommand.h, Source/cmLocalGenerator.cxx,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h,
- Source/cmMacroCommand.cxx, Source/cmMakeDepend.h,
- Source/cmMakefile.cxx, Source/cmMakefile.h,
- Source/cmMakefileExecutableTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.cxx,
- Source/cmMarkAsAdvancedCommand.cxx, Source/cmMathCommand.h,
- Source/cmObject.h, Source/cmOptionCommand.cxx,
- Source/cmOrderLinkDirectories.cxx,
- Source/cmOrderLinkDirectories.h,
- Source/cmOutputRequiredFilesCommand.cxx,
- Source/cmProjectCommand.cxx, Source/cmQTWrapCPPCommand.cxx,
- Source/cmQTWrapUICommand.cxx,
- Source/cmRemoveDefinitionsCommand.cxx,
- Source/cmSeparateArgumentsCommand.cxx,
- Source/cmSeparateArgumentsCommand.h,
- Source/cmSetDirectoryPropertiesCommand.cxx,
- Source/cmSetSourceFilesPropertiesCommand.h,
- Source/cmSetTargetPropertiesCommand.cxx,
- Source/cmSetTargetPropertiesCommand.h,
- Source/cmSetTestsPropertiesCommand.cxx,
- Source/cmSetTestsPropertiesCommand.h,
- Source/cmSiteNameCommand.cxx, Source/cmSourceFile.cxx,
- Source/cmSourceFile.h, Source/cmSourceGroupCommand.h,
- Source/cmStringCommand.cxx, Source/cmSubdirCommand.cxx,
- Source/cmSubdirCommand.h, Source/cmSystemTools.cxx,
- Source/cmSystemTools.h, Source/cmTarget.cxx, Source/cmTarget.h,
- Source/cmTargetLinkLibrariesCommand.cxx,
- Source/cmTryCompileCommand.cxx, Source/cmTryCompileCommand.h,
- Source/cmUseMangledMesaCommand.cxx,
- Source/cmUtilitySourceCommand.cxx,
- Source/cmVTKMakeInstantiatorCommand.cxx,
- Source/cmVTKWrapJavaCommand.cxx,
- Source/cmVTKWrapPythonCommand.cxx,
- Source/cmVTKWrapTclCommand.cxx, Source/cmWin32ProcessExecution.h,
- Source/cmWriteFileCommand.cxx, Source/cmXCode21Object.cxx,
- Source/cmXCode21Object.h, Source/cmXCodeObject.cxx,
- Source/cmXCodeObject.h, Source/cmXMLParser.h, Source/cmake.cxx,
- Source/cmake.h, Source/cmakemain.cxx,
- Source/CPack/cmCPackGenericGenerator.cxx,
- Source/CPack/cmCPackNSISGenerator.cxx,
- Source/CPack/cmCPackPackageMakerGenerator.cxx,
- Source/CPack/cmCPackSTGZGenerator.cxx,
- Source/CPack/cmCPackTarCompressGenerator.cxx,
- Source/CPack/cpack.cxx, Tests/Complex/CMakeLists.txt,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexRelativePaths/CMakeLists.txt: ENH: merge from main
- tree
-
-2006-05-14 09:36 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-13 12:28 king
-
- * Source/cmGlobalGenerator.cxx: BUG: Make sure RUN_TESTS target
- passes the desired configuration to ctest.
-
-2006-05-13 08:03 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-12 14:44 martink
-
- * Source/CPack/: cmCPackGenericGenerator.cxx,
- cmCPackNSISGenerator.cxx, cmCPackPackageMakerGenerator.cxx,
- cmCPackSTGZGenerator.cxx, cmCPackTarCompressGenerator.cxx,
- cpack.cxx: STYLE: fix line length
-
-2006-05-12 14:36 martink
-
- * Source/: cmXCode21Object.cxx, cmXCode21Object.h,
- cmXCodeObject.cxx, cmXCodeObject.h, cmXMLParser.h, cmake.cxx,
- cmake.h, cmakemain.cxx: STYLE: fix line length
-
-2006-05-12 14:12 martink
-
- * Source/: cmTarget.cxx, cmTarget.h,
- cmTargetLinkLibrariesCommand.cxx, cmTryCompileCommand.cxx,
- cmTryCompileCommand.h, cmUseMangledMesaCommand.cxx,
- cmUtilitySourceCommand.cxx, cmVTKMakeInstantiatorCommand.cxx,
- cmVTKWrapJavaCommand.cxx, cmVTKWrapPythonCommand.cxx,
- cmVTKWrapTclCommand.cxx, cmWin32ProcessExecution.h,
- cmWriteFileCommand.cxx: STYLE: fix line length
-
-2006-05-12 13:53 martink
-
- * Source/: cmSeparateArgumentsCommand.cxx,
- cmSeparateArgumentsCommand.h,
- cmSetDirectoryPropertiesCommand.cxx,
- cmSetSourceFilesPropertiesCommand.h,
- cmSetTargetPropertiesCommand.cxx, cmSetTargetPropertiesCommand.h,
- cmSetTestsPropertiesCommand.cxx, cmSetTestsPropertiesCommand.h,
- cmSiteNameCommand.cxx, cmSourceFile.cxx, cmSourceFile.h,
- cmSourceGroupCommand.h, cmStringCommand.cxx, cmSubdirCommand.cxx,
- cmSubdirCommand.h, cmSystemTools.cxx, cmSystemTools.h: STYLE: fix
- line length
-
-2006-05-12 13:44 martink
-
- * Source/: cmProjectCommand.cxx, cmQTWrapCPPCommand.cxx,
- cmQTWrapUICommand.cxx, cmRemoveDefinitionsCommand.cxx: STYLE: fix
- line length
-
-2006-05-12 13:39 martink
-
- * Source/: cmObject.h, cmOptionCommand.cxx,
- cmOrderLinkDirectories.cxx, cmOrderLinkDirectories.h,
- cmOutputRequiredFilesCommand.cxx: STYLE: fix line length
-
-2006-05-12 12:29 martink
-
- * Source/: cmMacroCommand.cxx, cmMakeDepend.h, cmMakefile.cxx,
- cmMakefile.h, cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx, cmMarkAsAdvancedCommand.cxx,
- cmMathCommand.h: STYLE: fix line length
-
-2006-05-12 11:56 martink
-
- * Source/: cmLinkDirectoriesCommand.cxx,
- cmLinkLibrariesCommand.cxx, cmListCommand.cxx,
- cmListFileCache.cxx, cmLoadCacheCommand.cxx,
- cmLoadCommandCommand.h, cmLocalGenerator.cxx,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h: STYLE: fix line length
-
-2006-05-12 11:03 hoffman
-
- * CMakeLists.txt: ENH: add the processor to the system name for
- cpack
-
-2006-05-12 10:56 hoffman
-
- * Modules/FindQt4.cmake: ENH: remove bad quoteed code
-
-2006-05-12 10:54 king
-
- * Source/cmIncludeDirectoryCommand.cxx,
- Tests/Complex/CMakeLists.txt,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexRelativePaths/CMakeLists.txt: BUG:
- INCLUDE_DIRECTORIES should interpret relative path arguments with
- respect to the current source directory.
-
-2006-05-12 10:46 martink
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalMSYSMakefileGenerator.h:
- STYLE: fix line length
-
-2006-05-12 10:09 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: ENH: remove bogus
- machine setting
-
-2006-05-12 09:47 hoffman
-
- * Modules/FindQt4.cmake: ENH: fix path problem with qt
-
-2006-05-12 07:56 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-11 18:32 alex
-
- * Modules/FindJPEG.cmake: ENH: honor REQUIRED flag
-
- Alex
-
-2006-05-11 18:27 alex
-
- * Modules/FindKDE4.cmake: ENH: use the new FILE(TO_CMAKE_PATH ...)
- command instead of regexps BUG: append the kde 4 cmake module
- path instead of prepending it
-
- Alex
-
-2006-05-11 16:07 hoffman
-
- * Utilities/Release/: dashmacmini2_release.cmake,
- destiny_release.cmake, release_cmake.cmake, release_cmake.sh.in,
- vogon_release.cmake: ENH: working package creator
-
-2006-05-11 16:05 hoffman
-
- * Source/: cmAddSubDirectoryCommand.cxx, cmExprParser.cxx,
- cmExprParserHelper.cxx, cmFLTKWrapUICommand.cxx,
- cmFileCommand.cxx, cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalKdevelopGenerator.cxx, cmGlobalMSYSMakefileGenerator.cxx,
- cmGlobalMinGWMakefileGenerator.cxx,
- cmGlobalMinGWMakefileGenerator.h,
- cmGlobalNMakeMakefileGenerator.cxx,
- cmGlobalNMakeMakefileGenerator.h,
- cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio6Generator.h,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio71Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h,
- cmGlobalVisualStudio8Generator.cxx,
- cmGlobalVisualStudio8Generator.h,
- cmGlobalVisualStudio8Win64Generator.cxx,
- cmGlobalVisualStudio8Win64Generator.h,
- cmGlobalWatcomWMakeGenerator.cxx, cmGlobalXCode21Generator.cxx,
- cmGlobalXCode21Generator.h, cmGlobalXCodeGenerator.cxx,
- cmGlobalXCodeGenerator.h, cmIfCommand.cxx, cmIfCommand.h,
- cmIncludeCommand.cxx, cmIncludeDirectoryCommand.cxx,
- cmIncludeExternalMSProjectCommand.cxx,
- cmIncludeExternalMSProjectCommand.h,
- cmIncludeRegularExpressionCommand.cxx,
- cmIncludeRegularExpressionCommand.h, cmInstallCommand.h,
- cmInstallFilesCommand.cxx, cmInstallGenerator.cxx,
- cmInstallGenerator.h, cmInstallProgramsCommand.cxx,
- cmInstallTargetGenerator.cxx, cmInstallTargetGenerator.h,
- cmInstallTargetsCommand.cxx, cmListCommand.cxx, cmListCommand.h,
- CTest/cmCTestBuildHandler.cxx: ENH: merge changes from main tree
-
-2006-05-11 15:50 hoffman
-
- * Source/cmFileCommand.cxx: ENH: fix error message
-
-2006-05-11 15:50 martink
-
- * Source/: cmIfCommand.cxx, cmIfCommand.h, cmIncludeCommand.cxx,
- cmIncludeDirectoryCommand.cxx,
- cmIncludeExternalMSProjectCommand.cxx,
- cmIncludeExternalMSProjectCommand.h,
- cmIncludeRegularExpressionCommand.cxx,
- cmIncludeRegularExpressionCommand.h, cmInstallCommand.h,
- cmInstallFilesCommand.cxx, cmInstallGenerator.cxx,
- cmInstallGenerator.h, cmInstallProgramsCommand.cxx,
- cmInstallProgramsCommand.h, cmInstallTargetGenerator.cxx,
- cmInstallTargetGenerator.h, cmInstallTargetsCommand.cxx: STYLE:
- fix line length
-
-2006-05-11 15:39 martink
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h:
- STYLE: fix line length
-
-2006-05-11 13:56 andy
-
- * Source/: cmListCommand.cxx, cmListCommand.h: ENH: Some
- documentation and add APPEND
-
-2006-05-11 12:00 andy
-
- * Source/CTest/cmCTestBuildHandler.cxx: BUG: Fix segfault
-
-2006-05-11 11:47 martink
-
- * Source/: cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio6Generator.h,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio71Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h,
- cmGlobalVisualStudio8Generator.cxx,
- cmGlobalVisualStudio8Generator.h,
- cmGlobalVisualStudio8Win64Generator.cxx,
- cmGlobalVisualStudio8Win64Generator.h,
- cmGlobalWatcomWMakeGenerator.cxx, cmGlobalXCode21Generator.cxx,
- cmGlobalXCode21Generator.h, cmGlobalXCodeGenerator.cxx: STYLE:
- fix line length
-
-2006-05-11 10:56 hoffman
-
- * ChangeLog.manual, Modules/FindQt4.cmake: ENH: merge changs from
- main tree
-
-2006-05-11 10:45 martink
-
- * Source/: cmExprParser.cxx, cmExprParserHelper.cxx,
- cmFLTKWrapUICommand.cxx: STYLE: fix line length
-
-2006-05-11 10:41 hoffman
-
- * Modules/FindQt4.cmake: ENH: fix for bug 3216 allow full path to
- qt input files
-
-2006-05-11 10:39 martink
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalKdevelopGenerator.cxx, cmGlobalMSYSMakefileGenerator.cxx,
- cmGlobalMinGWMakefileGenerator.cxx,
- cmGlobalMinGWMakefileGenerator.h,
- cmGlobalNMakeMakefileGenerator.cxx,
- cmGlobalNMakeMakefileGenerator.h,
- cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h, cmAddSubDirectoryCommand.cxx:
- STYLE: fix line length
-
-2006-05-11 10:33 hoffman
-
- * ChangeLog.manual, Source/CPack/cmCPackZIPGenerator.cxx: ENH:
- merge changes from main tree
-
-2006-05-11 09:37 hoffman
-
- * Source/CPack/cmCPackZIPGenerator.cxx: ENH: use @ file for winzip
- on windows
-
-2006-05-11 08:03 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-10 22:15 hoffman
-
- * CMakeLists.txt, Modules/CPack.cmake,
- Modules/NSIS.InstallOptions.ini.in, Modules/NSIS.template.in,
- Source/cmAddExecutableCommand.cxx,
- Source/cmAddSubDirectoryCommand.cxx, Source/cmAddTestCommand.cxx,
- Source/cmAuxSourceDirectoryCommand.cxx,
- Source/cmAuxSourceDirectoryCommand.h, Source/cmCTest.cxx,
- Source/cmCacheManager.cxx, Source/cmCommandArgumentLexer.cxx,
- Source/cmCommandArgumentParser.cxx,
- Source/cmCommandArgumentParserHelper.cxx,
- Source/cmCommandArgumentParserTokens.h,
- Source/cmConfigureFileCommand.cxx,
- Source/cmCreateTestSourceList.h, Source/cmDepends.cxx,
- Source/cmDepends.h, Source/cmDependsC.cxx,
- Source/cmDependsFortran.cxx, Source/cmDependsFortranParser.cxx,
- Source/cmDependsJavaParserHelper.cxx,
- Source/cmDependsJavaParserHelper.h, Source/cmDocumentation.cxx,
- Source/cmDumpDocumentation.cxx, Source/cmElseCommand.cxx,
- Source/cmEnableLanguageCommand.cxx,
- Source/cmEndForEachCommand.cxx, Source/cmEndIfCommand.cxx,
- Source/cmEndWhileCommand.cxx, Source/cmExecProgramCommand.cxx,
- Source/cmExecuteProcessCommand.cxx,
- Source/cmExecuteProcessCommand.h,
- Source/cmExportLibraryDependencies.cxx,
- Source/cmExportLibraryDependencies.h, Source/cmExprLexer.cxx,
- Source/cmExprLexer.h, Source/cmFLTKWrapUICommand.cxx,
- Source/cmFileCommand.cxx, Source/cmFileCommand.h,
- Source/cmFileTimeComparison.cxx, Source/cmFindBase.cxx,
- Source/cmFindFileCommand.cxx, Source/cmFindLibraryCommand.cxx,
- Source/cmFindPackageCommand.cxx, Source/cmFindPathCommand.cxx,
- Source/cmFindProgramCommand.cxx, Source/cmForEachCommand.cxx,
- Source/cmGeneratedFileStream.cxx,
- Source/cmGetDirectoryPropertyCommand.cxx,
- Source/cmGetFilenameComponentCommand.cxx,
- Source/cmGetFilenameComponentCommand.h,
- Source/cmGlobalBorlandMakefileGenerator.cxx,
- Source/CPack/cmCPackGenericGenerator.cxx, Source/CPack/cpack.cxx,
- Source/CTest/cmCTestGenericHandler.cxx,
- Source/CTest/cmCTestHandlerCommand.cxx,
- Source/CTest/cmCTestReadCustomFilesCommand.h,
- Source/CTest/cmCTestScriptHandler.cxx,
- Source/CTest/cmCTestTestHandler.cxx,
- Source/CTest/cmCTestUpdateCommand.cxx: ENH: move changes from
- main tree
-
-2006-05-10 17:26 andy
-
- * CMakeLists.txt, Modules/CPack.cmake: BUG: Prevent stripping of
- sources
-
-2006-05-10 16:44 hoffman
-
- * Utilities/Release/create-cmake-release.cmake: ENH: remove ps
- thing
-
-2006-05-10 16:43 hoffman
-
- * Utilities/Release/: create-cmake-release.cmake,
- vogon_release.cmake: ENH: it works
-
-2006-05-10 15:56 martink
-
- * Source/: cmGeneratedFileStream.cxx,
- cmGetDirectoryPropertyCommand.cxx,
- cmGetFilenameComponentCommand.cxx,
- cmGetFilenameComponentCommand.h,
- cmGetSourceFilePropertyCommand.h,
- cmGlobalBorlandMakefileGenerator.cxx: STYLE: fix line length
-
-2006-05-10 15:46 martink
-
- * Source/: cmFLTKWrapUICommand.cxx, cmFileCommand.cxx,
- cmFileCommand.h, cmFileTimeComparison.cxx, cmFindBase.cxx,
- cmFindFileCommand.cxx, cmFindLibraryCommand.cxx,
- cmFindPackageCommand.cxx, cmFindPathCommand.cxx,
- cmFindProgramCommand.cxx, cmForEachCommand.cxx: STYLE: fix line
- length
-
-2006-05-10 15:29 hoffman
-
- * Utilities/Release/vogon_release.cmake: ENH: add vogon
-
-2006-05-10 15:06 martink
-
- * Source/: cmElseCommand.cxx, cmEnableLanguageCommand.cxx,
- cmEndForEachCommand.cxx, cmEndIfCommand.cxx,
- cmEndWhileCommand.cxx, cmExecProgramCommand.cxx,
- cmExecuteProcessCommand.cxx, cmExecuteProcessCommand.h,
- cmExportLibraryDependencies.cxx, cmExportLibraryDependencies.h,
- cmExprLexer.cxx, cmExprLexer.h: STYLE: fix line length
-
-2006-05-10 15:01 martink
-
- * Source/: cmDependsJavaParserHelper.cxx,
- cmDependsJavaParserHelper.h, cmDocumentation.cxx,
- cmDumpDocumentation.cxx: STYLE: fix line length
-
-2006-05-10 14:54 martink
-
- * Source/: cmDepends.h, cmDependsC.cxx, cmDependsFortran.cxx,
- cmDependsFortranParser.cxx: STYLE: fix line length
-
-2006-05-10 14:13 martink
-
- * Source/: cmCommandArgumentParser.cxx,
- cmCommandArgumentParserHelper.cxx,
- cmCommandArgumentParserTokens.h, cmConfigureFileCommand.cxx,
- cmCreateTestSourceList.h, cmDepends.cxx: STYLE: fix line length
-
-2006-05-10 14:07 martink
-
- * Source/cmCommandArgumentLexer.cxx: STYLE: hmm
-
-2006-05-10 14:03 hoffman
-
- * Utilities/Release/: create-cmake-release.cmake,
- dashsgi1_release.cmake, dashsgi1_release64.cmake,
- release_cmake.sh.in: ENH:
-
-2006-05-10 14:00 martink
-
- * Source/cmCommandArgumentLexer.cxx: STYLE: hmm
-
-2006-05-10 13:56 martink
-
- * Source/: cmAuxSourceDirectoryCommand.h, cmCTest.cxx,
- cmCacheManager.cxx: STYLE: fix line length
-
-2006-05-10 13:48 martink
-
- * Source/: CTest/cmCTestGenericHandler.cxx,
- CTest/cmCTestHandlerCommand.cxx,
- CTest/cmCTestReadCustomFilesCommand.h,
- CTest/cmCTestScriptHandler.cxx, CTest/cmCTestTestHandler.cxx,
- CTest/cmCTestUpdateCommand.cxx, cmAddExecutableCommand.cxx,
- cmAddSubDirectoryCommand.cxx, cmAddTestCommand.cxx,
- cmAuxSourceDirectoryCommand.cxx: STYLE: fix line length
-
-2006-05-10 12:39 andy
-
- * Source/CPack/: cmCPackGenericGenerator.cxx, cpack.cxx: BUG: Fix
- relative path to config file, fix cmake_install.cmake location
- problem
-
-2006-05-10 12:15 hoffman
-
- * Modules/: NSIS.InstallOptions.ini.in, NSIS.template.in: ENH: use
- radio buttons to choose PATH options
-
-2006-05-10 09:28 hoffman
-
- * CMakeLists.txt: ENH: allow package name to be changed from cmake
- cache
-
-2006-05-10 09:15 hoffman
-
- * CMakeLists.txt: ENH: allow for cpack stuff to be changed
-
-2006-05-10 07:58 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-09 17:18 hoffman
-
- * Utilities/Release/: dashsun1_release.cmake, release_cmake.cmake,
- v60n177_aix_release.cmake: ENH: works
-
-2006-05-09 16:30 hoffman
-
- * ChangeLog.manual, Modules/FindQt3.cmake,
- Modules/NSIS.template.in, Source/cmSetTargetPropertiesCommand.h,
- Source/kwsys/SystemTools.cxx, Tests/Complex/CMakeLists.txt,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexRelativePaths/CMakeLists.txt: ENH: merge from main
- tree
-
-2006-05-09 14:14 hoffman
-
- * Utilities/Release/: create-cmake-release.cmake,
- release_cmake.cmake: ENH: seems to be working
-
-2006-05-09 13:49 hoffman
-
- * Utilities/Release/create-cmake-release.cmake: ENH: add a xterm
- script create script
-
-2006-05-09 13:48 hoffman
-
- * Utilities/Release/: dashsun1_release.cmake, muse_release64.cmake,
- release_cmake.cmake, release_cmake.sh.in: ENH: add 64 bit sgi
-
-2006-05-09 12:23 hoffman
-
- * Utilities/Release/release_cmake.sh.in: ENH: mark time
-
-2006-05-09 12:23 andy
-
- * Utilities/Release/v60n177_aix_release.cmake: ENH: copy right
- files
-
-2006-05-09 08:22 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-08 16:59 hoffman
-
- * Utilities/Release/: dashmacmini2_release.cmake,
- dashsun1_release.cmake, destiny_release.cmake,
- muse_release.cmake, v60n177_aix_release.cmake: ENH: skip
- bootstrap test as it already does a bootstrap
-
-2006-05-08 16:50 hoffman
-
- * Utilities/Release/: dashmacmini2_release.cmake,
- destiny_release.cmake, hythloth_release.cmake,
- muse_release.cmake, release_cmake.cmake,
- v60n177_aix_release.cmake: ENH: change name to MAKE_COMMAND
-
-2006-05-08 16:40 hoffman
-
- * Source/cmSetTargetPropertiesCommand.h: ENH: fix docs to include
- linker lang
-
-2006-05-08 16:38 andy
-
- * Utilities/Release/release_cmake.cmake: ENH: add extra copy for
- ibm
-
-2006-05-08 16:36 hoffman
-
- * Utilities/Release/: dashmacmini2_release.cmake,
- destiny_release.cmake, hythloth_release.cmake,
- muse_release.cmake, release_cmake.cmake, release_cmake.sh.in,
- v60n177_aix_release.cmake: ENH: add make program stuff
-
-2006-05-08 14:18 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: search for program without
- extensions
-
-2006-05-08 13:34 andy
-
- * Modules/NSIS.template.in: ENH: Some cleanups and fix installing
- as a non-admin
-
-2006-05-08 10:02 king
-
- * Tests/: Complex/CMakeLists.txt, ComplexOneConfig/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt: BUG: Disabling an
- EXECUTE_PROCESS test until problems on UNIX systems are fixed.
-
-2006-05-07 13:04 hoffman
-
- * Modules/FindQt3.cmake: ENH: try to find qt3 better
-
-2006-05-07 10:55 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Modules/CMakeDetermineCCompiler.cmake,
- Modules/CPack.STGZ_Header.sh.in, Modules/FindQt4.cmake,
- Modules/Platform/CYGWIN.cmake, Modules/Platform/SunOS.cmake,
- Modules/Platform/Windows-cl.cmake, Source/CMakeLists.txt,
- Source/cmCommandArgumentParserHelper.cxx, Source/cmDepends.h,
- Source/cmDependsC.cxx, Source/cmFileCommand.cxx,
- Source/cmGlobalGenerator.cxx,
- Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmGlobalUnixMakefileGenerator3.h,
- Source/cmGlobalVisualStudio6Generator.cxx,
- Source/cmGlobalVisualStudio71Generator.cxx,
- Source/cmGlobalVisualStudio71Generator.h,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.h,
- Source/cmGlobalVisualStudio8Generator.cxx,
- Source/cmGlobalVisualStudio8Generator.h,
- Source/cmIncludeExternalMSProjectCommand.cxx,
- Source/cmInstallCommand.cxx, Source/cmInstallCommand.h,
- Source/cmInstallFilesGenerator.cxx,
- Source/cmInstallFilesGenerator.h, Source/cmInstallGenerator.cxx,
- Source/cmInstallGenerator.h, Source/cmInstallTargetGenerator.cxx,
- Source/cmInstallTargetGenerator.h, Source/cmLocalGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalVisualStudio7Generator.cxx, Source/cmMakefile.cxx,
- Source/cmSourceFile.cxx, Source/cmSourceFile.h,
- Source/cmSourceGroupCommand.h, Source/cmTarget.cxx,
- Source/CPack/cmCPackGenerators.cxx,
- Source/CPack/cmCPackGenerators.h,
- Source/CPack/cmCPackGenericGenerator.cxx,
- Source/CPack/cmCPackNSISGenerator.cxx,
- Source/CPack/cmCPackPackageMakerGenerator.cxx,
- Source/CPack/cmCPackSTGZGenerator.cxx,
- Source/CPack/cmCPackTGZGenerator.cxx,
- Source/CPack/cmCPackTGZGenerator.h,
- Source/CPack/cmCPackTarBZip2Generator.cxx,
- Source/CPack/cmCPackTarBZip2Generator.h,
- Source/CPack/cmCPackTarCompressGenerator.cxx,
- Source/CPack/cmCPackTarCompressGenerator.h,
- Source/CPack/cmCPackZIPGenerator.cxx, Source/CPack/cpack.cxx,
- Source/kwsys/SystemTools.cxx, Source/kwsys/SystemTools.hxx.in,
- Tests/COnly/conly.c, Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt,
- Utilities/Release/cmake_release.sh.in: ENH: move changes from
- main tree and change version to 2.4.2
-
-2006-05-07 09:29 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-06 10:01 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-05 22:04 hoffman
-
- * Utilities/Release/: release_cmake.sh.in,
- v60n177_aix_release.cmake: ENH: add extra copy for aix
-
-2006-05-05 21:49 hoffman
-
- * Modules/Platform/CYGWIN.cmake: ENH: add the flag for creating
- windows gui's
-
-2006-05-05 21:45 hoffman
-
- * Source/cmCommandArgumentParserHelper.cxx: ENH: handle empty
- variables
-
-2006-05-05 20:54 king
-
- * Source/: cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio71Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h,
- cmGlobalVisualStudio8Generator.cxx,
- cmGlobalVisualStudio8Generator.h: BUG: MSVC* variables should be
- set in IDE generators instead of just NMake.
-
-2006-05-05 16:12 andy
-
- * Utilities/Release/v60n177_aix_release.cmake: ENH: use a directory
- with space
-
-2006-05-05 15:51 hoffman
-
- * Utilities/Release/: release_cmake.cmake, release_cmake.sh.in:
- ENH: make release directory a variable
-
-2006-05-05 15:04 hoffman
-
- * Modules/FindQt4.cmake: ENH: fix windows path issue
-
-2006-05-05 14:57 king
-
- * Source/cmFileCommand.cxx, Source/cmInstallCommand.cxx,
- Source/cmInstallCommand.h, Source/cmInstallFilesGenerator.cxx,
- Source/cmInstallFilesGenerator.h, Source/cmInstallGenerator.cxx,
- Source/cmInstallGenerator.h, Source/cmInstallTargetGenerator.cxx,
- Source/cmInstallTargetGenerator.h, Source/cmLocalGenerator.cxx,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: Added CONFIGURATIONS
- option to INSTALL command to allow per-configuration install
- rules.
-
-2006-05-05 14:53 andy
-
- * Utilities/Release/: release_cmake.sh.in,
- v60n177_aix_release.cmake: ENH: fix env vars
-
-2006-05-05 13:52 hoffman
-
- * Utilities/Release/release_cmake.sh.in: ENH: add ability to set
- CC, CXX and LDFLAGS
-
-2006-05-05 13:10 hoffman
-
- * Utilities/Release/release_cmake.cmake: ENH: move from tr to cat
- since it works from a windows machine and works on the AIX
-
-2006-05-05 12:49 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-05 12:34 hoffman
-
- * Utilities/Release/: release_cmake.cmake, release_cmake.sh.in:
- ENH: add missing quote and some comments
-
-2006-05-05 12:25 hoffman
-
- * Utilities/Release/: release_cmake.cmake, release_cmake.sh.in:
- ENH: remove old copy
-
-2006-05-05 12:14 hoffman
-
- * Utilities/Release/: destiny_release.cmake, release_cmake.cmake,
- release_cmake.sh.in: ENH: working on hp
-
-2006-05-05 11:51 king
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ENH: Adding COMPONENT option to
- an INSTALL command call to smoke-test it.
-
-2006-05-05 11:46 king
-
- * Source/: cmSourceFile.cxx, cmSourceFile.h, cmTarget.cxx: ENH:
- Added information about target needing a source file when one
- cannot be found.
-
-2006-05-05 11:37 king
-
- * Source/cmSourceGroupCommand.h: ENH: Added example of sub-group to
- docs.
-
-2006-05-05 10:38 king
-
- * Source/cmFileCommand.cxx: ENH: Added option to not use
- copy-if-different when installing.
-
-2006-05-05 10:33 hoffman
-
- * Utilities/Release/: release_cmake.cmake: ENH: create script is
- working
-
-2006-05-05 10:30 hoffman
-
- * Utilities/Release/: release_cmake.cmake, release_cmake.sh.in:
- ENH: create script is working
-
-2006-05-05 10:29 king
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH: Added
- always/if-different option to CopyADirectory. Added CopyAFile
- with the same interface.
-
-2006-05-05 08:16 hoffman
-
- * Utilities/Release/release_cmake.cmake: ENH: change to script mode
-
-2006-05-04 22:58 hoffman
-
- * Utilities/Release/: release_cmake.sh.in: ENH: add file
-
-2006-05-04 21:57 hoffman
-
- * Utilities/Release/: destiny_release.cmake, muse_release.cmake:
- ENH: add some machines
-
-2006-05-04 17:54 hoffman
-
- * Source/cmMakefile.cxx: ENH: add a check to make sure targets only
- link to libraries and not utility targets to avoid seg faults,
- bug 3194
-
-2006-05-04 13:39 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: ENH: remove debug
- output
-
-2006-05-04 13:35 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx, Tests/COnly/conly.c:
- ENH: fix build c stuff with c and c++ with c++
-
-2006-05-04 10:07 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-03 23:03 hoffman
-
- * Source/cmIncludeExternalMSProjectCommand.cxx: ENH: make sure path
- is converted to unix
-
-2006-05-03 21:42 andy
-
- * Source/: CMakeLists.txt, CPack/cmCPackGenerators.cxx,
- CPack/cmCPackTarBZip2Generator.cxx,
- CPack/cmCPackTarBZip2Generator.h, CPack/cpack.cxx: ENH: Add BZip2
- support, add better documentation
-
-2006-05-03 17:27 hoffman
-
- * Utilities/Release/release_cmake.cmake: ENH: add cvs command
- variable
-
-2006-05-03 17:22 hoffman
-
- * Utilities/Release/: release_cmake.cmake,
- v60n177_aix_release.cmake: ENH: more aix stuff
-
-2006-05-03 17:08 hoffman
-
- * Utilities/Release/: release_cmake.cmake,
- v60n177_aix_release.cmake: ENH: add aix
-
-2006-05-03 16:24 andy
-
- * Modules/CPack.STGZ_Header.sh.in: ENH: Better output
-
-2006-05-03 15:17 martink
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: BUG: use SHELL var
-
-2006-05-03 15:17 martink
-
- * Source/CPack/cmCPackGenericGenerator.cxx: BUG: fix CPack to use
- correct paths
-
-2006-05-03 10:07 king
-
- * Source/: cmDepends.h, cmDependsC.cxx,
- cmLocalUnixMakefileGenerator3.cxx: BUG: Fix to avoid repeated
- calls to CollapseFullPath during dependency scanning. This
- addresses bug#3191.
-
-2006-05-03 09:23 hoffman
-
- * Modules/Platform/SunOS.cmake: ENH: use correct flags for
- optimization
-
-2006-05-03 08:16 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-02 23:20 hoffman
-
- * Utilities/Release/: dashmacmini2_release.cmake,
- dashsun1_release.cmake, hythloth_release.cmake,
- release_cmake.cmake: ENH: getting better
-
-2006-05-02 18:47 andy
-
- * Source/CPack/cmCPackTGZGenerator.cxx: COMP: Fix cast to char*
-
-2006-05-02 18:43 andy
-
- * Source/CPack/cmCPackTarCompressGenerator.cxx: COMP: Try to fix
- windows builds
-
-2006-05-02 17:52 andy
-
- * Source/CPack/: cmCPackGenerators.cxx, cmCPackGenerators.h,
- cpack.cxx: ENH: Add generators documentation
-
-2006-05-02 17:34 andy
-
- * Source/CPack/: cmCPackTGZGenerator.cxx, cmCPackTGZGenerator.h,
- cmCPackTarCompressGenerator.cxx, cmCPackTarCompressGenerator.h:
- ENH: Simplify TarCompress to only require compress. Use cmake's
- tar
-
-2006-05-02 17:07 andy
-
- * Source/: CMakeLists.txt, CPack/cmCPackGenerators.cxx,
- CPack/cmCPackTarCompressGenerator.cxx,
- CPack/cmCPackTarCompressGenerator.h: ENH: Initial cut at
- TarCompress generator
-
-2006-05-02 16:41 hoffman
-
- * Utilities/Release/release_cmake.cmake: ENH: remove debug
-
-2006-05-02 16:41 hoffman
-
- * Utilities/Release/: cmake_login, release_cmake.cmake: ENH: more
- stuff
-
-2006-05-02 16:33 hoffman
-
- * Utilities/Release/release_cmake.cmake: ENH: remove if0
-
-2006-05-02 16:32 hoffman
-
- * Utilities/Release/: dashsun1_release.cmake,
- hythloth_release.cmake, release_cmake.cmake: ENH: first pass at
- cmake scripts to create the cmake release
-
-2006-05-02 14:04 hoffman
-
- * Modules/FindQt4.cmake: ENH: fix qt version detection
-
-2006-05-02 13:31 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: add a fast version
- for preinstall
-
-2006-05-02 12:44 martink
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: BUG: need to make sure
- paths are OK
-
-2006-05-02 12:40 martink
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: BUG: need to make sure
- paths are OK
-
-2006-05-02 10:48 martink
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: BUG: fix for unix
-
-2006-05-02 09:56 martink
-
- * Source/cmGlobalGenerator.cxx,
- Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmGlobalUnixMakefileGenerator3.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Modules/CMakeDetermineCCompiler.cmake,
- Modules/Platform/Windows-cl.cmake: ENH: Makefile performance
- improvements
-
-2006-05-02 08:49 andy
-
- * CMakeLists.txt, Source/CPack/cmCPackGenericGenerator.cxx,
- Source/CPack/cmCPackNSISGenerator.cxx,
- Source/CPack/cmCPackPackageMakerGenerator.cxx,
- Source/CPack/cmCPackSTGZGenerator.cxx,
- Source/CPack/cmCPackZIPGenerator.cxx: ENH: Add support for
- stipping and make more things overwritable
-
-2006-05-02 08:14 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-05-01 22:40 hoffman
-
- * Utilities/Release/cmake_release.sh: ENH: try again
-
-2006-05-01 22:31 hoffman
-
- * Utilities/Release/cmake_release.sh: ENH: try to call cpack from
- script
-
-2006-05-01 14:23 andy
-
- * Modules/CPack.STGZ_Header.sh.in,
- Source/CPack/cmCPackSTGZGenerator.cxx: ENH: Add license and make
- it more verbose
-
-2006-05-01 08:06 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-30 10:59 hoffman
-
- * CMakeLists.txt, Copyright.txt, Modules/CPack.cmake,
- Modules/NSIS.InstallOptions.ini.in, Modules/NSIS.template.in,
- Source/CPack/cmCPackNSISGenerator.cxx,
- Source/CTest/cmCTestGenericHandler.cxx,
- Source/CTest/cmCTestScriptHandler.cxx,
- Source/CTest/cmCTestScriptHandler.h: ENH: move files from main
- tree to 2.4.1
-
-2006-04-30 08:04 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-30 03:16 andy
-
- * Source/CTest/cmCTestGenericHandler.cxx: BUG: Make handle
- arguments work again
-
-2006-04-30 03:10 andy
-
- * Modules/NSIS.template.in: ENH: Handle the no-icon case
-
-2006-04-29 20:13 andy
-
- * Source/CTest/: cmCTestScriptHandler.cxx, cmCTestScriptHandler.h:
- ENH: Allow CTEST_UPDATE_COMMAND and fix the comments. This should
- allow SVN update too, maybe
-
-2006-04-29 20:03 andy
-
- * Copyright.txt: ENH: Acknowledge NAMIC
-
-2006-04-29 20:01 andy
-
- * CMakeLists.txt, Modules/CPack.cmake, Modules/NSIS.template.in:
- ENH: Add more install registry options
-
-2006-04-29 19:22 andy
-
- * CMakeLists.txt, Modules/NSIS.InstallOptions.ini.in,
- Modules/NSIS.template.in, Source/CPack/cmCPackNSISGenerator.cxx:
- ENH: Add NSIS options page for path selection, fix adding and
- removing from path, add welcome page and license page
-
-2006-04-29 11:49 hoffman
-
- * CMakeLists.txt, CTestConfig.cmake, ChangeLog.manual,
- Modules/CTest.cmake, Modules/FindQt4.cmake,
- Modules/NSIS.template.in, Source/cmCTest.cxx, Source/cmCTest.h,
- Source/cmMakefile.cxx, Source/cmVersion.cxx, Source/ctest.cxx,
- Source/CTest/cmCTestBuildHandler.cxx,
- Source/CTest/cmCTestGenericHandler.cxx,
- Source/CTest/cmCTestGenericHandler.h,
- Source/CTest/cmCTestStartCommand.cxx,
- Source/CTest/cmCTestStartCommand.h,
- Source/CTest/cmCTestSubmitHandler.cxx,
- Source/kwsys/DynamicLoader.cxx, Source/kwsys/SystemTools.cxx,
- Templates/CTestScript.cmake.in: ENH: merge in changes from main
- tree and change version to 2.4.1-beta
-
-2006-04-29 08:13 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-28 11:59 andy
-
- * Source/: cmCTest.cxx, cmCTest.h, ctest.cxx,
- CTest/cmCTestGenericHandler.cxx, CTest/cmCTestGenericHandler.h,
- CTest/cmCTestStartCommand.cxx, CTest/cmCTestStartCommand.h,
- CTest/cmCTestSubmitHandler.cxx: ENH: Add support for special
- tracks, fix options of handlers so that the -R, -U, and so on
- work in the new style scripting
-
-2006-04-28 11:58 andy
-
- * CTestConfig.cmake: ENH: Add XMLRPC support
-
-2006-04-28 11:58 andy
-
- * CMakeLists.txt, Templates/CTestScript.cmake.in: ENH: Add template
- of ctest script
-
-2006-04-28 09:58 andy
-
- * Modules/CTest.cmake: ENH: Allow overwriting CTestConfig.cmake
- items
-
-2006-04-28 08:59 hoffman
-
- * ChangeLog.manual, Docs/cmake-mode.el,
- Modules/CheckCSourceCompiles.cmake,
- Modules/CheckCXXSourceCompiles.cmake, Modules/FindQt4.cmake,
- Modules/UseQt4.cmake,
- Source/cmGlobalBorlandMakefileGenerator.cxx,
- Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmGlobalKdevelopGenerator.cxx,
- Source/cmGlobalMSYSMakefileGenerator.cxx,
- Source/cmGlobalMinGWMakefileGenerator.cxx,
- Source/cmGlobalNMakeMakefileGenerator.cxx,
- Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalWatcomWMakeGenerator.cxx,
- Source/cmLocalGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmMakefileTargetGenerator.cxx, Source/cmTest.cxx,
- Source/cmake.cxx, Source/cmake.h, Source/kwsys/CMakeLists.txt,
- Source/kwsys/SystemTools.cxx, Source/kwsys/Terminal.c,
- Source/kwsys/Terminal.h.in, Source/kwsys/testTerminal.c: ENH:
- merge changes from main tree
-
-2006-04-28 08:12 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-27 17:52 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: put the fix back in with abort
-
-2006-04-27 17:46 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: remove code that does not
- compile, on windows cwd must exist
-
-2006-04-27 16:20 andy
-
- * Modules/NSIS.template.in: ENH: Better support for adding and
- removing path
-
-2006-04-27 16:02 mrichardson
-
- * Source/kwsys/SystemTools.cxx: COMP: Fixing the the build for
- windows.
-
-2006-04-27 15:48 hoffman
-
- * Source/kwsys/DynamicLoader.cxx: ENH: remove warning
-
-2006-04-27 15:26 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: handle running from a
- directory that has been deleted
-
-2006-04-27 15:23 andy
-
- * Source/CTest/cmCTestBuildHandler.cxx: ENH: Fix problem with
- Source Lines and add debugging of regular expressions
-
-2006-04-27 15:14 alex
-
- * Modules/FindQt4.cmake: ENH: use the ADD_FILE_DEPENDENCIES() macro
- coming with cmake instead a duplicated implementation
- _qt4_add_file_dependencies() here
-
- Alex
-
-2006-04-27 15:07 alex
-
- * Modules/: FindQt4.cmake, UseQt4.cmake: ENH: -apply the patches by
- Clinton Stimpson and Kenneth Moreland which fix some QtMain
- issues on Windows ENH: -sync with KDE svn FindQt4, which features
- a lot of enhancements
-
- Alex
-
-2006-04-27 10:55 andy
-
- * Modules/: CheckCSourceCompiles.cmake,
- CheckCXXSourceCompiles.cmake: BUG: Use the extra definicions
-
-2006-04-27 10:41 king
-
- * Source/cmMakefileTargetGenerator.cxx: BUG: Make sure each
- cmake_depends process uses the same SystemTools path translation
- table as the original process. This addresses problems with
- dependency scanning when make is run from a symlink directory
- pointing at the original binary tree.
-
-2006-04-27 08:01 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-26 21:53 king
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx, cmake.cxx: COMP:
- Disable color support for bootstrap.
-
-2006-04-26 21:51 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Default SHELL on
- windows should not be a hard-coded path.
-
-2006-04-26 21:31 king
-
- * Source/: cmGlobalBorlandMakefileGenerator.cxx,
- cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalKdevelopGenerator.cxx, cmGlobalMSYSMakefileGenerator.cxx,
- cmGlobalMinGWMakefileGenerator.cxx,
- cmGlobalNMakeMakefileGenerator.cxx,
- cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalWatcomWMakeGenerator.cxx,
- cmLocalUnixMakefileGenerator3.cxx, cmake.cxx, cmake.h: ENH:
- Enabling color makefile support using cmsysTerminal_cfprintf.
- Support for color is automatically detected when messages are
- printed. Also made color scheme more readable on both black and
- white backgrounds. This option can be enabled by setting
- CMAKE_COLOR_MAKEFILE to true in the project.
-
-2006-04-26 15:54 king
-
- * Docs/cmake-mode.el: BUG: In example .emacs code use \' for
- end-of-string instead of $ for end-of-line.
-
-2006-04-26 14:28 king
-
- * Docs/cmake-mode.el: BUG: Mode should only be used if
- CMakeLists.txt is at the end of the buffer name.
-
-2006-04-26 14:22 king
-
- * Docs/cmake-mode.el: BUG: Tabs around a function name are allowed.
-
-2006-04-26 13:04 king
-
- * Docs/cmake-mode.el: ENH: Using suggestion from Stuart Herring to
- avoid needing a list of command names in the highlighting table.
-
-2006-04-26 08:01 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-25 16:31 hoffman
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: ENH: fix global help
-
-2006-04-25 12:09 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Docs/cmake-indent.vim,
- Modules/CPack.cmake, Modules/CTest.cmake, Modules/FindQt3.cmake,
- Modules/NSIS.template.in, Modules/UseEcos.cmake,
- Source/CMakeLists.txt, Source/cmGlobalKdevelopGenerator.cxx,
- Source/kwsys/SystemTools.cxx, Tests/Java/CMakeLists.txt: ENH:
- move from main tree to 2.4 branch
-
-2006-04-25 11:58 hoffman
-
- * Source/cmLocalGenerator.cxx: ENH: make sure special vs ide path
- is only used for msvc_ide builds
-
-2006-04-25 11:52 king
-
- * Docs/cmake-mode.el: ENH: Cleaned-up mode in preparation for
- inclusion in emacs upstream.
-
-2006-04-25 09:54 king
-
- * Source/cmLocalGenerator.cxx: ENH: Added option
- CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE to put all in-project
- include directories before all out-of-project include
- directories.
-
-2006-04-25 09:54 king
-
- * Source/kwsys/SystemTools.cxx: BUG: IsSubDirectory should use
- ComparePath to do platform-independent path comparison.
-
-2006-04-25 09:38 hoffman
-
- * Source/: cmGlobalVisualStudio7Generator.cxx,
- cmLocalGenerator.cxx: ENH: add special windows
- CMAKE_MSVCIDE_RUN_PATH variable for adding to the path of vs IDE
- for running custom commands from cmake
-
-2006-04-25 08:34 hoffman
-
- * Source/cmTest.cxx: ENH: make sure command is unix style as it may
- have been sent into cmake as a windows path
-
-2006-04-25 08:33 hoffman
-
- * Source/kwsys/Terminal.h.in: ENH: fix build on AIX
-
-2006-04-25 08:04 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-24 12:15 king
-
- * Source/kwsys/CMakeLists.txt: ENH: Enabling build/test of Terminal
- code now that it has been manually tested on several platforms.
-
-2006-04-24 12:12 hoffman
-
- * Source/cmFLTKWrapUICommand.cxx: ENH: fix fltk fluid order of
- build
-
-2006-04-24 11:30 hoffman
-
- * Source/cmFLTKWrapUICommand.cxx: ENH: make sure command depends on
- fluid
-
-2006-04-24 09:39 hoffman
-
- * Source/cmGlobalKdevelopGenerator.cxx: ENH: fix warnings
-
-2006-04-24 07:56 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-23 23:24 hoffman
-
- * Tests/Java/CMakeLists.txt: ENH: create the correct jar name
-
-2006-04-23 21:12 hoffman
-
- * Source/cmGlobalKdevelopGenerator.cxx: ENH: merge in Alex patches
-
-2006-04-23 19:45 andy
-
- * Modules/: CPack.cmake, NSIS.template.in: ENH: Propagate system
- name and handle win32/win64 name
-
-2006-04-23 18:39 andy
-
- * CMakeLists.txt: ENH: Enable path
-
-2006-04-23 18:23 andy
-
- * Modules/NSIS.template.in: ENH: Add a line to Add/Remove programs
- to uninstall
-
-2006-04-23 15:34 hoffman
-
- * Tests/Java/CMakeLists.txt: ENH: use the right name for the test
-
-2006-04-23 11:10 hoffman
-
- * Tests/Java/CMakeLists.txt: ENH: fix build
-
-2006-04-23 08:08 alex
-
- * Modules/UseEcos.cmake: BUG: finally really fix #2576 by adding
- UseEcos.cmake to cvs :-)
-
- Alex
-
-2006-04-23 07:57 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-23 07:23 alex
-
- * Modules/FindQt3.cmake: BUG: fix QT_MIN_VERSION handling, it
- didn't work anymore (qt_version_str vs. qt_version_str_lib)
-
- Alex
-
-2006-04-22 20:32 king
-
- * Source/kwsys/Terminal.c: COMP: Added missing include of string.h
- for strcmp.
-
-2006-04-22 20:26 king
-
- * Source/kwsys/Terminal.c: BUG: Fixed bug in check for vt100
- assumption.
-
-2006-04-22 20:25 king
-
- * Source/kwsys/Terminal.c: BUG: Fixed uninitialized variable when
- not building with windows console support.
-
-2006-04-22 20:20 king
-
- * Source/kwsys/: CMakeLists.txt, Terminal.c, Terminal.h.in,
- testTerminal.c: ENH: Adding 'Terminal' component to hold support
- routines for dealing with interactive terminals. Currently only
- a cfprintf function is provided to print color messages.
-
-2006-04-22 09:13 hoffman
-
- * Tests/Java/CMakeLists.txt: ENH: fix in source build for vs ide
-
-2006-04-22 08:07 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-21 20:13 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: fix borland bug
-
-2006-04-21 16:33 andy
-
- * Docs/cmake-indent.vim: BUG: Fix typo
-
-2006-04-21 15:15 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: performance improvments
-
-2006-04-21 14:36 andy
-
- * Modules/CTest.cmake: BUG: Fix the missing nightly start time bug
- and do some cleanup
-
-2006-04-21 14:26 andy
-
- * Source/CMakeLists.txt: ENH: Cleanup
-
-2006-04-21 10:26 hoffman
-
- * CTestCustom.ctest.in, ChangeLog.manual, Docs/cmake-indent.vim,
- Docs/cmake-syntax.vim, Modules/CMakeGenericSystem.cmake,
- Modules/Platform/HP-UX.cmake, Modules/Platform/Linux-ifort.cmake,
- Modules/Platform/Linux.cmake, Modules/Platform/kFreeBSD.cmake,
- Source/cmGlobalGenerator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx, Source/cmMakefile.h,
- Source/cmMakefileTargetGenerator.cxx, Source/cmake.cxx: ENH: move
- stuff from main tree
-
-2006-04-21 08:59 hoffman
-
- * CTestCustom.ctest.in: ENH: supress xcode warning
-
-2006-04-21 08:59 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: ENH: use a better name
-
-2006-04-21 08:06 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-21 07:17 andy
-
- * Docs/cmake-indent.vim: ENH: Add While support
-
-2006-04-20 21:54 hoffman
-
- * Source/cmMakefileTargetGenerator.cxx: ENH: ignore all files that
- we do not know about just like in ide generators
-
-2006-04-20 21:32 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: ENH: do not compile
- header files
-
-2006-04-20 17:00 hoffman
-
- * Source/cmake.cxx: ENH: save the cache on fatal error so that
- users can set cache values
-
-2006-04-20 16:16 hoffman
-
- * ChangeLog.manual, Modules/CheckCSourceCompiles.cmake,
- Modules/CheckCXXSourceCompiles.cmake,
- Modules/Platform/Windows-cl.cmake,
- Source/cmBootstrapCommands.cxx, Source/cmCommands.cxx,
- Source/cmLocalGenerator.cxx, Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio6Generator.h,
- Source/cmMakefileExecutableTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.cxx, Source/cmakemain.cxx,
- Templates/CPack.GenericDescription.txt,
- Templates/CPack.GenericLicense.txt,
- Templates/CPack.GenericWelcome.txt,
- Templates/DLLHeader.dsptemplate, Templates/EXEHeader.dsptemplate,
- Templates/EXEWinHeader.dsptemplate: ENH: merge changes from main
- tree
-
-2006-04-20 15:49 hoffman
-
- * Source/cmMakefile.h: ENH: fix .. in the path of subdirs
-
-2006-04-20 15:49 hoffman
-
- * Source/cmGlobalGenerator.cxx: ENH: don't add package target if no
- package file is around
-
-2006-04-20 15:28 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: VS7 seems to have
- a limit on the length of the link directory list string. Try to
- make the string as short as possible by avoiding trailing slashes
- and using a relative path (if it is shorter).
-
-2006-04-20 10:51 hoffman
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: ENH: fix help for
- global targets
-
-2006-04-20 10:23 andy
-
- * Modules/: CMakeGenericSystem.cmake, Platform/HP-UX.cmake,
- Platform/Linux-ifort.cmake, Platform/Linux.cmake,
- Platform/kFreeBSD.cmake: ENH: Cleanup link libraries. Remove -l
- from -ldl
-
-2006-04-20 10:22 andy
-
- * Source/cmakemain.cxx: ENH: Add help for graphviz
-
-2006-04-20 10:20 andy
-
- * Docs/cmake-syntax.vim: STYLE: Add missing command
-
-2006-04-20 09:59 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Changed color
- scheme to be more readable on both white and black backgrounds.
-
-2006-04-20 09:54 andy
-
- * Templates/: CPack.GenericDescription.txt,
- CPack.GenericLicense.txt, CPack.GenericWelcome.txt: ENH: Simplify
- the generic instructions
-
-2006-04-20 09:32 hoffman
-
- * CTestCustom.ctest.in: ENH: add ignore for xcode
-
-2006-04-19 17:23 hoffman
-
- * Modules/: CheckCSourceCompiles.cmake,
- CheckCXXSourceCompiles.cmake: ENH: append to log files
-
-2006-04-19 16:51 hoffman
-
- * CMakeLists.txt: ENH: update cpack stuff to match old cmake
- releases
-
-2006-04-19 16:36 hoffman
-
- * Modules/Platform/Windows-cl.cmake, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmMakefileExecutableTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.cxx: ENH: name pdb files for
- visual studio make based builds
-
-2006-04-19 15:29 hoffman
-
- * Modules/Platform/Windows-cl.cmake: ENH: unix makefiles should
- work with cl
-
-2006-04-19 12:58 hoffman
-
- * ChangeLog.txt: ENH: put cvs2cl changelog to match branch
-
-2006-04-19 12:30 hoffman
-
- * ChangeLog.manual: ENH: add changelog for 2.4
-
-2006-04-19 12:29 hoffman
-
- * ChangeLog.txt: ENH: create new change log with cvs2cl
-
-2006-04-19 11:14 hoffman
-
- * Modules/Platform/Windows-cl.cmake: ENH: don't need two of these
-
-2006-04-19 10:56 hoffman
-
- * Modules/Platform/Windows-cl.cmake: ENH: test for vs8 correctly
-
-2006-04-19 10:50 king
-
- * Source/: cmBootstrapCommands.cxx, cmCommands.cxx: BUG: Need
- ADD_DEPENDENCIES command for MinGW bootstrap since kwsys uses the
- Win32 implementation of process execution.
-
-2006-04-19 10:34 king
-
- * Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio6Generator.h,
- Templates/DLLHeader.dsptemplate, Templates/EXEHeader.dsptemplate,
- Templates/EXEWinHeader.dsptemplate: BUG: VS6 generator now uses
- ComputeLinkInformation just like all other generators.
-
-2006-04-19 10:11 hoffman
-
- * Modules/Platform/Windows-cl.cmake: ENH: check for version 1400
-
-2006-04-19 08:06 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-18 16:40 hoffman
-
- * CMakeLists.txt: ENH: make cpack names match old cmake release
- process
-
-2006-04-18 15:32 hoffman
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: ENH: put global
- targets in the help
-
-2006-04-18 15:30 hoffman
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: BUG: make sure help
- has global targets
-
-2006-04-18 14:48 hoffman
-
- * CMakeLists.txt, Source/cmCPluginAPI.h: ENH: move version numbers
- to 2.5.0
-
-2006-04-18 14:48 hoffman
-
- * CMakeLists.txt, Source/cmCPluginAPI.h, Utilities/Release/README:
- ENH: move version numbers to 2.4.0
-
-2006-04-18 11:53 king
-
- * Source/cmLocalVisualStudio6Generator.cxx: BUG: Do not require
- language flags variables. Other generators do not, and it breaks
- programmable language support (like the Java test).
-
-2006-04-18 11:50 barre
-
- * Source/kwsys/SystemTools.cxx: ENH: try to bypass Microsoft
- assert() on isspace, isalpha, etc.
-
-2006-04-18 11:45 king
-
- * Source/cmLocalVisualStudio6Generator.cxx,
- Templates/DLLHeader.dsptemplate, Templates/EXEHeader.dsptemplate,
- Templates/EXEWinHeader.dsptemplate,
- Templates/staticLibHeader.dsptemplate,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: Updated VS6 generator
- to use target.GetFullName() to compute target file names.
-
-2006-04-18 10:56 king
-
- * Source/: cmSetTargetPropertiesCommand.h, cmTarget.cxx: ENH: Added
- <config>_OUTPUT_NAME target property to allow the output name to
- be set on a per-configuration basis.
-
-2006-04-18 10:32 andy
-
- * Docs/: cmake-indent.vim, cmake-syntax.vim: ENH: Cleanup header
- and make license compatible with VIM
-
-2006-04-18 10:32 andy
-
- * Source/CPack/: cmCPackGenericGenerator.cxx,
- cmCPackSTGZGenerator.cxx: ENH: Remove some debugging
-
-2006-04-18 10:30 king
-
- * Source/: cmFileCommand.cxx, cmInstallCommand.h: BUG: Using the
- source-file permissions by default for installation is somewhat
- unpredictable because users can extract source code with almost
- any permissions (umask). Changing the default to use 644 for
- files and 755 for programs. No release has documented the old
- behavior so we do not need compatibility.
-
-2006-04-18 10:27 king
-
- * Source/cmIfCommand.h: BUG: Fixed missing false values in
- documentation of IF command.
-
-2006-04-18 10:01 king
-
- * Modules/CPack.cmake: BUG: Need to ignore source packaging of #*#
- files created by emacs during editing.
-
-2006-04-18 09:24 andy
-
- * Source/CPack/cmCPackSTGZGenerator.cxx: COMP: Remove non-existent
- header
-
-2006-04-18 08:25 andy
-
- * Modules/CPack.STGZ_Header.sh.in, Source/cmFileCommand.cxx,
- Source/CPack/cmCPackGenericGenerator.cxx,
- Source/CPack/cmCPackGenericGenerator.h,
- Source/CPack/cmCPackSTGZGenerator.cxx,
- Source/CPack/cmCPackSTGZGenerator.h, Source/CPack/cpack.cxx: ENH:
- More cleanups and add stgz header script, so it does not have to
- be hard-coded. Also, the user can overwrite it
-
-2006-04-18 08:17 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-17 19:02 andy
-
- * bootstrap: ENH: Fix copyright year
-
-2006-04-17 18:10 hoffman
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt,
- Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/complex.cxx: ENH: remove
- duplicate file name test because it fails on xcode
-
-2006-04-17 16:06 andy
-
- * Source/cmGlobalGenerator.cxx: BUG: Verify the global target name
- exists before using it. Fixes VS and Xcode
-
-2006-04-17 15:55 hoffman
-
- * Modules/FindX11.cmake: ENH: fix find x11 on the mac
-
-2006-04-17 15:35 hoffman
-
- * Source/cmLocalGenerator.cxx: ENH: fix java for ide builds again
-
-2006-04-17 15:26 andy
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalUnixMakefileGenerator3.h: ENH: Add packaging of source
- code (make package_source)
-
-2006-04-17 14:13 malaterre
-
- * Source/kwsys/CMakeLists.txt: COMP: Fix compilation on linux
- (dlopen/dlclose symbols)
-
-2006-04-17 14:00 hoffman
-
- * Modules/CMakeJavaInformation.cmake, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.cxx: ENH: fix java and add
- OBJECT_DIR support
-
-2006-04-17 13:59 hoffman
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- Complex/Executable/complex.cxx,
- Complex/Executable/Sub1/NameConflictTest.c,
- Complex/Executable/Sub2/NameConflictTest.c,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexOneConfig/Executable/Sub1/NameConflictTest.c,
- ComplexOneConfig/Executable/Sub2/NameConflictTest.c,
- ComplexRelativePaths/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/complex.cxx,
- ComplexRelativePaths/Executable/Sub1/NameConflictTest.c,
- ComplexRelativePaths/Executable/Sub2/NameConflictTest.c: ENH:
- allow multiple files with the same name in different sub dirs
- test
-
-2006-04-17 13:58 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: ENH: allow multiple
- files with the same name in different subdirs
-
-2006-04-17 13:57 hoffman
-
- * Modules/CMakeDetermineCXXCompiler.cmake: ENH: add mingw test to
- cxx
-
-2006-04-17 13:57 hoffman
-
- * Modules/Platform/Windows-gcc.cmake: ENH: add windows apps to
- mingw
-
-2006-04-17 07:56 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-16 13:49 andy
-
- * Docs/cmake-syntax.vim: ENH: Cleanup, make case insensitive,
- remove macro since it does not work anyway
-
-2006-04-16 08:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-15 13:02 andy
-
- * Modules/CPack.cmake, Source/CPack/cmCPackGenericGenerator.cxx,
- Source/CPack/cmCPackGenericGenerator.h,
- Source/CPack/cmCPackNSISGenerator.cxx,
- Source/CPack/cmCPackNSISGenerator.h,
- Source/CPack/cmCPackPackageMakerGenerator.cxx,
- Source/CPack/cmCPackPackageMakerGenerator.h,
- Source/CPack/cmCPackSTGZGenerator.cxx,
- Source/CPack/cmCPackSTGZGenerator.h,
- Source/CPack/cmCPackTGZGenerator.cxx,
- Source/CPack/cmCPackTGZGenerator.h,
- Source/CPack/cmCPackZIPGenerator.cxx,
- Source/CPack/cmCPackZIPGenerator.h: ENH: Support for packaging
- source, several cleanups and more yeehaa...
-
-2006-04-15 08:12 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-14 15:08 hoffman
-
- * Modules/FindX11.cmake: ENH: make sure frameworks are not searched
- for x header files
-
-2006-04-14 09:13 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-14 09:02 hoffman
-
- * Source/CMakeLists.txt: ENH: fix syntax
-
-2006-04-14 08:58 andy
-
- * Modules/CPack.cmake, Source/CPack/cmCPackGenericGenerator.cxx,
- Templates/CPackConfig.cmake.in: ENH: Start adding support for
- packaging component and to package into a subdirectory
-
-2006-04-14 08:44 hoffman
-
- * Source/CMakeLists.txt: ENH: make sure cmake can be built with an
- older version of cmake
-
-2006-04-13 23:24 hoffman
-
- * Source/cmFindProgramCommand.cxx: ENH: fix warning
-
-2006-04-13 23:15 hoffman
-
- * Source/: cmDocumentation.cxx, cmDocumentation.h, cmakemain.cxx:
- ENH: search for help modules in the correct place for install and
- source tree builds
-
-2006-04-13 22:57 king
-
- * Source/cmFileCommand.cxx: BUG: Fixed install rules to use
- copy-if-different.
-
-2006-04-13 22:56 king
-
- * Source/kwsys/SystemTools.cxx: ENH: Improved implementation of
- FilesDiffer to avoid allocating enough memory for the entire file
- twice. Instead using a block-at-a-time comparison.
-
-2006-04-13 15:28 king
-
- * Tests/CustomCommand/wrapper.cxx: COMP: Do not use ANSI function
- prototypes to pacify HP.
-
-2006-04-13 11:00 hoffman
-
- * bootstrap, Modules/Platform/Darwin.cmake, Source/CMakeLists.txt,
- Source/cmFindBase.cxx, Source/cmFindBase.h,
- Source/cmFindProgramCommand.cxx, Source/cmFindProgramCommand.h,
- Source/kwsys/SystemTools.cxx, Source/kwsys/SystemTools.hxx.in:
- ENH: add patch for finding applications on OSX
-
-2006-04-13 10:15 king
-
- * Source/: cmGlobalUnixMakefileGenerator3.h,
- cmGlobalWatcomWMakeGenerator.cxx, cmMakefileTargetGenerator.cxx:
- BUG: Work-around Watcom WMake limitation for multiple-output
- custom command support.
-
-2006-04-13 08:02 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-12 22:04 king
-
- * Source/cmInstallCommand.cxx, Source/cmInstallCommand.h,
- Source/cmInstallScriptGenerator.cxx,
- Source/cmInstallScriptGenerator.h,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstall/InstallScript1.cmake,
- Tests/SimpleInstall/InstallScript2.cmake,
- Tests/SimpleInstallS2/CMakeLists.txt,
- Tests/SimpleInstallS2/InstallScript1.cmake,
- Tests/SimpleInstallS2/InstallScript2.cmake: ENH: Added
- INSTALL(CODE) mode to allow inline specification of install
- script code. This reduces the need for configuring an install
- script that needs some variable settings because the install code
- can set thing up first.
-
-2006-04-12 21:24 andy
-
- * Docs/cmake-indent.vim: ENH: Unify the comment
-
-2006-04-12 21:20 andy
-
- * Docs/cmake-syntax.vim: ENH: More system variables, more
- operators, more commands, fix some string issues and some cmake
- arguments issues
-
-2006-04-12 15:23 hoffman
-
- * Source/CMakeLists.txt: ENH: lang by custom command does not yet
- work for Xcode
-
-2006-04-12 11:56 martink
-
- * Source/cmGlobalGenerator.cxx: COMP: fix warning
-
-2006-04-12 11:36 martink
-
- * Source/cmGlobalGenerator.h: ENH: fix compile issue on HP
- hopefully
-
-2006-04-12 09:12 hoffman
-
- * Source/cmDocumentation.cxx: ENH: case insensitive command help
-
-2006-04-12 08:15 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-11 22:39 hoffman
-
- * Source/cmake.cxx: ENH: add more verbose output in verbose mode
-
-2006-04-11 22:39 hoffman
-
- * Source/cmMakefile.cxx: ENH: fix re-run of cmake based on
- configured files that are done with copy if different and never
- change
-
-2006-04-11 17:11 hoffman
-
- * Source/: CMakeLists.txt, cmLocalGenerator.cxx: ENH: enable test
- for java with IDE builds
-
-2006-04-11 16:55 king
-
- * Modules/CMakeCInformation.cmake,
- Modules/CMakeCXXInformation.cmake,
- Modules/CMakeFortranInformation.cmake,
- Modules/Platform/Windows-bcc32.cmake,
- Modules/Platform/Windows-cl.cmake,
- Modules/Platform/Windows-icl.cmake,
- Modules/Platform/Windows-ifort.cmake,
- Modules/Platform/Windows-wcl386.cmake,
- Source/cmLocalGenerator.cxx,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx: ENH: Split
- CMAKE_STANDARD_LIBRARIES into per-language variables
- CMAKE_<lang>_STANDARD_LIBRARIES. This is needed to get
- programmable language support working with Visual Studio
- generators. It makes sense anyway.
-
-2006-04-11 14:54 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: Use flag-map
- transform only for C and C++ flags.
-
-2006-04-11 14:53 king
-
- * Source/cmLocalGenerator.cxx: ENH: Restored implementation of
- AddCustomCommandToCreateObject. Updated it to use newer custom
- command functionality.
-
-2006-04-11 13:32 king
-
- * Source/cmLocalGenerator.cxx: BUG: Install scripts should honor
- EXCLUDE_FROM_ALL options for subdirectories. This addresses
- bug#3100.
-
-2006-04-11 12:51 martink
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmLocalUnixMakefileGenerator3.cxx, cmMakefile.cxx, cmMakefile.h:
- ENH: some performance optimizations
-
-2006-04-11 11:40 king
-
- * Source/cmLocalGenerator.cxx: BUG: Do not add non-per-config
- subdirectory name of cmake target libraries as full path libs.
-
-2006-04-11 11:06 king
-
- * Source/cmAddCustomCommandCommand.cxx,
- Source/cmAddCustomCommandCommand.h, Source/cmCustomCommand.cxx,
- Source/cmCustomCommand.h, Source/cmGlobalGenerator.cxx,
- Source/cmGlobalGenerator.h,
- Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmGlobalUnixMakefileGenerator3.h,
- Source/cmGlobalVisualStudio8Generator.cxx,
- Source/cmGlobalXCodeGenerator.cxx, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio6Generator.h,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmMakefileTargetGenerator.cxx,
- Source/cmake.cxx, Tests/CustomCommand/CMakeLists.txt,
- Tests/CustomCommand/wrapper.cxx: ENH: Added support for multiple
- outputs generated by a single custom command. For Visual Studio
- generators the native tool provides support. For Xcode and
- Makefile generators a simple trick is used. The first output is
- considered primary and has the build rule attached. Other
- outputs simply depend on the first output with no build rule.
- During cmake_check_build_system CMake detects when a secondary
- output is missing and removes the primary output to make sure all
- outputs are regenerated. This approach always builds the custom
- command at the right time and only once even during parallel
- builds.
-
-2006-04-11 10:04 king
-
- * Source/cmMakefile.h: BUG: Fixed typo in new cmake-rerun code.
-
-2006-04-11 08:56 andy
-
- * Source/cmCTest.cxx: BUG: The fast mode should not read
- CTestCustom.ctest files
-
-2006-04-11 08:16 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-10 13:52 hoffman
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx, cmMakefile.cxx,
- cmMakefile.h: ENH: add support for re-running cmake if the
- cmakefiles change
-
-2006-04-10 13:52 hoffman
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ENH: add test for mfc
-
-2006-04-10 13:47 hoffman
-
- * Source/cmFileCommand.cxx: ENH: handle single path
-
-2006-04-10 13:46 hoffman
-
- * Modules/: CMakeVS6FindMake.cmake, CMakeVS71FindMake.cmake,
- CMakeVS7FindMake.cmake, CMakeVS8FindMake.cmake,
- InstallRequiredSystemLibraries.cmake: ENH: add correct flags for
- msvc generators
-
-2006-04-10 13:44 andy
-
- * Modules/CPack.cmake, Source/cmGlobalGenerator.h,
- Source/ctest.cxx, Source/CPack/cmCPackGenericGenerator.cxx: ENH:
- Add support for preinstall for cmake generated projects when
- packaging them
-
-2006-04-10 11:39 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: fix so all configurations
- show up
-
-2006-04-10 11:09 andy
-
- * Modules/CPack.cmake, Source/CPack/cmCPackGenericGenerator.cxx:
- ENH: Deprecate CPACK_BINARY_DIR and add
- CPACK_INSTALL_CMAKE_PROJECTS
-
-2006-04-10 09:36 andy
-
- * CTestCustom.ctest.in: ENH: Some ctest custom fixes
-
-2006-04-10 08:10 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-09 08:15 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-09 07:45 andy
-
- * Source/: cmCTest.cxx, cmCTest.h, CTest/cmCTestBuildHandler.cxx,
- CTest/cmCTestReadCustomFilesCommand.cxx: BUG: Improve the
- behavior of the ReadCustomFilesCommand
-
-2006-04-08 14:15 hoffman
-
- * Source/: cmLocalKdevelopGenerator.cxx,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: make sure verbose output is
- used for kde
-
-2006-04-08 08:23 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-07 16:46 hoffman
-
- * Modules/Platform/: Windows-cl.cmake, Windows-cl.cmake.in: ENH:
- add better variables for MSVC versions
-
-2006-04-07 16:35 andy
-
- * Modules/CPack.cmake: ENH: Allow to overwrite CPACK_BINARY_DIR
-
-2006-04-07 07:40 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-06 07:39 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-05 11:07 king
-
- * Source/cmOrderLinkDirectories.cxx: COMP: Moved var decl out of
- _WIN32 block.
-
-2006-04-05 11:05 king
-
- * Source/: cmLocalGenerator.cxx, cmOrderLinkDirectories.cxx: BUG:
- Fixed cmOrderLinkDirectories to deal with raw link items that do
- not yet exist and correct drive letter case to avoid duplicate
- paths on windows. Fixed cmLocalGenerator to pass CMake targets
- as full paths to cmOrderLinkDirectories to make sure the ordering
- will pick up the proper target libraries.
-
-2006-04-05 07:46 hoffman
-
- * Source/: cmFileCommand.cxx, cmFileCommand.h: ENH: add path
- conversion stuff and rm SYSTEM_PATH
-
-2006-04-05 07:31 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-04 17:27 hoffman
-
- * Modules/CMakeVS8FindMake.cmake: ENH: add search directories for
- 32 bit devenv from a 64bit cmake
-
-2006-04-04 17:14 king
-
- * Source/cmLocalGenerator.cxx: BUG: Removing part of earlier fix
- because it does not work with VS generators. It may be restored
- later after cmOrderLinkDirs is further fixed.
-
-2006-04-04 14:53 king
-
- * Source/cmSetTargetPropertiesCommand.h: ENH: Added documentation
- for COMPILE_FLAGS property and clarified meaning of
- DEFINE_SYMBOL.
-
-2006-04-04 14:25 king
-
- * Source/cmLocalGenerator.cxx, Source/cmOrderLinkDirectories.cxx,
- Source/cmOrderLinkDirectories.h,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/complex.cxx: BUG: Fixed
- cmOrderLinkDirectories to make sure cmake-built libraries are
- found properly. Also taking libraries that will be built but may
- not yet exist into account. The per-configuration subdirectories
- that are included by generators in the link path are checked for
- conflicting libraries also. Potentially conflicting libraries
- that are actually symlinks back to the desired library are no
- longer considered conflicting, which avoids bogus impossible
- ordering warnings.
-
-2006-04-04 14:25 martink
-
- * Source/cmakexbuild.cxx: BUG: compiler fix
-
-2006-04-04 13:04 martink
-
- * Source/: cmCTest.cxx, cmCTest.h, cmForEachCommand.cxx,
- cmSystemTools.cxx, cmSystemTools.h, cmakexbuild.cxx, ctest.cxx,
- CTest/cmCTestRunScriptCommand.cxx,
- CTest/cmCTestRunScriptCommand.h, CTest/cmCTestScriptHandler.cxx,
- CTest/cmCTestScriptHandler.h: ENH: added support for -SP scripts
- in new processes
-
-2006-04-04 11:52 hoffman
-
- * Source/cmOrderLinkDirectories.cxx,
- Source/cmOrderLinkDirectories.h,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/complex.cxx: ENH: change
- library order to use a vector
-
-2006-04-04 11:48 king
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmLocalGenerator.cxx, cmLocalGenerator.h, cmTarget.h: ENH: Added
- global TargetManifest computation between Configure and Generate
- steps. This allows generators to know what other targets will
- exist on disk when the build completes.
-
-2006-04-04 09:35 king
-
- * Source/: cmIncludeDirectoryCommand.cxx,
- cmIncludeDirectoryCommand.h: ENH: INCLUDE_DIRECTORIES should have
- been written to prepend to the include path so that the most
- local directories are included first. This is a patch from Alex
- to resolve the problem by allowing users to switch the default
- using a variable CMAKE_INCLUDE_DIRECTORIES_BEFORE and then still
- explicitly appending or prepending by using AFTER or BEFORE
- arguments explicitly.
-
-2006-04-04 07:38 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-03 22:05 hoffman
-
- * Source/cmGlobalGenerator.cxx: ENH: use correct addcache call to
- fix build tools
-
-2006-04-03 17:54 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: fix spaces in path for
- xcode
-
-2006-04-03 16:20 hoffman
-
- * Source/: cmIncludeDirectoryCommand.cxx,
- cmLinkDirectoriesCommand.cxx: ENH: make sure include and lib dirs
- are unix paths
-
-2006-04-03 15:59 hoffman
-
- * Source/cmFileCommand.cxx: ENH: fix warning, and remove debug code
-
-2006-04-03 12:57 hoffman
-
- * Source/: cmLocalGenerator.cxx, cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx,
- cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx,
- cmSetTargetPropertiesCommand.h: ENH: add support for per config
- target LINK_FLAGS
-
-2006-04-03 07:37 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-02 11:20 andy
-
- * Source/: CMakeLists.txt, CPack/cmCPackGenerators.cxx,
- CPack/cmCPackGenericGenerator.cxx,
- CPack/cmCPackNSISGenerator.cxx,
- CPack/cmCPackPackageMakerGenerator.cxx,
- CPack/cmCPackZIPGenerator.cxx, CPack/cmCPackZIPGenerator.h,
- CPack/cpack.cxx: ENH: Add ZIP generator and add support for
- including or excluding the toplevel directory
-
-2006-04-02 08:35 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-04-01 07:37 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-31 21:43 hoffman
-
- * Source/: cmOrderLinkDirectories.cxx, cmOrderLinkDirectories.h:
- ENH: fix spelling
-
-2006-03-31 17:59 hoffman
-
- * Source/cmOrderLinkDirectories.cxx: ENH: fix for bug 3067 the
- first framework ate the rest of the libraries
-
-2006-03-31 13:17 hoffman
-
- * bootstrap, Source/CMakeLists.txt, Source/cmGlobalGenerator.cxx,
- Source/cmGlobalXCodeGenerator.cxx,
- Source/cmTryCompileCommand.cxx, Source/cmakemain.cxx,
- Source/cmakexbuild.cxx: ENH: add a wrapper for xcodebuild to get
- around bug and verbose output
-
-2006-03-31 08:46 hoffman
-
- * Utilities/cmcurl/getdate.c: ENH: remove c++ comment from c code
-
-2006-03-31 08:13 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-30 23:03 hoffman
-
- * Utilities/cmtar/append.c: ENH: remove warning
-
-2006-03-30 17:26 hoffman
-
- * Source/cmakexbuild.cxx: ENH: add program to run xcodebuild and
- get around bug
-
-2006-03-30 16:55 king
-
- * Modules/Platform/Windows-cl.cmake: BUG: Fixed order of options to
- cl for 32-bit/64-bit test to work with VS 6 NMake.
-
-2006-03-30 15:39 king
-
- * Source/: cmGlobalBorlandMakefileGenerator.cxx,
- cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalKdevelopGenerator.cxx, cmGlobalMSYSMakefileGenerator.cxx,
- cmGlobalMinGWMakefileGenerator.cxx,
- cmGlobalNMakeMakefileGenerator.cxx,
- cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalWatcomWMakeGenerator.cxx,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h,
- cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx: ENH: Implemented VT100 terminal
- escape sequences. If CMAKE_COLOR_MAKEFILE is set then messages
- produced by makefiles will be in color if the native tool
- supports it. This addresses bug#3060.
-
-2006-03-30 13:49 hoffman
-
- * Modules/Platform/Windows-cl.cmake,
- Modules/Platform/Windows-cl.cmake.in, Source/CMakeLists.txt,
- Source/cmCommandArgumentParserHelper.cxx,
- Source/cmDependsJavaParserHelper.cxx,
- Source/cmExecuteProcessCommand.cxx, Source/cmGlobalGenerator.cxx,
- Source/cmGlobalVisualStudio8Generator.cxx,
- Source/cmGlobalVisualStudio8Generator.h,
- Source/cmGlobalVisualStudio8Win64Generator.cxx,
- Source/cmGlobalVisualStudio8Win64Generator.h,
- Source/cmIfCommand.cxx, Source/cmListCommand.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h, Source/cmXMLParser.cxx,
- Source/cmake.cxx, Source/CTest/cmCTestHandlerCommand.cxx,
- Source/CTest/cmCTestMemCheckHandler.cxx,
- Source/CTest/cmCTestSubmitHandler.cxx,
- Source/kwsys/CommandLineArguments.cxx, Source/kwsys/Glob.cxx,
- Source/kwsys/ProcessWin32.c, Source/kwsys/Registry.cxx,
- Source/kwsys/SystemTools.cxx, Source/kwsys/hashtable.hxx.in,
- Source/kwsys/testDynamicLoader.cxx,
- Utilities/cmcurl/CMakeLists.txt, Utilities/cmcurl/getdate.c,
- Utilities/cmcurl/inet_pton.c, Utilities/cmcurl/md5.c,
- Utilities/cmcurl/mprintf.c, Utilities/cmtar/CMakeLists.txt,
- Utilities/cmtar/append.c, Utilities/cmtar/block.c,
- Utilities/cmtar/extract.c, Utilities/cmtar/handle.c,
- Utilities/cmtar/output.c, Utilities/cmtar/compat/snprintf.c: ENH:
- add support for win64 for visual studio 2005 ide and nmake, also
- fix warnings produced by building for win64
-
-2006-03-30 13:33 king
-
- * Source/: cmFileCommand.cxx, cmGlobalGenerator.cxx,
- cmGlobalGenerator.h, cmInstallCommand.cxx, cmInstallCommand.h,
- cmInstallFilesGenerator.cxx, cmInstallFilesGenerator.h,
- cmInstallGenerator.cxx, cmInstallGenerator.h,
- cmInstallTargetGenerator.cxx, cmInstallTargetGenerator.h,
- cmLocalGenerator.cxx: ENH: Added named component installation
- implementation. Installation behavior should be unchanged unless
- -DCOMPONENT=<name> is specified when cmake_install.cmake is
- invoked.
-
-2006-03-30 11:55 hoffman
-
- * Source/: cmFileCommand.cxx, cmFindBase.cxx, cmFindBase.h: ENH:
- make sure framework search order is correct
-
-2006-03-30 09:17 martink
-
- * Source/cmGlobalGenerator.cxx: ENH: modified the relative path
- code to not do relative paths between bin and source
-
-2006-03-30 08:38 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-29 16:34 andy
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: Use
- PBXResourcesBuildPhase for resrources
-
-2006-03-29 16:34 hoffman
-
- * Modules/Platform/Darwin.cmake: ENH: use correct name for path
-
-2006-03-29 16:25 andy
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: Simplify. Instead of
- doing ../MacOS just copy to current directory
-
-2006-03-29 16:21 andy
-
- * Source/cmXCode21Object.cxx: ENH: Add support for Xcode 2.1
-
-2006-03-29 15:02 andy
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmXCodeObject.cxx,
- cmXCodeObject.h: ENH: Add copy stages for bundle files
-
-2006-03-29 13:33 hoffman
-
- * Source/cmFindBase.cxx, Tests/BundleTest/CMakeLists.txt: ENH: add
- a test for find framework stuff in find_library, and fix the
- framework search stuff
-
-2006-03-29 13:26 hoffman
-
- * Source/kwsys/CMakeLists.txt: ENH: remove test on cygwin since it
- randomly fails
-
-2006-03-29 12:33 andy
-
- * Source/CTest/: cmCTestBuildCommand.cxx,
- cmCTestConfigureCommand.cxx, cmCTestCoverageCommand.cxx,
- cmCTestSubmitCommand.cxx, cmCTestUpdateCommand.cxx: COMP: Return
- 0 instead of false
-
-2006-03-29 12:01 andy
-
- * Source/cmCTest.cxx, Source/cmCTest.h,
- Source/CTest/cmCTestBuildCommand.cxx,
- Source/CTest/cmCTestBuildCommand.h,
- Source/CTest/cmCTestBuildHandler.cxx,
- Source/CTest/cmCTestConfigureCommand.cxx,
- Source/CTest/cmCTestConfigureCommand.h,
- Source/CTest/cmCTestCoverageCommand.cxx,
- Source/CTest/cmCTestCoverageCommand.h,
- Source/CTest/cmCTestCoverageHandler.cxx,
- Source/CTest/cmCTestHandlerCommand.cxx,
- Source/CTest/cmCTestMemCheckHandler.cxx,
- Source/CTest/cmCTestSubmitCommand.cxx,
- Source/CTest/cmCTestSubmitCommand.h,
- Source/CTest/cmCTestTestCommand.h,
- Source/CTest/cmCTestTestHandler.cxx,
- Source/CTest/cmCTestUpdateCommand.cxx,
- Source/CTest/cmCTestUpdateCommand.h,
- Tests/CTestTest3/test.cmake.in: ENH: Several cleanups and make
- sure things get propagated where they should. Also, allow to load
- CTest custom files to the actual ctest -S script
-
-2006-03-29 09:10 andy
-
- * Source/cmSetSourceFilesPropertiesCommand.cxx: COMP: Remove
- warning
-
-2006-03-29 08:31 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-28 16:36 andy
-
- * Source/CTest/cmCTestReadCustomFilesCommand.cxx,
- Tests/CTestTest3/test.cmake.in: BUG: Fix the read custom files
- command and add a coverage test
-
-2006-03-28 16:25 andy
-
- * Source/: cmLocalGenerator.cxx, cmTarget.cxx: COMP: Remove
- warnings
-
-2006-03-28 15:20 andy
-
- * Source/cmCTest.cxx: ENH: Pass handler flags to both test and
- memcheck handler
-
-2006-03-28 15:19 andy
-
- * Source/: CMakeLists.txt, cmCTest.h: ENH: Add new ctest command
-
-2006-03-28 14:45 king
-
- * Source/cmFindBase.cxx: ENH: Added check of
- CMAKE_BACKWARDS_COMPATIBILITY to skip the CMake system path
- search when simulating CMake 2.2 and earlier.
-
-2006-03-28 14:37 andy
-
- * Source/CTest/: cmCTestReadCustomFilesCommand.cxx,
- cmCTestReadCustomFilesCommand.h, cmCTestScriptHandler.cxx: ENH:
- Add command to read ctest custom files
-
-2006-03-28 13:48 andy
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Handle spaces in
- the path
-
-2006-03-28 13:23 andy
-
- * Tests/BundleTest/: BundleLib.cxx, BundleTest.cxx: ENH: Check if
- files exist
-
-2006-03-28 13:16 andy
-
- * Source/: cmFileCommand.cxx, cmInstallGenerator.cxx,
- cmInstallTargetGenerator.cxx, cmTarget.h: ENH: Add proper support
- for installing bundles
-
-2006-03-28 13:07 alex
-
- * Modules/FindKDE4.cmake: STYLE: better error message when KDE4
- hasn't been found
-
- Alex
-
-2006-03-28 10:58 king
-
- * Source/cmInstallTargetGenerator.cxx: BUG: Pay attention to the
- MACOSX_BUNDLE target property only on APPLE platforms.
-
-2006-03-28 08:54 andy
-
- * Modules/Platform/Darwin.cmake,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmMakefileExecutableTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.h,
- Source/cmSetSourceFilesPropertiesCommand.cxx,
- Tests/BundleTest/CMakeLists.txt,
- Tests/BundleTest/SomeRandomFile.txt,
- Tests/BundleTest/randomResourceFile.plist.in: ENH: Add support
- for adding content to bundles
-
-2006-03-28 08:22 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-27 12:21 hoffman
-
- * Modules/Platform/UnixPaths.cmake: ENH: add /opt/local/include
-
-2006-03-27 11:09 hoffman
-
- * Modules/Platform/: FreeBSD.cmake, OpenBSD.cmake: ENH: add unix
- paths
-
-2006-03-27 10:46 hoffman
-
- * Modules/Platform/: FreeBSD.cmake, HP-UX.cmake, IRIX.cmake,
- IRIX64.cmake, NetBSD.cmake, OSF1.cmake, SCO_SV.cmake,
- SINIX.cmake, Tru64.cmake, ULTRIX.cmake, UNIX_SV.cmake,
- UnixPaths.cmake, UnixWare.cmake, Xenix.cmake, kFreeBSD.cmake:
- ENH: add more search paths and add UnixPaths to all unix
- platforms
-
-2006-03-27 08:13 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-26 08:10 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-25 08:11 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-24 16:13 hoffman
-
- * Source/cmListCommand.cxx: ENH: allow unset vars to be used in
- list length
-
-2006-03-24 16:11 king
-
- * CMakeLists.txt, Source/cmInstallCommand.cxx,
- Source/cmInstallCommand.h, Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: Added ARCHIVE option
- to the TARGETS mode of the INSTALL command. It is a third option
- added to RUNTIME and LIBRARY property types. Static libraries
- and import libraries are now treated as ARCHIVE targets instead
- of LIBRARY targets. This adds a level of granularity necessary
- for upcoming features. Also updated the CVS CMake patch level
- set in CMake_VERSION_PATCH from 4 to 5 to allow users of this
- version to know whether this incompatible change is present.
-
-2006-03-24 14:47 king
-
- * Modules/FindPythonLibs.cmake: ENH: Updated implementation to use
- new FIND_* command power. The correct library is now found on
- MinGW also.
-
-2006-03-24 14:16 king
-
- * Source/: cmFindBase.cxx, cmFindBase.h: ENH: Added
- NO_CMAKE_ENVIRONMENT_PATH, NO_CMAKE_PATH,
- NO_SYSTEM_ENVIRONMENT_PATH, and NO_CMAKE_SYSTEM_PATH options back
- to allow more granularity than NO_DEFAULT_PATH.
-
-2006-03-24 14:15 king
-
- * Modules/Platform/UnixPaths.cmake: BUG: Fix '/use/lib' to be
- '/usr/lib'.
-
-2006-03-24 12:20 martink
-
- * Tests/CustomCommand/: CMakeLists.txt,
- GeneratedHeader/CMakeLists.txt: BUG: fix test to list generate
- dheader
-
-2006-03-24 09:15 hoffman
-
- * Modules/Platform/Darwin.cmake, Source/cmGlobalXCodeGenerator.cxx,
- Source/cmLocalGenerator.cxx, Source/cmLocalGenerator.h,
- Source/cmLocalXCodeGenerator.cxx, Source/cmTryCompileCommand.cxx,
- Tests/ExternalOBJ/CMakeLists.txt,
- Tests/ExternalOBJ/Object/CMakeLists.txt,
- Tests/X11/CMakeLists.txt: ENH: add support for universal binaries
-
-2006-03-24 08:17 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-23 15:35 andy
-
- * Source/CTest/cmCTestBuildAndTestHandler.cxx: COMP: Remove warning
-
-2006-03-23 13:55 martink
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: ENH: removed unused rules from
- targets for VS
-
-2006-03-23 11:19 andy
-
- * Source/cmCTest.cxx: BUG: Fix CTestCustom.ctest file
-
-2006-03-23 10:10 hoffman
-
- * CTestCustom.ctest.in: ENH: try to get rid of warning on HP
-
-2006-03-23 09:56 andy
-
- * Source/CTest/cmCTestBuildHandler.cxx: ENH: More error handling
-
-2006-03-23 08:13 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-22 17:21 hoffman
-
- * Source/cmExecuteProcessCommand.cxx: ENH: do not dereference empty
- stl vectors
-
-2006-03-22 15:01 martink
-
- * Tests/: Complex/VarTests.cmake,
- Complex/Executable/CMakeLists.txt,
- Complex/Executable/Included.cmake,
- Complex/Executable/complex.cxx, ComplexOneConfig/VarTests.cmake,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/Included.cmake,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/VarTests.cmake,
- ComplexRelativePaths/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/Included.cmake,
- ComplexRelativePaths/Executable/complex.cxx: ENH: added testing
- for new features
-
-2006-03-22 14:45 andy
-
- * Source/cmMakefile.cxx: BUG: Fix logic. If the variable is not
- set, then it is always ok to write the file
-
-2006-03-22 14:40 andy
-
- * Source/: cmAddCustomCommandCommand.cxx,
- cmConfigureFileCommand.cxx, cmExecuteProcessCommand.cxx,
- cmFileCommand.cxx, cmMakeDirectoryCommand.cxx, cmMakefile.cxx,
- cmMakefile.h, cmWriteFileCommand.cxx: ENH: Allow blocking of
- writing into the source tree
-
-2006-03-22 14:06 martink
-
- * Source/: cmGetDirectoryPropertyCommand.h,
- cmGetSourceFilePropertyCommand.cxx,
- cmGetSourceFilePropertyCommand.h, cmIfCommand.cxx, cmIfCommand.h,
- cmMakefile.cxx, cmMakefile.h, cmSourceFile.cxx: ENH: added some
- new functionality
-
-2006-03-22 13:04 andy
-
- * Source/: cmBootstrapCommands.cxx, cmCommands.cxx, cmake.cxx:
- COMP: Fix apple bootstrap issues
-
-2006-03-22 11:14 andy
-
- * Source/cmBootstrapCommands.cxx,
- Modules/CheckCSourceCompiles.cmake,
- Modules/CheckCXXSourceCompiles.cmake, Source/cmCommands.cxx,
- Source/cmWriteFileCommand.cxx: ENH: Cleanup bootstrap even more
-
-2006-03-22 11:10 king
-
- * Modules/Platform/Windows-gcc.cmake, Source/cmLocalGenerator.cxx:
- ENH: Added support for linking to MS .lib libraries in MinGW.
-
-2006-03-22 09:58 andy
-
- * bootstrap, Source/cmMakefile.cxx, Source/cmMakefile.h,
- Source/cmakemain.cxx: ENH: Remove things from bootstrap
-
-2006-03-22 08:11 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-21 17:47 barre
-
- * Source/kwsys/SystemTools.cxx: ENH: the arguments to this function
- were not checked in a robust way
-
-2006-03-21 16:59 andy
-
- * CMakeLists.txt: ENH: Add flag for MFC
-
-2006-03-21 16:58 andy
-
- * Modules/InstallRequiredSystemLibraries.cmake: ENH: Handle visual
- studio versions
-
-2006-03-21 16:39 andy
-
- * Source/cmCTest.cxx: ENH: Two things. If there is
- CTestCustom.cmake in the toplevel directory read that file only.
- If there is CTestCustom.ctest in the toplevel directory, do the
- glob, if there is none, do nothing
-
-2006-03-21 16:03 andy
-
- * Source/cmFileCommand.cxx, Source/cmFileCommand.h,
- Tests/StringFileTest/CMakeLists.txt: ENH: Add relative tag and
- add test for relative tag
-
-2006-03-21 16:02 andy
-
- * Source/kwsys/: Glob.cxx, Glob.hxx.in: ENH: Add support for
- relative paths and cleanup
-
-2006-03-21 16:01 andy
-
- * Source/cmCTest.cxx: BUG: Handle visual studio 8
-
-2006-03-21 12:56 alex
-
- * Modules/FindKDE3.cmake: BUG: put the path to the kde3 lib dir in
- KDE3_LIB_DIR, not the complete libkdecore.so
-
- Alex
-
-2006-03-21 12:54 andy
-
- * bootstrap, Source/CMakeLists.txt, Source/cmCTest.cxx,
- Source/cmCacheManager.cxx, Source/cmFileCommand.cxx,
- Source/cmFindPathCommand.cxx, Source/cmGlob.cxx, Source/cmGlob.h,
- Source/CTest/cmCTestCoverageHandler.cxx: ENH: Remove cmGlob and
- use glob from kwsys
-
-2006-03-21 08:45 king
-
- * Source/cmLocalGenerator.cxx: ENH: Enabling
- CMAKE_INCLUDE_CURRENT_DIR even for in-source builds to be more
- consistent with its name. This also makes double-quote and
- angle-bracket include styles (almost) identical.
-
-2006-03-21 08:20 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-20 16:24 andy
-
- * Source/CPack/cmCPackPackageMakerGenerator.cxx: ENH: Handle
- unusual path for packagemaker
-
-2006-03-20 12:29 alex
-
- * Modules/: AddFileDependencies.cmake, FindPNG.cmake,
- KDE3Macros.cmake: BUG: don't include MacroLibrary.cmake, but add
- a cmake module which implements ADD_FILE_DEPENDENCIES() ENH: mark
- the variables from FindPNG.cmake as advanced
-
- Alex
-
-2006-03-20 07:55 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-19 07:53 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-18 12:23 hoffman
-
- * CTestCustom.ctest.in: ENH: add more warning stuff
-
-2006-03-18 12:16 alex
-
- * Modules/FindKDE3.cmake: STYLE: fix typos
-
- Alex
-
-2006-03-18 08:59 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-17 16:30 andy
-
- * Source/cmConfigure.cmake.h.in: ENH: Propagate cmake variables to
- macros in C
-
-2006-03-17 16:14 andy
-
- * CMakeLists.txt, Source/CMakeLists.txt, Source/cmSystemTools.cxx:
- ENH: Simplify the test
-
-2006-03-17 15:47 andy
-
- * Source/CMakeLists.txt: COMP: Use the current cmake's
- CheckCXXSourceCompiles
-
-2006-03-17 15:46 andy
-
- * Source/: CMakeLists.txt, cmSystemTools.cxx, cmSystemTools.h,
- cmake.cxx: ENH: Handle missing unsetenv and add check for environ
-
-2006-03-17 15:33 hoffman
-
- * Source/cmSystemTools.cxx: ENH: make cmake compile
-
-2006-03-17 12:31 andy
-
- * Source/cmSystemTools.cxx: COMP: Fix windows
-
-2006-03-17 12:24 andy
-
- * Source/cmSystemTools.cxx: COMP: Handle windows with hack for now
-
-2006-03-17 12:06 malaterre
-
- * Source/kwsys/: Directory.cxx, Directory.hxx.in, SystemTools.cxx,
- SystemTools.hxx.in: ENH: Use const char where it should have
- been. At same time fix Bug#2958
-
-2006-03-17 11:44 andy
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Add a method to
- remove environment variables
-
-2006-03-17 11:14 andy
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h, cmake.cxx: ENH: Use
- vector of plain strings and add cmake -E command for getting
- environment
-
-2006-03-17 10:58 andy
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Add access for
- all environment variables
-
-2006-03-17 09:32 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-16 18:24 king
-
- * Source/cmGlobalGenerator.cxx: BUG: When generating the install
- rules for CMake itself the per-configuration subdirectory must be
- used to specify the executable location.
-
-2006-03-16 17:49 hoffman
-
- * Source/: cmFindBase.cxx, cmFindBase.h: ENH: clean up find stuff
- so that NO_SYSTEM_PATH is backwards compatible and you get put
- system env variables in the find commands
-
-2006-03-16 17:40 king
-
- * Modules/Platform/Windows-cl.cmake: BUG: /DWIN32 and /D_WINDOWS
- should be defined for all configurations or if no configuration
- is set.
-
-2006-03-16 17:26 king
-
- * Source/kwsys/auto_ptr.hxx.in: COMP: Skip trying to use native
- auto_ptr implementation and just provide a conforming one.
-
-2006-03-16 17:20 king
-
- * Tests/: Complex/cmTestConfigure.h.in,
- Complex/Executable/complex.cxx,
- ComplexOneConfig/cmTestConfigure.h.in,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/cmTestConfigure.h.in,
- ComplexRelativePaths/Executable/complex.cxx: BUG: Removed
- compiled-in CMAKE_SHARED_MODULE_PREFIX and
- CMAKE_SHARED_MODULE_SUFFIX for loaded commands in favor of using
- the settings from the platform files.
-
-2006-03-16 17:09 king
-
- * Source/: cmConfigure.cmake.h.in, cmDynamicLoader.cxx,
- cmDynamicLoader.h, cmLoadCommandCommand.cxx: BUG: Removed
- compiled-in CMAKE_SHARED_MODULE_PREFIX and
- CMAKE_SHARED_MODULE_SUFFIX for loaded commands in favor of using
- the settings from the platform files.
-
-2006-03-16 17:07 king
-
- * Modules/CMakeSystemSpecificInformation.cmake: BUG: When copying
- the module variables from shared library variables use double
- quotes for the required definitions ...PREFIX and ...SUFFIX to
- make sure a value is set even if it is empty.
-
-2006-03-16 16:04 king
-
- * Source/cmExportLibraryDependencies.cxx: COMP: Using KWSys
- auto_ptr to avoid cross-platform problems.
-
-2006-03-16 16:04 king
-
- * Source/kwsys/: CMakeLists.txt, auto_ptr.hxx.in: ENH: Adding
- auto_ptr to KWSys to provide a conforming version everywhere.
-
-2006-03-16 15:53 alex
-
- * Modules/FindKDE4.cmake: ENH: after searching for kde-config in
- the special dirs, search again in the standard dirs BUG: handle
- paths on windows correctly
-
- Alex
-
-2006-03-16 15:50 king
-
- * Source/cmExportLibraryDependencies.cxx: COMP: Fix for auto_ptr
- usage on VC6's broken implementation.
-
-2006-03-16 14:51 king
-
- * Source/cmLocalGenerator.cxx: BUG: Fixed generation of mismatched
- IF in install script. This bug was introduced during the m_
- sweep.
-
-2006-03-16 14:44 king
-
- * Source/: cmCommandArgumentParser.cxx, cmCommandArgumentParser.y:
- COMP: Fix malloc/free declaration for windows compilers.
-
-2006-03-16 14:14 king
-
- * Source/cmExportLibraryDependencies.cxx: BUG: Do not leak the
- ofstream object in append mode. Just use an auto_ptr for both
- cases.
-
-2006-03-16 11:57 king
-
- * Source/: cmCommandArgumentParser.cxx, cmCommandArgumentParser.y,
- cmCommandArgumentParserTokens.h: ENH: Using patch from Frans
- Englich to clarify error messages.
-
-2006-03-16 11:34 andy
-
- * Source/CTest/cmCTestTestHandler.h: COMP: Make members protected
- so that subclass can use them
-
-2006-03-16 11:29 andy
-
- * Source/CTest/: cmCTestMemCheckHandler.cxx,
- cmCTestTestHandler.cxx: BUG: Couple of memcheck bugs: Log files
- should really be different for test and memcheck. Also make sure
- to not trunkate the output of the test until the valgrind or any
- other checking is pefrormed.
-
-2006-03-16 11:28 hoffman
-
- * Source/CursesDialog/cmCursesMainForm.cxx: ENH: not all messages
- are errors
-
-2006-03-16 11:27 hoffman
-
- * Source/cmOrderLinkDirectories.cxx: ENH: don't put the default
- framework path in a -F option
-
-2006-03-16 11:21 andy
-
- * Source/kwsys/DynamicLoader.hxx.in: COMP: Fix problem with
- namespace
-
-2006-03-16 11:15 king
-
- * Modules/Platform/FreeBSD.cmake: ENH: Enabling soname support on
- FreeBSD.
-
-2006-03-16 11:01 andy
-
- * Source/cmDynamicLoader.cxx, Source/cmDynamicLoader.h,
- Source/cmLoadCommandCommand.cxx, Source/cmSystemTools.cxx,
- Source/cmakemain.cxx, Source/kwsys/DynamicLoader.cxx,
- Source/kwsys/DynamicLoader.hxx.in,
- Source/kwsys/testDynamicLoader.cxx, Source/kwsys/testDynload.c,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/complex.cxx: ENH: Cleanup
- DynamicLoader so that the symbols have more consistent names,
- start using dynamic loader from kwsys in CMake
-
-2006-03-16 10:53 martink
-
- * Source/: cmGlobalGenerator.h, cmLocalVisualStudio7Generator.h,
- cmLocalXCodeGenerator.h, cmMakefile.h: STYLE: minor comment
- cleanups
-
-2006-03-16 10:44 martink
-
- * Source/CursesDialog/: cmCursesBoolWidget.cxx,
- cmCursesCacheEntryComposite.cxx, cmCursesCacheEntryComposite.h,
- cmCursesDummyWidget.cxx, cmCursesFilePathWidget.cxx,
- cmCursesForm.cxx, cmCursesForm.h, cmCursesLabelWidget.cxx,
- cmCursesLongMessageForm.cxx, cmCursesLongMessageForm.h,
- cmCursesMainForm.cxx, cmCursesMainForm.h, cmCursesPathWidget.cxx,
- cmCursesPathWidget.h, cmCursesStringWidget.cxx,
- cmCursesStringWidget.h, cmCursesWidget.cxx, cmCursesWidget.h:
- ENH: m_ cleanup for curses
-
-2006-03-16 09:33 martink
-
- * Source/: cmAddTestCommand.h, cmData.h, cmDependsC.cxx,
- cmDependsC.h, cmStandardIncludes.h, cmUseMangledMesaCommand.h,
- cmVariableRequiresCommand.h: ENH: a warning fix and some more
- cleanup
-
-2006-03-16 09:17 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-15 16:32 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: fix warning
-
-2006-03-15 14:14 hoffman
-
- * Modules/Platform/IRIX64.cmake: ENH: use c not cxx
-
-2006-03-15 13:20 alex
-
- * Modules/UsePkgConfig.cmake: BUG: change the formatting of the
- pkgconfig module documentation so that it doesn't crash some
- versions of konqueror (fixed with current konqy)
-
- Alex
-
-2006-03-15 12:02 hoffman
-
- * Source/: cmGlobalXCode21Generator.cxx,
- cmGlobalXCodeGenerator.cxx, cmake.cxx: ENH: fix up this changes
- for mac
-
-2006-03-15 11:38 martink
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmMakeDepend.cxx,
- cmMakeDepend.h, cmXCodeObject.cxx, cmXCodeObject.h: BUG: some
- UNIX fixes for my m_ commit
-
-2006-03-15 11:26 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-15 11:01 martink
-
- * Source/: cmAddCustomCommandCommand.cxx,
- cmAddCustomTargetCommand.cxx, cmAddDefinitionsCommand.cxx,
- cmAddDependenciesCommand.cxx, cmAddExecutableCommand.cxx,
- cmAddLibraryCommand.cxx, cmAddLibraryCommand.h,
- cmAddSubDirectoryCommand.cxx, cmAddTestCommand.cxx,
- cmAuxSourceDirectoryCommand.cxx, cmBuildCommand.cxx,
- cmBuildNameCommand.cxx, cmCMakeMinimumRequired.cxx,
- cmCPluginAPI.cxx, cmCTest.cxx, cmCTest.h, cmCacheManager.cxx,
- cmCacheManager.h, cmCommand.h, cmCommandArgumentLexer.cxx,
- cmCommandArgumentParserHelper.cxx,
- cmCommandArgumentParserHelper.h, cmConfigureFileCommand.cxx,
- cmConfigureFileCommand.h, cmCreateTestSourceList.cxx,
- cmCustomCommand.cxx, cmCustomCommand.h, cmDepends.cxx,
- cmDepends.h, cmDependsC.cxx, cmDependsC.h, cmDependsFortran.cxx,
- cmDependsFortran.h, cmDependsFortranLexer.cxx,
- cmDependsJavaLexer.cxx, cmDynamicLoader.cxx,
- cmEnableLanguageCommand.cxx, cmEnableTestingCommand.cxx,
- cmEndIfCommand.cxx, cmExecProgramCommand.cxx,
- cmExecuteProcessCommand.cxx, cmExportLibraryDependencies.cxx,
- cmExportLibraryDependencies.h, cmExprLexer.cxx,
- cmExprParserHelper.cxx, cmExprParserHelper.h,
- cmFLTKWrapUICommand.cxx, cmFLTKWrapUICommand.h,
- cmFileCommand.cxx, cmFileTimeComparison.cxx,
- cmFileTimeComparison.h, cmFindBase.cxx, cmFindLibraryCommand.cxx,
- cmFindPackageCommand.cxx, cmFindPathCommand.cxx,
- cmFindProgramCommand.cxx, cmForEachCommand.cxx,
- cmForEachCommand.h, cmGeneratedFileStream.cxx,
- cmGeneratedFileStream.h, cmGetCMakePropertyCommand.cxx,
- cmGetDirectoryPropertyCommand.cxx,
- cmGetFilenameComponentCommand.cxx,
- cmGetSourceFilePropertyCommand.cxx,
- cmGetTargetPropertyCommand.cxx, cmGetTestPropertyCommand.cxx,
- cmGlob.cxx, cmGlob.h, cmGlobalBorlandMakefileGenerator.cxx,
- cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalKdevelopGenerator.cxx, cmGlobalMSYSMakefileGenerator.cxx,
- cmGlobalMinGWMakefileGenerator.cxx,
- cmGlobalNMakeMakefileGenerator.cxx,
- cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio71Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h,
- cmGlobalVisualStudio8Generator.cxx,
- cmGlobalWatcomWMakeGenerator.cxx, cmGlobalXCode21Generator.cxx,
- cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h,
- cmIfCommand.cxx, cmIfCommand.h, cmIncludeCommand.cxx,
- cmIncludeDirectoryCommand.cxx,
- cmIncludeExternalMSProjectCommand.cxx,
- cmIncludeRegularExpressionCommand.cxx, cmInstallCommand.cxx,
- cmInstallFilesCommand.cxx, cmInstallFilesCommand.h,
- cmInstallProgramsCommand.cxx, cmInstallProgramsCommand.h,
- cmInstallTargetGenerator.cxx, cmInstallTargetsCommand.cxx,
- cmLinkDirectoriesCommand.cxx, cmLinkLibrariesCommand.cxx,
- cmListCommand.cxx, cmListFileCache.cxx, cmListFileCache.h,
- cmLoadCacheCommand.cxx, cmLoadCommandCommand.cxx,
- cmLocalGenerator.cxx, cmLocalGenerator.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio6Generator.h,
- cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h, cmMacroCommand.cxx,
- cmMacroCommand.h, cmMakeDepend.cxx, cmMakeDepend.h,
- cmMakefile.cxx, cmMakefile.h,
- cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx, cmMakefileTargetGenerator.h,
- cmMarkAsAdvancedCommand.cxx, cmMathCommand.cxx,
- cmMessageCommand.cxx, cmOptionCommand.cxx,
- cmOrderLinkDirectories.cxx, cmOrderLinkDirectories.h,
- cmOutputRequiredFilesCommand.cxx, cmOutputRequiredFilesCommand.h,
- cmProjectCommand.cxx, cmQTWrapCPPCommand.cxx,
- cmQTWrapCPPCommand.h, cmQTWrapUICommand.cxx, cmQTWrapUICommand.h,
- cmRemoveCommand.cxx, cmRemoveDefinitionsCommand.cxx,
- cmSeparateArgumentsCommand.cxx, cmSetCommand.cxx,
- cmSetDirectoryPropertiesCommand.cxx,
- cmSetSourceFilesPropertiesCommand.cxx,
- cmSetTargetPropertiesCommand.cxx,
- cmSetTestsPropertiesCommand.cxx, cmSiteNameCommand.cxx,
- cmSourceFile.cxx, cmSourceFile.h, cmSourceGroup.cxx,
- cmSourceGroup.h, cmSourceGroupCommand.cxx, cmStringCommand.cxx,
- cmSubdirCommand.cxx, cmTarget.cxx, cmTarget.h,
- cmTargetLinkLibrariesCommand.cxx, cmTargetLinkLibrariesCommand.h,
- cmTest.cxx, cmTest.h, cmTryCompileCommand.cxx,
- cmTryRunCommand.cxx, cmUtilitySourceCommand.cxx,
- cmVTKMakeInstantiatorCommand.cxx, cmVTKMakeInstantiatorCommand.h,
- cmVTKWrapJavaCommand.cxx, cmVTKWrapJavaCommand.h,
- cmVTKWrapPythonCommand.cxx, cmVTKWrapPythonCommand.h,
- cmVTKWrapTclCommand.cxx, cmVTKWrapTclCommand.h,
- cmVariableRequiresCommand.cxx, cmVariableWatch.cxx,
- cmVariableWatch.h, cmWhileCommand.cxx, cmWhileCommand.h,
- cmWin32ProcessExecution.cxx, cmWin32ProcessExecution.h,
- cmWriteFileCommand.cxx, cmXCode21Object.cxx, cmXCodeObject.cxx,
- cmXCodeObject.h, cmake.cxx, cmake.h, cmakemain.cxx,
- cmakewizard.cxx, cmakewizard.h, CTest/cmCTestBuildCommand.cxx,
- CTest/cmCTestConfigureCommand.cxx,
- CTest/cmCTestCoverageCommand.cxx,
- CTest/cmCTestHandlerCommand.cxx,
- CTest/cmCTestMemCheckCommand.cxx, CTest/cmCTestStartCommand.cxx,
- CTest/cmCTestSubmitCommand.cxx, CTest/cmCTestTestCommand.cxx,
- CTest/cmCTestTestHandler.cxx, CTest/cmCTestUpdateCommand.cxx:
- STYLE: some m_ to this-> cleanup
-
-2006-03-15 09:23 andy
-
- * Source/CTest/cmCTestUpdateHandler.cxx: ENH: Add svn cleanup
- before running svn
-
-2006-03-15 09:22 andy
-
- * Source/CPack/cmCPackGenericGenerator.cxx: ENH: Allow multiple
- install directories
-
-2006-03-14 16:38 hoffman
-
- * Modules/FindOpenGL.cmake: ENH: go back to finding the framework
- opengl on the mac
-
-2006-03-14 15:19 hoffman
-
- * Modules/FindOpenGL.cmake: ENH: use standard include path for
- OpenGL
-
-2006-03-14 14:03 hoffman
-
- * Modules/Platform/Darwin.cmake,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.cxx,
- Source/cmMakefileTargetGenerator.h: ENH: add support for removing
- language flags from shared library and shared module link
- commands
-
-2006-03-14 11:35 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Fixed object file
- name construction to use Convert method for relative path
- conversion. Also fixed test of result to check explicitly for a
- full path.
-
-2006-03-14 10:14 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Avoid full paths
- and spaces when constructing object file names.
-
-2006-03-14 09:37 king
-
- * Source/cmMakefile.cxx: BUG: Clarified confusing error message.
-
-2006-03-14 02:31 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-13 16:45 andy
-
- * Source/CPack/cmCPackGenericGenerator.h: STYLE: Fix style checker
-
-2006-03-13 15:57 malaterre
-
- * Source/kwsys/testDynamicLoader.cxx: COMP: Fix warning
-
-2006-03-13 15:19 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: Introducing new
- policy to construct more unique object file names. This should
- allow multiple sources with the same file name but different FULL
- paths to be added to a single target.
-
-2006-03-13 14:39 malaterre
-
- * Source/kwsys/: DynamicLoader.cxx, testDynamicLoader.cxx: BUG: Fix
- problem on MacOSX, by disabling part of the test.
-
-2006-03-13 13:11 hoffman
-
- * Modules/VTKCompatibility.cmake: ENH: add backwards compatibility
- fix for more aggressive find_path command
-
-2006-03-13 11:27 malaterre
-
- * Source/kwsys/DynamicLoader.cxx: ENH: Fix dashboard with coverage
-
-2006-03-13 10:49 malaterre
-
- * Source/kwsys/CMakeLists.txt: ENH: Do not build the library if we
- are not doing Testing
-
-2006-03-13 10:27 malaterre
-
- * Source/kwsys/testDynamicLoader.cxx: ENH: Make test usable from
- command line
-
-2006-03-13 02:31 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-12 10:03 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: remove warning
-
-2006-03-12 09:43 hoffman
-
- * Source/CMakeLists.txt: ENH: remove test until it works
-
-2006-03-12 02:26 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-11 12:43 hoffman
-
- * Modules/FindOpenGL.cmake: ENH: take advantage of new framework
- stuff
-
-2006-03-11 11:53 hoffman
-
- * Source/cmake.cxx: ENH: remove print
-
-2006-03-11 11:52 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: try to clean up the search for
- programs
-
-2006-03-11 10:09 malaterre
-
- * Source/kwsys/DynamicLoader.cxx: BUG: Fix for MINGW32
-
-2006-03-11 09:59 malaterre
-
- * Source/kwsys/DynamicLoader.cxx: ENH: Add support for LastError on
- HPUX
-
-2006-03-11 09:47 malaterre
-
- * Source/kwsys/DynamicLoader.cxx: ENH: Also look into data segment
- (consistant with other implementation)
-
-2006-03-11 02:33 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-10 17:37 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: undo last change because it
- broke the dashboard
-
-2006-03-10 16:53 hoffman
-
- * Source/: cmFileCommand.cxx, cmFileCommand.h: ENH: add a new FILE
- SYSTEM_PATH that allows you to read a environment variable with a
- path in it.
-
-2006-03-10 16:52 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: fix find program to look for
- .com and .exe correctly and not return files with no extension on
- windows
-
-2006-03-10 16:03 malaterre
-
- * Source/kwsys/: DynamicLoader.hxx.in, SystemTools.hxx.in: ENH: Add
- documentation on the problem with system wide path for looking up
- dynamic libraries. STYLE: Fix trailing white spaces
-
-2006-03-10 15:42 malaterre
-
- * Source/kwsys/testDynamicLoader.cxx: BUG: Need a / for Visual
- Studio build
-
-2006-03-10 15:38 malaterre
-
- * Source/kwsys/: testDynamicLoader.cxx, testSystemTools.h.in: BUG:
- Do the proper path
-
-2006-03-10 15:12 malaterre
-
- * Source/kwsys/testDynamicLoader.cxx: BUG: Need a trailing slash
-
-2006-03-10 15:08 malaterre
-
- * Source/kwsys/: CMakeLists.txt, testDynamicLoader.cxx,
- testSystemTools.h.in: BUG: Fix problem with in the path
-
-2006-03-10 15:03 andy
-
- * Source/: cmCTest.cxx, cmCTest.h,
- CTest/cmCTestBuildAndTestHandler.cxx,
- CTest/cmCTestBuildAndTestHandler.h,
- CTest/cmCTestBuildCommand.cxx, CTest/cmCTestBuildCommand.h,
- CTest/cmCTestBuildHandler.cxx, CTest/cmCTestBuildHandler.h,
- CTest/cmCTestCommand.h, CTest/cmCTestConfigureCommand.cxx,
- CTest/cmCTestConfigureCommand.h,
- CTest/cmCTestConfigureHandler.cxx,
- CTest/cmCTestCoverageCommand.cxx, CTest/cmCTestCoverageCommand.h,
- CTest/cmCTestCoverageHandler.cxx, CTest/cmCTestCoverageHandler.h,
- CTest/cmCTestEmptyBinaryDirectoryCommand.h,
- CTest/cmCTestGenericHandler.cxx, CTest/cmCTestGenericHandler.h,
- CTest/cmCTestHandlerCommand.cxx, CTest/cmCTestHandlerCommand.h,
- CTest/cmCTestMemCheckCommand.cxx, CTest/cmCTestMemCheckCommand.h,
- CTest/cmCTestMemCheckHandler.cxx, CTest/cmCTestMemCheckHandler.h,
- CTest/cmCTestRunScriptCommand.cxx,
- CTest/cmCTestRunScriptCommand.h, CTest/cmCTestScriptHandler.cxx,
- CTest/cmCTestScriptHandler.h, CTest/cmCTestSleepCommand.cxx,
- CTest/cmCTestSleepCommand.h, CTest/cmCTestStartCommand.cxx,
- CTest/cmCTestStartCommand.h, CTest/cmCTestSubmitCommand.cxx,
- CTest/cmCTestSubmitCommand.h, CTest/cmCTestSubmitHandler.cxx,
- CTest/cmCTestSubmitHandler.h, CTest/cmCTestTestCommand.cxx,
- CTest/cmCTestTestCommand.h, CTest/cmCTestTestHandler.cxx,
- CTest/cmCTestTestHandler.h, CTest/cmCTestUpdateCommand.cxx,
- CTest/cmCTestUpdateCommand.h, CTest/cmCTestUpdateHandler.cxx,
- CTest/cmCTestUpdateHandler.h: STYLE: Fix some style issues
-
-2006-03-10 14:53 malaterre
-
- * Source/kwsys/: CMakeLists.txt, testDynamicLoader.cxx,
- testSystemTools.h.in: BUG: Trying to get testDynamicLoader to
- work on Solaris and SunOS, where current directory is not lookup
- when doing dlopen
-
-2006-03-10 13:54 hoffman
-
- * Source/: cmCommandArgumentLexer.h,
- cmDependsFortranParserTokens.h, cmDependsJavaLexer.h,
- cmDependsJavaParserHelper.h, cmDependsJavaParserTokens.h,
- cmExecProgramCommand.h, cmExprLexer.h, cmExprParserTokens.h,
- cmFLTKWrapUICommand.h, cmFileCommand.h, cmFindBase.h,
- cmGlobalBorlandMakefileGenerator.h, cmGlobalGenerator.h,
- cmGlobalMSYSMakefileGenerator.h,
- cmGlobalMinGWMakefileGenerator.h,
- cmGlobalNMakeMakefileGenerator.h,
- cmGlobalUnixMakefileGenerator3.h,
- cmGlobalVisualStudio6Generator.h,
- cmGlobalVisualStudio71Generator.h,
- cmGlobalVisualStudio7Generator.h, cmGlobalWatcomWMakeGenerator.h,
- cmGlobalXCodeGenerator.h, cmListCommand.h, cmLocalGenerator.h,
- cmLocalUnixMakefileGenerator3.h, cmSourceFile.cxx,
- cmStringCommand.cxx, cmSystemTools.cxx, cmTarget.cxx,
- cmTargetLinkLibrariesCommand.cxx, cmTryCompileCommand.cxx,
- cmTryRunCommand.cxx, cmUseMangledMesaCommand.cxx,
- cmUtilitySourceCommand.cxx, cmVTKMakeInstantiatorCommand.cxx,
- cmVTKWrapJavaCommand.cxx, cmVTKWrapPythonCommand.cxx,
- cmVTKWrapTclCommand.cxx, cmVariableRequiresCommand.cxx,
- cmVariableWatch.cxx, cmVariableWatch.h, cmWhileCommand.cxx,
- cmWin32ProcessExecution.cxx, cmXCode21Object.cxx,
- cmXCodeObject.cxx, cmakemain.cxx: STYLE: fix line lengths
-
-2006-03-10 13:34 malaterre
-
- * Source/kwsys/SystemTools.cxx: STYLE: Remove trailing whitespaces
-
-2006-03-10 13:34 malaterre
-
- * Source/kwsys/: CMakeLists.txt, DynamicLoader.cxx: BUG: Fix
- DynamicLoader implementation on MacOSX (using old API)
-
-2006-03-10 13:33 malaterre
-
- * Source/kwsys/SystemTools.cxx: ENH: Add trailing whitespace
-
-2006-03-10 13:06 andy
-
- * Source/: cmAddCustomCommandCommand.cxx,
- cmAddCustomTargetCommand.cxx, cmAddDefinitionsCommand.cxx,
- cmAddDefinitionsCommand.h, cmAddDependenciesCommand.cxx,
- cmAddExecutableCommand.h, cmBuildCommand.cxx,
- cmBuildNameCommand.h, cmCMakeMinimumRequired.cxx,
- cmCPluginAPI.cxx, cmCPluginAPI.h, cmCacheManager.cxx,
- cmCommandArgumentParser.cxx, cmCommandArgumentParserHelper.h,
- cmCommandArgumentParserTokens.h, cmCreateTestSourceList.cxx,
- cmCustomCommand.cxx, cmDependsC.cxx, cmDependsC.h,
- cmDependsFortranLexer.cxx, cmDependsFortranLexer.h,
- cmLocalVisualStudio7Generator.cxx, cmMacroCommand.cxx,
- cmMacroCommand.h, cmMakeDepend.cxx, cmake.cxx, cmakewizard.cxx,
- CPack/cmCPackGenerators.cxx, CPack/cmCPackGenerators.h,
- CPack/cmCPackGenericGenerator.cxx,
- CPack/cmCPackGenericGenerator.h, CPack/cmCPackLog.cxx,
- CPack/cmCPackLog.h, CPack/cmCPackNSISGenerator.cxx,
- CPack/cmCPackNSISGenerator.h,
- CPack/cmCPackPackageMakerGenerator.cxx,
- CPack/cmCPackSTGZGenerator.cxx, CPack/cmCPackSTGZGenerator.h,
- CPack/cmCPackTGZGenerator.cxx, CPack/cmCPackTGZGenerator.h,
- CPack/cpack.cxx: STYLE: Fix some style issues
-
-2006-03-10 12:47 andy
-
- * Source/CPack/cmCPackPackageMakerGenerator.cxx: STYLE: Cleanup
- trailing spaces
-
-2006-03-10 12:01 malaterre
-
- * Source/kwsys/: Glob.cxx, Registry.cxx, RegularExpression.cxx,
- testCommandLineArguments.cxx: STYLE: Make sure to use the proper
- cast.
-
-2006-03-10 11:58 alex
-
- * Modules/FindKDE4.cmake: ENH: new module to find the
- FindKDE4Internal.cmake installed by kdelibs4
-
- Alex
-
-2006-03-10 11:57 malaterre
-
- * Source/kwsys/: DynamicLoader.cxx, testDynamicLoader.cxx: ENH:
- Make sure that we find the proper symbol and not the one that
- start with _. STYLE: Remove an old style cast
-
-2006-03-10 11:32 malaterre
-
- * Source/kwsys/: DynamicLoader.cxx, testDynamicLoader.cxx: ENH:
- Hopefully have the DynamicLoader to the proper thing.
-
-2006-03-10 11:13 hoffman
-
- * Source/: cmCacheManager.h, cmLocalVisualStudio7Generator.h,
- cmMakeDepend.h, cmMakefile.h, cmOutputRequiredFilesCommand.h,
- cmProjectCommand.h, cmRemoveDefinitionsCommand.h,
- cmSetTestsPropertiesCommand.h, cmSourceGroup.h,
- cmStandardIncludes.h, cmStringCommand.h, cmSubdirCommand.h,
- cmSystemTools.h, cmTarget.h, cmTryCompileCommand.h,
- cmVariableWatch.h, cmXCode21Object.h, cmake.h: ENH: fix line
- length style stuff
-
-2006-03-10 11:12 hoffman
-
- * Source/cmFindBase.cxx: ENH: avoid adding junk into paths
-
-2006-03-10 10:28 malaterre
-
- * Source/kwsys/testDynamicLoader.cxx: BUG: Make sure to have proper
- dependencies
-
-2006-03-10 10:26 hoffman
-
- * Source/kwsys/CMakeLists.txt: ENH: use CMAKE_DL_LIBS and not dl
- directly as it does not always exist
-
-2006-03-10 10:23 malaterre
-
- * Source/kwsys/CMakeLists.txt: COMP: Fix cygwin build
-
-2006-03-10 10:19 malaterre
-
- * Source/kwsys/testDynload.c: COMP: Fix compilation on MacOSX
- (common symbols not allowed with MH_DYLIB output format)
-
-2006-03-10 10:12 andy
-
- * Source/CMakeLists.txt, Tests/BundleTest/CMakeLists.txt: ENH: Add
- package to bundle test
-
-2006-03-10 10:07 andy
-
- * Source/kwsys/testDynamicLoader.cxx: COMP: Add missing include
-
-2006-03-10 02:32 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-09 17:16 malaterre
-
- * Source/kwsys/testDynload.c: BUG: Remove comment
-
-2006-03-09 17:15 malaterre
-
- * Source/kwsys/: testDynamicLoader.cxx, testDynload.c: ENH: remove
- test temporarily
-
-2006-03-09 17:08 malaterre
-
- * Source/kwsys/: CMakeLists.txt, testDynamicLoader.cxx: ENH: Still
- more coverage of the DynamicLoader
-
-2006-03-09 17:06 malaterre
-
- * Source/kwsys/testDynload.c: ENH: Add a file to generate the lib
-
-2006-03-09 16:40 malaterre
-
- * Source/kwsys/testDynamicLoader.cxx: ENH: Improve test coverage
-
-2006-03-09 16:40 malaterre
-
- * Source/kwsys/: Registry.cxx, Registry.hxx.in: STYLE: Minor style
-
-2006-03-09 15:55 king
-
- * CMakeLists.txt: ENH: Updated patch level to 4 for special KDE
- release.
-
-2006-03-09 15:47 hoffman
-
- * Source/: cmCacheManager.cxx, cmCacheManager.h: ENH: if
- CMakeCache.txt has been removed, then automatically remove
- CMakefiles/*.cmake
-
-2006-03-09 15:00 hoffman
-
- * Modules/Platform/AIX.cmake: ENH: add correct initial flags for
- aix
-
-2006-03-09 14:57 hoffman
-
- * Modules/Platform/Darwin.cmake: ENH: remove junk
-
-2006-03-09 14:41 malaterre
-
- * Source/kwsys/CMakeLists.txt: ENH: Carefully turn testing of
- DynamicLib on
-
-2006-03-09 14:36 malaterre
-
- * Source/kwsys/: Directory.cxx, testSystemTools.cxx,
- DynamicLoader.cxx: STYLE: Minor style
-
-2006-03-09 14:35 malaterre
-
- * Source/kwsys/testDynamicLoader.cxx: ENH: Adding initial test for
- DynamicLoader
-
-2006-03-09 14:30 hoffman
-
- * Source/: cmFileCommand.cxx, cmFileCommand.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h,
- cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx: ENH: use a cmake script to do the
- clean step, this allows for large numbers of files to be removed
- without making the command line too long
-
-2006-03-09 14:10 alex
-
- * Modules/: FindKDE.cmake, FindKDE3.cmake, KDE3Macros.cmake,
- kde3init_dummy.cpp.in, kde3uic.cmake: ENH: add real-world-tested
- and used KDE3 support, and obsolete FindKDE.cmake, which wasn't
- used by anybody that I heard of
-
- Alex
-
-2006-03-09 11:57 andy
-
- * Source/: cmCTest.cxx, cmCTest.h, ctest.cxx: STYLE: Fix some style
- issues
-
-2006-03-09 11:35 hoffman
-
- * Modules/FindTCL.cmake, Source/cmFindPathCommand.cxx: ENH: fix a
- bug in the find path stuff so that it can find headers deep in
- frameworks
-
-2006-03-09 11:17 andy
-
- * Source/CTest/: cmCTestBuildAndTestHandler.cxx,
- cmCTestBuildCommand.cxx, cmCTestBuildHandler.cxx,
- cmCTestBuildHandler.h, cmCTestConfigureCommand.cxx,
- cmCTestConfigureCommand.h, cmCTestConfigureHandler.cxx,
- cmCTestConfigureHandler.h, cmCTestCoverageCommand.cxx,
- cmCTestCoverageCommand.h, cmCTestCoverageHandler.cxx,
- cmCTestCoverageHandler.h, cmCTestEmptyBinaryDirectoryCommand.h,
- cmCTestGenericHandler.cxx, cmCTestGenericHandler.h,
- cmCTestHandlerCommand.cxx, cmCTestHandlerCommand.h,
- cmCTestMemCheckCommand.h, cmCTestMemCheckHandler.cxx,
- cmCTestRunScriptCommand.cxx, cmCTestScriptHandler.cxx,
- cmCTestStartCommand.cxx, cmCTestStartCommand.h,
- cmCTestSubmitCommand.cxx, cmCTestSubmitCommand.h,
- cmCTestSubmitHandler.cxx, cmCTestTestCommand.cxx,
- cmCTestTestHandler.cxx, cmCTestTestHandler.h,
- cmCTestUpdateCommand.cxx, cmCTestUpdateCommand.h,
- cmCTestUpdateHandler.cxx: STYLE: Fix some style issues
-
-2006-03-09 09:53 andy
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Fix problem on
- Wacom system with global symbolic targets
-
-2006-03-09 08:32 andy
-
- * Source/CPack/: cmCPackGenericGenerator.cxx,
- cmCPackPackageMakerGenerator.cxx, cpack.cxx: STYLE: Fix style
- problems
-
-2006-03-09 08:20 andy
-
- * Utilities/: cmcurl/formdata.c, cmtar/libtar.h: COMP: Remove win64
- warnings
-
-2006-03-09 02:41 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-08 18:16 hoffman
-
- * Source/cmFindProgramCommand.cxx: ENH: make sure system path is
- not added unless asked for
-
-2006-03-08 17:11 alex
-
- * Modules/UsePkgConfig.cmake: ENH: add a cmake module for using
- pkg-config, tested in kdelibs, ok by Bill Hoffman
-
- Alex
-
-2006-03-08 16:33 andy
-
- * Source/CPack/: cmCPackGenerators.cxx, cmCPackGenerators.h,
- cmCPackGenericGenerator.cxx, cmCPackGenericGenerator.h,
- cmCPackLog.cxx, cmCPackLog.h, cmCPackNSISGenerator.cxx,
- cmCPackNSISGenerator.h, cmCPackPackageMakerGenerator.cxx,
- cmCPackPackageMakerGenerator.h, cmCPackSTGZGenerator.cxx,
- cmCPackSTGZGenerator.h, cmCPackTGZGenerator.cxx,
- cmCPackTGZGenerator.h, cpack.cxx: STYLE: Lots of formating to
- remove style problems
-
-2006-03-08 14:02 andy
-
- * Source/CMakeLists.txt, Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstall/InstallScript2.cmake,
- Tests/SimpleInstall/TestSubDir/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt,
- Tests/SimpleInstallS2/InstallScript2.cmake,
- Tests/SimpleInstallS2/TestSubDir/CMakeLists.txt: ENH: Add
- additional subdirectory to improve testing and to allow cleanup
- when testing cpack
-
-2006-03-08 13:59 andy
-
- * Source/CPack/cmCPackPackageMakerGenerator.cxx: BUG: Handle
- version with multiple dots
-
-2006-03-08 13:20 andy
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: COMP: Ok, fix typo
-
-2006-03-08 13:13 andy
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ENH: Add testing for cpack
-
-2006-03-08 13:06 king
-
- * Source/kwsys/ProcessUNIX.c: ENH: Enabled process tree killing on
- AIX.
-
-2006-03-08 12:42 king
-
- * Source/kwsys/ProcessUNIX.c: ENH: Enabled process tree killing on
- the SGI.
-
-2006-03-08 12:36 king
-
- * Source/kwsys/ProcessUNIX.c: ENH: Enabled process tree killing for
- FreeBSD and Sun.
-
-2006-03-08 12:12 king
-
- * Source/kwsys/ProcessUNIX.c: ENH: Enabled process tree killing on
- HP-UX.
-
-2006-03-08 11:57 king
-
- * Source/kwsys/ProcessUNIX.c: BUG: Do not leak ps FILE when the
- process starts but reading the header fails.
-
-2006-03-08 11:39 king
-
- * Source/kwsys/testProcess.c: ENH: Added a way to quickly enable
- manual testing of grandchild killing.
-
-2006-03-08 11:38 king
-
- * Source/kwsys/ProcessUNIX.c: ENH: Added implementation of process
- tree killing that runs "ps" to traverse the tree.
-
-2006-03-08 10:52 andy
-
- * Source/: cmListFileCache.cxx, cmListFileCache.h: BUG: Remove some
- old legacy code and remove memory leak
-
-2006-03-08 09:16 malaterre
-
- * Source/kwsys/: DynamicLoader.cxx, DynamicLoader.hxx.in: BUG:
- Including file within a namespace{} is dangerous(unless symbols
- are within an extern C). Also update documentation about special
- case for MacOSX
-
-2006-03-08 02:43 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-07 19:52 hoffman
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ENH: remove cpack stuff for now
- so that we can get mac dashboards again
-
-2006-03-07 15:31 andy
-
- * CMakeGraphVizOptions.cmake, Source/cmake.cxx: ENH: Add a way to
- overwrite some preferences and ignore certain targets
-
-2006-03-07 14:46 king
-
- * Source/cmake.cxx: ENH: Add CMAKE_COMMAND and CMAKE_ROOT variables
- when running in script mode. This partially addresses bug#2828.
-
-2006-03-07 14:38 king
-
- * Source/cmGlobalGenerator.cxx: BUG: Check for whether to add -C to
- package rule should check for a . in the first character not the
- second.
-
-2006-03-07 12:03 andy
-
- * Source/cmake.cxx: COMP: Fix warnings
-
-2006-03-07 10:05 king
-
- * Source/cmFileCommand.cxx: BUG: Most platforms other than Linux
- seem to require executable permissions on their shared libraries.
-
-2006-03-07 10:04 king
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: BUG: Some platforms require
- executable permission on shared libraries.
-
-2006-03-07 02:12 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-06 15:41 hoffman
-
- * bootstrap: ENH: add more depends for bootstrap
-
-2006-03-06 15:14 hoffman
-
- * Modules/Platform/Darwin.cmake: ENH: add support for language
- flags that allow for universal binaries
-
-2006-03-06 15:14 hoffman
-
- * Modules/CMakeCInformation.cmake,
- Modules/CMakeCXXInformation.cmake,
- Modules/CMakeFortranInformation.cmake,
- Modules/Platform/CYGWIN.cmake, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmMakefileLibraryTargetGenerator.cxx: ENH: add support for
- language flags at rule expansion time
-
-2006-03-06 15:01 hoffman
-
- * Modules/Platform/Windows-cl.cmake: ENH: add support for manifest
- stuff
-
-2006-03-06 14:30 malaterre
-
- * Source/kwsys/DynamicLoader.cxx: COMP: Fix compilation on MacOSX
-
-2006-03-06 14:08 hoffman
-
- * Modules/FindQt3.cmake: ENH: try to fix non-clean dashboards
-
-2006-03-06 14:07 malaterre
-
- * Source/kwsys/CMakeLists.txt: ENH: Compile DynamicLoader
-
-2006-03-06 14:02 malaterre
-
- * Source/kwsys/: DynamicLoader.cxx, DynamicLoader.hxx.in: ENH:
- Adding kwsys implementation for a DynamicLoader class. Copy from
- itkDynamicLoader, with patch from cmDynamicLoader
-
-2006-03-06 13:43 hoffman
-
- * Source/kwsys/: Directory.cxx, Registry.cxx: ENH: add missing
- cmake depend hacks
-
-2006-03-06 13:34 hoffman
-
- * Source/kwsys/Glob.cxx: ENH: add missing cmake include
-
-2006-03-06 13:02 malaterre
-
- * Source/kwsys/Directory.cxx: COMP: Some STL implementation do not
- provide clear on std::string
-
-2006-03-06 11:57 malaterre
-
- * Source/kwsys/: Directory.cxx, Directory.hxx.in: BUG: Need to
- reset internal structure in case of multiple calls to Load
-
-2006-03-06 10:12 malaterre
-
- * Source/kwsys/: Directory.cxx, Directory.hxx.in: ENH: Redo
- implementation of itkDirectory to use kwsys (avoid duplicating
- code).
-
-2006-03-06 02:11 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-05 09:09 king
-
- * Source/cmLocalGenerator.cxx: BUG: Fix for generated install
- scripts to support prefixes with trailing slashes or just a
- single slash.
-
-2006-03-05 08:38 hoffman
-
- * Source/cmFindBase.cxx: ENH: fix old style parsing of FIND
- commands and fix broken tests
-
-2006-03-05 02:11 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-04 02:22 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-03 23:00 hoffman
-
- * Source/cmFindBase.cxx: ENH: make sure NAMES tag is not required
- for name argument, fixes msys generator
-
-2006-03-03 19:29 king
-
- * Source/cmInstallCommand.cxx, Source/cmInstallCommand.h,
- Source/cmInstallTargetGenerator.cxx,
- Source/cmInstallTargetGenerator.h,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: Added PERMISSIONS
- option to the TARGETS mode of the INSTALL command.
-
-2006-03-03 18:44 king
-
- * Source/cmFileCommand.cxx, Source/cmInstallCommand.cxx,
- Source/cmInstallCommand.h, Source/cmInstallFilesGenerator.cxx,
- Source/cmInstallFilesGenerator.h, Source/cmInstallGenerator.cxx,
- Source/cmInstallGenerator.h, Source/cmLocalGenerator.cxx,
- Tests/SimpleInstall/CMakeLists.txt, Tests/SimpleInstall/inst.cxx,
- Tests/SimpleInstall/inst2.cxx,
- Tests/SimpleInstallS2/CMakeLists.txt,
- Tests/SimpleInstallS2/inst.cxx, Tests/SimpleInstallS2/inst2.cxx:
- ENH: Added PERMISSIONS and RENAME options to the INSTALL
- command's FILES and PROGRAMS mode, and corresponding support to
- FILE(INSTALL). Default permissions for shared libraries on
- non-Windows/non-OSX platforms no longer has the execute bit set.
-
-2006-03-03 18:06 king
-
- * Source/: cmTarget.cxx, cmTarget.h: ENH: Replaced UpdateLocation
- method with call to GetLocation. Added comment about problems
- with the LOCATION attribute.
-
-2006-03-03 15:04 andy
-
- * Source/CPack/: cmCPackPackageMakerGenerator.cxx,
- cmCPackPackageMakerGenerator.h: ENH: Check package maker version
-
-2006-03-03 14:28 andy
-
- * Source/cmake.cxx: COMP: Oops, typo
-
-2006-03-03 14:24 andy
-
- * Source/: cmTarget.cxx, cmTarget.h, cmake.cxx, cmake.h: ENH: Add
- support for exporting graphviz of the project dependencies
-
-2006-03-03 12:58 king
-
- * Source/CMakeLists.txt, Source/cmGlobalGenerator.cxx,
- Source/cmGlobalGenerator.h,
- Source/cmGlobalVisualStudio6Generator.cxx,
- Source/cmGlobalVisualStudio6Generator.h,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.h,
- Source/cmGlobalXCodeGenerator.cxx,
- Source/cmGlobalXCodeGenerator.h,
- Source/cmInstallTargetGenerator.cxx,
- Source/cmInstallTargetGenerator.h,
- Source/cmMakefileExecutableTargetGenerator.cxx,
- Source/cmTarget.cxx, Tests/BundleTest/BundleLib.cxx,
- Tests/BundleTest/BundleTest.cxx, Tests/BundleTest/CMakeLists.txt:
- BUG: Fixed installation of MacOSX Bundle executables and the
- corresponding install_name remapping support. Extended the
- BundleTest test to check that this all works. Part of these
- fixes required changing the signature of AppendDirectoryForConfig
- in all generators. It now accepts prefix and suffix strings to
- deal with whether leading or trailing slashes should be included
- with the configuration subdirectory.
-
-2006-03-03 12:01 hoffman
-
- * Modules/Platform/Windows-cl.cmake: ENH: add manifest support for
- 2005
-
-2006-03-03 11:59 hoffman
-
- * Modules/CMakeVS8FindMake.cmake: ENH: look for VCExpress first
-
-2006-03-03 10:52 andy
-
- * Modules/CPack.Info.plist.in,
- Source/CPack/cmCPackPackageMakerGenerator.cxx: ENH: Add verbose
- flag to package maker and add CFBundleIdentifier string
-
-2006-03-03 02:34 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-02 21:33 hoffman
-
- * Source/kwsys/: Registry.cxx, SystemTools.cxx: ENH: fix std in
- kwsys, has to be kwsys_stl
-
-2006-03-02 20:11 hoffman
-
- * Source/cmFindBase.cxx: ENH: remove warning
-
-2006-03-02 15:03 hoffman
-
- * Source/: cmMakefile.cxx, cmMakefile.h: ENH: removed unused
- methods after find changes
-
-2006-03-02 14:39 hoffman
-
- * Source/cmTryCompileCommand.cxx: ENH: pass CMAKE_MODULE_PATH into
- try compile projects
-
-2006-03-02 13:43 hoffman
-
- * Source/: cmFindBase.cxx, cmFindLibraryCommand.cxx: ENH: fix
- spelling errors in docs
-
-2006-03-02 13:30 hoffman
-
- * Modules/Platform/CYGWIN.cmake, Modules/Platform/Darwin.cmake,
- Modules/Platform/Linux.cmake, Modules/Platform/SunOS.cmake,
- Modules/Platform/UnixPaths.cmake,
- Modules/Platform/Windows-cl.cmake,
- Modules/Platform/WindowsPaths.cmake,
- Source/cmBootstrapCommands.cxx, Source/cmFindBase.cxx,
- Source/cmFindBase.h, Source/cmFindFileCommand.cxx,
- Source/cmFindFileCommand.h, Source/cmFindLibraryCommand.cxx,
- Source/cmFindLibraryCommand.h, Source/cmFindPathCommand.cxx,
- Source/cmFindPathCommand.h, Source/cmFindProgramCommand.cxx,
- Source/cmFindProgramCommand.h, Source/kwsys/Registry.cxx,
- Source/kwsys/SystemTools.cxx: ENH: check in new find stuff
-
-2006-03-02 07:52 hoffman
-
- * Modules/CMakeCInformation.cmake,
- Modules/CMakeCXXInformation.cmake,
- Modules/CMakeFortranInformation.cmake,
- Modules/CMakeJavaInformation.cmake, Source/cmGlobalGenerator.cxx:
- ENH: fix for bug 2921, move _OVERRIDE variable to a better
- position to allow changing _INIT variables
-
-2006-03-02 02:17 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-03-01 22:45 king
-
- * Source/: cmSetTargetPropertiesCommand.h, cmTarget.cxx: ENH:
- Finished CMAKE_<CONFIG>_POSTFIX feature and documented it. The
- value of this variable is used when a library target is created
- to initialize the <CONFIG>_POSTFIX target property. The value of
- this property is used (even for executables) to define a
- per-configuration postfix on the name of the target. Also
- enabled use of the OUTPUT_NAME property for non-executable
- targets.
-
-2006-03-01 19:00 king
-
- * CMakeLists.txt: ENH: CMake does not need RPATHs at all for its
- own executables. Disable them to avoid relinking during
- installation.
-
-2006-03-01 18:54 king
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h,
- cmLocalUnixMakefileGenerator3.cxx: ENH: Cleaned up generation of
- directory-level rules and their support structure. The
- directorystart rule has been removed in favor of checking the
- build system in the subdirectory makefile first. The "directory"
- rule has been renamed "all" since it corresponds to the "all"
- pass anyway (as against "clean"). Also fixed directory-level
- rule for preinstall.
-
-2006-03-01 18:49 king
-
- * Source/cmGlobalGenerator.cxx: BUG: Check for whether to add
- BUILD_TYPE to install rule should check for a . in the first
- character not the second.
-
-2006-03-01 15:00 andy
-
- * Modules/: CPack.cmake, NSIS.template.in: ENH: Several changes to
- for NSIS
-
-2006-03-01 13:15 andy
-
- * CMakeLists.txt, Modules/CPack.cmake,
- Modules/InstallRequiredSystemLibraries.cmake: ENH: Install system
- libraries only if project requires them
-
-2006-03-01 13:05 andy
-
- * Source/cmSystemTools.cxx: BUG: Even more VS8 issues
-
-2006-03-01 12:50 andy
-
- * Source/CTest/cmCTestSubmitHandler.cxx: BUG: More VS8 fixes
-
-2006-03-01 11:55 andy
-
- * Templates/CMakeLists.txt: ENH: Install cpack files
-
-2006-03-01 08:28 andy
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalUnixMakefileGenerator3.h, cmGlobalXCodeGenerator.cxx,
- cmGlobalXCodeGenerator.h: ENH: Cleanup global targets even more
- and potentially fix Xcode
-
-2006-03-01 02:32 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-28 16:33 andy
-
- * Source/cmGlobalGenerator.cxx: BUG: Ok, fix the ordering
-
-2006-02-28 16:22 andy
-
- * Source/CTest/cmCTestHandlerCommand.cxx: BUG: Fix for STL
-
-2006-02-28 16:17 andy
-
- * Source/cmCTest.h: BUG: Handle buggy streams
-
-2006-02-28 15:56 andy
-
- * Source/cmCTest.cxx: BUG: Add additional check
-
-2006-02-28 15:31 andy
-
- * Source/cmGlobalGenerator.cxx: BUG: On Visual Studio and XCode,
- handle build configurations
-
-2006-02-28 15:31 andy
-
- * Source/CTest/cmCTestBuildAndTestHandler.cxx: STYLE: Remove debug
-
-2006-02-28 14:18 andy
-
- * Modules/CPack.cmake, Templates/CPack.GenericLicense.txt,
- Templates/CPack.GenericWelcome.txt: ENH: Add resource files for
- PackageMaker
-
-2006-02-28 14:06 andy
-
- * Templates/CPack.GenericDescription.txt,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: Add generic
- instructions
-
-2006-02-28 13:30 andy
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ENH: Attempt to handle windows
- without NSIS installed
-
-2006-02-28 11:38 king
-
- * Source/kwsys/ProcessWin32.c: COMP: Fixed warnings for Borland
- 5.8.
-
-2006-02-28 11:14 andy
-
- * Modules/FindQt4.cmake: BUG: Fix typo
-
-2006-02-28 11:13 andy
-
- * Modules/FindQt4.cmake: ENH: Add support for debian having both
- qt3 and qt4
-
-2006-02-28 10:27 hoffman
-
- * Modules/: CMakeVS71FindMake.cmake, CMakeVS8FindMake.cmake,
- FindDart.cmake, FindDoxygen.cmake, FindGCCXML.cmake,
- FindHTMLHelp.cmake, FindMPI.cmake, FindQt3.cmake, FindQt4.cmake,
- FindTCL.cmake, Platform/Darwin.cmake: ENH: use program files env
- for searching
-
-2006-02-28 09:53 king
-
- * Source/cmGlobalGenerator.cxx: BUG: Need to use the CMAKE_COMMAND
- cache entry to get the location of CMake.
-
-2006-02-28 08:23 andy
-
- * Source/CTest/cmCTestBuildAndTestHandler.cxx,
- Source/CTest/cmCTestBuildAndTestHandler.h,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: Add support for
- multiple build targets and start adding simple cpack tests
-
-2006-02-28 02:32 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-27 23:06 hoffman
-
- * Source/cmSourceGroupCommand.cxx: ENH: fix problem if there are ..
- in the path to the source file specified in a source group
-
-2006-02-27 16:38 hoffman
-
- * Source/: cmFindBase.cxx, cmFindBase.h: ENH: add new find stuff
-
-2006-02-27 12:14 hoffman
-
- * Modules/: CMakeCInformation.cmake, CMakeCXXInformation.cmake,
- CMakeFortranInformation.cmake, CMakeRCInformation.cmake: ENH: fix
- spelling errors
-
-2006-02-27 10:58 andy
-
- * Modules/CPack.Info.plist.in, Modules/CPack.cmake,
- Modules/NSIS.template.in, Source/cmBootstrapCommands.cxx,
- Source/cmCommands.cxx, Source/cmGlobalGenerator.cxx,
- Source/CPack/cmCPackGenericGenerator.cxx,
- Templates/CPackConfig.cmake.in: ENH: Several packaging issues.
- Allow random variables to be passed to cpack (anything starting
- with CPACK_, add preinstall to the list of dependencies for
- package, fix typos
-
-2006-02-27 02:00 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-26 02:00 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-25 01:56 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-24 18:15 andy
-
- * Source/: cmGlobalGenerator.cxx, cmake.h: COMP: More fixes for non
- makefile generators and global targets
-
-2006-02-24 17:43 andy
-
- * Source/cmGlobalGenerator.cxx: STYLE: Remove debug
-
-2006-02-24 17:35 andy
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio6Generator.h,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h, cmGlobalXCode21Generator.h,
- cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx, cmMakefile.cxx, cmTarget.h:
- COMP: Even more global target fixes
-
-2006-02-24 16:30 andy
-
- * Source/CMakeLists.txt: ENH: Install cpack
-
-2006-02-24 16:20 andy
-
- * Source/: cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: BUG: More fixing of support
- for global target son visual studio
-
-2006-02-24 13:13 king
-
- * Modules/Platform/Darwin.cmake, Source/cmGlobalXCodeGenerator.cxx,
- Source/cmGlobalXCodeGenerator.h,
- Source/cmInstallTargetGenerator.cxx,
- Source/cmInstallTargetGenerator.h, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmSetTargetPropertiesCommand.h, Source/cmTarget.cxx,
- Source/cmTarget.h, Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: Created target
- property INSTALL_NAME_DIR initalized by CMAKE_INSTALL_NAME_DIR
- specifying the directory portion of the OSX install_name field in
- shared libraries. This is the OSX equivalent of RPATH.
-
-2006-02-24 12:50 hoffman
-
- * Source/cmSourceGroupCommand.cxx: ENH: fix warning and remove
- unused variable
-
-2006-02-24 11:13 king
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmLocalGenerator.cxx,
- cmLocalGenerator.h, cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx: BUG: Fix generation of Xcode 2.0
- and earlier projects to use CMAKE_BUILD_TYPE.
-
-2006-02-24 11:07 king
-
- * Source/cmGlobalXCodeGenerator.cxx: BUG: Treat GLOBAL_TARGET like
- UTILITY for generation.
-
-2006-02-24 10:56 andy
-
- * Source/cmLocalGenerator.cxx: COMP: Remove warnings
-
-2006-02-24 10:55 andy
-
- * Source/cmGlobalGenerator.cxx: BUG: Only add test targets when
- testing is enabled. Also add CMAKE_CFG_INTDIR when specified
-
-2006-02-24 09:43 andy
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalUnixMakefileGenerator3.h,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx: COMP: Handle preinstall
- properly on IDEs
-
-2006-02-24 09:32 andy
-
- * Source/: cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx: COMP: Fix for preinstall
-
-2006-02-24 09:08 andy
-
- * Modules/CheckIncludeFiles.cmake: BUG: Fix the module
-
-2006-02-24 08:57 andy
-
- * Source/cmake.cxx: BUG: Fix location of ctest for bootstrap
-
-2006-02-24 02:24 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-23 18:25 hoffman
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: try to fix things
- up for the dashboard
-
-2006-02-23 17:30 andy
-
- * Source/: cmGlobalGenerator.cxx,
- cmLocalUnixMakefileGenerator3.cxx: ENH: Properly handle target
- dependencies
-
-2006-02-23 14:05 andy
-
- * Source/cmGlobalVisualStudio71Generator.cxx: COMP: Even more
- Visual Studio fixes. Why is this code duplicated?
-
-2006-02-23 13:46 andy
-
- * Source/: cmGlobalGenerator.cxx,
- cmLocalVisualStudio7Generator.cxx: COMP: More fixes for visual
- studio
-
-2006-02-23 13:37 andy
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalUnixMakefileGenerator3.h,
- cmGlobalVisualStudio7Generator.cxx: COMP: Fixes for visual studio
-
-2006-02-23 11:36 hoffman
-
- * Source/cmSourceGroupCommand.cxx: ENH: fix for bug 2908 crash for
- empty source group name
-
-2006-02-23 10:48 andy
-
- * Source/: cmGlobalGenerator.cxx,
- cmLocalUnixMakefileGenerator3.cxx: ENH: Remove debug
-
-2006-02-23 10:07 andy
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmLocalUnixMakefileGenerator3.cxx: ENH: Add a notion of a global
- target
-
-2006-02-23 10:02 andy
-
- * Source/: cmTarget.cxx, cmTarget.h, cmMakefile.cxx: ENH: Add a
- notion of a global target
-
-2006-02-23 10:00 andy
-
- * Source/: cmake.cxx, cmake.h: ENH: Add accessors for CTest and
- CPack
-
-2006-02-23 09:59 andy
-
- * Source/CPack/cpack.cxx: ENH: Allow running without config file
-
-2006-02-23 09:58 andy
-
- * Modules/: CMakeConfigurableFile.in, CheckIncludeFiles.cmake,
- CheckSymbolExists.cmake: ENH: Make modules use configure instead
- of file write
-
-2006-02-23 09:38 andy
-
- * Modules/CPack.cmake, Modules/NSIS.template.in,
- Source/CPack/cmCPackNSISGenerator.cxx,
- Templates/CPackConfig.cmake.in: ENH: Several NSIS features
-
-2006-02-23 02:34 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-22 02:36 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-21 12:19 hoffman
-
- * Modules/Platform/Windows-cl.cmake,
- Source/cmLocalVisualStudio7Generator.cxx: ENH: make command line
- flags more consistent with ide settings
-
-2006-02-21 09:35 hoffman
-
- * Source/cmGlobalMSYSMakefileGenerator.cxx: ENH: use last mount
- point found for mingw location, not first
-
-2006-02-21 07:58 hoffman
-
- * Source/cmGlobalMSYSMakefileGenerator.cxx: ENH: try to get the
- order a bit better
-
-2006-02-21 02:35 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-20 23:08 hoffman
-
- * Modules/CMakeDetermineCCompiler.cmake, Source/cmCacheManager.cxx,
- Source/cmGlobalMSYSMakefileGenerator.cxx,
- Source/cmGlobalMSYSMakefileGenerator.h: ENH: better finding of
- mingw from msys, and delete CMakeFiles directory when cache is
- deleted
-
-2006-02-20 17:47 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: ENH: make sure
- CMAKE_STANDARD_LIBRARIES are used
-
-2006-02-20 14:37 hoffman
-
- * Source/cmLocalGenerator.h: ENH: make it compile on vs6
-
-2006-02-20 14:21 king
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: BUG: Add target-level
- COMPILE_FLAGS to the target not the individual source files.
- This simplifies the generated files and puts flags in a more
- logical order (VS6 works, VS7 needs more translation to work).
-
-2006-02-20 13:42 hoffman
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h,
- cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx: ENH: change expand stuff to pass a
- struct for all the args
-
-2006-02-20 12:48 king
-
- * Source/cmMakefileTargetGenerator.cxx: ENH: Order compilation
- flags from most general to most specific: language, then target,
- then source.
-
-2006-02-20 09:54 king
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmLocalGenerator.h: BUG:
- Xcode generator should use local generator computation of include
- directories.
-
-2006-02-20 03:00 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-19 19:29 king
-
- * Source/: cmFileCommand.cxx, cmInstallGenerator.cxx,
- cmInstallTargetGenerator.cxx: BUG: Fixed optional file install
- support for multi-configuration generators.
-
-2006-02-19 19:28 king
-
- * Source/: cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx, cmGlobalXCodeGenerator.cxx,
- cmTarget.cxx: ENH: Switched order of slash and configuration name
- in cmGlobalGenerator::AppendDirectoryForConfig method to increase
- flexibility.
-
-2006-02-19 18:47 king
-
- * bootstrap, Source/CMakeLists.txt, Source/cmInstallCommand.cxx,
- Source/cmInstallCommand.h, Source/cmInstallFilesCommand.h,
- Source/cmInstallFilesGenerator.cxx,
- Source/cmInstallFilesGenerator.h,
- Source/cmInstallProgramsCommand.h, Source/cmLocalGenerator.cxx,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: Implemented FILES and
- PROGRAMS forms of the INSTALL command as replacements for the
- INSTALL_FILES and INSTALL_PROGRAMS commands. This addresses the
- request for absolute path install destinations in bug#2691.
-
-2006-02-19 18:44 king
-
- * Source/cmInstallTargetGenerator.cxx: STYLE: Removed unused
- includes.
-
-2006-02-19 17:44 king
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ENH: Using CMAKE_SKIP_BUILD_RPATH
- to test relink support.
-
-2006-02-19 17:27 king
-
- * Source/: cmInstallTargetGenerator.cxx,
- cmInstallTargetsCommand.cxx, cmTarget.cxx, cmTarget.h: BUG: Fixed
- relink with new install framework.
-
-2006-02-19 16:35 king
-
- * Source/cmInstallCommand.cxx: COMP: Removed unused variables.
-
-2006-02-19 16:12 king
-
- * Source/: cmInstallGenerator.cxx, cmInstallGenerator.h: BUG: Do
- not report files as installed if they are optional and do not
- exist.
-
-2006-02-19 16:10 king
-
- * Source/cmInstallTargetGenerator.cxx: BUG: Import libraries should
- be installed as STATIC_LIBRARY.
-
-2006-02-19 15:25 king
-
- * bootstrap, Source/CMakeLists.txt, Source/cmInstallCommand.cxx,
- Source/cmInstallCommand.h, Source/cmInstallGenerator.cxx,
- Source/cmInstallGenerator.h, Source/cmInstallScriptGenerator.cxx,
- Source/cmInstallScriptGenerator.h,
- Source/cmInstallTargetGenerator.cxx,
- Source/cmInstallTargetGenerator.h,
- Source/cmInstallTargetsCommand.h, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmSetTargetPropertiesCommand.h,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: Created new install
- script generation framework. The INSTALL command creates the
- generators which are later used by cmLocalGenerator to create the
- cmake_install.cmake files. A new target installation interface
- is provided by the INSTALL command which fixes several problems
- with the INSTALL_TARGETS command. See bug#2691. Bugs 1481 and
- 1695 are addressed by these changes.
-
-2006-02-19 13:49 king
-
- * Modules/Platform/Windows-gcc.cmake: BUG: Fixed module creation
- rules. Removed soname portion of all rules because it is never
- used on this platform.
-
-2006-02-19 13:34 king
-
- * Modules/Platform/CYGWIN.cmake: BUG: Fixed cygwin module creation
- rules. Modules should not have the "cyg" prefix by default.
- Removd soname flags from creation rules because they are never
- used on this platform.
-
-2006-02-19 13:10 king
-
- * Source/cmLocalGenerator.cxx,
- Tests/CustomCommand/GeneratedHeader/CMakeLists.txt: ENH:
- Automatic include directories should not be done by default as
- was just implemented. Instead a project may now set
- CMAKE_INCLUDE_CURRENT_DIR to get this behavior. The current
- source and binary directories are added automatically to the
- beginning of the include path in every directory. This simulates
- in-source behavior for double-quote includes when there are
- generated sources and headers in the directory.
-
-2006-02-19 13:08 king
-
- * Source/cmFileCommand.cxx: BUG: Install location full-path test
- for windows needs to account for both lower case and upper case
- drive letters.
-
-2006-02-19 01:53 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-18 16:47 king
-
- * Source/cmLocalGenerator.cxx: BUG: Remove trailing slashes from
- install destinations.
-
-2006-02-18 16:36 king
-
- * Source/cmFileCommand.cxx: ENH: Clarified error message.
-
-2006-02-18 15:42 king
-
- * Source/cmLocalGenerator.cxx: COMP: Fixed shadowed variable
- warning.
-
-2006-02-18 15:37 king
-
- * Modules/Platform/CYGWIN.cmake,
- Modules/Platform/Windows-bcc32.cmake,
- Modules/Platform/Windows-gcc.cmake,
- Modules/Platform/Windows-wcl386.cmake,
- Modules/Platform/Windows.cmake, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmMakefileLibraryTargetGenerator.cxx, Source/cmTarget.cxx,
- Source/cmTarget.h: ENH: Generate import libraries for DLLs on
- Cygwin and MinGW.
-
-2006-02-18 11:51 king
-
- * Source/: cmLocalGenerator.cxx, cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: ENH: If
- CMAKE_NO_AUTOMATIC_INCLUDE_DIRECTORIES is not set try to
- approximate in-source build include file behavior in an
- out-of-source build by adding the build tree directory
- corresponding to a source tree directory at the beginning of the
- include path. Also fixed VS6 and VS7 generators to use
- cmLocalGenerator's computation of include paths. The VS6
- generator will now short-path the include directories if the
- total length is too long in order to try to avoid its truncation
- limit.
-
-2006-02-18 11:03 hoffman
-
- * Source/: cmGlobalKdevelopGenerator.cxx,
- cmGlobalKdevelopGenerator.h: ENH: apply patch from Alex to
- support some more kdevelop stuff
-
-2006-02-18 01:55 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-17 12:49 hoffman
-
- * Source/cmMakefile.cxx: ENH: put the system path ahead of the
- command path
-
-2006-02-17 02:26 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-16 20:15 king
-
- * Modules/CPack.cmake, Utilities/Release/Release.cmake: BUG: Do not
- install MSVC dlls for a non-MSVC build.
-
-2006-02-16 20:13 king
-
- * bootstrap: ENH: Made default install prefix consistent with
- building with another CMake.
-
-2006-02-16 18:50 king
-
- * Source/: cmGlobalBorlandMakefileGenerator.cxx,
- cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h: BUG: Work-around borland make
- bug that drops a rule completely if it has no dependencies or
- commands.
-
-2006-02-16 18:09 king
-
- * Source/cmSetTargetPropertiesCommand.h: ENH: Clarified
- documentation of DEFINE_SYMBOL.
-
-2006-02-16 17:49 king
-
- * Source/cmSetTargetPropertiesCommand.cxx: BUG: Report error when a
- target does not exist.
-
-2006-02-16 15:55 andy
-
- * Source/CPack/cmCPackNSISGenerator.cxx: BUG: Remove debug and fix
- space between label and exec name
-
-2006-02-16 15:41 andy
-
- * CMakeLists.txt: ENH: Variable name changed
-
-2006-02-16 15:39 king
-
- * Source/cmMakefileExecutableTargetGenerator.cxx: BUG: Do not
- perform pre-build, pre-link, or post-install commands when
- relinking.
-
-2006-02-16 15:38 king
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: BUG: Need INSTALL_RPATH property
- on SimpleInstallS2 also.
-
-2006-02-16 15:35 andy
-
- * Templates/CPackConfig.cmake.in: ENH: Fix icons
-
-2006-02-16 15:28 king
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ENH: Use target property for
- INSTALL_RPATH of SimpleInstall so that it is the only one that
- needs to relink.
-
-2006-02-16 15:20 andy
-
- * Modules/NSIS.template.in, Source/CPack/cmCPackNSISGenerator.cxx,
- Source/CPack/cmCPackNSISGenerator.h: ENH: More work on NSI to
- improve installing and uninstalling
-
-2006-02-16 15:18 king
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmLocalGenerator.cxx, Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmMakefileExecutableTargetGenerator.cxx,
- Source/cmMakefileExecutableTargetGenerator.h,
- Source/cmMakefileLibraryTargetGenerator.cxx,
- Source/cmMakefileLibraryTargetGenerator.h,
- Source/cmSetTargetPropertiesCommand.h, Source/cmTarget.cxx,
- Source/cmTarget.h, Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: Implemented RPATH
- specification support. It is documented by the command
- SET_TARGET_PROPERTIES.
-
-2006-02-16 13:42 martink
-
- * Source/cmMakefileTargetGenerator.cxx: ENH: warning fix
-
-2006-02-16 11:32 martink
-
- * Source/cmMakefileTargetGenerator.cxx: ENH: warning fix
-
-2006-02-16 10:35 hoffman
-
- * Source/: cmDynamicLoader.cxx, cmDynamicLoader.h: ENH: fix for bug
- 2808, use dlopen on new OSX versions
-
-2006-02-16 02:25 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-15 21:26 hoffman
-
- * Modules/CMakeMSYSFindMake.cmake,
- Modules/CMakeMinGWFindMake.cmake,
- Source/cmGlobalMSYSMakefileGenerator.cxx,
- Source/cmGlobalMinGWMakefileGenerator.cxx: ENH: better algorithm
- for looking for make and gcc on msys and mingw
-
-2006-02-15 16:38 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: Use NOINHERIT
- macro to avoid linking to project default libraries which may not
- exist.
-
-2006-02-15 16:35 king
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h,
- cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx,
- cmMakefileUtilityTargetGenerator.cxx: ENH: Cleaned up generation
- of symbolic rules. Removed generation of rebuild_cache and
- similar rules from internal makefiles.
-
-2006-02-15 12:32 martink
-
- * Source/cmMakefileTargetGenerator.h: COMP: fix compiler warning
-
-2006-02-15 12:30 hoffman
-
- * Source/cmMakefileTargetGenerator.cxx: ENH: fix build error for
- mac
-
-2006-02-15 10:34 martink
-
- * bootstrap, Source/CMakeLists.txt,
- Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalUnixMakefileGenerator3.h,
- Source/cmMakefileTargetGenerator.h: ENH: some reorg of the unix
- makefile generator
-
-2006-02-15 10:22 king
-
- * Source/: cmCTest.cxx, cmSystemTools.cxx, cmSystemTools.h,
- cmake.cxx: ENH: Enable capture of output from VCExpress.exe and
- devenv.exe.
-
-2006-02-15 08:05 hoffman
-
- * Modules/Platform/Windows-bcc32.cmake: ENH: remove warning
- suppressions for borland compiler, projects wanting this should
- use -w-, the default warning level is used for all other
- compilers. Used to be -w- -whid -waus -wpar
-
-2006-02-15 02:21 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-14 22:03 hoffman
-
- * Modules/CMakeMinGWFindMake.cmake, Source/cmake.cxx: ENH: do not
- allow mingw makefiles to generate if sh.exe is in the path, also
- do not write CMakeCache.txt if there is a fatal error.
-
-2006-02-14 17:16 king
-
- * Source/: cmCMakeMinimumRequired.cxx, cmCMakeMinimumRequired.h:
- ENH: Added FATAL_ERROR option and fixed check to not have
- floating point roundoff problems.
-
-2006-02-14 16:35 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: Removed hard-coded
- linking to odbc32 and odbccp32.
-
-2006-02-14 16:32 king
-
- * Source/: cmGlobalVisualStudio8Generator.cxx,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: BUG: Avoid adding unused rules
- to special targets like ALL_BUILD. Make sure project
- regeneration rules go only in desired targets.
-
-2006-02-14 15:35 king
-
- * Source/: cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio71Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio8Generator.cxx,
- cmGlobalVisualStudio8Generator.h: BUG: Fixed generation of VS8
- solution file to not be re-written when loaded by VS and to work
- with msbuild.
-
-2006-02-14 15:29 king
-
- * Modules/CheckTypeSize.cmake: ENH: Added
- CMAKE_REQUIRED_DEFINITIONS and CMAKE_REQUIRED_INCLUDES to the
- interface.
-
-2006-02-14 15:15 king
-
- * Tests/CustomCommand/GeneratedHeader/main.cpp: COMP: Fixed form of
- function main.
-
-2006-02-14 14:29 andy
-
- * Modules/NSIS.template.in, Source/CPack/cmCPackNSISGenerator.cxx:
- ENH: Better handling of executables on windows
-
-2006-02-14 14:28 andy
-
- * Templates/CPackConfig.cmake.in: ENH: Cleanup
-
-2006-02-14 11:17 andy
-
- * Source/cmCacheManager.cxx: ENH: Report which cmake was used to
- generate the cache in the comment
-
-2006-02-14 10:51 hoffman
-
- * Modules/Platform/Windows-cl.cmake: ENH: fix try compile for MFC
-
-2006-02-14 10:35 martink
-
- * Source/: cmMakefileExecutableTargetGenerator.h,
- cmMakefileLibraryTargetGenerator.h, cmMakefileTargetGenerator.h,
- cmMakefileUtilityTargetGenerator.h,
- cmMakefileExecutableTargetGenerator.cxx,
- cmMakefileLibraryTargetGenerator.cxx,
- cmMakefileTargetGenerator.cxx,
- cmMakefileUtilityTargetGenerator.cxx: ENH: some cleanup of the
- makefile generator
-
-2006-02-14 10:28 andy
-
- * CMakeLists.txt, Modules/CPack.cmake,
- Source/CPack/cmCPackGenericGenerator.cxx,
- Source/CPack/cmCPackSTGZGenerator.cxx, Source/CPack/cpack.cxx,
- Templates/CPackConfig.cmake.in: ENH: Improved support for icons,
- random directories, etc...
-
-2006-02-14 02:14 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-13 02:10 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-12 02:27 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-11 02:11 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-10 15:45 king
-
- * Tests/CommandLineTest/CMakeLists.txt: ENH: Added test for
- IF(DEFINED ENV{var})(.
-
-2006-02-10 14:59 king
-
- * CMakeLists.txt: ENH: Updated patch level to 3 for special KDE
- release.
-
-2006-02-10 14:41 king
-
- * Source/cmIfCommand.cxx: ENH: Allow IF(DEFINED ENV{somevar}) to
- work.
-
-2006-02-10 14:15 king
-
- * Docs/cmake-mode.el: ENH: Added highlighting for LIST command.
-
-2006-02-10 14:11 andy
-
- * CMakeLists.txt, Source/cmCommands.cxx, Source/cmListCommand.cxx,
- Source/cmListCommand.h, Tests/CMakeTests/CMakeLists.txt,
- Tests/CMakeTests/ListTest.cmake.in: ENH: Add initial
- implementation of the list command
-
-2006-02-10 13:54 king
-
- * Docs/cmake-mode.el, Source/cmCommands.cxx,
- Source/cmInstallCommand.cxx, Source/cmInstallCommand.h,
- Source/cmLocalGenerator.cxx, Source/cmMakefile.h,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstall/InstallScript1.cmake,
- Tests/SimpleInstall/InstallScript2.cmake,
- Tests/SimpleInstallS2/CMakeLists.txt,
- Tests/SimpleInstallS2/InstallScript1.cmake,
- Tests/SimpleInstallS2/InstallScript2.cmake: ENH: Added INSTALL
- command as a placeholder for a future generic install
- specification interface. Currently it supports only a SCRIPT
- option specifying a script to run during the install stage.
-
-2006-02-10 12:43 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: fix for bug 28618, cmake.exe
- can not find itself
-
-2006-02-10 11:47 king
-
- * Tests/: Complex/CMakeLists.txt, ComplexOneConfig/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt: ENH: Strengthened
- EXECUTE_PROCESS output check test.
-
-2006-02-10 11:46 king
-
- * Source/cmExecuteProcessCommand.cxx: ENH: Remove extra windows
- newline characters from process output. Centralized text fix
- processing.
-
-2006-02-10 11:43 king
-
- * Source/: cmExecProgramCommand.h, cmExecuteProcessCommand.h: ENH:
- Mention relationship of EXECUTE_PROCESS and EXEC_PROGRAM.
-
-2006-02-10 11:41 king
-
- * Source/cmake.cxx: BUG: Fixed echo command to not print trailing
- space.
-
-2006-02-10 11:19 king
-
- * bootstrap: BUG: Fixed bootstrap from MSYS prompt. It was working
- only when the bootstrap directory in MSYS mapped to the same
- directory on windows except for the drive letter in front. Now
- it should work from any path.
-
-2006-02-10 10:30 hoffman
-
- * Tests/CustomCommandWorkingDirectory/: CMakeLists.txt, working.c,
- working.c.in: ENH: fix test to work with in source build
-
-2006-02-10 10:11 hoffman
-
- * Source/cmLocalGenerator.cxx: ENH: fix bug for single char
- libraries
-
-2006-02-10 09:46 andy
-
- * Modules/CheckLibraryExists.cmake: BUG: Fix
- CMAKE_REQUIRED_LIBRARIES stuff in this module
-
-2006-02-10 02:16 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-09 23:08 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: ENH: bug fix for 2829
- better flags for idl tool
-
-2006-02-09 19:29 king
-
- * Source/cmLocalVisualStudio6Generator.cxx: COMP: Removed unused
- variables.
-
-2006-02-09 19:25 king
-
- * CMakeLists.txt: ENH: Updated patch level to 2 for special KDE
- release.
-
-2006-02-09 19:23 king
-
- * Modules/: CheckCSourceCompiles.cmake,
- CheckCXXSourceCompiles.cmake, CheckFunctionExists.cmake,
- CheckIncludeFile.cmake, CheckIncludeFileCXX.cmake,
- CheckIncludeFiles.cmake, CheckLibraryExists.cmake,
- CheckSymbolExists.cmake, CheckVariableExists.cmake: ENH: Made
- Check* modules more consistent and well documented. Added
- CMAKE_REQUIRED_DEFINITIONS option.
-
-2006-02-09 19:03 king
-
- * Source/cmMakefile.cxx: BUG: Need to include empty arguments when
- parsing prefix/suffix lists for FindLibrary.
-
-2006-02-09 19:03 king
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Adding option
- to return empty arguments when expanding a list.
-
-2006-02-09 18:42 king
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio6Generator.h,
- cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h: BUG: Fixed generation of cmake
- re-run rules.
-
-2006-02-09 18:39 king
-
- * Tests/: Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/complex.cxx: BUG: Avoid case
- problems on windows.
-
-2006-02-09 17:29 king
-
- * Source/: cmOrderLinkDirectories.cxx, cmOrderLinkDirectories.h:
- BUG: Deal with case insensitivity on windows linker paths. Also
- fixed spelling typo.
-
-2006-02-09 15:33 king
-
- * Modules/FindPNG.cmake: ENH: Put libpng name back because it is
- needed for plain windows.
-
-2006-02-09 15:08 king
-
- * Modules/: FindJPEG.cmake, FindPNG.cmake, FindTIFF.cmake,
- FindZLIB.cmake: ENH: Removing platform-specific name hacks now
- that FIND_LIBRARY handles it.
-
-2006-02-09 15:05 king
-
- * Modules/CMakeGenericSystem.cmake, Modules/Platform/CYGWIN.cmake,
- Modules/Platform/Darwin.cmake, Modules/Platform/HP-UX.cmake,
- Modules/Platform/Windows-bcc32.cmake,
- Modules/Platform/Windows-gcc.cmake,
- Modules/Platform/Windows.cmake, Source/cmMakefile.cxx: ENH: Added
- platform settings CMAKE_FIND_LIBRARY_PREFIXES and
- CMAKE_FIND_LIBRARY_SUFFIXES to allow customized searching for
- libraries.
-
-2006-02-09 14:28 king
-
- * Modules/CheckSymbolExists.cmake: ENH: Pay attention to
- CMAKE_REQUIRED_INCLUDES.
-
-2006-02-09 14:18 king
-
- * Modules/Platform/Windows-g++.cmake: BUG: Need Windows-g++.cmake
- module to support C++-only projects on Windows.
-
-2006-02-09 13:48 king
-
- * Modules/CMakeCXXCompiler.cmake.in: BUG: Need to duplicate some
- information from CMakeCCompiler to support C++-only projects.
-
-2006-02-09 13:14 king
-
- * Modules/: CheckCSourceCompiles.cmake,
- CheckCXXSourceCompiles.cmake, CheckIncludeFiles.cmake: ENH: Patch
- from Alexander Neundorf to improve behavior.
-
-2006-02-09 12:04 king
-
- * Modules/: FindJPEG.cmake, FindPNG.cmake, FindTIFF.cmake,
- FindZLIB.cmake: ENH: Added names for gnuwin32 library versions.
-
-2006-02-09 09:34 david.cole
-
- * Utilities/cmtar/wrapper.c: COMP: Last (?) fix for dashboard
- warning.
-
-2006-02-09 02:17 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-08 15:37 hoffman
-
- * Source/: cmAddCustomCommandCommand.cxx,
- cmAddCustomTargetCommand.cxx, cmVTKWrapJavaCommand.cxx: ENH: fix
- broken tests
-
-2006-02-08 14:12 hoffman
-
- * Source/: CMakeLists.txt, cmGlobalXCodeGenerator.cxx: ENH: working
- directory working for XCode
-
-2006-02-08 12:01 king
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio6Generator.h: ENH: Enabled new
- WORKING_DIRECTORY option to ADD_CUSTOM_COMMAND and
- ADD_CUSTOM_TARGET on VS 6 generator.
-
-2006-02-08 11:33 hoffman
-
- * Tests/CustomCommandWorkingDirectory/: CMakeLists.txt,
- customTarget.c, working.c: ENH: add test for working directory of
- custom command and target
-
-2006-02-08 10:58 hoffman
-
- * Modules/CMakeFortranInformation.cmake, Source/CMakeLists.txt,
- Source/cmAddCustomCommandCommand.cxx,
- Source/cmAddCustomCommandCommand.h,
- Source/cmAddCustomTargetCommand.cxx,
- Source/cmAddCustomTargetCommand.h, Source/cmCPluginAPI.cxx,
- Source/cmCustomCommand.cxx, Source/cmCustomCommand.h,
- Source/cmFLTKWrapUICommand.cxx, Source/cmGlobalGenerator.cxx,
- Source/cmGlobalVisualStudio6Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalVisualStudio8Generator.cxx,
- Source/cmGlobalXCodeGenerator.cxx,
- Source/cmIncludeExternalMSProjectCommand.cxx,
- Source/cmLocalGenerator.cxx, Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmQTWrapCPPCommand.cxx,
- Source/cmQTWrapUICommand.cxx, Source/cmVTKWrapJavaCommand.cxx:
- ENH: add working directory support
-
-2006-02-08 10:13 king
-
- * CMakeLists.txt, Source/CMakeLists.txt, Utilities/CMakeLists.txt:
- ENH: Added option BUILD_CursesDialog if curses is found. This
- allows people to disable building the dialog even when curses is
- found.
-
-2006-02-08 09:51 king
-
- * Modules/FindQt4.cmake: BUG: Fixed qt version message. Submitted
- by Tanner Lovelace.
-
-2006-02-08 07:17 andy
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: COMP: Fix
- problem with STL on HP, and fix reusing the same variable in for
- loops
-
-2006-02-08 02:50 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-07 17:10 king
-
- * Modules/Platform/Windows-cl.cmake: ENH: Adding definition of MSVC
- when it is the compiler.
-
-2006-02-07 17:09 king
-
- * Source/cmMakefile.cxx: BUG: Fixed finding of MinGW libraries with
- a windows build of CMake.
-
-2006-02-07 12:53 andy
-
- * Source/CPack/cpack.cxx: ENH: Add missing help for -C option
-
-2006-02-07 11:43 andy
-
- * Source/kwsys/SystemTools.cxx: COMP: Fix compile problem on
- windows and mac
-
-2006-02-07 10:43 andy
-
- * Source/kwsys/SystemTools.cxx: COMP: Fix build problem
-
-2006-02-07 10:23 andy
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h,
- kwsys/SystemTools.cxx, kwsys/SystemTools.hxx.in: ENH: Move
- relative path to kwsys
-
-2006-02-07 10:11 king
-
- * bootstrap, Source/cmStandardIncludes.h,
- Source/kwsys/CMakeLists.txt, Source/kwsys/String.hxx.in: ENH:
- Added kwsys::String class to shorten debugging symbols and error
- messages involving std::string.
-
-2006-02-07 09:25 malaterre
-
- * Source/kwsys/SystemTools.hxx.in: ENH: Add some doc for visible
- class
-
-2006-02-07 08:49 andy
-
- * Source/: cmCTest.cxx, cmListFileCache.cxx, cmListFileCache.h,
- cmMakefile.cxx, cmTryCompileCommand.cxx, cmTryRunCommand.cxx,
- cmakemain.cxx, ctest.cxx, CTest/cmCTestBuildAndTestHandler.cxx:
- ENH: Since list file cache does not make much sense any more
- (because of proper list file parsing), and it actually adds
- unnecessary complications and make ctest scripting not work, take
- it out
-
-2006-02-07 08:03 david.cole
-
- * Utilities/cmtar/wrapper.c: COMP: Fix next round of dashboard
- warnings.
-
-2006-02-07 02:06 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-06 16:32 hoffman
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: allow for - in the
- name of targets for nmake
-
-2006-02-06 09:31 david.cole
-
- * Utilities/cmtar/: extract.c, output.c, wrapper.c: COMP: Fix CMake
- dashboard warnings related to previous revisions.
-
-2006-02-06 02:11 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-05 02:06 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-04 02:19 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-03 18:08 king
-
- * CMakeLists.txt: ENH: Incremented patch version for special KDE
- release.
-
-2006-02-03 17:09 king
-
- * Tests/: Complex/CMakeLists.txt, ComplexOneConfig/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt: ENH: Added test for new
- EXECUTE_PROCESS command.
-
-2006-02-03 16:55 king
-
- * Docs/cmake-mode.el: ENH: Adding new EXECUTE_PROCESS command that
- interfaces to KWSys Process Execution.
-
-2006-02-03 16:51 king
-
- * Source/: cmCommands.cxx, cmExecuteProcessCommand.cxx,
- cmExecuteProcessCommand.h: ENH: Adding new EXECUTE_PROCESS
- command that interfaces to KWSys Process Execution.
-
-2006-02-03 12:03 king
-
- * Source/cmGlobalXCodeGenerator.h: COMP: Added missing method decl
- to header.
-
-2006-02-03 11:48 david.cole
-
- * Utilities/cmtar/: decode.c, extract.c, output.c, wrapper.c: BUG:
- Fix mem leaks related to th_get_pathname. Change this
- implementation of th_get_pathname so that it *always* returns a
- strdup'ed value. Callers must now free non-NULL returns from
- th_get_pathname. Change all callers to call free appropriately.
-
-2006-02-03 11:36 king
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio6Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h, cmGlobalXCodeGenerator.cxx,
- cmTarget.cxx: BUG: Fixed cmTarget::GetFullPath to not append the
- configuration name when only one configuration is built. It now
- asks the generator what subdirectory if any to use for a given
- configuration name.
-
-2006-02-03 02:29 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-02 20:18 king
-
- * CMakeLists.txt, Source/CMakeLists.txt, Utilities/CMakeLists.txt:
- COMP: Fixed build on VC++ Express 2005. Explicitly testing for
- MFC to determine whether to build the MFCDialog.
-
-2006-02-02 20:16 king
-
- * Modules/CMakeGenericSystem.cmake: BUG: CMAKE_INSTALL_PREFIX must
- always have forward slashes.
-
-2006-02-02 20:15 king
-
- * Modules/Platform/Windows-cl.cmake: BUG: Removed odbc32.lib and
- odbccp32.lib from standard libraries on VS 8 because VC++ Express
- 2005 does not have them. They are SQL database access libraries
- and should not be needed for every application. User code can
- always explicitly link the library. Also replacing deprecated
- /GZ option with /RTC1 for VS 8. This addresses bug#2795.
-
-2006-02-02 15:53 david.cole
-
- * Utilities/cmtar/filesystem.c: BUG: Fix memory leak in libtar's
- kwReadDir. Use a static buffer like readdir (probably) does
- rather than malloc-ing a block which never gets free-d.
-
-2006-02-02 03:30 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-02-01 02:24 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-31 19:34 king
-
- * Source/: CMakeLists.txt, cmake.cxx: ENH: Enabled build of VS 7
- and 8 generators for MinGW.
-
-2006-01-31 18:50 king
-
- * bootstrap, Source/cmake.cxx: ENH: Enabled bootstrapping with
- MinGW from an MSYS prompt.
-
-2006-01-31 10:46 king
-
- * Source/cmGetFilenameComponentCommand.cxx: BUG: ABSOLUTE option
- should evaluate relative paths with respect to
- CMAKE_CURRENT_SOURCE_DIR. This addresses bug#2797.
-
-2006-01-31 05:09 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-30 14:25 martink
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: more cleanup and removal of
- old code
-
-2006-01-30 13:57 martink
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: cleanup and remove some old
- code
-
-2006-01-30 02:15 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-29 02:06 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-28 01:38 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-27 18:20 king
-
- * Source/: cmFindFileCommand.cxx, cmFindLibraryCommand.h,
- cmFindPathCommand.cxx, cmFindPathCommand.h, cmMakefile.cxx,
- cmMakefile.h: ENH: Improved support for user-configured search
- paths. Paths given in the CMAKE_LIBRARY_PATH cmake variable are
- searched first, then those in the CMAKE_LIBRARY_PATH environment
- variable, then those listed in the call to the FIND_LIBRARY
- command and finally those listed in the PATH environment
- variable. The support is similar for finding include files with
- FIND_PATH, but the variable is CMAKE_INCLUDE_PATH.
-
-2006-01-27 13:48 king
-
- * Source/: cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h: BUG: VS7 generator should use
- per-configuration linker flags for targets. This addresses
- bug#2765.
-
-2006-01-27 13:46 andy
-
- * Source/CTest/: cmCTestBuildHandler.cxx, cmCTestBuildHandler.h:
- ENH: Better handle interleved error/output
-
-2006-01-27 13:07 king
-
- * Modules/readme.txt, Source/cmFindPackageCommand.cxx,
- Source/cmFindPackageCommand.h: ENH: Added optional component list
- to the REQUIRED option of the FIND_PACKAGE command. This
- addresses bug#2771.
-
-2006-01-27 12:58 martink
-
- * Source/cmOptionCommand.h: STYLE: spelling fix
-
-2006-01-27 12:58 martink
-
- * Source/cmMessageCommand.h: STYLE: grammer fix
-
-2006-01-27 11:19 hoffman
-
- * Source/CTest/cmCTestUpdateHandler.cxx: ENH: add extra thing for
- svn X status output
-
-2006-01-27 01:36 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-26 01:21 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-25 14:12 hoffman
-
- * Source/cmTryCompileCommand.cxx: ENH: fix double
- CMAKE_(LANG)_FLAGS problem in try compile
-
-2006-01-25 12:16 hoffman
-
- * Modules/: FindQt.cmake, FindQt4.cmake: ENH: change to fatal error
-
-2006-01-25 11:41 hoffman
-
- * Modules/: CMakeCCompiler.cmake.in, CMakeCXXCompiler.cmake.in,
- CMakeDetermineCCompiler.cmake, CMakeDetermineCXXCompiler.cmake,
- CMakeDetermineFortranCompiler.cmake,
- CMakeDetermineJavaCompiler.cmake, CMakeDetermineRCCompiler.cmake:
- ENH: fix more than one argument passed in to compilers via
- environment
-
-2006-01-25 11:07 hoffman
-
- * Source/: cmMessageCommand.cxx, cmMessageCommand.h: ENH: fix docs,
- and revert fatal error change
-
-2006-01-25 08:39 hoffman
-
- * Source/cmMessageCommand.cxx: ENH: make all errors fatal in
- message command
-
-2006-01-25 08:38 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx,
- Source/cmGlobalXCodeGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Tests/Complex/Executable/CMakeLists.txt,
- Tests/Complex/Executable/complex.cxx,
- Tests/Complex/Executable/testcflags.c,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/testcflags.c,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/testcflags.c: ENH: add
- COMPILE_FLAGS to targets
-
-2006-01-25 00:57 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-24 15:48 hoffman
-
- * Source/cmStandardIncludes.h: ENH: fix for borland memcpy junk
-
-2006-01-24 12:07 andy
-
- * Modules/CheckCXXSourceCompiles.cmake: ENH: fix bug, write the
- correct file
-
-2006-01-24 07:58 hoffman
-
- * Source/cmLocalGenerator.cxx: COMP: fix warning
-
-2006-01-24 00:57 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-23 17:24 hoffman
-
- * Source/cmLocalGenerator.cxx: ENH: fix warning
-
-2006-01-23 16:36 martink
-
- * Source/kwsys/SystemTools.cxx: ENH: by Bill make sure path is unix
- style
-
-2006-01-23 13:50 hoffman
-
- * Source/: CMakeLists.txt, cmGlobalWatcomWMakeGenerator.cxx,
- cmLocalGenerator.cxx: ENH: fix problem with watcom and short
- paths and -I
-
-2006-01-23 12:31 hoffman
-
- * Source/cmDepends.cxx: ENH: correct include for memcpy
-
-2006-01-23 11:32 hoffman
-
- * Modules/Platform/kFreeBSD.cmake: ENH: add kFreeBSD support
-
-2006-01-23 00:51 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-22 21:15 hoffman
-
- * Modules/CheckTypeSize.cmake: ENH: fix check type size
-
-2006-01-22 00:47 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-21 00:51 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-20 01:01 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-19 00:57 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-18 00:47 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-17 16:53 hoffman
-
- * Source/kwsys/SystemTools.hxx.in: ENH: fix for icc
-
-2006-01-17 16:22 martink
-
- * Utilities/cmcurl/CMake/CheckTypeSize.cmake: BUG: revert such that
- it should work
-
-2006-01-17 14:35 hoffman
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt: ENH: more fixes
- for watcom
-
-2006-01-17 10:21 hoffman
-
- * Modules/CMakeBackwardCompatibilityCXX.cmake,
- Modules/CMakeFindWMake.cmake, Modules/TestForSSTREAM.cmake,
- Modules/TestForSSTREAM.cxx, Modules/readme.txt,
- Modules/Platform/Windows-wcl386.cmake, Source/CMakeLists.txt,
- Source/cmCPluginAPI.cxx, Source/cmCPluginAPI.h,
- Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmGlobalWatcomWMakeGenerator.cxx,
- Source/cmGlobalWatcomWMakeGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalUnixMakefileGenerator3.h, Source/cmStringCommand.h,
- Source/cmake.cxx, Source/kwsys/Directory.cxx,
- Source/kwsys/EncodeExecutable.c, Source/kwsys/Glob.cxx,
- Source/kwsys/ProcessWin32.c, Source/kwsys/Registry.cxx,
- Source/kwsys/SystemTools.cxx, Source/kwsys/SystemTools.hxx.in,
- Source/kwsys/kwsysPlatformCxxTests.cxx,
- Source/kwsys/testRegistry.cxx,
- Tests/Complex/cmTestConfigure.h.in,
- Tests/Complex/Executable/CMakeLists.txt,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/cmTestConfigure.h.in,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/cmTestConfigure.h.in,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/complex.cxx,
- Tests/LoadCommand/CMakeCommands/CMakeLists.txt,
- Tests/LoadCommand/CMakeCommands/cmTestCommand.c,
- Tests/LoadCommandOneConfig/CMakeCommands/CMakeLists.txt,
- Tests/LoadCommandOneConfig/CMakeCommands/cmTestCommand.c,
- Tests/SubDir/CMakeLists.txt,
- Tests/SubDir/vcl_algorithm_vcl_pair_double.foo.c,
- Tests/SubDir/AnotherSubdir/pair_int.int.c,
- Tests/SubDir/ThirdSubDir/pair_int.int1.c,
- Utilities/cmcurl/CMakeLists.txt, Utilities/cmcurl/timeval.h,
- Utilities/cmcurl/CMake/CheckTypeSize.c.in,
- Utilities/cmcurl/CMake/CheckTypeSize.cmake,
- Utilities/cmcurl/Platforms/WindowsCache.cmake,
- Utilities/cmtar/handle.c, Utilities/cmtar/libtar.c: ENH: add
- support for watcom wmake and wcl386
-
-2006-01-17 09:27 hoffman
-
- * Modules/Platform/Windows-cl.cmake: ENH: correct standard
- libraries
-
-2006-01-17 00:46 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-16 12:54 yogi.girdhar
-
- * Utilities/cmtar/compat/compat.h: COMP: wrapped compat.h inside a
- extern C block so that we can use it in C++ code
-
-2006-01-16 00:42 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-15 00:43 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-14 10:27 king
-
- * Source/cmGlobalXCodeGenerator.cxx: COMP: Fixed shadowed variable
- warning.
-
-2006-01-14 00:42 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-13 20:51 king
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: Further centralized custom
- command dependency computation. Custom command dependencies in
- the source tree may now also be specified relative to the source
- directory.
-
-2006-01-13 19:36 king
-
- * Source/cmFLTKWrapUICommand.cxx: BUG: Removed bogust dependency.
-
-2006-01-13 19:35 king
-
- * Source/: cmFileCommand.cxx, cmLocalGenerator.cxx: COMP: Removed
- unused variables.
-
-2006-01-13 18:33 king
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h,
- cmLocalUnixMakefileGenerator3.cxx: COMP: Removed unused paramter
- from cmLocalGenerator::OutputLinkLibraries.
-
-2006-01-13 18:18 king
-
- * Source/cmFileCommand.cxx, Source/cmGlobalGenerator.h,
- Source/cmGlobalVisualStudio6Generator.cxx,
- Source/cmGlobalVisualStudio71Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.h,
- Source/cmGlobalXCodeGenerator.cxx,
- Source/cmGlobalXCodeGenerator.h,
- Source/cmLinkLibrariesCommand.cxx, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalUnixMakefileGenerator3.h,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h, Source/cmMakefile.cxx,
- Source/cmOrderLinkDirectories.cxx,
- Source/cmOrderLinkDirectories.h, Source/cmTarget.cxx,
- Source/cmTarget.h, Source/cmTargetLinkLibrariesCommand.cxx,
- Source/cmTargetLinkLibrariesCommand.h, Source/cmXCodeObject.h,
- Source/CTest/cmCTestBuildAndTestHandler.cxx,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/complex.cxx: BUG: Sweeping
- changes to cleanup computation of target names. This should fix
- many bugs related to target names being computed inconsistently.
-
- - Centralized computation of a target's file name to a method in
- cmTarget. Now that global knowledge is always available the
- *_CMAKE_PATH cache variables are no longer needed.
-
- - Centralized computation of link library command lines and link
- directory search order.
-
- - Moved computation of link directories needed to link CMake
- targets to be after evaluation of linking dependencies.
-
- This also removed alot of duplicate code in which each version
- had its own bugs.
-
- This commit is surrounded by the tags
-
- CMake-TargetNameCentralization1-pre
-
- and
-
- CMake-TargetNameCentralization1-post
-
- so make the large set of changes easy to identify.
-
-2006-01-13 11:44 hoffman
-
- * Source/cmTryCompileCommand.cxx,
- Utilities/cmcurl/CMake/CheckTypeSize.cmake: ENH: fix for CMakeTmp
- move broken stuff
-
-2006-01-13 09:57 hoffman
-
- * Modules/: CheckTypeSize.c.in, CheckTypeSize.cmake: ENH: fix
- checktypesize
-
-2006-01-13 00:43 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-12 23:08 hoffman
-
- * Modules/: CheckTypeSize.c.in, CheckTypeSize.cmake: ENH: move
- define into configured file and do not use the command line
-
-2006-01-12 14:21 andy
-
- * Source/: cmGeneratedFileStream.cxx, cmGeneratedFileStream.h:
- COMP: Remove warning
-
-2006-01-12 13:48 martink
-
- * Modules/CMakeTestCCompiler.cmake,
- Modules/CMakeTestCXXCompiler.cmake,
- Modules/CMakeTestFortranCompiler.cmake,
- Modules/CheckCSourceCompiles.cmake,
- Modules/CheckCXXSourceCompiles.cmake,
- Modules/CheckIncludeFile.cmake,
- Modules/CheckIncludeFileCXX.cmake,
- Modules/CheckIncludeFiles.cmake, Modules/CheckSymbolExists.cmake,
- Modules/CheckTypeSize.cmake, Modules/FindSDL_sound.cmake,
- Modules/Platform/Windows-cl.cmake,
- Source/cmTryCompileCommand.cxx, Source/cmTryCompileCommand.h,
- Source/cmTryRunCommand.cxx,
- Utilities/cmcurl/CMake/CheckTypeSize.cmake,
- Tests/TryCompile/CMakeLists.txt: ENH: put CmakeTmp into
- CMakeFiles
-
-2006-01-12 11:10 hoffman
-
- * Modules/FindwxWindows.cmake: ENH: contribution from Jan Woetzel
-
-2006-01-12 09:20 andy
-
- * Source/cmGeneratedFileStream.cxx: COMP: Fix compile error that
- was caused by the binary flag
-
-2006-01-12 00:40 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-11 19:12 andy
-
- * Source/CPack/cmCPackTGZGenerator.cxx: ENH: Fix compression on
- Windows
-
-2006-01-11 19:06 andy
-
- * Source/: cmGeneratedFileStream.cxx, cmGeneratedFileStream.h: ENH:
- Add support for binary
-
-2006-01-11 11:23 andy
-
- * Source/CPack/cmCPackGenericGenerator.cxx: ENH: Add a way to
- specify a custom install command
-
-2006-01-11 11:08 andy
-
- * CMakeLists.txt, Modules/CPack.cmake, Modules/NSIS.template.in,
- Source/CPack/cmCPackGenericGenerator.cxx,
- Templates/CPackConfig.cmake.in: ENH: Some improvements: specify
- link, copy msvc libraries, fix install directory
-
-2006-01-11 00:42 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-10 12:05 andy
-
- * Source/CPack/: cmCPackConfigure.h.in, cmCPackNSISGenerator.cxx,
- cmCPackNSISGenerator.h, cmCPackPackageMakerGenerator.h: COMP:
- Remove legacy code and fix sun build
-
-2006-01-10 00:44 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-09 18:24 andy
-
- * Modules/NSIS.template.in,
- Source/CPack/cmCPackGenericGenerator.cxx: ENH: Use specified
- output file name, also detect errors during install
-
-2006-01-09 18:20 andy
-
- * Templates/CPackConfig.cmake.in: ENH: Pass CPACK_PACKAGE_FILE_NAME
-
-2006-01-09 18:20 andy
-
- * Modules/CPack.cmake: ENH: Cleanup
-
-2006-01-09 16:34 andy
-
- * Modules/NSIS.template.in: BUG: Allow spaces in path
-
-2006-01-09 14:56 hoffman
-
- * Tests/CustomCommand/GeneratedHeader/: CMakeLists.txt,
- generated.h.in, main.cpp: ENH: add test for generated header
-
-2006-01-09 14:40 hoffman
-
- * Source/cmCustomCommand.cxx, Source/cmCustomCommand.h,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx, Source/cmTarget.cxx,
- Tests/CustomCommand/CMakeLists.txt,
- Tests/Wrapping/CMakeLists.txt, Tests/Wrapping/fakefluid.cxx: ENH:
- for all custom commands that can not be given to a target, add
- them to all targets in the current makefile
-
-2006-01-09 13:15 andy
-
- * CMakeLists.txt: STYLE: Add an explanation for a bunch of
- backslashes
-
-2006-01-09 13:14 andy
-
- * Source/CPack/cmCPackTGZGenerator.cxx: BUG: Fix memory problem
-
-2006-01-09 12:46 hoffman
-
- * Utilities/Release/: Release.cmake, cmake_release.sh.in: ENH:
-
-2006-01-09 12:45 hoffman
-
- * Modules/: FindQt.cmake, FindQt4.cmake: ENH: add qt quiet stuff
-
-2006-01-09 11:26 andy
-
- * CMakeLists.txt, Modules/CPack.cmake,
- Source/CPack/cmCPackGenericGenerator.cxx,
- Templates/CPackConfig.cmake.in: ENH: Fix test for cpack
- variables, add support for icon on windows
-
-2006-01-09 00:41 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-08 00:41 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-07 00:43 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-06 15:51 hoffman
-
- * Modules/: CMakeMSYSFindMake.cmake, CMakeMinGWFindMake.cmake,
- Platform/Linux-icpc.cmake: ENH: merge from main tree
-
-2006-01-06 15:51 hoffman
-
- * Source/: cmGlobalMSYSMakefileGenerator.cxx,
- cmGlobalMSYSMakefileGenerator.h,
- cmGlobalMinGWMakefileGenerator.cxx,
- cmGlobalMinGWMakefileGenerator.h: ENH: add missing files
-
-2006-01-06 15:07 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeGenericSystem.cmake,
- Modules/Platform/CYGWIN-g77.cmake, Modules/Platform/CYGWIN.cmake,
- Modules/Platform/Windows-cl.cmake,
- Modules/Platform/Windows-g77.cmake,
- Modules/Platform/Windows-gcc.cmake,
- Modules/Platform/Windows.cmake, Source/CMakeLists.txt,
- Source/cmAddExecutableCommand.cxx, Source/cmCTest.cxx,
- Source/cmDependsC.cxx, Source/cmDependsC.h,
- Source/cmFindFileCommand.cxx, Source/cmFindFileCommand.h,
- Source/cmFindPathCommand.cxx, Source/cmFindPathCommand.h,
- Source/cmGlobalBorlandMakefileGenerator.cxx,
- Source/cmGlobalNMakeMakefileGenerator.cxx,
- Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmGlobalXCodeGenerator.cxx,
- Source/cmGlobalXCodeGenerator.h, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalUnixMakefileGenerator3.h, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmOrderLinkDirectories.cxx,
- Source/cmOrderLinkDirectories.h, Source/cmSystemTools.cxx,
- Source/cmSystemTools.h, Source/cmTarget.cxx, Source/cmTarget.h,
- Source/cmake.cxx, Source/CTest/cmCTestBuildAndTestHandler.cxx,
- Source/kwsys/ProcessUNIX.c, Source/kwsys/SystemTools.cxx,
- Source/kwsys/SystemTools.hxx.in, Tests/Complex/CMakeLists.txt,
- Tests/Complex/cmTestConfigure.h.in,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexOneConfig/cmTestConfigure.h.in,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/CMakeLists.txt,
- Tests/ComplexRelativePaths/cmTestConfigure.h.in,
- Tests/ComplexRelativePaths/Executable/complex.cxx,
- Tests/CustomCommand/CMakeLists.txt,
- Utilities/Release/cmake_release.sh,
- Utilities/Release/cmake_release.sh.in: ENH: merges from main tree
-
-2006-01-06 13:54 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: fix missing plist file
- error
-
-2006-01-06 10:45 andy
-
- * Utilities/cmtar/compat/snprintf.c: COMP: Try to remove more
- warnings
-
-2006-01-06 00:43 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-05 17:16 king
-
- * Source/: cmDependsC.cxx, cmDependsC.h: BUG: Fix for scanning
- generated headers included with double-quotes. Also fixed
- double-quote include support to not use the special quoted
- location when a full path is given on the include line.
-
-2006-01-05 15:49 king
-
- * Source/kwsys/testProcess.c: ENH: Added special test 0 to just run
- a given command line.
-
-2006-01-05 13:27 andy
-
- * Source/CPack/: cmCPackGenericGenerator.cxx, cpack.cxx: ENH: More
- debugging and work on PackageMaker code
-
-2006-01-05 13:25 yogi.girdhar
-
- * Utilities/cmtar/: config.h.in, libtar.c: BUG: libtar now compiles
- in VJ and works with vtkzlib
-
-2006-01-05 12:33 andy
-
- * Source/CPack/cmCPackLog.cxx: ENH: flush the output
-
-2006-01-05 12:16 andy
-
- * Source/CPack/cpack.cxx: BUG: Use objects that exist
-
-2006-01-05 12:16 andy
-
- * Source/CPack/cmCPackLog.cxx: BUG: Print the right line number to
- the right pipe
-
-2006-01-05 10:37 andy
-
- * Source/CPack/cmCPackPackageMakerGenerator.cxx: BUG: Revert back
-
-2006-01-05 09:18 hoffman
-
- * CMakeLists.txt: ENH: use a safer check for CPack
-
-2006-01-05 09:13 hoffman
-
- * Source/: cmAddExecutableCommand.cxx, cmGlobalXCodeGenerator.cxx,
- cmLocalUnixMakefileGenerator3.cxx, cmMakefile.cxx: ENH: fix
- bundles for Mac and Xcode
-
-2006-01-05 03:15 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-04 16:24 hoffman
-
- * Source/CPack/cmCPackTGZGenerator.cxx: ENH: remove assert
-
-2006-01-04 15:13 andy
-
- * CMakeLists.txt, Modules/CPack.Description.plist.in,
- Modules/NSIS.template.in,
- Source/CPack/cmCPackGenericGenerator.cxx,
- Source/CPack/cmCPackSTGZGenerator.cxx,
- Source/CPack/cmCPackTGZGenerator.cxx, Source/CPack/cpack.cxx,
- Modules/CPack.cmake, Templates/CPackConfig.cmake.in: ENH: More
- CPack stuff and fix zlib compression
-
-2006-01-04 09:55 hoffman
-
- * Source/cmFindPathCommand.cxx: ENH: remove debug print stuff
-
-2006-01-04 08:32 andy
-
- * Source/kwsys/CMakeLists.txt: COMP: Do not build tests if build
- testing is off
-
-2006-01-04 01:15 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-03 17:11 hoffman
-
- * Utilities/Release/cmake_release.sh: ENH: update revision numbers
-
-2006-01-03 17:07 hoffman
-
- * Utilities/Release/cmake_release.sh.in: ENH: move to patch 2
-
-2006-01-03 16:40 hoffman
-
- * Source/cmMakefile.cxx, Source/cmMakefile.h,
- Tests/Complex/CMakeLists.txt, Tests/Complex/cmTestConfigure.h.in,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexOneConfig/cmTestConfigure.h.in,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/CMakeLists.txt,
- Tests/ComplexRelativePaths/cmTestConfigure.h.in,
- Tests/ComplexRelativePaths/Executable/complex.cxx: ENH: add new
- cmakedefine01 feature from bug report 2603
-
-2006-01-03 14:00 hoffman
-
- * Modules/Platform/: CYGWIN-g77.cmake, CYGWIN.cmake: ENH: add exe
- stuff for cygwin
-
-2006-01-03 08:39 andy
-
- * Source/cmSystemTools.cxx: COMP: Remove warnings on HP-UX
-
-2006-01-03 08:39 andy
-
- * Utilities/cmtar/append.c, Utilities/cmtar/extract.c,
- Utilities/cmtar/libtar.c, Source/CPack/cmCPackLog.cxx,
- Source/CPack/cpack.cxx: COMP: Remove warnings
-
-2006-01-03 01:11 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-02 17:28 andy
-
- * Source/CPack/: cmCPackGenerators.cxx,
- cmCPackGenericGenerator.cxx, cmCPackGenericGenerator.h,
- cmCPackNSISGenerator.cxx, cmCPackNSISGenerator.h,
- cmCPackPackageMakerGenerator.cxx, cmCPackPackageMakerGenerator.h,
- cmCPackSTGZGenerator.cxx, cmCPackSTGZGenerator.h,
- cmCPackTGZGenerator.cxx, cmCPackTGZGenerator.h, cpack.cxx: ENH:
- Start working on CPack input file and cleanups
-
-2006-01-02 17:22 andy
-
- * Source/CPack/: cmCPackLog.h, cmCPackLog.cxx: COMP: Fix compile
- errors
-
-2006-01-02 16:14 andy
-
- * Source/: CMakeLists.txt, CPack/cmCPackGenerators.cxx,
- CPack/cmCPackGenerators.h, CPack/cmCPackGenericGenerator.cxx,
- CPack/cmCPackGenericGenerator.h, CPack/cmCPackLog.cxx,
- CPack/cmCPackLog.h, CPack/cmCPackNSISGenerator.cxx,
- CPack/cmCPackPackageMakerGenerator.cxx,
- CPack/cmCPackSTGZGenerator.cxx, CPack/cmCPackTGZGenerator.cxx,
- CPack/cpack.cxx: ENH: More improvements and add logging
-
-2006-01-02 15:01 hoffman
-
- * Tests/: CustomCommand/CMakeLists.txt, Wrapping/CMakeLists.txt:
- BUG: force EXECUABLE and LIBRARY output paths so bad cache
- entries do not fail tests
-
-2006-01-02 14:33 andy
-
- * Tests/: Complex/CMakeLists.txt, ComplexOneConfig/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt: BUG: Flush the EXECUTABLE
- and LIBRARY output path to internal
-
-2006-01-02 13:37 hoffman
-
- * Modules/CMakeGenericSystem.cmake,
- Modules/Platform/Windows-g77.cmake,
- Modules/Platform/Windows-gcc.cmake,
- Modules/Platform/Windows.cmake, Source/cmTarget.cxx: BUG: fix for
- bug 2322, use CMAKE_EXECUTABLE_SUFFIX variable for exe suffix
-
-2006-01-02 13:34 hoffman
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: BUG: fix build problem
- on gcc
-
-2006-01-02 12:36 hoffman
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: BUG: fix for bug 2533, make
- foo/foo.o now works and .o files are in the help
-
-2006-01-02 11:39 andy
-
- * Source/CPack/cmCPackGenericGenerator.cxx: COMP: Remove warning
-
-2006-01-02 11:21 hoffman
-
- * Utilities/Release/Release.cmake: ENH: remove MS dll's from
- install on cygwin
-
-2006-01-02 11:07 hoffman
-
- * Source/: cmFindPathCommand.cxx, cmMakefile.cxx: ENH: change
- framework order
-
-2006-01-02 10:37 andy
-
- * Source/CPack/: cmCPackGenericGenerator.cxx,
- cmCPackGenericGenerator.h, cmCPackTGZGenerator.cxx,
- cmCPackTGZGenerator.h: COMP: Fix build problems
-
-2006-01-02 10:36 andy
-
- * Source/cmGeneratedFileStream.cxx: BUG: Fix the compression with
- custom extension
-
-2006-01-02 07:53 andy
-
- * Source/CPack/: cmCPackPackageMakerGenerator.cxx,
- cmCPackTGZGenerator.cxx, cmCPackTGZGenerator.h: ENH: Use libtar
-
-2006-01-02 07:52 andy
-
- * Source/: cmGeneratedFileStream.cxx, cmGeneratedFileStream.h: ENH:
- Add a way to overwrite compression extension
-
-2006-01-02 01:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2006-01-01 23:31 andy
-
- * Source/: CMakeLists.txt, cmSystemTools.cxx, cmSystemTools.h: ENH:
- Merge from cpack branch
-
-2006-01-01 23:28 andy
-
- * Modules/: CPack.Description.plist.in, CPack.Info.plist.in,
- NSIS.template.in: ENH: Merge from CPack branch
-
-2006-01-01 23:21 andy
-
- * Source/CPack/: cmCPackConfigure.h.in, cmCPackGenerators.cxx,
- cmCPackGenerators.h, cmCPackGenericGenerator.cxx,
- cmCPackGenericGenerator.h, cmCPackNSISGenerator.cxx,
- cmCPackNSISGenerator.h, cmCPackPackageMakerGenerator.cxx,
- cmCPackPackageMakerGenerator.h, cmCPackSTGZGenerator.cxx,
- cmCPackSTGZGenerator.h, cmCPackTGZGenerator.cxx,
- cmCPackTGZGenerator.h, cpack.cxx: ENH: Merge from the cpack
- branch
-
-2006-01-01 01:05 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-31 13:10 king
-
- * Tests/TarTest/CMakeLists.txt: ENH: Simplified ln command to use
- relative path in symlink.
-
-2005-12-31 12:59 king
-
- * Source/kwsys/ProcessUNIX.c: BUG: When more than one command is
- given and one of them fails to start and the rest are killed, do
- not forget to reap the killed children.
-
-2005-12-31 10:33 andy
-
- * Utilities/cmtar/: CMakeLists.txt, config.h.in, internal.h: COMP:
- Try to fix major/minor problem on aix
-
-2005-12-31 09:40 andy
-
- * Utilities/cmtar/: CMakeLists.txt, config.h.in, internal.h: COMP:
- Attempt to fix problems with major and minor
-
-2005-12-31 01:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-30 21:54 hoffman
-
- * Source/: cmFindFileCommand.cxx, cmFindFileCommand.h,
- cmFindPathCommand.cxx, cmFindPathCommand.h: ENH: move framework
- stuff from FindFile to FindPath
-
-2005-12-30 21:54 hoffman
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: fix so verbose is
- put in the correct place
-
-2005-12-30 17:51 andy
-
- * Utilities/cmtar/compat/snprintf.c: COMP: Fix systems that do not
- have both vsnprintf and snprintf.
-
-2005-12-30 17:27 andy
-
- * Utilities/cmtar/: CMakeLists.txt, config.h.in, compat/compat.h,
- compat/snprintf.c: COMP: Fix support for vsnprintf
-
-2005-12-30 16:28 andy
-
- * Source/cmSystemTools.cxx: COMP: Fix warning on sun
-
-2005-12-30 16:05 andy
-
- * Utilities/cmtar/extract.c: COMP: Another borland bug
-
-2005-12-30 15:46 andy
-
- * Tests/TarTest/CMakeLists.txt: ENH: Add testing of symlinks too
-
-2005-12-30 15:46 andy
-
- * Utilities/cmtar/extract.c: BUG: Handle mkdirhier properly since
- it may modify the string
-
-2005-12-30 15:32 andy
-
- * Source/cmSystemTools.cxx: COMP: Remove sun warning
-
-2005-12-30 15:27 andy
-
- * Source/CMakeLists.txt, Tests/TarTest/CMakeLists.txt,
- Tests/TarTest/TestTarExec.cxx: ENH: Add a tar test
-
-2005-12-30 15:25 andy
-
- * Source/cmake.cxx: ENH: Add a way to compare two files
-
-2005-12-30 14:51 andy
-
- * Source/cmSystemTools.cxx, Utilities/cmtar/handle.c,
- Utilities/cmtar/libtar.c, Utilities/cmtar/libtar.h: ENH: Cleanup
- the file handler stuf so that now any file descriptor type can be
- used
-
-2005-12-30 14:50 andy
-
- * CMakeLists.txt, Utilities/cmcurl/CMakeLists.txt,
- Utilities/cmexpat/CMakeLists.txt, Utilities/cmtar/CMakeLists.txt,
- Utilities/cmzlib/CMakeLists.txt, Source/CMakeLists.txt: COMP:
- Cleanup regular expressions
-
-2005-12-30 14:31 andy
-
- * Source/cmSystemTools.cxx: COMP: Remove unused variable
-
-2005-12-30 14:23 andy
-
- * Utilities/cmtar/compat/: basename.c, dirname.c: COMP: Remove
- warnings by exposing some variables
-
-2005-12-30 14:22 andy
-
- * Source/cmSystemTools.cxx, Utilities/cmtar/handle.c,
- Utilities/cmtar/libtar.c, Utilities/cmtar/libtar.h: COMP: Fix
- support for gzip on non-32 bit platforms
-
-2005-12-30 13:22 andy
-
- * Utilities/cmtar/util.c: COMP: Remove warning about argument not
- being int
-
-2005-12-30 13:22 andy
-
- * Source/: cmFindFileCommand.cxx, cmGlobalXCodeGenerator.cxx: COMP:
- Remove shadow variable warning
-
-2005-12-30 12:58 andy
-
- * Source/cmSystemTools.cxx: COMP: Use mangle names
-
-2005-12-30 12:58 andy
-
- * Source/: cmFindFileCommand.cxx, cmTarget.cxx: COMP: Remove
- warnings
-
-2005-12-30 10:35 andy
-
- * Utilities/cmtar/: CMakeLists.txt, append.c, config.h.in,
- encode.c, internal.h, output.c, util.c, wrapper.c: BUG: Several
- Borland fixes
-
-2005-12-30 01:11 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-29 12:19 andy
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h, cmake.cxx: ENH: Make
- the syntax more line tar
-
-2005-12-29 12:18 andy
-
- * Utilities/cmtar/append.c: COMP: More cygwin fixes
-
-2005-12-29 11:42 andy
-
- * Utilities/cmtar/append.c: BUG: Fix on cygwin... again?
-
-2005-12-29 11:15 andy
-
- * Utilities/cmtar/output.c: COMP: Try to remove warnings and add
- support for cygwin
-
-2005-12-29 10:52 andy
-
- * Source/cmake.cxx: ENH: Make additional file names optional
-
-2005-12-29 10:43 andy
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h, cmake.cxx: ENH: Add
- untaring support
-
-2005-12-29 10:41 andy
-
- * Utilities/cmtar/extract.c: BUG: Fix extract. Looks like dirname
- actually changes the string, so temporary string should be used
-
-2005-12-29 09:11 andy
-
- * Utilities/cmtar/: output.c, compat/compat.h: COMP: Remove c++
- style comments
-
-2005-12-29 01:04 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-28 20:04 andy
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt: BUG: Now really
- fix the test
-
-2005-12-28 19:31 andy
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt: COMP: Fix test
-
-2005-12-28 17:02 andy
-
- * Source/cmSystemTools.cxx,
- Tests/Complex/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt: COMP: Fix
- complex test and fix bootstrap
-
-2005-12-28 16:53 andy
-
- * Source/cmSystemTools.cxx: COMP: Add missing include
-
-2005-12-28 16:44 andy
-
- * Source/cmSystemTools.cxx: BUG: Return proper values
-
-2005-12-28 16:43 andy
-
- * Utilities/cmtar/: extract.c, libtar.c: COMP: Remove more warnings
-
-2005-12-28 16:31 andy
-
- * Source/cmake.cxx: ENH: Add command to create tar
-
-2005-12-28 16:30 andy
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Add method to
- create tar
-
-2005-12-28 16:30 andy
-
- * Source/CMakeLists.txt: COMP: Link tar library to cmake
-
-2005-12-28 16:29 andy
-
- * CMakeLists.txt: COMP: Fix path to include files
-
-2005-12-28 15:31 andy
-
- * Utilities/cmtar/: CMakeLists.txt, config.h.in, handle.c,
- compat/compat.h: COMP: Remove more warnings and rename library to
- cmtar
-
-2005-12-28 15:03 andy
-
- * Utilities/cmtar/append.c: COMP: Remove warning
-
-2005-12-28 14:58 andy
-
- * Utilities/cmtar/: CMakeLists.txt, append.c, decode.c, extract.c,
- filesystem.c, filesystem.h, handle.c, internal.h, libtar.c,
- util.c, wrapper.c, compat/basename.c, compat/compat.h,
- compat/dirname.c: COMP: Several borland fixes
-
-2005-12-28 14:50 andy
-
- * Utilities/cmtar/compat/snprintf.c: COMP: Remove warnings
-
-2005-12-28 13:36 andy
-
- * CMakeLists.txt: ENH: First cut at enabling tar
-
-2005-12-28 13:35 andy
-
- * Utilities/cmtar/append.c: COMP: Only do O_BINARY on windows
-
-2005-12-28 13:33 andy
-
- * Utilities/cmtar/: append.c, libtar.c: COMP: Fix windows
-
-2005-12-28 13:01 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-28 12:34 andy
-
- * Utilities/cmtar/libtar.c: ENH: Fix building on cygwin
-
-2005-12-28 12:24 andy
-
- * Utilities/cmtar/: CMakeLists.txt, config.h.in, extract.c,
- libtar.c: COMP: Fix build on sun by adding missing include
-
-2005-12-28 11:00 andy
-
- * Utilities/cmtar/: CMakeLists.txt, decode.c, filesystem.c,
- wrapper.c, compat/basename.c, compat/dirname.c, compat/fnmatch.c,
- compat/snprintf.c: ENH: Windows fixes
-
-2005-12-28 10:28 andy
-
- * CMakeLists.txt: ENH: Merge change from the main tree
-
-2005-12-28 10:19 andy
-
- * CMakeLists.txt: ENH: Initial setup of libtar
-
-2005-12-28 10:18 andy
-
- * Utilities/cmtar/: CMakeLists.txt, COPYRIGHT, append.c, block.c,
- config.h.in, decode.c, encode.c, extract.c, filesystem.c,
- filesystem.h, handle.c, internal.h, libtar.c, libtar.h, output.c,
- tar.h, util.c, wrapper.c, compat/README, compat/basename.c,
- compat/compat.h, compat/dirname.c, compat/fnmatch.c,
- compat/gethostbyname_r.c, compat/gethostname.c,
- compat/getservbyname_r.c, compat/glob.c, compat/inet_aton.c,
- compat/snprintf.c, compat/strdup.c, compat/strlcat.c,
- compat/strlcpy.c, compat/strmode.c, compat/strrstr.c,
- compat/strsep.c, listhash/hash.c.in, listhash/list.c.in,
- listhash/listhash.h.in: ENH: Initial import
-
-2005-12-28 10:09 andy
-
- * Utilities/cmtar/: CMakeLists.txt, COPYRIGHT, append.c, block.c,
- config.h.in, decode.c, encode.c, extract.c, filesystem.c,
- filesystem.h, handle.c, internal.h, libtar.c, libtar.h, output.c,
- tar.h, util.c, wrapper.c, compat/README, compat/basename.c,
- compat/compat.h, compat/dirname.c, compat/fnmatch.c,
- compat/gethostbyname_r.c, compat/gethostname.c,
- compat/getservbyname_r.c, compat/glob.c, compat/inet_aton.c,
- compat/snprintf.c, compat/strdup.c, compat/strlcat.c,
- compat/strlcpy.c, compat/strmode.c, compat/strrstr.c,
- compat/strsep.c, listhash/hash.c.in, listhash/list.c.in,
- listhash/listhash.h.in: ENH: Initial import
-
-2005-12-28 10:07 andy
-
- * Source/cmake.cxx: ENH: Add file compare
-
-2005-12-27 15:33 hoffman
-
- * Source/: cmFindFileCommand.cxx, cmFindFileCommand.h,
- cmLocalUnixMakefileGenerator3.cxx: ENH: make sure -F is not
- duplicated
-
-2005-12-27 15:08 andy
-
- * Source/CPack/: cmCPackConfigure.h.in, cmCPackGenerators.cxx,
- cmCPackGenerators.h, cmCPackGenericGenerator.cxx,
- cmCPackGenericGenerator.h, cmCPackNSISGenerator.cxx,
- cmCPackNSISGenerator.h, cmCPackPackageMakerGenerator.cxx,
- cmCPackPackageMakerGenerator.h, cmCPackSTGZGenerator.h,
- cmCPackTGZGenerator.cxx, cmCPackTGZGenerator.h: ENH: Remove
- references to m_Makefile. It is now private. Fix several build
- problems. Change generator creation. ...
-
-2005-12-27 14:56 hoffman
-
- * Source/: cmFindFileCommand.cxx, cmFindFileCommand.h,
- cmGlobalXCodeGenerator.cxx, cmLocalGenerator.cxx: ENH: add
- framework support to FIND_FILE
-
-2005-12-27 14:32 andy
-
- * Source/CPack/cpack.cxx, Utilities/CMakeLists.txt: ENH: Improve
- help arguments and add generation of doc files
-
-2005-12-27 13:10 andy
-
- * Source/cmCTest.cxx: ENH: Fix command line argument parsing
-
-2005-12-27 13:03 hoffman
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: remove warning
-
-2005-12-26 13:14 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmLocalGenerator.cxx,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h, cmMakefile.cxx,
- cmOrderLinkDirectories.cxx, cmOrderLinkDirectories.h,
- cmSystemTools.cxx, cmSystemTools.h, cmTarget.cxx, cmTarget.h,
- kwsys/SystemTools.cxx: ENH: add better support for framework
- linking
-
-2005-12-26 01:06 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-25 01:07 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-24 01:03 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-23 01:09 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-22 16:42 hoffman
-
- * Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeMSYSFindMake.cmake,
- Modules/CMakeMinGWFindMake.cmake, Source/CMakeLists.txt,
- Source/cmGlobalBorlandMakefileGenerator.cxx,
- Source/cmGlobalMSYSMakefileGenerator.cxx,
- Source/cmGlobalMSYSMakefileGenerator.h,
- Source/cmGlobalMinGWMakefileGenerator.cxx,
- Source/cmGlobalMinGWMakefileGenerator.h,
- Source/cmGlobalNMakeMakefileGenerator.cxx,
- Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmLocalGenerator.cxx, Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalUnixMakefileGenerator3.h, Source/cmake.cxx: ENH:
- fix borland make clean targets before build, add new generators
- for msys and mingw
-
-2005-12-22 16:02 hoffman
-
- * ChangeLog.manual, Modules/CMake.cmake,
- Modules/CMakeBackwardCompatibilityC.cmake,
- Modules/CMakeBackwardCompatibilityCXX.cmake,
- Modules/CMakeCInformation.cmake,
- Modules/CMakeCXXInformation.cmake,
- Modules/CMakeCommonLanguageInclude.cmake,
- Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Modules/CMakeDetermineFortranCompiler.cmake,
- Modules/CMakeDetermineJavaCompiler.cmake,
- Modules/CMakeDetermineRCCompiler.cmake,
- Modules/CMakeDetermineSystem.cmake,
- Modules/CMakeExportBuildSettings.cmake,
- Modules/CMakeFindFrameworks.cmake,
- Modules/CMakeFortranInformation.cmake,
- Modules/CMakeImportBuildSettings.cmake,
- Modules/CMakeJavaInformation.cmake,
- Modules/CMakePrintSystemInformation.cmake,
- Modules/CMakeRCInformation.cmake,
- Modules/CMakeSystemSpecificInformation.cmake,
- Modules/CMakeTestCCompiler.cmake,
- Modules/CMakeTestCXXCompiler.cmake,
- Modules/CMakeTestFortranCompiler.cmake,
- Modules/CMakeTestJavaCompiler.cmake,
- Modules/CMakeTestRCCompiler.cmake,
- Modules/CMakeVS6BackwardCompatibility.cmake,
- Modules/CMakeVS7BackwardCompatibility.cmake, Modules/CTest.cmake,
- Modules/CheckCSourceCompiles.cmake,
- Modules/CheckCXXSourceCompiles.cmake,
- Modules/CheckFunctionExists.cmake,
- Modules/CheckIncludeFile.cmake,
- Modules/CheckIncludeFileCXX.cmake,
- Modules/CheckIncludeFiles.cmake,
- Modules/CheckLibraryExists.cmake,
- Modules/CheckSymbolExists.cmake, Modules/CheckTypeSize.cmake,
- Modules/CheckVariableExists.cmake, Modules/Dart.cmake,
- Modules/Documentation.cmake, Modules/FindAVIFile.cmake,
- Modules/FindCABLE.cmake, Modules/FindCurses.cmake,
- Modules/FindCygwin.cmake, Modules/FindDCMTK.cmake,
- Modules/FindDart.cmake, Modules/FindDoxygen.cmake,
- Modules/FindFLTK.cmake, Modules/FindGCCXML.cmake,
- Modules/FindGLU.cmake, Modules/FindGLUT.cmake,
- Modules/FindGTK.cmake, Modules/FindGnuplot.cmake,
- Modules/FindHTMLHelp.cmake, Modules/FindITK.cmake,
- Modules/FindImageMagick.cmake, Modules/FindJNI.cmake,
- Modules/FindJPEG.cmake, Modules/FindJava.cmake,
- Modules/FindKDE.cmake, Modules/FindLATEX.cmake,
- Modules/FindMFC.cmake, Modules/FindMPEG.cmake,
- Modules/FindMPEG2.cmake, Modules/FindMPI.cmake,
- Modules/FindMatlab.cmake, Modules/FindMotif.cmake,
- Modules/FindOpenAL.cmake, Modules/FindOpenGL.cmake,
- Modules/FindPHP4.cmake, Modules/FindPNG.cmake,
- Modules/FindPerl.cmake, Modules/FindPerlLibs.cmake,
- Modules/FindPhysFS.cmake, Modules/FindPike.cmake,
- Modules/FindPythonInterp.cmake, Modules/FindPythonLibs.cmake,
- Modules/FindQt.cmake, Modules/FindQt.cmake.bak,
- Modules/FindQt3.cmake, Modules/FindQt4.cmake,
- Modules/FindRuby.cmake, Modules/FindSDL.cmake,
- Modules/FindSDL.cmake.bak, Modules/FindSDL_image.cmake,
- Modules/FindSDL_image.cmake.bak, Modules/FindSDL_mixer.cmake,
- Modules/FindSDL_mixer.cmake.bak, Modules/FindSDL_net.cmake,
- Modules/FindSDL_net.cmake.bak, Modules/FindSDL_sound.cmake,
- Modules/FindSDL_ttf.cmake, Modules/FindSDL_ttf.cmake.bak,
- Modules/FindSWIG.cmake, Modules/FindSelfPackers.cmake,
- Modules/FindTCL.cmake, Modules/FindTIFF.cmake,
- Modules/FindTclsh.cmake, Modules/FindThreads.cmake,
- Modules/FindUnixCommands.cmake, Modules/FindVTK.cmake,
- Modules/FindWget.cmake, Modules/FindWish.cmake,
- Modules/FindX11.cmake, Modules/FindZLIB.cmake,
- Modules/FindwxWindows.cmake, Modules/TestBigEndian.cmake,
- Modules/TestCXXAcceptsFlag.cmake,
- Modules/TestForANSIForScope.cmake,
- Modules/TestForANSIStreamHeaders.cmake,
- Modules/TestForSTDNamespace.cmake, Modules/UseQt4.cmake,
- Modules/UseSWIG.cmake, Modules/UseVTK40.cmake,
- Modules/UseVTKBuildSettings40.cmake,
- Modules/UseVTKConfig40.cmake, Modules/Use_wxWindows.cmake,
- Modules/UsewxWidgets.cmake, Modules/readme.txt,
- Source/cmBuildCommand.cxx, Source/cmBuildNameCommand.h,
- Source/cmCTest.cxx, Source/cmDepends.cxx, Source/cmDepends.h,
- Source/cmDependsC.cxx, Source/cmDependsC.h,
- Source/cmDependsFortran.cxx, Source/cmDependsFortran.h,
- Source/cmDependsJava.cxx, Source/cmDependsJava.h,
- Source/cmDocumentation.cxx, Source/cmDocumentation.h,
- Source/cmFindPackageCommand.h,
- Source/cmGetCMakePropertyCommand.h,
- Source/cmGetDirectoryPropertyCommand.h,
- Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmGlobalVisualStudio6Generator.cxx,
- Source/cmGlobalVisualStudio6Generator.h,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.h,
- Source/cmGlobalVisualStudio8Generator.cxx,
- Source/cmGlobalVisualStudio8Generator.h,
- Source/cmGlobalXCodeGenerator.cxx,
- Source/cmGlobalXCodeGenerator.h,
- Source/cmInstallTargetsCommand.cxx, Source/cmLocalGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalVisualStudio7Generator.cxx, Source/cmMakefile.cxx,
- Source/cmSetDirectoryPropertiesCommand.h,
- Source/cmSiteNameCommand.h, Source/cmTarget.cxx,
- Source/cmTarget.h, Source/cmTryRunCommand.h,
- Source/cmakemain.cxx, Source/CTest/cmCTestBuildCommand.cxx,
- Source/CTest/cmCTestUpdateHandler.cxx,
- Source/kwsys/ProcessWin32.c, Source/kwsys/SystemTools.cxx,
- Source/kwsys/SystemTools.hxx.in,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: merge changes from
- main tree to branch
-
-2005-12-22 15:41 andy
-
- * Modules/CPack.Description.plist.in, Modules/CPack.Info.plist.in,
- Source/CPack/cmCPackPackageMakerGenerator.cxx,
- Source/CPack/cmCPackPackageMakerGenerator.h: ENH: Ok, now it
- works
-
-2005-12-22 15:34 andy
-
- * Source/CPack/cmCPackGenericGenerator.cxx: ENH: Add mandatory
- project description file or string
-
-2005-12-22 15:34 andy
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Add XML
- encoduing method
-
-2005-12-22 01:13 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-21 15:45 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h:
- ENH: make sure depend helper actually works, if a depend library
- gets updated, then the target needs to be removed, and the
- CONFIGURATION directory needs to be used
-
-2005-12-21 08:46 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Libraries and
- executables that are built with version numbers and symlinks
- should be built by a rule using the real file name. The symlink
- file names should be rules that just depend on the main rule.
- This way if a version number changes a target will re-link with
- the new name and the symlinks will be updated.
-
-2005-12-21 01:04 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-20 14:07 andy
-
- * Utilities/cmcurl/mprintf.c: COMP: Fix build on uclibc
-
-2005-12-20 13:53 hoffman
-
- * Modules/Platform/Windows-cl.cmake: ENH: remove duplicates
-
-2005-12-20 13:22 king
-
- * Source/kwsys/ProcessWin32.c: ENH: Improved robustness of sharing
- parent pipes with children. This ensures that the parent pipe
- handles are inherited by the children. If a parent pipe handle
- is invalid a handle to an empty pipe is given to the child to
- make sure all pipes are defined for the children.
-
-2005-12-20 09:20 andy
-
- * Source/CMakeLists.txt: ENH: Start working on PackageMaker
-
-2005-12-20 01:11 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-19 18:17 andy
-
- * Source/CPack/: cmCPackGenerators.cxx,
- cmCPackGenericGenerator.cxx, cmCPackGenericGenerator.h,
- cmCPackPackageMakerGenerator.cxx, cmCPackPackageMakerGenerator.h:
- ENH: Start working on Osx
-
-2005-12-19 11:29 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx,
- CTest/cmCTestBuildAndTestHandler.cxx: BUG: fix for bug 2560,
- Xcode does not create correct bundles
-
-2005-12-19 01:06 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-18 10:00 andy
-
- * Source/CPack/: cmCPackGenericGenerator.cxx,
- cmCPackGenericGenerator.h, cmCPackNSISGenerator.cxx,
- cmCPackNSISGenerator.h, cpack.cxx: ENH: 'Finish; NSI
-
-2005-12-18 09:59 andy
-
- * Modules/NSIS.template.in: ENH: Unify with Ken's
-
-2005-12-18 01:05 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-17 01:12 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-16 16:49 hoffman
-
- * Source/cmDocumentation.cxx: ENH: make sure uncommented modules
- are not documented
-
-2005-12-16 09:03 andy
-
- * Source/kwsys/SystemTools.cxx: BUG: Return if the file is in any
- directory not just in first one
-
-2005-12-16 01:12 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-15 16:28 andy
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: BUG: Fix test
-
-2005-12-15 14:17 martink
-
- * Modules/: FindMFC.cmake, FindMPEG.cmake, FindMPEG2.cmake,
- FindMPI.cmake, FindMotif.cmake, FindOpenGL.cmake, FindPHP4.cmake,
- FindPerl.cmake, FindPerlLibs.cmake, FindPhysFS.cmake,
- FindPike.cmake, FindPythonInterp.cmake, FindPythonLibs.cmake,
- FindQt.cmake, FindQt4.cmake, FindRuby.cmake, FindSDL.cmake,
- FindSDL_image.cmake, FindSDL_mixer.cmake, FindSDL_net.cmake,
- FindSDL_sound.cmake, FindSDL_ttf.cmake, FindTCL.cmake,
- FindTIFF.cmake, FindTclsh.cmake, FindThreads.cmake,
- FindVTK.cmake, FindWget.cmake, FindWish.cmake, FindX11.cmake,
- FindwxWindows.cmake, TestForANSIStreamHeaders.cmake,
- TestForSTDNamespace.cmake, UseSWIG.cmake, Use_wxWindows.cmake:
- ENH: cleanups
-
-2005-12-15 12:01 andy
-
- * Source/cmInstallTargetsCommand.cxx: ENH: Report an error if the
- target does not exists
-
-2005-12-15 10:41 martink
-
- * Modules/: CMakeBackwardCompatibilityCXX.cmake,
- CMakeExportBuildSettings.cmake, CMakeImportBuildSettings.cmake,
- CheckCXXSourceCompiles.cmake, CheckIncludeFile.cmake,
- CheckIncludeFileCXX.cmake, CheckIncludeFiles.cmake,
- CheckLibraryExists.cmake, CheckSymbolExists.cmake,
- CheckTypeSize.cmake, CheckVariableExists.cmake,
- FindAVIFile.cmake, FindCABLE.cmake, FindFLTK.cmake,
- FindGLUT.cmake, FindGTK.cmake, FindHTMLHelp.cmake, FindITK.cmake,
- FindImageMagick.cmake, FindJNI.cmake, FindJPEG.cmake,
- FindJava.cmake, FindLATEX.cmake, FindMatlab.cmake: ENH: some
- style fixes for the book
-
-2005-12-15 09:19 hoffman
-
- * Modules/FindQt3.cmake, Source/cmDocumentation.cxx: ENH: fix
- module documenation to handle bad docs and fix qt3 docs
-
-2005-12-15 01:47 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-14 13:51 hoffman
-
- * Modules/CMake.cmake, Modules/CMakeBackwardCompatibilityC.cmake,
- Modules/CMakeBackwardCompatibilityCXX.cmake,
- Modules/CMakeCInformation.cmake,
- Modules/CMakeCXXInformation.cmake,
- Modules/CMakeCommonLanguageInclude.cmake,
- Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Modules/CMakeDetermineFortranCompiler.cmake,
- Modules/CMakeDetermineJavaCompiler.cmake,
- Modules/CMakeDetermineRCCompiler.cmake,
- Modules/CMakeDetermineSystem.cmake,
- Modules/CMakeExportBuildSettings.cmake,
- Modules/CMakeFindFrameworks.cmake,
- Modules/CMakeFortranInformation.cmake,
- Modules/CMakeImportBuildSettings.cmake,
- Modules/CMakeJavaInformation.cmake,
- Modules/CMakePrintSystemInformation.cmake,
- Modules/CMakeRCInformation.cmake,
- Modules/CMakeSystemSpecificInformation.cmake,
- Modules/CMakeTestCCompiler.cmake,
- Modules/CMakeTestCXXCompiler.cmake,
- Modules/CMakeTestFortranCompiler.cmake,
- Modules/CMakeTestJavaCompiler.cmake,
- Modules/CMakeTestRCCompiler.cmake,
- Modules/CMakeVS6BackwardCompatibility.cmake,
- Modules/CMakeVS7BackwardCompatibility.cmake, Modules/CTest.cmake,
- Modules/CheckCSourceCompiles.cmake,
- Modules/CheckCXXSourceCompiles.cmake,
- Modules/CheckFunctionExists.cmake,
- Modules/CheckIncludeFile.cmake,
- Modules/CheckIncludeFileCXX.cmake,
- Modules/CheckIncludeFiles.cmake,
- Modules/CheckLibraryExists.cmake,
- Modules/CheckSymbolExists.cmake, Modules/CheckTypeSize.cmake,
- Modules/CheckVariableExists.cmake, Modules/Dart.cmake,
- Modules/Documentation.cmake, Modules/FindAVIFile.cmake,
- Modules/FindCABLE.cmake, Modules/FindCurses.cmake,
- Modules/FindCygwin.cmake, Modules/FindDCMTK.cmake,
- Modules/FindDart.cmake, Modules/FindDoxygen.cmake,
- Modules/FindFLTK.cmake, Modules/FindGCCXML.cmake,
- Modules/FindGLU.cmake, Modules/FindGLUT.cmake,
- Modules/FindGTK.cmake, Modules/FindGnuplot.cmake,
- Modules/FindHTMLHelp.cmake, Modules/FindITK.cmake,
- Modules/FindImageMagick.cmake, Modules/FindJNI.cmake,
- Modules/FindJPEG.cmake, Modules/FindJava.cmake,
- Modules/FindKDE.cmake, Modules/FindLATEX.cmake,
- Modules/FindMFC.cmake, Modules/FindMPEG.cmake,
- Modules/FindMPEG2.cmake, Modules/FindMPI.cmake,
- Modules/FindMatlab.cmake, Modules/FindMotif.cmake,
- Modules/FindOpenAL.cmake, Modules/FindOpenGL.cmake,
- Modules/FindPHP4.cmake, Modules/FindPNG.cmake,
- Modules/FindPerl.cmake, Modules/FindPerlLibs.cmake,
- Modules/FindPhysFS.cmake, Modules/FindPike.cmake,
- Modules/FindPythonInterp.cmake, Modules/FindPythonLibs.cmake,
- Modules/FindQt.cmake, Modules/FindQt3.cmake,
- Modules/FindQt4.cmake, Modules/FindRuby.cmake,
- Modules/FindSDL.cmake, Modules/FindSDL_image.cmake,
- Modules/FindSDL_mixer.cmake, Modules/FindSDL_net.cmake,
- Modules/FindSDL_sound.cmake, Modules/FindSDL_ttf.cmake,
- Modules/FindSWIG.cmake, Modules/FindSelfPackers.cmake,
- Modules/FindTCL.cmake, Modules/FindTIFF.cmake,
- Modules/FindTclsh.cmake, Modules/FindThreads.cmake,
- Modules/FindUnixCommands.cmake, Modules/FindVTK.cmake,
- Modules/FindWget.cmake, Modules/FindWish.cmake,
- Modules/FindX11.cmake, Modules/FindZLIB.cmake,
- Modules/FindwxWindows.cmake, Modules/TestBigEndian.cmake,
- Modules/TestCXXAcceptsFlag.cmake,
- Modules/TestForANSIForScope.cmake,
- Modules/TestForANSIStreamHeaders.cmake,
- Modules/TestForSTDNamespace.cmake, Modules/UseQt4.cmake,
- Modules/UseSWIG.cmake, Modules/UseVTK40.cmake,
- Modules/UseVTKBuildSettings40.cmake,
- Modules/UseVTKConfig40.cmake, Modules/Use_wxWindows.cmake,
- Modules/UsewxWidgets.cmake, Modules/readme.txt,
- Source/cmDocumentation.cxx, Source/cmDocumentation.h,
- Source/cmakemain.cxx: ENH: add documentation support for modules
-
-2005-12-14 11:00 king
-
- * Source/cmGlobalVisualStudio7Generator.h: ENH: Renamed
- ZeroTargetCheck target to ZERO_CHECK for consistency with other
- CMake-generated targets (ALL_BUILD, RUN_TESTS, INSTALL).
-
-2005-12-14 10:58 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: COMP: Fix conversion
- warning.
-
-2005-12-14 10:47 king
-
- * Source/: cmLocalGenerator.cxx, cmLocalUnixMakefileGenerator3.cxx,
- cmMakefile.cxx, cmTarget.cxx, cmTarget.h: ENH: Removed cmMakefile
- arguments from cmTarget methods because cmTarget has the ivar
- m_Makefile now. Re-implemented
- cmLocalUnixMakefileGenerator3::AppendAnyDepend to use the new
- global knowledge and avoid the need to look at the cache for
- information about other targets. This should fix problems with
- custom commands and executables with the OUTPUT_NAME set. Also
- the <target>_LIBRARY_TYPE cache variable is no longer needed at
- all and has been removed.
-
-2005-12-13 18:23 king
-
- * Source/cmGlobalVisualStudio8Generator.cxx: COMP: Fixed unused
- variable warning.
-
-2005-12-13 15:16 andy
-
- * Source/CTest/cmCTestUpdateHandler.cxx: BUG: Fix the problem with
- update.xml.tmp not being coppied
-
-2005-12-13 15:14 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: removed
- TARGET_DIR_PREFIX support and someother fix
-
-2005-12-13 15:13 martink
-
- * Source/cmLocalVisualStudio7Generator.cxx: ENH: removed
- TARGET_DIR_PREFIX support
-
-2005-12-13 15:12 martink
-
- * Source/cmTryRunCommand.h: STYLE: fix missing docs
-
-2005-12-13 14:21 king
-
- * Source/: cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h,
- cmGlobalVisualStudio8Generator.cxx,
- cmGlobalVisualStudio8Generator.h,
- cmLocalVisualStudio7Generator.cxx: ENH: Added support for
- parallel builds in VS 8. There is now a special target on which
- all other targets depend that re-runs CMake if any listfiles have
- been changed. This addresses bug#2512.
-
-2005-12-13 14:07 martink
-
- * Utilities/Release/CMake.nsi.in: ENH: removed the add to path
-
-2005-12-13 04:24 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-12 11:34 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: ENH: fix for bug 2584,
- empty source groups with children skipped
-
-2005-12-12 04:17 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-11 04:20 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-11 00:12 andy
-
- * Source/kwsys/SystemTools.cxx: COMP: for a in range(100):
- write_on_board(No std in kwsys...)
-
-2005-12-10 12:16 andy
-
- * Modules/NSIS.template.in: ENH: Some fixes to make it work
-
-2005-12-10 12:14 andy
-
- * Source/CPack/: cmCPackGenericGenerator.cxx,
- cmCPackGenericGenerator.h, cmCPackNSISGenerator.cxx, cpack.cxx:
- ENH: More work on NSIS:
-
-2005-12-10 12:11 andy
-
- * Source/cmLocalGenerator.cxx: ENH: Allow the installer to
- overwrite the install prefix
-
-2005-12-10 12:10 andy
-
- * Source/kwsys/: CommandLineArguments.cxx,
- CommandLineArguments.hxx.in: ENH: Add a method to remove
- remaining arguments
-
-2005-12-10 12:09 andy
-
- * Source/kwsys/Glob.hxx.in: COMP: Fix the exporting so that it can
- actually be used
-
-2005-12-10 12:08 andy
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH: Add
- another signature to FindProgram that matches more to the one
- from CMake
-
-2005-12-10 04:21 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-09 23:04 hoffman
-
- * Source/: cmDependsC.cxx, cmDependsC.h: ENH: try to fix hp build
- problem
-
-2005-12-09 16:32 andy
-
- * Source/cmDependsC.h: ENH: fix compile error
-
-2005-12-09 14:30 hoffman
-
- * Source/: cmDependsC.cxx, cmDependsC.h: ENH: clean up style a bit
-
-2005-12-09 13:58 hoffman
-
- * Source/: cmDependsC.cxx, cmDependsC.h,
- cmLocalUnixMakefileGenerator3.cxx: PERF: apply patch for bug 2575
- speeds up depend scanning
-
-2005-12-09 04:17 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-08 04:21 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-07 11:39 andy
-
- * Source/: cmBuildNameCommand.h, cmFindPackageCommand.h,
- cmGetCMakePropertyCommand.h, cmGetDirectoryPropertyCommand.h,
- cmSetDirectoryPropertiesCommand.h, cmSiteNameCommand.h: ENH: Make
- commands scriptable
-
-2005-12-06 10:55 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-05 08:19 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-04 05:04 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-03 06:10 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-02 09:18 hoffman
-
- * Utilities/Release/cmake_release.sh: ENH: update revision numbers
-
-2005-12-02 09:16 hoffman
-
- * ChangeLog.manual, Utilities/Release/config_IRIX64,
- Utilities/Release/release_dispatch.sh: ENH: fix change log and
- change sgi release scripts
-
-2005-12-02 05:30 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-12-01 21:52 andy
-
- * Modules/NSIS.template.in, Source/CPack/cmCPackNSISGenerator.cxx,
- Source/CPack/cmCPackNSISGenerator.h: ENH: Work on nsis
-
-2005-12-01 12:27 hoffman
-
- * Utilities/Release/cmake_release.sh: ENH: update revision numbers
-
-2005-12-01 11:41 andy
-
- * Source/: cmBuildCommand.cxx, cmGlobalGenerator.cxx,
- cmGlobalGenerator.h, cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio6Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h, cmGlobalXCodeGenerator.cxx,
- cmGlobalXCodeGenerator.h, CTest/cmCTestBuildCommand.cxx: ENH: Add
- a way for the generated command to include extra flags. This is
- useful for CTest (or try compile) to add -j2
-
-2005-12-01 05:32 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-11-30 13:46 andy
-
- * Source/cmMakefile.cxx: ENH: Add variable for debugging. This
- variable CMAKE_PARENT_LIST_FILE holds the parent CMake list file
- of the current cmake list file.
-
-2005-11-30 05:22 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-11-29 05:24 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-11-28 15:57 hoffman
-
- * Source/CMakeLists.txt, Tests/Tutorial/Step1/CMakeLists.txt,
- Tests/Tutorial/Step1/TutorialConfig.h.in,
- Tests/Tutorial/Step1/tutorial.cxx,
- Tests/Tutorial/Step2/CMakeLists.txt,
- Tests/Tutorial/Step2/TutorialConfig.h.in,
- Tests/Tutorial/Step2/tutorial.cxx,
- Tests/Tutorial/Step2/MathFunctions/CMakeLists.txt,
- Tests/Tutorial/Step2/MathFunctions/MathFunctions.h,
- Tests/Tutorial/Step2/MathFunctions/mysqrt.cxx,
- Tests/Tutorial/Step3/CMakeLists.txt,
- Tests/Tutorial/Step3/TutorialConfig.h.in,
- Tests/Tutorial/Step3/tutorial.cxx,
- Tests/Tutorial/Step3/MathFunctions/CMakeLists.txt,
- Tests/Tutorial/Step3/MathFunctions/MathFunctions.h,
- Tests/Tutorial/Step3/MathFunctions/mysqrt.cxx,
- Tests/Tutorial/Step4/CMakeLists.txt,
- Tests/Tutorial/Step4/TutorialConfig.h.in,
- Tests/Tutorial/Step4/tutorial.cxx,
- Tests/Tutorial/Step4/MathFunctions/CMakeLists.txt,
- Tests/Tutorial/Step4/MathFunctions/MathFunctions.h,
- Tests/Tutorial/Step4/MathFunctions/mysqrt.cxx,
- Tests/Tutorial/Step5/CMakeLists.txt,
- Tests/Tutorial/Step5/TutorialConfig.h.in,
- Tests/Tutorial/Step5/tutorial.cxx,
- Tests/Tutorial/Step5/MathFunctions/CMakeLists.txt,
- Tests/Tutorial/Step5/MathFunctions/MakeTable.cxx,
- Tests/Tutorial/Step5/MathFunctions/MathFunctions.h,
- Tests/Tutorial/Step5/MathFunctions/mysqrt.cxx: ENH: move tutorial
- to branch
-
-2005-11-28 15:15 hoffman
-
- * CMakeLists.txt, Source/cmDependsFortranLexer.cxx,
- Source/cmDependsFortranLexer.in.l: ENH: Version 2.2.3
-
-2005-11-28 14:19 hoffman
-
- * Modules/VTKCompatibility.cmake: ENH: fix problem with building
- vtk 4.4.2
-
-2005-11-28 14:05 hoffman
-
- * Modules/VTKCompatibility.cmake: ENH: fix for vtk 4.4.2 and cmake
- 2.2
-
-2005-11-28 05:17 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-11-27 05:27 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-11-26 05:21 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-11-25 05:18 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-11-24 05:21 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-11-23 12:33 hoffman
-
- * ChangeLog.manual, Modules/CMakeCCompiler.cmake.in,
- Modules/CMakeTestCCompiler.cmake,
- Modules/CMakeTestJavaCompiler.cmake,
- Modules/CheckFunctionExists.cmake,
- Modules/CheckIncludeFile.cmake,
- Modules/CheckIncludeFileCXX.cmake,
- Modules/CheckIncludeFiles.cmake,
- Modules/CheckLibraryExists.cmake,
- Modules/CheckSymbolExists.cmake,
- Modules/CheckVariableExists.cmake, Modules/FindOpenAL.cmake,
- Modules/FindPhysFS.cmake, Modules/FindQt3.cmake,
- Modules/FindSDL.cmake, Modules/FindSDL.cmake.bak,
- Modules/FindSDL_image.cmake, Modules/FindSDL_image.cmake.bak,
- Modules/FindSDL_mixer.cmake, Modules/FindSDL_mixer.cmake.bak,
- Modules/FindSDL_net.cmake, Modules/FindSDL_net.cmake.bak,
- Modules/FindSDL_sound.cmake, Modules/FindSDL_ttf.cmake,
- Modules/FindSDL_ttf.cmake.bak, Modules/Platform/SunOS.cmake,
- Modules/Platform/Windows-cl.cmake,
- Modules/Platform/Windows-icl.cmake,
- Modules/Platform/Windows-ifort.cmake,
- Source/cmAddLibraryCommand.h, Source/cmAddSubDirectoryCommand.h,
- Source/cmCMakeMinimumRequired.h, Source/cmCPluginAPI.h,
- Source/cmCTest.cxx, Source/cmConfigureFileCommand.h,
- Source/cmCreateTestSourceList.h, Source/cmElseCommand.h,
- Source/cmEnableLanguageCommand.h,
- Source/cmEnableTestingCommand.h, Source/cmEndForEachCommand.h,
- Source/cmEndIfCommand.h, Source/cmEndWhileCommand.h,
- Source/cmExecProgramCommand.h, Source/cmFLTKWrapUICommand.h,
- Source/cmFileCommand.h, Source/cmForEachCommand.h,
- Source/cmGetCMakePropertyCommand.h,
- Source/cmGetDirectoryPropertyCommand.h,
- Source/cmGetSourceFilePropertyCommand.h,
- Source/cmGetTargetPropertyCommand.h,
- Source/cmGetTestPropertyCommand.h,
- Source/cmGlobalVisualStudio7Generator.h,
- Source/cmGlobalVisualStudio8Generator.cxx,
- Source/cmGlobalXCodeGenerator.cxx,
- Source/cmGlobalXCodeGenerator.h, Source/cmIfCommand.cxx,
- Source/cmIfCommand.h, Source/cmIncludeCommand.h,
- Source/cmInstallFilesCommand.h, Source/cmInstallTargetsCommand.h,
- Source/cmLoadCacheCommand.h, Source/cmLocalGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmMacroCommand.h, Source/cmMakefile.cxx,
- Source/cmMarkAsAdvancedCommand.h, Source/cmMessageCommand.h,
- Source/cmOrderLinkDirectories.cxx,
- Source/cmOrderLinkDirectories.h, Source/cmQTWrapCPPCommand.h,
- Source/cmQTWrapUICommand.h, Source/cmSetCommand.h,
- Source/cmSetSourceFilesPropertiesCommand.h,
- Source/cmSetTargetPropertiesCommand.h,
- Source/cmSetTestsPropertiesCommand.h, Source/cmSourceFile.cxx,
- Source/cmSourceGroupCommand.h, Source/cmSubdirCommand.h,
- Source/cmSystemTools.cxx, Source/cmTarget.cxx,
- Source/cmTryCompileCommand.h, Source/cmTryRunCommand.h,
- Source/cmVariableRequiresCommand.h, Source/cmWhileCommand.h,
- Source/cmWriteFileCommand.h, Source/cmXCode21Object.cxx,
- Source/cmXCodeObject.cxx, Source/cmXCodeObject.h,
- Source/ctest.cxx, Source/CTest/cmCTestBuildHandler.cxx,
- Source/CTest/cmCTestScriptHandler.h,
- Source/CTest/cmCTestSubmitHandler.cxx,
- Source/CTest/cmCTestTestHandler.cxx,
- Source/CTest/cmCTestTestHandler.h, Source/kwsys/ProcessUNIX.c,
- Source/kwsys/ProcessWin32.c, Source/kwsys/SystemTools.cxx,
- Tests/ExternalOBJ/CMakeLists.txt, Tests/Wrapping/CMakeLists.txt,
- Utilities/Release/CMake.nsi.in: ENH: merge fixes from main tree,
- see ChangeLog.manual
-
-2005-11-23 10:27 hoffman
-
- * Source/cmTarget.cxx: ENH: executable prefix and post fix
- variables should not be the same as the executable extension
-
-2005-11-23 05:35 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-11-22 17:03 king
-
- * Source/: cmMakefile.cxx, cmTarget.cxx: BUG: Do not expand escape
- sequences when re-expanding variables in include directories,
- link directories, and link libraries.
-
-2005-11-22 16:59 king
-
- * Source/cmOrderLinkDirectories.cxx: BUG: Do not accept a directory
- name as a library.
-
-2005-11-22 16:08 hoffman
-
- * Source/: cmOrderLinkDirectories.cxx, cmOrderLinkDirectories.h:
- BUG: fix for bug 2357, do not allow targets to link to
- directories
-
-2005-11-22 15:15 hoffman
-
- * Source/CTest/cmCTestScriptHandler.h: BUG: fix spelling error
-
-2005-11-22 13:37 king
-
- * Source/: cmGlobalVisualStudio7Generator.h,
- cmGlobalVisualStudio8Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: BUG: Tweak VS8 generator to
- keep VS8 happy. The .vcproj files need their own GUIDs in a
- ProjectGUID attribute. The top level .sln file needs a special
- comment at the top to allow it to be opened with double-click in
- explorer.
-
-2005-11-22 13:36 king
-
- * CMakeLists.txt: COMP: Define _CRT_SECURE_NO_DEPRECATE to build
- CMake itself on VS8. This disables 1000s of deprecation warnings
- about standard code.
-
-2005-11-22 12:04 hoffman
-
- * Modules/Platform/Windows-cl.cmake: BUG: fix for bug 2488
-
-2005-11-22 11:44 hoffman
-
- * Modules/Platform/: Linux-icpc.cmake, SunOS.cmake: ENH: more
- compiler flags
-
-2005-11-22 11:35 king
-
- * Source/cmSetTargetPropertiesCommand.h: STYLE: Fixed documentation
- to state target_EXPORTS default right after DEFINE_SYMBOL
- documentation instead of many sentences later in a random place.
-
-2005-11-22 11:33 king
-
- * Modules/FindQt3.cmake: BUG: QT_DEFINITIONS should not be quoted.
- This addresses bug#2481.
-
-2005-11-22 11:28 hoffman
-
- * Modules/CMakeTestJavaCompiler.cmake: ENH: set java compiler works
-
-2005-11-22 05:18 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-11-21 05:18 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-11-20 05:30 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-11-19 09:40 hoffman
-
- * Source/: cmLocalVisualStudio7Generator.cxx,
- cmSetTargetPropertiesCommand.h: ENH: add some more properties for
- visual studio projects
-
-2005-11-19 08:29 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: COMP: fix compile error
-
-2005-11-19 08:04 hoffman
-
- * Source/cmTryRunCommand.h: ENH: fix docs
-
-2005-11-19 05:22 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-11-18 17:07 andy
-
- * Source/CPack/: cmCPackGenerators.cxx,
- cmCPackGenericGenerator.cxx, cmCPackGenericGenerator.h,
- cmCPackTGZGenerator.cxx, cpack.cxx: ENH: Use cmMakefile instead
- for the options, more cleanups and start working on NSIS
-
-2005-11-18 17:07 andy
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH: Add
- another signature for FindProgram that takes the list of names
-
-2005-11-18 17:06 andy
-
- * Source/CMakeLists.txt: ENH: Add NSIS
-
-2005-11-18 16:59 hoffman
-
- * Source/cmXCodeObject.cxx: ENH: more chars need quotes
-
-2005-11-18 15:03 martink
-
- * Utilities/Release/CMake.nsi.in: BUG: fixe dproblem with not
- uninstalling start menu entries
-
-2005-11-18 14:12 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h:
- ENH: fixes for Xcode 2.2
-
-2005-11-18 10:40 hoffman
-
- * Source/CTest/cmCTestBuildHandler.cxx: ENH: add new error regex
-
-2005-11-18 10:36 king
-
- * Modules/Platform/Windows-cl.cmake,
- Modules/Platform/Windows-icl.cmake,
- Modules/Platform/Windows-ifort.cmake,
- Source/cmLocalVisualStudio7Generator.cxx: BUG: Fixed
- flag-to-vcproj-attribute conversion code to work again (it was
- broken by the optimization changes). Added conversion of /nologo
- flag to SuppressStartupBanner attribute and /Gy flag to
- EnableFunctionLevelLinking attribute.
-
-2005-11-17 16:49 king
-
- * Tests/Wrapping/CMakeLists.txt: COMP: Need target-level dependency
- from wrapper targets on Wrap executable target.
-
-2005-11-17 15:57 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: Fixed XML escapes
- for custom commands. Also added escaping of newlines for VS
- 2005.
-
-2005-11-17 15:44 king
-
- * Source/: cmCTest.cxx, cmSystemTools.cxx: BUG: Do not dereference
- an end iterator.
-
-2005-11-17 13:49 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmSourceFile.cxx, Tests/ExternalOBJ/CMakeLists.txt: BUG:
- Fixed support for external object files built by custom commands.
- Also added a test to keep it working.
-
-2005-11-17 11:44 martink
-
- * Source/: cmVariableRequiresCommand.h, cmWhileCommand.h,
- cmWriteFileCommand.h: STYLE: fix docs
-
-2005-11-17 11:37 martink
-
- * Source/: cmTryCompileCommand.h, cmTryRunCommand.h: STYLE: fix
- docs
-
-2005-11-17 11:20 martink
-
- * Source/cmSubdirCommand.h: STYLE: fix docs
-
-2005-11-17 11:04 martink
-
- * Source/cmSourceGroupCommand.h: STYLE: fix docs
-
-2005-11-17 10:41 martink
-
- * Source/cmSetTargetPropertiesCommand.h: STYLE: fix docs
-
-2005-11-17 10:36 martink
-
- * Source/cmSetSourceFilesPropertiesCommand.h: STYLE: fix docs
-
-2005-11-17 10:28 martink
-
- * Source/: cmQTWrapUICommand.h, cmSetCommand.h: STYLE: fix docs
-
-2005-11-17 10:20 martink
-
- * Source/: cmMessageCommand.h, cmQTWrapCPPCommand.h: STYLE: fix
- docs
-
-2005-11-17 09:44 martink
-
- * Source/cmIfCommand.cxx: BUG: clean up scoping
-
-2005-11-17 09:32 martink
-
- * Source/: cmIfCommand.cxx: BUG: fix incrementing past end
-
-2005-11-17 09:31 martink
-
- * Source/cmMarkAsAdvancedCommand.h: STYLE: fix docs
-
-2005-11-17 05:24 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-11-16 14:41 martink
-
- * Source/cmMacroCommand.h: STYLE: fix docs
-
-2005-11-16 14:36 martink
-
- * Source/: cmInstallTargetsCommand.h, cmLoadCacheCommand.h: STYLE:
- fix docs
-
-2005-11-16 14:27 martink
-
- * Source/cmInstallFilesCommand.h: STYLE: fix docs
-
-2005-11-16 14:08 martink
-
- * Source/: cmIfCommand.h, cmIncludeCommand.h: STYLE: fix docs
-
-2005-11-16 14:02 martink
-
- * Source/cmGetTestPropertyCommand.h: STYLE: fix docs
-
-2005-11-16 13:13 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmXCode21Object.cxx,
- cmXCodeObject.cxx, cmXCodeObject.h: ENH: fixes for xcode21 and
- build styles and comments in the generated project
-
-2005-11-16 12:08 martink
-
- * Source/: cmGetSourceFilePropertyCommand.h,
- cmGetTargetPropertyCommand.h: STYLE: fix docs
-
-2005-11-16 12:05 martink
-
- * Source/cmGetDirectoryPropertyCommand.h: STYLE: fix docs
-
-2005-11-16 12:00 martink
-
- * Source/: cmForEachCommand.h, cmGetCMakePropertyCommand.h: STYLE:
- fix docs
-
-2005-11-16 11:57 martink
-
- * Source/cmFLTKWrapUICommand.h: STYLE: fix docs
-
-2005-11-16 11:39 king
-
- * Source/kwsys/ProcessUNIX.c: STYLE: Documented reference to "man
- select_tut".
-
-2005-11-16 11:36 king
-
- * Source/kwsys/ProcessWin32.c: BUG: Do not close handle obtained
- from GetModuleHandle which does not increase the reference count
- of the module.
-
-2005-11-16 11:25 martink
-
- * Source/cmFileCommand.h: STYLE: fix docs
-
-2005-11-16 10:40 martink
-
- * Source/cmExecProgramCommand.h: STYLE: fix docs
-
-2005-11-16 10:35 martink
-
- * Source/: cmEnableTestingCommand.h, cmEndForEachCommand.h,
- cmEndIfCommand.h, cmEndWhileCommand.h: STYLE: fix docs
-
-2005-11-16 10:31 martink
-
- * Source/: cmCreateTestSourceList.h, cmElseCommand.h,
- cmEnableLanguageCommand.h: STYLE: fix docs
-
-2005-11-16 10:26 martink
-
- * Source/: cmConfigureFileCommand.h: STYLE: fix docs
-
-2005-11-16 10:22 martink
-
- * Source/cmCMakeMinimumRequired.h: STYLE: fix docs
-
-2005-11-16 10:14 martink
-
- * Source/: cmAddLibraryCommand.h, cmAddSubDirectoryCommand.h:
- STYLE: fix docs
-
-2005-11-16 10:08 martink
-
- * Source/ctest.cxx: STYLE: removed some docs that did not make
- sense
-
-2005-11-16 06:30 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-11-15 13:30 martink
-
- * Source/cmConfigureFileCommand.h: STYLE: updated comments
-
-2005-11-15 05:27 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-11-14 14:21 hoffman
-
- * Modules/: CMakeCCompiler.cmake.in, CMakeTestCCompiler.cmake: BUG:
- fix SIZEOF VOIDP problem
-
-2005-11-14 12:29 andy
-
- * Source/: CMakeLists.txt, cmConfigure.cmake.h.in,
- CPack/cmCPackConfigure.h.in, CPack/cmCPackTGZGenerator.cxx,
- CPack/cmCPackTGZGenerator.h: ENH: More cross platform stuff
-
-2005-11-14 05:24 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-11-13 05:20 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-11-12 05:28 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-11-11 14:39 andy
-
- * Source/CPack/cmCPackSTGZGenerator.cxx: ENH: Cleanup
-
-2005-11-11 14:32 andy
-
- * Source/CPack/cmCPackSTGZGenerator.cxx: ENH: Fix for sun
-
-2005-11-11 14:25 andy
-
- * Source/: CMakeLists.txt, CPack/cmCPackGenerators.cxx,
- CPack/cmCPackGenericGenerator.cxx,
- CPack/cmCPackGenericGenerator.h, CPack/cmCPackSTGZGenerator.cxx,
- CPack/cmCPackSTGZGenerator.h, CPack/cmCPackTGZGenerator.cxx,
- CPack/cmCPackTGZGenerator.h: ENH: Add support for self extracted
- tars
-
-2005-11-11 05:51 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-11-10 15:15 andy
-
- * Source/: CMakeLists.txt, cmConfigure.cmake.h.in,
- CPack/cmCPackTGZGenerator.h: COMP: Fix building on Cygwin
-
-2005-11-10 15:13 martink
-
- * Tests/Tutorial/Step5/MathFunctions/CMakeLists.txt: ENH: some
- fixes
-
-2005-11-10 15:10 martink
-
- * Tests/Tutorial/: Step1/tutorial.cxx, Step2/tutorial.cxx,
- Step3/tutorial.cxx, Step4/tutorial.cxx, Step5/tutorial.cxx: ENH:
- some fixes
-
-2005-11-10 14:36 andy
-
- * Source/: CMakeLists.txt, CPack/cmCPackGenerators.cxx,
- CPack/cmCPackGenerators.h, CPack/cmCPackGenericGenerator.cxx,
- CPack/cmCPackGenericGenerator.h, CPack/cmCPackTGZGenerator.cxx,
- CPack/cmCPackTGZGenerator.h, CPack/cpack.cxx: ENH: Start working
- on CPack
-
-2005-11-10 14:33 andy
-
- * Source/cmLocalGenerator.cxx: ENH: Make CMAKE_INSTALL_PREFIX to be
- optional (on by default)
-
-2005-11-10 14:32 andy
-
- * Source/CTest/cmCTestGenericHandler.h: ENH: More type macros
-
-2005-11-10 14:32 andy
-
- * Source/kwsys/Glob.hxx.in: COMP: Fix the building with Glob
-
-2005-11-10 14:31 andy
-
- * Source/kwsys/: CommandLineArguments.cxx,
- CommandLineArguments.hxx.in: ENH: Add method to delete the
- remaining arguments
-
-2005-11-10 14:28 hoffman
-
- * Modules/Platform/Windows-cl.cmake: ENH: add all libs
-
-2005-11-10 12:02 martink
-
- * Tests/Tutorial/: Step5/CMakeLists.txt, Step2/CMakeLists.txt,
- Step3/CMakeLists.txt, Step4/CMakeLists.txt,
- Step5/MathFunctions/CMakeLists.txt: ENH: some fixes
-
-2005-11-10 11:48 martink
-
- * Tests/Tutorial/Step5/MathFunctions/MakeTable.cxx: STYLE: fix
- spelling
-
-2005-11-10 10:55 martink
-
- * Source/CMakeLists.txt: ENH: added tutorial tests
-
-2005-11-10 10:55 martink
-
- * Source/CTest/cmCTestTestHandler.cxx: ENH: change the pass regexp
- so that it overrides the return value
-
-2005-11-10 10:51 martink
-
- * Tests/Tutorial/Step5/: CMakeLists.txt, TutorialConfig.h.in,
- tutorial.cxx, MathFunctions/CMakeLists.txt,
- MathFunctions/MakeTable.cxx, MathFunctions/MathFunctions.h,
- MathFunctions/mysqrt.cxx: ENH: step 5
-
-2005-11-10 10:50 martink
-
- * Tests/Tutorial/Step4/: CMakeLists.txt, TutorialConfig.h.in,
- tutorial.cxx, MathFunctions/CMakeLists.txt,
- MathFunctions/MathFunctions.h, MathFunctions/mysqrt.cxx: ENH:
- step 4
-
-2005-11-10 10:50 martink
-
- * Tests/Tutorial/Step3/: CMakeLists.txt, TutorialConfig.h.in,
- tutorial.cxx, MathFunctions/CMakeLists.txt,
- MathFunctions/MathFunctions.h, MathFunctions/mysqrt.cxx: ENH:
- step 3
-
-2005-11-10 04:48 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-11-09 16:21 martink
-
- * Tests/Tutorial/: Step1/CMakeLists.txt, Step1/TutorialConfig.h.in,
- Step1/tutorial.cxx, Step2/CMakeLists.txt,
- Step2/TutorialConfig.h.in, Step2/tutorial.cxx,
- Step2/MathFunctions/CMakeLists.txt,
- Step2/MathFunctions/MathFunctions.h,
- Step2/MathFunctions/mysqrt.cxx: ENH: checkeed in step 1 and 2
-
-2005-11-09 11:14 andy
-
- * Source/cmSetTestsPropertiesCommand.h: STYLE: More comments
-
-2005-11-09 11:07 andy
-
- * Source/: cmSetTestsPropertiesCommand.h,
- CTest/cmCTestTestHandler.cxx, kwsys/CMakeLists.txt: ENH: Change
- flag to PASS_REGULAR_EXPRESSION and FAIL_REGULAR_EXPRESSION and
- add help in cmSetTestsPropertiesCommand
-
-2005-11-09 07:22 andy
-
- * Source/kwsys/CMakeLists.txt: COMP: Fix all dashboards
-
-2005-11-09 05:33 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-11-08 17:59 andy
-
- * Source/kwsys/: CMakeLists.txt, testRegistry.cxx: ENH: Add test
- for output regular expression
-
-2005-11-08 17:59 andy
-
- * Source/: cmLocalGenerator.cxx, CTest/cmCTestTestHandler.cxx,
- CTest/cmCTestTestHandler.h: ENH: Add support for output reguilar
- expression
-
-2005-11-08 05:33 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-11-07 05:34 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-11-06 05:22 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-11-05 04:18 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-11-04 10:52 martink
-
- * Source/cmCPluginAPI.h: DOC: updated comment about the inherited
- ivar
-
-2005-11-04 09:28 andy
-
- * Modules/: CheckIncludeFile.cmake, CheckIncludeFileCXX.cmake: ENH:
- Cleanup and unify
-
-2005-11-03 04:24 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-11-02 13:59 martink
-
- * Modules/CheckLibraryExists.cmake: DOC: better documentation
-
-2005-11-02 13:51 martink
-
- * Modules/: CheckFunctionExists.cmake, CheckIncludeFile.cmake,
- CheckIncludeFileCXX.cmake, CheckIncludeFiles.cmake,
- CheckLibraryExists.cmake, CheckSymbolExists.cmake,
- CheckVariableExists.cmake: DOC: better documentaiton
-
-2005-11-02 04:14 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-31 12:09 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-31 10:52 hoffman
-
- * Utilities/Release/release_dispatch.sh: ENH: change names of
- machine
-
-2005-10-31 10:48 hoffman
-
- * Utilities/Release/: cmake_release.sh: ENH: update revision
- numbers
-
-2005-10-31 10:01 hoffman
-
- * ChangeLog.manual, Source/cmFileTimeComparison.cxx,
- Source/cmLocalUnixMakefileGenerator3.cxx, Source/cmake.cxx: ENH:
- merge from main tree
-
-2005-10-30 08:01 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-28 17:46 hoffman
-
- * Modules/: FindOpenAL.cmake, FindPhysFS.cmake, FindSDL.cmake,
- FindSDL_image.cmake, FindSDL_mixer.cmake, FindSDL_net.cmake,
- FindSDL_sound.cmake, FindSDL_ttf.cmake: ENH: changes from Eric
- Wing, bug 2249
-
-2005-10-28 11:52 hoffman
-
- * Source/cmWin32ProcessExecution.cxx: BUG: fix stack over write bug
-
-2005-10-28 11:51 hoffman
-
- * Utilities/Release/: CMake.nsi.in, MakeRelease.cmake.in: BUG: fix
- space in path probs
-
-2005-10-28 11:32 hoffman
-
- * Utilities/Release/: CMake.nsi.in, MakeRelease.cmake.in: BUG: fix
- release with spaces in the path
-
-2005-10-28 11:31 hoffman
-
- * Source/cmWin32ProcessExecution.cxx: BUG: fix stack write error
-
-2005-10-28 11:02 hoffman
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: make the clean
- target work
-
-2005-10-27 13:57 king
-
- * Source/: cmFileTimeComparison.cxx, kwsys/SystemTools.cxx: ENH:
- Improved file modification time comparison on Windows to use
- GetFileAttributesEx instead of CreateFile/GetFileTime/CloseHandle
- to get file times. This results in a 30% reduction in time to do
- a build system check.
-
-2005-10-26 09:03 hoffman
-
- * Utilities/Release/cmake_release.sh: ENH: update revision numbers
-
-2005-10-26 05:32 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-25 05:32 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-24 17:00 hoffman
-
- * ChangeLog.manual: [no log message]
-
-2005-10-24 15:43 hoffman
-
- * CMakeLists.txt, Modules/Platform/Windows-gcc.cmake,
- Source/cmBuildNameCommand.h, Source/cmFileCommand.cxx,
- Source/cmFileCommand.h,
- Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmGlobalUnixMakefileGenerator3.h,
- Source/cmLocalKdevelopGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalUnixMakefileGenerator3.h,
- Source/cmOutputRequiredFilesCommand.cxx,
- Source/cmStringCommand.cxx, Source/cmStringCommand.h,
- Source/CTest/cmCTestTestHandler.cxx,
- Source/CTest/cmCTestUpdateHandler.cxx,
- Tests/StringFileTest/CMakeLists.txt,
- Tests/StringFileTest/StringFile.cxx: ENH: move stuff into the
- branch in prep for 2.2.2
-
-2005-10-24 05:29 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-23 05:21 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-22 05:51 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-21 15:24 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: fix for bad
- placement of SILENT target
-
-2005-10-21 12:04 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: symlink issue
-
-2005-10-21 11:10 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: fix bad checkin
- that had debugging code in it
-
-2005-10-21 09:49 hoffman
-
- * Source/kwsys/testFail.c: ENH: try to get this thing to pass with
- cmake 2.2.1
-
-2005-10-21 04:43 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-20 16:37 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: fix over checking
- of build system
-
-2005-10-20 16:37 martink
-
- * Source/cmake.cxx: STYLE: minor cleanup
-
-2005-10-20 15:03 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: fix for def files
- and new local target link lines
-
-2005-10-20 14:25 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: missing
- check_build_system for all target
-
-2005-10-20 13:40 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: big cleanup and fix for
- jump commands
-
-2005-10-20 10:10 hoffman
-
- * Source/: cmStringCommand.cxx, cmStringCommand.h: BUG: end is not
- really end, but rather length
-
-2005-10-20 04:37 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-19 13:23 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: COMP: fix compiler
- error
-
-2005-10-19 11:00 andy
-
- * Source/: cmCTest.cxx, CTest/cmCTestUpdateHandler.cxx: ENH: More
- output
-
-2005-10-19 11:00 andy
-
- * Source/CTest/cmCTestTestHandler.cxx: BUG: Initialize to something
- resonable
-
-2005-10-19 10:47 andy
-
- * Source/kwsys/: Glob.cxx, Glob.hxx.in: COMP: More namespace fixes
- to build on HP
-
-2005-10-19 10:03 martink
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: BUG: cd into local directory to
- reduce link line length
-
-2005-10-19 08:42 andy
-
- * Source/kwsys/Glob.cxx: COMP: Fix namespace. This way kwsys can be
- built outside cmake
-
-2005-10-19 04:41 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-18 16:35 hoffman
-
- * Source/cmOutputRequiredFilesCommand.cxx: ENH: fix test
-
-2005-10-18 16:10 hoffman
-
- * Source/cmOutputRequiredFilesCommand.cxx: ENH: add .txx files and
- put the start directory in the search path
-
-2005-10-18 16:09 hoffman
-
- * Source/cmLocalKdevelopGenerator.cxx: ENH: unused include
-
-2005-10-18 16:09 hoffman
-
- * Source/cmBuildNameCommand.h: ENH: spelling
-
-2005-10-18 14:08 andy
-
- * bootstrap, Source/kwsys/CMakeLists.txt, Source/kwsys/Glob.cxx,
- Source/kwsys/Glob.hxx.in: ENH: Push glob to the kwsys
-
-2005-10-18 13:25 andy
-
- * Modules/Platform/Windows-gcc.cmake: COMP: On mingw, -fPIC is not
- necessary and it actually produces warnings
-
-2005-10-18 13:22 andy
-
- * Tests/MathTest/CMakeLists.txt: ENH: More tests
-
-2005-10-18 09:42 andy
-
- * Source/cmStringCommand.cxx: COMP: Remove warning
-
-2005-10-18 04:37 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-17 21:34 hoffman
-
- * Source/: cmFileTimeComparison.cxx, cmFileTimeComparison.h: add
- missing file
-
-2005-10-17 16:53 andy
-
- * Source/: cmExprParser.cxx, cmExprParser.y: ENH: Fix precedence
-
-2005-10-17 16:42 andy
-
- * Source/: CMakeLists.txt, cmCommands.cxx, cmExprLexer.cxx,
- cmExprLexer.h, cmExprLexer.in.l, cmExprParser.cxx,
- cmExprParser.y, cmExprParserHelper.cxx, cmExprParserHelper.h,
- cmExprParserTokens.h, cmMathCommand.cxx, cmMathCommand.h,
- cmStringCommand.cxx: ENH: Add rudamentary mathematical expression
- support
-
-2005-10-17 16:39 andy
-
- * Tests/MathTest/: CMakeLists.txt, MathTestExec.cxx,
- MathTestTests.h.in: ENH: Add math test
-
-2005-10-17 09:58 king
-
- * Source/: cmDependsFortranLexer.cxx, cmDependsFortranLexer.in.l:
- BUG: Lexer should be case insensitive so flex should be run with
- -i option. This partially addresses bug#2361.
-
-2005-10-17 09:56 andy
-
- * Source/cmStringCommand.cxx, Source/cmStringCommand.h,
- Tests/StringFileTest/CMakeLists.txt,
- Tests/StringFileTest/StringFile.cxx: ENH: Add String length and
- substring
-
-2005-10-17 09:10 andy
-
- * Source/cmFileCommand.cxx, Source/cmFileCommand.h,
- Source/cmStringCommand.cxx, Source/cmStringCommand.h,
- Tests/StringFileTest/CMakeLists.txt,
- Tests/StringFileTest/StringFile.cxx: ENH: Add regular string
- replace (not regex), and relative path command. Also add tests
-
-2005-10-17 09:09 andy
-
- * Source/CTest/cmCTestTestHandler.cxx: BUG: If test passes but it
- should fail, report an error
-
-2005-10-17 08:49 hoffman
-
- * ChangeLog.manual, bootstrap, Modules/CMakeCXXInformation.cmake,
- Modules/FindJNI.cmake, Modules/FindJava.cmake,
- Source/CMakeLists.txt, Source/cmDepends.cxx, Source/cmDepends.h,
- Source/cmDependsC.cxx, Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmGlobalUnixMakefileGenerator3.h,
- Source/cmLocalUnixMakefileGenerator3.cxx, Source/cmMakefile.cxx,
- Source/cmTarget.h, Source/cmake.cxx, Source/cmake.h,
- Source/CTest/cmCTestBuildHandler.cxx: ENH: merge fixes from main
- tree
-
-2005-10-17 04:45 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-16 04:42 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-15 04:43 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-14 05:24 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-13 10:30 andy
-
- * Source/CTest/cmCTestBuildHandler.cxx: ENH: More error exceptions
-
-2005-10-13 10:07 andy
-
- * Source/: cmDepends.cxx, cmFileTimeComparison.cxx: BUG: Fix logic
- to return true when the file was already statted. Also, use
- nanosecond percision if available. Remove debug
-
-2005-10-13 05:14 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-12 13:52 andy
-
- * Source/: cmDepends.cxx, cmDepends.h, cmDependsC.cxx,
- cmDependsC.h, cmDependsFortran.cxx, cmDependsFortran.h,
- cmDependsJava.cxx, cmDependsJava.h,
- cmLocalUnixMakefileGenerator3.cxx: ENH: Improve performance of
- check build system by creating another file that is simpler to
- parse and therefore much faster overall
-
-2005-10-12 13:51 andy
-
- * Source/: cmake.cxx, cmake.h: ENH: Optimize performance by caching
- stat results
-
-2005-10-12 13:50 andy
-
- * Source/cmFileTimeComparison.cxx: COMP: Windows fixes
-
-2005-10-12 13:36 andy
-
- * bootstrap, Source/CMakeLists.txt,
- Source/cmFileTimeComparison.cxx, Source/cmFileTimeComparison.h:
- ENH: Add file time comparison code
-
-2005-10-12 12:08 andy
-
- * Source/kwsys/: SystemTools.hxx.in, SystemTools.cxx: ENH: Add an
- accessor for the maximum file length
-
-2005-10-12 05:16 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-11 05:19 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-10 11:49 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h, cmMakefile.cxx, cmTarget.h:
- ENH: some fixes for better backwards compatibility
-
-2005-10-10 05:09 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-09 05:07 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-08 05:09 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-07 11:36 andy
-
- * Source/CTest/cmCTestBuildHandler.cxx: ENH: Add support for
- setting the maximum number of errors and warnings reported. This
- should fix Bug #2318 - The maximum number of errors to report is
- fixed to 50
-
-2005-10-07 05:26 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-06 17:16 barre
-
- * Source/kwsys/: CMakeLists.txt, testSystemTools.bin,
- testSystemTools.cxx, testSystemTools.h.in: ENH: CMake kills me
- (so does Cygwin)
-
-2005-10-06 15:28 hoffman
-
- * ChangeLog.manual, Source/cmGetSourceFilePropertyCommand.h,
- Source/cmGetTargetPropertyCommand.h,
- Source/cmGetTestPropertyCommand.cxx, Source/cmListFileLexer.c,
- Source/cmListFileLexer.in.l,
- Source/cmLocalVisualStudio7Generator.cxx, Source/cmake.cxx,
- Source/cmake.h, Source/cmakemain.cxx,
- Source/CTest/cmCTestTestCommand.cxx,
- Source/CTest/cmCTestTestCommand.h,
- Source/CTest/cmCTestTestHandler.cxx,
- Utilities/Release/Release.cmake: ENH: merge bug fixes from main
- trunk
-
-2005-10-06 15:10 martink
-
- * Utilities/Release/Release.cmake: ENH: some fixes for missing vars
- and missing libs
-
-2005-10-06 05:18 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-05 16:06 barre
-
- * Source/kwsys/: CMakeLists.txt, testSystemTools.cxx,
- testSystemTools.h.in: ENH: avoid the use of GET_TARGET_PROPERTY
- by testing the CMake executable instead of the test executable
-
-2005-10-05 13:11 king
-
- * Source/kwsys/CMakeLists.txt: BUG: Reverting fundamental type info
- change until it is fixed on more platforms. It was tested on
- Linux, SGI, HP, Sun, OSX, Windows with nmake and VS 6, 7, 7.1, 8,
- Borland Make, and cygwin by hand with spaces in the path and
- cmake 2.0 and 2.2 before committing but still seems to be failing
- on some dashboards...strange.
-
-2005-10-05 05:17 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-04 16:40 barre
-
- * Source/: cmBootstrapCommands.cxx, cmCommands.cxx: ENH: the test
- for kwsys uses GET_TARGET_PROPERTY, which was not in the CMake
- bootstrap
-
-2005-10-04 15:09 barre
-
- * Source/kwsys/: CMakeLists.txt, testSystemTools.cxx,
- testSystemTools.h.in: ENH: add kwsys test for DetectFileType
-
-2005-10-04 10:58 andy
-
- * Source/: cmCTest.cxx, CTest/cmCTestSubmitHandler.cxx: ENH: More
- verbosity
-
-2005-10-04 05:02 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-03 14:44 king
-
- * Source/kwsys/: CMakeLists.txt, kwsysPlatformCxxTests.cxx: ENH:
- Converting FundamentalType try-compiles into a single try-run.
- All the information about the existence, size, and signedness of
- types can be determined in one program thanks to limits.h.
-
-2005-10-03 14:33 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: Double-quotes in
- definitions must be escaped.
-
-2005-10-03 05:03 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-02 05:01 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-10-01 05:03 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-29 04:55 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-28 04:55 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-27 04:54 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-26 04:55 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-24 04:57 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-23 14:39 hoffman
-
- * Modules/CMakeCXXInformation.cmake: ENH: remove -lgcc used by
- crazy coverage stuff
-
-2005-09-23 14:38 hoffman
-
- * Modules/: FindJNI.cmake, FindJava.cmake: ENH: java fixes from
- Mathieu
-
-2005-09-23 12:50 martink
-
- * Source/cmake.cxx: BUG: the -P option was not working with
- relative paths and a couple types
-
-2005-09-23 04:54 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-22 09:58 andy
-
- * Source/kwsys/Registry.cxx: COMP: Try to remove warnings
-
-2005-09-22 05:06 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-21 14:15 king
-
- * Source/kwsys/kwsysPlatformCxxTests.cmake: ENH: Updated to use
- modern FILE command for writing to output logs instead of
- WRITE_FILE.
-
-2005-09-21 13:42 king
-
- * Source/kwsys/kwsys_ios_sstream.h.in: BUG: kwsys_ios namespace
- should import streambuf also.
-
-2005-09-21 13:31 king
-
- * Source/: cmGetSourceFilePropertyCommand.h,
- cmGetTargetPropertyCommand.h, cmake.h, cmakemain.cxx: BUG:
- Corrected and updated documentation of the -P option, -C option,
- GET_TARGET_PROPERTY command, and GET_SOURCE_FILE_PROPERTY
- command.
-
-2005-09-21 10:32 martink
-
- * Source/: cmCommands.cxx, cmITKWrapTclCommand.cxx,
- cmITKWrapTclCommand.h: ENH: removed ITK command
-
-2005-09-21 05:10 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-20 15:08 andy
-
- * Source/CTest/cmCTestTestHandler.cxx: ENH: Properly report failed
- tests
-
-2005-09-20 12:50 martink
-
- * Tests/: LoadCommand/CMakeLists.txt,
- LoadCommand/CMakeCommands/cmTestCommand.c,
- LoadCommandOneConfig/CMakeLists.txt,
- LoadCommandOneConfig/CMakeCommands/cmTestCommand.c: ENH: increase
- coverage in loaded commands
-
-2005-09-20 10:42 andy
-
- * Source/kwsys/CMakeLists.txt: ENH: Make message into status
-
-2005-09-20 05:05 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-19 17:20 king
-
- * Source/: cmListFileLexer.c, cmListFileLexer.in.l: BUG: When an
- unquoted argument contains a pair of matching double quotes
- spaces and tabs should be allowed in-between. This allows
- arguments like -DFOO='"bar zot"' to work.
-
-2005-09-19 16:19 andy
-
- * Source/kwsys/Registry.cxx: BUG: Remove warning and try to fix
- memory problem
-
-2005-09-19 15:15 andy
-
- * Source/kwsys/CMakeLists.txt: ENH: Test for both commands
-
-2005-09-19 15:11 andy
-
- * Source/CTest/cmCTestTestHandler.cxx: ENH: Modify output based on
- wether it is tested or memory checked
-
-2005-09-19 15:08 andy
-
- * Source/CTest/cmCTestTestCommand.h: BUG: This should fix memory
- checking
-
-2005-09-19 12:38 martink
-
- * Utilities/Release/cmake_release.sh: ENH: update revision numbers
-
-2005-09-19 12:33 hoffman
-
- * Modules/FindQt4.cmake, Modules/FindQt4.cmake.bak,
- Modules/VTKCompatibility.cmake, Source/cmCTest.cxx: minor fixes
- for 2.2.1
-
-2005-09-19 12:19 hoffman
-
- * Modules/FindQt4.cmake: ENH: fix typo
-
-2005-09-19 12:17 hoffman
-
- * Modules/VTKCompatibility.cmake: ENH: remove message
-
-2005-09-19 04:45 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-18 17:15 king
-
- * Source/kwsys/README.txt: STYLE: Added reference to documentation
- in CMakeLists.txt.
-
-2005-09-18 17:08 king
-
- * Source/kwsys/CMakeLists.txt: STYLE: Added backward compatibility
- disclaimer.
-
-2005-09-18 08:17 andy
-
- * Source/: cmGetTestPropertyCommand.cxx, kwsys/CMakeLists.txt: BUG:
- Fix which argument is which, also, fix the test to be less
- agressive
-
-2005-09-18 04:35 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-17 11:31 andy
-
- * Source/CTest/cmCTestTestCommand.cxx: ENH: Fix memcheck command
-
-2005-09-17 09:53 andy
-
- * Source/kwsys/CMakeLists.txt: ENH: Add testing of
- GET_TEST_PROPERTY command
-
-2005-09-17 08:50 andy
-
- * Source/kwsys/Registry.cxx: BUG: On WIN32, since we are using
- subkey, set it
-
-2005-09-17 05:04 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-16 15:30 andy
-
- * Source/kwsys/Registry.cxx: COMP: Remove unused variable
-
-2005-09-16 13:56 andy
-
- * Source/kwsys/: Registry.cxx, testRegistry.cxx: BUG: Fix encoding
- and add deleting to the test
-
-2005-09-16 13:38 andy
-
- * Source/kwsys/: Registry.cxx, Registry.hxx.in, testRegistry.cxx:
- ENH: Modify API a little bit to allow arbitrary length values.
- Encode certain characters. Rename UNIX registry to FILE registry.
- More testing
-
-2005-09-16 12:17 martink
-
- * Utilities/Release/cmake_release.sh: ENH: update revision numbers
-
-2005-09-16 10:57 hoffman
-
- * Utilities/Release/: MakeRelease.cmake.in, README, Release.cmake:
- move off branch
-
-2005-09-16 10:53 martink
-
- * Utilities/Release/: cmake_release.sh: ENH: update revision
- numbers
-
-2005-09-16 10:53 martink
-
- * Utilities/Release/MakeRelease.cmake.in: ENH: fix for
- CMAKE_COMMAND not being defined with -P
-
-2005-09-16 10:47 martink
-
- * Utilities/Release/cmake_release.sh: ENH: fix Bill
-
-2005-09-16 10:41 martink
-
- * Utilities/Release/: MakeRelease.cmake.in, Release.cmake: ENH: fix
- to syntax
-
-2005-09-16 10:32 martink
-
- * Utilities/Release/: Release.cmake, MakeRelease.cmake.in: ENH:
- added commit for release script
-
-2005-09-16 10:10 hoffman
-
- * Utilities/Release/MakeRelease.cmake.in: ENH: auto release stuff
-
-2005-09-16 10:09 andy
-
- * Source/kwsys/Registry.cxx: COMP: Remove problem on borland
-
-2005-09-16 09:21 andy
-
- * Source/kwsys/CMakeLists.txt: ENH: Enable registry, add test of
- SET_TESTS_PROPERTIES, rename tests for dart2
-
-2005-09-16 09:20 andy
-
- * Source/kwsys/Registry.cxx: COMP: Remove some more warnings
-
-2005-09-16 09:15 andy
-
- * Source/kwsys/: Registry.cxx, Registry.hxx.in: ENH: Cleanups and
- expose unix registry on windows (for cygwin etc)
-
-2005-09-16 09:08 andy
-
- * Source/kwsys/: Registry.cxx, Registry.hxx.in: COMP: Win32 fixes
-
-2005-09-16 08:38 andy
-
- * Source/kwsys/Registry.cxx: ENH: More handling of unix versus
- windows registry
-
-2005-09-16 08:20 andy
-
- * Source/kwsys/: Registry.cxx, Registry.hxx.in, testFail.c,
- testRegistry.cxx: ENH: Initial import
-
-2005-09-16 05:17 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-15 17:22 andy
-
- * Source/cmCTest.cxx: ENH: Expose version of ctest
-
-2005-09-15 16:38 hoffman
-
- * CTestCustom.ctest.in, ChangeLog.manual, bootstrap,
- Docs/cmake-mode.el, Modules/CMakeAddNewLanguage.txt,
- Modules/CMakeTestRCCompiler.cmake, Modules/FindQt.cmake,
- Modules/FindQt.cmake.bak, Modules/FindQt3.cmake,
- Modules/FindQt4.cmake, Modules/FindQt4.cmake.bak,
- Modules/UseQt4.cmake, Source/CMakeLists.txt,
- Source/cmAddSubDirectoryCommand.cxx,
- Source/cmAddSubDirectoryCommand.h,
- Source/cmCommandArgumentParserHelper.cxx,
- Source/cmFileCommand.cxx,
- Source/cmGetDirectoryPropertyCommand.cxx,
- Source/cmGetDirectoryPropertyCommand.h,
- Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmLocalGenerator.cxx, Source/cmOrderLinkDirectories.cxx,
- Source/cmTest.h, Source/CTest/cmCTestCoverageHandler.cxx,
- Source/CTest/cmCTestTestHandler.cxx,
- Source/CTest/cmCTestTestHandler.h,
- Tests/OutOfSource/CMakeLists.txt, Tests/OutOfSource/testdp.h.in,
- Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt,
- Tests/OutOfSource/OutOfSourceSubdir/simple.cxx,
- Tests/OutOfSource/SubDir/CMakeLists.txt,
- Tests/Wrapping/CMakeLists.txt, Utilities/Release/CMake.nsi.in:
- Merge more changes from main trunk
-
-2005-09-15 16:06 andy
-
- * Source/CTest/cmCTestCoverageHandler.cxx: COMP: Too fast commit
-
-2005-09-15 16:03 andy
-
- * Source/CTest/cmCTestCoverageHandler.cxx: BUG: Make sure full
- paths are collapsed
-
-2005-09-15 13:26 hoffman
-
- * Source/cmGlobalGenerator.cxx: ENH: fix warning
-
-2005-09-15 12:17 hoffman
-
- * Modules/CMakeAddNewLanguage.txt,
- Modules/CMakeTestRCCompiler.cmake, Source/cmGlobalGenerator.cxx:
- ENH: clean up EnableLanguage try to fix problem where try compile
- runs cmake
-
-2005-09-15 11:05 martink
-
- * CTestCustom.ctest.in: ENH: cleaner code coverage
-
-2005-09-15 04:53 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-14 11:16 hoffman
-
- * Modules/FindQt4.cmake: ENH: only add optional qt stuff to
- QT_INCLUDES
-
-2005-09-14 09:12 hoffman
-
- * Modules/FindQt.cmake: ENH: if qt4 qmake is found then set
- QT_QMAKE_EXECUTABLE to that value so that the same one will be
- used in FindQt4.cmake
-
-2005-09-14 04:52 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-13 12:55 martink
-
- * CTestCustom.ctest.in: ENH: coverage cleanup for non XCode builds
-
-2005-09-13 10:40 martink
-
- * Tests/OutOfSource/: CMakeLists.txt, testdp.h.in,
- OutOfSourceSubdir/CMakeLists.txt, OutOfSourceSubdir/simple.cxx:
- ENH: test get directory properties ability to get props from
- subdirs
-
-2005-09-13 10:39 martink
-
- * Source/: cmGetDirectoryPropertyCommand.cxx,
- cmGetDirectoryPropertyCommand.h, cmGlobalGenerator.cxx,
- cmGlobalGenerator.h: ENH: added DIRECTORY option to
- GET_DIRECTORY_PROPERTIES
-
-2005-09-13 10:33 martink
-
- * Docs/cmake-mode.el: ENH: missing get_directory_property command
-
-2005-09-13 09:25 hoffman
-
- * Modules/FindQt4.cmake: ENH: add some checks on the qmake install
-
-2005-09-13 08:52 hoffman
-
- * Modules/FindQt.cmake: ENH: fix if statement
-
-2005-09-13 04:52 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-12 22:46 hoffman
-
- * Modules/FindQt.cmake: ENH: add docs for QT_REQUIRED
-
-2005-09-12 22:39 hoffman
-
- * Modules/: FindQt.cmake, FindQt4.cmake: ENH: more findqt fixes
-
-2005-09-12 14:26 martink
-
- * Tests/OutOfSource/SubDir/CMakeLists.txt: ENH: convert to work
- with the new syntax for ADD_SUBDIRECTORY
-
-2005-09-12 13:46 martink
-
- * Source/: cmAddSubDirectoryCommand.cxx,
- cmAddSubDirectoryCommand.h: ENH: better format for
- ADD_SUBDIRECTORY command
-
-2005-09-12 11:43 hoffman
-
- * Modules/: FindQt.cmake, FindQt4.cmake: ENH: add new place to
- search for qt4 in registry
-
-2005-09-12 11:25 hoffman
-
- * Modules/FindQt.cmake: ENH: fix typo
-
-2005-09-12 10:37 hoffman
-
- * Source/CMakeLists.txt: ENH: use the findqt3 from this cmake and
- not the one configureing cmake
-
-2005-09-12 10:33 hoffman
-
- * Modules/FindQt.cmake: ENH: add a better message
-
-2005-09-12 10:28 hoffman
-
- * Modules/FindQt3.cmake: ENH: add more libraries for qt3
-
-2005-09-12 09:55 hoffman
-
- * Modules/FindQt4.cmake: ENH: use correct variable for qmake
-
-2005-09-12 09:52 hoffman
-
- * Modules/FindQt4.cmake: ENH: add a better message
-
-2005-09-12 09:36 hoffman
-
- * Modules/FindQt.cmake: ENH: add some messages not errors for
- findqt
-
-2005-09-12 09:32 hoffman
-
- * Modules/FindQt3.cmake, Modules/FindQt4.cmake,
- Source/CMakeLists.txt, Tests/Wrapping/CMakeLists.txt: ENH: more
- qt changes
-
-2005-09-12 09:09 hoffman
-
- * Modules/UseQt4.cmake: ENH: add -D options for qt stuff
-
-2005-09-12 09:00 hoffman
-
- * Modules/: FindQt.cmake, FindQt4.cmake: ENH: make sure the correct
- qmake is used
-
-2005-09-12 04:37 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-11 04:50 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-10 22:36 hoffman
-
- * Modules/FindQt.cmake: ENH: only print errors if QT_REQUIRED is
- set
-
-2005-09-10 10:33 hoffman
-
- * bootstrap, Modules/FindQt.cmake, Source/cmFileCommand.cxx: BUG:
- try to fix qt problems
-
-2005-09-10 04:55 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-09 21:51 hoffman
-
- * Modules/FindQt.cmake, Modules/FindQt3.cmake,
- Modules/FindQt4.cmake, Tests/Wrapping/CMakeLists.txt: ENH: clean
- up the find qt stuff some
-
-2005-09-09 17:04 hoffman
-
- * Modules/: CheckQtInstalled.cmake, FindQt.cmake: ENH: try to fix
- this find qt stuff
-
-2005-09-09 13:23 martink
-
- * Utilities/Release/CMake.nsi.in: ENH: to support both admin and
- locla installs
-
-2005-09-09 11:32 hoffman
-
- * Modules/: CheckQtInstalled.cmake, FindQt.cmake: ENH: make FindQt
- default to qt3 and print a message, and add
- CheckQtInstalled.cmake
-
-2005-09-09 05:07 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-08 15:26 hoffman
-
- * Source/cmCommandArgumentParserHelper.cxx: ENH: remove UMR
-
-2005-09-08 15:25 hoffman
-
- * Source/cmOrderLinkDirectories.cxx: BUG: fix spelling error
-
-2005-09-08 14:59 hoffman
-
- * ChangeLog.manual, Modules/CMakeCInformation.cmake,
- Modules/CMakeCXXInformation.cmake,
- Modules/CMakeDetermineJavaCompiler.cmake,
- Modules/CMakeFortranInformation.cmake, Modules/FindCurses.cmake,
- Modules/FindJNI.cmake, Modules/FindJPEG.cmake,
- Modules/FindJava.cmake, Modules/FindMatlab.cmake,
- Modules/FindMotif.cmake, Modules/FindQt4.cmake,
- Modules/FindQt4.cmake.bak, Modules/FindZLIB.cmake,
- Modules/UseQt4.cmake, Modules/UseSWIG.cmake,
- Modules/VTKCompatibility.cmake, Source/cmGlobalGenerator.cxx,
- Source/cmGlobalXCodeGenerator.cxx,
- Source/cmGlobalXCodeGenerator.h,
- Source/cmOrderLinkDirectories.cxx: merge with main trunk
-
-2005-09-08 14:35 andy
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h:
- BUG: fix xcode 15 (really bill Hoffman)
-
-2005-09-08 14:22 martink
-
- * Source/cmOrderLinkDirectories.cxx: BUG: bug num 1994 library
- linking when a config is not specified but debug and opt libs are
-
-2005-09-08 11:38 hoffman
-
- * Modules/: FindCurses.cmake, FindJPEG.cmake, FindZLIB.cmake: ENH:
- clean up some stuff
-
-2005-09-08 11:38 hoffman
-
- * Modules/UseSWIG.cmake: ENH: add ability to set outdir in swig
-
-2005-09-08 10:03 hoffman
-
- * Modules/: CMakeDetermineJavaCompiler.cmake, FindJNI.cmake,
- FindJava.cmake: ENH: add support for java 1.5
-
-2005-09-08 10:01 hoffman
-
- * Modules/FindMatlab.cmake: ENH: add Matlab support
-
-2005-09-08 09:59 hoffman
-
- * Modules/FindMotif.cmake: ENH: add a find motif
-
-2005-09-08 09:58 hoffman
-
- * Modules/: FindQt4.cmake, UseQt4.cmake: ENH: add Ken Morelands
- fixes for FindQT
-
-2005-09-08 05:05 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-07 17:05 hoffman
-
- * Modules/CMakeCInformation.cmake,
- Modules/CMakeCXXInformation.cmake,
- Modules/CMakeFortranInformation.cmake,
- Modules/VTKCompatibility.cmake, Source/cmGlobalGenerator.cxx:
- ENH: add a fix for VTK on the mac and a way to fix some projects
- with a single file in the cmake modules directory
-
-2005-09-07 05:00 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-06 23:31 andy
-
- * Source/: cmLocalGenerator.cxx, cmTest.h,
- CTest/cmCTestTestHandler.cxx, CTest/cmCTestTestHandler.h: ENH:
- Add a way for test to intentionally fail
-
-2005-09-06 12:55 hoffman
-
- * ChangeLog.manual, bootstrap, Modules/CMakeGenericSystem.cmake,
- Modules/Platform/AIX.cmake, Source/CMakeLists.txt,
- Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmGlobalXCode21Generator.cxx,
- Source/cmGlobalXCode21Generator.h,
- Source/cmGlobalXCodeGenerator.cxx,
- Source/cmGlobalXCodeGenerator.h, Source/cmTryRunCommand.cxx,
- Source/cmXCode21Object.cxx, Source/cmXCode21Object.h,
- Source/cmXCodeObject.cxx, Source/cmXCodeObject.h,
- Source/CTest/cmCTestTestHandler.cxx,
- Source/kwsys/SharedForward.h.in,
- Tests/LoadCommand/CMakeLists.txt,
- Tests/LoadCommandOneConfig/CMakeLists.txt: Merge with main tree
-
-2005-09-06 05:04 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-05 09:17 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmXCodeObject.h: ENH: fix
- warnings
-
-2005-09-05 04:58 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-04 04:46 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-03 22:16 hoffman
-
- * bootstrap: ENH: fix bootstrap, maybe this should somehow grep awk
- the sources from the cmakelist file....
-
-2005-09-03 04:55 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-02 16:29 hoffman
-
- * Source/: CMakeLists.txt, cmGlobalXCode21Generator.cxx,
- cmGlobalXCode21Generator.h, cmGlobalXCodeGenerator.cxx,
- cmGlobalXCodeGenerator.h, cmXCode21Object.cxx, cmXCode21Object.h,
- cmXCodeObject.cxx, cmXCodeObject.h: ENH: add real support for
- Xcode21
-
-2005-09-02 08:41 hoffman
-
- * Source/CMakeLists.txt: BUG: not all Macs are case insensitive if
- they mount nfs directories
-
-2005-09-02 05:05 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-09-01 17:14 hoffman
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: ENH: fix NONE
-
-2005-09-01 05:01 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-31 19:41 king
-
- * Source/kwsys/SharedForward.h.in: ENH: Added cygcheck knowledge
- for --ldd option on Cygwin. Added error message for --ldd option
- when no tool is available but the option was still requested.
-
-2005-08-31 05:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-30 13:58 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx, Source/cmTryRunCommand.cxx,
- Source/CTest/cmCTestTestHandler.cxx,
- Tests/LoadCommand/CMakeLists.txt,
- Tests/LoadCommandOneConfig/CMakeLists.txt: ENH: use native
- Deployment and Development directories
-
-2005-08-30 04:59 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-29 17:09 hoffman
-
- * Modules/Platform/AIX.cmake: ENH: add flags for debug release for
- aix
-
-2005-08-29 16:19 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Modules/CMakeTestCCompiler.cmake, Modules/FindJava.cmake,
- Modules/FindQt3.cmake, Source/CMakeLists.txt,
- Source/cmDependsC.cxx, Source/cmDependsC.h,
- Source/cmFileCommand.cxx, Source/cmGlobalXCodeGenerator.cxx,
- Source/cmLocalGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalVisualStudio6Generator.cxx, Source/cmMakefile.cxx,
- Source/cmSetTargetPropertiesCommand.h, Source/cmSystemTools.cxx,
- Source/cmTarget.cxx, Source/cmTarget.h, Source/cmVersion.cxx,
- Source/cmake.cxx, Source/CTest/cmCTestBuildHandler.cxx,
- Source/CTest/cmCTestGenericHandler.cxx,
- Source/CTest/cmCTestTestHandler.cxx,
- Source/CTest/cmCTestTestHandler.h,
- Source/CTest/cmCTestUpdateCommand.cxx,
- Source/kwsys/SharedForward.h.in, Source/kwsys/SystemTools.cxx,
- Templates/EXEHeader.dsptemplate,
- Tests/CustomCommand/CMakeLists.txt, Tests/CustomCommand/foo.h.in,
- Tests/CustomCommand/foo.in, Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: merge with cvs again
- and change version
-
-2005-08-29 15:49 king
-
- * Modules/CMakeGenericSystem.cmake: ENH: Picking better default for
- CMAKE_INSTALL_PREFIX on Windows by using ProgramFiles environment
- variable. Now that install actually works on Windows I'm making
- this entry non-advanced also.
-
-2005-08-29 04:57 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-28 04:57 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-27 05:04 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-26 17:02 andy
-
- * Modules/FindJava.cmake: ENH: More paths for java
-
-2005-08-26 16:20 andy
-
- * Source/CTest/cmCTestGenericHandler.cxx: COMP: Simplify logic and
- remove sun compile error
-
-2005-08-26 05:00 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-25 05:01 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-24 11:18 andy
-
- * Source/CTest/cmCTestGenericHandler.cxx: BUG: Prevent from
- creating bogus files
-
-2005-08-24 04:54 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-23 13:25 king
-
- * Modules/FindQt3.cmake: ENH: Added support for finding qt-mtedu,
- the educational version of Qt.
-
-2005-08-23 10:24 hoffman
-
- * Source/cmFileCommand.cxx: make sure correct path type is used
-
-2005-08-23 04:48 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-22 04:52 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-21 04:56 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-20 05:01 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-19 17:57 king
-
- * Source/cmLocalVisualStudio6Generator.cxx,
- Templates/EXEHeader.dsptemplate: BUG: Fixed OUTPUT_NAME feature
- for VS6 generator. It was not working for Debug builds and was
- not paying attention to the executable output path.
-
-2005-08-19 17:56 king
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: BUG: Install rule should take
- build configuration into account.
-
-2005-08-19 17:17 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: add support for
- OUTPUT_NAME
-
-2005-08-19 10:13 andy
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: If the scanner is
- not defined this would crash. For example when using new language
-
-2005-08-19 09:38 king
-
- * Source/cmake.cxx: ENH: Added cmake -E create_symlink command that
- behaves like ln -s.
-
-2005-08-19 09:29 king
-
- * Modules/CMakeTestCCompiler.cmake: BUG: Need to test void* not
- "void *" because the Intel compiler icc expands the asterisk.
- Thanks to Filipe Sousa for the patch.
-
-2005-08-19 09:22 king
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: BUG: Removing exe VERSION
- attribute test until it is implemented in the XCode generator.
-
-2005-08-19 04:52 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-18 16:17 andy
-
- * Source/CTest/cmCTestTestHandler.h: COMP: Add STD namespace
-
-2005-08-18 16:06 king
-
- * Source/kwsys/SharedForward.h.in: BUG: Fixed dirname in a few
- cases on windows. Now using KWSYS_SHARED_FORWARD_CONFIG_NAME
- setting instead of CMAKE_INTDIR directly to give choice to user
- code. Updated documentation to include
- @KWSYS_NAMESPACE@_SHARED_FORWARD_CONFIG_NAME,
- @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_PRINT, and
- @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_LDD settings.
-
-2005-08-18 13:50 andy
-
- * Source/CTest/: cmCTestTestHandler.cxx, cmCTestTestHandler.h: ENH:
- Improve log file strategy
-
-2005-08-18 10:02 andy
-
- * Source/CTest/cmCTestUpdateCommand.cxx: ENH: Set update options
-
-2005-08-18 09:23 king
-
- * Source/kwsys/SharedForward.h.in: ENH: Added support for Windows.
-
-2005-08-18 09:21 king
-
- * Tests/CustomCommand/foo.h.in: COMP: Avoid C++ comment in C
- translation unit.
-
-2005-08-18 09:19 king
-
- * Source/cmDependsC.cxx: COMP: Work-around iterator/const_iterator
- comparison problem on Borland 5.5.
-
-2005-08-18 05:41 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-17 17:56 king
-
- * Tests/CustomCommand/CMakeLists.txt: BUG: It seems the
- auto-object-depends feature does not work in Visual Studio. I'm
- restoring the explicit OBJECT_DEPENDS lines.
-
-2005-08-17 17:39 king
-
- * Source/cmSystemTools.cxx: BUG: RunSingleCommand should translate
- NULL characters in the output to valid text. This should fix the
- missing-output problem caused by NULL-characters in VS build
- output.
-
-2005-08-17 17:04 king
-
- * Source/kwsys/SystemTools.cxx: BUG: Automatic pwd/cwd path
- translation must check that the generated logical-to-physical
- mapping is correct by using realpath.
-
-2005-08-17 16:19 king
-
- * Source/CMakeLists.txt, Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: Updated SimpleInstall
- test to test new versioned executable and OUTPUT_NAME support.
-
-2005-08-17 16:11 king
-
- * Source/: cmFileCommand.cxx, cmLocalGenerator.cxx,
- cmLocalUnixMakefileGenerator3.cxx,
- cmSetTargetPropertiesCommand.h, cmTarget.cxx, cmTarget.h: ENH:
- Added versioned executable support. This partially addresses
- bug#2143. Also made OUTPUT_NAME work when installing
- executables.
-
-2005-08-17 16:06 king
-
- * Source/cmake.cxx: ENH: Added -E cmake_symlink_executable command
- to help create symbolic links for versioned executables.
-
-2005-08-17 16:05 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Do not make a file
- depend on a virtual target. That causes everything to always
- rebuild.
-
-2005-08-17 14:16 andy
-
- * Source/CTest/cmCTestBuildHandler.cxx: ENH: More error regex
-
-2005-08-17 13:23 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: COMP: Cannot use
- first/last insertion constructor of std::set because it is not
- available on all platforms.
-
-2005-08-17 11:48 king
-
- * Tests/CustomCommand/: CMakeLists.txt, foo.in, foo.h.in: ENH:
- Adding test for auto-object-depends feature. It has been tested
- with the Makefile generator. Hopefully this will work for the
- Visual Studio and XCode generators.
-
-2005-08-17 11:43 king
-
- * Source/: cmDependsC.cxx, cmDependsC.h,
- cmLocalUnixMakefileGenerator3.cxx: ENH: Adding support for
- automatically adding the OBJECT_DEPENDS for generated header
- files.
-
-2005-08-17 05:44 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-16 08:32 hoffman
-
- * Utilities/Release/: cmake_release.sh: ENH: file is now configured
-
-2005-08-16 05:46 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-15 05:40 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-14 05:45 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-13 05:50 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-12 11:57 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-11 14:02 hoffman
-
- * ChangeLog.manual, Modules/CMakeCCompiler.cmake.in,
- Modules/CMakeCInformation.cmake,
- Modules/CMakeCXXCompiler.cmake.in,
- Modules/CMakeCXXInformation.cmake,
- Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Modules/CMakeDetermineFortranCompiler.cmake,
- Modules/CMakeDetermineJavaCompiler.cmake,
- Modules/CMakeDetermineRCCompiler.cmake,
- Modules/CMakeDetermineSystem.cmake,
- Modules/CMakeFortranCompiler.cmake.in,
- Modules/CMakeFortranInformation.cmake,
- Modules/CMakeGenericSystem.cmake,
- Modules/CMakeJavaCompiler.cmake.in,
- Modules/CMakeRCCompiler.cmake.in,
- Modules/CMakeRCInformation.cmake,
- Modules/CMakeTestCCompiler.cmake,
- Modules/CMakeTestCXXCompiler.cmake,
- Modules/CMakeTestFortranCompiler.cmake, Modules/CTest.cmake,
- Modules/CTestTargets.cmake, Modules/CheckCSourceCompiles.cmake,
- Modules/CheckCXXSourceCompiles.cmake,
- Modules/CheckFunctionExists.cmake,
- Modules/CheckIncludeFile.cmake,
- Modules/CheckIncludeFileCXX.cmake,
- Modules/CheckIncludeFiles.cmake,
- Modules/CheckLibraryExists.cmake,
- Modules/CheckSymbolExists.cmake, Modules/CheckTypeSize.cmake,
- Modules/CheckVariableExists.cmake, Modules/Dart.cmake,
- Modules/FindDoxygen.cmake, Modules/FindGLUT.cmake,
- Modules/FindJNI.cmake, Modules/FindOpenAL.cmake,
- Modules/FindPhysFS.cmake, Modules/FindPythonInterp.cmake,
- Modules/FindQt.cmake, Modules/FindQt.cmake.bak,
- Modules/FindQt3.cmake, Modules/FindQt4.cmake,
- Modules/FindQt4.cmake.bak, Modules/FindSDL.cmake,
- Modules/FindSDL.cmake.bak, Modules/FindSDL_image.cmake,
- Modules/FindSDL_image.cmake.bak, Modules/FindSDL_mixer.cmake,
- Modules/FindSDL_mixer.cmake.bak, Modules/FindSDL_net.cmake,
- Modules/FindSDL_net.cmake.bak, Modules/FindSDL_sound.cmake,
- Modules/FindSDL_ttf.cmake, Modules/FindSDL_ttf.cmake.bak,
- Modules/FindThreads.cmake, Modules/TestBigEndian.cmake,
- Modules/TestCXXAcceptsFlag.cmake,
- Modules/TestForANSIForScope.cmake,
- Modules/TestForSTDNamespace.cmake, Modules/Use_wxWindows.cmake,
- Modules/Platform/CYGWIN-g77.cmake, Modules/Platform/IRIX64.cmake,
- Modules/Platform/Windows-cl.cmake, Modules/Platform/g77.cmake,
- Source/CMakeLists.txt, Source/cmAddCustomCommandCommand.cxx,
- Source/cmAddDependenciesCommand.h, Source/cmAddTestCommand.h,
- Source/cmCTest.cxx, Source/cmCTest.h, Source/cmCacheManager.cxx,
- Source/cmCommands.cxx, Source/cmCustomCommand.cxx,
- Source/cmCustomCommand.h, Source/cmDepends.cxx,
- Source/cmDepends.h, Source/cmDependsC.cxx, Source/cmDependsC.h,
- Source/cmDependsFortran.cxx, Source/cmDependsFortran.h,
- Source/cmDependsJava.cxx, Source/cmDependsJava.h,
- Source/cmDocumentation.cxx, Source/cmDynamicLoader.cxx,
- Source/cmFLTKWrapUICommand.cxx, Source/cmFileCommand.cxx,
- Source/cmGetTestPropertyCommand.cxx,
- Source/cmGetTestPropertyCommand.h, Source/cmGlobalGenerator.cxx,
- Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmGlobalUnixMakefileGenerator3.h,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalXCode21Generator.cxx,
- Source/cmGlobalXCode21Generator.h,
- Source/cmGlobalXCodeGenerator.cxx,
- Source/cmGlobalXCodeGenerator.h, Source/cmListFileLexer.c,
- Source/cmListFileLexer.in.l, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalUnixMakefileGenerator3.h,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio6Generator.h,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmOrderLinkDirectories.cxx,
- Source/cmOrderLinkDirectories.h, Source/cmQTWrapCPPCommand.cxx,
- Source/cmSetTestsPropertiesCommand.cxx,
- Source/cmSetTestsPropertiesCommand.h, Source/cmSourceGroup.cxx,
- Source/cmSourceGroup.h, Source/cmSourceGroupCommand.cxx,
- Source/cmTarget.cxx, Source/cmTest.cxx, Source/cmTest.h,
- Source/cmTryCompileCommand.h, Source/cmUtilitySourceCommand.cxx,
- Source/cmake.cxx, Source/cmake.h, Source/ctest.cxx,
- Source/CTest/cmCTestBuildHandler.cxx,
- Source/CTest/cmCTestCoverageHandler.cxx,
- Source/CTest/cmCTestCoverageHandler.h,
- Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx,
- Source/CTest/cmCTestGenericHandler.cxx,
- Source/CTest/cmCTestSubmitCommand.cxx,
- Source/CTest/cmCTestSubmitHandler.cxx,
- Source/CTest/cmCTestTestCommand.cxx,
- Source/CTest/cmCTestTestHandler.cxx,
- Source/CTest/cmCTestUpdateHandler.cxx, Source/kwsys/Base64.c,
- Source/kwsys/Base64.h.in, Source/kwsys/CMakeLists.txt,
- Source/kwsys/Configure.h.in, Source/kwsys/FundamentalType.h.in,
- Source/kwsys/Process.h.in, Source/kwsys/SystemTools.cxx,
- Source/kwsys/SystemTools.hxx.in,
- Source/kwsys/kwsysPlatformCxxTests.cmake,
- Source/kwsys/kwsysPlatformCxxTests.cxx,
- Source/kwsys/testHashSTL.cxx, Source/kwsys/testhash.cxx,
- Tests/BundleTest/BundleTest.cxx, Tests/BundleTest/CMakeLists.txt,
- Tests/CTestTest/test.cmake.in, Tests/CTestTest2/test.cmake.in,
- Tests/CTestTest3/test.cmake.in,
- Tests/Complex/cmTestConfigure.h.in,
- Tests/Complex/Executable/CMakeLists.txt,
- Tests/Complex/Executable/complex.cxx,
- Tests/Complex/Executable/testcflags.c,
- Tests/ComplexOneConfig/cmTestConfigure.h.in,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/testcflags.c,
- Tests/ComplexRelativePaths/cmTestConfigure.h.in,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/testcflags.c,
- Tests/MacroTest/CMakeLists.txt,
- Tests/MakeClean/ToClean/CMakeLists.txt,
- Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt,
- Tests/OutOfSource/OutOfSourceSubdir/simple.cxx,
- Tests/OutOfSource/OutOfSourceSubdir/testlib.cxx,
- Tests/OutOfSource/OutOfSourceSubdir/testlib.h,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt, Utilities/CMakeLists.txt,
- Utilities/cmcurl/CMakeLists.txt: ENH: move cvs onto branch and
- try for beta 2
-
-2005-08-11 13:20 martink
-
- * Source/cmake.cxx: ENH: added better error checking for cases when
- there is a CMakeCache.txt file but it is not readable
-
-2005-08-11 11:44 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-10 12:55 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx, Source/cmLocalGenerator.cxx,
- Source/cmOrderLinkDirectories.cxx,
- Source/cmOrderLinkDirectories.h,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/complex.cxx: ENH: fix bug
- 2087 lib prefix stripped off on windows
-
-2005-08-10 12:50 hoffman
-
- * Modules/FindQt4.cmake: ENH: some clean up from Clinton
-
-2005-08-10 12:01 hoffman
-
- * Modules/: FindOpenAL.cmake, FindSDL.cmake, FindSDL_image.cmake,
- FindSDL_mixer.cmake, FindSDL_net.cmake, FindSDL_sound.cmake,
- FindSDL_ttf.cmake: ENH: add Eric Wings FindSDL updates
-
-2005-08-10 11:42 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-10 10:01 hoffman
-
- * Source/cmDependsC.cxx: ENH: fix bug in depend file removing for
- deleted depend files
-
-2005-08-10 08:48 hoffman
-
- * Modules/: FindQt.cmake, FindQt4.cmake: ENH: fixed up qt stuff
- from Clinton Stimpson
-
-2005-08-09 13:12 martink
-
- * Source/CTest/cmCTestTestHandler.cxx: BUG: do not search the
- user's path for text executables when a full path is provided to
- the test
-
-2005-08-09 11:36 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-09 10:35 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: fix for sun make
- with spaces
-
-2005-08-08 15:23 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: have the
- build.make file include flags.make and use the language flags
-
-2005-08-08 13:28 martink
-
- * Source/cmAddCustomCommandCommand.cxx: ENH: fix for earlier fix on
- source with relative path
-
-2005-08-08 12:00 king
-
- * Source/cmAddCustomCommandCommand.cxx: BUG: Do not convert SOURCE
- argument from relative to full path. It breaks the old-style
- SOURCE==TARGET trick and the SOURCE argument is only present for
- old-style commands anyway. This addresses bug#2120.
-
-2005-08-08 11:33 king
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: BUG: Need TSD target to be built
- before SimpleInstall.
-
-2005-08-08 11:28 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Do not escape
- CMAKE_COMMAND twice.
-
-2005-08-08 11:02 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: fix and issue with
- spaces in paths
-
-2005-08-08 10:47 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-08 09:37 king
-
- * Source/cmake.cxx: BUG: When exiting before the configure step in
- script mode we must account for
- cmSystemTools::GetErrorOccuredFlag() for the return code.
-
-2005-08-07 10:30 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-06 10:50 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-05 17:07 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: fix warning
-
-2005-08-05 14:19 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: some fixes for cwd
- problems with rebuild_cache option
-
-2005-08-05 11:31 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-04 17:12 king
-
- * Source/kwsys/CMakeLists.txt: ENH: If VTK_LIBRARY_PROPERTIES is
- set then the properties it lists will be added to VTK library
- targets with SET_TARGET_PROPERTIES. This will be useful to
- enable shared library versioning.
-
-2005-08-04 11:19 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-03 16:10 king
-
- * Source/cmAddDependenciesCommand.h: ENH: Clarified documentation
- further.
-
-2005-08-03 14:16 andy
-
- * Source/CTest/cmCTestBuildHandler.cxx: ENH: More build errors
-
-2005-08-03 14:15 andy
-
- * Source/CTest/cmCTestCoverageHandler.cxx: ENH: More handling of
- gcov 4.0
-
-2005-08-03 13:34 andy
-
- * Source/CTest/cmCTestCoverageHandler.cxx: ENH: More support for
- gcov 4.0
-
-2005-08-03 13:19 andy
-
- * Modules/: CTest.cmake, CTestTargets.cmake: ENH: Initial import
-
-2005-08-03 13:19 andy
-
- * Modules/: Dart.cmake, FindJNI.cmake: STYLE: Fix typo
-
-2005-08-03 11:56 andy
-
- * Source/CTest/cmCTestCoverageHandler.cxx: ENH: Add support for the
- new gcc that uses files with extension .gcda
-
-2005-08-03 11:50 andy
-
- * Tests/CTestTest2/test.cmake.in: COMP: Fix for proxy test
-
-2005-08-03 11:24 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-02 17:41 hoffman
-
- * Modules/Platform/Windows-cl.cmake: ENH: /nologo must be first
-
-2005-08-02 16:44 hoffman
-
- * Modules/FindQt4.cmake: ENH: add changes for qt4 from Clinton
- Stimpson
-
-2005-08-02 16:34 hoffman
-
- * Modules/FindQt4.cmake: ENH: add changes for qt4 from Clinton
- Stimpson
-
-2005-08-02 13:40 andy
-
- * Source/CMakeLists.txt: ENH: change name from XCode to Xcode no
- need to test bootstrap for xcode
-
-2005-08-02 13:02 andy
-
- * Source/CMakeLists.txt: ENH: change name from XCode to Xcode no
- need to test bootstrap for xcode
-
-2005-08-02 13:01 andy
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: get around problem where
- OBJROOT has been set by default for all projects in Xcode gui
-
-2005-08-02 11:22 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-02 11:06 hoffman
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.cxx: FIX: fix bad depend info and
- COMPILE_FLAGS problem and remove extra cerr calls
-
-2005-08-02 10:07 andy
-
- * Tests/CTestTest/test.cmake.in: COMP: Try to fix test by taking
- arg1 into acount
-
-2005-08-02 09:55 hoffman
-
- * Modules/FindQt.cmake: ENH: add advanced values
-
-2005-08-01 16:49 king
-
- * Source/: cmListFileLexer.c, cmListFileLexer.in.l: BUG: Unquoted
- arguments can have quotes that are not at the beginning, but only
- an even number of them.
-
-2005-08-01 12:06 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-08-01 10:19 martink
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: first step to only
- rebuuilding on flag changes
-
-2005-08-01 09:44 hoffman
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt: ENH: make sure
- CMAKE_C_FLAGS are not clobbered
-
-2005-08-01 09:24 king
-
- * Source/cmQTWrapCPPCommand.cxx: BUG: Patch from Filipe Sousa.
- QT_WRAP_CPP should generate the file moc_dlgmain.ui.cxx instead
- of moc_dlgmain.cxx.
-
-2005-07-31 23:05 andy
-
- * Modules/CheckCXXSourceCompiles.cmake,
- Tests/MacroTest/CMakeLists.txt: ENH: Add C++ test too
-
-2005-07-31 23:02 andy
-
- * Modules/CheckCSourceCompiles.cmake,
- Tests/MacroTest/CMakeLists.txt: ENH: Add a test for C source file
- like AC_TRY_COMPILE
-
-2005-07-31 22:25 hoffman
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt: ENH: use ansi
- flags
-
-2005-07-31 11:51 andy
-
- * Source/: cmCommands.cxx, cmGetTestPropertyCommand.cxx,
- cmGetTestPropertyCommand.h, cmLocalGenerator.cxx, cmMakefile.cxx,
- cmMakefile.h, cmSetTestsPropertiesCommand.cxx,
- cmSetTestsPropertiesCommand.h, cmTest.cxx, cmTest.h: ENH: Add set
- and get test propety command
-
-2005-07-31 11:42 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-30 21:58 hoffman
-
- * Tests/: Complex/Executable/testcflags.c,
- ComplexOneConfig/Executable/testcflags.c,
- ComplexRelativePaths/Executable/testcflags.c: ENH: no c++
- comments in a c file
-
-2005-07-30 11:51 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-29 14:17 martink
-
- * Source/cmFLTKWrapUICommand.cxx: ENH; better warning message and
- fix type per julien
-
-2005-07-29 14:02 hoffman
-
- * Tests/: Complex/cmTestConfigure.h.in,
- Complex/Executable/complex.cxx,
- ComplexOneConfig/cmTestConfigure.h.in,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/cmTestConfigure.h.in,
- ComplexRelativePaths/Executable/complex.cxx: ENH: do not test for
- c and cxx flags on visual studio as it does not work yet
-
-2005-07-29 13:19 martink
-
- * Source/kwsys/kwsysPlatformCxxTests.cmake: ENH: change loc of log
- files
-
-2005-07-29 11:56 hoffman
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- Complex/Executable/complex.cxx, Complex/Executable/testcflags.c,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexOneConfig/Executable/testcflags.c,
- ComplexRelativePaths/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/complex.cxx,
- ComplexRelativePaths/Executable/testcflags.c: ENH: add new test
- to make sure c and cxx flags are going to the right files
-
-2005-07-29 11:52 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-29 11:25 andy
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Fix dependencies.
- Looks like all dependencies were missing subdirectory
-
-2005-07-29 10:04 andy
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: undo last change
-
-2005-07-29 10:02 andy
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: support versions greater
- than 20
-
-2005-07-29 09:19 martink
-
- * Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Modules/CMakeDetermineFortranCompiler.cmake,
- Modules/CMakeDetermineJavaCompiler.cmake,
- Modules/CMakeDetermineRCCompiler.cmake,
- Modules/CMakeDetermineSystem.cmake,
- Modules/CMakeTestCCompiler.cmake,
- Modules/CMakeTestCXXCompiler.cmake,
- Modules/CMakeTestFortranCompiler.cmake,
- Modules/CheckFunctionExists.cmake,
- Modules/CheckIncludeFile.cmake,
- Modules/CheckIncludeFileCXX.cmake,
- Modules/CheckIncludeFiles.cmake,
- Modules/CheckLibraryExists.cmake,
- Modules/CheckSymbolExists.cmake, Modules/CheckTypeSize.cmake,
- Modules/CheckVariableExists.cmake, Modules/FindThreads.cmake,
- Modules/TestBigEndian.cmake, Modules/TestCXXAcceptsFlag.cmake,
- Modules/TestForANSIForScope.cmake,
- Modules/TestForSTDNamespace.cmake,
- Modules/Platform/Windows-cl.cmake, Source/cmCacheManager.cxx,
- Source/cmGlobalGenerator.cxx,
- Source/cmGlobalUnixMakefileGenerator3.cxx,
- Source/cmGlobalXCodeGenerator.cxx, Source/cmLocalGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator3.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Tests/MakeClean/ToClean/CMakeLists.txt,
- Utilities/cmcurl/CMakeLists.txt: ENH: put cmake files intoa
- CMakeFiles subdir to clean up bin tree
-
-2005-07-28 15:24 martink
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: fix warning
-
-2005-07-28 14:52 andy
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: make sure c flags are
- used for c and cxx flags are used for cxx, really Bill
-
-2005-07-28 13:21 barre
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH: add
- method to attempt to check if a file is text or binary
-
-2005-07-28 13:12 andy
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: make sure custom commands
- depend on full path files only: Bill as Andy
-
-2005-07-28 11:58 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-28 09:14 martink
-
- * Source/: cmCustomCommand.cxx, cmCustomCommand.h,
- cmLocalUnixMakefileGenerator3.cxx: ENH: always write out all
- custom commands
-
-2005-07-27 17:23 king
-
- * Source/cmMakefile.cxx: BUG: InitializeFromParent should copy
- include file regular expressions.
-
-2005-07-27 16:46 king
-
- * Source/cmGlobalGenerator.cxx: ENH: RUN_TESTS target now uses
- proper CMAKE_CFG_INTDIR setting to get $(IntDir) or $(OutDir)
- depending on the generator.
-
-2005-07-27 16:37 king
-
- * Source/cmUtilitySourceCommand.cxx: BUG: Hack to support building
- existing trees with UTILITY_SOURCE commands and the new VS
- generator directory structure.
-
-2005-07-27 15:46 andy
-
- * Source/cmGlobalGenerator.cxx: BUG: Generate RUN_TEST target if
- any tests are there
-
-2005-07-27 13:36 king
-
- * Source/: cmGlobalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h: ENH: Generator now creates a
- separate intermediate files directory for each target. This is
- needed for MSVC 8 to support parallel builds.
-
-2005-07-27 12:41 martink
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: fix some warnings and
- cleanup some
-
-2005-07-27 11:56 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-27 11:42 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: maybe fix fortran
- issue
-
-2005-07-27 11:36 martink
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: fix some warnings and
- cleanup some
-
-2005-07-27 11:31 martink
-
- * Source/: cmDependsJava.cxx, cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: fix some warnings and
- cleanup some
-
-2005-07-27 09:49 martink
-
- * Source/: cmDepends.cxx, cmDepends.h, cmDependsC.cxx,
- cmDependsC.h, cmDependsFortran.cxx, cmDependsFortran.h,
- cmDependsJava.cxx, cmDependsJava.h,
- cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h, cmLocalGenerator.cxx,
- cmLocalGenerator.h, cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h, cmake.cxx: ENH: reduce the
- number of files produced still needs a bit more cleanup
-
-2005-07-26 17:40 king
-
- * Modules/Dart.cmake: ENH: Added VS8 support for DART_CXX_NAME.
-
-2005-07-26 13:26 hoffman
-
- * Source/cmTarget.cxx: ENH: make sure source file depends are used
- to determine if custom commands are used
-
-2005-07-26 13:26 hoffman
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: if it is not a
- cmake target or a full path do not put depend information in the
- command
-
-2005-07-26 13:25 hoffman
-
- * Source/cmFLTKWrapUICommand.cxx: ENH: make sure custom command
- depend on fluid so if fltk is part of project fluid gets built
- first
-
-2005-07-26 11:45 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-26 11:37 king
-
- * Source/kwsys/: CMakeLists.txt, FundamentalType.h.in: ENH: Added
- FundamentalType header defining platform-independent fixed
- size/signedness integer types.
-
-2005-07-26 11:36 king
-
- * Source/kwsys/kwsysPlatformCxxTests.cxx: ENH: Added
- TEST_KWSYS_CXX_SAME_LONG_AND___INT64,
- TEST_KWSYS_CXX_SAME_LONG_LONG_AND___INT64,
- TEST_KWSYS_CAN_CONVERT_UI64_TO_DOUBLE, and
- TEST_KWSYS_CHAR_IS_SIGNED.
-
-2005-07-26 11:34 king
-
- * Source/kwsys/: Base64.c, Base64.h.in, Configure.h.in,
- Process.h.in: ENH: Moved kwsys_ns and kwsysEXPORT macros to
- Configure.h in the case of building a kwsys source file. This
- allows more than one header to be included in a kwsys source file
- without redefining the macros.
-
-2005-07-26 09:17 andy
-
- * Tests/CTestTest3/test.cmake.in: ENH: Add support for multi-string
- compiler name, and improve support for subversion
-
-2005-07-25 16:10 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: ENH: fix lib case bug
- correctly
-
-2005-07-25 11:41 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-24 11:42 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-23 11:44 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-23 10:32 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: undo fix
-
-2005-07-22 17:36 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-22 15:41 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: ENH: more efficent fix
- for bug # 2063
-
-2005-07-22 15:33 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: fix for case
- mismatched lib bug # 2063
-
-2005-07-22 15:32 hoffman
-
- * Source/cmDependsC.cxx: ENH: string += is very slow, so don't use
- it
-
-2005-07-22 08:40 andy
-
- * Source/CTest/cmCTestUpdateHandler.cxx: ENH: Better handling of
- removed files and remove warning
-
-2005-07-22 08:39 andy
-
- * Source/CTest/cmCTestBuildHandler.cxx: ENH: More regular
- expressions
-
-2005-07-21 15:54 andy
-
- * Source/CTest/cmCTestUpdateHandler.cxx: ENH: Add support for
- detecting files that were removed
-
-2005-07-21 10:26 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-21 09:07 andy
-
- * Source/CTest/cmCTestSubmitHandler.cxx: BUG: Remove duplicate
- prefix
-
-2005-07-20 22:23 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: fix warning
-
-2005-07-20 15:44 hoffman
-
- * Modules/CMakeCCompiler.cmake.in, Modules/CMakeCInformation.cmake,
- Modules/CMakeCXXCompiler.cmake.in,
- Modules/CMakeCXXInformation.cmake,
- Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Modules/CMakeDetermineFortranCompiler.cmake,
- Modules/CMakeDetermineJavaCompiler.cmake,
- Modules/CMakeDetermineRCCompiler.cmake,
- Modules/CMakeFortranCompiler.cmake.in,
- Modules/CMakeFortranInformation.cmake,
- Modules/CMakeJavaCompiler.cmake.in,
- Modules/CMakeRCCompiler.cmake.in,
- Modules/CMakeRCInformation.cmake, Source/cmLocalGenerator.cxx:
- ENH: make sure flags set in CC or CXX environment variables stay
- with the compiler
-
-2005-07-20 12:54 hoffman
-
- * Modules/: CMakeCInformation.cmake, CMakeCXXInformation.cmake,
- Platform/Windows-cl.cmake: ENH: move flags next to compiler, so
- if env contains compiler and some flag, they stay together
-
-2005-07-20 12:53 hoffman
-
- * Source/CMakeLists.txt: ENH: java does not work under mingw
-
-2005-07-20 12:48 hoffman
-
- * Modules/: FindQt.cmake, FindQt4.cmake: ENH: make sure qmake is on
- the machine before running it
-
-2005-07-20 12:40 andy
-
- * Source/kwsys/testHashSTL.cxx: ENH: Rename test
-
-2005-07-20 12:03 andy
-
- * Source/cmCTest.cxx: BUG: Initialize variable
-
-2005-07-20 12:02 andy
-
- * Source/kwsys/: CMakeLists.txt, testhash.cxx: ENH: Rename test
-
-2005-07-20 10:16 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-19 18:05 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: make it so that bootstrap
- does not use xml parser
-
-2005-07-19 17:16 hoffman
-
- * Source/: cmake.cxx, cmake.h: ENH: fix for bug 1866, make -G,-D -C
- options allow for space between arg and value
-
-2005-07-19 16:40 hoffman
-
- * Source/: CMakeLists.txt, cmFileCommand.cxx,
- cmGlobalXCode21Generator.cxx, cmGlobalXCodeGenerator.cxx,
- cmGlobalXCodeGenerator.h: ENH: if Xcode21 is installed then
- create 21 compatible project files
-
-2005-07-19 15:28 hoffman
-
- * Source/: cmGlobalXCode21Generator.cxx,
- cmGlobalXCode21Generator.h: ENH: add new stub generator
-
-2005-07-19 15:27 hoffman
-
- * Source/cmTryCompileCommand.h: ENH: add more docs
-
-2005-07-19 14:36 hoffman
-
- * Modules/CMakeGenericSystem.cmake: ENH: make KDevelop3 default to
- CMAKE_VERBOSE_MAKEFILE
-
-2005-07-19 11:48 hoffman
-
- * Modules/CMakeGenericSystem.cmake: ENH: make KDevelop3 default to
- CMAKE_VERBOSE_MAKEFILE
-
-2005-07-19 10:10 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-18 12:53 andy
-
- * Source/: cmCTest.cxx, cmCTest.h, ctest.cxx,
- CTest/cmCTestSubmitCommand.cxx, CTest/cmCTestSubmitHandler.cxx:
- ENH: Add a way to submit extra files to the dashboard
-
-2005-07-18 11:46 andy
-
- * Modules/Dart.cmake, Source/cmCTest.cxx, Source/cmCTest.h,
- Source/ctest.cxx, Tests/CTestTest2/test.cmake.in: ENH: Several
- improvements and cleanups: 1. Add long command line arguments for
- every argument 2. Add a way to overwrite CTest configuration by
- providing --overwrite TimeOut=10 3. Improve argument parsing. 4.
- Add submit index argument
-
-2005-07-18 11:32 andy
-
- * Source/CTest/cmCTestGenericHandler.cxx: ENH: Cleanup file name
-
-2005-07-18 11:32 andy
-
- * Source/cmDocumentation.cxx: ENH: Cleanup the help a bit
-
-2005-07-18 08:47 hoffman
-
- * Modules/FindQt.cmake: ENH: fix qt bug
-
-2005-07-18 03:18 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-17 03:14 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-16 03:16 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-15 15:20 hoffman
-
- * Source/cmGlobalXCodeGenerator.h: ENH: fix bug 1960
-
-2005-07-15 13:24 hoffman
-
- * Source/cmAddTestCommand.h: BUG: fix for bug 1838
-
-2005-07-15 12:57 hoffman
-
- * Modules/FindGLUT.cmake: BUG: fix for bug 852
-
-2005-07-15 12:39 hoffman
-
- * Modules/: FindQt.cmake: ENH: fix hard coded include from patch
-
-2005-07-15 12:14 hoffman
-
- * Modules/: FindQt.cmake, FindQt3.cmake, FindQt4.cmake: ENH: add
- new qt stuff from warfield@bwh.harvard.edu, thanks
-
-2005-07-15 12:01 martink
-
- * Utilities/CMakeLists.txt: BUG: converted to 1.8 form of custom
- commands
-
-2005-07-15 11:48 andy
-
- * Modules/FindPythonInterp.cmake: ENH: Add registry for 2.4
-
-2005-07-15 11:45 andy
-
- * Modules/FindPythonInterp.cmake: BUG: Set PYTHONINTERP_FOUND
-
-2005-07-15 11:38 hoffman
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h: ENH: fix static build of vtk
- with cmake by having custom targets chain depend information
-
-2005-07-15 11:37 hoffman
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: remove commented
- code
-
-2005-07-15 11:36 hoffman
-
- * Source/CMakeLists.txt: ENH: remove messages about not running
- java test
-
-2005-07-15 11:34 hoffman
-
- * Source/cmDynamicLoader.cxx: ENH: fix compile error bug# 2020 on
- mac
-
-2005-07-15 08:36 andy
-
- * Modules/FindPythonInterp.cmake: ENH: Initial import
-
-2005-07-15 03:11 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-14 16:00 hoffman
-
- * Source/cmLocalGenerator.cxx: ENH: fix for bug 992, mac bundle
- install fix
-
-2005-07-14 15:12 hoffman
-
- * Source/cmMakefile.cxx: BUG: fix for bug 1850 wrapping can leave
- out files if they are a substring of another file
-
-2005-07-14 14:15 andy
-
- * Source/CTest/cmCTestCoverageHandler.cxx: ENH: Some more cleanups
- and add ctest custom vector for regular expression to exclude
- from coverage
-
-2005-07-14 14:15 andy
-
- * Source/cmCTest.cxx: BUG: Look for custom files in all directories
-
-2005-07-14 13:50 hoffman
-
- * Tests/OutOfSource/OutOfSourceSubdir/: testlib.cxx, testlib.h:
- ENH: add missing files
-
-2005-07-14 13:25 andy
-
- * Source/CTest/: cmCTestCoverageHandler.cxx,
- cmCTestCoverageHandler.h: ENH: Add custom supression regular
- expressions
-
-2005-07-14 12:21 hoffman
-
- * Source/cmLocalUnixMakefileGenerator3.cxx,
- Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt,
- Tests/OutOfSource/OutOfSourceSubdir/simple.cxx: FIX: fix bug
- 2043 borland compiler and dll problem and add a test for it
-
-2005-07-14 11:24 andy
-
- * Source/CTest/cmCTestCoverageHandler.cxx: BUG: Fix line number
- inconsistency, improve output
-
-2005-07-14 10:15 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: add support for
- borland exe with shared libs back in
-
-2005-07-14 09:44 andy
-
- * Tests/: Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/complex.cxx: ENH: Do 4 files
-
-2005-07-14 09:30 andy
-
- * Tests/: Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/complex.cxx: ENH: Add a test for
- cmGeneratedFileStream
-
-2005-07-14 09:29 andy
-
- * Source/CTest/cmCTestTestCommand.cxx: COMP: Remove warning and fix
- the logic
-
-2005-07-14 09:29 andy
-
- * Source/CTest/cmCTestCoverageHandler.cxx: BUG: Rename tmp files
-
-2005-07-14 03:13 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-13 16:57 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: remove part of
- patch from bug 1965 that set executable paths
-
-2005-07-13 16:49 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx: BUG: revert part of
- patch that set executable debug prefix as it breaks too much
- stuff
-
-2005-07-13 16:24 hoffman
-
- * Source/cmLocalGenerator.cxx: ENH: add -L as possible library flag
-
-2005-07-13 16:23 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: add support for bundles
-
-2005-07-13 16:20 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx: BUG: try to fix failed
- test
-
-2005-07-13 15:49 hoffman
-
- * Source/CMakeLists.txt: ENH: add bundle test
-
-2005-07-13 15:43 hoffman
-
- * Tests/BundleTest/: BundleTest.cxx, CMakeLists.txt: ENH: add a
- bundle test
-
-2005-07-13 11:21 hoffman
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio6Generator.h,
- cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h, cmMakefile.cxx, cmMakefile.h,
- cmSourceGroup.cxx, cmSourceGroup.h, cmSourceGroupCommand.cxx:
- FIX: apply patch from bug# 1965
-
-2005-07-13 10:17 andy
-
- * Source/: cmCTest.h, CTest/cmCTestTestCommand.cxx: ENH: Add
- timeout support
-
-2005-07-13 09:49 andy
-
- * Source/kwsys/SystemTools.cxx: COMP: Remove warning on windows
-
-2005-07-13 09:08 hoffman
-
- * Modules/FindDoxygen.cmake: ENH: fix for darwin from eric wing
-
-2005-07-13 09:06 hoffman
-
- * Modules/: FindOpenAL.cmake, FindPhysFS.cmake, FindSDL.cmake,
- FindSDL_image.cmake, FindSDL_mixer.cmake, FindSDL_net.cmake,
- FindSDL_ttf.cmake: ENH: add a bunch of find sdl stuff from eric
- wing
-
-2005-07-13 08:29 hoffman
-
- * Modules/Platform/: CYGWIN-g77.cmake, IRIX64.cmake, g77.cmake:
- FIX: for 1852 fix fortran case
-
-2005-07-13 03:10 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-12 17:30 hoffman
-
- * ChangeLog.manual, Source/kwsys/SystemTools.cxx,
- Source/kwsys/SystemTools.hxx.in: merge from main tree
-
-2005-07-12 17:24 hoffman
-
- * CMakeSystemConfig.txt.in, CMakeWindowsSystemConfig.txt: ENH:
- remove unused files
-
-2005-07-12 17:24 hoffman
-
- * Source/cmCPluginAPI.h: ENH: change version
-
-2005-07-12 17:23 hoffman
-
- * Utilities/cmcurl/CMakeLists.txt: add -dl on unix
-
-2005-07-12 17:22 hoffman
-
- * Utilities/Release/: cmake_release.sh, config_Darwin,
- config_HP-UX, config_SunOS, release_dispatch.sh: move release
- stuff off branch
-
-2005-07-12 16:56 hoffman
-
- * ChangeLog.txt: update changes
-
-2005-07-12 16:51 hoffman
-
- * ChangeLog.txt: ENH: update changes for 2.2
-
-2005-07-12 15:40 hoffman
-
- * Utilities/Release/config_Darwin: [no log message]
-
-2005-07-12 15:26 hoffman
-
- * Utilities/Release/config_Darwin: [no log message]
-
-2005-07-12 15:11 hoffman
-
- * Utilities/Release/: config_Darwin, release_dispatch.sh: fixes for
- osx
-
-2005-07-12 13:54 hoffman
-
- * Utilities/Release/config_SunOS: put it back
-
-2005-07-12 13:21 andy
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: BUG: Revert
- the change to FileIsDirectory. Add FileIsSymlink and treat
- symlinks as files when removing directory
-
-2005-07-12 12:40 hoffman
-
- * Utilities/cmcurl/CMakeLists.txt: [no log message]
-
-2005-07-12 12:31 andy
-
- * Source/CTest/cmCTestTestHandler.cxx: BUG: Go back to the original
- directory after examining the current directory
-
-2005-07-12 12:30 andy
-
- * Source/CTest/cmCTestTestHandler.cxx: BUG: Make sure it always
- starts in the current directory when searching for tests
-
-2005-07-12 10:39 andy
-
- * Source/: kwsys/SystemTools.cxx,
- CTest/cmCTestEmptyBinaryDirectoryCommand.cxx: BUG: When removing
- directory, use lstat instead of stat to make sure that symlinks
- are treated as files and not as directories
-
-2005-07-12 10:25 hoffman
-
- * Utilities/Release/config_SunOS: [no log message]
-
-2005-07-12 10:08 hoffman
-
- * Utilities/Release/config_SunOS: [no log message]
-
-2005-07-12 09:36 hoffman
-
- * Utilities/Release/config_HP-UX: use gmake
-
-2005-07-12 08:50 andy
-
- * Source/cmCTest.cxx: BUG: Fix problem with visual studio in
- release mode
-
-2005-07-12 03:10 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-11 18:07 hoffman
-
- * Source/CursesDialog/form/CMakeLists.txt: ENH: fix from main tree
-
-2005-07-11 18:07 hoffman
-
- * Source/CursesDialog/form/CMakeLists.txt: ENH: add curses include
- directory
-
-2005-07-11 17:58 hoffman
-
- * Utilities/Release/config_Darwin: turn off wx dialog for now
-
-2005-07-11 17:15 hoffman
-
- * Utilities/Release/cmake_release.sh: get the correct version
-
-2005-07-11 17:11 hoffman
-
- * Utilities/Release/: cmake_release.sh, cmake_release.sh.in,
- config_CYGWIN_NT-5.1, config_IRIX64, config_Linux,
- cygwin-package.sh.in, release_dispatch.sh, README: ENH: merge
- changes from branches
-
-2005-07-11 16:57 hoffman
-
- * Utilities/Release/release_dispatch.sh: [no log message]
-
-2005-07-11 16:09 hoffman
-
- * Utilities/Release/: cmake_release.sh, cmake_release.sh.in,
- config_CYGWIN_NT-5.1, config_IRIX64, cygwin-package.sh.in,
- release_dispatch.sh: move stuff from 2.0 over to 2.2
-
-2005-07-11 15:21 hoffman
-
- * Utilities/Release/config_Linux: move config linix to 2.2 branch
-
-2005-07-11 15:11 hoffman
-
- * Utilities/Release/release_dispatch.sh: change to muse
-
-2005-07-11 15:05 hoffman
-
- * Utilities/Release/release_dispatch.sh: ENH: add from HEAD
-
-2005-07-11 15:04 hoffman
-
- * Utilities/Release/release_dispatch.sh: add from branch
-
-2005-07-11 14:55 martink
-
- * ChangeLog.manual: ENH: commit some change logs
-
-2005-07-11 14:54 hoffman
-
- * Source/cmCPluginAPI.h, Utilities/Release/cmake_release.sh,
- Utilities/Release/cmake_release.sh.in: ENH: fix up some version
- stuff
-
-2005-07-11 12:22 martink
-
- * Source/CTest/cmCTestUpdateHandler.cxx: ENH: provide default
- update options if none were provided
-
-2005-07-11 11:59 andy
-
- * Source/CTest/cmCTestUpdateHandler.cxx: ENH: Add default update
- options
-
-2005-07-11 11:37 martink
-
- * ChangeLog.manual: ENH: added ChangeLog as in prior release
-
-2005-07-11 11:36 martink
-
- * Source/cmAddCustomCommandCommand.cxx: ENH: merge from the main
- tree to handle relative files
-
-2005-07-11 11:31 martink
-
- * Source/CTest/cmCTestUpdateHandler.cxx: ENH: merged from CVS fix
- for SNV warning
-
-2005-07-11 11:16 andy
-
- * Source/CTest/cmCTestUpdateHandler.cxx: BUG: Remove warning when
- using CVS
-
-2005-07-11 03:07 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-10 03:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-09 03:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-08 11:51 martink
-
- * Source/cmAddCustomCommandCommand.cxx: ENH: slightly modified
- version of Alex's relative path arguments for custom commands
-
-2005-07-08 10:13 martink
-
- * Utilities/Release/cmake_release.sh: ENH: release commit
-
-2005-07-08 10:00 martink
-
- * CMakeLists.txt: ENH: rev to 22
-
-2005-07-08 09:55 martink
-
- * CMakeLists.txt: ENH: update rev to 23
-
-2005-07-08 09:05 king
-
- * Source/kwsys/testProcess.c: COMP: Fixed uninitialized variable.
-
-2005-07-08 03:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-07 16:01 martink
-
- * Source/cmConfigureFileCommand.cxx: ENH: configure file will
- assume start source dir if a full path is not provided
-
-2005-07-07 15:06 martink
-
- * Source/cmMakefile.cxx: BUG: library return values were not UNIX
- slashes on Win98
-
-2005-07-07 13:55 martink
-
- * Source/cmSourceFile.cxx: BUG: mor emissing convert to unix
- slashes
-
-2005-07-07 11:44 martink
-
- * Source/: cmMakefile.cxx, cmMakefile.h: ENH: cleaned up some old
- methods and vars
-
-2005-07-07 10:21 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: Removing
- CMAKE_HIDE_TARGET_DIRS since it has been superceded by
- CMAKE_TARGET_DIR_PREFIX.
-
-2005-07-07 10:14 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: Added use of
- CMAKE_TARGET_DIR_PREFIX variable to prepend a project-specified
- string to the names of all the target-name.dir directories.
-
-2005-07-07 10:11 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: added ability to
- prefix target directories with a . to make them not show up in
- ls. From patch from Alex
-
-2005-07-07 09:44 martink
-
- * Source/cmake.cxx: BUG: win95 returning non unix path for cmake
- command
-
-2005-07-07 09:06 king
-
- * Source/kwsys/testProcess.c: ENH: Extended test 0 to run the
- executable twice using the same process object. This tests the
- reusability of the objects.
-
-2005-07-07 09:05 king
-
- * Source/kwsys/ProcessWin32.c: BUG: Fixed reusability of process
- object by clearing each pipe's Closed flag when cleaning up.
-
-2005-07-07 03:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-06 16:16 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: BUG: fix for bootstrap problem
-
-2005-07-06 15:51 andy
-
- * Source/: cmCacheManager.cxx, cmFileCommand.cxx,
- cmWriteFileCommand.cxx: STYLE: Fix typos
-
-2005-07-06 15:49 andy
-
- * Source/CTest/cmCTestCoverageHandler.cxx: COMP: Remove warning
-
-2005-07-06 15:27 andy
-
- * Source/CTest/: cmCTestCoverageHandler.cxx,
- cmCTestCoverageHandler.h: ENH: Improve support for various
- versions of gcov
-
-2005-07-06 15:25 andy
-
- * Modules/FindFLTK.cmake: ENH: Replace with the one from InsightApp
-
-2005-07-06 15:25 martink
-
- * Source/cmListFileCache.cxx: BUG: project command should also work
- with lower case
-
-2005-07-06 15:24 martink
-
- * Tests/Simple/CMakeLists.txt: BUG: minor fix to project name to
- match ADD_TEST call
-
-2005-07-06 15:11 andy
-
- * Source/CTest/cmCTestSubmitHandler.cxx: BUG: On windows there can
- be a problem because scp does not handle drive names. This uses
- relative path for scp
-
-2005-07-06 03:10 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-05 16:13 martink
-
- * Utilities/Release/: MakeRelease.cmake.in, Release.cmake: ENH: a
- start on UNIX release
-
-2005-07-05 15:43 martink
-
- * Utilities/Release/Release.cmake: ENH: better release support
-
-2005-07-05 12:38 martink
-
- * Utilities/Release/: MakeRelease.cmake.in, Release.cmake: ENH:
- better release support
-
-2005-07-05 11:17 andy
-
- * Modules/FindDCMTK.cmake: ENH: Improvements by Julien
-
-2005-07-05 10:08 martink
-
- * Source/cmMacroCommand.cxx: ENH: revert back to string replacement
- version
-
-2005-07-05 09:21 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: util targets now
- show up in locla makefile and make rebuild_cache now works in
- subdirs
-
-2005-07-05 09:00 martink
-
- * Source/cmLocalGenerator.cxx: BUG: fix for debug optimized link
- libraries
-
-2005-07-05 03:02 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-04 03:01 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-03 12:06 andy
-
- * Source/cmake.cxx: ENH: Only truncate files when not in try
- compile. Alsom move truncating code closer to configure
-
-2005-07-03 03:02 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-02 22:50 andy
-
- * Source/cmCTest.cxx: ENH: Improve performance of MakeXMLSafe,
- improve performance of reading custom ctest files, and remove
- error when running ctest on directory without
- DartConfiguration.tcl
-
-2005-07-02 22:32 andy
-
- * Source/CTest/cmCTestCoverageHandler.cxx: STYLE: Unify number of
- spaces
-
-2005-07-02 22:31 andy
-
- * Source/CTest/cmCTestBuildHandler.cxx: ENH: Improve performance by
- compiling regular expressions when needed
-
-2005-07-02 22:30 andy
-
- * Source/CTest/: cmCTestTestHandler.cxx, cmCTestTestHandler.h: ENH:
- Improve performance of testing and do not complain if
- DartTestfile.txt is not found or if directory does not exist
-
-2005-07-02 22:25 andy
-
- * Source/: cmake.cxx, cmake.h: ENH: Start adding the code that will
- truncate output logs
-
-2005-07-02 01:25 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-07-01 10:57 martink
-
- * Source/: cmGetTargetPropertyCommand.h, cmTarget.cxx: ENH: added
- Alexander's target property TYPE
-
-2005-07-01 10:23 martink
-
- * Source/: cmGetDirectoryPropertyCommand.cxx,
- cmGetDirectoryPropertyCommand.h: ENH: added patch from Alexander
- Neundorf to get DEFINITIONS
-
-2005-06-30 13:39 martink
-
- * Tests/: Complex/CMakeLists.txt, Complex/cmTestConfigure.h.in,
- Complex/Executable/complex.cxx, ComplexOneConfig/CMakeLists.txt,
- ComplexOneConfig/cmTestConfigure.h.in,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/CMakeLists.txt,
- ComplexRelativePaths/cmTestConfigure.h.in,
- ComplexRelativePaths/Executable/complex.cxx: ENH: added testing
- of the WHILE command
-
-2005-06-30 13:39 martink
-
- * Docs/cmake-mode.el: ENH: added while command
-
-2005-06-30 13:27 martink
-
- * Docs/cmake-mode.el: ENH: added while command
-
-2005-06-30 13:09 martink
-
- * Utilities/Release/: CMake.nsi.in, MakeRelease.cmake.in,
- Release.cmake, Win32Release.sh.in: ENH: better release scripts
-
-2005-06-30 11:33 martink
-
- * Utilities/Release/Release.cmake: ENH: hard coded for VS 71 nmake
- for now
-
-2005-06-30 11:18 king
-
- * Modules/Platform/Windows-cl.cmake: BUG: Fixed escaped quote at
- end of .
-
-2005-06-30 09:53 martink
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: added local help and
- install targets
-
-2005-06-30 09:21 king
-
- * Source/kwsys/Base64.c: BUG: Do not increment optr by 2 after
- storing only one character. Also fixed possibility of storing
- uninitialized characters from the last triplet.
-
-2005-06-30 05:47 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-06-29 12:07 king
-
- * Modules/Platform/Windows-bcc32.cmake: BUG: Need to use the -c
- option for implib to produce case-sensitive symbols in the .lib
- files.
-
-2005-06-29 08:46 martink
-
- * CTestCustom.ctest.in: COMP: shut up warning
-
-2005-06-29 05:49 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-06-28 15:00 martink
-
- * Utilities/Release/: CMake.nsi.in, CMakeInstall.bmp: ENH: added
- our own bitmap
-
-2005-06-28 10:55 martink
-
- * Utilities/Release/CMake.nsi.in,
- Utilities/Release/Win32Release.sh.in,
- Utilities/Release/cmake_release.sh.in,
- Utilities/Release/Release.cmake, CMakeLists.txt: ENH: added some
- release support
-
-2005-06-28 05:45 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-06-27 15:59 martink
-
- * Source/cmMakefile.cxx: BUG: dont pass unverified char * to
- streams
-
-2005-06-27 12:45 martink
-
- * Tests/Simple/CMakeLists.txt: ENH: convert to lower case
-
-2005-06-27 12:44 martink
-
- * Example/: CMakeLists.txt, Demo/CMakeLists.txt,
- Hello/CMakeLists.txt: ENH: updte to lower case and using
- ADD_SUBDIRECTORY
-
-2005-06-27 11:39 martink
-
- * CTestCustom.ctest.in: ENH: mods to warning excludes based on new
- locaiton of curl
-
-2005-06-27 05:50 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-06-26 05:43 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-06-25 05:44 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-06-24 13:29 andy
-
- * Source/CTest/cmCTestSubmitHandler.cxx: BUG: Exit properly on SCP
- submission
-
-2005-06-24 09:41 andy
-
- * Source/CTest/cmCTestSubmitHandler.cxx: COMP: Remove warnings
-
-2005-06-24 09:06 andy
-
- * CMakeLists.txt, Source/CMakeLists.txt, Source/cmCTest.cxx,
- Source/CTest/cmCTestSubmitHandler.cxx: ENH: Move curl to
- utilities
-
-2005-06-24 09:00 andy
-
- * Utilities/cmcurl/: amigaos.c, amigaos.h, arpa_telnet.h, base64.c,
- base64.h, ca-bundle.h, connect.c, connect.h, content_encoding.c,
- content_encoding.h, cookie.c, cookie.h, curl_memory.h, curlx.h,
- dict.c, dict.h, easy.c, escape.c, escape.h, file.c, file.h,
- formdata.c, formdata.h, ftp.c, ftp.h, getdate.c, getdate.h,
- getenv.c, getinfo.c, getinfo.h, hash.c, hash.h, hostares.c,
- hostasyn.c, hostip.c, hostip.h, hostip4.c, hostip6.c, hostsyn.c,
- hostthre.c, http.c, http.h, http_chunks.c, http_chunks.h,
- http_digest.c, http_digest.h, http_negotiate.c, http_negotiate.h,
- http_ntlm.c, http_ntlm.h, if2ip.c, if2ip.h, inet_ntoa_r.h,
- inet_ntop.c, inet_ntop.h, inet_pton.c, inet_pton.h, krb4.c,
- krb4.h, ldap.c, ldap.h, llist.c, llist.h, md5.c, md5.h,
- memdebug.c, memdebug.h, mprintf.c, multi.c, netrc.c, netrc.h,
- nwlib.c, progress.c, progress.h, security.c, security.h, sendf.c,
- sendf.h, setup.h, share.c, share.h, speedcheck.c, speedcheck.h,
- ssluse.c, ssluse.h, strequal.c, strequal.h, strerror.c,
- strerror.h, strtok.c, strtok.h, strtoofft.c, strtoofft.h,
- telnet.c, telnet.h, timeval.c, timeval.h, transfer.c, transfer.h,
- url.c, url.h, urldata.h, version.c, CMakeLists.txt, config.h.in,
- curl.copyright, CMake/CheckTypeSize.c.in,
- CMake/CheckTypeSize.cmake, CMake/CurlTests.c,
- Platforms/WindowsCache.cmake, Platforms/config-aix.h,
- Testing/CMakeLists.txt, Testing/curlgtk.c, Testing/curltest.c,
- Testing/ftpget.c, Testing/ftpgetresp.c, Testing/ftpupload.c,
- Testing/getinmemory.c, Testing/http-post.c, Testing/httpput.c,
- Testing/multithread.c, Testing/persistant.c, Testing/postit2.c,
- Testing/sepheaders.c, Testing/simple.c, Testing/simplessl.c,
- Testing/testconfig.h.in, Testing/win32sockets.c, curl/curl.h,
- curl/curlver.h, curl/easy.h, curl/mprintf.h, curl/multi.h,
- curl/stdcheaders.h, curl/types.h: ENH: Initial import
-
-2005-06-24 05:43 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-06-23 16:06 andy
-
- * Source/CTest/cmCTestSubmitHandler.cxx: ENH: Make iterators const
-
-2005-06-23 13:07 andy
-
- * Tests/CTestTest3/test.cmake.in: ENH: Perform second test if
- subversion exists
-
-2005-06-23 13:04 andy
-
- * Source/: CMakeLists.txt, cmCTest.cxx, cmCTest.h,
- CTest/cmCTestBuildAndTestHandler.cxx,
- CTest/cmCTestBuildCommand.cxx, CTest/cmCTestBuildHandler.cxx,
- CTest/cmCTestConfigureCommand.cxx,
- CTest/cmCTestConfigureHandler.cxx,
- CTest/cmCTestCoverageCommand.cxx,
- CTest/cmCTestCoverageHandler.cxx, CTest/cmCTestCoverageHandler.h,
- CTest/cmCTestGenericHandler.cxx, CTest/cmCTestGenericHandler.h,
- CTest/cmCTestHandlerCommand.cxx, CTest/cmCTestHandlerCommand.h,
- CTest/cmCTestMemCheckCommand.cxx, CTest/cmCTestMemCheckCommand.h,
- CTest/cmCTestScriptHandler.cxx, CTest/cmCTestStartCommand.cxx,
- CTest/cmCTestSubmitCommand.cxx, CTest/cmCTestSubmitHandler.cxx,
- CTest/cmCTestSubmitHandler.h, CTest/cmCTestTestCommand.cxx,
- CTest/cmCTestTestCommand.h, CTest/cmCTestTestHandler.cxx,
- CTest/cmCTestUpdateCommand.cxx, CTest/cmCTestUpdateHandler.cxx,
- kwsys/CTestConfig.cmake: ENH: Several improvements with the way
- things are handled. Also, support multiple submited files
-
-2005-06-23 12:34 martink
-
- * Source/cmMacroCommand.cxx: COMP: fix compiler warnings
-
-2005-06-23 11:03 martink
-
- * Source/: cmForEachCommand.cxx, cmIfCommand.cxx,
- cmMacroCommand.cxx, cmWhileCommand.cxx: ENH: converted macro to
- use variables and fixed some case issues with some function
- blockers
-
-2005-06-23 10:25 king
-
- * Source/kwsys/hashtable.hxx.in: ENH: Added some smaller primes to
- allow small hash table sizes and therefore shorter initial
- construction times.
-
-2005-06-23 05:57 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-06-22 14:20 martink
-
- * Source/cmForEachCommand.h: STYLE: updated the docs to be more
- accurate
-
-2005-06-22 14:16 martink
-
- * Source/cmForEachCommand.cxx: COMP: fix possible poroblem with
- freed memory
-
-2005-06-22 14:04 martink
-
- * Source/cmForEachCommand.cxx: COMP: fix unused variable
-
-2005-06-22 13:32 martink
-
- * Source/cmForEachCommand.cxx: ENH: changed FOREACH to use
- variables instead of string replacement
-
-2005-06-22 10:54 andy
-
- * Source/CTest/cmCTestTestHandler.cxx: BUG: Fix displaying of
- percentage
-
-2005-06-22 10:09 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: clean rule wasn't
- cleaning libs and executables
-
-2005-06-22 09:12 martink
-
- * Source/cmTarget.cxx: ENH: some better checks
-
-2005-06-22 09:06 martink
-
- * Source/: cmExportLibraryDependencies.cxx, cmGlobalGenerator.cxx,
- cmGlobalKdevelopGenerator.cxx,
- cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio6Generator.h,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio71Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h, cmLocalGenerator.cxx,
- cmLocalGenerator.h, cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio6Generator.h,
- cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h, cmMakeDepend.cxx,
- cmMakeDepend.h, cmMakefile.cxx, cmMakefile.h,
- cmOrderLinkDirectories.cxx, cmOrderLinkDirectories.h,
- cmTarget.cxx, cmTarget.h: ENH: make LOCATION an computed property
- of the target and get rid of a bunch of const junk
-
-2005-06-22 05:43 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-06-21 16:44 andy
-
- * Source/cmCommandArgumentParserHelper.cxx: ENH: Remove stray abort
-
-2005-06-21 16:29 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.cxx: ENH: fix for BSD makes no
- longer use dir name as a target
-
-2005-06-21 14:20 king
-
- * Source/cmTryRunCommand.cxx: BUG: Fixed error message formatting
- when try run executable command cannot be found.
-
-2005-06-21 11:01 andy
-
- * Source/cmCommandArgumentParserHelper.cxx: BUG: Fix escaping to
- make OSX work again
-
-2005-06-21 10:33 king
-
- * Source/kwsys/testProcess.c: BUG: Use sleep(1) instead of
- usleep(1000000) because some UNIX systems specify that the
- argument to usleep must be less than 1000000.
-
-2005-06-21 09:34 martink
-
- * Source/: cmCustomCommand.cxx, cmCustomCommand.h,
- cmLocalUnixMakefileGenerator3.cxx: ENH: add test to make sure
- custom commands are used
-
-2005-06-21 05:56 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-06-20 17:57 andy
-
- * Source/cmCTest.cxx: ENH: Initialize handler before processing it
-
-2005-06-20 17:37 andy
-
- * Source/CursesDialog/.NoDartCoverage: ENH: Until there is some
- test for curses dialog, no need to do coverage
-
-2005-06-20 16:31 martink
-
- * Modules/: Dart.cmake, TestCXXAcceptsFlag.cmake,
- Platform/Darwin.cmake: ENH: fixed some spelling errors
-
-2005-06-20 16:24 martink
-
- * Source/cmMakefile.cxx: BUG: goof in new feature fixed
-
-2005-06-20 14:15 martink
-
- * Source/: cmLocalUnixMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator.h: ENH: removed unused files
-
-2005-06-20 14:00 martink
-
- * Docs/CMake04.rtf, Source/cmGetTargetPropertyCommand.cxx,
- Source/cmGetTargetPropertyCommand.h, Source/cmGlobalGenerator.h,
- Source/cmMakefile.cxx: ENH: modified GET_TARGET_PROPERTIES to
- work with all targets
-
-2005-06-20 13:49 barre
-
- * Source/kwsys/testSystemTools.cxx: ENH: fix test, it has to return
- a true/false value otherwise it just passes the test, and add
- test for EscapeChars
-
-2005-06-20 13:10 martink
-
- * Modules/: TestBigEndian.cmake, UseSWIG.cmake: BUG: fix some
- missing quotes for STREQUAL IF statements
-
-2005-06-20 12:55 martink
-
- * Modules/CMakeGenericSystem.cmake: ENH: adde dback in
- CMAKE_VERBOSE_MAKEFILE that was acc removed
-
-2005-06-20 11:54 king
-
- * Source/cmSetTargetPropertiesCommand.h: ENH: Added documentation
- of VERSION and SOVERSION properties.
-
-2005-06-20 11:53 martink
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h,
- cmGlobalUnixMakefileGenerator.cxx,
- cmGlobalUnixMakefileGenerator.h: ENH: no longer used
-
-2005-06-20 11:49 martink
-
- * Tests/COnly/CMakeLists.txt: COMP: converted to lowercase commands
-
-2005-06-20 11:47 martink
-
- * Docs/cmake-mode.el: ENH: updated emacs mode to include lowercase
- commands and missing command ENDMACRO
-
-2005-06-20 08:59 martink
-
- * Source/CTest/cmCTestTestHandler.cxx: COMP: see about fixing
- warning
-
-2005-06-20 07:42 andy
-
- * Tests/CTestTest3/test.cmake.in: ENH: Skip svn test for now
-
-2005-06-20 05:50 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-06-19 06:51 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-06-18 05:28 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-06-17 23:15 andy
-
- * Source/CMakeLists.txt: COMP: Fix problems with old cmake
-
-2005-06-17 15:50 andy
-
- * Source/: cmCommandArgumentLexer.cxx, cmCommandArgumentLexer.in.l,
- cmCommandArgumentParserHelper.cxx,
- cmCommandArgumentParserHelper.h, cmListFileCache.cxx,
- cmMakefile.cxx, cmMakefile.h: ENH: Improve handling of escaped
- characters
-
-2005-06-17 15:44 andy
-
- * Source/CMakeLists.txt: ENH: Pass ctest config type to
- subprocesses
-
-2005-06-17 15:43 andy
-
- * Source/CTest/cmCTestTestHandler.cxx: ENH: Pass configuration type
- to subprocesses
-
-2005-06-17 14:13 king
-
- * Source/kwsys/CMakeLists.txt: ENH: Enabling new test 7 of process
- execution.
-
-2005-06-17 14:07 king
-
- * Source/kwsys/Process.h.in: ENH: Added polling feature to
- documentation of WaitForData.
-
-2005-06-17 14:05 king
-
- * Source/kwsys/ProcessWin32.c: BUG: Fixed polling feature of
- WaitForData.
-
-2005-06-17 13:59 king
-
- * Source/kwsys/testProcess.c: ENH: Added test 7 to expose problems
- with polling by WaitForData.
-
-2005-06-17 13:57 king
-
- * Source/kwsys/ProcessUNIX.c: BUG: Fixed polling capability of
- WaitForData.
-
-2005-06-17 13:14 andy
-
- * Tests/CTestTest3/test.cmake.in: ENH: Make CVS one nightly
-
-2005-06-17 13:07 andy
-
- * Tests/CTestTest3/test.cmake.in: ENH: Add subversion test
-
-2005-06-17 13:04 andy
-
- * Source/: cmCTest.cxx, cmCTest.h, cmCommand.h, cmObject.h,
- cmStandardIncludes.h, CTest/cmCTestBuildAndTestHandler.cxx,
- CTest/cmCTestBuildAndTestHandler.h,
- CTest/cmCTestBuildHandler.cxx, CTest/cmCTestBuildHandler.h,
- CTest/cmCTestConfigureHandler.cxx,
- CTest/cmCTestConfigureHandler.h,
- CTest/cmCTestCoverageHandler.cxx, CTest/cmCTestCoverageHandler.h,
- CTest/cmCTestGenericHandler.h, CTest/cmCTestMemCheckHandler.cxx,
- CTest/cmCTestMemCheckHandler.h, CTest/cmCTestScriptHandler.cxx,
- CTest/cmCTestScriptHandler.h, CTest/cmCTestStartCommand.cxx,
- CTest/cmCTestSubmitHandler.cxx, CTest/cmCTestSubmitHandler.h,
- CTest/cmCTestTestHandler.cxx, CTest/cmCTestTestHandler.h,
- CTest/cmCTestUpdateCommand.cxx, CTest/cmCTestUpdateHandler.cxx,
- CTest/cmCTestUpdateHandler.h: ENH: Add superclass for all
- commands and handlers. Improve handlers to have initialization
- code, and start initializing ctest when start is invoked
-
-2005-06-17 11:46 malaterre
-
- * Source/kwsys/CommandLineArguments.hxx.in: ENH: Fix Bug #1950,
- provide a direct access to the input. Minor cleanup (convenience)
-
-2005-06-17 09:49 king
-
- * Source/: cmCMakeMinimumRequired.cxx, cmMakefile.h, cmVersion.h:
- ENH: Enabling ability for CMAKE_MINIMUM_REQUIRED version to
- include patch level. Submitted by Alexander Neundorf.
-
-2005-06-17 08:45 andy
-
- * Tests/MacroTest/CMakeLists.txt: ENH: Fix test on HP
-
-2005-06-17 05:50 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-06-16 16:42 andy
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: When running the same
- ctest as the one we are testing, make sure to run as separate
- process
-
-2005-06-16 16:33 andy
-
- * Source/: cmMakefile.cxx, cmMakefile.h: ENH: Add extra argument
-
-2005-06-16 16:24 andy
-
- * Source/cmCTest.cxx, Tests/CTestTest3/test.cmake.in: ENH: Return
- error if there is an ERROR_MESSAGE. Also fix tag for the test
-
-2005-06-16 15:44 andy
-
- * Source/cmCommand.h: COMP: Fix build error on Windows
-
-2005-06-16 14:56 andy
-
- * Source/CMakeLists.txt, Tests/MacroTest/CMakeLists.txt,
- Tests/MacroTest/macroTest.c: ENH: Add test of macro
-
-2005-06-16 14:56 andy
-
- * Source/: cmake.cxx, cmake.h: ENH: Before running configre, remove
- all macros. Also, backup the command names. Also, make command
- names case insensitive
-
-2005-06-16 14:05 andy
-
- * Source/: cmCommand.h, cmConfigureFileCommand.h,
- cmFLTKWrapUICommand.h, cmQTWrapCPPCommand.h, cmQTWrapUICommand.h,
- cmUseMangledMesaCommand.h, cmVTKWrapJavaCommand.h,
- cmVTKWrapPythonCommand.h, cmVTKWrapTclCommand.h: ENH: Add
- classname to commands
-
-2005-06-16 13:29 andy
-
- * Tests/CTestTest3/test.cmake.in: ENH: Initial import
-
-2005-06-16 13:18 andy
-
- * Source/CMakeLists.txt, Source/cmCTest.cxx, Source/cmCTest.h,
- Source/CTest/cmCTestBuildCommand.cxx,
- Source/CTest/cmCTestCommand.h,
- Source/CTest/cmCTestGenericHandler.h,
- Source/CTest/cmCTestStartCommand.cxx,
- Source/CTest/cmCTestSubmitCommand.cxx,
- Source/CTest/cmCTestSubmitHandler.cxx,
- Source/CTest/cmCTestUpdateCommand.cxx,
- Source/CTest/cmCTestUpdateHandler.cxx,
- Tests/CTestTest2/test.cmake.in: ENH: Several improvements to
- CTest:
-
- 1. Support for showing line numbers when debugging ctest
- --show-line-numbers 2. Modify the ctest initialization code, so
- that it can be delayed 3. Handlers now have corresponding command
- if they were invoked from the command (so far only update
- actually use that) 4. Start command is simplified and the
- functionality is moved to CTest 5. Update can perform initial
- checkout if CTEST_CHECKOUT_COMMAND is set 6. Add test that checks
- out kwsys and perform tests on the fresh checkout
-
-2005-06-16 11:52 martink
-
- * Source/CMakeLists.txt: ENH: add first cut at support for exe with
- same name as lib
-
-2005-06-16 11:48 martink
-
- * Source/: cmSetTargetPropertiesCommand.h,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx,
- cmLocalUnixMakefileGenerator3.cxx: ENH: add first cut at support
- for exe with same name as lib
-
-2005-06-16 11:47 martink
-
- * Tests/SameName/: CMakeLists.txt, Exe1/CMakeLists.txt,
- Exe1/conly.c, Lib1/CMakeLists.txt, Lib1/libc1.c, Lib1/libc1.h:
- ENH: add same name test
-
-2005-06-16 10:23 martink
-
- * Source/cmITKWrapTclCommand.cxx: ENH: replace brackets with more
- generic find
-
-2005-06-16 10:22 martink
-
- * Source/cmOrderLinkDirectories.cxx: ENH: make more specific in
- reject self linking
-
-2005-06-16 05:50 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-06-15 15:51 andy
-
- * Source/cmCommand.h: ENH: Add accessor for Makefile and make
- SetError public
-
-2005-06-15 15:29 hoffman
-
- * CTestConfig.cmake: ENH: add for testing
-
-2005-06-15 10:54 andy
-
- * Tests/CTestTest2/test.cmake.in: BUG: Fix typo
-
-2005-06-15 10:53 andy
-
- * Source/CTest/: cmCTestMemCheckCommand.cxx,
- cmCTestMemCheckHandler.cxx: ENH: Pass in memcheck command options
- and suppresions, and change skin to tool
-
-2005-06-15 10:53 andy
-
- * Source/CTest/cmCTestCoverageCommand.cxx: ENH: Handle passing in
- coverage command
-
-2005-06-15 08:54 andy
-
- * Source/CMakeLists.txt: ENH: Add logging to improve coverage
-
-2005-06-15 05:42 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-06-14 15:53 andy
-
- * Utilities/.NoDartCoverage: ENH: No need to do coverage of
- utilities
-
-2005-06-14 15:49 andy
-
- * Source/: cmCommandArgumentParserHelper.cxx,
- cmCommandArgumentParserHelper.h: ENH: More cleanups
-
-2005-06-14 14:01 andy
-
- * Tests/CTestTest2/test.cmake.in: ENH: Also perform memory checking
- and coverage
-
-2005-06-14 14:00 andy
-
- * Source/: CMakeLists.txt, CTest/cmCTestCoverageCommand.cxx,
- CTest/cmCTestCoverageCommand.h, CTest/cmCTestMemCheckCommand.cxx,
- CTest/cmCTestMemCheckCommand.h, CTest/cmCTestScriptHandler.cxx:
- ENH: Add commands for memory checking and coverage
-
-2005-06-14 13:22 andy
-
- * Source/: cmCommandArgumentLexer.cxx, cmCommandArgumentLexer.in.l:
- ENH: Improve variable name regular expression
-
-2005-06-14 12:48 andy
-
- * Source/: cmMacroCommand.cxx, cmake.cxx, cmake.h: ENH: Save
- command that macro overwrites
-
-2005-06-14 11:42 andy
-
- * Source/: cmCTest.cxx, cmCTest.h,
- CTest/cmCTestCoverageHandler.cxx, CTest/cmCTestUpdateHandler.cxx:
- ENH: Separate standard output and standard error for problematic
- commands
-
-2005-06-14 03:02 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-06-13 18:03 barre
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH: add
- method to escape some chars in a string
-
-2005-06-13 14:29 andy
-
- * Source/cmCommandArgumentParserHelper.cxx: ENH: Handle
- non-existing variables
-
-2005-06-13 11:00 andy
-
- * bootstrap, Source/CMakeLists.txt, Source/cmMakefile.cxx: ENH: Use
- the new parser that supports nested variables
-
-2005-06-13 10:27 andy
-
- * Source/: cmCommandArgumentParser.cxx, cmCommandArgumentParser.y:
- ENH: More cleanups
-
-2005-06-13 10:11 andy
-
- * Source/: cmCommandArgumentParserHelper.cxx,
- cmCommandArgumentParserHelper.h: ENH: More optimization
-
-2005-06-13 10:01 andy
-
- * Source/: cmCommandArgumentLexer.cxx, cmCommandArgumentLexer.h,
- cmCommandArgumentParser.cxx, cmCommandArgumentParserTokens.h:
- ENH: Initial import
-
-2005-06-13 10:00 andy
-
- * Source/: cmCommandArgumentParserHelper.cxx,
- cmCommandArgumentParserHelper.h: ENH: Handle errors and optimize
- a bit
-
-2005-06-13 10:00 andy
-
- * Source/cmCommandArgumentLexer.in.l: ENH: Remove some allocations
-
-2005-06-13 09:59 andy
-
- * Source/cmCommandArgumentParser.y: ENH: Rearange and cleanup
-
-2005-06-13 09:33 martink
-
- * Source/: cmConfigureFileCommand.cxx, cmConfigureFileCommand.h:
- ENH: made configure file immediate by default for 2.2 or later
-
-2005-06-12 03:07 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-06-11 03:07 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-06-10 11:27 martink
-
- * Source/cmMakefile.cxx: ENH: remove old 1.2 compatability from
- cmake 2.2
-
-2005-06-10 10:45 martink
-
- * Source/cmMakefile.cxx: ENH: remove old 1.2 compatability from
- cmake 2.2
-
-2005-06-10 10:44 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h, cmake.cxx, cmake.h,
- cmLocalGenerator.h: ENH: added support for forcing recomputation
- of depends
-
-2005-06-10 10:09 martink
-
- * Tests/Wrapping/CMakeLists.txt: ENH: change to work with new FLTK
- command
-
-2005-06-10 10:09 martink
-
- * Source/: cmFLTKWrapUICommand.cxx, cmFLTKWrapUICommand.h: ENH:
- change workings of command so that it can all happing in the
- initial pass still works the old way but complains
-
-2005-06-10 10:08 martink
-
- * Source/cmAddLibraryCommand.cxx: ENH: allow libs with no sources
- but complain
-
-2005-06-10 09:01 andy
-
- * Source/: cmCTest.cxx, CTest/cmCTestBuildHandler.cxx: ENH: Be more
- verbose
-
-2005-06-10 08:56 andy
-
- * Source/CTest/: cmCTestBuildHandler.cxx,
- cmCTestConfigureHandler.cxx: ENH: Be more verbose
-
-2005-06-10 08:40 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx, cmGlobalXCodeGenerator.cxx,
- cmLocalGenerator.cxx, cmLocalGenerator.h: ENH: removed old
- convert calls
-
-2005-06-10 02:57 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-06-09 14:37 martink
-
- * bootstrap, Source/cmake.cxx, Source/CMakeLists.txt: ENH: removed
- UMG2
-
-2005-06-09 14:34 martink
-
- * Source/cmITKWrapTclCommand.cxx: ENH: deprecate old ITK wrap
- command
-
-2005-06-09 11:46 martink
-
- * Source/cmGlobalKdevelopGenerator.cxx: BUG: fix KDev gen to call
- parent class Generate
-
-2005-06-09 11:39 martink
-
- * Source/: cmGlobalKdevelopGenerator.h,
- cmLocalKdevelopGenerator.cxx, cmLocalKdevelopGenerator.h: ENH:
- make KDev sub off of Gen3
-
-2005-06-09 11:33 martink
-
- * Source/cmTarget.cxx: ENH: removed old 1.2 compatability
-
-2005-06-09 11:23 martink
-
- * Tests/Wrapping/CMakeLists.txt: ENH: no longer test ITK command
-
-2005-06-09 09:48 andy
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.cxx: ENH: some better error
- reporting and more robust handlign of bad targets
-
-2005-06-09 08:19 king
-
- * Source/kwsys/Configure.h.in: COMP: Disable more warnings.
-
-2005-06-09 08:18 king
-
- * Source/kwsys/kwsys_ios_sstream.h.in: COMP: Fix
- no-assignment-operator warning and disable typedef-name synonym
- warning.
-
-2005-06-09 08:03 king
-
- * Source/kwsys/Configure.h.in: COMP: Disable useless warnings.
-
-2005-06-09 08:02 king
-
- * Source/kwsys/Configure.hxx.in: ENH: C++ configuration should
- include C configuration.
-
-2005-06-09 07:51 king
-
- * Source/kwsys/SystemTools.cxx: COMP: Need windows.h even on cygwin
- to get CreateFile API.
-
-2005-06-09 07:40 king
-
- * Source/kwsys/RegularExpression.cxx: COMP: Fixed conversion
- warnings.
-
-2005-06-09 04:14 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-06-08 16:55 martink
-
- * Source/cmIncludeCommand.cxx: BUG: fatal error in include file
- should not cause report of missing include file
-
-2005-06-08 16:39 martink
-
- * Tests/Wrapping/CMakeLists.txt: ENH: remove bad add target
- commands
-
-2005-06-08 16:39 martink
-
- * Source/: cmAddExecutableCommand.cxx, cmAddLibraryCommand.cxx:
- ENH: better error checking for add library or executable with no
- source files
-
-2005-06-08 16:31 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: prevent segfault
- when no sources provided for lib
-
-2005-06-08 14:18 andy
-
- * Source/: cmCommandArgumentLexer.in.l, cmCommandArgumentParser.y,
- cmCommandArgumentParserHelper.cxx,
- cmCommandArgumentParserHelper.h: ENH: Handle more cases
-
-2005-06-08 14:11 martink
-
- * Tests/: Complex/CMakeLists.txt, ComplexOneConfig/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt, Wrapping/CMakeLists.txt:
- ENH: remove requirements on 1.2
-
-2005-06-08 12:26 martink
-
- * Tests/: OutOfSource/SubDir/CMakeLists.txt,
- Complex/CMakeLists.txt, Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt,
- Dependency/CMakeLists.txt, Jump/CMakeLists.txt,
- Jump/Library/CMakeLists.txt, PreOrder/CMakeLists.txt,
- SimpleInstall/CMakeLists.txt, SimpleInstallS2/CMakeLists.txt,
- Testing/CMakeLists.txt: ENH: shift to using ADD_SUBDIRECTORY
-
-2005-06-08 10:41 andy
-
- * Source/: cmCommandArgumentLexer.in.l, cmCommandArgumentParser.y,
- cmCommandArgumentParserHelper.cxx,
- cmCommandArgumentParserHelper.h: ENH: Initial import (not working
- yet)
-
-2005-06-08 09:59 king
-
- * Docs/cmake-mode.el: ENH: Experimenting with auto-dated copyright.
-
-2005-06-08 09:52 andy
-
- * Tests/CTestTest/CMakeLists.txt: ENH: Cleanup
-
-2005-06-08 04:09 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-06-07 12:07 martink
-
- * Source/cmGlobalVisualStudio7Generator.cxx,
- Modules/Platform/Windows-cl.cmake: ENH: fix for incorrect setting
- of CONFIZGURATION_TYPES
-
-2005-06-07 10:55 andy
-
- * Source/CTest/cmCTestTestHandler.cxx: BUG: Remove debugging code
-
-2005-06-07 10:47 martink
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx, cmake.cxx: ENH: fix
- problem with dependency scanning
-
-2005-06-07 09:57 andy
-
- * Source/cmLocalGenerator.cxx, Source/kwsys/CMakeLists.txt,
- Source/kwsys/ExtraTest.cmake.in, Tests/CTestTest/test.cmake.in,
- Tests/CTestTest2/test.cmake.in: ENH: Add capability to include
- files to DartTestfile.txt and add example of that
-
-2005-06-07 09:06 andy
-
- * Source/CTest/: cmCTestTestHandler.cxx, cmCTestTestHandler.h: ENH:
- Use CMake for parsing DartTestfile.txt
-
-2005-06-07 08:44 king
-
- * Modules/FindQt.cmake: ENH: Added search locations for a FreeBSD
- location. Contributed by Alexander Neundorf.
-
-2005-06-07 04:09 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-06-06 09:23 andy
-
- * Source/CTest/cmCTestBuildHandler.cxx: BUG: Initialize the
- iterator to prevent seg-fault
-
-2005-06-06 04:19 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-06-05 15:35 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-06-03 16:10 andy
-
- * Source/: CMakeLists.txt, cmCTest.cxx, cmCTest.h,
- CTest/cmCTestBuildAndTestHandler.cxx,
- CTest/cmCTestBuildAndTestHandler.h: ENH: Move the build-and-test
- code to a handler
-
-2005-06-03 14:42 andy
-
- * Source/CTest/: cmCTestGenericHandler.cxx,
- cmCTestGenericHandler.h: ENH: Add a method to parse command line
- argument inside the handler
-
-2005-06-03 14:42 andy
-
- * Tests/CommandLineTest/CMakeLists.txt: ENH: Test setting of
- environment variables
-
-2005-06-03 14:17 andy
-
- * Source/cmSetCommand.cxx: BUG: Remove memory leak
-
-2005-06-03 12:59 martink
-
- * Source/: cmWrapExcludeFilesCommand.cxx,
- cmWrapExcludeFilesCommand.h, cmSourceFilesCommand.cxx,
- cmSourceFilesCommand.h, cmSourceFilesRemoveCommand.cxx,
- cmSourceFilesRemoveCommand.h: ENH: no longer used
-
-2005-06-03 12:58 martink
-
- * Source/cmCommands.cxx: ENH: removed old commands
-
-2005-06-03 11:29 andy
-
- * Source/CTest/cmCTestConfigureHandler.cxx: BUG: Remove unused code
-
-2005-06-03 11:26 martink
-
- * CTestCustom.ctest.in: ENH: shut up buggy gcc stl header
-
-2005-06-03 04:03 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-06-02 18:10 andy
-
- * Source/: cmCTest.cxx, ctest.cxx: ENH: Add debug flag
-
-2005-06-02 16:47 andy
-
- * Source/: cmCTest.cxx, CTest/cmCTestSubmitHandler.cxx: BUG: Fix
- the order of things to make submit handler not crash when proxies
- are set
-
-2005-06-02 15:14 martink
-
- * Docs/cmake-mode.el: ENH: updated commands
-
-2005-06-02 15:09 martink
-
- * Tests/Wrapping/CMakeLists.txt: ENH: removed old command
-
-2005-06-02 14:56 martink
-
- * Tests/: Complex/Library/CMakeLists.txt,
- ComplexOneConfig/Library/CMakeLists.txt,
- ComplexRelativePaths/Library/CMakeLists.txt: ENH: removed old
- commands
-
-2005-06-02 14:48 andy
-
- * Source/CTest/cmCTestSubmitHandler.cxx: ENH: Cleanup output even
- more
-
-2005-06-02 14:24 martink
-
- * Source/: cmCommands.cxx, cmAbstractFilesCommand.cxx,
- cmAbstractFilesCommand.h: ENH: removed the ABSTRACT_FILES command
-
-2005-06-02 14:21 martink
-
- * Docs/cmake-mode.el: ENH: updated to remove ABSTRACT_FILES and add
- ADD_SUBDIRECTORY
-
-2005-06-02 14:10 martink
-
- * Tests/: Complex/Library/CMakeLists.txt,
- ComplexOneConfig/Library/CMakeLists.txt,
- ComplexRelativePaths/Library/CMakeLists.txt: ENH: removed use of
- ABSTRACT command
-
-2005-06-02 13:41 martink
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: now also provides obj rules
- for local Makefiles
-
-2005-06-02 12:26 andy
-
- * Source/CTest/cmCTestBuildHandler.cxx: COMP: Remove compile
- warning
-
-2005-06-02 11:47 andy
-
- * Source/CTest/: cmCTestBuildHandler.cxx, cmCTestBuildHandler.h:
- ENH: Once the number of errors or warnings was reached, stop
- counting them. Also fix compile warning on bad compilers
-
-2005-06-02 09:35 andy
-
- * Source/CTest/cmCTestSubmitHandler.cxx: BUG: On windows there are
- problems when opening file as ascii
-
-2005-06-02 04:02 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-06-01 15:59 andy
-
- * Source/CTest/: cmCTestBuildHandler.cxx, cmCTestBuildHandler.h:
- ENH: Streamline build process. This reduces the memory footprint,
- since only some number of lines of output will be in memory at
- the time. Also, this will report the build errors and warnings as
- it goes through the build
-
-2005-06-01 13:37 martink
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: minor perf improvement
-
-2005-06-01 13:24 martink
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: BUG: do not add help
- target if there is a real target named help
-
-2005-06-01 13:19 king
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: Fixed name given
- to clean target listing for executable and library targets.
-
-2005-06-01 11:18 martink
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: COMP: fix warning
-
-2005-06-01 09:25 andy
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h: BUG: Remove duplicate targets
- when in different generators
-
-2005-06-01 08:59 martink
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: COMP: fix warning
-
-2005-06-01 08:56 martink
-
- * CTestCustom.ctest.in: COMP: suppress warnings in 3rd party libs
-
-2005-06-01 08:54 martink
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: COMP: fix warning
-
-2005-06-01 08:50 martink
-
- * Source/cmQTWrapUICommand.cxx: COMP: fix warning
-
-2005-06-01 08:48 martink
-
- * Source/: cmVariableRequiresCommand.cxx,
- cmVariableRequiresCommand.h: ENH: made immediate
-
-2005-06-01 08:25 andy
-
- * Source/cmCTest.cxx: ENH: Make CMake --build-and-test to be
- verbose by default
-
-2005-06-01 08:25 andy
-
- * Source/cmStandardIncludes.h: ENH: Add support for deque
-
-2005-06-01 03:56 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-31 18:40 andy
-
- * Source/: cmCTest.cxx, cmCTest.h, ctest.cxx,
- CTest/cmCTestBuildHandler.cxx, CTest/cmCTestConfigureHandler.cxx,
- CTest/cmCTestCoverageHandler.cxx,
- CTest/cmCTestMemCheckHandler.cxx, CTest/cmCTestScriptHandler.cxx,
- CTest/cmCTestSubmitHandler.cxx, CTest/cmCTestTestHandler.cxx,
- CTest/cmCTestUpdateHandler.cxx: COMP: Remove ERROR reserved word
- or something and replace with ERROR_MESSAGE
-
-2005-05-31 17:32 andy
-
- * Source/: cmCTest.cxx, cmCTest.h, ctest.cxx,
- CTest/cmCTestBuildHandler.cxx, CTest/cmCTestConfigureHandler.cxx,
- CTest/cmCTestCoverageHandler.cxx, CTest/cmCTestCoverageHandler.h,
- CTest/cmCTestGenericHandler.cxx, CTest/cmCTestGenericHandler.h,
- CTest/cmCTestMemCheckHandler.cxx, CTest/cmCTestScriptHandler.cxx,
- CTest/cmCTestStartCommand.cxx, CTest/cmCTestSubmitHandler.cxx,
- CTest/cmCTestTestHandler.cxx, CTest/cmCTestUpdateHandler.cxx:
- ENH: Add support for writing output file. While doing that,
- redesign the way ctest does output. There may still be problems
- with commands failing, but that should be fixed by applying the
- similar concept to whole CMake
-
-2005-05-31 16:20 martink
-
- * CTestCustom.ctest.in: ENH: shut up some warning on SGI
-
-2005-05-31 15:10 martink
-
- * Source/: cmAddSubDirectoryCommand.cxx,
- cmAddSubDirectoryCommand.h: ENH: removed the PREORDER option from
- the AddSubDirectory command
-
-2005-05-31 14:09 martink
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: COMP: fix a waring
-
-2005-05-31 11:46 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h,
- cmLocalUnixMakefileGenerator3.cxx: ENH: now uses Makefile2 to
- cleanup zsh issues and provided some more documentation
-
-2005-05-31 10:16 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: STYLE: add some better comments
- and remove some unused code
-
-2005-05-31 04:10 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-30 17:26 andy
-
- * Source/cmStandardIncludes.h: ENH: Add support for iomanip
-
-2005-05-30 04:02 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-29 04:04 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-28 08:44 lorensen
-
- * Source/kwsys/SystemTools.cxx: COMP: warning.
-
-2005-05-28 04:10 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-27 22:11 barre
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH: add
- convenience function to convert Windows command line args into
- Unix argc/argv. Pulled and cleaned from PV/VV/VJ init code
-
-2005-05-27 16:17 andy
-
- * Source/CTest/cmCTestScriptHandler.cxx: ENH: Use generated file
- stream for files
-
-2005-05-27 11:26 andy
-
- * DartConfig.cmake: ENH: Dart change
-
-2005-05-27 04:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-26 18:15 andy
-
- * Source/CTest/cmCTestSubmitHandler.cxx: ENH: Fix for changes in
- XML-RPC for Dart2
-
-2005-05-26 17:30 andy
-
- * Modules/CMakeVS8FindMake.cmake: COMP: Fix for support of VS 8.0
- beta 2
-
-2005-05-26 04:09 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-25 15:09 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.cxx: ENH: added clean target for
- subdirs
-
-2005-05-25 12:22 martink
-
- * Source/: cmDepends.cxx, cmDepends.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: BUG: a fix for constant
- recomputing of depends
-
-2005-05-25 11:19 andy
-
- * Source/cmDependsFortran.cxx: ENH: new fortran depends to match
- new Unix Gen
-
-2005-05-25 11:18 martink
-
- * Source/: cmGlobalUnixMakefileGenerator.h,
- cmGlobalUnixMakefileGenerator3.h, cmake.cxx: ENH: switch to using
- new Unix Makefile generator for Unix as well
-
-2005-05-25 04:07 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-24 16:36 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: fix for directory
- of empty depend.make files
-
-2005-05-24 16:11 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: building libs
- caused all generated files to be deleted
-
-2005-05-24 15:36 martink
-
- * Source/cmIfCommand.h: STYLE: fix the docs
-
-2005-05-24 14:42 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: some more cleanup and
- changes to how custom commands are stored
-
-2005-05-24 11:17 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h,
- cmLocalUnixMakefileGenerator3.cxx: ENH: optimization to not use
- requires step unless a language requires it
-
-2005-05-24 10:45 martink
-
- * Modules/CMakeFortranInformation.cmake: ENH: added requires flag
-
-2005-05-24 04:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-23 03:57 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-22 03:56 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-21 03:56 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-20 12:09 andy
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: fix for empty
- custom commands
-
-2005-05-20 11:01 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: added help target and made
- custom commands execute in start output directory
-
-2005-05-20 08:45 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx: ENH: fix warning and
- also add back in build.make
-
-2005-05-20 03:57 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-19 15:55 martink
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: COMP: fix warning
-
-2005-05-19 15:00 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.cxx: ENH: fixes for subdir build
- Makefiles
-
-2005-05-19 14:36 andy
-
- * Modules/Platform/Windows-cl.cmake: ENH: Be more verbose, handle
- network paths, and write compiler output to the log files
-
-2005-05-19 13:32 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: COMP: fix warning
-
-2005-05-19 13:26 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: BUG: fix for bad
- depency clearing
-
-2005-05-19 10:52 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.cxx: ENH: some performance
- improvements
-
-2005-05-19 03:55 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-18 16:10 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: fix for makes that
- do not handle targets wihtout a rule to build them
-
-2005-05-18 13:46 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h, cmTarget.cxx: ENH: another step
- to the next generator still not optimized yet
-
-2005-05-18 04:01 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-17 14:39 martink
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: COMP: some warning fixes and
- cleanup
-
-2005-05-17 14:22 andy
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: implemented
- provides requires code
-
-2005-05-17 11:15 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: some more reorg
-
-2005-05-17 03:57 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-16 14:17 king
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h: BUG:
- Changing to a new test for whether to do relative path
- conversion. Now only paths inside the source or binary trees are
- converted.
-
-2005-05-16 13:42 king
-
- * Source/kwsys/: ProcessUNIX.c, testProcess.c: ENH: Removing
- previous debug code.
-
-2005-05-16 10:53 martink
-
- * Source/: cmDependsFortran.cxx, cmLocalUnixMakefileGenerator3.cxx:
- ENH: some updates to the provides requires code
-
-2005-05-15 03:57 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-14 04:01 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-13 15:51 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: ENH: remove duplicate
- provide rule for fortran
-
-2005-05-13 15:50 martink
-
- * Source/cmLocalGenerator.cxx: COMP: shut up warning
-
-2005-05-13 14:45 king
-
- * Source/kwsys/SharedForward.h.in: ENH: Added knowledge of FreeBSD.
-
-2005-05-13 14:44 king
-
- * Source/kwsys/: ProcessUNIX.c, testProcess.c: ENH: Adding
- debugging code for freebsd.
-
-2005-05-13 14:13 martink
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: BUG: minor cleanup and
- fix for convenience rules
-
-2005-05-13 14:12 martink
-
- * Source/cmGlobalGenerator.cxx: BUG: filx for old bug in rel path
- computaiton code
-
-2005-05-13 09:54 martink
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalUnixMakefileGenerator3.cxx, cmLocalGenerator.cxx,
- cmLocalGenerator.h, cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: warning fixes and some
- first steps in cleaning up the convert code
-
-2005-05-13 04:04 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-12 16:25 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: Undo fix as it broke
- the dashboard
-
-2005-05-12 13:27 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: ENH: fix for bug where
- debug, release etc flags were not used for linker options, BUG
- 1781 fix
-
-2005-05-12 11:53 martink
-
- * bootstrap: ENH: moved gen3 into bootstrap process
-
-2005-05-12 11:26 martink
-
- * Source/cmLocalUnixMakefileGenerator3.cxx: COMP: shut up unused
- var
-
-2005-05-12 11:24 martink
-
- * Source/cmake.cxx: BUG: fix bad generator name
-
-2005-05-12 10:58 martink
-
- * Source/CMakeLists.txt: ENH: defer relative paths
-
-2005-05-12 10:49 martink
-
- * Source/: CMakeLists.txt, cmGlobalBorlandMakefileGenerator.cxx,
- cmGlobalNMakeMakefileGenerator.cxx,
- cmGlobalNMakeMakefileGenerator.h,
- cmGlobalUnixMakefileGenerator3.cxx, cmLocalGenerator.h,
- cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h, cmake.cxx: ENH: added new
- generator
-
-2005-05-12 03:53 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-11 13:16 martink
-
- * Source/: cmDepends.cxx, cmDepends.h, cmDependsC.cxx,
- cmDependsC.h, cmDependsFortran.cxx, cmDependsFortran.h,
- cmDependsJava.cxx, cmDependsJava.h,
- cmLocalUnixMakefileGenerator2.cxx: ENH: some changes to the
- depends signature to be more flexible
-
-2005-05-11 12:44 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: another snapshot
-
-2005-05-11 10:19 martink
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h: ENH: added
- new methods to convert to HomeRelative paths
-
-2005-05-11 08:45 martink
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h,
- cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h: ENH: snapshot
-
-2005-05-11 03:55 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-10 16:41 king
-
- * Source/kwsys/testProcess.c: ENH: Removing QNX hack for test 6 now
- that the problem has been fixed.
-
-2005-05-10 16:36 king
-
- * Source/kwsys/ProcessUNIX.c: BUG: struct timeval uses unsigned
- types on at least one platform (QNX). Alot of the time logic
- assumes a signed type. Switch to using a signed representation
- that is converted to the native representation only for system
- calls.
-
-2005-05-10 11:11 andy
-
- * Source/: cmGeneratedFileStream.cxx, cmGeneratedFileStream.h: ENH:
- Allow changing of file name
-
-2005-05-10 11:00 king
-
- * Source/: cmDependsC.cxx, cmDependsC.h: BUG: Re-implemented
- dependency line parsing to deal with quoted paths and escaped
- spaces.
-
-2005-05-10 10:10 andy
-
- * Source/cmBuildCommand.cxx: ENH: Remove the old code
-
-2005-05-10 03:52 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-09 15:11 martink
-
- * Source/cmGlobalUnixMakefileGenerator3.cxx: ENH: some more fixes
-
-2005-05-09 08:53 martink
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: some more cleanup
-
-2005-05-09 03:57 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-08 13:49 andy
-
- * Source/CTest/cmCTestSubmitCommand.cxx,
- Tests/CTestTest2/test.cmake.in: ENH: Add notes
-
-2005-05-08 13:48 andy
-
- * Source/CTest/cmCTestStartCommand.cxx: ENH: Remove error about not
- being able to update CTest configuration
-
-2005-05-08 13:48 andy
-
- * Source/CTest/: cmCTestBuildCommand.cxx, cmCTestBuildCommand.h:
- ENH: Remove memory leak and remember global generator for next
- time
-
-2005-05-08 13:47 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: ENH: Add method so that ctest
- handlers and commands can add notes
-
-2005-05-08 04:00 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-07 03:56 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-06 14:49 martink
-
- * Source/: cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h,
- cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h: ENH: updates
-
-2005-05-06 12:38 king
-
- * Source/cmake.cxx: COMP: Fixed forced bool conversion warning.
-
-2005-05-06 09:58 king
-
- * Source/: cmDepends.cxx, cmDepends.h, cmDependsC.cxx,
- cmDependsC.h, cmDependsFortran.cxx, cmDependsFortran.h,
- cmDependsJava.cxx, cmDependsJava.h,
- cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h, cmake.cxx: ENH: Added optional
- verbose output to build system dependency check.
-
-2005-05-06 03:52 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-05 12:45 martink
-
- * Source/: cmGlobalUnixMakefileGenerator3.cxx,
- cmGlobalUnixMakefileGenerator3.h,
- cmLocalUnixMakefileGenerator3.cxx,
- cmLocalUnixMakefileGenerator3.h: ENH: backup of work in progress
-
-2005-05-05 10:40 andy
-
- * Source/cmMakefile.cxx: BUG: If there is a fatal error, stop
- processing list file
-
-2005-05-05 10:26 king
-
- * Source/cmGlobalVisualStudio7Generator.cxx: BUG: Added space after
- /clean to avoid putting it together with the build configuration.
- This fixes the failure of the complext test on the second run in
- the same tree.
-
-2005-05-05 10:19 andy
-
- * Source/kwsys/CTestConfig.cmake: ENH: Add configuration file for
- kwsys
-
-2005-05-05 10:19 andy
-
- * Source/CMakeLists.txt, Tests/CTestTest2/CMakeLists.txt,
- Tests/CTestTest2/test.cmake.in: ENH: Add new style ctest project
-
-2005-05-05 10:18 andy
-
- * Source/CTest/: cmCTestConfigureCommand.cxx,
- cmCTestSubmitCommand.cxx: ENH: Add default configure rules for
- CMake projects and add default rules for submission
-
-2005-05-05 10:18 andy
-
- * Source/CTest/cmCTestScriptHandler.cxx: ENH: Add variable that
- holds cmake executable
-
-2005-05-05 10:17 andy
-
- * Source/cmCTest.h: ENH: Add accessort for CMake executable
-
-2005-05-05 09:45 king
-
- * Source/kwsys/testProcess.c: ENH: Disabling test 6 on QNX until
- process killing can be resolved. It will just fail always for
- now.
-
-2005-05-05 09:21 andy
-
- * Source/cmCTest.cxx: BUG: Fix logic for verbose
-
-2005-05-05 09:09 king
-
- * Source/kwsys/hashtable.hxx.in: COMP: Removed unused parameter
- warning.
-
-2005-05-05 09:08 king
-
- * Source/kwsys/SystemTools.cxx: COMP: Added work-around to avoid
- warnings about unreferenced inline functions from SGI termios.
-
-2005-05-05 09:05 king
-
- * Source/kwsys/ProcessUNIX.c: COMP: Added initializer to avoid
- warning. It is not really needed, though.
-
-2005-05-05 03:51 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-04 11:37 andy
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH: Add
- split that splits on arbitrary separator
-
-2005-05-04 11:16 andy
-
- * Source/CTest/cmCTestUpdateHandler.cxx: ENH: Allow spaces in
- update command
-
-2005-05-04 11:13 andy
-
- * Source/CTest/: cmCTestBuildCommand.cxx, cmCTestBuildCommand.h,
- cmCTestConfigureCommand.cxx, cmCTestConfigureCommand.h,
- cmCTestCoverageHandler.cxx, cmCTestSubmitCommand.cxx,
- cmCTestSubmitCommand.h, cmCTestTestCommand.cxx,
- cmCTestTestCommand.h, cmCTestUpdateCommand.cxx,
- cmCTestUpdateCommand.h: ENH: Improve syntax
-
-2005-05-04 11:13 andy
-
- * Source/cmGlobalGenerator.cxx: BUG: Fix bootstrap test on machines
- with spaces in the path
-
-2005-05-04 11:12 andy
-
- * Source/kwsys/SystemTools.hxx.in: ENH: Expose
- ConvertToUnixOutputPath
-
-2005-05-04 03:50 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-03 15:28 andy
-
- * Source/: cmCTest.cxx, cmCTest.h, CTest/cmCTestStartCommand.cxx:
- ENH: Add Site and BuildName, make sure that the rest of the
- default -S rule does not happen, and make sure that new tag will
- be created
-
-2005-05-03 15:20 andy
-
- * Source/cmGlobalGenerator.cxx: ENH: No need to convert to output
- path
-
-2005-05-03 15:19 king
-
- * Source/: cmDependsFortranLexer.cxx, cmDependsFortranLexer.in.l,
- cmDependsJavaLexer.cxx, cmDependsJavaLexer.in.l: COMP: Removed
- warnings about unreachable code and constant control expressions.
- Added the changes to the instructions in the input lex files.
-
-2005-05-03 14:58 king
-
- * Source/: cmGeneratedFileStream.h,
- cmLocalUnixMakefileGenerator2.h, cmStandardIncludes.h,
- cmSystemTools.cxx, CTest/cmCTestUpdateHandler.h,
- kwsys/CommandLineArguments.cxx, kwsys/SystemTools.cxx,
- kwsys/testhash.cxx: COMP: Added pragma directives for SGI
- compilers to avoid useless warnings.
-
-2005-05-03 14:57 king
-
- * Source/CursesDialog/: cmCursesLongMessageForm.cxx,
- cmCursesMainForm.cxx: COMP: Changed while(1) to for(;;) to avoid
- warning about constant control expression.
-
-2005-05-03 14:53 king
-
- * Source/kwsys/kwsysPlatformCxxTests.cxx: COMP: Removed stray
- semicolon.
-
-2005-05-03 14:28 king
-
- * Source/cmStandardIncludes.h: COMP: Added hack to avoid SGI
- termios.h warnings.
-
-2005-05-03 14:28 king
-
- * Source/: cmDependsJavaLexer.cxx, cmDependsJavaLexer.in.l: COMP:
- Need #undef ECHO to avoid conflict with system ECHO definition.
-
-2005-05-03 14:27 king
-
- * Source/kwsys/RegularExpression.hxx.in: COMP: Changed type of
- regmlen to avoid warnings when other lengths are converted to it.
-
-2005-05-03 10:02 king
-
- * Source/kwsys/testProcess.c: ENH: Adding test of running
- executable with forward slashes on windows.
-
-2005-05-03 09:40 andy
-
- * Source/: cmCTest.cxx, cmCTest.h, CTest/cmCTestBuildCommand.cxx,
- CTest/cmCTestBuildHandler.cxx, CTest/cmCTestConfigureCommand.cxx,
- CTest/cmCTestConfigureHandler.cxx,
- CTest/cmCTestCoverageHandler.cxx,
- CTest/cmCTestMemCheckHandler.cxx, CTest/cmCTestStartCommand.cxx,
- CTest/cmCTestSubmitCommand.cxx, CTest/cmCTestSubmitHandler.cxx,
- CTest/cmCTestTestCommand.cxx, CTest/cmCTestUpdateCommand.cxx,
- CTest/cmCTestUpdateHandler.cxx: ENH: Cleanups
-
-2005-05-03 08:17 andy
-
- * CTestConfig.cmake, Source/CMakeLists.txt, Source/cmCTest.cxx,
- Source/cmCTest.h, Source/CTest/cmCTestBuildHandler.cxx,
- Source/CTest/cmCTestScriptHandler.cxx,
- Source/CTest/cmCTestSubmit.cxx, Source/CTest/cmCTestSubmit.h,
- Source/CTest/cmCTestSubmitCommand.cxx,
- Source/CTest/cmCTestSubmitCommand.h,
- Source/CTest/cmCTestSubmitHandler.cxx,
- Source/CTest/cmCTestSubmitHandler.h,
- Source/CTest/cmCTestTestCommand.cxx,
- Source/CTest/cmCTestTestCommand.h: ENH: Promote submit into a
- full handler, add test and submit command and do some cleanups
-
-2005-05-03 04:15 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-02 15:51 andy
-
- * CTestConfig.cmake, Source/CTest/cmCTestBuildCommand.cxx,
- Source/CTest/cmCTestScriptHandler.cxx: ENH: Make ctest build
- command work
-
-2005-05-02 15:51 andy
-
- * Source/cmake.h: ENH: Make AddCMakePath public
-
-2005-05-02 15:50 andy
-
- * Source/cmGlobalGenerator.h: ENH: Make FindMakeProgram public
-
-2005-05-02 14:15 andy
-
- * CTestConfig.cmake, Source/CMakeLists.txt, Source/cmCTest.cxx,
- Source/cmCTest.h, Source/CTest/cmCTestBuildCommand.cxx,
- Source/CTest/cmCTestBuildCommand.h,
- Source/CTest/cmCTestConfigureCommand.cxx,
- Source/CTest/cmCTestConfigureCommand.h,
- Source/CTest/cmCTestScriptHandler.cxx,
- Source/CTest/cmCTestStartCommand.cxx,
- Source/CTest/cmCTestUpdateCommand.cxx: ENH: More commands. Start
- working on new style ctest configuration
-
-2005-05-02 03:42 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-05-01 03:38 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-04-30 15:36 andy
-
- * Source/cmGlobalXCodeGenerator.cxx: COMP: Remove warning
-
-2005-04-30 04:13 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-04-29 12:50 andy
-
- * Source/cmBuildCommand.cxx: ENH: Try to see if
- GenerateBuildCommand produces apropriate result
-
-2005-04-29 11:49 andy
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio6Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h, cmGlobalXCodeGenerator.cxx,
- cmGlobalXCodeGenerator.h: ENH: Add option to ignore errors. Only
- works on make
-
-2005-04-29 10:11 king
-
- * Source/: cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio6Generator.h,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio71Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h: COMP: Converting
- INSTALL->ALL_BUILD dependency implementation to use the
- AddUtility method on a target. This significantly simplifies the
- implementation and removes warnings about hiding virtual
- functions.
-
-2005-04-29 10:07 andy
-
- * Source/cmGlobalXCodeGenerator.cxx: COMP: Remove warning
-
-2005-04-29 10:06 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: make install depend on
- all
-
-2005-04-29 04:15 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-04-28 18:34 andy
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h:
- ENH: Start working on command that will abstract generating of
- build command
-
-2005-04-28 18:18 andy
-
- * Source/: cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio6Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h: ENH: Start working on a method
- that abstracts generating of build command
-
-2005-04-28 17:33 andy
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h: ENH: Start
- working on command that will abstract generating of build command
-
-2005-04-28 16:21 king
-
- * Source/: cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio6Generator.h,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio71Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h: ENH: Added dependency from
- INSTALL target to ALL_BUILD target so that targets build before
- being installed.
-
-2005-04-28 11:47 king
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: BUG: Avoid infinite loop during
- installation.
-
-2005-04-28 09:21 king
-
- * Source/kwsys/testProcess.c: BUG: Extending all timeouts to help
- out slower machines.
-
-2005-04-28 09:14 andy
-
- * Source/CTest/cmCTestBuildHandler.cxx: ENH: Add internal error
-
-2005-04-28 05:07 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-04-27 11:46 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: ENH: Added dependency
- on all for install rule to make sure build is up to date before
- installing. This behavior can be disabled by setting
- CMAKE_SKIP_INSTALL_ALL_DEPENDENCY to true.
-
-2005-04-27 11:33 king
-
- * Source/cmSourceFile.cxx: BUG: Do not leave ../ in the full path
- to a source file. Using CollapseFullPath simplifies the code
- anyway.
-
-2005-04-27 10:01 king
-
- * Source/kwsys/testProcess.c: BUG: Extending timeout of test 6 from
- 0.1 seconds to 3 seconds. This should avoid missed signals and
- intermittent failures.
-
-2005-04-27 09:12 king
-
- * Tests/CustomCommand/CMakeLists.txt: BUG: Use copy to produce
- doc1pre.txt instead of echo. The redirection does not like
- forward slashes on Win9x.
-
-2005-04-27 04:35 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-04-26 17:11 king
-
- * Modules/: CMakeBackwardCompatibilityC.cmake, FindThreads.cmake:
- BUG: Fix try-compile for sys/prctl.h. It needs to include
- sys/types.h first according to the man page.
-
-2005-04-26 14:12 king
-
- * Source/CursesDialog/form/: CMakeLists.txt,
- internal_stdio_core.h.in: ENH: Removing stdio_core hack. A
- better work-around has been put in cmStandardIncludes.h.
-
-2005-04-26 14:11 king
-
- * Source/cmStandardIncludes.h: COMP: Adding inclusion of stdarg.h
- to work-around SGI header bug in 7.4.2m.
-
-2005-04-26 11:55 king
-
- * Tests/CustomCommand/CMakeLists.txt: ENH: Added pre-build and
- post-build test for custom targets.
-
-2005-04-26 11:31 andy
-
- * Source/kwsys/SystemTools.cxx: BUG: Looks like std::string changes
- the result of c_str() call. This fixes potential problems
-
-2005-04-26 11:15 andy
-
- * Source/cmakewizard.h: COMP: Remove warning
-
-2005-04-26 11:09 andy
-
- * Source/: cmakewizard.h, CTest/cmCTestUpdateHandler.cxx: COMP:
- Remove warnings
-
-2005-04-26 11:08 king
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio6Generator.h: BUG: Fixed ordering of multiple
- commands in a custom target when implemented as custom commands.
- Also added support to execute pre-build rules first to be
- consistent with makefile generator.
-
-2005-04-26 08:51 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: BUG: Added inclusion of
- pre-build rules for custom targets.
-
-2005-04-26 04:45 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-04-25 09:59 andy
-
- * Source/cmLocalGenerator.cxx: COMP: Remove warning
-
-2005-04-25 03:03 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-04-24 16:19 andy
-
- * Source/cmAddTestCommand.cxx: COMP: Fix problem on compilers that
- cannot implicitly convert std::string to cmStdString
-
-2005-04-24 15:59 andy
-
- * bootstrap, Source/CMakeLists.txt, Source/cmAddTestCommand.cxx,
- Source/cmAddTestCommand.h, Source/cmEnableTestingCommand.cxx,
- Source/cmEnableTestingCommand.h, Source/cmGlobalGenerator.cxx,
- Source/cmLocalGenerator.cxx, Source/cmLocalGenerator.h,
- Source/cmMakefile.cxx, Source/cmMakefile.h, Source/cmTest.cxx,
- Source/cmTest.h: ENH: Improve internal test handling by creating
- a test class. Command cmEnableTesting now only sets
- CMAKE_TESTING_ENABLED and cmAddTest only adds a test to the list.
- The actual test files are written by local generator. This way we
- can at some point in the future replace DartTestfile with some
- XML file
-
-2005-04-24 14:28 andy
-
- * Source/cmCTest.cxx: BUG: The argument is --ctest-config
-
-2005-04-24 13:57 andy
-
- * Source/CTest/cmCTestUpdateHandler.cxx: ENH: Support for modified
- and conflicts in subversion
-
-2005-04-24 13:15 king
-
- * Source/CursesDialog/form/CMakeLists.txt: BUG: Older SGI compilers
- still have internal/stdio_core.h but do not support
- #include_next. We'll have to try-compile to test whether this
- hack is needed.
-
-2005-04-24 12:32 andy
-
- * Source/CTest/cmCTestUpdateHandler.cxx: BUG: Remember if there was
- update error
-
-2005-04-24 02:26 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-04-23 02:26 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-04-22 16:11 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h, cmTarget.cxx, cmTarget.h: ENH:
- Created cmTarget::GetLibraryNames to replace
- cmLocalUnixMakefileGenerator2::GetLibraryNames. Added
- cmTarget::GetLibraryCleanNames to be used by
- cmLocalUnixMakefileGenerator2. Now when a library is linked both
- the shared and static versions are removed from the build tree.
- In this way we avoid having both kinds of libraries present when
- the user switches BUILD_SHARED_LIBS on/off. This prevents
- problems with turning off shared libraries and then expecting the
- linker to use the static libraries only to find it is using the
- out-of-date shared versions.
-
-2005-04-22 15:23 king
-
- * Source/: cmGetTargetPropertyCommand.cxx, cmLocalGenerator.cxx,
- cmLocalGenerator.h, cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h, cmTarget.cxx, cmTarget.h: ENH:
- Added cmTarget::GetBaseName and cmTarget::GetFullName methods and
- removed cmLocalGenerator::GetFullTargetName and
- cmLocalUnixMakefileGenerator2::GetBaseTargetName. This
- functionality is more sensibly implemented in cmTarget. It is
- also needed for an upcoming feature in which both the shared and
- static versions of a library will be removed before one is
- linked.
-
-2005-04-22 13:52 king
-
- * Source/CTest/cmCTestUpdateHandler.cxx: COMP: Commented out unused
- variable until the corresponding logic is finished.
-
-2005-04-22 11:57 king
-
- * Source/kwsys/: hashtable.hxx.in, kwsys_stl_string.hxx.in: COMP:
- Removed line continuation characters from #if lines to avoid
- linefeed problems on cygwin.
-
-2005-04-22 09:44 king
-
- * Source/kwsys/testProcess.c: BUG: Drastically extending test5's
- timeouts to get it to pass when running on a heavily-loaded
- machine.
-
-2005-04-22 09:22 king
-
- * Source/kwsys/SystemTools.cxx: COMP: Fixed
- assignment-in-conditional warning.
-
-2005-04-22 09:21 king
-
- * Source/kwsys/CommandLineArguments.cxx: COMP: Fixed constant
- conditional warning.
-
-2005-04-22 09:21 king
-
- * Source/kwsys/ProcessWin32.c: COMP: Fixed unused parameter and
- constant conditional warnings.
-
-2005-04-22 03:03 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-04-21 18:23 andy
-
- * Source/CTest/cmCTestUpdateHandler.cxx: ENH: Reorganize a bit and
- make sure to report an error if there are modified files or
- conflicts
-
-2005-04-21 17:00 king
-
- * Source/CursesDialog/form/: CMakeLists.txt, form.h,
- internal_stdio_core.h.in: COMP: Using a new work-around for
- stdarg.h problem on SGI.
-
-2005-04-21 16:46 king
-
- * Source/kwsys/hashtable.hxx.in: BUG: Fixed hash_allocator_n size
- computation.
-
-2005-04-21 16:46 king
-
- * Source/kwsys/testhash.cxx: ENH: Added include-work-around for
- hashtable.hxx.in dependency.
-
-2005-04-21 16:05 king
-
- * Source/kwsys/: ProcessUNIX.c, ProcessWin32.c: BUG: Do not close
- stdout/stderr pipes in parent if they are shared.
-
-2005-04-21 13:56 king
-
- * Source/kwsys/SystemTools.hxx.in: COMP: Do not do va_list hack if
- there is no std:: namespace.
-
-2005-04-21 13:47 king
-
- * bootstrap, Source/kwsys/CMakeLists.txt,
- Source/kwsys/Configure.hxx.in, Source/kwsys/hashtable.hxx.in,
- Source/kwsys/kwsysPlatformCxxTests.cxx: COMP: Added KWSys
- try-compiles KWSYS_STL_HAS_ALLOCATOR_TEMPLATE and
- KWSYS_STL_HAS_ALLOCATOR_OBJECTS. Needed for more old-stl support
- in the hashtable.
-
-2005-04-21 02:50 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-04-20 16:11 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-04-20 08:53 king
-
- * Source/kwsys/testProcess.c: BUG: Adjusting timeouts for tests 4
- and 5 to avoid early killing.
-
-2005-04-19 18:26 andy
-
- * Source/: CursesDialog/form/form.h, kwsys/SystemTools.hxx.in:
- COMP: Attempt to fix problem with building on SGI
-
-2005-04-19 11:52 king
-
- * Source/kwsys/ProcessUNIX.c: BUG: When killing a child all the
- pipe read ends should be closed. This will allow a child that is
- blocking while waiting to write to the pipe to wake up and
- receive the kill signal properly on cygwin.
-
-2005-04-19 10:52 king
-
- * Source/kwsys/testProcess.c: BUG: Expanded difference in timeouts
- between tests 4 and 5 so that 5 does not timeout while waiting
- for 4 to timeout. This should fix the intermittent failure of
- test 5 on cygwin. ENH: When a mismatch is reported it now
- reports what it was as well as what it should have been.
-
-2005-04-15 18:57 king
-
- * Source/kwsys/kwsysPlatformCxxTests.cxx: BUG: For some reason the
- non-template allocator test compiles on VS6 even though its
- allocator is a template. Adding ::size_type to be sure it
- accesses a member of the allocator.
-
-2005-04-15 18:49 king
-
- * Source/kwsys/kwsysPlatformCxxTests.cxx: BUG: Fix iterator traits
- test to use a real iterator instead of int*.
-
-2005-04-15 16:10 king
-
- * Source/kwsys/CMakeLists.txt: BUG: Cannot use Win32 implementation
- for cygwin processes because then cygwin paths to executables
- like /usr/bin/ls are not found.
-
-2005-04-15 16:00 king
-
- * bootstrap, Source/kwsys/CMakeLists.txt,
- Source/kwsys/Configure.hxx.in, Source/kwsys/hash_fun.hxx.in,
- Source/kwsys/hashtable.hxx.in,
- Source/kwsys/kwsysPlatformCxxTests.cxx,
- Source/kwsys/kwsys_cstddef.hxx.in: COMP: Added
- KWSYS_CXX_HAS_CSTDDEF try-compile to KWSys to provide
- kwsys/cstddef header (to get size_t for hash_fun.hxx).
-
-2005-04-15 15:30 king
-
- * Source/kwsys/: hash_map.hxx.in, hash_set.hxx.in,
- hashtable.hxx.in: COMP: Replaced kwsys_stl with
- @KWSYS_NAMESPACE@_stl to properly use the configured namespace.
-
-2005-04-15 15:18 barre
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH: move
- convenience method to get OS name and version from KWApp to
- KWSys.
-
-2005-04-15 14:47 andy
-
- * Source/cmCTest.cxx: STYLE: Fix english
-
-2005-04-15 13:56 king
-
- * Source/kwsys/SystemTools.cxx: BUG: Added missing variable
- initialization that was accidentally removed on the previsous
- commit.
-
-2005-04-15 13:35 king
-
- * Source/kwsys/CMakeLists.txt: ENH: Changing kwsysProcess
- implementation on Cygwin to use the Win32 implementation instead
- of the UNIX implementation. This makes dealing with misbehaving
- children work better. The KWSys Win32 process implementaion is
- more robust than the Cygwin implementation (partly because it
- doesn't have to exactly reproduce the POSIX api).
-
-2005-04-15 10:46 hoffman
-
- * Source/cmTryCompileCommand.cxx: BUG: work around for buggy Tigger
- OSX systems that read two copies of the same file in a directory
-
-2005-04-15 09:54 king
-
- * bootstrap, Source/kwsys/CMakeLists.txt,
- Source/kwsys/Configure.hxx.in, Source/kwsys/hash_map.hxx.in,
- Source/kwsys/hash_set.hxx.in, Source/kwsys/hashtable.hxx.in,
- Source/kwsys/kwsysPlatformCxxTests.cxx: ENH: Added KWSys
- try-compiles KWSYS_STL_HAS_ITERATOR_TRAITS,
- KWSYS_STL_HAS_ITERATOR_CATEGORY,
- KWSYS_STL_HAS___ITERATOR_CATEGORY, and
- KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE to get the hash table to
- compile on old HP and Sun compilers.
-
-2005-04-15 09:35 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-04-15 09:05 king
-
- * Source/kwsys/hash_map.hxx.in: COMP: Replacing _Select1st with a
- specialized hash_select1st that avoids requiring the stl pair to
- have first_type defined. The old HP STL does not define
- first_type and second_type in its pair.
-
-2005-04-15 08:59 king
-
- * bootstrap, Source/kwsys/CMakeLists.txt,
- Source/kwsys/Configure.hxx.in, Source/kwsys/hashtable.hxx.in,
- Source/kwsys/kwsysPlatformCxxTests.cxx: ENH: Added
- KWSYS_CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP try-compile to KWSys.
- Needed to optionally bring hash table comparison operators into
- the global namespace when argument dependent lookup is not
- supported.
-
-2005-04-15 08:25 king
-
- * Source/kwsys/SystemTools.cxx: COMP: Removed extra variable
- initializations to avoid Borland warnings.
-
-2005-04-14 04:50 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-04-13 23:04 king
-
- * Source/kwsys/: hash_map.hxx.in, hash_set.hxx.in,
- hashtable.hxx.in: COMP: Remove friend templates and always use
- template friends (possibly with <>). Needed to work-around Sun
- CC bug.
-
-2005-04-13 23:03 king
-
- * Source/kwsys/testSystemTools.cxx: COMP: Disable MSVC debug symbol
- truncation warning.
-
-2005-04-13 18:13 andy
-
- * Source/cmGeneratedFileStream.cxx: ENH: For sanity, create
- directory before creating generated file stream
-
-2005-04-13 17:58 king
-
- * Source/CMakeLists.txt: BUG: The test1 executable has been removed
- from kwsys. Instead using testIOS for the kwsys test.
-
-2005-04-13 16:58 king
-
- * Source/kwsys/CMakeLists.txt: STYLE: Renaming kwsys-hash test to
- kwsys-testhash for consistency with other tests.
-
-2005-04-13 16:55 king
-
- * Source/kwsys/testProcess.c: COMP: Removing return value from
- test6. It is an infinite loop, so the return causes warnings.
- It will never return anyway.
-
-2005-04-13 16:47 king
-
- * Source/kwsys/: CMakeLists.txt, test1.cxx: ENH: Removing old
- test1.c Process execution example. It is fully replaced by
- testProcess.
-
-2005-04-13 16:46 king
-
- * Source/kwsys/: Base64.c, CommandLineArguments.cxx, Directory.cxx,
- ProcessUNIX.c, ProcessWin32.c, RegularExpression.cxx,
- SystemTools.cxx, test1.cxx, testCommandLineArguments.cxx,
- testIOS.cxx, testProcess.c, testSystemTools.cxx, testhash.cxx:
- COMP: Adding work-around for CMake dependency scanning
- limitation. Any configured header included by KWSYS_HEADER() in
- a .c or .cxx file in kwsys itself must use this hack to get
- dependencies.
-
-2005-04-13 16:35 andy
-
- * Source/: cmMakefile.cxx, cmSourceFile.cxx, cmSourceFile.h: ENH:
- Speedup by storing source name without last extension
-
-2005-04-13 16:34 andy
-
- * Source/cmTarget.cxx: ENH: Speedup by only getting the source once
-
-2005-04-13 16:25 andy
-
- * Source/cmSystemTools.cxx: ENH: Improve performance by using
- vector of char instead of string
-
-2005-04-13 16:05 king
-
- * Source/kwsys/testSystemTools.cxx: BUG: Only do ~ test if HOME
- variable is defined.
-
-2005-04-13 15:57 king
-
- * Source/kwsys/testProcess.c: BUG: Avoid error diagnostic popups on
- windows for test that crashes on purpose.
-
-2005-04-13 15:39 king
-
- * bootstrap, Source/kwsys/CMakeLists.txt,
- Source/kwsys/Configure.hxx.in, Source/kwsys/hashtable.hxx.in,
- Source/kwsys/kwsysPlatformCxxTests.cxx: COMP: Added
- KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT check for non-standard
- argument to stl allocator<>::max_size method. Needed for kwsys
- hashtable to compile on Sun CC.
-
-2005-04-13 15:29 king
-
- * Source/kwsys/kwsysPlatformCxxTests.cxx: BUG:
- allocator<>::rebind<> test should use kwsys_stl::allocator, not
- std::allocator.
-
-2005-04-13 15:22 king
-
- * Source/kwsys/hashtable.hxx.in: COMP: Fix for Sun CC stl allocator
- signature of allocate method.
-
-2005-04-13 15:04 king
-
- * Source/kwsys/hashtable.hxx.in: BUG: When constructing the bucket
- vector type the allocator given must have been rebound to _Node*
- already because GCC 3.4's vector type does not rebind it.
-
-2005-04-13 14:43 king
-
- * Source/cmTryCompileCommand.cxx: ENH: Added better error message
- when TRY_COMPILE does not recognize an extension.
-
-2005-04-13 14:37 king
-
- * Source/kwsys/SystemTools.cxx: BUG: Fix GetFilenameName to not use
- uninitialized search position in win32 version.
-
-2005-04-13 14:13 king
-
- * bootstrap: BUG: Added more try-compiles from kwsys.
-
-2005-04-13 14:13 king
-
- * Source/kwsys/kwsysPlatformCxxTests.cxx: BUG: Fixed member
- template test to not produce a test program that crashes when it
- runs.
-
-2005-04-13 13:59 andy
-
- * Source/kwsys/SystemTools.cxx: ENH: Speedup improvements
-
-2005-04-13 13:57 andy
-
- * Source/kwsys/: CMakeLists.txt, Configure.hxx.in, Process.h.in,
- ProcessUNIX.c, ProcessWin32.c, test1.cxx,
- testCommandLineArguments.cxx, testIOS.cxx, testProcess.c,
- testSystemTools.cxx, testhash.cxx: ENH: Do kwsys testing as part
- of cmake testing, command line arguments are not experimental and
- add simple test for systemtools
-
-2005-04-13 13:43 hoffman
-
- * Utilities/Release/cmake_release.sh: BUG: fix clean action
-
-2005-04-13 12:44 hoffman
-
- * CMakeLists.txt, Utilities/Release/cmake_release.sh: Move minor
- version to 2.0.6
-
-2005-04-13 09:54 hoffman
-
- * Source/: cmLocalVisualStudio7Generator.cxx,
- kwsys/SystemTools.cxx: BUG: fix insert for 64 bit
-
-2005-04-13 08:08 king
-
- * Source/kwsys/: CMakeLists.txt, Configure.hxx.in, hash_fun.hxx.in,
- hash_map.hxx.in, hash_set.hxx.in, hashtable.hxx.in,
- kwsysPlatformCxxTests.cxx, testhash.cxx: ENH: Adding SGI hash_map
- and hash_set implementation ported from STL to KWSys. This also
- adds try-compiles for KWSYS_STL_HAS_ALLOCATOR_REBIND,
- KWSYS_CXX_HAS_FULL_SPECIALIZATION,
- KWSYS_CXX_HAS_MEMBER_TEMPLATES, and
- KWSYS_CXX_HAS_NULL_TEMPLATE_ARGS.
-
-2005-04-13 08:05 king
-
- * Source/kwsys/kwsys_stl.hxx.in: ENH: Added
- __HPACC_USING_MULTIPLIES_IN_FUNCTIONAL fix from vtkstd.
-
-2005-04-13 04:39 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-04-12 15:40 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: fix Ambiguity in
- insert call
-
-2005-04-12 15:11 hoffman
-
- * Source/cmLocalGenerator.cxx: BUG: add missing header for borland
-
-2005-04-12 13:33 king
-
- * Source/kwsys/SystemTools.cxx: COMP: Fixed ambiguous call to
- insert method of string.
-
-2005-04-12 13:27 hoffman
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h,
- cmLocalVisualStudio7Generator.cxx, cmMacroCommand.cxx,
- cmMakefile.cxx, cmMakefile.h: ENH: performance improvements
-
-2005-04-12 13:26 hoffman
-
- * Source/cmDepends.cxx: ENH: do not collapse full path for cwd
-
-2005-04-12 13:26 hoffman
-
- * Source/cmCacheManager.cxx: ENH: make regex static so it is not
- recomputed for each line of the cache
-
-2005-04-12 13:25 hoffman
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH:
- optimization of cwd and do not leak library handle
-
-2005-04-12 09:36 martink
-
- * Source/cmLocalGenerator.cxx: BUG: local gen was setting proj dir
- when it shouldnt
-
-2005-04-12 09:35 martink
-
- * Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt: ENH: also
- test for correct Proj dir settings
-
-2005-04-12 03:09 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-04-11 12:38 hoffman
-
- * ChangeLog.manual, Source/cmCTest.cxx: BUG: fix GetLongPathName
- for all versions of windows
-
-2005-04-11 12:20 hoffman
-
- * Source/kwsys/SystemTools.cxx: BUG: fix GetLongPathName for
- WindowsNT
-
-2005-04-11 04:58 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-04-10 04:06 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-04-09 02:38 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-04-08 12:46 hoffman
-
- * Source/: cmOrderLinkDirectories.cxx, cmOrderLinkDirectories.h:
- BUG: handle case insensitive library extensions on windows
-
-2005-04-08 08:34 hoffman
-
- * Source/kwsys/SystemTools.cxx: BUG: fix build on mingw
-
-2005-04-08 02:37 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-04-07 17:39 hoffman
-
- * Source/cmakemain.cxx: BUG: move fix for -E option to branch
-
-2005-04-07 17:24 hoffman
-
- * Tests/CommandLineTest/CMakeLists.txt: merge from main tree fix
- for command line test
-
-2005-04-07 17:22 hoffman
-
- * Source/cmCTest.cxx: BUG: add error checking on GetLongPath
-
-2005-04-07 17:20 hoffman
-
- * Source/kwsys/SystemTools.cxx: BUG: if short path or long path
- fails return the original input
-
-2005-04-07 16:58 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: check return value of
- GetLongPath
-
-2005-04-07 16:12 hoffman
-
- * ChangeLog.manual, Source/cmSystemTools.cxx,
- Source/cmWin32ProcessExecution.cxx,
- Source/cmWin32ProcessExecution.h: Merge in fix for win32 process
- stuff
-
-2005-04-07 16:09 hoffman
-
- * Modules/Platform/Darwin.cmake, Source/cmGlobalXCodeGenerator.cxx:
- ENH: fix install test with xcode, the xcode generator does not
- support library versioning yet
-
-2005-04-07 15:09 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: BUG: Avoid converting
- the subdirectory name to a relative path twice.
-
-2005-04-07 14:41 king
-
- * Source/cmMakefile.cxx: BUG: Do not repeat paths when trying the
- lib/ to lib64/ replacement.
-
-2005-04-07 14:30 king
-
- * Source/cmMakefile.cxx: ENH: Adding automatic generation of
- several 64-bit search path forms.
-
-2005-04-07 14:27 king
-
- * Modules/: CMakeDetermineJavaCompiler.cmake, FindAVIFile.cmake,
- FindFLTK.cmake, FindGLUT.cmake, FindGTK.cmake, FindJNI.cmake,
- FindJPEG.cmake, FindJava.cmake, FindMPEG.cmake, FindMPEG2.cmake,
- FindOpenGL.cmake, FindPHP4.cmake, FindPNG.cmake,
- FindPerlLibs.cmake, FindPythonLibs.cmake, FindQt.cmake,
- FindRuby.cmake, FindSDL.cmake, FindSWIG.cmake, FindTCL.cmake,
- FindTIFF.cmake, FindX11.cmake, FindZLIB.cmake: ENH: Removing
- extra 64-bit search paths. They are now constructed
- automatically from the paths listed.
-
-2005-04-07 13:48 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: BUG: Fix rule name for
- subdirectory traversal to use relative paths. This was broken by
- the recent subdirectory changes.
-
-2005-04-07 13:46 king
-
- * Modules/: CMakeDetermineJavaCompiler.cmake, FindAVIFile.cmake,
- FindFLTK.cmake, FindGLUT.cmake, FindGTK.cmake, FindJNI.cmake,
- FindJPEG.cmake, FindJava.cmake, FindMPEG.cmake, FindMPEG2.cmake,
- FindOpenGL.cmake, FindPHP4.cmake, FindPNG.cmake,
- FindPerlLibs.cmake, FindPythonLibs.cmake, FindQt.cmake,
- FindRuby.cmake, FindSDL.cmake, FindSWIG.cmake, FindTCL.cmake,
- FindTIFF.cmake, FindX11.cmake, FindZLIB.cmake: ENH: Adding
- support for 64-bit library paths. Contributed by Peter Vanroose.
-
-2005-04-07 13:03 hoffman
-
- * Source/: CTest/cmCTestBuildHandler.cxx, kwsys/SystemTools.cxx,
- kwsys/SystemTools.hxx.in: BUG: fix for bug 1717 incorrect path
- sent to dart server
-
-2005-04-07 12:44 hoffman
-
- * Source/cmCTest.cxx: BUG: remove debug statement
-
-2005-04-07 12:12 hoffman
-
- * ChangeLog.manual, Source/cmSystemTools.cxx,
- Source/cmSystemTools.h: move fix for relative paths from main
- tree
-
-2005-04-07 12:11 hoffman
-
- * ChangeLog.manual, Source/cmCTest.cxx: BUG: fix for bug 1717 use
- the correct path for Dart server on warnings and errors
-
-2005-04-07 10:37 hoffman
-
- * ChangeLog.manual, Source/cmInstallProgramsCommand.cxx,
- Source/cmInstallProgramsCommand.h: move from main tree
-
-2005-04-07 02:31 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-04-06 16:53 king
-
- * Modules/Dart.cmake: STYLE: Fixed spelling of "memmory".
-
-2005-04-06 16:15 king
-
- * Source/cmStandardIncludes.h: BUG: Avoid duplicate definition by
- using cmsys_STL_STRING_NEQ_CHAR_DEFINED and
- cmsys_STL_STRING_NO_NEQ_CHAR.
-
-2005-04-06 16:14 king
-
- * Source/kwsys/kwsys_stl_string.hxx.in: ENH: Added proper
- namespaced version of KWSYS_STL_STRING_ISTREAM_DEFINED,
- KWSYS_STL_STRING_OSTREAM_DEFINED, and
- _STL_STRING_NEQ_CHAR_DEFINED macros.
-
-2005-04-06 15:06 king
-
- * Modules/Platform/Darwin-xlc.cmake, Modules/Platform/Darwin.cmake,
- Source/cmGlobalBorlandMakefileGenerator.cxx,
- Source/cmGlobalNMakeMakefileGenerator.cxx,
- Source/cmGlobalUnixMakefileGenerator.cxx,
- Tests/Fortran/CMakeLists.txt,
- Tests/MakeClean/ToClean/CMakeLists.txt: ENH: Removed
- CMAKE_GENERATOR_NEW now that the old unix makefile generator is
- never used.
-
-2005-04-06 13:34 king
-
- * bootstrap: BUG: The bootstrap script should perform the
- KWSYS_STL_STRING_HAVE_NEQ_CHAR test for kwsys.
-
-2005-04-06 11:56 hoffman
-
- * Source/cmMakefile.cxx: ENH: better fix for 64 bit, add 64 to the
- name of all directories in the search path
-
-2005-04-06 10:59 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: allow sub projects to use
- targets that are not part of the sub-project
-
-2005-04-06 09:47 hoffman
-
- * Source/kwsys/SystemTools.cxx: remove cerr stuff
-
-2005-04-06 09:44 hoffman
-
- * Source/kwsys/SystemTools.cxx: Fix bug in != stuff
-
-2005-04-06 04:28 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-04-05 21:10 hoffman
-
- * Source/kwsys/SystemTools.cxx: COMP: hack fix for old sgi until
- bootstrap is fixed
-
-2005-04-05 17:06 hoffman
-
- * Modules/CMakeTestCCompiler.cmake, Source/cmMakefile.cxx: BUG: try
- to address Bug 1673 .
-
-2005-04-05 16:24 hoffman
-
- * Modules/FindOpenGL.cmake: Fix for bug Bug #1287 - cmake use
- MesaGL by default instead of libGL - Return to bug list
-
-2005-04-05 14:48 hoffman
-
- * Source/cmAuxSourceDirectoryCommand.cxx: BUG: fix for bug 1636 add
- extensions to AUX_SOURCE_DIRECTORY files
-
-2005-04-05 13:39 hoffman
-
- * ChangeLog.manual, Modules/FindDCMTK.cmake: Move from main tree,
- fix for 1652
-
-2005-04-05 13:37 hoffman
-
- * Modules/FindDCMTK.cmake: BUG: fix for bug 1652
-
-2005-04-05 13:30 hoffman
-
- * ChangeLog.manual, Source/cmLocalVisualStudio7Generator.cxx: fix
- on branch for 1660 language NONE working
-
-2005-04-05 13:14 hoffman
-
- * Source/cmGlobalGenerator.cxx: BUG: fix for bug 1660
-
-2005-04-05 12:54 hoffman
-
- * ChangeLog.manual: fixes on branch
-
-2005-04-05 12:52 hoffman
-
- * Source/: cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx: BUG: fix for bug 1702 better
- error on bad GUID
-
-2005-04-05 12:51 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: move fix from main
- tree for bug 1680
-
-2005-04-05 11:23 hoffman
-
- * Source/cmake.cxx: BUG: fix for bug 1700
-
-2005-04-05 10:22 hoffman
-
- * Source/: cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx: BUG: fix for bug 1702, better
- error message for GUID missing
-
-2005-04-05 08:25 king
-
- * Source/: cmGeneratedFileStream.cxx, cmGeneratedFileStream.h: ENH:
- Added Close method and updated Open method to allow streams to be
- reused.
-
-2005-04-05 04:25 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-04-04 17:01 hoffman
-
- * ChangeLog.manual, Modules/UseSWIG.cmake,
- Source/cmGetDirectoryPropertyCommand.cxx: FIX: swig fixes from
- main tree
-
-2005-04-04 16:55 hoffman
-
- * Modules/UseSWIG.cmake: ENH: make sure source flags don't have to
- be set
-
-2005-04-04 16:43 hoffman
-
- * Source/cmGetDirectoryPropertyCommand.cxx: ENH: get directory
- property should return an empty variable if it is not set, not
- just have an error
-
-2005-04-04 16:13 hoffman
-
- * Modules/UseSWIG.cmake: ENH: fix for bug 1304
-
-2005-04-04 15:55 hoffman
-
- * ChangeLog.manual, Modules/UseSWIG.cmake: ENH: move changes from
- main tree
-
-2005-04-04 15:52 hoffman
-
- * ChangeLog.manual, Source/cmCTest.cxx: ENH: move from main tree
- timezone fix
-
-2005-04-04 15:51 hoffman
-
- * Modules/UseSWIG.cmake: FIX: fix for bug 1730
-
-2005-04-04 15:41 hoffman
-
- * ChangeLog.manual, Source/cmFileCommand.cxx,
- Source/cmWriteFileCommand.cxx, Source/kwsys/SystemTools.cxx: ENH:
- move fix for read only file configure to branch
-
-2005-04-04 12:22 andy
-
- * Modules/Dart.cmake, Source/cmAddTestCommand.cxx,
- Source/cmEnableTestingCommand.cxx, Source/cmGlobalGenerator.cxx:
- BUG: By default disable new files.
-
-2005-04-04 03:01 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-04-03 03:17 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-04-02 02:16 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-04-01 15:48 andy
-
- * Source/: cmAddTestCommand.cxx, cmEnableTestingCommand.cxx,
- cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio6Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h, cmMakefile.cxx, cmMakefile.h:
- ENH: More ctest changes and move SetupTest to superclass
-
-2005-04-01 15:45 andy
-
- * Modules/Dart.cmake, Source/cmCTest.cxx: ENH: Rename the
- DartConfiguration.tcl to CTestConfiguration.ini
-
-2005-04-01 14:57 andy
-
- * Source/: cmAddTestCommand.cxx, cmCTest.cxx, cmCTest.h,
- cmEnableTestingCommand.cxx, ctest.cxx,
- CTest/cmCTestTestHandler.cxx: ENH: Start adding support for CTest
- testfiles
-
-2005-04-01 02:17 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-31 18:03 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: BUG: When generating
- the name of the custom rule file the character : should be
- replaced with an underscore because it might be a non-file-name
- part of a path.
-
-2005-03-31 11:57 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: BUG: fix ITK build with xcode,
- as long as you build it in little parts, this fixes the headermap
- problem
-
-2005-03-31 10:00 martink
-
- * CTestCustom.ctest.in: ENH: shut up warning in 3rd party packages
-
-2005-03-31 02:20 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-30 16:11 king
-
- * Source/cmCTest.cxx: BUG: It is possible for the nightly start
- time to be over 24 hours in the future which requires two days to
- be subtracted. Using a while loop to make sure enough days are
- added or subtracted. It should never be able to iterate more
- than twice.
-
-2005-03-30 15:41 hoffman
-
- * ChangeLog.manual, Source/cmLocalVisualStudio7Generator.cxx: FIX:
- Merge from main tree: fix for VS 2005 beta
-
-2005-03-30 15:27 king
-
- * Source/kwsys/CMakeLists.txt: BUG: Test for stl stirng operator!=
- for char* needs to know result of KWSYS_STL_HAVE_STD.
-
-2005-03-30 02:19 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-29 15:34 martink
-
- * Source/: cmGlobalGenerator.cxx, cmMakefile.cxx, cmMakefile.h:
- ENH: removed GetParentProjects
-
-2005-03-29 15:33 martink
-
- * Tests/OutOfSource/SubDir/CMakeLists.txt: ENH: better test for
- subdirs
-
-2005-03-29 15:26 henderson
-
- * Source/kwsys/: CMakeLists.txt, SharedForward.h.in: ENH: copying
- Brad's installation changes from the main tree to the ParaView
- 2.0 branch
-
-2005-03-29 10:34 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: BUG: Fix dependencies of custom
- commands that are relative paths to files or other custom command
- outputs.
-
-2005-03-29 10:10 king
-
- * Source/kwsys/: CMakeLists.txt, Configure.hxx.in,
- kwsysPlatformCxxTests.cxx, kwsys_stl_string.hxx.in: ENH: Added
- operator!= for stl string and char* when the system does not
- provide one.
-
-2005-03-29 08:20 king
-
- * bootstrap, Source/kwsys/CMakeLists.txt,
- Source/kwsys/Configure.hxx.in,
- Source/kwsys/kwsysPlatformCxxTests.cmake,
- Source/kwsys/kwsysPlatformCxxTests.cxx,
- Source/kwsys/kwsys_stl.h.in, Source/kwsys/kwsys_stl.hxx.in,
- Source/kwsys/kwsys_stl_string.hxx.in: ENH: Added istream and
- ostream operators for stl string in KWSys when using old streams
- that do not provide them.
-
-2005-03-29 08:09 king
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH:
- SplitPath now supports slashes in both directions in the input
- path but still produces forward slashes in the root component.
-
-2005-03-29 02:21 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-28 18:00 andy
-
- * bootstrap: BUG: The is replaced by cvs... This is safer anyway
-
-2005-03-28 17:46 barre
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH: move
- EstimateFormatLength to kwsys
-
-2005-03-28 02:12 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-27 02:18 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-26 09:58 king
-
- * Source/kwsys/: CMakeLists.txt, Configure.hxx.in,
- kwsysPlatformCxxTests.cmake, kwsysPlatformCxxTests.cxx,
- kwsys_stl.h.in, kwsys_stl.hxx.in, kwsys_stl_string.hxx.in: COMP:
- Removing stl string io operators change until the CMake bootstrap
- script can be fixed.
-
-2005-03-26 08:19 king
-
- * Source/kwsys/: CMakeLists.txt, Configure.hxx.in,
- kwsysPlatformCxxTests.cmake, kwsysPlatformCxxTests.cxx,
- kwsys_stl.h.in, kwsys_stl.hxx.in, kwsys_stl_string.hxx.in: ENH:
- Added istream and ostream operators for stl string when using old
- streams that do not provide them.
-
-2005-03-26 02:22 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-25 18:55 andy
-
- * Source/CMakeLists.txt: ENH: When in-source build, do not do
- bootstrap test
-
-2005-03-25 18:46 andy
-
- * Source/CMakeLists.txt: ENH: Remove curl build testing
-
-2005-03-25 16:40 king
-
- * Source/cmAddSubDirectoryCommand.h: ENH: Clarified documentation
- of the command.
-
-2005-03-25 14:23 andy
-
- * bootstrap: ENH: For development versions report version when
- doing bootstrap
-
-2005-03-25 08:41 king
-
- * Source/kwsys/: CMakeLists.txt, SharedForward.h.in: ENH: Adding
- SharedForward C header to help create forwarding executables on
- UNIX systems that configure the shared library runtime search
- path and then replace themselves with the real executable. This
- is useful to create binary distributions that work from any
- extracted location even with shared libraries.
-
-2005-03-25 08:09 king
-
- * Source/kwsys/SystemTools.cxx: ENH: Re-implemented
- CollapseFullPath to not need to change directories. Operation is
- now fully string based.
-
-2005-03-25 08:05 king
-
- * Source/cmCTest.cxx: BUG: Adjusted GetNightlyTime computation to
- not depend on time_t being a signed type.
-
-2005-03-25 02:16 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-24 02:25 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-23 08:20 hoffman
-
- * Source/cmBuildCommand.cxx: fix for xcode
-
-2005-03-23 02:22 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-22 14:27 hoffman
-
- * Source/cmDynamicLoader.h: FIX: fix bug 1690
-
-2005-03-22 14:00 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: try to handle more source
- file types
-
-2005-03-22 13:32 andy
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: just use the file name
-
-2005-03-22 11:33 hoffman
-
- * Source/cmGlobalGenerator.cxx: ENH: make sure project map is
- cleared each time.
-
-2005-03-22 10:29 andy
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: use better names for
- files
-
-2005-03-22 10:23 king
-
- * Source/cmMakefile.cxx: BUG: Initializing from parent should copy
- link directories as well.
-
-2005-03-22 08:36 king
-
- * Source/: cmAddCustomCommandCommand.cxx,
- cmAddCustomTargetCommand.cxx: ENH: Added check for invalid
- characters in output name.
-
-2005-03-22 07:27 hoffman
-
- * Source/cmLocalGenerator.cxx: ENH: remove commented code
-
-2005-03-22 07:26 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: ENH: fix adding of rc
- files
-
-2005-03-22 02:24 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-21 02:32 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-20 02:34 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-19 09:05 martink
-
- * Source/cmGlobalGenerator.cxx: COMP: fix warning
-
-2005-03-19 02:38 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-18 11:29 martink
-
- * Source/cmMacroCommand.cxx: COMP: fix warning
-
-2005-03-18 10:58 martink
-
- * Source/: cmLocalUnixMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator.h: ENH: remove cmSubDirectory from
- unused files?
-
-2005-03-18 10:41 martink
-
- * Source/cmAddDefinitionsCommand.h, Source/cmAddTestCommand.cxx,
- Source/cmBootstrapCommands.cxx, Source/cmBuildCommand.h,
- Source/cmBuildNameCommand.h, Source/cmCMakeMinimumRequired.h,
- Source/cmCommand.h, Source/cmCreateTestSourceList.h,
- Source/cmElseCommand.h, Source/cmEnableLanguageCommand.h,
- Source/cmEnableTestingCommand.cxx,
- Source/cmEnableTestingCommand.h, Source/cmEndForEachCommand.h,
- Source/cmEndIfCommand.h, Source/cmEndWhileCommand.h,
- Source/cmFileCommand.h, Source/cmFindFileCommand.h,
- Source/cmFindLibraryCommand.h, Source/cmFindPackageCommand.cxx,
- Source/cmFindPackageCommand.h, Source/cmFindPathCommand.h,
- Source/cmFindProgramCommand.h, Source/cmForEachCommand.h,
- Source/cmGetFilenameComponentCommand.h,
- Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmIfCommand.h, Source/cmIncludeCommand.h,
- Source/cmIncludeDirectoryCommand.h,
- Source/cmIncludeRegularExpressionCommand.h,
- Source/cmLinkDirectoriesCommand.h,
- Source/cmLinkLibrariesCommand.h, Source/cmLoadCacheCommand.h,
- Source/cmLoadCommandCommand.cxx, Source/cmLoadCommandCommand.h,
- Source/cmLocalGenerator.cxx, Source/cmLocalGenerator.h,
- Source/cmLocalKdevelopGenerator.cxx,
- Source/cmLocalKdevelopGenerator.h,
- Source/cmLocalUnixMakefileGenerator2.cxx,
- Source/cmLocalUnixMakefileGenerator2.h,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio6Generator.h,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h,
- Source/cmMacroCommand.cxx, Source/cmMacroCommand.h,
- Source/cmMakefile.cxx, Source/cmMakefile.h,
- Source/cmMarkAsAdvancedCommand.h, Source/cmOptionCommand.h,
- Source/cmProjectCommand.h, Source/cmRemoveCommand.h,
- Source/cmRemoveDefinitionsCommand.h,
- Source/cmSeparateArgumentsCommand.h, Source/cmSetCommand.h,
- Source/cmSetDirectoryPropertiesCommand.h,
- Source/cmSiteNameCommand.h, Source/cmSourceGroupCommand.h,
- Source/cmStringCommand.h, Source/cmSubdirCommand.cxx,
- Source/cmUtilitySourceCommand.h, Source/cmWhileCommand.h,
- Tests/OutOfSource/CMakeLists.txt,
- Tests/OutOfSource/SubDir/CMakeLists.txt: ENH: big change that
- includes immediate subdir support, removing the notion of
- inherited commands, makefiles no longer read in the parent
- makefiles but instead inherit thier parent makefiles current
- settings
-
-2005-03-18 10:39 martink
-
- * Source/: cmAddSubDirectoryCommand.cxx,
- cmAddSubDirectoryCommand.h: ENH: added immediate subdirectory
- command
-
-2005-03-18 09:03 martink
-
- * Source/cmSubDirectory.h: ENH: bad idea
-
-2005-03-18 02:34 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-17 18:37 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: BUG: Need to collapse
- full paths before depending on them to remove ./ and ../ to make
- sure target names match.
-
-2005-03-17 15:35 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h:
- ENH: add source groups xcode
-
-2005-03-17 13:06 king
-
- * Source/kwsys/SystemTools.cxx: COMP: Using proper __QNX__
- preprocessor test.
-
-2005-03-17 02:41 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-16 13:26 andy
-
- * CMakeLists.txt, Utilities/cmexpat/CMakeLists.txt,
- Utilities/cmzlib/CMakeLists.txt: COMP: More cleanups
-
-2005-03-16 12:54 andy
-
- * Source/CMakeLists.txt: ENH: Make sure to use internal zlib
-
-2005-03-16 12:54 andy
-
- * Source/CTest/cmCTestSubmit.cxx: ENH: Cleanup of the output
-
-2005-03-16 10:49 king
-
- * Source/kwsys/SystemTools.cxx: COMP: Only include malloc.h on QNX.
-
-2005-03-16 10:15 barre
-
- * Source/kwsys/SystemTools.cxx: FIX: that was wrong
-
-2005-03-16 09:55 king
-
- * Source/CMakeLists.txt, Tests/Wrapping/CMakeLists.txt: BUG: Do not
- add Qt wrapping test unless QT is found and QT_UIC_EXECUTABLE is
- found.
-
-2005-03-16 09:41 king
-
- * Source/kwsys/SystemTools.cxx: COMP: Need malloc.h for malloc/free
- on QNX.
-
-2005-03-16 02:35 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-15 11:22 martink
-
- * Source/cmEnableTestingCommand.cxx: ENH: only support rel paths
- for now
-
-2005-03-15 08:14 king
-
- * Source/: cmListFileLexer.c, cmListFileLexer.in.l: COMP: Defining
- YY_NO_INPUT to remove compilation of unused yyinput function. It
- was producing a warning about unreachable code.
-
-2005-03-15 08:13 king
-
- * Source/cmCacheManager.cxx: COMP: Removed warning due to unsigned
- enum type.
-
-2005-03-15 02:38 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-14 13:23 hoffman
-
- * Source/: CMakeLists.txt, cmake.cxx: ENH: make xcode compile only
- on apple
-
-2005-03-14 12:25 martink
-
- * bootstrap: ENH: oops forgot to chek this in
-
-2005-03-14 12:18 hoffman
-
- * Modules/Platform/QNX.cmake: ENH: try to fix rpath on qnx
-
-2005-03-14 11:28 martink
-
- * Source/: CMakeLists.txt, cmEnableTestingCommand.cxx,
- cmGlobalGenerator.cxx, cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx, cmLocalGenerator.cxx,
- cmLocalGenerator.h, cmLocalUnixMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator.h,
- cmLocalUnixMakefileGenerator2.cxx, cmMakefile.cxx, cmMakefile.h,
- cmSubdirCommand.cxx, cmGlobalVisualStudio6Generator.cxx: ENH: add
- support for out of source source
-
-2005-03-14 11:26 martink
-
- * Tests/OutOfSource/: CMakeLists.txt,
- OutOfSourceSubdir/CMakeLists.txt, OutOfSourceSubdir/simple.cxx,
- SubDir/CMakeLists.txt: ENH: added new test for out of dir source
- trees
-
-2005-03-14 09:23 martink
-
- * Source/cmSubDirectory.h: ENH: added new structure to hold
- subdirectories
-
-2005-03-14 08:15 king
-
- * Source/: cmDependsFortranParser.cxx, cmDependsFortranParser.y:
- COMP: Added __INTEL_COMPILER to test for yyerrorlab warning
- suppression.
-
-2005-03-14 03:18 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-13 03:01 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-12 02:35 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-11 13:12 hoffman
-
- * Tests/: Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/complex.cxx: ENH: try to see if
- there is still a problem
-
-2005-03-11 12:56 king
-
- * Source/CTest/cmCTestScriptHandler.cxx: BUG: Do not report an
- error removing the binary directory if it doesn't exist.
-
-2005-03-11 11:48 barre
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH: add last
- two small funcs from vtkString. Done removing deps
-
-2005-03-11 10:53 andy
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h:
- FIX: fix crashing test SubDir for xcode
-
-2005-03-11 10:43 barre
-
- * Source/kwsys/: SystemTools.hxx.in, SystemTools.cxx: ENH: update
- documentation, sort methods into categories
-
-2005-03-11 10:29 hoffman
-
- * Source/ctest.cxx: FIX: fix output of passing tests
-
-2005-03-11 10:15 king
-
- * Modules/Platform/QNX.cmake: ENH: Initial attempt at QNX support.
- Submitted by Tim Arney.
-
-2005-03-11 10:07 king
-
- * Source/kwsys/: CommandLineArguments.cxx, RegularExpression.cxx,
- SystemTools.cxx: COMP: Added missing include of string.h.
-
-2005-03-11 10:03 king
-
- * Source/cmStandardIncludes.h: COMP: Adding stdlib.h to standard
- includes. We are using functions from it all over the place
- assuming it has been included here.
-
-2005-03-11 09:31 barre
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: COMP: fix
- some warnings
-
-2005-03-11 08:38 martink
-
- * Source/cmake.cxx: COMP: fix a warning
-
-2005-03-11 02:32 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-10 17:49 barre
-
- * Source/kwsys/SystemTools.cxx: ENH: remove deps to vtkString by
- using KWSys (a handful of functions have been moved to KWSys)
-
-2005-03-10 17:44 barre
-
- * Source/kwsys/: SystemTools.hxx.in, SystemTools.cxx: ENH: remove
- deps to vtkString by using KWSys (a handful of functions have
- been moved to KWSys)
-
-2005-03-10 17:34 barre
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH: remove
- deps to vtkString by using KWSys (a handful of functions have
- been moved to KWSys)
-
-2005-03-10 13:39 martink
-
- * Source/: cmExportLibraryDependencies.cxx, cmGlobalGenerator.cxx,
- cmGlobalGenerator.h, cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h, cmMakefile.cxx, cmMakefile.h,
- cmTryCompileCommand.cxx, cmTryRunCommand.cxx, cmake.cxx, cmake.h:
- ENH: cleanup by removing all the olf local generate junk that i
- not longer needed
-
-2005-03-10 12:50 barre
-
- * Source/kwsys/: SystemTools.hxx.in, SystemTools.cxx: ENH: move
- function from vtkKWDirectoryUtilities and vtkString to
- SystemTools
-
-2005-03-10 10:04 martink
-
- * Source/ctest.cxx: ENH: better docs
-
-2005-03-10 02:26 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-09 18:06 andy
-
- * Source/CTest/cmCTestSubmit.cxx: BUG: xmlrpc does the base64
- encoding
-
-2005-03-09 15:51 andy
-
- * bootstrap: BUG: Remove awk, remove problems and add full spaces
- in the path support
-
-2005-03-09 02:26 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-08 18:38 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: BUG: Removing
- jump-and-build ordering change until we can prevent extra jumps
- from always occuring.
-
-2005-03-08 17:27 king
-
- * bootstrap: BUG: Fix for spaces in the path when constructing
- cmBootstrapCommands dependencies.
-
-2005-03-08 16:01 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: ENH: Removing ...
- ellipsis from end of echo lines. It is just clutter.
-
-2005-03-08 15:55 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: ENH: Adding extra
- dependencies to jump-and-build rules that force a single ordering
- to prevent parallel jumps. This avoids problems with two jumps
- reaching the same target in parallel which happened occasionally
- with the old generator.
-
-2005-03-08 15:35 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: ENH: Removed "Checking
- build system in ..." message. It is always paired with an
- Entering or Jumping message and is not necessary.
-
-2005-03-08 13:43 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Added option
- CMAKE_SKIP_RULE_DEPENDENCY to skip making build rules depend on
- their own rule files. It can be added to the cache by the user
- or added by the project in a list file.
-
-2005-03-08 11:37 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: BUG: Only add leading
- ./ to custom command executable if the command is really
- specified as one in the current directory.
-
-2005-03-08 11:25 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: BUG: When a custom
- command's executable is in the current directory the relative
- path to it needs a "./".
-
-2005-03-08 09:25 king
-
- * Source/: cmLocalKdevelopGenerator.cxx,
- cmLocalKdevelopGenerator.h: ENH: Updating Kdevelop generator to
- use the new makefile generator. The old one no longer works
- anyway because local generates are now disabled.
-
-2005-03-08 09:24 king
-
- * Source/cmDepends.cxx: BUG: Dependency scans and checks must
- always set the current working directory to the directory
- containing the Makefile.
-
-2005-03-08 02:26 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-07 15:19 king
-
- * Source/cmDependsFortran.cxx: BUG: When checking for upper-case
- modules do not use an upper-case .MOD extension.
-
-2005-03-07 13:51 andy
-
- * Source/: cmFileCommand.cxx, cmWriteFileCommand.cxx: BUG: Handle
- restrictive permissions
-
-2005-03-07 12:14 andy
-
- * Source/CTest/cmCTestSubmit.cxx: COMP: Remove warning
-
-2005-03-07 12:11 andy
-
- * bootstrap: ENH: Add proper dependencies for cmBootstrapCommands
-
-2005-03-07 02:28 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-06 08:51 andy
-
- * DartConfig.cmake, Source/cmCTest.cxx,
- Source/CTest/cmCTestSubmit.cxx: COMP: Remove warning and fix the
- logic
-
-2005-03-06 08:17 andy
-
- * Source/CMakeLists.txt: COMP: Do not build cmw9xcom on Cygwin
-
-2005-03-06 02:27 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-05 08:25 andy
-
- * DartConfig.cmake: ENH: Work on xmlrpc submit
-
-2005-03-05 08:12 andy
-
- * Source/CTest/cmCTestSubmit.cxx: COMP: Remove compile error
-
-2005-03-05 02:21 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-04 17:11 andy
-
- * Source/: CTest/cmCTestSubmit.cxx, CTest/cmCTestSubmit.h,
- cmCTest.cxx: ENH: Start working on xmlrpc code. This code does
- not work, but it will at least test compiling with cmxmlrpc
-
-2005-03-04 14:27 andy
-
- * CMakeLists.txt, Source/CMakeLists.txt: ENH: More cleanups and
- start linking ctest to XML-RPC
-
-2005-03-04 11:37 andy
-
- * Source/CMakeLists.txt, CMakeLists.txt, Utilities/CMakeLists.txt:
- ENH: More cleanups and reorganization
-
-2005-03-04 10:05 andy
-
- * CMakeLists.txt, Source/CMakeLists.txt: ENH: Cleanups
-
-2005-03-04 10:04 andy
-
- * Source/CTest/CMakeLists.txt: BUG: This cmakelists file is not
- used any more
-
-2005-03-04 10:03 andy
-
- * bootstrap: BUG: Handle when initial cmake fails
-
-2005-03-04 02:25 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-03 22:35 hoffman
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalXCodeGenerator.cxx: ENH: fix for finding the correct
- target in the current project
-
-2005-03-03 19:42 hoffman
-
- * Tests/: Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/complex.cxx: ENH: make it pass
- anyway so I can see debug info
-
-2005-03-03 18:46 hoffman
-
- * Source/cmOrderLinkDirectories.cxx,
- Source/cmOrderLinkDirectories.h,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/complex.cxx: ENH: try and
- debug the failed test on the continuous
-
-2005-03-03 18:15 hoffman
-
- * Source/cmOrderLinkDirectories.cxx,
- Source/cmOrderLinkDirectories.h,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/complex.cxx: ENH: try
- number two with topological sort
-
-2005-03-03 16:53 king
-
- * Source/: cmDependsFortran.cxx, cmDependsFortran.h, cmake.cxx:
- ENH: Implementing explicit cmake_copy_f90_mod callback to copy
- Fortran90 modules to the stamp files more reliably. This removes
- the temporary hack for per-platform upper-/lower- case.
-
-2005-03-03 15:22 king
-
- * Source/: cmDependsC.cxx, cmDependsC.h: BUG: Fixed scanning to
- account for double-quote includes.
-
-2005-03-03 12:00 king
-
- * Source/kwsys/kwsys_ios_sstream.h.in: ENH: Added
- "ostringstream(const kwsys_stl::string& s)" and "void str(const
- kwsys_stl::string& s)" compatibility methods.
-
-2005-03-03 08:46 martink
-
- * Source/: CMakeLists.txt, cmake.cxx: ENH: remove code warrior
- classes
-
-2005-03-03 02:26 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-02 18:56 hoffman
-
- * Source/cmOrderLinkDirectories.cxx,
- Source/cmOrderLinkDirectories.h,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/complex.cxx: ENH: reverse
- last changes to avoid dashboard failures
-
-2005-03-02 17:49 hoffman
-
- * Source/cmOrderLinkDirectories.cxx,
- Source/cmOrderLinkDirectories.h,
- Tests/Complex/Executable/CMakeLists.txt,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/complex.cxx: ENH: fix
- library ordering stuff to use a topological sort
-
-2005-03-02 11:48 andy
-
- * Source/cmOrderLinkDirectories.cxx: BUG: Attempt to fix sorting
- stability using more deterministic compare function
-
-2005-03-02 10:58 martink
-
- * Source/: cmGlobalCodeWarriorGenerator.cxx,
- cmGlobalCodeWarriorGenerator.h, cmLocalCodeWarriorGenerator.cxx,
- cmLocalCodeWarriorGenerator.h: ENH: now use xcode instead
-
-2005-03-02 09:34 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: BUG: Pay attention to
- ForceUnixPaths setting in cmSystemTools for
- ConvertToQuotedOutputPath and for dependency scanning.
-
-2005-03-02 09:02 king
-
- * Source/cmDependsFortran.cxx: BUG: We need to test the compiler
- for the case of the mod file names. For now this is a temporary
- hack to use upper case on SGI and lower case on Sun.
-
-2005-03-02 08:51 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: BUG: SGI make can
- support suffixes only up to 32 characters. Renaming
- .hpux_make_must_have_suffixes_list to
- .hpux_make_needs_suffix_list.
-
-2005-03-02 02:30 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-03-01 17:32 hoffman
-
- * Source/cmOrderLinkDirectories.cxx: FIX: switch to stable_sort to
- avoid crash
-
-2005-03-01 14:30 andy
-
- * Modules/Dart.cmake: BUG: Change error to warning
-
-2005-03-01 14:21 andy
-
- * CMakeLists.txt: COMP: CMake should be build static. Also
- propagate build_shared_libs to curl
-
-2005-03-01 13:36 king
-
- * Source/cmDependsFortran.cxx: BUG: Module file names are case
- insensitive. Always use lower case no matter the real name of
- the module.
-
-2005-03-01 13:32 king
-
- * Source/cmDependsJava.cxx: COMP: Removed unused parameter warning.
-
-2005-03-01 12:27 king
-
- * Source/: cmGlobalBorlandMakefileGenerator.cxx,
- cmGlobalNMakeMakefileGenerator.cxx: ENH: Enabling
- cmLocalUnixMakefileGenerator2 by default.
-
-2005-03-01 12:26 king
-
- * Modules/Platform/: Darwin-xlc.cmake, Darwin.cmake: ENH: Adding
- support for shared library versioning using the -install_name
- option on the OSX linker. This is actually needed to support
- relative -o paths which are used by
- cmLocalUnixMakefileGenerator2.
-
-2005-03-01 12:26 king
-
- * bootstrap, Source/cmGlobalUnixMakefileGenerator.cxx,
- Source/cmake.cxx: ENH: Enabling cmLocalUnixMakefileGenerator2
- (new makefile generator) by default.
-
-2005-03-01 12:20 king
-
- * Source/: cmDependsJava.cxx, cmDependsJava.h, CMakeLists.txt,
- cmLocalUnixMakefileGenerator2.cxx: ENH: Framework for java
- dependency scanner. Right now it does nothing but always reports
- success. This is enough to get the Java test to pass with the
- new generator because the old implementation did not do
- dependencies anyway.
-
-2005-03-01 12:13 king
-
- * Source/: cmInstallProgramsCommand.cxx,
- cmInstallProgramsCommand.h: BUG: Added FILES mode to
- INSTALL_PROGRAMS command to make the single argument case
- unambiguous.
-
-2005-03-01 11:25 andy
-
- * Source/cmGlobalXCodeGenerator.cxx: FIX: fix spaces in paths
-
-2005-03-01 10:54 andy
-
- * CMakeLists.txt: ENH: Enable XMLRPC... please do not break
- everywhere...
-
-2005-03-01 10:05 king
-
- * Source/cmLocalVisualStudio6Generator.cxx: BUG: Replaced previous
- fix with an implementation of properly formatting the custom
- build code in the generated file.
-
-2005-03-01 02:28 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-02-28 17:12 andy
-
- * CMakeLists.txt: ENH: Add the rest of xmlrpc stuff
-
-2005-02-28 16:11 martink
-
- * Source/cmLocalVisualStudio6Generator.cxx: FIXTHIS THING: fix the
- bug
-
-2005-02-28 15:30 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: fix typeo
-
-2005-02-28 15:07 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h:
- ENH: add re run cmake if inputs change
-
-2005-02-28 02:25 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-02-27 17:36 andy
-
- * Source/kwsys/ProcessUNIX.c: COMP: Remove warnings about shadow
- variables
-
-2005-02-27 17:33 andy
-
- * Utilities/cmexpat/xmlparse.c: COMP: Remove compile warning about
- shadow variables
-
-2005-02-27 03:04 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-02-26 16:58 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: COMP: remove some warnings
-
-2005-02-26 03:02 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-02-25 20:46 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: COMP: fix warning
-
-2005-02-25 17:45 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmOrderLinkDirectories.cxx,
- cmOrderLinkDirectories.h: ENH: clean up and use order link
- directories
-
-2005-02-25 14:21 hoffman
-
- * Utilities/cmexpat/xmltok_impl.c: COMP: fix warnings
-
-2005-02-25 14:20 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: make sure header files
- are in the header file group
-
-2005-02-25 11:23 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Replaced
- OutputEcho/pre-echo/post-echo with AppendEcho. This allows for
- more flexible echo specifications and better preserves echo text.
-
-2005-02-25 09:31 king
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- Complex/Executable/complex.cxx, Complex/Library/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexOneConfig/Library/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/complex.cxx,
- ComplexRelativePaths/Library/CMakeLists.txt: ENH: Added full
- pre-build/pre-link/post-build testing for both library and
- executable targets.
-
-2005-02-25 09:19 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: ENH: Adding inclusion
- of pre-build and pre-link commands when building executables and
- libraries.
-
-2005-02-25 09:14 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: BUG:
- ConvertToQuotedOutputPath must replace slashes in root component
- on windows.
-
-2005-02-25 09:06 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Added
- ConvertToQuotedOutputPath method and used it to properly generate
- external object references with spaces in the path.
-
-2005-02-25 03:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-02-24 19:32 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: Removed instances
- of calling ConvertToRelativeOutputPath twice on the same path.
-
-2005-02-24 19:28 king
-
- * Source/cmGlobalGenerator.cxx: BUG: Need to configure relative
- path support for LocalGenerate to support old makefile generator.
-
-2005-02-24 18:35 king
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: ENH: Converted some
- ConvertToRelativeOutputPath calls to
- ConvertToOptionallyRelativeOutputPath in preparation for making
- ConvertToRelativeOutputPath always convert. Some of these might
- be able to be switched back but we will first have to test what
- paths can be relative in the generate VS project files.
-
-2005-02-24 17:46 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h,
- kwsys/SystemTools.cxx: ENH: fix relative paths in xcode
-
-2005-02-24 16:25 king
-
- * Source/cmLocalGenerator.cxx: ENH: Converted some
- ConvertToRelativeOutputPath calls to
- ConvertToOptionallyRelativeOutputPath in preparation for making
- ConvertToRelativeOutputPath not check CMAKE_USE_RELATIVE_PATHS.
-
-2005-02-24 16:19 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: BUG: The path to the
- source file in a compile line should be made relative only when
- CMAKE_USE_RELATIVE_PATHS is on.
-
-2005-02-24 16:04 king
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmLocalGenerator.cxx, cmLocalGenerator.h,
- cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Merged implementations of
- ConvertToRelative*Path methods. The main ConvertToRelativePath
- method is now in cmGlobalGenerator. It converts paths only if
- they are at least inside the deepest common directory between the
- top-level source and build trees. Each cmLocalGenerator instance
- calls this global method with its own output directory as the
- "local" argument from which paths are relative. Added separate
- ConvertToOptionallyRelative path that pays attention to the
- CMAKE_USE_RELATIVE_PATHS option.
-
-2005-02-24 15:36 andy
-
- * Source/cmOrderLinkDirectories.cxx: COMP: remove compiler warning
-
-2005-02-24 15:34 andy
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h:
- ENH: fix spaces in paths problems
-
-2005-02-24 14:47 king
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH: Added
- ComparePath method.
-
-2005-02-24 14:27 hoffman
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h: ENH: remove
- unused code
-
-2005-02-24 13:45 king
-
- * Source/cmMakefile.cxx: COMP: HP compiler does not like
- initializing a const std::string & with a const char* (which
- requires the reference to be bound to a temporary with the scope
- of the reference).
-
-2005-02-24 13:26 hoffman
-
- * Source/cmOrderLinkDirectories.cxx: ENH: clean up and remove some
- debug code
-
-2005-02-24 13:16 hoffman
-
- * bootstrap, Source/CMakeLists.txt, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h, Source/cmOrderLinkDirectories.cxx,
- Source/cmOrderLinkDirectories.h: ENH: add a new library path
- ordering algorithm to make sure -L paths will pick the correct
- libraries if possible
-
-2005-02-24 12:44 king
-
- * Source/cmDependsC.cxx: BUG: Avoid putting a leading ./ on the
- dependency names.
-
-2005-02-24 12:19 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: BUG: Using a better technique to
- produce the rule file name for a custom command when the output
- is not in the current directory or lower.
-
-2005-02-24 11:46 king
-
- * Modules/Platform/CMakeLists.txt: BUG: Added installation of .in
- files as well as .cmake files.
-
-2005-02-24 10:32 king
-
- * Source/cmGlobalGenerator.cxx: BUG: Only use the existing
- CMake(lang)Compiler.cmake file from the build tree if it was
- generated by the same version of CMake.
-
-2005-02-24 10:31 king
-
- * Source/cmMakefile.cxx: BUG: Fixed GetCacheMinorVersion to not
- always return 0.
-
-2005-02-24 10:14 andy
-
- * Source/cmCommands.cxx: COMP: Remove compile warning in bootstrap
- stage
-
-2005-02-24 09:21 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: BUG: Do not crash when
- the link language for a target is not known.
-
-2005-02-24 09:20 king
-
- * Source/cmLocalVisualStudio6Generator.cxx: BUG: Need proper
- newline argument to ConstructScript call.
-
-2005-02-24 03:46 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-02-23 20:41 andy
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: remove output path stuff
-
-2005-02-23 14:36 martink
-
- * Source/cmGlobalVisualStudio6Generator.cxx: BUG: fix for empty
- target or config strings in the Build method
-
-2005-02-23 13:50 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: FIX: fix to make this work
- with new custom command stuff
-
-2005-02-23 03:03 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-02-22 15:31 king
-
- * Source/cmProjectCommand.cxx: ENH: Added CMAKE_PROJECT_NAME
- variable to play the role of CMAKE_SOURCE_DIR and
- CMAKE_BINARY_DIR for the top-level project name.
-
-2005-02-22 15:22 king
-
- * Modules/CMakeGenericSystem.cmake, Source/cmLocalGenerator.cxx:
- ENH: Added better default install location for windows builds.
- The previous default /usr/local did not make much sense. Now
- "%SystemDrive%/Program Files/PROJECT_NAME" is used, which is the
- windows equivalent to /usr/local.
-
-2005-02-22 14:52 king
-
- * Source/: cmLoadCommandCommand.cxx, cmLoadCommandCommand.h: ENH:
- LOAD_COMMAND command will now set a variable called
- CMAKE_LOADED_COMMAND_<COMMAND_NAME> to the full path of the
- loaded module if loading was successful. Otherwise the variable
- is not set (will evaluate to empty string). This is useful both
- in testing whether loading worked and for installing loaded
- command modules.
-
-2005-02-22 12:34 martink
-
- * Source/cmGlobalGenerator.cxx: COMP: fix warning
-
-2005-02-22 12:10 king
-
- * Source/cmAddCustomCommandCommand.h: BUG: Fixed formatting of
- generated documentation.
-
-2005-02-22 12:04 king
-
- * Tests/CustomCommand/CMakeLists.txt: ENH: Added test for multiple
- commands in a custom command.
-
-2005-02-22 10:43 martink
-
- * Source/CMakeLists.txt: BUG: fix test execution
-
-2005-02-22 10:42 martink
-
- * Source/cmCTest.cxx: BUG: better error handling
-
-2005-02-22 10:32 king
-
- * Source/: cmAddCustomCommandCommand.cxx,
- cmAddCustomCommandCommand.h, cmAddCustomTargetCommand.cxx,
- cmAddCustomTargetCommand.h, cmCPluginAPI.cxx,
- cmCustomCommand.cxx, cmCustomCommand.h, cmFLTKWrapUICommand.cxx,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx, cmGlobalXCodeGenerator.cxx,
- cmITKWrapTclCommand.cxx, cmIncludeExternalMSProjectCommand.cxx,
- cmLocalGenerator.cxx, cmLocalGenerator.h,
- cmLocalUnixMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator2.cxx,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx, cmMakefile.cxx, cmMakefile.h,
- cmQTWrapCPPCommand.cxx, cmQTWrapUICommand.cxx,
- cmVTKWrapJavaCommand.cxx, cmVTKWrapPythonCommand.cxx,
- cmVTKWrapTclCommand.cxx: ENH: Updated implementation of custom
- commands. Multiple command lines are now supported effectively
- allowing entire scripts to be written. Also removed extra
- variable expansions and cleaned up passing of commands through to
- the generators. The command and individual arguments are now
- kept separate all the way until the generator writes them out.
- This cleans up alot of escaping issues.
-
-2005-02-22 09:12 martink
-
- * Source/: cmCTest.cxx, cmCTest.h, cmGlobalGenerator.cxx,
- cmGlobalGenerator.h, cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio6Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h, cmGlobalXCodeGenerator.cxx,
- cmGlobalXCodeGenerator.h, ctest.cxx: ENH: ctest now uses CMake
- global generator to do the build part of build-and-test
-
-2005-02-22 09:08 king
-
- * Source/cmake.cxx: BUG: Need to return before configure step when
- running in script mode.
-
-2005-02-22 08:22 king
-
- * Source/cmStandardIncludes.h: ENH: Adding cmCustomCommandLine and
- cmCustomCommandLines subclasses of std::vector instantiations to
- represent multiple commands for a single custom command. These
- will be used in an upcoming checkin.
-
-2005-02-22 03:01 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-02-21 03:07 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-02-20 03:13 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-02-19 02:43 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-02-18 16:19 king
-
- * Source/: cmMakefile.cxx, cmSourceFile.cxx, cmSourceFile.h: BUG:
- cmSourceFile instances should delete their own custom commands
- when a new one is set.
-
-2005-02-18 16:12 king
-
- * Source/cmTarget.cxx: COMP: Using const_iterator instead of
- iterator to walk through custom command dependencies.
-
-2005-02-18 16:12 king
-
- * Source/cmTarget.h: COMP: Added missing forward declaration of
- cmMakefile. This was only working because cmCustomCommand.h
- declared it.
-
-2005-02-18 15:45 andy
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: fix for spaces in the
- path
-
-2005-02-18 15:43 king
-
- * Tests/ExternalOBJ/CMakeLists.txt: BUG: We still want to print out
- the location where the object was found if it was found by the
- glob.
-
-2005-02-18 14:32 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: COMP: remove warning
-
-2005-02-18 14:22 king
-
- * CMakeLists.txt: BUG: Disabling DART_ROOT removal until we can get
- Dart to submit without it.
-
-2005-02-18 13:32 hoffman
-
- * Source/CMakeLists.txt, Source/cmFileCommand.cxx,
- Source/cmGlobalXCodeGenerator.cxx,
- Source/cmGlobalXCodeGenerator.h, Source/cmLocalGenerator.cxx,
- Tests/ExternalOBJ/CMakeLists.txt: ENH: all tests are passing for
- XCode
-
-2005-02-18 02:44 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-02-17 17:54 hoffman
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalXCodeGenerator.cxx,
- cmGlobalXCodeGenerator.h, cmXCodeObject.h: ENH: more tests are
- passing, relative paths, and external objects are the ones left
- now
-
-2005-02-17 16:59 andy
-
- * Source/CTest/cmCTestTestHandler.cxx: BUG: Detect when
- TestsToRunInformation is not set
-
-2005-02-17 16:11 andy
-
- * Source/: cmCTest.cxx, CTest/cmCTestTestHandler.cxx: ENH: Some
- more generalization
-
-2005-02-17 15:23 andy
-
- * Source/: CMakeLists.txt, cmCTest.cxx, cmCTest.h,
- CTest/cmCTestScriptHandler.cxx, CTest/cmCTestUpdateCommand.cxx,
- CTest/cmCTestUpdateCommand.h, CTest/cmCTestUpdateHandler.cxx:
- ENH: Cleanups and add CTEST_UPDATE command
-
-2005-02-17 15:22 andy
-
- * Source/CTest/: cmCTestGenericHandler.cxx,
- cmCTestGenericHandler.h: ENH: Add a way to set options of the
- handler genericly
-
-2005-02-17 11:28 king
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h,
- kwsys/SystemTools.cxx, kwsys/SystemTools.hxx.in: ENH: Adding
- kwsys::SystemTools::FileTimeCompare method to compare file
- modification times with the highest resolution possible on the
- file system.
-
-2005-02-17 11:27 king
-
- * bootstrap: ENH: Added try-compile KWSYS_STAT_HAS_ST_MTIM. This
- tests whether struct stat has the extra st_mtim member that has
- high resolution times.
-
-2005-02-17 10:51 andy
-
- * Source/: CMakeLists.txt, cmCTest.cxx, cmCTest.h,
- CTest/cmCTestCoverageHandler.cxx,
- CTest/cmCTestMemCheckHandler.cxx, CTest/cmCTestScriptHandler.cxx,
- CTest/cmCTestScriptHandler.h, CTest/cmCTestStartCommand.cxx,
- CTest/cmCTestStartCommand.h: ENH: Cleanups and add CTEST_START
- command
-
-2005-02-17 10:51 andy
-
- * Source/cmSystemTools.cxx: ENH: Add support for single '
-
-2005-02-17 10:49 king
-
- * Source/kwsys/: CMakeLists.txt, Configure.hxx.in,
- kwsysPlatformCxxTests.cxx: ENH: Added try-compile
- KWSYS_STAT_HAS_ST_MTIM. This tests whether struct stat has the
- extra st_mtim member that has high resolution times.
-
-2005-02-17 10:45 hoffman
-
- * Modules/FindQt.cmake: FIX: fix for bug 1409
-
-2005-02-17 10:42 hoffman
-
- * Modules/FindCurses.cmake: FIX: fix for bug 1438
-
-2005-02-17 10:39 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: FIX: fix for bug 1606
-
-2005-02-17 10:18 king
-
- * Source/cmDependsC.cxx: ENH: Removing collapsing of files to full
- path before checking. The current working directory is set
- correctly because the dependency lines are used by make anyway.
- This drastically improves the speed of dependency checking.
-
-2005-02-17 10:03 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Avoid generating duplicate
- rules for an object file. A warning about duplicate source files
- in a target is now generated.
-
-2005-02-17 08:50 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: ENH: Added generation
- of test target to run ctest.
-
-2005-02-17 07:53 king
-
- * Source/cmake.cxx: BUG: Removing "guess when there is a space in
- the path" check for chdir command. It is the responsibility of
- the caller of the command to ensure the arguments are properly
- quoted on the command line.
-
-2005-02-17 07:53 king
-
- * Tests/CommandLineTest/CMakeLists.txt: BUG: Fix for space in path
- for chdir test. We just need to double-quote the arguments.
-
-2005-02-17 02:42 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-02-16 19:13 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: add CMAKE_CFG_INTDIR
-
-2005-02-16 18:47 hoffman
-
- * Source/: cmCTest.cxx, cmGlobalXCodeGenerator.cxx: ENH: use
- ALL_BUILD target
-
-2005-02-16 16:35 hoffman
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalXCodeGenerator.cxx,
- cmGlobalXCodeGenerator.h, cmMakefile.cxx, cmMakefile.h: ENH: more
- tests are passing
-
-2005-02-16 16:06 andy
-
- * Source/CTest/: cmCTestEmptyBinaryDirectoryCommand.cxx,
- cmCTestScriptHandler.cxx: BUG: Report errors
-
-2005-02-16 16:03 andy
-
- * Source/kwsys/SystemTools.cxx: BUG: On windows allow removing of
- files that are read-only
-
-2005-02-16 14:38 andy
-
- * Source/CTest/cmCTestUpdateHandler.cxx: COMP: Remove unused
- variable
-
-2005-02-16 14:24 andy
-
- * Source/CTest/cmCTestUpdateHandler.h: COMP: Remove warning
-
-2005-02-16 14:24 andy
-
- * Source/CTest/cmCTestUpdateHandler.cxx: ENH: Improve output, and
- handle 'G' files in subversion
-
-2005-02-16 13:45 andy
-
- * Source/CTest/cmCTestUpdateHandler.cxx: BUG: If project is up to
- date, handle that case
-
-2005-02-16 13:36 andy
-
- * Modules/Dart.cmake: BUG: Clean the messages
-
-2005-02-16 13:30 andy
-
- * Modules/: Dart.cmake, DartConfiguration.tcl.in: ENH: Reorganize
- and add subversion support
-
-2005-02-16 13:29 andy
-
- * CMakeLists.txt: ENH: Remove DART_ROOT to force
- DartConfiguration.tcl to be up to date
-
-2005-02-16 13:28 andy
-
- * Source/CTest/: cmCTestUpdateHandler.cxx, cmCTestUpdateHandler.h:
- ENH: Initial implementation of SVN support. Closes Bug #1601 -
- Add subversion support
-
-2005-02-16 13:15 hoffman
-
- * Source/cmake.cxx, Source/cmakemain.cxx,
- Tests/CommandLineTest/CMakeLists.txt: BUG: fix CommandLine test
- problems with spaces and testing for the return value
-
-2005-02-16 12:31 martink
-
- * CTestCustom.ctest.in: ENH: add supp for xlc linking on darwin
-
-2005-02-16 09:17 andy
-
- * Utilities/cmzlib/CMakeLists.txt: COMP: attempt to fix warning on
- Visual Studio 7
-
-2005-02-16 09:00 hoffman
-
- * CTestCustom.ctest.in: COMP: add a warning ignore for gcc 3.4.2
-
-2005-02-16 08:56 king
-
- * Source/kwsys/SystemTools.cxx: BUG: Removing debugging code now
- that the problem has been fixed on the remote dashboard.
-
-2005-02-16 02:18 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-02-15 17:25 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h:
- ENH: add custom commands, still failing a bunch of tests
-
-2005-02-15 16:03 king
-
- * Source/kwsys/SystemTools.cxx: BUG: Preserve trailing slash state
- when translating paths.
-
-2005-02-15 09:58 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: make sure paths do not end in
- / before adding one
-
-2005-02-15 09:02 king
-
- * Source/cmDependsFortran.cxx: STYLE: Added TODO comment for
- checking dependencies.
-
-2005-02-15 09:01 king
-
- * Tests/Fortran/: CMakeLists.txt, test_module_implementation.f90,
- test_module_interface.f90, test_module_main.f90: ENH: Added
- Fortran 90 test if the platform supports it.
-
-2005-02-15 08:40 king
-
- * Source/kwsys/SystemTools.cxx: BUG: Adding debugging code to
- remotely debug a failing dashboard test.
-
-2005-02-15 08:28 king
-
- * Source/kwsys/SystemTools.cxx: BUG: Adding debugging code to
- remotely debug a failing dashboard test.
-
-2005-02-15 02:16 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-02-14 16:46 hoffman
-
- * Source/: cmCTest.cxx, cmGlobalXCodeGenerator.cxx,
- cmGlobalXCodeGenerator.h, cmLocalGenerator.h: ENH: getting closer
-
-2005-02-14 16:15 andy
-
- * Tests/MakeClean/CMakeLists.txt: COMP: Try to fix test on HP
-
-2005-02-14 14:35 hoffman
-
- * CMakeLists.txt, CTestCustom.ctest.in, ChangeLog.manual,
- Source/CMakeLists.txt, Source/cmCTest.cxx: ENH: merge from main
- tree
-
-2005-02-14 10:16 martink
-
- * Source/CMakeLists.txt: ENH: only do objc++ test with GNU of
- course
-
-2005-02-14 10:16 martink
-
- * CTestCustom.ctest.in: ENH: added supp for Curl coding style
-
-2005-02-14 09:21 hoffman
-
- * Modules/Platform/Darwin-xlc.cmake: ENH: move xlc stuff to branch
-
-2005-02-14 08:44 king
-
- * Tests/MakeClean/CMakeLists.txt: COMP: Need ANSI flags for C
- executable.
-
-2005-02-14 02:14 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-02-13 02:17 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-02-12 02:14 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-02-11 16:25 andy
-
- * Source/cmake.cxx: ENH: Add command to copy directory with content
-
-2005-02-11 16:25 andy
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH:
- Implement copy of directory with content
-
-2005-02-11 14:25 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h:
- more work on linking flags
-
-2005-02-11 14:22 hoffman
-
- * Modules/CMakeCXXCompiler.cmake.in: FIX: fix bug 1495
-
-2005-02-11 14:20 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: FIX: fix for bug 1460
-
-2005-02-11 14:18 hoffman
-
- * Modules/UseSWIG.cmake: FIX: fix bug 1303
-
-2005-02-11 14:13 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx,
- Templates/staticLibHeader.dsptemplate: FIX: fixes bugs 1152 and
- 1154
-
-2005-02-11 02:17 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-02-10 16:18 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Split
- cmLocalUnixMakefileGenerator2 away from
- cmLocalUnixMakefileGenerator to be a stand-alone generator.
-
-2005-02-10 14:19 king
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH:
- Initializing translation map using the PWD environment variable
- and getcwd functions to automatically translate logical paths
- involving the current working directory. Also added the JoinPath
- method to aid users of the SplitPath method.
-
-2005-02-10 10:35 king
-
- * Source/kwsys/SystemTools.cxx: COMP: std:: -> kwsys_stl::
-
-2005-02-10 10:32 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h, kwsys/SystemTools.cxx,
- kwsys/SystemTools.hxx.in: ENH: Added SystemTools::SplitPath
- method to split any file path into its basic components.
-
-2005-02-10 08:27 hoffman
-
- * Source/cmGlobalKdevelopGenerator.cxx: COMP: fix warning
-
-2005-02-10 08:22 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: Fix for bug 1100.
- If EXECUTABLE_OUTPUT_PATH or LIBRARY_OUTPUT_PATH is a relative
- path it should be converted to a full path relative to each build
- directory.
-
-2005-02-10 07:46 king
-
- * Utilities/cmzlib/: CMakeLists.txt, zconf.h: COMP: Disabling
- warnings in zlib code to avoid changing it too much.
-
-2005-02-10 07:44 hoffman
-
- * Source/cmGlobalKdevelopGenerator.cxx: COMP: fix warning
-
-2005-02-10 02:14 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-02-09 23:25 hoffman
-
- * Source/: cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h: ENH: fix bug 1324
-
-2005-02-09 23:21 hoffman
-
- * Source/: cmGlobalKdevelopGenerator.cxx,
- cmGlobalKdevelopGenerator.h, cmLocalKdevelopGenerator.cxx,
- cmLocalKdevelopGenerator.h: ENH: move most of the to global
- generator
-
-2005-02-09 23:00 hoffman
-
- * Source/cmTryRunCommand.cxx, Source/cmTryRunCommand.h,
- Modules/TestBigEndian.cmake: ENH: fix for 1450
-
-2005-02-09 22:46 hoffman
-
- * Modules/: FindJNI.cmake, FindJava.cmake: ENH: bug fix 1573
-
-2005-02-09 22:45 hoffman
-
- * Modules/FindPythonLibs.cmake: ENH: bug fix 1574
-
-2005-02-09 11:40 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx,
- Source/cmLocalUnixMakefileGenerator2.h,
- Tests/MakeClean/CMakeLists.txt,
- Tests/MakeClean/ToClean/CMakeLists.txt,
- Tests/Wrapping/CMakeLists.txt: ENH: Adding cleaning of custom
- command outputs during "make clean".
-
-2005-02-09 09:36 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Moved reference from local
- driver targets (like build.local) into individual target rule
- files. Main rule is now empty, except that clean.local may
- remove files registered for cleaning.
-
-2005-02-09 09:32 king
-
- * Source/CMakeLists.txt: ENH: Adding MakeClean test to test
- cleaning for makefile generators.
-
-2005-02-09 09:21 king
-
- * Tests/MakeClean/: CMakeLists.txt, check_clean.c.in,
- ToClean/CMakeLists.txt, ToClean/ToCleanFiles.cmake.in,
- ToClean/toclean.cxx: ENH: Adding test of "make clean".
-
-2005-02-08 17:12 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h,
- cmXCodeObject.h: ENH: add link library stuff
-
-2005-02-08 10:13 andy
-
- * Tests/SystemInformation/CMakeLists.txt: ENH: Display all output
- in ctest
-
-2005-02-07 17:36 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmXCodeObject.cxx,
- cmXCodeObject.h: ENH: fix bug in target linking
-
-2005-02-07 16:18 king
-
- * Tests/: Complex/CMakeLists.txt,
- Complex/Executable/complex.file.cxx,
- ComplexOneConfig/CMakeLists.txt,
- ComplexOneConfig/Executable/complex.file.cxx,
- ComplexRelativePaths/CMakeLists.txt,
- ComplexRelativePaths/Executable/complex.file.cxx: ENH: Added
- partial test for include regular expressions.
-
-2005-02-07 16:16 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: COMP: Removed useless
- expression warning.
-
-2005-02-07 16:11 king
-
- * Source/: cmDepends.cxx, cmDepends.h, cmDependsC.cxx,
- cmDependsC.h, cmLocalUnixMakefileGenerator2.cxx: ENH: Implemented
- support for include/complain regular expressions for dependency
- scanning. This now includes the possibility that scanning will
- return failure and the build will stop.
-
-2005-02-07 15:10 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Added generation of
- CMakeDirectoryInformation.cmake file in each directory next to
- the Makefile. The include file search path is now stored in this
- file instead of duplicating it for every object file. This will
- also allow more information to be passed in the future.
-
-2005-02-07 15:09 king
-
- * Source/cmMakefile.h: ENH: Added GetComplainRegularExpression
- method.
-
-2005-02-07 09:05 king
-
- * Tests/SystemInformation/DumpInformation.cxx: BUG: Need to include
- full output to be a useful test.
-
-2005-02-07 05:26 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-02-06 05:27 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-02-05 07:50 king
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ENH: Updated post-build command
- to drive installation through the native build system.
-
-2005-02-05 05:27 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-02-04 17:58 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmXCodeObject.cxx,
- cmXCodeObject.h: ENH: this version can build cmake
-
-2005-02-04 17:38 king
-
- * Source/cmCTest.cxx: BUG: Fixed --build-target implementation to
- work with Visual Studio generators.
-
-2005-02-04 15:14 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Implemented external object
- feature.
-
-2005-02-04 14:13 king
-
- * Source/CMakeLists.txt: ENH: Adding test for external object file
- feature.
-
-2005-02-04 13:58 king
-
- * Tests/ExternalOBJ/: CMakeLists.txt, executable.cxx,
- Object/CMakeLists.txt, Object/external_main.cxx,
- Object/external_object.cxx: ENH: Adding test for external object
- file feature.
-
-2005-02-04 10:06 king
-
- * Modules/CMakeTestFortranCompiler.cmake: ENH: Added test for
- Fortran90 support.
-
-2005-02-04 05:28 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-02-03 19:32 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: COMP: remove warnings
-
-2005-02-03 17:42 hoffman
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h,
- cmLocalGenerator.h, cmXCodeObject.cxx, cmXCodeObject.h: ENH:
- depends work between targets
-
-2005-02-03 08:39 king
-
- * Source/cmDependsJavaParserHelper.cxx: COMP: Fix warning about
- printf format and given type.
-
-2005-02-03 05:29 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-02-02 17:16 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h,
- cmLocalGenerator.h, cmXCodeObject.cxx, cmXCodeObject.h: ENH:
- getting closer
-
-2005-02-02 17:05 king
-
- * Source/: cmDependsFortranParser.cxx, cmDependsFortranParser.y,
- cmDependsJavaParser.cxx, cmDependsJavaParser.y: COMP: Adding
- warning work-around for unused case label yyerrorlab on HP
- compiler.
-
-2005-02-02 13:19 hoffman
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h,
- cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: move AddFlags stuff up to
- LocalGenerator from LocalUnix generator
-
-2005-02-02 05:44 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-02-01 17:17 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h:
- ENH: closer
-
-2005-02-01 15:48 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmXCodeObject.cxx: ENH:
- getting closer
-
-2005-02-01 14:28 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: COMP: fix warning
-
-2005-02-01 13:12 hoffman
-
- * Modules/CMakeFindXCode.cmake: ENH: add trycompile code for xcode
-
-2005-02-01 13:07 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h:
- ENH: add trycompile code for xcode
-
-2005-02-01 11:28 king
-
- * Source/: cmDependsFortranParser.cxx, cmDependsFortranParser.y:
- COMP: Disabling warning in generated code.
-
-2005-02-01 10:44 king
-
- * Source/: cmDependsJavaLexer.h, cmDependsJavaLexer.in.l: COMP:
- Removing #line directives from .h file to avoid bogus Sun
- warning.
-
-2005-02-01 10:42 king
-
- * Source/: CMakeLists.txt, cmDependsFortran.cxx,
- cmDependsFortranLexer.cxx, cmDependsFortranLexer.h,
- cmDependsFortranLexer.in.l, cmDependsFortranParser.cxx,
- cmDependsFortranParser.h, cmDependsFortranParser.y,
- cmDependsFortranParserTokens.h, cmDependsFortranLexer.c,
- cmDependsFortranParser.c: ENH: Changed over to using C++ for
- building flex/bison generated files. It reduces the number of
- changes that need to be made after generation.
-
-2005-02-01 05:38 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-01-31 05:19 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-01-30 05:23 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-01-29 07:57 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: COMP: Removed shadowed
- variable warning.
-
-2005-01-29 05:23 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-01-28 18:12 king
-
- * Source/cmGlobalXCodeGenerator.cxx: COMP: Added missing labels to
- case.
-
-2005-01-28 17:46 andy
-
- * Source/: cmDependsJavaLexer.cxx, cmDependsJavaLexer.in.l: COMP:
- Another borland problem
-
-2005-01-28 17:43 andy
-
- * Source/: cmDependsJavaLexer.cxx, cmDependsJavaLexer.in.l,
- cmDependsJavaParser.cxx, cmDependsJavaParser.y,
- cmDependsJavaParserTokens.h: COMP: Remove more warnings/errors
-
-2005-01-28 17:25 king
-
- * Source/cmGeneratedFileStream.cxx: COMP: Fix unused parameter
- warning when bootstrapping.
-
-2005-01-28 17:24 andy
-
- * Source/: cmDependsJavaLexer.cxx, cmDependsJavaLexer.in.l,
- cmDependsJavaParser.cxx, cmDependsJavaParser.y,
- cmDependsJavaParserTokens.h: COMP: Remove warnings
-
-2005-01-28 17:21 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h:
- ENH: move executable xcode stuff to a method
-
-2005-01-28 17:18 king
-
- * Source/cmDependsJavaParserHelper.cxx: COMP: Removed default
- argument from method definition.
-
-2005-01-28 17:14 andy
-
- * Source/CMakeLists.txt: ENH: Enable java dependency
-
-2005-01-28 17:13 andy
-
- * Source/: cmDependsJavaParser.cxx, cmDependsJavaParser.y,
- cmDependsJavaParserHelper.cxx, cmDependsJavaParserHelper.h,
- cmDependsJavaParserTokens.h: ENH: Initial import of java parser
-
-2005-01-28 17:13 andy
-
- * Source/cmDependsFortranParser.y: STYLE: Add some diff helping
- comments
-
-2005-01-28 17:09 king
-
- * Source/: cmDependsFortranParser.c, cmDependsFortranParser.y,
- cmDependsFortranParserTokens.h: COMP: Disabled warnings in
- generated code.
-
-2005-01-28 16:56 andy
-
- * Source/: cmDependsJavaLexer.cxx, cmDependsJavaLexer.h,
- cmDependsJavaLexer.in.l: ENH: Initial import of java parser
-
-2005-01-28 16:26 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: ENH: use absolute paths
-
-2005-01-28 16:00 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h:
- ENH: create mainGroup
-
-2005-01-28 14:17 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Implemented full per-object
- test for whether provides-requires mode is needed. This will
- still use a recursive make for any Fortran object even if it
- doesn't have requires. It is possible to avoid it but we can do
- that later.
-
-2005-01-28 13:20 andy
-
- * Modules/Dart.cmake: ENH: Better checking for Dart. Closes Bug
- #1505 - Configuration fails to create Makefile
-
-2005-01-28 13:00 andy
-
- * Source/cmake.cxx: BUG: prevent -P or script to be passed as
- homedirectory
-
-2005-01-28 12:01 king
-
- * Source/cmDependsFortran.cxx: STYLE: Added another solution
- proposal for out-of-directory modules.
-
-2005-01-28 10:45 king
-
- * Source/cmDependsFortran.cxx: ENH: Added provides/requires output
- for modules.
-
-2005-01-28 10:12 andy
-
- * Source/CTest/cmCTestBuildHandler.cxx: ENH: Add error regex
-
-2005-01-28 08:30 hoffman
-
- * Modules/Platform/Windows-cl.cmake: ENH: remove debug print
-
-2005-01-28 05:20 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-01-27 19:24 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: COMP: fix warning
-
-2005-01-27 17:45 andy
-
- * Modules/Dart.cmake: ENH: Enable compression and use the new
- trigger script
-
-2005-01-27 17:43 andy
-
- * Source/cmCTest.cxx, Modules/DartConfiguration.tcl.in: ENH: Enable
- compression with DartConfiguration file
-
-2005-01-27 17:09 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmXCodeObject.cxx: ENH:
- xcode almost working for simple exe, but not yet
-
-2005-01-27 16:49 andy
-
- * Source/CTest/cmCTestTestHandler.h: COMP: Fix build on sun
-
-2005-01-27 16:43 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmXCodeObject.cxx: ENH: fix
- a few more xcode things
-
-2005-01-27 16:25 hoffman
-
- * Source/cmXCodeObject.cxx: ENH: add missing ;
-
-2005-01-27 16:11 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h,
- cmXCodeObject.cxx: ENH: add more xcode stuff
-
-2005-01-27 15:54 andy
-
- * Source/: CMakeLists.txt, cmCTest.cxx, cmCTest.h,
- CTest/cmCTestBuildHandler.cxx, CTest/cmCTestBuildHandler.h,
- CTest/cmCTestConfigureHandler.cxx,
- CTest/cmCTestConfigureHandler.h,
- CTest/cmCTestCoverageHandler.cxx, CTest/cmCTestCoverageHandler.h,
- CTest/cmCTestGenericHandler.cxx, CTest/cmCTestGenericHandler.h,
- CTest/cmCTestMemCheckHandler.cxx, CTest/cmCTestMemCheckHandler.h,
- CTest/cmCTestScriptHandler.cxx, CTest/cmCTestScriptHandler.h,
- CTest/cmCTestTestHandler.cxx, CTest/cmCTestTestHandler.h,
- CTest/cmCTestUpdateHandler.cxx, CTest/cmCTestUpdateHandler.h:
- ENH: Several cleanups and improvements
-
-2005-01-27 13:31 martink
-
- * Source/CTest/: cmCTestRunScriptCommand.cxx,
- cmCTestScriptHandler.cxx, cmCTestScriptHandler.h: ENH: clean up
- running of default script
-
-2005-01-27 11:43 andy
-
- * Source/: CMakeLists.txt, cmCTest.cxx,
- CTest/cmCTestBuildHandler.cxx, CTest/cmCTestBuildHandler.h,
- CTest/cmCTestConfigureHandler.cxx,
- CTest/cmCTestConfigureHandler.h,
- CTest/cmCTestCoverageHandler.cxx, CTest/cmCTestCoverageHandler.h,
- CTest/cmCTestGenericHandler.cxx, CTest/cmCTestGenericHandler.h,
- CTest/cmCTestScriptHandler.cxx, CTest/cmCTestScriptHandler.h,
- CTest/cmCTestTestHandler.cxx, CTest/cmCTestTestHandler.h,
- CTest/cmCTestUpdateHandler.cxx, CTest/cmCTestUpdateHandler.h:
- ENH: Add a superclass to all handlers
-
-2005-01-27 11:01 martink
-
- * Source/CTest/: cmCTestRunScriptCommand.cxx,
- cmCTestScriptHandler.cxx, cmCTestScriptHandler.h,
- cmCTestSleepCommand.cxx: COMP: fix some compiler warnings/errors
-
-2005-01-27 10:47 martink
-
- * Source/ctest.cxx: ENH: added missing documentation
-
-2005-01-27 10:14 andy
-
- * Source/: cmCTest.cxx, cmCTest.h, CTest/cmCTestBuildHandler.cxx,
- CTest/cmCTestConfigureHandler.cxx,
- CTest/cmCTestCoverageHandler.cxx, CTest/cmCTestCoverageHandler.h,
- CTest/cmCTestTestHandler.cxx, CTest/cmCTestUpdateHandler.cxx:
- ENH: Add compression support to XML files
-
-2005-01-27 10:14 andy
-
- * Source/: cmGeneratedFileStream.cxx, cmGeneratedFileStream.h: ENH:
- Add compression support
-
-2005-01-27 10:11 andy
-
- * Tests/Complex/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt,
- Source/CMakeLists.txt: ENH: Link to cmzlib
-
-2005-01-27 10:11 martink
-
- * Source/: CMakeLists.txt, CTest/cmCTestCommand.h,
- CTest/cmCTestEmptyBinaryDirectoryCommand.cxx,
- CTest/cmCTestEmptyBinaryDirectoryCommand.h,
- CTest/cmCTestRunScriptCommand.cxx,
- CTest/cmCTestRunScriptCommand.h, CTest/cmCTestScriptHandler.cxx,
- CTest/cmCTestScriptHandler.h, CTest/cmCTestSleepCommand.cxx,
- CTest/cmCTestSleepCommand.h: ENH: added more capabilities to
- ctest
-
-2005-01-27 05:24 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-01-26 16:19 king
-
- * Source/cmDependsFortranParser.y: COMP: Added instruction to
- remove TABs from generated file.
-
-2005-01-26 16:18 king
-
- * Source/: CMakeLists.txt, cmLocalUnixMakefileGenerator2.cxx: ENH:
- Added hook into Fortran dependency scanner.
-
-2005-01-26 16:17 king
-
- * Source/: cmDependsFortranLexer.c, cmDependsFortranLexer.h,
- cmDependsFortranParser.c, cmDependsFortranParserTokens.h: ENH:
- Added generated lexer and parser sources.
-
-2005-01-26 16:10 king
-
- * Source/: cmDependsFortranLexer.in.l, cmDependsFortranParser.y:
- COMP: Added additional instructions about how to modify the
- generated files.
-
-2005-01-26 16:09 king
-
- * Source/cmDependsFortran.cxx: COMP: Added constructor to
- cmDependsFortranFile to avoid using initializer list. Also
- included assert.h.
-
-2005-01-26 15:58 king
-
- * Source/cmDependsFortranParser.y: COMP: Added forward declaration
- of yylex.
-
-2005-01-26 15:55 andy
-
- * CMakeLists.txt: ENH: Add zlib from VTK
-
-2005-01-26 15:55 andy
-
- * Utilities/cmzlib/: .NoDartCoverage, CMakeLists.txt, adler32.c,
- cm_zlib_mangle.h, compress.c, crc32.c, deflate.c, deflate.h,
- example.c, gzio.c, infblock.c, infblock.h, infcodes.c,
- infcodes.h, inffast.c, inffast.h, inffixed.h, inflate.c,
- inftrees.c, inftrees.h, infutil.c, infutil.h, maketree.c,
- minigzip.c, trees.c, trees.h, uncompr.c, zconf.h, zlib.def,
- zlib.h, zlib.rc, zlibDllConfig.h.in, zutil.c, zutil.h: ENH:
- Initial import from VTK
-
-2005-01-26 15:45 king
-
- * Source/cmDependsFortran.cxx: ENH: Removed Lexer/Parser prefix
- before _yy symbols. Just cmDependsFortran_yy is enough.
-
-2005-01-26 15:43 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: fix version number
-
-2005-01-26 15:33 king
-
- * Source/: cmDependsFortran.cxx, cmDependsFortran.h,
- cmDependsFortranLexer.in.l, cmDependsFortranParser.h,
- cmDependsFortranParser.y: ENH: Added Fortran dependency scanner
- implementation.
-
-2005-01-26 14:25 king
-
- * Source/: cmGeneratedFileStream.cxx, cmGeneratedFileStream.h: ENH:
- Added default constructor and Open method.
-
-2005-01-26 11:13 andy
-
- * Source/CTest/: cmCTestTestHandler.cxx, cmCTestTestHandler.h: ENH:
- Add support for shrinking the output of the test
-
-2005-01-26 10:10 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: ENH: Add method to populate
- custom integers
-
-2005-01-26 05:59 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-01-25 16:36 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: COMP: fix warnings
-
-2005-01-25 16:30 hoffman
-
- * Source/cmGlobalXCodeGenerator.cxx: COMP: fix warnings
-
-2005-01-25 16:09 hoffman
-
- * bootstrap: ENH: add xcode stuff to bootstrap
-
-2005-01-25 15:26 hoffman
-
- * Source/: CMakeLists.txt, cmGlobalXCodeGenerator.cxx,
- cmGlobalXCodeGenerator.h, cmXCodeObject.cxx, cmXCodeObject.h,
- cmake.cxx: ENH: add initial non-working XCode stuff
-
-2005-01-25 05:59 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-01-24 17:35 hoffman
-
- * Source/: cmGlobalXCodeGenerator.cxx, cmGlobalXCodeGenerator.h,
- cmLocalXCodeGenerator.cxx, cmLocalXCodeGenerator.h,
- cmXCodeObject.cxx, cmXCodeObject.h: ENH: initial xcode stuff
-
-2005-01-24 05:53 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-01-23 05:56 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-01-22 05:51 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-01-21 16:25 hoffman
-
- * Source/: cmXCodeObject.cxx, cmXCodeObject.h: ENH: start xcode
- stuff
-
-2005-01-21 12:26 hoffman
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio6Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h: ENH: move project map to global
- generator base
-
-2005-01-21 11:22 martink
-
- * Source/cmWhileCommand.cxx: COMP: fix unused var warning
-
-2005-01-21 10:27 hoffman
-
- * bootstrap, Source/CMakeLists.txt, Source/cmBootstrapCommands.cxx,
- Source/cmCommands.cxx, Source/cmCommands.h,
- Source/cmWhileCommand.cxx, Source/cmake.cxx: ENH: split up
- cmCommands into two files
-
-2005-01-21 09:37 martink
-
- * Source/: cmCommands.cxx, cmWhileCommand.cxx, cmWhileCommand.h,
- cmEndWhileCommand.cxx, cmEndWhileCommand.h: ENH: added while
- command
-
-2005-01-21 05:36 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-01-20 15:26 martink
-
- * Source/cmSetCommand.cxx: COMP: fix unused var warning
-
-2005-01-20 14:38 martink
-
- * Source/: cmSetCommand.cxx, cmSetCommand.h: ENH: now the set
- command can set environment variables
-
-2005-01-20 12:30 hoffman
-
- * Modules/: CMakeCCompiler.cmake.in, CMakeCXXCompiler.cmake.in,
- CMakeDetermineCCompiler.cmake, CMakeFortranCompiler.cmake.in,
- CMakeJavaCompiler.cmake.in, CMakeRCCompiler.cmake.in,
- CMakeTestCCompiler.cmake, CMakeTestCXXCompiler.cmake,
- Platform/Windows-cl.cmake, Platform/Windows-cl.cmake.in: ENH:
- stuff to keep compiler tests from re-running all the time
-
-2005-01-20 12:28 hoffman
-
- * Source/: cmGlobalGenerator.cxx, cmLocalKdevelopGenerator.cxx:
- ENH: add some comments on how this could be moved to global
- generator
-
-2005-01-20 04:38 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-01-19 12:06 king
-
- * Source/: cmListFileLexer.in.l, cmListFileLexer.c: ENH: Mangled
- lexer symbols to begin in cmListFileLexer_yy instead of just yy
- to avoid conflict with other lexers that may be added.
-
-2005-01-19 07:23 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Removed unquoted version of
- OBJECTS make variable. Quoted seems to work everywhere. BUG:
- Fixed AppendAnyDepend to properly identify executable targets.
- BUG: Used CreateMakeVariable to fix variable name for OBJECTS
- list when target has a . in its name.
-
-2005-01-19 05:19 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-01-18 18:11 andy
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt: COMP: Add proper
- link directory
-
-2005-01-18 17:29 andy
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt: COMP: Add cmexpat
- to complex
-
-2005-01-18 17:09 king
-
- * Source/: CMakeLists.txt, cmDepends.cxx, cmDepends.h,
- cmDependsC.cxx, cmDependsC.h, cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h, cmake.cxx: ENH: Split dependency
- scanning and checking into separate cmDepends superclass with
- language-specific subclasses such as cmDependsC.
-
-2005-01-18 16:47 andy
-
- * Source/CMakeLists.txt: COMP: Ok, actually link to the library....
-
-2005-01-18 15:54 andy
-
- * Source/cmXMLParser.cxx, Utilities/cmexpat/xmlparse.c: COMP: Try
- to resolve compile errors because of missing includes and wrong
- include path
-
-2005-01-18 14:02 andy
-
- * Source/cmXMLParser.cxx: COMP: Use cmOStringStream not
- ostringstream
-
-2005-01-18 13:41 andy
-
- * Source/: CMakeLists.txt, cmXMLParser.cxx, cmXMLParser.h: ENH: Add
- XML parser
-
-2005-01-18 11:15 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: STYLE: Added TODO
- comment for another missing feature (external object files).
-
-2005-01-18 09:06 andy
-
- * Utilities/Doxygen/doc_makeall.sh.in: ENH: Cleanup
-
-2005-01-18 08:58 andy
-
- * CMakeLists.txt, cmake_uninstall.cmake.in: ENH: Add uninstall.
- This is not really a feature but more of an example on how to do
- it.
-
-2005-01-18 04:17 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-01-17 16:29 hoffman
-
- * Source/cmCTest.cxx: BUG: when ctest is looking for cmake look in
- the build directory as well as where ctest is so that purify will
- work
-
-2005-01-17 15:20 hoffman
-
- * Modules/: CMakeCCompiler.cmake.in, CMakeCXXCompiler.cmake.in,
- Platform/Windows-cl.cmake: BUG: fix running of cl in trycompiles
-
-2005-01-17 15:09 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Adding partial
- implementation of provides-requires mode.
-
-2005-01-17 15:09 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: BUG: Fix for relative
- path conversion when path is a subset of relative path root.
-
-2005-01-17 14:29 hoffman
-
- * Source/: cmWin32ProcessExecution.cxx, cmWin32ProcessExecution.h:
- BUG: make sure handles are always closed even if Wait is not
- called.
-
-2005-01-17 04:41 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-01-15 04:40 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-01-13 12:38 hoffman
-
- * ChangeLog.manual: BUG: fix from main tree
-
-2005-01-13 03:58 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-01-12 13:58 martink
-
- * Source/CTest/cmCTestBuildHandler.cxx: ENH: now limits warnings
- and error report to 50 each
-
-2005-01-12 13:51 martink
-
- * Source/CTest/cmCTestBuildHandler.cxx: ENH: now limits warnings
- and error report to 50 each
-
-2005-01-12 10:11 millerjv
-
- * Source/kwsys/Base64.c: BUG: encoding 2 bytes into 4 bytes was
- accessing a 3rd byte from the source
-
-2005-01-12 04:43 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-01-11 05:03 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-01-10 05:06 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-01-08 05:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-01-07 11:56 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-01-05 05:13 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-01-04 18:24 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Added install target
- implementation. Also added missing include of assert.h.
-
-2005-01-04 17:41 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Added relative path support
- (mostly done). Many paths are written relative even if
- CMAKE_USE_RELATIVE_PATHS is not on just to keep makefiles short.
-
-2005-01-04 16:26 king
-
- * Source/cmLocalUnixMakefileGenerator.h: ENH: Made
- ConfigureOutputPaths virtual to help new generator.
-
-2005-01-04 15:38 hoffman
-
- * ChangeLog.manual, Modules/Platform/Windows-icl.cmake: add intel
- compiler config file
-
-2005-01-04 12:12 hoffman
-
- * ChangeLog.manual, Source/cmSetCommand.cxx: fix for bug 1445
-
-2005-01-04 10:55 andy
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH: Add a
- delay method
-
-2005-01-04 09:56 king
-
- * Source/cmLocalKdevelopGenerator.cxx: BUG: Applied patch attached
- to bug #1453.
-
-2005-01-04 08:42 martink
-
- * Source/cmSetCommand.cxx: ENH: fixed SET command to accept cache
- values with more than one value
-
-2005-01-04 04:17 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-01-02 05:04 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2005-01-01 21:02 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-31 05:03 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-30 05:03 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-29 05:27 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-28 05:23 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-27 05:22 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-26 05:25 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-25 05:21 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-24 05:16 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-23 05:27 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-22 05:16 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-21 05:14 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-20 05:09 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-19 05:15 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-18 05:11 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-17 05:06 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-16 22:19 hoffman
-
- * Modules/CMakeDetermineSystem.cmake: fix wrong number of arguments
-
-2004-12-16 22:18 hoffman
-
- * Modules/CMakeDetermineSystem.cmake: fix number of arguments
-
-2004-12-16 17:26 hoffman
-
- * ChangeLog.manual, Modules/CMakeDetermineSystem.cmake,
- Modules/Platform/OpenBSD.cmake: ENH: fix for OpenBSD
-
-2004-12-16 05:52 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-15 05:46 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-14 05:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-13 05:03 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-12 05:08 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-11 05:10 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-10 05:13 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-09 16:14 king
-
- * Source/cmSystemTools.cxx: BUG: Fix to avoid relative path with
- ..s all the way to the root.
-
-2004-12-09 15:56 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: BUG: Support for custom
- command outputs in subdirectories of current build tree location.
-
-2004-12-09 15:23 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: BUG: AppendAnyDepend
- must handle non-existing files.
-
-2004-12-09 15:11 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Added post-build rules to
- executables and libraries. Generalized AppendLibDepend method to
- AppendAnyDepend. This takes most of the functionality of
- AppendCustomDepend too, and generalized jump-and-build to
- executables.
-
-2004-12-09 13:52 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Implemented utility
- targets. This involved pulling part of the custom command rule
- implementation out into shared methods.
-
-2004-12-09 05:12 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-08 05:05 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-07 05:19 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-06 12:39 hoffman
-
- * Modules/Platform/: Tru64.cmake, True64.cmake: FIX: fix for bug
- 1325, Tru64 not True64
-
-2004-12-06 12:38 hoffman
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmLocalUnixMakefileGenerator.cxx: BUG: fix for bug 1396, object
- files could not be used as sources any more
-
-2004-12-06 11:10 hoffman
-
- * ChangeLog.manual, Source/cmCTest.cxx,
- Source/cmLocalUnixMakefileGenerator.cxx, Source/cmMakefile.cxx,
- Source/CTest/cmCTestSubmit.cxx, Source/CTest/cmCTestSubmit.h,
- Utilities/Release/cmake_release.sh: merge from main tree
-
-2004-12-06 05:00 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-05 04:22 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-04 04:36 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-03 09:25 martink
-
- * Source/CMakeLists.txt: ENH: minor fix for windows
-
-2004-12-03 09:05 martink
-
- * Source/cmMakefile.cxx: ENH: fix for relative paths
-
-2004-12-03 06:27 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-02 13:14 hoffman
-
- * Source/cmMakefile.cxx: BUG: fix for 1369 before include
- directories need to be always added
-
-2004-12-02 12:33 hoffman
-
- * Source/kwsys/SystemTools.cxx: BUG: fix for bug 1385, /tmp should
- not be used on windows
-
-2004-12-02 06:13 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-12-01 07:28 king
-
- * Source/kwsys/kwsys_ios_sstream.h.in: COMP: Need to choose between
- <new> and <new.h> based on whether standard headers are
- available.
-
-2004-12-01 07:24 king
-
- * Source/kwsys/: kwsys_ios_fstream.h.in, kwsys_ios_iostream.h.in:
- COMP: Disabling old streams warnings when including old headers
- on MSVC.
-
-2004-12-01 06:25 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-30 18:20 king
-
- * Source/kwsys/kwsys_ios_sstream.h.in: BUG: Need to include header
- <new> to use placement new syntax. Really this should be fixed
- by replacing the stream buffer to set a new string instead of
- reconstructing the object, but this will require quite a bit of
- work to do portably.
-
-2004-11-30 06:29 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-29 06:21 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-28 06:16 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-27 06:28 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-26 06:16 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-25 06:19 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-24 09:25 andy
-
- * Source/CTest/: cmCTestSubmit.cxx, cmCTestSubmit.h: ENH: Add
- support for proxy authentication (thanks Jean-Michel)
-
-2004-11-24 05:45 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-23 17:34 hoffman
-
- * Modules/Platform/AIX.cmake: ENH: try and fix aix xlC with gcc
-
-2004-11-23 17:28 hoffman
-
- * Modules/Platform/AIX.cmake: ENH: try and fix aix xlC with gcc
-
-2004-11-23 14:07 hoffman
-
- * Modules/Platform/AIX.cmake: ENH: try to fix aix with native cxx
- and gcc
-
-2004-11-23 10:48 andy
-
- * Source/CTest/cmCTestUpdateHandler.cxx: ENH: Make more things XML
- safe
-
-2004-11-23 05:46 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-22 05:45 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-21 05:44 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-20 05:46 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-19 09:42 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: ENH: Moved custom
- command rule files into special CMakeCustomCommands.dir
- subdirectory.
-
-2004-11-19 09:32 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Unified WriteDependRules,
- WriteBuildRules, WriteCleanRules, and the future
- WriteInstallRules into a single WritePassRules method. Also
- added WriteTargetDependsRule and WriteTargetCleanRule methods to
- unify writing of depend and clean rules for each target.
-
-2004-11-19 05:41 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-18 08:25 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-17 08:33 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-16 08:16 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-15 09:39 martink
-
- * Source/ctest.cxx: COMP: fix warning
-
-2004-11-15 08:22 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-14 08:21 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-13 09:55 martink
-
- * Source/: cmCTest.cxx, ctest.cxx, CTest/cmCTestTestHandler.cxx,
- CTest/cmCTestTestHandler.h: ENH: added -U option to take union of
- -R and -I
-
-2004-11-13 08:15 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-12 05:36 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-11 17:40 andy
-
- * Source/CTest/cmCTestBuildHandler.cxx: ENH: Another linker error
- on sun
-
-2004-11-11 05:34 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-10 15:39 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: FIX: make sure the
- object file name is correctly mangled for depend information
-
-2004-11-10 13:15 martink
-
- * CMakeLists.txt, CTestCustom.ctest.in: ENH: added custom supp for
- cmake
-
-2004-11-10 10:24 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-09 09:57 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-08 05:46 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-07 05:45 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-06 05:40 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-05 15:09 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Added partial clean target
- support.
-
-2004-11-05 15:03 king
-
- * Source/: cmLocalUnixMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator.h: ENH: Moved code that checks
- output path variables to separate ConfigureOutputPaths method.
- Needed to provide access to the same code from a subclass.
-
-2004-11-05 07:39 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Implemented VERBOSE output
- setting.
-
-2004-11-05 05:38 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-04 05:38 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-03 15:43 martink
-
- * Source/kwsys/SystemTools.cxx: ENH: merges from the main tree
-
-2004-11-03 11:02 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Generalized driver targets
- and subdirectory traversal rules. The implementations of all,
- depend, build, clean, install, etc. now follow a common
- framework.
-
-2004-11-03 08:59 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Removed unneeded requires
- rules now that canonical names are available.
-
-2004-11-03 08:46 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Added convenience rules to
- build targets without specifying full paths.
-
-2004-11-03 07:51 king
-
- * Source/: cmExportLibraryDependencies.cxx,
- cmGeneratedFileStream.cxx, cmGeneratedFileStream.h,
- cmGlobalVisualStudio7Generator.cxx, cmLocalGenerator.cxx,
- cmLocalKdevelopGenerator.cxx, cmLocalUnixMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator2.cxx,
- cmVTKMakeInstantiatorCommand.cxx: STYLE: Adjusted signature of
- cmGeneratedFileStream to make copy-if-different more explicity.
-
-2004-11-03 07:27 king
-
- * Source/: cmGlobalVisualStudio7Generator.cxx,
- cmGeneratedFileStream.cxx, cmGeneratedFileStream.h: COMP: Fix new
- cmGeneratedFileStream for MSVC.
-
-2004-11-03 07:23 king
-
- * bootstrap, Source/CMakeLists.txt,
- Source/cmExportLibraryDependencies.cxx,
- Source/cmGeneratedFileStream.cxx, Source/cmGeneratedFileStream.h,
- Source/cmLocalGenerator.cxx, Source/cmLocalKdevelopGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator2.cxx,
- Source/cmVTKMakeInstantiatorCommand.cxx: ENH: Re-implemented
- cmGeneratedFileStream to look like a real stream and replace the
- destination file atomically. This will avoid problems with the
- process being terminated while generating a file.
-
-2004-11-03 05:34 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-02 18:09 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: ENH: Added partial RC
- language dependency scanning (just using C dependencies for now).
-
-2004-11-02 17:38 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Added dependencies between
- libraries.
-
-2004-11-02 17:19 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: BUG: Removed debugging
- output.
-
-2004-11-02 17:14 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Implemented generation of
- custom command rule files.
-
-2004-11-02 17:11 andy
-
- * Source/kwsys/SystemTools.cxx: COMP: Remove compile warning
-
-2004-11-02 08:32 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: BUG: Fixed subdirectory
- implementation for Borland Make.
-
-2004-11-02 07:36 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Implemented subdirectory
- rules for all target.
-
-2004-11-02 04:49 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-11-01 16:57 hoffman
-
- * Source/kwsys/SystemTools.cxx, Tests/Dependency/CMakeLists.txt,
- Tests/Dependency/1/CMakeLists.txt, Tests/Dependency/1/OneSrc.c:
- BUG: add a test for a single char dir, and fix bug introduced in
- 1.53, but we still can not handle a space as the start of a
- directory name
-
-2004-11-01 04:34 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-10-31 03:40 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-10-30 04:32 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-10-29 18:15 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Added framework for
- subdirectory traversal.
-
-2004-10-29 17:18 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: BUG: Dependency
- makefile lines must be at least three characters long to hold a
- dependency.
-
-2004-10-29 16:50 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h, cmake.cxx, cmake.h: ENH: Added
- build system integrity check to cmLocalUnixMakefileGenerator2.
- This now uses a special --check-build-system flag to cmake which
- replaces --check-rerun. Integrity of dependencies is also
- checked during generation.
-
-2004-10-29 15:32 hoffman
-
- * Source/cmLocalGenerator.cxx: FIX: fix shared flag
-
-2004-10-29 15:31 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: remove debug print
-
-2004-10-29 14:57 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: BUG: Fixes for Borland
- Make.
-
-2004-10-29 13:55 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: BUG: Fixes for NMake.
-
-2004-10-29 13:04 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Changed AppendRecursiveMake
- to GetRecursiveMakeCall and implemented jump-and-build on Windows
- and UNIX.
-
-2004-10-29 11:42 hoffman
-
- * CMakeLists.txt, ChangeLog.manual,
- Modules/TestCXXAcceptsFlag.cmake, Source/cmCTest.cxx,
- Source/cmCacheManager.cxx,
- Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmSystemTools.cxx, Source/cmSystemTools.h,
- Source/kwsys/SystemTools.cxx, Source/kwsys/SystemTools.hxx.in,
- Tests/Complex/Executable/A.cxx,
- Tests/Complex/Executable/CMakeLists.txt,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/A.cxx,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/A.cxx,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/complex.cxx,
- Tests/LoadCommand/LoadedCommand.cxx,
- Tests/LoadCommandOneConfig/LoadedCommand.cxx,
- Utilities/Release/cmake_release.sh: move 2.0.5 to LatestRelease
-
-2004-10-29 10:52 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Cleaned up format of
- generated makefiles. Consolidated rule generation into single
- WriteMakeRule method. Added special targets like rebuild_cache
- and edit_cache.
-
-2004-10-29 04:36 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-10-28 15:40 hoffman
-
- * Source/cmIncludeDirectoryCommand.cxx: ENH: add a check for empty
- include directories
-
-2004-10-28 15:31 hoffman
-
- * CMakeLists.txt, Utilities/Release/cmake_release.sh: Create
- CMake2.0.5 version
-
-2004-10-28 07:46 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: COMP: Fix local shadow
- warnings.
-
-2004-10-28 07:43 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: COMP: Fix for Mac
- specific code.
-
-2004-10-28 04:36 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-10-27 16:00 hoffman
-
- * Source/cmMakefile.cxx: ENH: look in the windows LIB env variable
- for libraries
-
-2004-10-27 16:00 hoffman
-
- * Source/cmGlobalKdevelopGenerator.cxx: DOC: documentation change
-
-2004-10-27 15:58 hoffman
-
- * ChangeLog.manual, Modules/TestCXXAcceptsFlag.cmake,
- Source/cmCacheManager.cxx,
- Source/cmLocalUnixMakefileGenerator.cxx: ENH: merge from main
- tree bug fixes
-
-2004-10-27 12:05 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Do not try to handle
- unimplemented target types yet. Fixes for projects with
- subdirectories.
-
-2004-10-27 11:26 andy
-
- * Source/cmakemain.cxx: BUG: If bootstrap cmake is run with no
- argument produce error
-
-2004-10-27 10:53 hoffman
-
- * Source/: cmLocalGenerator.cxx, cmLocalUnixMakefileGenerator.cxx,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: ENH: put error checking for
- missing linker languages
-
-2004-10-27 10:47 andy
-
- * bootstrap, Source/cmFileCommand.cxx,
- Source/cmFindPackageCommand.cxx, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmake.cxx, Source/cmake.h,
- Source/cmakemain.cxx: PERF: Remove several classes from the
- bootstrap and so making bootstrap smaller and faster
-
-2004-10-27 10:45 andy
-
- * Source/CursesDialog/ccmake.cxx: STYLE: Remove unused code
-
-2004-10-27 10:45 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Added executable
- dependencies on libraries including jump-and-build support.
-
-2004-10-27 10:45 andy
-
- * Modules/TestCXXAcceptsFlag.cmake: BUG: Check for the variable
- first time
-
-2004-10-27 08:49 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: Add a space before
- the : only if the target name is one letter long. This works
- around bugs in some shells' tab completion of target names.
-
-2004-10-27 08:47 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Added generation of rules
- for shared libraries and modules.
-
-2004-10-27 08:20 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Added rules to build
- executables. Also began to consolidate flag list construction
- into separate methods.
-
-2004-10-27 04:37 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-10-26 20:13 andy
-
- * Source/cmCacheManager.cxx: BUG: Handle DOS files un unix file
- systems
-
-2004-10-26 17:23 andy
-
- * Modules/TestCXXAcceptsFlag.cmake: BUG: Only test for cxx flags
- the first time around
-
-2004-10-26 16:07 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: ENH: Do not generate
- touch rule for target level dependencies. There are no
- build-time dependencies by default.
-
-2004-10-26 15:03 hoffman
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h,
- kwsys/SystemTools.cxx, kwsys/SystemTools.hxx.in: ENH: move stuff
- from main tree to branch
-
-2004-10-26 14:49 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Added generation of rule to
- build object file.
-
-2004-10-26 14:33 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: handle read only directories
- with configure file destination
-
-2004-10-26 14:12 hoffman
-
- * ChangeLog.manual, Source/cmCTest.cxx: ENH: merge from main tree
-
-2004-10-26 13:00 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: ERR: Missing std:: on
- endl.
-
-2004-10-26 12:55 king
-
- * Source/cmake.cxx: ENH: Added object file dependency scanning to
- cmLocalUnixMakefileGenerator2. This needs a hook in cmake.cxx.
-
-2004-10-26 12:54 king
-
- * bootstrap, Source/CMakeLists.txt: ENH: Added
- cmLocalUnixMakefileGenerator2 to build.
-
-2004-10-26 12:53 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Added object file
- dependency scanning.
-
-2004-10-26 10:24 andy
-
- * Source/CTest/cmCTestBuildHandler.cxx: ENH: Handle more REMARKS on
- SGI
-
-2004-10-26 10:15 king
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h: ENH: Split
- part of GetIncludeFlags method into separate
- GetIncludeDirectories method.
-
-2004-10-26 08:45 andy
-
- * Source/kwsys/SystemTools.hxx.in: COMP: Attempt to fix warnings on
- SGI
-
-2004-10-26 04:40 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-10-25 16:39 hoffman
-
- * Source/: cmLocalKdevelopGenerator.cxx,
- cmLocalKdevelopGenerator.h: ENH: add some more comments
-
-2004-10-25 15:08 hoffman
-
- * Tests/: LoadCommand/CMakeLists.txt,
- LoadCommand/LoadedCommand.cxx, LoadCommand/LoadedCommand.h.in,
- LoadCommandOneConfig/CMakeLists.txt,
- LoadCommandOneConfig/LoadedCommand.cxx,
- LoadCommandOneConfig/LoadedCommand.h.in: ENH: clean up loaded
- command test so you can tell what really failed
-
-2004-10-25 13:40 hoffman
-
- * Source/cmSystemTools.cxx: COMP: remove an unused variable warning
-
-2004-10-25 13:24 hoffman
-
- * ChangeLog.manual, Source/cmSystemTools.cxx,
- Source/cmSystemTools.h, Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/complex.cxx,
- Tests/LoadCommand/LoadedCommand.cxx,
- Tests/LoadCommandOneConfig/LoadedCommand.cxx: ENH: move stuff
- from main tree to fix the runsingle program mess
-
-2004-10-25 13:16 hoffman
-
- * Source/cmSystemTools.cxx, Source/cmSystemTools.h,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/complex.cxx: FIX: go back
- to not trying to handle spaces in the path for run single command
- and comment it so that people know to call the right thing
-
-2004-10-25 12:26 hoffman
-
- * Source/cmLocalKdevelopGenerator.cxx: COMP: remove warnings
-
-2004-10-25 12:15 hoffman
-
- * Tests/: Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/complex.cxx: ENH: add test back
- for single char exe
-
-2004-10-25 11:59 hoffman
-
- * Source/cmSystemTools.cxx, Tests/LoadCommand/LoadedCommand.cxx,
- Tests/LoadCommandOneConfig/LoadedCommand.cxx: FIX: fix
- RunSingleCommand to work with spaces in the path, and with an
- already quoted command
-
-2004-10-25 10:04 andy
-
- * Source/CMakeLists.txt: ENH: Allow disabling of long running tests
-
-2004-10-25 04:34 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-10-24 11:38 andy
-
- * Source/cmVersion.cxx: STYLE: Nightly Version update
-
-2004-10-22 21:52 hoffman
-
- * Tests/: Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/complex.cxx: remove run program
- test until run single command is fixed
-
-2004-10-22 21:03 hoffman
-
- * Source/cmSystemTools.cxx: undo last check in as it breaks borland
- with spaces some how
-
-2004-10-22 17:51 hoffman
-
- * ChangeLog.manual, Source/cmCTest.cxx,
- Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmSystemTools.cxx, Source/kwsys/SystemTools.cxx,
- Tests/Complex/Executable/A.cxx,
- Tests/Complex/Executable/CMakeLists.txt,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/A.cxx,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/A.cxx,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/complex.cxx: fixes from
- main tree
-
-2004-10-22 17:05 hoffman
-
- * Tests/: Complex/Executable/A.cxx,
- ComplexOneConfig/Executable/A.cxx,
- ComplexRelativePaths/Executable/A.cxx: ENH: add missing file
-
-2004-10-22 17:00 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmSystemTools.cxx,
- Tests/Complex/Executable/CMakeLists.txt,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/complex.cxx: FIX: fix the
- problem where a target is a single character and nmake gets
- confused and add a test for it
-
-2004-10-22 16:58 hoffman
-
- * Source/cmTarget.cxx: COMP: remove warnings
-
-2004-10-22 15:45 andy
-
- * Source/CMakeLists.txt: COMP: Remove unnecessary commit
-
-2004-10-22 15:44 andy
-
- * bootstrap, Source/CMakeLists.txt, Source/cmCTest.cxx,
- Source/cmDocumentation.cxx, Source/cmDumpDocumentation.cxx,
- Source/cmVersion.cxx, Source/cmVersion.h, Source/cmake.cxx,
- Source/CTest/cmCTestUpdateHandler.cxx: ENH: Add development
- version support in CMake
-
-2004-10-22 10:19 hoffman
-
- * Source/cmLocalKdevelopGenerator.cxx: COMP: remove warning
-
-2004-10-21 17:29 hoffman
-
- * ChangeLog.manual: add .0.5
-
-2004-10-21 17:11 hoffman
-
- * ChangeLog.manual: add .0.5
-
-2004-10-21 16:07 andy
-
- * Source/CTest/cmCTestTestHandler.cxx: BUG: Fix reporting of path
- and full command when test program was not found
-
-2004-10-21 15:21 hoffman
-
- * Source/: cmLocalGenerator.cxx, cmTarget.cxx: COMP: fix warnings
-
-2004-10-21 14:55 hoffman
-
- * Source/cmLocalGenerator.cxx: COMP: fix warning
-
-2004-10-21 14:34 hoffman
-
- * Modules/CMakeDetermineFortranCompiler.cmake,
- Modules/Platform/Windows-g77.cmake, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.h,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx, Source/cmTarget.cxx,
- Source/cmTarget.h: ENH: add the ability to generate custom
- commands for a language that is not supported by an IDE
-
-2004-10-21 13:34 andy
-
- * Source/CTest/cmCTestBuildHandler.cxx: BUG: Handle remarks on SGI
- properly
-
-2004-10-21 11:58 hoffman
-
- * Source/: cmLocalKdevelopGenerator.cxx,
- cmLocalKdevelopGenerator.h: ENH: better support for kdevelop3
-
-2004-10-20 12:37 andy
-
- * Source/kwsys/CommandLineArguments.cxx: COMP: Remove warning
-
-2004-10-20 08:19 hoffman
-
- * Source/cmCTest.cxx: fix warning on LRB
-
-2004-10-20 08:14 hoffman
-
- * Source/cmCTest.cxx: COMP: remove warning
-
-2004-10-19 15:09 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Modules/CMakeTestForFreeVC.cxx,
- Modules/Platform/Windows-cl.cmake, Source/CMakeLists.txt,
- Source/cmAddExecutableCommand.cxx, Source/cmCTest.cxx,
- Source/cmCTest.h, Source/cmFileCommand.cxx,
- Source/cmForEachCommand.cxx, Source/cmGlob.cxx, Source/cmGlob.h,
- Source/cmGlobalCodeWarriorGenerator.cxx,
- Source/cmGlobalCodeWarriorGenerator.h,
- Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmGlobalVisualStudio6Generator.cxx,
- Source/cmGlobalVisualStudio6Generator.h,
- Source/cmGlobalVisualStudio71Generator.cxx,
- Source/cmGlobalVisualStudio71Generator.h,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.h,
- Source/cmIncludeExternalMSProjectCommand.cxx,
- Source/cmListFileLexer.c, Source/cmListFileLexer.h,
- Source/cmListFileLexer.in.l,
- Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx, Source/cmMakefile.cxx,
- Source/cmSystemTools.h, Source/cmTryRunCommand.cxx,
- Source/cmWin32ProcessExecution.cxx,
- Source/cmWin32ProcessExecution.h, Source/cmakemain.cxx,
- Source/kwsys/SystemTools.cxx,
- Tests/StringFileTest/CMakeLists.txt,
- Utilities/Release/cmake_release.sh,
- Utilities/Release/config_IRIX64: ENH: move 2.0.4 to LRB
-
-2004-10-19 14:57 hoffman
-
- * ChangeLog.manual: update change log
-
-2004-10-19 14:56 hoffman
-
- * Source/cmCTest.cxx: merge from main tree, add more warning cases
- to ctest
-
-2004-10-19 14:51 hoffman
-
- * bootstrap: ENH: perfer gmake for bootstrap
-
-2004-10-19 13:25 andy
-
- * Tests/CTestTest/test.cmake.in: ENH: Display version of ctest
- first
-
-2004-10-19 13:25 andy
-
- * Source/CTest/cmCTestBuildHandler.cxx: ENH: Add regular expression
- for remarks on IRIX
-
-2004-10-19 13:02 hoffman
-
- * Source/cmSystemTools.cxx: BUG: if the paths share nothing then
- just return the remote path with no ..
-
-2004-10-19 12:48 andy
-
- * Source/cmCTest.cxx: BUG: Remove instances of // in the output
-
-2004-10-19 12:38 andy
-
- * Source/cmCTest.cxx: EHN: Even more cleanup
-
-2004-10-19 10:59 andy
-
- * Source/CMakeLists.txt, Tests/CTestTest/test.cmake.in: ERR: Fix
- problems on windows
-
-2004-10-18 18:11 will
-
- * bootstrap: COMP: Fix on sun
-
-2004-10-18 17:24 andy
-
- * Source/CMakeLists.txt: ENH: Remove bogus clean step
-
-2004-10-18 15:37 andy
-
- * Source/CMakeLists.txt: BUG: Ok, this should make the test
- actually do something
-
-2004-10-18 15:05 andy
-
- * Source/CMakeLists.txt: ENH: Do bootstrap test on all unix systems
-
-2004-10-18 13:19 hoffman
-
- * Source/cmSystemTools.cxx: ENH: better comments and variable names
-
-2004-10-18 12:33 andy
-
- * Source/CMakeLists.txt: ENH: Add bootstrap test
-
-2004-10-18 11:48 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: make sure output
- path is used for target with canonical name
-
-2004-10-18 11:34 andy
-
- * bootstrap: ENH: Add check for previous bootstrap in the source
- tree when doing out-of-source build
-
-2004-10-17 22:47 andy
-
- * Source/CTest/: cmCTestCoverageHandler.cxx,
- cmCTestCoverageHandler.h: BUG: Fix output to match the Dart
- output
-
-2004-10-17 22:47 andy
-
- * Source/CTest/cmCTestTestHandler.cxx: ENH: Cleanups and unify
- output
-
-2004-10-17 22:46 andy
-
- * Source/kwsys/CMakeLists.txt: ENH: Specify full path to the
- executable
-
-2004-10-17 22:46 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: ENH: Add method to get the
- relative path to source or build
-
-2004-10-17 19:45 andy
-
- * Source/CTest/: cmCTestCoverageHandler.cxx,
- cmCTestCoverageHandler.h: ENH: Update to the new coverage code.
- It may not be perfect yet, but it is a start
-
-2004-10-17 19:02 andy
-
- * Tests/CTestTest/test.cmake.in: ENH: Propagate more things
-
-2004-10-17 18:50 andy
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH: Add
- method to find file in parent directories if it exists
-
-2004-10-17 18:50 andy
-
- * Tests/CTestTest/test.cmake.in: ENH: Propagate MEMORYCHECK_COMMAND
- and COVERAGE_COMMAND to the CTest test
-
-2004-10-17 18:49 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: ENH: Handle coverage errors
-
-2004-10-15 09:24 king
-
- * Source/: cmake.cxx, cmake.h: ENH: Added --check-rerun option to
- allow a runtime check of whether a new generate should really be
- done.
-
-2004-10-15 09:23 king
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Added
- FileTimeCompare method to compare file modification times.
- Currently the resolution is limited to one second.
-
-2004-10-15 08:57 king
-
- * Source/cmLocalUnixMakefileGenerator2.cxx: ENH: Added generation
- of rule to build object file.
-
-2004-10-14 16:50 hoffman
-
- * Source/cmLocalGenerator.cxx: BUG: make sure all returns for
- ConvertToRelativeOutputPath get passed by ConvertToOutputPath
-
-2004-10-14 15:09 hoffman
-
- * Source/cmLocalGenerator.cxx: BUG: now that system tools relative
- path works, clean up the convert to relative output path code
-
-2004-10-14 11:59 hoffman
-
- * Source/cmLocalKdevelopGenerator.cxx: COMP: remove warning
-
-2004-10-14 11:46 hoffman
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: BUG: allow split
- string to know if it is separating a path
-
-2004-10-13 11:37 hoffman
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: BUG: fix and comment
- relative path funciton
-
-2004-10-12 18:29 andy
-
- * Modules/Dart.cmake: ENH: If dart or ctest are not found, use
- ctest. For default drop location etc, support http submit (just
- set DROP_METHOD to http. Only look for tclsh if DART_ROOT is set
-
-2004-10-12 10:57 hoffman
-
- * bootstrap, Source/CMakeLists.txt: allow kdevelop for cygwin
-
-2004-10-12 10:22 hoffman
-
- * Source/cmLocalKdevelopGenerator.cxx: BUG: remove bad headers
-
-2004-10-12 09:50 hoffman
-
- * bootstrap, Source/cmake.cxx: BUG: do not build kdevlop stuff when
- bootstrapping
-
-2004-10-11 16:35 andy
-
- * Source/cmLocalKdevelopGenerator.cxx: ENH: Support not writing
- files to the source tree. Generate single project file for whole
- project, some other little cleanups
-
-2004-10-11 15:25 andy
-
- * Source/cmLocalKdevelopGenerator.cxx: BUG: Fix generated XML
-
-2004-10-11 14:47 andy
-
- * Source/CMakeLists.txt: STYLE: Remove anoying message
-
-2004-10-11 13:57 andy
-
- * Source/cmCTest.cxx: BUG: On Windows, remove extra CR characters.
- Hopefully this will result in not duplicated new-lines
-
-2004-10-11 11:57 hoffman
-
- * Source/kwsys/SystemTools.cxx: BUG: fix split program from args to
- not get stuck in an infinite loop in some cases
-
-2004-10-11 11:55 hoffman
-
- * Modules/CMakeTestCXXCompiler.cmake: ENH: make sure the c++
- compiler is a c++ compiler
-
-2004-10-11 11:47 hoffman
-
- * bootstrap: ENH: add kdev to bootstrap
-
-2004-10-11 11:32 hoffman
-
- * Source/: CMakeLists.txt, cmGlobalKdevelopGenerator.cxx,
- cmGlobalKdevelopGenerator.h, cmLocalKdevelopGenerator.cxx,
- cmLocalKdevelopGenerator.h, cmake.cxx: NEW: add kdevelop patch
- from Alexander Neundorf
-
-2004-10-11 08:02 king
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ERR: Replaced
- std::string with kwsys_stl::string for portability.
-
-2004-10-10 12:14 andy
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH: Add
- method to retrieve parent directory and for checking if directory
- is a subdirectory of another directory
-
-2004-10-06 12:41 hoffman
-
- * ChangeLog.manual, Source/cmAddExecutableCommand.cxx: FIX: merge
- from main tree mac bundle fix
-
-2004-10-06 12:25 hoffman
-
- * ChangeLog.manual, Source/cmCTest.cxx, Source/cmCTest.h: ENH:
- merge from main tree fix for build overview page
-
-2004-10-05 16:16 andy
-
- * Source/CMakeLists.txt: ERR: Too much commits
-
-2004-10-05 16:14 andy
-
- * Source/: CMakeLists.txt, cmCTest.cxx, CTest/CMakeLists.txt,
- CTest/cmCTestSubmit.cxx: PERF: Several cleanups, and remove need
- for Curl directory to be in include path
-
-2004-10-05 11:37 hoffman
-
- * Source/cmake.cxx: FIX: correctly handle if path table can not
- open
-
-2004-10-05 11:29 hoffman
-
- * bootstrap: ENH: pick native compilers first, and aCC before CC
-
-2004-10-05 10:59 hoffman
-
- * Source/kwsys/SystemTools.cxx: BUG: fix realpath problem and unix
- slashes
-
-2004-10-05 10:13 andy
-
- * Source/CTest/cmCTestSubmit.cxx: ERR: Fix TRUE build problem and
- replace error couts with cerrs
-
-2004-10-05 10:00 andy
-
- * Source/cmCTest.cxx: ERR: Fix Windows build
-
-2004-10-05 09:25 martink
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: COMP: fix
- some compile issues with insert
-
-2004-10-05 09:01 martink
-
- * Source/cmake.cxx: COMP: fix bad include file
-
-2004-10-05 08:49 andy
-
- * bootstrap: ERR: Fix bootstrap
-
-2004-10-05 08:33 andy
-
- * Modules/: CheckTypeSize.c.in, CheckTypeSize.cmake,
- CheckTypeSize.c: ENH: Add option of adding random include files
- before doing CheckTypeSize
-
-2004-10-05 08:32 andy
-
- * Modules/CheckIncludeFiles.cmake: ENH: When test fails, write out
- the output
-
-2004-10-04 16:15 king
-
- * Source/: cmLocalUnixMakefileGenerator2.cxx,
- cmLocalUnixMakefileGenerator2.h: ENH: Started new makefile
- generator implementation. It will temporarily be called
- cmLocalUnixMakefileGenerator2 until it is ready to replace the
- original completely.
-
-2004-10-04 12:31 martink
-
- * CMake.rtf, Source/cmake.cxx, Source/cmake.h,
- Source/kwsys/SystemTools.cxx, Source/kwsys/SystemTools.hxx.in:
- ENH: Mathieus support for path conversions
-
-2004-10-04 12:02 andy
-
- * Tests/CTestTest/test.cmake.in: BUG: Use kwsys from the source
- tree
-
-2004-10-04 08:06 andy
-
- * Tests/CTestTest/test.cmake.in: ENH: Better sorting of results
-
-2004-10-03 07:27 andy
-
- * Tests/CTestTest/test.cmake.in: BUG: Fix problem with spaces in
- the path
-
-2004-10-03 07:14 andy
-
- * Source/ctest.cxx: BUG: Attempt to remove memory leak
-
-2004-10-01 13:23 andy
-
- * Source/CTest/cmCTestBuildHandler.cxx: BUG: Add regular expression
- to vector
-
-2004-10-01 13:10 andy
-
- * Tests/CTestTest/test.cmake.in: ENH: Use existing CTest and cmake
-
-2004-10-01 12:21 andy
-
- * Source/: cmCTest.cxx, cmCTest.h, CTest/cmCTestScriptHandler.cxx,
- CTest/cmCTestScriptHandler.h: ENH: Add CTEST_EXECUTABLE_NAME to
- CTest scripting. This way you do not have to specify ctest
- executable in CTEST_COMMAND, but just a variable
-
-2004-10-01 11:36 king
-
- * Source/kwsys/testProcess.c: ERR: Added missing include of
- string.h
-
-2004-10-01 11:13 andy
-
- * Tests/CTestTest/test.cmake.in: ENH: Let us recognize it on the
- dashboard
-
-2004-09-30 18:45 andy
-
- * Source/CMakeLists.txt: ENH: Cleanup CTest test
-
-2004-09-30 18:45 andy
-
- * Tests/CTestTest/test.cmake.in: ENH: Do kwsys instead of CMake
-
-2004-09-30 18:06 andy
-
- * Source/CTest/: cmCTestBuildHandler.cxx, cmCTestBuildHandler.h:
- ERR: Fix for non-gcc/icc compilers
-
-2004-09-30 17:42 king
-
- * Source/kwsys/testProcess.c: ENH: Added optional display of output
- for tests. Avoid printing alot of output for test 6.
-
-2004-09-30 17:27 andy
-
- * Source/CTest/cmCTestBuildHandler.h: ERR: Fix error
-
-2004-09-30 16:24 andy
-
- * bootstrap: BUG: Check if the compiler is gnu. If it is, do not do
- special platform tests. Fixes Bug #1215 - bootstrap uses native
- flags with gnu compiler on OSF
-
-2004-09-30 16:20 andy
-
- * Source/CTest/: cmCTestBuildHandler.cxx, cmCTestBuildHandler.h:
- ENH: Add support for SourceFile and LineNumber
-
-2004-09-29 16:07 hoffman
-
- * Source/: cmCTest.h, cmCacheManager.cxx, cmCacheManager.h,
- cmDynamicLoader.cxx, cmGlobalGenerator.cxx,
- cmLoadCacheCommand.cxx, cmLocalUnixMakefileGenerator.cxx,
- cmMakefile.cxx, cmTarget.cxx, cmakewizard.cxx: ENH: shorten the
- symbols a bit and remove maps of std::string for map of
- cmStdString
-
-2004-09-29 14:14 andy
-
- * Source/CTest/: cmCTestTestHandler.cxx, cmCTestTestHandler.h: BUG:
- Remove maximum size of test output
-
-2004-09-29 13:21 andy
-
- * Source/kwsys/SystemTools.hxx.in: ERR: Fix Windows build
-
-2004-09-29 12:20 andy
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h,
- kwsys/SystemTools.cxx, kwsys/SystemTools.hxx.in: ENH: Move
- permissions code to kwsys so that copyfile can use it. Fixes Bug
- #1133 - cmake -E copy file dir sets the wrong permissions on the
- destination directory
-
-2004-09-29 11:52 andy
-
- * Source/CTest/cmCTestScriptHandler.cxx: BUG: If extra update
- failes, continue with dashboard. Closes Bug #894 - Fatal CVS
- update error kills test, and is not reported
-
-2004-09-29 11:18 andy
-
- * Source/kwsys/SystemTools.cxx: ENH: When copy file, if the output
- file exits, delete it first
-
-2004-09-29 08:58 andy
-
- * Source/kwsys/CMakeLists.txt: ENH: Allow CMake to use
- CommandLineArguments without warning
-
-2004-09-29 08:34 andy
-
- * Source/kwsys/CommandLineArguments.hxx.in: ENH: Add lots of
- comments
-
-2004-09-29 07:56 andy
-
- * Source/kwsys/: CommandLineArguments.cxx,
- CommandLineArguments.hxx.in: ENH: Add access to last argument
- parsed
-
-2004-09-28 17:51 andy
-
- * CMakeLists.txt: ENH: Enable Command Line Arguments
-
-2004-09-28 17:51 andy
-
- * Source/CTest/: cmCTestScriptHandler.cxx, cmCTestScriptHandler.h:
- ENH: Move all extracting of variables to ExtractVariables. This
- way it is easy to know what variables are used
-
-2004-09-28 11:34 andy
-
- * Source/kwsys/: CommandLineArguments.cxx,
- CommandLineArguments.hxx.in: ENH: Add accessor for Argv0
-
-2004-09-28 09:00 andy
-
- * Source/CTest/: cmCTestScriptHandler.h, cmCTestScriptHandler.cxx:
- ENH: Add some documentation
-
-2004-09-27 16:33 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx: BUG: make sure release
- flags are replaced
-
-2004-09-27 15:21 hoffman
-
- * Source/CMakeLists.txt: ENH: allow for a different jni.h to enable
- java testing
-
-2004-09-27 15:15 hoffman
-
- * Source/CMakeLists.txt: ENH: allow for a different jni.h to enable
- java testing
-
-2004-09-27 15:11 hoffman
-
- * Source/CMakeLists.txt: space in path problem
-
-2004-09-27 14:39 hoffman
-
- * Source/CMakeLists.txt: ENH: use jni.h to determine java version
-
-2004-09-27 14:35 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, Source/cmCTest.cxx,
- Utilities/Release/cmake_release.sh: merge from main tree and
- change version to 2.0.4
-
-2004-09-27 14:21 hoffman
-
- * Source/CMakeLists.txt: ENH: use jni.h to determine java version
-
-2004-09-27 13:36 andy
-
- * Source/cmCTest.cxx: BUG: If notes file is missing, create empty
- notes file with error message
-
-2004-09-27 13:03 hoffman
-
- * Tests/Fortran/CMakeLists.txt: clean up output of test and force
- verbose makefiles
-
-2004-09-27 11:36 hoffman
-
- * Modules/CMakeJavaCompiler.cmake.in,
- Modules/CMakeJavaInformation.cmake,
- Source/cmLocalUnixMakefileGenerator.cxx: BUG: make sure java jar
- files are not libfoo.jar but are just foo.jar
-
-2004-09-27 11:03 hoffman
-
- * Source/CMakeLists.txt: ENH: better message for skipping java
-
-2004-09-27 09:49 andy
-
- * Modules/Documentation.cmake: ENH: Replace INCLUDE(Find...) with
- FIND_PACKAGE(...)
-
-2004-09-24 16:54 hoffman
-
- * Source/CMakeLists.txt: ENH: use correct args for test of java
-
-2004-09-24 16:34 hoffman
-
- * Tests/Java/: CMakeCheckJavaPath.java, CMakeLists.txt: try and get
- this java test to work
-
-2004-09-24 16:34 hoffman
-
- * Source/CMakeLists.txt: ENH: only use newer java for testing
-
-2004-09-24 15:40 hoffman
-
- * Tests/Java/: CMakeCheckJavaPath.java, CMakeLists.txt: ENH: add
- some java code to try and find the system path
-
-2004-09-24 14:37 hoffman
-
- * Modules/: CMakeCXXInformation.cmake,
- CMakeFortranInformation.cmake,
- CMakeSystemSpecificInformation.cmake: BUG: LINK_FLAGS are now all
- LINK_(LANG)_FLAGS
-
-2004-09-24 11:35 martink
-
- * Source/cmLocalVisualStudio6Generator.cxx: BUG: fix crash with vs6
-
-2004-09-24 11:34 martink
-
- * Source/CMakeLists.txt: ENH: check for all parts of java
-
-2004-09-24 11:05 hoffman
-
- * Tests/Java/CMakeLists.txt: ENH: remove classpath so that this
- test passes with older java compilers that clober the system
- class path with the -classpath option
-
-2004-09-24 10:07 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: replace all enabled
- languages in rule vars
-
-2004-09-24 09:34 hoffman
-
- * Source/cmGlobalGenerator.cxx: ENH: change ignore function so that
- it first checks to see if the extension has a language
-
-2004-09-24 09:11 hoffman
-
- * Modules/Platform/Darwin.cmake: ENH: use c++ with c++ and c flags
- with c
-
-2004-09-24 08:39 hoffman
-
- * Source/: cmLocalUnixMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator.h: ENH: correctly ignore files
-
-2004-09-23 17:49 hoffman
-
- * Source/CMakeLists.txt: temporary fix to try and get a clean
- dashboard
-
-2004-09-23 15:02 andy
-
- * Source/kwsys/CommandLineArguments.cxx: ERR: Fix memory problem
-
-2004-09-23 11:53 andy
-
- * Source/kwsys/CommandLineArguments.cxx: STYLE: Only allocate as
- much space as needed
-
-2004-09-23 11:45 andy
-
- * Source/kwsys/CommandLineArguments.cxx: ENH: Make
- GetRemainingArguments actually work
-
-2004-09-23 11:44 hoffman
-
- * Source/: cmLocalUnixMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator.h: ENH: only replace the language
- being used in expand rule variables
-
-2004-09-23 09:11 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: STYLE: remove warning
-
-2004-09-23 09:08 hoffman
-
- * Source/cmTryCompileCommand.cxx: remove warning
-
-2004-09-23 08:51 hoffman
-
- * Modules/CMakeRCInformation.cmake, Source/cmGlobalGenerator.cxx:
- ENH: fix problems with .def and RC files
-
-2004-09-23 08:20 hoffman
-
- * CMakeLists.txt: ENH: make sure cmake has 2.0
-
-2004-09-23 07:53 andy
-
- * bootstrap: ENH: Attempt to detect a non-parallel make
-
-2004-09-22 17:50 hoffman
-
- * Source/cmTarget.cxx: BUG: fix perfered linker language code
-
-2004-09-22 17:41 hoffman
-
- * Tests/Java/CMakeLists.txt: use verbose makefiles
-
-2004-09-22 16:51 hoffman
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: make it verbose
-
-2004-09-22 16:44 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx: fix compilation
-
-2004-09-22 15:14 hoffman
-
- * Source/cmProjectCommand.cxx: remove warnings
-
-2004-09-22 14:52 hoffman
-
- * Modules/CMakeJavaInformation.cmake: BUG: let the generator quote
- the path
-
-2004-09-22 14:42 hoffman
-
- * Modules/CMakeCCompiler.cmake.in, Modules/CMakeCInformation.cmake,
- Modules/CMakeCXXCompiler.cmake.in,
- Modules/CMakeCXXInformation.cmake,
- Modules/CMakeCommonLanguageInclude.cmake,
- Modules/CMakeDetermineJavaCompiler.cmake,
- Modules/CMakeDetermineRCCompiler.cmake,
- Modules/CMakeFortranInformation.cmake,
- Modules/CMakeGenericSystem.cmake,
- Modules/CMakeJavaCompiler.cmake.in,
- Modules/CMakeJavaInformation.cmake,
- Modules/CMakeRCCompiler.cmake.in,
- Modules/CMakeRCInformation.cmake,
- Modules/CMakeSystemSpecificInformation.cmake,
- Modules/CMakeTestJavaCompiler.cmake,
- Modules/CMakeTestRCCompiler.cmake, Modules/Platform/AIX.cmake,
- Modules/Platform/FreeBSD.cmake, Modules/Platform/HP-UX.cmake,
- Modules/Platform/IRIX.cmake, Modules/Platform/IRIX64.cmake,
- Modules/Platform/Linux-como.cmake, Modules/Platform/Linux.cmake,
- Modules/Platform/MP-RAS.cmake, Modules/Platform/NetBSD.cmake,
- Modules/Platform/OSF1.cmake, Modules/Platform/RISCos.cmake,
- Modules/Platform/SunOS.cmake, Modules/Platform/ULTRIX.cmake,
- Modules/Platform/UNIX_SV.cmake,
- Modules/Platform/Windows-cl.cmake,
- Modules/Platform/Windows-gcc.cmake, Source/CMakeLists.txt,
- Source/cmCommands.cxx, Source/cmEnableLanguageCommand.cxx,
- Source/cmEnableLanguageCommand.h, Source/cmGlobalGenerator.cxx,
- Source/cmGlobalGenerator.h, Source/cmInstallFilesCommand.cxx,
- Source/cmInstallProgramsCommand.cxx, Source/cmLocalGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.h,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx, Source/cmMakefile.cxx,
- Source/cmProjectCommand.cxx, Source/cmTarget.cxx,
- Source/cmTarget.h, Source/cmTryCompileCommand.cxx,
- Source/cmTryRunCommand.cxx, Tests/Fortran/CMakeLists.txt,
- Tests/Java/A.java, Tests/Java/CMakeLists.txt,
- Tests/Java/HelloWorld.java: ENH: major changes to support
- addition of languages from cmake modules directory.
-
-2004-09-22 10:06 hoffman
-
- * Source/CMakeLists.txt: ENH: only try to use fortran if the
- generator is make based
-
-2004-09-22 08:50 hoffman
-
- * Modules/CMakeFortranCompiler.cmake.in: BUG: fix GNU check
- variable and add new variables used by enable language
-
-2004-09-21 12:51 hoffman
-
- * Source/cmListFileLexer.h: merge from main tree
-
-2004-09-21 12:47 hoffman
-
- * ChangeLog.manual, Source/cmListFileLexer.c,
- Source/cmListFileLexer.in.l, Tests/StringFileTest/CMakeLists.txt:
- merge from main tree
-
-2004-09-20 14:39 hoffman
-
- * Modules/FindJava.cmake: ENH: look for java in more places
-
-2004-09-20 13:47 hoffman
-
- * Source/: cmGlobalGenerator.cxx,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx: BUG: branch only fix for
- VSExternalInclude
-
-2004-09-20 08:51 king
-
- * Source/cmListFileLexer.c, Source/cmListFileLexer.in.l,
- Tests/StringFileTest/CMakeLists.txt: BUG#1179: Fix for syntax in
- unquoted arguments.
-
-2004-09-17 16:46 hoffman
-
- * ChangeLog.manual, Source/CMakeLists.txt,
- Source/cmForEachCommand.cxx, Source/cmGlob.cxx, Source/cmGlob.h,
- Source/cmGlobalVisualStudio6Generator.cxx,
- Source/cmGlobalVisualStudio71Generator.cxx,
- Source/cmGlobalVisualStudio71Generator.h,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmIncludeExternalMSProjectCommand.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmWin32ProcessExecution.cxx,
- Source/cmWin32ProcessExecution.h, Source/cmakemain.cxx,
- Source/kwsys/SystemTools.cxx,
- Tests/VSExternalInclude/CMakeLists.txt,
- Tests/VSExternalInclude/main.cpp,
- Tests/VSExternalInclude/Lib1/CMakeLists.txt,
- Tests/VSExternalInclude/Lib1/lib1.cpp,
- Tests/VSExternalInclude/Lib1/lib1.h,
- Tests/VSExternalInclude/Lib2/CMakeLists.txt,
- Tests/VSExternalInclude/Lib2/lib2.cpp,
- Tests/VSExternalInclude/Lib2/lib2.h: merge from main tree
-
-2004-09-17 16:00 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx: merge from main tree
- bug 1041
-
-2004-09-17 15:57 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx: BUG: fix for bug 1041,
- _MBCS sometimes added for UNIICODE which is bad
-
-2004-09-17 09:14 hoffman
-
- * Modules/CMakeJavaCompiler.cmake.in: BUG: commit bug 1123
-
-2004-09-17 09:01 hoffman
-
- * Source/cmProjectCommand.h: BUG: 1163 fix documentation
-
-2004-09-16 17:16 hoffman
-
- * Source/cmFileCommand.cxx: merge from main tree fix bug 1122
-
-2004-09-16 17:13 andy
-
- * Source/CTest/cmCTestBuildHandler.cxx: ENH: Attempt to handle
- Intel's remarks. Close Bug #1156 - Better support for icc
- 'remark'
-
-2004-09-16 12:39 andy
-
- * Source/kwsys/SystemTools.cxx: ENH: Add missing include
-
-2004-09-16 10:58 andy
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH: Add
- method to retrieve the terminal width
-
-2004-09-16 10:49 andy
-
- * Source/kwsys/CommandLineArguments.cxx: ENH: a bit more cleanup.
- The help should really be replaced by something like
- cmDocumentation
-
-2004-09-16 10:48 martink
-
- * Source/cmGlobalVisualStudio6Generator.cxx,
- Tests/VSExternalInclude/CMakeLists.txt: BUG: fix VSExternal for
- visual studio 6
-
-2004-09-16 10:27 andy
-
- * Source/kwsys/: CommandLineArguments.cxx,
- CommandLineArguments.hxx.in: ENH: Condense help string, add
- support for setting line length and make it work
-
-2004-09-15 15:15 hoffman
-
- * Source/: cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio71Generator.h,
- cmGlobalVisualStudio7Generator.cxx: BUG: fix external project
- command for VS 7 and 71
-
-2004-09-15 14:08 andy
-
- * Source/: cmGlob.cxx, cmGlob.h: ENH: Remove double slash
-
-2004-09-15 13:33 andy
-
- * Source/cmGlob.cxx: BUG: Attempt to fix bug on Windows (and apple)
- where files returned are all lowercase
-
-2004-09-15 13:31 andy
-
- * Source/cmForEachCommand.cxx: BUG: Propagate file name and line
- number inside FOREACH. Fixes Bug #1169 - Erro messages inside
- FOREACH have bad filename and line number
-
-2004-09-15 13:03 hoffman
-
- * Source/cmGlobalVisualStudio7Generator.cxx: ENH: fix for vs 70
- generator
-
-2004-09-15 12:07 hoffman
-
- * Source/: cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx,
- cmIncludeExternalMSProjectCommand.cxx,
- cmLocalVisualStudio7Generator.cxx: ENH: clean up of
- INCLUDE_EXTERNAL_MSPROJECT contributed by Clinton Stimpson
-
-2004-09-15 11:31 hoffman
-
- * Source/: cmGlobalGenerator.cxx,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx: BUG: make sure env CC and CXX
- are not set for VS IDE builds
-
-2004-09-15 10:35 martink
-
- * Tests/VSExternalInclude/CMakeLists.txt: ENH: produce better
- output
-
-2004-09-15 10:32 martink
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeDetermineCXXCompiler.cmake,
- CMakeDetermineFortranCompiler.cmake: ENH: do not check for gnu
- for visual studio
-
-2004-09-15 09:22 andy
-
- * Source/kwsys/: CommandLineArguments.cxx,
- CommandLineArguments.hxx.in: ENH: Move callback structure out of
- the public interface. Also block the warning on Visual Studio
- Debug
-
-2004-09-14 16:34 hoffman
-
- * Tests/VSExternalInclude/: CMakeLists.txt: ENH: add a test for
- external projects
-
-2004-09-14 16:01 hoffman
-
- * Source/CMakeLists.txt, Tests/VSExternalInclude/CMakeLists.txt,
- Tests/VSExternalInclude/main.cpp,
- Tests/VSExternalInclude/Lib1/CMakeLists.txt,
- Tests/VSExternalInclude/Lib1/lib1.cpp,
- Tests/VSExternalInclude/Lib1/lib1.h,
- Tests/VSExternalInclude/Lib2/CMakeLists.txt,
- Tests/VSExternalInclude/Lib2/lib2.cpp,
- Tests/VSExternalInclude/Lib2/lib2.h: ENH: add a test for external
- projects
-
-2004-09-14 14:05 hoffman
-
- * Source/: cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx,
- cmIncludeExternalMSProjectCommand.cxx: bug fixes for external
- projects
-
-2004-09-14 11:48 martink
-
- * Source/kwsys/: CommandLineArguments.cxx,
- CommandLineArguments.hxx.in: ERR: Fix borland build
-
-2004-09-14 11:39 andy
-
- * Source/kwsys/CommandLineArguments.cxx: ERR: Add missing include
-
-2004-09-14 10:34 andy
-
- * Source/kwsys/: CommandLineArguments.cxx,
- CommandLineArguments.hxx.in: ENH: Use const correctness for
- arguments
-
-2004-09-14 09:19 hoffman
-
- * Source/: cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx: BUG: fix include external
- project bug
-
-2004-09-13 19:06 andy
-
- * Source/kwsys/: CommandLineArguments.cxx,
- testCommandLineArguments.cxx: ERR: More missing ios and includes
-
-2004-09-13 18:57 andy
-
- * Source/kwsys/CommandLineArguments.cxx: ERR: Fix IOS namespace
-
-2004-09-13 16:15 andy
-
- * Source/kwsys/: CMakeLists.txt, CommandLineArguments.cxx,
- CommandLineArguments.hxx.in, testCommandLineArguments.cxx: ENH:
- Move command line argument parsing code to kwsys
-
-2004-09-10 14:40 hoffman
-
- * Source/: cmCTest.cxx, cmakemain.cxx: ENH: fix warning correctly
-
-2004-09-10 11:19 andy
-
- * CMakeLists.txt: ENH: Add warning messages if curses library is
- not found
-
-2004-09-10 11:15 andy
-
- * Modules/FindQt.cmake: ENH: Use FIND_PACKAGE instead of
- INCLUDE(Find...
-
-2004-09-10 08:42 martink
-
- * Source/cmCTest.cxx: fix dash8 warning
-
-2004-09-10 08:30 martink
-
- * Source/CTest/cmCTestTestHandler.h: fix HPUX bugs
-
-2004-09-09 16:05 hoffman
-
- * Modules/Platform/Linux-ifort.cmake: add ifort support
-
-2004-09-09 12:58 hoffman
-
- * Source/: cmCTest.cxx, cmakemain.cxx: WAR: remove a warning on i64
-
-2004-09-09 11:50 hoffman
-
- * Modules/Platform/HP-UX.cmake: try to fix fortran on hp
-
-2004-09-09 10:52 martink
-
- * Source/CTest/cmCTestTestHandler.cxx: missing include
-
-2004-09-09 09:31 martink
-
- * Source/CTest/cmCTestCoverageHandler.cxx: missing include
-
-2004-09-09 08:41 martink
-
- * Source/: CMakeLists.txt, cmCTest.cxx, cmCTest.h,
- CTest/cmCTestCoverageHandler.cxx, CTest/cmCTestCoverageHandler.h,
- CTest/cmCTestTestHandler.cxx, CTest/cmCTestTestHandler.h,
- CTest/cmCTestUpdateHandler.cxx: more cleanup of ctest
-
-2004-09-08 17:53 hoffman
-
- * Tests/Fortran/CMakeLists.txt: ENH: add more output for fortran so
- I can figure out what is going on with other fortran compilers
-
-2004-09-08 10:41 hoffman
-
- * Source/: cmWin32ProcessExecution.cxx, cmWin32ProcessExecution.h:
- BUG: don't close the pipes too early
-
-2004-09-07 16:55 hoffman
-
- * Source/: cmCacheManager.cxx, cmDumpDocumentation.cxx,
- cmEnableTestingCommand.cxx, cmExportLibraryDependencies.cxx,
- cmGlobalCodeWarriorGenerator.cxx,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx,
- cmLocalUnixMakefileGenerator.cxx,
- cmLocalVisualStudio6Generator.cxx, cmMakefile.cxx,
- cmTryCompileCommand.cxx, cmUseMangledMesaCommand.cxx,
- cmVTKWrapPythonCommand.cxx, cmVTKWrapTclCommand.cxx: ENH: add
- better error reporting for file open failures
-
-2004-09-07 16:03 hoffman
-
- * Source/: cmWin32ProcessExecution.cxx, kwsys/SystemTools.cxx: Fix
- leaked file and registry descriptors
-
-2004-09-07 12:51 martink
-
- * Source/: cmCTest.h, cmCTest.cxx: duh errors
-
-2004-09-07 11:45 martink
-
- * Source/: cmCTest.cxx, cmCTest.h: more warnings
-
-2004-09-07 11:28 martink
-
- * Source/CTest/cmCTestScriptHandler.cxx: more warnings
-
-2004-09-07 10:46 martink
-
- * Source/cmCTest.cxx: more cleanup
-
-2004-09-07 10:37 martink
-
- * Source/: CMakeLists.txt, cmCTest.cxx, cmCTest.h,
- CTest/cmCTestBuildHandler.cxx, CTest/cmCTestBuildHandler.h: more
- cleanup
-
-2004-09-07 09:17 martink
-
- * Source/: CMakeLists.txt, cmCTest.cxx, cmCTest.h,
- CTest/cmCTestConfigureHandler.cxx,
- CTest/cmCTestConfigureHandler.h, CTest/cmCTestScriptHandler.cxx,
- CTest/cmCTestScriptHandler.h, CTest/cmCTestUpdateHandler.cxx,
- CTest/cmCTestUpdateHandler.h: some bug fixes for my recent
- checkins and some more cleanup
-
-2004-09-06 14:43 martink
-
- * Source/CTest/cmCTestScriptHandler.cxx: another platform fix
-
-2004-09-06 14:17 martink
-
- * Source/CTest/cmCTestScriptHandler.h: another platform fix
-
-2004-09-06 13:54 martink
-
- * Source/cmCTest.cxx: jesus
-
-2004-09-06 13:37 martink
-
- * Source/CMakeLists.txt: oops
-
-2004-09-06 12:49 martink
-
- * Source/kwsys/SystemTools.cxx: fix warning
-
-2004-09-06 12:46 martink
-
- * Source/: CMakeLists.txt, cmCTest.cxx, cmCTest.h: starting cleanup
- of ctest
-
-2004-09-06 12:46 martink
-
- * Source/cmGlobalGenerator.cxx: warning fix
-
-2004-09-06 12:45 martink
-
- * Source/CTest/: cmCTestScriptHandler.cxx, cmCTestScriptHandler.h:
- broke out part of test scripting into seperate class
-
-2004-09-03 15:47 hoffman
-
- * ChangeLog.manual, Modules/CMakeTestForFreeVC.cxx,
- Modules/Platform/Windows-cl.cmake: merge from main tree fix for
- free vc tools
-
-2004-09-03 15:19 hoffman
-
- * Modules/: CMakeTestForFreeVC.cxx, Platform/Windows-cl.cmake: ENH
- better test for free VC tools
-
-2004-09-03 13:49 hoffman
-
- * Source/cmGlobalCodeWarriorGenerator.cxx: remove warning
-
-2004-09-03 13:48 hoffman
-
- * Source/cmGlobalCodeWarriorGenerator.cxx: fix for darwin
-
-2004-09-03 13:24 hoffman
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h,
- cmLocalUnixMakefileGenerator.cxx: ENH: remove warnings
-
-2004-09-03 12:03 hoffman
-
- * Modules/CMakeCCompiler.cmake.in,
- Modules/CMakeCXXCompiler.cmake.in,
- Modules/CMakeFortranCompiler.cmake.in,
- Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmLocalGenerator.cxx, Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator.cxx, Source/cmMakefile.cxx:
- ENH: define language extensions in cmake files and not hard
- coded, also fix trycompile problem
-
-2004-09-03 12:01 hoffman
-
- * Modules/Platform/Windows-cl.cmake: ENH: check for ms free command
- line tools
-
-2004-08-31 18:51 king
-
- * Source/cmListFileCache.cxx: BUG: Fixed line number of end of file
- error message.
-
-2004-08-31 18:39 king
-
- * Source/: cmListFileCache.cxx, cmListFileLexer.c,
- cmListFileLexer.h, cmListFileLexer.in.l: BUG#1049: Added error
- message when file ends in an unterminated string.
-
-2004-08-31 10:41 king
-
- * Source/cmFileCommand.cxx: BUG: Fix crash when CMAKE_DEBUG_POSTFIX
- is not set.
-
-2004-08-31 10:20 andy
-
- * DartConfig.cmake: ENH: Cleanups
-
-2004-08-31 08:25 king
-
- * Source/kwsys/kwsys_ios_iosfwd.h.in: ERR: Removed inclusion of
- fstream header. This file is meant as a compatibility header for
- iosfwd and therefore should not include any other header.
- Whatever was fixed by adding the include of fstream here should
- be fixed by other means.
-
-2004-08-30 15:15 hoffman
-
- * ChangeLog.manual, Source/cmCTest.cxx: merge fixes from main tree
-
-2004-08-30 14:07 hoffman
-
- * ChangeLog.manual, Source/cmGlobalVisualStudio6Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.cxx, Source/cmMakefile.cxx:
- fix RUN_TESTS and generated header files merge from main tree
-
-2004-08-30 14:01 hoffman
-
- * ChangeLog.manual, Modules/Platform/Windows-cl.cmake,
- Modules/Platform/Windows-gcc.cmake, Source/cmSystemTools.h,
- Utilities/Release/cmake_release.sh: merge from main tree
-
-2004-08-30 13:50 hoffman
-
- * Source/: cmSystemTools.h, kwsys/SystemTools.cxx: BUG: fixes for
- mingw and CMakesetup with spaces in the source directory
-
-2004-08-30 12:14 hoffman
-
- * Modules/Platform/Windows-gcc.cmake: Make sure cmake uses
- consistent module prefixes
-
-2004-08-27 09:55 hoffman
-
- * Source/cmMakefile.h: ENH: remove warning
-
-2004-08-27 08:41 hoffman
-
- * Source/: cmGlobalBorlandMakefileGenerator.cxx,
- cmGlobalBorlandMakefileGenerator.h,
- cmGlobalCodeWarriorGenerator.cxx, cmGlobalCodeWarriorGenerator.h,
- cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalNMakeMakefileGenerator.cxx,
- cmGlobalNMakeMakefileGenerator.h,
- cmGlobalUnixMakefileGenerator.cxx,
- cmGlobalUnixMakefileGenerator.h,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio6Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h, cmMakefile.cxx, cmMakefile.h,
- cmProjectCommand.cxx: ENH: try to initialize all languages at the
- same time
-
-2004-08-26 22:52 andy
-
- * Modules/: CMakeBackwardCompatibilityC.cmake,
- CMakeBackwardCompatibilityCXX.cmake, Documentation.cmake,
- FindFLTK.cmake, FindGLU.cmake, FindGnuplot.cmake,
- FindOpenGL.cmake, FindPNG.cmake, FindPerl.cmake,
- FindPythonLibs.cmake, FindQt.cmake, FindSelfPackers.cmake,
- FindTCL.cmake, FindThreads.cmake, FindUnixCommands.cmake,
- FindVTK.cmake, FindWget.cmake, FindX11.cmake,
- FindwxWidgets.cmake, FindwxWindows.cmake,
- TestForANSIStreamHeaders.cmake, UseVTK40.cmake,
- Use_wxWindows.cmake, UsewxWidgets.cmake,
- Platform/CYGWIN-g77.cmake: ENH: Cleanup. Use relative path to
- modules
-
-2004-08-26 21:43 hoffman
-
- * Modules/Platform/SunOS.cmake: hack to try and fix sun platform
-
-2004-08-26 18:00 king
-
- * Docs/cmake-mode.el: BUG: Only count block open tokens if they are
- followed by an open paren.
-
-2004-08-26 17:49 hoffman
-
- * Source/cmTryCompileCommand.cxx: ENH: try compiles in CXX require
- C to be enabled as well
-
-2004-08-26 16:34 hoffman
-
- * Modules/CMakeDetermineFortranCompiler.cmake,
- Source/CMakeLists.txt: ENH: try to find fortran compiler before
- adding the test
-
-2004-08-26 16:11 hoffman
-
- * Source/CMakeLists.txt: ENH: try to find fortran compiler before
- adding the test
-
-2004-08-26 16:00 hoffman
-
- * Source/CMakeLists.txt: remove test fortran for now
-
-2004-08-26 15:55 hoffman
-
- * Source/CMakeLists.txt: Add a fortran test if there is a fortran
- compiler
-
-2004-08-26 15:50 hoffman
-
- * Modules/CMakeDetermineFortranCompiler.cmake,
- Source/CMakeLists.txt: Add a fortran test if there is a fortran
- compiler
-
-2004-08-26 14:55 hoffman
-
- * Modules/CMake.cmake, Modules/CMakeCInformation.cmake,
- Modules/CMakeCXXInformation.cmake,
- Modules/CMakeCommonLanguageInclude.cmake,
- Modules/CMakeDefaultMakeRuleVariables.cmake,
- Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Modules/CMakeDetermineFortranCompiler.cmake,
- Modules/CMakeDetermineJavaCompiler.cmake,
- Modules/CMakeFortranCompiler.cmake.in,
- Modules/CMakeFortranInformation.cmake,
- Modules/CMakeGenericSystem.cmake,
- Modules/CMakeJavaCompiler.cmake.in,
- Modules/CMakeJavaInformation.cmake,
- Modules/CMakeSystemSpecificInformation.cmake,
- Modules/CMakeTestFortranCompiler.cmake,
- Modules/Platform/AIX.cmake, Modules/Platform/BSDOS.cmake,
- Modules/Platform/CYGWIN.cmake, Modules/Platform/Darwin.cmake,
- Modules/Platform/FreeBSD.cmake, Modules/Platform/HP-UX.cmake,
- Modules/Platform/IRIX.cmake, Modules/Platform/IRIX64.cmake,
- Modules/Platform/Linux.cmake, Modules/Platform/MP-RAS.cmake,
- Modules/Platform/NetBSD.cmake, Modules/Platform/OSF1.cmake,
- Modules/Platform/OpenBSD.cmake, Modules/Platform/RISCos.cmake,
- Modules/Platform/SCO_SV.cmake, Modules/Platform/SINIX.cmake,
- Modules/Platform/SunOS.cmake, Modules/Platform/True64.cmake,
- Modules/Platform/ULTRIX.cmake, Modules/Platform/UNIX_SV.cmake,
- Modules/Platform/UnixWare.cmake,
- Modules/Platform/Windows-gcc.cmake,
- Modules/Platform/Windows-ifort.cmake,
- Modules/Platform/Xenix.cmake, Source/CMakeLists.txt,
- Source/cmGlobalBorlandMakefileGenerator.cxx,
- Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmGlobalUnixMakefileGenerator.cxx,
- Source/cmListFileCache.cxx,
- Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmProjectCommand.cxx, Source/cmTryCompileCommand.cxx,
- Source/cmake.cxx, Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/complex.cxx,
- Tests/Fortran/CMakeLists.txt: ENH: more uniform approach to
- enable language, one step closer to being able to enable a
- language without modifing cmake source code
-
-2004-08-26 09:45 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: ENH: Make default date shorter
-
-2004-08-25 12:42 hoffman
-
- * Source/cmCTest.cxx: ENH: better error display for failure
-
-2004-08-25 08:44 hoffman
-
- * Source/cmCTest.cxx: ENH: produce better error message for missing
- variables in -S mode
-
-2004-08-24 11:30 andy
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ERR: Fix the list of
- targets. The base target name now includes the MACOSX_BUNDLE path
-
-2004-08-24 11:17 andy
-
- * Source/cmAddExecutableCommand.cxx: BUG: If macdir does not end
- with '/' then add it always, not just when adding current
- directory
-
-2004-08-23 14:33 andy
-
- * Source/cmake.cxx: ENH: Implement PreLoad.cmake feature for
- CMakeSetup
-
-2004-08-23 14:09 hoffman
-
- * Source/CTest/CMakeLists.txt: fix syntax
-
-2004-08-23 13:45 hoffman
-
- * CMakeLists.txt, Source/CTest/CMakeLists.txt: ENH: fix out of the
- box build on sgi to match dashboards
-
-2004-08-23 11:33 hoffman
-
- * Modules/FindJava.cmake: BUG: 1107 add extra place to look for
- java
-
-2004-08-23 11:29 martink
-
- * Source/cmCTest.cxx: now will check out src dir if it has the necc
- info
-
-2004-08-23 11:21 hoffman
-
- * Modules/FindJava.cmake: BUG: 1107 add extra place to look for
- java
-
-2004-08-19 12:51 andy
-
- * Source/cmCTest.cxx: ENH: Handle gmake error message
-
-2004-08-18 09:28 andy
-
- * Modules/CMakeSystemSpecificInformation.cmake: BUG: Unly set gcc
- flags for C compiler if CMAKE_COMPILER_IS_GNUCC is set
-
-2004-08-18 08:52 andy
-
- * Source/cmCTest.cxx: BUG: When GetNightlyTime returns past time,
- fix everything. Also, return correct time when printing
-
-2004-08-17 19:18 andy
-
- * Modules/Platform/Darwin-xlc.cmake: ENH: Initial import for Darwin
- using xlC
-
-2004-08-17 16:13 andy
-
- * Source/CursesDialog/cmCursesMainForm.cxx: ENH: Reload
- PreLoad.cmake every time you do configure
-
-2004-08-17 15:36 andy
-
- * Source/CursesDialog/cmCursesMainForm.cxx: ENH: Enable preload for
- ccmake
-
-2004-08-17 15:36 andy
-
- * Source/: cmake.cxx, cmake.h: ENH: Move PreLoad.cmake code to
- public method so that ccmake and CMakeSetup can call it
-
-2004-08-17 14:23 andy
-
- * Source/cmCTest.cxx: BUG: Attempt to fix timezone problem where
- start time appears one day before the actual start time. Also add
- verbosity to GetNightlyTime
-
-2004-08-16 09:03 king
-
- * Utilities/Release/config_IRIX64: BUG: Need to set HAVE_LIBCRYPTO
- to 0 instead of letting the test be done.
-
-2004-08-11 20:36 hoffman
-
- * Source/cmCTest.cxx: fix it
-
-2004-08-11 16:58 hoffman
-
- * Source/: cmAbstractFilesCommand.cxx, cmAddExecutableCommand.cxx,
- cmCreateTestSourceList.cxx, cmGlobalCodeWarriorGenerator.cxx,
- cmGlobalGenerator.cxx, cmGlobalUnixMakefileGenerator.cxx,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx, cmUtilitySourceCommand.cxx:
- ENH: use GetRequiredDefinition instead of GetDefinition and crash
-
-2004-08-11 16:57 hoffman
-
- * Source/: cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx: ENH: change RUN_TESTS to use
- -C and not -D also use GetRequiredDefinition where needed
-
-2004-08-11 16:37 hoffman
-
- * Source/cmCTest.cxx: ENH: fixes for RUN_TESTS from visual studio
- IDE, fprintf does not print right away, so std::cerr had to be
- used. Also, allow .\ to start the config type
-
-2004-08-11 16:35 hoffman
-
- * Modules/CMakeSystemSpecificInformation.cmake,
- Modules/CMakeTestFortranCompiler.cmake, Source/cmSystemTools.cxx:
- ENH: minor fortran fixes
-
-2004-08-11 09:31 hoffman
-
- * CMakeLists.txt, ChangeLog.manual, DartConfig.cmake,
- Docs/cmake-mode.el, Modules/CMakeSystemSpecificInformation.cmake,
- Modules/CMakeVS8FindMake.cmake, Modules/Dart.cmake,
- Modules/FindDoxygen.cmake, Modules/FindFLTK.cmake,
- Modules/FindKDE.cmake, Modules/FindQt.cmake,
- Modules/FindSWIG.cmake, Modules/UseSWIG.cmake,
- Source/CMakeLists.txt, Source/cmAuxSourceDirectoryCommand.h,
- Source/cmCTest.cxx, Source/cmCTest.h, Source/cmCommands.cxx,
- Source/cmCreateTestSourceList.cxx, Source/cmDynamicLoader.cxx,
- Source/cmExecProgramCommand.cxx, Source/cmFLTKWrapUICommand.cxx,
- Source/cmFileCommand.cxx, Source/cmGetTargetPropertyCommand.h,
- Source/cmGlobalCodeWarriorGenerator.cxx,
- Source/cmGlobalGenerator.cxx,
- Source/cmGlobalVisualStudio6Generator.cxx,
- Source/cmGlobalVisualStudio71Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalVisualStudio8Generator.cxx,
- Source/cmGlobalVisualStudio8Generator.h, Source/cmIfCommand.cxx,
- Source/cmIfCommand.h, Source/cmLinkLibrariesCommand.cxx,
- Source/cmListFileLexer.c, Source/cmListFileLexer.in.l,
- Source/cmLocalGenerator.cxx, Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h, Source/cmMakefile.cxx,
- Source/cmQTWrapCPPCommand.cxx, Source/cmQTWrapUICommand.cxx,
- Source/cmSubdirCommand.h, Source/cmSystemTools.cxx,
- Source/cmSystemTools.h, Source/cmTarget.cxx,
- Source/cmTargetLinkLibrariesCommand.cxx,
- Source/cmTryRunCommand.cxx, Source/cmUseMangledMesaCommand.cxx,
- Source/cmWin32ProcessExecution.cxx, Source/cmake.cxx,
- Source/cmakewizard.h, Source/CTest/cmCTestSubmit.cxx,
- Source/CTest/cmCTestSubmit.h,
- Source/CursesDialog/cmCursesMainForm.cxx,
- Source/kwsys/CMakeLists.txt, Source/kwsys/ProcessUNIX.c,
- Source/kwsys/SystemTools.cxx,
- Templates/CMakeWindowsSystemConfig.cmake,
- Templates/TestDriver.cxx.in, Tests/Simple/CMakeLists.txt,
- Tests/SimpleInstall/CMakeLists.txt, Tests/SimpleInstall/inst.cxx,
- Tests/SimpleInstall/lib4.cxx, Tests/SimpleInstall/lib4.h,
- Tests/SimpleInstall/TestSubDir/CMakeLists.txt,
- Tests/SimpleInstall/TestSubDir/TSD.cxx,
- Tests/SimpleInstall/TestSubDir/TSD.h,
- Tests/SimpleInstall/TestSubDir/TSD_utils.cxx,
- Tests/SimpleInstallS2/CMakeLists.txt,
- Tests/SimpleInstallS2/inst.cxx, Tests/SimpleInstallS2/lib4.cxx,
- Tests/SimpleInstallS2/lib4.h,
- Tests/SimpleInstallS2/TestSubDir/CMakeLists.txt,
- Tests/SimpleInstallS2/TestSubDir/TSD.cxx,
- Tests/SimpleInstallS2/TestSubDir/TSD.h,
- Tests/SimpleInstallS2/TestSubDir/TSD_utils.cxx,
- Utilities/Doxygen/CMakeLists.txt,
- Utilities/Release/cmake_release.sh: Moving latest release branch
- to CMake-2-0-3.
-
-2004-08-09 18:39 martink
-
- * Source/cmIncludeCommand.cxx: ENH: Allow user to overwrite
- Platforms files
-
-2004-08-09 18:20 martink
-
- * Modules/Platform/Windows-icl.cmake: ENH: Initial import
-
-2004-08-09 17:42 hoffman
-
- * Source/kwsys/SystemTools.cxx: BUG: fix for try run failing on
- some cygwin builds. Allow a driver letter to start a full path
- on cygwin
-
-2004-08-09 13:03 hoffman
-
- * Source/cmMakefile.cxx: BUG: fix bug where custom command
- generated .h files do not get the header_file_only flag set
-
-2004-08-06 15:05 hoffman
-
- * Tests/Fortran/: CMakeLists.txt, hello.f: ENH: initial fortran
-
-2004-08-06 14:51 hoffman
-
- * Modules/CMakeDefaultMakeRuleVariables.cmake,
- Modules/CMakeDetermineFortranCompiler.cmake,
- Modules/CMakeFortranCompiler.cmake.in,
- Modules/CMakeSystemSpecificInformation.cmake,
- Modules/CMakeTestFortranCompiler.cmake,
- Modules/Platform/CYGWIN-g77.cmake, Modules/Platform/g77.cmake,
- Source/cmGlobalGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.cxx, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmSystemTools.cxx,
- Source/cmSystemTools.h, Source/cmTarget.cxx, Source/cmTarget.h,
- Source/cmTryCompileCommand.cxx: ENH: initial fortran support
-
-2004-08-05 11:59 hoffman
-
- * Modules/FindQt.cmake: ENH: remove verbose QT message
-
-2004-08-05 11:51 king
-
- * Source/cmAddExecutableCommand.cxx: ERR: Replacing hack call to
- CONFIGURE_FILE command with direct call to
- m_Makefile->ConfigureFile.
-
-2004-08-05 10:27 king
-
- * ChangeLog.manual, Source/cmGlobalGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.cxx: BUG#427: Merging fix to
- CMake 2.0 release branch.
-
-2004-08-05 10:17 king
-
- * Source/: cmGlobalGenerator.cxx, cmLocalUnixMakefileGenerator.cxx:
- BUG#427: Generated makefiles need to have targets with canonical
- names for each executable and library target in order for
- try-compiles to work correctly when specifying the target.
-
-2004-08-05 09:29 king
-
- * ChangeLog.manual, Source/cmGlobalCodeWarriorGenerator.cxx,
- Source/cmGlobalCodeWarriorGenerator.h,
- Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmGlobalVisualStudio6Generator.cxx,
- Source/cmGlobalVisualStudio6Generator.h,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.h,
- Source/cmLocalVisualStudio7Generator.cxx, Source/cmMakefile.cxx,
- Source/cmTryRunCommand.cxx: Merging fixes from main tree. See
- ChangeLog.manual section on 2.0.4 for details.
-
-2004-08-05 09:17 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: Fixed crash when
- CMAKE_CXX_STACK_SIZE is not defined.
-
-2004-08-04 17:24 king
-
- * Source/cmMakefile.cxx: BUG: Fix crash when adding a custom
- command to a source file that cannot be created.
-
-2004-08-04 17:21 hoffman
-
- * Source/cmTryRunCommand.cxx: ENH: allow debug of tryrun
-
-2004-08-04 16:33 king
-
- * Source/: cmGlobalCodeWarriorGenerator.cxx,
- cmGlobalCodeWarriorGenerator.h, cmGlobalGenerator.cxx,
- cmGlobalGenerator.h, cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio6Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h, cmMakefile.cxx: BUG:
- CMAKE_TRY_COMPILE_CONFIGURATION should be obtained from the
- cmMakefile instance for the listfile containing the TRY_COMPILE
- call, not the top level listfile.
-
-2004-08-04 14:34 king
-
- * Source/cmMakefile.cxx: ERR: Removed duplicate default arguments.
-
-2004-08-04 13:05 hoffman
-
- * Source/cmake.cxx: fix incorrect selection of visual studio
- generator
-
-2004-08-04 10:45 king
-
- * Source/: cmCPluginAPI.cxx, cmForEachCommand.cxx,
- cmListFileCache.cxx, cmListFileCache.h, cmMacroCommand.cxx,
- cmMakefile.cxx, cmMakefile.h: ENH: Added support for special
- variables CMAKE_CURRENT_LIST_FILE and CMAKE_CURRENT_LIST_LINE
- that evaluate to the file name and line number in which they
- appear. This implements the feature request from bug 1012.
-
-2004-08-04 10:00 king
-
- * Source/cmake.cxx: BUG: Fixed typo in name of MSVC 8 registry key.
-
-2004-08-04 08:50 andy
-
- * Source/cmIfCommand.cxx: ERR: Fix warnings and memory leak
-
-2004-08-03 10:20 hoffman
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH: create a
- server that does not use vtkPVApplication or tcl wrapping. Move
- several classes from GUI/Client to Servers/Filters. Remove use of
- PARAVIEW_NEW_SOURCE_ORGANIZATION define.
-
-2004-08-03 08:13 andy
-
- * Source/: cmIfCommand.cxx, cmIfCommand.h: BUG: When regular
- expression failes to compile, produce error: Fixes part of Bug
- #1025 - CMake silently ignores regular expression failure
-
-2004-08-02 08:36 andy
-
- * Source/cmCTest.cxx: BUG: these flags do not take arguments, so
- they do not really need to check if they are last. Fixes Bug
- #1020 - ctest doesn't parse its options correctly
-
-2004-07-30 15:50 andy
-
- * Source/: cmInstallFilesCommand.h, cmInstallProgramsCommand.h,
- cmInstallTargetsCommand.h: ENH: Since install works on Windows
- too, remove the UNIX
-
-2004-07-30 09:42 hoffman
-
- * CMakeLists.txt, Utilities/Release/cmake_release.sh: change
- version to 2.0.3
-
-2004-07-29 17:15 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: ENH: Add some documentation, and
- make sure that the flag given to -D -T or -M is valid. Fixes Bug
- #1015 - Documentation: ctest -D
-
-2004-07-29 17:07 andy
-
- * Modules/Dart.cmake: ENH: Add MemCheck to the list of Make
- targets. Closes Bug #1016 - Testing targets in Makefile
-
-2004-07-29 15:26 andy
-
- * Source/cmCTest.cxx: ENH: Add AIX linker error
-
-2004-07-29 14:45 hoffman
-
- * ChangeLog.manual, Modules/Dart.cmake, Source/cmCTest.cxx,
- Source/cmCTest.h, Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h, Source/cmMakefile.cxx,
- Source/cmTarget.cxx, Source/cmake.cxx,
- Source/CTest/cmCTestSubmit.cxx, Source/kwsys/SystemTools.cxx:
- merges from main tree
-
-2004-07-29 14:19 hoffman
-
- * Modules/CMakeSystemSpecificInformation.cmake,
- Source/cmTarget.cxx, Source/cmakewizard.h: merge from main tree,
- comment spelling fixes
-
-2004-07-29 11:46 king
-
- * ChangeLog.manual, Source/cmLinkLibrariesCommand.cxx,
- Source/cmTargetLinkLibrariesCommand.cxx: BUG: Fixed crash when
- optimized/debug argument to a link-libraries command is not
- followed by a value.
-
-2004-07-29 11:43 king
-
- * Source/: cmTargetLinkLibrariesCommand.cxx,
- cmLinkLibrariesCommand.cxx: BUG: Fixed crash when optimized/debug
- argument is not followed by a value.
-
-2004-07-29 11:11 andy
-
- * Tests/X11/CMakeLists.txt: ERR: Fix test to use post CMAKE_X_LIBS
- variables
-
-2004-07-29 10:22 king
-
- * ChangeLog.manual: ENH: Added changes for
- cmAuxSourceDirectoryCommand.h and cmGetTargetPropertyCommand.h
-
-2004-07-28 08:12 king
-
- * Source/: cmGetTargetPropertyCommand.h: ENH: Added documentation
- of LOCATION target property.
-
-2004-07-27 13:40 hoffman
-
- * Source/cmake.cxx: BUG: fix for bug 971, pick a better generator
- from the command line
-
-2004-07-27 08:52 andy
-
- * Modules/Dart.cmake: DOC: Fix typo
-
-2004-07-27 08:49 andy
-
- * Source/CTest/cmCTestSubmit.cxx: BUG: Allow submit and trigger url
- to contain ?. Fixes Bug #997 - CTest cannot handle URLs which
- contain a "?"
-
-2004-07-27 08:48 andy
-
- * Modules/Dart.cmake: ENH: Allow project to overwrite
- CMAKE_SYSTEM_NAME part of default BUILDNAME
-
-2004-07-26 16:59 hoffman
-
- * Modules/CMakeSystemSpecificInformation.cmake,
- Source/cmMakefile.cxx, Source/cmTarget.cxx, Source/cmakewizard.h:
- BUG: fix for bug 998, fix spelling errors
-
-2004-07-26 16:00 andy
-
- * Source/cmCTest.cxx: ENH: Support Threading Problem in memcheck
-
-2004-07-26 15:52 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: ENH: Add maximum size of test
- output
-
-2004-07-24 19:58 king
-
- * Source/: cmAuxSourceDirectoryCommand.h: ENH: Added warning about
- using this command to avoid listing sources for a library by
- hand. It is supposed to be used only for Templates directories.
-
-2004-07-22 11:20 hoffman
-
- * ChangeLog.manual, Modules/FindFLTK.cmake, Modules/FindQt.cmake,
- Source/cmCTest.cxx, Source/cmDynamicLoader.cxx,
- Source/cmGlobalCodeWarriorGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.cxx, Source/cmMakefile.cxx,
- Source/cmUseMangledMesaCommand.cxx, Source/cmake.cxx,
- Source/CursesDialog/cmCursesMainForm.cxx,
- Templates/CMakeWindowsSystemConfig.cmake,
- Templates/TestDriver.cxx.in: merge from main tree
-
-2004-07-22 10:59 hoffman
-
- * Modules/: FindFLTK.cmake, FindQt.cmake: BUG: put back flags to
- maintain backwards compatibility
-
-2004-07-20 16:18 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: BUG: Encode current time so that
- on some international computers xslt will not break. Also, for
- continuous, do not repeat if there were locally modified files or
- conflict, but only when things actually update
-
-2004-07-20 11:09 andy
-
- * Source/kwsys/SystemTools.cxx: BUG: If source and destination is
- the same file, then do not copy file always
-
-2004-07-20 11:07 andy
-
- * Source/cmMakefile.cxx: ENH: When running cmake with PreLoad make
- sure CMAKE_CURRENT_SOURCE/BINARY_DIR works
-
-2004-07-20 11:02 hoffman
-
- * Source/CursesDialog/cmCursesMainForm.cxx: ENH: remove deletes
-
-2004-07-19 13:01 hoffman
-
- * Source/CursesDialog/cmCursesMainForm.cxx: BUG: fix for 981 cursor
- returns to correct place in help screen
-
-2004-07-19 13:00 hoffman
-
- * Source/cmDynamicLoader.cxx: bug fix for 986
-
-2004-07-16 16:02 hoffman
-
- * Source/cmake.cxx: ENH: add a message at the end of the cmake run
- telling the user where things were written.
-
-2004-07-16 15:18 hoffman
-
- * Templates/TestDriver.cxx.in: make sure tests flush output
-
-2004-07-15 14:38 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: ENH: sort flags, and
- fix order and case problems and add a few more
-
-2004-07-15 13:53 martink
-
- * Source/cmCTest.cxx: better error warning exceptions
-
-2004-07-14 19:53 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: ENH: remove warnings
-
-2004-07-14 16:10 hoffman
-
- * Source/: cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h: ENH: use a map to fill out
- flags, and keep command line consistent with the GUI
-
-2004-07-13 17:33 king
-
- * Source/kwsys/testProcess.c: BUG: Fixed off-by-one error in test6
- function.
-
-2004-07-13 17:27 king
-
- * Source/kwsys/: testProcess.c, CMakeLists.txt: ENH: Added test for
- runaway output.
-
-2004-07-13 16:50 king
-
- * Source/kwsys/ProcessWin32.c: ENH: Re-arranged handling of the two
- threads per pipe to improve readability of code.
-
-2004-07-13 16:23 king
-
- * Source/kwsys/ProcessWin32.c: BUG: Fix for read pipe wakeup when
- child is writing alot of data and may fill the pipe buffer before
- WriteFile is called.
-
-2004-07-13 11:06 martink
-
- * Source/: cmCTest.cxx, cmCTest.h: submit elapsed times as well
-
-2004-07-13 10:03 andy
-
- * Modules/FindQt.cmake: BUG: These regular expressions were wrong
- because \\t does not match tab. Also, this fix prevents whole
- file to be dumped to the cache
-
-2004-07-09 15:38 hoffman
-
- * Modules/FindQt.cmake: merge in fixes from neundorf at kde org,
- bug 869
-
-2004-07-09 14:18 hoffman
-
- * Source/: cmMakefile.cxx, cmUseMangledMesaCommand.cxx: BUG: fix
- spelling errors BUG 952
-
-2004-07-09 13:50 hoffman
-
- * Source/cmGlobalCodeWarriorGenerator.cxx,
- Templates/CMakeDotNetSystemConfig.cmake,
- Templates/CMakeWindowsSystemConfig.cmake: BUG: remove unused
- variable CMAKE_OBJECT_FILE_SUFFIX from cmake
-
-2004-07-09 11:49 king
-
- * Source/kwsys/ProcessUNIX.c: ERR: Fixed missing return warning.
- Code was not reachable anyway.
-
-2004-07-09 09:12 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: remove double
- include flags for rc resouce compiles
-
-2004-07-07 18:15 king
-
- * Source/kwsys/ProcessWin32.c: ENH: Added windows implementation of
- Disown/Detach.
-
-2004-07-07 17:46 king
-
- * Source/kwsys/ProcessUNIX.c: BUG: Do not disown if process has
- already been killed or the timeout expired. Also need to call
- kwsysProcessCleanup to disown.
-
-2004-07-07 17:27 king
-
- * Source/kwsys/: Process.h.in, ProcessUNIX.c, ProcessWin32.c: ENH:
- Added kwsysProcess_Disown an kwsysProcess_Option_Detach to allow
- detached processes to be created. Currently implemented only on
- UNIX.
-
-2004-07-07 17:09 hoffman
-
- * ChangeLog.manual, DartConfig.cmake,
- Modules/CMakeVS8FindMake.cmake, Modules/FindSWIG.cmake,
- Modules/UseSWIG.cmake, Source/CMakeLists.txt, Source/cmCTest.cxx,
- Source/cmCTest.h, Source/cmExecProgramCommand.cxx,
- Source/cmFileCommand.cxx, Source/cmGlobalGenerator.cxx,
- Source/cmGlobalVisualStudio8Generator.cxx,
- Source/cmGlobalVisualStudio8Generator.h,
- Source/cmLocalGenerator.cxx, Source/cmLocalGenerator.h,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h, Source/cmMakefile.cxx,
- Source/cmQTWrapUICommand.cxx, Source/cmSystemTools.cxx,
- Source/cmSystemTools.h, Source/cmTryRunCommand.cxx,
- Source/cmWin32ProcessExecution.cxx, Source/cmake.cxx,
- Source/kwsys/CMakeLists.txt, Source/kwsys/ProcessUNIX.c,
- Source/kwsys/SystemTools.cxx, Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstall/inst.cxx, Tests/SimpleInstall/lib4.cxx,
- Tests/SimpleInstall/lib4.h,
- Tests/SimpleInstall/TestSubDir/CMakeLists.txt,
- Tests/SimpleInstall/TestSubDir/TSD.cxx,
- Tests/SimpleInstall/TestSubDir/TSD.h,
- Tests/SimpleInstall/TestSubDir/TSD_utils.cxx,
- Tests/SimpleInstallS2/CMakeLists.txt,
- Tests/SimpleInstallS2/inst.cxx, Tests/SimpleInstallS2/lib4.cxx,
- Tests/SimpleInstallS2/lib4.h,
- Tests/SimpleInstallS2/TestSubDir/CMakeLists.txt,
- Tests/SimpleInstallS2/TestSubDir/TSD.cxx,
- Tests/SimpleInstallS2/TestSubDir/TSD.h,
- Tests/SimpleInstallS2/TestSubDir/TSD_utils.cxx: merge from main
- tree, see ChangeLog.manual for changes
-
-2004-07-07 16:09 andy
-
- * Source/cmCTest.cxx: BUG: LastMemCheck is not really an XML file
-
-2004-07-07 13:03 king
-
- * Source/kwsys/ProcessUNIX.c: ERR: Using KWSYSPE_PIPE_BUFFER_SIZE
- in place of separate bufferSize constant for consistency.
-
-2004-07-05 12:16 hoffman
-
- * Modules/CMakeVS8FindMake.cmake,
- Modules/Platform/Windows-cl.cmake, Source/CMakeLists.txt,
- Source/cmGlobalGenerator.cxx,
- Source/cmGlobalVisualStudio8Generator.cxx,
- Source/cmGlobalVisualStudio8Generator.h,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h, Source/cmake.cxx: ENH:
- add support for VCExpress 2005
-
-2004-07-04 00:05 hoffman
-
- * Source/kwsys/ProcessUNIX.c: no c++ comments in c
-
-2004-07-03 12:00 hoffman
-
- * Source/kwsys/ProcessUNIX.c: fix for hp build
-
-2004-07-02 17:39 king
-
- * Source/kwsys/CMakeLists.txt: BUG: Need a C-only library for C
- tests.
-
-2004-07-02 16:39 king
-
- * Source/kwsys/ProcessUNIX.c: BUG#392: Implementation of process
- tree killing for systems with /proc filesystem.
-
-2004-07-02 16:29 king
-
- * Source/: cmCTest.cxx, cmCTest.h: BUG#969: Partially fixed by at
- least using the timeout for the individual calls to
- RunSingleCommand from within the inner ctest instance. This
- should be modified to incrementally adjust remaining time.
-
-2004-07-02 16:27 king
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Made
- RunSingleCommand take a double as its timeout length.
-
-2004-07-02 14:09 king
-
- * Source/cmFileCommand.cxx: BUG: Fixed generation of installation
- manifest to account for library versioning symlinks. Also
- removed DESTDIR prefix from generated manifest.
-
-2004-07-02 14:08 king
-
- * Source/cmLocalGenerator.cxx: BUG: install_manifest.txt should be
- overwritten each time the install is run.
-
-2004-07-02 13:39 king
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ERR: Removed debugging code from
- test.
-
-2004-07-02 11:51 andy
-
- * Source/cmFileCommand.cxx: BUG: If the destination is the same as
- source, do not copy file. Fixes Bug #956 - make install broken
-
-2004-07-02 09:57 andy
-
- * Source/cmake.cxx: ENH: Also read PreLoad.cmake from the binary
- tree
-
-2004-06-30 11:31 hoffman
-
- * Source/: cmMakefile.cxx, kwsys/SystemTools.cxx: ENH: add
- CMAKE_FILE_PATH, CMAKE_PROGRAM_PATH, CMAKE_LIBRARY_PATH, and
- search them first, PATH second, and last the paths listed in the
- FIND call
-
-2004-06-30 08:59 andy
-
- * Source/cmFileCommand.cxx: ERR: Fix typo
-
-2004-06-29 16:40 hoffman
-
- * Source/cmQTWrapUICommand.cxx: ENH: remove QT_WRAP_UI flag
-
-2004-06-29 10:22 hoffman
-
- * Modules/FindSWIG.cmake: BUG: make sure if swig is found, we know
- it is found
-
-2004-06-29 09:23 andy
-
- * Source/cmFileCommand.cxx, Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: Better handling of
- debug postfix and fix the test
-
-2004-06-28 16:39 andy
-
- * Source/cmFileCommand.cxx, Source/cmGlobalGenerator.cxx,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ERR: Fix visual studio
- install
-
-2004-06-28 14:39 andy
-
- * Source/cmFileCommand.cxx, Source/cmLocalGenerator.cxx,
- Source/cmLocalGenerator.h, Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstall/inst.cxx,
- Tests/SimpleInstallS2/CMakeLists.txt,
- Tests/SimpleInstallS2/inst.cxx, Tests/SimpleInstall/lib4.cxx,
- Tests/SimpleInstall/lib4.h, Tests/SimpleInstallS2/lib4.cxx,
- Tests/SimpleInstallS2/lib4.h: BUG: Implement installing of shared
- library versioning and add test for the whole thing
-
-2004-06-28 11:14 andy
-
- * Modules/UseSWIG.cmake: BUG: Add more comments and fix
- CMAKE_SWIG_FLAGS
-
-2004-06-28 09:08 andy
-
- * Modules/FindSWIG.cmake: BUG: Replace MATCHES with STREQUAL for
- better checking, better checking for existence of swig directory,
- verify if required flag was set, support fedora's location of
- swig. Fixes Bug #955 - Swig on fedora and Bug #954 -
- FIND_PACKAGE(SWIG REQUIRED)
-
-2004-06-26 08:40 hoffman
-
- * Modules/UseSWIG.cmake: BUG: SWIG_FLAGS was ignored by the add
- swig source to module command
-
-2004-06-25 14:04 andy
-
- * CMakeLists.txt: ENH: Build expat as a part of default build
-
-2004-06-25 14:04 andy
-
- * Utilities/cmexpat/: .NoDartCoverage, CMakeLists.txt, COPYING,
- ascii.h, asciitab.h, cm_expat_mangle.h, expat.h,
- expatConfig.h.in, expatDllConfig.h.in, iasciitab.h, latin1tab.h,
- nametab.h, utf8tab.h, xmlparse.c, xmlrole.c, xmlrole.h, xmltok.c,
- xmltok.h, xmltok_impl.c, xmltok_impl.h, xmltok_ns.c: ENH: Initial
- import of expat
-
-2004-06-24 09:05 hoffman
-
- * Source/cmWin32ProcessExecution.cxx: ENH: remove warning on
- borland
-
-2004-06-24 08:57 hoffman
-
- * Source/cmExecProgramCommand.cxx: BUG: exec program should not
- fail if it can not exec the program, but should only set the
- return value to -1 and set the output to the reason for the
- failure.
-
-2004-06-23 16:34 hoffman
-
- * Source/: cmExecProgramCommand.cxx, cmSystemTools.cxx,
- cmSystemTools.h, cmTryRunCommand.cxx,
- cmWin32ProcessExecution.cxx: BUG: fix spaces in path on mingw,
- and change EXEC_PROGRAM to return false when it does not run,
- also do not convert the directory to an output path for
- EXEC_PROGRAM as this is done by the process execution, and doing
- it twice may cause trouble on some shells.
-
-2004-06-23 16:15 hoffman
-
- * Modules/Platform/Windows-cl.cmake: C++ compiler is not set for c
- only projects
-
-2004-06-23 10:13 king
-
- * Source/: cmCacheManager.cxx, CursesDialog/cmCursesMainForm.cxx,
- CursesDialog/cmCursesMainForm.h: ENH: Adding MODIFIED property to
- cache values that have been changed by the user.
-
-2004-06-22 17:23 hoffman
-
- * Source/cmSystemTools.cxx: BUG: fix spaces in path with mingw and
- custom commands
-
-2004-06-21 12:59 hoffman
-
- * ChangeLog.manual: update changes for release 2.0.2
-
-2004-06-21 12:48 hoffman
-
- * CMakeLists.txt, Utilities/Release/cmake_release.sh: change
- version on branch
-
-2004-06-21 12:48 hoffman
-
- * CMakeLists.txt: change minimum cmake
-
-2004-06-18 15:47 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: merge from main tree,
- remove automatic -I for source
-
-2004-06-18 15:47 hoffman
-
- * Source/cmSubdirCommand.h: merge from main tree, fix docs
-
-2004-06-18 15:46 hoffman
-
- * Modules/FindFLTK.cmake, Modules/FindQt.cmake,
- Source/cmFLTKWrapUICommand.cxx, Source/cmQTWrapCPPCommand.cxx:
- merge from main tree, remove useless variables
-
-2004-06-18 15:14 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: Added special hack
- for VTK 4.0-4.4 to re-enable automatic addition of current source
- directory to -I path.
-
-2004-06-18 15:01 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: Added special hack
- for VTK 4.0-4.4 to re-enable automatic addition of current source
- directory to -I path.
-
-2004-06-18 13:04 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: Need to preserve
- automatic addition of source tree to -I path if
- CMAKE_BACKWARDS_COMPATIBILITY is set to below 2.0.
-
-2004-06-18 13:00 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ERR: Fixed typo.
-
-2004-06-18 12:56 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: Need to preserve
- automatic addition of source tree to -I path if
- CMAKE_BACKWARDS_COMPATIBILITY is set to below 2.0.
-
-2004-06-18 10:54 king
-
- * Docs/: cmake-mode.el: BUG: Fixed parsing of unquoted arguments to
- allow double-quotes within the argument.
-
-2004-06-18 10:51 king
-
- * Source/: cmListFileLexer.c, cmListFileLexer.in.l: BUG: Fixed
- parsing of unquoted arguments to allow double-quotes within the
- argument.
-
-2004-06-16 09:45 hoffman
-
- * Source/cmSubdirCommand.h: clean up documentation
-
-2004-06-16 09:43 hoffman
-
- * Source/cmFLTKWrapUICommand.cxx, Source/cmQTWrapCPPCommand.cxx,
- Modules/FindFLTK.cmake, Modules/FindQt.cmake: clean up commands
- so they don't need extra variable
-
-2004-06-15 11:52 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: Removing automatic
- addition of a -I path for the current source directory. This is
- not consistent with the Visual Studio generators which do not
- provide this path. It should not be added anyway because it is
- adding an include path not requested by the CMakeLists.txt code.
- The code I'm removing was originally added in revision 1.17 of
- cmUnixMakefileGenerator.cxx as a part of several other changes
- and has a commit log entry of
-
- "some bug fixes"
-
- It was propagated from their to cmLocalUnixMakefileGenerator.cxx.
- Since all our projects build in the VS IDE without this include
- path, it should not be needed. Users can easily fix problems
- caused by this by adding
-
- INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
-
- to their CMakeLists.txt code. This was often necessary
- previously when a project was originally written on a Unix system
- and then built with Visual Studio.
-
-2004-06-15 08:32 hoffman
-
- * Source/: cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx: merge from main tree, fix
- GetCurrentDirectory problem
-
-2004-06-15 08:30 hoffman
-
- * Source/: cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx: fix include order because of
- GetCurrentDirectory define and windows.h problem
-
-2004-06-14 13:25 hoffman
-
- * Modules/FindKDE.cmake: merge from main tree, new module
-
-2004-06-14 12:29 hoffman
-
- * Utilities/Doxygen/CMakeLists.txt: merge from main tree
-
-2004-06-14 12:28 hoffman
-
- * Source/: cmIfCommand.cxx, cmIfCommand.h: merge from main tree,
- add STRGREATER
-
-2004-06-14 12:28 hoffman
-
- * Source/cmCommands.cxx: merge from main tree, fix bootstrap on mac
-
-2004-06-14 12:27 hoffman
-
- * Modules/FindFLTK.cmake: merge from main tree, look for both Fl.h
- and Fl.H
-
-2004-06-14 12:21 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: merge from main tree,
- use cmake to install itself, when building cmake
-
-2004-06-14 12:20 hoffman
-
- * Source/cmIfCommand.cxx: merge from main tree, fix compound if
- crash on unix
-
-2004-06-14 12:19 hoffman
-
- * Source/: cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx: merge from main tree, use
- correct path for sub projects
-
-2004-06-14 12:18 hoffman
-
- * Source/cmCTest.cxx: merge from main tree, more -I stuff
-
-2004-06-14 12:18 hoffman
-
- * Source/CMakeLists.txt: merge from main tree, do not use regex for
- directoires
-
-2004-06-14 12:17 hoffman
-
- * Modules/FindDoxygen.cmake: ENH: better find for doxygen
-
-2004-06-14 12:16 hoffman
-
- * Modules/Platform/Windows-cl.cmake,
- Source/cmLocalVisualStudio7Generator.cxx,
- Templates/DLLHeader.dsptemplate: ENH: add NDEBUG to windows
- release builds for both ide and nmake
-
-2004-06-14 12:02 martink
-
- * Source/: cmIfCommand.h, cmIfCommand.cxx: added strequal
-
-2004-06-14 11:24 andy
-
- * Tests/CTestTest/test.cmake.in: ENH: Handle spaces in the path
-
-2004-06-14 11:23 andy
-
- * Source/cmCommands.cxx: ERR: On Mac we need
- GET_SOURCE_FILE_PROPERTY for building curl
-
-2004-06-14 10:46 hoffman
-
- * Modules/FindKDE.cmake: ENH: add FindKDE from Alex from kde.org
-
-2004-06-14 10:36 hoffman
-
- * Modules/FindFLTK.cmake: fix for bug 915
-
-2004-06-14 10:28 hoffman
-
- * Source/: cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx: BUG: fix sub project path
- problem
-
-2004-06-11 15:27 martink
-
- * CMakeLists.txt, CMakeSystemConfig.txt.in,
- CMakeWindowsSystemConfig.txt, ChangeLog.manual, ChangeLog.txt,
- DartConfig.cmake, bootstrap, Docs/cmake-mode.el,
- Modules/CMakeCCompiler.cmake.in,
- Modules/CMakeCXXCompiler.cmake.in,
- Modules/CMakeDefaultMakeRuleVariables.cmake,
- Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Modules/CMakeImportBuildSettings.cmake,
- Modules/CMakeSystemSpecificInformation.cmake,
- Modules/CMakeTestCCompiler.cmake, Modules/CMakeTestGNU.c,
- Modules/CheckForPthreads.c, Modules/CheckFunctionExists.c,
- Modules/CheckIncludeFile.cmake,
- Modules/CheckIncludeFileCXX.cmake, Modules/CheckTypeSize.c,
- Modules/CheckTypeSize.cmake, Modules/CheckVariableExists.c,
- Modules/Dart.cmake, Modules/DartConfiguration.tcl.in,
- Modules/FindDCMTK.cmake, Modules/FindGLUT.cmake,
- Modules/FindGTK.cmake, Modules/FindITK.cmake,
- Modules/FindJNI.cmake, Modules/FindMFC.cmake,
- Modules/FindOpenGL.cmake, Modules/FindPHP4.cmake,
- Modules/FindPerlLibs.cmake, Modules/FindPike.cmake,
- Modules/FindPythonLibs.cmake, Modules/FindQt.cmake,
- Modules/FindRuby.cmake, Modules/FindSWIG.cmake,
- Modules/FindTCL.cmake, Modules/FindTclsh.cmake,
- Modules/FindVTK.cmake, Modules/FindwxWidgets.cmake,
- Modules/FindwxWindows.cmake, Modules/MacOSXBundleInfo.plist.in,
- Modules/TestBigEndian.c, Modules/UseSWIG.cmake,
- Modules/UsewxWidgets.cmake, Modules/Platform/Darwin.cmake,
- Modules/Platform/HP-UX.cmake, Modules/Platform/IRIX64.cmake,
- Modules/Platform/Linux.cmake, Modules/Platform/OSF1.cmake,
- Modules/Platform/SunOS.cmake,
- Modules/Platform/Windows-bcc32.cmake,
- Modules/Platform/Windows-cl.cmake,
- Modules/Platform/Windows-gcc.cmake, Source/CMakeLists.txt,
- Source/TODO, Source/cmAddCustomCommandCommand.h,
- Source/cmAddCustomTargetCommand.cxx,
- Source/cmAddExecutableCommand.cxx,
- Source/cmAddExecutableCommand.h, Source/cmAddTestCommand.cxx,
- Source/cmCMakeMinimumRequired.h, Source/cmCPluginAPI.cxx,
- Source/cmCPluginAPI.h, Source/cmCTest.cxx, Source/cmCTest.h,
- Source/cmCacheManager.cxx, Source/cmCacheManager.h,
- Source/cmCommand.h, Source/cmCommands.cxx,
- Source/cmConfigure.cmake.h.in, Source/cmConfigureFileCommand.cxx,
- Source/cmConfigureFileCommand.h,
- Source/cmCreateTestSourceList.cxx,
- Source/cmCreateTestSourceList.h, Source/cmDocumentation.cxx,
- Source/cmDocumentation.h, Source/cmDynamicLoader.cxx,
- Source/cmElseCommand.h, Source/cmEnableTestingCommand.cxx,
- Source/cmEnableTestingCommand.h, Source/cmEndForEachCommand.cxx,
- Source/cmEndForEachCommand.h, Source/cmEndIfCommand.h,
- Source/cmExecProgramCommand.h,
- Source/cmExportLibraryDependencies.cxx,
- Source/cmFLTKWrapUICommand.cxx, Source/cmFileCommand.cxx,
- Source/cmFileCommand.h, Source/cmFindFileCommand.h,
- Source/cmFindLibraryCommand.h, Source/cmFindPackageCommand.cxx,
- Source/cmFindPackageCommand.h, Source/cmFindPathCommand.cxx,
- Source/cmFindPathCommand.h, Source/cmFindProgramCommand.h,
- Source/cmForEachCommand.cxx, Source/cmForEachCommand.h,
- Source/cmGeneratedFileStream.h,
- Source/cmGetCMakePropertyCommand.cxx,
- Source/cmGetDirectoryPropertyCommand.cxx,
- Source/cmGetDirectoryPropertyCommand.h,
- Source/cmGetFilenameComponentCommand.h,
- Source/cmGetSourceFilePropertyCommand.cxx,
- Source/cmGetTargetPropertyCommand.cxx, Source/cmGlob.cxx,
- Source/cmGlobalBorlandMakefileGenerator.cxx,
- Source/cmGlobalCodeWarriorGenerator.cxx,
- Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmGlobalNMakeMakefileGenerator.cxx,
- Source/cmGlobalUnixMakefileGenerator.cxx,
- Source/cmGlobalVisualStudio6Generator.cxx,
- Source/cmGlobalVisualStudio6Generator.h,
- Source/cmGlobalVisualStudio71Generator.cxx,
- Source/cmGlobalVisualStudio71Generator.h,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.h, Source/cmIfCommand.cxx,
- Source/cmIfCommand.h, Source/cmIncludeCommand.cxx,
- Source/cmIncludeCommand.h, Source/cmInstallTargetsCommand.cxx,
- Source/cmInstallTargetsCommand.h,
- Source/cmLinkLibrariesCommand.cxx,
- Source/cmLinkLibrariesCommand.h, Source/cmListFileCache.cxx,
- Source/cmListFileCache.h, Source/cmListFileLexer.c,
- Source/cmListFileLexer.h, Source/cmListFileLexer.in.l,
- Source/cmLoadCacheCommand.h, Source/cmLoadCommandCommand.cxx,
- Source/cmLocalCodeWarriorGenerator.cxx,
- Source/cmLocalGenerator.cxx, Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.h,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h,
- Source/cmMacroCommand.cxx, Source/cmMacroCommand.h,
- Source/cmMakeDepend.cxx, Source/cmMakeDirectoryCommand.h,
- Source/cmMakefile.cxx, Source/cmMakefile.h,
- Source/cmMessageCommand.h, Source/cmOptionCommand.cxx,
- Source/cmOutputRequiredFilesCommand.h,
- Source/cmQTWrapCPPCommand.cxx, Source/cmQTWrapCPPCommand.h,
- Source/cmQTWrapUICommand.cxx, Source/cmQTWrapUICommand.h,
- Source/cmRemoveCommand.h, Source/cmRemoveDefinitionsCommand.cxx,
- Source/cmRemoveDefinitionsCommand.h,
- Source/cmSeparateArgumentsCommand.h, Source/cmSetCommand.h,
- Source/cmSetDirectoryPropertiesCommand.cxx,
- Source/cmSetDirectoryPropertiesCommand.h,
- Source/cmSetSourceFilesPropertiesCommand.cxx,
- Source/cmSetTargetPropertiesCommand.h,
- Source/cmSiteNameCommand.cxx, Source/cmSourceFile.cxx,
- Source/cmSourceFilesCommand.cxx, Source/cmStandardIncludes.h,
- Source/cmStringCommand.cxx, Source/cmStringCommand.h,
- Source/cmSubdirCommand.cxx, Source/cmSubdirCommand.h,
- Source/cmSystemTools.cxx, Source/cmSystemTools.h,
- Source/cmTarget.cxx, Source/cmTarget.h,
- Source/cmTargetLinkLibrariesCommand.cxx,
- Source/cmTargetLinkLibrariesCommand.h,
- Source/cmTryCompileCommand.cxx, Source/cmTryCompileCommand.h,
- Source/cmUseMangledMesaCommand.h,
- Source/cmVTKMakeInstantiatorCommand.cxx,
- Source/cmVTKWrapJavaCommand.h, Source/cmVTKWrapPythonCommand.h,
- Source/cmVTKWrapTclCommand.h, Source/cmWin32ProcessExecution.cxx,
- Source/cmWrapExcludeFilesCommand.cxx,
- Source/cmWriteFileCommand.cxx, Source/cmWriteFileCommand.h,
- Source/cmake.cxx, Source/cmake.h, Source/cmakemain.cxx,
- Source/cmaketest.cxx, Source/cmakewizard.cxx,
- Source/cmakewizard.h, Source/ctest.cxx,
- Source/CTest/cmCTestSubmit.cxx, Source/CTest/cmCTestSubmit.h,
- Source/CursesDialog/ccmake.cxx,
- Source/CursesDialog/cmCursesMainForm.cxx,
- Source/CursesDialog/cmCursesPathWidget.cxx,
- Source/CursesDialog/cmCursesStringWidget.cxx,
- Source/kwsys/Base64.c, Source/kwsys/Base64.h.in,
- Source/kwsys/CMakeLists.txt, Source/kwsys/Configure.h.in,
- Source/kwsys/Configure.hxx.in, Source/kwsys/Copyright.txt,
- Source/kwsys/Directory.cxx, Source/kwsys/Directory.hxx.in,
- Source/kwsys/EncodeExecutable.c, Source/kwsys/Process.h.in,
- Source/kwsys/ProcessFwd9x.c, Source/kwsys/ProcessUNIX.c,
- Source/kwsys/ProcessWin32.c, Source/kwsys/RegularExpression.cxx,
- Source/kwsys/RegularExpression.hxx.in,
- Source/kwsys/SystemTools.cxx, Source/kwsys/SystemTools.hxx.in,
- Source/kwsys/kwsysHeaderDump.pl,
- Source/kwsys/kwsysPlatformCxxTests.cmake,
- Source/kwsys/kwsysPlatformCxxTests.cxx,
- Source/kwsys/kwsysPrivate.h, Source/kwsys/kwsys_ios_fstream.h.in,
- Source/kwsys/kwsys_ios_iosfwd.h.in,
- Source/kwsys/kwsys_ios_iostream.h.in,
- Source/kwsys/kwsys_ios_sstream.h.in, Source/kwsys/kwsys_std.h.in,
- Source/kwsys/kwsys_std_fstream.h.in,
- Source/kwsys/kwsys_std_iosfwd.h.in,
- Source/kwsys/kwsys_std_iostream.h.in,
- Source/kwsys/kwsys_std_sstream.h.in, Source/kwsys/kwsys_stl.h.in,
- Source/kwsys/test1.cxx, Source/kwsys/testIOS.cxx,
- Source/kwsys/testProcess.c, Templates/CMakeLists.txt,
- Templates/DLLHeader.dsptemplate, Templates/EXEHeader.dsptemplate,
- Templates/EXEWinHeader.dsptemplate, Templates/TestDriver.cxx.in,
- Templates/install-sh, Templates/staticLibHeader.dsptemplate,
- Tests/COnly/CMakeLists.txt, Tests/CommandLineTest/CMakeLists.txt,
- Tests/CommandLineTest/PreLoad.cmake,
- Tests/Complex/CMakeLists.txt, Tests/Complex/VarTests.cmake,
- Tests/Complex/Executable/complex.cxx,
- Tests/Complex/Library/CMakeLists.txt,
- Tests/Complex/Library/file2.cxx,
- Tests/Complex/Library/testConly.c,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexOneConfig/VarTests.cmake,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexOneConfig/Library/CMakeLists.txt,
- Tests/ComplexOneConfig/Library/file2.cxx,
- Tests/ComplexOneConfig/Library/testConly.c,
- Tests/ComplexRelativePaths/CMakeLists.txt,
- Tests/ComplexRelativePaths/VarTests.cmake,
- Tests/ComplexRelativePaths/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Library/CMakeLists.txt,
- Tests/ComplexRelativePaths/Library/file2.cxx,
- Tests/ComplexRelativePaths/Library/testConly.c,
- Tests/CustomCommand/CMakeLists.txt,
- Tests/CustomCommand/generator.cxx,
- Tests/CustomCommand/wrapper.cxx, Tests/Jump/CMakeLists.txt,
- Tests/Jump/Executable/CMakeLists.txt,
- Tests/Jump/Executable/jumpExecutable.cxx,
- Tests/Jump/Library/CMakeLists.txt,
- Tests/Jump/Library/Shared/CMakeLists.txt,
- Tests/Jump/Library/Shared/jumpShared.cxx,
- Tests/Jump/Library/Static/CMakeLists.txt,
- Tests/Jump/Library/Static/jumpStatic.cxx,
- Tests/LinkLineOrder/Two.c, Tests/LoadCommand/CMakeLists.txt,
- Tests/LoadCommand/CMakeCommands/cmTestCommand.c,
- Tests/LoadCommandOneConfig/CMakeLists.txt,
- Tests/LoadCommandOneConfig/CMakeCommands/cmTestCommand.c,
- Tests/PreOrder/CMakeLists.txt, Tests/PreOrder/simple.cxx,
- Tests/PreOrder/Library/CMakeLists.txt,
- Tests/PreOrder/Library/simpleLib.cxx,
- Tests/Simple/CMakeLists.txt, Tests/Simple/simpleWe.cpp,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstall/PostInstall.cmake,
- Tests/SimpleInstall/PreInstall.cmake, Tests/SimpleInstall/foo.c,
- Tests/SimpleInstall/foo.h, Tests/SimpleInstall/inst.cxx,
- Tests/SimpleInstall/lib1.cxx, Tests/SimpleInstall/lib1.h,
- Tests/SimpleInstall/lib2.cxx, Tests/SimpleInstall/lib2.h,
- Tests/SimpleInstall/lib3.cxx, Tests/SimpleInstall/lib3.h,
- Tests/SimpleInstallS2/CMakeLists.txt,
- Tests/SimpleInstallS2/PostInstall.cmake,
- Tests/SimpleInstallS2/PreInstall.cmake,
- Tests/SimpleInstallS2/foo.c, Tests/SimpleInstallS2/foo.h,
- Tests/SimpleInstallS2/inst.cxx, Tests/SimpleInstallS2/lib1.cxx,
- Tests/SimpleInstallS2/lib1.h, Tests/SimpleInstallS2/lib2.cxx,
- Tests/SimpleInstallS2/lib2.h, Tests/SimpleInstallS2/lib3.cxx,
- Tests/SimpleInstallS2/lib3.h,
- Tests/StringFileTest/CMakeLists.txt,
- Tests/StringFileTest/InputFile.h.in, Tests/SubDir/CMakeLists.txt,
- Tests/SubDir/vcl_algorithm+vcl_pair+double.foo.c,
- Tests/SubDir/AnotherSubdir/pair+int.int.c,
- Tests/SubDir/AnotherSubdir/secondone.c,
- Tests/SubDir/AnotherSubdir/testfromsubdir.c,
- Tests/SubDir/Examples/CMakeLists.txt,
- Tests/SubDir/Examples/example1/CMakeLists.txt,
- Tests/SubDir/Examples/example1/example1.cxx,
- Tests/SubDir/Examples/example2/CMakeLists.txt,
- Tests/SubDir/Examples/example2/example2.cxx,
- Tests/SubDir/Executable/CMakeLists.txt,
- Tests/SubDir/Executable/test.cxx,
- Tests/SubDir/ThirdSubDir/pair+int.int1.c,
- Tests/SubDir/ThirdSubDir/pair_p_int.int1.c,
- Tests/SubDir/ThirdSubDir/testfromauxsubdir.c,
- Tests/SubDir/ThirdSubDir/thirdone.c,
- Tests/SwigTest/CMakeLists.txt, Tests/SwigTest/example.cxx,
- Tests/SwigTest/example.h, Tests/SwigTest/example.i,
- Tests/SwigTest/runme.php4, Tests/SwigTest/runme.pike,
- Tests/SwigTest/runme.pl, Tests/SwigTest/runme.py,
- Tests/SwigTest/runme.rb, Tests/SwigTest/runme.tcl,
- Tests/SwigTest/runme2.tcl,
- Tests/SystemInformation/CMakeLists.txt,
- Tests/SystemInformation/DumpInformation.cxx,
- Tests/TryCompile/CMakeLists.txt, Tests/Wrapping/CMakeLists.txt,
- Tests/Wrapping/vtkTestMoc.h, Utilities/Doxygen/CMakeLists.txt,
- Utilities/Doxygen/doxyfile.in,
- Utilities/Release/cmake_release.sh,
- Utilities/Release/config_IRIX64,
- Utilities/Release/release_dispatch.sh: updated to 2.0.1
-
-2004-06-11 15:07 hoffman
-
- * Source/cmIfCommand.cxx: BUG: fix crash for if statment due to bad
- microsoft docs on deque BUG id 917
-
-2004-06-09 18:56 martink
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG#891: When building
- CMake itself, use the new cmake to install so that the current
- cmake can be overwritten.
-
-2004-06-09 18:01 martink
-
- * Source/CMakeLists.txt: ERR: Do not use the binary directory as a
- regular expression.
-
-2004-06-09 17:36 martink
-
- * Source/cmCTest.cxx: BUG: Files in top-level directory of source
- tree were not reported in updates log.
-
-2004-06-09 11:30 andy
-
- * DartConfig.cmake: ENH: Cleanups
-
-2004-06-09 11:19 andy
-
- * Source/cmCTest.cxx: BUG: Even if update fails it should produce
- valid XML
-
-2004-06-09 10:37 andy
-
- * DartConfig.cmake: ENH: Use viewcvs instead of cvsweb
-
-2004-06-08 17:36 martink
-
- * Source/cmCTest.cxx: support for floating ponit strides
-
-2004-06-08 17:26 barre
-
- * Modules/FindDoxygen.cmake, Utilities/Doxygen/CMakeLists.txt: a)
- new version of tools like Doxygen and Graphviz now set install
- path info in win32 registery. use it. b) remove DOT_PATH, it was
- polluting the cache (can be computed from DOT, update
- CMakeLists.txt accordingly if DOT_PATH is not defined)
-
-2004-06-07 21:41 hoffman
-
- * Source/kwsys/SystemTools.cxx: BUG: undo last bug fix because it
- breaks cmake, rebuild_cache on ParaView gets tons of errors about
- not being able to create the bin directory
-
-2004-06-07 13:55 king
-
- * Source/kwsys/SystemTools.cxx: BUG: Do not create a directory on
- top of a file.
-
-2004-06-07 12:35 hoffman
-
- * Source/: cmCTest.cxx, cmCTest.h, CTest/cmCTestSubmit.cxx,
- CTest/cmCTestSubmit.h: merge from main tree, add support for scp
- submit
-
-2004-06-07 09:54 hoffman
-
- * Modules/FindFLTK.cmake: merge from main tree, fix order of
- libraries
-
-2004-06-07 09:50 hoffman
-
- * Tests/Simple/CMakeLists.txt: merge from main tree
-
-2004-06-07 09:49 hoffman
-
- * Source/kwsys/SystemTools.cxx: merge from main tree, fix find
- library so it does not find directories
-
-2004-06-07 09:48 hoffman
-
- * Source/cmMakefile.cxx: merge from main tree, detect problems
- writting files
-
-2004-06-07 09:47 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: merger from main tree,
- fix subdir preorder
-
-2004-06-07 09:46 hoffman
-
- * Source/cmLocalGenerator.cxx: merge from main tree, fix install
- with subdir and not exepath
-
-2004-06-07 09:46 hoffman
-
- * Source/: cmGlobalVisualStudio71Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: merge from main tree, fix
- crash in external project include
-
-2004-06-07 09:45 hoffman
-
- * Source/cmCreateTestSourceList.cxx: merge from main tree, do not
- write test driver each time cmake is run
-
-2004-06-07 09:44 hoffman
-
- * Source/: cmCTest.cxx, cmCTest.h: ENH: changes from main tree,
- some different -I options, CTEST_DASHBOARD_ROOT computation, some
- more error and warning matches
-
-2004-06-07 08:51 andy
-
- * Source/CTest/cmCTestSubmit.cxx: ERR: Remove warning
-
-2004-06-04 14:59 king
-
- * Source/kwsys/CMakeLists.txt: ERR: Do not add the library if no
- sources are used.
-
-2004-06-03 19:12 andy
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ERR: Remove testinf of PREORDER
- on Windows
-
-2004-06-03 17:09 andy
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ERR: Try to fix simple install on
- vs6
-
-2004-06-03 14:54 hoffman
-
- * Modules/FindFLTK.cmake: Fix for bug 903 change order of fltk
- libraries
-
-2004-06-02 13:39 andy
-
- * Source/: cmCTest.cxx, cmCTest.h, CTest/cmCTestSubmit.cxx,
- CTest/cmCTestSubmit.h: ENH: Implement scp submission
-
-2004-06-01 14:08 king
-
- * Modules/Platform/: HP-UX.cmake, IRIX.cmake, IRIX64.cmake,
- OSF1.cmake, Windows-bcc32.cmake, gcc.cmake: BUG#895: Adding
- -DNDEBUG to C and C++ flags for release builds.
-
-2004-06-01 12:55 andy
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstall/TestSubDir/CMakeLists.txt,
- SimpleInstall/TestSubDir/TSD.cxx, SimpleInstall/TestSubDir/TSD.h,
- SimpleInstall/TestSubDir/TSD_utils.cxx,
- SimpleInstallS2/CMakeLists.txt,
- SimpleInstallS2/TestSubDir/CMakeLists.txt,
- SimpleInstallS2/TestSubDir/TSD.cxx,
- SimpleInstallS2/TestSubDir/TSD.h,
- SimpleInstallS2/TestSubDir/TSD_utils.cxx: ENH: More elaborate
- install test
-
-2004-06-01 12:19 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: make sure find library does
- not find directories
-
-2004-06-01 12:07 hoffman
-
- * Source/: cmGlobalVisualStudio71Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: BUG: fix for 871, include
- external should work for 7.1 and 7.0
-
-2004-06-01 11:30 andy
-
- * Source/cmLocalGenerator.cxx: ENH: Fix bug in cmake install when
- exec/librayr output path not defined. Closes Bug #899 - subdir
- INSTALL_TARGETS INSTALL_PROGRAMS dont work
-
-2004-06-01 09:58 andy
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: Fix preorder. This
- caused preorder to not work and the test passed because of
- jump-over rule
-
-2004-05-28 15:02 martink
-
- * Source/: cmCTest.cxx, cmCTest.h: ctest -S support for multiple
- ctest command arguments
-
-2004-05-27 12:56 andy
-
- * Source/cmCreateTestSourceList.cxx: BUG: When creating a test
- driver, do not remove the old file, so if nothing changes, it
- will not rebuild. Fixes Bug #885 - cmCreateTestSource overwrite
- file when running cmake
-
-2004-05-27 12:53 andy
-
- * Source/cmMakefile.cxx: ENH: Detect if there were problems writing
- file
-
-2004-05-27 11:21 king
-
- * Utilities/Release/cmake_release.sh: Updated to not include CVS
- directories in cygwin package.
-
-2004-05-26 15:27 martink
-
- * Source/cmCTest.cxx: added another error string and change the -I
- option some
-
-2004-05-25 14:34 martink
-
- * CMakeLists.txt, Utilities/Release/cmake_release.sh: merges from
- the main tree
-
-2004-05-25 11:31 martink
-
- * Modules/CMakeImportBuildSettings.cmake, Modules/FindQt.cmake,
- Modules/UseSWIG.cmake, Source/cmCTest.cxx,
- Source/cmCacheManager.cxx, Source/cmCacheManager.h,
- Source/cmGeneratedFileStream.h,
- Source/cmGetDirectoryPropertyCommand.cxx,
- Source/cmGlobalVisualStudio71Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.h,
- Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h,
- Source/cmMacroCommand.cxx, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmSetDirectoryPropertiesCommand.cxx,
- Source/cmSetDirectoryPropertiesCommand.h,
- Source/cmSystemTools.cxx, Tests/CommandLineTest/CMakeLists.txt,
- Tests/Simple/CMakeLists.txt, Tests/TryCompile/CMakeLists.txt:
- merges from the main tree
-
-2004-05-25 11:20 martink
-
- * Modules/CMakeImportBuildSettings.cmake, Source/cmCTest.cxx:
- better error message
-
-2004-05-21 11:52 hoffman
-
- * Source/cmSystemTools.cxx: ENH: speed up for NOTFOUND
-
-2004-05-21 09:51 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx: ENH: fix rerun of cmake
- command
-
-2004-05-20 21:27 hoffman
-
- * Source/cmSystemTools.cxx: BUG: back out change due to broken
- dashboard
-
-2004-05-20 17:33 hoffman
-
- * Source/cmSystemTools.cxx: ENH: remove regex use where strcmp is
- faster
-
-2004-05-20 16:56 andy
-
- * Modules/UseSWIG.cmake, Source/cmGetDirectoryPropertyCommand.cxx,
- Source/cmLocalUnixMakefileGenerator.cxx, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmSetDirectoryPropertiesCommand.cxx,
- Source/cmSetDirectoryPropertiesCommand.h: ENH: Implement
- additional make clean files as a directory property instead of
- cmake variable
-
-2004-05-20 16:35 hoffman
-
- * Tests/TryCompile/CMakeLists.txt: BUG: dont put the output of a
- try compile in the output because visual stduio 7 ide will thing
- there were errors
-
-2004-05-20 16:29 hoffman
-
- * Source/: cmGeneratedFileStream.h,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h: BUG: make sure global generate
- is done when cmakelist file chagnes, also make sure guids are
- stored in the cache so the .sln file does not change every time
-
-2004-05-20 16:26 hoffman
-
- * Modules/FindQt.cmake: ENH: look for qtmoc in some other places
-
-2004-05-20 15:08 martink
-
- * Source/: cmCacheManager.cxx, cmCacheManager.h: updates to gui to
- delete cache
-
-2004-05-20 13:15 martink
-
- * Source/cmCTest.cxx: added error
-
-2004-05-19 16:04 hoffman
-
- * Source/cmMacroCommand.cxx: ENH: make it run much faster
-
-2004-05-18 15:40 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: make sure
- ADDITIONAL_MAKE_CLEAN_FILES works with spaces in the path and is
- converted to the correct native path type
-
-2004-05-18 15:39 hoffman
-
- * Source/: cmEndForEachCommand.cxx, cmForEachCommand.cxx: merge
- from main tree, detect missing endforeach
-
-2004-05-18 15:39 hoffman
-
- * Source/: cmDocumentation.cxx, cmakemain.cxx: merge from main
- tree, move doc stuff around so it does not give cmake docs to
- ctest
-
-2004-05-18 15:38 hoffman
-
- * Source/cmCTest.cxx: merge from main tree, add some more obscure
- options to ctest
-
-2004-05-18 15:37 hoffman
-
- * Modules/UseSWIG.cmake: BUG: 835 fix
-
-2004-05-18 15:37 hoffman
-
- * Modules/CMakeTestGNU.c: BUG: 825 fix
-
-2004-05-18 14:33 hoffman
-
- * Modules/CMakeTestGNU.c: BUG: fix problem where cmake thinks the
- intel compiler is gnu
-
-2004-05-17 16:31 hoffman
-
- * Modules/UseSWIG.cmake: ENH: append to the list of clean files,
- don't just set them
-
-2004-05-17 15:56 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: change
- ADDITIONAL_MAKE_CLEAN_FILES to work with spaces in the path and
- on windows with no spaces
-
-2004-05-17 15:55 hoffman
-
- * Modules/UseSWIG.cmake: BUG: Bug #835 fix, add swig generated
- files to clean target
-
-2004-05-13 16:17 hoffman
-
- * ChangeLog.manual: add a hand edited changelog
-
-2004-05-13 16:17 hoffman
-
- * ChangeLog.manual: file ChangeLog.manual was added on branch
- CMake-2-6 on 2008-03-30 13:09:04 +0000
-
-2004-05-13 13:41 martink
-
- * Source/cmCTest.cxx: new feature for continuous clean once
-
-2004-05-13 13:07 king
-
- * Utilities/Release/cmake_release.sh: Removed support for
- wxCMakeSetup dialog.
-
-2004-05-13 10:34 hoffman
-
- * Source/kwsys/: Base64.h.in, CMakeLists.txt, Process.h.in,
- ProcessWin32.c, ProcessWin32Kill.c, ProcessWin32Kill.h.in,
- kwsysHeaderDump.pl: Merge changes from the main tree, fix a bug
- in the process kill code
-
-2004-05-13 10:08 king
-
- * Source/kwsys/ProcessWin32.c: BUG: Do not wait for children to
- exit when killing them. Sometimes they do not really die.
-
-2004-05-12 15:34 martink
-
- * Source/cmEndForEachCommand.cxx: fix warning
-
-2004-05-12 14:32 martink
-
- * Source/: cmEndForEachCommand.cxx, cmForEachCommand.cxx: better
- error checking for FOREACH
-
-2004-05-12 08:46 king
-
- * Utilities/Release/cmake_release.sh: ENH: Updated for 2.0.0
- release tag.
-
-2004-05-10 18:06 andy
-
- * Source/CMakeLists.txt, Tests/CTestTest/CMakeLists.txt,
- Tests/CTestTest/test.cmake.in,
- Tests/CommandLineTest/CMakeLists.txt: ENH: Add some ctest
- coverage
-
-2004-05-10 17:53 andy
-
- * Source/: cmDocumentation.cxx, cmakemain.cxx: BUG: Move
- documentation so that it does not apear in ctest
-
-2004-05-10 17:44 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: ENH: Add a way to force ctest to
- be a new process
-
-2004-05-10 16:58 king
-
- * Utilities/Release/cmake_release.sh: ENH: Added support for using
- cvs checkout instead of cvs export.
-
-2004-05-10 16:55 will
-
- * Source/cmCTest.cxx: ENH: Added regex.
-
-2004-05-10 16:40 king
-
- * Source/: cmLocalUnixMakefileGenerator.cxx: BUG: Need to recognize
- -B linker options.
-
-2004-05-10 15:49 king
-
- * Utilities/Release/release_dispatch.sh: ENH: Adding release
- dispatch script.
-
-2004-05-10 15:48 king
-
- * Utilities/Release/: cmake_release.sh, config_CYGWIN_NT-5.1,
- config_Linux, cygwin-package.sh.in: ENH: Updated to latest
- version from 1.8 branch.
-
-2004-05-10 14:54 king
-
- * Source/kwsys/: CMakeLists.txt, ProcessWin32.c,
- ProcessWin32Kill.c, ProcessWin32Kill.h.in: ENH: Adding native
- windows process tree kill to ProcessWin32.c. This replaces the
- ProcessWin32Kill.c implementation.
-
-2004-05-10 13:38 king
-
- * Source/kwsys/: Base64.h.in, ProcessWin32.c: ERR: Avoiding
- namespace pollution: kw_sys -> kwsys_ns. Also undefining the
- macro at the correct time.
-
-2004-05-10 13:15 king
-
- * Source/kwsys/kwsysHeaderDump.pl: ENH: Renaming kwsys macro to
- kwsys_ns to work around borland preprocessor bug.
-
-2004-05-10 13:10 king
-
- * Source/kwsys/: Process.h.in, ProcessWin32Kill.h.in: ERR: Avoiding
- namespace pollution: kw_sys -> kwsys_ns. Also undefining the
- macro at the correct time.
-
-2004-05-10 12:45 hoffman
-
- * Modules/FindGTK.cmake, Modules/Platform/OSF1.cmake,
- Source/cmCTest.cxx, Source/cmCTest.h, Source/cmIfCommand.cxx,
- Source/cmLocalGenerator.cxx, Source/cmake.cxx, Source/ctest.cxx,
- Source/kwsys/Base64.h.in, Source/kwsys/CMakeLists.txt,
- Source/kwsys/Process.h.in, Source/kwsys/ProcessWin32.c,
- Source/kwsys/ProcessWin32Kill.c,
- Source/kwsys/ProcessWin32Kill.h.in, Source/kwsys/SystemTools.cxx,
- Templates/TestDriver.cxx.in: merge from main tree
-
-2004-05-10 12:08 hoffman
-
- * Source/kwsys/ProcessWin32Kill.c: ENH: remove extra include for
- compile with mingw
-
-2004-05-10 12:06 hoffman
-
- * Source/kwsys/: CMakeLists.txt, ProcessWin32Kill.c,
- ProcessWin32Kill.cxx: ENH: change to c code so it can be built
- with mingw
-
-2004-05-10 11:04 hoffman
-
- * Source/kwsys/ProcessWin32Kill.cxx: ENH: remove unused include
- file so it will build with mingw
-
-2004-05-10 10:20 martink
-
- * Source/cmCTest.cxx: fix for config type passing between ctests
-
-2004-05-09 12:27 martink
-
- * Source/cmCTest.cxx: some cleanup and fix for PVLocal
-
-2004-05-08 14:55 hoffman
-
- * Templates/TestDriver.cxx.in: BUG: remove debug pop hacks, also
- remove duplicate call to argvc function
-
-2004-05-07 14:22 andy
-
- * Source/kwsys/: Base64.h.in, Process.h.in, ProcessWin32.c,
- ProcessWin32Kill.h.in: ERR: On Borland preprocessor goes into
- recursion which adds some weid spaces in the include name. This
- fixes it
-
-2004-05-07 13:26 hoffman
-
- * Source/ctest.cxx: ENH: better documentation
-
-2004-05-07 12:53 hoffman
-
- * Source/: cmCTest.cxx, cmCTest.h: ENH: add the ability to block
- popup error dialogs in tests on windows
-
-2004-05-07 12:52 hoffman
-
- * Source/kwsys/ProcessWin32.c: BUG: make sure the correct state is
- set for expired processes
-
-2004-05-07 11:24 martink
-
- * Source/cmCTest.cxx: missing header for unix
-
-2004-05-07 10:50 martink
-
- * Source/: cmCTest.cxx, cmCTest.h: updated testingoptions for
- continuous dashboards
-
-2004-05-07 10:16 hoffman
-
- * Modules/FindGTK.cmake: Add a missing dollar sign
-
-2004-05-07 08:35 martink
-
- * Templates/TestDriver.cxx.in: fix warning maybe
-
-2004-05-06 16:06 hoffman
-
- * Source/cmLocalGenerator.cxx: BUG: make sure install works with
- spaces in the path
-
-2004-05-06 15:34 king
-
- * Source/kwsys/: CMakeLists.txt, ProcessWin32.c,
- ProcessWin32Kill.cxx, ProcessWin32Kill.h.in: ENH: Adding process
- tree killing for Win32 process execution.
-
-2004-05-06 14:30 king
-
- * Source/kwsys/Process.h.in: ERR: Added units to SetTimeout
- documentation.
-
-2004-05-06 10:30 hoffman
-
- * Source/cmCTest.cxx: BUG: fix ctest so that the search path for
- test executables produces better output and does not use config
- dir when it is not set
-
-2004-05-06 10:29 hoffman
-
- * Source/kwsys/SystemTools.cxx: BUG: fix collapse full path to
- handle a file in the root directory
-
-2004-05-06 09:47 martink
-
- * Source/cmIfCommand.cxx: horrible hack
-
-2004-05-06 08:51 martink
-
- * Templates/TestDriver.cxx.in: fix warning
-
-2004-05-05 11:41 martink
-
- * Source/cmCTest.cxx: fix for in source testing
-
-2004-05-05 10:41 martink
-
- * Modules/Platform/OSF1.cmake: a guess at some OSF compiler flags
-
-2004-05-05 10:23 hoffman
-
- * ChangeLog.txt: change log up-to 2.0 branch point
-
-2004-05-05 10:21 hoffman
-
- * ChangeLog.txt: ENH: add new change log marking 2.0 branch
-
-2004-05-05 10:19 hoffman
-
- * CMakeLists.txt, Source/cmCPluginAPI.h: ENH: move version to 2.1
- for cvs because 2.0 has been branched
-
-2004-05-05 10:17 hoffman
-
- * CMakeLists.txt, Source/cmCPluginAPI.h,
- Utilities/Release/cmake_release.sh: ENH: move version numbers to
- cmake 2.0 for branch
-
-2004-05-05 10:13 andy
-
- * Source/: cmCTest.cxx, cmake.cxx: ENH: Remove memory leak
-
-2004-05-04 14:24 hoffman
-
- * Source/CMakeLists.txt, Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/complex.cxx: ENH: fix tests
- to work with in source builds
-
-2004-05-04 14:18 martink
-
- * Source/cmCTest.cxx: support in source builds and arg passing
-
-2004-05-04 11:24 andy
-
- * Modules/Platform/Windows-bcc32.cmake,
- Source/cmLocalUnixMakefileGenerator.cxx: ENH: Only mangle object
- files if CMAKE_MANGLE_OBJECT_FILE_NAMES is set. Only on borland
- for now.
-
-2004-05-04 09:16 martink
-
- * Source/cmIfCommand.cxx: fix warning
-
-2004-05-03 17:51 andy
-
- * Tests/SwigTest/CMakeLists.txt: ENH: Cleanup example a bit
-
-2004-05-03 16:38 andy
-
- * Source/cmCTest.cxx: ENH: After running test clear results for
- memory checking
-
-2004-05-03 16:36 andy
-
- * Source/cmCTest.cxx: ENH: Skip tests that do not have defects
-
-2004-05-03 16:35 andy
-
- * Modules/: CheckTypeSize.c, CheckTypeSize.cmake: ENH: support
- STDDEF and cleanup
-
-2004-05-03 15:33 martink
-
- * Source/cmIfCommand.cxx: minor backwards fix
-
-2004-05-03 12:34 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: fix to make spaces
- in paths work for jump over with borland and nmake on second
- build
-
-2004-05-03 12:02 andy
-
- * Tests/: LoadCommand/CMakeCommands/cmTestCommand.c,
- LoadCommandOneConfig/CMakeCommands/cmTestCommand.c: ENH: Remove
- warning
-
-2004-05-03 10:10 king
-
- * Source/cmStringCommand.h: ENH: Documented use of \1 syntax in
- replace expression.
-
-2004-05-03 08:52 hoffman
-
- * Tests/: LoadCommand/CMakeCommands/cmTestCommand.c,
- LoadCommandOneConfig/CMakeCommands/cmTestCommand.c: ENH: fix
- warnings in test
-
-2004-05-02 11:50 hoffman
-
- * Tests/: LinkLineOrder/Two.c,
- LoadCommand/CMakeCommands/cmTestCommand.c,
- LoadCommandOneConfig/CMakeCommands/cmTestCommand.c: ENH: remove
- warnings in tests
-
-2004-05-01 22:05 hoffman
-
- * Source/ctest.cxx: BUG: putenv syntax was wrong and caused a crash
- on the SGI
-
-2004-05-01 10:08 martink
-
- * Source/: cmIfCommand.cxx, cmIfCommand.h: better if expression
- support
-
-2004-05-01 10:07 martink
-
- * Modules/FindOpenGL.cmake: fix to find opengl on some osf systems
-
-2004-05-01 09:57 andy
-
- * Source/cmCTest.cxx: ERR: Remove warning about shadow variables
-
-2004-04-30 18:21 andy
-
- * Tests/: Complex/Library/testConly.c,
- ComplexOneConfig/Library/testConly.c,
- ComplexRelativePaths/Library/testConly.c,
- SubDir/ThirdSubDir/testfromauxsubdir.c: ENH: Remove warnings
-
-2004-04-30 17:28 andy
-
- * Tests/Simple/simpleWe.cpp: ENH: Remove warning
-
-2004-04-30 15:17 andy
-
- * Source/ctest.cxx: ENH: Add environment variable that Dart sets so
- that tests can know they are being tested from Dart/CTest
-
-2004-04-30 14:27 hoffman
-
- * Tests/SwigTest/CMakeLists.txt: ENH: link in more than just python
-
-2004-04-30 14:14 andy
-
- * Source/cmCTest.cxx: ENH: Report filename of the note
-
-2004-04-30 13:41 andy
-
- * Modules/FindSWIG.cmake: ENH: More paths
-
-2004-04-30 12:54 hoffman
-
- * Modules/FindSWIG.cmake: ENH: add another place to look for
- swig.exe
-
-2004-04-30 12:52 hoffman
-
- * Modules/FindSWIG.cmake: ENH: try to find swig.exe in SWIG_DIR
-
-2004-04-30 12:36 andy
-
- * Source/cmCTest.cxx: ENH: Add support for notes in Testing/Notes
- subdirectory. This way test can write notes that will be reported
-
-2004-04-30 12:17 andy
-
- * Tests/SwigTest/: CMakeLists.txt, example.cxx, example.h,
- example.i, runme.php4, runme.pike, runme.pl, runme.py, runme.rb,
- runme.tcl, runme2.tcl: ENH: Here is test for swig module
-
-2004-04-30 12:11 andy
-
- * Modules/: FindPHP4.cmake, FindPerlLibs.cmake, FindPike.cmake,
- FindRuby.cmake, FindSWIG.cmake, UseSWIG.cmake: ENH: Initial
- import of swig. Start working towards Bug #749 - Add swig support
- module to cmake
-
-2004-04-30 11:36 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: remove duplicate
- depend on cache file and use of make variable in make target
-
-2004-04-30 11:36 hoffman
-
- * Templates/TestDriver.cxx.in: ENH: remove unused variable
-
-2004-04-30 10:32 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: remove warnings
-
-2004-04-30 08:02 hoffman
-
- * Templates/CMakeLists.txt: BUG: add missing install file
-
-2004-04-29 17:44 king
-
- * Source/kwsys/CMakeLists.txt: ENH: Added automatic adjustment of
- C++ flags to include -timplicit_local and -no_implicit_include
- for the Compaq compiler on OSF.
-
-2004-04-29 17:41 andy
-
- * Source/cmMacroCommand.cxx, Source/cmMacroCommand.h,
- Tests/Complex/CMakeLists.txt,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexRelativePaths/CMakeLists.txt: ENH: Add ARGV and ARGN
- support to MACRO command. ARGV is the list of all arguments and
- ARGN is the list of all nonexpected arguments
-
-2004-04-29 15:12 andy
-
- * Source/cmForEachCommand.cxx, Source/cmForEachCommand.h,
- Tests/StringFileTest/CMakeLists.txt: ENH: Add RANGE support to
- FOREACH
-
-2004-04-29 14:51 andy
-
- * Source/: cmCTest.cxx, cmStandardIncludes.h: BUG: Add a safety
- check so that you cannot send cmOStringStream.str() to other
- stream and produce the funky hex number. This makes it impossible
- to compile such a code. Adding that exposed a whole bunch of
- places in CMake where streams were used wrongly
-
-2004-04-29 13:25 andy
-
- * Source/kwsys/SystemTools.cxx: BUG: Most of time when asking if
- file exists, we actually want to read it... Should fix Bug #809 -
- FIND_INCLUDE should check readability
-
-2004-04-29 12:33 hoffman
-
- * Source/: cmGetTargetPropertyCommand.cxx,
- cmLocalUnixMakefileGenerator.cxx: ENH: remove warnings
-
-2004-04-29 10:26 hoffman
-
- * Source/cmake.cxx: BUG: fix crash from bug id 806
-
-2004-04-28 14:25 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: remove warning
-
-2004-04-28 13:40 hoffman
-
- * Source/cmAddExecutableCommand.h: BUG: fix for bug 121 add some
- docs for MFC flag
-
-2004-04-28 13:21 hoffman
-
- * Modules/Platform/Darwin.cmake,
- Source/cmLocalUnixMakefileGenerator.cxx: BUG: fix for bug 116
- platform files can now specify directories that should not be
- added by CMAKE
-
-2004-04-28 12:31 hoffman
-
- * Source/cmCreateTestSourceList.cxx,
- Source/cmCreateTestSourceList.h, Templates/TestDriver.cxx.in:
- ENH: make test driver more flexible by using a configured file
- instead of generating all the code. fixes bug 28
-
-2004-04-28 10:52 andy
-
- * Source/cmake.cxx, Tests/CommandLineTest/CMakeLists.txt,
- Tests/CommandLineTest/PreLoad.cmake: ENH: Add support for
- automatically preloaded cmake file. Closes Bug #802 - Add auto
- preload file support in CMake
-
-2004-04-28 10:15 andy
-
- * Source/: cmLocalUnixMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator.h: ENH: Encode object files with
- funny characters in the name. It should fix Bug #418 - Borland
- 5.5.1, Templates/*.cxx files with '+' chars used in execs
-
-2004-04-28 10:09 hoffman
-
- * Tests/: Complex/VarTests.cmake, Complex/Executable/complex.cxx,
- ComplexOneConfig/VarTests.cmake,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/VarTests.cmake,
- ComplexRelativePaths/Executable/complex.cxx: ENH: add a test for
- EQUAL in if
-
-2004-04-28 10:05 andy
-
- * Tests/SubDir/ThirdSubDir/: pair_p_int.int1.c,
- testfromauxsubdir.c: ENH: More special cases
-
-2004-04-28 10:00 hoffman
-
- * Modules/: CheckIncludeFile.cmake, CheckIncludeFileCXX.cmake: ENH:
- fixes for optional flag arguments to check include macros
-
-2004-04-28 09:59 hoffman
-
- * Source/cmIfCommand.cxx: BUG: fix logic in EQUAL if test
-
-2004-04-28 09:52 hoffman
-
- * Modules/CheckIncludeFileCXX.cmake: BUG: fix for bug 80, check
- include cxx now has an optional argument that can is added to the
- cxx flags
-
-2004-04-28 09:51 hoffman
-
- * Source/: cmIfCommand.cxx, cmIfCommand.h: ENH: add a numeric EQUAL
- to the IF statment, very useful for variable arguments in MACROS
-
-2004-04-27 14:16 andy
-
- * Source/kwsys/: Base64.c, Base64.h.in, CMakeLists.txt,
- Configure.h.in, Configure.hxx.in, Copyright.txt, Directory.cxx,
- Directory.hxx.in, EncodeExecutable.c, Process.h.in,
- ProcessFwd9x.c, ProcessUNIX.c, ProcessWin32.c, README.txt,
- RegularExpression.cxx, RegularExpression.hxx.in, SystemTools.cxx,
- SystemTools.hxx.in, kwsysHeaderDump.pl,
- kwsysPlatformCxxTests.cmake, kwsysPlatformCxxTests.cxx,
- kwsysPrivate.h, kwsys_ios_fstream.h.in, kwsys_ios_iosfwd.h.in,
- kwsys_ios_iostream.h.in, kwsys_ios_sstream.h.in, kwsys_stl.h.in,
- test1.cxx, testIOS.cxx, testProcess.c: ENH: Move to VolView
- branch
-
-2004-04-27 12:03 andy
-
- * Source/cmGetTargetPropertyCommand.cxx,
- Tests/CustomCommand/CMakeLists.txt: ENH: Add LOCATION to
- GET_TARGET_PROPERTY. Closes Bug #34 - Add to GET_TARGET_PROPERTY
- location of target
-
-2004-04-27 12:02 andy
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h,
- cmLocalUnixMakefileGenerator.cxx, cmLocalUnixMakefileGenerator.h:
- ENH: GetSafeDefinition is now in cmMakefile
-
-2004-04-27 11:30 andy
-
- * Source/: cmMakefile.cxx, cmMakefile.h: ENH: Add method to get
- definition even if it does not exists
-
-2004-04-27 11:08 andy
-
- * Tests/CustomCommand/: generator.cxx, wrapper.cxx: ERR: Remove
- warnings from tests
-
-2004-04-27 09:22 andy
-
- * Source/cmSourceFile.cxx, Tests/SubDir/CMakeLists.txt,
- Tests/SubDir/vcl_algorithm+vcl_pair+double.foo.c,
- Tests/SubDir/AnotherSubdir/pair+int.int.c,
- Tests/SubDir/AnotherSubdir/secondone.c,
- Tests/SubDir/AnotherSubdir/testfromsubdir.c,
- Tests/SubDir/ThirdSubDir/pair+int.int1.c,
- Tests/SubDir/ThirdSubDir/testfromauxsubdir.c,
- Tests/SubDir/ThirdSubDir/thirdone.c: BUG: Fix aus source dir and
- add better testing of it
-
-2004-04-27 08:30 hoffman
-
- * Source/: cmLoadCommandCommand.cxx, cmMacroCommand.cxx: WRN:
- remove warnings
-
-2004-04-26 18:51 andy
-
- * Source/cmCTest.cxx: ENH: Another one of those nasty hex numbers
- in the ctest output
-
-2004-04-26 18:49 andy
-
- * Tests/SubDir/AnotherSubdir/: secondone.c, testfromsubdir.c: ENH:
- Add extra test files
-
-2004-04-26 17:45 hoffman
-
- * Source/cmLoadCommandCommand.cxx: ENH: fix for bug id 27, add a
- signal handler for crashes in loaded commands
-
-2004-04-26 17:32 andy
-
- * Source/CMakeLists.txt, Source/cmSourceFile.cxx,
- Tests/SubDir/CMakeLists.txt, Tests/SubDir/Executable/test.cxx:
- ENH: When source file is in subdirectory put object file in
- subdirectory. Fixes Bug #290 - Source files in subdirectories
- should produce object files in subdirectories
-
-2004-04-26 13:42 andy
-
- * Modules/FindTCL.cmake: ENH: Add TCL_FOUND
-
-2004-04-26 13:42 andy
-
- * Templates/: CMakeLists.txt, install-sh: ENH: With new install
- framework we don't need install-sh any more
-
-2004-04-26 13:42 andy
-
- * Tests/SystemInformation/: CMakeLists.txt, DumpInformation.cxx:
- ENH:Add test for GET/SET_DIRECTORY_PROPERTY
-
-2004-04-26 11:23 andy
-
- * Source/: cmake.cxx, cmake.h: BUG: Fix resolving of infinite loops
- while CMakeSetup/ccmake still running
-
-2004-04-26 11:12 martink
-
- * Tests/: Complex/CMakeLists.txt, Complex/Executable/complex.cxx,
- ComplexOneConfig/CMakeLists.txt,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/CMakeLists.txt,
- ComplexRelativePaths/Executable/complex.cxx: added tests for var
- args with macros
-
-2004-04-26 11:11 martink
-
- * Source/: cmMacroCommand.cxx, cmMacroCommand.h: macros now support
- varargs
-
-2004-04-26 11:00 king
-
- * Modules/FindITK.cmake, Modules/FindVTK.cmake,
- Source/cmFindPackageCommand.cxx: BUG#682: Adding environment
- variable check to FIND_PACKAGE command.
-
-2004-04-26 10:49 king
-
- * Source/cmFindPackageCommand.cxx: STYLE: Removed trailing
- whitespace.
-
-2004-04-26 10:19 king
-
- * Modules/: CheckVariableExists.c: BUG#502: Do not let optimizing
- compilers think the symbol exists. Require the symbol by making
- the return value depend on it to force linking.
-
-2004-04-23 16:26 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Templates/DLLHeader.dsptemplate, Templates/EXEHeader.dsptemplate,
- Templates/EXEWinHeader.dsptemplate: BUG: fix for bug 769
- CMAKE_STANDARD_LIBRARIES now used in ides
-
-2004-04-23 16:20 andy
-
- * Source/: cmCommands.cxx, cmGetDirectoryPropertyCommand.cxx,
- cmGetDirectoryPropertyCommand.h, cmMakefile.h,
- cmSetDirectoryPropertiesCommand.cxx,
- cmSetDirectoryPropertiesCommand.h: ENH: Add
- GET/SET_DIRECTORY_PROPERTY/PROPERTIES commands so that we can
- change include directories and get all sorts of things. Closes
- Bug #25 - Get_CMAKE_PROPERTIES
-
-2004-04-23 13:12 hoffman
-
- * Modules/CMakeSystemSpecificInformation.cmake,
- Source/cmLocalVisualStudio7Generator.cxx: ENH: add verbose make
- abilility to visual studio 7
-
-2004-04-23 12:52 hoffman
-
- * Source/CMakeLists.txt, Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.h, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmSubdirCommand.cxx,
- Tests/PreOrder/CMakeLists.txt, Tests/PreOrder/simple.cxx,
- Tests/PreOrder/Library/CMakeLists.txt,
- Tests/PreOrder/Library/simpleLib.cxx: ENH: add SUBDIR PREORDER
- and fix clean for non-relative paths
-
-2004-04-23 10:03 andy
-
- * Source/: cmAddExecutableCommand.cxx, cmAddExecutableCommand.h:
- ENH: Unify with other variables
-
-2004-04-23 09:12 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx: ENH: allow verbose
- makefile flag to remove nologo from all commands so you can see
- them in visual studio 6
-
-2004-04-23 08:50 king
-
- * Source/cmCTest.cxx: ERR: Fixed unused variable assignment
- warning.
-
-2004-04-22 18:04 andy
-
- * Source/cmCTest.cxx: ENH: Add DynamicAnalisys support. The old
- Purify is still available through --compatibility-mode
-
-2004-04-22 17:23 hoffman
-
- * Modules/: FindwxWidgets.cmake, UsewxWidgets.cmake: BUG: fix for
- bug 618
-
-2004-04-22 17:20 hoffman
-
- * Modules/FindGLUT.cmake: BUG: fix for bug 743
-
-2004-04-22 17:08 hoffman
-
- * Modules/FindGTK.cmake: BUG: fix for bug 607
-
-2004-04-22 16:58 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Templates/staticLibHeader.dsptemplate: ENH: add support for
- static library property STATIC_LIBRARY_FLAGS
-
-2004-04-22 16:16 hoffman
-
- * Modules/FindDCMTK.cmake: ENH: contribution from Ian Scott,
- thanks.
-
-2004-04-22 15:59 martink
-
- * Modules/FindOpenGL.cmake: update comments
-
-2004-04-22 14:38 hoffman
-
- * Source/cmTarget.cxx: ENH: add a property for HAS_CXX to a target
- that will force the use of a c++ compiler in the linking of an
- executable that contains only c code
-
-2004-04-22 14:11 andy
-
- * Source/kwsys/SystemTools.cxx: ERR: Verify that getenv returned
- something before using it
-
-2004-04-22 13:37 martink
-
- * Source/cmAddCustomCommandCommand.h: update docs
-
-2004-04-22 13:24 hoffman
-
- * Source/: cmFindLibraryCommand.h, cmFindPathCommand.cxx,
- cmFindPathCommand.h, cmMakefile.cxx, kwsys/SystemTools.cxx,
- kwsys/SystemTools.hxx.in: BUG: fix for 301 CMAKE_LIBRARY_PATH and
- CMAKE_INCLUDE_PATH env vars now used in FIND_LIBRARY and
- FIND_PATH in addtion to and before PATH
-
-2004-04-22 11:12 hoffman
-
- * Modules/FindwxWindows.cmake: BUG: fix bad if statements
-
-2004-04-22 09:44 hoffman
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: BUG 178: make top level
- cmakelist file a source in ALL_BUILD
-
-2004-04-21 17:54 andy
-
- * Source/cmGlobalVisualStudio71Generator.cxx: ERR: Fix install on
- VS71
-
-2004-04-21 16:23 king
-
- * Source/: cmListFileLexer.c, cmListFileLexer.h,
- cmListFileLexer.in.l: ENH: Added cmListFileLexer_SetString method
- to allow a string to be parsed as input.
-
-2004-04-21 16:07 hoffman
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: add dep
-
-2004-04-21 15:09 hoffman
-
- * Modules/FindwxWindows.cmake: ENH: fix for mingw
-
-2004-04-21 11:42 andy
-
- * Source/cmFileCommand.cxx: BUG: Put all files to manifest
-
-2004-04-21 11:36 king
-
- * Source/cmAddCustomTargetCommand.cxx: BUG: Fixed check of number
- of arguments.
-
-2004-04-21 11:33 king
-
- * Modules/: FindITK.cmake, FindVTK.cmake: ENH: Terminate with a
- FATAL_ERROR if FIND_PACKAGE command was called with REQUIRED
- argument and package was not found.
-
-2004-04-21 11:32 andy
-
- * Source/cmLocalGenerator.cxx: ENH: Do preinstall and postinstall
- script even if the target is not installed
-
-2004-04-21 10:34 andy
-
- * Source/: cmakemain.cxx, ctest.cxx: ENH: Report error and exit
- when the current directory is not specified
-
-2004-04-21 10:33 andy
-
- * Source/kwsys/SystemTools.cxx: BUG: Prevent crash when the current
- working directory cannot be established
-
-2004-04-20 18:28 andy
-
- * Source/cmSystemTools.cxx: BUG: If the line ends without new-line
- character, Split should still return something
-
-2004-04-19 17:21 andy
-
- * Source/cmCTest.cxx: RNH: Support NoDartCoverage in the binary
- directorory
-
-2004-04-19 10:36 king
-
- * Source/: cmFindPackageCommand.cxx, cmFindPackageCommand.h:
- ENH#696: Adding REQUIRED option to FIND_PACKAGE command. It will
- terminate the cmake configure step if the package is not found.
-
-2004-04-18 14:41 andy
-
- * Source/: cmFileCommand.cxx, cmFileCommand.h,
- cmGlobalGenerator.cxx, cmMakefile.cxx, cmMakefile.h,
- cmWriteFileCommand.cxx, cmWriteFileCommand.h, cmake.cxx, cmake.h:
- ENH: Add check for infinite loops. Make sure that files written
- using WRITE_FILE and FILE WRITE are not used as input files.
- Fixes Bug #678 - WRITE_FILE and FILE(WRITE...) lead to infinite
- loops
-
-2004-04-18 13:16 andy
-
- * Source/: cmLocalUnixMakefileGenerator.cxx, cmSourceFile.cxx: ENH:
- Add support for adding object files and sources. This way you can
- use external program such as assembler or fortran to generate
- object files. Also star of fixing: Bug #757 - add .o file as a
- source file
-
-2004-04-16 14:55 martink
-
- * Source/cmCTest.cxx: better args handling for -I options
-
-2004-04-16 14:52 martink
-
- * Source/: cmCTest.cxx, cmCTest.h: better args handling for -I
- option
-
-2004-04-16 13:36 andy
-
- * Source/cmCTest.cxx: ENH: Better reporting of what tests failed
- and write a file with failed tests
-
-2004-04-16 09:50 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: fix for bug 91
-
-2004-04-15 16:11 andy
-
- * Source/CursesDialog/cmCursesStringWidget.cxx: ENH: Add support
- for HOME and END keys. Also fix Bug #666 - In CCMake when
- deleting something, it does not stop at the beginning of line
-
-2004-04-15 15:46 andy
-
- * Source/CursesDialog/cmCursesMainForm.cxx: BUG: Prevent deleting
- not existing variables and therefore prevent crash. Fixes: Bug
- #750 - CCMake crashes when deleting all variables
-
-2004-04-15 13:59 andy
-
- * Tests/: Complex/CMakeLists.txt, Complex/Executable/complex.cxx,
- Complex/Library/CMakeLists.txt, Complex/Library/file2.cxx,
- ComplexOneConfig/CMakeLists.txt,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexOneConfig/Library/CMakeLists.txt,
- ComplexOneConfig/Library/file2.cxx,
- ComplexRelativePaths/CMakeLists.txt,
- ComplexRelativePaths/Executable/complex.cxx,
- ComplexRelativePaths/Library/CMakeLists.txt,
- ComplexRelativePaths/Library/file2.cxx: ENH: Add test for
- REMOVE_DEFINITION
-
-2004-04-15 13:58 andy
-
- * Source/: cmCommands.cxx, cmMakefile.cxx, cmMakefile.h,
- cmRemoveDefinitionsCommand.cxx, cmRemoveDefinitionsCommand.h:
- ENH: ADD REMOVE_DEFINITION command. Fix feature request: Bug #182
- - Add opposite to ADD_DEFINITIONS
-
-2004-04-15 13:15 hoffman
-
- * Source/cmOptionCommand.cxx: BUG: fix for 282
-
-2004-04-15 13:09 andy
-
- * Source/cmGlobalVisualStudio6Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Templates/CMakeLists.txt: ENH: Handle make install target on
- Visual Studio 6 and 7 and install templates
-
-2004-04-15 12:07 andy
-
- * Source/: cmLocalUnixMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator.h: ENH: Ok, that is it. Remove old
- install and replace it with new
-
-2004-04-15 11:55 hoffman
-
- * Modules/FindMFC.cmake: BUG: fix for bug 506
-
-2004-04-15 11:38 hoffman
-
- * Source/cmSiteNameCommand.cxx: BUG: fix for bug 689
-
-2004-04-15 08:22 hoffman
-
- * Modules/: CheckForPthreads.c, CheckFunctionExists.c,
- CheckTypeSize.c, CheckVariableExists.c, TestBigEndian.c: ENH: fix
- tests for non-ansi c on hp and remove warnings for ansi c
-
-2004-04-14 17:02 hoffman
-
- * Modules/FindITK.cmake: BUG: fix for bug 608
-
-2004-04-14 16:58 hoffman
-
- * Source/cmGlobalVisualStudio7Generator.cxx: BUG: fix external
- projects for vc7
-
-2004-04-14 15:56 hoffman
-
- * Modules/: CheckFunctionExists.c, TestBigEndian.c: ENH: remove
- warnings from try compiles
-
-2004-04-14 14:25 king
-
- * Source/: cmDocumentation.cxx, cmDocumentation.h: ENH: Renamed
- --help-list-commands to --help-command-list and split --help
- [command] into separate --help and --help-command cmd options.
-
-2004-04-14 13:40 king
-
- * Source/: cmDocumentation.cxx, cmDocumentation.h: ENH: Added
- --help-list-commands option.
-
-2004-04-14 08:55 hoffman
-
- * Source/cmCTest.cxx: ENH: remove warning
-
-2004-04-13 18:27 hoffman
-
- * Source/cmCTest.cxx: ENH: fix warning
-
-2004-04-13 16:32 hoffman
-
- * Source/: cmCTest.cxx, cmCTest.h, ctest.cxx: ENH: add the ability
- to run a limited sub-set of the tests
-
-2004-04-12 21:01 hoffman
-
- * Modules/FindGTK.cmake: BUG: fix for bug 593
-
-2004-04-09 09:53 andy
-
- * Source/cmCTest.cxx: BUG: Display string not some weird pointer
-
-2004-04-09 08:37 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: add full path
- libraries to the depend information
-
-2004-04-08 17:13 andy
-
- * Modules/MacOSXBundleInfo.plist.in,
- Source/cmAddExecutableCommand.cxx,
- Source/cmAddExecutableCommand.h: ENH: Improve Mac OSX bundle
- support
-
-2004-04-07 12:07 martink
-
- * Source/cmLocalVisualStudio7Generator.cxx: fix problem with custom
- command
-
-2004-04-07 09:58 hoffman
-
- * Source/cmTarget.cxx: ENH: remove warnings on sgi
-
-2004-04-05 10:35 king
-
- * DartConfig.cmake: ERR: Need to use latest testing configuration
- even on branch.
-
-2004-04-02 13:21 king
-
- * Source/cmTarget.cxx: BUG: _LINK_TYPE cache variable should never
- be switched from optimized to debug or vice versa.
-
-2004-04-02 09:43 hoffman
-
- * Source/CMakeLists.txt, Tests/Jump/Library/Shared/CMakeLists.txt:
- ENH: fix for apple
-
-2004-04-02 08:09 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: fix warning and
- shadow variable
-
-2004-04-01 16:07 martink
-
- * Source/cmCTest.cxx: fix for missing valid images
-
-2004-04-01 15:28 king
-
- * Source/kwsys/ProcessFwd9x.c: ENH: Added comment for future work
- to make forwarding executable always statically linked.
-
-2004-04-01 14:37 andy
-
- * Source/cmCTest.cxx: BUG: Fix bug on windows. You cannot cout
- std::string directly
-
-2004-04-01 14:11 andy
-
- * Source/: cmCTest.cxx, CTest/cmCTestSubmit.cxx,
- CTest/cmCTestSubmit.h: ENH: Add logging of submitting
-
-2004-04-01 09:59 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: fix non relative
- paths
-
-2004-04-01 08:59 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: fix for non
- relative paths with spaces in the path
-
-2004-03-31 16:44 king
-
- * Modules/FindTclsh.cmake: ENH: Added registry check for
- ActiveState Tcl 8.4.6.
-
-2004-03-31 11:26 andy
-
- * Source/cmCTest.cxx: ENH: Reduce number of
- GetCurrentWorkingDirectory
-
-2004-03-31 11:24 andy
-
- * Source/cmCTest.cxx: ENH: Change to the new directory
-
-2004-03-31 10:01 hoffman
-
- * Source/: CMakeLists.txt, cmLocalGenerator.cxx,
- cmLocalUnixMakefileGenerator.cxx, cmLocalUnixMakefileGenerator.h,
- cmake.cxx: ENH: make relative paths optional and default off, and
- add a test for them
-
-2004-03-29 12:51 king
-
- * Source/cmConfigureFileCommand.cxx: BUG#485: Fixing on CMake 1.8
- branch.
-
-2004-03-29 12:04 king
-
- * Source/: cmSystemTools.h, cmTryCompileCommand.cxx: BUG#679:
- Merging fix to CMake 1.8 branch.
-
-2004-03-28 17:59 andy
-
- * Source/: cmFileCommand.cxx, cmLocalGenerator.cxx: ENH: When
- installing project, write manifest
-
-2004-03-28 16:36 andy
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: Add a way to clean
- additional files
-
-2004-03-28 16:00 andy
-
- * Source/: cmConfigureFileCommand.cxx, cmConfigureFileCommand.h,
- cmMakefile.cxx: ENH: If configure file fails do not create
- directory
-
-2004-03-28 10:14 andy
-
- * Source/cmIncludeCommand.cxx: ERR: Remove debug
-
-2004-03-28 10:14 andy
-
- * Source/cmLocalGenerator.cxx: BUG: Support paths with spaces
-
-2004-03-28 09:46 andy
-
- * Source/: cmIncludeCommand.h, cmSetTargetPropertiesCommand.h: DOC:
- Fix comment
-
-2004-03-27 20:59 andy
-
- * Source/cmLocalGenerator.cxx,
- Source/cmSetTargetPropertiesCommand.h,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstall/PostInstall.cmake,
- Tests/SimpleInstall/PreInstall.cmake,
- Tests/SimpleInstallS2/CMakeLists.txt,
- Tests/SimpleInstallS2/PostInstall.cmake,
- Tests/SimpleInstallS2/PreInstall.cmake: ENH: Add pre and post
- install script support
-
-2004-03-27 19:52 andy
-
- * Source/cmIncludeCommand.cxx, Source/cmIncludeCommand.h,
- Tests/LoadCommand/CMakeLists.txt,
- Tests/LoadCommandOneConfig/CMakeLists.txt: ENH: Add support for
- importing modules without specifying path
-
-2004-03-27 19:52 andy
-
- * Source/cmFindPackageCommand.cxx: ERR: That slash is unnecessary
-
-2004-03-27 13:20 starreveld
-
- * Modules/FindOpenGL.cmake: ERR: Shouldn't be adding xlibs to
- opengllibs on osx
-
-2004-03-25 16:06 martink
-
- * Source/cmCTest.cxx: coverage change that will probably end in an
- infinite loop
-
-2004-03-25 08:45 king
-
- * Source/: cmLinkLibrariesCommand.h,
- cmTargetLinkLibrariesCommand.h: ENH: Clarified documentation for
- LINK_LIBRARIES and TARGET_LINK_LIBRARIES.
-
-2004-03-24 16:31 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: Added support to
- library flags parser for -Wl and -R options.
-
-2004-03-23 15:02 king
-
- * Modules/Platform/Windows-cl.cmake: ERR: Fixed incorrect
- documentation for CMAKE_CXX_WARNING_LEVEL. Submitted by David
- Cole.
-
-2004-03-20 20:37 andy
-
- * Source/cmCTest.cxx: ENH: Fix warning
-
-2004-03-19 14:48 king
-
- * Source/cmTryCompileCommand.cxx: ENH: Clarified recursive
- TRY_COMPILE error message.
-
-2004-03-19 09:34 andy
-
- * Source/cmCTest.cxx: ERR: Fix warnings about wrong format
-
-2004-03-18 09:52 andy
-
- * Source/cmCTest.cxx: ERR: Fix build on broken C++ compiles with no
- != operator for std::string
-
-2004-03-17 11:30 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: BUG: change directory before
- running test and remember test number
-
-2004-03-17 09:42 berk
-
- * Source/: cmSystemTools.h, cmTryCompileCommand.cxx: BUG: When
- error occurs, try compiles should still work
-
-2004-03-17 08:20 andy
-
- * Source/cmCTest.h: ERR: On some compilers structure inside class
- cannot reference private typdefs from the same class
-
-2004-03-16 12:54 king
-
- * Source/cmExportLibraryDependencies.cxx: ERR: Added missing
- include for auto_ptr.
-
-2004-03-15 14:54 andy
-
- * Source/kwsys/CMakeLists.txt: ENH: Always include KWSys header
- files directory
-
-2004-03-15 10:44 king
-
- * Source/cmExportLibraryDependencies.cxx: BUG#675: If not
- appending, do copy-if-different on exported file.
-
-2004-03-15 09:35 andy
-
- * Source/cmCTest.h: ERR: Fix build
-
-2004-03-14 12:28 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: ENH: Add support for future tags
-
-2004-03-14 11:23 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: ENH: Count tests while they go.
- Also in the logs report more stuff like elapsed time etc.
-
-2004-03-12 14:43 king
-
- * Source/kwsys/ProcessUNIX.c: ERR: SIGSEGV == SIGBUS on BeOS.
-
-2004-03-10 14:33 hoffman
-
- * Source/: cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio71Generator.h: ENH: update vs71 generator to
- support excluded subdirs
-
-2004-03-09 16:28 hoffman
-
- * Source/CMakeLists.txt, Source/cmEnableTestingCommand.cxx,
- Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmGlobalVisualStudio6Generator.cxx,
- Source/cmGlobalVisualStudio6Generator.h,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.h,
- Source/cmLocalGenerator.cxx, Source/cmLocalGenerator.h,
- Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.h, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmSubdirCommand.cxx,
- Source/cmSubdirCommand.h, Tests/SubDir/Executable/test.cxx: ENH:
- add new subdirectory exclude from top option
-
-2004-03-09 16:20 hoffman
-
- * Tests/SubDir/: CMakeLists.txt, Examples/CMakeLists.txt,
- Examples/example1/CMakeLists.txt, Examples/example1/example1.cxx,
- Examples/example2/CMakeLists.txt, Examples/example2/example2.cxx,
- Executable/CMakeLists.txt, Executable/test.cxx: ENH: create new
- test to test subdir exclude
-
-2004-03-09 12:31 andy
-
- * Source/cmLocalVisualStudio7Generator.cxx: ENH: Properly build
- WIN32 executables
-
-2004-03-09 07:50 andy
-
- * Source/: cmMakefile.cxx, cmMakefile.h: ENH: Try to remove warning
-
-2004-03-08 22:24 andy
-
- * Source/cmInstallTargetsCommand.h: ENH: Add comment about
- RUNTIME_DIRECTORY
-
-2004-03-08 19:05 andy
-
- * Source/: cmConfigureFileCommand.cxx, cmMakefile.cxx,
- cmMakefile.h: ENH: Move implementation of configure_file to
- cmMakefile, so that other classes can use it
-
-2004-03-04 10:05 king
-
- * Source/cmStringCommand.cxx, Source/cmStringCommand.h,
- Tests/StringFileTest/CMakeLists.txt,
- Tests/StringFileTest/InputFile.h.in: ENH: Added STRING(CONFIGURE
- ...) command.
-
-2004-03-03 18:18 king
-
- * Source/: cmConfigureFileCommand.cxx, cmMakefile.cxx,
- cmMakefile.h: ENH: Moved variable and #cmakedefine replacement
- from cmConfigureFileCommand.cxx to a ConfigureString method on
- cmMakefile. This will give other commands access to the
- configuration code.
-
-2004-02-29 15:13 andy
-
- * Tests/COnly/CMakeLists.txt: ERR: Too much commits
-
-2004-02-29 15:13 andy
-
- * Source/cmMakefile.cxx, Tests/COnly/CMakeLists.txt: ERR: Fix
- GetModulesFile
-
-2004-02-29 14:23 andy
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: Handle backticks as
- a valid library
-
-2004-02-29 09:53 andy
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ERR: Cleanup and remove
- warning
-
-2004-02-29 09:51 andy
-
- * Source/cmLocalCodeWarriorGenerator.cxx: ERR: Fix build on Mac
-
-2004-02-28 18:59 andy
-
- * Modules/MacOSXBundleInfo.plist.in,
- Source/cmAddExecutableCommand.cxx, Source/cmCPluginAPI.cxx,
- Source/cmFindPackageCommand.cxx, Source/cmLocalGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmTarget.h: ENH: Styart working on
- bundles support and abstract WIN32_EXECUTABLE
-
-2004-02-24 18:48 andy
-
- * Source/cmSystemTools.cxx: ERR: Fix crash. We should check output
- before appending to it
-
-2004-02-24 10:05 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: BUG: CVS update fix. If the CVS
- command was not set there was no indication that something went
- wrong. Now it will make sure it does. Also start working on
- multiple configuration scripts
-
-2004-02-24 10:04 andy
-
- * Source/cmSystemTools.cxx: ENH: Put Process execution errors in
- output and honor verbosity
-
-2004-02-23 09:56 andy
-
- * Source/: cmCTest.cxx, cmLocalGenerator.cxx: ENH: Improve coverage
- support and add more verbosity
-
-2004-02-23 09:54 king
-
- * Source/kwsys/Directory.cxx: ERR: Merging 1.7->1.9 changes to
- CMake 1.8 branch.
-
-2004-02-22 22:07 andy
-
- * Source/: cmCMakeMinimumRequired.h, cmConfigureFileCommand.h,
- cmElseCommand.h, cmEndIfCommand.h, cmExecProgramCommand.h,
- cmFindFileCommand.h, cmFindLibraryCommand.h, cmFindPathCommand.h,
- cmFindProgramCommand.h, cmGetFilenameComponentCommand.h,
- cmMakeDirectoryCommand.h, cmRemoveCommand.h,
- cmSeparateArgumentsCommand.h, cmWriteFileCommand.h: ENH: Make
- more commands scriptable
-
-2004-02-22 22:06 andy
-
- * Source/CursesDialog/cmCursesMainForm.cxx: BUG: Prevent crash when
- deleting the last cache item
-
-2004-02-22 13:14 andy
-
- * Source/: cmCPluginAPI.cxx, cmFLTKWrapUICommand.cxx,
- cmGetCMakePropertyCommand.cxx,
- cmGetSourceFilePropertyCommand.cxx, cmLoadCacheCommand.h,
- cmOutputRequiredFilesCommand.h, cmQTWrapCPPCommand.h,
- cmQTWrapUICommand.h, cmSetSourceFilesPropertiesCommand.cxx,
- cmSourceFilesCommand.cxx, cmUseMangledMesaCommand.h,
- cmVTKMakeInstantiatorCommand.cxx, cmVTKWrapJavaCommand.h,
- cmVTKWrapPythonCommand.h, cmVTKWrapTclCommand.h,
- cmWrapExcludeFilesCommand.cxx: ENH: Cleanups
-
-2004-02-20 14:46 andy
-
- * Source/cmake.cxx, Source/cmakemain.cxx,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: Ok, when doing cmake
- -P you should not have to squish filename next to -P, There
- should be space between
-
-2004-02-20 09:25 andy
-
- * Source/cmCTest.cxx: ENH: Handle wrong library on sun and no
- project on visual studio 7
-
-2004-02-19 10:33 andy
-
- * Source/CMakeLists.txt: ENH: Comment out test
-
-2004-02-19 10:32 andy
-
- * CMakeLists.txt, Source/CMakeLists.txt: ENH: Cleanup
-
-2004-02-19 10:29 andy
-
- * Source/cmIfCommand.h: ENH: Make IF command scriptable
-
-2004-02-19 10:28 king
-
- * Docs/cmake-mode.el: BUG: Fixed identification of ( and ) tokens
- to avoid finding them in string literals.
-
-2004-02-19 09:35 andy
-
- * Source/cmMacroCommand.h: ENH: Macro should be scriptable
-
-2004-02-19 09:35 andy
-
- * Source/cmCTest.cxx: ERR: Do not exit when find bad custom files.
-
-2004-02-17 08:35 hoffman
-
- * Source/cmDynamicLoader.cxx: BUG: don't crash when loading a
- module that does not exist
-
-2004-02-16 10:48 hoffman
-
- * Source/: cmConfigure.cmake.h.in, cmDynamicLoader.cxx: ENH: use
- cmake variables for cmDynamicLoader to figure out library prefix
- and extensions
-
-2004-02-16 09:50 hoffman
-
- * Modules/Platform/Windows-gcc.cmake, Source/cmDynamicLoader.cxx:
- BUG: fix mingw module load tests
-
-2004-02-14 16:55 hoffman
-
- * Modules/Platform/Windows-gcc.cmake: shared modules are not linked
- so do not use lib prefix
-
-2004-02-13 10:51 hoffman
-
- * Modules/Platform/Windows-gcc.cmake, Source/kwsys/SystemTools.cxx:
- ENH: change mingw to use libfoo.dll instead of foo.dll since it
- can link to them
-
-2004-02-12 21:44 andy
-
- * Source/cmFileCommand.cxx: ENH: Add DESTDIR support
-
-2004-02-12 13:38 king
-
- * Source/kwsys/Directory.cxx: ERR: Fixed use of _findfirst for MSVC
- 6.
-
-2004-02-12 11:23 martink
-
- * Source/kwsys/Directory.cxx: fix incorrect signature for findfirst
-
-2004-02-12 09:13 hoffman
-
- * Source/kwsys/SystemTools.cxx, Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: Fix install test fail on
- mingw
-
-2004-02-12 08:58 andy
-
- * Source/kwsys/SystemTools.cxx: BUG: Like cygwin, mingw does not
- produce .lib file for shared libraries, so search for dll when
- searching for library
-
-2004-02-11 10:56 andy
-
- * Source/cmCTest.cxx: ERR: Remove warning
-
-2004-02-11 08:28 andy
-
- * Source/kwsys/SystemTools.cxx, Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: On Cygwin shared
- libraries have only .dll file no .lib file, so when finding
- library on cygwin, search also for .dll. Also fix SimpleInstall
- test on cygwin
-
-2004-02-10 15:53 andy
-
- * Source/cmCTest.cxx: ERR: Use filepath followed by filename not
- another filepath
-
-2004-02-10 15:51 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: ENH: Add logging of tests while
- running. This way you can actually see the output as it goes
-
-2004-02-09 16:40 andy
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ENH: Some cleanup and try to fix
- Visual Studio builds
-
-2004-02-09 15:34 andy
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: -l or whatever
- should be at beginning of line.
-
-2004-02-09 11:33 andy
-
- * Source/CMakeLists.txt, Tests/SimpleInstall/inst.cxx,
- Tests/SimpleInstallS2/inst.cxx: ENH: Some systems do not handle
- spaces in the path
-
-2004-02-08 20:08 andy
-
- * Source/CMakeLists.txt, Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: Install stage2 to
- handle runtime problem
-
-2004-02-08 13:23 andy
-
- * Source/cmCTest.cxx: ENH: Attempt to support tests in funky
- subdirectories
-
-2004-02-08 12:04 andy
-
- * Source/CMakeLists.txt, Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: Add second part of
- SimpleInstall
-
-2004-02-06 16:43 king
-
- * Source/cmGlob.cxx: BUG#480: Merging 1.10->1.11 changes to 1.8
- branch.
-
-2004-02-06 15:26 andy
-
- * Source/cmGlob.cxx: ENH: When nor specifying full path, make sure
- it actually works, on broken filesystems fix case of files.
-
-2004-02-06 15:18 andy
-
- * Source/cmFileCommand.cxx: ENH: Handle script mode
-
-2004-02-06 13:47 andy
-
- * Source/: cmEndForEachCommand.h, cmForEachCommand.h,
- cmStringCommand.h: ENH: Make more commands scriptable
-
-2004-02-06 10:49 andy
-
- * Modules/FindJNI.cmake: ENH: Better finding of JNI
-
-2004-02-05 10:12 andy
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ERR: Fix test on windows with
- network paths
-
-2004-02-04 09:42 berk
-
- * Tests/: SimpleInstall/foo.c, SimpleInstall/foo.h,
- SimpleInstall/inst.cxx, SimpleInstallS2/foo.c,
- SimpleInstallS2/foo.h, SimpleInstallS2/inst.cxx: ENH: Fix test on
- HP-UX
-
-2004-02-03 11:23 andy
-
- * Source/cmFileCommand.cxx: ENH: Fix support for debug postfix
-
-2004-02-03 10:53 andy
-
- * Source/: cmFileCommand.cxx, cmLocalGenerator.cxx, cmSetCommand.h:
- ENH: Add support for install postfix
-
-2004-02-03 10:25 andy
-
- * Source/cmLocalGenerator.cxx: ENH: Cleanup output
-
-2004-02-03 09:26 andy
-
- * Source/cmLocalUnixMakefileGenerator.cxx,
- Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstallS2/CMakeLists.txt: ENH: Fix ADD_DEPENDENCIES
- on Unix makefiles and fix SimpleInstall test not to link the
- module
-
-2004-02-02 18:23 andy
-
- * Tests/: SimpleInstall/CMakeLists.txt,
- SimpleInstallS2/CMakeLists.txt: ENH: Make test work on windows
-
-2004-02-02 18:23 andy
-
- * Source/cmCTest.cxx: ENH: Propagate build type
-
-2004-02-01 16:48 andy
-
- * Tests/: SimpleInstall/lib2.h, SimpleInstall/lib3.h,
- SimpleInstallS2/lib2.h, SimpleInstallS2/lib3.h: ENH: Fix exports
-
-2004-02-01 12:53 andy
-
- * Source/CMakeLists.txt, Tests/SimpleInstall/CMakeLists.txt,
- Tests/SimpleInstall/foo.c, Tests/SimpleInstall/foo.h,
- Tests/SimpleInstall/inst.cxx, Tests/SimpleInstall/lib1.cxx,
- Tests/SimpleInstall/lib1.h, Tests/SimpleInstall/lib2.cxx,
- Tests/SimpleInstall/lib2.h, Tests/SimpleInstall/lib3.cxx,
- Tests/SimpleInstall/lib3.h, Tests/SimpleInstallS2/CMakeLists.txt,
- Tests/SimpleInstallS2/foo.c, Tests/SimpleInstallS2/foo.h,
- Tests/SimpleInstallS2/inst.cxx, Tests/SimpleInstallS2/lib1.cxx,
- Tests/SimpleInstallS2/lib1.h, Tests/SimpleInstallS2/lib2.cxx,
- Tests/SimpleInstallS2/lib2.h, Tests/SimpleInstallS2/lib3.cxx,
- Tests/SimpleInstallS2/lib3.h: ENH: Add install test
-
-2004-01-29 10:29 hoffman
-
- * Source/cmCTest.cxx: BUG: keep output
-
-2004-01-29 09:01 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: remove depend on
- CMakeCache for rebuild_cache target to avoid double rebuild cache
-
-2004-01-28 13:17 hoffman
-
- * Source/cmCTest.cxx: BUG: After running builtin ctest, go back to
- the original directory
-
-2004-01-28 11:22 andy
-
- * Source/cmLocalGenerator.cxx: ERR: Remove cout
-
-2004-01-28 10:59 king
-
- * Source/kwsys/ProcessWin32.c: BUG: Corrected detection of
- exceptional exit code.
-
-2004-01-28 10:59 king
-
- * Source/kwsys/testProcess.c: ENH: Added exception string to
- abnormal termination report.
-
-2004-01-28 09:47 martink
-
- * Source/cmCTest.cxx: Including exception string in test's error
- output.
-
-2004-01-28 08:11 andy
-
- * Source/cmFileCommand.cxx: ERR: Remove warning about unused
- variable
-
-2004-01-27 17:12 hoffman
-
- * Source/cmaketest.cxx: remove old file
-
-2004-01-27 17:12 hoffman
-
- * Source/cmCTest.cxx: ENH: add a dynamic loader flush cache
-
-2004-01-27 17:11 andy
-
- * Source/cmCTest.cxx: ENH: Only display the precontext or
- postcontext up to the next or previous warning or error
-
-2004-01-27 14:51 hoffman
-
- * Source/cmSystemTools.cxx: BUG: fix FMM
-
-2004-01-27 12:37 andy
-
- * Source/: cmFileCommand.cxx, cmInstallTargetsCommand.cxx,
- cmLocalGenerator.cxx, cmLocalGenerator.h, cmTarget.h: ENH: Make
- install on windows seems to work now
-
-2004-01-27 09:53 andy
-
- * Source/cmFileCommand.cxx: ERR: Fix build on Mingw. Looks like
- Mingw is more like visual studio... Thanks Fred Wheeler
-
-2004-01-27 09:42 martink
-
- * Source/cmCTest.cxx: fix for backup restore
-
-2004-01-27 09:05 andy
-
- * Source/cmFileCommand.cxx: ERR: And yet another set of constants
- for file permissions
-
-2004-01-27 09:05 andy
-
- * Source/: cmStandardIncludes.h, cmSystemTools.h: ERR: Properly
- handle mode_t on borland
-
-2004-01-26 17:52 andy
-
- * Source/cmStandardIncludes.h: ERR Fix borland
-
-2004-01-26 16:29 andy
-
- * Source/cmLocalGenerator.cxx: BUG: Fix for spaces in path
-
-2004-01-26 16:24 andy
-
- * Source/: cmFileCommand.cxx, cmLocalGenerator.cxx: ENH: Several
- windows bugs and fixes
-
-2004-01-26 16:05 andy
-
- * Source/: cmFileCommand.cxx, cmFileCommand.h: ENH: Add unix style
- install in file command
-
-2004-01-26 15:50 andy
-
- * Source/: cmConfigureFileCommand.cxx, cmSystemTools.cxx,
- cmSystemTools.h: ENH: Preserve permissions when copying files
-
-2004-01-26 15:03 andy
-
- * Source/: cmStandardIncludes.h, cmSystemTools.cxx: ERR: Fix build
- problems on Visual Studio 6
-
-2004-01-26 14:55 andy
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Add code for
- setting and getting permissions
-
-2004-01-26 14:41 andy
-
- * Source/: cmCTest.cxx, cmSystemTools.cxx: ENH: Improve calling of
- RunSingle command and fix compile error
-
-2004-01-26 14:00 hoffman
-
- * Source/cmSystemTools.cxx: ENH: forgot return value
-
-2004-01-26 13:57 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: ENH: Add support for
- CTestCustom.ctest, which modifies some behavior of ctest
-
-2004-01-26 13:32 hoffman
-
- * Source/: cmCTest.cxx, cmGlobalGenerator.cxx, cmSystemTools.cxx,
- cmSystemTools.h, cmake.cxx, cmake.h: BUG: fix put/get env
- problems
-
-2004-01-26 13:32 hoffman
-
- * Source/kwsys/ProcessWin32.c: ENH: fix for build on cygwin mingw
-
-2004-01-25 19:30 andy
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h: ERR: Fix std::
- namespace
-
-2004-01-25 19:25 andy
-
- * Source/: cmGlobalGenerator.cxx, cmLocalGenerator.cxx,
- cmLocalGenerator.h: ENH: Start adding new installation framework
-
-2004-01-24 12:52 king
-
- * Tests/Jump/Executable/CMakeLists.txt: BUG: Due to backward
- ordering, Visual Studio GUIs need the link directories for the
- libraries the first time.
-
-2004-01-23 15:17 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: .lib from a .dll
- should go in m_LibraryOutputPath not m_ExecutableOutputPath
-
-2004-01-23 13:43 hoffman
-
- * Tests/Jump/Library/Shared/CMakeLists.txt: BUG: libdir was set
- wrong on windows
-
-2004-01-23 13:43 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: jump over feature
- was not working for windows
-
-2004-01-23 13:19 andy
-
- * DartConfig.cmake: ENH: Fix url
-
-2004-01-23 13:01 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: fix for debug
- flags into project files
-
-2004-01-23 13:01 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: more fixes for
- relative path stuff
-
-2004-01-23 12:46 andy
-
- * DartConfig.cmake: ENH: Add nightly reporting
-
-2004-01-23 12:40 hoffman
-
- * Modules/CMakeDetermineCCompiler.cmake: ENH: use CFLAGS for
- testing for gnu
-
-2004-01-23 11:26 andy
-
- * DartConfig.cmake: ENH: More continuous e-mail stuff
-
-2004-01-23 11:22 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: convert the .o
- files to not have ./
-
-2004-01-23 09:54 king
-
- * Source/: cmLocalGenerator.cxx, cmLocalUnixMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator.h: BUG: Fix to build rule generation
- with relative paths.
-
-2004-01-23 09:48 king
-
- * DartConfig.cmake: ENH: Improving CMake continuous dashboards.
- Sending continuous email for all kinds of failures.
-
-2004-01-23 09:44 martink
-
- * Source/: cmCTest.cxx, cmCTest.h: fixes to backup restore options
-
-2004-01-23 08:53 king
-
- * Source/cmLocalGenerator.cxx: STYLE: Deleted trailing whitespace.
-
-2004-01-23 08:51 king
-
- * Source/CMakeLists.txt: ERR: Fixed project name for Jump tests.
-
-2004-01-22 14:44 king
-
- * Source/kwsys/: Process.h.in, ProcessUNIX.c: ERR: Fixed function
- prototypes with zero arguments to be C-style.
-
-2004-01-22 11:16 andy
-
- * Source/kwsys/ProcessUNIX.c: BUG: If working directory does not
- exists, exit
-
-2004-01-22 11:10 andy
-
- * Source/cmCTest.cxx: BUG: If at least one test fails, the percent
- cannot be greater than 99
-
-2004-01-22 10:54 king
-
- * Source/: cmLocalUnixMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator.h: BUG: Fix jump-over-and-build for
- missing libraries when the relative path to the library is
- different between the source and destination of the jump.
-
-2004-01-22 10:51 king
-
- * Tests/Jump/Library/: CMakeLists.txt, jumpShared.cxx,
- jumpStatic.cxx, Shared/CMakeLists.txt, Shared/jumpShared.cxx,
- Static/CMakeLists.txt, Static/jumpStatic.cxx: ENH: Improved test
- to have a different relative path name for libraries between the
- Executable and Library directories.
-
-2004-01-22 10:36 king
-
- * Source/CMakeLists.txt: ENH: Added JumpWithLibOut and JumpNoLibOut
- to test whether jumping over to build a missing library works.
-
-2004-01-22 10:30 king
-
- * Source/: cmake.cxx, kwsys/SystemTools.cxx: BUG:
- CopyFileIfDifferent should return success if the files did not
- differ or if the copy succeeded. It should return failure only
- if the files were different and the copy failed.
-
-2004-01-22 10:23 king
-
- * Tests/Jump/Library/CMakeLists.txt: ERR: Fixed post-build rule to
- copy shared library correctly.
-
-2004-01-22 09:56 king
-
- * Tests/Jump/: CMakeLists.txt, Executable/CMakeLists.txt,
- Executable/jumpExecutable.cxx, Library/CMakeLists.txt,
- Library/jumpShared.cxx, Library/jumpStatic.cxx: ENH: Adding test
- for jumping over and building a missing library.
-
-2004-01-21 18:39 andy
-
- * Modules/CMakeDefaultMakeRuleVariables.cmake: ENH: This will
- probably break some obscure version of gcc, but until then,
- everybody doing profiling will be happy
-
-2004-01-21 15:55 king
-
- * Source/cmSystemTools.cxx: BUG: ::Stdout method should flush cout
- after writing data.
-
-2004-01-21 15:12 king
-
- * Modules/CMakeTestCCompiler.cmake: BUG#530: Merging 1.9 -> 1.10
- changes to CMake 1.8 branch.
-
-2004-01-21 15:11 king
-
- * Modules/CMakeTestCCompiler.cmake: BUG#530: Using #error to report
- a nice error message if the C compiler is set to a C++ compiler.
-
-2004-01-21 15:08 king
-
- * Modules/TestBigEndian.c: BUG: Use return statement instead of
- exit.
-
-2004-01-21 15:07 martink
-
- * Source/kwsys/ProcessUNIX.c: merge from the main tree
-
-2004-01-21 14:43 king
-
- * Source/cmCTest.cxx: BUG: empty method on std string is a test,
- and does not set the string to empty.
-
-2004-01-21 14:27 hoffman
-
- * Source/cmCTest.cxx: BUG: fix leak
-
-2004-01-21 14:06 king
-
- * Source/cmCTest.cxx: BUG: Fixed buffer size in MakeXMLSafe.
-
-2004-01-21 13:38 andy
-
- * Source/kwsys/ProcessUNIX.c: BUG: Fix valgrind error. If working
- directory is not set do not do chdir
-
-2004-01-21 09:49 hoffman
-
- * Source/cmCTest.cxx: BUG: if a test is not found, it should fail
-
-2004-01-21 09:25 hoffman
-
- * Source/cmCTest.cxx: ENH: make sure tests that are not run fail,
- and make sure that it does not try to run directories with the
- same name as tests
-
-2004-01-20 14:36 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: bug fix for IBM
- broken xlC 6.0.0.4 compiler
-
-2004-01-20 14:35 hoffman
-
- * Source/cmSystemTools.cxx: ENH: dont do relative paths when
- nothing is relative
-
-2004-01-19 09:30 king
-
- * Source/kwsys/testProcess.c: ERR: Fixed unused argument warning.
-
-2004-01-19 09:30 king
-
- * Source/kwsys/CMakeLists.txt: ERR: Must include Dart module after
- PROJECT command.
-
-2004-01-17 12:47 king
-
- * Source/kwsys/CMakeLists.txt: ENH: Added Dart testing
- configuration.
-
-2004-01-17 12:46 king
-
- * Source/kwsys/testProcess.c: ENH: Added a recursive process
- execution test.
-
-2004-01-16 14:00 martink
-
- * Source/cmCTest.cxx: fix so that ctest is run even with bad cmake
- result
-
-2004-01-15 17:07 andy
-
- * Source/cmCTest.cxx: ENH: Handle spaces in the dart output of test
-
-2004-01-15 14:04 king
-
- * Modules/Platform/Windows-bcc32.cmake: BUG#518: Merging 1.30->1.31
- changes to CMake 1.8 branch.
-
-2004-01-15 13:57 andy
-
- * Modules/Platform/Windows-bcc32.cmake: ENH: Fix typos about
- copying exe flags to shared flags and to modules. Bug #518 - On
- borland, initial flags for bulding module are wrong
-
-2004-01-15 08:50 king
-
- * Source/cmSystemTools.cxx: ENH: Added more error state checks to
- RunSingleCommand.
-
-2004-01-13 12:28 andy
-
- * Source/cmCTest.cxx: ERR: Do not ignore argument after nocmake
-
-2004-01-13 11:22 hoffman
-
- * Source/: cmCTest.cxx, cmCTest.h: ENH: add no cmake option
-
-2004-01-13 09:05 king
-
- * Modules/CMakeDetermineCCompiler.cmake: BUG: Merging 1.23->1.25
- changes to 1.8 branch for correct setting of MINGW flag on cygwin
- with -mno-cygwin flag.
-
-2004-01-13 09:01 king
-
- * Modules/FindTclsh.cmake: Merging 1.6->1.7 changes to 1.8 branch
- to improve automatic finding of Tcl.
-
-2004-01-13 09:01 king
-
- * Modules/FindTCL.cmake: Merging 1.30->1.31 changes to 1.8 branch
- to improve automatic finding of Tcl.
-
-2004-01-13 09:00 hoffman
-
- * Modules/CMakeDetermineCCompiler.cmake: BUG: use the flags when
- testing for type of gnu compiler
-
-2004-01-12 16:16 hoffman
-
- * Source/kwsys/SystemTools.cxx: BUG: try to get access to work on
- borland
-
-2004-01-12 13:53 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: use access over stat for
- performance
-
-2004-01-12 13:30 andy
-
- * Source/: cmCTest.cxx, kwsys/SystemTools.cxx: ENH: Only look for
- executable until found
-
-2004-01-09 15:57 barre
-
- * Modules/: FindTCL.cmake, FindTclsh.cmake: ENH: make it a bit
- smarter at finding stuff: now you need only to set *ONE* of
- (TCL|TK)_INCLUDE_PATH, (TCL|TK)_LIBRARY, TCL_TCLSH and the rest
- will be found.
-
-2004-01-09 14:14 hoffman
-
- * Source/cmCTest.cxx: ENH: clean up the output some more
-
-2004-01-09 14:05 hoffman
-
- * Source/cmCTest.cxx: ENH: clean up output
-
-2004-01-09 13:35 hoffman
-
- * Source/: cmCTest.cxx, cmCTest.h: ENH: add an ability to specify a
- build run directory
-
-2004-01-09 12:35 hoffman
-
- * Source/cmCTest.cxx: ENH: clean up output
-
-2004-01-09 12:28 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: add a local target
- for libraries as well as executables
-
-2004-01-09 11:23 king
-
- * CMakeLists.txt, Modules/CMakeDetermineSystem.cmake,
- Modules/CMakeFindFrameworks.cmake,
- Modules/CMakeTestCCompiler.cmake,
- Modules/CMakeTestCXXCompiler.cmake, Modules/Dart.cmake,
- Modules/FindOpenGL.cmake, Modules/FindPythonLibs.cmake,
- Modules/FindQt.cmake, Modules/FindTCL.cmake,
- Modules/Platform/Windows-cl.cmake, Source/cmCTest.cxx,
- Source/cmCreateTestSourceList.cxx,
- Source/cmGlobalCodeWarriorGenerator.cxx,
- Source/cmGlobalGenerator.cxx,
- Source/cmGlobalVisualStudio6Generator.cxx,
- Source/cmGlobalVisualStudio71Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmLinkLibrariesCommand.cxx,
- Source/cmLocalCodeWarriorGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmOptionCommand.cxx, Source/cmQTWrapCPPCommand.cxx,
- Source/cmSiteNameCommand.cxx, Source/cmStringCommand.cxx,
- Source/cmTarget.cxx, Source/cmTargetLinkLibrariesCommand.cxx,
- Source/cmTryCompileCommand.cxx, Source/cmTryCompileCommand.h,
- Source/kwsys/SystemTools.cxx, Utilities/Release/cmake_release.sh,
- Utilities/Release/config_Linux,
- Utilities/Release/cygwin-package.sh.in: ENH: Merged Release-1-8-2
- -> Release-1-8-3 changes to CMake-LatestRelease branch.
-
-2004-01-09 10:13 king
-
- * Source/cmCTest.cxx: BUG: Updated warning regex to match in more
- cases.
-
-2004-01-09 08:54 hoffman
-
- * Source/cmCTest.cxx: BUG: if the build fails then the test fails
-
-2004-01-09 07:22 hoffman
-
- * Source/CMakeLists.txt: BUG: fix arguments to wxwindows test
-
-2004-01-08 09:59 hoffman
-
- * Source/: cmCTest.cxx, cmGlobalGenerator.cxx, cmake.cxx: BUG: make
- sure null terminator is in the right place for putenv static char
- array
-
-2004-01-08 09:23 king
-
- * Source/cmake.cxx: BUG: Fix environment variable setting.
-
-2004-01-08 09:19 king
-
- * Source/cmGlobalGenerator.cxx: BUG: Fix environment variable
- setting.
-
-2004-01-08 08:19 hoffman
-
- * Source/: cmCTest.cxx: ENH: remove warning
-
-2004-01-07 16:24 hoffman
-
- * Source/cmCTest.cxx: temp remove of optimization internal ctest
- use putenv causing trouble on cygwin
-
-2004-01-07 16:15 hoffman
-
- * Source/cmCTest.cxx: ENH: print errors when they are there
-
-2004-01-07 14:22 hoffman
-
- * Source/cmCTest.cxx: BUG: initialize ivar
-
-2004-01-07 13:27 martink
-
- * Source/cmCreateTestSourceList.cxx: merge fix from main tree
-
-2004-01-07 13:20 hoffman
-
- * Source/cmCTest.cxx: BUG: fix command line parser bug
-
-2004-01-07 12:50 hoffman
-
- * Source/cmCTest.cxx: ENH: remove warning
-
-2004-01-07 11:31 hoffman
-
- * Source/cmCTest.cxx: ENH: remove warnings
-
-2004-01-07 11:24 hoffman
-
- * Source/: CMakeLists.txt, cmCTest.cxx, cmCTest.h,
- cmSystemTools.cxx, cmSystemTools.h, cmWin32ProcessExecution.cxx,
- cmake.cxx, ctest.cxx: ENH: add new feature to ctest so that it
- can cmake, build and run a test executable
-
-2004-01-07 09:22 king
-
- * Source/cmGlobalVisualStudio6Generator.cxx: BUG: Fixed crash in
- extern MSVC project support.
-
-2004-01-07 09:22 hoffman
-
- * Source/cmGlobalVisualStudio6Generator.cxx: BUG: fix crash in
- external dsp include
-
-2004-01-07 09:10 king
-
- * Source/cmGlobalVisualStudio6Generator.cxx: BUG: Fixed crash in
- extern MSVC project support.
-
-2004-01-07 09:08 hoffman
-
- * Source/cmGlobalVisualStudio6Generator.cxx: BUG: fix crash
-
-2004-01-07 09:07 king
-
- * Source/cmCTest.cxx: BUG: Added missing Generator attributes to
- submitted XML files.
-
-2004-01-07 08:37 martink
-
- * Modules/Dart.cmake: merge change from main tree
-
-2004-01-06 19:13 andy
-
- * Source/: cmCTest.cxx, cmCTest.h, ctest.cxx: ENH: Improve notes
- support (now you can specify them with the rest of the command
- line), improve reading of configuration file (now it actually
- rereads configuration file after running
- update/configure/build...). Remember the model
- (nightly/experimental) across runs
-
-2004-01-06 16:56 king
-
- * Source/kwsys/: kwsys_std.h.in, kwsys_std_fstream.h.in,
- kwsys_std_iosfwd.h.in, kwsys_std_iostream.h.in,
- kwsys_std_sstream.h.in: ENH: Removing empty source file now that
- makefile dependencies should have updated.
-
-2004-01-06 16:18 hoffman
-
- * Source/: cmLocalGenerator.cxx, cmLocalUnixMakefileGenerator.cxx:
- ENH: fix for hp make and relative paths never have targets with a
- ./ at the start of the name
-
-2004-01-06 15:06 king
-
- * Utilities/Release/config_Linux: Fixed build for new machine.
-
-2004-01-06 13:21 king
-
- * Utilities/Release/config_Linux: ENH: Updated configuration for
- new build location.
-
-2004-01-05 16:29 martink
-
- * Source/cmGlob.cxx: fix for glob command
-
-2004-01-05 15:30 king
-
- * Source/cmFindPackageCommand.cxx: BUG: Fixed typo in error
- message.
-
-2004-01-05 13:20 king
-
- * Utilities/Release/cmake_release.sh: ENH: Updated TAG for 1.8.3
- release.
-
-2004-01-05 13:19 king
-
- * CMakeLists.txt, CMakeSystemConfig.txt.in,
- CMakeWindowsSystemConfig.txt, bootstrap,
- Modules/CMakeCCompiler.cmake.in,
- Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Modules/CMakeDetermineJavaCompiler.cmake,
- Modules/CMakeImportBuildSettings.cmake, Modules/CMakeLists.txt,
- Modules/CMakeSystemSpecificInformation.cmake,
- Modules/CMakeTestCCompiler.cmake,
- Modules/CMakeTestCXXCompiler.cmake, Modules/CMakeTestGNU.c,
- Modules/CheckTypeSize.cmake, Modules/CheckVariableExists.cmake,
- Modules/Dart.cmake, Modules/FindGTK.cmake, Modules/FindJNI.cmake,
- Modules/FindJava.cmake, Modules/FindLATEX.cmake,
- Modules/FindPythonLibs.cmake, Modules/FindTCL.cmake,
- Modules/FindTclsh.cmake, Modules/FindThreads.cmake,
- Modules/FindWish.cmake, Modules/FindwxWindows.cmake,
- Modules/TestForANSIForScope.cmake,
- Modules/TestForSTDNamespace.cmake, Modules/Platform/AIX.cmake,
- Modules/Platform/BSDOS.cmake, Modules/Platform/Darwin.cmake,
- Modules/Platform/FreeBSD.cmake, Modules/Platform/HP-UX.cmake,
- Modules/Platform/IRIX.cmake, Modules/Platform/IRIX64.cmake,
- Modules/Platform/MP-RAS.cmake, Modules/Platform/NetBSD.cmake,
- Modules/Platform/OSF1.cmake, Modules/Platform/OpenBSD.cmake,
- Modules/Platform/RISCos.cmake, Modules/Platform/SCO_SV.cmake,
- Modules/Platform/SINIX.cmake, Modules/Platform/SunOS.cmake,
- Modules/Platform/True64.cmake, Modules/Platform/ULTRIX.cmake,
- Modules/Platform/UNIX_SV.cmake, Modules/Platform/UnixWare.cmake,
- Modules/Platform/Windows-bcc32.cmake,
- Modules/Platform/Windows-cl.cmake,
- Modules/Platform/Windows-gcc.cmake,
- Modules/Platform/Windows.cmake, Modules/Platform/Xenix.cmake,
- Modules/Platform/gcc.cmake, Source/CMakeLists.txt,
- Source/cmAddCustomTargetCommand.cxx, Source/cmAddTestCommand.cxx,
- Source/cmCPluginAPI.h, Source/cmCTest.cxx, Source/cmCTest.h,
- Source/cmCacheManager.cxx, Source/cmCommands.cxx,
- Source/cmDynamicLoader.cxx, Source/cmFindFileCommand.h,
- Source/cmFindLibraryCommand.h, Source/cmFindPathCommand.h,
- Source/cmFindProgramCommand.h,
- Source/cmGlobalBorlandMakefileGenerator.cxx,
- Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmGlobalNMakeMakefileGenerator.cxx,
- Source/cmGlobalUnixMakefileGenerator.cxx,
- Source/cmGlobalVisualStudio6Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmLoadCommandCommand.cxx,
- Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.h,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmMakeDepend.cxx, Source/cmMakefile.cxx,
- Source/cmQTWrapCPPCommand.cxx, Source/cmSystemTools.cxx,
- Source/cmSystemTools.h, Source/cmTargetLinkLibrariesCommand.cxx,
- Source/cmTryCompileCommand.h, Source/cmWin32ProcessExecution.cxx,
- Source/cmake.cxx, Source/cmakemain.cxx, Source/cmakewizard.cxx,
- Source/cmakewizard.h, Source/CTest/cmCTestSubmit.cxx,
- Source/CursesDialog/ccmake.cxx, Source/kwsys/ProcessUNIX.c,
- Source/kwsys/ProcessWin32.c, Source/kwsys/SystemTools.cxx,
- Templates/EXEWinHeader.dsptemplate,
- Tests/Complex/Executable/CMakeLists.txt,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/complex.cxx,
- Tests/Complex/Library/CMakeLists.txt,
- Tests/ComplexOneConfig/Library/CMakeLists.txt,
- Tests/ComplexRelativePaths/Library/CMakeLists.txt,
- Utilities/CMakeLists.txt, Utilities/Release/cmake_release.sh,
- Utilities/Release/config_AIX,
- Utilities/Release/config_CYGWIN_NT-5.1,
- Utilities/Release/config_Darwin, Utilities/Release/config_HP-UX,
- Utilities/Release/config_IRIX64, Utilities/Release/config_Linux,
- Utilities/Release/config_OSF1, Utilities/Release/config_SunOS,
- Utilities/Release/cygwin-package.sh.in: ENH: Merging CMake
- Release-1-8-2 to CMake-LatestRelease.
-
-2004-01-05 12:58 king
-
- * Source/cmLocalVisualStudio6Generator.cxx: BUG#416: Merging
- 1.49->1.50 changes to 1.8 branch.
-
-2004-01-05 12:53 martink
-
- * Source/cmLocalVisualStudio6Generator.cxx: fix for long lines with
- post build rules
-
-2004-01-05 11:22 king
-
- * Source/cmQTWrapCPPCommand.cxx: BUG#421: Merging 1.16->1.17
- changes to 1.8 branch.
-
-2004-01-05 11:13 andy
-
- * Source/cmQTWrapCPPCommand.cxx, Tests/Wrapping/CMakeLists.txt,
- Tests/Wrapping/vtkTestMoc.h: BUG: Fix dependency to input file
- for QT_WRAP_CPP. Bug #421 - QT_WRAP_CPP
-
-2004-01-05 11:02 king
-
- * Source/kwsys/kwsysPlatformCxxTests.cmake: ERR: Removed use of
- FILE command and using WRITE_FILE instead. We would still like
- CMake 1.6 to be able to build CMake CVS, and kwsys is used.
-
-2004-01-02 10:23 martink
-
- * Modules/Dart.cmake: fix for multiple nexted projects
-
-2003-12-31 08:56 andy
-
- * bootstrap: ERR: Fix bootstrap for the changes in kwsys
-
-2003-12-30 17:15 king
-
- * Source/kwsys/: CMakeLists.txt, Configure.hxx.in,
- kwsysPlatformCxxTests.cxx, kwsys_ios_fstream.h.in,
- kwsys_ios_iosfwd.h.in, kwsys_ios_iostream.h.in,
- kwsys_ios_sstream.h.in: ENH: Renamed KWSYS_IOS_HAVE_* macros to
- KWSYS_IOS_USE_* to be more readable in the C++ sources.
-
-2003-12-30 16:23 king
-
- * Source/kwsys/: Process.h.in, ProcessUNIX.c, ProcessWin32.c,
- test1.cxx: ENH: Added GetExceptionString method to provide an
- error description when GetState returns Exception.
-
-2003-12-30 14:33 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: Removed stray
- debugging statement left from merge.
-
-2003-12-30 13:40 king
-
- * Source/kwsys/SystemTools.cxx: ERR: Use of kwsys_stl was merged
- from main tree. The CMake 1.8 branch still uses kwsys_std.
-
-2003-12-30 13:39 king
-
- * Source/kwsys/SystemTools.cxx: BUG: Merging 1.30->1.31 changes to
- CMake 1.8 branch.
-
-2003-12-30 13:38 king
-
- * Source/kwsys/SystemTools.cxx: BUG: CollapseFullPath was calling
- SplitProgramPath before changing the working directory to
- in_base.
-
-2003-12-30 10:26 king
-
- * Source/cmSystemTools.cxx: BUG: Do not call
- cmsysProcess_GetErrorString unless GetState returns State_Error.
-
-2003-12-30 08:41 hoffman
-
- * Source/: cmLocalGenerator.cxx, cmLocalUnixMakefileGenerator.cxx:
- BUG: borland make treats ./target and target as different also
- convert to outputpathrelative may get passed a quoted path
-
-2003-12-30 07:55 andy
-
- * Source/cmCTest.cxx: ENH: Remove warnings about unused variables
-
-2003-12-29 16:35 martink
-
- * Source/cmEnableTestingCommand.h: sets variable now
-
-2003-12-29 16:27 martink
-
- * Source/cmLocalUnixMakefileGenerator.cxx: only generate test
- target when enabled
-
-2003-12-29 16:27 martink
-
- * Source/cmEnableTestingCommand.cxx: sets variable now
-
-2003-12-29 16:19 king
-
- * Modules/: CMakeFindFrameworks.cmake, FindPythonLibs.cmake,
- FindTCL.cmake: BUG#423: Merged fix to 1.8 branch.
-
-2003-12-29 16:18 king
-
- * Modules/: CMakeFindFrameworks.cmake, FindPythonLibs.cmake,
- FindTCL.cmake: BUG#423: Fixed search for frameworks on OSX.
-
-2003-12-29 16:15 king
-
- * Source/cmSiteNameCommand.cxx: BUG#407: Merged fix to 1.8 branch.
-
-2003-12-29 16:10 andy
-
- * Source/cmSiteNameCommand.cxx: ENH: Do not use nslookup. All we
- really care is hostname. If somebody wants something fancy, just
- set it yourself. Fixes Bug #407 - nslookup is being deprecated
- for Red Hat and Fedora distributions
-
-2003-12-29 15:37 king
-
- * Source/cmOptionCommand.cxx: BUG#408: Merged fix to 1.8 branch.
-
-2003-12-29 15:26 andy
-
- * Source/cmOptionCommand.cxx: ERR: Fix problems with OPTION and -D
- on command line. Fix Bug #408 - Using -D without a type does not
- always work
-
-2003-12-29 15:15 king
-
- * Modules/CMakeDetermineSystem.cmake: BUG#426: Merged fix to 1.8
- branch.
-
-2003-12-29 15:14 king
-
- * Modules/FindQt.cmake: BUG#425: Merged fix to 1.8 branch.
-
-2003-12-29 14:55 hoffman
-
- * Source/: cmLocalGenerator.cxx, cmLocalUnixMakefileGenerator.cxx:
- BUG: use ./ infront of the current directory
-
-2003-12-29 14:26 andy
-
- * Modules/CMakeDetermineSystem.cmake: ERR: On systems where uname
- does not support -p, try -m. Fixes Bug #426 -
- CMAKE_SYSTEM_PROCESSOR unknown and inconsistent
-
-2003-12-29 14:19 andy
-
- * Modules/FindQt.cmake: ENH: Add QT_ASSISTANTCLIENT_LIBRARY
- support. Fixes Bug #425 - Suggsted mod to FindQt.cmake to handle
- qassistantclient.lib
-
-2003-12-29 13:41 king
-
- * Source/cmGlobalGenerator.cxx: BUG#427: Merged fix to 1.8 branch.
-
-2003-12-29 13:37 king
-
- * Source/: cmGlobalCodeWarriorGenerator.cxx,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx, cmLinkLibrariesCommand.cxx,
- cmLocalCodeWarriorGenerator.cxx,
- cmLocalUnixMakefileGenerator.cxx,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx, cmTarget.cxx,
- cmTargetLinkLibrariesCommand.cxx: BUG#445: Merging fix to 1.8
- branch.
-
-2003-12-29 13:32 king
-
- * Source/cmStringCommand.cxx: BUG#452: Merging 1.10->1.11 changes
- to 1.8 branch.
-
-2003-12-29 13:31 king
-
- * Source/cmStringCommand.cxx: BUG#452: Fix to argument checking for
- TOUPPER and TOLOWER subcommands.
-
-2003-12-29 13:26 king
-
- * Modules/FindOpenGL.cmake: BUG: Added missing include path to
- search.
-
-2003-12-29 13:14 king
-
- * Source/kwsys/SystemTools.cxx: ERR: Removed ftime ambiguity
- created by poor C++ standard headers provided by Borland 5.5.
-
-2003-12-26 15:02 andy
-
- * Source/: cmCTest.cxx, cmCTest.h, ctest.cxx: ENH: Add option to
- submit notes. Implements Bug #465 - Add notes support to CTest
-
-2003-12-26 15:00 andy
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: BUG: For
- consistency, use cmStdString. Also, there was a bug in
- SplitString which make it lose the first character.
-
-2003-12-24 15:02 andy
-
- * Source/cmLocalGenerator.cxx: BUG: On Windows network paths do not
- really work as regular paths, so when the binary directory is on
- the network, we will not support relative paths
-
-2003-12-24 13:17 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: use cd pwd trick
- for path for libnames
-
-2003-12-24 10:51 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: use full paths via
- pwd for -L paths on unix shells
-
-2003-12-24 10:07 kmorel
-
- * Source/kwsys/kwsys_ios_iosfwd.h.in: Fixed a problem where
- ifstream was not the same as kwsys_ios::ifstream on MSVC 6.0.
-
-2003-12-24 09:19 andy
-
- * Source/cmCTest.cxx: ENH: Fix coverage to actually work and add
- support for .NoDartCoverage
-
-2003-12-23 15:01 hoffman
-
- * Source/: cmLocalGenerator.cxx, cmTryCompileCommand.cxx,
- cmake.cxx, cmake.h: BUG: keep more of the case information
-
-2003-12-23 13:31 hoffman
-
- * Source/cmLocalGenerator.cxx: BUG: fix for vtk build
-
-2003-12-23 11:03 king
-
- * bootstrap: ENH: Merging changes from KWSys-IOS-bp to
- KWSys-IOS-b2t-1-mp to main tree. This corresponds to the same
- merge in KWSys. Fixes for bootstrapping on cygwin are also
- included.
-
-2003-12-23 11:03 king
-
- * Source/kwsys/: CMakeLists.txt, Configure.hxx.in, Directory.cxx,
- RegularExpression.cxx, RegularExpression.hxx.in, SystemTools.cxx,
- SystemTools.hxx.in, kwsysPlatformCxxTests.cmake,
- kwsysPlatformCxxTests.cxx, kwsys_ios_fstream.h.in,
- kwsys_ios_iosfwd.h.in, kwsys_ios_iostream.h.in,
- kwsys_ios_sstream.h.in, kwsys_std.h.in, kwsys_std_fstream.h.in,
- kwsys_std_iosfwd.h.in, kwsys_std_iostream.h.in,
- kwsys_std_sstream.h.in, kwsys_stl.h.in, test1.cxx, testIOS.cxx:
- ENH: Merging changes from KWSys-IOS-bp to KWSys-IOS-b2t-1-mp to
- main tree. This introduces separate kwsys_ios and kwsys_stl
- macros needed to support all platforms.
-
-2003-12-23 10:44 king
-
- * bootstrap: BUG: Fixed 3rd C++ test to use endl correctly. Fixed
- incorrect spelling of appropriate.
-
-2003-12-23 10:39 andy
-
- * bootstrap: ENH: Some cleanups and attempt to fix cygwin problem
-
-2003-12-23 10:16 andy
-
- * bootstrap: ENH: Some cleanups, add settings comment to kwsys
- header files. Add proper dependency to kwsys headers
-
-2003-12-23 09:53 king
-
- * bootstrap: BUG: Fixed use of KWSYS_IOS_HAVE_SSTREAM test result
- for cmConfigure.
-
-2003-12-23 09:31 king
-
- * bootstrap: BUG: Moved use of KWSYS_IOS test results to after the
- tests are performed. Also cleaned up ordering of some tests.
-
-2003-12-23 09:17 andy
-
- * bootstrap: ENH: support new KWSYS with IOS
-
-2003-12-22 16:21 hoffman
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx, cmSystemTools.cxx: ENH: add
- relative paths to visual studio 6 and 7 project files
-
-2003-12-22 15:16 hoffman
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h,
- cmLocalUnixMakefileGenerator.cxx, cmLocalUnixMakefileGenerator.h:
- ENH: move relative path to parent generator class
-
-2003-12-22 14:17 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: make new relative
- rpath work with spaces
-
-2003-12-22 13:59 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: use fullpaths based
- on the actual current directory
-
-2003-12-22 13:15 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: use a full path for
- rpath
-
-2003-12-22 12:24 hoffman
-
- * Source/: cmLocalUnixMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator.h, cmSystemTools.cxx,
- cmSystemTools.h, cmake.cxx: ENH: add support for relative paths
- in makefiles
-
-2003-12-22 11:20 king
-
- * Source/kwsys/: CMakeLists.txt, kwsysPlatformCxxTests.cxx: ENH:
- All platform tests are now in kwsysPlatformCxxTests.cxx. This
- makes the listfile code much more readable.
-
-2003-12-20 13:32 king
-
- * Source/kwsys/: CMakeLists.txt, testIOS.cxx: ENH: Added testIOS
- for kwsys_ios testing.
-
-2003-12-20 13:31 king
-
- * Source/kwsys/kwsys_ios_sstream.h.in: ERR: Fixed istringstream to
- work with MSVC 6 old streams.
-
-2003-12-20 12:44 king
-
- * Source/kwsys/: CMakeLists.txt, Configure.hxx.in,
- kwsysPlatformCxxTests.cxx, kwsys_ios_fstream.h.in,
- kwsys_ios_iosfwd.h.in, kwsys_ios_iostream.h.in,
- kwsys_ios_sstream.h.in: ENH: Shortened and grouped IOS and STL
- feature macro names.
-
-2003-12-19 16:56 king
-
- * Source/kwsys/: CMakeLists.txt, Configure.hxx.in, Directory.cxx,
- RegularExpression.cxx, RegularExpression.hxx.in, SystemTools.cxx,
- SystemTools.hxx.in, kwsysPlatformCxxTests.cmake,
- kwsysPlatformCxxTests.cxx, kwsys_ios_fstream.h.in,
- kwsys_ios_iosfwd.h.in, kwsys_ios_iostream.h.in,
- kwsys_ios_sstream.h.in, kwsys_std.h.in, kwsys_std_fstream.h.in,
- kwsys_std_iosfwd.h.in, kwsys_std_iostream.h.in,
- kwsys_std_sstream.h.in, kwsys_stl.h.in, test1.cxx: ENH: Split
- kwsys_std into kwsys_ios and kwsys_stl in order to avoid std
- namespace pollution and support more platforms.
-
-2003-12-18 18:04 andy
-
- * Source/cmCTest.cxx: ENH: Even better. Only replace when path
- longer than 20 characters. Also replace parent directory. That
- way it will replace for related projects.
-
-2003-12-18 17:42 andy
-
- * Source/cmCTest.cxx: ENH: Attempt to cleanup the build output
-
-2003-12-18 17:36 martink
-
- * Source/cmCTest.cxx: bug fix
-
-2003-12-18 13:40 andy
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ERR: Remove debug
-
-2003-12-18 13:17 andy
-
- * Source/: cmGlobalCodeWarriorGenerator.cxx,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx,
- cmLocalCodeWarriorGenerator.cxx,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: BUG: Fix Bug #445 - Same
- library in multiple projects can cause problems
-
-2003-12-18 13:04 andy
-
- * Source/: cmLinkLibrariesCommand.cxx,
- cmLocalUnixMakefileGenerator.cxx, cmTarget.cxx,
- cmTargetLinkLibrariesCommand.cxx: BUG: Fix Bug #445 - Same
- library in multiple projects can cause problems
-
-2003-12-17 09:42 andy
-
- * Modules/Dart.cmake: ENH: Mark things as advanced
-
-2003-12-17 09:40 andy
-
- * Source/cmCTest.cxx: ERR: Remove debug
-
-2003-12-17 09:25 andy
-
- * Source/cmCTest.cxx: ENH: Add more error regular expressions
-
-2003-12-17 08:49 king
-
- * Source/: cmTryCompileCommand.cxx, cmTryCompileCommand.h: BUG#439:
- Merging fix to 1.8 branch.
-
-2003-12-17 08:45 king
-
- * Modules/Platform/Windows-cl.cmake: BUG#438: Merging fix to 1.8
- branch.
-
-2003-12-17 08:36 martink
-
- * Source/cmCTest.cxx: better ctest driver and return codes
-
-2003-12-17 08:30 king
-
- * Source/kwsys/SystemTools.hxx.in: ERR: std -> kwsys_std.
-
-2003-12-17 08:21 martink
-
- * Modules/Platform/Windows-cl.cmake: fix in quoting
-
-2003-12-16 17:30 andy
-
- * Source/cmCTest.cxx: ENH: Purify support should work now.
-
-2003-12-16 17:20 king
-
- * Source/kwsys/: Process.h.in, ProcessUNIX.c, ProcessWin32.c: ENH:
- Added SetPipeShared method to allow stdout and stderr pipes to be
- shared with the parent process.
-
-2003-12-16 16:19 andy
-
- * Source/cmCTest.cxx: ENH: Add suppression file support for
- valgrind
-
-2003-12-16 16:19 andy
-
- * Modules/: Dart.cmake, DartConfiguration.tcl.in: ENH: Add
- suppression file
-
-2003-12-16 15:55 king
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH: Added
- GetEnv method.
-
-2003-12-16 15:38 king
-
- * Source/kwsys/CMakeLists.txt: ENH: Updated copyright.
-
-2003-12-16 15:37 king
-
- * Source/kwsys/CMakeLists.txt: ERR: SystemTools now depends on
- Directory.
-
-2003-12-16 14:43 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: ENH: Several cleanups and
- attempt to do purify support
-
-2003-12-16 14:26 martink
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: is there any
- chance thiswill work on all platforms hmmm added removeAdirectory
-
-2003-12-16 13:18 andy
-
- * Source/cmCTest.cxx: ENH: Cleanup output
-
-2003-12-15 18:44 andy
-
- * Source/cmCTest.cxx: ERR: Fix coverage on gcc 2.95
-
-2003-12-15 18:32 andy
-
- * Source/cmCTest.cxx: ERR: Ok, think before commit... This fixes
- two build problems. The missing brace and the std::string
- signature is different on gcc 2.95 and gcc 3.3.
-
-2003-12-15 18:03 andy
-
- * Source/cmCTest.cxx: ERR: Inner loop used the same counter as
- outer. Broke coverage code
-
-2003-12-15 17:28 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: ERR: STD fixes
-
-2003-12-15 17:25 andy
-
- * Modules/Dart.cmake, Modules/DartConfiguration.tcl.in,
- Source/cmCTest.cxx, Source/cmCTest.h, Source/cmSystemTools.cxx,
- Source/cmSystemTools.h, Source/ctest.cxx,
- Source/CTest/cmCTestSubmit.cxx, Source/CTest/cmCTestSubmit.h,
- Source/CursesDialog/cmCursesPathWidget.cxx: ENH: Add initial
- memory check support which works for Valgrind
-
-2003-12-15 16:30 king
-
- * Source/kwsys/: Base64.c, Base64.h.in, Configure.h.in,
- Configure.hxx.in, Copyright.txt, Directory.cxx, Directory.hxx.in,
- EncodeExecutable.c, Process.h.in, ProcessFwd9x.c, ProcessUNIX.c,
- ProcessWin32.c, RegularExpression.cxx, RegularExpression.hxx.in,
- SystemTools.cxx, SystemTools.hxx.in, kwsysHeaderDump.pl,
- kwsysPrivate.h, kwsys_std.h.in, kwsys_std_fstream.h.in,
- kwsys_std_iosfwd.h.in, kwsys_std_iostream.h.in,
- kwsys_std_sstream.h.in, test1.cxx, testProcess.c: ENH: Updated
- copyright.
-
-2003-12-15 12:56 martink
-
- * Source/cmCreateTestSourceList.cxx: fix compiler warning
-
-2003-12-15 12:02 hoffman
-
- * Source/cmCTest.cxx: ENH: fix for gcc 3.1
-
-2003-12-14 13:48 king
-
- * Source/kwsys/ProcessWin32.c: STYLE: Fixed typo on comment.
-
-2003-12-14 13:47 king
-
- * Source/kwsys/ProcessWin32.c: ENH: Using CreateFile with
- FILE_FLAG_DELETE_ON_CLOSE to automatically delete the Win9x
- forwarding executable even if the parent process crashes.
-
-2003-12-14 13:44 king
-
- * Source/kwsys/kwsysPrivate.h: ENH: Added KWSYS_NAMESPACE_STRING
- macro.
-
-2003-12-14 13:03 king
-
- * Source/kwsys/Configure.h.in: BUG: Fixed dllimport.
-
-2003-12-13 14:19 king
-
- * Source/kwsys/ProcessUNIX.c: ERR: Added include of sys/stat.h for
- open functions mode bits.
-
-2003-12-13 14:13 king
-
- * Source/kwsys/: Process.h.in, ProcessUNIX.c, ProcessWin32.c: ENH:
- Added SetPipeFile method to allow the process pipeline stdin,
- stdout, and stderr to be redirected from/to files.
-
-2003-12-13 10:36 king
-
- * Source/kwsys/: ProcessUNIX.c, ProcessWin32.c: ENH: Code is now
- robust to New method returning NULL.
-
-2003-12-12 15:42 king
-
- * Modules/Platform/IRIX64.cmake: ENH: Added
- CMAKE_SHARED_LIBRARY_SONAME_C_FLAG and
- CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG settings to enable shared
- library version support for SGI.
-
-2003-12-12 14:44 king
-
- * Modules/Platform/HP-UX.cmake: ENH: Added
- CMAKE_SHARED_LIBRARY_SONAME_FLAG setting to enable shared library
- version support for HP-UX.
-
-2003-12-12 14:34 king
-
- * Modules/CMakeDefaultMakeRuleVariables.cmake,
- Modules/Platform/SunOS.cmake,
- Source/cmLocalUnixMakefileGenerator.cxx,
- Modules/Platform/Linux.cmake: ENH: Using separate
- CMAKE_SHARED_LIBRARY_SONAME flags for C and CXX.
-
-2003-12-12 14:20 king
-
- * Modules/Platform/SunOS.cmake: ENH: Added
- CMAKE_SHARED_LIBRARY_SONAME_FLAG setting to enable shared library
- version support for SunOS.
-
-2003-12-12 09:12 hoffman
-
- * Modules/: CMakeCCompiler.cmake.in, CMakeCXXCompiler.cmake.in,
- CMakeDetermineCCompiler.cmake, CMakeDetermineCXXCompiler.cmake:
- ENH: reduce the number of times gnu is tested for
-
-2003-12-12 08:09 martink
-
- * Source/cmCTest.cxx: now can do extra updates
-
-2003-12-11 15:38 hoffman
-
- * Source/cmGlobalGenerator.cxx: BUG:427 trycompile target must be
- exe
-
-2003-12-11 10:11 hoffman
-
- * Source/cmTryCompileCommand.cxx: BUG: need a dummy first argument
- to cmake
-
-2003-12-11 08:57 martink
-
- * Source/: cmTryCompileCommand.cxx, cmTryCompileCommand.h: fix to
- the signature and argument parsing
-
-2003-12-10 19:47 andy
-
- * Source/: cmake.cxx, cmakemain.cxx: ENH: Argument for script mode
- is -P (process) and take out the automatic script mode
-
-2003-12-10 08:55 hoffman
-
- * Source/: cmLocalUnixMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator.h: BUG: roll back change for
- variable used in path
-
-2003-12-09 14:33 king
-
- * Modules/FindOpenGL.cmake: ENH: Adding /usr/include/w32api for
- OpenGL header search.
-
-2003-12-09 11:44 king
-
- * Source/kwsys/SystemTools.cxx: BUG: File comparison on windows
- must test the volume serial number as well as the file index.
-
-2003-12-09 10:33 martink
-
- * DartConfig.cmake: move start time up one hour
-
-2003-12-09 09:16 king
-
- * Source/: cmListFileLexer.c, cmListFileLexer.in.l: ERR: Removed
- YY_BREAK statements after return statements because they are
- unreachable.
-
-2003-12-09 09:11 king
-
- * Source/: cmListFileLexer.c, cmListFileLexer.in.l: ERR: Added
- missing static keyword to cmListFileLexerSetToken and
- cmListFileLexerAppend definitions.
-
-2003-12-09 08:32 hoffman
-
- * Source/: cmLocalUnixMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator.h: ENH: use variables for output
- paths
-
-2003-12-09 08:22 martink
-
- * Source/cmCTest.cxx: some updates to handle inline cache files and
- environment variables
-
-2003-12-08 18:05 king
-
- * Source/cmSystemTools.cxx: BUG: Reimplemented ExpandListArguments
- to properly handle escaped backslashes that occur right before
- semicolons. This is important for lists of paths ending in
- backslashes on windows.
-
-2003-12-08 16:10 martink
-
- * Source/cmSystemTools.cxx: bug fix to escaped semicolons in
- arguments
-
-2003-12-08 15:05 king
-
- * Source/cmListFileLexer.in.l: ERR: Fixed comment about how to run
- flex to reflect new name of this file.
-
-2003-12-08 14:20 king
-
- * Source/: cmListFileLexer.in.l, cmListFileLexer.l: ERR: Renaming
- cmListFileLexer.l to cmListFileLexer.in.l to avoid make programs
- trying to run lex automatically whn building cmListFileLexer.c.
-
-2003-12-08 14:11 andy
-
- * bootstrap: ENH: Fix bootstrap to handle lex parser
-
-2003-12-08 13:40 king
-
- * Source/: cmListFileLexer.c, cmListFileLexer.l: ERR: We must
- define YY_NO_UNISTD_H to build on windows.
-
-2003-12-08 13:36 king
-
- * Source/: CMakeLists.txt, cmListFileCache.cxx, cmListFileCache.h,
- cmListFileLexer.c, cmListFileLexer.h, cmListFileLexer.l: ENH:
- Using lex-based tokenizer and a simple recursive-descent parser
- in place of the old hand-coded parser for CMake listfiles.
-
-2003-12-08 11:35 king
-
- * Source/kwsys/CMakeLists.txt: STYLE: Removed trailing whitespace.
-
-2003-12-08 11:31 king
-
- * Source/cmake.cxx: ENH: Improved error messages when source tree
- does not have a CMakeLists.txt file. No matter how many cases we
- check, there always seems to be a user that finds a case that
- gives a confusing error message...
-
-2003-12-08 11:23 andy
-
- * Modules/Dart.cmake, Modules/DartConfiguration.tcl.in,
- Source/cmCTest.cxx: ENH: Improve coverage on systems with
- multiple gcov commands
-
-2003-12-07 14:09 king
-
- * Source/kwsys/: Process.h.in, ProcessUNIX.c, ProcessWin32.c: ENH:
- Cleaned up pipe numbering.
-
-2003-12-05 16:39 king
-
- * Source/cmCTest.cxx: ENH: Using cmListFileCache to read the
- DartTestfile instead of duplicating the parse loop.
-
-2003-12-05 14:51 king
-
- * Source/kwsys/kwsys_std.h.in: ERR: Need to include Configure.hxx
- to get kwsys_std definition.
-
-2003-12-05 11:53 king
-
- * Source/: cmCTest.cxx, cmSystemTools.cxx, kwsys/Process.h.in,
- kwsys/ProcessUNIX.c, kwsys/ProcessWin32.c, kwsys/test1.cxx,
- kwsys/testProcess.c: ENH: Removed pipe selection argument from
- WaitForData method in kwsysProcess. This greatly simplifies its
- use.
-
-2003-12-05 11:37 king
-
- * Source/kwsys/: Process.h.in, ProcessFwd9x.c, ProcessWin32.c:
- STYLE: Removed trailing whitespace.
-
-2003-12-05 11:19 king
-
- * Source/kwsys/ProcessWin32.c: BUG: Process startup-info struct
- dwFlags were being set incorrectly due to a change in statement
- order.
-
-2003-12-05 10:45 king
-
- * Docs/cmake-mode.el: ENH: New indentation implementation to
- support multi-line strings.
-
-2003-12-04 14:34 king
-
- * Docs/cmake-mode.el: STYLE: Removed trailing whitespace.
-
-2003-12-04 13:56 king
-
- * Source/kwsys/ProcessUNIX.c: ERR: Added missing static storage
- class specifier for kwsysProcessCreate.
-
-2003-12-03 14:16 martink
-
- * Source/cmCTest.cxx: some fixes to test harnes
-
-2003-12-03 13:37 king
-
- * Source/kwsys/ProcessUNIX.c: ERR: Some platforms define stdin,
- stdout, and stderr as macros. Renaming these symbols to StdIn,
- StdOut, and StdErr.
-
-2003-12-03 09:20 king
-
- * Source/kwsys/: Process.h.in, ProcessFwd9x.c, ProcessUNIX.c,
- ProcessWin32.c: ENH: Merged changes from KWSys-MultiProcess-bp to
- KWSys-MultiProcess-b2t-1-mp to main tree. This introduces
- support for process pipelines.
-
-2003-12-03 09:12 king
-
- * Source/kwsys/Process.h.in: ERR: Added missing macro definition
- for kwsysProcess_AddCommand.
-
-2003-12-02 17:23 king
-
- * Utilities/Release/cmake_release.sh: ENH: Added documentation
- about location of cmCPluginAPI.h in cygwin package.
-
-2003-12-02 17:16 king
-
- * Utilities/Release/cygwin-package.sh.in: BUG: No longer need to
- copy Copyright.txt into doc directory. It is done by the cmake
- installation.
-
-2003-12-02 17:14 king
-
- * Utilities/Release/cygwin-package.sh.in: BUG: Need to pass
- datadir/docdir/mandir to bootstrap script instead of writing in
- the cache.
-
-2003-12-02 16:57 king
-
- * Utilities/Release/cygwin-package.sh.in: ENH: Cygwin now uses
- /usr/share/doc instead of /usr/doc.
-
-2003-12-02 16:57 king
-
- * CMakeLists.txt, Utilities/Release/cmake_release.sh: ENH: Updating
- version number to 1.8.3.
-
-2003-12-02 16:50 martink
-
- * Source/cmCTest.cxx: better error handling
-
-2003-12-01 19:25 martink
-
- * Source/: cmCTest.cxx, cmCTest.h, ctest.cxx: a start on the
- dashboard driver
-
-2003-12-01 13:07 king
-
- * Modules/: CMakeTestCCompiler.cmake, CMakeTestCXXCompiler.cmake:
- BUG#411: Merged fix to 1.8 branch.
-
-2003-12-01 13:06 king
-
- * Modules/: CMakeTestCCompiler.cmake, CMakeTestCXXCompiler.cmake:
- BUG#411: Re-ordering statements so errors show up in
- CMakeError.log.
-
-2003-11-28 15:37 king
-
- * Source/kwsys/ProcessWin32.c: ENH: Cleaned up implementation of
- stderr and win9x forwarding executable error pipe.
-
-2003-11-28 14:21 king
-
- * Source/kwsys/ProcessWin32.c: ENH: Removing special termination
- pipe from Windows implementation. It does not need it because
- WaitForMultipleObjects can wait with a timeout for the process to
- terminate. This is not the case in UNIX because waitpid has no
- timeout, so we need the termination pipe there.
-
-2003-11-28 14:08 king
-
- * Source/kwsys/ProcessWin32.c: BUG: Removed stray debugging code
- that caused win9x mode to always be used.
-
-2003-11-28 14:02 king
-
- * Source/kwsys/ProcessWin32.c: ENH: Added special termination pipe
- to allow timeout to work for processes that close their output
- pipes.
-
-2003-11-28 13:07 king
-
- * Source/kwsys/ProcessWin32.c: ENH: Error messages from the
- forwarding executable are now read completely even if they are
- reported in multiple blocks.
-
-2003-11-28 12:58 king
-
- * Source/kwsys/ProcessWin32.c: BUG: Fixed error message when
- process control structure initialization runs out of memory.
-
-2003-11-28 12:52 king
-
- * Source/kwsys/ProcessWin32.c: ERR: Removed useless if(command) in
- AddString.
-
-2003-11-28 12:47 king
-
- * Source/kwsys/ProcessWin32.c: ENH: Renamed CMPE_* to KWSYSPE_* for
- consistency with ProcessUNIX.c.
-
-2003-11-28 12:42 king
-
- * Source/kwsys/ProcessUNIX.c: BUG: When a child fails to exec, we
- need to read the entire error message, not just the first block.
-
-2003-11-28 12:31 king
-
- * Source/kwsys/ProcessUNIX.c: ENH: UNIX implementation of process
- pipeline.
-
-2003-11-28 10:08 king
-
- * Source/kwsys/ProcessUNIX.c: ENH: Implemented SetCommand and
- AddCommand for multiple process support.
-
-2003-11-28 09:48 king
-
- * Source/kwsys/: ProcessUNIX.c: STYLE: Removed trailing whitespace.
-
-2003-11-27 23:08 king
-
- * Source/kwsys/: Process.h.in, ProcessFwd9x.c, ProcessWin32.c: ENH:
- Windows implementation of process pipeline.
-
-2003-11-27 10:28 king
-
- * Source/cmake.cxx: BUG: cmake_symlink_library should return the
- accumulated result, not just 0.
-
-2003-11-26 17:59 king
-
- * Modules/Platform/Linux.cmake: ENH: Adding implementation of
- shared library version support on UNIX. This addresses the
- feature request described in bug#32.
-
-2003-11-26 17:52 king
-
- * Modules/CMakeDefaultMakeRuleVariables.cmake: ENH: Adding
- implementation of shared library version support on UNIX. This
- addresses the feature request described in bug#32.
-
-2003-11-26 17:38 king
-
- * Source/: cmLocalUnixMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator.h: ENH: Adding implementation of
- shared library version support on UNIX. This addresses the
- feature request described in bug#32.
-
-2003-11-26 17:34 king
-
- * Source/cmake.cxx: BUG: The cmake_symlink_library command needs to
- remove existing files before creating links.
-
-2003-11-26 16:38 king
-
- * Source/cmake.cxx: ENH: Added undocumented cmake_symlink_library
- to help with building versioned shared libraries.
-
-2003-11-26 16:15 hoffman
-
- * Source/: cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx: remove more warnings
-
-2003-11-26 16:12 hoffman
-
- * Source/: cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio6Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h: remove warnings
-
-2003-11-26 16:11 king
-
- * Source/cmSystemTools.cxx: ERR: Fixed unused parameter warnings.
-
-2003-11-26 16:04 hoffman
-
- * Source/: cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio71Generator.h,
- cmGlobalVisualStudio7Generator.cxx: ENH: fix some warnings
-
-2003-11-26 14:52 king
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Added
- CreateSymlink method.
-
-2003-11-26 14:29 hoffman
-
- * Source/: cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio6Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h, cmMakefile.cxx, cmMakefile.h:
- ENH: generate a sln and dsw file for each sub project in a
- project
-
-2003-11-26 11:41 king
-
- * Source/: cmCTest.cxx, cmSystemTools.cxx: BUG: Do not use
- std::string to accumulate output. Use std::vector instead. This
- is much better at memory management.
-
-2003-11-25 16:14 king
-
- * Utilities/Release/cmake_release.sh: STYLE: Removed trailing
- whitepsace.
-
-2003-11-24 15:51 king
-
- * Utilities/Release/cmake_release.sh: BUG: osx_install should make
- the Resources directory before copying files into it.
-
-2003-11-24 14:04 king
-
- * Modules/FindPythonLibs.cmake: BUG#266: Merging 1.16->1.18 changes
- to 1.8 branch.
-
-2003-11-24 14:01 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG#393: Merging
- 1.40->1.41 changes to 1.8 branch.
-
-2003-11-21 14:13 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG#393: Adding XML
- escaping for additional per-source compile flags.
-
-2003-11-21 13:12 hoffman
-
- * Modules/FindPythonLibs.cmake: BUG: remove junk code
-
-2003-11-20 15:41 king
-
- * Modules/FindPythonLibs.cmake: BUG#266: Added cygwin names for the
- library. Module now documents output as PYTHON_LIBRARIES instead
- of PYTHON_LIBRARY.
-
-2003-11-20 15:31 king
-
- * Modules/FindPythonLibs.cmake: STYLE: Removed trailing whitespace.
-
-2003-11-20 15:30 king
-
- * Modules/Platform/: AIX.cmake, BSDOS.cmake, Darwin.cmake,
- FreeBSD.cmake, HP-UX.cmake, IRIX.cmake, IRIX64.cmake,
- MP-RAS.cmake, NetBSD.cmake, OSF1.cmake, OpenBSD.cmake,
- RISCos.cmake, SCO_SV.cmake, SINIX.cmake, SunOS.cmake,
- True64.cmake, ULTRIX.cmake, UNIX_SV.cmake, UnixWare.cmake,
- Windows-gcc.cmake, Xenix.cmake, gcc.cmake: BUG#383: Merged fix to
- 1.8 branch.
-
-2003-11-14 10:44 hoffman
-
- * Modules/Platform/: AIX.cmake, BSDOS.cmake, Darwin.cmake,
- FreeBSD.cmake, HP-UX.cmake, IRIX.cmake, IRIX64.cmake,
- MP-RAS.cmake, NetBSD.cmake, OSF1.cmake, OpenBSD.cmake,
- RISCos.cmake, SCO_SV.cmake, SINIX.cmake, SunOS.cmake,
- True64.cmake, ULTRIX.cmake, UNIX_SV.cmake, UnixWare.cmake,
- Windows-gcc.cmake, Xenix.cmake, gcc.cmake: BUG: fix for bug 383
- gcc flags are now always set if the compiler is gnu
-
-2003-11-13 15:54 king
-
- * Source/cmAddCustomTargetCommand.cxx: BUG#321: Merged 1.13->1.14
- changes to 1.8 branch.
-
-2003-11-13 14:45 martink
-
- * Source/cmAddCustomTargetCommand.cxx: fixed argument parsing
-
-2003-11-13 13:52 king
-
- * Source/: cmFindFileCommand.h, cmFindLibraryCommand.h,
- cmFindPathCommand.h, cmFindProgramCommand.h: ENH: Documentation
- improvements from main tree.
-
-2003-11-13 13:51 king
-
- * Source/: cmFindFileCommand.h, cmFindLibraryCommand.h,
- cmFindPathCommand.h, cmFindProgramCommand.h: ENH: Documentation
- improvements.
-
-2003-11-13 12:43 king
-
- * Modules/FindGTK.cmake: BUG#299: Merged 1.8->1.9 changes to 1.8
- branch.
-
-2003-11-12 17:44 king
-
- * Modules/FindGTK.cmake: BUG#299: GTK_gmodule_LIBRARY is optional
- just like GTK_gthread_LIBRARY.
-
-2003-11-12 16:53 king
-
- * Modules/TestForANSIForScope.cmake: BUG#374: Merging 1.10->1.11
- changes to 1.8 branch.
-
-2003-11-12 16:53 king
-
- * Modules/TestForSTDNamespace.cmake: BUG#374: Merging 1.9->1.10
- changes to 1.8 branch.
-
-2003-11-12 16:51 king
-
- * Modules/: TestForANSIForScope.cmake, TestForSTDNamespace.cmake:
- BUG#374: Adding OUTPUT_VARIABLE OUTPUT to TRY_COMPILE commands.
-
-2003-11-12 14:57 king
-
- * Source/cmMakeDepend.cxx: BUG#373: Merging 1.39->1.40 to 1.8
- branch.
-
-2003-11-12 14:20 hoffman
-
- * Source/cmMakeDepend.cxx: BUG: fix for bug 373 make depend problem
-
-2003-11-12 14:17 king
-
- * Source/cmGlobalVisualStudio6Generator.cxx: BUG#371: Merging
- 1.19->1.20 changes to 1.8 branch.
-
-2003-11-12 14:17 king
-
- * Source/cmGlobalVisualStudio7Generator.cxx: BUG#371: Merging
- 1.17->1.18 changes to 1.8 branch.
-
-2003-11-12 14:06 andy
-
- * Source/: cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx: ENH: Bug #371 - Add build
- configuration for try compiles using cmake variable
-
-2003-11-12 10:03 king
-
- * Modules/Dart.cmake: BUG#199: Merging 1.45->1.46 changes to 1.8
- branch.
-
-2003-11-12 10:00 king
-
- * Modules/Dart.cmake: BUG#199: If
- DART_EXPERIMENTAL_USE_PROJECT_NAME is set, the PROJECT_NAME will
- be included in the name of the Experimental and
- ExperimentalSubmit targets.
-
-2003-11-11 12:53 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG#363: Merged
- 1.39->1.40 changes to 1.8 branch.
-
-2003-11-11 12:51 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: fix for 363,
- VCMIDLTool not used for idl files
-
-2003-11-11 12:51 king
-
- * Source/cmCTest.cxx: BUG#344: Merged 1.66->1.67 to 1.8 branch.
-
-2003-11-11 12:36 andy
-
- * Source/cmCTest.cxx: BUG: Handle -C properly for executables that
- are not in the project; Fix Bug #344 - ctest -C Debug
-
-2003-11-11 11:42 king
-
- * Source/cmCTest.h: BUG#259: Merging 1.16->1.18 changes to 1.8
- branch.
-
-2003-11-11 11:42 king
-
- * Source/cmCTest.cxx: BUG#259: Merging 1.62->1.63 and 1.64->1.66
- changes to 1.8 branch.
-
-2003-11-11 11:41 king
-
- * Source/cmAddTestCommand.cxx: BUG#259: Merging 1.18->1.20 changes
- to 1.8 branch.
-
-2003-11-06 16:38 andy
-
- * Source/cmCTest.cxx: ENH: Add warning exception for VTK type
- warning blocking
-
-2003-11-05 15:02 andy
-
- * Utilities/Doxygen/doxyfile.in: ENH: Handle kwsys properly
-
-2003-11-05 15:02 andy
-
- * Utilities/Doxygen/CMakeLists.txt: ENH: Cleanup. We do not really
- need to use vtk for documentation. We only need utilities/doxygen
- directory
-
-2003-11-05 13:03 king
-
- * Modules/Platform/Windows-bcc32.cmake,
- Source/cmGlobalBorlandMakefileGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.cxx: BUG#346: Merging fix
- from main tree to 1.8 branch.
-
-2003-11-05 11:18 hoffman
-
- * Modules/Platform/Windows-bcc32.cmake,
- Source/cmGlobalBorlandMakefileGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.cxx: BUG: fix for bug 346,
- borland should now support dash in the path
-
-2003-11-05 10:46 king
-
- * Source/cmCTest.cxx: BUG#259: Fix for spaces in paths to
- executable added to previous fixes for this bug.
-
-2003-11-05 10:13 king
-
- * Modules/: FindTclsh.cmake, FindWish.cmake: BUG#322: Merging fix
- from main tree to 1.8 branch.
-
-2003-11-04 12:50 king
-
- * Source/cmCTest.cxx: BUG#323: Merging fix from main tree to 1.8
- branch.
-
-2003-11-04 11:19 hoffman
-
- * Source/cmCTest.cxx: BUG: fix for bug 323
-
-2003-11-04 09:45 king
-
- * Source/cmMakefile.cxx: BUG: Merging changes from revision 1.236
- to 1.237 to 1.8 branch.
-
-2003-11-04 09:44 king
-
- * Source/cmLocalVisualStudio6Generator.cxx: BUG: Merging changes
- from revisions 1.41 to 1.47 to 1.8 branch.
-
-2003-11-04 09:36 king
-
- * Modules/: FindTclsh.cmake, FindWish.cmake: ENH: Adding registry
- entries to search path.
-
-2003-11-04 09:06 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG#318: Merging fix
- from main tree to 1.8 branch.
-
-2003-11-04 09:03 king
-
- * Source/CTest/cmCTestSubmit.cxx: BUG#320: Merging fix from main
- tree to 1.8 branch.
-
-2003-11-04 09:01 king
-
- * Source/cmQTWrapCPPCommand.cxx: BUG#319: Merging fix from main
- tree (1.15->1.16) to 1.8 branch.
-
-2003-11-04 09:00 king
-
- * Source/kwsys/: ProcessWin32.c, RegularExpression.cxx: ERR:
- Removed extra variable assignments.
-
-2003-11-04 08:56 king
-
- * Source/kwsys/ProcessWin32.c: BUG: Removed CloseHandle in case of
- error in DuplicateHandle. According to documentation,
- DuplicateHandle will close the source handle regardless of error
- condition.
-
-2003-11-04 08:50 king
-
- * Source/cmAddTestCommand.cxx: BUG: Cannot add extra escapes for
- backslashes because it makes the behavior inconsistent with
- previous versions of cmake.
-
-2003-11-03 16:59 andy
-
- * Source/CTest/cmCTestSubmit.cxx: BUG: This fixes problem when
- submitting bugs on Mac: Bug #320 - When st_size in stat is 64 bit
- ctest does not submit
-
-2003-11-03 15:57 hoffman
-
- * Source/: cmLocalVisualStudio6Generator.cxx, cmMakefile.cxx: BUG:
- hack fix for problem of MS vs 6 and custom target commands
-
-2003-11-03 15:53 andy
-
- * Source/cmQTWrapCPPCommand.cxx: BUG: Fix Bug #319 - Change in
- QT_WRAP_CPP's behaviour
-
-2003-11-03 15:38 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: ENH: Cleanup parsing of argument
- to help fix Bug #259 - CMake does not quote correctly in
- DartTestfile.txt
-
-2003-11-03 15:19 king
-
- * Source/cmAddTestCommand.cxx: BUG#259: ADD_TEST command generated
- in DartTestfile.txt now quotes/escapes all arguments.
-
-2003-11-03 11:01 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx: BUG: fix for debug libs
- not using output path
-
-2003-10-31 17:22 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG#318:
- cmake.check_depends now collects all dependencies for
- cmake.depends and then uses a single rule.
-
-2003-10-31 17:05 king
-
- * Modules/Platform/Windows-cl.cmake: BUG#317: Merging 1.23->1.24
- changes to 1.8 branch.
-
-2003-10-31 17:01 king
-
- * Templates/EXEWinHeader.dsptemplate: BUG#316: Merged 1.15->1.16
- changes from main tree to 1.8 branch.
-
-2003-10-31 16:56 hoffman
-
- * Modules/Platform/Windows-cl.cmake: BUG: fix for bug# 317
-
-2003-10-31 16:55 andy
-
- * Source/cmLocalVisualStudio6Generator.cxx,
- Templates/DLLHeader.dsptemplate, Templates/EXEHeader.dsptemplate,
- Templates/EXEWinHeader.dsptemplate,
- Templates/staticLibHeader.dsptemplate,
- Tests/COnly/CMakeLists.txt: ENH: Attempt to add debug library
- postfix for visual studio 6
-
-2003-10-31 16:53 hoffman
-
- * Templates/EXEWinHeader.dsptemplate: Fix for BUG: 316
-
-2003-10-31 12:55 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: Merged all changes
- from main tree up to revision 1.39.
-
-2003-10-31 09:31 andy
-
- * Source/cmCTest.cxx: ENH: Report when having conflicts
-
-2003-10-30 16:12 king
-
- * Source/: cmake.cxx: BUG#313: Improving error message when no
- CMakeLists.txt file is found in the source tree.
-
-2003-10-30 14:27 king
-
- * Source/cmAddTestCommand.cxx: BUG: Backing out previous change
- until a deeper problem can be investigated.
-
-2003-10-30 14:00 king
-
- * Source/cmAddTestCommand.cxx: BUG#259: Do not double quote
- arguments if they are already quoted when writing
- DartTestfile.txt.
-
-2003-10-30 13:47 king
-
- * Source/cmTryCompileCommand.h: BUG#163: Merging 1.12->1.13 changes
- to 1.8 branch for 1.8.2 release.
-
-2003-10-30 13:46 king
-
- * Source/cmTryCompileCommand.h: BUG#163: Added documentation of
- OUTPUT_VARIABLE argument.
-
-2003-10-30 13:35 king
-
- * Modules/FindLATEX.cmake: BUG#262: Merging fix from main tree
- 1.8->1.9 to 1.8 branch for 1.8.2 release.
-
-2003-10-30 13:33 king
-
- * Modules/FindLATEX.cmake: BUG#262: Marking DVIPDF_CONVERTER as
- advanced.
-
-2003-10-30 13:18 king
-
- * Source/cmake.cxx: BUG#311: Merging 1.141->1.142 changes to 1.8
- branch for 1.8.2 release.
-
-2003-10-30 13:16 king
-
- * Source/cmCTest.cxx: BUG#310: Merging 1.60->1.61 from main tree to
- 1.8 branch.
-
-2003-10-30 10:05 andy
-
- * Source/cmCTest.cxx: BUG: Fix Bug #310 - CTest sends wrong time to
- cvs on Windows
-
-2003-10-29 19:48 andy
-
- * Source/: cmake.cxx, cmakemain.cxx, cmSystemTools.cxx,
- cmSystemTools.h: ENH: Ok, no more argument needed for script mode
-
-2003-10-29 09:56 andy
-
- * Source/cmGlobalGenerator.cxx: ENH: More scripting changes
-
-2003-10-29 09:43 andy
-
- * Source/: cmake.cxx, cmake.h, cmMakefile.cxx, cmakemain.cxx: ENH:
- Start includding the scripting support
-
-2003-10-29 08:58 andy
-
- * Source/: cmCommand.h, cmMessageCommand.h, cmIncludeCommand.h:
- ENH: Start includding the scripting support
-
-2003-10-28 15:26 andy
-
- * Source/cmake.cxx: ENH: Command should also be quoted
-
-2003-10-28 13:22 king
-
- * Source/: cmGlobalBorlandMakefileGenerator.cxx,
- cmGlobalNMakeMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator.cxx, cmLocalUnixMakefileGenerator.h:
- BUG#303: Merged fix from main tree to 1.8 branch for 1.8.2
- release.
-
-2003-10-28 13:19 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG#200: Merged fix to
- 1.8 branch for 1.8.2 release.
-
-2003-10-28 11:55 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: add preprocessor
- flags to resource compiler
-
-2003-10-28 11:06 hoffman
-
- * Source/: cmGlobalBorlandMakefileGenerator.cxx,
- cmGlobalNMakeMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator.cxx, cmLocalUnixMakefileGenerator.h:
- BUG: fix for bug 303 pass makeflags to sub makes
-
-2003-10-25 18:21 andy
-
- * Utilities/Doxygen/doxyfile.in: ENH: Add all subdirectories
-
-2003-10-17 16:19 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: make sure -M flags
- are not duplicated and are only set in the xml
-
-2003-10-17 16:10 king
-
- * Modules/CMakeDetermineCXXCompiler.cmake: BUG#276: Merge fix for
- spaces in path from main tree.
-
-2003-10-17 16:09 king
-
- * Modules/CMakeDetermineCXXCompiler.cmake: BUG: Fixed same
- spaces-in-paths problem for CMakeTestGNU.c as in
- CMakeDetermineCCompiler.cmake.
-
-2003-10-17 16:08 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: fix for unicode
- and for /D -D
-
-2003-10-16 19:15 andy
-
- * Source/CMakeLists.txt: ENH: Enable test on windows
-
-2003-10-16 17:51 king
-
- * Modules/Platform/Windows-cl.cmake: BUG#78: Merged fix from main
- tree (1.22->1.23).
-
-2003-10-16 13:42 king
-
- * CMakeLists.txt, Utilities/Release/cmake_release.sh: ENH: Updating
- version number for 1.8.2 release.
-
-2003-10-16 13:09 king
-
- * Modules/: CMakeDetermineJavaCompiler.cmake, FindJNI.cmake,
- FindJava.cmake, FindTCL.cmake: BUG#281: Merging fix from main
- tree. See bug report for revision changes.
-
-2003-10-16 13:06 king
-
- * Source/cmCTest.cxx: BUG#278: Merging fix from main tree
- (1.59->1.60) to 1.8 branch for 1.8.2 release.
-
-2003-10-16 11:05 barre
-
- * Modules/: CMakeDetermineJavaCompiler.cmake, FindJNI.cmake,
- FindJava.cmake, FindTCL.cmake: FIX: for Windows users, it seems
- logical to favor native win32 installation before Cygwin ones.
- Otherwise you can end up with bad mixes (part of the java tools
- were picked from the SDK, part from Cygwin)
-
-2003-10-16 10:32 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx,
- Templates/DLLHeader.dsptemplate, Templates/EXEHeader.dsptemplate,
- Templates/EXEWinHeader.dsptemplate,
- Templates/staticLibHeader.dsptemplate: ENH: allow UNICODE to be
- specifed in the cxx flags and if not default to MBCS
-
-2003-10-16 10:10 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: ENH: allow users to
- change to unicode
-
-2003-10-16 07:49 andy
-
- * Source/cmCTest.cxx: ENH: Handle all white spaces, fix problem on
- cygwin
-
-2003-10-15 23:42 hoffman
-
- * Modules/Platform/Windows-cl.cmake,
- Source/cmLocalVisualStudio7Generator.cxx: BUG: fix for bug 78
- should be on 1.8 branch
-
-2003-10-15 10:19 king
-
- * Modules/Platform/Darwin.cmake: BUG#277: Fix from main tree 1.5 ->
- 1.6 merged to 1.8 branch. Will be included in 1.8.2 release.
-
-2003-10-15 10:14 king
-
- * Modules/Platform/Darwin.cmake: ERR: Old -flat_namespace
- -undefined suppress flags for CMAKE_SHARED_MODULE_CREATE_C_FLAGS
- should be included when CMAKE_BACKWARDS_COMPATIBILITY is 1.6 or
- lower.
-
-2003-10-15 10:06 king
-
- * bootstrap: BUG#168: Merged fix for HP-UX ansi C flags as second
- part of the fix for this bug to 1.8 branch. 1.24 -> 1.25.
-
-2003-10-15 10:01 king
-
- * Source/kwsys/SystemTools.cxx: BUG#263: Merged search path
- ordering fix from main tree to CMake 1.8 branch. 1.22 -> 1.24.
-
-2003-10-15 09:56 king
-
- * Source/cmTargetLinkLibrariesCommand.cxx: BUG#201: Merged warning
- suppression support from main tree to 1.8 branch. 1.16->1.17.
-
-2003-10-15 09:53 king
-
- * Modules/CheckTypeSize.cmake: Documentation fix from main tree.
- 1.11->1.12.
-
-2003-10-15 09:52 king
-
- * Modules/CheckVariableExists.cmake: BUG: Merged trivial fix from
- main tree. 1.10 -> 1.11.
-
-2003-10-15 09:49 king
-
- * Modules/CMakeDetermineCCompiler.cmake: BUG#263: Merged fix for
- system paths in ar and ranlib find commands to 1.8 branch. Will
- be included in 1.8.2
-
-2003-10-15 09:26 king
-
- * Source/cmQTWrapCPPCommand.cxx: BUG#186: Merged fix from trunk to
- branch.
-
-2003-10-15 09:18 king
-
- * Modules/CMakeDetermineCCompiler.cmake: BUG#276: Merge fix for
- spaces in path from main tree.
-
-2003-10-14 22:30 king
-
- * Modules/CMakeDetermineCCompiler.cmake: BUG: Fix for spaces in
- path when loading CMakeTestGNU.c.
-
-2003-10-13 16:04 andy
-
- * Source/CMakeLists.txt: ENH: Add test for FindwxWindows. Thanks
- to: Mathieu Malaterre
-
-2003-10-13 15:27 andy
-
- * Modules/CheckTypeSize.cmake: ENH: Documentation fix
-
-2003-10-13 11:58 king
-
- * Modules/Platform/Windows-cl.cmake: BUG#269: Fix for spaces in
- paths. Will be included in 1.8.2 release.
-
-2003-10-13 11:32 andy
-
- * Modules/Platform/Windows-cl.cmake: ERR: allow spaces in the path
-
-2003-10-11 08:12 king
-
- * Modules/CheckVariableExists.cmake: BUG: Message describing
- variable was using result variable.
-
-2003-10-09 15:52 hoffman
-
- * Modules/CMakeDetermineCCompiler.cmake,
- Source/kwsys/SystemTools.cxx: ENH: put the system path after the
- paths specified on to the FIND command
-
-2003-10-07 13:45 king
-
- * Utilities/Release/cmake_release.sh: Updated cygwin dependencies.
-
-2003-10-07 09:50 king
-
- * Utilities/Release/config_CYGWIN_NT-5.1: GCC 2.95 is no longer
- available on cygwin.
-
-2003-10-02 14:50 andy
-
- * Source/cmTargetLinkLibrariesCommand.cxx: ENH: Add
- CMAKE_IGNORE_DEPENDENCIES_ORDERING to prevent warnings about
- dependency problems
-
-2003-09-26 11:27 king
-
- * Modules/CMakeImportBuildSettings.cmake: BUG: Comparison of build
- tool should be case-insensitive.
-
-2003-09-26 11:15 king
-
- * Modules/CMakeImportBuildSettings.cmake: BUG: Comparison of build
- tool should be case-insensitive.
-
-2003-09-24 17:51 andy
-
- * Source/cmQTWrapUICommand.cxx: ENH: Fix comment
-
-2003-09-24 17:51 andy
-
- * Tests/Wrapping/CMakeLists.txt: ENH: Better testing
-
-2003-09-24 17:50 andy
-
- * Source/cmQTWrapCPPCommand.cxx: BUG: Fix Bug #186 - QT_WRAP_UI
- uses the path twice
-
-2003-09-24 11:10 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG#191: Merging fix
- into 1.8 branch for inclusion in 1.8.2 release.
-
-2003-09-24 11:03 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: Check for whether
- to use CMAKE_EXE_LINKER_FLAGS should look both for EXECUTABLE and
- WIN32_EXECUTABLE targets.
-
-2003-09-23 13:58 king
-
- * Source/cmCTest.cxx: BUG#185: Merged fix from main tree to 1.8
- branch. Change will be included in 1.8.2 release.
-
-2003-09-23 13:49 andy
-
- * Source/cmCTest.cxx: ENH: Add missing newline Bug #185 - CTest
- exceptions output is missing new line
-
-2003-09-18 11:05 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: remove /tmp_mnt in collapse
- full path
-
-2003-09-15 15:58 king
-
- * bootstrap: BUG: Need to check for -Ae flag on HP-UX cc compiler.
- Needed for ANSI C compilation.
-
-2003-09-02 13:49 king
-
- * bootstrap: BUG#168: Using C compiler to build .c files during
- bootstrap instead of C++ compiler.
-
-2003-09-02 13:27 king
-
- * bootstrap: BUG: Must use C compiler to compile C files during
- bootstrap, not C++ compiler.
-
-2003-08-29 09:38 king
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: BUG: Merged more fixes from
- main tree.
-
-2003-08-28 16:22 hoffman
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: BUG: make sure exe output path
- is used for dep hack stuff
-
-2003-08-28 16:10 martink
-
- * Source/cmLocalVisualStudio6Generator.cxx: bad evil nasty ken
-
-2003-08-28 16:06 martink
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: fix to executable depends for
- custom commands
-
-2003-08-28 15:02 king
-
- * Utilities/Release/config_IRIX64: ERR: Don't need separate -n32
- and -64 binaries.
-
-2003-08-28 14:58 hoffman
-
- * Tests/: Complex/Library/CMakeLists.txt,
- ComplexOneConfig/Library/CMakeLists.txt,
- ComplexRelativePaths/Library/CMakeLists.txt: BUG: remove
- bundle_loader stuff it did not work with spaces in the path and
- is not needed for this test
-
-2003-08-28 14:55 king
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: BUG: Merged fix for bug with
- custom commands depending on executables from main tree.
-
-2003-08-28 14:52 hoffman
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: BUG: fix bug with custom
- commands depending on executables
-
-2003-08-28 14:03 king
-
- * CMakeLists.txt, Utilities/Release/cmake_release.sh: ENH: Updated
- for 1.8.1 release number.
-
-2003-08-27 20:35 starreveld
-
- * Modules/Platform/Darwin.cmake,
- Tests/Complex/Library/CMakeLists.txt,
- Tests/ComplexOneConfig/Library/CMakeLists.txt,
- Tests/ComplexRelativePaths/Library/CMakeLists.txt: ENH: remove
- the -flat_namespace and -undefined suppress hacks from ENH:
- CMAKE_SHARED_MODULE_CREATE_C_FLAGS ENH: and fix the complex
- example to specify a -bundle loader for the ENH: shared module
- that it builds.
-
-2003-08-27 17:45 hoffman
-
- * Source/cmWin32ProcessExecution.cxx: ENH: remove warnings from use
- of NULL
-
-2003-08-27 16:50 king
-
- * CMakeLists.txt, CMakeSystemConfig.txt.in,
- CMakeWindowsSystemConfig.txt, bootstrap,
- Modules/CMakeCCompiler.cmake.in,
- Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeSystemSpecificInformation.cmake,
- Modules/CMakeTestCCompiler.cmake,
- Modules/CMakeTestCXXCompiler.cmake, Modules/CMakeTestGNU.c,
- Modules/FindThreads.cmake, Modules/FindwxWindows.cmake,
- Modules/Platform/Windows-bcc32.cmake,
- Modules/Platform/Windows-cl.cmake,
- Modules/Platform/Windows-gcc.cmake,
- Modules/Platform/Windows.cmake, Source/CMakeLists.txt,
- Source/TODO, Source/cmCacheManager.cxx, Source/cmCommands.cxx,
- Source/cmDynamicLoader.cxx,
- Source/cmGlobalBorlandMakefileGenerator.cxx,
- Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmGlobalNMakeMakefileGenerator.cxx,
- Source/cmGlobalUnixMakefileGenerator.cxx,
- Source/cmLoadCommandCommand.cxx,
- Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmSystemTools.cxx, Source/cmSystemTools.h,
- Source/cmWin32ProcessExecution.cxx, Source/cmake.cxx,
- Source/kwsys/SystemTools.cxx,
- Tests/Complex/Executable/CMakeLists.txt,
- Tests/Complex/Executable/complex.cxx,
- Tests/Complex/Library/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexOneConfig/Library/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Library/CMakeLists.txt,
- Utilities/CMakeLists.txt: ENH: Merging changes from trunk into
- 1.8 branch.
-
- 1.) MinGW support (beta) 2.) make VERBOSE=1 3.) FindThreads.cmake
- fix 4.) FindwxWindows.cmake fix 5.)
- CMakeSystemSpecificInformation.cmake typo fix 6.) bootstrap
- spaces-in-path fix
-
-2003-08-27 16:42 hoffman
-
- * Modules/Platform/Windows-gcc.cmake,
- Tests/Complex/Executable/CMakeLists.txt,
- Tests/Complex/Executable/complex.cxx,
- Tests/Complex/Library/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexOneConfig/Library/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Library/CMakeLists.txt: ENH: MinGW
- build now passes all the tests
-
-2003-08-27 16:08 king
-
- * Utilities/Release/: cmake_release.sh, config_AIX, config_Darwin,
- config_HP-UX, config_IRIX64, config_Linux, config_OSF1,
- config_SunOS, cygwin-package.sh.in: Merging release script
- changes from 1.8 branch to main tree.
-
-2003-08-27 16:02 king
-
- * Modules/: CMakeTestCCompiler.cmake, CMakeTestCXXCompiler.cmake:
- ERR: Fixed typo in comment.
-
-2003-08-27 08:29 king
-
- * Source/cmake.cxx: ERR: Fixed placement of code introduced by a
- patch from main tree. Somehow it ended up on the wrong lines.
-
-2003-08-26 17:13 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: Added support for
- "make VERBOSE=1" to run one-time verbose make runs without
- changing CMAKE_VERBOSE_MAKEFILE.
-
-2003-08-26 15:08 king
-
- * Source/: cmake.cxx, cmakemain.cxx, cmakewizard.cxx,
- cmakewizard.h: BUG#164: Fixed crash of cmake -i when CMAKE_ROOT
- cannot be found. Made resulting error message cleaner.
-
-2003-08-26 15:06 king
-
- * Source/: cmake.cxx, cmakemain.cxx, cmakewizard.cxx,
- cmakewizard.h: BUG: Fixed crash of cmake -i when CMAKE_ROOT
- cannot be found. Made resulting error message cleaner.
-
-2003-08-22 12:53 king
-
- * CMakeLists.txt, Source/CMakeLists.txt, Utilities/CMakeLists.txt:
- ENH: Moved decision to build MFCDialog up to top level. It is
- used in both the Source and Utilities directories.
-
-2003-08-22 11:56 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: remove ifdef code
- and use makefile definitions
-
-2003-08-22 11:56 hoffman
-
- * Modules/Platform/Windows-gcc.cmake: ENH: add configure file for
- gcc under windows
-
-2003-08-22 09:52 andy
-
- * bootstrap, Modules/FindThreads.cmake: ERR: Reorganize to try to
- fix the -pthread problem on some systems
-
-2003-08-21 16:22 hoffman
-
- * Modules/CMakeCCompiler.cmake.in,
- Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeSystemSpecificInformation.cmake,
- Modules/CMakeTestCCompiler.cmake,
- Modules/CMakeTestCXXCompiler.cmake, Modules/CMakeTestGNU.c,
- Modules/Platform/Windows-bcc32.cmake,
- Modules/Platform/Windows-cl.cmake,
- Modules/Platform/Windows.cmake, Source/CMakeLists.txt,
- Source/cmDynamicLoader.cxx,
- Source/cmGlobalBorlandMakefileGenerator.cxx,
- Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmGlobalNMakeMakefileGenerator.cxx,
- Source/cmGlobalUnixMakefileGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmSystemTools.cxx, Source/cmSystemTools.h,
- Source/cmWin32ProcessExecution.cxx, Source/cmake.cxx,
- Source/kwsys/SystemTools.cxx: ENH: add the unix makefile
- generator as an option from the windows GUI, this builds with
- mingw, cygwin, and combinations of make cl, bcc32
-
-2003-08-21 13:26 andy
-
- * Modules/FindwxWindows.cmake: ERR: If WX_CONFIG_LIBS are , then
- you get weird cmake error. This should fix it
-
-2003-08-21 09:23 hoffman
-
- * Source/TODO: [no log message]
-
-2003-08-20 12:59 king
-
- * Source/: cmakemain.cxx, CursesDialog/ccmake.cxx: ENH: Added
- documentation of specifying an existing build tree as an
- argument.
-
-2003-08-19 11:02 andy
-
- * Source/cmLoadCommandCommand.cxx: ERR: Fix crash of cmake on
- broken load commands
-
-2003-08-19 10:50 king
-
- * Modules/Platform/: IRIX64.cmake: ENH: Improved default choice of
- -64 compiler/linker flags based on how cmake was built.
-
-2003-08-19 10:29 andy
-
- * Source/cmLoadCommandCommand.cxx: BUG: LastError can return 0, so
- handle that case
-
-2003-08-19 09:41 king
-
- * bootstrap: BUG: Merged cmake_make_processor error message to 1.8
- branch.
-
-2003-08-19 09:40 king
-
- * Source/: cmCTest.cxx, cmCTest.h: BUG: Merged fixes for bugs 146,
- 152, and 153 to 1.8 branch.
-
-2003-08-19 09:39 king
-
- * Source/cmCacheManager.cxx: BUG#154: Merged fix to 1.8 branch.
-
-2003-08-19 09:39 king
-
- * Source/cmake.cxx: ERR: Fixed warnings.
-
-2003-08-19 09:33 king
-
- * Source/kwsys/SystemTools.cxx: ERR: Merged warning fix from main
- tree to CMake 1.8 branch.
-
-2003-08-19 09:32 king
-
- * Source/kwsys/ProcessUNIX.c: ProcessUNIX.c
-
-2003-08-19 09:32 king
-
- * Source/kwsys/ProcessWin32.c: BUG: Merged error message fix to
- CMake 1.8 branch.
-
-2003-08-19 09:27 king
-
- * Modules/FindLATEX.cmake: BUG#156: Fixed typo psd2pdf -> ps2pdf.
- Will be included in 1.8.1 release.
-
-2003-08-19 09:12 king
-
- * Utilities/Release/: cmake_release.sh, config_IRIX64: Added
- LDFLAGS support.
-
-2003-08-19 09:06 king
-
- * Utilities/Release/config_IRIX64: ENH: Added configuration of both
- -64 and -n32 builds.
-
-2003-08-19 09:05 king
-
- * Utilities/Release/cmake_release.sh: ENH: Added support for
- configuration of install tree.
-
-2003-08-19 08:53 andy
-
- * Modules/FindLATEX.cmake: BUG: Fix Bug #156 - ps2pdf is not found
- on linux
-
-2003-08-18 14:31 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: BUG: Report failed as failed...
-
-2003-08-18 14:06 andy
-
- * Source/cmake.cxx: ENH: Remove unused variable
-
-2003-08-18 14:05 andy
-
- * Source/cmCacheManager.cxx: BUG: Fixed Bug #154 - Uninitialized
- type initialized value cache variables should return value
-
-2003-08-18 11:30 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: BUG: Fix Bug #153 - CTest does
- not detect tests that are not found and Bug #153 - CTest does not
- detect tests that are not found
-
-2003-08-17 12:24 hoffman
-
- * Source/kwsys/SystemTools.cxx: ENH: remove warning and unneeded
- cast
-
-2003-08-15 08:41 andy
-
- * Source/cmCTest.cxx: BUG: Fix test reporting
-
-2003-08-14 13:34 andy
-
- * Source/cmCTest.cxx: ENH: Fix verbose output, fix error message,
- and fix the exit code check
-
-2003-08-14 09:09 hoffman
-
- * Source/cmake.cxx: ENH: remove a warning
-
-2003-08-13 18:17 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: ENH: Better error reporting
-
-2003-08-13 18:08 king
-
- * Source/kwsys/ProcessWin32.c: ENH: Made error message consistent
- between win9x and non-win9x version of error reporting.
-
-2003-08-13 14:21 king
-
- * Source/kwsys/ProcessUNIX.c: ENH: Treating SIGBUS as a fault by
- default.
-
-2003-08-12 17:24 king
-
- * Source/cmSystemTools.cxx: BUG: Do not hide console when run from
- ctest.
-
-2003-08-12 17:18 andy
-
- * Source/cmSystemTools.cxx: ENH: Fix hidden console for ctest
-
-2003-08-12 17:17 king
-
- * Utilities/Release/cmake_release.sh: Redoing 1.8.0.
-
-2003-08-12 16:37 king
-
- * Utilities/Release/cmake_release.sh: Disable use of libdl by curl.
-
-2003-08-12 16:35 king
-
- * Utilities/Release/: config_AIX, config_Darwin, config_HP-UX,
- config_IRIX64, config_Linux, config_OSF1, config_SunOS: ENH:
- Using write_standard_cache to shorten config files.
-
-2003-08-12 16:35 king
-
- * Utilities/Release/cmake_release.sh: ENH: Unix builds should not
- use reentrant versions of network calls.
-
-2003-08-11 18:24 king
-
- * Utilities/Release/config_Darwin: ENH: Updated for new wx version.
-
-2003-08-11 18:21 king
-
- * Utilities/Release/cmake_release.sh: BUG: CMake.app directory is
- now in bin, not Source.
-
-2003-08-11 18:14 king
-
- * Utilities/Release/cygwin-package.sh.in: BUG: Tests are run by
- bin/ctest instead of Source/ctest.
-
-2003-08-11 17:58 king
-
- * Utilities/Release/: cmake_release.sh, config_IRIX64,
- config_Linux: ENH: Added support for parallel build during
- release.
-
-2003-08-11 17:53 andy
-
- * bootstrap: ENH: Add error message for make missing
-
-2003-08-11 17:41 king
-
- * Utilities/Release/cmake_release.sh: BUG: Test for build needs to
- look for bin/ccmake, not Source/ccmake.
-
-2003-08-11 17:35 king
-
- * Utilities/Release/: cmake_release.sh, config_Darwin,
- config_HP-UX, config_IRIX64, config_SunOS: Merge from 1.8 branch.
-
-2003-08-11 17:34 king
-
- * Source/cmCommands.cxx: BUG: Bootstrapping with wxWindows support
- needs SEPARATE_ARGUMENTS command.
-
-2003-08-11 17:34 king
-
- * Modules/CMakeLists.txt: ENH: Installing readme.txt in Modules
- directory to be consistent with windows.
-
-2003-08-11 16:55 king
-
- * Utilities/Release/config_Darwin: Fixed wx location.
-
-2003-08-11 16:43 king
-
- * Source/cmCommands.cxx: BUG: Bootstrapping with wxWindows support
- requires SEPARATE_ARGUMENTS command in bootstrapped executable.
-
-2003-08-11 16:31 king
-
- * Utilities/Release/config_HP-UX: ENH: Cleaned up link of dld.
-
-2003-08-11 16:31 king
-
- * Utilities/Release/config_SunOS: ENH: Switching to system
- compiler.
-
-2003-08-11 15:27 king
-
- * Utilities/Release/cmake_release.sh: Using bootstrap instead of
- configure.
-
-2003-08-11 15:22 king
-
- * Utilities/Release/cmake_release.sh: ENH: Allow config files to
- specify a make.
-
-2003-08-11 15:21 king
-
- * Utilities/Release/config_IRIX64: ENH: Enabling parallel build.
-
-2003-08-11 15:16 king
-
- * Utilities/Release/cmake_release.sh: BUG: Location of ctest has
- changed to bin, not Source.
-
-2003-08-11 15:15 king
-
- * Utilities/Release/config_Darwin: Updated for new FindwxWindows.
-
-2003-08-11 15:07 king
-
- * Utilities/Release/cmake_release.sh: Update from 1.8 branch.
-
-2003-08-11 15:06 king
-
- * Utilities/Release/config_Darwin: Updated for new location of
- wxWindows.
-
-2003-08-11 15:02 king
-
- * Utilities/Release/config_Darwin: Updated for new location of
- wxWindows.
-
-2003-08-11 15:01 king
-
- * Utilities/Release/cmake_release.sh: ENH: Updated for new FTP
- directory structure.
-
-2003-08-11 14:56 king
-
- * Modules/CMakeLists.txt: ENH: Installing readme.txt in modules to
- be consistent with windows.
-
-2003-08-11 14:44 martink
-
- * Source/: cmMakefile.cxx: added beta release support
-
-2003-08-11 14:41 martink
-
- * CMakeLists.txt, Source/cmCPluginAPI.h: version 19
-
-2003-08-11 14:37 martink
-
- * CMakeLists.txt, Source/cmCPluginAPI.h,
- Utilities/Release/cmake_release.sh: added version
-
-2003-08-11 12:20 andy
-
- * Source/ctest.cxx: ENH: Add documentation for -D and add missing
- targets
-
-2003-08-11 12:18 andy
-
- * Source/: cmCTest.cxx, CTest/cmCTestSubmit.cxx: ENH: Cleanup the
- output
-
-2003-08-11 12:17 andy
-
- * Modules/Dart.cmake: ENH: Take Purify out because it is not
- implemented yet
-
-2003-08-11 09:47 andy
-
- * Source/cmCTest.cxx: ENH: Remove debug
-
-2003-08-10 18:30 martink
-
- * Source/: cmAbstractFilesCommand.h, cmAddCustomCommandCommand.h,
- cmAddCustomTargetCommand.h, cmAddDefinitionsCommand.h,
- cmAddDependenciesCommand.h, cmAddExecutableCommand.h,
- cmAddLibraryCommand.h, cmAddTestCommand.h,
- cmAuxSourceDirectoryCommand.h, cmBuildCommand.h,
- cmBuildNameCommand.h, cmCMakeMinimumRequired.cxx,
- cmCMakeMinimumRequired.h, cmCTest.cxx, cmCacheManager.cxx,
- cmCommand.h, cmConfigureFileCommand.h, cmCreateTestSourceList.h,
- cmEnableTestingCommand.h, cmEndForEachCommand.h,
- cmExecProgramCommand.h, cmExportLibraryDependencies.h,
- cmFLTKWrapUICommand.h, cmFileCommand.h, cmFindFileCommand.cxx,
- cmFindFileCommand.h, cmFindLibraryCommand.h,
- cmFindPackageCommand.h, cmFindPathCommand.h,
- cmFindProgramCommand.cxx, cmFindProgramCommand.h,
- cmForEachCommand.h, cmGetCMakePropertyCommand.h,
- cmGetSourceFilePropertyCommand.h, cmGetTargetPropertyCommand.h,
- cmGlob.cxx, cmITKWrapTclCommand.h, cmIfCommand.h,
- cmIncludeCommand.h, cmIncludeDirectoryCommand.h,
- cmIncludeExternalMSProjectCommand.h,
- cmIncludeRegularExpressionCommand.h, cmInstallFilesCommand.h,
- cmInstallProgramsCommand.h, cmInstallTargetsCommand.h,
- cmLinkDirectoriesCommand.h, cmLinkLibrariesCommand.h,
- cmLoadCommandCommand.h, cmLocalUnixMakefileGenerator.cxx,
- cmMacroCommand.h, cmMakeDirectoryCommand.h, cmMakefile.cxx,
- cmMakefile.h, cmMarkAsAdvancedCommand.h, cmMessageCommand.h,
- cmOptionCommand.h, cmOutputRequiredFilesCommand.h,
- cmProjectCommand.h, cmQTWrapCPPCommand.h, cmQTWrapUICommand.h,
- cmRemoveCommand.h, cmSeparateArgumentsCommand.h, cmSetCommand.h,
- cmSetSourceFilesPropertiesCommand.h,
- cmSetTargetPropertiesCommand.h, cmSiteNameCommand.h,
- cmSourceFile.h, cmSourceFilesCommand.h,
- cmSourceFilesRemoveCommand.h, cmSourceGroupCommand.h,
- cmStringCommand.h, cmSubdirCommand.h, cmSubdirDependsCommand.h,
- cmSystemTools.cxx, cmTarget.h, cmTargetLinkLibrariesCommand.h,
- cmTryCompileCommand.h, cmTryRunCommand.h,
- cmUseMangledMesaCommand.h, cmUtilitySourceCommand.h,
- cmVTKMakeInstantiatorCommand.h, cmVTKWrapJavaCommand.h,
- cmVTKWrapPythonCommand.h, cmVTKWrapTclCommand.h,
- cmVariableRequiresCommand.h, cmWin32ProcessExecution.cxx,
- cmWrapExcludeFilesCommand.h, cmWriteFileCommand.h, cmake.cxx,
- cmake.h, cmakewizard.cxx, cmakewizard.h: removed redundent
- includes
-
-2003-08-10 16:01 martink
-
- * Source/: cmMakeDepend.cxx, cmMakeDepend.h, cmSourceFile.cxx:
- removed duplicate includes
-
-2003-08-10 16:00 martink
-
- * Source/cmMakefile.cxx: removed duplicate include
-
-2003-08-09 19:37 andy
-
- * Source/cmCTest.cxx: ERR: Rename some variables to remove shadow
- warning
-
-2003-08-08 18:28 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: ENH: Add regression images
- support
-
-2003-08-08 17:10 andy
-
- * Source/cmCTest.cxx: ENH: Better output and use RunMakeCommand for
- configure
-
-2003-08-08 11:59 andy
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeDetermineCXXCompiler.cmake, CMakeDetermineSystem.cmake,
- CMakeTestCCompiler.cmake, CMakeTestCXXCompiler.cmake,
- CMakeVS6FindMake.cmake, CMakeVS71FindMake.cmake,
- CMakeVS7FindMake.cmake, CheckFunctionExists.cmake,
- CheckIncludeFile.cmake, CheckIncludeFileCXX.cmake,
- CheckIncludeFiles.cmake, CheckLibraryExists.cmake,
- CheckTypeSize.cmake, CheckVariableExists.cmake,
- FindHTMLHelp.cmake, FindMFC.cmake, TestBigEndian.cmake,
- TestCXXAcceptsFlag.cmake, TestForANSIForScope.cmake,
- TestForSTDNamespace.cmake: ENH: Cleanups and add missing
- CMakeOutput.log and CMakeError.log appending. Close Bug #136 -
- Verify that all modules that do try compile produce
- CMakeError.log and CMakeOutput.log
-
-2003-08-08 11:19 martink
-
- * Source/cmStandardIncludes.h: added stdio
-
-2003-08-08 10:40 martink
-
- * Source/cmLocalVisualStudio6Generator.cxx: fid post build iue on
- vs6 utility targets
-
-2003-08-08 10:20 andy
-
- * Tests/SystemInformation/DumpInformation.cxx: EHN: Also display
- Configure.h and Configure.hxx from cmsys
-
-2003-08-08 10:07 andy
-
- * Source/cmMakefile.cxx: ENH: When fixing cache value with
- uninitialized type, collapse full paths for PATH and FILEPATH.
- Closes Bug #82 - Specifying relative path when entering path can
- break things
-
-2003-08-08 09:26 andy
-
- * Source/cmMakefile.cxx: ENH: Handle untyped but initialized values
- for boolean AddCacheDefinition. Closes Bug #118 - Specifying
- cache entries with -D should not need the type
-
-2003-08-08 09:22 andy
-
- * Source/: cmCacheManager.cxx, cmCacheManager.h: ENH: Get accessor
- for cache value as boolean
-
-2003-08-08 09:17 martink
-
- * Source/cmLocalUnixMakefileGenerator.cxx: remove shadowed variable
-
-2003-08-08 09:14 king
-
- * Source/cmFindPackageCommand.cxx: ERR: Fixed use of != operator
- for std::string on old broken compilers.
-
-2003-08-08 08:48 andy
-
- * Source/cmakemain.cxx: ENH: Add help for cmake -E
-
-2003-08-08 08:48 andy
-
- * Source/cmCTest.cxx: ENH: Flush the output file, to make more nice
- output for tail -f
-
-2003-08-07 19:23 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: ENH: Add displaying of dots when
- building project. Also, file is now written as the output is
- produced, so, tail -f works, baby...
-
-2003-08-07 19:00 andy
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Abstract
- parsing of arguments so that I can use it in other places
-
-2003-08-07 18:44 andy
-
- * Source/cmaketest.cxx: ENH: More verbose
-
-2003-08-07 17:43 king
-
- * Source/ctest.cxx: ENH: Clarification of help dumped when no
- arguments are given and no test file is found.
-
-2003-08-07 16:54 hoffman
-
- * Tests/: Complex/CMakeLists.txt, ComplexOneConfig/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt: BUG: fix the test
-
-2003-08-07 16:50 king
-
- * Source/cmFindPackageCommand.cxx: ENH: Added compatability for
- capitalization of _DIR and _FOUND variables in cmake 1.6.
-
-2003-08-07 16:32 andy
-
- * Modules/FindLATEX.cmake: ENH: Add PDFLaTeX and LaTeX2HTML. Closes
- Bug #132 - Add pdflatex and html2latex to FindLATEX.cmake
-
-2003-08-07 16:26 andy
-
- * Source/: cmVariableWatch.cxx, cmVariableWatch.h: ENH: Add remove
- watch
-
-2003-08-07 16:25 andy
-
- * CMakeLists.txt, Source/CMakeLists.txt: ENH: Fix dependencies for
- curses dialog
-
-2003-08-07 16:11 king
-
- * Source/cmake.cxx: BUG: Fixed typo in error message.
-
-2003-08-07 16:09 andy
-
- * CMakeLists.txt, Source/CMakeLists.txt,
- Source/cmTargetLinkLibrariesCommand.cxx,
- Source/cmTargetLinkLibrariesCommand.h,
- Source/CTest/CMakeLists.txt: ENH: Report an error when
- ADD_LIBRARY and TARGET_LINK_LIBRARIES are in the wrong order and
- fix CMakeLists files to actually work
-
-2003-08-07 16:04 hoffman
-
- * Tests/Complex/CMakeLists.txt,
- Tests/Complex/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt,
- Source/cmIncludeExternalMSProjectCommand.cxx: ENH: improve
- coverage
-
-2003-08-07 15:39 andy
-
- * Source/kwsys/ProcessWin32.c: ENH: Cast into apropriate type to
- remove warning
-
-2003-08-07 14:37 andy
-
- * Source/cmQTWrapUICommand.cxx: ENH: Use the new signature
-
-2003-08-07 14:37 andy
-
- * Tests/Wrapping/CMakeLists.txt: ENH: More verbose test
-
-2003-08-07 14:10 hoffman
-
- * Modules/Platform/Windows-cl.cmake: BUG: fix for main in a library
- on windows with nmake
-
-2003-08-07 11:53 king
-
- * Source/cmLocalUnixMakefileGenerator.h: ENH: Added convenience
- signature to OutputMakeRule.
-
-2003-08-07 11:42 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: Makefiles now have
- rules to do a global generate if the CMake listfiles have
- changed. Necessary for when try-compiles are added to a
- listfile.
-
-2003-08-07 09:19 hoffman
-
- * Modules/FindMPI.cmake, Source/cmLocalVisualStudio7Generator.cxx:
- BUG: fix for bugs 125 - 128, and a fix for the bug introduced by
- the bug fix for but 92. & was being replaced with &amp, but
- after double quote was replaced with &quot causing it to be
- &amp;quot. Also add more search paths for mpi
-
-2003-08-06 19:19 andy
-
- * Source/cmMakefile.cxx: ENH: oops, initialize variable
-
-2003-08-06 18:54 andy
-
- * Source/cmGetCMakePropertyCommand.cxx,
- Source/cmGetCMakePropertyCommand.h, Source/cmMacroCommand.cxx,
- Source/cmMakefile.cxx, Source/cmMakefile.h,
- Tests/SystemInformation/CMakeLists.txt,
- Tests/SystemInformation/DumpInformation.cxx: ENH: Add option to
- retrieve list of macros. Close Bug #25 - Get_CMAKE_PROPERTIES
-
-2003-08-06 18:43 king
-
- * Source/cmDocumentation.cxx: BUG: Don't use -V as a version
- option. It conflicts with ctest.
-
-2003-08-06 18:41 king
-
- * Source/cmake.cxx: ENH: Removed old argument processing code that
- never does anything.
-
-2003-08-06 18:39 king
-
- * Source/: cmakewizard.cxx, CursesDialog/cmCursesMainForm.cxx:
- BUG#129: Fixed load/save of CMakeCache.txt when it is not in the
- current directory.
-
-2003-08-06 17:58 andy
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: If
- CMAKE_EDIT_COMMAND is not specified, use cmake -i
-
-2003-08-06 17:52 andy
-
- * bootstrap: ENH: Add rebuild_cache
-
-2003-08-06 17:32 andy
-
- * Modules/FindThreads.cmake: ENH: On apple use -lpthreads
-
-2003-08-06 15:22 king
-
- * Source/: cmInstallFilesCommand.h, cmInstallProgramsCommand.h:
- ENH: Tweaked whitespace in documentation of command.
-
-2003-08-06 15:18 king
-
- * Source/cmAddCustomCommandCommand.h: ENH: Tweaked whitespace in
- documentation of command.
-
-2003-08-06 15:12 king
-
- * Source/CursesDialog/ccmake.cxx: ENH: Added SEE ALSO support for
- generated unix manpage.
-
-2003-08-06 15:10 king
-
- * Source/CMakeLists.txt: BUG: We don't want to install cmaketest on
- UNIX or windows. It is for internal CMake testing only. We
- should probably fold its functionality into ctest anyway.
-
-2003-08-06 15:03 king
-
- * Source/ctest.cxx, Utilities/CMakeLists.txt: ENH: Added
- documentation for ctest.
-
-2003-08-06 14:49 king
-
- * Source/: cmDocumentation.cxx, cmDocumentation.h, cmakemain.cxx,
- CursesDialog/ccmake.cxx: ENH: Added configuration of name of
- executable in man page header and version banner.
-
-2003-08-06 13:48 king
-
- * Source/cmSystemTools.cxx: ENH: Hide windows for processes run by
- RunSingleCommand.
-
-2003-08-06 13:41 king
-
- * Source/kwsys/SystemTools.cxx: Fixed indentation
-
-2003-08-06 12:52 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: do not output make
- install rules on windows because they do not work
-
-2003-08-06 11:51 king
-
- * Source/cmaketest.cxx: BUG: Fixed spacing error in message.
-
-2003-08-06 10:42 king
-
- * Source/CMakeLists.txt: ENH: Install test is now enabled when
- CMAKE_INSTALL_PREFIX is CMake_BINARY_DIR/Tests/TestInstall/Prefix
- to keep test in one directory.
-
-2003-08-06 10:39 king
-
- * Source/CMakeLists.txt, Tests/TestInstall.sh.in: ENH: Added
- Install test. It is enabled when the CMAKE_INSTALL_PREFIX is
- CMake_BINARY_DIR/InstallTest.
-
-2003-08-06 10:15 andy
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: Fix install problem
-
-2003-08-06 09:27 king
-
- * Source/kwsys/ProcessWin32.c: BUG: Need to provide stdin to child
- processes.
-
-2003-08-05 18:25 king
-
- * Tests/CommandLineTest/CMakeLists.txt: ENH: Added test of
- --copyright and --version arguments for coverage.
-
-2003-08-05 18:22 king
-
- * Tests/CommandLineTest/CMakeLists.txt: ENH: Added test of --help
- [command] form of help option for coverage.
-
-2003-08-05 18:10 king
-
- * Source/: cmDocumentation.cxx, cmDocumentation.h: ENH: Added
- support to --help to print help for a single command.
-
-2003-08-05 17:39 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: Fixed
- implementation of long dependency list support. The proxy target
- must have a corresponding file to work correctly. Instead of
- using a proxy target, we now just list one line for each
- dependency and then print one copy of the build rule at the end.
-
-2003-08-05 16:51 king
-
- * Source/cmake.cxx: ENH: Clarified source directory mismatch
- message.
-
-2003-08-05 16:36 king
-
- * Source/: cmake.cxx, cmake.h: ENH#61: cmake and ccmake now support
- passing the path to a CMakeCache.txt file as an argument. Its
- settings will be loaded.
-
-2003-08-05 16:04 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG#92 - Added XML
- escaping for <, >, and &.
-
-2003-08-05 15:20 andy
-
- * Tests/SystemInformation/DumpInformation.cxx: BUG: Open as ascii
- to remove extra new lines
-
-2003-08-05 15:10 king
-
- * Source/kwsys/: ProcessFwd9x.c, ProcessWin32.c: ENH: Added
- show/hide window support.
-
-2003-08-05 14:27 king
-
- * Source/kwsys/: Process.h.in, ProcessUNIX.c, ProcessWin32.c: ENH:
- Added SetOption/GetOption methods for platform-specific options.
-
-2003-08-05 13:53 king
-
- * Source/kwsys/ProcessUNIX.c: BUG: Can't close stdin.
-
-2003-08-05 11:34 king
-
- * Source/kwsys/ProcessUNIX.c: BUG: Added missing
- zero-initialization of struct sigaction.
-
-2003-08-05 09:55 martink
-
- * Modules/: CMakeTestNMakeCLVersion.c, Platform/Windows-cl.cmake:
- added test for whether pdbtype should be used for nmake
-
-2003-08-05 09:07 king
-
- * Source/kwsys/ProcessUNIX.c: BUG: GetErrorString should return
- ErrorMessage buffer, not the pipe buffer.
-
-2003-08-05 09:07 martink
-
- * Source/cmLocalUnixMakefileGenerator.cxx: minor fix
-
-2003-08-05 08:49 martink
-
- * Source/: cmLocalUnixMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator.h: added outputEcho method and fixed
- make help for nmake and borland
-
-2003-08-04 17:08 king
-
- * Modules/: CMakeTestCCompiler.cmake, CMakeTestCXXCompiler.cmake:
- ERR: Fixed typeo tests->test.
-
-2003-08-04 15:35 martink
-
- * Source/cmLocalUnixMakefileGenerator.cxx: added make help target
- first cut
-
-2003-08-04 14:34 martink
-
- * Source/cmLocalUnixMakefileGenerator.cxx: fix for debug libs on
- UNIX
-
-2003-08-04 11:48 andy
-
- * Source/cmSystemTools.cxx: ENH: Improve paths on windows
-
-2003-08-04 07:55 andy
-
- * Source/cmSystemTools.cxx: ENH: Fix escaping on windows
-
-2003-08-04 07:12 andy
-
- * Source/cmSystemTools.cxx: ENH: Fix argument parsing on UNIX with
- spaces
-
-2003-08-03 22:41 andy
-
- * Source/cmSiteNameCommand.cxx: ENH: Use new RunCommand
-
-2003-08-03 22:36 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: ENH: Use new RunCommand
-
-2003-08-03 22:34 andy
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx, cmake.cxx, cmaketest.cxx:
- ENH: Use the new RunCommand
-
-2003-08-03 22:33 andy
-
- * Source/: cmBuildNameCommand.cxx, cmTryRunCommand.cxx,
- cmSiteNameCommand.cxx: ENH: Use the new signature
-
-2003-08-03 22:32 andy
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Add back the
- kwsysProcess RunCommand, now is in parallel
-
-2003-08-03 20:47 andy
-
- * Source/cmGetCMakePropertyCommand.cxx,
- Source/cmGetCMakePropertyCommand.h, Source/cmake.h,
- Tests/SystemInformation/CMakeLists.txt,
- Tests/SystemInformation/DumpInformation.cxx: ENH: Add accessor
- for the list of commands
-
-2003-08-02 09:33 andy
-
- * Source/: cmCacheManager.cxx, cmCacheManager.h, cmMakefile.cxx:
- BUG: Fix problem with uninitialized variables
-
-2003-08-01 19:13 andy
-
- * Modules/FindQt.cmake, Tests/Wrapping/CMakeLists.txt: ENH: Make it
- work for QT 2.3 non commercial on windows
-
-2003-08-01 18:53 andy
-
- * Source/cmQTWrapUICommand.cxx: ENH: Make out of source work on
- Windows
-
-2003-08-01 18:52 andy
-
- * Tests/Wrapping/CMakeLists.txt: ENH: Add more debug
-
-2003-08-01 18:52 andy
-
- * Source/CMakeLists.txt: ENH: Fix test for Visual Studio
-
-2003-08-01 17:11 andy
-
- * Modules/FindThreads.cmake: ENH: MAke it work on FreeBSD
-
-2003-08-01 16:48 andy
-
- * Modules/: CheckForPthreads.c, FindThreads.cmake: ENH: Do better
- test for pthreads
-
-2003-08-01 16:48 andy
-
- * Modules/FindQt.cmake: ENH: Fix indentation
-
-2003-08-01 16:47 andy
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ERR: Remove debug
-
-2003-08-01 15:41 hoffman
-
- * Tests/: Complex/Executable/complex.file.cxx,
- ComplexOneConfig/Executable/complex.file.cxx,
- ComplexRelativePaths/Executable/complex.file.cxx: add missing
- file
-
-2003-08-01 15:33 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: Dependency lists
- are now split into multiple make lines to allow longer lists on
- limited make programs.
-
-2003-08-01 15:33 andy
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: Add support for
- -pthread
-
-2003-08-01 15:27 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: Adding link flags
- to an executable that links to shared libraries must be done for
- both EXECUTABLE and WIN32_EXECUTABLE targets.
-
-2003-08-01 14:34 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx,
- Tests/Complex/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt: BUG (85):
- allow . to be in the name of an executable
-
-2003-08-01 14:10 andy
-
- * Source/: cmCacheManager.cxx, cmCacheManager.h, cmMakefile.cxx,
- cmake.cxx: ENH: Allow specifying cmake variables on the command
- line without specifying the type Bug #118 - Specifying cache
- entries with -D should not need the type
-
-2003-08-01 14:10 martink
-
- * Source/cmLocalUnixMakefileGenerator.cxx: all Makefiles now have
- both full path to exe and short version
-
-2003-08-01 13:54 martink
-
- * Source/cmUtilitySourceCommand.cxx: fix for utility command
- without EXECUTABLE_OUTPUT_PATH
-
-2003-08-01 13:24 andy
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: Syntax cleanup
-
-2003-08-01 13:13 hoffman
-
- * Source/: cmGlobalNMakeMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator.cxx, cmLocalUnixMakefileGenerator.h:
- ENH: allow lib prefix for to stay for nmake and borland make as
- it is not a system prefix
-
-2003-08-01 13:00 martink
-
- * CMakeLists.txt: change lib path back to empty
-
-2003-08-01 12:49 andy
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: Fix echo's to use
- @echo. This way verbose mode does not print twice: Bug #45 - add
- @ from echo commands
-
-2003-08-01 11:58 martink
-
- * CMakeLists.txt: made more options advanced
-
-2003-08-01 09:18 andy
-
- * Tests/Wrapping/CMakeLists.txt: ERR: Only link qt to qt executable
-
-2003-08-01 09:11 martink
-
- * Source/cmExportLibraryDependencies.cxx: fix for bug # 101
-
-2003-07-31 16:43 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx: BUG: when creating rule
- files remove the IntDir
-
-2003-07-31 15:32 hoffman
-
- * Source/cmTarget.cxx: ENH: add support for OBJECT_DEPENDS for
- visual studio
-
-2003-07-31 14:46 martink
-
- * Source/cmMakefile.cxx: bug fix for bug # 117
-
-2003-07-31 13:15 andy
-
- * Modules/FindwxWindows.cmake: made a minor bugfix on my
- FindwxWindows.cmake. I capsulated the regular expression
- matching for the libdrs with another IF (line 355). By: Jan
- Woetzel
-
-2003-07-31 08:50 andy
-
- * Tests/Wrapping/CMakeLists.txt: ERR: Attempt to fix wrapping on
- Windows
-
-2003-07-31 08:33 andy
-
- * Tests/Wrapping/Wrap.c: ENH: Fix problem on HP. Whay should K&R be
- default?
-
-2003-07-30 15:38 andy
-
- * Modules/FindQt.cmake: ENH: when linking in QT, we should also
- link DL, since QT uses them
-
-2003-07-30 13:39 andy
-
- * Modules/FindQt.cmake: ENH: QT if it is multi threaded should link
- in threads
-
-2003-07-30 13:28 andy
-
- * Tests/Wrapping/: CMakeLists.txt, foo.ui.in: ENH: Really test uic
- and perform configured uic test
-
-2003-07-30 13:27 andy
-
- * Source/cmQTWrapUICommand.cxx: ENH: Allow qt ui files being it the
- binary dir. Bug #110 - QT_WRAP_UI problem on out-of-source builds
-
-2003-07-30 13:11 andy
-
- * Source/cmaketest.cxx: ENH: Also fail when make
- failsSource/cmaketest.cxx
-
-2003-07-30 13:10 andy
-
- * Tests/Wrapping/: CMakeLists.txt, Wrap.c: ENH: Add executable for
- wrapping test, so that make stage actually passes
-
-2003-07-29 18:06 andy
-
- * Source/cmGlob.cxx: ENH: Speedup globbing and attempt to fix
- cygwin problem
-
-2003-07-29 17:15 andy
-
- * Modules/FindQt.cmake: ENH: Use FindX11 when doing Qt on unix
-
-2003-07-29 13:36 andy
-
- * Modules/Use_wxWindows.cmake: ENH: Add Use file for wxWindows.
- Thanks Jan Woetzel
-
-2003-07-29 07:41 andy
-
- * Modules/FindwxWindows.cmake: ENH: Improved find module. Thank you
- Jan Woetzel
-
-2003-07-29 07:01 andy
-
- * Source/cmAddCustomCommandCommand.cxx: ENH: Fix typo: Bug #100 -
- Spelling correction to an error message
-
-2003-07-28 18:12 hoffman
-
- * Source/: cmLocalUnixMakefileGenerator.cxx, cmMakeDepend.cxx,
- cmMakeDepend.h: ENH: performance fixes for network depends
-
-2003-07-28 14:43 hoffman
-
- * Source/: cmSourceGroupCommand.cxx, cmSourceGroupCommand.h: ENH:
- put back old style call to SOURCE_GROUP, no need to break things
- for this
-
-2003-07-28 13:40 hoffman
-
- * Source/cmake.cxx: BUG: make sure initial cache file read only
- reads one file, and does not look for CMakeLists.txt files on the
- entire disk
-
-2003-07-25 13:39 hoffman
-
- * Source/cmake.cxx: add a better message for the GUI if no
- CMakeLists.txt file is found.
-
-2003-07-25 12:50 hoffman
-
- * Tests/Wrapping/CMakeLists.txt: for unix add x11 and pthreads for
- qt
-
-2003-07-24 11:53 andy
-
- * Source/cmGlob.cxx: ENH: Remove warning
-
-2003-07-24 11:37 martink
-
- * Source/cmLocalUnixMakefileGenerator.cxx: fix for utility depends
- bug#76
-
-2003-07-24 11:33 king
-
- * Source/CMakeLists.txt, Tests/FindPackageTest/CMakeLists.txt,
- Tests/FindPackageTest/FindPackageTest.cxx: ENH: Added
- FindPackageTest to improve coverage.
-
-2003-07-24 11:32 king
-
- * Source/: cmFindPackageCommand.cxx, cmFindPackageCommand.h: ENH:
- Implemented QUIET argument propagation to FOO_FIND_QUIETLY
- setting in FindFOO.cmake module that is found.
-
-2003-07-24 11:12 andy
-
- * Source/cmGlob.cxx: ENH: On windows handle network paths
-
-2003-07-24 11:06 king
-
- * Modules/FindVTK.cmake: ENH: Improved error message for VTK_DIR
- not found to refer to it as a cache entry. Some users thought
- this was supposed to be an environment variable.
-
-2003-07-24 10:58 king
-
- * Source/CMakeLists.txt, Source/cmDumpDocumentation.cxx,
- Tests/CommandLineTest/CMakeLists.txt,
- Tests/CommandLineTest/CommandLineTest.cxx,
- Tests/StringFileTest/CMakeLists.txt: ENH: Added CommandLineTest
- to add coverage for command line arguments to cmake executables.
- This replaces the old DumpDocumentation test.
-
-2003-07-23 18:01 andy
-
- * Tests/StringFileTest/CMakeLists.txt: ENH: More coverage
-
-2003-07-23 17:59 king
-
- * Utilities/CMakeLists.txt: ENH: Added build of documentation for
- CMakeSetup.
-
-2003-07-23 17:27 king
-
- * Source/: cmDocumentation.cxx, cmDocumentation.h: ENH:
- CheckOptions now takes const argv.
-
-2003-07-23 15:45 king
-
- * Source/cmSourceGroupCommand.cxx: ENH: Added backwards
- compatability.
-
-2003-07-23 15:32 king
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx, cmMakefile.cxx,
- cmSourceGroup.cxx, cmSourceGroup.h, cmSourceGroupCommand.cxx,
- cmSourceGroupCommand.h: ENH: Fully implemented SOURCE_GROUP
- command.
-
-2003-07-23 14:31 andy
-
- * Source/: cmCPluginAPI.cxx, cmCPluginAPI.h: ENH: Fix compatibility
-
-2003-07-23 10:39 king
-
- * Source/cmSourceGroupCommand.cxx: BUG: Fixed off-by-one error in
- file list loop. Fix submitted by David A. Karr.
-
-2003-07-23 10:26 andy
-
- * Source/cmGlob.cxx: ENH: On windows and apple handle
- lowercase/upercase file name problem
-
-2003-07-23 09:10 king
-
- * Tests/StringFileTest/CMakeLists.txt: ENH: Added more verbose
- output of what globbing results.
-
-2003-07-23 08:58 king
-
- * Utilities/CMakeLists.txt: BUG: Don't install ccmake documentation
- if no ccmake was built.
-
-2003-07-23 08:37 king
-
- * bootstrap: ENH: Adding forced settings for prefix, docdir,
- mandir, and datadir.
-
-2003-07-22 17:09 andy
-
- * DartConfig.cmake: ENH: Direct link to cmake bugs
-
-2003-07-22 13:53 andy
-
- * Source/cmCPluginAPI.cxx: ERR: Fix error on bad C++ compiler that
- do not handle return void
-
-2003-07-22 13:15 andy
-
- * Source/cmTarget.cxx: BUG: Fix copy/paste typo
-
-2003-07-22 13:14 andy
-
- * Source/: cmCPluginAPI.cxx, cmCPluginAPI.h: ENH: Add DisplayStatus
-
-2003-07-22 12:21 andy
-
- * Tests/: LoadCommand/LoadedCommand.cxx,
- LoadCommand/CMakeCommands/cmTestCommand.c,
- LoadCommandOneConfig/LoadedCommand.cxx,
- LoadCommandOneConfig/CMakeCommands/cmTestCommand.c: ENH: More
- coverage
-
-2003-07-22 11:17 andy
-
- * Tests/StringFileTest/CMakeLists.txt: ENH: More coverage
-
-2003-07-22 10:45 andy
-
- * Tests/StringFileTest/CMakeLists.txt: ENH: Increase coverage
-
-2003-07-21 17:14 king
-
- * Utilities/CMakeLists.txt: ENH: Added generation of ccmake
- documentation on UNIX.
-
-2003-07-21 17:13 king
-
- * Source/CursesDialog/ccmake.cxx: ENH: Added introduction paragraph
- to documentation.
-
-2003-07-21 16:38 king
-
- * CMakeLists.txt, bootstrap, Modules/CMakeLists.txt,
- Modules/Platform/CMakeLists.txt, Source/CMakeLists.txt,
- Source/cmCommands.cxx, Source/cmConfigure.cmake.h.in,
- Source/cmake.cxx, Templates/CMakeLists.txt,
- Utilities/CMakeLists.txt: ENH: Added optional configuration of
- data/doc/man dirs. This will be useful for package maintainers.
-
-2003-07-21 16:37 king
-
- * Source/: InitialConfigureFlags.cmake.in, cmConfigure.h.in:
- Removing old file. This was used by old configure script which
- has been removed.
-
-2003-07-21 15:29 andy
-
- * Source/cmGlob.cxx, Tests/StringFileTest/CMakeLists.txt: ENH: fix
- glob on windows and add glob recurse test
-
-2003-07-21 15:02 king
-
- * Source/CMakeLists.txt: ENH: Added generation of cmake
- documentation during build preocess.
-
-2003-07-21 14:58 king
-
- * Source/cmDocumentation.cxx: BUG: Text dump of documentation
- should be in ascii mode.
-
-2003-07-21 14:57 king
-
- * Source/cmAddCustomTargetCommand.h: BUG: Fixed documentation
- formatting.
-
-2003-07-21 14:44 andy
-
- * Source/: cmSourceFilesCommand.cxx, cmSourceFilesCommand.h: ENH:
- Use new deprecation mechanism
-
-2003-07-21 14:43 andy
-
- * Source/cmFileCommand.h: ENH: Fix comment
-
-2003-07-21 14:42 andy
-
- * Source/: cmCommand.h, cmMakefile.cxx: ENH: Initial framework for
- deprecated commands
-
-2003-07-21 13:48 andy
-
- * Tests/StringFileTest/CMakeLists.txt: ENH: add more coverage tests
-
-2003-07-21 13:46 andy
-
- * Source/cmGlob.cxx: ENH: Handle ^ as [^fu]
-
-2003-07-17 14:56 andy
-
- * Tests/StringFileTest/CMakeLists.txt: ENH: Add additional new line
- after the string to match the change in file command
-
-2003-07-17 14:56 andy
-
- * Source/cmFileCommand.cxx: ENH: Remove extra new line after the
- written string
-
-2003-07-17 14:54 andy
-
- * Modules/: CMakeTestCCompiler.cmake, CMakeTestCXXCompiler.cmake,
- CheckFunctionExists.cmake, CheckIncludeFile.cmake,
- CheckIncludeFileCXX.cmake, CheckIncludeFiles.cmake,
- CheckLibraryExists.cmake, CheckSymbolExists.cmake,
- CheckTypeSize.cmake, CheckVariableExists.cmake,
- TestBigEndian.cmake, TestCXXAcceptsFlag.cmake: ENH: Extra new
- line after output
-
-2003-07-16 15:38 hoffman
-
- * Modules/CMakeDetermineSystem.cmake, Source/cmGlobalGenerator.cxx:
- ENH: set CMAKE_SYSTEM_VERSION for windows
-
-2003-07-16 14:52 king
-
- * Source/: cmFindPackageCommand.cxx, cmFindPackageCommand.h: ENH:
- Added QUIET optional argument to block error message when _DIR
- variable is not set. Also removed upper-casing of package name.
-
-2003-07-16 11:38 king
-
- * Tests/SystemInformation/: DumpInformation.cxx,
- DumpInformation.h.in: ENH: Added dump of more files. Improved
- robustness of dump.
-
-2003-07-15 12:52 hoffman
-
- * Source/cmAddCustomCommandCommand.cxx: ENH: better error checking
-
-2003-07-14 10:33 king
-
- * Source/cmMakefile.cxx: BUG: Custom commands should have variables
- expanded before comparing with previously added custom commands.
-
-2003-07-14 10:13 martink
-
- * Source/cmFLTKWrapUICommand.cxx: some updates
-
-2003-07-14 09:44 martink
-
- * Source/cmFLTKWrapUICommand.cxx: some updates
-
-2003-07-14 09:31 martink
-
- * Source/: cmFLTKWrapUICommand.cxx, cmFLTKWrapUICommand.h: some
- updates
-
-2003-07-14 09:15 andy
-
- * Source/: cmFileCommand.cxx, cmFileCommand.h, cmGlob.cxx,
- cmGlob.h: ENH: Recurse subdirectories
-
-2003-07-11 17:21 king
-
- * bootstrap: ENH: Removed cmsys include directory from bootstrap
- build of kwsys. It is no longer needed.
-
-2003-07-11 16:29 king
-
- * Utilities/Release/cmake_release.sh: BUG: Update of release
- utilities must maintain tag.
-
-2003-07-11 14:14 andy
-
- * Modules/: CMakeTestCCompiler.cmake, CMakeTestCXXCompiler.cmake,
- CheckFunctionExists.cmake, CheckIncludeFile.cmake,
- CheckIncludeFileCXX.cmake, CheckIncludeFiles.cmake,
- CheckLibraryExists.cmake, CheckSymbolExists.cmake,
- CheckTypeSize.cmake, CheckVariableExists.cmake, Dart.cmake,
- TestBigEndian.cmake, TestCXXAcceptsFlag.cmake: ENH: Replace
- WRITE_FILE with FILE(WRITE and FILE(APPEND. Replace
- MAKE_DIRECTORY with FILE(MAKE_DIRECTORY, replace STRING(ASCII
- things
-
-2003-07-10 23:22 king
-
- * Source/cmake.h: ERR: Removed duplicate generator documentation.e
-
-2003-07-10 23:15 king
-
- * Source/: cmDocumentation.cxx, cmDocumentation.h, cmakemain.cxx:
- ENH: Added SEE ALSO section to generated man page. Minor
- formatting improvements for generated text-only documentation.
-
-2003-07-10 23:14 king
-
- * Source/cmake.h: ENH: Added CMAKE_STANDARD_INTRODUCTION macro
- defining standard documentation for inclusion in every binary's
- documentation.
-
-2003-07-10 23:14 king
-
- * Source/cmGlobalUnixMakefileGenerator.cxx: ENH: Wrote basic
- description in full documentation block.
-
-2003-07-10 14:48 andy
-
- * Tests/StringFileTest/StringFile.cxx: ENH: Add missing include
-
-2003-07-10 14:46 king
-
- * Source/kwsys/CMakeLists.txt: ERR: Generated source files need
- access to kwsysPrivate.h. Just copy it to the build tree.
-
-2003-07-10 14:35 andy
-
- * Source/cmStringCommand.cxx: ERR: Remove unused variable
-
-2003-07-10 14:32 king
-
- * Source/kwsys/: Base64.c, CMakeLists.txt, Directory.cxx,
- EncodeExecutable.c, ProcessUNIX.c, ProcessWin32.c,
- RegularExpression.cxx, SystemTools.cxx, kwsysPrivate.h: ENH:
- Added use of KWSYS_HEADER macro in c and cxx files to include
- kwsys headers through their configured namespace.
-
-2003-07-10 14:29 andy
-
- * Tests/StringFileTest/CMakeLists.txt,
- Tests/StringFileTest/InputFile.h.in,
- Tests/StringFileTest/StringFile.cxx, Source/CMakeLists.txt: ENH:
- Add test for string and file commands
-
-2003-07-10 13:25 andy
-
- * Source/: cmStringCommand.cxx, cmStringCommand.h: ENH: Add upper
- and lower case support. Close Bug #79 - STRING TOUPPER and
- TOLOWER
-
-2003-07-09 17:25 king
-
- * Source/cmSystemTools.cxx: ENH: Added escape support for ( and ).
-
-2003-07-09 17:17 king
-
- * Source/: cmListFileCache.cxx, cmSystemTools.cxx: ENH: Added
- support for # characters inside quoted arguments and for escaping
- # in a non-quoted argument. Improved parsing speed by not
- compiling regular expressions on blank lines.
-
-2003-07-09 16:18 king
-
- * Source/kwsys/ProcessUNIX.c: ERR: Using strncpy instead of
- snprintf for portability.
-
-2003-07-08 16:33 andy
-
- * Source/: cmFileCommand.cxx, cmFileCommand.h: ENH: Add
- MAKE_DIRECTORY and modify documentation
-
-2003-07-08 16:27 andy
-
- * Source/cmGlob.cxx: ENH: Remove commented code
-
-2003-07-08 14:18 andy
-
- * bootstrap, Source/CMakeLists.txt, Source/cmFileCommand.cxx,
- Source/cmFileCommand.h, Source/cmGlob.cxx, Source/cmGlob.h: ENH:
- Add globbing to FILE command
-
-2003-07-08 13:27 king
-
- * Source/cmMakefile.cxx: BUG#65: Fixed inheritance of
- CMAKE_CURRENT_SOURCE_DIR and CMAKE_CURRENT_BINARY_DIR.
-
-2003-07-08 09:21 andy
-
- * Source/kwsys/CMakeLists.txt: ENH: Fix example
-
-2003-07-08 00:28 king
-
- * Source/cmDocumentation.cxx: ERR: Added missing std::.
-
-2003-07-07 23:20 king
-
- * CMakeLists.txt, Source/cmDocumentation.cxx,
- Source/cmDumpDocumentation.cxx, Source/cmStandardIncludes.h: ENH:
- Improved name of cmake version variables. They are now
- CMake_VERSION (major.minor) and CMake_VERSION_FULL
- (major.minor.patch).
-
-2003-07-07 22:54 king
-
- * Source/cmStringCommand.h: BUG: Removed extra newlines from help
- text.
-
-2003-07-07 22:44 king
-
- * Source/: cmDocumentation.cxx, cmDocumentation.h, cmakemain.cxx,
- CursesDialog/ccmake.cxx: ENH: Added support to write multiple
- help options with one command line. Output files can now also be
- specified for the help options.
-
-2003-07-07 22:41 king
-
- * Source/kwsys/CMakeLists.txt: ERR: Removed useless set.
-
-2003-07-07 22:41 king
-
- * Source/cmCommands.cxx: ENH: Made ADD_DEPENDENCIES available from
- bootstrapped cmake. It will be needed to build cmake.
-
-2003-07-07 21:52 king
-
- * Source/: cmDocumentation.cxx, cmDocumentation.h,
- cmGlobalBorlandMakefileGenerator.cxx,
- cmGlobalBorlandMakefileGenerator.h,
- cmGlobalCodeWarriorGenerator.cxx, cmGlobalCodeWarriorGenerator.h,
- cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalNMakeMakefileGenerator.cxx,
- cmGlobalNMakeMakefileGenerator.h,
- cmGlobalUnixMakefileGenerator.cxx,
- cmGlobalUnixMakefileGenerator.h,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio6Generator.h,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio71Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h, cmake.cxx, cmake.h,
- cmakemain.cxx: ENH: Registered global generators are now kept in
- a table in the cmake instance. Added support for documentation
- with a Generators section.
-
-2003-07-07 18:27 king
-
- * Source/cmSystemTools.cxx: BUG: Parsing of arguments from string
- by RunCommand before passing to Process execution does not work
- with backslashes in path names. Until this is fixed, we cannot
- use Process execution from kwsys.
-
-2003-07-07 17:52 andy
-
- * bootstrap: ENH: Fix bootstrap to include ProcessUNIX.c
-
-2003-07-07 17:47 andy
-
- * Source/: cmCommands.cxx, cmFileCommand.cxx, cmFileCommand.h: ENH:
- Start working on a general file manipulation command
-
-2003-07-07 17:45 andy
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH: Add
- optional argument to GetLineFromStream which can let the caller
- know whether there was a new line character at the end of the
- line that was just read
-
-2003-07-07 13:36 andy
-
- * Docs/cmake-syntax.vim: Initial import of VIM syntax highlighting
- file
-
-2003-07-07 09:38 king
-
- * Source/kwsys/ProcessWin32.c: ENH: Made call to FormatMessage more
- robust.
-
-2003-07-07 09:16 king
-
- * Source/cmSystemTools.cxx: ENH: Using new Process
- SetWorkingDirectory method instead of manually implementing it.
-
-2003-07-07 09:12 king
-
- * Source/kwsys/: Process.h.in, ProcessUNIX.c: ENH: Implemented
- SetWorkingDirectory method.
-
-2003-07-07 09:10 king
-
- * Source/kwsys/ProcessWin32.c: ENH: Implemented SetWorkingDirectory
- method on Windows.
-
-2003-07-07 08:41 king
-
- * Source/cmSystemTools.cxx: ENH: Using kwsys Process implementation
- to implement RunCommand.
-
-2003-07-07 08:36 andy
-
- * Source/kwsys/: Process.h.in, ProcessUNIX.c: ENH: Start working on
- Working Directory support
-
-2003-07-06 20:40 king
-
- * Source/kwsys/ProcessWin32.c: ENH: Using GetTempPath instead of
- TEMP environment variable to get a location to write the Win9x
- forwarding executable.
-
-2003-07-03 18:33 king
-
- * Source/kwsys/ProcessWin32.c: BUG: Argument parsers do not always
- remove double quotes from around an argument that has no spaces.
-
-2003-07-03 12:50 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: ENH: add linker flags
-
-2003-07-03 11:39 hoffman
-
- * Source/cmCreateTestSourceList.cxx: ENH: null terminate at the end
- of the list
-
-2003-07-03 07:58 king
-
- * Source/kwsys/CMakeLists.txt: BUG: Install target for standard
- header wrappers must point at the std subdirectory in the
- installation.
-
-2003-07-02 10:48 andy
-
- * DartConfig.cmake: ENH: Add proper links to bugtracker
-
-2003-07-02 10:37 andy
-
- * DartConfig.cmake: ENH: Add links to bugtracker
-
-2003-07-02 08:35 king
-
- * Source/kwsys/ProcessWin32.c: ERR: Added cast to remove warning.
- We know the length of the string will not be beyond 2^31.
-
-2003-07-01 13:32 king
-
- * Source/kwsys/Base64.c: ERR: Added casts to remove type conversion
- warnings. Pointer differences can be 64-bit, but unsigned long
- is 32-bit on many platforms. We know we are not traversing more
- data than can be handled by an unsigned long, though, because the
- length argument is an unsigned long.
-
-2003-07-01 13:27 king
-
- * Source/kwsys/: ProcessFwd9x.c, ProcessWin32.c: ERR: Should use %p
- to pass HANDLE values on a command line, not %d.
-
-2003-07-01 13:27 king
-
- * Source/kwsys/SystemTools.cxx: ERR: Removed unreachable code.
-
-2003-07-01 11:40 king
-
- * Source/kwsys/: Base64.h.in, Process.h.in: ERR: Reduced
- requirements on preprocessor for export macro due to limitations
- of Mac preprocessor. The preprocessor can be fixed by using
- -no-cpp-precomp, but we don't want to require that option for
- every source file that includes our headers.
-
-2003-07-01 08:54 king
-
- * Source/kwsys/EncodeExecutable.c: ERR: Added explicit cast from
- size_t to int. We know that the data will not be out of range.
-
-2003-06-30 10:50 andy
-
- * bootstrap: ERR: Fix changes in kwsys for Configure.h and
- StandardIncludes.hxx
-
-2003-06-30 10:44 andy
-
- * Source/kwsys/: Base64.c, ProcessFwd9x.c, ProcessWin32.c: ERR:
- Remove warnings on Windows
-
-2003-06-30 10:30 king
-
- * Source/kwsys/: Base64.h.in, CMakeLists.txt, Configure.h.in,
- Directory.cxx, Directory.hxx.in, EncodeExecutable.c,
- Process.h.in, ProcessWin32.c, RegularExpression.cxx,
- RegularExpression.hxx.in, SystemTools.hxx.in: ENH: Added DLL
- support.
-
-2003-06-30 10:12 martink
-
- * Tests/CustomCommand/CMakeLists.txt: modified code to match cmake
- mode
-
-2003-06-30 10:07 king
-
- * Source/kwsys/StandardIncludes.hxx.in: Removing old file.
-
-2003-06-30 09:56 andy
-
- * bootstrap: ENH: Fix checking for C++ compiler on Mac, remove
- cmConfigure.h.tmp, so that nothing bad can happen if configure is
- interrupted, reports kwsys sources in cmConfigure.h
-
-2003-06-30 08:49 king
-
- * Source/kwsys/Base64.h.in: ENH: Updated comments for doxygen.
-
-2003-06-30 08:48 king
-
- * Source/kwsys/Base64.c: BUG: Should define KWSYS_IN_BASE64_C, not
- KWSYS_IN_PROCESS_C.
-
-2003-06-30 08:48 king
-
- * Source/kwsys/CMakeLists.txt: ENH: Using FOREACH to shorten
- enabling of C components.
-
-2003-06-29 21:42 andy
-
- * CMakeLists.txt, Source/kwsys/Base64.c, Source/kwsys/Base64.h.in,
- Source/kwsys/CMakeLists.txt: ENH: Initial import of Base64
-
-2003-06-29 20:30 king
-
- * CMakeLists.txt: ENH: Enabling build of kwsys's Process class.
- This will be needed for ctest.
-
-2003-06-29 20:20 king
-
- * Docs/cmake-mode.el: ENH: Added comment-region support.
-
-2003-06-27 09:48 king
-
- * CMakeLists.txt: ERR: Disabling multiply defined symbols warning
- for linking executables on IRIX. The compiler's prelinker does
- not add weak symbols, so template instantiations are duplicated.
-
-2003-06-27 08:46 martink
-
- * Source/: cmAuxSourceDirectoryCommand.cxx,
- cmTryCompileCommand.cxx: fix compiler warnings
-
-2003-06-26 13:39 king
-
- * Source/kwsys/CMakeLists.txt: ENH: Updated documentation to
- describe enabling of classes.
-
-2003-06-26 09:44 andy
-
- * bootstrap: ENH: Attempt to handle OSF compiler flags
-
-2003-06-25 09:32 king
-
- * Source/kwsys/testProcess.c: ERR: Fixed use of non-constant
- initializer.
-
-2003-06-25 08:29 king
-
- * Source/kwsys/Directory.cxx: ERR: Fixed conversion warning.
-
-2003-06-24 21:37 lorensen
-
- * Source/kwsys/SystemTools.cxx: ERR: portability.
-
-2003-06-24 16:35 martink
-
- * Source/kwsys/SystemTools.cxx: compiler fix
-
-2003-06-24 15:24 martink
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: moved depend code into
- cmTarget
-
-2003-06-24 15:21 martink
-
- * Source/: cmMakefile.cxx, cmMakefile.h, kwsys/SystemTools.cxx:
- performance improvements
-
-2003-06-24 15:11 martink
-
- * Source/cmMacroCommand.cxx: performance improvements
-
-2003-06-24 15:10 martink
-
- * Source/: cmTarget.cxx, cmTarget.h: moved function into cmTarget
-
-2003-06-24 10:16 king
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ERR: Renamed
- superclass typedef from SystemTools to Superclass to avoid
- conflict across platforms.
-
-2003-06-24 09:02 king
-
- * Source/kwsys/SystemTools.cxx: ERR: std->kwsys_std.
-
-2003-06-24 08:19 king
-
- * Source/cmSystemTools.h: ERR: Typedefs are not inherited on SGI
- and Borland.
-
-2003-06-23 16:26 martink
-
- * Source/: cmForEachCommand.cxx, cmMacroCommand.cxx: perf
- improvement
-
-2003-06-23 16:25 martink
-
- * Source/cmCustomCommand.h: performance improvement
-
-2003-06-23 14:10 king
-
- * CMakeLists.txt, bootstrap, Source/CMakeLists.txt,
- Source/cmBuildNameCommand.cxx, Source/cmCTest.cxx,
- Source/cmCacheManager.cxx, Source/cmConfigureFileCommand.cxx,
- Source/cmIfCommand.cxx, Source/cmListFileCache.cxx,
- Source/cmLoadCacheCommand.cxx,
- Source/cmLocalCodeWarriorGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmMakeDepend.cxx, Source/cmMakeDepend.h,
- Source/cmMakefile.cxx, Source/cmRegularExpression.cxx,
- Source/cmRegularExpression.h, Source/cmSiteNameCommand.cxx,
- Source/cmSourceGroup.h, Source/cmStringCommand.cxx,
- Source/cmSystemTools.cxx, Source/cmUseMangledMesaCommand.cxx,
- Source/cmaketest.cxx: ENH: Merged use of the kwsys
- RegularExpression class instead of cmRegularExpression.
-
-2003-06-23 14:05 king
-
- * Source/kwsys/RegularExpression.hxx.in: ERR: Fixed documentation
- to read RegularExpression instead of cmRegularExpression.
-
-2003-06-23 11:16 martink
-
- * Source/cmTarget.cxx: removed some no longer required code
-
-2003-06-23 08:58 king
-
- * CMakeLists.txt, bootstrap, Source/CMakeLists.txt,
- Source/cmAuxSourceDirectoryCommand.cxx, Source/cmDirectory.cxx,
- Source/cmDirectory.h, Source/cmMakeDirectoryCommand.cxx,
- Source/cmMakefile.cxx, Source/cmSystemTools.cxx,
- Source/cmSystemTools.h, Source/cmTryCompileCommand.cxx,
- Source/CursesDialog/cmCursesPathWidget.cxx,
- Tests/Complex/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt: ENH: Merged
- use of kwsys library.
-
-2003-06-23 08:58 king
-
- * Makefile.in, configure, configure.in, Source/Makefile.in: ENH:
- Configure script now just invokes bootstrap script.
-
-2003-06-23 08:56 king
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: ENH: Removed
- cmake-specific functions.
-
-2003-06-23 08:56 king
-
- * Source/kwsys/CMakeLists.txt: BUG: Need include regular expression
- to match all files.
-
-2003-06-21 11:57 andy
-
- * bootstrap: ENH: Add copyright, cmConfigure.h is now touched only
- when it is modified, remove some spaces from output, add
- procedure that copies file and replaces atstring with another
- string
-
-2003-06-20 20:33 martink
-
- * Source/cmMakefile.cxx: fix to expand variables in custom command
- outputs and main dependencies
-
-2003-06-20 14:10 king
-
- * Source/kwsys/CMakeLists.txt: ENH: Changed configuration of header
- directory to specify it without the namespace.
-
-2003-06-20 14:10 hoffman
-
- * Docs/cmake-mode.el: BUG: fix highlight for comments in multiple
- buffers
-
-2003-06-20 13:56 martink
-
- * Source/cmMakefile.cxx: bug in not expanding variables for custom
- commands in targets
-
-2003-06-20 11:23 martink
-
- * Source/cmMakefile.cxx: minor perf improvement
-
-2003-06-19 18:57 king
-
- * Source/kwsys/: CMakeLists.txt, Configure.hxx.in,
- RegularExpression.hxx.in, SystemTools.hxx.in,
- kwsys_std_fstream.h.in, kwsys_std_iosfwd.h.in,
- kwsys_std_iostream.h.in, kwsys_std_sstream.h.in: ENH: Added full
- configuration of namespace even for Configure.hxx macro
- definitions.
-
-2003-06-19 16:23 hoffman
-
- * Docs/cmake-mode.el: add a comment
-
-2003-06-19 15:05 king
-
- * Docs/: cmake-indent.vim, cmake-mode.el: Added copyright.
-
-2003-06-19 14:37 andy
-
- * Docs/cmake-indent.vim: Initial import: indentation file for vim
-
-2003-06-19 14:30 king
-
- * Docs/cmake-mode.el: Minor tweaks for anal cases of indentation.
-
-2003-06-19 14:27 martink
-
- * Source/cmMakefile.cxx: bug fix for finding source files
-
-2003-06-19 14:27 martink
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: new function
-
-2003-06-19 14:17 king
-
- * Docs/cmake-mode.el: BUG: Don't open a block if a command starts
- with IF in its name.
-
-2003-06-19 13:38 martink
-
- * Docs/cmake-mode.el: fix to use function-name
-
-2003-06-19 13:23 king
-
- * Docs/cmake-mode.el: Fixed slow regex for indentation.
-
-2003-06-19 11:11 king
-
- * Docs/cmake-mode.el: ENH: Wrote more robust regular expressions
- for indenting.
-
-2003-06-19 11:07 martink
-
- * Docs/cmake-mode.el: emacs mode
-
-2003-06-18 17:28 king
-
- * Source/kwsys/kwsysHeaderDump.pl: Tool to dump macros for
- redefining C header namespaces.
-
-2003-06-18 17:27 king
-
- * Source/kwsys/: CMakeLists.txt, testProcess.c: ENH: Added test for
- Process implementation.
-
-2003-06-18 17:27 king
-
- * Source/kwsys/ProcessWin32.c: BUG: Must return Exception status
- correctly.
-
-2003-06-18 17:19 king
-
- * Source/kwsys/ProcessUNIX.c: Removed Exception_Abort because there
- is no windows version. Also made ExitValue consistent with
- windows when a signal kills the process.
-
-2003-06-18 17:19 king
-
- * Source/kwsys/Process.h.in: Removed Exception_Abort because there
- is no windows version. Also removed stray typedef keywords.
-
-2003-06-18 17:06 king
-
- * Source/kwsys/: Process.h.in, ProcessUNIX.c, ProcessWin32.c,
- test1.cxx: ENH: Added documentation to interface. Finished
- process exit code interpretation implementation prototype.
-
-2003-06-18 11:43 hoffman
-
- * Source/cmStringCommand.h: remove non-html safe stuff
-
-2003-06-18 09:13 hoffman
-
- * Source/cmMakefile.cxx: BUG: fix not being able to find generated
- files in the binary tree
-
-2003-06-17 17:13 martink
-
- * Source/cmLocalVisualStudio7Generator.cxx: fix for bad assumption
- on custom rules
-
-2003-06-17 16:54 martink
-
- * Source/cmLocalVisualStudio6Generator.cxx: fix for bad assumption
-
-2003-06-17 15:13 martink
-
- * Source/cmLocalVisualStudio6Generator.cxx: fix for bad assumption
-
-2003-06-16 10:20 martink
-
- * Source/cmLocalVisualStudio6Generator.cxx: fix for vs6 rule files
-
-2003-06-13 16:59 king
-
- * Source/cmMakefile.cxx: BUG: Fixed translation of relative path
- names to full path names.
-
-2003-06-13 16:47 king
-
- * Source/cmSetSourceFilesPropertiesCommand.cxx: BUG: Fixed crash
- when source file cannot be looked up correctly.
-
-2003-06-13 14:15 king
-
- * Source/cmake.cxx: BUG: Fixed check for existence of
- CMakeLists.txt file in top-level source directory before first
- configure.
-
-2003-06-12 16:43 king
-
- * Modules/Platform/Windows-bcc32.cmake: BUG: Stack size in
- generated programs should be 10 meg, not 256.
-
-2003-06-12 16:18 king
-
- * Source/kwsys/ProcessWin32.c: ERR: Added error check for malloc of
- process control structure.
-
-2003-06-12 15:58 king
-
- * Source/kwsys/ProcessWin32.c: ERR: Using GetCurrentProcessId
- instead of _getpid so we don't need to include the system
- process.h header. Also creating pipe threads with 1K stacks to
- save memory.
-
-2003-06-11 11:00 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: Uninitialized
- std::string returns bad pointers from c_str() on some platforms.
-
-2003-06-11 10:21 king
-
- * Source/kwsys/CMakeLists.txt: ENH: EXECUTABLE_OUTPUT_PATH is now
- always set to get around cmake 1.6.7 dependency problems. Moved
- default header directory inside the build tree instead of up one
- level. User projects can now set the header directory.
-
-2003-06-11 10:11 hoffman
-
- * Modules/CMakeDetermineSystem.cmake: ENH: add processor type of
- win32
-
-2003-06-11 10:07 hoffman
-
- * Modules/: CMakeDetermineSystem.cmake, CMakeSystem.cmake.in: ENH:
- add CMAKE_SYSTEM_PROCESSOR
-
-2003-06-11 09:45 king
-
- * Source/kwsys/CMakeLists.txt: ERR: Added custom command that takes
- advantage of new syntax.
-
-2003-06-11 09:44 king
-
- * Source/kwsys/ProcessWin32.c: ERR: Removed unused variables.
-
-2003-06-11 09:44 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: When executable
- output path is not set, we still need to generate the full path
- to the executable target.
-
-2003-06-10 17:39 king
-
- * Source/kwsys/CMakeLists.txt: ERR: Added work-around for cmake
- 1.6.7 bug in borland makefile generator.
-
-2003-06-10 16:56 king
-
- * Source/kwsys/CMakeLists.txt: BUG: Need to add ANSI C flags for
- some platforms.
-
-2003-06-10 16:55 king
-
- * Source/kwsys/ProcessUNIX.c: ERR: Added static specifier to static
- function definitions to quiet warnings on HP compiler.
-
-2003-06-10 16:15 king
-
- * Source/kwsys/ProcessWin32.c: BUG: Don't show a console
- application's window.
-
-2003-06-10 15:50 king
-
- * Source/kwsys/test1.cxx: ENH: Added use of process execution.
-
-2003-06-10 15:46 king
-
- * Source/kwsys/: CMakeLists.txt, EncodeExecutable.c, Process.h.in,
- ProcessFwd9x.c, ProcessUNIX.c, ProcessWin32.c: ENH: Added Process
- execution implementation.
-
-2003-06-10 15:45 king
-
- * Source/kwsys/SystemTools.cxx: ENH: Moved disabling of warnings to
- after kwsys includes.
-
-2003-06-10 15:44 king
-
- * Source/kwsys/kwsys_std.h.in: ENH: Disabled warning 4786.
-
-2003-06-06 09:58 andy
-
- * Modules/FindVTK.cmake: BUG: When VTK is not found, it should be
- fatal error
-
-2003-06-06 09:57 andy
-
- * Source/CursesDialog/cmCursesMainForm.cxx: BUG: When only loading
- ccmake cache, do not allow generate
-
-2003-06-06 09:06 martink
-
- * Source/cmCreateTestSourceList.cxx: undid change because other
- changes make it no longer neccesary
-
-2003-06-05 16:45 martink
-
- * Source/: cmMakefile.cxx, cmMakefile.h: more custom command
-
-2003-06-05 16:12 martink
-
- * Source/cmMakefile.cxx: more changes to support full paths
-
-2003-06-05 15:28 martink
-
- * Source/cmMakefile.cxx: perf improvement
-
-2003-06-05 15:18 martink
-
- * Source/cmMakefile.cxx: more changes to handle full paths
- correctly
-
-2003-06-05 14:48 martink
-
- * Source/cmQTWrapUICommand.cxx: minor update for new custom
- commands
-
-2003-06-05 14:40 martink
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx, cmMakefile.cxx, cmTarget.cxx:
- more crazt changes source files now must match with full path
-
-2003-06-05 14:37 martink
-
- * Source/cmITKWrapTclCommand.cxx: updated for new custom command
-
-2003-06-05 14:37 martink
-
- * Source/cmCreateTestSourceList.cxx: minor fix
-
-2003-06-04 19:04 martink
-
- * Source/cmMakefile.cxx: hopeful fix for backwards compat
-
-2003-06-04 18:50 martink
-
- * Source/cmLocalVisualStudio6Generator.cxx: minor fix
-
-2003-06-04 16:06 martink
-
- * Source/cmMakefile.cxx: tricky fix for backwards compat
-
-2003-06-04 14:25 hoffman
-
- * Tests/CustomCommand/: generator.cxx, wrapper.cxx: minor fixes
-
-2003-06-04 14:01 hoffman
-
- * Source/cmMakefile.cxx: better error reporting
-
-2003-06-04 14:00 hoffman
-
- * Source/cmMakefile.cxx: ENH: allow duplicate commands with the
- same output to be reduced automatically to one command
-
-2003-06-04 13:55 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx: bug fix for vs6 custom
- commands
-
-2003-06-04 13:54 hoffman
-
- * Templates/UtilityHeader.dsptemplate: fix for new custom commands
-
-2003-06-04 13:42 hoffman
-
- * Source/: cmCustomCommand.cxx, cmCustomCommand.h,
- cmLocalVisualStudio7Generator.cxx, cmMakefile.cxx: ENH: allow
- duplicate commands with the same output to be reduced
- automatically to one command
-
-2003-06-04 11:46 hoffman
-
- * Source/cmAddCustomCommandCommand.h: command should nto be
- inherited
-
-2003-06-04 10:46 hoffman
-
- * Tests/Wrapping/CMakeLists.txt: minor fix
-
-2003-06-04 10:13 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx: bug fix
-
-2003-06-04 09:02 hoffman
-
- * Tests/CustomCommand/: CMakeLists.txt, generator.c, generator.cxx,
- wrapper.c, wrapper.cxx: fixes for HP
-
-2003-06-04 09:00 king
-
- * bootstrap: ERR: Cannot use iostream.h for strict C++ compiler
- sanity check. Using a small class instead.
-
-2003-06-04 08:42 martink
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: compielr warnings
-
-2003-06-04 08:40 martink
-
- * Source/cmMakefile.cxx: compielr errors on como
-
-2003-06-03 14:55 martink
-
- * Source/: cmCustomCommand.cxx, cmLocalUnixMakefileGenerator.cxx,
- cmMakefile.cxx, cmSourceGroup.cxx: warning fixes
-
-2003-06-03 14:45 hoffman
-
- * Modules/Dart.cmake: ENH: add all targets for dashboard build
- types
-
-2003-06-03 10:47 martink
-
- * Source/: cmAddCustomCommandCommand.h: better docs
-
-2003-06-03 10:33 martink
-
- * Tests/CustomCommand/: CMakeLists.txt, doc1.tex, foo.in,
- generator.c, wrapper.c, wrapped.h: new test
-
-2003-06-03 10:30 martink
-
- * Source/: CMakeLists.txt, cmAddCustomCommandCommand.cxx,
- cmAddCustomCommandCommand.h, cmAddCustomTargetCommand.cxx,
- cmAddCustomTargetCommand.h, cmCPluginAPI.cxx, cmCPluginAPI.h,
- cmCustomCommand.cxx, cmCustomCommand.h,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx,
- cmLocalUnixMakefileGenerator.cxx, cmLocalUnixMakefileGenerator.h,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio6Generator.h,
- cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h, cmMakefile.cxx, cmMakefile.h,
- cmSetSourceFilesPropertiesCommand.cxx, cmSourceFile.h,
- cmSourceGroup.cxx, cmSourceGroup.h, cmSystemTools.cxx,
- cmSystemTools.h, cmTarget.h: yikes added new custom command
- support
-
-2003-06-02 16:37 martink
-
- * Docs/: CMake04.rtf, CMake12p2.rtf, CMake14.rtf, CMake16.rtf: add
- release docs to cvs
-
-2003-05-29 15:30 martink
-
- * Source/: cmGetSourceFilePropertyCommand.cxx,
- cmGetTargetPropertyCommand.cxx: minor bug fix
-
-2003-05-29 11:14 andy
-
- * Source/CursesDialog/: ccmake.cxx, cmCursesMainForm.cxx,
- cmCursesMainForm.h: ENH: On envocation of ccmake check if
- directories are correct, but do not rerun configure
-
-2003-05-29 11:14 andy
-
- * Source/: cmake.cxx, cmake.h: ENH: Abstract pre configure check in
- a separate method
-
-2003-05-29 09:34 hoffman
-
- * Source/: cmCTest.cxx, cmRegularExpression.cxx,
- cmSetSourceFilesPropertiesCommand.cxx, cmTarget.cxx: ENH: remove
- warnings from borland 6 compiler
-
-2003-05-28 15:52 andy
-
- * Source/CursesDialog/ccmake.cxx: ENH: Do not do configure first
- time. This way ccmake loads fast.
-
-2003-05-28 09:21 hoffman
-
- * Source/: cmCTest.cxx, cmDynamicLoader.cxx,
- cmGlobalVisualStudio71Generator.cxx, cmSystemTools.cxx,
- CTest/cmCTestSubmit.cxx: Remove some borland 6 warnings
-
-2003-05-28 07:53 andy
-
- * Modules/FindQt.cmake: ENH: More locations
-
-2003-05-24 10:07 hoffman
-
- * Source/: cmAbstractFilesCommand.cxx, cmEndIfCommand.cxx,
- cmGlobalGenerator.cxx, cmIfCommand.cxx, cmSourceFilesCommand.cxx,
- cmSourceFilesRemoveCommand.cxx, cmTarget.cxx,
- cmWrapExcludeFilesCommand.cxx: ENH: add stdlib.h for portability
- to borland 6
-
-2003-05-23 16:40 hoffman
-
- * Source/: cmCTest.cxx, cmMakefile.cxx, cmStringCommand.cxx,
- cmake.cxx: ENH: add some includes for borland 6
-
-2003-05-23 09:35 hoffman
-
- * Modules/CMakeSystemSpecificInformation.cmake: ENH: add LDFLAGS as
- an initial value for all linker flags, good for -64
-
-2003-05-19 13:41 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: fix for .def files and
- nmake and spaces in the path
-
-2003-05-16 16:33 king
-
- * Modules/: TestForAnsiForScope.cxx: ERR: Removed warning for
- unused variable.
-
-2003-05-16 15:20 king
-
- * Source/: cmLocalUnixMakefileGenerator.cxx: BUG: When building a C
- executable, we should add CMAKE_SHARED_LIBRARY_C_FLAGS, not
- CMAKE_SHARED_LIBRARY_LINK_FLAGS. The latter is already added by
- the link line procedure.
-
-2003-05-16 15:18 king
-
- * Modules/Platform/: AIX.cmake: BUG: Need -brtl when creating
- shared libraries. Also added -bexpall (AIX equivalent to Linux's
- -rdynamic) when building executables.
-
-2003-05-15 15:15 king
-
- * Source/CursesDialog/cmCursesMainForm.cxx: BUG: Don't report an
- error of output was generated but no error was set. Merging from
- trunk to 1.6 branch.
-
-2003-05-15 15:05 king
-
- * Source/cmGlobalVisualStudio6Generator.cxx: Removed useless
- lower-casing and improved error message. Merged from trunk to
- 1.6 branch.
-
-2003-05-15 14:58 king
-
- * Modules/FindFLTK.cmake: Looking in another place (merge from
- trunk).
-
-2003-05-15 14:54 king
-
- * Source/CursesDialog/cmCursesStringWidget.cxx: Attempt to fix SGI
- ccmake problem (thank you Clint Miller). Merging from trunk to
- 1.6 branch.
-
-2003-05-15 14:45 king
-
- * Source/cmMacroCommand.cxx: BUG: Merging fix from trunk into 1.6
- branch. Report a missing ENDMACRO.
-
-2003-05-15 09:35 andy
-
- * bootstrap: Several fixes before bootstrap is ready for
- prime-time: 1. Add --version flag to display version of CMake 2.
- Add comments to explain what is going on 3. Move CMAKE_ROOT_DIR
- and CMAKE_BOOTSTRAP to cmConfigure.h 4. Forward CC, CXX, and MAKE
- to cmake 5. Add more instructions
-
-2003-05-14 15:38 king
-
- * Utilities/Release/cmake_release.sh: Updated for 1.6.7 release.
-
-2003-05-14 14:14 king
-
- * Source/cmMakefile.h, Utilities/Release/cmake_release.sh: ENH:
- Updated version number to 1.6.7 from 1.6.6.
-
-2003-05-14 12:10 king
-
- * Source/cmGlobalGenerator.cxx: BUG: Work-around for SGI MipsPro
- bug where #error doesn't return an error to make. Merged onto
- 1.6 branch from trunk.
-
-2003-05-14 12:06 king
-
- * Source/cmGlobalGenerator.cxx: BUG: Work-around for SGI MipsPro
- bug where #error doesn't return an error to make.
-
-2003-05-14 09:27 andy
-
- * bootstrap: ENH: Add parallel build support, fix bug in verbose
- and clean output when adding arguments
-
-2003-05-14 09:19 andy
-
- * bootstrap: ENH: Add better error reporting
-
-2003-05-14 08:45 king
-
- * Source/cmake.cxx: BUG: Need to remove the MAKEFLAGS when cmake
- starts. If cmake is run from inside make, we don't want the
- try-compiles to inherit the makeflags.
-
-2003-05-14 08:40 king
-
- * Source/cmake.cxx: ERR: Fixed string literal->char* conversion
- warning.
-
-2003-05-13 16:51 king
-
- * Source/cmake.cxx: BUG: Need to remove the MAKEFLAGS when cmake
- starts. If cmake is run from inside make, we don't want the
- try-compiles to inherit the makeflags.
-
-2003-05-13 16:10 king
-
- * Source/: cmGlobalGenerator.cxx, cmake.cxx: ENH: When the
- initially configured generator is invalid, allow the user to
- change the generator without deleting the cache by hand.
-
-2003-05-13 14:26 king
-
- * Source/: cmGlobalGenerator.cxx: ENH: Improved error message when
- a wrong generator is selected.
-
-2003-05-13 14:05 king
-
- * Source/cmDynamicLoader.cxx: ERR: Removed unused parameter.
-
-2003-05-13 13:54 king
-
- * Source/cmSystemTools.cxx: ERR: Removed unused variable from
- previous merge.
-
-2003-05-13 13:52 king
-
- * Source/: cmCacheManager.cxx, cmConfigureFileCommand.cxx,
- cmListFileCache.cxx, cmLocalVisualStudio6Generator.cxx,
- cmMakeDepend.cxx, cmOutputRequiredFilesCommand.cxx,
- cmSystemTools.cxx, cmSystemTools.h, cmUseMangledMesaCommand.cxx:
- BUG: Using GetLineFromStream instead of getline due to buggy
- stream implementations on some platforms. Merged from trunk into
- branch 1.6.
-
-2003-05-13 13:26 hoffman
-
- * Modules/CMakeVS71FindMake.cmake, Source/CMakeLists.txt,
- Source/cmGlobalVisualStudio71Generator.cxx,
- Source/cmGlobalVisualStudio71Generator.h,
- Source/cmGlobalVisualStudio7Generator.h,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h, Source/cmake.cxx: ENH:
- Adding VS 7.1 generator to 1.6 branch.
-
-2003-05-13 12:04 king
-
- * Modules/CheckIncludeFiles.cmake, Modules/CheckSymbolExists.cmake,
- Modules/FindCABLE.cmake, Modules/Platform/SunOS.cmake,
- Modules/Platform/Windows-bcc32.cmake,
- Modules/Platform/Windows-cl.cmake,
- Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmLocalVisualStudio6Generator.cxx,
- Source/cmLocalVisualStudio7Generator.cxx,
- Source/cmLocalVisualStudio7Generator.h,
- Source/cmRemoveCommand.cxx, Source/cmStringCommand.h,
- Source/cmaketest.cxx, Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/complex.cxx: BUG: Merged
- fixes from main tree into 1.6 branch.
-
-2003-05-13 11:42 hoffman
-
- * Source/cmGlobalVisualStudio71Generator.h: Change name of 71
- generator
-
-2003-05-13 09:50 king
-
- * Source/kwsys/SystemTools.cxx: ERR: Removed use of std::string !=
- operator due to bug in SGI compiler's library.
-
-2003-05-13 09:42 king
-
- * Source/kwsys/CMakeLists.txt: ERR: Test for ansi streams may need
- to use iosfwd for test because some compilers provide an iostream
- header that is old streams.
-
-2003-05-13 08:38 king
-
- * Source/kwsys/SystemTools.cxx: ERR: Added forward declarations of
- system functions for como compiler.
-
-2003-05-12 13:43 king
-
- * Source/kwsys/: CMakeLists.txt, Configure.hxx.in,
- kwsys_std_fstream.h.in, kwsys_std_iosfwd.h.in,
- kwsys_std_iostream.h.in, kwsys_std_sstream.h.in: ENH: Added
- KWSYS_FORCE_OLD_STREAMS option to force use of non-ansi stream
- headers even if they are available.
-
-2003-05-12 13:33 king
-
- * Source/kwsys/: CMakeLists.txt, StandardIncludes.hxx.in: ENH:
- Removed old (unused) StandardIncludes header.
-
-2003-05-12 13:27 king
-
- * Source/kwsys/kwsys_std_iosfwd.h.in: ERR: Need to move forward
- declarations of non-ansi streams into std namespace when it is
- available.
-
-2003-05-12 13:15 king
-
- * Source/kwsys/: CMakeLists.txt, Configure.hxx.in, SystemTools.cxx,
- SystemTools.hxx.in, kwsys_std.h.in, kwsys_std_fstream.h.in,
- kwsys_std_iosfwd.h.in, kwsys_std_iostream.h.in,
- kwsys_std_sstream.h.in: ENH: Added wrappers around the std stream
- headers to make them look like ansi streams on all platforms.
-
-2003-05-09 15:47 hoffman
-
- * Modules/CMakeVS71FindMake.cmake: add find make program for 71
-
-2003-05-09 09:32 hoffman
-
- * Modules/Platform/Windows-bcc32.cmake: BUG: remove typo from file
-
-2003-05-08 16:59 hoffman
-
- * Source/: CMakeLists.txt, cmGlobalVisualStudio71Generator.cxx,
- cmGlobalVisualStudio71Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h,
- cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h, cmake.cxx: add support for vs 71
-
-2003-05-08 16:52 king
-
- * Source/CMakeLists.txt: ERR: Fixed arguments to kwsys's ADD_TEST
- call for msvc6.
-
-2003-05-08 16:48 king
-
- * Source/kwsys/CMakeLists.txt: BUG: Need to invert test result for
- ansi string stream.
-
-2003-05-08 14:49 king
-
- * Source/CMakeLists.txt: ENH: Added kwsys test.
-
-2003-05-08 14:46 king
-
- * Source/kwsys/: CMakeLists.txt, Configure.hxx.in, Directory.cxx,
- Directory.hxx.in, RegularExpression.hxx.in,
- StandardIncludes.hxx.in, kwsys_std.h.in: ENH: Reduced header
- dependencies and cleaned up inclusion of standard headers.
-
-2003-05-08 14:17 king
-
- * Source/kwsys/: CMakeLists.txt, README.itk, README.txt, test1.cxx:
- ENH: Setup for testing as a stand-alone project.
-
-2003-05-08 09:55 hoffman
-
- * Modules/Platform/Windows-bcc32.cmake: BUG: fix for borland win32
- exe builds
-
-2003-05-08 09:43 martink
-
- * Modules/Platform/: Windows-bcc32.cmake: BUG: remove -H flags as
- they cause crashes on oldwww
-
-2003-05-06 10:16 andy
-
- * Source/ctest.cxx: ERR: Remove warning
-
-2003-05-05 10:24 hoffman
-
- * Modules/Platform/Windows-bcc32.cmake: ENH: change the default
- borland stack size
-
-2003-05-05 10:23 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx: BUG: add linker flags
- for modules
-
-2003-05-05 10:23 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: remove 64 bit
- warnings
-
-2003-05-05 09:54 andy
-
- * Modules/CheckIncludeFiles.cmake: ERR: Remove warning for main
- returning void.
-
-2003-05-05 08:42 andy
-
- * Source/: CMakeLists.txt, cmaketest.cxx, cmaketest.h.in: BUG: Fix
- some dependencies for location of executables
-
-2003-05-05 08:42 andy
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: Add support for
- make test even for fresh build of cmake
-
-2003-05-02 14:05 martink
-
- * Modules/Dart.cmake: fixed andy sloppy code again
-
-2003-05-02 13:57 andy
-
- * Modules/Dart.cmake, Modules/DartConfiguration.tcl.in,
- Source/CMakeLists.txt, Source/ctest.cxx: ENH: Fix some dart
- issues. Now it works fine without dart.
-
-2003-05-02 13:56 andy
-
- * Source/cmake.cxx: ENH: New location of cmake binaries
-
-2003-05-02 13:54 andy
-
- * Source/cmaketest.cxx: ENH: New location of cmake
-
-2003-05-02 13:54 andy
-
- * Source/CTest/cmCTestSubmit.cxx: ENH: Be just a bit more verbose
-
-2003-05-02 11:29 andy
-
- * CMakeLists.txt, Source/CMakeLists.txt: ENH: Executables should go
- to the bin directory
-
-2003-05-01 07:56 andy
-
- * Source/CTest/cmCTestSubmit.cxx: ERR: Remove warnings
-
-2003-04-30 07:32 andy
-
- * Source/cmake.h: ERR: Run should return a value
-
-2003-04-29 17:23 andy
-
- * Source/: CMakeLists.txt, CTest/CMakeLists.txt: ENH: Make Curl
- code to be built by default
-
-2003-04-29 10:07 andy
-
- * Source/cmakemain.cxx: ENH: Add argument -N which prevents CMake
- from doing configure and generate. This should be improved at
- some point that it will do all the error checking such as whether
- the CMakeLists.txt exists etc. It should essentially load cache,
- go through cmake lists, but not modify cache and other files in
- the build directory. The second feature is ability to display
- cache values. You run with argument -L (or -LH /-LA / -LAH) and
- it will display all nonadvanced cached variables (-L) / all
- cached variable (-LA) / and cached variables with corresponding
- help string (-LH -LAH).
-
-2003-04-29 10:04 andy
-
- * Source/: cmake.cxx, cmake.h: ENH: Add additional optional
- argument to Run. If it is true, it will only set paths and load
- cache. It will not do configure and gfenerate
-
-2003-04-29 10:02 andy
-
- * Source/: cmCacheManager.cxx, cmCacheManager.h: ENH: Add method to
- convert from CacheEntryType to string
-
-2003-04-28 13:16 martink
-
- * Source/cmMacroCommand.cxx: better error reporting
-
-2003-04-25 15:16 andy
-
- * Source/: CTest/CMakeLists.txt, CMakeLists.txt: ENH: Enable CTest
- to be build as a part of CMake
-
-2003-04-25 14:52 andy
-
- * Source/ctest.cxx: ENH: Rename option -D to -C because we will use
- -D later
-
-2003-04-25 14:51 andy
-
- * Source/cmCommands.cxx: ERR: Set source files properties is needed
- for Curl build
-
-2003-04-25 14:50 andy
-
- * Source/CTest/cmCTestSubmit.cxx: ERR: Remove warning because SCP
- not implemented
-
-2003-04-24 13:25 berk
-
- * Source/: cmSystemTools.cxx: minor fix
-
-2003-04-23 17:24 jjomier
-
- * Source/kwsys/Directory.hxx.in: FIX: warnings, disabling 4786
-
-2003-04-23 13:58 martink
-
- * Source/CTest/CMakeLists.txt: fix some incldue paths
-
-2003-04-22 16:10 king
-
- * Modules/FindCABLE.cmake: ENH: Updated search paths to newest
- values from Cable.
-
-2003-04-22 14:32 andy
-
- * bootstrap: ENH: Add SGI -LANG:std support
-
-2003-04-18 10:01 andy
-
- * Source/cmCTest.cxx: ENH: Cleanup
-
-2003-04-18 10:00 andy
-
- * Source/cmCTest.cxx: Even better error detection on AIX
-
-2003-04-18 09:48 andy
-
- * Source/cmCTest.cxx: Better AIX detection
-
-2003-04-17 15:20 andy
-
- * Source/cmCTest.cxx: This is really an error
-
-2003-04-17 13:13 andy
-
- * bootstrap: Support LDFLAGS
-
-2003-04-17 13:13 andy
-
- * Source/cmCTest.cxx: ENH: Add AIX warerr
-
-2003-04-17 11:59 martink
-
- * Source/cmLocalCodeWarriorGenerator.cxx: warning fix hopefully
-
-2003-04-17 11:17 andy
-
- * DartConfig.cmake: More attempt to make continuous email work
-
-2003-04-17 08:47 martink
-
- * Source/cmDynamicLoader.cxx: fix one warning
-
-2003-04-17 08:23 andy
-
- * DartConfig.cmake: Attempt to enable sending of e-mails from
- continuous
-
-2003-04-17 08:03 hoffman
-
- * Source/cmCommands.cxx: BUG: fix compile error on windows because
- of windows.h
-
-2003-04-17 08:02 andy
-
- * CMakeLists.txt, bootstrap, configure, configure.in: BUG: Rename
- Bootstrap directory to Bootstrap.cmk, so that on platforms such
- as Windows and Mac OSX it will break during in-source build
-
-2003-04-16 17:06 andy
-
- * DartConfig.cmake: ENH: cleanup
-
-2003-04-16 16:20 martink
-
- * Source/cmDynamicLoader.cxx: fix one warning
-
-2003-04-16 16:17 martink
-
- * Source/cmCommands.cxx: streamline bootstrap
-
-2003-04-16 15:40 martink
-
- * Source/cmake.cxx: minor fix
-
-2003-04-16 14:47 martink
-
- * Source/: CMakeLists.txt, cmLocalCodeWarriorGenerator.cxx,
- cmLocalCodeWarriorGenerator.h, cmake.cxx: add COdeWarrior back in
- for testing
-
-2003-04-16 14:13 andy
-
- * Source/cmDynamicLoader.cxx: Attempt to make unloading work on OSX
-
-2003-04-16 13:41 andy
-
- * Source/cmCTest.cxx: Fix update output
-
-2003-04-16 13:33 hoffman
-
- * Tests/: LoadCommand/CMakeLists.txt,
- LoadCommandOneConfig/CMakeLists.txt: ENH: add a double try
- compile to fix crazy make on hp
-
-2003-04-11 18:05 kentwilliams
-
- * Source/kwsys/SystemTools.cxx: took out an orphan endif
-
-2003-04-11 16:22 kentwilliams
-
- * Source/kwsys/: SystemTools.hxx.in, SystemTools.cxx: remove
- redundant function and eliminate need for strcasecmp
-
-2003-04-11 13:36 king
-
- * Source/kwsys/README.itk: ENH: Added documentation for ITK.
-
-2003-04-11 07:27 lorensen
-
- * Source/kwsys/SystemTools.cxx: ERR: Borland fix for stricmp. ERR:
- removed itk dependencies.
-
-2003-04-10 13:41 kentwilliams
-
- * Source/kwsys/: SystemTools.cxx, SystemTools.hxx.in: Removed
- platform-specific functions from Code/IO/itkIOCommon, fixed code
- to use kwsys/SystemTools
-
-2003-04-10 09:07 andy
-
- * Source/cmCTest.cxx: Do safe division instead of fixing result
-
-2003-04-10 09:03 king
-
- * Source/kwsys/SystemTools.cxx: ERR: Removed unused parameter and
- truncated debug symbol warnings.
-
-2003-04-09 08:08 andy
-
- * Source/cmCTest.cxx: Attempt to fix FIXNUM
-
-2003-04-08 13:14 king
-
- * Source/kwsys/SystemTools.cxx: ERR: Fixed typo.
- cmRegularExpression -> RegularExpression.
-
-2003-04-08 13:10 king
-
- * Source/kwsys/: CMakeLists.txt, Configure.hxx.in, Directory.cxx,
- Directory.hxx.in, RegularExpression.cxx,
- RegularExpression.hxx.in, StandardIncludes.hxx.in,
- SystemTools.cxx, SystemTools.hxx.in: ENH: Added kwsys library for
- platform-independent system tools.
-
-2003-04-08 10:57 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: Remove nan and inf, use
- iostreams to set precision, fix file name, and remove bogus files
-
-2003-04-08 07:16 andy
-
- * Source/cmCTest.cxx: Remove push_back on string. Why can't STL be
- standard?
-
-2003-04-07 18:21 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: Some cov improvements and better
- esc
-
-2003-04-07 12:20 andy
-
- * Source/cmaketest.cxx: We should really just call make and not
- make all
-
-2003-04-04 10:56 king
-
- * Source/cmSetCommand.h: ENH: Added CACHE entry types to
- documentation string.
-
-2003-04-04 10:05 king
-
- * Modules/FindFLTK.cmake: ENH: Added /usr/local/lib/fltk
-
-2003-04-03 18:40 andy
-
- * bootstrap: Better support for spaces in paths
-
-2003-04-03 08:44 andy
-
- * Source/cmSystemTools.cxx: Try differentiating extensions
-
-2003-04-02 22:48 king
-
- * Source/: cmake.cxx, cmake.h, cmakemain.cxx,
- CursesDialog/ccmake.cxx: ENH: Improved documentation. Also
- modified behavior of "cmake" to not configure a project in the
- current directory unless . is given.
-
-2003-04-02 22:44 king
-
- * Source/cmDocumentation.cxx: ENH: Running with zero arguments now
- produces usage.
-
-2003-04-02 09:19 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: Url escape password
-
-2003-04-02 09:19 andy
-
- * Source/CTest/cmCTestSubmit.cxx: On verbose, be more verbose
-
-2003-04-02 09:01 andy
-
- * Tests/Wrapping/qtwrappingmain.cxx: If display is not set, do not
- attempt to run application
-
-2003-04-02 08:45 andy
-
- * Modules/FindQt.cmake: Add QT on debian
-
-2003-04-01 15:31 andy
-
- * Source/cmCTest.cxx: Fix cov. problems, ignore nonascii char.
- Propagate verbosity
-
-2003-04-01 15:30 andy
-
- * Source/CTest/: cmCTestSubmit.cxx, cmCTestSubmit.h: Controle
- verbosity
-
-2003-04-01 13:29 king
-
- * Source/cmSystemTools.cxx: BUG: strlen(buffer) from getline may be
- 2 less than gcount on windows because both the CR and LF
- characters may be removed.
-
-2003-03-28 13:42 andy
-
- * Modules/CheckSymbolExists.cmake: New design of CheckSymbolExists
- pretty much replaces all other ones.
-
- For example:
-
- CHECK_HEADER_EXISTS("type.h" HAVE_TYPE_H) is:
- CHECK_SYMBOL_EXISTS(main "type.h" HAVE_TYPE_H)
-
- CHECK_LIBRARY_EXISTS("nsl" gethostname HAVE_LIBNSL) would be
- SET(CMAKE_REQUIRED_LIBRARIES "nsl")
- CHECK_SYMBOL_EXISTS(gethostname "netdb.h" HAVE_LIBNSL)
-
- ...
-
-2003-03-27 15:52 andy
-
- * Source/: cmLocalVisualStudio6Generator.cxx, cmSystemTools.cxx,
- cmUseMangledMesaCommand.cxx: Remove warnings
-
-2003-03-27 15:29 andy
-
- * bootstrap: Initial import of bootstrap for CMake
-
-2003-03-27 13:03 hoffman
-
- * Modules/Platform/SunOS.cmake: Fix gnu c and Sun CC mix
-
-2003-03-27 12:49 andy
-
- * CMakeLists.txt: Some more preparations for new bootstrap system
-
-2003-03-27 12:24 andy
-
- * Source/: cmCacheManager.cxx, cmConfigureFileCommand.cxx,
- cmListFileCache.cxx, cmLocalVisualStudio6Generator.cxx,
- cmMakeDepend.cxx, cmOutputRequiredFilesCommand.cxx,
- cmSystemTools.cxx, cmSystemTools.h, cmUseMangledMesaCommand.cxx:
- Implement GetLineFromStream that actually works and use it
- instead of getline
-
-2003-03-26 10:45 andy
-
- * Source/cmStandardIncludes.h, Tests/Complex/CMakeLists.txt,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexRelativePaths/CMakeLists.txt: Remove bogus flags
- from cmStandardIncludes and make complex test pass
-
-2003-03-21 11:33 hoffman
-
- * Tests/: Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/complex.cxx: BUG: fix REMOVE test
-
-2003-03-21 11:24 hoffman
-
- * Source/cmRemoveCommand.cxx: BUG: fix broken command
-
-2003-03-20 11:27 andy
-
- * Source/cmCTest.cxx: Fix problem with network paths
-
-2003-03-20 10:12 andy
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: Support cmake in
- directory with space
-
-2003-03-20 09:47 andy
-
- * Source/cmCTest.cxx: BUG: used wrong counters
-
-2003-03-19 18:28 andy
-
- * Source/cmCTest.cxx: More regex
-
-2003-03-19 16:35 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: Add start
-
-2003-03-19 16:25 andy
-
- * Source/cmCTest.cxx: Move files to different location and fix time
-
-2003-03-19 16:11 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: Fix for visual studio
-
-2003-03-19 10:16 king
-
- * Source/cmStringCommand.h: BUG: Command should be inherited.
-
-2003-03-18 11:47 king
-
- * Utilities/Release/: config_Linux: ENH: Updated to do release
- build on ringworld. Needed for old glibc support.
-
-2003-03-17 14:29 andy
-
- * Tests/Simple/: CMakeLists.txt, simple.cxx, simpleCLib.c,
- simpleWe.cpp: Improve test
-
-2003-03-17 13:26 andy
-
- * Tests/Simple/: CMakeLists.txt, simpleCLib.c: Add testing for when
- C sources are compiled with C++ compiler
-
-2003-03-17 11:21 andy
-
- * Source/CursesDialog/cmCursesMainForm.cxx: If there was no error,
- do not say that there was one
-
-2003-03-17 10:00 king
-
- * Modules/FindGTK.cmake: BUG: Fixed ENDIF ordering.
-
-2003-03-17 09:57 king
-
- * Modules/CheckSymbolExists.cmake: BUG: Fixed syntax of file
- generated for test.
-
-2003-03-17 09:29 hoffman
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: BUG: fix crash with force cxx
- type
-
-2003-03-17 09:15 hoffman
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: force cxx compiler for cxx
- files
-
-2003-03-17 08:25 andy
-
- * Tests/SystemInformation/: CMakeLists.txt, DumpInformation.cxx,
- DumpInformation.h.in: Display Cache and all variables
-
-2003-03-16 20:33 andy
-
- * Modules/CheckSymbolExists.cmake: Prevent CMake from putting ; in
- the file
-
-2003-03-16 20:25 andy
-
- * Modules/FindGTK.cmake: More variables advanced
-
-2003-03-16 20:23 andy
-
- * Modules/FindGTK.cmake: Add gthread library
-
-2003-03-15 10:04 hoffman
-
- * Source/cmTarget.cxx: BUG: HasCXX did not use GetFileFormat and
- was broken
-
-2003-03-14 15:44 hoffman
-
- * Modules/FindGTK.cmake: BUG: bad if statement order
-
-2003-03-14 15:06 hoffman
-
- * Source/cmGlobalVisualStudio6Generator.cxx: better error message
-
-2003-03-14 12:00 hoffman
-
- * Modules/Platform/Windows-cl.cmake: force c++ for c++ files
-
-2003-03-14 12:00 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx: use c flags with c and
- not cxx flags, also force c++ for c files
-
-2003-03-14 11:59 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: Force c++ builds for
- c++ files
-
-2003-03-14 11:58 hoffman
-
- * Source/cmMakefile.cxx: make sure M is after m
-
-2003-03-14 10:54 king
-
- * Source/cmMakefile.cxx: BUG: c extension must come before C.
-
-2003-03-14 10:38 king
-
- * Source/cmMakefile.cxx: BUG: c must precede C.
-
-2003-03-13 16:31 king
-
- * Utilities/Release/config_Linux: Merging from 1.6 again.
-
-2003-03-13 16:30 king
-
- * Utilities/Release/config_Linux: BUG: Need to link statically
- against curses.
-
-2003-03-13 15:59 king
-
- * Utilities/Release/: cmake_release.sh, config_Linux: Merging from
- 1.6 release branch.
-
-2003-03-13 15:58 king
-
- * Utilities/Release/cmake_release.sh: BUG: Need to checkout
- ReleaseUtilities with same tag.
-
-2003-03-13 15:47 king
-
- * Utilities/Release/: cmake_release.sh: ENH: Updated for 1.6.6
- release.
-
-2003-03-13 15:46 king
-
- * Modules/Platform/: SunOS.cmake: BUG: Don't use -nostdlib option
- to link shared libraries. Just use gcc -shared, even for C++
- libraries.
-
-2003-03-13 13:28 king
-
- * Source/cmMakefile.cxx: BUG: Added missing cc extension for Source
- Files group.
-
-2003-03-13 13:03 king
-
- * Source/cmMakefile.cxx: BUG: Don't duplicate SUBDIRS.
-
-2003-03-13 13:01 king
-
- * Source/cmMakefile.cxx: ENH: Added header file extensions.
-
-2003-03-13 12:59 martink
-
- * Source/cmMakefile.cxx: allow the same subdir to be added twice
-
-2003-03-13 12:48 andy
-
- * Source/cmMakefile.cxx: Fix regular expressions
-
-2003-03-13 12:24 andy
-
- * Source/: cmMakefile.cxx, cmSystemTools.cxx: Synchronize extension
- lists
-
-2003-03-13 11:53 king
-
- * Source/CursesDialog/form/fld_attr.c: BUG: Fixed forms for HP.
-
-2003-03-13 11:51 king
-
- * Modules/TestForSTDNamespace.cmake: BUG: Don't repeat test.
-
-2003-03-13 11:49 king
-
- * Modules/CheckTypeSize.cmake: BUG: Don't test type size more than
- once.
-
-2003-03-13 11:48 king
-
- * Source/cmSystemTools.cxx: BUG: FindLibrary should not accept a
- directory even if the exact specified name exists.
-
-2003-03-13 11:46 king
-
- * Source/cmake.cxx: BUG: Fixed crash when
- CMAKE_BACKWARDS_COMPATIBILITY is deleted.
-
-2003-03-13 11:33 king
-
- * Source/cmMakefile.h: ENH: Updated version for 1.6.6 release.
-
-2003-03-13 11:31 king
-
- * Utilities/Release/config_Linux: ERR: Need to do shared libc link
- with static C++ library to have safe dl loading on linux.
-
-2003-03-13 08:44 king
-
- * Source/cmSystemTools.cxx: BUG: FindLibrary should not accept a
- directory even if the exact specified name exists.
-
-2003-03-11 17:35 hoffman
-
- * Modules/TestForSTDNamespace.cmake: BUG: fix test not to run every
- time
-
-2003-03-11 15:25 hoffman
-
- * Source/cmDynamicLoader.cxx, Source/CTest/CMakeLists.txt,
- Source/CursesDialog/form/fld_attr.c,
- Tests/LoadCommand/CMakeLists.txt,
- Tests/LoadCommandOneConfig/CMakeLists.txt: BUG: fixes for hp
-
-2003-03-09 18:16 andy
-
- * Source/CursesDialog/cmCursesMainForm.cxx: Remove warnings
-
-2003-03-07 15:30 andy
-
- * Source/cmCTest.cxx: More XML
-
-2003-03-07 11:53 andy
-
- * Source/CursesDialog/cmCursesMainForm.cxx: Remove warning
-
-2003-03-07 11:45 andy
-
- * Source/cmCTest.cxx: Fix xml
-
-2003-03-07 11:27 andy
-
- * Source/CursesDialog/: cmCursesMainForm.cxx, cmCursesMainForm.h:
- Add searching of variables
-
-2003-03-06 15:32 andy
-
- * Modules/Dart.cmake: On borland and cygwin remove .EXE
-
-2003-03-06 12:31 andy
-
- * Source/cmGetCMakePropertyCommand.cxx: Remove warning
-
-2003-03-06 11:20 andy
-
- * Source/cmCommands.cxx, Source/cmGetCMakePropertyCommand.cxx,
- Source/cmGetCMakePropertyCommand.h,
- Tests/SystemInformation/CMakeLists.txt: Add command for accessing
- cmake properties. At this point the only properties are VARIABLES
- and CACHE_VARIABLES. Also add test for this feature
-
-2003-03-06 11:19 andy
-
- * Source/: cmMakefile.cxx, cmMakefile.h: Add method which returns a
- list of all variables
-
-2003-03-06 11:18 andy
-
- * Source/cmCacheManager.h: Cache manager should be able to take no
- arguments
-
-2003-03-06 10:32 king
-
- * Modules/CheckTypeSize.cmake: BUG: Should test HAVE_<VARIABLE>
- before repeating test, not just whether <VARIABLE> is set.
-
-2003-03-05 17:08 andy
-
- * Source/cmCTest.cxx: oops... Forgot the main step
-
-2003-03-03 13:58 andy
-
- * Modules/Dart.cmake: Add Update and configure steps where missing
-
-2003-03-03 13:57 andy
-
- * Source/cmCTest.cxx: Fix typo
-
-2003-03-03 09:32 andy
-
- * Modules/Dart.cmake: Start cleaning global namespace
-
-2003-03-03 09:29 andy
-
- * CMakeLists.txt: BUG: Should be use the host CMake's dart file
-
-2003-02-28 13:00 andy
-
- * Source/cmCTest.cxx: Ifdef code that is missing
-
-2003-02-28 12:42 andy
-
- * Modules/CheckSymbolExists.cmake, Source/cmCTest.cxx: Fix update
- date and cleanup
-
-2003-02-28 11:31 andy
-
- * Source/cmCTest.cxx: Add configure step
-
-2003-02-27 14:48 andy
-
- * Modules/Dart.cmake: On windows but not on borland, look at
- cmake_build_tool instead of compiler to determine build name.
- Otherwise they will all be cl
-
-2003-02-27 11:54 andy
-
- * Modules/Dart.cmake: Use more condense buildname. If this works
- fine we can make cmBuildName command deprecated
-
-2003-02-24 11:02 king
-
- * Source/cmake.cxx: BUG: Fixed crash when
- CMAKE_BACKWARDS_COMPATIBILITY is deleted between configures.
-
-2003-02-20 17:38 andy
-
- * Modules/Dart.cmake: Use simple defaults if DartConfig does not
- exist. This way you can use dart to build any project
-
-2003-02-20 10:46 king
-
- * Modules/CMakeVS6FindMake.cmake: BUG: Fix registry entry name.
-
-2003-02-20 10:44 hoffman
-
- * Modules/CMakeVS6FindMake.cmake: BUG: look for msdev in the right
- place
-
-2003-02-20 09:40 king
-
- * Utilities/Release/cmake_release.sh: ENH: Updated for 1.6.5
- release.
-
-2003-02-20 08:55 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: fix for correct path
- style in depend file
-
-2003-02-20 08:52 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: fix for correct path
- style in depend file
-
-2003-02-20 08:47 king
-
- * Modules/TestForANSIForScope.cmake: BUG: Don't test every time for
- "for" scope.
-
-2003-02-20 08:42 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: Fix problem with
- lib in the name of library. If there was lib in the name of
- library, then on Windows (where there is not lib prefix), cmake
- split the name wrongly. This only manifested when full path to
- the library is specified.
-
-2003-02-20 08:41 hoffman
-
- * Modules/TestForANSIForScope.cmake: remove commented code
-
-2003-02-20 08:38 king
-
- * Modules/CheckSymbolExists.cmake: BUG: Fixed return 0 through void
- type.
-
-2003-02-20 08:37 king
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeDetermineCXXCompiler.cmake: ENH: Removed creation of extra
- CMAKE_C_COMPILER_FULLPATH and CMAKE_CXX_COMPILER_FULLPATH cache
- entries.
-
-2003-02-20 08:34 king
-
- * Source/cmGlobalVisualStudio7Generator.cxx: BUG: Added missing
- paren to generated file.
-
-2003-02-20 08:32 king
-
- * Source/cmaketest.cxx: BUG: Fix lower-casing of compiler for
- win98.
-
-2003-02-20 08:30 king
-
- * Source/cmMakefile.h, Utilities/Release/cmake_release.sh: ENH:
- Updated for version 1.6.5.
-
-2003-02-20 08:28 king
-
- * Source/cmFindPackageCommand.h: BUG: This command must be
- inherited.
-
-2003-02-20 08:23 king
-
- * Modules/FindFLTK.cmake: BUG: Removed reference to CMake 1.4
- compatability variable.
-
-2003-02-20 07:55 king
-
- * Source/cmDumpDocumentation.cxx: ERR: Added missing return.
-
-2003-02-19 17:37 king
-
- * Source/CMakeLists.txt: ENH: Using new --all-for-coverage of
- DumpDocumentation to improve coverage.
-
-2003-02-19 17:36 king
-
- * Source/cmDumpDocumentation.cxx: ENH: Added option to dump all
- documentation (coverage).
-
-2003-02-19 17:10 king
-
- * Modules/FindFLTK.cmake: BUG: Removed use of cmake 1.4
- compatability variable.
-
-2003-02-19 12:54 andy
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: Fix problem with
- lib in the name of library. If there was lib in the name of
- library, then on Windows (where there is not lib prefix), cmake
- split the name wrongly. This only manifested when full path to
- the library is specified.
-
-2003-02-19 08:52 king
-
- * Source/cmDocumentation.cxx: ERR: Fixed signed/unsigned warning.
-
-2003-02-18 20:54 king
-
- * Source/cmDumpDocumentation.cxx: ENH: Updated to use
- cmDocumentation class.
-
-2003-02-18 20:42 king
-
- * Source/: cmDocumentation.cxx, cmDocumentation.h, cmakemain.cxx,
- CursesDialog/ccmake.cxx: ENH: Re-implemented document generation
- class to be more organized and more robust.
-
-2003-02-18 20:40 king
-
- * Source/cmAddCustomCommandCommand.h: Fix to documentation
- formatting: removed extra newline.
-
-2003-02-18 16:24 hoffman
-
- * Source/cmGlobalVisualStudio7Generator.cxx: ENH: fix for vs 7
- beta1
-
-2003-02-17 15:47 king
-
- * Source/cmFindPackageCommand.h: BUG: This command must be
- inherited.
-
-2003-02-17 10:30 andy
-
- * Modules/CheckSymbolExists.cmake: Fix return value problem
-
-2003-02-17 09:59 andy
-
- * Source/CursesDialog/cmCursesStringWidget.cxx: Attempt to fix SGI
- ccmake problem (thank you Clint Miller)
-
-2003-02-17 09:56 andy
-
- * Source/cmDocumentation.cxx: Minor documentation fixes
-
-2003-02-17 09:42 king
-
- * Source/cmakemain.cxx: ENH: Added executable-specific command-line
- options.
-
-2003-02-17 09:42 king
-
- * Source/: cmDocumentation.cxx, cmDocumentation.h: ENH: Added
- header before list of commands in generated docs. Made options
- more intuitive.
-
-2003-02-16 11:57 king
-
- * Source/cmDocumentation.cxx: ERR: Use of stream format flags is
- hard to make portable. Manually implementing justification.
-
-2003-02-15 22:36 king
-
- * Source/cmDocumentation.cxx: ERR: Use of std::ios::fmtflags is not
- portable to older compilers.
-
-2003-02-14 18:47 king
-
- * Source/: cmAbstractFilesCommand.h, cmAddCustomCommandCommand.h,
- cmAddCustomTargetCommand.h, cmAddDefinitionsCommand.h,
- cmAddDependenciesCommand.h, cmAddExecutableCommand.h,
- cmAddLibraryCommand.h, cmAddTestCommand.h,
- cmAuxSourceDirectoryCommand.h, cmBuildCommand.h,
- cmBuildNameCommand.h, cmConfigureFileCommand.h,
- cmCreateTestSourceList.h, cmElseCommand.h,
- cmEnableTestingCommand.h, cmEndForEachCommand.h,
- cmEndIfCommand.h, cmExecProgramCommand.h,
- cmExportLibraryDependencies.h, cmFLTKWrapUICommand.h,
- cmFindFileCommand.h, cmFindLibraryCommand.h,
- cmFindPackageCommand.h, cmFindPathCommand.h,
- cmFindProgramCommand.h, cmForEachCommand.h,
- cmGetFilenameComponentCommand.h,
- cmGetSourceFilePropertyCommand.h, cmGetTargetPropertyCommand.h,
- cmITKWrapTclCommand.h, cmIfCommand.h, cmIncludeCommand.h,
- cmIncludeDirectoryCommand.h, cmIncludeExternalMSProjectCommand.h,
- cmIncludeRegularExpressionCommand.h, cmInstallFilesCommand.h,
- cmInstallProgramsCommand.h, cmInstallTargetsCommand.h,
- cmLinkDirectoriesCommand.h, cmLinkLibrariesCommand.h,
- cmLoadCacheCommand.h, cmLoadCommandCommand.h, cmMacroCommand.h,
- cmMakeDirectoryCommand.h, cmMarkAsAdvancedCommand.h,
- cmMessageCommand.h, cmOptionCommand.h,
- cmOutputRequiredFilesCommand.h, cmProjectCommand.h,
- cmQTWrapCPPCommand.h, cmQTWrapUICommand.h, cmRemoveCommand.h,
- cmSeparateArgumentsCommand.h, cmSetCommand.h,
- cmSetSourceFilesPropertiesCommand.h,
- cmSetTargetPropertiesCommand.h, cmSiteNameCommand.h,
- cmSourceFilesCommand.h, cmSourceFilesRemoveCommand.h,
- cmSourceGroupCommand.h, cmStringCommand.h, cmSubdirCommand.h,
- cmSubdirDependsCommand.h, cmTargetLinkLibrariesCommand.h,
- cmTryCompileCommand.h, cmTryRunCommand.h,
- cmUseMangledMesaCommand.h, cmUtilitySourceCommand.h,
- cmVTKMakeInstantiatorCommand.h, cmVTKWrapJavaCommand.h,
- cmVTKWrapPythonCommand.h, cmVTKWrapTclCommand.h,
- cmVariableRequiresCommand.h, cmWrapExcludeFilesCommand.h,
- cmWriteFileCommand.h: ENH: Cleaned up documentation and formatted
- it for use by cmDocumentation.
-
-2003-02-14 16:16 king
-
- * Source/cmDocumentation.cxx: ENH: Improved formatting of
- plain-text help to add a blank line before the beginning of a
- preformatted section.
-
-2003-02-14 13:28 king
-
- * Source/: cmDocumentation.cxx, cmDocumentation.h: ENH: Further
- improved formatting. HTML/man/help now all have a consistent
- appearance.
-
-2003-02-14 13:06 king
-
- * Source/: cmDocumentation.cxx, cmDocumentation.h: ENH: Improved
- formatting of documentation.
-
-2003-02-14 11:13 martink
-
- * Source/cmaketest.cxx: Lowercase has a bad signiture, so I have to
- live with it
-
-2003-02-14 10:56 king
-
- * Source/cmSystemTools.cxx: ERR: Added missing include for msvc.
-
-2003-02-14 10:53 king
-
- * Source/: CMakeLists.txt, Makefile.in, cmDocumentation.cxx,
- cmDocumentation.h, cmStandardIncludes.h, cmSystemTools.cxx,
- cmSystemTools.h, cmake.cxx, cmake.h, cmakemain.cxx,
- CursesDialog/ccmake.cxx: ENH: Added cmDocumentation class to
- generate various forms of documentation. Each executable will be
- able to generate its own documentation.
-
-2003-02-14 10:40 hoffman
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeDetermineCXXCompiler.cmake: ENH: move full path compiler to
- internal and not just advanced
-
-2003-02-14 09:54 hoffman
-
- * Modules/TestForANSIForScope.cmake, Source/cmCacheManager.cxx,
- Source/cmConfigureFileCommand.cxx,
- Source/cmConfigureFileCommand.h, Source/cmIncludeCommand.h,
- Source/cmLocalUnixMakefileGenerator.cxx, Source/cmMakefile.h,
- Source/cmMarkAsAdvancedCommand.h,
- Source/cmUseMangledMesaCommand.cxx,
- Source/cmVariableRequiresCommand.cxx,
- Source/cmVariableRequiresCommand.h: spelling errors
-
-2003-02-14 09:25 hoffman
-
- * CMake.rtf: fix spelling errors
-
-2003-02-13 21:57 king
-
- * CMakeLists.txt, configure, configure.in, Source/CMakeLists.txt,
- Source/cmConfigure.cmake.h.in, Source/cmConfigure.h.in,
- Source/cmMakefile.cxx, Source/cmMakefile.h,
- Source/cmStandardIncludes.h: ENH: Centralized setting of CMake
- version number to top-level CMake listfile.
-
-2003-02-13 12:03 king
-
- * Utilities/Release/cmake_release.sh: ENH: Merged updates for 1.6.4
- release.
-
-2003-02-13 11:57 king
-
- * Modules/FindJNI.cmake: BUG: Fix find of JNI on Mac OSX 10.2.
-
-2003-02-13 11:54 king
-
- * Source/cmMakefile.h, Utilities/Release/cmake_release.sh: ENH:
- Updated for 1.6.4 release.
-
-2003-02-13 11:52 king
-
- * Modules/UseVTKConfig40.cmake: BUG: Copy of _LIB_DEPENDS variables
- needs to be double-quoted.
-
-2003-02-13 11:50 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: fix for spaces in
- paths in library path
-
-2003-02-13 11:47 king
-
- * Source/cmFindLibraryCommand.cxx: BUG: Use
- cmSystemTools::IsNOTFOUND.
-
-2003-02-12 13:43 andy
-
- * Source/: cmCTest.cxx, cmakemain.cxx: Try to fix update
-
-2003-02-12 09:26 andy
-
- * Source/cmCTest.cxx: Write individual too
-
-2003-02-11 14:49 andy
-
- * Modules/FindJNI.cmake: Ok, now it finds JNI on Mac OSX 10.2
-
-2003-02-11 13:56 andy
-
- * Modules/FindJNI.cmake: Fix typo
-
-2003-02-11 13:53 andy
-
- * Modules/FindJNI.cmake: Add missing location
-
-2003-02-11 13:37 andy
-
- * Modules/FindJNI.cmake: Improve searching for java files on OSX
-
-2003-02-11 13:34 andy
-
- * Source/cmSetTargetPropertiesCommand.h: Fix comment
-
-2003-02-11 09:50 king
-
- * Modules/: FindMangledMesa.cmake, FindOSMesa.cmake: Moving this
- very specific module to VTK.
-
-2003-02-11 09:19 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: Fix cont and remove comments
-
-2003-02-10 23:19 andy
-
- * Source/: cmCTest.cxx, cmCTest.h, ctest.cxx: Start working on cont
-
-2003-02-10 22:00 hoffman
-
- * Tests/TryCompile/CMakeLists.txt: ENH: add more testing for ansi
- for scopes
-
-2003-02-10 21:56 hoffman
-
- * Modules/TestForANSIForScope.cmake: clean up check for for scope
- test
-
-2003-02-10 21:52 andy
-
- * Source/: cmCTest.cxx, cmCTest.h, ctest.cxx: Fix date issues with
- different models
-
-2003-02-10 16:20 hoffman
-
- * Source/CMakeLists.txt, Tests/TryCompile/CMakeLists.txt: ENH: add
- a new test for TRY_COMPILE
-
-2003-02-10 13:19 hoffman
-
- * Tests/TryCompile/: CMakeLists.txt, fail.c, pass.c: ENH: add a new
- test to test try compile
-
-2003-02-10 11:08 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: Running "make test"
- can now have ARGS specified on the command line. These ARGS are
- passed to ctest.
-
-2003-02-09 16:11 king
-
- * Utilities/Release/cmake_release.sh: ERR: Removed extra &&.
-
-2003-02-08 10:24 hoffman
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: Fix for include
- optional
-
-2003-02-08 10:23 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: fix for spaces in
- paths in library path
-
-2003-02-07 16:29 king
-
- * Modules/UseVTKConfig40.cmake: BUG: Copying _LIB_DEPENDS variables
- requires double-quoted argument.
-
-2003-02-07 14:04 king
-
- * Source/: cmGetFilenameComponentCommand.cxx,
- cmGetFilenameComponentCommand.h,
- cmLocalUnixMakefileGenerator.cxx,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio6Generator.h,
- cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h, cmMakefile.cxx,
- cmSetSourceFilesPropertiesCommand.h,
- cmSetTargetPropertiesCommand.h, cmSystemTools.cxx,
- cmSystemTools.h: Several fixes/improvements:
-
- - Fixed CollapseFullPath to work on relative paths with base
- paths
- not in the current working directory.
- - INCLUDE command now supports relative paths (using above
- fix).
- - Added ABSOLUTE option to GET_FILENAME_COMPONENT command to
- unwind symlinks and relative paths.
- - Fixed libName_EXPORTS macro definition to be valid C
- identifier.
- - Added DEFINE_SYMBOL target propterty for customizing the
- export symbol.
- - Implemented LINK_FLAGS target propterty for libraries in VC6
- and VC7.
-
- Several of these fixes were contributed by Gareth Jones.
-
-2003-02-07 11:47 hoffman
-
- * Source/CTest/CMakeLists.txt: Remove warnings on AIX
-
-2003-02-07 11:03 andy
-
- * Source/CTest/cmCTestSubmit.cxx: Do not reuse connection as that
- feature seems to be broken
-
-2003-02-07 11:03 andy
-
- * Source/cmCTest.cxx: Fix update return status
-
-2003-02-07 10:34 hoffman
-
- * Source/cmSystemTools.cxx: ENH: spelling error fix
-
-2003-02-07 10:18 hoffman
-
- * Source/cmFindLibraryCommand.cxx: BUG: use IsNOTFOUND
-
-2003-02-07 10:05 king
-
- * Utilities/Release/cmake_release.sh: ERR: Removed stray && from
- end of line.
-
-2003-02-07 00:09 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: Add updating support
-
-2003-02-06 17:48 hoffman
-
- * CMakeLists.txt: tell the aix linker not to give warnings with
- -bhalt:5
-
-2003-02-06 15:18 martink
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: added option to shut off
- automatic rebuilding
-
-2003-02-06 10:49 king
-
- * Source/CMakeLists.txt: ENH: Comeau C++ has been added for nightly
- testing. It does not support shared libraries, so we cannot run
- the complex tests.
-
-2003-02-05 22:26 hoffman
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h,
- cmTryCompileCommand.cxx: add better testing for unlink
-
-2003-02-05 18:05 king
-
- * Source/cmCreateTestSourceList.cxx: BUG: Generate 0 into test
- driver instead of NULL.
-
-2003-02-05 16:56 king
-
- * Utilities/Release/cmake_release.sh: ENH: Added win32_zipfile and
- win32_upload commands.
-
-2003-02-05 16:53 king
-
- * Utilities/Release/cmake_release.sh: ENH: Added win32_zipfile and
- win32_upload commands.
-
-2003-02-05 15:14 king
-
- * Utilities/Release/cmake_release.sh: BUG: Updated release tag for
- 1.6.3.
-
-2003-02-05 15:07 king
-
- * Source/cmMakefile.h, Utilities/Release/cmake_release.sh: ENH:
- Updated to version 1.6.3.
-
-2003-02-05 15:05 king
-
- * Modules/CMakeSystemSpecificInformation.cmake: ENH:
- CMAKE_INSTALL_PREFIX should not be advanced on UNIX.
-
-2003-02-05 15:02 king
-
- * Modules/Platform/HP-UX.cmake: BUG: Optimization flags use +
- prefix, not -.
-
-2003-02-05 15:01 king
-
- * Source/CursesDialog/cmCursesLongMessageForm.cxx: BUG: Fixed crash
- when messages are too long.
-
-2003-02-05 14:58 king
-
- * Source/cmGlobalGenerator.cxx: BUG: Bug in NOTFOUND error
- reporting logic.
-
-2003-02-05 14:55 hoffman
-
- * Modules/Platform/HP-UX.cmake: fix default release flags for hp
-
-2003-02-05 14:55 king
-
- * Source/: cmCacheManager.cxx, cmCacheManager.h: ENH: Better error
- checking for cache iterator.
-
-2003-02-04 15:37 hoffman
-
- * Modules/CMakeSystemSpecificInformation.cmake: move cmake install
- out of advanced
-
-2003-02-04 15:37 hoffman
-
- * Source/cmGlobalGenerator.cxx: BUG: add better testing for
- notfound
-
-2003-02-04 14:37 berk
-
- * Modules/: FindMangledMesa.cmake, FindOSMesa.cmake: Created
- modules for Mesa headers and libraries.
-
-2003-02-04 14:31 hoffman
-
- * Source/CursesDialog/cmCursesLongMessageForm.cxx: BUG: don't let
- the messages get too big
-
-2003-02-04 14:01 martink
-
- * Source/: cmCacheManager.h, cmCacheManager.cxx: safer operation of
- iterators
-
-2003-02-04 09:50 andy
-
- * Source/cmVTKWrapJavaCommand.cxx: Oops, std namespace
-
-2003-02-04 09:48 andy
-
- * Source/cmVTKWrapJavaCommand.cxx: Generate java dependency files
-
-2003-02-03 23:08 king
-
- * Utilities/Release/: cmake_release.sh: ENH: Improved robustness of
- remote invocation. Added more documentation.
-
-2003-02-03 22:46 king
-
- * Utilities/Release/: cmake_release.sh: ENH: Added documentation
- and usage.
-
-2003-02-03 13:31 hoffman
-
- * Tests/: Complex/CMakeLists.txt, ComplexOneConfig/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt: ENH: add a better test for
- lib deps
-
-2003-02-03 12:02 king
-
- * Utilities/Release/cmake_release.sh: ENH: Updated version to
- 1.6.2.
-
-2003-02-03 12:01 king
-
- * Source/: cmFindFileCommand.cxx, cmFindFileCommand.h,
- cmFindLibraryCommand.cxx, cmFindPackageCommand.cxx,
- cmFindPathCommand.cxx, cmFindProgramCommand.cxx,
- cmFindProgramCommand.h, cmGetFilenameComponentCommand.cxx,
- cmGlobalGenerator.cxx, cmITKWrapTclCommand.cxx, cmSourceFile.cxx,
- cmSystemTools.cxx, cmSystemTools.h: ENH: Added new NOTFOUND
- notification feature.
-
-2003-02-03 11:50 king
-
- * Source/cmMakefile.h: ENH: Updated from version 1.6.1 to 1.6.2.
-
-2003-02-03 11:49 king
-
- * Source/cmExportLibraryDependencies.cxx: BUG: Removed generation
- of stray paren.
-
-2003-02-03 09:53 king
-
- * Source/cmExportLibraryDependencies.cxx: BUG: Removed generation
- of stray paren.
-
-2003-02-02 22:32 king
-
- * Source/CursesDialog/cmCursesStandardIncludes.h: ENH: Cleaned up
- sgi unreferenced warning hack.
-
-2003-02-02 11:45 hoffman
-
- * Source/cmGlobalGenerator.cxx: fix warning
-
-2003-02-01 16:39 hoffman
-
- * Source/cmMakefile.cxx: ENH: fix warning
-
-2003-02-01 16:39 hoffman
-
- * Source/cmAddLibraryCommand.h: ENH: fix doc line
-
-2003-02-01 16:27 hoffman
-
- * Source/CursesDialog/cmCursesStandardIncludes.h: BUG: add missing
- ;
-
-2003-01-31 15:01 hoffman
-
- * Modules/FindOpenGL.cmake: ENH: add checking for NOTFOUND
-
-2003-01-31 14:39 hoffman
-
- * Modules/FindOpenGL.cmake, Source/cmGlobalGenerator.cxx: ENH: add
- checking for NOTFOUND
-
-2003-01-31 13:50 hoffman
-
- * Source/: cmFindFileCommand.cxx, cmFindFileCommand.h,
- cmFindLibraryCommand.cxx, cmFindPackageCommand.cxx,
- cmFindPathCommand.cxx, cmFindProgramCommand.cxx,
- cmFindProgramCommand.h, cmGetFilenameComponentCommand.cxx,
- cmGlobalGenerator.cxx, cmITKWrapTclCommand.cxx,
- cmIncludeDirectoryCommand.cxx, cmLinkLibrariesCommand.cxx,
- cmMakefile.cxx, cmSourceFile.cxx, cmSystemTools.cxx,
- cmSystemTools.h, cmTargetLinkLibrariesCommand.cxx: ENH: add
- checking for NOTFOUND
-
-2003-01-31 13:24 king
-
- * Source/cmMakefile.h, Utilities/Release/cmake_release.sh: ENH:
- Updated to version 1.6.1 from 1.6.0.
-
-2003-01-31 13:18 king
-
- * Source/cmWin32ProcessExecution.cxx: Merge from HEAD. Use process
- output for error reporting instead of stdout.
-
-2003-01-31 13:04 king
-
- * Modules/FindLATEX.cmake: ENH: Changes to work on windows. Merged
- from HEAD.
-
-2003-01-31 11:52 king
-
- * Modules/FindFLTK.cmake: BUG: Need FIND_PROGRAM instead of
- FIND_FILE to find fluid.exe.
-
-2003-01-31 11:49 king
-
- * Modules/FindPerl.cmake: ENH: Added ActivePerl/804 as a search
- path.
-
-2003-01-31 11:44 king
-
- * Modules/CMakeSystemSpecificInformation.cmake: ERR: Removed stray
- double quote.
-
-2003-01-31 11:41 king
-
- * Utilities/Release/cmake_release.sh: ENH: Another merge from
- branch 1.6.
-
-2003-01-31 11:40 king
-
- * Modules/FindX11.cmake: BUG: Fix for cygwin's X11.
-
-2003-01-31 11:36 king
-
- * Source/cmakewizard.cxx: ENH: cmake -i on HP needs printf instead
- of cout.
-
-2003-01-31 11:35 king
-
- * Source/: CMakeLists.txt: BUG: Change install location of
- cmCPluginAPI header.
-
-2003-01-31 08:47 martink
-
- * Source/CursesDialog/cmCursesStandardIncludes.h: fixed warnings
-
-2003-01-30 14:34 andy
-
- * Source/: cmIncludeDirectoryCommand.cxx,
- cmLinkLibrariesCommand.cxx, cmTargetLinkLibrariesCommand.cxx: Add
- some error checking for missing include directories and link
- libraries
-
-2003-01-30 14:34 andy
-
- * Modules/CMakeSystemSpecificInformation.cmake: Remove extra quote
-
-2003-01-30 13:19 hoffman
-
- * Source/cmakewizard.cxx: BUG: can not mix cout and fgets on hp
-
-2003-01-30 11:50 king
-
- * Source/CursesDialog/cmCursesStandardIncludes.h: ERR: Fixing
- attempt to remove warnings.
-
-2003-01-29 14:20 king
-
- * Source/CursesDialog/cmCursesStandardIncludes.h: ERR: Another
- attempt to get rid of unreferenced inline function warnings on
- SGI.
-
-2003-01-29 13:56 king
-
- * Utilities/Release/cmake_release.sh: ENH: Use * instead of
- directory list for installation tarball.
-
-2003-01-29 13:46 king
-
- * Utilities/Release/cmake_release.sh: BUG: Need to include the
- include directory from the installation.
-
-2003-01-29 09:06 andy
-
- * Modules/FindX11.cmake: Attempt to fix build problem on some
- platforms
-
-2003-01-28 15:48 hoffman
-
- * Source/cmFindFileCommand.h: ENH: better docs
-
-2003-01-28 15:44 hoffman
-
- * Modules/: FindFLTK.cmake, FindQt.cmake: ENH: change FIND_FILE to
- FIND_PROGRAM
-
-2003-01-28 08:53 andy
-
- * Modules/FindLATEX.cmake: Make things work on unix and add DVIPDF
-
-2003-01-27 12:25 andy
-
- * Source/cmWin32ProcessExecution.cxx: Fix output variable and
- remove this->m_ to be only m_
-
-2003-01-27 12:18 andy
-
- * Source/cmWin32ProcessExecution.cxx: Move errors to output
- variable
-
-2003-01-24 17:40 king
-
- * Utilities/Release/cygwin-package.sh.in: ENH: Merged more changes
- from 1.6 branch.
-
-2003-01-24 17:34 king
-
- * Utilities/Release/cygwin-package.sh.in: ENH: Added testing to
- packaging script.
-
-2003-01-24 15:48 king
-
- * Utilities/Release/cmake_release.sh: ENH: Merged more changes from
- 1.6 branch.
-
-2003-01-24 15:02 king
-
- * Utilities/Release/cmake_release.sh: ENH: Added cygwin_upload
- function.
-
-2003-01-24 14:40 king
-
- * Utilities/Release/: cmake_release.sh, config_AIX, config_Darwin,
- config_IRIX64, config_Linux, config_OSF1, config_SunOS: ENH:
- Merged 1.6-branch changes to release scripts.
-
-2003-01-24 14:29 king
-
- * Utilities/Release/: config_AIX, config_Darwin, config_IRIX64,
- config_Linux, config_OSF1, config_SunOS: ENH: Use verbose
- makefile during release build.
-
-2003-01-24 13:55 king
-
- * Utilities/Release/cmake_release.sh: ENH: Updated checkout
- revision to Release-1-6-0 tag.
-
-2003-01-24 13:53 king
-
- * Modules/Platform/: HP-UX.cmake: BUG: Added missing link flag to
- export symbols from an executable.
-
-2003-01-24 11:49 king
-
- * Utilities/Release/cmake_release.sh: ENH: Updated for 1.6.0
- release over 1.6.beta2.
-
-2003-01-24 11:45 king
-
- * Utilities/: cmake_release_config_darwin,
- cmake_release_config_hpux, cmake_release_config_irix,
- cmake_release_config_linux, cmake_release_config_osf,
- cmake_release_config_sun, cmake_release_cygwin.sh,
- cmake_release_unix_config.sh, cmake_release_version.sh: ENH:
- Removing old release scripts. CMake 1.6 now has its own copy of
- the release scripts.
-
-2003-01-24 11:45 king
-
- * Utilities/: cmake-cygwin-package.sh, cmake_release_unix_build.sh,
- cmake_release_unix_package.sh, Release/cmake_release.sh,
- Release/config_AIX, Release/config_CYGWIN_NT-5.1,
- Release/config_Darwin, Release/config_HP-UX,
- Release/config_IRIX64, Release/config_Linux, Release/config_OSF1,
- Release/config_SunOS, Release/cygwin-package.sh.in: ENH: Release
- branch should contain its own release scripts.
-
-2003-01-24 11:41 king
-
- * Utilities/Release/: cmake_release.sh, config_AIX, config_Darwin,
- config_HP-UX, config_Linux, config_OSF1, config_SunOS: ENH:
- Enabled testing during release build.
-
-2003-01-24 10:33 king
-
- * Source/CursesDialog/cmCursesStandardIncludes.h: ERR: Fixed
- unreferenced termios declaration warning.
-
-2003-01-23 10:42 barre
-
- * Modules/FindLATEX.cmake: no message
-
-2003-01-23 10:37 barre
-
- * Modules/FindLATEX.cmake: FIX: - rename some entries (COMPILE ->
- COMPILER, and the converters -> _CONVERTER) - make sure that
- Window system are given a chance to find Latex and the converters
- if MikTex and GhostScript are installed (but not in the PATH)
-
-2003-01-23 10:36 barre
-
- * Modules/FindPerl.cmake: FIX: the current version of Perl is 5.8
-
-2003-01-23 10:35 barre
-
- * Source/cmGetFilenameComponentCommand.cxx: FIX: this command was
- not processing its arg to expand registery values
-
-2003-01-22 15:00 martink
-
- * Modules/Platform/gcc.cmake: joins from the main tree
-
-2003-01-22 14:59 martink
-
- * Modules/Platform/gcc.cmake: minor change to default compile flags
-
-2003-01-22 14:49 martink
-
- * Modules/: FindMPEG2.cmake, FindSDL.cmake: merge from branch
-
-2003-01-22 14:33 hoffman
-
- * Source/cmGlobalGenerator.h: ENH: merge from branch
-
-2003-01-22 14:21 hoffman
-
- * Tests/X11/CMakeLists.txt: ENH: merge from head
-
-2003-01-22 14:20 hoffman
-
- * Utilities/Doxygen/doc_makeall.sh.in: merge from main tree
-
-2003-01-22 14:20 hoffman
-
- * Source/cmGlobalGenerator.cxx: merge from main tree, test for
- working c and c++ compilers
-
-2003-01-22 14:17 hoffman
-
- * Templates/: cconfigure, cconfigure.in, cxxconfigure,
- cxxconfigure.in: merge with main branch and remove unused scripts
-
-2003-01-22 14:13 hoffman
-
- * Modules/FindAndImportCMakeProject.cmake: moved to c++ command
-
-2003-01-22 12:38 martink
-
- * Modules/: CMakeTestCCompiler.cmake, CMakeTestCXXCompiler.cmake:
- joins from the main tree
-
-2003-01-22 12:31 martink
-
- * Source/: cmCommands.cxx, cmFindPathCommand.cxx,
- cmGlobalUnixMakefileGenerator.cxx,
- cmGlobalVisualStudio6Generator.cxx, cmMakefile.cxx, cmMakefile.h,
- cmake.cxx: joins from the main tree
-
-2003-01-22 12:29 hoffman
-
- * Modules/: CMakeTestCCompiler.cmake, CMakeTestCXXCompiler.cmake:
- ENH: only run test for working c and cxx compiler once
-
-2003-01-22 12:28 martink
-
- * Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Modules/CMakeTestCCompiler.cmake,
- Modules/CMakeTestCXXCompiler.cmake,
- Modules/CheckIncludeFiles.cmake, Modules/FindFLTK.cmake,
- Modules/FindImageMagick.cmake, Modules/FindTclsh.cmake,
- Modules/FindVTK.cmake, Modules/FindX11.cmake,
- Modules/Platform/CYGWIN.cmake, Source/cmMessageCommand.cxx,
- Source/cmMessageCommand.h, Source/cmSystemTools.cxx,
- Source/cmSystemTools.h, Source/CursesDialog/ccmake.cxx,
- Source/CursesDialog/cmCursesMainForm.cxx,
- Source/CursesDialog/cmCursesMainForm.h,
- Source/cmExportLibraryDependencies.cxx,
- Source/cmExportLibraryDependencies.h,
- Source/cmFindPackageCommand.cxx, Source/cmFindPackageCommand.h:
- joins from the main tree
-
-2003-01-22 11:44 martink
-
- * Source/cmLocalVisualStudio6Generator.cxx: fixed spelling mistake
-
-2003-01-22 11:27 martink
-
- * Source/CursesDialog/ccmake.cxx: spelling fix
-
-2003-01-22 11:21 martink
-
- * Modules/FindOpenGL.cmake: merge from branch
-
-2003-01-22 11:16 martink
-
- * Modules/LinkQT.cmake: removed since no longer used
-
-2003-01-22 11:11 martink
-
- * Modules/FindLATEX.cmake: merge branch change into main tree
-
-2003-01-22 10:40 king
-
- * Source/cmFindPackageCommand.cxx: ENH: Added support for looking
- through CMAKE_MODULE_PATH to locate Find<name>.cmake modules.
-
-2003-01-22 10:33 king
-
- * Source/: cmake.cxx, CursesDialog/ccmake.cxx,
- CursesDialog/cmCursesMainForm.cxx,
- CursesDialog/cmCursesMainForm.h: BUG: Fixed crash when CMAKE_ROOT
- cannot be found.
-
-2003-01-22 09:34 hoffman
-
- * Source/cmake.cxx: BUG: fix command line to take -G only
-
-2003-01-22 09:28 king
-
- * Source/cmGlobalVisualStudio6Generator.cxx: BUG: CMake 1.4
- configured projects did not build with new CMake.
-
-2003-01-21 17:15 king
-
- * Source/: cmCommands.cxx, cmFindPackageCommand.cxx,
- cmFindPackageCommand.h: ENH: Added FIND_PACKAGE command prototyp.
-
-2003-01-21 16:46 king
-
- * Source/cmake.cxx: BUG: Use CMakeDefaultMakeRuleVariables.cmake to
- locate modules directory instead of FindVTK.cmake.
-
-2003-01-21 15:03 king
-
- * Modules/FindVTK.cmake: ENH: Updated documentation.
-
-2003-01-21 14:01 andy
-
- * Modules/CheckIncludeFiles.cmake: This list can be really long.
- Only display the variable name
-
-2003-01-21 12:50 hoffman
-
- * Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Modules/CMakeTestCCompiler.cmake,
- Modules/CMakeTestCXXCompiler.cmake, Source/cmGlobalGenerator.cxx,
- Source/cmGlobalUnixMakefileGenerator.cxx, Source/cmMakefile.cxx,
- Source/cmMessageCommand.cxx, Source/cmMessageCommand.h,
- Source/cmSystemTools.cxx, Source/cmSystemTools.h: add a fatal
- error, and make sure c and c++ compilers work before using them
-
-2003-01-21 12:41 hoffman
-
- * Modules/Platform/CYGWIN.cmake: use export all symbols on cygwin
-
-2003-01-21 10:59 barre
-
- * Modules/FindImageMagick.cmake: IMPORTANT FIX: be extra-careful
- here on WIN32, we do NOT want CMake to look in the system's PATH
- env var to search for ImageMagick's convert.exe, otherwise it is
- going to pick Microsoft Window's own convert.exe, which is used
- to convert FAT partitions to NTFS format ! Depending on the
- options passed to convert.exe, there is a good chance you would
- kiss your hard-disk good-bye.
-
-2003-01-20 21:15 ibanez
-
- * Modules/FindLATEX.cmake: ENH: PS2PDF_COMPILE added. It looks for
- ps2pdf.
-
-2003-01-20 19:17 king
-
- * Source/cmMakefile.cxx: BUG: Fix for custom commands with spaces
- in paths. The arguments were not having spaces escaped.
-
-2003-01-20 18:54 king
-
- * Source/: cmLocalUnixMakefileGenerator.cxx: BUG: Fixed typo in
- previous fix.
-
-2003-01-20 18:52 king
-
- * Source/: cmLocalUnixMakefileGenerator.cxx: BUG: Fixed directory
- creation for spaces in install path.
-
-2003-01-20 16:59 hoffman
-
- * Source/cmCommands.cxx, Source/cmExportLibraryDependencies.cxx,
- Source/cmExportLibraryDependencies.h, Source/cmGlobalGenerator.h,
- Source/cmMakefile.h, Tests/Complex/CMakeLists.txt,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexRelativePaths/CMakeLists.txt: ENH: add a new command
- that allows exports of library dependencies from a project to a
- file
-
-2003-01-20 14:39 will
-
- * Modules/FindX11.cmake: BUG: fix missed CMAKE to X11 variable name
-
-2003-01-19 11:42 king
-
- * Source/cmSystemTools.cxx: ENH: Improved CopyFile error messages.
-
-2003-01-18 11:34 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.h, Templates/install-sh: BUG:
- Fixed make install to handle library prefix/suffix settings.
- Also fixed support for spaces in paths during make install.
-
-2003-01-17 18:14 king
-
- * Modules/: FindVTK.cmake: BUG: Fix for application of
- expand-list-variables.
-
-2003-01-17 18:01 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.h, Templates/install-sh: ENH:
- Support for spaces in paths during make install.
-
-2003-01-17 17:19 king
-
- * Modules/FindAndImportCMakeProject.cmake: ENH: Adding
- FIND_AND_IMPORT_CMAKE_PROJECT macro.
-
-2003-01-17 15:15 king
-
- * Utilities/Release/cmake_release.sh: ENH: Added sanity check for
- setting of WX_RESOURCES by config_Darwin for osx_install.
-
-2003-01-17 13:35 king
-
- * Utilities/Release/: cmake_release.sh, config_Darwin: ENH:
- Prototype for OSX packaging.
-
-2003-01-17 13:35 king
-
- * Utilities/Release/cmake_release.sh: ENH: Cygwin package is now
- created in a Cygwin subdirectory.
-
-2003-01-17 11:57 king
-
- * Utilities/Release/: cmake-cygwin-package.sh, cmake_release.sh,
- cygwin-package.sh.in: ENH: Renamed cmake-cygwin-package.sh to
- cygwin-package.sh.in and removed executable permission so it
- cannot be run accidentally. It must be run after being renamed
- to cmake-${VERSION}-${RELEASE}.
-
-2003-01-17 11:55 king
-
- * Utilities/Release/cmake_release.sh: ENH: clean now removes the
- entire release root directory.
-
-2003-01-17 11:51 king
-
- * Utilities/: cmake-cygwin-package.sh, cmake_release_config_aix,
- cmake_release_config_darwin, cmake_release_config_hpux,
- cmake_release_config_irix, cmake_release_config_linux,
- cmake_release_config_osf, cmake_release_config_sun,
- cmake_release_cygwin.sh, cmake_release_unix_build.sh,
- cmake_release_unix_config.sh, cmake_release_unix_package.sh,
- cmake_release_version.sh: ENH: Removing old release scripts and
- config files.
-
-2003-01-17 11:42 king
-
- * Utilities/Release/config_OSF1: ENH: Adding OSF release
- configuration.
-
-2003-01-17 11:05 king
-
- * Utilities/Release/cmake_release.sh: ENH: Added cygwin release
- support.
-
-2003-01-17 10:30 king
-
- * Utilities/Release/cmake-cygwin-package.sh: ENH: Adding cygwin
- packaging script to release directory.
-
-2003-01-17 10:28 hoffman
-
- * Source/cmFindPathCommand.cxx,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/complex.cxx: remove
- trailing slash from findpath command
-
-2003-01-17 10:28 hoffman
-
- * Tests/SystemInformation/: DumpInformation.cxx,
- SystemInformation.in: add some more prints
-
-2003-01-17 10:21 king
-
- * Utilities/Release/config_Linux: ENH: Removed old setting.
-
-2003-01-17 10:21 king
-
- * Utilities/Release/config_CYGWIN_NT-5.1: ENH: Cygwin release
- configuration.
-
-2003-01-17 09:52 king
-
- * Utilities/Release/cmake_release.sh: ENH: Added support for full
- remote packaging and copying back to local machine. Added
- support for uploading to FTP server.
-
-2003-01-17 09:20 king
-
- * Utilities/Release/config_HP-UX: ENH: Linking with
- -a,archive_shared instead of -a,archive so that the shared curses
- library can be used.
-
-2003-01-17 09:15 king
-
- * Utilities/Release/config_AIX: ERR: Can't build release static on
- aix.
-
-2003-01-17 09:08 hoffman
-
- * Utilities/Release/config_AIX: Add AIX config file
-
-2003-01-17 08:56 andy
-
- * Source/cmCTest.cxx: Remove warning about %e and %T
-
-2003-01-16 15:47 martink
-
- * Tests/: Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/complex.cxx: ENH: fix for
- compilers that need _
-
-2003-01-16 14:59 andy
-
- * Source/cmCTest.cxx: Add aix warning
-
-2003-01-16 14:15 andy
-
- * DartConfig.cmake: Add selection of drop method
-
-2003-01-16 14:05 barre
-
- * Utilities/Doxygen/doc_makeall.sh.in: FIX: HHC is now
- HTML_HELP_COMPILER
-
-2003-01-16 13:31 ibanez
-
- * Modules/FindFLTK.cmake: FIX: Quotes added around the list of libs
- to be added in Apple.
-
-2003-01-16 13:24 ibanez
-
- * Modules/FindFLTK.cmake: ENH: Platform dependent libraries added
- for APPLE.
-
-2003-01-16 13:02 andy
-
- * Source/CTest/cmCTestSubmit.cxx: Try to fix aix problem
-
-2003-01-16 12:45 andy
-
- * Source/CTest/cmCTestSubmit.cxx: Add proxy support for triggering
-
-2003-01-16 12:38 hoffman
-
- * Modules/FindFLTK.cmake: ENH: fix for borland and cygwin
-
-2003-01-16 12:30 andy
-
- * Source/CTest/cmCTestSubmit.cxx: Improve submtitting using http
-
-2003-01-16 09:57 andy
-
- * Source/CTest/cmCTestSubmit.cxx: Improve build, now it should
- build on mac and other platforms where include file depend on
- each other
-
-2003-01-16 08:40 hoffman
-
- * Source/cmMakefile.h: add back GetCMakeInstance
-
-2003-01-16 08:31 hoffman
-
- * Source/cmMakefile.h: fix duplicate member on branch
-
-2003-01-16 08:28 hoffman
-
- * Tests/: Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/complex.cxx: ENH: add the config
- directory to look for the loadable module
-
-2003-01-15 19:24 king
-
- * Utilities/Release/cmake_release.sh: BUG: error_log function
- should return 1 to stop execution of rest of script.
-
-2003-01-15 19:20 king
-
- * Utilities/Release/cmake_release.sh: ENH: Renamed package command
- to binary_tarball for clarity.
-
-2003-01-15 19:17 king
-
- * Utilities/Release/: cmake_release.sh, config_HP-UX: ENH: Release
- script now exports PATH and LD_LIBRARY_PATH to remove the burden
- from the configuration scripts.
-
-2003-01-15 19:14 king
-
- * Utilities/Release/config_HP-UX: BUG: Attempt to fix remote
- invocation.
-
-2003-01-15 19:04 king
-
- * Utilities/Release/config_HP-UX: ENH: Enabling verbose makefile
- generation for hp-ux build. This will ease hand-fixing of the
- build of ccmake.
-
-2003-01-15 19:02 king
-
- * Utilities/Release/cmake_release.sh: ENH: Cleaned up remote
- invocation.
-
-2003-01-15 18:51 king
-
- * Utilities/Release/cmake_release.sh: ENH: Improved clean target.
-
-2003-01-15 18:48 king
-
- * Utilities/Release/cmake_release.sh: BUG: Finished clean target
- and fixed grep for cvsroot in ~/.cvspass.
-
-2003-01-15 18:44 king
-
- * Utilities/Release/cmake_release.sh: BUG: CVS login command is
- login, not cvs_login.
-
-2003-01-15 18:43 king
-
- * Utilities/Release/config_aix: ERR: Removed old config file.
-
-2003-01-15 18:42 king
-
- * Utilities/Release/: cmake_release.sh, config_Darwin,
- config_HP-UX, config_IRIX64, config_Linux, config_SunOS,
- config_aix: ENH: New release script prototype.
-
-2003-01-15 18:28 ibanez
-
- * Modules/FindFLTK.cmake: ENH: Libraries are not marked as ADVANCED
- now.
-
-2003-01-15 18:02 king
-
- * Source/cmMakefile.h: ERR: Removed duplicate declaration.
-
-2003-01-15 17:45 hoffman
-
- * Source/cmMakefile.h: ENH: fix for ibm build
-
-2003-01-15 17:31 hoffman
-
- * Source/CMakeLists.txt, Source/cmaketest.cxx,
- Tests/Complex/Executable/complex.cxx,
- Tests/Complex/Library/CMakeLists.txt,
- Tests/Complex/Library/moduleFile.c,
- Tests/Complex/Library/moduleFile.h,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexOneConfig/Library/CMakeLists.txt,
- Tests/ComplexOneConfig/Library/moduleFile.c,
- Tests/ComplexOneConfig/Library/moduleFile.h,
- Tests/ComplexRelativePaths/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Library/CMakeLists.txt,
- Tests/ComplexRelativePaths/Library/moduleFile.c,
- Tests/ComplexRelativePaths/Library/moduleFile.h: ENH: add testing
- for modules and one two config modes for cmaketest
-
-2003-01-15 17:02 hoffman
-
- * Tests/: LoadCommand/CMakeCommands/CMakeLists.txt,
- LoadCommandOneConfig/CMakeCommands/CMakeLists.txt: use module on
- all platforms
-
-2003-01-15 15:32 hoffman
-
- * Modules/FindOpenGL.cmake: fix from head
-
-2003-01-15 15:02 hoffman
-
- * Modules/FindOpenGL.cmake: BUG: fix for OSX with x11 gl stuff
-
-2003-01-15 13:25 hoffman
-
- * Modules/Platform/Windows-bcc32.cmake: merge with head fix for
- borland flag and bad set statment
-
-2003-01-15 13:22 hoffman
-
- * Modules/Platform/Windows-bcc32.cmake: BUG: fix flags for borland
- link shared and module
-
-2003-01-15 13:14 hoffman
-
- * Modules/FindOpenGL.cmake: BUG: make sure set command has proper
- quoting
-
-2003-01-15 13:12 hoffman
-
- * Modules/FindOpenGL.cmake: quote the variable
-
-2003-01-15 11:59 hoffman
-
- * Modules/FindTclsh.cmake: look for cygtcl83
-
-2003-01-15 11:32 king
-
- * CMakeLists.txt: ENH: Merge of backward compatability changes from
- trunk.
-
-2003-01-15 11:17 king
-
- * Utilities/cmake_release_version.sh: ENH: Updated version for
- 1.6.beta2 release.
-
-2003-01-15 11:03 martink
-
- * Source/cmMakefile.h: updated patch level
-
-2003-01-14 22:10 andy
-
- * Source/CTest/: cmCTestSubmit.cxx, cmCTestSubmit.h: Add support
- for http submit. Also, add support for proxy, but it does not
- work yet.
-
-2003-01-14 22:10 andy
-
- * Source/cmCTest.cxx: Add support for http submit
-
-2003-01-14 09:53 andy
-
- * Source/: cmMakefile.cxx, cmMakefile.h: Make GetCMakeInstance
- private and clean cxx file
-
-2003-01-13 10:15 martink
-
- * Modules/CheckSymbolExists.cmake: join from head
-
-2003-01-13 10:11 martink
-
- * Modules/FindQt.cmake: merge from branch
-
-2003-01-13 10:07 martink
-
- * Modules/Platform/Linux-como.cmake: joined to head
-
-2003-01-13 10:04 martink
-
- * Source/cmLocalVisualStudio6Generator.cxx,
- Tests/Complex/Library/testConly.c,
- Tests/ComplexOneConfig/Library/testConly.c,
- Tests/ComplexRelativePaths/Library/testConly.c: joined to head
-
-2003-01-13 09:30 hoffman
-
- * Source/cmLocalVisualStudio6Generator.cxx,
- Tests/Complex/Library/testConly.c,
- Tests/ComplexOneConfig/Library/testConly.c,
- Tests/ComplexRelativePaths/Library/testConly.c: BUG: fix
- CMAKE_C_FLAGS for visual studio 6, and add a test case
-
-2003-01-13 09:27 martink
-
- * Modules/CheckIncludeFileCXX.cmake: joined to head
-
-2003-01-13 09:24 martink
-
- * Modules/FindPNG.cmake: fixed typo
-
-2003-01-13 09:22 martink
-
- * Modules/: TestForANSIForScope.cmake, TestForSTDNamespace.cmake:
- joined to head
-
-2003-01-13 09:12 martink
-
- * Modules/: CMakeVS6BackwardCompatibility.cmake,
- CMakeVS7BackwardCompatibility.cmake, CheckTypeSize.cmake,
- FindX11.cmake: joined to head
-
-2003-01-13 09:09 martink
-
- * Source/cmake.cxx, Source/cmake.h, Modules/FindOpenGL.cmake,
- Modules/CMakeBackwardCompatibilityC.cmake,
- Modules/CMakeBackwardCompatibilityCXX.cmake: joined to head
-
-2003-01-13 09:06 martink
-
- * Source/: cmMakefile.cxx, cmVariableWatch.h: joined to head
-
-2003-01-13 09:02 martink
-
- * Source/: cmGlobalGenerator.cxx,
- cmLocalVisualStudio6Generator.cxx: joined to head
-
-2003-01-13 08:51 martink
-
- * Source/cmAbstractFilesCommand.cxx: joined
-
-2003-01-13 08:50 martink
-
- * Source/CMakeLists.txt: added install target
-
-2003-01-13 08:14 andy
-
- * Source/cmLocalVisualStudio6Generator.cxx: Add space between
- arguments
-
-2003-01-12 22:28 andy
-
- * Modules/CheckSymbolExists.cmake: Add macro for checking if symbol
- exists
-
-2003-01-12 10:50 andy
-
- * Source/cmLocalVisualStudio6Generator.cxx: Use C flags too. Not
- exactly the right solution but it will have to do for now.
-
-2003-01-11 21:47 andy
-
- * Source/CTest/: cmCTestSubmit.cxx, cmCTestSubmit.h: Add triggering
-
-2003-01-11 21:47 andy
-
- * Source/cmCTest.cxx: Fix time output and add triggering
-
-2003-01-11 10:57 andy
-
- * Source/CMakeLists.txt: Fix testing of curl on windows
-
-2003-01-10 20:22 andy
-
- * Source/CMakeLists.txt: Add curl testing
-
-2003-01-10 17:31 hoffman
-
- * CMakeLists.txt: ENH: make it work with cmake 1.6 with no
- backwards compatibility
-
-2003-01-10 11:07 martink
-
- * Source/cmGlobalGenerator.cxx: fix warnings
-
-2003-01-10 09:02 martink
-
- * Source/cmake.cxx: compiler warning
-
-2003-01-10 07:50 andy
-
- * Source/CTest/cmCTestSubmit.cxx: Method should return something
-
-2003-01-09 15:54 martink
-
- * Modules/FindOpenGL.cmake: better fix for win32
-
-2003-01-09 14:00 martink
-
- * Modules/FindOpenGL.cmake: update to not put PROJECT_SOURCE_DIR as
- OPENGL_PATH
-
-2003-01-09 12:18 martink
-
- * Source/: cmake.cxx, cmake.h, cmGlobalGenerator.cxx,
- cmGlobalGenerator.h: fix bug in env settings
-
-2003-01-09 11:35 martink
-
- * Source/: cmMakefile.cxx, cmVariableWatch.h: more option on var
- watches
-
-2003-01-09 11:34 martink
-
- * Modules/CheckTypeSize.cmake: minor fix to backw compat
-
-2003-01-09 11:32 hoffman
-
- * Source/cmGlobalGenerator.cxx: fix warning
-
-2003-01-09 11:28 hoffman
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h: restore the
- environment for cxx and cc in global generator
-
-2003-01-09 11:27 hoffman
-
- * Source/cmVariableWatch.h: use cmstdstring in maps
-
-2003-01-09 09:16 hoffman
-
- * Source/cmVariableWatch.h: fix syntax for addwatch
-
-2003-01-09 08:50 martink
-
- * Modules/: CMakeVS6BackwardCompatibility.cmake,
- CMakeVS7BackwardCompatibility.cmake: added big endian stuff
-
-2003-01-09 08:47 martink
-
- * Source/cmGlobalGenerator.cxx: only load bw compat if
- CMAKE_BACK... is set
-
-2003-01-09 08:47 martink
-
- * Source/cmake.cxx: added watches for access of bw compat vars
-
-2003-01-09 08:44 martink
-
- * Source/cmAbstractFilesCommand.cxx: now complains more
-
-2003-01-08 14:41 hoffman
-
- * Utilities/cmake_release_config_aix: release script for aix
-
-2003-01-08 13:24 andy
-
- * Source/: CMakeLists.txt, Makefile.in, cmMakefile.cxx,
- cmMakefile.h, cmVariableWatch.cxx, cmVariableWatch.h, cmake.cxx,
- cmake.h: Add variable watch support on the branch
-
-2003-01-08 13:24 andy
-
- * Source/cmTryCompileCommand.cxx: Merge try compile fixes to branch
-
-2003-01-08 12:59 andy
-
- * Source/: CMakeLists.txt, Makefile.in, cmMakefile.cxx,
- cmMakefile.h, cmVariableWatch.cxx, cmVariableWatch.h, cmake.cxx,
- cmake.h: Add option of watching variables
-
-2003-01-08 12:12 hoffman
-
- * Modules/CMakeBackwardCompatibilityCXX.cmake,
- Modules/CheckIncludeFileCXX.cmake,
- Modules/TestForANSIForScope.cmake,
- Modules/TestForSTDNamespace.cmake,
- Source/cmTryCompileCommand.cxx: ENH: only force the use of ansi
- flags in backwards mode
-
-2003-01-08 11:58 iscott
-
- * Modules/FindQt.cmake: mark all variables advanced
-
-2003-01-08 11:53 andy
-
- * Tests/X11/CMakeLists.txt: Change name of variable
-
-2003-01-08 11:45 andy
-
- * Modules/: CMakeBackwardCompatibilityC.cmake, FindX11.cmake: Fix
- FindX11 to match convention
-
-2003-01-08 10:48 iscott
-
- * Modules/: FindMPEG2.cmake, FindPNG.cmake, FindSDL.cmake,
- LinkQT.cmake: LinkQT.cmake has been deprecated for ages, removed
- it now. Fixed mistake in FindPNG.cmake Donated FindMPEG2 and
- FindSDL from VXL.
-
-2003-01-07 22:24 andy
-
- * Source/CTest/: cmCTestSubmit.cxx, cmCTestSubmit.h: Implement FTP
- uploading
-
-2003-01-07 22:23 andy
-
- * Source/CTest/CMakeLists.txt: Add more places to search for
- library, also include curl directory when compiling
-
-2003-01-07 22:23 andy
-
- * Source/cmCTest.cxx: New signature
-
-2003-01-07 15:04 hoffman
-
- * CMakeLists.txt: ENH: fix install of cmake.1
-
-2003-01-07 14:57 hoffman
-
- * CMakeLists.txt: fix reg ex for install cmake man
-
-2003-01-07 13:52 martink
-
- * Source/CMakeLists.txt: adde dinstall for cmCPluginAPI.h
-
-2003-01-07 13:19 hoffman
-
- * CMakeLists.txt, Templates/CMakeLists.txt: ENH: fix install and
- initial prefix
-
-2003-01-07 13:05 hoffman
-
- * Templates/CMakeLists.txt: ENH: fix install target for templates
-
-2003-01-07 12:54 hoffman
-
- * Templates/: cconfigure, cconfigure.in, cxxconfigure,
- cxxconfigure.in: remove unused files
-
-2003-01-07 12:05 hoffman
-
- * CMakeLists.txt: use bootstrap initial flags
-
-2003-01-07 10:22 king
-
- * Utilities/cmake_release_config_irix: BUG: Version number on rolle
- is 6.4, not 6.5.
-
-2003-01-06 23:13 andy
-
- * Source/: cmCTest.cxx, cmCTest.h: Work on submitting
-
-2003-01-06 23:07 andy
-
- * Source/CTest/: CMakeLists.txt, cmCTestSubmit.cxx,
- cmCTestSubmit.h: Start working on improved test
-
-2003-01-06 16:09 king
-
- * Utilities/cmake_release_config_hpux: ERR: Fixes for linking
- statically with -ldld.
-
-2003-01-06 15:41 hoffman
-
- * ChangeLog.txt: ENH: update change log for new version
-
-2003-01-06 15:21 king
-
- * Utilities/cmake_release_config_sun: ERR: Fix for building static
- with -ldl on sun.
-
-2003-01-06 14:56 king
-
- * Utilities/cmake_release_config_linux: ERR: Fixed typo.
-
-2003-01-06 14:30 biddi
-
- * Source/cmVTKWrapTclCommand.cxx: Fix a problem with TCL wrapping
- if the source files have a relative path. The dependency is not
- correctly handled
-
-2003-01-06 14:27 king
-
- * Utilities/: cmake_release_config_hpux,
- cmake_release_config_linux, cmake_release_config_sun: ENH:
- Updated for static executable.
-
-2003-01-06 11:31 king
-
- * Utilities/cmake_release_version.sh: ENH: Updated for 1.6 beta 1
- release.
-
-2003-01-06 11:23 king
-
- * Utilities/: cmake_release_config_darwin,
- cmake_release_config_hpux, cmake_release_config_irix,
- cmake_release_config_linux, cmake_release_config_osf,
- cmake_release_config_sun, cmake_release_cygwin.sh,
- cmake_release_unix_config.sh, cmake_release_version.sh: ENH:
- Updated for CMake 1.6 release. Version number is now in a single
- file that is sourced by all others.
-
-2003-01-06 10:58 martink
-
- * Source/: cmCPluginAPI.h: updated version
-
-2003-01-06 10:43 martink
-
- * CMake.rtf: updated docs
-
-2003-01-06 09:39 martink
-
- * Source/: cmMakefile.h: update version
-
-2003-01-06 09:36 martink
-
- * Source/cmMakefile.h: updated version
-
-2003-01-06 09:32 king
-
- * Modules/Platform/Linux-como.cmake: ENH: Added shared library
- settings.
-
-2003-01-06 09:04 hoffman
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeDetermineCXXCompiler.cmake: ENH: look for AIX compiler as
- well
-
-2003-01-06 08:39 hoffman
-
- * Modules/Platform/OSF1.cmake: add shared path for OSF
-
-2003-01-05 11:24 hoffman
-
- * Modules/Platform/OSF1.cmake: BUG: revert back to rpath,
-
-2003-01-03 20:26 andy
-
- * Modules/CheckTypeSize.cmake: Remove debug
-
-2003-01-03 20:03 andy
-
- * Modules/: CheckFunctionExists.cmake, CheckLibraryExists.cmake,
- CheckTypeSize.cmake, CheckVariableExists.cmake: Fix problems with
- required flags
-
-2003-01-03 19:21 andy
-
- * Modules/: CheckFunctionExists.cmake, CheckIncludeFile.cmake,
- CheckIncludeFiles.cmake, CheckLibraryExists.cmake,
- CheckTypeSize.cmake, CheckVariableExists.cmake: Add required
- flags
-
-2003-01-03 17:36 king
-
- * Modules/FindPythonLibs.cmake: ENH: Find python framework on Mac
- OSX.
-
-2003-01-03 16:23 hoffman
-
- * Modules/Platform/OSF1.cmake: try to fix rpath on OSF
-
-2003-01-03 16:14 andy
-
- * Tests/COnly/libc2.h: Fix problem with test on Borland
-
-2003-01-03 08:12 hoffman
-
- * Modules/Platform/SunOS.cmake: BUG: bad rpath flag for suns
-
-2003-01-02 10:27 king
-
- * Source/cmCPluginAPI.h: ENH: Changed magic numbers to reserved.
- Added CMAKE_VERSION_MAJOR and CMAKE_VERSION_MINOR macros to allow
- commands to do conditional compilation across multiple versions
- of CMake.
-
-2003-01-02 09:57 king
-
- * Modules/CMakeBackwardCompatibilityC.cmake: BUG: Don't add
- -I/usr/include as an X_CFLAGS setting.
-
-2003-01-02 09:57 king
-
- * Modules/FindX11.cmake: BUG: Fixed ordering of X11 search.
-
-2003-01-02 09:06 andy
-
- * Tests/COnly/CMakeLists.txt: Rename libraries from c1 to testc1
-
-2003-01-02 08:51 hoffman
-
- * Modules/Platform/: AIX.cmake, OSF1.cmake, SunOS.cmake: clean up
- some c/cxx issues
-
-2003-01-01 18:00 andy
-
- * Modules/CheckIncludeFiles.cmake: Add macro for checking if a
- swequence of includes can be includes
-
-2003-01-01 17:35 andy
-
- * Tests/COnly/CMakeLists.txt: Test conversion from ascii to string
-
-2003-01-01 17:34 andy
-
- * Source/: cmStringCommand.cxx, cmStringCommand.h: Add a way to
- convert ascii to string
-
-2003-01-01 16:25 andy
-
- * Modules/: CheckFunctionExists.cmake, CheckLibraryExists.cmake,
- CheckTypeSize.cmake, CheckVariableExists.cmake: To prevent cmake
- from breaking up arguments, put quotes around them
-
-2003-01-01 15:02 andy
-
- * Modules/CheckVariableExists.cmake: Add a way to add custom
- libraries to the mix. Also add status reporting
-
-2003-01-01 15:01 andy
-
- * Modules/: CheckFunctionExists.cmake, CheckLibraryExists.cmake,
- CheckTypeSize.cmake: Add a way to add custom libraries to the mix
-
-2003-01-01 14:26 andy
-
- * Tests/COnly/: libc2.c, libc2.h: Shared library should export
- symbols on windows
-
-2002-12-31 15:22 andy
-
- * Tests/COnly/: CMakeLists.txt, conly.c, libc1.c, libc1.h, libc2.c,
- libc2.h: Test also stating and shared libraries
-
-2002-12-31 13:08 king
-
- * Modules/: CMakeDefaultMakeRuleVariables.cmake,
- Platform/Darwin.cmake, Platform/HP-UX.cmake,
- Platform/Linux-como.cmake, Platform/Windows-bcc32.cmake,
- Platform/Windows-cl.cmake: ENH: Added <LINK_FLAGS> to link rules.
-
-2002-12-31 12:59 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: When there are no
- link flags, we want an empty string, not a null pointer.
-
-2002-12-31 12:41 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: Support LINK_FLAGS
- property for static libraries.
-
-2002-12-30 11:48 hoffman
-
- * Modules/Platform/AIX.cmake: ENH: fix shared libraries on AIX
-
-2002-12-30 11:02 king
-
- * Modules/CMakeBackwardCompatibilityC.cmake, Modules/CheckSizeOf.c,
- Modules/CheckSizeOf.cmake, Modules/CheckTypeSize.c,
- Modules/CheckTypeSize.cmake, Tests/LoadCommand/CMakeLists.txt,
- Tests/LoadCommandOneConfig/CMakeLists.txt: ENH: Renamed
- Modules/CheckSizeOf to Modules/CheckTypeSize for consistency with
- the macro name that is defined by the module.
-
-2002-12-30 08:18 andy
-
- * Source/cmSystemTools.cxx: Fix problem on windows with network
- paths
-
-2002-12-30 07:47 hoffman
-
- * Source/: cmAbstractFilesCommand.h, cmAddCustomCommandCommand.h,
- cmAddCustomTargetCommand.h, cmAddDefinitionsCommand.h,
- cmAddExecutableCommand.h, cmAddTestCommand.h,
- cmAuxSourceDirectoryCommand.h, cmBuildCommand.h,
- cmBuildNameCommand.h, cmFLTKWrapUICommand.h: ENH: clean up docs
- some
-
-2002-12-27 11:14 starreveld
-
- * Modules/FindPythonLibs.cmake: ENH: find python framework and
- include files on OSX
-
-2002-12-26 19:59 andy
-
- * Modules/CMakeJavaCompiler.cmake.in: If there is no java compiler
- report error on ADD_JAVA_LIBRARY
-
-2002-12-26 13:58 andy
-
- * Modules/Platform/Windows-cl.cmake: Add missing closing bracket
-
-2002-12-23 12:19 hoffman
-
- * Source/cmSystemTools.h: ENH: fix for AIX
-
-2002-12-23 09:51 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: WAR: remove warinings
-
-2002-12-23 09:25 hoffman
-
- * Source/cmSystemTools.cxx: ENH: handle // in the path
-
-2002-12-22 15:19 hoffman
-
- * Modules/Platform/Windows-bcc32.cmake,
- Source/cmLocalUnixMakefileGenerator.cxx: ENH: fixes for borland
- with spaces in the path
-
-2002-12-22 11:50 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: clean up warning and use
- more short paths
-
-2002-12-22 10:09 barre
-
- * Modules/: Documentation.cmake, FindHTMLHelp.cmake, FindHhc.cmake:
- ENH: it's time to create a real Microsoft HTML Help Workshop
- CMake module
-
-2002-12-21 11:14 hoffman
-
- * Source/: cmGetTargetPropertyCommand.cxx,
- cmGetTargetPropertyCommand.h, cmSetTargetPropertiesCommand.cxx,
- cmSetTargetPropertiesCommand.h: ENH: add target properties files
-
-2002-12-20 17:15 hoffman
-
- * Source/cmCommands.cxx, Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmTarget.cxx, Source/cmTarget.h,
- Tests/Complex/Library/CMakeLists.txt,
- Tests/ComplexOneConfig/Library/CMakeLists.txt,
- Tests/ComplexRelativePaths/Library/CMakeLists.txt: ENH: add
- target properties
-
-2002-12-20 16:15 king
-
- * Source/cmVTKWrapTclCommand.cxx: ERR: Tcl_PkgProvide takes char*,
- so we cannot pass a string literal to it.
-
-2002-12-20 12:59 king
-
- * Modules/Platform/Windows-cl.cmake,
- Source/cmGlobalVisualStudio6Generator.cxx,
- Source/cmGlobalVisualStudio6Generator.h,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.h,
- Templates/CMakeVisualStudio6Configurations.cmake: ENH: Visual
- Studio 6 and 7 generators now set CMAKE_CONFIGURATION_TYPES to be
- a semicolon-separated list of configurations that will be built.
-
-2002-12-20 11:56 barre
-
- * Modules/: CMakeBackwardCompatibilityC.cmake, FindX11.cmake: FIX:
- make CMAKE_X_LIBS and CMAKE_X_CFLAGS advanced
-
-2002-12-20 11:20 hoffman
-
- * Source/cmGlobalUnixMakefileGenerator.cxx: ENH: add a check to
- make sure cmake can find the c or C++ compiler for trycompile
-
-2002-12-20 11:20 hoffman
-
- * Tests/: Complex/CMakeLists.txt, ComplexOneConfig/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt: BUG: fix for backwards
- compatibility
-
-2002-12-20 10:23 martink
-
- * Source/: cmSourceFilesCommand.cxx, cmake.cxx: testing more
- agressive compatability settings
-
-2002-12-20 09:43 king
-
- * Modules/FindTCL.cmake: ENH: Use the Mac -framework for Tk if it
- is available.
-
-2002-12-20 09:42 king
-
- * Modules/FindTCL.cmake: ENH: Use the Mac -framework for Tcl if it
- is available.
-
-2002-12-19 15:34 hoffman
-
- * Source/cmGlobalGenerator.cxx: BUG: enable the languages when not
- running in global mode
-
-2002-12-19 12:51 hoffman
-
- * Modules/CMakeSystemSpecificInformation.cmake: better docs
-
-2002-12-19 12:51 hoffman
-
- * Modules/Platform/Windows-cl.cmake: ENH: make linker flags use
- init values so users can set them from the cache
-
-2002-12-18 16:58 king
-
- * Source/cmVTKWrapTclCommand.cxx: ENH: Tcl packages now
- Tcl_PkgProvide their own name and version.
-
-2002-12-18 10:52 king
-
- * Modules/Platform/gcc.cmake: ENH: Adding build type flags for C.
-
-2002-12-18 09:38 king
-
- * Source/CMakeLists.txt, Tests/X11/CMakeLists.txt: ERR: Project
- name and executable name should match for consistency in the X11
- test.
-
-2002-12-17 17:05 king
-
- * Source/: cmCPluginAPI.cxx, cmCPluginAPI.h: ENH: Added return type
- int to ExecuteCommand.
-
-2002-12-17 14:55 king
-
- * Source/cmFLTKWrapUICommand.cxx: BUG: Need at least 2 arguments,
- not exactly 2.
-
-2002-12-17 14:55 king
-
- * Source/cmListFileCache.h: ERR: Added operator != for SGI.
-
-2002-12-17 14:54 hoffman
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeDetermineCXXCompiler.cmake,
- CMakeDetermineJavaCompiler.cmake, CMakeDetermineSystem.cmake,
- CMakeSystemSpecificInformation.cmake, CheckFunctionExists.cmake,
- CheckIncludeFile.cmake, CheckIncludeFileCXX.cmake,
- CheckLibraryExists.cmake, CheckSizeOf.cmake,
- CheckVariableExists.cmake, TestBigEndian.cmake,
- TestCXXAcceptsFlag.cmake, TestForANSIForScope.cmake,
- TestForSTDNamespace.cmake: ENH: use CMAKE_ROOT and not PROJECT_
- for try compile stuff, this allows projects within projects to
- have different languages
-
-2002-12-17 13:28 king
-
- * Source/CMakeLists.txt, Tests/X11/CMakeLists.txt: BUG: Renamed X11
- test executable to useX11 to avoid conflict with name of library.
-
-2002-12-17 12:56 martink
-
- * Source/cmLocalVisualStudio6Generator.cxx: better handling of
- Module
-
-2002-12-17 12:11 andy
-
- * Source/cmake.cxx: Save directories when doing global build
-
-2002-12-17 11:58 king
-
- * Source/cmMacroCommand.cxx: ENH: Improved error message for macro
- invoked with incorrect number of arguments.
-
-2002-12-17 11:57 king
-
- * Source/cmTryCompileCommand.cxx: ENH: TryCompile should produce a
- verbose makefile.
-
-2002-12-17 11:55 king
-
- * Modules/: CMakeBackwardCompatibilityC.cmake, FindX11.cmake: ENH:
- FindX11.cmake module now almost fully duplicates old configure
- functionality.
-
-2002-12-17 10:04 martink
-
- * Source/cmLocalVisualStudio7Generator.cxx: some clean up in link
- directories
-
-2002-12-16 21:19 andy
-
- * Source/: CMakeLists.txt, cmCTest.cxx, cmCTest.h, ctest.cxx,
- ctest.h: Split ctest into two three files
-
-2002-12-16 18:28 king
-
- * Source/cmLocalVisualStudio7Generator.cxx: BUG: Cannot remove
- quotes from defined flags.
-
-2002-12-16 12:13 andy
-
- * Source/cmake.cxx: Fix switching from local to global generation
- when cmake version changes or when things change inside version
-
-2002-12-16 11:10 king
-
- * Source/cmake.cxx: ENH: Added copy_if_different option to -E flag.
-
-2002-12-16 09:39 king
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: BUG: Fixed quotes in output
- paths.
-
-2002-12-15 13:45 andy
-
- * Source/: ctest.cxx, ctest.h: Add support for only showing what
- will be done. This way you can for example get a list of all
- tests: ctest -N or list of all tests that match regex: ctest -N
- -R regex
-
-2002-12-13 17:35 king
-
- * Tests/: Complex/CMakeLists.txt,
- Complex/cmTestGeneratedHeader.h.in,
- Complex/Executable/CMakeLists.txt,
- Complex/Executable/complex.cxx, ComplexOneConfig/CMakeLists.txt,
- ComplexOneConfig/cmTestGeneratedHeader.h.in,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/CMakeLists.txt,
- ComplexRelativePaths/cmTestGeneratedHeader.h.in,
- ComplexRelativePaths/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/complex.cxx: ENH: Added test for
- generated header included by non-generated source.
-
-2002-12-13 17:34 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: Need source file
- and OBJECT_DEPENDS as dependencies of an object file.
-
-2002-12-13 16:16 king
-
- * Source/: cmLocalUnixMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator.h,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx,
- cmSetSourceFilesPropertiesCommand.cxx: ENH: Added source file
- property OBJECT_DEPENDS to support generated header files
- included in non-generated sources.
-
-2002-12-13 14:58 king
-
- * Modules/: CheckFunctionExists.cmake, CheckIncludeFile.cmake,
- CheckIncludeFileCXX.cmake, CheckLibraryExists.cmake,
- CheckSizeOf.cmake, CheckVariableExists.cmake: ENH: Don't repeat
- check even if answer was no.
-
-2002-12-13 09:52 martink
-
- * Source/cmIfCommand.cxx: made more strict
-
-2002-12-13 09:27 martink
-
- * Source/: ctest.cxx, cmCPluginAPI.cxx: fixed warnings
-
-2002-12-13 09:18 king
-
- * Source/: cmFunctionBlocker.h, cmIfCommand.h: ERR: Fixed unused
- parameter warning.
-
-2002-12-12 17:48 hoffman
-
- * Source/: cmTryCompileCommand.cxx, cmTryCompileCommand.h: Make try
- compile add a depend to re-run cmake if its source chagnes
-
-2002-12-12 12:02 king
-
- * Utilities/: cmake_release_config_darwin,
- cmake_release_config_hpux, cmake_release_config_irix,
- cmake_release_config_linux, cmake_release_config_osf,
- cmake_release_config_sun, cmake_release_cygwin.sh: ENH: Updated
- for 1.4.7 release.
-
-2002-12-12 11:51 martink
-
- * Source/cmMakefile.h: updated to patch7
-
-2002-12-12 11:36 king
-
- * Source/: cmListFileCache.cxx, cmListFileCache.h,
- cmMacroCommand.cxx, cmMakefile.cxx, cmMakefile.h, ctest.cxx: ENH:
- Improved filename/line number reporting in error message. Macro
- invocations now chain up the error message.
-
-2002-12-12 10:25 king
-
- * Modules/CMakeTestGNU.c: ERR: Fixed syntax errors for picky
- preprocessors.
-
-2002-12-12 10:25 king
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeDetermineCXXCompiler.cmake: ERR: Need double-quotes around
- expression to be mached in IF command.
-
-2002-12-12 10:10 king
-
- * Tests/: Complex/CMakeLists.txt, Complex/VarTests.cmake,
- ComplexOneConfig/CMakeLists.txt, ComplexOneConfig/VarTests.cmake,
- ComplexRelativePaths/CMakeLists.txt,
- ComplexRelativePaths/VarTests.cmake: BUG: Can't double-quote
- foreach arguments.
-
-2002-12-12 08:42 martink
-
- * Tests/Wrapping/CMakeLists.txt: now uses SET instead of
- SOURCE_LIST command
-
-2002-12-11 18:20 king
-
- * Source/cmListFileCache.cxx: BUG: Multi-line functions must also
- increment line number, not the pointer.
-
-2002-12-11 18:15 king
-
- * Source/cmEndForEachCommand.h: ERR: Dummy InitialPass
- implementation must return a value.
-
-2002-12-11 18:13 king
-
- * Source/: cmAbstractFilesCommand.cxx,
- cmAddCustomCommandCommand.cxx, cmAddCustomTargetCommand.cxx,
- cmAddDefinitionsCommand.cxx, cmAddDependenciesCommand.cxx,
- cmAddExecutableCommand.cxx, cmAddLibraryCommand.cxx,
- cmAddTestCommand.cxx, cmCPluginAPI.cxx, cmCommand.h,
- cmCreateTestSourceList.cxx, cmEndForEachCommand.cxx,
- cmEndForEachCommand.h, cmFindFileCommand.cxx,
- cmFindLibraryCommand.cxx, cmFindPathCommand.cxx,
- cmFindProgramCommand.cxx, cmForEachCommand.cxx,
- cmForEachCommand.h, cmFunctionBlocker.h, cmITKWrapTclCommand.cxx,
- cmIfCommand.cxx, cmIfCommand.h, cmIncludeDirectoryCommand.cxx,
- cmInstallProgramsCommand.cxx, cmInstallTargetsCommand.cxx,
- cmLinkDirectoriesCommand.cxx, cmLinkLibrariesCommand.cxx,
- cmListFileCache.cxx, cmListFileCache.h, cmLoadCacheCommand.cxx,
- cmLoadCommandCommand.cxx, cmLocalUnixMakefileGenerator.cxx,
- cmMacroCommand.cxx, cmMacroCommand.h, cmMakefile.cxx,
- cmMakefile.h, cmMarkAsAdvancedCommand.cxx, cmMessageCommand.cxx,
- cmProjectCommand.cxx, cmRemoveCommand.cxx,
- cmSetSourceFilesPropertiesCommand.cxx, cmSourceFilesCommand.cxx,
- cmSourceFilesRemoveCommand.cxx, cmSubdirCommand.cxx,
- cmSystemTools.cxx, cmSystemTools.h, cmTarget.cxx,
- cmTargetLinkLibrariesCommand.cxx, cmUtilitySourceCommand.cxx,
- cmVariableRequiresCommand.cxx, cmWriteFileCommand.cxx, ctest.cxx:
- ENH: Moved ExpandListVariables out of individual commands.
- Argument evaluation rules are now very consistent. Double quotes
- can always be used to create exactly one argument, regardless of
- contents inside.
-
-2002-12-11 14:18 martink
-
- * Source/CMakeSetup.dsw: removed dsw file
-
-2002-12-11 14:16 martink
-
- * Source/: cmCPluginAPI.cxx, cmCPluginAPI.h: added a Free method
-
-2002-12-11 14:15 king
-
- * Source/: cmCreateTestSourceList.cxx, cmSystemTools.cxx: ENH:
- Improved implementation of MSVC debug hook to only add the hook
- if DART_TEST_FROM_DART is set in the environment. This is better
- than always adding the hook and testing the environment from the
- callback.
-
-2002-12-11 12:09 andy
-
- * Source/: cmGlobalVisualStudio7Generator.cxx,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: Add check so that java
- projects build without C++
-
-2002-12-11 11:49 king
-
- * Source/: cmDumpDocumentation.cxx, cmSystemTools.cxx,
- cmSystemTools.h, cmakemain.cxx, cmaketest.cxx, cmw9xcom.cxx,
- ctest.cxx: ENH: Added cmSystemTools::EnableMSVCDebugHook() to
- prevent error dialogs when CMake is invoked by Dart.
-
-2002-12-11 11:32 king
-
- * Source/cmCreateTestSourceList.cxx: ENH: Generate code to setup
- MSVC debug library hook. The test driver program will not
- display error dialogs if DART_TEST_FROM_DART is set in the
- environment.
-
-2002-12-11 10:34 andy
-
- * Modules/CMakeDetermineJavaCompiler.cmake,
- Modules/CMakeJavaCompiler.cmake.in, Source/cmGlobalGenerator.cxx:
- Add java support
-
-2002-12-10 17:52 andy
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio6Generator.h: Add support for comments on
- custom commands in visual studio 6
-
-2002-12-10 17:43 andy
-
- * Source/: cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h: Add support for comments on
- custom commands in visual studio 7
-
-2002-12-10 16:46 andy
-
- * Source/: cmCustomCommand.cxx, cmCustomCommand.h, cmMakefile.cxx,
- cmMakefile.h, cmAddCustomCommandCommand.cxx,
- cmAddCustomCommandCommand.h, cmLocalUnixMakefileGenerator.cxx,
- cmSourceGroup.cxx, cmSourceGroup.h: Add comment support, so that
- you can see in build process what the custom command does
-
-2002-12-10 16:45 andy
-
- * Source/: cmAddCustomTargetCommand.cxx,
- cmAddCustomTargetCommand.h: Allow target with no command
-
-2002-12-10 16:08 hoffman
-
- * Source/: cmOutputRequiredFilesCommand.cxx,
- cmOutputRequiredFilesCommand.h: BUG: update for changes in
- cmMakeDepend
-
-2002-12-10 16:01 hoffman
-
- * Source/: cmITKWrapTclCommand.cxx, cmITKWrapTclCommand.h: ENH:
- update use of makedepend
-
-2002-12-10 15:55 hoffman
-
- * Source/: cmITKWrapTclCommand.cxx, cmITKWrapTclCommand.h: ENH:
- update to new style MakeDepend
-
-2002-12-10 14:12 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: make sure empty depends
- are not used
-
-2002-12-10 14:10 martink
-
- * Source/: cmOutputRequiredFilesCommand.cxx,
- cmOutputRequiredFilesCommand.h: updated for changes in Depend
- Calcs
-
-2002-12-10 13:59 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: do not output empty
- depends
-
-2002-12-10 13:36 andy
-
- * Source/ctest.cxx: Remove warning
-
-2002-12-10 10:34 hoffman
-
- * Source/: cmMakeDepend.cxx, cmUnixMakefileGenerator.cxx,
- cmUnixMakefileGenerator.h: BUG: fix compile flags for source
- files, and fix depend bug for cmake 14 branch
-
-2002-12-10 09:34 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: remove cerr
-
-2002-12-10 09:28 hoffman
-
- * Source/: cmLocalUnixMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator.h, cmMakeDepend.cxx: BUG: fix bug
- in depends
-
-2002-12-09 16:23 andy
-
- * Source/cmaketest.cxx: Add to usage
-
-2002-12-09 16:22 andy
-
- * Modules/FindPythonLibs.cmake: Better search for python
-
-2002-12-09 14:33 king
-
- * Modules/CMakeImportBuildSettings.cmake: ENH: Using only filename
- without path or extension for comparing build tools.
-
-2002-12-09 08:27 hoffman
-
- * Modules/: CMakeVS6BackwardCompatibility.cmake,
- CMakeVS7BackwardCompatibility.cmake: use win32 threads for win32
-
-2002-12-08 22:36 andy
-
- * Source/: ctest.cxx, ctest.h: Initial addition of coverage
-
-2002-12-08 22:35 andy
-
- * Source/cmSystemTools.cxx: Fix bug in globbing. Now it actually
- uses only files or directories that result in globbing not the
- ones that were is the vector before
-
-2002-12-08 22:33 andy
-
- * Source/: cmGlobalGenerator.cxx, cmLocalUnixMakefileGenerator.cxx:
- Rename variable to remove warning
-
-2002-12-08 14:25 starreveld
-
- * Templates/CMakeLists.txt: ERR: Remove references to files removed
- 4 days ago
-
-2002-12-06 15:35 hoffman
-
- * Source/: cmGlobalUnixMakefileGenerator.cxx,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx,
- cmLocalUnixMakefileGenerator.cxx, cmMakefile.cxx: ENH: fix IntDir
- jump and build problem
-
-2002-12-06 11:43 hoffman
-
- * Source/cmGlobalGenerator.cxx: ENH: set the CXX and CC environment
- vars
-
-2002-12-06 10:16 hoffman
-
- * Modules/CMakeDetermineCCompiler.cmake: BUG: fix C compiler init
-
-2002-12-06 10:09 hoffman
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeDetermineCXXCompiler.cmake: clean up compiler picking code
-
-2002-12-06 10:02 hoffman
-
- * Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Source/cmGlobalVisualStudio6Generator.cxx: fix for generator
- picked compilers
-
-2002-12-05 16:53 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: use correct path type
- for check_cache file
-
-2002-12-05 16:52 hoffman
-
- * Source/cmDynamicLoader.cxx: fix free before use
-
-2002-12-05 14:56 hoffman
-
- * Source/: cmCacheManager.cxx, cmLocalUnixMakefileGenerator.cxx:
- ENH: add a rule to automatically re-run cmake from the top if the
- CMakeCache.txt file is changed
-
-2002-12-05 14:24 andy
-
- * Source/Makefile.in: Better dependencies for bootstrap
-
-2002-12-05 13:44 hoffman
-
- * Modules/CMakeBackwardCompatibilityC.cmake,
- Modules/CMakeBackwardCompatibilityCXX.cmake,
- Modules/CMakeSystemSpecificInformation.cmake,
- Modules/CMakeVS6BackwardCompatibility.cmake,
- Modules/CMakeVS6FindMake.cmake,
- Modules/CMakeVS7BackwardCompatibility.cmake,
- Modules/CMakeVS7FindMake.cmake, Modules/Dart.cmake,
- Modules/Platform/Windows-cl.cmake,
- Source/cmGlobalBorlandMakefileGenerator.cxx,
- Source/cmGlobalBorlandMakefileGenerator.h,
- Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmGlobalNMakeMakefileGenerator.cxx,
- Source/cmGlobalNMakeMakefileGenerator.h,
- Source/cmGlobalUnixMakefileGenerator.cxx,
- Source/cmGlobalUnixMakefileGenerator.h,
- Source/cmGlobalVisualStudio6Generator.cxx,
- Source/cmGlobalVisualStudio6Generator.h,
- Source/cmGlobalVisualStudio7Generator.cxx,
- Source/cmGlobalVisualStudio7Generator.h,
- Source/cmLocalVisualStudio6Generator.cxx: ENH: unify
- EnableLanguage across all generators
-
-2002-12-05 11:55 andy
-
- * Tests/: LoadCommand/CMakeLists.txt,
- LoadCommand/LoadedCommand.cxx, LoadCommand/LoadedCommand.h.in,
- LoadCommandOneConfig/CMakeLists.txt,
- LoadCommandOneConfig/LoadedCommand.cxx,
- LoadCommandOneConfig/LoadedCommand.h.in: Speedup the test
-
-2002-12-05 11:09 martink
-
- * Source/cmGlobalVisualStudio7Generator.h: use InAll target setting
- to determine what targets are in the default build
-
-2002-12-05 10:47 king
-
- * Modules/: FindVTK.cmake, UseVTK40.cmake,
- UseVTKBuildSettings40.cmake, UseVTKConfig40.cmake: ENH: Added
- support for finding/using VTK 4.0 without using its UseVTK.cmake
- file that does a LOAD_CACHE.
-
-2002-12-05 10:34 king
-
- * Modules/CMakeImportBuildSettings.cmake: BUG: Fix for string
- comparison when one string is empty.
-
-2002-12-05 09:46 king
-
- * Modules/: CMakeBuildSettings.cmake.in,
- CMakeExportBuildSettings.cmake, CMakeImportBuildSettings.cmake:
- ENH: Adding CMAKE_EXPORT_BUILD_SETTINGS and
- CMAKE_IMPORT_BUILD_SETTINGS macro.
-
-2002-12-05 08:30 martink
-
- * Source/cmGlobalVisualStudio7Generator.cxx: use InAll target
- setting to determine what targets are in the default build
-
-2002-12-04 18:44 king
-
- * Source/: cmStringCommand.cxx, cmStringCommand.h: ENH: Added
- COMPARE modes to STRING command.
-
-2002-12-04 16:59 king
-
- * Modules/CMakeUnixFindMake.cmake: BUG: Removed stray debugging
- message.
-
-2002-12-04 14:18 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: When a full path to
- a library cannot be parsed, just add the whole path to the link
- line. If it isn't a valid path, the linker will complain.
-
-2002-12-04 10:57 hoffman
-
- * Modules/CMakeUnixFindMake.cmake,
- Source/cmGlobalBorlandMakefileGenerator.cxx,
- Source/cmGlobalNMakeMakefileGenerator.cxx,
- Source/cmGlobalUnixMakefileGenerator.cxx, Source/cmake.cxx,
- Source/cmake.h: BUG: fix get make command problems.
-
-2002-12-04 10:44 martink
-
- * Source/cmake.cxx: added CMAKE_BACKWARDS_COMPATIBILITY entry
-
-2002-12-04 10:25 martink
-
- * Source/cmLinkLibrariesCommand.h: updated comment
-
-2002-12-03 16:19 hoffman
-
- * Modules/CMakeBorlandFindMake.cmake,
- Modules/CMakeNMakeFindMake.cmake,
- Modules/CMakeSystemSpecificInformation.cmake,
- Modules/CMakeUnixFindMake.cmake, Modules/Platform/CYGWIN.cmake,
- Modules/Platform/Windows-bcc32.cmake,
- Modules/Platform/Windows-cl.cmake,
- Source/cmGlobalBorlandMakefileGenerator.cxx,
- Source/cmGlobalNMakeMakefileGenerator.cxx,
- Source/cmGlobalUnixMakefileGenerator.cxx: determine
- CMAKE_MAKE_PROGRAM in EnableLanguage
-
-2002-12-03 15:23 hoffman
-
- * Source/CMakeLists.txt,
- Source/cmLocalBorlandMakefileGenerator.cxx,
- Source/cmLocalBorlandMakefileGenerator.h,
- Source/cmLocalNMakeMakefileGenerator.cxx,
- Source/cmLocalNMakeMakefileGenerator.h,
- Templates/CCMakeSystemConfig.cmake.in,
- Templates/CMakeBorlandWindowsSystemConfig.cmake,
- Templates/CMakeNMakeWindowsSystemConfig.cmake,
- Templates/CXXCMakeSystemConfig.cmake.in: remove unused files
-
-2002-12-03 14:15 ibanez
-
- * Modules/FindImageMagick.cmake: Module to find tools from the
- ImageMagick package. These tools are useful for converting image
- formats.
-
-2002-12-03 14:09 martink
-
- * Source/: CMakeLists.txt, Makefile.in, cmake.cxx: remove code
- warrior and fixed GUI isues
-
-2002-12-03 13:46 ibanez
-
- * Modules/FindFLTK.cmake: ENH: description of variables now follows
- other style in other .cmake files.
-
-2002-12-03 13:44 ibanez
-
- * Modules/FindGLUT.cmake: ENH: Description of variables now
- specifies that the full path is required.
-
-2002-12-03 12:59 martink
-
- * Source/cmMakefile.cxx: fix purify FMR
-
-2002-12-03 11:23 martink
-
- * CMakeLists.txt: bug fix and some cleanup
-
-2002-12-03 11:21 martink
-
- * Tests/.NoDartCoverage: clean up coverage some
-
-2002-12-03 10:47 hoffman
-
- * Modules/CMakeDefaultMakeRuleVariables.cmake,
- Modules/Platform/Linux-como.cmake,
- Modules/Platform/Windows-bcc32.cmake,
- Modules/Platform/Windows-cl.cmake,
- Source/cmLocalUnixMakefileGenerator.cxx: correctly place both
- LINK_FLAGS and CXX_LINK_FLAGS and C_LINK_FLAGS into all the rules
-
-2002-12-03 09:59 hoffman
-
- * Modules/CMakeDefaultMakeRuleVariables.cmake: use LINK_FLAGS not C
- and CXX LINK_FLAGS
-
-2002-12-02 16:35 martink
-
- * Source/cmStringCommand.cxx: fix compile warning
-
-2002-12-02 16:15 hoffman
-
- * Source/cmMakefile.cxx: add project command even if inheriting
-
-2002-12-02 16:08 hoffman
-
- * Source/cmListFileCache.cxx: ENH: put the project command at the
- front of the project
-
-2002-12-02 15:59 martink
-
- * Source/: cmFindLibraryCommand.cxx, cmMakefile.cxx, cmMakefile.h,
- cmSystemTools.cxx, cmSystemTools.h: removed cmMakefile depend
- from cmSystemTools
-
-2002-12-02 15:43 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ENH: remove forced
- enable language call because a PROJECT command is now added to
- each project
-
-2002-12-02 15:37 hoffman
-
- * Source/: cmListFileCache.cxx, cmMakefile.cxx: ENH: remove cerr
- calls
-
-2002-12-02 15:30 hoffman
-
- * Source/: cmListFileCache.cxx, cmListFileCache.h, cmMakefile.cxx:
- ENH: add PROJECT command if there is not one
-
-2002-12-02 15:03 martink
-
- * Source/cmIfCommand.cxx: minor fix
-
-2002-12-02 13:18 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: add a space around
- the compile flags
-
-2002-12-02 10:33 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: fix compile flags
- for a single file
-
-2002-11-29 18:56 andy
-
- * Source/cmGlobalUnixMakefileGenerator.cxx: Fix problem on unix
- with space
-
-2002-11-29 16:35 andy
-
- * Source/cmSystemTools.cxx: When cd-jing into directory, if
- directory has space, it should put quotes around. I guess we
- could just put quotes around all the time
-
-2002-11-28 23:45 ibanez
-
- * Modules/FindFLTK.cmake: ENH: FLTK 1.1.1 under Windows links now
- with the comctl32 library.
-
-2002-11-27 07:42 andy
-
- * Tests/ObjC++/CMakeLists.txt: Add missing library. The test should
- be linked to framework Cocoa
-
-2002-11-27 07:41 andy
-
- * Source/cmSystemTools.cxx: Add objective C++ file in the list of
- C++ files. This may be wrong, but it will fix problems on Mac for
- now
-
-2002-11-26 19:02 starreveld
-
- * Source/CMakeLists.txt: Add ObjC++ test for OSX
-
-2002-11-26 19:01 starreveld
-
- * Tests/ObjC++/: CMakeLists.txt, objc++.mm:
- Test for ObjC++ on OSX machines only
-
-2002-11-26 09:37 andy
-
- * Source/cmTryCompileCommand.cxx: Remove warning
-
-2002-11-25 17:57 andy
-
- * Modules/FindwxWindows.cmake: Change priorities
-
-2002-11-22 16:59 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: fix for paths with
- spaces and borland
-
-2002-11-22 16:18 hoffman
-
- * Modules/Platform/Windows-bcc32.cmake: change flags for borland
-
-2002-11-22 15:44 andy
-
- * Source/cmLocalVisualStudio6Generator.cxx: Revert back to 1.5,
- since it is fixed in ConvertToOutputPath and this breaks Windows
- 98
-
-2002-11-22 09:45 andy
-
- * Source/CursesDialog/cmCursesMainForm.cxx: Rename local variable
-
-2002-11-21 23:54 hoffman
-
- * Source/cmLocalVisualStudio7Generator.cxx: add support for
- CMAKE_C_FLAGS and handle quotes in CMAKE_CXX_FLAGS
-
-2002-11-21 16:11 hoffman
-
- * Source/cmTryCompileCommand.cxx: fix for c flags
-
-2002-11-21 16:03 hoffman
-
- * Source/: cmTryCompileCommand.cxx: fix flag setting
-
-2002-11-21 15:36 hoffman
-
- * Modules/Platform/CYGWIN.cmake: remove debug stuff
-
-2002-11-21 15:15 hoffman
-
- * Source/cmTryCompileCommand.cxx: move compile defs to cxx and c
- flags
-
-2002-11-21 14:59 hoffman
-
- * Source/: cmTryCompileCommand.cxx, cmTryCompileCommand.h: clean up
- entire temp directory
-
-2002-11-21 14:45 hoffman
-
- * Modules/: CheckIncludeFileCXX.cmake,
- TestForANSIStreamHeaders.cmake: try to fix check for ansi stream
-
-2002-11-21 14:32 hoffman
-
- * Modules/CheckIncludeFileCXX.cmake: fix order
-
-2002-11-21 14:24 hoffman
-
- * Modules/TestForSTDNamespace.cmake: fix order
-
-2002-11-21 14:11 hoffman
-
- * Modules/CheckIncludeFileCXX.cmake,
- Modules/TestForANSIForScope.cmake,
- Modules/TestForANSIStreamHeaders.cmake,
- Modules/TestForSTDNamespace.cmake,
- Source/cmTryCompileCommand.cxx: move ansi cxx flags stuff out of
- try compile and into cmake files
-
-2002-11-21 13:37 hoffman
-
- * Source/cmSystemTools.cxx: fix network paths with spaces
-
-2002-11-21 13:28 hoffman
-
- * Modules/CMakeBackwardCompatibilityCXX.cmake: have to cache
- ansi_cxxflags
-
-2002-11-21 12:59 hoffman
-
- * Modules/: CMakeBackwardCompatibilityCXX.cmake,
- TestCXXAcceptsFlag.cmake: spelling error
-
-2002-11-21 12:52 hoffman
-
- * Modules/: CMakeBackwardCompatibilityCXX.cmake, DummyCXXFile.cxx,
- TestCXXAcceptsFlag.cmake, Platform/IRIX64.cmake,
- Platform/OSF1.cmake: add checks for ansi flags and not hard code
- them
-
-2002-11-21 12:26 andy
-
- * Source/cmLocalVisualStudio6Generator.cxx: Fix for network paths
- with space
-
-2002-11-21 12:26 andy
-
- * Source/ctest.cxx: Fix for network paths
-
-2002-11-21 11:46 barre
-
- * Modules/CMakeSystemSpecificInformation.cmake: FUX: those vars
- need to be ADVANCED
-
-2002-11-21 10:11 king
-
- * Modules/: CheckVariableExists.c, CheckVariableExists.cmake: ENH:
- Added CHECK_VARIABLE_EXISTS macro.
-
-2002-11-21 10:03 king
-
- * Source/CursesDialog/cmCursesMainForm.cxx: ERR: Fixed string
- literal to char* warnings.
-
-2002-11-21 08:45 hoffman
-
- * Modules/CMakeDefaultMakeRuleVariables.cmake,
- Modules/Platform/CYGWIN.cmake,
- Source/cmLocalUnixMakefileGenerator.cxx,
- Tests/SystemInformation/SystemInformation.in: fix for create
- shared library
-
-2002-11-21 08:19 martink
-
- * Tests/LinkLineOrder/: Exec1.c, Exec2.c, NoDepB.c, NoDepC.c,
- NoDepE.c, NoDepF.c, NoDepX.c, NoDepY.c, NoDepZ.c, One.c:
- converted c plus plus comments
-
-2002-11-21 08:12 hoffman
-
- * Modules/CMakeSystemSpecificInformation.cmake: ENH: fix for module
- run time flag
-
-2002-11-20 18:18 hoffman
-
- * Source/: cmCacheManager.h, cmSystemTools.cxx: rename foo
- variables to better names
-
-2002-11-20 18:00 king
-
- * Source/: cmLoadCacheCommand.cxx, cmLoadCacheCommand.h: ENH: Added
- READ_WITH_PREFIX option to LOAD_CACHE command. This allows
- reading of cache values from another cache without actually
- creating local copies of the cache entires. The values are
- stored as prefixed local makefile variables.
-
-2002-11-20 16:23 king
-
- * Modules/FindVTK.cmake: ENH: Added support to find VTK 4.0.
-
-2002-11-20 15:23 hoffman
-
- * Modules/CMakeCCompiler.cmake.in: BUG: use CMAKE_COMPILER_IS_GNUCC
- not CMAKE_COMPILER_IS_GNUGCC
-
-2002-11-20 14:40 ibanez
-
- * Modules/FindLATEX.cmake: ENH: Now also locates the "makeindex"
- program.
-
-2002-11-20 14:11 king
-
- * Modules/FindVTK.cmake: ENH: Only search VTK_INSTALL_PATH if
- USE_INSTALLED_VTK is on. Only search VTK_BINARY_PATH if
- USE_BUILT_VTK is on.
-
-2002-11-20 13:37 king
-
- * Modules/FindVTK.cmake: ENH: New implementation of FindVTK to take
- advantage of VTKConfig.cmake. Also provides more powerful search
- path mechanism, and requires only one cache entry in user
- project.
-
-2002-11-20 12:58 king
-
- * Source/cmSystemTools.cxx: BUG: Attempt to fix CopyFile problem
- using flush before check for success.
-
-2002-11-20 09:06 king
-
- * Source/cmGetFilenameComponentCommand.cxx: ERR: Fixed
- signed/unsigned warning.
-
-2002-11-20 09:06 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ERR: Fixed unused
- parameter warning.
-
-2002-11-20 09:04 martink
-
- * Tests/LinkLineOrder/NoDepA.c: fixed comments to be c style not c
- plus plus
-
-2002-11-19 18:17 hoffman
-
- * Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Modules/CMakeSystemSpecificInformation.cmake,
- Source/cmGetFilenameComponentCommand.cxx,
- Source/cmGetFilenameComponentCommand.h, Source/cmSystemTools.cxx,
- Source/cmSystemTools.h: allow flags to be in the CC and CXX
- environment variables
-
-2002-11-19 18:01 perera
-
- * Source/CMakeLists.txt, Source/cmMakefile.cxx,
- Source/cmTarget.cxx, Source/cmTarget.h,
- Tests/LinkLineOrder/CMakeLists.txt, Tests/LinkLineOrder/Exec1.c,
- Tests/LinkLineOrder/Exec2.c, Tests/LinkLineOrder/NoDepA.c,
- Tests/LinkLineOrder/NoDepB.c, Tests/LinkLineOrder/NoDepC.c,
- Tests/LinkLineOrder/NoDepE.c, Tests/LinkLineOrder/NoDepF.c,
- Tests/LinkLineOrder/NoDepX.c, Tests/LinkLineOrder/NoDepY.c,
- Tests/LinkLineOrder/NoDepZ.c, Tests/LinkLineOrder/One.c,
- Tests/LinkLineOrder/Two.c: BUG: the dependency analysis would
- incorrectly alphabetically re-order the link lines, which affects
- external libraries pulled up from deep within the dependency
- tree. Fixed by preserving order everywhere.
-
-2002-11-19 15:55 hoffman
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeDetermineCXXCompiler.cmake: fixes to better honor env CC and
- CXX
-
-2002-11-19 14:40 hoffman
-
- * Source/cmSystemTools.cxx: ENH: add some better output when copy
- file fails
-
-2002-11-19 14:40 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: fix some warnings
-
-2002-11-19 13:19 andy
-
- * Source/CursesDialog/cmCursesPathWidget.cxx: Add / after directory
- name when doing tab completion
-
-2002-11-19 13:09 andy
-
- * Source/CursesDialog/: cmCursesMainForm.cxx, cmCursesMainForm.h:
- Add progress to ccmake
-
-2002-11-19 12:20 hoffman
-
- * Modules/CMakeSystemSpecificInformation.cmake: BUG: fix CFLAGS
-
-2002-11-19 12:18 hoffman
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeDetermineCXXCompiler.cmake: BUG: fix handling of CXX
-
-2002-11-19 09:12 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: fix warning
-
-2002-11-19 09:01 martink
-
- * Source/cmSystemTools.cxx: fix in warning
-
-2002-11-18 16:29 andy
-
- * Source/CursesDialog/: cmCursesMainForm.cxx, cmCursesMainForm.h:
- Initial add of progress
-
-2002-11-18 15:14 hoffman
-
- * Modules/: CMakeBackwardCompatibilityC.cmake, FindThreads.cmake:
- BUG: fix for thread and cache override
-
-2002-11-18 10:52 andy
-
- * Modules/: CheckFunctionExists.cmake, CheckIncludeFile.cmake,
- CheckLibraryExists.cmake, CheckSizeOf.cmake,
- TestForANSIForScope.cmake, TestForANSIStreamHeaders.cmake,
- TestForSTDNamespace.cmake: Add more messages, make messages look
- the same, add checks if test was already successfull
-
-2002-11-18 10:51 andy
-
- * Modules/CMakeSystemSpecificInformation.cmake: If system detection
- fails, make copy of CMakeCache
-
-2002-11-18 09:08 hoffman
-
- * Tests/SystemInformation/SystemInformation.in: add print for
- compiler is gnu
-
-2002-11-17 17:28 martink
-
- * Source/: cmake.cxx, cmLocalUnixMakefileGenerator.cxx: fix some
- compiler warnings hopefully
-
-2002-11-15 17:45 hoffman
-
- * Modules/Platform/Windows-bcc32.cmake,
- Source/cmLocalUnixMakefileGenerator.cxx: BUG: fix for borland run
- time dll
-
-2002-11-15 16:00 hoffman
-
- * Modules/Platform/SunOS.cmake: fix for sun
-
-2002-11-15 13:17 martink
-
- * Source/cmake.cxx: fixed bad source directory bug
-
-2002-11-15 12:54 martink
-
- * Source/cmIfCommand.cxx: fixed compiler warning
-
-2002-11-15 10:07 hoffman
-
- * Modules/CMakeSystemSpecificInformation.cmake: ENH: add back
- install prefix
-
-2002-11-15 09:30 hoffman
-
- * Modules/FindThreads.cmake: fix thread logic
-
-2002-11-15 09:16 hoffman
-
- * Modules/CMakeSystemSpecificInformation.cmake: ENH: add CFLAGS and
- CXXFLAGS
-
-2002-11-15 07:42 andy
-
- * Source/cmakemain.cxx: Oops, std namespace
-
-2002-11-14 17:12 andy
-
- * Source/cmakemain.cxx: Add Progress support
-
-2002-11-14 16:29 berk
-
- * Modules/Platform/HP-UX.cmake: temp fix for hp
-
-2002-11-14 16:29 hoffman
-
- * Source/TODO: [no log message]
-
-2002-11-14 16:12 berk
-
- * Modules/Platform/HP-UX.cmake: fix flags for hp
-
-2002-11-14 14:06 andy
-
- * Source/cmLocalUnixMakefileGenerator.cxx: Fix compile flags on c
- files in static liobraries on windows
-
-2002-11-14 11:33 andy
-
- * Modules/CMakeSystemSpecificInformation.cmake,
- Modules/Platform/Windows-cl.cmake,
- Source/cmLocalUnixMakefileGenerator.cxx: BUG: fix flags for c
- compiler on windows
-
-2002-11-14 11:16 martink
-
- * Source/: cmCPluginAPI.cxx, cmCPluginAPI.h: added another func
-
-2002-11-14 11:03 martink
-
- * Source/: cmCPluginAPI.h, cmCPluginAPI.cxx: added another func
-
-2002-11-14 09:38 andy
-
- * Modules/: FindJNI.cmake, FindJava.cmake, FindPythonLibs.cmake:
- Clean find for Python, add find for python 2.2 on windows,
- cleanup java on windows and add java 1.4 support
-
-2002-11-14 09:38 berk
-
- * Source/cmLocalUnixMakefileGenerator.cxx: Added missing space.
-
-2002-11-14 09:37 andy
-
- * Source/cmLocalUnixMakefileGenerator.cxx: Fix building on NMake.
- Use short paths
-
-2002-11-14 08:59 hoffman
-
- * Modules/Platform/Windows-bcc32.cmake: BUG: fix for missing temp
- file variable
-
-2002-11-13 23:36 hoffman
-
- * Modules/Platform/Windows-bcc32.cmake,
- Source/cmLocalUnixMakefileGenerator.cxx: reorder tWR so that it
- does not crash with shared
-
-2002-11-13 20:14 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: add support for borland
- run time flag for shared builds
-
-2002-11-13 20:11 hoffman
-
- * Modules/Platform/Windows-bcc32.cmake: fix shared builds on
- borland and add debug stuff for makefiles
-
-2002-11-13 18:27 hoffman
-
- * Source/: cmLocalUnixMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator.h: BUG: fix for build out of dir for
- windows
-
-2002-11-13 16:31 hoffman
-
- * Modules/: CheckFunctionExists.cmake, CheckIncludeFile.cmake,
- CheckLibraryExists.cmake, CheckSizeOf.cmake: ENH: add status
- messages
-
-2002-11-13 15:59 martink
-
- * Source/: cmLocalUnixMakefileGenerator.cxx, cmMakefile.cxx,
- cmMakefile.h, cmMessageCommand.cxx, cmMessageCommand.h: ENH:
- space fixes and add a status option to message command
-
-2002-11-13 15:32 martink
-
- * Modules/Platform/Windows-bcc32.cmake: ENH: move -P flag from
- cxxflags to the compile line for cxx files
-
-2002-11-13 15:20 hoffman
-
- * Source/: cmGlobalUnixMakefileGenerator.cxx, cmake.cxx, cmake.h:
- ENH: check to make sure cmake matches the cmake used to generate
- the cache
-
-2002-11-13 14:51 hoffman
-
- * Modules/Platform/Windows-bcc32.cmake: ENH: use correct run time
- library for borland
-
-2002-11-13 14:31 hoffman
-
- * Source/: cmCacheManager.cxx, cmGlobalUnixMakefileGenerator.cxx:
- ENH: force a global generate if the cache version does not match
- the running cmake
-
-2002-11-13 13:19 berk
-
- * Source/Makefile.in: BUG: add missing depend rules for hp make
-
-2002-11-13 11:49 hoffman
-
- * Modules/FindX11.cmake: fix for nsl library and X11
-
-2002-11-13 11:36 hoffman
-
- * Modules/: CMakeBackwardCompatibilityC.cmake, FindX11.cmake: fix
- for nsl library and X11
-
-2002-11-13 11:25 hoffman
-
- * Modules/Platform/Windows-bcc32.cmake: BUG: fix order of link line
- for creating shared libraries
-
-2002-11-12 19:39 king
-
- * Modules/CheckFunctionExists.cmake: BUG: Fixed doc string on
- generated variable.
-
-2002-11-12 16:58 hoffman
-
- * Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Source/cmLocalUnixMakefileGenerator.cxx: BUG: fix path problems
-
-2002-11-12 16:27 will
-
- * Modules/FindX11.cmake: Backwards compatibility. Andy and Bill
- made me add socket library.
-
-2002-11-12 15:24 hoffman
-
- * Modules/Platform/Windows-bcc32.cmake,
- Modules/Platform/Windows-cl.cmake,
- Source/cmLocalUnixMakefileGenerator.cxx: ENH: add .def file
- support
-
-2002-11-12 14:48 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: change to new
- variables
-
-2002-11-12 14:19 hoffman
-
- * Modules/: CMakeBackwardCompatibilityC.cmake,
- CheckLibraryExists.cmake, FindThreads.cmake: add find threads
- check
-
-2002-11-12 14:18 hoffman
-
- * Tests/SystemInformation/: CMakeLists.txt, DumpInformation.cxx,
- DumpInformation.h.in, SystemInformation.in: clean up test for
- html output
-
-2002-11-12 13:06 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: fix reg expression
-
-2002-11-12 12:47 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: [no log message]
-
-2002-11-12 10:47 barre
-
- * Modules/FindOpenGL.cmake: FIX: minor fix, OPENGL_INCLUDE_PATH was
- set 2 times
-
-2002-11-12 09:33 hoffman
-
- * Tests/SystemInformation/DumpInformation.cxx: [no log message]
-
-2002-11-12 09:31 hoffman
-
- * Tests/SystemInformation/CMakeLists.txt: fix project name
-
-2002-11-12 09:12 hoffman
-
- * Modules/: CMakeSystemSpecificInformation.cmake,
- Platform/CYGWIN.cmake, Platform/Windows-bcc32.cmake,
- Platform/Windows-cl.cmake: Set CMAKE_BUILD_TOOL
-
-2002-11-11 18:10 hoffman
-
- * Modules/CMakeSystemSpecificInformation.cmake,
- Modules/Platform/Windows-bcc32.cmake,
- Modules/Platform/Windows-cl.cmake, Source/CMakeLists.txt,
- Source/TODO, Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.h: ENH: fix up several
- problems with new stuff
-
-2002-11-11 18:07 hoffman
-
- * Tests/SystemInformation/: CMakeLists.txt, DumpInformation.cxx,
- DumpInformation.h.in, SystemInformation.in: new test
-
-2002-11-11 17:00 hoffman
-
- * Modules/Platform/OSF1.cmake: Fix for OSF
-
-2002-11-11 13:15 andy
-
- * Source/cmLocalUnixMakefileGenerator.cxx: Fix regular expressions
- to be able to handle windows libraries
-
-2002-11-11 12:31 hoffman
-
- * Modules/CMakeBackwardCompatibilityC.cmake,
- Modules/CMakeCCompiler.cmake.in,
- Modules/CMakeCXXCompiler.cmake.in, Modules/CMakeSystem.cmake.in,
- Modules/CMakeSystemSpecificInformation.cmake,
- Modules/Platform/HP-UX.cmake, Modules/Platform/IRIX.cmake,
- Modules/Platform/IRIX64.cmake,
- Modules/Platform/Windows-bcc32.cmake,
- Modules/Platform/Windows-cl.cmake, Modules/Platform/gcc.cmake,
- Source/TODO, Source/cmGlobalUnixMakefileGenerator.cxx: clean up
- flags with _init flags
-
-2002-11-11 11:43 hoffman
-
- * Modules/: CMakeLists.txt, Platform/CMakeLists.txt: add install
- stuff for platform directory
-
-2002-11-11 09:11 hoffman
-
- * Modules/Platform/Darwin.cmake: ENH: fix for darwin modules
-
-2002-11-10 10:02 hoffman
-
- * Modules/Platform/: HP-UX.cmake, IRIX.cmake, IRIX64.cmake,
- Windows-bcc32.cmake, Windows-cl.cmake, gcc.cmake: BUG: fix
- setting of c flags
-
-2002-11-09 13:43 hoffman
-
- * Modules/Platform/: HP-UX.cmake, IRIX.cmake, IRIX64.cmake,
- Windows-bcc32.cmake, Windows-cl.cmake, gcc.cmake: fix for
- cxxflags
-
-2002-11-08 18:07 king
-
- * Modules/Platform/Linux-como.cmake: ENH: Adding support for comeau
- C++ compiler.
-
-2002-11-08 18:06 king
-
- * Modules/: CMakeSystemSpecificInformation.cmake,
- Platform/HP-UX.cmake, Platform/IRIX.cmake, Platform/IRIX64.cmake,
- Platform/Linux.cmake, Platform/Windows-bcc32.cmake,
- Platform/Windows-cl.cmake, Platform/gcc.cmake: ENH: Moved caching
- of C*_FLAGS* settings down to
- CMakeSystemSpecificInformation.cmake. The platform files can set
- the defaults on the first run, and then the settings are cached
- at the end.
-
-2002-11-08 18:05 king
-
- * Source/cmSetCommand.cxx: BUG: A variable is not in the cache if
- it is UNINITIALIZED.
-
-2002-11-08 18:05 king
-
- * Source/cmGlobalCodeWarriorGenerator.cxx: ERR: Removed use of
- NULL.
-
-2002-11-08 18:05 king
-
- * Source/cmSystemTools.cxx: ERR: Added missing include.
-
-2002-11-08 17:24 hoffman
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeDetermineCXXCompiler.cmake: store the compiler in the cache
-
-2002-11-08 15:46 hoffman
-
- * CMakeLists.txt, Modules/CMakeBackwardCompatibilityCXX.cmake,
- Modules/CMakeCCompiler.cmake.in,
- Modules/CMakeCXXCompiler.cmake.in,
- Modules/CMakeDefaultMakeRuleVariables.cmake,
- Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Modules/CMakeDetermineSystem.cmake,
- Modules/CMakePrintSystemInformation.cmake,
- Modules/CMakeSystem.cmake.in,
- Modules/CMakeSystemSpecificInformation.cmake,
- Modules/CYGWIN.cmake, Modules/CheckIncludeFile.cxx.in,
- Modules/CheckIncludeFileCXX.cmake,
- Modules/TestForANSIForScope.cmake,
- Modules/TestForAnsiForScope.cxx,
- Modules/TestForSTDNamespace.cmake,
- Modules/TestForSTDNamespace.cxx, Modules/Windows.cmake,
- Modules/Platform/AIX.cmake, Modules/Platform/BSDOS.cmake,
- Modules/Platform/CYGWIN.cmake, Modules/Platform/Darwin.cmake,
- Modules/Platform/FreeBSD.cmake, Modules/Platform/HP-UX.cmake,
- Modules/Platform/IRIX.cmake, Modules/Platform/IRIX64.cmake,
- Modules/Platform/Linux.cmake, Modules/Platform/MP-RAS.cmake,
- Modules/Platform/NetBSD.cmake, Modules/Platform/OSF1.cmake,
- Modules/Platform/OpenBSD.cmake, Modules/Platform/RISCos.cmake,
- Modules/Platform/SCO_SV.cmake, Modules/Platform/SINIX.cmake,
- Modules/Platform/SunOS.cmake, Modules/Platform/True64.cmake,
- Modules/Platform/ULTRIX.cmake, Modules/Platform/UNIX_SV.cmake,
- Modules/Platform/UnixWare.cmake,
- Modules/Platform/Windows-bcc32.cmake,
- Modules/Platform/Windows-cl.cmake,
- Modules/Platform/Windows.cmake, Modules/Platform/Xenix.cmake,
- Modules/Platform/gcc.cmake, Source/CMakeLists.txt, Source/TODO,
- Source/cmExecProgramCommand.cxx,
- Source/cmGlobalBorlandMakefileGenerator.cxx,
- Source/cmGlobalGenerator.cxx, Source/cmGlobalGenerator.h,
- Source/cmGlobalNMakeMakefileGenerator.cxx,
- Source/cmGlobalNMakeMakefileGenerator.h,
- Source/cmGlobalUnixMakefileGenerator.cxx,
- Source/cmGlobalUnixMakefileGenerator.h, Source/cmIfCommand.cxx,
- Source/cmLoadCommandCommand.cxx,
- Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.h, Source/cmMakefile.cxx,
- Source/cmStandardIncludes.h, Source/cmSystemTools.cxx,
- Source/cmSystemTools.h, Source/cmTryCompileCommand.cxx,
- Source/cmWin32ProcessExecution.cxx,
- Source/cmWin32ProcessExecution.h, Source/ctest.cxx: Complete
- rework of makefile generators expect trouble
-
-2002-11-08 13:28 hoffman
-
- * Modules/: CMakeCCompiler.cmake.in, CMakeDetermineCCompiler.cmake,
- CMakeDetermineCXXCompiler.cmake,
- CMakeSystemSpecificInformation.cmake,
- Platform/Windows-bcc32.cmake, Platform/Windows-cl.cmake: [no log
- message]
-
-2002-11-08 11:31 hoffman
-
- * Source/ctest.cxx: fix ctest
-
-2002-11-08 11:30 hoffman
-
- * Modules/: AIX.cmake, BSDOS.cmake,
- CMakeSystemSpecificInformation.cmake, CYGWIN.cmake, Darwin.cmake,
- FreeBSD.cmake, HP-UX.cmake, IRIX.cmake, IRIX64.cmake,
- Linux.cmake, MP-RAS.cmake, NetBSD.cmake, OSF1.cmake,
- OpenBSD.cmake, RISCos.cmake, SCO_SV.cmake, SINIX.cmake,
- SunOS.cmake, True64.cmake, ULTRIX.cmake, UNIX_SV.cmake,
- UnixWare.cmake, Windows-bcc32.cmake, Windows-cl.cmake,
- Windows.cmake, Xenix.cmake, gcc.cmake, Platform/AIX.cmake,
- Platform/BSDOS.cmake, Platform/CYGWIN.cmake,
- Platform/Darwin.cmake, Platform/FreeBSD.cmake,
- Platform/HP-UX.cmake, Platform/IRIX.cmake, Platform/IRIX64.cmake,
- Platform/Linux.cmake, Platform/MP-RAS.cmake,
- Platform/NetBSD.cmake, Platform/OSF1.cmake,
- Platform/OpenBSD.cmake, Platform/RISCos.cmake,
- Platform/SCO_SV.cmake, Platform/SINIX.cmake,
- Platform/SunOS.cmake, Platform/True64.cmake,
- Platform/ULTRIX.cmake, Platform/UNIX_SV.cmake,
- Platform/UnixWare.cmake, Platform/Windows-bcc32.cmake,
- Platform/Windows-cl.cmake, Platform/Windows.cmake,
- Platform/Xenix.cmake, Platform/gcc.cmake: move to platform
- directory
-
-2002-11-08 11:09 hoffman
-
- * Modules/CMakeSystemSpecificInformation.cmake: hp fixes
-
-2002-11-08 10:40 hoffman
-
- * Modules/HP-UX.cmake: hp fixes
-
-2002-11-08 10:29 hoffman
-
- * Modules/HP-UX.cmake: hp fixes
-
-2002-11-08 10:22 hoffman
-
- * Modules/CMakeSystemSpecificInformation.cmake,
- Modules/HP-UX.cmake, Source/cmLocalUnixMakefileGenerator.cxx: hp
- fixes
-
-2002-11-08 08:47 hoffman
-
- * Modules/: CMakeBackwardCompatibilityCXX.cmake, HP-UX.cmake,
- TestForANSIForScope.cmake: ENH: fix for hp and remove some
- messages
-
-2002-11-07 17:45 hoffman
-
- * Modules/: CMakeBackwardCompatibilityCXX.cmake,
- TestForANSIForScope.cmake, TestForAnsiForScope.cxx,
- TestForSTDNamespace.cxx: [no log message]
-
-2002-11-07 17:26 hoffman
-
- * Modules/TestForANSIForScope.cmake: [no log message]
-
-2002-11-07 17:21 hoffman
-
- * Modules/: CMakeBackwardCompatibilityCXX.cmake, HP-UX.cmake,
- TestForAnsiForScope.cxx, TestForSTDNamespace.cmake,
- TestForSTDNamespace.cxx: [no log message]
-
-2002-11-07 11:43 hoffman
-
- * Modules/Windows-cl.cmake, Source/cmExecProgramCommand.cxx,
- Source/cmLocalUnixMakefileGenerator.cxx: win32 apps and crash on
- sun
-
-2002-11-07 09:22 king
-
- * Source/cmStringCommand.cxx: ERR: Fixed signed/unsigned warnings.
-
-2002-11-07 09:15 andy
-
- * Source/CursesDialog/cmCursesMainForm.cxx: Revert
-
-2002-11-07 09:04 andy
-
- * Source/: cmake.cxx, cmake.h: Revert back
-
-2002-11-06 23:25 hoffman
-
- * Source/: cmGlobalNMakeMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator.cxx: clean up echos
-
-2002-11-06 23:06 hoffman
-
- * Modules/CMakeDefaultMakeRuleVariables.cmake,
- Modules/Windows-bcc32.cmake,
- Source/cmGlobalBorlandMakefileGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.h: borland mostly working,
- tests are passing, no command to file stuff yet
-
-2002-11-06 18:40 king
-
- * Modules/FindITK.cmake: ENH: Enhanced FindITK supporting use of
- ITK from an install tree or a build tree. Only one cache entry
- is brought into user's project, called "ITK_DIR". This is the
- location of an ITKConfig.cmake file from which other settings are
- loaded.
-
-2002-11-06 18:05 king
-
- * Source/cmStringCommand.cxx, Tests/Complex/CMakeLists.txt,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexRelativePaths/CMakeLists.txt: BUG: Fixed
- STRING(REGEX REPLACE ...) and added better test.
-
-2002-11-06 17:35 king
-
- * Source/cmCommands.cxx, Source/cmStringCommand.cxx,
- Source/cmStringCommand.h, Tests/Complex/CMakeLists.txt,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexRelativePaths/CMakeLists.txt: ENH: Added STRING
- command.
-
-2002-11-06 17:04 hoffman
-
- * Modules/Windows-bcc32.cmake: borland config
-
-2002-11-06 16:59 king
-
- * Source/: cmRegularExpression.cxx, cmRegularExpression.h: ENH:
- compile method now returns whether compilation succeeded.
-
-2002-11-06 16:30 hoffman
-
- * Modules/Windows-cl.cmake,
- Source/cmGlobalBorlandMakefileGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.h: borland getting closer
-
-2002-11-06 16:05 andy
-
- * Templates/AppleInfo.plist: Use CMake icon on Mac
-
-2002-11-06 14:56 andy
-
- * CMakeIcon.icns: Add Mac icon
-
-2002-11-06 14:54 andy
-
- * CMakeIcon.icns: Add CMake icon
-
-2002-11-06 13:06 andy
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h, ctest.cxx: Move the
- hi-res time to system tools
-
-2002-11-06 12:04 andy
-
- * Source/: cmake.cxx, cmake.h, CursesDialog/cmCursesMainForm.cxx:
- In certain cases, try to guess the source directory, so that you
- can run cmake or ccmake without specifying source dir
-
-2002-11-06 11:36 andy
-
- * Source/: cmSystemTools.cxx, CursesDialog/cmCursesPathWidget.cxx:
- Remove warning
-
-2002-11-06 11:20 barre
-
- * Source/cmMakeDepend.cxx: FIX: a / was appended without checking
- if there wasn't one already.
-
-2002-11-06 08:52 andy
-
- * Tests/X11/X11.c: Try to fix test
-
-2002-11-05 23:07 hoffman
-
- * Source/: TODO, cmLocalUnixMakefileGenerator.cxx: remove warning
-
-2002-11-05 22:55 hoffman
-
- * Modules/: CMakeDetermineCCompiler.cmake, IRIX64.cmake: ranlib
- trouble
-
-2002-11-05 22:44 hoffman
-
- * Modules/: CMakeDetermineCCompiler.cmake, IRIX.cmake,
- IRIX64.cmake: fix for no ranlib
-
-2002-11-05 18:11 hoffman
-
- * CMakeLists.txt, Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeSystem.cmake.in, Modules/IRIX64.cmake: remove debug
- message statements
-
-2002-11-05 18:06 hoffman
-
- * Modules/: IRIX64.cmake: [no log message]
-
-2002-11-05 17:57 hoffman
-
- * Modules/IRIX64.cmake, Source/cmLocalUnixMakefileGenerator.cxx:
- [no log message]
-
-2002-11-05 17:55 hoffman
-
- * CMakeLists.txt: debug
-
-2002-11-05 17:49 hoffman
-
- * Modules/CMakeDefaultMakeRuleVariables.cmake: enh: add <FLAGS> to
- link libs
-
-2002-11-05 17:31 hoffman
-
- * Modules/: CYGWIN.cmake, IRIX.cmake, IRIX64.cmake, gcc.cmake: add
- flags
-
-2002-11-05 17:20 andy
-
- * Modules/FindX11.cmake: Make things advanced
-
-2002-11-05 17:05 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: add cxx flags to link
- exe
-
-2002-11-05 15:49 hoffman
-
- * Modules/: HP-UX.cmake, IRIX64.cmake, OSF1.cmake: add ansi flags
-
-2002-11-05 14:33 hoffman
-
- * Modules/: IRIX.cmake, IRIX64.cmake, SunOS.cmake: [no log message]
-
-2002-11-05 14:10 hoffman
-
- * Modules/: AIX.cmake, BSDOS.cmake, Darwin.cmake, FreeBSD.cmake,
- HP-UX.cmake, IRIX.cmake, MP-RAS.cmake, NetBSD.cmake, OSF1.cmake,
- OpenBSD.cmake, RISCos.cmake, SCO_SV.cmake, SINIX.cmake,
- SunOS.cmake, True64.cmake, ULTRIX.cmake, UNIX_SV.cmake,
- UnixWare.cmake, Xenix.cmake: ENH: add all the OS files
-
-2002-11-05 13:35 andy
-
- * Source/CursesDialog/ccmake.cxx: Cleanup
-
-2002-11-05 11:52 hoffman
-
- * Modules/Linux.cmake: add linux config file
-
-2002-11-05 11:31 hoffman
-
- * Modules/: CMakeSystemSpecificInformation.cmake, Windows.cmake:
- add check for sstream
-
-2002-11-05 11:02 hoffman
-
- * Modules/: CMakeBackwardCompatibilityCXX.cmake,
- CheckIncludeFile.cxx.in, CheckIncludeFileCXX.cmake: add check for
- sstream
-
-2002-11-05 10:45 hoffman
-
- * Source/: cmGlobalUnixMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator.cxx: fix backwards compat enable and
- remove full path target
-
-2002-11-05 08:52 andy
-
- * Source/CursesDialog/: cmCursesFilePathWidget.cxx,
- cmCursesFilePathWidget.h, cmCursesPathWidget.cxx,
- cmCursesStringWidget.cxx: Reparent file path widget, add tab
- completion support to path anf file path widget
-
-2002-11-05 08:51 andy
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: Add a simple
- globbing of files and directories
-
-2002-11-05 07:15 andy
-
- * Modules/FindX11.cmake, Tests/X11/CMakeLists.txt: Try to fix
- FindX11
-
-2002-11-05 07:06 andy
-
- * Tests/X11/X11.c: Simplify
-
-2002-11-04 19:45 king
-
- * Source/cmITKWrapTclCommand.cxx: ENH: Added generation of
- --gccxml-compiler argument to GCC-XML for msvc6, msvc7, and nmake
- makefiles generators.
-
-2002-11-04 17:37 andy
-
- * Source/CursesDialog/: cmCursesPathWidget.cxx,
- cmCursesPathWidget.h, cmCursesStringWidget.cxx,
- cmCursesStringWidget.h: Start working on adding tab support
-
-2002-11-04 16:59 andy
-
- * Source/cmWin32ProcessExecution.cxx: Fix windows process execution
- so that it pops up the windows
-
-2002-11-04 16:26 hoffman
-
- * Modules/CMakeCCompiler.cmake.in,
- Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeSystemSpecificInformation.cmake,
- Modules/Windows-cl.cmake, Modules/Windows.cmake, Source/TODO,
- Source/cmGlobalNMakeMakefileGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.h, Source/cmSystemTools.cxx,
- Source/cmSystemTools.h, Source/cmTryCompileCommand.cxx: nmake
- passing tests
-
-2002-11-04 15:01 andy
-
- * Source/cmWriteFileCommand.cxx: Make directory if it does not
- exist yet
-
-2002-11-04 14:50 andy
-
- * Templates/AppleInfo.plist: Attempt to automate apple gui
- generation
-
-2002-11-04 11:54 andy
-
- * Tests/X11/X11.c: Fix test
-
-2002-11-04 10:13 hoffman
-
- * Source/TODO: [no log message]
-
-2002-11-04 10:11 hoffman
-
- * CMakeLists.txt, Modules/CMakeCXXCompiler.cmake.in,
- Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Modules/CMakePrintSystemInformation.cmake,
- Modules/CMakeSystemSpecificInformation.cmake,
- Modules/Windows-cl.cmake, Modules/Windows.cmake,
- Source/CMakeLists.txt,
- Source/cmGlobalBorlandMakefileGenerator.cxx,
- Source/cmGlobalNMakeMakefileGenerator.cxx,
- Source/cmIfCommand.cxx, Source/cmLocalUnixMakefileGenerator.cxx:
- nmake almost working
-
-2002-11-03 18:18 andy
-
- * Tests/X11/X11.c: Try to make test to run
-
-2002-11-01 22:57 hoffman
-
- * Source/CMakeLists.txt: make qt stuff advanced
-
-2002-10-31 10:36 andy
-
- * Templates/CCMakeSystemConfig.cmake.in: Revert X11 stuff until
- other steps are done
-
-2002-10-29 15:58 andy
-
- * Tests/X11/X11.c: Print message on system without X11
-
-2002-10-29 15:54 andy
-
- * Tests/X11/: CMakeLists.txt, X11.c: Add Windows code
-
-2002-10-29 15:47 andy
-
- * Modules/FindX11.cmake: Now it should work
-
-2002-10-29 15:46 andy
-
- * Source/CMakeLists.txt, Tests/X11/CMakeLists.txt, Tests/X11/X11.c:
- Add test for X11
-
-2002-10-29 15:03 hoffman
-
- * Modules/CMakeCXXCompiler.cmake.in,
- Modules/CMakeDefaultMakeRuleVariables.cmake,
- Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeDetermineCXXCompiler.cmake,
- Modules/CMakeDetermineSystem.cmake,
- Modules/CMakePrintSystemInformation.cmake,
- Modules/CMakeSystem.cmake.in,
- Modules/CMakeSystemSpecificInformation.cmake,
- Modules/CYGWIN.cmake, Source/cmGlobalGenerator.cxx,
- Source/cmGlobalGenerator.h,
- Source/cmGlobalNMakeMakefileGenerator.h,
- Source/cmGlobalUnixMakefileGenerator.cxx,
- Source/cmGlobalUnixMakefileGenerator.h,
- Source/cmLoadCommandCommand.cxx,
- Source/cmLocalUnixMakefileGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.h, Source/cmMakefile.cxx,
- Source/cmSystemTools.cxx, Tests/Testing/CMakeLists.txt: branch
- checkin of working cygwin build for generator cleanup and removal
- of configure
-
-2002-10-29 13:34 andy
-
- * Templates/CCMakeSystemConfig.cmake.in: Remove X11 stuff
-
-2002-10-29 13:34 andy
-
- * Modules/: CheckFunctionExists.cmake, CheckIncludeFile.cmake,
- CheckLibraryExists.cmake, CheckSizeOf.cmake, TestBigEndian.cmake:
- Add append to write_file
-
-2002-10-29 13:32 andy
-
- * Source/: cmWriteFileCommand.cxx, cmWriteFileCommand.h: Add flag
- to WRITE_FILE to append
-
-2002-10-29 13:30 andy
-
- * Modules/CMakeBackwardCompatibilityC.cmake: Do this the right way
-
-2002-10-29 13:30 andy
-
- * Modules/FindX11.cmake: This should substitute configure part that
- finds X11
-
-2002-10-28 10:29 king
-
- * Source/cmITKWrapTclCommand.cxx: ENH: Added generation of
- --gccxml-cxxflags option to complement --gccxml-compiler.
-
-2002-10-25 16:47 hoffman
-
- * Modules/CMakeDetermineCCompiler.cmake,
- Modules/CMakeSystemSpecificInformation.cmake,
- Source/cmGlobalUnixMakefileGenerator.cxx,
- Source/cmLocalUnixMakefileGenerator.cxx: [no log message]
-
-2002-10-25 16:13 hoffman
-
- * Modules/CMakeCXXCompiler.cmake.in: [no log message]
-
-2002-10-25 15:46 king
-
- * Utilities/cmake_release_cygwin.sh: ENH: Updated for cmake 1.4.6
- package. Added automatic conversion of setup.hint to unix
- newlines.
-
-2002-10-25 14:34 hoffman
-
- * Modules/: CMakeCCompiler.cmake.in, CMakeDetermineCCompiler.cmake:
- [no log message]
-
-2002-10-25 14:25 hoffman
-
- * Source/: cmGlobalUnixMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator.cxx, cmLocalUnixMakefileGenerator.h:
- test on unix
-
-2002-10-25 14:13 king
-
- * Utilities/: cmake_release_config_darwin,
- cmake_release_config_hpux, cmake_release_config_irix,
- cmake_release_config_linux, cmake_release_config_osf,
- cmake_release_config_sun, cmake_release_cygwin.sh: ENH: Updated
- for 1.4.6 release.
-
-2002-10-25 14:08 hoffman
-
- * Modules/: CMakeDefaultMakeRuleVariables.cmake,
- CMakeDetermineCCompiler.cmake, CMakeDetermineCXXCompiler.cmake,
- CMakeDetermineSystem.cmake, CMakeSystemSpecificInformation.cmake:
- [no log message]
-
-2002-10-24 15:39 hoffman
-
- * Source/cmake.cxx: BUG: fix stack limit size on mac OSX
-
-2002-10-24 13:39 andy
-
- * Modules/CMakeBackwardCompatibilityC.cmake: Add check for big
- endian in backward compatibility scripts
-
-2002-10-24 11:58 martink
-
- * Source/cmMakefile.h: updated patch level to 6
-
-2002-10-24 11:48 martink
-
- * Source/cmBorlandMakefileGenerator.cxx: fix support for Win32
- execs
-
-2002-10-24 10:58 andy
-
- * Source/cmSubdirCommand.cxx: Subdirs reports an error if the
- subdirectory does not exists
-
-2002-10-24 10:23 andy
-
- * Source/cmMakefile.cxx: Try to remove some warnings
-
-2002-10-23 18:03 king
-
- * Source/: cmAbstractFilesCommand.cxx, cmAbstractFilesCommand.h,
- cmAddCustomCommandCommand.cxx, cmAddCustomCommandCommand.h,
- cmAddCustomTargetCommand.cxx, cmAddCustomTargetCommand.h,
- cmAddDefinitionsCommand.cxx, cmAddDefinitionsCommand.h,
- cmAddDependenciesCommand.cxx, cmAddDependenciesCommand.h,
- cmAddExecutableCommand.cxx, cmAddExecutableCommand.h,
- cmAddLibraryCommand.cxx, cmAddLibraryCommand.h,
- cmAddTestCommand.cxx, cmAddTestCommand.h,
- cmAuxSourceDirectoryCommand.cxx, cmAuxSourceDirectoryCommand.h,
- cmBuildCommand.cxx, cmBuildCommand.h, cmBuildNameCommand.cxx,
- cmBuildNameCommand.h, cmCMakeMinimumRequired.cxx,
- cmCMakeMinimumRequired.h, cmCPluginAPI.cxx, cmCPluginAPI.h,
- cmCacheManager.cxx, cmCacheManager.h, cmCommand.h,
- cmCommands.cxx, cmCommands.h, cmConfigureFileCommand.cxx,
- cmConfigureFileCommand.h, cmCreateTestSourceList.cxx,
- cmCreateTestSourceList.h, cmCustomCommand.cxx, cmCustomCommand.h,
- cmData.h, cmDirectory.cxx, cmDirectory.h,
- cmDumpDocumentation.cxx, cmDynamicLoader.cxx, cmDynamicLoader.h,
- cmElseCommand.cxx, cmElseCommand.h, cmEnableTestingCommand.cxx,
- cmEnableTestingCommand.h, cmEndForEachCommand.cxx,
- cmEndForEachCommand.h, cmEndIfCommand.cxx, cmEndIfCommand.h,
- cmExecProgramCommand.cxx, cmExecProgramCommand.h,
- cmFLTKWrapUICommand.cxx, cmFLTKWrapUICommand.h,
- cmFindFileCommand.cxx, cmFindFileCommand.h,
- cmFindLibraryCommand.cxx, cmFindLibraryCommand.h,
- cmFindPathCommand.cxx, cmFindPathCommand.h,
- cmFindProgramCommand.cxx, cmFindProgramCommand.h,
- cmForEachCommand.cxx, cmForEachCommand.h, cmFunctionBlocker.h,
- cmGeneratedFileStream.h, cmGetFilenameComponentCommand.cxx,
- cmGetFilenameComponentCommand.h,
- cmGetSourceFilePropertyCommand.cxx,
- cmGetSourceFilePropertyCommand.h,
- cmGlobalBorlandMakefileGenerator.cxx,
- cmGlobalBorlandMakefileGenerator.h,
- cmGlobalCodeWarriorGenerator.cxx, cmGlobalCodeWarriorGenerator.h,
- cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalNMakeMakefileGenerator.cxx,
- cmGlobalNMakeMakefileGenerator.h,
- cmGlobalUnixMakefileGenerator.cxx,
- cmGlobalUnixMakefileGenerator.h,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio6Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h, cmITKWrapTclCommand.cxx,
- cmITKWrapTclCommand.h, cmIfCommand.cxx, cmIfCommand.h,
- cmIncludeCommand.cxx, cmIncludeCommand.h,
- cmIncludeDirectoryCommand.cxx, cmIncludeDirectoryCommand.h,
- cmIncludeExternalMSProjectCommand.cxx,
- cmIncludeExternalMSProjectCommand.h,
- cmIncludeRegularExpressionCommand.cxx,
- cmIncludeRegularExpressionCommand.h, cmInstallFilesCommand.cxx,
- cmInstallFilesCommand.h, cmInstallProgramsCommand.cxx,
- cmInstallProgramsCommand.h, cmInstallTargetsCommand.cxx,
- cmInstallTargetsCommand.h, cmLinkDirectoriesCommand.cxx,
- cmLinkDirectoriesCommand.h, cmLinkLibrariesCommand.cxx,
- cmLinkLibrariesCommand.h, cmListFileCache.cxx, cmListFileCache.h,
- cmLoadCacheCommand.cxx, cmLoadCacheCommand.h,
- cmLoadCommandCommand.cxx, cmLoadCommandCommand.h,
- cmLocalBorlandMakefileGenerator.cxx,
- cmLocalBorlandMakefileGenerator.h,
- cmLocalCodeWarriorGenerator.cxx, cmLocalCodeWarriorGenerator.h,
- cmLocalGenerator.cxx, cmLocalGenerator.h,
- cmLocalNMakeMakefileGenerator.cxx,
- cmLocalNMakeMakefileGenerator.h,
- cmLocalUnixMakefileGenerator.cxx, cmLocalUnixMakefileGenerator.h,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio6Generator.h,
- cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h, cmMacroCommand.cxx,
- cmMacroCommand.h, cmMakeDepend.cxx, cmMakeDepend.h,
- cmMakeDirectoryCommand.cxx, cmMakeDirectoryCommand.h,
- cmMakefile.cxx, cmMakefile.h, cmMarkAsAdvancedCommand.cxx,
- cmMarkAsAdvancedCommand.h, cmMessageCommand.cxx,
- cmMessageCommand.h, cmOptionCommand.cxx, cmOptionCommand.h,
- cmOutputRequiredFilesCommand.cxx, cmOutputRequiredFilesCommand.h,
- cmProjectCommand.cxx, cmProjectCommand.h, cmQTWrapCPPCommand.cxx,
- cmQTWrapCPPCommand.h, cmQTWrapUICommand.cxx, cmQTWrapUICommand.h,
- cmRegularExpression.cxx, cmRegularExpression.h,
- cmRemoveCommand.cxx, cmRemoveCommand.h,
- cmSeparateArgumentsCommand.cxx, cmSeparateArgumentsCommand.h,
- cmSetCommand.cxx, cmSetCommand.h,
- cmSetSourceFilesPropertiesCommand.cxx,
- cmSetSourceFilesPropertiesCommand.h, cmSiteNameCommand.cxx,
- cmSiteNameCommand.h, cmSourceFile.cxx, cmSourceFile.h,
- cmSourceFilesCommand.cxx, cmSourceFilesCommand.h,
- cmSourceFilesRemoveCommand.cxx, cmSourceFilesRemoveCommand.h,
- cmSourceGroup.cxx, cmSourceGroup.h, cmSourceGroupCommand.cxx,
- cmSourceGroupCommand.h, cmStandardIncludes.h,
- cmSubdirCommand.cxx, cmSubdirCommand.h,
- cmSubdirDependsCommand.cxx, cmSubdirDependsCommand.h,
- cmSystemTools.cxx, cmSystemTools.h, cmTarget.cxx, cmTarget.h,
- cmTargetLinkLibrariesCommand.cxx, cmTargetLinkLibrariesCommand.h,
- cmTryCompileCommand.cxx, cmTryCompileCommand.h,
- cmTryRunCommand.cxx, cmTryRunCommand.h,
- cmUseMangledMesaCommand.cxx, cmUseMangledMesaCommand.h,
- cmUtilitySourceCommand.cxx, cmUtilitySourceCommand.h,
- cmVTKMakeInstantiatorCommand.cxx, cmVTKMakeInstantiatorCommand.h,
- cmVTKWrapJavaCommand.cxx, cmVTKWrapJavaCommand.h,
- cmVTKWrapPythonCommand.cxx, cmVTKWrapPythonCommand.h,
- cmVTKWrapTclCommand.cxx, cmVTKWrapTclCommand.h,
- cmVariableRequiresCommand.cxx, cmVariableRequiresCommand.h,
- cmWin32ProcessExecution.cxx, cmWin32ProcessExecution.h,
- cmWrapExcludeFilesCommand.cxx, cmWrapExcludeFilesCommand.h,
- cmWriteFileCommand.cxx, cmWriteFileCommand.h, cmake.cxx, cmake.h,
- cmakemain.cxx, cmaketest.cxx, cmakewizard.cxx, cmakewizard.h,
- cmw9xcom.cxx, ctest.cxx, ctest.h, CursesDialog/ccmake.cxx,
- CursesDialog/cmCursesBoolWidget.cxx,
- CursesDialog/cmCursesBoolWidget.h,
- CursesDialog/cmCursesCacheEntryComposite.cxx,
- CursesDialog/cmCursesCacheEntryComposite.h,
- CursesDialog/cmCursesDummyWidget.cxx,
- CursesDialog/cmCursesDummyWidget.h,
- CursesDialog/cmCursesFilePathWidget.cxx,
- CursesDialog/cmCursesFilePathWidget.h,
- CursesDialog/cmCursesForm.cxx, CursesDialog/cmCursesForm.h,
- CursesDialog/cmCursesLabelWidget.cxx,
- CursesDialog/cmCursesLabelWidget.h,
- CursesDialog/cmCursesLongMessageForm.cxx,
- CursesDialog/cmCursesLongMessageForm.h,
- CursesDialog/cmCursesMainForm.cxx,
- CursesDialog/cmCursesMainForm.h,
- CursesDialog/cmCursesPathWidget.cxx,
- CursesDialog/cmCursesPathWidget.h,
- CursesDialog/cmCursesStandardIncludes.h,
- CursesDialog/cmCursesStringWidget.cxx,
- CursesDialog/cmCursesStringWidget.h,
- CursesDialog/cmCursesWidget.cxx, CursesDialog/cmCursesWidget.h:
- ENH: Added reference to Copyright.txt. Removed old reference to
- ITK copyright. Changed program name to CMake instead of Insight
- in source file header. Also removed tabs.
-
-2002-10-23 16:57 hoffman
-
- * Source/: cmExecProgramCommand.cxx, cmExecProgramCommand.h: ENH:
- if output variable turn verbose off
-
-2002-10-23 16:53 hoffman
-
- * Modules/: CMakeCCompiler.cmake.in,
- CMakeDefaultMakeRuleVariables.cmake,
- CMakeDetermineCCompiler.cmake, CMakeDetermineCXXCompiler.cmake,
- CMakeDetermineSystem.cmake, CMakePrintSystemInformation.cmake,
- CMakeSystem.cmake.in, CMakeSystemSpecificInformation.cmake,
- CYGWIN.cmake: closer to removing autoconf
-
-2002-10-23 16:43 king
-
- * Source/CursesDialog/form/frm_driver.c: ERR: Another attempt to
- remove warnings from missing prototypes.
-
-2002-10-22 18:17 hoffman
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeDetermineCXXCompiler.cmake, CMakeTestGNU.c, Windows.cmake:
- test for gnu compiler
-
-2002-10-22 15:04 hoffman
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeSystemSpecificInformation.cmake, CYGWIN.cmake: [no log
- message]
-
-2002-10-22 10:36 hoffman
-
- * Source/cmLocalBorlandMakefileGenerator.cxx: BUG: make sure win32
- exes are win32
-
-2002-10-22 10:34 hoffman
-
- * Modules/: CMakeDetermineCCompiler.cmake,
- CMakeDetermineCXXCompiler.cmake, CMakeDetermineSystem.cmake,
- CMakeSystemSpecificInformation.cmake: new cmake based
- configuration
-
-2002-10-18 15:51 andy
-
- * Source/ctest.cxx: When in verbose mode print test command
-
-2002-10-18 12:08 andy
-
- * Source/cmWin32ProcessExecution.h: Improve comment
-
-2002-10-17 10:50 andy
-
- * Source/: CursesDialog/cmCursesMainForm.cxx,
- cmCreateTestSourceList.cxx, cmDirectory.cxx,
- cmFindProgramCommand.cxx, cmGlobalUnixMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator.cxx, cmSystemTools.cxx,
- cmUseMangledMesaCommand.cxx: Rename variables to remove warnings
-
-2002-10-16 13:30 martink
-
- * Source/cmVTKWrapTclCommand.cxx: update to handle tcl 84
-
-2002-10-16 11:48 martink
-
- * Source/CursesDialog/cmCursesLongMessageForm.cxx: fix compiler
- warnings
-
-2002-10-16 11:41 martink
-
- * Source/CursesDialog/form/fty_regex.c: fix compiler warnings
-
-2002-10-16 11:37 martink
-
- * Source/CursesDialog/form/: fty_alnum.c, fty_alpha.c, fty_int.c,
- fty_ipv4.c, fty_num.c: fix compiler warnings
-
-2002-10-16 11:32 martink
-
- * Source/CursesDialog/: cmCursesMainForm.cxx, ccmake.cxx: fixed a
- warning
-
-2002-10-16 11:24 martink
-
- * Source/CursesDialog/cmCursesLongMessageForm.cxx: fixed a warning
-
-2002-10-16 11:20 martink
-
- * Source/CursesDialog/: cmCursesForm.h, cmCursesLabelWidget.cxx:
- fixed a warning
-
-2002-10-16 11:16 martink
-
- * Source/CursesDialog/: cmCursesBoolWidget.cxx,
- cmCursesDummyWidget.cxx: fixed a warning
-
-2002-10-16 10:53 king
-
- * Source/CursesDialog/form/frm_driver.c: ENH: Another attempt to
- fix OSF warnings. Also removed TABS.
-
-2002-10-16 08:49 andy
-
- * Source/ctest.cxx: Remove unused variable
-
-2002-10-15 14:33 martink
-
- * Source/cmLoadCommandCommand.cxx: better warning message
-
-2002-10-15 11:45 martink
-
- * Source/cmLoadCommandCommand.cxx: better warning message
-
-2002-10-15 07:20 andy
-
- * Source/ctest.cxx: Remove std::hex as it does not seems to work on
- SGI, attempt to fix ftime problem on borland
-
-2002-10-14 18:33 andy
-
- * Source/ctest.cxx: Fix namespace, typo, and make ftime work on
- windows
-
-2002-10-14 15:11 andy
-
- * Source/: ctest.cxx, ctest.h: Even more cleanups, fix time on
- certain platforms such as windows, cygwin, and linux. Hopefully
- we can add entries for other platforms until try_compile works.
- Also escape certain characters for xml.
-
-2002-10-14 09:30 andy
-
- * Source/ctest.cxx: More cleanups, fix prexontext and log number
-
-2002-10-13 23:07 andy
-
- * Source/: ctest.cxx, ctest.h: Add LastBuild.log file, fix some
- minor problems in output, modify output a bit...
-
-2002-10-11 13:17 martink
-
- * Source/cmLocalCodeWarriorGenerator.cxx: compiler warning
-
-2002-10-11 11:22 iscott
-
- * Modules/Dart.cmake: Add option to control number of errors sent
- to dashbaord
-
-2002-10-11 10:16 king
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Added Split
- method to cmSystemTools to split a string into lines on its
- newlines.
-
-2002-10-11 10:14 king
-
- * Modules/FindCABLE.cmake: BUG: Should not load
- CMAKE_INSTALL_PREFIX from the cache.
-
-2002-10-11 08:36 king
-
- * Source/cmStandardIncludes.h: ERR: istrstream and istringstream
- need to be pulled into namespace std on the SGI.
-
-2002-10-10 11:08 andy
-
- * Source/cmWin32ProcessExecution.cxx: Fix network build
-
-2002-10-10 10:45 barre
-
- * Modules/FindJava.cmake, Templates/CCMakeSystemConfig.cmake.in,
- Templates/CMakeBorlandWindowsSystemConfig.cmake,
- Templates/CMakeDotNetSystemConfig.cmake,
- Templates/CMakeNMakeWindowsSystemConfig.cmake,
- Templates/CMakeWindowsSystemConfig.cmake,
- Templates/CXXCMakeSystemConfig.cmake.in: ENH: mark some vars as
- advanced (and resort the list)
-
-2002-10-10 10:43 king
-
- * Source/: cmCMakeMinimumRequired.cxx,
- cmLocalBorlandMakefileGenerator.cxx,
- cmLocalNMakeMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator.cxx, cmStandardIncludes.h,
- cmSystemTools.cxx, cmVTKMakeInstantiatorCommand.cxx, cmake.cxx,
- ctest.cxx: ENH: Renamed cmStringStream to cmOStringStream and
- added cmIStringStream. Removed cmInputStringStream.
-
-2002-10-10 09:41 andy
-
- * Source/: cmGlobalCodeWarriorGenerator.cxx,
- cmLocalCodeWarriorGenerator.cxx, cmStandardIncludes.h: Remove
- compile error and remove some warnings
-
-2002-10-10 09:02 king
-
- * Utilities/cmake_release_config_osf: ENH: Updated for actual
- build.
-
-2002-10-10 08:25 martink
-
- * Source/: cmGlobalCodeWarriorGenerator.cxx,
- cmLocalCodeWarriorGenerator.cxx: fixed some compiler warnings
-
-2002-10-10 08:23 andy
-
- * Source/ctest.cxx: Remove warning
-
-2002-10-10 08:11 andy
-
- * Source/cmSetCommand.cxx: Remove warning
-
-2002-10-10 08:11 andy
-
- * Source/: cmStandardIncludes.h, ctest.cxx: Try to use platform
- independent input string stream
-
-2002-10-09 17:47 martink
-
- * Source/: cmDynamicLoader.cxx, cmaketest.cxx: Remove memory leak
- caused by cmDynamicLoader not being deleted properly
-
-2002-10-09 15:54 martink
-
- * Tests/: Complex/CMakeLists.txt, Complex/cmTestConfigure.h.in,
- Complex/Executable/complex.cxx, ComplexOneConfig/CMakeLists.txt,
- ComplexOneConfig/cmTestConfigure.h.in,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/CMakeLists.txt,
- ComplexRelativePaths/cmTestConfigure.h.in,
- ComplexRelativePaths/Executable/complex.cxx: added test of SET
- CACHE FORCE
-
-2002-10-09 15:48 martink
-
- * Source/: cmSetCommand.cxx, cmSetCommand.h: added FORCE option
-
-2002-10-09 15:36 martink
-
- * Source/CursesDialog/ccmake.cxx: fix for OSF
-
-2002-10-09 15:24 barre
-
- * Source/cmGlobalGenerator.cxx: ENH: update the progress when
- generating is "done".
-
-2002-10-09 13:49 martink
-
- * Source/cmGlobalCodeWarriorGenerator.h: changed name
-
-2002-10-09 13:47 andy
-
- * Modules/FindwxWindows.cmake: Add some search paths
-
-2002-10-09 13:37 martink
-
- * Source/cmake.cxx: added Code Warrior dev
-
-2002-10-09 13:31 martink
-
- * Source/: Makefile.in, CMakeLists.txt: added build for Code
- Warrior
-
-2002-10-09 13:30 martink
-
- * Source/: cmGlobalCodeWarriorGenerator.cxx,
- cmLocalCodeWarriorGenerator.cxx, cmLocalCodeWarriorGenerator.h:
- some updates
-
-2002-10-08 22:54 andy
-
- * Source/: ctest.cxx, ctest.h: Reorganization, cleanup and some
- improvement in dart emulation
-
-2002-10-08 22:00 andy
-
- * Source/: ctest.cxx, ctest.h: Add parsing of warnings and errors
-
-2002-10-08 20:02 andy
-
- * Source/: ctest.cxx, ctest.h: Add configure option and fix
- potential bug in other targets. Now the run command is actually
- run with directory, so eventually we should be able to run this
- from a subdirectory
-
-2002-10-08 15:55 martink
-
- * Tests/: LoadCommand/CMakeCommands/cmTestCommand.c,
- LoadCommandOneConfig/CMakeCommands/cmTestCommand.c: new plugin
- API
-
-2002-10-08 15:55 martink
-
- * Source/: cmCPluginAPI.cxx, cmCPluginAPI.h,
- cmLoadCommandCommand.cxx: some mods to the plugin API
-
-2002-10-08 10:53 hoffman
-
- * Source/cmExecProgramCommand.cxx: BUG: get all the output
- including the last character
-
-2002-10-07 16:23 martink
-
- * CMakeLists.txt: added header dep
-
-2002-10-07 09:20 andy
-
- * Tests/COnly/: foo.c, foo.h: Fix problem on HP
-
-2002-10-07 09:16 martink
-
- * Source/cmIfCommand.cxx: minor fix to allow if with no arguments
-
-2002-10-07 08:23 andy
-
- * Source/cmGlobalVisualStudio6Generator.cxx: Suppress output of
- trycompile
-
-2002-10-06 21:25 andy
-
- * Source/ctest.cxx: Fix update so that it actually updates the
- source directory,
-
-2002-10-06 21:24 andy
-
- * Source/cmSystemTools.cxx: Fix for run command on windows. If you
- specify command in quotes but not full path, it should still work
-
-2002-10-06 20:44 andy
-
- * Source/ctest.cxx: Add missing namespace
-
-2002-10-06 20:44 andy
-
- * Source/cmSystemTools.cxx: Revert back. Does not seems to work on
- Windows
-
-2002-10-06 20:36 andy
-
- * Source/: ctest.cxx, ctest.h: Add some minimal Dart capability to
- ctest. For example now you can actually use ctest to build
- projects, do cvs update on all platforms. This is especially cool
- for Visual Studio where you do not want to load the whole
- development environment just to build your project.
-
-2002-10-06 18:56 andy
-
- * Source/cmSystemTools.cxx: Check if directory was actually created
-
-2002-10-06 15:10 barre
-
- * Templates/CMakeNMakeWindowsSystemConfig.cmake: ENH: nmake now
- uses incremental linking as Msdev does. Faster build (linking a
- static vtk.exe or paraview.exe could take more than 10 minutes)
-
-2002-10-06 12:12 andy
-
- * Source/cmTarget.cxx, Tests/COnly/CMakeLists.txt,
- Tests/COnly/conly.c, Tests/COnly/foo.c, Tests/COnly/foo.h: If you
- specify header file as source, it should still use C compiler and
- not CXX. Also fix COnly test so that it make sure that this still
- works...
-
-2002-10-05 10:24 andy
-
- * Source/: cmSystemTools.cxx, cmWin32ProcessExecution.h: Fix
- borland build. Borland Run command should be static, since it is
- called with no object...
-
-2002-10-04 18:16 andy
-
- * Source/: cmMakefile.cxx, cmMakefile.h, cmRegularExpression.cxx,
- cmRegularExpression.h, cmSourceGroupCommand.cxx: Try to improve
- source group interface
-
-2002-10-04 14:01 andy
-
- * Source/cmCacheManager.cxx: Remove tabs
-
-2002-10-04 12:30 andy
-
- * Source/cmCacheManager.cxx: Fix reading of advanced values from
- CMakeCache
-
-2002-10-04 11:42 martink
-
- * Source/: cmLocalCodeWarriorGenerator.h,
- cmGlobalCodeWarriorGenerator.cxx,
- cmLocalCodeWarriorGenerator.cxx: updates
-
-2002-10-04 11:33 barre
-
- * DartConfig.cmake: ENH: my opinion is that it should be ADVANCED.
- Few people build the doc.
-
-2002-10-04 10:47 andy
-
- * Source/cmSystemTools.cxx: Add missing argument
-
-2002-10-04 10:38 andy
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h,
- cmWin32ProcessExecution.cxx, cmWin32ProcessExecution.h: Cleanup
- RunCOmmand code and move borland one to vtkWin32ProcessExecution,
- so that it is all in one place... Add timeout option whihc does
- not work yet, but it should not produce warning any more
-
-2002-10-04 08:59 martink
-
- * Source/cmLocalGenerator.cxx: always set PROJECT_SOURCE_DIR etc
-
-2002-10-03 16:40 martink
-
- * Source/: cmGlobalCodeWarriorGenerator.cxx,
- cmLocalCodeWarriorGenerator.cxx: some fixes
-
-2002-10-03 15:14 martink
-
- * Source/: cmGlobalCodeWarriorGenerator.cxx,
- cmGlobalCodeWarriorGenerator.h, cmLocalCodeWarriorGenerator.cxx,
- cmLocalCodeWarriorGenerator.h: under development
-
-2002-10-02 17:46 martink
-
- * Source/cmWin32ProcessExecution.cxx: Revert to fix win 9x
-
-2002-10-02 17:31 king
-
- * Source/: cmGlobalUnixMakefileGenerator.cxx, cmStandardIncludes.h:
- ENH: Added explicit declarations of some C functions that are
- hard to get from standard headers in como
- (www.comeaucomputing.com) strict mode.
-
-2002-10-02 17:23 king
-
- * Source/cmIncludeCommand.cxx: BUG: Must return false after an
- error of incorrect arguments.
-
-2002-10-02 17:22 king
-
- * Source/: cmIfCommand.cxx, cmIfCommand.h: BUG: STRLESS and
- STRGREATER need to treat non-existent definitions as strings.
-
-2002-10-02 17:16 andy
-
- * Source/cmWin32ProcessExecution.cxx: Cleanup and try to unify with
- the other code
-
-2002-10-02 17:14 andy
-
- * Source/cmSystemTools.cxx: Cleanup
-
-2002-10-02 16:42 ibanez
-
- * Modules/CMakeLists.txt: ENH: Adding install of .in and .c
- modules.
-
-2002-10-02 11:35 martink
-
- * Source/cmLocalBorlandMakefileGenerator.cxx: Remove unnecessary
- new line
-
-2002-10-02 11:15 martink
-
- * Source/cmSystemTools.cxx: Fix bug in borland run command
-
-2002-10-02 11:14 martink
-
- * Source/cmake.cxx: Produce only one output
-
-2002-10-01 18:37 king
-
- * Source/cmITKWrapTclCommand.cxx: ENH: Added support to pass the
- gccxml program location to cable if ITK_GCCXML_EXECUTABLE is set
- on m_Makefile.
-
-2002-10-01 15:56 andy
-
- * Modules/: TestBigEndian.c, TestBigEndian.cmake: Add test for big
- endian
-
-2002-10-01 13:04 martink
-
- * Source/cmWin32ProcessExecution.cxx: Fix grouping of arguments on
- Windows 98
-
-2002-10-01 13:04 martink
-
- * Source/cmLocalVisualStudio6Generator.cxx: Fix a bug in generator.
- This one is good: This bug is only present on Windows 98, but
- since RunCommand did not work, it never showed on the
- dashboard... In any case commands in Visual studio 6 should be in
- windows style slashes
-
-2002-10-01 13:00 martink
-
- * Source/cmw9xcom.cxx: Put quotes around arguments if they have
- spaces and no quotes
-
-2002-10-01 12:59 martink
-
- * Tests/: Complex/CMakeLists.txt, ComplexOneConfig/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt: Remove bogus exec_program
-
-2002-10-01 10:12 ibanez
-
- * Modules/FindFLTK.cmake: ENH: removed "USE_FLTK_VERSION_1.1" in
- favor of "FLTK_VERSION_1.1" to avoid confusions.
-
-2002-10-01 07:28 andy
-
- * Source/: Makefile.in, cmakemain.cxx: Remove dependency to dynamic
- loader during bootstrap
-
-2002-09-30 22:26 ibanez
-
- * Modules/FindFLTK.cmake: ENH: Version 1.1 is considered to be the
- default.
-
-2002-09-30 21:34 king
-
- * Source/CursesDialog/cmCursesMainForm.cxx: ERR: Fixed bad sentence
- in error message.
-
-2002-09-30 16:46 andy
-
- * Source/cmake.cxx: Fix bug in chdir; Who did this anyway...
-
-2002-09-30 16:25 hoffman
-
- * Source/: Makefile.in, cmDynamicLoader.cxx, cmakemain.cxx: BUG:
- fix load command stuff for cygwin and cleanup at exit
-
-2002-09-30 15:05 martink
-
- * Source/cmWin32ProcessExecution.h: Add some more comments
-
-2002-09-30 15:00 martink
-
- * Source/cmWin32ProcessExecution.cxx: Cleanups and hopefully now it
- works on all windows platforms
-
-2002-09-30 14:01 martink
-
- * Source/cmake.cxx: Set comspec substitute the right way
-
-2002-09-30 14:00 martink
-
- * Source/ctest.cxx: Set comspec substitute
-
-2002-09-30 13:59 martink
-
- * Source/cmw9xcom.cxx: Add spaces
-
-2002-09-30 12:24 ibanez
-
- * Modules/FindLATEX.cmake: Configuratiion for finding LaTeX
- related executables.
-
-2002-09-30 11:41 andy
-
- * Source/: CMakeLists.txt, cmSystemTools.cxx, cmake.cxx,
- cmw9xcom.cxx: Another attempt on Windows 98
-
-2002-09-30 11:00 andy
-
- * Source/cmSystemTools.cxx: Attempt to unify the code
-
-2002-09-30 10:47 andy
-
- * Source/cmSystemTools.cxx: Fix bug in printing
-
-2002-09-30 07:55 andy
-
- * Source/cmWin32ProcessExecution.cxx: Remove warnings and fix
- potential bug
-
-2002-09-30 07:09 andy
-
- * Source/cmSystemTools.cxx,
- Templates/CMakeBorlandWindowsSystemConfig.cmake: Make borland
- pass all the tests on XP (and 2000?)
-
-2002-09-29 22:10 andy
-
- * Source/cmSystemTools.cxx: Remove debug
-
-2002-09-29 21:57 andy
-
- * Source/cmSystemTools.cxx: It is late and it at least seems to
- work better than before...
-
-2002-09-29 21:55 andy
-
- * Source/: cmWin32ProcessExecution.cxx, cmWin32ProcessExecution.h:
- Fix for it to compile on "all" windows platforms...
-
-2002-09-29 21:48 andy
-
- * Source/cmSystemTools.cxx: Simplify debugging by resetting error
- code
-
-2002-09-29 14:09 martink
-
- * Source/: cmWin32ProcessExecution.cxx, cmWin32ProcessExecution.h:
- possible fix for warnings
-
-2002-09-29 14:09 martink
-
- * Source/cmake.cxx: compiler warnings
-
-2002-09-27 17:28 andy
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h, cmake.cxx: Add two
- cmake commands -E echo for echoing strings and -E comspec for
- workaround of bug of windows 9x; add another implementation of
- run command on windows which should work...
-
-2002-09-27 17:26 andy
-
- * Source/: CMakeLists.txt, cmWin32ProcessExecution.cxx,
- cmWin32ProcessExecution.h: Add class for process execution on
- Windows
-
-2002-09-27 17:16 andy
-
- * Tests/: Complex/CMakeLists.txt, ComplexOneConfig/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt: Use cmake echo
-
-2002-09-27 16:23 martink
-
- * Source/: cmCreateTestSourceList.cxx, cmInstallFilesCommand.cxx,
- cmInstallProgramsCommand.cxx, cmIncludeDirectoryCommand.cxx:
- removed some includes
-
-2002-09-27 16:19 martink
-
- * Source/: cmTarget.cxx, cmTarget.h, cmCommand.h,
- cmEnableTestingCommand.cxx, cmEndForEachCommand.cxx,
- cmForEachCommand.cxx, cmAddTestCommand.cxx,
- cmAuxSourceDirectoryCommand.cxx, cmElseCommand.cxx,
- cmEndIfCommand.cxx, cmIfCommand.cxx, cmAbstractFilesCommand.cxx,
- cmAddDependenciesCommand.cxx, cmAddLibraryCommand.cxx,
- cmInstallTargetsCommand.cxx, cmMacroCommand.cxx,
- cmMessageCommand.cxx, cmWriteFileCommand.cxx,
- cmAddExecutableCommand.cxx: removed some includes
-
-2002-09-27 16:19 hoffman
-
- * Source/: cmSetCommand.cxx, cmSetCommand.h: BUG: fix doc string
- and allow a variable to be promoted from non-cache to cache
-
-2002-09-27 16:18 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: remove unused stuff
-
-2002-09-27 15:52 martink
-
- * Source/cmMakefile.h: new patch
-
-2002-09-27 14:12 andy
-
- * Templates/: CCMakeSystemConfig.cmake.in, cconfigure,
- cconfigure.in: Cleanup configure scripts
-
-2002-09-26 15:13 martink
-
- * Source/: cmake.h, cmake.cxx, cmGlobalGenerator.cxx,
- cmGlobalGenerator.h: added progress
-
-2002-09-26 13:52 martink
-
- * Source/cmMakefile.cxx: minor memory fix
-
-2002-09-25 17:25 andy
-
- * Modules/: CheckFunctionExists.cmake, CheckIncludeFile.cmake,
- CheckLibraryExists.cmake: Set variable to either 1 or empty
- string instead of TRUE and FALSE
-
-2002-09-25 10:38 andy
-
- * Modules/CheckLibraryExists.cmake: Cleanup
-
-2002-09-25 10:08 andy
-
- * Tests/: LoadCommand/CMakeLists.txt,
- LoadCommand/LoadedCommand.h.in,
- LoadCommandOneConfig/CMakeLists.txt,
- LoadCommandOneConfig/LoadedCommand.h.in: Check for library
-
-2002-09-25 10:08 andy
-
- * Modules/: CheckFunctionExists.cmake, CheckLibraryExists.cmake,
- CheckSizeOf.cmake: Fix modules for recent changes
-
-2002-09-25 10:07 andy
-
- * Source/: cmGlobalUnixMakefileGenerator.cxx,
- cmTryCompileCommand.cxx: Several changes: COMPILE_DEFINITIONS is
- now depricated. If you want to specify some, use CMAKE_FLAGS
- -DCMAKE_DEFINITIONS:STRING=...; same goes for libraries, include
- path, ... It now detects wether the file is C or C++ and uses the
- apropriate project command, it also does the right thing when
- doing try_compile, so it does not execute configure for every
- single try_compile
-
-2002-09-25 09:31 andy
-
- * Source/cmLocalUnixMakefileGenerator.cxx: Use file format
- detection
-
-2002-09-25 09:30 andy
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: Add detection of
- file format from extension
-
-2002-09-25 07:46 andy
-
- * Source/cmGlobalGenerator.cxx: Attempt to make NMake quiet during
- TRY_COMPILE
-
-2002-09-24 18:34 andy
-
- * Source/: ctest.cxx, ctest.h: Add verbose flag -V, which makes the
- output of tests to be displayed; also add help to ctest
-
-2002-09-24 17:58 andy
-
- * Modules/CMakeBackwardCompatibilityC.cmake,
- Modules/CMakeBackwardCompatibilityCXX.cmake,
- Source/cmGlobalUnixMakefileGenerator.cxx: Improve backward
- compatibility, so that all backward compatibility stuff is in two
- modules; fix invoking of try_compile; add checking for header
- files and sizes of types
-
-2002-09-24 17:37 andy
-
- * Source/cmSystemTools.cxx: Add support for mac dylib
-
-2002-09-24 16:36 andy
-
- * Modules/: CheckLibraryExists.cmake, CheckLibraryExists.lists.in:
- Initial attempt to check if library exists
-
-2002-09-24 16:20 andy
-
- * Modules/CheckSizeOf.cmake: Improve check size of. Now it checks
- for some header files before trying to check types
-
-2002-09-24 14:49 king
-
- * Source/: cmEndIfCommand.cxx, cmIfCommand.cxx: [no log message]
-
-2002-09-24 14:22 king
-
- * Utilities/cmake_release_config_osf: ENH: Adding prototype release
- config script for OSF.
-
-2002-09-24 14:18 king
-
- * Utilities/cmake_release_config_cygwin: ERR: Removed old cygwin
- release config file. A separate script is now used.
-
-2002-09-24 13:24 martink
-
- * Source/cmake.cxx: fixed memory leak
-
-2002-09-24 13:17 martink
-
- * Source/cmTryRunCommand.cxx: always convert to output path
-
-2002-09-24 10:47 hoffman
-
- * Utilities/: cmake-cygwin-package.sh, cmake_release_cygwin.sh: use
- /usr/bin/find and uname for cygwin version
-
-2002-09-24 10:30 andy
-
- * Source/cmLoadCommandCommand.cxx: Cleanup
-
-2002-09-24 10:24 andy
-
- * Source/: cmDynamicLoader.cxx, cmDynamicLoader.h: Add accessor for
- Flushing cache
-
-2002-09-24 09:51 hoffman
-
- * Source/cmLocalUnixMakefileGenerator.cxx: one rule per line so
- borland make does not die
-
-2002-09-24 09:50 hoffman
-
- * Source/cmLocalBorlandMakefileGenerator.cxx: handle long commands
-
-2002-09-24 09:24 hoffman
-
- * Source/: cmDynamicLoader.cxx, cmGlobalGenerator.cxx: fix for
- cygwin and nmake that does not define WIN32
-
-2002-09-23 21:14 king
-
- * Utilities/: cmake-cygwin-package.sh, cmake-cygwin.README,
- cmake_release_cygwin.sh, setup.hint: ENH: Added cygwin packaging
- scripts. The setup.hint and cmake.README files required by
- Cygwin are generated automatically.
-
-2002-09-23 17:24 andy
-
- * Tests/: LoadCommand/CMakeCommands/CMakeLists.txt,
- LoadCommandOneConfig/CMakeCommands/CMakeLists.txt: Fix problem
-
-2002-09-23 17:20 king
-
- * Utilities/cmake_release_unix_package.sh: ENH: Added to generated
- README the typical install locaiton of /usr/local.
-
-2002-09-23 16:57 andy
-
- * Source/cmDynamicLoader.cxx: Fix cache for non void* types
-
-2002-09-23 16:24 andy
-
- * Source/cmDynamicLoader.cxx: Keep track of libraries so that you
- can load them as many times as you want...
-
-2002-09-23 15:57 andy
-
- * Source/cmaketest.cxx: Cleanup
-
-2002-09-23 15:56 andy
-
- * Tests/: LoadCommand/CMakeCommands/CMakeLists.txt,
- LoadCommand/CMakeCommands/cmTestCommand.c,
- LoadCommandOneConfig/CMakeCommands/CMakeLists.txt,
- LoadCommandOneConfig/CMakeCommands/cmTestCommand.c: Some minor
- fixes for mac
-
-2002-09-23 15:54 andy
-
- * Source/cmLocalUnixMakefileGenerator.cxx: Fix generation of C only
- modules
-
-2002-09-23 15:53 andy
-
- * Source/cmDynamicLoader.cxx: Fix extension and suffix for modules
- on mac
-
-2002-09-23 14:57 martink
-
- * Tests/: LoadCommand/CMakeCommands/cmTestCommand.c,
- LoadCommandOneConfig/CMakeCommands/cmTestCommand.c: cleanup
-
-2002-09-23 14:57 martink
-
- * Source/: cmCPluginAPI.h, cmLoadCommandCommand.cxx: cleaned up API
-
-2002-09-23 14:11 andy
-
- * Tests/: LoadCommand/CMakeCommands/CMakeLists.txt,
- LoadCommandOneConfig/CMakeCommands/CMakeLists.txt: Fix test so
- that it will work on HP
-
-2002-09-23 14:04 andy
-
- * Source/cmTryCompileCommand.cxx: Fix HP build
-
-2002-09-23 13:32 andy
-
- * Source/: cmSystemTools.cxx, cmTryCompileCommand.cxx: Try to
- remove some warnings
-
-2002-09-23 13:11 andy
-
- * Source/cmLoadCommandCommand.cxx: Fix loading of module for
- borland
-
-2002-09-23 12:23 andy
-
- * Source/cmGlobalGenerator.cxx: Try to fix borland and nmake try
- compile
-
-2002-09-23 11:06 andy
-
- * Source/: cmTryCompileCommand.cxx, cmTryCompileCommand.h,
- cmTryRunCommand.cxx: Abstract cleaning of files and add code that
- deletes files from Debug subdirectory
-
-2002-09-23 11:05 andy
-
- * Source/cmGlobalVisualStudio6Generator.cxx: Remove debug stuff
-
-2002-09-23 10:01 andy
-
- * Modules/FindwxWindows.cmake: Fix comments
-
-2002-09-23 09:58 andy
-
- * Source/cmLocalVisualStudio7Generator.cxx: Try to fix quoted
- definitions
-
-2002-09-23 09:41 martink
-
- * Source/cmIfCommand.cxx: hopefull another fix to if statements
-
-2002-09-23 09:07 andy
-
- * Source/: cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio6Generator.h: Attempt to fix Visual studio 6
- comiling
-
-2002-09-23 08:51 king
-
- * Utilities/cmake_release_unix_package.sh: BUG: Creating source
- tarball should not affect current directory.
-
-2002-09-23 08:44 king
-
- * Utilities/: cmake_release_config_darwin,
- cmake_release_config_hpux, cmake_release_config_irix,
- cmake_release_config_linux, cmake_release_config_sun: ENH:
- Incremented version to 1.4.5.
-
-2002-09-22 10:08 martink
-
- * Source/cmLocalVisualStudio7Generator.cxx: defines cannot have
- quotes in them
-
-2002-09-22 09:53 martink
-
- * Source/: cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h: some try compile fixes
-
-2002-09-22 07:52 martink
-
- * Source/: cmWriteFileCommand.cxx,
- CursesDialog/cmCursesMainForm.cxx: compiler warning
-
-2002-09-21 07:29 andy
-
- * Source/cmWriteFileCommand.cxx: Fix namespace problem
-
-2002-09-20 15:01 andy
-
- * Modules/: CheckFunctionExists.cmake, CheckIncludeFile.cmake,
- CheckSizeOf.cmake: Fix tests for new trycompile and tryrun
-
-2002-09-20 15:01 andy
-
- * Source/: cmMakefile.cxx, cmMakefile.h, cmTryCompileCommand.cxx,
- cmTryRunCommand.cxx: Add GetLocal on cmMakefile and on local
- builds do not perform tests
-
-2002-09-20 14:17 andy
-
- * Tests/: LoadCommand/CMakeLists.txt,
- LoadCommand/LoadedCommand.h.in,
- LoadCommandOneConfig/CMakeLists.txt,
- LoadCommandOneConfig/LoadedCommand.h.in: Include more testing
-
-2002-09-20 14:16 andy
-
- * Modules/: CheckIncludeFile.c.in, CheckIncludeFile.cmake: Simplify
- checking for headers
-
-2002-09-20 13:40 andy
-
- * Modules/: CheckIncludeFile.c.in, CheckIncludeFile.cmake: Add
- macro which checks if the header file exists
-
-2002-09-20 13:40 andy
-
- * Modules/CheckFunctionExists.cmake: Fix comment
-
-2002-09-20 13:17 andy
-
- * Tests/: LoadCommand/CMakeLists.txt,
- LoadCommand/LoadedCommand.cxx,
- LoadCommandOneConfig/CMakeLists.txt,
- LoadCommandOneConfig/LoadedCommand.cxx,
- LoadCommand/LoadedCommand.h.in,
- LoadCommandOneConfig/LoadedCommand.h.in: Fix test so that it does
- some modules testing by checking for some functions and some size
- of types
-
-2002-09-20 13:16 andy
-
- * Modules/: CheckFunctionExists.c, CheckFunctionExists.cmake,
- CheckSizeOf.c, CheckSizeOf.cmake: Add two commonly used modules.
- First one checks if the function exists, the second one checks
- the size of type
-
-2002-09-20 13:15 andy
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmMakefile.cxx, cmMakefile.h, cmTryCompileCommand.cxx: Add option
- of TRY_COMPILE to store the output of compilation so that if the
- output fails you can display it or store it in the file
-
-2002-09-20 13:14 andy
-
- * Source/: cmCommands.cxx, cmWriteFileCommand.cxx,
- cmWriteFileCommand.h: Add WRITE_FILE command, which writes string
- to a file
-
-2002-09-20 10:06 martink
-
- * Tests/: LoadCommand/CMakeCommands/cmTestCommand.c,
- LoadCommandOneConfig/CMakeCommands/cmTestCommand.c: removed c++
- style comments
-
-2002-09-20 08:07 martink
-
- * Source/: cmTryRunCommand.h, cmTryRunCommand.cxx: compiler
- warnings
-
-2002-09-19 16:12 hoffman
-
- * Source/cmBorlandMakefileGenerator.cxx: ENH: allow for long
- command lines
-
-2002-09-19 16:09 andy
-
- * Source/cmMakefile.cxx: Remove unnecessary disabling of output
-
-2002-09-19 16:07 andy
-
- * Source/cmTryRunCommand.cxx: Fix tryrun to work on Linux
-
-2002-09-19 15:01 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: ENH: use single line depend
- rules for borland compiler
-
-2002-09-19 14:59 hoffman
-
- * Source/cmMSDotNETGenerator.cxx: ENH: add include to rc, and
- newline to custom commnad
-
-2002-09-19 14:59 hoffman
-
- * Source/: cmBorlandMakefileGenerator.cxx,
- cmNMakeMakefileGenerator.cxx: ENH: add include to rc
-
-2002-09-19 14:58 hoffman
-
- * Source/CMakeLists.txt: ENH: fix bad endif
-
-2002-09-19 14:58 hoffman
-
- * Templates/: DLLHeader.dsptemplate, EXEHeader.dsptemplate,
- staticLibHeader.dsptemplate: ENH: add include paths to rc
-
-2002-09-19 14:40 andy
-
- * Source/cmSystemTools.cxx: Supress standard error when running
- command
-
-2002-09-19 14:36 andy
-
- * Source/cmTryCompileCommand.cxx: Fix try compile with second
- signature, remove cmake lists from cache so that multiple tests
- work
-
-2002-09-19 14:35 andy
-
- * Source/cmSystemTools.h: Add a way to check if run command output
- is disabled
-
-2002-09-19 14:35 andy
-
- * Source/cmMakefile.cxx: When doing try compile disable output
-
-2002-09-19 14:34 andy
-
- * Source/: cmListFileCache.cxx, cmListFileCache.h: Add a way to
- remove files from cache
-
-2002-09-19 11:06 andy
-
- * Source/cmTryRunCommand.cxx: Fix compile problem
-
-2002-09-19 11:01 martink
-
- * Source/cmTryRunCommand.cxx: minor cleanup
-
-2002-09-19 10:25 andy
-
- * Modules/FindwxWindows.cmake: Fix find wxWindows
-
-2002-09-19 09:49 martink
-
- * Source/: cmCommands.cxx, cmTryCompileCommand.cxx,
- cmTryCompileCommand.h: updated to try compile
-
-2002-09-19 09:48 martink
-
- * Source/: cmTryRunCommand.cxx, cmTryRunCommand.h: new command
-
-2002-09-19 09:47 andy
-
- * Source/CMakeLists.txt: Add option for building wxWindows GUI for
- CMake
-
-2002-09-19 09:42 andy
-
- * Modules/FindwxWindows.cmake: Improve searching for wxWindows
-
-2002-09-18 14:18 andy
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h,
- CursesDialog/ccmake.cxx: Improve message handler to include
- client data.
-
-2002-09-18 11:38 martink
-
- * Tests/: LoadCommand/CMakeLists.txt,
- LoadCommand/CMakeCommands/CMakeLists.txt,
- LoadCommand/CMakeCommands/cmTestCommand.c,
- LoadCommandOneConfig/CMakeLists.txt,
- LoadCommandOneConfig/CMakeCommands/CMakeLists.txt,
- LoadCommandOneConfig/CMakeCommands/cmTestCommand.c: test passing
- CMAKE_FLAGS
-
-2002-09-18 11:37 martink
-
- * Source/: cmMakefile.cxx, cmMakefile.h, cmTryCompileCommand.cxx,
- cmTryCompileCommand.h: now Try compile can include CMAKE_FLAGS
-
-2002-09-18 11:36 martink
-
- * Source/cmLoadCommandCommand.cxx: better error reporting
-
-2002-09-18 10:40 king
-
- * Source/cmSetCommand.cxx: ENH: If SET(VAR) is called with no other
- arguments, remove the definition of VAR.
-
-2002-09-18 10:39 king
-
- * Source/: cmMakefile.cxx, cmMakefile.h: ENH: Added
- RemoveDefinition method.
-
-2002-09-18 09:53 barre
-
- * Source/cmVTKWrapTclCommand.cxx: FIX: better support for the
- Tcl/Tk 8.4 pre-release
-
-2002-09-18 08:15 andy
-
- * Modules/FindGTK.cmake: GL should not be a completely necessary
- thing for finding GTK. This will find gtk and GL but also just
- GTK
-
-2002-09-18 08:13 andy
-
- * Source/cmakewizard.cxx: Remove unnecessary variable
-
-2002-09-18 08:07 martink
-
- * Tests/: LoadCommand/CMakeLists.txt,
- LoadCommandOneConfig/CMakeLists.txt: removed target
-
-2002-09-17 15:41 king
-
- * Modules/CMakeLists.txt: ENH: Adding installation of TRY_COMPILE
- tests.
-
-2002-09-17 15:41 king
-
- * Source/cmTryCompileCommand.cxx: BUG: Generated CMakeLists.txt
- file needs to take CMAKE_ANSI_CXXFLAGS into account.
-
-2002-09-17 14:40 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: ERR: Fixed typo:
- INSTALL_PROGRAMS -> INSTALL_PROGRAM.
-
-2002-09-17 14:20 martink
-
- * Source/CursesDialog/cmCursesMainForm.cxx: some cmake api changees
-
-2002-09-17 14:19 andy
-
- * Source/cmakewizard.cxx: Strip the string that user answers
-
-2002-09-17 14:18 barre
-
- * Source/cmVTKWrapTclCommand.cxx: ENH: add support for Tcl/Tk 8.4.0
-
-2002-09-17 14:12 martink
-
- * Source/cmake.h: updated comments
-
-2002-09-17 14:09 king
-
- * Source/cmLocalUnixMakefileGenerator.cxx: BUG: INSTALL_DATA should
- be INSTALL_PROGRAMS for program install targets.
-
-2002-09-17 14:04 martink
-
- * Source/CursesDialog/cmCursesMainForm.cxx: some cmake api changees
-
-2002-09-17 13:59 martink
-
- * Source/: cmMakefile.cxx, cmake.cxx, cmake.h, cmakewizard.cxx:
- cleaned up some of the cmake interface
-
-2002-09-17 13:59 martink
-
- * Source/CMakeLists.txt: new test
-
-2002-09-17 13:48 andy
-
- * Source/cmakewizard.cxx: Replace getline with fgets since getline
- does not seems to work properly on Mac OSX
-
-2002-09-17 11:48 andy
-
- * Source/: cmCacheManager.cxx, cmCacheManager.h,
- cmMarkAsAdvancedCommand.cxx: Fix problems with advanced not being
- marked.
-
-2002-09-17 10:56 king
-
- * Source/: cmInstallFilesCommand.cxx, cmInstallFilesCommand.h,
- cmInstallProgramsCommand.cxx, cmInstallProgramsCommand.h,
- cmLocalUnixMakefileGenerator.cxx: ENH: Improved implementation of
- INSTALL_FILES and INSTALL_PROGRAMS commands. Source paths can
- now be relative or full paths, and don't need to be in the same
- directory as the CMakeLists.txt file.
-
-2002-09-17 10:38 martink
-
- * Tests/: LoadCommand/CMakeCommands/cmTestCommand.c,
- LoadCommandOneConfig/CMakeCommands/cmTestCommand.c: added
- Destructor
-
-2002-09-17 10:38 martink
-
- * Source/: cmCPluginAPI.h, cmLoadCommandCommand.cxx: added
- destructor to loaded commands
-
-2002-09-17 09:17 martink
-
- * Modules/TestForANSIStreamHeaders.cmake: slight change in
- signature for TryCompile
-
-2002-09-17 09:16 martink
-
- * Source/: cmGlobalVisualStudio6Generator.cxx,
- cmTryCompileCommand.cxx, cmTryCompileCommand.h: slight change in
- signature
-
-2002-09-17 09:16 martink
-
- * Tests/: LoadCommand/CMakeLists.txt,
- LoadCommandOneConfig/CMakeLists.txt: some cleanup
-
-2002-09-17 08:29 martink
-
- * Tests/: LoadCommand/CMakeLists.txt,
- LoadCommandOneConfig/CMakeLists.txt: minor fix in error message
-
-2002-09-16 16:27 martink
-
- * Tests/: LoadCommand/CMakeLists.txt,
- LoadCommand/LoadedCommand.cxx,
- LoadCommand/CMakeCommands/CMakeLists.txt,
- LoadCommand/CMakeCommands/cmTestCommand.c,
- LoadCommandOneConfig/CMakeLists.txt,
- LoadCommandOneConfig/LoadedCommand.cxx,
- LoadCommandOneConfig/CMakeCommands/CMakeLists.txt,
- LoadCommandOneConfig/CMakeCommands/cmTestCommand.c: load command
- test
-
-2002-09-15 09:54 martink
-
- * Source/: cmAddCustomCommandCommand.cxx,
- cmAddDependenciesCommand.cxx, cmCacheManager.cxx,
- cmExecProgramCommand.cxx, cmFLTKWrapUICommand.cxx,
- cmListFileCache.cxx, cmaketest.cxx, ctest.cxx: remove unused
- variables
-
-2002-09-15 09:42 martink
-
- * Source/: cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx: updated to use
- ConfigureFinalPass
-
-2002-09-15 08:53 martink
-
- * Source/: cmLocalGenerator.cxx, cmLocalGenerator.h,
- cmGlobalGenerator.cxx: changed handling of FinalPass
-
-2002-09-15 08:53 martink
-
- * Source/cmLocalUnixMakefileGenerator.cxx: changed when final pass
- is done
-
-2002-09-15 08:52 martink
-
- * Source/: cmMakefile.h, cmMakefile.cxx: renamed GenerateMakefile
- to ConfigureFinalPass
-
-2002-09-14 10:59 martink
-
- * Source/CursesDialog/cmCursesMainForm.cxx: removed extra Generate
- that was screwing things up
-
-2002-09-14 08:47 martink
-
- * Source/cmGlobalGenerator.cxx: fixed warning
-
-2002-09-13 19:23 martink
-
- * Source/cmGlobalGenerator.cxx: made less verbose
-
-2002-09-13 19:23 martink
-
- * Modules/TestForANSIStreamHeaders.cmake: removed messages
-
-2002-09-13 16:38 king
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Added
- FileIsFullPath test method.
-
-2002-09-13 13:48 martink
-
- * Source/: cmGlobalGenerator.cxx, cmMakefile.cxx, cmake.h: some
- fixes for try compile
-
-2002-09-13 11:09 martink
-
- * Templates/: CXXCMakeSystemConfig.cmake.in, cxxconfigure,
- cxxconfigure.in: now uses TryCompile
-
-2002-09-13 11:05 martink
-
- * Source/cmGlobalNMakeMakefileGenerator.h: minor fix
- inEnableLanguages
-
-2002-09-13 11:01 martink
-
- * Source/: cmTryCompileCommand.cxx: fix to the cleanup code
-
-2002-09-13 10:42 martink
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalNMakeMakefileGenerator.h,
- cmGlobalUnixMakefileGenerator.cxx,
- cmGlobalUnixMakefileGenerator.h,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx, cmMakefile.cxx,
- cmTryCompileCommand.cxx: better trycompile and enable langiages
-
-2002-09-13 10:41 martink
-
- * Source/cmake.cxx: better try compile
-
-2002-09-13 10:40 martink
-
- * Modules/TestForANSIStreamHeaders.cmake: removed messages
-
-2002-09-13 09:51 andy
-
- * configure, configure.in: Improve bootstrapping on Unix, so that
- it bootstraps in the subdirectory. This prevents from compiler
- files being reused and you can do make clean...
-
-2002-09-13 09:49 iscott
-
- * Modules/FindQt.cmake: Make QT variables advanced
-
-2002-09-13 08:15 martink
-
- * Source/: cmEndIfCommand.cxx, cmLocalUnixMakefileGenerator.cxx:
- compiler warning
-
-2002-09-13 05:39 iscott
-
- * Modules/FindQt.cmake: Need to use $ENV{} to access environment
- variables
-
-2002-09-12 16:36 martink
-
- * Modules/TestForANSIStreamHeaders.cmake: some cleanup
-
-2002-09-12 14:37 martink
-
- * Source/cmake.cxx: uninitialized var
-
-2002-09-12 13:55 andy
-
- * Source/cmaketest.cxx: Remove unnecessary include
-
-2002-09-12 13:42 andy
-
- * Source/cmakemain.cxx: Remove unnecessary include
-
-2002-09-12 13:19 bettingf
-
- * Tests/Wrapping/CMakeLists.txt, Source/CMakeLists.txt: added
- include of FindQT.cmake
-
-2002-09-12 11:47 martink
-
- * Source/: cmMakefileGenerator.cxx, cmMakefileGenerator.h,
- CMakeLists.txt: new arch
-
-2002-09-12 11:44 martink
-
- * Source/: cmMSDotNETGenerator.cxx, cmMSDotNETGenerator.h,
- cmMSProjectGenerator.cxx, cmMSProjectGenerator.h,
- cmDSWWriter.cxx, cmDSWWriter.h, cmDSPWriter.cxx, cmDSPWriter.h,
- cmNMakeMakefileGenerator.cxx, cmNMakeMakefileGenerator.h,
- cmBorlandMakefileGenerator.cxx, cmBorlandMakefileGenerator.h,
- cmUnixMakefileGenerator.cxx, cmUnixMakefileGenerator.h: new arch
-
-2002-09-12 11:38 bettingf
-
- * Source/CMakeLists.txt: added test for QTWrapUI called qtwrapping
-
-2002-09-12 11:37 bettingf
-
- * Tests/Wrapping/: qtwrappingmain.cxx, CMakeLists.txt: corrected
- test for QTWrapUI
-
-2002-09-12 11:14 martink
-
- * Modules/: TestForANSIStreamHeaders.cmake,
- TestForANSIStreamHeaders.cxx: new try compile module
-
-2002-09-12 11:13 andy
-
- * Source/cmCacheManager.cxx: Oops, too fast commit; add missing ;
-
-2002-09-12 11:12 andy
-
- * Source/cmCacheManager.cxx: Add more error checking
-
-2002-09-12 11:08 martink
-
- * Source/: cmTryCompileCommand.cxx, cmTryCompileCommand.h: another
- signature for Try_Compile
-
-2002-09-12 11:08 martink
-
- * Source/: cmMakefile.cxx, cmake.cxx, cmake.h: added a flag if a
- cmake is in try compile
-
-2002-09-12 09:56 andy
-
- * Source/cmMarkAsAdvancedCommand.cxx: Fix mark as advanced. Now it
- should work properly
-
-2002-09-12 09:00 andy
-
- * Source/: cmakewizard.cxx, cmakewizard.h: Simplify code. Since we
- access cache entry through the iterator, we do not need the cache
- manager any more
-
-2002-09-12 08:56 andy
-
- * Source/cmCacheManager.h: Fix build problem on Sun
-
-2002-09-11 16:44 bettingf
-
- * Source/cmQTWrapUICommand.cxx: corrected the generated lists .h in
- header list and .cxx in sources list
-
-2002-09-11 16:43 bettingf
-
- * Source/cmLocalUnixMakefileGenerator.cxx: added generation of the
- GENERATED_QT_FILES list for make clean
-
-2002-09-11 16:41 bettingf
-
- * Tests/Wrapping/CMakeLists.txt: added test for QTWrapUI
-
-2002-09-11 16:40 bettingf
-
- * Tests/Wrapping/: qtwrappingmain.cxx, qtwrapping.ui: test for
- QTWarpUI
-
-2002-09-11 16:12 king
-
- * Source/cmCacheManager.cxx: BUG: GetCacheValue must check if value
- is UNINITIALIZED. If so, pretend it doesn't exist.
-
-2002-09-11 15:13 andy
-
- * Source/CursesDialog/cmCursesMainForm.cxx: Fix bug in ccmake which
- made it crash when all cache values were deleted
-
-2002-09-11 15:04 andy
-
- * Source/CursesDialog/cmCursesMainForm.cxx: Fix problem with ccmake
- crashing on empty caches
-
-2002-09-11 14:38 andy
-
- * Source/cmCacheManager.cxx: Fix find and remove check for
- uninitialized entries
-
-2002-09-11 14:08 andy
-
- * Source/cmCacheManager.cxx: Function strcasecmp is not portable
-
-2002-09-11 14:05 andy
-
- * Source/: cmCacheManager.cxx, cmCacheManager.h,
- cmFindPathCommand.cxx, cmFindProgramCommand.cxx, cmMakefile.cxx,
- cmMarkAsAdvancedCommand.cxx, cmVariableRequiresCommand.cxx,
- cmakewizard.cxx, cmakewizard.h,
- CursesDialog/cmCursesCacheEntryComposite.cxx,
- CursesDialog/cmCursesCacheEntryComposite.h,
- CursesDialog/cmCursesMainForm.cxx: Couple of changes: cache
- variables now have a map of properties. ADVANCED and HELPSTRING
- are now properties of cache variable, IsAdvanced is gone, so is
- GetCacheEntry, since cache entries are now all private. To access
- them, you use the iterator. -ADVANCED cache entries are gone and
- are replaced by the property of cache variables. The cache file
- still looks the same, but the -ADVANCED cache entries are created
- when writing file. MarkAsAdvanced and VariableRequires are fixed.
- So are curses gui and wizard
-
-2002-09-11 13:27 andy
-
- * Templates/CCMakeSystemConfig.cmake.in: Remove Mark_AS_ADVANCED
- for some variables that do not exist
-
-2002-09-11 12:52 martink
-
- * Source/cmMakefile.cxx: minor fix in try compile code
-
-2002-09-11 09:54 king
-
- * Source/: CMakeLists.txt, cmDynamicLoader.cxx, cmDynamicLoader.h,
- cmDynamicLoaderC.c: ENH: Pointer-to-function to pointer-to-data
- casts are not even allowed in strict C. Re-implemented this
- conversion in pure C++ using a casting trick with an extra level
- of indirection.
-
-2002-09-11 08:52 king
-
- * Source/cmDynamicLoaderC.c: ERR: Removed C++-style comments, used
- C-style instead.
-
-2002-09-10 17:24 king
-
- * Source/cmake.cxx: ERR: Added missing include of stdio.h for
- sprintf.
-
-2002-09-10 16:52 martink
-
- * Source/: cmTryCompileCommand.cxx, cmTryCompileCommand.h: updated
- signature
-
-2002-09-10 16:52 martink
-
- * Source/: cmMakefile.cxx, cmMakefile.h: updated makefile moved
- commands into cmake and fixed try compile
-
-2002-09-10 16:51 martink
-
- * Source/cmDumpDocumentation.cxx: moved dump docs into cmake
-
-2002-09-10 16:51 martink
-
- * Source/: cmake.h, cmake.cxx: moved commands into cmake
-
-2002-09-10 16:49 martink
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio6Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h: modified TryCompile
-
-2002-09-10 15:46 king
-
- * Source/: CMakeLists.txt, cmDynamicLoader.cxx, cmDynamicLoader.h,
- cmDynamicLoaderC.c: ERR: Cast from pointer-to-data to
- pointer-to-function is not allowed in C++. The cast needed by
- cmDynamicLoader::GetSymbolAddress is now hidden in a C file.
-
-2002-09-10 15:40 king
-
- * Source/cmGlobalUnixMakefileGenerator.cxx: ERR: Fixes for comeau
- compiler. NULL is a pointer of type void*, and cannot be
- compared directly with other pointer types. We use 0 instead.
- Also changed putenv to setenv for comeau on linux.
-
-2002-09-10 15:40 king
-
- * Source/cmStandardIncludes.h: ENH: Added definition of _BSD_SOURCE
- to enable proper use of POSIX functions on comeau in linux.
-
-2002-09-10 15:38 king
-
- * Source/cmSystemTools.cxx: ERR: Fix for borland on linux. We
- cannot directly compare the st_dev and st_ino members of struct
- stat. Use memcmp instead.
-
-2002-09-10 15:37 king
-
- * Source/cmLocalGenerator.cxx: ERR: Removed stray semi-colon.
-
-2002-09-10 15:36 king
-
- * Source/: cmMakefile.cxx, cmRegularExpression.cxx,
- cmRegularExpression.h, cmMakeDepend.cxx,
- cmLoadCommandCommand.cxx, cmCPluginAPI.cxx: ERR: Fixes for comeau
- compiler. NULL is a pointer of type void*, and cannot be
- compared directly with other pointer types. We use 0 instead.
-
-2002-09-10 15:36 king
-
- * Source/cmake.cxx: ERR: Fix for borland on linux.
-
-2002-09-10 13:32 barre
-
- * Modules/FindOpenGL.cmake: FIX: typo + bring back the
- OPENGL_gl_LIBRARY path that can be used to find GLU (was wiped
- out from FindGLU)
-
-2002-09-10 12:49 martink
-
- * Source/CMakeLists.txt: removed extra ENDIF
-
-2002-09-10 10:35 king
-
- * configure, configure.in: ERR: Went back to old-style test for
- -LANG:std on the SGI.
-
-2002-09-10 10:16 martink
-
- * Source/: cmEndIfCommand.cxx, cmIfCommand.cxx: better error
- checking on If statements
-
-2002-09-10 10:02 king
-
- * configure, configure.in: ERR: AC_SUBST replaced with AC_DEFINE.
- Needed to get configure script to correctly setup cmConfigure.h.
-
-2002-09-10 09:51 king
-
- * Source/cmCommands.cxx: ERR: Removed accidental commit.
-
-2002-09-10 09:50 king
-
- * configure, configure.in, Source/cmCommands.cxx: BUG: Missing
- AC_SUBST commands added.
-
-2002-09-09 09:50 hoffman
-
- * Modules/FindOpenGL.cmake: Adding GLU to the OPENGL_LIBRARIES only
- if it is found.
-
-2002-09-08 10:15 martink
-
- * Source/: cmGlobalNMakeMakefileGenerator.cxx,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio7Generator.cxx, cmake.cxx: compiler warnings
-
-2002-09-07 21:25 martink
-
- * Source/: cmGlobalGenerator.cxx,
- cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio7Generator.cxx: compiler warnings
-
-2002-09-07 21:22 martink
-
- * Source/cmLocalGenerator.h: compiler warning
-
-2002-09-07 21:18 martink
-
- * Source/: cmGlobalBorlandMakefileGenerator.cxx,
- cmLocalBorlandMakefileGenerator.cxx: fix for borland compilers
-
-2002-09-06 18:05 king
-
- * Source/cmVTKWrapTclCommand.cxx: ERR: Fix for borland in generated
- code. vtkCommand is ambiguously both a function and a class.
-
-2002-09-06 17:19 king
-
- * configure, configure.in, Templates/cconfigure,
- Templates/cconfigure.in, Templates/cxxconfigure,
- Templates/cxxconfigure.in: ENH: Improved configure test
- implementations by using AC_TRY_COMPILE.
-
-2002-09-06 16:30 martink
-
- * Source/cmLocalUnixMakefileGenerator.cxx: updated to fix the long
- depend line issue on Borland
-
-2002-09-06 14:03 starreveld
-
- * Modules/FindOpenGL.cmake:
- ERR: Fix opengl finding on osx
-
-2002-09-06 13:56 barre
-
- * Modules/FindTCL.cmake: ENH: make stub stuff ADVANCED
-
-2002-09-06 13:04 martink
-
- * Source/: cmakewizard.cxx, CMakeLists.txt, Makefile.in,
- cmGlobalGenerator.cxx, cmGlobalUnixMakefileGenerator.cxx,
- cmLocalUnixMakefileGenerator.cxx: new arch
-
-2002-09-06 13:01 martink
-
- * Source/: cmaketest.cxx, cmake.cxx, cmake.h, cmMakefile.cxx,
- cmMakefile.h, cmakemain.cxx: new arch
-
-2002-09-06 13:00 martink
-
- * Source/CursesDialog/: ccmake.cxx, cmCursesLongMessageForm.cxx,
- cmCursesMainForm.cxx, cmCursesMainForm.h: new architecture
-
-2002-09-06 11:47 hoffman
-
- * Templates/CMakeBorlandWindowsSystemConfig.cmake: fix comment
-
-2002-09-06 11:00 iscott
-
- * Modules/readme.txt: Add important missing word to documentation
-
-2002-09-06 10:55 iscott
-
- * Modules/readme.txt: More detailed information about consistent
- FindXXX.cmake files
-
-2002-09-06 10:47 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: ENH: use :: rule and not a
- long line extension
-
-2002-09-06 09:24 martink
-
- * Source/cmLocalUnixMakefileGenerator.cxx: minor fix
-
-2002-09-06 08:33 martink
-
- * Source/cmLocalUnixMakefileGenerator.cxx: minor fixes
-
-2002-09-05 12:00 iscott
-
- * Modules/: FindFLTK.cmake, FindGLUT.cmake, FindGTK.cmake,
- FindOpenGL.cmake, FindX11.cmake: Hide lots of values in the
- advanced list Fix some bugs OpenGL always needs X11 on Unix
-
-2002-09-05 09:04 martink
-
- * Source/cmLocalGenerator.h: made destructor virtual
-
-2002-09-05 08:22 martink
-
- * Source/cmDynamicLoader.cxx: removed some couts
-
-2002-09-04 15:46 martink
-
- * Source/cmCacheManager.h: made method public
-
-2002-09-04 15:28 martink
-
- * Source/cmLocalUnixMakefileGenerator.cxx: fixes
-
-2002-09-04 15:24 martink
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmGlobalNMakeMakefileGenerator.cxx, cmLocalGenerator.cxx,
- cmLocalGenerator.h: updates
-
-2002-09-04 15:22 martink
-
- * Source/: cmGlobalVisualStudio6Generator.cxx,
- cmGlobalVisualStudio6Generator.h,
- cmLocalVisualStudio6Generator.cxx,
- cmLocalVisualStudio6Generator.h,
- cmGlobalVisualStudio7Generator.cxx,
- cmGlobalVisualStudio7Generator.h,
- cmLocalVisualStudio7Generator.cxx,
- cmLocalVisualStudio7Generator.h: new arch
-
-2002-09-04 15:22 martink
-
- * Source/: cmGlobalBorlandMakefileGenerator.cxx,
- cmGlobalBorlandMakefileGenerator.h,
- cmLocalBorlandMakefileGenerator.cxx,
- cmLocalBorlandMakefileGenerator.h: first cut a new arch
-
-2002-09-04 11:17 martink
-
- * Tests/Wrapping/CMakeLists.txt: fixed test for new cmake
-
-2002-09-04 09:24 king
-
- * Modules/FindOpenGL.cmake: ERR: Still need to define
- OPENGL_INCLUDE_PATH in addition to the standard
- OPENGL_INCLUDE_DIR for backward compatability.
-
-2002-09-03 12:29 iscott
-
- * Modules/FindMFC.cmake: A simple FindMFC module for consistency
-
-2002-09-03 10:41 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: use windows paths for
- utility depends
-
-2002-09-03 10:41 hoffman
-
- * Source/cmMSDotNETGenerator.cxx: BUG: bug for more than one custom
- commands
-
-2002-09-03 09:14 iscott
-
- * Modules/Dart.cmake: Dart now has a configure option
-
-2002-09-03 09:00 iscott
-
- * Modules/FindPNG.cmake: I copied a bit too much VXL functionality
- here. Oops
-
-2002-09-03 08:33 iscott
-
- * Modules/FindPerl.cmake: Added PERL_FOUND
-
-2002-09-03 08:24 iscott
-
- * Modules/FindMPEG.cmake: Add an MPEG finder in the new format -
- functionality copied from VXL.
-
-2002-09-03 06:10 iscott
-
- * Modules/: FindAVIFile.cmake, FindGLU.cmake, FindGLUT.cmake,
- FindJPEG.cmake, FindOpenGL.cmake, FindPNG.cmake, FindTIFF.cmake,
- FindX11.cmake: Fixed mistake in comments Transferred OPENGL
- finding logic in from VXL Added Some backwards compatibility with
- CMake1.4
-
-2002-09-02 17:34 iscott
-
- * Modules/: FindFLTK.cmake, FindGTK.cmake: Moved FLTK and GTK to
- new FindXXX scheme. Imported some functionality from VXL
-
-2002-09-02 17:33 iscott
-
- * Modules/FindX11.cmake: small bug fixes
-
-2002-09-02 17:29 iscott
-
- * Source/cmFLTKWrapUICommand.cxx: FLTK_FLUID_EXE ->
- FLTK_FLUID_EXECUTABLE because Module files are moving to
- consistent scheme
-
-2002-09-02 16:59 iscott
-
- * Modules/: FindQt.cmake, FindTIFF.cmake: Fix Bugs
-
-2002-09-02 16:24 iscott
-
- * Modules/FindZLIB.cmake: This file should not be empty
-
-2002-09-02 15:49 iscott
-
- * Modules/: FindZLIB.cmake, FindZLib.cmake: Moved FindZLib.cmake to
- FindZLIB.cmake
-
-2002-09-02 15:46 iscott
-
- * Modules/: FindPNG.cmake, FindX11.cmake, FindZLib.cmake: Copied
- the X11 PNG and ZLIB functoinality from VXL
-
-2002-09-02 14:08 iscott
-
- * Modules/: FindPNG.cmake, FindZLib.cmake: Adding Zlib and PNG find
- modules in the new format
-
-2002-09-02 12:58 iscott
-
- * Modules/FindTIFF.cmake: This Find Module is in the new style
-
-2002-09-02 12:05 iscott
-
- * Modules/: FindJPEG.cmake, FindQt.cmake, FindWget.cmake,
- FindZLib.cmake: Add helpful message for QT Windows users Add
- FindZLib in new format Move FindJPEG and FINDWGET over to new
- scheme
-
-2002-09-02 07:03 iscott
-
- * Modules/FindAVIFile.cmake, Modules/FindQt.cmake,
- Modules/LinkQT.cmake, Modules/readme.txt,
- Source/cmQTWrapCPPCommand.cxx, Source/cmQTWrapUICommand.cxx:
- Define a single expected format for the values defined in every
- FindXXX.cmake file. Upgrade all the QT functionality to use the
- new FindXXX.cmake format Add a module for AVIFile.
-
-2002-08-30 16:01 martink
-
- * Source/: cmGlobalUnixMakefileGenerator.cxx,
- cmGlobalUnixMakefileGenerator.h,
- cmLocalUnixMakefileGenerator.cxx, cmLocalUnixMakefileGenerator.h,
- cmGlobalNMakeMakefileGenerator.cxx,
- cmGlobalNMakeMakefileGenerator.h,
- cmLocalNMakeMakefileGenerator.cxx,
- cmLocalNMakeMakefileGenerator.h: in progress
-
-2002-08-30 16:00 martink
-
- * Source/: cmGlobalGenerator.cxx, cmGlobalGenerator.h,
- cmLocalGenerator.cxx, cmLocalGenerator.h: in progress checkin
-
-2002-08-30 09:54 hoffman
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt: add rpcrt4.lib
- because of CMakeLib needing it
-
-2002-08-29 09:45 martink
-
- * Source/cmCPluginAPI.cxx: extern C fixes
-
-2002-08-28 16:35 martink
-
- * Source/CursesDialog/: ccmake.cxx, cmCursesMainForm.cxx,
- cmCursesMainForm.h: some changes in cachemanager and singletons
-
-2002-08-28 16:34 martink
-
- * Source/cmaketest.cxx: no more singletons
-
-2002-08-28 16:33 martink
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt: now needs dynlib
- support
-
-2002-08-28 15:08 king
-
- * Utilities/: cmake_release_config_cygwin,
- cmake_release_unix_build.sh, cmake_release_unix_config.sh,
- cmake_release_unix_package.sh: ENH: Moved build of source tarball
- to package script.
-
-2002-08-28 14:51 martink
-
- * Source/: cmCPluginAPI.cxx, cmCacheManager.cxx, cmCacheManager.h,
- cmCommands.cxx, cmFindPathCommand.cxx, cmFindProgramCommand.cxx,
- cmLoadCacheCommand.cxx, cmLoadCommandCommand.cxx,
- cmMSDotNETGenerator.cxx, cmMSDotNETGenerator.h,
- cmMSProjectGenerator.cxx, cmMSProjectGenerator.h, cmMakefile.cxx,
- cmMakefile.h, cmMakefileGenerator.cxx, cmMakefileGenerator.h,
- cmNMakeMakefileGenerator.cxx, cmNMakeMakefileGenerator.h,
- cmUnixMakefileGenerator.cxx, cmUnixMakefileGenerator.h,
- cmVariableRequiresCommand.cxx, cmake.cxx, cmake.h, cmakemain.cxx,
- cmakewizard.cxx, cmakewizard.h: changed cache manager and
- registered generators to no longer be singletons
-
-2002-08-28 14:49 martink
-
- * Source/: cmTryCompileCommand.cxx, cmTryCompileCommand.h: an early
- checking not complete
-
-2002-08-28 14:33 hoffman
-
- * Source/cmBorlandMakefileGenerator.cxx,
- Source/cmMSDotNETGenerator.cxx,
- Source/cmNMakeMakefileGenerator.cxx,
- Templates/DLLHeader.dsptemplate, Templates/EXEHeader.dsptemplate,
- Templates/EXEWinHeader.dsptemplate,
- Templates/staticLibHeader.dsptemplate: ENH: add include paths to
- rc program for resource generation
-
-2002-08-28 10:43 king
-
- * Utilities/setup.hint: ENH: Incremented version number for 1.4-4
-
-2002-08-28 10:40 king
-
- * Utilities/: cmake-cygwin.README, setup.hint: ENH: Adding cygwin
- installation files to branch.
-
-2002-08-28 10:28 hoffman
-
- * Utilities/: cmake-cygwin.README, cmake_release_config_cygwin,
- setup.hint: [no log message]
-
-2002-08-28 09:30 king
-
- * Utilities/cmake_release_config_darwin: Switched to release branch
- tag instead of sticky tag.
-
-2002-08-28 09:27 king
-
- * Utilities/cmake_release_config_darwin: ENH: Adding release
- configuration for darwin.
-
-2002-08-28 09:07 king
-
- * Utilities/cmake_release_unix_package.sh: BUG: Don't erase tarball
- directory in packaging step in case there is a source tarball
- there.
-
-2002-08-28 09:04 hoffman
-
- * Utilities/: cmake_release_unix_config.sh,
- cmake_release_unix_package.sh: cygwin release
-
-2002-08-28 08:51 king
-
- * Utilities/: cmake_release_config_hpux, cmake_release_config_irix,
- cmake_release_config_linux, cmake_release_config_sun: ENH:
- Updated release script configuration for CMake release 1.4.4.
-
-2002-08-27 14:45 andy
-
- * Source/cmSourceFile.cxx: Fix bug in trying to set stding with
- null
-
-2002-08-27 09:43 hoffman
-
- * Source/: CMakeLists.txt, cmLoadCommandCommand.cxx: ENH: fix
- warnings
-
-2002-08-27 08:36 martink
-
- * Source/: CMakeLists.txt, cmCommands.cxx: fixed bootstrap build to
- not use LoadCOmmandCOmmand
-
-2002-08-26 15:22 martink
-
- * Source/: cmGetSourceFilePropertyCommand.cxx,
- cmGetSourceFilePropertyCommand.h: updated to match the SET
-
-2002-08-26 15:20 martink
-
- * Tests/: Complex/CMakeLists.txt, ComplexOneConfig/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt: added new form of Set source
- file properties command
-
-2002-08-26 10:52 martink
-
- * Source/: cmCPluginAPI.cxx, cmCPluginAPI.h, cmCommands.cxx,
- cmLoadCommandCommand.cxx: now uses stubs
-
-2002-08-26 08:53 martink
-
- * Source/cmSetSourceFilesPropertiesCommand.cxx: fixed bug maybe
-
-2002-08-23 17:00 hoffman
-
- * Templates/cxxconfigure, Templates/cxxconfigure.in, configure,
- configure.in: try another flag for the dec compiler...
-
-2002-08-23 16:25 hoffman
-
- * Tests/: Complex/CMakeLists.txt, ComplexOneConfig/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt: no more dll for plugin
-
-2002-08-23 16:15 martink
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt: remoevd shared
- lib
-
-2002-08-23 16:12 martink
-
- * Source/: cmCPluginAPI.h, cmCacheManager.h, cmDirectory.h,
- cmRegularExpression.h, cmStandardIncludes.h, cmSystemTools.h,
- cmake.h, CMakeLists.txt, cmListFileCache.h, cmMakefile.h,
- cmMakefileGenerator.h, cmakewizard.h: removed shared lib support
-
-2002-08-23 16:12 martink
-
- * Source/cmaketest.cxx: memory issue
-
-2002-08-23 15:11 martink
-
- * Source/: cmVTKMakeInstantiatorCommand.cxx, cmCacheManager.h,
- cmCPluginAPI.cxx: compiler warnings
-
-2002-08-23 13:47 hoffman
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt: BUG: fix for
- cygwin
-
-2002-08-23 13:46 hoffman
-
- * Source/: CMakeLists.txt, cmCacheManager.cxx, cmCacheManager.h,
- cmake.cxx, cmake.h, cmakemain.cxx, cmaketest.cxx,
- CursesDialog/CMakeLists.txt, CursesDialog/form/CMakeLists.txt:
- BUG: add explicit clean up of the cachemanager at exit of
- programs, so dll destruction is not a problem.
-
-2002-08-23 09:09 hoffman
-
- * Source/cmNMakeMakefileGenerator.cxx: remove use of
- getpropertyasbool
-
-2002-08-22 17:06 hoffman
-
- * Tests/: Complex/CMakeLists.txt, ComplexOneConfig/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt: BUG: fix for borland and a
- shared CMakeLib
-
-2002-08-22 16:57 hoffman
-
- * Tests/: Complex/CMakeLists.txt,
- Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt: BUG: fix for
- borland and a shared CMakeLib
-
-2002-08-22 16:16 hoffman
-
- * Source/CMakeLists.txt: BUG: borland needs to have
- BUILD_SHARED_LIBS on for executables to work with c++
-
-2002-08-22 15:58 martink
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt: complex test
- needs the dll
-
-2002-08-22 14:41 martink
-
- * Source/cmCPluginAPI.cxx: minor warning fix
-
-2002-08-22 14:40 iscott
-
- * Modules/: FindAVIFile.cmake, readme.txt: Some more explanation of
- a consistent scheme
-
-2002-08-22 11:37 hoffman
-
- * configure, configure.in, Templates/cxxconfigure,
- Templates/cxxconfigure.in: BUG: fix for OSF compiler to use ansi
- mode for streams
-
-2002-08-22 11:12 hoffman
-
- * Source/cmNMakeMakefileGenerator.cxx: BUG: use c flags for
- cprograms, and do not use large command lines for linking
-
-2002-08-22 09:17 martink
-
- * Source/cmCPluginAPI.cxx: fixed some warnings
-
-2002-08-22 09:11 martink
-
- * Source/cmSetSourceFilesPropertiesCommand.cxx: fixed some warnings
-
-2002-08-22 09:10 martink
-
- * Source/cmCPluginAPI.h: fixed nested comment
-
-2002-08-22 08:25 martink
-
- * Source/CursesDialog/CMakeLists.txt: added lib
-
-2002-08-21 15:52 king
-
- * Utilities/cmake_release_unix_package.sh: ENH: Added -files to end
- of internal binary tarball to distinguish from the outer
- tarball's name.
-
-2002-08-21 15:37 martink
-
- * Source/CursesDialog/cmCursesMainForm.cxx: minor fixes for new
- cache api
-
-2002-08-21 13:15 martink
-
- * Source/: cmMakefile.cxx, cmMakefile.h, cmCPluginAPI.cxx: minor
- bug
-
-2002-08-21 12:01 martink
-
- * Source/: cmMakefileGenerator.h, cmMakefile.h: dll support
-
-2002-08-21 12:00 martink
-
- * Source/cmRegularExpression.h: made into dll
-
-2002-08-21 11:59 martink
-
- * Source/: cmake.h, cmakewizard.h, cmakewizard.cxx: support for
- plugins
-
-2002-08-21 11:58 martink
-
- * Source/: cmLoadCommandCommand.cxx, cmLoadCommandCommand.h: adding
- plugin support
-
-2002-08-21 11:58 martink
-
- * Source/: cmDynamicLoader.cxx, cmDynamicLoader.h: added plugin
- support
-
-2002-08-21 11:55 martink
-
- * Source/: cmStandardIncludes.h, CMakeLists.txt,
- cmCacheManager.cxx, cmCacheManager.h, cmDirectory.h,
- cmSystemTools.h, cmListFileCache.h: made CMakeLib shared on
- windows
-
-2002-08-21 11:54 martink
-
- * Source/: cmCPluginAPI.cxx, cmCPluginAPI.h: added C Plugin API
- first cut
-
-2002-08-21 09:45 hoffman
-
- * Source/cmNMakeMakefileGenerator.cxx: BUG: use c compiler for link
- of c programs, and use temp file nmake syntax for linking c and
- c++ programs
-
-2002-08-19 15:40 iscott
-
- * Modules/: FindQt.cmake, LinkQT.cmake: I have tested this with
- VXL/our internal code, and it works for me.
-
-2002-08-19 10:05 iscott
-
- * Modules/FindQt.cmake: I first go at a consistent FindXXX.cmake
- file
-
-2002-08-16 11:20 martink
-
- * Source/cmMacroCommand.cxx: minor fix
-
-2002-08-16 11:17 martink
-
- * Source/: cmQTWrapCPPCommand.cxx, cmQTWrapUICommand.cxx,
- cmSetSourceFilesPropertiesCommand.cxx,
- cmSetSourceFilesPropertiesCommand.h, cmSourceFile.cxx,
- cmSourceFile.h, cmSourceFilesCommand.cxx,
- cmVTKWrapJavaCommand.cxx, cmVTKWrapPythonCommand.cxx,
- cmVTKWrapTclCommand.cxx, cmGetSourceFilePropertyCommand.cxx,
- cmWrapExcludeFilesCommand.cxx, cmCreateTestSourceList.cxx,
- cmAbstractFilesCommand.cxx, cmAuxSourceDirectoryCommand.cxx,
- cmBorlandMakefileGenerator.cxx, cmDSPWriter.cxx,
- cmFLTKWrapUICommand.cxx, cmMSDotNETGenerator.cxx,
- cmMakeDepend.cxx, cmNMakeMakefileGenerator.cxx, cmTarget.cxx,
- cmUnixMakefileGenerator.cxx, cmVTKMakeInstantiatorCommand.cxx:
- modified how source files store properties
-
-2002-08-16 09:45 king
-
- * Source/cmVTKMakeInstantiatorCommand.cxx: ERR: unsigned int ->
- size_t.
-
-2002-08-16 09:31 king
-
- * Source/cmVTKMakeInstantiatorCommand.cxx: ENH: Changed check for
- which version of instantiators to generate to look for definition
- of VTK_USE_INSTANTIATOR_NEW instead of an extra argument to
- VTK_MAKE_INSTANTIATOR.
-
-2002-08-15 15:01 king
-
- * Source/: cmVTKMakeInstantiatorCommand.cxx,
- cmVTKMakeInstantiatorCommand.h: BUG: Added
- backward-compatability. The old instantiator style will be used
- unless the argument USE_INSTANTIATOR_NEW is given to tell the
- command to make use of the instantiator new functions exported
- from each class's implementation file.
-
-2002-08-15 14:39 king
-
- * Source/: cmVTKMakeInstantiatorCommand.cxx,
- cmVTKMakeInstantiatorCommand.h: ENH: Improved generated
- instantiator to use extern declarations to wrappers around the
- New() methods. This avoids the need to include each class's
- header in an instantiator source. The instantiator class
- implementations can now fit in a single source file that compiles
- quickly.
-
-2002-08-15 09:34 hoffman
-
- * Source/cmNMakeMakefileGenerator.cxx: ENH: add -DWIN32 flag for
- builds
-
-2002-08-14 11:44 ibanez
-
- * Modules/FindFLTK.cmake: ENH: Platform dependent libraries added.
-
-2002-08-13 15:47 martink
-
- * Tests/: Complex/CMakeLists.txt, ComplexOneConfig/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt: added macro test
-
-2002-08-13 15:46 martink
-
- * Source/: cmCommands.cxx, cmMacroCommand.cxx, cmMacroCommand.h:
- added new command
-
-2002-08-13 10:46 martink
-
- * Source/: cmExecProgramCommand.h, cmExecProgramCommand.cxx: merge
- from main tree
-
-2002-08-13 10:08 martink
-
- * CMakeLists.txt: added man page
-
-2002-08-13 10:05 martink
-
- * Source/cmCreateTestSourceList.cxx: some warning and purify fixes
-
-2002-08-13 10:04 martink
-
- * Source/: cmElseCommand.cxx, cmIfCommand.cxx: IF Else improvements
-
-2002-08-13 10:03 martink
-
- * Source/: cmMakefile.cxx, cmMakefile.h: merges from the main
- branch
-
-2002-08-13 10:02 martink
-
- * Source/cmRemoveCommand.cxx: merge from main branch
-
-2002-08-13 10:01 martink
-
- * Copyright.txt: merge from the main branch
-
-2002-08-13 10:00 martink
-
- * cmake.1: updated from main branch
-
-2002-08-13 09:59 martink
-
- * Modules/: FindFLTK.cmake, FindTCL.cmake: updates from the main
- branch
-
-2002-08-12 08:39 martink
-
- * Source/cmElseCommand.cxx: compiler warning
-
-2002-08-09 12:00 martink
-
- * Source/: cmElseCommand.cxx, cmIfCommand.cxx, cmMakefile.cxx:
- better IF ELSE handling
-
-2002-08-09 10:04 barre
-
- * Modules/FindTCL.cmake: FIX: fix commit messup (this change was
- committed to the branch instead of the main tree, thus was
- wiped-out later)
-
-2002-08-09 08:33 barre
-
- * Modules/FindwxWindows.cmake: FIX: - WINDOWS does not exist, use
- WIN32 (or defineWINDOWS if cygwin can not be used inUnix mode?),
- - fix an un-closed IF, - use same prefix for vars (and make it
- advanced)
-
-2002-08-09 07:55 andy
-
- * Modules/FindwxWindows.cmake: This hopefully finds wxWindows on
- UNIX
-
-2002-08-08 15:30 andy
-
- * Modules/FindwxWindows.cmake: Add UNIX support for WXWINDOWS
-
-2002-08-08 15:29 andy
-
- * Source/: cmExecProgramCommand.cxx, cmExecProgramCommand.h: Add
- return value support and add documentation
-
-2002-08-08 15:14 king
-
- * Copyright.txt: ENH: Updated copyright.
-
-2002-08-08 15:13 andy
-
- * Source/: cmExecProgramCommand.cxx, cmExecProgramCommand.h: Add
- option of storing output to the variable
-
-2002-08-08 13:41 barre
-
- * Modules/FindwxWindows.cmake: ENH: first stab at wxWindows support
- (win32)
-
-2002-08-08 12:49 king
-
- * CMakeLists.txt: ENH: Adding installation for man page.
-
-2002-08-08 12:30 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: handle .exe extension
- for cygwin
-
-2002-08-08 11:58 king
-
- * cmake.1: ENH: Initial checkin of unix manpage.
-
-2002-08-08 08:51 martink
-
- * Source/cmCreateTestSourceList.cxx: fixed some compiler warnings
- and leaks
-
-2002-08-07 18:12 king
-
- * Utilities/: cmake_release_config_hpux, cmake_release_config_irix,
- cmake_release_config_linux, cmake_release_config_sun,
- cmake_release_unix.sh, cmake_release_unix_build.sh,
- cmake_release_unix_config.sh, cmake_release_unix_package.sh: ENH:
- Split install script into two parts. Added basic support for
- adding more files to the distribution and creating packages.
-
-2002-08-07 11:01 martink
-
- * Source/cmCreateTestSourceList.cxx: fixed some compiler warnings
- and leaks
-
-2002-08-07 10:30 martink
-
- * Source/cmCreateTestSourceList.cxx: fixed some compiler warnings
- and leaks
-
-2002-08-05 18:08 ibanez
-
- * Modules/FindFLTK.cmake: ENH: Images library added. Names for
- debuggin versions in windows added.
-
-2002-08-05 09:51 martink
-
- * Source/cmRemoveCommand.cxx: minor fix
-
-2002-08-02 13:43 ibanez
-
- * Modules/FindFLTK.cmake: FIX: names styles for fltkgl and
- fltkforms are different in windows and linux. Both styles
- are now searched taking advantage of the NAMES option in
- FIND_LIBRARY.
-
-2002-08-02 12:51 martink
-
- * Source/cmLinkDirectoriesCommand.cxx: duhhhhhh
-
-2002-08-02 08:50 martink
-
- * Source/: cmFindLibraryCommand.cxx, cmLinkLibrariesCommand.cxx,
- cmMakefile.h: updates from the main tree
-
-2002-08-01 23:05 barre
-
- * Source/cmFindLibraryCommand.cxx: FIX: put ExpandRegistryValue()
- back (seems to have been removed accidentally I guess in 1.25)
-
-2002-08-01 15:58 martink
-
- * Source/cmLinkDirectoriesCommand.cxx: no longer need an argument
-
-2002-08-01 09:50 martink
-
- * Source/cmCreateTestSourceList.cxx,
- Source/cmCreateTestSourceList.h, Source/cmMakefile.h,
- Source/cmNMakeMakefileGenerator.cxx,
- Source/cmNMakeMakefileGenerator.h, Source/cmSystemTools.cxx,
- Source/cmUnixMakefileGenerator.cxx,
- Source/cmUnixMakefileGenerator.h, Source/cmVTKWrapTclCommand.cxx,
- Source/cmake.cxx, Tests/Complex/CMakeLists.txt,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexRelativePaths/CMakeLists.txt,
- Tests/TestDriver/CMakeLists.txt, Tests/TestDriver/test1.cxx,
- Tests/TestDriver/test2.cxx, Tests/TestDriver/testArgs.h,
- Tests/TestDriver/subdir/test3.cxx: merges from the main branch
-
-2002-08-01 08:41 martink
-
- * Modules/: FindGLU.cmake, FindJNI.cmake, FindOpenGL.cmake,
- FindTCL.cmake: merges from the main tree
-
-2002-07-31 13:45 hoffman
-
- * Source/: cmNMakeMakefileGenerator.cxx,
- cmNMakeMakefileGenerator.h, cmUnixMakefileGenerator.cxx,
- cmUnixMakefileGenerator.h: BUG: fix jump to directory and build
- for nmake if library path is not set. combine
- OutputBuildExecutableInDir and OutputBuildLibraryInDir into
- OutputBuildTargetInDir
-
-2002-07-31 11:08 martink
-
- * Tests/TestDriver/testArgs.h: minor fix for c tests
-
-2002-07-31 11:07 martink
-
- * Source/cmCreateTestSourceList.cxx: fixed support for C test
- programs
-
-2002-07-31 09:29 barre
-
- * Source/cmCreateTestSourceList.cxx: FIX: <stdlib.h> is enough to
- get malloc()/free()
-
-2002-07-30 16:19 martink
-
- * Tests/TestDriver/: CMakeLists.txt, test1.cxx, test2.cxx,
- subdir/test3.cxx: updated to mods in command
-
-2002-07-30 16:18 martink
-
- * Source/: cmCreateTestSourceList.cxx, cmCreateTestSourceList.h:
- updated to handle extensions
-
-2002-07-30 10:33 barre
-
- * Source/cmCreateTestSourceList.cxx: FIX: la commande créait du
- code C++. Du code C devrait faire l'affaire.
-
-2002-07-30 10:23 barre
-
- * Source/cmCreateTestSourceList.cxx: FIX: la commande créait du
- code C++. Du code C devrait faire l'affaire.
-
-2002-07-29 09:46 barre
-
- * Modules/: FindTCL.cmake: ENH: change the search path order (if
- several Tcl/Tk are installed, the "current" version is likely to
- be the one that is bound to the wish/tclsh found in the PATH)
-
-2002-07-26 14:06 barre
-
- * Modules/: FindTCL.cmake: ENH: clean the module, add debug libs
-
-2002-07-26 10:14 king
-
- * Source/: cmITKWrapTclCommand.cxx, cmITKWrapTclCommand.h: BUG:
- Only one generated Tcl wrapper source was getting added to the
- package's library.
-
-2002-07-26 09:54 king
-
- * Source/cmVTKWrapTclCommand.cxx: BUG: Generated call to
- Tcl_CreateCommand for vtkCommand should cast pointer to extern
- "C" version.
-
-2002-07-25 16:47 king
-
- * Source/cmVTKWrapTclCommand.cxx: BUG: Generated vtkCommand
- prototype cannot be extern "C" because it may not match with the
- version in VTK.
-
-2002-07-25 16:41 andy
-
- * Source/cmSystemTools.cxx: Ok, now cd will work on windows
-
-2002-07-25 16:25 will
-
- * Source/cmVTKWrapTclCommand.cxx: fixed warning
-
-2002-07-25 11:17 barre
-
- * Modules/FindTCL.cmake: FIX: the stub libs were not searched
-
-2002-07-25 11:10 barre
-
- * Modules/FindTCL.cmake: FIX: the stub libs were not searched
-
-2002-07-25 09:16 martink
-
- * Source/cmMakefile.cxx: makefile now does not ignore NOTFOUND libs
- and includes
-
-2002-07-25 08:00 martink
-
- * Source/cmMakefile.cxx: makefile now ignores NOTFOUND libs and
- includes
-
-2002-07-22 11:03 king
-
- * Utilities/cmake_release_config_irix: ENH: Added release script
- configuration for IRIX build.
-
-2002-07-22 10:40 martink
-
- * Source/cmMakefile.h: updated to patch 1
-
-2002-07-22 10:34 martink
-
- * Templates/CXXCMakeSystemConfig.cmake.in: better docs and support
- for mising args
-
-2002-07-22 10:33 martink
-
- * Source/cmMakefile.cxx: now replaces args even if not defined
-
-2002-07-22 10:31 martink
-
- * Source/: cmAddDefinitionsCommand.cxx,
- cmIncludeDirectoryCommand.cxx, cmLinkLibrariesCommand.cxx,
- cmTargetLinkLibrariesCommand.cxx: allows less arguments changes
- from main tree
-
-2002-07-22 10:00 martink
-
- * Source/: cmIncludeDirectoryCommand.cxx,
- cmLinkLibrariesCommand.cxx: allows no arguments
-
-2002-07-20 08:55 martink
-
- * Source/cmAddDefinitionsCommand.cxx: modified to accept no
- arguments
-
-2002-07-19 15:49 martink
-
- * Templates/CXXCMakeSystemConfig.cmake.in: fixed some empty
- descriptions
-
-2002-07-19 14:42 martink
-
- * Source/cmMakefile.cxx: full variable replacement and removal or
- empty arguments
-
-2002-07-19 14:40 martink
-
- * Source/cmTargetLinkLibrariesCommand.cxx: does not need a second
- argument
-
-2002-07-18 18:43 starreveld
-
- * Modules/: FindGLU.cmake, FindOpenGL.cmake: ERR: remove automatic
- Carbon framework on osx
-
-2002-07-17 16:33 martink
-
- * Source/cmInstallFilesCommand.cxx: fix for install with paths
-
-2002-07-17 15:57 martink
-
- * Source/cmInstallFilesCommand.cxx: fixe for files with paths
-
-2002-07-17 11:53 andy
-
- * Source/cmake.cxx: Fix changing of directories using cmSystemTools
- RunCommand feature
-
-2002-07-17 10:52 martink
-
- * Source/: cmForEachCommand.cxx, cmForEachCommand.h,
- cmMakefile.cxx: fix for IF statements inside of Foreach loops
-
-2002-07-17 10:48 martink
-
- * Source/cmForEachCommand.cxx, Source/cmForEachCommand.h,
- Source/cmMakefile.cxx, Tests/Complex/CMakeLists.txt,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexRelativePaths/CMakeLists.txt: fixed if statements
- inside a foreach
-
-2002-07-16 17:42 king
-
- * Tests/: Complex/CMakeLists.txt, Complex/cmTestConfigure.h.in,
- Complex/Executable/complex.cxx, ComplexOneConfig/CMakeLists.txt,
- ComplexOneConfig/cmTestConfigure.h.in,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/CMakeLists.txt,
- ComplexRelativePaths/cmTestConfigure.h.in,
- ComplexRelativePaths/Executable/complex.cxx: ENH: Added test for
- IF inside a FOREACH.
-
-2002-07-15 11:37 king
-
- * Utilities/cmake_release_config_hpux: ENH: Adding release script
- configuration for HPUX.e
-
-2002-07-15 11:13 king
-
- * Utilities/cmake_release_config_sun: ENH: Added release
- configuration file for Sun.
-
-2002-07-15 10:48 king
-
- * Utilities/: cmake_release_config_linux, cmake_release_unix.sh:
- ENH: Made release script more generic for creating static and
- shared releases.
-
-2002-07-15 10:09 king
-
- * Utilities/cmake_release_config_linux: ENH: Release script
- configuration file for linux.
-
-2002-07-15 10:08 king
-
- * Utilities/cmake_release_unix.sh: ENH: Protoype unix release
- script.
-
-2002-07-15 09:55 king
-
- * Templates/CMakeLists.txt: ERR: CXXCMakeSystemConfig.cmake and
- CCMakeSystemConfig.cmake need .in extension.
-
-2002-07-15 09:46 king
-
- * Source/cmInstallFilesCommand.cxx: BUG: Only the last extension
- should be removed.
-
-2002-07-15 09:45 king
-
- * Source/: cmInstallFilesCommand.cxx, cmInstallFilesCommand.h: BUG:
- INSTALL_FILES command should remove the extension of a file
- before adding the user provided extension.
-
-2002-07-15 09:44 king
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Added
- GetFilenameWithoutLastExtension.
-
-2002-07-15 09:23 king
-
- * Templates/CMakeLists.txt: ERR: Install for
- CXXCMakeSystemConfig.cmake and CCMakeSystemConfig.cmake need .in
- extension.
-
-2002-07-15 09:22 king
-
- * Modules/FindJNI.cmake: ENH: Added /usr/local/lib/java search
- paths.
-
-2002-07-15 08:44 martink
-
- * Source/: cmInstallFilesCommand.cxx, cmInstallFilesCommand.h: fix
- install target
-
-2002-07-12 11:17 martink
-
- * Modules/FindJava.cmake: merged module into branch
-
-2002-07-12 11:10 martink
-
- * Source/cmIfCommand.cxx: minor warning fix
-
-2002-07-11 14:58 martink
-
- * Source/cmIfCommand.cxx: fix warning
-
-2002-07-11 14:25 martink
-
- * Source/cmMakefile.cxx: merge from the main tree
-
-2002-07-11 14:20 hoffman
-
- * Source/cmMakefile.cxx: BUG: fix for compile with hp
-
-2002-07-11 14:03 martink
-
- * Source/: cmElseCommand.cxx, cmIfCommand.cxx, cmIfCommand.h,
- cmMakefile.cxx, cmMakefile.h: merged some updates, the IF
- checking
-
-2002-07-11 13:58 martink
-
- * Source/: cmUnixMakefileGenerator.cxx, cmVTKWrapTclCommand.cxx,
- cmake.cxx: updates from the main tree
-
-2002-07-10 16:07 martink
-
- * Source/cmVTKWrapTclCommand.cxx: fix warning on Sun
-
-2002-07-10 14:34 andy
-
- * Source/cmake.cxx: Add command that runs program in given
- directory
-
-2002-07-10 11:38 martink
-
- * Source/: cmElseCommand.cxx, cmIfCommand.cxx, cmIfCommand.h,
- cmMakefile.cxx, cmMakefile.h: better error handling with if
- statements
-
-2002-07-10 09:33 andy
-
- * Source/cmUnixMakefileGenerator.cxx: Fix problem when using NMake.
- This generated lines without space so nmake got all confused
-
-2002-07-08 09:30 andy
-
- * Modules/FindJava.cmake: Add module that finds java executables.
- This module should find java, javac, and jar.
-
-2002-07-02 09:58 martink
-
- * configure, configure.in: merges from main tree
-
-2002-07-02 09:56 martink
-
- * Modules/FindFLTK.cmake: merges with main tree
-
-2002-07-02 09:54 martink
-
- * Source/: cmAuxSourceDirectoryCommand.cxx,
- cmBorlandMakefileGenerator.cxx, cmCMakeMinimumRequired.cxx,
- cmConfigure.cmake.h.in, cmConfigure.h.in,
- cmCreateTestSourceList.cxx, cmCreateTestSourceList.h,
- cmDSWWriter.cxx, cmElseCommand.cxx, cmEnableTestingCommand.h,
- cmFLTKWrapUICommand.cxx, cmFindLibraryCommand.cxx,
- cmFunctionBlocker.h, cmGetFilenameComponentCommand.cxx,
- cmITKWrapTclCommand.cxx, cmIfCommand.cxx, cmIfCommand.h,
- cmInstallFilesCommand.cxx, cmLinkLibrariesCommand.cxx,
- cmMSDotNETGenerator.cxx, cmMSDotNETGenerator.h, cmMakeDepend.cxx,
- cmMakeDepend.h, cmMakefile.cxx, cmMakefile.h,
- cmNMakeMakefileGenerator.cxx, cmNMakeMakefileGenerator.h,
- cmQTWrapCPPCommand.cxx, cmQTWrapUICommand.cxx, cmSourceFile.cxx,
- cmSourceFile.h, cmSourceFilesCommand.cxx,
- cmSourceFilesRemoveCommand.cxx, cmStandardIncludes.h,
- cmSystemTools.cxx, cmSystemTools.h, cmTarget.cxx,
- cmTargetLinkLibrariesCommand.cxx, cmUnixMakefileGenerator.cxx,
- cmUnixMakefileGenerator.h, cmVTKMakeInstantiatorCommand.cxx,
- cmVTKWrapJavaCommand.cxx, cmVTKWrapPythonCommand.cxx,
- cmVTKWrapTclCommand.cxx, cmWrapExcludeFilesCommand.cxx,
- cmake.cxx, cmake.h, ctest.cxx: massive merge from main tree
-
-2002-07-02 09:33 martink
-
- * Source/: cmFindLibraryCommand.cxx, cmMakefile.h,
- cmSystemTools.cxx, cmSystemTools.h: updates
-
-2002-07-02 08:24 martink
-
- * Source/: cmMakefile.cxx, cmMakefile.h: fixed warning
-
-2002-07-01 08:49 martink
-
- * Source/: cmElseCommand.cxx, cmIfCommand.cxx, cmIfCommand.h:
- consolidated IF handling and added checks for bad arguments
-
-2002-06-30 13:53 martink
-
- * Source/: cmVTKWrapPythonCommand.cxx, cmVTKWrapTclCommand.cxx:
- fixed commands that were setting definitions in final pass to set
- definitions in initial pass
-
-2002-06-29 20:04 martink
-
- * Source/: cmQTWrapCPPCommand.cxx, cmVTKWrapJavaCommand.cxx,
- cmVTKWrapPythonCommand.cxx, cmVTKWrapTclCommand.cxx: fixed
- commands that were setting definitions in final pass to set
- definitions in initial pass
-
-2002-06-28 10:29 andy
-
- * Source/cmVTKWrapPythonCommand.cxx: Remove another warning in the
- python wrapping
-
-2002-06-28 10:18 martink
-
- * Source/cmSourceFile.h: performance fix
-
-2002-06-28 09:43 andy
-
- * Source/cmVTKWrapPythonCommand.cxx: Add removing of warnings and
- add comment about the file being generated in CMake
-
-2002-06-28 09:21 martink
-
- * Source/cmAuxSourceDirectoryCommand.cxx: bug fix for aux src dirs
-
-2002-06-28 08:57 martink
-
- * Source/: cmMakefile.cxx, cmSourceFile.h: minor cleanup
-
-2002-06-27 21:17 martink
-
- * Source/: cmMakefile.cxx, cmSourceFile.h: performance inprovements
-
-2002-06-27 16:47 martink
-
- * Source/cmMakefile.cxx: bug fix
-
-2002-06-27 16:42 martink
-
- * Source/: cmMakefile.cxx, cmSourceFilesCommand.cxx: bug fix
-
-2002-06-27 16:25 martink
-
- * Source/cmSourceFilesCommand.cxx: bug fix
-
-2002-06-27 16:05 martink
-
- * Tests/Simple/CMakeLists.txt: a minor fix to make my life easier
-
-2002-06-27 15:57 martink
-
- * Source/cmAuxSourceDirectoryCommand.cxx,
- Source/cmCreateTestSourceList.cxx, Source/cmDSWWriter.cxx,
- Source/cmFLTKWrapUICommand.cxx,
- Source/cmGetFilenameComponentCommand.cxx,
- Source/cmITKWrapTclCommand.cxx, Source/cmInstallFilesCommand.cxx,
- Source/cmLinkLibrariesCommand.cxx,
- Source/cmMSDotNETGenerator.cxx, Source/cmMakeDepend.cxx,
- Source/cmMakefile.cxx, Source/cmMakefile.h,
- Source/cmQTWrapCPPCommand.cxx, Source/cmQTWrapUICommand.cxx,
- Source/cmSourceFilesCommand.cxx,
- Source/cmSourceFilesRemoveCommand.cxx, Source/cmSystemTools.cxx,
- Source/cmSystemTools.h, Source/cmTarget.cxx,
- Source/cmTargetLinkLibrariesCommand.cxx,
- Source/cmUnixMakefileGenerator.cxx,
- Source/cmVTKMakeInstantiatorCommand.cxx,
- Source/cmVTKWrapJavaCommand.cxx,
- Source/cmVTKWrapPythonCommand.cxx,
- Source/cmVTKWrapTclCommand.cxx,
- Source/cmWrapExcludeFilesCommand.cxx,
- Tests/Complex/Library/CMakeLists.txt,
- Tests/ComplexOneConfig/Library/CMakeLists.txt,
- Tests/ComplexRelativePaths/Library/CMakeLists.txt: removed all
- source lists from the system and made them vectors. Also appended
- _CMAKE_PATH to the end of the automatic cache entries for
- executables and libraries. Odds of all these changes working are
- slim but cmake builds and passes all its tests. VTK40 starts
- building
-
-2002-06-27 09:35 king
-
- * Source/: cmake.cxx, cmake.h: BUG: CMake crashed if it failed to
- find its own executable. Also added better error messages when
- this occurs.
-
-2002-06-25 09:59 hoffman
-
- * Tests/Simple/CMakeLists.txt: add a test with no extension
-
-2002-06-25 09:59 hoffman
-
- * Source/cmTarget.cxx: BUG: try to tell the difference between
- variables with sources and other variables
-
-2002-06-25 09:18 king
-
- * Source/cmStandardIncludes.h: BUG: Result from ostrstream::str()
- can be a null pointer.
-
-2002-06-24 18:19 king
-
- * Source/cmStandardIncludes.h: BUG: Attempt to fix
- ostrstream::str() wrapper for broken platforms.
-
-2002-06-24 16:42 martink
-
- * Source/cmTarget.cxx: modified to handle src list vectors without
- proper dollar signs
-
-2002-06-24 14:07 martink
-
- * Source/ctest.cxx: BUG: make sure windows paths are used for the
- command or it will not work for win 98
-
-2002-06-21 11:35 martink
-
- * Templates/: CXXCMakeSystemConfig.cmake.in, cxxconfigure,
- cxxconfigure.in: now looks for stringstream as well, from the
- main tree
-
-2002-06-21 11:25 martink
-
- * Source/: cmElseCommand.cxx, cmIfCommand.cxx: fixed if matches bug
-
-2002-06-21 10:31 king
-
- * Source/cmStandardIncludes.h: ERR: using declaration to move
- streams into std namespace needs to bring up ostrstream and
- ostringstream, not strstream and stringstream.
-
-2002-06-21 10:26 king
-
- * Source/CursesDialog/form/frm_driver.c: ERR: Removed most of the
- repeated curses declarations. The cause errors on other
- platforms. Grrrr..
-
-2002-06-21 09:25 king
-
- * Source/CursesDialog/form/frm_driver.c: ERR: Added function
- declarations from curses.h. They are not present on some
- platforms. Fixes warnings about implicit declarations.
-
-2002-06-21 09:00 king
-
- * Tests/: Complex/cmTestConfigure.h.in,
- ComplexOneConfig/cmTestConfigure.h.in,
- ComplexRelativePaths/cmTestConfigure.h.in: ENH: Added
- configuration of CMAKE_NO_ANSI_STRING_STREAM. It is defined when
- the sstream header does not exist.
-
-2002-06-21 08:42 king
-
- * configure, Templates/cxxconfigure: ERR: Ran autoconf on
- corresponding fixes to configure.in and cxxconfigure.in.
-
-2002-06-21 08:39 hoffman
-
- * Templates/cxxconfigure.in: fix for sstream
-
-2002-06-21 08:38 hoffman
-
- * configure.in: fix to sstring stuff
-
-2002-06-20 10:39 hoffman
-
- * Source/: cmElseCommand.cxx, cmIfCommand.cxx: modified MATCHES to
- handle non variables
-
-2002-06-20 10:20 king
-
- * Source/cmStandardIncludes.h: ERR: cmStringStream is taking the
- functionality of ostringstream and ostrstream, not stringstream
- and strstream.
-
-2002-06-20 10:19 king
-
- * Templates/CXXCMakeSystemConfig.cmake.in: BUG:
- CMAKE_NO_ANSI_STRING_STREAM needs to be copied from the
- cxxconfigure results.
-
-2002-06-19 15:21 king
-
- * Source/: cmBorlandMakefileGenerator.cxx,
- cmCMakeMinimumRequired.cxx, cmConfigure.cmake.h.in,
- cmConfigure.h.in, cmNMakeMakefileGenerator.cxx,
- cmStandardIncludes.h, cmSystemTools.cxx,
- cmUnixMakefileGenerator.cxx, cmVTKMakeInstantiatorCommand.cxx,
- cmake.cxx: ENH: Added cmStringStream class to wrap
- std::stringstream or std::strstream depending on the platform.
- The interface is that of std::stringstream, so no "ends" or
- "rdbuf()->freeze(0)" lines are needed.
-
-2002-06-19 15:09 king
-
- * configure, Templates/cxxconfigure: ENH: Re-ran autoconf to
- include changes to corresponding configure input. This adds a
- test for the availability of sstream.
-
-2002-06-19 15:05 king
-
- * configure.in, Templates/cxxconfigure.in: ENH: Added test for
- sstream header. Defines CMAKE_NO_ANSI_STRING_STREAM if the
- header doesn't exist.
-
-2002-06-19 14:35 barre
-
- * Source/cmSystemTools.cxx: ENH: FindLibrary supports .Net specific
- lib dirs
-
-2002-06-19 13:49 martink
-
- * Source/: cmCreateTestSourceList.cxx, cmCreateTestSourceList.h,
- cmEnableTestingCommand.h, cmFunctionBlocker.h, cmMakefile.h,
- cmTarget.cxx: merges from main tree
-
-2002-06-19 13:28 martink
-
- * Source/cmSourceFile.cxx: modified create test source to create a
- vector
-
-2002-06-19 13:14 martink
-
- * Modules/: Dart.cmake, FindGLU.cmake, FindGLUT.cmake,
- FindJNI.cmake, FindOpenGL.cmake, FindTclsh.cmake, FindX11.cmake:
- update dfrom main tree
-
-2002-06-19 12:51 martink
-
- * Source/cmCreateTestSourceList.cxx,
- Source/cmCreateTestSourceList.h, Source/cmSourceFile.cxx,
- Source/cmTarget.cxx, Tests/TestDriver/CMakeLists.txt: modified
- create test source to create a vector
-
-2002-06-19 08:57 king
-
- * Source/CursesDialog/form/fty_alpha.c: ERR: Fixed unused parameter
- warning.
-
-2002-06-19 07:28 hoffman
-
- * CMakeLists.txt, Tests/Complex/CMakeLists.txt,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexRelativePaths/CMakeLists.txt: [no log message]
-
-2002-06-18 17:20 king
-
- * Source/: cmEnableTestingCommand.h, cmFunctionBlocker.h,
- cmMakefile.cxx, cmSystemTools.cxx, cmTarget.cxx: ERR: Fixed
- compiler warnings.
-
-2002-06-18 17:20 king
-
- * Source/CursesDialog/: ccmake.cxx, cmCursesBoolWidget.cxx,
- cmCursesDummyWidget.cxx, cmCursesForm.h, cmCursesLabelWidget.cxx,
- cmCursesLongMessageForm.cxx, cmCursesMainForm.cxx: ERR: Fixed
- compiler warnings about unused parameters.
-
-2002-06-18 17:19 king
-
- * Source/CursesDialog/form/: frm_driver.c, frm_req_name.c,
- fty_alnum.c, fty_int.c, fty_ipv4.c, fty_num.c, fty_regex.c: ERR:
- Fixed compiler warnings when using strict ansi.
-
-2002-06-18 16:43 martink
-
- * Modules/Dart.cmake: fixed another bug
-
-2002-06-18 16:35 martink
-
- * Modules/Dart.cmake: fixed bug
-
-2002-06-18 16:32 king
-
- * Source/ctest.cxx: ERR: Fix for fprintf format warning.
-
-2002-06-18 16:30 king
-
- * Source/CursesDialog/form/frm_data.c: ERR: Attempt to fix warning
- on OSF about implicit declaration of winnstr.
-
-2002-06-18 14:26 barre
-
- * Modules/FindGLUT.cmake: ENH: add more paths for the HP
-
-2002-06-18 08:54 hoffman
-
- * CMakeLists.txt, Tests/Complex/CMakeLists.txt,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexRelativePaths/CMakeLists.txt: ENH: try and fix link
- problem on dec
-
-2002-06-17 13:43 andy
-
- * Modules/FindJNI.cmake: Add debian Java paths
-
-2002-06-17 13:07 barre
-
- * Modules/: FindGLU.cmake, FindGLUT.cmake: FIX: GLU and GLUT flags
- for Mac OSX
-
-2002-06-14 16:49 barre
-
- * Modules/: FindCABLE.cmake, FindTclsh.cmake, FindX11.cmake: ENH:
- clean modules (doc, make stuff advanced, etc.)
-
-2002-06-14 16:38 hoffman
-
- * Modules/Dart.cmake: ENH: change so that on all make based systems
- all dart targets are added
-
-2002-06-14 11:46 barre
-
- * Modules/: FindGLU.cmake, FindGLUT.cmake: ENH: use
- OPENGL_LIBRARY_PATH as additional search path
-
-2002-06-14 11:45 barre
-
- * Modules/FindOpenGL.cmake: ENH: define OPENGL_LIBRARY_PATH (path
- to OPENGL_LIBRARY) so that it can be used to search for other
- OpenGL-related libs
-
-2002-06-14 11:31 barre
-
- * Modules/FindGLU.cmake: FIX: bug, the wrong include file was
- searched.
-
-2002-06-14 10:37 barre
-
- * Source/: cmFindLibraryCommand.cxx, cmSystemTools.cxx,
- cmSystemTools.h: ENH: FindLibrary can now use the makefile to add
- some compiler-specific lib search path (depending on the
- generator).
-
-2002-06-14 10:35 barre
-
- * Modules/FindGLUT.cmake: ENH/FIX: Glut should be found, not set.
- Add search path for Cygwin
-
-2002-06-13 14:45 barre
-
- * Modules/FindGLUT.cmake: FIX: comply with the way OpenGL libs are
- set in FindOpenGL and FindGLU
-
-2002-06-13 11:48 barre
-
- * Modules/: FindGLU.cmake, FindGLUT.cmake, FindOpenGL.cmake: ENH:
- make all OpenGL libs advanced, and add support for glu lib with
- Borland
-
-2002-06-11 14:54 martink
-
- * Source/: cmMSDotNETGenerator.cxx, cmMSDotNETGenerator.h,
- cmNMakeMakefileGenerator.cxx, cmNMakeMakefileGenerator.h,
- cmUnixMakefileGenerator.cxx, cmUnixMakefileGenerator.h: some
- fixes for dot net and spaces
-
-2002-06-11 14:25 hoffman
-
- * Source/: cmNMakeMakefileGenerator.cxx,
- cmNMakeMakefileGenerator.h, cmUnixMakefileGenerator.cxx,
- cmUnixMakefileGenerator.h: use lower case and not short path for
- uniq paths on window
-
-2002-06-11 14:25 hoffman
-
- * Source/cmMSDotNETGenerator.cxx: only allow unique configurations
-
-2002-06-11 14:15 hoffman
-
- * Source/: cmMSDotNETGenerator.cxx, cmMSDotNETGenerator.h: BUG: fix
- dot net for paths with spaces
-
-2002-06-11 12:16 hoffman
-
- * Source/cmMSDotNETGenerator.cxx: BUG: RelativePath should not be
- quoted in output files even if it has spaces
-
-2002-06-11 11:19 martink
-
- * Source/cmUnixMakefileGenerator.cxx: some win98 depend problems
-
-2002-06-11 11:01 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: ENH: don't use short paths in
- the output
-
-2002-06-11 10:43 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: use short path to get unique
- path names for depend path output
-
-2002-06-11 09:14 hoffman
-
- * Source/CursesDialog/: ccmake.cxx, cmCursesMainForm.cxx: ERR:
- Fixed sun CC warnings.
-
-2002-06-10 14:21 martink
-
- * Source/: cmMakeDepend.cxx, cmMakeDepend.h, CMakeLists.txt: joins
- with the head
-
-2002-06-10 14:19 martink
-
- * Source/: cmMakeDepend.cxx, cmMakeDepend.h: now includes current
- include files directory when searching for files it includes
-
-2002-06-10 11:33 hoffman
-
- * Source/CMakeLists.txt: BUG: cmake needs it's own directory for
- includes, so depends work
-
-2002-06-10 09:50 hoffman
-
- * ChangeLog.txt: new changes for 1.4
-
-2002-06-10 09:35 martink
-
- * Source/cmMakefile.h: updated revision
-
-2002-06-10 09:33 martink
-
- * Modules/: FindGLUT.cmake, FindPythonLibs.cmake: updated from main
- branch
-
-2002-06-10 08:53 andy
-
- * Modules/FindPythonLibs.cmake: Oops, forgot the library name
-
-2002-06-10 08:52 andy
-
- * Modules/FindPythonLibs.cmake: Add search for python 2.2
-
-2002-06-07 08:39 ibanez
-
- * Modules/FindFLTK.cmake: FIX: {} were missing around
- FLTK_*_LIBRARY.
-
-2002-06-06 17:49 ibanez
-
- * Modules/FindFLTK.cmake: FIX: The final test is done now over
- FLTK_LIBRARY instead of FLTK_LIBRARY_PATH
-
-2002-06-06 15:28 ibanez
-
- * Modules/FindFLTK.cmake: ENH: Support for FLTK1.1 and FLTK1.0.11
- added. An option allows to select between the two versions.
-
-2002-06-06 15:00 martink
-
- * CMake.rtf: updates
-
-2002-06-06 11:53 hoffman
-
- * Source/: Makefile.borland: ENH: remove borland bootstrap makefile
-
-2002-06-06 08:49 hoffman
-
- * Modules/FindGLUT.cmake: fix for glut on win32
-
-2002-06-05 13:31 martink
-
- * Source/cmMakefile.h: updated revision
-
-2002-06-05 13:30 martink
-
- * Source/cmMakefile.h: updated rev
-
-2002-06-05 13:22 martink
-
- * Source/ccommand.cxx: merged ccommand into cmake
-
-2002-06-05 09:11 martink
-
- * Source/: CMakeLib.dsp, DumpDocumentation.dsp, ccommand.dsp,
- cmake.dsp, ctest.dsp: uses executabke bootstrap
-
-2002-06-03 13:40 martink
-
- * Tests/: Complex/Library/CMakeLists.txt,
- ComplexOneConfig/Library/CMakeLists.txt,
- ComplexRelativePaths/Library/CMakeLists.txt: changed CCOMMAND to
- CMAKE
-
-2002-06-03 13:08 martink
-
- * Source/CMakeLists.txt, Source/cmBorlandMakefileGenerator.cxx,
- Source/cmNMakeMakefileGenerator.cxx, Source/cmake.cxx,
- Source/cmake.h, Source/cmakemain.cxx,
- Tests/Complex/CMakeLists.txt,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexRelativePaths/CMakeLists.txt: removed ccommand use
- cmake now
-
-2002-06-03 11:06 martink
-
- * CMake.rtf: updated
-
-2002-06-03 10:25 hoffman
-
- * Source/: cmMakefile.cxx, cmTarget.cxx: ENH: only add _LIB_DEPEND
- information for libraries and modules
-
-2002-05-31 08:39 martink
-
- * Source/cmSystemTools.cxx: fixed bug in get short path for quoted
- paths
-
-2002-05-29 15:00 perera
-
- * Source/cmTarget.cxx: BUG: never make a target depend on itself.
- This was causing unnecessary library duplication, resulting in
- link errors on some platforms.
-
-2002-05-29 09:56 king
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: MAKEFLAGS does not need
- to be passed on command line. It is automatically set by make in
- environment for recursive call.
-
-2002-05-28 08:56 martink
-
- * Source/: cmake.cxx, cmake.h: remobed bootstrap
-
-2002-05-28 08:50 martink
-
- * bootstrap.exe, ccommand.exe: different bootstrap command
-
-2002-05-27 10:29 barre
-
- * Tests/: Complex/VarTests.cmake, Complex/Executable/complex.cxx,
- ComplexOneConfig/VarTests.cmake,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/VarTests.cmake,
- ComplexRelativePaths/Executable/complex.cxx: ENH: add tests for
- LESS, GREATER, STRLESS, STRGREATER (IF command)
-
-2002-05-23 13:27 hoffman
-
- * Tests/: Complex/CMakeLists.txt, ComplexOneConfig/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt: ENH: increse coverage
-
-2002-05-23 13:23 hoffman
-
- * Source/cmSystemTools.cxx, Source/cmSystemTools.h,
- Tests/Complex/CMakeLists.txt,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/complex.cxx: ENH: increase
- coverage
-
-2002-05-23 13:04 hoffman
-
- * Tests/: Complex/CMakeLists.txt,
- Complex/cmTestConfigureEscape.h.in,
- Complex/Executable/complex.cxx, ComplexOneConfig/CMakeLists.txt,
- ComplexOneConfig/cmTestConfigureEscape.h.in,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/CMakeLists.txt,
- ComplexRelativePaths/cmTestConfigureEscape.h.in,
- ComplexRelativePaths/Executable/complex.cxx: add a test for
- escape quotes and configure file
-
-2002-05-23 10:36 martink
-
- * bootstrap.exe, ccommand.exe: added win32 bootstrap support
-
-2002-05-23 10:34 martink
-
- * Source/: cmDSWWriter.cxx, cmMSDotNETGenerator.cxx: only add test
- target if testing is enabled and ctest is found
-
-2002-05-23 10:33 martink
-
- * Source/cmake.cxx: minor bootstap fixes
-
-2002-05-23 10:32 martink
-
- * Source/: cmElseCommand.cxx, cmIfCommand.cxx, cmIfCommand.h: adde
- less greater
-
-2002-05-22 13:20 hoffman
-
- * Source/cmAddCustomCommandCommand.cxx: ENH: add list expansion
- back
-
-2002-05-22 09:48 hoffman
-
- * Source/: cmMSDotNETGenerator.cxx, cmMSProjectGenerator.cxx,
- cmUnixMakefileGenerator.cxx: ENH: enable cxx by default if no
- languages have been enabled
-
-2002-05-22 09:48 hoffman
-
- * Source/cmSystemTools.cxx: ENH: better comment processing
-
-2002-05-22 09:47 hoffman
-
- * Source/: ctest.cxx, ctest.h: ENH: fix depend problem
-
-2002-05-18 16:09 starreveld
-
- * Modules/FindOpenGL.cmake: find openGL in Carbon
-
-2002-05-15 17:23 martink
-
- * Source/: cmake.cxx, cmake.h: added initial attempt to support
- win32 bootstrapping
-
-2002-05-15 11:11 berk
-
- * Source/cmSystemTools.cxx: RunCommand now checks whether the
- process died abnormally (on Unix)
-
-2002-05-14 08:42 andy
-
- * Modules/FindWish.cmake: Add better detection of wish 8.2
-
-2002-05-12 11:32 barre
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: add
- no_system_path option to FindProgram so that the PATH is ignored
-
-2002-05-12 11:31 barre
-
- * Source/: cmFindProgramCommand.cxx, cmFindProgramCommand.h:
- ENH/FIX: add NO_SYSTEM_PATH option + fix command usage
-
-2002-05-12 11:31 barre
-
- * Source/cmFindLibraryCommand.h: FIX: command usage
-
-2002-05-11 22:28 perera
-
- * Source/cmTarget.cxx: FIX: Remove assert since it was breaking
- IRIX builds.
-
-2002-05-10 14:06 millerjv
-
- * Source/cmTarget.cxx: FIX: Const reference to a set needs a
- const_iterator. (.NET build error)
-
-2002-05-10 13:35 perera
-
- * Source/CMakeLists.txt, Source/cmTarget.cxx, Source/cmTarget.h,
- Tests/Dependency/CMakeLists.txt,
- Tests/Dependency/Eight/CMakeLists.txt,
- Tests/Dependency/Eight/EightSrc.c,
- Tests/Dependency/Exec2/CMakeLists.txt,
- Tests/Dependency/Exec2/ExecMain.c,
- Tests/Dependency/Exec3/CMakeLists.txt,
- Tests/Dependency/Exec3/ExecMain.c,
- Tests/Dependency/Exec4/CMakeLists.txt,
- Tests/Dependency/Exec4/ExecMain.c,
- Tests/Dependency/Seven/CMakeLists.txt,
- Tests/Dependency/Seven/SevenSrc.c, Tests/LinkLine/CMakeLists.txt,
- Tests/LinkLine/Exec.c, Tests/LinkLine/One.c,
- Tests/LinkLine/Two.c: BUG: Correct some of the dependency
- analysis code. - Make sure the original link line is untouched -
- Avoid duplicating the link line when supporting version < 1.4 -
- Make sure the cyclic dependencies and such are output correctly
- in complicated cases. - Avoid outputing dependencies that are
- already satisfied on the original link line when possible.
-
-2002-05-10 08:54 king
-
- * Source/cmSystemTools.cxx: ERR: Added variable initializer.
-
-2002-05-09 09:33 hoffman
-
- * Source/: cmDSWWriter.cxx, cmMSDotNETGenerator.cxx, cmTarget.cxx,
- cmTarget.h, cmUnixMakefileGenerator.cxx: ENH: change set<string>
- to set<cmStdString> to avoid long symbols that crash ar on
- solaris
-
-2002-05-08 17:45 king
-
- * Tests/Wrapping/: CMakeLists.txt, itkWrapperConfig.cxx: ENH: Added
- coverage test for ITK_WRAP_TCL. Doesn't actually invoke CABLE.
-
-2002-05-08 17:45 king
-
- * Source/cmITKWrapTclCommand.cxx: ENH: Added dependency hack to
- support wrapping test.
-
-2002-05-08 17:37 king
-
- * Source/cmITKWrapTclCommand.cxx: BUG: Need to use
- CMAKE_CXX_COMPILER, not CXX, to get the C++ compiler name.
-
-2002-05-08 13:11 king
-
- * Source/: cmCommands.cxx, cmITKWrapTclCommand.cxx,
- cmITKWrapTclCommand.h: ENH: Added ITK Tcl wrapping command.
-
-2002-05-08 10:27 martink
-
- * Source/Makefile.borland: ENH: add clean command
-
-2002-05-08 09:05 hoffman
-
- * Source/cmake.cxx: ENH: fix cmake to work without ccommand.
-
-2002-05-08 08:46 hoffman
-
- * Source/cmBorlandMakefileGenerator.cxx: BUG: short path does not
- work on bcc32
-
-2002-05-07 11:03 hoffman
-
- * Source/CursesDialog/ccmake.cxx: ENH: add -B option to specify the
- build directory, so make edit_cache will work
-
-2002-05-07 09:11 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: WNG: remove a warning
-
-2002-05-07 09:03 hoffman
-
- * CMake.rtf: ENH: update with docs about the targets
-
-2002-05-07 09:02 hoffman
-
- * Source/: cmBorlandMakefileGenerator.cxx,
- cmNMakeMakefileGenerator.cxx, cmUnixMakefileGenerator.cxx,
- cmake.cxx: ENH: add an edit_cache target that runs ccmake or
- CMakeSetup
-
-2002-05-03 18:10 hoffman
-
- * Tests/: Complex/Library/CMakeLists.txt,
- ComplexOneConfig/Library/CMakeLists.txt,
- ComplexRelativePaths/Library/CMakeLists.txt: fix borland test
-
-2002-05-03 16:34 hoffman
-
- * Source/: cmMakefile.cxx, cmTarget.cxx, cmTarget.h: ENH: rework
- library depend stuff
-
-2002-05-03 00:27 perera
-
- * Source/CMakeLists.txt, Source/cmTarget.cxx, Source/cmTarget.h,
- Tests/Dependency/CMakeLists.txt: - bug fix where paths weren't
- being output when LIB_OUT_PATH *isn't* used - test case for above
- mentioned bug - more comments. Comments are good.
-
-2002-05-02 19:09 hoffman
-
- * Source/cmTarget.cxx: check for optimized or debug library adds
-
-2002-05-02 16:13 hoffman
-
- * Source/: cmTarget.cxx, cmTarget.h: remove canonical conversion
- for lib names
-
-2002-05-02 15:56 hoffman
-
- * Source/: cmMakefile.cxx, cmMakefile.h, cmTarget.cxx: make it
- backwards compatible with old cmake
-
-2002-05-02 15:10 hoffman
-
- * Source/CMakeLists.txt, Source/cmMakefile.cxx,
- Source/cmTarget.cxx, Tests/Complex/Library/CMakeLists.txt,
- Tests/ComplexOneConfig/Library/CMakeLists.txt,
- Tests/ComplexRelativePaths/Library/CMakeLists.txt: Debug
- optimized cache fixes
-
-2002-05-02 13:41 perera
-
- * Source/: cmTarget.cxx, cmTarget.h: BUG: The library paths should
- stay with the libraries during dependency analysis.
-
-2002-05-02 13:17 hoffman
-
- * Source/cmAddLibraryCommand.cxx, Source/cmAddLibraryCommand.h,
- Source/cmMakefile.cxx, Source/cmMakefile.h, Source/cmTarget.cxx,
- Source/cmTarget.h, Source/cmTargetLinkLibrariesCommand.cxx,
- Source/cmUnixMakefileGenerator.cxx,
- Tests/Complex/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt,
- Tests/Dependency/Exec/CMakeLists.txt,
- Tests/Dependency/Six/CMakeLists.txt: ENH: change LINK_LIBRARY to
- add to targets
-
-2002-05-02 08:54 andy
-
- * configure, configure.in: Revert to make it work again
-
-2002-05-02 08:46 andy
-
- * configure, configure.in: Improve bootstrap on UNIX. Now it
- bootstraps into a separate directory.
-
-2002-05-02 02:27 perera
-
- * Source/cmTarget.cxx: BUG: if a_LIBS_DEPENDS exists but is empty,
- there are no explicit dependencies.
-
-2002-05-01 16:33 perera
-
- * Source/cmAddLibraryCommand.cxx, Source/cmAddLibraryCommand.h,
- Source/cmMakefile.cxx, Source/cmMakefile.h, Source/cmTarget.cxx,
- Tests/Dependency/CMakeLists.txt: ENH: Make the LinkLibraries
- command contribute dependencies towards AddLibraries.
-
-2002-05-01 16:24 perera
-
- * Tests/Dependency/: CMakeLists.txt, Exec/CMakeLists.txt,
- Exec/ExecMain.c, Six/CMakeLists.txt, Six/SixASrc.c,
- Six/SixBSrc.c: ENH: Make the LinkLibraries command contribute
- dependencies towards AddLibraries.
-
-2002-05-01 14:00 perera
-
- * Source/CMakeLists.txt, Source/cmDSPWriter.cxx,
- Source/cmDSWWriter.cxx, Source/cmMSDotNETGenerator.cxx,
- Source/cmMakefile.cxx, Source/cmMakefile.h,
- Source/cmNMakeMakefileGenerator.cxx, Source/cmTarget.cxx,
- Source/cmTarget.h, Source/cmUnixMakefileGenerator.cxx,
- Tests/Dependency/CMakeLists.txt,
- Tests/Dependency/Exec/CMakeLists.txt,
- Tests/Dependency/Exec/ExecMain.c,
- Tests/Dependency/Five/CMakeLists.txt,
- Tests/Dependency/Five/FiveSrc.c,
- Tests/Dependency/Four/CMakeLists.txt,
- Tests/Dependency/Four/FourSrc.c,
- Tests/Dependency/NoDepA/CMakeLists.txt,
- Tests/Dependency/NoDepA/NoDepASrc.c,
- Tests/Dependency/NoDepB/CMakeLists.txt,
- Tests/Dependency/NoDepB/NoDepBSrc.c,
- Tests/Dependency/NoDepC/CMakeLists.txt,
- Tests/Dependency/NoDepC/NoDepCSrc.c,
- Tests/Dependency/Three/CMakeLists.txt,
- Tests/Dependency/Three/ThreeSrc.c,
- Tests/Dependency/Two/CMakeLists.txt,
- Tests/Dependency/Two/TwoSrc.c: ENH: Add library dependency
- analysis.
-
-2002-05-01 11:34 berk
-
- * Source/CursesDialog/: ccmake.cxx,
- cmCursesCacheEntryComposite.cxx, cmCursesCacheEntryComposite.h,
- cmCursesMainForm.cxx, cmCursesMainForm.h: The entry widgets are
- now created with what is initially available on the terminal.
-
-2002-05-01 10:12 berk
-
- * Source/: cmIncludeCommand.cxx, cmMakefile.cxx: Reformatted the
- error printed by cmMakefile.
-
-2002-04-30 21:48 hoffman
-
- * Source/CMakeLists.txt: ENH: allow cmake tests to be run without
- dart.
-
-2002-04-30 17:49 hoffman
-
- * CMakeLists.txt, Source/CMakeLists.txt: create tests without Dart
-
-2002-04-30 17:45 hoffman
-
- * Source/cmVTKMakeInstantiatorCommand.cxx: ENH: replace freeze with
- delete
-
-2002-04-30 16:58 hoffman
-
- * Templates/: cconfigure, cconfigure.in: ENH: remove -fPIC for AIX
- gnu
-
-2002-04-30 15:33 hoffman
-
- * Source/cmMSDotNETGenerator.cxx: ENH: fix relwithdebinfo
-
-2002-04-30 14:01 hoffman
-
- * Tests/: Complex/CMakeLists.txt, Complex/cmTestConfigure.h.in,
- Complex/Executable/complex.cxx, ComplexOneConfig/CMakeLists.txt,
- ComplexOneConfig/cmTestConfigure.h.in,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/CMakeLists.txt,
- ComplexRelativePaths/cmTestConfigure.h.in,
- ComplexRelativePaths/Executable/complex.cxx: ENH: add test for
- SEPARATE_ARGUMENTS
-
-2002-04-30 14:00 hoffman
-
- * Source/: cmCommands.cxx, cmSeparateArgumentsCommand.cxx,
- cmSeparateArgumentsCommand.h: ENH: add new command to separate
- space separated arguments
-
-2002-04-30 14:00 hoffman
-
- * Source/: cmBorlandMakefileGenerator.cxx, cmCacheManager.cxx: ENH:
- do not use count, find for map lookup
-
-2002-04-30 12:58 hoffman
-
- * Source/cmMakefile.cxx: ENH: improve speed of GetSource function
-
-2002-04-30 08:09 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: look for -l anywhere in
- link library entry not just the begining of the line
-
-2002-04-29 10:23 hoffman
-
- * Source/cmMakefile.cxx: BUG: make sure link directories are not
- duplicated
-
-2002-04-29 08:27 hoffman
-
- * Templates/: cconfigure, cconfigure.in: use multiple rpath options
- for sgi
-
-2002-04-28 16:14 perera
-
- * Source/: cmLinkLibrariesCommand.cxx,
- cmTargetLinkLibrariesCommand.cxx: ENH: Make it unnecessary to
- ever specify LINK_DIRECTORIES for any library generated in this
- project, even when LIBRARY_OUTPUT_PATH is set.
-
-2002-04-26 21:45 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: ENH: remove redirections for
- output of make commands as some things are lost
-
-2002-04-26 12:43 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: COM: just fix up a comment
-
-2002-04-26 12:42 hoffman
-
- * Templates/CCMakeSystemConfig.cmake.in: correct c flags for shared
- links
-
-2002-04-26 12:21 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx,
- Templates/CCMakeSystemConfig.cmake.in,
- Templates/CMakeSystemConfig.cmake.in: BUG: fix shared links for
- cc on hp
-
-2002-04-26 09:55 hoffman
-
- * Source/cmBuildNameCommand.cxx: ENH: fix build name
-
-2002-04-26 09:35 hoffman
-
- * Source/cmSiteNameCommand.cxx: ENH: look for nslookup and hostname
- in the right places
-
-2002-04-26 09:22 will
-
- * CMake.pdf: ENH:New pdf for CMake
-
-2002-04-26 09:17 martink
-
- * CMake.rtf: updated for 1.4
-
-2002-04-26 09:11 martink
-
- * Source/cmSourceFilesRemoveCommand.cxx: dprecated
-
-2002-04-26 08:59 martink
-
- * Source/Makefile.borland: fixed up again duh
-
-2002-04-25 16:29 martink
-
- * Source/Makefile.borland: updated to build ccommand
-
-2002-04-25 15:40 hoffman
-
- * Modules/Dart.cmake, Source/cmSiteNameCommand.cxx: fix up hostname
- for windows
-
-2002-04-25 13:09 hoffman
-
- * Source/cmake.cxx: ENH: check for mismatched generators
-
-2002-04-25 07:59 hoffman
-
- * Source/: ccommand.cxx, cmCMakeMinimumRequired.cxx,
- cmOptionCommand.cxx: WAR: remove warnings for .NET compiler
-
-2002-04-24 10:08 andy
-
- * Source/.cvsignore: Add cvsignore so that you do not see visual
- stufio files when you do cvs update
-
-2002-04-23 16:16 berk
-
- * Source/: cmake.cxx, CursesDialog/ccmake.cxx,
- CursesDialog/cmCursesMainForm.cxx,
- CursesDialog/cmCursesMainForm.h: Exit ccmake on fatal errors.
-
-2002-04-23 12:18 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: ENH: clean up depend output
-
-2002-04-23 11:33 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: ENH: add depends for utility
- targets
-
-2002-04-22 15:16 barre
-
- * Templates/CMakeNMakeWindowsSystemConfig.cmake,
- Templates/CMakeWindowsSystemConfig.cmake,
- Source/cmNMakeMakefileGenerator.cxx,
- Source/cmUnixMakefileGenerator.cxx: ENH: make CMake less
- verbose/precious
-
-2002-04-22 15:05 perera
-
- * Source/CursesDialog/: CMakeLists.txt, form/CMakeLists.txt: BUG:
- Changed from SOURCE_FILES to SET
-
-2002-04-22 14:29 barre
-
- * Source/cmNMakeMakefileGenerator.cxx: ENH: need CMAKE_LINKER_FLAGS
-
-2002-04-22 14:22 barre
-
- * Source/: cmNMakeMakefileGenerator.cxx,
- cmNMakeMakefileGenerator.h, cmUnixMakefileGenerator.cxx,
- cmUnixMakefileGenerator.h: ENH: make CMake less verbose/precious
-
-2002-04-22 14:18 martink
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt: duhZ
-
-2002-04-22 11:51 martink
-
- * Tests/: Complex/CMakeLists.txt, Complex/cmTestConfigure.h.in,
- Complex/Executable/CMakeLists.txt,
- Complex/Executable/cmVersion.h.in,
- Complex/Executable/complex.cxx, ComplexOneConfig/CMakeLists.txt,
- ComplexOneConfig/cmTestConfigure.h.in,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/cmVersion.h.in,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/CMakeLists.txt,
- ComplexRelativePaths/cmTestConfigure.h.in,
- ComplexRelativePaths/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/cmVersion.h.in,
- ComplexRelativePaths/Executable/complex.cxx: fixed for remove
- COMMAND
-
-2002-04-22 11:50 martink
-
- * Source/: CMakeLists.txt, cmCommands.cxx, cmRemoveCommand.cxx,
- cmRemoveCommand.h: updated for 1.4
-
-2002-04-19 15:28 hoffman
-
- * Source/cmTargetLinkLibrariesCommand.cxx,
- Tests/Simple/CMakeLists.txt, Tests/Simple/simple.cxx,
- Tests/Simple/simpleLib.cxx: BUG: add link directories for target
- link libraries and add a test for it
-
-2002-04-19 14:03 martink
-
- * Source/: cmAbstractFilesCommand.cxx, cmSourceFilesCommand.cxx,
- cmWrapExcludeFilesCommand.cxx: added deprecated warnings for
- version 1.4 or later
-
-2002-04-19 13:05 hoffman
-
- * Source/cmCMakeMinimumRequired.h: ENH: fix doc line
-
-2002-04-19 12:49 martink
-
- * Source/cmNMakeMakefileGenerator.cxx: renamed unix to unixPath for
- compile error
-
-2002-04-19 11:49 hoffman
-
- * Source/cmNMakeMakefileGenerator.cxx: BUG: fix short path on files
- that do not exist
-
-2002-04-19 09:00 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: try to make sure a
- depend file only has one rule
-
-2002-04-19 08:27 hoffman
-
- * Source/: cmSystemTools.cxx, cmake.cxx: BUG: fix SameFile function
- for windows, and compare source directories
-
-2002-04-18 16:13 martink
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: work with spaces in the
- path
-
-2002-04-18 15:58 andy
-
- * Source/cmUnixMakefileGenerator.cxx: Make quotes and echos to work
- on unix (hopefully)
-
-2002-04-18 15:58 andy
-
- * Modules/FindMPI.cmake: Add mpi search paths for Debian
-
-2002-04-18 14:51 hoffman
-
- * Source/cmake.cxx: ENH: use home not start
-
-2002-04-18 14:19 hoffman
-
- * Source/cmake.cxx: ENH: check for mis-matched source directories
-
-2002-04-18 13:44 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: quote the echo commands
-
-2002-04-18 13:12 hoffman
-
- * Source/cmSystemTools.cxx: BUG: do escaped semi-colon better
-
-2002-04-18 12:02 hoffman
-
- * Source/cmMessageCommand.cxx, Source/cmSystemTools.cxx,
- Tests/Complex/CMakeLists.txt,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexRelativePaths/CMakeLists.txt: ENH: add ability to
- escape semi-colons
-
-2002-04-18 11:52 martink
-
- * configure, configure.in: ENH: handle spaces in paths for cygwin
- bootstrap
-
-2002-04-18 07:58 hoffman
-
- * Source/cmCMakeMinimumRequired.cxx: BUG: add missing include
-
-2002-04-18 07:57 hoffman
-
- * Source/: CMakeLib.dsp, Makefile.borland: BUG: fix bootstrap build
- makefiles
-
-2002-04-17 16:16 hoffman
-
- * Source/cmAbstractFilesCommand.cxx,
- Source/cmAddCustomCommandCommand.cxx,
- Source/cmCMakeMinimumRequired.cxx,
- Source/cmCMakeMinimumRequired.h, Source/cmCommands.cxx,
- Source/cmOptionCommand.cxx, Tests/Complex/CMakeLists.txt,
- Tests/Complex/cmTestConfigure.h.in,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexOneConfig/cmTestConfigure.h.in,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/CMakeLists.txt,
- Tests/ComplexRelativePaths/cmTestConfigure.h.in,
- Tests/ComplexRelativePaths/Executable/complex.cxx: ENH: backwards
- compatible for VTK 4.0, add cmake version requires
-
-2002-04-17 14:58 king
-
- * Tests/Wrapping/CMakeLists.txt: ENH: Removed tests for commands
- that no longer exist.
-
-2002-04-17 14:54 king
-
- * Source/: CMakeLists.txt, Makefile.in, cmCableClassSet.cxx,
- cmCableClassSet.h, cmCableClassSetCommand.cxx,
- cmCableClassSetCommand.h, cmCableWrapTclCommand.cxx,
- cmCableWrapTclCommand.h, cmCommands.cxx,
- cmConfigureGccXmlCommand.cxx, cmConfigureGccXmlCommand.h,
- cmMakefile.cxx: ENH: Removed out-of-date commands CABLE_WRAP_TCL
- CABLE_CLASS_SET and CONFIGURE_GCCXML
-
-2002-04-17 14:52 king
-
- * Modules/FindCABLE.cmake: ENH: Updated for latest Cable from CVS.
- Old alpha version of Cable is no longer supported.
-
-2002-04-17 14:51 king
-
- * Modules/FindGCCXML.cmake: ENH: Updated for version 0.2 of
- GCC-XML.
-
-2002-04-17 14:39 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: ENH: use convert to output
- path for depend files
-
-2002-04-17 08:28 hoffman
-
- * Modules/FindOpenGL.cmake: better to find mac opengl
-
-2002-04-17 08:15 hoffman
-
- * Templates/: CCMakeSystemConfig.cmake.in,
- CXXCMakeSystemConfig.cmake.in: more advanced values
-
-2002-04-17 08:09 hoffman
-
- * Tests/: Complex/CMakeLists.txt, ComplexOneConfig/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt: ENH: more coverage
-
-2002-04-16 13:48 barre
-
- * Source/cmSystemTools.cxx: Syntax seemed to be confusing according
- to the Bill
-
-2002-04-16 09:28 barre
-
- * Source/ccommand.cxx: FIX: warning
-
-2002-04-15 09:09 hoffman
-
- * Source/cmSystemTools.cxx: use stream not sprintf
-
-2002-04-15 08:48 barre
-
- * Source/cmSystemTools.cxx: ENH: FilesDiffer checks for 0 byte
- files
-
-2002-04-14 15:32 barre
-
- * Source/cmSystemTools.cxx: ENH: more paranoid checkings
-
-2002-04-12 12:05 barre
-
- * Source/cmSystemTools.cxx: FIX: iostream binary flag should be
- used for cygwin too
-
-2002-04-12 09:57 barre
-
- * Source/cmSystemTools.cxx: FIX: fix UMR
-
-2002-04-11 18:59 barre
-
- * Source/ccommand.cxx: ENH: also displays command output
-
-2002-04-11 18:17 barre
-
- * Source/ccommand.cxx: can be used to time commands (time() &
- clock())
-
-2002-04-11 17:02 hoffman
-
- * Source/cmFindFileCommand.h, Source/cmFindLibraryCommand.h,
- Source/cmFindPathCommand.h, Source/cmFindProgramCommand.h,
- Source/cmIncludeCommand.cxx, Source/cmListFileCache.cxx,
- Source/cmMakefile.cxx, Source/cmSystemTools.cxx,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/complex.cxx: ENH: speed
- improvements
-
-2002-04-11 16:58 starreveld
-
- * Source/cmUnixMakefileGenerator.cxx:
-
- Allow modules to build properly again. (broken when Cxx testing
- was added)
-
-2002-04-11 11:30 barre
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt: ENH: increase
- coverage
-
-2002-04-11 10:29 hoffman
-
- * Source/: cmUnixMakefileGenerator.cxx, cmUnixMakefileGenerator.h:
- ENH: clean up utility rule generation
-
-2002-04-11 10:11 barre
-
- * Tests/: Complex/Library/CMakeLists.txt,
- ComplexOneConfig/Library/CMakeLists.txt,
- ComplexRelativePaths/Library/CMakeLists.txt: ENH: use target as
- source if source is empty
-
-2002-04-11 10:05 barre
-
- * Source/: cmAddCustomCommandCommand.cxx,
- cmAddCustomCommandCommand.h: ENH: use target as source if source
- is empty
-
-2002-04-11 09:53 barre
-
- * Source/: cmNMakeMakefileGenerator.cxx,
- cmUnixMakefileGenerator.cxx: FIX: echo pb, make Nmake gen use
- Unix gen, factorize stuff in Unix gen
-
-2002-04-10 17:33 barre
-
- * Tests/: Complex/Executable/complex.cxx,
- Complex/Library/CMakeLists.txt,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexOneConfig/Library/CMakeLists.txt,
- ComplexRelativePaths/Executable/complex.cxx,
- ComplexRelativePaths/Library/CMakeLists.txt: ENH: add a test to
- check if more than one post-build command can be attached. it
- fails right now.
-
-2002-04-10 16:45 andy
-
- * Source/cmUnixMakefileGenerator.cxx: Fix problem with custom
- commands on unix
-
-2002-04-10 12:13 king
-
- * Source/cmaketest.cxx: ERR: UseIt() missing return type.
-
-2002-04-10 11:23 hoffman
-
- * Tests/: Complex/Library/testConly.c,
- ComplexOneConfig/Library/testConly.c,
- ComplexRelativePaths/Library/testConly.c: ENH: only check flag on
- unix
-
-2002-04-10 08:38 hoffman
-
- * Source/cmaketest.cxx: fix warning
-
-2002-04-09 12:22 hoffman
-
- * Tests/: Complex/Library/testConly.h,
- ComplexOneConfig/Library/testConly.h,
- ComplexRelativePaths/Library/testConly.h,
- Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/complex.cxx: ENH: check for
- compile flags and add back c flag to unix generator
-
-2002-04-09 12:15 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: ENH: check for compile flags
- and add back c flag to unix generator
-
-2002-04-09 12:02 hoffman
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- Complex/Executable/complex.cxx, Complex/Library/CMakeLists.txt,
- Complex/Library/testConly.c,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexOneConfig/Library/CMakeLists.txt,
- ComplexOneConfig/Library/testConly.c,
- ComplexRelativePaths/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/complex.cxx,
- ComplexRelativePaths/Library/CMakeLists.txt,
- ComplexRelativePaths/Library/testConly.c: ENH: check for compile
- flags and add back c flag to unix generator
-
-2002-04-09 11:33 barre
-
- * DartConfig.cmake: ENH: quick stab at a rollup button
-
-2002-04-09 10:19 hoffman
-
- * Tests/: Complex/Library/testConly.c, Complex/Library/testConly.h,
- ComplexOneConfig/Library/testConly.c,
- ComplexOneConfig/Library/testConly.h,
- ComplexRelativePaths/Library/testConly.c,
- ComplexRelativePaths/Library/testConly.h: correct exports for
- windows
-
-2002-04-09 09:37 hoffman
-
- * Tests/: Complex/Library/sharedFile.h,
- ComplexOneConfig/Library/sharedFile.h,
- ComplexRelativePaths/Library/sharedFile.h: c not c++ comment
-
-2002-04-09 08:55 hoffman
-
- * DartConfig.cmake: change EST to EDT
-
-2002-04-08 19:31 biddi
-
- * Source/cmSystemTools.cxx: ERR: ReplaceString didn't work properly
- if replace was longer than with as length added to start pos on
- next search was replaceLength instead of withLength
-
-2002-04-08 15:01 hoffman
-
- * Templates/: CXXCMakeSystemConfig.cmake.in, cconfigure,
- cconfigure.in: [no log message]
-
-2002-04-08 13:36 hoffman
-
- * Source/cmExecProgramCommand.cxx,
- Source/cmUnixMakefileGenerator.cxx,
- Templates/CCMakeSystemConfig.cmake.in,
- Templates/CXXCMakeSystemConfig.cmake.in, Templates/cconfigure,
- Templates/cconfigure.in, Templates/cxxconfigure,
- Templates/cxxconfigure.in,
- Tests/Complex/Executable/CMakeLists.txt,
- Tests/Complex/Executable/complex.cxx,
- Tests/Complex/Library/CMakeLists.txt,
- Tests/Complex/Library/testConly.c,
- Tests/Complex/Library/testConly.h,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexOneConfig/Library/CMakeLists.txt,
- Tests/ComplexOneConfig/Library/testConly.c,
- Tests/ComplexOneConfig/Library/testConly.h,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Library/CMakeLists.txt,
- Tests/ComplexRelativePaths/Library/testConly.c,
- Tests/ComplexRelativePaths/Library/testConly.h: ENH: use separate
- vars for creating c++ and c shared libraries and add a test for c
- libraries
-
-2002-04-05 12:08 hoffman
-
- * Source/cmProjectCommand.cxx: expand ; args
-
-2002-04-05 10:51 martink
-
- * Modules/Dart.cmake: improved finding purify on windows to use
- registry
-
-2002-04-05 09:39 hoffman
-
- * Source/: Makefile.borland, cmaketest.cxx, cmaketest.h.in: ENH:
- make sure the test tests the right cmake, and not the cmake used
- to bootstrap this cmake
-
-2002-04-05 07:22 hoffman
-
- * Tests/TestDriver/testArgs.h: ENH: add missing file
-
-2002-04-04 16:53 hoffman
-
- * Source/cmCreateTestSourceList.cxx,
- Source/cmCreateTestSourceList.h, Tests/TestDriver/CMakeLists.txt:
- ENH: add the ability to process command line arguments in the
- test driver before the test driver gets them
-
-2002-04-04 11:01 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx,
- Templates/CXXCMakeSystemConfig.cmake.in, Templates/cxxconfigure,
- Templates/cxxconfigure.in: ENH: separate the ar program for cxx
- and c
-
-2002-04-04 10:08 hoffman
-
- * Templates/CMakeLists.txt: update install information
-
-2002-04-04 09:04 hoffman
-
- * Templates/: cxxconfigure, cxxconfigure.in: BUG: add system
- command back into script
-
-2002-04-03 16:14 hoffman
-
- * Source/cmExecProgramCommand.cxx, Source/cmExecProgramCommand.h,
- Source/cmNMakeMakefileGenerator.cxx, Source/cmSystemTools.cxx,
- Source/cmSystemTools.h, Source/cmaketest.cxx,
- Tests/Complex/CMakeLists.txt,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexRelativePaths/CMakeLists.txt: ENH: fix more space
- problems, you can add args to the ExecProgram command separatly
- now
-
-2002-04-03 13:53 andy
-
- * Modules/FindTCL.cmake: More places to find TCL/TK for example on
- Debian
-
-2002-04-02 15:42 hoffman
-
- * CMake.rtf, Example/Demo/CMakeLists.txt,
- Example/Hello/CMakeLists.txt, Source/CMakeLists.txt,
- Source/cmBorlandMakefileGenerator.cxx,
- Source/cmBorlandMakefileGenerator.h, Source/cmDSWWriter.cxx,
- Source/cmMSDotNETGenerator.cxx, Source/cmMSDotNETGenerator.h,
- Source/cmMSProjectGenerator.cxx, Source/cmMSProjectGenerator.h,
- Source/cmMakefile.cxx, Source/cmMakefile.h,
- Source/cmMakefileGenerator.cxx, Source/cmMakefileGenerator.h,
- Source/cmNMakeMakefileGenerator.cxx,
- Source/cmNMakeMakefileGenerator.h, Source/cmProjectCommand.cxx,
- Source/cmProjectCommand.h, Source/cmSetCommand.cxx,
- Source/cmSetSourceFilesPropertiesCommand.h, Source/cmTarget.cxx,
- Source/cmTarget.h, Source/cmUnixMakefileGenerator.cxx,
- Source/cmUnixMakefileGenerator.h, Source/cmake.cxx,
- Templates/cconfigure, Templates/cconfigure.in,
- Templates/cxxconfigure, Templates/cxxconfigure.in,
- Tests/COnly/CMakeLists.txt, Tests/COnly/conly.c,
- Templates/configure, Templates/configure.in,
- Templates/CCMakeSystemConfig.cmake.in,
- Templates/CXXCMakeSystemConfig.cmake.in: ENH: add enable language
- support for PROJECT command, this means that a C only project can
- be built with cmake, even without a cxx compiler
-
-2002-04-01 14:58 barre
-
- * Tests/: Complex/CMakeLists.txt, Complex/cmTestConfigure.h.in,
- ComplexOneConfig/CMakeLists.txt,
- ComplexOneConfig/cmTestConfigure.h.in,
- ComplexRelativePaths/CMakeLists.txt,
- ComplexRelativePaths/cmTestConfigure.h.in,
- Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/complex.cxx: ENH: add test for
- registry-related functions (win32)
-
-2002-04-01 14:50 hoffman
-
- * Source/cmSystemTools.cxx: ENH: fix for regkey and ; separation
-
-2002-04-01 13:34 barre
-
- * Source/: ccommand.cxx, cmSystemTools.cxx, cmSystemTools.h: ENH:
- add functions to API (read, write, delete registry key value)
-
-2002-04-01 08:08 andy
-
- * Modules/FindVTK.cmake: More finds for VTK
-
-2002-03-31 11:43 andy
-
- * Modules/FindVTK.cmake: Add some more locations of VTK
-
-2002-03-30 17:17 barre
-
- * Source/: cmAbstractFilesCommand.cxx, cmSetCommand.cxx: FIX: get
- rid of warnings
-
-2002-03-29 18:07 ibanez
-
- * Modules/FindFLTK.cmake: ENH: HAS_FLTK variable added.
- FLTK_WRAP_UI command made INTERNAL.
-
-2002-03-29 16:25 barre
-
- * Source/cmCreateTestSourceList.cxx: FIX: should compare to 0, not
- NULL
-
-2002-03-29 16:03 barre
-
- * Source/: ctest.cxx, ctest.h: ENH: if -R or -E was used, displays
- also the name of the tests that passed.
-
-2002-03-29 15:41 barre
-
- * Tests/: Complex/CMakeLists.txt, ComplexOneConfig/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt: FIX: fix dummy lib name for
- Unix
-
-2002-03-29 15:02 barre
-
- * Tests/: Complex/CMakeLists.txt, Complex/cmTestConfigure.h.in,
- Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/CMakeLists.txt,
- ComplexOneConfig/cmTestConfigure.h.in,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt,
- ComplexRelativePaths/cmTestConfigure.h.in,
- ComplexRelativePaths/Executable/CMakeLists.txt,
- Complex/Executable/complex.cxx, Complex/Library/CMakeLists.txt,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexOneConfig/Library/CMakeLists.txt,
- ComplexRelativePaths/Executable/complex.cxx,
- ComplexRelativePaths/Library/CMakeLists.txt,
- Complex/Library/cmTestLibraryConfigure.h.in,
- Complex/Library/dummy, Complex/Library/empty.h,
- Complex/Library/file2.cxx, Complex/Library/file2.h,
- ComplexOneConfig/Library/cmTestLibraryConfigure.h.in,
- ComplexOneConfig/Library/dummy, ComplexOneConfig/Library/empty.h,
- ComplexOneConfig/Library/file2.cxx,
- ComplexOneConfig/Library/file2.h,
- ComplexRelativePaths/Library/cmTestLibraryConfigure.h.in,
- ComplexRelativePaths/Library/dummy,
- ComplexRelativePaths/Library/empty.h,
- ComplexRelativePaths/Library/file2.cxx,
- ComplexRelativePaths/Library/file2.h,
- Complex/Library/fileFlags.cxx,
- ComplexOneConfig/Library/fileFlags.cxx,
- ComplexRelativePaths/Library/fileFlags.cxx: ENH: fix tests
-
-2002-03-29 14:31 hoffman
-
- * Source/cmMSDotNETGenerator.cxx: output list bug
-
-2002-03-29 14:22 hoffman
-
- * Tests/: Complex/Library/cmTestLibraryConfigure.h.in,
- ComplexOneConfig/Library/cmTestLibraryConfigure.h.in,
- ComplexRelativePaths/Library/cmTestLibraryConfigure.h.in: [no log
- message]
-
-2002-03-29 14:20 hoffman
-
- * Source/cmAbstractFilesCommand.cxx,
- Source/cmAddCustomCommandCommand.cxx,
- Source/cmAddCustomTargetCommand.cxx,
- Source/cmAddDefinitionsCommand.cxx,
- Source/cmAddDependenciesCommand.cxx, Source/cmAddTestCommand.cxx,
- Source/cmCableClassSetCommand.cxx,
- Source/cmCableWrapTclCommand.cxx, Source/cmCommands.cxx,
- Source/cmCreateTestSourceList.cxx,
- Source/cmFLTKWrapUICommand.cxx, Source/cmFindFileCommand.cxx,
- Source/cmFindLibraryCommand.cxx, Source/cmFindPathCommand.cxx,
- Source/cmFindProgramCommand.cxx,
- Source/cmGetSourceFilePropertyCommand.cxx,
- Source/cmGetSourceFilePropertyCommand.h,
- Source/cmIncludeDirectoryCommand.cxx,
- Source/cmInstallFilesCommand.cxx,
- Source/cmInstallProgramsCommand.cxx,
- Source/cmInstallTargetsCommand.cxx,
- Source/cmLinkDirectoriesCommand.cxx,
- Source/cmLoadCacheCommand.cxx, Source/cmMakeDirectoryCommand.cxx,
- Source/cmMarkAsAdvancedCommand.cxx,
- Source/cmOutputRequiredFilesCommand.cxx,
- Source/cmProjectCommand.cxx, Source/cmQTWrapCPPCommand.cxx,
- Source/cmQTWrapUICommand.cxx,
- Source/cmSetSourceFilesPropertiesCommand.cxx,
- Source/cmSetSourceFilesPropertiesCommand.h,
- Source/cmSiteNameCommand.cxx, Source/cmSourceFilesCommand.cxx,
- Source/cmSourceFilesFlagsCommand.cxx,
- Source/cmSourceFilesFlagsCommand.h,
- Source/cmSourceFilesRemoveCommand.cxx,
- Source/cmSubdirCommand.cxx, Source/cmSystemTools.cxx,
- Source/cmSystemTools.h, Source/cmUseMangledMesaCommand.cxx,
- Source/cmUseMangledMesaCommand.h,
- Source/cmUtilitySourceCommand.cxx,
- Source/cmVTKMakeInstantiatorCommand.cxx,
- Source/cmVTKWrapJavaCommand.cxx,
- Source/cmVTKWrapPythonCommand.cxx,
- Source/cmVTKWrapTclCommand.cxx,
- Source/cmVariableRequiresCommand.cxx,
- Source/cmWrapExcludeFilesCommand.cxx,
- Tests/Complex/Executable/CMakeLists.txt,
- Tests/Complex/Executable/complex.cxx,
- Tests/ComplexOneConfig/Executable/CMakeLists.txt,
- Tests/ComplexOneConfig/Executable/complex.cxx,
- Tests/ComplexRelativePaths/Executable/CMakeLists.txt,
- Tests/ComplexRelativePaths/Executable/complex.cxx,
- Tests/Complex/Library/CMakeLists.txt,
- Tests/Complex/Library/file2.cxx, Tests/Complex/Library/file2.h,
- Tests/ComplexOneConfig/Library/CMakeLists.txt,
- Tests/ComplexOneConfig/Library/file2.cxx,
- Tests/ComplexOneConfig/Library/file2.h,
- Tests/ComplexRelativePaths/Library/CMakeLists.txt,
- Tests/ComplexRelativePaths/Library/file2.cxx,
- Tests/ComplexRelativePaths/Library/file2.h: make sure ; expansion
- is done in all commands
-
-2002-03-29 11:12 hoffman
-
- * Tests/TestDriver/: CMakeLists.txt, test1.cxx, testExtraStuff.cxx,
- testExtraStuff2.cxx, testExtraStuff3.cxx: ENH: add test for set
- to create source lists
-
-2002-03-29 11:11 hoffman
-
- * Source/cmAddExecutableCommand.cxx: fix const problem
-
-2002-03-29 11:04 hoffman
-
- * Source/: cmAddExecutableCommand.cxx, cmAddLibraryCommand.cxx,
- cmSetCommand.cxx, cmSetCommand.h: ENH: add ability to use ;
- separated lists in SET and expand them for addexecutable and
- addlibrary
-
-2002-03-29 11:03 hoffman
-
- * Source/cmGetSourceFilePropertyCommand.h: fix docs
-
-2002-03-29 10:56 barre
-
- * Source/: cmMessageCommand.cxx, cmMessageCommand.h: ENH: Add
- SEND_ERROR flag to MESSAGE so that an error can be raised within
- a CMakeList file
-
-2002-03-29 10:07 hoffman
-
- * Tests/: Complex/Library/CMakeLists.txt,
- ComplexOneConfig/Library/CMakeLists.txt,
- ComplexRelativePaths/Library/CMakeLists.txt: more tests
-
-2002-03-29 10:06 hoffman
-
- * Source/: cmAbstractFilesCommand.cxx,
- cmBorlandMakefileGenerator.cxx, cmCommands.cxx,
- cmCreateTestSourceList.cxx, cmDSPWriter.cxx,
- cmFLTKWrapUICommand.cxx, cmGetSourceFilePropertyCommand.cxx,
- cmGetSourceFilePropertyCommand.h, cmInstallFilesCommand.cxx,
- cmMSDotNETGenerator.cxx, cmMakeDepend.cxx, cmMakefile.cxx,
- cmMakefile.h, cmNMakeMakefileGenerator.cxx,
- cmQTWrapCPPCommand.cxx, cmQTWrapUICommand.cxx,
- cmSetSourceFilesPropertiesCommand.cxx,
- cmSetSourceFilesPropertiesCommand.h, cmSourceFile.cxx,
- cmSourceFilesCommand.cxx, cmSourceFilesFlagsCommand.cxx,
- cmTarget.cxx, cmTarget.h, cmUnixMakefileGenerator.cxx,
- cmVTKMakeInstantiatorCommand.cxx, cmVTKWrapJavaCommand.cxx,
- cmVTKWrapPythonCommand.cxx, cmVTKWrapTclCommand.cxx,
- cmWrapExcludeFilesCommand.cxx, cmaketest.cxx, cmaketest.h.in:
- ENH: major change, the cmMakefile now contains a master list of
- cmSourceFile objects, the source lists reference the list via
- pointers, also you can now set properties on a file, like compile
- flags, abstract, etc.
-
-2002-03-29 08:42 barre
-
- * Source/cmCreateTestSourceList.cxx: FIX: tolower is in <ctype.h>
- !, frenchy
-
-2002-03-28 11:43 barre
-
- * Source/cmCreateTestSourceList.cxx: ENH: perform case insensitive
- comparison on test names
-
-2002-03-27 16:19 barre
-
- * Source/cmCreateTestSourceList.cxx: FIX: cmSourceFile::SetName was
- not called correctly for the test source files
-
-2002-03-27 15:52 barre
-
- * Source/cmCreateTestSourceList.cxx: ENH: small formatting enh
-
-2002-03-27 13:54 barre
-
- * Tests/: Complex/VarTests.cmake, Complex/cmTestConfigure.h.in,
- Complex/Executable/complex.cxx, ComplexOneConfig/VarTests.cmake,
- ComplexOneConfig/cmTestConfigure.h.in,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/VarTests.cmake,
- ComplexRelativePaths/cmTestConfigure.h.in,
- ComplexRelativePaths/Executable/complex.cxx: ENH: add a more
- stressing FOREACH test.
-
-2002-03-27 13:46 barre
-
- * Source/CMakeLists.txt, Tests/TestDriver/CMakeLists.txt,
- Tests/TestDriver/test3.cxx, Tests/TestDriver/subdir/test3.cxx:
- ENH: add testdriver test with source file in subdir
-
-2002-03-27 10:55 barre
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt: FIX: do not use
- CMAKE_CFG_INTDIR, just use LINK_DIRECTORIES
-
-2002-03-27 10:54 barre
-
- * Tests/: Testing/CMakeLists.txt, Wrapping/CMakeLists.txt: FIX: do
- not need CMakeLib
-
-2002-03-26 18:06 barre
-
- * Source/cmCreateTestSourceList.cxx: ENH: keep the name of the test
- as close to the source file (only the function name is cleaned
- up)
-
-2002-03-26 17:53 barre
-
- * Source/cmCreateTestSourceList.cxx: ENH: add -R (similar to ctest
- but use substr instead of regexp). indent.
-
-2002-03-26 16:45 barre
-
- * Source/: cmForEachCommand.h, cmFunctionBlocker.h, cmMakefile.cxx:
- FIX: foreach function-blockers were using expanded args. Add
- virtual func to specify if function blocker needs them expanded
- or not.
-
-2002-03-26 16:44 barre
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH:
- ExpandListArguments(): empty elements in semi-colon-separated
- string-list can now be ignored.
-
-2002-03-26 16:42 barre
-
- * Source/cmCreateTestSourceList.cxx: ENH: now supports tests inside
- sub-dirs
-
-2002-03-26 14:42 barre
-
- * Tests/Wrapping/CMakeLists.txt: ENH: USE_MANGLED_MESA is more
- careful now. Try to trick it again.
-
-2002-03-26 14:41 barre
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt,
- Testing/CMakeLists.txt, Wrapping/CMakeLists.txt: ENH: Use
- ${CMAKE_CFG_INTDIR} instead of hardcoded RelInfo, Debug, Release,
- etc.
-
-2002-03-26 12:55 hoffman
-
- * Source/cmUseMangledMesaCommand.cxx: ENH: add error checking for
- mmesa
-
-2002-03-26 12:38 hoffman
-
- * Source/: ccommand.cxx, cmBorlandMakefileGenerator.cxx,
- cmNMakeMakefileGenerator.cxx: ENH: use ccommand for del on
- windows
-
-2002-03-26 12:38 hoffman
-
- * Source/cmaketest.cxx: ENH: show output when running tests
-
-2002-03-26 12:37 hoffman
-
- * Source/cmCreateTestSourceList.cxx: ENH: if no arguments are given
- and there is only one test, then run it
-
-2002-03-25 17:03 martink
-
- * Source/cmake.cxx: removed quotes from cmake and ccommand
- executable to be consistant
-
-2002-03-25 16:24 barre
-
- * Source/cmForEachCommand.cxx: ENH: support semi-colon format (list
- of args as string)
-
-2002-03-25 15:59 barre
-
- * Source/: ccommand.cxx, cmSystemTools.cxx: ENH: cmCopyFile ; the
- path to the destination file will be created ; second arg can be
- a directory.
-
-2002-03-25 15:58 barre
-
- * Templates/: CMakeDotNetSystemConfig.cmake,
- CMakeWindowsSystemConfig.cmake: Add suffixes
-
-2002-03-20 16:18 hoffman
-
- * Source/CMakeLists.txt, Source/cmCommands.cxx,
- Source/cmCreateTestSourceList.cxx,
- Source/cmCreateTestSourceList.h, Source/cmaketest.cxx,
- Tests/TestDriver/CMakeLists.txt, Tests/TestDriver/test1.cxx,
- Tests/TestDriver/test2.cxx, Tests/TestDriver/test3.cxx: ENH: add
- new command to create a test driver
-
-2002-03-20 13:16 hoffman
-
- * CMakeLists.txt, Source/CMakeLists.txt: ENH: remove fltk dialog as
- it is no longer supported
-
-2002-03-19 12:25 andy
-
- * Source/ccommand.cxx: Return error on copy
-
-2002-03-18 11:59 andy
-
- * Source/ccommand.cxx: Remove warning about sign and unsigned
-
-2002-03-15 15:42 andy
-
- * Source/: CMakeLists.txt, CMakeSetup.dsw, ccommand.cxx,
- ccommand.dsp, cmake.cxx: Add ccommand for executing commands on
- the system, so by using ADD_CUSTOM_COMMAND, you can make rules to
- do some system commands during build. Currently supported
- commands are copy and remove. Others will follow.
-
-2002-03-15 13:20 perera
-
- * Source/cmSourceFilesFlagsCommand.cxx: BUG: The source file may be
- specified with an extension.
-
-2002-03-15 10:43 martink
-
- * Source/ctest.cxx: less noisy about changing directories
-
-2002-03-15 09:40 berk
-
- * Templates/CMakeSystemConfig.cmake.in: There can be multiple ansi
- flags now
-
-2002-03-15 09:23 hoffman
-
- * Templates/configure: HP add Ae flag
-
-2002-03-15 09:14 berk
-
- * Templates/configure.in: Added better support for HPux
-
-2002-03-14 16:04 hoffman
-
- * Source/cmMakefile.cxx: ENH: add .in as a header file type, as it
- can not be compiled
-
-2002-03-14 16:03 hoffman
-
- * Source/CMakeLists.txt: BUG: .h not two .cxx files
-
-2002-03-14 14:59 hoffman
-
- * Source/cmSystemTools.cxx: BUG: fix RunCommand again... back to
- system, but with GetShortPath
-
-2002-03-14 14:59 hoffman
-
- * Source/cmDSPWriter.cxx: BUG: fix for paths with spaces
-
-2002-03-14 14:58 hoffman
-
- * Source/: cmNMakeMakefileGenerator.cxx,
- cmNMakeMakefileGenerator.h: BUG: fix for files with dashes in
- them
-
-2002-03-14 11:11 hoffman
-
- * Source/: cmConfigureGccXmlCommand.cxx, cmExecProgramCommand.cxx,
- cmSystemTools.cxx, cmSystemTools.h, cmaketest.cxx, ctest.cxx:
- ENH: overhaul of RunCommand on windows, if only win32 had
- popen...
-
-2002-03-13 14:23 martink
-
- * Source/: cmDSPWriter.cxx, cmDSWWriter.cxx: ENH: closer to working
- with spaces in the path
-
-2002-03-13 10:25 hoffman
-
- * Source/: CMakeLists.txt, cmAuxSourceDirectoryCommand.cxx,
- cmCableClassSet.cxx, cmCableClassSet.h, cmDirectory.cxx,
- cmDirectory.h, cmFLTKWrapUICommand.cxx, cmFindFileCommand.cxx,
- cmFindLibraryCommand.cxx, cmFindPathCommand.cxx,
- cmFindProgramCommand.cxx, cmMSDotNETGenerator.cxx,
- cmMakefile.cxx, cmNMakeMakefileGenerator.cxx,
- cmQTWrapCPPCommand.cxx, cmQTWrapUICommand.cxx,
- cmRegularExpression.cxx, cmSourceGroup.cxx, cmSystemTools.cxx,
- cmVTKMakeInstantiatorCommand.cxx, cmVTKWrapJavaCommand.cxx,
- cmVTKWrapPythonCommand.cxx, cmVTKWrapTclCommand.cxx,
- cmaketest.cxx, ctest.cxx: ENH: remove several compiler warnings
-
-2002-03-12 10:16 king
-
- * Templates/: configure, configure.in: ENH: Added test for explicit
- instantiation support.
-
-2002-03-11 16:04 hoffman
-
- * Source/cmOptionCommand.cxx: ENH: add error checking for option
- commands with too many arguments
-
-2002-03-11 12:11 hoffman
-
- * Source/: cmMSDotNETGenerator.cxx, cmMSDotNETGenerator.h: ENH: add
- support for .def files
-
-2002-03-11 08:11 hoffman
-
- * Source/cmMSDotNETGenerator.cxx: BUG: make sure libraries do not
- depend on themselves
-
-2002-03-10 18:24 hoffman
-
- * Templates/: configure, configure.in: ENH: try to get crazy dec
- cxx to work again... one more time
-
-2002-03-10 10:02 hoffman
-
- * Templates/: configure, configure.in: ENH: try to get crazy dec
- cxx to work again...
-
-2002-03-08 13:12 hoffman
-
- * Tests/: Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/complex.cxx: ENH: more dec silly
- stuff
-
-2002-03-08 11:01 hoffman
-
- * Tests/: Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/complex.cxx: more stupid dec cxx
- tricks...
-
-2002-03-08 08:19 hoffman
-
- * Tests/: Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/complex.cxx: ENH: add one more
- stupid function call for the dec cxx compiler...
-
-2002-03-08 07:25 hoffman
-
- * Tests/: Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/complex.cxx: try to fix dec cxx
-
-2002-03-07 22:07 hoffman
-
- * Tests/: Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/complex.cxx: ENH: add more junk
- for the dec cxx compiler to force it to instantiate stuff
-
-2002-03-07 12:13 hoffman
-
- * Tests/: Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/complex.cxx: ENH: use the string
- class to force the dec compiler to instantiate some templates
-
-2002-03-07 10:41 barre
-
- * Source/CMakeLists.txt: Build cmaketest even if testing if OFF (so
- that it can be used externally)
-
-2002-03-06 17:58 barre
-
- * Source/: ctest.cxx, ctest.h: ENH: add -E option (exclude tests
- matching a regexp)
-
-2002-03-06 16:30 barre
-
- * Source/: CMakeLists.txt, cmaketest.cxx: ENH: add cmaketest to
- install targets (so that it can be used in other projects) and
- pass the rest of its command-line args to cmake
-
-2002-03-06 10:44 hoffman
-
- * Templates/CMakeNMakeWindowsSystemConfig.cmake: build type should
- not be advanced
-
-2002-03-06 10:11 hoffman
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt: ENH: add test for
- semi-colon separated lists of libraries
-
-2002-03-06 10:10 hoffman
-
- * Source/: cmLinkLibrariesCommand.cxx, cmMSDotNETGenerator.cxx,
- cmSystemTools.cxx, cmSystemTools.h,
- cmTargetLinkLibrariesCommand.cxx: ENH: add suport for semi-colon
- separated list variables
-
-2002-03-05 18:41 hoffman
-
- * Source/: cmAddCustomCommandCommand.cxx,
- cmAddCustomTargetCommand.cxx, cmAddDefinitionsCommand.cxx,
- cmAddDependenciesCommand.cxx, cmAddExecutableCommand.cxx,
- cmAddLibraryCommand.cxx, cmAddTestCommand.cxx,
- cmBuildCommand.cxx, cmCableClassSetCommand.cxx,
- cmCableWrapTclCommand.cxx, cmConfigureFileCommand.cxx,
- cmElseCommand.cxx, cmEndIfCommand.cxx, cmExecProgramCommand.cxx,
- cmFindFileCommand.cxx, cmFindLibraryCommand.cxx,
- cmFindPathCommand.cxx, cmFindProgramCommand.cxx,
- cmGetFilenameComponentCommand.cxx, cmIfCommand.cxx,
- cmIncludeCommand.cxx, cmIncludeExternalMSProjectCommand.cxx,
- cmInstallFilesCommand.cxx, cmInstallProgramsCommand.cxx,
- cmLoadCacheCommand.cxx, cmMakeDirectoryCommand.cxx,
- cmMakefile.cxx, cmMessageCommand.cxx, cmOptionCommand.cxx,
- cmOutputRequiredFilesCommand.cxx, cmSetCommand.cxx,
- cmSourceFilesCommand.cxx, cmSubdirCommand.cxx, cmSystemTools.cxx,
- cmUnixMakefileGenerator.cxx, cmUseMangledMesaCommand.cxx,
- cmVTKMakeInstantiatorCommand.cxx: ENH: expand variables in
- arguments before the commands get them
-
-2002-03-05 18:25 hoffman
-
- * Source/cmSystemTools.cxx: BUG: get the correct return value from
- pclose
-
-2002-03-04 15:00 hoffman
-
- * Tests/: Complex/Library/fileFlags.cxx,
- ComplexOneConfig/Library/fileFlags.cxx,
- ComplexRelativePaths/Library/fileFlags.cxx: ENH: add support for
- per file flags
-
-2002-03-04 14:12 hoffman
-
- * Source/: cmCommands.cxx, cmDSPWriter.cxx, cmDSPWriter.h,
- cmMSDotNETGenerator.cxx, cmMSDotNETGenerator.h, cmSourceFile.h,
- cmSourceGroup.cxx, cmSourceGroup.h, cmUnixMakefileGenerator.cxx,
- cmSourceFilesFlagsCommand.cxx, cmSourceFilesFlagsCommand.h: ENH:
- add file specific compile flags
-
-2002-03-04 14:11 hoffman
-
- * Tests/: Complex/Library/CMakeLists.txt,
- ComplexOneConfig/Library/CMakeLists.txt,
- ComplexRelativePaths/Library/CMakeLists.txt: ENH: add a test for
- per file flags
-
-2002-03-01 15:49 king
-
- * Source/: cmVTKMakeInstantiatorCommand.cxx,
- cmVTKMakeInstantiatorCommand.h: ENH: Added support for including
- extra files in generated header to get access to export macros of
- derived projects.
-
-2002-03-01 09:00 hoffman
-
- * Templates/: CMakeBorlandWindowsSystemConfig.cmake,
- CMakeDotNetSystemConfig.cmake,
- CMakeNMakeWindowsSystemConfig.cmake, CMakeSystemConfig.cmake.in,
- CMakeWindowsSystemConfig.cmake, configure, configure.in: ENH: add
- some OS/compiler variables
-
-2002-02-28 15:58 hoffman
-
- * Modules/Dart.cmake: ENH: add VERBOSE_BUILD to options
-
-2002-02-28 15:57 hoffman
-
- * Source/cmakewizard.cxx: check bool values and prefere off
-
-2002-02-28 15:42 hoffman
-
- * Source/: cmMSDotNETGenerator.cxx, cmMSDotNETGenerator.h: use xml
- output quotes for paths
-
-2002-02-28 15:06 hoffman
-
- * Templates/: configure, configure.in: change hp checks to all hps
- and not just version 10
-
-2002-02-28 11:15 hoffman
-
- * Source/cmSystemTools.cxx: BUG: look for exe path as well.
-
-2002-02-28 10:41 hoffman
-
- * Source/cmSystemTools.cxx: ENH: look for .com files before .exe
-
-2002-02-28 08:45 hoffman
-
- * Templates/CMakeDotNetSystemConfig.cmake: find path to devenv
-
-2002-02-28 07:50 hoffman
-
- * Templates/CMakeDotNetSystemConfig.cmake: ENH: add build name to
- the cache with a default value for dot net
-
-2002-02-27 18:11 hoffman
-
- * Source/cmMSDotNETGenerator.cxx, Source/cmSystemTools.cxx,
- Templates/CMakeDotNetSystemConfig.cmake: clean up in dot net
-
-2002-02-26 15:15 hoffman
-
- * Source/: ctest.cxx, ctest.h: add command line option -D for
- config directory to run
-
-2002-02-26 15:14 hoffman
-
- * Source/: cmDSWWriter.cxx, cmMSDotNETGenerator.cxx: ENH: add
- RUN_TESTS
-
-2002-02-26 11:46 barre
-
- * Source/cmAddTestCommand.cxx: FIX: command now expands args during
- the first pass (found through FOREACH example)
-
-2002-02-26 10:11 hoffman
-
- * Templates/CMakeDotNetSystemConfig.cmake: [no log message]
-
-2002-02-26 08:56 hoffman
-
- * Source/cmCableClassSet.cxx: BUG: fix type problem size_type is
- unsigned
-
-2002-02-25 18:14 hoffman
-
- * Source/: cmBuildCommand.cxx, cmDirectory.h,
- cmMSDotNETGenerator.cxx, cmMSDotNETGenerator.h,
- cmRegularExpression.h, cmSystemTools.cxx: ENH: dot net almost
- working
-
-2002-02-25 16:57 barre
-
- * Source/cmAddExecutableCommand.cxx: FIX: command now expands *all*
- args (found through FOREACH example)
-
-2002-02-25 15:22 barre
-
- * Tests/Testing/: CMakeLists.txt, Sub/CMakeLists.txt,
- Sub/Sub2/CMakeLists.txt, Sub/Sub2/testing2.cxx: ENH: provide a
- test for today's ReadListFile() bug fix
-
-2002-02-25 15:06 barre
-
- * Source/cmMakefile.cxx: FIX: although a CMakeLists.txt file could
- be searched up 'n' level in the directory tree, ReadListFile()
- always implied a CMakeLists.txt file was up *one* level.
-
-2002-02-25 13:20 hoffman
-
- * Modules/FindDart.cmake: ENH: look for Dart in c:
-
-2002-02-25 11:58 barre
-
- * Source/cmSubdirCommand.cxx: ENH: Expand vars in SUBDIRS
-
-2002-02-25 10:47 hoffman
-
- * Source/cmSystemTools.cxx: BUG: fix remove of cygdrive path stuff
-
-2002-02-23 10:00 king
-
- * Source/cmSystemTools.cxx: ERR: std::ios::binary is only needed
- for Windows platforms, and isn't supported for all UNIX
- platforms.
-
-2002-02-22 15:40 hoffman
-
- * Source/: cmAddTestCommand.cxx, cmSystemTools.cxx,
- cmUnixMakefileGenerator.cxx: ENH: fix for spaces in paths on unix
-
-2002-02-22 13:38 hoffman
-
- * Source/: cmBorlandMakefileGenerator.cxx, cmDSPWriter.cxx,
- cmExecProgramCommand.cxx, cmMSDotNETGenerator.cxx,
- cmNMakeMakefileGenerator.cxx, cmNMakeMakefileGenerator.h,
- cmSystemTools.cxx, cmSystemTools.h, cmUnixMakefileGenerator.cxx,
- cmUnixMakefileGenerator.h, cmaketest.cxx: ENH: big change in the
- path handling, one function CreateOutputPath is used to escape
- spaces and convert to the native path type
-
-2002-02-22 10:08 king
-
- * Source/cmSystemTools.cxx: ENH: Another attempt at getting
- cmCopyFile to work correctly. The previous implementation was
- correct, but didn't work on HPUX due to stream library bugs.
- This implementation will hopefully work everywhere.
-
-2002-02-21 17:32 hoffman
-
- * Source/cmSystemTools.cxx: BUG: fix copy file for HP
-
-2002-02-21 16:06 barre
-
- * Source/: ctest.cxx, ctest.h: ENH: Since each test can send a lot
- of text to stderr/stdout, ctest now displays the list of tests
- that failed at the end of the process.
-
-2002-02-21 15:55 hoffman
-
- * Source/: cmBorlandMakefileGenerator.cxx,
- cmBorlandMakefileGenerator.h, cmNMakeMakefileGenerator.cxx,
- cmUnixMakefileGenerator.cxx, cmUnixMakefileGenerator.h: ENH: add
- a virtual CreateMakeVariable to shorten makefile variables for
- borland make
-
-2002-02-21 08:53 berk
-
- * Source/cmake.dsp: Argh
-
-2002-02-21 08:43 hoffman
-
- * Source/cmaketest.cxx: add ifdef for windows function
-
-2002-02-20 15:26 hoffman
-
- * Source/: cmMSDotNETGenerator.cxx, cmaketest.cxx: close to dot net
- working
-
-2002-02-20 09:16 berk
-
- * Source/cmake.dsp: Bill forgot to add a library to the release
- target.
-
-2002-02-19 17:56 hoffman
-
- * Source/: cmMSDotNETGenerator.cxx, cmMSDotNETGenerator.h: ENH:
- getting closer
-
-2002-02-19 11:53 hoffman
-
- * Source/: Makefile.borland, CMakeLists.txt: ENH: add dotnet stuff
-
-2002-02-19 09:43 hoffman
-
- * Source/: CMakeLib.dsp, CMakeLists.txt: add dot net stuff to
- cmakelists file and dsp file
-
-2002-02-18 17:41 hoffman
-
- * Source/: cmMSDotNETGenerator.cxx, cmMSDotNETGenerator.h,
- cmSLNWriter.cxx, cmSLNWriter.h, cmVCProjWriter.cxx,
- cmVCProjWriter.h: getting closer but still not working dot net
- support
-
-2002-02-18 14:36 hoffman
-
- * Source/: CMakeLib.dsp, cmMSDotNETGenerator.cxx,
- cmMSDotNETGenerator.h, cmSLNWriter.cxx, cmSLNWriter.h,
- cmSystemTools.cxx, cmVCProjWriter.cxx, cmVCProjWriter.h,
- cmake.cxx, cmake.dsp: ENH: first pass at dot net support
-
-2002-02-18 14:09 hoffman
-
- * Source/: cmBorlandMakefileGenerator.cxx,
- cmUnixMakefileGenerator.cxx: ENH: fix for borland tlib files with
- dash in them problem.
-
-2002-02-14 10:03 hoffman
-
- * Source/: cmUnixMakefileGenerator.cxx, cmUnixMakefileGenerator.h:
- ENH: only depend subdir builds on TARGETS, not all sub dir
- operations, we do not want to build when doing a make depend
-
-2002-02-14 10:01 hoffman
-
- * configure, configure.in, Templates/configure,
- Templates/configure.in: ENH: do not use O2 g as default flags
-
-2002-02-14 09:31 barre
-
- * DartConfig.cmake: ENH: Add PROJECT_URL
-
-2002-02-13 18:57 barre
-
- * DartConfig.cmake: ENH: Doxygen page
-
-2002-02-13 18:50 barre
-
- * Utilities/Doxygen/doc_makeall.sh.in: FIX: remove that good ol'
- exit 0;
-
-2002-02-13 18:32 barre
-
- * Utilities/Doxygen/doc_makeall.sh.in: FIX: update html archive
- filename
-
-2002-02-13 18:28 barre
-
- * Utilities/Doxygen/: CMakeLists.txt, authors.txt,
- doc_makeall.sh.in, doxyfile.in: ENH: Contribution graphs
-
-2002-02-13 16:17 barre
-
- * Source/CursesDialog/form/.NoDartCoverage: This dir should not be
- covered (form distrib)
-
-2002-02-12 17:38 barre
-
- * Tests/Wrapping/: CMakeLists.txt, dummy: ENH: Trick VTK_WRAP_JAVA
- in a better way (avoid CUSTOM_TARGET)
-
-2002-02-08 15:52 hoffman
-
- * Source/cmSystemTools.cxx: BUG: fix CollapseFullPath so a trailing
- slash is not added to directories
-
-2002-02-07 11:39 andy
-
- * Templates/CMakeSystemConfig.cmake.in: ERR: Cache bigendian
-
-2002-02-07 11:28 martink
-
- * Source/cmMakefile.h: next patch
-
-2002-02-07 11:27 martink
-
- * Templates/CMakeSystemConfig.cmake.in: value needed to be cached
-
-2002-02-06 12:14 hoffman
-
- * Source/cmake.cxx: ENH: add ends at end of string
-
-2002-02-06 10:50 hoffman
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: add bool return
- value so diagnostics are easier
-
-2002-02-06 10:42 hoffman
-
- * Source/cmAuxSourceDirectoryCommand.cxx: BUG: remove depend on
- directory because it is not supported by all makes
-
-2002-02-04 22:00 hoffman
-
- * Source/CursesDialog/CMakeLists.txt: ENH: use target link
- libraries and add the link directory for cmform
-
-2002-02-04 18:41 barre
-
- * Modules/: Documentation.cmake, FindGnuplot.cmake: Add module to
- find gnuplot
-
-2002-02-04 08:28 iscott
-
- * Source/cmAuxSourceDirectoryCommand.cxx: the generated
- makefiles/DSPfiles now depend on the aux source directory's last
- modified date.
-
-2002-02-01 13:08 berk
-
- * Source/cmake.cxx: Using cmSystemTools::Error() instead of cerr.
-
-2002-02-01 13:07 berk
-
- * Source/cmUnixMakefileGenerator.cxx: Better support for parallel
- builds. Subdirs depend on their parent.
-
-2002-02-01 09:28 hoffman
-
- * CMakeLists.txt, Source/CMakeLists.txt: use CMake_SOURCE and not
- CMAKE_ROOT
-
-2002-01-31 15:16 blezek
-
- * Modules/FindPythonLibs.cmake: ENH: Adding search path's for
- PYTHON_LIBRARY
-
-2002-01-31 10:32 hoffman
-
- * Source/: CMakeLists.txt, CursesDialog/CMakeLists.txt: try to get
- this working for dec cxx default compiler options
-
-2002-01-30 11:23 hoffman
-
- * Source/cmStandardIncludes.h: ENH: fix for dec compiler, they
- still do not have the correct ansi stream library
-
-2002-01-25 09:06 king
-
- * Source/CursesDialog/form/: fld_def.c, frm_data.c, frm_def.c,
- frm_driver.c: ERR: Corrected assertions of pointers to remove
- warnings.
-
-2002-01-24 14:15 berk
-
- * Source/cmSystemTools.cxx: BUG: fix for network paths
-
-2002-01-23 11:58 hoffman
-
- * Source/cmMakefile.h: patch 2 release to fix dsp header problem
-
-2002-01-23 11:52 hoffman
-
- * Source/cmDSPWriter.cxx: BUG: allow .h files to be added to the
- sources
-
-2002-01-23 10:56 barre
-
- * Source/cmaketest.cxx: ENH: run CMake a second time. The first
- time it is run, some cache values are computed. The second time
- it is run, some commands check if the value is already in the
- cache and return that value instead of re-computing it. Therefore
- this ENH: a) make sure that this specific code is tested, b)
- increase coverage.
-
-2002-01-22 17:18 king
-
- * Modules/FindVTK.cmake: ENH: Added option of disabling error
- message when VTK is not found.
-
-2002-01-22 15:55 barre
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- Complex/Executable/complex.cxx,
- Complex/Executable/Temp/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexOneConfig/Executable/Temp/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/complex.cxx,
- ComplexRelativePaths/Executable/Temp/CMakeLists.txt,
- Testing/CMakeLists.txt, Testing/Sub/CMakeLists.txt: Just rename
- dir
-
-2002-01-22 15:50 barre
-
- * Tests/: Complex/CMakeCache.txt, ComplexOneConfig/CMakeCache.txt,
- ComplexRelativePaths/CMakeCache.txt, Complex/CMakeLists.txt,
- Complex/Cache/CMakeCache.txt, ComplexOneConfig/CMakeLists.txt,
- ComplexOneConfig/Cache/CMakeCache.txt,
- ComplexRelativePaths/CMakeLists.txt,
- ComplexRelativePaths/Cache/CMakeCache.txt: ENH: Move
- CMakeCache.txt to Cache/ directory to avoid any in-source build
- pb.
-
-2002-01-22 14:15 millerjv
-
- * Modules/Dart.cmake: ENH: New variables CVS_UPDATE_OPTIONS,
- DART_TESTING_TIMEOUT
-
-2002-01-22 13:30 barre
-
- * Tests/: Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt,
- Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/complex.cxx: Coverage for
- OUTPUT_REQUIRED_FILES
-
-2002-01-22 10:17 king
-
- * Source/: cmCacheManager.cxx, cmCacheManager.h,
- cmLoadCacheCommand.cxx, cmMakefile.cxx, cmake.cxx: ERR: Removed
- cmCacheManager::DefineCache method. It is no longer needed.
-
-2002-01-22 07:37 hoffman
-
- * Tests/: Complex/CMakeLists.txt, ComplexOneConfig/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt: flags already there, just
- not working
-
-2002-01-22 07:18 hoffman
-
- * Tests/: Complex/CMakeLists.txt, ComplexOneConfig/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt: BUG: must use ANSI flags for
- complex test now.
-
-2002-01-21 15:30 barre
-
- * Tests/: Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/complex.cxx: Add warnings/infos
-
-2002-01-21 15:30 barre
-
- * Tests/Wrapping/CMakeLists.txt: Add coverage for
- VTK_MAKE_INSTANTIATOR
-
-2002-01-21 15:30 will
-
- * Source/: cmAbstractFilesCommand.cxx, cmAbstractFilesCommand.h,
- cmAddCustomCommandCommand.cxx, cmAddCustomCommandCommand.h,
- cmAddCustomTargetCommand.cxx, cmAddCustomTargetCommand.h,
- cmAddDefinitionsCommand.cxx, cmAddDefinitionsCommand.h,
- cmAddDependenciesCommand.cxx, cmAddDependenciesCommand.h,
- cmAddExecutableCommand.cxx, cmAddExecutableCommand.h,
- cmAddLibraryCommand.cxx, cmAddLibraryCommand.h,
- cmAddTestCommand.cxx, cmAddTestCommand.h,
- cmAuxSourceDirectoryCommand.cxx, cmAuxSourceDirectoryCommand.h,
- cmBorlandMakefileGenerator.cxx, cmBorlandMakefileGenerator.h,
- cmBuildCommand.cxx, cmBuildCommand.h, cmBuildNameCommand.cxx,
- cmBuildNameCommand.h, cmCableClassSet.cxx, cmCableClassSet.h,
- cmCableClassSetCommand.cxx, cmCableClassSetCommand.h,
- cmCableWrapTclCommand.cxx, cmCableWrapTclCommand.h,
- cmCacheManager.cxx, cmCacheManager.h, cmCommand.h,
- cmCommands.cxx, cmCommands.h, cmConfigureFileCommand.cxx,
- cmConfigureFileCommand.h, cmConfigureGccXmlCommand.cxx,
- cmConfigureGccXmlCommand.h, cmCustomCommand.cxx,
- cmCustomCommand.h, cmDSPWriter.cxx, cmDSPWriter.h,
- cmDSWWriter.cxx, cmDSWWriter.h, cmData.h, cmDirectory.cxx,
- cmDirectory.h, cmDumpDocumentation.cxx, cmElseCommand.cxx,
- cmElseCommand.h, cmEnableTestingCommand.cxx,
- cmEnableTestingCommand.h, cmEndForEachCommand.cxx,
- cmEndForEachCommand.h, cmEndIfCommand.cxx, cmEndIfCommand.h,
- cmExecProgramCommand.cxx, cmExecProgramCommand.h,
- cmFLTKWrapUICommand.cxx, cmFLTKWrapUICommand.h,
- cmFindFileCommand.cxx, cmFindFileCommand.h,
- cmFindLibraryCommand.cxx, cmFindLibraryCommand.h,
- cmFindPathCommand.cxx, cmFindPathCommand.h,
- cmFindProgramCommand.cxx, cmFindProgramCommand.h,
- cmForEachCommand.cxx, cmForEachCommand.h, cmFunctionBlocker.h,
- cmGeneratedFileStream.h, cmGetFilenameComponentCommand.cxx,
- cmGetFilenameComponentCommand.h, cmIfCommand.cxx, cmIfCommand.h,
- cmIncludeCommand.cxx, cmIncludeCommand.h,
- cmIncludeDirectoryCommand.cxx, cmIncludeDirectoryCommand.h,
- cmIncludeExternalMSProjectCommand.cxx,
- cmIncludeExternalMSProjectCommand.h,
- cmIncludeRegularExpressionCommand.cxx,
- cmIncludeRegularExpressionCommand.h, cmInstallFilesCommand.cxx,
- cmInstallFilesCommand.h, cmInstallProgramsCommand.cxx,
- cmInstallProgramsCommand.h, cmInstallTargetsCommand.cxx,
- cmInstallTargetsCommand.h, cmLinkDirectoriesCommand.cxx,
- cmLinkDirectoriesCommand.h, cmLinkLibrariesCommand.cxx,
- cmLinkLibrariesCommand.h, cmListFileCache.cxx, cmListFileCache.h,
- cmLoadCacheCommand.cxx, cmLoadCacheCommand.h,
- cmMSProjectGenerator.cxx, cmMSProjectGenerator.h,
- cmMakeDepend.cxx, cmMakeDepend.h, cmMakeDirectoryCommand.cxx,
- cmMakeDirectoryCommand.h, cmMakefile.cxx, cmMakefile.h,
- cmMakefileGenerator.cxx, cmMakefileGenerator.h,
- cmMarkAsAdvancedCommand.cxx, cmMarkAsAdvancedCommand.h,
- cmMessageCommand.cxx, cmMessageCommand.h,
- cmNMakeMakefileGenerator.cxx, cmNMakeMakefileGenerator.h,
- cmOptionCommand.cxx, cmOptionCommand.h,
- cmOutputRequiredFilesCommand.cxx, cmOutputRequiredFilesCommand.h,
- cmProjectCommand.cxx, cmProjectCommand.h, cmQTWrapCPPCommand.cxx,
- cmQTWrapCPPCommand.h, cmQTWrapUICommand.cxx, cmQTWrapUICommand.h,
- cmRegularExpression.cxx, cmRegularExpression.h, cmSetCommand.cxx,
- cmSetCommand.h, cmSiteNameCommand.cxx, cmSiteNameCommand.h,
- cmSourceFile.cxx, cmSourceFile.h, cmSourceFilesCommand.cxx,
- cmSourceFilesCommand.h, cmSourceFilesRemoveCommand.cxx,
- cmSourceFilesRemoveCommand.h, cmSourceGroup.cxx, cmSourceGroup.h,
- cmSourceGroupCommand.cxx, cmSourceGroupCommand.h,
- cmStandardIncludes.h, cmSubdirCommand.cxx, cmSubdirCommand.h,
- cmSubdirDependsCommand.cxx, cmSubdirDependsCommand.h,
- cmSystemTools.cxx, cmSystemTools.h, cmTarget.cxx, cmTarget.h,
- cmTargetLinkLibrariesCommand.cxx, cmTargetLinkLibrariesCommand.h,
- cmUnixMakefileGenerator.cxx, cmUnixMakefileGenerator.h,
- cmUseMangledMesaCommand.cxx, cmUseMangledMesaCommand.h,
- cmUtilitySourceCommand.cxx, cmUtilitySourceCommand.h,
- cmVTKMakeInstantiatorCommand.cxx, cmVTKMakeInstantiatorCommand.h,
- cmVTKWrapJavaCommand.cxx, cmVTKWrapJavaCommand.h,
- cmVTKWrapPythonCommand.cxx, cmVTKWrapPythonCommand.h,
- cmVTKWrapTclCommand.cxx, cmVTKWrapTclCommand.h,
- cmVariableRequiresCommand.cxx, cmVariableRequiresCommand.h,
- cmWrapExcludeFilesCommand.cxx, cmWrapExcludeFilesCommand.h,
- cmake.cxx, cmake.h, cmakemain.cxx, cmaketest.cxx,
- cmakewizard.cxx, cmakewizard.h, ctest.cxx, ctest.h,
- CursesDialog/ccmake.cxx, CursesDialog/cmCursesBoolWidget.cxx,
- CursesDialog/cmCursesBoolWidget.h,
- CursesDialog/cmCursesCacheEntryComposite.cxx,
- CursesDialog/cmCursesCacheEntryComposite.h,
- CursesDialog/cmCursesDummyWidget.cxx,
- CursesDialog/cmCursesDummyWidget.h,
- CursesDialog/cmCursesFilePathWidget.cxx,
- CursesDialog/cmCursesFilePathWidget.h,
- CursesDialog/cmCursesForm.cxx, CursesDialog/cmCursesForm.h,
- CursesDialog/cmCursesLabelWidget.cxx,
- CursesDialog/cmCursesLabelWidget.h,
- CursesDialog/cmCursesLongMessageForm.cxx,
- CursesDialog/cmCursesLongMessageForm.h,
- CursesDialog/cmCursesMainForm.cxx,
- CursesDialog/cmCursesMainForm.h,
- CursesDialog/cmCursesPathWidget.cxx,
- CursesDialog/cmCursesPathWidget.h,
- CursesDialog/cmCursesStandardIncludes.h,
- CursesDialog/cmCursesStringWidget.cxx,
- CursesDialog/cmCursesStringWidget.h,
- CursesDialog/cmCursesWidget.cxx, CursesDialog/cmCursesWidget.h:
- ENH:Updated copyright
-
-2002-01-21 15:11 will
-
- * Copyright.txt: ENH:Formal copyright notice
-
-2002-01-21 11:39 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: remove warning from hpux
- make
-
-2002-01-21 10:38 hoffman
-
- * Source/cmaketest.cxx: ENH: check the return value of the test
- program to be run
-
-2002-01-21 10:22 barre
-
- * Tests/: Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/complex.cxx: Comment test
- OUTPUT_REQUIRED
-
-2002-01-21 10:11 hoffman
-
- * Source/: cmSourceFile.cxx, cmSourceFilesCommand.cxx,
- cmSourceFilesRemoveCommand.cxx: BUG: fix generated files with no
- extension bug
-
-2002-01-20 02:21 barre
-
- * Tests/: Complex/VarTests.cmake, ComplexOneConfig/VarTests.cmake,
- ComplexRelativePaths/VarTests.cmake: More IF coverage
-
-2002-01-20 01:58 barre
-
- * Tests/: Complex/CMakeLists.txt, ComplexOneConfig/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt, Complex/VarTests.cmake,
- ComplexOneConfig/VarTests.cmake,
- ComplexRelativePaths/VarTests.cmake,
- Complex/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt,
- Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/complex.cxx,
- Complex/Library/CMakeLists.txt,
- ComplexOneConfig/Library/CMakeLists.txt,
- ComplexRelativePaths/Library/CMakeLists.txt,
- Complex/Library/empty.h, ComplexOneConfig/Library/empty.h,
- ComplexRelativePaths/Library/empty.h, Testing/CMakeLists.txt,
- Wrapping/vtkExcluded.h, Wrapping/vtkIncluded.h: Increase
- Coverage.
-
-2002-01-20 01:05 barre
-
- * Tests/Wrapping/: CMakeLists.txt, fltk1.fl: Add coverage for QT
- and FLTK wrappers. Also MANGLED_MESA
-
-2002-01-20 00:12 barre
-
- * Tests/: Complex/CMakeCache.txt, Complex/CMakeLists.txt,
- Complex/VarTests.cmake, Complex/cmTestConfigure.h.in,
- ComplexOneConfig/CMakeCache.txt, ComplexOneConfig/CMakeLists.txt,
- ComplexOneConfig/VarTests.cmake,
- ComplexOneConfig/cmTestConfigure.h.in,
- ComplexRelativePaths/CMakeCache.txt,
- ComplexRelativePaths/CMakeLists.txt,
- ComplexRelativePaths/VarTests.cmake,
- ComplexRelativePaths/cmTestConfigure.h.in,
- Complex/Executable/CMakeLists.txt,
- Complex/Executable/complex.cxx, Complex/Library/CMakeLists.txt,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexOneConfig/Library/CMakeLists.txt,
- ComplexRelativePaths/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/complex.cxx,
- ComplexRelativePaths/Library/CMakeLists.txt: More tests +
- coverage
-
-2002-01-20 00:11 barre
-
- * Tests/Testing/: CMakeLists.txt, DartConfig.cmake: More coverage +
- include Dart.cmake to maximize chance nslookup/hostname are found
-
-2002-01-20 00:11 barre
-
- * Tests/Wrapping/: CMakeLists.txt, hints, vtkExcluded.cxx,
- vtkExcluded.h, vtkIncluded.cxx, vtkIncluded.h: Add test for
- VTK_WRAP_*
-
-2002-01-20 00:06 barre
-
- * Source/cmLoadCacheCommand.h: Typo
-
-2002-01-19 21:24 barre
-
- * Tests/: Complex/CMakeLists.txt, Complex/VarTests.cmake,
- Complex/cmTestConfigure.h.in, Complex/Executable/CMakeLists.txt,
- Complex/Executable/complex.cxx, Complex/Library/CMakeLists.txt,
- ComplexOneConfig/CMakeLists.txt, ComplexOneConfig/VarTests.cmake,
- ComplexOneConfig/cmTestConfigure.h.in,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexOneConfig/Library/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt,
- ComplexRelativePaths/VarTests.cmake,
- ComplexRelativePaths/cmTestConfigure.h.in,
- ComplexRelativePaths/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/complex.cxx,
- ComplexRelativePaths/Library/CMakeLists.txt,
- Testing/CMakeLists.txt, Testing/testing.cxx,
- Wrapping/CMakeLists.txt, Wrapping/wrapping.cxx: Add
- documentation, comments. Move some 'Complex' sub-tests into 2 new
- 'Wrapping' and 'Testing' tests.
-
-2002-01-19 21:23 barre
-
- * Source/CMakeLists.txt: Add 2 new tests
-
-2002-01-19 21:22 barre
-
- * Source/cmSiteNameCommand.cxx: FIX: if the 'hostname' and
- 'nslookup' commands were not found from their HOSTNAME and
- NSLOOKUP cache definition, hard-coded values were used instead,
- thus causing pb if the corresponding progs were not in the PATH
- (RunCommand). Now use FindProgram() to be sure to find both,
- otherwise do nothing and set the site name to "unknown"
- (arbitrary. could be empty string ? or error ?).
-
-2002-01-18 23:38 hoffman
-
- * Source/cmCableClassSet.cxx: BUG: make sure regex match has a
- string to match
-
-2002-01-18 20:33 barre
-
- * Source/cmExecProgramCommand.cxx: Fix: "cd arg2 ; arg1" not
- working. OK with &&. Also should prevent from: "cd
- non_existing_dir_oops && rm -fr *"
-
-2002-01-18 20:32 barre
-
- * Tests/: Complex/CMakeLists.txt, ComplexOneConfig/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt, Complex/VarTests.cmake,
- Complex/VarTests.txt, ComplexOneConfig/VarTests.cmake,
- ComplexOneConfig/VarTests.txt,
- ComplexRelativePaths/VarTests.cmake,
- ComplexRelativePaths/VarTests.txt,
- Complex/Executable/CMakeLists.txt,
- Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/complex.cxx: ENH: Increase test +
- coverage
-
-2002-01-18 19:22 barre
-
- * Tests/: Complex/CMakeCache.txt, ComplexOneConfig/CMakeCache.txt,
- ComplexRelativePaths/CMakeCache.txt: ENH: Increase test +
- coverage. This is not a bug, this cache is used for test.
-
-2002-01-18 19:21 barre
-
- * Tests/: Complex/CMakeLists.txt, ComplexOneConfig/CMakeLists.txt,
- ComplexRelativePaths/CMakeLists.txt,
- Complex/cmTestConfigure.h.in, Complex/Executable/CMakeLists.txt,
- Complex/Executable/complex.cxx, Complex/Library/CMakeLists.txt,
- ComplexOneConfig/cmTestConfigure.h.in,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexOneConfig/Library/CMakeLists.txt,
- ComplexRelativePaths/cmTestConfigure.h.in,
- ComplexRelativePaths/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/complex.cxx,
- ComplexRelativePaths/Library/CMakeLists.txt: ENH: Increase test +
- coverage
-
-2002-01-18 19:21 barre
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: RemoveFile
- returns if the file was removed or not
-
-2002-01-18 17:01 barre
-
- * Source/cmLibraryCommand.h: Unused and deprecated class. Goodbye.
-
-2002-01-18 16:59 martink
-
- * Source/cmIfCommand.cxx: bug fix
-
-2002-01-18 16:45 hoffman
-
- * Source/cmIfCommand.cxx: fix if logic for null defs
-
-2002-01-18 15:54 martink
-
- * Source/: cmSourceFilesCommand.cxx, cmSourceFilesCommand.h:
- required for utilties
-
-2002-01-18 15:51 martink
-
- * Source/: cmUnixMakefileGenerator.h, cmUnixMakefileGenerator.cxx:
- fix for utilties
-
-2002-01-18 15:39 andy
-
- * Source/cmSourceFilesRemoveCommand.cxx,
- Tests/Complex/Library/CMakeLists.txt,
- Tests/ComplexOneConfig/Library/CMakeLists.txt,
- Tests/ComplexRelativePaths/Library/CMakeLists.txt: Add GENERATED
- to cmSourceFilesRemoveCommand
-
-2002-01-18 15:32 martink
-
- * Source/cmAddCustomCommandCommand.cxx: revert to old behaviour
-
-2002-01-18 15:31 barre
-
- * Tests/: Complex/Library/CMakeLists.txt,
- ComplexOneConfig/Library/CMakeLists.txt,
- ComplexRelativePaths/Library/CMakeLists.txt: Fix: create_file.cxx
- is not GENERATED, it exists (so that it can be removed, until
- SOURCE_FILES_REMOVE is synced with SOURCE_FILES)
-
-2002-01-18 15:18 martink
-
- * Source/cmSiteNameCommand.cxx: minor bug fix
-
-2002-01-18 15:16 martink
-
- * Source/cmMakefile.h: bug fixes
-
-2002-01-18 14:44 martink
-
- * Source/: cmCableClassSet.cxx, cmBuildNameCommand.cxx: bug fixes
-
-2002-01-18 14:38 martink
-
- * Source/cmBuildCommand.cxx: compiler warning
-
-2002-01-18 14:07 barre
-
- * Source/cmake.cxx: Fix: escaping spaces was preventing a value
- with space to be passed correctly
-
-2002-01-18 13:37 martink
-
- * Source/: cmElseCommand.cxx, cmIfCommand.cxx: merged if MATCHES
- fix
-
-2002-01-18 13:30 martink
-
- * Source/: cmUnixMakefileGenerator.h, cmUnixMakefileGenerator.cxx:
- some fixes to recent screwerd up changes
-
-2002-01-18 12:03 barre
-
- * Tests/: Complex/CMakeLists.txt, Complex/VarTests.txt,
- Complex/cmTestConfigure.h.in, ComplexOneConfig/CMakeLists.txt,
- ComplexOneConfig/VarTests.txt,
- ComplexOneConfig/cmTestConfigure.h.in,
- ComplexRelativePaths/CMakeLists.txt,
- ComplexRelativePaths/VarTests.txt,
- ComplexRelativePaths/cmTestConfigure.h.in,
- Complex/Executable/complex.cxx, Complex/Library/CMakeLists.txt,
- Complex/Library/create_file.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexOneConfig/Library/CMakeLists.txt,
- ComplexOneConfig/Library/create_file.cxx,
- ComplexRelativePaths/Executable/complex.cxx,
- ComplexRelativePaths/Library/CMakeLists.txt,
- ComplexRelativePaths/Library/create_file.cxx: Increase coverage,
- add tests
-
-2002-01-18 11:48 barre
-
- * Source/cmExecProgramCommand.cxx: Fix bug: was expanding second
- arg even if not passed. crashed
-
-2002-01-18 11:38 barre
-
- * Source/: cmVariableRequiresCommand.h, cmExecProgramCommand.h: Fix
- typo
-
-2002-01-18 11:37 barre
-
- * Source/: cmBuildNameCommand.cxx, cmSiteNameCommand.cxx: Fix:
- argument was not used.
-
-2002-01-18 11:36 barre
-
- * Source/cmBuildCommand.h: Fix typo (second argument was not
- reported)
-
-2002-01-18 11:36 barre
-
- * Source/cmBuildCommand.cxx: no message
-
-2002-01-18 10:28 hoffman
-
- * Source/cmCableClassSet.cxx: AIX compiler fix private to public
-
-2002-01-18 10:27 hoffman
-
- * Source/cmElseCommand.cxx: BUG: GetDefiniton can return null
-
-2002-01-18 09:02 barre
-
- * Tests/: Complex/simple.cxx, ComplexOneConfig/simple.cxx,
- ComplexRelativePaths/simple.cxx: Is not used (see Simple test)
-
-2002-01-18 07:05 hoffman
-
- * Tests/: Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/complex.cxx: ENH: remove unused
- and non-standard io.h file
-
-2002-01-18 07:04 hoffman
-
- * Source/cmIfCommand.cxx: BUG: fix null pointer read if def is not
- defined
-
-2002-01-17 16:36 barre
-
- * Tests/: Complex/Executable/complex.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/Executable/complex.cxx: Fix: displays msg if
- passed for custom command
-
-2002-01-17 16:35 barre
-
- * Source/cmaketest.cxx: FIX: need a 'make clean' before 'make all'
- otherwise the post-build custom-command are not run (since a lib
- might be up to date already for ex.).
-
-2002-01-17 15:49 barre
-
- * Tests/: Complex/CMakeLists.txt, Complex/cmTestConfigure.h.in,
- ComplexOneConfig/CMakeLists.txt,
- ComplexOneConfig/cmTestConfigure.h.in,
- ComplexRelativePaths/CMakeLists.txt,
- ComplexRelativePaths/cmTestConfigure.h.in,
- Complex/Executable/complex.cxx, Complex/Library/CMakeLists.txt,
- Complex/Library/create_file.cxx,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexOneConfig/Library/CMakeLists.txt,
- ComplexOneConfig/Library/create_file.cxx,
- ComplexRelativePaths/Executable/complex.cxx,
- ComplexRelativePaths/Library/CMakeLists.txt,
- ComplexRelativePaths/Library/create_file.cxx: ENH: tests
- ADD_DEPENDENCIES and ADD_CUSTOM_COMMAND
-
-2002-01-17 15:46 barre
-
- * Source/: cmUnixMakefileGenerator.cxx, cmUnixMakefileGenerator.h:
- Fix so that ADD_DEPENDENCIES work (the Utilities dependencies
- were not output)
-
-2002-01-17 14:11 andy
-
- * Source/: cmSourceFilesCommand.cxx, cmSourceFilesCommand.h: Add
- option of adding generated files to source list
-
-2002-01-17 12:54 hoffman
-
- * Source/cmDSPWriter.cxx: ENH: only output each link path once
-
-2002-01-17 10:48 king
-
- * Source/cmMakefile.h: ERR: Missing forward declaration of
- cmMakeDepend added.
-
-2002-01-17 09:28 hoffman
-
- * Source/cmDSPWriter.cxx: BUG: allow header files to be added to
- the dsp file
-
-2002-01-16 17:29 barre
-
- * Source/cmAddCustomCommandCommand.cxx: Remove hack.
-
-2002-01-16 17:26 andy
-
- * Source/cmAddCustomCommandCommand.cxx: Hack to make it work almost
- like before
-
-2002-01-16 15:53 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: ENH: add silent and suffixes
- to check depend file
-
-2002-01-16 15:00 hoffman
-
- * Source/cmConfigureFileCommand.cxx: BUG: make sure non cmakedef
- lines are not skipped
-
-2002-01-16 12:45 hoffman
-
- * Source/cmConfigureFileCommand.cxx: ENH: do not undef cmakedefine
- stuff, just comment out the line
-
-2002-01-15 17:21 berk
-
- * Source/cmUnixMakefileGenerator.cxx: Improved performance by
- removing implicit rules.
-
-2002-01-15 16:20 martink
-
- * CMake.pdf, CMake.rtf: updated
-
-2002-01-15 16:19 will
-
- * CMake.pdf: ENH:Support v1.2
-
-2002-01-15 16:15 hoffman
-
- * CMake.rtf: public to www.cmake.org
-
-2002-01-15 15:56 will
-
- * CMake.pdf: ENH:Docs for version 1.2
-
-2002-01-15 15:52 hoffman
-
- * CMake.rtf: update for next version
-
-2002-01-15 15:50 martink
-
- * Source/cmMakefile.h: next release
-
-2002-01-15 15:46 martink
-
- * Source/cmMakefile.h: next release
-
-2002-01-15 15:38 hoffman
-
- * ChangeLog.txt: log for relase 1.2
-
-2002-01-15 15:29 millerjv
-
- * Modules/Dart.cmake: ENH: Added DELIVER_CONTINUOUS_EMAIL as an
- advanced cache entry.
-
-2002-01-15 13:20 berk
-
- * Source/: cmFindPathCommand.cxx, cmFindProgramCommand.cxx: FIX:
- Entry doc. should never be overwritten. This may cause cmake to
- be re-run very often.
-
-2002-01-14 19:08 hoffman
-
- * Source/cmDSPWriter.cxx: ENH: do not depend on the .dsp file but
- rather depend on .dsp.cmake and if the .dsp actually changes,
- then write it, so clean and rebuild will not cause many reloads
-
-2002-01-14 18:52 hoffman
-
- * Source/cmCacheManager.cxx: ENH: try to keep the dsp files from
- changing between each write
-
-2002-01-14 16:28 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: remove extra logic not needed
- anymore because of better depends
-
-2002-01-14 16:02 berk
-
- * Source/cmUnixMakefileGenerator.cxx: Quote echo
-
-2002-01-14 14:49 berk
-
- * Source/CursesDialog/cmCursesMainForm.cxx: BUG: Curses was being
- used without initialization.
-
-2002-01-12 22:55 hoffman
-
- * Source/cmBorlandMakefileGenerator.cxx: BUG: use borland run time
- dll for shared builds to avoid crashes
-
-2002-01-11 10:55 hoffman
-
- * Templates/configure: ENH: add support for AIX shared libraries
- with gcc
-
-2002-01-11 10:54 hoffman
-
- * Templates/configure.in: ENH: add support for shared libraries
- with gcc on AIX
-
-2002-01-10 18:09 hoffman
-
- * Source/CMakeLists.txt: ENH: make the fltk build default to OFF,
- it fails on too many linux machines with the default build
-
-2002-01-10 18:09 hoffman
-
- * Source/cmNMakeMakefileGenerator.cxx: BUG: fix build of library in
- other directory if it is not there
-
-2002-01-10 16:22 andy
-
- * Source/cmConfigureFileCommand.cxx: Add space to output
-
-2002-01-08 17:18 hoffman
-
- * Source/cmBorlandMakefileGenerator.cxx: BUG: need a larger default
- page size
-
-2002-01-08 17:18 hoffman
-
- * Source/cmDSPWriter.cxx: BUG: need spaces around linker options
-
-2002-01-08 13:32 hoffman
-
- * Source/cmDSPWriter.cxx, Templates/CMakeWindowsSystemConfig.cmake:
- ENH: add CMAKE_EXTRA_LINK_FLAGS to dsp generator
-
-2002-01-08 12:57 hoffman
-
- * Templates/: configure, configure.in: ENH: use +Z not +z for pic
- and use -fPIC for gcc
-
-2002-01-08 12:53 hoffman
-
- * Templates/: configure, configure.in: ENH: add -L/usr/lib for hp
- so shared libs find that directory before the pa1.1 directory
-
-2002-01-07 17:29 barre
-
- * Modules/FindVTK.cmake: More user friendly (built tree is
- automatically used).
-
-2002-01-07 16:30 hoffman
-
- * Source/CursesDialog/cmCursesMainForm.cxx: BUG: not all displayed
- messages are errors
-
-2002-01-07 15:49 perera
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h, cmake.cxx, cmake.h:
- Rolling back symbolic path changes until it works on Windows.
-
-2002-01-07 14:12 hoffman
-
- * Templates/configure: Add sizeof some types support
-
-2002-01-07 14:07 andy
-
- * Templates/: configure.in, CMakeBorlandWindowsSystemConfig.cmake,
- CMakeNMakeWindowsSystemConfig.cmake, CMakeSystemConfig.cmake.in,
- CMakeWindowsSystemConfig.cmake: Add sizeof some types support
-
-2002-01-07 13:47 hoffman
-
- * Templates/: configure, configure.in: use -shared for sunos build
-
-2002-01-06 14:59 perera
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h, cmake.cxx, cmake.h:
- ENH: Add an invocation that maintains symbolic paths to the
- source and binary trees, mainly for systems with automounted
- network drives. ENH: CollapseFullPath() no longer adds a
- trailing "/" to directory paths.
-
-2002-01-03 16:02 andy
-
- * Source/: cmAddCustomCommandCommand.cxx,
- cmAddCustomCommandCommand.h: Fix add custom command so that it
- actually executes the code
-
-2002-01-03 14:19 martink
-
- * Source/: cmVTKWrapJavaCommand.cxx, cmVTKWrapPythonCommand.cxx:
- minor fixes
-
-2002-01-03 14:05 martink
-
- * Source/cmVTKWrapTclCommand.cxx: minor fix
-
-2002-01-03 13:56 martink
-
- * Source/cmVTKWrapTclCommand.cxx: minor fix
-
-2002-01-03 09:34 martink
-
- * Source/: cmElseCommand.cxx, cmIfCommand.cxx: expand vars nwo for
- exists test
-
-2002-01-02 16:46 martink
-
- * Source/: cmElseCommand.cxx, cmIfCommand.cxx, cmIfCommand.h: added
- exists option for if statement
-
-2002-01-02 16:45 martink
-
- * Source/: cmake.cxx, CursesDialog/cmCursesLongMessageForm.cxx,
- CursesDialog/cmCursesMainForm.cxx: prints the relese version
-
-2002-01-02 16:44 martink
-
- * Source/cmMakefile.h: added release verison to cmMakefile
-
-2002-01-02 11:54 hoffman
-
- * Source/: cmNMakeMakefileGenerator.cxx,
- cmUnixMakefileGenerator.cxx: BUG: put back recursive call to make
- for checking sources
-
-2001-12-31 12:02 berk
-
- * Source/cmUnixMakefileGenerator.cxx: Type || should have been &&
-
-2001-12-31 11:54 hoffman
-
- * Source/: cmNMakeMakefileGenerator.cxx,
- cmUnixMakefileGenerator.cxx: ENH: remove one call to make, and
- clean echo stuff a bit
-
-2001-12-30 17:18 berk
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: fix long depend list
- because it gets cut on the hp: I may look like berk, but it is
- bill H.
-
-2001-12-28 17:00 hoffman
-
- * Source/: cmNMakeMakefileGenerator.cxx,
- cmUnixMakefileGenerator.cxx, cmUnixMakefileGenerator.h: ENH:
- remove the rule to run make depend from the top with each change
- in any cmakelist file. Instead, run make depend in the current
- directory if a source file changes, or if a .h file changes or is
- removed
-
-2001-12-28 15:58 perera
-
- * Source/: cmBorlandMakefileGenerator.cxx,
- cmNMakeMakefileGenerator.cxx, cmUnixMakefileGenerator.cxx: BUG:
- Don't generate build rules for header files.
-
-2001-12-28 15:56 perera
-
- * Source/cmMakefile.cxx: BUG: .txx are not source files. They
- contain template code which can only be compiled when included in
- a regular .cxx file. By themselves, they cause do not cause code
- to be generated.
-
-2001-12-28 15:54 perera
-
- * Source/cmSourceFile.cxx: ENH: Classify a file as source or header
- even when the extension is given explicitly.
-
-2001-12-28 15:37 hoffman
-
- * CMakeLists.txt: remove bad ADD_DEPENDENCIES commands
-
-2001-12-28 12:40 hoffman
-
- * Source/CMakeLists.txt: ERR: remove bad ADD_DEPENDENCIES commands
-
-2001-12-27 14:55 hoffman
-
- * Source/cmIfCommand.cxx: remove warning
-
-2001-12-27 13:55 hoffman
-
- * Source/cmAddDependenciesCommand.cxx: ENH: add error checking
-
-2001-12-21 15:39 hoffman
-
- * Source/: cmNMakeMakefileGenerator.cxx,
- cmUnixMakefileGenerator.cxx: BUG: fix so you can remove a
- directory in the source tree, and clean up echo of commands
-
-2001-12-21 15:11 martink
-
- * Source/CursesDialog/: cmCursesBoolWidget.cxx,
- cmCursesBoolWidget.h, cmCursesDummyWidget.cxx,
- cmCursesDummyWidget.h, cmCursesForm.h, cmCursesLabelWidget.cxx,
- cmCursesLabelWidget.h, cmCursesLongMessageForm.cxx,
- cmCursesMainForm.cxx, cmCursesMainForm.h,
- cmCursesStringWidget.cxx, cmCursesStringWidget.h,
- cmCursesWidget.cxx, cmCursesWidget.h: update interface
-
-2001-12-21 15:10 martink
-
- * Source/cmake.cxx: add patch hack
-
-2001-12-21 14:54 martink
-
- * Source/: cmBuildCommand.cxx, cmSystemTools.cxx, ctest.cxx: fix
- for dos files on UNIX make -k and flush in ctest
-
-2001-12-21 14:44 martink
-
- * Modules/: FindCurses.cmake, FindJNI.cmake, FindMPI.cmake,
- FindPythonLibs.cmake: general improvements
-
-2001-12-21 14:40 barre
-
- * Modules/: FindVTK.cmake: Change so that different flavours of VTK
- might be chosen by the user. See full instructions in that file.
-
-2001-12-21 14:40 martink
-
- * configure.in, configure: fixed for SGI CC
-
-2001-12-21 14:39 martink
-
- * Templates/: CMakeBorlandWindowsSystemConfig.cmake,
- CMakeNMakeWindowsSystemConfig.cmake,
- CMakeWindowsSystemConfig.cmake, DLLHeader.dsptemplate, configure,
- configure.in, staticLibHeader.dsptemplate: variety of bug fixes
-
-2001-12-21 09:55 ibanez
-
- * Source/cmFLTKWrapUICommand.cxx: ENH: No longer tries to create a
- directory for the output
-
-2001-12-21 09:07 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: ENH: add support for DESTDIR
- in install targets
-
-2001-12-21 00:01 perera
-
- * Source/cmUnixMakefileGenerator.cxx,
- Templates/CMakeSystemConfig.cmake.in: ENH: Add option to disable
- use of -rpath.
-
-2001-12-20 17:00 hoffman
-
- * Source/: cmBorlandMakefileGenerator.cxx,
- cmNMakeMakefileGenerator.cxx: ENH: fix for win98 check for
- directory existence
-
-2001-12-20 16:10 barre
-
- * Modules/: FindTclsh.cmake, FindWish.cmake, FindTCL.cmake: ENH:
- ADVANCED was not propagated to the new sub-mods
-
-2001-12-20 15:46 hoffman
-
- * Source/: cmNMakeMakefileGenerator.cxx,
- cmUnixMakefileGenerator.cxx: ENH: add make silent flag for nmake
- and move .SILENT: directive to top of makefile
-
-2001-12-20 15:45 barre
-
- * Modules/: FindFLTK.cmake: ENH: mark everything ADVANCED
-
-2001-12-20 15:45 hoffman
-
- * Source/cmBorlandMakefileGenerator.cxx: ENH: use better command
- for creating static library
-
-2001-12-20 15:44 hoffman
-
- * Templates/: CMakeBorlandWindowsSystemConfig.cmake,
- CMakeNMakeWindowsSystemConfig.cmake,
- CMakeWindowsSystemConfig.cmake: BUG: must use CACHE values in
- these
-
-2001-12-20 15:22 barre
-
- * Modules/FindVTK.cmake: ENH: Also look for 4.2, 4.1, 4.0
-
-2001-12-20 15:17 barre
-
- * Modules/FindVTK.cmake: ENH: Also look for 4.2, 4.1, 4.0
-
-2001-12-20 08:16 hoffman
-
- * Example/Demo/demo.cxx: remove fancy cxx stuff from the example
-
-2001-12-19 21:51 barre
-
- * Modules/FindJNI.cmake: ENH: Make everything ADVANCED
-
-2001-12-19 18:45 hoffman
-
- * Source/: cmBorlandMakefileGenerator.cxx,
- cmBorlandMakefileGenerator.h, cmNMakeMakefileGenerator.cxx,
- cmUnixMakefileGenerator.cxx: ENH: add silent mode for makefile
- builds and fix borland and nmake after the depend stuff
-
-2001-12-19 15:26 hoffman
-
- * Source/: CMakeLists.txt, cmaketest.cxx: add example to tests
-
-2001-12-19 15:25 hoffman
-
- * Example/: CMakeLists.txt, Demo/CMakeLists.txt, Demo/demo.cxx,
- Demo/demo_b.cxx, Hello/CMakeLists.txt, Hello/hello.cxx,
- Hello/hello.h: move example into the source tree so it will
- work...
-
-2001-12-19 11:38 barre
-
- * Modules/FindTCL.cmake: default ActiveState Tcl install dir is now
- C:/Tcl
-
-2001-12-19 08:35 hoffman
-
- * Source/cmVTKMakeInstantiatorCommand.cxx: change ostrstream to
- strstream
-
-2001-12-19 08:26 hoffman
-
- * Templates/configure, Templates/configure.in, configure,
- configure.in: check for LANG:std
-
-2001-12-18 21:00 hoffman
-
- * configure, configure.in, Templates/configure,
- Templates/configure.in: -LANG:std should be default on sgi for
- ansi CXX Flags
-
-2001-12-18 20:32 hoffman
-
- * Templates/staticLibHeader.dsptemplate: fix comment
-
-2001-12-18 17:30 hoffman
-
- * Templates/: configure, configure.in: syntax error
-
-2001-12-18 17:17 hoffman
-
- * Templates/configure: use cxx compiler on sgi to build static libs
-
-2001-12-18 17:16 hoffman
-
- * Templates/configure.in: use cxx compiler to build static libs on
- sgi
-
-2001-12-18 16:21 martink
-
- * Modules/FindJNI.cmake: bad spelling of java
-
-2001-12-18 14:55 king
-
- * Source/cmIfCommand.cxx: ENH: Added error reporting for missing
- arguments to ENDIF.
-
-2001-12-18 13:35 berk
-
- * Source/CursesDialog/cmCursesBoolWidget.cxx: Fixed warning.
-
-2001-12-18 11:35 king
-
- * Source/: cmVTKMakeInstantiatorCommand.cxx,
- cmVTKMakeInstantiatorCommand.h: ENH: Improved flexibility of
- command by allowing specificiation of separate input and outputs
- source lists. Multiple input source lists are now also allowed.
-
-2001-12-18 10:21 king
-
- * Source/: cmBorlandMakefileGenerator.cxx,
- cmNMakeMakefileGenerator.cxx, cmUnixMakefileGenerator.cxx: ENH:
- Improved dependency generation. If any cmake.depends is out of
- date, all of them in the tree are re-generated. This is
- necessary in certain cases when CMakeLists.txt files change.
-
-2001-12-18 09:51 king
-
- * Source/cmElseCommand.cxx: ENH: Added option to IF command to test
- if a command exists. Syntax is IF(COMMAND name-of-command).
-
-2001-12-18 09:39 king
-
- * Source/: cmIfCommand.cxx, cmMakefile.cxx, cmMakefile.h: ENH:
- Added option to IF command to test if a command exists. Syntax
- is IF(COMMAND name-of-command).
-
-2001-12-18 09:16 king
-
- * Source/cmMakefile.cxx: BUG: Existing projects have cache entries
- with the same name as the command they adjust (VTK_WRAP_JAVA in
- VTK, for example). Setting the command name as a variable is too
- dangerous.
-
-2001-12-17 17:44 andy
-
- * Source/cmSystemTools.cxx: Better handling of new lines when
- moving from dos to unix
-
-2001-12-17 16:20 king
-
- * Source/: cmCommands.cxx, cmVTKMakeInstantiatorCommand.cxx,
- cmVTKMakeInstantiatorCommand.h: ENH: Adding VTK_MAKE_INSTANTIATOR
- command. This command will be used by VTK kits to register their
- classes with vtkInstantiator.
-
-2001-12-17 16:19 king
-
- * Source/cmMakefile.cxx: ENH: Each cmake command now adds a cmake
- variable of its own name, set to ON. This allows constructs in
- CMakeLists.txt files like: IF(FOO_COMMAND) FOO_COMMAND()
- ENDIF(FOO_COMMAND) This provides the option to add CMake commands
- for extra functionality without breaking compatability with
- earlier versions of CMake.
-
-2001-12-17 11:30 hoffman
-
- * Templates/: CMakeNMakeWindowsSystemConfig.cmake,
- DLLHeader.dsptemplate: remove stack stuff
-
-2001-12-17 11:28 hoffman
-
- * Templates/CMakeWindowsSystemConfig.cmake: use a better compiler
- name
-
-2001-12-17 11:15 hoffman
-
- * Source/cmDSPWriter.cxx: ENH: allow custom commands for files that
- msdev knows about
-
-2001-12-16 18:52 barre
-
- * Source/cmVTKWrapPythonCommand.cxx: Wrap abstract class too, as
- per David Gobbi's request (for the sake of the internal
- documentation features of python").
-
-2001-12-14 22:41 hoffman
-
- * Source/cmBuildCommand.cxx: use -i not -k for make
-
-2001-12-13 13:28 berk
-
- * Source/CursesDialog/: cmCursesBoolWidget.cxx,
- cmCursesBoolWidget.h, cmCursesDummyWidget.cxx,
- cmCursesDummyWidget.h, cmCursesForm.h, cmCursesLabelWidget.cxx,
- cmCursesLabelWidget.h, cmCursesLongMessageForm.cxx,
- cmCursesMainForm.cxx, cmCursesMainForm.h,
- cmCursesStringWidget.cxx, cmCursesStringWidget.h,
- cmCursesWidget.cxx, cmCursesWidget.h: Updated toolbar.
-
-2001-12-12 18:27 hoffman
-
- * Source/CMakeLists.txt: ENH: allow local changes
-
-2001-12-12 13:57 berk
-
- * Modules/FindMPI.cmake: Added doc.
-
-2001-12-12 12:05 king
-
- * Modules/FindCurses.cmake: ENH: Added /lib to curses search path.
-
-2001-12-12 11:51 berk
-
- * Modules/FindMPI.cmake: Added support for a 2nd mpi library
- (usually mpi++)
-
-2001-12-11 15:59 king
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: cmake.depends files of
- zero size were not being re-written in some cases. Added a
- comment output to the top of the file so it will be re-written
- every time.
-
-2001-12-11 14:09 blezek
-
- * Modules/FindPythonLibs.cmake: ENH: Adding /usr/*/python1.5 for
- RedHat 7.1/Python 1.5 users
-
-2001-12-11 12:29 hoffman
-
- * Source/cmSubdirDependsCommand.cxx: remove warning
-
-2001-12-11 10:42 hoffman
-
- * Source/: cmUnixMakefileGenerator.cxx: check for empty library
- output path
-
-2001-12-11 10:39 hoffman
-
- * Source/ctest.cxx: ENH: add flush
-
-2001-12-11 02:21 ibanez
-
- * Source/: cmFLTKWrapUICommand.h, cmFLTKWrapUICommand.cxx: FIX: The
- command was modified it uses now a target and a source list
- composed of .fl files. The names of the generated .cxx files are
- added internally to the Sources list of the target.
-
-2001-12-11 02:17 ibanez
-
- * Source/: cmUnixMakefileGenerator.cxx, cmTarget.h: FIX:
- GENERATED_CODE type is no longer needed: generated code is not a
- Target.
-
-2001-12-10 12:10 king
-
- * Modules/FindTclsh.cmake: ENH: Added more filenames for tclsh
- program. Also now only looks for cygtclsh80 if under cygwin.
-
-2001-12-10 12:04 king
-
- * Modules/FindTclsh.cmake: ENH: Added more filenames for tclsh
- program. Also now only looks for cygtclsh80 if under cygwin.
-
-2001-12-10 12:02 perera
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: LIBRARY_OUTPATH_PATH may
- be "set" to the null string, in which case it should be ignored.
-
-2001-12-10 11:27 king
-
- * Source/: cmMakefile.cxx, cmMakefile.h,
- cmSubdirDependsCommand.cxx, cmSubdirDependsCommand.h,
- cmUnixMakefileGenerator.cxx: ENH: Parallel build support is now
- automatic. SUBDIR_DEPENDS command now does nothing. Also fixed
- a bug in CMakeLists.txt file inheritance when a directory level
- is skipped.
-
-2001-12-10 11:03 king
-
- * Source/: cmMakefile.cxx, cmMakefile.h,
- cmSubdirDependsCommand.cxx, cmSubdirDependsCommand.h,
- cmUnixMakefileGenerator.cxx: ENH: SUBDIR_DEPENDS command now does
- nothing. The parallel build functionality is now automatic.
- Dependencies are setup to force the same build order as a single
- threaded build, but multiple files in the same directory can be
- built simultaneously. Also fixed bug with inheriting
- CMakeLists.txt files when a directory level is skipped.
-
-2001-12-08 21:17 hoffman
-
- * Source/: cmUnixMakefileGenerator.cxx, cmUnixMakefileGenerator.h:
- merge bug fixes to release
-
-2001-12-08 21:16 hoffman
-
- * Source/cmCacheManager.cxx: merge bug fixes to release, mistaken
- comment in cache
-
-2001-12-08 21:10 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: if LIBRARY_OUTPUT_PATH
- is set, then use the fullpath for a remote target
-
-2001-12-08 20:49 hoffman
-
- * Source/cmUnixMakefileGenerator.h: WAR: remove warning
-
-2001-12-07 19:11 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: executable extension
- wrong for ctest search, and was not looking in Debug and Release
-
-2001-12-07 18:27 berk
-
- * Source/cmCacheManager.cxx: If an entry starts with // (network
- paths), double quote it.
-
-2001-12-07 18:15 perera
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: the rule for generating
- a library no longer has the full path, and so the dependency
- targets shouldn't, either.
-
-2001-12-07 18:12 berk
-
- * Source/cmCacheManager.cxx: Comments start with TWO leading
- slashes not _one_
-
-2001-12-07 16:06 martink
-
- * Source/cmMakefile.h: version rev
-
-2001-12-07 16:01 martink
-
- * Source/cmMakefile.h: release 10
-
-2001-12-07 15:47 hoffman
-
- * Source/cmCacheManager.cxx, Source/cmMarkAsAdvancedCommand.cxx,
- Source/cmMarkAsAdvancedCommand.h,
- Templates/CMakeBorlandWindowsSystemConfig.cmake: ENH: add mark as
- not advanced to mark as advanced
-
-2001-12-07 14:57 hoffman
-
- * ChangeLog.txt: yet another release
-
-2001-12-07 14:31 hoffman
-
- * Source/cmaketest.cxx: ENH: convert to windows paths
-
-2001-12-07 13:10 hoffman
-
- * Source/cmaketest.cxx: ENH: use windows paths to run commands and
- escape spaces
-
-2001-12-07 10:58 hoffman
-
- * Source/: cmBorlandMakefileGenerator.cxx,
- cmNMakeMakefileGenerator.cxx, cmUnixMakefileGenerator.cxx,
- cmUnixMakefileGenerator.h: ENH: add custom commands for targets
-
-2001-12-07 10:32 barre
-
- * Templates/CMakeBorlandWindowsSystemConfig.cmake: Remove "unused
- var" warning from C_FLAGS
-
-2001-12-06 20:04 barre
-
- * Source/cmNMakeMakefileGenerator.cxx: Do not output library search
- path if the library path option/flag is empty + add
- CMAKE_LINKER_HIDE_PARAMETERS since some linkers just do not
- support the @<< syntax
-
-2001-12-06 20:02 barre
-
- * Templates/CMakeNMakeWindowsSystemConfig.cmake: Add
- CMAKE_LINKER_HIDE_PARAMETERS since some linkers just do not
- support the @<< syntax
-
-2001-12-06 17:40 andy
-
- * Source/CursesDialog/cmCursesMainForm.cxx: Fix bug with string
-
-2001-12-06 17:09 hoffman
-
- * Source/cmakewizard.cxx: ENH: call convert to unix slashes for
- path and filepath entries
-
-2001-12-06 17:07 berk
-
- * Source/CursesDialog/cmCursesMainForm.cxx: Added support for ~.
-
-2001-12-06 16:50 martink
-
- * Source/cmSystemTools.cxx: handle tildas
-
-2001-12-06 13:32 barre
-
- * Source/cmUnixMakefileGenerator.cxx: Lib path should be converted
- to native path too.
-
-2001-12-06 13:31 barre
-
- * Source/: cmBorlandMakefileGenerator.cxx,
- cmBorlandMakefileGenerator.h, cmNMakeMakefileGenerator.cxx,
- cmNMakeMakefileGenerator.h: Fix the command quoting pb (remove
- m_QuoteNextCommand), move ConvertToNativePath to NMake gen
-
-2001-12-06 11:52 martink
-
- * Modules/Dart.cmake: better use of modules
-
-2001-12-06 11:52 martink
-
- * Modules/FindDart.cmake: better docs
-
-2001-12-06 11:52 martink
-
- * Modules/FindTCL.cmake: now broken into pieces
-
-2001-12-06 11:51 martink
-
- * Modules/: FindTclsh.cmake, FindWish.cmake: new modules
-
-2001-12-06 11:49 martink
-
- * Source/CursesDialog/ccmake.cxx: Cleaning last line at exit.
-
-2001-12-06 10:24 martink
-
- * Templates/CMakeSystemConfig.cmake.in: made install prefix non
- advanced
-
-2001-12-05 15:36 perera
-
- * Modules/FindTCL.cmake: ENH: add more possible names for
- executables.
-
-2001-12-05 15:28 barre
-
- * Source/: cmNMakeMakefileGenerator.cxx, cmCacheManager.cxx: Add
- single quotes feature.
-
-2001-12-05 15:00 barre
-
- * Templates/CMakeNMakeWindowsSystemConfig.cmake: Add single quotes
- feature.
-
-2001-12-05 12:07 martink
-
- * Source/cmMakefile.h: up version
-
-2001-12-05 11:59 martink
-
- * Source/cmMakefile.h: up version
-
-2001-12-05 11:38 hoffman
-
- * ChangeLog.txt: new version
-
-2001-12-05 11:37 will
-
- * CMake.pdf: updated from rtf
-
-2001-12-05 11:32 hoffman
-
- * CMake.rtf: ENH: update cvs path
-
-2001-12-04 18:49 starreveld
-
- * Templates/: configure, configure.in:
-
- Add the flat_namespace and undefined suppress flags to OSX builds
-
-2001-12-04 17:28 hoffman
-
- * Source/cmSystemTools.cxx: ENH: remove /tmp_mnt from all paths in
- convert to unix slashes
-
-2001-12-04 16:19 berk
-
- * Source/CursesDialog/cmCursesMainForm.cxx: Fixed outdated comment
-
-2001-12-04 15:55 hoffman
-
- * Templates/CMakeBorlandWindowsSystemConfig.cmake: add tWM to c
- flags as well as CXX flags
-
-2001-12-04 15:53 berk
-
- * Source/CursesDialog/cmCursesMainForm.cxx: Fixed overflow problem.
-
-2001-12-04 15:16 hoffman
-
- * Templates/CMakeBorlandWindowsSystemConfig.cmake: ENH: add -tWM to
- default flags for compilation
-
-2001-12-04 12:03 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: crazy fix for putenv, and
- native path called on custom command paths
-
-2001-12-04 11:20 berk
-
- * Source/CursesDialog/cmCursesStandardIncludes.h: replacing clear()
-
-2001-12-04 11:16 berk
-
- * Source/CursesDialog/: ccmake.cxx, cmCursesForm.cxx,
- cmCursesForm.h, cmCursesLongMessageForm.cxx,
- cmCursesMainForm.cxx, cmCursesStringWidget.cxx: Added debugging.
-
-2001-12-04 10:55 barre
-
- * Modules/: Documentation.cmake, FindCygwin.cmake,
- FindDoxygen.cmake, FindHhc.cmake, FindPerl.cmake,
- FindSelfPackers.cmake, FindUnixCommands.cmake, FindWget.cmake:
- Remove unneeded test and code duplication. Add WIN32 test. Make
- all ADVANCED.
-
-2001-12-04 10:54 barre
-
- * Modules/Dart.cmake: Remove code duplication. Call FindTcl.cmake,
- which also does the ADVANCED stuff.
-
-2001-12-04 10:53 barre
-
- * Modules/FindTCL.cmake: Make shells also ADVANCED
-
-2001-12-04 10:27 barre
-
- * Modules/FindPythonLibs.cmake: Make vars ADVANCED for WIN32 (same
- as Tcl)
-
-2001-12-04 10:11 hoffman
-
- * Source/CursesDialog/form/frm_driver.c: no c++ comments in c code,
- duhhhh
-
-2001-12-03 19:58 hoffman
-
- * Source/CursesDialog/form/frm_driver.c: ENH: AIX seems to define
- lines and columns as macros, I undefed them
-
-2001-12-03 18:04 hoffman
-
- * Templates/CMakeBorlandWindowsSystemConfig.cmake: ENH: fix crashes
- in console apps
-
-2001-12-03 17:47 hoffman
-
- * Source/cmVariableRequiresCommand.cxx: ENH: let people know the
- variable is advanced
-
-2001-12-03 17:01 hoffman
-
- * Modules/FindOpenGL.cmake, Source/cmBorlandMakefileGenerator.cxx,
- Templates/CMakeBorlandWindowsSystemConfig.cmake: ENH: fix
- debugging with borland
-
-2001-12-03 17:00 hoffman
-
- * Source/cmake.cxx: ENH: add -C load cache file option
-
-2001-12-03 15:55 martink
-
- * Source/ctest.cxx: minor fix for not found executables
-
-2001-12-03 15:48 hoffman
-
- * CMake.rtf: [no log message]
-
-2001-12-03 15:11 berk
-
- * Source/: cmake.cxx: Fixed help.
-
-2001-12-03 13:05 hoffman
-
- * Source/Makefile.borland: add wizard
-
-2001-12-03 09:39 hoffman
-
- * CMake.rtf: update docs some
-
-2001-12-02 18:22 ibanez
-
- * Source/cmFLTKWrapUICommand.cxx: ENH: AddCustomCommand register
- now multiple outputs. Auxiliary variable manage the output
- directory where FLTK generated code is going to be writen.
-
-2001-11-30 17:20 barre
-
- * Source/: cmBuildCommand.cxx, cmDSPWriter.cxx, cmDSWWriter.cxx,
- cmIfCommand.cxx, cmUnixMakefileGenerator.cxx, cmake.cxx: fix
- warning for Borland build
-
-2001-11-30 16:51 hoffman
-
- * Source/cmakewizard.h: [no log message]
-
-2001-11-30 16:48 hoffman
-
- * Source/CMakeLib.dsp, Source/CMakeLists.txt,
- Source/Makefile.borland, Source/Makefile.in,
- Source/cmBorlandMakefileGenerator.cxx,
- Source/cmBorlandMakefileGenerator.h,
- Source/cmBorlandMakefileGenerator2.cxx,
- Source/cmBorlandMakefileGenerator2.h,
- Source/cmForEachCommand.cxx, Source/cmake.cxx,
- Source/cmakemain.cxx, Source/cmakewizard.cxx,
- Templates/CMakeBorlandWindowsSystemConfig.cmake,
- Templates/CMakeWindowsBorlandConfig.cmake,
- Templates/CMakeWindowsBorlandConfig2.cmake: new borland generator
- moved into place
-
-2001-11-30 16:27 hoffman
-
- * Source/: cmBorlandMakefileGenerator.cpp,
- cmBorlandMakefileGenerator.h: Replace with nmake subclassed
- generator
-
-2001-11-30 16:05 barre
-
- * Source/: cmBorlandMakefileGenerator2.cxx,
- cmNMakeMakefileGenerator.cxx, cmUnixMakefileGenerator.cxx: Add
- options for library manager (lib).
-
-2001-11-30 16:04 barre
-
- * Templates/CMakeNMakeWindowsSystemConfig.cmake: Add options for
- library manager (lib). Alpha sort
-
-2001-11-30 15:55 berk
-
- * Modules/FindTCL.cmake: Unix users are smarter.
-
-2001-11-30 15:04 berk
-
- * Source/CursesDialog/: cmCursesMainForm.cxx,
- cmCursesStringWidget.cxx: Improving interface.
-
-2001-11-30 14:50 hoffman
-
- * Source/CursesDialog/cmCursesMainForm.cxx: print cmake running
- message to cerr
-
-2001-11-30 14:33 barre
-
- * Templates/CMakeNMakeWindowsSystemConfig.cmake,
- Source/cmNMakeMakefileGenerator.cxx: Add linker flags for each
- build type
-
-2001-11-30 14:24 berk
-
- * Source/CursesDialog/cmCursesMainForm.cxx: Better documentation.
-
-2001-11-30 14:16 berk
-
- * Source/CursesDialog/cmCursesMainForm.cxx: Better documentation.
-
-2001-11-30 13:59 berk
-
- * Source/CursesDialog/: cmCursesLongMessageForm.cxx,
- cmCursesMainForm.cxx, cmCursesStringWidget.cxx: Improved help.
-
-2001-11-30 13:53 berk
-
- * Templates/CMakeSystemConfig.cmake.in: Removed unused options.
-
-2001-11-30 13:10 barre
-
- * Templates/CMakeNMakeWindowsSystemConfig.cmake: CMAKE_ANSI_CFLAGS
- is used by VTK, so it should be set in the NMake config so that
- it gets expanded (even to "")
-
-2001-11-30 13:09 hoffman
-
- * Source/cmNMakeMakefileGenerator.cxx: fix library suffix
-
-2001-11-30 12:41 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: remove suffix rules
-
-2001-11-30 12:05 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: add new suffix rules
-
-2001-11-30 11:34 berk
-
- * Source/CursesDialog/: ccmake.cxx, cmCursesLongMessageForm.cxx,
- cmCursesMainForm.cxx, cmCursesStandardIncludes.h: Can non use
- clear because it is undef'ed.
-
-2001-11-30 10:58 berk
-
- * Source/CursesDialog/ccmake.cxx: Fixed warning.
-
-2001-11-30 10:54 berk
-
- * Source/CursesDialog/: ccmake.cxx, cmCursesMainForm.cxx: Fixed
- warning.
-
-2001-11-30 10:51 berk
-
- * Source/CursesDialog/: cmCursesMainForm.h, cmCursesMainForm.cxx:
- Since it is being used as an array size in another file, it is
- not possible to initialize MAX_WIDTH in a .cxx file.
-
-2001-11-30 10:41 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: fix warning
-
-2001-11-30 10:39 berk
-
- * Source/CursesDialog/: cmCursesLongMessageForm.cxx,
- cmCursesLongMessageForm.h: Missed std::
-
-2001-11-30 10:28 berk
-
- * Source/CursesDialog/cmCursesMainForm.h: Missed std::
-
-2001-11-30 10:27 berk
-
- * Templates/CMakeSystemConfig.cmake.in: CMAKE_WORDS_BIGENDIAN
- should not be in the cache.
-
-2001-11-30 10:23 berk
-
- * Modules/FindPythonLibs.cmake: PYTHON_DEBUG_LIBRARY is only used
- on Windows.
-
-2001-11-30 09:19 barre
-
- * Templates/CMakeSystemConfig.cmake.in: fix: If documentation
- added, then need cache type
-
-2001-11-29 23:45 berk
-
- * Source/CursesDialog/: cmCursesLongMessageForm.cxx,
- cmCursesLongMessageForm.h: opps I forgot to add these
-
-2001-11-29 23:24 hoffman
-
- * Source/Makefile.borland, Source/cmBorlandMakefileGenerator2.cxx,
- Source/cmNMakeMakefileGenerator.cxx,
- Source/cmUnixMakefileGenerator.cxx,
- Templates/CMakeSystemConfig.cmake.in,
- Templates/CMakeWindowsBorlandConfig2.cmake: ENH: fix various
- problems caused by the generalization of nmake generator
-
-2001-11-29 20:59 barre
-
- * Source/cmBorlandMakefileGenerator2.cxx,
- Source/cmNMakeMakefileGenerator.cxx,
- Source/cmUnixMakefileGenerator.cxx,
- Source/cmUnixMakefileGenerator.h,
- Templates/CMakeNMakeWindowsSystemConfig.cmake,
- Templates/CMakeSystemConfig.cmake.in,
- Templates/CMakeWindowsBorlandConfig2.cmake,
- Templates/CMakeWindowsSystemConfig.cmake: Nmake build: move most
- of hard-coded values to config parameters
-
-2001-11-29 16:44 berk
-
- * Source/: cmListFileCache.cxx, cmSystemTools.cxx, cmSystemTools.h,
- ctest.cxx, CursesDialog/CMakeLists.txt, CursesDialog/ccmake.cxx,
- CursesDialog/cmCursesCacheEntryComposite.cxx,
- CursesDialog/cmCursesCacheEntryComposite.h,
- CursesDialog/cmCursesForm.h, CursesDialog/cmCursesMainForm.cxx,
- CursesDialog/cmCursesMainForm.h: Improvements to the curses
- interface.
-
-2001-11-29 14:51 barre
-
- * Source/cmNMakeMakefileGenerator.cxx: Fix space pb (embended, then
- escaped)
-
-2001-11-29 09:22 hoffman
-
- * Source/Makefile.borland: add bootstrap makefile for borland
- compiler
-
-2001-11-29 09:09 hoffman
-
- * Source/CMakeLists.txt, Source/cmBorlandMakefileGenerator2.cxx,
- Source/cmakewizard.cxx,
- Templates/CMakeWindowsBorlandConfig2.cmake: fix for shared libs
- and borland
-
-2001-11-29 01:51 ibanez
-
- * Source/cmUnixMakefileGenerator.cxx: ENH: GENERATED_CODE case
- added to switch.
-
-2001-11-29 01:48 ibanez
-
- * Source/cmTarget.h: ENH: A type of target was added for
- representing GENERATED_CODE
-
-2001-11-29 01:46 ibanez
-
- * Source/cmFLTKWrapUICommand.cxx: ENH: Custom commands are now
- builded.
-
-2001-11-28 18:07 hoffman
-
- * Source/CMakeLib.dsp, Source/cmBorlandMakefileGenerator2.cxx,
- Source/cmBorlandMakefileGenerator2.h,
- Source/cmNMakeMakefileGenerator.cxx,
- Source/cmNMakeMakefileGenerator.h,
- Source/cmUnixMakefileGenerator.cxx,
- Source/cmUnixMakefileGenerator.h,
- Templates/CMakeWindowsBorlandConfig2.cmake: ENH: borland
- generator 2 is working more or less
-
-2001-11-28 14:45 ibanez
-
- * Source/cmFLTKWrapUICommand.cxx: ENH: Command simplified in order
- to construct a Source list of .cxx from a source list of .fl
- GUI files.
-
-2001-11-28 14:44 ibanez
-
- * Source/cmFLTKWrapUICommand.h: ENH: The command was simplified to
- generate a source list of cxx from a source list of .fl GUI
- files.
-
-2001-11-28 12:49 barre
-
- * Modules/FindPythonLibs.cmake: Fynd Python debug lib in usual libs
- dir too
-
-2001-11-28 11:12 hoffman
-
- * Source/: CMakeLists.txt, cmBorlandMakefileGenerator2.cxx,
- cmBorlandMakefileGenerator2.h, cmNMakeMakefileGenerator.cxx,
- cmNMakeMakefileGenerator.h, cmake.cxx: add new borland generator
-
-2001-11-28 10:51 hoffman
-
- * Source/cmaketest.cxx: [no log message]
-
-2001-11-28 07:15 hoffman
-
- * Source/: cmNMakeMakefileGenerator.cxx,
- cmNMakeMakefileGenerator.h, cmUnixMakefileGenerator.cxx,
- cmUnixMakefileGenerator.h: bug: fix same path comparison when
- short paths are used
-
-2001-11-28 07:14 hoffman
-
- * Source/cmMarkAsAdvancedCommand.cxx: fix warning
-
-2001-11-27 17:53 berk
-
- * Source/: cmNMakeMakefileGenerator.cxx,
- cmNMakeMakefileGenerator.h, cmUnixMakefileGenerator.cxx,
- cmUnixMakefileGenerator.h: ENH: nmake generator much closer to
- working with spaces
-
-2001-11-27 17:32 berk
-
- * Source/cmMakefile.cxx: ENH: expand variables in a command before
- escaping spaces in the command
-
-2001-11-27 17:31 berk
-
- * Source/cmOptionCommand.cxx: ENH: do not write over existing cache
- values even doc strings to avoid changing the cache file
-
-2001-11-27 16:12 berk
-
- * Source/cmDSPWriter.cxx: remove unused include
-
-2001-11-27 15:33 martink
-
- * Source/cmLinkLibrariesCommand.cxx: removed extra lib paths to
- avoid finding old libs
-
-2001-11-27 15:32 martink
-
- * Modules/FindTCL.cmake: made some vars advanced
-
-2001-11-27 15:20 martink
-
- * Modules/Dart.cmake: made some vars advanced
-
-2001-11-27 00:03 ibanez
-
- * Source/cmCommands.cxx: ENH: Command for running FLTK's UI tool
- "Fluid" was added.
-
-2001-11-27 00:02 ibanez
-
- * Source/cmUnixMakefileGenerator.cxx: ENH: Support for FLTK Fluid
- tool added.
-
-2001-11-26 23:57 ibanez
-
- * Modules/FindFLTK.cmake: ENH: Support for running FLUID was added.
-
-2001-11-26 22:40 ibanez
-
- * Source/: cmFLTKWrapUICommand.cxx, cmFLTKWrapUICommand.h: Command
- for invoking FLTK's code generator "Fluid" during the building
- process
-
-2001-11-26 18:26 hoffman
-
- * Modules/Dart.cmake, Source/CMakeLists.txt,
- Source/cmCacheManager.cxx, Source/cmCacheManager.h,
- Source/cmCommands.cxx, Source/cmSystemTools.cxx,
- Source/cmSystemTools.h, Source/cmUnixMakefileGenerator.cxx,
- Source/cmakewizard.cxx, Templates/CMakeSystemConfig.cmake.in,
- Templates/CMakeWindowsSystemConfig.cmake,
- Source/cmMarkAsAdvancedCommand.cxx,
- Source/cmMarkAsAdvancedCommand.h: ENH: add advanced variable
- types and command line wizard gui
-
-2001-11-26 18:24 hoffman
-
- * Source/: cmFindFileCommand.cxx, cmFindFileCommand.h,
- cmFindLibraryCommand.cxx, cmFindLibraryCommand.h,
- cmFindPathCommand.cxx, cmFindPathCommand.h,
- cmFindProgramCommand.cxx, cmFindProgramCommand.h: ENH: add
- possibility to add doc strings to varibles created by find type
- commands
-
-2001-11-26 16:32 berk
-
- * Source/cmCacheManager.cxx: Oops. The wrong version of the
- duplicate code was kept. Loaded cache values were not made
- internal.
-
-2001-11-26 15:45 berk
-
- * Modules/FindTCL.cmake: TK_INTERNAL_PATH is only needed on
- Windows.
-
-2001-11-26 11:32 martink
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: removed warning
- messages
-
-2001-11-26 11:31 martink
-
- * Source/cmIfCommand.cxx: better error messages
-
-2001-11-24 18:47 barre
-
- * Modules/Dart.cmake: I want to be able to start/end
- experimental-only dashboards
-
-2001-11-21 17:45 hoffman
-
- * Source/: cmCacheManager.cxx, cmDSPWriter.cxx,
- cmNMakeMakefileGenerator.cxx, cmSystemTools.cxx, cmSystemTools.h,
- cmUnixMakefileGenerator.cxx, cmake.cxx, cmaketest.cxx: NMake with
- spaces in directories
-
-2001-11-21 11:35 andy
-
- * Source/cmCacheManager.cxx: Fix the current directory check for
- NMake
-
-2001-11-21 08:47 hoffman
-
- * Source/cmake.cxx: ENH: clean up command line arguments
-
-2001-11-21 08:46 hoffman
-
- * Source/: cmQTWrapUICommand.cxx, cmVariableRequiresCommand.cxx:
- WAR: fix warning
-
-2001-11-20 17:50 hoffman
-
- * Source/: cmCacheManager.cxx, cmCacheManager.h, cmake.cxx,
- cmake.h: ENH: add command line arguments to set cache entries
-
-2001-11-20 17:27 berk
-
- * Source/cmNMakeMakefileGenerator.cxx: ENH: closer to working with
- spaces in source directory
-
-2001-11-20 17:27 berk
-
- * Source/cmaketest.cxx: BUG: fix memory leak
-
-2001-11-20 17:26 berk
-
- * Source/cmDSPWriter.cxx: BUG: fix for spaces in path to
- CMakeList.txt file
-
-2001-11-20 08:28 hoffman
-
- * Source/: cmStandardIncludes.h, CursesDialog/cmCursesMainForm.cxx,
- CursesDialog/cmCursesStandardIncludes.h: define hacks and such
- for the dec compiler
-
-2001-11-19 17:52 hoffman
-
- * Source/: cmCommands.cxx, cmSystemTools.cxx, cmSystemTools.h,
- cmVariableRequiresCommand.cxx, cmVariableRequiresCommand.h: ENH:
- add new command VARIABLE_REQUIRES for better debugging of list
- files
-
-2001-11-19 09:34 hoffman
-
- * Source/: cmVariableRequiresCommand.cxx,
- cmVariableRequiresCommand.h: [no log message]
-
-2001-11-16 16:42 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: ENH: look for cmake test with
- .exe if nmake
-
-2001-11-16 16:28 hoffman
-
- * Source/cmNMakeMakefileGenerator.cxx: ENH: fix for dll builds
-
-2001-11-16 13:08 bettingf
-
- * Source/cmUnixMakefileGenerator.cxx: Added a make depend in the
- clean rule to refresh the dependencies
-
-2001-11-16 10:14 bettingf
-
- * Source/cmUnixMakefileGenerator.cxx: undo the last change because
- of problem with some versions of make
-
-2001-11-16 09:40 bettingf
-
- * Modules/FindQt.cmake: fixed QT_UIC_EXE name
-
-2001-11-16 09:04 bettingf
-
- * Source/cmUnixMakefileGenerator.cxx: added the deletion of
- cmake.depends in the cleaning so that it is recomputed even
- source files (i.e. .cxx or .h) are generated
-
-2001-11-16 09:03 bettingf
-
- * Source/cmMakeDepend.cxx: Now adds dependency if the file doesn't
- exist but will be created during the compilation
-
-2001-11-16 09:01 bettingf
-
- * Source/: cmQTWrapUICommand.cxx, cmQTWrapUICommand.h: corrected
- path problem and added moc compilation too
-
-2001-11-15 22:10 hoffman
-
- * Source/Makefile.in: remove depend on star dot h as it is not
- really needed and breaks some versions of gmake
-
-2001-11-15 18:18 hoffman
-
- * Source/cmNMakeMakefileGenerator.cxx: ENH: use crazy temp files
- for long command lines
-
-2001-11-15 17:45 hoffman
-
- * Source/cmNMakeMakefileGenerator.cxx: ENH: remove debug prints
-
-2001-11-15 17:11 hoffman
-
- * Modules/Dart.cmake, Source/cmBuildCommand.cxx,
- Source/cmNMakeMakefileGenerator.cxx,
- Source/cmNMakeMakefileGenerator.h,
- Source/cmUnixMakefileGenerator.cxx,
- Source/cmUnixMakefileGenerator.h,
- Templates/CMakeNMakeWindowsSystemConfig.cmake,
- Templates/CMakeSystemConfig.cmake.in,
- Templates/CMakeWindowsBorlandConfig.cmake,
- Templates/CMakeWindowsSystemConfig.cmake: closer to nmake
- working, added CMAKE_MAKE_COMMAND instead of MAKECOMMAND used by
- Dart, nmake makefiles work with borland make and nmake
-
-2001-11-15 14:54 millerjv
-
- * Modules/Dart.cmake: ENH: New make targets for Continuous builds.
- Added a NightlyStart and NightlyUpdate target for unix builds as
- well.
-
-2001-11-15 14:52 millerjv
-
- * DartConfig.cmake: ENH: Changed Nightly start time
-
-2001-11-15 09:55 hoffman
-
- * Source/: cmNMakeMakefileGenerator.cxx,
- cmNMakeMakefileGenerator.h, cmUnixMakefileGenerator.h, cmake.cxx:
- ENH: fix library builds with nmake
-
-2001-11-15 09:00 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: wrong shortname used
-
-2001-11-15 08:43 hoffman
-
- * Source/cmaketest.cxx: BUG: fix build for cygwin
-
-2001-11-15 08:42 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: avoid .cxx.o names...
-
-2001-11-14 18:12 hoffman
-
- * Source/cmSystemTools.cxx, Source/cmSystemTools.h,
- Source/cmUnixMakefileGenerator.cxx,
- Source/cmUnixMakefileGenerator.h, Source/cmake.cxx,
- Source/cmaketest.cxx, Source/cmaketest.h.in,
- Templates/CMakeNMakeWindowsSystemConfig.cmake: Closer to nmake
- build
-
-2001-11-14 18:11 hoffman
-
- * Source/: cmNMakeMakefileGenerator.cxx,
- cmNMakeMakefileGenerator.h: closer to nmake build
-
-2001-11-14 10:21 hoffman
-
- * Templates/CMakeNMakeWindowsSystemConfig.cmake,
- Source/cmNMakeMakefileGenerator.cxx,
- Source/cmNMakeMakefileGenerator.h,
- Source/cmUnixMakefileGenerator.cxx,
- Source/cmUnixMakefileGenerator.h: nmake support
-
-2001-11-14 09:56 king
-
- * Source/CursesDialog/ccmake.cxx: ERR: Re-ordered includes to fix
- macro conflict for gcc 3.0.
-
-2001-11-14 09:55 king
-
- * Source/CursesDialog/form/frm_driver.c: ERR: Fixed compiler
- warning for gcc 3.0.
-
-2001-11-14 09:22 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: ENH: remove debug statements
-
-2001-11-13 18:23 hoffman
-
- * Source/: CMakeLib.dsp, CMakeLists.txt,
- cmNMakeMakefileGenerator.cxx, cmNMakeMakefileGenerator.h,
- cmUnixMakefileGenerator.cxx, cmUnixMakefileGenerator.h: start
- work on nmake generator
-
-2001-11-13 15:54 hoffman
-
- * Source/: cmUnixMakefileGenerator.h, cmUnixMakefileGenerator.cxx:
- clean up object file build rule, and do not attempt to remove
- link_directories that are in the build tree
-
-2001-11-13 14:22 martink
-
- * Source/: CMakeLists.txt, CursesDialog/CMakeLists.txt: fixes to
- curses stuff
-
-2001-11-13 12:42 hoffman
-
- * Source/CursesDialog/form/fty_num.c: warnings
-
-2001-11-13 12:38 hoffman
-
- * Source/: cmCacheManager.cxx, cmForEachCommand.cxx,
- cmIncludeExternalMSProjectCommand.cxx, cmMakefile.cxx,
- cmSystemTools.cxx, cmUnixMakefileGenerator.cxx: ENH: clean up
- warnings
-
-2001-11-13 12:21 hoffman
-
- * Source/cmAddDependenciesCommand.h: ENH: fix spelling error
-
-2001-11-13 12:21 hoffman
-
- * Source/CursesDialog/cmCursesMainForm.cxx: ENH: remove warnings
-
-2001-11-12 15:37 king
-
- * Source/cmMakeDepend.cxx: ENH:
- cmMakeDepend::GenerateDependInformation will now use hints
- regardless of whether the actual file exists. This can be used
- to add dependencies to .h files which are generated but included
- in hand-written .cxx files. If the .cxx does exist, though, it
- will be used first, and the hints will be used afterward.
-
-2001-11-12 09:21 martink
-
- * Source/cmDSPWriter.cxx: minor fix
-
-2001-11-10 23:01 ibanez
-
- * Modules/FindX11.cmake: Module to search for the installation
- of X11
-
-2001-11-09 16:16 berk
-
- * Source/CursesDialog/: CMakeLists.txt, ccmake.cxx, ccurses.cxx:
- Renaming ccurses to ccmake.
-
-2001-11-09 16:15 barre
-
- * Modules/FindSelfPackers.cmake: Self-packers
-
-2001-11-09 16:05 berk
-
- * Source/: CMakeLists.txt, CursesDialog/CMakeLists.txt,
- CursesDialog/cmCursesStandardIncludes.h,
- CursesDialog/form/frm_driver.c, CursesDialog/form/frm_req_name.c:
- Trying to fix curses.
-
-2001-11-09 13:00 martink
-
- * Source/cmDSPWriter.cxx, Source/cmDSPWriter.h,
- Templates/DLLHeader.dsptemplate, Templates/EXEHeader.dsptemplate,
- Templates/EXEWinHeader.dsptemplate,
- Templates/staticLibHeader.dsptemplate: support for custom targets
- on exe and lib
-
-2001-11-09 12:08 bettingf
-
- * Modules/FindQt.cmake: support for compilation of .ui files into
- .h and .cxx files
-
-2001-11-09 12:07 bettingf
-
- * Source/: cmQTWrapCPPCommand.cxx, cmQTWrapCPPCommand.h: cleanups
-
-2001-11-09 12:02 bettingf
-
- * Source/: cmQTWrapUICommand.h, cmQTWrapUICommand.cxx,
- cmCommands.cxx, cmUnixMakefileGenerator.cxx: support for
- compilation of .ui files into .h and .cxx files
-
-2001-11-09 10:42 barre
-
- * Source/cmAddCustomCommandCommand.cxx: SOURCE, COMMAND, TARGET are
- required now
-
-2001-11-09 10:37 barre
-
- * Source/cmAddCustomCommandCommand.h: SOURCE, COMMAND, TARGET are
- required now
-
-2001-11-09 10:33 barre
-
- * Source/: cmAddCustomCommandCommand.cxx,
- cmAddCustomCommandCommand.h: Reimplement code. Since a custom
- command is very flexible and might be extended in the future,
- make all arguments prefixed with arg type, make ordering
- irrelevant and potentially all args optional.
-
-2001-11-08 17:30 berk
-
- * Source/CursesDialog/form/: frm_driver.c, frm_req_name.c: Trying
- to fix curses problems.
-
-2001-11-08 17:25 berk
-
- * Source/CursesDialog/form/: frm_driver.c, frm_req_name.c: Fixing
- problems with curses headers.
-
-2001-11-08 17:17 berk
-
- * Source/CursesDialog/form/: frm_driver.c, frm_req_name.c: Trying
- to fix curses problems.
-
-2001-11-08 17:10 berk
-
- * Source/CursesDialog/form/form.h: Oops.
-
-2001-11-08 17:03 berk
-
- * CMakeLists.txt, Source/CursesDialog/CMakeLists.txt,
- Source/CursesDialog/form/CMakeLists.txt,
- Source/CursesDialog/form/form.h,
- Source/CursesDialog/form/nc_alloc.h: Changes to remove warnings
- and fix dependencies.
-
-2001-11-08 15:09 martink
-
- * Source/cmDSWWriter.cxx: a better fix maybe
-
-2001-11-08 14:44 hoffman
-
- * Source/cmDSWWriter.cxx: make sure custom targets are in the
- ALL_BUILD
-
-2001-11-08 14:34 barre
-
- * Source/cmAddCustomCommandCommand.cxx: Fix number of params and
- expand vars in all args
-
-2001-11-08 11:50 barre
-
- * Source/cmSourceFilesCommand.cxx: Fix bug. Was using unexpanded
- var instead of copy
-
-2001-11-08 11:40 barre
-
- * Source/cmAddLibraryCommand.cxx: Break the "to infinity and
- beyond" stuff
-
-2001-11-08 10:48 barre
-
- * Source/cmAddLibraryCommand.cxx: Expand var in srclist name too
-
-2001-11-08 10:40 barre
-
- * Source/cmSourceFilesCommand.cxx: Expand var in name too
-
-2001-11-08 09:16 barre
-
- * Source/cmAddDependenciesCommand.cxx: Expand variables in all
- target args
-
-2001-11-08 08:42 berk
-
- * Source/cmUnixMakefileGenerator.cxx: Needed to replace srcdir to
- make install targets work.
-
-2001-11-07 17:12 hoffman
-
- * Templates/: configure, configure.in: put back
- CMAKE_TEMPLATE_FLAGS
-
-2001-11-07 17:04 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: no +=+
-
-2001-11-07 16:47 andy
-
- * Source/: cmAddCustomCommandCommand.cxx,
- cmAddCustomCommandCommand.h, cmCommands.cxx: Added accessor for
- add custom command
-
-2001-11-07 16:07 barre
-
- * Modules/FindUnixCommands.cmake: Add cp (CP)
-
-2001-11-07 15:57 hoffman
-
- * configure, configure.in, Source/cmUnixMakefileGenerator.cxx,
- Templates/configure, Templates/configure.in: remove template
- flags from cmake, no ptused, or -instance=static
-
-2001-11-07 15:57 hoffman
-
- * Source/CursesDialog/cmCursesStandardIncludes.h: Trying to fix
- curses problems with some systems.
-
-2001-11-07 15:01 berk
-
- * Source/CursesDialog/cmCursesStandardIncludes.h: Trying to fix
- build problems related to curses.
-
-2001-11-07 14:55 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: ENH: use full source name for
- c code as well as c++
-
-2001-11-07 14:44 hoffman
-
- * Source/CursesDialog/ccurses.cxx: use cmake as the executable for
- cmake and not ccurses
-
-2001-11-07 14:44 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: make sure default_target is
- first
-
-2001-11-07 13:46 hoffman
-
- * CMakeLists.txt: ENH: add ansi flag for c compiler
-
-2001-11-07 12:23 hoffman
-
- * Source/cmMessageCommand.cxx: Allow multiline messages
-
-2001-11-07 09:54 hoffman
-
- * Source/: cmUnixMakefileGenerator.cxx, cmUnixMakefileGenerator.h:
- Clean up a bit more
-
-2001-11-07 09:29 hoffman
-
- * Source/cmCacheManager.cxx: One more time... case does not matter
- on cygwin
-
-2001-11-06 16:14 hoffman
-
- * Source/cmExecProgramCommand.h: ENH: fix doc string
-
-2001-11-06 15:29 bettingf
-
- * Source/: cmQTWrapCPPCommand.cxx, cmUnixMakefileGenerator.cxx: add
- cleaning of QT generated files when make clean is used
-
-2001-11-06 12:03 hoffman
-
- * Source/CursesDialog/: ccurses.cxx, cmCursesMainForm.cxx,
- cmCursesMainForm.h: ENH: tell cmake object where cmake is
-
-2001-11-06 09:35 hoffman
-
- * Source/: cmCableWrapTclCommand.cxx, cmQTWrapCPPCommand.cxx,
- cmVTKWrapJavaCommand.cxx, cmVTKWrapPythonCommand.cxx,
- cmVTKWrapTclCommand.cxx: BUG: CustomCommand has to use full path
- to Source file now
-
-2001-11-06 08:40 hoffman
-
- * Source/CursesDialog/form/: fld_type.c, form.h: Removed a function
- which used va_start (did not compile on Sun with gcc)
-
-2001-11-05 22:10 berk
-
- * Source/CursesDialog/: ccurses.cxx, cmCursesBoolWidget.cxx,
- cmCursesLabelWidget.cxx, cmCursesMainForm.cxx,
- cmCursesMainForm.h, cmCursesStringWidget.cxx: Many improvements.
-
-2001-11-05 16:38 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: ENH: use full paths for
- object compile rules
-
-2001-11-05 15:55 berk
-
- * Source/: CMakeLists.txt, CursesDialog/cmCursesMainForm.cxx:
- Re-enabling curses support.
-
-2001-11-05 15:39 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: ENH: change to work with
- nmake
-
-2001-11-05 13:22 berk
-
- * Modules/FindCurses.cmake, Source/CursesDialog/CMakeLists.txt,
- Source/CursesDialog/cmCursesForm.h,
- Source/CursesDialog/cmCursesLabelWidget.h,
- Source/CursesDialog/cmCursesMainForm.h,
- Source/CursesDialog/cmCursesWidget.h,
- Source/CursesDialog/form/frm_driver.c,
- Source/CursesDialog/form/frm_req_name.c,
- Source/CursesDialog/cmCursesStandardIncludes.h: HPUX support.
-
-2001-11-05 12:57 lorensen
-
- * Source/cmIncludeExternalMSProjectCommand.cxx: ERR: ^M's removed.
-
-2001-11-05 11:52 berk
-
- * Source/CursesDialog/form/: CMakeLists.txt, READ.ME, eti.h,
- fld_arg.c, fld_attr.c, fld_current.c, fld_def.c, fld_dup.c,
- fld_ftchoice.c, fld_ftlink.c, fld_info.c, fld_just.c, fld_link.c,
- fld_max.c, fld_move.c, fld_newftyp.c, fld_opts.c, fld_pad.c,
- fld_page.c, fld_stat.c, fld_type.c, fld_user.c, form.h,
- form.priv.h, frm_cursor.c, frm_data.c, frm_def.c, frm_driver.c,
- frm_hook.c, frm_opts.c, frm_page.c, frm_post.c, frm_req_name.c,
- frm_scale.c, frm_sub.c, frm_user.c, frm_win.c, fty_alnum.c,
- fty_alpha.c, fty_enum.c, fty_int.c, fty_ipv4.c, fty_num.c,
- fty_regex.c, llib-lform, mf_common.h, nc_alloc.h: Adding form
- library.
-
-2001-11-05 11:52 berk
-
- * Source/: CMakeLists.txt, CursesDialog/CMakeLists.txt,
- CursesDialog/cmCursesCacheEntryComposite.h,
- CursesDialog/cmCursesLabelWidget.h,
- CursesDialog/cmCursesMainForm.cxx,
- CursesDialog/cmCursesMainForm.h, CursesDialog/cmCursesWidget.h:
- Fixing problems on Sun (name collusions between STL and curses)
- and disabling curses temporarily.
-
-2001-11-05 10:42 andy
-
- * Source/CMakeLists.txt: Fix the IF IF problem
-
-2001-11-05 08:37 berk
-
- * Source/CursesDialog/: ccurses.cxx,
- cmCursesCacheEntryComposite.cxx, cmCursesCacheEntryComposite.h,
- cmCursesLabelWidget.h, cmCursesMainForm.cxx, cmCursesMainForm.h,
- cmCursesWidget.h: ERR: To include cmake headers, one should use
- ../
-
-2001-11-05 05:43 pcp
-
- * Source/: cmDSPWriter.cxx, cmDSWWriter.cxx: switched
- string::compare to strncmp
-
-2001-11-04 18:10 berk
-
- * Source/CursesDialog/cmCursesMainForm.h: Need to include standard
- headers.
-
-2001-11-04 18:05 berk
-
- * Source/CursesDialog/: CMakeLists.txt, cmCursesBoolWidget.h,
- cmCursesCacheEntryComposite.h, cmCursesDummyWidget.h,
- cmCursesFilePathWidget.h, cmCursesForm.h, cmCursesLabelWidget.h,
- cmCursesMainForm.h, cmCursesPathWidget.h, cmCursesStringWidget.h,
- cmCursesWidget.h, ccurses.cxx, cmCursesBoolWidget.cxx,
- cmCursesCacheEntryComposite.cxx, cmCursesDummyWidget.cxx,
- cmCursesFilePathWidget.cxx, cmCursesForm.cxx,
- cmCursesLabelWidget.cxx, cmCursesMainForm.cxx,
- cmCursesPathWidget.cxx, cmCursesStringWidget.cxx,
- cmCursesWidget.cxx: Adding curses support.
-
-2001-11-04 18:00 berk
-
- * Modules/FindCurses.cmake, Source/CMakeLists.txt: Adding curses
- support.
-
-2001-11-02 22:32 barre
-
- * Source/: cmIncludeDirectoryCommand.cxx,
- cmIncludeDirectoryCommand.h, cmMakefile.cxx, cmMakefile.h: Add
- optional BEFORE param to INCLUDE_DIRECTORIES so that include dirs
- can be specified before the actual include dirs
-
-2001-11-02 16:44 barre
-
- * Utilities/Doxygen/: CMakeLists.txt, doc_makeall.sh.in: Update
-
-2001-11-02 16:43 barre
-
- * Modules/: Documentation.cmake, DocumentationVTK.cmake,
- FindCygwin.cmake, FindPerl.cmake, FindUnixCommands.cmake,
- FindWget.cmake: Move usual Unix commands to FindUnixCommands, use
- FingCygwin in other modules
-
-2001-11-02 16:05 barre
-
- * Utilities/: CMakeLists.txt, Doxygen/CMakeLists.txt,
- Doxygen/doc_makeall.sh.in, Doxygen/doxyfile.in: Doxygen doc
- generator
-
-2001-11-02 16:01 barre
-
- * CMakeLists.txt: Doxygen doc generator
-
-2001-11-02 15:26 blezek
-
- * Modules/Dart.cmake: ENH: More Experimental targets for unix
-
-2001-11-02 11:19 pcp
-
- * Source/: cmDSWWriter.cxx, cmIncludeExternalMSProjectCommand.cxx,
- cmDSPWriter.cxx: allow more than one external MS project
-
-2001-11-02 09:18 andy
-
- * Source/cmCacheManager.cxx: On win32 path is all in lower case now
-
-2001-11-01 18:37 hoffman
-
- * Source/: cmUnixMakefileGenerator.cxx, cmUnixMakefileGenerator.h:
- ENH: clean up interface and change build in current directory to
- build the depend file first
-
-2001-11-01 18:36 hoffman
-
- * Source/cmCacheManager.cxx: BUG: use collapse full path when
- testing cache directory
-
-2001-11-01 18:36 hoffman
-
- * Source/cmDSPWriter.cxx: ENH: IntDir to INTDIR
-
-2001-11-01 13:09 barre
-
- * Source/: cmAddExecutableCommand.cxx, cmAddLibraryCommand.cxx:
- Expand vars in exe and lib name
-
-2001-11-01 10:42 hoffman
-
- * Source/cmCacheManager.cxx: ENH: clean up drive letter check
-
-2001-10-31 18:56 king
-
- * Source/: cmCableClassSet.cxx, cmCableClassSet.h: ENH: Added
- automatic detection of >> sequences in template names and
- replacement with "> >" in the output.
-
-2001-10-31 18:56 king
-
- * Source/cmStandardIncludes.h: ENH: Replaced cmStdString
- implementation to make it more transparently a std:string.
-
-2001-10-31 07:03 pcp
-
- * Source/: cmCommands.cxx, cmDSPWriter.cxx, cmDSWWriter.cxx,
- cmDSWWriter.h, cmIncludeExternalMSProjectCommand.cxx,
- cmIncludeExternalMSProjectCommand.h: INCLUDE_EXTERNAL_MSPROJECT
- command
-
-2001-10-30 14:36 andy
-
- * Source/cmCacheManager.cxx: Fix the problem on windows of capital
- or lower case drive letter for CMAKE_CACHEFILE_DIR
-
-2001-10-30 14:15 andy
-
- * Source/cmCacheManager.cxx: Change CMAKE_CURRENT_CWD to
- CMAKE_CACHEFILE_DIR and change the messages
-
-2001-10-30 14:05 hoffman
-
- * Source/: cmConfigureFileCommand.cxx, cmConfigureFileCommand.h,
- cmMakefile.cxx, cmMakefile.h: ENH: add an option to configure
- file command that allows for only expansion of at variables and
- not dollar variables
-
-2001-10-29 10:41 hoffman
-
- * Source/cmSystemTools.cxx: ENH: use callback not ifdef for MFC
- message box errors
-
-2001-10-29 10:19 hoffman
-
- * Source/: cmCacheManager.cxx, cmSystemTools.cxx, cmSystemTools.h:
- ENH: add callback for message display
-
-2001-10-26 18:21 hoffman
-
- * Modules/FindITK.cmake: [no log message]
-
-2001-10-26 17:06 berk
-
- * Templates/: CMakeSystemConfig.cmake.in, configure, configure.in:
- added CMAKE_NO_EXPLICIT_TEMPLATE_INSTANTIATION
-
-2001-10-26 15:42 hoffman
-
- * Source/: cmConfigureFileCommand.cxx, cmMakefile.h, cmaketest.cxx:
- add dependency for configure files and use short path in WIN32
- cmake test
-
-2001-10-26 14:35 hoffman
-
- * Modules/FindVTK.cmake: use find_file and not just a set for
- USE_VTK_FILE
-
-2001-10-26 11:22 barre
-
- * Modules/DocumentationVTK.cmake: VTK documentation framework
-
-2001-10-26 09:29 andy
-
- * Source/cmCacheManager.cxx: Added check if the binary directory
- changed. If it did, it will print the warning message
-
-2001-10-24 20:37 barre
-
- * Modules/FindCygwin.cmake: Add GZIP (gzip)
-
-2001-10-24 20:33 barre
-
- * Modules/FindCygwin.cmake: Add TAR (path to tar or gtar)
-
-2001-10-24 17:51 berk
-
- * Source/cmUnixMakefileGenerator.cxx: ENH: allow -framework as a
- complete entry in the link line for Mac OSX
-
-2001-10-24 15:51 berk
-
- * DartConfig.cmake: public no longer has anonymous ftp.
-
-2001-10-24 09:41 king
-
- * Modules/FindGCCXML.cmake: ENH: Improved FIND_PROGRAM call to find
- the executable in PREFIX/share/GCC_XML, the new standard install
- location.
-
-2001-10-23 18:30 barre
-
- * Modules/FindCygwin.cmake: Cygwin mod
-
-2001-10-23 17:49 barre
-
- * Source/: cmGetFilenameComponentCommand.cxx,
- cmGetFilenameComponentCommand.h: The result of this utility
- command can now be optionally added to the cache
-
-2001-10-23 17:47 barre
-
- * Modules/FindDoxygen.cmake: Find Graphivz's dot too
-
-2001-10-23 17:06 barre
-
- * Modules/: FindDoxygen.cmake, FindWget.cmake: Add Doxygen and Wget
- modules. Very simple. But might be more complex later, so let's
- use them asap
-
-2001-10-23 16:55 barre
-
- * Modules/: FindHhc.cmake, FindPerl.cmake: Modules to find Perl and
- the HTML Help Compiler
-
-2001-10-19 10:07 barre
-
- * Source/cmEnableTestingCommand.h: Add warning regarding the
- location of ENABLE_TESTING (should be in the top CMakeList.txt,
- otherwise Dart is lost)
-
-2001-10-18 18:01 barre
-
- * Source/cmSiteNameCommand.cxx: SITE_NAME should return the most
- qualified name of the host. If nslookup works, now the domain is
- appended to the hostname (whereas it *replaced* the host name
- before)
-
-2001-10-18 13:51 iscott
-
- * Source/cmQTWrapCPPCommand.cxx: Detect error and output useful
- message Previously it would have got confused about the
- destinationSourceGroup
-
-2001-10-18 13:03 iscott
-
- * Source/cmFindFileCommand.cxx: This command should always set the
- cahce variabel to a filepath not a path
-
-2001-10-17 15:11 barre
-
- * Source/cmProjectCommand.cxx: Add PROJECT_NAME to the set of
- definitions
-
-2001-10-16 15:40 iscott
-
- * Modules/FindQt.cmake: fixed some stupid mistakes I thought I had
- tested these - honest
-
-2001-10-16 15:32 iscott
-
- * Modules/: FindQt.cmake, LinkQT.cmake: Some simple modules for
- finding and linking qt
-
-2001-10-15 18:37 hoffman
-
- * Source/cmMessageCommand.cxx: ENH: expand variables in message
- command output
-
-2001-10-15 18:36 hoffman
-
- * Source/cmSourceFile.cxx: ENH: clean up error report for source
- files not found
-
-2001-10-15 14:19 iscott
-
- * CMake.rtf, Source/cmCommands.cxx, Source/cmQTWrapCPPCommand.cxx,
- Source/cmQTWrapCPPCommand.h: added a QT_WRAP_CPP command
-
-2001-10-11 17:20 king
-
- * Source/cmCableWrapTclCommand.cxx: ENH: Improved parsing of
- GCCXML_FLAGS to improve generation of gccxml rule. Also added
- ADD_DEFINITIONS arguments to the generated rule.
-
-2001-10-11 14:57 andy
-
- * Source/cmCacheManager.cxx: Added removing of spaces in
- CMakeCache.txt in front of comments and variables
-
-2001-10-10 10:22 hoffman
-
- * Source/cmCacheManager.cxx: ENH: add a warning comment for cache
- values that can not be changed because they are always loaded
- from another cache
-
-2001-10-09 22:18 biddi
-
- * Source/cmBorlandMakefileGenerator.cpp: FIX: Same as last checkin
- except applies to bpi files as wellas lib files If we can't find
- it - and it's not a target - and it has no path already
- specified, it must be in OUTDIRLIB from another makefile in the
- same project ! (What this really means is the lib paths are
- correctly specified)
-
-2001-10-09 10:25 hoffman
-
- * Source/cmSystemTools.cxx: ENH: better fix for dos return in
- lines, use the regular expression and don't edit the input line
-
-2001-10-05 17:31 hoffman
-
- * Source/cmSystemTools.cxx: ENH: clean up returns from input, so we
- can read dos files on unix
-
-2001-10-04 09:32 starreveld
-
- * Templates/: configure, configure.in:
-
- ERR: remove undefined warning for compatibility with new 10.1
- linker
-
-2001-10-03 15:49 hoffman
-
- * Modules/Dart.cmake, Source/CMakeLists.txt, Source/cmake.cxx,
- Source/cmaketest.cxx: ENH: fixes for borland compiler testing
-
-2001-10-03 11:36 king
-
- * Modules/FindCABLE.cmake: ENH: Changed CABLE_BUILD_DIR to look for
- cableVersion.h instead of cable.README.txt.
-
-2001-10-02 23:10 biddi
-
- * Source/cmBorlandMakefileGenerator.cpp: FIX:if we can't find it -
- and it's not a target - and it has no path already specified, it
- must be in OUTDIRLIB from another makefile in the same project !
- (What this really means is the lib paths are correctly specified)
-
-2001-10-02 17:28 hoffman
-
- * Source/: cmListFileCache.cxx, cmMakefile.cxx, cmSystemTools.cxx,
- cmSystemTools.h, ctest.cxx: ENH: add better error reports in
- parsing cmake files, like what file has the error
-
-2001-10-01 13:35 martink
-
- * Source/: cmMakefile.h: version
-
-2001-10-01 13:26 hoffman
-
- * ChangeLog.txt: [no log message]
-
-2001-10-01 11:55 hoffman
-
- * Source/cmaketest.cxx: BUG: add missing include
-
-2001-10-01 10:14 hoffman
-
- * Source/cmaketest.cxx: ENH: change checkboxes back to pull down
- menus, remove leak
-
-2001-09-29 11:12 hoffman
-
- * Source/cmSystemTools.cxx: BUG: fix full path for file in current
- directory
-
-2001-09-28 13:35 berk
-
- * Source/cmSystemTools.cxx: BUG: fix realpath problem again...
-
-2001-09-28 12:14 berk
-
- * Source/cmSystemTools.cxx: BUG: separate path from file name
- before calling realpath
-
-2001-09-28 10:40 hoffman
-
- * Source/: cmSystemTools.cxx, cmUnixMakefileGenerator.cxx: BUG: get
- correct library name
-
-2001-09-28 10:34 hoffman
-
- * CMakeLists.txt: BUG: optional in wrong order
-
-2001-09-28 09:57 hoffman
-
- * CMakeLists.txt: make the include of the initial config flags
- optional, for builds that do not use configure
-
-2001-09-27 16:50 hoffman
-
- * Source/: cmSystemTools.cxx, cmUnixMakefileGenerator.cxx: BUG: use
- realpath instead of cd/pwd
-
-2001-09-27 15:54 hoffman
-
- * CMakeLists.txt, Source/CMakeLists.txt: BUG: fix install prefix
-
-2001-09-27 14:58 hoffman
-
- * configure, configure.in, Source/CMakeLists.txt,
- Source/InitialConfigureFlags.cmake.in: ENH: pass prefix from
- configure into cmake
-
-2001-09-26 16:23 berk
-
- * Modules/Dart.cmake: Typo.
-
-2001-09-25 14:39 martink
-
- * Modules/FindVTK.cmake: changes to chamghe
-
-2001-09-25 11:06 martink
-
- * Source/cmVTKWrapTclCommand.cxx: memory leak
-
-2001-09-21 11:48 martink
-
- * Modules/FindVTK.cmake: better install targets
-
-2001-09-21 09:40 king
-
- * Source/cmSystemTools.cxx: BUG: CopyFile should return immediately
- after an error occurs.
-
-2001-09-20 17:31 martink
-
- * Modules/FindVTK.cmake: updates
-
-2001-09-20 16:43 berk
-
- * Source/ctest.cxx: handle spaces in commands and args
-
-2001-09-20 15:08 hoffman
-
- * Source/: cmAbstractFilesCommand.cxx, cmAbstractFilesCommand.h,
- cmAddCustomTargetCommand.cxx, cmAddCustomTargetCommand.h,
- cmAddDefinitionsCommand.cxx, cmAddDefinitionsCommand.h,
- cmAddDependenciesCommand.cxx, cmAddDependenciesCommand.h,
- cmAddExecutableCommand.cxx, cmAddExecutableCommand.h,
- cmAddLibraryCommand.cxx, cmAddLibraryCommand.h,
- cmAddTestCommand.cxx, cmAddTestCommand.h,
- cmAuxSourceDirectoryCommand.cxx, cmAuxSourceDirectoryCommand.h,
- cmBuildCommand.cxx, cmBuildCommand.h, cmBuildNameCommand.cxx,
- cmBuildNameCommand.h, cmCableClassSetCommand.cxx,
- cmCableClassSetCommand.h, cmCableWrapTclCommand.cxx,
- cmCableWrapTclCommand.h, cmCommand.h, cmConfigureFileCommand.cxx,
- cmConfigureFileCommand.h, cmConfigureGccXmlCommand.cxx,
- cmConfigureGccXmlCommand.h, cmElseCommand.cxx, cmElseCommand.h,
- cmEnableTestingCommand.h, cmEndForEachCommand.cxx,
- cmEndForEachCommand.h, cmEndIfCommand.cxx, cmEndIfCommand.h,
- cmExecProgramCommand.cxx, cmExecProgramCommand.h,
- cmFindFileCommand.cxx, cmFindFileCommand.h,
- cmFindLibraryCommand.cxx, cmFindLibraryCommand.h,
- cmFindPathCommand.cxx, cmFindPathCommand.h,
- cmFindProgramCommand.cxx, cmFindProgramCommand.h,
- cmForEachCommand.cxx, cmForEachCommand.h,
- cmGetFilenameComponentCommand.cxx,
- cmGetFilenameComponentCommand.h, cmIfCommand.cxx, cmIfCommand.h,
- cmIncludeCommand.cxx, cmIncludeCommand.h,
- cmIncludeDirectoryCommand.cxx, cmIncludeDirectoryCommand.h,
- cmIncludeRegularExpressionCommand.cxx,
- cmIncludeRegularExpressionCommand.h, cmInstallFilesCommand.cxx,
- cmInstallFilesCommand.h, cmInstallProgramsCommand.cxx,
- cmInstallProgramsCommand.h, cmInstallTargetsCommand.cxx,
- cmInstallTargetsCommand.h, cmLibraryCommand.h,
- cmLinkDirectoriesCommand.cxx, cmLinkDirectoriesCommand.h,
- cmLinkLibrariesCommand.cxx, cmLinkLibrariesCommand.h,
- cmLoadCacheCommand.cxx, cmLoadCacheCommand.h,
- cmMakeDirectoryCommand.cxx, cmMakeDirectoryCommand.h,
- cmMakefile.cxx, cmMakefile.h, cmMessageCommand.cxx,
- cmMessageCommand.h, cmOptionCommand.cxx, cmOptionCommand.h,
- cmOutputRequiredFilesCommand.cxx, cmOutputRequiredFilesCommand.h,
- cmProjectCommand.cxx, cmProjectCommand.h, cmSetCommand.cxx,
- cmSetCommand.h, cmSiteNameCommand.cxx, cmSiteNameCommand.h,
- cmSourceFilesCommand.cxx, cmSourceFilesCommand.h,
- cmSourceFilesRemoveCommand.cxx, cmSourceFilesRemoveCommand.h,
- cmSourceGroupCommand.cxx, cmSourceGroupCommand.h,
- cmSubdirCommand.cxx, cmSubdirCommand.h,
- cmSubdirDependsCommand.cxx, cmSubdirDependsCommand.h,
- cmTargetLinkLibrariesCommand.cxx, cmTargetLinkLibrariesCommand.h,
- cmUseMangledMesaCommand.cxx, cmUseMangledMesaCommand.h,
- cmUtilitySourceCommand.cxx, cmUtilitySourceCommand.h,
- cmVTKWrapJavaCommand.cxx, cmVTKWrapJavaCommand.h,
- cmVTKWrapPythonCommand.cxx, cmVTKWrapPythonCommand.h,
- cmVTKWrapTclCommand.cxx, cmVTKWrapTclCommand.h,
- cmWrapExcludeFilesCommand.cxx, cmWrapExcludeFilesCommand.h: ENH:
- change InitialPass to take a const reference to the argument
- string, to avoid changes to the file cache
-
-2001-09-20 13:44 martink
-
- * Source/cmMakefile.cxx: BUG: make a copy of the arguments before
- passing them to Execute
-
-2001-09-20 12:00 martink
-
- * CMake.rtf: fixed some problems
-
-2001-09-20 10:57 king
-
- * Modules/FindCABLE.cmake: ENH: Added support for finding cable
- when it is built in a configuration subdirectory by MSVC.
-
-2001-09-20 10:54 king
-
- * Source/: cmFindFileCommand.cxx, cmFindLibraryCommand.cxx,
- cmFindPathCommand.cxx, cmFindProgramCommand.cxx,
- cmSystemTools.cxx, cmSystemTools.h: ENH: Added
- cmSystemTools::GlobDirs function to allow wildcards in paths
- (like /foo/bar/*).
-
-2001-09-20 10:53 king
-
- * Source/cmSetCommand.cxx: ENH: Added extra newline in an error
- message to improve readability.
-
-2001-09-20 10:27 martink
-
- * Modules/FindVTK.cmake: minor changes
-
-2001-09-20 09:11 martink
-
- * Modules/: FindVTK.cmake, UseVTKIncludes.cmake,
- UseVTKLibraries.cmake: removed some VTK stuff
-
-2001-09-19 14:52 martink
-
- * Modules/: FindVTK.cmake, UseVTKIncludes.cmake,
- UseVTKLibraries.cmake: updated to how FindVTK works
-
-2001-09-19 14:20 martink
-
- * Source/cmMakefile.h: version rev to 95
-
-2001-09-19 14:20 martink
-
- * Source/cmMakefile.h: version rev to 94
-
-2001-09-18 10:45 hoffman
-
- * ChangeLog.txt: [no log message]
-
-2001-09-18 10:38 will
-
- * CMake.pdf: ENH:Updated documentation
-
-2001-09-17 17:40 hoffman
-
- * CMake.rtf: ENH: update for new version
-
-2001-09-17 16:36 hoffman
-
- * Source/: cmUseMangledMesaCommand.cxx, cmUseMangledMesaCommand.h:
- ENH: change to take a path as input
-
-2001-09-17 16:34 hoffman
-
- * Source/cmFindFileCommand.cxx: BUG: fix return when file is not
- found
-
-2001-09-17 14:16 king
-
- * Modules/FindCABLE.cmake: ENH: Added find support for looking at
- Cable's build directory if the user sets the CABLE_BUILD_DIR
- cache entry.
-
-2001-09-17 13:58 hoffman
-
- * Source/: cmCommands.cxx, cmUseMangledMesaCommand.cxx,
- cmUseMangledMesaCommand.h: ENH: add Use mangled mesa command
-
-2001-09-17 12:07 blezek
-
- * Modules/Dart.cmake: ENH: NightlyCoverage got lost
-
-2001-09-14 16:36 martink
-
- * Source/: cmVTKWrapTclCommand.cxx, cmVTKWrapJavaCommand.cxx,
- cmVTKWrapPythonCommand.cxx: now uses five argument version of
- wrap commands
-
-2001-09-14 16:26 hoffman
-
- * Source/: cmMakefileGenerator.cxx, cmStandardIncludes.h,
- cmUnixMakefileGenerator.cxx, cmUnixMakefileGenerator.h,
- cmakemain.cxx: remove memory leaks
-
-2001-09-14 15:18 hoffman
-
- * Source/cmDSPWriter.cxx: fix error in cygwin
-
-2001-09-14 15:18 hoffman
-
- * Source/cmListFileCache.h: initialize class
-
-2001-09-14 15:18 hoffman
-
- * Source/: cmMakefileGenerator.cxx, cmMakefileGenerator.h: add
- support for clean up
-
-2001-09-14 10:14 martink
-
- * Templates/: DLLHeader.dsptemplate, EXEHeader.dsptemplate,
- EXEWinHeader.dsptemplate, UtilityHeader.dsptemplate,
- staticLibHeader.dsptemplate: made Debug the default configuration
-
-2001-09-14 08:34 barre
-
- * Modules/FindTCL.cmake: move cygtclsh80 to the end of list,
- otherwise it might be found while the non-cygwin wish8x.exe will
- be found too. If wish8x.exe is found, then the non-cygwin
- tclsh8x.exe must be found too.
-
-2001-09-13 14:45 martink
-
- * Modules/Dart.cmake: added back some targets for UNIX
-
-2001-09-13 11:27 martink
-
- * Source/: cmSystemTools.h, cmSystemTools.cxx: added shortest ext
- function
-
-2001-09-12 17:09 lorensen
-
- * Source/cmSiteNameCommand.cxx: ENH: drop the case of the site
- name. This makes it consistent with Dart's usage.
-
-2001-09-12 17:09 lorensen
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Added LowerCase
- method.
-
-2001-09-12 15:18 king
-
- * Source/: cmCableWrapTclCommand.cxx, cmCableWrapTclCommand.h: ENH:
- Added parsing of gccxml flags into separate arguments for setting
- the custom command. This is necessary since the custom command
- now takes a vector of individual command line options instead of
- a single string.
-
-2001-09-11 21:46 biddi
-
- * Templates/CMakeWindowsBorlandConfig.cmake: ERR: Spelling
-
-2001-09-11 21:45 biddi
-
- * Source/: cmBorlandMakefileGenerator.cpp,
- cmBorlandMakefileGenerator.h, cmSystemTools.cxx: ERR: Change to
- EscapeSpaces forces rework of Borland generator <sigh> Add clause
- to prevent adding quotes when they're already present, then stuff
- them onto all lib paths to prevent forward slashes causing
- trouble.
-
-2001-09-11 20:00 biddi
-
- * Source/: cmBorlandMakefileGenerator.cpp,
- cmBorlandMakefileGenerator.h: ENH: Major fix of the Borland
- generator which addresses the problem of libraries with
- dependencies (other libraries) not linking when required.
- Dependency checking required the full path to be supplied to each
- file when they're not in the current directory (very tedious).
- All seems to be working nicely now.
-
-2001-09-11 19:58 biddi
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Add a findfile
- routine (as opposed to find executable or library) which doesn't
- add any extensions - Borland make needs full paths to certain
- dependencies otherwise linking doesn't work properly
- (dependencies aren't checked)
-
-2001-09-11 15:17 martink
-
- * Source/ctest.cxx: updated testing
-
-2001-09-11 14:58 martink
-
- * Source/cmDSPWriter.cxx: include fixes
-
-2001-09-11 14:43 martink
-
- * Modules/Dart.cmake: reduced the number of targets
-
-2001-09-11 14:42 martink
-
- * Source/cmaketest.cxx: bug in testing code
-
-2001-09-11 13:44 hoffman
-
- * Source/cmBorlandMakefileGenerator.cpp: BUG: fix build with
- non-borland compiler
-
-2001-09-11 13:40 martink
-
- * Source/cmDSPWriter.cxx: fix for include paths
-
-2001-09-10 15:11 martink
-
- * Modules/Dart.cmake: reduced targets and merged tclsh commands
-
-2001-09-10 15:11 martink
-
- * Source/: cmCableWrapTclCommand.cxx, cmDSPWriter.cxx,
- cmMakefile.cxx, cmMakefile.h, cmSystemTools.cxx,
- cmVTKWrapJavaCommand.cxx, cmVTKWrapPythonCommand.cxx,
- cmVTKWrapTclCommand.cxx: various windows fixes
-
-2001-09-10 11:03 berk
-
- * Source/CMakeLists.txt: Typo in link command.
-
-2001-09-08 12:09 biddi
-
- * Source/: cmBorlandMakefileGenerator.cpp,
- cmBorlandMakefileGenerator.h: ERR: Forgot to put back a backslash
-
-2001-09-08 10:02 biddi
-
- * Source/cmBorlandMakefileGenerator.cpp: ERR: LINK_DIR must ot have
- backslah at end. Fix plus cleanup of some code.
-
-2001-09-07 10:08 martink
-
- * Source/cmDirectory.cxx: fixed bug in mismatched directory opens
- consuming file descriptors
-
-2001-09-07 09:40 king
-
- * Source/cmConfigureGccXmlCommand.cxx: ENH: Removed addition of
- compiler support directory include option since the
- find_*_options scripts now include it automatically.
-
-2001-09-06 18:02 hoffman
-
- * Source/: CMakeLists.txt, cmBorlandMakefileGenerator.cpp: BUG:
- clean up lib and exe output paths
-
-2001-09-06 17:28 hoffman
-
- * Source/CMakeLib.dsp, Source/cmBorlandMakefileGenerator.cpp,
- Source/cmBorlandMakefileGenerator.h,
- Source/cmMSProjectGenerator.h, Source/cmMakefileGenerator.cxx,
- Source/cmMakefileGenerator.h, Source/cmUnixMakefileGenerator.h,
- Source/cmake.cxx, Source/cmake.h,
- Templates/CMakeWindowsBorlandConfig.cmake: ENH: integrate borland
- support
-
-2001-09-04 16:29 biddi
-
- * Source/cmBorlandMakefileGenerator.cpp,
- Source/cmBorlandMakefileGenerator.h,
- Templates/CMakeWindowsBorlandConfig.cmake: NEW: First check in of
- Borland Makefile Generator and template stuff
-
-2001-09-04 16:07 hoffman
-
- * Source/: cmAddCustomTargetCommand.cxx, cmCustomCommand.cxx,
- cmCustomCommand.h, cmDSPWriter.cxx, cmDSWWriter.cxx,
- cmMakefile.cxx, cmMakefile.h, cmSourceGroup.cxx, cmSourceGroup.h,
- cmVTKWrapJavaCommand.cxx: ENH: separate command from its
- arguments in the custom command. This allows the generator on
- windows to change the slashes for just the command
-
-2001-09-01 17:13 biddi
-
- * Source/cmBuildCommand.cxx: ENH: Added a clause for Borland
- compiler compatibility
-
-2001-09-01 16:56 barre
-
- * Source/cmDSPWriter.cxx: Convert path format back to Windows
- slashes syntax. Mandatory for Win98 build.
-
-2001-09-01 16:55 barre
-
- * Source/cmSystemTools.cxx: fix comment pb
-
-2001-09-01 16:13 biddi
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Windows and
- Unix slash conversions return a char*, clean function seperated
- from Convert function
-
-2001-09-01 16:12 biddi
-
- * Source/: cmMakefile.cxx, cmMakefile.h: ENH: ExpandVariables
- functions return a char * for convenience
-
-2001-08-31 21:10 starreveld
-
- * Source/cmUnixMakefileGenerator.cxx:
-
- ENH: Generate compile lines for .m, .M, and .mm files (ObjC and
- ObjC++)
-
-2001-08-30 17:32 hoffman
-
- * Source/cmMakefile.cxx: BUG: fix incorrect deletion of function
- blockers
-
-2001-08-30 16:19 martink
-
- * Source/: cmMakefile.h: version rev
-
-2001-08-30 16:06 hoffman
-
- * ChangeLog, ChangeLog.txt: [no log message]
-
-2001-08-30 15:54 hoffman
-
- * ChangeLog.txt: ENH: add autogenerated changelog
-
-2001-08-29 17:21 hoffman
-
- * Source/cmake.cxx: opps
-
-2001-08-29 17:11 king
-
- * Source/cmConfigureGccXmlCommand.cxx: BUG: GCCXML_FLAGS found from
- find_gcc_options or find_mpro_options should have the trailing
- newline stripped from the string.
-
-2001-08-29 17:10 king
-
- * Source/cmCableWrapTclCommand.cxx: ENH: Updated generated
- dependencies since cable's installation directory now uses
- separate CxxTypes and WrapTclFacility subdirecories for includes.
-
-2001-08-29 17:08 king
-
- * Modules/FindCABLE.cmake: ENH: Updated library finding code to
- handle new cable installation directory structure. It now uses
- separate directories for CxxTypes and WrapTclFacility headers.
-
-2001-08-29 16:42 martink
-
- * Source/: ctest.cxx, ctest.h: added regexp option
-
-2001-08-29 16:13 hoffman
-
- * Source/: CMakeLib.dsp, DumpDocumentation.dsp, cmake.dsp,
- ctest.dsp: remove /ZI
-
-2001-08-29 15:57 hoffman
-
- * Source/: cmake.cxx, cmaketest.cxx: ENH: run cmake from cmaketest
-
-2001-08-29 10:47 king
-
- * Source/cmMakefile.h: ENH: Added a const version of
- GetLinkLibraries().
-
-2001-08-29 10:46 king
-
- * Source/: cmUnixMakefileGenerator.cxx, cmUnixMakefileGenerator.h:
- ENH: Proper dependencies between shared libraries now exist in
- the generated makefiles. If a shared library links to another,
- the other will be built before the link is attempted.
-
-2001-08-29 09:57 hoffman
-
- * Source/cmMakefile.cxx: clean up a bit
-
-2001-08-29 09:44 berk
-
- * Source/cmSystemTools.cxx: BUG: fix out of bounds read on string
- in mkdir
-
-2001-08-29 09:26 perera
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Special value
- IGNORE behaves like NOTFOUND, but makes FindLibrary, etc, _not_
- search for a library, etc.
-
-2001-08-28 18:35 hoffman
-
- * Source/cmListFileCache.h: remove warning
-
-2001-08-28 18:28 hoffman
-
- * Source/: CMakeLib.dsp, CMakeLists.txt, CMakeSetup.dsw,
- Makefile.in, cmListFileCache.cxx, cmListFileCache.h,
- cmMakefile.cxx: ENH: add caching for the input CMakeList.txt
- files, 2X speed up
-
-2001-08-28 18:27 hoffman
-
- * Source/cmDSPWriter.cxx: BUG: put spaces in /I paths
-
-2001-08-28 18:02 starreveld
-
- * Source/: cmAddLibraryCommand.cxx, cmAddLibraryCommand.h,
- cmMakefile.cxx, cmMakefile.h, cmTarget.h,
- cmUnixMakefileGenerator.cxx:
-
- Changes to allow MODULE type target for a shared library
-
-2001-08-28 18:01 starreveld
-
- * Templates/: CMakeSystemConfig.cmake.in, configure, configure.in:
-
- Changes to allow a MODULE target for a shared library.
-
-2001-08-28 16:04 martink
-
- * CMakeLists.txt, Tests/Complex/CMakeLists.txt,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexRelativePaths/CMakeLists.txt: minor fix
-
-2001-08-28 14:55 martink
-
- * Source/: cmDSPWriter.cxx, cmSystemTools.cxx, cmSystemTools.h:
- better network build support
-
-2001-08-28 13:49 starreveld
-
- * Templates/: configure, configure.in:
-
- Added support for Darwin (OSX)
-
-2001-08-28 10:57 hoffman
-
- * Modules/FindTCL.cmake: ENH: support for cygwin
-
-2001-08-28 10:57 hoffman
-
- * Source/: cmSystemTools.cxx, cmUnixMakefileGenerator.cxx: BUG: fix
- for broken apple mkdir and general clean up of MakeDirectory
- command
-
-2001-08-27 15:19 martink
-
- * Source/cmDSPWriter.cxx: support for network path link libraries
-
-2001-08-27 14:44 hoffman
-
- * Source/: cmMakefile.cxx, cmMakefile.h,
- cmUnixMakefileGenerator.cxx: ENH: change expand variables to use
- GetDefinition
-
-2001-08-27 14:38 hoffman
-
- * configure, configure.in: [no log message]
-
-2001-08-27 14:35 hoffman
-
- * configure, configure.in, Source/Makefile.in: ENH: clean up sgi
- build and use non-broken autoconf
-
-2001-08-27 12:24 hoffman
-
- * configure, Source/cmUnixMakefileGenerator.cxx,
- Templates/configure: [no log message]
-
-2001-08-27 11:03 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: set CXX and CC when
- running configure from cmake
-
-2001-08-27 10:23 martink
-
- * Source/ctest.cxx: better formatted output
-
-2001-08-27 10:22 hoffman
-
- * Templates/: configure, configure.in: ENH: use ANSI_CXXFLAGS for
- testing compiler
-
-2001-08-27 10:11 hoffman
-
- * CMakeLists.txt, Templates/CMakeSystemConfig.cmake.in,
- Templates/configure, Templates/configure.in,
- Tests/Complex/CMakeLists.txt,
- Tests/ComplexOneConfig/CMakeLists.txt,
- Tests/ComplexRelativePaths/CMakeLists.txt: ENH: sgi -LANG:std
-
-2001-08-27 10:07 berk
-
- * Source/CMakeSetup.dsw: ken added dependancy to build everything
-
-2001-08-25 12:31 martink
-
- * Source/: CMakeSetup.dsw, ctest.dsp: added ctest to win32
-
-2001-08-24 17:50 hoffman
-
- * Templates/: configure, configure.in: [no log message]
-
-2001-08-24 17:30 hoffman
-
- * Templates/: CMakeSystemConfig.cmake.in, configure, configure.in:
- ENH: more sgi -LANG stuff
-
-2001-08-24 17:25 hoffman
-
- * configure, configure.in: auto detect lang:std:
-
-2001-08-24 17:17 hoffman
-
- * Source/Makefile.in: ENH: build for sgi CC out of box
-
-2001-08-24 17:12 hoffman
-
- * configure, configure.in: auto detect lang:std:
-
-2001-08-24 17:00 hoffman
-
- * configure, configure.in: auto detect lang:std:
-
-2001-08-24 16:51 hoffman
-
- * configure, configure.in: auto detect lang:std:
-
-2001-08-24 15:54 hoffman
-
- * Tests/: Complex/cmTestConfigure.h.in,
- Complex/Executable/complex.cxx,
- ComplexOneConfig/cmTestConfigure.h.in,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexRelativePaths/cmTestConfigure.h.in,
- ComplexRelativePaths/Executable/complex.cxx: BUG: fix complex
- test for old compilers
-
-2001-08-24 15:45 hoffman
-
- * configure, configure.in, Tests/Complex/cmTestConfigure.h.in,
- Tests/ComplexOneConfig/cmTestConfigure.h.in,
- Tests/ComplexRelativePaths/cmTestConfigure.h.in: BUG: fix for SGI
- Native compiler
-
-2001-08-24 15:41 hoffman
-
- * Templates/: configure, configure.in: BUG: fix flag for building
- shared on HP
-
-2001-08-23 18:30 perera
-
- * Source/: cmAddTestCommand.cxx, cmAddTestCommand.h: BUG: ADD_TEST
- now only does stuff if ENABLE_TESTING has been run.
-
-2001-08-23 18:02 hoffman
-
- * Source/: cmMakefile.cxx, cmSystemTools.cxx, cmSystemTools.h: ENH:
- improve coverage
-
-2001-08-23 17:40 hoffman
-
- * Source/: CMakeLists.txt, cmDumpDocumentation.cxx, cmMakefile.cxx,
- cmMakefile.h: ENH: add dump documentation test
-
-2001-08-23 16:28 king
-
- * Source/: cmCableWrapTclCommand.cxx, cmCableWrapTclCommand.h: ENH:
- Each cmCableWrapTclCommand instance now uses a single
- cmMakeDepend object for dependencies for all the gccxml input
- files it generates. This should significantly improve generation
- time.
-
-2001-08-23 16:24 hoffman
-
- * Source/cmaketest.cxx: BUG: run make all on unix not make exename
-
-2001-08-23 16:00 hoffman
-
- * Source/: CMakeLists.txt, cmStandardIncludes.h, cmaketest.cxx,
- ctest.cxx: ENH: add more testing
-
-2001-08-23 13:57 hoffman
-
- * Tests/: Complex/CMakeLists.txt, Complex/VarTests.txt,
- Complex/cmTestConfigure.h.in, Complex/simple.cxx,
- Complex/Executable/CMakeLists.txt,
- Complex/Executable/complex.cxx, Complex/Library/CMakeLists.txt,
- Complex/Library/file2.cxx, Complex/Library/file2.h,
- Complex/Library/sharedFile.cxx, Complex/Library/sharedFile.h,
- Complex/Library/ExtraSources/file1.cxx,
- Complex/Library/ExtraSources/file1.h,
- ComplexOneConfig/CMakeLists.txt, ComplexOneConfig/VarTests.txt,
- ComplexOneConfig/cmTestConfigure.h.in,
- ComplexOneConfig/simple.cxx,
- ComplexOneConfig/Executable/CMakeLists.txt,
- ComplexOneConfig/Executable/complex.cxx,
- ComplexOneConfig/Library/CMakeLists.txt,
- ComplexOneConfig/Library/file2.cxx,
- ComplexOneConfig/Library/file2.h,
- ComplexOneConfig/Library/sharedFile.cxx,
- ComplexOneConfig/Library/sharedFile.h,
- ComplexOneConfig/Library/ExtraSources/file1.cxx,
- ComplexOneConfig/Library/ExtraSources/file1.h,
- ComplexRelativePaths/CMakeLists.txt,
- ComplexRelativePaths/VarTests.txt,
- ComplexRelativePaths/cmTestConfigure.h.in,
- ComplexRelativePaths/simple.cxx,
- ComplexRelativePaths/Executable/CMakeLists.txt,
- ComplexRelativePaths/Executable/complex.cxx,
- ComplexRelativePaths/Library/CMakeLists.txt,
- ComplexRelativePaths/Library/file2.cxx,
- ComplexRelativePaths/Library/file2.h,
- ComplexRelativePaths/Library/sharedFile.cxx,
- ComplexRelativePaths/Library/sharedFile.h,
- ComplexRelativePaths/Library/ExtraSources/file1.cxx,
- ComplexRelativePaths/Library/ExtraSources/file1.h: ENH: try to
- get better test coverage
-
-2001-08-23 13:12 martink
-
- * Source/ctest.cxx: also check path for test executables
-
-2001-08-23 11:39 martink
-
- * Source/ctest.cxx: fixed format
-
-2001-08-23 11:32 martink
-
- * Source/cmUnixMakefileGenerator.cxx: better ctest support
-
-2001-08-23 11:12 martink
-
- * Source/: CMakeLists.txt, cmSystemTools.cxx, cmSystemTools.h,
- cmUnixMakefileGenerator.cxx, ctest.cxx, ctest.h: added test
- driver for make test target
-
-2001-08-22 16:33 martink
-
- * Source/cmDSPWriter.cxx: ENH: do not put a rule in to rebuild the
- ALL_BUILD.dsp file, as it is not possible...
-
-2001-08-22 11:58 hoffman
-
- * Source/: cmCableClassSet.h, cmCableWrapTclCommand.cxx,
- cmCacheManager.cxx, cmCacheManager.h, cmMakeDepend.h,
- cmMakefile.h, cmSourceGroup.h, cmStandardIncludes.h, cmTarget.h,
- cmUnixMakefileGenerator.cxx: ENH: change all maps of string to be
- maps of cmStdString, to reduce symbol length in object files.
-
-2001-08-22 11:26 hoffman
-
- * Source/cmMakefile.h: BUG: shorten length of symbols
-
-2001-08-22 10:12 berk
-
- * Source/cmDSPWriter.cxx: OUTDIR->IntDir
-
-2001-08-21 11:04 starreveld
-
- * Source/cmMakefile.cxx:
-
- Added support for .mm source files (ObjC++)
-
-2001-08-20 13:32 hoffman
-
- * Templates/: configure, configure.in: BUG: fix check for no std::
-
-2001-08-20 09:23 hoffman
-
- * Source/cmSetCommand.cxx: BUG: cmSystemTools::CollapseFullPath is
- a bad thing to call on the compiler which is a filepath
-
-2001-08-19 19:11 barre
-
- * Source/cmOptionCommand.cxx: Allow option value to be expanded
- (thus, we can use the value of another option as default)
-
-2001-08-19 12:14 barre
-
- * Source/cmMakefile.cxx: gcc and MSVC clash on
- basic_string::compare(), let's try substr()
-
-2001-08-19 07:36 barre
-
- * Source/cmSetCommand.cxx: If the value is a path, collapse it
- (cleaner)
-
-2001-08-18 17:57 hoffman
-
- * Templates/: configure, configure.in: BUG: get the flags right
-
-2001-08-18 12:51 barre
-
- * Source/cmMakefile.cxx, Modules/FindDart.cmake: Support for
- $ENV{VAR} syntax (lookup in the environment vars)
-
-2001-08-17 17:11 martink
-
- * Source/: cmElseCommand.cxx, cmIfCommand.cxx: backwards MATCHES in
- if and else statements
-
-2001-08-16 18:01 hoffman
-
- * Templates/configure: ENH: default for cygwin should be pthreads
-
-2001-08-16 17:42 hoffman
-
- * Templates/: CMakeSystemConfig.cmake.in,
- CMakeWindowsSystemConfig.cmake, configure, configure.in: ENH: add
- CMAKE_USE_WIN32_THREADS to the possible thread types
-
-2001-08-16 11:41 berk
-
- * Source/: cmCacheManager.cxx, cmCacheManager.h,
- cmLoadCacheCommand.cxx, cmLoadCacheCommand.h: Adding new options
- to LoadCache.
-
-2001-08-15 13:40 berk
-
- * Source/: cmCacheManager.cxx, cmCacheManager.h,
- cmLoadCacheCommand.cxx: 1. Added EXCLUDE option to LOAD_CACHE.
- 2. Entries brought in from another cache are now marked as
- internal.
-
-2001-08-15 13:23 martink
-
- * Modules/FindDart.cmake: looks at same level
-
-2001-08-15 10:03 hoffman
-
- * Templates/: configure, configure.in: ENH: make pthreads the
- default for cygwin
-
-2001-08-14 17:18 king
-
- * Source/: cmInstallFilesCommand.cxx, cmInstallFilesCommand.h,
- cmInstallProgramsCommand.cxx, cmInstallProgramsCommand.h,
- cmMakefile.cxx: ENH: Improved INSTALL_FILES and INSTALL_PROGRAMS
- commands to allow each call to the command in a single directory
- to specify a different install path.
-
-2001-08-13 16:04 martink
-
- * Modules/Dart.cmake: removed grep
-
-2001-08-10 15:52 martink
-
- * Source/: cmVTKWrapTclCommand.cxx, cmMakefile.h: now creates
- output directories
-
-2001-08-09 15:35 hoffman
-
- * CMake.pdf: ENH: update pdf to rtf
-
-2001-08-09 15:23 hoffman
-
- * CMake.rtf: ENH: add some docs for sgi CC
-
-2001-08-09 14:58 berk
-
- * Source/: cmElseCommand.cxx, cmIfCommand.cxx: BUG: or and and were
- inverted.
-
-2001-08-09 11:12 hoffman
-
- * ChangeLog: add generated ChangeLog file. Should be updated each
- time a new version is made
-
-2001-08-09 11:08 martink
-
- * Source/: cmMakefile.h: updated version
-
-2001-08-09 11:07 martink
-
- * README: out of date
-
-2001-08-09 09:33 hoffman
-
- * Source/cmConfigure.cmake.h.in: BUG: add in for scope variable
-
-2001-08-08 13:14 hoffman
-
- * Source/: cmSiteNameCommand.cxx, cmUtilitySourceCommand.cxx: BUG:
- can not Add a definition that you just got
-
-2001-08-08 11:54 hoffman
-
- * configure, configure.in, Source/cmBuildCommand.cxx,
- Source/cmBuildNameCommand.cxx, Source/cmCableWrapTclCommand.cxx,
- Source/cmCacheManager.cxx, Source/cmCacheManager.h,
- Source/cmConfigure.h.in, Source/cmConfigureGccXmlCommand.cxx,
- Source/cmDSPWriter.cxx, Source/cmDSWWriter.cxx,
- Source/cmFindFileCommand.cxx, Source/cmFindLibraryCommand.cxx,
- Source/cmFindPathCommand.cxx, Source/cmFindProgramCommand.cxx,
- Source/cmLinkLibrariesCommand.cxx,
- Source/cmMSProjectGenerator.cxx, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmOptionCommand.cxx,
- Source/cmProjectCommand.cxx, Source/cmSetCommand.cxx,
- Source/cmSiteNameCommand.cxx, Source/cmStandardIncludes.h,
- Source/cmSystemTools.cxx, Source/cmUnixMakefileGenerator.cxx,
- Source/cmUtilitySourceCommand.cxx,
- Source/cmVTKWrapJavaCommand.cxx,
- Source/cmVTKWrapPythonCommand.cxx,
- Source/cmVTKWrapTclCommand.cxx,
- Templates/CMakeSystemConfig.cmake.in, Templates/configure,
- Templates/configure.in: ENH: big change, only allow commands
- access to the cache via the cmMakefile class and GetDefinition,
- also the cmMakefile is the only way for commands to add to the
- cache. Also, some changes to configure.in that check for for
- scoping
-
-2001-08-07 15:49 hoffman
-
- * Source/: cmStandardIncludes.h, cmSystemTools.cxx: ENH: compile
- with broken 720 SGI C++ compiler
-
-2001-08-07 13:46 hoffman
-
- * Source/cmMakefile.cxx: ENH: html output for docs
-
-2001-08-07 13:15 hoffman
-
- * CMake.rtf: ENH: update documents with current commands and new
- GUI
-
-2001-08-07 08:47 king
-
- * CMakeLists.txt: ERR: CMakeLogo.gif has been moved to the root
- directory of the source so that the Web and Web/Art directories
- are not needed here.
-
-2001-08-07 08:46 king
-
- * CMakeLogo.gif: ENH: CMakeLogo for Dart to use on testing web
- page.
-
-2001-08-06 17:01 martink
-
- * Source/: cmElseCommand.cxx, cmElseCommand.h, cmIfCommand.cxx,
- cmIfCommand.h: added new if commands
-
-2001-08-06 15:11 king
-
- * CMake.pdf, CMake.rtf: Re-adding doc files. They were
- accidentally removed due to a symlink from the CMake/Web
- directory when it was removed.
-
-2001-08-06 15:01 king
-
- * CMake.pdf, CMake.rtf: Removing Web directory from CMake. It is
- moving to a separate, parallel CVS module called "CMakeWeb"
-
-2001-08-03 15:47 king
-
- * Source/: cmConfigureFileCommand.cxx, cmConfigureFileCommand.h:
- ENH: Added 'IMMEDIATE' option to CONFIGURE_FILE command to force
- file copy and configuration on the initial pass so that current
- variable values are used.
-
-2001-08-02 17:27 king
-
- * Source/: cmCableWrapTclCommand.cxx, cmCableWrapTclCommand.h: ENH:
- Added use of a class's tag to generate a better set of filenames
- for its wrapper configuration, xml, and generated files. This
- should also prevent half the classes from re-wrapping when a new
- one is inserted in the middle.
-
-2001-08-02 14:42 king
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: Generated link line for
- shared libraries had CMAKE_CXX_FLAGS instead of CMAKE_CXXFLAGS
- (note underscore).
-
-2001-08-02 14:10 king
-
- * Source/cmMakefile.cxx: BUG: Fixed off-by-one error in
- ExpandVariablesInString for case of $ or @ as last character of
- string.
-
-2001-08-02 09:07 king
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: We don't want to output
- -I/usr/include in the INCLUDE_FLAGS variable. This causes
- problems with finding system headers in the wrong places for
- certain standard library implementations.
-
-2001-08-01 16:14 king
-
- * Source/: cmCommands.cxx, cmMakefile.cxx, cmMakefile.h,
- cmSubdirDependsCommand.cxx, cmSubdirDependsCommand.h,
- cmUnixMakefileGenerator.cxx: ENH: Added SUBDIR_DEPENDS command
- and corresponding support code. This command allows
- specification that a set of subdirectories be built before a
- particular directory.
-
-2001-08-01 16:13 king
-
- * Source/cmAddDefinitionsCommand.cxx: BUG: Needed to expand
- variables of definitions.
-
-2001-08-01 16:12 king
-
- * Source/cmInstallFilesCommand.cxx: BUG: Need to expand variables
- when a regular expression is specified.
-
-2001-08-01 16:11 king
-
- * Modules/FindCABLE.cmake: ENH: Support to find CABLE utility if it
- is installed.
-
-2001-08-01 11:19 king
-
- * Modules/FindTCL.cmake: ENH: Added tk library names tk8.4 tk8.3
- tk8.2 and tk8.0 to correspond to tk84 tk83 tk82 and tk80.
- TK_LIBRARY should now be found on more platforms.
-
-2001-07-31 11:29 king
-
- * Source/cmCommands.cxx, Source/cmDSPWriter.cxx,
- Source/cmDSWWriter.cxx, Source/cmInstallFilesCommand.cxx,
- Source/cmInstallProgramsCommand.cxx,
- Source/cmInstallProgramsCommand.h, Source/cmMakefile.cxx,
- Source/cmTarget.cxx, Source/cmTarget.h,
- Source/cmUnixMakefileGenerator.cxx, Templates/CMakeLists.txt:
- ENH: Added INSTALL_PROGRAMS command and corresponding support.
- This involved splitting cmTarget::INSTALL into INSTALL_FILES and
- INSTALL_PROGRAMS enum values. INSTALL_FILES no longer adds
- execute permission. The INSTALL_PROGRAMS commnad takes either a
- list of explicit names, or a regex. It will not expand source
- lists like the INSTALL_FILES command will.
-
-2001-07-30 12:21 king
-
- * Source/cmCableClassSet.cxx: ERR:
- ElementCombinationGenerator::ReplacePortion needs to be a friend
- of ElementCombinationGenerator so that it can get access to
- ElementCombinationGenerator::Substitution. Also fixed one minor
- problem for HP build.
-
-2001-07-30 11:34 king
-
- * Source/: cmCableClassSet.cxx, cmCableWrapTclCommand.cxx,
- cmDSPWriter.cxx, cmMakeDepend.cxx, cmMakefile.cxx, cmMakefile.h,
- cmUnixMakefileGenerator.cxx: BUG: Changed include and link
- directory paths in cmMakefile back to std::vector because there
- is an order dependency. Only cmMakefile::AddIncludeDirectory and
- cmMakefile::AddLinkDirectory should be called to add directories
- to the paths. They make sure the paths are unique as they are
- inserted.
-
-2001-07-30 07:18 scottim
-
- * Source/: cmCableClassSet.cxx, cmCableWrapTclCommand.cxx,
- cmDSPWriter.cxx, cmMakeDepend.cxx, cmMakefile.cxx, cmMakefile.h,
- cmUnixMakefileGenerator.cxx: Removed the Uniquification of the
- include and link directory list in FinalPass, and achieved the
- same effect by makein m_LinkDirectores and m_IncludeDirectories a
- set rather than vector
-
-2001-07-27 16:29 hoffman
-
- * Source/cmMakefile.cxx: ENH: Re-implemented
- ExpandVariablesInString to significantly improve performance.
-
-2001-07-27 13:06 scottim
-
- * Source/: cmMakefile.cxx, cmMakefile.h: MAkefile now strips
- duplicate directores from the libraries and include paths
-
-2001-07-26 11:07 king
-
- * Source/: cmCableClassSet.cxx, cmCableClassSet.h,
- cmCableClassSetCommand.cxx, cmCableWrapTclCommand.cxx: ENH: Added
- cable class-set expansion and tagging for alternate name
- generation. This should make the generated wrappers much easier
- to setup and use.
-
-2001-07-26 09:47 berk
-
- * CMakeLists.txt: ENH: Updated regexp for tracing dependencies in
- FLTK dialog.
-
-2001-07-26 08:36 martink
-
- * Source/cmMakefile.h: fixed warnings
-
-2001-07-25 18:30 hoffman
-
- * Source/: cmMakefile.cxx, cmMakefile.h, cmake.cxx, cmake.h: ENH:
- rework GUI with configure/OK/Cancel
-
-2001-07-25 16:53 martink
-
- * Source/: cmCommands.cxx, cmFunctionBlocker.h, cmIfCommand.cxx,
- cmIfCommand.h, cmMakefile.cxx, cmMakefile.h: added for each
- command
-
-2001-07-25 16:52 martink
-
- * Source/: cmEndForEachCommand.cxx, cmEndForEachCommand.h,
- cmForEachCommand.cxx, cmForEachCommand.h: new commands
-
-2001-07-25 09:40 berk
-
- * Source/cmCacheManager.cxx: Removing trailing spaces after cache
- entry value.
-
-2001-07-24 16:16 king
-
- * Source/cmDSPWriter.cxx: BUG: Fixed dependency generation to work
- for when there are many, many dependencies. Output is now easier
- to ready anyway because each dependency is on its own line.
-
-2001-07-23 14:43 king
-
- * Source/: cmConfigureGccXmlCommand.cxx,
- cmConfigureGccXmlCommand.h: BUG: CompilerIsMipsPro needs to
- redirect stderr to stdout so that the test output can be checked.
-
-2001-07-23 11:54 king
-
- * Source/: cmConfigureGccXmlCommand.cxx,
- cmConfigureGccXmlCommand.h: ENH: Added support for UNIX
- compilers. GCC and MIPSpro are supported.
-
-2001-07-23 11:53 king
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Added support
- for non-verbose mode output from running a command. This can be
- used when it is expected that the command may fail.
-
-2001-07-23 11:07 king
-
- * Source/: cmCommands.cxx, cmConfigureGccXmlCommand.cxx,
- cmConfigureGccXmlCommand.h: ENH: Added CONFIGURE_GCCXML command
- to do hard work of configuring GCCXML's flags for the current
- compiler. Currently only implemented correctly for Visual C++ in
- Windows.
-
-2001-07-23 11:06 king
-
- * Modules/FindGCCXML.cmake: ENH: Module to find and configure
- GCCXML and GCCXML_FLAGS.
-
-2001-07-20 11:41 millerjv
-
- * Modules/Dart.cmake: ENH: Added Purify targets
-
-2001-07-20 09:20 millerjv
-
- * Modules/Dart.cmake: ENH: Added purify command.
-
-2001-07-20 04:56 scottim
-
- * Templates/DLLHeader.dsptemplate: adding what I think is a missing
- /pdbtype:sept
-
-2001-07-18 16:45 martink
-
- * Source/cmMakefile.h: updated version
-
-2001-07-18 11:40 martink
-
- * Source/cmSystemTools.cxx: limit library search to appropriate
- extensions
-
-2001-07-18 10:17 hoffman
-
- * Modules/Dart.cmake: BUG: enable testing even if not tcl found
-
-2001-07-17 15:41 king
-
- * Source/cmCableWrapTclCommand.cxx: ENH: Added generation of
- dependencies on the CMake-generated input to gcc-xml so that
- re-generation of wrappers will occur if a header changes.
-
-2001-07-17 15:41 king
-
- * Source/cmMakeDepend.cxx: BUG: Need to expand variables in search
- paths in case it hasn't been done yet by the makefile.
-
-2001-07-17 15:09 king
-
- * Source/: cmMakeDepend.cxx, cmMakeDepend.h,
- cmOutputRequiredFilesCommand.cxx, cmUnixMakefileGenerator.cxx:
- ENH: Hacked together a new implementation of the dependency
- generator code. This should support finding dependencies for
- individual files without doing them for the entire makefile. Use
- cmMakeDepend::FindDependencies() to do this.
-
-2001-07-17 09:54 king
-
- * Modules/CMakeLists.txt, Modules/FindDart.cmake,
- Modules/FindJNI.cmake, Modules/FindPythonLibs.cmake,
- Modules/FindTCL.cmake, Source/cmSystemTools.cxx,
- Source/cmSystemTools.h, Templates/configure,
- Templates/configure.in: ENH: Added support for using
- backslash-style escaping in CMakeLists.txt file arguments. This
- allows double quotes to be used in arguments.
-
-2001-07-16 18:40 perera
-
- * Source/: cmAuxSourceDirectoryCommand.cxx, cmMakefile.cxx,
- cmMakefile.h, cmSourceFile.cxx, cmSourceFile.h,
- cmSourceFilesCommand.cxx, cmSourceFilesRemoveCommand.cxx,
- cmTarget.cxx: ENH: Source and header file extensions are in
- variables in cmMakefile. AUX_SOURCE_DIRECTORY will only add
- files that have a "source" extension.
-
-2001-07-16 15:19 ibanez
-
- * Modules/: FindGLU.cmake, FindGLUT.cmake: Search path for
- OpenGL related libraries
-
-2001-07-16 10:17 hoffman
-
- * Templates/: CMakeSystemConfig.cmake.in, configure, configure.in:
- ENH: add a variable for CMAKE_COMPILER_IS_GNUCXX
-
-2001-07-16 10:14 hoffman
-
- * Source/: cmMakefile.cxx, cmSourceFile.cxx: ENH: add support for
- mac osx
-
-2001-07-15 21:10 barre
-
- * Modules/FindPythonLibs.cmake: update include/lib path to Python
- (Linux)
-
-2001-07-11 13:30 martink
-
- * Source/: cmMakefile.h: version num
-
-2001-07-11 12:12 hoffman
-
- * Source/cmSystemTools.cxx: BUG: make sure find program does not
- find directories
-
-2001-07-10 17:13 hoffman
-
- * Source/: cmIncludeCommand.cxx, cmLoadCacheCommand.cxx: BUG:
- remove iostream.h includes
-
-2001-07-10 16:20 berk
-
- * Source/cmUnixMakefileGenerator.cxx: Unnecessary variable
-
-2001-07-10 16:20 berk
-
- * Source/cmMakefile.cxx: Better error checking.
-
-2001-07-10 14:29 hoffman
-
- * Templates/: configure, configure.in: BUG: fix excape of * for
- cmake
-
-2001-07-10 13:57 king
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: When splitting a full
- path library into separate -L and -l parts, the -l part may not
- have a "lib" prefix on cygwin.
-
-2001-07-10 12:09 king
-
- * Source/cmake.cxx: ENH: Removing automatic setting of
- BUILD_SHARED_LIBS. Projects that support this should explicitly
- declare it with the OPTION command, or set its libraries to
- shared or static directly on each ADD_LIBRARY command.
-
-2001-07-10 11:56 berk
-
- * Modules/Dart.cmake: Checking if tclshcommand is defined before
- running it.
-
-2001-07-10 11:46 king
-
- * Source/cmUnixMakefileGenerator.cxx: ENH: Added
- -D(library_name)_EXPORTS to build rules for sources that are
- going to be linked into a shared library. This allows dllexport
- setup for DLL building on cygwin. It may also come in handy in
- unix in the future. This corresponds to the same definition
- added by the dll dsp template in windows.
-
-2001-07-10 09:23 martink
-
- * Source/cmBuildNameCommand.cxx: changes to better handle old
- values or hand set values
-
-2001-07-09 12:46 nobody
-
- * DartConfig.cmake: Disabled doxygen and gnats
-
-2001-07-08 17:54 perera
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: library extension goes
- after library name, not before
-
-2001-07-06 14:41 hoffman
-
- * Source/: cmUnixMakefileGenerator.cxx, cmUnixMakefileGenerator.h:
- ENH: some clean up, and better checking to see if we are building
- cmake
-
-2001-07-06 14:11 hoffman
-
- * configure, configure.in: ENH: run make depend
-
-2001-07-06 12:46 will
-
- * Source/cmCommand.h: ERR:Spelling mistake
-
-2001-07-06 09:22 king
-
- * Source/cmStandardIncludes.h: ENH: Warning 4503 disable for MSVC.
-
-2001-07-05 18:15 hoffman
-
- * Templates/: configure, configure.in: BUG: fix flags for cygwin
- and shared builds
-
-2001-07-05 17:52 hoffman
-
- * Source/cmSystemTools.cxx: ENH: add better error output
-
-2001-07-05 12:03 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx, Templates/configure,
- Templates/configure.in: BUG: fix solaris problems in install and
- ar
-
-2001-07-03 10:53 king
-
- * Source/cmCableWrapTclCommand.cxx: ENH: Removed -fsyntax-only flag
- from call to gcc-xml. It should be part of GCCXML_FLAGS.
-
-2001-07-03 05:27 scottim
-
- * Source/cmDSPWriter.cxx, Templates/CMakeWindowsSystemConfig.cmake,
- Templates/DLLHeader.dsptemplate, Templates/EXEHeader.dsptemplate,
- Templates/EXEWinHeader.dsptemplate,
- Templates/UtilityHeader.dsptemplate,
- Templates/staticLibHeader.dsptemplate: Renamed the
- ReleaseWithDebugInfo Build configuration to RelWithDebInfo,
- because msdev does simple matching on build target, and
- specifying either Release or Debug builds would also build
- ReleaseWithDebugInfo
-
-2001-07-02 16:52 king
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: When outputting relative
- path of .o, the relative path of the source file must also be
- written (not full path).
-
-2001-07-02 16:30 millerjv
-
- * Source/cmBuildNameCommand.cxx: FIX: BuildName removes path to
- compiler and converts any illegal characters
-
-2001-07-02 15:57 king
-
- * Source/: cmCommands.cxx, cmBuildSharedLibrariesCommand.cxx,
- cmBuildSharedLibrariesCommand.h: ENH: Removed deprecated command
- completely.
-
-2001-07-02 15:38 king
-
- * Source/: cmAddLibraryCommand.cxx, cmAddLibraryCommand.h,
- cmDSPWriter.cxx, cmDSPWriter.h, cmDSWWriter.cxx, cmMakefile.cxx,
- cmMakefile.h, cmTarget.h, cmUnixMakefileGenerator.cxx,
- cmUnixMakefileGenerator.h: ENH: Added support for selection of
- static/shared build on a per-library basis.
-
-2001-07-02 14:38 martink
-
- * Source/cmake.cxx: better arg support
-
-2001-07-02 14:03 berk
-
- * Source/: cmVTKWrapJavaCommand.h, cmVTKWrapPythonCommand.h,
- cmVTKWrapTclCommand.h: Should not be inherited.
-
-2001-07-02 14:03 berk
-
- * Source/: cmVTKWrapJavaCommand.cxx, cmVTKWrapPythonCommand.cxx,
- cmVTKWrapTclCommand.cxx: Better error checking.
-
-2001-07-02 14:02 berk
-
- * Source/cmConfigureFileCommand.cxx: Wrong place for fout
-
-2001-06-29 16:46 martink
-
- * Source/cmConfigureFileCommand.cxx: better configure file command
-
-2001-06-29 16:06 nobody
-
- * CMakeLists.txt: added logo
-
-2001-06-29 09:53 martink
-
- * Source/cmaketest.cxx: minor compile fix
-
-2001-06-29 09:30 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx,
- Templates/CMakeSystemConfig.cmake.in, Templates/configure,
- Templates/configure.in: BUG: break up CMAKE_AR into program and
- ARGS
-
-2001-06-28 17:45 hoffman
-
- * configure, configure.in, Source/cmSystemTools.cxx,
- Source/cmUnixMakefileGenerator.cxx, Templates/configure,
- Templates/configure.in: ENH: various fixes to allow bootstrap on
- sunos with CC
-
-2001-06-28 16:45 hoffman
-
- * Source/cmEnableTestingCommand.cxx: fixed Dart issue
-
-2001-06-28 15:27 hoffman
-
- * Templates/CMakeSystemConfig.cmake.in: set values in the cache not
- just the current makefile
-
-2001-06-28 15:08 berk
-
- * Source/cmUnixMakefileGenerator.cxx: Special rules for
- out-of-package source files.
-
-2001-06-28 14:38 hoffman
-
- * Templates/: configure, configure.in: BUG: pass flags to compiler
- during configure
-
-2001-06-28 14:27 hoffman
-
- * Templates/: configure, configure.in: BUG: pass flags to compiler
- during configure
-
-2001-06-28 14:01 hoffman
-
- * Source/cmSourceFilesCommand.cxx: BUG: find files in
- subdirectories
-
-2001-06-28 11:42 hoffman
-
- * Source/cmStandardIncludes.h: fix for scope on hp
-
-2001-06-28 11:40 hoffman
-
- * Source/cmSystemTools.cxx: BUG: check size of path error, HP
- gcount problem
-
-2001-06-27 17:19 berk
-
- * Source/cmSourceFilesCommand.cxx: Added variable expansion.
-
-2001-06-27 16:18 martink
-
- * Source/cmMakefile.h: updated version to 0.3
-
-2001-06-27 16:17 martink
-
- * Source/cmMakefile.h: updated version to 0.2
-
-2001-06-27 16:14 martink
-
- * Source/cmUnixMakefileGenerator.cxx: ENH: fix install when
- executable and lib path set
-
-2001-06-27 15:42 hoffman
-
- * configure, configure.in, Source/CMakeLists.txt,
- Source/cmSystemTools.cxx, Source/cmUnixMakefileGenerator.cxx,
- Source/cmake.cxx, Templates/install-sh: ENH: fix install for
- cygwin, build cmake from configure
-
-2001-06-27 15:13 king
-
- * Source/: cmUnixMakefileGenerator.cxx, cmUnixMakefileGenerator.h:
- BUG: Check for building shared libraries should read from the
- make file's setting, not directly from the cache.
-
-2001-06-27 15:09 king
-
- * Source/cmDSPWriter.cxx: BUG: Check for building shared libraries
- should read from makefile's setting, not directly from the cache.
-
-2001-06-27 13:16 martink
-
- * CMake.rtf: updated for 0.2
-
-2001-06-27 13:12 martink
-
- * Source/: cmLinkLibrariesCommand.h, cmSubdirCommand.h:
- documentation change
-
-2001-06-27 12:09 perera
-
- * Source/cmUnixMakefileGenerator.cxx: ENH: Use ${MAKE} instead of
- make for dependent library rules
-
-2001-06-27 11:49 martink
-
- * Source/cmCommands.cxx: alphabetized
-
-2001-06-27 11:35 martink
-
- * Source/cmake.cxx: added help options
-
-2001-06-27 09:17 martink
-
- * Source/: cmSystemTools.cxx, cmaketest.cxx, cmaketest.h.in: minor
- fixes to testing
-
-2001-06-27 09:16 martink
-
- * Source/CMakeLists.txt: mod to the testing
-
-2001-06-27 09:16 martink
-
- * CMakeLists.txt: added dependencies for testing
-
-2001-06-26 16:19 hoffman
-
- * Source/cmake.dsp: BUG: change to dos mode
-
-2001-06-26 13:41 martink
-
- * Modules/Dart.cmake: update for CMake changes
-
-2001-06-26 13:23 martink
-
- * Source/: CMakeLists.txt, cmAddCustomTargetCommand.cxx,
- cmAddCustomTargetCommand.h, cmBuildCommand.cxx: modified how
- paths are escaped, added depends
-
-2001-06-26 10:01 martink
-
- * Source/: cmAddDependenciesCommand.cxx,
- cmAddDependenciesCommand.h, cmCommands.cxx: added add
- dependencies command
-
-2001-06-25 13:34 millerjv
-
- * Source/: cmBuildNameCommand.cxx, cmSiteNameCommand.cxx: FIX:
- added AddDefinition() to store site name and build name in
- makefile. Also stripped white space from the result of
- hostname.
-
-2001-06-25 10:59 martink
-
- * CMakeLists.txt: made cmake write its execs into CMake/Source
-
-2001-06-22 14:53 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: shared libraries should
- not depend on other shared libraries, they get relinked too
- often.
-
-2001-06-22 14:53 hoffman
-
- * Source/cmMakefile.cxx: ENH: put back stdio.h to get sprintf
-
-2001-06-22 14:23 biddi
-
- * Source/cmCommands.cxx: ERR: Serious problems with my CVS. How did
- this get committed?
-
-2001-06-22 12:19 king
-
- * Source/cmSystemTools.cxx: BUG: Wrote correct implementation of
- cmCopyFile.
-
-2001-06-22 12:18 king
-
- * Source/cmake.cxx: BUG: Fixed generation of cMakeRoot in one case.
-
-2001-06-22 12:18 king
-
- * Source/cmStandardIncludes.h: ENH: Added string.h include.
-
-2001-06-22 12:17 king
-
- * Source/cmMakefile.cxx: ERR: Removed stray standard header
- include. They should be added to cmStandardIncludes.h
-
-2001-06-22 12:17 king
-
- * Source/cmIncludeCommand.cxx: BUG: Added missing newline in error
- message.
-
-2001-06-22 11:32 martink
-
- * Source/cmMakefile.cxx: removed stricmp
-
-2001-06-22 11:28 martink
-
- * Source/CMakeLists.txt: escape quotes on cmaketest.h.in
-
-2001-06-22 11:15 martink
-
- * Source/: cmConfigureFileCommand.cxx, cmConfigureFileCommand.h:
- added escape quotes option
-
-2001-06-22 11:14 martink
-
- * Source/: cmMakefile.cxx, cmMakefile.h: added escape quotes option
- in replace strings
-
-2001-06-22 10:21 martink
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: added escape quote
- method
-
-2001-06-22 09:58 biddi
-
- * Source/: cmCommands.cxx, cmSourceFilesRemoveCommand.cxx,
- cmSourceFilesRemoveCommand.h: ENH: Added new command
- SOURCE_FILES_REMOVE which can be used to take files out of the
- build. Especially useful when certain compilers choke on the odd
- file.
-
-2001-06-22 09:47 biddi
-
- * Source/: cmMakefile.cxx, cmMakefile.h: ENH: Added
- RemoveSource(...) to complement AddSource. New command
- SOURCE_FILES_REMOVE uses it and can be used to take files out of
- the build
-
-2001-06-22 09:27 martink
-
- * Source/cmaketest.cxx: namespace issues
-
-2001-06-21 17:55 hoffman
-
- * Source/cmDSWWriter.cxx: allow no name project
-
-2001-06-21 17:53 martink
-
- * Source/CMakeLists.txt: better testing
-
-2001-06-21 17:53 martink
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: adde changeDirectory
-
-2001-06-21 17:52 martink
-
- * Source/: cmaketest.cxx, cmaketest.h.in: new test driver
-
-2001-06-21 17:52 martink
-
- * Tests/Simple/: CMakeLists.txt, simple.cxx: new tests
-
-2001-06-21 17:41 hoffman
-
- * Source/cmake.cxx: BUG: fix for unix
-
-2001-06-21 17:25 hoffman
-
- * Source/cmake.cxx: ENH: clean up
-
-2001-06-21 17:20 hoffman
-
- * Source/cmake.cxx: ENH: look in the PREFIX dir for the modules
-
-2001-06-21 16:34 hoffman
-
- * Source/: cmConfigure.cmake.h.in, cmake.cxx: ENH: better ability
- to find cmake program
-
-2001-06-21 15:57 martink
-
- * Templates/CMakeLists.txt: minor install fix
-
-2001-06-21 15:54 martink
-
- * Source/cmUnixMakefileGenerator.cxx: better permission handling
-
-2001-06-21 15:02 king
-
- * Source/: cmIncludeRegularExpressionCommand.cxx,
- cmIncludeRegularExpressionCommand.h, cmMakeDepend.cxx,
- cmMakeDepend.h, cmMakefile.cxx, cmMakefile.h,
- cmUnixMakefileGenerator.cxx: ENH: Extended
- INCLUDE_REGULAR_EXPRESSION to allow selective complaints about
- missing dependencies.
-
-2001-06-21 15:02 king
-
- * Source/CMakeLists.txt: ENH: Added BUILD_FLTK_GUI option (defaults
- to ON).
-
-2001-06-21 13:48 hoffman
-
- * Source/: CMakeLists.txt, cmSourceFile.cxx, cmStandardIncludes.h:
- BUG: fix bootstrap build on unix
-
-2001-06-21 12:31 hoffman
-
- * CMakeLists.txt: ENH: add include regexp
-
-2001-06-21 12:01 martink
-
- * CMakeLists.txt, Makefile.in, configure, configure.in, install-sh,
- Modules/CMakeLists.txt, Source/cmInstallFilesCommand.cxx,
- Source/cmInstallFilesCommand.h, Source/cmSystemTools.cxx,
- Source/cmSystemTools.h, Source/cmake.cxx,
- Templates/CMakeLists.txt, Templates/install-sh: better install
- support
-
-2001-06-21 10:58 hoffman
-
- * Templates/CMakeSystemConfig.cmake.in: BUG: remove quotes
-
-2001-06-21 10:36 hoffman
-
- * Source/: cmIncludeCommand.cxx, cmIncludeCommand.h: ENH: add
- optional include and only allow one file per INCLUDE
-
-2001-06-20 16:49 hoffman
-
- * Source/CMakeLists.txt, Source/cmDSPWriter.cxx,
- Templates/DLLHeader.dsptemplate, Templates/EXEHeader.dsptemplate,
- Templates/EXEWinHeader.dsptemplate,
- Templates/staticLibHeader.dsptemplate: ENH: boot strap mfc gui
- and support for MFC
-
-2001-06-20 13:56 hoffman
-
- * Source/CMakeLists.txt, Source/cmConfigure.cmake.h.in,
- Source/cmSourceFile.cxx, Source/cmStandardIncludes.h,
- Source/cmake.cxx, Templates/CMakeSystemConfig.cmake.in,
- Templates/configure, Templates/configure.in: ENH: fix cmake so it
- can boot strap itself better
-
-2001-06-19 16:29 hoffman
-
- * Modules/FindFLTK.cmake: [no log message]
-
-2001-06-19 16:10 hoffman
-
- * Source/CMakeLists.txt: ENH: build fltk cmake on unix with
- bootstrap
-
-2001-06-19 16:05 king
-
- * Makefile.in: BUG: Exectuable installation must set permissions to
- 755 in case installer has a umask like 007.
-
-2001-06-19 15:50 king
-
- * Source/: cmBuildSharedLibrariesCommand.cxx, cmake.cxx: ENH: CMake
- now always adds the BUILD_SHARED_LIBS cache entry. The
- BUILD_SHARED_LIBRARIES command that used to be used is now
- deprecated.
-
-2001-06-19 15:33 hoffman
-
- * Source/CMakeLists.txt: ENH: add bootstrap support for building
- fltk
-
-2001-06-19 12:03 king
-
- * Source/: cmCableCloseNamespaceCommand.cxx,
- cmCableCloseNamespaceCommand.h, cmCableCommand.cxx,
- cmCableCommand.h, cmCableData.cxx, cmCableData.h,
- cmCableDefineSetCommand.cxx, cmCableDefineSetCommand.h,
- cmCableInstantiateClassCommand.cxx,
- cmCableInstantiateClassCommand.h, cmCableInstantiateCommand.cxx,
- cmCableInstantiateCommand.h, cmCableOpenNamespaceCommand.cxx,
- cmCableOpenNamespaceCommand.h, cmCablePackageCommand.cxx,
- cmCablePackageCommand.h, cmCablePackageEntryCommand.cxx,
- cmCablePackageEntryCommand.h, cmCableSourceFilesCommand.cxx,
- cmCableSourceFilesCommand.h, cmCableWrapCommand.cxx,
- cmCableWrapCommand.h, cmCommands.cxx: ENH: Removing old-style
- cable commands related to the instantiation functionality which
- has now been removed from cable.
-
-2001-06-19 12:01 king
-
- * Source/cmOutputRequiredFilesCommand.cxx: ERR: Removed unused
- variable.
-
-2001-06-19 07:41 millerjv
-
- * Source/: cmAddTestCommand.cxx, cmEnableTestingCommand.cxx: ENH:
- Changed generated filename to DartTestfile.txt
-
-2001-06-18 17:26 hoffman
-
- * Source/cmSystemTools.cxx: BUG: use pclose not fclose
-
-2001-06-18 16:54 perera
-
- * Source/cmLinkLibrariesCommand.cxx: ENH: LINK_LIBRARIES(abc) will
- automatically add the path to abc to the link directories, if the
- path is known.
-
-2001-06-18 15:35 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: remove unused
-
-2001-06-18 15:32 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: create directories in
- the right place
-
-2001-06-18 15:31 hoffman
-
- * Source/cmake.cxx: ENH: move EXECUTABLE_OUTPUT_PATH and
- LIBRARY_OUTPUT_PATH initial creation to after the CMakeLists.txt
- files have been parsed
-
-2001-06-18 13:16 martink
-
- * Modules/Dart.cmake: out of source dart support
-
-2001-06-15 17:57 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: ENH: do not add anything from
- the current directory to the depends
-
-2001-06-15 10:35 perera
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: fixed so that empty
- library paths are ignored
-
-2001-06-14 17:06 biddi
-
- * Source/cmSourceFile.cxx: ERR: allow *.cpp as well as *.cxx etc
- etc
-
-2001-06-14 11:45 martink
-
- * Source/CMakeLib.dsp: added make depend on win32
-
-2001-06-14 10:19 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: fix it so that if a
- Makefile is out of date for some reason, it is only built once,
- it was doing it twice.
-
-2001-06-14 09:10 martink
-
- * CMakeLists.txt, DartConfig.cmake: modified testing
-
-2001-06-13 17:50 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: fix so it does not jump
- into the current directory for inital target builds
-
-2001-06-13 17:03 hoffman
-
- * Source/: cmUnixMakefileGenerator.cxx, cmUnixMakefileGenerator.h,
- cmake.cxx: ENH: fix EXECUTABLE_OUTPUT_PATH and
- LIBRARY_OUTPUT_PATH for unix
-
-2001-06-13 16:15 martink
-
- * Modules/FindDart.cmake: used to find the dart testing system
-
-2001-06-13 14:49 martink
-
- * CMakeLists.txt: minor dart change
-
-2001-06-13 13:53 martink
-
- * Source/: cmTarget.cxx, cmTarget.h: duh
-
-2001-06-13 13:49 martink
-
- * CMakeLists.txt, Source/cmTarget.cxx, Source/cmTarget.h: minor cvs
- web changeCMakeLists.txt
-
-2001-06-12 14:15 perera
-
- * Source/cmUnixMakefileGenerator.cxx, Templates/configure,
- Templates/configure.in: BUG: SHLIB_LINK was being used when
- linking static executables. Missing comma in RUNTIME_FLAG for
- IRIX. ENH: User supplied SHLIB_CFLAGS (-fPIC, etc) will override
- configure detected flags
-
-2001-06-12 13:30 martink
-
- * CMakeLists.txt, Source/CMakeLists.txt: support testing
-
-2001-06-12 12:22 king
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: CMake's configure needs
- to run with the current directory as the project's binary
- directory.
-
-2001-06-12 11:55 martink
-
- * Source/: cmakemain.cxx: cmake does not require two arguments
-
-2001-06-12 11:12 martink
-
- * Source/cmCommands.cxx: removed old added new
-
-2001-06-12 11:08 martink
-
- * Source/cmCommands.cxx: removed old added new
-
-2001-06-12 11:08 martink
-
- * Source/: cmOutputRequiredFilesCommand.cxx,
- cmOutputRequiredFilesCommand.h: added new command
-
-2001-06-12 11:08 martink
-
- * Source/: cmConfigureFileNoAutoconf.cxx,
- cmConfigureFileNoAutoconf.h, cmTestsCommand.cxx,
- cmTestsCommand.h: removed old commands
-
-2001-06-12 10:59 king
-
- * Source/: cmMakeDepend.cxx, cmUnixMakefileGenerator.cxx: BUG:
- Dependency hints must be removed by the makefile generator before
- adding the dependencies generated by cmMakeDepend.
-
-2001-06-12 10:45 perera
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: There was no dependency
- for library targets on their required libraries. (Hopefully
- there aren't any cyclic dependencies for libraries.)
- CMAKE_SHLIB_LINK is now used for executable targets.
-
-2001-06-12 09:00 martink
-
- * Source/: cmMakeDepend.h, cmUnixMakefileGenerator.cxx,
- cmUnixMakefileGenerator.h, cmMakeDepend.cxx: some cleanup to the
- make depend process
-
-2001-06-12 08:31 king
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: WIN32_EXECUTABLE targets
- were not being installed on unix properly. They are supposed to
- be treated just like any other EXECUTABLE target.
-
-2001-06-12 08:30 king
-
- * Source/cmake.cxx: ERR: int -> unsigned int.
-
-2001-06-11 21:50 ibanez
-
- * Modules/FindFLTK.cmake: ENH: Added the path used in SuSe Linux
- 7.1
-
-2001-06-11 19:14 millerjv
-
- * Modules/Dart.cmake: Modified for new Dart source tree
-
-2001-06-11 18:00 martink
-
- * Source/cmake.cxx: minor fix in error checking
-
-2001-06-11 17:09 king
-
- * Modules/FindTCL.cmake: ENH: Added check for tcl8.4 (as against
- tcl84), tcl8.3, tcl8.2, and tcl8.0 when finding the TCL_LIBRARY.
-
-2001-06-11 16:47 martink
-
- * Source/cmMakefile.h: added some const versions of get methods
-
-2001-06-11 15:31 millerjv
-
- * Modules/Testing.cmake: Changed Testing.cmake to Dart.cmake
-
-2001-06-11 15:28 millerjv
-
- * Modules/Dart.cmake: Rename Testing.cmake to Dart.cmake
-
-2001-06-11 10:18 king
-
- * Source/cmSystemTools.cxx: BUG: Fixed regular expression used to
- match registry entries. The expression now matches everything
- after a [HKEY until the first ']' is encountered.
-
-2001-06-10 18:27 ibanez
-
- * Source/cmSystemTools.cxx: DOC: Added a comment about the risk of
- using tempnam in Unix, as opposed to using mkstemp.
-
-2001-06-09 20:54 king
-
- * Source/cmCableWrapTclCommand.cxx: BUG: Changed custom command
- generation to not use full path of output file from cable.
-
-2001-06-08 14:40 king
-
- * Source/: cmCableWrapTclCommand.cxx, cmCableWrapTclCommand.h: ENH:
- Added proper request for/generation of CABLE, GCCXML, and
- GCCXML_FLAGS cache entries. This also allowed the correct
- generation of gccxml rules.
-
-2001-06-08 14:38 king
-
- * Source/cmDSPWriter.cxx: BUG: Removed generation of stray # Begin
- Custom Build line.
-
-2001-06-08 00:18 perera
-
- * Source/cmUnixMakefileGenerator.cxx,
- Templates/CMakeSystemConfig.cmake.in, Templates/configure,
- Templates/configure.in: ENH: Runtime library search paths can be
- added to the link lines for on shared builds.
-
-2001-06-07 16:48 martink
-
- * CMake.pdf.gz: replaced with pdf version
-
-2001-06-07 16:45 will
-
- * CMake.pdf: updated docs
-
-2001-06-07 16:34 martink
-
- * CMake.doc.gz: checked in rtf version
-
-2001-06-07 16:24 martink
-
- * CMake.rtf: updated docs
-
-2001-06-07 14:52 hoffman
-
- * Source/cmAddTestCommand.cxx, Source/cmCablePackageCommand.cxx,
- Source/cmCableWrapTclCommand.cxx, Source/cmCacheManager.cxx,
- Source/cmCacheManager.h, Source/cmDSWWriter.cxx,
- Source/cmMakefile.cxx, Source/cmMakefile.h,
- Source/cmSystemTools.h, Source/cmTarget.h,
- Source/cmUnixMakefileGenerator.cxx,
- Source/cmUtilitySourceCommand.cxx,
- Source/cmVTKWrapJavaCommand.cxx,
- Source/cmVTKWrapPythonCommand.cxx,
- Source/cmVTKWrapTclCommand.cxx, Source/cmake.cxx,
- Templates/CMakeWindowsSystemConfig.cmake: ENH: move utilities to
- targets from makefile, and add versioning to cache
-
-2001-06-07 12:22 king
-
- * Source/cmEnableTestingCommand.cxx: BUG: ENABLE_TESTING command
- may need to create output directory before writing the
- CMakeTestfile into it since it is invoked before the makefile
- generator runs.
-
-2001-06-07 11:36 scottim
-
- * Source/cmDSPWriter.cxx, Templates/CMakeWindowsSystemConfig.cmake,
- Templates/DLLHeader.dsptemplate, Templates/EXEHeader.dsptemplate,
- Templates/EXEWinHeader.dsptemplate,
- Templates/UtilityHeader.dsptemplate,
- Templates/staticLibHeader.dsptemplate: adding a "Release with
- debugging Info" build to CMake for NT
-
-2001-06-07 10:16 king
-
- * Source/cmCableWrapTclCommand.cxx: ERR: Fixed generation of source
- name and directory for cmSourceFiles of generated Tcl wrapper
- files. Changed extension of generated gcc-xml input c++ file to
- be .cc so that GCC will recognize it, but MsDev will still allow
- a custom command on it.
-
-2001-06-07 08:50 millerjv
-
- * Source/cmConfigureFileNoAutoconf.cxx: FIX: Chaned error message
- to match command
-
-2001-06-06 16:45 king
-
- * Source/cmCableWrapTclCommand.cxx: ENH: Changed generation of
- gccxml command to write out define and include flags explicitly
- instead of using CMAKE_CXX_FLAGS and INCLUDE_FLAGS variables.
- This should help it run when gccxml is not the compiler that will
- build the generated wrappers.
-
-2001-06-06 16:14 millerjv
-
- * Source/cmAddTestCommand.cxx: FIX: InitialPass() seg fault on
- std::copy and FinalPass() was not appending to the file
-
-2001-06-06 13:58 martink
-
- * Source/: cmAddTestCommand.cxx, cmAddTestCommand.h,
- cmCommands.cxx, cmConfigureFileNoAutoconf.cxx,
- cmEnableTestingCommand.cxx, cmEnableTestingCommand.h,
- cmMakefile.cxx, cmMakefile.h, cmTestsCommand.cxx: added enable
- testing deprecated some commands
-
-2001-06-06 13:55 hoffman
-
- * Source/CMakeLib.dsp: [no log message]
-
-2001-06-06 13:48 hoffman
-
- * Source/: cmDSPMakefile.cxx, cmDSPMakefile.h, cmDSPWriter.cxx,
- cmDSPWriter.h, cmDSWMakefile.cxx, cmDSWMakefile.h,
- cmDSWWriter.cxx, cmDSWWriter.h, cmMSProjectGenerator.cxx,
- cmMSProjectGenerator.h: ENH: rename DSWMakefile and DSPMakefile
- to DSWWriter and DSPWriter
-
-2001-06-06 13:19 hoffman
-
- * Source/: cmAbstractFilesCommand.cxx, cmAbstractFilesCommand.h,
- cmAddCustomTargetCommand.cxx, cmAddCustomTargetCommand.h,
- cmAddDefinitionsCommand.cxx, cmAddDefinitionsCommand.h,
- cmAddExecutableCommand.cxx, cmAddExecutableCommand.h,
- cmAddLibraryCommand.cxx, cmAddLibraryCommand.h,
- cmAddTestCommand.cxx, cmAddTestCommand.h,
- cmAuxSourceDirectoryCommand.cxx, cmAuxSourceDirectoryCommand.h,
- cmBuildCommand.cxx, cmBuildCommand.h, cmBuildNameCommand.cxx,
- cmBuildNameCommand.h, cmBuildSharedLibrariesCommand.cxx,
- cmBuildSharedLibrariesCommand.h, cmCableClassSetCommand.cxx,
- cmCableClassSetCommand.h, cmCableCloseNamespaceCommand.cxx,
- cmCableCloseNamespaceCommand.h, cmCableDefineSetCommand.cxx,
- cmCableDefineSetCommand.h, cmCableOpenNamespaceCommand.cxx,
- cmCableOpenNamespaceCommand.h, cmCablePackageCommand.cxx,
- cmCablePackageCommand.h, cmCablePackageEntryCommand.cxx,
- cmCablePackageEntryCommand.h, cmCableWrapTclCommand.cxx,
- cmCableWrapTclCommand.h, cmCommand.h, cmConfigureFileCommand.cxx,
- cmConfigureFileCommand.h, cmConfigureFileNoAutoconf.cxx,
- cmConfigureFileNoAutoconf.h, cmElseCommand.cxx, cmElseCommand.h,
- cmEndIfCommand.cxx, cmEndIfCommand.h, cmExecProgramCommand.cxx,
- cmExecProgramCommand.h, cmFindFileCommand.cxx,
- cmFindFileCommand.h, cmFindLibraryCommand.cxx,
- cmFindLibraryCommand.h, cmFindPathCommand.cxx,
- cmFindPathCommand.h, cmFindProgramCommand.cxx,
- cmFindProgramCommand.h, cmGetFilenameComponentCommand.cxx,
- cmGetFilenameComponentCommand.h, cmIfCommand.cxx, cmIfCommand.h,
- cmIncludeCommand.cxx, cmIncludeCommand.h,
- cmIncludeDirectoryCommand.cxx, cmIncludeDirectoryCommand.h,
- cmIncludeRegularExpressionCommand.cxx,
- cmIncludeRegularExpressionCommand.h, cmInstallFilesCommand.cxx,
- cmInstallFilesCommand.h, cmInstallTargetsCommand.cxx,
- cmInstallTargetsCommand.h, cmLibraryCommand.h,
- cmLinkDirectoriesCommand.cxx, cmLinkDirectoriesCommand.h,
- cmLinkLibrariesCommand.cxx, cmLinkLibrariesCommand.h,
- cmLoadCacheCommand.cxx, cmLoadCacheCommand.h,
- cmMakeDirectoryCommand.cxx, cmMakeDirectoryCommand.h,
- cmMakefile.cxx, cmMessageCommand.cxx, cmMessageCommand.h,
- cmOptionCommand.cxx, cmOptionCommand.h, cmProjectCommand.cxx,
- cmProjectCommand.h, cmSetCommand.cxx, cmSetCommand.h,
- cmSiteNameCommand.cxx, cmSiteNameCommand.h,
- cmSourceFilesCommand.cxx, cmSourceFilesCommand.h,
- cmSourceGroupCommand.cxx, cmSourceGroupCommand.h,
- cmSubdirCommand.cxx, cmSubdirCommand.h,
- cmTargetLinkLibrariesCommand.cxx, cmTargetLinkLibrariesCommand.h,
- cmTestsCommand.cxx, cmTestsCommand.h, cmUtilitySourceCommand.cxx,
- cmUtilitySourceCommand.h, cmVTKWrapJavaCommand.cxx,
- cmVTKWrapJavaCommand.h, cmVTKWrapPythonCommand.cxx,
- cmVTKWrapPythonCommand.h, cmVTKWrapTclCommand.cxx,
- cmVTKWrapTclCommand.h, cmWrapExcludeFilesCommand.cxx,
- cmWrapExcludeFilesCommand.h: ENH: rename Invoke to InitialPass
-
-2001-06-06 11:02 millerjv
-
- * Source/cmMakefile.cxx: Change name of file created from Testfile
- to CMakeTestfile.txt
-
-2001-06-06 09:44 martink
-
- * Source/cmSystemTools.cxx: better regexp for reg entries
-
-2001-06-06 09:43 martink
-
- * Modules/FindJNI.cmake: better tests
-
-2001-06-06 07:47 millerjv
-
- * Source/cmMakefile.cxx: FIX: forgot to close the files
-
-2001-06-05 22:54 perera
-
- * Source/cmUnixMakefileGenerator.cxx: ENH: Compress the library
- search directories so that each appears only once.
-
-2001-06-05 20:34 millerjv
-
- * Source/cmCommands.cxx: ENH: Added AddTest command
-
-2001-06-05 20:34 millerjv
-
- * Source/: cmMakefile.cxx, cmMakefile.h: ENH: Added AddTest, and
- GenerateTestfile routines
-
-2001-06-05 20:32 millerjv
-
- * Source/: cmAddTestCommand.cxx, cmAddTestCommand.h: New cmake
- command to specify a single test
-
-2001-06-05 17:46 berk
-
- * Source/cmVTKWrapPythonCommand.cxx: Module name between Unix and
- Windows got switched by mistake.
-
-2001-06-05 17:41 biddi
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Some tweaks,
- hacks and #ifdefs required to compile cmake on Borland C++Builder
-
-2001-06-05 15:48 hoffman
-
- * Source/: cmDSPMakefile.cxx, cmDSPWriter.cxx: BUG: fix EXE and LIB
- path problems
-
-2001-06-04 18:24 hoffman
-
- * Source/: cmDSWMakefile.cxx, cmDSWWriter.cxx: STYLE: line too long
-
-2001-06-04 18:24 hoffman
-
- * Source/cmMessageCommand.cxx: ENH: print all arguments
-
-2001-06-04 18:23 hoffman
-
- * Source/cmSetCommand.cxx: ENH: add better error checking
-
-2001-06-04 17:17 martink
-
- * Source/: cmFindIncludeCommand.cxx, cmFindIncludeCommand.h:
- removed find include command
-
-2001-06-04 17:16 martink
-
- * Source/cmCommands.cxx: removed find include command finally added
- message
-
-2001-06-04 16:55 martink
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: new message command
-
-2001-06-04 16:55 martink
-
- * Source/: cmMessageCommand.cxx, cmMessageCommand.h: new command
-
-2001-06-04 16:45 martink
-
- * Source/cmVTKWrapPythonCommand.cxx: unused variable
-
-2001-06-04 15:46 barre
-
- * Templates/: DLLHeader.dsptemplate, EXEHeader.dsptemplate,
- EXEWinHeader.dsptemplate, UtilityHeader.dsptemplate,
- staticLibHeader.dsptemplate: the "Release" target is not the
- default.
-
-2001-06-04 11:34 hoffman
-
- * Source/: cmGeneratedFileStream.h, cmUnixMakefileGenerator.cxx:
- ENH: try to better handle control-c during make Makefiles
-
-2001-06-04 10:18 hoffman
-
- * Source/: cmCacheManager.cxx, cmDSWMakefile.cxx, cmDSWWriter.cxx,
- cmFunctionBlocker.h, cmMSProjectGenerator.cxx, cmMakefile.cxx,
- cmMakefileGenerator.h: BUG: clean up memory leaks.
-
-2001-06-01 13:54 martink
-
- * Source/: cmDSPMakefile.cxx, cmDSPWriter.cxx: fix for network
- includ paths
-
-2001-06-01 13:29 berk
-
- * Source/cmVTKWrapPythonCommand.cxx: Fixing the module name for
- Unix.
-
-2001-05-31 15:48 hoffman
-
- * Source/cmake.cxx: BUG: fix edit of directories
-
-2001-05-31 14:15 berk
-
- * Source/cmVTKWrapPythonCommand.cxx: Should not use decl if not on
- Windows.
-
-2001-05-30 15:56 hoffman
-
- * Source/cmakemain.cxx: BUG: add missing file
-
-2001-05-30 15:28 hoffman
-
- * Source/: CMakeLib.dsp, Makefile.in, cmMSProjectGenerator.cxx,
- cmake.cxx, cmake.dsp, cmake.h: ENH: change MFC gui to use cmake
- class
-
-2001-05-29 14:16 perera
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: Now only one makefile
- rule is generated per depenency. This eliminates a number of
- warnings.
-
-2001-05-25 17:19 geoff
-
- * Source/cmSetCommand.cxx: bug meaning that set(a b) just set a to
- "" and not to b
-
-2001-05-25 15:33 king
-
- * Source/cmSystemTools.cxx: BUG: Fixed stupid error in the hack I
- just checked in.
-
-2001-05-25 15:32 king
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: WIN32 executable target
- rules are now generated in unix the same as any other executable
- (instead of not at all).
-
-2001-05-25 15:27 barre
-
- * Templates/CMakeWindowsSystemConfig.cmake: better help
-
-2001-05-25 14:31 king
-
- * Source/cmSystemTools.cxx: BUG: Added hack to
- cmSystemTools::GetPath to make its algorithm correctly parse off
- the last entry of the system PATH environment variable.
-
-2001-05-25 14:27 king
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: Fixed logic that splits
- a full path library link into the -L and -l pieces to not write
- out a -l by itself if the file regular expression does not match.
-
-2001-05-25 07:31 millerjv
-
- * Modules/Testing.cmake: BUG: missing quote on a custom command
-
-2001-05-24 21:17 barre
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: New functions used
- to extract the components of a full filename.
-
-2001-05-24 21:14 barre
-
- * Source/cmFindPathCommand.cxx: The path found is now collapsed
- (cleaner).
-
-2001-05-24 21:13 barre
-
- * Source/: cmGetFilenameComponentCommand.cxx,
- cmGetFilenameComponentCommand.h, cmCommands.cxx: Welcome to
- cmGetFilenameComponentCommand ("Get a specific component of a
- full filename")
-
-2001-05-24 21:12 barre
-
- * Source/CMakeLib.dsp: Welcome to cmGetFilenameComponentCommand
-
-2001-05-24 21:11 barre
-
- * Modules/FindTCL.cmake: Try to find tclsh or wish and use that
- path to find the include or lib directory. TK_INTERNAL_PATH is
- searched too (path to tkWinInt.h)
-
-2001-05-24 19:17 barre
-
- * Source/cmSystemTools.cxx: optimize ConvertToUnixSlashes a little
- bit, and use it in MakeDirectory (code was duplicated)
-
-2001-05-24 17:51 king
-
- * Templates/CMakeSystemConfig.cmake.in: ERR: VAR type entry missing
- after CACHE for CMAKE_TEMPLATE_FLAGS.
-
-2001-05-24 14:59 barre
-
- * Source/: cmVTKWrapTclCommand.cxx, cmVTKWrapTclCommand.h: updated
- to handle Tk commands compiled/linked separately. Useful for VTK
- Tk widgets for example.
-
-2001-05-24 13:45 millerjv
-
- * Modules/Testing.cmake: Project independent setting for testing
-
-2001-05-24 13:40 barre
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: new Capitalized
- function. Will be used in the VTK Tcl wrapper for example (in a
- more portable way).
-
-2001-05-24 12:57 hoffman
-
- * Modules/FindOpenGL.cmake, Source/cmSetCommand.cxx,
- Source/cmSetCommand.h, Templates/CMakeSystemConfig.cmake.in,
- Templates/CMakeWindowsSystemConfig.cmake: ENH: change the syntax
- of the SET command, fix the combo box for larger strings
-
-2001-05-24 11:47 martink
-
- * Source/: cmMakefile.h, cmake.cxx: added version number
-
-2001-05-24 10:32 barre
-
- * Templates/DLLHeader.dsptemplate: removed hardcoded VTKDLL
-
-2001-05-24 10:00 barre
-
- * Templates/: DLLHeader.dsptemplate, EXEHeader.dsptemplate,
- EXEWinHeader.dsptemplate, staticLibHeader.dsptemplate: slight
- change in the order of the options (right-most takes precedence)
-
-2001-05-23 20:16 millerjv
-
- * Source/cmBuildCommand.cxx: Changed Windows build command to build
- Release
-
-2001-05-23 18:31 barre
-
- * Templates/DLLHeader.dsptemplate: Intermediate Dir was wrong
-
-2001-05-23 18:22 barre
-
- * Templates/CMakeWindowsSystemConfig.cmake: /Gz => /GZ
-
-2001-05-23 18:19 barre
-
- * Templates/CMakeWindowsSystemConfig.cmake: removed /O2 from debug
-
-2001-05-23 17:19 hoffman
-
- * Source/cmDSPMakefile.cxx, Source/cmDSPWriter.cxx,
- Templates/CMakeWindowsSystemConfig.cmake,
- Templates/DLLHeader.dsptemplate, Templates/EXEHeader.dsptemplate,
- Templates/EXEWinHeader.dsptemplate,
- Templates/staticLibHeader.dsptemplate: ENH: create
- CMAKE_CXX_FLAGS_[Buildtype] flags
-
-2001-05-23 16:31 martink
-
- * Source/cmMSProjectGenerator.cxx: bug finding windows template
- file
-
-2001-05-23 16:28 martink
-
- * Source/: cmSystemTools.cxx, cmake.cxx: command line fixes for
- win32
-
-2001-05-23 16:09 barre
-
- * Templates/: DLLHeader.dsptemplate, EXEHeader.dsptemplate,
- EXEWinHeader.dsptemplate, UtilityHeader.dsptemplate,
- staticLibHeader.dsptemplate: ReleaseMinSize => MinSizeRel
-
-2001-05-23 15:53 hoffman
-
- * Templates/DLLHeader.dsptemplate: BUG: remove vtkCommon
-
-2001-05-23 15:49 martink
-
- * Source/cmake.cxx: fixed quoted cmake
-
-2001-05-23 14:44 hoffman
-
- * Source/cmSystemTools.cxx: ENH: add better error message
-
-2001-05-23 14:33 geoff
-
- * Source/cmake.dsp: DSPs have to be binary
-
-2001-05-23 14:05 hoffman
-
- * Templates/: DLLHeader.dsptemplate, EXEHeader.dsptemplate,
- EXEWinHeader.dsptemplate, UtilityHeader.dsptemplate,
- staticLibHeader.dsptemplate: ENH: change Release Minsize to
- MinSizeRel, add MinSizeRel to dll template
-
-2001-05-23 13:16 king
-
- * Source/: cmDSPMakefile.cxx, cmDSPWriter.cxx: ENH: Added INSTALL
- target to switch in OutputDSPFile. Also added a default that
- prints out an error message so that anyone who adds a target
- doesn't forget to update the switch.
-
-2001-05-23 12:02 martink
-
- * Source/: cmDSPMakefile.cxx, cmDSPWriter.cxx, cmDSWMakefile.cxx,
- cmDSWWriter.cxx: install fixes for win32
-
-2001-05-23 11:53 martink
-
- * Source/: cmMakefile.cxx, cmUnixMakefileGenerator.cxx,
- cmUnixMakefileGenerator.h: added install target support
-
-2001-05-23 11:34 ibanez
-
- * Modules/FindVTK.cmake: Module to search for VTK include and
- library paths
-
-2001-05-23 11:29 martink
-
- * Source/: cmInstallFilesCommand.cxx, cmInstallFilesCommand.h,
- cmInstallTargetsCommand.cxx, cmInstallTargetsCommand.h,
- cmCommands.cxx, cmTarget.cxx, cmTarget.h: added install rules
-
-2001-05-23 11:27 martink
-
- * Templates/CMakeSystemConfig.cmake.in: added prefix to config
-
-2001-05-23 10:47 hoffman
-
- * Source/cmGeneratedFileStream.h: BUG: remove warning
-
-2001-05-23 10:47 hoffman
-
- * Source/cmake.dsp: BUG: fix output directory
-
-2001-05-23 10:01 martink
-
- * Source/cmProjectCommand.cxx: added PROJECT_SOURCE_DIR
-
-2001-05-23 09:35 hoffman
-
- * Source/cmTarget.cxx: ENH: allow duplicate libraries
-
-2001-05-22 20:45 barre
-
- * Templates/UtilityHeader.dsptemplate: Template now uses
- EXECUTABLE_OUTPUT_PATH too.
-
-2001-05-22 20:44 barre
-
- * Templates/EXEWinHeader.dsptemplate: PROP BASE and PROP were
- inverted
-
-2001-05-22 20:36 barre
-
- * Source/: cmDSPMakefile.cxx, cmDSPWriter.cxx: Seems to me that
- EXEWinHeader was not searched in the right place.
-
-2001-05-22 17:49 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: do not include /usr/lib
- in -L
-
-2001-05-22 13:52 hoffman
-
- * Source/Makefile.in: fix CXXFLAGS
-
-2001-05-22 13:42 hoffman
-
- * Source/Makefile.in: [no log message]
-
-2001-05-22 13:40 hoffman
-
- * configure, configure.in: use cxxflags in test builds
-
-2001-05-22 13:22 hoffman
-
- * Source/Makefile.in, Source/cmUnixMakefileGenerator.cxx,
- Templates/configure, Templates/configure.in: BUG: fix depends and
- CXXFLAGS passing
-
-2001-05-22 12:38 barre
-
- * Source/cmDSPMakefile.cxx, Source/cmDSPWriter.cxx,
- Templates/DLLHeader.dsptemplate, Templates/EXEHeader.dsptemplate,
- Templates/EXEWinHeader.dsptemplate,
- Templates/staticLibHeader.dsptemplate: fixed some of the
- LIBRARY_OUTPUT_PATH and EXECUTABLE_OUTPUT_PATH problems.
-
-2001-05-22 11:15 martink
-
- * dummy.in: no longer used
-
-2001-05-21 16:43 king
-
- * Makefile.in: ERR: Added missing @srcdir@ and modified install
- expressions to include *.cmake* files instead of just *.cmake
- files (for .in).
-
-2001-05-21 16:21 king
-
- * Source/cmCableWrapTclCommand.cxx: ENH: Converted to new Class and
- Group tags in place of WrapperSet and Groups tags.
-
-2001-05-21 16:10 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx,
- Templates/CMakeSystemConfig.cmake.in: fix for hp x11 and gl
-
-2001-05-21 15:16 hoffman
-
- * Modules/FindOpenGL.cmake, Source/cmSystemTools.cxx: fix opengl on
- hp
-
-2001-05-21 14:17 hoffman
-
- * Source/cmake.cxx: BUG: remove declaration without variable
-
-2001-05-21 14:01 hoffman
-
- * configure, configure.in, Source/Makefile.in,
- Source/cmBuildNameCommand.cxx,
- Source/cmUnixMakefileGenerator.cxx,
- Templates/CMakeSystemConfig.cmake.in: clean up for build on its
- own
-
-2001-05-21 11:43 martink
-
- * Source/cmake.dsp: release fix
-
-2001-05-21 11:34 martink
-
- * Source/: CMakeBuildTargets.cxx, CMakeSetupCMD.cxx,
- CMakeSetupCMD.dsp: collapsed into cmake.cxx
-
-2001-05-21 11:32 martink
-
- * Source/cmake.dsp: new dsp
-
-2001-05-21 11:13 martink
-
- * Source/cmake.cxx: bug fix in finding CMAKE_ROOT
-
-2001-05-21 11:10 martink
-
- * Makefile.in: added install target
-
-2001-05-21 10:47 hoffman
-
- * Source/: cmBuildNameCommand.cxx, cmSetCommand.cxx: BUG: fix
- compiler name
-
-2001-05-21 09:50 martink
-
- * Source/: CMakeSetup.dsw, cmake.cxx: updated for out of tree
- builds
-
-2001-05-21 09:32 martink
-
- * Makefile.in, configure, configure.in, install-sh: out of place
- cmake
-
-2001-05-21 09:32 martink
-
- * CMakeSystemConfig.cmake.in, configure.in.sample,
- Source/Makefile.in, Source/cmMakefile.cxx,
- Source/cmUnixMakefileGenerator.cxx, Source/cmake.cxx: new out of
- place builds
-
-2001-05-21 09:31 martink
-
- * Templates/: CMakeSystemConfig.cmake.in, configure, configure.in:
- new structure
-
-2001-05-18 16:45 hoffman
-
- * CMakeSystemConfig.cmake.in, Source/cmUnixMakefileGenerator.cxx:
- ENH: add support for X11
-
-2001-05-18 16:30 martink
-
- * Source/cmUnixMakefileGenerator.cxx: duh
-
-2001-05-18 15:25 martink
-
- * Source/: cmake.cxx, cmake.h: new command
-
-2001-05-18 15:23 martink
-
- * Source/cmSystemTools.h: minor whitespace change
-
-2001-05-18 15:22 martink
-
- * Source/cmMSProjectGenerator.cxx: compiler fix
-
-2001-05-18 15:20 martink
-
- * Source/: cmMSProjectGenerator.cxx, cmMSProjectGenerator.h,
- cmMakefileGenerator.h, cmUnixMakefileGenerator.cxx,
- cmUnixMakefileGenerator.h: changes for cmake to live outside of
- the source tree
-
-2001-05-18 13:04 hoffman
-
- * CMakeSystemConfig.cmake.in, Source/cmSetCommand.cxx: ENH: allow
- cache to override config file
-
-2001-05-18 11:48 king
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: fix link of executables
-
-2001-05-18 11:12 martink
-
- * Source/cmMakefileGenerator.h: added SetLocal method
-
-2001-05-18 11:09 martink
-
- * Source/: cmMSProjectGenerator.cxx, cmMSProjectGenerator.h,
- cmUnixMakefileGenerator.cxx, cmUnixMakefileGenerator.h: added
- SetLocal method
-
-2001-05-18 10:15 hoffman
-
- * CMakeSystemConfig.cmake.in, Source/cmUnixMakefileGenerator.cxx:
- BUG: quote the compiler and other options
-
-2001-05-17 17:43 hoffman
-
- * Source/: CMakeBuildTargets.cxx, Makefile.in: compile source dir
- into cmake
-
-2001-05-17 15:48 will
-
- * Source/cmSystemTools.cxx: ERR:Bad #ifdef's
-
-2001-05-17 12:36 martink
-
- * Source/: DLLFooter.dsptemplate, DLLHeader.dsptemplate,
- EXEFooter.dsptemplate, EXEHeader.dsptemplate,
- EXEWinHeader.dsptemplate, UtilityFooter.dsptemplate,
- UtilityHeader.dsptemplate, staticLibFooter.dsptemplate,
- staticLibHeader.dsptemplate: moved into Template directory
-
-2001-05-17 12:25 martink
-
- * CMakeMakefileTemplate.in, CMakeMaster.make.in,
- CMakeRules.make.in, CMakeSimpleRules.make.in,
- CMakeTargets.make.in, CMakeTopMakefileTemplate.in,
- CMakeVariables.make.in, CMakeWindowsSystemConfig.cmake: no longer
- used
-
-2001-05-17 12:14 martink
-
- * Source/CMakeBuildTargets.cxx: unix fix
-
-2001-05-17 12:08 martink
-
- * Source/: CMakeBuildTargets.cxx, CMakeSetupCMD.cxx,
- cmCablePackageCommand.cxx, cmDSPMakefile.cxx, cmDSPWriter.cxx,
- cmMakefile.cxx, cmUnixMakefileGenerator.cxx: half checked in
- changes for CMAKE_ROOT
-
-2001-05-17 12:04 martink
-
- * Templates/: CMakeWindowsSystemConfig.cmake,
- DLLFooter.dsptemplate, DLLHeader.dsptemplate,
- EXEFooter.dsptemplate, EXEHeader.dsptemplate,
- EXEWinHeader.dsptemplate, UtilityFooter.dsptemplate,
- UtilityHeader.dsptemplate, staticLibFooter.dsptemplate,
- staticLibHeader.dsptemplate: new directory
-
-2001-05-17 11:44 hoffman
-
- * Source/: cmCableWrapTclCommand.cxx, cmConfigure.h.in,
- cmGeneratedFileStream.h, cmStandardIncludes.h: BUG: fix to
- compile on hp with aCC
-
-2001-05-17 11:22 king
-
- * Source/cmCableWrapTclCommand.cxx: Renamed gccxml input/output
- files to drop _tcl qualification.
-
-2001-05-16 18:10 hoffman
-
- * CMakeSystemConfig.cmake.in: ENH: fix for sunCC
-
-2001-05-16 18:08 hoffman
-
- * Source/: cmCacheManager.cxx, cmUnixMakefileGenerator.cxx: BUG:
- fix for sun compiler
-
-2001-05-16 17:43 king
-
- * Source/: cmCableClassSet.cxx, cmCableClassSet.h: ERR: Removed use
- of member templates.
-
-2001-05-16 17:18 king
-
- * Source/cmUnixMakefileGenerator.cxx: ERR: int -> unsigned int
-
-2001-05-16 17:18 king
-
- * Source/cmGeneratedFileStream.h: ERR: const error fixed.
-
-2001-05-16 17:11 king
-
- * Source/CMakeLib.dsp: ENH: Added cmCableClassSet.cxx to build.
-
-2001-05-16 17:11 king
-
- * Source/cmGeneratedFileStream.h: ERR: Added is_open() check in
- cmGeneratedFileStream::operator bool() so that implicit
- conversion to bool is not used.
-
-2001-05-16 17:11 king
-
- * Source/cmCableClassSet.cxx: ERR: Removed dynamic_cast so that
- RTTI isn't required.
-
-2001-05-16 16:41 king
-
- * Source/: Makefile.in, cmCableClassSet.cxx, cmCableClassSet.h,
- cmCableClassSetCommand.cxx, cmCableClassSetCommand.h,
- cmCableWrapTclCommand.cxx, cmCableWrapTclCommand.h,
- cmCommands.cxx: ENH: Adding CABLE_CLASS_SET and CABLE_WRAP_TCL
- commands. They cannot yet be used with the main branch of CABLE,
- though.
-
-2001-05-16 16:40 king
-
- * Source/cmGeneratedFileStream.h: ENH: cmGeneratedFileStream class
- added to simplify copy-if-different usage on generated files.
-
-2001-05-16 15:43 hoffman
-
- * configure.in.sample: [no log message]
-
-2001-05-16 15:15 hoffman
-
- * CMakeSystemConfig.cmake.in, Source/Makefile.in,
- Source/cmBuildNameCommand.cxx,
- Source/cmBuildSharedLibrariesCommand.cxx,
- Source/cmCacheManager.cxx, Source/cmCacheManager.h,
- Source/cmDSPMakefile.cxx, Source/cmDSPWriter.cxx,
- Source/cmMakeDepend.cxx, Source/cmMakefile.cxx,
- Source/cmProjectCommand.cxx, Source/cmSetCommand.cxx,
- Source/cmUnixMakefileGenerator.cxx,
- Source/cmUnixMakefileGenerator.h: ENH: unify make process on unix
-
-2001-05-16 09:19 king
-
- * Source/: cmData.h, cmMakefile.cxx, cmMakefile.h: ENH: Added
- cmData and corresponding DataMap in cmMakefile to allow commands
- to register arbitrary extra data with the makefile without
- modifying the cmMakefile class definition.
-
-2001-05-15 13:14 martink
-
- * Source/: DLLHeader.dsptemplate, EXEHeader.dsptemplate,
- EXEWinHeader.dsptemplate, cmDSPMakefile.cxx, cmDSPWriter.cxx,
- staticLibHeader.dsptemplate: added output directory support
-
-2001-05-14 16:47 barre
-
- * Source/cmSystemTools.cxx: Changed separator between registry key
- and its value. Change regexp for registry key.
-
-2001-05-14 16:46 barre
-
- * Modules/FindTCL.cmake: Changed separator between registry key and
- its value.
-
-2001-05-14 10:36 hoffman
-
- * Source/cmSystemTools.cxx: ENH: put back lost changes from r1.38
-
-2001-05-12 07:29 barre
-
- * Source/cmSystemTools.cxx: fix + => += bug reported by A. Perera
-
-2001-05-11 17:22 barre
-
- * Source/cmSystemTools.cxx: Extended the registry key regexp
-
-2001-05-11 17:11 barre
-
- * Modules/FindTCL.cmake: Add 8.4 and registry support
-
-2001-05-11 17:11 barre
-
- * Source/cmSystemTools.cxx: Add support for a specific value name
- in a registry key
-
-2001-05-11 14:49 geoff
-
- * Source/cmCacheManager.cxx: Cache file is a bit prettier
-
-2001-05-11 14:39 hoffman
-
- * Source/: cmCableSourceFilesCommand.cxx, cmSystemTools.cxx,
- cmUnixMakefileGenerator.cxx: BUG: fix find library for unix
-
-2001-05-11 13:58 barre
-
- * Modules/FindPythonLibs.cmake: NAMES syntax
-
-2001-05-11 13:52 martink
-
- * Source/: cmDSPMakefile.cxx, cmDSPWriter.cxx: fix for expanding
- library vars
-
-2001-05-11 12:30 barre
-
- * Source/cmFindLibraryCommand.cxx: Fix help string when NAMES was
- used (forgot the case when there is no name)
-
-2001-05-11 12:13 barre
-
- * Source/cmFindLibraryCommand.cxx: Fix help string when NAMES was
- used
-
-2001-05-11 11:45 king
-
- * Source/cmFindLibraryCommand.cxx: ERR: int -> unsigned int.
-
-2001-05-11 11:39 hoffman
-
- * CMakeVariables.make.in, Source/cmFindLibraryCommand.cxx: BUG: add
- back thread library
-
-2001-05-11 11:07 martink
-
- * Source/cmFindProgramCommand.cxx: expands reg values
-
-2001-05-11 10:52 martink
-
- * Source/: EXEHeader.dsptemplate, cmAddExecutableCommand.cxx,
- cmAddExecutableCommand.h, cmDSPMakefile.cxx, cmDSPMakefile.h,
- cmDSPWriter.cxx, cmDSPWriter.h, cmFindLibraryCommand.cxx,
- cmFindPathCommand.cxx, cmMakefile.cxx, cmMakefile.h,
- cmSystemTools.cxx, cmSystemTools.h, cmUnixMakefileGenerator.cxx,
- EXEWinHeader.dsptemplate: added registry entry support and
- windows app support
-
-2001-05-11 10:27 martink
-
- * Modules/: FindJNI.cmake, FindPythonLibs.cmake: minor fixes and
- new python module
-
-2001-05-10 17:22 hoffman
-
- * Source/: cmDSPMakefile.cxx, cmDSPWriter.cxx: BUG: fix up gui with
- values that stay around too long
-
-2001-05-10 16:21 geoff
-
- * Source/cmMakefile.cxx: definitions should now be overwritten if
- they already exist
-
-2001-05-10 15:50 hoffman
-
- * Source/cmSystemTools.cxx: BUG: fix unix path search
-
-2001-05-10 15:32 martink
-
- * Source/cmTarget.cxx: fix for expaning libraries prior to
- generating dsp
-
-2001-05-10 14:30 geoff
-
- * Source/: cmDSPMakefile.cxx, cmDSPWriter.cxx: Reads and uses
- MSPROJECT_TEMPLATE_DIRECTORY if it exists
-
-2001-05-10 14:02 king
-
- * CMake.doc: BUG: Removing this file. It has been replaced by
- CMake.doc.gz to get around a problem with CVS.
-
-2001-05-10 13:52 martink
-
- * Source/cmTarget.h: added win32 executable option
-
-2001-05-10 12:25 king
-
- * CMake.doc.gz: Testing strange cvs problem with .doc files.
-
-2001-05-10 12:05 king
-
- * CMake.pdf, CMake.pdf.gz: BUG: Removing old CMake.pdf and adding
- the gzipped version, CMake.pdf.gz because of file size problems
- with cvs.
-
-2001-05-10 11:20 king
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: Removed stray debugging
- output statement. Also renamed some variables for clarity.
-
-2001-05-10 11:19 king
-
- * Source/cmSystemTools.cxx: ERR: RunCommand method needed return in
- unix.
-
-2001-05-10 11:18 king
-
- * Source/: cmFindLibraryCommand.cxx, cmFindProgramCommand.cxx: ERR:
- Removed unused variable
-
-2001-05-10 09:45 king
-
- * CMakeVariables.make.in: BUG: ANSI_CFLAGS -> CMAKE_ANSI_CFLAGS
-
-2001-05-09 18:00 geoff
-
- * Source/: EXEHeader.dsptemplate, cmDSPMakefile.cxx,
- cmDSPWriter.cxx: ADD LINK32s are now on multiple lines because VC
- breaks otherwise
-
-2001-05-09 17:38 barre
-
- * Modules/FindTCL.cmake: ENH: add 8.3 support
-
-2001-05-09 16:17 hoffman
-
- * Source/: cmDSPMakefile.cxx, cmDSPWriter.cxx: BUG: escape spaces
- before adding .lib
-
-2001-05-09 16:08 hoffman
-
- * Source/: cmDSPMakefile.cxx, cmDSPWriter.cxx: ENH: escape spaces
-
-2001-05-09 15:48 hoffman
-
- * Source/: cmDSPMakefile.cxx, cmDSPWriter.cxx: ENH: only add .lib
- if no .lib exists
-
-2001-05-09 14:53 hoffman
-
- * Modules/FindFLTK.cmake, Modules/FindGTK.cmake,
- Modules/FindJNI.cmake, Modules/FindJPEG.cmake,
- Modules/FindMPI.cmake, Modules/FindTCL.cmake, Source/cmCommand.h,
- Source/cmFindLibraryCommand.cxx, Source/cmFindLibraryCommand.h,
- Source/cmFindProgramCommand.cxx, Source/cmSystemTools.cxx,
- Source/cmSystemTools.h, Source/cmUnixMakefileGenerator.cxx: ENH:
- change find library and find program to look for more than one
- name
-
-2001-05-09 13:44 hoffman
-
- * Source/cmCableDefineSetCommand.cxx: BUG: match called on invalid
- number
-
-2001-05-09 13:22 martink
-
- * CMakeMaster.make.in, CMakeRules.make.in,
- CMakeSystemConfig.cmake.in, CMakeTopMakefileTemplate.in,
- CMakeVariables.make.in, configure.in.sample, Source/Makefile.in:
- cleaned up configure some
-
-2001-05-09 11:15 millerjv
-
- * Source/cmCacheManager.cxx: FIX: only clear the cache on a load
- when the load needs to read internal values. Otherwise, it is
- assumed that we are reading another projects cache.
-
-2001-05-09 09:52 hoffman
-
- * Source/cmConfigureFileCommand.cxx: BUG: fix use beyond end of
- array
-
-2001-05-09 08:51 martink
-
- * Source/: cmCommands.cxx, cmLoadCacheCommand.cxx,
- cmLoadCacheCommand.h, cmSourceFile.cxx: added load cache command
- and fixed source file
-
-2001-05-08 17:37 king
-
- * Source/cmCacheManager.cxx: ERR: LoadCache needed to return a
- value.
-
-2001-05-08 17:04 martink
-
- * Source/: cmCacheManager.cxx, cmCacheManager.h: added ability to
- load another cache
-
-2001-05-08 17:03 martink
-
- * Source/cmProjectCommand.cxx: now adds src and bin dir into cache
-
-2001-05-08 16:20 martink
-
- * Source/cmVTKWrapTclCommand.cxx: fixed bug in init code
-
-2001-05-08 16:01 hoffman
-
- * configure.in.sample: clean up
-
-2001-05-08 11:40 martink
-
- * Source/cmTargetLinkLibrariesCommand.cxx: BUG: added arg0 to link
- libraries
-
-2001-05-08 10:16 ibanez
-
- * Modules/FindFLTK.cmake: Module to search the path for FLTK
- library ( http://www.fltk.org )
-
-2001-05-07 18:14 king
-
- * Source/: cmAddExecutableCommand.cxx, cmAddLibraryCommand.cxx,
- cmMakefile.cxx: ENH: Moved cache entry addition into
- cmMakefile::AddLibrary and AddExecutable so that commands do not
- have to add it explicitly.
-
-2001-05-07 18:11 hoffman
-
- * CMakeSystemConfig.cmake.in, Source/CMakeBuildTargets.cxx,
- Source/Makefile.in, Source/cmCacheManager.cxx,
- Source/cmCommands.cxx, Source/cmConfigureFile.cxx,
- Source/cmConfigureFile.h, Source/cmConfigureFileCommand.cxx,
- Source/cmConfigureFileCommand.h, Source/cmExecProgram.cxx,
- Source/cmExecProgram.h, Source/cmExecProgramCommand.cxx,
- Source/cmExecProgramCommand.h, Source/cmMakeDirectoryCommand.cxx,
- Source/cmMakeDirectoryCommand.h, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmSystemTools.cxx,
- Source/cmUnixMakefileGenerator.cxx,
- Source/cmUnixMakefileGenerator.h: ENH: call configure from cmake
-
-2001-05-07 10:02 blezek
-
- * Source/cmConfigureFile.cxx: BUG: Removing Remove Variables call
-
-2001-05-07 09:16 geoff
-
- * configure.in.sample: Under FreeBSD: should be
- CMAKE_SHLIB_BUILD_FLAGS and not CMAKE_SHLIB_LINK_FLAGS.
- CMakeSystemConfig.cmake not being made
-
-2001-05-05 11:28 hoffman
-
- * Source/cmAddExecutableCommand.cxx: BUG: add internal cache entry
- for executables, so depends can work
-
-2001-05-05 11:03 hoffman
-
- * Source/: cmAddTargetCommand.cxx, cmAddTargetCommand.h,
- cmCableInstantiateClassCommand.h, cmCableInstantiateCommand.h,
- cmCommands.cxx, cmLibraryCommand.cxx: BUG: add removed command,
- and sort the order in cmCommands.cxx
-
-2001-05-04 17:00 martink
-
- * Source/: cmMakefile.cxx, cmUnixMakefileGenerator.cxx: fixes for
- untiltiy targets in all
-
-2001-05-04 16:44 blezek
-
- * Source/cmBuildNameCommand.cxx: ENH: Proper build name
-
-2001-05-04 16:43 blezek
-
- * Source/cmSiteNameCommand.cxx: ENH: Correct sitename
-
-2001-05-04 15:50 martink
-
- * Source/: cmAddCustomTargetCommand.cxx,
- cmAddCustomTargetCommand.h, cmAddTargetCommand.cxx,
- cmAddTargetCommand.h, cmDSWMakefile.cxx, cmDSWWriter.cxx,
- cmMakefile.cxx, cmMakefile.h, cmTarget.h,
- cmVTKWrapJavaCommand.cxx: option to make utilities in the all
- target
-
-2001-05-04 14:53 hoffman
-
- * CMakeSystemConfig.cmake.in, CMakeWindowsSystemConfig.cmake: ENH:
- move to cmake for itkConfigure.h.in
-
-2001-05-04 12:52 martink
-
- * Source/cmVTKWrapJavaCommand.cxx: updates
-
-2001-05-04 11:35 geoff
-
- * Modules/: FindGTK.cmake, FindJPEG.cmake: INCLUDE these to find
- the relevant libraries
-
-2001-05-04 11:34 hoffman
-
- * Source/: cmAddCustomTargetCommand.cxx,
- cmAddCustomTargetCommand.h, cmBuildCommand.cxx, cmBuildCommand.h,
- cmBuildNameCommand.cxx, cmBuildNameCommand.h, cmExecProgram.cxx,
- cmExecProgram.h, cmSiteNameCommand.cxx, cmSiteNameCommand.h: ENH:
- move testing stuff to cmake from configure, good bye dashboard...
- :)
-
-2001-05-04 11:30 hoffman
-
- * CMakeRules.make.in, CMakeSystemConfig.txt.in,
- CMakeWindowsSystemConfig.txt, Source/cmAddTargetCommand.cxx,
- Source/cmAddTargetCommand.h, Source/cmCacheManager.cxx,
- Source/cmCommands.cxx, Source/cmDSWMakefile.cxx,
- Source/cmDSWWriter.cxx, Source/cmFindProgramCommand.cxx,
- Source/cmMakefile.cxx, Source/cmOptionCommand.cxx,
- Source/cmOptionCommand.h, Source/cmSourceGroup.cxx,
- Source/cmSourceGroup.h, Source/cmSystemTools.cxx,
- Source/cmSystemTools.h, Source/cmUnixMakefileGenerator.cxx: ENH:
- move testing stuff to cmake from configure, good bye dashboard...
- :)
-
-2001-05-04 10:44 king
-
- * Source/cmSystemTools.cxx: ENH: Added support to EscapeSpaces to
- use double quotes on windows.
-
-2001-05-04 10:44 king
-
- * Source/cmCablePackageCommand.cxx: ENH: Added use of CMAKE cache
- entry for generating the DSP/makefile build rules.
-
-2001-05-04 10:44 king
-
- * Source/: cmDSPMakefile.cxx, cmDSPMakefile.h, cmDSPWriter.cxx,
- cmDSPWriter.h: ENH: Added use of CMAKE cache entry for generating
- the DSP build rules.
-
-2001-05-04 10:13 martink
-
- * Modules/FindJNI.cmake: minor fixes
-
-2001-05-04 09:56 martink
-
- * Source/: cmDSPMakefile.cxx, cmDSPWriter.cxx: fixed custom command
- rule
-
-2001-05-04 09:47 martink
-
- * Modules/FindJNI.cmake: new module
-
-2001-05-04 09:39 martink
-
- * Source/: cmDSPMakefile.cxx, cmDSPWriter.cxx, cmSourceGroup.cxx,
- cmSourceGroup.h, cmVTKWrapJavaCommand.cxx: better custom rules
-
-2001-05-04 08:46 martink
-
- * Source/: cmFunctionBlocker.h, cmIfCommand.cxx, cmIfCommand.h,
- cmMakefile.cxx, cmVTKWrapJavaCommand.cxx: better If checks
-
-2001-05-04 08:45 martink
-
- * Source/: cmSourceFilesRequireCommand.cxx,
- cmSourceFilesRequireCommand.h, cmUnixDefinesCommand.cxx,
- cmUnixDefinesCommand.h, cmUnixLibrariesCommand.cxx,
- cmUnixLibrariesCommand.h, cmWin32DefinesCommand.cxx,
- cmWin32DefinesCommand.h, cmWin32IncludeDirectoryCommand.cxx,
- cmWin32IncludeDirectoryCommand.h, cmWin32LibrariesCommand.cxx,
- cmWin32LibrariesCommand.h: removed old functions
-
-2001-05-03 16:55 king
-
- * Source/: CMakeBuildTargets.cxx, CMakeSetupCMD.cxx: ENH: Added
- generation of internal CMAKE cache entry with path to
- command-line CMake executable.
-
-2001-05-03 16:55 king
-
- * Source/: cmFindProgramCommand.cxx, cmSystemTools.cxx,
- cmSystemTools.h: ENH: Added cmSystemTools::FindProgram() and
- full-path detection utilities.
-
-2001-05-03 15:27 martink
-
- * Source/: cmCommands.cxx, cmVTKWrapJavaCommand.cxx,
- cmVTKWrapJavaCommand.h: minor fixes
-
-2001-05-03 11:04 martink
-
- * Source/cmCommands.cxx: removed deprecated commands
-
-2001-05-03 10:58 martink
-
- * CMakeSystemConfig.cmake.in: better config info
-
-2001-05-03 10:35 martink
-
- * Source/cmConfigureFile.cxx: now support cmakedefine
-
-2001-05-03 08:53 martink
-
- * CMakeSystemConfig.txt.in, CMakeWindowsSystemConfig.txt: uses
- cmake commands now
-
-2001-05-03 08:52 martink
-
- * CMakeSystemConfig.cmake.in, CMakeSystemConfig.txt.in,
- CMakeWindowsSystemConfig.cmake, CMakeWindowsSystemConfig.txt,
- Source/cmMakefile.cxx, Source/cmMakefile.h: system config uses
- cmake commands now
-
-2001-05-02 17:33 martink
-
- * Modules/FindMPI.cmake: minor fixes
-
-2001-05-02 17:07 martink
-
- * Modules/FindMPI.cmake: new module
-
-2001-05-02 14:08 martink
-
- * Modules/FindOpenGL.cmake: simple module
-
-2001-05-02 11:53 martink
-
- * Modules/FindTCL.cmake: finds tk as well
-
-2001-05-02 11:53 martink
-
- * Source/: CMakeBuildTargets.cxx, CMakeSetupCMD.cxx: cache loaded
- into makefile
-
-2001-05-01 17:52 martink
-
- * Source/: cmVTKWrapPythonCommand.cxx, cmVTKWrapTclCommand.cxx:
- fixed bug in limiting to source lists
-
-2001-05-01 17:37 king
-
- * Source/: cmCableDefineSetCommand.cxx, cmCableDefineSetCommand.h,
- cmCableWrapCommand.cxx, cmCableWrapCommand.h: ENH: Changed
- cmCableWrapCommand to inherit from cmCableDefineSetCommand since
- they do almost exactly the same thing. Added a GetXmlTag virtual
- function to both classes to return what XML tag to generate in
- the set's output. cmCableDefineSetCommand generates a "Set" tag,
- and cmCableWrapCommand generates a "WrapperSet" tag. What is
- inside the tags is still generated by the cmCableDefineSetCommand
- superclass.
-
-2001-05-01 17:35 king
-
- * Source/: cmCableInstantiateClassCommand.cxx,
- cmCableInstantiateClassCommand.h, cmCableInstantiateCommand.cxx,
- cmCableInstantiateCommand.h, cmCablePackageEntryCommand.cxx,
- cmCablePackageEntryCommand.h, cmCableSourceFilesCommand.cxx,
- cmCableSourceFilesCommand.h: ENH: Changed WriteConfiguration back
- to const because it doesn't need to report errors anymore.
-
-2001-05-01 17:12 hoffman
-
- * Source/: UtilityFooter.dsptemplate, UtilityHeader.dsptemplate:
- ADD: add utiltity templates
-
-2001-05-01 16:55 hoffman
-
- * configure.in.sample, Source/cmAddTargetCommand.cxx,
- Source/cmDSPMakefile.cxx, Source/cmDSPMakefile.h,
- Source/cmDSPWriter.cxx, Source/cmDSPWriter.h,
- Source/cmDSWMakefile.cxx, Source/cmDSWMakefile.h,
- Source/cmDSWWriter.cxx, Source/cmDSWWriter.h,
- Source/cmMakefile.cxx, Source/cmMakefile.h, Source/cmTarget.h,
- Source/cmUnixMakefileGenerator.cxx: ENH: implement ADD_TARGET
- command, and add an ALL_BUILD target
-
-2001-05-01 16:34 martink
-
- * Source/cmMakefile.cxx: cache now loaded into makefile
-
-2001-05-01 16:28 martink
-
- * Source/: cmCacheManager.cxx, cmCacheManager.h: added method to
- puch cache into makefile defines
-
-2001-05-01 16:27 martink
-
- * Source/cmIfCommand.cxx: slight bug in If command I think
-
-2001-05-01 11:28 martink
-
- * Modules/FindTCL.cmake: first module
-
-2001-05-01 11:16 martink
-
- * Source/: cmCommands.cxx, cmElseCommand.cxx, cmIfCommand.cxx,
- cmIfCommand.h, cmSetCommand.cxx, cmSetCommand.h,
- cmVTKWrapPythonCommand.cxx, cmVTKWrapTclCommand.cxx: new set
- command and IF NOT
-
-2001-04-30 14:56 martink
-
- * Source/: cmElseCommand.cxx, cmFindFileCommand.cxx,
- cmFindLibraryCommand.cxx, cmFindPathCommand.cxx, cmIfCommand.cxx,
- cmSystemTools.cxx, cmSystemTools.h: bug fixes
-
-2001-04-30 11:51 king
-
- * Source/cmCablePackageCommand.cxx: BUG: Fixed output of
- CMakeLists.txt path in cable_config.xml dependency list for unix.
- Needed to escape spaces instead of enclosing in double quotes.
-
-2001-04-30 11:29 king
-
- * Source/cmMakefile.h: ERR: Removed a conflict that was checked in.
-
-2001-04-30 10:52 anonymous
-
- * Source/: cmCommands.cxx, cmDSPMakefile.cxx, cmDSPMakefile.h,
- cmDSPWriter.cxx, cmDSPWriter.h, cmIncludeCommand.cxx,
- cmIncludeCommand.h, cmMakefile.cxx, cmMakefile.h: New command:
- INCLUDE(somefile.txt)
-
-2001-04-30 10:44 martink
-
- * Source/: cmCommands.cxx, cmDSPMakefile.cxx, cmDSPWriter.cxx,
- cmDSWMakefile.cxx, cmDSWWriter.cxx, cmFindIncludeCommand.cxx,
- cmFindLibraryCommand.cxx, cmLinkLibrariesCommand.cxx,
- cmLinkLibrariesCommand.h, cmMakefile.cxx, cmMakefile.h,
- cmTarget.cxx, cmTarget.h, cmTargetLinkLibrariesCommand.cxx,
- cmTargetLinkLibrariesCommand.h, cmUnixMakefileGenerator.cxx,
- cmUnixMakefileGenerator.h: added TARGET_LINK_LIBRARY command and
- support for debug and release libraries to link against
-
-2001-04-27 14:57 king
-
- * Source/cmUnixMakefileGenerator.cxx: ERR: Renamed CustomCommands
- to BuildRules to match change in cmSourceGroup.
-
-2001-04-27 14:52 king
-
- * Source/cmCablePackageCommand.cxx: BUG: Removed output of GCC_XML
- rules when the command cannot be found.
-
-2001-04-27 14:51 king
-
- * Source/: cmDSPMakefile.cxx, cmDSPMakefile.h, cmDSPWriter.cxx,
- cmDSPWriter.h, cmSourceGroup.cxx, cmSourceGroup.h: BUG: Removed
- output of dual rules for source files that are processed by both
- the compiler and by a custom command. Also removed generation of
- duplicate CMakeLists.txt in the project files.
-
-2001-04-27 14:40 martink
-
- * CMakeSystemConfig.txt.in, CMakeWindowsSystemConfig.txt: get
- system info into cmake
-
-2001-04-27 14:25 martink
-
- * Source/: cmConfigureFile.cxx, cmConfigureFile.h: added configure
- file
-
-2001-04-27 11:53 hoffman
-
- * configure.in.sample: BUG: run cache build with each configure
-
-2001-04-27 11:36 hoffman
-
- * CMakeRules.make.in, Source/cmMakefile.cxx: BUG: fix inplace
- builds
-
-2001-04-27 11:03 hoffman
-
- * Source/cmMakefile.cxx: ENH: fix in source build with non-gnu
-
-2001-04-27 09:32 hoffman
-
- * Source/cmMakefile.cxx: ENH: add output when creating files
-
-2001-04-27 09:30 martink
-
- * Source/: cmFindFileCommand.cxx, cmFindLibraryCommand.cxx,
- cmFindPathCommand.cxx: better help strings
-
-2001-04-27 09:13 will
-
- * Source/cmAuxSourceDirectoryCommand.h: ENH:New copyright
-
-2001-04-27 08:46 martink
-
- * CMakeVariables.make.in: removed old junk
-
-2001-04-27 08:01 will
-
- * Source/: CMakeBuildTargets.cxx, CMakeSetupCMD.cxx,
- cmAddDefinitionsCommand.cxx, cmAddDefinitionsCommand.h,
- cmAddExecutableCommand.cxx, cmAddExecutableCommand.h,
- cmAddLibraryCommand.cxx, cmAddLibraryCommand.h,
- cmAddTargetCommand.cxx, cmAddTargetCommand.h,
- cmAuxSourceDirectoryCommand.cxx,
- cmBuildSharedLibrariesCommand.cxx,
- cmCableCloseNamespaceCommand.cxx, cmCableCloseNamespaceCommand.h,
- cmCableCommand.cxx, cmCableCommand.h, cmCableData.cxx,
- cmCableData.h, cmCableDefineSetCommand.cxx,
- cmCableDefineSetCommand.h, cmCableInstantiateClassCommand.cxx,
- cmCableInstantiateClassCommand.h, cmCableInstantiateCommand.cxx,
- cmCableInstantiateCommand.h, cmCableOpenNamespaceCommand.cxx,
- cmCableOpenNamespaceCommand.h, cmCablePackageCommand.cxx,
- cmCablePackageCommand.h, cmCablePackageEntryCommand.cxx,
- cmCablePackageEntryCommand.h, cmCableSourceFilesCommand.cxx,
- cmCableSourceFilesCommand.h, cmCableWrapCommand.cxx,
- cmCableWrapCommand.h, cmCacheManager.cxx, cmCacheManager.h,
- cmCommand.h, cmCommands.h, cmConfigureFileNoAutoconf.cxx,
- cmConfigureFileNoAutoconf.h, cmCustomCommand.cxx,
- cmCustomCommand.h, cmDSPMakefile.cxx, cmDSPMakefile.h,
- cmDSPWriter.cxx, cmDSPWriter.h, cmDSWMakefile.cxx,
- cmDSWMakefile.h, cmDSWWriter.cxx, cmDSWWriter.h, cmDirectory.cxx,
- cmDirectory.h, cmElseCommand.cxx, cmElseCommand.h,
- cmEndIfCommand.cxx, cmEndIfCommand.h, cmFindFileCommand.cxx,
- cmFindFileCommand.h, cmFindIncludeCommand.cxx,
- cmFindIncludeCommand.h, cmFindLibraryCommand.cxx,
- cmFindLibraryCommand.h, cmFindProgramCommand.cxx,
- cmFindProgramCommand.h, cmFunctionBlocker.h, cmIfCommand.cxx,
- cmIfCommand.h, cmIncludeDirectoryCommand.cxx,
- cmIncludeDirectoryCommand.h,
- cmIncludeRegularExpressionCommand.cxx,
- cmIncludeRegularExpressionCommand.h, cmLibraryCommand.cxx,
- cmLibraryCommand.h, cmLinkDirectoriesCommand.cxx,
- cmLinkDirectoriesCommand.h, cmLinkLibrariesCommand.cxx,
- cmLinkLibrariesCommand.h, cmMSProjectGenerator.cxx,
- cmMSProjectGenerator.h, cmMakeDepend.cxx, cmMakeDepend.h,
- cmMakefile.cxx, cmMakefile.h, cmMakefileGenerator.cxx,
- cmMakefileGenerator.h, cmOptionCommand.cxx, cmOptionCommand.h,
- cmProjectCommand.cxx, cmProjectCommand.h,
- cmRegularExpression.cxx, cmRegularExpression.h, cmSourceFile.cxx,
- cmSourceFile.h, cmSourceFilesCommand.cxx, cmSourceFilesCommand.h,
- cmSourceFilesRequireCommand.cxx, cmSourceFilesRequireCommand.h,
- cmSourceGroup.cxx, cmSourceGroup.h, cmSourceGroupCommand.cxx,
- cmSourceGroupCommand.h, cmStandardIncludes.h,
- cmSubdirCommand.cxx, cmSubdirCommand.h, cmSystemTools.cxx,
- cmSystemTools.h, cmTarget.cxx, cmTarget.h, cmTestsCommand.cxx,
- cmTestsCommand.h, cmUnixDefinesCommand.cxx,
- cmUnixDefinesCommand.h, cmUnixLibrariesCommand.cxx,
- cmUnixLibrariesCommand.h, cmUnixMakefileGenerator.cxx,
- cmUnixMakefileGenerator.h, cmUtilitySourceCommand.cxx,
- cmUtilitySourceCommand.h, cmVTKWrapPythonCommand.cxx,
- cmVTKWrapTclCommand.cxx, cmWin32DefinesCommand.cxx,
- cmWin32DefinesCommand.h, cmWin32IncludeDirectoryCommand.cxx,
- cmWin32IncludeDirectoryCommand.h, cmWin32LibrariesCommand.cxx,
- cmWin32LibrariesCommand.h, cmWrapExcludeFilesCommand.cxx,
- cmWrapExcludeFilesCommand.h: ENH:New copyright
-
-2001-04-27 07:55 will
-
- * Source/: cmAbstractFilesCommand.cxx, cmAbstractFilesCommand.h:
- ENH:Copyright
-
-2001-04-26 16:22 martink
-
- * Source/: DLLHeader.dsptemplate, EXEHeader.dsptemplate,
- cmDSPMakefile.cxx, cmDSPMakefile.h, cmDSPWriter.cxx,
- cmDSPWriter.h, cmDSWMakefile.cxx, cmDSWWriter.cxx,
- cmLinkLibrariesCommand.cxx, cmLinkLibrariesCommand.h,
- cmMakefile.cxx, cmMakefile.h, cmUnixMakefileGenerator.cxx,
- cmVTKWrapPythonCommand.cxx: support for debug and opt libraries
-
-2001-04-26 15:41 martink
-
- * Source/: cmOptionCommand.cxx, cmOptionCommand.h: better help
-
-2001-04-26 15:27 king
-
- * Source/: cmCableInstantiateClassCommand.cxx,
- cmCableInstantiateClassCommand.h, cmCableInstantiateCommand.cxx,
- cmCableInstantiateCommand.h, cmCablePackageCommand.cxx,
- cmCablePackageEntryCommand.cxx, cmCablePackageEntryCommand.h,
- cmCableSourceFilesCommand.cxx, cmCableSourceFilesCommand.h,
- cmCableWrapCommand.cxx, cmCableWrapCommand.h: ENH: Changed
- WriteConfiguration to non-const so it can do error checking.
- Added parsing and output of a name for each WrapperSet generated
- from a CABLE_WRAP command.
-
-2001-04-26 14:53 hoffman
-
- * Source/: cmAddLibraryCommand.cxx,
- cmBuildSharedLibrariesCommand.cxx, cmCacheManager.cxx,
- cmCacheManager.h, cmFindFileCommand.cxx,
- cmFindIncludeCommand.cxx, cmFindLibraryCommand.cxx,
- cmFindPathCommand.cxx, cmFindProgramCommand.cxx,
- cmOptionCommand.cxx, cmUtilitySourceCommand.cxx: ENH: add help
- for cache entries
-
-2001-04-26 10:49 martink
-
- * Source/: cmCacheManager.cxx, cmElseCommand.cxx, cmIfCommand.cxx,
- cmSystemTools.cxx, cmSystemTools.h: some fixes for If commands
-
-2001-04-26 09:38 martink
-
- * Source/: CMakeSetup.dsw, DumpDocumentation.dsp, cmCommands.cxx,
- cmDSPMakefile.cxx, cmDSPWriter.cxx, cmDSPMakefile.h,
- cmDSPWriter.h, cmFindFileCommand.cxx, cmFindIncludeCommand.cxx,
- cmFindIncludeCommand.h, cmFindLibraryCommand.cxx,
- cmFindLibraryCommand.h, cmFindPathCommand.cxx,
- cmFindPathCommand.h, cmMakefile.cxx, cmMakefile.h,
- cmUnixMakefileGenerator.cxx: bug fixes
-
-2001-04-25 16:09 hoffman
-
- * configure.in.sample, Source/Makefile.in,
- Source/cmCacheManager.cxx, Source/cmCacheManager.h,
- Source/cmMakefile.cxx: ENH: clean up cmake GUI and remove the
- parsing of CMakeLists.txt files by configure
-
-2001-04-25 11:47 martink
-
- * Source/: cmElseCommand.h, cmEndIfCommand.h, cmIfCommand.h: rules
- were not inherited when they should be
-
-2001-04-25 09:39 king
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: Fixed output of
- dependencies. It needs to loop over the makefile's targets, not
- the source lists.
-
-2001-04-25 09:37 king
-
- * Source/cmMakeDepend.cxx: STYLE: Updated comments for name change
- cmClassFile->cmSourceFile
-
-2001-04-25 09:33 martink
-
- * CMake.doc: updated the docs some
-
-2001-04-24 17:33 king
-
- * Source/cmUnixMakefileGenerator.cxx: ERR: cmClassFile.h ->
- cmSourceFile.h include change.
-
-2001-04-24 16:49 martink
-
- * Source/: cmClassFile.cxx, cmClassFile.h: many fixes and cleanup
- and features
-
-2001-04-24 16:46 martink
-
- * Source/: CMakeLib.dsp, Makefile.in, cmAbstractFilesCommand.cxx,
- cmAuxSourceDirectoryCommand.cxx, cmCablePackageCommand.cxx,
- cmCableSourceFilesCommand.cxx, cmCacheManager.cxx,
- cmCacheManager.h, cmCommands.cxx, cmDSPMakefile.cxx,
- cmDSPMakefile.h, cmDSPWriter.cxx, cmDSPWriter.h,
- cmMakeDepend.cxx, cmMakeDepend.h, cmMakefile.cxx, cmMakefile.h,
- cmOptionCommand.cxx, cmSourceFilesCommand.cxx,
- cmSourceFilesRequireCommand.cxx, cmTarget.h,
- cmUnixDefinesCommand.cxx, cmUnixLibrariesCommand.cxx,
- cmUnixMakefileGenerator.cxx, cmWin32DefinesCommand.cxx,
- cmWin32IncludeDirectoryCommand.cxx, cmWin32LibrariesCommand.cxx,
- cmWrapExcludeFilesCommand.cxx, cmVTKWrapPythonCommand.cxx,
- cmVTKWrapPythonCommand.h, cmVTKWrapTclCommand.cxx,
- cmVTKWrapTclCommand.h, cmSourceFile.cxx, cmSourceFile.h,
- cmTarget.cxx, cmWrapTclCommand.cxx, cmWrapTclCommand.h: many
- fixes and cleanup and features
-
-2001-04-24 12:40 hoffman
-
- * Source/: cmBuildSharedLibrariesCommand.cxx, cmCacheManager.cxx,
- cmCacheManager.h, cmMakefile.cxx, cmMakefile.h,
- cmOptionCommand.cxx, cmWrapTclCommand.cxx: BUG: fix build
- directory problem
-
-2001-04-24 09:45 king
-
- * CMakeVariables.make.in: ERR: Removed extra SRC_OBJ reference.
- The variable is no longer used.
-
-2001-04-23 16:40 hoffman
-
- * Source/: CMakeLib.dsp, cmCacheManager.cxx, cmCacheManager.h,
- cmDSWMakefile.cxx, cmDSWWriter.cxx, cmSourceGroup.h,
- cmStandardIncludes.h, cmWindowsConfigure.cxx,
- cmWindowsConfigure.h: ENH: new GUI editor for cmake cache file
-
-2001-04-23 16:34 martink
-
- * Source/: cmCommands.cxx, cmWrapTclCommand.cxx: added option
- command
-
-2001-04-23 16:33 martink
-
- * Source/: cmOptionCommand.cxx, cmOptionCommand.h: new command
-
-2001-04-23 13:58 blezek
-
- * CMakeRules.make.in, Source/cmUnixMakefileGenerator.cxx: BUG:
- Clean was not doing it's job
-
-2001-04-23 10:23 king
-
- * Source/cmIfCommand.h: ERR: Added virtual destructor to complement
- virtual functions in cmIfFunctionBlocker.
-
-2001-04-19 17:39 martink
-
- * Source/: cmAddDefinitionsCommand.cxx, cmAddDefinitionsCommand.h,
- cmCommands.cxx, cmElseCommand.cxx, cmElseCommand.h,
- cmEndIfCommand.cxx, cmEndIfCommand.h, cmFunctionBlocker.h,
- cmIfCommand.cxx, cmIfCommand.h, cmMakefile.cxx, cmMakefile.h:
- added if else endif add definition
-
-2001-04-19 13:28 martink
-
- * Source/: cmCablePackageCommand.cxx, cmCustomCommand.h,
- cmDSPMakefile.cxx, cmDSPWriter.cxx, cmDSWMakefile.cxx,
- cmDSWWriter.cxx, cmMakefile.cxx, cmSourceGroup.cxx, cmTarget.h,
- cmUnixMakefileGenerator.cxx: cleaned up the coding style made
- ivars private etc
-
-2001-04-18 08:01 king
-
- * Source/cmMakeDepend.cxx: ERR: We can't assume a vector iterator
- is a pointer. It must be dereferenced to get a reference to the
- element, and then we can take the address of that to get a
- pointer. "i" becomes "&*i"
-
-2001-04-17 07:42 king
-
- * Source/cmUnixMakefileGenerator.cxx: ERR: Removed unused variable.
-
-2001-04-16 15:40 hoffman
-
- * Source/: cmStandardIncludes.h, cmSystemTools.cxx: BUG: fix small
- compile issues on HP aCC
-
-2001-04-16 12:31 king
-
- * Source/: cmMakeDepend.cxx, cmMakeDepend.h: ENH: Changed m_Indices
- to an stl set and renamed it to m_IndexSet. Using a set results
- in a significant performance increase and reduction in memory
- usage.
-
-2001-04-16 10:15 millerjv
-
- * Source/cmAddLibraryCommand.cxx: FIX: allow ADD_LIBRARY with no
- source list
-
-2001-04-16 10:01 martink
-
- * Source/: cmCablePackageCommand.cxx, cmMakefile.h: fixed cable
- package issue
-
-2001-04-12 15:34 martink
-
- * Source/: Makefile.in, cmAddLibraryCommand.cxx,
- cmCacheManager.cxx, cmCacheManager.h, cmMakefile.h,
- cmUnixMakefileGenerator.cxx, cmWrapTclCommand.cxx: some bug fixes
-
-2001-04-12 09:55 king
-
- * Source/: cmUnixMakefileGenerator.cxx, cmUnixMakefileGenerator.h:
- ENH: Added individual library linkage output so that shared
- libraries will not try to link against themselves.
-
-2001-04-12 09:49 martink
-
- * Source/: cmExecutablesCommand.cxx, cmExecutablesCommand.h:
- removed old rules
-
-2001-04-11 16:34 king
-
- * Source/cmUnixMakefileGenerator.cxx: ENH: Generation now sets up
- proper linking of shared libraries to each other.
-
-2001-04-11 15:43 king
-
- * CMakeMaster.make.in: ERR: Needed to switch point where
- CMakeTargets.make is included so that Variables will be available
- to the targets file.
-
-2001-04-11 14:58 martink
-
- * Source/CMakeLib.dsp, Source/CMakeSetupCMD.dsp,
- Source/Makefile.in, Source/cmAbstractFilesCommand.cxx,
- Source/cmAddExecutableCommand.cxx,
- Source/cmAddExecutableCommand.h, Source/cmAddLibraryCommand.cxx,
- Source/cmAddLibraryCommand.h,
- Source/cmAuxSourceDirectoryCommand.cxx,
- Source/cmAuxSourceDirectoryCommand.h, Source/cmCableCommand.cxx,
- Source/cmCableData.cxx, Source/cmCableData.h,
- Source/cmCablePackageCommand.cxx, Source/cmCablePackageCommand.h,
- Source/cmCableSourceFilesCommand.cxx, Source/cmClassFile.cxx,
- Source/cmClassFile.h, Source/cmCommands.cxx,
- Source/cmCustomCommand.cxx, Source/cmCustomCommand.h,
- Source/cmDSPMakefile.cxx, Source/cmDSPMakefile.h,
- Source/cmDSPWriter.cxx, Source/cmDSPWriter.h,
- Source/cmDSWMakefile.cxx, Source/cmDSWMakefile.h,
- Source/cmDSWWriter.cxx, Source/cmDSWWriter.h,
- Source/cmMakeDepend.cxx, Source/cmMakeDepend.h,
- Source/cmMakefile.cxx, Source/cmMakefile.h,
- Source/cmSourceFilesCommand.cxx, Source/cmSourceFilesCommand.h,
- Source/cmSourceFilesRequireCommand.cxx,
- Source/cmSourceFilesRequireCommand.h, Source/cmSourceGroup.cxx,
- Source/cmSourceGroup.h, Source/cmTarget.h,
- Source/cmTestsCommand.cxx, Source/cmUnixMakefileGenerator.cxx,
- Source/cmUnixMakefileGenerator.h,
- Source/cmWrapExcludeFilesCommand.cxx,
- Source/cmWrapTclCommand.cxx, Source/cmWrapTclCommand.h,
- CMakeRules.make.in: major changes to support multiple libraries
- and source lists
-
-2001-04-10 15:26 king
-
- * Source/DLLHeader.dsptemplate: ENH: Need BUILD_SHARED_LIBRARIES
- defined for making windows DLLs.
-
-2001-04-09 10:56 king
-
- * Source/cmCablePackageCommand.cxx: ERR: Added double-quotes around
- command name before arguments are appended.
-
-2001-04-09 10:53 king
-
- * Source/cmUnixMakefileGenerator.cxx: ERR: Missed one EscapeSpaces
- call.
-
-2001-04-09 10:31 king
-
- * Source/: cmCableCommand.cxx, cmDSPMakefile.cxx, cmDSPWriter.cxx,
- cmSystemTools.cxx, cmSystemTools.h, cmUnixMakefileGenerator.cxx,
- cmUtilitySourceCommand.cxx: ERR: Corrected use of double-quotes
- to be compatible with UNIX make. Now double quotes (windows) or
- escape sequences for spaces (unix) are added when dependencies
- are output.
-
-2001-04-09 09:44 king
-
- * Source/: cmCableCommand.cxx, cmDSPMakefile.cxx, cmDSPWriter.cxx,
- cmUtilitySourceCommand.cxx: ENH: Added support for spaces in the
- output directory names. Spaces in the input directory name may
- work also, but are untested.
-
-2001-04-06 17:01 hoffman
-
- * Source/: cmDSPMakefile.cxx, cmDSPWriter.cxx, cmDSPMakefile.h,
- cmDSPWriter.h, cmDSWMakefile.cxx, cmDSWWriter.cxx: BUG: fix
- depends for libraries and executables in the same dir
-
-2001-04-06 14:51 hoffman
-
- * Source/: cmFindIncludeCommand.cxx, cmFindLibraryCommand.cxx,
- cmMakefile.cxx: ENH: better error reporting, and add NOTFOUND
- into cache for library and file find
-
-2001-04-06 12:00 martink
-
- * Source/cmFindIncludeCommand.h: fixed the documentation some
-
-2001-04-06 08:28 millerjv
-
- * Source/: cmDSPMakefile.cxx, cmDSPWriter.cxx: FIX: configurations
- list needed to be reset for each dsp file created
-
-2001-04-04 09:33 millerjv
-
- * Source/: EXEHeader.dsptemplate, staticLibHeader.dsptemplate: FIX:
- returned to using /O2 optimization level and put a pragma in the
- netlib code that could not handle the /Og component of /O2
-
-2001-03-28 11:49 king
-
- * Source/cmSystemTools.cxx: ERR: Blank line regular expression
- updated to allow whitespace on the line.
-
-2001-03-23 14:27 king
-
- * Source/: cmCableSourceFilesCommand.cxx,
- cmCableSourceFilesCommand.h: ENH: Added support for
- CABLE_SOURCE_FILES to refer to files that are not in the current
- directory. The include path is searched for the files.
-
-2001-03-21 15:52 king
-
- * Source/cmStandardIncludes.h: ERR: Added pragma to disable symbol
- length warning for Intel compiler.
-
-2001-03-20 13:48 king
-
- * Source/: cmDSPMakefile.cxx, cmDSPWriter.cxx: ERR: Small bug in
- generated DSP file fixed. A custom command environment variable
- has been replaced with explicity writing out the command.
-
-2001-03-20 13:20 king
-
- * Source/: CMakeLib.dsp, Makefile.in, cmCableCommand.cxx,
- cmCablePackageCommand.cxx, cmCommands.cxx, cmDSPMakefile.cxx,
- cmDSPMakefile.h, cmDSPWriter.cxx, cmDSPWriter.h, cmMakefile.cxx,
- cmMakefile.h, cmSourceGroup.cxx, cmSourceGroup.h,
- cmSourceGroupCommand.cxx, cmSourceGroupCommand.h,
- cmUnixMakefileGenerator.cxx, cmWrapTclCommand.cxx: ENH: Added
- SOURCE_GROUP command and corresponding support code. This
- command allows CMakeLists files to specify how sources are
- organized into groups in the generated DSP files and makefiles.
-
-2001-03-19 11:47 millerjv
-
- * Source/EXEHeader.dsptemplate: ENH: ignore unused libary warnings,
- removed /force
-
-2001-03-19 11:02 king
-
- * Source/: cmDSPMakefile.cxx, cmDSPWriter.cxx: ENH: Added text
- files group to DSP output. CMakeLists.txt is duplicated in this
- group and outside, but fixing this will require a reorganization
- of custom rule generation. I should get to that soon.
-
-2001-03-19 11:01 king
-
- * Source/cmCableCommand.cxx: ERR: Changed generation of rule to
- generate cable_config.xml to be produced differently for windows
- and unix.
-
-2001-03-19 11:00 king
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ERR: Removed
- functions I just added. They don't belong here (yet?).
-
-2001-03-19 10:09 king
-
- * Source/cmCableCommand.cxx: ENH: Added generation of a rule to
- re-run CMake if the cable_config.xml file is missing.
-
-2001-03-19 10:09 king
-
- * Source/: cmSystemTools.cxx, cmSystemTools.h: ENH: Added functions
- to get information about the CMake executable on each platform.
-
-2001-03-16 11:14 king
-
- * Source/: cmCableData.cxx, cmCableData.h: ERR: Re-ordered
- declaration of members v. order of initialization on the
- constructor to match each other.
-
-2001-03-16 11:04 king
-
- * Source/: cmCableData.cxx, cmCableData.h: BUG: Rearranged cable
- config file open to do open in construction of m_OutputFile.
- Fixes problem on SGI with opening the file.
-
-2001-03-16 09:25 king
-
- * Source/: cmCableDefineSetCommand.cxx,
- cmCableSourceFilesCommand.cxx: ENH: Changed generated includes to
- not have full path specified.
-
-2001-03-15 18:09 king
-
- * Source/: cmCommands.cxx, cmIncludeRegularExpressionCommand.cxx,
- cmIncludeRegularExpressionCommand.h, cmMakeDepend.cxx,
- cmMakeDepend.h, cmMakefile.cxx, cmMakefile.h: ENH: Added
- INCLUDE_REGULAR_EXPRESSION command to set regular expression used
- in dependency checking.
-
-2001-03-15 14:46 king
-
- * Source/: cmCableDefineSetCommand.cxx, cmCableDefineSetCommand.h:
- ENH: Added SOURCE_FILES syntax to CABLE_DEFINE_SET command.
-
-2001-03-15 14:33 king
-
- * Source/: cmMakefile.cxx, cmMakefile.h: BUG: Moved definition of
- CMAKE_SOURCE_DIR and CMAKE_BINARY_DIR to be as soon as their
- information is known.
-
-2001-03-15 10:42 king
-
- * Source/: cmCablePackageCommand.cxx, cmCablePackageCommand.h: BUG:
- Fixed segfault when CABLE_PACKAGE is only CABLE command. Related
- to order of virtual destructor calls.
-
-2001-03-14 17:49 king
-
- * Source/cmStandardIncludes.h: ERR: Added for-loop scoping hack for
- CMake sources on MSVC
-
-2001-03-14 16:34 king
-
- * Source/cmSystemTools.cxx: ENH: Added support for comments inside
- function calls and indented comments.
-
-2001-03-13 18:01 king
-
- * Source/: cmCableDefineSetCommand.cxx, cmCableDefineSetCommand.h:
- ENH: Added support for element tag specification with syntax
- tag:element as an argument to the CABLE_DEFINE_SET command. A
- single colon with nothing to its left will result in an empty
- tag.
-
-2001-03-13 09:33 king
-
- * Source/cmWrapTclCommand.cxx: ERR: Less-than-zero test replaced
- with greater-than-zero since we want zero arguments.
-
-2001-03-12 18:30 king
-
- * Source/: cmCommand.h, cmSystemTools.cxx, cmSystemTools.h: ENH:
- Improved error handling when GetError is called on a command that
- has not called SetError.
-
-2001-03-12 10:10 geoff
-
- * Source/: cmCommands.cxx, cmWin32IncludeDirectoryCommand.cxx,
- cmWin32IncludeDirectoryCommand.h: Include directories under Win32
- only (inherited by subdirs)
-
-2001-03-09 16:56 king
-
- * Source/: DLLHeader.dsptemplate, EXEHeader.dsptemplate,
- cmDSPMakefile.cxx, cmDSPMakefile.h, cmDSPWriter.cxx,
- cmDSPWriter.h, staticLibHeader.dsptemplate: ENH: Finished
- Simplifying dsptemplate processing with in place of separate
- Release, Debug, ReleaseDLL, ... configurations.
-
-2001-03-09 15:35 king
-
- * Source/: cmDSPMakefile.cxx, cmDSPWriter.cxx,
- staticLibHeader.dsptemplate: ERR: Fixed library path problem for
- ReleaseMinSize build. should now be used in place of separate
- Release, Debug, and ReleaseMinSize.
-
-2001-03-09 14:35 king
-
- * Source/EXEHeader.dsptemplate: ERR: Fixed header template for
- Release MinSize builds.
-
-2001-03-09 11:34 king
-
- * Source/EXEHeader.dsptemplate: ENH: Added Release MinSize
- configuration for executables.
-
-2001-03-09 11:33 king
-
- * Source/cmUtilitySourceCommand.h: ENH: Made UTILITY_SOURCE command
- inherited, just like FIND_PROGRAM.
-
-2001-03-09 11:16 king
-
- * Source/cmCablePackageCommand.cxx: ERR: Missing initalization of a
- cmClassFile::m_HeaderFileOnly fixed.
-
-2001-03-09 10:53 king
-
- * Source/: cmDSWMakefile.cxx, cmDSWWriter.cxx, cmMakefile.cxx,
- cmMakefile.h, cmUnixMakefileGenerator.cxx,
- cmUnixMakefileGenerator.h, cmUtilitySourceCommand.cxx: ENH: Added
- utility dependency support. Now a project can depend on other
- executables as well as link libraries.
-
-2001-03-09 10:52 king
-
- * Source/: cmCableCommand.cxx, cmCableData.cxx: ERR: Added
- automatic creation of directory for cable_config.xml file and
- corresponding error reporting.
-
-2001-03-09 10:52 king
-
- * Source/cmCablePackageCommand.cxx: ENH: Added proper dependency
- generation for a package on cable executable.
-
-2001-03-08 18:24 king
-
- * Source/: cmMakefile.cxx, cmUtilitySourceCommand.cxx: ERR:
- Replaced CMAKE_CFG= with CMAKE_CFG_OUTDIR= to fix windows
- behavior.
-
-2001-03-08 18:13 king
-
- * Source/: cmDSPMakefile.cxx, cmDSPWriter.cxx: ENH: Added output of
- custom rules for XML sources.
-
-2001-03-08 17:38 king
-
- * Source/cmUnixMakefileGenerator.cxx: ENH: Added output of defines
- flags as part of INCLUDE_FLAGS.
-
-2001-03-08 17:31 king
-
- * Source/cmUnixMakefileGenerator.cxx: ENH: Added output of a custom
- command's m_Source as a dependency.
-
-2001-03-08 17:31 king
-
- * Source/cmUnixDefinesCommand.cxx: ERR: Minor wording error in
- output message.
-
-2001-03-08 17:30 king
-
- * Source/cmCablePackageCommand.cxx: ENH: Creation of generator rule
- now properly uses the custom command's m_Source member.
-
-2001-03-08 16:13 king
-
- * Source/: cmCableCommand.cxx, cmCableData.cxx, cmCableData.h,
- cmCablePackageCommand.cxx, cmCablePackageCommand.h,
- cmCableSourceFilesCommand.cxx, cmCableSourceFilesCommand.h: ENH:
- Added creation of custom rules for generating CABLE packages.
-
-2001-03-08 16:12 king
-
- * Source/: cmMakeDepend.cxx, cmMakeDepend.h: ENH: Added support for
- finding dependencies for files that don't exist. Dependency
- recursion begins with hints provided in the cmClassFile for a
- file if it doesn't exist.
-
-2001-03-08 11:30 king
-
- * Source/cmCableSourceFilesCommand.cxx: ENH: Added .txx detection
- for Header block output.
-
-2001-03-08 10:30 king
-
- * Source/: cmCommands.cxx, cmMakefile.cxx, cmMakefile.h,
- cmSystemTools.cxx, cmSystemTools.h, cmUtilitySourceCommand.cxx,
- cmUtilitySourceCommand.h: ENH: Added UTILITY_SOURCE command for
- specifying where a 3rd party utility's source is located when it
- is included in the distribution of a project.
-
-2001-03-07 13:33 king
-
- * Source/cmCableCommand.cxx: ERR: Commented out experimental code
- that was accidentally checked in.
-
-2001-03-07 13:23 king
-
- * Source/cmCableCommand.cxx: ENH: Added Cable to Utilities and
- appropriate CMakeLists.txt changes. Moved VXLNumerics link out
- of source's root directory and into separate entries for Code and
- Testing directories. This prevents linking of all programs (like
- Cable) with the numerics library.
-
-2001-03-02 16:04 king
-
- * Source/: cmUnixMakefileGenerator.cxx, cmUnixMakefileGenerator.h:
- ENH: Added custom rule support to cmUnixMakefileGenerator.
-
-2001-03-02 13:47 will
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: repeat all -l options to
- avoid having to worry about link order.
-
-2001-03-02 12:27 king
-
- * Source/: cmCableCommand.cxx, cmCableData.cxx, cmCableData.h: ENH:
- CABLE config file (config_cable.xml) should now be opened in the
- output directory.
-
-2001-03-01 16:47 king
-
- * Source/: cmCableCloseNamespaceCommand.cxx,
- cmCableCloseNamespaceCommand.h, cmCableCommand.cxx,
- cmCableCommand.h, cmCableData.cxx, cmCableData.h,
- cmCableDefineSetCommand.cxx, cmCableDefineSetCommand.h,
- cmCableInstantiateClassCommand.cxx,
- cmCableInstantiateClassCommand.h, cmCableInstantiateCommand.cxx,
- cmCableInstantiateCommand.h, cmCableOpenNamespaceCommand.cxx,
- cmCableOpenNamespaceCommand.h, cmCablePackageCommand.cxx,
- cmCablePackageCommand.h, cmCablePackageEntryCommand.cxx,
- cmCablePackageEntryCommand.h, cmCableSourceFilesCommand.cxx,
- cmCableSourceFilesCommand.h, cmCableWrapCommand.cxx,
- cmCableWrapCommand.h, cmCommands.cxx: ENH: Change to new CABLE
- command architecture. CABLE configuration code is now generated
- on the first pass, during the Invoke() calls.
-
-2001-02-28 17:50 hoffman
-
- * Source/: cmDSPMakefile.cxx, cmDSPWriter.cxx, cmDSPMakefile.h,
- cmDSPWriter.h, cmDSWMakefile.cxx, cmDSWWriter.cxx: BUG: fix
- circular depends on libraries and remove depends for static
- libraries
-
-2001-02-28 09:34 king
-
- * Source/: cmCableCommand.cxx, cmCableCommand.h, cmCableData.cxx,
- cmCableData.h, cmCableDefineSetCommand.cxx,
- cmCableDefineSetCommand.h, cmCableInstantiateClassCommand.cxx,
- cmCableInstantiateClassCommand.h, cmCableInstantiateCommand.cxx,
- cmCableInstantiateCommand.h, cmCommands.cxx: ENH: CABIL -> CABLE
- rename.
-
-2001-02-27 16:50 martink
-
- * Source/: cmDSPMakefile.cxx, cmDSPMakefile.h, cmDSPWriter.cxx,
- cmDSPWriter.h, cmDSWMakefile.cxx, cmDSWWriter.cxx: many
- enhancements including dll support
-
-2001-02-27 16:49 martink
-
- * Source/cmWrapTclCommand.cxx: bug fixes
-
-2001-02-27 16:49 martink
-
- * Source/cmCommands.cxx: added new commands
-
-2001-02-27 16:48 martink
-
- * Source/cmClassFile.h: added wrap exclude ivar
-
-2001-02-27 16:48 martink
-
- * Source/: cmBuildSharedLibrariesCommand.cxx,
- cmBuildSharedLibrariesCommand.h, cmWrapExcludeFilesCommand.cxx,
- cmWrapExcludeFilesCommand.h: new commands
-
-2001-02-27 16:46 martink
-
- * Source/: DLLFooter.dsptemplate, DLLHeader.dsptemplate: dll build
- rules
-
-2001-02-27 16:44 martink
-
- * Source/staticLibHeader.dsptemplate: change in options for much
- smaller libraries
-
-2001-02-27 16:28 king
-
- * Source/: cmCableCommand.h, cmCableDefineSetCommand.cxx,
- cmCableDefineSetCommand.h, cmCableInstantiateClassCommand.cxx,
- cmCableInstantiateClassCommand.h, cmCableInstantiateCommand.cxx,
- cmCableInstantiateCommand.h, cmCommands.cxx: ENH: Implemented
- automatic tag generation for CABIL_DEFINE_SET command. Added tag
- output to WriteConfiguration methods. Added
- CABIL_INSTANTIATE_CLASS command to generate explicit class
- template instantiation configuration output.
-
-2001-02-27 15:41 king
-
- * Source/cmSystemTools.cxx: ENH/BUG: Improved function parsing to
- allow just about anything inside a double-quoted argument. Also
- fixed parsing of lines with both quoted and non-quoted arguments.
-
-2001-02-27 12:00 lorensen
-
- * Source/cmSystemTools.cxx: ENH: mask on mkdir set to 777.
-
-2001-02-27 12:00 lorensen
-
- * Source/CMakeBuildTargets.cxx: ERR: missing std:: on cout.
-
-2001-02-26 20:58 millerjv
-
- * Source/staticLibHeader.dsptemplate: FIX: added /GR to MinSize
- build to avoid warnings about dynamic cast
-
-2001-02-26 18:20 king
-
- * Source/cmCableInstantiateCommand.cxx: ERR: Fixed configuration
- file output to open file in output directory.
-
-2001-02-26 18:16 king
-
- * Source/cmWrapTclCommand.cxx: int -> unsigned int
-
-2001-02-26 18:00 king
-
- * Source/: cmCableCommand.cxx, cmCableCommand.h, cmCableData.cxx,
- cmCableData.h, cmCableDefineSetCommand.cxx,
- cmCableDefineSetCommand.h, cmCableInstantiateCommand.cxx,
- cmCableInstantiateCommand.h, cmCommands.cxx: ENH: Added CABIL
- commands for configuration file generation.
-
-2001-02-26 17:58 king
-
- * Source/cmMakefile.h: ENH: Added GetUsedCommands() method.
-
-2001-02-26 17:58 king
-
- * Source/cmStandardIncludes.h: ERR: fsream.h -> fstream.h
-
-2001-02-26 17:17 martink
-
- * Source/: cmCommands.cxx, cmDSPMakefile.cxx, cmDSPMakefile.h,
- cmDSPWriter.cxx, cmDSPWriter.h, cmMakefile.h: a variety of fixes
- and enhancements
-
-2001-02-26 17:17 martink
-
- * Source/: cmWrapTclCommand.cxx, cmWrapTclCommand.h: very early
- version of a wrapper
-
-2001-02-26 17:15 martink
-
- * Source/: cmClassFile.cxx, cmClassFile.h: added functionality,
- fixed bug if no file existed and with header files
-
-2001-02-26 17:14 martink
-
- * Source/: cmFindProgramCommand.cxx, cmFindProgramCommand.h: fixed
- bug and modified functionality
-
-2001-02-26 17:13 martink
-
- * Source/: cmFindFileCommand.cxx, cmFindFileCommand.h: new command
-
-2001-02-26 13:25 king
-
- * Source/cmMakefile.cxx: ERR: Fixed unknown command output error
- message for spacing.
-
-2001-02-26 12:07 king
-
- * Source/: cmAbstractFilesCommand.h, cmAddTargetCommand.h,
- cmAuxSourceDirectoryCommand.h, cmCommand.h,
- cmExecutablesCommand.h, cmFindIncludeCommand.h,
- cmFindLibraryCommand.h, cmFindProgramCommand.h,
- cmIncludeDirectoryCommand.h, cmLibraryCommand.h,
- cmLinkDirectoriesCommand.h, cmLinkLibrariesCommand.h,
- cmProjectCommand.h, cmSourceFilesCommand.h,
- cmSourceFilesRequireCommand.h, cmSubdirCommand.h,
- cmTestsCommand.h, cmUnixDefinesCommand.h,
- cmUnixLibrariesCommand.h, cmWin32DefinesCommand.h,
- cmWin32LibrariesCommand.h: ENH: Added safe downcast support
- (without RTTI) to cmCommand and its subclasses.
-
-2001-02-23 10:40 king
-
- * Source/: cmAbstractFilesCommand.cxx, cmCommand.h, cmCommands.h,
- cmConfigureFileNoAutoconf.h, cmFindIncludeCommand.cxx,
- cmFindLibraryCommand.cxx, cmFindProgramCommand.cxx,
- cmMakefile.cxx, cmUnixMakefileGenerator.cxx: ERR: Fixed warnings
- (int->unsigned int and a few others).
-
-2001-02-22 19:37 hoffman
-
- * configure.in.sample: ENH: update sample
-
-2001-02-22 19:31 hoffman
-
- * Source/cmSystemTools.cxx: BUG: remove debug print
-
-2001-02-22 19:23 hoffman
-
- * Source/CMakeBuildTargets.cxx, Source/Makefile.in,
- Source/cmCacheManager.cxx, Source/cmCacheManager.h,
- Source/cmConfigureFileNoAutoconf.cxx, Source/cmDSPMakefile.cxx,
- Source/cmDSPWriter.cxx, Source/cmDSWMakefile.cxx,
- Source/cmDSWWriter.cxx, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmStandardIncludes.h,
- Source/cmSystemTools.cxx, Source/cmSystemTools.h,
- CMakeRules.make.in, CMakeTopMakefileTemplate.in,
- Source/cmConfigure.h.in: ENH: add CMakeCache.txt support
-
-2001-02-20 14:12 hoffman
-
- * Source/cmSystemTools.cxx: ENH: remove relative and extra paths in
- CMakeLists.txt files
-
-2001-02-20 12:25 hoffman
-
- * CMakeRules.make.in: BUG: fix for in source build
-
-2001-02-19 15:13 hoffman
-
- * CMakeMakefileTemplate.in, MakefileTemplate.in,
- configure.in.sample, Source/CMakeBuildTargets.cxx,
- Source/CMakeSetupCMD.cxx, Source/Makefile.in,
- Source/cmCacheManager.cxx, Source/cmCacheManager.h,
- Source/cmCommand.h, Source/cmDSWMakefile.cxx,
- Source/cmDSWWriter.cxx, Source/cmFindIncludeCommand.cxx,
- Source/cmFindLibraryCommand.cxx, Source/cmFindProgramCommand.cxx,
- Source/cmIncludeDirectoryCommand.cxx, Source/cmMakefile.cxx,
- Source/cmRegularExpression.h, Source/cmSystemTools.cxx,
- Source/cmUnixMakefileGenerator.cxx,
- Source/cmUnixMakefileGenerator.h: ENH: first pass at cache, clean
- up the unix generator, clean up configure.in some
-
-2001-02-18 13:02 hoffman
-
- * configure.in.sample: ENH: add a smaple configure.in for CMake
- based projects
-
-2001-02-18 12:47 hoffman
-
- * configure.in.sample: ENH: add a smaple configure.in for CMake
- based projects
-
-2001-02-16 15:34 hoffman
-
- * Source/cmCacheManager.h: ENH: clean up comments some
-
-2001-02-16 15:01 will
-
- * CMake.pdf: ENH:Added pdf file
-
-2001-02-16 11:52 martink
-
- * CMake.doc: clean up docs
-
-2001-02-16 11:34 martink
-
- * Source/: cmConfigureFileNoAutoconf.cxx, cmDSWMakefile.cxx,
- cmDSWWriter.cxx, cmFindIncludeCommand.cxx,
- cmFindLibraryCommand.cxx, cmFindLibraryCommand.h,
- cmFindProgramCommand.cxx, cmMakefile.cxx, cmMakefile.h,
- cmSystemTools.cxx, cmSystemTools.h: ENH: add new commands fro
- find library and find program
-
-2001-02-15 13:30 martink
-
- * CMakeRules.make.in, CMakeVariables.make.in,
- Source/CMakeBuildTargets.cxx, Source/CMakeSetupCMD.cxx,
- Source/cmClassFile.cxx, Source/cmClassFile.h,
- Source/cmConfigureFileNoAutoconf.h, Source/cmDSPMakefile.cxx,
- Source/cmDSPWriter.cxx, Source/cmDSWMakefile.cxx,
- Source/cmDSWWriter.cxx, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmProjectCommand.cxx,
- Source/cmProjectCommand.h: some cleanup and fixes
-
-2001-02-14 12:26 hoffman
-
- * Source/cmMakeDepend.cxx: ENH: fix depend segfault
-
-2001-02-13 18:49 hoffman
-
- * Source/: cmConfigureFileNoAutoconf.cxx, cmMakefile.cxx: ENH: new
- vnl
-
-2001-02-13 16:48 hoffman
-
- * Source/: cmMakefile.cxx, cmMakefile.h: ENH: add configure style
- @var@ expansion
-
-2001-02-12 19:49 hoffman
-
- * Source/: CMakeBuildTargets.cxx, Makefile.in, cmCommands.cxx,
- cmConfigureFileNoAutoconf.cxx, cmConfigureFileNoAutoconf.h,
- cmConfigureHeaderCommand.cxx, cmConfigureHeaderCommand.h,
- cmMakefile.cxx, cmMakefile.h, cmStandardIncludes.h,
- cmSystemTools.cxx, cmCommands.h: ENH: get rid of special msc
- configure file
-
-2001-02-12 14:42 hoffman
-
- * Source/: CMakeLib.dsp, CMakeSetup.dsw, CMakeSetupCMD.dsp: ENH:
- share a .lib with the command line and mfc versions.
-
-2001-02-12 14:26 hoffman
-
- * Source/: CMakeLib.dsp, CMakeSetup.dsw, CMakeSetupCMD.cxx,
- CMakeSetupCMD.dsp, Makefile.in, cmCacheManager.cxx,
- cmCacheManager.h, cmCommands.cxx, cmConfigureHeaderCommand.cxx,
- cmConfigureHeaderCommand.h, cmDSWMakefile.cxx, cmDSWWriter.cxx,
- cmMSProjectGenerator.h: ENH: add cache manager class, move all
- commands into cmCommands.cxx to speed up compile times, share a
- .lib with the command line and mfc versions.
-
-2001-02-06 17:01 hoffman
-
- * Source/staticLibHeader.dsptemplate: ENH: add /GX /Zm1000
-
-2001-02-06 16:48 hoffman
-
- * Source/staticLibHeader.dsptemplate: ENH: min size build
-
-2001-02-06 10:52 hoffman
-
- * Source/staticLibHeader.dsptemplate: ENH: put back /Zm1000 so we
- can build large files
-
-2001-02-06 08:56 millerjv
-
- * Source/staticLibHeader.dsptemplate: FIX: remove precompiled
- header settings
-
-2001-02-06 08:54 millerjv
-
- * Source/EXEHeader.dsptemplate: FIX: added /force to link options
- and removed precompiled header usage
-
-2001-01-25 15:48 millerjv
-
- * Source/: EXEHeader.dsptemplate, staticLibHeader.dsptemplate: BUG:
- backed off on the compiler optimization used. Instead of using
- /O2, we now use all the components of /Ox (/Ob1 /Oi /Ot /Oy /Gs)
- except for /Og
-
-2001-01-22 10:00 will
-
- * Source/CMakeSetupCMD.dsp: BUG: convert to dos format
-
-2001-01-22 09:49 will
-
- * Source/: CMakeSetup.dsw, CMakeSetupCMD.dsp: BUG: make dsp and dsw
- files binary
-
-2001-01-18 13:43 will
-
- * README: ENH:Commands not rules
-
-2001-01-18 12:06 will
-
- * Source/Makefile.in: ERR:Oops, use SimpleRule not SimpleCommand
-
-2001-01-18 11:51 will
-
- * CMakeCommands.make.in, CMakeMaster.make.in, CMakeRules.make.in,
- CMakeSimpleCommands.make.in, CMakeSimpleRules.make.in: ERR:Oops,
- renamed back
-
-2001-01-18 11:20 will
-
- * CMakeCommands.make.in, CMakeMaster.make.in, CMakeRules.make.in,
- CMakeSimpleCommands.make.in, CMakeSimpleRules.make.in,
- Source/CMakeSetupCMD.dsp, Source/Makefile.in,
- Source/cmAbstractFilesCommand.cxx,
- Source/cmAbstractFilesCommand.h, Source/cmAbstractFilesRule.cxx,
- Source/cmAbstractFilesRule.h, Source/cmAddTargetCommand.cxx,
- Source/cmAddTargetCommand.h, Source/cmAddTargetRule.cxx,
- Source/cmAddTargetRule.h, Source/cmAuxSourceDirectoryCommand.cxx,
- Source/cmAuxSourceDirectoryCommand.h,
- Source/cmAuxSourceDirectoryRule.cxx,
- Source/cmAuxSourceDirectoryRule.h, Source/cmCommand.h,
- Source/cmDumpDocumentation.cxx, Source/cmExecutablesCommand.cxx,
- Source/cmExecutablesCommand.h, Source/cmExecutablesRule.cxx,
- Source/cmExecutablesRule.h, Source/cmFindIncludeCommand.cxx,
- Source/cmFindIncludeCommand.h, Source/cmFindIncludeRule.cxx,
- Source/cmFindIncludeRule.h, Source/cmFindLibraryCommand.cxx,
- Source/cmFindLibraryCommand.h, Source/cmFindLibraryRule.cxx,
- Source/cmFindLibraryRule.h, Source/cmFindProgramCommand.cxx,
- Source/cmFindProgramCommand.h, Source/cmFindProgramRule.cxx,
- Source/cmFindProgramRule.h, Source/cmIncludeDirectoryCommand.cxx,
- Source/cmIncludeDirectoryCommand.h,
- Source/cmIncludeDirectoryRule.cxx,
- Source/cmIncludeDirectoryRule.h, Source/cmLibraryCommand.cxx,
- Source/cmLibraryCommand.h, Source/cmLibraryRule.cxx,
- Source/cmLibraryRule.h, Source/cmLinkDirectoriesCommand.cxx,
- Source/cmLinkDirectoriesCommand.h,
- Source/cmLinkDirectoriesRule.cxx, Source/cmLinkDirectoriesRule.h,
- Source/cmLinkLibrariesCommand.cxx,
- Source/cmLinkLibrariesCommand.h, Source/cmLinkLibrariesRule.cxx,
- Source/cmLinkLibrariesRule.h, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmMakefileGenerator.h,
- Source/cmProjectCommand.cxx, Source/cmProjectCommand.h,
- Source/cmProjectRule.cxx, Source/cmProjectRule.h,
- Source/cmRuleMaker.h, Source/cmSourceFilesCommand.cxx,
- Source/cmSourceFilesCommand.h,
- Source/cmSourceFilesRequireCommand.cxx,
- Source/cmSourceFilesRequireCommand.h,
- Source/cmSourceFilesRequireRule.cxx,
- Source/cmSourceFilesRequireRule.h, Source/cmSourceFilesRule.cxx,
- Source/cmSourceFilesRule.h, Source/cmSubdirCommand.cxx,
- Source/cmSubdirCommand.h, Source/cmSubdirRule.cxx,
- Source/cmSubdirRule.h, Source/cmSystemTools.h,
- Source/cmTestsCommand.cxx, Source/cmTestsCommand.h,
- Source/cmTestsRule.cxx, Source/cmTestsRule.h,
- Source/cmUnixDefinesCommand.cxx, Source/cmUnixDefinesCommand.h,
- Source/cmUnixDefinesRule.cxx, Source/cmUnixDefinesRule.h,
- Source/cmUnixLibrariesCommand.cxx,
- Source/cmUnixLibrariesCommand.h, Source/cmUnixLibrariesRule.cxx,
- Source/cmUnixLibrariesRule.h, Source/cmWin32DefinesCommand.cxx,
- Source/cmWin32DefinesCommand.h, Source/cmWin32DefinesRule.cxx,
- Source/cmWin32DefinesRule.h, Source/cmWin32LibrariesCommand.cxx,
- Source/cmWin32LibrariesCommand.h,
- Source/cmWin32LibrariesRule.cxx, Source/cmWin32LibrariesRule.h:
- ENH:Reworked CMake for consistency
-
-2001-01-12 14:35 will
-
- * README, Source/cmAbstractFilesRule.h, Source/cmAddTargetRule.h,
- Source/cmAuxSourceDirectoryRule.h, Source/cmExecutablesRule.h,
- Source/cmFindIncludeRule.h, Source/cmFindLibraryRule.h,
- Source/cmFindProgramRule.h, Source/cmIncludeDirectoryRule.h,
- Source/cmLibraryRule.h, Source/cmLinkDirectoriesRule.h,
- Source/cmLinkLibrariesRule.h, Source/cmMakefile.cxx,
- Source/cmProjectRule.h, Source/cmRuleMaker.h,
- Source/cmSourceFilesRequireRule.h, Source/cmSourceFilesRule.h,
- Source/cmSubdirRule.h, Source/cmTestsRule.h,
- Source/cmUnixDefinesRule.h, Source/cmUnixLibrariesRule.h,
- Source/cmWin32DefinesRule.h, Source/cmWin32LibrariesRule.h:
- ENH:Tweaks to dump documentation
-
-2001-01-12 14:05 hoffman
-
- * Source/: cmDSPMakefile.cxx, cmDSPWriter.cxx: ENH: add define
- flags in the right place
-
-2001-01-12 13:48 hoffman
-
- * Source/cmSystemTools.cxx: BUG: add check for missing ) on
- function
-
-2001-01-12 13:07 will
-
- * README, Source/cmAuxSourceDirectoryRule.h,
- Source/cmIncludeDirectoryRule.h, Source/cmLinkLibrariesRule.h,
- Source/cmProjectRule.h, Source/cmSourceFilesRequireRule.h,
- Source/cmSubdirRule.h, Source/cmUnixDefinesRule.h,
- Source/cmWin32DefinesRule.h: ENH:Tweaks to dump documentation
-
-2001-01-12 12:49 will
-
- * Source/: cmAddTargetRule.h, cmMakefile.cxx: ENH:Tweaks to
- documentation
-
-2001-01-12 12:49 will
-
- * README: ENH:Updated for rule-based CMake
-
-2001-01-12 12:42 will
-
- * Source/: cmDumpDocumentation.cxx, cmMakefile.cxx, cmMakefile.h:
- ENH:Simple program dumps out internal documentation for CMake
-
-2001-01-12 07:43 will
-
- * README: README
-
-2001-01-11 16:19 will
-
- * doxygen.config: ENH:Doxygenated CMake
-
-2001-01-11 14:55 will
-
- * Source/: CMakeBuildTargets.cxx, CMakeSetupCMD.cxx,
- cmAbstractFilesRule.cxx, cmClassFile.cxx, cmDSPMakefile.cxx,
- cmDSPWriter.cxx, cmDSWMakefile.cxx, cmDSWWriter.cxx,
- cmExecutablesRule.cxx, cmFindIncludeRule.cxx,
- cmFindLibraryRule.cxx, cmFindProgramRule.cxx,
- cmIncludeDirectoryRule.cxx, cmLibraryRule.cxx,
- cmLinkDirectoriesRule.cxx, cmLinkLibrariesRule.cxx,
- cmMSProjectGenerator.cxx, cmMakeDepend.cxx, cmMakefile.cxx,
- cmMakefileGenerator.cxx, cmProjectRule.cxx,
- cmSourceFilesRequireRule.cxx, cmSourceFilesRule.cxx,
- cmSubdirRule.cxx, cmSystemTools.cxx, cmTestsRule.cxx,
- cmUnixDefinesRule.cxx, cmUnixLibrariesRule.cxx,
- cmWin32DefinesRule.cxx, cmWin32LibrariesRule.cxx:
- ENH:Documentation and cleanups
-
-2001-01-11 14:47 will
-
- * Source/: CMakeSetupCMD.cxx, cmAddTargetRule.cxx,
- cmAuxSourceDirectoryRule.cxx, cmClassFile.h, cmDSWMakefile.cxx,
- cmDSWMakefile.h, cmDSWWriter.cxx, cmDSWWriter.h, cmDirectory.h,
- cmFindProgramRule.h, cmMSProjectGenerator.cxx,
- cmMSProjectGenerator.h, cmMakeDepend.h, cmMakefile.h,
- cmMakefileGenerator.h, cmRegularExpression.cxx,
- cmRegularExpression.h, cmStandardIncludes.h, cmSystemTools.cxx,
- cmSystemTools.h, cmUnixMakefileGenerator.cxx,
- cmUnixMakefileGenerator.h, cmWindowsConfigure.cxx,
- cmWindowsConfigure.h: ENH:Documentation and cleanups
-
-2001-01-11 11:35 blezek
-
- * Source/: cmWin32DefinesRule.cxx, cmWin32LibrariesRule.cxx: BUG:
- Broken on non WIN32 platforms, changed SetEnableOff to EnabledOff
-
-2001-01-11 08:04 will
-
- * Source/: cmFindIncludeRule.h, cmFindLibraryRule.h,
- cmFindProgramRule.h, cmIncludeDirectoryRule.h, cmLibraryRule.h,
- cmLinkDirectoriesRule.h, cmLinkLibrariesRule.h, cmProjectRule.h,
- cmSourceFilesRequireRule.h, cmSourceFilesRule.h, cmSubdirRule.h,
- cmTestsRule.h, cmUnixDefinesRule.h, cmUnixLibrariesRule.h,
- cmWin32DefinesRule.h, cmWin32LibrariesRule.h: ENH:Added
- documentation; clean-up
-
-2001-01-10 17:29 will
-
- * Source/: cmExecutablesRule.h, cmFindIncludeRule.h: ENH:Beginning
- clean up; adding documentation
-
-2001-01-10 17:13 will
-
- * Source/cmAuxSourceDirectoryRule.h: ENH:Beginning clean up; adding
- documentation
-
-2001-01-10 17:05 will
-
- * Source/: cmAbstractFilesRule.h, cmAddTargetRule.h,
- cmAuxSourceDirectoryRule.h, cmDSPMakefile.h, cmDSPWriter.h,
- cmExecutablesRule.h, cmFindIncludeRule.h, cmFindLibraryRule.h,
- cmFindProgramRule.h, cmIncludeDirectoryRule.h, cmLibraryRule.h,
- cmLinkDirectoriesRule.h, cmLinkLibrariesRule.h, cmProjectRule.h,
- cmRuleMaker.h, cmSourceFilesRequireRule.h, cmSourceFilesRule.h,
- cmSubdirRule.h, cmTestsRule.h, cmUnixDefinesRule.cxx,
- cmUnixDefinesRule.h, cmUnixLibrariesRule.cxx,
- cmUnixLibrariesRule.h, cmWin32DefinesRule.h,
- cmWin32LibrariesRule.h: ENH:Beginning clean up; adding
- documentation
-
-2001-01-09 15:13 hoffman
-
- * Source/cmUnixMakefileGenerator.cxx: BUG: look for -l and -L only
- at the begining of a link string
-
-2001-01-05 13:52 blezek
-
- * Source/: CMakeBuildTargets.cxx, CMakeSetupCMD.cxx: BUG: main can
- not be void under ANSI C++
-
-2001-01-05 13:49 blezek
-
- * Source/cmMakefileGenerator.cxx: BUG: Looking for
- cmMakeFileGenerator.h rather than cmMakefileGenerator.h
-
-2001-01-05 11:41 hoffman
-
- * Source/: CMakeBuildTargets.cxx, CMakeSetupCMD.cxx,
- CMakeSetupCMD.dsp, Makefile.in, cmAbstractFilesRule.cxx,
- cmAbstractFilesRule.h, cmAddTargetRule.cxx, cmAddTargetRule.h,
- cmAuxSourceDirectoryRule.cxx, cmAuxSourceDirectoryRule.h,
- cmClassFile.cxx, cmClassFile.h, cmCollectFlags.cxx,
- cmCollectFlags.h, cmDSPMakefile.cxx, cmDSPMakefile.h,
- cmDSPWriter.cxx, cmDSPWriter.h, cmDSWMakefile.cxx,
- cmDSWWriter.cxx, cmDSWMakefile.h, cmDSWWriter.h, cmDirectory.cxx,
- cmDirectory.h, cmExecutablesRule.cxx, cmExecutablesRule.h,
- cmFindIncludeRule.cxx, cmFindIncludeRule.h,
- cmFindLibraryRule.cxx, cmFindLibraryRule.h,
- cmFindProgramRule.cxx, cmFindProgramRule.h,
- cmIncludeDirectoryRule.cxx, cmIncludeDirectoryRule.h,
- cmLibraryRule.cxx, cmLibraryRule.h, cmLinkDirectoriesRule.cxx,
- cmLinkDirectoriesRule.h, cmLinkLibrariesRule.cxx,
- cmLinkLibrariesRule.h, cmMSProjectGenerator.cxx,
- cmMSProjectGenerator.h, cmMakeDepend.cxx, cmMakeDepend.h,
- cmMakefile.cxx, cmMakefile.h, cmMakefileGenerator.cxx,
- cmMakefileGenerator.h, cmProjectRule.cxx, cmProjectRule.h,
- cmRegularExpression.cxx, cmRegularExpression.h, cmRuleMaker.h,
- cmSourceFilesRequireRule.cxx, cmSourceFilesRequireRule.h,
- cmSourceFilesRule.cxx, cmSourceFilesRule.h, cmStandardIncludes.h,
- cmSubdirRule.cxx, cmSubdirRule.h, cmSystemTools.cxx,
- cmSystemTools.h, cmTestsRule.cxx, cmTestsRule.h,
- cmUnixDefinesRule.cxx, cmUnixDefinesRule.h,
- cmUnixLibrariesRule.cxx, cmUnixLibrariesRule.h,
- cmUnixMakefile.cxx, cmUnixMakefile.h,
- cmUnixMakefileGenerator.cxx, cmUnixMakefileGenerator.h,
- cmWin32DefinesRule.cxx, cmWin32DefinesRule.h,
- cmWin32LibrariesRule.cxx, cmWin32LibrariesRule.h,
- cmWindowsConfigure.cxx, cmWindowsConfigure.h: ENH: rework cmake,
- added ruleMaker classes and changed the syntax of the
- CMakeLists.txt files.
-
-2000-12-07 15:45 blezek
-
- * Source/cmMakefile.cxx: ENH: Added TESTS target
-
-2000-11-22 11:02 hoffman
-
- * Source/cmMakeDepend.cxx: BUG: remove bogus warning about not
- finding a depend file, if there are no include paths
-
-2000-11-09 10:41 will
-
- * README, Source/cmCollectFlags.cxx, Source/cmCollectFlags.h,
- Source/cmWindowsConfigure.cxx: ENH:Changed CMAKE_SOURCE_ROOT to
- CMAKE_SOURCE_DIR
-
-2000-11-03 16:38 hoffman
-
- * README: [no log message]
-
-2000-11-02 11:13 hoffman
-
- * Source/cmMakefile.cxx: BUG: make sure SOURCE_FILES starts at the
- begining of line
-
-2000-11-02 10:56 blezek
-
- * CMakeVariables.make.in: ENH: Moved @JAVA@ to @JAVACOMMAND@
-
-2000-11-02 10:24 will
-
- * README, Source/cmClassFile.cxx, Source/cmMakefile.cxx:
- ENH:Reworked CMake to clearer indicate what the variables do
-
-2000-10-25 17:18 hoffman
-
- * Source/: cmSystemTools.cxx: BUG: remove tabs from classnames
-
-2000-10-04 09:58 lorensen
-
- * CMakeVariables.make.in: Enh: Added TCLSH
-
-2000-10-02 14:21 blezek
-
- * Source/CMakeBuildTargets.cxx: BUG: if the path to your source
- directory has a -S in it, it will be picked up as the source
- directory by the command line parser, because it matches -S at
- any character position in the argements. Bad, should have used
- getopt, except that it is not cross platform.
-
-2000-10-02 13:50 blezek
-
- * CMakeVariables.make.in: ENH: Support for XML builds and Dashboard
-
-2000-09-28 12:43 blezek
-
- * README: ENH: Added note about VERBATIM targets in CMakeList.txt
-
-2000-09-27 15:01 hoffman
-
- * CMakeMaster.make.in, CMakeRules.make.in, CMakeVariables.make.in,
- README, Source/cmDSWMakefile.cxx, Source/cmDSWMakefile.h,
- Source/cmDSWWriter.cxx, Source/cmDSWWriter.h,
- Source/cmMakefile.cxx, Source/cmMakefile.h,
- Source/cmSystemTools.cxx, Source/cmSystemTools.h,
- Source/cmUnixMakefile.cxx, Source/cmUnixMakefile.h: ENH: change
- ME to LIBRARY and added PROJECT, also remove ITK stuff and
- replaced with CMake
-
-2000-09-21 13:45 hoffman
-
- * README, Source/CMakeBuildTargets.cxx, Source/CMakeSetupCMD.cxx,
- Source/cmCollectFlags.cxx, Source/cmCollectFlags.h,
- Source/cmDSPMakefile.cxx, Source/cmDSPWriter.cxx,
- Source/cmDSWMakefile.cxx, Source/cmDSWWriter.cxx,
- Source/cmMakeDepend.cxx, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmUnixMakefile.cxx,
- Source/itkVC60Configure.cxx, Source/itkVC60Configure.h: ENH:
- clean up code, and varible names
-
-2000-09-18 10:19 hoffman
-
- * Source/cmUnixMakefile.cxx: BUG: remove cout
-
-2000-09-18 09:19 hoffman
-
- * CMakeRules.make.in, CMakeVariables.make.in, README,
- Source/cmDSPMakefile.cxx, Source/cmDSPWriter.cxx,
- Source/cmMakeDepend.cxx, Source/cmUnixMakefile.cxx,
- Source/cmWindowsConfigure.cxx, Source/cmWindowsConfigure.h: ENH:
- added a config setup file for CMakeSetup. Cleaned up the names
- of the source and binary directories
-
-2000-09-18 07:27 hoffman
-
- * Source/CMakeSetupCMD.dsp: ENH: remove unused files
-
-2000-09-12 06:44 hoffman
-
- * CMakeRules.make.in, CMakeVariables.make.in: BUG: fix build in
- place source directory
-
-2000-09-12 05:37 hoffman
-
- * Source/: cmCollectFlags.cxx, cmCollectFlags.h: NEW: class to
- collect all the flags from parent directories
-
-2000-09-12 05:30 hoffman
-
- * CMakeMaster.make.in, CMakeRules.make.in, CMakeTargets.make.in,
- CMakeVariables.make.in, MakefileTemplate.in, README,
- Source/CMakeBuildTargets.cxx, Source/CMakeSetup.cxx,
- Source/CMakeSetup.dsw, Source/CMakeSetupCMD.cxx,
- Source/CMakeSetupCMD.dsp, Source/Makefile.in,
- Source/cmClassFile.cxx, Source/cmClassFile.h,
- Source/cmDSPBuilder.cxx, Source/cmDSPBuilder.h,
- Source/cmDSPMakefile.cxx, Source/cmDSPWriter.cxx,
- Source/cmDSWBuilder.cxx, Source/cmDSWBuilder.h,
- Source/cmDSWMakefile.cxx, Source/cmDSWMakefile.h,
- Source/cmDSWWriter.cxx, Source/cmDSWWriter.h,
- Source/cmMakeDepend.cxx, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmPCBuilder.cxx,
- Source/cmPCBuilder.h, Source/cmSystemTools.cxx,
- Source/cmSystemTools.h, Source/cmUnixMakefile.cxx,
- Source/cmUnixMakefile.h, Source/cmWindowsConfigure.h,
- Source/itkVC60Configure.h: ENH: CMake and configure now use
- SUBDIRS in CMakeLists.txt to find all the directories of the
- system.
-
-2000-09-01 10:43 hoffman
-
- * Source/: EXEHeader.dsptemplate, cmSystemTools.cxx: BUG: fix
- release build on windows
-
-2000-08-31 14:26 hoffman
-
- * CMakeVariables.make.in, Source/cmUnixMakefile.cxx: BUG: fix build
- of lib.a problem
-
-2000-08-31 14:15 hoffman
-
- * Source/: CMakeSetup.dsw, cmDSPMakefile.cxx, cmDSPWriter.cxx: BUG:
- fix name of command line version in dsp files
-
-2000-08-31 13:54 hoffman
-
- * CMakeSimpleRules.make, CMakeSimpleRules.make.in: BUG: fix for out
- of source build
-
-2000-08-31 13:52 hoffman
-
- * CMakeSimpleRules.make: ENH: fix for Sgi make
-
-2000-08-31 09:36 hoffman
-
- * CMakeRules.make.in, Source/Makefile.in,
- Source/cmUnixMakefile.cxx: ENH: fix for SGI make
-
-2000-08-31 06:36 hoffman
-
- * CMakeVariables.make.in, README: ENH: clean things up a bit
-
-2000-08-30 13:59 hoffman
-
- * Source/cmDirectory.cxx, Source/cmDirectory.h,
- MakefileTemplate.in: ENH: add ability to compile all the files in
- a sub-directory
-
-2000-08-30 13:35 hoffman
-
- * CMakeRules.make.in, CMakeVariables.make.in, README,
- Source/CMakeSetupCMD.dsp, Source/Makefile.in,
- Source/cmClassFile.cxx, Source/cmDSPMakefile.cxx,
- Source/cmDSPWriter.cxx, Source/cmDSWMakefile.cxx,
- Source/cmDSWWriter.cxx, Source/cmMakefile.cxx,
- Source/cmMakefile.h, Source/cmUnixMakefile.cxx: ENH: move from
- tools and create working CMake program
-
-2000-08-29 15:26 hoffman
-
- * CMakeMaster.make.in, CMakeRules.make.in, CMakeVariables.make.in,
- Source/CMakeBuildTargets.cxx, Source/CMakeSetup.cxx,
- Source/CMakeSetup.dsw, Source/CMakeSetupCMD.cxx,
- Source/CMakeSetupCMD.dsp, Source/EXEFooter.dsptemplate,
- Source/EXEHeader.dsptemplate, Source/Makefile.in,
- Source/cmClassFile.cxx, Source/cmClassFile.h,
- Source/cmDSPBuilder.cxx, Source/cmDSPBuilder.h,
- Source/cmDSPMakefile.cxx, Source/cmDSPMakefile.h,
- Source/cmDSPWriter.cxx, Source/cmDSPWriter.h,
- Source/cmDSWBuilder.cxx, Source/cmDSWBuilder.h,
- Source/cmDSWMakefile.cxx, Source/cmDSWMakefile.h,
- Source/cmDSWWriter.cxx, Source/cmDSWWriter.h,
- Source/cmMakeDepend.cxx, Source/cmMakeDepend.h,
- Source/cmMakefile.cxx, Source/cmMakefile.h,
- Source/cmPCBuilder.cxx, Source/cmPCBuilder.h,
- Source/cmRegularExpression.cxx, Source/cmRegularExpression.h,
- Source/cmSystemTools.cxx, Source/cmSystemTools.h,
- Source/cmUnixMakefile.cxx, Source/cmUnixMakefile.h,
- Source/cmWindowsConfigure.cxx, Source/cmWindowsConfigure.h,
- Source/itkVC60Configure.cxx, Source/itkVC60Configure.h,
- Source/staticLibFooter.dsptemplate,
- Source/staticLibHeader.dsptemplate, README: NEW: move from tools
- and config to create CMake
-
-2000-08-29 10:56 hoffman
-
- * CMakeMaster.make.in, CMakeRules.make.in, CMakeVariables.make.in,
- dummy.in: [no log message]
-
diff --git a/CompileFlags.cmake b/CompileFlags.cmake
index 20f5decf1..3c053fae0 100644
--- a/CompileFlags.cmake
+++ b/CompileFlags.cmake
@@ -16,12 +16,8 @@
if(CMAKE_GENERATOR MATCHES "Visual Studio 7")
set(CMAKE_SKIP_COMPATIBILITY_TESTS 1)
endif()
-if(CMAKE_GENERATOR MATCHES "Visual Studio 6")
- set(CMAKE_SKIP_COMPATIBILITY_TESTS 1)
-endif()
-include (${CMAKE_ROOT}/Modules/CMakeBackwardCompatibilityCXX.cmake)
-if(WIN32 AND "${CMAKE_C_COMPILER_ID}" MATCHES "^(Intel)$")
+if(WIN32 AND CMAKE_C_COMPILER_ID STREQUAL "Intel")
set(_INTEL_WINDOWS 1)
endif()
@@ -35,25 +31,55 @@ else()
endif()
#silence duplicate symbol warnings on AIX
-if(CMAKE_SYSTEM MATCHES "AIX.*")
+if(CMAKE_SYSTEM_NAME MATCHES "AIX")
if(NOT CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -bhalt:5 ")
endif()
endif()
-if(CMAKE_SYSTEM MATCHES "IRIX.*")
+if(CMAKE_SYSTEM_NAME MATCHES "IRIX")
if(NOT CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,-woff84 -no_auto_include")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-woff15")
endif()
endif()
-if(CMAKE_SYSTEM MATCHES "OSF1-V.*")
+if(CMAKE_SYSTEM MATCHES "OSF1-V")
if(NOT CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -timplicit_local -no_implicit_include ")
endif()
endif()
+if(CMAKE_SYSTEM_NAME MATCHES "HP-UX" AND CMAKE_CXX_COMPILER_ID MATCHES "HP")
+ # HP aCC since version 3.80 supports the flag +hpxstd98 to get ANSI C++98
+ # template support. It is known that version 6.25 doesn't need that flag.
+ # Versions prior to 3.80 will not be able to build CMake. Current assumption:
+ # it is needed for every version from 3.80 to 4 to get it working.
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4 AND
+ NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.80)
+ # use new C++ library and improved template support
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -AA +hpxstd98")
+ endif()
+endif()
+
+# Workaround for short jump tables on PA-RISC
+if(CMAKE_SYSTEM_PROCESSOR MATCHES "^parisc")
+ if(CMAKE_COMPILER_IS_GNUC)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mlong-calls")
+ endif()
+ if(CMAKE_COMPILER_IS_GNUCXX)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mlong-calls")
+ endif()
+endif()
+
+if (CMAKE_CXX_COMPILER_ID STREQUAL SunPro)
+ if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.13)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++03")
+ else()
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -library=stlport4")
+ endif()
+endif()
+
# use the ansi CXX compile flag for building cmake
if (CMAKE_ANSI_CXXFLAGS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_ANSI_CXXFLAGS}")
@@ -62,9 +88,3 @@ endif ()
if (CMAKE_ANSI_CFLAGS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_ANSI_CFLAGS}")
endif ()
-
-# avoid binutils problem with large binaries, e.g. when building CMake in debug mode
-# See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50230
-if (CMAKE_SYSTEM_NAME STREQUAL Linux AND CMAKE_SYSTEM_PROCESSOR STREQUAL parisc)
- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--unique=.text.*")
-endif ()
diff --git a/Copyright.txt b/Copyright.txt
index 83a2482c0..f99998fe7 100644
--- a/Copyright.txt
+++ b/Copyright.txt
@@ -1,5 +1,6 @@
CMake - Cross Platform Makefile Generator
-Copyright 2000-2011 Kitware, Inc., Insight Software Consortium
+Copyright 2000-2016 Kitware, Inc.
+Copyright 2000-2011 Insight Software Consortium
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/DartConfig.cmake b/DartConfig.cmake
index 37f66c7c1..92dffca7a 100644
--- a/DartConfig.cmake
+++ b/DartConfig.cmake
@@ -13,6 +13,6 @@ set(CTEST_PROJECT_NAME "CMake")
set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
set(CTEST_DROP_METHOD "http")
-set(CTEST_DROP_SITE "www.cdash.org")
-set(CTEST_DROP_LOCATION "/CDash/submit.php?project=CMake")
+set(CTEST_DROP_SITE "open.cdash.org")
+set(CTEST_DROP_LOCATION "/submit.php?project=CMake")
set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/DartLocal.conf.in b/DartLocal.conf.in
deleted file mode 100644
index e28cb187f..000000000
--- a/DartLocal.conf.in
+++ /dev/null
@@ -1,121 +0,0 @@
-ExpectedBuilds: \
-{andoria.kitware Linux-g++3.4-KDevelop} \
-{andoria.kitware Linux-g++3.4-SVN} \
-{DASH1.kitware Win32-nmake71} \
-{DASH1.kitware Win32-vs71} \
-{DASH1.kitware Win32-vs71Rel} \
-{DASH1.kitware zRel24-Win32-nmake71} \
-{DASH1.kitware zRel24-Win32-vs71} \
-{DASH11.kitware zRel24-Win32-nmake71} \
-{dash14.kitware Win32-bcc5.6} \
-{dash14.kitware Win32-cygwin} \
-{dash14.kitware Win32-mingw} \
-{dash14.kitware zRel24-Win32-bcc5.6} \
-{dash17.kitware Linux-g++4.0} \
-{dash1win64.kitware Win64-vs80} \
-{dash1win98.kitware Win32-vs60} \
-{DASH2.kitware Win32-nmake70} \
-{DASH2.kitware Win32-vs70} \
-{DASH2.kitware Win32-vs70-InPlace} \
-{DASH2.kitware zRel24-Win32-nmake70} \
-{DASH2.kitware zRel24-Win32-vs70} \
-{DASH3.kitware Win32-nmake60} \
-{DASH3.kitware Win32-vs60} \
-{DASH3.kitware zRel24-Win32-nmake60} \
-{DASH3.kitware zRel24-Win32-vs60} \
-{dash4.kitware Win32-bcc5.8} \
-{DASH5.kitware Linux-gcc332-InPlace} \
-{DASH5.kitware zRel24-Linix-gcc332} \
-{DASH6.kitware zRel24-Linix-gcc332} \
-{dash8.kitware Linux64-g++} \
-{dash8.kitware Linux64-g++332} \
-{dash8.kitware Linux64-g++341} \
-{dash8.kitware zRel24-Linux64-g++} \
-{dash8.kitware zRel24-Linux64-g++332} \
-{dashmacmini1.kitware Darwin-Tiger-Xcode21} \
-{dashmacmini1.kitware zRel24-Darwin-Tiger-g++} \
-{dashmacmini2.kitware DarwinIntel-g++} \
-{dashmacmini2.kitware DarwinIntel-Universal} \
-{dashmacmini2.kitware Darwin-Tiger-Xcode21-univ} \
-{dashmacmini3.kitware Darwin-LeopardIntel-g++} \
-{dashmacmini3.kitware Darwin-LeopardIntel-Universal} \
-{dashmacmini3.kitware Darwin-Leopard-Xcode21-univ} \
-{dashsgi1.kitware IRIX32-CC} \
-{dashsgi1.kitware IRIX64-CC} \
-{dashsun1.kitware SunOS-CC} \
-{dashsun1.kitware SunOS-CC-64} \
-{dashsun1.kitware SunOS-gcc34-64} \
-{destiny.kitware HP-UX-aCC} \
-{destiny.kitware HP-UX-aCC-gmake} \
-{devqnx.acfr.usyd.edu.au qnx-V3.3.5-gcc_ntox86} \
-{grayson.kitware Win32-nmake80} \
-{heart HP-UXia64-aCC} \
-{hythloth.kitware Linux64-bullseye-cov} \
-{hythloth.kitware Linux64-suncc-5.9} \
-{hythloth.kitware Linux-nightly-win32-release} \
-{insight.journal.kitware KWStyle} \
-{iris.elemtech IRIX64-CC64-7.4} \
-{iris.elemtech IRIX64-CC-7.4} \
-{JET.kitware Linux-valgrind2} \
-{krondor.kitware Darwin-c++} \
-{krondor.kitware zRel24-Darwin-c++} \
-{midworld.kitware DarwinG5-g++} \
-{midworld.kitware DarwinG5-XCode15} \
-{midworld.kitware zRel24-DarwinG5-g++} \
-{pre.vision.cs.rpi.edu FreeBSD-CC-gmake} \
-{pre.vision.cs.rpi.edu FreeBSD-CC-make} \
-{RogueResearch3 Mac10.5-CMake-gcc-dbg-ppc} \
-{RogueResearch3 Mac10.5-CMake-gcc-dbg-ppc64} \
-{RogueResearch3 Mac10.5-CMake-gcc-rel-ppc} \
-{RogueResearch3 Mac10.5-CMake-gcc-rel-ppc64} \
-{RogueResearch3 Mac10.5-CMake-Xcode-dbg-ppc} \
-{RogueResearch3 Mac10.5-CMake-Xcode-dbg-ppc64} \
-{RogueResearch4 Mac10.5-CMake-gcc-dbg-i386} \
-{RogueResearch4 Mac10.5-CMake-gcc-dbg-rosetta} \
-{RogueResearch4 Mac10.5-CMake-gcc-rel-i386} \
-{tick.rz.uni-augsburg.de LinuxPPC-g++3.3} \
-{tick.rz.uni-augsburg.de LinuxPPC-g++3.4} \
-{trinsic.kitware Win32-mingw} \
-{r06n01.pbm.ihost.com AIX53-xlC} \
-{r06n01.pbm.ihost.com zRel24-AIX53-xlC} \
-{valhalla.kitware Win32-wcl386}
-
-#{devqnx.acfr.usyd.edu.au qnx-V3.3.5-gcc_ntox86 } \
-#{mr-orange.obtech.net gentoo-linux-x86\_64-gcc-4.0.2 } \
-#{G5.Nfsnet.Org Darwin8.3-gcc4} \
-
-# commas in names do not work for expected builds....
-
-#{G4.Nfsnet.Org Darwin-c++} \
-#{salmon.nlm.nih.gov Darwin8.7-gcc4} \
-
-#{crd.ge.com Solaris-gcc343} \
-#{crd.ge.com Linux-icc81} \
-#{crd.ge.com Windows-bcc32} \
-#{crd.ge.com Windows-nmake71} \
-#{crd.ge.com Windows-nmake60} \
-
-#{dash16.kitware Linux-g++4.0} \
-#{styx Linuxia64-g++} \
-#{crd.ge.com Cygwin-gcc344} \
-#{valhalla.kitware Win32-bccRel} \
-#{valhalla.kitware Win32-bcc} \
-#{valhalla.kitware Win32-g++} \
-#{valhalla.kitware Win32-nmake60} \
-#{valhalla.kitware Win32-nmake70} \
-#{valhalla.kitware Win32-vs60} \
-#{valhalla.kitware Win32-vs70}
-#{crd.ge.com FreeBSD-gcc321} \
-#{crd.ge.com Linux-gcc320} \
-
-#{cogattaca.kitware LinuxWin32-g++-Werror} \
-#{cogattaca.kitware LinuxWin32-g++} \
-
-#{dash8.kitware Win64-icl80} \
-#{dash8.kitware zLRB-Win64-icl80} \
-
-#{hythloth.kitware Linux-icc-8.1} \
-
-CompressionMode: ALL
-CompressionCommand: /bin/gzip
-CompressionType: gzip
diff --git a/Docs/CMakeLists.txt b/Docs/CMakeLists.txt
deleted file mode 100644
index 34090d234..000000000
--- a/Docs/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-install(FILES cmake-help.vim cmake-indent.vim cmake-syntax.vim DESTINATION ${CMAKE_DATA_DIR}/editors/vim)
-install(FILES cmake-mode.el DESTINATION ${CMAKE_DATA_DIR}/editors/emacs)
-add_subdirectory (bash-completion)
diff --git a/Docs/bash-completion/cmake b/Docs/bash-completion/cmake
deleted file mode 100644
index 59e02987b..000000000
--- a/Docs/bash-completion/cmake
+++ /dev/null
@@ -1,151 +0,0 @@
-# bash completion for cmake(1) -*- shell-script -*-
-
-_cmake()
-{
- local cur prev words cword split=false
- _init_completion -n := || return
-
- # Workaround for options like -DCMAKE_BUILD_TYPE=Release
- local prefix=
- if [[ $cur == -D* ]]; then
- prev=-D
- prefix=-D
- cur="${cur#-D}"
- elif [[ $cur == -U* ]]; then
- prev=-U
- prefix=-U
- cur="${cur#-U}"
- fi
-
- case "$prev" in
- -D)
- if [[ $cur == *=* ]]; then
- # complete values for variables
- local var type value
- var="${cur%%[:=]*}"
- value="${cur#*=}"
-
- if [[ $cur == CMAKE_BUILD_TYPE* ]]; then # most widely used case
- COMPREPLY=( $( compgen -W 'Debug Release RelWithDebInfo
- MinSizeRel' -- "$value" ) )
- return
- fi
-
- if [[ $cur == *:* ]]; then
- type="${cur#*:}"
- type="${type%%=*}"
- else # get type from cache if it's not set explicitly
- type=$( cmake -LA -N 2>/dev/null | grep "$var:" \
- 2>/dev/null )
- type="${type#*:}"
- type="${type%%=*}"
- fi
- case "$type" in
- FILEPATH)
- cur="$value"
- _filedir
- return
- ;;
- PATH)
- cur="$value"
- _filedir -d
- return
- ;;
- BOOL)
- COMPREPLY=( $( compgen -W 'ON OFF TRUE FALSE' -- \
- "$value" ) )
- return
- ;;
- STRING|INTERNAL)
- # no completion available
- return
- ;;
- esac
- elif [[ $cur == *:* ]]; then
- # complete types
- local type="${cur#*:}"
- COMPREPLY=( $( compgen -W 'FILEPATH PATH STRING BOOL INTERNAL'\
- -S = -- "$type" ) )
- compopt -o nospace
- else
- # complete variable names
- COMPREPLY=( $( compgen -W '$( cmake -LA -N | tail -n +2 |
- cut -f1 -d: )' -P "$prefix" -- "$cur" ) )
- compopt -o nospace
- fi
- return
- ;;
- -U)
- COMPREPLY=( $( compgen -W '$( cmake -LA -N | tail -n +2 |
- cut -f1 -d: )' -P "$prefix" -- "$cur" ) )
- return
- ;;
- esac
-
- _split_longopt && split=true
-
- case "$prev" in
- -C|-P|--graphviz|--system-information)
- _filedir
- return
- ;;
- --build)
- _filedir -d
- return
- ;;
- -E)
- COMPREPLY=( $( compgen -W "$( cmake -E help |& sed -n \
- '/^ /{s|^ \([^ ]\{1,\}\) .*$|\1|;p}' 2>/dev/null )" \
- -- "$cur" ) )
- return
- ;;
- -G)
- local IFS=$'\n'
- local quoted
- printf -v quoted %q "$cur"
- COMPREPLY=( $( compgen -W '$( cmake --help 2>/dev/null | sed -n \
- -e "1,/^Generators/d" \
- -e "/^ *[^ =]/{s|^ *\([^=]*[^ =]\).*$|\1|;s| |\\\\ |g;p}" \
- 2>/dev/null )' -- "$quoted" ) )
- return
- ;;
- --help-command)
- COMPREPLY=( $( compgen -W '$( cmake --help-command-list 2>/dev/null|
- grep -v "^cmake version " )' -- "$cur" ) )
- return
- ;;
- --help-module)
- COMPREPLY=( $( compgen -W '$( cmake --help-module-list 2>/dev/null|
- grep -v "^cmake version " )' -- "$cur" ) )
- return
- ;;
- --help-policy)
- COMPREPLY=( $( compgen -W '$( cmake --help-policies 2>/dev/null |
- grep "^ CMP" 2>/dev/null )' -- "$cur" ) )
- return
- ;;
- --help-property)
- COMPREPLY=( $( compgen -W '$( cmake --help-property-list \
- 2>/dev/null | grep -v "^cmake version " )' -- "$cur" ) )
- return
- ;;
- --help-variable)
- COMPREPLY=( $( compgen -W '$( cmake --help-variable-list \
- 2>/dev/null | grep -v "^cmake version " )' -- "$cur" ) )
- return
- ;;
- esac
-
- $split && return
-
- if [[ "$cur" == -* ]]; then
- COMPREPLY=( $(compgen -W '$( _parse_help "$1" --help )' -- ${cur}) )
- [[ $COMPREPLY == *= ]] && compopt -o nospace
- [[ $COMPREPLY ]] && return
- fi
-
- _filedir
-} &&
-complete -F _cmake cmake
-
-# ex: ts=4 sw=4 et filetype=sh
diff --git a/Docs/bash-completion/cpack b/Docs/bash-completion/cpack
deleted file mode 100644
index 9ab604839..000000000
--- a/Docs/bash-completion/cpack
+++ /dev/null
@@ -1,61 +0,0 @@
-# bash completion for cpack(1) -*- shell-script -*-
-
-_cpack()
-{
- local cur prev words cword
- _init_completion -n = || return
-
- case "$prev" in
- -G)
- COMPREPLY=( $( compgen -W '$( cpack --help 2>/dev/null |
- sed -e "1,/^Generators/d" -e "s|^ *\([^ ]*\) .*$|\1|" \
- 2>/dev/null )' -- "$cur" ) )
- return
- ;;
- -C)
- COMPREPLY=( $( compgen -W 'Debug Release RelWithDebInfo
- MinSizeRel' -- "$cur" ) )
- return
- ;;
- -D)
- [[ $cur == *=* ]] && return # no completion for values
- COMPREPLY=( $( compgen -W '$( cpack --help-variable-list \
- 2>/dev/null | grep -v "^cpack version " )' -S = -- "$cur" ) )
- compopt -o nospace
- return
- ;;
- -P|-R|--vendor)
- # argument required but no completions available
- return
- ;;
- -B)
- _filedir -d
- return
- ;;
- --config)
- _filedir
- return
- ;;
- --help-command)
- COMPREPLY=( $( compgen -W '$( cpack --help-command-list 2>/dev/null|
- grep -v "^cpack version " )' -- "$cur" ) )
- return
- ;;
- --help-variable)
- COMPREPLY=( $( compgen -W '$( cpack --help-variable-list \
- 2>/dev/null | grep -v "^cpack version " )' -- "$cur" ) )
- return
- ;;
- esac
-
- if [[ "$cur" == -* ]]; then
- COMPREPLY=( $(compgen -W '$( _parse_help "$1" --help )' -- ${cur}) )
- [[ $COMPREPLY == *= ]] && compopt -o nospace
- [[ $COMPREPLY ]] && return
- fi
-
- _filedir
-} &&
-complete -F _cpack cpack
-
-# ex: ts=4 sw=4 et filetype=sh
diff --git a/Docs/bash-completion/ctest b/Docs/bash-completion/ctest
deleted file mode 100644
index 25cb99841..000000000
--- a/Docs/bash-completion/ctest
+++ /dev/null
@@ -1,81 +0,0 @@
-# bash completion for ctest(1) -*- shell-script -*-
-
-_ctest()
-{
- local cur prev words cword
- _init_completion -n = || return
-
- case "$prev" in
- -C|--build-config)
- COMPREPLY=( $( compgen -W 'Debug Release RelWithDebInfo
- MinSizeRel' -- "$cur" ) )
- return
- ;;
- -j|--parallel)
- COMPREPLY=( $( compgen -W "{1..$(( $(_ncpus)*2 ))}" -- "$cur" ) )
- return
- ;;
- -O|--output-log|-A|--add-notes|--extra-submit)
- _filedir
- return
- ;;
- -L|--label-regex|-LE|--label-exclude|--track|-I|--tests-information|\
- --max-width|--timeout|--stop-time)
- # argument required but no completions available
- return
- ;;
- -R|--tests-regex|-E|--exclude-regex)
- COMPREPLY=( $( compgen -W '$( ctest -N 2>/dev/null |
- grep "^ Test" 2>/dev/null | cut -d: -f 2 )' -- "$cur" ) )
- return
- ;;
- -D|--dashboard)
- if [[ $cur == @(Experimental|Nightly|Continuous)* ]]; then
- local model action
- action=${cur#@(Experimental|Nightly|Continuous)}
- model=${cur%"$action"}
- COMPREPLY=( $( compgen -W 'Start Update Configure Build Test
- Coverage Submit MemCheck' -P "$model" -- "$action" ) )
- else
- COMPREPLY=( $( compgen -W 'Experimental Nightly Continuous' \
- -- "$cur" ) )
- compopt -o nospace
- fi
- return
- ;;
- -M|--test-model)
- COMPREPLY=( $( compgen -W 'Experimental Nightly Continuous' -- \
- "$cur" ) )
- return
- ;;
- -T|--test-action)
- COMPREPLY=( $( compgen -W 'Start Update Configure Build Test
- Coverage Submit MemCheck' -- "$cur" ) )
- return
- ;;
- -S|--script|-SP|--script-new-process)
- _filedir '@(cmake|ctest)'
- return
- ;;
- --interactive-debug-mode)
- COMPREPLY=( $( compgen -W '0 1' -- "$cur" ) )
- return
- ;;
- --help-command)
- COMPREPLY=( $( compgen -W '$( ctest --help-command-list 2>/dev/null|
- grep -v "^ctest version " )' -- "$cur" ) )
- return
- ;;
- esac
-
- if [[ "$cur" == -* ]]; then
- COMPREPLY=( $(compgen -W '$( _parse_help "$1" --help )' -- ${cur}) )
- [[ $COMPREPLY == *= ]] && compopt -o nospace
- [[ $COMPREPLY ]] && return
- fi
-
- _filedir
-} &&
-complete -F _ctest ctest
-
-# ex: ts=4 sw=4 et filetype=sh
diff --git a/Docs/cmake-indent.vim b/Docs/cmake-indent.vim
deleted file mode 100644
index a26dd06a2..000000000
--- a/Docs/cmake-indent.vim
+++ /dev/null
@@ -1,93 +0,0 @@
-" =============================================================================
-"
-" Program: CMake - Cross-Platform Makefile Generator
-" Module: $RCSfile$
-" Language: VIM
-" Date: $Date$
-" Version: $Revision$
-"
-" =============================================================================
-
-" Vim indent file
-" Language: CMake (ft=cmake)
-" Author: Andy Cedilnik <andy.cedilnik@kitware.com>
-" Maintainer: Karthik Krishnan <karthik.krishnan@kitware.com>
-" Last Change: $Date$
-" Version: $Revision$
-"
-" Licence: The CMake license applies to this file. See
-" http://www.cmake.org/HTML/Copyright.html
-" This implies that distribution with Vim is allowed
-
-if exists("b:did_indent")
- finish
-endif
-let b:did_indent = 1
-
-setlocal indentexpr=CMakeGetIndent(v:lnum)
-setlocal indentkeys+==ENDIF(,ENDFOREACH(,ENDMACRO(,ELSE(,ELSEIF(,ENDWHILE(
-
-" Only define the function once.
-if exists("*CMakeGetIndent")
- finish
-endif
-
-fun! CMakeGetIndent(lnum)
- let this_line = getline(a:lnum)
-
- " Find a non-blank line above the current line.
- let lnum = a:lnum
- let lnum = prevnonblank(lnum - 1)
- let previous_line = getline(lnum)
-
- " Hit the start of the file, use zero indent.
- if lnum == 0
- return 0
- endif
-
- let ind = indent(lnum)
-
- let or = '\|'
- " Regular expressions used by line indentation function.
- let cmake_regex_comment = '#.*'
- let cmake_regex_identifier = '[A-Za-z][A-Za-z0-9_]*'
- let cmake_regex_quoted = '"\([^"\\]\|\\.\)*"'
- let cmake_regex_arguments = '\(' . cmake_regex_quoted .
- \ or . '\$(' . cmake_regex_identifier . ')' .
- \ or . '[^()\\#"]' . or . '\\.' . '\)*'
-
- let cmake_indent_comment_line = '^\s*' . cmake_regex_comment
- let cmake_indent_blank_regex = '^\s*$'
- let cmake_indent_open_regex = '^\s*' . cmake_regex_identifier .
- \ '\s*(' . cmake_regex_arguments .
- \ '\(' . cmake_regex_comment . '\)\?$'
-
- let cmake_indent_close_regex = '^' . cmake_regex_arguments .
- \ ')\s*' .
- \ '\(' . cmake_regex_comment . '\)\?$'
-
- let cmake_indent_begin_regex = '^\s*\(IF\|MACRO\|FOREACH\|ELSE\|ELSEIF\|WHILE\|FUNCTION\)\s*('
- let cmake_indent_end_regex = '^\s*\(ENDIF\|ENDFOREACH\|ENDMACRO\|ELSE\|ELSEIF\|ENDWHILE\|ENDFUNCTION\)\s*('
-
- " Add
- if previous_line =~? cmake_indent_comment_line " Handle comments
- let ind = ind
- else
- if previous_line =~? cmake_indent_begin_regex
- let ind = ind + &sw
- endif
- if previous_line =~? cmake_indent_open_regex
- let ind = ind + &sw
- endif
- endif
-
- " Subtract
- if this_line =~? cmake_indent_end_regex
- let ind = ind - &sw
- endif
- if previous_line =~? cmake_indent_close_regex
- let ind = ind - &sw
- endif
-
- return ind
-endfun
diff --git a/Docs/cmake-mode.el b/Docs/cmake-mode.el
deleted file mode 100644
index 6feed94c5..000000000
--- a/Docs/cmake-mode.el
+++ /dev/null
@@ -1,357 +0,0 @@
-;=============================================================================
-; CMake - Cross Platform Makefile Generator
-; Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-;
-; Distributed under the OSI-approved BSD License (the "License");
-; see accompanying file Copyright.txt for details.
-;
-; This software is distributed WITHOUT ANY WARRANTY; without even the
-; implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-; See the License for more information.
-;=============================================================================
-;;; cmake-mode.el --- major-mode for editing CMake sources
-
-;------------------------------------------------------------------------------
-
-;;; Commentary:
-
-;; Provides syntax highlighting and indentation for CMakeLists.txt and
-;; *.cmake source files.
-;;
-;; Add this code to your .emacs file to use the mode:
-;;
-;; (setq load-path (cons (expand-file-name "/dir/with/cmake-mode") load-path))
-;; (require 'cmake-mode)
-;; (setq auto-mode-alist
-;; (append '(("CMakeLists\\.txt\\'" . cmake-mode)
-;; ("\\.cmake\\'" . cmake-mode))
-;; auto-mode-alist))
-
-;------------------------------------------------------------------------------
-
-;;; Code:
-;;
-;; cmake executable variable used to run cmake --help-command
-;; on commands in cmake-mode
-;;
-;; cmake-command-help Written by James Bigler
-;;
-
-(defcustom cmake-mode-cmake-executable "cmake"
- "*The name of the cmake executable.
-
-This can be either absolute or looked up in $PATH. You can also
-set the path with these commands:
- (setenv \"PATH\" (concat (getenv \"PATH\") \";C:\\\\Program Files\\\\CMake 2.8\\\\bin\"))
- (setenv \"PATH\" (concat (getenv \"PATH\") \":/usr/local/cmake/bin\"))"
- :type 'file
- :group 'cmake)
-;;
-;; Regular expressions used by line indentation function.
-;;
-(defconst cmake-regex-blank "^[ \t]*$")
-(defconst cmake-regex-comment "#.*")
-(defconst cmake-regex-paren-left "(")
-(defconst cmake-regex-paren-right ")")
-(defconst cmake-regex-argument-quoted
- "\"\\([^\"\\\\]\\|\\\\\\(.\\|\n\\)\\)*\"")
-(defconst cmake-regex-argument-unquoted
- "\\([^ \t\r\n()#\"\\\\]\\|\\\\.\\)\\([^ \t\r\n()#\\\\]\\|\\\\.\\)*")
-(defconst cmake-regex-token (concat "\\(" cmake-regex-comment
- "\\|" cmake-regex-paren-left
- "\\|" cmake-regex-paren-right
- "\\|" cmake-regex-argument-unquoted
- "\\|" cmake-regex-argument-quoted
- "\\)"))
-(defconst cmake-regex-indented (concat "^\\("
- cmake-regex-token
- "\\|" "[ \t\r\n]"
- "\\)*"))
-(defconst cmake-regex-block-open
- "^\\(if\\|macro\\|foreach\\|else\\|elseif\\|while\\|function\\)$")
-(defconst cmake-regex-block-close
- "^[ \t]*\\(endif\\|endforeach\\|endmacro\\|else\\|elseif\\|endwhile\\|endfunction\\)[ \t]*(")
-
-;------------------------------------------------------------------------------
-
-;;
-;; Helper functions for line indentation function.
-;;
-(defun cmake-line-starts-inside-string ()
- "Determine whether the beginning of the current line is in a string."
- (if (save-excursion
- (beginning-of-line)
- (let ((parse-end (point)))
- (beginning-of-buffer)
- (nth 3 (parse-partial-sexp (point) parse-end))
- )
- )
- t
- nil
- )
- )
-
-(defun cmake-find-last-indented-line ()
- "Move to the beginning of the last line that has meaningful indentation."
- (let ((point-start (point))
- region)
- (forward-line -1)
- (setq region (buffer-substring-no-properties (point) point-start))
- (while (and (not (bobp))
- (or (looking-at cmake-regex-blank)
- (cmake-line-starts-inside-string)
- (not (and (string-match cmake-regex-indented region)
- (= (length region) (match-end 0))))))
- (forward-line -1)
- (setq region (buffer-substring-no-properties (point) point-start))
- )
- )
- )
-
-;------------------------------------------------------------------------------
-
-;;
-;; Line indentation function.
-;;
-(defun cmake-indent ()
- "Indent current line as CMAKE code."
- (interactive)
- (if (cmake-line-starts-inside-string)
- ()
- (if (bobp)
- (cmake-indent-line-to 0)
- (let (cur-indent)
-
- (save-excursion
- (beginning-of-line)
-
- (let ((point-start (point))
- (case-fold-search t) ;; case-insensitive
- token)
-
- ; Search back for the last indented line.
- (cmake-find-last-indented-line)
-
- ; Start with the indentation on this line.
- (setq cur-indent (current-indentation))
-
- ; Search forward counting tokens that adjust indentation.
- (while (re-search-forward cmake-regex-token point-start t)
- (setq token (match-string 0))
- (if (string-match (concat "^" cmake-regex-paren-left "$") token)
- (setq cur-indent (+ cur-indent cmake-tab-width))
- )
- (if (string-match (concat "^" cmake-regex-paren-right "$") token)
- (setq cur-indent (- cur-indent cmake-tab-width))
- )
- (if (and
- (string-match cmake-regex-block-open token)
- (looking-at (concat "[ \t]*" cmake-regex-paren-left))
- )
- (setq cur-indent (+ cur-indent cmake-tab-width))
- )
- )
- (goto-char point-start)
-
- ; If this is the end of a block, decrease indentation.
- (if (looking-at cmake-regex-block-close)
- (setq cur-indent (- cur-indent cmake-tab-width))
- )
- )
- )
-
- ; Indent this line by the amount selected.
- (if (< cur-indent 0)
- (cmake-indent-line-to 0)
- (cmake-indent-line-to cur-indent)
- )
- )
- )
- )
- )
-
-(defun cmake-point-in-indendation ()
- (string-match "^[ \\t]*$" (buffer-substring (point-at-bol) (point))))
-
-(defun cmake-indent-line-to (column)
- "Indent the current line to COLUMN.
-If point is within the existing indentation it is moved to the end of
-the indentation. Otherwise it retains the same position on the line"
- (if (cmake-point-in-indendation)
- (indent-line-to column)
- (save-excursion (indent-line-to column))))
-
-;------------------------------------------------------------------------------
-
-;;
-;; Helper functions for buffer
-;;
-(defun unscreamify-cmake-buffer ()
- "Convert all CMake commands to lowercase in buffer."
- (interactive)
- (setq save-point (point))
- (goto-char (point-min))
- (while (re-search-forward "^\\([ \t]*\\)\\(\\w+\\)\\([ \t]*(\\)" nil t)
- (replace-match
- (concat
- (match-string 1)
- (downcase (match-string 2))
- (match-string 3))
- t))
- (goto-char save-point)
- )
-
-;------------------------------------------------------------------------------
-
-;;
-;; Keyword highlighting regex-to-face map.
-;;
-(defconst cmake-font-lock-keywords
- (list '("^[ \t]*\\(\\w+\\)[ \t]*(" 1 font-lock-function-name-face))
- "Highlighting expressions for CMAKE mode."
- )
-
-;------------------------------------------------------------------------------
-
-;;
-;; Syntax table for this mode. Initialize to nil so that it is
-;; regenerated when the cmake-mode function is called.
-;;
-(defvar cmake-mode-syntax-table nil "Syntax table for cmake-mode.")
-(setq cmake-mode-syntax-table nil)
-
-;;
-;; User hook entry point.
-;;
-(defvar cmake-mode-hook nil)
-
-;;
-;; Indentation increment.
-;;
-(defvar cmake-tab-width 2)
-
-;;
-;; Keymap.
-;;
-(defvar cmake-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map "\C-ch" 'cmake-help-command)
- (define-key map "\C-cl" 'cmake-help-list-commands)
- (define-key map "\C-cu" 'unscreamify-cmake-buffer)
- map)
- "Keymap used in cmake-mode buffers.")
-
-;------------------------------------------------------------------------------
-
-;;
-;; CMake mode startup function.
-;;
-(defun cmake-mode ()
- "Major mode for editing CMake listfiles.
-
-\\{cmake-mode-map}"
- (interactive)
- (kill-all-local-variables)
- (setq major-mode 'cmake-mode)
- (setq mode-name "CMAKE")
-
- ; Create the syntax table
- (setq cmake-mode-syntax-table (make-syntax-table))
- (set-syntax-table cmake-mode-syntax-table)
- (modify-syntax-entry ?_ "w" cmake-mode-syntax-table)
- (modify-syntax-entry ?\( "()" cmake-mode-syntax-table)
- (modify-syntax-entry ?\) ")(" cmake-mode-syntax-table)
- (modify-syntax-entry ?# "<" cmake-mode-syntax-table)
- (modify-syntax-entry ?\n ">" cmake-mode-syntax-table)
-
- ; Setup font-lock mode.
- (make-local-variable 'font-lock-defaults)
- (setq font-lock-defaults '(cmake-font-lock-keywords))
-
- ; Setup indentation function.
- (make-local-variable 'indent-line-function)
- (setq indent-line-function 'cmake-indent)
-
- ; Setup comment syntax.
- (make-local-variable 'comment-start)
- (setq comment-start "#")
-
- ; Setup keymap.
- (use-local-map cmake-mode-map)
-
- ; Run user hooks.
- (run-hooks 'cmake-mode-hook))
-
-; Help mode starts here
-
-
-(defun cmake-command-run (type &optional topic)
- "Runs the command cmake with the arguments specified. The
-optional argument topic will be appended to the argument list."
- (interactive "s")
- (let* ((bufname (concat "*CMake" type (if topic "-") topic "*"))
- (buffer (get-buffer bufname))
- )
- (if buffer
- (display-buffer buffer 'not-this-window)
- ;; Buffer doesn't exist. Create it and fill it
- (setq buffer (generate-new-buffer bufname))
- (setq command (concat cmake-mode-cmake-executable " " type " " topic))
- (message "Running %s" command)
- ;; We don't want the contents of the shell-command running to the
- ;; minibuffer, so turn it off. A value of nil means don't automatically
- ;; resize mini-windows.
- (setq resize-mini-windows-save resize-mini-windows)
- (setq resize-mini-windows nil)
- (shell-command command buffer)
- ;; Save the original window, so that we can come back to it later.
- ;; save-excursion doesn't seem to work for this.
- (setq window (selected-window))
- ;; We need to select it so that we can apply special modes to it
- (select-window (display-buffer buffer 'not-this-window))
- (cmake-mode)
- (toggle-read-only t)
- ;; Restore the original window
- (select-window window)
- (setq resize-mini-windows resize-mini-windows-save)
- )
- )
- )
-
-(defun cmake-help-list-commands ()
- "Prints out a list of the cmake commands."
- (interactive)
- (cmake-command-run "--help-command-list")
- )
-
-(defvar cmake-help-command-history nil "Topic read history.")
-
-(require 'thingatpt)
-(defun cmake-get-topic (type)
- "Gets the topic from the minibuffer input. The default is the word the cursor is on."
- (interactive)
- (let* ((default-entry (word-at-point))
- (input (read-string
- (format "CMake %s (default %s): " type default-entry) ; prompt
- nil ; initial input
- 'cmake-help-command-history ; command history
- default-entry ; default-value
- )))
- (if (string= input "")
- (error "No argument given")
- input))
- )
-
-
-(defun cmake-help-command ()
- "Prints out the help message corresponding to the command the cursor is on."
- (interactive)
- (setq command (cmake-get-topic "command"))
- (cmake-command-run "--help-command" (downcase command))
- )
-
-
-; This file provides cmake-mode.
-(provide 'cmake-mode)
-
-;;; cmake-mode.el ends here
diff --git a/Docs/cmake-syntax.vim b/Docs/cmake-syntax.vim
deleted file mode 100644
index 80395ab1a..000000000
--- a/Docs/cmake-syntax.vim
+++ /dev/null
@@ -1,89 +0,0 @@
-" =============================================================================
-"
-" Program: CMake - Cross-Platform Makefile Generator
-" Module: $RCSfile$
-" Language: VIM
-" Date: $Date$
-" Version: $Revision$
-"
-" =============================================================================
-
-" Vim syntax file
-" Language: CMake
-" Author: Andy Cedilnik <andy.cedilnik@kitware.com>
-" Maintainer: Karthik Krishnan <karthik.krishnan@kitware.com>
-" Last Change: $Date$
-" Version: $Revision$
-"
-" Licence: The CMake license applies to this file. See
-" http://www.cmake.org/HTML/Copyright.html
-" This implies that distribution with Vim is allowed
-
-" For version 5.x: Clear all syntax items
-" For version 6.x: Quit when a syntax file was already loaded
-if version < 600
- syntax clear
-elseif exists("b:current_syntax")
- finish
-endif
-
-syn case ignore
-syn match cmakeEscaped /\(\\\\\|\\"\|\\n\|\\t\)/ contained
-syn region cmakeComment start="#" end="$" contains=cmakeTodo
-syn region cmakeRegistry start=/\[/ end=/]/
- \ contained oneline contains=CONTAINED,cmakeTodo,cmakeEscaped
-syn region cmakeVariableValue start=/\${/ end=/}/
- \ contained oneline contains=CONTAINED,cmakeTodo
-syn region cmakeEnvironment start=/\$ENV{/ end=/}/
- \ contained oneline contains=CONTAINED,cmakeTodo
-syn region cmakeString start=/"/ end=/"/
- \ contains=CONTAINED,cmakeTodo,cmakeOperators
-syn region cmakeArguments start=/(/ end=/)/
- \ contains=ALLBUT,cmakeArguments,cmakeTodo
-syn keyword cmakeSystemVariables
- \ WIN32 UNIX APPLE CYGWIN BORLAND MINGW MSVC MSVC_IDE MSVC60 MSVC70 MSVC71 MSVC80 MSVC90
-syn keyword cmakeOperators
- \ ABSOLUTE AND BOOL CACHE COMMAND DEFINED DOC EQUAL EXISTS EXT FALSE GREATER INTERNAL LESS MATCHES NAME NAMES NAME_WE NOT OFF ON OR PATH PATHS PROGRAM STREQUAL STRGREATER STRING STRLESS TRUE
- \ contained
-syn keyword cmakeDeprecated ABSTRACT_FILES BUILD_NAME SOURCE_FILES SOURCE_FILES_REMOVE VTK_MAKE_INSTANTIATOR VTK_WRAP_JAVA VTK_WRAP_PYTHON VTK_WRAP_TCL WRAP_EXCLUDE_FILES
- \ nextgroup=cmakeArguments
-
-" The keywords are generated as: cmake --help-command-list | tr "\n" " "
-syn keyword cmakeStatement
- \ ADD_CUSTOM_COMMAND ADD_CUSTOM_TARGET ADD_DEFINITIONS ADD_DEPENDENCIES ADD_EXECUTABLE ADD_LIBRARY ADD_SUBDIRECTORY ADD_TEST AUX_SOURCE_DIRECTORY BUILD_COMMAND BUILD_NAME CMAKE_MINIMUM_REQUIRED CONFIGURE_FILE CREATE_TEST_SOURCELIST ELSE ELSEIF ENABLE_LANGUAGE ENABLE_TESTING ENDFOREACH ENDFUNCTION ENDIF ENDMACRO ENDWHILE EXEC_PROGRAM EXECUTE_PROCESS EXPORT_LIBRARY_DEPENDENCIES FILE FIND_FILE FIND_LIBRARY FIND_PACKAGE FIND_PATH FIND_PROGRAM FLTK_WRAP_UI FOREACH FUNCTION GET_CMAKE_PROPERTY GET_DIRECTORY_PROPERTY GET_FILENAME_COMPONENT GET_SOURCE_FILE_PROPERTY GET_TARGET_PROPERTY GET_TEST_PROPERTY IF INCLUDE INCLUDE_DIRECTORIES INCLUDE_EXTERNAL_MSPROJECT INCLUDE_REGULAR_EXPRESSION INSTALL INSTALL_FILES INSTALL_PROGRAMS INSTALL_TARGETS LINK_DIRECTORIES LINK_LIBRARIES LIST LOAD_CACHE LOAD_COMMAND MACRO MAKE_DIRECTORY MARK_AS_ADVANCED MATH MESSAGE OPTION OUTPUT_REQUIRED_FILES PROJECT QT_WRAP_CPP QT_WRAP_UI REMOVE REMOVE_DEFINITIONS SEPARATE_ARGUMENTS SET SET_DIRECTORY_PROPERTIES SET_SOURCE_FILES_PROPERTIES SET_TARGET_PROPERTIES SET_TESTS_PROPERTIES SITE_NAME SOURCE_GROUP STRING SUBDIR_DEPENDS SUBDIRS TARGET_LINK_LIBRARIES TRY_COMPILE TRY_RUN UNSET USE_MANGLED_MESA UTILITY_SOURCE VARIABLE_REQUIRES VTK_MAKE_INSTANTIATOR VTK_WRAP_JAVA VTK_WRAP_PYTHON VTK_WRAP_TCL WHILE WRITE_FILE
- \ nextgroup=cmakeArguments
-syn keyword cmakeTodo
- \ TODO FIXME XXX
- \ contained
-
-" Define the default highlighting.
-" For version 5.7 and earlier: only when not done already
-" For version 5.8 and later: only when an item doesn't have highlighting yet
-if version >= 508 || !exists("did_cmake_syntax_inits")
- if version < 508
- let did_cmake_syntax_inits = 1
- command -nargs=+ HiLink hi link <args>
- else
- command -nargs=+ HiLink hi def link <args>
- endif
-
- HiLink cmakeStatement Statement
- HiLink cmakeComment Comment
- HiLink cmakeString String
- HiLink cmakeVariableValue Type
- HiLink cmakeRegistry Underlined
- HiLink cmakeArguments Identifier
- HiLink cmakeArgument Constant
- HiLink cmakeEnvironment Special
- HiLink cmakeOperators Operator
- HiLink cmakeMacro PreProc
- HiLink cmakeError Error
- HiLink cmakeTodo TODO
- HiLink cmakeEscaped Special
-
- delcommand HiLink
-endif
-
-let b:current_syntax = "cmake"
-
-"EOF"
diff --git a/Example/CMakeLists.txt b/Example/CMakeLists.txt
deleted file mode 100644
index 8ee7d721e..000000000
--- a/Example/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-# The name of our project is "HELLO". CMakeLists files in this project can
-# refer to the root source directory of the project as ${HELLO_SOURCE_DIR} and
-# to the root binary directory of the project as ${HELLO_BINARY_DIR}.
-project (HELLO)
-
-# Recurse into the "Hello" and "Demo" subdirectories. This does not actually
-# cause another cmake executable to run. The same process will walk through
-# the project's entire directory structure.
-add_subdirectory (Hello)
-add_subdirectory (Demo)
diff --git a/Example/Demo/CMakeLists.txt b/Example/Demo/CMakeLists.txt
deleted file mode 100644
index 477700fab..000000000
--- a/Example/Demo/CMakeLists.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-# Make sure the compiler can find include files from our Hello library.
-include_directories (${HELLO_SOURCE_DIR}/Hello)
-
-# Make sure the linker can find the Hello library once it is built.
-link_directories (${HELLO_BINARY_DIR}/Hello)
-
-# Add executable called "helloDemo" that is built from the source files
-# "demo.cxx" and "demo_b.cxx". The extensions are automatically found.
-add_executable (helloDemo demo.cxx demo_b.cxx)
-
-# Link the executable to the Hello library.
-target_link_libraries (helloDemo Hello)
diff --git a/Example/Demo/demo.cxx b/Example/Demo/demo.cxx
deleted file mode 100644
index 815c8149e..000000000
--- a/Example/Demo/demo.cxx
+++ /dev/null
@@ -1,10 +0,0 @@
-#include "hello.h"
-
-extern Hello hello;
-
-int main()
-{
- hello.Print();
-
- return 0;
-}
diff --git a/Example/Demo/demo_b.cxx b/Example/Demo/demo_b.cxx
deleted file mode 100644
index 08a232913..000000000
--- a/Example/Demo/demo_b.cxx
+++ /dev/null
@@ -1,3 +0,0 @@
-#include "hello.h"
-
-Hello hello;
diff --git a/Example/Hello/CMakeLists.txt b/Example/Hello/CMakeLists.txt
deleted file mode 100644
index 879f4e5b1..000000000
--- a/Example/Hello/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-# Create a library called "Hello" which includes the source file "hello.cxx".
-# The extension is already found. Any number of sources could be listed here.
-add_library (Hello hello.cxx)
diff --git a/Example/Hello/hello.cxx b/Example/Hello/hello.cxx
deleted file mode 100644
index 7107cc555..000000000
--- a/Example/Hello/hello.cxx
+++ /dev/null
@@ -1,7 +0,0 @@
-#include "hello.h"
-#include <stdio.h>
-
-void Hello::Print()
-{
- printf("Hello, World!\n");
-}
diff --git a/Example/Hello/hello.h b/Example/Hello/hello.h
deleted file mode 100644
index b17d68343..000000000
--- a/Example/Hello/hello.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef _hello_h
-#define _hello_h
-
-
-class Hello
-{
-public:
- void Print();
-};
-
-#endif
diff --git a/Help/command/FIND_XXX.txt b/Help/command/FIND_XXX.txt
new file mode 100644
index 000000000..bd4d2959d
--- /dev/null
+++ b/Help/command/FIND_XXX.txt
@@ -0,0 +1,119 @@
+A short-hand signature is:
+
+.. parsed-literal::
+
+ |FIND_XXX| (<VAR> name1 [path1 path2 ...])
+
+The general signature is:
+
+.. parsed-literal::
+
+ |FIND_XXX| (
+ <VAR>
+ name | |NAMES|
+ [HINTS path1 [path2 ... ENV var]]
+ [PATHS path1 [path2 ... ENV var]]
+ [PATH_SUFFIXES suffix1 [suffix2 ...]]
+ [DOC "cache documentation string"]
+ [NO_DEFAULT_PATH]
+ [NO_CMAKE_ENVIRONMENT_PATH]
+ [NO_CMAKE_PATH]
+ [NO_SYSTEM_ENVIRONMENT_PATH]
+ [NO_CMAKE_SYSTEM_PATH]
+ [CMAKE_FIND_ROOT_PATH_BOTH |
+ ONLY_CMAKE_FIND_ROOT_PATH |
+ NO_CMAKE_FIND_ROOT_PATH]
+ )
+
+This command is used to find a |SEARCH_XXX_DESC|.
+A cache entry named by ``<VAR>`` is created to store the result
+of this command.
+If the |SEARCH_XXX| is found the result is stored in the variable
+and the search will not be repeated unless the variable is cleared.
+If nothing is found, the result will be
+``<VAR>-NOTFOUND``, and the search will be attempted again the
+next time |FIND_XXX| is invoked with the same variable.
+
+Options include:
+
+``NAMES``
+ Specify one or more possible names for the |SEARCH_XXX|.
+
+ When using this to specify names with and without a version
+ suffix, we recommend specifying the unversioned name first
+ so that locally-built packages can be found before those
+ provided by distributions.
+
+``HINTS``, ``PATHS``
+ Specify directories to search in addition to the default locations.
+ The ``ENV var`` sub-option reads paths from a system environment
+ variable.
+
+``PATH_SUFFIXES``
+ Specify additional subdirectories to check below each directory
+ location otherwise considered.
+
+``DOC``
+ Specify the documentation string for the ``<VAR>`` cache entry.
+
+If ``NO_DEFAULT_PATH`` is specified, then no additional paths are
+added to the search.
+If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows:
+
+.. |CMAKE_PREFIX_PATH_XXX_SUBDIR| replace::
+ |prefix_XXX_SUBDIR| for each ``<prefix>`` in :variable:`CMAKE_PREFIX_PATH`
+
+.. |SYSTEM_ENVIRONMENT_PREFIX_PATH_XXX_SUBDIR| replace::
+ |prefix_XXX_SUBDIR| for each ``<prefix>/[s]bin`` in ``PATH``, and
+ |entry_XXX_SUBDIR| for other entries in ``PATH``
+
+.. |CMAKE_SYSTEM_PREFIX_PATH_XXX_SUBDIR| replace::
+ |prefix_XXX_SUBDIR| for each ``<prefix>`` in
+ :variable:`CMAKE_SYSTEM_PREFIX_PATH`
+
+1. Search paths specified in cmake-specific cache variables.
+ These are intended to be used on the command line with a ``-DVAR=value``.
+ This can be skipped if ``NO_CMAKE_PATH`` is passed.
+
+ * |CMAKE_PREFIX_PATH_XXX|
+ * |CMAKE_XXX_PATH|
+ * |CMAKE_XXX_MAC_PATH|
+
+2. Search paths specified in cmake-specific environment variables.
+ These are intended to be set in the user's shell configuration.
+ This can be skipped if ``NO_CMAKE_ENVIRONMENT_PATH`` is passed.
+
+ * |CMAKE_PREFIX_PATH_XXX|
+ * |CMAKE_XXX_PATH|
+ * |CMAKE_XXX_MAC_PATH|
+
+3. Search the paths specified by the ``HINTS`` option.
+ These should be paths computed by system introspection, such as a
+ hint provided by the location of another item already found.
+ Hard-coded guesses should be specified with the ``PATHS`` option.
+
+4. Search the standard system environment variables.
+ This can be skipped if ``NO_SYSTEM_ENVIRONMENT_PATH`` is an argument.
+
+ * |SYSTEM_ENVIRONMENT_PATH_XXX|
+
+5. Search cmake variables defined in the Platform files
+ for the current system. This can be skipped if ``NO_CMAKE_SYSTEM_PATH``
+ is passed.
+
+ * |CMAKE_SYSTEM_PREFIX_PATH_XXX|
+ * |CMAKE_SYSTEM_XXX_PATH|
+ * |CMAKE_SYSTEM_XXX_MAC_PATH|
+
+6. Search the paths specified by the PATHS option
+ or in the short-hand version of the command.
+ These are typically hard-coded guesses.
+
+.. |FIND_ARGS_XXX| replace:: <VAR> NAMES name
+
+On OS X the :variable:`CMAKE_FIND_FRAMEWORK` and
+:variable:`CMAKE_FIND_APPBUNDLE` variables determine the order of
+preference between Apple-style and unix-style package components.
+
+.. include:: FIND_XXX_ROOT.txt
+.. include:: FIND_XXX_ORDER.txt
diff --git a/Help/command/FIND_XXX_ORDER.txt b/Help/command/FIND_XXX_ORDER.txt
new file mode 100644
index 000000000..bac241964
--- /dev/null
+++ b/Help/command/FIND_XXX_ORDER.txt
@@ -0,0 +1,12 @@
+The default search order is designed to be most-specific to
+least-specific for common use cases.
+Projects may override the order by simply calling the command
+multiple times and using the ``NO_*`` options:
+
+.. parsed-literal::
+
+ |FIND_XXX| (|FIND_ARGS_XXX| PATHS paths... NO_DEFAULT_PATH)
+ |FIND_XXX| (|FIND_ARGS_XXX|)
+
+Once one of the calls succeeds the result variable will be set
+and stored in the cache so that no call will search again.
diff --git a/Help/command/FIND_XXX_ROOT.txt b/Help/command/FIND_XXX_ROOT.txt
new file mode 100644
index 000000000..fab23037c
--- /dev/null
+++ b/Help/command/FIND_XXX_ROOT.txt
@@ -0,0 +1,29 @@
+The CMake variable :variable:`CMAKE_FIND_ROOT_PATH` specifies one or more
+directories to be prepended to all other search directories. This
+effectively "re-roots" the entire search under given locations.
+Paths which are descendants of the :variable:`CMAKE_STAGING_PREFIX` are excluded
+from this re-rooting, because that variable is always a path on the host system.
+By default the :variable:`CMAKE_FIND_ROOT_PATH` is empty.
+
+The :variable:`CMAKE_SYSROOT` variable can also be used to specify exactly one
+directory to use as a prefix. Setting :variable:`CMAKE_SYSROOT` also has other
+effects. See the documentation for that variable for more.
+
+These variables are especially useful when cross-compiling to
+point to the root directory of the target environment and CMake will
+search there too. By default at first the directories listed in
+:variable:`CMAKE_FIND_ROOT_PATH` are searched, then the :variable:`CMAKE_SYSROOT`
+directory is searched, and then the non-rooted directories will be
+searched. The default behavior can be adjusted by setting
+|CMAKE_FIND_ROOT_PATH_MODE_XXX|. This behavior can be manually
+overridden on a per-call basis using options:
+
+``CMAKE_FIND_ROOT_PATH_BOTH``
+ Search in the order described above.
+
+``NO_CMAKE_FIND_ROOT_PATH``
+ Do not use the :variable:`CMAKE_FIND_ROOT_PATH` variable.
+
+``ONLY_CMAKE_FIND_ROOT_PATH``
+ Search only the re-rooted directories and directories below
+ :variable:`CMAKE_STAGING_PREFIX`.
diff --git a/Help/command/add_compile_options.rst b/Help/command/add_compile_options.rst
new file mode 100644
index 000000000..3fe2a3330
--- /dev/null
+++ b/Help/command/add_compile_options.rst
@@ -0,0 +1,23 @@
+add_compile_options
+-------------------
+
+Adds options to the compilation of source files.
+
+::
+
+ add_compile_options(<option> ...)
+
+Adds options to the compiler command line for targets in the current
+directory and below that are added after this command is invoked.
+See documentation of the :prop_dir:`directory <COMPILE_OPTIONS>` and
+:prop_tgt:`target <COMPILE_OPTIONS>` ``COMPILE_OPTIONS`` properties.
+
+This command can be used to add any options, but alternative commands
+exist to add preprocessor definitions (:command:`target_compile_definitions`
+and :command:`add_definitions`) or include directories
+(:command:`target_include_directories` and :command:`include_directories`).
+
+Arguments to ``add_compile_options`` may use "generator expressions" with
+the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions. See the :manual:`cmake-buildsystem(7)`
+manual for more on defining buildsystem properties.
diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst
new file mode 100644
index 000000000..8726b709e
--- /dev/null
+++ b/Help/command/add_custom_command.rst
@@ -0,0 +1,208 @@
+add_custom_command
+------------------
+
+Add a custom build rule to the generated build system.
+
+There are two main signatures for ``add_custom_command``.
+
+Generating Files
+^^^^^^^^^^^^^^^^
+
+The first signature is for adding a custom command to produce an output::
+
+ add_custom_command(OUTPUT output1 [output2 ...]
+ COMMAND command1 [ARGS] [args1...]
+ [COMMAND command2 [ARGS] [args2...] ...]
+ [MAIN_DEPENDENCY depend]
+ [DEPENDS [depends...]]
+ [BYPRODUCTS [files...]]
+ [IMPLICIT_DEPENDS <lang1> depend1
+ [<lang2> depend2] ...]
+ [WORKING_DIRECTORY dir]
+ [COMMENT comment]
+ [VERBATIM] [APPEND] [USES_TERMINAL])
+
+This defines a command to generate specified ``OUTPUT`` file(s).
+A target created in the same directory (``CMakeLists.txt`` file)
+that specifies any output of the custom command as a source file
+is given a rule to generate the file using the command at build time.
+Do not list the output in more than one independent target that
+may build in parallel or the two instances of the rule may conflict
+(instead use the :command:`add_custom_target` command to drive the
+command and make the other targets depend on that one).
+In makefile terms this creates a new target in the following form::
+
+ OUTPUT: MAIN_DEPENDENCY DEPENDS
+ COMMAND
+
+The options are:
+
+``APPEND``
+ Append the ``COMMAND`` and ``DEPENDS`` option values to the custom
+ command for the first output specified. There must have already
+ been a previous call to this command with the same output.
+ The ``COMMENT``, ``MAIN_DEPENDENCY``, and ``WORKING_DIRECTORY``
+ options are currently ignored when APPEND is given, but may be
+ used in the future.
+
+``BYPRODUCTS``
+ Specify the files the command is expected to produce but whose
+ modification time may or may not be newer than the dependencies.
+ If a byproduct name is a relative path it will be interpreted
+ relative to the build tree directory corresponding to the
+ current source directory.
+ Each byproduct file will be marked with the :prop_sf:`GENERATED`
+ source file property automatically.
+
+ Explicit specification of byproducts is supported by the
+ :generator:`Ninja` generator to tell the ``ninja`` build tool
+ how to regenerate byproducts when they are missing. It is
+ also useful when other build rules (e.g. custom commands)
+ depend on the byproducts. Ninja requires a build rule for any
+ generated file on which another rule depends even if there are
+ order-only dependencies to ensure the byproducts will be
+ available before their dependents build.
+
+ The ``BYPRODUCTS`` option is ignored on non-Ninja generators
+ except to mark byproducts ``GENERATED``.
+
+``COMMAND``
+ Specify the command-line(s) to execute at build time.
+ If more than one ``COMMAND`` is specified they will be executed in order,
+ but *not* necessarily composed into a stateful shell or batch script.
+ (To run a full script, use the :command:`configure_file` command or the
+ :command:`file(GENERATE)` command to create it, and then specify
+ a ``COMMAND`` to launch it.)
+ The optional ``ARGS`` argument is for backward compatibility and
+ will be ignored.
+
+ If ``COMMAND`` specifies an executable target (created by the
+ :command:`add_executable` command) it will automatically be replaced
+ by the location of the executable created at build time.
+ (Use the ``TARGET_FILE``
+ :manual:`generator expression <cmake-generator-expressions(7)>` to
+ reference an executable later in the command line.)
+ Additionally a target-level dependency will be added so that the
+ executable target will be built before any target using this custom
+ command. However this does NOT add a file-level dependency that
+ would cause the custom command to re-run whenever the executable is
+ recompiled.
+
+ Arguments to ``COMMAND`` may use
+ :manual:`generator expressions <cmake-generator-expressions(7)>`.
+ References to target names in generator expressions imply target-level
+ dependencies, but NOT file-level dependencies. List target names with
+ the ``DEPENDS`` option to add file-level dependencies.
+
+``COMMENT``
+ Display the given message before the commands are executed at
+ build time.
+
+``DEPENDS``
+ Specify files on which the command depends. If any dependency is
+ an ``OUTPUT`` of another custom command in the same directory
+ (``CMakeLists.txt`` file) CMake automatically brings the other
+ custom command into the target in which this command is built.
+ If ``DEPENDS`` is not specified the command will run whenever
+ the ``OUTPUT`` is missing; if the command does not actually
+ create the ``OUTPUT`` then the rule will always run.
+ If ``DEPENDS`` specifies any target (created by the
+ :command:`add_custom_target`, :command:`add_executable`, or
+ :command:`add_library` command) a target-level dependency is
+ created to make sure the target is built before any target
+ using this custom command. Additionally, if the target is an
+ executable or library a file-level dependency is created to
+ cause the custom command to re-run whenever the target is
+ recompiled.
+
+ Arguments to ``DEPENDS`` may use
+ :manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+``IMPLICIT_DEPENDS``
+ Request scanning of implicit dependencies of an input file.
+ The language given specifies the programming language whose
+ corresponding dependency scanner should be used.
+ Currently only ``C`` and ``CXX`` language scanners are supported.
+ The language has to be specified for every file in the
+ ``IMPLICIT_DEPENDS`` list. Dependencies discovered from the
+ scanning are added to those of the custom command at build time.
+ Note that the ``IMPLICIT_DEPENDS`` option is currently supported
+ only for Makefile generators and will be ignored by other generators.
+
+``MAIN_DEPENDENCY``
+ Specify the primary input source file to the command. This is
+ treated just like any value given to the ``DEPENDS`` option
+ but also suggests to Visual Studio generators where to hang
+ the custom command. At most one custom command may specify a
+ given source file as its main dependency.
+
+``OUTPUT``
+ Specify the output files the command is expected to produce.
+ If an output name is a relative path it will be interpreted
+ relative to the build tree directory corresponding to the
+ current source directory.
+ Each output file will be marked with the :prop_sf:`GENERATED`
+ source file property automatically.
+ If the output of the custom command is not actually created
+ as a file on disk it should be marked with the :prop_sf:`SYMBOLIC`
+ source file property.
+
+``USES_TERMINAL``
+ The command will be given direct access to the terminal if possible.
+ With the :generator:`Ninja` generator, this places the command in
+ the ``console`` :prop_gbl:`pool <JOB_POOLS>`.
+
+``VERBATIM``
+ All arguments to the commands will be escaped properly for the
+ build tool so that the invoked command receives each argument
+ unchanged. Note that one level of escapes is still used by the
+ CMake language processor before add_custom_command even sees the
+ arguments. Use of ``VERBATIM`` is recommended as it enables
+ correct behavior. When ``VERBATIM`` is not given the behavior
+ is platform specific because there is no protection of
+ tool-specific special characters.
+
+``WORKING_DIRECTORY``
+ Execute the command with the given current working directory.
+ If it is a relative path it will be interpreted relative to the
+ build tree directory corresponding to the current source directory.
+
+Build Events
+^^^^^^^^^^^^
+
+The second signature adds a custom command to a target such as a
+library or executable. This is useful for performing an operation
+before or after building the target. The command becomes part of the
+target and will only execute when the target itself is built. If the
+target is already built, the command will not execute.
+
+::
+
+ add_custom_command(TARGET <target>
+ PRE_BUILD | PRE_LINK | POST_BUILD
+ COMMAND command1 [ARGS] [args1...]
+ [COMMAND command2 [ARGS] [args2...] ...]
+ [BYPRODUCTS [files...]]
+ [WORKING_DIRECTORY dir]
+ [COMMENT comment]
+ [VERBATIM] [USES_TERMINAL])
+
+This defines a new command that will be associated with building the
+specified ``<target>``. The ``<target>`` must be defined in the current
+directory; targets defined in other directories may not be specified.
+
+When the command will happen is determined by which
+of the following is specified:
+
+``PRE_BUILD``
+ Run before any other rules are executed within the target.
+ This is supported only on Visual Studio 7 or later.
+ For all other generators ``PRE_BUILD`` will be treated as
+ ``PRE_LINK``.
+``PRE_LINK``
+ Run after sources have been compiled but before linking the binary
+ or running the librarian or archiver tool of a static library.
+ This is not defined for targets created by the
+ :command:`add_custom_target` command.
+``POST_BUILD``
+ Run after all other rules within the target have been executed.
diff --git a/Help/command/add_custom_target.rst b/Help/command/add_custom_target.rst
new file mode 100644
index 000000000..82d69db9f
--- /dev/null
+++ b/Help/command/add_custom_target.rst
@@ -0,0 +1,111 @@
+add_custom_target
+-----------------
+
+Add a target with no output so it will always be built.
+
+::
+
+ add_custom_target(Name [ALL] [command1 [args1...]]
+ [COMMAND command2 [args2...] ...]
+ [DEPENDS depend depend depend ... ]
+ [BYPRODUCTS [files...]]
+ [WORKING_DIRECTORY dir]
+ [COMMENT comment]
+ [VERBATIM] [USES_TERMINAL]
+ [SOURCES src1 [src2...]])
+
+Adds a target with the given name that executes the given commands.
+The target has no output file and is *always considered out of date*
+even if the commands try to create a file with the name of the target.
+Use the :command:`add_custom_command` command to generate a file with
+dependencies. By default nothing depends on the custom target. Use
+the :command:`add_dependencies` command to add dependencies to or
+from other targets.
+
+The options are:
+
+``ALL``
+ Indicate that this target should be added to the default build
+ target so that it will be run every time (the command cannot be
+ called ``ALL``).
+
+``BYPRODUCTS``
+ Specify the files the command is expected to produce but whose
+ modification time may or may not be updated on subsequent builds.
+ If a byproduct name is a relative path it will be interpreted
+ relative to the build tree directory corresponding to the
+ current source directory.
+ Each byproduct file will be marked with the :prop_sf:`GENERATED`
+ source file property automatically.
+
+ Explicit specification of byproducts is supported by the
+ :generator:`Ninja` generator to tell the ``ninja`` build tool
+ how to regenerate byproducts when they are missing. It is
+ also useful when other build rules (e.g. custom commands)
+ depend on the byproducts. Ninja requires a build rule for any
+ generated file on which another rule depends even if there are
+ order-only dependencies to ensure the byproducts will be
+ available before their dependents build.
+
+ The ``BYPRODUCTS`` option is ignored on non-Ninja generators
+ except to mark byproducts ``GENERATED``.
+
+``COMMAND``
+ Specify the command-line(s) to execute at build time.
+ If more than one ``COMMAND`` is specified they will be executed in order,
+ but *not* necessarily composed into a stateful shell or batch script.
+ (To run a full script, use the :command:`configure_file` command or the
+ :command:`file(GENERATE)` command to create it, and then specify
+ a ``COMMAND`` to launch it.)
+
+ If ``COMMAND`` specifies an executable target (created by the
+ :command:`add_executable` command) it will automatically be replaced
+ by the location of the executable created at build time.
+ Additionally a target-level dependency will be added so that the
+ executable target will be built before this custom target.
+
+ Arguments to ``COMMAND`` may use
+ :manual:`generator expressions <cmake-generator-expressions(7)>`.
+ References to target names in generator expressions imply target-level
+ dependencies.
+
+ The command and arguments are optional and if not specified an empty
+ target will be created.
+
+``COMMENT``
+ Display the given message before the commands are executed at
+ build time.
+
+``DEPENDS``
+ Reference files and outputs of custom commands created with
+ :command:`add_custom_command` command calls in the same directory
+ (``CMakeLists.txt`` file). They will be brought up to date when
+ the target is built.
+
+ Use the :command:`add_dependencies` command to add dependencies
+ on other targets.
+
+``SOURCES``
+ Specify additional source files to be included in the custom target.
+ Specified source files will be added to IDE project files for
+ convenience in editing even if they have no build rules.
+
+``VERBATIM``
+ All arguments to the commands will be escaped properly for the
+ build tool so that the invoked command receives each argument
+ unchanged. Note that one level of escapes is still used by the
+ CMake language processor before ``add_custom_target`` even sees
+ the arguments. Use of ``VERBATIM`` is recommended as it enables
+ correct behavior. When ``VERBATIM`` is not given the behavior
+ is platform specific because there is no protection of
+ tool-specific special characters.
+
+``USES_TERMINAL``
+ The command will be given direct access to the terminal if possible.
+ With the :generator:`Ninja` generator, this places the command in
+ the ``console`` :prop_gbl:`pool <JOB_POOLS>`.
+
+``WORKING_DIRECTORY``
+ Execute the command with the given current working directory.
+ If it is a relative path it will be interpreted relative to the
+ build tree directory corresponding to the current source directory.
diff --git a/Help/command/add_definitions.rst b/Help/command/add_definitions.rst
new file mode 100644
index 000000000..a04faf591
--- /dev/null
+++ b/Help/command/add_definitions.rst
@@ -0,0 +1,27 @@
+add_definitions
+---------------
+
+Adds -D define flags to the compilation of source files.
+
+::
+
+ add_definitions(-DFOO -DBAR ...)
+
+Adds definitions to the compiler command line for targets in the current
+directory and below (whether added before or after this command is invoked).
+This command can be used to add any flags, but it is intended to add
+preprocessor definitions (see the :command:`add_compile_options` command
+to add other flags).
+Flags beginning in -D or /D that look like preprocessor definitions are
+automatically added to the :prop_dir:`COMPILE_DEFINITIONS` directory
+property for the current directory. Definitions with non-trivial values
+may be left in the set of flags instead of being converted for reasons of
+backwards compatibility. See documentation of the
+:prop_dir:`directory <COMPILE_DEFINITIONS>`,
+:prop_tgt:`target <COMPILE_DEFINITIONS>`,
+:prop_sf:`source file <COMPILE_DEFINITIONS>` ``COMPILE_DEFINITIONS``
+properties for details on adding preprocessor definitions to specific
+scopes and configurations.
+
+See the :manual:`cmake-buildsystem(7)` manual for more on defining
+buildsystem properties.
diff --git a/Help/command/add_dependencies.rst b/Help/command/add_dependencies.rst
new file mode 100644
index 000000000..7a6614328
--- /dev/null
+++ b/Help/command/add_dependencies.rst
@@ -0,0 +1,23 @@
+add_dependencies
+----------------
+
+Add a dependency between top-level targets.
+
+::
+
+ add_dependencies(<target> [<target-dependency>]...)
+
+Make a top-level ``<target>`` depend on other top-level targets to
+ensure that they build before ``<target>`` does. A top-level target
+is one created by one of the :command:`add_executable`,
+:command:`add_library`, or :command:`add_custom_target` commands
+(but not targets generated by CMake like ``install``).
+
+Dependencies added to an :ref:`imported target <Imported Targets>`
+or an :ref:`interface library <Interface Libraries>` are followed
+transitively in its place since the target itself does not build.
+
+See the ``DEPENDS`` option of :command:`add_custom_target` and
+:command:`add_custom_command` commands for adding file-level
+dependencies in custom rules. See the :prop_sf:`OBJECT_DEPENDS`
+source file property to add file-level dependencies to object files.
diff --git a/Help/command/add_executable.rst b/Help/command/add_executable.rst
new file mode 100644
index 000000000..8b3fb5772
--- /dev/null
+++ b/Help/command/add_executable.rst
@@ -0,0 +1,80 @@
+add_executable
+--------------
+
+Add an executable to the project using the specified source files.
+
+::
+
+ add_executable(<name> [WIN32] [MACOSX_BUNDLE]
+ [EXCLUDE_FROM_ALL]
+ source1 [source2 ...])
+
+Adds an executable target called ``<name>`` to be built from the source
+files listed in the command invocation. The ``<name>`` corresponds to the
+logical target name and must be globally unique within a project. The
+actual file name of the executable built is constructed based on
+conventions of the native platform (such as ``<name>.exe`` or just
+``<name>``).
+
+By default the executable file will be created in the build tree
+directory corresponding to the source tree directory in which the
+command was invoked. See documentation of the
+:prop_tgt:`RUNTIME_OUTPUT_DIRECTORY` target property to change this
+location. See documentation of the :prop_tgt:`OUTPUT_NAME` target property
+to change the ``<name>`` part of the final file name.
+
+If ``WIN32`` is given the property :prop_tgt:`WIN32_EXECUTABLE` will be
+set on the target created. See documentation of that target property for
+details.
+
+If ``MACOSX_BUNDLE`` is given the corresponding property will be set on
+the created target. See documentation of the :prop_tgt:`MACOSX_BUNDLE`
+target property for details.
+
+If ``EXCLUDE_FROM_ALL`` is given the corresponding property will be set on
+the created target. See documentation of the :prop_tgt:`EXCLUDE_FROM_ALL`
+target property for details.
+
+Source arguments to ``add_executable`` may use "generator expressions" with
+the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions. See the :manual:`cmake-buildsystem(7)`
+manual for more on defining buildsystem properties.
+
+
+--------------------------------------------------------------------------
+
+::
+
+ add_executable(<name> IMPORTED [GLOBAL])
+
+An :ref:`IMPORTED executable target <Imported Targets>` references an
+executable file located outside the project. No rules are generated to
+build it, and the :prop_tgt:`IMPORTED` target property is ``True``. The
+target name has scope in the directory in which it is created and below, but
+the ``GLOBAL`` option extends visibility. It may be referenced like any
+target built within the project. ``IMPORTED`` executables are useful
+for convenient reference from commands like :command:`add_custom_command`.
+Details about the imported executable are specified by setting properties
+whose names begin in ``IMPORTED_``. The most important such property is
+:prop_tgt:`IMPORTED_LOCATION` (and its per-configuration version
+:prop_tgt:`IMPORTED_LOCATION_<CONFIG>`) which specifies the location of
+the main executable file on disk. See documentation of the ``IMPORTED_*``
+properties for more information.
+
+--------------------------------------------------------------------------
+
+::
+
+ add_executable(<name> ALIAS <target>)
+
+Creates an :ref:`Alias Target <Alias Targets>`, such that ``<name>`` can
+be used to refer to ``<target>`` in subsequent commands. The ``<name>``
+does not appear in the generated buildsystem as a make target. The
+``<target>`` may not be an :ref:`Imported Target <Imported Targets>` or an
+``ALIAS``. ``ALIAS`` targets can be used as targets to read properties
+from, executables for custom commands and custom targets. They can also be
+tested for existance with the regular :command:`if(TARGET)` subcommand.
+The ``<name>`` may not be used to modify properties of ``<target>``, that
+is, it may not be used as the operand of :command:`set_property`,
+:command:`set_target_properties`, :command:`target_link_libraries` etc.
+An ``ALIAS`` target may not be installed or exported.
diff --git a/Help/command/add_library.rst b/Help/command/add_library.rst
new file mode 100644
index 000000000..5033e1869
--- /dev/null
+++ b/Help/command/add_library.rst
@@ -0,0 +1,162 @@
+add_library
+-----------
+
+.. only:: html
+
+ .. contents::
+
+Add a library to the project using the specified source files.
+
+Normal Libraries
+^^^^^^^^^^^^^^^^
+
+::
+
+ add_library(<name> [STATIC | SHARED | MODULE]
+ [EXCLUDE_FROM_ALL]
+ source1 [source2 ...])
+
+Adds a library target called ``<name>`` to be built from the source files
+listed in the command invocation. The ``<name>`` corresponds to the
+logical target name and must be globally unique within a project. The
+actual file name of the library built is constructed based on
+conventions of the native platform (such as ``lib<name>.a`` or
+``<name>.lib``).
+
+``STATIC``, ``SHARED``, or ``MODULE`` may be given to specify the type of
+library to be created. ``STATIC`` libraries are archives of object files
+for use when linking other targets. ``SHARED`` libraries are linked
+dynamically and loaded at runtime. ``MODULE`` libraries are plugins that
+are not linked into other targets but may be loaded dynamically at runtime
+using dlopen-like functionality. If no type is given explicitly the
+type is ``STATIC`` or ``SHARED`` based on whether the current value of the
+variable :variable:`BUILD_SHARED_LIBS` is ``ON``. For ``SHARED`` and
+``MODULE`` libraries the :prop_tgt:`POSITION_INDEPENDENT_CODE` target
+property is set to ``ON`` automatically.
+A ``SHARED`` library may be marked with the :prop_tgt:`FRAMEWORK`
+target property to create an OS X Framework.
+
+If a library does not export any symbols, it must not be declared as a
+``SHARED`` library. For example, a Windows resource DLL or a managed C++/CLI
+DLL that exports no unmanaged symbols would need to be a ``MODULE`` library.
+This is because CMake expects a ``SHARED`` library to always have an
+associated import library on Windows.
+
+By default the library file will be created in the build tree directory
+corresponding to the source tree directory in which the command was
+invoked. See documentation of the :prop_tgt:`ARCHIVE_OUTPUT_DIRECTORY`,
+:prop_tgt:`LIBRARY_OUTPUT_DIRECTORY`, and
+:prop_tgt:`RUNTIME_OUTPUT_DIRECTORY` target properties to change this
+location. See documentation of the :prop_tgt:`OUTPUT_NAME` target
+property to change the ``<name>`` part of the final file name.
+
+If ``EXCLUDE_FROM_ALL`` is given the corresponding property will be set on
+the created target. See documentation of the :prop_tgt:`EXCLUDE_FROM_ALL`
+target property for details.
+
+Source arguments to ``add_library`` may use "generator expressions" with
+the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions. See the :manual:`cmake-buildsystem(7)`
+manual for more on defining buildsystem properties.
+
+Imported Libraries
+^^^^^^^^^^^^^^^^^^
+
+::
+
+ add_library(<name> <SHARED|STATIC|MODULE|UNKNOWN> IMPORTED
+ [GLOBAL])
+
+An :ref:`IMPORTED library target <Imported Targets>` references a library
+file located outside the project. No rules are generated to build it, and
+the :prop_tgt:`IMPORTED` target property is ``True``. The target name has
+scope in the directory in which it is created and below, but the ``GLOBAL``
+option extends visibility. It may be referenced like any target built
+within the project. ``IMPORTED`` libraries are useful for convenient
+reference from commands like :command:`target_link_libraries`. Details
+about the imported library are specified by setting properties whose names
+begin in ``IMPORTED_`` and ``INTERFACE_``. The most important such
+property is :prop_tgt:`IMPORTED_LOCATION` (and its per-configuration
+variant :prop_tgt:`IMPORTED_LOCATION_<CONFIG>`) which specifies the
+location of the main library file on disk. See documentation of the
+``IMPORTED_*`` and ``INTERFACE_*`` properties for more information.
+
+Object Libraries
+^^^^^^^^^^^^^^^^
+
+::
+
+ add_library(<name> OBJECT <src>...)
+
+Creates an :ref:`Object Library <Object Libraries>`. An object library
+compiles source files but does not archive or link their object files into a
+library. Instead other targets created by :command:`add_library` or
+:command:`add_executable` may reference the objects using an expression of the
+form ``$<TARGET_OBJECTS:objlib>`` as a source, where ``objlib`` is the
+object library name. For example:
+
+.. code-block:: cmake
+
+ add_library(... $<TARGET_OBJECTS:objlib> ...)
+ add_executable(... $<TARGET_OBJECTS:objlib> ...)
+
+will include objlib's object files in a library and an executable
+along with those compiled from their own sources. Object libraries
+may contain only sources that compile, header files, and other files
+that would not affect linking of a normal library (e.g. ``.txt``).
+They may contain custom commands generating such sources, but not
+``PRE_BUILD``, ``PRE_LINK``, or ``POST_BUILD`` commands. Object libraries
+cannot be imported, exported, installed, or linked. Some native build
+systems may not like targets that have only object files, so consider
+adding at least one real source file to any target that references
+``$<TARGET_OBJECTS:objlib>``.
+
+Alias Libraries
+^^^^^^^^^^^^^^^
+
+::
+
+ add_library(<name> ALIAS <target>)
+
+Creates an :ref:`Alias Target <Alias Targets>`, such that ``<name>`` can be
+used to refer to ``<target>`` in subsequent commands. The ``<name>`` does
+not appear in the generatedbuildsystem as a make target. The ``<target>``
+may not be an :ref:`Imported Target <Imported Targets>` or an ``ALIAS``.
+``ALIAS`` targets can be used as linkable targets and as targets to
+read properties from. They can also be tested for existance with the
+regular :command:`if(TARGET)` subcommand. The ``<name>`` may not be used
+to modify properties of ``<target>``, that is, it may not be used as the
+operand of :command:`set_property`, :command:`set_target_properties`,
+:command:`target_link_libraries` etc. An ``ALIAS`` target may not be
+installed or exported.
+
+Interface Libraries
+^^^^^^^^^^^^^^^^^^^
+
+::
+
+ add_library(<name> INTERFACE [IMPORTED [GLOBAL]])
+
+Creates an :ref:`Interface Library <Interface Libraries>`. An ``INTERFACE``
+library target does not directly create build output, though it may
+have properties set on it and it may be installed, exported and
+imported. Typically the ``INTERFACE_*`` properties are populated on
+the interface target using the commands:
+
+* :command:`set_property`,
+* :command:`target_link_libraries(INTERFACE)`,
+* :command:`target_include_directories(INTERFACE)`,
+* :command:`target_compile_options(INTERFACE)`,
+* :command:`target_compile_definitions(INTERFACE)`, and
+* :command:`target_sources(INTERFACE)`,
+
+and then it is used as an argument to :command:`target_link_libraries`
+like any other target.
+
+An ``INTERFACE`` :ref:`Imported Target <Imported Targets>` may also be
+created with this signature. An ``IMPORTED`` library target references a
+library defined outside the project. The target name has scope in the
+directory in which it is created and below, but the ``GLOBAL`` option
+extends visibility. It may be referenced like any target built within
+the project. ``IMPORTED`` libraries are useful for convenient reference
+from commands like :command:`target_link_libraries`.
diff --git a/Help/command/add_subdirectory.rst b/Help/command/add_subdirectory.rst
new file mode 100644
index 000000000..e97925302
--- /dev/null
+++ b/Help/command/add_subdirectory.rst
@@ -0,0 +1,36 @@
+add_subdirectory
+----------------
+
+Add a subdirectory to the build.
+
+::
+
+ add_subdirectory(source_dir [binary_dir]
+ [EXCLUDE_FROM_ALL])
+
+Add a subdirectory to the build. The source_dir specifies the
+directory in which the source CMakeLists.txt and code files are
+located. If it is a relative path it will be evaluated with respect
+to the current directory (the typical usage), but it may also be an
+absolute path. The ``binary_dir`` specifies the directory in which to
+place the output files. If it is a relative path it will be evaluated
+with respect to the current output directory, but it may also be an
+absolute path. If ``binary_dir`` is not specified, the value of
+``source_dir``, before expanding any relative path, will be used (the
+typical usage). The CMakeLists.txt file in the specified source
+directory will be processed immediately by CMake before processing in
+the current input file continues beyond this command.
+
+If the ``EXCLUDE_FROM_ALL`` argument is provided then targets in the
+subdirectory will not be included in the ``ALL`` target of the parent
+directory by default, and will be excluded from IDE project files.
+Users must explicitly build targets in the subdirectory. This is
+meant for use when the subdirectory contains a separate part of the
+project that is useful but not necessary, such as a set of examples.
+Typically the subdirectory should contain its own :command:`project`
+command invocation so that a full build system will be generated in the
+subdirectory (such as a VS IDE solution file). Note that inter-target
+dependencies supercede this exclusion. If a target built by the
+parent project depends on a target in the subdirectory, the dependee
+target will be included in the parent project build system to satisfy
+the dependency.
diff --git a/Help/command/add_test.rst b/Help/command/add_test.rst
new file mode 100644
index 000000000..d8a96e9b9
--- /dev/null
+++ b/Help/command/add_test.rst
@@ -0,0 +1,66 @@
+add_test
+--------
+
+Add a test to the project to be run by :manual:`ctest(1)`.
+
+::
+
+ add_test(NAME <name> COMMAND <command> [<arg>...]
+ [CONFIGURATIONS <config>...]
+ [WORKING_DIRECTORY <dir>])
+
+Add a test called ``<name>``. The test name may not contain spaces,
+quotes, or other characters special in CMake syntax. The options are:
+
+``COMMAND``
+ Specify the test command-line. If ``<command>`` specifies an
+ executable target (created by :command:`add_executable`) it will
+ automatically be replaced by the location of the executable created
+ at build time.
+
+``CONFIGURATIONS``
+ Restrict execution of the test only to the named configurations.
+
+``WORKING_DIRECTORY``
+ Set the :prop_test:`WORKING_DIRECTORY` test property to
+ specify the working directory in which to execute the test.
+ If not specified the test will be run with the current working
+ directory set to the build directory corresponding to the
+ current source directory.
+
+The given test command is expected to exit with code ``0`` to pass and
+non-zero to fail, or vice-versa if the :prop_test:`WILL_FAIL` test
+property is set. Any output written to stdout or stderr will be
+captured by :manual:`ctest(1)` but does not affect the pass/fail status
+unless the :prop_test:`PASS_REGULAR_EXPRESSION` or
+:prop_test:`FAIL_REGULAR_EXPRESSION` test property is used.
+
+The ``COMMAND`` and ``WORKING_DIRECTORY`` options may use "generator
+expressions" with the syntax ``$<...>``. See the
+:manual:`cmake-generator-expressions(7)` manual for available expressions.
+
+Example usage::
+
+ add_test(NAME mytest
+ COMMAND testDriver --config $<CONFIGURATION>
+ --exe $<TARGET_FILE:myexe>)
+
+This creates a test ``mytest`` whose command runs a ``testDriver`` tool
+passing the configuration name and the full path to the executable
+file produced by target ``myexe``.
+
+.. note::
+
+ CMake will generate tests only if the :command:`enable_testing`
+ command has been invoked. The :module:`CTest` module invokes the
+ command automatically when the ``BUILD_TESTING`` option is ``ON``.
+
+---------------------------------------------------------------------
+
+::
+
+ add_test(<name> <command> [<arg>...])
+
+Add a test called ``<name>`` with the given command-line. Unlike
+the above ``NAME`` signature no transformation is performed on the
+command-line to support target names or generator expressions.
diff --git a/Help/command/aux_source_directory.rst b/Help/command/aux_source_directory.rst
new file mode 100644
index 000000000..dcd1cdfc3
--- /dev/null
+++ b/Help/command/aux_source_directory.rst
@@ -0,0 +1,24 @@
+aux_source_directory
+--------------------
+
+Find all source files in a directory.
+
+::
+
+ aux_source_directory(<dir> <variable>)
+
+Collects the names of all the source files in the specified directory
+and stores the list in the ``<variable>`` provided. This command is
+intended to be used by projects that use explicit template
+instantiation. Template instantiation files can be stored in a
+"Templates" subdirectory and collected automatically using this
+command to avoid manually listing all instantiations.
+
+It is tempting to use this command to avoid writing the list of source
+files for a library or executable target. While this seems to work,
+there is no way for CMake to generate a build system that knows when a
+new source file has been added. Normally the generated build system
+knows when it needs to rerun CMake because the CMakeLists.txt file is
+modified to add a new source. When the source is just added to the
+directory without modifying this file, one would have to manually
+rerun CMake to generate a build system incorporating the new file.
diff --git a/Help/command/break.rst b/Help/command/break.rst
new file mode 100644
index 000000000..fc2cd3c7b
--- /dev/null
+++ b/Help/command/break.rst
@@ -0,0 +1,12 @@
+break
+-----
+
+Break from an enclosing foreach or while loop.
+
+::
+
+ break()
+
+Breaks from an enclosing foreach loop or while loop
+
+See also the :command:`continue` command.
diff --git a/Help/command/build_command.rst b/Help/command/build_command.rst
new file mode 100644
index 000000000..1298c1f8f
--- /dev/null
+++ b/Help/command/build_command.rst
@@ -0,0 +1,45 @@
+build_command
+-------------
+
+Get a command line to build the current project.
+This is mainly intended for internal use by the :module:`CTest` module.
+
+.. code-block:: cmake
+
+ build_command(<variable>
+ [CONFIGURATION <config>]
+ [TARGET <target>]
+ [PROJECT_NAME <projname>] # legacy, causes warning
+ )
+
+Sets the given ``<variable>`` to a command-line string of the form::
+
+ <cmake> --build . [--config <config>] [--target <target>] [-- -i]
+
+where ``<cmake>`` is the location of the :manual:`cmake(1)` command-line
+tool, and ``<config>`` and ``<target>`` are the values provided to the
+``CONFIGURATION`` and ``TARGET`` options, if any. The trailing ``-- -i``
+option is added for :ref:`Makefile Generators` if policy :policy:`CMP0061`
+is not set to ``NEW``.
+
+When invoked, this ``cmake --build`` command line will launch the
+underlying build system tool.
+
+.. code-block:: cmake
+
+ build_command(<cachevariable> <makecommand>)
+
+This second signature is deprecated, but still available for backwards
+compatibility. Use the first signature instead.
+
+It sets the given ``<cachevariable>`` to a command-line string as
+above but without the ``--target`` option.
+The ``<makecommand>`` is ignored but should be the full path to
+msdev, devenv, nmake, make or one of the end user build tools
+for legacy invocations.
+
+.. note::
+ In CMake versions prior to 3.0 this command returned a command
+ line that directly invokes the native build tool for the current
+ generator. Their implementation of the ``PROJECT_NAME`` option
+ had no useful effects, so CMake now warns on use of the option.
diff --git a/Help/command/build_name.rst b/Help/command/build_name.rst
new file mode 100644
index 000000000..f717db1dd
--- /dev/null
+++ b/Help/command/build_name.rst
@@ -0,0 +1,15 @@
+build_name
+----------
+
+Disallowed. See CMake Policy :policy:`CMP0036`.
+
+Use ``${CMAKE_SYSTEM}`` and ``${CMAKE_CXX_COMPILER}`` instead.
+
+::
+
+ build_name(variable)
+
+Sets the specified variable to a string representing the platform and
+compiler settings. These values are now available through the
+:variable:`CMAKE_SYSTEM` and
+:variable:`CMAKE_CXX_COMPILER <CMAKE_<LANG>_COMPILER>` variables.
diff --git a/Help/command/cmake_host_system_information.rst b/Help/command/cmake_host_system_information.rst
new file mode 100644
index 000000000..9402d57e9
--- /dev/null
+++ b/Help/command/cmake_host_system_information.rst
@@ -0,0 +1,25 @@
+cmake_host_system_information
+-----------------------------
+
+Query host system specific information.
+
+::
+
+ cmake_host_system_information(RESULT <variable> QUERY <key> ...)
+
+Queries system information of the host system on which cmake runs.
+One or more ``<key>`` can be provided to select the information to be
+queried. The list of queried values is stored in ``<variable>``.
+
+``<key>`` can be one of the following values:
+
+::
+
+ NUMBER_OF_LOGICAL_CORES = Number of logical cores.
+ NUMBER_OF_PHYSICAL_CORES = Number of physical cores.
+ HOSTNAME = Hostname.
+ FQDN = Fully qualified domain name.
+ TOTAL_VIRTUAL_MEMORY = Total virtual memory in megabytes.
+ AVAILABLE_VIRTUAL_MEMORY = Available virtual memory in megabytes.
+ TOTAL_PHYSICAL_MEMORY = Total physical memory in megabytes.
+ AVAILABLE_PHYSICAL_MEMORY = Available physical memory in megabytes.
diff --git a/Help/command/cmake_minimum_required.rst b/Help/command/cmake_minimum_required.rst
new file mode 100644
index 000000000..dc65a9e68
--- /dev/null
+++ b/Help/command/cmake_minimum_required.rst
@@ -0,0 +1,41 @@
+cmake_minimum_required
+----------------------
+
+Set the minimum required version of cmake for a project.
+
+::
+
+ cmake_minimum_required(VERSION major.minor[.patch[.tweak]]
+ [FATAL_ERROR])
+
+If the current version of CMake is lower than that required it will
+stop processing the project and report an error. When a version
+higher than 2.4 is specified the command implicitly invokes
+
+::
+
+ cmake_policy(VERSION major[.minor[.patch[.tweak]]])
+
+which sets the cmake policy version level to the version specified.
+When version 2.4 or lower is given the command implicitly invokes
+
+::
+
+ cmake_policy(VERSION 2.4)
+
+which enables compatibility features for CMake 2.4 and lower.
+
+The ``FATAL_ERROR`` option is accepted but ignored by CMake 2.6 and
+higher. It should be specified so CMake versions 2.4 and lower fail
+with an error instead of just a warning.
+
+.. note::
+ Call the ``cmake_minimum_required()`` command at the beginning of
+ the top-level ``CMakeLists.txt`` file even before calling the
+ :command:`project` command. It is important to establish version
+ and policy settings before invoking other commands whose behavior
+ they may affect. See also policy :policy:`CMP0000`.
+
+ Calling ``cmake_minimum_required()`` inside a :command:`function`
+ limits some effects to the function scope when invoked. Such calls
+ should not be made with the intention of having global effects.
diff --git a/Help/command/cmake_parse_arguments.rst b/Help/command/cmake_parse_arguments.rst
new file mode 100644
index 000000000..6206611d2
--- /dev/null
+++ b/Help/command/cmake_parse_arguments.rst
@@ -0,0 +1,85 @@
+cmake_parse_arguments
+---------------------
+
+``cmake_parse_arguments`` is intended to be used in macros or functions for
+parsing the arguments given to that macro or function. It processes the
+arguments and defines a set of variables which hold the values of the
+respective options.
+
+::
+
+ cmake_parse_arguments(<prefix> <options> <one_value_keywords>
+ <multi_value_keywords> args...)
+
+
+The ``<options>`` argument contains all options for the respective macro,
+i.e. keywords which can be used when calling the macro without any value
+following, like e.g. the ``OPTIONAL`` keyword of the :command:`install`
+command.
+
+The ``<one_value_keywords>`` argument contains all keywords for this macro
+which are followed by one value, like e.g. ``DESTINATION`` keyword of the
+:command:`install` command.
+
+The ``<multi_value_keywords>`` argument contains all keywords for this
+macro which can be followed by more than one value, like e.g. the
+``TARGETS`` or ``FILES`` keywords of the :command:`install` command.
+
+.. note::
+
+ All keywords shall be unique. I.e. every keyword shall only be specified
+ once in either ``<options>``, ``<one_value_keywords>`` or
+ ``<multi_value_keywords>``. A warning will be emitted if uniqueness is
+ violated.
+
+When done, ``cmake_parse_arguments`` will have defined for each of the
+keywords listed in ``<options>``, ``<one_value_keywords>`` and
+``<multi_value_keywords>`` a variable composed of the given ``<prefix>``
+followed by ``"_"`` and the name of the respective keyword. These
+variables will then hold the respective value from the argument list.
+For the ``<options>`` keywords this will be ``TRUE`` or ``FALSE``.
+
+All remaining arguments are collected in a variable
+``<prefix>_UNPARSED_ARGUMENTS``, this can be checked afterwards to see
+whether your macro was called with unrecognized parameters.
+
+As an example here a ``my_install()`` macro, which takes similar arguments
+as the real :command:`install` command:
+
+.. code-block:: cmake
+
+ function(MY_INSTALL)
+ set(options OPTIONAL FAST)
+ set(oneValueArgs DESTINATION RENAME)
+ set(multiValueArgs TARGETS CONFIGURATIONS)
+ cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}"
+ "${multiValueArgs}" ${ARGN} )
+
+ # ...
+
+Assume ``my_install()`` has been called like this:
+
+.. code-block:: cmake
+
+ my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub)
+
+After the ``cmake_parse_arguments`` call the macro will have set the
+following variables::
+
+ MY_INSTALL_OPTIONAL = TRUE
+ MY_INSTALL_FAST = FALSE (was not used in call to my_install)
+ MY_INSTALL_DESTINATION = "bin"
+ MY_INSTALL_RENAME = "" (was not used)
+ MY_INSTALL_TARGETS = "foo;bar"
+ MY_INSTALL_CONFIGURATIONS = "" (was not used)
+ MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (nothing expected after "OPTIONAL")
+
+You can then continue and process these variables.
+
+Keywords terminate lists of values, e.g. if directly after a
+one_value_keyword another recognized keyword follows, this is
+interpreted as the beginning of the new option. E.g.
+``my_install(TARGETS foo DESTINATION OPTIONAL)`` would result in
+``MY_INSTALL_DESTINATION`` set to ``"OPTIONAL"``, but as ``OPTIONAL``
+is a keyword itself ``MY_INSTALL_DESTINATION`` will be empty and
+``MY_INSTALL_OPTIONAL`` will therefore be set to ``TRUE``.
diff --git a/Help/command/cmake_policy.rst b/Help/command/cmake_policy.rst
new file mode 100644
index 000000000..b51b9512c
--- /dev/null
+++ b/Help/command/cmake_policy.rst
@@ -0,0 +1,96 @@
+cmake_policy
+------------
+
+Manage CMake Policy settings. See the :manual:`cmake-policies(7)`
+manual for defined policies.
+
+As CMake evolves it is sometimes necessary to change existing behavior
+in order to fix bugs or improve implementations of existing features.
+The CMake Policy mechanism is designed to help keep existing projects
+building as new versions of CMake introduce changes in behavior. Each
+new policy (behavioral change) is given an identifier of the form
+``CMP<NNNN>`` where ``<NNNN>`` is an integer index. Documentation
+associated with each policy describes the ``OLD`` and ``NEW`` behavior
+and the reason the policy was introduced. Projects may set each policy
+to select the desired behavior. When CMake needs to know which behavior
+to use it checks for a setting specified by the project. If no
+setting is available the ``OLD`` behavior is assumed and a warning is
+produced requesting that the policy be set.
+
+Setting Policies by CMake Version
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The ``cmake_policy`` command is used to set policies to ``OLD`` or ``NEW``
+behavior. While setting policies individually is supported, we
+encourage projects to set policies based on CMake versions::
+
+ cmake_policy(VERSION major.minor[.patch[.tweak]])
+
+Specify that the current CMake code is written for the given
+version of CMake. All policies introduced in the specified version or
+earlier will be set to use ``NEW`` behavior. All policies introduced
+after the specified version will be unset (unless the
+:variable:`CMAKE_POLICY_DEFAULT_CMP<NNNN>` variable sets a default).
+This effectively requests behavior preferred as of a given CMake
+version and tells newer CMake versions to warn about their new policies.
+The policy version specified must be at least 2.4 or the command will
+report an error.
+
+Note that the :command:`cmake_minimum_required(VERSION)`
+command implicitly calls ``cmake_policy(VERSION)`` too.
+
+Setting Policies Explicitly
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+ cmake_policy(SET CMP<NNNN> NEW)
+ cmake_policy(SET CMP<NNNN> OLD)
+
+Tell CMake to use the ``OLD`` or ``NEW`` behavior for a given policy.
+Projects depending on the old behavior of a given policy may silence a
+policy warning by setting the policy state to ``OLD``. Alternatively
+one may fix the project to work with the new behavior and set the
+policy state to ``NEW``.
+
+.. include:: ../policy/DEPRECATED.txt
+
+Checking Policy Settings
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+ cmake_policy(GET CMP<NNNN> <variable>)
+
+Check whether a given policy is set to ``OLD`` or ``NEW`` behavior.
+The output ``<variable>`` value will be ``OLD`` or ``NEW`` if the
+policy is set, and empty otherwise.
+
+CMake Policy Stack
+^^^^^^^^^^^^^^^^^^
+
+CMake keeps policy settings on a stack, so changes made by the
+cmake_policy command affect only the top of the stack. A new entry on
+the policy stack is managed automatically for each subdirectory to
+protect its parents and siblings. CMake also manages a new entry for
+scripts loaded by :command:`include` and :command:`find_package` commands
+except when invoked with the ``NO_POLICY_SCOPE`` option
+(see also policy :policy:`CMP0011`).
+The ``cmake_policy`` command provides an interface to manage custom
+entries on the policy stack::
+
+ cmake_policy(PUSH)
+ cmake_policy(POP)
+
+Each ``PUSH`` must have a matching ``POP`` to erase any changes.
+This is useful to make temporary changes to policy settings.
+Calls to the :command:`cmake_minimum_required(VERSION)`,
+``cmake_policy(VERSION)``, or ``cmake_policy(SET)`` commands
+influence only the current top of the policy stack.
+
+Commands created by the :command:`function` and :command:`macro`
+commands record policy settings when they are created and
+use the pre-record policies when they are invoked. If the function or
+macro implementation sets policies, the changes automatically
+propagate up through callers until they reach the closest nested
+policy stack entry.
diff --git a/Help/command/configure_file.rst b/Help/command/configure_file.rst
new file mode 100644
index 000000000..4304f095b
--- /dev/null
+++ b/Help/command/configure_file.rst
@@ -0,0 +1,111 @@
+configure_file
+--------------
+
+Copy a file to another location and modify its contents.
+
+::
+
+ configure_file(<input> <output>
+ [COPYONLY] [ESCAPE_QUOTES] [@ONLY]
+ [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])
+
+Copies an ``<input>`` file to an ``<output>`` file and substitutes
+variable values referenced as ``@VAR@`` or ``${VAR}`` in the input
+file content. Each variable reference will be replaced with the
+current value of the variable, or the empty string if the variable
+is not defined. Furthermore, input lines of the form::
+
+ #cmakedefine VAR ...
+
+will be replaced with either::
+
+ #define VAR ...
+
+or::
+
+ /* #undef VAR */
+
+depending on whether ``VAR`` is set in CMake to any value not considered
+a false constant by the :command:`if` command. The "..." content on the
+line after the variable name, if any, is processed as above.
+Input file lines of the form ``#cmakedefine01 VAR`` will be replaced with
+either ``#define VAR 1`` or ``#define VAR 0`` similarly.
+
+If the input file is modified the build system will re-run CMake to
+re-configure the file and generate the build system again.
+
+The arguments are:
+
+``<input>``
+ Path to the input file. A relative path is treated with respect to
+ the value of :variable:`CMAKE_CURRENT_SOURCE_DIR`. The input path
+ must be a file, not a directory.
+
+``<output>``
+ Path to the output file or directory. A relative path is treated
+ with respect to the value of :variable:`CMAKE_CURRENT_BINARY_DIR`.
+ If the path names an existing directory the output file is placed
+ in that directory with the same file name as the input file.
+
+``COPYONLY``
+ Copy the file without replacing any variable references or other
+ content. This option may not be used with ``NEWLINE_STYLE``.
+
+``ESCAPE_QUOTES``
+ Escape any substituted quotes with backslashes (C-style).
+
+``@ONLY``
+ Restrict variable replacement to references of the form ``@VAR@``.
+ This is useful for configuring scripts that use ``${VAR}`` syntax.
+
+``NEWLINE_STYLE <style>``
+ Specify the newline style for the output file. Specify
+ ``UNIX`` or ``LF`` for ``\n`` newlines, or specify
+ ``DOS``, ``WIN32``, or ``CRLF`` for ``\r\n`` newlines.
+ This option may not be used with ``COPYONLY``.
+
+Example
+^^^^^^^
+
+Consider a source tree containing a ``foo.h.in`` file:
+
+.. code-block:: c
+
+ #cmakedefine FOO_ENABLE
+ #cmakedefine FOO_STRING "@FOO_STRING@"
+
+An adjacent ``CMakeLists.txt`` may use ``configure_file`` to
+configure the header:
+
+.. code-block:: cmake
+
+ option(FOO_ENABLE "Enable Foo" ON)
+ if(FOO_ENABLE)
+ set(FOO_STRING "foo")
+ endif()
+ configure_file(foo.h.in foo.h @ONLY)
+
+This creates a ``foo.h`` in the build directory corresponding to
+this source directory. If the ``FOO_ENABLE`` option is on, the
+configured file will contain:
+
+.. code-block:: c
+
+ #define FOO_ENABLE
+ #define FOO_STRING "foo"
+
+Otherwise it will contain:
+
+.. code-block:: c
+
+ /* #undef FOO_ENABLE */
+ /* #undef FOO_STRING */
+
+One may then use the :command:`include_directories` command to
+specify the output directory as an include directory:
+
+.. code-block:: cmake
+
+ include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+so that sources may include the header as ``#include <foo.h>``.
diff --git a/Help/command/continue.rst b/Help/command/continue.rst
new file mode 100644
index 000000000..1c7d6730c
--- /dev/null
+++ b/Help/command/continue.rst
@@ -0,0 +1,12 @@
+continue
+--------
+
+Continue to the top of enclosing foreach or while loop.
+
+::
+
+ continue()
+
+The ``continue`` command allows a cmake script to abort the rest of a block
+in a :command:`foreach` or :command:`while` loop, and start at the top of
+the next iteration. See also the :command:`break` command.
diff --git a/Help/command/create_test_sourcelist.rst b/Help/command/create_test_sourcelist.rst
new file mode 100644
index 000000000..dde6812e1
--- /dev/null
+++ b/Help/command/create_test_sourcelist.rst
@@ -0,0 +1,30 @@
+create_test_sourcelist
+----------------------
+
+Create a test driver and source list for building test programs.
+
+::
+
+ create_test_sourcelist(sourceListName driverName
+ test1 test2 test3
+ EXTRA_INCLUDE include.h
+ FUNCTION function)
+
+A test driver is a program that links together many small tests into a
+single executable. This is useful when building static executables
+with large libraries to shrink the total required size. The list of
+source files needed to build the test driver will be in
+``sourceListName``. ``driverName`` is the name of the test driver program.
+The rest of the arguments consist of a list of test source files, can
+be semicolon separated. Each test source file should have a function
+in it that is the same name as the file with no extension (foo.cxx
+should have int foo(int, char*[]);) ``driverName`` will be able to call
+each of the tests by name on the command line. If ``EXTRA_INCLUDE`` is
+specified, then the next argument is included into the generated file.
+If ``FUNCTION`` is specified, then the next argument is taken as a
+function name that is passed a pointer to ac and av. This can be used
+to add extra command line processing to each test. The
+``CMAKE_TESTDRIVER_BEFORE_TESTMAIN`` cmake variable can be set to
+have code that will be placed directly before calling the test main function.
+``CMAKE_TESTDRIVER_AFTER_TESTMAIN`` can be set to have code that
+will be placed directly after the call to the test main function.
diff --git a/Help/command/ctest_build.rst b/Help/command/ctest_build.rst
new file mode 100644
index 000000000..e1b7793fc
--- /dev/null
+++ b/Help/command/ctest_build.rst
@@ -0,0 +1,73 @@
+ctest_build
+-----------
+
+Perform the :ref:`CTest Build Step` as a :ref:`Dashboard Client`.
+
+::
+
+ ctest_build([BUILD <build-dir>] [APPEND]
+ [CONFIGURATION <config>]
+ [FLAGS <flags>]
+ [PROJECT_NAME <project-name>]
+ [TARGET <target-name>]
+ [NUMBER_ERRORS <num-err-var>]
+ [NUMBER_WARNINGS <num-warn-var>]
+ [RETURN_VALUE <result-var>]
+ )
+
+Build the project and store results in ``Build.xml``
+for submission with the :command:`ctest_submit` command.
+
+The :variable:`CTEST_BUILD_COMMAND` variable may be set to explicitly
+specify the build command line. Otherwise the build command line is
+computed automatically based on the options given.
+
+The options are:
+
+``BUILD <build-dir>``
+ Specify the top-level build directory. If not given, the
+ :variable:`CTEST_BINARY_DIRECTORY` variable is used.
+
+``APPEND``
+ Mark results for append to those previously submitted to a
+ dashboard server since the last :command:`ctest_start` call.
+ Append semantics are defined by the dashboard server in use.
+
+``CONFIGURATION <config>``
+ Specify the build configuration (e.g. ``Debug``). If not
+ specified the ``CTEST_BUILD_CONFIGURATION`` variable will be checked.
+ Otherwise the ``-C <cfg>`` option given to the :manual:`ctest(1)`
+ command will be used, if any.
+
+``FLAGS <flags>``
+ Pass additional arguments to the underlying build command.
+ If not specified the ``CTEST_BUILD_FLAGS`` variable will be checked.
+ This can, e.g., be used to trigger a parallel build using the
+ ``-j`` option of make. See the :module:`ProcessorCount` module
+ for an example.
+
+``PROJECT_NAME <project-name>``
+ Set the name of the project to build. This should correspond
+ to the top-level call to the :command:`project` command.
+ If not specified the ``CTEST_PROJECT_NAME`` variable will be checked.
+
+``TARGET <target-name>``
+ Specify the name of a target to build. If not specified the
+ ``CTEST_BUILD_TARGET`` variable will be checked. Otherwise the
+ default target will be built. This is the "all" target
+ (called ``ALL_BUILD`` in :ref:`Visual Studio Generators`).
+
+``NUMBER_ERRORS <num-err-var>``
+ Store the number of build errors detected in the given variable.
+
+``NUMBER_WARNINGS <num-warn-var>``
+ Store the number of build warnings detected in the given variable.
+
+``RETURN_VALUE <result-var>``
+ Store the return value of the native build tool in the given variable.
+
+``QUIET``
+ Suppress any CTest-specific non-error output that would have been
+ printed to the console otherwise. The summary of warnings / errors,
+ as well as the output from the native build tool is unaffected by
+ this option.
diff --git a/Help/command/ctest_configure.rst b/Help/command/ctest_configure.rst
new file mode 100644
index 000000000..851c29292
--- /dev/null
+++ b/Help/command/ctest_configure.rst
@@ -0,0 +1,39 @@
+ctest_configure
+---------------
+
+Perform the :ref:`CTest Configure Step` as a :ref:`Dashboard Client`.
+
+::
+
+ ctest_configure([BUILD <build-dir>] [SOURCE <source-dir>] [APPEND]
+ [OPTIONS <options>] [RETURN_VALUE <result-var>] [QUIET])
+
+Configure the project build tree and record results in ``Configure.xml``
+for submission with the :command:`ctest_submit` command.
+
+The options are:
+
+``BUILD <build-dir>``
+ Specify the top-level build directory. If not given, the
+ :variable:`CTEST_BINARY_DIRECTORY` variable is used.
+
+``SOURCE <source-dir>``
+ Specify the source directory. If not given, the
+ :variable:`CTEST_SOURCE_DIRECTORY` variable is used.
+
+``APPEND``
+ Mark results for append to those previously submitted to a
+ dashboard server since the last :command:`ctest_start` call.
+ Append semantics are defined by the dashboard server in use.
+
+``OPTIONS <options>``
+ Specify command-line arguments to pass to the configuration tool.
+
+``RETURN_VALUE <result-var>``
+ Store in the ``<result-var>`` variable the return value of the native
+ configuration tool.
+
+``QUIET``
+ Suppress any CTest-specific non-error messages that would have
+ otherwise been printed to the console. Output from the underlying
+ configure command is not affected.
diff --git a/Help/command/ctest_coverage.rst b/Help/command/ctest_coverage.rst
new file mode 100644
index 000000000..12429b99d
--- /dev/null
+++ b/Help/command/ctest_coverage.rst
@@ -0,0 +1,39 @@
+ctest_coverage
+--------------
+
+Perform the :ref:`CTest Coverage Step` as a :ref:`Dashboard Client`.
+
+::
+
+ ctest_coverage([BUILD <build-dir>] [APPEND]
+ [LABELS <label>...]
+ [RETURN_VALUE <result-var>]
+ [QUIET]
+ )
+
+Collect coverage tool results and stores them in ``Coverage.xml``
+for submission with the :command:`ctest_submit` command.
+
+The options are:
+
+``BUILD <build-dir>``
+ Specify the top-level build directory. If not given, the
+ :variable:`CTEST_BINARY_DIRECTORY` variable is used.
+
+``APPEND``
+ Mark results for append to those previously submitted to a
+ dashboard server since the last :command:`ctest_start` call.
+ Append semantics are defined by the dashboard server in use.
+
+``LABELS``
+ Filter the coverage report to include only source files labeled
+ with at least one of the labels specified.
+
+``RETURN_VALUE <result-var>``
+ Store in the ``<result-var>`` variable ``0`` if coverage tools
+ ran without error and non-zero otherwise.
+
+``QUIET``
+ Suppress any CTest-specific non-error output that would have been
+ printed to the console otherwise. The summary indicating how many
+ lines of code were covered is unaffected by this option.
diff --git a/Help/command/ctest_empty_binary_directory.rst b/Help/command/ctest_empty_binary_directory.rst
new file mode 100644
index 000000000..77536673c
--- /dev/null
+++ b/Help/command/ctest_empty_binary_directory.rst
@@ -0,0 +1,12 @@
+ctest_empty_binary_directory
+----------------------------
+
+empties the binary directory
+
+::
+
+ ctest_empty_binary_directory( directory )
+
+Removes a binary directory. This command will perform some checks
+prior to deleting the directory in an attempt to avoid malicious or
+accidental directory deletion.
diff --git a/Help/command/ctest_memcheck.rst b/Help/command/ctest_memcheck.rst
new file mode 100644
index 000000000..29bdf7d0e
--- /dev/null
+++ b/Help/command/ctest_memcheck.rst
@@ -0,0 +1,29 @@
+ctest_memcheck
+--------------
+
+Perform the :ref:`CTest MemCheck Step` as a :ref:`Dashboard Client`.
+
+::
+
+ ctest_memcheck([BUILD <build-dir>] [APPEND]
+ [START <start-number>]
+ [END <end-number>]
+ [STRIDE <stride-number>]
+ [EXCLUDE <exclude-regex>]
+ [INCLUDE <include-regex>]
+ [EXCLUDE_LABEL <label-exclude-regex>]
+ [INCLUDE_LABEL <label-include-regex>]
+ [PARALLEL_LEVEL <level>]
+ [TEST_LOAD <threshold>]
+ [SCHEDULE_RANDOM <ON|OFF>]
+ [STOP_TIME <time-of-day>]
+ [RETURN_VALUE <result-var>]
+ [QUIET]
+ )
+
+
+Run tests with a dynamic analysis tool and store results in
+``MemCheck.xml`` for submission with the :command:`ctest_submit`
+command.
+
+The options are the same as those for the :command:`ctest_test` command.
diff --git a/Help/command/ctest_read_custom_files.rst b/Help/command/ctest_read_custom_files.rst
new file mode 100644
index 000000000..cf8e17a9c
--- /dev/null
+++ b/Help/command/ctest_read_custom_files.rst
@@ -0,0 +1,14 @@
+ctest_read_custom_files
+-----------------------
+
+read CTestCustom files.
+
+::
+
+ ctest_read_custom_files( directory ... )
+
+Read all the CTestCustom.ctest or CTestCustom.cmake files from the
+given directory.
+
+By default, invoking :manual:`ctest(1)` without a script will read custom
+files from the binary directory.
diff --git a/Help/command/ctest_run_script.rst b/Help/command/ctest_run_script.rst
new file mode 100644
index 000000000..5ec543ed1
--- /dev/null
+++ b/Help/command/ctest_run_script.rst
@@ -0,0 +1,15 @@
+ctest_run_script
+----------------
+
+runs a ctest -S script
+
+::
+
+ ctest_run_script([NEW_PROCESS] script_file_name script_file_name1
+ script_file_name2 ... [RETURN_VALUE var])
+
+Runs a script or scripts much like if it was run from ctest -S. If no
+argument is provided then the current script is run using the current
+settings of the variables. If ``NEW_PROCESS`` is specified then each
+script will be run in a separate process.If ``RETURN_VALUE`` is specified
+the return value of the last script run will be put into ``var``.
diff --git a/Help/command/ctest_sleep.rst b/Help/command/ctest_sleep.rst
new file mode 100644
index 000000000..16a914c0b
--- /dev/null
+++ b/Help/command/ctest_sleep.rst
@@ -0,0 +1,16 @@
+ctest_sleep
+-----------
+
+sleeps for some amount of time
+
+::
+
+ ctest_sleep(<seconds>)
+
+Sleep for given number of seconds.
+
+::
+
+ ctest_sleep(<time1> <duration> <time2>)
+
+Sleep for t=(time1 + duration - time2) seconds if t > 0.
diff --git a/Help/command/ctest_start.rst b/Help/command/ctest_start.rst
new file mode 100644
index 000000000..63db32f4e
--- /dev/null
+++ b/Help/command/ctest_start.rst
@@ -0,0 +1,25 @@
+ctest_start
+-----------
+
+Starts the testing for a given model
+
+::
+
+ ctest_start(Model [TRACK <track>] [APPEND] [source [binary]] [QUIET])
+
+Starts the testing for a given model. The command should be called
+after the binary directory is initialized. If the 'source' and
+'binary' directory are not specified, it reads the
+:variable:`CTEST_SOURCE_DIRECTORY` and :variable:`CTEST_BINARY_DIRECTORY`.
+If the track is
+specified, the submissions will go to the specified track. If APPEND
+is used, the existing TAG is used rather than creating a new one based
+on the current time stamp. If ``QUIET`` is used, CTest will suppress any
+non-error messages that it otherwise would have printed to the console.
+
+If the :variable:`CTEST_CHECKOUT_COMMAND` variable
+(or the :variable:`CTEST_CVS_CHECKOUT` variable)
+is set, its content is treated as command-line. The command is
+invoked with the current working directory set to the parent of the source
+directory, even if the source directory already exists. This can be used
+to create the source tree from a version control repository.
diff --git a/Help/command/ctest_submit.rst b/Help/command/ctest_submit.rst
new file mode 100644
index 000000000..6830b599f
--- /dev/null
+++ b/Help/command/ctest_submit.rst
@@ -0,0 +1,65 @@
+ctest_submit
+------------
+
+Perform the :ref:`CTest Submit Step` as a :ref:`Dashboard Client`.
+
+::
+
+ ctest_submit([PARTS <part>...] [FILES <file>...]
+ [RETRY_COUNT <count>]
+ [RETRY_DELAY <delay>]
+ [RETURN_VALUE <result-var>]
+ [QUIET]
+ )
+
+Submit results to a dashboard server.
+By default all available parts are submitted.
+
+The options are:
+
+``PARTS <part>...``
+ Specify a subset of parts to submit. Valid part names are::
+
+ Start = nothing
+ Update = ctest_update results, in Update.xml
+ Configure = ctest_configure results, in Configure.xml
+ Build = ctest_build results, in Build.xml
+ Test = ctest_test results, in Test.xml
+ Coverage = ctest_coverage results, in Coverage.xml
+ MemCheck = ctest_memcheck results, in DynamicAnalysis.xml
+ Notes = Files listed by CTEST_NOTES_FILES, in Notes.xml
+ ExtraFiles = Files listed by CTEST_EXTRA_SUBMIT_FILES
+ Upload = Files prepared for upload by ctest_upload(), in Upload.xml
+ Submit = nothing
+
+``FILES <file>...``
+ Specify an explicit list of specific files to be submitted.
+ Each individual file must exist at the time of the call.
+
+``RETRY_COUNT <count>``
+ Specify how many times to retry a timed-out submission.
+
+``RETRY_DELAY <delay>``
+ Specify how long (in seconds) to wait after a timed-out submission
+ before attempting to re-submit.
+
+``RETURN_VALUE <result-var>``
+ Store in the ``<result-var>`` variable ``0`` for success and
+ non-zero on failure.
+
+``QUIET``
+ Suppress all non-error messages that would have otherwise been
+ printed to the console.
+
+Submit to CDash Upload API
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+ ctest_submit(CDASH_UPLOAD <file> [CDASH_UPLOAD_TYPE <type>])
+
+This second signature is used to upload files to CDash via the CDash
+file upload API. The api first sends a request to upload to CDash along
+with a content hash of the file. If CDash does not already have the file,
+then it is uploaded. Along with the file, a CDash type string is specified
+to tell CDash which handler to use to process the data.
diff --git a/Help/command/ctest_test.rst b/Help/command/ctest_test.rst
new file mode 100644
index 000000000..412e323a5
--- /dev/null
+++ b/Help/command/ctest_test.rst
@@ -0,0 +1,90 @@
+ctest_test
+----------
+
+Perform the :ref:`CTest Test Step` as a :ref:`Dashboard Client`.
+
+::
+
+ ctest_test([BUILD <build-dir>] [APPEND]
+ [START <start-number>]
+ [END <end-number>]
+ [STRIDE <stride-number>]
+ [EXCLUDE <exclude-regex>]
+ [INCLUDE <include-regex>]
+ [EXCLUDE_LABEL <label-exclude-regex>]
+ [INCLUDE_LABEL <label-include-regex>]
+ [PARALLEL_LEVEL <level>]
+ [TEST_LOAD <threshold>]
+ [SCHEDULE_RANDOM <ON|OFF>]
+ [STOP_TIME <time-of-day>]
+ [RETURN_VALUE <result-var>]
+ [QUIET]
+ )
+
+Run tests in the project build tree and store results in
+``Test.xml`` for submission with the :command:`ctest_submit` command.
+
+The options are:
+
+``BUILD <build-dir>``
+ Specify the top-level build directory. If not given, the
+ :variable:`CTEST_BINARY_DIRECTORY` variable is used.
+
+``APPEND``
+ Mark results for append to those previously submitted to a
+ dashboard server since the last :command:`ctest_start` call.
+ Append semantics are defined by the dashboard server in use.
+
+``START <start-number>``
+ Specify the beginning of a range of test numbers.
+
+``END <end-number>``
+ Specify the end of a range of test numbers.
+
+``STRIDE <stride-number>``
+ Specify the stride by which to step across a range of test numbers.
+
+``EXCLUDE <exclude-regex>``
+ Specify a regular expression matching test names to exclude.
+
+``INCLUDE <include-regex>``
+ Specify a regular expression matching test names to include.
+ Tests not matching this expression are excluded.
+
+``EXCLUDE_LABEL <label-exclude-regex>``
+ Specify a regular expression matching test labels to exclude.
+
+``INCLUDE_LABEL <label-include-regex>``
+ Specify a regular expression matching test labels to include.
+ Tests not matching this expression are excluded.
+
+``PARALLEL_LEVEL <level>``
+ Specify a positive number representing the number of tests to
+ be run in parallel.
+
+``TEST_LOAD <threshold>``
+ While running tests in parallel, try not to start tests when they
+ may cause the CPU load to pass above a given threshold. If not
+ specified the :variable:`CTEST_TEST_LOAD` variable will be checked,
+ and then the ``--test-load`` command-line argument to :manual:`ctest(1)`.
+ See also the ``TestLoad`` setting in the :ref:`CTest Test Step`.
+
+``SCHEDULE_RANDOM <ON|OFF>``
+ Launch tests in a random order. This may be useful for detecting
+ implicit test dependencies.
+
+``STOP_TIME <time-of-day>``
+ Specify a time of day at which the tests should all stop running.
+
+``RETURN_VALUE <result-var>``
+ Store in the ``<result-var>`` variable ``0`` if all tests passed.
+ Store non-zero if anything went wrong.
+
+``QUIET``
+ Suppress any CTest-specific non-error messages that would have otherwise
+ been printed to the console. Output from the underlying test command is not
+ affected. Summary info detailing the percentage of passing tests is also
+ unaffected by the ``QUIET`` option.
+
+See also the :variable:`CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE`
+and :variable:`CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE` variables.
diff --git a/Help/command/ctest_update.rst b/Help/command/ctest_update.rst
new file mode 100644
index 000000000..74af1f7b7
--- /dev/null
+++ b/Help/command/ctest_update.rst
@@ -0,0 +1,27 @@
+ctest_update
+------------
+
+Perform the :ref:`CTest Update Step` as a :ref:`Dashboard Client`.
+
+::
+
+ ctest_update([SOURCE <source-dir>] [RETURN_VALUE <result-var>] [QUIET])
+
+Update the source tree from version control and record results in
+``Update.xml`` for submission with the :command:`ctest_submit` command.
+
+The options are:
+
+``SOURCE <source-dir>``
+ Specify the source directory. If not given, the
+ :variable:`CTEST_SOURCE_DIRECTORY` variable is used.
+
+``RETURN_VALUE <result-var>``
+ Store in the ``<result-var>`` variable the number of files
+ updated or ``-1`` on error.
+
+``QUIET``
+ Tell CTest to suppress most non-error messages that it would
+ have otherwise printed to the console. CTest will still report
+ the new revision of the repository and any conflicting files
+ that were found.
diff --git a/Help/command/ctest_upload.rst b/Help/command/ctest_upload.rst
new file mode 100644
index 000000000..d9630d2ae
--- /dev/null
+++ b/Help/command/ctest_upload.rst
@@ -0,0 +1,18 @@
+ctest_upload
+------------
+
+Upload files to a dashboard server as a :ref:`Dashboard Client`.
+
+::
+
+ ctest_upload(FILES <file>... [QUIET])
+
+The options are:
+
+``FILES <file>...``
+ Specify a list of files to be sent along with the build results to the
+ dashboard server.
+
+``QUIET``
+ Suppress any CTest-specific non-error output that would have been
+ printed to the console otherwise.
diff --git a/Help/command/define_property.rst b/Help/command/define_property.rst
new file mode 100644
index 000000000..873c6cabb
--- /dev/null
+++ b/Help/command/define_property.rst
@@ -0,0 +1,45 @@
+define_property
+---------------
+
+Define and document custom properties.
+
+::
+
+ define_property(<GLOBAL | DIRECTORY | TARGET | SOURCE |
+ TEST | VARIABLE | CACHED_VARIABLE>
+ PROPERTY <name> [INHERITED]
+ BRIEF_DOCS <brief-doc> [docs...]
+ FULL_DOCS <full-doc> [docs...])
+
+Define one property in a scope for use with the :command:`set_property` and
+:command:`get_property` commands. This is primarily useful to associate
+documentation with property names that may be retrieved with the
+:command:`get_property` command. The first argument determines the kind of
+scope in which the property should be used. It must be one of the
+following:
+
+::
+
+ GLOBAL = associated with the global namespace
+ DIRECTORY = associated with one directory
+ TARGET = associated with one target
+ SOURCE = associated with one source file
+ TEST = associated with a test named with add_test
+ VARIABLE = documents a CMake language variable
+ CACHED_VARIABLE = documents a CMake cache variable
+
+Note that unlike :command:`set_property` and :command:`get_property` no
+actual scope needs to be given; only the kind of scope is important.
+
+The required ``PROPERTY`` option is immediately followed by the name of
+the property being defined.
+
+If the ``INHERITED`` option then the :command:`get_property` command will
+chain up to the next higher scope when the requested property is not set
+in the scope given to the command. ``DIRECTORY`` scope chains to
+``GLOBAL``. ``TARGET``, ``SOURCE``, and ``TEST`` chain to ``DIRECTORY``.
+
+The ``BRIEF_DOCS`` and ``FULL_DOCS`` options are followed by strings to be
+associated with the property as its brief and full documentation.
+Corresponding options to the :command:`get_property` command will retrieve
+the documentation.
diff --git a/Help/command/else.rst b/Help/command/else.rst
new file mode 100644
index 000000000..0e5a19810
--- /dev/null
+++ b/Help/command/else.rst
@@ -0,0 +1,10 @@
+else
+----
+
+Starts the else portion of an if block.
+
+::
+
+ else(expression)
+
+See the :command:`if` command.
diff --git a/Help/command/elseif.rst b/Help/command/elseif.rst
new file mode 100644
index 000000000..9a8dfed1d
--- /dev/null
+++ b/Help/command/elseif.rst
@@ -0,0 +1,10 @@
+elseif
+------
+
+Starts the elseif portion of an if block.
+
+::
+
+ elseif(expression)
+
+See the :command:`if` command.
diff --git a/Help/command/enable_language.rst b/Help/command/enable_language.rst
new file mode 100644
index 000000000..444556151
--- /dev/null
+++ b/Help/command/enable_language.rst
@@ -0,0 +1,22 @@
+enable_language
+---------------
+
+Enable a language (CXX/C/Fortran/etc)
+
+::
+
+ enable_language(<lang> [OPTIONAL] )
+
+This command enables support for the named language in CMake. This is
+the same as the project command but does not create any of the extra
+variables that are created by the project command. Example languages
+are CXX, C, Fortran.
+
+This command must be called in file scope, not in a function call.
+Furthermore, it must be called in the highest directory common to all
+targets using the named language directly for compiling sources or
+indirectly through link dependencies. It is simplest to enable all
+needed languages in the top-level directory of a project.
+
+The ``OPTIONAL`` keyword is a placeholder for future implementation and
+does not currently work.
diff --git a/Help/command/enable_testing.rst b/Help/command/enable_testing.rst
new file mode 100644
index 000000000..1e3e2799c
--- /dev/null
+++ b/Help/command/enable_testing.rst
@@ -0,0 +1,13 @@
+enable_testing
+--------------
+
+Enable testing for current directory and below.
+
+::
+
+ enable_testing()
+
+Enables testing for this directory and below. See also the
+:command:`add_test` command. Note that ctest expects to find a test file
+in the build directory root. Therefore, this command should be in the
+source directory root.
diff --git a/Help/command/endforeach.rst b/Help/command/endforeach.rst
new file mode 100644
index 000000000..9af972bee
--- /dev/null
+++ b/Help/command/endforeach.rst
@@ -0,0 +1,10 @@
+endforeach
+----------
+
+Ends a list of commands in a foreach block.
+
+::
+
+ endforeach(expression)
+
+See the :command:`foreach` command.
diff --git a/Help/command/endfunction.rst b/Help/command/endfunction.rst
new file mode 100644
index 000000000..6cc196cde
--- /dev/null
+++ b/Help/command/endfunction.rst
@@ -0,0 +1,10 @@
+endfunction
+-----------
+
+Ends a list of commands in a function block.
+
+::
+
+ endfunction(expression)
+
+See the :command:`function` command.
diff --git a/Help/command/endif.rst b/Help/command/endif.rst
new file mode 100644
index 000000000..a0163bf33
--- /dev/null
+++ b/Help/command/endif.rst
@@ -0,0 +1,10 @@
+endif
+-----
+
+Ends a list of commands in an if block.
+
+::
+
+ endif(expression)
+
+See the :command:`if` command.
diff --git a/Help/command/endmacro.rst b/Help/command/endmacro.rst
new file mode 100644
index 000000000..47327a783
--- /dev/null
+++ b/Help/command/endmacro.rst
@@ -0,0 +1,10 @@
+endmacro
+--------
+
+Ends a list of commands in a macro block.
+
+::
+
+ endmacro(expression)
+
+See the :command:`macro` command.
diff --git a/Help/command/endwhile.rst b/Help/command/endwhile.rst
new file mode 100644
index 000000000..798c20e71
--- /dev/null
+++ b/Help/command/endwhile.rst
@@ -0,0 +1,10 @@
+endwhile
+--------
+
+Ends a list of commands in a while block.
+
+::
+
+ endwhile(expression)
+
+See the :command:`while` command.
diff --git a/Help/command/exec_program.rst b/Help/command/exec_program.rst
new file mode 100644
index 000000000..6dfdad394
--- /dev/null
+++ b/Help/command/exec_program.rst
@@ -0,0 +1,24 @@
+exec_program
+------------
+
+Deprecated. Use the :command:`execute_process` command instead.
+
+Run an executable program during the processing of the CMakeList.txt
+file.
+
+::
+
+ exec_program(Executable [directory in which to run]
+ [ARGS <arguments to executable>]
+ [OUTPUT_VARIABLE <var>]
+ [RETURN_VALUE <var>])
+
+The executable is run in the optionally specified directory. The
+executable can include arguments if it is double quoted, but it is
+better to use the optional ``ARGS`` argument to specify arguments to the
+program. This is because cmake will then be able to escape spaces in
+the executable path. An optional argument ``OUTPUT_VARIABLE`` specifies a
+variable in which to store the output. To capture the return value of
+the execution, provide a ``RETURN_VALUE``. If ``OUTPUT_VARIABLE`` is
+specified, then no output will go to the stdout/stderr of the console
+running cmake.
diff --git a/Help/command/execute_process.rst b/Help/command/execute_process.rst
new file mode 100644
index 000000000..ca44b534c
--- /dev/null
+++ b/Help/command/execute_process.rst
@@ -0,0 +1,76 @@
+execute_process
+---------------
+
+Execute one or more child processes.
+
+.. code-block:: cmake
+
+ execute_process(COMMAND <cmd1> [args1...]]
+ [COMMAND <cmd2> [args2...] [...]]
+ [WORKING_DIRECTORY <directory>]
+ [TIMEOUT <seconds>]
+ [RESULT_VARIABLE <variable>]
+ [OUTPUT_VARIABLE <variable>]
+ [ERROR_VARIABLE <variable>]
+ [INPUT_FILE <file>]
+ [OUTPUT_FILE <file>]
+ [ERROR_FILE <file>]
+ [OUTPUT_QUIET]
+ [ERROR_QUIET]
+ [OUTPUT_STRIP_TRAILING_WHITESPACE]
+ [ERROR_STRIP_TRAILING_WHITESPACE])
+
+Runs the given sequence of one or more commands with the standard
+output of each process piped to the standard input of the next.
+A single standard error pipe is used for all processes.
+
+Options:
+
+``COMMAND``
+ A child process command line.
+
+ CMake executes the child process using operating system APIs directly.
+ All arguments are passed VERBATIM to the child process.
+ No intermediate shell is used, so shell operators such as ``>``
+ are treated as normal arguments.
+ (Use the ``INPUT_*``, ``OUTPUT_*``, and ``ERROR_*`` options to
+ redirect stdin, stdout, and stderr.)
+
+``WORKING_DIRECTORY``
+ The named directory will be set as the current working directory of
+ the child processes.
+
+``TIMEOUT``
+ The child processes will be terminated if they do not finish in the
+ specified number of seconds (fractions are allowed).
+
+``RESULT_VARIABLE``
+ The variable will be set to contain the result of running the processes.
+ This will be an integer return code from the last child or a string
+ describing an error condition.
+
+``OUTPUT_VARIABLE``, ``ERROR_VARIABLE``
+ The variable named will be set with the contents of the standard output
+ and standard error pipes, respectively. If the same variable is named
+ for both pipes their output will be merged in the order produced.
+
+``INPUT_FILE, OUTPUT_FILE``, ``ERROR_FILE``
+ The file named will be attached to the standard input of the first
+ process, standard output of the last process, or standard error of
+ all processes, respectively. If the same file is named for both
+ output and error then it will be used for both.
+
+``OUTPUT_QUIET``, ``ERROR_QUIET``
+ The standard output or standard error results will be quietly ignored.
+
+If more than one ``OUTPUT_*`` or ``ERROR_*`` option is given for the
+same pipe the precedence is not specified.
+If no ``OUTPUT_*`` or ``ERROR_*`` options are given the output will
+be shared with the corresponding pipes of the CMake process itself.
+
+The :command:`execute_process` command is a newer more powerful version of
+:command:`exec_program`, but the old command has been kept for compatibility.
+Both commands run while CMake is processing the project prior to build
+system generation. Use :command:`add_custom_target` and
+:command:`add_custom_command` to create custom commands that run at
+build time.
diff --git a/Help/command/export.rst b/Help/command/export.rst
new file mode 100644
index 000000000..4419dc120
--- /dev/null
+++ b/Help/command/export.rst
@@ -0,0 +1,57 @@
+export
+------
+
+Export targets from the build tree for use by outside projects.
+
+::
+
+ export(EXPORT <export-name> [NAMESPACE <namespace>] [FILE <filename>])
+
+Create a file ``<filename>`` that may be included by outside projects to
+import targets from the current project's build tree. This is useful
+during cross-compiling to build utility executables that can run on
+the host platform in one project and then import them into another
+project being compiled for the target platform. If the ``NAMESPACE``
+option is given the ``<namespace>`` string will be prepended to all target
+names written to the file.
+
+Target installations are associated with the export ``<export-name>``
+using the ``EXPORT`` option of the :command:`install(TARGETS)` command.
+
+The file created by this command is specific to the build tree and
+should never be installed. See the :command:`install(EXPORT)` command to
+export targets from an installation tree.
+
+The properties set on the generated IMPORTED targets will have the
+same values as the final values of the input TARGETS.
+
+::
+
+ export(TARGETS [target1 [target2 [...]]] [NAMESPACE <namespace>]
+ [APPEND] FILE <filename> [EXPORT_LINK_INTERFACE_LIBRARIES])
+
+This signature is similar to the ``EXPORT`` signature, but targets are listed
+explicitly rather than specified as an export-name. If the APPEND option is
+given the generated code will be appended to the file instead of overwriting it.
+The EXPORT_LINK_INTERFACE_LIBRARIES keyword, if present, causes the
+contents of the properties matching
+``(IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)?`` to be exported, when
+policy CMP0022 is NEW. If a library target is included in the export
+but a target to which it links is not included the behavior is
+unspecified.
+
+::
+
+ export(PACKAGE <name>)
+
+Store the current build directory in the CMake user package registry
+for package ``<name>``. The find_package command may consider the
+directory while searching for package ``<name>``. This helps dependent
+projects find and use a package from the current project's build tree
+without help from the user. Note that the entry in the package
+registry that this command creates works only in conjunction with a
+package configuration file (``<name>Config.cmake``) that works with the
+build tree. In some cases, for example for packaging and for system
+wide installations, it is not desirable to write the user package
+registry. If the :variable:`CMAKE_EXPORT_NO_PACKAGE_REGISTRY` variable
+is enabled, the ``export(PACKAGE)`` command will do nothing.
diff --git a/Help/command/export_library_dependencies.rst b/Help/command/export_library_dependencies.rst
new file mode 100644
index 000000000..2cb437e77
--- /dev/null
+++ b/Help/command/export_library_dependencies.rst
@@ -0,0 +1,28 @@
+export_library_dependencies
+---------------------------
+
+Disallowed. See CMake Policy :policy:`CMP0033`.
+
+Use :command:`install(EXPORT)` or :command:`export` command.
+
+This command generates an old-style library dependencies file.
+Projects requiring CMake 2.6 or later should not use the command. Use
+instead the :command:`install(EXPORT)` command to help export targets from an
+installation tree and the :command:`export` command to export targets from a
+build tree.
+
+The old-style library dependencies file does not take into account
+per-configuration names of libraries or the
+:prop_tgt:`LINK_INTERFACE_LIBRARIES` target property.
+
+::
+
+ export_library_dependencies(<file> [APPEND])
+
+Create a file named ``<file>`` that can be included into a CMake listfile
+with the INCLUDE command. The file will contain a number of SET
+commands that will set all the variables needed for library dependency
+information. This should be the last command in the top level
+CMakeLists.txt file of the project. If the ``APPEND`` option is
+specified, the SET commands will be appended to the given file instead
+of replacing it.
diff --git a/Help/command/file.rst b/Help/command/file.rst
new file mode 100644
index 000000000..96ac6c72a
--- /dev/null
+++ b/Help/command/file.rst
@@ -0,0 +1,358 @@
+file
+----
+
+File manipulation command.
+
+------------------------------------------------------------------------------
+
+::
+
+ file(WRITE <filename> <content>...)
+ file(APPEND <filename> <content>...)
+
+Write ``<content>`` into a file called ``<filename>``. If the file does
+not exist, it will be created. If the file already exists, ``WRITE``
+mode will overwrite it and ``APPEND`` mode will append to the end.
+(If the file is a build input, use the :command:`configure_file` command
+to update the file only when its content changes.)
+
+------------------------------------------------------------------------------
+
+::
+
+ file(READ <filename> <variable>
+ [OFFSET <offset>] [LIMIT <max-in>] [HEX])
+
+Read content from a file called ``<filename>`` and store it in a
+``<variable>``. Optionally start from the given ``<offset>`` and
+read at most ``<max-in>`` bytes. The ``HEX`` option causes data to
+be converted to a hexadecimal representation (useful for binary data).
+
+------------------------------------------------------------------------------
+
+::
+
+ file(STRINGS <filename> <variable> [<options>...])
+
+Parse a list of ASCII strings from ``<filename>`` and store it in
+``<variable>``. Binary data in the file are ignored. Carriage return
+(``\r``, CR) characters are ignored. The options are:
+
+``LENGTH_MAXIMUM <max-len>``
+ Consider only strings of at most a given length.
+
+``LENGTH_MINIMUM <min-len>``
+ Consider only strings of at least a given length.
+
+``LIMIT_COUNT <max-num>``
+ Limit the number of distinct strings to be extracted.
+
+``LIMIT_INPUT <max-in>``
+ Limit the number of input bytes to read from the file.
+
+``LIMIT_OUTPUT <max-out>``
+ Limit the number of total bytes to store in the ``<variable>``.
+
+``NEWLINE_CONSUME``
+ Treat newline characters (``\n``, LF) as part of string content
+ instead of terminating at them.
+
+``NO_HEX_CONVERSION``
+ Intel Hex and Motorola S-record files are automatically converted to
+ binary while reading unless this option is given.
+
+``REGEX <regex>``
+ Consider only strings that match the given regular expression.
+
+``ENCODING <encoding-type>``
+ Consider strings of a given encoding. Currently supported encodings are:
+ UTF-8, UTF-16LE, UTF-16BE, UTF-32LE, UTF-32BE. If the ENCODING option
+ is not provided and the file has a Byte Order Mark, the ENCODING option
+ will be defaulted to respect the Byte Order Mark.
+
+For example, the code
+
+.. code-block:: cmake
+
+ file(STRINGS myfile.txt myfile)
+
+stores a list in the variable ``myfile`` in which each item is a line
+from the input file.
+
+------------------------------------------------------------------------------
+
+::
+
+ file(<MD5|SHA1|SHA224|SHA256|SHA384|SHA512> <filename> <variable>)
+
+Compute a cryptographic hash of the content of ``<filename>`` and
+store it in a ``<variable>``.
+
+------------------------------------------------------------------------------
+
+::
+
+ file(GLOB <variable>
+ [LIST_DIRECTORIES true|false] [RELATIVE <path>]
+ [<globbing-expressions>...])
+ file(GLOB_RECURSE <variable> [FOLLOW_SYMLINKS]
+ [LIST_DIRECTORIES true|false] [RELATIVE <path>]
+ [<globbing-expressions>...])
+
+Generate a list of files that match the ``<globbing-expressions>`` and
+store it into the ``<variable>``. Globbing expressions are similar to
+regular expressions, but much simpler. If ``RELATIVE`` flag is
+specified, the results will be returned as relative paths to the given
+path. No specific order of results is defined. If order is important then
+sort the list explicitly (e.g. using the :command:`list(SORT)` command).
+
+By default ``GLOB`` lists directories - directories are omited in result if
+``LIST_DIRECTORIES`` is set to false.
+
+.. note::
+ We do not recommend using GLOB to collect a list of source files from
+ your source tree. If no CMakeLists.txt file changes when a source is
+ added or removed then the generated build system cannot know when to
+ ask CMake to regenerate.
+
+Examples of globbing expressions include::
+
+ *.cxx - match all files with extension cxx
+ *.vt? - match all files with extension vta,...,vtz
+ f[3-5].txt - match files f3.txt, f4.txt, f5.txt
+
+The ``GLOB_RECURSE`` mode will traverse all the subdirectories of the
+matched directory and match the files. Subdirectories that are symlinks
+are only traversed if ``FOLLOW_SYMLINKS`` is given or policy
+:policy:`CMP0009` is not set to ``NEW``.
+
+By default ``GLOB_RECURSE`` omits directories from result list - setting
+``LIST_DIRECTORIES`` to true adds directories to result list.
+If ``FOLLOW_SYMLINKS`` is given or policy :policy:`CMP0009` is not set to
+``OLD`` then ``LIST_DIRECTORIES`` treats symlinks as directories.
+
+Examples of recursive globbing include::
+
+ /dir/*.py - match all python files in /dir and subdirectories
+
+------------------------------------------------------------------------------
+
+::
+
+ file(RENAME <oldname> <newname>)
+
+Move a file or directory within a filesystem from ``<oldname>`` to
+``<newname>``, replacing the destination atomically.
+
+------------------------------------------------------------------------------
+
+::
+
+ file(REMOVE [<files>...])
+ file(REMOVE_RECURSE [<files>...])
+
+Remove the given files. The ``REMOVE_RECURSE`` mode will remove the given
+files and directories, also non-empty directories
+
+------------------------------------------------------------------------------
+
+::
+
+ file(MAKE_DIRECTORY [<directories>...])
+
+Create the given directories and their parents as needed.
+
+------------------------------------------------------------------------------
+
+::
+
+ file(RELATIVE_PATH <variable> <directory> <file>)
+
+Compute the relative path from a ``<directory>`` to a ``<file>`` and
+store it in the ``<variable>``.
+
+------------------------------------------------------------------------------
+
+::
+
+ file(TO_CMAKE_PATH "<path>" <variable>)
+ file(TO_NATIVE_PATH "<path>" <variable>)
+
+The ``TO_CMAKE_PATH`` mode converts a native ``<path>`` into a cmake-style
+path with forward-slashes (``/``). The input can be a single path or a
+system search path like ``$ENV{PATH}``. A search path will be converted
+to a cmake-style list separated by ``;`` characters.
+
+The ``TO_NATIVE_PATH`` mode converts a cmake-style ``<path>`` into a native
+path with platform-specific slashes (``\`` on Windows and ``/`` elsewhere).
+
+Always use double quotes around the ``<path>`` to be sure it is treated
+as a single argument to this command.
+
+------------------------------------------------------------------------------
+
+::
+
+ file(DOWNLOAD <url> <file> [<options>...])
+ file(UPLOAD <file> <url> [<options>...])
+
+The ``DOWNLOAD`` mode downloads the given ``<url>`` to a local ``<file>``.
+The ``UPLOAD`` mode uploads a local ``<file>`` to a given ``<url>``.
+
+Options to both ``DOWNLOAD`` and ``UPLOAD`` are:
+
+``INACTIVITY_TIMEOUT <seconds>``
+ Terminate the operation after a period of inactivity.
+
+``LOG <variable>``
+ Store a human-readable log of the operation in a variable.
+
+``SHOW_PROGRESS``
+ Print progress information as status messages until the operation is
+ complete.
+
+``STATUS <variable>``
+ Store the resulting status of the operation in a variable.
+ The status is a ``;`` separated list of length 2.
+ The first element is the numeric return value for the operation,
+ and the second element is a string value for the error.
+ A ``0`` numeric error means no error in the operation.
+
+``TIMEOUT <seconds>``
+ Terminate the operation after a given total time has elapsed.
+
+Additional options to ``DOWNLOAD`` are:
+
+``EXPECTED_HASH ALGO=<value>``
+
+ Verify that the downloaded content hash matches the expected value, where
+ ``ALGO`` is one of ``MD5``, ``SHA1``, ``SHA224``, ``SHA256``, ``SHA384``, or
+ ``SHA512``. If it does not match, the operation fails with an error.
+
+``EXPECTED_MD5 <value>``
+ Historical short-hand for ``EXPECTED_HASH MD5=<value>``.
+
+``TLS_VERIFY <ON|OFF>``
+ Specify whether to verify the server certificate for ``https://`` URLs.
+ The default is to *not* verify.
+
+``TLS_CAINFO <file>``
+ Specify a custom Certificate Authority file for ``https://`` URLs.
+
+For ``https://`` URLs CMake must be built with OpenSSL support. ``TLS/SSL``
+certificates are not checked by default. Set ``TLS_VERIFY`` to ``ON`` to
+check certificates and/or use ``EXPECTED_HASH`` to verify downloaded content.
+If neither ``TLS`` option is given CMake will check variables
+``CMAKE_TLS_VERIFY`` and ``CMAKE_TLS_CAINFO``, respectively.
+
+------------------------------------------------------------------------------
+
+::
+
+ file(TIMESTAMP <filename> <variable> [<format>] [UTC])
+
+Compute a string representation of the modification time of ``<filename>``
+and store it in ``<variable>``. Should the command be unable to obtain a
+timestamp variable will be set to the empty string ("").
+
+See the :command:`string(TIMESTAMP)` command for documentation of
+the ``<format>`` and ``UTC`` options.
+
+------------------------------------------------------------------------------
+
+::
+
+ file(GENERATE OUTPUT output-file
+ <INPUT input-file|CONTENT content>
+ [CONDITION expression])
+
+Generate an output file for each build configuration supported by the current
+:manual:`CMake Generator <cmake-generators(7)>`. Evaluate
+:manual:`generator expressions <cmake-generator-expressions(7)>`
+from the input content to produce the output content. The options are:
+
+``CONDITION <condition>``
+ Generate the output file for a particular configuration only if
+ the condition is true. The condition must be either ``0`` or ``1``
+ after evaluating generator expressions.
+
+``CONTENT <content>``
+ Use the content given explicitly as input.
+
+``INPUT <input-file>``
+ Use the content from a given file as input.
+
+``OUTPUT <output-file>``
+ Specify the output file name to generate. Use generator expressions
+ such as ``$<CONFIG>`` to specify a configuration-specific output file
+ name. Multiple configurations may generate the same output file only
+ if the generated content is identical. Otherwise, the ``<output-file>``
+ must evaluate to an unique name for each configuration.
+
+Exactly one ``CONTENT`` or ``INPUT`` option must be given. A specific
+``OUTPUT`` file may be named by at most one invocation of ``file(GENERATE)``.
+Generated files are modified on subsequent cmake runs only if their content
+is changed.
+
+------------------------------------------------------------------------------
+
+::
+
+ file(<COPY|INSTALL> <files>... DESTINATION <dir>
+ [FILE_PERMISSIONS <permissions>...]
+ [DIRECTORY_PERMISSIONS <permissions>...]
+ [NO_SOURCE_PERMISSIONS] [USE_SOURCE_PERMISSIONS]
+ [FILES_MATCHING]
+ [[PATTERN <pattern> | REGEX <regex>]
+ [EXCLUDE] [PERMISSIONS <permissions>...]] [...])
+
+The ``COPY`` signature copies files, directories, and symlinks to a
+destination folder. Relative input paths are evaluated with respect
+to the current source directory, and a relative destination is
+evaluated with respect to the current build directory. Copying
+preserves input file timestamps, and optimizes out a file if it exists
+at the destination with the same timestamp. Copying preserves input
+permissions unless explicit permissions or ``NO_SOURCE_PERMISSIONS``
+are given (default is ``USE_SOURCE_PERMISSIONS``).
+
+See the :command:`install(DIRECTORY)` command for documentation of
+permissions, ``FILES_MATCHING``, ``PATTERN``, ``REGEX``, and
+``EXCLUDE`` options. Copying directories preserves the structure
+of their content even if options are used to select a subset of
+files.
+
+The ``INSTALL`` signature differs slightly from ``COPY``: it prints
+status messages (subject to the :variable:`CMAKE_INSTALL_MESSAGE` variable),
+and ``NO_SOURCE_PERMISSIONS`` is default.
+Installation scripts generated by the :command:`install` command
+use this signature (with some undocumented options for internal use).
+
+------------------------------------------------------------------------------
+
+::
+
+ file(LOCK <path> [DIRECTORY] [RELEASE]
+ [GUARD <FUNCTION|FILE|PROCESS>]
+ [RESULT_VARIABLE <variable>]
+ [TIMEOUT <seconds>])
+
+Lock a file specified by ``<path>`` if no ``DIRECTORY`` option present and file
+``<path>/cmake.lock`` otherwise. File will be locked for scope defined by
+``GUARD`` option (default value is ``PROCESS``). ``RELEASE`` option can be used
+to unlock file explicitly. If option ``TIMEOUT`` is not specified CMake will
+wait until lock succeed or until fatal error occurs. If ``TIMEOUT`` is set to
+``0`` lock will be tried once and result will be reported immediately. If
+``TIMEOUT`` is not ``0`` CMake will try to lock file for the period specified
+by ``<seconds>`` value. Any errors will be interpreted as fatal if there is no
+``RESULT_VARIABLE`` option. Otherwise result will be stored in ``<variable>``
+and will be ``0`` on success or error message on failure.
+
+Note that lock is advisory - there is no guarantee that other processes will
+respect this lock, i.e. lock synchronize two or more CMake instances sharing
+some modifiable resources. Similar logic applied to ``DIRECTORY`` option -
+locking parent directory doesn't prevent other ``LOCK`` commands to lock any
+child directory or file.
+
+Trying to lock file twice is not allowed. Any intermediate directories and
+file itself will be created if they not exist. ``GUARD`` and ``TIMEOUT``
+options ignored on ``RELEASE`` operation.
diff --git a/Help/command/find_file.rst b/Help/command/find_file.rst
new file mode 100644
index 000000000..bf7a91993
--- /dev/null
+++ b/Help/command/find_file.rst
@@ -0,0 +1,33 @@
+find_file
+---------
+
+.. |FIND_XXX| replace:: find_file
+.. |NAMES| replace:: NAMES name1 [name2 ...]
+.. |SEARCH_XXX| replace:: full path to a file
+.. |SEARCH_XXX_DESC| replace:: full path to named file
+.. |prefix_XXX_SUBDIR| replace:: ``<prefix>/include``
+.. |entry_XXX_SUBDIR| replace:: ``<entry>/include``
+
+.. |CMAKE_PREFIX_PATH_XXX| replace::
+ ``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE`
+ is set, and |CMAKE_PREFIX_PATH_XXX_SUBDIR|
+.. |CMAKE_XXX_PATH| replace:: :variable:`CMAKE_INCLUDE_PATH`
+.. |CMAKE_XXX_MAC_PATH| replace:: :variable:`CMAKE_FRAMEWORK_PATH`
+
+.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: Directories in ``INCLUDE``,
+ ``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE`
+ is set, and |SYSTEM_ENVIRONMENT_PREFIX_PATH_XXX_SUBDIR|, and the
+ directories in ``PATH`` itself.
+
+.. |CMAKE_SYSTEM_PREFIX_PATH_XXX| replace::
+ ``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE`
+ is set, and |CMAKE_SYSTEM_PREFIX_PATH_XXX_SUBDIR|
+.. |CMAKE_SYSTEM_XXX_PATH| replace::
+ :variable:`CMAKE_SYSTEM_INCLUDE_PATH`
+.. |CMAKE_SYSTEM_XXX_MAC_PATH| replace::
+ :variable:`CMAKE_SYSTEM_FRAMEWORK_PATH`
+
+.. |CMAKE_FIND_ROOT_PATH_MODE_XXX| replace::
+ :variable:`CMAKE_FIND_ROOT_PATH_MODE_INCLUDE`
+
+.. include:: FIND_XXX.txt
diff --git a/Help/command/find_library.rst b/Help/command/find_library.rst
new file mode 100644
index 000000000..5d07574ad
--- /dev/null
+++ b/Help/command/find_library.rst
@@ -0,0 +1,56 @@
+find_library
+------------
+
+.. |FIND_XXX| replace:: find_library
+.. |NAMES| replace:: NAMES name1 [name2 ...] [NAMES_PER_DIR]
+.. |SEARCH_XXX| replace:: library
+.. |SEARCH_XXX_DESC| replace:: library
+.. |prefix_XXX_SUBDIR| replace:: ``<prefix>/lib``
+.. |entry_XXX_SUBDIR| replace:: ``<entry>/lib``
+
+.. |CMAKE_PREFIX_PATH_XXX| replace::
+ ``<prefix>/lib/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE` is set,
+ and |CMAKE_PREFIX_PATH_XXX_SUBDIR|
+.. |CMAKE_XXX_PATH| replace:: :variable:`CMAKE_LIBRARY_PATH`
+.. |CMAKE_XXX_MAC_PATH| replace:: :variable:`CMAKE_FRAMEWORK_PATH`
+
+.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: Directories in ``LIB``,
+ ``<prefix>/lib/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE` is set,
+ and |SYSTEM_ENVIRONMENT_PREFIX_PATH_XXX_SUBDIR|,
+ and the directories in ``PATH`` itself.
+
+.. |CMAKE_SYSTEM_PREFIX_PATH_XXX| replace::
+ ``<prefix>/lib/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE` is set,
+ and |CMAKE_SYSTEM_PREFIX_PATH_XXX_SUBDIR|
+.. |CMAKE_SYSTEM_XXX_PATH| replace::
+ :variable:`CMAKE_SYSTEM_LIBRARY_PATH`
+.. |CMAKE_SYSTEM_XXX_MAC_PATH| replace::
+ :variable:`CMAKE_SYSTEM_FRAMEWORK_PATH`
+
+.. |CMAKE_FIND_ROOT_PATH_MODE_XXX| replace::
+ :variable:`CMAKE_FIND_ROOT_PATH_MODE_LIBRARY`
+
+.. include:: FIND_XXX.txt
+
+When more than one value is given to the ``NAMES`` option this command by
+default will consider one name at a time and search every directory
+for it. The ``NAMES_PER_DIR`` option tells this command to consider one
+directory at a time and search for all names in it.
+
+Each library name given to the ``NAMES`` option is first considered
+as a library file name and then considered with platform-specific
+prefixes (e.g. ``lib``) and suffixes (e.g. ``.so``). Therefore one
+may specify library file names such as ``libfoo.a`` directly.
+This can be used to locate static libraries on UNIX-like systems.
+
+If the library found is a framework, then ``<VAR>`` will be set to the full
+path to the framework ``<fullPath>/A.framework``. When a full path to a
+framework is used as a library, CMake will use a ``-framework A``, and a
+``-F<fullPath>`` to link the framework to the target.
+
+If the :prop_gbl:`FIND_LIBRARY_USE_LIB64_PATHS` global property is set
+all search paths will be tested as normal, with ``64/`` appended, and
+with all matches of ``lib/`` replaced with ``lib64/``. This property is
+automatically set for the platforms that are known to need it if at
+least one of the languages supported by the :command:`project` command
+is enabled.
diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst
new file mode 100644
index 000000000..58dff9d39
--- /dev/null
+++ b/Help/command/find_package.rst
@@ -0,0 +1,344 @@
+find_package
+------------
+
+Load settings for an external project.
+
+::
+
+ find_package(<package> [version] [EXACT] [QUIET] [MODULE]
+ [REQUIRED] [[COMPONENTS] [components...]]
+ [OPTIONAL_COMPONENTS components...]
+ [NO_POLICY_SCOPE])
+
+Finds and loads settings from an external project. ``<package>_FOUND``
+will be set to indicate whether the package was found. When the
+package is found package-specific information is provided through
+variables and :ref:`Imported Targets` documented by the package itself. The
+``QUIET`` option disables messages if the package cannot be found. The
+``MODULE`` option disables the second signature documented below. The
+``REQUIRED`` option stops processing with an error message if the package
+cannot be found.
+
+A package-specific list of required components may be listed after the
+``COMPONENTS`` option (or after the ``REQUIRED`` option if present).
+Additional optional components may be listed after
+``OPTIONAL_COMPONENTS``. Available components and their influence on
+whether a package is considered to be found are defined by the target
+package.
+
+The ``[version]`` argument requests a version with which the package found
+should be compatible (format is ``major[.minor[.patch[.tweak]]]``). The
+``EXACT`` option requests that the version be matched exactly. If no
+``[version]`` and/or component list is given to a recursive invocation
+inside a find-module, the corresponding arguments are forwarded
+automatically from the outer call (including the ``EXACT`` flag for
+``[version]``). Version support is currently provided only on a
+package-by-package basis (details below).
+
+User code should generally look for packages using the above simple
+signature. The remainder of this command documentation specifies the
+full command signature and details of the search process. Project
+maintainers wishing to provide a package to be found by this command
+are encouraged to read on.
+
+The command has two modes by which it searches for packages: "Module"
+mode and "Config" mode. Module mode is available when the command is
+invoked with the above reduced signature. CMake searches for a file
+called ``Find<package>.cmake`` in the :variable:`CMAKE_MODULE_PATH`
+followed by the CMake installation. If the file is found, it is read
+and processed by CMake. It is responsible for finding the package,
+checking the version, and producing any needed messages. Many
+find-modules provide limited or no support for versioning; check
+the module documentation. If no module is found and the ``MODULE``
+option is not given the command proceeds to Config mode.
+
+The complete Config mode command signature is::
+
+ find_package(<package> [version] [EXACT] [QUIET]
+ [REQUIRED] [[COMPONENTS] [components...]]
+ [CONFIG|NO_MODULE]
+ [NO_POLICY_SCOPE]
+ [NAMES name1 [name2 ...]]
+ [CONFIGS config1 [config2 ...]]
+ [HINTS path1 [path2 ... ]]
+ [PATHS path1 [path2 ... ]]
+ [PATH_SUFFIXES suffix1 [suffix2 ...]]
+ [NO_DEFAULT_PATH]
+ [NO_CMAKE_ENVIRONMENT_PATH]
+ [NO_CMAKE_PATH]
+ [NO_SYSTEM_ENVIRONMENT_PATH]
+ [NO_CMAKE_PACKAGE_REGISTRY]
+ [NO_CMAKE_BUILDS_PATH] # Deprecated; does nothing.
+ [NO_CMAKE_SYSTEM_PATH]
+ [NO_CMAKE_SYSTEM_PACKAGE_REGISTRY]
+ [CMAKE_FIND_ROOT_PATH_BOTH |
+ ONLY_CMAKE_FIND_ROOT_PATH |
+ NO_CMAKE_FIND_ROOT_PATH])
+
+The ``CONFIG`` option may be used to skip Module mode explicitly and
+switch to Config mode. It is synonymous to using ``NO_MODULE``. Config
+mode is also implied by use of options not specified in the reduced
+signature.
+
+Config mode attempts to locate a configuration file provided by the
+package to be found. A cache entry called ``<package>_DIR`` is created to
+hold the directory containing the file. By default the command
+searches for a package with the name ``<package>``. If the ``NAMES`` option
+is given the names following it are used instead of ``<package>``. The
+command searches for a file called ``<name>Config.cmake`` or
+``<lower-case-name>-config.cmake`` for each name specified. A
+replacement set of possible configuration file names may be given
+using the ``CONFIGS`` option. The search procedure is specified below.
+Once found, the configuration file is read and processed by CMake.
+Since the file is provided by the package it already knows the
+location of package contents. The full path to the configuration file
+is stored in the cmake variable ``<package>_CONFIG``.
+
+All configuration files which have been considered by CMake while
+searching for an installation of the package with an appropriate
+version are stored in the cmake variable ``<package>_CONSIDERED_CONFIGS``,
+the associated versions in ``<package>_CONSIDERED_VERSIONS``.
+
+If the package configuration file cannot be found CMake will generate
+an error describing the problem unless the ``QUIET`` argument is
+specified. If ``REQUIRED`` is specified and the package is not found a
+fatal error is generated and the configure step stops executing. If
+``<package>_DIR`` has been set to a directory not containing a
+configuration file CMake will ignore it and search from scratch.
+
+When the ``[version]`` argument is given Config mode will only find a
+version of the package that claims compatibility with the requested
+version (format is ``major[.minor[.patch[.tweak]]]``). If the ``EXACT``
+option is given only a version of the package claiming an exact match
+of the requested version may be found. CMake does not establish any
+convention for the meaning of version numbers. Package version
+numbers are checked by "version" files provided by the packages
+themselves. For a candidate package configuration file
+``<config-file>.cmake`` the corresponding version file is located next
+to it and named either ``<config-file>-version.cmake`` or
+``<config-file>Version.cmake``. If no such version file is available
+then the configuration file is assumed to not be compatible with any
+requested version. A basic version file containing generic version
+matching code can be created using the
+:module:`CMakePackageConfigHelpers` module. When a version file
+is found it is loaded to check the requested version number. The
+version file is loaded in a nested scope in which the following
+variables have been defined:
+
+``PACKAGE_FIND_NAME``
+ the ``<package>`` name
+``PACKAGE_FIND_VERSION``
+ full requested version string
+``PACKAGE_FIND_VERSION_MAJOR``
+ major version if requested, else 0
+``PACKAGE_FIND_VERSION_MINOR``
+ minor version if requested, else 0
+``PACKAGE_FIND_VERSION_PATCH``
+ patch version if requested, else 0
+``PACKAGE_FIND_VERSION_TWEAK``
+ tweak version if requested, else 0
+``PACKAGE_FIND_VERSION_COUNT``
+ number of version components, 0 to 4
+
+The version file checks whether it satisfies the requested version and
+sets these variables:
+
+``PACKAGE_VERSION``
+ full provided version string
+``PACKAGE_VERSION_EXACT``
+ true if version is exact match
+``PACKAGE_VERSION_COMPATIBLE``
+ true if version is compatible
+``PACKAGE_VERSION_UNSUITABLE``
+ true if unsuitable as any version
+
+These variables are checked by the ``find_package`` command to determine
+whether the configuration file provides an acceptable version. They
+are not available after the find_package call returns. If the version
+is acceptable the following variables are set:
+
+``<package>_VERSION``
+ full provided version string
+``<package>_VERSION_MAJOR``
+ major version if provided, else 0
+``<package>_VERSION_MINOR``
+ minor version if provided, else 0
+``<package>_VERSION_PATCH``
+ patch version if provided, else 0
+``<package>_VERSION_TWEAK``
+ tweak version if provided, else 0
+``<package>_VERSION_COUNT``
+ number of version components, 0 to 4
+
+and the corresponding package configuration file is loaded. When
+multiple package configuration files are available whose version files
+claim compatibility with the version requested it is unspecified which
+one is chosen. No attempt is made to choose a highest or closest
+version number.
+
+Config mode provides an elaborate interface and search procedure.
+Much of the interface is provided for completeness and for use
+internally by find-modules loaded by Module mode. Most user code
+should simply call::
+
+ find_package(<package> [major[.minor]] [EXACT] [REQUIRED|QUIET])
+
+in order to find a package. Package maintainers providing CMake
+package configuration files are encouraged to name and install them
+such that the procedure outlined below will find them without
+requiring use of additional options.
+
+CMake constructs a set of possible installation prefixes for the
+package. Under each prefix several directories are searched for a
+configuration file. The tables below show the directories searched.
+Each entry is meant for installation trees following Windows (W), UNIX
+(U), or Apple (A) conventions::
+
+ <prefix>/ (W)
+ <prefix>/(cmake|CMake)/ (W)
+ <prefix>/<name>*/ (W)
+ <prefix>/<name>*/(cmake|CMake)/ (W)
+ <prefix>/(lib/<arch>|lib|share)/cmake/<name>*/ (U)
+ <prefix>/(lib/<arch>|lib|share)/<name>*/ (U)
+ <prefix>/(lib/<arch>|lib|share)/<name>*/(cmake|CMake)/ (U)
+
+On systems supporting OS X Frameworks and Application Bundles the
+following directories are searched for frameworks or bundles
+containing a configuration file::
+
+ <prefix>/<name>.framework/Resources/ (A)
+ <prefix>/<name>.framework/Resources/CMake/ (A)
+ <prefix>/<name>.framework/Versions/*/Resources/ (A)
+ <prefix>/<name>.framework/Versions/*/Resources/CMake/ (A)
+ <prefix>/<name>.app/Contents/Resources/ (A)
+ <prefix>/<name>.app/Contents/Resources/CMake/ (A)
+
+In all cases the ``<name>`` is treated as case-insensitive and corresponds
+to any of the names specified (``<package>`` or names given by ``NAMES``).
+Paths with ``lib/<arch>`` are enabled if the
+:variable:`CMAKE_LIBRARY_ARCHITECTURE` variable is set. If ``PATH_SUFFIXES``
+is specified the suffixes are appended to each (W) or (U) directory entry
+one-by-one.
+
+This set of directories is intended to work in cooperation with
+projects that provide configuration files in their installation trees.
+Directories above marked with (W) are intended for installations on
+Windows where the prefix may point at the top of an application's
+installation directory. Those marked with (U) are intended for
+installations on UNIX platforms where the prefix is shared by multiple
+packages. This is merely a convention, so all (W) and (U) directories
+are still searched on all platforms. Directories marked with (A) are
+intended for installations on Apple platforms. The
+:variable:`CMAKE_FIND_FRAMEWORK` and :variable:`CMAKE_FIND_APPBUNDLE`
+variables determine the order of preference.
+
+The set of installation prefixes is constructed using the following
+steps. If ``NO_DEFAULT_PATH`` is specified all ``NO_*`` options are
+enabled.
+
+1. Search paths specified in cmake-specific cache variables. These
+ are intended to be used on the command line with a ``-DVAR=value``.
+ This can be skipped if ``NO_CMAKE_PATH`` is passed::
+
+ CMAKE_PREFIX_PATH
+ CMAKE_FRAMEWORK_PATH
+ CMAKE_APPBUNDLE_PATH
+
+2. Search paths specified in cmake-specific environment variables.
+ These are intended to be set in the user's shell configuration.
+ This can be skipped if ``NO_CMAKE_ENVIRONMENT_PATH`` is passed::
+
+ <package>_DIR
+ CMAKE_PREFIX_PATH
+ CMAKE_FRAMEWORK_PATH
+ CMAKE_APPBUNDLE_PATH
+
+3. Search paths specified by the ``HINTS`` option. These should be paths
+ computed by system introspection, such as a hint provided by the
+ location of another item already found. Hard-coded guesses should
+ be specified with the ``PATHS`` option.
+
+4. Search the standard system environment variables. This can be
+ skipped if ``NO_SYSTEM_ENVIRONMENT_PATH`` is passed. Path entries
+ ending in ``/bin`` or ``/sbin`` are automatically converted to their
+ parent directories::
+
+ PATH
+
+5. Search paths stored in the CMake :ref:`User Package Registry`.
+ This can be skipped if ``NO_CMAKE_PACKAGE_REGISTRY`` is passed or by
+ setting the :variable:`CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY`
+ to ``TRUE``.
+ See the :manual:`cmake-packages(7)` manual for details on the user
+ package registry.
+
+6. Search cmake variables defined in the Platform files for the
+ current system. This can be skipped if ``NO_CMAKE_SYSTEM_PATH`` is
+ passed::
+
+ CMAKE_SYSTEM_PREFIX_PATH
+ CMAKE_SYSTEM_FRAMEWORK_PATH
+ CMAKE_SYSTEM_APPBUNDLE_PATH
+
+7. Search paths stored in the CMake :ref:`System Package Registry`.
+ This can be skipped if ``NO_CMAKE_SYSTEM_PACKAGE_REGISTRY`` is passed
+ or by setting the
+ :variable:`CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY` to ``TRUE``.
+ See the :manual:`cmake-packages(7)` manual for details on the system
+ package registry.
+
+8. Search paths specified by the ``PATHS`` option. These are typically
+ hard-coded guesses.
+
+.. |FIND_XXX| replace:: find_package
+.. |FIND_ARGS_XXX| replace:: <package>
+.. |CMAKE_FIND_ROOT_PATH_MODE_XXX| replace::
+ :variable:`CMAKE_FIND_ROOT_PATH_MODE_PACKAGE`
+
+.. include:: FIND_XXX_ROOT.txt
+.. include:: FIND_XXX_ORDER.txt
+
+Every non-REQUIRED ``find_package`` call can be disabled by setting the
+:variable:`CMAKE_DISABLE_FIND_PACKAGE_<PackageName>` variable to ``TRUE``.
+
+When loading a find module or package configuration file ``find_package``
+defines variables to provide information about the call arguments (and
+restores their original state before returning):
+
+``CMAKE_FIND_PACKAGE_NAME``
+ the ``<package>`` name which is searched for
+``<package>_FIND_REQUIRED``
+ true if ``REQUIRED`` option was given
+``<package>_FIND_QUIETLY``
+ true if ``QUIET`` option was given
+``<package>_FIND_VERSION``
+ full requested version string
+``<package>_FIND_VERSION_MAJOR``
+ major version if requested, else 0
+``<package>_FIND_VERSION_MINOR``
+ minor version if requested, else 0
+``<package>_FIND_VERSION_PATCH``
+ patch version if requested, else 0
+``<package>_FIND_VERSION_TWEAK``
+ tweak version if requested, else 0
+``<package>_FIND_VERSION_COUNT``
+ number of version components, 0 to 4
+``<package>_FIND_VERSION_EXACT``
+ true if ``EXACT`` option was given
+``<package>_FIND_COMPONENTS``
+ list of requested components
+``<package>_FIND_REQUIRED_<c>``
+ true if component ``<c>`` is required,
+ false if component ``<c>`` is optional
+
+In Module mode the loaded find module is responsible to honor the
+request detailed by these variables; see the find module for details.
+In Config mode ``find_package`` handles ``REQUIRED``, ``QUIET``, and
+``[version]`` options automatically but leaves it to the package
+configuration file to handle components in a way that makes sense
+for the package. The package configuration file may set
+``<package>_FOUND`` to false to tell ``find_package`` that component
+requirements are not satisfied.
+
+See the :command:`cmake_policy` command documentation for discussion
+of the ``NO_POLICY_SCOPE`` option.
diff --git a/Help/command/find_path.rst b/Help/command/find_path.rst
new file mode 100644
index 000000000..4403cb5bc
--- /dev/null
+++ b/Help/command/find_path.rst
@@ -0,0 +1,38 @@
+find_path
+---------
+
+.. |FIND_XXX| replace:: find_path
+.. |NAMES| replace:: NAMES name1 [name2 ...]
+.. |SEARCH_XXX| replace:: file in a directory
+.. |SEARCH_XXX_DESC| replace:: directory containing the named file
+.. |prefix_XXX_SUBDIR| replace:: ``<prefix>/include``
+.. |entry_XXX_SUBDIR| replace:: ``<entry>/include``
+
+.. |CMAKE_PREFIX_PATH_XXX| replace::
+ ``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE`
+ is set, and |CMAKE_PREFIX_PATH_XXX_SUBDIR|
+.. |CMAKE_XXX_PATH| replace:: :variable:`CMAKE_INCLUDE_PATH`
+.. |CMAKE_XXX_MAC_PATH| replace:: :variable:`CMAKE_FRAMEWORK_PATH`
+
+.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: Directories in ``INCLUDE``,
+ ``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE`
+ is set, and |SYSTEM_ENVIRONMENT_PREFIX_PATH_XXX_SUBDIR|, and the
+ directories in ``PATH`` itself.
+
+.. |CMAKE_SYSTEM_PREFIX_PATH_XXX| replace::
+ ``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE`
+ is set, and |CMAKE_SYSTEM_PREFIX_PATH_XXX_SUBDIR|
+.. |CMAKE_SYSTEM_XXX_PATH| replace::
+ :variable:`CMAKE_SYSTEM_INCLUDE_PATH`
+.. |CMAKE_SYSTEM_XXX_MAC_PATH| replace::
+ :variable:`CMAKE_SYSTEM_FRAMEWORK_PATH`
+
+.. |CMAKE_FIND_ROOT_PATH_MODE_XXX| replace::
+ :variable:`CMAKE_FIND_ROOT_PATH_MODE_INCLUDE`
+
+.. include:: FIND_XXX.txt
+
+When searching for frameworks, if the file is specified as ``A/b.h``, then
+the framework search will look for ``A.framework/Headers/b.h``. If that
+is found the path will be set to the path to the framework. CMake
+will convert this to the correct ``-F`` option to include the file.
diff --git a/Help/command/find_program.rst b/Help/command/find_program.rst
new file mode 100644
index 000000000..d3430c054
--- /dev/null
+++ b/Help/command/find_program.rst
@@ -0,0 +1,33 @@
+find_program
+------------
+
+.. |FIND_XXX| replace:: find_program
+.. |NAMES| replace:: NAMES name1 [name2 ...] [NAMES_PER_DIR]
+.. |SEARCH_XXX| replace:: program
+.. |SEARCH_XXX_DESC| replace:: program
+.. |prefix_XXX_SUBDIR| replace:: ``<prefix>/[s]bin``
+.. |entry_XXX_SUBDIR| replace:: ``<entry>/[s]bin``
+
+.. |CMAKE_PREFIX_PATH_XXX| replace::
+ |CMAKE_PREFIX_PATH_XXX_SUBDIR|
+.. |CMAKE_XXX_PATH| replace:: :variable:`CMAKE_PROGRAM_PATH`
+.. |CMAKE_XXX_MAC_PATH| replace:: :variable:`CMAKE_APPBUNDLE_PATH`
+
+.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: ``PATH``
+
+.. |CMAKE_SYSTEM_PREFIX_PATH_XXX| replace::
+ |CMAKE_SYSTEM_PREFIX_PATH_XXX_SUBDIR|
+.. |CMAKE_SYSTEM_XXX_PATH| replace::
+ :variable:`CMAKE_SYSTEM_PROGRAM_PATH`
+.. |CMAKE_SYSTEM_XXX_MAC_PATH| replace::
+ :variable:`CMAKE_SYSTEM_APPBUNDLE_PATH`
+
+.. |CMAKE_FIND_ROOT_PATH_MODE_XXX| replace::
+ :variable:`CMAKE_FIND_ROOT_PATH_MODE_PROGRAM`
+
+.. include:: FIND_XXX.txt
+
+When more than one value is given to the ``NAMES`` option this command by
+default will consider one name at a time and search every directory
+for it. The ``NAMES_PER_DIR`` option tells this command to consider one
+directory at a time and search for all names in it.
diff --git a/Help/command/fltk_wrap_ui.rst b/Help/command/fltk_wrap_ui.rst
new file mode 100644
index 000000000..041e5a7e3
--- /dev/null
+++ b/Help/command/fltk_wrap_ui.rst
@@ -0,0 +1,14 @@
+fltk_wrap_ui
+------------
+
+Create FLTK user interfaces Wrappers.
+
+::
+
+ fltk_wrap_ui(resultingLibraryName source1
+ source2 ... sourceN )
+
+Produce .h and .cxx files for all the .fl and .fld files listed. The
+resulting .h and .cxx files will be added to a variable named
+``resultingLibraryName_FLTK_UI_SRCS`` which should be added to your
+library.
diff --git a/Help/command/foreach.rst b/Help/command/foreach.rst
new file mode 100644
index 000000000..c0f3679d9
--- /dev/null
+++ b/Help/command/foreach.rst
@@ -0,0 +1,47 @@
+foreach
+-------
+
+Evaluate a group of commands for each value in a list.
+
+::
+
+ foreach(loop_var arg1 arg2 ...)
+ COMMAND1(ARGS ...)
+ COMMAND2(ARGS ...)
+ ...
+ endforeach(loop_var)
+
+All commands between foreach and the matching endforeach are recorded
+without being invoked. Once the endforeach is evaluated, the recorded
+list of commands is invoked once for each argument listed in the
+original foreach command. Before each iteration of the loop
+``${loop_var}`` will be set as a variable with the current value in the
+list.
+
+::
+
+ foreach(loop_var RANGE total)
+ foreach(loop_var RANGE start stop [step])
+
+Foreach can also iterate over a generated range of numbers. There are
+three types of this iteration:
+
+* When specifying single number, the range will have elements 0 to
+ "total".
+
+* When specifying two numbers, the range will have elements from the
+ first number to the second number.
+
+* The third optional number is the increment used to iterate from the
+ first number to the second number.
+
+::
+
+ foreach(loop_var IN [LISTS [list1 [...]]]
+ [ITEMS [item1 [...]]])
+
+Iterates over a precise list of items. The ``LISTS`` option names
+list-valued variables to be traversed, including empty elements (an
+empty string is a zero-length list). (Note macro
+arguments are not variables.) The ``ITEMS`` option ends argument
+parsing and includes all arguments following it in the iteration.
diff --git a/Help/command/function.rst b/Help/command/function.rst
new file mode 100644
index 000000000..7ffdfee65
--- /dev/null
+++ b/Help/command/function.rst
@@ -0,0 +1,36 @@
+function
+--------
+
+Start recording a function for later invocation as a command::
+
+ function(<name> [arg1 [arg2 [arg3 ...]]])
+ COMMAND1(ARGS ...)
+ COMMAND2(ARGS ...)
+ ...
+ endfunction(<name>)
+
+Define a function named ``<name>`` that takes arguments named ``arg1``,
+``arg2``, ``arg3``, (...).
+Commands listed after function, but before the matching
+:command:`endfunction()`, are not invoked until the function is invoked.
+When it is invoked, the commands recorded in the function are first
+modified by replacing formal parameters (``${arg1}``) with the arguments
+passed, and then invoked as normal commands.
+In addition to referencing the formal parameters you can reference the
+``ARGC`` variable which will be set to the number of arguments passed
+into the function as well as ``ARGV0``, ``ARGV1``, ``ARGV2``, ... which
+will have the actual values of the arguments passed in.
+This facilitates creating functions with optional arguments.
+Additionally ``ARGV`` holds the list of all arguments given to the
+function and ``ARGN`` holds the list of arguments past the last expected
+argument.
+Referencing to ``ARGV#`` arguments beyond ``ARGC`` have undefined
+behavior. Checking that ``ARGC`` is greater than ``#`` is the only way
+to ensure that ``ARGV#`` was passed to the function as an extra
+argument.
+
+A function opens a new scope: see :command:`set(var PARENT_SCOPE)` for
+details.
+
+See the :command:`cmake_policy()` command documentation for the behavior
+of policies inside functions.
diff --git a/Help/command/get_cmake_property.rst b/Help/command/get_cmake_property.rst
new file mode 100644
index 000000000..3a6fb41e1
--- /dev/null
+++ b/Help/command/get_cmake_property.rst
@@ -0,0 +1,15 @@
+get_cmake_property
+------------------
+
+Get a property of the CMake instance.
+
+::
+
+ get_cmake_property(VAR property)
+
+Get a property from the CMake instance. The value of the property is
+stored in the variable ``VAR``. If the property is not found, ``VAR``
+will be set to "NOTFOUND". See the :manual:`cmake-properties(7)` manual
+for available properties.
+
+See also the more general :command:`get_property` command.
diff --git a/Help/command/get_directory_property.rst b/Help/command/get_directory_property.rst
new file mode 100644
index 000000000..e50abe0e9
--- /dev/null
+++ b/Help/command/get_directory_property.rst
@@ -0,0 +1,24 @@
+get_directory_property
+----------------------
+
+Get a property of ``DIRECTORY`` scope.
+
+::
+
+ get_directory_property(<variable> [DIRECTORY <dir>] <prop-name>)
+
+Store a property of directory scope in the named variable. If the
+property is not defined the empty-string is returned. The ``DIRECTORY``
+argument specifies another directory from which to retrieve the
+property value. The specified directory must have already been
+traversed by CMake.
+
+::
+
+ get_directory_property(<variable> [DIRECTORY <dir>]
+ DEFINITION <var-name>)
+
+Get a variable definition from a directory. This form is useful to
+get a variable definition from another directory.
+
+See also the more general :command:`get_property` command.
diff --git a/Help/command/get_filename_component.rst b/Help/command/get_filename_component.rst
new file mode 100644
index 000000000..14c8cf279
--- /dev/null
+++ b/Help/command/get_filename_component.rst
@@ -0,0 +1,64 @@
+get_filename_component
+----------------------
+
+Get a specific component of a full filename.
+
+------------------------------------------------------------------------------
+
+::
+
+ get_filename_component(<VAR> <FileName> <COMP> [CACHE])
+
+Set ``<VAR>`` to a component of ``<FileName>``, where ``<COMP>`` is one of:
+
+::
+
+ DIRECTORY = Directory without file name
+ NAME = File name without directory
+ EXT = File name longest extension (.b.c from d/a.b.c)
+ NAME_WE = File name without directory or longest extension
+ PATH = Legacy alias for DIRECTORY (use for CMake <= 2.8.11)
+
+Paths are returned with forward slashes and have no trailing slashes.
+The longest file extension is always considered. If the optional
+``CACHE`` argument is specified, the result variable is added to the
+cache.
+
+------------------------------------------------------------------------------
+
+::
+
+ get_filename_component(<VAR> <FileName>
+ <COMP> [BASE_DIR <BASE_DIR>]
+ [CACHE])
+
+Set ``<VAR>`` to the absolute path of ``<FileName>``, where ``<COMP>`` is one
+of:
+
+::
+
+ ABSOLUTE = Full path to file
+ REALPATH = Full path to existing file with symlinks resolved
+
+If the provided ``<FileName>`` is a relative path, it is evaluated relative
+to the given base directory ``<BASE_DIR>``. If no base directory is
+provided, the default base directory will be
+:variable:`CMAKE_CURRENT_SOURCE_DIR`.
+
+Paths are returned with forward slashes and have no trailing slahes. If the
+optional ``CACHE`` argument is specified, the result variable is added to the
+cache.
+
+------------------------------------------------------------------------------
+
+::
+
+ get_filename_component(<VAR> <FileName>
+ PROGRAM [PROGRAM_ARGS <ARG_VAR>]
+ [CACHE])
+
+The program in ``<FileName>`` will be found in the system search path or
+left as a full path. If ``PROGRAM_ARGS`` is present with ``PROGRAM``, then
+any command-line arguments present in the ``<FileName>`` string are split
+from the program name and stored in ``<ARG_VAR>``. This is used to
+separate a program name from its arguments in a command line string.
diff --git a/Help/command/get_property.rst b/Help/command/get_property.rst
new file mode 100644
index 000000000..632ece65c
--- /dev/null
+++ b/Help/command/get_property.rst
@@ -0,0 +1,61 @@
+get_property
+------------
+
+Get a property.
+
+::
+
+ get_property(<variable>
+ <GLOBAL |
+ DIRECTORY [dir] |
+ TARGET <target> |
+ SOURCE <source> |
+ INSTALL <file> |
+ TEST <test> |
+ CACHE <entry> |
+ VARIABLE>
+ PROPERTY <name>
+ [SET | DEFINED | BRIEF_DOCS | FULL_DOCS])
+
+Get one property from one object in a scope. The first argument
+specifies the variable in which to store the result. The second
+argument determines the scope from which to get the property. It must
+be one of the following:
+
+``GLOBAL``
+ Scope is unique and does not accept a name.
+
+``DIRECTORY``
+ Scope defaults to the current directory but another
+ directory (already processed by CMake) may be named by full or
+ relative path.
+
+``TARGET``
+ Scope must name one existing target.
+
+``SOURCE``
+ Scope must name one source file.
+
+``INSTALL``
+ Scope must name one installed file path.
+
+``TEST``
+ Scope must name one existing test.
+
+``CACHE``
+ Scope must name one cache entry.
+
+``VARIABLE``
+ Scope is unique and does not accept a name.
+
+The required ``PROPERTY`` option is immediately followed by the name of
+the property to get. If the property is not set an empty value is
+returned. If the ``SET`` option is given the variable is set to a boolean
+value indicating whether the property has been set. If the ``DEFINED``
+option is given the variable is set to a boolean value indicating
+whether the property has been defined such as with the
+:command:`define_property` command.
+If ``BRIEF_DOCS`` or ``FULL_DOCS`` is given then the variable is set to a
+string containing documentation for the requested property. If
+documentation is requested for a property that has not been defined
+``NOTFOUND`` is returned.
diff --git a/Help/command/get_source_file_property.rst b/Help/command/get_source_file_property.rst
new file mode 100644
index 000000000..3e975c2f9
--- /dev/null
+++ b/Help/command/get_source_file_property.rst
@@ -0,0 +1,16 @@
+get_source_file_property
+------------------------
+
+Get a property for a source file.
+
+::
+
+ get_source_file_property(VAR file property)
+
+Get a property from a source file. The value of the property is
+stored in the variable ``VAR``. If the property is not found, ``VAR``
+will be set to "NOTFOUND". Use :command:`set_source_files_properties`
+to set property values. Source file properties usually control how the
+file is built. One property that is always there is :prop_sf:`LOCATION`
+
+See also the more general :command:`get_property` command.
diff --git a/Help/command/get_target_property.rst b/Help/command/get_target_property.rst
new file mode 100644
index 000000000..2a72c3af7
--- /dev/null
+++ b/Help/command/get_target_property.rst
@@ -0,0 +1,18 @@
+get_target_property
+-------------------
+
+Get a property from a target.
+
+::
+
+ get_target_property(VAR target property)
+
+Get a property from a target. The value of the property is stored in
+the variable ``VAR``. If the property is not found, ``VAR`` will be set to
+"NOTFOUND". Use :command:`set_target_properties` to set property values.
+Properties are usually used to control how a target is built, but some
+query the target instead. This command can get properties for any
+target so far created. The targets do not need to be in the current
+``CMakeLists.txt`` file.
+
+See also the more general :command:`get_property` command.
diff --git a/Help/command/get_test_property.rst b/Help/command/get_test_property.rst
new file mode 100644
index 000000000..e359f4b3d
--- /dev/null
+++ b/Help/command/get_test_property.rst
@@ -0,0 +1,15 @@
+get_test_property
+-----------------
+
+Get a property of the test.
+
+::
+
+ get_test_property(test property VAR)
+
+Get a property from the test. The value of the property is stored in
+the variable ``VAR``. If the test or property is not found, ``VAR`` will
+be set to "NOTFOUND". For a list of standard properties you can type
+``cmake --help-property-list``.
+
+See also the more general :command:`get_property` command.
diff --git a/Help/command/if.rst b/Help/command/if.rst
new file mode 100644
index 000000000..56e618c31
--- /dev/null
+++ b/Help/command/if.rst
@@ -0,0 +1,216 @@
+if
+--
+
+Conditionally execute a group of commands.
+
+.. code-block:: cmake
+
+ if(expression)
+ # then section.
+ COMMAND1(ARGS ...)
+ COMMAND2(ARGS ...)
+ ...
+ elseif(expression2)
+ # elseif section.
+ COMMAND1(ARGS ...)
+ COMMAND2(ARGS ...)
+ ...
+ else(expression)
+ # else section.
+ COMMAND1(ARGS ...)
+ COMMAND2(ARGS ...)
+ ...
+ endif(expression)
+
+Evaluates the given expression. If the result is true, the commands
+in the THEN section are invoked. Otherwise, the commands in the else
+section are invoked. The elseif and else sections are optional. You
+may have multiple elseif clauses. Note that the expression in the
+else and endif clause is optional. Long expressions can be used and
+there is a traditional order of precedence. Parenthetical expressions
+are evaluated first followed by unary tests such as ``EXISTS``,
+``COMMAND``, and ``DEFINED``. Then any binary tests such as
+``EQUAL``, ``LESS``, ``GREATER``, ``STRLESS``, ``STRGREATER``,
+``STREQUAL``, and ``MATCHES`` will be evaluated. Then boolean ``NOT``
+operators and finally boolean ``AND`` and then ``OR`` operators will
+be evaluated.
+
+Possible expressions are:
+
+``if(<constant>)``
+ True if the constant is ``1``, ``ON``, ``YES``, ``TRUE``, ``Y``,
+ or a non-zero number. False if the constant is ``0``, ``OFF``,
+ ``NO``, ``FALSE``, ``N``, ``IGNORE``, ``NOTFOUND``, the empty string,
+ or ends in the suffix ``-NOTFOUND``. Named boolean constants are
+ case-insensitive. If the argument is not one of these specific
+ constants, it is treated as a variable or string and the following
+ signature is used.
+
+``if(<variable|string>)``
+ True if given a variable that is defined to a value that is not a false
+ constant. False otherwise. (Note macro arguments are not variables.)
+
+``if(NOT <expression>)``
+ True if the expression is not true.
+
+``if(<expr1> AND <expr2>)``
+ True if both expressions would be considered true individually.
+
+``if(<expr1> OR <expr2>)``
+ True if either expression would be considered true individually.
+
+``if(COMMAND command-name)``
+ True if the given name is a command, macro or function that can be
+ invoked.
+
+``if(POLICY policy-id)``
+ True if the given name is an existing policy (of the form ``CMP<NNNN>``).
+
+``if(TARGET target-name)``
+ True if the given name is an existing logical target name created
+ by a call to the :command:`add_executable`, :command:`add_library`,
+ or :command:`add_custom_target` command that has already been invoked
+ (in any directory).
+
+``if(TEST test-name)``
+ True if the given name is an existing test name created by the
+ :command:`add_test` command.
+
+``if(EXISTS path-to-file-or-directory)``
+ True if the named file or directory exists. Behavior is well-defined
+ only for full paths.
+
+``if(file1 IS_NEWER_THAN file2)``
+ True if ``file1`` is newer than ``file2`` or if one of the two files doesn't
+ exist. Behavior is well-defined only for full paths. If the file
+ time stamps are exactly the same, an ``IS_NEWER_THAN`` comparison returns
+ true, so that any dependent build operations will occur in the event
+ of a tie. This includes the case of passing the same file name for
+ both file1 and file2.
+
+``if(IS_DIRECTORY path-to-directory)``
+ True if the given name is a directory. Behavior is well-defined only
+ for full paths.
+
+``if(IS_SYMLINK file-name)``
+ True if the given name is a symbolic link. Behavior is well-defined
+ only for full paths.
+
+``if(IS_ABSOLUTE path)``
+ True if the given path is an absolute path.
+
+``if(<variable|string> MATCHES regex)``
+ True if the given string or variable's value matches the given regular
+ expression.
+
+``if(<variable|string> LESS <variable|string>)``
+ True if the given string or variable's value is a valid number and less
+ than that on the right.
+
+``if(<variable|string> GREATER <variable|string>)``
+ True if the given string or variable's value is a valid number and greater
+ than that on the right.
+
+``if(<variable|string> EQUAL <variable|string>)``
+ True if the given string or variable's value is a valid number and equal
+ to that on the right.
+
+``if(<variable|string> STRLESS <variable|string>)``
+ True if the given string or variable's value is lexicographically less
+ than the string or variable on the right.
+
+``if(<variable|string> STRGREATER <variable|string>)``
+ True if the given string or variable's value is lexicographically greater
+ than the string or variable on the right.
+
+``if(<variable|string> STREQUAL <variable|string>)``
+ True if the given string or variable's value is lexicographically equal
+ to the string or variable on the right.
+
+``if(<variable|string> VERSION_LESS <variable|string>)``
+ Component-wise integer version number comparison (version format is
+ ``major[.minor[.patch[.tweak]]]``).
+
+``if(<variable|string> VERSION_EQUAL <variable|string>)``
+ Component-wise integer version number comparison (version format is
+ ``major[.minor[.patch[.tweak]]]``).
+
+``if(<variable|string> VERSION_GREATER <variable|string>)``
+ Component-wise integer version number comparison (version format is
+ ``major[.minor[.patch[.tweak]]]``).
+
+``if(<variable|string> IN_LIST <variable>)``
+ True if the given element is contained in the named list variable.
+
+``if(DEFINED <variable>)``
+ True if the given variable is defined. It does not matter if the
+ variable is true or false just if it has been set. (Note macro
+ arguments are not variables.)
+
+``if((expression) AND (expression OR (expression)))``
+ The expressions inside the parenthesis are evaluated first and then
+ the remaining expression is evaluated as in the previous examples.
+ Where there are nested parenthesis the innermost are evaluated as part
+ of evaluating the expression that contains them.
+
+The if command was written very early in CMake's history, predating
+the ``${}`` variable evaluation syntax, and for convenience evaluates
+variables named by its arguments as shown in the above signatures.
+Note that normal variable evaluation with ``${}`` applies before the if
+command even receives the arguments. Therefore code like::
+
+ set(var1 OFF)
+ set(var2 "var1")
+ if(${var2})
+
+appears to the if command as::
+
+ if(var1)
+
+and is evaluated according to the ``if(<variable>)`` case documented
+above. The result is ``OFF`` which is false. However, if we remove the
+``${}`` from the example then the command sees::
+
+ if(var2)
+
+which is true because ``var2`` is defined to "var1" which is not a false
+constant.
+
+Automatic evaluation applies in the other cases whenever the
+above-documented signature accepts ``<variable|string>``:
+
+* The left hand argument to ``MATCHES`` is first checked to see if it is
+ a defined variable, if so the variable's value is used, otherwise the
+ original value is used.
+
+* If the left hand argument to ``MATCHES`` is missing it returns false
+ without error
+
+* Both left and right hand arguments to ``LESS``, ``GREATER``, and
+ ``EQUAL`` are independently tested to see if they are defined
+ variables, if so their defined values are used otherwise the original
+ value is used.
+
+* Both left and right hand arguments to ``STRLESS``, ``STREQUAL``, and
+ ``STRGREATER`` are independently tested to see if they are defined
+ variables, if so their defined values are used otherwise the original
+ value is used.
+
+* Both left and right hand arguments to ``VERSION_LESS``,
+ ``VERSION_EQUAL``, and ``VERSION_GREATER`` are independently tested
+ to see if they are defined variables, if so their defined values are
+ used otherwise the original value is used.
+
+* The right hand argument to ``NOT`` is tested to see if it is a boolean
+ constant, if so the value is used, otherwise it is assumed to be a
+ variable and it is dereferenced.
+
+* The left and right hand arguments to ``AND`` and ``OR`` are independently
+ tested to see if they are boolean constants, if so they are used as
+ such, otherwise they are assumed to be variables and are dereferenced.
+
+To prevent ambiguity, potential variable or keyword names can be
+specified in a :ref:`Quoted Argument` or a :ref:`Bracket Argument`.
+A quoted or bracketed variable or keyword will be interpreted as a
+string and not dereferenced or interpreted.
+See policy :policy:`CMP0054`.
diff --git a/Help/command/include.rst b/Help/command/include.rst
new file mode 100644
index 000000000..c391561b1
--- /dev/null
+++ b/Help/command/include.rst
@@ -0,0 +1,25 @@
+include
+-------
+
+Load and run CMake code from a file or module.
+
+::
+
+ include(<file|module> [OPTIONAL] [RESULT_VARIABLE <VAR>]
+ [NO_POLICY_SCOPE])
+
+Load and run CMake code from the file given. Variable reads and
+writes access the scope of the caller (dynamic scoping). If ``OPTIONAL``
+is present, then no error is raised if the file does not exist. If
+``RESULT_VARIABLE`` is given the variable will be set to the full filename
+which has been included or NOTFOUND if it failed.
+
+If a module is specified instead of a file, the file with name
+<modulename>.cmake is searched first in :variable:`CMAKE_MODULE_PATH`,
+then in the CMake module directory. There is one exception to this: if
+the file which calls ``include()`` is located itself in the CMake module
+directory, then first the CMake module directory is searched and
+:variable:`CMAKE_MODULE_PATH` afterwards. See also policy :policy:`CMP0017`.
+
+See the :command:`cmake_policy` command documentation for discussion of the
+``NO_POLICY_SCOPE`` option.
diff --git a/Help/command/include_directories.rst b/Help/command/include_directories.rst
new file mode 100644
index 000000000..f69493460
--- /dev/null
+++ b/Help/command/include_directories.rst
@@ -0,0 +1,35 @@
+include_directories
+-------------------
+
+Add include directories to the build.
+
+::
+
+ include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])
+
+Add the given directories to those the compiler uses to search for
+include files. Relative paths are interpreted as relative to the
+current source directory.
+
+The include directories are added to the :prop_dir:`INCLUDE_DIRECTORIES`
+directory property for the current ``CMakeLists`` file. They are also
+added to the :prop_tgt:`INCLUDE_DIRECTORIES` target property for each
+target in the current ``CMakeLists`` file. The target property values
+are the ones used by the generators.
+
+By default the directories specified are appended onto the current list of
+directories. This default behavior can be changed by setting
+:variable:`CMAKE_INCLUDE_DIRECTORIES_BEFORE` to ``ON``. By using
+``AFTER`` or ``BEFORE`` explicitly, you can select between appending and
+prepending, independent of the default.
+
+If the ``SYSTEM`` option is given, the compiler will be told the
+directories are meant as system include directories on some platforms.
+Signalling this setting might achieve effects such as the compiler
+skipping warnings, or these fixed-install system files not being
+considered in dependency calculations - see compiler docs.
+
+Arguments to ``include_directories`` may use "generator expressions" with
+the syntax "$<...>". See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions. See the :manual:`cmake-buildsystem(7)`
+manual for more on defining buildsystem properties.
diff --git a/Help/command/include_external_msproject.rst b/Help/command/include_external_msproject.rst
new file mode 100644
index 000000000..595762d7a
--- /dev/null
+++ b/Help/command/include_external_msproject.rst
@@ -0,0 +1,23 @@
+include_external_msproject
+--------------------------
+
+Include an external Microsoft project file in a workspace.
+
+::
+
+ include_external_msproject(projectname location
+ [TYPE projectTypeGUID]
+ [GUID projectGUID]
+ [PLATFORM platformName]
+ dep1 dep2 ...)
+
+Includes an external Microsoft project in the generated workspace
+file. Currently does nothing on UNIX. This will create a target
+named [projectname]. This can be used in the :command:`add_dependencies`
+command to make things depend on the external project.
+
+``TYPE``, ``GUID`` and ``PLATFORM`` are optional parameters that allow one to
+specify the type of project, id (GUID) of the project and the name of
+the target platform. This is useful for projects requiring values
+other than the default (e.g. WIX projects). These options are not
+supported by the Visual Studio 6 generator.
diff --git a/Help/command/include_regular_expression.rst b/Help/command/include_regular_expression.rst
new file mode 100644
index 000000000..ab5a56325
--- /dev/null
+++ b/Help/command/include_regular_expression.rst
@@ -0,0 +1,18 @@
+include_regular_expression
+--------------------------
+
+Set the regular expression used for dependency checking.
+
+::
+
+ include_regular_expression(regex_match [regex_complain])
+
+Set the regular expressions used in dependency checking. Only files
+matching ``regex_match`` will be traced as dependencies. Only files
+matching ``regex_complain`` will generate warnings if they cannot be found
+(standard header paths are not searched). The defaults are:
+
+::
+
+ regex_match = "^.*$" (match everything)
+ regex_complain = "^$" (match empty string only)
diff --git a/Help/command/install.rst b/Help/command/install.rst
new file mode 100644
index 000000000..45167bc19
--- /dev/null
+++ b/Help/command/install.rst
@@ -0,0 +1,360 @@
+install
+-------
+
+.. only:: html
+
+ .. contents::
+
+Specify rules to run at install time.
+
+Introduction
+^^^^^^^^^^^^
+
+This command generates installation rules for a project. Rules
+specified by calls to this command within a source directory are
+executed in order during installation. The order across directories
+is not defined.
+
+There are multiple signatures for this command. Some of them define
+installation options for files and targets. Options common to
+multiple signatures are covered here but they are valid only for
+signatures that specify them. The common options are:
+
+``DESTINATION``
+ Specify the directory on disk to which a file will be installed.
+ If a full path (with a leading slash or drive letter) is given
+ it is used directly. If a relative path is given it is interpreted
+ relative to the value of the :variable:`CMAKE_INSTALL_PREFIX` variable.
+ The prefix can be relocated at install time using the ``DESTDIR``
+ mechanism explained in the :variable:`CMAKE_INSTALL_PREFIX` variable
+ documentation.
+
+``PERMISSIONS``
+ Specify permissions for installed files. Valid permissions are
+ ``OWNER_READ``, ``OWNER_WRITE``, ``OWNER_EXECUTE``, ``GROUP_READ``,
+ ``GROUP_WRITE``, ``GROUP_EXECUTE``, ``WORLD_READ``, ``WORLD_WRITE``,
+ ``WORLD_EXECUTE``, ``SETUID``, and ``SETGID``. Permissions that do
+ not make sense on certain platforms are ignored on those platforms.
+
+``CONFIGURATIONS``
+ Specify a list of build configurations for which the install rule
+ applies (Debug, Release, etc.).
+
+``COMPONENT``
+ Specify an installation component name with which the install rule
+ is associated, such as "runtime" or "development". During
+ component-specific installation only install rules associated with
+ the given component name will be executed. During a full installation
+ all components are installed. If ``COMPONENT`` is not provided a
+ default component "Unspecified" is created. The default component
+ name may be controlled with the
+ :variable:`CMAKE_INSTALL_DEFAULT_COMPONENT_NAME` variable.
+
+``RENAME``
+ Specify a name for an installed file that may be different from the
+ original file. Renaming is allowed only when a single file is
+ installed by the command.
+
+``OPTIONAL``
+ Specify that it is not an error if the file to be installed does
+ not exist.
+
+Command signatures that install files may print messages during
+installation. Use the :variable:`CMAKE_INSTALL_MESSAGE` variable
+to control which messages are printed.
+
+Installing Targets
+^^^^^^^^^^^^^^^^^^
+
+::
+
+ install(TARGETS targets... [EXPORT <export-name>]
+ [[ARCHIVE|LIBRARY|RUNTIME|FRAMEWORK|BUNDLE|
+ PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE]
+ [DESTINATION <dir>]
+ [PERMISSIONS permissions...]
+ [CONFIGURATIONS [Debug|Release|...]]
+ [COMPONENT <component>]
+ [OPTIONAL] [NAMELINK_ONLY|NAMELINK_SKIP]
+ ] [...]
+ [INCLUDES DESTINATION [<dir> ...]]
+ )
+
+The ``TARGETS`` form specifies rules for installing targets from a
+project. There are five kinds of target files that may be installed:
+``ARCHIVE``, ``LIBRARY``, ``RUNTIME``, ``FRAMEWORK``, and ``BUNDLE``.
+Executables are treated as ``RUNTIME`` targets, except that those
+marked with the ``MACOSX_BUNDLE`` property are treated as ``BUNDLE``
+targets on OS X. Static libraries are always treated as ``ARCHIVE``
+targets. Module libraries are always treated as ``LIBRARY`` targets.
+For non-DLL platforms shared libraries are treated as ``LIBRARY``
+targets, except that those marked with the ``FRAMEWORK`` property are
+treated as ``FRAMEWORK`` targets on OS X. For DLL platforms the DLL
+part of a shared library is treated as a ``RUNTIME`` target and the
+corresponding import library is treated as an ``ARCHIVE`` target.
+All Windows-based systems including Cygwin are DLL platforms.
+The ``ARCHIVE``, ``LIBRARY``, ``RUNTIME``, and ``FRAMEWORK`` arguments
+change the type of target to which the subsequent properties apply.
+If none is given the installation properties apply to all target
+types. If only one is given then only targets of that type will be
+installed (which can be used to install just a DLL or just an import
+library).
+
+The ``PRIVATE_HEADER``, ``PUBLIC_HEADER``, and ``RESOURCE`` arguments
+cause subsequent properties to be applied to installing a ``FRAMEWORK``
+shared library target's associated files on non-Apple platforms. Rules
+defined by these arguments are ignored on Apple platforms because the
+associated files are installed into the appropriate locations inside
+the framework folder. See documentation of the
+:prop_tgt:`PRIVATE_HEADER`, :prop_tgt:`PUBLIC_HEADER`, and
+:prop_tgt:`RESOURCE` target properties for details.
+
+Either ``NAMELINK_ONLY`` or ``NAMELINK_SKIP`` may be specified as a
+``LIBRARY`` option. On some platforms a versioned shared library
+has a symbolic link such as::
+
+ lib<name>.so -> lib<name>.so.1
+
+where ``lib<name>.so.1`` is the soname of the library and ``lib<name>.so``
+is a "namelink" allowing linkers to find the library when given
+``-l<name>``. The ``NAMELINK_ONLY`` option causes installation of only the
+namelink when a library target is installed. The ``NAMELINK_SKIP`` option
+causes installation of library files other than the namelink when a
+library target is installed. When neither option is given both
+portions are installed. On platforms where versioned shared libraries
+do not have namelinks or when a library is not versioned the
+``NAMELINK_SKIP`` option installs the library and the ``NAMELINK_ONLY``
+option installs nothing. See the :prop_tgt:`VERSION` and
+:prop_tgt:`SOVERSION` target properties for details on creating versioned
+shared libraries.
+
+The ``INCLUDES DESTINATION`` specifies a list of directories
+which will be added to the :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`
+target property of the ``<targets>`` when exported by the
+:command:`install(EXPORT)` command. If a relative path is
+specified, it is treated as relative to the ``$<INSTALL_PREFIX>``.
+This is independent of the rest of the argument groups and does
+not actually install anything.
+
+One or more groups of properties may be specified in a single call to
+the ``TARGETS`` form of this command. A target may be installed more than
+once to different locations. Consider hypothetical targets ``myExe``,
+``mySharedLib``, and ``myStaticLib``. The code:
+
+.. code-block:: cmake
+
+ install(TARGETS myExe mySharedLib myStaticLib
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION lib
+ ARCHIVE DESTINATION lib/static)
+ install(TARGETS mySharedLib DESTINATION /some/full/path)
+
+will install ``myExe`` to ``<prefix>/bin`` and ``myStaticLib`` to
+``<prefix>/lib/static``. On non-DLL platforms ``mySharedLib`` will be
+installed to ``<prefix>/lib`` and ``/some/full/path``. On DLL platforms
+the ``mySharedLib`` DLL will be installed to ``<prefix>/bin`` and
+``/some/full/path`` and its import library will be installed to
+``<prefix>/lib/static`` and ``/some/full/path``.
+
+The ``EXPORT`` option associates the installed target files with an
+export called ``<export-name>``. It must appear before any ``RUNTIME``,
+``LIBRARY``, or ``ARCHIVE`` options. To actually install the export
+file itself, call ``install(EXPORT)``, documented below.
+
+Installing a target with the :prop_tgt:`EXCLUDE_FROM_ALL` target property
+set to ``TRUE`` has undefined behavior.
+
+The install destination given to the target install ``DESTINATION`` may
+use "generator expressions" with the syntax ``$<...>``. See the
+:manual:`cmake-generator-expressions(7)` manual for available expressions.
+
+Installing Files
+^^^^^^^^^^^^^^^^
+
+::
+
+ install(<FILES|PROGRAMS> files... DESTINATION <dir>
+ [PERMISSIONS permissions...]
+ [CONFIGURATIONS [Debug|Release|...]]
+ [COMPONENT <component>]
+ [RENAME <name>] [OPTIONAL])
+
+The ``FILES`` form specifies rules for installing files for a project.
+File names given as relative paths are interpreted with respect to the
+current source directory. Files installed by this form are by default
+given permissions ``OWNER_WRITE``, ``OWNER_READ``, ``GROUP_READ``, and
+``WORLD_READ`` if no ``PERMISSIONS`` argument is given.
+
+The ``PROGRAMS`` form is identical to the ``FILES`` form except that the
+default permissions for the installed file also include ``OWNER_EXECUTE``,
+``GROUP_EXECUTE``, and ``WORLD_EXECUTE``. This form is intended to install
+programs that are not targets, such as shell scripts. Use the ``TARGETS``
+form to install targets built within the project.
+
+The list of ``files...`` given to ``FILES`` or ``PROGRAMS`` may use
+"generator expressions" with the syntax ``$<...>``. See the
+:manual:`cmake-generator-expressions(7)` manual for available expressions.
+However, if any item begins in a generator expression it must evaluate
+to a full path.
+
+The install destination given to the files install ``DESTINATION`` may
+use "generator expressions" with the syntax ``$<...>``. See the
+:manual:`cmake-generator-expressions(7)` manual for available expressions.
+
+Installing Directories
+^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+ install(DIRECTORY dirs... DESTINATION <dir>
+ [FILE_PERMISSIONS permissions...]
+ [DIRECTORY_PERMISSIONS permissions...]
+ [USE_SOURCE_PERMISSIONS] [OPTIONAL] [MESSAGE_NEVER]
+ [CONFIGURATIONS [Debug|Release|...]]
+ [COMPONENT <component>] [FILES_MATCHING]
+ [[PATTERN <pattern> | REGEX <regex>]
+ [EXCLUDE] [PERMISSIONS permissions...]] [...])
+
+The ``DIRECTORY`` form installs contents of one or more directories to a
+given destination. The directory structure is copied verbatim to the
+destination. The last component of each directory name is appended to
+the destination directory but a trailing slash may be used to avoid
+this because it leaves the last component empty. Directory names
+given as relative paths are interpreted with respect to the current
+source directory. If no input directory names are given the
+destination directory will be created but nothing will be installed
+into it. The ``FILE_PERMISSIONS`` and ``DIRECTORY_PERMISSIONS`` options
+specify permissions given to files and directories in the destination.
+If ``USE_SOURCE_PERMISSIONS`` is specified and ``FILE_PERMISSIONS`` is not,
+file permissions will be copied from the source directory structure.
+If no permissions are specified files will be given the default
+permissions specified in the ``FILES`` form of the command, and the
+directories will be given the default permissions specified in the
+``PROGRAMS`` form of the command.
+
+The ``MESSAGE_NEVER`` option disables file installation status output.
+
+Installation of directories may be controlled with fine granularity
+using the ``PATTERN`` or ``REGEX`` options. These "match" options specify a
+globbing pattern or regular expression to match directories or files
+encountered within input directories. They may be used to apply
+certain options (see below) to a subset of the files and directories
+encountered. The full path to each input file or directory (with
+forward slashes) is matched against the expression. A ``PATTERN`` will
+match only complete file names: the portion of the full path matching
+the pattern must occur at the end of the file name and be preceded by
+a slash. A ``REGEX`` will match any portion of the full path but it may
+use ``/`` and ``$`` to simulate the ``PATTERN`` behavior. By default all
+files and directories are installed whether or not they are matched.
+The ``FILES_MATCHING`` option may be given before the first match option
+to disable installation of files (but not directories) not matched by
+any expression. For example, the code
+
+.. code-block:: cmake
+
+ install(DIRECTORY src/ DESTINATION include/myproj
+ FILES_MATCHING PATTERN "*.h")
+
+will extract and install header files from a source tree.
+
+Some options may follow a ``PATTERN`` or ``REGEX`` expression and are applied
+only to files or directories matching them. The ``EXCLUDE`` option will
+skip the matched file or directory. The ``PERMISSIONS`` option overrides
+the permissions setting for the matched file or directory. For
+example the code
+
+.. code-block:: cmake
+
+ install(DIRECTORY icons scripts/ DESTINATION share/myproj
+ PATTERN "CVS" EXCLUDE
+ PATTERN "scripts/*"
+ PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ)
+
+will install the ``icons`` directory to ``share/myproj/icons`` and the
+``scripts`` directory to ``share/myproj``. The icons will get default
+file permissions, the scripts will be given specific permissions, and any
+``CVS`` directories will be excluded.
+
+The list of ``dirs...`` given to ``DIRECTORY`` and the install destination
+given to the directory install ``DESTINATION`` may use "generator expressions"
+with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions.
+
+Custom Installation Logic
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+ install([[SCRIPT <file>] [CODE <code>]]
+ [COMPONENT <component>] [...])
+
+The ``SCRIPT`` form will invoke the given CMake script files during
+installation. If the script file name is a relative path it will be
+interpreted with respect to the current source directory. The ``CODE``
+form will invoke the given CMake code during installation. Code is
+specified as a single argument inside a double-quoted string. For
+example, the code
+
+.. code-block:: cmake
+
+ install(CODE "MESSAGE(\"Sample install message.\")")
+
+will print a message during installation.
+
+Installing Exports
+^^^^^^^^^^^^^^^^^^
+
+::
+
+ install(EXPORT <export-name> DESTINATION <dir>
+ [NAMESPACE <namespace>] [FILE <name>.cmake]
+ [PERMISSIONS permissions...]
+ [CONFIGURATIONS [Debug|Release|...]]
+ [EXPORT_LINK_INTERFACE_LIBRARIES]
+ [COMPONENT <component>])
+
+The ``EXPORT`` form generates and installs a CMake file containing code to
+import targets from the installation tree into another project.
+Target installations are associated with the export ``<export-name>``
+using the ``EXPORT`` option of the ``install(TARGETS)`` signature
+documented above. The ``NAMESPACE`` option will prepend ``<namespace>`` to
+the target names as they are written to the import file. By default
+the generated file will be called ``<export-name>.cmake`` but the ``FILE``
+option may be used to specify a different name. The value given to
+the ``FILE`` option must be a file name with the ``.cmake`` extension.
+If a ``CONFIGURATIONS`` option is given then the file will only be installed
+when one of the named configurations is installed. Additionally, the
+generated import file will reference only the matching target
+configurations. The ``EXPORT_LINK_INTERFACE_LIBRARIES`` keyword, if
+present, causes the contents of the properties matching
+``(IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)?`` to be exported, when
+policy :policy:`CMP0022` is ``NEW``. If a ``COMPONENT`` option is
+specified that does not match that given to the targets associated with
+``<export-name>`` the behavior is undefined. If a library target is
+included in the export but a target to which it links is not included
+the behavior is unspecified.
+
+The ``EXPORT`` form is useful to help outside projects use targets built
+and installed by the current project. For example, the code
+
+.. code-block:: cmake
+
+ install(TARGETS myexe EXPORT myproj DESTINATION bin)
+ install(EXPORT myproj NAMESPACE mp_ DESTINATION lib/myproj)
+
+will install the executable myexe to ``<prefix>/bin`` and code to import
+it in the file ``<prefix>/lib/myproj/myproj.cmake``. An outside project
+may load this file with the include command and reference the ``myexe``
+executable from the installation tree using the imported target name
+``mp_myexe`` as if the target were built in its own tree.
+
+.. note::
+ This command supercedes the :command:`install_targets` command and
+ the :prop_tgt:`PRE_INSTALL_SCRIPT` and :prop_tgt:`POST_INSTALL_SCRIPT`
+ target properties. It also replaces the ``FILES`` forms of the
+ :command:`install_files` and :command:`install_programs` commands.
+ The processing order of these install rules relative to
+ those generated by :command:`install_targets`,
+ :command:`install_files`, and :command:`install_programs` commands
+ is not defined.
diff --git a/Help/command/install_files.rst b/Help/command/install_files.rst
new file mode 100644
index 000000000..1850be6e1
--- /dev/null
+++ b/Help/command/install_files.rst
@@ -0,0 +1,39 @@
+install_files
+-------------
+
+Deprecated. Use the :command:`install(FILES)` command instead.
+
+This command has been superceded by the :command:`install` command. It is
+provided for compatibility with older CMake code. The ``FILES`` form is
+directly replaced by the ``FILES`` form of the :command:`install`
+command. The regexp form can be expressed more clearly using the ``GLOB``
+form of the :command:`file` command.
+
+::
+
+ install_files(<dir> extension file file ...)
+
+Create rules to install the listed files with the given extension into
+the given directory. Only files existing in the current source tree
+or its corresponding location in the binary tree may be listed. If a
+file specified already has an extension, that extension will be
+removed first. This is useful for providing lists of source files
+such as foo.cxx when you want the corresponding foo.h to be installed.
+A typical extension is '.h'.
+
+::
+
+ install_files(<dir> regexp)
+
+Any files in the current source directory that match the regular
+expression will be installed.
+
+::
+
+ install_files(<dir> FILES file file ...)
+
+Any files listed after the ``FILES`` keyword will be installed explicitly
+from the names given. Full paths are allowed in this form.
+
+The directory ``<dir>`` is relative to the installation prefix, which is
+stored in the variable :variable:`CMAKE_INSTALL_PREFIX`.
diff --git a/Help/command/install_programs.rst b/Help/command/install_programs.rst
new file mode 100644
index 000000000..79aa486a3
--- /dev/null
+++ b/Help/command/install_programs.rst
@@ -0,0 +1,34 @@
+install_programs
+----------------
+
+Deprecated. Use the :command:`install(PROGRAMS)` command instead.
+
+This command has been superceded by the :command:`install` command. It is
+provided for compatibility with older CMake code. The ``FILES`` form is
+directly replaced by the ``PROGRAMS`` form of the :command:`install`
+command. The regexp form can be expressed more clearly using the ``GLOB``
+form of the :command:`file` command.
+
+::
+
+ install_programs(<dir> file1 file2 [file3 ...])
+ install_programs(<dir> FILES file1 [file2 ...])
+
+Create rules to install the listed programs into the given directory.
+Use the ``FILES`` argument to guarantee that the file list version of the
+command will be used even when there is only one argument.
+
+::
+
+ install_programs(<dir> regexp)
+
+In the second form any program in the current source directory that
+matches the regular expression will be installed.
+
+This command is intended to install programs that are not built by
+cmake, such as shell scripts. See the ``TARGETS`` form of the
+:command:`install` command to create installation rules for targets built
+by cmake.
+
+The directory ``<dir>`` is relative to the installation prefix, which is
+stored in the variable :variable:`CMAKE_INSTALL_PREFIX`.
diff --git a/Help/command/install_targets.rst b/Help/command/install_targets.rst
new file mode 100644
index 000000000..49ca69694
--- /dev/null
+++ b/Help/command/install_targets.rst
@@ -0,0 +1,17 @@
+install_targets
+---------------
+
+Deprecated. Use the :command:`install(TARGETS)` command instead.
+
+This command has been superceded by the :command:`install` command. It is
+provided for compatibility with older CMake code.
+
+::
+
+ install_targets(<dir> [RUNTIME_DIRECTORY dir] target target)
+
+Create rules to install the listed targets into the given directory.
+The directory ``<dir>`` is relative to the installation prefix, which is
+stored in the variable :variable:`CMAKE_INSTALL_PREFIX`. If
+``RUNTIME_DIRECTORY`` is specified, then on systems with special runtime
+files (Windows DLL), the files will be copied to that directory.
diff --git a/Help/command/link_directories.rst b/Help/command/link_directories.rst
new file mode 100644
index 000000000..5c64bc609
--- /dev/null
+++ b/Help/command/link_directories.rst
@@ -0,0 +1,19 @@
+link_directories
+----------------
+
+Specify directories in which the linker will look for libraries.
+
+::
+
+ link_directories(directory1 directory2 ...)
+
+Specify the paths in which the linker should search for libraries.
+The command will apply only to targets created after it is called.
+Relative paths given to this command are interpreted as relative to
+the current source directory, see :policy:`CMP0015`.
+
+Note that this command is rarely necessary. Library locations
+returned by :command:`find_package` and :command:`find_library` are
+absolute paths. Pass these absolute library file paths directly to the
+:command:`target_link_libraries` command. CMake will ensure the linker finds
+them.
diff --git a/Help/command/link_libraries.rst b/Help/command/link_libraries.rst
new file mode 100644
index 000000000..fd5dc3723
--- /dev/null
+++ b/Help/command/link_libraries.rst
@@ -0,0 +1,19 @@
+link_libraries
+--------------
+
+Link libraries to all targets added later.
+
+::
+
+ link_libraries([item1 [item2 [...]]]
+ [[debug|optimized|general] <item>] ...)
+
+Specify libraries or flags to use when linking any targets created later in
+the current directory or below by commands such as :command:`add_executable`
+or :command:`add_library`. See the :command:`target_link_libraries` command
+for meaning of arguments.
+
+.. note::
+ The :command:`target_link_libraries` command should be preferred whenever
+ possible. Library dependencies are chained automatically, so directory-wide
+ specification of link libraries is rarely needed.
diff --git a/Help/command/list.rst b/Help/command/list.rst
new file mode 100644
index 000000000..a7a05c7af
--- /dev/null
+++ b/Help/command/list.rst
@@ -0,0 +1,61 @@
+list
+----
+
+List operations.
+
+::
+
+ list(LENGTH <list> <output variable>)
+ list(GET <list> <element index> [<element index> ...]
+ <output variable>)
+ list(APPEND <list> [<element> ...])
+ list(FIND <list> <value> <output variable>)
+ list(INSERT <list> <element_index> <element> [<element> ...])
+ list(REMOVE_ITEM <list> <value> [<value> ...])
+ list(REMOVE_AT <list> <index> [<index> ...])
+ list(REMOVE_DUPLICATES <list>)
+ list(REVERSE <list>)
+ list(SORT <list>)
+
+``LENGTH`` will return a given list's length.
+
+``GET`` will return list of elements specified by indices from the list.
+
+``APPEND`` will append elements to the list.
+
+``FIND`` will return the index of the element specified in the list or -1
+if it wasn't found.
+
+``INSERT`` will insert elements to the list to the specified location.
+
+``REMOVE_AT`` and ``REMOVE_ITEM`` will remove items from the list. The
+difference is that ``REMOVE_ITEM`` will remove the given items, while
+``REMOVE_AT`` will remove the items at the given indices.
+
+``REMOVE_DUPLICATES`` will remove duplicated items in the list.
+
+``REVERSE`` reverses the contents of the list in-place.
+
+``SORT`` sorts the list in-place alphabetically.
+
+The list subcommands ``APPEND``, ``INSERT``, ``REMOVE_AT``, ``REMOVE_ITEM``,
+``REMOVE_DUPLICATES``, ``REVERSE`` and ``SORT`` may create new values for
+the list within the current CMake variable scope. Similar to the
+:command:`set` command, the LIST command creates new variable values in the
+current scope, even if the list itself is actually defined in a parent
+scope. To propagate the results of these operations upwards, use
+:command:`set` with ``PARENT_SCOPE``, :command:`set` with
+``CACHE INTERNAL``, or some other means of value propagation.
+
+NOTES: A list in cmake is a ``;`` separated group of strings. To create a
+list the set command can be used. For example, ``set(var a b c d e)``
+creates a list with ``a;b;c;d;e``, and ``set(var "a b c d e")`` creates a
+string or a list with one item in it. (Note macro arguments are not
+variables, and therefore cannot be used in LIST commands.)
+
+When specifying index values, if ``<element index>`` is 0 or greater, it
+is indexed from the beginning of the list, with 0 representing the
+first list element. If ``<element index>`` is -1 or lesser, it is indexed
+from the end of the list, with -1 representing the last list element.
+Be careful when counting with negative indices: they do not start from
+0. -0 is equivalent to 0, the first list element.
diff --git a/Help/command/load_cache.rst b/Help/command/load_cache.rst
new file mode 100644
index 000000000..f1134472d
--- /dev/null
+++ b/Help/command/load_cache.rst
@@ -0,0 +1,27 @@
+load_cache
+----------
+
+Load in the values from another project's CMake cache.
+
+::
+
+ load_cache(pathToCacheFile READ_WITH_PREFIX
+ prefix entry1...)
+
+Read the cache and store the requested entries in variables with their
+name prefixed with the given prefix. This only reads the values, and
+does not create entries in the local project's cache.
+
+::
+
+ load_cache(pathToCacheFile [EXCLUDE entry1...]
+ [INCLUDE_INTERNALS entry1...])
+
+Load in the values from another cache and store them in the local
+project's cache as internal entries. This is useful for a project
+that depends on another project built in a different tree. ``EXCLUDE``
+option can be used to provide a list of entries to be excluded.
+``INCLUDE_INTERNALS`` can be used to provide a list of internal entries to
+be included. Normally, no internal entries are brought in. Use of
+this form of the command is strongly discouraged, but it is provided
+for backward compatibility.
diff --git a/Help/command/load_command.rst b/Help/command/load_command.rst
new file mode 100644
index 000000000..a1576e8b5
--- /dev/null
+++ b/Help/command/load_command.rst
@@ -0,0 +1,23 @@
+load_command
+------------
+
+Disallowed. See CMake Policy :policy:`CMP0031`.
+
+Load a command into a running CMake.
+
+::
+
+ load_command(COMMAND_NAME <loc1> [loc2 ...])
+
+The given locations are searched for a library whose name is
+cmCOMMAND_NAME. If found, it is loaded as a module and the command is
+added to the set of available CMake commands. Usually,
+:command:`try_compile` is used before this command to compile the
+module. If the command is successfully loaded a variable named
+
+::
+
+ CMAKE_LOADED_COMMAND_<COMMAND_NAME>
+
+will be set to the full path of the module that was loaded. Otherwise
+the variable will not be set.
diff --git a/Help/command/macro.rst b/Help/command/macro.rst
new file mode 100644
index 000000000..6bee69c73
--- /dev/null
+++ b/Help/command/macro.rst
@@ -0,0 +1,76 @@
+macro
+-----
+
+Start recording a macro for later invocation as a command::
+
+ macro(<name> [arg1 [arg2 [arg3 ...]]])
+ COMMAND1(ARGS ...)
+ COMMAND2(ARGS ...)
+ ...
+ endmacro(<name>)
+
+Define a macro named ``<name>`` that takes arguments named ``arg1``,
+``arg2``, ``arg3``, (...).
+Commands listed after macro, but before the matching
+:command:`endmacro()`, are not invoked until the macro is invoked.
+When it is invoked, the commands recorded in the macro are first
+modified by replacing formal parameters (``${arg1}``) with the arguments
+passed, and then invoked as normal commands.
+In addition to referencing the formal parameters you can reference the
+values ``${ARGC}`` which will be set to the number of arguments passed
+into the function as well as ``${ARGV0}``, ``${ARGV1}``, ``${ARGV2}``,
+... which will have the actual values of the arguments passed in.
+This facilitates creating macros with optional arguments.
+Additionally ``${ARGV}`` holds the list of all arguments given to the
+macro and ``${ARGN}`` holds the list of arguments past the last expected
+argument.
+Referencing to ``${ARGV#}`` arguments beyond ``${ARGC}`` have undefined
+behavior. Checking that ``${ARGC}`` is greater than ``#`` is the only
+way to ensure that ``${ARGV#}`` was passed to the function as an extra
+argument.
+
+See the :command:`cmake_policy()` command documentation for the behavior
+of policies inside macros.
+
+Macro Argument Caveats
+^^^^^^^^^^^^^^^^^^^^^^
+
+Note that the parameters to a macro and values such as ``ARGN`` are
+not variables in the usual CMake sense. They are string
+replacements much like the C preprocessor would do with a macro.
+Therefore you will NOT be able to use commands like::
+
+ if(ARGV1) # ARGV1 is not a variable
+ if(DEFINED ARGV2) # ARGV2 is not a variable
+ if(ARGC GREATER 2) # ARGC is not a variable
+ foreach(loop_var IN LISTS ARGN) # ARGN is not a variable
+
+In the first case, you can use ``if(${ARGV1})``.
+In the second and third case, the proper way to check if an optional
+variable was passed to the macro is to use ``if(${ARGC} GREATER 2)``.
+In the last case, you can use ``foreach(loop_var ${ARGN})`` but this
+will skip empty arguments.
+If you need to include them, you can use::
+
+ set(list_var "${ARGN}")
+ foreach(loop_var IN LISTS list_var)
+
+Note that if you have a variable with the same name in the scope from
+which the macro is called, using unreferenced names will use the
+existing variable instead of the arguments. For example::
+
+ macro(_BAR)
+ foreach(arg IN LISTS ARGN)
+ [...]
+ endforeach()
+ endmacro()
+
+ function(_FOO)
+ _bar(x y z)
+ endfunction()
+
+ _foo(a b c)
+
+Will loop over ``a;b;c`` and not over ``x;y;z`` as one might be expecting.
+If you want true CMake variables and/or better CMake scope control you
+should look at the function command.
diff --git a/Help/command/make_directory.rst b/Help/command/make_directory.rst
new file mode 100644
index 000000000..27ecf5194
--- /dev/null
+++ b/Help/command/make_directory.rst
@@ -0,0 +1,12 @@
+make_directory
+--------------
+
+Deprecated. Use the :command:`file(MAKE_DIRECTORY)` command instead.
+
+::
+
+ make_directory(directory)
+
+Creates the specified directory. Full paths should be given. Any
+parent directories that do not exist will also be created. Use with
+care.
diff --git a/Help/command/mark_as_advanced.rst b/Help/command/mark_as_advanced.rst
new file mode 100644
index 000000000..c3f94fc48
--- /dev/null
+++ b/Help/command/mark_as_advanced.rst
@@ -0,0 +1,19 @@
+mark_as_advanced
+----------------
+
+Mark cmake cached variables as advanced.
+
+::
+
+ mark_as_advanced([CLEAR|FORCE] VAR [VAR2 ...])
+
+Mark the named cached variables as advanced. An advanced variable
+will not be displayed in any of the cmake GUIs unless the show
+advanced option is on. If ``CLEAR`` is the first argument advanced
+variables are changed back to unadvanced. If ``FORCE`` is the first
+argument, then the variable is made advanced. If neither ``FORCE`` nor
+``CLEAR`` is specified, new values will be marked as advanced, but if the
+variable already has an advanced/non-advanced state, it will not be
+changed.
+
+It does nothing in script mode.
diff --git a/Help/command/math.rst b/Help/command/math.rst
new file mode 100644
index 000000000..d4deb16e4
--- /dev/null
+++ b/Help/command/math.rst
@@ -0,0 +1,13 @@
+math
+----
+
+Mathematical expressions.
+
+::
+
+ math(EXPR <output variable> <math expression>)
+
+``EXPR`` evaluates mathematical expression and returns result in the
+output variable. Example mathematical expression is '5 * ( 10 + 13
+)'. Supported operators are + - * / % | & ^ ~ << >> * / %. They have
+the same meaning as they do in C code.
diff --git a/Help/command/message.rst b/Help/command/message.rst
new file mode 100644
index 000000000..04c62fdff
--- /dev/null
+++ b/Help/command/message.rst
@@ -0,0 +1,33 @@
+message
+-------
+
+Display a message to the user.
+
+::
+
+ message([<mode>] "message to display" ...)
+
+The optional ``<mode>`` keyword determines the type of message:
+
+::
+
+ (none) = Important information
+ STATUS = Incidental information
+ WARNING = CMake Warning, continue processing
+ AUTHOR_WARNING = CMake Warning (dev), continue processing
+ SEND_ERROR = CMake Error, continue processing,
+ but skip generation
+ FATAL_ERROR = CMake Error, stop processing and generation
+ DEPRECATION = CMake Deprecation Error or Warning if variable
+ CMAKE_ERROR_DEPRECATED or CMAKE_WARN_DEPRECATED
+ is enabled, respectively, else no message.
+
+The CMake command-line tool displays STATUS messages on stdout and all
+other message types on stderr. The CMake GUI displays all messages in
+its log area. The interactive dialogs (ccmake and CMakeSetup) show
+STATUS messages one at a time on a status line and other messages in
+interactive pop-up boxes.
+
+CMake Warning and Error message text displays using a simple markup
+language. Non-indented text is formatted in line-wrapped paragraphs
+delimited by newlines. Indented text is considered pre-formatted.
diff --git a/Help/command/option.rst b/Help/command/option.rst
new file mode 100644
index 000000000..91cd0a778
--- /dev/null
+++ b/Help/command/option.rst
@@ -0,0 +1,15 @@
+option
+------
+
+Provides an option that the user can optionally select.
+
+::
+
+ option(<option_variable> "help string describing option"
+ [initial value])
+
+Provide an option for the user to select as ``ON`` or ``OFF``. If no
+initial value is provided, ``OFF`` is used.
+
+If you have options that depend on the values of other options, see
+the module help for :module:`CMakeDependentOption`.
diff --git a/Help/command/output_required_files.rst b/Help/command/output_required_files.rst
new file mode 100644
index 000000000..5e1355763
--- /dev/null
+++ b/Help/command/output_required_files.rst
@@ -0,0 +1,19 @@
+output_required_files
+---------------------
+
+Disallowed. See CMake Policy :policy:`CMP0032`.
+
+Approximate C preprocessor dependency scanning.
+
+This command exists only because ancient CMake versions provided it.
+CMake handles preprocessor dependency scanning automatically using a
+more advanced scanner.
+
+::
+
+ output_required_files(srcfile outputfile)
+
+Outputs a list of all the source files that are required by the
+specified srcfile. This list is written into outputfile. This is
+similar to writing out the dependencies for srcfile except that it
+jumps from .h files into .cxx, .c and .cpp files if possible.
diff --git a/Help/command/project.rst b/Help/command/project.rst
new file mode 100644
index 000000000..6c5ace7f1
--- /dev/null
+++ b/Help/command/project.rst
@@ -0,0 +1,64 @@
+project
+-------
+
+Set a name, version, and enable languages for the entire project.
+
+.. code-block:: cmake
+
+ project(<PROJECT-NAME> [LANGUAGES] [<language-name>...])
+ project(<PROJECT-NAME>
+ [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
+ [LANGUAGES <language-name>...])
+
+Sets the name of the project and stores the name in the
+:variable:`PROJECT_NAME` variable. Additionally this sets variables
+
+* :variable:`PROJECT_SOURCE_DIR`,
+ :variable:`<PROJECT-NAME>_SOURCE_DIR`
+* :variable:`PROJECT_BINARY_DIR`,
+ :variable:`<PROJECT-NAME>_BINARY_DIR`
+
+If ``VERSION`` is specified, given components must be non-negative integers.
+If ``VERSION`` is not specified, the default version is the empty string.
+The ``VERSION`` option may not be used unless policy :policy:`CMP0048` is
+set to ``NEW``.
+
+The :command:`project()` command stores the version number and its components
+in variables
+
+* :variable:`PROJECT_VERSION`,
+ :variable:`<PROJECT-NAME>_VERSION`
+* :variable:`PROJECT_VERSION_MAJOR`,
+ :variable:`<PROJECT-NAME>_VERSION_MAJOR`
+* :variable:`PROJECT_VERSION_MINOR`,
+ :variable:`<PROJECT-NAME>_VERSION_MINOR`
+* :variable:`PROJECT_VERSION_PATCH`,
+ :variable:`<PROJECT-NAME>_VERSION_PATCH`
+* :variable:`PROJECT_VERSION_TWEAK`,
+ :variable:`<PROJECT-NAME>_VERSION_TWEAK`
+
+Variables corresponding to unspecified versions are set to the empty string
+(if policy :policy:`CMP0048` is set to ``NEW``).
+
+Optionally you can specify which languages your project supports.
+Example languages are ``C``, ``CXX`` (i.e. C++), ``Fortran``, etc.
+By default ``C`` and ``CXX`` are enabled if no language options are
+given. Specify language ``NONE``, or use the ``LANGUAGES`` keyword
+and list no languages, to skip enabling any languages.
+
+If a variable exists called :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE`,
+the file pointed to by that variable will be included as the last step of the
+project command.
+
+The top-level ``CMakeLists.txt`` file for a project must contain a
+literal, direct call to the :command:`project` command; loading one
+through the :command:`include` command is not sufficient. If no such
+call exists CMake will implicitly add one to the top that enables the
+default languages (``C`` and ``CXX``).
+
+.. note::
+ Call the :command:`cmake_minimum_required` command at the beginning
+ of the top-level ``CMakeLists.txt`` file even before calling the
+ ``project()`` command. It is important to establish version and
+ policy settings before invoking other commands whose behavior they
+ may affect. See also policy :policy:`CMP0000`.
diff --git a/Help/command/qt_wrap_cpp.rst b/Help/command/qt_wrap_cpp.rst
new file mode 100644
index 000000000..3843bf5e9
--- /dev/null
+++ b/Help/command/qt_wrap_cpp.rst
@@ -0,0 +1,12 @@
+qt_wrap_cpp
+-----------
+
+Create Qt Wrappers.
+
+::
+
+ qt_wrap_cpp(resultingLibraryName DestName
+ SourceLists ...)
+
+Produce moc files for all the .h files listed in the SourceLists. The
+moc files will be added to the library using the ``DestName`` source list.
diff --git a/Help/command/qt_wrap_ui.rst b/Help/command/qt_wrap_ui.rst
new file mode 100644
index 000000000..f731ed9a8
--- /dev/null
+++ b/Help/command/qt_wrap_ui.rst
@@ -0,0 +1,14 @@
+qt_wrap_ui
+----------
+
+Create Qt user interfaces Wrappers.
+
+::
+
+ qt_wrap_ui(resultingLibraryName HeadersDestName
+ SourcesDestName SourceLists ...)
+
+Produce .h and .cxx files for all the .ui files listed in the
+``SourceLists``. The .h files will be added to the library using the
+``HeadersDestNamesource`` list. The .cxx files will be added to the
+library using the ``SourcesDestNamesource`` list.
diff --git a/Help/command/remove.rst b/Help/command/remove.rst
new file mode 100644
index 000000000..462827796
--- /dev/null
+++ b/Help/command/remove.rst
@@ -0,0 +1,12 @@
+remove
+------
+
+Deprecated. Use the :command:`list(REMOVE_ITEM)` command instead.
+
+::
+
+ remove(VAR VALUE VALUE ...)
+
+Removes ``VALUE`` from the variable ``VAR``. This is typically used to
+remove entries from a vector (e.g. semicolon separated list). ``VALUE``
+is expanded.
diff --git a/Help/command/remove_definitions.rst b/Help/command/remove_definitions.rst
new file mode 100644
index 000000000..ea189181c
--- /dev/null
+++ b/Help/command/remove_definitions.rst
@@ -0,0 +1,11 @@
+remove_definitions
+------------------
+
+Removes -D define flags added by :command:`add_definitions`.
+
+::
+
+ remove_definitions(-DFOO -DBAR ...)
+
+Removes flags (added by :command:`add_definitions`) from the compiler
+command line for sources in the current directory and below.
diff --git a/Help/command/return.rst b/Help/command/return.rst
new file mode 100644
index 000000000..e49fb3c8d
--- /dev/null
+++ b/Help/command/return.rst
@@ -0,0 +1,18 @@
+return
+------
+
+Return from a file, directory or function.
+
+::
+
+ return()
+
+Returns from a file, directory or function. When this command is
+encountered in an included file (via :command:`include` or
+:command:`find_package`), it causes processing of the current file to stop
+and control is returned to the including file. If it is encountered in a
+file which is not included by another file, e.g. a ``CMakeLists.txt``,
+control is returned to the parent directory if there is one. If return is
+called in a function, control is returned to the caller of the function.
+Note that a macro is not a function and does not handle return like a
+function does.
diff --git a/Help/command/separate_arguments.rst b/Help/command/separate_arguments.rst
new file mode 100644
index 000000000..0e3e5a5f2
--- /dev/null
+++ b/Help/command/separate_arguments.rst
@@ -0,0 +1,31 @@
+separate_arguments
+------------------
+
+Parse space-separated arguments into a semicolon-separated list.
+
+::
+
+ separate_arguments(<var> <UNIX|WINDOWS>_COMMAND "<args>")
+
+Parses a unix- or windows-style command-line string "<args>" and
+stores a semicolon-separated list of the arguments in ``<var>``. The
+entire command line must be given in one "<args>" argument.
+
+The ``UNIX_COMMAND`` mode separates arguments by unquoted whitespace. It
+recognizes both single-quote and double-quote pairs. A backslash
+escapes the next literal character (\" is "); there are no special
+escapes (\n is just n).
+
+The ``WINDOWS_COMMAND`` mode parses a windows command-line using the same
+syntax the runtime library uses to construct argv at startup. It
+separates arguments by whitespace that is not double-quoted.
+Backslashes are literal unless they precede double-quotes. See the
+MSDN article "Parsing C Command-Line Arguments" for details.
+
+::
+
+ separate_arguments(VARIABLE)
+
+Convert the value of ``VARIABLE`` to a semi-colon separated list. All
+spaces are replaced with ';'. This helps with generating command
+lines.
diff --git a/Help/command/set.rst b/Help/command/set.rst
new file mode 100644
index 000000000..d04b88004
--- /dev/null
+++ b/Help/command/set.rst
@@ -0,0 +1,89 @@
+set
+---
+
+Set a normal, cache, or environment variable to a given value.
+See the :ref:`cmake-language(7) variables <CMake Language Variables>`
+documentation for the scopes and interaction of normal variables
+and cache entries.
+
+Signatures of this command that specify a ``<value>...`` placeholder
+expect zero or more arguments. Multiple arguments will be joined as
+a :ref:`;-list <CMake Language Lists>` to form the actual variable
+value to be set. Zero arguments will cause normal variables to be
+unset. See the :command:`unset` command to unset variables explicitly.
+
+Set Normal Variable
+^^^^^^^^^^^^^^^^^^^
+
+::
+
+ set(<variable> <value>... [PARENT_SCOPE])
+
+Set the given ``<variable>`` in the current function or directory scope.
+
+If the ``PARENT_SCOPE`` option is given the variable will be set in
+the scope above the current scope. Each new directory or function
+creates a new scope. This command will set the value of a variable
+into the parent directory or calling function (whichever is applicable
+to the case at hand).
+
+Set Cache Entry
+^^^^^^^^^^^^^^^
+
+::
+
+ set(<variable> <value>... CACHE <type> <docstring> [FORCE])
+
+Set the given cache ``<variable>`` (cache entry). Since cache entries
+are meant to provide user-settable values this does not overwrite
+existing cache entries by default. Use the ``FORCE`` option to
+overwrite existing entries.
+
+The ``<type>`` must be specified as one of:
+
+``BOOL``
+ Boolean ``ON/OFF`` value. :manual:`cmake-gui(1)` offers a checkbox.
+
+``FILEPATH``
+ Path to a file on disk. :manual:`cmake-gui(1)` offers a file dialog.
+
+``PATH``
+ Path to a directory on disk. :manual:`cmake-gui(1)` offers a file dialog.
+
+``STRING``
+ A line of text. :manual:`cmake-gui(1)` offers a text field or a
+ drop-down selection if the :prop_cache:`STRINGS` cache entry
+ property is set.
+
+``INTERNAL``
+ A line of text. :manual:`cmake-gui(1)` does not show internal entries.
+ They may be used to store variables persistently across runs.
+ Use of this type implies ``FORCE``.
+
+The ``<docstring>`` must be specified as a line of text providing
+a quick summary of the option for presentation to :manual:`cmake-gui(1)`
+users.
+
+If the cache entry does not exist prior to the call or the ``FORCE``
+option is given then the cache entry will be set to the given value.
+Furthermore, any normal variable binding in the current scope will
+be removed to expose the newly cached value to any immediately
+following evaluation.
+
+It is possible for the cache entry to exist prior to the call but
+have no type set if it was created on the :manual:`cmake(1)` command
+line by a user through the ``-D<var>=<value>`` option without
+specifying a type. In this case the ``set`` command will add the
+type. Furthermore, if the ``<type>`` is ``PATH`` or ``FILEPATH``
+and the ``<value>`` provided on the command line is a relative path,
+then the ``set`` command will treat the path as relative to the
+current working directory and convert it to an absolute path.
+
+Set Environment Variable
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+ set(ENV{<variable>} <value>...)
+
+Set the current process environment ``<variable>`` to the given value.
diff --git a/Help/command/set_directory_properties.rst b/Help/command/set_directory_properties.rst
new file mode 100644
index 000000000..e485fce0a
--- /dev/null
+++ b/Help/command/set_directory_properties.rst
@@ -0,0 +1,12 @@
+set_directory_properties
+------------------------
+
+Set a property of the directory.
+
+::
+
+ set_directory_properties(PROPERTIES prop1 value1 prop2 value2)
+
+Set a property for the current directory and subdirectories. See
+:ref:`Directory Properties` for the list of properties known
+to CMake.
diff --git a/Help/command/set_property.rst b/Help/command/set_property.rst
new file mode 100644
index 000000000..5ed788e4a
--- /dev/null
+++ b/Help/command/set_property.rst
@@ -0,0 +1,69 @@
+set_property
+------------
+
+Set a named property in a given scope.
+
+::
+
+ set_property(<GLOBAL |
+ DIRECTORY [dir] |
+ TARGET [target1 [target2 ...]] |
+ SOURCE [src1 [src2 ...]] |
+ INSTALL [file1 [file2 ...]] |
+ TEST [test1 [test2 ...]] |
+ CACHE [entry1 [entry2 ...]]>
+ [APPEND] [APPEND_STRING]
+ PROPERTY <name> [value1 [value2 ...]])
+
+Set one property on zero or more objects of a scope. The first
+argument determines the scope in which the property is set. It must
+be one of the following:
+
+``GLOBAL``
+ Scope is unique and does not accept a name.
+
+``DIRECTORY``
+ Scope defaults to the current directory but another
+ directory (already processed by CMake) may be named by full or
+ relative path.
+
+``TARGET``
+ Scope may name zero or more existing targets.
+
+``SOURCE``
+ Scope may name zero or more source files. Note that source
+ file properties are visible only to targets added in the same
+ directory (CMakeLists.txt).
+
+``INSTALL``
+ Scope may name zero or more installed file paths.
+ These are made available to CPack to influence deployment.
+
+ Both the property key and value may use generator expressions.
+ Specific properties may apply to installed files and/or directories.
+
+ Path components have to be separated by forward slashes,
+ must be normalized and are case sensitive.
+
+ To reference the installation prefix itself with a relative path use ".".
+
+ Currently installed file properties are only defined for
+ the WIX generator where the given paths are relative
+ to the installation prefix.
+
+``TEST``
+ Scope may name zero or more existing tests.
+
+``CACHE``
+ Scope must name zero or more cache existing entries.
+
+The required ``PROPERTY`` option is immediately followed by the name of
+the property to set. Remaining arguments are used to compose the
+property value in the form of a semicolon-separated list. If the
+``APPEND`` option is given the list is appended to any existing property
+value. If the ``APPEND_STRING`` option is given the string is append to any
+existing property value as string, i.e. it results in a longer string
+and not a list of strings.
+
+See the :manual:`cmake-properties(7)` manual for a list of properties
+in each scope.
diff --git a/Help/command/set_source_files_properties.rst b/Help/command/set_source_files_properties.rst
new file mode 100644
index 000000000..b4904e8d0
--- /dev/null
+++ b/Help/command/set_source_files_properties.rst
@@ -0,0 +1,15 @@
+set_source_files_properties
+---------------------------
+
+Source files can have properties that affect how they are built.
+
+::
+
+ set_source_files_properties([file1 [file2 [...]]]
+ PROPERTIES prop1 value1
+ [prop2 value2 [...]])
+
+Set properties associated with source files using a key/value paired
+list. See :ref:`Source File Properties` for the list of properties known
+to CMake. Source file properties are visible only to targets added
+in the same directory (CMakeLists.txt).
diff --git a/Help/command/set_target_properties.rst b/Help/command/set_target_properties.rst
new file mode 100644
index 000000000..b894eace3
--- /dev/null
+++ b/Help/command/set_target_properties.rst
@@ -0,0 +1,18 @@
+set_target_properties
+---------------------
+
+Targets can have properties that affect how they are built.
+
+::
+
+ set_target_properties(target1 target2 ...
+ PROPERTIES prop1 value1
+ prop2 value2 ...)
+
+Set properties on a target. The syntax for the command is to list all
+the files you want to change, and then provide the values you want to
+set next. You can use any prop value pair you want and extract it
+later with the :command:`get_property` or :command:`get_target_property`
+command.
+
+See :ref:`Target Properties` for the list of properties known to CMake.
diff --git a/Help/command/set_tests_properties.rst b/Help/command/set_tests_properties.rst
new file mode 100644
index 000000000..3efb1653e
--- /dev/null
+++ b/Help/command/set_tests_properties.rst
@@ -0,0 +1,14 @@
+set_tests_properties
+--------------------
+
+Set a property of the tests.
+
+::
+
+ set_tests_properties(test1 [test2...] PROPERTIES prop1 value1 prop2 value2)
+
+Set a property for the tests. If the test is not found, CMake
+will report an error.
+:manual:`Generator expressions <cmake-generator-expressions(7)>` will be
+expanded the same as supported by the test's :command:`add_test` call. See
+:ref:`Test Properties` for the list of properties known to CMake.
diff --git a/Help/command/site_name.rst b/Help/command/site_name.rst
new file mode 100644
index 000000000..e17c1ee68
--- /dev/null
+++ b/Help/command/site_name.rst
@@ -0,0 +1,8 @@
+site_name
+---------
+
+Set the given variable to the name of the computer.
+
+::
+
+ site_name(variable)
diff --git a/Help/command/source_group.rst b/Help/command/source_group.rst
new file mode 100644
index 000000000..6e3829c04
--- /dev/null
+++ b/Help/command/source_group.rst
@@ -0,0 +1,44 @@
+source_group
+------------
+
+Define a grouping for source files in IDE project generation.
+
+.. code-block:: cmake
+
+ source_group(<name> [FILES <src>...] [REGULAR_EXPRESSION <regex>])
+
+Defines a group into which sources will be placed in project files.
+This is intended to set up file tabs in Visual Studio.
+The options are:
+
+``FILES``
+ Any source file specified explicitly will be placed in group
+ ``<name>``. Relative paths are interpreted with respect to the
+ current source directory.
+
+``REGULAR_EXPRESSION``
+ Any source file whose name matches the regular expression will
+ be placed in group ``<name>``.
+
+If a source file matches multiple groups, the *last* group that
+explicitly lists the file with ``FILES`` will be favored, if any.
+If no group explicitly lists the file, the *last* group whose
+regular expression matches the file will be favored.
+
+The ``<name>`` of the group may contain backslashes to specify subgroups:
+
+.. code-block:: cmake
+
+ source_group(outer\\inner ...)
+
+For backwards compatibility, the short-hand signature
+
+.. code-block:: cmake
+
+ source_group(<name> <regex>)
+
+is equivalent to
+
+.. code-block:: cmake
+
+ source_group(<name> REGULAR_EXPRESSION <regex>)
diff --git a/Help/command/string.rst b/Help/command/string.rst
new file mode 100644
index 000000000..0361c74db
--- /dev/null
+++ b/Help/command/string.rst
@@ -0,0 +1,320 @@
+string
+------
+
+.. only:: html
+
+ .. contents::
+
+String operations.
+
+Search and Replace
+^^^^^^^^^^^^^^^^^^
+
+FIND
+""""
+
+::
+
+ string(FIND <string> <substring> <output variable> [REVERSE])
+
+Return the position where the given substring was found in
+the supplied string. If the ``REVERSE`` flag was used, the command will
+search for the position of the last occurrence of the specified
+substring. If the substring is not found, a position of -1 is returned.
+
+REPLACE
+"""""""
+
+::
+
+ string(REPLACE <match_string>
+ <replace_string> <output variable>
+ <input> [<input>...])
+
+Replace all occurrences of ``match_string`` in the input
+with ``replace_string`` and store the result in the output.
+
+Regular Expressions
+^^^^^^^^^^^^^^^^^^^
+
+REGEX MATCH
+"""""""""""
+
+::
+
+ string(REGEX MATCH <regular_expression>
+ <output variable> <input> [<input>...])
+
+Match the regular expression once and store the match in the output variable.
+All ``<input>`` arguments are concatenated before matching.
+
+REGEX MATCHALL
+""""""""""""""
+
+::
+
+ string(REGEX MATCHALL <regular_expression>
+ <output variable> <input> [<input>...])
+
+Match the regular expression as many times as possible and store the matches
+in the output variable as a list.
+All ``<input>`` arguments are concatenated before matching.
+
+REGEX REPLACE
+"""""""""""""
+
+::
+
+ string(REGEX REPLACE <regular_expression>
+ <replace_expression> <output variable>
+ <input> [<input>...])
+
+Match the regular expression as many times as possible and substitute the
+replacement expression for the match in the output.
+All ``<input>`` arguments are concatenated before matching.
+
+The replace expression may refer to paren-delimited subexpressions of the
+match using ``\1``, ``\2``, ..., ``\9``. Note that two backslashes (``\\1``)
+are required in CMake code to get a backslash through argument parsing.
+
+Regex Specification
+"""""""""""""""""""
+
+The following characters have special meaning in regular expressions:
+
+::
+
+ ^ Matches at beginning of input
+ $ Matches at end of input
+ . Matches any single character
+ [ ] Matches any character(s) inside the brackets
+ [^ ] Matches any character(s) not inside the brackets
+ - Inside brackets, specifies an inclusive range between
+ characters on either side e.g. [a-f] is [abcdef]
+ To match a literal - using brackets, make it the first
+ or the last character e.g. [+*/-] matches basic
+ mathematical operators.
+ * Matches preceding pattern zero or more times
+ + Matches preceding pattern one or more times
+ ? Matches preceding pattern zero or once only
+ | Matches a pattern on either side of the |
+ () Saves a matched subexpression, which can be referenced
+ in the REGEX REPLACE operation. Additionally it is saved
+ by all regular expression-related commands, including
+ e.g. if( MATCHES ), in the variables CMAKE_MATCH_(0..9).
+
+``*``, ``+`` and ``?`` have higher precedence than concatenation. ``|``
+has lower precedence than concatenation. This means that the regular
+expression ``^ab+d$`` matches ``abbd`` but not ``ababd``, and the regular
+expression ``^(ab|cd)$`` matches ``ab`` but not ``abd``.
+
+Manipulation
+^^^^^^^^^^^^
+
+APPEND
+""""""
+
+::
+
+ string(APPEND <string variable> [<input>...])
+
+Append all the input arguments to the string.
+
+CONCAT
+""""""
+
+::
+
+ string(CONCAT <output variable> [<input>...])
+
+Concatenate all the input arguments together and store
+the result in the named output variable.
+
+TOLOWER
+"""""""
+
+::
+
+ string(TOLOWER <string1> <output variable>)
+
+Convert string to lower characters.
+
+TOUPPER
+"""""""
+
+::
+
+ string(TOUPPER <string1> <output variable>)
+
+Convert string to upper characters.
+
+LENGTH
+""""""
+
+::
+
+ string(LENGTH <string> <output variable>)
+
+Store in an output variable a given string's length.
+
+SUBSTRING
+"""""""""
+
+::
+
+ string(SUBSTRING <string> <begin> <length> <output variable>)
+
+Store in an output variable a substring of a given string. If length is
+``-1`` the remainder of the string starting at begin will be returned.
+If string is shorter than length then end of string is used instead.
+
+.. note::
+ CMake 3.1 and below reported an error if length pointed past
+ the end of string.
+
+STRIP
+"""""
+
+::
+
+ string(STRIP <string> <output variable>)
+
+Store in an output variable a substring of a given string with leading and
+trailing spaces removed.
+
+GENEX_STRIP
+"""""""""""
+
+::
+
+ string(GENEX_STRIP <input string> <output variable>)
+
+Strip any :manual:`generator expressions <cmake-generator-expressions(7)>`
+from the ``input string`` and store the result in the ``output variable``.
+
+Comparison
+^^^^^^^^^^
+
+::
+
+ string(COMPARE EQUAL <string1> <string2> <output variable>)
+ string(COMPARE NOTEQUAL <string1> <string2> <output variable>)
+ string(COMPARE LESS <string1> <string2> <output variable>)
+ string(COMPARE GREATER <string1> <string2> <output variable>)
+
+Compare the strings and store true or false in the output variable.
+
+Hashing
+^^^^^^^
+
+::
+
+ string(<MD5|SHA1|SHA224|SHA256|SHA384|SHA512>
+ <output variable> <input>)
+
+Compute a cryptographic hash of the input string.
+
+Generation
+^^^^^^^^^^
+
+ASCII
+"""""
+
+::
+
+ string(ASCII <number> [<number> ...] <output variable>)
+
+Convert all numbers into corresponding ASCII characters.
+
+CONFIGURE
+"""""""""
+
+::
+
+ string(CONFIGURE <string1> <output variable>
+ [@ONLY] [ESCAPE_QUOTES])
+
+Transform a string like :command:`configure_file` transforms a file.
+
+RANDOM
+""""""
+
+::
+
+ string(RANDOM [LENGTH <length>] [ALPHABET <alphabet>]
+ [RANDOM_SEED <seed>] <output variable>)
+
+Return a random string of given length consisting of
+characters from the given alphabet. Default length is 5 characters
+and default alphabet is all numbers and upper and lower case letters.
+If an integer ``RANDOM_SEED`` is given, its value will be used to seed the
+random number generator.
+
+TIMESTAMP
+"""""""""
+
+::
+
+ string(TIMESTAMP <output variable> [<format string>] [UTC])
+
+Write a string representation of the current date
+and/or time to the output variable.
+
+Should the command be unable to obtain a timestamp the output variable
+will be set to the empty string "".
+
+The optional ``UTC`` flag requests the current date/time representation to
+be in Coordinated Universal Time (UTC) rather than local time.
+
+The optional ``<format string>`` may contain the following format
+specifiers:
+
+::
+
+ %d The day of the current month (01-31).
+ %H The hour on a 24-hour clock (00-23).
+ %I The hour on a 12-hour clock (01-12).
+ %j The day of the current year (001-366).
+ %m The month of the current year (01-12).
+ %M The minute of the current hour (00-59).
+ %S The second of the current minute.
+ 60 represents a leap second. (00-60)
+ %U The week number of the current year (00-53).
+ %w The day of the current week. 0 is Sunday. (0-6)
+ %y The last two digits of the current year (00-99)
+ %Y The current year.
+
+Unknown format specifiers will be ignored and copied to the output
+as-is.
+
+If no explicit ``<format string>`` is given it will default to:
+
+::
+
+ %Y-%m-%dT%H:%M:%S for local time.
+ %Y-%m-%dT%H:%M:%SZ for UTC.
+
+
+::
+
+ string(MAKE_C_IDENTIFIER <input string> <output variable>)
+
+Write a string which can be used as an identifier in C.
+
+UUID
+""""
+
+::
+
+ string(UUID <output variable> NAMESPACE <namespace> NAME <name>
+ TYPE <MD5|SHA1> [UPPER])
+
+Create a univerally unique identifier (aka GUID) as per RFC4122
+based on the hash of the combined values of ``<namespace>``
+(which itself has to be a valid UUID) and ``<name>``.
+The hash algorithm can be either ``MD5`` (Version 3 UUID) or
+``SHA1`` (Version 5 UUID).
+A UUID has the format ``xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx``
+where each `x` represents a lower case hexadecimal character.
+Where required an uppercase representation can be requested
+with the optional ``UPPER`` flag.
diff --git a/Help/command/subdir_depends.rst b/Help/command/subdir_depends.rst
new file mode 100644
index 000000000..5676c8f40
--- /dev/null
+++ b/Help/command/subdir_depends.rst
@@ -0,0 +1,13 @@
+subdir_depends
+--------------
+
+Disallowed. See CMake Policy :policy:`CMP0029`.
+
+Does nothing.
+
+::
+
+ subdir_depends(subdir dep1 dep2 ...)
+
+Does not do anything. This command used to help projects order
+parallel builds correctly. This functionality is now automatic.
diff --git a/Help/command/subdirs.rst b/Help/command/subdirs.rst
new file mode 100644
index 000000000..43b87d4d7
--- /dev/null
+++ b/Help/command/subdirs.rst
@@ -0,0 +1,24 @@
+subdirs
+-------
+
+Deprecated. Use the :command:`add_subdirectory` command instead.
+
+Add a list of subdirectories to the build.
+
+::
+
+ subdirs(dir1 dir2 ...[EXCLUDE_FROM_ALL exclude_dir1 exclude_dir2 ...]
+ [PREORDER] )
+
+Add a list of subdirectories to the build. The :command:`add_subdirectory`
+command should be used instead of ``subdirs`` although ``subdirs`` will still
+work. This will cause any CMakeLists.txt files in the sub directories
+to be processed by CMake. Any directories after the ``PREORDER`` flag are
+traversed first by makefile builds, the ``PREORDER`` flag has no effect on
+IDE projects. Any directories after the ``EXCLUDE_FROM_ALL`` marker will
+not be included in the top level makefile or project file. This is
+useful for having CMake create makefiles or projects for a set of
+examples in a project. You would want CMake to generate makefiles or
+project files for all the examples at the same time, but you would not
+want them to show up in the top level project or be built each time
+make is run from the top.
diff --git a/Help/command/target_compile_definitions.rst b/Help/command/target_compile_definitions.rst
new file mode 100644
index 000000000..8bd323375
--- /dev/null
+++ b/Help/command/target_compile_definitions.rst
@@ -0,0 +1,28 @@
+target_compile_definitions
+--------------------------
+
+Add compile definitions to a target.
+
+::
+
+ target_compile_definitions(<target>
+ <INTERFACE|PUBLIC|PRIVATE> [items1...]
+ [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
+
+Specify compile definitions to use when compiling a given ``<target>``. The
+named ``<target>`` must have been created by a command such as
+:command:`add_executable` or :command:`add_library` and must not be an
+:ref:`Imported Target <Imported Targets>`.
+
+The ``INTERFACE``, ``PUBLIC`` and ``PRIVATE`` keywords are required to
+specify the scope of the following arguments. ``PRIVATE`` and ``PUBLIC``
+items will populate the :prop_tgt:`COMPILE_DEFINITIONS` property of
+``<target>``. ``PUBLIC`` and ``INTERFACE`` items will populate the
+:prop_tgt:`INTERFACE_COMPILE_DEFINITIONS` property of ``<target>``. The
+following arguments specify compile definitions. Repeated calls for the
+same ``<target>`` append items in the order called.
+
+Arguments to ``target_compile_definitions`` may use "generator expressions"
+with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions. See the :manual:`cmake-buildsystem(7)`
+manual for more on defining buildsystem properties.
diff --git a/Help/command/target_compile_features.rst b/Help/command/target_compile_features.rst
new file mode 100644
index 000000000..b66a4ec16
--- /dev/null
+++ b/Help/command/target_compile_features.rst
@@ -0,0 +1,32 @@
+target_compile_features
+-----------------------
+
+Add expected compiler features to a target.
+
+::
+
+ target_compile_features(<target> <PRIVATE|PUBLIC|INTERFACE> <feature> [...])
+
+Specify compiler features required when compiling a given target. If the
+feature is not listed in the :variable:`CMAKE_C_COMPILE_FEATURES` variable
+or :variable:`CMAKE_CXX_COMPILE_FEATURES` variable,
+then an error will be reported by CMake. If the use of the feature requires
+an additional compiler flag, such as ``-std=gnu++11``, the flag will be added
+automatically.
+
+The ``INTERFACE``, ``PUBLIC`` and ``PRIVATE`` keywords are required to
+specify the scope of the features. ``PRIVATE`` and ``PUBLIC`` items will
+populate the :prop_tgt:`COMPILE_FEATURES` property of ``<target>``.
+``PUBLIC`` and ``INTERFACE`` items will populate the
+:prop_tgt:`INTERFACE_COMPILE_FEATURES` property of ``<target>``. Repeated
+calls for the same ``<target>`` append items.
+
+The named ``<target>`` must have been created by a command such as
+:command:`add_executable` or :command:`add_library` and must not be
+an ``IMPORTED`` target.
+
+Arguments to ``target_compile_features`` may use "generator expressions"
+with the syntax ``$<...>``.
+See the :manual:`cmake-generator-expressions(7)` manual for available
+expressions. See the :manual:`cmake-compile-features(7)` manual for
+information on compile features and a list of supported compilers.
diff --git a/Help/command/target_compile_options.rst b/Help/command/target_compile_options.rst
new file mode 100644
index 000000000..73e01e7f8
--- /dev/null
+++ b/Help/command/target_compile_options.rst
@@ -0,0 +1,37 @@
+target_compile_options
+----------------------
+
+Add compile options to a target.
+
+::
+
+ target_compile_options(<target> [BEFORE]
+ <INTERFACE|PUBLIC|PRIVATE> [items1...]
+ [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
+
+Specify compile options to use when compiling a given target. The
+named ``<target>`` must have been created by a command such as
+:command:`add_executable` or :command:`add_library` and must not be an
+:ref:`IMPORTED Target <Imported Targets>`. If ``BEFORE`` is specified,
+the content will be prepended to the property instead of being appended.
+
+This command can be used to add any options, but
+alternative commands exist to add preprocessor definitions
+(:command:`target_compile_definitions` and :command:`add_definitions`) or
+include directories (:command:`target_include_directories` and
+:command:`include_directories`). See documentation of the
+:prop_dir:`directory <COMPILE_OPTIONS>` and
+:prop_tgt:`target <COMPILE_OPTIONS>` ``COMPILE_OPTIONS`` properties.
+
+The ``INTERFACE``, ``PUBLIC`` and ``PRIVATE`` keywords are required to
+specify the scope of the following arguments. ``PRIVATE`` and ``PUBLIC``
+items will populate the :prop_tgt:`COMPILE_OPTIONS` property of
+``<target>``. ``PUBLIC`` and ``INTERFACE`` items will populate the
+:prop_tgt:`INTERFACE_COMPILE_OPTIONS` property of ``<target>``. The
+following arguments specify compile options. Repeated calls for the same
+``<target>`` append items in the order called.
+
+Arguments to ``target_compile_options`` may use "generator expressions"
+with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions. See the :manual:`cmake-buildsystem(7)`
+manual for more on defining buildsystem properties.
diff --git a/Help/command/target_include_directories.rst b/Help/command/target_include_directories.rst
new file mode 100644
index 000000000..30ec2cb27
--- /dev/null
+++ b/Help/command/target_include_directories.rst
@@ -0,0 +1,62 @@
+target_include_directories
+--------------------------
+
+Add include directories to a target.
+
+::
+
+ target_include_directories(<target> [SYSTEM] [BEFORE]
+ <INTERFACE|PUBLIC|PRIVATE> [items1...]
+ [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
+
+Specify include directories to use when compiling a given target.
+The named ``<target>`` must have been created by a command such
+as :command:`add_executable` or :command:`add_library` and must not be an
+:prop_tgt:`IMPORTED` target.
+
+If ``BEFORE`` is specified, the content will be prepended to the property
+instead of being appended.
+
+The ``INTERFACE``, ``PUBLIC`` and ``PRIVATE`` keywords are required to specify
+the scope of the following arguments. ``PRIVATE`` and ``PUBLIC`` items will
+populate the :prop_tgt:`INCLUDE_DIRECTORIES` property of ``<target>``.
+``PUBLIC`` and ``INTERFACE`` items will populate the
+:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`
+property of ``<target>``. The following arguments specify include
+directories.
+
+Specified include directories may be absolute paths or relative paths.
+Repeated calls for the same <target> append items in the order called. If
+``SYSTEM`` is specified, the compiler will be told the
+directories are meant as system include directories on some platforms
+(signalling this setting might achieve effects such as the compiler
+skipping warnings, or these fixed-install system files not being
+considered in dependency calculations - see compiler docs). If ``SYSTEM``
+is used together with ``PUBLIC`` or ``INTERFACE``, the
+:prop_tgt:`INTERFACE_SYSTEM_INCLUDE_DIRECTORIES` target property will be
+populated with the specified directories.
+
+Arguments to ``target_include_directories`` may use "generator expressions"
+with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions. See the :manual:`cmake-buildsystem(7)`
+manual for more on defining buildsystem properties.
+
+Include directories usage requirements commonly differ between the build-tree
+and the install-tree. The ``BUILD_INTERFACE`` and ``INSTALL_INTERFACE``
+generator expressions can be used to describe separate usage requirements
+based on the usage location. Relative paths are allowed within the
+``INSTALL_INTERFACE`` expression and are interpreted relative to the
+installation prefix. For example:
+
+.. code-block:: cmake
+
+ target_include_directories(mylib PUBLIC
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/mylib>
+ $<INSTALL_INTERFACE:include/mylib> # <prefix>/include/mylib
+ )
+
+Creating Relocatable Packages
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. |INTERFACE_PROPERTY_LINK| replace:: :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`
+.. include:: /include/INTERFACE_INCLUDE_DIRECTORIES_WARNING.txt
diff --git a/Help/command/target_link_libraries.rst b/Help/command/target_link_libraries.rst
new file mode 100644
index 000000000..d903d0566
--- /dev/null
+++ b/Help/command/target_link_libraries.rst
@@ -0,0 +1,204 @@
+target_link_libraries
+---------------------
+
+.. only:: html
+
+ .. contents::
+
+Specify libraries or flags to use when linking a given target and/or
+its dependents. :ref:`Usage requirements <Target Usage Requirements>`
+from linked library targets will be propagated. Usage requirements
+of a target's dependencies affect compilation of its own sources.
+
+Overview
+^^^^^^^^
+
+This command has several signatures as detailed in subsections below.
+All of them have the general form::
+
+ target_link_libraries(<target> ... <item>... ...)
+
+The named ``<target>`` must have been created in the current directory by
+a command such as :command:`add_executable` or :command:`add_library`.
+Repeated calls for the same ``<target>`` append items in the order called.
+Each ``<item>`` may be:
+
+* **A library target name**: The generated link line will have the
+ full path to the linkable library file associated with the target.
+ The buildsystem will have a dependency to re-link ``<target>`` if
+ the library file changes.
+
+ The named target must be created by :command:`add_library` within
+ the project or as an :ref:`IMPORTED library <Imported Targets>`.
+ If it is created within the project an ordering dependency will
+ automatically be added in the build system to make sure the named
+ library target is up-to-date before the ``<target>`` links.
+
+ If an imported library has the :prop_tgt:`IMPORTED_NO_SONAME`
+ target property set, CMake may ask the linker to search for
+ the library instead of using the full path
+ (e.g. ``/usr/lib/libfoo.so`` becomes ``-lfoo``).
+
+* **A full path to a library file**: The generated link line will
+ normally preserve the full path to the file. The buildsystem will
+ have a dependency to re-link ``<target>`` if the library file changes.
+
+ There are some cases where CMake may ask the linker to search for
+ the library (e.g. ``/usr/lib/libfoo.so`` becomes ``-lfoo``), such
+ as when a shared library is detected to have no ``SONAME`` field.
+ See policy :policy:`CMP0060` for discussion of another case.
+
+ If the library file is in a Mac OSX framework, the ``Headers`` directory
+ of the framework will also be processed as a
+ :ref:`usage requirement <Target Usage Requirements>`. This has the same
+ effect as passing the framework directory as an include directory.
+
+* **A plain library name**: The generated link line will ask the linker
+ to search for the library (e.g. ``foo`` becomes ``-lfoo`` or ``foo.lib``).
+
+* **A link flag**: Item names starting with ``-``, but not ``-l`` or
+ ``-framework``, are treated as linker flags. Note that such flags will
+ be treated like any other library link item for purposes of transitive
+ dependencies, so they are generally safe to specify only as private link
+ items that will not propagate to dependents.
+
+* A ``debug``, ``optimized``, or ``general`` keyword immediately followed
+ by another ``<item>``. The item following such a keyword will be used
+ only for the corresponding build configuration. The ``debug`` keyword
+ corresponds to the ``Debug`` configuration (or to configurations named
+ in the :prop_gbl:`DEBUG_CONFIGURATIONS` global property if it is set).
+ The ``optimized`` keyword corresponds to all other configurations. The
+ ``general`` keyword corresponds to all configurations, and is purely
+ optional. Higher granularity may be achieved for per-configuration
+ rules by creating and linking to
+ :ref:`IMPORTED library targets <Imported Targets>`.
+
+Items containing ``::``, such as ``Foo::Bar``, are assumed to be
+:ref:`IMPORTED <Imported Targets>` or :ref:`ALIAS <Alias Targets>` library
+target names and will cause an error if no such target exists.
+See policy :policy:`CMP0028`.
+
+Arguments to ``target_link_libraries`` may use "generator expressions"
+with the syntax ``$<...>``. Note however, that generator expressions
+will not be used in OLD handling of :policy:`CMP0003` or :policy:`CMP0004`.
+See the :manual:`cmake-generator-expressions(7)` manual for available
+expressions. See the :manual:`cmake-buildsystem(7)` manual for more on
+defining buildsystem properties.
+
+Libraries for a Target and/or its Dependents
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+ target_link_libraries(<target>
+ <PRIVATE|PUBLIC|INTERFACE> <item>...
+ [<PRIVATE|PUBLIC|INTERFACE> <item>...]...)
+
+The ``PUBLIC``, ``PRIVATE`` and ``INTERFACE`` keywords can be used to
+specify both the link dependencies and the link interface in one command.
+Libraries and targets following ``PUBLIC`` are linked to, and are made
+part of the link interface. Libraries and targets following ``PRIVATE``
+are linked to, but are not made part of the link interface. Libraries
+following ``INTERFACE`` are appended to the link interface and are not
+used for linking ``<target>``.
+
+Libraries for both a Target and its Dependents
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+ target_link_libraries(<target> <item>...)
+
+Library dependencies are transitive by default with this signature.
+When this target is linked into another target then the libraries
+linked to this target will appear on the link line for the other
+target too. This transitive "link interface" is stored in the
+:prop_tgt:`INTERFACE_LINK_LIBRARIES` target property and may be overridden
+by setting the property directly. When :policy:`CMP0022` is not set to
+``NEW``, transitive linking is built in but may be overridden by the
+:prop_tgt:`LINK_INTERFACE_LIBRARIES` property. Calls to other signatures
+of this command may set the property making any libraries linked
+exclusively by this signature private.
+
+Libraries for a Target and/or its Dependents (Legacy)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+ target_link_libraries(<target>
+ <LINK_PRIVATE|LINK_PUBLIC> <lib>...
+ [<LINK_PRIVATE|LINK_PUBLIC> <lib>...]...)
+
+The ``LINK_PUBLIC`` and ``LINK_PRIVATE`` modes can be used to specify both
+the link dependencies and the link interface in one command.
+
+This signature is for compatibility only. Prefer the ``PUBLIC`` or
+``PRIVATE`` keywords instead.
+
+Libraries and targets following ``LINK_PUBLIC`` are linked to, and are
+made part of the :prop_tgt:`INTERFACE_LINK_LIBRARIES`. If policy
+:policy:`CMP0022` is not ``NEW``, they are also made part of the
+:prop_tgt:`LINK_INTERFACE_LIBRARIES`. Libraries and targets following
+``LINK_PRIVATE`` are linked to, but are not made part of the
+:prop_tgt:`INTERFACE_LINK_LIBRARIES` (or :prop_tgt:`LINK_INTERFACE_LIBRARIES`).
+
+Libraries for Dependents Only (Legacy)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+ target_link_libraries(<target> LINK_INTERFACE_LIBRARIES <item>...)
+
+The ``LINK_INTERFACE_LIBRARIES`` mode appends the libraries to the
+:prop_tgt:`INTERFACE_LINK_LIBRARIES` target property instead of using them
+for linking. If policy :policy:`CMP0022` is not ``NEW``, then this mode
+also appends libraries to the :prop_tgt:`LINK_INTERFACE_LIBRARIES` and its
+per-configuration equivalent.
+
+This signature is for compatibility only. Prefer the ``INTERFACE`` mode
+instead.
+
+Libraries specified as ``debug`` are wrapped in a generator expression to
+correspond to debug builds. If policy :policy:`CMP0022` is
+not ``NEW``, the libraries are also appended to the
+:prop_tgt:`LINK_INTERFACE_LIBRARIES_DEBUG <LINK_INTERFACE_LIBRARIES_<CONFIG>>`
+property (or to the properties corresponding to configurations listed in
+the :prop_gbl:`DEBUG_CONFIGURATIONS` global property if it is set).
+Libraries specified as ``optimized`` are appended to the
+:prop_tgt:`INTERFACE_LINK_LIBRARIES` property. If policy :policy:`CMP0022`
+is not ``NEW``, they are also appended to the
+:prop_tgt:`LINK_INTERFACE_LIBRARIES` property. Libraries specified as
+``general`` (or without any keyword) are treated as if specified for both
+``debug`` and ``optimized``.
+
+Cyclic Dependencies of Static Libraries
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The library dependency graph is normally acyclic (a DAG), but in the case
+of mutually-dependent ``STATIC`` libraries CMake allows the graph to
+contain cycles (strongly connected components). When another target links
+to one of the libraries, CMake repeats the entire connected component.
+For example, the code
+
+.. code-block:: cmake
+
+ add_library(A STATIC a.c)
+ add_library(B STATIC b.c)
+ target_link_libraries(A B)
+ target_link_libraries(B A)
+ add_executable(main main.c)
+ target_link_libraries(main A)
+
+links ``main`` to ``A B A B``. While one repetition is usually
+sufficient, pathological object file and symbol arrangements can require
+more. One may handle such cases by using the
+:prop_tgt:`LINK_INTERFACE_MULTIPLICITY` target property or by manually
+repeating the component in the last ``target_link_libraries`` call.
+However, if two archives are really so interdependent they should probably
+be combined into a single archive, perhaps by using :ref:`Object Libraries`.
+
+Creating Relocatable Packages
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. |INTERFACE_PROPERTY_LINK| replace:: :prop_tgt:`INTERFACE_LINK_LIBRARIES`
+.. include:: /include/INTERFACE_LINK_LIBRARIES_WARNING.txt
diff --git a/Help/command/target_sources.rst b/Help/command/target_sources.rst
new file mode 100644
index 000000000..d6f148d23
--- /dev/null
+++ b/Help/command/target_sources.rst
@@ -0,0 +1,28 @@
+target_sources
+--------------
+
+Add sources to a target.
+
+::
+
+ target_sources(<target>
+ <INTERFACE|PUBLIC|PRIVATE> [items1...]
+ [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
+
+Specify sources to use when compiling a given target. The
+named ``<target>`` must have been created by a command such as
+:command:`add_executable` or :command:`add_library` and must not be an
+:ref:`IMPORTED Target <Imported Targets>`.
+
+The ``INTERFACE``, ``PUBLIC`` and ``PRIVATE`` keywords are required to
+specify the scope of the following arguments. ``PRIVATE`` and ``PUBLIC``
+items will populate the :prop_tgt:`SOURCES` property of
+``<target>``. ``PUBLIC`` and ``INTERFACE`` items will populate the
+:prop_tgt:`INTERFACE_SOURCES` property of ``<target>``. The
+following arguments specify sources. Repeated calls for the same
+``<target>`` append items in the order called.
+
+Arguments to ``target_sources`` may use "generator expressions"
+with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions. See the :manual:`cmake-buildsystem(7)`
+manual for more on defining buildsystem properties.
diff --git a/Help/command/try_compile.rst b/Help/command/try_compile.rst
new file mode 100644
index 000000000..28dae8074
--- /dev/null
+++ b/Help/command/try_compile.rst
@@ -0,0 +1,114 @@
+try_compile
+-----------
+
+.. only:: html
+
+ .. contents::
+
+Try building some code.
+
+Try Compiling Whole Projects
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+ try_compile(RESULT_VAR <bindir> <srcdir>
+ <projectName> [<targetName>] [CMAKE_FLAGS <flags>...]
+ [OUTPUT_VARIABLE <var>])
+
+Try building a project. The success or failure of the ``try_compile``,
+i.e. ``TRUE`` or ``FALSE`` respectively, is returned in ``RESULT_VAR``.
+
+In this form, ``<srcdir>`` should contain a complete CMake project with a
+``CMakeLists.txt`` file and all sources. The ``<bindir>`` and ``<srcdir>``
+will not be deleted after this command is run. Specify ``<targetName>`` to
+build a specific target instead of the ``all`` or ``ALL_BUILD`` target. See
+below for the meaning of other options.
+
+Try Compiling Source Files
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+ try_compile(RESULT_VAR <bindir> <srcfile|SOURCES srcfile...>
+ [CMAKE_FLAGS <flags>...]
+ [COMPILE_DEFINITIONS <defs>...]
+ [LINK_LIBRARIES <libs>...]
+ [OUTPUT_VARIABLE <var>]
+ [COPY_FILE <fileName> [COPY_FILE_ERROR <var>]])
+
+Try building an executable from one or more source files. The success or
+failure of the ``try_compile``, i.e. ``TRUE`` or ``FALSE`` respectively, is
+returned in ``RESULT_VAR``.
+
+In this form the user need only supply one or more source files that include a
+definition for ``main``. CMake will create a ``CMakeLists.txt`` file to build
+the source(s) as an executable that looks something like this::
+
+ add_definitions(<expanded COMPILE_DEFINITIONS from caller>)
+ include_directories(${INCLUDE_DIRECTORIES})
+ link_directories(${LINK_DIRECTORIES})
+ add_executable(cmTryCompileExec <srcfile>...)
+ target_link_libraries(cmTryCompileExec ${LINK_LIBRARIES})
+
+The options are:
+
+``CMAKE_FLAGS <flags>...``
+ Specify flags of the form ``-DVAR:TYPE=VALUE`` to be passed to
+ the ``cmake`` command-line used to drive the test build.
+ The above example shows how values for variables
+ ``INCLUDE_DIRECTORIES``, ``LINK_DIRECTORIES``, and ``LINK_LIBRARIES``
+ are used.
+
+``COMPILE_DEFINITIONS <defs>...``
+ Specify ``-Ddefinition`` arguments to pass to ``add_definitions``
+ in the generated test project.
+
+``COPY_FILE <fileName>``
+ Copy the linked executable to the given ``<fileName>``.
+
+``COPY_FILE_ERROR <var>``
+ Use after ``COPY_FILE`` to capture into variable ``<var>`` any error
+ message encountered while trying to copy the file.
+
+``LINK_LIBRARIES <libs>...``
+ Specify libraries to be linked in the generated project.
+ The list of libraries may refer to system libraries and to
+ :ref:`Imported Targets <Imported Targets>` from the calling project.
+
+ If this option is specified, any ``-DLINK_LIBRARIES=...`` value
+ given to the ``CMAKE_FLAGS`` option will be ignored.
+
+``OUTPUT_VARIABLE <var>``
+ Store the output from the build process the given variable.
+
+In this version all files in ``<bindir>/CMakeFiles/CMakeTmp`` will be
+cleaned automatically. For debugging, ``--debug-trycompile`` can be
+passed to ``cmake`` to avoid this clean. However, multiple sequential
+``try_compile`` operations reuse this single output directory. If you use
+``--debug-trycompile``, you can only debug one ``try_compile`` call at a time.
+The recommended procedure is to protect all ``try_compile`` calls in your
+project by ``if(NOT DEFINED RESULT_VAR)`` logic, configure with cmake
+all the way through once, then delete the cache entry associated with
+the try_compile call of interest, and then re-run cmake again with
+``--debug-trycompile``.
+
+Other Behavior Settings
+^^^^^^^^^^^^^^^^^^^^^^^
+
+If set, the following variables are passed in to the generated
+try_compile CMakeLists.txt to initialize compile target properties with
+default values:
+
+* :variable:`CMAKE_ENABLE_EXPORTS`
+* :variable:`CMAKE_LINK_SEARCH_START_STATIC`
+* :variable:`CMAKE_LINK_SEARCH_END_STATIC`
+* :variable:`CMAKE_POSITION_INDEPENDENT_CODE`
+
+If :policy:`CMP0056` is set to ``NEW``, then
+:variable:`CMAKE_EXE_LINKER_FLAGS` is passed in as well.
+
+The current setting of :policy:`CMP0065` is set in the generated project.
+
+Set the :variable:`CMAKE_TRY_COMPILE_CONFIGURATION` variable to choose
+a build configuration.
diff --git a/Help/command/try_run.rst b/Help/command/try_run.rst
new file mode 100644
index 000000000..e3bd57d50
--- /dev/null
+++ b/Help/command/try_run.rst
@@ -0,0 +1,98 @@
+try_run
+-------
+
+.. only:: html
+
+ .. contents::
+
+Try compiling and then running some code.
+
+Try Compiling and Running Source Files
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+ try_run(RUN_RESULT_VAR COMPILE_RESULT_VAR
+ bindir srcfile [CMAKE_FLAGS <flags>...]
+ [COMPILE_DEFINITIONS <defs>...]
+ [LINK_LIBRARIES <libs>...]
+ [COMPILE_OUTPUT_VARIABLE <var>]
+ [RUN_OUTPUT_VARIABLE <var>]
+ [OUTPUT_VARIABLE <var>]
+ [ARGS <args>...])
+
+Try compiling a ``<srcfile>``. Returns ``TRUE`` or ``FALSE`` for success
+or failure in ``COMPILE_RESULT_VAR``. If the compile succeeded, runs the
+executable and returns its exit code in ``RUN_RESULT_VAR``. If the
+executable was built, but failed to run, then ``RUN_RESULT_VAR`` will be
+set to ``FAILED_TO_RUN``. See the :command:`try_compile` command for
+information on how the test project is constructed to build the source file.
+
+The options are:
+
+``CMAKE_FLAGS <flags>...``
+ Specify flags of the form ``-DVAR:TYPE=VALUE`` to be passed to
+ the ``cmake`` command-line used to drive the test build.
+ The example in :command:`try_compile` shows how values for variables
+ ``INCLUDE_DIRECTORIES``, ``LINK_DIRECTORIES``, and ``LINK_LIBRARIES``
+ are used.
+
+``COMPILE_DEFINITIONS <defs>...``
+ Specify ``-Ddefinition`` arguments to pass to ``add_definitions``
+ in the generated test project.
+
+``COMPILE_OUTPUT_VARIABLE <var>``
+ Report the compile step build output in a given variable.
+
+``LINK_LIBRARIES <libs>...``
+ Specify libraries to be linked in the generated project.
+ The list of libraries may refer to system libraries and to
+ :ref:`Imported Targets <Imported Targets>` from the calling project.
+
+ If this option is specified, any ``-DLINK_LIBRARIES=...`` value
+ given to the ``CMAKE_FLAGS`` option will be ignored.
+
+``OUTPUT_VARIABLE <var>``
+ Report the compile build output and the output from running the executable
+ in the given variable. This option exists for legacy reasons. Prefer
+ ``COMPILE_OUTPUT_VARIABLE`` and ``RUN_OUTPUT_VARIABLE`` instead.
+
+``RUN_OUTPUT_VARIABLE <var>``
+ Report the output from running the executable in a given variable.
+
+Other Behavior Settings
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Set the :variable:`CMAKE_TRY_COMPILE_CONFIGURATION` variable to choose
+a build configuration.
+
+Behavior when Cross Compiling
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When cross compiling, the executable compiled in the first step
+usually cannot be run on the build host. The ``try_run`` command checks
+the :variable:`CMAKE_CROSSCOMPILING` variable to detect whether CMake is in
+cross-compiling mode. If that is the case, it will still try to compile
+the executable, but it will not try to run the executable unless the
+:variable:`CMAKE_CROSSCOMPILING_EMULATOR` variable is set. Instead it
+will create cache variables which must be filled by the user or by
+presetting them in some CMake script file to the values the executable
+would have produced if it had been run on its actual target platform.
+These cache entries are:
+
+``<RUN_RESULT_VAR>``
+ Exit code if the executable were to be run on the target platform.
+
+``<RUN_RESULT_VAR>__TRYRUN_OUTPUT``
+ Output from stdout and stderr if the executable were to be run on
+ the target platform. This is created only if the
+ ``RUN_OUTPUT_VARIABLE`` or ``OUTPUT_VARIABLE`` option was used.
+
+In order to make cross compiling your project easier, use ``try_run``
+only if really required. If you use ``try_run``, use the
+``RUN_OUTPUT_VARIABLE`` or ``OUTPUT_VARIABLE`` options only if really
+required. Using them will require that when cross-compiling, the cache
+variables will have to be set manually to the output of the executable.
+You can also "guard" the calls to ``try_run`` with an :command:`if`
+block checking the :variable:`CMAKE_CROSSCOMPILING` variable and
+provide an easy-to-preset alternative for this case.
diff --git a/Help/command/unset.rst b/Help/command/unset.rst
new file mode 100644
index 000000000..a1fc95cc6
--- /dev/null
+++ b/Help/command/unset.rst
@@ -0,0 +1,25 @@
+unset
+-----
+
+Unset a variable, cache variable, or environment variable.
+
+::
+
+ unset(<variable> [CACHE | PARENT_SCOPE])
+
+Removes the specified variable causing it to become undefined. If
+``CACHE`` is present then the variable is removed from the cache instead
+of the current scope.
+
+If ``PARENT_SCOPE`` is present then the variable is removed from the scope
+above the current scope. See the same option in the :command:`set` command
+for further details.
+
+``<variable>`` can be an environment variable such as:
+
+::
+
+ unset(ENV{LD_LIBRARY_PATH})
+
+in which case the variable will be removed from the current
+environment.
diff --git a/Help/command/use_mangled_mesa.rst b/Help/command/use_mangled_mesa.rst
new file mode 100644
index 000000000..6f4d7aca6
--- /dev/null
+++ b/Help/command/use_mangled_mesa.rst
@@ -0,0 +1,15 @@
+use_mangled_mesa
+----------------
+
+Disallowed. See CMake Policy :policy:`CMP0030`.
+
+Copy mesa headers for use in combination with system GL.
+
+::
+
+ use_mangled_mesa(PATH_TO_MESA OUTPUT_DIRECTORY)
+
+The path to mesa includes, should contain gl_mangle.h. The mesa
+headers are copied to the specified output directory. This allows
+mangled mesa headers to override other GL headers by being added to
+the include directory path earlier.
diff --git a/Help/command/utility_source.rst b/Help/command/utility_source.rst
new file mode 100644
index 000000000..ee34492c3
--- /dev/null
+++ b/Help/command/utility_source.rst
@@ -0,0 +1,24 @@
+utility_source
+--------------
+
+Disallowed. See CMake Policy :policy:`CMP0034`.
+
+Specify the source tree of a third-party utility.
+
+::
+
+ utility_source(cache_entry executable_name
+ path_to_source [file1 file2 ...])
+
+When a third-party utility's source is included in the distribution,
+this command specifies its location and name. The cache entry will
+not be set unless the ``path_to_source`` and all listed files exist. It
+is assumed that the source tree of the utility will have been built
+before it is needed.
+
+When cross compiling CMake will print a warning if a ``utility_source()``
+command is executed, because in many cases it is used to build an
+executable which is executed later on. This doesn't work when cross
+compiling, since the executable can run only on their target platform.
+So in this case the cache entry has to be adjusted manually so it
+points to an executable which is runnable on the build host.
diff --git a/Help/command/variable_requires.rst b/Help/command/variable_requires.rst
new file mode 100644
index 000000000..9cf9f3ffd
--- /dev/null
+++ b/Help/command/variable_requires.rst
@@ -0,0 +1,22 @@
+variable_requires
+-----------------
+
+Disallowed. See CMake Policy :policy:`CMP0035`.
+
+Use the :command:`if` command instead.
+
+Assert satisfaction of an option's required variables.
+
+::
+
+ variable_requires(TEST_VARIABLE RESULT_VARIABLE
+ REQUIRED_VARIABLE1
+ REQUIRED_VARIABLE2 ...)
+
+The first argument (``TEST_VARIABLE``) is the name of the variable to be
+tested, if that variable is false nothing else is done. If
+``TEST_VARIABLE`` is true, then the next argument (``RESULT_VARIABLE``)
+is a variable that is set to true if all the required variables are set.
+The rest of the arguments are variables that must be true or not set
+to NOTFOUND to avoid an error. If any are not true, an error is
+reported.
diff --git a/Help/command/variable_watch.rst b/Help/command/variable_watch.rst
new file mode 100644
index 000000000..a2df058eb
--- /dev/null
+++ b/Help/command/variable_watch.rst
@@ -0,0 +1,13 @@
+variable_watch
+--------------
+
+Watch the CMake variable for change.
+
+::
+
+ variable_watch(<variable name> [<command to execute>])
+
+If the specified variable changes, the message will be printed about
+the variable being changed. If the command is specified, the command
+will be executed. The command will receive the following arguments:
+COMMAND(<variable> <access> <value> <current list file> <stack>)
diff --git a/Help/command/while.rst b/Help/command/while.rst
new file mode 100644
index 000000000..7509da309
--- /dev/null
+++ b/Help/command/while.rst
@@ -0,0 +1,17 @@
+while
+-----
+
+Evaluate a group of commands while a condition is true
+
+::
+
+ while(condition)
+ COMMAND1(ARGS ...)
+ COMMAND2(ARGS ...)
+ ...
+ endwhile(condition)
+
+All commands between while and the matching :command:`endwhile` are recorded
+without being invoked. Once the :command:`endwhile` is evaluated, the
+recorded list of commands is invoked as long as the condition is true. The
+condition is evaluated using the same logic as the :command:`if` command.
diff --git a/Help/command/write_file.rst b/Help/command/write_file.rst
new file mode 100644
index 000000000..40e755763
--- /dev/null
+++ b/Help/command/write_file.rst
@@ -0,0 +1,20 @@
+write_file
+----------
+
+Deprecated. Use the :command:`file(WRITE)` command instead.
+
+::
+
+ write_file(filename "message to write"... [APPEND])
+
+The first argument is the file name, the rest of the arguments are
+messages to write. If the argument ``APPEND`` is specified, then the
+message will be appended.
+
+NOTE 1: :command:`file(WRITE)` and :command:`file(APPEND)` do exactly
+the same as this one but add some more functionality.
+
+NOTE 2: When using ``write_file`` the produced file cannot be used as an
+input to CMake (CONFIGURE_FILE, source file ...) because it will lead
+to an infinite loop. Use :command:`configure_file` if you want to
+generate input files to CMake.
diff --git a/Help/generator/Borland Makefiles.rst b/Help/generator/Borland Makefiles.rst
new file mode 100644
index 000000000..c00d00a86
--- /dev/null
+++ b/Help/generator/Borland Makefiles.rst
@@ -0,0 +1,4 @@
+Borland Makefiles
+-----------------
+
+Generates Borland makefiles.
diff --git a/Help/generator/CodeBlocks.rst b/Help/generator/CodeBlocks.rst
new file mode 100644
index 000000000..01798c7f0
--- /dev/null
+++ b/Help/generator/CodeBlocks.rst
@@ -0,0 +1,25 @@
+CodeBlocks
+----------
+
+Generates CodeBlocks project files.
+
+Project files for CodeBlocks will be created in the top directory and
+in every subdirectory which features a CMakeLists.txt file containing
+a PROJECT() call. Additionally a hierarchy of makefiles is generated
+into the build tree. The appropriate make program can build the
+project through the default make target. A "make install" target is
+also provided.
+
+This "extra" generator may be specified as:
+
+``CodeBlocks - MinGW Makefiles``
+ Generate with :generator:`MinGW Makefiles`.
+
+``CodeBlocks - NMake Makefiles``
+ Generate with :generator:`NMake Makefiles`.
+
+``CodeBlocks - Ninja``
+ Generate with :generator:`Ninja`.
+
+``CodeBlocks - Unix Makefiles``
+ Generate with :generator:`Unix Makefiles`.
diff --git a/Help/generator/CodeLite.rst b/Help/generator/CodeLite.rst
new file mode 100644
index 000000000..dbc46d72b
--- /dev/null
+++ b/Help/generator/CodeLite.rst
@@ -0,0 +1,24 @@
+CodeLite
+----------
+
+Generates CodeLite project files.
+
+Project files for CodeLite will be created in the top directory and
+in every subdirectory which features a CMakeLists.txt file containing
+a PROJECT() call. The appropriate make program can build the
+project through the default make target. A "make install" target is
+also provided.
+
+This "extra" generator may be specified as:
+
+``CodeLite - MinGW Makefiles``
+ Generate with :generator:`MinGW Makefiles`.
+
+``CodeLite - NMake Makefiles``
+ Generate with :generator:`NMake Makefiles`.
+
+``CodeLite - Ninja``
+ Generate with :generator:`Ninja`.
+
+``CodeLite - Unix Makefiles``
+ Generate with :generator:`Unix Makefiles`.
diff --git a/Help/generator/Eclipse CDT4.rst b/Help/generator/Eclipse CDT4.rst
new file mode 100644
index 000000000..eb68bf094
--- /dev/null
+++ b/Help/generator/Eclipse CDT4.rst
@@ -0,0 +1,25 @@
+Eclipse CDT4
+------------
+
+Generates Eclipse CDT 4.0 project files.
+
+Project files for Eclipse will be created in the top directory. In
+out of source builds, a linked resource to the top level source
+directory will be created. Additionally a hierarchy of makefiles is
+generated into the build tree. The appropriate make program can build
+the project through the default make target. A "make install" target
+is also provided.
+
+This "extra" generator may be specified as:
+
+``Eclipse CDT4 - MinGW Makefiles``
+ Generate with :generator:`MinGW Makefiles`.
+
+``Eclipse CDT4 - NMake Makefiles``
+ Generate with :generator:`NMake Makefiles`.
+
+``Eclipse CDT4 - Ninja``
+ Generate with :generator:`Ninja`.
+
+``Eclipse CDT4 - Unix Makefiles``
+ Generate with :generator:`Unix Makefiles`.
diff --git a/Help/generator/Green Hills MULTI.rst b/Help/generator/Green Hills MULTI.rst
new file mode 100644
index 000000000..4d3169026
--- /dev/null
+++ b/Help/generator/Green Hills MULTI.rst
@@ -0,0 +1,16 @@
+Green Hills MULTI
+-----------------
+
+Generates Green Hills MULTI project files (experimental, work-in-progress).
+
+Customizations are available through the following cache variables:
+
+* ``GHS_BSP_NAME``
+* ``GHS_CUSTOMIZATION``
+* ``GHS_GPJ_MACROS``
+* ``GHS_OS_DIR``
+
+.. note::
+ This generator is deemed experimental as of CMake |release|
+ and is still a work in progress. Future versions of CMake
+ may make breaking changes as the generator matures.
diff --git a/Help/generator/KDevelop3.rst b/Help/generator/KDevelop3.rst
new file mode 100644
index 000000000..eaa218bc8
--- /dev/null
+++ b/Help/generator/KDevelop3.rst
@@ -0,0 +1,25 @@
+KDevelop3
+---------
+
+Generates KDevelop 3 project files.
+
+Project files for KDevelop 3 will be created in the top directory and
+in every subdirectory which features a CMakeLists.txt file containing
+a PROJECT() call. If you change the settings using KDevelop cmake
+will try its best to keep your changes when regenerating the project
+files. Additionally a hierarchy of UNIX makefiles is generated into
+the build tree. Any standard UNIX-style make program can build the
+project through the default make target. A "make install" target is
+also provided.
+
+This "extra" generator may be specified as:
+
+``KDevelop3 - Unix Makefiles``
+ Generate with :generator:`Unix Makefiles`.
+
+``KDevelop3``
+ Generate with :generator:`Unix Makefiles`.
+
+ For historical reasons this extra generator may be specified
+ directly as the main generator and it will be used as the
+ extra generator with :generator:`Unix Makefiles` automatically.
diff --git a/Help/generator/Kate.rst b/Help/generator/Kate.rst
new file mode 100644
index 000000000..9b61a93b3
--- /dev/null
+++ b/Help/generator/Kate.rst
@@ -0,0 +1,26 @@
+Kate
+----
+
+Generates Kate project files.
+
+A project file for Kate will be created in the top directory in the top level
+build directory.
+To use it in kate, the Project plugin must be enabled.
+The project file is loaded in kate simply by opening the
+ProjectName.kateproject file in the editor.
+If the kate Build-plugin is enabled, all targets generated by CMake are
+available for building.
+
+This "extra" generator may be specified as:
+
+``Kate - MinGW Makefiles``
+ Generate with :generator:`MinGW Makefiles`.
+
+``Kate - NMake Makefiles``
+ Generate with :generator:`NMake Makefiles`.
+
+``Kate - Ninja``
+ Generate with :generator:`Ninja`.
+
+``Kate - Unix Makefiles``
+ Generate with :generator:`Unix Makefiles`.
diff --git a/Help/generator/MSYS Makefiles.rst b/Help/generator/MSYS Makefiles.rst
new file mode 100644
index 000000000..f7cfa4461
--- /dev/null
+++ b/Help/generator/MSYS Makefiles.rst
@@ -0,0 +1,11 @@
+MSYS Makefiles
+--------------
+
+Generates makefiles for use with MSYS ``make`` under the MSYS shell.
+
+Use this generator in a MSYS shell prompt and using ``make`` as the build
+tool. The generated makefiles use ``/bin/sh`` as the shell to launch build
+rules. They are not compatible with a Windows command prompt.
+
+To build under a Windows command prompt, use the
+:generator:`MinGW Makefiles` generator.
diff --git a/Help/generator/MinGW Makefiles.rst b/Help/generator/MinGW Makefiles.rst
new file mode 100644
index 000000000..9fe5fe3e5
--- /dev/null
+++ b/Help/generator/MinGW Makefiles.rst
@@ -0,0 +1,12 @@
+MinGW Makefiles
+---------------
+
+Generates makefiles for use with ``mingw32-make`` under a Windows command
+prompt.
+
+Use this generator under a Windows command prompt with MinGW in the ``PATH``
+and using ``mingw32-make`` as the build tool. The generated makefiles use
+``cmd.exe`` as the shell to launch build rules. They are not compatible with
+MSYS or a unix shell.
+
+To build under the MSYS shell, use the :generator:`MSYS Makefiles` generator.
diff --git a/Help/generator/NMake Makefiles JOM.rst b/Help/generator/NMake Makefiles JOM.rst
new file mode 100644
index 000000000..3a8744c1e
--- /dev/null
+++ b/Help/generator/NMake Makefiles JOM.rst
@@ -0,0 +1,4 @@
+NMake Makefiles JOM
+-------------------
+
+Generates JOM makefiles.
diff --git a/Help/generator/NMake Makefiles.rst b/Help/generator/NMake Makefiles.rst
new file mode 100644
index 000000000..89f2479b7
--- /dev/null
+++ b/Help/generator/NMake Makefiles.rst
@@ -0,0 +1,4 @@
+NMake Makefiles
+---------------
+
+Generates NMake makefiles.
diff --git a/Help/generator/Ninja.rst b/Help/generator/Ninja.rst
new file mode 100644
index 000000000..920abcbfa
--- /dev/null
+++ b/Help/generator/Ninja.rst
@@ -0,0 +1,8 @@
+Ninja
+-----
+
+Generates build.ninja files.
+
+A build.ninja file is generated into the build tree. Recent versions
+of the ninja program can build the project through the "all" target.
+An "install" target is also provided.
diff --git a/Help/generator/Sublime Text 2.rst b/Help/generator/Sublime Text 2.rst
new file mode 100644
index 000000000..0597a9528
--- /dev/null
+++ b/Help/generator/Sublime Text 2.rst
@@ -0,0 +1,25 @@
+Sublime Text 2
+--------------
+
+Generates Sublime Text 2 project files.
+
+Project files for Sublime Text 2 will be created in the top directory
+and in every subdirectory which features a CMakeLists.txt file
+containing a PROJECT() call. Additionally Makefiles (or build.ninja
+files) are generated into the build tree. The appropriate make
+program can build the project through the default make target. A
+"make install" target is also provided.
+
+This "extra" generator may be specified as:
+
+``Sublime Text 2 - MinGW Makefiles``
+ Generate with :generator:`MinGW Makefiles`.
+
+``Sublime Text 2 - NMake Makefiles``
+ Generate with :generator:`NMake Makefiles`.
+
+``Sublime Text 2 - Ninja``
+ Generate with :generator:`Ninja`.
+
+``Sublime Text 2 - Unix Makefiles``
+ Generate with :generator:`Unix Makefiles`.
diff --git a/Help/generator/Unix Makefiles.rst b/Help/generator/Unix Makefiles.rst
new file mode 100644
index 000000000..97d74a853
--- /dev/null
+++ b/Help/generator/Unix Makefiles.rst
@@ -0,0 +1,8 @@
+Unix Makefiles
+--------------
+
+Generates standard UNIX makefiles.
+
+A hierarchy of UNIX makefiles is generated into the build tree. Any
+standard UNIX-style make program can build the project through the
+default make target. A "make install" target is also provided.
diff --git a/Help/generator/Visual Studio 10 2010.rst b/Help/generator/Visual Studio 10 2010.rst
new file mode 100644
index 000000000..77ea9df02
--- /dev/null
+++ b/Help/generator/Visual Studio 10 2010.rst
@@ -0,0 +1,19 @@
+Visual Studio 10 2010
+---------------------
+
+Generates Visual Studio 10 (VS 2010) project files.
+
+The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set
+to specify a target platform name.
+
+For compatibility with CMake versions prior to 3.1, one may specify
+a target platform name optionally at the end of this generator name:
+
+``Visual Studio 10 2010 Win64``
+ Specify target platform ``x64``.
+
+``Visual Studio 10 2010 IA64``
+ Specify target platform ``Itanium``.
+
+For compatibility with CMake versions prior to 3.0, one may specify this
+generator using the name ``Visual Studio 10`` without the year component.
diff --git a/Help/generator/Visual Studio 11 2012.rst b/Help/generator/Visual Studio 11 2012.rst
new file mode 100644
index 000000000..5fa7f2c76
--- /dev/null
+++ b/Help/generator/Visual Studio 11 2012.rst
@@ -0,0 +1,22 @@
+Visual Studio 11 2012
+---------------------
+
+Generates Visual Studio 11 (VS 2012) project files.
+
+The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set
+to specify a target platform name.
+
+For compatibility with CMake versions prior to 3.1, one may specify
+a target platform name optionally at the end of this generator name:
+
+``Visual Studio 11 2012 Win64``
+ Specify target platform ``x64``.
+
+``Visual Studio 11 2012 ARM``
+ Specify target platform ``ARM``.
+
+``Visual Studio 11 2012 <WinCE-SDK>``
+ Specify target platform matching a Windows CE SDK name.
+
+For compatibility with CMake versions prior to 3.0, one may specify this
+generator using the name "Visual Studio 11" without the year component.
diff --git a/Help/generator/Visual Studio 12 2013.rst b/Help/generator/Visual Studio 12 2013.rst
new file mode 100644
index 000000000..2c3b119a4
--- /dev/null
+++ b/Help/generator/Visual Studio 12 2013.rst
@@ -0,0 +1,19 @@
+Visual Studio 12 2013
+---------------------
+
+Generates Visual Studio 12 (VS 2013) project files.
+
+The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set
+to specify a target platform name.
+
+For compatibility with CMake versions prior to 3.1, one may specify
+a target platform name optionally at the end of this generator name:
+
+``Visual Studio 12 2013 Win64``
+ Specify target platform ``x64``.
+
+``Visual Studio 12 2013 ARM``
+ Specify target platform ``ARM``.
+
+For compatibility with CMake versions prior to 3.0, one may specify this
+generator using the name "Visual Studio 12" without the year component.
diff --git a/Help/generator/Visual Studio 14 2015.rst b/Help/generator/Visual Studio 14 2015.rst
new file mode 100644
index 000000000..b35997a10
--- /dev/null
+++ b/Help/generator/Visual Studio 14 2015.rst
@@ -0,0 +1,16 @@
+Visual Studio 14 2015
+---------------------
+
+Generates Visual Studio 14 (VS 2015) project files.
+
+The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set
+to specify a target platform name.
+
+For compatibility with CMake versions prior to 3.1, one may specify
+a target platform name optionally at the end of this generator name:
+
+``Visual Studio 14 2015 Win64``
+ Specify target platform ``x64``.
+
+``Visual Studio 14 2015 ARM``
+ Specify target platform ``ARM``.
diff --git a/Help/generator/Visual Studio 6.rst b/Help/generator/Visual Studio 6.rst
new file mode 100644
index 000000000..855589c93
--- /dev/null
+++ b/Help/generator/Visual Studio 6.rst
@@ -0,0 +1,10 @@
+Visual Studio 6
+---------------
+
+Deprected. Generates Visual Studio 6 project files.
+
+.. note::
+ This generator is deprecated and will be removed
+ in a future version of CMake. It will still be
+ possible to build with VS 6 tools using the
+ :generator:`NMake Makefiles` generator.
diff --git a/Help/generator/Visual Studio 7 .NET 2003.rst b/Help/generator/Visual Studio 7 .NET 2003.rst
new file mode 100644
index 000000000..20341402b
--- /dev/null
+++ b/Help/generator/Visual Studio 7 .NET 2003.rst
@@ -0,0 +1,4 @@
+Visual Studio 7 .NET 2003
+-------------------------
+
+Generates Visual Studio .NET 2003 project files.
diff --git a/Help/generator/Visual Studio 7.rst b/Help/generator/Visual Studio 7.rst
new file mode 100644
index 000000000..eb426f47a
--- /dev/null
+++ b/Help/generator/Visual Studio 7.rst
@@ -0,0 +1,10 @@
+Visual Studio 7
+---------------
+
+Deprected. Generates Visual Studio .NET 2002 project files.
+
+.. note::
+ This generator is deprecated and will be removed
+ in a future version of CMake. It will still be
+ possible to build with VS 7.0 tools using the
+ :generator:`NMake Makefiles` generator.
diff --git a/Help/generator/Visual Studio 8 2005.rst b/Help/generator/Visual Studio 8 2005.rst
new file mode 100644
index 000000000..29012c371
--- /dev/null
+++ b/Help/generator/Visual Studio 8 2005.rst
@@ -0,0 +1,16 @@
+Visual Studio 8 2005
+--------------------
+
+Generates Visual Studio 8 2005 project files.
+
+The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set
+to specify a target platform name.
+
+For compatibility with CMake versions prior to 3.1, one may specify
+a target platform name optionally at the end of this generator name:
+
+``Visual Studio 8 2005 Win64``
+ Specify target platform ``x64``.
+
+``Visual Studio 8 2005 <WinCE-SDK>``
+ Specify target platform matching a Windows CE SDK name.
diff --git a/Help/generator/Visual Studio 9 2008.rst b/Help/generator/Visual Studio 9 2008.rst
new file mode 100644
index 000000000..40471b92e
--- /dev/null
+++ b/Help/generator/Visual Studio 9 2008.rst
@@ -0,0 +1,19 @@
+Visual Studio 9 2008
+--------------------
+
+Generates Visual Studio 9 2008 project files.
+
+The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set
+to specify a target platform name.
+
+For compatibility with CMake versions prior to 3.1, one may specify
+a target platform name optionally at the end of this generator name:
+
+``Visual Studio 9 2008 Win64``
+ Specify target platform ``x64``.
+
+``Visual Studio 9 2008 IA64``
+ Specify target platform ``Itanium``.
+
+``Visual Studio 9 2008 <WinCE-SDK>``
+ Specify target platform matching a Windows CE SDK name.
diff --git a/Help/generator/Watcom WMake.rst b/Help/generator/Watcom WMake.rst
new file mode 100644
index 000000000..09bdc3d9f
--- /dev/null
+++ b/Help/generator/Watcom WMake.rst
@@ -0,0 +1,4 @@
+Watcom WMake
+------------
+
+Generates Watcom WMake makefiles.
diff --git a/Help/generator/Xcode.rst b/Help/generator/Xcode.rst
new file mode 100644
index 000000000..d8a679064
--- /dev/null
+++ b/Help/generator/Xcode.rst
@@ -0,0 +1,4 @@
+Xcode
+-----
+
+Generate Xcode project files.
diff --git a/Help/include/COMPILE_DEFINITIONS_DISCLAIMER.txt b/Help/include/COMPILE_DEFINITIONS_DISCLAIMER.txt
new file mode 100644
index 000000000..6797d0e2b
--- /dev/null
+++ b/Help/include/COMPILE_DEFINITIONS_DISCLAIMER.txt
@@ -0,0 +1,18 @@
+Disclaimer: Most native build tools have poor support for escaping
+certain values. CMake has work-arounds for many cases but some values
+may just not be possible to pass correctly. If a value does not seem
+to be escaped correctly, do not attempt to work-around the problem by
+adding escape sequences to the value. Your work-around may break in a
+future version of CMake that has improved escape support. Instead
+consider defining the macro in a (configured) header file. Then
+report the limitation. Known limitations include::
+
+ # - broken almost everywhere
+ ; - broken in VS IDE 7.0 and Borland Makefiles
+ , - broken in VS IDE
+ % - broken in some cases in NMake
+ & | - broken in some cases on MinGW
+ ^ < > \" - broken in most Make tools on Windows
+
+CMake does not reject these values outright because they do work in
+some cases. Use with caution.
diff --git a/Help/include/INTERFACE_INCLUDE_DIRECTORIES_WARNING.txt b/Help/include/INTERFACE_INCLUDE_DIRECTORIES_WARNING.txt
new file mode 100644
index 000000000..a54d7280d
--- /dev/null
+++ b/Help/include/INTERFACE_INCLUDE_DIRECTORIES_WARNING.txt
@@ -0,0 +1,18 @@
+
+Note that it is not advisable to populate the ``INSTALL_INTERFACE`` of the
+|INTERFACE_PROPERTY_LINK| of a target with absolute paths to the include
+directories of dependencies. That would hard-code into installed packages
+the include directory paths for dependencies
+**as found on the machine the package was made on**.
+
+The ``INSTALL_INTERFACE`` of the |INTERFACE_PROPERTY_LINK| is only
+suitable for specifying the required include directories for headers
+provided with the target itself, not those provided by the transitive
+dependencies listed in its :prop_tgt:`INTERFACE_LINK_LIBRARIES` target
+property. Those dependencies should themselves be targets that specify
+their own header locations in |INTERFACE_PROPERTY_LINK|.
+
+See the :ref:`Creating Relocatable Packages` section of the
+:manual:`cmake-packages(7)` manual for discussion of additional care
+that must be taken when specifying usage requirements while creating
+packages for redistribution.
diff --git a/Help/include/INTERFACE_LINK_LIBRARIES_WARNING.txt b/Help/include/INTERFACE_LINK_LIBRARIES_WARNING.txt
new file mode 100644
index 000000000..46e84ac22
--- /dev/null
+++ b/Help/include/INTERFACE_LINK_LIBRARIES_WARNING.txt
@@ -0,0 +1,10 @@
+
+Note that it is not advisable to populate the
+|INTERFACE_PROPERTY_LINK| of a target with absolute paths to dependencies.
+That would hard-code into installed packages the library file paths
+for dependencies **as found on the machine the package was made on**.
+
+See the :ref:`Creating Relocatable Packages` section of the
+:manual:`cmake-packages(7)` manual for discussion of additional care
+that must be taken when specifying usage requirements while creating
+packages for redistribution.
diff --git a/Help/index.rst b/Help/index.rst
new file mode 100644
index 000000000..2d3f15645
--- /dev/null
+++ b/Help/index.rst
@@ -0,0 +1,59 @@
+.. title:: CMake Reference Documentation
+
+Command-Line Tools
+##################
+
+.. toctree::
+ :maxdepth: 1
+
+ /manual/cmake.1
+ /manual/ctest.1
+ /manual/cpack.1
+
+Interactive Dialogs
+###################
+
+.. toctree::
+ :maxdepth: 1
+
+ /manual/cmake-gui.1
+ /manual/ccmake.1
+
+Reference Manuals
+#################
+
+.. toctree::
+ :maxdepth: 1
+
+ /manual/cmake-buildsystem.7
+ /manual/cmake-commands.7
+ /manual/cmake-compile-features.7
+ /manual/cmake-developer.7
+ /manual/cmake-generator-expressions.7
+ /manual/cmake-generators.7
+ /manual/cmake-language.7
+ /manual/cmake-modules.7
+ /manual/cmake-packages.7
+ /manual/cmake-policies.7
+ /manual/cmake-properties.7
+ /manual/cmake-qt.7
+ /manual/cmake-toolchains.7
+ /manual/cmake-variables.7
+
+.. only:: html or text
+
+ Release Notes
+ #############
+
+ .. toctree::
+ :maxdepth: 1
+
+ /release/index
+
+.. only:: html
+
+ Index and Search
+ ################
+
+ * :ref:`genindex`
+ * :ref:`search`
diff --git a/Help/manual/LINKS.txt b/Help/manual/LINKS.txt
new file mode 100644
index 000000000..3993ff83d
--- /dev/null
+++ b/Help/manual/LINKS.txt
@@ -0,0 +1,25 @@
+The following resources are available to get help using CMake:
+
+Home Page
+ https://cmake.org
+
+ The primary starting point for learning about CMake.
+
+Frequently Asked Questions
+ https://cmake.org/Wiki/CMake_FAQ
+
+ A Wiki is provided containing answers to frequently asked questions.
+
+Online Documentation
+ https://cmake.org/documentation
+
+ Links to available documentation may be found on this web page.
+
+Mailing List
+ https://cmake.org/mailing-lists
+
+ For help and discussion about using cmake, a mailing list is
+ provided at cmake@cmake.org. The list is member-post-only but one
+ may sign up on the CMake web page. Please first read the full
+ documentation at https://cmake.org before posting questions to
+ the list.
diff --git a/Help/manual/OPTIONS_BUILD.txt b/Help/manual/OPTIONS_BUILD.txt
new file mode 100644
index 000000000..b428a74d7
--- /dev/null
+++ b/Help/manual/OPTIONS_BUILD.txt
@@ -0,0 +1,123 @@
+``-C <initial-cache>``
+ Pre-load a script to populate the cache.
+
+ When cmake is first run in an empty build tree, it creates a
+ CMakeCache.txt file and populates it with customizable settings for
+ the project. This option may be used to specify a file from which
+ to load cache entries before the first pass through the project's
+ cmake listfiles. The loaded entries take priority over the
+ project's default values. The given file should be a CMake script
+ containing SET commands that use the CACHE option, not a
+ cache-format file.
+
+``-D <var>:<type>=<value>, -D <var>=<value>``
+ Create a cmake cache entry.
+
+ When cmake is first run in an empty build tree, it creates a
+ CMakeCache.txt file and populates it with customizable settings for
+ the project. This option may be used to specify a setting that
+ takes priority over the project's default value. The option may be
+ repeated for as many cache entries as desired.
+
+ If the ``:<type>`` portion is given it must be one of the types
+ specified by the :command:`set` command documentation for its
+ ``CACHE`` signature.
+ If the ``:<type>`` portion is omitted the entry will be created
+ with no type if it does not exist with a type already. If a
+ command in the project sets the type to ``PATH`` or ``FILEPATH``
+ then the ``<value>`` will be converted to an absolute path.
+
+ This option may also be given as a single argument:
+ ``-D<var>:<type>=<value>`` or ``-D<var>=<value>``.
+
+``-U <globbing_expr>``
+ Remove matching entries from CMake cache.
+
+ This option may be used to remove one or more variables from the
+ CMakeCache.txt file, globbing expressions using * and ? are
+ supported. The option may be repeated for as many cache entries as
+ desired.
+
+ Use with care, you can make your CMakeCache.txt non-working.
+
+``-G <generator-name>``
+ Specify a build system generator.
+
+ CMake may support multiple native build systems on certain
+ platforms. A generator is responsible for generating a particular
+ build system. Possible generator names are specified in the
+ :manual:`cmake-generators(7)` manual.
+
+``-T <toolset-name>``
+ Specify toolset name if supported by generator.
+
+ Some CMake generators support a toolset name to be given to the
+ native build system to choose a compiler. This is supported only on
+ specific generators:
+
+ ::
+
+ Visual Studio >= 10
+ Xcode >= 3.0
+
+ See native build system documentation for allowed toolset names.
+
+``-A <platform-name>``
+ Specify platform name if supported by generator.
+
+ Some CMake generators support a platform name to be given to the
+ native build system to choose a compiler or SDK. This is supported only on
+ specific generators::
+
+ Visual Studio >= 8
+
+ See native build system documentation for allowed platform names.
+
+``-Wno-dev``
+ Suppress developer warnings.
+
+ Suppress warnings that are meant for the author of the
+ CMakeLists.txt files. By default this will also turn off
+ deprecation warnings.
+
+``-Wdev``
+ Enable developer warnings.
+
+ Enable warnings that are meant for the author of the CMakeLists.txt
+ files. By default this will also turn on deprecation warnings.
+
+``-Werror=dev``
+ Make developer warnings errors.
+
+ Make warnings that are meant for the author of the CMakeLists.txt files
+ errors. By default this will also turn on deprecated warnings as errors.
+
+``-Wno-error=dev``
+ Make developer warnings not errors.
+
+ Make warnings that are meant for the author of the CMakeLists.txt files not
+ errors. By default this will also turn off deprecated warnings as errors.
+
+``-Wdeprecated``
+ Enable deprecated functionality warnings.
+
+ Enable warnings for usage of deprecated functionality, that are meant
+ for the author of the CMakeLists.txt files.
+
+``-Wno-deprecated``
+ Suppress deprecated functionality warnings.
+
+ Suppress warnings for usage of deprecated functionality, that are meant
+ for the author of the CMakeLists.txt files.
+
+``-Werror=deprecated``
+ Make deprecated macro and function warnings errors.
+
+ Make warnings for usage of deprecated macros and functions, that are meant
+ for the author of the CMakeLists.txt files, errors.
+
+``-Wno-error=deprecated``
+ Make deprecated macro and function warnings not errors.
+
+ Make warnings for usage of deprecated macros and functions, that are meant
+ for the author of the CMakeLists.txt files, not errors.
diff --git a/Help/manual/OPTIONS_HELP.txt b/Help/manual/OPTIONS_HELP.txt
new file mode 100644
index 000000000..feeca7dc3
--- /dev/null
+++ b/Help/manual/OPTIONS_HELP.txt
@@ -0,0 +1,136 @@
+.. |file| replace:: The help is printed to a named <f>ile if given.
+
+``--help,-help,-usage,-h,-H,/?``
+ Print usage information and exit.
+
+ Usage describes the basic command line interface and its options.
+
+``--version,-version,/V [<f>]``
+ Show program name/version banner and exit.
+
+ If a file is specified, the version is written into it.
+ |file|
+
+``--help-full [<f>]``
+ Print all help manuals and exit.
+
+ All manuals are printed in a human-readable text format.
+ |file|
+
+``--help-manual <man> [<f>]``
+ Print one help manual and exit.
+
+ The specified manual is printed in a human-readable text format.
+ |file|
+
+``--help-manual-list [<f>]``
+ List help manuals available and exit.
+
+ The list contains all manuals for which help may be obtained by
+ using the ``--help-manual`` option followed by a manual name.
+ |file|
+
+``--help-command <cmd> [<f>]``
+ Print help for one command and exit.
+
+ The :manual:`cmake-commands(7)` manual entry for ``<cmd>`` is
+ printed in a human-readable text format.
+ |file|
+
+``--help-command-list [<f>]``
+ List commands with help available and exit.
+
+ The list contains all commands for which help may be obtained by
+ using the ``--help-command`` option followed by a command name.
+ |file|
+
+``--help-commands [<f>]``
+ Print cmake-commands manual and exit.
+
+ The :manual:`cmake-commands(7)` manual is printed in a
+ human-readable text format.
+ |file|
+
+``--help-module <mod> [<f>]``
+ Print help for one module and exit.
+
+ The :manual:`cmake-modules(7)` manual entry for ``<mod>`` is printed
+ in a human-readable text format.
+ |file|
+
+``--help-module-list [<f>]``
+ List modules with help available and exit.
+
+ The list contains all modules for which help may be obtained by
+ using the ``--help-module`` option followed by a module name.
+ |file|
+
+``--help-modules [<f>]``
+ Print cmake-modules manual and exit.
+
+ The :manual:`cmake-modules(7)` manual is printed in a human-readable
+ text format.
+ |file|
+
+``--help-policy <cmp> [<f>]``
+ Print help for one policy and exit.
+
+ The :manual:`cmake-policies(7)` manual entry for ``<cmp>`` is
+ printed in a human-readable text format.
+ |file|
+
+``--help-policy-list [<f>]``
+ List policies with help available and exit.
+
+ The list contains all policies for which help may be obtained by
+ using the ``--help-policy`` option followed by a policy name.
+ |file|
+
+``--help-policies [<f>]``
+ Print cmake-policies manual and exit.
+
+ The :manual:`cmake-policies(7)` manual is printed in a
+ human-readable text format.
+ |file|
+
+``--help-property <prop> [<f>]``
+ Print help for one property and exit.
+
+ The :manual:`cmake-properties(7)` manual entries for ``<prop>`` are
+ printed in a human-readable text format.
+ |file|
+
+``--help-property-list [<f>]``
+ List properties with help available and exit.
+
+ The list contains all properties for which help may be obtained by
+ using the ``--help-property`` option followed by a property name.
+ |file|
+
+``--help-properties [<f>]``
+ Print cmake-properties manual and exit.
+
+ The :manual:`cmake-properties(7)` manual is printed in a
+ human-readable text format.
+ |file|
+
+``--help-variable <var> [<f>]``
+ Print help for one variable and exit.
+
+ The :manual:`cmake-variables(7)` manual entry for ``<var>`` is
+ printed in a human-readable text format.
+ |file|
+
+``--help-variable-list [<f>]``
+ List variables with help available and exit.
+
+ The list contains all variables for which help may be obtained by
+ using the ``--help-variable`` option followed by a variable name.
+ |file|
+
+``--help-variables [<f>]``
+ Print cmake-variables manual and exit.
+
+ The :manual:`cmake-variables(7)` manual is printed in a
+ human-readable text format.
+ |file|
diff --git a/Help/manual/ccmake.1.rst b/Help/manual/ccmake.1.rst
new file mode 100644
index 000000000..a5fe19168
--- /dev/null
+++ b/Help/manual/ccmake.1.rst
@@ -0,0 +1,37 @@
+.. cmake-manual-description: CMake Curses Dialog Command-Line Reference
+
+ccmake(1)
+*********
+
+Synopsis
+========
+
+.. parsed-literal::
+
+ ccmake [<options>] (<path-to-source> | <path-to-existing-build>)
+
+Description
+===========
+
+The "ccmake" executable is the CMake curses interface. Project
+configuration settings may be specified interactively through this
+GUI. Brief instructions are provided at the bottom of the terminal
+when the program is running.
+
+CMake is a cross-platform build system generator. Projects specify
+their build process with platform-independent CMake listfiles included
+in each directory of a source tree with the name CMakeLists.txt.
+Users build a project by using CMake to generate a build system for a
+native tool on their platform.
+
+Options
+=======
+
+.. include:: OPTIONS_BUILD.txt
+
+.. include:: OPTIONS_HELP.txt
+
+See Also
+========
+
+.. include:: LINKS.txt
diff --git a/Help/manual/cmake-buildsystem.7.rst b/Help/manual/cmake-buildsystem.7.rst
new file mode 100644
index 000000000..9004bb26e
--- /dev/null
+++ b/Help/manual/cmake-buildsystem.7.rst
@@ -0,0 +1,989 @@
+.. cmake-manual-description: CMake Buildsystem Reference
+
+cmake-buildsystem(7)
+********************
+
+.. only:: html
+
+ .. contents::
+
+Introduction
+============
+
+A CMake-based buildsystem is organized as a set of high-level logical
+targets. Each target corresponds to an executable or library, or
+is a custom target containing custom commands. Dependencies between the
+targets are expressed in the buildsystem to determine the build order
+and the rules for regeneration in response to change.
+
+Binary Targets
+==============
+
+Executables and libraries are defined using the :command:`add_executable`
+and :command:`add_library` commands. The resulting binary files have
+appropriate prefixes, suffixes and extensions for the platform targeted.
+Dependencies between binary targets are expressed using the
+:command:`target_link_libraries` command:
+
+.. code-block:: cmake
+
+ add_library(archive archive.cpp zip.cpp lzma.cpp)
+ add_executable(zipapp zipapp.cpp)
+ target_link_libraries(zipapp archive)
+
+``archive`` is defined as a static library -- an archive containing objects
+compiled from ``archive.cpp``, ``zip.cpp``, and ``lzma.cpp``. ``zipapp``
+is defined as an executable formed by compiling and linking ``zipapp.cpp``.
+When linking the ``zipapp`` executable, the ``archive`` static library is
+linked in.
+
+Binary Executables
+------------------
+
+The :command:`add_executable` command defines an executable target:
+
+.. code-block:: cmake
+
+ add_executable(mytool mytool.cpp)
+
+Commands such as :command:`add_custom_command`, which generates rules to be
+run at build time can transparently use an :prop_tgt:`EXECUTABLE <TYPE>`
+target as a ``COMMAND`` executable. The buildsystem rules will ensure that
+the executable is built before attempting to run the command.
+
+Binary Library Types
+--------------------
+
+.. _`Normal Libraries`:
+
+Normal Libraries
+^^^^^^^^^^^^^^^^
+
+By default, the :command:`add_library` command defines a static library,
+unless a type is specified. A type may be specified when using the command:
+
+.. code-block:: cmake
+
+ add_library(archive SHARED archive.cpp zip.cpp lzma.cpp)
+
+.. code-block:: cmake
+
+ add_library(archive STATIC archive.cpp zip.cpp lzma.cpp)
+
+The :variable:`BUILD_SHARED_LIBS` variable may be enabled to change the
+behavior of :command:`add_library` to build shared libraries by default.
+
+In the context of the buildsystem definition as a whole, it is largely
+irrelevant whether particular libraries are ``SHARED`` or ``STATIC`` --
+the commands, dependency specifications and other APIs work similarly
+regardless of the library type. The ``MODULE`` library type is
+dissimilar in that it is generally not linked to -- it is not used in
+the right-hand-side of the :command:`target_link_libraries` command.
+It is a type which is loaded as a plugin using runtime techniques.
+If the library does not export any unmanaged symbols (e.g. Windows
+resource DLL, C++/CLI DLL), it is required that the library not be a
+``SHARED`` library because CMake expects ``SHARED`` libraries to export
+at least one symbol.
+
+.. code-block:: cmake
+
+ add_library(archive MODULE 7z.cpp)
+
+.. _`Apple Frameworks`:
+
+Apple Frameworks
+""""""""""""""""
+
+A ``SHARED`` library may be marked with the :prop_tgt:`FRAMEWORK`
+target property to create an OS X or iOS Framework Bundle.
+The ``MACOSX_FRAMEWORK_IDENTIFIER`` sets ``CFBundleIdentifier`` key
+and it uniquely identifies the bundle.
+
+.. code-block:: cmake
+
+ add_library(MyFramework SHARED MyFramework.cpp)
+ set_target_properties(MyFramework PROPERTIES
+ FRAMEWORK TRUE
+ FRAMEWORK_VERSION A
+ MACOSX_FRAMEWORK_IDENTIFIER org.cmake.MyFramework
+ )
+
+.. _`Object Libraries`:
+
+Object Libraries
+^^^^^^^^^^^^^^^^
+
+The ``OBJECT`` library type is also not linked to. It defines a non-archival
+collection of object files resulting from compiling the given source files.
+The object files collection can be used as source inputs to other targets:
+
+.. code-block:: cmake
+
+ add_library(archive OBJECT archive.cpp zip.cpp lzma.cpp)
+
+ add_library(archiveExtras STATIC $<TARGET_OBJECTS:archive> extras.cpp)
+
+ add_executable(test_exe $<TARGET_OBJECTS:archive> test.cpp)
+
+``OBJECT`` libraries may only be used locally as sources in a buildsystem --
+they may not be installed, exported, or used in the right hand side of
+:command:`target_link_libraries`. They also may not be used as the ``TARGET``
+in a use of the :command:`add_custom_command(TARGET)` command signature.
+
+Although object libraries may not be named directly in calls to
+the :command:`target_link_libraries` command, they can be "linked"
+indirectly by using an :ref:`Interface Library <Interface Libraries>`
+whose :prop_tgt:`INTERFACE_SOURCES` target property is set to name
+``$<TARGET_OBJECTS:objlib>``.
+
+Build Specification and Usage Requirements
+==========================================
+
+The :command:`target_include_directories`, :command:`target_compile_definitions`
+and :command:`target_compile_options` commands specify the build specifications
+and the usage requirements of binary targets. The commands populate the
+:prop_tgt:`INCLUDE_DIRECTORIES`, :prop_tgt:`COMPILE_DEFINITIONS` and
+:prop_tgt:`COMPILE_OPTIONS` target properties respectively, and/or the
+:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`, :prop_tgt:`INTERFACE_COMPILE_DEFINITIONS`
+and :prop_tgt:`INTERFACE_COMPILE_OPTIONS` target properties.
+
+Each of the commands has a ``PRIVATE``, ``PUBLIC`` and ``INTERFACE`` mode. The
+``PRIVATE`` mode populates only the non-``INTERFACE_`` variant of the target
+property and the ``INTERFACE`` mode populates only the ``INTERFACE_`` variants.
+The ``PUBLIC`` mode populates both variants of the repective target property.
+Each command may be invoked with multiple uses of each keyword:
+
+.. code-block:: cmake
+
+ target_compile_definitions(archive
+ PRIVATE BUILDING_WITH_LZMA
+ INTERFACE USING_ARCHIVE_LIB
+ )
+
+Note that usage requirements are not designed as a way to make downstreams
+use particular :prop_tgt:`COMPILE_OPTIONS` or
+:prop_tgt:`COMPILE_DEFINITIONS` etc for convenience only. The contents of
+the properties must be **requirements**, not merely recommendations or
+convenience.
+
+See the :ref:`Creating Relocatable Packages` section of the
+:manual:`cmake-packages(7)` manual for discussion of additional care
+that must be taken when specifying usage requirements while creating
+packages for redistribution.
+
+Target Properties
+-----------------
+
+The contents of the :prop_tgt:`INCLUDE_DIRECTORIES`,
+:prop_tgt:`COMPILE_DEFINITIONS` and :prop_tgt:`COMPILE_OPTIONS` target
+properties are used appropriately when compiling the source files of a
+binary target.
+
+Entries in the :prop_tgt:`INCLUDE_DIRECTORIES` are added to the compile line
+with ``-I`` or ``-isystem`` prefixes and in the order of appearance in the
+property value.
+
+Entries in the :prop_tgt:`COMPILE_DEFINITIONS` are prefixed with ``-D`` or
+``/D`` and added to the compile line in an unspecified order. The
+:prop_tgt:`DEFINE_SYMBOL` target property is also added as a compile
+definition as a special convenience case for ``SHARED`` and ``MODULE``
+library targets.
+
+Entries in the :prop_tgt:`COMPILE_OPTIONS` are escaped for the shell and added
+in the order of appearance in the property value. Several compile options have
+special separate handling, such as :prop_tgt:`POSITION_INDEPENDENT_CODE`.
+
+The contents of the :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`,
+:prop_tgt:`INTERFACE_COMPILE_DEFINITIONS` and
+:prop_tgt:`INTERFACE_COMPILE_OPTIONS` target properties are
+*Usage Requirements* -- they specify content which consumers
+must use to correctly compile and link with the target they appear on.
+For any binary target, the contents of each ``INTERFACE_`` property on
+each target specified in a :command:`target_link_libraries` command is
+consumed:
+
+.. code-block:: cmake
+
+ set(srcs archive.cpp zip.cpp)
+ if (LZMA_FOUND)
+ list(APPEND srcs lzma.cpp)
+ endif()
+ add_library(archive SHARED ${srcs})
+ if (LZMA_FOUND)
+ # The archive library sources are compiled with -DBUILDING_WITH_LZMA
+ target_compile_definitions(archive PRIVATE BUILDING_WITH_LZMA)
+ endif()
+ target_compile_definitions(archive INTERFACE USING_ARCHIVE_LIB)
+
+ add_executable(consumer)
+ # Link consumer to archive and consume its usage requirements. The consumer
+ # executable sources are compiled with -DUSING_ARCHIVE_LIB.
+ target_link_libraries(consumer archive)
+
+Because it is common to require that the source directory and corresponding
+build directory are added to the :prop_tgt:`INCLUDE_DIRECTORIES`, the
+:variable:`CMAKE_INCLUDE_CURRENT_DIR` variable can be enabled to conveniently
+add the corresponding directories to the :prop_tgt:`INCLUDE_DIRECTORIES` of
+all targets. The variable :variable:`CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE`
+can be enabled to add the corresponding directories to the
+:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` of all targets. This makes use of
+targets in multiple different directories convenient through use of the
+:command:`target_link_libraries` command.
+
+
+.. _`Target Usage Requirements`:
+
+Transitive Usage Requirements
+-----------------------------
+
+The usage requirements of a target can transitively propagate to dependents.
+The :command:`target_link_libraries` command has ``PRIVATE``,
+``INTERFACE`` and ``PUBLIC`` keywords to control the propagation.
+
+.. code-block:: cmake
+
+ add_library(archive archive.cpp)
+ target_compile_definitions(archive INTERFACE USING_ARCHIVE_LIB)
+
+ add_library(serialization serialization.cpp)
+ target_compile_definitions(serialization INTERFACE USING_SERIALIZATION_LIB)
+
+ add_library(archiveExtras extras.cpp)
+ target_link_libraries(archiveExtras PUBLIC archive)
+ target_link_libraries(archiveExtras PRIVATE serialization)
+ # archiveExtras is compiled with -DUSING_ARCHIVE_LIB
+ # and -DUSING_SERIALIZATION_LIB
+
+ add_executable(consumer consumer.cpp)
+ # consumer is compiled with -DUSING_ARCHIVE_LIB
+ target_link_libraries(consumer archiveExtras)
+
+Because ``archive`` is a ``PUBLIC`` dependency of ``archiveExtras``, the
+usage requirements of it are propagated to ``consumer`` too. Because
+``serialization`` is a ``PRIVATE`` dependency of ``archive``, the usage
+requirements of it are not propagated to ``consumer``.
+
+Generally, a dependency should be specified in a use of
+:command:`target_link_libraries` with the ``PRIVATE`` keyword if it is used by
+only the implementation of a library, and not in the header files. If a
+dependency is additionally used in the header files of a library (e.g. for
+class inheritance), then it should be specified as a ``PUBLIC`` dependency.
+A dependency which is not used by the implementation of a library, but only by
+its headers should be specified as an ``INTERFACE`` dependency. The
+:command:`target_link_libraries` command may be invoked with multiple uses of
+each keyword:
+
+.. code-block:: cmake
+
+ target_link_libraries(archiveExtras
+ PUBLIC archive
+ PRIVATE serialization
+ )
+
+Usage requirements are propagated by reading the ``INTERFACE_`` variants
+of target properties from dependencies and appending the values to the
+non-``INTERFACE_`` variants of the operand. For example, the
+:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` of dependencies is read and
+appended to the :prop_tgt:`INCLUDE_DIRECTORIES` of the operand. In cases
+where order is relevant and maintained, and the order resulting from the
+:command:`target_link_libraries` calls does not allow correct compilation,
+use of an appropriate command to set the property directly may update the
+order.
+
+For example, if the linked libraries for a target must be specified
+in the order ``lib1`` ``lib2`` ``lib3`` , but the include directories must
+be specified in the order ``lib3`` ``lib1`` ``lib2``:
+
+.. code-block:: cmake
+
+ target_link_libraries(myExe lib1 lib2 lib3)
+ target_include_directories(myExe
+ PRIVATE $<TARGET_PROPERTY:lib3,INTERFACE_INCLUDE_DIRECTORIES>)
+
+Note that care must be taken when specifying usage requirements for targets
+which will be exported for installation using the :command:`install(EXPORT)`
+command. See :ref:`Creating Packages` for more.
+
+.. _`Compatible Interface Properties`:
+
+Compatible Interface Properties
+-------------------------------
+
+Some target properties are required to be compatible between a target and
+the interface of each dependency. For example, the
+:prop_tgt:`POSITION_INDEPENDENT_CODE` target property may specify a
+boolean value of whether a target should be compiled as
+position-independent-code, which has platform-specific consequences.
+A target may also specify the usage requirement
+:prop_tgt:`INTERFACE_POSITION_INDEPENDENT_CODE` to communicate that
+consumers must be compiled as position-independent-code.
+
+.. code-block:: cmake
+
+ add_executable(exe1 exe1.cpp)
+ set_property(TARGET exe1 PROPERTY POSITION_INDEPENDENT_CODE ON)
+
+ add_library(lib1 SHARED lib1.cpp)
+ set_property(TARGET lib1 PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON)
+
+ add_executable(exe2 exe2.cpp)
+ target_link_libraries(exe2 lib1)
+
+Here, both ``exe1`` and ``exe2`` will be compiled as position-independent-code.
+``lib1`` will also be compiled as position-independent-code because that is the
+default setting for ``SHARED`` libraries. If dependencies have conflicting,
+non-compatible requirements :manual:`cmake(1)` issues a diagnostic:
+
+.. code-block:: cmake
+
+ add_library(lib1 SHARED lib1.cpp)
+ set_property(TARGET lib1 PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON)
+
+ add_library(lib2 SHARED lib2.cpp)
+ set_property(TARGET lib2 PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE OFF)
+
+ add_executable(exe1 exe1.cpp)
+ target_link_libraries(exe1 lib1)
+ set_property(TARGET exe1 PROPERTY POSITION_INDEPENDENT_CODE OFF)
+
+ add_executable(exe2 exe2.cpp)
+ target_link_libraries(exe2 lib1 lib2)
+
+The ``lib1`` requirement ``INTERFACE_POSITION_INDEPENDENT_CODE`` is not
+"compatible" with the ``POSITION_INDEPENDENT_CODE`` property of the ``exe1``
+target. The library requires that consumers are built as
+position-independent-code, while the executable specifies to not built as
+position-independent-code, so a diagnostic is issued.
+
+The ``lib1`` and ``lib2`` requirements are not "compatible". One of them
+requires that consumers are built as position-independent-code, while
+the other requires that consumers are not built as position-independent-code.
+Because ``exe2`` links to both and they are in conflict, a diagnostic is
+issued.
+
+To be "compatible", the :prop_tgt:`POSITION_INDEPENDENT_CODE` property,
+if set must be either the same, in a boolean sense, as the
+:prop_tgt:`INTERFACE_POSITION_INDEPENDENT_CODE` property of all transitively
+specified dependencies on which that property is set.
+
+This property of "compatible interface requirement" may be extended to other
+properties by specifying the property in the content of the
+:prop_tgt:`COMPATIBLE_INTERFACE_BOOL` target property. Each specified property
+must be compatible between the consuming target and the corresponding property
+with an ``INTERFACE_`` prefix from each dependency:
+
+.. code-block:: cmake
+
+ add_library(lib1Version2 SHARED lib1_v2.cpp)
+ set_property(TARGET lib1Version2 PROPERTY INTERFACE_CUSTOM_PROP ON)
+ set_property(TARGET lib1Version2 APPEND PROPERTY
+ COMPATIBLE_INTERFACE_BOOL CUSTOM_PROP
+ )
+
+ add_library(lib1Version3 SHARED lib1_v3.cpp)
+ set_property(TARGET lib1Version3 PROPERTY INTERFACE_CUSTOM_PROP OFF)
+
+ add_executable(exe1 exe1.cpp)
+ target_link_libraries(exe1 lib1Version2) # CUSTOM_PROP will be ON
+
+ add_executable(exe2 exe2.cpp)
+ target_link_libraries(exe2 lib1Version2 lib1Version3) # Diagnostic
+
+Non-boolean properties may also participate in "compatible interface"
+computations. Properties specified in the
+:prop_tgt:`COMPATIBLE_INTERFACE_STRING`
+property must be either unspecified or compare to the same string among
+all transitively specified dependencies. This can be useful to ensure
+that multiple incompatible versions of a library are not linked together
+through transitive requirements of a target:
+
+.. code-block:: cmake
+
+ add_library(lib1Version2 SHARED lib1_v2.cpp)
+ set_property(TARGET lib1Version2 PROPERTY INTERFACE_LIB_VERSION 2)
+ set_property(TARGET lib1Version2 APPEND PROPERTY
+ COMPATIBLE_INTERFACE_STRING LIB_VERSION
+ )
+
+ add_library(lib1Version3 SHARED lib1_v3.cpp)
+ set_property(TARGET lib1Version3 PROPERTY INTERFACE_LIB_VERSION 3)
+
+ add_executable(exe1 exe1.cpp)
+ target_link_libraries(exe1 lib1Version2) # LIB_VERSION will be "2"
+
+ add_executable(exe2 exe2.cpp)
+ target_link_libraries(exe2 lib1Version2 lib1Version3) # Diagnostic
+
+The :prop_tgt:`COMPATIBLE_INTERFACE_NUMBER_MAX` target property specifies
+that content will be evaluated numerically and the maximum number among all
+specified will be calculated:
+
+.. code-block:: cmake
+
+ add_library(lib1Version2 SHARED lib1_v2.cpp)
+ set_property(TARGET lib1Version2 PROPERTY INTERFACE_CONTAINER_SIZE_REQUIRED 200)
+ set_property(TARGET lib1Version2 APPEND PROPERTY
+ COMPATIBLE_INTERFACE_NUMBER_MAX CONTAINER_SIZE_REQUIRED
+ )
+
+ add_library(lib1Version3 SHARED lib1_v3.cpp)
+ set_property(TARGET lib1Version3 PROPERTY INTERFACE_CONTAINER_SIZE_REQUIRED 1000)
+
+ add_executable(exe1 exe1.cpp)
+ # CONTAINER_SIZE_REQUIRED will be "200"
+ target_link_libraries(exe1 lib1Version2)
+
+ add_executable(exe2 exe2.cpp)
+ # CONTAINER_SIZE_REQUIRED will be "1000"
+ target_link_libraries(exe2 lib1Version2 lib1Version3)
+
+Similarly, the :prop_tgt:`COMPATIBLE_INTERFACE_NUMBER_MIN` may be used to
+calculate the numeric minimum value for a property from dependencies.
+
+Each calculated "compatible" property value may be read in the consumer at
+generate-time using generator expressions.
+
+Note that for each dependee, the set of properties specified in each
+compatible interface property must not intersect with the set specified in
+any of the other properties.
+
+Property Origin Debugging
+-------------------------
+
+Because build specifications can be determined by dependencies, the lack of
+locality of code which creates a target and code which is responsible for
+setting build specifications may make the code more difficult to reason about.
+:manual:`cmake(1)` provides a debugging facility to print the origin of the
+contents of properties which may be determined by dependencies. The properties
+which can be debugged are listed in the
+:variable:`CMAKE_DEBUG_TARGET_PROPERTIES` variable documentation:
+
+.. code-block:: cmake
+
+ set(CMAKE_DEBUG_TARGET_PROPERTIES
+ INCLUDE_DIRECTORIES
+ COMPILE_DEFINITIONS
+ POSITION_INDEPENDENT_CODE
+ CONTAINER_SIZE_REQUIRED
+ LIB_VERSION
+ )
+ add_executable(exe1 exe1.cpp)
+
+In the case of properties listed in :prop_tgt:`COMPATIBLE_INTERFACE_BOOL` or
+:prop_tgt:`COMPATIBLE_INTERFACE_STRING`, the debug output shows which target
+was responsible for setting the property, and which other dependencies also
+defined the property. In the case of
+:prop_tgt:`COMPATIBLE_INTERFACE_NUMBER_MAX` and
+:prop_tgt:`COMPATIBLE_INTERFACE_NUMBER_MIN`, the debug output shows the
+value of the property from each dependency, and whether the value determines
+the new extreme.
+
+Build Specification with Generator Expressions
+----------------------------------------------
+
+Build specifications may use
+:manual:`generator expressions <cmake-generator-expressions(7)>` containing
+content which may be conditional or known only at generate-time. For example,
+the calculated "compatible" value of a property may be read with the
+``TARGET_PROPERTY`` expression:
+
+.. code-block:: cmake
+
+ add_library(lib1Version2 SHARED lib1_v2.cpp)
+ set_property(TARGET lib1Version2 PROPERTY
+ INTERFACE_CONTAINER_SIZE_REQUIRED 200)
+ set_property(TARGET lib1Version2 APPEND PROPERTY
+ COMPATIBLE_INTERFACE_NUMBER_MAX CONTAINER_SIZE_REQUIRED
+ )
+
+ add_executable(exe1 exe1.cpp)
+ target_link_libraries(exe1 lib1Version2)
+ target_compile_definitions(exe1 PRIVATE
+ CONTAINER_SIZE=$<TARGET_PROPERTY:CONTAINER_SIZE_REQUIRED>
+ )
+
+In this case, the ``exe1`` source files will be compiled with
+``-DCONTAINER_SIZE=200``.
+
+Configuration determined build specifications may be conveniently set using
+the ``CONFIG`` generator expression.
+
+.. code-block:: cmake
+
+ target_compile_definitions(exe1 PRIVATE
+ $<$<CONFIG:Debug>:DEBUG_BUILD>
+ )
+
+The ``CONFIG`` parameter is compared case-insensitively with the configuration
+being built. In the presence of :prop_tgt:`IMPORTED` targets, the content of
+:prop_tgt:`MAP_IMPORTED_CONFIG_DEBUG <MAP_IMPORTED_CONFIG_<CONFIG>>` is also
+accounted for by this expression.
+
+Some buildsystems generated by :manual:`cmake(1)` have a predetermined
+build-configuration set in the :variable:`CMAKE_BUILD_TYPE` variable. The
+buildsystem for the IDEs such as Visual Studio and Xcode are generated
+independent of the build-configuration, and the actual build configuration
+is not known until build-time. Therefore, code such as
+
+.. code-block:: cmake
+
+ string(TOLOWER ${CMAKE_BUILD_TYPE} _type)
+ if (_type STREQUAL debug)
+ target_compile_definitions(exe1 PRIVATE DEBUG_BUILD)
+ endif()
+
+may appear to work for ``Makefile`` based and ``Ninja`` generators, but is not
+portable to IDE generators. Additionally, the :prop_tgt:`IMPORTED`
+configuration-mappings are not accounted for with code like this, so it should
+be avoided.
+
+The unary ``TARGET_PROPERTY`` generator expression and the ``TARGET_POLICY``
+generator expression are evaluated with the consuming target context. This
+means that a usage requirement specification may be evaluated differently based
+on the consumer:
+
+.. code-block:: cmake
+
+ add_library(lib1 lib1.cpp)
+ target_compile_definitions(lib1 INTERFACE
+ $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:LIB1_WITH_EXE>
+ $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:LIB1_WITH_SHARED_LIB>
+ $<$<TARGET_POLICY:CMP0041>:CONSUMER_CMP0041_NEW>
+ )
+
+ add_executable(exe1 exe1.cpp)
+ target_link_libraries(exe1 lib1)
+
+ cmake_policy(SET CMP0041 NEW)
+
+ add_library(shared_lib shared_lib.cpp)
+ target_link_libraries(shared_lib lib1)
+
+The ``exe1`` executable will be compiled with ``-DLIB1_WITH_EXE``, while the
+``shared_lib`` shared library will be compiled with ``-DLIB1_WITH_SHARED_LIB``
+and ``-DCONSUMER_CMP0041_NEW``, because policy :policy:`CMP0041` is
+``NEW`` at the point where the ``shared_lib`` target is created.
+
+The ``BUILD_INTERFACE`` expression wraps requirements which are only used when
+consumed from a target in the same buildsystem, or when consumed from a target
+exported to the build directory using the :command:`export` command. The
+``INSTALL_INTERFACE`` expression wraps requirements which are only used when
+consumed from a target which has been installed and exported with the
+:command:`install(EXPORT)` command:
+
+.. code-block:: cmake
+
+ add_library(ClimbingStats climbingstats.cpp)
+ target_compile_definitions(ClimbingStats INTERFACE
+ $<BUILD_INTERFACE:ClimbingStats_FROM_BUILD_LOCATION>
+ $<INSTALL_INTERFACE:ClimbingStats_FROM_INSTALLED_LOCATION>
+ )
+ install(TARGETS ClimbingStats EXPORT libExport ${InstallArgs})
+ install(EXPORT libExport NAMESPACE Upstream::
+ DESTINATION lib/cmake/ClimbingStats)
+ export(EXPORT libExport NAMESPACE Upstream::)
+
+ add_executable(exe1 exe1.cpp)
+ target_link_libraries(exe1 ClimbingStats)
+
+In this case, the ``exe1`` executable will be compiled with
+``-DClimbingStats_FROM_BUILD_LOCATION``. The exporting commands generate
+:prop_tgt:`IMPORTED` targets with either the ``INSTALL_INTERFACE`` or the
+``BUILD_INTERFACE`` omitted, and the ``*_INTERFACE`` marker stripped away.
+A separate project consuming the ``ClimbingStats`` package would contain:
+
+.. code-block:: cmake
+
+ find_package(ClimbingStats REQUIRED)
+
+ add_executable(Downstream main.cpp)
+ target_link_libraries(Downstream Upstream::ClimbingStats)
+
+Depending on whether the ``ClimbingStats`` package was used from the build
+location or the install location, the ``Downstream`` target would be compiled
+with either ``-DClimbingStats_FROM_BUILD_LOCATION`` or
+``-DClimbingStats_FROM_INSTALL_LOCATION``. For more about packages and
+exporting see the :manual:`cmake-packages(7)` manual.
+
+.. _`Include Directories and Usage Requirements`:
+
+Include Directories and Usage Requirements
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Include directories require some special consideration when specified as usage
+requirements and when used with generator expressions. The
+:command:`target_include_directories` command accepts both relative and
+absolute include directories:
+
+.. code-block:: cmake
+
+ add_library(lib1 lib1.cpp)
+ target_include_directories(lib1 PRIVATE
+ /absolute/path
+ relative/path
+ )
+
+Relative paths are interpreted relative to the source directory where the
+command appears. Relative paths are not allowed in the
+:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` of :prop_tgt:`IMPORTED` targets.
+
+In cases where a non-trivial generator expression is used, the
+``INSTALL_PREFIX`` expression may be used within the argument of an
+``INSTALL_INTERFACE`` expression. It is a replacement marker which
+expands to the installation prefix when imported by a consuming project.
+
+Include directories usage requirements commonly differ between the build-tree
+and the install-tree. The ``BUILD_INTERFACE`` and ``INSTALL_INTERFACE``
+generator expressions can be used to describe separate usage requirements
+based on the usage location. Relative paths are allowed within the
+``INSTALL_INTERFACE`` expression and are interpreted relative to the
+installation prefix. For example:
+
+.. code-block:: cmake
+
+ add_library(ClimbingStats climbingstats.cpp)
+ target_include_directories(ClimbingStats INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/generated>
+ $<INSTALL_INTERFACE:/absolute/path>
+ $<INSTALL_INTERFACE:relative/path>
+ $<INSTALL_INTERFACE:$<INSTALL_PREFIX>/$<CONFIG>/generated>
+ )
+
+Two convenience APIs are provided relating to include directories usage
+requirements. The :variable:`CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE` variable
+may be enabled, with an equivalent effect to:
+
+.. code-block:: cmake
+
+ set_property(TARGET tgt APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_BINARY_DIR}>
+ )
+
+for each target affected. The convenience for installed targets is
+an ``INCLUDES DESTINATION`` component with the :command:`install(TARGETS)`
+command:
+
+.. code-block:: cmake
+
+ install(TARGETS foo bar bat EXPORT tgts ${dest_args}
+ INCLUDES DESTINATION include
+ )
+ install(EXPORT tgts ${other_args})
+ install(FILES ${headers} DESTINATION include)
+
+This is equivalent to appending ``${CMAKE_INSTALL_PREFIX}/include`` to the
+:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` of each of the installed
+:prop_tgt:`IMPORTED` targets when generated by :command:`install(EXPORT)`.
+
+When the :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` of an
+:ref:`imported target <Imported targets>` is consumed, the entries in the
+property are treated as ``SYSTEM`` include directories, as if they were
+listed in the :prop_tgt:`INTERFACE_SYSTEM_INCLUDE_DIRECTORIES` of the
+dependency. This can result in omission of compiler warnings for headers
+found in those directories. This behavior for :ref:`imported targets` may
+be controlled with the :prop_tgt:`NO_SYSTEM_FROM_IMPORTED` target property.
+
+If a binary target is linked transitively to a Mac OX framework, the
+``Headers`` directory of the framework is also treated as a usage requirement.
+This has the same effect as passing the framework directory as an include
+directory.
+
+Link Libraries and Generator Expressions
+----------------------------------------
+
+Like build specifications, :prop_tgt:`link libraries <LINK_LIBRARIES>` may be
+specified with generator expression conditions. However, as consumption of
+usage requirements is based on collection from linked dependencies, there is
+an additional limitation that the link dependencies must form a "directed
+acyclic graph". That is, if linking to a target is dependent on the value of
+a target property, that target property may not be dependent on the linked
+dependencies:
+
+.. code-block:: cmake
+
+ add_library(lib1 lib1.cpp)
+ add_library(lib2 lib2.cpp)
+ target_link_libraries(lib1 PUBLIC
+ $<$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>:lib2>
+ )
+ add_library(lib3 lib3.cpp)
+ set_property(TARGET lib3 PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON)
+
+ add_executable(exe1 exe1.cpp)
+ target_link_libraries(exe1 lib1 lib3)
+
+As the value of the :prop_tgt:`POSITION_INDEPENDENT_CODE` property of
+the ``exe1`` target is dependent on the linked libraries (``lib3``), and the
+edge of linking ``exe1`` is determined by the same
+:prop_tgt:`POSITION_INDEPENDENT_CODE` property, the dependency graph above
+contains a cycle. :manual:`cmake(1)` issues a diagnostic in this case.
+
+.. _`Output Artifacts`:
+
+Output Artifacts
+----------------
+
+The buildsystem targets created by the :command:`add_library` and
+:command:`add_executable` commands create rules to create binary outputs.
+The exact output location of the binaries can only be determined at
+generate-time because it can depend on the build-configuration and the
+link-language of linked dependencies etc. ``TARGET_FILE``,
+``TARGET_LINKER_FILE`` and related expressions can be used to access the
+name and location of generated binaries. These expressions do not work
+for ``OBJECT`` libraries however, as there is no single file generated
+by such libraries which is relevant to the expressions.
+
+There are three kinds of output artifacts that may be build by targets
+as detailed in the following sections. Their classification differs
+between DLL platforms and non-DLL platforms. All Windows-based
+systems including Cygwin are DLL platforms.
+
+.. _`Runtime Output Artifacts`:
+
+Runtime Output Artifacts
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+A *runtime* output artifact of a buildsystem target may be:
+
+* The executable file (e.g. ``.exe``) of an executable target
+ created by the :command:`add_executable` command.
+
+* On DLL platforms: the executable file (e.g. ``.dll``) of a shared
+ library target created by the :command:`add_library` command
+ with the ``SHARED`` option.
+
+The :prop_tgt:`RUNTIME_OUTPUT_DIRECTORY` and :prop_tgt:`RUNTIME_OUTPUT_NAME`
+target properties may be used to control runtime output artifact locations
+and names in the build tree.
+
+.. _`Library Output Artifacts`:
+
+Library Output Artifacts
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+A *library* output artifact of a buildsystem target may be:
+
+* The loadable module file (e.g. ``.dll`` or ``.so``) of a module
+ library target created by the :command:`add_library` command
+ with the ``MODULE`` option.
+
+* On non-DLL platforms: the shared library file (e.g. ``.so`` or ``.dylib``)
+ of a shared shared library target created by the :command:`add_library`
+ command with the ``SHARED`` option.
+
+The :prop_tgt:`LIBRARY_OUTPUT_DIRECTORY` and :prop_tgt:`LIBRARY_OUTPUT_NAME`
+target properties may be used to control library output artifact locations
+and names in the build tree.
+
+.. _`Archive Output Artifacts`:
+
+Archive Output Artifacts
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+An *archive* output artifact of a buildsystem target may be:
+
+* The static library file (e.g. ``.lib`` or ``.a``) of a static
+ library target created by the :command:`add_library` command
+ with the ``STATIC`` option.
+
+* On DLL platforms: the import library file (e.g. ``.lib``) of a shared
+ library target created by the :command:`add_library` command
+ with the ``SHARED`` option. This file is only guaranteed to exist if
+ the library exports at least one unmanaged symbol.
+
+* On DLL platforms: the import library file (e.g. ``.lib``) of an
+ executable target created by the :command:`add_executable` command
+ when its :prop_tgt:`ENABLE_EXPORTS` target property is set.
+
+The :prop_tgt:`ARCHIVE_OUTPUT_DIRECTORY` and :prop_tgt:`ARCHIVE_OUTPUT_NAME`
+target properties may be used to control archive output artifact locations
+and names in the build tree.
+
+Directory-Scoped Commands
+-------------------------
+
+The :command:`target_include_directories`,
+:command:`target_compile_definitions` and
+:command:`target_compile_options` commands have an effect on only one
+target at a time. The commands :command:`add_definitions`,
+:command:`add_compile_options` and :command:`include_directories` have
+a similar function, but operate at directory scope instead of target
+scope for convenience.
+
+Pseudo Targets
+==============
+
+Some target types do not represent outputs of the buildsystem, but only inputs
+such as external dependencies, aliases or other non-build artifacts. Pseudo
+targets are not represented in the generated buildsystem.
+
+.. _`Imported Targets`:
+
+Imported Targets
+----------------
+
+An :prop_tgt:`IMPORTED` target represents a pre-existing dependency. Usually
+such targets are defined by an upstream package and should be treated as
+immutable. It is not possible to use an :prop_tgt:`IMPORTED` target in the
+left-hand-side of the :command:`target_compile_definitions`,
+:command:`target_include_directories`, :command:`target_compile_options` or
+:command:`target_link_libraries` commands, as that would be an attempt to
+modify it. :prop_tgt:`IMPORTED` targets are designed to be used only in the
+right-hand-side of those commands.
+
+:prop_tgt:`IMPORTED` targets may have the same usage requirement properties
+populated as binary targets, such as
+:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`,
+:prop_tgt:`INTERFACE_COMPILE_DEFINITIONS`,
+:prop_tgt:`INTERFACE_COMPILE_OPTIONS`,
+:prop_tgt:`INTERFACE_LINK_LIBRARIES`, and
+:prop_tgt:`INTERFACE_POSITION_INDEPENDENT_CODE`.
+
+The :prop_tgt:`LOCATION` may also be read from an IMPORTED target, though there
+is rarely reason to do so. Commands such as :command:`add_custom_command` can
+transparently use an :prop_tgt:`IMPORTED` :prop_tgt:`EXECUTABLE <TYPE>` target
+as a ``COMMAND`` executable.
+
+The scope of the definition of an :prop_tgt:`IMPORTED` target is the directory
+where it was defined. It may be accessed and used from subdirectories, but
+not from parent directories or sibling directories. The scope is similar to
+the scope of a cmake variable.
+
+It is also possible to define a ``GLOBAL`` :prop_tgt:`IMPORTED` target which is
+accessible globally in the buildsystem.
+
+See the :manual:`cmake-packages(7)` manual for more on creating packages
+with :prop_tgt:`IMPORTED` targets.
+
+.. _`Alias Targets`:
+
+Alias Targets
+-------------
+
+An ``ALIAS`` target is a name which may be used interchangably with
+a binary target name in read-only contexts. A primary use-case for ``ALIAS``
+targets is for example or unit test executables accompanying a library, which
+may be part of the same buildsystem or built separately based on user
+configuration.
+
+.. code-block:: cmake
+
+ add_library(lib1 lib1.cpp)
+ install(TARGETS lib1 EXPORT lib1Export ${dest_args})
+ install(EXPORT lib1Export NAMESPACE Upstream:: ${other_args})
+
+ add_library(Upstream::lib1 ALIAS lib1)
+
+In another directory, we can link unconditionally to the ``Upstream::lib1``
+target, which may be an :prop_tgt:`IMPORTED` target from a package, or an
+``ALIAS`` target if built as part of the same buildsystem.
+
+.. code-block:: cmake
+
+ if (NOT TARGET Upstream::lib1)
+ find_package(lib1 REQUIRED)
+ endif()
+ add_executable(exe1 exe1.cpp)
+ target_link_libraries(exe1 Upstream::lib1)
+
+``ALIAS`` targets are not mutable, installable or exportable. They are
+entirely local to the buildsystem description. A name can be tested for
+whether it is an ``ALIAS`` name by reading the :prop_tgt:`ALIASED_TARGET`
+property from it:
+
+.. code-block:: cmake
+
+ get_target_property(_aliased Upstream::lib1 ALIASED_TARGET)
+ if(_aliased)
+ message(STATUS "The name Upstream::lib1 is an ALIAS for ${_aliased}.")
+ endif()
+
+.. _`Interface Libraries`:
+
+Interface Libraries
+-------------------
+
+An ``INTERFACE`` target has no :prop_tgt:`LOCATION` and is mutable, but is
+otherwise similar to an :prop_tgt:`IMPORTED` target.
+
+It may specify usage requirements such as
+:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`,
+:prop_tgt:`INTERFACE_COMPILE_DEFINITIONS`,
+:prop_tgt:`INTERFACE_COMPILE_OPTIONS`,
+:prop_tgt:`INTERFACE_LINK_LIBRARIES`,
+:prop_tgt:`INTERFACE_SOURCES`,
+and :prop_tgt:`INTERFACE_POSITION_INDEPENDENT_CODE`.
+Only the ``INTERFACE`` modes of the :command:`target_include_directories`,
+:command:`target_compile_definitions`, :command:`target_compile_options`,
+:command:`target_sources`, and :command:`target_link_libraries` commands
+may be used with ``INTERFACE`` libraries.
+
+A primary use-case for ``INTERFACE`` libraries is header-only libraries.
+
+.. code-block:: cmake
+
+ add_library(Eigen INTERFACE)
+ target_include_directories(Eigen INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
+ $<INSTALL_INTERFACE:include/Eigen>
+ )
+
+ add_executable(exe1 exe1.cpp)
+ target_link_libraries(exe1 Eigen)
+
+Here, the usage requirements from the ``Eigen`` target are consumed and used
+when compiling, but it has no effect on linking.
+
+Another use-case is to employ an entirely target-focussed design for usage
+requirements:
+
+.. code-block:: cmake
+
+ add_library(pic_on INTERFACE)
+ set_property(TARGET pic_on PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON)
+ add_library(pic_off INTERFACE)
+ set_property(TARGET pic_off PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE OFF)
+
+ add_library(enable_rtti INTERFACE)
+ target_compile_options(enable_rtti INTERFACE
+ $<$<OR:$<COMPILER_ID:GNU>,$<COMPILER_ID:Clang>>:-rtti>
+ )
+
+ add_executable(exe1 exe1.cpp)
+ target_link_libraries(exe1 pic_on enable_rtti)
+
+This way, the build specification of ``exe1`` is expressed entirely as linked
+targets, and the complexity of compiler-specific flags is encapsulated in an
+``INTERFACE`` library target.
+
+The properties permitted to be set on or read from an ``INTERFACE`` library
+are:
+
+* Properties matching ``INTERFACE_*``
+* Built-in properties matching ``COMPATIBLE_INTERFACE_*``
+* ``EXPORT_NAME``
+* ``IMPORTED``
+* ``NAME``
+* Properties matching ``MAP_IMPORTED_CONFIG_*``
+
+``INTERFACE`` libraries may be installed and exported. Any content they refer
+to must be installed separately:
+
+.. code-block:: cmake
+
+ add_library(Eigen INTERFACE)
+ target_include_directories(Eigen INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
+ $<INSTALL_INTERFACE:include/Eigen>
+ )
+
+ install(TARGETS Eigen EXPORT eigenExport)
+ install(EXPORT eigenExport NAMESPACE Upstream::
+ DESTINATION lib/cmake/Eigen
+ )
+ install(FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/eigen.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/vector.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/matrix.h
+ DESTINATION include/Eigen
+ )
diff --git a/Help/manual/cmake-commands.7.rst b/Help/manual/cmake-commands.7.rst
new file mode 100644
index 000000000..d0c298659
--- /dev/null
+++ b/Help/manual/cmake-commands.7.rst
@@ -0,0 +1,155 @@
+.. cmake-manual-description: CMake Language Command Reference
+
+cmake-commands(7)
+*****************
+
+.. only:: html
+
+ .. contents::
+
+Normal Commands
+===============
+
+These commands may be used freely in CMake projects.
+
+.. toctree::
+ :maxdepth: 1
+
+ /command/add_compile_options
+ /command/add_custom_command
+ /command/add_custom_target
+ /command/add_definitions
+ /command/add_dependencies
+ /command/add_executable
+ /command/add_library
+ /command/add_subdirectory
+ /command/add_test
+ /command/aux_source_directory
+ /command/break
+ /command/build_command
+ /command/cmake_host_system_information
+ /command/cmake_minimum_required
+ /command/cmake_parse_arguments
+ /command/cmake_policy
+ /command/configure_file
+ /command/continue
+ /command/create_test_sourcelist
+ /command/define_property
+ /command/elseif
+ /command/else
+ /command/enable_language
+ /command/enable_testing
+ /command/endforeach
+ /command/endfunction
+ /command/endif
+ /command/endmacro
+ /command/endwhile
+ /command/execute_process
+ /command/export
+ /command/file
+ /command/find_file
+ /command/find_library
+ /command/find_package
+ /command/find_path
+ /command/find_program
+ /command/fltk_wrap_ui
+ /command/foreach
+ /command/function
+ /command/get_cmake_property
+ /command/get_directory_property
+ /command/get_filename_component
+ /command/get_property
+ /command/get_source_file_property
+ /command/get_target_property
+ /command/get_test_property
+ /command/if
+ /command/include_directories
+ /command/include_external_msproject
+ /command/include_regular_expression
+ /command/include
+ /command/install
+ /command/link_directories
+ /command/link_libraries
+ /command/list
+ /command/load_cache
+ /command/macro
+ /command/mark_as_advanced
+ /command/math
+ /command/message
+ /command/option
+ /command/project
+ /command/qt_wrap_cpp
+ /command/qt_wrap_ui
+ /command/remove_definitions
+ /command/return
+ /command/separate_arguments
+ /command/set_directory_properties
+ /command/set_property
+ /command/set
+ /command/set_source_files_properties
+ /command/set_target_properties
+ /command/set_tests_properties
+ /command/site_name
+ /command/source_group
+ /command/string
+ /command/target_compile_definitions
+ /command/target_compile_features
+ /command/target_compile_options
+ /command/target_include_directories
+ /command/target_link_libraries
+ /command/target_sources
+ /command/try_compile
+ /command/try_run
+ /command/unset
+ /command/variable_watch
+ /command/while
+
+Deprecated Commands
+===================
+
+These commands are available only for compatibility with older
+versions of CMake. Do not use them in new code.
+
+.. toctree::
+ :maxdepth: 1
+
+ /command/build_name
+ /command/exec_program
+ /command/export_library_dependencies
+ /command/install_files
+ /command/install_programs
+ /command/install_targets
+ /command/load_command
+ /command/make_directory
+ /command/output_required_files
+ /command/remove
+ /command/subdir_depends
+ /command/subdirs
+ /command/use_mangled_mesa
+ /command/utility_source
+ /command/variable_requires
+ /command/write_file
+
+.. _`CTest Commands`:
+
+CTest Commands
+==============
+
+These commands are available only in ctest scripts.
+
+.. toctree::
+ :maxdepth: 1
+
+ /command/ctest_build
+ /command/ctest_configure
+ /command/ctest_coverage
+ /command/ctest_empty_binary_directory
+ /command/ctest_memcheck
+ /command/ctest_read_custom_files
+ /command/ctest_run_script
+ /command/ctest_sleep
+ /command/ctest_start
+ /command/ctest_submit
+ /command/ctest_test
+ /command/ctest_update
+ /command/ctest_upload
diff --git a/Help/manual/cmake-compile-features.7.rst b/Help/manual/cmake-compile-features.7.rst
new file mode 100644
index 000000000..caf5bac2a
--- /dev/null
+++ b/Help/manual/cmake-compile-features.7.rst
@@ -0,0 +1,311 @@
+.. cmake-manual-description: CMake Compile Features Reference
+
+cmake-compile-features(7)
+*************************
+
+.. only:: html
+
+ .. contents::
+
+Introduction
+============
+
+Project source code may depend on, or be conditional on, the availability
+of certain features of the compiler. There are three use-cases which arise:
+`Compile Feature Requirements`_, `Optional Compile Features`_
+and `Conditional Compilation Options`_.
+
+While features are typically specified in programming language standards,
+CMake provides a primary user interface based on granular handling of
+the features, not the language standard that introduced the feature.
+
+The :prop_gbl:`CMAKE_C_KNOWN_FEATURES` and
+:prop_gbl:`CMAKE_CXX_KNOWN_FEATURES` global properties contain all the
+features known to CMake, regardless of compiler support for the feature.
+The :variable:`CMAKE_C_COMPILE_FEATURES` and
+:variable:`CMAKE_CXX_COMPILE_FEATURES` variables contain all features
+CMake knows are known to the compiler, regardless of language standard
+or compile flags needed to use them.
+
+Features known to CMake are named mostly following the same convention
+as the Clang feature test macros. The are some exceptions, such as
+CMake using ``cxx_final`` and ``cxx_override`` instead of the single
+``cxx_override_control`` used by Clang.
+
+Compile Feature Requirements
+============================
+
+Compile feature requirements may be specified with the
+:command:`target_compile_features` command. For example, if a target must
+be compiled with compiler support for the
+:prop_gbl:`cxx_constexpr <CMAKE_CXX_KNOWN_FEATURES>` feature:
+
+.. code-block:: cmake
+
+ add_library(mylib requires_constexpr.cpp)
+ target_compile_features(mylib PRIVATE cxx_constexpr)
+
+In processing the requirement for the ``cxx_constexpr`` feature,
+:manual:`cmake(1)` will ensure that the in-use C++ compiler is capable
+of the feature, and will add any necessary flags such as ``-std=gnu++11``
+to the compile lines of C++ files in the ``mylib`` target. A
+``FATAL_ERROR`` is issued if the compiler is not capable of the
+feature.
+
+The exact compile flags and language standard are deliberately not part
+of the user interface for this use-case. CMake will compute the
+appropriate compile flags to use by considering the features specified
+for each target.
+
+Such compile flags are added even if the compiler supports the
+particular feature without the flag. For example, the GNU compiler
+supports variadic templates (with a warning) even if ``-std=gnu++98`` is
+used. CMake adds the ``-std=gnu++11`` flag if ``cxx_variadic_templates``
+is specified as a requirement.
+
+In the above example, ``mylib`` requires ``cxx_constexpr`` when it
+is built itself, but consumers of ``mylib`` are not required to use a
+compiler which supports ``cxx_constexpr``. If the interface of
+``mylib`` does require the ``cxx_constexpr`` feature (or any other
+known feature), that may be specified with the ``PUBLIC`` or
+``INTERFACE`` signatures of :command:`target_compile_features`:
+
+.. code-block:: cmake
+
+ add_library(mylib requires_constexpr.cpp)
+ # cxx_constexpr is a usage-requirement
+ target_compile_features(mylib PUBLIC cxx_constexpr)
+
+ # main.cpp will be compiled with -std=gnu++11 on GNU for cxx_constexpr.
+ add_executable(myexe main.cpp)
+ target_link_libraries(myexe mylib)
+
+Feature requirements are evaluated transitively by consuming the link
+implementation. See :manual:`cmake-buildsystem(7)` for more on
+transitive behavior of build properties and usage requirements.
+
+Because the :prop_tgt:`CXX_EXTENSIONS` target property is ``ON`` by default,
+CMake uses extended variants of language dialects by default, such as
+``-std=gnu++11`` instead of ``-std=c++11``. That target property may be
+set to ``OFF`` to use the non-extended variant of the dialect flag. Note
+that because most compilers enable extensions by default, this could
+expose cross-platform bugs in user code or in the headers of third-party
+dependencies.
+
+Optional Compile Features
+=========================
+
+Compile features may be preferred if available, without creating a hard
+requirement. For example, a library may provides alternative
+implementations depending on whether the ``cxx_variadic_templates``
+feature is available:
+
+.. code-block:: c++
+
+ #if Foo_COMPILER_CXX_VARIADIC_TEMPLATES
+ template<int I, int... Is>
+ struct Interface;
+
+ template<int I>
+ struct Interface<I>
+ {
+ static int accumulate()
+ {
+ return I;
+ }
+ };
+
+ template<int I, int... Is>
+ struct Interface
+ {
+ static int accumulate()
+ {
+ return I + Interface<Is...>::accumulate();
+ }
+ };
+ #else
+ template<int I1, int I2 = 0, int I3 = 0, int I4 = 0>
+ struct Interface
+ {
+ static int accumulate() { return I1 + I2 + I3 + I4; }
+ };
+ #endif
+
+Such an interface depends on using the correct preprocessor defines for the
+compiler features. CMake can generate a header file containing such
+defines using the :module:`WriteCompilerDetectionHeader` module. The
+module contains the ``write_compiler_detection_header`` function which
+accepts parameters to control the content of the generated header file:
+
+.. code-block:: cmake
+
+ write_compiler_detection_header(
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/foo_compiler_detection.h"
+ PREFIX Foo
+ COMPILERS GNU
+ FEATURES
+ cxx_variadic_templates
+ )
+
+Such a header file may be used internally in the source code of a project,
+and it may be installed and used in the interface of library code.
+
+For each feature listed in ``FEATURES``, a preprocessor definition
+is created in the header file, and defined to either ``1`` or ``0``.
+
+Additionally, some features call for additional defines, such as the
+``cxx_final`` and ``cxx_override`` features. Rather than being used in
+``#ifdef`` code, the ``final`` keyword is abstracted by a symbol
+which is defined to either ``final``, a compiler-specific equivalent, or
+to empty. That way, C++ code can be written to unconditionally use the
+symbol, and compiler support determines what it is expanded to:
+
+.. code-block:: c++
+
+ struct Interface {
+ virtual void Execute() = 0;
+ };
+
+ struct Concrete Foo_FINAL {
+ void Execute() Foo_OVERRIDE;
+ };
+
+In this case, ``Foo_FINAL`` will expand to ``final`` if the
+compiler supports the keyword, or to empty otherwise.
+
+In this use-case, the CMake code will wish to enable a particular language
+standard if available from the compiler. The :prop_tgt:`CXX_STANDARD`
+target property variable may be set to the desired language standard
+for a particular target, and the :variable:`CMAKE_CXX_STANDARD` may be
+set to influence all following targets:
+
+.. code-block:: cmake
+
+ write_compiler_detection_header(
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/foo_compiler_detection.h"
+ PREFIX Foo
+ COMPILERS GNU
+ FEATURES
+ cxx_final cxx_override
+ )
+
+ # Includes foo_compiler_detection.h and uses the Foo_FINAL symbol
+ # which will expand to 'final' if the compiler supports the requested
+ # CXX_STANDARD.
+ add_library(foo foo.cpp)
+ set_property(TARGET foo PROPERTY CXX_STANDARD 11)
+
+ # Includes foo_compiler_detection.h and uses the Foo_FINAL symbol
+ # which will expand to 'final' if the compiler supports the feature,
+ # even though CXX_STANDARD is not set explicitly. The requirement of
+ # cxx_constexpr causes CMake to set CXX_STANDARD internally, which
+ # affects the compile flags.
+ add_library(foo_impl foo_impl.cpp)
+ target_compile_features(foo_impl PRIVATE cxx_constexpr)
+
+The ``write_compiler_detection_header`` function also creates compatibility
+code for other features which have standard equivalents. For example, the
+``cxx_static_assert`` feature is emulated with a template and abstracted
+via the ``<PREFIX>_STATIC_ASSERT`` and ``<PREFIX>_STATIC_ASSERT_MSG``
+function-macros.
+
+Conditional Compilation Options
+===============================
+
+Libraries may provide entirely different header files depending on
+requested compiler features.
+
+For example, a header at ``with_variadics/interface.h`` may contain:
+
+.. code-block:: c++
+
+ template<int I, int... Is>
+ struct Interface;
+
+ template<int I>
+ struct Interface<I>
+ {
+ static int accumulate()
+ {
+ return I;
+ }
+ };
+
+ template<int I, int... Is>
+ struct Interface
+ {
+ static int accumulate()
+ {
+ return I + Interface<Is...>::accumulate();
+ }
+ };
+
+while a header at ``no_variadics/interface.h`` may contain:
+
+.. code-block:: c++
+
+ template<int I1, int I2 = 0, int I3 = 0, int I4 = 0>
+ struct Interface
+ {
+ static int accumulate() { return I1 + I2 + I3 + I4; }
+ };
+
+It would be possible to write a abstraction ``interface.h`` header
+containing something like:
+
+.. code-block:: c++
+
+ #include "foo_compiler_detection.h"
+ #if Foo_COMPILER_CXX_VARIADIC_TEMPLATES
+ #include "with_variadics/interface.h"
+ #else
+ #include "no_variadics/interface.h"
+ #endif
+
+However this could be unmaintainable if there are many files to
+abstract. What is needed is to use alternative include directories
+depending on the compiler capabilities.
+
+CMake provides a ``COMPILE_FEATURES``
+:manual:`generator expression <cmake-generator-expressions(7)>` to implement
+such conditions. This may be used with the build-property commands such as
+:command:`target_include_directories` and :command:`target_link_libraries`
+to set the appropriate :manual:`buildsystem <cmake-buildsystem(7)>`
+properties:
+
+.. code-block:: cmake
+
+ add_library(foo INTERFACE)
+ set(with_variadics ${CMAKE_CURRENT_SOURCE_DIR}/with_variadics)
+ set(no_variadics ${CMAKE_CURRENT_SOURCE_DIR}/no_variadics)
+ target_include_directories(foo
+ INTERFACE
+ "$<$<COMPILE_FEATURES:cxx_variadic_templates>:${with_variadics}>"
+ "$<$<NOT:$<COMPILE_FEATURES:cxx_variadic_templates>>:${no_variadics}>"
+ )
+
+Consuming code then simply links to the ``foo`` target as usual and uses
+the feature-appropriate include directory
+
+.. code-block:: cmake
+
+ add_executable(consumer_with consumer_with.cpp)
+ target_link_libraries(consumer_with foo)
+ set_property(TARGET consumer_with CXX_STANDARD 11)
+
+ add_executable(consumer_no consumer_no.cpp)
+ target_link_libraries(consumer_no foo)
+
+Supported Compilers
+===================
+
+CMake is currently aware of the :prop_tgt:`language standards <CXX_STANDARD>`
+and :prop_gbl:`compile features <CMAKE_CXX_KNOWN_FEATURES>` available from
+the following :variable:`compiler ids <CMAKE_<LANG>_COMPILER_ID>` as of the
+versions specified for each:
+
+* ``AppleClang``: Apple Clang for Xcode versions 4.4 though 6.2.
+* ``Clang``: Clang compiler versions 2.9 through 3.4.
+* ``GNU``: GNU compiler versions 4.4 through 5.0.
+* ``MSVC``: Microsoft Visual Studio versions 2010 through 2015.
+* ``SunPro``: Oracle SolarisStudio version 12.4.
diff --git a/Help/manual/cmake-developer.7.rst b/Help/manual/cmake-developer.7.rst
new file mode 100644
index 000000000..7bfdcadcb
--- /dev/null
+++ b/Help/manual/cmake-developer.7.rst
@@ -0,0 +1,1007 @@
+.. cmake-manual-description: CMake Developer Reference
+
+cmake-developer(7)
+******************
+
+.. only:: html
+
+ .. contents::
+
+Introduction
+============
+
+This manual is intended for reference by developers modifying the CMake
+source tree itself.
+
+
+Permitted C++ Subset
+====================
+
+CMake is required to build with ancient C++ compilers and standard library
+implementations. Some common C++ constructs may not be used in CMake in order
+to build with such toolchains.
+
+std::auto_ptr
+-------------
+
+Some implementations have a ``std::auto_ptr`` which can not be used as a
+return value from a function. ``std::auto_ptr`` may not be used. Use
+``cmsys::auto_ptr`` instead.
+
+size_t
+------
+
+Various implementations have differing implementation of ``size_t``. When
+assigning the result of ``.size()`` on a container for example, the result
+should be assigned to ``size_t`` not to ``std::size_t``, ``unsigned int`` or
+similar types.
+
+Adding Compile Features
+=======================
+
+CMake reports an error if a compiler whose features are known does not report
+support for a particular requested feature. A compiler is considered to have
+known features if it reports support for at least one feature.
+
+When adding a new compile feature to CMake, it is therefore necessary to list
+support for the feature for all CompilerIds which already have one or more
+feature supported, if the new feature is available for any version of the
+compiler.
+
+When adding the first supported feature to a particular CompilerId, it is
+necessary to list support for all features known to cmake (See
+:variable:`CMAKE_C_COMPILE_FEATURES` and
+:variable:`CMAKE_CXX_COMPILE_FEATURES` as appropriate), where available for
+the compiler. Ensure that the ``CMAKE_<LANG>_STANDARD_DEFAULT`` is set to
+the computed internal variable ``CMAKE_<LANG>_STANDARD_COMPUTED_DEFAULT``
+for compiler versions which should be supported.
+
+It is sensible to record the features for the most recent version of a
+particular CompilerId first, and then work backwards. It is sensible to
+try to create a continuous range of versions of feature releases of the
+compiler. Gaps in the range indicate incorrect features recorded for
+intermediate releases.
+
+Generally, features are made available for a particular version if the
+compiler vendor documents availability of the feature with that
+version. Note that sometimes partially implemented features appear to
+be functional in previous releases (such as ``cxx_constexpr`` in GNU 4.6,
+though availability is documented in GNU 4.7), and sometimes compiler vendors
+document availability of features, though supporting infrastructure is
+not available (such as ``__has_feature(cxx_generic_lambdas)`` indicating
+non-availability in Clang 3.4, though it is documented as available, and
+fixed in Clang 3.5). Similar cases for other compilers and versions
+need to be investigated when extending CMake to support them.
+
+When a vendor releases a new version of a known compiler which supports
+a previously unsupported feature, and there are already known features for
+that compiler, the feature should be listed as supported in CMake for
+that version of the compiler as soon as reasonably possible.
+
+Standard-specific/compiler-specific variables such
+``CMAKE_CXX98_COMPILE_FEATURES`` are deliberately not documented. They
+only exist for the compiler-specific implementation of adding the ``-std``
+compile flag for compilers which need that.
+
+Help
+====
+
+The ``Help`` directory contains CMake help manual source files.
+They are written using the `reStructuredText`_ markup syntax and
+processed by `Sphinx`_ to generate the CMake help manuals.
+
+.. _`reStructuredText`: http://docutils.sourceforge.net/docs/ref/rst/introduction.html
+.. _`Sphinx`: http://sphinx-doc.org
+
+Markup Constructs
+-----------------
+
+In addition to using Sphinx to generate the CMake help manuals, we
+also use a C++-implemented document processor to print documents for
+the ``--help-*`` command-line help options. It supports a subset of
+reStructuredText markup. When authoring or modifying documents,
+please verify that the command-line help looks good in addition to the
+Sphinx-generated html and man pages.
+
+The command-line help processor supports the following constructs
+defined by reStructuredText, Sphinx, and a CMake extension to Sphinx.
+
+..
+ Note: This list must be kept consistent with the cmRST implementation.
+
+CMake Domain directives
+ Directives defined in the `CMake Domain`_ for defining CMake
+ documentation objects are printed in command-line help output as
+ if the lines were normal paragraph text with interpretation.
+
+CMake Domain interpreted text roles
+ Interpreted text roles defined in the `CMake Domain`_ for
+ cross-referencing CMake documentation objects are replaced by their
+ link text in command-line help output. Other roles are printed
+ literally and not processed.
+
+``code-block`` directive
+ Add a literal code block without interpretation. The command-line
+ help processor prints the block content without the leading directive
+ line and with common indentation replaced by one space.
+
+``include`` directive
+ Include another document source file. The command-line help
+ processor prints the included document inline with the referencing
+ document.
+
+literal block after ``::``
+ A paragraph ending in ``::`` followed by a blank line treats
+ the following indented block as literal text without interpretation.
+ The command-line help processor prints the ``::`` literally and
+ prints the block content with common indentation replaced by one
+ space.
+
+``note`` directive
+ Call out a side note. The command-line help processor prints the
+ block content as if the lines were normal paragraph text with
+ interpretation.
+
+``parsed-literal`` directive
+ Add a literal block with markup interpretation. The command-line
+ help processor prints the block content without the leading
+ directive line and with common indentation replaced by one space.
+
+``productionlist`` directive
+ Render context-free grammar productions. The command-line help
+ processor prints the block content as if the lines were normal
+ paragraph text with interpretation.
+
+``replace`` directive
+ Define a ``|substitution|`` replacement.
+ The command-line help processor requires a substitution replacement
+ to be defined before it is referenced.
+
+``|substitution|`` reference
+ Reference a substitution replacement previously defined by
+ the ``replace`` directive. The command-line help processor
+ performs the substitution and replaces all newlines in the
+ replacement text with spaces.
+
+``toctree`` directive
+ Include other document sources in the Table-of-Contents
+ document tree. The command-line help processor prints
+ the referenced documents inline as part of the referencing
+ document.
+
+Inline markup constructs not listed above are printed literally in the
+command-line help output. We prefer to use inline markup constructs that
+look correct in source form, so avoid use of \\-escapes in favor of inline
+literals when possible.
+
+Explicit markup blocks not matching directives listed above are removed from
+command-line help output. Do not use them, except for plain ``..`` comments
+that are removed by Sphinx too.
+
+Note that nested indentation of blocks is not recognized by the
+command-line help processor. Therefore:
+
+* Explicit markup blocks are recognized only when not indented
+ inside other blocks.
+
+* Literal blocks after paragraphs ending in ``::`` but not
+ at the top indentation level may consume all indented lines
+ following them.
+
+Try to avoid these cases in practice.
+
+CMake Domain
+------------
+
+CMake adds a `Sphinx Domain`_ called ``cmake``, also called the
+"CMake Domain". It defines several "object" types for CMake
+documentation:
+
+``command``
+ A CMake language command.
+
+``generator``
+ A CMake native build system generator.
+ See the :manual:`cmake(1)` command-line tool's ``-G`` option.
+
+``manual``
+ A CMake manual page, like this :manual:`cmake-developer(7)` manual.
+
+``module``
+ A CMake module.
+ See the :manual:`cmake-modules(7)` manual
+ and the :command:`include` command.
+
+``policy``
+ A CMake policy.
+ See the :manual:`cmake-policies(7)` manual
+ and the :command:`cmake_policy` command.
+
+``prop_cache, prop_dir, prop_gbl, prop_sf, prop_inst, prop_test, prop_tgt``
+ A CMake cache, directory, global, source file, installed file, test,
+ or target property, respectively. See the :manual:`cmake-properties(7)`
+ manual and the :command:`set_property` command.
+
+``variable``
+ A CMake language variable.
+ See the :manual:`cmake-variables(7)` manual
+ and the :command:`set` command.
+
+Documentation objects in the CMake Domain come from two sources.
+First, the CMake extension to Sphinx transforms every document named
+with the form ``Help/<type>/<file-name>.rst`` to a domain object with
+type ``<type>``. The object name is extracted from the document title,
+which is expected to be of the form::
+
+ <object-name>
+ -------------
+
+and to appear at or near the top of the ``.rst`` file before any other
+lines starting in a letter, digit, or ``<``. If no such title appears
+literally in the ``.rst`` file, the object name is the ``<file-name>``.
+If a title does appear, it is expected that ``<file-name>`` is equal
+to ``<object-name>`` with any ``<`` and ``>`` characters removed.
+
+Second, the CMake Domain provides directives to define objects inside
+other documents:
+
+.. code-block:: rst
+
+ .. command:: <command-name>
+
+ This indented block documents <command-name>.
+
+ .. variable:: <variable-name>
+
+ This indented block documents <variable-name>.
+
+Object types for which no directive is available must be defined using
+the first approach above.
+
+.. _`Sphinx Domain`: http://sphinx-doc.org/domains.html
+
+Cross-References
+----------------
+
+Sphinx uses reStructuredText interpreted text roles to provide
+cross-reference syntax. The `CMake Domain`_ provides for each
+domain object type a role of the same name to cross-reference it.
+CMake Domain roles are inline markup of the forms::
+
+ :type:`name`
+ :type:`text <name>`
+
+where ``type`` is the domain object type and ``name`` is the
+domain object name. In the first form the link text will be
+``name`` (or ``name()`` if the type is ``command``) and in
+the second form the link text will be the explicit ``text``.
+For example, the code:
+
+.. code-block:: rst
+
+ * The :command:`list` command.
+ * The :command:`list(APPEND)` sub-command.
+ * The :command:`list() command <list>`.
+ * The :command:`list(APPEND) sub-command <list>`.
+ * The :variable:`CMAKE_VERSION` variable.
+ * The :prop_tgt:`OUTPUT_NAME_<CONFIG>` target property.
+
+produces:
+
+* The :command:`list` command.
+* The :command:`list(APPEND)` sub-command.
+* The :command:`list() command <list>`.
+* The :command:`list(APPEND) sub-command <list>`.
+* The :variable:`CMAKE_VERSION` variable.
+* The :prop_tgt:`OUTPUT_NAME_<CONFIG>` target property.
+
+Note that CMake Domain roles differ from Sphinx and reStructuredText
+convention in that the form ``a<b>``, without a space preceding ``<``,
+is interpreted as a name instead of link text with an explicit target.
+This is necessary because we use ``<placeholders>`` frequently in
+object names like ``OUTPUT_NAME_<CONFIG>``. The form ``a <b>``,
+with a space preceding ``<``, is still interpreted as a link text
+with an explicit target.
+
+Style
+-----
+
+Style: Section Headers
+^^^^^^^^^^^^^^^^^^^^^^
+
+When marking section titles, make the section decoration line as long as
+the title text. Use only a line below the title, not above. For
+example:
+
+.. code-block:: rst
+
+ Title Text
+ ----------
+
+Capitalize the first letter of each non-minor word in the title.
+
+The section header underline character hierarchy is
+
+* ``#``: Manual group (part) in the master document
+* ``*``: Manual (chapter) title
+* ``=``: Section within a manual
+* ``-``: Subsection or `CMake Domain`_ object document title
+* ``^``: Subsubsection or `CMake Domain`_ object document section
+* ``"``: Paragraph or `CMake Domain`_ object document subsection
+
+Style: Whitespace
+^^^^^^^^^^^^^^^^^
+
+Use two spaces for indentation. Use two spaces between sentences in
+prose.
+
+Style: Line Length
+^^^^^^^^^^^^^^^^^^
+
+Prefer to restrict the width of lines to 75-80 columns. This is not a
+hard restriction, but writing new paragraphs wrapped at 75 columns
+allows space for adding minor content without significant re-wrapping of
+content.
+
+Style: Prose
+^^^^^^^^^^^^
+
+Use American English spellings in prose.
+
+Style: Starting Literal Blocks
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Prefer to mark the start of literal blocks with ``::`` at the end of
+the preceding paragraph. In cases where the following block gets
+a ``code-block`` marker, put a single ``:`` at the end of the preceding
+paragraph.
+
+Style: CMake Command Signatures
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Command signatures should be marked up as plain literal blocks, not as
+cmake ``code-blocks``.
+
+Signatures are separated from preceding content by a section header.
+That is, use:
+
+.. code-block:: rst
+
+ ... preceding paragraph.
+
+ Normal Libraries
+ ^^^^^^^^^^^^^^^^
+
+ ::
+
+ add_library(<lib> ...)
+
+ This signature is used for ...
+
+Signatures of commands should wrap optional parts with square brackets,
+and should mark list of optional arguments with an ellipsis (``...``).
+Elements of the signature which are specified by the user should be
+specified with angle brackets, and may be referred to in prose using
+``inline-literal`` syntax.
+
+Style: Boolean Constants
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Use "``OFF``" and "``ON``" for boolean values which can be modified by
+the user, such as :prop_tgt:`POSITION_INDEPENDENT_CODE`. Such properties
+may be "enabled" and "disabled". Use "``True``" and "``False``" for
+inherent values which can't be modified after being set, such as the
+:prop_tgt:`IMPORTED` property of a build target.
+
+Style: Inline Literals
+^^^^^^^^^^^^^^^^^^^^^^
+
+Mark up references to keywords in signatures, file names, and other
+technical terms with ``inline-literal`` syntax, for example:
+
+.. code-block:: rst
+
+ If ``WIN32`` is used with :command:`add_executable`, the
+ :prop_tgt:`WIN32_EXECUTABLE` target property is enabled. That command
+ creates the file ``<name>.exe`` on Windows.
+
+Style: Cross-References
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Mark up linkable references as links, including repeats.
+An alternative, which is used by wikipedia
+(`<http://en.wikipedia.org/wiki/WP:REPEATLINK>`_),
+is to link to a reference only once per article. That style is not used
+in CMake documentation.
+
+Style: Referencing CMake Concepts
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If referring to a concept which corresponds to a property, and that
+concept is described in a high-level manual, prefer to link to the
+manual section instead of the property. For example:
+
+.. code-block:: rst
+
+ This command creates an :ref:`Imported Target <Imported Targets>`.
+
+instead of:
+
+.. code-block:: rst
+
+ This command creates an :prop_tgt:`IMPORTED` target.
+
+The latter should be used only when referring specifically to the
+property.
+
+References to manual sections are not automatically created by creating
+a section, but code such as:
+
+.. code-block:: rst
+
+ .. _`Imported Targets`:
+
+creates a suitable anchor. Use an anchor name which matches the name
+of the corresponding section. Refer to the anchor using a
+cross-reference with specified text.
+
+Imported Targets need the ``IMPORTED`` term marked up with care in
+particular because the term may refer to a command keyword
+(``IMPORTED``), a target property (:prop_tgt:`IMPORTED`), or a
+concept (:ref:`Imported Targets`).
+
+Where a property, command or variable is related conceptually to others,
+by for example, being related to the buildsystem description, generator
+expressions or Qt, each relevant property, command or variable should
+link to the primary manual, which provides high-level information. Only
+particular information relating to the command should be in the
+documentation of the command.
+
+Style: Referencing CMake Domain Objects
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When referring to `CMake Domain`_ objects such as properties, variables,
+commands etc, prefer to link to the target object and follow that with
+the type of object it is. For example:
+
+.. code-block:: rst
+
+ Set the :prop_tgt:`AUTOMOC` target property to ``ON``.
+
+Instead of
+
+.. code-block:: rst
+
+ Set the target property :prop_tgt:`AUTOMOC` to ``ON``.
+
+The ``policy`` directive is an exception, and the type us usually
+referred to before the link:
+
+.. code-block:: rst
+
+ If policy :prop_tgt:`CMP0022` is set to ``NEW`` the behavior is ...
+
+However, markup self-references with ``inline-literal`` syntax.
+For example, within the :command:`add_executable` command
+documentation, use
+
+.. code-block:: rst
+
+ ``add_executable``
+
+not
+
+.. code-block:: rst
+
+ :command:`add_executable`
+
+which is used elsewhere.
+
+Modules
+=======
+
+The ``Modules`` directory contains CMake-language ``.cmake`` module files.
+
+Module Documentation
+--------------------
+
+To document CMake module ``Modules/<module-name>.cmake``, modify
+``Help/manual/cmake-modules.7.rst`` to reference the module in the
+``toctree`` directive, in sorted order, as::
+
+ /module/<module-name>
+
+Then add the module document file ``Help/module/<module-name>.rst``
+containing just the line::
+
+ .. cmake-module:: ../../Modules/<module-name>.cmake
+
+The ``cmake-module`` directive will scan the module file to extract
+reStructuredText markup from comment blocks that start in ``.rst:``.
+Add to the top of ``Modules/<module-name>.cmake`` a
+:ref:`Line Comment` block of the form:
+
+.. code-block:: cmake
+
+ #.rst:
+ # <module-name>
+ # -------------
+ #
+ # <reStructuredText documentation of module>
+
+or a :ref:`Bracket Comment` of the form:
+
+.. code-block:: cmake
+
+ #[[.rst:
+ <module-name>
+ -------------
+
+ <reStructuredText documentation of module>
+ #]]
+
+Any number of ``=`` may be used in the opening and closing brackets
+as long as they match. Content on the line containing the closing
+bracket is excluded if and only if the line starts in ``#``.
+
+Additional such ``.rst:`` comments may appear anywhere in the module file.
+All such comments must start with ``#`` in the first column.
+
+For example, a ``Modules/Findxxx.cmake`` module may contain:
+
+.. code-block:: cmake
+
+ #.rst:
+ # FindXxx
+ # -------
+ #
+ # This is a cool module.
+ # This module does really cool stuff.
+ # It can do even more than you think.
+ #
+ # It even needs two paragraphs to tell you about it.
+ # And it defines the following variables:
+ #
+ # * VAR_COOL: this is great isn't it?
+ # * VAR_REALLY_COOL: cool right?
+
+ <code>
+
+ #[========================================[.rst:
+ .. command:: xxx_do_something
+
+ This command does something for Xxx::
+
+ xxx_do_something(some arguments)
+ #]========================================]
+ macro(xxx_do_something)
+ <code>
+ endmacro()
+
+After the top documentation block, leave a *BLANK* line, and then add a
+copyright and licence notice block like this one (change only the year
+range and name)
+
+.. code-block:: cmake
+
+ #=============================================================================
+ # Copyright 2009-2011 Your Name
+ #
+ # Distributed under the OSI-approved BSD License (the "License");
+ # see accompanying file Copyright.txt for details.
+ #
+ # This software is distributed WITHOUT ANY WARRANTY; without even the
+ # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ # See the License for more information.
+ #=============================================================================
+ # (To distribute this file outside of CMake, substitute the full
+ # License text for the above reference.)
+
+Test the documentation formatting by running
+``cmake --help-module <module-name>``, and also by enabling the
+``SPHINX_HTML`` and ``SPHINX_MAN`` options to build the documentation.
+Edit the comments until generated documentation looks satisfactory. To
+have a .cmake file in this directory NOT show up in the modules
+documentation, simply leave out the ``Help/module/<module-name>.rst``
+file and the ``Help/manual/cmake-modules.7.rst`` toctree entry.
+
+.. _`Find Modules`:
+
+Find Modules
+------------
+
+A "find module" is a ``Modules/Find<package>.cmake`` file to be loaded
+by the :command:`find_package` command when invoked for ``<package>``.
+
+The primary task of a find module is to determine whether a package
+exists on the system, set the ``<package>_FOUND`` variable to reflect
+this and provide any variables, macros and imported targets required to
+use the package. A find module is useful in cases where an upstream
+library does not provide a
+:ref:`config file package <Config File Packages>`.
+
+The traditional approach is to use variables for everything, including
+libraries and executables: see the `Standard Variable Names`_ section
+below. This is what most of the existing find modules provided by CMake
+do.
+
+The more modern approach is to behave as much like
+:ref:`config file packages <Config File Packages>` files as possible, by
+providing :ref:`imported target <Imported targets>`. This has the advantage
+of propagating :ref:`Target Usage Requirements` to consumers.
+
+In either case (or even when providing both variables and imported
+targets), find modules should provide backwards compatibility with old
+versions that had the same name.
+
+A FindFoo.cmake module will typically be loaded by the command::
+
+ find_package(Foo [major[.minor[.patch[.tweak]]]]
+ [EXACT] [QUIET] [REQUIRED]
+ [[COMPONENTS] [components...]]
+ [OPTIONAL_COMPONENTS components...]
+ [NO_POLICY_SCOPE])
+
+See the :command:`find_package` documentation for details on what
+variables are set for the find module. Most of these are dealt with by
+using :module:`FindPackageHandleStandardArgs`.
+
+Briefly, the module should only locate versions of the package
+compatible with the requested version, as described by the
+``Foo_FIND_VERSION`` family of variables. If ``Foo_FIND_QUIETLY`` is
+set to true, it should avoid printing messages, including anything
+complaining about the package not being found. If ``Foo_FIND_REQUIRED``
+is set to true, the module should issue a ``FATAL_ERROR`` if the package
+cannot be found. If neither are set to true, it should print a
+non-fatal message if it cannot find the package.
+
+Packages that find multiple semi-independent parts (like bundles of
+libraries) should search for the components listed in
+``Foo_FIND_COMPONENTS`` if it is set , and only set ``Foo_FOUND`` to
+true if for each searched-for component ``<c>`` that was not found,
+``Foo_FIND_REQUIRED_<c>`` is not set to true. The ``HANDLE_COMPONENTS``
+argument of ``find_package_handle_standard_args()`` can be used to
+implement this.
+
+If ``Foo_FIND_COMPONENTS`` is not set, which modules are searched for
+and required is up to the find module, but should be documented.
+
+For internal implementation, it is a generally accepted convention that
+variables starting with underscore are for temporary use only.
+
+Like all modules, find modules should be properly documented. To add a
+module to the CMake documentation, follow the steps in the `Module
+Documentation`_ section above.
+
+
+
+Standard Variable Names
+^^^^^^^^^^^^^^^^^^^^^^^
+
+For a ``FindXxx.cmake`` module that takes the approach of setting
+variables (either instead of or in addition to creating imported
+targets), the following variable names should be used to keep things
+consistent between find modules. Note that all variables start with
+``Xxx_`` to make sure they do not interfere with other find modules; the
+same consideration applies to macros, functions and imported targets.
+
+``Xxx_INCLUDE_DIRS``
+ The final set of include directories listed in one variable for use by
+ client code. This should not be a cache entry.
+
+``Xxx_LIBRARIES``
+ The libraries to link against to use Xxx. These should include full
+ paths. This should not be a cache entry.
+
+``Xxx_DEFINITIONS``
+ Definitions to use when compiling code that uses Xxx. This really
+ shouldn't include options such as ``-DHAS_JPEG`` that a client
+ source-code file uses to decide whether to ``#include <jpeg.h>``
+
+``Xxx_EXECUTABLE``
+ Where to find the Xxx tool.
+
+``Xxx_Yyy_EXECUTABLE``
+ Where to find the Yyy tool that comes with Xxx.
+
+``Xxx_LIBRARY_DIRS``
+ Optionally, the final set of library directories listed in one
+ variable for use by client code. This should not be a cache entry.
+
+``Xxx_ROOT_DIR``
+ Where to find the base directory of Xxx.
+
+``Xxx_VERSION_Yy``
+ Expect Version Yy if true. Make sure at most one of these is ever true.
+
+``Xxx_WRAP_Yy``
+ If False, do not try to use the relevant CMake wrapping command.
+
+``Xxx_Yy_FOUND``
+ If False, optional Yy part of Xxx system is not available.
+
+``Xxx_FOUND``
+ Set to false, or undefined, if we haven't found, or don't want to use
+ Xxx.
+
+``Xxx_NOT_FOUND_MESSAGE``
+ Should be set by config-files in the case that it has set
+ ``Xxx_FOUND`` to FALSE. The contained message will be printed by the
+ :command:`find_package` command and by
+ ``find_package_handle_standard_args()`` to inform the user about the
+ problem.
+
+``Xxx_RUNTIME_LIBRARY_DIRS``
+ Optionally, the runtime library search path for use when running an
+ executable linked to shared libraries. The list should be used by
+ user code to create the ``PATH`` on windows or ``LD_LIBRARY_PATH`` on
+ UNIX. This should not be a cache entry.
+
+``Xxx_VERSION``
+ The full version string of the package found, if any. Note that many
+ existing modules provide ``Xxx_VERSION_STRING`` instead.
+
+``Xxx_VERSION_MAJOR``
+ The major version of the package found, if any.
+
+``Xxx_VERSION_MINOR``
+ The minor version of the package found, if any.
+
+``Xxx_VERSION_PATCH``
+ The patch version of the package found, if any.
+
+The following names should not usually be used in CMakeLists.txt files, but
+are typically cache variables for users to edit and control the
+behaviour of find modules (like entering the path to a library manually)
+
+``Xxx_LIBRARY``
+ The path of the Xxx library (as used with :command:`find_library`, for
+ example).
+
+``Xxx_Yy_LIBRARY``
+ The path of the Yy library that is part of the Xxx system. It may or
+ may not be required to use Xxx.
+
+``Xxx_INCLUDE_DIR``
+ Where to find headers for using the Xxx library.
+
+``Xxx_Yy_INCLUDE_DIR``
+ Where to find headers for using the Yy library of the Xxx system.
+
+To prevent users being overwhelmed with settings to configure, try to
+keep as many options as possible out of the cache, leaving at least one
+option which can be used to disable use of the module, or locate a
+not-found library (e.g. ``Xxx_ROOT_DIR``). For the same reason, mark
+most cache options as advanced. For packages which provide both debug
+and release binaries, it is common to create cache variables with a
+``_LIBRARY_<CONFIG>`` suffix, such as ``Foo_LIBRARY_RELEASE`` and
+``Foo_LIBRARY_DEBUG``.
+
+While these are the standard variable names, you should provide
+backwards compatibility for any old names that were actually in use.
+Make sure you comment them as deprecated, so that no-one starts using
+them.
+
+
+
+A Sample Find Module
+^^^^^^^^^^^^^^^^^^^^
+
+We will describe how to create a simple find module for a library
+``Foo``.
+
+The first thing that is needed is documentation. CMake's documentation
+system requires you to start the file with a documentation marker and
+the name of the module. You should follow this with a simple statement
+of what the module does.
+
+.. code-block:: cmake
+
+ #.rst:
+ # FindFoo
+ # -------
+ #
+ # Finds the Foo library
+ #
+
+More description may be required for some packages. If there are
+caveats or other details users of the module should be aware of, you can
+add further paragraphs below this. Then you need to document what
+variables and imported targets are set by the module, such as
+
+.. code-block:: cmake
+
+ # This will define the following variables::
+ #
+ # Foo_FOUND - True if the system has the Foo library
+ # Foo_VERSION - The version of the Foo library which was found
+ #
+ # and the following imported targets::
+ #
+ # Foo::Foo - The Foo library
+
+If the package provides any macros, they should be listed here, but can
+be documented where they are defined. See the `Module
+Documentation`_ section above for more details.
+
+After the documentation, leave a blank line, and then add a copyright and
+licence notice block
+
+.. code-block:: cmake
+
+ #=============================================================================
+ # Copyright 2009-2011 Your Name
+ #
+ # Distributed under the OSI-approved BSD License (the "License");
+ # see accompanying file Copyright.txt for details.
+ #
+ # This software is distributed WITHOUT ANY WARRANTY; without even the
+ # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ # See the License for more information.
+ #=============================================================================
+ # (To distribute this file outside of CMake, substitute the full
+ # License text for the above reference.)
+
+Now the actual libraries and so on have to be found. The code here will
+obviously vary from module to module (dealing with that, after all, is the
+point of find modules), but there tends to be a common pattern for libraries.
+
+First, we try to use ``pkg-config`` to find the library. Note that we
+cannot rely on this, as it may not be available, but it provides a good
+starting point.
+
+.. code-block:: cmake
+
+ find_package(PkgConfig)
+ pkg_check_modules(PC_Foo QUIET Foo)
+
+This should define some variables starting ``PC_Foo_`` that contain the
+information from the ``Foo.pc`` file.
+
+Now we need to find the libraries and include files; we use the
+information from ``pkg-config`` to provide hints to CMake about where to
+look.
+
+.. code-block:: cmake
+
+ find_path(Foo_INCLUDE_DIR
+ NAMES foo.h
+ PATHS ${PC_Foo_INCLUDE_DIRS}
+ PATH_SUFFIXES Foo
+ )
+ find_library(Foo_LIBRARY
+ NAMES foo
+ PATHS ${PC_Foo_LIBRARY_DIRS}
+ )
+
+If you have a good way of getting the version (from a header file, for
+example), you can use that information to set ``Foo_VERSION`` (although
+note that find modules have traditionally used ``Foo_VERSION_STRING``,
+so you may want to set both). Otherwise, attempt to use the information
+from ``pkg-config``
+
+.. code-block:: cmake
+
+ set(Foo_VERSION ${PC_Foo_VERSION})
+
+Now we can use :module:`FindPackageHandleStandardArgs` to do most of the
+rest of the work for us
+
+.. code-block:: cmake
+
+ include(FindPackageHandleStandardArgs)
+ find_package_handle_standard_args(Foo
+ FOUND_VAR Foo_FOUND
+ REQUIRED_VARS
+ Foo_LIBRARY
+ Foo_INCLUDE_DIR
+ VERSION_VAR Foo_VERSION
+ )
+
+This will check that the ``REQUIRED_VARS`` contain values (that do not
+end in ``-NOTFOUND``) and set ``Foo_FOUND`` appropriately. It will also
+cache those values. If ``Foo_VERSION`` is set, and a required version
+was passed to :command:`find_package`, it will check the requested version
+against the one in ``Foo_VERSION``. It will also print messages as
+appropriate; note that if the package was found, it will print the
+contents of the first required variable to indicate where it was found.
+
+At this point, we have to provide a way for users of the find module to
+link to the library or libraries that were found. There are two
+approaches, as discussed in the `Find Modules`_ section above. The
+traditional variable approach looks like
+
+.. code-block:: cmake
+
+ if(Foo_FOUND)
+ set(Foo_LIBRARIES ${Foo_LIBRARY})
+ set(Foo_INCLUDE_DIRS ${Foo_INCLUDE_DIR})
+ set(Foo_DEFINITIONS ${PC_Foo_CFLAGS_OTHER})
+ endif()
+
+If more than one library was found, all of them should be included in
+these variables (see the `Standard Variable Names`_ section for more
+information).
+
+When providing imported targets, these should be namespaced (hence the
+``Foo::`` prefix); CMake will recognize that values passed to
+:command:`target_link_libraries` that contain ``::`` in their name are
+supposed to be imported targets (rather than just library names), and
+will produce appropriate diagnostic messages if that target does not
+exist (see policy :policy:`CMP0028`).
+
+.. code-block:: cmake
+
+ if(Foo_FOUND AND NOT TARGET Foo::Foo)
+ add_library(Foo::Foo UNKNOWN IMPORTED)
+ set_target_properties(Foo::Foo PROPERTIES
+ IMPORTED_LOCATION "${Foo_LIBRARY}"
+ INTERFACE_COMPILE_OPTIONS "${PC_Foo_CFLAGS_OTHER}"
+ INTERFACE_INCLUDE_DIRECTORIES "${Foo_INCLUDE_DIR}"
+ )
+ endif()
+
+One thing to note about this is that the ``INTERFACE_INCLUDE_DIRECTORIES`` and
+similar properties should only contain information about the target itself, and
+not any of its dependencies. Instead, those dependencies should also be
+targets, and CMake should be told that they are dependencies of this target.
+CMake will then combine all the necessary information automatically.
+
+The type of the :prop_tgt:`IMPORTED` target created in the
+:command:`add_library` command can always be specified as ``UNKNOWN``
+type. This simplifies the code in cases where static or shared variants may
+be found, and CMake will determine the type by inspecting the files.
+
+If the library is available with multiple configurations, the
+:prop_tgt:`IMPORTED_CONFIGURATIONS` target property should also be
+populated:
+
+.. code-block:: cmake
+
+ if(Foo_FOUND)
+ if (NOT TARGET Foo::Foo)
+ add_library(Foo::Foo UNKNOWN IMPORTED)
+ endif()
+ if (Foo_LIBRARY_RELEASE)
+ set_property(TARGET Foo::Foo APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS RELEASE
+ )
+ set_target_properties(Foo::Foo PROPERTIES
+ IMPORTED_LOCATION_RELEASE "${Foo_LIBRARY_RELEASE}"
+ )
+ endif()
+ if (Foo_LIBRARY_DEBUG)
+ set_property(TARGET Foo::Foo APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS DEBUG
+ )
+ set_target_properties(Foo::Foo PROPERTIES
+ IMPORTED_LOCATION_DEBUG "${Foo_LIBRARY_DEBUG}"
+ )
+ endif()
+ set_target_properties(Foo::Foo PROPERTIES
+ INTERFACE_COMPILE_OPTIONS "${PC_Foo_CFLAGS_OTHER}"
+ INTERFACE_INCLUDE_DIRECTORIES "${Foo_INCLUDE_DIR}"
+ )
+ endif()
+
+The ``RELEASE`` variant should be listed first in the property
+so that that variant is chosen if the user uses a configuration which is
+not an exact match for any listed ``IMPORTED_CONFIGURATIONS``.
+
+Most of the cache variables should be hidden in the ``ccmake`` interface unless
+the user explicitly asks to edit them.
+
+.. code-block:: cmake
+
+ mark_as_advanced(
+ Foo_INCLUDE_DIR
+ Foo_LIBRARY
+ )
+
+If this module replaces an older version, you should set compatibility variables
+to cause the least disruption possible.
+
+.. code-block:: cmake
+
+ # compatibility variables
+ set(Foo_VERSION_STRING ${Foo_VERSION})
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
new file mode 100644
index 000000000..13ee4bd3f
--- /dev/null
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -0,0 +1,284 @@
+.. cmake-manual-description: CMake Generator Expressions
+
+cmake-generator-expressions(7)
+******************************
+
+.. only:: html
+
+ .. contents::
+
+Introduction
+============
+
+Generator expressions are evaluated during build system generation to produce
+information specific to each build configuration.
+
+Generator expressions are allowed in the context of many target properties,
+such as :prop_tgt:`LINK_LIBRARIES`, :prop_tgt:`INCLUDE_DIRECTORIES`,
+:prop_tgt:`COMPILE_DEFINITIONS` and others. They may also be used when using
+commands to populate those properties, such as :command:`target_link_libraries`,
+:command:`target_include_directories`, :command:`target_compile_definitions`
+and others.
+
+This means that they enable conditional linking, conditional
+definitions used when compiling, and conditional include directories and
+more. The conditions may be based on the build configuration, target
+properties, platform information or any other queryable information.
+
+Logical Expressions
+===================
+
+Logical expressions are used to create conditional output. The basic
+expressions are the ``0`` and ``1`` expressions. Because other logical
+expressions evaluate to either ``0`` or ``1``, they can be composed to
+create conditional output::
+
+ $<$<CONFIG:Debug>:DEBUG_MODE>
+
+expands to ``DEBUG_MODE`` when the ``Debug`` configuration is used, and
+otherwise expands to nothing.
+
+Available logical expressions are:
+
+``$<BOOL:...>``
+ ``1`` if the ``...`` is true, else ``0``
+``$<AND:?[,?]...>``
+ ``1`` if all ``?`` are ``1``, else ``0``
+
+ The ``?`` must always be either ``0`` or ``1`` in boolean expressions.
+
+``$<OR:?[,?]...>``
+ ``0`` if all ``?`` are ``0``, else ``1``
+``$<NOT:?>``
+ ``0`` if ``?`` is ``1``, else ``1``
+``$<STREQUAL:a,b>``
+ ``1`` if ``a`` is STREQUAL ``b``, else ``0``
+``$<EQUAL:a,b>``
+ ``1`` if ``a`` is EQUAL ``b`` in a numeric comparison, else ``0``
+``$<CONFIG:cfg>``
+ ``1`` if config is ``cfg``, else ``0``. This is a case-insensitive comparison.
+ The mapping in :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>` is also considered by
+ this expression when it is evaluated on a property on an :prop_tgt:`IMPORTED`
+ target.
+``$<PLATFORM_ID:comp>``
+ ``1`` if the CMake-id of the platform matches ``comp``, otherwise ``0``.
+``$<C_COMPILER_ID:comp>``
+ ``1`` if the CMake-id of the C compiler matches ``comp``, otherwise ``0``.
+``$<CXX_COMPILER_ID:comp>``
+ ``1`` if the CMake-id of the CXX compiler matches ``comp``, otherwise ``0``.
+``$<VERSION_GREATER:v1,v2>``
+ ``1`` if ``v1`` is a version greater than ``v2``, else ``0``.
+``$<VERSION_LESS:v1,v2>``
+ ``1`` if ``v1`` is a version less than ``v2``, else ``0``.
+``$<VERSION_EQUAL:v1,v2>``
+ ``1`` if ``v1`` is the same version as ``v2``, else ``0``.
+``$<C_COMPILER_VERSION:ver>``
+ ``1`` if the version of the C compiler matches ``ver``, otherwise ``0``.
+``$<CXX_COMPILER_VERSION:ver>``
+ ``1`` if the version of the CXX compiler matches ``ver``, otherwise ``0``.
+``$<TARGET_POLICY:pol>``
+ ``1`` if the policy ``pol`` was NEW when the 'head' target was created,
+ else ``0``. If the policy was not set, the warning message for the policy
+ will be emitted. This generator expression only works for a subset of
+ policies.
+``$<COMPILE_FEATURES:feature[,feature]...>``
+ ``1`` if all of the ``feature`` features are available for the 'head'
+ target, and ``0`` otherwise. If this expression is used while evaluating
+ the link implementation of a target and if any dependency transitively
+ increases the required :prop_tgt:`C_STANDARD` or :prop_tgt:`CXX_STANDARD`
+ for the 'head' target, an error is reported. See the
+ :manual:`cmake-compile-features(7)` manual for information on
+ compile features and a list of supported compilers.
+``$<COMPILE_LANGUAGE:lang>``
+ ``1`` when the language used for compilation unit matches ``lang``,
+ otherwise ``0``. This expression used to specify compile options for
+ source files of a particular language in a target. For example, to specify
+ the use of the ``-fno-exceptions`` compile option (compiler id checks
+ elided):
+
+ .. code-block:: cmake
+
+ add_executable(myapp main.cpp foo.c bar.cpp)
+ target_compile_options(myapp
+ PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions>
+ )
+
+ This generator expression has limited use because it is not possible to
+ use it with the Visual Studio generators. Portable buildsystems would
+ not use this expression, and would create separate libraries for each
+ source file language instead:
+
+ .. code-block:: cmake
+
+ add_library(myapp_c foo.c)
+ add_library(myapp_cxx foo.c)
+ target_compile_options(myapp_cxx PUBLIC -fno-exceptions)
+ add_executable(myapp main.cpp)
+ target_link_libraries(myapp myapp_c myapp_cxx)
+
+ The ``Makefile`` and ``Ninja`` based generators can also use this
+ expression to specify compile-language specific compile definitions
+ and include directories:
+
+ .. code-block:: cmake
+
+ add_executable(myapp main.cpp foo.c bar.cpp)
+ target_compile_definitions(myapp
+ PRIVATE $<$<COMPILE_LANGUAGE:CXX>:COMPILING_CXX>
+ )
+ target_include_directories(myapp
+ PRIVATE $<$<COMPILE_LANGUAGE:CXX>:/opt/foo/cxx_headers>
+ )
+
+Informational Expressions
+=========================
+
+These expressions expand to some information. The information may be used
+directly, eg::
+
+ include_directories(/usr/include/$<CXX_COMPILER_ID>/)
+
+expands to ``/usr/include/GNU/`` or ``/usr/include/Clang/`` etc, depending on
+the Id of the compiler.
+
+These expressions may also may be combined with logical expressions::
+
+ $<$<VERSION_LESS:$<CXX_COMPILER_VERSION>,4.2.0>:OLD_COMPILER>
+
+expands to ``OLD_COMPILER`` if the
+:variable:`CMAKE_CXX_COMPILER_VERSION <CMAKE_<LANG>_COMPILER_VERSION>` is less
+than 4.2.0.
+
+Available informational expressions are:
+
+``$<CONFIGURATION>``
+ Configuration name. Deprecated. Use ``CONFIG`` instead.
+``$<CONFIG>``
+ Configuration name
+``$<PLATFORM_ID>``
+ The CMake-id of the platform.
+ See also the :variable:`CMAKE_SYSTEM_NAME` variable.
+``$<C_COMPILER_ID>``
+ The CMake-id of the C compiler used.
+ See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
+``$<CXX_COMPILER_ID>``
+ The CMake-id of the CXX compiler used.
+ See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
+``$<C_COMPILER_VERSION>``
+ The version of the C compiler used.
+ See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable.
+``$<CXX_COMPILER_VERSION>``
+ The version of the CXX compiler used.
+ See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable.
+``$<TARGET_FILE:tgt>``
+ Full path to main file (.exe, .so.1.2, .a) where ``tgt`` is the name of a target.
+``$<TARGET_FILE_NAME:tgt>``
+ Name of main file (.exe, .so.1.2, .a).
+``$<TARGET_FILE_DIR:tgt>``
+ Directory of main file (.exe, .so.1.2, .a).
+``$<TARGET_LINKER_FILE:tgt>``
+ File used to link (.a, .lib, .so) where ``tgt`` is the name of a target.
+``$<TARGET_LINKER_FILE_NAME:tgt>``
+ Name of file used to link (.a, .lib, .so).
+``$<TARGET_LINKER_FILE_DIR:tgt>``
+ Directory of file used to link (.a, .lib, .so).
+``$<TARGET_SONAME_FILE:tgt>``
+ File with soname (.so.3) where ``tgt`` is the name of a target.
+``$<TARGET_SONAME_FILE_NAME:tgt>``
+ Name of file with soname (.so.3).
+``$<TARGET_SONAME_FILE_DIR:tgt>``
+ Directory of with soname (.so.3).
+``$<TARGET_PDB_FILE:tgt>``
+ Full path to the linker generated program database file (.pdb)
+ where ``tgt`` is the name of a target.
+
+ See also the :prop_tgt:`PDB_NAME` and :prop_tgt:`PDB_OUTPUT_DIRECTORY`
+ target properties and their configuration specific variants
+ :prop_tgt:`PDB_NAME_<CONFIG>` and :prop_tgt:`PDB_OUTPUT_DIRECTORY_<CONFIG>`.
+``$<TARGET_PDB_FILE_NAME:tgt>``
+ Name of the linker generated program database file (.pdb).
+``$<TARGET_PDB_FILE_DIR:tgt>``
+ Directory of the linker generated program database file (.pdb).
+``$<TARGET_PROPERTY:tgt,prop>``
+ Value of the property ``prop`` on the target ``tgt``.
+
+ Note that ``tgt`` is not added as a dependency of the target this
+ expression is evaluated on.
+``$<TARGET_PROPERTY:prop>``
+ Value of the property ``prop`` on the target on which the generator
+ expression is evaluated.
+``$<INSTALL_PREFIX>``
+ Content of the install prefix when the target is exported via
+ :command:`install(EXPORT)` and empty otherwise.
+``$<COMPILE_LANGUAGE>``
+ The compile language of source files when evaluating compile options. See
+ the unary version for notes about portability of this generator
+ expression.
+
+Output Expressions
+==================
+
+These expressions generate output, in some cases depending on an input. These
+expressions may be combined with other expressions for information or logical
+comparison::
+
+ -I$<JOIN:$<TARGET_PROPERTY:INCLUDE_DIRECTORIES>, -I>
+
+generates a string of the entries in the :prop_tgt:`INCLUDE_DIRECTORIES` target
+property with each entry preceeded by ``-I``. Note that a more-complete use
+in this situation would require first checking if the INCLUDE_DIRECTORIES
+property is non-empty::
+
+ $<$<BOOL:${prop}>:-I$<JOIN:${prop}, -I>>
+
+where ``${prop}`` refers to a helper variable::
+
+ set(prop "$<TARGET_PROPERTY:INCLUDE_DIRECTORIES>")
+
+Available output expressions are:
+
+``$<0:...>``
+ Empty string (ignores ``...``)
+``$<1:...>``
+ Content of ``...``
+``$<JOIN:list,...>``
+ Joins the list with the content of ``...``
+``$<ANGLE-R>``
+ A literal ``>``. Used to compare strings which contain a ``>`` for example.
+``$<COMMA>``
+ A literal ``,``. Used to compare strings which contain a ``,`` for example.
+``$<SEMICOLON>``
+ A literal ``;``. Used to prevent list expansion on an argument with ``;``.
+``$<TARGET_NAME:...>``
+ Marks ``...`` as being the name of a target. This is required if exporting
+ targets to multiple dependent export sets. The ``...`` must be a literal
+ name of a target- it may not contain generator expressions.
+``$<LINK_ONLY:...>``
+ Content of ``...`` except when evaluated in a link interface while
+ propagating :ref:`Target Usage Requirements`, in which case it is the
+ empty string.
+ Intended for use only in an :prop_tgt:`INTERFACE_LINK_LIBRARIES` target
+ property, perhaps via the :command:`target_link_libraries` command,
+ to specify private link dependencies without other usage requirements.
+``$<INSTALL_INTERFACE:...>``
+ Content of ``...`` when the property is exported using :command:`install(EXPORT)`,
+ and empty otherwise.
+``$<BUILD_INTERFACE:...>``
+ Content of ``...`` when the property is exported using :command:`export`, or
+ when the target is used by another target in the same buildsystem. Expands to
+ the empty string otherwise.
+``$<LOWER_CASE:...>``
+ Content of ``...`` converted to lower case.
+``$<UPPER_CASE:...>``
+ Content of ``...`` converted to upper case.
+``$<MAKE_C_IDENTIFIER:...>``
+ Content of ``...`` converted to a C identifier.
+``$<TARGET_OBJECTS:objLib>``
+ List of objects resulting from build of ``objLib``. ``objLib`` must be an
+ object of type ``OBJECT_LIBRARY``. This expression may only be used in
+ the sources of :command:`add_library` and :command:`add_executable`
+ commands.
+``$<SHELL_PATH:...>``
+ Content of ``...`` converted to shell path style. For example, slashes are
+ converted to backslashes in Windows shells and drive letters are converted
+ to posix paths in MSYS shells. The ``...`` must be an absolute path.
diff --git a/Help/manual/cmake-generators.7.rst b/Help/manual/cmake-generators.7.rst
new file mode 100644
index 000000000..cde8de855
--- /dev/null
+++ b/Help/manual/cmake-generators.7.rst
@@ -0,0 +1,112 @@
+.. cmake-manual-description: CMake Generators Reference
+
+cmake-generators(7)
+*******************
+
+.. only:: html
+
+ .. contents::
+
+Introduction
+============
+
+A *CMake Generator* is responsible for writing the input files for
+a native build system. Exactly one of the `CMake Generators`_ must be
+selected for a build tree to determine what native build system is to
+be used. Optionally one of the `Extra Generators`_ may be selected
+as a variant of some of the `Command-Line Build Tool Generators`_ to
+produce project files for an auxiliary IDE.
+
+CMake Generators are platform-specific so each may be available only
+on certain platforms. The :manual:`cmake(1)` command-line tool ``--help``
+output lists available generators on the current platform. Use its ``-G``
+option to specify the generator for a new build tree.
+The :manual:`cmake-gui(1)` offers interactive selection of a generator
+when creating a new build tree.
+
+CMake Generators
+================
+
+Command-Line Build Tool Generators
+----------------------------------
+
+These generators support command-line build tools. In order to use them,
+one must launch CMake from a command-line prompt whose environment is
+already configured for the chosen compiler and build tool.
+
+.. _`Makefile Generators`:
+
+Makefile Generators
+^^^^^^^^^^^^^^^^^^^
+
+.. toctree::
+ :maxdepth: 1
+
+ /generator/Borland Makefiles
+ /generator/MSYS Makefiles
+ /generator/MinGW Makefiles
+ /generator/NMake Makefiles
+ /generator/NMake Makefiles JOM
+ /generator/Unix Makefiles
+ /generator/Watcom WMake
+
+Ninja Generator
+^^^^^^^^^^^^^^^
+
+.. toctree::
+ :maxdepth: 1
+
+ /generator/Ninja
+
+IDE Build Tool Generators
+-------------------------
+
+These generators support Integrated Development Environment (IDE)
+project files. Since the IDEs configure their own environment
+one may launch CMake from any environment.
+
+.. _`Visual Studio Generators`:
+
+Visual Studio Generators
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. toctree::
+ :maxdepth: 1
+
+ /generator/Visual Studio 6
+ /generator/Visual Studio 7
+ /generator/Visual Studio 7 .NET 2003
+ /generator/Visual Studio 8 2005
+ /generator/Visual Studio 9 2008
+ /generator/Visual Studio 10 2010
+ /generator/Visual Studio 11 2012
+ /generator/Visual Studio 12 2013
+ /generator/Visual Studio 14 2015
+
+Other Generators
+^^^^^^^^^^^^^^^^
+
+.. toctree::
+ :maxdepth: 1
+
+ /generator/Green Hills MULTI
+ /generator/Xcode
+
+Extra Generators
+================
+
+Some of the `CMake Generators`_ listed in the :manual:`cmake(1)`
+command-line tool ``--help`` output may have variants that specify
+an extra generator for an auxiliary IDE tool. Such generator
+names have the form ``<extra-generator> - <main-generator>``.
+The following extra generators are known to CMake.
+
+.. toctree::
+ :maxdepth: 1
+
+ /generator/CodeBlocks
+ /generator/CodeLite
+ /generator/Eclipse CDT4
+ /generator/KDevelop3
+ /generator/Kate
+ /generator/Sublime Text 2
diff --git a/Help/manual/cmake-gui.1.rst b/Help/manual/cmake-gui.1.rst
new file mode 100644
index 000000000..032b51fda
--- /dev/null
+++ b/Help/manual/cmake-gui.1.rst
@@ -0,0 +1,35 @@
+.. cmake-manual-description: CMake GUI Command-Line Reference
+
+cmake-gui(1)
+************
+
+Synopsis
+========
+
+.. parsed-literal::
+
+ cmake-gui [<options>]
+ cmake-gui [<options>] (<path-to-source> | <path-to-existing-build>)
+
+Description
+===========
+
+The "cmake-gui" executable is the CMake GUI. Project configuration
+settings may be specified interactively. Brief instructions are
+provided at the bottom of the window when the program is running.
+
+CMake is a cross-platform build system generator. Projects specify
+their build process with platform-independent CMake listfiles included
+in each directory of a source tree with the name CMakeLists.txt.
+Users build a project by using CMake to generate a build system for a
+native tool on their platform.
+
+Options
+=======
+
+.. include:: OPTIONS_HELP.txt
+
+See Also
+========
+
+.. include:: LINKS.txt
diff --git a/Help/manual/cmake-language.7.rst b/Help/manual/cmake-language.7.rst
new file mode 100644
index 000000000..41542c914
--- /dev/null
+++ b/Help/manual/cmake-language.7.rst
@@ -0,0 +1,572 @@
+.. cmake-manual-description: CMake Language Reference
+
+cmake-language(7)
+*****************
+
+.. only:: html
+
+ .. contents::
+
+Organization
+============
+
+CMake input files are written in the "CMake Language" in source files
+named ``CMakeLists.txt`` or ending in a ``.cmake`` file name extension.
+
+CMake Language source files in a project are organized into:
+
+* `Directories`_ (``CMakeLists.txt``),
+* `Scripts`_ (``<script>.cmake``), and
+* `Modules`_ (``<module>.cmake``).
+
+Directories
+-----------
+
+When CMake processes a project source tree, the entry point is
+a source file called ``CMakeLists.txt`` in the top-level source
+directory. This file may contain the entire build specification
+or use the :command:`add_subdirectory` command to add subdirectories
+to the build. Each subdirectory added by the command must also
+contain a ``CMakeLists.txt`` file as the entry point to that
+directory. For each source directory whose ``CMakeLists.txt`` file
+is processed CMake generates a corresponding directory in the build
+tree to act as the default working and output directory.
+
+Scripts
+-------
+
+An individual ``<script>.cmake`` source file may be processed
+in *script mode* by using the :manual:`cmake(1)` command-line tool
+with the ``-P`` option. Script mode simply runs the commands in
+the given CMake Language source file and does not generate a
+build system. It does not allow CMake commands that define build
+targets or actions.
+
+Modules
+-------
+
+CMake Language code in either `Directories`_ or `Scripts`_ may
+use the :command:`include` command to load a ``<module>.cmake``
+source file in the scope of the including context.
+See the :manual:`cmake-modules(7)` manual page for documentation
+of modules included with the CMake distribution.
+Project source trees may also provide their own modules and
+specify their location(s) in the :variable:`CMAKE_MODULE_PATH`
+variable.
+
+Syntax
+======
+
+.. _`CMake Language Encoding`:
+
+Encoding
+--------
+
+A CMake Language source file may be written in 7-bit ASCII text for
+maximum portability across all supported platforms. Newlines may be
+encoded as either ``\n`` or ``\r\n`` but will be converted to ``\n``
+as input files are read.
+
+Note that the implementation is 8-bit clean so source files may
+be encoded as UTF-8 on platforms with system APIs supporting this
+encoding. In addition, CMake 3.2 and above support source files
+encoded in UTF-8 on Windows (using UTF-16 to call system APIs).
+Furthermore, CMake 3.0 and above allow a leading UTF-8
+`Byte-Order Mark`_ in source files.
+
+.. _`Byte-Order Mark`: http://en.wikipedia.org/wiki/Byte_order_mark
+
+Source Files
+------------
+
+A CMake Language source file consists of zero or more
+`Command Invocations`_ separated by newlines and optionally
+spaces and `Comments`_:
+
+.. raw:: latex
+
+ \begin{small}
+
+.. productionlist::
+ file: `file_element`*
+ file_element: `command_invocation` `line_ending` |
+ : (`bracket_comment`|`space`)* `line_ending`
+ line_ending: `line_comment`? `newline`
+ space: <match '[ \t]+'>
+ newline: <match '\n'>
+
+.. raw:: latex
+
+ \end{small}
+
+Note that any source file line not inside `Command Arguments`_ or
+a `Bracket Comment`_ can end in a `Line Comment`_.
+
+.. _`Command Invocations`:
+
+Command Invocations
+-------------------
+
+A *command invocation* is a name followed by paren-enclosed arguments
+separated by whitespace:
+
+.. raw:: latex
+
+ \begin{small}
+
+.. productionlist::
+ command_invocation: `space`* `identifier` `space`* '(' `arguments` ')'
+ identifier: <match '[A-Za-z_][A-Za-z0-9_]*'>
+ arguments: `argument`? `separated_arguments`*
+ separated_arguments: `separation`+ `argument`? |
+ : `separation`* '(' `arguments` ')'
+ separation: `space` | `line_ending`
+
+.. raw:: latex
+
+ \end{small}
+
+For example:
+
+.. code-block:: cmake
+
+ add_executable(hello world.c)
+
+Command names are case-insensitive.
+Nested unquoted parentheses in the arguments must balance.
+Each ``(`` or ``)`` is given to the command invocation as
+a literal `Unquoted Argument`_. This may be used in calls
+to the :command:`if` command to enclose conditions.
+For example:
+
+.. code-block:: cmake
+
+ if(FALSE AND (FALSE OR TRUE)) # evaluates to FALSE
+
+.. note::
+ CMake versions prior to 3.0 require command name identifiers
+ to be at least 2 characters.
+
+ CMake versions prior to 2.8.12 silently accept an `Unquoted Argument`_
+ or a `Quoted Argument`_ immediately following a `Quoted Argument`_ and
+ not separated by any whitespace. For compatibility, CMake 2.8.12 and
+ higher accept such code but produce a warning.
+
+Command Arguments
+-----------------
+
+There are three types of arguments within `Command Invocations`_:
+
+.. raw:: latex
+
+ \begin{small}
+
+.. productionlist::
+ argument: `bracket_argument` | `quoted_argument` | `unquoted_argument`
+
+.. raw:: latex
+
+ \end{small}
+
+.. _`Bracket Argument`:
+
+Bracket Argument
+^^^^^^^^^^^^^^^^
+
+A *bracket argument*, inspired by `Lua`_ long bracket syntax,
+encloses content between opening and closing "brackets" of the
+same length:
+
+.. raw:: latex
+
+ \begin{small}
+
+.. productionlist::
+ bracket_argument: `bracket_open` `bracket_content` `bracket_close`
+ bracket_open: '[' '='{len} '['
+ bracket_content: <any text not containing a `bracket_close`
+ : of the same {len} as the `bracket_open`>
+ bracket_close: ']' '='{len} ']'
+
+.. raw:: latex
+
+ \end{small}
+
+An opening bracket of length *len >= 0* is written ``[`` followed
+by *len* ``=`` followed by ``[`` and the corresponding closing
+bracket is written ``]`` followed by *len* ``=`` followed by ``]``.
+Brackets do not nest. A unique length may always be chosen
+for the opening and closing brackets to contain closing brackets
+of other lengths.
+
+Bracket argument content consists of all text between the opening
+and closing brackets, except that one newline immediately following
+the opening bracket, if any, is ignored. No evaluation of the
+enclosed content, such as `Escape Sequences`_ or `Variable References`_,
+is performed. A bracket argument is always given to the command
+invocation as exactly one argument.
+
+For example:
+
+.. code-block:: cmake
+
+ message([=[
+ This is the first line in a bracket argument with bracket length 1.
+ No \-escape sequences or ${variable} references are evaluated.
+ This is always one argument even though it contains a ; character.
+ The text does not end on a closing bracket of length 0 like ]].
+ It does end in a closing bracket of length 1.
+ ]=])
+
+.. note::
+ CMake versions prior to 3.0 do not support bracket arguments.
+ They interpret the opening bracket as the start of an
+ `Unquoted Argument`_.
+
+.. _`Lua`: http://www.lua.org/
+
+.. _`Quoted Argument`:
+
+Quoted Argument
+^^^^^^^^^^^^^^^
+
+A *quoted argument* encloses content between opening and closing
+double-quote characters:
+
+.. raw:: latex
+
+ \begin{small}
+
+.. productionlist::
+ quoted_argument: '"' `quoted_element`* '"'
+ quoted_element: <any character except '\' or '"'> |
+ : `escape_sequence` |
+ : `quoted_continuation`
+ quoted_continuation: '\' `newline`
+
+.. raw:: latex
+
+ \end{small}
+
+Quoted argument content consists of all text between opening and
+closing quotes. Both `Escape Sequences`_ and `Variable References`_
+are evaluated. A quoted argument is always given to the command
+invocation as exactly one argument.
+
+For example:
+
+.. code-block:: cmake
+
+ message("This is a quoted argument containing multiple lines.
+ This is always one argument even though it contains a ; character.
+ Both \\-escape sequences and ${variable} references are evaluated.
+ The text does not end on an escaped double-quote like \".
+ It does end in an unescaped double quote.
+ ")
+
+The final ``\`` on any line ending in an odd number of backslashes
+is treated as a line continuation and ignored along with the
+immediately following newline character. For example:
+
+.. code-block:: cmake
+
+ message("\
+ This is the first line of a quoted argument. \
+ In fact it is the only line but since it is long \
+ the source code uses line continuation.\
+ ")
+
+.. note::
+ CMake versions prior to 3.0 do not support continuation with ``\``.
+ They report errors in quoted arguments containing lines ending in
+ an odd number of ``\`` characters.
+
+.. _`Unquoted Argument`:
+
+Unquoted Argument
+^^^^^^^^^^^^^^^^^
+
+An *unquoted argument* is not enclosed by any quoting syntax.
+It may not contain any whitespace, ``(``, ``)``, ``#``, ``"``, or ``\``
+except when escaped by a backslash:
+
+.. raw:: latex
+
+ \begin{small}
+
+.. productionlist::
+ unquoted_argument: `unquoted_element`+ | `unquoted_legacy`
+ unquoted_element: <any character except whitespace or one of '()#"\'> |
+ : `escape_sequence`
+ unquoted_legacy: <see note in text>
+
+.. raw:: latex
+
+ \end{small}
+
+Unquoted argument content consists of all text in a contiguous block
+of allowed or escaped characters. Both `Escape Sequences`_ and
+`Variable References`_ are evaluated. The resulting value is divided
+in the same way `Lists`_ divide into elements. Each non-empty element
+is given to the command invocation as an argument. Therefore an
+unquoted argument may be given to a command invocation as zero or
+more arguments.
+
+For example:
+
+.. code-block:: cmake
+
+ foreach(arg
+ NoSpace
+ Escaped\ Space
+ This;Divides;Into;Five;Arguments
+ Escaped\;Semicolon
+ )
+ message("${arg}")
+ endforeach()
+
+.. note::
+ To support legacy CMake code, unquoted arguments may also contain
+ double-quoted strings (``"..."``, possibly enclosing horizontal
+ whitespace), and make-style variable references (``$(MAKEVAR)``).
+ Unescaped double-quotes must balance, may not appear at the
+ beginning of an unquoted argument, and are treated as part of the
+ content. For example, the unquoted arguments ``-Da="b c"``,
+ ``-Da=$(v)``, and ``a" "b"c"d`` are each interpreted literally.
+
+ The above "unquoted_legacy" production represents such arguments.
+ We do not recommend using legacy unquoted arguments in new code.
+ Instead use a `Quoted Argument`_ or a `Bracket Argument`_ to
+ represent the content.
+
+.. _`Escape Sequences`:
+
+Escape Sequences
+----------------
+
+An *escape sequence* is a ``\`` followed by one character:
+
+.. raw:: latex
+
+ \begin{small}
+
+.. productionlist::
+ escape_sequence: `escape_identity` | `escape_encoded` | `escape_semicolon`
+ escape_identity: '\' <match '[^A-Za-z0-9;]'>
+ escape_encoded: '\t' | '\r' | '\n'
+ escape_semicolon: '\;'
+
+.. raw:: latex
+
+ \end{small}
+
+A ``\`` followed by a non-alphanumeric character simply encodes the literal
+character without interpreting it as syntax. A ``\t``, ``\r``, or ``\n``
+encodes a tab, carriage return, or newline character, respectively. A ``\;``
+outside of any `Variable References`_ encodes itself but may be used in an
+`Unquoted Argument`_ to encode the ``;`` without dividing the argument
+value on it. A ``\;`` inside `Variable References`_ encodes the literal
+``;`` character. (See also policy :policy:`CMP0053` documentation for
+historical considerations.)
+
+.. _`Variable References`:
+
+Variable References
+-------------------
+
+A *variable reference* has the form ``${variable_name}`` and is
+evaluated inside a `Quoted Argument`_ or an `Unquoted Argument`_.
+A variable reference is replaced by the value of the variable,
+or by the empty string if the variable is not set.
+Variable references can nest and are evaluated from the
+inside out, e.g. ``${outer_${inner_variable}_variable}``.
+
+Literal variable references may consist of alphanumeric characters,
+the characters ``/_.+-``, and `Escape Sequences`_. Nested references
+may be used to evaluate variables of any name. (See also policy
+:policy:`CMP0053` documentation for historical considerations.)
+
+The `Variables`_ section documents the scope of variable names
+and how their values are set.
+
+An *environment variable reference* has the form ``$ENV{VAR}`` and
+is evaluated in the same contexts as a normal variable reference.
+
+Comments
+--------
+
+A comment starts with a ``#`` character that is not inside a
+`Bracket Argument`_, `Quoted Argument`_, or escaped with ``\``
+as part of an `Unquoted Argument`_. There are two types of
+comments: a `Bracket Comment`_ and a `Line Comment`_.
+
+.. _`Bracket Comment`:
+
+Bracket Comment
+^^^^^^^^^^^^^^^
+
+A ``#`` immediately followed by a `Bracket Argument`_ forms a
+*bracket comment* consisting of the entire bracket enclosure:
+
+.. raw:: latex
+
+ \begin{small}
+
+.. productionlist::
+ bracket_comment: '#' `bracket_argument`
+
+.. raw:: latex
+
+ \end{small}
+
+For example:
+
+.. code-block:: cmake
+
+ #[[This is a bracket comment.
+ It runs until the close bracket.]]
+ message("First Argument\n" #[[Bracket Comment]] "Second Argument")
+
+.. note::
+ CMake versions prior to 3.0 do not support bracket comments.
+ They interpret the opening ``#`` as the start of a `Line Comment`_.
+
+.. _`Line Comment`:
+
+Line Comment
+^^^^^^^^^^^^
+
+A ``#`` not immediately followed by a `Bracket Argument`_ forms a
+*line comment* that runs until the end of the line:
+
+.. raw:: latex
+
+ \begin{small}
+
+.. productionlist::
+ line_comment: '#' <any text not starting in a `bracket_argument`
+ : and not containing a `newline`>
+
+.. raw:: latex
+
+ \end{small}
+
+For example:
+
+.. code-block:: cmake
+
+ # This is a line comment.
+ message("First Argument\n" # This is a line comment :)
+ "Second Argument") # This is a line comment.
+
+Control Structures
+==================
+
+Conditional Blocks
+------------------
+
+The :command:`if`/:command:`elseif`/:command:`else`/:command:`endif`
+commands delimit code blocks to be executed conditionally.
+
+Loops
+-----
+
+The :command:`foreach`/:command:`endforeach` and
+:command:`while`/:command:`endwhile` commands delimit code
+blocks to be executed in a loop. Inside such blocks the
+:command:`break` command may be used to terminate the loop
+early whereas the :command:`continue` command may be used
+to start with the next iteration immediately.
+
+Command Definitions
+-------------------
+
+The :command:`macro`/:command:`endmacro`, and
+:command:`function`/:command:`endfunction` commands delimit
+code blocks to be recorded for later invocation as commands.
+
+.. _`CMake Language Variables`:
+
+Variables
+=========
+
+Variables are the basic unit of storage in the CMake Language.
+Their values are always of string type, though some commands may
+interpret the strings as values of other types.
+The :command:`set` and :command:`unset` commands explicitly
+set or unset a variable, but other commands have semantics
+that modify variables as well.
+Variable names are case-sensitive and may consist of almost
+any text, but we recommend sticking to names consisting only
+of alphanumeric characters plus ``_`` and ``-``.
+
+Variables have dynamic scope. Each variable "set" or "unset"
+creates a binding in the current scope:
+
+Function Scope
+ `Command Definitions`_ created by the :command:`function` command
+ create commands that, when invoked, process the recorded commands
+ in a new variable binding scope. A variable "set" or "unset"
+ binds in this scope and is visible for the current function and
+ any nested calls, but not after the function returns.
+
+Directory Scope
+ Each of the `Directories`_ in a source tree has its own variable
+ bindings. Before processing the ``CMakeLists.txt`` file for a
+ directory, CMake copies all variable bindings currently defined
+ in the parent directory, if any, to initialize the new directory
+ scope. CMake `Scripts`_, when processed with ``cmake -P``, bind
+ variables in one "directory" scope.
+
+ A variable "set" or "unset" not inside a function call binds
+ to the current directory scope.
+
+Persistent Cache
+ CMake stores a separate set of "cache" variables, or "cache entries",
+ whose values persist across multiple runs within a project build
+ tree. Cache entries have an isolated binding scope modified only
+ by explicit request, such as by the ``CACHE`` option of the
+ :command:`set` and :command:`unset` commands.
+
+When evaluating `Variable References`_, CMake first searches the
+function call stack, if any, for a binding and then falls back
+to the binding in the current directory scope, if any. If a
+"set" binding is found, its value is used. If an "unset" binding
+is found, or no binding is found, CMake then searches for a
+cache entry. If a cache entry is found, its value is used.
+Otherwise, the variable reference evaluates to an empty string.
+
+The :manual:`cmake-variables(7)` manual documents many variables
+that are provided by CMake or have meaning to CMake when set
+by project code.
+
+.. _`CMake Language Lists`:
+
+Lists
+=====
+
+Although all values in CMake are stored as strings, a string
+may be treated as a list in certain contexts, such as during
+evaluation of an `Unquoted Argument`_. In such contexts, a string
+is divided into list elements by splitting on ``;`` characters not
+following an unequal number of ``[`` and ``]`` characters and not
+immediately preceded by a ``\``. The sequence ``\;`` does not
+divide a value but is replaced by ``;`` in the resulting element.
+
+A list of elements is represented as a string by concatenating
+the elements separated by ``;``. For example, the :command:`set`
+command stores multiple values into the destination variable
+as a list:
+
+.. code-block:: cmake
+
+ set(srcs a.c b.c c.c) # sets "srcs" to "a.c;b.c;c.c"
+
+Lists are meant for simple use cases such as a list of source
+files and should not be used for complex data processing tasks.
+Most commands that construct lists do not escape ``;`` characters
+in list elements, thus flattening nested lists:
+
+.. code-block:: cmake
+
+ set(x a "b;c") # sets "x" to "a;b;c", not "a;b\;c"
diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst
new file mode 100644
index 000000000..10f05dffe
--- /dev/null
+++ b/Help/manual/cmake-modules.7.rst
@@ -0,0 +1,245 @@
+.. cmake-manual-description: CMake Modules Reference
+
+cmake-modules(7)
+****************
+
+.. only:: html
+
+ .. contents::
+
+All Modules
+===========
+
+.. toctree::
+ :maxdepth: 1
+
+ /module/AddFileDependencies
+ /module/BundleUtilities
+ /module/CheckCCompilerFlag
+ /module/CheckCSourceCompiles
+ /module/CheckCSourceRuns
+ /module/CheckCXXCompilerFlag
+ /module/CheckCXXSourceCompiles
+ /module/CheckCXXSourceRuns
+ /module/CheckCXXSymbolExists
+ /module/CheckFortranCompilerFlag
+ /module/CheckFortranFunctionExists
+ /module/CheckFortranSourceCompiles
+ /module/CheckFunctionExists
+ /module/CheckIncludeFileCXX
+ /module/CheckIncludeFile
+ /module/CheckIncludeFiles
+ /module/CheckLanguage
+ /module/CheckLibraryExists
+ /module/CheckPrototypeDefinition
+ /module/CheckStructHasMember
+ /module/CheckSymbolExists
+ /module/CheckTypeSize
+ /module/CheckVariableExists
+ /module/CMakeAddFortranSubdirectory
+ /module/CMakeBackwardCompatibilityCXX
+ /module/CMakeDependentOption
+ /module/CMakeDetermineVSServicePack
+ /module/CMakeExpandImportedTargets
+ /module/CMakeFindDependencyMacro
+ /module/CMakeFindFrameworks
+ /module/CMakeFindPackageMode
+ /module/CMakeForceCompiler
+ /module/CMakeGraphVizOptions
+ /module/CMakePackageConfigHelpers
+ /module/CMakeParseArguments
+ /module/CMakePrintHelpers
+ /module/CMakePrintSystemInformation
+ /module/CMakePushCheckState
+ /module/CMakeVerifyManifest
+ /module/CPackBundle
+ /module/CPackComponent
+ /module/CPackCygwin
+ /module/CPackDeb
+ /module/CPackDMG
+ /module/CPackIFW
+ /module/CPackNSIS
+ /module/CPackPackageMaker
+ /module/CPackRPM
+ /module/CPack
+ /module/CPackWIX
+ /module/CTest
+ /module/CTestCoverageCollectGCOV
+ /module/CTestScriptMode
+ /module/CTestUseLaunchers
+ /module/Dart
+ /module/DeployQt4
+ /module/Documentation
+ /module/ExternalData
+ /module/ExternalProject
+ /module/FeatureSummary
+ /module/FindALSA
+ /module/FindArmadillo
+ /module/FindASPELL
+ /module/FindAVIFile
+ /module/FindBISON
+ /module/FindBLAS
+ /module/FindBacktrace
+ /module/FindBoost
+ /module/FindBullet
+ /module/FindBZip2
+ /module/FindCABLE
+ /module/FindCoin3D
+ /module/FindCUDA
+ /module/FindCups
+ /module/FindCURL
+ /module/FindCurses
+ /module/FindCVS
+ /module/FindCxxTest
+ /module/FindCygwin
+ /module/FindDart
+ /module/FindDCMTK
+ /module/FindDevIL
+ /module/FindDoxygen
+ /module/FindEXPAT
+ /module/FindFLEX
+ /module/FindFLTK2
+ /module/FindFLTK
+ /module/FindFreetype
+ /module/FindGCCXML
+ /module/FindGDAL
+ /module/FindGettext
+ /module/FindGIF
+ /module/FindGit
+ /module/FindGLEW
+ /module/FindGLUT
+ /module/FindGnuplot
+ /module/FindGnuTLS
+ /module/FindGSL
+ /module/FindGTest
+ /module/FindGTK2
+ /module/FindGTK
+ /module/FindHDF5
+ /module/FindHg
+ /module/FindHSPELL
+ /module/FindHTMLHelp
+ /module/FindIce
+ /module/FindIcotool
+ /module/FindImageMagick
+ /module/FindIntl
+ /module/FindITK
+ /module/FindJasper
+ /module/FindJava
+ /module/FindJNI
+ /module/FindJPEG
+ /module/FindKDE3
+ /module/FindKDE4
+ /module/FindLAPACK
+ /module/FindLATEX
+ /module/FindLibArchive
+ /module/FindLibLZMA
+ /module/FindLibXml2
+ /module/FindLibXslt
+ /module/FindLua50
+ /module/FindLua51
+ /module/FindLua
+ /module/FindMatlab
+ /module/FindMFC
+ /module/FindMotif
+ /module/FindMPEG2
+ /module/FindMPEG
+ /module/FindMPI
+ /module/FindOpenAL
+ /module/FindOpenCL
+ /module/FindOpenGL
+ /module/FindOpenMP
+ /module/FindOpenSceneGraph
+ /module/FindOpenSSL
+ /module/FindOpenThreads
+ /module/FindosgAnimation
+ /module/FindosgDB
+ /module/Findosg_functions
+ /module/FindosgFX
+ /module/FindosgGA
+ /module/FindosgIntrospection
+ /module/FindosgManipulator
+ /module/FindosgParticle
+ /module/FindosgPresentation
+ /module/FindosgProducer
+ /module/FindosgQt
+ /module/Findosg
+ /module/FindosgShadow
+ /module/FindosgSim
+ /module/FindosgTerrain
+ /module/FindosgText
+ /module/FindosgUtil
+ /module/FindosgViewer
+ /module/FindosgVolume
+ /module/FindosgWidget
+ /module/FindPackageHandleStandardArgs
+ /module/FindPackageMessage
+ /module/FindPerlLibs
+ /module/FindPerl
+ /module/FindPHP4
+ /module/FindPhysFS
+ /module/FindPike
+ /module/FindPkgConfig
+ /module/FindPNG
+ /module/FindPostgreSQL
+ /module/FindProducer
+ /module/FindProtobuf
+ /module/FindPythonInterp
+ /module/FindPythonLibs
+ /module/FindQt3
+ /module/FindQt4
+ /module/FindQt
+ /module/FindQuickTime
+ /module/FindRTI
+ /module/FindRuby
+ /module/FindSDL_image
+ /module/FindSDL_mixer
+ /module/FindSDL_net
+ /module/FindSDL
+ /module/FindSDL_sound
+ /module/FindSDL_ttf
+ /module/FindSelfPackers
+ /module/FindSquish
+ /module/FindSubversion
+ /module/FindSWIG
+ /module/FindTCL
+ /module/FindTclsh
+ /module/FindTclStub
+ /module/FindThreads
+ /module/FindTIFF
+ /module/FindUnixCommands
+ /module/FindVTK
+ /module/FindWget
+ /module/FindWish
+ /module/FindwxWidgets
+ /module/FindwxWindows
+ /module/FindXCTest
+ /module/FindXalanC
+ /module/FindXercesC
+ /module/FindX11
+ /module/FindXMLRPC
+ /module/FindZLIB
+ /module/FortranCInterface
+ /module/GenerateExportHeader
+ /module/GetPrerequisites
+ /module/GNUInstallDirs
+ /module/InstallRequiredSystemLibraries
+ /module/MacroAddFileDependencies
+ /module/ProcessorCount
+ /module/SelectLibraryConfigurations
+ /module/SquishTestScript
+ /module/TestBigEndian
+ /module/TestCXXAcceptsFlag
+ /module/TestForANSIForScope
+ /module/TestForANSIStreamHeaders
+ /module/TestForSSTREAM
+ /module/TestForSTDNamespace
+ /module/UseEcos
+ /module/UseJavaClassFilelist
+ /module/UseJava
+ /module/UseJavaSymlinks
+ /module/UsePkgConfig
+ /module/UseSWIG
+ /module/UsewxWidgets
+ /module/Use_wxWindows
+ /module/WriteBasicConfigVersionFile
+ /module/WriteCompilerDetectionHeader
diff --git a/Help/manual/cmake-packages.7.rst b/Help/manual/cmake-packages.7.rst
new file mode 100644
index 000000000..aebc5d952
--- /dev/null
+++ b/Help/manual/cmake-packages.7.rst
@@ -0,0 +1,709 @@
+.. cmake-manual-description: CMake Packages Reference
+
+cmake-packages(7)
+*****************
+
+.. only:: html
+
+ .. contents::
+
+Introduction
+============
+
+Packages provide dependency information to CMake based buildsystems. Packages
+are found with the :command:`find_package` command. The result of
+using ``find_package`` is either a set of :prop_tgt:`IMPORTED` targets, or
+a set of variables corresponding to build-relevant information.
+
+Using Packages
+==============
+
+CMake provides direct support for two forms of packages,
+`Config-file Packages`_ and `Find-module Packages`_.
+Indirect support for ``pkg-config`` packages is also provided via
+the :module:`FindPkgConfig` module. In all cases, the basic form
+of :command:`find_package` calls is the same:
+
+.. code-block:: cmake
+
+ find_package(Qt4 4.7.0 REQUIRED) # CMake provides a Qt4 find-module
+ find_package(Qt5Core 5.1.0 REQUIRED) # Qt provides a Qt5 package config file.
+ find_package(LibXml2 REQUIRED) # Use pkg-config via the LibXml2 find-module
+
+In cases where it is known that a package configuration file is provided by
+upstream, and only that should be used, the ``CONFIG`` keyword may be passed
+to :command:`find_package`:
+
+.. code-block:: cmake
+
+ find_package(Qt5Core 5.1.0 CONFIG REQUIRED)
+ find_package(Qt5Gui 5.1.0 CONFIG)
+
+Similarly, the ``MODULE`` keyword says to use only a find-module:
+
+.. code-block:: cmake
+
+ find_package(Qt4 4.7.0 MODULE REQUIRED)
+
+Specifying the type of package explicitly improves the error message shown to
+the user if it is not found.
+
+Both types of packages also support specifying components of a package,
+either after the ``REQUIRED`` keyword:
+
+.. code-block:: cmake
+
+ find_package(Qt5 5.1.0 CONFIG REQUIRED Widgets Xml Sql)
+
+or as a separate ``COMPONENTS`` list:
+
+.. code-block:: cmake
+
+ find_package(Qt5 5.1.0 COMPONENTS Widgets Xml Sql)
+
+or as a separate ``OPTIONAL_COMPONENTS`` list:
+
+.. code-block:: cmake
+
+ find_package(Qt5 5.1.0 COMPONENTS Widgets
+ OPTIONAL_COMPONENTS Xml Sql
+ )
+
+Handling of ``COMPONENTS`` and ``OPTIONAL_COMPONENTS`` is defined by the
+package.
+
+By setting the :variable:`CMAKE_DISABLE_FIND_PACKAGE_<PackageName>` variable to
+``TRUE``, the ``PackageName`` package will not be searched, and will always
+be ``NOTFOUND``.
+
+.. _`Config File Packages`:
+
+Config-file Packages
+--------------------
+
+A config-file package is a set of files provided by upstreams for downstreams
+to use. CMake searches in a number of locations for package configuration files, as
+described in the :command:`find_package` documentation. The most simple way for
+a CMake user to tell :manual:`cmake(1)` to search in a non-standard prefix for
+a package is to set the ``CMAKE_PREFIX_PATH`` cache variable.
+
+Config-file packages are provided by upstream vendors as part of development
+packages, that is, they belong with the header files and any other files
+provided to assist downstreams in using the package.
+
+A set of variables which provide package status information are also set
+automatically when using a config-file package. The ``<Package>_FOUND``
+variable is set to true or false, depending on whether the package was
+found. The ``<Package>_DIR`` cache variable is set to the location of the
+package configuration file.
+
+Find-module Packages
+--------------------
+
+A find module is a file with a set of rules for finding the required pieces of
+a dependency, primarily header files and libraries. Typically, a find module
+is needed when the upstream is not built with CMake, or is not CMake-aware
+enough to otherwise provide a package configuration file. Unlike a package configuration
+file, it is not shipped with upstream, but is used by downstream to find the
+files by guessing locations of files with platform-specific hints.
+
+Unlike the case of an upstream-provided package configuration file, no single point
+of reference identifies the package as being found, so the ``<Package>_FOUND``
+variable is not automatically set by the :command:`find_package` command. It
+can still be expected to be set by convention however and should be set by
+the author of the Find-module. Similarly there is no ``<Package>_DIR`` variable,
+but each of the artifacts such as library locations and header file locations
+provide a separate cache variable.
+
+See the :manual:`cmake-developer(7)` manual for more information about creating
+Find-module files.
+
+Package Layout
+==============
+
+A config-file package consists of a `Package Configuration File`_ and
+optionally a `Package Version File`_ provided with the project distribution.
+
+Package Configuration File
+--------------------------
+
+Consider a project ``Foo`` that installs the following files::
+
+ <prefix>/include/foo-1.2/foo.h
+ <prefix>/lib/foo-1.2/libfoo.a
+
+It may also provide a CMake package configuration file::
+
+ <prefix>/lib/cmake/foo-1.2/FooConfig.cmake
+
+with content defining :prop_tgt:`IMPORTED` targets, or defining variables, such
+as:
+
+.. code-block:: cmake
+
+ # ...
+ # (compute PREFIX relative to file location)
+ # ...
+ set(Foo_INCLUDE_DIRS ${PREFIX}/include/foo-1.2)
+ set(Foo_LIBRARIES ${PREFIX}/lib/foo-1.2/libfoo.a)
+
+If another project wishes to use ``Foo`` it need only to locate the ``FooConfig.cmake``
+file and load it to get all the information it needs about package content
+locations. Since the package configuration file is provided by the package
+installation it already knows all the file locations.
+
+The :command:`find_package` command may be used to search for the package
+configuration file. This command constructs a set of installation prefixes
+and searches under each prefix in several locations. Given the name ``Foo``,
+it looks for a file called ``FooConfig.cmake`` or ``foo-config.cmake``.
+The full set of locations is specified in the :command:`find_package` command
+documentation. One place it looks is::
+
+ <prefix>/lib/cmake/Foo*/
+
+where ``Foo*`` is a case-insensitive globbing expression. In our example the
+globbing expression will match ``<prefix>/lib/cmake/foo-1.2`` and the package
+configuration file will be found.
+
+Once found, a package configuration file is immediately loaded. It, together
+with a package version file, contains all the information the project needs to
+use the package.
+
+Package Version File
+--------------------
+
+When the :command:`find_package` command finds a candidate package configuration
+file it looks next to it for a version file. The version file is loaded to test
+whether the package version is an acceptable match for the version requested.
+If the version file claims compatibility the configuration file is accepted.
+Otherwise it is ignored.
+
+The name of the package version file must match that of the package configuration
+file but has either ``-version`` or ``Version`` appended to the name before
+the ``.cmake`` extension. For example, the files::
+
+ <prefix>/lib/cmake/foo-1.3/foo-config.cmake
+ <prefix>/lib/cmake/foo-1.3/foo-config-version.cmake
+
+and::
+
+ <prefix>/lib/cmake/bar-4.2/BarConfig.cmake
+ <prefix>/lib/cmake/bar-4.2/BarConfigVersion.cmake
+
+are each pairs of package configuration files and corresponding package version
+files.
+
+When the :command:`find_package` command loads a version file it first sets the
+following variables:
+
+``PACKAGE_FIND_NAME``
+ The <package> name
+
+``PACKAGE_FIND_VERSION``
+ Full requested version string
+
+``PACKAGE_FIND_VERSION_MAJOR``
+ Major version if requested, else 0
+
+``PACKAGE_FIND_VERSION_MINOR``
+ Minor version if requested, else 0
+
+``PACKAGE_FIND_VERSION_PATCH``
+ Patch version if requested, else 0
+
+``PACKAGE_FIND_VERSION_TWEAK``
+ Tweak version if requested, else 0
+
+``PACKAGE_FIND_VERSION_COUNT``
+ Number of version components, 0 to 4
+
+The version file must use these variables to check whether it is compatible or
+an exact match for the requested version and set the following variables with
+results:
+
+``PACKAGE_VERSION``
+ Full provided version string
+
+``PACKAGE_VERSION_EXACT``
+ True if version is exact match
+
+``PACKAGE_VERSION_COMPATIBLE``
+ True if version is compatible
+
+``PACKAGE_VERSION_UNSUITABLE``
+ True if unsuitable as any version
+
+Version files are loaded in a nested scope so they are free to set any variables
+they wish as part of their computation. The find_package command wipes out the
+scope when the version file has completed and it has checked the output
+variables. When the version file claims to be an acceptable match for the
+requested version the find_package command sets the following variables for
+use by the project:
+
+``<package>_VERSION``
+ Full provided version string
+
+``<package>_VERSION_MAJOR``
+ Major version if provided, else 0
+
+``<package>_VERSION_MINOR``
+ Minor version if provided, else 0
+
+``<package>_VERSION_PATCH``
+ Patch version if provided, else 0
+
+``<package>_VERSION_TWEAK``
+ Tweak version if provided, else 0
+
+``<package>_VERSION_COUNT``
+ Number of version components, 0 to 4
+
+The variables report the version of the package that was actually found.
+The ``<package>`` part of their name matches the argument given to the
+:command:`find_package` command.
+
+.. _`Creating Packages`:
+
+Creating Packages
+=================
+
+Usually, the upstream depends on CMake itself and can use some CMake facilities
+for creating the package files. Consider an upstream which provides a single
+shared library:
+
+.. code-block:: cmake
+
+ project(UpstreamLib)
+
+ set(CMAKE_INCLUDE_CURRENT_DIR ON)
+ set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)
+
+ set(Upstream_VERSION 3.4.1)
+
+ include(GenerateExportHeader)
+
+ add_library(ClimbingStats SHARED climbingstats.cpp)
+ generate_export_header(ClimbingStats)
+ set_property(TARGET ClimbingStats PROPERTY VERSION ${Upstream_VERSION})
+ set_property(TARGET ClimbingStats PROPERTY SOVERSION 3)
+ set_property(TARGET ClimbingStats PROPERTY
+ INTERFACE_ClimbingStats_MAJOR_VERSION 3)
+ set_property(TARGET ClimbingStats APPEND PROPERTY
+ COMPATIBLE_INTERFACE_STRING ClimbingStats_MAJOR_VERSION
+ )
+
+ install(TARGETS ClimbingStats EXPORT ClimbingStatsTargets
+ LIBRARY DESTINATION lib
+ ARCHIVE DESTINATION lib
+ RUNTIME DESTINATION bin
+ INCLUDES DESTINATION include
+ )
+ install(
+ FILES
+ climbingstats.h
+ "${CMAKE_CURRENT_BINARY_DIR}/climbingstats_export.h"
+ DESTINATION
+ include
+ COMPONENT
+ Devel
+ )
+
+ include(CMakePackageConfigHelpers)
+ write_basic_package_version_file(
+ "${CMAKE_CURRENT_BINARY_DIR}/ClimbingStats/ClimbingStatsConfigVersion.cmake"
+ VERSION ${Upstream_VERSION}
+ COMPATIBILITY AnyNewerVersion
+ )
+
+ export(EXPORT ClimbingStatsTargets
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/ClimbingStats/ClimbingStatsTargets.cmake"
+ NAMESPACE Upstream::
+ )
+ configure_file(cmake/ClimbingStatsConfig.cmake
+ "${CMAKE_CURRENT_BINARY_DIR}/ClimbingStats/ClimbingStatsConfig.cmake"
+ COPYONLY
+ )
+
+ set(ConfigPackageLocation lib/cmake/ClimbingStats)
+ install(EXPORT ClimbingStatsTargets
+ FILE
+ ClimbingStatsTargets.cmake
+ NAMESPACE
+ Upstream::
+ DESTINATION
+ ${ConfigPackageLocation}
+ )
+ install(
+ FILES
+ cmake/ClimbingStatsConfig.cmake
+ "${CMAKE_CURRENT_BINARY_DIR}/ClimbingStats/ClimbingStatsConfigVersion.cmake"
+ DESTINATION
+ ${ConfigPackageLocation}
+ COMPONENT
+ Devel
+ )
+
+The :module:`CMakePackageConfigHelpers` module provides a macro for creating
+a simple ``ConfigVersion.cmake`` file. This file sets the version of the
+package. It is read by CMake when :command:`find_package` is called to
+determine the compatibility with the requested version, and to set some
+version-specific variables ``<Package>_VERSION``, ``<Package>_VERSION_MAJOR``,
+``<Package>_VERSION_MINOR`` etc. The :command:`install(EXPORT)` command is
+used to export the targets in the ``ClimbingStatsTargets`` export-set, defined
+previously by the :command:`install(TARGETS)` command. This command generates
+the ``ClimbingStatsTargets.cmake`` file to contain :prop_tgt:`IMPORTED`
+targets, suitable for use by downstreams and arranges to install it to
+``lib/cmake/ClimbingStats``. The generated ``ClimbingStatsConfigVersion.cmake``
+and a ``cmake/ClimbingStatsConfig.cmake`` are installed to the same location,
+completing the package.
+
+The generated :prop_tgt:`IMPORTED` targets have appropriate properties set
+to define their :ref:`usage requirements <Target Usage Requirements>`, such as
+:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`,
+:prop_tgt:`INTERFACE_COMPILE_DEFINITIONS` and other relevant built-in
+``INTERFACE_`` properties. The ``INTERFACE`` variant of user-defined
+properties listed in :prop_tgt:`COMPATIBLE_INTERFACE_STRING` and
+other :ref:`Compatible Interface Properties` are also propagated to the
+generated :prop_tgt:`IMPORTED` targets. In the above case,
+``ClimbingStats_MAJOR_VERSION`` is defined as a string which must be
+compatible among the dependencies of any depender. By setting this custom
+defined user property in this version and in the next version of
+``ClimbingStats``, :manual:`cmake(1)` will issue a diagnostic if there is an
+attempt to use version 3 together with version 4. Packages can choose to
+employ such a pattern if different major versions of the package are designed
+to be incompatible.
+
+A ``NAMESPACE`` with double-colons is specified when exporting the targets
+for installation. This convention of double-colons gives CMake a hint that
+the name is an :prop_tgt:`IMPORTED` target when it is used by downstreams
+with the :command:`target_link_libraries` command. This way, CMake can
+issue a diagnostic if the package providing it has not yet been found.
+
+In this case, when using :command:`install(TARGETS)` the ``INCLUDES DESTINATION``
+was specified. This causes the ``IMPORTED`` targets to have their
+:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` populated with the ``include``
+directory in the :variable:`CMAKE_INSTALL_PREFIX`. When the ``IMPORTED``
+target is used by downstream, it automatically consumes the entries from
+that property.
+
+Creating a Package Configuration File
+-------------------------------------
+
+In this case, the ``ClimbingStatsConfig.cmake`` file could be as simple as:
+
+.. code-block:: cmake
+
+ include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsTargets.cmake")
+
+As this allows downstreams to use the ``IMPORTED`` targets. If any macros
+should be provided by the ``ClimbingStats`` package, they should
+be in a separate file which is installed to the same location as the
+``ClimbingStatsConfig.cmake`` file, and included from there.
+
+This can also be extended to cover dependencies:
+
+.. code-block:: cmake
+
+ # ...
+ add_library(ClimbingStats SHARED climbingstats.cpp)
+ generate_export_header(ClimbingStats)
+
+ find_package(Stats 2.6.4 REQUIRED)
+ target_link_libraries(ClimbingStats PUBLIC Stats::Types)
+
+As the ``Stats::Types`` target is a ``PUBLIC`` dependency of ``ClimbingStats``,
+downstreams must also find the ``Stats`` package and link to the ``Stats::Types``
+library. The ``Stats`` package should be found in the ``ClimbingStatsConfig.cmake``
+file to ensure this. The ``find_dependency`` macro from the
+:module:`CMakeFindDependencyMacro` helps with this by propagating
+whether the package is ``REQUIRED``, or ``QUIET`` etc. All ``REQUIRED``
+dependencies of a package should be found in the ``Config.cmake`` file:
+
+.. code-block:: cmake
+
+ include(CMakeFindDependencyMacro)
+ find_dependency(Stats 2.6.4)
+
+ include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsTargets.cmake")
+ include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsMacros.cmake")
+
+The ``find_dependency`` macro also sets ``ClimbingStats_FOUND`` to ``False`` if
+the dependency is not found, along with a diagnostic that the ``ClimbingStats``
+package can not be used without the ``Stats`` package.
+
+If ``COMPONENTS`` are specified when the downstream uses :command:`find_package`,
+they are listed in the ``<Package>_FIND_COMPONENTS`` variable. If a particular
+component is non-optional, then the ``<Package>_FIND_REQUIRED_<comp>`` will
+be true. This can be tested with logic in the package configuration file:
+
+.. code-block:: cmake
+
+ include(CMakeFindDependencyMacro)
+ find_dependency(Stats 2.6.4)
+
+ include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsTargets.cmake")
+ include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsMacros.cmake")
+
+ set(_supported_components Plot Table)
+
+ foreach(_comp ${ClimbingStats_FIND_COMPONENTS})
+ if (NOT ";${_supported_components};" MATCHES _comp)
+ set(ClimbingStats_FOUND False)
+ set(ClimbingStats_NOTFOUND_MESSAGE "Unsupported component: ${_comp}")
+ endif()
+ include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStats${_comp}Targets.cmake")
+ endforeach()
+
+Here, the ``ClimbingStats_NOTFOUND_MESSAGE`` is set to a diagnosis that the package
+could not be found because an invalid component was specified. This message
+variable can be set for any case where the ``_FOUND`` variable is set to ``False``,
+and will be displayed to the user.
+
+Creating a Package Configuration File for the Build Tree
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The :command:`export(EXPORT)` command creates an :prop_tgt:`IMPORTED` targets
+definition file which is specific to the build-tree, and is not relocatable.
+This can similarly be used with a suitable package configuration file and
+package version file to define a package for the build tree which may be used
+without installation. Consumers of the build tree can simply ensure that the
+:variable:`CMAKE_PREFIX_PATH` contains the build directory, or set the
+``ClimbingStats_DIR`` to ``<build_dir>/ClimbingStats`` in the cache.
+
+.. _`Creating Relocatable Packages`:
+
+Creating Relocatable Packages
+-----------------------------
+
+A relocatable package must not reference absolute paths of files on
+the machine where the package is built that will not exist on the
+machines where the package may be installed.
+
+Packages created by :command:`install(EXPORT)` are designed to be relocatable,
+using paths relative to the location of the package itself. When defining
+the interface of a target for ``EXPORT``, keep in mind that the include
+directories should be specified as relative paths which are relative to the
+:variable:`CMAKE_INSTALL_PREFIX`:
+
+.. code-block:: cmake
+
+ target_include_directories(tgt INTERFACE
+ # Wrong, not relocatable:
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include/TgtName>
+ )
+
+ target_include_directories(tgt INTERFACE
+ # Ok, relocatable:
+ $<INSTALL_INTERFACE:include/TgtName>
+ )
+
+The ``$<INSTALL_PREFIX>``
+:manual:`generator expression <cmake-generator-expressions(7)>` may be used as
+a placeholder for the install prefix without resulting in a non-relocatable
+package. This is necessary if complex generator expressions are used:
+
+.. code-block:: cmake
+
+ target_include_directories(tgt INTERFACE
+ # Ok, relocatable:
+ $<INSTALL_INTERFACE:$<$<CONFIG:Debug>:$<INSTALL_PREFIX>/include/TgtName>>
+ )
+
+This also applies to paths referencing external dependencies.
+It is not advisable to populate any properties which may contain
+paths, such as :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` and
+:prop_tgt:`INTERFACE_LINK_LIBRARIES`, with paths relevant to dependencies.
+For example, this code may not work well for a relocatable package:
+
+.. code-block:: cmake
+
+ target_link_libraries(ClimbingStats INTERFACE
+ ${Foo_LIBRARIES} ${Bar_LIBRARIES}
+ )
+ target_include_directories(ClimbingStats INTERFACE
+ "$<INSTALL_INTERFACE:${Foo_INCLUDE_DIRS};${Bar_INCLUDE_DIRS}>"
+ )
+
+The referenced variables may contain the absolute paths to libraries
+and include directories **as found on the machine the package was made on**.
+This would create a package with hard-coded paths to dependencies and not
+suitable for relocation.
+
+Ideally such dependencies should be used through their own
+:ref:`IMPORTED targets <Imported Targets>` that have their own
+:prop_tgt:`IMPORTED_LOCATION` and usage requirement properties
+such as :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` populated
+appropriately. Those imported targets may then be used with
+the :command:`target_link_libraries` command for ``ClimbingStats``:
+
+.. code-block:: cmake
+
+ target_link_libraries(ClimbingStats INTERFACE Foo::Foo Bar::Bar)
+
+With this approach the package references its external dependencies
+only through the names of :ref:`IMPORTED targets <Imported Targets>`.
+When a consumer uses the installed package, the consumer will run the
+appropriate :command:`find_package` commands (via the ``find_dependency``
+macro described above) to find the dependencies and populate the
+imported targets with appropriate paths on their own machine.
+
+Unfortunately many :manual:`modules <cmake-modules(7)>` shipped with
+CMake do not yet provide :ref:`IMPORTED targets <Imported Targets>`
+because their development pre-dated this approach. This may improve
+incrementally over time. Workarounds to create relocatable packages
+using such modules include:
+
+* When building the package, specify each ``Foo_LIBRARY`` cache
+ entry as just a library name, e.g. ``-DFoo_LIBRARY=foo``. This
+ tells the corresponding find module to populate the ``Foo_LIBRARIES``
+ with just ``foo`` to ask the linker to search for the library
+ instead of hard-coding a path.
+
+* Or, after installing the package content but before creating the
+ package installation binary for redistribution, manually replace
+ the absolute paths with placeholders for substitution by the
+ installation tool when the package is installed.
+
+.. _`Package Registry`:
+
+Package Registry
+================
+
+CMake provides two central locations to register packages that have
+been built or installed anywhere on a system:
+
+* `User Package Registry`_
+* `System Package Registry`_
+
+The registries are especially useful to help projects find packages in
+non-standard install locations or directly in their own build trees.
+A project may populate either the user or system registry (using its own
+means, see below) to refer to its location.
+In either case the package should store at the registered location a
+`Package Configuration File`_ (``<package>Config.cmake``) and optionally a
+`Package Version File`_ (``<package>ConfigVersion.cmake``).
+
+The :command:`find_package` command searches the two package registries
+as two of the search steps specified in its documentation. If it has
+sufficient permissions it also removes stale package registry entries
+that refer to directories that do not exist or do not contain a matching
+package configuration file.
+
+.. _`User Package Registry`:
+
+User Package Registry
+---------------------
+
+The User Package Registry is stored in a per-user location.
+The :command:`export(PACKAGE)` command may be used to register a project
+build tree in the user package registry. CMake currently provides no
+interface to add install trees to the user package registry. Installers
+must be manually taught to register their packages if desired.
+
+On Windows the user package registry is stored in the Windows registry
+under a key in ``HKEY_CURRENT_USER``.
+
+A ``<package>`` may appear under registry key::
+
+ HKEY_CURRENT_USER\Software\Kitware\CMake\Packages\<package>
+
+as a ``REG_SZ`` value, with arbitrary name, that specifies the directory
+containing the package configuration file.
+
+On UNIX platforms the user package registry is stored in the user home
+directory under ``~/.cmake/packages``. A ``<package>`` may appear under
+the directory::
+
+ ~/.cmake/packages/<package>
+
+as a file, with arbitrary name, whose content specifies the directory
+containing the package configuration file.
+
+.. _`System Package Registry`:
+
+System Package Registry
+-----------------------
+
+The System Package Registry is stored in a system-wide location.
+CMake currently provides no interface to add to the system package registry.
+Installers must be manually taught to register their packages if desired.
+
+On Windows the system package registry is stored in the Windows registry
+under a key in ``HKEY_LOCAL_MACHINE``. A ``<package>`` may appear under
+registry key::
+
+ HKEY_LOCAL_MACHINE\Software\Kitware\CMake\Packages\<package>
+
+as a ``REG_SZ`` value, with arbitrary name, that specifies the directory
+containing the package configuration file.
+
+There is no system package registry on non-Windows platforms.
+
+.. _`Disabling the Package Registry`:
+
+Disabling the Package Registry
+------------------------------
+
+In some cases using the Package Registries is not desirable. CMake
+allows to disable them using the following variables:
+
+ * :variable:`CMAKE_EXPORT_NO_PACKAGE_REGISTRY` disables the
+ :command:`export(PACKAGE)` command.
+ * :variable:`CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY` disables the
+ User Package Registry in all the :command:`find_package` calls.
+ * :variable:`CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY` disables
+ the System Package Registry in all the :command:`find_package` calls.
+
+Package Registry Example
+------------------------
+
+A simple convention for naming package registry entries is to use content
+hashes. They are deterministic and unlikely to collide
+(:command:`export(PACKAGE)` uses this approach).
+The name of an entry referencing a specific directory is simply the content
+hash of the directory path itself.
+
+If a project arranges for package registry entries to exist, such as::
+
+ > reg query HKCU\Software\Kitware\CMake\Packages\MyPackage
+ HKEY_CURRENT_USER\Software\Kitware\CMake\Packages\MyPackage
+ 45e7d55f13b87179bb12f907c8de6fc4 REG_SZ c:/Users/Me/Work/lib/cmake/MyPackage
+ 7b4a9844f681c80ce93190d4e3185db9 REG_SZ c:/Users/Me/Work/MyPackage-build
+
+or::
+
+ $ cat ~/.cmake/packages/MyPackage/7d1fb77e07ce59a81bed093bbee945bd
+ /home/me/work/lib/cmake/MyPackage
+ $ cat ~/.cmake/packages/MyPackage/f92c1db873a1937f3100706657c63e07
+ /home/me/work/MyPackage-build
+
+then the ``CMakeLists.txt`` code:
+
+.. code-block:: cmake
+
+ find_package(MyPackage)
+
+will search the registered locations for package configuration files
+(``MyPackageConfig.cmake``). The search order among package registry
+entries for a single package is unspecified and the entry names
+(hashes in this example) have no meaning. Registered locations may
+contain package version files (``MyPackageConfigVersion.cmake``) to
+tell :command:`find_package` whether a specific location is suitable
+for the version requested.
+
+Package Registry Ownership
+--------------------------
+
+Package registry entries are individually owned by the project installations
+that they reference. A package installer is responsible for adding its own
+entry and the corresponding uninstaller is responsible for removing it.
+
+The :command:`export(PACKAGE)` command populates the user package registry
+with the location of a project build tree. Build trees tend to be deleted by
+developers and have no "uninstall" event that could trigger removal of their
+entries. In order to keep the registries clean the :command:`find_package`
+command automatically removes stale entries it encounters if it has sufficient
+permissions. CMake provides no interface to remove an entry referencing an
+existing build tree once :command:`export(PACKAGE)` has been invoked.
+However, if the project removes its package configuration file from the build
+tree then the entry referencing the location will be considered stale.
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
new file mode 100644
index 000000000..ae5354fb4
--- /dev/null
+++ b/Help/manual/cmake-policies.7.rst
@@ -0,0 +1,125 @@
+.. cmake-manual-description: CMake Policies Reference
+
+cmake-policies(7)
+*****************
+
+.. only:: html
+
+ .. contents::
+
+Introduction
+============
+
+Policies in CMake are used to preserve backward compatible behavior
+across multiple releases. When a new policy is introduced, newer CMake
+versions will begin to warn about the backward compatible behavior. It
+is possible to disable the warning by explicitly requesting the OLD, or
+backward compatible behavior using the :command:`cmake_policy` command.
+It is also possible to request ``NEW``, or non-backward compatible behavior
+for a policy, also avoiding the warning. Each policy can also be set to
+either ``NEW`` or ``OLD`` behavior explicitly on the command line with the
+:variable:`CMAKE_POLICY_DEFAULT_CMP<NNNN>` variable.
+
+A policy is a deprecation mechanism and not a reliable feature toggle.
+A policy should almost never be set to ``OLD``, except to silence warnings
+in an otherwise frozen or stable codebase, or temporarily as part of a
+larger migration path. The ``OLD`` behavior of each policy is undesirable
+and will be replaced with an error condition in a future release.
+
+The :command:`cmake_minimum_required` command does more than report an
+error if a too-old version of CMake is used to build a project. It
+also sets all policies introduced in that CMake version or earlier to
+``NEW`` behavior. To manage policies without increasing the minimum required
+CMake version, the :command:`if(POLICY)` command may be used:
+
+.. code-block:: cmake
+
+ if(POLICY CMP0990)
+ cmake_policy(SET CMP0990 NEW)
+ endif()
+
+This has the effect of using the ``NEW`` behavior with newer CMake releases which
+users may be using and not issuing a compatibility warning.
+
+The setting of a policy is confined in some cases to not propagate to the
+parent scope. For example, if the files read by the :command:`include` command
+or the :command:`find_package` command contain a use of :command:`cmake_policy`,
+that policy setting will not affect the caller by default. Both commands accept
+an optional ``NO_POLICY_SCOPE`` keyword to control this behavior.
+
+The :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` variable may also be used
+to determine whether to report an error on use of deprecated macros or
+functions.
+
+All Policies
+============
+
+.. toctree::
+ :maxdepth: 1
+
+ /policy/CMP0000
+ /policy/CMP0001
+ /policy/CMP0002
+ /policy/CMP0003
+ /policy/CMP0004
+ /policy/CMP0005
+ /policy/CMP0006
+ /policy/CMP0007
+ /policy/CMP0008
+ /policy/CMP0009
+ /policy/CMP0010
+ /policy/CMP0011
+ /policy/CMP0012
+ /policy/CMP0013
+ /policy/CMP0014
+ /policy/CMP0015
+ /policy/CMP0016
+ /policy/CMP0017
+ /policy/CMP0018
+ /policy/CMP0019
+ /policy/CMP0020
+ /policy/CMP0021
+ /policy/CMP0022
+ /policy/CMP0023
+ /policy/CMP0024
+ /policy/CMP0025
+ /policy/CMP0026
+ /policy/CMP0027
+ /policy/CMP0028
+ /policy/CMP0029
+ /policy/CMP0030
+ /policy/CMP0031
+ /policy/CMP0032
+ /policy/CMP0033
+ /policy/CMP0034
+ /policy/CMP0035
+ /policy/CMP0036
+ /policy/CMP0037
+ /policy/CMP0038
+ /policy/CMP0039
+ /policy/CMP0040
+ /policy/CMP0041
+ /policy/CMP0042
+ /policy/CMP0043
+ /policy/CMP0044
+ /policy/CMP0045
+ /policy/CMP0046
+ /policy/CMP0047
+ /policy/CMP0048
+ /policy/CMP0049
+ /policy/CMP0050
+ /policy/CMP0051
+ /policy/CMP0052
+ /policy/CMP0053
+ /policy/CMP0054
+ /policy/CMP0055
+ /policy/CMP0056
+ /policy/CMP0057
+ /policy/CMP0058
+ /policy/CMP0059
+ /policy/CMP0060
+ /policy/CMP0061
+ /policy/CMP0062
+ /policy/CMP0063
+ /policy/CMP0064
+ /policy/CMP0065
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
new file mode 100644
index 000000000..a41d48499
--- /dev/null
+++ b/Help/manual/cmake-properties.7.rst
@@ -0,0 +1,401 @@
+.. cmake-manual-description: CMake Properties Reference
+
+cmake-properties(7)
+*******************
+
+.. only:: html
+
+ .. contents::
+
+.. _`Global Properties`:
+
+Properties of Global Scope
+==========================
+
+.. toctree::
+ :maxdepth: 1
+
+ /prop_gbl/ALLOW_DUPLICATE_CUSTOM_TARGETS
+ /prop_gbl/AUTOGEN_TARGETS_FOLDER
+ /prop_gbl/AUTOMOC_TARGETS_FOLDER
+ /prop_gbl/CMAKE_C_KNOWN_FEATURES
+ /prop_gbl/CMAKE_CXX_KNOWN_FEATURES
+ /prop_gbl/DEBUG_CONFIGURATIONS
+ /prop_gbl/DISABLED_FEATURES
+ /prop_gbl/ENABLED_FEATURES
+ /prop_gbl/ENABLED_LANGUAGES
+ /prop_gbl/FIND_LIBRARY_USE_LIB64_PATHS
+ /prop_gbl/FIND_LIBRARY_USE_OPENBSD_VERSIONING
+ /prop_gbl/GLOBAL_DEPENDS_DEBUG_MODE
+ /prop_gbl/GLOBAL_DEPENDS_NO_CYCLES
+ /prop_gbl/IN_TRY_COMPILE
+ /prop_gbl/PACKAGES_FOUND
+ /prop_gbl/PACKAGES_NOT_FOUND
+ /prop_gbl/JOB_POOLS
+ /prop_gbl/PREDEFINED_TARGETS_FOLDER
+ /prop_gbl/ECLIPSE_EXTRA_NATURES
+ /prop_gbl/REPORT_UNDEFINED_PROPERTIES
+ /prop_gbl/RULE_LAUNCH_COMPILE
+ /prop_gbl/RULE_LAUNCH_CUSTOM
+ /prop_gbl/RULE_LAUNCH_LINK
+ /prop_gbl/RULE_MESSAGES
+ /prop_gbl/TARGET_ARCHIVES_MAY_BE_SHARED_LIBS
+ /prop_gbl/TARGET_MESSAGES
+ /prop_gbl/TARGET_SUPPORTS_SHARED_LIBS
+ /prop_gbl/USE_FOLDERS
+
+.. _`Directory Properties`:
+
+Properties on Directories
+=========================
+
+.. toctree::
+ :maxdepth: 1
+
+ /prop_dir/ADDITIONAL_MAKE_CLEAN_FILES
+ /prop_dir/CACHE_VARIABLES
+ /prop_dir/CLEAN_NO_CUSTOM
+ /prop_dir/CMAKE_CONFIGURE_DEPENDS
+ /prop_dir/COMPILE_DEFINITIONS
+ /prop_dir/COMPILE_OPTIONS
+ /prop_dir/DEFINITIONS
+ /prop_dir/EXCLUDE_FROM_ALL
+ /prop_dir/IMPLICIT_DEPENDS_INCLUDE_TRANSFORM
+ /prop_dir/INCLUDE_DIRECTORIES
+ /prop_dir/INCLUDE_REGULAR_EXPRESSION
+ /prop_dir/INTERPROCEDURAL_OPTIMIZATION_CONFIG
+ /prop_dir/INTERPROCEDURAL_OPTIMIZATION
+ /prop_dir/LINK_DIRECTORIES
+ /prop_dir/LISTFILE_STACK
+ /prop_dir/MACROS
+ /prop_dir/PARENT_DIRECTORY
+ /prop_dir/RULE_LAUNCH_COMPILE
+ /prop_dir/RULE_LAUNCH_CUSTOM
+ /prop_dir/RULE_LAUNCH_LINK
+ /prop_dir/TEST_INCLUDE_FILE
+ /prop_dir/VARIABLES
+ /prop_dir/VS_GLOBAL_SECTION_POST_section
+ /prop_dir/VS_GLOBAL_SECTION_PRE_section
+
+.. _`Target Properties`:
+
+Properties on Targets
+=====================
+
+.. toctree::
+ :maxdepth: 1
+
+ /prop_tgt/ALIASED_TARGET
+ /prop_tgt/ANDROID_ANT_ADDITIONAL_OPTIONS
+ /prop_tgt/ANDROID_API
+ /prop_tgt/ANDROID_API_MIN
+ /prop_tgt/ANDROID_ARCH
+ /prop_tgt/ANDROID_ASSETS_DIRECTORIES
+ /prop_tgt/ANDROID_GUI
+ /prop_tgt/ANDROID_JAR_DEPENDENCIES
+ /prop_tgt/ANDROID_JAR_DIRECTORIES
+ /prop_tgt/ANDROID_JAVA_SOURCE_DIR
+ /prop_tgt/ANDROID_NATIVE_LIB_DEPENDENCIES
+ /prop_tgt/ANDROID_NATIVE_LIB_DIRECTORIES
+ /prop_tgt/ANDROID_PROCESS_MAX
+ /prop_tgt/ANDROID_PROGUARD
+ /prop_tgt/ANDROID_PROGUARD_CONFIG_PATH
+ /prop_tgt/ANDROID_SECURE_PROPS_PATH
+ /prop_tgt/ANDROID_SKIP_ANT_STEP
+ /prop_tgt/ANDROID_STL_TYPE
+ /prop_tgt/ARCHIVE_OUTPUT_DIRECTORY_CONFIG
+ /prop_tgt/ARCHIVE_OUTPUT_DIRECTORY
+ /prop_tgt/ARCHIVE_OUTPUT_NAME_CONFIG
+ /prop_tgt/ARCHIVE_OUTPUT_NAME
+ /prop_tgt/AUTOGEN_TARGET_DEPENDS
+ /prop_tgt/AUTOMOC_MOC_OPTIONS
+ /prop_tgt/AUTOMOC
+ /prop_tgt/AUTOUIC
+ /prop_tgt/AUTOUIC_OPTIONS
+ /prop_tgt/AUTORCC
+ /prop_tgt/AUTORCC_OPTIONS
+ /prop_tgt/BINARY_DIR
+ /prop_tgt/BUILD_WITH_INSTALL_RPATH
+ /prop_tgt/BUNDLE_EXTENSION
+ /prop_tgt/BUNDLE
+ /prop_tgt/C_EXTENSIONS
+ /prop_tgt/C_STANDARD
+ /prop_tgt/C_STANDARD_REQUIRED
+ /prop_tgt/COMPATIBLE_INTERFACE_BOOL
+ /prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MAX
+ /prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MIN
+ /prop_tgt/COMPATIBLE_INTERFACE_STRING
+ /prop_tgt/COMPILE_DEFINITIONS
+ /prop_tgt/COMPILE_FEATURES
+ /prop_tgt/COMPILE_FLAGS
+ /prop_tgt/COMPILE_OPTIONS
+ /prop_tgt/COMPILE_PDB_NAME
+ /prop_tgt/COMPILE_PDB_NAME_CONFIG
+ /prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY
+ /prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG
+ /prop_tgt/CONFIG_OUTPUT_NAME
+ /prop_tgt/CONFIG_POSTFIX
+ /prop_tgt/CROSSCOMPILING_EMULATOR
+ /prop_tgt/CXX_EXTENSIONS
+ /prop_tgt/CXX_STANDARD
+ /prop_tgt/CXX_STANDARD_REQUIRED
+ /prop_tgt/DEBUG_POSTFIX
+ /prop_tgt/DEFINE_SYMBOL
+ /prop_tgt/EchoString
+ /prop_tgt/ENABLE_EXPORTS
+ /prop_tgt/EXCLUDE_FROM_ALL
+ /prop_tgt/EXCLUDE_FROM_DEFAULT_BUILD_CONFIG
+ /prop_tgt/EXCLUDE_FROM_DEFAULT_BUILD
+ /prop_tgt/EXPORT_NAME
+ /prop_tgt/FOLDER
+ /prop_tgt/Fortran_FORMAT
+ /prop_tgt/Fortran_MODULE_DIRECTORY
+ /prop_tgt/FRAMEWORK
+ /prop_tgt/FRAMEWORK_VERSION
+ /prop_tgt/GENERATOR_FILE_NAME
+ /prop_tgt/GNUtoMS
+ /prop_tgt/HAS_CXX
+ /prop_tgt/IMPLICIT_DEPENDS_INCLUDE_TRANSFORM
+ /prop_tgt/IMPORTED_CONFIGURATIONS
+ /prop_tgt/IMPORTED_IMPLIB_CONFIG
+ /prop_tgt/IMPORTED_IMPLIB
+ /prop_tgt/IMPORTED_LINK_DEPENDENT_LIBRARIES_CONFIG
+ /prop_tgt/IMPORTED_LINK_DEPENDENT_LIBRARIES
+ /prop_tgt/IMPORTED_LINK_INTERFACE_LANGUAGES_CONFIG
+ /prop_tgt/IMPORTED_LINK_INTERFACE_LANGUAGES
+ /prop_tgt/IMPORTED_LINK_INTERFACE_LIBRARIES_CONFIG
+ /prop_tgt/IMPORTED_LINK_INTERFACE_LIBRARIES
+ /prop_tgt/IMPORTED_LINK_INTERFACE_MULTIPLICITY_CONFIG
+ /prop_tgt/IMPORTED_LINK_INTERFACE_MULTIPLICITY
+ /prop_tgt/IMPORTED_LOCATION_CONFIG
+ /prop_tgt/IMPORTED_LOCATION
+ /prop_tgt/IMPORTED_NO_SONAME_CONFIG
+ /prop_tgt/IMPORTED_NO_SONAME
+ /prop_tgt/IMPORTED
+ /prop_tgt/IMPORTED_SONAME_CONFIG
+ /prop_tgt/IMPORTED_SONAME
+ /prop_tgt/IMPORT_PREFIX
+ /prop_tgt/IMPORT_SUFFIX
+ /prop_tgt/INCLUDE_DIRECTORIES
+ /prop_tgt/INSTALL_NAME_DIR
+ /prop_tgt/INSTALL_RPATH
+ /prop_tgt/INSTALL_RPATH_USE_LINK_PATH
+ /prop_tgt/INTERFACE_AUTOUIC_OPTIONS
+ /prop_tgt/INTERFACE_COMPILE_DEFINITIONS
+ /prop_tgt/INTERFACE_COMPILE_FEATURES
+ /prop_tgt/INTERFACE_COMPILE_OPTIONS
+ /prop_tgt/INTERFACE_INCLUDE_DIRECTORIES
+ /prop_tgt/INTERFACE_LINK_LIBRARIES
+ /prop_tgt/INTERFACE_POSITION_INDEPENDENT_CODE
+ /prop_tgt/INTERFACE_SOURCES
+ /prop_tgt/INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
+ /prop_tgt/INTERPROCEDURAL_OPTIMIZATION_CONFIG
+ /prop_tgt/INTERPROCEDURAL_OPTIMIZATION
+ /prop_tgt/IOS_INSTALL_COMBINED
+ /prop_tgt/JOB_POOL_COMPILE
+ /prop_tgt/JOB_POOL_LINK
+ /prop_tgt/LABELS
+ /prop_tgt/LANG_COMPILER_LAUNCHER
+ /prop_tgt/LANG_INCLUDE_WHAT_YOU_USE
+ /prop_tgt/LANG_VISIBILITY_PRESET
+ /prop_tgt/LIBRARY_OUTPUT_DIRECTORY_CONFIG
+ /prop_tgt/LIBRARY_OUTPUT_DIRECTORY
+ /prop_tgt/LIBRARY_OUTPUT_NAME_CONFIG
+ /prop_tgt/LIBRARY_OUTPUT_NAME
+ /prop_tgt/LINK_DEPENDS_NO_SHARED
+ /prop_tgt/LINK_DEPENDS
+ /prop_tgt/LINKER_LANGUAGE
+ /prop_tgt/LINK_FLAGS_CONFIG
+ /prop_tgt/LINK_FLAGS
+ /prop_tgt/LINK_INTERFACE_LIBRARIES_CONFIG
+ /prop_tgt/LINK_INTERFACE_LIBRARIES
+ /prop_tgt/LINK_INTERFACE_MULTIPLICITY_CONFIG
+ /prop_tgt/LINK_INTERFACE_MULTIPLICITY
+ /prop_tgt/LINK_LIBRARIES
+ /prop_tgt/LINK_SEARCH_END_STATIC
+ /prop_tgt/LINK_SEARCH_START_STATIC
+ /prop_tgt/LOCATION_CONFIG
+ /prop_tgt/LOCATION
+ /prop_tgt/MACOSX_BUNDLE_INFO_PLIST
+ /prop_tgt/MACOSX_BUNDLE
+ /prop_tgt/MACOSX_FRAMEWORK_INFO_PLIST
+ /prop_tgt/MACOSX_RPATH
+ /prop_tgt/MAP_IMPORTED_CONFIG_CONFIG
+ /prop_tgt/NAME
+ /prop_tgt/NO_SONAME
+ /prop_tgt/NO_SYSTEM_FROM_IMPORTED
+ /prop_tgt/OSX_ARCHITECTURES_CONFIG
+ /prop_tgt/OSX_ARCHITECTURES
+ /prop_tgt/OUTPUT_NAME_CONFIG
+ /prop_tgt/OUTPUT_NAME
+ /prop_tgt/PDB_NAME_CONFIG
+ /prop_tgt/PDB_NAME
+ /prop_tgt/PDB_OUTPUT_DIRECTORY_CONFIG
+ /prop_tgt/PDB_OUTPUT_DIRECTORY
+ /prop_tgt/POSITION_INDEPENDENT_CODE
+ /prop_tgt/PREFIX
+ /prop_tgt/PRIVATE_HEADER
+ /prop_tgt/PROJECT_LABEL
+ /prop_tgt/PUBLIC_HEADER
+ /prop_tgt/RESOURCE
+ /prop_tgt/RULE_LAUNCH_COMPILE
+ /prop_tgt/RULE_LAUNCH_CUSTOM
+ /prop_tgt/RULE_LAUNCH_LINK
+ /prop_tgt/RUNTIME_OUTPUT_DIRECTORY_CONFIG
+ /prop_tgt/RUNTIME_OUTPUT_DIRECTORY
+ /prop_tgt/RUNTIME_OUTPUT_NAME_CONFIG
+ /prop_tgt/RUNTIME_OUTPUT_NAME
+ /prop_tgt/SKIP_BUILD_RPATH
+ /prop_tgt/SOURCE_DIR
+ /prop_tgt/SOURCES
+ /prop_tgt/SOVERSION
+ /prop_tgt/STATIC_LIBRARY_FLAGS_CONFIG
+ /prop_tgt/STATIC_LIBRARY_FLAGS
+ /prop_tgt/SUFFIX
+ /prop_tgt/TYPE
+ /prop_tgt/VERSION
+ /prop_tgt/VISIBILITY_INLINES_HIDDEN
+ /prop_tgt/VS_DESKTOP_EXTENSIONS_VERSION
+ /prop_tgt/VS_DOTNET_REFERENCES
+ /prop_tgt/VS_DOTNET_TARGET_FRAMEWORK_VERSION
+ /prop_tgt/VS_GLOBAL_KEYWORD
+ /prop_tgt/VS_GLOBAL_PROJECT_TYPES
+ /prop_tgt/VS_GLOBAL_ROOTNAMESPACE
+ /prop_tgt/VS_GLOBAL_variable
+ /prop_tgt/VS_IOT_EXTENSIONS_VERSION
+ /prop_tgt/VS_IOT_STARTUP_TASK
+ /prop_tgt/VS_KEYWORD
+ /prop_tgt/VS_MOBILE_EXTENSIONS_VERSION
+ /prop_tgt/VS_SCC_AUXPATH
+ /prop_tgt/VS_SCC_LOCALPATH
+ /prop_tgt/VS_SCC_PROJECTNAME
+ /prop_tgt/VS_SCC_PROVIDER
+ /prop_tgt/VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION
+ /prop_tgt/VS_WINRT_COMPONENT
+ /prop_tgt/VS_WINRT_EXTENSIONS
+ /prop_tgt/VS_WINRT_REFERENCES
+ /prop_tgt/WIN32_EXECUTABLE
+ /prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS
+ /prop_tgt/XCODE_ATTRIBUTE_an-attribute
+ /prop_tgt/XCTEST
+
+.. _`Test Properties`:
+
+Properties on Tests
+===================
+
+.. toctree::
+ :maxdepth: 1
+
+ /prop_test/ATTACHED_FILES_ON_FAIL
+ /prop_test/ATTACHED_FILES
+ /prop_test/COST
+ /prop_test/DEPENDS
+ /prop_test/ENVIRONMENT
+ /prop_test/FAIL_REGULAR_EXPRESSION
+ /prop_test/LABELS
+ /prop_test/MEASUREMENT
+ /prop_test/PASS_REGULAR_EXPRESSION
+ /prop_test/PROCESSORS
+ /prop_test/REQUIRED_FILES
+ /prop_test/RESOURCE_LOCK
+ /prop_test/RUN_SERIAL
+ /prop_test/SKIP_RETURN_CODE
+ /prop_test/TIMEOUT
+ /prop_test/WILL_FAIL
+ /prop_test/WORKING_DIRECTORY
+
+.. _`Source File Properties`:
+
+Properties on Source Files
+==========================
+
+.. toctree::
+ :maxdepth: 1
+
+ /prop_sf/ABSTRACT
+ /prop_sf/AUTOUIC_OPTIONS
+ /prop_sf/AUTORCC_OPTIONS
+ /prop_sf/COMPILE_DEFINITIONS
+ /prop_sf/COMPILE_FLAGS
+ /prop_sf/EXTERNAL_OBJECT
+ /prop_sf/Fortran_FORMAT
+ /prop_sf/GENERATED
+ /prop_sf/HEADER_FILE_ONLY
+ /prop_sf/KEEP_EXTENSION
+ /prop_sf/LABELS
+ /prop_sf/LANGUAGE
+ /prop_sf/LOCATION
+ /prop_sf/MACOSX_PACKAGE_LOCATION
+ /prop_sf/OBJECT_DEPENDS
+ /prop_sf/OBJECT_OUTPUTS
+ /prop_sf/SYMBOLIC
+ /prop_sf/VS_DEPLOYMENT_CONTENT
+ /prop_sf/VS_DEPLOYMENT_LOCATION
+ /prop_sf/VS_SHADER_ENTRYPOINT
+ /prop_sf/VS_SHADER_FLAGS
+ /prop_sf/VS_SHADER_MODEL
+ /prop_sf/VS_SHADER_TYPE
+ /prop_sf/VS_XAML_TYPE
+ /prop_sf/WRAP_EXCLUDE
+ /prop_sf/XCODE_EXPLICIT_FILE_TYPE
+ /prop_sf/XCODE_LAST_KNOWN_FILE_TYPE
+
+.. _`Cache Entry Properties`:
+
+Properties on Cache Entries
+===========================
+
+.. toctree::
+ :maxdepth: 1
+
+ /prop_cache/ADVANCED
+ /prop_cache/HELPSTRING
+ /prop_cache/MODIFIED
+ /prop_cache/STRINGS
+ /prop_cache/TYPE
+ /prop_cache/VALUE
+
+.. _`Installed File Properties`:
+
+Properties on Installed Files
+=============================
+
+.. toctree::
+ :maxdepth: 1
+
+ /prop_inst/CPACK_DESKTOP_SHORTCUTS.rst
+ /prop_inst/CPACK_NEVER_OVERWRITE.rst
+ /prop_inst/CPACK_PERMANENT.rst
+ /prop_inst/CPACK_START_MENU_SHORTCUTS.rst
+ /prop_inst/CPACK_STARTUP_SHORTCUTS.rst
+ /prop_inst/CPACK_WIX_ACL.rst
+
+
+Deprecated Properties on Directories
+====================================
+
+.. toctree::
+ :maxdepth: 1
+
+ /prop_dir/COMPILE_DEFINITIONS_CONFIG
+
+
+Deprecated Properties on Targets
+================================
+
+.. toctree::
+ :maxdepth: 1
+
+ /prop_tgt/COMPILE_DEFINITIONS_CONFIG
+ /prop_tgt/POST_INSTALL_SCRIPT
+ /prop_tgt/PRE_INSTALL_SCRIPT
+
+
+Deprecated Properties on Source Files
+=====================================
+
+.. toctree::
+ :maxdepth: 1
+
+ /prop_sf/COMPILE_DEFINITIONS_CONFIG
diff --git a/Help/manual/cmake-qt.7.rst b/Help/manual/cmake-qt.7.rst
new file mode 100644
index 000000000..e8a2c1e68
--- /dev/null
+++ b/Help/manual/cmake-qt.7.rst
@@ -0,0 +1,187 @@
+.. cmake-manual-description: CMake Qt Features Reference
+
+cmake-qt(7)
+***********
+
+.. only:: html
+
+ .. contents::
+
+Introduction
+============
+
+CMake can find and use Qt 4 and Qt 5 libraries. The Qt 4 libraries are found
+by the :module:`FindQt4` find-module shipped with CMake, whereas the
+Qt 5 libraries are found using "Config-file Packages" shipped with Qt 5. See
+:manual:`cmake-packages(7)` for more information about CMake packages, and
+see `the Qt cmake manual <http://qt-project.org/doc/qt-5/cmake-manual.html>`_
+for your Qt version.
+
+Qt 4 and Qt 5 may be used together in the same
+:manual:`CMake buildsystem <cmake-buildsystem(7)>`:
+
+.. code-block:: cmake
+
+ cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR)
+
+ project(Qt4And5)
+
+ set(CMAKE_AUTOMOC ON)
+ set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+ find_package(Qt5Widgets REQUIRED)
+ add_executable(publisher publisher.cpp)
+ target_link_libraries(publisher Qt5::Widgets Qt5::DBus)
+
+ find_package(Qt4 REQUIRED)
+ add_executable(subscriber subscriber.cpp)
+ target_link_libraries(subscriber Qt4::QtGui Qt4::QtDBus)
+
+A CMake target may not link to both Qt 4 and Qt 5. A diagnostic is issued if
+this is attempted or results from transitive target dependency evaluation.
+
+Qt Build Tools
+==============
+
+Qt relies on some bundled tools for code generation, such as ``moc`` for
+meta-object code generation, ``uic`` for widget layout and population,
+and ``rcc`` for virtual filesystem content generation. These tools may be
+automatically invoked by :manual:`cmake(1)` if the appropriate conditions
+are met. The automatic tool invocation may be used with both Qt 4 and Qt 5.
+
+The tools are executed as part of a synthesized custom target generated by
+CMake. Target dependencies may be added to that custom target by adding them
+to the :prop_tgt:`AUTOGEN_TARGET_DEPENDS` target property.
+
+AUTOMOC
+^^^^^^^
+
+The :prop_tgt:`AUTOMOC` target property controls whether :manual:`cmake(1)`
+inspects the C++ files in the target to determine if they require ``moc`` to
+be run, and to create rules to execute ``moc`` at the appropriate time.
+
+If a ``Q_OBJECT`` or ``Q_GADGET`` macro is found in a header file, ``moc``
+will be run on the file. The result will be put into a file named according
+to ``moc_<basename>.cpp``. If the macro is found in a C++ implementation
+file, the moc output will be put into a file named according to
+``<basename>.moc``, following the Qt conventions. The ``moc file`` may be
+included by the user in the C++ implementation file with a preprocessor
+``#include``. If it is not so included, it will be added to a separate file
+which is compiled into the target.
+
+The ``moc`` command line will consume the :prop_tgt:`COMPILE_DEFINITIONS` and
+:prop_tgt:`INCLUDE_DIRECTORIES` target properties from the target it is being
+invoked for, and for the appropriate build configuration.
+
+Generated ``moc_*.cpp`` and ``*.moc`` files are placed in the build directory
+so it is convenient to set the :variable:`CMAKE_INCLUDE_CURRENT_DIR`
+variable. The :prop_tgt:`AUTOMOC` target property may be pre-set for all
+following targets by setting the :variable:`CMAKE_AUTOMOC` variable. The
+:prop_tgt:`AUTOMOC_MOC_OPTIONS` target property may be populated to set
+options to pass to ``moc``. The :variable:`CMAKE_AUTOMOC_MOC_OPTIONS`
+variable may be populated to pre-set the options for all following targets.
+
+.. _`Qt AUTOUIC`:
+
+AUTOUIC
+^^^^^^^
+
+The :prop_tgt:`AUTOUIC` target property controls whether :manual:`cmake(1)`
+inspects the C++ files in the target to determine if they require ``uic`` to
+be run, and to create rules to execute ``uic`` at the appropriate time.
+
+If a preprocessor ``#include`` directive is found which matches
+``ui_<basename>.h``, and a ``<basename>.ui`` file exists, then ``uic`` will
+be executed to generate the appropriate file.
+
+Generated ``ui_*.h`` files are placed in the build directory so it is
+convenient to set the :variable:`CMAKE_INCLUDE_CURRENT_DIR` variable. The
+:prop_tgt:`AUTOUIC` target property may be pre-set for all following targets
+by setting the :variable:`CMAKE_AUTOUIC` variable. The
+:prop_tgt:`AUTOUIC_OPTIONS` target property may be populated to set options
+to pass to ``uic``. The :variable:`CMAKE_AUTOUIC_OPTIONS` variable may be
+populated to pre-set the options for all following targets. The
+:prop_sf:`AUTOUIC_OPTIONS` source file property may be set on the
+``<basename>.ui`` file to set particular options for the file. This
+overrides options from the :prop_tgt:`AUTOUIC_OPTIONS` target property.
+
+A target may populate the :prop_tgt:`INTERFACE_AUTOUIC_OPTIONS` target
+property with options that should be used when invoking ``uic``. This must be
+consistent with the :prop_tgt:`AUTOUIC_OPTIONS` target property content of the
+depender target. The :variable:`CMAKE_DEBUG_TARGET_PROPERTIES` variable may
+be used to track the origin target of such
+:prop_tgt:`INTERFACE_AUTOUIC_OPTIONS`. This means that a library which
+provides an alternative translation system for Qt may specify options which
+should be used when running ``uic``:
+
+.. code-block:: cmake
+
+ add_library(KI18n klocalizedstring.cpp)
+ target_link_libraries(KI18n Qt5::Core)
+
+ # KI18n uses the tr2i18n() function instead of tr(). That function is
+ # declared in the klocalizedstring.h header.
+ set(autouic_options
+ -tr tr2i18n
+ -include klocalizedstring.h
+ )
+
+ set_property(TARGET KI18n APPEND PROPERTY
+ INTERFACE_AUTOUIC_OPTIONS ${autouic_options}
+ )
+
+A consuming project linking to the target exported from upstream automatically
+uses appropriate options when ``uic`` is run by :prop_tgt:`AUTOUIC`, as a
+result of linking with the :prop_tgt:`IMPORTED` target:
+
+.. code-block:: cmake
+
+ set(CMAKE_AUTOUIC ON)
+ # Uses a libwidget.ui file:
+ add_library(LibWidget libwidget.cpp)
+ target_link_libraries(LibWidget
+ KF5::KI18n
+ Qt5::Widgets
+ )
+
+.. _`Qt AUTORCC`:
+
+AUTORCC
+^^^^^^^
+
+The :prop_tgt:`AUTORCC` target property controls whether :manual:`cmake(1)`
+creates rules to execute ``rcc`` at the appropriate time on source files
+which have the suffix ``.qrc``.
+
+.. code-block:: cmake
+
+ add_executable(myexe main.cpp resource_file.qrc)
+
+The :prop_tgt:`AUTORCC` target property may be pre-set for all following targets
+by setting the :variable:`CMAKE_AUTORCC` variable. The
+:prop_tgt:`AUTORCC_OPTIONS` target property may be populated to set options
+to pass to ``rcc``. The :variable:`CMAKE_AUTORCC_OPTIONS` variable may be
+populated to pre-set the options for all following targets. The
+:prop_sf:`AUTORCC_OPTIONS` source file property may be set on the
+``<name>.qrc`` file to set particular options for the file. This
+overrides options from the :prop_tgt:`AUTORCC_OPTIONS` target property.
+
+qtmain.lib on Windows
+=====================
+
+The Qt 4 and 5 :prop_tgt:`IMPORTED` targets for the QtGui libraries specify
+that the qtmain.lib static library shipped with Qt will be linked by all
+dependent executables which have the :prop_tgt:`WIN32_EXECUTABLE` enabled.
+
+To disable this behavior, enable the ``Qt5_NO_LINK_QTMAIN`` target property for
+Qt 5 based targets or ``QT4_NO_LINK_QTMAIN`` target property for Qt 4 based
+targets.
+
+.. code-block:: cmake
+
+ add_executable(myexe WIN32 main.cpp)
+ target_link_libraries(myexe Qt4::QtGui)
+
+ add_executable(myexe_no_qtmain WIN32 main_no_qtmain.cpp)
+ set_property(TARGET main_no_qtmain PROPERTY QT4_NO_LINK_QTMAIN ON)
+ target_link_libraries(main_no_qtmain Qt4::QtGui)
diff --git a/Help/manual/cmake-toolchains.7.rst b/Help/manual/cmake-toolchains.7.rst
new file mode 100644
index 000000000..7b294a87d
--- /dev/null
+++ b/Help/manual/cmake-toolchains.7.rst
@@ -0,0 +1,324 @@
+.. cmake-manual-description: CMake Toolchains Reference
+
+cmake-toolchains(7)
+*******************
+
+.. only:: html
+
+ .. contents::
+
+Introduction
+============
+
+CMake uses a toolchain of utilities to compile, link libraries and create
+archives, and other tasks to drive the build. The toolchain utilities available
+are determined by the languages enabled. In normal builds, CMake automatically
+determines the toolchain for host builds based on system introspection and
+defaults. In cross-compiling scenarios, a toolchain file may be specified
+with information about compiler and utility paths.
+
+Languages
+=========
+
+Languages are enabled by the :command:`project` command. Language-specific
+built-in variables, such as
+:variable:`CMAKE_CXX_COMPILER <CMAKE_<LANG>_COMPILER>`,
+:variable:`CMAKE_CXX_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` etc are set by
+invoking the :command:`project` command. If no project command
+is in the top-level CMakeLists file, one will be implicitly generated. By default
+the enabled languages are C and CXX:
+
+.. code-block:: cmake
+
+ project(C_Only C)
+
+A special value of NONE can also be used with the :command:`project` command
+to enable no languages:
+
+.. code-block:: cmake
+
+ project(MyProject NONE)
+
+The :command:`enable_language` command can be used to enable languages after the
+:command:`project` command:
+
+.. code-block:: cmake
+
+ enable_language(CXX)
+
+When a language is enabled, CMake finds a compiler for that language, and
+determines some information, such as the vendor and version of the compiler,
+the target architecture and bitwidth, the location of corresponding utilities
+etc.
+
+The :prop_gbl:`ENABLED_LANGUAGES` global property contains the languages which
+are currently enabled.
+
+Variables and Properties
+========================
+
+Several variables relate to the language components of a toolchain which are
+enabled. :variable:`CMAKE_<LANG>_COMPILER` is the full path to the compiler used
+for ``<LANG>``. :variable:`CMAKE_<LANG>_COMPILER_ID` is the identifier used
+by CMake for the compiler and :variable:`CMAKE_<LANG>_COMPILER_VERSION` is the
+version of the compiler.
+
+The :variable:`CMAKE_<LANG>_FLAGS` variables and the configuration-specific
+equivalents contain flags that will be added to the compile command when
+compiling a file of a particular language.
+
+As the linker is invoked by the compiler driver, CMake needs a way to determine
+which compiler to use to invoke the linker. This is calculated by the
+:prop_sf:`LANGUAGE` of source files in the target, and in the case of static
+libraries, the language of the dependent libraries. The choice CMake makes may
+be overridden with the :prop_tgt:`LINKER_LANGUAGE` target property.
+
+Toolchain Features
+==================
+
+CMake provides the :command:`try_compile` command and wrapper macros such as
+:module:`CheckCXXSourceCompiles`, :module:`CheckCXXSymbolExists` and
+:module:`CheckIncludeFile` to test capability and availability of various
+toolchain features. These APIs test the toolchain in some way and cache the
+result so that the test does not have to be performed again the next time
+CMake runs.
+
+Some toolchain features have built-in handling in CMake, and do not require
+compile-tests. For example, :prop_tgt:`POSITION_INDEPENDENT_CODE` allows
+specifying that a target should be built as position-independent code, if
+the compiler supports that feature. The :prop_tgt:`<LANG>_VISIBILITY_PRESET`
+and :prop_tgt:`VISIBILITY_INLINES_HIDDEN` target properties add flags for
+hidden visibility, if supported by the compiler.
+
+.. _`Cross Compiling Toolchain`:
+
+Cross Compiling
+===============
+
+If :manual:`cmake(1)` is invoked with the command line parameter
+``-DCMAKE_TOOLCHAIN_FILE=path/to/file``, the file will be loaded early to set
+values for the compilers.
+The :variable:`CMAKE_CROSSCOMPILING` variable is set to true when CMake is
+cross-compiling.
+
+Cross Compiling for Linux
+-------------------------
+
+A typical cross-compiling toolchain for Linux has content such
+as:
+
+.. code-block:: cmake
+
+ set(CMAKE_SYSTEM_NAME Linux)
+ set(CMAKE_SYSTEM_PROCESSOR arm)
+
+ set(CMAKE_SYSROOT /home/devel/rasp-pi-rootfs)
+ set(CMAKE_STAGING_PREFIX /home/devel/stage)
+
+ set(tools /home/devel/gcc-4.7-linaro-rpi-gnueabihf)
+ set(CMAKE_C_COMPILER ${tools}/bin/arm-linux-gnueabihf-gcc)
+ set(CMAKE_CXX_COMPILER ${tools}/bin/arm-linux-gnueabihf-g++)
+
+ set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+ set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+ set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+
+The :variable:`CMAKE_SYSTEM_NAME` is the CMake-identifier of the target platform
+to build for.
+
+The :variable:`CMAKE_SYSTEM_PROCESSOR` is the CMake-identifier of the target architecture
+to build for.
+
+The :variable:`CMAKE_SYSROOT` is optional, and may be specified if a sysroot
+is available.
+
+The :variable:`CMAKE_STAGING_PREFIX` is also optional. It may be used to specify
+a path on the host to install to. The :variable:`CMAKE_INSTALL_PREFIX` is always
+the runtime installation location, even when cross-compiling.
+
+The :variable:`CMAKE_<LANG>_COMPILER` variables may be set to full paths, or to
+names of compilers to search for in standard locations. In cases where CMake does
+not have enough information to extract information from the compiler, the
+:module:`CMakeForceCompiler` module can be used to bypass some of the checks.
+
+CMake ``find_*`` commands will look in the sysroot, and the :variable:`CMAKE_FIND_ROOT_PATH`
+entries by default in all cases, as well as looking in the host system root prefix.
+Although this can be controlled on a case-by-case basis, when cross-compiling, it
+can be useful to exclude looking in either the host or the target for particular
+artifacts. Generally, includes, libraries and packages should be found in the
+target system prefixes, whereas executables which must be run as part of the build
+should be found only on the host and not on the target. This is the purpose of
+the ``CMAKE_FIND_ROOT_PATH_MODE_*`` variables.
+
+.. _`Cray Cross-Compile`:
+
+Cross Compiling for the Cray Linux Environment
+----------------------------------------------
+
+Cross compiling for compute nodes in the Cray Linux Environment can be done
+without needing a separate toolchain file. Specifying
+``-DCMAKE_SYSTEM_NAME=CrayLinuxEnvironment`` on the CMake command line will
+ensure that the appropriate build settings and search paths are configured.
+The platform will pull its configuration from the current environment
+variables and will configure a project to use the compiler wrappers from the
+Cray Programming Environment's ``PrgEnv-*`` modules if present and loaded.
+
+The default configuration of the Cray Programming Environment is to only
+support static libraries. This can be overridden and shared libraries
+enabled by setting the ``CRAYPE_LINK_TYPE`` environment variable to
+``dynamic``.
+
+Running CMake without specifying :variable:`CMAKE_SYSTEM_NAME` will
+run the configure step in host mode assuming a standard Linux environment.
+If not overridden, the ``PrgEnv-*`` compiler wrappers will end up getting used,
+which if targeting the either the login node or compute node, is likely not the
+desired behavior. The exception to this would be if you are building directly
+on a NID instead of cross-compiling from a login node. If trying to build
+software for a login node, you will need to either first unload the
+currently loaded ``PrgEnv-*`` module or explicitly tell CMake to use the
+system compilers in ``/usr/bin`` instead of the Cray wrappers. If instead
+targeting a compute node is desired, just specify the
+:variable:`CMAKE_SYSTEM_NAME` as mentioned above.
+
+Cross Compiling using Clang
+---------------------------
+
+Some compilers such as Clang are inherently cross compilers.
+The :variable:`CMAKE_<LANG>_COMPILER_TARGET` can be set to pass a
+value to those supported compilers when compiling:
+
+.. code-block:: cmake
+
+ set(CMAKE_SYSTEM_NAME Linux)
+ set(CMAKE_SYSTEM_PROCESSOR arm)
+
+ set(triple arm-linux-gnueabihf)
+
+ set(CMAKE_C_COMPILER clang)
+ set(CMAKE_C_COMPILER_TARGET ${triple})
+ set(CMAKE_CXX_COMPILER clang++)
+ set(CMAKE_CXX_COMPILER_TARGET ${triple})
+
+Similarly, some compilers do not ship their own supplementary utilities
+such as linkers, but provide a way to specify the location of the external
+toolchain which will be used by the compiler driver. The
+:variable:`CMAKE_<LANG>_COMPILER_EXTERNAL_TOOLCHAIN` variable can be set in a
+toolchain file to pass the path to the compiler driver.
+
+Cross Compiling for QNX
+-----------------------
+
+As the Clang compiler the QNX QCC compile is inherently a cross compiler.
+And the :variable:`CMAKE_<LANG>_COMPILER_TARGET` can be set to pass a
+value to those supported compilers when compiling:
+
+.. code-block:: cmake
+
+ set(CMAKE_SYSTEM_NAME QNX)
+
+ set(arch gcc_ntoarmv7le)
+
+ set(CMAKE_C_COMPILER qcc)
+ set(CMAKE_C_COMPILER_TARGET ${arch})
+ set(CMAKE_CXX_COMPILER QCC)
+ set(CMAKE_CXX_COMPILER_TARGET ${arch})
+
+Cross Compiling for Windows CE
+------------------------------
+
+Cross compiling for Windows CE requires the corresponding SDK being
+installed on your system. These SDKs are usually installed under
+``C:/Program Files (x86)/Windows CE Tools/SDKs``.
+
+A toolchain file to configure a Visual Studio generator for
+Windows CE may look like this:
+
+.. code-block:: cmake
+
+ set(CMAKE_SYSTEM_NAME WindowsCE)
+
+ set(CMAKE_SYSTEM_VERSION 8.0)
+ set(CMAKE_SYSTEM_PROCESSOR arm)
+
+ set(CMAKE_GENERATOR_TOOLSET CE800) # Can be omitted for 8.0
+ set(CMAKE_GENERATOR_PLATFORM SDK_AM335X_SK_WEC2013_V310)
+
+The :variable:`CMAKE_GENERATOR_PLATFORM` tells the generator which SDK to use.
+Further :variable:`CMAKE_SYSTEM_VERSION` tells the generator what version of
+Windows CE to use. Currently version 8.0 (Windows Embedded Compact 2013) is
+supported out of the box. Other versions may require one to set
+:variable:`CMAKE_GENERATOR_TOOLSET` to the correct value.
+
+Cross Compiling for Windows 10 Universal Applications
+-----------------------------------------------------
+
+A toolchain file to configure a Visual Studio generator for a
+Windows 10 Universal Application may look like this:
+
+.. code-block:: cmake
+
+ set(CMAKE_SYSTEM_NAME WindowsStore)
+ set(CMAKE_SYSTEM_VERSION 10.0)
+
+A Windows 10 Universal Application targets both Windows Store and
+Windows Phone. Specify the :variable:`CMAKE_SYSTEM_VERSION` variable
+to be ``10.0`` to build with the latest available Windows 10 SDK.
+Specify a more specific version (e.g. ``10.0.10240.0`` for RTM)
+to build with the corresponding SDK.
+
+Cross Compiling for Windows Phone
+---------------------------------
+
+A toolchain file to configure a Visual Studio generator for
+Windows Phone may look like this:
+
+.. code-block:: cmake
+
+ set(CMAKE_SYSTEM_NAME WindowsPhone)
+ set(CMAKE_SYSTEM_VERSION 8.1)
+
+Cross Compiling for Windows Store
+---------------------------------
+
+A toolchain file to configure a Visual Studio generator for
+Windows Store may look like this:
+
+.. code-block:: cmake
+
+ set(CMAKE_SYSTEM_NAME WindowsStore)
+ set(CMAKE_SYSTEM_VERSION 8.1)
+
+Cross Compiling using NVIDIA Nsight Tegra
+-----------------------------------------
+
+A toolchain file to configure a Visual Studio generator to
+build using NVIDIA Nsight Tegra targeting Android may look
+like this:
+
+.. code-block:: cmake
+
+ set(CMAKE_SYSTEM_NAME Android)
+
+The :variable:`CMAKE_GENERATOR_TOOLSET` may be set to select
+the Nsight Tegra "Toolchain Version" value.
+
+See also target properties:
+
+* :prop_tgt:`ANDROID_ANT_ADDITIONAL_OPTIONS`
+* :prop_tgt:`ANDROID_API_MIN`
+* :prop_tgt:`ANDROID_API`
+* :prop_tgt:`ANDROID_ARCH`
+* :prop_tgt:`ANDROID_ASSETS_DIRECTORIES`
+* :prop_tgt:`ANDROID_GUI`
+* :prop_tgt:`ANDROID_JAR_DEPENDENCIES`
+* :prop_tgt:`ANDROID_JAR_DIRECTORIES`
+* :prop_tgt:`ANDROID_JAVA_SOURCE_DIR`
+* :prop_tgt:`ANDROID_NATIVE_LIB_DEPENDENCIES`
+* :prop_tgt:`ANDROID_NATIVE_LIB_DIRECTORIES`
+* :prop_tgt:`ANDROID_PROCESS_MAX`
+* :prop_tgt:`ANDROID_PROGUARD_CONFIG_PATH`
+* :prop_tgt:`ANDROID_PROGUARD`
+* :prop_tgt:`ANDROID_SECURE_PROPS_PATH`
+* :prop_tgt:`ANDROID_SKIP_ANT_STEP`
+* :prop_tgt:`ANDROID_STL_TYPE`
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
new file mode 100644
index 000000000..15eaece95
--- /dev/null
+++ b/Help/manual/cmake-variables.7.rst
@@ -0,0 +1,450 @@
+.. cmake-manual-description: CMake Variables Reference
+
+cmake-variables(7)
+******************
+
+.. only:: html
+
+ .. contents::
+
+Variables that Provide Information
+==================================
+
+.. toctree::
+ :maxdepth: 1
+
+ /variable/CMAKE_ARGC
+ /variable/CMAKE_ARGV0
+ /variable/CMAKE_AR
+ /variable/CMAKE_BINARY_DIR
+ /variable/CMAKE_BUILD_TOOL
+ /variable/CMAKE_CACHEFILE_DIR
+ /variable/CMAKE_CACHE_MAJOR_VERSION
+ /variable/CMAKE_CACHE_MINOR_VERSION
+ /variable/CMAKE_CACHE_PATCH_VERSION
+ /variable/CMAKE_CFG_INTDIR
+ /variable/CMAKE_COMMAND
+ /variable/CMAKE_CROSSCOMPILING
+ /variable/CMAKE_CROSSCOMPILING_EMULATOR
+ /variable/CMAKE_CTEST_COMMAND
+ /variable/CMAKE_CURRENT_BINARY_DIR
+ /variable/CMAKE_CURRENT_LIST_DIR
+ /variable/CMAKE_CURRENT_LIST_FILE
+ /variable/CMAKE_CURRENT_LIST_LINE
+ /variable/CMAKE_CURRENT_SOURCE_DIR
+ /variable/CMAKE_DL_LIBS
+ /variable/CMAKE_EDIT_COMMAND
+ /variable/CMAKE_EXECUTABLE_SUFFIX
+ /variable/CMAKE_EXTRA_GENERATOR
+ /variable/CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES
+ /variable/CMAKE_FIND_PACKAGE_NAME
+ /variable/CMAKE_GENERATOR
+ /variable/CMAKE_GENERATOR_PLATFORM
+ /variable/CMAKE_GENERATOR_TOOLSET
+ /variable/CMAKE_HOME_DIRECTORY
+ /variable/CMAKE_IMPORT_LIBRARY_PREFIX
+ /variable/CMAKE_IMPORT_LIBRARY_SUFFIX
+ /variable/CMAKE_JOB_POOL_COMPILE
+ /variable/CMAKE_JOB_POOL_LINK
+ /variable/CMAKE_LINK_LIBRARY_SUFFIX
+ /variable/CMAKE_LINK_SEARCH_END_STATIC
+ /variable/CMAKE_LINK_SEARCH_START_STATIC
+ /variable/CMAKE_MAJOR_VERSION
+ /variable/CMAKE_MAKE_PROGRAM
+ /variable/CMAKE_MATCH_COUNT
+ /variable/CMAKE_MINIMUM_REQUIRED_VERSION
+ /variable/CMAKE_MINOR_VERSION
+ /variable/CMAKE_PARENT_LIST_FILE
+ /variable/CMAKE_PATCH_VERSION
+ /variable/CMAKE_PROJECT_NAME
+ /variable/CMAKE_RANLIB
+ /variable/CMAKE_ROOT
+ /variable/CMAKE_SCRIPT_MODE_FILE
+ /variable/CMAKE_SHARED_LIBRARY_PREFIX
+ /variable/CMAKE_SHARED_LIBRARY_SUFFIX
+ /variable/CMAKE_SHARED_MODULE_PREFIX
+ /variable/CMAKE_SHARED_MODULE_SUFFIX
+ /variable/CMAKE_SIZEOF_VOID_P
+ /variable/CMAKE_SKIP_INSTALL_RULES
+ /variable/CMAKE_SKIP_RPATH
+ /variable/CMAKE_SOURCE_DIR
+ /variable/CMAKE_STANDARD_LIBRARIES
+ /variable/CMAKE_STATIC_LIBRARY_PREFIX
+ /variable/CMAKE_STATIC_LIBRARY_SUFFIX
+ /variable/CMAKE_TOOLCHAIN_FILE
+ /variable/CMAKE_TWEAK_VERSION
+ /variable/CMAKE_VERBOSE_MAKEFILE
+ /variable/CMAKE_VERSION
+ /variable/CMAKE_VS_DEVENV_COMMAND
+ /variable/CMAKE_VS_INTEL_Fortran_PROJECT_VERSION
+ /variable/CMAKE_VS_MSBUILD_COMMAND
+ /variable/CMAKE_VS_MSDEV_COMMAND
+ /variable/CMAKE_VS_NsightTegra_VERSION
+ /variable/CMAKE_VS_PLATFORM_NAME
+ /variable/CMAKE_VS_PLATFORM_TOOLSET
+ /variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION
+ /variable/CMAKE_XCODE_PLATFORM_TOOLSET
+ /variable/PROJECT_BINARY_DIR
+ /variable/PROJECT-NAME_BINARY_DIR
+ /variable/PROJECT_NAME
+ /variable/PROJECT-NAME_SOURCE_DIR
+ /variable/PROJECT-NAME_VERSION
+ /variable/PROJECT-NAME_VERSION_MAJOR
+ /variable/PROJECT-NAME_VERSION_MINOR
+ /variable/PROJECT-NAME_VERSION_PATCH
+ /variable/PROJECT-NAME_VERSION_TWEAK
+ /variable/PROJECT_SOURCE_DIR
+ /variable/PROJECT_VERSION
+ /variable/PROJECT_VERSION_MAJOR
+ /variable/PROJECT_VERSION_MINOR
+ /variable/PROJECT_VERSION_PATCH
+ /variable/PROJECT_VERSION_TWEAK
+
+Variables that Change Behavior
+==============================
+
+.. toctree::
+ :maxdepth: 1
+
+ /variable/BUILD_SHARED_LIBS
+ /variable/CMAKE_ABSOLUTE_DESTINATION_FILES
+ /variable/CMAKE_APPBUNDLE_PATH
+ /variable/CMAKE_AUTOMOC_RELAXED_MODE
+ /variable/CMAKE_BACKWARDS_COMPATIBILITY
+ /variable/CMAKE_BUILD_TYPE
+ /variable/CMAKE_COLOR_MAKEFILE
+ /variable/CMAKE_CONFIGURATION_TYPES
+ /variable/CMAKE_DEBUG_TARGET_PROPERTIES
+ /variable/CMAKE_DISABLE_FIND_PACKAGE_PackageName
+ /variable/CMAKE_ERROR_DEPRECATED
+ /variable/CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION
+ /variable/CMAKE_EXPORT_COMPILE_COMMANDS
+ /variable/CMAKE_EXPORT_NO_PACKAGE_REGISTRY
+ /variable/CMAKE_SYSROOT
+ /variable/CMAKE_FIND_APPBUNDLE
+ /variable/CMAKE_FIND_FRAMEWORK
+ /variable/CMAKE_FIND_LIBRARY_PREFIXES
+ /variable/CMAKE_FIND_LIBRARY_SUFFIXES
+ /variable/CMAKE_FIND_NO_INSTALL_PREFIX
+ /variable/CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY
+ /variable/CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY
+ /variable/CMAKE_FIND_PACKAGE_WARN_NO_MODULE
+ /variable/CMAKE_FIND_ROOT_PATH
+ /variable/CMAKE_FIND_ROOT_PATH_MODE_INCLUDE
+ /variable/CMAKE_FIND_ROOT_PATH_MODE_LIBRARY
+ /variable/CMAKE_FIND_ROOT_PATH_MODE_PACKAGE
+ /variable/CMAKE_FIND_ROOT_PATH_MODE_PROGRAM
+ /variable/CMAKE_FRAMEWORK_PATH
+ /variable/CMAKE_IGNORE_PATH
+ /variable/CMAKE_INCLUDE_PATH
+ /variable/CMAKE_INCLUDE_DIRECTORIES_BEFORE
+ /variable/CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE
+ /variable/CMAKE_INSTALL_DEFAULT_COMPONENT_NAME
+ /variable/CMAKE_INSTALL_MESSAGE
+ /variable/CMAKE_INSTALL_PREFIX
+ /variable/CMAKE_LIBRARY_PATH
+ /variable/CMAKE_MFC_FLAG
+ /variable/CMAKE_MODULE_PATH
+ /variable/CMAKE_NOT_USING_CONFIG_FLAGS
+ /variable/CMAKE_POLICY_DEFAULT_CMPNNNN
+ /variable/CMAKE_POLICY_WARNING_CMPNNNN
+ /variable/CMAKE_PREFIX_PATH
+ /variable/CMAKE_PROGRAM_PATH
+ /variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE
+ /variable/CMAKE_SKIP_INSTALL_ALL_DEPENDENCY
+ /variable/CMAKE_STAGING_PREFIX
+ /variable/CMAKE_SYSTEM_APPBUNDLE_PATH
+ /variable/CMAKE_SYSTEM_FRAMEWORK_PATH
+ /variable/CMAKE_SYSTEM_IGNORE_PATH
+ /variable/CMAKE_SYSTEM_INCLUDE_PATH
+ /variable/CMAKE_SYSTEM_LIBRARY_PATH
+ /variable/CMAKE_SYSTEM_PREFIX_PATH
+ /variable/CMAKE_SYSTEM_PROGRAM_PATH
+ /variable/CMAKE_USER_MAKE_RULES_OVERRIDE
+ /variable/CMAKE_WARN_DEPRECATED
+ /variable/CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION
+
+Variables that Describe the System
+==================================
+
+.. toctree::
+ :maxdepth: 1
+
+ /variable/APPLE
+ /variable/BORLAND
+ /variable/CMAKE_CL_64
+ /variable/CMAKE_COMPILER_2005
+ /variable/CMAKE_HOST_APPLE
+ /variable/CMAKE_HOST_SYSTEM_NAME
+ /variable/CMAKE_HOST_SYSTEM_PROCESSOR
+ /variable/CMAKE_HOST_SYSTEM
+ /variable/CMAKE_HOST_SYSTEM_VERSION
+ /variable/CMAKE_HOST_UNIX
+ /variable/CMAKE_HOST_WIN32
+ /variable/CMAKE_LIBRARY_ARCHITECTURE_REGEX
+ /variable/CMAKE_LIBRARY_ARCHITECTURE
+ /variable/CMAKE_OBJECT_PATH_MAX
+ /variable/CMAKE_SYSTEM_NAME
+ /variable/CMAKE_SYSTEM_PROCESSOR
+ /variable/CMAKE_SYSTEM
+ /variable/CMAKE_SYSTEM_VERSION
+ /variable/CYGWIN
+ /variable/ENV
+ /variable/GHS-MULTI
+ /variable/MINGW
+ /variable/MSVC10
+ /variable/MSVC11
+ /variable/MSVC12
+ /variable/MSVC14
+ /variable/MSVC60
+ /variable/MSVC70
+ /variable/MSVC71
+ /variable/MSVC80
+ /variable/MSVC90
+ /variable/MSVC_IDE
+ /variable/MSVC
+ /variable/MSVC_VERSION
+ /variable/UNIX
+ /variable/WIN32
+ /variable/WINCE
+ /variable/WINDOWS_PHONE
+ /variable/WINDOWS_STORE
+ /variable/XCODE_VERSION
+
+Variables that Control the Build
+================================
+
+.. toctree::
+ :maxdepth: 1
+
+ /variable/CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS
+ /variable/CMAKE_ANDROID_API
+ /variable/CMAKE_ANDROID_API_MIN
+ /variable/CMAKE_ANDROID_ARCH
+ /variable/CMAKE_ANDROID_ASSETS_DIRECTORIES
+ /variable/CMAKE_ANDROID_GUI
+ /variable/CMAKE_ANDROID_JAR_DEPENDENCIES
+ /variable/CMAKE_ANDROID_JAR_DIRECTORIES
+ /variable/CMAKE_ANDROID_JAVA_SOURCE_DIR
+ /variable/CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES
+ /variable/CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES
+ /variable/CMAKE_ANDROID_PROCESS_MAX
+ /variable/CMAKE_ANDROID_PROGUARD
+ /variable/CMAKE_ANDROID_PROGUARD_CONFIG_PATH
+ /variable/CMAKE_ANDROID_SECURE_PROPS_PATH
+ /variable/CMAKE_ANDROID_SKIP_ANT_STEP
+ /variable/CMAKE_ANDROID_STL_TYPE
+ /variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY
+ /variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CONFIG
+ /variable/CMAKE_AUTOMOC_MOC_OPTIONS
+ /variable/CMAKE_AUTOMOC
+ /variable/CMAKE_AUTORCC
+ /variable/CMAKE_AUTORCC_OPTIONS
+ /variable/CMAKE_AUTOUIC
+ /variable/CMAKE_AUTOUIC_OPTIONS
+ /variable/CMAKE_BUILD_WITH_INSTALL_RPATH
+ /variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY
+ /variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG
+ /variable/CMAKE_CONFIG_POSTFIX
+ /variable/CMAKE_DEBUG_POSTFIX
+ /variable/CMAKE_ENABLE_EXPORTS
+ /variable/CMAKE_EXE_LINKER_FLAGS_CONFIG
+ /variable/CMAKE_EXE_LINKER_FLAGS
+ /variable/CMAKE_Fortran_FORMAT
+ /variable/CMAKE_Fortran_MODULE_DIRECTORY
+ /variable/CMAKE_GNUtoMS
+ /variable/CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE
+ /variable/CMAKE_INCLUDE_CURRENT_DIR
+ /variable/CMAKE_INSTALL_NAME_DIR
+ /variable/CMAKE_INSTALL_RPATH
+ /variable/CMAKE_INSTALL_RPATH_USE_LINK_PATH
+ /variable/CMAKE_IOS_INSTALL_COMBINED
+ /variable/CMAKE_LANG_COMPILER_LAUNCHER
+ /variable/CMAKE_LANG_INCLUDE_WHAT_YOU_USE
+ /variable/CMAKE_LANG_VISIBILITY_PRESET
+ /variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY
+ /variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY_CONFIG
+ /variable/CMAKE_LIBRARY_PATH_FLAG
+ /variable/CMAKE_LINK_DEF_FILE_FLAG
+ /variable/CMAKE_LINK_DEPENDS_NO_SHARED
+ /variable/CMAKE_LINK_INTERFACE_LIBRARIES
+ /variable/CMAKE_LINK_LIBRARY_FILE_FLAG
+ /variable/CMAKE_LINK_LIBRARY_FLAG
+ /variable/CMAKE_MACOSX_BUNDLE
+ /variable/CMAKE_MACOSX_RPATH
+ /variable/CMAKE_MAP_IMPORTED_CONFIG_CONFIG
+ /variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG
+ /variable/CMAKE_MODULE_LINKER_FLAGS
+ /variable/CMAKE_NO_BUILTIN_CHRPATH
+ /variable/CMAKE_NO_SYSTEM_FROM_IMPORTED
+ /variable/CMAKE_OSX_ARCHITECTURES
+ /variable/CMAKE_OSX_DEPLOYMENT_TARGET
+ /variable/CMAKE_OSX_SYSROOT
+ /variable/CMAKE_PDB_OUTPUT_DIRECTORY
+ /variable/CMAKE_PDB_OUTPUT_DIRECTORY_CONFIG
+ /variable/CMAKE_POSITION_INDEPENDENT_CODE
+ /variable/CMAKE_RUNTIME_OUTPUT_DIRECTORY
+ /variable/CMAKE_RUNTIME_OUTPUT_DIRECTORY_CONFIG
+ /variable/CMAKE_SHARED_LINKER_FLAGS_CONFIG
+ /variable/CMAKE_SHARED_LINKER_FLAGS
+ /variable/CMAKE_SKIP_BUILD_RPATH
+ /variable/CMAKE_SKIP_INSTALL_RPATH
+ /variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG
+ /variable/CMAKE_STATIC_LINKER_FLAGS
+ /variable/CMAKE_TRY_COMPILE_CONFIGURATION
+ /variable/CMAKE_USE_RELATIVE_PATHS
+ /variable/CMAKE_VISIBILITY_INLINES_HIDDEN
+ /variable/CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD
+ /variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
+ /variable/CMAKE_WIN32_EXECUTABLE
+ /variable/CMAKE_XCODE_ATTRIBUTE_an-attribute
+ /variable/EXECUTABLE_OUTPUT_PATH
+ /variable/LIBRARY_OUTPUT_PATH
+
+Variables for Languages
+=======================
+
+.. toctree::
+ :maxdepth: 1
+
+ /variable/CMAKE_COMPILER_IS_GNULANG
+ /variable/CMAKE_C_COMPILE_FEATURES
+ /variable/CMAKE_C_EXTENSIONS
+ /variable/CMAKE_C_STANDARD
+ /variable/CMAKE_C_STANDARD_REQUIRED
+ /variable/CMAKE_CXX_COMPILE_FEATURES
+ /variable/CMAKE_CXX_EXTENSIONS
+ /variable/CMAKE_CXX_STANDARD
+ /variable/CMAKE_CXX_STANDARD_REQUIRED
+ /variable/CMAKE_Fortran_MODDIR_DEFAULT
+ /variable/CMAKE_Fortran_MODDIR_FLAG
+ /variable/CMAKE_Fortran_MODOUT_FLAG
+ /variable/CMAKE_INTERNAL_PLATFORM_ABI
+ /variable/CMAKE_LANG_ARCHIVE_APPEND
+ /variable/CMAKE_LANG_ARCHIVE_CREATE
+ /variable/CMAKE_LANG_ARCHIVE_FINISH
+ /variable/CMAKE_LANG_COMPILE_OBJECT
+ /variable/CMAKE_LANG_COMPILER_ABI
+ /variable/CMAKE_LANG_COMPILER_ID
+ /variable/CMAKE_LANG_COMPILER_LOADED
+ /variable/CMAKE_LANG_COMPILER
+ /variable/CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN
+ /variable/CMAKE_LANG_COMPILER_TARGET
+ /variable/CMAKE_LANG_COMPILER_VERSION
+ /variable/CMAKE_LANG_CREATE_SHARED_LIBRARY
+ /variable/CMAKE_LANG_CREATE_SHARED_MODULE
+ /variable/CMAKE_LANG_CREATE_STATIC_LIBRARY
+ /variable/CMAKE_LANG_FLAGS_DEBUG
+ /variable/CMAKE_LANG_FLAGS_MINSIZEREL
+ /variable/CMAKE_LANG_FLAGS_RELEASE
+ /variable/CMAKE_LANG_FLAGS_RELWITHDEBINFO
+ /variable/CMAKE_LANG_FLAGS
+ /variable/CMAKE_LANG_GHS_KERNEL_FLAGS_DEBUG
+ /variable/CMAKE_LANG_GHS_KERNEL_FLAGS_MINSIZEREL
+ /variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELEASE
+ /variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELWITHDEBINFO
+ /variable/CMAKE_LANG_IGNORE_EXTENSIONS
+ /variable/CMAKE_LANG_IMPLICIT_INCLUDE_DIRECTORIES
+ /variable/CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES
+ /variable/CMAKE_LANG_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES
+ /variable/CMAKE_LANG_IMPLICIT_LINK_LIBRARIES
+ /variable/CMAKE_LANG_LIBRARY_ARCHITECTURE
+ /variable/CMAKE_LANG_LINKER_PREFERENCE_PROPAGATES
+ /variable/CMAKE_LANG_LINKER_PREFERENCE
+ /variable/CMAKE_LANG_LINK_EXECUTABLE
+ /variable/CMAKE_LANG_OUTPUT_EXTENSION
+ /variable/CMAKE_LANG_PLATFORM_ID
+ /variable/CMAKE_LANG_SIMULATE_ID
+ /variable/CMAKE_LANG_SIMULATE_VERSION
+ /variable/CMAKE_LANG_SIZEOF_DATA_PTR
+ /variable/CMAKE_LANG_SOURCE_FILE_EXTENSIONS
+ /variable/CMAKE_USER_MAKE_RULES_OVERRIDE_LANG
+
+Variables for CTest
+===================
+
+.. toctree::
+ :maxdepth: 1
+
+ /variable/CTEST_BINARY_DIRECTORY
+ /variable/CTEST_BUILD_COMMAND
+ /variable/CTEST_BUILD_NAME
+ /variable/CTEST_BZR_COMMAND
+ /variable/CTEST_BZR_UPDATE_OPTIONS
+ /variable/CTEST_CHANGE_ID
+ /variable/CTEST_CHECKOUT_COMMAND
+ /variable/CTEST_CONFIGURATION_TYPE
+ /variable/CTEST_CONFIGURE_COMMAND
+ /variable/CTEST_COVERAGE_COMMAND
+ /variable/CTEST_COVERAGE_EXTRA_FLAGS
+ /variable/CTEST_CURL_OPTIONS
+ /variable/CTEST_CUSTOM_COVERAGE_EXCLUDE
+ /variable/CTEST_CUSTOM_ERROR_EXCEPTION
+ /variable/CTEST_CUSTOM_ERROR_MATCH
+ /variable/CTEST_CUSTOM_ERROR_POST_CONTEXT
+ /variable/CTEST_CUSTOM_ERROR_PRE_CONTEXT
+ /variable/CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE
+ /variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS
+ /variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS
+ /variable/CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE
+ /variable/CTEST_CUSTOM_MEMCHECK_IGNORE
+ /variable/CTEST_CUSTOM_POST_MEMCHECK
+ /variable/CTEST_CUSTOM_POST_TEST
+ /variable/CTEST_CUSTOM_PRE_MEMCHECK
+ /variable/CTEST_CUSTOM_PRE_TEST
+ /variable/CTEST_CUSTOM_TEST_IGNORE
+ /variable/CTEST_CUSTOM_WARNING_EXCEPTION
+ /variable/CTEST_CUSTOM_WARNING_MATCH
+ /variable/CTEST_CVS_CHECKOUT
+ /variable/CTEST_CVS_COMMAND
+ /variable/CTEST_CVS_UPDATE_OPTIONS
+ /variable/CTEST_DROP_LOCATION
+ /variable/CTEST_DROP_METHOD
+ /variable/CTEST_DROP_SITE
+ /variable/CTEST_DROP_SITE_CDASH
+ /variable/CTEST_DROP_SITE_PASSWORD
+ /variable/CTEST_DROP_SITE_USER
+ /variable/CTEST_EXTRA_COVERAGE_GLOB
+ /variable/CTEST_GIT_COMMAND
+ /variable/CTEST_GIT_UPDATE_CUSTOM
+ /variable/CTEST_GIT_UPDATE_OPTIONS
+ /variable/CTEST_HG_COMMAND
+ /variable/CTEST_HG_UPDATE_OPTIONS
+ /variable/CTEST_MEMORYCHECK_COMMAND
+ /variable/CTEST_MEMORYCHECK_COMMAND_OPTIONS
+ /variable/CTEST_MEMORYCHECK_SANITIZER_OPTIONS
+ /variable/CTEST_MEMORYCHECK_SUPPRESSIONS_FILE
+ /variable/CTEST_MEMORYCHECK_TYPE
+ /variable/CTEST_NIGHTLY_START_TIME
+ /variable/CTEST_P4_CLIENT
+ /variable/CTEST_P4_COMMAND
+ /variable/CTEST_P4_OPTIONS
+ /variable/CTEST_P4_UPDATE_OPTIONS
+ /variable/CTEST_SCP_COMMAND
+ /variable/CTEST_SITE
+ /variable/CTEST_SOURCE_DIRECTORY
+ /variable/CTEST_SVN_COMMAND
+ /variable/CTEST_SVN_OPTIONS
+ /variable/CTEST_SVN_UPDATE_OPTIONS
+ /variable/CTEST_TEST_LOAD
+ /variable/CTEST_TEST_TIMEOUT
+ /variable/CTEST_TRIGGER_SITE
+ /variable/CTEST_UPDATE_COMMAND
+ /variable/CTEST_UPDATE_OPTIONS
+ /variable/CTEST_UPDATE_VERSION_ONLY
+ /variable/CTEST_USE_LAUNCHERS
+
+Variables for CPack
+===================
+
+.. toctree::
+ :maxdepth: 1
+
+ /variable/CPACK_ABSOLUTE_DESTINATION_FILES
+ /variable/CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY
+ /variable/CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION
+ /variable/CPACK_INCLUDE_TOPLEVEL_DIRECTORY
+ /variable/CPACK_INSTALL_SCRIPT
+ /variable/CPACK_PACKAGING_INSTALL_PREFIX
+ /variable/CPACK_SET_DESTDIR
+ /variable/CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst
new file mode 100644
index 000000000..92f52302c
--- /dev/null
+++ b/Help/manual/cmake.1.rst
@@ -0,0 +1,280 @@
+.. cmake-manual-description: CMake Command-Line Reference
+
+cmake(1)
+********
+
+Synopsis
+========
+
+.. parsed-literal::
+
+ cmake [<options>] (<path-to-source> | <path-to-existing-build>)
+ cmake [(-D <var>=<value>)...] -P <cmake-script-file>
+ cmake --build <dir> [<options>] [-- <build-tool-options>...]
+ cmake -E <command> [<options>...]
+ cmake --find-package <options>...
+
+Description
+===========
+
+The "cmake" executable is the CMake command-line interface. It may be
+used to configure projects in scripts. Project configuration settings
+may be specified on the command line with the -D option.
+
+CMake is a cross-platform build system generator. Projects specify
+their build process with platform-independent CMake listfiles included
+in each directory of a source tree with the name CMakeLists.txt.
+Users build a project by using CMake to generate a build system for a
+native tool on their platform.
+
+.. _`CMake Options`:
+
+Options
+=======
+
+.. include:: OPTIONS_BUILD.txt
+
+``-E <command> [<options>...]``
+ See `Command-Line Tool Mode`_.
+
+``-L[A][H]``
+ List non-advanced cached variables.
+
+ List cache variables will run CMake and list all the variables from
+ the CMake cache that are not marked as INTERNAL or ADVANCED. This
+ will effectively display current CMake settings, which can then be
+ changed with -D option. Changing some of the variables may result
+ in more variables being created. If A is specified, then it will
+ display also advanced variables. If H is specified, it will also
+ display help for each variable.
+
+``--build <dir>``
+ Build a CMake-generated project binary tree.
+
+ This abstracts a native build tool's command-line interface with the
+ following options:
+
+ ::
+
+ <dir> = Project binary directory to be built.
+ --target <tgt> = Build <tgt> instead of default targets.
+ --config <cfg> = For multi-configuration tools, choose <cfg>.
+ --clean-first = Build target 'clean' first, then build.
+ (To clean only, use --target 'clean'.)
+ --use-stderr = Ignored. Behavior is default in CMake >= 3.0.
+ -- = Pass remaining options to the native tool.
+
+ Run cmake --build with no options for quick help.
+
+``-N``
+ View mode only.
+
+ Only load the cache. Do not actually run configure and generate
+ steps.
+
+``-P <file>``
+ Process script mode.
+
+ Process the given cmake file as a script written in the CMake
+ language. No configure or generate step is performed and the cache
+ is not modified. If variables are defined using -D, this must be
+ done before the -P argument.
+
+``--find-package``
+ Run in pkg-config like mode.
+
+ Search a package using find_package() and print the resulting flags
+ to stdout. This can be used to use cmake instead of pkg-config to
+ find installed libraries in plain Makefile-based projects or in
+ autoconf-based projects (via share/aclocal/cmake.m4).
+
+``--graphviz=[file]``
+ Generate graphviz of dependencies, see CMakeGraphVizOptions.cmake for more.
+
+ Generate a graphviz input file that will contain all the library and
+ executable dependencies in the project. See the documentation for
+ CMakeGraphVizOptions.cmake for more details.
+
+``--system-information [file]``
+ Dump information about this system.
+
+ Dump a wide range of information about the current system. If run
+ from the top of a binary tree for a CMake project it will dump
+ additional information such as the cache, log files etc.
+
+``--debug-trycompile``
+ Do not delete the try_compile build tree. Only useful on one try_compile at a time.
+
+ Do not delete the files and directories created for try_compile
+ calls. This is useful in debugging failed try_compiles. It may
+ however change the results of the try-compiles as old junk from a
+ previous try-compile may cause a different test to either pass or
+ fail incorrectly. This option is best used for one try-compile at a
+ time, and only when debugging.
+
+``--debug-output``
+ Put cmake in a debug mode.
+
+ Print extra information during the cmake run like stack traces with
+ message(send_error ) calls.
+
+``--trace``
+ Put cmake in trace mode.
+
+ Print a trace of all calls made and from where.
+
+``--trace-expand``
+ Put cmake in trace mode.
+
+ Like ``--trace``, but with variables expanded.
+
+``--warn-uninitialized``
+ Warn about uninitialized values.
+
+ Print a warning when an uninitialized variable is used.
+
+``--warn-unused-vars``
+ Warn about unused variables.
+
+ Find variables that are declared or set, but not used.
+
+``--no-warn-unused-cli``
+ Don't warn about command line options.
+
+ Don't find variables that are declared on the command line, but not
+ used.
+
+``--check-system-vars``
+ Find problems with variable usage in system files.
+
+ Normally, unused and uninitialized variables are searched for only
+ in CMAKE_SOURCE_DIR and CMAKE_BINARY_DIR. This flag tells CMake to
+ warn about other files as well.
+
+.. include:: OPTIONS_HELP.txt
+
+Command-Line Tool Mode
+======================
+
+CMake provides builtin command-line tools through the signature::
+
+ cmake -E <command> [<options>...]
+
+Run ``cmake -E`` or ``cmake -E help`` for a summary of commands.
+Available commands are:
+
+``chdir <dir> <cmd> [<arg>...]``
+ Change the current working directory and run a command.
+
+``compare_files <file1> <file2>``
+ Check if ``<file1>`` is same as ``<file2>``. If files are the same,
+ then returns 0, if not itreturns 1.
+
+``copy <file>... <destination>``
+ Copy files to ``<destination>`` (either file or directory).
+ If multiple files are specified, the ``<destination>`` must be
+ directory and it must exist.
+
+``copy_directory <dir>... <destination>``
+ Copy directories to ``<destination>`` directory.
+ If ``<destination>`` directory does not exist it will be created.
+
+``copy_if_different <file>... <destination>``
+ Copy files to ``<destination>`` (either file or directory) if
+ they have changed.
+ If multiple files are specified, the ``<destination>`` must be
+ directory and it must exist.
+
+``echo [<string>...]``
+ Displays arguments as text.
+
+``echo_append [<string>...]``
+ Displays arguments as text but no new line.
+
+``env [--unset=NAME]... [NAME=VALUE]... COMMAND [ARG]...``
+ Run command in a modified environment.
+
+``environment``
+ Display the current environment variables.
+
+``make_directory <dir>...``
+ Create ``<dir>`` directories. If necessary, create parent
+ directories too. If a directory already exists it will be
+ silently ignored.
+
+``md5sum <file>...``
+ Compute md5sum of files.
+
+``remove [-f] <file>...``
+ Remove the file(s), use ``-f`` to force it. If a file does
+ not exist it will be silently ignored.
+
+``remove_directory <dir>``
+ Remove a directory and its contents. If a directory does
+ not exist it will be silently ignored.
+
+``rename <oldname> <newname>``
+ Rename a file or directory (on one volume).
+
+``sleep <number>...``
+ Sleep for given number of seconds.
+
+``tar [cxt][vf][zjJ] file.tar [<options>...] [--] [<file>...]``
+ Create or extract a tar or zip archive. Options are:
+
+ ``--``
+ Stop interpreting options and treat all remaining arguments
+ as file names even if they start in ``-``.
+ ``--files-from=<file>``
+ Read file names from the given file, one per line.
+ Blank lines are ignored. Lines may not start in ``-``
+ except for ``--add-file=<name>`` to add files whose
+ names start in ``-``.
+ ``--mtime=<date>``
+ Specify modification time recorded in tarball entries.
+ ``--format=<format>``
+ Specify the format of the archive to be created.
+ Supported formats are: ``7zip``, ``gnutar``, ``pax``,
+ ``paxr`` (restricted pax, default), and ``zip``.
+
+``time <command> [<args>...]``
+ Run command and return elapsed time.
+
+``touch <file>``
+ Touch a file.
+
+``touch_nocreate <file>``
+ Touch a file if it exists but do not create it. If a file does
+ not exist it will be silently ignored.
+
+UNIX-specific Command-Line Tools
+--------------------------------
+
+The following ``cmake -E`` commands are available only on UNIX:
+
+``create_symlink <old> <new>``
+ Create a symbolic link ``<new>`` naming ``<old>``.
+
+Windows-specific Command-Line Tools
+-----------------------------------
+
+The following ``cmake -E`` commands are available only on Windows:
+
+``delete_regv <key>``
+ Delete Windows registry value.
+
+``env_vs8_wince <sdkname>``
+ Displays a batch file which sets the environment for the provided
+ Windows CE SDK installed in VS2005.
+
+``env_vs9_wince <sdkname>``
+ Displays a batch file which sets the environment for the provided
+ Windows CE SDK installed in VS2008.
+
+``write_regv <key> <value>``
+ Write Windows registry value.
+
+See Also
+========
+
+.. include:: LINKS.txt
diff --git a/Help/manual/cpack.1.rst b/Help/manual/cpack.1.rst
new file mode 100644
index 000000000..ba2086e98
--- /dev/null
+++ b/Help/manual/cpack.1.rst
@@ -0,0 +1,97 @@
+.. cmake-manual-description: CPack Command-Line Reference
+
+cpack(1)
+********
+
+Synopsis
+========
+
+.. parsed-literal::
+
+ cpack -G <generator> [<options>]
+
+Description
+===========
+
+The "cpack" executable is the CMake packaging program.
+CMake-generated build trees created for projects that use the
+INSTALL_* commands have packaging support. This program will generate
+the package.
+
+CMake is a cross-platform build system generator. Projects specify
+their build process with platform-independent CMake listfiles included
+in each directory of a source tree with the name CMakeLists.txt.
+Users build a project by using CMake to generate a build system for a
+native tool on their platform.
+
+Options
+=======
+
+``-G <generator>``
+ Use the specified generator to generate package.
+
+ CPack may support multiple native packaging systems on certain
+ platforms. A generator is responsible for generating input files
+ for particular system and invoking that systems. Possible generator
+ names are specified in the Generators section.
+
+``-C <Configuration>``
+ Specify the project configuration
+
+ This option specifies the configuration that the project was build
+ with, for example 'Debug', 'Release'.
+
+``-D <var>=<value>``
+ Set a CPack variable.
+
+ Set a variable that can be used by the generator.
+
+``--config <config file>``
+ Specify the config file.
+
+ Specify the config file to use to create the package. By default
+ CPackConfig.cmake in the current directory will be used.
+
+``--verbose,-V``
+ enable verbose output
+
+ Run cpack with verbose output.
+
+``--debug``
+ enable debug output (for CPack developers)
+
+ Run cpack with debug output (for CPack developers).
+
+``-P <package name>``
+ override/define CPACK_PACKAGE_NAME
+
+ If the package name is not specified on cpack commmand line
+ thenCPack.cmake defines it as CMAKE_PROJECT_NAME
+
+``-R <package version>``
+ override/define CPACK_PACKAGE_VERSION
+
+ If version is not specified on cpack command line thenCPack.cmake
+ defines it from CPACK_PACKAGE_VERSION_[MAJOR|MINOR|PATCH]look into
+ CPack.cmake for detail
+
+``-B <package directory>``
+ override/define CPACK_PACKAGE_DIRECTORY
+
+ The directory where CPack will be doing its packaging work.The
+ resulting package will be found there. Inside this directoryCPack
+ creates '_CPack_Packages' sub-directory which is theCPack temporary
+ directory.
+
+``--vendor <vendor name>``
+ override/define CPACK_PACKAGE_VENDOR
+
+ If vendor is not specified on cpack command line (or inside
+ CMakeLists.txt) thenCPack.cmake defines it with a default value
+
+.. include:: OPTIONS_HELP.txt
+
+See Also
+========
+
+.. include:: LINKS.txt
diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst
new file mode 100644
index 000000000..2fdf7f329
--- /dev/null
+++ b/Help/manual/ctest.1.rst
@@ -0,0 +1,1023 @@
+.. cmake-manual-description: CTest Command-Line Reference
+
+ctest(1)
+********
+
+Synopsis
+========
+
+.. parsed-literal::
+
+ ctest [<options>]
+
+Description
+===========
+
+The "ctest" executable is the CMake test driver program.
+CMake-generated build trees created for projects that use the
+ENABLE_TESTING and ADD_TEST commands have testing support. This
+program will run the tests and report results.
+
+Options
+=======
+
+``-C <cfg>, --build-config <cfg>``
+ Choose configuration to test.
+
+ Some CMake-generated build trees can have multiple build
+ configurations in the same tree. This option can be used to specify
+ which one should be tested. Example configurations are "Debug" and
+ "Release".
+
+``-V,--verbose``
+ Enable verbose output from tests.
+
+ Test output is normally suppressed and only summary information is
+ displayed. This option will show all test output.
+
+``-VV,--extra-verbose``
+ Enable more verbose output from tests.
+
+ Test output is normally suppressed and only summary information is
+ displayed. This option will show even more test output.
+
+``--debug``
+ Displaying more verbose internals of CTest.
+
+ This feature will result in a large number of output that is mostly
+ useful for debugging dashboard problems.
+
+``--output-on-failure``
+ Output anything outputted by the test program if the test should fail.
+ This option can also be enabled by setting the environment variable
+ ``CTEST_OUTPUT_ON_FAILURE``.
+
+``-F``
+ Enable failover.
+
+ This option allows ctest to resume a test set execution that was
+ previously interrupted. If no interruption occurred, the -F option
+ will have no effect.
+
+``-j <jobs>, --parallel <jobs>``
+ Run the tests in parallel using the given number of jobs.
+
+ This option tells ctest to run the tests in parallel using given
+ number of jobs. This option can also be set by setting the
+ environment variable ``CTEST_PARALLEL_LEVEL``.
+
+``--test-load <level>``
+ While running tests in parallel (e.g. with ``-j``), try not to start
+ tests when they may cause the CPU load to pass above a given threshold.
+
+ When ``ctest`` is run as a `Dashboard Client`_ this sets the
+ ``TestLoad`` option of the `CTest Test Step`_.
+
+``-Q,--quiet``
+ Make ctest quiet.
+
+ This option will suppress all the output. The output log file will
+ still be generated if the --output-log is specified. Options such
+ as --verbose, --extra-verbose, and --debug are ignored if --quiet is
+ specified.
+
+``-O <file>, --output-log <file>``
+ Output to log file
+
+ This option tells ctest to write all its output to a log file.
+
+``-N,--show-only``
+ Disable actual execution of tests.
+
+ This option tells ctest to list the tests that would be run but not
+ actually run them. Useful in conjunction with the -R and -E
+ options.
+
+``-L <regex>, --label-regex <regex>``
+ Run tests with labels matching regular expression.
+
+ This option tells ctest to run only the tests whose labels match the
+ given regular expression.
+
+``-R <regex>, --tests-regex <regex>``
+ Run tests matching regular expression.
+
+ This option tells ctest to run only the tests whose names match the
+ given regular expression.
+
+``-E <regex>, --exclude-regex <regex>``
+ Exclude tests matching regular expression.
+
+ This option tells ctest to NOT run the tests whose names match the
+ given regular expression.
+
+``-LE <regex>, --label-exclude <regex>``
+ Exclude tests with labels matching regular expression.
+
+ This option tells ctest to NOT run the tests whose labels match the
+ given regular expression.
+
+``-D <dashboard>, --dashboard <dashboard>``
+ Execute dashboard test
+
+ This option tells ctest to act as a CDash client and perform a
+ dashboard test. All tests are <Mode><Test>, where Mode can be
+ Experimental, Nightly, and Continuous, and Test can be Start,
+ Update, Configure, Build, Test, Coverage, and Submit.
+
+``-D <var>:<type>=<value>``
+ Define a variable for script mode
+
+ Pass in variable values on the command line. Use in conjunction
+ with -S to pass variable values to a dashboard script. Parsing -D
+ arguments as variable values is only attempted if the value
+ following -D does not match any of the known dashboard types.
+
+``-M <model>, --test-model <model>``
+ Sets the model for a dashboard
+
+ This option tells ctest to act as a CDash client where the TestModel
+ can be Experimental, Nightly, and Continuous. Combining -M and -T
+ is similar to -D
+
+``-T <action>, --test-action <action>``
+ Sets the dashboard action to perform
+
+ This option tells ctest to act as a CDash client and perform some
+ action such as start, build, test etc. Combining -M and -T is
+ similar to -D
+
+``--track <track>``
+ Specify the track to submit dashboard to
+
+ Submit dashboard to specified track instead of default one. By
+ default, the dashboard is submitted to Nightly, Experimental, or
+ Continuous track, but by specifying this option, the track can be
+ arbitrary.
+
+``-S <script>, --script <script>``
+ Execute a dashboard for a configuration
+
+ This option tells ctest to load in a configuration script which sets
+ a number of parameters such as the binary and source directories.
+ Then ctest will do what is required to create and run a dashboard.
+ This option basically sets up a dashboard and then runs ctest -D
+ with the appropriate options.
+
+``-SP <script>, --script-new-process <script>``
+ Execute a dashboard for a configuration
+
+ This option does the same operations as -S but it will do them in a
+ separate process. This is primarily useful in cases where the
+ script may modify the environment and you do not want the modified
+ environment to impact other -S scripts.
+
+``-A <file>, --add-notes <file>``
+ Add a notes file with submission
+
+ This option tells ctest to include a notes file when submitting
+ dashboard.
+
+``-I [Start,End,Stride,test#,test#|Test file], --tests-information``
+ Run a specific number of tests by number.
+
+ This option causes ctest to run tests starting at number Start,
+ ending at number End, and incrementing by Stride. Any additional
+ numbers after Stride are considered individual test numbers. Start,
+ End,or stride can be empty. Optionally a file can be given that
+ contains the same syntax as the command line.
+
+``-U, --union``
+ Take the Union of -I and -R
+
+ When both -R and -I are specified by default the intersection of
+ tests are run. By specifying -U the union of tests is run instead.
+
+``--rerun-failed``
+ Run only the tests that failed previously
+
+ This option tells ctest to perform only the tests that failed during
+ its previous run. When this option is specified, ctest ignores all
+ other options intended to modify the list of tests to run (-L, -R,
+ -E, -LE, -I, etc). In the event that CTest runs and no tests fail,
+ subsequent calls to ctest with the --rerun-failed option will run
+ the set of tests that most recently failed (if any).
+
+``--repeat-until-fail <n>``
+ Require each test to run ``<n>`` times without failing in order to pass.
+
+ This is useful in finding sporadic failures in test cases.
+
+``--max-width <width>``
+ Set the max width for a test name to output
+
+ Set the maximum width for each test name to show in the output.
+ This allows the user to widen the output to avoid clipping the test
+ name which can be very annoying.
+
+``--interactive-debug-mode [0|1]``
+ Set the interactive mode to 0 or 1.
+
+ This option causes ctest to run tests in either an interactive mode
+ or a non-interactive mode. On Windows this means that in
+ non-interactive mode, all system debug pop up windows are blocked.
+ In dashboard mode (Experimental, Nightly, Continuous), the default
+ is non-interactive. When just running tests not for a dashboard the
+ default is to allow popups and interactive debugging.
+
+``--no-label-summary``
+ Disable timing summary information for labels.
+
+ This option tells ctest not to print summary information for each
+ label associated with the tests run. If there are no labels on the
+ tests, nothing extra is printed.
+
+``--build-and-test``
+ Configure, build and run a test.
+
+ This option tells ctest to configure (i.e. run cmake on), build,
+ and or execute a test. The configure and test steps are optional.
+ The arguments to this command line are the source and binary
+ directories. By default this will run CMake on the Source/Bin
+ directories specified unless --build-nocmake is specified.
+ The --build-generator option *must* be provided to use
+ --build-and-test. If --test-command is specified then that will be
+ run after the build is complete. Other options that affect this
+ mode are --build-target --build-nocmake, --build-run-dir,
+ --build-two-config, --build-exe-dir,
+ --build-project,--build-noclean, --build-options
+
+``--build-target``
+ Specify a specific target to build.
+
+ This option goes with the --build-and-test option, if left out the
+ all target is built.
+
+``--build-nocmake``
+ Run the build without running cmake first.
+
+ Skip the cmake step.
+
+``--build-run-dir``
+ Specify directory to run programs from.
+
+ Directory where programs will be after it has been compiled.
+
+``--build-two-config``
+ Run CMake twice
+
+``--build-exe-dir``
+ Specify the directory for the executable.
+
+``--build-generator``
+ Specify the generator to use.
+
+``--build-generator-platform``
+ Specify the generator-specific platform.
+
+``--build-generator-toolset``
+ Specify the generator-specific toolset.
+
+``--build-project``
+ Specify the name of the project to build.
+
+``--build-makeprogram``
+ Override the make program chosen by CTest with a given one.
+
+``--build-noclean``
+ Skip the make clean step.
+
+``--build-config-sample``
+ A sample executable to use to determine the configuration
+
+ A sample executable to use to determine the configuration that
+ should be used. e.g. Debug/Release/etc
+
+``--build-options``
+ Add extra options to the build step.
+
+ This option must be the last option with the exception of
+ --test-command
+
+``--test-command``
+ The test to run with the --build-and-test option.
+
+``--test-output-size-passed <size>``
+ Limit the output for passed tests to <size> bytes.
+
+``--test-output-size-failed <size>``
+ Limit the output for failed tests to <size> bytes.
+
+``--test-timeout``
+ The time limit in seconds, internal use only.
+
+``--tomorrow-tag``
+ Nightly or experimental starts with next day tag.
+
+ This is useful if the build will not finish in one day.
+
+``--ctest-config``
+ The configuration file used to initialize CTest state when submitting dashboards.
+
+ This option tells CTest to use different initialization file instead
+ of CTestConfiguration.tcl. This way multiple initialization files
+ can be used for example to submit to multiple dashboards.
+
+``--overwrite``
+ Overwrite CTest configuration option.
+
+ By default ctest uses configuration options from configuration file.
+ This option will overwrite the configuration option.
+
+``--extra-submit <file>[;<file>]``
+ Submit extra files to the dashboard.
+
+ This option will submit extra files to the dashboard.
+
+``--force-new-ctest-process``
+ Run child CTest instances as new processes
+
+ By default CTest will run child CTest instances within the same
+ process. If this behavior is not desired, this argument will
+ enforce new processes for child CTest processes.
+
+``--schedule-random``
+ Use a random order for scheduling tests
+
+ This option will run the tests in a random order. It is commonly
+ used to detect implicit dependencies in a test suite.
+
+``--submit-index``
+ Legacy option for old Dart2 dashboard server feature.
+ Do not use.
+
+``--timeout <seconds>``
+ Set a global timeout on all tests.
+
+ This option will set a global timeout on all tests that do not
+ already have a timeout set on them.
+
+``--stop-time <time>``
+ Set a time at which all tests should stop running.
+
+ Set a real time of day at which all tests should timeout. Example:
+ 7:00:00 -0400. Any time format understood by the curl date parser
+ is accepted. Local time is assumed if no timezone is specified.
+
+``--http1.0``
+ Submit using HTTP 1.0.
+
+ This option will force CTest to use HTTP 1.0 to submit files to the
+ dashboard, instead of HTTP 1.1.
+
+``--no-compress-output``
+ Do not compress test output when submitting.
+
+ This flag will turn off automatic compression of test output. Use
+ this to maintain compatibility with an older version of CDash which
+ doesn't support compressed test output.
+
+``--print-labels``
+ Print all available test labels.
+
+ This option will not run any tests, it will simply print the list of
+ all labels associated with the test set.
+
+.. include:: OPTIONS_HELP.txt
+
+.. _`Dashboard Client`:
+
+Dashboard Client
+================
+
+CTest can operate as a client for the `CDash`_ software quality dashboard
+application. As a dashboard client, CTest performs a sequence of steps
+to configure, build, and test software, and then submits the results to
+a `CDash`_ server.
+
+.. _`CDash`: http://cdash.org/
+
+Dashboard Client Steps
+----------------------
+
+CTest defines an ordered list of testing steps of which some or all may
+be run as a dashboard client:
+
+``Start``
+ Start a new dashboard submission to be composed of results recorded
+ by the following steps.
+ See the `CTest Start Step`_ section below.
+
+``Update``
+ Update the source tree from its version control repository.
+ Record the old and new versions and the list of updated source files.
+ See the `CTest Update Step`_ section below.
+
+``Configure``
+ Configure the software by running a command in the build tree.
+ Record the configuration output log.
+ See the `CTest Configure Step`_ section below.
+
+``Build``
+ Build the software by running a command in the build tree.
+ Record the build output log and detect warnings and errors.
+ See the `CTest Build Step`_ section below.
+
+``Test``
+ Test the software by loading a ``CTestTestfile.cmake``
+ from the build tree and executing the defined tests.
+ Record the output and result of each test.
+ See the `CTest Test Step`_ section below.
+
+``Coverage``
+ Compute coverage of the source code by running a coverage
+ analysis tool and recording its output.
+ See the `CTest Coverage Step`_ section below.
+
+``MemCheck``
+ Run the software test suite through a memory check tool.
+ Record the test output, results, and issues reported by the tool.
+ See the `CTest MemCheck Step`_ section below.
+
+``Submit``
+ Submit results recorded from other testing steps to the
+ software quality dashboard server.
+ See the `CTest Submit Step`_ section below.
+
+Dashboard Client Modes
+----------------------
+
+CTest defines three modes of operation as a dashboard client:
+
+``Nightly``
+ This mode is intended to be invoked once per day, typically at night.
+ It enables the ``Start``, ``Update``, ``Configure``, ``Build``, ``Test``,
+ ``Coverage``, and ``Submit`` steps by default. Selected steps run even
+ if the ``Update`` step reports no changes to the source tree.
+
+``Continuous``
+ This mode is intended to be invoked repeatedly throughout the day.
+ It enables the ``Start``, ``Update``, ``Configure``, ``Build``, ``Test``,
+ ``Coverage``, and ``Submit`` steps by default, but exits after the
+ ``Update`` step if it reports no changes to the source tree.
+
+``Experimental``
+ This mode is intended to be invoked by a developer to test local changes.
+ It enables the ``Start``, ``Configure``, ``Build``, ``Test``, ``Coverage``,
+ and ``Submit`` steps by default.
+
+Dashboard Client via CTest Command-Line
+---------------------------------------
+
+CTest can perform testing on an already-generated build tree.
+Run the ``ctest`` command with the current working directory set
+to the build tree and use one of these signatures::
+
+ ctest -D <mode>[<step>]
+ ctest -M <mode> [ -T <step> ]...
+
+The ``<mode>`` must be one of the above `Dashboard Client Modes`_,
+and each ``<step>`` must be one of the above `Dashboard Client Steps`_.
+
+CTest reads the `Dashboard Client Configuration`_ settings from
+a file in the build tree called either ``CTestConfiguration.ini``
+or ``DartConfiguration.tcl`` (the names are historical). The format
+of the file is::
+
+ # Lines starting in '#' are comments.
+ # Other non-blank lines are key-value pairs.
+ <setting>: <value>
+
+where ``<setting>`` is the setting name and ``<value>`` is the
+setting value.
+
+In build trees generated by CMake, this configuration file is
+generated by the :module:`CTest` module if included by the project.
+The module uses variables to obtain a value for each setting
+as documented with the settings below.
+
+.. _`CTest Script`:
+
+Dashboard Client via CTest Script
+---------------------------------
+
+CTest can perform testing driven by a :manual:`cmake-language(7)`
+script that creates and maintains the source and build tree as
+well as performing the testing steps. Run the ``ctest`` command
+with the current working directory set outside of any build tree
+and use one of these signatures::
+
+ ctest -S <script>
+ ctest -SP <script>
+
+The ``<script>`` file must call :ref:`CTest Commands` commands
+to run testing steps explicitly as documented below. The commands
+obtain `Dashboard Client Configuration`_ settings from their
+arguments or from variables set in the script.
+
+Dashboard Client Configuration
+==============================
+
+The `Dashboard Client Steps`_ may be configured by named
+settings as documented in the following sections.
+
+.. _`CTest Start Step`:
+
+CTest Start Step
+----------------
+
+Start a new dashboard submission to be composed of results recorded
+by the following steps.
+
+In a `CTest Script`_, the :command:`ctest_start` command runs this step.
+Arguments to the command may specify some of the step settings.
+The command first runs the command-line specified by the
+``CTEST_CHECKOUT_COMMAND`` variable, if set, to initialize the source
+directory.
+
+Configuration settings include:
+
+``BuildDirectory``
+ The full path to the project build tree.
+
+ * `CTest Script`_ variable: :variable:`CTEST_BINARY_DIRECTORY`
+ * :module:`CTest` module variable: :variable:`PROJECT_BINARY_DIR`
+
+``SourceDirectory``
+ The full path to the project source tree.
+
+ * `CTest Script`_ variable: :variable:`CTEST_SOURCE_DIRECTORY`
+ * :module:`CTest` module variable: :variable:`PROJECT_SOURCE_DIR`
+
+.. _`CTest Update Step`:
+
+CTest Update Step
+-----------------
+
+In a `CTest Script`_, the :command:`ctest_update` command runs this step.
+Arguments to the command may specify some of the step settings.
+
+Configuration settings to specify the version control tool include:
+
+``BZRCommand``
+ ``bzr`` command-line tool to use if source tree is managed by Bazaar.
+
+ * `CTest Script`_ variable: :variable:`CTEST_BZR_COMMAND`
+ * :module:`CTest` module variable: none
+
+``BZRUpdateOptions``
+ Command-line options to the ``BZRCommand`` when updating the source.
+
+ * `CTest Script`_ variable: :variable:`CTEST_BZR_UPDATE_OPTIONS`
+ * :module:`CTest` module variable: none
+
+``CVSCommand``
+ ``cvs`` command-line tool to use if source tree is managed by CVS.
+
+ * `CTest Script`_ variable: :variable:`CTEST_CVS_COMMAND`
+ * :module:`CTest` module variable: ``CVSCOMMAND``
+
+``CVSUpdateOptions``
+ Command-line options to the ``CVSCommand`` when updating the source.
+
+ * `CTest Script`_ variable: :variable:`CTEST_CVS_UPDATE_OPTIONS`
+ * :module:`CTest` module variable: ``CVS_UPDATE_OPTIONS``
+
+``GITCommand``
+ ``git`` command-line tool to use if source tree is managed by Git.
+
+ * `CTest Script`_ variable: :variable:`CTEST_GIT_COMMAND`
+ * :module:`CTest` module variable: ``GITCOMMAND``
+
+``GITUpdateCustom``
+ Specify a custom command line (as a semicolon-separated list) to run
+ in the source tree (Git work tree) to update it instead of running
+ the ``GITCommand``.
+
+ * `CTest Script`_ variable: :variable:`CTEST_GIT_UPDATE_CUSTOM`
+ * :module:`CTest` module variable: ``CTEST_GIT_UPDATE_CUSTOM``
+
+``GITUpdateOptions``
+ Command-line options to the ``GITCommand`` when updating the source.
+
+ * `CTest Script`_ variable: :variable:`CTEST_GIT_UPDATE_OPTIONS`
+ * :module:`CTest` module variable: ``GIT_UPDATE_OPTIONS``
+
+``HGCommand``
+ ``hg`` command-line tool to use if source tree is managed by Mercurial.
+
+ * `CTest Script`_ variable: :variable:`CTEST_HG_COMMAND`
+ * :module:`CTest` module variable: none
+
+``HGUpdateOptions``
+ Command-line options to the ``HGCommand`` when updating the source.
+
+ * `CTest Script`_ variable: :variable:`CTEST_HG_UPDATE_OPTIONS`
+ * :module:`CTest` module variable: none
+
+``P4Client``
+ Value of the ``-c`` option to the ``P4Command``.
+
+ * `CTest Script`_ variable: :variable:`CTEST_P4_CLIENT`
+ * :module:`CTest` module variable: ``CTEST_P4_CLIENT``
+
+``P4Command``
+ ``p4`` command-line tool to use if source tree is managed by Perforce.
+
+ * `CTest Script`_ variable: :variable:`CTEST_P4_COMMAND`
+ * :module:`CTest` module variable: ``P4COMMAND``
+
+``P4Options``
+ Command-line options to the ``P4Command`` for all invocations.
+
+ * `CTest Script`_ variable: :variable:`CTEST_P4_OPTIONS`
+ * :module:`CTest` module variable: ``CTEST_P4_OPTIONS``
+
+``P4UpdateCustom``
+ Specify a custom command line (as a semicolon-separated list) to run
+ in the source tree (Perforce tree) to update it instead of running
+ the ``P4Command``.
+
+ * `CTest Script`_ variable: none
+ * :module:`CTest` module variable: ``CTEST_P4_UPDATE_CUSTOM``
+
+``P4UpdateOptions``
+ Command-line options to the ``P4Command`` when updating the source.
+
+ * `CTest Script`_ variable: :variable:`CTEST_P4_UPDATE_OPTIONS`
+ * :module:`CTest` module variable: ``CTEST_P4_UPDATE_OPTIONS``
+
+``SVNCommand``
+ ``svn`` command-line tool to use if source tree is managed by Subversion.
+
+ * `CTest Script`_ variable: :variable:`CTEST_SVN_COMMAND`
+ * :module:`CTest` module variable: ``SVNCOMMAND``
+
+``SVNOptions``
+ Command-line options to the ``SVNCommand`` for all invocations.
+
+ * `CTest Script`_ variable: :variable:`CTEST_SVN_OPTIONS`
+ * :module:`CTest` module variable: ``CTEST_SVN_OPTIONS``
+
+``SVNUpdateOptions``
+ Command-line options to the ``SVNCommand`` when updating the source.
+
+ * `CTest Script`_ variable: :variable:`CTEST_SVN_UPDATE_OPTIONS`
+ * :module:`CTest` module variable: ``SVN_UPDATE_OPTIONS``
+
+``UpdateCommand``
+ Specify the version-control command-line tool to use without
+ detecting the VCS that manages the source tree.
+
+ * `CTest Script`_ variable: :variable:`CTEST_UPDATE_COMMAND`
+ * :module:`CTest` module variable: ``<VCS>COMMAND``
+ when ``UPDATE_TYPE`` is ``<vcs>``, else ``UPDATE_COMMAND``
+
+``UpdateOptions``
+ Command-line options to the ``UpdateCommand``.
+
+ * `CTest Script`_ variable: :variable:`CTEST_UPDATE_OPTIONS`
+ * :module:`CTest` module variable: ``<VCS>_UPDATE_OPTIONS``
+ when ``UPDATE_TYPE`` is ``<vcs>``, else ``UPDATE_OPTIONS``
+
+``UpdateType``
+ Specify the version-control system that manages the source
+ tree if it cannot be detected automatically.
+ The value may be ``bzr``, ``cvs``, ``git``, ``hg``,
+ ``p4``, or ``svn``.
+
+ * `CTest Script`_ variable: none, detected from source tree
+ * :module:`CTest` module variable: ``UPDATE_TYPE`` if set,
+ else ``CTEST_UPDATE_TYPE``
+
+``UpdateVersionOnly``
+ Specify that you want the version control update command to only
+ discover the current version that is checked out, and not to update
+ to a different version.
+
+ * `CTest Script`_ variable: :variable:`CTEST_UPDATE_VERSION_ONLY`
+
+
+
+Additional configuration settings include:
+
+``NightlyStartTime``
+ In the ``Nightly`` dashboard mode, specify the "nightly start time".
+ With centralized version control systems (``cvs`` and ``svn``),
+ the ``Update`` step checks out the version of the software as of
+ this time so that multiple clients choose a common version to test.
+ This is not well-defined in distributed version-control systems so
+ the setting is ignored.
+
+ * `CTest Script`_ variable: :variable:`CTEST_NIGHTLY_START_TIME`
+ * :module:`CTest` module variable: ``NIGHTLY_START_TIME`` if set,
+ else ``CTEST_NIGHTLY_START_TIME``
+
+.. _`CTest Configure Step`:
+
+CTest Configure Step
+--------------------
+
+In a `CTest Script`_, the :command:`ctest_configure` command runs this step.
+Arguments to the command may specify some of the step settings.
+
+Configuration settings include:
+
+``ConfigureCommand``
+ Command-line to launch the software configuration process.
+ It will be executed in the location specified by the
+ ``BuildDirectory`` setting.
+
+ * `CTest Script`_ variable: :variable:`CTEST_CONFIGURE_COMMAND`
+ * :module:`CTest` module variable: :variable:`CMAKE_COMMAND`
+ followed by :variable:`PROJECT_SOURCE_DIR`
+
+.. _`CTest Build Step`:
+
+CTest Build Step
+----------------
+
+In a `CTest Script`_, the :command:`ctest_build` command runs this step.
+Arguments to the command may specify some of the step settings.
+
+Configuration settings include:
+
+``DefaultCTestConfigurationType``
+ When the build system to be launched allows build-time selection
+ of the configuration (e.g. ``Debug``, ``Release``), this specifies
+ the default configuration to be built when no ``-C`` option is
+ given to the ``ctest`` command. The value will be substituted into
+ the value of ``MakeCommand`` to replace the literal string
+ ``${CTEST_CONFIGURATION_TYPE}`` if it appears.
+
+ * `CTest Script`_ variable: :variable:`CTEST_CONFIGURATION_TYPE`
+ * :module:`CTest` module variable: ``DEFAULT_CTEST_CONFIGURATION_TYPE``,
+ initialized by the ``CMAKE_CONFIG_TYPE`` environment variable
+
+``MakeCommand``
+ Command-line to launch the software build process.
+ It will be executed in the location specified by the
+ ``BuildDirectory`` setting.
+
+ * `CTest Script`_ variable: :variable:`CTEST_BUILD_COMMAND`
+ * :module:`CTest` module variable: ``MAKECOMMAND``,
+ initialized by the :command:`build_command` command
+
+``UseLaunchers``
+ For build trees generated by CMake using one of the
+ :ref:`Makefile Generators` or the :generator:`Ninja`
+ generator, specify whether the
+ ``CTEST_USE_LAUNCHERS`` feature is enabled by the
+ :module:`CTestUseLaunchers` module (also included by the
+ :module:`CTest` module). When enabled, the generated build
+ system wraps each invocation of the compiler, linker, or
+ custom command line with a "launcher" that communicates
+ with CTest via environment variables and files to report
+ granular build warning and error information. Otherwise,
+ CTest must "scrape" the build output log for diagnostics.
+
+ * `CTest Script`_ variable: :variable:`CTEST_USE_LAUNCHERS`
+ * :module:`CTest` module variable: ``CTEST_USE_LAUNCHERS``
+
+.. _`CTest Test Step`:
+
+CTest Test Step
+---------------
+
+In a `CTest Script`_, the :command:`ctest_test` command runs this step.
+Arguments to the command may specify some of the step settings.
+
+Configuration settings include:
+
+``TestLoad``
+ While running tests in parallel (e.g. with ``-j``), try not to start
+ tests when they may cause the CPU load to pass above a given threshold.
+
+ * `CTest Script`_ variable: :variable:`CTEST_TEST_LOAD`
+ * :module:`CTest` module variable: ``CTEST_TEST_LOAD``
+
+``TimeOut``
+ The default timeout for each test if not specified by the
+ :prop_test:`TIMEOUT` test property.
+
+ * `CTest Script`_ variable: :variable:`CTEST_TEST_TIMEOUT`
+ * :module:`CTest` module variable: ``DART_TESTING_TIMEOUT``
+
+.. _`CTest Coverage Step`:
+
+CTest Coverage Step
+-------------------
+
+In a `CTest Script`_, the :command:`ctest_coverage` command runs this step.
+Arguments to the command may specify some of the step settings.
+
+Configuration settings include:
+
+``CoverageCommand``
+ Command-line tool to perform software coverage analysis.
+ It will be executed in the location specified by the
+ ``BuildDirectory`` setting.
+
+ * `CTest Script`_ variable: :variable:`CTEST_COVERAGE_COMMAND`
+ * :module:`CTest` module variable: ``COVERAGE_COMMAND``
+
+``CoverageExtraFlags``
+ Specify command-line options to the ``CoverageCommand`` tool.
+
+ * `CTest Script`_ variable: :variable:`CTEST_COVERAGE_EXTRA_FLAGS`
+ * :module:`CTest` module variable: ``COVERAGE_EXTRA_FLAGS``
+
+.. _`CTest MemCheck Step`:
+
+CTest MemCheck Step
+-------------------
+
+In a `CTest Script`_, the :command:`ctest_memcheck` command runs this step.
+Arguments to the command may specify some of the step settings.
+
+Configuration settings include:
+
+``MemoryCheckCommand``
+ Command-line tool to perform dynamic analysis. Test command lines
+ will be launched through this tool.
+
+ * `CTest Script`_ variable: :variable:`CTEST_MEMORYCHECK_COMMAND`
+ * :module:`CTest` module variable: ``MEMORYCHECK_COMMAND``
+
+``MemoryCheckCommandOptions``
+ Specify command-line options to the ``MemoryCheckCommand`` tool.
+ They will be placed prior to the test command line.
+
+ * `CTest Script`_ variable: :variable:`CTEST_MEMORYCHECK_COMMAND_OPTIONS`
+ * :module:`CTest` module variable: ``MEMORYCHECK_COMMAND_OPTIONS``
+
+``MemoryCheckType``
+ Specify the type of memory checking to perform.
+
+ * `CTest Script`_ variable: :variable:`CTEST_MEMORYCHECK_TYPE`
+ * :module:`CTest` module variable: ``MEMORYCHECK_TYPE``
+
+``MemoryCheckSanitizerOptions``
+ Specify options to sanitizers when running with a sanitize-enabled build.
+
+ * `CTest Script`_ variable: :variable:`CTEST_MEMORYCHECK_SANITIZER_OPTIONS`
+ * :module:`CTest` module variable: ``MEMORYCHECK_SANITIZER_OPTIONS``
+
+``MemoryCheckSuppressionFile``
+ Specify a file containing suppression rules for the
+ ``MemoryCheckCommand`` tool. It will be passed with options
+ appropriate to the tool.
+
+ * `CTest Script`_ variable: :variable:`CTEST_MEMORYCHECK_SUPPRESSIONS_FILE`
+ * :module:`CTest` module variable: ``MEMORYCHECK_SUPPRESSIONS_FILE``
+
+Additional configuration settings include:
+
+``BoundsCheckerCommand``
+ Specify a ``MemoryCheckCommand`` that is known to be command-line
+ compatible with Bounds Checker.
+
+ * `CTest Script`_ variable: none
+ * :module:`CTest` module variable: none
+
+``PurifyCommand``
+ Specify a ``MemoryCheckCommand`` that is known to be command-line
+ compatible with Purify.
+
+ * `CTest Script`_ variable: none
+ * :module:`CTest` module variable: ``PURIFYCOMMAND``
+
+``ValgrindCommand``
+ Specify a ``MemoryCheckCommand`` that is known to be command-line
+ compatible with Valgrind.
+
+ * `CTest Script`_ variable: none
+ * :module:`CTest` module variable: ``VALGRIND_COMMAND``
+
+``ValgrindCommandOptions``
+ Specify command-line options to the ``ValgrindCommand`` tool.
+ They will be placed prior to the test command line.
+
+ * `CTest Script`_ variable: none
+ * :module:`CTest` module variable: ``VALGRIND_COMMAND_OPTIONS``
+
+.. _`CTest Submit Step`:
+
+CTest Submit Step
+-----------------
+
+In a `CTest Script`_, the :command:`ctest_submit` command runs this step.
+Arguments to the command may specify some of the step settings.
+
+Configuration settings include:
+
+``BuildName``
+ Describe the dashboard client platform with a short string.
+ (Operating system, compiler, etc.)
+
+ * `CTest Script`_ variable: :variable:`CTEST_BUILD_NAME`
+ * :module:`CTest` module variable: ``BUILDNAME``
+
+``CDashVersion``
+ Specify the version of `CDash`_ on the server.
+
+ * `CTest Script`_ variable: none, detected from server
+ * :module:`CTest` module variable: ``CTEST_CDASH_VERSION``
+
+``CTestSubmitRetryCount``
+ Specify a number of attempts to retry submission on network failure.
+
+ * `CTest Script`_ variable: none,
+ use the :command:`ctest_submit` ``RETRY_COUNT`` option.
+ * :module:`CTest` module variable: ``CTEST_SUBMIT_RETRY_COUNT``
+
+``CTestSubmitRetryDelay``
+ Specify a delay before retrying submission on network failure.
+
+ * `CTest Script`_ variable: none,
+ use the :command:`ctest_submit` ``RETRY_DELAY`` option.
+ * :module:`CTest` module variable: ``CTEST_SUBMIT_RETRY_DELAY``
+
+``CurlOptions``
+ Specify a semicolon-separated list of options to control the
+ Curl library that CTest uses internally to connect to the
+ server. Possible options are ``CURLOPT_SSL_VERIFYPEER_OFF``
+ and ``CURLOPT_SSL_VERIFYHOST_OFF``.
+
+ * `CTest Script`_ variable: :variable:`CTEST_CURL_OPTIONS`
+ * :module:`CTest` module variable: ``CTEST_CURL_OPTIONS``
+
+``DropLocation``
+ The path on the dashboard server to send the submission.
+
+ * `CTest Script`_ variable: :variable:`CTEST_DROP_LOCATION`
+ * :module:`CTest` module variable: ``DROP_LOCATION`` if set,
+ else ``CTEST_DROP_LOCATION``
+
+``DropMethod``
+ Specify the method by which results should be submitted to the
+ dashboard server. The value may be ``cp``, ``ftp``, ``http``,
+ ``https``, ``scp``, or ``xmlrpc`` (if CMake was built with
+ support for it).
+
+ * `CTest Script`_ variable: :variable:`CTEST_DROP_METHOD`
+ * :module:`CTest` module variable: ``DROP_METHOD`` if set,
+ else ``CTEST_DROP_METHOD``
+
+``DropSite``
+ The dashboard server name
+ (for ``ftp``, ``http``, and ``https``, ``scp``, and ``xmlrpc``).
+
+ * `CTest Script`_ variable: :variable:`CTEST_DROP_SITE`
+ * :module:`CTest` module variable: ``DROP_SITE`` if set,
+ else ``CTEST_DROP_SITE``
+
+``DropSitePassword``
+ The dashboard server login password, if any
+ (for ``ftp``, ``http``, and ``https``).
+
+ * `CTest Script`_ variable: :variable:`CTEST_DROP_SITE_PASSWORD`
+ * :module:`CTest` module variable: ``DROP_SITE_PASSWORD`` if set,
+ else ``CTEST_DROP_SITE_PASWORD``
+
+``DropSiteUser``
+ The dashboard server login user name, if any
+ (for ``ftp``, ``http``, and ``https``).
+
+ * `CTest Script`_ variable: :variable:`CTEST_DROP_SITE_USER`
+ * :module:`CTest` module variable: ``DROP_SITE_USER`` if set,
+ else ``CTEST_DROP_SITE_USER``
+
+``IsCDash``
+ Specify whether the dashboard server is `CDash`_ or an older
+ dashboard server implementation requiring ``TriggerSite``.
+
+ * `CTest Script`_ variable: :variable:`CTEST_DROP_SITE_CDASH`
+ * :module:`CTest` module variable: ``CTEST_DROP_SITE_CDASH``
+
+``ScpCommand``
+ ``scp`` command-line tool to use when ``DropMethod`` is ``scp``.
+
+ * `CTest Script`_ variable: :variable:`CTEST_SCP_COMMAND`
+ * :module:`CTest` module variable: ``SCPCOMMAND``
+
+``Site``
+ Describe the dashboard client host site with a short string.
+ (Hostname, domain, etc.)
+
+ * `CTest Script`_ variable: :variable:`CTEST_SITE`
+ * :module:`CTest` module variable: ``SITE``,
+ initialized by the :command:`site_name` command
+
+``TriggerSite``
+ Legacy option to support older dashboard server implementations.
+ Not used when ``IsCDash`` is true.
+
+ * `CTest Script`_ variable: :variable:`CTEST_TRIGGER_SITE`
+ * :module:`CTest` module variable: ``TRIGGER_SITE`` if set,
+ else ``CTEST_TRIGGER_SITE``
+
+See Also
+========
+
+.. include:: LINKS.txt
diff --git a/Help/module/AddFileDependencies.rst b/Help/module/AddFileDependencies.rst
new file mode 100644
index 000000000..3cbce33ac
--- /dev/null
+++ b/Help/module/AddFileDependencies.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/AddFileDependencies.cmake
diff --git a/Help/module/BundleUtilities.rst b/Help/module/BundleUtilities.rst
new file mode 100644
index 000000000..5d9c84017
--- /dev/null
+++ b/Help/module/BundleUtilities.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/BundleUtilities.cmake
diff --git a/Help/module/CMakeAddFortranSubdirectory.rst b/Help/module/CMakeAddFortranSubdirectory.rst
new file mode 100644
index 000000000..9abf571af
--- /dev/null
+++ b/Help/module/CMakeAddFortranSubdirectory.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CMakeAddFortranSubdirectory.cmake
diff --git a/Help/module/CMakeBackwardCompatibilityCXX.rst b/Help/module/CMakeBackwardCompatibilityCXX.rst
new file mode 100644
index 000000000..05e5f4abe
--- /dev/null
+++ b/Help/module/CMakeBackwardCompatibilityCXX.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CMakeBackwardCompatibilityCXX.cmake
diff --git a/Help/module/CMakeDependentOption.rst b/Help/module/CMakeDependentOption.rst
new file mode 100644
index 000000000..fd071b55b
--- /dev/null
+++ b/Help/module/CMakeDependentOption.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CMakeDependentOption.cmake
diff --git a/Help/module/CMakeDetermineVSServicePack.rst b/Help/module/CMakeDetermineVSServicePack.rst
new file mode 100644
index 000000000..176853372
--- /dev/null
+++ b/Help/module/CMakeDetermineVSServicePack.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CMakeDetermineVSServicePack.cmake
diff --git a/Help/module/CMakeExpandImportedTargets.rst b/Help/module/CMakeExpandImportedTargets.rst
new file mode 100644
index 000000000..108428034
--- /dev/null
+++ b/Help/module/CMakeExpandImportedTargets.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CMakeExpandImportedTargets.cmake
diff --git a/Help/module/CMakeFindDependencyMacro.rst b/Help/module/CMakeFindDependencyMacro.rst
new file mode 100644
index 000000000..5b5b550a3
--- /dev/null
+++ b/Help/module/CMakeFindDependencyMacro.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CMakeFindDependencyMacro.cmake
diff --git a/Help/module/CMakeFindFrameworks.rst b/Help/module/CMakeFindFrameworks.rst
new file mode 100644
index 000000000..c2c219b3e
--- /dev/null
+++ b/Help/module/CMakeFindFrameworks.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CMakeFindFrameworks.cmake
diff --git a/Help/module/CMakeFindPackageMode.rst b/Help/module/CMakeFindPackageMode.rst
new file mode 100644
index 000000000..d099d19e3
--- /dev/null
+++ b/Help/module/CMakeFindPackageMode.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CMakeFindPackageMode.cmake
diff --git a/Help/module/CMakeForceCompiler.rst b/Help/module/CMakeForceCompiler.rst
new file mode 100644
index 000000000..327742694
--- /dev/null
+++ b/Help/module/CMakeForceCompiler.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CMakeForceCompiler.cmake
diff --git a/Help/module/CMakeGraphVizOptions.rst b/Help/module/CMakeGraphVizOptions.rst
new file mode 100644
index 000000000..2cd97b3c4
--- /dev/null
+++ b/Help/module/CMakeGraphVizOptions.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CMakeGraphVizOptions.cmake
diff --git a/Help/module/CMakePackageConfigHelpers.rst b/Help/module/CMakePackageConfigHelpers.rst
new file mode 100644
index 000000000..a291aff0c
--- /dev/null
+++ b/Help/module/CMakePackageConfigHelpers.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CMakePackageConfigHelpers.cmake
diff --git a/Help/module/CMakeParseArguments.rst b/Help/module/CMakeParseArguments.rst
new file mode 100644
index 000000000..810a9dd3c
--- /dev/null
+++ b/Help/module/CMakeParseArguments.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CMakeParseArguments.cmake
diff --git a/Help/module/CMakePrintHelpers.rst b/Help/module/CMakePrintHelpers.rst
new file mode 100644
index 000000000..a75a34f0a
--- /dev/null
+++ b/Help/module/CMakePrintHelpers.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CMakePrintHelpers.cmake
diff --git a/Help/module/CMakePrintSystemInformation.rst b/Help/module/CMakePrintSystemInformation.rst
new file mode 100644
index 000000000..0b5d8489a
--- /dev/null
+++ b/Help/module/CMakePrintSystemInformation.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CMakePrintSystemInformation.cmake
diff --git a/Help/module/CMakePushCheckState.rst b/Help/module/CMakePushCheckState.rst
new file mode 100644
index 000000000..e89792959
--- /dev/null
+++ b/Help/module/CMakePushCheckState.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CMakePushCheckState.cmake
diff --git a/Help/module/CMakeVerifyManifest.rst b/Help/module/CMakeVerifyManifest.rst
new file mode 100644
index 000000000..eeff1bf49
--- /dev/null
+++ b/Help/module/CMakeVerifyManifest.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CMakeVerifyManifest.cmake
diff --git a/Help/module/CPack.rst b/Help/module/CPack.rst
new file mode 100644
index 000000000..bfbda1f89
--- /dev/null
+++ b/Help/module/CPack.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CPack.cmake
diff --git a/Help/module/CPackBundle.rst b/Help/module/CPackBundle.rst
new file mode 100644
index 000000000..651e87426
--- /dev/null
+++ b/Help/module/CPackBundle.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CPackBundle.cmake
diff --git a/Help/module/CPackComponent.rst b/Help/module/CPackComponent.rst
new file mode 100644
index 000000000..df82836ca
--- /dev/null
+++ b/Help/module/CPackComponent.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CPackComponent.cmake
diff --git a/Help/module/CPackCygwin.rst b/Help/module/CPackCygwin.rst
new file mode 100644
index 000000000..21f447348
--- /dev/null
+++ b/Help/module/CPackCygwin.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CPackCygwin.cmake
diff --git a/Help/module/CPackDMG.rst b/Help/module/CPackDMG.rst
new file mode 100644
index 000000000..784262c5e
--- /dev/null
+++ b/Help/module/CPackDMG.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CPackDMG.cmake
diff --git a/Help/module/CPackDeb.rst b/Help/module/CPackDeb.rst
new file mode 100644
index 000000000..d1526ee49
--- /dev/null
+++ b/Help/module/CPackDeb.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CPackDeb.cmake
diff --git a/Help/module/CPackIFW.rst b/Help/module/CPackIFW.rst
new file mode 100644
index 000000000..ea05796ad
--- /dev/null
+++ b/Help/module/CPackIFW.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CPackIFW.cmake
diff --git a/Help/module/CPackNSIS.rst b/Help/module/CPackNSIS.rst
new file mode 100644
index 000000000..bb35ed60a
--- /dev/null
+++ b/Help/module/CPackNSIS.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CPackNSIS.cmake
diff --git a/Help/module/CPackPackageMaker.rst b/Help/module/CPackPackageMaker.rst
new file mode 100644
index 000000000..de5544869
--- /dev/null
+++ b/Help/module/CPackPackageMaker.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CPackPackageMaker.cmake
diff --git a/Help/module/CPackRPM.rst b/Help/module/CPackRPM.rst
new file mode 100644
index 000000000..28d0e6912
--- /dev/null
+++ b/Help/module/CPackRPM.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CPackRPM.cmake
diff --git a/Help/module/CPackWIX.rst b/Help/module/CPackWIX.rst
new file mode 100644
index 000000000..1f5e451e9
--- /dev/null
+++ b/Help/module/CPackWIX.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CPackWIX.cmake
diff --git a/Help/module/CTest.rst b/Help/module/CTest.rst
new file mode 100644
index 000000000..11a6af7d7
--- /dev/null
+++ b/Help/module/CTest.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CTest.cmake
diff --git a/Help/module/CTestCoverageCollectGCOV.rst b/Help/module/CTestCoverageCollectGCOV.rst
new file mode 100644
index 000000000..4c5deca4d
--- /dev/null
+++ b/Help/module/CTestCoverageCollectGCOV.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CTestCoverageCollectGCOV.cmake
diff --git a/Help/module/CTestScriptMode.rst b/Help/module/CTestScriptMode.rst
new file mode 100644
index 000000000..be1b0447e
--- /dev/null
+++ b/Help/module/CTestScriptMode.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CTestScriptMode.cmake
diff --git a/Help/module/CTestUseLaunchers.rst b/Help/module/CTestUseLaunchers.rst
new file mode 100644
index 000000000..688da0870
--- /dev/null
+++ b/Help/module/CTestUseLaunchers.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CTestUseLaunchers.cmake
diff --git a/Help/module/CheckCCompilerFlag.rst b/Help/module/CheckCCompilerFlag.rst
new file mode 100644
index 000000000..1be1491cc
--- /dev/null
+++ b/Help/module/CheckCCompilerFlag.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckCCompilerFlag.cmake
diff --git a/Help/module/CheckCSourceCompiles.rst b/Help/module/CheckCSourceCompiles.rst
new file mode 100644
index 000000000..1fa02f9b1
--- /dev/null
+++ b/Help/module/CheckCSourceCompiles.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckCSourceCompiles.cmake
diff --git a/Help/module/CheckCSourceRuns.rst b/Help/module/CheckCSourceRuns.rst
new file mode 100644
index 000000000..16b47e66d
--- /dev/null
+++ b/Help/module/CheckCSourceRuns.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckCSourceRuns.cmake
diff --git a/Help/module/CheckCXXCompilerFlag.rst b/Help/module/CheckCXXCompilerFlag.rst
new file mode 100644
index 000000000..cfd1f457b
--- /dev/null
+++ b/Help/module/CheckCXXCompilerFlag.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckCXXCompilerFlag.cmake
diff --git a/Help/module/CheckCXXSourceCompiles.rst b/Help/module/CheckCXXSourceCompiles.rst
new file mode 100644
index 000000000..d701c4e54
--- /dev/null
+++ b/Help/module/CheckCXXSourceCompiles.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckCXXSourceCompiles.cmake
diff --git a/Help/module/CheckCXXSourceRuns.rst b/Help/module/CheckCXXSourceRuns.rst
new file mode 100644
index 000000000..caab97589
--- /dev/null
+++ b/Help/module/CheckCXXSourceRuns.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckCXXSourceRuns.cmake
diff --git a/Help/module/CheckCXXSymbolExists.rst b/Help/module/CheckCXXSymbolExists.rst
new file mode 100644
index 000000000..fc192e819
--- /dev/null
+++ b/Help/module/CheckCXXSymbolExists.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckCXXSymbolExists.cmake
diff --git a/Help/module/CheckFortranCompilerFlag.rst b/Help/module/CheckFortranCompilerFlag.rst
new file mode 100644
index 000000000..58bf6ec35
--- /dev/null
+++ b/Help/module/CheckFortranCompilerFlag.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckFortranCompilerFlag.cmake
diff --git a/Help/module/CheckFortranFunctionExists.rst b/Help/module/CheckFortranFunctionExists.rst
new file mode 100644
index 000000000..3395d05c4
--- /dev/null
+++ b/Help/module/CheckFortranFunctionExists.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckFortranFunctionExists.cmake
diff --git a/Help/module/CheckFortranSourceCompiles.rst b/Help/module/CheckFortranSourceCompiles.rst
new file mode 100644
index 000000000..b749a2a30
--- /dev/null
+++ b/Help/module/CheckFortranSourceCompiles.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckFortranSourceCompiles.cmake
diff --git a/Help/module/CheckFunctionExists.rst b/Help/module/CheckFunctionExists.rst
new file mode 100644
index 000000000..ed89dc407
--- /dev/null
+++ b/Help/module/CheckFunctionExists.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckFunctionExists.cmake
diff --git a/Help/module/CheckIncludeFile.rst b/Help/module/CheckIncludeFile.rst
new file mode 100644
index 000000000..6b831089e
--- /dev/null
+++ b/Help/module/CheckIncludeFile.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckIncludeFile.cmake
diff --git a/Help/module/CheckIncludeFileCXX.rst b/Help/module/CheckIncludeFileCXX.rst
new file mode 100644
index 000000000..fdbf39fd1
--- /dev/null
+++ b/Help/module/CheckIncludeFileCXX.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckIncludeFileCXX.cmake
diff --git a/Help/module/CheckIncludeFiles.rst b/Help/module/CheckIncludeFiles.rst
new file mode 100644
index 000000000..b56f14565
--- /dev/null
+++ b/Help/module/CheckIncludeFiles.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckIncludeFiles.cmake
diff --git a/Help/module/CheckLanguage.rst b/Help/module/CheckLanguage.rst
new file mode 100644
index 000000000..16f1a3f79
--- /dev/null
+++ b/Help/module/CheckLanguage.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckLanguage.cmake
diff --git a/Help/module/CheckLibraryExists.rst b/Help/module/CheckLibraryExists.rst
new file mode 100644
index 000000000..7512f46c5
--- /dev/null
+++ b/Help/module/CheckLibraryExists.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckLibraryExists.cmake
diff --git a/Help/module/CheckPrototypeDefinition.rst b/Help/module/CheckPrototypeDefinition.rst
new file mode 100644
index 000000000..073fcb59f
--- /dev/null
+++ b/Help/module/CheckPrototypeDefinition.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckPrototypeDefinition.cmake
diff --git a/Help/module/CheckStructHasMember.rst b/Help/module/CheckStructHasMember.rst
new file mode 100644
index 000000000..5277ad2f6
--- /dev/null
+++ b/Help/module/CheckStructHasMember.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckStructHasMember.cmake
diff --git a/Help/module/CheckSymbolExists.rst b/Help/module/CheckSymbolExists.rst
new file mode 100644
index 000000000..68ae70009
--- /dev/null
+++ b/Help/module/CheckSymbolExists.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckSymbolExists.cmake
diff --git a/Help/module/CheckTypeSize.rst b/Help/module/CheckTypeSize.rst
new file mode 100644
index 000000000..6ad03456f
--- /dev/null
+++ b/Help/module/CheckTypeSize.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckTypeSize.cmake
diff --git a/Help/module/CheckVariableExists.rst b/Help/module/CheckVariableExists.rst
new file mode 100644
index 000000000..07f077792
--- /dev/null
+++ b/Help/module/CheckVariableExists.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckVariableExists.cmake
diff --git a/Help/module/Dart.rst b/Help/module/Dart.rst
new file mode 100644
index 000000000..524ac33df
--- /dev/null
+++ b/Help/module/Dart.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/Dart.cmake
diff --git a/Help/module/DeployQt4.rst b/Help/module/DeployQt4.rst
new file mode 100644
index 000000000..3c0ef444a
--- /dev/null
+++ b/Help/module/DeployQt4.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/DeployQt4.cmake
diff --git a/Help/module/Documentation.rst b/Help/module/Documentation.rst
new file mode 100644
index 000000000..08e2ffb6d
--- /dev/null
+++ b/Help/module/Documentation.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/Documentation.cmake
diff --git a/Help/module/ExternalData.rst b/Help/module/ExternalData.rst
new file mode 100644
index 000000000..f0f8f1d07
--- /dev/null
+++ b/Help/module/ExternalData.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/ExternalData.cmake
diff --git a/Help/module/ExternalProject.rst b/Help/module/ExternalProject.rst
new file mode 100644
index 000000000..fce70567e
--- /dev/null
+++ b/Help/module/ExternalProject.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/ExternalProject.cmake
diff --git a/Help/module/FeatureSummary.rst b/Help/module/FeatureSummary.rst
new file mode 100644
index 000000000..6fd8f3805
--- /dev/null
+++ b/Help/module/FeatureSummary.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FeatureSummary.cmake
diff --git a/Help/module/FindALSA.rst b/Help/module/FindALSA.rst
new file mode 100644
index 000000000..2a73786b4
--- /dev/null
+++ b/Help/module/FindALSA.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindALSA.cmake
diff --git a/Help/module/FindASPELL.rst b/Help/module/FindASPELL.rst
new file mode 100644
index 000000000..56dedc428
--- /dev/null
+++ b/Help/module/FindASPELL.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindASPELL.cmake
diff --git a/Help/module/FindAVIFile.rst b/Help/module/FindAVIFile.rst
new file mode 100644
index 000000000..71282a684
--- /dev/null
+++ b/Help/module/FindAVIFile.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindAVIFile.cmake
diff --git a/Help/module/FindArmadillo.rst b/Help/module/FindArmadillo.rst
new file mode 100644
index 000000000..f0ac933d1
--- /dev/null
+++ b/Help/module/FindArmadillo.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindArmadillo.cmake
diff --git a/Help/module/FindBISON.rst b/Help/module/FindBISON.rst
new file mode 100644
index 000000000..c6e5791be
--- /dev/null
+++ b/Help/module/FindBISON.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindBISON.cmake
diff --git a/Help/module/FindBLAS.rst b/Help/module/FindBLAS.rst
new file mode 100644
index 000000000..41f67711c
--- /dev/null
+++ b/Help/module/FindBLAS.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindBLAS.cmake
diff --git a/Help/module/FindBZip2.rst b/Help/module/FindBZip2.rst
new file mode 100644
index 000000000..281b1d10d
--- /dev/null
+++ b/Help/module/FindBZip2.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindBZip2.cmake
diff --git a/Help/module/FindBacktrace.rst b/Help/module/FindBacktrace.rst
new file mode 100644
index 000000000..e1ca48c77
--- /dev/null
+++ b/Help/module/FindBacktrace.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindBacktrace.cmake
diff --git a/Help/module/FindBoost.rst b/Help/module/FindBoost.rst
new file mode 100644
index 000000000..139254055
--- /dev/null
+++ b/Help/module/FindBoost.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindBoost.cmake
diff --git a/Help/module/FindBullet.rst b/Help/module/FindBullet.rst
new file mode 100644
index 000000000..4ed2b855b
--- /dev/null
+++ b/Help/module/FindBullet.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindBullet.cmake
diff --git a/Help/module/FindCABLE.rst b/Help/module/FindCABLE.rst
new file mode 100644
index 000000000..716d5abd5
--- /dev/null
+++ b/Help/module/FindCABLE.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindCABLE.cmake
diff --git a/Help/module/FindCUDA.rst b/Help/module/FindCUDA.rst
new file mode 100644
index 000000000..46ffa9fc2
--- /dev/null
+++ b/Help/module/FindCUDA.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindCUDA.cmake
diff --git a/Help/module/FindCURL.rst b/Help/module/FindCURL.rst
new file mode 100644
index 000000000..e2acc4987
--- /dev/null
+++ b/Help/module/FindCURL.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindCURL.cmake
diff --git a/Help/module/FindCVS.rst b/Help/module/FindCVS.rst
new file mode 100644
index 000000000..c891c07d7
--- /dev/null
+++ b/Help/module/FindCVS.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindCVS.cmake
diff --git a/Help/module/FindCoin3D.rst b/Help/module/FindCoin3D.rst
new file mode 100644
index 000000000..fc70a74d6
--- /dev/null
+++ b/Help/module/FindCoin3D.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindCoin3D.cmake
diff --git a/Help/module/FindCups.rst b/Help/module/FindCups.rst
new file mode 100644
index 000000000..10d0646fd
--- /dev/null
+++ b/Help/module/FindCups.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindCups.cmake
diff --git a/Help/module/FindCurses.rst b/Help/module/FindCurses.rst
new file mode 100644
index 000000000..73dd01171
--- /dev/null
+++ b/Help/module/FindCurses.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindCurses.cmake
diff --git a/Help/module/FindCxxTest.rst b/Help/module/FindCxxTest.rst
new file mode 100644
index 000000000..4f17c39bc
--- /dev/null
+++ b/Help/module/FindCxxTest.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindCxxTest.cmake
diff --git a/Help/module/FindCygwin.rst b/Help/module/FindCygwin.rst
new file mode 100644
index 000000000..2e529dd03
--- /dev/null
+++ b/Help/module/FindCygwin.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindCygwin.cmake
diff --git a/Help/module/FindDCMTK.rst b/Help/module/FindDCMTK.rst
new file mode 100644
index 000000000..8437d5557
--- /dev/null
+++ b/Help/module/FindDCMTK.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindDCMTK.cmake
diff --git a/Help/module/FindDart.rst b/Help/module/FindDart.rst
new file mode 100644
index 000000000..6f21ad4be
--- /dev/null
+++ b/Help/module/FindDart.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindDart.cmake
diff --git a/Help/module/FindDevIL.rst b/Help/module/FindDevIL.rst
new file mode 100644
index 000000000..91a28ddc4
--- /dev/null
+++ b/Help/module/FindDevIL.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindDevIL.cmake
diff --git a/Help/module/FindDoxygen.rst b/Help/module/FindDoxygen.rst
new file mode 100644
index 000000000..cffe73453
--- /dev/null
+++ b/Help/module/FindDoxygen.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindDoxygen.cmake
diff --git a/Help/module/FindEXPAT.rst b/Help/module/FindEXPAT.rst
new file mode 100644
index 000000000..5063680bb
--- /dev/null
+++ b/Help/module/FindEXPAT.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindEXPAT.cmake
diff --git a/Help/module/FindFLEX.rst b/Help/module/FindFLEX.rst
new file mode 100644
index 000000000..cc90791d9
--- /dev/null
+++ b/Help/module/FindFLEX.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindFLEX.cmake
diff --git a/Help/module/FindFLTK.rst b/Help/module/FindFLTK.rst
new file mode 100644
index 000000000..cc1964cc4
--- /dev/null
+++ b/Help/module/FindFLTK.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindFLTK.cmake
diff --git a/Help/module/FindFLTK2.rst b/Help/module/FindFLTK2.rst
new file mode 100644
index 000000000..5c2acc4ae
--- /dev/null
+++ b/Help/module/FindFLTK2.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindFLTK2.cmake
diff --git a/Help/module/FindFreetype.rst b/Help/module/FindFreetype.rst
new file mode 100644
index 000000000..424c3fcb3
--- /dev/null
+++ b/Help/module/FindFreetype.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindFreetype.cmake
diff --git a/Help/module/FindGCCXML.rst b/Help/module/FindGCCXML.rst
new file mode 100644
index 000000000..15fd4d0d6
--- /dev/null
+++ b/Help/module/FindGCCXML.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindGCCXML.cmake
diff --git a/Help/module/FindGDAL.rst b/Help/module/FindGDAL.rst
new file mode 100644
index 000000000..81fcb3a20
--- /dev/null
+++ b/Help/module/FindGDAL.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindGDAL.cmake
diff --git a/Help/module/FindGIF.rst b/Help/module/FindGIF.rst
new file mode 100644
index 000000000..03d3a7538
--- /dev/null
+++ b/Help/module/FindGIF.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindGIF.cmake
diff --git a/Help/module/FindGLEW.rst b/Help/module/FindGLEW.rst
new file mode 100644
index 000000000..77755da1f
--- /dev/null
+++ b/Help/module/FindGLEW.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindGLEW.cmake
diff --git a/Help/module/FindGLUT.rst b/Help/module/FindGLUT.rst
new file mode 100644
index 000000000..40263eeb9
--- /dev/null
+++ b/Help/module/FindGLUT.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindGLUT.cmake
diff --git a/Help/module/FindGSL.rst b/Help/module/FindGSL.rst
new file mode 100644
index 000000000..baf221368
--- /dev/null
+++ b/Help/module/FindGSL.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindGSL.cmake
diff --git a/Help/module/FindGTK.rst b/Help/module/FindGTK.rst
new file mode 100644
index 000000000..1ce6a8675
--- /dev/null
+++ b/Help/module/FindGTK.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindGTK.cmake
diff --git a/Help/module/FindGTK2.rst b/Help/module/FindGTK2.rst
new file mode 100644
index 000000000..67c1ba9e2
--- /dev/null
+++ b/Help/module/FindGTK2.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindGTK2.cmake
diff --git a/Help/module/FindGTest.rst b/Help/module/FindGTest.rst
new file mode 100644
index 000000000..0e3b4d770
--- /dev/null
+++ b/Help/module/FindGTest.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindGTest.cmake
diff --git a/Help/module/FindGettext.rst b/Help/module/FindGettext.rst
new file mode 100644
index 000000000..e880dc038
--- /dev/null
+++ b/Help/module/FindGettext.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindGettext.cmake
diff --git a/Help/module/FindGit.rst b/Help/module/FindGit.rst
new file mode 100644
index 000000000..dd540ef2f
--- /dev/null
+++ b/Help/module/FindGit.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindGit.cmake
diff --git a/Help/module/FindGnuTLS.rst b/Help/module/FindGnuTLS.rst
new file mode 100644
index 000000000..de0c1d4f8
--- /dev/null
+++ b/Help/module/FindGnuTLS.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindGnuTLS.cmake
diff --git a/Help/module/FindGnuplot.rst b/Help/module/FindGnuplot.rst
new file mode 100644
index 000000000..93a18b608
--- /dev/null
+++ b/Help/module/FindGnuplot.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindGnuplot.cmake
diff --git a/Help/module/FindHDF5.rst b/Help/module/FindHDF5.rst
new file mode 100644
index 000000000..8ac1b8be9
--- /dev/null
+++ b/Help/module/FindHDF5.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindHDF5.cmake
diff --git a/Help/module/FindHSPELL.rst b/Help/module/FindHSPELL.rst
new file mode 100644
index 000000000..c1905a2e3
--- /dev/null
+++ b/Help/module/FindHSPELL.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindHSPELL.cmake
diff --git a/Help/module/FindHTMLHelp.rst b/Help/module/FindHTMLHelp.rst
new file mode 100644
index 000000000..47d9c8c49
--- /dev/null
+++ b/Help/module/FindHTMLHelp.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindHTMLHelp.cmake
diff --git a/Help/module/FindHg.rst b/Help/module/FindHg.rst
new file mode 100644
index 000000000..94aba6f7e
--- /dev/null
+++ b/Help/module/FindHg.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindHg.cmake
diff --git a/Help/module/FindITK.rst b/Help/module/FindITK.rst
new file mode 100644
index 000000000..21a922f61
--- /dev/null
+++ b/Help/module/FindITK.rst
@@ -0,0 +1,10 @@
+FindITK
+-------
+
+This module no longer exists.
+
+This module existed in versions of CMake prior to 3.1, but became
+only a thin wrapper around ``find_package(ITK NO_MODULE)`` to
+provide compatibility for projects using long-outdated conventions.
+Now ``find_package(ITK)`` will search for ``ITKConfig.cmake``
+directly.
diff --git a/Help/module/FindIce.rst b/Help/module/FindIce.rst
new file mode 100644
index 000000000..3af9405e0
--- /dev/null
+++ b/Help/module/FindIce.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindIce.cmake
diff --git a/Help/module/FindIcotool.rst b/Help/module/FindIcotool.rst
new file mode 100644
index 000000000..c139f58cc
--- /dev/null
+++ b/Help/module/FindIcotool.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindIcotool.cmake
diff --git a/Help/module/FindImageMagick.rst b/Help/module/FindImageMagick.rst
new file mode 100644
index 000000000..3a3596e5e
--- /dev/null
+++ b/Help/module/FindImageMagick.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindImageMagick.cmake
diff --git a/Help/module/FindIntl.rst b/Help/module/FindIntl.rst
new file mode 100644
index 000000000..813e2df9a
--- /dev/null
+++ b/Help/module/FindIntl.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindIntl.cmake
diff --git a/Help/module/FindJNI.rst b/Help/module/FindJNI.rst
new file mode 100644
index 000000000..b753cf891
--- /dev/null
+++ b/Help/module/FindJNI.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindJNI.cmake
diff --git a/Help/module/FindJPEG.rst b/Help/module/FindJPEG.rst
new file mode 100644
index 000000000..80363529a
--- /dev/null
+++ b/Help/module/FindJPEG.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindJPEG.cmake
diff --git a/Help/module/FindJasper.rst b/Help/module/FindJasper.rst
new file mode 100644
index 000000000..725a87fc4
--- /dev/null
+++ b/Help/module/FindJasper.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindJasper.cmake
diff --git a/Help/module/FindJava.rst b/Help/module/FindJava.rst
new file mode 100644
index 000000000..39e6b6b21
--- /dev/null
+++ b/Help/module/FindJava.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindJava.cmake
diff --git a/Help/module/FindKDE3.rst b/Help/module/FindKDE3.rst
new file mode 100644
index 000000000..13ac15c8c
--- /dev/null
+++ b/Help/module/FindKDE3.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindKDE3.cmake
diff --git a/Help/module/FindKDE4.rst b/Help/module/FindKDE4.rst
new file mode 100644
index 000000000..8b22f7fc8
--- /dev/null
+++ b/Help/module/FindKDE4.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindKDE4.cmake
diff --git a/Help/module/FindLAPACK.rst b/Help/module/FindLAPACK.rst
new file mode 100644
index 000000000..6e9909016
--- /dev/null
+++ b/Help/module/FindLAPACK.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindLAPACK.cmake
diff --git a/Help/module/FindLATEX.rst b/Help/module/FindLATEX.rst
new file mode 100644
index 000000000..4b14c7136
--- /dev/null
+++ b/Help/module/FindLATEX.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindLATEX.cmake
diff --git a/Help/module/FindLibArchive.rst b/Help/module/FindLibArchive.rst
new file mode 100644
index 000000000..c46b1d004
--- /dev/null
+++ b/Help/module/FindLibArchive.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindLibArchive.cmake
diff --git a/Help/module/FindLibLZMA.rst b/Help/module/FindLibLZMA.rst
new file mode 100644
index 000000000..88801580c
--- /dev/null
+++ b/Help/module/FindLibLZMA.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindLibLZMA.cmake
diff --git a/Help/module/FindLibXml2.rst b/Help/module/FindLibXml2.rst
new file mode 100644
index 000000000..bbb322590
--- /dev/null
+++ b/Help/module/FindLibXml2.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindLibXml2.cmake
diff --git a/Help/module/FindLibXslt.rst b/Help/module/FindLibXslt.rst
new file mode 100644
index 000000000..4107170cf
--- /dev/null
+++ b/Help/module/FindLibXslt.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindLibXslt.cmake
diff --git a/Help/module/FindLua.rst b/Help/module/FindLua.rst
new file mode 100644
index 000000000..977e5bfce
--- /dev/null
+++ b/Help/module/FindLua.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindLua.cmake
diff --git a/Help/module/FindLua50.rst b/Help/module/FindLua50.rst
new file mode 100644
index 000000000..0353fc35e
--- /dev/null
+++ b/Help/module/FindLua50.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindLua50.cmake
diff --git a/Help/module/FindLua51.rst b/Help/module/FindLua51.rst
new file mode 100644
index 000000000..672ff357b
--- /dev/null
+++ b/Help/module/FindLua51.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindLua51.cmake
diff --git a/Help/module/FindMFC.rst b/Help/module/FindMFC.rst
new file mode 100644
index 000000000..a3226a690
--- /dev/null
+++ b/Help/module/FindMFC.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindMFC.cmake
diff --git a/Help/module/FindMPEG.rst b/Help/module/FindMPEG.rst
new file mode 100644
index 000000000..c9ce48142
--- /dev/null
+++ b/Help/module/FindMPEG.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindMPEG.cmake
diff --git a/Help/module/FindMPEG2.rst b/Help/module/FindMPEG2.rst
new file mode 100644
index 000000000..f843c8971
--- /dev/null
+++ b/Help/module/FindMPEG2.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindMPEG2.cmake
diff --git a/Help/module/FindMPI.rst b/Help/module/FindMPI.rst
new file mode 100644
index 000000000..fad10c732
--- /dev/null
+++ b/Help/module/FindMPI.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindMPI.cmake
diff --git a/Help/module/FindMatlab.rst b/Help/module/FindMatlab.rst
new file mode 100644
index 000000000..43f861adc
--- /dev/null
+++ b/Help/module/FindMatlab.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindMatlab.cmake
diff --git a/Help/module/FindMotif.rst b/Help/module/FindMotif.rst
new file mode 100644
index 000000000..e602a501c
--- /dev/null
+++ b/Help/module/FindMotif.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindMotif.cmake
diff --git a/Help/module/FindOpenAL.rst b/Help/module/FindOpenAL.rst
new file mode 100644
index 000000000..f0865569d
--- /dev/null
+++ b/Help/module/FindOpenAL.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindOpenAL.cmake
diff --git a/Help/module/FindOpenCL.rst b/Help/module/FindOpenCL.rst
new file mode 100644
index 000000000..e87e289bd
--- /dev/null
+++ b/Help/module/FindOpenCL.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindOpenCL.cmake
diff --git a/Help/module/FindOpenGL.rst b/Help/module/FindOpenGL.rst
new file mode 100644
index 000000000..85e89bcb3
--- /dev/null
+++ b/Help/module/FindOpenGL.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindOpenGL.cmake
diff --git a/Help/module/FindOpenMP.rst b/Help/module/FindOpenMP.rst
new file mode 100644
index 000000000..01362abfb
--- /dev/null
+++ b/Help/module/FindOpenMP.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindOpenMP.cmake
diff --git a/Help/module/FindOpenSSL.rst b/Help/module/FindOpenSSL.rst
new file mode 100644
index 000000000..f622bb14e
--- /dev/null
+++ b/Help/module/FindOpenSSL.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindOpenSSL.cmake
diff --git a/Help/module/FindOpenSceneGraph.rst b/Help/module/FindOpenSceneGraph.rst
new file mode 100644
index 000000000..434649257
--- /dev/null
+++ b/Help/module/FindOpenSceneGraph.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindOpenSceneGraph.cmake
diff --git a/Help/module/FindOpenThreads.rst b/Help/module/FindOpenThreads.rst
new file mode 100644
index 000000000..bb3f0f97b
--- /dev/null
+++ b/Help/module/FindOpenThreads.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindOpenThreads.cmake
diff --git a/Help/module/FindPHP4.rst b/Help/module/FindPHP4.rst
new file mode 100644
index 000000000..1de62e8d4
--- /dev/null
+++ b/Help/module/FindPHP4.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindPHP4.cmake
diff --git a/Help/module/FindPNG.rst b/Help/module/FindPNG.rst
new file mode 100644
index 000000000..e6d161875
--- /dev/null
+++ b/Help/module/FindPNG.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindPNG.cmake
diff --git a/Help/module/FindPackageHandleStandardArgs.rst b/Help/module/FindPackageHandleStandardArgs.rst
new file mode 100644
index 000000000..feda7ef61
--- /dev/null
+++ b/Help/module/FindPackageHandleStandardArgs.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindPackageHandleStandardArgs.cmake
diff --git a/Help/module/FindPackageMessage.rst b/Help/module/FindPackageMessage.rst
new file mode 100644
index 000000000..b682d8c0f
--- /dev/null
+++ b/Help/module/FindPackageMessage.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindPackageMessage.cmake
diff --git a/Help/module/FindPerl.rst b/Help/module/FindPerl.rst
new file mode 100644
index 000000000..098f4b545
--- /dev/null
+++ b/Help/module/FindPerl.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindPerl.cmake
diff --git a/Help/module/FindPerlLibs.rst b/Help/module/FindPerlLibs.rst
new file mode 100644
index 000000000..8d8bbab7b
--- /dev/null
+++ b/Help/module/FindPerlLibs.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindPerlLibs.cmake
diff --git a/Help/module/FindPhysFS.rst b/Help/module/FindPhysFS.rst
new file mode 100644
index 000000000..21d928bab
--- /dev/null
+++ b/Help/module/FindPhysFS.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindPhysFS.cmake
diff --git a/Help/module/FindPike.rst b/Help/module/FindPike.rst
new file mode 100644
index 000000000..b096ca4da
--- /dev/null
+++ b/Help/module/FindPike.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindPike.cmake
diff --git a/Help/module/FindPkgConfig.rst b/Help/module/FindPkgConfig.rst
new file mode 100644
index 000000000..b8caf7442
--- /dev/null
+++ b/Help/module/FindPkgConfig.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindPkgConfig.cmake
diff --git a/Help/module/FindPostgreSQL.rst b/Help/module/FindPostgreSQL.rst
new file mode 100644
index 000000000..b45c07e7f
--- /dev/null
+++ b/Help/module/FindPostgreSQL.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindPostgreSQL.cmake
diff --git a/Help/module/FindProducer.rst b/Help/module/FindProducer.rst
new file mode 100644
index 000000000..1c0c575ff
--- /dev/null
+++ b/Help/module/FindProducer.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindProducer.cmake
diff --git a/Help/module/FindProtobuf.rst b/Help/module/FindProtobuf.rst
new file mode 100644
index 000000000..b978e010f
--- /dev/null
+++ b/Help/module/FindProtobuf.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindProtobuf.cmake
diff --git a/Help/module/FindPythonInterp.rst b/Help/module/FindPythonInterp.rst
new file mode 100644
index 000000000..3be230692
--- /dev/null
+++ b/Help/module/FindPythonInterp.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindPythonInterp.cmake
diff --git a/Help/module/FindPythonLibs.rst b/Help/module/FindPythonLibs.rst
new file mode 100644
index 000000000..8f0015d33
--- /dev/null
+++ b/Help/module/FindPythonLibs.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindPythonLibs.cmake
diff --git a/Help/module/FindQt.rst b/Help/module/FindQt.rst
new file mode 100644
index 000000000..3aa8a26de
--- /dev/null
+++ b/Help/module/FindQt.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindQt.cmake
diff --git a/Help/module/FindQt3.rst b/Help/module/FindQt3.rst
new file mode 100644
index 000000000..b93305909
--- /dev/null
+++ b/Help/module/FindQt3.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindQt3.cmake
diff --git a/Help/module/FindQt4.rst b/Help/module/FindQt4.rst
new file mode 100644
index 000000000..28036b2fd
--- /dev/null
+++ b/Help/module/FindQt4.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindQt4.cmake
diff --git a/Help/module/FindQuickTime.rst b/Help/module/FindQuickTime.rst
new file mode 100644
index 000000000..735f7d29f
--- /dev/null
+++ b/Help/module/FindQuickTime.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindQuickTime.cmake
diff --git a/Help/module/FindRTI.rst b/Help/module/FindRTI.rst
new file mode 100644
index 000000000..a93ad1658
--- /dev/null
+++ b/Help/module/FindRTI.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindRTI.cmake
diff --git a/Help/module/FindRuby.rst b/Help/module/FindRuby.rst
new file mode 100644
index 000000000..a1e792241
--- /dev/null
+++ b/Help/module/FindRuby.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindRuby.cmake
diff --git a/Help/module/FindSDL.rst b/Help/module/FindSDL.rst
new file mode 100644
index 000000000..79893c03c
--- /dev/null
+++ b/Help/module/FindSDL.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindSDL.cmake
diff --git a/Help/module/FindSDL_image.rst b/Help/module/FindSDL_image.rst
new file mode 100644
index 000000000..dc69d7070
--- /dev/null
+++ b/Help/module/FindSDL_image.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindSDL_image.cmake
diff --git a/Help/module/FindSDL_mixer.rst b/Help/module/FindSDL_mixer.rst
new file mode 100644
index 000000000..1c9c44674
--- /dev/null
+++ b/Help/module/FindSDL_mixer.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindSDL_mixer.cmake
diff --git a/Help/module/FindSDL_net.rst b/Help/module/FindSDL_net.rst
new file mode 100644
index 000000000..079d0bbe3
--- /dev/null
+++ b/Help/module/FindSDL_net.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindSDL_net.cmake
diff --git a/Help/module/FindSDL_sound.rst b/Help/module/FindSDL_sound.rst
new file mode 100644
index 000000000..077edf700
--- /dev/null
+++ b/Help/module/FindSDL_sound.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindSDL_sound.cmake
diff --git a/Help/module/FindSDL_ttf.rst b/Help/module/FindSDL_ttf.rst
new file mode 100644
index 000000000..40c5ec4c4
--- /dev/null
+++ b/Help/module/FindSDL_ttf.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindSDL_ttf.cmake
diff --git a/Help/module/FindSWIG.rst b/Help/module/FindSWIG.rst
new file mode 100644
index 000000000..9b25b94b3
--- /dev/null
+++ b/Help/module/FindSWIG.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindSWIG.cmake
diff --git a/Help/module/FindSelfPackers.rst b/Help/module/FindSelfPackers.rst
new file mode 100644
index 000000000..5f2c689ca
--- /dev/null
+++ b/Help/module/FindSelfPackers.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindSelfPackers.cmake
diff --git a/Help/module/FindSquish.rst b/Help/module/FindSquish.rst
new file mode 100644
index 000000000..dc2c86d53
--- /dev/null
+++ b/Help/module/FindSquish.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindSquish.cmake
diff --git a/Help/module/FindSubversion.rst b/Help/module/FindSubversion.rst
new file mode 100644
index 000000000..aa15857d1
--- /dev/null
+++ b/Help/module/FindSubversion.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindSubversion.cmake
diff --git a/Help/module/FindTCL.rst b/Help/module/FindTCL.rst
new file mode 100644
index 000000000..cbd203589
--- /dev/null
+++ b/Help/module/FindTCL.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindTCL.cmake
diff --git a/Help/module/FindTIFF.rst b/Help/module/FindTIFF.rst
new file mode 100644
index 000000000..69f8ca585
--- /dev/null
+++ b/Help/module/FindTIFF.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindTIFF.cmake
diff --git a/Help/module/FindTclStub.rst b/Help/module/FindTclStub.rst
new file mode 100644
index 000000000..6cc5b2df2
--- /dev/null
+++ b/Help/module/FindTclStub.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindTclStub.cmake
diff --git a/Help/module/FindTclsh.rst b/Help/module/FindTclsh.rst
new file mode 100644
index 000000000..23e7d6b39
--- /dev/null
+++ b/Help/module/FindTclsh.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindTclsh.cmake
diff --git a/Help/module/FindThreads.rst b/Help/module/FindThreads.rst
new file mode 100644
index 000000000..91967a7a3
--- /dev/null
+++ b/Help/module/FindThreads.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindThreads.cmake
diff --git a/Help/module/FindUnixCommands.rst b/Help/module/FindUnixCommands.rst
new file mode 100644
index 000000000..9ad05ad2d
--- /dev/null
+++ b/Help/module/FindUnixCommands.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindUnixCommands.cmake
diff --git a/Help/module/FindVTK.rst b/Help/module/FindVTK.rst
new file mode 100644
index 000000000..3bc67c5c9
--- /dev/null
+++ b/Help/module/FindVTK.rst
@@ -0,0 +1,10 @@
+FindVTK
+-------
+
+This module no longer exists.
+
+This module existed in versions of CMake prior to 3.1, but became
+only a thin wrapper around ``find_package(VTK NO_MODULE)`` to
+provide compatibility for projects using long-outdated conventions.
+Now ``find_package(VTK)`` will search for ``VTKConfig.cmake``
+directly.
diff --git a/Help/module/FindWget.rst b/Help/module/FindWget.rst
new file mode 100644
index 000000000..06affd4eb
--- /dev/null
+++ b/Help/module/FindWget.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindWget.cmake
diff --git a/Help/module/FindWish.rst b/Help/module/FindWish.rst
new file mode 100644
index 000000000..76be4cf54
--- /dev/null
+++ b/Help/module/FindWish.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindWish.cmake
diff --git a/Help/module/FindX11.rst b/Help/module/FindX11.rst
new file mode 100644
index 000000000..906efd738
--- /dev/null
+++ b/Help/module/FindX11.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindX11.cmake
diff --git a/Help/module/FindXCTest.rst b/Help/module/FindXCTest.rst
new file mode 100644
index 000000000..ff6273c47
--- /dev/null
+++ b/Help/module/FindXCTest.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindXCTest.cmake
diff --git a/Help/module/FindXMLRPC.rst b/Help/module/FindXMLRPC.rst
new file mode 100644
index 000000000..5d11a0ca8
--- /dev/null
+++ b/Help/module/FindXMLRPC.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindXMLRPC.cmake
diff --git a/Help/module/FindXalanC.rst b/Help/module/FindXalanC.rst
new file mode 100644
index 000000000..b99d21256
--- /dev/null
+++ b/Help/module/FindXalanC.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindXalanC.cmake
diff --git a/Help/module/FindXercesC.rst b/Help/module/FindXercesC.rst
new file mode 100644
index 000000000..4818071c3
--- /dev/null
+++ b/Help/module/FindXercesC.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindXercesC.cmake
diff --git a/Help/module/FindZLIB.rst b/Help/module/FindZLIB.rst
new file mode 100644
index 000000000..ded863463
--- /dev/null
+++ b/Help/module/FindZLIB.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindZLIB.cmake
diff --git a/Help/module/Findosg.rst b/Help/module/Findosg.rst
new file mode 100644
index 000000000..6b407aca5
--- /dev/null
+++ b/Help/module/Findosg.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/Findosg.cmake
diff --git a/Help/module/FindosgAnimation.rst b/Help/module/FindosgAnimation.rst
new file mode 100644
index 000000000..f14a1e7f3
--- /dev/null
+++ b/Help/module/FindosgAnimation.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindosgAnimation.cmake
diff --git a/Help/module/FindosgDB.rst b/Help/module/FindosgDB.rst
new file mode 100644
index 000000000..9f72bc794
--- /dev/null
+++ b/Help/module/FindosgDB.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindosgDB.cmake
diff --git a/Help/module/FindosgFX.rst b/Help/module/FindosgFX.rst
new file mode 100644
index 000000000..0e1edfba1
--- /dev/null
+++ b/Help/module/FindosgFX.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindosgFX.cmake
diff --git a/Help/module/FindosgGA.rst b/Help/module/FindosgGA.rst
new file mode 100644
index 000000000..562d73fd5
--- /dev/null
+++ b/Help/module/FindosgGA.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindosgGA.cmake
diff --git a/Help/module/FindosgIntrospection.rst b/Help/module/FindosgIntrospection.rst
new file mode 100644
index 000000000..53621a71e
--- /dev/null
+++ b/Help/module/FindosgIntrospection.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindosgIntrospection.cmake
diff --git a/Help/module/FindosgManipulator.rst b/Help/module/FindosgManipulator.rst
new file mode 100644
index 000000000..b9d615d37
--- /dev/null
+++ b/Help/module/FindosgManipulator.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindosgManipulator.cmake
diff --git a/Help/module/FindosgParticle.rst b/Help/module/FindosgParticle.rst
new file mode 100644
index 000000000..9cf191c37
--- /dev/null
+++ b/Help/module/FindosgParticle.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindosgParticle.cmake
diff --git a/Help/module/FindosgPresentation.rst b/Help/module/FindosgPresentation.rst
new file mode 100644
index 000000000..cb47841bd
--- /dev/null
+++ b/Help/module/FindosgPresentation.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindosgPresentation.cmake
diff --git a/Help/module/FindosgProducer.rst b/Help/module/FindosgProducer.rst
new file mode 100644
index 000000000..c502851b4
--- /dev/null
+++ b/Help/module/FindosgProducer.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindosgProducer.cmake
diff --git a/Help/module/FindosgQt.rst b/Help/module/FindosgQt.rst
new file mode 100644
index 000000000..08c870453
--- /dev/null
+++ b/Help/module/FindosgQt.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindosgQt.cmake
diff --git a/Help/module/FindosgShadow.rst b/Help/module/FindosgShadow.rst
new file mode 100644
index 000000000..fbb22e108
--- /dev/null
+++ b/Help/module/FindosgShadow.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindosgShadow.cmake
diff --git a/Help/module/FindosgSim.rst b/Help/module/FindosgSim.rst
new file mode 100644
index 000000000..9e47b6567
--- /dev/null
+++ b/Help/module/FindosgSim.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindosgSim.cmake
diff --git a/Help/module/FindosgTerrain.rst b/Help/module/FindosgTerrain.rst
new file mode 100644
index 000000000..dd401d8b2
--- /dev/null
+++ b/Help/module/FindosgTerrain.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindosgTerrain.cmake
diff --git a/Help/module/FindosgText.rst b/Help/module/FindosgText.rst
new file mode 100644
index 000000000..bb028fb15
--- /dev/null
+++ b/Help/module/FindosgText.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindosgText.cmake
diff --git a/Help/module/FindosgUtil.rst b/Help/module/FindosgUtil.rst
new file mode 100644
index 000000000..bb11bdf4d
--- /dev/null
+++ b/Help/module/FindosgUtil.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindosgUtil.cmake
diff --git a/Help/module/FindosgViewer.rst b/Help/module/FindosgViewer.rst
new file mode 100644
index 000000000..5def37544
--- /dev/null
+++ b/Help/module/FindosgViewer.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindosgViewer.cmake
diff --git a/Help/module/FindosgVolume.rst b/Help/module/FindosgVolume.rst
new file mode 100644
index 000000000..d836906e3
--- /dev/null
+++ b/Help/module/FindosgVolume.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindosgVolume.cmake
diff --git a/Help/module/FindosgWidget.rst b/Help/module/FindosgWidget.rst
new file mode 100644
index 000000000..bdd11355d
--- /dev/null
+++ b/Help/module/FindosgWidget.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindosgWidget.cmake
diff --git a/Help/module/Findosg_functions.rst b/Help/module/Findosg_functions.rst
new file mode 100644
index 000000000..522e1ac16
--- /dev/null
+++ b/Help/module/Findosg_functions.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/Findosg_functions.cmake
diff --git a/Help/module/FindwxWidgets.rst b/Help/module/FindwxWidgets.rst
new file mode 100644
index 000000000..519beb725
--- /dev/null
+++ b/Help/module/FindwxWidgets.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindwxWidgets.cmake
diff --git a/Help/module/FindwxWindows.rst b/Help/module/FindwxWindows.rst
new file mode 100644
index 000000000..35c972813
--- /dev/null
+++ b/Help/module/FindwxWindows.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindwxWindows.cmake
diff --git a/Help/module/FortranCInterface.rst b/Help/module/FortranCInterface.rst
new file mode 100644
index 000000000..7afcf154b
--- /dev/null
+++ b/Help/module/FortranCInterface.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FortranCInterface.cmake
diff --git a/Help/module/GNUInstallDirs.rst b/Help/module/GNUInstallDirs.rst
new file mode 100644
index 000000000..79d357040
--- /dev/null
+++ b/Help/module/GNUInstallDirs.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/GNUInstallDirs.cmake
diff --git a/Help/module/GenerateExportHeader.rst b/Help/module/GenerateExportHeader.rst
new file mode 100644
index 000000000..115713ecd
--- /dev/null
+++ b/Help/module/GenerateExportHeader.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/GenerateExportHeader.cmake
diff --git a/Help/module/GetPrerequisites.rst b/Help/module/GetPrerequisites.rst
new file mode 100644
index 000000000..84b20c876
--- /dev/null
+++ b/Help/module/GetPrerequisites.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/GetPrerequisites.cmake
diff --git a/Help/module/InstallRequiredSystemLibraries.rst b/Help/module/InstallRequiredSystemLibraries.rst
new file mode 100644
index 000000000..5ea9af33e
--- /dev/null
+++ b/Help/module/InstallRequiredSystemLibraries.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/InstallRequiredSystemLibraries.cmake
diff --git a/Help/module/MacroAddFileDependencies.rst b/Help/module/MacroAddFileDependencies.rst
new file mode 100644
index 000000000..5f0bf6bbf
--- /dev/null
+++ b/Help/module/MacroAddFileDependencies.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/MacroAddFileDependencies.cmake
diff --git a/Help/module/ProcessorCount.rst b/Help/module/ProcessorCount.rst
new file mode 100644
index 000000000..0149d0924
--- /dev/null
+++ b/Help/module/ProcessorCount.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/ProcessorCount.cmake
diff --git a/Help/module/SelectLibraryConfigurations.rst b/Help/module/SelectLibraryConfigurations.rst
new file mode 100644
index 000000000..14fd6f88a
--- /dev/null
+++ b/Help/module/SelectLibraryConfigurations.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/SelectLibraryConfigurations.cmake
diff --git a/Help/module/SquishTestScript.rst b/Help/module/SquishTestScript.rst
new file mode 100644
index 000000000..47da404f1
--- /dev/null
+++ b/Help/module/SquishTestScript.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/SquishTestScript.cmake
diff --git a/Help/module/TestBigEndian.rst b/Help/module/TestBigEndian.rst
new file mode 100644
index 000000000..f9e4d2f10
--- /dev/null
+++ b/Help/module/TestBigEndian.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/TestBigEndian.cmake
diff --git a/Help/module/TestCXXAcceptsFlag.rst b/Help/module/TestCXXAcceptsFlag.rst
new file mode 100644
index 000000000..ee3d70a71
--- /dev/null
+++ b/Help/module/TestCXXAcceptsFlag.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/TestCXXAcceptsFlag.cmake
diff --git a/Help/module/TestForANSIForScope.rst b/Help/module/TestForANSIForScope.rst
new file mode 100644
index 000000000..00d923803
--- /dev/null
+++ b/Help/module/TestForANSIForScope.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/TestForANSIForScope.cmake
diff --git a/Help/module/TestForANSIStreamHeaders.rst b/Help/module/TestForANSIStreamHeaders.rst
new file mode 100644
index 000000000..212a30b79
--- /dev/null
+++ b/Help/module/TestForANSIStreamHeaders.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/TestForANSIStreamHeaders.cmake
diff --git a/Help/module/TestForSSTREAM.rst b/Help/module/TestForSSTREAM.rst
new file mode 100644
index 000000000..d1547519e
--- /dev/null
+++ b/Help/module/TestForSSTREAM.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/TestForSSTREAM.cmake
diff --git a/Help/module/TestForSTDNamespace.rst b/Help/module/TestForSTDNamespace.rst
new file mode 100644
index 000000000..ad989e367
--- /dev/null
+++ b/Help/module/TestForSTDNamespace.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/TestForSTDNamespace.cmake
diff --git a/Help/module/UseEcos.rst b/Help/module/UseEcos.rst
new file mode 100644
index 000000000..0e578685a
--- /dev/null
+++ b/Help/module/UseEcos.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/UseEcos.cmake
diff --git a/Help/module/UseJava.rst b/Help/module/UseJava.rst
new file mode 100644
index 000000000..fa2f1bd6f
--- /dev/null
+++ b/Help/module/UseJava.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/UseJava.cmake
diff --git a/Help/module/UseJavaClassFilelist.rst b/Help/module/UseJavaClassFilelist.rst
new file mode 100644
index 000000000..b9cd4769e
--- /dev/null
+++ b/Help/module/UseJavaClassFilelist.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/UseJavaClassFilelist.cmake
diff --git a/Help/module/UseJavaSymlinks.rst b/Help/module/UseJavaSymlinks.rst
new file mode 100644
index 000000000..2fab8e8dd
--- /dev/null
+++ b/Help/module/UseJavaSymlinks.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/UseJavaSymlinks.cmake
diff --git a/Help/module/UsePkgConfig.rst b/Help/module/UsePkgConfig.rst
new file mode 100644
index 000000000..668f7662b
--- /dev/null
+++ b/Help/module/UsePkgConfig.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/UsePkgConfig.cmake
diff --git a/Help/module/UseSWIG.rst b/Help/module/UseSWIG.rst
new file mode 100644
index 000000000..0007c355c
--- /dev/null
+++ b/Help/module/UseSWIG.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/UseSWIG.cmake
diff --git a/Help/module/Use_wxWindows.rst b/Help/module/Use_wxWindows.rst
new file mode 100644
index 000000000..a489e9849
--- /dev/null
+++ b/Help/module/Use_wxWindows.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/Use_wxWindows.cmake
diff --git a/Help/module/UsewxWidgets.rst b/Help/module/UsewxWidgets.rst
new file mode 100644
index 000000000..6829c2d2b
--- /dev/null
+++ b/Help/module/UsewxWidgets.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/UsewxWidgets.cmake
diff --git a/Help/module/WriteBasicConfigVersionFile.rst b/Help/module/WriteBasicConfigVersionFile.rst
new file mode 100644
index 000000000..c637d5dc2
--- /dev/null
+++ b/Help/module/WriteBasicConfigVersionFile.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/WriteBasicConfigVersionFile.cmake
diff --git a/Help/module/WriteCompilerDetectionHeader.rst b/Help/module/WriteCompilerDetectionHeader.rst
new file mode 100644
index 000000000..4c81b4883
--- /dev/null
+++ b/Help/module/WriteCompilerDetectionHeader.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/WriteCompilerDetectionHeader.cmake
diff --git a/Help/policy/CMP0000.rst b/Help/policy/CMP0000.rst
new file mode 100644
index 000000000..97ea633b2
--- /dev/null
+++ b/Help/policy/CMP0000.rst
@@ -0,0 +1,32 @@
+CMP0000
+-------
+
+A minimum required CMake version must be specified.
+
+CMake requires that projects specify the version of CMake to which
+they have been written. This policy has been put in place so users
+trying to build the project may be told when they need to update their
+CMake. Specifying a version also helps the project build with CMake
+versions newer than that specified. Use the cmake_minimum_required
+command at the top of your main CMakeLists.txt file:
+
+::
+
+ cmake_minimum_required(VERSION <major>.<minor>)
+
+where "<major>.<minor>" is the version of CMake you want to support
+(such as "2.6"). The command will ensure that at least the given
+version of CMake is running and help newer versions be compatible with
+the project. See documentation of cmake_minimum_required for details.
+
+Note that the command invocation must appear in the CMakeLists.txt
+file itself; a call in an included file is not sufficient. However,
+the cmake_policy command may be called to set policy CMP0000 to OLD or
+NEW behavior explicitly. The OLD behavior is to silently ignore the
+missing invocation. The NEW behavior is to issue an error instead of
+a warning. An included file may set CMP0000 explicitly to affect how
+this policy is enforced for the main CMakeLists.txt file.
+
+This policy was introduced in CMake version 2.6.0.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0001.rst b/Help/policy/CMP0001.rst
new file mode 100644
index 000000000..09ad38702
--- /dev/null
+++ b/Help/policy/CMP0001.rst
@@ -0,0 +1,21 @@
+CMP0001
+-------
+
+CMAKE_BACKWARDS_COMPATIBILITY should no longer be used.
+
+The OLD behavior is to check CMAKE_BACKWARDS_COMPATIBILITY and present
+it to the user. The NEW behavior is to ignore
+CMAKE_BACKWARDS_COMPATIBILITY completely.
+
+In CMake 2.4 and below the variable CMAKE_BACKWARDS_COMPATIBILITY was
+used to request compatibility with earlier versions of CMake. In
+CMake 2.6 and above all compatibility issues are handled by policies
+and the cmake_policy command. However, CMake must still check
+CMAKE_BACKWARDS_COMPATIBILITY for projects written for CMake 2.4 and
+below.
+
+This policy was introduced in CMake version 2.6.0. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0002.rst b/Help/policy/CMP0002.rst
new file mode 100644
index 000000000..7cc53efa1
--- /dev/null
+++ b/Help/policy/CMP0002.rst
@@ -0,0 +1,28 @@
+CMP0002
+-------
+
+Logical target names must be globally unique.
+
+Targets names created with add_executable, add_library, or
+add_custom_target are logical build target names. Logical target
+names must be globally unique because:
+
+::
+
+ - Unique names may be referenced unambiguously both in CMake
+ code and on make tool command lines.
+ - Logical names are used by Xcode and VS IDE generators
+ to produce meaningful project names for the targets.
+
+The logical name of executable and library targets does not have to
+correspond to the physical file names built. Consider using the
+OUTPUT_NAME target property to create two targets with the same
+physical name while keeping logical names distinct. Custom targets
+must simply have globally unique names (unless one uses the global
+property ALLOW_DUPLICATE_CUSTOM_TARGETS with a Makefiles generator).
+
+This policy was introduced in CMake version 2.6.0. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0003.rst b/Help/policy/CMP0003.rst
new file mode 100644
index 000000000..16b045165
--- /dev/null
+++ b/Help/policy/CMP0003.rst
@@ -0,0 +1,104 @@
+CMP0003
+-------
+
+Libraries linked via full path no longer produce linker search paths.
+
+This policy affects how libraries whose full paths are NOT known are
+found at link time, but was created due to a change in how CMake deals
+with libraries whose full paths are known. Consider the code
+
+::
+
+ target_link_libraries(myexe /path/to/libA.so)
+
+CMake 2.4 and below implemented linking to libraries whose full paths
+are known by splitting them on the link line into separate components
+consisting of the linker search path and the library name. The
+example code might have produced something like
+
+::
+
+ ... -L/path/to -lA ...
+
+in order to link to library A. An analysis was performed to order
+multiple link directories such that the linker would find library A in
+the desired location, but there are cases in which this does not work.
+CMake versions 2.6 and above use the more reliable approach of passing
+the full path to libraries directly to the linker in most cases. The
+example code now produces something like
+
+::
+
+ ... /path/to/libA.so ....
+
+Unfortunately this change can break code like
+
+::
+
+ target_link_libraries(myexe /path/to/libA.so B)
+
+where "B" is meant to find "/path/to/libB.so". This code is wrong
+because the user is asking the linker to find library B but has not
+provided a linker search path (which may be added with the
+link_directories command). However, with the old linking
+implementation the code would work accidentally because the linker
+search path added for library A allowed library B to be found.
+
+In order to support projects depending on linker search paths added by
+linking to libraries with known full paths, the OLD behavior for this
+policy will add the linker search paths even though they are not
+needed for their own libraries. When this policy is set to OLD, CMake
+will produce a link line such as
+
+::
+
+ ... -L/path/to /path/to/libA.so -lB ...
+
+which will allow library B to be found as it was previously. When
+this policy is set to NEW, CMake will produce a link line such as
+
+::
+
+ ... /path/to/libA.so -lB ...
+
+which more accurately matches what the project specified.
+
+The setting for this policy used when generating the link line is that
+in effect when the target is created by an add_executable or
+add_library command. For the example described above, the code
+
+::
+
+ cmake_policy(SET CMP0003 OLD) # or cmake_policy(VERSION 2.4)
+ add_executable(myexe myexe.c)
+ target_link_libraries(myexe /path/to/libA.so B)
+
+will work and suppress the warning for this policy. It may also be
+updated to work with the corrected linking approach:
+
+::
+
+ cmake_policy(SET CMP0003 NEW) # or cmake_policy(VERSION 2.6)
+ link_directories(/path/to) # needed to find library B
+ add_executable(myexe myexe.c)
+ target_link_libraries(myexe /path/to/libA.so B)
+
+Even better, library B may be specified with a full path:
+
+::
+
+ add_executable(myexe myexe.c)
+ target_link_libraries(myexe /path/to/libA.so /path/to/libB.so)
+
+When all items on the link line have known paths CMake does not check
+this policy so it has no effect.
+
+Note that the warning for this policy will be issued for at most one
+target. This avoids flooding users with messages for every target
+when setting the policy once will probably fix all targets.
+
+This policy was introduced in CMake version 2.6.0. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0004.rst b/Help/policy/CMP0004.rst
new file mode 100644
index 000000000..55da4d293
--- /dev/null
+++ b/Help/policy/CMP0004.rst
@@ -0,0 +1,25 @@
+CMP0004
+-------
+
+Libraries linked may not have leading or trailing whitespace.
+
+CMake versions 2.4 and below silently removed leading and trailing
+whitespace from libraries linked with code like
+
+::
+
+ target_link_libraries(myexe " A ")
+
+This could lead to subtle errors in user projects.
+
+The OLD behavior for this policy is to silently remove leading and
+trailing whitespace. The NEW behavior for this policy is to diagnose
+the existence of such whitespace as an error. The setting for this
+policy used when checking the library names is that in effect when the
+target is created by an add_executable or add_library command.
+
+This policy was introduced in CMake version 2.6.0. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0005.rst b/Help/policy/CMP0005.rst
new file mode 100644
index 000000000..66d125fb7
--- /dev/null
+++ b/Help/policy/CMP0005.rst
@@ -0,0 +1,26 @@
+CMP0005
+-------
+
+Preprocessor definition values are now escaped automatically.
+
+This policy determines whether or not CMake should generate escaped
+preprocessor definition values added via add_definitions. CMake
+versions 2.4 and below assumed that only trivial values would be given
+for macros in add_definitions calls. It did not attempt to escape
+non-trivial values such as string literals in generated build rules.
+CMake versions 2.6 and above support escaping of most values, but
+cannot assume the user has not added escapes already in an attempt to
+work around limitations in earlier versions.
+
+The OLD behavior for this policy is to place definition values given
+to add_definitions directly in the generated build rules without
+attempting to escape anything. The NEW behavior for this policy is to
+generate correct escapes for all native build tools automatically.
+See documentation of the COMPILE_DEFINITIONS target property for
+limitations of the escaping implementation.
+
+This policy was introduced in CMake version 2.6.0. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0006.rst b/Help/policy/CMP0006.rst
new file mode 100644
index 000000000..d1b9ece7f
--- /dev/null
+++ b/Help/policy/CMP0006.rst
@@ -0,0 +1,24 @@
+CMP0006
+-------
+
+Installing MACOSX_BUNDLE targets requires a BUNDLE DESTINATION.
+
+This policy determines whether the install(TARGETS) command must be
+given a BUNDLE DESTINATION when asked to install a target with the
+MACOSX_BUNDLE property set. CMake 2.4 and below did not distinguish
+application bundles from normal executables when installing targets.
+CMake 2.6 provides a BUNDLE option to the install(TARGETS) command
+that specifies rules specific to application bundles on the Mac.
+Projects should use this option when installing a target with the
+MACOSX_BUNDLE property set.
+
+The OLD behavior for this policy is to fall back to the RUNTIME
+DESTINATION if a BUNDLE DESTINATION is not given. The NEW behavior
+for this policy is to produce an error if a bundle target is installed
+without a BUNDLE DESTINATION.
+
+This policy was introduced in CMake version 2.6.0. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0007.rst b/Help/policy/CMP0007.rst
new file mode 100644
index 000000000..39276457a
--- /dev/null
+++ b/Help/policy/CMP0007.rst
@@ -0,0 +1,17 @@
+CMP0007
+-------
+
+list command no longer ignores empty elements.
+
+This policy determines whether the list command will ignore empty
+elements in the list. CMake 2.4 and below list commands ignored all
+empty elements in the list. For example, a;b;;c would have length 3
+and not 4. The OLD behavior for this policy is to ignore empty list
+elements. The NEW behavior for this policy is to correctly count
+empty elements in a list.
+
+This policy was introduced in CMake version 2.6.0. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0008.rst b/Help/policy/CMP0008.rst
new file mode 100644
index 000000000..f1e2ddde5
--- /dev/null
+++ b/Help/policy/CMP0008.rst
@@ -0,0 +1,34 @@
+CMP0008
+-------
+
+Libraries linked by full-path must have a valid library file name.
+
+In CMake 2.4 and below it is possible to write code like
+
+::
+
+ target_link_libraries(myexe /full/path/to/somelib)
+
+where "somelib" is supposed to be a valid library file name such as
+"libsomelib.a" or "somelib.lib". For Makefile generators this
+produces an error at build time because the dependency on the full
+path cannot be found. For VS IDE and Xcode generators this used to
+work by accident because CMake would always split off the library
+directory and ask the linker to search for the library by name
+(-lsomelib or somelib.lib). Despite the failure with Makefiles, some
+projects have code like this and build only with VS and/or Xcode.
+This version of CMake prefers to pass the full path directly to the
+native build tool, which will fail in this case because it does not
+name a valid library file.
+
+This policy determines what to do with full paths that do not appear
+to name a valid library file. The OLD behavior for this policy is to
+split the library name from the path and ask the linker to search for
+it. The NEW behavior for this policy is to trust the given path and
+pass it directly to the native build tool unchanged.
+
+This policy was introduced in CMake version 2.6.1. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0009.rst b/Help/policy/CMP0009.rst
new file mode 100644
index 000000000..44baeb449
--- /dev/null
+++ b/Help/policy/CMP0009.rst
@@ -0,0 +1,21 @@
+CMP0009
+-------
+
+FILE GLOB_RECURSE calls should not follow symlinks by default.
+
+In CMake 2.6.1 and below, FILE GLOB_RECURSE calls would follow through
+symlinks, sometimes coming up with unexpectedly large result sets
+because of symlinks to top level directories that contain hundreds of
+thousands of files.
+
+This policy determines whether or not to follow symlinks encountered
+during a FILE GLOB_RECURSE call. The OLD behavior for this policy is
+to follow the symlinks. The NEW behavior for this policy is not to
+follow the symlinks by default, but only if FOLLOW_SYMLINKS is given
+as an additional argument to the FILE command.
+
+This policy was introduced in CMake version 2.6.2. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0010.rst b/Help/policy/CMP0010.rst
new file mode 100644
index 000000000..344d70475
--- /dev/null
+++ b/Help/policy/CMP0010.rst
@@ -0,0 +1,20 @@
+CMP0010
+-------
+
+Bad variable reference syntax is an error.
+
+In CMake 2.6.2 and below, incorrect variable reference syntax such as
+a missing close-brace ("${FOO") was reported but did not stop
+processing of CMake code. This policy determines whether a bad
+variable reference is an error. The OLD behavior for this policy is
+to warn about the error, leave the string untouched, and continue.
+The NEW behavior for this policy is to report an error.
+
+If :policy:`CMP0053` is set to ``NEW``, this policy has no effect
+and is treated as always being ``NEW``.
+
+This policy was introduced in CMake version 2.6.3. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0011.rst b/Help/policy/CMP0011.rst
new file mode 100644
index 000000000..d281e0ef7
--- /dev/null
+++ b/Help/policy/CMP0011.rst
@@ -0,0 +1,24 @@
+CMP0011
+-------
+
+Included scripts do automatic cmake_policy PUSH and POP.
+
+In CMake 2.6.2 and below, CMake Policy settings in scripts loaded by
+the include() and find_package() commands would affect the includer.
+Explicit invocations of cmake_policy(PUSH) and cmake_policy(POP) were
+required to isolate policy changes and protect the includer. While
+some scripts intend to affect the policies of their includer, most do
+not. In CMake 2.6.3 and above, include() and find_package() by
+default PUSH and POP an entry on the policy stack around an included
+script, but provide a NO_POLICY_SCOPE option to disable it. This
+policy determines whether or not to imply NO_POLICY_SCOPE for
+compatibility. The OLD behavior for this policy is to imply
+NO_POLICY_SCOPE for include() and find_package() commands. The NEW
+behavior for this policy is to allow the commands to do their default
+cmake_policy PUSH and POP.
+
+This policy was introduced in CMake version 2.6.3. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0012.rst b/Help/policy/CMP0012.rst
new file mode 100644
index 000000000..85d64f4d4
--- /dev/null
+++ b/Help/policy/CMP0012.rst
@@ -0,0 +1,27 @@
+CMP0012
+-------
+
+if() recognizes numbers and boolean constants.
+
+In CMake versions 2.6.4 and lower the if() command implicitly
+dereferenced arguments corresponding to variables, even those named
+like numbers or boolean constants, except for 0 and 1. Numbers and
+boolean constants such as true, false, yes, no, on, off, y, n,
+notfound, ignore (all case insensitive) were recognized in some cases
+but not all. For example, the code "if(TRUE)" might have evaluated as
+false. Numbers such as 2 were recognized only in boolean expressions
+like "if(NOT 2)" (leading to false) but not as a single-argument like
+"if(2)" (also leading to false). Later versions of CMake prefer to
+treat numbers and boolean constants literally, so they should not be
+used as variable names.
+
+The OLD behavior for this policy is to implicitly dereference
+variables named like numbers and boolean constants. The NEW behavior
+for this policy is to recognize numbers and boolean constants without
+dereferencing variables with such names.
+
+This policy was introduced in CMake version 2.8.0. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0013.rst b/Help/policy/CMP0013.rst
new file mode 100644
index 000000000..2fabb8920
--- /dev/null
+++ b/Help/policy/CMP0013.rst
@@ -0,0 +1,21 @@
+CMP0013
+-------
+
+Duplicate binary directories are not allowed.
+
+CMake 2.6.3 and below silently permitted add_subdirectory() calls to
+create the same binary directory multiple times. During build system
+generation files would be written and then overwritten in the build
+tree and could lead to strange behavior. CMake 2.6.4 and above
+explicitly detect duplicate binary directories. CMake 2.6.4 always
+considers this case an error. In CMake 2.8.0 and above this policy
+determines whether or not the case is an error. The OLD behavior for
+this policy is to allow duplicate binary directories. The NEW
+behavior for this policy is to disallow duplicate binary directories
+with an error.
+
+This policy was introduced in CMake version 2.8.0. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0014.rst b/Help/policy/CMP0014.rst
new file mode 100644
index 000000000..f1f7b77b8
--- /dev/null
+++ b/Help/policy/CMP0014.rst
@@ -0,0 +1,17 @@
+CMP0014
+-------
+
+Input directories must have CMakeLists.txt.
+
+CMake versions before 2.8 silently ignored missing CMakeLists.txt
+files in directories referenced by add_subdirectory() or subdirs(),
+treating them as if present but empty. In CMake 2.8.0 and above this
+policy determines whether or not the case is an error. The OLD
+behavior for this policy is to silently ignore the problem. The NEW
+behavior for this policy is to report an error.
+
+This policy was introduced in CMake version 2.8.0. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0015.rst b/Help/policy/CMP0015.rst
new file mode 100644
index 000000000..9a48e3dac
--- /dev/null
+++ b/Help/policy/CMP0015.rst
@@ -0,0 +1,19 @@
+CMP0015
+-------
+
+link_directories() treats paths relative to the source dir.
+
+In CMake 2.8.0 and lower the link_directories() command passed
+relative paths unchanged to the linker. In CMake 2.8.1 and above the
+link_directories() command prefers to interpret relative paths with
+respect to CMAKE_CURRENT_SOURCE_DIR, which is consistent with
+include_directories() and other commands. The OLD behavior for this
+policy is to use relative paths verbatim in the linker command. The
+NEW behavior for this policy is to convert relative paths to absolute
+paths by appending the relative path to CMAKE_CURRENT_SOURCE_DIR.
+
+This policy was introduced in CMake version 2.8.1. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0016.rst b/Help/policy/CMP0016.rst
new file mode 100644
index 000000000..cc898c8ca
--- /dev/null
+++ b/Help/policy/CMP0016.rst
@@ -0,0 +1,15 @@
+CMP0016
+-------
+
+target_link_libraries() reports error if its only argument is not a target.
+
+In CMake 2.8.2 and lower the target_link_libraries() command silently
+ignored if it was called with only one argument, and this argument
+wasn't a valid target. In CMake 2.8.3 and above it reports an error
+in this case.
+
+This policy was introduced in CMake version 2.8.3. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0017.rst b/Help/policy/CMP0017.rst
new file mode 100644
index 000000000..9f0f0380f
--- /dev/null
+++ b/Help/policy/CMP0017.rst
@@ -0,0 +1,21 @@
+CMP0017
+-------
+
+Prefer files from the CMake module directory when including from there.
+
+Starting with CMake 2.8.4, if a cmake-module shipped with CMake (i.e.
+located in the CMake module directory) calls include() or
+find_package(), the files located in the CMake module directory are
+preferred over the files in CMAKE_MODULE_PATH. This makes sure that
+the modules belonging to CMake always get those files included which
+they expect, and against which they were developed and tested. In all
+other cases, the files found in CMAKE_MODULE_PATH still take
+precedence over the ones in the CMake module directory. The OLD
+behavior is to always prefer files from CMAKE_MODULE_PATH over files
+from the CMake modules directory.
+
+This policy was introduced in CMake version 2.8.4. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0018.rst b/Help/policy/CMP0018.rst
new file mode 100644
index 000000000..a3a7a12bd
--- /dev/null
+++ b/Help/policy/CMP0018.rst
@@ -0,0 +1,34 @@
+CMP0018
+-------
+
+Ignore CMAKE_SHARED_LIBRARY_<Lang>_FLAGS variable.
+
+CMake 2.8.8 and lower compiled sources in SHARED and MODULE libraries
+using the value of the undocumented CMAKE_SHARED_LIBRARY_<Lang>_FLAGS
+platform variable. The variable contained platform-specific flags
+needed to compile objects for shared libraries. Typically it included
+a flag such as -fPIC for position independent code but also included
+other flags needed on certain platforms. CMake 2.8.9 and higher
+prefer instead to use the POSITION_INDEPENDENT_CODE target property to
+determine what targets should be position independent, and new
+undocumented platform variables to select flags while ignoring
+CMAKE_SHARED_LIBRARY_<Lang>_FLAGS completely.
+
+The default for either approach produces identical compilation flags,
+but if a project modifies CMAKE_SHARED_LIBRARY_<Lang>_FLAGS from its
+original value this policy determines which approach to use.
+
+The OLD behavior for this policy is to ignore the
+POSITION_INDEPENDENT_CODE property for all targets and use the
+modified value of CMAKE_SHARED_LIBRARY_<Lang>_FLAGS for SHARED and
+MODULE libraries.
+
+The NEW behavior for this policy is to ignore
+CMAKE_SHARED_LIBRARY_<Lang>_FLAGS whether it is modified or not and
+honor the POSITION_INDEPENDENT_CODE target property.
+
+This policy was introduced in CMake version 2.8.9. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0019.rst b/Help/policy/CMP0019.rst
new file mode 100644
index 000000000..2e3557d32
--- /dev/null
+++ b/Help/policy/CMP0019.rst
@@ -0,0 +1,22 @@
+CMP0019
+-------
+
+Do not re-expand variables in include and link information.
+
+CMake 2.8.10 and lower re-evaluated values given to the
+include_directories, link_directories, and link_libraries commands to
+expand any leftover variable references at the end of the
+configuration step. This was for strict compatibility with VERY early
+CMake versions because all variable references are now normally
+evaluated during CMake language processing. CMake 2.8.11 and higher
+prefer to skip the extra evaluation.
+
+The OLD behavior for this policy is to re-evaluate the values for
+strict compatibility. The NEW behavior for this policy is to leave
+the values untouched.
+
+This policy was introduced in CMake version 2.8.11. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0020.rst b/Help/policy/CMP0020.rst
new file mode 100644
index 000000000..75ca9deb2
--- /dev/null
+++ b/Help/policy/CMP0020.rst
@@ -0,0 +1,27 @@
+CMP0020
+-------
+
+Automatically link Qt executables to qtmain target on Windows.
+
+CMake 2.8.10 and lower required users of Qt to always specify a link
+dependency to the qtmain.lib static library manually on Windows.
+CMake 2.8.11 gained the ability to evaluate generator expressions
+while determining the link dependencies from IMPORTED targets. This
+allows CMake itself to automatically link executables which link to Qt
+to the qtmain.lib library when using IMPORTED Qt targets. For
+applications already linking to qtmain.lib, this should have little
+impact. For applications which supply their own alternative WinMain
+implementation and for applications which use the QAxServer library,
+this automatic linking will need to be disabled as per the
+documentation.
+
+The OLD behavior for this policy is not to link executables to
+qtmain.lib automatically when they link to the QtCore IMPORTED target.
+The NEW behavior for this policy is to link executables to qtmain.lib
+automatically when they link to QtCore IMPORTED target.
+
+This policy was introduced in CMake version 2.8.11. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0021.rst b/Help/policy/CMP0021.rst
new file mode 100644
index 000000000..3a792ca14
--- /dev/null
+++ b/Help/policy/CMP0021.rst
@@ -0,0 +1,20 @@
+CMP0021
+-------
+
+Fatal error on relative paths in INCLUDE_DIRECTORIES target property.
+
+CMake 2.8.10.2 and lower allowed the INCLUDE_DIRECTORIES target
+property to contain relative paths. The base path for such relative
+entries is not well defined. CMake 2.8.12 issues a FATAL_ERROR if the
+INCLUDE_DIRECTORIES property contains a relative path.
+
+The OLD behavior for this policy is not to warn about relative paths
+in the INCLUDE_DIRECTORIES target property. The NEW behavior for this
+policy is to issue a FATAL_ERROR if INCLUDE_DIRECTORIES contains a
+relative path.
+
+This policy was introduced in CMake version 2.8.12. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0022.rst b/Help/policy/CMP0022.rst
new file mode 100644
index 000000000..579d09ac0
--- /dev/null
+++ b/Help/policy/CMP0022.rst
@@ -0,0 +1,39 @@
+CMP0022
+-------
+
+INTERFACE_LINK_LIBRARIES defines the link interface.
+
+CMake 2.8.11 constructed the 'link interface' of a target from
+properties matching ``(IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)?``.
+The modern way to specify config-sensitive content is to use generator
+expressions and the ``IMPORTED_`` prefix makes uniform processing of the
+link interface with generator expressions impossible. The
+INTERFACE_LINK_LIBRARIES target property was introduced as a
+replacement in CMake 2.8.12. This new property is named consistently
+with the INTERFACE_COMPILE_DEFINITIONS, INTERFACE_INCLUDE_DIRECTORIES
+and INTERFACE_COMPILE_OPTIONS properties. For in-build targets, CMake
+will use the INTERFACE_LINK_LIBRARIES property as the source of the
+link interface only if policy CMP0022 is NEW. When exporting a target
+which has this policy set to NEW, only the INTERFACE_LINK_LIBRARIES
+property will be processed and generated for the IMPORTED target by
+default. A new option to the install(EXPORT) and export commands
+allows export of the old-style properties for compatibility with
+downstream users of CMake versions older than 2.8.12. The
+target_link_libraries command will no longer populate the properties
+matching LINK_INTERFACE_LIBRARIES(_<CONFIG>)? if this policy is NEW.
+
+Warning-free future-compatible code which works with CMake 2.8.7 onwards
+can be written by using the ``LINK_PRIVATE`` and ``LINK_PUBLIC`` keywords
+of :command:`target_link_libraries`.
+
+The OLD behavior for this policy is to ignore the
+INTERFACE_LINK_LIBRARIES property for in-build targets. The NEW
+behavior for this policy is to use the INTERFACE_LINK_LIBRARIES
+property for in-build targets, and ignore the old properties matching
+``(IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)?``.
+
+This policy was introduced in CMake version 2.8.12. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0023.rst b/Help/policy/CMP0023.rst
new file mode 100644
index 000000000..76a4900b6
--- /dev/null
+++ b/Help/policy/CMP0023.rst
@@ -0,0 +1,35 @@
+CMP0023
+-------
+
+Plain and keyword target_link_libraries signatures cannot be mixed.
+
+CMake 2.8.12 introduced the target_link_libraries signature using the
+PUBLIC, PRIVATE, and INTERFACE keywords to generalize the LINK_PUBLIC
+and LINK_PRIVATE keywords introduced in CMake 2.8.7. Use of
+signatures with any of these keywords sets the link interface of a
+target explicitly, even if empty. This produces confusing behavior
+when used in combination with the historical behavior of the plain
+target_link_libraries signature. For example, consider the code:
+
+::
+
+ target_link_libraries(mylib A)
+ target_link_libraries(mylib PRIVATE B)
+
+After the first line the link interface has not been set explicitly so
+CMake would use the link implementation, A, as the link interface.
+However, the second line sets the link interface to empty. In order
+to avoid this subtle behavior CMake now prefers to disallow mixing the
+plain and keyword signatures of target_link_libraries for a single
+target.
+
+The OLD behavior for this policy is to allow keyword and plain
+target_link_libraries signatures to be mixed. The NEW behavior for
+this policy is to not to allow mixing of the keyword and plain
+signatures.
+
+This policy was introduced in CMake version 2.8.12. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0024.rst b/Help/policy/CMP0024.rst
new file mode 100644
index 000000000..272a56c8d
--- /dev/null
+++ b/Help/policy/CMP0024.rst
@@ -0,0 +1,24 @@
+CMP0024
+-------
+
+Disallow include export result.
+
+CMake 2.8.12 and lower allowed use of the include() command with the
+result of the export() command. This relies on the assumption that
+the export() command has an immediate effect at configure-time during
+a cmake run. Certain properties of targets are not fully determined
+until later at generate-time, such as the link language and complete
+list of link libraries. Future refactoring will change the effect of
+the export() command to be executed at generate-time. Use ALIAS
+targets instead in cases where the goal is to refer to targets by
+another name.
+
+The OLD behavior for this policy is to allow including the result of
+an export() command. The NEW behavior for this policy is not to
+allow including the result of an export() command.
+
+This policy was introduced in CMake version 3.0. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0025.rst b/Help/policy/CMP0025.rst
new file mode 100644
index 000000000..62dd50985
--- /dev/null
+++ b/Help/policy/CMP0025.rst
@@ -0,0 +1,29 @@
+CMP0025
+-------
+
+Compiler id for Apple Clang is now ``AppleClang``.
+
+CMake 3.0 and above recognize that Apple Clang is a different compiler
+than upstream Clang and that they have different version numbers.
+CMake now prefers to present this to projects by setting the
+:variable:`CMAKE_<LANG>_COMPILER_ID` variable to ``AppleClang`` instead
+of ``Clang``. However, existing projects may assume the compiler id for
+Apple Clang is just ``Clang`` as it was in CMake versions prior to 3.0.
+Therefore this policy determines for Apple Clang which compiler id to
+report in the :variable:`CMAKE_<LANG>_COMPILER_ID` variable after
+language ``<LANG>`` is enabled by the :command:`project` or
+:command:`enable_language` command. The policy must be set prior
+to the invocation of either command.
+
+The OLD behavior for this policy is to use compiler id ``Clang``. The
+NEW behavior for this policy is to use compiler id ``AppleClang``.
+
+This policy was introduced in CMake version 3.0. Use the
+:command:`cmake_policy` command to set this policy to OLD or NEW explicitly.
+Unlike most policies, CMake version |release| does *not* warn
+by default when this policy is not set and simply uses OLD behavior.
+See documentation of the
+:variable:`CMAKE_POLICY_WARNING_CMP0025 <CMAKE_POLICY_WARNING_CMP<NNNN>>`
+variable to control the warning.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0026.rst b/Help/policy/CMP0026.rst
new file mode 100644
index 000000000..3fe1374c8
--- /dev/null
+++ b/Help/policy/CMP0026.rst
@@ -0,0 +1,28 @@
+CMP0026
+-------
+
+Disallow use of the LOCATION property for build targets.
+
+CMake 2.8.12 and lower allowed reading the LOCATION target
+property (and configuration-specific variants) to
+determine the eventual location of build targets. This relies on the
+assumption that all necessary information is available at
+configure-time to determine the final location and filename of the
+target. However, this property is not fully determined until later at
+generate-time. At generate time, the $<TARGET_FILE> generator
+expression can be used to determine the eventual LOCATION of a target
+output.
+
+Code which reads the LOCATION target property can be ported to use the
+$<TARGET_FILE> generator expression together with the file(GENERATE)
+subcommand to generate a file containing the target location.
+
+The OLD behavior for this policy is to allow reading the LOCATION
+properties from build-targets. The NEW behavior for this policy is to
+not to allow reading the LOCATION properties from build-targets.
+
+This policy was introduced in CMake version 3.0. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0027.rst b/Help/policy/CMP0027.rst
new file mode 100644
index 000000000..28913cee4
--- /dev/null
+++ b/Help/policy/CMP0027.rst
@@ -0,0 +1,27 @@
+CMP0027
+-------
+
+Conditionally linked imported targets with missing include directories.
+
+CMake 2.8.11 introduced introduced the concept of
+INTERFACE_INCLUDE_DIRECTORIES, and a check at cmake time that the
+entries in the INTERFACE_INCLUDE_DIRECTORIES of an IMPORTED target
+actually exist. CMake 2.8.11 also introduced generator expression
+support in the target_link_libraries command. However, if an imported
+target is linked as a result of a generator expression evaluation, the
+entries in the INTERFACE_INCLUDE_DIRECTORIES of that target were not
+checked for existence as they should be.
+
+The OLD behavior of this policy is to report a warning if an entry in
+the INTERFACE_INCLUDE_DIRECTORIES of a generator-expression
+conditionally linked IMPORTED target does not exist.
+
+The NEW behavior of this policy is to report an error if an entry in
+the INTERFACE_INCLUDE_DIRECTORIES of a generator-expression
+conditionally linked IMPORTED target does not exist.
+
+This policy was introduced in CMake version 3.0. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0028.rst b/Help/policy/CMP0028.rst
new file mode 100644
index 000000000..be57125d4
--- /dev/null
+++ b/Help/policy/CMP0028.rst
@@ -0,0 +1,25 @@
+CMP0028
+-------
+
+Double colon in target name means ALIAS or IMPORTED target.
+
+CMake 2.8.12 and lower allowed the use of targets and files with double
+colons in target_link_libraries, with some buildsystem generators.
+
+The use of double-colons is a common pattern used to namespace IMPORTED
+targets and ALIAS targets. When computing the link dependencies of a target,
+the name of each dependency could either be a target, or a file on disk.
+Previously, if a target was not found with a matching name, the name was
+considered to refer to a file on disk. This can lead to confusing error
+messages if there is a typo in what should be a target name.
+
+The OLD behavior for this policy is to search for targets, then files on disk,
+even if the search term contains double-colons. The NEW behavior for this
+policy is to issue a FATAL_ERROR if a link dependency contains
+double-colons but is not an IMPORTED target or an ALIAS target.
+
+This policy was introduced in CMake version 3.0. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0029.rst b/Help/policy/CMP0029.rst
new file mode 100644
index 000000000..aa10b97a9
--- /dev/null
+++ b/Help/policy/CMP0029.rst
@@ -0,0 +1,12 @@
+CMP0029
+-------
+
+The :command:`subdir_depends` command should not be called.
+
+The implementation of this command has been empty since December 2001
+but was kept in CMake for compatibility for a long time.
+
+.. |disallowed_version| replace:: 3.0
+.. include:: DISALLOWED_COMMAND.txt
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0030.rst b/Help/policy/CMP0030.rst
new file mode 100644
index 000000000..81bbb84e8
--- /dev/null
+++ b/Help/policy/CMP0030.rst
@@ -0,0 +1,13 @@
+CMP0030
+-------
+
+The :command:`use_mangled_mesa` command should not be called.
+
+This command was created in September 2001 to support VTK before
+modern CMake language and custom command capabilities. VTK has
+not used it in years.
+
+.. |disallowed_version| replace:: 3.0
+.. include:: DISALLOWED_COMMAND.txt
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0031.rst b/Help/policy/CMP0031.rst
new file mode 100644
index 000000000..8c3eef62a
--- /dev/null
+++ b/Help/policy/CMP0031.rst
@@ -0,0 +1,15 @@
+CMP0031
+-------
+
+The :command:`load_command` command should not be called.
+
+This command was added in August 2002 to allow projects to add
+arbitrary commands implemented in C or C++. However, it does
+not work when the toolchain in use does not match the ABI of
+the CMake process. It has been mostly superseded by the
+:command:`macro` and :command:`function` commands.
+
+.. |disallowed_version| replace:: 3.0
+.. include:: DISALLOWED_COMMAND.txt
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0032.rst b/Help/policy/CMP0032.rst
new file mode 100644
index 000000000..5c1fa4be2
--- /dev/null
+++ b/Help/policy/CMP0032.rst
@@ -0,0 +1,15 @@
+CMP0032
+-------
+
+The :command:`output_required_files` command should not be called.
+
+This command was added in June 2001 to expose the then-current CMake
+implicit dependency scanner. CMake's real implicit dependency scanner
+has evolved since then but is not exposed through this command. The
+scanning capabilities of this command are very limited and this
+functionality is better achieved through dedicated outside tools.
+
+.. |disallowed_version| replace:: 3.0
+.. include:: DISALLOWED_COMMAND.txt
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0033.rst b/Help/policy/CMP0033.rst
new file mode 100644
index 000000000..4a6cc591d
--- /dev/null
+++ b/Help/policy/CMP0033.rst
@@ -0,0 +1,16 @@
+CMP0033
+-------
+
+The :command:`export_library_dependencies` command should not be called.
+
+This command was added in January 2003 to export ``<tgt>_LIB_DEPENDS``
+internal CMake cache entries to a file for installation with a project.
+This was used at the time to allow transitive link dependencies to
+work for applications outside of the original build tree of a project.
+The functionality has been superseded by the :command:`export` and
+:command:`install(EXPORT)` commands.
+
+.. |disallowed_version| replace:: 3.0
+.. include:: DISALLOWED_COMMAND.txt
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0034.rst b/Help/policy/CMP0034.rst
new file mode 100644
index 000000000..0f3934aae
--- /dev/null
+++ b/Help/policy/CMP0034.rst
@@ -0,0 +1,13 @@
+CMP0034
+-------
+
+The :command:`utility_source` command should not be called.
+
+This command was introduced in March 2001 to help build executables used to
+generate other files. This approach has long been replaced by
+:command:`add_executable` combined with :command:`add_custom_command`.
+
+.. |disallowed_version| replace:: 3.0
+.. include:: DISALLOWED_COMMAND.txt
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0035.rst b/Help/policy/CMP0035.rst
new file mode 100644
index 000000000..58199a45f
--- /dev/null
+++ b/Help/policy/CMP0035.rst
@@ -0,0 +1,12 @@
+CMP0035
+-------
+
+The :command:`variable_requires` command should not be called.
+
+This command was introduced in November 2001 to perform some conditional
+logic. It has long been replaced by the :command:`if` command.
+
+.. |disallowed_version| replace:: 3.0
+.. include:: DISALLOWED_COMMAND.txt
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0036.rst b/Help/policy/CMP0036.rst
new file mode 100644
index 000000000..4bcfc54d9
--- /dev/null
+++ b/Help/policy/CMP0036.rst
@@ -0,0 +1,14 @@
+CMP0036
+-------
+
+The :command:`build_name` command should not be called.
+
+This command was added in May 2001 to compute a name for the current
+operating system and compiler combination. The command has long been
+documented as discouraged and replaced by the :variable:`CMAKE_SYSTEM`
+and :variable:`CMAKE_<LANG>_COMPILER` variables.
+
+.. |disallowed_version| replace:: 3.0
+.. include:: DISALLOWED_COMMAND.txt
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0037.rst b/Help/policy/CMP0037.rst
new file mode 100644
index 000000000..9f8457c62
--- /dev/null
+++ b/Help/policy/CMP0037.rst
@@ -0,0 +1,28 @@
+CMP0037
+-------
+
+Target names should not be reserved and should match a validity pattern.
+
+CMake 2.8.12 and lower allowed creating targets using :command:`add_library`,
+:command:`add_executable` and :command:`add_custom_target` with unrestricted
+choice for the target name. Newer cmake features such
+as :manual:`cmake-generator-expressions(7)` and some
+diagnostics expect target names to match a restricted pattern.
+
+Target names may contain upper and lower case letters, numbers, the underscore
+character (_), dot(.), plus(+) and minus(-). As a special case, ALIAS
+targets and IMPORTED targets may contain two consequtive colons.
+
+Target names reserved by one or more CMake generators are not allowed.
+Among others these include "all", "help" and "test".
+
+The OLD behavior for this policy is to allow creating targets with
+reserved names or which do not match the validity pattern.
+The NEW behavior for this policy is to report an error
+if an add_* command is used with an invalid target name.
+
+This policy was introduced in CMake version 3.0. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0038.rst b/Help/policy/CMP0038.rst
new file mode 100644
index 000000000..a306d90a9
--- /dev/null
+++ b/Help/policy/CMP0038.rst
@@ -0,0 +1,18 @@
+CMP0038
+-------
+
+Targets may not link directly to themselves.
+
+CMake 2.8.12 and lower allowed a build target to link to itself directly with
+a :command:`target_link_libraries` call. This is an indicator of a bug in
+user code.
+
+The OLD behavior for this policy is to ignore targets which list themselves
+in their own link implementation. The NEW behavior for this policy is to
+report an error if a target attempts to link to itself.
+
+This policy was introduced in CMake version 3.0. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0039.rst b/Help/policy/CMP0039.rst
new file mode 100644
index 000000000..97d78ae2a
--- /dev/null
+++ b/Help/policy/CMP0039.rst
@@ -0,0 +1,19 @@
+CMP0039
+-------
+
+Utility targets may not have link dependencies.
+
+CMake 2.8.12 and lower allowed using utility targets in the left hand side
+position of the :command:`target_link_libraries` command. This is an indicator
+of a bug in user code.
+
+The OLD behavior for this policy is to ignore attempts to set the link
+libraries of utility targets. The NEW behavior for this policy is to
+report an error if an attempt is made to set the link libraries of a
+utility target.
+
+This policy was introduced in CMake version 3.0. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0040.rst b/Help/policy/CMP0040.rst
new file mode 100644
index 000000000..d46baf647
--- /dev/null
+++ b/Help/policy/CMP0040.rst
@@ -0,0 +1,21 @@
+CMP0040
+-------
+
+The target in the ``TARGET`` signature of :command:`add_custom_command`
+must exist and must be defined in current directory.
+
+CMake 2.8.12 and lower silently ignored a custom command created with
+the ``TARGET`` signature of :command:`add_custom_command`
+if the target is unknown or was defined outside the current directory.
+
+The ``OLD`` behavior for this policy is to ignore custom commands
+for unknown targets. The ``NEW`` behavior for this policy is to report
+an error if the target referenced in :command:`add_custom_command` is
+unknown or was defined outside the current directory.
+
+This policy was introduced in CMake version 3.0. CMake version
+|release| warns when the policy is not set and uses ``OLD`` behavior.
+Use the :command:`cmake_policy` command to set it to ``OLD`` or
+``NEW`` explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0041.rst b/Help/policy/CMP0041.rst
new file mode 100644
index 000000000..f027d5de9
--- /dev/null
+++ b/Help/policy/CMP0041.rst
@@ -0,0 +1,27 @@
+CMP0041
+-------
+
+Error on relative include with generator expression.
+
+Diagnostics in CMake 2.8.12 and lower silently ignored an entry in the
+:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` of a target if it contained a generator
+expression at any position.
+
+The path entries in that target property should not be relative. High-level
+API should ensure that by adding either a source directory or a install
+directory prefix, as appropriate.
+
+As an additional diagnostic, the :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` generated
+on an :prop_tgt:`IMPORTED` target for the install location should not contain
+paths in the source directory or the build directory.
+
+The OLD behavior for this policy is to ignore relative path entries if they
+contain a generator expression. The NEW behavior for this policy is to report
+an error if a generator expression appears in another location and the path is
+relative.
+
+This policy was introduced in CMake version 3.0. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0042.rst b/Help/policy/CMP0042.rst
new file mode 100644
index 000000000..31314b2cd
--- /dev/null
+++ b/Help/policy/CMP0042.rst
@@ -0,0 +1,21 @@
+CMP0042
+-------
+
+:prop_tgt:`MACOSX_RPATH` is enabled by default.
+
+CMake 2.8.12 and newer has support for using ``@rpath`` in a target's install
+name. This was enabled by setting the target property
+:prop_tgt:`MACOSX_RPATH`. The ``@rpath`` in an install name is a more
+flexible and powerful mechanism than ``@executable_path`` or ``@loader_path``
+for locating shared libraries.
+
+CMake 3.0 and later prefer this property to be ON by default. Projects
+wanting ``@rpath`` in a target's install name may remove any setting of
+the :prop_tgt:`INSTALL_NAME_DIR` and :variable:`CMAKE_INSTALL_NAME_DIR`
+variables.
+
+This policy was introduced in CMake version 3.0. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0043.rst b/Help/policy/CMP0043.rst
new file mode 100644
index 000000000..9e427c377
--- /dev/null
+++ b/Help/policy/CMP0043.rst
@@ -0,0 +1,47 @@
+CMP0043
+-------
+
+Ignore COMPILE_DEFINITIONS_<Config> properties
+
+CMake 2.8.12 and lower allowed setting the
+:prop_tgt:`COMPILE_DEFINITIONS_<CONFIG>` target property and
+:prop_dir:`COMPILE_DEFINITIONS_<CONFIG>` directory property to apply
+configuration-specific compile definitions.
+
+Since CMake 2.8.10, the :prop_tgt:`COMPILE_DEFINITIONS` property has supported
+:manual:`generator expressions <cmake-generator-expressions(7)>` for setting
+configuration-dependent content. The continued existence of the suffixed
+variables is redundant, and causes a maintenance burden. Population of the
+:prop_tgt:`COMPILE_DEFINITIONS_DEBUG <COMPILE_DEFINITIONS_<CONFIG>>` property
+may be replaced with a population of :prop_tgt:`COMPILE_DEFINITIONS` directly
+or via :command:`target_compile_definitions`:
+
+.. code-block:: cmake
+
+ # Old Interfaces:
+ set_property(TARGET tgt APPEND PROPERTY
+ COMPILE_DEFINITIONS_DEBUG DEBUG_MODE
+ )
+ set_property(DIRECTORY APPEND PROPERTY
+ COMPILE_DEFINITIONS_DEBUG DIR_DEBUG_MODE
+ )
+
+ # New Interfaces:
+ set_property(TARGET tgt APPEND PROPERTY
+ COMPILE_DEFINITIONS $<$<CONFIG:Debug>:DEBUG_MODE>
+ )
+ target_compile_definitions(tgt PRIVATE $<$<CONFIG:Debug>:DEBUG_MODE>)
+ set_property(DIRECTORY APPEND PROPERTY
+ COMPILE_DEFINITIONS $<$<CONFIG:Debug>:DIR_DEBUG_MODE>
+ )
+
+The OLD behavior for this policy is to consume the content of the suffixed
+:prop_tgt:`COMPILE_DEFINITIONS_<CONFIG>` target property when generating the
+compilation command. The NEW behavior for this policy is to ignore the content
+of the :prop_tgt:`COMPILE_DEFINITIONS_<CONFIG>` target property .
+
+This policy was introduced in CMake version 3.0. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0044.rst b/Help/policy/CMP0044.rst
new file mode 100644
index 000000000..02afa9f1a
--- /dev/null
+++ b/Help/policy/CMP0044.rst
@@ -0,0 +1,21 @@
+CMP0044
+-------
+
+Case sensitive ``<LANG>_COMPILER_ID`` generator expressions
+
+CMake 2.8.12 introduced the ``<LANG>_COMPILER_ID``
+:manual:`generator expressions <cmake-generator-expressions(7)>` to allow
+comparison of the :variable:`CMAKE_<LANG>_COMPILER_ID` with a test value. The
+possible valid values are lowercase, but the comparison with the test value
+was performed case-insensitively.
+
+The OLD behavior for this policy is to perform a case-insensitive comparison
+with the value in the ``<LANG>_COMPILER_ID`` expression. The NEW behavior
+for this policy is to perform a case-sensitive comparison with the value in
+the ``<LANG>_COMPILER_ID`` expression.
+
+This policy was introduced in CMake version 3.0. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0045.rst b/Help/policy/CMP0045.rst
new file mode 100644
index 000000000..c7e1a90f6
--- /dev/null
+++ b/Help/policy/CMP0045.rst
@@ -0,0 +1,19 @@
+CMP0045
+-------
+
+Error on non-existent target in get_target_property.
+
+In CMake 2.8.12 and lower, the :command:`get_target_property` command accepted
+a non-existent target argument without issuing any error or warning. The
+result variable is set to a ``-NOTFOUND`` value.
+
+The OLD behavior for this policy is to issue no warning and set the result
+variable to a ``-NOTFOUND`` value. The NEW behavior
+for this policy is to issue a ``FATAL_ERROR`` if the command is called with a
+non-existent target.
+
+This policy was introduced in CMake version 3.0. CMake version
+|release| warns when the policy is not set and uses OLD behavior. Use
+the cmake_policy command to set it to OLD or NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0046.rst b/Help/policy/CMP0046.rst
new file mode 100644
index 000000000..576d1b1cc
--- /dev/null
+++ b/Help/policy/CMP0046.rst
@@ -0,0 +1,19 @@
+CMP0046
+-------
+
+Error on non-existent dependency in add_dependencies.
+
+CMake 2.8.12 and lower silently ignored non-existent dependencies
+listed in the :command:`add_dependencies` command.
+
+The OLD behavior for this policy is to silently ignore non-existent
+dependencies. The NEW behavior for this policy is to report an error
+if non-existent dependencies are listed in the :command:`add_dependencies`
+command.
+
+This policy was introduced in CMake version 3.0.
+CMake version |release| warns when the policy is not set and uses
+OLD behavior. Use the cmake_policy command to set it to OLD or
+NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0047.rst b/Help/policy/CMP0047.rst
new file mode 100644
index 000000000..882dd7828
--- /dev/null
+++ b/Help/policy/CMP0047.rst
@@ -0,0 +1,30 @@
+CMP0047
+-------
+
+Use ``QCC`` compiler id for the qcc drivers on QNX.
+
+CMake 3.0 and above recognize that the QNX qcc compiler driver is
+different from the GNU compiler.
+CMake now prefers to present this to projects by setting the
+:variable:`CMAKE_<LANG>_COMPILER_ID` variable to ``QCC`` instead
+of ``GNU``. However, existing projects may assume the compiler id for
+QNX qcc is just ``GNU`` as it was in CMake versions prior to 3.0.
+Therefore this policy determines for QNX qcc which compiler id to
+report in the :variable:`CMAKE_<LANG>_COMPILER_ID` variable after
+language ``<LANG>`` is enabled by the :command:`project` or
+:command:`enable_language` command. The policy must be set prior
+to the invocation of either command.
+
+The OLD behavior for this policy is to use the ``GNU`` compiler id
+for the qcc and QCC compiler drivers. The NEW behavior for this policy
+is to use the ``QCC`` compiler id for those drivers.
+
+This policy was introduced in CMake version 3.0. Use the
+:command:`cmake_policy` command to set this policy to OLD or NEW explicitly.
+Unlike most policies, CMake version |release| does *not* warn
+by default when this policy is not set and simply uses OLD behavior.
+See documentation of the
+:variable:`CMAKE_POLICY_WARNING_CMP0047 <CMAKE_POLICY_WARNING_CMP<NNNN>>`
+variable to control the warning.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0048.rst b/Help/policy/CMP0048.rst
new file mode 100644
index 000000000..0e7e60681
--- /dev/null
+++ b/Help/policy/CMP0048.rst
@@ -0,0 +1,24 @@
+CMP0048
+-------
+
+The :command:`project` command manages VERSION variables.
+
+CMake version 3.0 introduced the ``VERSION`` option of the :command:`project`
+command to specify a project version as well as the name. In order to keep
+:variable:`PROJECT_VERSION` and related variables consistent with variable
+:variable:`PROJECT_NAME` it is necessary to set the VERSION variables
+to the empty string when no ``VERSION`` is given to :command:`project`.
+However, this can change behavior for existing projects that set VERSION
+variables themselves since :command:`project` may now clear them.
+This policy controls the behavior for compatibility with such projects.
+
+The OLD behavior for this policy is to leave VERSION variables untouched.
+The NEW behavior for this policy is to set VERSION as documented by the
+:command:`project` command.
+
+This policy was introduced in CMake version 3.0.
+CMake version |release| warns when the policy is not set and uses
+OLD behavior. Use the cmake_policy command to set it to OLD or
+NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0049.rst b/Help/policy/CMP0049.rst
new file mode 100644
index 000000000..a3ce4b1fa
--- /dev/null
+++ b/Help/policy/CMP0049.rst
@@ -0,0 +1,25 @@
+CMP0049
+-------
+
+Do not expand variables in target source entries.
+
+CMake 2.8.12 and lower performed and extra layer of variable expansion
+when evaluating source file names:
+
+.. code-block:: cmake
+
+ set(a_source foo.c)
+ add_executable(foo \${a_source})
+
+This was undocumented behavior.
+
+The OLD behavior for this policy is to expand such variables when processing
+the target sources. The NEW behavior for this policy is to issue an error
+if such variables need to be expanded.
+
+This policy was introduced in CMake version 3.0.
+CMake version |release| warns when the policy is not set and uses
+OLD behavior. Use the cmake_policy command to set it to OLD or
+NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0050.rst b/Help/policy/CMP0050.rst
new file mode 100644
index 000000000..39e40b698
--- /dev/null
+++ b/Help/policy/CMP0050.rst
@@ -0,0 +1,20 @@
+CMP0050
+-------
+
+Disallow add_custom_command SOURCE signatures.
+
+CMake 2.8.12 and lower allowed a signature for :command:`add_custom_command`
+which specified an input to a command. This was undocumented behavior.
+Modern use of CMake associates custom commands with their output, rather
+than their input.
+
+The OLD behavior for this policy is to allow the use of
+:command:`add_custom_command` SOURCE signatures. The NEW behavior for this
+policy is to issue an error if such a signature is used.
+
+This policy was introduced in CMake version 3.0.
+CMake version |release| warns when the policy is not set and uses
+OLD behavior. Use the cmake_policy command to set it to OLD or
+NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0051.rst b/Help/policy/CMP0051.rst
new file mode 100644
index 000000000..6b679e5b4
--- /dev/null
+++ b/Help/policy/CMP0051.rst
@@ -0,0 +1,26 @@
+CMP0051
+-------
+
+List TARGET_OBJECTS in SOURCES target property.
+
+CMake 3.0 and lower did not include the ``TARGET_OBJECTS``
+:manual:`generator expression <cmake-generator-expressions(7)>` when
+returning the :prop_tgt:`SOURCES` target property.
+
+Configure-time CMake code is not able to handle generator expressions. If
+using the :prop_tgt:`SOURCES` target property at configure time, it may be
+necessary to first remove generator expressions using the
+:command:`string(GENEX_STRIP)` command. Generate-time CMake code such as
+:command:`file(GENERATE)` can handle the content without stripping.
+
+The ``OLD`` behavior for this policy is to omit ``TARGET_OBJECTS``
+expressions from the :prop_tgt:`SOURCES` target property. The ``NEW``
+behavior for this policy is to include ``TARGET_OBJECTS`` expressions
+in the output.
+
+This policy was introduced in CMake version 3.1.
+CMake version |release| warns when the policy is not set and uses
+``OLD`` behavior. Use the :command:`cmake_policy` command to set it
+to ``OLD`` or ``NEW`` explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0052.rst b/Help/policy/CMP0052.rst
new file mode 100644
index 000000000..0ea5ace77
--- /dev/null
+++ b/Help/policy/CMP0052.rst
@@ -0,0 +1,26 @@
+CMP0052
+-------
+
+Reject source and build dirs in installed INTERFACE_INCLUDE_DIRECTORIES.
+
+CMake 3.0 and lower allowed subdirectories of the source directory or build
+directory to be in the :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` of
+installed and exported targets, if the directory was also a subdirectory of
+the installation prefix. This makes the installation depend on the
+existence of the source dir or binary dir, and the installation will be
+broken if either are removed after installation.
+
+See :ref:`Include Directories and Usage Requirements` for more on
+specifying include directories for targets.
+
+The OLD behavior for this policy is to export the content of the
+:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` with the source or binary
+directory. The NEW behavior for this
+policy is to issue an error if such a directory is used.
+
+This policy was introduced in CMake version 3.1.
+CMake version |release| warns when the policy is not set and uses
+``OLD`` behavior. Use the :command:`cmake_policy` command to set it
+to ``OLD`` or ``NEW`` explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0053.rst b/Help/policy/CMP0053.rst
new file mode 100644
index 000000000..2620a60e0
--- /dev/null
+++ b/Help/policy/CMP0053.rst
@@ -0,0 +1,46 @@
+CMP0053
+-------
+
+Simplify variable reference and escape sequence evaluation.
+
+CMake 3.1 introduced a much faster implementation of evaluation of the
+:ref:`Variable References` and :ref:`Escape Sequences` documented in the
+:manual:`cmake-language(7)` manual. While the behavior is identical
+to the legacy implementation in most cases, some corner cases were
+cleaned up to simplify the behavior. Specifically:
+
+* Expansion of ``@VAR@`` reference syntax defined by the
+ :command:`configure_file` and :command:`string(CONFIGURE)`
+ commands is no longer performed in other contexts.
+
+* Literal ``${VAR}`` reference syntax may contain only
+ alphanumeric characters (``A-Z``, ``a-z``, ``0-9``) and
+ the characters ``_``, ``.``, ``/``, ``-``, and ``+``.
+ Variables with other characters in their name may still
+ be referenced indirectly, e.g.
+
+ .. code-block:: cmake
+
+ set(varname "otherwise & disallowed $ characters")
+ message("${${varname}}")
+
+* The setting of policy :policy:`CMP0010` is not considered,
+ so improper variable reference syntax is always an error.
+
+* More characters are allowed to be escaped in variable names.
+ Previously, only ``()#" \@^`` were valid characters to
+ escape. Now any non-alphanumeric, non-semicolon, non-NUL
+ character may be escaped following the ``escape_identity``
+ production in the :ref:`Escape Sequences` section of the
+ :manual:`cmake-language(7)` manual.
+
+The ``OLD`` behavior for this policy is to honor the legacy behavior for
+variable references and escape sequences. The ``NEW`` behavior is to
+use the simpler variable expansion and escape sequence evaluation rules.
+
+This policy was introduced in CMake version 3.1.
+CMake version |release| warns when the policy is not set and uses
+``OLD`` behavior. Use the :command:`cmake_policy` command to set
+it to ``OLD`` or ``NEW`` explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0054.rst b/Help/policy/CMP0054.rst
new file mode 100644
index 000000000..1e000a662
--- /dev/null
+++ b/Help/policy/CMP0054.rst
@@ -0,0 +1,52 @@
+CMP0054
+-------
+
+Only interpret :command:`if` arguments as variables or keywords when unquoted.
+
+CMake 3.1 and above no longer implicitly dereference variables or
+interpret keywords in an :command:`if` command argument when
+it is a :ref:`Quoted Argument` or a :ref:`Bracket Argument`.
+
+The ``OLD`` behavior for this policy is to dereference variables and
+interpret keywords even if they are quoted or bracketed.
+The ``NEW`` behavior is to not dereference variables or interpret keywords
+that have been quoted or bracketed.
+
+Given the following partial example:
+
+::
+
+ set(A E)
+ set(E "")
+
+ if("${A}" STREQUAL "")
+ message("Result is TRUE before CMake 3.1 or when CMP0054 is OLD")
+ else()
+ message("Result is FALSE in CMake 3.1 and above if CMP0054 is NEW")
+ endif()
+
+After explicit expansion of variables this gives:
+
+::
+
+ if("E" STREQUAL "")
+
+With the policy set to ``OLD`` implicit expansion reduces this semantically to:
+
+::
+
+ if("" STREQUAL "")
+
+With the policy set to ``NEW`` the quoted arguments will not be
+further dereferenced:
+
+::
+
+ if("E" STREQUAL "")
+
+This policy was introduced in CMake version 3.1.
+CMake version |release| warns when the policy is not set and uses
+``OLD`` behavior. Use the :command:`cmake_policy` command to set
+it to ``OLD`` or ``NEW`` explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0055.rst b/Help/policy/CMP0055.rst
new file mode 100644
index 000000000..b3df758fe
--- /dev/null
+++ b/Help/policy/CMP0055.rst
@@ -0,0 +1,19 @@
+CMP0055
+-------
+
+Strict checking for the :command:`break` command.
+
+CMake 3.1 and lower allowed calls to the :command:`break` command
+outside of a loop context and also ignored any given arguments.
+This was undefined behavior.
+
+The OLD behavior for this policy is to allow :command:`break` to be placed
+outside of loop contexts and ignores any arguments. The NEW behavior for this
+policy is to issue an error if a misplaced break or any arguments are found.
+
+This policy was introduced in CMake version 3.2.
+CMake version |release| warns when the policy is not set and uses
+OLD behavior. Use the cmake_policy command to set it to OLD or
+NEW explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0056.rst b/Help/policy/CMP0056.rst
new file mode 100644
index 000000000..3ba89d576
--- /dev/null
+++ b/Help/policy/CMP0056.rst
@@ -0,0 +1,34 @@
+CMP0056
+-------
+
+Honor link flags in :command:`try_compile` source-file signature.
+
+The :command:`try_compile` command source-file signature generates a
+``CMakeLists.txt`` file to build the source file into an executable.
+In order to compile the source the same way as it might be compiled
+by the calling project, the generated project sets the value of the
+:variable:`CMAKE_<LANG>_FLAGS` variable to that in the calling project.
+The value of the :variable:`CMAKE_EXE_LINKER_FLAGS` variable may be
+needed in some cases too, but CMake 3.1 and lower did not set it in
+the generated project. CMake 3.2 and above prefer to set it so that
+linker flags are honored as well as compiler flags. This policy
+provides compatibility with the pre-3.2 behavior.
+
+The OLD behavior for this policy is to not set the value of the
+:variable:`CMAKE_EXE_LINKER_FLAGS` variable in the generated test
+project. The NEW behavior for this policy is to set the value of
+the :variable:`CMAKE_EXE_LINKER_FLAGS` variable in the test project
+to the same as it is in the calling project.
+
+If the project code does not set the policy explicitly, users may
+set it on the command line by defining the
+:variable:`CMAKE_POLICY_DEFAULT_CMP0056 <CMAKE_POLICY_DEFAULT_CMP<NNNN>>`
+variable in the cache.
+
+This policy was introduced in CMake version 3.2. Unlike most policies,
+CMake version |release| does *not* warn by default when this policy
+is not set and simply uses OLD behavior. See documentation of the
+:variable:`CMAKE_POLICY_WARNING_CMP0056 <CMAKE_POLICY_WARNING_CMP<NNNN>>`
+variable to control the warning.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0057.rst b/Help/policy/CMP0057.rst
new file mode 100644
index 000000000..83db1863d
--- /dev/null
+++ b/Help/policy/CMP0057.rst
@@ -0,0 +1,16 @@
+CMP0057
+-------
+
+Support new :command:`if` IN_LIST operator.
+
+CMake 3.3 adds support for the new IN_LIST operator.
+
+The ``OLD`` behavior for this policy is to ignore the IN_LIST operator.
+The ``NEW`` behavior is to interpret the IN_LIST operator.
+
+This policy was introduced in CMake version 3.3.
+CMake version |release| warns when the policy is not set and uses
+``OLD`` behavior. Use the :command:`cmake_policy` command to set
+it to ``OLD`` or ``NEW`` explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0058.rst b/Help/policy/CMP0058.rst
new file mode 100644
index 000000000..05efd48fb
--- /dev/null
+++ b/Help/policy/CMP0058.rst
@@ -0,0 +1,110 @@
+CMP0058
+-------
+
+Ninja requires custom command byproducts to be explicit.
+
+When an intermediate file generated during the build is consumed
+by an expensive operation or a large tree of dependents, one may
+reduce the work needed for an incremental rebuild by updating the
+file timestamp only when its content changes. With this approach
+the generation rule must have a separate output file that is always
+updated with a new timestamp that is newer than any dependencies of
+the rule so that the build tool re-runs the rule only when the input
+changes. We refer to the separate output file as a rule's *witness*
+and the generated file as a rule's *byproduct*.
+
+Byproducts may not be listed as outputs because their timestamps are
+allowed to be older than the inputs. No build tools (like ``make``)
+that existed when CMake was designed have a way to express byproducts.
+Therefore CMake versions prior to 3.2 had no way to specify them.
+Projects typically left byproducts undeclared in the rules that
+generate them. For example:
+
+.. code-block:: cmake
+
+ add_custom_command(
+ OUTPUT witness.txt
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ ${CMAKE_CURRENT_SOURCE_DIR}/input.txt
+ byproduct.txt # timestamp may not change
+ COMMAND ${CMAKE_COMMAND} -E touch witness.txt
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/input.txt
+ )
+ add_custom_target(Provider DEPENDS witness.txt)
+ add_custom_command(
+ OUTPUT generated.c
+ COMMAND expensive-task -i byproduct.txt -o generated.c
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/byproduct.txt
+ )
+ add_library(Consumer generated.c)
+ add_dependencies(Consumer Provider)
+
+This works well for all generators except :generator:`Ninja`.
+The Ninja build tool sees a rule listing ``byproduct.txt``
+as a dependency and no rule listing it as an output. Ninja then
+complains that there is no way to satisfy the dependency and
+stops building even though there are order-only dependencies
+that ensure ``byproduct.txt`` will exist before its consumers
+need it. See discussion of this problem in `Ninja Issue 760`_
+for further details on why Ninja works this way.
+
+.. _`Ninja Issue 760`: https://github.com/martine/ninja/issues/760
+
+Instead of leaving byproducts undeclared in the rules that generate
+them, Ninja expects byproducts to be listed along with other outputs.
+Such rules may be marked with a ``restat`` option that tells Ninja
+to check the timestamps of outputs after the rules run. This
+prevents byproducts whose timestamps do not change from causing
+their dependents to re-build unnecessarily.
+
+Since the above approach does not tell CMake what custom command
+generates ``byproduct.txt``, the Ninja generator does not have
+enough information to add the byproduct as an output of any rule.
+CMake 2.8.12 and above work around this problem and allow projects
+using the above approach to build by generating ``phony`` build
+rules to tell Ninja to tolerate such missing files. However, this
+workaround prevents Ninja from diagnosing a dependency that is
+really missing. It also works poorly in in-source builds where
+every custom command dependency, even on source files, needs to
+be treated this way because CMake does not have enough information
+to know which files are generated as byproducts of custom commands.
+
+CMake 3.2 introduced the ``BYPRODUCTS`` option to the
+:command:`add_custom_command` and :command:`add_custom_target`
+commands. This option allows byproducts to be specified explicitly:
+
+.. code-block:: cmake
+
+ add_custom_command(
+ OUTPUT witness.txt
+ BYPRODUCTS byproduct.txt # explicit byproduct specification
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ ${CMAKE_CURRENT_SOURCE_DIR}/input.txt
+ byproduct.txt # timestamp may not change
+ ...
+
+The ``BYPRODUCTS`` option is used by the :generator:`Ninja` generator
+to list byproducts among the outputs of the custom commands that
+generate them, and is ignored by other generators.
+
+CMake 3.3 and above prefer to require projects to specify custom
+command byproducts explicitly so that it can avoid using the
+``phony`` rule workaround altogether. Policy ``CMP0058`` was
+introduced to provide compatibility with existing projects that
+still need the workaround.
+
+This policy has no effect on generators other than :generator:`Ninja`.
+The ``OLD`` behavior for this policy is to generate Ninja ``phony``
+rules for unknown dependencies in the build tree. The ``NEW``
+behavior for this policy is to not generate these and instead
+require projects to specify custom command ``BYPRODUCTS`` explicitly.
+
+This policy was introduced in CMake version 3.3.
+CMake version |release| warns when it sees unknown dependencies in
+out-of-source build trees if the policy is not set and then uses
+``OLD`` behavior. Use the :command:`cmake_policy` command to set
+the policy to ``OLD`` or ``NEW`` explicitly. The policy setting
+must be in scope at the end of the top-level ``CMakeLists.txt``
+file of the project and has global effect.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0059.rst b/Help/policy/CMP0059.rst
new file mode 100644
index 000000000..5da479a65
--- /dev/null
+++ b/Help/policy/CMP0059.rst
@@ -0,0 +1,19 @@
+CMP0059
+-------
+
+Don't treat ``DEFINITIONS`` as a built-in directory property.
+
+CMake 3.3 and above no longer make a list of definitions available through
+the :prop_dir:`DEFINITIONS` directory property. The
+:prop_dir:`COMPILE_DEFINITIONS` directory property may be used instead.
+
+The ``OLD`` behavior for this policy is to provide the list of flags given
+so far to the :command:`add_definitions` command. The ``NEW`` behavior is
+to behave as a normal user-defined directory property.
+
+This policy was introduced in CMake version 3.3.
+CMake version |release| warns when the policy is not set and uses
+``OLD`` behavior. Use the :command:`cmake_policy` command to set
+it to ``OLD`` or ``NEW`` explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0060.rst b/Help/policy/CMP0060.rst
new file mode 100644
index 000000000..8611affac
--- /dev/null
+++ b/Help/policy/CMP0060.rst
@@ -0,0 +1,65 @@
+CMP0060
+-------
+
+Link libraries by full path even in implicit directories.
+
+Policy :policy:`CMP0003` was introduced with the intention of always
+linking library files by full path when a full path is given to the
+:command:`target_link_libraries` command. However, on some platforms
+(e.g. HP-UX) the compiler front-end adds alternative library search paths
+for the current architecture (e.g. ``/usr/lib/<arch>`` has alternatives
+to libraries in ``/usr/lib`` for the current architecture).
+On such platforms the :command:`find_library` may find a library such as
+``/usr/lib/libfoo.so`` that does not belong to the current architecture.
+
+Prior to policy :policy:`CMP0003` projects would still build in such
+cases because the incorrect library path would be converted to ``-lfoo``
+on the link line and the linker would find the proper library in the
+arch-specific search path provided by the compiler front-end implicitly.
+At the time we chose to remain compatible with such projects by always
+converting library files found in implicit link directories to ``-lfoo``
+flags to ask the linker to search for them. This approach allowed existing
+projects to continue to build while still linking to libraries outside
+implicit link directories via full path (such as those in the build tree).
+
+CMake does allow projects to override this behavior by using an
+:ref:`IMPORTED library target <Imported Targets>` with its
+:prop_tgt:`IMPORTED_LOCATION` property set to the desired full path to
+a library file. In fact, many :ref:`Find Modules` are learning to provide
+:ref:`Imported Targets` instead of just the traditional ``Foo_LIBRARIES``
+variable listing library files. However, this makes the link line
+generated for a library found by a Find Module depend on whether it
+is linked through an imported target or not, which is inconsistent.
+Furthermore, this behavior has been a source of confusion because the
+generated link line for a library file depends on its location. It is
+also problematic for projects trying to link statically because flags
+like ``-Wl,-Bstatic -lfoo -Wl,-Bdynamic`` may be used to help the linker
+select ``libfoo.a`` instead of ``libfoo.so`` but then leak dynamic linking
+to following libraries. (See the :prop_tgt:`LINK_SEARCH_END_STATIC`
+target property for a solution typically used for that problem.)
+
+When the special case for libraries in implicit link directories was first
+introduced the list of implicit link directories was simply hard-coded
+(e.g. ``/lib``, ``/usr/lib``, and a few others). Since that time, CMake
+has learned to detect the implicit link directories used by the compiler
+front-end. If necessary, the :command:`find_library` command could be
+taught to use this information to help find libraries of the proper
+architecture.
+
+For these reasons, CMake 3.3 and above prefer to drop the special case
+and link libraries by full path even when they are in implicit link
+directories. Policy ``CMP0060`` provides compatibility for existing
+projects.
+
+The OLD behavior for this policy is to ask the linker to search for
+libraries whose full paths are known to be in implicit link directories.
+The NEW behavior for this policy is to link libraries by full path even
+if they are in implicit link directories.
+
+This policy was introduced in CMake version 3.3. Unlike most policies,
+CMake version |release| does *not* warn by default when this policy
+is not set and simply uses OLD behavior. See documentation of the
+:variable:`CMAKE_POLICY_WARNING_CMP0060 <CMAKE_POLICY_WARNING_CMP<NNNN>>`
+variable to control the warning.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0061.rst b/Help/policy/CMP0061.rst
new file mode 100644
index 000000000..cb2ac2840
--- /dev/null
+++ b/Help/policy/CMP0061.rst
@@ -0,0 +1,26 @@
+CMP0061
+-------
+
+CTest does not by default tell ``make`` to ignore errors (``-i``).
+
+The :command:`ctest_build` and :command:`build_command` commands no
+longer generate build commands for :ref:`Makefile Generators` with
+the ``-i`` option. Previously this was done to help build as much
+of tested projects as possible. However, this behavior is not
+consistent with other generators and also causes the return code
+of the ``make`` tool to be meaningless.
+
+Of course users may still add this option manually by setting
+:variable:`CTEST_BUILD_COMMAND` or the ``MAKECOMMAND`` cache entry.
+See the :ref:`CTest Build Step` ``MakeCommand`` setting documentation
+for their effects.
+
+The ``OLD`` behavior for this policy is to add ``-i`` to ``make``
+calls in CTest. The ``NEW`` behavior for this policy is to not
+add ``-i``.
+
+This policy was introduced in CMake version 3.3. Unlike most policies,
+CMake version |release| does *not* warn when this policy is not set and
+simply uses OLD behavior.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0062.rst b/Help/policy/CMP0062.rst
new file mode 100644
index 000000000..9047fffbe
--- /dev/null
+++ b/Help/policy/CMP0062.rst
@@ -0,0 +1,29 @@
+CMP0062
+-------
+
+Disallow install() of export() result.
+
+The :command:`export()` command generates a file containing
+:ref:`Imported Targets`, which is suitable for use from the build
+directory. It is not suitable for installation because it contains absolute
+paths to buildsystem locations, and is particular to a single build
+configuration.
+
+The :command:`install(EXPORT)` generates and installs files which contain
+:ref:`Imported Targets`. These files are generated with relative paths
+(unless the user specifies absolute paths), and are designed for
+multi-configuration use. See :ref:`Creating Packages` for more.
+
+CMake 3.3 no longer allows the use of the :command:`install(FILES)` command
+with the result of the :command:`export()` command.
+
+The ``OLD`` behavior for this policy is to allow installing the result of
+an :command:`export()` command. The ``NEW`` behavior for this policy is
+not to allow installing the result of an :command:`export()` command.
+
+This policy was introduced in CMake version 3.3. CMake version
+|release| warns when the policy is not set and uses ``OLD`` behavior. Use
+the :command:`cmake_policy()` command to set it to ``OLD`` or ``NEW``
+explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0063.rst b/Help/policy/CMP0063.rst
new file mode 100644
index 000000000..d736d0634
--- /dev/null
+++ b/Help/policy/CMP0063.rst
@@ -0,0 +1,28 @@
+CMP0063
+-------
+
+Honor visibility properties for all target types.
+
+The :prop_tgt:`<LANG>_VISIBILITY_PRESET` and
+:prop_tgt:`VISIBILITY_INLINES_HIDDEN` target properties affect visibility
+of symbols during dynamic linking. When first introduced these properties
+affected compilation of sources only in shared libraries, module libraries,
+and executables with the :prop_tgt:`ENABLE_EXPORTS` property set. This
+was sufficient for the basic use cases of shared libraries and executables
+with plugins. However, some sources may be compiled as part of static
+libraries or object libraries and then linked into a shared library later.
+CMake 3.3 and above prefer to honor these properties for sources compiled
+in all target types. This policy preserves compatibility for projects
+expecting the properties to work only for some target types.
+
+The ``OLD`` behavior for this policy is to ignore the visibility properties
+for static libraries, object libraries, and executables without exports.
+The ``NEW`` behavior for this policy is to honor the visibility properties
+for all target types.
+
+This policy was introduced in CMake version 3.3. CMake version
+|release| warns when the policy is not set and uses ``OLD`` behavior. Use
+the :command:`cmake_policy()` command to set it to ``OLD`` or ``NEW``
+explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0064.rst b/Help/policy/CMP0064.rst
new file mode 100644
index 000000000..e9a061ba1
--- /dev/null
+++ b/Help/policy/CMP0064.rst
@@ -0,0 +1,17 @@
+CMP0064
+-------
+
+Recognize ``TEST`` as a operator for the :command:`if` command.
+
+The ``TEST`` operator was added to the :command:`if` command to determine if a
+given test name was created by the :command:`add_test` command.
+
+The ``OLD`` behavior for this policy is to ignore the ``TEST`` operator.
+The ``NEW`` behavior is to interpret the ``TEST`` operator.
+
+This policy was introduced in CMake version 3.4. CMake version
+|release| warns when the policy is not set and uses ``OLD`` behavior. Use
+the :command:`cmake_policy()` command to set it to ``OLD`` or ``NEW``
+explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0065.rst b/Help/policy/CMP0065.rst
new file mode 100644
index 000000000..2ed775dee
--- /dev/null
+++ b/Help/policy/CMP0065.rst
@@ -0,0 +1,27 @@
+CMP0065
+-------
+
+Do not add flags to export symbols from executables without
+the :prop_tgt:`ENABLE_EXPORTS` target property.
+
+CMake 3.3 and below, for historical reasons, always linked executables
+on some platforms with flags like ``-rdynamic`` to export symbols from
+the executables for use by any plugins they may load via ``dlopen``.
+CMake 3.4 and above prefer to do this only for executables that are
+explicitly marked with the :prop_tgt:`ENABLE_EXPORTS` target property.
+
+The ``OLD`` behavior of this policy is to always use the additional link
+flags when linking executables regardless of the value of the
+:prop_tgt:`ENABLE_EXPORTS` target property.
+
+The ``NEW`` behavior of this policy is to only use the additional link
+flags when linking executables if the :prop_tgt:`ENABLE_EXPORTS` target
+property is set to ``True``.
+
+This policy was introduced in CMake version 3.4. Unlike most policies,
+CMake version |release| does *not* warn by default when this policy
+is not set and simply uses OLD behavior. See documentation of the
+:variable:`CMAKE_POLICY_WARNING_CMP0065 <CMAKE_POLICY_WARNING_CMP<NNNN>>`
+variable to control the warning.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/DEPRECATED.txt b/Help/policy/DEPRECATED.txt
new file mode 100644
index 000000000..f66de55ae
--- /dev/null
+++ b/Help/policy/DEPRECATED.txt
@@ -0,0 +1,4 @@
+.. note::
+ The ``OLD`` behavior of a policy is
+ :manual:`deprecated by definition <cmake-policies(7)>`
+ and may be removed in a future version of CMake.
diff --git a/Help/policy/DISALLOWED_COMMAND.txt b/Help/policy/DISALLOWED_COMMAND.txt
new file mode 100644
index 000000000..36280d2b6
--- /dev/null
+++ b/Help/policy/DISALLOWED_COMMAND.txt
@@ -0,0 +1,9 @@
+CMake >= |disallowed_version| prefer that this command never be called.
+The OLD behavior for this policy is to allow the command to be called.
+The NEW behavior for this policy is to issue a FATAL_ERROR when the
+command is called.
+
+This policy was introduced in CMake version |disallowed_version|.
+CMake version |release| warns when the policy is not set and uses
+OLD behavior. Use the cmake_policy command to set it to OLD or
+NEW explicitly.
diff --git a/Help/prop_cache/ADVANCED.rst b/Help/prop_cache/ADVANCED.rst
new file mode 100644
index 000000000..a0a4f73bb
--- /dev/null
+++ b/Help/prop_cache/ADVANCED.rst
@@ -0,0 +1,8 @@
+ADVANCED
+--------
+
+True if entry should be hidden by default in GUIs.
+
+This is a boolean value indicating whether the entry is considered
+interesting only for advanced configuration. The mark_as_advanced()
+command modifies this property.
diff --git a/Help/prop_cache/HELPSTRING.rst b/Help/prop_cache/HELPSTRING.rst
new file mode 100644
index 000000000..71a86d055
--- /dev/null
+++ b/Help/prop_cache/HELPSTRING.rst
@@ -0,0 +1,7 @@
+HELPSTRING
+----------
+
+Help associated with entry in GUIs.
+
+This string summarizes the purpose of an entry to help users set it
+through a CMake GUI.
diff --git a/Help/prop_cache/MODIFIED.rst b/Help/prop_cache/MODIFIED.rst
new file mode 100644
index 000000000..3ad70354d
--- /dev/null
+++ b/Help/prop_cache/MODIFIED.rst
@@ -0,0 +1,7 @@
+MODIFIED
+--------
+
+Internal management property. Do not set or get.
+
+This is an internal cache entry property managed by CMake to track
+interactive user modification of entries. Ignore it.
diff --git a/Help/prop_cache/STRINGS.rst b/Help/prop_cache/STRINGS.rst
new file mode 100644
index 000000000..2f8e32e3f
--- /dev/null
+++ b/Help/prop_cache/STRINGS.rst
@@ -0,0 +1,9 @@
+STRINGS
+-------
+
+Enumerate possible STRING entry values for GUI selection.
+
+For cache entries with type STRING, this enumerates a set of values.
+CMake GUIs may use this to provide a selection widget instead of a
+generic string entry field. This is for convenience only. CMake does
+not enforce that the value matches one of those listed.
diff --git a/Help/prop_cache/TYPE.rst b/Help/prop_cache/TYPE.rst
new file mode 100644
index 000000000..eb75c2ab2
--- /dev/null
+++ b/Help/prop_cache/TYPE.rst
@@ -0,0 +1,21 @@
+TYPE
+----
+
+Widget type for entry in GUIs.
+
+Cache entry values are always strings, but CMake GUIs present widgets
+to help users set values. The GUIs use this property as a hint to
+determine the widget type. Valid TYPE values are:
+
+::
+
+ BOOL = Boolean ON/OFF value.
+ PATH = Path to a directory.
+ FILEPATH = Path to a file.
+ STRING = Generic string value.
+ INTERNAL = Do not present in GUI at all.
+ STATIC = Value managed by CMake, do not change.
+ UNINITIALIZED = Type not yet specified.
+
+Generally the TYPE of a cache entry should be set by the command which
+creates it (set, option, find_library, etc.).
diff --git a/Help/prop_cache/VALUE.rst b/Help/prop_cache/VALUE.rst
new file mode 100644
index 000000000..59aabd431
--- /dev/null
+++ b/Help/prop_cache/VALUE.rst
@@ -0,0 +1,7 @@
+VALUE
+-----
+
+Value of a cache entry.
+
+This property maps to the actual value of a cache entry. Setting this
+property always sets the value without checking, so use with care.
diff --git a/Help/prop_dir/ADDITIONAL_MAKE_CLEAN_FILES.rst b/Help/prop_dir/ADDITIONAL_MAKE_CLEAN_FILES.rst
new file mode 100644
index 000000000..e32eed3ed
--- /dev/null
+++ b/Help/prop_dir/ADDITIONAL_MAKE_CLEAN_FILES.rst
@@ -0,0 +1,7 @@
+ADDITIONAL_MAKE_CLEAN_FILES
+---------------------------
+
+Additional files to clean during the make clean stage.
+
+A list of files that will be cleaned as a part of the "make clean"
+stage.
diff --git a/Help/prop_dir/CACHE_VARIABLES.rst b/Help/prop_dir/CACHE_VARIABLES.rst
new file mode 100644
index 000000000..2c66f939e
--- /dev/null
+++ b/Help/prop_dir/CACHE_VARIABLES.rst
@@ -0,0 +1,7 @@
+CACHE_VARIABLES
+---------------
+
+List of cache variables available in the current directory.
+
+This read-only property specifies the list of CMake cache variables
+currently defined. It is intended for debugging purposes.
diff --git a/Help/prop_dir/CLEAN_NO_CUSTOM.rst b/Help/prop_dir/CLEAN_NO_CUSTOM.rst
new file mode 100644
index 000000000..5ae78bf75
--- /dev/null
+++ b/Help/prop_dir/CLEAN_NO_CUSTOM.rst
@@ -0,0 +1,6 @@
+CLEAN_NO_CUSTOM
+---------------
+
+Set to true to tell :ref:`Makefile Generators` not to remove the outputs of
+custom commands for this directory during the ``make clean`` operation.
+This is ignored on other generators because it is not possible to implement.
diff --git a/Help/prop_dir/CMAKE_CONFIGURE_DEPENDS.rst b/Help/prop_dir/CMAKE_CONFIGURE_DEPENDS.rst
new file mode 100644
index 000000000..b1aef1966
--- /dev/null
+++ b/Help/prop_dir/CMAKE_CONFIGURE_DEPENDS.rst
@@ -0,0 +1,9 @@
+CMAKE_CONFIGURE_DEPENDS
+-----------------------
+
+Tell CMake about additional input files to the configuration process.
+If any named file is modified the build system will re-run CMake to
+re-configure the file and generate the build system again.
+
+Specify files as a semicolon-separated list of paths. Relative paths
+are interpreted as relative to the current source directory.
diff --git a/Help/prop_dir/COMPILE_DEFINITIONS.rst b/Help/prop_dir/COMPILE_DEFINITIONS.rst
new file mode 100644
index 000000000..ab7e7f058
--- /dev/null
+++ b/Help/prop_dir/COMPILE_DEFINITIONS.rst
@@ -0,0 +1,32 @@
+COMPILE_DEFINITIONS
+-------------------
+
+Preprocessor definitions for compiling a directory's sources.
+
+This property specifies the list of options given so far to the
+:command:`add_definitions` command.
+
+The ``COMPILE_DEFINITIONS`` property may be set to a semicolon-separated
+list of preprocessor definitions using the syntax ``VAR`` or ``VAR=value``.
+Function-style definitions are not supported. CMake will
+automatically escape the value correctly for the native build system
+(note that CMake language syntax may require escapes to specify some
+values).
+
+This property will be initialized in each directory by its value in the
+directory's parent.
+
+CMake will automatically drop some definitions that are not supported
+by the native build tool. The VS6 IDE does not support definition
+values with spaces (but NMake does).
+
+.. include:: /include/COMPILE_DEFINITIONS_DISCLAIMER.txt
+
+Contents of ``COMPILE_DEFINITIONS`` may use "generator expressions" with
+the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions. See the :manual:`cmake-buildsystem(7)`
+manual for more on defining buildsystem properties.
+
+The corresponding :prop_dir:`COMPILE_DEFINITIONS_<CONFIG>` property may
+be set to specify per-configuration definitions. Generator expressions
+should be preferred instead of setting the alternative property.
diff --git a/Help/prop_dir/COMPILE_DEFINITIONS_CONFIG.rst b/Help/prop_dir/COMPILE_DEFINITIONS_CONFIG.rst
new file mode 100644
index 000000000..a6af45f35
--- /dev/null
+++ b/Help/prop_dir/COMPILE_DEFINITIONS_CONFIG.rst
@@ -0,0 +1,19 @@
+COMPILE_DEFINITIONS_<CONFIG>
+----------------------------
+
+Ignored. See CMake Policy :policy:`CMP0043`.
+
+Per-configuration preprocessor definitions in a directory.
+
+This is the configuration-specific version of :prop_dir:`COMPILE_DEFINITIONS`
+where ``<CONFIG>`` is an upper-case name (ex. ``COMPILE_DEFINITIONS_DEBUG``).
+
+This property will be initialized in each directory by its value in
+the directory's parent.
+
+Contents of ``COMPILE_DEFINITIONS_<CONFIG>`` may use "generator expressions"
+with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions. See the :manual:`cmake-buildsystem(7)`
+manual for more on defining buildsystem properties.
+
+Generator expressions should be preferred instead of setting this property.
diff --git a/Help/prop_dir/COMPILE_OPTIONS.rst b/Help/prop_dir/COMPILE_OPTIONS.rst
new file mode 100644
index 000000000..877deb000
--- /dev/null
+++ b/Help/prop_dir/COMPILE_OPTIONS.rst
@@ -0,0 +1,16 @@
+COMPILE_OPTIONS
+---------------
+
+List of options to pass to the compiler.
+
+This property holds a :ref:`;-list <CMake Language Lists>` of options
+given so far to the :command:`add_compile_options` command.
+
+This property is used to initialize the :prop_tgt:`COMPILE_OPTIONS` target
+property when a target is created, which is used by the generators to set
+the options for the compiler.
+
+Contents of ``COMPILE_OPTIONS`` may use "generator expressions" with the
+syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual
+for available expressions. See the :manual:`cmake-buildsystem(7)` manual
+for more on defining buildsystem properties.
diff --git a/Help/prop_dir/DEFINITIONS.rst b/Help/prop_dir/DEFINITIONS.rst
new file mode 100644
index 000000000..79ac3f346
--- /dev/null
+++ b/Help/prop_dir/DEFINITIONS.rst
@@ -0,0 +1,13 @@
+DEFINITIONS
+-----------
+
+For CMake 2.4 compatibility only. Use :prop_dir:`COMPILE_DEFINITIONS`
+instead.
+
+This read-only property specifies the list of flags given so far to
+the :command:`add_definitions` command. It is intended for debugging
+purposes. Use the :prop_dir:`COMPILE_DEFINITIONS` directory property
+instead.
+
+This built-in read-only property does not exist if policy
+:policy:`CMP0059` is set to ``NEW``.
diff --git a/Help/prop_dir/EXCLUDE_FROM_ALL.rst b/Help/prop_dir/EXCLUDE_FROM_ALL.rst
new file mode 100644
index 000000000..1aa24e44b
--- /dev/null
+++ b/Help/prop_dir/EXCLUDE_FROM_ALL.rst
@@ -0,0 +1,9 @@
+EXCLUDE_FROM_ALL
+----------------
+
+Exclude the directory from the all target of its parent.
+
+A property on a directory that indicates if its targets are excluded
+from the default build target. If it is not, then with a Makefile for
+example typing make will cause the targets to be built. The same
+concept applies to the default build of other generators.
diff --git a/Help/prop_dir/IMPLICIT_DEPENDS_INCLUDE_TRANSFORM.rst b/Help/prop_dir/IMPLICIT_DEPENDS_INCLUDE_TRANSFORM.rst
new file mode 100644
index 000000000..993f6200e
--- /dev/null
+++ b/Help/prop_dir/IMPLICIT_DEPENDS_INCLUDE_TRANSFORM.rst
@@ -0,0 +1,34 @@
+IMPLICIT_DEPENDS_INCLUDE_TRANSFORM
+----------------------------------
+
+Specify #include line transforms for dependencies in a directory.
+
+This property specifies rules to transform macro-like #include lines
+during implicit dependency scanning of C and C++ source files. The
+list of rules must be semicolon-separated with each entry of the form
+"A_MACRO(%)=value-with-%" (the % must be literal). During dependency
+scanning occurrences of A_MACRO(...) on #include lines will be
+replaced by the value given with the macro argument substituted for
+'%'. For example, the entry
+
+::
+
+ MYDIR(%)=<mydir/%>
+
+will convert lines of the form
+
+::
+
+ #include MYDIR(myheader.h)
+
+to
+
+::
+
+ #include <mydir/myheader.h>
+
+allowing the dependency to be followed.
+
+This property applies to sources in all targets within a directory.
+The property value is initialized in each directory by its value in
+the directory's parent.
diff --git a/Help/prop_dir/INCLUDE_DIRECTORIES.rst b/Help/prop_dir/INCLUDE_DIRECTORIES.rst
new file mode 100644
index 000000000..baba49bf3
--- /dev/null
+++ b/Help/prop_dir/INCLUDE_DIRECTORIES.rst
@@ -0,0 +1,26 @@
+INCLUDE_DIRECTORIES
+-------------------
+
+List of preprocessor include file search directories.
+
+This property specifies the list of directories given so far to the
+:command:`include_directories` command.
+
+This property is used to populate the :prop_tgt:`INCLUDE_DIRECTORIES`
+target property, which is used by the generators to set the include
+directories for the compiler.
+
+In addition to accepting values from that command, values may be set
+directly on any directory using the :command:`set_property` command. A
+directory gets its initial value from its parent directory if it has one.
+The intial value of the :prop_tgt:`INCLUDE_DIRECTORIES` target property
+comes from the value of this property. Both directory and target property
+values are adjusted by calls to the :command:`include_directories` command.
+
+The target property values are used by the generators to set the
+include paths for the compiler.
+
+Contents of ``INCLUDE_DIRECTORIES`` may use "generator expressions" with
+the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions. See the :manual:`cmake-buildsystem(7)`
+manual for more on defining buildsystem properties.
diff --git a/Help/prop_dir/INCLUDE_REGULAR_EXPRESSION.rst b/Help/prop_dir/INCLUDE_REGULAR_EXPRESSION.rst
new file mode 100644
index 000000000..bb90c61a7
--- /dev/null
+++ b/Help/prop_dir/INCLUDE_REGULAR_EXPRESSION.rst
@@ -0,0 +1,9 @@
+INCLUDE_REGULAR_EXPRESSION
+--------------------------
+
+Include file scanning regular expression.
+
+This property specifies the regular expression used during
+dependency scanning to match include files that should be followed.
+See the :command:`include_regular_expression` command for a high-level
+interface to set this property.
diff --git a/Help/prop_dir/INTERPROCEDURAL_OPTIMIZATION.rst b/Help/prop_dir/INTERPROCEDURAL_OPTIMIZATION.rst
new file mode 100644
index 000000000..0c78dfbe7
--- /dev/null
+++ b/Help/prop_dir/INTERPROCEDURAL_OPTIMIZATION.rst
@@ -0,0 +1,7 @@
+INTERPROCEDURAL_OPTIMIZATION
+----------------------------
+
+Enable interprocedural optimization for targets in a directory.
+
+If set to true, enables interprocedural optimizations if they are
+known to be supported by the compiler.
diff --git a/Help/prop_dir/INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst b/Help/prop_dir/INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst
new file mode 100644
index 000000000..325208656
--- /dev/null
+++ b/Help/prop_dir/INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst
@@ -0,0 +1,8 @@
+INTERPROCEDURAL_OPTIMIZATION_<CONFIG>
+-------------------------------------
+
+Per-configuration interprocedural optimization for a directory.
+
+This is a per-configuration version of INTERPROCEDURAL_OPTIMIZATION.
+If set, this property overrides the generic property for the named
+configuration.
diff --git a/Help/prop_dir/LINK_DIRECTORIES.rst b/Help/prop_dir/LINK_DIRECTORIES.rst
new file mode 100644
index 000000000..fa375766d
--- /dev/null
+++ b/Help/prop_dir/LINK_DIRECTORIES.rst
@@ -0,0 +1,8 @@
+LINK_DIRECTORIES
+----------------
+
+List of linker search directories.
+
+This read-only property specifies the list of directories given so far
+to the link_directories command. It is intended for debugging
+purposes.
diff --git a/Help/prop_dir/LISTFILE_STACK.rst b/Help/prop_dir/LISTFILE_STACK.rst
new file mode 100644
index 000000000..f729c1e78
--- /dev/null
+++ b/Help/prop_dir/LISTFILE_STACK.rst
@@ -0,0 +1,9 @@
+LISTFILE_STACK
+--------------
+
+The current stack of listfiles being processed.
+
+This property is mainly useful when trying to debug errors in your
+CMake scripts. It returns a list of what list files are currently
+being processed, in order. So if one listfile does an INCLUDE command
+then that is effectively pushing the included listfile onto the stack.
diff --git a/Help/prop_dir/MACROS.rst b/Help/prop_dir/MACROS.rst
new file mode 100644
index 000000000..e4feadaa5
--- /dev/null
+++ b/Help/prop_dir/MACROS.rst
@@ -0,0 +1,8 @@
+MACROS
+------
+
+List of macro commands available in the current directory.
+
+This read-only property specifies the list of CMake macros currently
+defined. It is intended for debugging purposes. See the macro
+command.
diff --git a/Help/prop_dir/PARENT_DIRECTORY.rst b/Help/prop_dir/PARENT_DIRECTORY.rst
new file mode 100644
index 000000000..3bc5824c9
--- /dev/null
+++ b/Help/prop_dir/PARENT_DIRECTORY.rst
@@ -0,0 +1,8 @@
+PARENT_DIRECTORY
+----------------
+
+Source directory that added current subdirectory.
+
+This read-only property specifies the source directory that added the
+current source directory as a subdirectory of the build. In the
+top-level directory the value is the empty-string.
diff --git a/Help/prop_dir/RULE_LAUNCH_COMPILE.rst b/Help/prop_dir/RULE_LAUNCH_COMPILE.rst
new file mode 100644
index 000000000..342d0ae79
--- /dev/null
+++ b/Help/prop_dir/RULE_LAUNCH_COMPILE.rst
@@ -0,0 +1,7 @@
+RULE_LAUNCH_COMPILE
+-------------------
+
+Specify a launcher for compile rules.
+
+See the global property of the same name for details. This overrides
+the global property for a directory.
diff --git a/Help/prop_dir/RULE_LAUNCH_CUSTOM.rst b/Help/prop_dir/RULE_LAUNCH_CUSTOM.rst
new file mode 100644
index 000000000..93d1e0111
--- /dev/null
+++ b/Help/prop_dir/RULE_LAUNCH_CUSTOM.rst
@@ -0,0 +1,7 @@
+RULE_LAUNCH_CUSTOM
+------------------
+
+Specify a launcher for custom rules.
+
+See the global property of the same name for details. This overrides
+the global property for a directory.
diff --git a/Help/prop_dir/RULE_LAUNCH_LINK.rst b/Help/prop_dir/RULE_LAUNCH_LINK.rst
new file mode 100644
index 000000000..3cfb2369b
--- /dev/null
+++ b/Help/prop_dir/RULE_LAUNCH_LINK.rst
@@ -0,0 +1,7 @@
+RULE_LAUNCH_LINK
+----------------
+
+Specify a launcher for link rules.
+
+See the global property of the same name for details. This overrides
+the global property for a directory.
diff --git a/Help/prop_dir/TEST_INCLUDE_FILE.rst b/Help/prop_dir/TEST_INCLUDE_FILE.rst
new file mode 100644
index 000000000..e47795191
--- /dev/null
+++ b/Help/prop_dir/TEST_INCLUDE_FILE.rst
@@ -0,0 +1,7 @@
+TEST_INCLUDE_FILE
+-----------------
+
+A cmake file that will be included when ctest is run.
+
+If you specify TEST_INCLUDE_FILE, that file will be included and
+processed when ctest is run on the directory.
diff --git a/Help/prop_dir/VARIABLES.rst b/Help/prop_dir/VARIABLES.rst
new file mode 100644
index 000000000..0328295c3
--- /dev/null
+++ b/Help/prop_dir/VARIABLES.rst
@@ -0,0 +1,7 @@
+VARIABLES
+---------
+
+List of variables defined in the current directory.
+
+This read-only property specifies the list of CMake variables
+currently defined. It is intended for debugging purposes.
diff --git a/Help/prop_dir/VS_GLOBAL_SECTION_POST_section.rst b/Help/prop_dir/VS_GLOBAL_SECTION_POST_section.rst
new file mode 100644
index 000000000..eb9183288
--- /dev/null
+++ b/Help/prop_dir/VS_GLOBAL_SECTION_POST_section.rst
@@ -0,0 +1,29 @@
+VS_GLOBAL_SECTION_POST_<section>
+--------------------------------
+
+Specify a postSolution global section in Visual Studio.
+
+Setting a property like this generates an entry of the following form
+in the solution file:
+
+::
+
+ GlobalSection(<section>) = postSolution
+ <contents based on property value>
+ EndGlobalSection
+
+The property must be set to a semicolon-separated list of key=value
+pairs. Each such pair will be transformed into an entry in the
+solution global section. Whitespace around key and value is ignored.
+List elements which do not contain an equal sign are skipped.
+
+This property only works for Visual Studio 7 and above; it is ignored
+on other generators. The property only applies when set on a
+directory whose CMakeLists.txt contains a project() command.
+
+Note that CMake generates postSolution sections ExtensibilityGlobals
+and ExtensibilityAddIns by default. If you set the corresponding
+property, it will override the default section. For example, setting
+VS_GLOBAL_SECTION_POST_ExtensibilityGlobals will override the default
+contents of the ExtensibilityGlobals section, while keeping
+ExtensibilityAddIns on its default.
diff --git a/Help/prop_dir/VS_GLOBAL_SECTION_PRE_section.rst b/Help/prop_dir/VS_GLOBAL_SECTION_PRE_section.rst
new file mode 100644
index 000000000..fbcd9e6f3
--- /dev/null
+++ b/Help/prop_dir/VS_GLOBAL_SECTION_PRE_section.rst
@@ -0,0 +1,22 @@
+VS_GLOBAL_SECTION_PRE_<section>
+-------------------------------
+
+Specify a preSolution global section in Visual Studio.
+
+Setting a property like this generates an entry of the following form
+in the solution file:
+
+::
+
+ GlobalSection(<section>) = preSolution
+ <contents based on property value>
+ EndGlobalSection
+
+The property must be set to a semicolon-separated list of key=value
+pairs. Each such pair will be transformed into an entry in the
+solution global section. Whitespace around key and value is ignored.
+List elements which do not contain an equal sign are skipped.
+
+This property only works for Visual Studio 7 and above; it is ignored
+on other generators. The property only applies when set on a
+directory whose CMakeLists.txt contains a project() command.
diff --git a/Help/prop_gbl/ALLOW_DUPLICATE_CUSTOM_TARGETS.rst b/Help/prop_gbl/ALLOW_DUPLICATE_CUSTOM_TARGETS.rst
new file mode 100644
index 000000000..8fab50345
--- /dev/null
+++ b/Help/prop_gbl/ALLOW_DUPLICATE_CUSTOM_TARGETS.rst
@@ -0,0 +1,19 @@
+ALLOW_DUPLICATE_CUSTOM_TARGETS
+------------------------------
+
+Allow duplicate custom targets to be created.
+
+Normally CMake requires that all targets built in a project have
+globally unique logical names (see policy CMP0002). This is necessary
+to generate meaningful project file names in Xcode and VS IDE
+generators. It also allows the target names to be referenced
+unambiguously.
+
+Makefile generators are capable of supporting duplicate custom target
+names. For projects that care only about Makefile generators and do
+not wish to support Xcode or VS IDE generators, one may set this
+property to true to allow duplicate custom targets. The property
+allows multiple add_custom_target command calls in different
+directories to specify the same target name. However, setting this
+property will cause non-Makefile generators to produce an error and
+refuse to generate the project.
diff --git a/Help/prop_gbl/AUTOGEN_TARGETS_FOLDER.rst b/Help/prop_gbl/AUTOGEN_TARGETS_FOLDER.rst
new file mode 100644
index 000000000..5a69ef31d
--- /dev/null
+++ b/Help/prop_gbl/AUTOGEN_TARGETS_FOLDER.rst
@@ -0,0 +1,9 @@
+AUTOGEN_TARGETS_FOLDER
+----------------------
+
+Name of :prop_tgt:`FOLDER` for ``*_automoc`` targets that are added automatically by
+CMake for targets for which :prop_tgt:`AUTOMOC` is enabled.
+
+If not set, CMake uses the :prop_tgt:`FOLDER` property of the parent target as a
+default value for this property. See also the documentation for the
+:prop_tgt:`FOLDER` target property and the :prop_tgt:`AUTOMOC` target property.
diff --git a/Help/prop_gbl/AUTOMOC_TARGETS_FOLDER.rst b/Help/prop_gbl/AUTOMOC_TARGETS_FOLDER.rst
new file mode 100644
index 000000000..671f86a85
--- /dev/null
+++ b/Help/prop_gbl/AUTOMOC_TARGETS_FOLDER.rst
@@ -0,0 +1,11 @@
+AUTOMOC_TARGETS_FOLDER
+----------------------
+
+Name of :prop_tgt:`FOLDER` for ``*_automoc`` targets that are added automatically by
+CMake for targets for which :prop_tgt:`AUTOMOC` is enabled.
+
+This property is obsolete. Use :prop_gbl:`AUTOGEN_TARGETS_FOLDER` instead.
+
+If not set, CMake uses the :prop_tgt:`FOLDER` property of the parent target as a
+default value for this property. See also the documentation for the
+:prop_tgt:`FOLDER` target property and the :prop_tgt:`AUTOMOC` target property.
diff --git a/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst b/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst
new file mode 100644
index 000000000..3db4f1814
--- /dev/null
+++ b/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst
@@ -0,0 +1,303 @@
+CMAKE_CXX_KNOWN_FEATURES
+------------------------
+
+List of C++ features known to this version of CMake.
+
+The features listed in this global property may be known to be available to the
+C++ compiler. If the feature is available with the C++ compiler, it will
+be listed in the :variable:`CMAKE_CXX_COMPILE_FEATURES` variable.
+
+The features listed here may be used with the :command:`target_compile_features`
+command. See the :manual:`cmake-compile-features(7)` manual for information on
+compile features and a list of supported compilers.
+
+
+The features known to this version of CMake are:
+
+``cxx_aggregate_default_initializers``
+ Aggregate default initializers, as defined in N3605_.
+
+ .. _N3605: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3605.html
+
+``cxx_alias_templates``
+ Template aliases, as defined in N2258_.
+
+ .. _N2258: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf
+
+``cxx_alignas``
+ Alignment control ``alignas``, as defined in N2341_.
+
+ .. _N2341: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2341.pdf
+
+``cxx_alignof``
+ Alignment control ``alignof``, as defined in N2341_.
+
+ .. _N2341: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2341.pdf
+
+``cxx_attributes``
+ Generic attributes, as defined in N2761_.
+
+ .. _N2761: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2761.pdf
+
+``cxx_attribute_deprecated``
+ ``[[deprecated]]`` attribute, as defined in N3760_.
+
+ .. _N3760: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3760.html
+
+``cxx_auto_type``
+ Automatic type deduction, as defined in N1984_.
+
+ .. _N1984: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1984.pdf
+
+``cxx_binary_literals``
+ Binary literals, as defined in N3472_.
+
+ .. _N3472: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3472.pdf
+
+``cxx_constexpr``
+ Constant expressions, as defined in N2235_.
+
+ .. _N2235: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf
+
+``cxx_contextual_conversions``
+ Contextual conversions, as defined in N3323_.
+
+ .. _N3323: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3323.pdf
+
+``cxx_decltype_incomplete_return_types``
+ Decltype on incomplete return types, as defined in N3276_.
+
+ .. _N3276 : http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3276.pdf
+
+``cxx_decltype``
+ Decltype, as defined in N2343_.
+
+ .. _N2343: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2343.pdf
+
+``cxx_decltype_auto``
+ ``decltype(auto)`` semantics, as defined in N3638_.
+
+ .. _N3638: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3638.html
+
+``cxx_default_function_template_args``
+ Default template arguments for function templates, as defined in DR226_
+
+ .. _DR226: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#226
+
+``cxx_defaulted_functions``
+ Defaulted functions, as defined in N2346_.
+
+ .. _N2346: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm
+
+``cxx_defaulted_move_initializers``
+ Defaulted move initializers, as defined in N3053_.
+
+ .. _N3053: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3053.html
+
+``cxx_delegating_constructors``
+ Delegating constructors, as defined in N1986_.
+
+ .. _N1986: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf
+
+``cxx_deleted_functions``
+ Deleted functions, as defined in N2346_.
+
+ .. _N2346: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm
+
+``cxx_digit_separators``
+ Digit separators, as defined in N3781_.
+
+ .. _N3781: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3781.pdf
+
+``cxx_enum_forward_declarations``
+ Enum forward declarations, as defined in N2764_.
+
+ .. _N2764: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2764.pdf
+
+``cxx_explicit_conversions``
+ Explicit conversion operators, as defined in N2437_.
+
+ .. _N2437: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2437.pdf
+
+``cxx_extended_friend_declarations``
+ Extended friend declarations, as defined in N1791_.
+
+ .. _N1791: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1791.pdf
+
+``cxx_extern_templates``
+ Extern templates, as defined in N1987_.
+
+ .. _N1987: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1987.htm
+
+``cxx_final``
+ Override control ``final`` keyword, as defined in N2928_, N3206_ and N3272_.
+
+ .. _N2928: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2928.htm
+ .. _N3206: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3206.htm
+ .. _N3272: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3272.htm
+
+``cxx_func_identifier``
+ Predefined ``__func__`` identifier, as defined in N2340_.
+
+ .. _N2340: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2340.htm
+
+``cxx_generalized_initializers``
+ Initializer lists, as defined in N2672_.
+
+ .. _N2672: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2672.htm
+
+``cxx_generic_lambdas``
+ Generic lambdas, as defined in N3649_.
+
+ .. _N3649: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3649.html
+
+``cxx_inheriting_constructors``
+ Inheriting constructors, as defined in N2540_.
+
+ .. _N2540: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2540.htm
+
+``cxx_inline_namespaces``
+ Inline namespaces, as defined in N2535_.
+
+ .. _N2535: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2535.htm
+
+``cxx_lambdas``
+ Lambda functions, as defined in N2927_.
+
+ .. _N2927: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2927.pdf
+
+``cxx_lambda_init_captures``
+ Initialized lambda captures, as defined in N3648_.
+
+ .. _N3648: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3648.html
+
+``cxx_local_type_template_args``
+ Local and unnamed types as template arguments, as defined in N2657_.
+
+ .. _N2657: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm
+
+``cxx_long_long_type``
+ ``long long`` type, as defined in N1811_.
+
+ .. _N1811: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1811.pdf
+
+``cxx_noexcept``
+ Exception specifications, as defined in N3050_.
+
+ .. _N3050: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3050.html
+
+``cxx_nonstatic_member_init``
+ Non-static data member initialization, as defined in N2756_.
+
+ .. _N2756: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2756.htm
+
+``cxx_nullptr``
+ Null pointer, as defined in N2431_.
+
+ .. _N2431: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf
+
+``cxx_override``
+ Override control ``override`` keyword, as defined in N2928_, N3206_
+ and N3272_.
+
+ .. _N2928: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2928.htm
+ .. _N3206: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3206.htm
+ .. _N3272: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3272.htm
+
+``cxx_range_for``
+ Range-based for, as defined in N2930_.
+
+ .. _N2930: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2930.html
+
+``cxx_raw_string_literals``
+ Raw string literals, as defined in N2442_.
+
+ .. _N2442: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2442.htm
+
+``cxx_reference_qualified_functions``
+ Reference qualified functions, as defined in N2439_.
+
+ .. _N2439: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2439.htm
+
+``cxx_relaxed_constexpr``
+ Relaxed constexpr, as defined in N3652_.
+
+ .. _N3652: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3652.html
+
+``cxx_return_type_deduction``
+ Return type deduction on normal functions, as defined in N3386_.
+
+ .. _N3386: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3386.html
+
+``cxx_right_angle_brackets``
+ Right angle bracket parsing, as defined in N1757_.
+
+ .. _N1757: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html
+
+``cxx_rvalue_references``
+ R-value references, as defined in N2118_.
+
+ .. _N2118: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2118.html
+
+``cxx_sizeof_member``
+ Size of non-static data members, as defined in N2253_.
+
+ .. _N2253: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2253.html
+
+``cxx_static_assert``
+ Static assert, as defined in N1720_.
+
+ .. _N1720: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1720.html
+
+``cxx_strong_enums``
+ Strongly typed enums, as defined in N2347_.
+
+ .. _N2347: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf
+
+``cxx_thread_local``
+ Thread-local variables, as defined in N2659_.
+
+ .. _N2659: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2659.htm
+
+``cxx_trailing_return_types``
+ Automatic function return type, as defined in N2541_.
+
+ .. _N2541: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2541.htm
+
+``cxx_unicode_literals``
+ Unicode string literals, as defined in N2442_.
+
+ .. _N2442: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2442.htm
+
+``cxx_uniform_initialization``
+ Uniform intialization, as defined in N2640_.
+
+ .. _N2640: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2640.pdf
+
+``cxx_unrestricted_unions``
+ Unrestricted unions, as defined in N2544_.
+
+ .. _N2544: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2544.pdf
+
+``cxx_user_literals``
+ User-defined literals, as defined in N2765_.
+
+ .. _N2765: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2765.pdf
+
+``cxx_variable_templates``
+ Variable templates, as defined in N3651_.
+
+ .. _N3651: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3651.pdf
+
+``cxx_variadic_macros``
+ Variadic macros, as defined in N1653_.
+
+ .. _N1653: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1653.htm
+
+``cxx_variadic_templates``
+ Variadic templates, as defined in N2242_.
+
+ .. _N2242: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2242.pdf
+
+``cxx_template_template_parameters``
+ Template template parameters, as defined in ``ISO/IEC 14882:1998``.
diff --git a/Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst b/Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst
new file mode 100644
index 000000000..a08af0089
--- /dev/null
+++ b/Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst
@@ -0,0 +1,26 @@
+CMAKE_C_KNOWN_FEATURES
+----------------------
+
+List of C features known to this version of CMake.
+
+The features listed in this global property may be known to be available to the
+C compiler. If the feature is available with the C compiler, it will
+be listed in the :variable:`CMAKE_C_COMPILE_FEATURES` variable.
+
+The features listed here may be used with the :command:`target_compile_features`
+command. See the :manual:`cmake-compile-features(7)` manual for information on
+compile features and a list of supported compilers.
+
+The features known to this version of CMake are:
+
+``c_function_prototypes``
+ Function prototypes, as defined in ``ISO/IEC 9899:1990``.
+
+``c_restrict``
+ ``restrict`` keyword, as defined in ``ISO/IEC 9899:1999``.
+
+``c_static_assert``
+ Static assert, as defined in ``ISO/IEC 9899:2011``.
+
+``c_variadic_macros``
+ Variadic macros, as defined in ``ISO/IEC 9899:1999``.
diff --git a/Help/prop_gbl/DEBUG_CONFIGURATIONS.rst b/Help/prop_gbl/DEBUG_CONFIGURATIONS.rst
new file mode 100644
index 000000000..690143f82
--- /dev/null
+++ b/Help/prop_gbl/DEBUG_CONFIGURATIONS.rst
@@ -0,0 +1,14 @@
+DEBUG_CONFIGURATIONS
+--------------------
+
+Specify which configurations are for debugging.
+
+The value must be a semi-colon separated list of configuration names.
+Currently this property is used only by the target_link_libraries
+command (see its documentation for details). Additional uses may be
+defined in the future.
+
+This property must be set at the top level of the project and before
+the first target_link_libraries command invocation. If any entry in
+the list does not match a valid configuration for the project the
+behavior is undefined.
diff --git a/Help/prop_gbl/DISABLED_FEATURES.rst b/Help/prop_gbl/DISABLED_FEATURES.rst
new file mode 100644
index 000000000..111cdf67e
--- /dev/null
+++ b/Help/prop_gbl/DISABLED_FEATURES.rst
@@ -0,0 +1,11 @@
+DISABLED_FEATURES
+-----------------
+
+List of features which are disabled during the CMake run.
+
+List of features which are disabled during the CMake run. By default
+it contains the names of all packages which were not found. This is
+determined using the <NAME>_FOUND variables. Packages which are
+searched QUIET are not listed. A project can add its own features to
+this list. This property is used by the macros in
+FeatureSummary.cmake.
diff --git a/Help/prop_gbl/ECLIPSE_EXTRA_NATURES.rst b/Help/prop_gbl/ECLIPSE_EXTRA_NATURES.rst
new file mode 100644
index 000000000..6d1529d3a
--- /dev/null
+++ b/Help/prop_gbl/ECLIPSE_EXTRA_NATURES.rst
@@ -0,0 +1,8 @@
+ECLIPSE_EXTRA_NATURES
+---------------------
+
+List of natures to add to the generated Eclipse project file.
+
+Eclipse projects specify language plugins by using natures. This property
+should be set to the unique identifier for a nature (which looks like a Java
+package name).
diff --git a/Help/prop_gbl/ENABLED_FEATURES.rst b/Help/prop_gbl/ENABLED_FEATURES.rst
new file mode 100644
index 000000000..b03da5a45
--- /dev/null
+++ b/Help/prop_gbl/ENABLED_FEATURES.rst
@@ -0,0 +1,11 @@
+ENABLED_FEATURES
+----------------
+
+List of features which are enabled during the CMake run.
+
+List of features which are enabled during the CMake run. By default
+it contains the names of all packages which were found. This is
+determined using the <NAME>_FOUND variables. Packages which are
+searched QUIET are not listed. A project can add its own features to
+this list. This property is used by the macros in
+FeatureSummary.cmake.
diff --git a/Help/prop_gbl/ENABLED_LANGUAGES.rst b/Help/prop_gbl/ENABLED_LANGUAGES.rst
new file mode 100644
index 000000000..43e3c09f7
--- /dev/null
+++ b/Help/prop_gbl/ENABLED_LANGUAGES.rst
@@ -0,0 +1,6 @@
+ENABLED_LANGUAGES
+-----------------
+
+Read-only property that contains the list of currently enabled languages
+
+Set to list of currently enabled languages.
diff --git a/Help/prop_gbl/FIND_LIBRARY_USE_LIB64_PATHS.rst b/Help/prop_gbl/FIND_LIBRARY_USE_LIB64_PATHS.rst
new file mode 100644
index 000000000..185246cda
--- /dev/null
+++ b/Help/prop_gbl/FIND_LIBRARY_USE_LIB64_PATHS.rst
@@ -0,0 +1,9 @@
+FIND_LIBRARY_USE_LIB64_PATHS
+----------------------------
+
+Whether FIND_LIBRARY should automatically search lib64 directories.
+
+FIND_LIBRARY_USE_LIB64_PATHS is a boolean specifying whether the
+FIND_LIBRARY command should automatically search the lib64 variant of
+directories called lib in the search path when building 64-bit
+binaries.
diff --git a/Help/prop_gbl/FIND_LIBRARY_USE_OPENBSD_VERSIONING.rst b/Help/prop_gbl/FIND_LIBRARY_USE_OPENBSD_VERSIONING.rst
new file mode 100644
index 000000000..9a3edd869
--- /dev/null
+++ b/Help/prop_gbl/FIND_LIBRARY_USE_OPENBSD_VERSIONING.rst
@@ -0,0 +1,9 @@
+FIND_LIBRARY_USE_OPENBSD_VERSIONING
+-----------------------------------
+
+Whether FIND_LIBRARY should find OpenBSD-style shared libraries.
+
+This property is a boolean specifying whether the FIND_LIBRARY command
+should find shared libraries with OpenBSD-style versioned extension:
+".so.<major>.<minor>". The property is set to true on OpenBSD and
+false on other platforms.
diff --git a/Help/prop_gbl/GLOBAL_DEPENDS_DEBUG_MODE.rst b/Help/prop_gbl/GLOBAL_DEPENDS_DEBUG_MODE.rst
new file mode 100644
index 000000000..832503b51
--- /dev/null
+++ b/Help/prop_gbl/GLOBAL_DEPENDS_DEBUG_MODE.rst
@@ -0,0 +1,8 @@
+GLOBAL_DEPENDS_DEBUG_MODE
+-------------------------
+
+Enable global target dependency graph debug mode.
+
+CMake automatically analyzes the global inter-target dependency graph
+at the beginning of native build system generation. This property
+causes it to display details of its analysis to stderr.
diff --git a/Help/prop_gbl/GLOBAL_DEPENDS_NO_CYCLES.rst b/Help/prop_gbl/GLOBAL_DEPENDS_NO_CYCLES.rst
new file mode 100644
index 000000000..d10661e62
--- /dev/null
+++ b/Help/prop_gbl/GLOBAL_DEPENDS_NO_CYCLES.rst
@@ -0,0 +1,10 @@
+GLOBAL_DEPENDS_NO_CYCLES
+------------------------
+
+Disallow global target dependency graph cycles.
+
+CMake automatically analyzes the global inter-target dependency graph
+at the beginning of native build system generation. It reports an
+error if the dependency graph contains a cycle that does not consist
+of all STATIC library targets. This property tells CMake to disallow
+all cycles completely, even among static libraries.
diff --git a/Help/prop_gbl/IN_TRY_COMPILE.rst b/Help/prop_gbl/IN_TRY_COMPILE.rst
new file mode 100644
index 000000000..3a2ef5b65
--- /dev/null
+++ b/Help/prop_gbl/IN_TRY_COMPILE.rst
@@ -0,0 +1,6 @@
+IN_TRY_COMPILE
+--------------
+
+Read-only property that is true during a try-compile configuration.
+
+True when building a project inside a TRY_COMPILE or TRY_RUN command.
diff --git a/Help/prop_gbl/JOB_POOLS.rst b/Help/prop_gbl/JOB_POOLS.rst
new file mode 100644
index 000000000..2ce74b81c
--- /dev/null
+++ b/Help/prop_gbl/JOB_POOLS.rst
@@ -0,0 +1,23 @@
+JOB_POOLS
+---------
+
+Ninja only: List of available pools.
+
+A pool is a named integer property and defines the maximum number
+of concurrent jobs which can be started by a rule assigned to the pool.
+The :prop_gbl:`JOB_POOLS` property is a semicolon-separated list of
+pairs using the syntax NAME=integer (without a space after the equality sign).
+
+For instance:
+
+.. code-block:: cmake
+
+ set_property(GLOBAL PROPERTY JOB_POOLS two_jobs=2 ten_jobs=10)
+
+Defined pools could be used globally by setting
+:variable:`CMAKE_JOB_POOL_COMPILE` and :variable:`CMAKE_JOB_POOL_LINK`
+or per target by setting the target properties
+:prop_tgt:`JOB_POOL_COMPILE` and :prop_tgt:`JOB_POOL_LINK`.
+
+Build targets provided by CMake that are meant for individual interactive
+use, such as ``install``, are placed in the ``console`` pool automatically.
diff --git a/Help/prop_gbl/PACKAGES_FOUND.rst b/Help/prop_gbl/PACKAGES_FOUND.rst
new file mode 100644
index 000000000..61cce1fd8
--- /dev/null
+++ b/Help/prop_gbl/PACKAGES_FOUND.rst
@@ -0,0 +1,7 @@
+PACKAGES_FOUND
+--------------
+
+List of packages which were found during the CMake run.
+
+List of packages which were found during the CMake run. Whether a
+package has been found is determined using the <NAME>_FOUND variables.
diff --git a/Help/prop_gbl/PACKAGES_NOT_FOUND.rst b/Help/prop_gbl/PACKAGES_NOT_FOUND.rst
new file mode 100644
index 000000000..ca3c5bac6
--- /dev/null
+++ b/Help/prop_gbl/PACKAGES_NOT_FOUND.rst
@@ -0,0 +1,7 @@
+PACKAGES_NOT_FOUND
+------------------
+
+List of packages which were not found during the CMake run.
+
+List of packages which were not found during the CMake run. Whether a
+package has been found is determined using the <NAME>_FOUND variables.
diff --git a/Help/prop_gbl/PREDEFINED_TARGETS_FOLDER.rst b/Help/prop_gbl/PREDEFINED_TARGETS_FOLDER.rst
new file mode 100644
index 000000000..e85b823b1
--- /dev/null
+++ b/Help/prop_gbl/PREDEFINED_TARGETS_FOLDER.rst
@@ -0,0 +1,9 @@
+PREDEFINED_TARGETS_FOLDER
+-------------------------
+
+Name of FOLDER for targets that are added automatically by CMake.
+
+If not set, CMake uses "CMakePredefinedTargets" as a default value for
+this property. Targets such as INSTALL, PACKAGE and RUN_TESTS will be
+organized into this FOLDER. See also the documentation for the FOLDER
+target property.
diff --git a/Help/prop_gbl/REPORT_UNDEFINED_PROPERTIES.rst b/Help/prop_gbl/REPORT_UNDEFINED_PROPERTIES.rst
new file mode 100644
index 000000000..29ba36557
--- /dev/null
+++ b/Help/prop_gbl/REPORT_UNDEFINED_PROPERTIES.rst
@@ -0,0 +1,8 @@
+REPORT_UNDEFINED_PROPERTIES
+---------------------------
+
+If set, report any undefined properties to this file.
+
+If this property is set to a filename then when CMake runs it will
+report any properties or variables that were accessed but not defined
+into the filename specified in this property.
diff --git a/Help/prop_gbl/RULE_LAUNCH_COMPILE.rst b/Help/prop_gbl/RULE_LAUNCH_COMPILE.rst
new file mode 100644
index 000000000..e0df8784a
--- /dev/null
+++ b/Help/prop_gbl/RULE_LAUNCH_COMPILE.rst
@@ -0,0 +1,11 @@
+RULE_LAUNCH_COMPILE
+-------------------
+
+Specify a launcher for compile rules.
+
+:ref:`Makefile Generators` and the :generator:`Ninja` generator prefix
+compiler commands with the given launcher command line.
+This is intended to allow launchers to intercept build problems
+with high granularity. Other generators ignore this property
+because their underlying build systems provide no hook to wrap
+individual commands with a launcher.
diff --git a/Help/prop_gbl/RULE_LAUNCH_CUSTOM.rst b/Help/prop_gbl/RULE_LAUNCH_CUSTOM.rst
new file mode 100644
index 000000000..b20c59bcc
--- /dev/null
+++ b/Help/prop_gbl/RULE_LAUNCH_CUSTOM.rst
@@ -0,0 +1,11 @@
+RULE_LAUNCH_CUSTOM
+------------------
+
+Specify a launcher for custom rules.
+
+:ref:`Makefile Generators` and the :generator:`Ninja` generator prefix
+custom commands with the given launcher command line.
+This is intended to allow launchers to intercept build problems
+with high granularity. Other generators ignore this property
+because their underlying build systems provide no hook to wrap
+individual commands with a launcher.
diff --git a/Help/prop_gbl/RULE_LAUNCH_LINK.rst b/Help/prop_gbl/RULE_LAUNCH_LINK.rst
new file mode 100644
index 000000000..567bb6864
--- /dev/null
+++ b/Help/prop_gbl/RULE_LAUNCH_LINK.rst
@@ -0,0 +1,11 @@
+RULE_LAUNCH_LINK
+----------------
+
+Specify a launcher for link rules.
+
+:ref:`Makefile Generators` and the :generator:`Ninja` generator prefix
+link and archive commands with the given launcher command line.
+This is intended to allow launchers to intercept build problems
+with high granularity. Other generators ignore this property
+because their underlying build systems provide no hook to wrap
+individual commands with a launcher.
diff --git a/Help/prop_gbl/RULE_MESSAGES.rst b/Help/prop_gbl/RULE_MESSAGES.rst
new file mode 100644
index 000000000..38d83a36b
--- /dev/null
+++ b/Help/prop_gbl/RULE_MESSAGES.rst
@@ -0,0 +1,13 @@
+RULE_MESSAGES
+-------------
+
+Specify whether to report a message for each make rule.
+
+This property specifies whether Makefile generators should add a
+progress message describing what each build rule does. If the
+property is not set the default is ON. Set the property to OFF to
+disable granular messages and report only as each target completes.
+This is intended to allow scripted builds to avoid the build time cost
+of detailed reports. If a CMAKE_RULE_MESSAGES cache entry exists its
+value initializes the value of this property. Non-Makefile generators
+currently ignore this property.
diff --git a/Help/prop_gbl/TARGET_ARCHIVES_MAY_BE_SHARED_LIBS.rst b/Help/prop_gbl/TARGET_ARCHIVES_MAY_BE_SHARED_LIBS.rst
new file mode 100644
index 000000000..930febae7
--- /dev/null
+++ b/Help/prop_gbl/TARGET_ARCHIVES_MAY_BE_SHARED_LIBS.rst
@@ -0,0 +1,7 @@
+TARGET_ARCHIVES_MAY_BE_SHARED_LIBS
+----------------------------------
+
+Set if shared libraries may be named like archives.
+
+On AIX shared libraries may be named "lib<name>.a". This property is
+set to true on such platforms.
diff --git a/Help/prop_gbl/TARGET_MESSAGES.rst b/Help/prop_gbl/TARGET_MESSAGES.rst
new file mode 100644
index 000000000..275b0741d
--- /dev/null
+++ b/Help/prop_gbl/TARGET_MESSAGES.rst
@@ -0,0 +1,20 @@
+TARGET_MESSAGES
+---------------
+
+Specify whether to report the completion of each target.
+
+This property specifies whether :ref:`Makefile Generators` should
+add a progress message describing that each target has been completed.
+If the property is not set the default is ``ON``. Set the property
+to ``OFF`` to disable target completion messages.
+
+This option is intended to reduce build output when little or no
+work needs to be done to bring the build tree up to date.
+
+If a ``CMAKE_TARGET_MESSAGES`` cache entry exists its value
+initializes the value of this property.
+
+Non-Makefile generators currently ignore this property.
+
+See the counterpart property :prop_gbl:`RULE_MESSAGES` to disable
+everything except for target completion messages.
diff --git a/Help/prop_gbl/TARGET_SUPPORTS_SHARED_LIBS.rst b/Help/prop_gbl/TARGET_SUPPORTS_SHARED_LIBS.rst
new file mode 100644
index 000000000..f6e89fb83
--- /dev/null
+++ b/Help/prop_gbl/TARGET_SUPPORTS_SHARED_LIBS.rst
@@ -0,0 +1,9 @@
+TARGET_SUPPORTS_SHARED_LIBS
+---------------------------
+
+Does the target platform support shared libraries.
+
+TARGET_SUPPORTS_SHARED_LIBS is a boolean specifying whether the target
+platform supports shared libraries. Basically all current general
+general purpose OS do so, the exception are usually embedded systems
+with no or special OSs.
diff --git a/Help/prop_gbl/USE_FOLDERS.rst b/Help/prop_gbl/USE_FOLDERS.rst
new file mode 100644
index 000000000..fdbca9f4a
--- /dev/null
+++ b/Help/prop_gbl/USE_FOLDERS.rst
@@ -0,0 +1,9 @@
+USE_FOLDERS
+-----------
+
+Use the FOLDER target property to organize targets into folders.
+
+If not set, CMake treats this property as OFF by default. CMake
+generators that are capable of organizing into a hierarchy of folders
+use the values of the FOLDER target property to name those folders.
+See also the documentation for the FOLDER target property.
diff --git a/Help/prop_inst/CPACK_DESKTOP_SHORTCUTS.rst b/Help/prop_inst/CPACK_DESKTOP_SHORTCUTS.rst
new file mode 100644
index 000000000..11f2c036c
--- /dev/null
+++ b/Help/prop_inst/CPACK_DESKTOP_SHORTCUTS.rst
@@ -0,0 +1,7 @@
+CPACK_DESKTOP_SHORTCUTS
+-----------------------
+
+Species a list of shortcut names that should be created on the Desktop
+for this file.
+
+The property is currently only supported by the WIX generator.
diff --git a/Help/prop_inst/CPACK_NEVER_OVERWRITE.rst b/Help/prop_inst/CPACK_NEVER_OVERWRITE.rst
new file mode 100644
index 000000000..11f44d0df
--- /dev/null
+++ b/Help/prop_inst/CPACK_NEVER_OVERWRITE.rst
@@ -0,0 +1,6 @@
+CPACK_NEVER_OVERWRITE
+---------------------
+
+Request that this file not be overwritten on install or reinstall.
+
+The property is currently only supported by the WIX generator.
diff --git a/Help/prop_inst/CPACK_PERMANENT.rst b/Help/prop_inst/CPACK_PERMANENT.rst
new file mode 100644
index 000000000..5e191d08e
--- /dev/null
+++ b/Help/prop_inst/CPACK_PERMANENT.rst
@@ -0,0 +1,6 @@
+CPACK_PERMANENT
+---------------
+
+Request that this file not be removed on uninstall.
+
+The property is currently only supported by the WIX generator.
diff --git a/Help/prop_inst/CPACK_STARTUP_SHORTCUTS.rst b/Help/prop_inst/CPACK_STARTUP_SHORTCUTS.rst
new file mode 100644
index 000000000..8a160223d
--- /dev/null
+++ b/Help/prop_inst/CPACK_STARTUP_SHORTCUTS.rst
@@ -0,0 +1,7 @@
+CPACK_STARTUP_SHORTCUTS
+-----------------------
+
+Species a list of shortcut names that should be created in the Startup folder
+for this file.
+
+The property is currently only supported by the WIX generator.
diff --git a/Help/prop_inst/CPACK_START_MENU_SHORTCUTS.rst b/Help/prop_inst/CPACK_START_MENU_SHORTCUTS.rst
new file mode 100644
index 000000000..d30ea39fd
--- /dev/null
+++ b/Help/prop_inst/CPACK_START_MENU_SHORTCUTS.rst
@@ -0,0 +1,7 @@
+CPACK_START_MENU_SHORTCUTS
+--------------------------
+
+Species a list of shortcut names that should be created in the Start Menu
+for this file.
+
+The property is currently only supported by the WIX generator.
diff --git a/Help/prop_inst/CPACK_WIX_ACL.rst b/Help/prop_inst/CPACK_WIX_ACL.rst
new file mode 100644
index 000000000..4e13ec48c
--- /dev/null
+++ b/Help/prop_inst/CPACK_WIX_ACL.rst
@@ -0,0 +1,19 @@
+CPACK_WIX_ACL
+-------------
+
+Specifies access permissions for files or directories
+installed by a WiX installer.
+
+The property can contain multiple list entries,
+each of which has to match the following format.
+
+::
+
+ <user>[@<domain>]=<permission>[,<permission>]
+
+``<user>`` and ``<domain>`` specify the windows user and domain for which the
+``<Permission>`` element should be generated.
+
+``<permission>`` is any of the YesNoType attributes listed here::
+
+ http://wixtoolset.org/documentation/manual/v3/xsd/wix/permission.html
diff --git a/Help/prop_sf/ABSTRACT.rst b/Help/prop_sf/ABSTRACT.rst
new file mode 100644
index 000000000..339d11528
--- /dev/null
+++ b/Help/prop_sf/ABSTRACT.rst
@@ -0,0 +1,9 @@
+ABSTRACT
+--------
+
+Is this source file an abstract class.
+
+A property on a source file that indicates if the source file
+represents a class that is abstract. This only makes sense for
+languages that have a notion of an abstract class and it is only used
+by some tools that wrap classes into other languages.
diff --git a/Help/prop_sf/AUTORCC_OPTIONS.rst b/Help/prop_sf/AUTORCC_OPTIONS.rst
new file mode 100644
index 000000000..d9dc4d33e
--- /dev/null
+++ b/Help/prop_sf/AUTORCC_OPTIONS.rst
@@ -0,0 +1,13 @@
+AUTORCC_OPTIONS
+---------------
+
+Additional options for ``rcc`` when using :prop_tgt:`AUTORCC`
+
+This property holds additional command line options which will be used when
+``rcc`` is executed during the build via :prop_tgt:`AUTORCC`, i.e. it is equivalent to the
+optional ``OPTIONS`` argument of the :module:`qt4_add_resources() <FindQt4>` macro.
+
+By default it is empty.
+
+The options set on the ``.qrc`` source file may override :prop_tgt:`AUTORCC_OPTIONS` set
+on the target.
diff --git a/Help/prop_sf/AUTOUIC_OPTIONS.rst b/Help/prop_sf/AUTOUIC_OPTIONS.rst
new file mode 100644
index 000000000..bb48da90f
--- /dev/null
+++ b/Help/prop_sf/AUTOUIC_OPTIONS.rst
@@ -0,0 +1,14 @@
+AUTOUIC_OPTIONS
+---------------
+
+Additional options for ``uic`` when using :prop_tgt:`AUTOUIC`
+
+This property holds additional command line options
+which will be used when ``uic`` is executed during the build via :prop_tgt:`AUTOUIC`,
+i.e. it is equivalent to the optional ``OPTIONS`` argument of the
+:module:`qt4_wrap_ui() <FindQt4>` macro.
+
+By default it is empty.
+
+The options set on the ``.ui`` source file may override :prop_tgt:`AUTOUIC_OPTIONS` set
+on the target.
diff --git a/Help/prop_sf/COMPILE_DEFINITIONS.rst b/Help/prop_sf/COMPILE_DEFINITIONS.rst
new file mode 100644
index 000000000..7f7e7c795
--- /dev/null
+++ b/Help/prop_sf/COMPILE_DEFINITIONS.rst
@@ -0,0 +1,20 @@
+COMPILE_DEFINITIONS
+-------------------
+
+Preprocessor definitions for compiling a source file.
+
+The COMPILE_DEFINITIONS property may be set to a semicolon-separated
+list of preprocessor definitions using the syntax VAR or VAR=value.
+Function-style definitions are not supported. CMake will
+automatically escape the value correctly for the native build system
+(note that CMake language syntax may require escapes to specify some
+values). This property may be set on a per-configuration basis using
+the name COMPILE_DEFINITIONS_<CONFIG> where <CONFIG> is an upper-case
+name (ex. "COMPILE_DEFINITIONS_DEBUG").
+
+CMake will automatically drop some definitions that are not supported
+by the native build tool. The VS6 IDE does not support definition
+values with spaces (but NMake does). Xcode does not support
+per-configuration definitions on source files.
+
+.. include:: /include/COMPILE_DEFINITIONS_DISCLAIMER.txt
diff --git a/Help/prop_sf/COMPILE_DEFINITIONS_CONFIG.rst b/Help/prop_sf/COMPILE_DEFINITIONS_CONFIG.rst
new file mode 100644
index 000000000..848707647
--- /dev/null
+++ b/Help/prop_sf/COMPILE_DEFINITIONS_CONFIG.rst
@@ -0,0 +1,10 @@
+COMPILE_DEFINITIONS_<CONFIG>
+----------------------------
+
+Ignored. See CMake Policy :policy:`CMP0043`.
+
+Per-configuration preprocessor definitions on a source file.
+
+This is the configuration-specific version of COMPILE_DEFINITIONS.
+Note that Xcode does not support per-configuration source file flags
+so this property will be ignored by the Xcode generator.
diff --git a/Help/prop_sf/COMPILE_FLAGS.rst b/Help/prop_sf/COMPILE_FLAGS.rst
new file mode 100644
index 000000000..daba50231
--- /dev/null
+++ b/Help/prop_sf/COMPILE_FLAGS.rst
@@ -0,0 +1,8 @@
+COMPILE_FLAGS
+-------------
+
+Additional flags to be added when compiling this source file.
+
+These flags will be added to the list of compile flags when this
+source file builds. Use COMPILE_DEFINITIONS to pass additional
+preprocessor definitions.
diff --git a/Help/prop_sf/EXTERNAL_OBJECT.rst b/Help/prop_sf/EXTERNAL_OBJECT.rst
new file mode 100644
index 000000000..efa0e9bea
--- /dev/null
+++ b/Help/prop_sf/EXTERNAL_OBJECT.rst
@@ -0,0 +1,8 @@
+EXTERNAL_OBJECT
+---------------
+
+If set to true then this is an object file.
+
+If this property is set to true then the source file is really an
+object file and should not be compiled. It will still be linked into
+the target though.
diff --git a/Help/prop_sf/Fortran_FORMAT.rst b/Help/prop_sf/Fortran_FORMAT.rst
new file mode 100644
index 000000000..69e34aafd
--- /dev/null
+++ b/Help/prop_sf/Fortran_FORMAT.rst
@@ -0,0 +1,9 @@
+Fortran_FORMAT
+--------------
+
+Set to FIXED or FREE to indicate the Fortran source layout.
+
+This property tells CMake whether a given Fortran source file uses
+fixed-format or free-format. CMake will pass the corresponding format
+flag to the compiler. Consider using the target-wide Fortran_FORMAT
+property if all source files in a target share the same format.
diff --git a/Help/prop_sf/GENERATED.rst b/Help/prop_sf/GENERATED.rst
new file mode 100644
index 000000000..a3aa12747
--- /dev/null
+++ b/Help/prop_sf/GENERATED.rst
@@ -0,0 +1,8 @@
+GENERATED
+---------
+
+Is this source file generated as part of the build process.
+
+If a source file is generated by the build process CMake will handle
+it differently in terms of dependency checking etc. Otherwise having
+a non-existent source file could create problems.
diff --git a/Help/prop_sf/HEADER_FILE_ONLY.rst b/Help/prop_sf/HEADER_FILE_ONLY.rst
new file mode 100644
index 000000000..b4fb2db22
--- /dev/null
+++ b/Help/prop_sf/HEADER_FILE_ONLY.rst
@@ -0,0 +1,9 @@
+HEADER_FILE_ONLY
+----------------
+
+Is this source file only a header file.
+
+A property on a source file that indicates if the source file is a
+header file with no associated implementation. This is set
+automatically based on the file extension and is used by CMake to
+determine if certain dependency information should be computed.
diff --git a/Help/prop_sf/KEEP_EXTENSION.rst b/Help/prop_sf/KEEP_EXTENSION.rst
new file mode 100644
index 000000000..d6167e5a9
--- /dev/null
+++ b/Help/prop_sf/KEEP_EXTENSION.rst
@@ -0,0 +1,9 @@
+KEEP_EXTENSION
+--------------
+
+Make the output file have the same extension as the source file.
+
+If this property is set then the file extension of the output file
+will be the same as that of the source file. Normally the output file
+extension is computed based on the language of the source file, for
+example .cxx will go to a .o extension.
diff --git a/Help/prop_sf/LABELS.rst b/Help/prop_sf/LABELS.rst
new file mode 100644
index 000000000..e1c10696a
--- /dev/null
+++ b/Help/prop_sf/LABELS.rst
@@ -0,0 +1,8 @@
+LABELS
+------
+
+Specify a list of text labels associated with a source file.
+
+This property has meaning only when the source file is listed in a
+target whose LABELS property is also set. No other semantics are
+currently specified.
diff --git a/Help/prop_sf/LANGUAGE.rst b/Help/prop_sf/LANGUAGE.rst
new file mode 100644
index 000000000..97bfa20f4
--- /dev/null
+++ b/Help/prop_sf/LANGUAGE.rst
@@ -0,0 +1,10 @@
+LANGUAGE
+--------
+
+What programming language is the file.
+
+A property that can be set to indicate what programming language the
+source file is. If it is not set the language is determined based on
+the file extension. Typical values are CXX C etc. Setting this
+property for a file means this file will be compiled. Do not set this
+for headers or files that should not be compiled.
diff --git a/Help/prop_sf/LOCATION.rst b/Help/prop_sf/LOCATION.rst
new file mode 100644
index 000000000..252d68024
--- /dev/null
+++ b/Help/prop_sf/LOCATION.rst
@@ -0,0 +1,7 @@
+LOCATION
+--------
+
+The full path to a source file.
+
+A read only property on a SOURCE FILE that contains the full path to
+the source file.
diff --git a/Help/prop_sf/MACOSX_PACKAGE_LOCATION.rst b/Help/prop_sf/MACOSX_PACKAGE_LOCATION.rst
new file mode 100644
index 000000000..69cdcb7ff
--- /dev/null
+++ b/Help/prop_sf/MACOSX_PACKAGE_LOCATION.rst
@@ -0,0 +1,23 @@
+MACOSX_PACKAGE_LOCATION
+-----------------------
+
+Place a source file inside a Application Bundle
+(:prop_tgt:`MACOSX_BUNDLE`), Core Foundation Bundle (:prop_tgt:`BUNDLE`),
+or Framework Bundle (:prop_tgt:`FRAMEWORK`). It is applicable for OS X
+and iOS.
+
+Executable targets with the :prop_tgt:`MACOSX_BUNDLE` property set are
+built as OS X or iOS application bundles on Apple platforms. Shared
+library targets with the :prop_tgt:`FRAMEWORK` property set are built as
+OS X or iOS frameworks on Apple platforms. Module library targets with
+the :prop_tgt:`BUNDLE` property set are built as OS X ``CFBundle`` bundles
+on Apple platforms. Source files listed in the target with this property
+set will be copied to a directory inside the bundle or framework content
+folder specified by the property value. For OS X Application Bundles the
+content folder is ``<name>.app/Contents``. For OS X Frameworks the
+content folder is ``<name>.framework/Versions/<version>``. For OS X
+CFBundles the content folder is ``<name>.bundle/Contents`` (unless the
+extension is changed). See the :prop_tgt:`PUBLIC_HEADER`,
+:prop_tgt:`PRIVATE_HEADER`, and :prop_tgt:`RESOURCE` target properties for
+specifying files meant for ``Headers``, ``PrivateHeaders``, or
+``Resources`` directories.
diff --git a/Help/prop_sf/OBJECT_DEPENDS.rst b/Help/prop_sf/OBJECT_DEPENDS.rst
new file mode 100644
index 000000000..1d24960b5
--- /dev/null
+++ b/Help/prop_sf/OBJECT_DEPENDS.rst
@@ -0,0 +1,21 @@
+OBJECT_DEPENDS
+--------------
+
+Additional files on which a compiled object file depends.
+
+Specifies a :ref:`;-list <CMake Language Lists>` of full-paths to
+files on which any object files compiled from this source file depend.
+On :ref:`Makefile Generators` and the :generator:`Ninja` generator an
+object file will be recompiled if any of the named files is newer than it.
+:ref:`Visual Studio Generators` and the :generator:`Xcode` generator
+cannot implement such compilation dependencies.
+
+This property need not be used to specify the dependency of a source
+file on a generated header file that it includes. Although the
+property was originally introduced for this purpose, it is no longer
+necessary. If the generated header file is created by a custom
+command in the same target as the source file, the automatic
+dependency scanning process will recognize the dependency. If the
+generated header file is created by another target, an inter-target
+dependency should be created with the :command:`add_dependencies`
+command (if one does not already exist due to linking relationships).
diff --git a/Help/prop_sf/OBJECT_OUTPUTS.rst b/Help/prop_sf/OBJECT_OUTPUTS.rst
new file mode 100644
index 000000000..6a2855374
--- /dev/null
+++ b/Help/prop_sf/OBJECT_OUTPUTS.rst
@@ -0,0 +1,9 @@
+OBJECT_OUTPUTS
+--------------
+
+Additional outputs for a Makefile rule.
+
+Additional outputs created by compilation of this source file. If any
+of these outputs is missing the object will be recompiled. This is
+supported only on Makefile generators and will be ignored on other
+generators.
diff --git a/Help/prop_sf/SYMBOLIC.rst b/Help/prop_sf/SYMBOLIC.rst
new file mode 100644
index 000000000..c7d0b2603
--- /dev/null
+++ b/Help/prop_sf/SYMBOLIC.rst
@@ -0,0 +1,8 @@
+SYMBOLIC
+--------
+
+Is this just a name for a rule.
+
+If SYMBOLIC (boolean) is set to true the build system will be informed
+that the source file is not actually created on disk but instead used
+as a symbolic name for a build rule.
diff --git a/Help/prop_sf/VS_DEPLOYMENT_CONTENT.rst b/Help/prop_sf/VS_DEPLOYMENT_CONTENT.rst
new file mode 100644
index 000000000..9fb3ba3d0
--- /dev/null
+++ b/Help/prop_sf/VS_DEPLOYMENT_CONTENT.rst
@@ -0,0 +1,11 @@
+VS_DEPLOYMENT_CONTENT
+---------------------
+
+Mark a source file as content for deployment with a Windows Phone or
+Windows Store application when built with a Visual Studio generator.
+The value must evaluate to either ``1`` or ``0`` and may use
+:manual:`generator expressions <cmake-generator-expressions(7)>`
+to make the choice based on the build configuration.
+The ``.vcxproj`` file entry for the source file will be
+marked either ``DeploymentContent`` or ``ExcludedFromBuild``
+for values ``1`` and ``0``, respectively.
diff --git a/Help/prop_sf/VS_DEPLOYMENT_LOCATION.rst b/Help/prop_sf/VS_DEPLOYMENT_LOCATION.rst
new file mode 100644
index 000000000..303db952b
--- /dev/null
+++ b/Help/prop_sf/VS_DEPLOYMENT_LOCATION.rst
@@ -0,0 +1,8 @@
+VS_DEPLOYMENT_LOCATION
+----------------------
+
+Specifies the deployment location for a content source file with a Windows
+Phone or Windows Store application when built with a Visual Studio generator.
+This property is only applicable when using :prop_sf:`VS_DEPLOYMENT_CONTENT`.
+The value represent the path relative to the app package and applies to all
+configurations.
diff --git a/Help/prop_sf/VS_SHADER_ENTRYPOINT.rst b/Help/prop_sf/VS_SHADER_ENTRYPOINT.rst
new file mode 100644
index 000000000..fe3471f25
--- /dev/null
+++ b/Help/prop_sf/VS_SHADER_ENTRYPOINT.rst
@@ -0,0 +1,5 @@
+VS_SHADER_ENTRYPOINT
+--------------------
+
+Specifies the name of the entry point for the shader of a ``.hlsl`` source
+file.
diff --git a/Help/prop_sf/VS_SHADER_FLAGS.rst b/Help/prop_sf/VS_SHADER_FLAGS.rst
new file mode 100644
index 000000000..09011231b
--- /dev/null
+++ b/Help/prop_sf/VS_SHADER_FLAGS.rst
@@ -0,0 +1,4 @@
+VS_SHADER_FLAGS
+---------------
+
+Set additional VS shader flags of a ``.hlsl`` source file.
diff --git a/Help/prop_sf/VS_SHADER_MODEL.rst b/Help/prop_sf/VS_SHADER_MODEL.rst
new file mode 100644
index 000000000..b1cf0df55
--- /dev/null
+++ b/Help/prop_sf/VS_SHADER_MODEL.rst
@@ -0,0 +1,5 @@
+VS_SHADER_MODEL
+---------------
+
+Specifies the shader model of a ``.hlsl`` source file. Some shader types can
+only be used with recent shader models
diff --git a/Help/prop_sf/VS_SHADER_TYPE.rst b/Help/prop_sf/VS_SHADER_TYPE.rst
new file mode 100644
index 000000000..688025608
--- /dev/null
+++ b/Help/prop_sf/VS_SHADER_TYPE.rst
@@ -0,0 +1,4 @@
+VS_SHADER_TYPE
+--------------
+
+Set the VS shader type of a ``.hlsl`` source file.
diff --git a/Help/prop_sf/VS_XAML_TYPE.rst b/Help/prop_sf/VS_XAML_TYPE.rst
new file mode 100644
index 000000000..e92191dcb
--- /dev/null
+++ b/Help/prop_sf/VS_XAML_TYPE.rst
@@ -0,0 +1,6 @@
+VS_XAML_TYPE
+------------
+
+Mark a XAML source file as a different type than the default ``Page``.
+The most common usage would be to set the default App.xaml file as
+ApplicationDefinition.
diff --git a/Help/prop_sf/WRAP_EXCLUDE.rst b/Help/prop_sf/WRAP_EXCLUDE.rst
new file mode 100644
index 000000000..2c79f72a2
--- /dev/null
+++ b/Help/prop_sf/WRAP_EXCLUDE.rst
@@ -0,0 +1,10 @@
+WRAP_EXCLUDE
+------------
+
+Exclude this source file from any code wrapping techniques.
+
+Some packages can wrap source files into alternate languages to
+provide additional functionality. For example, C++ code can be
+wrapped into Java or Python etc using SWIG etc. If WRAP_EXCLUDE is
+set to true (1 etc) that indicates that this source file should not be
+wrapped.
diff --git a/Help/prop_sf/XCODE_EXPLICIT_FILE_TYPE.rst b/Help/prop_sf/XCODE_EXPLICIT_FILE_TYPE.rst
new file mode 100644
index 000000000..1b24701a3
--- /dev/null
+++ b/Help/prop_sf/XCODE_EXPLICIT_FILE_TYPE.rst
@@ -0,0 +1,8 @@
+XCODE_EXPLICIT_FILE_TYPE
+------------------------
+
+Set the Xcode ``explicitFileType`` attribute on its reference to a
+source file. CMake computes a default based on file extension but
+can be told explicitly with this property.
+
+See also :prop_sf:`XCODE_LAST_KNOWN_FILE_TYPE`.
diff --git a/Help/prop_sf/XCODE_LAST_KNOWN_FILE_TYPE.rst b/Help/prop_sf/XCODE_LAST_KNOWN_FILE_TYPE.rst
new file mode 100644
index 000000000..42e37574d
--- /dev/null
+++ b/Help/prop_sf/XCODE_LAST_KNOWN_FILE_TYPE.rst
@@ -0,0 +1,9 @@
+XCODE_LAST_KNOWN_FILE_TYPE
+--------------------------
+
+Set the Xcode ``lastKnownFileType`` attribute on its reference to a
+source file. CMake computes a default based on file extension but
+can be told explicitly with this property.
+
+See also :prop_sf:`XCODE_EXPLICIT_FILE_TYPE`, which is preferred
+over this property if set.
diff --git a/Help/prop_test/ATTACHED_FILES.rst b/Help/prop_test/ATTACHED_FILES.rst
new file mode 100644
index 000000000..496d80071
--- /dev/null
+++ b/Help/prop_test/ATTACHED_FILES.rst
@@ -0,0 +1,7 @@
+ATTACHED_FILES
+--------------
+
+Attach a list of files to a dashboard submission.
+
+Set this property to a list of files that will be encoded and
+submitted to the dashboard as an addition to the test result.
diff --git a/Help/prop_test/ATTACHED_FILES_ON_FAIL.rst b/Help/prop_test/ATTACHED_FILES_ON_FAIL.rst
new file mode 100644
index 000000000..681914334
--- /dev/null
+++ b/Help/prop_test/ATTACHED_FILES_ON_FAIL.rst
@@ -0,0 +1,7 @@
+ATTACHED_FILES_ON_FAIL
+----------------------
+
+Attach a list of files to a dashboard submission if the test fails.
+
+Same as ATTACHED_FILES, but these files will only be included if the
+test does not pass.
diff --git a/Help/prop_test/COST.rst b/Help/prop_test/COST.rst
new file mode 100644
index 000000000..3236a0295
--- /dev/null
+++ b/Help/prop_test/COST.rst
@@ -0,0 +1,7 @@
+COST
+----
+
+Set this to a floating point value. Tests in a test set will be run in descending order of cost.
+
+This property describes the cost of a test. You can explicitly set
+this value; tests with higher COST values will run first.
diff --git a/Help/prop_test/DEPENDS.rst b/Help/prop_test/DEPENDS.rst
new file mode 100644
index 000000000..ee946d938
--- /dev/null
+++ b/Help/prop_test/DEPENDS.rst
@@ -0,0 +1,6 @@
+DEPENDS
+-------
+
+Specifies that this test should only be run after the specified list of tests.
+
+Set this to a list of tests that must finish before this test is run.
diff --git a/Help/prop_test/ENVIRONMENT.rst b/Help/prop_test/ENVIRONMENT.rst
new file mode 100644
index 000000000..df9bc9e14
--- /dev/null
+++ b/Help/prop_test/ENVIRONMENT.rst
@@ -0,0 +1,9 @@
+ENVIRONMENT
+-----------
+
+Specify environment variables that should be defined for running a test.
+
+If set to a list of environment variables and values of the form
+MYVAR=value those environment variables will be defined while running
+the test. The environment is restored to its previous state after the
+test is done.
diff --git a/Help/prop_test/FAIL_REGULAR_EXPRESSION.rst b/Help/prop_test/FAIL_REGULAR_EXPRESSION.rst
new file mode 100644
index 000000000..facf90255
--- /dev/null
+++ b/Help/prop_test/FAIL_REGULAR_EXPRESSION.rst
@@ -0,0 +1,15 @@
+FAIL_REGULAR_EXPRESSION
+-----------------------
+
+If the output matches this regular expression the test will fail.
+
+If set, if the output matches one of specified regular expressions,
+the test will fail. Example:
+
+.. code-block:: cmake
+
+ set_tests_properties(mytest PROPERTIES
+ FAIL_REGULAR_EXPRESSION "[^a-z]Error;ERROR;Failed"
+ )
+
+``FAIL_REGULAR_EXPRESSION`` expects a list of regular expressions.
diff --git a/Help/prop_test/LABELS.rst b/Help/prop_test/LABELS.rst
new file mode 100644
index 000000000..8d7557095
--- /dev/null
+++ b/Help/prop_test/LABELS.rst
@@ -0,0 +1,6 @@
+LABELS
+------
+
+Specify a list of text labels associated with a test.
+
+The list is reported in dashboard submissions.
diff --git a/Help/prop_test/MEASUREMENT.rst b/Help/prop_test/MEASUREMENT.rst
new file mode 100644
index 000000000..bc4936e97
--- /dev/null
+++ b/Help/prop_test/MEASUREMENT.rst
@@ -0,0 +1,8 @@
+MEASUREMENT
+-----------
+
+Specify a CDASH measurement and value to be reported for a test.
+
+If set to a name then that name will be reported to CDASH as a named
+measurement with a value of 1. You may also specify a value by
+setting MEASUREMENT to "measurement=value".
diff --git a/Help/prop_test/PASS_REGULAR_EXPRESSION.rst b/Help/prop_test/PASS_REGULAR_EXPRESSION.rst
new file mode 100644
index 000000000..0cd621526
--- /dev/null
+++ b/Help/prop_test/PASS_REGULAR_EXPRESSION.rst
@@ -0,0 +1,16 @@
+PASS_REGULAR_EXPRESSION
+-----------------------
+
+The output must match this regular expression for the test to pass.
+
+If set, the test output will be checked against the specified regular
+expressions and at least one of the regular expressions has to match,
+otherwise the test will fail. Example:
+
+.. code-block:: cmake
+
+ set_tests_properties(mytest PROPERTIES
+ PASS_REGULAR_EXPRESSION "TestPassed;All ok"
+ )
+
+``PASS_REGULAR_EXPRESSION`` expects a list of regular expressions.
diff --git a/Help/prop_test/PROCESSORS.rst b/Help/prop_test/PROCESSORS.rst
new file mode 100644
index 000000000..763b6d003
--- /dev/null
+++ b/Help/prop_test/PROCESSORS.rst
@@ -0,0 +1,8 @@
+PROCESSORS
+----------
+
+How many process slots this test requires
+
+Denotes the number of processors that this test will require. This is
+typically used for MPI tests, and should be used in conjunction with
+the ctest_test PARALLEL_LEVEL option.
diff --git a/Help/prop_test/REQUIRED_FILES.rst b/Help/prop_test/REQUIRED_FILES.rst
new file mode 100644
index 000000000..fac357c1e
--- /dev/null
+++ b/Help/prop_test/REQUIRED_FILES.rst
@@ -0,0 +1,7 @@
+REQUIRED_FILES
+--------------
+
+List of files required to run the test.
+
+If set to a list of files, the test will not be run unless all of the
+files exist.
diff --git a/Help/prop_test/RESOURCE_LOCK.rst b/Help/prop_test/RESOURCE_LOCK.rst
new file mode 100644
index 000000000..8c30f0177
--- /dev/null
+++ b/Help/prop_test/RESOURCE_LOCK.rst
@@ -0,0 +1,7 @@
+RESOURCE_LOCK
+-------------
+
+Specify a list of resources that are locked by this test.
+
+If multiple tests specify the same resource lock, they are guaranteed
+not to run concurrently.
diff --git a/Help/prop_test/RUN_SERIAL.rst b/Help/prop_test/RUN_SERIAL.rst
new file mode 100644
index 000000000..8f65ae18a
--- /dev/null
+++ b/Help/prop_test/RUN_SERIAL.rst
@@ -0,0 +1,8 @@
+RUN_SERIAL
+----------
+
+Do not run this test in parallel with any other test.
+
+Use this option in conjunction with the ctest_test PARALLEL_LEVEL
+option to specify that this test should not be run in parallel with
+any other tests.
diff --git a/Help/prop_test/SKIP_RETURN_CODE.rst b/Help/prop_test/SKIP_RETURN_CODE.rst
new file mode 100644
index 000000000..c61273c56
--- /dev/null
+++ b/Help/prop_test/SKIP_RETURN_CODE.rst
@@ -0,0 +1,9 @@
+SKIP_RETURN_CODE
+----------------
+
+Return code to mark a test as skipped.
+
+Sometimes only a test itself can determine if all requirements for the
+test are met. If such a situation should not be considered a hard failure
+a return code of the process can be specified that will mark the test as
+"Not Run" if it is encountered.
diff --git a/Help/prop_test/TIMEOUT.rst b/Help/prop_test/TIMEOUT.rst
new file mode 100644
index 000000000..d1cb90d0a
--- /dev/null
+++ b/Help/prop_test/TIMEOUT.rst
@@ -0,0 +1,9 @@
+TIMEOUT
+-------
+
+How many seconds to allow for this test.
+
+This property if set will limit a test to not take more than the
+specified number of seconds to run. If it exceeds that the test
+process will be killed and ctest will move to the next test. This
+setting takes precedence over :variable:`CTEST_TEST_TIMEOUT`.
diff --git a/Help/prop_test/WILL_FAIL.rst b/Help/prop_test/WILL_FAIL.rst
new file mode 100644
index 000000000..f1f94a43a
--- /dev/null
+++ b/Help/prop_test/WILL_FAIL.rst
@@ -0,0 +1,7 @@
+WILL_FAIL
+---------
+
+If set to true, this will invert the pass/fail flag of the test.
+
+This property can be used for tests that are expected to fail and
+return a non zero return code.
diff --git a/Help/prop_test/WORKING_DIRECTORY.rst b/Help/prop_test/WORKING_DIRECTORY.rst
new file mode 100644
index 000000000..5222a197b
--- /dev/null
+++ b/Help/prop_test/WORKING_DIRECTORY.rst
@@ -0,0 +1,7 @@
+WORKING_DIRECTORY
+-----------------
+
+The directory from which the test executable will be called.
+
+If this is not set it is called from the directory the test executable
+is located in.
diff --git a/Help/prop_tgt/ALIASED_TARGET.rst b/Help/prop_tgt/ALIASED_TARGET.rst
new file mode 100644
index 000000000..f9e60348d
--- /dev/null
+++ b/Help/prop_tgt/ALIASED_TARGET.rst
@@ -0,0 +1,7 @@
+ALIASED_TARGET
+--------------
+
+Name of target aliased by this target.
+
+If this is an :ref:`Alias Target <Alias Targets>`, this property contains
+the name of the target aliased.
diff --git a/Help/prop_tgt/ANDROID_ANT_ADDITIONAL_OPTIONS.rst b/Help/prop_tgt/ANDROID_ANT_ADDITIONAL_OPTIONS.rst
new file mode 100644
index 000000000..af6b40587
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_ANT_ADDITIONAL_OPTIONS.rst
@@ -0,0 +1,8 @@
+ANDROID_ANT_ADDITIONAL_OPTIONS
+------------------------------
+
+Set the additional options for Android Ant build system. This is
+a string value containing all command line options for the Ant build.
+This property is initialized by the value of the
+:variable:`CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS` variable if it is
+set when a target is created.
diff --git a/Help/prop_tgt/ANDROID_API.rst b/Help/prop_tgt/ANDROID_API.rst
new file mode 100644
index 000000000..714ad584a
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_API.rst
@@ -0,0 +1,7 @@
+ANDROID_API
+-----------
+
+Set the Android Target API version (e.g. ``15``). The version number
+must be a positive decimal integer. This property is initialized by
+the value of the :variable:`CMAKE_ANDROID_API` variable if it is set
+when a target is created.
diff --git a/Help/prop_tgt/ANDROID_API_MIN.rst b/Help/prop_tgt/ANDROID_API_MIN.rst
new file mode 100644
index 000000000..773ab3feb
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_API_MIN.rst
@@ -0,0 +1,7 @@
+ANDROID_API_MIN
+---------------
+
+Set the Android MIN API version (e.g. ``9``). The version number
+must be a positive decimal integer. This property is initialized by
+the value of the :variable:`CMAKE_ANDROID_API_MIN` variable if it is set
+when a target is created. Native code builds using this API version.
diff --git a/Help/prop_tgt/ANDROID_ARCH.rst b/Help/prop_tgt/ANDROID_ARCH.rst
new file mode 100644
index 000000000..5477fb598
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_ARCH.rst
@@ -0,0 +1,17 @@
+ANDROID_ARCH
+------------
+
+Set the Android target architecture.
+
+This is a string property that could be set to the one of
+the following values:
+
+* ``armv7-a``: "ARMv7-A (armv7-a)"
+* ``armv7-a-hard``: "ARMv7-A, hard-float ABI (armv7-a)"
+* ``arm64-v8a``: "ARMv8-A, 64bit (arm64-v8a)"
+* ``x86``: "x86 (x86)"
+* ``x86_64``: "x86_64 (x86_64)"
+
+This property is initialized by the value of the
+:variable:`CMAKE_ANDROID_ARCH` variable if it is set
+when a target is created.
diff --git a/Help/prop_tgt/ANDROID_ASSETS_DIRECTORIES.rst b/Help/prop_tgt/ANDROID_ASSETS_DIRECTORIES.rst
new file mode 100644
index 000000000..764a58244
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_ASSETS_DIRECTORIES.rst
@@ -0,0 +1,9 @@
+ANDROID_ASSETS_DIRECTORIES
+--------------------------
+
+Set the Android assets directories to copy into the main assets
+folder before build. This a string property that contains the
+directory paths separated by semicolon.
+This property is initialized by the value of the
+:variable:`CMAKE_ANDROID_ASSETS_DIRECTORIES` variable if it is set when
+a target is created.
diff --git a/Help/prop_tgt/ANDROID_GUI.rst b/Help/prop_tgt/ANDROID_GUI.rst
new file mode 100644
index 000000000..abdba7a3d
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_GUI.rst
@@ -0,0 +1,13 @@
+ANDROID_GUI
+-----------
+
+Build an executable as an application package on Android.
+
+When this property is set to true the executable when built for Android
+will be created as an application package. This property is initialized
+by the value of the :variable:`CMAKE_ANDROID_GUI` variable if it is set
+when a target is created.
+
+Add the ``AndroidManifest.xml`` source file explicitly to the
+target :command:`add_executable` command invocation to specify the
+root directory of the application package source.
diff --git a/Help/prop_tgt/ANDROID_JAR_DEPENDENCIES.rst b/Help/prop_tgt/ANDROID_JAR_DEPENDENCIES.rst
new file mode 100644
index 000000000..42937c1b4
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_JAR_DEPENDENCIES.rst
@@ -0,0 +1,7 @@
+ANDROID_JAR_DEPENDENCIES
+------------------------
+
+Set the Android property that specifies JAR dependencies.
+This is a string value property. This property is initialized
+by the value of the :variable:`CMAKE_ANDROID_JAR_DEPENDENCIES`
+variable if it is set when a target is created.
diff --git a/Help/prop_tgt/ANDROID_JAR_DIRECTORIES.rst b/Help/prop_tgt/ANDROID_JAR_DIRECTORIES.rst
new file mode 100644
index 000000000..54f0a8ff7
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_JAR_DIRECTORIES.rst
@@ -0,0 +1,14 @@
+ANDROID_JAR_DIRECTORIES
+-----------------------
+
+Set the Android property that specifies directories to search for
+the JAR libraries.
+
+This a string property that contains the directory paths separated by
+semicolons. This property is initialized by the value of the
+:variable:`CMAKE_ANDROID_JAR_DIRECTORIES` variable if it is set when
+a target is created.
+
+Contents of ``ANDROID_JAR_DIRECTORIES`` may use "generator expressions"
+with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions.
diff --git a/Help/prop_tgt/ANDROID_JAVA_SOURCE_DIR.rst b/Help/prop_tgt/ANDROID_JAVA_SOURCE_DIR.rst
new file mode 100644
index 000000000..90ef1ce93
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_JAVA_SOURCE_DIR.rst
@@ -0,0 +1,8 @@
+ANDROID_JAVA_SOURCE_DIR
+-----------------------
+
+Set the Android property that defines the Java source code root directories.
+This a string property that contains the directory paths separated by semicolon.
+This property is initialized by the value of the
+:variable:`CMAKE_ANDROID_JAVA_SOURCE_DIR` variable if it is set
+when a target is created.
diff --git a/Help/prop_tgt/ANDROID_NATIVE_LIB_DEPENDENCIES.rst b/Help/prop_tgt/ANDROID_NATIVE_LIB_DEPENDENCIES.rst
new file mode 100644
index 000000000..759a37b06
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_NATIVE_LIB_DEPENDENCIES.rst
@@ -0,0 +1,14 @@
+ANDROID_NATIVE_LIB_DEPENDENCIES
+-------------------------------
+
+Set the Android property that specifies the .so dependencies.
+This is a string property.
+
+This property is initialized by the value of the
+:variable:`CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES` variable if it is set
+when a target is created.
+
+Contents of ``ANDROID_NATIVE_LIB_DEPENDENCIES`` may use
+"generator expressions" with the syntax ``$<...>``. See the
+:manual:`cmake-generator-expressions(7)` manual for
+available expressions.
diff --git a/Help/prop_tgt/ANDROID_NATIVE_LIB_DIRECTORIES.rst b/Help/prop_tgt/ANDROID_NATIVE_LIB_DIRECTORIES.rst
new file mode 100644
index 000000000..bc673804d
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_NATIVE_LIB_DIRECTORIES.rst
@@ -0,0 +1,16 @@
+ANDROID_NATIVE_LIB_DIRECTORIES
+------------------------------
+
+Set the Android property that specifies directories to search for the
+.so libraries.
+
+This a string property that contains the directory paths separated
+by semicolons.
+
+This property is initialized by the value of the
+:variable:`CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES` variable if it is set when a
+target is created.
+
+Contents of ``ANDROID_NATIVE_LIB_DIRECTORIES`` may use "generator expressions"
+with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions.
diff --git a/Help/prop_tgt/ANDROID_PROCESS_MAX.rst b/Help/prop_tgt/ANDROID_PROCESS_MAX.rst
new file mode 100644
index 000000000..847acae5b
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_PROCESS_MAX.rst
@@ -0,0 +1,8 @@
+ANDROID_PROCESS_MAX
+-------------------
+
+Set the Android property that defines the maximum number of a
+parallel Android NDK compiler processes (e.g. ``4``).
+This property is initialized by the value of the
+:variable:`CMAKE_ANDROID_PROCESS_MAX` variable if it is set
+when a target is created.
diff --git a/Help/prop_tgt/ANDROID_PROGUARD.rst b/Help/prop_tgt/ANDROID_PROGUARD.rst
new file mode 100644
index 000000000..dafc51ee5
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_PROGUARD.rst
@@ -0,0 +1,9 @@
+ANDROID_PROGUARD
+----------------
+
+When this property is set to true that enables the ProGuard tool to shrink,
+optimize, and obfuscate the code by removing unused code and renaming
+classes, fields, and methods with semantically obscure names.
+This property is initialized by the value of the
+:variable:`CMAKE_ANDROID_PROGUARD` variable if it is set
+when a target is created.
diff --git a/Help/prop_tgt/ANDROID_PROGUARD_CONFIG_PATH.rst b/Help/prop_tgt/ANDROID_PROGUARD_CONFIG_PATH.rst
new file mode 100644
index 000000000..0e929d16a
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_PROGUARD_CONFIG_PATH.rst
@@ -0,0 +1,9 @@
+ANDROID_PROGUARD_CONFIG_PATH
+----------------------------
+
+Set the Android property that specifies the location of the ProGuard
+config file. Leave empty to use the default one.
+This a string property that contains the path to ProGuard config file.
+This property is initialized by the value of the
+:variable:`CMAKE_ANDROID_PROGUARD_CONFIG_PATH` variable if it is set
+when a target is created.
diff --git a/Help/prop_tgt/ANDROID_SECURE_PROPS_PATH.rst b/Help/prop_tgt/ANDROID_SECURE_PROPS_PATH.rst
new file mode 100644
index 000000000..9533f1a70
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_SECURE_PROPS_PATH.rst
@@ -0,0 +1,8 @@
+ANDROID_SECURE_PROPS_PATH
+-------------------------
+
+Set the Android property that states the location of the secure properties file.
+This is a string property that contains the file path.
+This property is initialized by the value of the
+:variable:`CMAKE_ANDROID_SECURE_PROPS_PATH` variable
+if it is set when a target is created.
diff --git a/Help/prop_tgt/ANDROID_SKIP_ANT_STEP.rst b/Help/prop_tgt/ANDROID_SKIP_ANT_STEP.rst
new file mode 100644
index 000000000..636189656
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_SKIP_ANT_STEP.rst
@@ -0,0 +1,6 @@
+ANDROID_SKIP_ANT_STEP
+---------------------
+
+Set the Android property that defines whether or not to skip the Ant build step.
+This is a boolean property initialized by the value of the
+:variable:`CMAKE_ANDROID_SKIP_ANT_STEP` variable if it is set when a target is created.
diff --git a/Help/prop_tgt/ANDROID_STL_TYPE.rst b/Help/prop_tgt/ANDROID_STL_TYPE.rst
new file mode 100644
index 000000000..7256e266c
--- /dev/null
+++ b/Help/prop_tgt/ANDROID_STL_TYPE.rst
@@ -0,0 +1,15 @@
+ANDROID_STL_TYPE
+----------------
+
+Set the Android property that defines the type of STL support for the project.
+This is a string property that could set to the one of the following values:
+``none`` e.g. "No C++ Support"
+``system`` e.g. "Minimal C++ without STL"
+``gabi++_static`` e.g. "GAbi++ Static"
+``gabi++_shared`` e.g. "GAbi++ Shared"
+``gnustl_static`` e.g. "GNU libstdc++ Static"
+``gnustl_shared`` e.g. "GNU libstdc++ Shared"
+``stlport_static`` e.g. "STLport Static"
+``stlport_shared`` e.g. "STLport Shared"
+This property is initialized by the value of the
+variable:`CMAKE_ANDROID_STL_TYPE` variable if it is set when a target is created.
diff --git a/Help/prop_tgt/ARCHIVE_OUTPUT_DIRECTORY.rst b/Help/prop_tgt/ARCHIVE_OUTPUT_DIRECTORY.rst
new file mode 100644
index 000000000..42210696b
--- /dev/null
+++ b/Help/prop_tgt/ARCHIVE_OUTPUT_DIRECTORY.rst
@@ -0,0 +1,9 @@
+ARCHIVE_OUTPUT_DIRECTORY
+------------------------
+
+.. |XXX| replace:: :ref:`ARCHIVE <Archive Output Artifacts>`
+.. |xxx| replace:: archive
+.. |CMAKE_XXX_OUTPUT_DIRECTORY| replace:: CMAKE_ARCHIVE_OUTPUT_DIRECTORY
+.. include:: XXX_OUTPUT_DIRECTORY.txt
+
+See also the :prop_tgt:`ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>` target property.
diff --git a/Help/prop_tgt/ARCHIVE_OUTPUT_DIRECTORY_CONFIG.rst b/Help/prop_tgt/ARCHIVE_OUTPUT_DIRECTORY_CONFIG.rst
new file mode 100644
index 000000000..12f8bb7ef
--- /dev/null
+++ b/Help/prop_tgt/ARCHIVE_OUTPUT_DIRECTORY_CONFIG.rst
@@ -0,0 +1,16 @@
+ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>
+---------------------------------
+
+Per-configuration output directory for
+:ref:`ARCHIVE <Archive Output Artifacts>` target files.
+
+This is a per-configuration version of the
+:prop_tgt:`ARCHIVE_OUTPUT_DIRECTORY` target property, but
+multi-configuration generators (VS, Xcode) do NOT append a
+per-configuration subdirectory to the specified directory. This
+property is initialized by the value of the
+:variable:`CMAKE_ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>` variable if
+it is set when a target is created.
+
+Contents of ``ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>`` may use
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Help/prop_tgt/ARCHIVE_OUTPUT_NAME.rst b/Help/prop_tgt/ARCHIVE_OUTPUT_NAME.rst
new file mode 100644
index 000000000..615019373
--- /dev/null
+++ b/Help/prop_tgt/ARCHIVE_OUTPUT_NAME.rst
@@ -0,0 +1,8 @@
+ARCHIVE_OUTPUT_NAME
+-------------------
+
+.. |XXX| replace:: :ref:`ARCHIVE <Archive Output Artifacts>`
+.. |xxx| replace:: archive
+.. include:: XXX_OUTPUT_NAME.txt
+
+See also the :prop_tgt:`ARCHIVE_OUTPUT_NAME_<CONFIG>` target property.
diff --git a/Help/prop_tgt/ARCHIVE_OUTPUT_NAME_CONFIG.rst b/Help/prop_tgt/ARCHIVE_OUTPUT_NAME_CONFIG.rst
new file mode 100644
index 000000000..4f62eb995
--- /dev/null
+++ b/Help/prop_tgt/ARCHIVE_OUTPUT_NAME_CONFIG.rst
@@ -0,0 +1,8 @@
+ARCHIVE_OUTPUT_NAME_<CONFIG>
+----------------------------
+
+Per-configuration output name for
+:ref:`ARCHIVE <Archive Output Artifacts>` target files.
+
+This is the configuration-specific version of the
+:prop_tgt:`ARCHIVE_OUTPUT_NAME` target property.
diff --git a/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst b/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst
new file mode 100644
index 000000000..5063244b5
--- /dev/null
+++ b/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst
@@ -0,0 +1,17 @@
+AUTOGEN_TARGET_DEPENDS
+----------------------
+
+Target dependencies of the corresponding ``_automoc`` target.
+
+Targets which have their :prop_tgt:`AUTOMOC` target ``ON`` have a
+corresponding ``_automoc`` target which is used to autogenerate generate moc
+files. As this ``_automoc`` target is created at generate-time, it is not
+possible to define dependencies of it, such as to create inputs for the ``moc``
+executable.
+
+The ``AUTOGEN_TARGET_DEPENDS`` target property can be set instead to a list of
+dependencies for the ``_automoc`` target. The buildsystem will be generated to
+depend on its contents.
+
+See the :manual:`cmake-qt(7)` manual for more information on using CMake
+with Qt.
diff --git a/Help/prop_tgt/AUTOMOC.rst b/Help/prop_tgt/AUTOMOC.rst
new file mode 100644
index 000000000..045ebb275
--- /dev/null
+++ b/Help/prop_tgt/AUTOMOC.rst
@@ -0,0 +1,37 @@
+AUTOMOC
+-------
+
+Should the target be processed with automoc (for Qt projects).
+
+AUTOMOC is a boolean specifying whether CMake will handle the Qt ``moc``
+preprocessor automatically, i.e. without having to use the
+:module:`QT4_WRAP_CPP() <FindQt4>` or QT5_WRAP_CPP() macro. Currently Qt4 and Qt5 are
+supported. When this property is set ``ON``, CMake will scan the
+source files at build time and invoke moc accordingly. If an ``#include``
+statement like ``#include "moc_foo.cpp"`` is found, the ``Q_OBJECT`` class
+declaration is expected in the header, and ``moc`` is run on the header
+file. If an ``#include`` statement like ``#include "foo.moc"`` is found, then
+a ``Q_OBJECT`` is expected in the current source file and ``moc`` is run on
+the file itself. Additionally, header files with the same base name (like
+``foo.h``) or ``_p`` appended to the base name (like ``foo_p.h``) are parsed
+for ``Q_OBJECT`` macros, and if found, ``moc`` is also executed on those files.
+``AUTOMOC`` checks multiple header alternative extensions, such as
+``hpp``, ``hxx`` etc when searching for headers.
+The resulting moc files, which are not included as shown above in any
+of the source files are included in a generated
+``<targetname>_automoc.cpp`` file, which is compiled as part of the
+target. This property is initialized by the value of the
+:variable:`CMAKE_AUTOMOC` variable if it is set when a target is created.
+
+Additional command line options for moc can be set via the
+:prop_tgt:`AUTOMOC_MOC_OPTIONS` property.
+
+By enabling the :variable:`CMAKE_AUTOMOC_RELAXED_MODE` variable the
+rules for searching the files which will be processed by moc can be relaxed.
+See the documentation for this variable for more details.
+
+The global property :prop_gbl:`AUTOGEN_TARGETS_FOLDER` can be used to group the
+automoc targets together in an IDE, e.g. in MSVS.
+
+See the :manual:`cmake-qt(7)` manual for more information on using CMake
+with Qt.
diff --git a/Help/prop_tgt/AUTOMOC_MOC_OPTIONS.rst b/Help/prop_tgt/AUTOMOC_MOC_OPTIONS.rst
new file mode 100644
index 000000000..ebd5c4951
--- /dev/null
+++ b/Help/prop_tgt/AUTOMOC_MOC_OPTIONS.rst
@@ -0,0 +1,15 @@
+AUTOMOC_MOC_OPTIONS
+-------------------
+
+Additional options for moc when using :prop_tgt:`AUTOMOC`
+
+This property is only used if the :prop_tgt:`AUTOMOC` property is ``ON``
+for this target. In this case, it holds additional command line
+options which will be used when ``moc`` is executed during the build, i.e.
+it is equivalent to the optional ``OPTIONS`` argument of the
+:module:`qt4_wrap_cpp() <FindQt4>` macro.
+
+By default it is empty.
+
+See the :manual:`cmake-qt(7)` manual for more information on using CMake
+with Qt.
diff --git a/Help/prop_tgt/AUTORCC.rst b/Help/prop_tgt/AUTORCC.rst
new file mode 100644
index 000000000..8dce6b184
--- /dev/null
+++ b/Help/prop_tgt/AUTORCC.rst
@@ -0,0 +1,23 @@
+AUTORCC
+-------
+
+Should the target be processed with autorcc (for Qt projects).
+
+``AUTORCC`` is a boolean specifying whether CMake will handle
+the Qt ``rcc`` code generator automatically, i.e. without having to use
+the :module:`QT4_ADD_RESOURCES() <FindQt4>` or ``QT5_ADD_RESOURCES()``
+macro. Currently Qt4 and Qt5 are supported.
+
+When this property is ``ON``, CMake will handle ``.qrc`` files added
+as target sources at build time and invoke ``rcc`` accordingly.
+This property is initialized by the value of the :variable:`CMAKE_AUTORCC`
+variable if it is set when a target is created.
+
+Additional command line options for rcc can be set via the
+:prop_sf:`AUTORCC_OPTIONS` source file property on the ``.qrc`` file.
+
+The global property :prop_gbl:`AUTOGEN_TARGETS_FOLDER` can be used to group
+the autorcc targets together in an IDE, e.g. in MSVS.
+
+See the :manual:`cmake-qt(7)` manual for more information on using CMake
+with Qt.
diff --git a/Help/prop_tgt/AUTORCC_OPTIONS.rst b/Help/prop_tgt/AUTORCC_OPTIONS.rst
new file mode 100644
index 000000000..8a0f632c2
--- /dev/null
+++ b/Help/prop_tgt/AUTORCC_OPTIONS.rst
@@ -0,0 +1,21 @@
+AUTORCC_OPTIONS
+---------------
+
+Additional options for ``rcc`` when using :prop_tgt:`AUTORCC`
+
+This property holds additional command line options which will be used
+when ``rcc`` is executed during the build via :prop_tgt:`AUTORCC`,
+i.e. it is equivalent to the optional ``OPTIONS`` argument of the
+:module:`qt4_add_resources() <FindQt4>` macro.
+
+By default it is empty.
+
+This property is initialized by the value of the
+:variable:`CMAKE_AUTORCC_OPTIONS` variable if it is set when a target is
+created.
+
+The options set on the target may be overridden by :prop_sf:`AUTORCC_OPTIONS`
+set on the ``.qrc`` source file.
+
+See the :manual:`cmake-qt(7)` manual for more information on using CMake
+with Qt.
diff --git a/Help/prop_tgt/AUTOUIC.rst b/Help/prop_tgt/AUTOUIC.rst
new file mode 100644
index 000000000..4e60ec33a
--- /dev/null
+++ b/Help/prop_tgt/AUTOUIC.rst
@@ -0,0 +1,24 @@
+AUTOUIC
+-------
+
+Should the target be processed with autouic (for Qt projects).
+
+``AUTOUIC`` is a boolean specifying whether CMake will handle
+the Qt ``uic`` code generator automatically, i.e. without having to use
+the :module:`QT4_WRAP_UI() <FindQt4>` or ``QT5_WRAP_UI()`` macro. Currently
+Qt4 and Qt5 are supported.
+
+When this property is ``ON``, CMake will scan the source files at build time
+and invoke ``uic`` accordingly. If an ``#include`` statement like
+``#include "ui_foo.h"`` is found in ``foo.cpp``, a ``foo.ui`` file is
+expected next to ``foo.cpp``, and ``uic`` is run on the ``foo.ui`` file.
+This property is initialized by the value of the :variable:`CMAKE_AUTOUIC`
+variable if it is set when a target is created.
+
+Additional command line options for ``uic`` can be set via the
+:prop_sf:`AUTOUIC_OPTIONS` source file property on the ``foo.ui`` file.
+The global property :prop_gbl:`AUTOGEN_TARGETS_FOLDER` can be used to group the
+autouic targets together in an IDE, e.g. in MSVS.
+
+See the :manual:`cmake-qt(7)` manual for more information on using CMake
+with Qt.
diff --git a/Help/prop_tgt/AUTOUIC_OPTIONS.rst b/Help/prop_tgt/AUTOUIC_OPTIONS.rst
new file mode 100644
index 000000000..dc3bee55f
--- /dev/null
+++ b/Help/prop_tgt/AUTOUIC_OPTIONS.rst
@@ -0,0 +1,25 @@
+AUTOUIC_OPTIONS
+---------------
+
+Additional options for uic when using :prop_tgt:`AUTOUIC`
+
+This property holds additional command line options which will be used when
+``uic`` is executed during the build via :prop_tgt:`AUTOUIC`, i.e. it is
+equivalent to the optional ``OPTIONS`` argument of the
+:module:`qt4_wrap_ui() <FindQt4>` macro.
+
+By default it is empty.
+
+This property is initialized by the value of the
+:variable:`CMAKE_AUTOUIC_OPTIONS` variable if it is set when a target is
+created.
+
+The options set on the target may be overridden by :prop_sf:`AUTOUIC_OPTIONS`
+set on the ``.ui`` source file.
+
+This property may use "generator expressions" with the syntax ``$<...>``.
+See the :manual:`cmake-generator-expressions(7)` manual for available
+expressions.
+
+See the :manual:`cmake-qt(7)` manual for more information on using CMake
+with Qt.
diff --git a/Help/prop_tgt/BINARY_DIR.rst b/Help/prop_tgt/BINARY_DIR.rst
new file mode 100644
index 000000000..246f7e605
--- /dev/null
+++ b/Help/prop_tgt/BINARY_DIR.rst
@@ -0,0 +1,6 @@
+BINARY_DIR
+----------
+
+This read-only property reports the value of the
+:variable:`CMAKE_CURRENT_BINARY_DIR` variable in the directory in which
+the target was defined.
diff --git a/Help/prop_tgt/BUILD_WITH_INSTALL_RPATH.rst b/Help/prop_tgt/BUILD_WITH_INSTALL_RPATH.rst
new file mode 100644
index 000000000..abcf28ffd
--- /dev/null
+++ b/Help/prop_tgt/BUILD_WITH_INSTALL_RPATH.rst
@@ -0,0 +1,11 @@
+BUILD_WITH_INSTALL_RPATH
+------------------------
+
+Should build tree targets have install tree rpaths.
+
+BUILD_WITH_INSTALL_RPATH is a boolean specifying whether to link the
+target in the build tree with the INSTALL_RPATH. This takes
+precedence over SKIP_BUILD_RPATH and avoids the need for relinking
+before installation. This property is initialized by the value of the
+variable CMAKE_BUILD_WITH_INSTALL_RPATH if it is set when a target is
+created.
diff --git a/Help/prop_tgt/BUNDLE.rst b/Help/prop_tgt/BUNDLE.rst
new file mode 100644
index 000000000..075f017df
--- /dev/null
+++ b/Help/prop_tgt/BUNDLE.rst
@@ -0,0 +1,9 @@
+BUNDLE
+------
+
+This target is a ``CFBundle`` on the OS X.
+
+If a module library target has this property set to true it will be
+built as a ``CFBundle`` when built on the mac. It will have the directory
+structure required for a ``CFBundle`` and will be suitable to be used for
+creating Browser Plugins or other application resources.
diff --git a/Help/prop_tgt/BUNDLE_EXTENSION.rst b/Help/prop_tgt/BUNDLE_EXTENSION.rst
new file mode 100644
index 000000000..ea265b373
--- /dev/null
+++ b/Help/prop_tgt/BUNDLE_EXTENSION.rst
@@ -0,0 +1,7 @@
+BUNDLE_EXTENSION
+----------------
+
+The file extension used to name a :prop_tgt:`BUNDLE` target on the OS X and iOS.
+
+The default value is ``bundle`` - you can also use ``plugin`` or whatever
+file extension is required by the host app for your bundle.
diff --git a/Help/prop_tgt/COMPATIBLE_INTERFACE_BOOL.rst b/Help/prop_tgt/COMPATIBLE_INTERFACE_BOOL.rst
new file mode 100644
index 000000000..6910367e4
--- /dev/null
+++ b/Help/prop_tgt/COMPATIBLE_INTERFACE_BOOL.rst
@@ -0,0 +1,20 @@
+COMPATIBLE_INTERFACE_BOOL
+-------------------------
+
+Properties which must be compatible with their link interface
+
+The ``COMPATIBLE_INTERFACE_BOOL`` property may contain a list of
+properties for this target which must be consistent when evaluated as a
+boolean with the ``INTERFACE`` variant of the property in all linked
+dependees. For example, if a property ``FOO`` appears in the list, then
+for each dependee, the ``INTERFACE_FOO`` property content in all of its
+dependencies must be consistent with each other, and with the ``FOO``
+property in the depender.
+
+Consistency in this sense has the meaning that if the property is set,
+then it must have the same boolean value as all others, and if the
+property is not set, then it is ignored.
+
+Note that for each dependee, the set of properties specified in this
+property must not intersect with the set specified in any of the other
+:ref:`Compatible Interface Properties`.
diff --git a/Help/prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MAX.rst b/Help/prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MAX.rst
new file mode 100644
index 000000000..298acf1ba
--- /dev/null
+++ b/Help/prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MAX.rst
@@ -0,0 +1,18 @@
+COMPATIBLE_INTERFACE_NUMBER_MAX
+-------------------------------
+
+Properties whose maximum value from the link interface will be used.
+
+The ``COMPATIBLE_INTERFACE_NUMBER_MAX`` property may contain a list of
+properties for this target whose maximum value may be read at generate
+time when evaluated in the ``INTERFACE`` variant of the property in all
+linked dependees. For example, if a property ``FOO`` appears in the list,
+then for each dependee, the ``INTERFACE_FOO`` property content in all of
+its dependencies will be compared with each other and with the ``FOO``
+property in the depender. When reading the ``FOO`` property at generate
+time, the maximum value will be returned. If the property is not set,
+then it is ignored.
+
+Note that for each dependee, the set of properties specified in this
+property must not intersect with the set specified in any of the other
+:ref:`Compatible Interface Properties`.
diff --git a/Help/prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MIN.rst b/Help/prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MIN.rst
new file mode 100644
index 000000000..d5fd8252a
--- /dev/null
+++ b/Help/prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MIN.rst
@@ -0,0 +1,18 @@
+COMPATIBLE_INTERFACE_NUMBER_MIN
+-------------------------------
+
+Properties whose maximum value from the link interface will be used.
+
+The ``COMPATIBLE_INTERFACE_NUMBER_MIN`` property may contain a list of
+properties for this target whose minimum value may be read at generate
+time when evaluated in the ``INTERFACE`` variant of the property of all
+linked dependees. For example, if a
+property ``FOO`` appears in the list, then for each dependee, the
+``INTERFACE_FOO`` property content in all of its dependencies will be
+compared with each other and with the ``FOO`` property in the depender.
+When reading the ``FOO`` property at generate time, the minimum value
+will be returned. If the property is not set, then it is ignored.
+
+Note that for each dependee, the set of properties specified in this
+property must not intersect with the set specified in any of the other
+:ref:`Compatible Interface Properties`.
diff --git a/Help/prop_tgt/COMPATIBLE_INTERFACE_STRING.rst b/Help/prop_tgt/COMPATIBLE_INTERFACE_STRING.rst
new file mode 100644
index 000000000..a0050b941
--- /dev/null
+++ b/Help/prop_tgt/COMPATIBLE_INTERFACE_STRING.rst
@@ -0,0 +1,16 @@
+COMPATIBLE_INTERFACE_STRING
+---------------------------
+
+Properties which must be string-compatible with their link interface
+
+The ``COMPATIBLE_INTERFACE_STRING`` property may contain a list of
+properties for this target which must be the same when evaluated as a
+string in the ``INTERFACE`` variant of the property all linked dependees.
+For example, if a property ``FOO`` appears in the list, then for each
+dependee, the ``INTERFACE_FOO`` property content in all of its
+dependencies must be equal with each other, and with the ``FOO`` property
+in the depender. If the property is not set, then it is ignored.
+
+Note that for each dependee, the set of properties specified in this
+property must not intersect with the set specified in any of the other
+:ref:`Compatible Interface Properties`.
diff --git a/Help/prop_tgt/COMPILE_DEFINITIONS.rst b/Help/prop_tgt/COMPILE_DEFINITIONS.rst
new file mode 100644
index 000000000..00c49c379
--- /dev/null
+++ b/Help/prop_tgt/COMPILE_DEFINITIONS.rst
@@ -0,0 +1,26 @@
+COMPILE_DEFINITIONS
+-------------------
+
+Preprocessor definitions for compiling a target's sources.
+
+The ``COMPILE_DEFINITIONS`` property may be set to a semicolon-separated
+list of preprocessor definitions using the syntax ``VAR`` or ``VAR=value``.
+Function-style definitions are not supported. CMake will
+automatically escape the value correctly for the native build system
+(note that CMake language syntax may require escapes to specify some
+values).
+
+CMake will automatically drop some definitions that are not supported
+by the native build tool. The VS6 IDE does not support definition
+values with spaces (but NMake does).
+
+.. include:: /include/COMPILE_DEFINITIONS_DISCLAIMER.txt
+
+Contents of ``COMPILE_DEFINITIONS`` may use "generator expressions" with the
+syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual
+for available expressions. See the :manual:`cmake-buildsystem(7)` manual
+for more on defining buildsystem properties.
+
+The corresponding :prop_tgt:`COMPILE_DEFINITIONS_<CONFIG>` property may
+be set to specify per-configuration definitions. Generator expressions
+should be preferred instead of setting the alternative property.
diff --git a/Help/prop_tgt/COMPILE_DEFINITIONS_CONFIG.rst b/Help/prop_tgt/COMPILE_DEFINITIONS_CONFIG.rst
new file mode 100644
index 000000000..84bd5e483
--- /dev/null
+++ b/Help/prop_tgt/COMPILE_DEFINITIONS_CONFIG.rst
@@ -0,0 +1,16 @@
+COMPILE_DEFINITIONS_<CONFIG>
+----------------------------
+
+Ignored. See CMake Policy :policy:`CMP0043`.
+
+Per-configuration preprocessor definitions on a target.
+
+This is the configuration-specific version of :prop_tgt:`COMPILE_DEFINITIONS`
+where ``<CONFIG>`` is an upper-case name (ex. ``COMPILE_DEFINITIONS_DEBUG``).
+
+Contents of ``COMPILE_DEFINITIONS_<CONFIG>`` may use "generator expressions"
+with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions. See the :manual:`cmake-buildsystem(7)`
+manual for more on defining buildsystem properties.
+
+Generator expressions should be preferred instead of setting this property.
diff --git a/Help/prop_tgt/COMPILE_FEATURES.rst b/Help/prop_tgt/COMPILE_FEATURES.rst
new file mode 100644
index 000000000..195215e3c
--- /dev/null
+++ b/Help/prop_tgt/COMPILE_FEATURES.rst
@@ -0,0 +1,12 @@
+COMPILE_FEATURES
+----------------
+
+Compiler features enabled for this target.
+
+The list of features in this property are a subset of the features listed
+in the :variable:`CMAKE_CXX_COMPILE_FEATURES` variable.
+
+Contents of ``COMPILE_FEATURES`` may use "generator expressions" with the
+syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual for
+available expressions. See the :manual:`cmake-compile-features(7)` manual
+for information on compile features and a list of supported compilers.
diff --git a/Help/prop_tgt/COMPILE_FLAGS.rst b/Help/prop_tgt/COMPILE_FLAGS.rst
new file mode 100644
index 000000000..6ee6c5148
--- /dev/null
+++ b/Help/prop_tgt/COMPILE_FLAGS.rst
@@ -0,0 +1,11 @@
+COMPILE_FLAGS
+-------------
+
+Additional flags to use when compiling this target's sources.
+
+The COMPILE_FLAGS property sets additional compiler flags used to
+build sources within the target. Use COMPILE_DEFINITIONS to pass
+additional preprocessor definitions.
+
+This property is deprecated. Use the COMPILE_OPTIONS property or the
+target_compile_options command instead.
diff --git a/Help/prop_tgt/COMPILE_OPTIONS.rst b/Help/prop_tgt/COMPILE_OPTIONS.rst
new file mode 100644
index 000000000..36d786a7f
--- /dev/null
+++ b/Help/prop_tgt/COMPILE_OPTIONS.rst
@@ -0,0 +1,17 @@
+COMPILE_OPTIONS
+---------------
+
+List of options to pass to the compiler.
+
+This property holds a :ref:`;-list <CMake Language Lists>` of options
+specified so far for its target. Use the :command:`target_compile_options`
+command to append more options.
+
+This property is intialized by the :prop_dir:`COMPILE_OPTIONS` directory
+property when a target is created, and is used by the generators to set
+the options for the compiler.
+
+Contents of ``COMPILE_OPTIONS`` may use "generator expressions" with the
+syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual
+for available expressions. See the :manual:`cmake-buildsystem(7)` manual
+for more on defining buildsystem properties.
diff --git a/Help/prop_tgt/COMPILE_PDB_NAME.rst b/Help/prop_tgt/COMPILE_PDB_NAME.rst
new file mode 100644
index 000000000..24a9f62d6
--- /dev/null
+++ b/Help/prop_tgt/COMPILE_PDB_NAME.rst
@@ -0,0 +1,11 @@
+COMPILE_PDB_NAME
+----------------
+
+Output name for the MS debug symbol ``.pdb`` file generated by the
+compiler while building source files.
+
+This property specifies the base name for the debug symbols file.
+If not set, the default is unspecified.
+
+.. |PDB_XXX| replace:: :prop_tgt:`PDB_NAME`
+.. include:: COMPILE_PDB_NOTE.txt
diff --git a/Help/prop_tgt/COMPILE_PDB_NAME_CONFIG.rst b/Help/prop_tgt/COMPILE_PDB_NAME_CONFIG.rst
new file mode 100644
index 000000000..e4077f559
--- /dev/null
+++ b/Help/prop_tgt/COMPILE_PDB_NAME_CONFIG.rst
@@ -0,0 +1,10 @@
+COMPILE_PDB_NAME_<CONFIG>
+-------------------------
+
+Per-configuration output name for the MS debug symbol ``.pdb`` file
+generated by the compiler while building source files.
+
+This is the configuration-specific version of :prop_tgt:`COMPILE_PDB_NAME`.
+
+.. |PDB_XXX| replace:: :prop_tgt:`PDB_NAME_<CONFIG>`
+.. include:: COMPILE_PDB_NOTE.txt
diff --git a/Help/prop_tgt/COMPILE_PDB_NOTE.txt b/Help/prop_tgt/COMPILE_PDB_NOTE.txt
new file mode 100644
index 000000000..5941d72ef
--- /dev/null
+++ b/Help/prop_tgt/COMPILE_PDB_NOTE.txt
@@ -0,0 +1,8 @@
+.. note::
+ The compiler-generated program database files are specified by the
+ ``/Fd`` compiler flag and are not the same as linker-generated
+ program database files specified by the ``/pdb`` linker flag.
+ Use the |PDB_XXX| property to specify the latter.
+
+ This property is not implemented by the :generator:`Visual Studio 6`
+ generator.
diff --git a/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY.rst b/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY.rst
new file mode 100644
index 000000000..34f49bebe
--- /dev/null
+++ b/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY.rst
@@ -0,0 +1,13 @@
+COMPILE_PDB_OUTPUT_DIRECTORY
+----------------------------
+
+Output directory for the MS debug symbol ``.pdb`` file
+generated by the compiler while building source files.
+
+This property specifies the directory into which the MS debug symbols
+will be placed by the compiler. This property is initialized by the
+value of the :variable:`CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY` variable
+if it is set when a target is created.
+
+.. |PDB_XXX| replace:: :prop_tgt:`PDB_OUTPUT_DIRECTORY`
+.. include:: COMPILE_PDB_NOTE.txt
diff --git a/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst b/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst
new file mode 100644
index 000000000..52ef013da
--- /dev/null
+++ b/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst
@@ -0,0 +1,16 @@
+COMPILE_PDB_OUTPUT_DIRECTORY_<CONFIG>
+-------------------------------------
+
+Per-configuration output directory for the MS debug symbol ``.pdb`` file
+generated by the compiler while building source files.
+
+This is a per-configuration version of
+:prop_tgt:`COMPILE_PDB_OUTPUT_DIRECTORY`,
+but multi-configuration generators (VS, Xcode) do NOT append a
+per-configuration subdirectory to the specified directory. This
+property is initialized by the value of the
+:variable:`CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_<CONFIG>` variable
+if it is set when a target is created.
+
+.. |PDB_XXX| replace:: :prop_tgt:`PDB_OUTPUT_DIRECTORY_<CONFIG>`
+.. include:: COMPILE_PDB_NOTE.txt
diff --git a/Help/prop_tgt/CONFIG_OUTPUT_NAME.rst b/Help/prop_tgt/CONFIG_OUTPUT_NAME.rst
new file mode 100644
index 000000000..a61c70295
--- /dev/null
+++ b/Help/prop_tgt/CONFIG_OUTPUT_NAME.rst
@@ -0,0 +1,8 @@
+<CONFIG>_OUTPUT_NAME
+--------------------
+
+Old per-configuration target file base name.
+Use :prop_tgt:`OUTPUT_NAME_<CONFIG>` instead.
+
+This is a configuration-specific version of the :prop_tgt:`OUTPUT_NAME`
+target property.
diff --git a/Help/prop_tgt/CONFIG_POSTFIX.rst b/Help/prop_tgt/CONFIG_POSTFIX.rst
new file mode 100644
index 000000000..11b50b900
--- /dev/null
+++ b/Help/prop_tgt/CONFIG_POSTFIX.rst
@@ -0,0 +1,10 @@
+<CONFIG>_POSTFIX
+----------------
+
+Postfix to append to the target file name for configuration <CONFIG>.
+
+When building with configuration <CONFIG> the value of this property
+is appended to the target file name built on disk. For non-executable
+targets, this property is initialized by the value of the variable
+CMAKE_<CONFIG>_POSTFIX if it is set when a target is created. This
+property is ignored on the Mac for Frameworks and App Bundles.
diff --git a/Help/prop_tgt/CROSSCOMPILING_EMULATOR.rst b/Help/prop_tgt/CROSSCOMPILING_EMULATOR.rst
new file mode 100644
index 000000000..3ef8e0308
--- /dev/null
+++ b/Help/prop_tgt/CROSSCOMPILING_EMULATOR.rst
@@ -0,0 +1,6 @@
+CROSSCOMPILING_EMULATOR
+-----------------------
+
+Use the given emulator to run executables created when crosscompiling. This
+command will be added as a prefix to :command:`add_test` test commands for
+built target system executables.
diff --git a/Help/prop_tgt/CXX_EXTENSIONS.rst b/Help/prop_tgt/CXX_EXTENSIONS.rst
new file mode 100644
index 000000000..0f547e292
--- /dev/null
+++ b/Help/prop_tgt/CXX_EXTENSIONS.rst
@@ -0,0 +1,16 @@
+CXX_EXTENSIONS
+--------------
+
+Boolean specifying whether compiler specific extensions are requested.
+
+This property specifies whether compiler specific extensions should be
+used. For some compilers, this results in adding a flag such
+as ``-std=gnu++11`` instead of ``-std=c++11`` to the compile line. This
+property is ``ON`` by default.
+
+See the :manual:`cmake-compile-features(7)` manual for information on
+compile features and a list of supported compilers.
+
+This property is initialized by the value of
+the :variable:`CMAKE_CXX_EXTENSIONS` variable if it is set when a target
+is created.
diff --git a/Help/prop_tgt/CXX_STANDARD.rst b/Help/prop_tgt/CXX_STANDARD.rst
new file mode 100644
index 000000000..edc9ba534
--- /dev/null
+++ b/Help/prop_tgt/CXX_STANDARD.rst
@@ -0,0 +1,31 @@
+CXX_STANDARD
+------------
+
+The C++ standard whose features are requested to build this target.
+
+This property specifies the C++ standard whose features are requested
+to build this target. For some compilers, this results in adding a
+flag such as ``-std=gnu++11`` to the compile line. For compilers that
+have no notion of a standard level, such as MSVC, this has no effect.
+
+Supported values are ``98``, ``11`` and ``14``.
+
+If the value requested does not result in a compile flag being added for
+the compiler in use, a previous standard flag will be added instead. This
+means that using:
+
+.. code-block:: cmake
+
+ set_property(TARGET tgt PROPERTY CXX_STANDARD 11)
+
+with a compiler which does not support ``-std=gnu++11`` or an equivalent
+flag will not result in an error or warning, but will instead add the
+``-std=gnu++98`` flag if supported. This "decay" behavior may be controlled
+with the :prop_tgt:`CXX_STANDARD_REQUIRED` target property.
+
+See the :manual:`cmake-compile-features(7)` manual for information on
+compile features and a list of supported compilers.
+
+This property is initialized by the value of
+the :variable:`CMAKE_CXX_STANDARD` variable if it is set when a target
+is created.
diff --git a/Help/prop_tgt/CXX_STANDARD_REQUIRED.rst b/Help/prop_tgt/CXX_STANDARD_REQUIRED.rst
new file mode 100644
index 000000000..697d7f60d
--- /dev/null
+++ b/Help/prop_tgt/CXX_STANDARD_REQUIRED.rst
@@ -0,0 +1,18 @@
+CXX_STANDARD_REQUIRED
+---------------------
+
+Boolean describing whether the value of :prop_tgt:`CXX_STANDARD` is a requirement.
+
+If this property is set to ``ON``, then the value of the
+:prop_tgt:`CXX_STANDARD` target property is treated as a requirement. If this
+property is ``OFF`` or unset, the :prop_tgt:`CXX_STANDARD` target property is
+treated as optional and may "decay" to a previous standard if the requested is
+not available. For compilers that have no notion of a standard level, such as
+MSVC, this has no effect.
+
+See the :manual:`cmake-compile-features(7)` manual for information on
+compile features and a list of supported compilers.
+
+This property is initialized by the value of
+the :variable:`CMAKE_CXX_STANDARD_REQUIRED` variable if it is set when a
+target is created.
diff --git a/Help/prop_tgt/C_EXTENSIONS.rst b/Help/prop_tgt/C_EXTENSIONS.rst
new file mode 100644
index 000000000..fce67f49c
--- /dev/null
+++ b/Help/prop_tgt/C_EXTENSIONS.rst
@@ -0,0 +1,16 @@
+C_EXTENSIONS
+------------
+
+Boolean specifying whether compiler specific extensions are requested.
+
+This property specifies whether compiler specific extensions should be
+used. For some compilers, this results in adding a flag such
+as ``-std=gnu11`` instead of ``-std=c11`` to the compile line. This
+property is ``ON`` by default.
+
+See the :manual:`cmake-compile-features(7)` manual for information on
+compile features and a list of supported compilers.
+
+This property is initialized by the value of
+the :variable:`CMAKE_C_EXTENSIONS` variable if it is set when a target
+is created.
diff --git a/Help/prop_tgt/C_STANDARD.rst b/Help/prop_tgt/C_STANDARD.rst
new file mode 100644
index 000000000..5e3682186
--- /dev/null
+++ b/Help/prop_tgt/C_STANDARD.rst
@@ -0,0 +1,31 @@
+C_STANDARD
+----------
+
+The C standard whose features are requested to build this target.
+
+This property specifies the C standard whose features are requested
+to build this target. For some compilers, this results in adding a
+flag such as ``-std=gnu11`` to the compile line. For compilers that
+have no notion of a standard level, such as MSVC, this has no effect.
+
+Supported values are ``90``, ``99`` and ``11``.
+
+If the value requested does not result in a compile flag being added for
+the compiler in use, a previous standard flag will be added instead. This
+means that using:
+
+.. code-block:: cmake
+
+ set_property(TARGET tgt PROPERTY C_STANDARD 11)
+
+with a compiler which does not support ``-std=gnu11`` or an equivalent
+flag will not result in an error or warning, but will instead add the
+``-std=gnu99`` or ``-std=gnu90`` flag if supported. This "decay" behavior may
+be controlled with the :prop_tgt:`C_STANDARD_REQUIRED` target property.
+
+See the :manual:`cmake-compile-features(7)` manual for information on
+compile features and a list of supported compilers.
+
+This property is initialized by the value of
+the :variable:`CMAKE_C_STANDARD` variable if it is set when a target
+is created.
diff --git a/Help/prop_tgt/C_STANDARD_REQUIRED.rst b/Help/prop_tgt/C_STANDARD_REQUIRED.rst
new file mode 100644
index 000000000..acfad986b
--- /dev/null
+++ b/Help/prop_tgt/C_STANDARD_REQUIRED.rst
@@ -0,0 +1,18 @@
+C_STANDARD_REQUIRED
+-------------------
+
+Boolean describing whether the value of :prop_tgt:`C_STANDARD` is a requirement.
+
+If this property is set to ``ON``, then the value of the
+:prop_tgt:`C_STANDARD` target property is treated as a requirement. If this
+property is ``OFF`` or unset, the :prop_tgt:`C_STANDARD` target property is
+treated as optional and may "decay" to a previous standard if the requested is
+not available. For compilers that have no notion of a standard level, such as
+MSVC, this has no effect.
+
+See the :manual:`cmake-compile-features(7)` manual for information on
+compile features and a list of supported compilers.
+
+This property is initialized by the value of
+the :variable:`CMAKE_C_STANDARD_REQUIRED` variable if it is set when a
+target is created.
diff --git a/Help/prop_tgt/DEBUG_POSTFIX.rst b/Help/prop_tgt/DEBUG_POSTFIX.rst
new file mode 100644
index 000000000..1487656d9
--- /dev/null
+++ b/Help/prop_tgt/DEBUG_POSTFIX.rst
@@ -0,0 +1,7 @@
+DEBUG_POSTFIX
+-------------
+
+See target property <CONFIG>_POSTFIX.
+
+This property is a special case of the more-general <CONFIG>_POSTFIX
+property for the DEBUG configuration.
diff --git a/Help/prop_tgt/DEFINE_SYMBOL.rst b/Help/prop_tgt/DEFINE_SYMBOL.rst
new file mode 100644
index 000000000..f47f135ea
--- /dev/null
+++ b/Help/prop_tgt/DEFINE_SYMBOL.rst
@@ -0,0 +1,11 @@
+DEFINE_SYMBOL
+-------------
+
+Define a symbol when compiling this target's sources.
+
+DEFINE_SYMBOL sets the name of the preprocessor symbol defined when
+compiling sources in a shared library. If not set here then it is set
+to target_EXPORTS by default (with some substitutions if the target is
+not a valid C identifier). This is useful for headers to know whether
+they are being included from inside their library or outside to
+properly setup dllexport/dllimport decorations.
diff --git a/Help/prop_tgt/ENABLE_EXPORTS.rst b/Help/prop_tgt/ENABLE_EXPORTS.rst
new file mode 100644
index 000000000..9e2230971
--- /dev/null
+++ b/Help/prop_tgt/ENABLE_EXPORTS.rst
@@ -0,0 +1,22 @@
+ENABLE_EXPORTS
+--------------
+
+Specify whether an executable exports symbols for loadable modules.
+
+Normally an executable does not export any symbols because it is the
+final program. It is possible for an executable to export symbols to
+be used by loadable modules. When this property is set to true CMake
+will allow other targets to "link" to the executable with the
+:command:`TARGET_LINK_LIBRARIES` command. On all platforms a target-level
+dependency on the executable is created for targets that link to it.
+For DLL platforms an import library will be created for the exported
+symbols and then used for linking. All Windows-based systems
+including Cygwin are DLL platforms. For non-DLL platforms that
+require all symbols to be resolved at link time, such as OS X, the
+module will "link" to the executable using a flag like
+``-bundle_loader``. For other non-DLL platforms the link rule is simply
+ignored since the dynamic loader will automatically bind symbols when
+the module is loaded.
+
+This property is initialized by the value of the variable
+:variable:`CMAKE_ENABLE_EXPORTS` if it is set when a target is created.
diff --git a/Help/prop_tgt/EXCLUDE_FROM_ALL.rst b/Help/prop_tgt/EXCLUDE_FROM_ALL.rst
new file mode 100644
index 000000000..caa5741f8
--- /dev/null
+++ b/Help/prop_tgt/EXCLUDE_FROM_ALL.rst
@@ -0,0 +1,10 @@
+EXCLUDE_FROM_ALL
+----------------
+
+Exclude the target from the all target.
+
+A property on a target that indicates if the target is excluded from
+the default build target. If it is not, then with a Makefile for
+example typing make will cause this target to be built. The same
+concept applies to the default build of other generators. Installing
+a target with EXCLUDE_FROM_ALL set to true has undefined behavior.
diff --git a/Help/prop_tgt/EXCLUDE_FROM_DEFAULT_BUILD.rst b/Help/prop_tgt/EXCLUDE_FROM_DEFAULT_BUILD.rst
new file mode 100644
index 000000000..19270a59d
--- /dev/null
+++ b/Help/prop_tgt/EXCLUDE_FROM_DEFAULT_BUILD.rst
@@ -0,0 +1,8 @@
+EXCLUDE_FROM_DEFAULT_BUILD
+--------------------------
+
+Exclude target from "Build Solution".
+
+This property is only used by Visual Studio generators 7 and above.
+When set to TRUE, the target will not be built when you press "Build
+Solution".
diff --git a/Help/prop_tgt/EXCLUDE_FROM_DEFAULT_BUILD_CONFIG.rst b/Help/prop_tgt/EXCLUDE_FROM_DEFAULT_BUILD_CONFIG.rst
new file mode 100644
index 000000000..655a9dee0
--- /dev/null
+++ b/Help/prop_tgt/EXCLUDE_FROM_DEFAULT_BUILD_CONFIG.rst
@@ -0,0 +1,9 @@
+EXCLUDE_FROM_DEFAULT_BUILD_<CONFIG>
+-----------------------------------
+
+Per-configuration version of target exclusion from "Build Solution".
+
+This is the configuration-specific version of
+EXCLUDE_FROM_DEFAULT_BUILD. If the generic EXCLUDE_FROM_DEFAULT_BUILD
+is also set on a target, EXCLUDE_FROM_DEFAULT_BUILD_<CONFIG> takes
+precedence in configurations for which it has a value.
diff --git a/Help/prop_tgt/EXPORT_NAME.rst b/Help/prop_tgt/EXPORT_NAME.rst
new file mode 100644
index 000000000..1b4247cc5
--- /dev/null
+++ b/Help/prop_tgt/EXPORT_NAME.rst
@@ -0,0 +1,8 @@
+EXPORT_NAME
+-----------
+
+Exported name for target files.
+
+This sets the name for the IMPORTED target generated when it this
+target is is exported. If not set, the logical target name is used by
+default.
diff --git a/Help/prop_tgt/EchoString.rst b/Help/prop_tgt/EchoString.rst
new file mode 100644
index 000000000..32ae2aa8f
--- /dev/null
+++ b/Help/prop_tgt/EchoString.rst
@@ -0,0 +1,7 @@
+EchoString
+----------
+
+A message to be displayed when the target is built.
+
+A message to display on some generators (such as makefiles) when the
+target is built.
diff --git a/Help/prop_tgt/FOLDER.rst b/Help/prop_tgt/FOLDER.rst
new file mode 100644
index 000000000..bfe4e8e16
--- /dev/null
+++ b/Help/prop_tgt/FOLDER.rst
@@ -0,0 +1,10 @@
+FOLDER
+------
+
+Set the folder name. Use to organize targets in an IDE.
+
+Targets with no FOLDER property will appear as top level entities in
+IDEs like Visual Studio. Targets with the same FOLDER property value
+will appear next to each other in a folder of that name. To nest
+folders, use FOLDER values such as 'GUI/Dialogs' with '/' characters
+separating folder levels.
diff --git a/Help/prop_tgt/FRAMEWORK.rst b/Help/prop_tgt/FRAMEWORK.rst
new file mode 100644
index 000000000..6c212c3d0
--- /dev/null
+++ b/Help/prop_tgt/FRAMEWORK.rst
@@ -0,0 +1,31 @@
+FRAMEWORK
+---------
+
+Build ``SHARED`` library as Framework Bundle on the OS X and iOS.
+
+If a ``SHARED`` library target has this property set to ``TRUE`` it will be
+built as a framework when built on the OS X and iOS. It will have the
+directory structure required for a framework and will be suitable to
+be used with the ``-framework`` option
+
+To customize ``Info.plist`` file in the framework, use
+:prop_tgt:`MACOSX_FRAMEWORK_INFO_PLIST` target property.
+
+For OS X see also the :prop_tgt:`FRAMEWORK_VERSION` target property.
+
+Example of creation ``dynamicFramework``:
+
+.. code-block:: cmake
+
+ add_library(dynamicFramework SHARED
+ dynamicFramework.c
+ dynamicFramework.h
+ )
+ set_target_properties(dynamicFramework PROPERTIES
+ FRAMEWORK TRUE
+ FRAMEWORK_VERSION C
+ MACOSX_FRAMEWORK_IDENTIFIER com.cmake.dynamicFramework
+ MACOSX_FRAMEWORK_INFO_PLIST Info.plist
+ PUBLIC_HEADER dynamicFramework.h
+ XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer"
+ )
diff --git a/Help/prop_tgt/FRAMEWORK_VERSION.rst b/Help/prop_tgt/FRAMEWORK_VERSION.rst
new file mode 100644
index 000000000..6aa30268a
--- /dev/null
+++ b/Help/prop_tgt/FRAMEWORK_VERSION.rst
@@ -0,0 +1,8 @@
+FRAMEWORK_VERSION
+-----------------
+
+Version of a framework created using the :prop_tgt:`FRAMEWORK` target
+property (e.g. ``A``).
+
+This property only affects OS X, as iOS doesn't have versioned
+directory structure.
diff --git a/Help/prop_tgt/Fortran_FORMAT.rst b/Help/prop_tgt/Fortran_FORMAT.rst
new file mode 100644
index 000000000..0a11d91ca
--- /dev/null
+++ b/Help/prop_tgt/Fortran_FORMAT.rst
@@ -0,0 +1,11 @@
+Fortran_FORMAT
+--------------
+
+Set to FIXED or FREE to indicate the Fortran source layout.
+
+This property tells CMake whether the Fortran source files in a target
+use fixed-format or free-format. CMake will pass the corresponding
+format flag to the compiler. Use the source-specific Fortran_FORMAT
+property to change the format of a specific source file. If the
+variable CMAKE_Fortran_FORMAT is set when a target is created its
+value is used to initialize this property.
diff --git a/Help/prop_tgt/Fortran_MODULE_DIRECTORY.rst b/Help/prop_tgt/Fortran_MODULE_DIRECTORY.rst
new file mode 100644
index 000000000..9c8643764
--- /dev/null
+++ b/Help/prop_tgt/Fortran_MODULE_DIRECTORY.rst
@@ -0,0 +1,17 @@
+Fortran_MODULE_DIRECTORY
+------------------------
+
+Specify output directory for Fortran modules provided by the target.
+
+If the target contains Fortran source files that provide modules and
+the compiler supports a module output directory this specifies the
+directory in which the modules will be placed. When this property is
+not set the modules will be placed in the build directory
+corresponding to the target's source directory. If the variable
+CMAKE_Fortran_MODULE_DIRECTORY is set when a target is created its
+value is used to initialize this property.
+
+Note that some compilers will automatically search the module output
+directory for modules USEd during compilation but others will not. If
+your sources USE modules their location must be specified by
+INCLUDE_DIRECTORIES regardless of this property.
diff --git a/Help/prop_tgt/GENERATOR_FILE_NAME.rst b/Help/prop_tgt/GENERATOR_FILE_NAME.rst
new file mode 100644
index 000000000..032b22acf
--- /dev/null
+++ b/Help/prop_tgt/GENERATOR_FILE_NAME.rst
@@ -0,0 +1,9 @@
+GENERATOR_FILE_NAME
+-------------------
+
+Generator's file for this target.
+
+An internal property used by some generators to record the name of the
+project or dsp file associated with this target. Note that at
+configure time, this property is only set for targets created by
+include_external_msproject().
diff --git a/Help/prop_tgt/GNUtoMS.rst b/Help/prop_tgt/GNUtoMS.rst
new file mode 100644
index 000000000..cf34da9c3
--- /dev/null
+++ b/Help/prop_tgt/GNUtoMS.rst
@@ -0,0 +1,17 @@
+GNUtoMS
+-------
+
+Convert GNU import library (.dll.a) to MS format (.lib).
+
+When linking a shared library or executable that exports symbols using
+GNU tools on Windows (MinGW/MSYS) with Visual Studio installed convert
+the import library (.dll.a) from GNU to MS format (.lib). Both import
+libraries will be installed by install(TARGETS) and exported by
+install(EXPORT) and export() to be linked by applications with either
+GNU- or MS-compatible tools.
+
+If the variable CMAKE_GNUtoMS is set when a target is created its
+value is used to initialize this property. The variable must be set
+prior to the first command that enables a language such as project()
+or enable_language(). CMake provides the variable as an option to the
+user automatically when configuring on Windows with GNU tools.
diff --git a/Help/prop_tgt/HAS_CXX.rst b/Help/prop_tgt/HAS_CXX.rst
new file mode 100644
index 000000000..7790932ae
--- /dev/null
+++ b/Help/prop_tgt/HAS_CXX.rst
@@ -0,0 +1,7 @@
+HAS_CXX
+-------
+
+Link the target using the C++ linker tool (obsolete).
+
+This is equivalent to setting the LINKER_LANGUAGE property to CXX.
+See that property's documentation for details.
diff --git a/Help/prop_tgt/IMPLICIT_DEPENDS_INCLUDE_TRANSFORM.rst b/Help/prop_tgt/IMPLICIT_DEPENDS_INCLUDE_TRANSFORM.rst
new file mode 100644
index 000000000..dc738071d
--- /dev/null
+++ b/Help/prop_tgt/IMPLICIT_DEPENDS_INCLUDE_TRANSFORM.rst
@@ -0,0 +1,32 @@
+IMPLICIT_DEPENDS_INCLUDE_TRANSFORM
+----------------------------------
+
+Specify #include line transforms for dependencies in a target.
+
+This property specifies rules to transform macro-like #include lines
+during implicit dependency scanning of C and C++ source files. The
+list of rules must be semicolon-separated with each entry of the form
+"A_MACRO(%)=value-with-%" (the % must be literal). During dependency
+scanning occurrences of A_MACRO(...) on #include lines will be
+replaced by the value given with the macro argument substituted for
+'%'. For example, the entry
+
+::
+
+ MYDIR(%)=<mydir/%>
+
+will convert lines of the form
+
+::
+
+ #include MYDIR(myheader.h)
+
+to
+
+::
+
+ #include <mydir/myheader.h>
+
+allowing the dependency to be followed.
+
+This property applies to sources in the target on which it is set.
diff --git a/Help/prop_tgt/IMPORTED.rst b/Help/prop_tgt/IMPORTED.rst
new file mode 100644
index 000000000..605c1ce6c
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED.rst
@@ -0,0 +1,8 @@
+IMPORTED
+--------
+
+Read-only indication of whether a target is IMPORTED.
+
+The boolean value of this property is ``True`` for targets created with
+the IMPORTED option to :command:`add_executable` or :command:`add_library`.
+It is ``False`` for targets built within the project.
diff --git a/Help/prop_tgt/IMPORTED_CONFIGURATIONS.rst b/Help/prop_tgt/IMPORTED_CONFIGURATIONS.rst
new file mode 100644
index 000000000..6de1baa23
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED_CONFIGURATIONS.rst
@@ -0,0 +1,11 @@
+IMPORTED_CONFIGURATIONS
+-----------------------
+
+Configurations provided for an IMPORTED target.
+
+Set this to the list of configuration names available for an IMPORTED
+target. The names correspond to configurations defined in the project
+from which the target is imported. If the importing project uses a
+different set of configurations the names may be mapped using the
+MAP_IMPORTED_CONFIG_<CONFIG> property. Ignored for non-imported
+targets.
diff --git a/Help/prop_tgt/IMPORTED_IMPLIB.rst b/Help/prop_tgt/IMPORTED_IMPLIB.rst
new file mode 100644
index 000000000..acf4b321f
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED_IMPLIB.rst
@@ -0,0 +1,7 @@
+IMPORTED_IMPLIB
+---------------
+
+Full path to the import library for an IMPORTED target.
+
+Set this to the location of the ".lib" part of a windows DLL. Ignored
+for non-imported targets.
diff --git a/Help/prop_tgt/IMPORTED_IMPLIB_CONFIG.rst b/Help/prop_tgt/IMPORTED_IMPLIB_CONFIG.rst
new file mode 100644
index 000000000..b4b3f0228
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED_IMPLIB_CONFIG.rst
@@ -0,0 +1,7 @@
+IMPORTED_IMPLIB_<CONFIG>
+------------------------
+
+<CONFIG>-specific version of IMPORTED_IMPLIB property.
+
+Configuration names correspond to those provided by the project from
+which the target is imported.
diff --git a/Help/prop_tgt/IMPORTED_LINK_DEPENDENT_LIBRARIES.rst b/Help/prop_tgt/IMPORTED_LINK_DEPENDENT_LIBRARIES.rst
new file mode 100644
index 000000000..2db2b0e58
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED_LINK_DEPENDENT_LIBRARIES.rst
@@ -0,0 +1,14 @@
+IMPORTED_LINK_DEPENDENT_LIBRARIES
+---------------------------------
+
+Dependent shared libraries of an imported shared library.
+
+Shared libraries may be linked to other shared libraries as part of
+their implementation. On some platforms the linker searches for the
+dependent libraries of shared libraries they are including in the
+link. Set this property to the list of dependent shared libraries of
+an imported library. The list should be disjoint from the list of
+interface libraries in the INTERFACE_LINK_LIBRARIES property. On
+platforms requiring dependent shared libraries to be found at link
+time CMake uses this list to add appropriate files or paths to the
+link command line. Ignored for non-imported targets.
diff --git a/Help/prop_tgt/IMPORTED_LINK_DEPENDENT_LIBRARIES_CONFIG.rst b/Help/prop_tgt/IMPORTED_LINK_DEPENDENT_LIBRARIES_CONFIG.rst
new file mode 100644
index 000000000..ee243c75d
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED_LINK_DEPENDENT_LIBRARIES_CONFIG.rst
@@ -0,0 +1,8 @@
+IMPORTED_LINK_DEPENDENT_LIBRARIES_<CONFIG>
+------------------------------------------
+
+<CONFIG>-specific version of IMPORTED_LINK_DEPENDENT_LIBRARIES.
+
+Configuration names correspond to those provided by the project from
+which the target is imported. If set, this property completely
+overrides the generic property for the named configuration.
diff --git a/Help/prop_tgt/IMPORTED_LINK_INTERFACE_LANGUAGES.rst b/Help/prop_tgt/IMPORTED_LINK_INTERFACE_LANGUAGES.rst
new file mode 100644
index 000000000..5ca9c8b6f
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED_LINK_INTERFACE_LANGUAGES.rst
@@ -0,0 +1,14 @@
+IMPORTED_LINK_INTERFACE_LANGUAGES
+---------------------------------
+
+Languages compiled into an IMPORTED static library.
+
+Set this to the list of languages of source files compiled to produce
+a STATIC IMPORTED library (such as "C" or "CXX"). CMake accounts for
+these languages when computing how to link a target to the imported
+library. For example, when a C executable links to an imported C++
+static library CMake chooses the C++ linker to satisfy language
+runtime dependencies of the static library.
+
+This property is ignored for targets that are not STATIC libraries.
+This property is ignored for non-imported targets.
diff --git a/Help/prop_tgt/IMPORTED_LINK_INTERFACE_LANGUAGES_CONFIG.rst b/Help/prop_tgt/IMPORTED_LINK_INTERFACE_LANGUAGES_CONFIG.rst
new file mode 100644
index 000000000..d4a10fbdd
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED_LINK_INTERFACE_LANGUAGES_CONFIG.rst
@@ -0,0 +1,8 @@
+IMPORTED_LINK_INTERFACE_LANGUAGES_<CONFIG>
+------------------------------------------
+
+<CONFIG>-specific version of IMPORTED_LINK_INTERFACE_LANGUAGES.
+
+Configuration names correspond to those provided by the project from
+which the target is imported. If set, this property completely
+overrides the generic property for the named configuration.
diff --git a/Help/prop_tgt/IMPORTED_LINK_INTERFACE_LIBRARIES.rst b/Help/prop_tgt/IMPORTED_LINK_INTERFACE_LIBRARIES.rst
new file mode 100644
index 000000000..61134a401
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED_LINK_INTERFACE_LIBRARIES.rst
@@ -0,0 +1,16 @@
+IMPORTED_LINK_INTERFACE_LIBRARIES
+---------------------------------
+
+Transitive link interface of an IMPORTED target.
+
+Set this to the list of libraries whose interface is included when an
+IMPORTED library target is linked to another target. The libraries
+will be included on the link line for the target. Unlike the
+LINK_INTERFACE_LIBRARIES property, this property applies to all
+imported target types, including STATIC libraries. This property is
+ignored for non-imported targets.
+
+This property is ignored if the target also has a non-empty
+INTERFACE_LINK_LIBRARIES property.
+
+This property is deprecated. Use INTERFACE_LINK_LIBRARIES instead.
diff --git a/Help/prop_tgt/IMPORTED_LINK_INTERFACE_LIBRARIES_CONFIG.rst b/Help/prop_tgt/IMPORTED_LINK_INTERFACE_LIBRARIES_CONFIG.rst
new file mode 100644
index 000000000..13b93ba98
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED_LINK_INTERFACE_LIBRARIES_CONFIG.rst
@@ -0,0 +1,13 @@
+IMPORTED_LINK_INTERFACE_LIBRARIES_<CONFIG>
+------------------------------------------
+
+<CONFIG>-specific version of IMPORTED_LINK_INTERFACE_LIBRARIES.
+
+Configuration names correspond to those provided by the project from
+which the target is imported. If set, this property completely
+overrides the generic property for the named configuration.
+
+This property is ignored if the target also has a non-empty
+INTERFACE_LINK_LIBRARIES property.
+
+This property is deprecated. Use INTERFACE_LINK_LIBRARIES instead.
diff --git a/Help/prop_tgt/IMPORTED_LINK_INTERFACE_MULTIPLICITY.rst b/Help/prop_tgt/IMPORTED_LINK_INTERFACE_MULTIPLICITY.rst
new file mode 100644
index 000000000..3a86b9985
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED_LINK_INTERFACE_MULTIPLICITY.rst
@@ -0,0 +1,6 @@
+IMPORTED_LINK_INTERFACE_MULTIPLICITY
+------------------------------------
+
+Repetition count for cycles of IMPORTED static libraries.
+
+This is LINK_INTERFACE_MULTIPLICITY for IMPORTED targets.
diff --git a/Help/prop_tgt/IMPORTED_LINK_INTERFACE_MULTIPLICITY_CONFIG.rst b/Help/prop_tgt/IMPORTED_LINK_INTERFACE_MULTIPLICITY_CONFIG.rst
new file mode 100644
index 000000000..33b9b8419
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED_LINK_INTERFACE_MULTIPLICITY_CONFIG.rst
@@ -0,0 +1,7 @@
+IMPORTED_LINK_INTERFACE_MULTIPLICITY_<CONFIG>
+---------------------------------------------
+
+<CONFIG>-specific version of IMPORTED_LINK_INTERFACE_MULTIPLICITY.
+
+If set, this property completely overrides the generic property for
+the named configuration.
diff --git a/Help/prop_tgt/IMPORTED_LOCATION.rst b/Help/prop_tgt/IMPORTED_LOCATION.rst
new file mode 100644
index 000000000..8cfef7343
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED_LOCATION.rst
@@ -0,0 +1,21 @@
+IMPORTED_LOCATION
+-----------------
+
+Full path to the main file on disk for an IMPORTED target.
+
+Set this to the location of an IMPORTED target file on disk. For
+executables this is the location of the executable file. For bundles
+on OS X this is the location of the executable file inside
+Contents/MacOS under the application bundle folder. For static
+libraries and modules this is the location of the library or module.
+For shared libraries on non-DLL platforms this is the location of the
+shared library. For frameworks on OS X this is the location of the
+library file symlink just inside the framework folder. For DLLs this
+is the location of the ".dll" part of the library. For UNKNOWN
+libraries this is the location of the file to be linked. Ignored for
+non-imported targets.
+
+Projects may skip IMPORTED_LOCATION if the configuration-specific
+property IMPORTED_LOCATION_<CONFIG> is set. To get the location of an
+imported target read one of the LOCATION or LOCATION_<CONFIG>
+properties.
diff --git a/Help/prop_tgt/IMPORTED_LOCATION_CONFIG.rst b/Help/prop_tgt/IMPORTED_LOCATION_CONFIG.rst
new file mode 100644
index 000000000..f85bb19c9
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED_LOCATION_CONFIG.rst
@@ -0,0 +1,7 @@
+IMPORTED_LOCATION_<CONFIG>
+--------------------------
+
+<CONFIG>-specific version of IMPORTED_LOCATION property.
+
+Configuration names correspond to those provided by the project from
+which the target is imported.
diff --git a/Help/prop_tgt/IMPORTED_NO_SONAME.rst b/Help/prop_tgt/IMPORTED_NO_SONAME.rst
new file mode 100644
index 000000000..4a1bb447a
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED_NO_SONAME.rst
@@ -0,0 +1,9 @@
+IMPORTED_NO_SONAME
+------------------
+
+Specifies that an IMPORTED shared library target has no "soname".
+
+Set this property to true for an imported shared library file that has
+no "soname" field. CMake may adjust generated link commands for some
+platforms to prevent the linker from using the path to the library in
+place of its missing soname. Ignored for non-imported targets.
diff --git a/Help/prop_tgt/IMPORTED_NO_SONAME_CONFIG.rst b/Help/prop_tgt/IMPORTED_NO_SONAME_CONFIG.rst
new file mode 100644
index 000000000..22d68220c
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED_NO_SONAME_CONFIG.rst
@@ -0,0 +1,7 @@
+IMPORTED_NO_SONAME_<CONFIG>
+---------------------------
+
+<CONFIG>-specific version of IMPORTED_NO_SONAME property.
+
+Configuration names correspond to those provided by the project from
+which the target is imported.
diff --git a/Help/prop_tgt/IMPORTED_SONAME.rst b/Help/prop_tgt/IMPORTED_SONAME.rst
new file mode 100644
index 000000000..d80907e3e
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED_SONAME.rst
@@ -0,0 +1,8 @@
+IMPORTED_SONAME
+---------------
+
+The "soname" of an IMPORTED target of shared library type.
+
+Set this to the "soname" embedded in an imported shared library. This
+is meaningful only on platforms supporting the feature. Ignored for
+non-imported targets.
diff --git a/Help/prop_tgt/IMPORTED_SONAME_CONFIG.rst b/Help/prop_tgt/IMPORTED_SONAME_CONFIG.rst
new file mode 100644
index 000000000..6ec9af3f8
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED_SONAME_CONFIG.rst
@@ -0,0 +1,7 @@
+IMPORTED_SONAME_<CONFIG>
+------------------------
+
+<CONFIG>-specific version of IMPORTED_SONAME property.
+
+Configuration names correspond to those provided by the project from
+which the target is imported.
diff --git a/Help/prop_tgt/IMPORT_PREFIX.rst b/Help/prop_tgt/IMPORT_PREFIX.rst
new file mode 100644
index 000000000..deede9788
--- /dev/null
+++ b/Help/prop_tgt/IMPORT_PREFIX.rst
@@ -0,0 +1,9 @@
+IMPORT_PREFIX
+-------------
+
+What comes before the import library name.
+
+Similar to the target property PREFIX, but used for import libraries
+(typically corresponding to a DLL) instead of regular libraries. A
+target property that can be set to override the prefix (such as "lib")
+on an import library name.
diff --git a/Help/prop_tgt/IMPORT_SUFFIX.rst b/Help/prop_tgt/IMPORT_SUFFIX.rst
new file mode 100644
index 000000000..bd0125037
--- /dev/null
+++ b/Help/prop_tgt/IMPORT_SUFFIX.rst
@@ -0,0 +1,9 @@
+IMPORT_SUFFIX
+-------------
+
+What comes after the import library name.
+
+Similar to the target property SUFFIX, but used for import libraries
+(typically corresponding to a DLL) instead of regular libraries. A
+target property that can be set to override the suffix (such as
+".lib") on an import library name.
diff --git a/Help/prop_tgt/INCLUDE_DIRECTORIES.rst b/Help/prop_tgt/INCLUDE_DIRECTORIES.rst
new file mode 100644
index 000000000..8b40d9c34
--- /dev/null
+++ b/Help/prop_tgt/INCLUDE_DIRECTORIES.rst
@@ -0,0 +1,24 @@
+INCLUDE_DIRECTORIES
+-------------------
+
+List of preprocessor include file search directories.
+
+This property specifies the list of directories given so far to the
+:command:`target_include_directories` command. In addition to accepting
+values from that command, values may be set directly on any
+target using the :command:`set_property` command. A target gets its
+initial value for this property from the value of the
+:prop_dir:`INCLUDE_DIRECTORIES` directory property. Both directory and
+target property values are adjusted by calls to the
+:command:`include_directories` command.
+
+The value of this property is used by the generators to set the include
+paths for the compiler.
+
+Relative paths should not be added to this property directly. Use one of
+the commands above instead to handle relative paths.
+
+Contents of ``INCLUDE_DIRECTORIES`` may use "generator expressions" with
+the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions. See the :manual:`cmake-buildsystem(7)`
+manual for more on defining buildsystem properties.
diff --git a/Help/prop_tgt/INSTALL_NAME_DIR.rst b/Help/prop_tgt/INSTALL_NAME_DIR.rst
new file mode 100644
index 000000000..a67ec1584
--- /dev/null
+++ b/Help/prop_tgt/INSTALL_NAME_DIR.rst
@@ -0,0 +1,8 @@
+INSTALL_NAME_DIR
+----------------
+
+Mac OSX directory name for installed targets.
+
+INSTALL_NAME_DIR is a string specifying the directory portion of the
+"install_name" field of shared libraries on Mac OSX to use in the
+installed targets.
diff --git a/Help/prop_tgt/INSTALL_RPATH.rst b/Help/prop_tgt/INSTALL_RPATH.rst
new file mode 100644
index 000000000..6206b6889
--- /dev/null
+++ b/Help/prop_tgt/INSTALL_RPATH.rst
@@ -0,0 +1,9 @@
+INSTALL_RPATH
+-------------
+
+The rpath to use for installed targets.
+
+A semicolon-separated list specifying the rpath to use in installed
+targets (for platforms that support it). This property is initialized
+by the value of the variable CMAKE_INSTALL_RPATH if it is set when a
+target is created.
diff --git a/Help/prop_tgt/INSTALL_RPATH_USE_LINK_PATH.rst b/Help/prop_tgt/INSTALL_RPATH_USE_LINK_PATH.rst
new file mode 100644
index 000000000..f0006f85b
--- /dev/null
+++ b/Help/prop_tgt/INSTALL_RPATH_USE_LINK_PATH.rst
@@ -0,0 +1,10 @@
+INSTALL_RPATH_USE_LINK_PATH
+---------------------------
+
+Add paths to linker search and installed rpath.
+
+INSTALL_RPATH_USE_LINK_PATH is a boolean that if set to true will
+append directories in the linker search path and outside the project
+to the INSTALL_RPATH. This property is initialized by the value of
+the variable CMAKE_INSTALL_RPATH_USE_LINK_PATH if it is set when a
+target is created.
diff --git a/Help/prop_tgt/INTERFACE_AUTOUIC_OPTIONS.rst b/Help/prop_tgt/INTERFACE_AUTOUIC_OPTIONS.rst
new file mode 100644
index 000000000..e97d29318
--- /dev/null
+++ b/Help/prop_tgt/INTERFACE_AUTOUIC_OPTIONS.rst
@@ -0,0 +1,14 @@
+INTERFACE_AUTOUIC_OPTIONS
+-------------------------
+
+List of interface options to pass to uic.
+
+Targets may populate this property to publish the options
+required to use when invoking ``uic``. Consuming targets can add entries to their
+own :prop_tgt:`AUTOUIC_OPTIONS` property such as
+``$<TARGET_PROPERTY:foo,INTERFACE_AUTOUIC_OPTIONS>`` to use the uic options
+specified in the interface of ``foo``. This is done automatically by
+the :command:`target_link_libraries` command.
+
+This property supports generator expressions. See the
+:manual:`cmake-generator-expressions(7)` manual for available expressions.
diff --git a/Help/prop_tgt/INTERFACE_BUILD_PROPERTY.txt b/Help/prop_tgt/INTERFACE_BUILD_PROPERTY.txt
new file mode 100644
index 000000000..4188b8dae
--- /dev/null
+++ b/Help/prop_tgt/INTERFACE_BUILD_PROPERTY.txt
@@ -0,0 +1,16 @@
+
+List of public |property_name| requirements for a library.
+
+Targets may populate this property to publish the |property_name|
+required to compile against the headers for the target. The |command_name|
+command populates this property with values given to the ``PUBLIC`` and
+``INTERFACE`` keywords. Projects may also get and set the property directly.
+
+When target dependencies are specified using :command:`target_link_libraries`,
+CMake will read this property from all target dependencies to determine the
+build properties of the consumer.
+
+Contents of |PROPERTY_INTERFACE_NAME| may use "generator expressions"
+with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions. See the :manual:`cmake-buildsystem(7)`
+-manual for more on defining buildsystem properties.
diff --git a/Help/prop_tgt/INTERFACE_COMPILE_DEFINITIONS.rst b/Help/prop_tgt/INTERFACE_COMPILE_DEFINITIONS.rst
new file mode 100644
index 000000000..c74a31901
--- /dev/null
+++ b/Help/prop_tgt/INTERFACE_COMPILE_DEFINITIONS.rst
@@ -0,0 +1,9 @@
+INTERFACE_COMPILE_DEFINITIONS
+-----------------------------
+
+.. |property_name| replace:: compile definitions
+.. |command_name| replace:: :command:`target_compile_definitions`
+.. |PROPERTY_INTERFACE_NAME| replace:: ``INTERFACE_COMPILE_DEFINITIONS``
+.. |PROPERTY_LINK| replace:: :prop_tgt:`COMPILE_DEFINITIONS`
+.. |PROPERTY_GENEX| replace:: ``$<TARGET_PROPERTY:foo,INTERFACE_COMPILE_DEFINITIONS>``
+.. include:: INTERFACE_BUILD_PROPERTY.txt
diff --git a/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst b/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst
new file mode 100644
index 000000000..31b594f82
--- /dev/null
+++ b/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst
@@ -0,0 +1,12 @@
+INTERFACE_COMPILE_FEATURES
+--------------------------
+
+.. |property_name| replace:: compile features
+.. |command_name| replace:: :command:`target_compile_features`
+.. |PROPERTY_INTERFACE_NAME| replace:: ``INTERFACE_COMPILE_FEATURES``
+.. |PROPERTY_LINK| replace:: :prop_tgt:`COMPILE_FEATURES`
+.. |PROPERTY_GENEX| replace:: ``$<TARGET_PROPERTY:foo,INTERFACE_COMPILE_FEATURES>``
+.. include:: INTERFACE_BUILD_PROPERTY.txt
+
+See the :manual:`cmake-compile-features(7)` manual for information on compile
+features and a list of supported compilers.
diff --git a/Help/prop_tgt/INTERFACE_COMPILE_OPTIONS.rst b/Help/prop_tgt/INTERFACE_COMPILE_OPTIONS.rst
new file mode 100644
index 000000000..7f0b38534
--- /dev/null
+++ b/Help/prop_tgt/INTERFACE_COMPILE_OPTIONS.rst
@@ -0,0 +1,9 @@
+INTERFACE_COMPILE_OPTIONS
+-------------------------
+
+.. |property_name| replace:: compile options
+.. |command_name| replace:: :command:`target_compile_options`
+.. |PROPERTY_INTERFACE_NAME| replace:: ``INTERFACE_COMPILE_OPTIONS``
+.. |PROPERTY_LINK| replace:: :prop_tgt:`COMPILE_OPTIONS`
+.. |PROPERTY_GENEX| replace:: ``$<TARGET_PROPERTY:foo,INTERFACE_COMPILE_OPTIONS>``
+.. include:: INTERFACE_BUILD_PROPERTY.txt
diff --git a/Help/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES.rst b/Help/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES.rst
new file mode 100644
index 000000000..b1c40b224
--- /dev/null
+++ b/Help/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES.rst
@@ -0,0 +1,29 @@
+INTERFACE_INCLUDE_DIRECTORIES
+-----------------------------
+
+.. |property_name| replace:: include directories
+.. |command_name| replace:: :command:`target_include_directories`
+.. |PROPERTY_INTERFACE_NAME| replace:: ``INTERFACE_INCLUDE_DIRECTORIES``
+.. |PROPERTY_LINK| replace:: :prop_tgt:`INCLUDE_DIRECTORIES`
+.. |PROPERTY_GENEX| replace:: ``$<TARGET_PROPERTY:foo,INTERFACE_INCLUDE_DIRECTORIES>``
+.. include:: INTERFACE_BUILD_PROPERTY.txt
+
+Include directories usage requirements commonly differ between the build-tree
+and the install-tree. The ``BUILD_INTERFACE`` and ``INSTALL_INTERFACE``
+generator expressions can be used to describe separate usage requirements
+based on the usage location. Relative paths are allowed within the
+``INSTALL_INTERFACE`` expression and are interpreted relative to the
+installation prefix. For example:
+
+.. code-block:: cmake
+
+ target_include_directories(mylib INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/mylib>
+ $<INSTALL_INTERFACE:include/mylib> # <prefix>/include/mylib
+ )
+
+Creating Relocatable Packages
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. |INTERFACE_PROPERTY_LINK| replace:: ``INTERFACE_INCLUDE_DIRECTORIES``
+.. include:: /include/INTERFACE_INCLUDE_DIRECTORIES_WARNING.txt
diff --git a/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst b/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst
new file mode 100644
index 000000000..832d12bbc
--- /dev/null
+++ b/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst
@@ -0,0 +1,24 @@
+INTERFACE_LINK_LIBRARIES
+------------------------
+
+List public interface libraries for a library.
+
+This property contains the list of transitive link dependencies. When
+the target is linked into another target using the
+:command:`target_link_libraries` command, the libraries listed (and
+recursively their link interface libraries) will be provided to the
+other target also. This property is overridden by the
+:prop_tgt:`LINK_INTERFACE_LIBRARIES` or
+:prop_tgt:`LINK_INTERFACE_LIBRARIES_<CONFIG>` property if policy
+:policy:`CMP0022` is ``OLD`` or unset.
+
+Contents of ``INTERFACE_LINK_LIBRARIES`` may use "generator expressions"
+with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions. See the :manual:`cmake-buildsystem(7)`
+manual for more on defining buildsystem properties.
+
+Creating Relocatable Packages
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. |INTERFACE_PROPERTY_LINK| replace:: ``INTERFACE_LINK_LIBRARIES``
+.. include:: /include/INTERFACE_LINK_LIBRARIES_WARNING.txt
diff --git a/Help/prop_tgt/INTERFACE_POSITION_INDEPENDENT_CODE.rst b/Help/prop_tgt/INTERFACE_POSITION_INDEPENDENT_CODE.rst
new file mode 100644
index 000000000..ea700dfe9
--- /dev/null
+++ b/Help/prop_tgt/INTERFACE_POSITION_INDEPENDENT_CODE.rst
@@ -0,0 +1,16 @@
+INTERFACE_POSITION_INDEPENDENT_CODE
+-----------------------------------
+
+Whether consumers need to create a position-independent target
+
+The ``INTERFACE_POSITION_INDEPENDENT_CODE`` property informs consumers of
+this target whether they must set their
+:prop_tgt:`POSITION_INDEPENDENT_CODE` property to ``ON``. If this
+property is set to ``ON``, then the :prop_tgt:`POSITION_INDEPENDENT_CODE`
+property on all consumers will be set to ``ON``. Similarly, if this
+property is set to ``OFF``, then the :prop_tgt:`POSITION_INDEPENDENT_CODE`
+property on all consumers will be set to ``OFF``. If this property is
+undefined, then consumers will determine their
+:prop_tgt:`POSITION_INDEPENDENT_CODE` property by other means. Consumers
+must ensure that the targets that they link to have a consistent
+requirement for their ``INTERFACE_POSITION_INDEPENDENT_CODE`` property.
diff --git a/Help/prop_tgt/INTERFACE_SOURCES.rst b/Help/prop_tgt/INTERFACE_SOURCES.rst
new file mode 100644
index 000000000..a224b6859
--- /dev/null
+++ b/Help/prop_tgt/INTERFACE_SOURCES.rst
@@ -0,0 +1,18 @@
+INTERFACE_SOURCES
+-----------------
+
+List of interface sources to compile into consuming targets.
+
+Targets may populate this property to publish the sources
+for consuming targets to compile. The :command:`target_sources` command
+populates this property with values given to the ``PUBLIC`` and
+``INTERFACE`` keywords. Projects may also get and set the property directly.
+
+When target dependencies are specified using :command:`target_link_libraries`,
+CMake will read this property from all target dependencies to determine the
+sources of the consumer.
+
+Contents of ``INTERFACE_SOURCES`` may use "generator expressions"
+with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions. See the :manual:`cmake-buildsystem(7)`
+manual for more on defining buildsystem properties.
diff --git a/Help/prop_tgt/INTERFACE_SYSTEM_INCLUDE_DIRECTORIES.rst b/Help/prop_tgt/INTERFACE_SYSTEM_INCLUDE_DIRECTORIES.rst
new file mode 100644
index 000000000..a0a97ada7
--- /dev/null
+++ b/Help/prop_tgt/INTERFACE_SYSTEM_INCLUDE_DIRECTORIES.rst
@@ -0,0 +1,28 @@
+INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
+------------------------------------
+
+List of public system include directories for a library.
+
+Targets may populate this property to publish the include directories
+which contain system headers, and therefore should not result in
+compiler warnings. The :command:`target_include_directories(SYSTEM)`
+command signature populates this property with values given to the
+``PUBLIC`` and ``INTERFACE`` keywords.
+
+Projects may also get and set the property directly, but must be aware that
+adding directories to this property does not make those directories used
+during compilation. Adding directories to this property marks directories
+as ``SYSTEM`` which otherwise would be used in a non-``SYSTEM`` manner. This
+can appear similar to 'duplication', so prefer the
+high-level :command:`target_include_directories(SYSTEM)` command and avoid
+setting the property by low-level means.
+
+When target dependencies are specified using :command:`target_link_libraries`,
+CMake will read this property from all target dependencies to mark the
+same include directories as containing system headers.
+
+Contents of ``INTERFACE_SYSTEM_INCLUDE_DIRECTORIES`` may use "generator
+expressions" with the syntax ``$<...>``. See the
+:manual:`cmake-generator-expressions(7)` manual for available expressions.
+See the :manual:`cmake-buildsystem(7)` manual for more on defining
+buildsystem properties.
diff --git a/Help/prop_tgt/INTERPROCEDURAL_OPTIMIZATION.rst b/Help/prop_tgt/INTERPROCEDURAL_OPTIMIZATION.rst
new file mode 100644
index 000000000..effa3b01f
--- /dev/null
+++ b/Help/prop_tgt/INTERPROCEDURAL_OPTIMIZATION.rst
@@ -0,0 +1,7 @@
+INTERPROCEDURAL_OPTIMIZATION
+----------------------------
+
+Enable interprocedural optimization for a target.
+
+If set to true, enables interprocedural optimizations if they are
+known to be supported by the compiler.
diff --git a/Help/prop_tgt/INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst b/Help/prop_tgt/INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst
new file mode 100644
index 000000000..492fee078
--- /dev/null
+++ b/Help/prop_tgt/INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst
@@ -0,0 +1,8 @@
+INTERPROCEDURAL_OPTIMIZATION_<CONFIG>
+-------------------------------------
+
+Per-configuration interprocedural optimization for a target.
+
+This is a per-configuration version of INTERPROCEDURAL_OPTIMIZATION.
+If set, this property overrides the generic property for the named
+configuration.
diff --git a/Help/prop_tgt/IOS_INSTALL_COMBINED.rst b/Help/prop_tgt/IOS_INSTALL_COMBINED.rst
new file mode 100644
index 000000000..59f67a7eb
--- /dev/null
+++ b/Help/prop_tgt/IOS_INSTALL_COMBINED.rst
@@ -0,0 +1,11 @@
+IOS_INSTALL_COMBINED
+--------------------
+
+Build a combined (device and simulator) target when installing.
+
+When this property is set to set to false (which is the default) then it will
+either be built with the device SDK or the simulator SDK depending on the SDK
+set. But if this property is set to true then the target will at install time
+also be built for the corresponding SDK and combined into one library.
+
+This feature requires at least Xcode version 6.
diff --git a/Help/prop_tgt/JOB_POOL_COMPILE.rst b/Help/prop_tgt/JOB_POOL_COMPILE.rst
new file mode 100644
index 000000000..5d8e94038
--- /dev/null
+++ b/Help/prop_tgt/JOB_POOL_COMPILE.rst
@@ -0,0 +1,17 @@
+JOB_POOL_COMPILE
+----------------
+
+Ninja only: Pool used for compiling.
+
+The number of parallel compile processes could be limited by defining
+pools with the global :prop_gbl:`JOB_POOLS`
+property and then specifying here the pool name.
+
+For instance:
+
+.. code-block:: cmake
+
+ set_property(TARGET myexe PROPERTY JOB_POOL_COMPILE ten_jobs)
+
+This property is initialized by the value of
+:variable:`CMAKE_JOB_POOL_COMPILE`.
diff --git a/Help/prop_tgt/JOB_POOL_LINK.rst b/Help/prop_tgt/JOB_POOL_LINK.rst
new file mode 100644
index 000000000..716f53f71
--- /dev/null
+++ b/Help/prop_tgt/JOB_POOL_LINK.rst
@@ -0,0 +1,16 @@
+JOB_POOL_LINK
+-------------
+
+Ninja only: Pool used for linking.
+
+The number of parallel link processes could be limited by defining
+pools with the global :prop_gbl:`JOB_POOLS`
+property and then specifing here the pool name.
+
+For instance:
+
+.. code-block:: cmake
+
+ set_property(TARGET myexe PROPERTY JOB_POOL_LINK two_jobs)
+
+This property is initialized by the value of :variable:`CMAKE_JOB_POOL_LINK`.
diff --git a/Help/prop_tgt/LABELS.rst b/Help/prop_tgt/LABELS.rst
new file mode 100644
index 000000000..5e464696d
--- /dev/null
+++ b/Help/prop_tgt/LABELS.rst
@@ -0,0 +1,6 @@
+LABELS
+------
+
+Specify a list of text labels associated with a target.
+
+Target label semantics are currently unspecified.
diff --git a/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst b/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst
new file mode 100644
index 000000000..0fe0b31e5
--- /dev/null
+++ b/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst
@@ -0,0 +1,13 @@
+<LANG>_COMPILER_LAUNCHER
+------------------------
+
+This property is implemented only when ``<LANG>`` is ``C`` or ``CXX``.
+
+Specify a :ref:`;-list <CMake Language Lists>` containing a command line
+for a compiler launching tool. The :ref:`Makefile Generators` and the
+:generator:`Ninja` generator will run this tool and pass the compiler and
+its arguments to the tool. Some example tools are distcc and ccache.
+
+This property is initialized by the value of
+the :variable:`CMAKE_<LANG>_COMPILER_LAUNCHER` variable if it is set
+when a target is created.
diff --git a/Help/prop_tgt/LANG_INCLUDE_WHAT_YOU_USE.rst b/Help/prop_tgt/LANG_INCLUDE_WHAT_YOU_USE.rst
new file mode 100644
index 000000000..26f6d1671
--- /dev/null
+++ b/Help/prop_tgt/LANG_INCLUDE_WHAT_YOU_USE.rst
@@ -0,0 +1,13 @@
+<LANG>_INCLUDE_WHAT_YOU_USE
+---------------------------
+
+This property is implemented only when ``<LANG>`` is ``C`` or ``CXX``.
+
+Specify a :ref:`;-list <CMake Language Lists>` containing a command
+line for the ``include-what-you-use`` tool. The :ref:`Makefile Generators`
+and the :generator:`Ninja` generator will run this tool along with the
+compiler and report a warning if the tool reports any problems.
+
+This property is initialized by the value of
+the :variable:`CMAKE_<LANG>_INCLUDE_WHAT_YOU_USE` variable if it is set
+when a target is created.
diff --git a/Help/prop_tgt/LANG_VISIBILITY_PRESET.rst b/Help/prop_tgt/LANG_VISIBILITY_PRESET.rst
new file mode 100644
index 000000000..5d34e207e
--- /dev/null
+++ b/Help/prop_tgt/LANG_VISIBILITY_PRESET.rst
@@ -0,0 +1,13 @@
+<LANG>_VISIBILITY_PRESET
+------------------------
+
+Value for symbol visibility compile flags
+
+The ``<LANG>_VISIBILITY_PRESET`` property determines the value passed in a
+visibility related compile option, such as ``-fvisibility=`` for ``<LANG>``.
+This property affects compilation in sources of all types of targets
+(subject to policy :policy:`CMP0063`).
+
+This property is initialized by the value of the
+:variable:`CMAKE_<LANG>_VISIBILITY_PRESET` variable if it is set when a
+target is created.
diff --git a/Help/prop_tgt/LIBRARY_OUTPUT_DIRECTORY.rst b/Help/prop_tgt/LIBRARY_OUTPUT_DIRECTORY.rst
new file mode 100644
index 000000000..785a57bbf
--- /dev/null
+++ b/Help/prop_tgt/LIBRARY_OUTPUT_DIRECTORY.rst
@@ -0,0 +1,9 @@
+LIBRARY_OUTPUT_DIRECTORY
+------------------------
+
+.. |XXX| replace:: :ref:`LIBRARY <Library Output Artifacts>`
+.. |xxx| replace:: library
+.. |CMAKE_XXX_OUTPUT_DIRECTORY| replace:: CMAKE_LIBRARY_OUTPUT_DIRECTORY
+.. include:: XXX_OUTPUT_DIRECTORY.txt
+
+See also the :prop_tgt:`LIBRARY_OUTPUT_DIRECTORY_<CONFIG>` target property.
diff --git a/Help/prop_tgt/LIBRARY_OUTPUT_DIRECTORY_CONFIG.rst b/Help/prop_tgt/LIBRARY_OUTPUT_DIRECTORY_CONFIG.rst
new file mode 100644
index 000000000..28dd404df
--- /dev/null
+++ b/Help/prop_tgt/LIBRARY_OUTPUT_DIRECTORY_CONFIG.rst
@@ -0,0 +1,16 @@
+LIBRARY_OUTPUT_DIRECTORY_<CONFIG>
+---------------------------------
+
+Per-configuration output directory for
+:ref:`LIBRARY <Library Output Artifacts>` target files.
+
+This is a per-configuration version of the
+:prop_tgt:`LIBRARY_OUTPUT_DIRECTORY` target property, but
+multi-configuration generators (VS, Xcode) do NOT append a
+per-configuration subdirectory to the specified directory. This
+property is initialized by the value of the
+:variable:`CMAKE_LIBRARY_OUTPUT_DIRECTORY_<CONFIG>` variable if
+it is set when a target is created.
+
+Contents of ``LIBRARY_OUTPUT_DIRECTORY_<CONFIG>`` may use
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Help/prop_tgt/LIBRARY_OUTPUT_NAME.rst b/Help/prop_tgt/LIBRARY_OUTPUT_NAME.rst
new file mode 100644
index 000000000..6027f7f73
--- /dev/null
+++ b/Help/prop_tgt/LIBRARY_OUTPUT_NAME.rst
@@ -0,0 +1,8 @@
+LIBRARY_OUTPUT_NAME
+-------------------
+
+.. |XXX| replace:: :ref:`LIBRARY <Library Output Artifacts>`
+.. |xxx| replace:: library
+.. include:: XXX_OUTPUT_NAME.txt
+
+See also the :prop_tgt:`LIBRARY_OUTPUT_NAME_<CONFIG>` target property.
diff --git a/Help/prop_tgt/LIBRARY_OUTPUT_NAME_CONFIG.rst b/Help/prop_tgt/LIBRARY_OUTPUT_NAME_CONFIG.rst
new file mode 100644
index 000000000..1994c7b16
--- /dev/null
+++ b/Help/prop_tgt/LIBRARY_OUTPUT_NAME_CONFIG.rst
@@ -0,0 +1,8 @@
+LIBRARY_OUTPUT_NAME_<CONFIG>
+----------------------------
+
+Per-configuration output name for
+:ref:`LIBRARY <Library Output Artifacts>` target files.
+
+This is the configuration-specific version of the
+:prop_tgt:`LIBRARY_OUTPUT_NAME` target property.
diff --git a/Help/prop_tgt/LINKER_LANGUAGE.rst b/Help/prop_tgt/LINKER_LANGUAGE.rst
new file mode 100644
index 000000000..b1ca86710
--- /dev/null
+++ b/Help/prop_tgt/LINKER_LANGUAGE.rst
@@ -0,0 +1,14 @@
+LINKER_LANGUAGE
+---------------
+
+Specifies language whose compiler will invoke the linker.
+
+For executables, shared libraries, and modules, this sets the language
+whose compiler is used to link the target (such as "C" or "CXX"). A
+typical value for an executable is the language of the source file
+providing the program entry point (main). If not set, the language
+with the highest linker preference value is the default. See
+documentation of CMAKE_<LANG>_LINKER_PREFERENCE variables.
+
+If this property is not set by the user, it will be calculated at
+generate-time by CMake.
diff --git a/Help/prop_tgt/LINK_DEPENDS.rst b/Help/prop_tgt/LINK_DEPENDS.rst
new file mode 100644
index 000000000..5576b85fa
--- /dev/null
+++ b/Help/prop_tgt/LINK_DEPENDS.rst
@@ -0,0 +1,12 @@
+LINK_DEPENDS
+------------
+
+Additional files on which a target binary depends for linking.
+
+Specifies a semicolon-separated list of full-paths to files on which
+the link rule for this target depends. The target binary will be
+linked if any of the named files is newer than it.
+
+This property is ignored by non-Makefile generators. It is intended
+to specify dependencies on "linker scripts" for custom Makefile link
+rules.
diff --git a/Help/prop_tgt/LINK_DEPENDS_NO_SHARED.rst b/Help/prop_tgt/LINK_DEPENDS_NO_SHARED.rst
new file mode 100644
index 000000000..5c6778d24
--- /dev/null
+++ b/Help/prop_tgt/LINK_DEPENDS_NO_SHARED.rst
@@ -0,0 +1,14 @@
+LINK_DEPENDS_NO_SHARED
+----------------------
+
+Do not depend on linked shared library files.
+
+Set this property to true to tell CMake generators not to add
+file-level dependencies on the shared library files linked by this
+target. Modification to the shared libraries will not be sufficient
+to re-link this target. Logical target-level dependencies will not be
+affected so the linked shared libraries will still be brought up to
+date before this target is built.
+
+This property is initialized by the value of the variable
+CMAKE_LINK_DEPENDS_NO_SHARED if it is set when a target is created.
diff --git a/Help/prop_tgt/LINK_FLAGS.rst b/Help/prop_tgt/LINK_FLAGS.rst
new file mode 100644
index 000000000..409d00a29
--- /dev/null
+++ b/Help/prop_tgt/LINK_FLAGS.rst
@@ -0,0 +1,8 @@
+LINK_FLAGS
+----------
+
+Additional flags to use when linking this target.
+
+The LINK_FLAGS property can be used to add extra flags to the link
+step of a target. LINK_FLAGS_<CONFIG> will add to the configuration
+<CONFIG>, for example, DEBUG, RELEASE, MINSIZEREL, RELWITHDEBINFO.
diff --git a/Help/prop_tgt/LINK_FLAGS_CONFIG.rst b/Help/prop_tgt/LINK_FLAGS_CONFIG.rst
new file mode 100644
index 000000000..ba7adc84f
--- /dev/null
+++ b/Help/prop_tgt/LINK_FLAGS_CONFIG.rst
@@ -0,0 +1,6 @@
+LINK_FLAGS_<CONFIG>
+-------------------
+
+Per-configuration linker flags for a target.
+
+This is the configuration-specific version of LINK_FLAGS.
diff --git a/Help/prop_tgt/LINK_INTERFACE_LIBRARIES.rst b/Help/prop_tgt/LINK_INTERFACE_LIBRARIES.rst
new file mode 100644
index 000000000..2dcf45cbd
--- /dev/null
+++ b/Help/prop_tgt/LINK_INTERFACE_LIBRARIES.rst
@@ -0,0 +1,31 @@
+LINK_INTERFACE_LIBRARIES
+------------------------
+
+List public interface libraries for a shared library or executable.
+
+By default linking to a shared library target transitively links to
+targets with which the library itself was linked. For an executable
+with exports (see the :prop_tgt:`ENABLE_EXPORTS` target property) no
+default transitive link dependencies are used. This property replaces the default
+transitive link dependencies with an explicit list. When the target
+is linked into another target using the :command:`target_link_libraries`
+command, the libraries listed (and recursively
+their link interface libraries) will be provided to the other target
+also. If the list is empty then no transitive link dependencies will
+be incorporated when this target is linked into another target even if
+the default set is non-empty. This property is initialized by the
+value of the :variable:`CMAKE_LINK_INTERFACE_LIBRARIES` variable if it is
+set when a target is created. This property is ignored for ``STATIC``
+libraries.
+
+This property is overridden by the :prop_tgt:`INTERFACE_LINK_LIBRARIES`
+property if policy :policy:`CMP0022` is ``NEW``.
+
+This property is deprecated. Use :prop_tgt:`INTERFACE_LINK_LIBRARIES`
+instead.
+
+Creating Relocatable Packages
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. |INTERFACE_PROPERTY_LINK| replace:: ``LINK_INTERFACE_LIBRARIES``
+.. include:: /include/INTERFACE_LINK_LIBRARIES_WARNING.txt
diff --git a/Help/prop_tgt/LINK_INTERFACE_LIBRARIES_CONFIG.rst b/Help/prop_tgt/LINK_INTERFACE_LIBRARIES_CONFIG.rst
new file mode 100644
index 000000000..22ee5a68b
--- /dev/null
+++ b/Help/prop_tgt/LINK_INTERFACE_LIBRARIES_CONFIG.rst
@@ -0,0 +1,20 @@
+LINK_INTERFACE_LIBRARIES_<CONFIG>
+---------------------------------
+
+Per-configuration list of public interface libraries for a target.
+
+This is the configuration-specific version of
+:prop_tgt:`LINK_INTERFACE_LIBRARIES`. If set, this property completely
+overrides the generic property for the named configuration.
+
+This property is overridden by the :prop_tgt:`INTERFACE_LINK_LIBRARIES`
+property if policy :policy:`CMP0022` is ``NEW``.
+
+This property is deprecated. Use :prop_tgt:`INTERFACE_LINK_LIBRARIES`
+instead.
+
+Creating Relocatable Packages
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. |INTERFACE_PROPERTY_LINK| replace:: ``LINK_INTERFACE_LIBRARIES_<CONFIG>``
+.. include:: /include/INTERFACE_LINK_LIBRARIES_WARNING.txt
diff --git a/Help/prop_tgt/LINK_INTERFACE_MULTIPLICITY.rst b/Help/prop_tgt/LINK_INTERFACE_MULTIPLICITY.rst
new file mode 100644
index 000000000..4e26388a9
--- /dev/null
+++ b/Help/prop_tgt/LINK_INTERFACE_MULTIPLICITY.rst
@@ -0,0 +1,12 @@
+LINK_INTERFACE_MULTIPLICITY
+---------------------------
+
+Repetition count for STATIC libraries with cyclic dependencies.
+
+When linking to a STATIC library target with cyclic dependencies the
+linker may need to scan more than once through the archives in the
+strongly connected component of the dependency graph. CMake by
+default constructs the link line so that the linker will scan through
+the component at least twice. This property specifies the minimum
+number of scans if it is larger than the default. CMake uses the
+largest value specified by any target in a component.
diff --git a/Help/prop_tgt/LINK_INTERFACE_MULTIPLICITY_CONFIG.rst b/Help/prop_tgt/LINK_INTERFACE_MULTIPLICITY_CONFIG.rst
new file mode 100644
index 000000000..5ea4a45cf
--- /dev/null
+++ b/Help/prop_tgt/LINK_INTERFACE_MULTIPLICITY_CONFIG.rst
@@ -0,0 +1,8 @@
+LINK_INTERFACE_MULTIPLICITY_<CONFIG>
+------------------------------------
+
+Per-configuration repetition count for cycles of STATIC libraries.
+
+This is the configuration-specific version of
+LINK_INTERFACE_MULTIPLICITY. If set, this property completely
+overrides the generic property for the named configuration.
diff --git a/Help/prop_tgt/LINK_LIBRARIES.rst b/Help/prop_tgt/LINK_LIBRARIES.rst
new file mode 100644
index 000000000..aa4b9f55f
--- /dev/null
+++ b/Help/prop_tgt/LINK_LIBRARIES.rst
@@ -0,0 +1,17 @@
+LINK_LIBRARIES
+--------------
+
+List of direct link dependencies.
+
+This property specifies the list of libraries or targets which will be
+used for linking. In addition to accepting values from the
+:command:`target_link_libraries` command, values may be set directly on
+any target using the :command:`set_property` command.
+
+The value of this property is used by the generators to set the link
+libraries for the compiler.
+
+Contents of ``LINK_LIBRARIES`` may use "generator expressions" with the
+syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual
+for available expressions. See the :manual:`cmake-buildsystem(7)` manual
+for more on defining buildsystem properties.
diff --git a/Help/prop_tgt/LINK_SEARCH_END_STATIC.rst b/Help/prop_tgt/LINK_SEARCH_END_STATIC.rst
new file mode 100644
index 000000000..cf9c87147
--- /dev/null
+++ b/Help/prop_tgt/LINK_SEARCH_END_STATIC.rst
@@ -0,0 +1,18 @@
+LINK_SEARCH_END_STATIC
+----------------------
+
+End a link line such that static system libraries are used.
+
+Some linkers support switches such as -Bstatic and -Bdynamic to
+determine whether to use static or shared libraries for -lXXX options.
+CMake uses these options to set the link type for libraries whose full
+paths are not known or (in some cases) are in implicit link
+directories for the platform. By default CMake adds an option at the
+end of the library list (if necessary) to set the linker search type
+back to its starting type. This property switches the final linker
+search type to -Bstatic regardless of how it started.
+
+This property is initialized by the value of the variable
+CMAKE_LINK_SEARCH_END_STATIC if it is set when a target is created.
+
+See also LINK_SEARCH_START_STATIC.
diff --git a/Help/prop_tgt/LINK_SEARCH_START_STATIC.rst b/Help/prop_tgt/LINK_SEARCH_START_STATIC.rst
new file mode 100644
index 000000000..2e0f9bd33
--- /dev/null
+++ b/Help/prop_tgt/LINK_SEARCH_START_STATIC.rst
@@ -0,0 +1,19 @@
+LINK_SEARCH_START_STATIC
+------------------------
+
+Assume the linker looks for static libraries by default.
+
+Some linkers support switches such as -Bstatic and -Bdynamic to
+determine whether to use static or shared libraries for -lXXX options.
+CMake uses these options to set the link type for libraries whose full
+paths are not known or (in some cases) are in implicit link
+directories for the platform. By default the linker search type is
+assumed to be -Bdynamic at the beginning of the library list. This
+property switches the assumption to -Bstatic. It is intended for use
+when linking an executable statically (e.g. with the GNU -static
+option).
+
+This property is initialized by the value of the variable
+CMAKE_LINK_SEARCH_START_STATIC if it is set when a target is created.
+
+See also LINK_SEARCH_END_STATIC.
diff --git a/Help/prop_tgt/LOCATION.rst b/Help/prop_tgt/LOCATION.rst
new file mode 100644
index 000000000..16d5696e5
--- /dev/null
+++ b/Help/prop_tgt/LOCATION.rst
@@ -0,0 +1,27 @@
+LOCATION
+--------
+
+Read-only location of a target on disk.
+
+For an imported target, this read-only property returns the value of
+the LOCATION_<CONFIG> property for an unspecified configuration
+<CONFIG> provided by the target.
+
+For a non-imported target, this property is provided for compatibility
+with CMake 2.4 and below. It was meant to get the location of an
+executable target's output file for use in add_custom_command. The
+path may contain a build-system-specific portion that is replaced at
+build time with the configuration getting built (such as
+"$(ConfigurationName)" in VS). In CMake 2.6 and above
+add_custom_command automatically recognizes a target name in its
+COMMAND and DEPENDS options and computes the target location. In
+CMake 2.8.4 and above add_custom_command recognizes generator
+expressions to refer to target locations anywhere in the command.
+Therefore this property is not needed for creating custom commands.
+
+Do not set properties that affect the location of a target after
+reading this property. These include properties whose names match
+"(RUNTIME|LIBRARY|ARCHIVE)_OUTPUT_(NAME|DIRECTORY)(_<CONFIG>)?",
+``(IMPLIB_)?(PREFIX|SUFFIX)``, or "LINKER_LANGUAGE". Failure to follow
+this rule is not diagnosed and leaves the location of the target
+undefined.
diff --git a/Help/prop_tgt/LOCATION_CONFIG.rst b/Help/prop_tgt/LOCATION_CONFIG.rst
new file mode 100644
index 000000000..ac6bdb786
--- /dev/null
+++ b/Help/prop_tgt/LOCATION_CONFIG.rst
@@ -0,0 +1,20 @@
+LOCATION_<CONFIG>
+-----------------
+
+Read-only property providing a target location on disk.
+
+A read-only property that indicates where a target's main file is
+located on disk for the configuration <CONFIG>. The property is
+defined only for library and executable targets. An imported target
+may provide a set of configurations different from that of the
+importing project. By default CMake looks for an exact-match but
+otherwise uses an arbitrary available configuration. Use the
+MAP_IMPORTED_CONFIG_<CONFIG> property to map imported configurations
+explicitly.
+
+Do not set properties that affect the location of a target after
+reading this property. These include properties whose names match
+"(RUNTIME|LIBRARY|ARCHIVE)_OUTPUT_(NAME|DIRECTORY)(_<CONFIG>)?",
+``(IMPLIB_)?(PREFIX|SUFFIX)``, or "LINKER_LANGUAGE". Failure to follow
+this rule is not diagnosed and leaves the location of the target
+undefined.
diff --git a/Help/prop_tgt/MACOSX_BUNDLE.rst b/Help/prop_tgt/MACOSX_BUNDLE.rst
new file mode 100644
index 000000000..7cd80462a
--- /dev/null
+++ b/Help/prop_tgt/MACOSX_BUNDLE.rst
@@ -0,0 +1,12 @@
+MACOSX_BUNDLE
+-------------
+
+Build an executable as an Application Bundle on OS X or iOS.
+
+When this property is set to ``TRUE`` the executable when built on OS X
+or iOS will be created as an application bundle. This makes it
+a GUI executable that can be launched from the Finder. See the
+:prop_tgt:`MACOSX_FRAMEWORK_INFO_PLIST` target property for information about
+creation of the ``Info.plist`` file for the application bundle.
+This property is initialized by the value of the variable
+:variable:`CMAKE_MACOSX_BUNDLE` if it is set when a target is created.
diff --git a/Help/prop_tgt/MACOSX_BUNDLE_INFO_PLIST.rst b/Help/prop_tgt/MACOSX_BUNDLE_INFO_PLIST.rst
new file mode 100644
index 000000000..8515accc2
--- /dev/null
+++ b/Help/prop_tgt/MACOSX_BUNDLE_INFO_PLIST.rst
@@ -0,0 +1,35 @@
+MACOSX_BUNDLE_INFO_PLIST
+------------------------
+
+Specify a custom ``Info.plist`` template for a OS X and iOS Application Bundle.
+
+An executable target with :prop_tgt:`MACOSX_BUNDLE` enabled will be built as an
+application bundle on OS X. By default its ``Info.plist`` file is created
+by configuring a template called ``MacOSXBundleInfo.plist.in`` located in the
+:variable:`CMAKE_MODULE_PATH`. This property specifies an alternative template
+file name which may be a full path.
+
+The following target properties may be set to specify content to be
+configured into the file:
+
+``MACOSX_BUNDLE_BUNDLE_NAME``
+ Sets ``CFBundleName``.
+``MACOSX_BUNDLE_BUNDLE_VERSION``
+ Sets ``CFBundleVersion``.
+``MACOSX_BUNDLE_COPYRIGHT``
+ Sets ``NSHumanReadableCopyright``.
+``MACOSX_BUNDLE_GUI_IDENTIFIER``
+ Sets ``CFBundleIdentifier``.
+``MACOSX_BUNDLE_ICON_FILE``
+ Sets ``CFBundleIconFile``.
+``MACOSX_BUNDLE_INFO_STRING``
+ Sets ``CFBundleGetInfoString``.
+``MACOSX_BUNDLE_LONG_VERSION_STRING``
+ Sets ``CFBundleLongVersionString``.
+``MACOSX_BUNDLE_SHORT_VERSION_STRING``
+ Sets ``CFBundleShortVersionString``.
+
+CMake variables of the same name may be set to affect all targets in a
+directory that do not have each specific property set. If a custom
+``Info.plist`` is specified by this property it may of course hard-code
+all the settings instead of using the target properties.
diff --git a/Help/prop_tgt/MACOSX_FRAMEWORK_INFO_PLIST.rst b/Help/prop_tgt/MACOSX_FRAMEWORK_INFO_PLIST.rst
new file mode 100644
index 000000000..58f31d495
--- /dev/null
+++ b/Help/prop_tgt/MACOSX_FRAMEWORK_INFO_PLIST.rst
@@ -0,0 +1,27 @@
+MACOSX_FRAMEWORK_INFO_PLIST
+---------------------------
+
+Specify a custom ``Info.plist`` template for a OS X and iOS Framework.
+
+A library target with :prop_tgt:`FRAMEWORK` enabled will be built as a
+framework on OS X. By default its ``Info.plist`` file is created by
+configuring a template called ``MacOSXFrameworkInfo.plist.in`` located in the
+:variable:`CMAKE_MODULE_PATH`. This property specifies an alternative template
+file name which may be a full path.
+
+The following target properties may be set to specify content to be
+configured into the file:
+
+``MACOSX_FRAMEWORK_BUNDLE_VERSION``
+ Sets ``CFBundleVersion``.
+``MACOSX_FRAMEWORK_ICON_FILE``
+ Sets ``CFBundleIconFile``.
+``MACOSX_FRAMEWORK_IDENTIFIER``
+ Sets ``CFBundleIdentifier``.
+``MACOSX_FRAMEWORK_SHORT_VERSION_STRING``
+ Sets ``CFBundleShortVersionString``.
+
+CMake variables of the same name may be set to affect all targets in a
+directory that do not have each specific property set. If a custom
+``Info.plist`` is specified by this property it may of course hard-code
+all the settings instead of using the target properties.
diff --git a/Help/prop_tgt/MACOSX_RPATH.rst b/Help/prop_tgt/MACOSX_RPATH.rst
new file mode 100644
index 000000000..1f9a036bf
--- /dev/null
+++ b/Help/prop_tgt/MACOSX_RPATH.rst
@@ -0,0 +1,23 @@
+MACOSX_RPATH
+------------
+
+Whether this target on OS X or iOS is located at runtime using rpaths.
+
+When this property is set to ``TRUE``, the directory portion of
+the ``install_name`` field of this shared library will be ``@rpath``
+unless overridden by :prop_tgt:`INSTALL_NAME_DIR`. This indicates
+the shared library is to be found at runtime using runtime
+paths (rpaths).
+
+This property is initialized by the value of the variable
+:variable:`CMAKE_MACOSX_RPATH` if it is set when a target is
+created.
+
+Runtime paths will also be embedded in binaries using this target and
+can be controlled by the :prop_tgt:`INSTALL_RPATH` target property on
+the target linking to this target.
+
+Policy :policy:`CMP0042` was introduced to change the default value of
+``MACOSX_RPATH`` to ``TRUE``. This is because use of ``@rpath`` is a
+more flexible and powerful alternative to ``@executable_path`` and
+``@loader_path``.
diff --git a/Help/prop_tgt/MAP_IMPORTED_CONFIG_CONFIG.rst b/Help/prop_tgt/MAP_IMPORTED_CONFIG_CONFIG.rst
new file mode 100644
index 000000000..09ff0cee6
--- /dev/null
+++ b/Help/prop_tgt/MAP_IMPORTED_CONFIG_CONFIG.rst
@@ -0,0 +1,19 @@
+MAP_IMPORTED_CONFIG_<CONFIG>
+----------------------------
+
+Map from project configuration to IMPORTED target's configuration.
+
+Set this to the list of configurations of an imported target that may
+be used for the current project's <CONFIG> configuration. Targets
+imported from another project may not provide the same set of
+configuration names available in the current project. Setting this
+property tells CMake what imported configurations are suitable for use
+when building the <CONFIG> configuration. The first configuration in
+the list found to be provided by the imported target is selected. If
+this property is set and no matching configurations are available,
+then the imported target is considered to be not found. This property
+is ignored for non-imported targets.
+
+This property is initialized by the value of the variable
+CMAKE_MAP_IMPORTED_CONFIG_<CONFIG> if it is set when a target is
+created.
diff --git a/Help/prop_tgt/NAME.rst b/Help/prop_tgt/NAME.rst
new file mode 100644
index 000000000..ddd84f23c
--- /dev/null
+++ b/Help/prop_tgt/NAME.rst
@@ -0,0 +1,6 @@
+NAME
+----
+
+Logical name for the target.
+
+Read-only logical name for the target as used by CMake.
diff --git a/Help/prop_tgt/NO_SONAME.rst b/Help/prop_tgt/NO_SONAME.rst
new file mode 100644
index 000000000..ee45ed849
--- /dev/null
+++ b/Help/prop_tgt/NO_SONAME.rst
@@ -0,0 +1,14 @@
+NO_SONAME
+---------
+
+Whether to set "soname" when linking a shared library.
+
+Enable this boolean property if a generated shared library
+should not have "soname" set. Default is to set "soname" on all
+shared libraries as long as the platform supports it.
+Generally, use this property only for leaf private libraries or
+plugins. If you use it on normal shared libraries which other targets
+link against, on some platforms a linker will insert a full path to
+the library (as specified at link time) into the dynamic section of
+the dependent binary. Therefore, once installed, dynamic loader may
+eventually fail to locate the library for the binary.
diff --git a/Help/prop_tgt/NO_SYSTEM_FROM_IMPORTED.rst b/Help/prop_tgt/NO_SYSTEM_FROM_IMPORTED.rst
new file mode 100644
index 000000000..070dd3018
--- /dev/null
+++ b/Help/prop_tgt/NO_SYSTEM_FROM_IMPORTED.rst
@@ -0,0 +1,11 @@
+NO_SYSTEM_FROM_IMPORTED
+-----------------------
+
+Do not treat includes from IMPORTED target interfaces as SYSTEM.
+
+The contents of the INTERFACE_INCLUDE_DIRECTORIES of IMPORTED targets
+are treated as SYSTEM includes by default. If this property is
+enabled, the contents of the INTERFACE_INCLUDE_DIRECTORIES of IMPORTED
+targets are not treated as system includes. This property is
+initialized by the value of the variable CMAKE_NO_SYSTEM_FROM_IMPORTED
+if it is set when a target is created.
diff --git a/Help/prop_tgt/OSX_ARCHITECTURES.rst b/Help/prop_tgt/OSX_ARCHITECTURES.rst
new file mode 100644
index 000000000..cefe03f5b
--- /dev/null
+++ b/Help/prop_tgt/OSX_ARCHITECTURES.rst
@@ -0,0 +1,11 @@
+OSX_ARCHITECTURES
+-----------------
+
+Target specific architectures for OS X.
+
+The ``OSX_ARCHITECTURES`` property sets the target binary architecture for
+targets on OS X (``-arch``). This property is initialized by the value of the
+variable :variable:`CMAKE_OSX_ARCHITECTURES` if it is set when a target is
+created. Use :prop_tgt:`OSX_ARCHITECTURES_<CONFIG>` to set the binary
+architectures on a per-configuration basis, where ``<CONFIG>`` is an
+upper-case name (e.g. ``OSX_ARCHITECTURES_DEBUG``).
diff --git a/Help/prop_tgt/OSX_ARCHITECTURES_CONFIG.rst b/Help/prop_tgt/OSX_ARCHITECTURES_CONFIG.rst
new file mode 100644
index 000000000..fb78177fb
--- /dev/null
+++ b/Help/prop_tgt/OSX_ARCHITECTURES_CONFIG.rst
@@ -0,0 +1,7 @@
+OSX_ARCHITECTURES_<CONFIG>
+--------------------------
+
+Per-configuration OS X and iOS binary architectures for a target.
+
+This property is the configuration-specific version of
+:prop_tgt:`OSX_ARCHITECTURES`.
diff --git a/Help/prop_tgt/OUTPUT_NAME.rst b/Help/prop_tgt/OUTPUT_NAME.rst
new file mode 100644
index 000000000..f1bdb7c88
--- /dev/null
+++ b/Help/prop_tgt/OUTPUT_NAME.rst
@@ -0,0 +1,21 @@
+OUTPUT_NAME
+-----------
+
+Output name for target files.
+
+This sets the base name for output files created for an executable or
+library target. If not set, the logical target name is used by
+default.
+
+Contents of ``OUTPUT_NAME`` and the variants listed below may use
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+See also the variants:
+
+* :prop_tgt:`OUTPUT_NAME_<CONFIG>`
+* :prop_tgt:`ARCHIVE_OUTPUT_NAME_<CONFIG>`
+* :prop_tgt:`ARCHIVE_OUTPUT_NAME`
+* :prop_tgt:`LIBRARY_OUTPUT_NAME_<CONFIG>`
+* :prop_tgt:`LIBRARY_OUTPUT_NAME`
+* :prop_tgt:`RUNTIME_OUTPUT_NAME_<CONFIG>`
+* :prop_tgt:`RUNTIME_OUTPUT_NAME`
diff --git a/Help/prop_tgt/OUTPUT_NAME_CONFIG.rst b/Help/prop_tgt/OUTPUT_NAME_CONFIG.rst
new file mode 100644
index 000000000..41b782f98
--- /dev/null
+++ b/Help/prop_tgt/OUTPUT_NAME_CONFIG.rst
@@ -0,0 +1,7 @@
+OUTPUT_NAME_<CONFIG>
+--------------------
+
+Per-configuration target file base name.
+
+This is the configuration-specific version of the :prop_tgt:`OUTPUT_NAME`
+target property.
diff --git a/Help/prop_tgt/PDB_NAME.rst b/Help/prop_tgt/PDB_NAME.rst
new file mode 100644
index 000000000..3a6579669
--- /dev/null
+++ b/Help/prop_tgt/PDB_NAME.rst
@@ -0,0 +1,12 @@
+PDB_NAME
+--------
+
+Output name for the MS debug symbol ``.pdb`` file generated by the
+linker for an executable or shared library target.
+
+This property specifies the base name for the debug symbols file.
+If not set, the :prop_tgt:`OUTPUT_NAME` target property value or
+logical target name is used by default.
+
+.. |COMPILE_PDB_XXX| replace:: :prop_tgt:`COMPILE_PDB_NAME`
+.. include:: PDB_NOTE.txt
diff --git a/Help/prop_tgt/PDB_NAME_CONFIG.rst b/Help/prop_tgt/PDB_NAME_CONFIG.rst
new file mode 100644
index 000000000..cb3121c2f
--- /dev/null
+++ b/Help/prop_tgt/PDB_NAME_CONFIG.rst
@@ -0,0 +1,10 @@
+PDB_NAME_<CONFIG>
+-----------------
+
+Per-configuration output name for the MS debug symbol ``.pdb`` file
+generated by the linker for an executable or shared library target.
+
+This is the configuration-specific version of :prop_tgt:`PDB_NAME`.
+
+.. |COMPILE_PDB_XXX| replace:: :prop_tgt:`COMPILE_PDB_NAME_<CONFIG>`
+.. include:: PDB_NOTE.txt
diff --git a/Help/prop_tgt/PDB_NOTE.txt b/Help/prop_tgt/PDB_NOTE.txt
new file mode 100644
index 000000000..f90ea8117
--- /dev/null
+++ b/Help/prop_tgt/PDB_NOTE.txt
@@ -0,0 +1,12 @@
+.. note::
+ This property does not apply to STATIC library targets because no linker
+ is invoked to produce them so they have no linker-generated ``.pdb`` file
+ containing debug symbols.
+
+ The linker-generated program database files are specified by the
+ ``/pdb`` linker flag and are not the same as compiler-generated
+ program database files specified by the ``/Fd`` compiler flag.
+ Use the |COMPILE_PDB_XXX| property to specify the latter.
+
+ This property is not implemented by the :generator:`Visual Studio 6`
+ generator.
diff --git a/Help/prop_tgt/PDB_OUTPUT_DIRECTORY.rst b/Help/prop_tgt/PDB_OUTPUT_DIRECTORY.rst
new file mode 100644
index 000000000..730cf5776
--- /dev/null
+++ b/Help/prop_tgt/PDB_OUTPUT_DIRECTORY.rst
@@ -0,0 +1,13 @@
+PDB_OUTPUT_DIRECTORY
+--------------------
+
+Output directory for the MS debug symbols ``.pdb`` file
+generated by the linker for an executable or shared library target.
+
+This property specifies the directory into which the MS debug symbols
+will be placed by the linker. This property is initialized by the
+value of the :variable:`CMAKE_PDB_OUTPUT_DIRECTORY` variable if it is
+set when a target is created.
+
+.. |COMPILE_PDB_XXX| replace:: :prop_tgt:`COMPILE_PDB_OUTPUT_DIRECTORY`
+.. include:: PDB_NOTE.txt
diff --git a/Help/prop_tgt/PDB_OUTPUT_DIRECTORY_CONFIG.rst b/Help/prop_tgt/PDB_OUTPUT_DIRECTORY_CONFIG.rst
new file mode 100644
index 000000000..6037fa0c7
--- /dev/null
+++ b/Help/prop_tgt/PDB_OUTPUT_DIRECTORY_CONFIG.rst
@@ -0,0 +1,15 @@
+PDB_OUTPUT_DIRECTORY_<CONFIG>
+-----------------------------
+
+Per-configuration output directory for the MS debug symbol ``.pdb`` file
+generated by the linker for an executable or shared library target.
+
+This is a per-configuration version of :prop_tgt:`PDB_OUTPUT_DIRECTORY`,
+but multi-configuration generators (VS, Xcode) do NOT append a
+per-configuration subdirectory to the specified directory. This
+property is initialized by the value of the
+:variable:`CMAKE_PDB_OUTPUT_DIRECTORY_<CONFIG>` variable if it is
+set when a target is created.
+
+.. |COMPILE_PDB_XXX| replace:: :prop_tgt:`COMPILE_PDB_OUTPUT_DIRECTORY_<CONFIG>`
+.. include:: PDB_NOTE.txt
diff --git a/Help/prop_tgt/POSITION_INDEPENDENT_CODE.rst b/Help/prop_tgt/POSITION_INDEPENDENT_CODE.rst
new file mode 100644
index 000000000..54af8c6de
--- /dev/null
+++ b/Help/prop_tgt/POSITION_INDEPENDENT_CODE.rst
@@ -0,0 +1,11 @@
+POSITION_INDEPENDENT_CODE
+-------------------------
+
+Whether to create a position-independent target
+
+The ``POSITION_INDEPENDENT_CODE`` property determines whether position
+independent executables or shared libraries will be created. This
+property is ``True`` by default for ``SHARED`` and ``MODULE`` library
+targets and ``False`` otherwise. This property is initialized by the value
+of the :variable:`CMAKE_POSITION_INDEPENDENT_CODE` variable if it is set
+when a target is created.
diff --git a/Help/prop_tgt/POST_INSTALL_SCRIPT.rst b/Help/prop_tgt/POST_INSTALL_SCRIPT.rst
new file mode 100644
index 000000000..f1adb40b7
--- /dev/null
+++ b/Help/prop_tgt/POST_INSTALL_SCRIPT.rst
@@ -0,0 +1,9 @@
+POST_INSTALL_SCRIPT
+-------------------
+
+Deprecated install support.
+
+The PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT properties are the old
+way to specify CMake scripts to run before and after installing a
+target. They are used only when the old INSTALL_TARGETS command is
+used to install the target. Use the INSTALL command instead.
diff --git a/Help/prop_tgt/PREFIX.rst b/Help/prop_tgt/PREFIX.rst
new file mode 100644
index 000000000..a16510461
--- /dev/null
+++ b/Help/prop_tgt/PREFIX.rst
@@ -0,0 +1,7 @@
+PREFIX
+------
+
+What comes before the library name.
+
+A target property that can be set to override the prefix (such as
+"lib") on a library name.
diff --git a/Help/prop_tgt/PRE_INSTALL_SCRIPT.rst b/Help/prop_tgt/PRE_INSTALL_SCRIPT.rst
new file mode 100644
index 000000000..113d7c56a
--- /dev/null
+++ b/Help/prop_tgt/PRE_INSTALL_SCRIPT.rst
@@ -0,0 +1,9 @@
+PRE_INSTALL_SCRIPT
+------------------
+
+Deprecated install support.
+
+The PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT properties are the old
+way to specify CMake scripts to run before and after installing a
+target. They are used only when the old INSTALL_TARGETS command is
+used to install the target. Use the INSTALL command instead.
diff --git a/Help/prop_tgt/PRIVATE_HEADER.rst b/Help/prop_tgt/PRIVATE_HEADER.rst
new file mode 100644
index 000000000..c4412ed25
--- /dev/null
+++ b/Help/prop_tgt/PRIVATE_HEADER.rst
@@ -0,0 +1,11 @@
+PRIVATE_HEADER
+--------------
+
+Specify private header files in a :prop_tgt:`FRAMEWORK` shared library target.
+
+Shared library targets marked with the :prop_tgt:`FRAMEWORK` property generate
+frameworks on OS X, iOS and normal shared libraries on other platforms.
+This property may be set to a list of header files to be placed in the
+PrivateHeaders directory inside the framework folder. On non-Apple
+platforms these headers may be installed using the ``PRIVATE_HEADER``
+option to the ``install(TARGETS)`` command.
diff --git a/Help/prop_tgt/PROJECT_LABEL.rst b/Help/prop_tgt/PROJECT_LABEL.rst
new file mode 100644
index 000000000..a1491ee13
--- /dev/null
+++ b/Help/prop_tgt/PROJECT_LABEL.rst
@@ -0,0 +1,7 @@
+PROJECT_LABEL
+-------------
+
+Change the name of a target in an IDE.
+
+Can be used to change the name of the target in an IDE like Visual
+Studio.
diff --git a/Help/prop_tgt/PUBLIC_HEADER.rst b/Help/prop_tgt/PUBLIC_HEADER.rst
new file mode 100644
index 000000000..d4a636caf
--- /dev/null
+++ b/Help/prop_tgt/PUBLIC_HEADER.rst
@@ -0,0 +1,11 @@
+PUBLIC_HEADER
+-------------
+
+Specify public header files in a :prop_tgt:`FRAMEWORK` shared library target.
+
+Shared library targets marked with the :prop_tgt:`FRAMEWORK` property generate
+frameworks on OS X, iOS and normal shared libraries on other platforms.
+This property may be set to a list of header files to be placed in the
+``Headers`` directory inside the framework folder. On non-Apple platforms
+these headers may be installed using the ``PUBLIC_HEADER`` option to the
+``install(TARGETS)`` command.
diff --git a/Help/prop_tgt/RESOURCE.rst b/Help/prop_tgt/RESOURCE.rst
new file mode 100644
index 000000000..d837f7b33
--- /dev/null
+++ b/Help/prop_tgt/RESOURCE.rst
@@ -0,0 +1,61 @@
+RESOURCE
+--------
+
+Specify resource files in a :prop_tgt:`FRAMEWORK` or :prop_tgt:`BUNDLE`.
+
+Target marked with the :prop_tgt:`FRAMEWORK` or :prop_tgt:`BUNDLE` property
+generate framework or application bundle (both OS X and iOS is supported)
+or normal shared libraries on other platforms.
+This property may be set to a list of files to be placed in the corresponding
+directory (eg. ``Resources`` directory for OS X) inside the bundle.
+On non-Apple platforms these files may be installed using the ``RESOURCE``
+option to the ``install(TARGETS)`` command.
+
+Following example of Application Bundle:
+
+.. code-block:: cmake
+
+ add_executable(ExecutableTarget
+ addDemo.c
+ resourcefile.txt
+ appresourcedir/appres.txt
+ )
+
+ target_link_libraries(ExecutableTarget heymath mul)
+
+ set(RESOURCE_FILES
+ resourcefile.txt
+ appresourcedir/appres.txt
+ )
+
+ set_target_properties(ExecutableTarget PROPERTIES
+ MACOSX_BUNDLE TRUE
+ MACOSX_FRAMEWORK_IDENTIFIER org.cmake.ExecutableTarget
+ RESOURCE "${RESOURCE_FILES}"
+ )
+
+will produce flat structure for iOS systems::
+
+ ExecutableTarget.app
+ appres.txt
+ ExecutableTarget
+ Info.plist
+ resourcefile.txt
+
+For OS X systems it will produce following directory structure::
+
+ ExecutableTarget.app/
+ Contents
+ Info.plist
+ MacOS
+ ExecutableTarget
+ Resources
+ appres.txt
+ resourcefile.txt
+
+For Linux, such cmake script produce following files::
+
+ ExecutableTarget
+ Resources
+ appres.txt
+ resourcefile.txt
diff --git a/Help/prop_tgt/RULE_LAUNCH_COMPILE.rst b/Help/prop_tgt/RULE_LAUNCH_COMPILE.rst
new file mode 100644
index 000000000..e92ab86af
--- /dev/null
+++ b/Help/prop_tgt/RULE_LAUNCH_COMPILE.rst
@@ -0,0 +1,7 @@
+RULE_LAUNCH_COMPILE
+-------------------
+
+Specify a launcher for compile rules.
+
+See the global property of the same name for details. This overrides
+the global and directory property for a target.
diff --git a/Help/prop_tgt/RULE_LAUNCH_CUSTOM.rst b/Help/prop_tgt/RULE_LAUNCH_CUSTOM.rst
new file mode 100644
index 000000000..2db03177f
--- /dev/null
+++ b/Help/prop_tgt/RULE_LAUNCH_CUSTOM.rst
@@ -0,0 +1,7 @@
+RULE_LAUNCH_CUSTOM
+------------------
+
+Specify a launcher for custom rules.
+
+See the global property of the same name for details. This overrides
+the global and directory property for a target.
diff --git a/Help/prop_tgt/RULE_LAUNCH_LINK.rst b/Help/prop_tgt/RULE_LAUNCH_LINK.rst
new file mode 100644
index 000000000..f33003367
--- /dev/null
+++ b/Help/prop_tgt/RULE_LAUNCH_LINK.rst
@@ -0,0 +1,7 @@
+RULE_LAUNCH_LINK
+----------------
+
+Specify a launcher for link rules.
+
+See the global property of the same name for details. This overrides
+the global and directory property for a target.
diff --git a/Help/prop_tgt/RUNTIME_OUTPUT_DIRECTORY.rst b/Help/prop_tgt/RUNTIME_OUTPUT_DIRECTORY.rst
new file mode 100644
index 000000000..12390f50a
--- /dev/null
+++ b/Help/prop_tgt/RUNTIME_OUTPUT_DIRECTORY.rst
@@ -0,0 +1,9 @@
+RUNTIME_OUTPUT_DIRECTORY
+------------------------
+
+.. |XXX| replace:: :ref:`RUNTIME <Runtime Output Artifacts>`
+.. |xxx| replace:: runtime
+.. |CMAKE_XXX_OUTPUT_DIRECTORY| replace:: CMAKE_RUNTIME_OUTPUT_DIRECTORY
+.. include:: XXX_OUTPUT_DIRECTORY.txt
+
+See also the :prop_tgt:`RUNTIME_OUTPUT_DIRECTORY_<CONFIG>` target property.
diff --git a/Help/prop_tgt/RUNTIME_OUTPUT_DIRECTORY_CONFIG.rst b/Help/prop_tgt/RUNTIME_OUTPUT_DIRECTORY_CONFIG.rst
new file mode 100644
index 000000000..94fb2776a
--- /dev/null
+++ b/Help/prop_tgt/RUNTIME_OUTPUT_DIRECTORY_CONFIG.rst
@@ -0,0 +1,16 @@
+RUNTIME_OUTPUT_DIRECTORY_<CONFIG>
+---------------------------------
+
+Per-configuration output directory for
+:ref:`RUNTIME <Runtime Output Artifacts>` target files.
+
+This is a per-configuration version of the
+:prop_tgt:`RUNTIME_OUTPUT_DIRECTORY` target property, but
+multi-configuration generators (VS, Xcode) do NOT append a
+per-configuration subdirectory to the specified directory. This
+property is initialized by the value of the
+:variable:`CMAKE_RUNTIME_OUTPUT_DIRECTORY_<CONFIG>` variable if
+it is set when a target is created.
+
+Contents of ``RUNTIME_OUTPUT_DIRECTORY_<CONFIG>`` may use
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Help/prop_tgt/RUNTIME_OUTPUT_NAME.rst b/Help/prop_tgt/RUNTIME_OUTPUT_NAME.rst
new file mode 100644
index 000000000..11729c3a5
--- /dev/null
+++ b/Help/prop_tgt/RUNTIME_OUTPUT_NAME.rst
@@ -0,0 +1,8 @@
+RUNTIME_OUTPUT_NAME
+-------------------
+
+.. |XXX| replace:: :ref:`RUNTIME <Runtime Output Artifacts>`
+.. |xxx| replace:: runtime
+.. include:: XXX_OUTPUT_NAME.txt
+
+See also the :prop_tgt:`RUNTIME_OUTPUT_NAME_<CONFIG>` target property.
diff --git a/Help/prop_tgt/RUNTIME_OUTPUT_NAME_CONFIG.rst b/Help/prop_tgt/RUNTIME_OUTPUT_NAME_CONFIG.rst
new file mode 100644
index 000000000..b6a31bfdf
--- /dev/null
+++ b/Help/prop_tgt/RUNTIME_OUTPUT_NAME_CONFIG.rst
@@ -0,0 +1,8 @@
+RUNTIME_OUTPUT_NAME_<CONFIG>
+----------------------------
+
+Per-configuration output name for
+:ref:`RUNTIME <Runtime Output Artifacts>` target files.
+
+This is the configuration-specific version of the
+:prop_tgt:`RUNTIME_OUTPUT_NAME` target property.
diff --git a/Help/prop_tgt/SKIP_BUILD_RPATH.rst b/Help/prop_tgt/SKIP_BUILD_RPATH.rst
new file mode 100644
index 000000000..a91fa9ca3
--- /dev/null
+++ b/Help/prop_tgt/SKIP_BUILD_RPATH.rst
@@ -0,0 +1,9 @@
+SKIP_BUILD_RPATH
+----------------
+
+Should rpaths be used for the build tree.
+
+SKIP_BUILD_RPATH is a boolean specifying whether to skip automatic
+generation of an rpath allowing the target to run from the build tree.
+This property is initialized by the value of the variable
+CMAKE_SKIP_BUILD_RPATH if it is set when a target is created.
diff --git a/Help/prop_tgt/SOURCES.rst b/Help/prop_tgt/SOURCES.rst
new file mode 100644
index 000000000..493643e84
--- /dev/null
+++ b/Help/prop_tgt/SOURCES.rst
@@ -0,0 +1,6 @@
+SOURCES
+-------
+
+Source names specified for a target.
+
+List of sources specified for a target.
diff --git a/Help/prop_tgt/SOURCE_DIR.rst b/Help/prop_tgt/SOURCE_DIR.rst
new file mode 100644
index 000000000..b25813bff
--- /dev/null
+++ b/Help/prop_tgt/SOURCE_DIR.rst
@@ -0,0 +1,6 @@
+SOURCE_DIR
+----------
+
+This read-only property reports the value of the
+:variable:`CMAKE_CURRENT_SOURCE_DIR` variable in the directory in which
+the target was defined.
diff --git a/Help/prop_tgt/SOVERSION.rst b/Help/prop_tgt/SOVERSION.rst
new file mode 100644
index 000000000..672ff23a8
--- /dev/null
+++ b/Help/prop_tgt/SOVERSION.rst
@@ -0,0 +1,14 @@
+SOVERSION
+---------
+
+What version number is this target.
+
+For shared libraries VERSION and SOVERSION can be used to specify the
+build version and API version respectively. When building or
+installing appropriate symlinks are created if the platform supports
+symlinks and the linker supports so-names. If only one of both is
+specified the missing is assumed to have the same version number.
+SOVERSION is ignored if NO_SONAME property is set. For shared
+libraries and executables on Windows the VERSION attribute is parsed
+to extract a "major.minor" version number. These numbers are used as
+the image version of the binary.
diff --git a/Help/prop_tgt/STATIC_LIBRARY_FLAGS.rst b/Help/prop_tgt/STATIC_LIBRARY_FLAGS.rst
new file mode 100644
index 000000000..d3b2cd478
--- /dev/null
+++ b/Help/prop_tgt/STATIC_LIBRARY_FLAGS.rst
@@ -0,0 +1,6 @@
+STATIC_LIBRARY_FLAGS
+--------------------
+
+Extra flags to use when linking static libraries.
+
+Extra flags to use when linking a static library.
diff --git a/Help/prop_tgt/STATIC_LIBRARY_FLAGS_CONFIG.rst b/Help/prop_tgt/STATIC_LIBRARY_FLAGS_CONFIG.rst
new file mode 100644
index 000000000..cca353ddc
--- /dev/null
+++ b/Help/prop_tgt/STATIC_LIBRARY_FLAGS_CONFIG.rst
@@ -0,0 +1,6 @@
+STATIC_LIBRARY_FLAGS_<CONFIG>
+-----------------------------
+
+Per-configuration flags for creating a static library.
+
+This is the configuration-specific version of STATIC_LIBRARY_FLAGS.
diff --git a/Help/prop_tgt/SUFFIX.rst b/Help/prop_tgt/SUFFIX.rst
new file mode 100644
index 000000000..70844be5c
--- /dev/null
+++ b/Help/prop_tgt/SUFFIX.rst
@@ -0,0 +1,7 @@
+SUFFIX
+------
+
+What comes after the target name.
+
+A target property that can be set to override the suffix (such as
+".so" or ".exe") on the name of a library, module or executable.
diff --git a/Help/prop_tgt/TYPE.rst b/Help/prop_tgt/TYPE.rst
new file mode 100644
index 000000000..5ac63cc37
--- /dev/null
+++ b/Help/prop_tgt/TYPE.rst
@@ -0,0 +1,9 @@
+TYPE
+----
+
+The type of the target.
+
+This read-only property can be used to test the type of the given
+target. It will be one of STATIC_LIBRARY, MODULE_LIBRARY,
+SHARED_LIBRARY, INTERFACE_LIBRARY, EXECUTABLE or one of the internal
+target types.
diff --git a/Help/prop_tgt/VERSION.rst b/Help/prop_tgt/VERSION.rst
new file mode 100644
index 000000000..87f6c4976
--- /dev/null
+++ b/Help/prop_tgt/VERSION.rst
@@ -0,0 +1,16 @@
+VERSION
+-------
+
+What version number is this target.
+
+For shared libraries VERSION and SOVERSION can be used to specify the
+build version and API version respectively. When building or
+installing appropriate symlinks are created if the platform supports
+symlinks and the linker supports so-names. If only one of both is
+specified the missing is assumed to have the same version number. For
+executables VERSION can be used to specify the build version. When
+building or installing appropriate symlinks are created if the
+platform supports symlinks. For shared libraries and executables on
+Windows the VERSION attribute is parsed to extract a "major.minor"
+version number. These numbers are used as the image version of the
+binary.
diff --git a/Help/prop_tgt/VISIBILITY_INLINES_HIDDEN.rst b/Help/prop_tgt/VISIBILITY_INLINES_HIDDEN.rst
new file mode 100644
index 000000000..adbbc7103
--- /dev/null
+++ b/Help/prop_tgt/VISIBILITY_INLINES_HIDDEN.rst
@@ -0,0 +1,13 @@
+VISIBILITY_INLINES_HIDDEN
+-------------------------
+
+Whether to add a compile flag to hide symbols of inline functions
+
+The ``VISIBILITY_INLINES_HIDDEN`` property determines whether a flag for
+hiding symbols for inline functions, such as ``-fvisibility-inlines-hidden``,
+should be used when invoking the compiler. This property affects compilation
+in sources of all types of targets (subject to policy :policy:`CMP0063`).
+
+This property is initialized by
+the value of the :variable:`CMAKE_VISIBILITY_INLINES_HIDDEN` variable if it
+is set when a target is created.
diff --git a/Help/prop_tgt/VS_DESKTOP_EXTENSIONS_VERSION.rst b/Help/prop_tgt/VS_DESKTOP_EXTENSIONS_VERSION.rst
new file mode 100644
index 000000000..19d162049
--- /dev/null
+++ b/Help/prop_tgt/VS_DESKTOP_EXTENSIONS_VERSION.rst
@@ -0,0 +1,10 @@
+VS_DESKTOP_EXTENSIONS_VERSION
+-----------------------------
+
+Visual Studio Windows 10 Desktop Extensions Version
+
+Specifies the version of the Desktop Extensions that should be included in the
+target. For example ``10.0.10240.0``. If the value is not specified, the Desktop
+Extensions will not be included. To use the same version of the extensions as
+the Windows 10 SDK that is being used, you can use the
+:variable:`CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION` variable.
diff --git a/Help/prop_tgt/VS_DOTNET_REFERENCES.rst b/Help/prop_tgt/VS_DOTNET_REFERENCES.rst
new file mode 100644
index 000000000..a661ad926
--- /dev/null
+++ b/Help/prop_tgt/VS_DOTNET_REFERENCES.rst
@@ -0,0 +1,7 @@
+VS_DOTNET_REFERENCES
+--------------------
+
+Visual Studio managed project .NET references
+
+Adds one or more semicolon-delimited .NET references to a generated
+Visual Studio project. For example, "System;System.Windows.Forms".
diff --git a/Help/prop_tgt/VS_DOTNET_TARGET_FRAMEWORK_VERSION.rst b/Help/prop_tgt/VS_DOTNET_TARGET_FRAMEWORK_VERSION.rst
new file mode 100644
index 000000000..829d696d5
--- /dev/null
+++ b/Help/prop_tgt/VS_DOTNET_TARGET_FRAMEWORK_VERSION.rst
@@ -0,0 +1,7 @@
+VS_DOTNET_TARGET_FRAMEWORK_VERSION
+----------------------------------
+
+Specify the .NET target framework version.
+
+Used to specify the .NET target framework version for C++/CLI. For
+example, "v4.5".
diff --git a/Help/prop_tgt/VS_GLOBAL_KEYWORD.rst b/Help/prop_tgt/VS_GLOBAL_KEYWORD.rst
new file mode 100644
index 000000000..ce49316d8
--- /dev/null
+++ b/Help/prop_tgt/VS_GLOBAL_KEYWORD.rst
@@ -0,0 +1,12 @@
+VS_GLOBAL_KEYWORD
+-----------------
+
+Visual Studio project keyword for VS 10 (2010) and newer.
+
+Sets the "keyword" attribute for a generated Visual Studio project.
+Defaults to "Win32Proj". You may wish to override this value with
+"ManagedCProj", for example, in a Visual Studio managed C++ unit test
+project.
+
+Use the :prop_tgt:`VS_KEYWORD` target property to set the
+keyword for Visual Studio 9 (2008) and older.
diff --git a/Help/prop_tgt/VS_GLOBAL_PROJECT_TYPES.rst b/Help/prop_tgt/VS_GLOBAL_PROJECT_TYPES.rst
new file mode 100644
index 000000000..f4d9efc8e
--- /dev/null
+++ b/Help/prop_tgt/VS_GLOBAL_PROJECT_TYPES.rst
@@ -0,0 +1,15 @@
+VS_GLOBAL_PROJECT_TYPES
+-----------------------
+
+Visual Studio project type(s).
+
+Can be set to one or more UUIDs recognized by Visual Studio to
+indicate the type of project. This value is copied verbatim into the
+generated project file. Example for a managed C++ unit testing
+project:
+
+::
+
+ {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}
+
+UUIDs are semicolon-delimited.
diff --git a/Help/prop_tgt/VS_GLOBAL_ROOTNAMESPACE.rst b/Help/prop_tgt/VS_GLOBAL_ROOTNAMESPACE.rst
new file mode 100644
index 000000000..a23c54005
--- /dev/null
+++ b/Help/prop_tgt/VS_GLOBAL_ROOTNAMESPACE.rst
@@ -0,0 +1,7 @@
+VS_GLOBAL_ROOTNAMESPACE
+-----------------------
+
+Visual Studio project root namespace.
+
+Sets the "RootNamespace" attribute for a generated Visual Studio
+project. The attribute will be generated only if this is set.
diff --git a/Help/prop_tgt/VS_GLOBAL_variable.rst b/Help/prop_tgt/VS_GLOBAL_variable.rst
new file mode 100644
index 000000000..56b8021be
--- /dev/null
+++ b/Help/prop_tgt/VS_GLOBAL_variable.rst
@@ -0,0 +1,10 @@
+VS_GLOBAL_<variable>
+--------------------
+
+Visual Studio project-specific global variable.
+
+Tell the Visual Studio generator to set the global variable
+'<variable>' to a given value in the generated Visual Studio project.
+Ignored on other generators. Qt integration works better if
+VS_GLOBAL_QtVersion is set to the version FindQt4.cmake found. For
+example, "4.7.3"
diff --git a/Help/prop_tgt/VS_IOT_EXTENSIONS_VERSION.rst b/Help/prop_tgt/VS_IOT_EXTENSIONS_VERSION.rst
new file mode 100644
index 000000000..27c8a3df3
--- /dev/null
+++ b/Help/prop_tgt/VS_IOT_EXTENSIONS_VERSION.rst
@@ -0,0 +1,10 @@
+VS_IOT_EXTENSIONS_VERSION
+-------------------------
+
+Visual Studio Windows 10 IoT Extensions Version
+
+Specifies the version of the IoT Extensions that should be included in the
+target. For example ``10.0.10240.0``. If the value is not specified, the IoT
+Extensions will not be included. To use the same version of the extensions as
+the Windows 10 SDK that is being used, you can use the
+:variable:`CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION` variable.
diff --git a/Help/prop_tgt/VS_IOT_STARTUP_TASK.rst b/Help/prop_tgt/VS_IOT_STARTUP_TASK.rst
new file mode 100644
index 000000000..add50cb24
--- /dev/null
+++ b/Help/prop_tgt/VS_IOT_STARTUP_TASK.rst
@@ -0,0 +1,6 @@
+VS_IOT_STARTUP_TASK
+-------------------
+
+Visual Studio Windows 10 IoT Continuous Background Task
+
+Specifies that the target should be compiled as a Continuous Background Task library.
diff --git a/Help/prop_tgt/VS_KEYWORD.rst b/Help/prop_tgt/VS_KEYWORD.rst
new file mode 100644
index 000000000..6c2e0420e
--- /dev/null
+++ b/Help/prop_tgt/VS_KEYWORD.rst
@@ -0,0 +1,10 @@
+VS_KEYWORD
+----------
+
+Visual Studio project keyword for VS 9 (2008) and older.
+
+Can be set to change the visual studio keyword, for example Qt
+integration works better if this is set to Qt4VSv1.0.
+
+Use the :prop_tgt:`VS_GLOBAL_KEYWORD` target property to set the
+keyword for Visual Studio 10 (2010) and newer.
diff --git a/Help/prop_tgt/VS_MOBILE_EXTENSIONS_VERSION.rst b/Help/prop_tgt/VS_MOBILE_EXTENSIONS_VERSION.rst
new file mode 100644
index 000000000..be3c9a018
--- /dev/null
+++ b/Help/prop_tgt/VS_MOBILE_EXTENSIONS_VERSION.rst
@@ -0,0 +1,10 @@
+VS_MOBILE_EXTENSIONS_VERSION
+----------------------------
+
+Visual Studio Windows 10 Mobile Extensions Version
+
+Specifies the version of the Mobile Extensions that should be included in the
+target. For example ``10.0.10240.0``. If the value is not specified, the Mobile
+Extensions will not be included. To use the same version of the extensions as
+the Windows 10 SDK that is being used, you can use the
+:variable:`CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION` variable.
diff --git a/Help/prop_tgt/VS_SCC_AUXPATH.rst b/Help/prop_tgt/VS_SCC_AUXPATH.rst
new file mode 100644
index 000000000..054f59e3a
--- /dev/null
+++ b/Help/prop_tgt/VS_SCC_AUXPATH.rst
@@ -0,0 +1,7 @@
+VS_SCC_AUXPATH
+--------------
+
+Visual Studio Source Code Control Aux Path.
+
+Can be set to change the visual studio source code control auxpath
+property.
diff --git a/Help/prop_tgt/VS_SCC_LOCALPATH.rst b/Help/prop_tgt/VS_SCC_LOCALPATH.rst
new file mode 100644
index 000000000..b5b7721c5
--- /dev/null
+++ b/Help/prop_tgt/VS_SCC_LOCALPATH.rst
@@ -0,0 +1,7 @@
+VS_SCC_LOCALPATH
+----------------
+
+Visual Studio Source Code Control Local Path.
+
+Can be set to change the visual studio source code control local path
+property.
diff --git a/Help/prop_tgt/VS_SCC_PROJECTNAME.rst b/Help/prop_tgt/VS_SCC_PROJECTNAME.rst
new file mode 100644
index 000000000..6d7f628d9
--- /dev/null
+++ b/Help/prop_tgt/VS_SCC_PROJECTNAME.rst
@@ -0,0 +1,7 @@
+VS_SCC_PROJECTNAME
+------------------
+
+Visual Studio Source Code Control Project.
+
+Can be set to change the visual studio source code control project
+name property.
diff --git a/Help/prop_tgt/VS_SCC_PROVIDER.rst b/Help/prop_tgt/VS_SCC_PROVIDER.rst
new file mode 100644
index 000000000..80475af1f
--- /dev/null
+++ b/Help/prop_tgt/VS_SCC_PROVIDER.rst
@@ -0,0 +1,7 @@
+VS_SCC_PROVIDER
+---------------
+
+Visual Studio Source Code Control Provider.
+
+Can be set to change the visual studio source code control provider
+property.
diff --git a/Help/prop_tgt/VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION.rst b/Help/prop_tgt/VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION.rst
new file mode 100644
index 000000000..1ad7a7164
--- /dev/null
+++ b/Help/prop_tgt/VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION.rst
@@ -0,0 +1,10 @@
+VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION
+--------------------------------------
+
+Visual Studio Windows Target Platform Minimum Version
+
+For Windows 10. Specifies the minimum version of the OS that is being
+targeted. For example ``10.0.10240.0``. If the value is not specified, the
+value of :variable:`CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION` will be used on
+WindowsStore projects otherwise the target platform minimum version will not
+be specified for the project.
diff --git a/Help/prop_tgt/VS_WINRT_COMPONENT.rst b/Help/prop_tgt/VS_WINRT_COMPONENT.rst
new file mode 100644
index 000000000..e160bd64b
--- /dev/null
+++ b/Help/prop_tgt/VS_WINRT_COMPONENT.rst
@@ -0,0 +1,11 @@
+VS_WINRT_COMPONENT
+------------------
+
+Mark a target as a Windows Runtime component for the Visual Studio generator.
+Compile the target with ``C++/CX`` language extensions for Windows Runtime.
+For ``SHARED`` and ``MODULE`` libraries, this also defines the
+``_WINRT_DLL`` preprocessor macro.
+
+.. note::
+ Currently this is implemented only by Visual Studio generators.
+ Support may be added to other generators in the future.
diff --git a/Help/prop_tgt/VS_WINRT_EXTENSIONS.rst b/Help/prop_tgt/VS_WINRT_EXTENSIONS.rst
new file mode 100644
index 000000000..d1cba3471
--- /dev/null
+++ b/Help/prop_tgt/VS_WINRT_EXTENSIONS.rst
@@ -0,0 +1,5 @@
+VS_WINRT_EXTENSIONS
+-------------------
+
+Deprecated. Use :prop_tgt:`VS_WINRT_COMPONENT` instead.
+This property was an experimental partial implementation of that one.
diff --git a/Help/prop_tgt/VS_WINRT_REFERENCES.rst b/Help/prop_tgt/VS_WINRT_REFERENCES.rst
new file mode 100644
index 000000000..af98b2f7b
--- /dev/null
+++ b/Help/prop_tgt/VS_WINRT_REFERENCES.rst
@@ -0,0 +1,7 @@
+VS_WINRT_REFERENCES
+-------------------
+
+Visual Studio project Windows Runtime Metadata references
+
+Adds one or more semicolon-delimited WinRT references to a generated
+Visual Studio project. For example, "Windows;Windows.UI.Core".
diff --git a/Help/prop_tgt/WIN32_EXECUTABLE.rst b/Help/prop_tgt/WIN32_EXECUTABLE.rst
new file mode 100644
index 000000000..336d5f7f3
--- /dev/null
+++ b/Help/prop_tgt/WIN32_EXECUTABLE.rst
@@ -0,0 +1,12 @@
+WIN32_EXECUTABLE
+----------------
+
+Build an executable with a WinMain entry point on windows.
+
+When this property is set to true the executable when linked on
+Windows will be created with a WinMain() entry point instead of just
+main(). This makes it a GUI executable instead of a console
+application. See the CMAKE_MFC_FLAG variable documentation to
+configure use of MFC for WinMain executables. This property is
+initialized by the value of the variable CMAKE_WIN32_EXECUTABLE if it
+is set when a target is created.
diff --git a/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst b/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst
new file mode 100644
index 000000000..3f48af88c
--- /dev/null
+++ b/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst
@@ -0,0 +1,18 @@
+WINDOWS_EXPORT_ALL_SYMBOLS
+--------------------------
+
+This property is implemented only for MS-compatible tools on Windows.
+
+Enable this boolean property to automatically create a module definition
+(``.def``) file with all global symbols found in the input ``.obj`` files
+for a ``SHARED`` library on Windows. The module definition file will be
+passed to the linker causing all symbols to be exported from the ``.dll``.
+For global *data* symbols, ``__declspec(dllimport)`` must still be used when
+compiling against the code in the ``.dll``. All other function symbols will
+be automatically exported and imported by callers. This simplifies porting
+projects to Windows by reducing the need for explicit ``dllexport`` markup,
+even in ``C++`` classes.
+
+This property is initialized by the value of
+the :variable:`CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS` variable if it is set
+when a target is created.
diff --git a/Help/prop_tgt/XCODE_ATTRIBUTE_an-attribute.rst b/Help/prop_tgt/XCODE_ATTRIBUTE_an-attribute.rst
new file mode 100644
index 000000000..7e00ac430
--- /dev/null
+++ b/Help/prop_tgt/XCODE_ATTRIBUTE_an-attribute.rst
@@ -0,0 +1,16 @@
+XCODE_ATTRIBUTE_<an-attribute>
+------------------------------
+
+Set Xcode target attributes directly.
+
+Tell the Xcode generator to set '<an-attribute>' to a given value in
+the generated Xcode project. Ignored on other generators.
+
+See the :variable:`CMAKE_XCODE_ATTRIBUTE_<an-attribute>` variable
+to set attributes on all targets in a directory tree.
+
+Contents of ``XCODE_ATTRIBUTE_<an-attribute>`` may use
+"generator expressions" with the syntax ``$<...>``. See the
+:manual:`cmake-generator-expressions(7)` manual for available
+expressions. See the :manual:`cmake-buildsystem(7)` manual
+for more on defining buildsystem properties.
diff --git a/Help/prop_tgt/XCTEST.rst b/Help/prop_tgt/XCTEST.rst
new file mode 100644
index 000000000..eb47e606f
--- /dev/null
+++ b/Help/prop_tgt/XCTEST.rst
@@ -0,0 +1,13 @@
+XCTEST
+------
+
+This target is a XCTest CFBundle on the Mac.
+
+This property will usually get set via the :command:`xctest_add_bundle`
+macro in :module:`FindXCTest` module.
+
+If a module library target has this property set to true it will be
+built as a CFBundle when built on the Mac. It will have the directory
+structure required for a CFBundle.
+
+This property depends on :prop_tgt:`BUNDLE` to be effective.
diff --git a/Help/prop_tgt/XXX_OUTPUT_DIRECTORY.txt b/Help/prop_tgt/XXX_OUTPUT_DIRECTORY.txt
new file mode 100644
index 000000000..3ae54484a
--- /dev/null
+++ b/Help/prop_tgt/XXX_OUTPUT_DIRECTORY.txt
@@ -0,0 +1,11 @@
+Output directory in which to build |XXX| target files.
+
+This property specifies the directory into which |xxx| target files
+should be built. The property value may use
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
+Multi-configuration generators (VS, Xcode) append a per-configuration
+subdirectory to the specified directory unless a generator expression
+is used.
+
+This property is initialized by the value of the variable
+|CMAKE_XXX_OUTPUT_DIRECTORY| if it is set when a target is created.
diff --git a/Help/prop_tgt/XXX_OUTPUT_NAME.txt b/Help/prop_tgt/XXX_OUTPUT_NAME.txt
new file mode 100644
index 000000000..126f39198
--- /dev/null
+++ b/Help/prop_tgt/XXX_OUTPUT_NAME.txt
@@ -0,0 +1,5 @@
+Output name for |XXX| target files.
+
+This property specifies the base name for |xxx| target files. It
+overrides :prop_tgt:`OUTPUT_NAME` and :prop_tgt:`OUTPUT_NAME_<CONFIG>`
+properties.
diff --git a/Help/release/3.0.rst b/Help/release/3.0.rst
new file mode 100644
index 000000000..d02f94093
--- /dev/null
+++ b/Help/release/3.0.rst
@@ -0,0 +1,473 @@
+CMake 3.0 Release Notes
+***********************
+
+.. only:: html
+
+ .. contents::
+
+Changes made since CMake 2.8.12 include the following.
+
+Documentation Changes
+=====================
+
+* The CMake documentation has been converted to reStructuredText and
+ now transforms via Sphinx (`<http://sphinx-doc.org>`__) into man and
+ html pages. This allows the documentation to be properly indexed
+ and to contain cross-references.
+
+ Conversion from the old internal documentation format was done by
+ an automatic process so some documents may still contain artifacts.
+ They will be updated incrementally over time.
+
+ A basic reStructuredText processor has been implemented to support
+ ``cmake --help-command`` and similar command-line options.
+
+* New manuals were added:
+
+ - :manual:`cmake-buildsystem(7)`
+ - :manual:`cmake-commands(7)`, replacing ``cmakecommands(1)``
+ and ``cmakecompat(1)``
+ - :manual:`cmake-developer(7)`
+ - :manual:`cmake-generator-expressions(7)`
+ - :manual:`cmake-generators(7)`
+ - :manual:`cmake-language(7)`
+ - :manual:`cmake-modules(7)`, replacing ``cmakemodules(1)``
+ - :manual:`cmake-packages(7)`
+ - :manual:`cmake-policies(7)`, replacing ``cmakepolicies(1)``
+ - :manual:`cmake-properties(7)`, replacing ``cmakeprops(1)``
+ - :manual:`cmake-qt(7)`
+ - :manual:`cmake-toolchains(7)`
+ - :manual:`cmake-variables(7)`, replacing ``cmakevars(1)``
+
+* Release notes for CMake 3.0.0 and above will now be included with
+ the html documentation.
+
+New Features
+============
+
+Syntax
+------
+
+* The CMake language has been extended with
+ :ref:`Bracket Argument` and :ref:`Bracket Comment`
+ syntax inspired by Lua long brackets::
+
+ set(x [===[bracket argument]===] #[[bracket comment]])
+
+ Content between equal-length open- and close-brackets is taken
+ literally with no variable replacements.
+
+ .. warning::
+ This syntax change could not be made in a fully compatible
+ way. No policy is possible because syntax parsing occurs before
+ any chance to set a policy. Existing code using an unquoted
+ argument that starts with an open bracket will be interpreted
+ differently without any diagnostic. Fortunately the syntax is
+ obscure enough that this problem is unlikely in practice.
+
+Generators
+----------
+
+* A new :generator:`CodeLite` extra generator is available
+ for use with the Makefile or Ninja generators.
+
+* A new :generator:`Kate` extra generator is available
+ for use with the Makefile or Ninja generators.
+
+* The :generator:`Ninja` generator learned to use ``ninja`` job pools
+ when specified by a new :prop_gbl:`JOB_POOLS` global property.
+
+Commands
+--------
+
+* The :command:`add_library` command learned a new ``INTERFACE``
+ library type. Interface libraries have no build rules but may
+ have properties defining
+ :manual:`usage requirements <cmake-buildsystem(7)>`
+ and may be installed, exported, and imported. This is useful to
+ create header-only libraries that have concrete link dependencies
+ on other libraries.
+
+* The :command:`export()` command learned a new ``EXPORT`` mode that
+ retrieves the list of targets to export from an export set configured
+ by the :command:`install(TARGETS)` command ``EXPORT`` option. This
+ makes it easy to export from the build tree the same targets that
+ are exported from the install tree.
+
+* The :command:`export` command learned to work with multiple dependent
+ export sets, thus allowing multiple packages to be built and exported
+ from a single tree. The feature requires CMake to wait until the
+ generation step to write the output file. This means one should not
+ :command:`include` the generated targets file later during project
+ configuration because it will not be available.
+ Use :ref:`Alias Targets` instead. See policy :policy:`CMP0024`.
+
+* The :command:`install(FILES)` command learned to support
+ :manual:`generator expressions <cmake-generator-expressions(7)>`
+ in the list of files.
+
+* The :command:`project` command learned to set some version variables
+ to values specified by the new ``VERSION`` option or to empty strings.
+ See policy :policy:`CMP0048`.
+
+* The :command:`string` command learned a new ``CONCAT`` mode.
+ It is particularly useful in combination with the new
+ :ref:`Bracket Argument` syntax.
+
+* The :command:`unset` command learned a ``PARENT_SCOPE`` option
+ matching that of the :command:`set` command.
+
+* The :command:`include_external_msproject` command learned
+ to handle non-C++ projects like ``.vbproj`` or ``.csproj``.
+
+* The :command:`ctest_update` command learned to update work trees
+ managed by the Perforce (p4) version control tool.
+
+* The :command:`message` command learned a ``DEPRECATION`` mode. Such
+ messages are not issued by default, but may be issued as a warning if
+ :variable:`CMAKE_WARN_DEPRECATED` is enabled, or as an error if
+ :variable:`CMAKE_ERROR_DEPRECATED` is enabled.
+
+* The :command:`target_link_libraries` command now allows repeated use of
+ the ``LINK_PUBLIC`` and ``LINK_PRIVATE`` keywords.
+
+Variables
+---------
+
+* Variable :variable:`CMAKE_FIND_NO_INSTALL_PREFIX` has been
+ introduced to tell CMake not to add the value of
+ :variable:`CMAKE_INSTALL_PREFIX` to the
+ :variable:`CMAKE_SYSTEM_PREFIX_PATH` variable by default.
+ This is useful when building a project that installs some
+ of its own dependencies to avoid finding files it is about
+ to replace.
+
+* Variable :variable:`CMAKE_STAGING_PREFIX` was introduced for use
+ when cross-compiling to specify an installation prefix on the
+ host system that differs from a :variable:`CMAKE_INSTALL_PREFIX`
+ value meant for the target system.
+
+* Variable :variable:`CMAKE_SYSROOT` was introduced to specify the
+ toolchain SDK installation prefix, typically for cross-compiling.
+ This is used to pass a ``--sysroot`` option to the compiler and
+ as a prefix searched by ``find_*`` commands.
+
+* Variable :variable:`CMAKE_<LANG>_COMPILER_TARGET` was introduced
+ for use when cross-compiling to specify the target platform in the
+ :ref:`toolchain file <Cross Compiling Toolchain>` specified by the
+ :variable:`CMAKE_TOOLCHAIN_FILE` variable.
+ This is used to pass an option such as ``--target=<triple>`` to some
+ cross-compiling compiler drivers.
+
+* Variable :variable:`CMAKE_MAP_IMPORTED_CONFIG_<CONFIG>` has been
+ introduced to optionally initialize the
+ :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>` target property.
+
+Properties
+----------
+
+* The :prop_dir:`ADDITIONAL_MAKE_CLEAN_FILES` directory property
+ learned to support
+ :manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+* A new directory property :prop_dir:`CMAKE_CONFIGURE_DEPENDS`
+ was introduced to allow projects to specify additional
+ files on which the configuration process depends. CMake will
+ re-run at build time when one of these files is modified.
+ Previously this was only possible to achieve by specifying
+ such files as the input to a :command:`configure_file` command.
+
+* A new :ref:`Qt AUTORCC` feature replaces the need to
+ invoke ``qt4_add_resources()`` by allowing ``.qrc`` files to
+ be listed as target sources.
+
+* A new :ref:`Qt AUTOUIC` feature replaces the need to
+ invoke ``qt4_wrap_ui()``.
+
+* Test properties learned to support
+ :manual:`generator expressions <cmake-generator-expressions(7)>`.
+ This is useful to specify per-configuration values for test
+ properties like :prop_test:`REQUIRED_FILES` and
+ :prop_test:`WORKING_DIRECTORY`.
+
+* A new :prop_test:`SKIP_RETURN_CODE` test property was introduced
+ to tell :manual:`ctest(1)` to treat a particular test return code as
+ if the test were not run. This is useful for test drivers to report
+ that certain test requirements were not available.
+
+* New types of :ref:`Compatible Interface Properties` were introduced,
+ namely the :prop_tgt:`COMPATIBLE_INTERFACE_NUMBER_MAX` and
+ :prop_tgt:`COMPATIBLE_INTERFACE_NUMBER_MIN` for calculating numeric
+ maximum and minimum values respectively.
+
+Modules
+-------
+
+* The :module:`CheckTypeSize` module ``check_type_size`` macro and
+ the :module:`CheckStructHasMember` module ``check_struct_has_member``
+ macro learned a new ``LANGUAGE`` option to optionally check C++ types.
+
+* The :module:`ExternalData` module learned to work with no
+ URL templates if a local store is available.
+
+* The :module:`ExternalProject` function ``ExternalProject_Add``
+ learned a new ``GIT_SUBMODULES`` option to specify a subset
+ of available submodules to checkout.
+
+* A new :module:`FindBacktrace` module has been added to support
+ :command:`find_package(Backtrace)` calls.
+
+* A new :module:`FindLua` module has been added to support
+ :command:`find_package(Lua)` calls.
+
+* The :module:`FindBoost` module learned a new ``Boost_NAMESPACE``
+ option to change the ``boost`` prefix on library names.
+
+* The :module:`FindBoost` module learned to control search
+ for libraies with the ``g`` tag (for MS debug runtime) with
+ a new ``Boost_USE_DEBUG_RUNTIME`` option. It is ``ON`` by
+ default to preserve existing behavior.
+
+* The :module:`FindJava` and :module:`FindJNI` modules learned
+ to use a ``JAVA_HOME`` CMake variable or environment variable,
+ and then try ``/usr/libexec/java_home`` on OS X.
+
+* The :module:`UseJava` module ``add_jar`` function learned a new
+ ``MANIFEST`` option to pass the ``-m`` option to ``jar``.
+
+* A new :module:`CMakeFindDependencyMacro` module was introduced with
+ a ``find_dependency`` macro to find transitive dependencies in
+ a :manual:`package configuration file <cmake-packages(7)>`. Such
+ dependencies are omitted by the listing of the :module:`FeatureSummary`
+ module.
+
+* The :module:`FindQt4` module learned to create :ref:`Imported Targets`
+ for Qt executables. This helps disambiguate when using multiple
+ :manual:`Qt versions <cmake-qt(7)>` in the same buildsystem.
+
+* The :module:`FindRuby` module learned to search for Ruby 2.0 and 2.1.
+
+Generator Expressions
+---------------------
+
+* New ``$<PLATFORM_ID>`` and ``$<PLATFORM_ID:...>``
+ :manual:`generator expressions <cmake-generator-expressions(7)>`
+ have been added.
+
+* The ``$<CONFIG>``
+ :manual:`generator expression <cmake-generator-expressions(7)>` now has
+ a variant which takes no argument. This is equivalent to the
+ ``$<CONFIGURATION>`` expression.
+
+* New ``$<UPPER_CASE:...>`` and ``$<LOWER_CASE:...>``
+ :manual:`generator expressions <cmake-generator-expressions(7)>`
+ generator expressions have been added.
+
+* A new ``$<MAKE_C_IDENTIFIER:...>``
+ :manual:`generator expression <cmake-generator-expressions(7)>` has
+ been added.
+
+Other
+-----
+
+* The :manual:`cmake(1)` ``-E`` option learned a new ``sleep`` command.
+
+* The :manual:`ccmake(1)` dialog learned to honor the
+ :prop_cache:`STRINGS` cache entry property to cycle through
+ the enumerated list of possible values.
+
+* The :manual:`cmake-gui(1)` dialog learned to remember window
+ settings between sessions.
+
+* The :manual:`cmake-gui(1)` dialog learned to remember the type
+ of a cache entry for completion in the ``Add Entry`` dialog.
+
+New Diagnostics
+===============
+
+* Directories named in the :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`
+ target property of imported targets linked conditionally by a
+ :manual:`generator expression <cmake-generator-expressions(7)>`
+ were not checked for existence. Now they are checked.
+ See policy :policy:`CMP0027`.
+
+* Build target names must now match a validity pattern and may no longer
+ conflict with CMake-defined targets. See policy :policy:`CMP0037`.
+
+* Build targets that specify themselves as a link dependency were
+ silently accepted but are now diagnosed. See :policy:`CMP0038`.
+
+* The :command:`target_link_libraries` command used to silently ignore
+ calls specifying as their first argument build targets created by
+ :command:`add_custom_target` but now diagnoses this mistake.
+ See policy :policy:`CMP0039`.
+
+* The :command:`add_custom_command` command used to silently ignore
+ calls specifying the ``TARGET`` option with a non-existent target
+ but now diagnoses this mistake. See policy :policy:`CMP0040`.
+
+* Relative paths in the :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`
+ target property used to be silently accepted if they contained a
+ :manual:`generator expression <cmake-generator-expressions(7)>`
+ but are now rejected. See policy :policy:`CMP0041`.
+
+* The :command:`get_target_property` command learned to reject calls
+ specifying a non-existent target. See policy :policy:`CMP0045`.
+
+* The :command:`add_dependencies` command learned to reject calls
+ specifying a dependency on a non-existent target.
+ See policy :policy:`CMP0046`.
+
+* Link dependency analysis learned to assume names containing ``::``
+ refer to :ref:`Alias Targets` or :ref:`Imported Targets`. It will
+ now produce an error if such a linked target is missing. Previously
+ in this case CMake generated a link line that failed at build time.
+ See policy :policy:`CMP0028`.
+
+* When the :command:`project` or :command:`enable_language` commands
+ initialize support for a language, it is now an error if the full
+ path to the compiler cannot be found and stored in the corresponding
+ :variable:`CMAKE_<LANG>_COMPILER` variable. This produces nicer error
+ messages up front and stops processing when no working compiler
+ is known to be available.
+
+* Target sources specified with the :command:`add_library` or
+ :command:`add_executable` command learned to reject items which
+ require an undocumented extra layer of variable expansion.
+ See policy :policy:`CMP0049`.
+
+* Use of :command:`add_custom_command` undocumented ``SOURCE``
+ signatures now results in an error. See policy :policy:`CMP0050`.
+
+Deprecated and Removed Features
+===============================
+
+* Compatibility options supporting code written for CMake versions
+ prior to 2.4 have been removed.
+
+* Several long-outdated commands that should no longer be called
+ have been disallowed in new code by policies:
+
+ - Policy :policy:`CMP0029` disallows :command:`subdir_depends`
+ - Policy :policy:`CMP0030` disallows :command:`use_mangled_mesa`
+ - Policy :policy:`CMP0031` disallows :command:`load_command`
+ - Policy :policy:`CMP0032` disallows :command:`output_required_files`
+ - Policy :policy:`CMP0033` disallows :command:`export_library_dependencies`
+ - Policy :policy:`CMP0034` disallows :command:`utility_source`
+ - Policy :policy:`CMP0035` disallows :command:`variable_requires`
+ - Policy :policy:`CMP0036` disallows :command:`build_name`
+
+* The :manual:`cmake(1)` ``-i`` wizard mode has been removed.
+ Instead use an interactive dialog such as :manual:`ccmake(1)`
+ or use the ``-D`` option to set cache values from the command line.
+
+* The builtin documentation formatters that supported command-line
+ options such as ``--help-man`` and ``--help-html`` have been removed
+ in favor of the above-mentioned new documentation system. These and
+ other command-line options that used to generate man- and html-
+ formatted pages no longer work. The :manual:`cmake(1)`
+ ``--help-custom-modules`` option now produces a warning at runtime
+ and generates a minimal document that reports the limitation.
+
+* The :prop_dir:`COMPILE_DEFINITIONS_<CONFIG>` directory properties and the
+ :prop_tgt:`COMPILE_DEFINITIONS_<CONFIG>` target properties have been
+ deprecated. Instead set the corresponding :prop_dir:`COMPILE_DEFINITIONS`
+ directory property or :prop_tgt:`COMPILE_DEFINITIONS` target property and
+ use :manual:`generator expressions <cmake-generator-expressions(7)>` like
+ ``$<CONFIG:...>`` to specify per-configuration definitions.
+ See policy :policy:`CMP0043`.
+
+* The :prop_tgt:`LOCATION` target property should no longer be read from
+ non-IMPORTED targets. It does not make sense in multi-configuration
+ generators since the build configuration is not known while configuring
+ the project. It has been superseded by the ``$<TARGET_FILE>`` generator
+ expression. See policy :policy:`CMP0026`.
+
+* The :prop_tgt:`COMPILE_FLAGS` target property is now documented
+ as deprecated, though no warning is issued. Use the
+ :prop_tgt:`COMPILE_OPTIONS` target property or the
+ :command:`target_compile_options` command instead.
+
+* The :module:`GenerateExportHeader` module ``add_compiler_export_flags``
+ function is now deprecated. It has been superseded by the
+ :prop_tgt:`<LANG>_VISIBILITY_PRESET` and
+ :prop_tgt:`VISIBILITY_INLINES_HIDDEN` target properties.
+
+Other Changes
+=============
+
+* The version scheme was changed to use only two components for
+ the feature level instead of three. The third component will
+ now be used for bug-fix releases or the date of development versions.
+ See the :variable:`CMAKE_VERSION` variable documentation for details.
+
+* The default install locations of CMake itself on Windows and
+ OS X no longer contain the CMake version number. This allows
+ for easy replacement without re-generating local build trees
+ manually.
+
+* Generators for Visual Studio 10 (2010) and later were renamed to
+ include the product year like generators for older VS versions:
+
+ - ``Visual Studio 10`` -> :generator:`Visual Studio 10 2010`
+ - ``Visual Studio 11`` -> :generator:`Visual Studio 11 2012`
+ - ``Visual Studio 12`` -> :generator:`Visual Studio 12 2013`
+
+ This clarifies which generator goes with each Visual Studio
+ version. The old names are recognized for compatibility.
+
+* The :variable:`CMAKE_<LANG>_COMPILER_ID` value for Apple-provided
+ Clang is now ``AppleClang``. It must be distinct from upstream
+ Clang because the version numbers differ.
+ See policy :policy:`CMP0025`.
+
+* The :variable:`CMAKE_<LANG>_COMPILER_ID` value for ``qcc`` on QNX
+ is now ``QCC``. It must be distinct from ``GNU`` because the
+ command-line options differ. See policy :policy:`CMP0047`.
+
+* On 64-bit OS X the :variable:`CMAKE_HOST_SYSTEM_PROCESSOR` value
+ is now correctly detected as ``x86_64`` instead of ``i386``.
+
+* On OS X, CMake learned to enable behavior specified by the
+ :prop_tgt:`MACOSX_RPATH` target property by default. This activates
+ use of ``@rpath`` for runtime shared library searches.
+ See policy :policy:`CMP0042`.
+
+* The :command:`build_command` command now returns a :manual:`cmake(1)`
+ ``--build`` command line instead of a direct invocation of the native
+ build tool. When using ``Visual Studio`` generators, CMake and CTest
+ no longer require :variable:`CMAKE_MAKE_PROGRAM` to be located up front.
+ Selection of the proper msbuild or devenv tool is now performed as
+ late as possible when the solution (``.sln``) file is available so
+ it can depend on project content.
+
+* The :manual:`cmake(1)` ``--build`` command now shares its own stdout
+ and stderr pipes with the native build tool by default.
+ The ``--use-stderr`` option that once activated this is now ignored.
+
+* The ``$<C_COMPILER_ID:...>`` and ``$<CXX_COMPILER_ID:...>``
+ :manual:`generator expressions <cmake-generator-expressions(7)>`
+ used to perform case-insensitive comparison but have now been
+ corrected to perform case-sensitive comparison.
+ See policy :policy:`CMP0044`.
+
+* The builtin ``edit_cache`` target will no longer select
+ :manual:`ccmake(1)` by default when no interactive terminal will
+ be available (e.g. with :generator:`Ninja` or an IDE generator).
+ Instead :manual:`cmake-gui(1)` will be preferred if available.
+
+* The :module:`ExternalProject` download step learned to
+ re-attempt download in certain cases to be more robust to
+ temporary network failure.
+
+* The :module:`FeatureSummary` no longer lists transitive
+ dependencies since they were not directly requested by the
+ current project.
+
+* The ``cmake-mode.el`` major Emacs editing mode has been cleaned
+ up and enhanced in several ways.
+
+* Include directories specified in the
+ :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` of :ref:`Imported Targets`
+ are treated as ``SYSTEM`` includes by default when handled as
+ :ref:`usage requirements <Include Directories and Usage Requirements>`.
diff --git a/Help/release/3.1.rst b/Help/release/3.1.rst
new file mode 100644
index 000000000..dca42cdcd
--- /dev/null
+++ b/Help/release/3.1.rst
@@ -0,0 +1,425 @@
+CMake 3.1 Release Notes
+***********************
+
+.. only:: html
+
+ .. contents::
+
+Changes made since CMake 3.0 include the following.
+
+Documentation Changes
+=====================
+
+* A new :manual:`cmake-compile-features(7)` manual was added.
+
+New Features
+============
+
+Generators
+----------
+
+* The :generator:`Visual Studio 14 2015` generator was added.
+
+Windows Phone and Windows Store
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Generators for Visual Studio 11 (2012) and above learned to generate
+ projects for Windows Phone and Windows Store. One may set the
+ :variable:`CMAKE_SYSTEM_NAME` variable to ``WindowsPhone``
+ or ``WindowsStore`` on the :manual:`cmake(1)` command-line
+ or in a :variable:`CMAKE_TOOLCHAIN_FILE` to activate these platforms.
+ Also set :variable:`CMAKE_SYSTEM_VERSION` to ``8.0`` or ``8.1`` to
+ specify the version of Windows to be targeted.
+
+NVIDIA Nsight Tegra
+^^^^^^^^^^^^^^^^^^^
+
+* Generators for Visual Studio 10 (2010) and above learned to generate
+ projects for NVIDIA Nsight Tegra Visual Studio Edition. One may set
+ the :variable:`CMAKE_SYSTEM_NAME` variable to ``Android`` on the
+ :manual:`cmake(1)` command-line or in a :variable:`CMAKE_TOOLCHAIN_FILE`
+ to activate this platform.
+
+Syntax
+------
+
+* The :manual:`cmake-language(7)` syntax for :ref:`Variable References` and
+ :ref:`Escape Sequences` was simplified in order to allow a much faster
+ implementation. See policy :policy:`CMP0053`.
+
+* The :command:`if` command no longer automatically dereferences
+ variables named in quoted or bracket arguments. See policy
+ :policy:`CMP0054`.
+
+Commands
+--------
+
+* The :command:`add_custom_command` command learned to interpret
+ :manual:`cmake-generator-expressions(7)` in arguments to ``DEPENDS``.
+
+* The :command:`export(PACKAGE)` command learned to check the
+ :variable:`CMAKE_EXPORT_NO_PACKAGE_REGISTRY` variable to skip
+ exporting the package.
+
+* The :command:`file(STRINGS)` command gained a new ``ENCODING``
+ option to enable extraction of ``UTF-8`` strings.
+
+* The :command:`find_package` command learned to check the
+ :variable:`CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY` and
+ :variable:`CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY`
+ variables to skip searching the package registries.
+
+* The :command:`get_property` command learned a new ``INSTALL`` scope
+ for properties.
+
+* The :command:`install` command learned a ``MESSAGE_NEVER`` option
+ to avoid output during installation.
+
+* The :command:`set_property` command learned a new ``INSTALL`` scope
+ for properties.
+
+* The :command:`string` command learned a new ``GENEX_STRIP`` subcommand
+ which removes
+ :manual:`generator expression <cmake-generator-expressions(7)>`.
+
+* The :command:`string` command learned a new ``UUID`` subcommand
+ to generate a univerally unique identifier.
+
+* New :command:`target_compile_features` command allows populating the
+ :prop_tgt:`COMPILE_FEATURES` target property, just like any other
+ build variable.
+
+* The :command:`target_sources` command was added to add to the
+ :prop_tgt:`SOURCES` target property.
+
+Variables
+---------
+
+* The Visual Studio generators for versions 8 (2005) and above
+ learned to read the target platform name from a new
+ :variable:`CMAKE_GENERATOR_PLATFORM` variable when it is
+ not specified as part of the generator name. The platform
+ name may be specified on the :manual:`cmake(1)` command line
+ with the ``-A`` option, e.g. ``-G "Visual Studio 12 2013" -A x64``.
+
+* The :variable:`CMAKE_GENERATOR_TOOLSET` variable may now be
+ initialized in a toolchain file specified by the
+ :variable:`CMAKE_TOOLCHAIN_FILE` variable. This is useful
+ when cross-compiling with the Xcode or Visual Studio
+ generators.
+
+* The :variable:`CMAKE_INSTALL_MESSAGE` variable was introduced to
+ optionally reduce output installation.
+
+Properties
+----------
+
+* New :prop_tgt:`CXX_STANDARD` and :prop_tgt:`CXX_EXTENSIONS` target
+ properties may specify values which CMake uses to compute required
+ compile options such as ``-std=c++11`` or ``-std=gnu++11``. The
+ :variable:`CMAKE_CXX_STANDARD` and :variable:`CMAKE_CXX_EXTENSIONS`
+ variables may be set to initialize the target properties.
+
+* New :prop_tgt:`C_STANDARD` and :prop_tgt:`C_EXTENSIONS` target
+ properties may specify values which CMake uses to compute required
+ compile options such as ``-std=c11`` or ``-std=gnu11``. The
+ :variable:`CMAKE_C_STANDARD` and :variable:`CMAKE_C_EXTENSIONS`
+ variables may be set to initialize the target properties.
+
+* New :prop_tgt:`COMPILE_FEATURES` target property may contain a list
+ of features required to compile a target. CMake uses this
+ information to ensure that the compiler in use is capable of building
+ the target, and to add any necessary compile flags to support language
+ features.
+
+* New :prop_tgt:`COMPILE_PDB_NAME` and
+ :prop_tgt:`COMPILE_PDB_OUTPUT_DIRECTORY` target properties
+ were introduced to specify the MSVC compiler program database
+ file location (``cl /Fd``). This complements the existing
+ :prop_tgt:`PDB_NAME` and :prop_tgt:`PDB_OUTPUT_DIRECTORY`
+ target properties that specify the linker program database
+ file location (``link /pdb``).
+
+* The :prop_tgt:`INTERFACE_LINK_LIBRARIES` target property now supports
+ a ``$<LINK_ONLY:...>``
+ :manual:`generator expression <cmake-generator-expressions(7)>`.
+
+* A new :prop_tgt:`INTERFACE_SOURCES` target property was introduced. This is
+ consumed by dependent targets, which compile and link the listed sources.
+
+* The :prop_tgt:`SOURCES` target property now contains
+ :manual:`generator expression <cmake-generator-expressions(7)>`
+ such as ``TARGET_OBJECTS`` when read at configure time, if
+ policy :policy:`CMP0051` is ``NEW``.
+
+* The :prop_tgt:`SOURCES` target property now generally supports
+ :manual:`generator expression <cmake-generator-expressions(7)>`. The
+ generator expressions may be used in the :command:`add_library` and
+ :command:`add_executable` commands.
+
+* It is now possible to write and append to the :prop_tgt:`SOURCES` target
+ property. The :variable:`CMAKE_DEBUG_TARGET_PROPERTIES` variable may be
+ used to trace the origin of sources.
+
+* A :prop_sf:`VS_DEPLOYMENT_CONTENT` source file property was added
+ to tell the Visual Studio generators to mark content for deployment
+ in Windows Phone and Windows Store projects.
+
+* A :prop_sf:`VS_DEPLOYMENT_LOCATION` source file property was added
+ to tell the Visual Studio generators the relative location of content
+ marked for deployment in Windows Phone and Windows Store projects.
+
+* The :prop_tgt:`VS_WINRT_COMPONENT` target property was created to
+ tell Visual Studio generators to compile a shared library as a
+ Windows Runtime (WinRT) component.
+
+* The :generator:`Xcode` generator learned to check source
+ file properties :prop_sf:`XCODE_EXPLICIT_FILE_TYPE` and
+ :prop_sf:`XCODE_LAST_KNOWN_FILE_TYPE` for a custom Xcode
+ file reference type.
+
+Modules
+-------
+
+* The :module:`BundleUtilities` module learned to resolve and replace
+ ``@rpath`` placeholders on OS X to correctly bundle applications
+ using them.
+
+* The :module:`CMakePackageConfigHelpers` module
+ :command:`configure_package_config_file` command learned a new
+ ``INSTALL_PREFIX`` option to generate package configuration files
+ meant for a prefix other than :variable:`CMAKE_INSTALL_PREFIX`.
+
+* The :module:`CheckFortranSourceCompiles` module was added to
+ provide a ``CHECK_Fortran_SOURCE_COMPILES`` macro.
+
+* The :module:`ExternalData` module learned to tolerate a ``DATA{}``
+ reference to a missing source file with a warning instead of
+ rejecting it with an error. This helps developers write new
+ ``DATA{}`` references to test reference outputs that have not
+ yet been created.
+
+* The :module:`ExternalProject` module learned to support lzma-compressed
+ source tarballs with ``.7z``, ``.tar.xz``, and ``.txz`` extensions.
+
+* The :module:`ExternalProject` module ``ExternalProject_Add`` command
+ learned a new ``BUILD_ALWAYS`` option to cause the external project
+ build step to run every time the host project is built.
+
+* The :module:`ExternalProject` module ``ExternalProject_Add`` command
+ learned a new ``EXCLUDE_FROM_ALL`` option to cause the external
+ project target to have the :prop_tgt:`EXCLUDE_FROM_ALL` target
+ property set.
+
+* The :module:`ExternalProject` module ``ExternalProject_Add_Step`` command
+ learned a new ``EXCLUDE_FROM_MAIN`` option to cause the step to not be
+ a direct dependency of the main external project target.
+
+* The :module:`ExternalProject` module ``ExternalProject_Add`` command
+ learned a new ``DOWNLOAD_NO_PROGRESS`` option to disable progress
+ output while downloading the source tarball.
+
+* The :module:`FeatureSummary` module ``feature_summary`` API
+ learned to accept multiple values for the ``WHAT`` option and
+ combine them appropriately.
+
+* The :module:`FindCUDA` module learned to support ``fatbin`` and ``cubin``
+ modules.
+
+* The :module:`FindGTest` module ``gtest_add_tests`` macro learned
+ a new ``AUTO`` option to automatically read the :prop_tgt:`SOURCES`
+ target property of the test executable and scan the source files
+ for tests to be added.
+
+* The :module:`FindGLEW` module now provides imported targets.
+
+* The :module:`FindGLUT` module now provides imported targets.
+
+* The :module:`FindHg` module gained a new ``Hg_WC_INFO`` macro to
+ help run ``hg`` to extract information about a Mercurial work copy.
+
+* The :module:`FindOpenCL` module was introduced.
+
+* The :module:`FindOpenMP` module learned to support Fortran.
+
+* The :module:`FindPkgConfig` module learned to use the ``PKG_CONFIG``
+ environment variable value as the ``pkg-config`` executable, if set.
+
+* The :module:`FindXercesC` module was introduced.
+
+* The :module:`FindZLIB` module now provides imported targets.
+
+* The :module:`GenerateExportHeader` module ``generate_export_header``
+ function learned to allow use with :ref:`Object Libraries`.
+
+* The :module:`InstallRequiredSystemLibraries` module gained a new
+ ``CMAKE_INSTALL_OPENMP_LIBRARIES`` option to install MSVC OpenMP
+ runtime libraries.
+
+* The :module:`UseSWIG` module learned to detect the module name
+ from ``.i`` source files if possible to avoid the need to set
+ the ``SWIG_MODULE_NAME`` source file property explicitly.
+
+* The :module:`WriteCompilerDetectionHeader` module was added to allow
+ creation of a portable header file for compiler optional feature detection.
+
+Generator Expressions
+---------------------
+
+* New ``COMPILE_FEATURES``
+ :manual:`generator expression <cmake-generator-expressions(7)>` allows
+ setting build properties based on available compiler features.
+
+CTest
+-----
+
+* The :command:`ctest_coverage` command learned to read variable
+ ``CTEST_COVERAGE_EXTRA_FLAGS`` to set ``CoverageExtraFlags``.
+
+* The :command:`ctest_coverage` command learned to support
+ Intel coverage files with the ``codecov`` tool.
+
+* The :command:`ctest_memcheck` command learned to support sanitizer
+ modes, including ``AddressSanitizer``, ``MemorySanitizer``,
+ ``ThreadSanitizer``, and ``UndefinedBehaviorSanitizer``.
+ Options may be set using the new
+ :variable:`CTEST_MEMORYCHECK_SANITIZER_OPTIONS` variable.
+
+CPack
+-----
+
+* :manual:`cpack(1)` gained an ``IFW`` generator to package using
+ Qt Framework Installer tools. See the :module:`CPackIFW` module.
+
+* :manual:`cpack(1)` gained ``7Z`` and ``TXZ`` generators supporting
+ lzma-compressed archives.
+
+* The :module:`CPackDeb` module learned a new
+ :variable:`CPACK_DEBIAN_COMPRESSION_TYPE` variable to set the
+ tarball compression type.
+
+* The :manual:`cpack(1)` ``WiX`` generator learned to support
+ a :prop_inst:`CPACK_WIX_ACL` installed file property to
+ specify an Access Control List.
+
+Other
+-----
+
+* The :manual:`cmake(1)` ``-E`` option learned a new ``env`` command.
+
+* The :manual:`cmake(1)` ``-E tar`` command learned to support
+ lzma-compressed files.
+
+* :ref:`Object Libraries` may now have extra sources that do not
+ compile to object files so long as they would not affect linking
+ of a normal library (e.g. ``.dat`` is okay but not ``.def``).
+
+* Visual Studio generators for VS 8 and later learned to support
+ the ``ASM_MASM`` language.
+
+* The Visual Studio generators learned to treat ``.hlsl`` source
+ files as High Level Shading Language sources (using ``FXCompile``
+ in ``.vcxproj`` files). Source file properties
+ :prop_sf:`VS_SHADER_TYPE`, :prop_sf:`VS_SHADER_MODEL`, and
+ :prop_sf:`VS_SHADER_ENTRYPOINT` were added added to specify the
+ shader type, model, and entry point name.
+
+New Diagnostics
+===============
+
+* Policy :policy:`CMP0052` introduced to control directories in the
+ :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` of exported targets.
+
+Deprecated and Removed Features
+===============================
+
+* In CMake 3.0 the :command:`target_link_libraries` command
+ accidentally began allowing unquoted arguments to use
+ :manual:`generator expressions <cmake-generator-expressions(7)>`
+ containing a (``;`` separated) list within them. For example::
+
+ set(libs B C)
+ target_link_libraries(A PUBLIC $<BUILD_INTERFACE:${libs}>)
+
+ This is equivalent to writing::
+
+ target_link_libraries(A PUBLIC $<BUILD_INTERFACE:B C>)
+
+ and was never intended to work. It did not work in CMake 2.8.12.
+ Such generator expressions should be in quoted arguments::
+
+ set(libs B C)
+ target_link_libraries(A PUBLIC "$<BUILD_INTERFACE:${libs}>")
+
+ CMake 3.1 again requires the quotes for this to work correctly.
+
+* Prior to CMake 3.1 the Makefile generators did not escape ``#``
+ correctly inside make variable assignments used in generated
+ makefiles, causing them to be treated as comments. This made
+ code like::
+
+ add_compile_options(-Wno-#pragma-messages)
+
+ not work in Makefile generators, but work in other generators.
+ Now it is escaped correctly, making the behavior consistent
+ across generators. However, some projects may have tried to
+ workaround the original bug with code like::
+
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-\\#pragma-messages")
+
+ This added the needed escape for Makefile generators but also
+ caused other generators to pass ``-Wno-\#pragma-messages`` to
+ the shell, which would work only in POSIX shells.
+ Unfortunately the escaping fix could not be made in a compatible
+ way so this platform- and generator-specific workaround no
+ longer works. Project code may test the :variable:`CMAKE_VERSION`
+ variable value to make the workaround version-specific too.
+
+* Callbacks established by the :command:`variable_watch` command will no
+ longer receive the ``ALLOWED_UNKNOWN_READ_ACCESS`` access type when
+ the undocumented ``CMAKE_ALLOW_UNKNOWN_VARIABLE_READ_ACCESS`` variable is
+ set. Uninitialized variable accesses will always be reported as
+ ``UNKNOWN_READ_ACCESS``.
+
+* The :module:`CMakeDetermineVSServicePack` module now warns that
+ it is deprecated and should not longer be used. Use the
+ :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable instead.
+
+* The :module:`FindITK` module has been removed altogether.
+ It was a thin-wrapper around ``find_package(ITK ... NO_MODULE)``.
+ This produces much clearer error messages when ITK is not found.
+
+* The :module:`FindVTK` module has been removed altogether.
+ It was a thin-wrapper around ``find_package(VTK ... NO_MODULE)``.
+ This produces much clearer error messages when VTK is not found.
+
+ The module also provided compatibility support for finding VTK 4.0.
+ This capability has been dropped.
+
+Other Changes
+=============
+
+* The :manual:`cmake-gui(1)` learned to capture output from child
+ processes started by the :command:`execute_process` command
+ and display it in the output window.
+
+* The :manual:`cmake-language(7)` internal implementation of generator
+ expression and list expansion parsers have been optimized and shows
+ non-trivial speedup on large projects.
+
+* The Makefile generators learned to use response files with GNU tools
+ on Windows to pass library directories and names to the linker.
+
+* When generating linker command-lines, CMake now avoids repeating
+ items corresponding to SHARED library targets.
+
+* Support for the Open Watcom compiler has been overhauled.
+ The :variable:`CMAKE_<LANG>_COMPILER_ID` is now ``OpenWatcom``,
+ and the :variable:`CMAKE_<LANG>_COMPILER_VERSION` now uses
+ the Open Watcom external version numbering. The external
+ version numbers are lower than the internal version number
+ by 11.
+
+* The ``cmake-mode.el`` major Emacs editing mode no longer
+ treats ``_`` as part of words, making it more consistent
+ with other major modes.
diff --git a/Help/release/3.2.rst b/Help/release/3.2.rst
new file mode 100644
index 000000000..8abb1ca62
--- /dev/null
+++ b/Help/release/3.2.rst
@@ -0,0 +1,277 @@
+CMake 3.2 Release Notes
+***********************
+
+.. only:: html
+
+ .. contents::
+
+Changes made since CMake 3.1 include the following.
+
+New Features
+============
+
+Syntax
+------
+
+* CMake learned to support unicode characters
+ :ref:`encoded as UTF-8 <CMake Language Encoding>`
+ on Windows. This was already supported on platforms whose
+ system APIs accept UTF-8 encoded strings.
+ Unicode characters may now be used in CMake code, paths to
+ source files, configured files such as ``.h.in`` files, and
+ other files read and written by CMake. Note that because CMake
+ interoperates with many other tools, there may still be some
+ limitations when using certain unicode characters.
+
+Commands
+--------
+
+* The :command:`add_custom_command` and :command:`add_custom_target`
+ commands learned a new ``BYPRODUCTS`` option to specify files
+ produced as side effects of the custom commands. These are not
+ outputs because they do not always have to be newer than inputs.
+
+* The :command:`add_custom_command` and :command:`add_custom_target`
+ commands learned a new ``USES_TERMINAL`` option to request that
+ the command be given direct access to the terminal if possible.
+ The :generator:`Ninja` generator will places such commands in the
+ ``console`` :prop_gbl:`pool <JOB_POOLS>`. Build targets provided by CMake
+ that are meant for individual interactive use, such as ``install``, are now
+ placed in this pool.
+
+* A new :command:`continue` command was added that can be called inside loop
+ contexts to end the current iteration and start the next one at the top of
+ the loop block.
+
+* The :command:`file(LOCK)` subcommand was created to allow CMake
+ processes to synchronize through file and directory locks.
+
+* The :command:`file(STRINGS)` now supports UTF-16LE, UTF-16BE,
+ UTF-32LE, UTF-32BE as ``ENCODING`` options.
+
+* The :command:`install(EXPORT)` command now works with an absolute
+ ``DESTINATION`` even if targets in the export set are installed
+ with a destination or :ref:`usage requirements <Target Usage Requirements>`
+ specified relative to the install prefix. The value of the
+ :variable:`CMAKE_INSTALL_PREFIX` variable is hard-coded into the installed
+ export file as the base for relative references.
+
+* The :command:`try_compile` command source file signature now honors
+ link flags (e.g. :variable:`CMAKE_EXE_LINKER_FLAGS`) in the generated
+ test project. See policy :policy:`CMP0056`.
+
+* The :command:`try_run` command learned to honor the ``LINK_LIBRARIES``
+ option just as :command:`try_compile` already does.
+
+* The :command:`file(GENERATE)` command now generates the output file with
+ the same permissions as the input file if set.
+
+* The :command:`file(GENERATE)` command can now generate files which are
+ used as source files for buildsystem targets. Generated files
+ automatically get their :prop_sf:`GENERATED` property set to ``TRUE``.
+
+Variables
+---------
+
+* The :variable:`CMAKE_MATCH_COUNT` variable was introduced to record the
+ number of matches made in the last regular expression matched in an
+ :command:`if` command or a :command:`string` command.
+
+Properties
+----------
+
+* An :prop_tgt:`ANDROID_API_MIN` target property was introduced to
+ specify the minimum version to be targeted by the toolchain.
+
+* A :prop_sf:`VS_SHADER_FLAGS` source file property was added to specify
+ additional shader flags to ``.hlsl`` files, for the Visual Studio
+ generators.
+
+Modules
+-------
+
+* The :module:`ExternalData` module learned to support
+ :ref:`Custom Fetch Scripts <ExternalData Custom Fetch Scripts>`.
+ This allows projects to specify custom ``.cmake`` scripts for
+ fetching data objects during the build.
+
+* The :module:`ExternalProject` module learned options to create
+ independent external project step targets that do not depend
+ on the builtin steps.
+
+* The :module:`ExternalProject` module :command:`ExternalProject_Add`
+ command learned a new ``CMAKE_CACHE_DEFAULT_ARGS`` option to
+ initialize cache values in the external project without setting
+ them on future builds.
+
+* The :module:`ExternalProject` module :command:`ExternalProject_Add`
+ command learned a new ``TEST_EXCLUDE_FROM_MAIN`` option to exclude
+ tests from the main build.
+
+* The :module:`ExternalProject` module :command:`ExternalProject_Add`
+ command learned a new ``UPDATE_DISCONNECTED`` option to avoid
+ automatically updating the source tree checkout from version control.
+
+* The :module:`FindCUDA` module learned about the ``cusolver``
+ library in CUDA 7.0.
+
+* The :module:`FindGit` module learned to find the ``git`` command-line tool
+ that comes with GitHub for Windows installed in user home directories.
+
+* A :module:`FindGSL` module was introduced to find the
+ GNU Scientific Library.
+
+* A :module:`FindIntl` module was introduced to find the
+ Gettext ``libintl`` library.
+
+* The :module:`FindLATEX` module learned to support components.
+
+* The :module:`FindMPI` module learned to find MS-MPI on Windows.
+
+* The :module:`FindOpenSSL` module now reports ``crypto`` and ``ssl``
+ libraries separately in ``OPENSSL_CRYPTO_LIBRARY`` and
+ ``OPENSSL_SSL_LIBRARY``, respectively, to allow applications to
+ link to one without the other.
+
+* The :module:`WriteCompilerDetectionHeader` module learned to
+ create a define for portability of the ``cxx_thread_local`` feature.
+ The define expands to either the C++11 ``thread_local`` keyword, or a
+ pre-standardization compiler-specific equivalent, as appropriate.
+
+* The :module:`WriteCompilerDetectionHeader` module learned to create
+ multiple output files per compiler and per language, instead of creating
+ one large file.
+
+CTest
+-----
+
+* The :command:`ctest_coverage` command learned to support Delphi coverage.
+
+* The :command:`ctest_coverage` command learned to support Javascript coverage.
+
+* The :module:`CTestCoverageCollectGCOV` module was introduced as an
+ alternative to the :command:`ctest_coverage` command for collecting
+ ``gcov`` results for submission to CDash.
+
+CPack
+-----
+
+* The :module:`CPackRPM` module learned options to set per-component
+ descriptions and summaries. See the
+ :variable:`CPACK_RPM_<component>_PACKAGE_DESCRIPTION` and
+ :variable:`CPACK_RPM_<component>_PACKAGE_SUMMARY` variables.
+
+* The :module:`CPackRPM` module learned options to specify
+ requirements for pre- and post-install scripts. See the
+ :variable:`CPACK_RPM_PACKAGE_REQUIRES_PRE` and
+ :variable:`CPACK_RPM_PACKAGE_REQUIRES_POST` variables.
+
+* The :module:`CPackRPM` module learned options to specify
+ requirements for pre- and post-uninstall scripts. See the
+ :variable:`CPACK_RPM_PACKAGE_REQUIRES_PREUN` and
+ :variable:`CPACK_RPM_PACKAGE_REQUIRES_POSTUN` variables.
+
+* The :module:`CPackRPM` module learned a new
+ :variable:`CPACK_RPM_<COMPONENT>_PACKAGE_PREFIX` variable to
+ specify a component-specific value to use instead of
+ :variable:`CPACK_PACKAGING_INSTALL_PREFIX`.
+
+* The :module:`CPackRPM` module learned a new
+ :variable:`CPACK_RPM_RELOCATION_PATHS` variable to
+ specify multiple relocation prefixes for a single rpm package.
+
+Other
+-----
+
+* The :manual:`cmake(1)` ``-E tar`` command now supports creating
+ ``.xz``-compressed archives with the ``J`` flag.
+
+* The :manual:`cmake(1)` ``-E tar`` command learned a new
+ ``--files-from=<file>`` option to specify file names using
+ lines in a file to overcome command-line length limits.
+
+* The :manual:`cmake(1)` ``-E tar`` command learned a new
+ ``--mtime=<date>`` option to specify the modification time
+ recorded in tarball entries.
+
+* The :manual:`Compile Features <cmake-compile-features(7)>` functionality
+ is now aware of features supported by more compilers, including:
+
+ * Apple Clang (``AppleClang``) for Xcode versions 4.4 though 6.1.
+ * GNU compiler versions 4.4 through 5.0 on UNIX and Apple (``GNU``).
+ * Microsoft Visual Studio (``MSVC``) for versions 2010 through 2015.
+ * Oracle SolarisStudio (``SunPro``) version 12.4.
+
+* The :ref:`Qt AUTORCC` feature now tracks files listed in ``.qrc`` files
+ as dependencies. If an input file to the ``rcc`` tool is changed, the tool
+ is automatically re-run.
+
+New Diagnostics
+===============
+
+* The :command:`break` command now rejects calls outside of a loop
+ context or that pass arguments to the command.
+ See policy :policy:`CMP0055`.
+
+Deprecated and Removed Features
+===============================
+
+* Files written in the :manual:`cmake-language(7)`, such as
+ ``CMakeLists.txt`` or ``*.cmake`` files, are now expected to be
+ encoded as UTF-8. If files are already ASCII, they will be
+ compatible. If files were in a different encoding, including
+ Latin 1, they will need to be converted.
+
+* The :module:`FindOpenGL` module no longer explicitly searches
+ for any dependency on X11 libraries with the :module:`FindX11`
+ module. Such dependencies should not need to be explicit.
+ Applications using X11 APIs themselves should find and link
+ to X11 libraries explicitly.
+
+* The implementation of CMake now relies on some C++ compiler features which
+ are not supported by some older compilers. As a result, those old compilers
+ can no longer be used to build CMake itself. CMake continues to be able to
+ generate Makefiles and project files for users of those old compilers
+ however. Compilers known to no longer be capable of building CMake are:
+
+ * Visual Studio 6 and 7.0 -- superseded by VisualStudio 7.1 and newer.
+ * GCC 2.95 -- superseded by GCC 3 and newer compilers.
+ * Borland compilers -- superseded by other Windows compilers.
+ * Compaq compilers -- superseded by other compilers.
+ * SGI compilers -- IRIX was dropped as a host platform.
+
+Other Changes
+=============
+
+* On Windows and OS X, commands supporting network communication
+ via ``https``, such as :command:`file(DOWNLOAD)`,
+ :command:`file(UPLOAD)`, and :command:`ctest_submit`, now support
+ SSL/TLS even when CMake is not built against OpenSSL.
+ The Windows or OS X native SSL/TLS implementation is used by default.
+ OS-configured certificate authorities will be trusted automatically.
+
+ On other platforms, when CMake is built with OpenSSL, these
+ commands now search for OS-configured certificate authorities
+ in a few ``/etc`` paths to be trusted automatically.
+
+* On OS X with Makefile and Ninja generators, when a compiler is found
+ in ``/usr/bin`` it is now mapped to the corresponding compiler inside
+ the Xcode application folder, if any. This allows such build
+ trees to continue to work with their original compiler even when
+ ``xcode-select`` switches to a different Xcode installation.
+
+* The Visual Studio generators now write solution and project
+ files in UTF-8 instead of Windows-1252. Windows-1252 supported
+ Latin 1 languages such as those found in North and South America
+ and Western Europe. With UTF-8, additional languages are now
+ supported.
+
+* The :generator:`Xcode` generator no longer requires a value for
+ the :variable:`CMAKE_MAKE_PROGRAM` variable to be located up front.
+ It now locates ``xcodebuild`` when needed at build time.
+
+* When building CMake itself using SolarisStudio 12, the default ``libCStd``
+ standard library is not sufficient to build CMake. The SolarisStudio
+ distribution supports compiler options to use ``STLPort4`` or ``libstdc++``.
+ An appropriate option to select the standard library is now added
+ automatically when building CMake with SolarisStudio compilers.
diff --git a/Help/release/3.3.rst b/Help/release/3.3.rst
new file mode 100644
index 000000000..0beb354ac
--- /dev/null
+++ b/Help/release/3.3.rst
@@ -0,0 +1,287 @@
+CMake 3.3 Release Notes
+***********************
+
+.. only:: html
+
+ .. contents::
+
+Changes made since CMake 3.2 include the following.
+
+New Features
+============
+
+Generators
+----------
+
+* The :ref:`Makefile Generators` now add ``.DELETE_ON_ERROR`` to the
+ makefiles that contain the actual build rules for files on disk.
+ This tells GNU make to remove rule outputs when their recipe
+ modifies an output but fails.
+
+* The :ref:`Visual Studio Generators` learned to support ``.xaml``
+ source files and automatically associate them with corresponding
+ ``.h`` and ``.cpp`` sources.
+
+* A new experimental :generator:`Green Hills MULTI` generator was
+ added on Windows. `Green Hills MULTI`_ is an IDE for embedded
+ real-time systems.
+
+.. _`Green Hills MULTI`: http://www.ghs.com/products/MULTI_IDE.html
+
+Commands
+--------
+
+* The :command:`add_dependencies` command learned to allow dependencies
+ to be added to :ref:`interface libraries <Interface Libraries>`.
+ Dependencies added to an interface library are followed transitively
+ in its place since the target itself does not build.
+
+* The :command:`execute_process` command learned to support specifying
+ the same file for ``OUTPUT_FILE`` and ``ERROR_FILE``.
+
+* The :command:`file(GLOB)` and :command:`file(GLOB_RECURSE)` commands
+ learned a new ``LIST_DIRECTORIES <bool>`` option to specify whether
+ the glob result should include directories.
+
+* The :command:`find_library`, :command:`find_path`, and :command:`find_file`
+ commands now search in installation prefixes derived from the ``PATH``
+ environment variable.
+
+* The :command:`if` command learned a new ``IN_LIST`` operator that
+ evaluates to true if a given element is contained in a named list.
+
+* The :command:`install(EXPORT)` and :command:`export()` commands
+ learned to export targets that populate the :prop_tgt:`INTERFACE_SOURCES`
+ target property.
+
+* The :command:`install(TARGETS)` command learned to support
+ generator expressions in the ``DESTINATION`` value.
+
+Variables
+---------
+
+* The version of some Fortran compilers is now detected and stored in the
+ :variable:`CMAKE_Fortran_COMPILER_VERSION <CMAKE_<LANG>_COMPILER_VERSION>`
+ variable.
+
+* The :ref:`Visual Studio Generators` learned a new
+ :variable:`CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD` option
+ to put the ``INSTALL`` target in the default build of a
+ solution (``.sln``) file.
+
+Properties
+----------
+
+* A :prop_tgt:`CROSSCOMPILING_EMULATOR` target property and supporting
+ :variable:`CMAKE_CROSSCOMPILING_EMULATOR` variable were introduced
+ to allow target platform binaries to run on the host during cross
+ compiling.
+
+* A :prop_tgt:`<LANG>_INCLUDE_WHAT_YOU_USE` target property and supporting
+ :variable:`CMAKE_<LANG>_INCLUDE_WHAT_YOU_USE` variable were introduced
+ to tell the :ref:`Makefile Generators` and the :generator:`Ninja` generator
+ to run ``include-what-you-use`` along with the compiler for ``C`` and
+ ``CXX`` languages.
+
+* The :prop_tgt:`<LANG>_VISIBILITY_PRESET` and
+ :prop_tgt:`VISIBILITY_INLINES_HIDDEN` target properties now
+ affect compilation in sources of all target types. See
+ policy :policy:`CMP0063`.
+
+* The :prop_tgt:`XCODE_ATTRIBUTE_<an-attribute>` target property learned
+ to support generator expressions.
+
+Modules
+-------
+
+* The :module:`CheckFortranCompilerFlag` module was introduced
+ to check ``Fortran`` compiler flags, much like the
+ :module:`CheckCCompilerFlag` module already does for ``C``.
+
+* The :module:`ExternalData` module learned a new
+ :variable:`ExternalData_NO_SYMLINKS` option to disable use of
+ symbolic links to populate the real data files and use copies
+ instead.
+
+* The :module:`ExternalData` module learned a new ``RECURSE:``
+ option in ``DATA{}`` references specifying directories.
+ This allows an entire directory tree of associated files
+ to be matched.
+
+* The :module:`ExternalData` module learned a new URL template
+ placeholder ``%(algo:<key>)`` to allow custom mapping from
+ algorithm name to URL component through configuration of new
+ :variable:`ExternalData_URL_ALGO_<algo>_<key>` variables.
+ This allows more flexibility in remote URLs.
+
+* The :module:`ExternalProject` module learned to replace tokens
+ like ``<BINARY_DIR>`` in the ``BYPRODUCTS`` of each step.
+
+* The :module:`ExternalProject` module APIs learned to support
+ :manual:`generator expressions <cmake-generator-expressions(7)>`
+ when using ``LOG_*`` options and in CMake initial cache options.
+
+* The :module:`FindBoost` module now tracks the directories containing
+ libraries separately for RELEASE and DEBUG configurations.
+
+* The :module:`FindCUDA` module now defaults to using the static
+ CUDA runtime library if it is available. A new
+ ``CUDA_USE_STATIC_CUDA_RUNTIME`` option is offered to control
+ this behavior.
+
+* The :module:`FindMatlab` module was completely rewritten. It learned
+ about versions and components and to find Matlab in a more precise and
+ multiplatform way. The module now offers APIs to create mex extensions,
+ documentation, and unit tests.
+
+* The :module:`FindPackageHandleStandardArgs` module
+ ``FIND_PACKAGE_HANDLE_STANDARD_ARGS`` function now
+ always populates both the ``<PackageName>_FOUND``
+ and ``<UPPERCASE_NAME>_FOUND`` variables (the latter
+ for backwards compatibility). The ``FOUND_VAR``
+ option is now ignored except to enforce its allowed
+ values.
+
+* The :module:`InstallRequiredSystemLibraries` module learned a new
+ ``CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT`` option to specify the
+ installation component.
+
+Generator Expressions
+---------------------
+
+* A new ``COMPILE_LANGUAGE`` generator expression was introduced to
+ allow specification of compile options for target files based on the
+ :prop_sf:`LANGUAGE` of each source file. Due to limitations of the
+ underlying native build tools, this feature has varying support across
+ generators. See the :manual:`cmake-generator-expressions(7)` manual
+ for details.
+
+CTest
+-----
+
+* The :manual:`ctest(1)` tool learned a new ``--repeat-until-fail <n>``
+ option to help find sporadic test failures.
+
+* The :module:`CTestCoverageCollectGCOV` module learned to support
+ the same ``CTEST_CUSTOM_COVERAGE_EXCLUDE`` option as the
+ :command:`ctest_coverage` command.
+
+CPack
+-----
+
+* The :manual:`cpack(1)` ``IFW`` generator and the :module:`CPackIFW`
+ module learned to support Qt Framework Installer 2.0 tools.
+
+* The :module:`CPackDeb` module learned a new
+ :variable:`CPACK_DEBIAN_<COMPONENT>_PACKAGE_SHLIBDEPS`
+ variable to specify per-component use of ``dpkg-shlibdeps``.
+
+* The :module:`CPackDeb` module learned a new
+ :variable:`CPACK_DEBIAN_<COMPONENT>_PACKAGE_DEPENDS`
+ option to specify per-component dependencies.
+
+* The :module:`CPackRPM` module learned to package symbolic links
+ more cleanly and now supports directory symlinks with recent
+ ``rpmbuild`` versions.
+
+* The :module:`CPackRPM` module learned a new
+ :variable:`CPACK_RPM_ADDITIONAL_MAN_DIRS` variable to specify
+ directories containing man pages for the brp-compress RPM macro.
+
+* The :module:`CPackRPM` module learned a new
+ :variable:`CPACK_RPM_<component>_PACKAGE_ARCHITECTURE` variable
+ to specify a component-specific package architecture.
+
+* The CPack WIX generator learned the new
+ :prop_inst:`CPACK_START_MENU_SHORTCUTS`,
+ :prop_inst:`CPACK_DESKTOP_SHORTCUTS` and
+ :prop_inst:`CPACK_STARTUP_SHORTCUTS` installed file properties which can
+ be used to install shorcuts in the Start Menu, on the Desktop and
+ in the Startup Folder respectively.
+
+Other
+-----
+
+* The :manual:`Compile Features <cmake-compile-features(7)>` functionality
+ is now aware of features supported by GNU compilers on Windows, versions
+ 4.4 through 5.0.
+
+* The :manual:`cmake(1)` ``-E tar`` command learned a new
+ ``--format<format>`` option to specify the archive format to
+ be written.
+
+* On OS X, CMake learned to create XCTest bundles to test Frameworks
+ and App Bundles within Xcode. The :module:`FindXCTest` module
+ provides convenience functions to handle :prop_tgt:`XCTEST` bundles.
+
+Deprecated and Removed Features
+===============================
+
+* On OS X the :manual:`cmake-gui(1)` no longer has the
+ ``Install For Command Line Use`` menu item. Instead there
+ is a ``How to Install For Command Line Use`` menu item
+ that shows an informational dialog box explaining how to
+ make the command line tools available. For example::
+
+ /Applications/CMake.app/Contents/bin/cmake-gui --install
+
+* The :command:`ctest_build` and :command:`build_command` commands
+ no longer tell ``make`` tools to ignore errors with the ``-i`` option.
+ Previously this was done for :ref:`Makefile Generators` but not others.
+ See policy :policy:`CMP0061`.
+
+* The :generator:`Visual Studio 10 2010` generator no longer checks
+ for running VS IDEs with the project open or asks them to reload.
+ This was originally done for VS 10 because it had been done for
+ VS 7 through 9 to avoid prompting for every project in a solution.
+ Since VS >= 10 allow the whole solution to reload at once they
+ do not need CMake to help them.
+
+* The :generator:`Visual Studio 7` generator (.NET 2002) is now
+ deprecated and will be removed in a future version of CMake.
+
+* The :generator:`Visual Studio 6` generator is now deprecated
+ and will be removed in a future version of CMake.
+
+* The :command:`find_package` command no longer considers project
+ build trees recently configured in a :manual:`cmake-gui(1)`.
+ This was previously done only on Windows and is now never done.
+ The ``NO_CMAKE_BUILDS_PATH`` option is now ignored if given
+ and effectively always on.
+ Projects may populate the :ref:`User Package Registry` to aid
+ users building multiple dependent projects one after another.
+
+* The :command:`add_definitions()` command no longer causes a
+ :prop_dir:`DEFINITIONS` directory property to be populated. See policy
+ :policy:`CMP0059`.
+
+* With Visual Studio 7, 8, and 9 generators the value of the ``$(OutDir)``
+ placeholder no longer evaluates to the configuration name. Projects
+ should use ``$(ConfigurationName)`` for that instead.
+
+* Using the output of :command:`export()` with the :command:`install(FILES)`
+ command is no longer allowed. See policy :policy:`CMP0062` for details.
+
+Other Changes
+=============
+
+* The :generator:`Ninja` generator now requires that calls to the
+ :command:`add_custom_command` and :command:`add_custom_target`
+ commands use the ``BYPRODUCTS`` option to explicitly specify any
+ files generated by the custom commands that are not listed as
+ outputs (perhaps because their timestamps are allowed to be older
+ than the inputs). See policy :policy:`CMP0058`.
+
+* Build-time progress output of :ref:`Makefile Generators` has been improved.
+ It no longer mixes progress and build rule messages during parallel builds.
+ The link rule messages now have progress and are displayed as bold green
+ instead of bold red (since red is often associated with an error message).
+
+* The :variable:`CMAKE_CFG_INTDIR` variable value for Visual Studio
+ 7, 8, and 9 is now ``$(ConfigurationName)`` instead of ``$(OutDir)``.
+ This should have no effect on the intended use cases of the variable.
+
+* Linking to library files by a full path in an implicit linker search
+ directory (e.g. ``/usr/lib/libfoo.a``) no longer asks the linker to
+ search for the library (e.g. ``-lfoo``) and now links by full path.
+ See policy :policy:`CMP0060`.
diff --git a/Help/release/3.4.rst b/Help/release/3.4.rst
new file mode 100644
index 000000000..89c5561d3
--- /dev/null
+++ b/Help/release/3.4.rst
@@ -0,0 +1,273 @@
+CMake 3.4 Release Notes
+***********************
+
+.. only:: html
+
+ .. contents::
+
+Changes made since CMake 3.3 include the following.
+
+New Features
+============
+
+Generators
+----------
+
+* The :generator:`Visual Studio 14 2015` generator learned to select
+ a Windows 10 SDK based on the value of the :variable:`CMAKE_SYSTEM_VERSION`
+ variable and the SDKs available on the host.
+
+* CMake learned rudimentary support for the Apple Swift language. When using
+ the :generator:`Xcode` generator with Xcode 6.1 or higher, one may enable
+ the ``Swift`` language with the :command:`enable_language` command or the
+ :command:`project` command (this is an error with other generators or when
+ Xcode is too old). Then one may list ``.swift`` source files in targets
+ for compilation.
+
+Commands
+--------
+
+* The :command:`find_program` command learned a ``NAMES_PER_DIR``
+ option to consider all given ``NAMES`` in each directory before
+ moving on to the next directory.
+
+* The :command:`get_filename_component` command learned a new ``BASE_DIR``
+ subcommand. This is used to specify a base directory when calculating an
+ absolute path from a relative path.
+
+* The :command:`if` command learned a new ``TEST`` operator that evaluates
+ to true if a given test name has been defined by the :command:`add_test`
+ command. See policy :policy:`CMP0064`.
+
+* The :command:`install(DIRECTORY)` command ``DESTINATION`` option learned to
+ support :manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+* The :command:`install(FILES)` command ``DESTINATION`` option learned to
+ support :manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+* The :command:`string` command learned a new ``APPEND`` subcommand.
+
+Variables
+---------
+
+* The :ref:`Makefile Generators` and the :generator:`Ninja` generator
+ learned to add compiler launcher tools like distcc and ccache along
+ with the compiler for ``C`` and ``CXX`` languages. See the
+ :variable:`CMAKE_<LANG>_COMPILER_LAUNCHER` variable and
+ :prop_tgt:`<LANG>_COMPILER_LAUNCHER` target property for details.
+
+* New :variable:`CMAKE_LINK_SEARCH_START_STATIC` and
+ :variable:`CMAKE_LINK_SEARCH_END_STATIC` variables were
+ introduced to initialize the
+ :prop_tgt:`LINK_SEARCH_START_STATIC` and
+ :prop_tgt:`LINK_SEARCH_END_STATIC` target properties,
+ respectively.
+
+Properties
+----------
+
+* :ref:`Visual Studio Generators` learned to support additonal
+ target properties to customize projects for NVIDIA Nsight
+ Tegra Visual Studio Edition:
+
+ * :prop_tgt:`ANDROID_ANT_ADDITIONAL_OPTIONS`
+ * :prop_tgt:`ANDROID_ARCH`
+ * :prop_tgt:`ANDROID_ASSETS_DIRECTORIES`
+ * :prop_tgt:`ANDROID_JAR_DEPENDENCIES`
+ * :prop_tgt:`ANDROID_JAR_DIRECTORIES`
+ * :prop_tgt:`ANDROID_JAVA_SOURCE_DIR`
+ * :prop_tgt:`ANDROID_NATIVE_LIB_DEPENDENCIES`
+ * :prop_tgt:`ANDROID_NATIVE_LIB_DIRECTORIES`
+ * :prop_tgt:`ANDROID_PROCESS_MAX`
+ * :prop_tgt:`ANDROID_PROGUARD`
+ * :prop_tgt:`ANDROID_PROGUARD_CONFIG_PATH`
+ * :prop_tgt:`ANDROID_SECURE_PROPS_PATH`
+ * :prop_tgt:`ANDROID_SKIP_ANT_STEP`
+ * :prop_tgt:`ANDROID_STL_TYPE`
+
+* The :prop_tgt:`ARCHIVE_OUTPUT_DIRECTORY`,
+ :prop_tgt:`LIBRARY_OUTPUT_DIRECTORY`, and
+ :prop_tgt:`RUNTIME_OUTPUT_DIRECTORY` target properties learned to
+ support :manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+* The :prop_tgt:`SOURCE_DIR` and :prop_tgt:`BINARY_DIR` target properties
+ were introduced to allow project code to query where a target is defined.
+
+* The :prop_tgt:`OUTPUT_NAME` target property and its variants learned to
+ support :manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+* A :prop_gbl:`TARGET_MESSAGES` global property was added to tell the
+ :ref:`Makefile Generators` whether to generate commands to print output
+ after each target is completed.
+
+* On Windows with MS-compatible tools, CMake learned to optionally
+ generate a module definition (``.def``) file for ``SHARED`` libraries.
+ See the :prop_tgt:`WINDOWS_EXPORT_ALL_SYMBOLS` target property.
+
+Modules
+-------
+
+* The :module:`ExternalProject` module :command:`ExternalProject_Add`
+ function ``GIT_SUBMODULES`` option now also limits the set of
+ submodules that are initialized in addition to the prior behavior
+ of limiting the set of submodules that are updated.
+
+* The :module:`ExternalProject` module learned new ``USES_TERMINAL``
+ arguments for giving steps exclusive terminal access. This is
+ useful with the :generator:`Ninja` generator to monitor CMake
+ superbuild progress and prevent CPU oversubscription.
+
+* The :module:`FindBISON` module ``BISON_TARGET`` macro learned a
+ new ``DEFINES_FILE`` option to specify a custom output header
+ to be generated.
+
+* The :module:`FindHDF5` module learend a new ``HDF5_PREFER_PARALLEL``
+ option allowing users to specify that a parallel HDF5 tool is
+ preferred if both are available.
+
+* The :module:`FindIce` module now provides imported targets.
+
+* The :module:`FindJava` module learned to optionally find
+ the ``idlj`` and ``jarsigner`` tools.
+
+* The :module:`FindOpenSSL` module now provides imported targets.
+
+* The :module:`FindOpenSSL` module learned a new ``OPENSSL_USE_STATIC_LIBS``
+ option to search only for static libraries.
+
+* The :module:`FindPkgConfig` learned a new :command:`pkg_get_variable`
+ command which may be used to query for arbitrary variables from a package
+ (such as for related tools or data and plugin install paths).
+
+* The :module:`FindProtobuf` module gained a new
+ :command:`protobuf_generate_python` function to generate python
+ sources from ``.proto`` files.
+
+* The :module:`FindTIFF` module learned to search separately for
+ debug and release variants.
+
+* The :module:`FindwxWidgets` module learned to support version requests.
+
+* The :module:`FindXercesC` module learned to search separately for
+ debug and release variants.
+
+* The :module:`FindZLIB` module learned to search separately for
+ debug and release variants.
+
+* The :module:`GNUInstallDirs` module learned special default values
+ for certain installation prefixes according to the `GNU Coding
+ Standards`_ and the `Filesystem Hierarchy Standard`_.
+
+* The :module:`UseJava` module ``add_jar`` function learned
+ to support response files (e.g. ``@srcs.txt``) for source
+ specification.
+
+* The :module:`UseJava` module ``install_jar`` function learned
+ new ``DESTINATION`` and ``COMPONENT`` options to specify
+ the corresponding :command:`install` command options.
+
+* The :module:`UseJava` module gained a new ``create_javah``
+ function to create C headers from Java classes.
+
+.. _`GNU Coding Standards`: https://www.gnu.org/prep/standards/html_node/Directory-Variables.html
+.. _`Filesystem Hierarchy Standard`: https://refspecs.linuxfoundation.org/FHS_3.0/fhs/index.html
+
+Generator Expressions
+---------------------
+
+* A new ``$<SHELL_PATH:...>``
+ :manual:`generator expression <cmake-generator-expressions(7)>`
+ has been added.
+
+CTest
+-----
+
+* CTest learned to optionally measure the CPU load during parallel
+ testing and avoid starting tests that may cause the load to exceed
+ a given threshold. See the :manual:`ctest(1)` command ``--test-load``
+ option, the ``TestLoad`` setting of the :ref:`CTest Test Step`,
+ the :variable:`CTEST_TEST_LOAD` variable, and the ``TEST_LOAD``
+ option of the :command:`ctest_test` command.
+
+* :manual:`ctest(1)` learned options
+ ``--test-output-size-passed`` and ``--test-output-size-failed``
+ to customize the limit on test output size submitted when
+ running as a :ref:`Dashboard Client`.
+
+CPack
+-----
+
+* The :module:`CPackDeb` module learned to set package dependencies
+ per component. See variables:
+
+ * :variable:`CPACK_DEBIAN_<COMPONENT>_PACKAGE_BREAKS`
+ * :variable:`CPACK_DEBIAN_<COMPONENT>_PACKAGE_CONFLICTS`
+ * :variable:`CPACK_DEBIAN_<COMPONENT>_PACKAGE_ENHANCES`
+ * :variable:`CPACK_DEBIAN_<COMPONENT>_PACKAGE_PREDEPENDS`
+ * :variable:`CPACK_DEBIAN_<COMPONENT>_PACKAGE_PROVIDES`
+ * :variable:`CPACK_DEBIAN_<COMPONENT>_PACKAGE_RECOMMENDS`
+ * :variable:`CPACK_DEBIAN_<COMPONENT>_PACKAGE_REPLACES`
+ * :variable:`CPACK_DEBIAN_<COMPONENT>_PACKAGE_SUGGESTS`
+
+* The :module:`CPack` module learned to package empty directories.
+
+* The :module:`CPack` module gained a new setting, ``CPACK_VERBATIM_VARIABLES``,
+ which can be used to ensure the cpack program receives the settings' values
+ exactly as they were set, even if they contain CMake-special characters.
+ For compatibility, it's off by default.
+
+Other
+-----
+
+* The :manual:`Compile Features <cmake-compile-features(7)>` functionality
+ is now aware of features supported by GNU C compilers on Windows.
+
+* CMake learned to honor ``*.manifest`` source files with MSVC tools.
+ Manifest files named as sources of ``.exe`` and ``.dll`` targets
+ will be merged with linker-generated manifests and embedded in the
+ binary.
+
+* The `Concurrent Fortran 77 <https://ccur.com>`__ compiler is now supported.
+ Its :variable:`compiler id <CMAKE_<LANG>_COMPILER_ID>` is ``CCur``.
+
+* :manual:`cmake(1)` gained a new ``--trace-expand`` command line option
+ that is like ``--trace`` but expands variable references in the output.
+
+Deprecated and Removed Features
+===============================
+
+* The :module:`CMakeExpandImportedTargets` module is now documented
+ as deprecated. See module documentation for an explanation.
+
+* The :variable:`CMAKE_USE_RELATIVE_PATHS` variable no longer has any
+ effect. Previously it was partially implemented and unreliable.
+
+Other Changes
+=============
+
+* The :module:`CheckFunctionExists`, :module:`CheckLibraryExists`,
+ :module:`CheckSymbolExists`, and :module:`FindThreads` modules learned to
+ work in environments where only CXX is enabled.
+
+* The :module:`CPackDeb` module now correctly excludes symlinks during package
+ checksum calculation.
+
+* The :module:`CPackDeb` no longer uses fakeroot and system tar program for
+ packaging.
+
+* The :module:`CPack` module no longer mangles settings with CMake-special
+ characters when they're used as defaults for other settings. The macro
+ ``cpack_set_if_not_set``, which was responsible for this, is now deprecated.
+
+* CMake no longer links executables with flags to export symbols
+ unless the :prop_tgt:`ENABLE_EXPORTS` target property is set.
+ See policy :policy:`CMP0065`.
+
+* The ``SONAME`` field is no longer set for ``MODULE`` libraries
+ created with the :command:`add_library` command. ``MODULE``
+ libraries are meant for explicit dynamic loading at runtime.
+ They cannot be linked so ``SONAME`` is not useful.
+
+* The internal :variable:`CMAKE_<LANG>_COMPILE_OBJECT` rule variable now
+ substitutes compiler include flags in a separate ``<INCLUDES>`` placeholder
+ instead of the main ``<FLAGS>`` placeholder.
diff --git a/Help/release/3.5.rst b/Help/release/3.5.rst
new file mode 100644
index 000000000..009eb3c7c
--- /dev/null
+++ b/Help/release/3.5.rst
@@ -0,0 +1,185 @@
+CMake 3.5 Release Notes
+***********************
+
+.. only:: html
+
+ .. contents::
+
+Changes made since CMake 3.4 include the following.
+
+New Features
+============
+
+GUI
+---
+
+* The :manual:`cmake-gui(1)` gained options to control warnings about
+ deprecated functionality.
+
+* The :manual:`cmake-gui(1)` learned an option to set the toolset
+ to be used with VS IDE and Xcode generators, much like the
+ existing ``-T`` option to :manual:`cmake(1)`.
+
+* The :manual:`cmake-gui(1)` gained a Regular Expression Explorer which
+ may be used to create and evaluate regular expressions in real-time.
+ The explorer window is available via the ``Tools`` menu.
+
+Command-Line
+------------
+
+* The ``-Wdev`` and ``-Wno-dev`` :manual:`cmake(1)` options now also enable
+ and suppress the deprecated warnings output by default.
+
+* The suppression of developer warnings as errors can now be controlled with
+ the new ``-Werror=dev`` and ``-Wno-error=dev`` :manual:`cmake(1)` options.
+
+* The :manual:`cmake(1)` ``-E`` command-line tools ``copy``,
+ ``copy_if_different``, ``copy_directory``, and ``make_directory``
+ learned to support multiple input files or directories.
+
+Commands
+--------
+
+* The :command:`cmake_parse_arguments` command is now implemented natively.
+ The :module:`CMakeParseArguments` module remains as an empty placeholder
+ for compatibility.
+
+* The :command:`install(DIRECTORY)` command learned to support
+ :manual:`generator expressions <cmake-generator-expressions(7)>`
+ in the list of directories.
+
+Variables
+---------
+
+* The :variable:`CMAKE_ERROR_DEPRECATED` variable can now be set using the
+ ``-Werror=deprecated`` and ``-Wno-error=deprecated`` :manual:`cmake(1)`
+ options.
+
+* The :variable:`CMAKE_WARN_DEPRECATED` variable can now be set using the
+ ``-Wdeprecated`` and ``-Wno-deprecated`` :manual:`cmake(1)` options.
+
+Properties
+----------
+
+* The :prop_tgt:`VS_GLOBAL_<variable>` target property is now implemented
+ for VS 2010 and above. Previously it worked only in VS 2008 and below.
+
+Modules
+-------
+
+* The :module:`ExternalProject` module learned a new ``GIT_REMOTE_NAME``
+ option to control the ``git clone --origin`` value.
+
+* The :module:`FindBoost` module now provides imported targets
+ such as ``Boost::boost`` and ``Boost::filesystem``.
+
+* The :module:`FindFLEX` module ``FLEX_TARGET`` macro learned a
+ new ``DEFINES_FILE`` option to specify a custom output header
+ to be generated.
+
+* The :module:`FindGTest` module now provides imported targets.
+
+* The :module:`FindGTK2` module, when ``GTK2_USE_IMPORTED_TARGETS`` is
+ enabled, now sets ``GTK2_LIBRARIES`` to contain the list of imported
+ targets instead of the paths to the libraries. Moreover it now sets
+ a new ``GTK2_TARGETS`` variable containing all the targets imported.
+
+* The :module:`FindOpenMP` module learned to support Clang.
+
+* The :module:`FindOpenSSL` module gained a new
+ ``OPENSSL_MSVC_STATIC_RT`` option to search for libraries using
+ the MSVC static runtime.
+
+* The :module:`FindPNG` module now provides imported targets.
+
+* The :module:`FindTIFF` module now provides imported targets.
+
+* A :module:`FindXalanC` module was introduced to find the
+ Apache Xalan-C++ XSL transform processing library.
+
+* The :module:`FindXercesC` module now provides imported targets.
+
+Platforms
+---------
+
+* Support was added for the ARM Compiler (arm.com) with compiler id ``ARMCC``.
+
+* A new platform file for cross-compiling in the Cray Linux Environment to
+ target compute nodes was added. See
+ :ref:`Cross Compiling for the Cray Linux Environment <Cray Cross-Compile>`
+ for usage details.
+
+* The :manual:`Compile Features <cmake-compile-features(7)>` functionality
+ is now aware of features supported by Clang compilers on Windows (MinGW).
+
+* When building for embedded Apple platforms like iOS CMake learned to build and
+ install combined targets which contain both a device and a simulator build.
+ This behavior can be enabled by setting the :prop_tgt:`IOS_INSTALL_COMBINED`
+ target property.
+
+CPack
+-----
+
+* The :module:`CPackDMG` module learned new variable to specify AppleScript
+ file run to customize appearance of ``DragNDrop`` installer folder,
+ including background image setting using supplied PNG or multi-resolution
+ TIFF file. See the :variable:`CPACK_DMG_DS_STORE_SETUP_SCRIPT` and
+ :variable:`CPACK_DMG_BACKGROUND_IMAGE` variables.
+
+* The :module:`CPackDeb` module learned to set the optional config
+ file ``Source`` field using a monolithic or per-component variable.
+ See :variable:`CPACK_DEBIAN_PACKAGE_SOURCE`.
+
+* The :module:`CPackDeb` module learned to set Package, Section
+ and Priority control fields per-component.
+ See variables :variable:`CPACK_DEBIAN_<COMPONENT>_PACKAGE_SECTION` and
+ :variable:`CPACK_DEBIAN_<COMPONENT>_PACKAGE_PRIORITY`.
+
+* The :module:`CPack DragNDrop generator <CPackDMG>` learned to add
+ multi-lingual SLAs to a DMG which is presented to the user when they try to
+ mount the DMG. See the :variable:`CPACK_DMG_SLA_LANGUAGES` and
+ :variable:`CPACK_DMG_SLA_DIR` variables for details.
+
+* The :module:`CPackNSIS` module learned new variables to add bitmaps to the
+ installer. See the :variable:`CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP`
+ and :variable:`CPACK_NSIS_MUI_UNWELCOMEFINISHPAGE_BITMAP` variables.
+
+* The :module:`CPackRPM` module learned to set Name and Group
+ control fields per-component.
+ See :variable:`CPACK_RPM_<component>_PACKAGE_NAME`
+ and :variable:`CPACK_RPM_<component>_PACKAGE_GROUP`.
+
+Other
+-----
+
+* Warnings about deprecated functionality are now enabled by default.
+ They may be suppressed with ``-Wno-deprecated`` or by setting the
+ :variable:`CMAKE_WARN_DEPRECATED` variable to false.
+
+Deprecated and Removed Features
+===============================
+
+* The :manual:`cmake(1)` ``-E time`` command now properly passes arguments
+ with spaces or special characters through to the child process. This
+ may break scripts that worked around the bug with their own extra
+ quoting or escaping.
+
+* The :generator:`Xcode` generator was fixed to escape backslashes in
+ strings consistently with other generators. Projects that previously
+ worked around the inconsistecy with an extra level of backslashes
+ conditioned on the Xcode generator must be updated to remove the
+ workaround for CMake 3.5 and greater.
+
+Other Changes
+=============
+
+* The :generator:`Visual Studio 14 2015` generator learned to map the
+ ``/debug:fastlink`` linker flag to the ``.vcxproj`` file property.
+
+* The :module:`FindGTK2` module now configures the ``GTK2::sigc++`` imported
+ target to enable c++11 on its dependents when using sigc++ 2.5.1 or higher.
+
+* The precompiled Windows binary provided on ``cmake.org`` is now a
+ ``.msi`` package instead of an installer executable. One may need
+ to manually uninstall CMake versions lower than 3.5 before installing
+ the new package.
diff --git a/Help/release/dev.txt b/Help/release/dev.txt
new file mode 100644
index 000000000..2cf9193e1
--- /dev/null
+++ b/Help/release/dev.txt
@@ -0,0 +1,16 @@
+..
+ This file should be included by the adjacent "index.rst"
+ in development versions but not in release versions.
+
+Changes Since Release
+=====================
+
+The following noteworthy changes have been made in this development
+version since the preceding release but have not yet been consolidated
+into notes for a specific release version:
+
+.. toctree::
+ :maxdepth: 1
+ :glob:
+
+ dev/*
diff --git a/Help/release/index.rst b/Help/release/index.rst
new file mode 100644
index 000000000..6b7da3c7f
--- /dev/null
+++ b/Help/release/index.rst
@@ -0,0 +1,19 @@
+CMake Release Notes
+*******************
+
+..
+ This file should include the adjacent "dev.txt" file
+ in development versions but not in release versions.
+
+Releases
+========
+
+.. toctree::
+ :maxdepth: 1
+
+ 3.5 <3.5>
+ 3.4 <3.4>
+ 3.3 <3.3>
+ 3.2 <3.2>
+ 3.1 <3.1>
+ 3.0 <3.0>
diff --git a/Help/variable/APPLE.rst b/Help/variable/APPLE.rst
new file mode 100644
index 000000000..75eecf183
--- /dev/null
+++ b/Help/variable/APPLE.rst
@@ -0,0 +1,6 @@
+APPLE
+-----
+
+``True`` if running on OS X.
+
+Set to ``true`` on OS X.
diff --git a/Help/variable/BORLAND.rst b/Help/variable/BORLAND.rst
new file mode 100644
index 000000000..badb7338e
--- /dev/null
+++ b/Help/variable/BORLAND.rst
@@ -0,0 +1,6 @@
+BORLAND
+-------
+
+``True`` if the Borland compiler is being used.
+
+This is set to ``true`` if the Borland compiler is being used.
diff --git a/Help/variable/BUILD_SHARED_LIBS.rst b/Help/variable/BUILD_SHARED_LIBS.rst
new file mode 100644
index 000000000..53087b23b
--- /dev/null
+++ b/Help/variable/BUILD_SHARED_LIBS.rst
@@ -0,0 +1,10 @@
+BUILD_SHARED_LIBS
+-----------------
+
+Global flag to cause :command:`add_library` to create shared libraries if on.
+
+If present and true, this will cause all libraries to be built shared
+unless the library was explicitly added as a static library. This
+variable is often added to projects as an :command:`option` so that each user
+of a project can decide if they want to build the project using shared or
+static libraries.
diff --git a/Help/variable/CMAKE_ABSOLUTE_DESTINATION_FILES.rst b/Help/variable/CMAKE_ABSOLUTE_DESTINATION_FILES.rst
new file mode 100644
index 000000000..b6d00543a
--- /dev/null
+++ b/Help/variable/CMAKE_ABSOLUTE_DESTINATION_FILES.rst
@@ -0,0 +1,9 @@
+CMAKE_ABSOLUTE_DESTINATION_FILES
+--------------------------------
+
+List of files which have been installed using an ``ABSOLUTE DESTINATION`` path.
+
+This variable is defined by CMake-generated ``cmake_install.cmake``
+scripts. It can be used (read-only) by programs or scripts that
+source those install scripts. This is used by some CPack generators
+(e.g. RPM).
diff --git a/Help/variable/CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS.rst b/Help/variable/CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS.rst
new file mode 100644
index 000000000..8862ba91d
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS
+------------------------------------
+
+Default value for the :prop_tgt:`ANDROID_ANT_ADDITIONAL_OPTIONS` target property.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_API.rst b/Help/variable/CMAKE_ANDROID_API.rst
new file mode 100644
index 000000000..c8264e0f8
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_API.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_API
+-----------------
+
+Default value for the :prop_tgt:`ANDROID_API` target property.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_API_MIN.rst b/Help/variable/CMAKE_ANDROID_API_MIN.rst
new file mode 100644
index 000000000..0246c75b9
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_API_MIN.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_API_MIN
+---------------------
+
+Default value for the :prop_tgt:`ANDROID_API_MIN` target property.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_ARCH.rst b/Help/variable/CMAKE_ANDROID_ARCH.rst
new file mode 100644
index 000000000..8fbb46d53
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_ARCH.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_ARCH
+------------------
+
+Default value for the :prop_tgt:`ANDROID_ARCH` target property.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_ASSETS_DIRECTORIES.rst b/Help/variable/CMAKE_ANDROID_ASSETS_DIRECTORIES.rst
new file mode 100644
index 000000000..c372fe449
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_ASSETS_DIRECTORIES.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_ASSETS_DIRECTORIES
+--------------------------------
+
+Default value for the :prop_tgt:`ANDROID_ASSETS_DIRECTORIES` target property.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_GUI.rst b/Help/variable/CMAKE_ANDROID_GUI.rst
new file mode 100644
index 000000000..175537527
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_GUI.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_GUI
+-----------------
+
+Default value for the :prop_tgt:`ANDROID_GUI` target property of
+executables. See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_JAR_DEPENDENCIES.rst b/Help/variable/CMAKE_ANDROID_JAR_DEPENDENCIES.rst
new file mode 100644
index 000000000..451a92960
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_JAR_DEPENDENCIES.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_JAR_DEPENDENCIES
+------------------------------
+
+Default value for the :prop_tgt:`ANDROID_JAR_DEPENDENCIES` target property.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_JAR_DIRECTORIES.rst b/Help/variable/CMAKE_ANDROID_JAR_DIRECTORIES.rst
new file mode 100644
index 000000000..af83e3430
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_JAR_DIRECTORIES.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_JAR_DIRECTORIES
+-----------------------------
+
+Default value for the :prop_tgt:`ANDROID_JAR_DIRECTORIES` target property.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_JAVA_SOURCE_DIR.rst b/Help/variable/CMAKE_ANDROID_JAVA_SOURCE_DIR.rst
new file mode 100644
index 000000000..3dc05e05e
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_JAVA_SOURCE_DIR.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_JAVA_SOURCE_DIR
+-----------------------------
+
+Default value for the :prop_tgt:`ANDROID_JAVA_SOURCE_DIR` target property.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES.rst b/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES.rst
new file mode 100644
index 000000000..4191907d4
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES
+-------------------------------------
+
+Default value for the :prop_tgt:`ANDROID_NATIVE_LIB_DEPENDENCIES` target
+property. See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES.rst b/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES.rst
new file mode 100644
index 000000000..7cb95274e
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES
+------------------------------------
+
+Default value for the :prop_tgt:`ANDROID_NATIVE_LIB_DIRECTORIES` target
+property. See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_PROCESS_MAX.rst b/Help/variable/CMAKE_ANDROID_PROCESS_MAX.rst
new file mode 100644
index 000000000..19fb527f7
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_PROCESS_MAX.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_PROCESS_MAX
+-------------------------
+
+Default value for the :prop_tgt:`ANDROID_PROCESS_MAX` target property.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_PROGUARD.rst b/Help/variable/CMAKE_ANDROID_PROGUARD.rst
new file mode 100644
index 000000000..b8fdd46cc
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_PROGUARD.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_PROGUARD
+----------------------
+
+Default value for the :prop_tgt:`ANDROID_PROGUARD` target property.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_PROGUARD_CONFIG_PATH.rst b/Help/variable/CMAKE_ANDROID_PROGUARD_CONFIG_PATH.rst
new file mode 100644
index 000000000..8dea00907
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_PROGUARD_CONFIG_PATH.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_PROGUARD_CONFIG_PATH
+----------------------------------
+
+Default value for the :prop_tgt:`ANDROID_PROGUARD_CONFIG_PATH` target property.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_SECURE_PROPS_PATH.rst b/Help/variable/CMAKE_ANDROID_SECURE_PROPS_PATH.rst
new file mode 100644
index 000000000..69a4d0b56
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_SECURE_PROPS_PATH.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_SECURE_PROPS_PATH
+-------------------------------
+
+Default value for the :prop_tgt:`ANDROID_SECURE_PROPS_PATH` target property.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_SKIP_ANT_STEP.rst b/Help/variable/CMAKE_ANDROID_SKIP_ANT_STEP.rst
new file mode 100644
index 000000000..0a96df9fa
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_SKIP_ANT_STEP.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_SKIP_ANT_STEP
+---------------------------
+
+Default value for the :prop_tgt:`ANDROID_SKIP_ANT_STEP` target property.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_STL_TYPE.rst b/Help/variable/CMAKE_ANDROID_STL_TYPE.rst
new file mode 100644
index 000000000..766b2c8fd
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_STL_TYPE.rst
@@ -0,0 +1,5 @@
+CMAKE_ANDROID_STL_TYPE
+----------------------
+
+Default value for the :prop_tgt:`ANDROID_STL_TYPE` target property.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_APPBUNDLE_PATH.rst b/Help/variable/CMAKE_APPBUNDLE_PATH.rst
new file mode 100644
index 000000000..2bc79ac3a
--- /dev/null
+++ b/Help/variable/CMAKE_APPBUNDLE_PATH.rst
@@ -0,0 +1,6 @@
+CMAKE_APPBUNDLE_PATH
+--------------------
+
+:ref:`;-list <CMake Language Lists>` of directories specifying a search path
+for OS X application bundles used by the :command:`find_program`, and
+:command:`find_package` commands.
diff --git a/Help/variable/CMAKE_AR.rst b/Help/variable/CMAKE_AR.rst
new file mode 100644
index 000000000..5893677ff
--- /dev/null
+++ b/Help/variable/CMAKE_AR.rst
@@ -0,0 +1,7 @@
+CMAKE_AR
+--------
+
+Name of archiving tool for static libraries.
+
+This specifies the name of the program that creates archive or static
+libraries.
diff --git a/Help/variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY.rst b/Help/variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY.rst
new file mode 100644
index 000000000..c88932164
--- /dev/null
+++ b/Help/variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY.rst
@@ -0,0 +1,9 @@
+CMAKE_ARCHIVE_OUTPUT_DIRECTORY
+------------------------------
+
+Where to put all the :ref:`ARCHIVE <Archive Output Artifacts>`
+target files when built.
+
+This variable is used to initialize the :prop_tgt:`ARCHIVE_OUTPUT_DIRECTORY`
+property on all the targets. See that target property for additional
+information.
diff --git a/Help/variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CONFIG.rst b/Help/variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CONFIG.rst
new file mode 100644
index 000000000..94c2b6efa
--- /dev/null
+++ b/Help/variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CONFIG.rst
@@ -0,0 +1,9 @@
+CMAKE_ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>
+---------------------------------------
+
+Where to put all the :ref:`ARCHIVE <Archive Output Artifacts>`
+target files when built for a specific configuration.
+
+This variable is used to initialize the
+:prop_tgt:`ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>` property on all the targets.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_ARGC.rst b/Help/variable/CMAKE_ARGC.rst
new file mode 100644
index 000000000..aec97119a
--- /dev/null
+++ b/Help/variable/CMAKE_ARGC.rst
@@ -0,0 +1,8 @@
+CMAKE_ARGC
+----------
+
+Number of command line arguments passed to CMake in script mode.
+
+When run in :ref:`-P <CMake Options>` script mode, CMake sets this variable to
+the number of command line arguments. See also :variable:`CMAKE_ARGV0`,
+``1``, ``2`` ...
diff --git a/Help/variable/CMAKE_ARGV0.rst b/Help/variable/CMAKE_ARGV0.rst
new file mode 100644
index 000000000..8b1ecb79e
--- /dev/null
+++ b/Help/variable/CMAKE_ARGV0.rst
@@ -0,0 +1,9 @@
+CMAKE_ARGV0
+-----------
+
+Command line argument passed to CMake in script mode.
+
+When run in :ref:`-P <CMake Options>` script mode, CMake sets this variable to
+the first command line argument. It then also sets ``CMAKE_ARGV1``,
+``CMAKE_ARGV2``, ... and so on, up to the number of command line arguments
+given. See also :variable:`CMAKE_ARGC`.
diff --git a/Help/variable/CMAKE_AUTOMOC.rst b/Help/variable/CMAKE_AUTOMOC.rst
new file mode 100644
index 000000000..02e5eb57a
--- /dev/null
+++ b/Help/variable/CMAKE_AUTOMOC.rst
@@ -0,0 +1,7 @@
+CMAKE_AUTOMOC
+-------------
+
+Whether to handle ``moc`` automatically for Qt targets.
+
+This variable is used to initialize the :prop_tgt:`AUTOMOC` property on all the
+targets. See that target property for additional information.
diff --git a/Help/variable/CMAKE_AUTOMOC_MOC_OPTIONS.rst b/Help/variable/CMAKE_AUTOMOC_MOC_OPTIONS.rst
new file mode 100644
index 000000000..09bf5cd2f
--- /dev/null
+++ b/Help/variable/CMAKE_AUTOMOC_MOC_OPTIONS.rst
@@ -0,0 +1,7 @@
+CMAKE_AUTOMOC_MOC_OPTIONS
+-------------------------
+
+Additional options for ``moc`` when using :variable:`CMAKE_AUTOMOC`.
+
+This variable is used to initialize the :prop_tgt:`AUTOMOC_MOC_OPTIONS` property
+on all the targets. See that target property for additional information.
diff --git a/Help/variable/CMAKE_AUTOMOC_RELAXED_MODE.rst b/Help/variable/CMAKE_AUTOMOC_RELAXED_MODE.rst
new file mode 100644
index 000000000..addc62de4
--- /dev/null
+++ b/Help/variable/CMAKE_AUTOMOC_RELAXED_MODE.rst
@@ -0,0 +1,13 @@
+CMAKE_AUTOMOC_RELAXED_MODE
+--------------------------
+
+Switch between strict and relaxed automoc mode.
+
+By default, :prop_tgt:`AUTOMOC` behaves exactly as described in the
+documentation of the :prop_tgt:`AUTOMOC` target property. When set to
+``TRUE``, it accepts more input and tries to find the correct input file for
+``moc`` even if it differs from the documented behaviour. In this mode it
+e.g. also checks whether a header file is intended to be processed by moc
+when a ``"foo.moc"`` file has been included.
+
+Relaxed mode has to be enabled for KDE4 compatibility.
diff --git a/Help/variable/CMAKE_AUTORCC.rst b/Help/variable/CMAKE_AUTORCC.rst
new file mode 100644
index 000000000..742610541
--- /dev/null
+++ b/Help/variable/CMAKE_AUTORCC.rst
@@ -0,0 +1,7 @@
+CMAKE_AUTORCC
+-------------
+
+Whether to handle ``rcc`` automatically for Qt targets.
+
+This variable is used to initialize the :prop_tgt:`AUTORCC` property on all
+the targets. See that target property for additional information.
diff --git a/Help/variable/CMAKE_AUTORCC_OPTIONS.rst b/Help/variable/CMAKE_AUTORCC_OPTIONS.rst
new file mode 100644
index 000000000..298cb6be7
--- /dev/null
+++ b/Help/variable/CMAKE_AUTORCC_OPTIONS.rst
@@ -0,0 +1,7 @@
+CMAKE_AUTORCC_OPTIONS
+---------------------
+
+Whether to handle ``rcc`` automatically for Qt targets.
+
+This variable is used to initialize the :prop_tgt:`AUTORCC_OPTIONS` property on
+all the targets. See that target property for additional information.
diff --git a/Help/variable/CMAKE_AUTOUIC.rst b/Help/variable/CMAKE_AUTOUIC.rst
new file mode 100644
index 000000000..5abefaab8
--- /dev/null
+++ b/Help/variable/CMAKE_AUTOUIC.rst
@@ -0,0 +1,7 @@
+CMAKE_AUTOUIC
+-------------
+
+Whether to handle ``uic`` automatically for Qt targets.
+
+This variable is used to initialize the :prop_tgt:`AUTOUIC` property on all
+the targets. See that target property for additional information.
diff --git a/Help/variable/CMAKE_AUTOUIC_OPTIONS.rst b/Help/variable/CMAKE_AUTOUIC_OPTIONS.rst
new file mode 100644
index 000000000..3c9b8c4f5
--- /dev/null
+++ b/Help/variable/CMAKE_AUTOUIC_OPTIONS.rst
@@ -0,0 +1,7 @@
+CMAKE_AUTOUIC_OPTIONS
+---------------------
+
+Whether to handle ``uic`` automatically for Qt targets.
+
+This variable is used to initialize the :prop_tgt:`AUTOUIC_OPTIONS` property on
+all the targets. See that target property for additional information.
diff --git a/Help/variable/CMAKE_BACKWARDS_COMPATIBILITY.rst b/Help/variable/CMAKE_BACKWARDS_COMPATIBILITY.rst
new file mode 100644
index 000000000..05c366a95
--- /dev/null
+++ b/Help/variable/CMAKE_BACKWARDS_COMPATIBILITY.rst
@@ -0,0 +1,4 @@
+CMAKE_BACKWARDS_COMPATIBILITY
+-----------------------------
+
+Deprecated. See CMake Policy :policy:`CMP0001` documentation.
diff --git a/Help/variable/CMAKE_BINARY_DIR.rst b/Help/variable/CMAKE_BINARY_DIR.rst
new file mode 100644
index 000000000..3b323b7ae
--- /dev/null
+++ b/Help/variable/CMAKE_BINARY_DIR.rst
@@ -0,0 +1,13 @@
+CMAKE_BINARY_DIR
+----------------
+
+The path to the top level of the build tree.
+
+This is the full path to the top level of the current CMake build
+tree. For an in-source build, this would be the same as
+:variable:`CMAKE_SOURCE_DIR`.
+
+When run in -P script mode, CMake sets the variables
+:variable:`CMAKE_BINARY_DIR`, :variable:`CMAKE_SOURCE_DIR`,
+:variable:`CMAKE_CURRENT_BINARY_DIR` and
+:variable:`CMAKE_CURRENT_SOURCE_DIR` to the current working directory.
diff --git a/Help/variable/CMAKE_BUILD_TOOL.rst b/Help/variable/CMAKE_BUILD_TOOL.rst
new file mode 100644
index 000000000..61334917b
--- /dev/null
+++ b/Help/variable/CMAKE_BUILD_TOOL.rst
@@ -0,0 +1,6 @@
+CMAKE_BUILD_TOOL
+----------------
+
+This variable exists only for backwards compatibility.
+It contains the same value as :variable:`CMAKE_MAKE_PROGRAM`.
+Use that variable instead.
diff --git a/Help/variable/CMAKE_BUILD_TYPE.rst b/Help/variable/CMAKE_BUILD_TYPE.rst
new file mode 100644
index 000000000..2d54d6049
--- /dev/null
+++ b/Help/variable/CMAKE_BUILD_TYPE.rst
@@ -0,0 +1,20 @@
+CMAKE_BUILD_TYPE
+----------------
+
+Specifies the build type on single-configuration generators.
+
+This statically specifies what build type (configuration) will be
+built in this build tree. Possible values are empty, ``Debug``, ``Release``,
+``RelWithDebInfo`` and ``MinSizeRel``. This variable is only meaningful to
+single-configuration generators (such as :ref:`Makefile Generators` and
+:generator:`Ninja`) i.e. those which choose a single configuration when CMake
+runs to generate a build tree as opposed to multi-configuration generators
+which offer selection of the build configuration within the generated build
+environment. There are many per-config properties and variables
+(usually following clean ``SOME_VAR_<CONFIG>`` order conventions), such as
+``CMAKE_C_FLAGS_<CONFIG>``, specified as uppercase:
+``CMAKE_C_FLAGS_[DEBUG|RELEASE|RELWITHDEBINFO|MINSIZEREL]``. For example,
+in a build tree configured to build type ``Debug``, CMake will see to
+having :variable:`CMAKE_C_FLAGS_DEBUG <CMAKE_<LANG>_FLAGS_DEBUG>` settings get
+added to the :variable:`CMAKE_C_FLAGS <CMAKE_<LANG>_FLAGS>` settings. See
+also :variable:`CMAKE_CONFIGURATION_TYPES`.
diff --git a/Help/variable/CMAKE_BUILD_WITH_INSTALL_RPATH.rst b/Help/variable/CMAKE_BUILD_WITH_INSTALL_RPATH.rst
new file mode 100644
index 000000000..5b59a6ef2
--- /dev/null
+++ b/Help/variable/CMAKE_BUILD_WITH_INSTALL_RPATH.rst
@@ -0,0 +1,11 @@
+CMAKE_BUILD_WITH_INSTALL_RPATH
+------------------------------
+
+Use the install path for the ``RPATH``.
+
+Normally CMake uses the build tree for the ``RPATH`` when building
+executables etc on systems that use ``RPATH``. When the software is
+installed the executables etc are relinked by CMake to have the
+install ``RPATH``. If this variable is set to true then the software is
+always built with the install path for the ``RPATH`` and does not need to
+be relinked when installed.
diff --git a/Help/variable/CMAKE_CACHEFILE_DIR.rst b/Help/variable/CMAKE_CACHEFILE_DIR.rst
new file mode 100644
index 000000000..8604d0e8c
--- /dev/null
+++ b/Help/variable/CMAKE_CACHEFILE_DIR.rst
@@ -0,0 +1,7 @@
+CMAKE_CACHEFILE_DIR
+-------------------
+
+The directory with the ``CMakeCache.txt`` file.
+
+This is the full path to the directory that has the ``CMakeCache.txt``
+file in it. This is the same as :variable:`CMAKE_BINARY_DIR`.
diff --git a/Help/variable/CMAKE_CACHE_MAJOR_VERSION.rst b/Help/variable/CMAKE_CACHE_MAJOR_VERSION.rst
new file mode 100644
index 000000000..1e53ed62d
--- /dev/null
+++ b/Help/variable/CMAKE_CACHE_MAJOR_VERSION.rst
@@ -0,0 +1,8 @@
+CMAKE_CACHE_MAJOR_VERSION
+-------------------------
+
+Major version of CMake used to create the ``CMakeCache.txt`` file
+
+This stores the major version of CMake used to write a CMake cache
+file. It is only different when a different version of CMake is run
+on a previously created cache file.
diff --git a/Help/variable/CMAKE_CACHE_MINOR_VERSION.rst b/Help/variable/CMAKE_CACHE_MINOR_VERSION.rst
new file mode 100644
index 000000000..5d174a3c9
--- /dev/null
+++ b/Help/variable/CMAKE_CACHE_MINOR_VERSION.rst
@@ -0,0 +1,8 @@
+CMAKE_CACHE_MINOR_VERSION
+-------------------------
+
+Minor version of CMake used to create the ``CMakeCache.txt`` file
+
+This stores the minor version of CMake used to write a CMake cache
+file. It is only different when a different version of CMake is run
+on a previously created cache file.
diff --git a/Help/variable/CMAKE_CACHE_PATCH_VERSION.rst b/Help/variable/CMAKE_CACHE_PATCH_VERSION.rst
new file mode 100644
index 000000000..22d267c98
--- /dev/null
+++ b/Help/variable/CMAKE_CACHE_PATCH_VERSION.rst
@@ -0,0 +1,8 @@
+CMAKE_CACHE_PATCH_VERSION
+-------------------------
+
+Patch version of CMake used to create the ``CMakeCache.txt`` file
+
+This stores the patch version of CMake used to write a CMake cache
+file. It is only different when a different version of CMake is run
+on a previously created cache file.
diff --git a/Help/variable/CMAKE_CFG_INTDIR.rst b/Help/variable/CMAKE_CFG_INTDIR.rst
new file mode 100644
index 000000000..dcc1aede1
--- /dev/null
+++ b/Help/variable/CMAKE_CFG_INTDIR.rst
@@ -0,0 +1,46 @@
+CMAKE_CFG_INTDIR
+----------------
+
+Build-time reference to per-configuration output subdirectory.
+
+For native build systems supporting multiple configurations in the
+build tree (such as :ref:`Visual Studio Generators` and :generator:`Xcode`),
+the value is a reference to a build-time variable specifying the name
+of the per-configuration output subdirectory. On :ref:`Makefile Generators`
+this evaluates to `.` because there is only one configuration in a build tree.
+Example values:
+
+::
+
+ $(IntDir) = Visual Studio 6
+ $(ConfigurationName) = Visual Studio 7, 8, 9
+ $(Configuration) = Visual Studio 10
+ $(CONFIGURATION) = Xcode
+ . = Make-based tools
+
+Since these values are evaluated by the native build system, this
+variable is suitable only for use in command lines that will be
+evaluated at build time. Example of intended usage:
+
+::
+
+ add_executable(mytool mytool.c)
+ add_custom_command(
+ OUTPUT out.txt
+ COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/mytool
+ ${CMAKE_CURRENT_SOURCE_DIR}/in.txt out.txt
+ DEPENDS mytool in.txt
+ )
+ add_custom_target(drive ALL DEPENDS out.txt)
+
+Note that ``CMAKE_CFG_INTDIR`` is no longer necessary for this purpose but
+has been left for compatibility with existing projects. Instead
+:command:`add_custom_command` recognizes executable target names in its
+``COMMAND`` option, so
+``${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/mytool`` can be replaced
+by just ``mytool``.
+
+This variable is read-only. Setting it is undefined behavior. In
+multi-configuration build systems the value of this variable is passed
+as the value of preprocessor symbol ``CMAKE_INTDIR`` to the compilation
+of all source files.
diff --git a/Help/variable/CMAKE_CL_64.rst b/Help/variable/CMAKE_CL_64.rst
new file mode 100644
index 000000000..a1e86a552
--- /dev/null
+++ b/Help/variable/CMAKE_CL_64.rst
@@ -0,0 +1,6 @@
+CMAKE_CL_64
+-----------
+
+Using the 64-bit compiler from Microsoft
+
+Set to ``true`` when using the 64-bit ``cl`` compiler from Microsoft.
diff --git a/Help/variable/CMAKE_COLOR_MAKEFILE.rst b/Help/variable/CMAKE_COLOR_MAKEFILE.rst
new file mode 100644
index 000000000..bb86eccc5
--- /dev/null
+++ b/Help/variable/CMAKE_COLOR_MAKEFILE.rst
@@ -0,0 +1,7 @@
+CMAKE_COLOR_MAKEFILE
+--------------------
+
+Enables color output when using the :ref:`Makefile Generators`.
+
+When enabled, the generated Makefiles will produce colored output.
+Default is ``ON``.
diff --git a/Help/variable/CMAKE_COMMAND.rst b/Help/variable/CMAKE_COMMAND.rst
new file mode 100644
index 000000000..f80b46cb5
--- /dev/null
+++ b/Help/variable/CMAKE_COMMAND.rst
@@ -0,0 +1,8 @@
+CMAKE_COMMAND
+-------------
+
+The full path to the :manual:`cmake(1)` executable.
+
+This is the full path to the CMake executable :manual:`cmake(1)` which is
+useful from custom commands that want to use the ``cmake -E`` option for
+portable system commands. (e.g. ``/usr/local/bin/cmake``)
diff --git a/Help/variable/CMAKE_COMPILER_2005.rst b/Help/variable/CMAKE_COMPILER_2005.rst
new file mode 100644
index 000000000..134559b6c
--- /dev/null
+++ b/Help/variable/CMAKE_COMPILER_2005.rst
@@ -0,0 +1,6 @@
+CMAKE_COMPILER_2005
+-------------------
+
+Using the Visual Studio 2005 compiler from Microsoft
+
+Set to true when using the Visual Studio 2005 compiler from Microsoft.
diff --git a/Help/variable/CMAKE_COMPILER_IS_GNULANG.rst b/Help/variable/CMAKE_COMPILER_IS_GNULANG.rst
new file mode 100644
index 000000000..4b652c008
--- /dev/null
+++ b/Help/variable/CMAKE_COMPILER_IS_GNULANG.rst
@@ -0,0 +1,15 @@
+CMAKE_COMPILER_IS_GNU<LANG>
+---------------------------
+
+True if the compiler is GNU.
+
+If the selected ``<LANG>`` compiler is the GNU compiler then this is ``TRUE``,
+if not it is ``FALSE``. Unlike the other per-language variables, this
+uses the GNU syntax for identifying languages instead of the CMake
+syntax. Recognized values of the ``<LANG>`` suffix are:
+
+::
+
+ CC = C compiler
+ CXX = C++ compiler
+ G77 = Fortran compiler
diff --git a/Help/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY.rst b/Help/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY.rst
new file mode 100644
index 000000000..ea33c7d64
--- /dev/null
+++ b/Help/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY.rst
@@ -0,0 +1,8 @@
+CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY
+----------------------------------
+
+Output directory for MS debug symbol ``.pdb`` files
+generated by the compiler while building source files.
+
+This variable is used to initialize the
+:prop_tgt:`COMPILE_PDB_OUTPUT_DIRECTORY` property on all the targets.
diff --git a/Help/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst b/Help/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst
new file mode 100644
index 000000000..fdeb9abdd
--- /dev/null
+++ b/Help/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst
@@ -0,0 +1,11 @@
+CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_<CONFIG>
+-------------------------------------------
+
+Per-configuration output directory for MS debug symbol ``.pdb`` files
+generated by the compiler while building source files.
+
+This is a per-configuration version of
+:variable:`CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY`.
+This variable is used to initialize the
+:prop_tgt:`COMPILE_PDB_OUTPUT_DIRECTORY_<CONFIG>`
+property on all the targets.
diff --git a/Help/variable/CMAKE_CONFIGURATION_TYPES.rst b/Help/variable/CMAKE_CONFIGURATION_TYPES.rst
new file mode 100644
index 000000000..34e99ebf7
--- /dev/null
+++ b/Help/variable/CMAKE_CONFIGURATION_TYPES.rst
@@ -0,0 +1,10 @@
+CMAKE_CONFIGURATION_TYPES
+-------------------------
+
+Specifies the available build types on multi-config generators.
+
+This specifies what build types (configurations) will be available
+such as ``Debug``, ``Release``, ``RelWithDebInfo`` etc. This has reasonable
+defaults on most platforms, but can be extended to provide other build
+types. See also :variable:`CMAKE_BUILD_TYPE` for details of managing
+configuration data, and :variable:`CMAKE_CFG_INTDIR`.
diff --git a/Help/variable/CMAKE_CONFIG_POSTFIX.rst b/Help/variable/CMAKE_CONFIG_POSTFIX.rst
new file mode 100644
index 000000000..e686a4338
--- /dev/null
+++ b/Help/variable/CMAKE_CONFIG_POSTFIX.rst
@@ -0,0 +1,7 @@
+CMAKE_<CONFIG>_POSTFIX
+----------------------
+
+Default filename postfix for libraries under configuration ``<CONFIG>``.
+
+When a non-executable target is created its :prop_tgt:`<CONFIG>_POSTFIX`
+target property is initialized with the value of this variable if it is set.
diff --git a/Help/variable/CMAKE_CROSSCOMPILING.rst b/Help/variable/CMAKE_CROSSCOMPILING.rst
new file mode 100644
index 000000000..cf9865b61
--- /dev/null
+++ b/Help/variable/CMAKE_CROSSCOMPILING.rst
@@ -0,0 +1,8 @@
+CMAKE_CROSSCOMPILING
+--------------------
+
+Is CMake currently cross compiling.
+
+This variable will be set to true by CMake if CMake is cross
+compiling. Specifically if the build platform is different from the
+target platform.
diff --git a/Help/variable/CMAKE_CROSSCOMPILING_EMULATOR.rst b/Help/variable/CMAKE_CROSSCOMPILING_EMULATOR.rst
new file mode 100644
index 000000000..95d2c7ffc
--- /dev/null
+++ b/Help/variable/CMAKE_CROSSCOMPILING_EMULATOR.rst
@@ -0,0 +1,12 @@
+CMAKE_CROSSCOMPILING_EMULATOR
+-----------------------------
+
+This variable is only used when :variable:`CMAKE_CROSSCOMPILING` is on. It
+should point to a command on the host system that can run executable built
+for the target system.
+
+The command will be used to run :command:`try_run` generated executables,
+which avoids manual population of the TryRunResults.cmake file.
+
+It is also used as the default value for the
+:prop_tgt:`CROSSCOMPILING_EMULATOR` target property of executables.
diff --git a/Help/variable/CMAKE_CTEST_COMMAND.rst b/Help/variable/CMAKE_CTEST_COMMAND.rst
new file mode 100644
index 000000000..b2942e2a8
--- /dev/null
+++ b/Help/variable/CMAKE_CTEST_COMMAND.rst
@@ -0,0 +1,8 @@
+CMAKE_CTEST_COMMAND
+-------------------
+
+Full path to :manual:`ctest(1)` command installed with CMake.
+
+This is the full path to the CTest executable :manual:`ctest(1)` which is
+useful from custom commands that want to use the :manual:`cmake(1)` ``-E``
+option for portable system commands.
diff --git a/Help/variable/CMAKE_CURRENT_BINARY_DIR.rst b/Help/variable/CMAKE_CURRENT_BINARY_DIR.rst
new file mode 100644
index 000000000..40496b5d9
--- /dev/null
+++ b/Help/variable/CMAKE_CURRENT_BINARY_DIR.rst
@@ -0,0 +1,15 @@
+CMAKE_CURRENT_BINARY_DIR
+------------------------
+
+The path to the binary directory currently being processed.
+
+This the full path to the build directory that is currently being
+processed by cmake. Each directory added by :command:`add_subdirectory` will
+create a binary directory in the build tree, and as it is being
+processed this variable will be set. For in-source builds this is the
+current source directory being processed.
+
+When run in -P script mode, CMake sets the variables
+:variable:`CMAKE_BINARY_DIR`, :variable:`CMAKE_SOURCE_DIR`,
+:variable:`CMAKE_CURRENT_BINARY_DIR` and
+:variable:`CMAKE_CURRENT_SOURCE_DIR` to the current working directory.
diff --git a/Help/variable/CMAKE_CURRENT_LIST_DIR.rst b/Help/variable/CMAKE_CURRENT_LIST_DIR.rst
new file mode 100644
index 000000000..ebc3ab9c9
--- /dev/null
+++ b/Help/variable/CMAKE_CURRENT_LIST_DIR.rst
@@ -0,0 +1,17 @@
+CMAKE_CURRENT_LIST_DIR
+----------------------
+
+Full directory of the listfile currently being processed.
+
+As CMake processes the listfiles in your project this variable will
+always be set to the directory where the listfile which is currently
+being processed (:variable:`CMAKE_CURRENT_LIST_FILE`) is located. The value
+has dynamic scope. When CMake starts processing commands in a source file
+it sets this variable to the directory where this file is located.
+When CMake finishes processing commands from the file it restores the
+previous value. Therefore the value of the variable inside a macro or
+function is the directory of the file invoking the bottom-most entry
+on the call stack, not the directory of the file containing the macro
+or function definition.
+
+See also :variable:`CMAKE_CURRENT_LIST_FILE`.
diff --git a/Help/variable/CMAKE_CURRENT_LIST_FILE.rst b/Help/variable/CMAKE_CURRENT_LIST_FILE.rst
new file mode 100644
index 000000000..84b0eeeba
--- /dev/null
+++ b/Help/variable/CMAKE_CURRENT_LIST_FILE.rst
@@ -0,0 +1,15 @@
+CMAKE_CURRENT_LIST_FILE
+-----------------------
+
+Full path to the listfile currently being processed.
+
+As CMake processes the listfiles in your project this variable will
+always be set to the one currently being processed. The value has
+dynamic scope. When CMake starts processing commands in a source file
+it sets this variable to the location of the file. When CMake
+finishes processing commands from the file it restores the previous
+value. Therefore the value of the variable inside a macro or function
+is the file invoking the bottom-most entry on the call stack, not the
+file containing the macro or function definition.
+
+See also :variable:`CMAKE_PARENT_LIST_FILE`.
diff --git a/Help/variable/CMAKE_CURRENT_LIST_LINE.rst b/Help/variable/CMAKE_CURRENT_LIST_LINE.rst
new file mode 100644
index 000000000..60e8e26ce
--- /dev/null
+++ b/Help/variable/CMAKE_CURRENT_LIST_LINE.rst
@@ -0,0 +1,7 @@
+CMAKE_CURRENT_LIST_LINE
+-----------------------
+
+The line number of the current file being processed.
+
+This is the line number of the file currently being processed by
+cmake.
diff --git a/Help/variable/CMAKE_CURRENT_SOURCE_DIR.rst b/Help/variable/CMAKE_CURRENT_SOURCE_DIR.rst
new file mode 100644
index 000000000..c1b755a0e
--- /dev/null
+++ b/Help/variable/CMAKE_CURRENT_SOURCE_DIR.rst
@@ -0,0 +1,12 @@
+CMAKE_CURRENT_SOURCE_DIR
+------------------------
+
+The path to the source directory currently being processed.
+
+This the full path to the source directory that is currently being
+processed by cmake.
+
+When run in -P script mode, CMake sets the variables
+:variable:`CMAKE_BINARY_DIR`, :variable:`CMAKE_SOURCE_DIR`,
+:variable:`CMAKE_CURRENT_BINARY_DIR` and
+:variable:`CMAKE_CURRENT_SOURCE_DIR` to the current working directory.
diff --git a/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst b/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst
new file mode 100644
index 000000000..5c59f9503
--- /dev/null
+++ b/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst
@@ -0,0 +1,11 @@
+CMAKE_CXX_COMPILE_FEATURES
+--------------------------
+
+List of features known to the C++ compiler
+
+These features are known to be available for use with the C++ compiler. This
+list is a subset of the features listed in the
+:prop_gbl:`CMAKE_CXX_KNOWN_FEATURES` global property.
+
+See the :manual:`cmake-compile-features(7)` manual for information on
+compile features and a list of supported compilers.
diff --git a/Help/variable/CMAKE_CXX_EXTENSIONS.rst b/Help/variable/CMAKE_CXX_EXTENSIONS.rst
new file mode 100644
index 000000000..4a92425e6
--- /dev/null
+++ b/Help/variable/CMAKE_CXX_EXTENSIONS.rst
@@ -0,0 +1,11 @@
+CMAKE_CXX_EXTENSIONS
+--------------------
+
+Default value for :prop_tgt:`CXX_EXTENSIONS` property of targets.
+
+This variable is used to initialize the :prop_tgt:`CXX_EXTENSIONS`
+property on all targets. See that target property for additional
+information.
+
+See the :manual:`cmake-compile-features(7)` manual for information on
+compile features and a list of supported compilers.
diff --git a/Help/variable/CMAKE_CXX_STANDARD.rst b/Help/variable/CMAKE_CXX_STANDARD.rst
new file mode 100644
index 000000000..8a8bdff29
--- /dev/null
+++ b/Help/variable/CMAKE_CXX_STANDARD.rst
@@ -0,0 +1,11 @@
+CMAKE_CXX_STANDARD
+------------------
+
+Default value for :prop_tgt:`CXX_STANDARD` property of targets.
+
+This variable is used to initialize the :prop_tgt:`CXX_STANDARD`
+property on all targets. See that target property for additional
+information.
+
+See the :manual:`cmake-compile-features(7)` manual for information on
+compile features and a list of supported compilers.
diff --git a/Help/variable/CMAKE_CXX_STANDARD_REQUIRED.rst b/Help/variable/CMAKE_CXX_STANDARD_REQUIRED.rst
new file mode 100644
index 000000000..4c710580a
--- /dev/null
+++ b/Help/variable/CMAKE_CXX_STANDARD_REQUIRED.rst
@@ -0,0 +1,11 @@
+CMAKE_CXX_STANDARD_REQUIRED
+---------------------------
+
+Default value for :prop_tgt:`CXX_STANDARD_REQUIRED` property of targets.
+
+This variable is used to initialize the :prop_tgt:`CXX_STANDARD_REQUIRED`
+property on all targets. See that target property for additional
+information.
+
+See the :manual:`cmake-compile-features(7)` manual for information on
+compile features and a list of supported compilers.
diff --git a/Help/variable/CMAKE_C_COMPILE_FEATURES.rst b/Help/variable/CMAKE_C_COMPILE_FEATURES.rst
new file mode 100644
index 000000000..8d1eca06a
--- /dev/null
+++ b/Help/variable/CMAKE_C_COMPILE_FEATURES.rst
@@ -0,0 +1,11 @@
+CMAKE_C_COMPILE_FEATURES
+------------------------
+
+List of features known to the C compiler
+
+These features are known to be available for use with the C compiler. This
+list is a subset of the features listed in the
+:prop_gbl:`CMAKE_C_KNOWN_FEATURES` global property.
+
+See the :manual:`cmake-compile-features(7)` manual for information on
+compile features and a list of supported compilers.
diff --git a/Help/variable/CMAKE_C_EXTENSIONS.rst b/Help/variable/CMAKE_C_EXTENSIONS.rst
new file mode 100644
index 000000000..fa510d4a8
--- /dev/null
+++ b/Help/variable/CMAKE_C_EXTENSIONS.rst
@@ -0,0 +1,11 @@
+CMAKE_C_EXTENSIONS
+------------------
+
+Default value for :prop_tgt:`C_EXTENSIONS` property of targets.
+
+This variable is used to initialize the :prop_tgt:`C_EXTENSIONS`
+property on all targets. See that target property for additional
+information.
+
+See the :manual:`cmake-compile-features(7)` manual for information on
+compile features and a list of supported compilers.
diff --git a/Help/variable/CMAKE_C_STANDARD.rst b/Help/variable/CMAKE_C_STANDARD.rst
new file mode 100644
index 000000000..b55e00cd9
--- /dev/null
+++ b/Help/variable/CMAKE_C_STANDARD.rst
@@ -0,0 +1,11 @@
+CMAKE_C_STANDARD
+----------------
+
+Default value for :prop_tgt:`C_STANDARD` property of targets.
+
+This variable is used to initialize the :prop_tgt:`C_STANDARD`
+property on all targets. See that target property for additional
+information.
+
+See the :manual:`cmake-compile-features(7)` manual for information on
+compile features and a list of supported compilers.
diff --git a/Help/variable/CMAKE_C_STANDARD_REQUIRED.rst b/Help/variable/CMAKE_C_STANDARD_REQUIRED.rst
new file mode 100644
index 000000000..7f70f6edb
--- /dev/null
+++ b/Help/variable/CMAKE_C_STANDARD_REQUIRED.rst
@@ -0,0 +1,11 @@
+CMAKE_C_STANDARD_REQUIRED
+-------------------------
+
+Default value for :prop_tgt:`C_STANDARD_REQUIRED` property of targets.
+
+This variable is used to initialize the :prop_tgt:`C_STANDARD_REQUIRED`
+property on all targets. See that target property for additional
+information.
+
+See the :manual:`cmake-compile-features(7)` manual for information on
+compile features and a list of supported compilers.
diff --git a/Help/variable/CMAKE_DEBUG_POSTFIX.rst b/Help/variable/CMAKE_DEBUG_POSTFIX.rst
new file mode 100644
index 000000000..08577a5c8
--- /dev/null
+++ b/Help/variable/CMAKE_DEBUG_POSTFIX.rst
@@ -0,0 +1,7 @@
+CMAKE_DEBUG_POSTFIX
+-------------------
+
+See variable :variable:`CMAKE_<CONFIG>_POSTFIX`.
+
+This variable is a special case of the more-general
+:variable:`CMAKE_<CONFIG>_POSTFIX` variable for the `DEBUG` configuration.
diff --git a/Help/variable/CMAKE_DEBUG_TARGET_PROPERTIES.rst b/Help/variable/CMAKE_DEBUG_TARGET_PROPERTIES.rst
new file mode 100644
index 000000000..513276e57
--- /dev/null
+++ b/Help/variable/CMAKE_DEBUG_TARGET_PROPERTIES.rst
@@ -0,0 +1,14 @@
+CMAKE_DEBUG_TARGET_PROPERTIES
+-----------------------------
+
+Enables tracing output for target properties.
+
+This variable can be populated with a list of properties to generate
+debug output for when evaluating target properties. Currently it can
+only be used when evaluating the :prop_tgt:`INCLUDE_DIRECTORIES`,
+:prop_tgt:`COMPILE_DEFINITIONS`, :prop_tgt:`COMPILE_OPTIONS`,
+:prop_tgt:`AUTOUIC_OPTIONS`, :prop_tgt:`SOURCES`, :prop_tgt:`COMPILE_FEATURES`,
+:prop_tgt:`POSITION_INDEPENDENT_CODE` target properties and any other property
+listed in :prop_tgt:`COMPATIBLE_INTERFACE_STRING` and other
+``COMPATIBLE_INTERFACE_`` properties. It outputs an origin for each entry in
+the target property. Default is unset.
diff --git a/Help/variable/CMAKE_DISABLE_FIND_PACKAGE_PackageName.rst b/Help/variable/CMAKE_DISABLE_FIND_PACKAGE_PackageName.rst
new file mode 100644
index 000000000..ed600202c
--- /dev/null
+++ b/Help/variable/CMAKE_DISABLE_FIND_PACKAGE_PackageName.rst
@@ -0,0 +1,16 @@
+CMAKE_DISABLE_FIND_PACKAGE_<PackageName>
+----------------------------------------
+
+Variable for disabling :command:`find_package` calls.
+
+Every non-``REQUIRED`` :command:`find_package` call in a project can be
+disabled by setting the variable
+``CMAKE_DISABLE_FIND_PACKAGE_<PackageName>`` to ``TRUE``.
+This can be used to build a project without an optional package,
+although that package is installed.
+
+This switch should be used during the initial CMake run. Otherwise if
+the package has already been found in a previous CMake run, the
+variables which have been stored in the cache will still be there. In
+that case it is recommended to remove the cache variables for this
+package from the cache using the cache editor or :manual:`cmake(1)` ``-U``
diff --git a/Help/variable/CMAKE_DL_LIBS.rst b/Help/variable/CMAKE_DL_LIBS.rst
new file mode 100644
index 000000000..1fe7641b8
--- /dev/null
+++ b/Help/variable/CMAKE_DL_LIBS.rst
@@ -0,0 +1,7 @@
+CMAKE_DL_LIBS
+-------------
+
+Name of library containing ``dlopen`` and ``dlcose``.
+
+The name of the library that has ``dlopen`` and ``dlclose`` in it, usually
+``-ldl`` on most UNIX machines.
diff --git a/Help/variable/CMAKE_EDIT_COMMAND.rst b/Help/variable/CMAKE_EDIT_COMMAND.rst
new file mode 100644
index 000000000..2f4ab1f62
--- /dev/null
+++ b/Help/variable/CMAKE_EDIT_COMMAND.rst
@@ -0,0 +1,8 @@
+CMAKE_EDIT_COMMAND
+------------------
+
+Full path to :manual:`cmake-gui(1)` or :manual:`ccmake(1)`. Defined only for
+:ref:`Makefile Generators` when not using an "extra" generator for an IDE.
+
+This is the full path to the CMake executable that can graphically
+edit the cache. For example, :manual:`cmake-gui(1)` or :manual:`ccmake(1)`.
diff --git a/Help/variable/CMAKE_ENABLE_EXPORTS.rst b/Help/variable/CMAKE_ENABLE_EXPORTS.rst
new file mode 100644
index 000000000..9a877e7e6
--- /dev/null
+++ b/Help/variable/CMAKE_ENABLE_EXPORTS.rst
@@ -0,0 +1,22 @@
+CMAKE_ENABLE_EXPORTS
+--------------------
+
+Specify whether an executable exports symbols for loadable modules.
+
+Normally an executable does not export any symbols because it is the
+final program. It is possible for an executable to export symbols to
+be used by loadable modules. When this property is set to true CMake
+will allow other targets to ``link`` to the executable with the
+:command:`TARGET_LINK_LIBRARIES` command. On all platforms a target-level
+dependency on the executable is created for targets that link to it.
+For DLL platforms an import library will be created for the exported
+symbols and then used for linking. All Windows-based systems
+including Cygwin are DLL platforms. For non-DLL platforms that
+require all symbols to be resolved at link time, such as OS X, the
+module will ``link`` to the executable using a flag like
+``-bundle_loader``. For other non-DLL platforms the link rule is simply
+ignored since the dynamic loader will automatically bind symbols when
+the module is loaded.
+
+This variable is used to initialize the target property
+:prop_tgt:`ENABLE_EXPORTS` for executable targets.
diff --git a/Help/variable/CMAKE_ERROR_DEPRECATED.rst b/Help/variable/CMAKE_ERROR_DEPRECATED.rst
new file mode 100644
index 000000000..f3a673827
--- /dev/null
+++ b/Help/variable/CMAKE_ERROR_DEPRECATED.rst
@@ -0,0 +1,7 @@
+CMAKE_ERROR_DEPRECATED
+----------------------
+
+Whether to issue errors for deprecated functionality.
+
+If ``TRUE``, use of deprecated functionality will issue fatal errors.
+If this variable is not set, CMake behaves as if it were set to ``FALSE``.
diff --git a/Help/variable/CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION.rst b/Help/variable/CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION.rst
new file mode 100644
index 000000000..38e9b7b36
--- /dev/null
+++ b/Help/variable/CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION.rst
@@ -0,0 +1,10 @@
+CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION
+-------------------------------------------
+
+Ask ``cmake_install.cmake`` script to error out as soon as a file with
+absolute ``INSTALL DESTINATION`` is encountered.
+
+The fatal error is emitted before the installation of the offending
+file takes place. This variable is used by CMake-generated
+``cmake_install.cmake`` scripts. If one sets this variable to ``ON`` while
+running the script, it may get fatal error messages from the script.
diff --git a/Help/variable/CMAKE_EXECUTABLE_SUFFIX.rst b/Help/variable/CMAKE_EXECUTABLE_SUFFIX.rst
new file mode 100644
index 000000000..356590f6f
--- /dev/null
+++ b/Help/variable/CMAKE_EXECUTABLE_SUFFIX.rst
@@ -0,0 +1,9 @@
+CMAKE_EXECUTABLE_SUFFIX
+-----------------------
+
+The suffix for executables on this platform.
+
+The suffix to use for the end of an executable filename if any, ``.exe``
+on Windows.
+
+``CMAKE_EXECUTABLE_SUFFIX_<LANG>`` overrides this for language ``<LANG>``.
diff --git a/Help/variable/CMAKE_EXE_LINKER_FLAGS.rst b/Help/variable/CMAKE_EXE_LINKER_FLAGS.rst
new file mode 100644
index 000000000..9e108f83f
--- /dev/null
+++ b/Help/variable/CMAKE_EXE_LINKER_FLAGS.rst
@@ -0,0 +1,6 @@
+CMAKE_EXE_LINKER_FLAGS
+----------------------
+
+Linker flags to be used to create executables.
+
+These flags will be used by the linker when creating an executable.
diff --git a/Help/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG.rst b/Help/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG.rst
new file mode 100644
index 000000000..0cd8113aa
--- /dev/null
+++ b/Help/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG.rst
@@ -0,0 +1,7 @@
+CMAKE_EXE_LINKER_FLAGS_<CONFIG>
+-------------------------------
+
+Flags to be used when linking an executable.
+
+Same as ``CMAKE_C_FLAGS_*`` but used by the linker when creating
+executables.
diff --git a/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst b/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst
new file mode 100644
index 000000000..8776279e8
--- /dev/null
+++ b/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst
@@ -0,0 +1,30 @@
+CMAKE_EXPORT_COMPILE_COMMANDS
+-----------------------------
+
+Enable/Disable output of compile commands during generation.
+
+If enabled, generates a ``compile_commands.json`` file containing the exact
+compiler calls for all translation units of the project in machine-readable
+form. The format of the JSON file looks like:
+
+.. code-block:: javascript
+
+ [
+ {
+ "directory": "/home/user/development/project",
+ "command": "/usr/bin/c++ ... -c ../foo/foo.cc",
+ "file": "../foo/foo.cc"
+ },
+
+ ...
+
+ {
+ "directory": "/home/user/development/project",
+ "command": "/usr/bin/c++ ... -c ../foo/bar.cc",
+ "file": "../foo/bar.cc"
+ }
+ ]
+
+.. note::
+ This option is implemented only by :ref:`Makefile Generators`
+ and the :generator:`Ninja`. It is ignored on other generators.
diff --git a/Help/variable/CMAKE_EXPORT_NO_PACKAGE_REGISTRY.rst b/Help/variable/CMAKE_EXPORT_NO_PACKAGE_REGISTRY.rst
new file mode 100644
index 000000000..ee109ba1a
--- /dev/null
+++ b/Help/variable/CMAKE_EXPORT_NO_PACKAGE_REGISTRY.rst
@@ -0,0 +1,11 @@
+CMAKE_EXPORT_NO_PACKAGE_REGISTRY
+--------------------------------
+
+Disable the :command:`export(PACKAGE)` command.
+
+In some cases, for example for packaging and for system wide
+installations, it is not desirable to write the user package registry.
+If the :variable:`CMAKE_EXPORT_NO_PACKAGE_REGISTRY` variable is enabled,
+the :command:`export(PACKAGE)` command will do nothing.
+
+See also :ref:`Disabling the Package Registry`.
diff --git a/Help/variable/CMAKE_EXTRA_GENERATOR.rst b/Help/variable/CMAKE_EXTRA_GENERATOR.rst
new file mode 100644
index 000000000..4d513e474
--- /dev/null
+++ b/Help/variable/CMAKE_EXTRA_GENERATOR.rst
@@ -0,0 +1,10 @@
+CMAKE_EXTRA_GENERATOR
+---------------------
+
+The extra generator used to build the project. See
+:manual:`cmake-generators(7)`.
+
+When using the Eclipse, CodeBlocks or KDevelop generators, CMake
+generates Makefiles (:variable:`CMAKE_GENERATOR`) and additionally project
+files for the respective IDE. This IDE project file generator is stored in
+``CMAKE_EXTRA_GENERATOR`` (e.g. ``Eclipse CDT4``).
diff --git a/Help/variable/CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES.rst b/Help/variable/CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES.rst
new file mode 100644
index 000000000..a130adbee
--- /dev/null
+++ b/Help/variable/CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES.rst
@@ -0,0 +1,9 @@
+CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES
+-----------------------------------
+
+Additional suffixes for shared libraries.
+
+Extensions for shared libraries other than that specified by
+:variable:`CMAKE_SHARED_LIBRARY_SUFFIX`, if any. CMake uses this to recognize
+external shared library files during analysis of libraries linked by a
+target.
diff --git a/Help/variable/CMAKE_FIND_APPBUNDLE.rst b/Help/variable/CMAKE_FIND_APPBUNDLE.rst
new file mode 100644
index 000000000..e0727b547
--- /dev/null
+++ b/Help/variable/CMAKE_FIND_APPBUNDLE.rst
@@ -0,0 +1,22 @@
+CMAKE_FIND_APPBUNDLE
+--------------------
+
+This variable affects how ``find_*`` commands choose between
+OS X Application Bundles and unix-style package components.
+
+On Darwin or systems supporting OS X Application Bundles, the
+``CMAKE_FIND_APPBUNDLE`` variable can be set to empty or
+one of the following:
+
+``FIRST``
+ Try to find application bundles before standard programs.
+ This is the default on Darwin.
+
+``LAST``
+ Try to find application bundles after standard programs.
+
+``ONLY``
+ Only try to find application bundles.
+
+``NEVER``
+ Never try to find application bundles.
diff --git a/Help/variable/CMAKE_FIND_FRAMEWORK.rst b/Help/variable/CMAKE_FIND_FRAMEWORK.rst
new file mode 100644
index 000000000..790694ac5
--- /dev/null
+++ b/Help/variable/CMAKE_FIND_FRAMEWORK.rst
@@ -0,0 +1,22 @@
+CMAKE_FIND_FRAMEWORK
+--------------------
+
+This variable affects how ``find_*`` commands choose between
+OS X Frameworks and unix-style package components.
+
+On Darwin or systems supporting OS X Frameworks, the
+``CMAKE_FIND_FRAMEWORK`` variable can be set to empty or
+one of the following:
+
+``FIRST``
+ Try to find frameworks before standard libraries or headers.
+ This is the default on Darwin.
+
+``LAST``
+ Try to find frameworks after standard libraries or headers.
+
+``ONLY``
+ Only try to find frameworks.
+
+``NEVER``
+ Never try to find frameworks.
diff --git a/Help/variable/CMAKE_FIND_LIBRARY_PREFIXES.rst b/Help/variable/CMAKE_FIND_LIBRARY_PREFIXES.rst
new file mode 100644
index 000000000..58354b2b2
--- /dev/null
+++ b/Help/variable/CMAKE_FIND_LIBRARY_PREFIXES.rst
@@ -0,0 +1,9 @@
+CMAKE_FIND_LIBRARY_PREFIXES
+---------------------------
+
+Prefixes to prepend when looking for libraries.
+
+This specifies what prefixes to add to library names when the
+:command:`find_library` command looks for libraries. On UNIX systems this is
+typically ``lib``, meaning that when trying to find the ``foo`` library it
+will look for ``libfoo``.
diff --git a/Help/variable/CMAKE_FIND_LIBRARY_SUFFIXES.rst b/Help/variable/CMAKE_FIND_LIBRARY_SUFFIXES.rst
new file mode 100644
index 000000000..4a64e33e9
--- /dev/null
+++ b/Help/variable/CMAKE_FIND_LIBRARY_SUFFIXES.rst
@@ -0,0 +1,9 @@
+CMAKE_FIND_LIBRARY_SUFFIXES
+---------------------------
+
+Suffixes to append when looking for libraries.
+
+This specifies what suffixes to add to library names when the
+:command:`find_library` command looks for libraries. On Windows systems this
+is typically ``.lib`` and ``.dll``, meaning that when trying to find the
+``foo`` library it will look for ``foo.dll`` etc.
diff --git a/Help/variable/CMAKE_FIND_NO_INSTALL_PREFIX.rst b/Help/variable/CMAKE_FIND_NO_INSTALL_PREFIX.rst
new file mode 100644
index 000000000..c49d2641b
--- /dev/null
+++ b/Help/variable/CMAKE_FIND_NO_INSTALL_PREFIX.rst
@@ -0,0 +1,15 @@
+CMAKE_FIND_NO_INSTALL_PREFIX
+----------------------------
+
+Ignore the :variable:`CMAKE_INSTALL_PREFIX` when searching for assets.
+
+CMake adds the :variable:`CMAKE_INSTALL_PREFIX` and the
+:variable:`CMAKE_STAGING_PREFIX` variable to the
+:variable:`CMAKE_SYSTEM_PREFIX_PATH` by default. This variable may be set
+on the command line to control that behavior.
+
+Set ``CMAKE_FIND_NO_INSTALL_PREFIX`` to ``TRUE`` to tell
+:command:`find_package` not to search in the :variable:`CMAKE_INSTALL_PREFIX`
+or :variable:`CMAKE_STAGING_PREFIX` by default. Note that the
+prefix may still be searched for other reasons, such as being the same prefix
+as the CMake installation, or for being a built-in system prefix.
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_NAME.rst b/Help/variable/CMAKE_FIND_PACKAGE_NAME.rst
new file mode 100644
index 000000000..bd1a30f52
--- /dev/null
+++ b/Help/variable/CMAKE_FIND_PACKAGE_NAME.rst
@@ -0,0 +1,6 @@
+CMAKE_FIND_PACKAGE_NAME
+-----------------------
+
+Defined by the :command:`find_package` command while loading
+a find module to record the caller-specified package name.
+See command documentation for details.
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY.rst b/Help/variable/CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY.rst
new file mode 100644
index 000000000..90584710e
--- /dev/null
+++ b/Help/variable/CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY.rst
@@ -0,0 +1,13 @@
+CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY
+--------------------------------------
+
+Skip :ref:`User Package Registry` in :command:`find_package` calls.
+
+In some cases, for example to locate only system wide installations, it
+is not desirable to use the :ref:`User Package Registry` when searching
+for packages. If the :variable:`CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY`
+variable is enabled, all the :command:`find_package` commands will skip
+the :ref:`User Package Registry` as if they were called with the
+``NO_CMAKE_PACKAGE_REGISTRY`` argument.
+
+See also :ref:`Disabling the Package Registry`.
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY.rst b/Help/variable/CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY.rst
new file mode 100644
index 000000000..44588b17a
--- /dev/null
+++ b/Help/variable/CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY.rst
@@ -0,0 +1,13 @@
+CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY
+---------------------------------------------
+
+Skip :ref:`System Package Registry` in :command:`find_package` calls.
+
+In some cases, it is not desirable to use the
+:ref:`System Package Registry` when searching for packages. If the
+:variable:`CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY` variable is
+enabled, all the :command:`find_package` commands will skip
+the :ref:`System Package Registry` as if they were called with the
+``NO_CMAKE_SYSTEM_PACKAGE_REGISTRY`` argument.
+
+See also :ref:`Disabling the Package Registry`.
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_WARN_NO_MODULE.rst b/Help/variable/CMAKE_FIND_PACKAGE_WARN_NO_MODULE.rst
new file mode 100644
index 000000000..f1116bb62
--- /dev/null
+++ b/Help/variable/CMAKE_FIND_PACKAGE_WARN_NO_MODULE.rst
@@ -0,0 +1,19 @@
+CMAKE_FIND_PACKAGE_WARN_NO_MODULE
+---------------------------------
+
+Tell :command:`find_package` to warn if called without an explicit mode.
+
+If :command:`find_package` is called without an explicit mode option
+(``MODULE``, ``CONFIG``, or ``NO_MODULE``) and no ``Find<pkg>.cmake`` module
+is in :variable:`CMAKE_MODULE_PATH` then CMake implicitly assumes that the
+caller intends to search for a package configuration file. If no package
+configuration file is found then the wording of the failure message
+must account for both the case that the package is really missing and
+the case that the project has a bug and failed to provide the intended
+Find module. If instead the caller specifies an explicit mode option
+then the failure message can be more specific.
+
+Set ``CMAKE_FIND_PACKAGE_WARN_NO_MODULE`` to ``TRUE`` to tell
+:command:`find_package` to warn when it implicitly assumes Config mode. This
+helps developers enforce use of an explicit mode in all calls to
+:command:`find_package` within a project.
diff --git a/Help/variable/CMAKE_FIND_ROOT_PATH.rst b/Help/variable/CMAKE_FIND_ROOT_PATH.rst
new file mode 100644
index 000000000..ba2cf313e
--- /dev/null
+++ b/Help/variable/CMAKE_FIND_ROOT_PATH.rst
@@ -0,0 +1,8 @@
+CMAKE_FIND_ROOT_PATH
+--------------------
+
+:ref:`;-list <CMake Language Lists>` of root paths to search on the filesystem.
+
+This variable is most useful when cross-compiling. CMake uses the paths in
+this list as alternative roots to find filesystem items with
+:command:`find_package`, :command:`find_library` etc.
diff --git a/Help/variable/CMAKE_FIND_ROOT_PATH_MODE_INCLUDE.rst b/Help/variable/CMAKE_FIND_ROOT_PATH_MODE_INCLUDE.rst
new file mode 100644
index 000000000..df1af5a88
--- /dev/null
+++ b/Help/variable/CMAKE_FIND_ROOT_PATH_MODE_INCLUDE.rst
@@ -0,0 +1,6 @@
+CMAKE_FIND_ROOT_PATH_MODE_INCLUDE
+---------------------------------
+
+.. |FIND_XXX| replace:: :command:`find_file` and :command:`find_path`
+
+.. include:: CMAKE_FIND_ROOT_PATH_MODE_XXX.txt
diff --git a/Help/variable/CMAKE_FIND_ROOT_PATH_MODE_LIBRARY.rst b/Help/variable/CMAKE_FIND_ROOT_PATH_MODE_LIBRARY.rst
new file mode 100644
index 000000000..52ab89dc5
--- /dev/null
+++ b/Help/variable/CMAKE_FIND_ROOT_PATH_MODE_LIBRARY.rst
@@ -0,0 +1,6 @@
+CMAKE_FIND_ROOT_PATH_MODE_LIBRARY
+---------------------------------
+
+.. |FIND_XXX| replace:: :command:`find_library`
+
+.. include:: CMAKE_FIND_ROOT_PATH_MODE_XXX.txt
diff --git a/Help/variable/CMAKE_FIND_ROOT_PATH_MODE_PACKAGE.rst b/Help/variable/CMAKE_FIND_ROOT_PATH_MODE_PACKAGE.rst
new file mode 100644
index 000000000..387294797
--- /dev/null
+++ b/Help/variable/CMAKE_FIND_ROOT_PATH_MODE_PACKAGE.rst
@@ -0,0 +1,6 @@
+CMAKE_FIND_ROOT_PATH_MODE_PACKAGE
+---------------------------------
+
+.. |FIND_XXX| replace:: :command:`find_package`
+
+.. include:: CMAKE_FIND_ROOT_PATH_MODE_XXX.txt
diff --git a/Help/variable/CMAKE_FIND_ROOT_PATH_MODE_PROGRAM.rst b/Help/variable/CMAKE_FIND_ROOT_PATH_MODE_PROGRAM.rst
new file mode 100644
index 000000000..d24a78a3f
--- /dev/null
+++ b/Help/variable/CMAKE_FIND_ROOT_PATH_MODE_PROGRAM.rst
@@ -0,0 +1,6 @@
+CMAKE_FIND_ROOT_PATH_MODE_PROGRAM
+---------------------------------
+
+.. |FIND_XXX| replace:: :command:`find_program`
+
+.. include:: CMAKE_FIND_ROOT_PATH_MODE_XXX.txt
diff --git a/Help/variable/CMAKE_FIND_ROOT_PATH_MODE_XXX.txt b/Help/variable/CMAKE_FIND_ROOT_PATH_MODE_XXX.txt
new file mode 100644
index 000000000..ab65e090e
--- /dev/null
+++ b/Help/variable/CMAKE_FIND_ROOT_PATH_MODE_XXX.txt
@@ -0,0 +1,8 @@
+This variable controls whether the :variable:`CMAKE_FIND_ROOT_PATH` and
+:variable:`CMAKE_SYSROOT` are used by |FIND_XXX|.
+
+If set to ``ONLY``, then only the roots in :variable:`CMAKE_FIND_ROOT_PATH`
+will be searched. If set to ``NEVER``, then the roots in
+:variable:`CMAKE_FIND_ROOT_PATH` will be ignored and only the host system
+root will be used. If set to ``BOTH``, then the host system paths and the
+paths in :variable:`CMAKE_FIND_ROOT_PATH` will be searched.
diff --git a/Help/variable/CMAKE_FRAMEWORK_PATH.rst b/Help/variable/CMAKE_FRAMEWORK_PATH.rst
new file mode 100644
index 000000000..5ff08e679
--- /dev/null
+++ b/Help/variable/CMAKE_FRAMEWORK_PATH.rst
@@ -0,0 +1,7 @@
+CMAKE_FRAMEWORK_PATH
+--------------------
+
+:ref:`;-list <CMake Language Lists>` of directories specifying a search path
+for OS X frameworks used by the :command:`find_library`,
+:command:`find_package`, :command:`find_path`, and :command:`find_file`
+commands.
diff --git a/Help/variable/CMAKE_Fortran_FORMAT.rst b/Help/variable/CMAKE_Fortran_FORMAT.rst
new file mode 100644
index 000000000..1406e59b1
--- /dev/null
+++ b/Help/variable/CMAKE_Fortran_FORMAT.rst
@@ -0,0 +1,7 @@
+CMAKE_Fortran_FORMAT
+--------------------
+
+Set to ``FIXED`` or ``FREE`` to indicate the Fortran source layout.
+
+This variable is used to initialize the :prop_tgt:`Fortran_FORMAT` property on
+all the targets. See that target property for additional information.
diff --git a/Help/variable/CMAKE_Fortran_MODDIR_DEFAULT.rst b/Help/variable/CMAKE_Fortran_MODDIR_DEFAULT.rst
new file mode 100644
index 000000000..5aeab0757
--- /dev/null
+++ b/Help/variable/CMAKE_Fortran_MODDIR_DEFAULT.rst
@@ -0,0 +1,8 @@
+CMAKE_Fortran_MODDIR_DEFAULT
+----------------------------
+
+Fortran default module output directory.
+
+Most Fortran compilers write ``.mod`` files to the current working
+directory. For those that do not, this is set to ``.`` and used when
+the :prop_tgt:`Fortran_MODULE_DIRECTORY` target property is not set.
diff --git a/Help/variable/CMAKE_Fortran_MODDIR_FLAG.rst b/Help/variable/CMAKE_Fortran_MODDIR_FLAG.rst
new file mode 100644
index 000000000..1da55cade
--- /dev/null
+++ b/Help/variable/CMAKE_Fortran_MODDIR_FLAG.rst
@@ -0,0 +1,7 @@
+CMAKE_Fortran_MODDIR_FLAG
+-------------------------
+
+Fortran flag for module output directory.
+
+This stores the flag needed to pass the value of the
+:prop_tgt:`Fortran_MODULE_DIRECTORY` target property to the compiler.
diff --git a/Help/variable/CMAKE_Fortran_MODOUT_FLAG.rst b/Help/variable/CMAKE_Fortran_MODOUT_FLAG.rst
new file mode 100644
index 000000000..2f8388017
--- /dev/null
+++ b/Help/variable/CMAKE_Fortran_MODOUT_FLAG.rst
@@ -0,0 +1,7 @@
+CMAKE_Fortran_MODOUT_FLAG
+-------------------------
+
+Fortran flag to enable module output.
+
+Most Fortran compilers write ``.mod`` files out by default. For others,
+this stores the flag needed to enable module output.
diff --git a/Help/variable/CMAKE_Fortran_MODULE_DIRECTORY.rst b/Help/variable/CMAKE_Fortran_MODULE_DIRECTORY.rst
new file mode 100644
index 000000000..3c7edc1cf
--- /dev/null
+++ b/Help/variable/CMAKE_Fortran_MODULE_DIRECTORY.rst
@@ -0,0 +1,8 @@
+CMAKE_Fortran_MODULE_DIRECTORY
+------------------------------
+
+Fortran module output directory.
+
+This variable is used to initialize the :prop_tgt:`Fortran_MODULE_DIRECTORY`
+property on all the targets. See that target property for additional
+information.
diff --git a/Help/variable/CMAKE_GENERATOR.rst b/Help/variable/CMAKE_GENERATOR.rst
new file mode 100644
index 000000000..3f6ebc1cd
--- /dev/null
+++ b/Help/variable/CMAKE_GENERATOR.rst
@@ -0,0 +1,7 @@
+CMAKE_GENERATOR
+---------------
+
+The generator used to build the project. See :manual:`cmake-generators(7)`.
+
+The name of the generator that is being used to generate the build
+files. (e.g. ``Unix Makefiles``, ``Visual Studio 6``, etc.)
diff --git a/Help/variable/CMAKE_GENERATOR_PLATFORM.rst b/Help/variable/CMAKE_GENERATOR_PLATFORM.rst
new file mode 100644
index 000000000..a5c284a87
--- /dev/null
+++ b/Help/variable/CMAKE_GENERATOR_PLATFORM.rst
@@ -0,0 +1,15 @@
+CMAKE_GENERATOR_PLATFORM
+------------------------
+
+Generator-specific target platform name specified by user.
+
+Some CMake generators support a target platform name to be given
+to the native build system to choose a compiler toolchain.
+If the user specifies a platform name (e.g. via the :manual:`cmake(1)` ``-A``
+option) the value will be available in this variable.
+
+The value of this variable should never be modified by project code.
+A toolchain file specified by the :variable:`CMAKE_TOOLCHAIN_FILE`
+variable may initialize ``CMAKE_GENERATOR_PLATFORM``. Once a given
+build tree has been initialized with a particular value for this
+variable, changing the value has undefined behavior.
diff --git a/Help/variable/CMAKE_GENERATOR_TOOLSET.rst b/Help/variable/CMAKE_GENERATOR_TOOLSET.rst
new file mode 100644
index 000000000..89abe5498
--- /dev/null
+++ b/Help/variable/CMAKE_GENERATOR_TOOLSET.rst
@@ -0,0 +1,15 @@
+CMAKE_GENERATOR_TOOLSET
+-----------------------
+
+Native build system toolset name specified by user.
+
+Some CMake generators support a toolset name to be given to the native
+build system to choose a compiler. If the user specifies a toolset
+name (e.g. via the :manual:`cmake(1)` ``-T`` option) the value will be
+available in this variable.
+
+The value of this variable should never be modified by project code.
+A toolchain file specified by the :variable:`CMAKE_TOOLCHAIN_FILE`
+variable may initialize ``CMAKE_GENERATOR_TOOLSET``. Once a given
+build tree has been initialized with a particular value for this
+variable, changing the value has undefined behavior.
diff --git a/Help/variable/CMAKE_GNUtoMS.rst b/Help/variable/CMAKE_GNUtoMS.rst
new file mode 100644
index 000000000..9c0f59e22
--- /dev/null
+++ b/Help/variable/CMAKE_GNUtoMS.rst
@@ -0,0 +1,8 @@
+CMAKE_GNUtoMS
+-------------
+
+Convert GNU import libraries (``.dll.a``) to MS format (``.lib``).
+
+This variable is used to initialize the :prop_tgt:`GNUtoMS` property on
+targets when they are created. See that target property for additional
+information.
diff --git a/Help/variable/CMAKE_HOME_DIRECTORY.rst b/Help/variable/CMAKE_HOME_DIRECTORY.rst
new file mode 100644
index 000000000..fdc5d8190
--- /dev/null
+++ b/Help/variable/CMAKE_HOME_DIRECTORY.rst
@@ -0,0 +1,6 @@
+CMAKE_HOME_DIRECTORY
+--------------------
+
+Path to top of source tree.
+
+This is the path to the top level of the source tree.
diff --git a/Help/variable/CMAKE_HOST_APPLE.rst b/Help/variable/CMAKE_HOST_APPLE.rst
new file mode 100644
index 000000000..ac7b03004
--- /dev/null
+++ b/Help/variable/CMAKE_HOST_APPLE.rst
@@ -0,0 +1,6 @@
+CMAKE_HOST_APPLE
+----------------
+
+``True`` for Apple OS X operating systems.
+
+Set to ``true`` when the host system is Apple OS X.
diff --git a/Help/variable/CMAKE_HOST_SYSTEM.rst b/Help/variable/CMAKE_HOST_SYSTEM.rst
new file mode 100644
index 000000000..c2a8f1a5f
--- /dev/null
+++ b/Help/variable/CMAKE_HOST_SYSTEM.rst
@@ -0,0 +1,10 @@
+CMAKE_HOST_SYSTEM
+-----------------
+
+Composit Name of OS CMake is being run on.
+
+This variable is the composite of :variable:`CMAKE_HOST_SYSTEM_NAME` and
+:variable:`CMAKE_HOST_SYSTEM_VERSION`, e.g.
+``${CMAKE_HOST_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_VERSION}``. If
+:variable:`CMAKE_HOST_SYSTEM_VERSION` is not set, then this variable is
+the same as :variable:`CMAKE_HOST_SYSTEM_NAME`.
diff --git a/Help/variable/CMAKE_HOST_SYSTEM_NAME.rst b/Help/variable/CMAKE_HOST_SYSTEM_NAME.rst
new file mode 100644
index 000000000..c67359272
--- /dev/null
+++ b/Help/variable/CMAKE_HOST_SYSTEM_NAME.rst
@@ -0,0 +1,8 @@
+CMAKE_HOST_SYSTEM_NAME
+----------------------
+
+Name of the OS CMake is running on.
+
+On systems that have the uname command, this variable is set to the
+output of ``uname -s``. ``Linux``, ``Windows``, and ``Darwin`` for OS X
+are the values found on the big three operating systems.
diff --git a/Help/variable/CMAKE_HOST_SYSTEM_PROCESSOR.rst b/Help/variable/CMAKE_HOST_SYSTEM_PROCESSOR.rst
new file mode 100644
index 000000000..ba8a850cd
--- /dev/null
+++ b/Help/variable/CMAKE_HOST_SYSTEM_PROCESSOR.rst
@@ -0,0 +1,8 @@
+CMAKE_HOST_SYSTEM_PROCESSOR
+---------------------------
+
+The name of the CPU CMake is running on.
+
+On systems that support ``uname``, this variable is set to the output of
+``uname -p``. On Windows it is set to the value of the environment variable
+``PROCESSOR_ARCHITECTURE``.
diff --git a/Help/variable/CMAKE_HOST_SYSTEM_VERSION.rst b/Help/variable/CMAKE_HOST_SYSTEM_VERSION.rst
new file mode 100644
index 000000000..ed230704c
--- /dev/null
+++ b/Help/variable/CMAKE_HOST_SYSTEM_VERSION.rst
@@ -0,0 +1,8 @@
+CMAKE_HOST_SYSTEM_VERSION
+-------------------------
+
+The OS version CMake is running on.
+
+A numeric version string for the system. On systems that support
+``uname``, this variable is set to the output of ``uname -r``. On other
+systems this is set to major-minor version numbers.
diff --git a/Help/variable/CMAKE_HOST_UNIX.rst b/Help/variable/CMAKE_HOST_UNIX.rst
new file mode 100644
index 000000000..817a957e9
--- /dev/null
+++ b/Help/variable/CMAKE_HOST_UNIX.rst
@@ -0,0 +1,7 @@
+CMAKE_HOST_UNIX
+---------------
+
+``True`` for UNIX and UNIX like operating systems.
+
+Set to ``true`` when the host system is UNIX or UNIX like (i.e. APPLE and
+CYGWIN).
diff --git a/Help/variable/CMAKE_HOST_WIN32.rst b/Help/variable/CMAKE_HOST_WIN32.rst
new file mode 100644
index 000000000..0e4c891a9
--- /dev/null
+++ b/Help/variable/CMAKE_HOST_WIN32.rst
@@ -0,0 +1,6 @@
+CMAKE_HOST_WIN32
+----------------
+
+``True`` on Windows systems, including Win64.
+
+Set to ``true`` when the host system is Windows and on Cygwin.
diff --git a/Help/variable/CMAKE_IGNORE_PATH.rst b/Help/variable/CMAKE_IGNORE_PATH.rst
new file mode 100644
index 000000000..92f377086
--- /dev/null
+++ b/Help/variable/CMAKE_IGNORE_PATH.rst
@@ -0,0 +1,18 @@
+CMAKE_IGNORE_PATH
+-----------------
+
+:ref:`;-list <CMake Language Lists>` of directories to be *ignored* by
+the :command:`find_program`, :command:`find_library`, :command:`find_file`,
+and :command:`find_path` commands. This is useful in cross-compiling
+environments where some system directories contain incompatible but
+possibly linkable libraries. For example, on cross-compiled cluster
+environments, this allows a user to ignore directories containing
+libraries meant for the front-end machine.
+
+By default this is empty; it is intended to be set by the project.
+Note that ``CMAKE_IGNORE_PATH`` takes a list of directory names, *not*
+a list of prefixes. To ignore paths under prefixes (``bin``, ``include``,
+``lib``, etc.), specify them explicitly.
+
+See also the :variable:`CMAKE_PREFIX_PATH`, :variable:`CMAKE_LIBRARY_PATH`,
+:variable:`CMAKE_INCLUDE_PATH`, and :variable:`CMAKE_PROGRAM_PATH` variables.
diff --git a/Help/variable/CMAKE_IMPORT_LIBRARY_PREFIX.rst b/Help/variable/CMAKE_IMPORT_LIBRARY_PREFIX.rst
new file mode 100644
index 000000000..1561a1db9
--- /dev/null
+++ b/Help/variable/CMAKE_IMPORT_LIBRARY_PREFIX.rst
@@ -0,0 +1,9 @@
+CMAKE_IMPORT_LIBRARY_PREFIX
+---------------------------
+
+The prefix for import libraries that you link to.
+
+The prefix to use for the name of an import library if used on this
+platform.
+
+``CMAKE_IMPORT_LIBRARY_PREFIX_<LANG>`` overrides this for language ``<LANG>``.
diff --git a/Help/variable/CMAKE_IMPORT_LIBRARY_SUFFIX.rst b/Help/variable/CMAKE_IMPORT_LIBRARY_SUFFIX.rst
new file mode 100644
index 000000000..11aeab7e6
--- /dev/null
+++ b/Help/variable/CMAKE_IMPORT_LIBRARY_SUFFIX.rst
@@ -0,0 +1,9 @@
+CMAKE_IMPORT_LIBRARY_SUFFIX
+---------------------------
+
+The suffix for import libraries that you link to.
+
+The suffix to use for the end of an import library filename if used on
+this platform.
+
+``CMAKE_IMPORT_LIBRARY_SUFFIX_<LANG>`` overrides this for language ``<LANG>``.
diff --git a/Help/variable/CMAKE_INCLUDE_CURRENT_DIR.rst b/Help/variable/CMAKE_INCLUDE_CURRENT_DIR.rst
new file mode 100644
index 000000000..6eea322f8
--- /dev/null
+++ b/Help/variable/CMAKE_INCLUDE_CURRENT_DIR.rst
@@ -0,0 +1,13 @@
+CMAKE_INCLUDE_CURRENT_DIR
+-------------------------
+
+Automatically add the current source- and build directories to the include path.
+
+If this variable is enabled, CMake automatically adds
+:variable:`CMAKE_CURRENT_SOURCE_DIR` and :variable:`CMAKE_CURRENT_BINARY_DIR`
+to the include path for each directory. These additional include
+directories do not propagate down to subdirectories. This is useful
+mainly for out-of-source builds, where files generated into the build
+tree are included by files located in the source tree.
+
+By default ``CMAKE_INCLUDE_CURRENT_DIR`` is ``OFF``.
diff --git a/Help/variable/CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE.rst b/Help/variable/CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE.rst
new file mode 100644
index 000000000..5fc95f00b
--- /dev/null
+++ b/Help/variable/CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE.rst
@@ -0,0 +1,12 @@
+CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE
+--------------------------------------
+
+Automatically add the current source- and build directories to the
+:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` target property.
+
+If this variable is enabled, CMake automatically adds for each shared
+library target, static library target, module target and executable
+target, :variable:`CMAKE_CURRENT_SOURCE_DIR` and
+:variable:`CMAKE_CURRENT_BINARY_DIR` to
+the :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` target property. By default
+``CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE`` is ``OFF``.
diff --git a/Help/variable/CMAKE_INCLUDE_DIRECTORIES_BEFORE.rst b/Help/variable/CMAKE_INCLUDE_DIRECTORIES_BEFORE.rst
new file mode 100644
index 000000000..e0f2a2e55
--- /dev/null
+++ b/Help/variable/CMAKE_INCLUDE_DIRECTORIES_BEFORE.rst
@@ -0,0 +1,9 @@
+CMAKE_INCLUDE_DIRECTORIES_BEFORE
+--------------------------------
+
+Whether to append or prepend directories by default in
+:command:`include_directories`.
+
+This variable affects the default behavior of the :command:`include_directories`
+command. Setting this variable to ``ON`` is equivalent to using the ``BEFORE``
+option in all uses of that command.
diff --git a/Help/variable/CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE.rst b/Help/variable/CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE.rst
new file mode 100644
index 000000000..37d0a3d48
--- /dev/null
+++ b/Help/variable/CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE.rst
@@ -0,0 +1,8 @@
+CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE
+----------------------------------------
+
+Whether to force prepending of project include directories.
+
+This variable affects the order of include directories generated in compiler
+command lines. If set to ``ON``, it causes the :variable:`CMAKE_SOURCE_DIR`
+and the :variable:`CMAKE_BINARY_DIR` to appear first.
diff --git a/Help/variable/CMAKE_INCLUDE_PATH.rst b/Help/variable/CMAKE_INCLUDE_PATH.rst
new file mode 100644
index 000000000..e4e7f2cfc
--- /dev/null
+++ b/Help/variable/CMAKE_INCLUDE_PATH.rst
@@ -0,0 +1,7 @@
+CMAKE_INCLUDE_PATH
+------------------
+
+:ref:`;-list <CMake Language Lists>` of directories specifying a search path
+for the :command:`find_file` and :command:`find_path` commands. By default it
+is empty, it is intended to be set by the project. See also
+:variable:`CMAKE_SYSTEM_INCLUDE_PATH` and :variable:`CMAKE_PREFIX_PATH`.
diff --git a/Help/variable/CMAKE_INSTALL_DEFAULT_COMPONENT_NAME.rst b/Help/variable/CMAKE_INSTALL_DEFAULT_COMPONENT_NAME.rst
new file mode 100644
index 000000000..57160f1d9
--- /dev/null
+++ b/Help/variable/CMAKE_INSTALL_DEFAULT_COMPONENT_NAME.rst
@@ -0,0 +1,9 @@
+CMAKE_INSTALL_DEFAULT_COMPONENT_NAME
+------------------------------------
+
+Default component used in :command:`install` commands.
+
+If an :command:`install` command is used without the ``COMPONENT`` argument,
+these files will be grouped into a default component. The name of this
+default install component will be taken from this variable. It
+defaults to ``Unspecified``.
diff --git a/Help/variable/CMAKE_INSTALL_MESSAGE.rst b/Help/variable/CMAKE_INSTALL_MESSAGE.rst
new file mode 100644
index 000000000..304df268c
--- /dev/null
+++ b/Help/variable/CMAKE_INSTALL_MESSAGE.rst
@@ -0,0 +1,30 @@
+CMAKE_INSTALL_MESSAGE
+---------------------
+
+Specify verbosity of installation script code generated by the
+:command:`install` command (using the :command:`file(INSTALL)` command).
+For paths that are newly installed or updated, installation
+may print lines like::
+
+ -- Installing: /some/destination/path
+
+For paths that are already up to date, installation may print
+lines like::
+
+ -- Up-to-date: /some/destination/path
+
+The ``CMAKE_INSTALL_MESSAGE`` variable may be set to control
+which messages are printed:
+
+``ALWAYS``
+ Print both ``Installing`` and ``Up-to-date`` messages.
+
+``LAZY``
+ Print ``Installing`` but not ``Up-to-date`` messages.
+
+``NEVER``
+ Print neither ``Installing`` nor ``Up-to-date`` messages.
+
+Other values have undefined behavior and may not be diagnosed.
+
+If this variable is not set, the default behavior is ``ALWAYS``.
diff --git a/Help/variable/CMAKE_INSTALL_NAME_DIR.rst b/Help/variable/CMAKE_INSTALL_NAME_DIR.rst
new file mode 100644
index 000000000..1f2d62bf6
--- /dev/null
+++ b/Help/variable/CMAKE_INSTALL_NAME_DIR.rst
@@ -0,0 +1,8 @@
+CMAKE_INSTALL_NAME_DIR
+----------------------
+
+OS X directory name for installed targets.
+
+``CMAKE_INSTALL_NAME_DIR`` is used to initialize the
+:prop_tgt:`INSTALL_NAME_DIR` property on all targets. See that target
+property for more information.
diff --git a/Help/variable/CMAKE_INSTALL_PREFIX.rst b/Help/variable/CMAKE_INSTALL_PREFIX.rst
new file mode 100644
index 000000000..3f3347f2f
--- /dev/null
+++ b/Help/variable/CMAKE_INSTALL_PREFIX.rst
@@ -0,0 +1,35 @@
+CMAKE_INSTALL_PREFIX
+--------------------
+
+Install directory used by :command:`install`.
+
+If ``make install`` is invoked or ``INSTALL`` is built, this directory is
+prepended onto all install directories. This variable defaults to
+``/usr/local`` on UNIX and ``c:/Program Files`` on Windows.
+
+On UNIX one can use the ``DESTDIR`` mechanism in order to relocate the
+whole installation. ``DESTDIR`` means DESTination DIRectory. It is
+commonly used by makefile users in order to install software at
+non-default location. It is usually invoked like this:
+
+::
+
+ make DESTDIR=/home/john install
+
+which will install the concerned software using the installation
+prefix, e.g. ``/usr/local`` prepended with the ``DESTDIR`` value which
+finally gives ``/home/john/usr/local``.
+
+WARNING: ``DESTDIR`` may not be used on Windows because installation
+prefix usually contains a drive letter like in ``C:/Program Files``
+which cannot be prepended with some other prefix.
+
+The installation prefix is also added to :variable:`CMAKE_SYSTEM_PREFIX_PATH`
+so that :command:`find_package`, :command:`find_program`,
+:command:`find_library`, :command:`find_path`, and :command:`find_file`
+will search the prefix for other software.
+
+.. note::
+
+ Use the :module:`GNUInstallDirs` module to provide GNU-style
+ options for the layout of directories within the installation.
diff --git a/Help/variable/CMAKE_INSTALL_RPATH.rst b/Help/variable/CMAKE_INSTALL_RPATH.rst
new file mode 100644
index 000000000..813d1e0a7
--- /dev/null
+++ b/Help/variable/CMAKE_INSTALL_RPATH.rst
@@ -0,0 +1,8 @@
+CMAKE_INSTALL_RPATH
+-------------------
+
+The rpath to use for installed targets.
+
+A semicolon-separated list specifying the rpath to use in installed
+targets (for platforms that support it). This is used to initialize
+the target property :prop_tgt:`INSTALL_RPATH` for all targets.
diff --git a/Help/variable/CMAKE_INSTALL_RPATH_USE_LINK_PATH.rst b/Help/variable/CMAKE_INSTALL_RPATH_USE_LINK_PATH.rst
new file mode 100644
index 000000000..78148d5f5
--- /dev/null
+++ b/Help/variable/CMAKE_INSTALL_RPATH_USE_LINK_PATH.rst
@@ -0,0 +1,9 @@
+CMAKE_INSTALL_RPATH_USE_LINK_PATH
+---------------------------------
+
+Add paths to linker search and installed rpath.
+
+``CMAKE_INSTALL_RPATH_USE_LINK_PATH`` is a boolean that if set to ``true``
+will append directories in the linker search path and outside the
+project to the :prop_tgt:`INSTALL_RPATH`. This is used to initialize the
+target property :prop_tgt:`INSTALL_RPATH_USE_LINK_PATH` for all targets.
diff --git a/Help/variable/CMAKE_INTERNAL_PLATFORM_ABI.rst b/Help/variable/CMAKE_INTERNAL_PLATFORM_ABI.rst
new file mode 100644
index 000000000..9693bf658
--- /dev/null
+++ b/Help/variable/CMAKE_INTERNAL_PLATFORM_ABI.rst
@@ -0,0 +1,6 @@
+CMAKE_INTERNAL_PLATFORM_ABI
+---------------------------
+
+An internal variable subject to change.
+
+This is used in determining the compiler ABI and is subject to change.
diff --git a/Help/variable/CMAKE_IOS_INSTALL_COMBINED.rst b/Help/variable/CMAKE_IOS_INSTALL_COMBINED.rst
new file mode 100644
index 000000000..c5cb9b647
--- /dev/null
+++ b/Help/variable/CMAKE_IOS_INSTALL_COMBINED.rst
@@ -0,0 +1,8 @@
+CMAKE_IOS_INSTALL_COMBINED
+--------------------------
+
+Default value for :prop_tgt:`IOS_INSTALL_COMBINED` of targets.
+
+This variable is used to initialize the :prop_tgt:`IOS_INSTALL_COMBINED`
+property on all the targets. See that target property for additional
+information.
diff --git a/Help/variable/CMAKE_JOB_POOL_COMPILE.rst b/Help/variable/CMAKE_JOB_POOL_COMPILE.rst
new file mode 100644
index 000000000..e5c2d9a81
--- /dev/null
+++ b/Help/variable/CMAKE_JOB_POOL_COMPILE.rst
@@ -0,0 +1,6 @@
+CMAKE_JOB_POOL_COMPILE
+----------------------
+
+This variable is used to initialize the :prop_tgt:`JOB_POOL_COMPILE`
+property on all the targets. See :prop_tgt:`JOB_POOL_COMPILE`
+for additional information.
diff --git a/Help/variable/CMAKE_JOB_POOL_LINK.rst b/Help/variable/CMAKE_JOB_POOL_LINK.rst
new file mode 100644
index 000000000..338f7714e
--- /dev/null
+++ b/Help/variable/CMAKE_JOB_POOL_LINK.rst
@@ -0,0 +1,6 @@
+CMAKE_JOB_POOL_LINK
+----------------------
+
+This variable is used to initialize the :prop_tgt:`JOB_POOL_LINK`
+property on all the targets. See :prop_tgt:`JOB_POOL_LINK`
+for additional information.
diff --git a/Help/variable/CMAKE_LANG_ARCHIVE_APPEND.rst b/Help/variable/CMAKE_LANG_ARCHIVE_APPEND.rst
new file mode 100644
index 000000000..ab4ad7164
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_ARCHIVE_APPEND.rst
@@ -0,0 +1,10 @@
+CMAKE_<LANG>_ARCHIVE_APPEND
+---------------------------
+
+Rule variable to append to a static archive.
+
+This is a rule variable that tells CMake how to append to a static
+archive. It is used in place of :variable:`CMAKE_<LANG>_CREATE_STATIC_LIBRARY`
+on some platforms in order to support large object counts. See also
+:variable:`CMAKE_<LANG>_ARCHIVE_CREATE` and
+:variable:`CMAKE_<LANG>_ARCHIVE_FINISH`.
diff --git a/Help/variable/CMAKE_LANG_ARCHIVE_CREATE.rst b/Help/variable/CMAKE_LANG_ARCHIVE_CREATE.rst
new file mode 100644
index 000000000..fc295af2c
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_ARCHIVE_CREATE.rst
@@ -0,0 +1,10 @@
+CMAKE_<LANG>_ARCHIVE_CREATE
+---------------------------
+
+Rule variable to create a new static archive.
+
+This is a rule variable that tells CMake how to create a static
+archive. It is used in place of :variable:`CMAKE_<LANG>_CREATE_STATIC_LIBRARY`
+on some platforms in order to support large object counts. See also
+:variable:`CMAKE_<LANG>_ARCHIVE_APPEND` and
+:variable:`CMAKE_<LANG>_ARCHIVE_FINISH`.
diff --git a/Help/variable/CMAKE_LANG_ARCHIVE_FINISH.rst b/Help/variable/CMAKE_LANG_ARCHIVE_FINISH.rst
new file mode 100644
index 000000000..1bb5d651d
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_ARCHIVE_FINISH.rst
@@ -0,0 +1,10 @@
+CMAKE_<LANG>_ARCHIVE_FINISH
+---------------------------
+
+Rule variable to finish an existing static archive.
+
+This is a rule variable that tells CMake how to finish a static
+archive. It is used in place of :variable:`CMAKE_<LANG>_CREATE_STATIC_LIBRARY`
+on some platforms in order to support large object counts. See also
+:variable:`CMAKE_<LANG>_ARCHIVE_CREATE` and
+:variable:`CMAKE_<LANG>_ARCHIVE_APPEND`.
diff --git a/Help/variable/CMAKE_LANG_COMPILER.rst b/Help/variable/CMAKE_LANG_COMPILER.rst
new file mode 100644
index 000000000..89df4954e
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_COMPILER.rst
@@ -0,0 +1,7 @@
+CMAKE_<LANG>_COMPILER
+---------------------
+
+The full path to the compiler for ``LANG``.
+
+This is the command that will be used as the ``<LANG>`` compiler. Once
+set, you can not change this variable.
diff --git a/Help/variable/CMAKE_LANG_COMPILER_ABI.rst b/Help/variable/CMAKE_LANG_COMPILER_ABI.rst
new file mode 100644
index 000000000..be946c01b
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_COMPILER_ABI.rst
@@ -0,0 +1,6 @@
+CMAKE_<LANG>_COMPILER_ABI
+-------------------------
+
+An internal variable subject to change.
+
+This is used in determining the compiler ABI and is subject to change.
diff --git a/Help/variable/CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN.rst b/Help/variable/CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN.rst
new file mode 100644
index 000000000..8bb7cc08a
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN.rst
@@ -0,0 +1,13 @@
+CMAKE_<LANG>_COMPILER_EXTERNAL_TOOLCHAIN
+----------------------------------------
+
+The external toolchain for cross-compiling, if supported.
+
+Some compiler toolchains do not ship their own auxilliary utilities such as
+archivers and linkers. The compiler driver may support a command-line argument
+to specify the location of such tools.
+``CMAKE_<LANG>_COMPILER_EXTERNAL_TOOLCHAIN`` may be set to a path to a path to
+the external toolchain and will be passed to the compiler driver if supported.
+
+This variable may only be set in a toolchain file specified by
+the :variable:`CMAKE_TOOLCHAIN_FILE` variable.
diff --git a/Help/variable/CMAKE_LANG_COMPILER_ID.rst b/Help/variable/CMAKE_LANG_COMPILER_ID.rst
new file mode 100644
index 000000000..81976a918
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_COMPILER_ID.rst
@@ -0,0 +1,35 @@
+CMAKE_<LANG>_COMPILER_ID
+------------------------
+
+Compiler identification string.
+
+A short string unique to the compiler vendor. Possible values
+include:
+
+::
+
+ Absoft = Absoft Fortran (absoft.com)
+ ADSP = Analog VisualDSP++ (analog.com)
+ AppleClang = Apple Clang (apple.com)
+ ARMCC = ARM Compiler (arm.com)
+ CCur = Concurrent Fortran (ccur.com)
+ Clang = LLVM Clang (clang.llvm.org)
+ Cray = Cray Compiler (cray.com)
+ Embarcadero, Borland = Embarcadero (embarcadero.com)
+ G95 = G95 Fortran (g95.org)
+ GNU = GNU Compiler Collection (gcc.gnu.org)
+ HP = Hewlett-Packard Compiler (hp.com)
+ Intel = Intel Compiler (intel.com)
+ MIPSpro = SGI MIPSpro (sgi.com)
+ MSVC = Microsoft Visual Studio (microsoft.com)
+ OpenWatcom = Open Watcom (openwatcom.org)
+ PGI = The Portland Group (pgroup.com)
+ PathScale = PathScale (pathscale.com)
+ SDCC = Small Device C Compiler (sdcc.sourceforge.net)
+ SunPro = Oracle Solaris Studio (oracle.com)
+ TI = Texas Instruments (ti.com)
+ TinyCC = Tiny C Compiler (tinycc.org)
+ XL, VisualAge, zOS = IBM XL (ibm.com)
+
+This variable is not guaranteed to be defined for all compilers or
+languages.
diff --git a/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst b/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst
new file mode 100644
index 000000000..7961f609e
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst
@@ -0,0 +1,6 @@
+CMAKE_<LANG>_COMPILER_LAUNCHER
+------------------------------
+
+Default value for :prop_tgt:`<LANG>_COMPILER_LAUNCHER` target property.
+This variable is used to initialize the property on each target as it is
+created. This is done only when ``<LANG>`` is ``C`` or ``CXX``.
diff --git a/Help/variable/CMAKE_LANG_COMPILER_LOADED.rst b/Help/variable/CMAKE_LANG_COMPILER_LOADED.rst
new file mode 100644
index 000000000..9308878df
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_COMPILER_LOADED.rst
@@ -0,0 +1,7 @@
+CMAKE_<LANG>_COMPILER_LOADED
+----------------------------
+
+Defined to true if the language is enabled.
+
+When language ``<LANG>`` is enabled by :command:`project` or
+:command:`enable_language` this variable is defined to ``1``.
diff --git a/Help/variable/CMAKE_LANG_COMPILER_TARGET.rst b/Help/variable/CMAKE_LANG_COMPILER_TARGET.rst
new file mode 100644
index 000000000..656c57d2b
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_COMPILER_TARGET.rst
@@ -0,0 +1,11 @@
+CMAKE_<LANG>_COMPILER_TARGET
+----------------------------
+
+The target for cross-compiling, if supported.
+
+Some compiler drivers are inherently cross-compilers, such as clang and
+QNX qcc. These compiler drivers support a command-line argument to specify
+the target to cross-compile for.
+
+This variable may only be set in a toolchain file specified by
+the :variable:`CMAKE_TOOLCHAIN_FILE` variable.
diff --git a/Help/variable/CMAKE_LANG_COMPILER_VERSION.rst b/Help/variable/CMAKE_LANG_COMPILER_VERSION.rst
new file mode 100644
index 000000000..50e77eba0
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_COMPILER_VERSION.rst
@@ -0,0 +1,8 @@
+CMAKE_<LANG>_COMPILER_VERSION
+-----------------------------
+
+Compiler version string.
+
+Compiler version in major[.minor[.patch[.tweak]]] format. This
+variable is not guaranteed to be defined for all compilers or
+languages.
diff --git a/Help/variable/CMAKE_LANG_COMPILE_OBJECT.rst b/Help/variable/CMAKE_LANG_COMPILE_OBJECT.rst
new file mode 100644
index 000000000..ba59cad03
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_COMPILE_OBJECT.rst
@@ -0,0 +1,7 @@
+CMAKE_<LANG>_COMPILE_OBJECT
+---------------------------
+
+Rule variable to compile a single object file.
+
+This is a rule variable that tells CMake how to compile a single
+object file for the language ``<LANG>``.
diff --git a/Help/variable/CMAKE_LANG_CREATE_SHARED_LIBRARY.rst b/Help/variable/CMAKE_LANG_CREATE_SHARED_LIBRARY.rst
new file mode 100644
index 000000000..be89f8529
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_CREATE_SHARED_LIBRARY.rst
@@ -0,0 +1,7 @@
+CMAKE_<LANG>_CREATE_SHARED_LIBRARY
+----------------------------------
+
+Rule variable to create a shared library.
+
+This is a rule variable that tells CMake how to create a shared
+library for the language ``<LANG>``.
diff --git a/Help/variable/CMAKE_LANG_CREATE_SHARED_MODULE.rst b/Help/variable/CMAKE_LANG_CREATE_SHARED_MODULE.rst
new file mode 100644
index 000000000..ae5f69d56
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_CREATE_SHARED_MODULE.rst
@@ -0,0 +1,7 @@
+CMAKE_<LANG>_CREATE_SHARED_MODULE
+---------------------------------
+
+Rule variable to create a shared module.
+
+This is a rule variable that tells CMake how to create a shared
+library for the language ``<LANG>``.
diff --git a/Help/variable/CMAKE_LANG_CREATE_STATIC_LIBRARY.rst b/Help/variable/CMAKE_LANG_CREATE_STATIC_LIBRARY.rst
new file mode 100644
index 000000000..0cff200d5
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_CREATE_STATIC_LIBRARY.rst
@@ -0,0 +1,7 @@
+CMAKE_<LANG>_CREATE_STATIC_LIBRARY
+----------------------------------
+
+Rule variable to create a static library.
+
+This is a rule variable that tells CMake how to create a static
+library for the language ``<LANG>``.
diff --git a/Help/variable/CMAKE_LANG_FLAGS.rst b/Help/variable/CMAKE_LANG_FLAGS.rst
new file mode 100644
index 000000000..c57d92cbf
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_FLAGS.rst
@@ -0,0 +1,6 @@
+CMAKE_<LANG>_FLAGS
+------------------
+
+Flags for all build types.
+
+``<LANG>`` flags used regardless of the value of :variable:`CMAKE_BUILD_TYPE`.
diff --git a/Help/variable/CMAKE_LANG_FLAGS_DEBUG.rst b/Help/variable/CMAKE_LANG_FLAGS_DEBUG.rst
new file mode 100644
index 000000000..a233d4ad7
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_FLAGS_DEBUG.rst
@@ -0,0 +1,6 @@
+CMAKE_<LANG>_FLAGS_DEBUG
+------------------------
+
+Flags for ``Debug`` build type or configuration.
+
+``<LANG>`` flags used when :variable:`CMAKE_BUILD_TYPE` is ``Debug``.
diff --git a/Help/variable/CMAKE_LANG_FLAGS_MINSIZEREL.rst b/Help/variable/CMAKE_LANG_FLAGS_MINSIZEREL.rst
new file mode 100644
index 000000000..a9436c184
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_FLAGS_MINSIZEREL.rst
@@ -0,0 +1,7 @@
+CMAKE_<LANG>_FLAGS_MINSIZEREL
+-----------------------------
+
+Flags for ``MinSizeRel`` build type or configuration.
+
+``<LANG>`` flags used when :variable:`CMAKE_BUILD_TYPE` is ``MinSizeRel``
+(short for minimum size release).
diff --git a/Help/variable/CMAKE_LANG_FLAGS_RELEASE.rst b/Help/variable/CMAKE_LANG_FLAGS_RELEASE.rst
new file mode 100644
index 000000000..ffc5d795d
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_FLAGS_RELEASE.rst
@@ -0,0 +1,6 @@
+CMAKE_<LANG>_FLAGS_RELEASE
+--------------------------
+
+Flags for ``Release`` build type or configuration.
+
+``<LANG>`` flags used when :variable:`CMAKE_BUILD_TYPE` is ``Release``.
diff --git a/Help/variable/CMAKE_LANG_FLAGS_RELWITHDEBINFO.rst b/Help/variable/CMAKE_LANG_FLAGS_RELWITHDEBINFO.rst
new file mode 100644
index 000000000..962768e44
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_FLAGS_RELWITHDEBINFO.rst
@@ -0,0 +1,7 @@
+CMAKE_<LANG>_FLAGS_RELWITHDEBINFO
+---------------------------------
+
+Flags for ``RelWithDebInfo`` type or configuration.
+
+``<LANG>`` flags used when :variable:`CMAKE_BUILD_TYPE` is ``RelWithDebInfo``
+(short for Release With Debug Information).
diff --git a/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_DEBUG.rst b/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_DEBUG.rst
new file mode 100644
index 000000000..1f639a3ba
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_DEBUG.rst
@@ -0,0 +1,6 @@
+CMAKE_<LANG>_GHS_KERNEL_FLAGS_DEBUG
+-----------------------------------
+
+GHS kernel flags for ``Debug`` build type or configuration.
+
+``<LANG>`` flags used when :variable:`CMAKE_BUILD_TYPE` is ``Debug``.
diff --git a/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_MINSIZEREL.rst b/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_MINSIZEREL.rst
new file mode 100644
index 000000000..94e21150a
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_MINSIZEREL.rst
@@ -0,0 +1,7 @@
+CMAKE_<LANG>_GHS_KERNEL_FLAGS_MINSIZEREL
+----------------------------------------
+
+GHS kernel flags for ``MinSizeRel`` build type or configuration.
+
+``<LANG>`` flags used when :variable:`CMAKE_BUILD_TYPE` is ``MinSizeRel``
+(short for minimum size release).
diff --git a/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELEASE.rst b/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELEASE.rst
new file mode 100644
index 000000000..74566efca
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELEASE.rst
@@ -0,0 +1,6 @@
+CMAKE_<LANG>_GHS_KERNEL_FLAGS_RELEASE
+-------------------------------------
+
+GHS kernel flags for ``Release`` build type or configuration.
+
+``<LANG>`` flags used when :variable:`CMAKE_BUILD_TYPE` is ``Release``.
diff --git a/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELWITHDEBINFO.rst b/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELWITHDEBINFO.rst
new file mode 100644
index 000000000..d148193d8
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELWITHDEBINFO.rst
@@ -0,0 +1,7 @@
+CMAKE_<LANG>_GHS_KERNEL_FLAGS_RELWITHDEBINFO
+--------------------------------------------
+
+GHS kernel flags for ``RelWithDebInfo`` type or configuration.
+
+``<LANG>`` flags used when :variable:`CMAKE_BUILD_TYPE` is ``RelWithDebInfo``
+(short for Release With Debug Information).
diff --git a/Help/variable/CMAKE_LANG_IGNORE_EXTENSIONS.rst b/Help/variable/CMAKE_LANG_IGNORE_EXTENSIONS.rst
new file mode 100644
index 000000000..3d07e912b
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_IGNORE_EXTENSIONS.rst
@@ -0,0 +1,7 @@
+CMAKE_<LANG>_IGNORE_EXTENSIONS
+------------------------------
+
+File extensions that should be ignored by the build.
+
+This is a list of file extensions that may be part of a project for a
+given language but are not compiled.
diff --git a/Help/variable/CMAKE_LANG_IMPLICIT_INCLUDE_DIRECTORIES.rst b/Help/variable/CMAKE_LANG_IMPLICIT_INCLUDE_DIRECTORIES.rst
new file mode 100644
index 000000000..cc8085107
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_IMPLICIT_INCLUDE_DIRECTORIES.rst
@@ -0,0 +1,9 @@
+CMAKE_<LANG>_IMPLICIT_INCLUDE_DIRECTORIES
+-----------------------------------------
+
+Directories implicitly searched by the compiler for header files.
+
+CMake does not explicitly specify these directories on compiler
+command lines for language ``<LANG>``. This prevents system include
+directories from being treated as user include directories on some
+compilers.
diff --git a/Help/variable/CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES.rst b/Help/variable/CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES.rst
new file mode 100644
index 000000000..a0bd8303c
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES.rst
@@ -0,0 +1,17 @@
+CMAKE_<LANG>_IMPLICIT_LINK_DIRECTORIES
+--------------------------------------
+
+Implicit linker search path detected for language ``<LANG>``.
+
+Compilers typically pass directories containing language runtime
+libraries and default library search paths when they invoke a linker.
+These paths are implicit linker search directories for the compiler's
+language. CMake automatically detects these directories for each
+language and reports the results in this variable.
+
+When a library in one of these directories is given by full path to
+:command:`target_link_libraries` CMake will generate the ``-l<name>`` form on
+link lines to ensure the linker searches its implicit directories for the
+library. Note that some toolchains read implicit directories from an
+environment variable such as ``LIBRARY_PATH`` so keep its value consistent
+when operating in a given build tree.
diff --git a/Help/variable/CMAKE_LANG_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES.rst b/Help/variable/CMAKE_LANG_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES.rst
new file mode 100644
index 000000000..61ccc5a16
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES.rst
@@ -0,0 +1,8 @@
+CMAKE_<LANG>_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES
+------------------------------------------------
+
+Implicit linker framework search path detected for language ``<LANG>``.
+
+These paths are implicit linker framework search directories for the
+compiler's language. CMake automatically detects these directories
+for each language and reports the results in this variable.
diff --git a/Help/variable/CMAKE_LANG_IMPLICIT_LINK_LIBRARIES.rst b/Help/variable/CMAKE_LANG_IMPLICIT_LINK_LIBRARIES.rst
new file mode 100644
index 000000000..ec164774b
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_IMPLICIT_LINK_LIBRARIES.rst
@@ -0,0 +1,10 @@
+CMAKE_<LANG>_IMPLICIT_LINK_LIBRARIES
+------------------------------------
+
+Implicit link libraries and flags detected for language ``<LANG>``.
+
+Compilers typically pass language runtime library names and other
+flags when they invoke a linker. These flags are implicit link
+options for the compiler's language. CMake automatically detects
+these libraries and flags for each language and reports the results in
+this variable.
diff --git a/Help/variable/CMAKE_LANG_INCLUDE_WHAT_YOU_USE.rst b/Help/variable/CMAKE_LANG_INCLUDE_WHAT_YOU_USE.rst
new file mode 100644
index 000000000..2c8028a60
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_INCLUDE_WHAT_YOU_USE.rst
@@ -0,0 +1,6 @@
+CMAKE_<LANG>_INCLUDE_WHAT_YOU_USE
+---------------------------------
+
+Default value for :prop_tgt:`<LANG>_INCLUDE_WHAT_YOU_USE` target property.
+This variable is used to initialize the property on each target as it is
+created. This is done only when ``<LANG>`` is ``C`` or ``CXX``.
diff --git a/Help/variable/CMAKE_LANG_LIBRARY_ARCHITECTURE.rst b/Help/variable/CMAKE_LANG_LIBRARY_ARCHITECTURE.rst
new file mode 100644
index 000000000..7f888eed7
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_LIBRARY_ARCHITECTURE.rst
@@ -0,0 +1,8 @@
+CMAKE_<LANG>_LIBRARY_ARCHITECTURE
+---------------------------------
+
+Target architecture library directory name detected for ``<LANG>``.
+
+If the ``<LANG>`` compiler passes to the linker an architecture-specific
+system library search directory such as ``<prefix>/lib/<arch>`` this
+variable contains the ``<arch>`` name if/as detected by CMake.
diff --git a/Help/variable/CMAKE_LANG_LINKER_PREFERENCE.rst b/Help/variable/CMAKE_LANG_LINKER_PREFERENCE.rst
new file mode 100644
index 000000000..ff82f8b4c
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_LINKER_PREFERENCE.rst
@@ -0,0 +1,11 @@
+CMAKE_<LANG>_LINKER_PREFERENCE
+------------------------------
+
+Preference value for linker language selection.
+
+The "linker language" for executable, shared library, and module
+targets is the language whose compiler will invoke the linker. The
+:prop_tgt:`LINKER_LANGUAGE` target property sets the language explicitly.
+Otherwise, the linker language is that whose linker preference value
+is highest among languages compiled and linked into the target. See
+also the :variable:`CMAKE_<LANG>_LINKER_PREFERENCE_PROPAGATES` variable.
diff --git a/Help/variable/CMAKE_LANG_LINKER_PREFERENCE_PROPAGATES.rst b/Help/variable/CMAKE_LANG_LINKER_PREFERENCE_PROPAGATES.rst
new file mode 100644
index 000000000..dbbeb0afb
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_LINKER_PREFERENCE_PROPAGATES.rst
@@ -0,0 +1,9 @@
+CMAKE_<LANG>_LINKER_PREFERENCE_PROPAGATES
+-----------------------------------------
+
+True if :variable:`CMAKE_<LANG>_LINKER_PREFERENCE` propagates across targets.
+
+This is used when CMake selects a linker language for a target.
+Languages compiled directly into the target are always considered. A
+language compiled into static libraries linked by the target is
+considered if this variable is true.
diff --git a/Help/variable/CMAKE_LANG_LINK_EXECUTABLE.rst b/Help/variable/CMAKE_LANG_LINK_EXECUTABLE.rst
new file mode 100644
index 000000000..abd589147
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_LINK_EXECUTABLE.rst
@@ -0,0 +1,6 @@
+CMAKE_<LANG>_LINK_EXECUTABLE
+----------------------------
+
+Rule variable to link an executable.
+
+Rule variable to link an executable for the given language.
diff --git a/Help/variable/CMAKE_LANG_OUTPUT_EXTENSION.rst b/Help/variable/CMAKE_LANG_OUTPUT_EXTENSION.rst
new file mode 100644
index 000000000..0fbc566c1
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_OUTPUT_EXTENSION.rst
@@ -0,0 +1,7 @@
+CMAKE_<LANG>_OUTPUT_EXTENSION
+-----------------------------
+
+Extension for the output of a compile for a single file.
+
+This is the extension for an object file for the given ``<LANG>``. For
+example ``.obj`` for C on Windows.
diff --git a/Help/variable/CMAKE_LANG_PLATFORM_ID.rst b/Help/variable/CMAKE_LANG_PLATFORM_ID.rst
new file mode 100644
index 000000000..1b243e39a
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_PLATFORM_ID.rst
@@ -0,0 +1,6 @@
+CMAKE_<LANG>_PLATFORM_ID
+------------------------
+
+An internal variable subject to change.
+
+This is used in determining the platform and is subject to change.
diff --git a/Help/variable/CMAKE_LANG_SIMULATE_ID.rst b/Help/variable/CMAKE_LANG_SIMULATE_ID.rst
new file mode 100644
index 000000000..15c87a186
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_SIMULATE_ID.rst
@@ -0,0 +1,9 @@
+CMAKE_<LANG>_SIMULATE_ID
+------------------------
+
+Identification string of "simulated" compiler.
+
+Some compilers simulate other compilers to serve as drop-in
+replacements. When CMake detects such a compiler it sets this
+variable to what would have been the :variable:`CMAKE_<LANG>_COMPILER_ID` for
+the simulated compiler.
diff --git a/Help/variable/CMAKE_LANG_SIMULATE_VERSION.rst b/Help/variable/CMAKE_LANG_SIMULATE_VERSION.rst
new file mode 100644
index 000000000..d6325e06d
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_SIMULATE_VERSION.rst
@@ -0,0 +1,9 @@
+CMAKE_<LANG>_SIMULATE_VERSION
+-----------------------------
+
+Version string of "simulated" compiler.
+
+Some compilers simulate other compilers to serve as drop-in
+replacements. When CMake detects such a compiler it sets this
+variable to what would have been the :variable:`CMAKE_<LANG>_COMPILER_VERSION`
+for the simulated compiler.
diff --git a/Help/variable/CMAKE_LANG_SIZEOF_DATA_PTR.rst b/Help/variable/CMAKE_LANG_SIZEOF_DATA_PTR.rst
new file mode 100644
index 000000000..746592324
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_SIZEOF_DATA_PTR.rst
@@ -0,0 +1,7 @@
+CMAKE_<LANG>_SIZEOF_DATA_PTR
+----------------------------
+
+Size of pointer-to-data types for language ``<LANG>``.
+
+This holds the size (in bytes) of pointer-to-data types in the target
+platform ABI. It is defined for languages ``C`` and ``CXX`` (C++).
diff --git a/Help/variable/CMAKE_LANG_SOURCE_FILE_EXTENSIONS.rst b/Help/variable/CMAKE_LANG_SOURCE_FILE_EXTENSIONS.rst
new file mode 100644
index 000000000..e085fee67
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_SOURCE_FILE_EXTENSIONS.rst
@@ -0,0 +1,6 @@
+CMAKE_<LANG>_SOURCE_FILE_EXTENSIONS
+-----------------------------------
+
+Extensions of source files for the given language.
+
+This is the list of extensions for a given language's source files.
diff --git a/Help/variable/CMAKE_LANG_VISIBILITY_PRESET.rst b/Help/variable/CMAKE_LANG_VISIBILITY_PRESET.rst
new file mode 100644
index 000000000..1961ea085
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_VISIBILITY_PRESET.rst
@@ -0,0 +1,5 @@
+CMAKE_<LANG>_VISIBILITY_PRESET
+------------------------------
+
+Default value for the :prop_tgt:`<LANG>_VISIBILITY_PRESET` target
+property when a target is created.
diff --git a/Help/variable/CMAKE_LIBRARY_ARCHITECTURE.rst b/Help/variable/CMAKE_LIBRARY_ARCHITECTURE.rst
new file mode 100644
index 000000000..8a7dcbd6d
--- /dev/null
+++ b/Help/variable/CMAKE_LIBRARY_ARCHITECTURE.rst
@@ -0,0 +1,7 @@
+CMAKE_LIBRARY_ARCHITECTURE
+--------------------------
+
+Target architecture library directory name, if detected.
+
+This is the value of :variable:`CMAKE_<LANG>_LIBRARY_ARCHITECTURE` as detected
+for one of the enabled languages.
diff --git a/Help/variable/CMAKE_LIBRARY_ARCHITECTURE_REGEX.rst b/Help/variable/CMAKE_LIBRARY_ARCHITECTURE_REGEX.rst
new file mode 100644
index 000000000..1eb2ac2c8
--- /dev/null
+++ b/Help/variable/CMAKE_LIBRARY_ARCHITECTURE_REGEX.rst
@@ -0,0 +1,7 @@
+CMAKE_LIBRARY_ARCHITECTURE_REGEX
+--------------------------------
+
+Regex matching possible target architecture library directory names.
+
+This is used to detect :variable:`CMAKE_<LANG>_LIBRARY_ARCHITECTURE` from the
+implicit linker search path by matching the ``<arch>`` name.
diff --git a/Help/variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY.rst b/Help/variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY.rst
new file mode 100644
index 000000000..e97296d5e
--- /dev/null
+++ b/Help/variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY.rst
@@ -0,0 +1,9 @@
+CMAKE_LIBRARY_OUTPUT_DIRECTORY
+------------------------------
+
+Where to put all the :ref:`LIBRARY <Library Output Artifacts>`
+target files when built.
+
+This variable is used to initialize the :prop_tgt:`LIBRARY_OUTPUT_DIRECTORY`
+property on all the targets. See that target property for additional
+information.
diff --git a/Help/variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY_CONFIG.rst b/Help/variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY_CONFIG.rst
new file mode 100644
index 000000000..e069cdd8b
--- /dev/null
+++ b/Help/variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY_CONFIG.rst
@@ -0,0 +1,9 @@
+CMAKE_LIBRARY_OUTPUT_DIRECTORY_<CONFIG>
+---------------------------------------
+
+Where to put all the :ref:`LIBRARY <Library Output Artifacts>`
+target files when built for a specific configuration.
+
+This variable is used to initialize the
+:prop_tgt:`LIBRARY_OUTPUT_DIRECTORY_<CONFIG>` property on all the targets.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_LIBRARY_PATH.rst b/Help/variable/CMAKE_LIBRARY_PATH.rst
new file mode 100644
index 000000000..b1770dc26
--- /dev/null
+++ b/Help/variable/CMAKE_LIBRARY_PATH.rst
@@ -0,0 +1,7 @@
+CMAKE_LIBRARY_PATH
+------------------
+
+:ref:`;-list <CMake Language Lists>` of directories specifying a search path
+for the :command:`find_library` command. By default it is empty, it is
+intended to be set by the project. See also
+:variable:`CMAKE_SYSTEM_LIBRARY_PATH` and :variable:`CMAKE_PREFIX_PATH`.
diff --git a/Help/variable/CMAKE_LIBRARY_PATH_FLAG.rst b/Help/variable/CMAKE_LIBRARY_PATH_FLAG.rst
new file mode 100644
index 000000000..ebe5fda9a
--- /dev/null
+++ b/Help/variable/CMAKE_LIBRARY_PATH_FLAG.rst
@@ -0,0 +1,7 @@
+CMAKE_LIBRARY_PATH_FLAG
+-----------------------
+
+The flag to be used to add a library search path to a compiler.
+
+The flag will be used to specify a library directory to the compiler.
+On most compilers this is ``-L``.
diff --git a/Help/variable/CMAKE_LINK_DEF_FILE_FLAG.rst b/Help/variable/CMAKE_LINK_DEF_FILE_FLAG.rst
new file mode 100644
index 000000000..fa09f9f9c
--- /dev/null
+++ b/Help/variable/CMAKE_LINK_DEF_FILE_FLAG.rst
@@ -0,0 +1,7 @@
+CMAKE_LINK_DEF_FILE_FLAG
+------------------------
+
+Linker flag to be used to specify a ``.def`` file for dll creation.
+
+The flag will be used to add a ``.def`` file when creating a dll on
+Windows; this is only defined on Windows.
diff --git a/Help/variable/CMAKE_LINK_DEPENDS_NO_SHARED.rst b/Help/variable/CMAKE_LINK_DEPENDS_NO_SHARED.rst
new file mode 100644
index 000000000..cec7906a1
--- /dev/null
+++ b/Help/variable/CMAKE_LINK_DEPENDS_NO_SHARED.rst
@@ -0,0 +1,8 @@
+CMAKE_LINK_DEPENDS_NO_SHARED
+----------------------------
+
+Whether to skip link dependencies on shared library files.
+
+This variable initializes the :prop_tgt:`LINK_DEPENDS_NO_SHARED` property on
+targets when they are created. See that target property for
+additional information.
diff --git a/Help/variable/CMAKE_LINK_INTERFACE_LIBRARIES.rst b/Help/variable/CMAKE_LINK_INTERFACE_LIBRARIES.rst
new file mode 100644
index 000000000..33865dae3
--- /dev/null
+++ b/Help/variable/CMAKE_LINK_INTERFACE_LIBRARIES.rst
@@ -0,0 +1,8 @@
+CMAKE_LINK_INTERFACE_LIBRARIES
+------------------------------
+
+Default value for :prop_tgt:`LINK_INTERFACE_LIBRARIES` of targets.
+
+This variable is used to initialize the :prop_tgt:`LINK_INTERFACE_LIBRARIES`
+property on all the targets. See that target property for additional
+information.
diff --git a/Help/variable/CMAKE_LINK_LIBRARY_FILE_FLAG.rst b/Help/variable/CMAKE_LINK_LIBRARY_FILE_FLAG.rst
new file mode 100644
index 000000000..6858e2c15
--- /dev/null
+++ b/Help/variable/CMAKE_LINK_LIBRARY_FILE_FLAG.rst
@@ -0,0 +1,7 @@
+CMAKE_LINK_LIBRARY_FILE_FLAG
+----------------------------
+
+Flag to be used to link a library specified by a path to its file.
+
+The flag will be used before a library file path is given to the
+linker. This is needed only on very few platforms.
diff --git a/Help/variable/CMAKE_LINK_LIBRARY_FLAG.rst b/Help/variable/CMAKE_LINK_LIBRARY_FLAG.rst
new file mode 100644
index 000000000..b5197e45a
--- /dev/null
+++ b/Help/variable/CMAKE_LINK_LIBRARY_FLAG.rst
@@ -0,0 +1,7 @@
+CMAKE_LINK_LIBRARY_FLAG
+-----------------------
+
+Flag to be used to link a library into an executable.
+
+The flag will be used to specify a library to link to an executable.
+On most compilers this is ``-l``.
diff --git a/Help/variable/CMAKE_LINK_LIBRARY_SUFFIX.rst b/Help/variable/CMAKE_LINK_LIBRARY_SUFFIX.rst
new file mode 100644
index 000000000..0ddafe853
--- /dev/null
+++ b/Help/variable/CMAKE_LINK_LIBRARY_SUFFIX.rst
@@ -0,0 +1,6 @@
+CMAKE_LINK_LIBRARY_SUFFIX
+-------------------------
+
+The suffix for libraries that you link to.
+
+The suffix to use for the end of a library filename, ``.lib`` on Windows.
diff --git a/Help/variable/CMAKE_LINK_SEARCH_END_STATIC.rst b/Help/variable/CMAKE_LINK_SEARCH_END_STATIC.rst
new file mode 100644
index 000000000..54cdaaa8e
--- /dev/null
+++ b/Help/variable/CMAKE_LINK_SEARCH_END_STATIC.rst
@@ -0,0 +1,19 @@
+CMAKE_LINK_SEARCH_END_STATIC
+----------------------------
+
+End a link line such that static system libraries are used.
+
+Some linkers support switches such as ``-Bstatic`` and ``-Bdynamic`` to
+determine whether to use static or shared libraries for ``-lXXX`` options.
+CMake uses these options to set the link type for libraries whose full
+paths are not known or (in some cases) are in implicit link
+directories for the platform. By default CMake adds an option at the
+end of the library list (if necessary) to set the linker search type
+back to its starting type. This property switches the final linker
+search type to ``-Bstatic`` regardless of how it started.
+
+This variable is used to initialize the target property
+:prop_tgt:`LINK_SEARCH_END_STATIC` for all targets. If set, it's
+value is also used by the :command:`try_compile` command.
+
+See also :variable:`CMAKE_LINK_SEARCH_START_STATIC`.
diff --git a/Help/variable/CMAKE_LINK_SEARCH_START_STATIC.rst b/Help/variable/CMAKE_LINK_SEARCH_START_STATIC.rst
new file mode 100644
index 000000000..0d52a3143
--- /dev/null
+++ b/Help/variable/CMAKE_LINK_SEARCH_START_STATIC.rst
@@ -0,0 +1,20 @@
+CMAKE_LINK_SEARCH_START_STATIC
+------------------------------
+
+Assume the linker looks for static libraries by default.
+
+Some linkers support switches such as ``-Bstatic`` and ``-Bdynamic`` to
+determine whether to use static or shared libraries for ``-lXXX`` options.
+CMake uses these options to set the link type for libraries whose full
+paths are not known or (in some cases) are in implicit link
+directories for the platform. By default the linker search type is
+assumed to be ``-Bdynamic`` at the beginning of the library list. This
+property switches the assumption to ``-Bstatic``. It is intended for use
+when linking an executable statically (e.g. with the GNU ``-static``
+option).
+
+This variable is used to initialize the target property
+:prop_tgt:`LINK_SEARCH_START_STATIC` for all targets. If set, it's
+value is also used by the :command:`try_compile` command.
+
+See also :variable:`CMAKE_LINK_SEARCH_END_STATIC`.
diff --git a/Help/variable/CMAKE_MACOSX_BUNDLE.rst b/Help/variable/CMAKE_MACOSX_BUNDLE.rst
new file mode 100644
index 000000000..0badaf0da
--- /dev/null
+++ b/Help/variable/CMAKE_MACOSX_BUNDLE.rst
@@ -0,0 +1,7 @@
+CMAKE_MACOSX_BUNDLE
+-------------------
+
+Default value for :prop_tgt:`MACOSX_BUNDLE` of targets.
+
+This variable is used to initialize the :prop_tgt:`MACOSX_BUNDLE` property on
+all the targets. See that target property for additional information.
diff --git a/Help/variable/CMAKE_MACOSX_RPATH.rst b/Help/variable/CMAKE_MACOSX_RPATH.rst
new file mode 100644
index 000000000..042e807f5
--- /dev/null
+++ b/Help/variable/CMAKE_MACOSX_RPATH.rst
@@ -0,0 +1,7 @@
+CMAKE_MACOSX_RPATH
+-------------------
+
+Whether to use rpaths on OS X and iOS.
+
+This variable is used to initialize the :prop_tgt:`MACOSX_RPATH` property on
+all targets.
diff --git a/Help/variable/CMAKE_MAJOR_VERSION.rst b/Help/variable/CMAKE_MAJOR_VERSION.rst
new file mode 100644
index 000000000..079ad7068
--- /dev/null
+++ b/Help/variable/CMAKE_MAJOR_VERSION.rst
@@ -0,0 +1,5 @@
+CMAKE_MAJOR_VERSION
+-------------------
+
+First version number component of the :variable:`CMAKE_VERSION`
+variable.
diff --git a/Help/variable/CMAKE_MAKE_PROGRAM.rst b/Help/variable/CMAKE_MAKE_PROGRAM.rst
new file mode 100644
index 000000000..edf27328c
--- /dev/null
+++ b/Help/variable/CMAKE_MAKE_PROGRAM.rst
@@ -0,0 +1,66 @@
+CMAKE_MAKE_PROGRAM
+------------------
+
+Tool that can launch the native build system.
+The value may be the full path to an executable or just the tool
+name if it is expected to be in the ``PATH``.
+
+The tool selected depends on the :variable:`CMAKE_GENERATOR` used
+to configure the project:
+
+* The :ref:`Makefile Generators` set this to ``make``, ``gmake``, or
+ a generator-specific tool (e.g. ``nmake`` for :generator:`NMake Makefiles`).
+
+ These generators store ``CMAKE_MAKE_PROGRAM`` in the CMake cache
+ so that it may be edited by the user.
+
+* The :generator:`Ninja` generator sets this to ``ninja``.
+
+ This generator stores ``CMAKE_MAKE_PROGRAM`` in the CMake cache
+ so that it may be edited by the user.
+
+* The :generator:`Xcode` generator sets this to ``xcodebuild`` (or possibly an
+ otherwise undocumented ``cmakexbuild`` wrapper implementing some
+ workarounds).
+
+ This generator prefers to lookup the build tool at build time
+ rather than to store ``CMAKE_MAKE_PROGRAM`` in the CMake cache
+ ahead of time. This is because ``xcodebuild`` is easy to find,
+ the ``cmakexbuild`` wrapper is needed only for older Xcode versions,
+ and the path to ``cmakexbuild`` may be outdated if CMake itself moves.
+
+ For compatibility with versions of CMake prior to 3.2, if
+ a user or project explicitly adds ``CMAKE_MAKE_PROGRAM`` to
+ the CMake cache then CMake will use the specified value.
+
+* The :ref:`Visual Studio Generators` set this to the full path to
+ ``MSBuild.exe`` (VS >= 10), ``devenv.com`` (VS 7,8,9),
+ ``VCExpress.exe`` (VS Express 8,9), or ``msdev.exe`` (VS 6).
+ (See also variables
+ :variable:`CMAKE_VS_MSBUILD_COMMAND`,
+ :variable:`CMAKE_VS_DEVENV_COMMAND`, and
+ :variable:`CMAKE_VS_MSDEV_COMMAND`.)
+
+ These generators prefer to lookup the build tool at build time
+ rather than to store ``CMAKE_MAKE_PROGRAM`` in the CMake cache
+ ahead of time. This is because the tools are version-specific
+ and can be located using the Windows Registry. It is also
+ necessary because the proper build tool may depend on the
+ project content (e.g. the Intel Fortran plugin to VS 10 and 11
+ requires ``devenv.com`` to build its ``.vfproj`` project files
+ even though ``MSBuild.exe`` is normally preferred to support
+ the :variable:`CMAKE_GENERATOR_TOOLSET`).
+
+ For compatibility with versions of CMake prior to 3.0, if
+ a user or project explicitly adds ``CMAKE_MAKE_PROGRAM`` to
+ the CMake cache then CMake will use the specified value if
+ possible.
+
+* The :generator:`Green Hills MULTI` generator sets this to ``gbuild``.
+ If a user or project explicitly adds ``CMAKE_MAKE_PROGRAM`` to
+ the CMake cache then CMake will use the specified value.
+
+The ``CMAKE_MAKE_PROGRAM`` variable is set for use by project code.
+The value is also used by the :manual:`cmake(1)` ``--build`` and
+:manual:`ctest(1)` ``--build-and-test`` tools to launch the native
+build process.
diff --git a/Help/variable/CMAKE_MAP_IMPORTED_CONFIG_CONFIG.rst b/Help/variable/CMAKE_MAP_IMPORTED_CONFIG_CONFIG.rst
new file mode 100644
index 000000000..ed29afe33
--- /dev/null
+++ b/Help/variable/CMAKE_MAP_IMPORTED_CONFIG_CONFIG.rst
@@ -0,0 +1,8 @@
+CMAKE_MAP_IMPORTED_CONFIG_<CONFIG>
+----------------------------------
+
+Default value for :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>` of targets.
+
+This variable is used to initialize the
+:prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>` property on all the targets. See
+that target property for additional information.
diff --git a/Help/variable/CMAKE_MATCH_COUNT.rst b/Help/variable/CMAKE_MATCH_COUNT.rst
new file mode 100644
index 000000000..8b1c0365b
--- /dev/null
+++ b/Help/variable/CMAKE_MATCH_COUNT.rst
@@ -0,0 +1,8 @@
+CMAKE_MATCH_COUNT
+-----------------
+
+The number of matches with the last regular expression.
+
+When a regular expression match is used, CMake fills in ``CMAKE_MATCH_<n>``
+variables with the match contents. The ``CMAKE_MATCH_COUNT`` variable holds
+the number of match expressions when these are filled.
diff --git a/Help/variable/CMAKE_MFC_FLAG.rst b/Help/variable/CMAKE_MFC_FLAG.rst
new file mode 100644
index 000000000..f60e7a597
--- /dev/null
+++ b/Help/variable/CMAKE_MFC_FLAG.rst
@@ -0,0 +1,16 @@
+CMAKE_MFC_FLAG
+--------------
+
+Tell cmake to use MFC for an executable or dll.
+
+This can be set in a ``CMakeLists.txt`` file and will enable MFC in the
+application. It should be set to ``1`` for the static MFC library, and ``2``
+for the shared MFC library. This is used in Visual Studio 6 and 7
+project files. The CMakeSetup dialog used MFC and the ``CMakeLists.txt``
+looks like this:
+
+::
+
+ add_definitions(-D_AFXDLL)
+ set(CMAKE_MFC_FLAG 2)
+ add_executable(CMakeSetup WIN32 ${SRCS})
diff --git a/Help/variable/CMAKE_MINIMUM_REQUIRED_VERSION.rst b/Help/variable/CMAKE_MINIMUM_REQUIRED_VERSION.rst
new file mode 100644
index 000000000..5a51634db
--- /dev/null
+++ b/Help/variable/CMAKE_MINIMUM_REQUIRED_VERSION.rst
@@ -0,0 +1,7 @@
+CMAKE_MINIMUM_REQUIRED_VERSION
+------------------------------
+
+Version specified to :command:`cmake_minimum_required` command
+
+Variable containing the ``VERSION`` component specified in the
+:command:`cmake_minimum_required` command.
diff --git a/Help/variable/CMAKE_MINOR_VERSION.rst b/Help/variable/CMAKE_MINOR_VERSION.rst
new file mode 100644
index 000000000..f67cfb955
--- /dev/null
+++ b/Help/variable/CMAKE_MINOR_VERSION.rst
@@ -0,0 +1,5 @@
+CMAKE_MINOR_VERSION
+-------------------
+
+Second version number component of the :variable:`CMAKE_VERSION`
+variable.
diff --git a/Help/variable/CMAKE_MODULE_LINKER_FLAGS.rst b/Help/variable/CMAKE_MODULE_LINKER_FLAGS.rst
new file mode 100644
index 000000000..6372bbdb9
--- /dev/null
+++ b/Help/variable/CMAKE_MODULE_LINKER_FLAGS.rst
@@ -0,0 +1,6 @@
+CMAKE_MODULE_LINKER_FLAGS
+-------------------------
+
+Linker flags to be used to create modules.
+
+These flags will be used by the linker when creating a module.
diff --git a/Help/variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG.rst b/Help/variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG.rst
new file mode 100644
index 000000000..393263ec8
--- /dev/null
+++ b/Help/variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG.rst
@@ -0,0 +1,6 @@
+CMAKE_MODULE_LINKER_FLAGS_<CONFIG>
+----------------------------------
+
+Flags to be used when linking a module.
+
+Same as ``CMAKE_C_FLAGS_*`` but used by the linker when creating modules.
diff --git a/Help/variable/CMAKE_MODULE_PATH.rst b/Help/variable/CMAKE_MODULE_PATH.rst
new file mode 100644
index 000000000..5ea7cbbc0
--- /dev/null
+++ b/Help/variable/CMAKE_MODULE_PATH.rst
@@ -0,0 +1,7 @@
+CMAKE_MODULE_PATH
+-----------------
+
+:ref:`;-list <CMake Language Lists>` of directories specifying a search path
+for CMake modules to be loaded by the the :command:`include` or
+:command:`find_package` commands before checking the default modules that come
+with CMake. By default it is empty, it is intended to be set by the project.
diff --git a/Help/variable/CMAKE_NOT_USING_CONFIG_FLAGS.rst b/Help/variable/CMAKE_NOT_USING_CONFIG_FLAGS.rst
new file mode 100644
index 000000000..98960c520
--- /dev/null
+++ b/Help/variable/CMAKE_NOT_USING_CONFIG_FLAGS.rst
@@ -0,0 +1,7 @@
+CMAKE_NOT_USING_CONFIG_FLAGS
+----------------------------
+
+Skip ``_BUILD_TYPE`` flags if true.
+
+This is an internal flag used by the generators in CMake to tell CMake
+to skip the ``_BUILD_TYPE`` flags.
diff --git a/Help/variable/CMAKE_NO_BUILTIN_CHRPATH.rst b/Help/variable/CMAKE_NO_BUILTIN_CHRPATH.rst
new file mode 100644
index 000000000..189f59fa3
--- /dev/null
+++ b/Help/variable/CMAKE_NO_BUILTIN_CHRPATH.rst
@@ -0,0 +1,10 @@
+CMAKE_NO_BUILTIN_CHRPATH
+------------------------
+
+Do not use the builtin ELF editor to fix RPATHs on installation.
+
+When an ELF binary needs to have a different RPATH after installation
+than it does in the build tree, CMake uses a builtin editor to change
+the RPATH in the installed copy. If this variable is set to true then
+CMake will relink the binary before installation instead of using its
+builtin editor.
diff --git a/Help/variable/CMAKE_NO_SYSTEM_FROM_IMPORTED.rst b/Help/variable/CMAKE_NO_SYSTEM_FROM_IMPORTED.rst
new file mode 100644
index 000000000..61e04b4ca
--- /dev/null
+++ b/Help/variable/CMAKE_NO_SYSTEM_FROM_IMPORTED.rst
@@ -0,0 +1,8 @@
+CMAKE_NO_SYSTEM_FROM_IMPORTED
+-----------------------------
+
+Default value for :prop_tgt:`NO_SYSTEM_FROM_IMPORTED` of targets.
+
+This variable is used to initialize the :prop_tgt:`NO_SYSTEM_FROM_IMPORTED`
+property on all the targets. See that target property for additional
+information.
diff --git a/Help/variable/CMAKE_OBJECT_PATH_MAX.rst b/Help/variable/CMAKE_OBJECT_PATH_MAX.rst
new file mode 100644
index 000000000..9e30cbbdb
--- /dev/null
+++ b/Help/variable/CMAKE_OBJECT_PATH_MAX.rst
@@ -0,0 +1,16 @@
+CMAKE_OBJECT_PATH_MAX
+---------------------
+
+Maximum object file full-path length allowed by native build tools.
+
+CMake computes for every source file an object file name that is
+unique to the source file and deterministic with respect to the full
+path to the source file. This allows multiple source files in a
+target to share the same name if they lie in different directories
+without rebuilding when one is added or removed. However, it can
+produce long full paths in a few cases, so CMake shortens the path
+using a hashing scheme when the full path to an object file exceeds a
+limit. CMake has a built-in limit for each platform that is
+sufficient for common tools, but some native tools may have a lower
+limit. This variable may be set to specify the limit explicitly. The
+value must be an integer no less than 128.
diff --git a/Help/variable/CMAKE_OSX_ARCHITECTURES.rst b/Help/variable/CMAKE_OSX_ARCHITECTURES.rst
new file mode 100644
index 000000000..93916dd62
--- /dev/null
+++ b/Help/variable/CMAKE_OSX_ARCHITECTURES.rst
@@ -0,0 +1,10 @@
+CMAKE_OSX_ARCHITECTURES
+-----------------------
+
+Target specific architectures for OS X and iOS.
+
+This variable is used to initialize the :prop_tgt:`OSX_ARCHITECTURES`
+property on each target as it is creaed. See that target property
+for additional information.
+
+.. include:: CMAKE_OSX_VARIABLE.txt
diff --git a/Help/variable/CMAKE_OSX_DEPLOYMENT_TARGET.rst b/Help/variable/CMAKE_OSX_DEPLOYMENT_TARGET.rst
new file mode 100644
index 000000000..4fb2caa4f
--- /dev/null
+++ b/Help/variable/CMAKE_OSX_DEPLOYMENT_TARGET.rst
@@ -0,0 +1,13 @@
+CMAKE_OSX_DEPLOYMENT_TARGET
+---------------------------
+
+Specify the minimum version of OS X on which the target binaries are
+to be deployed. CMake uses this value for the ``-mmacosx-version-min``
+flag and to help choose the default SDK
+(see :variable:`CMAKE_OSX_SYSROOT`).
+
+If not set explicitly the value is initialized by the
+``MACOSX_DEPLOYMENT_TARGET`` environment variable, if set,
+and otherwise computed based on the host platform.
+
+.. include:: CMAKE_OSX_VARIABLE.txt
diff --git a/Help/variable/CMAKE_OSX_SYSROOT.rst b/Help/variable/CMAKE_OSX_SYSROOT.rst
new file mode 100644
index 000000000..f1d58c6b5
--- /dev/null
+++ b/Help/variable/CMAKE_OSX_SYSROOT.rst
@@ -0,0 +1,13 @@
+CMAKE_OSX_SYSROOT
+-----------------
+
+Specify the location or name of the OS X platform SDK to be used.
+CMake uses this value to compute the value of the ``-isysroot`` flag
+or equivalent and to help the ``find_*`` commands locate files in
+the SDK.
+
+If not set explicitly the value is initialized by the ``SDKROOT``
+environment variable, if set, and otherwise computed based on the
+:variable:`CMAKE_OSX_DEPLOYMENT_TARGET` or the host platform.
+
+.. include:: CMAKE_OSX_VARIABLE.txt
diff --git a/Help/variable/CMAKE_OSX_VARIABLE.txt b/Help/variable/CMAKE_OSX_VARIABLE.txt
new file mode 100644
index 000000000..385f871f3
--- /dev/null
+++ b/Help/variable/CMAKE_OSX_VARIABLE.txt
@@ -0,0 +1,6 @@
+The value of this variable should be set prior to the first
+:command:`project` or :command:`enable_language` command invocation
+because it may influence configuration of the toolchain and flags.
+It is intended to be set locally by the user creating a build tree.
+
+This variable is ignored on platforms other than OS X.
diff --git a/Help/variable/CMAKE_PARENT_LIST_FILE.rst b/Help/variable/CMAKE_PARENT_LIST_FILE.rst
new file mode 100644
index 000000000..cfd8608c3
--- /dev/null
+++ b/Help/variable/CMAKE_PARENT_LIST_FILE.rst
@@ -0,0 +1,9 @@
+CMAKE_PARENT_LIST_FILE
+----------------------
+
+Full path to the CMake file that included the current one.
+
+While processing a CMake file loaded by :command:`include` or
+:command:`find_package` this variable contains the full path to the file
+including it. The top of the include stack is always the ``CMakeLists.txt``
+for the current directory. See also :variable:`CMAKE_CURRENT_LIST_FILE`.
diff --git a/Help/variable/CMAKE_PATCH_VERSION.rst b/Help/variable/CMAKE_PATCH_VERSION.rst
new file mode 100644
index 000000000..991ae7618
--- /dev/null
+++ b/Help/variable/CMAKE_PATCH_VERSION.rst
@@ -0,0 +1,5 @@
+CMAKE_PATCH_VERSION
+-------------------
+
+Third version number component of the :variable:`CMAKE_VERSION`
+variable.
diff --git a/Help/variable/CMAKE_PDB_OUTPUT_DIRECTORY.rst b/Help/variable/CMAKE_PDB_OUTPUT_DIRECTORY.rst
new file mode 100644
index 000000000..763bcb34f
--- /dev/null
+++ b/Help/variable/CMAKE_PDB_OUTPUT_DIRECTORY.rst
@@ -0,0 +1,9 @@
+CMAKE_PDB_OUTPUT_DIRECTORY
+--------------------------
+
+Output directory for MS debug symbol ``.pdb`` files generated by the
+linker for executable and shared library targets.
+
+This variable is used to initialize the :prop_tgt:`PDB_OUTPUT_DIRECTORY`
+property on all the targets. See that target property for additional
+information.
diff --git a/Help/variable/CMAKE_PDB_OUTPUT_DIRECTORY_CONFIG.rst b/Help/variable/CMAKE_PDB_OUTPUT_DIRECTORY_CONFIG.rst
new file mode 100644
index 000000000..4d18eec5d
--- /dev/null
+++ b/Help/variable/CMAKE_PDB_OUTPUT_DIRECTORY_CONFIG.rst
@@ -0,0 +1,11 @@
+CMAKE_PDB_OUTPUT_DIRECTORY_<CONFIG>
+-----------------------------------
+
+Per-configuration output directory for MS debug symbol ``.pdb`` files
+generated by the linker for executable and shared library targets.
+
+This is a per-configuration version of :variable:`CMAKE_PDB_OUTPUT_DIRECTORY`.
+This variable is used to initialize the
+:prop_tgt:`PDB_OUTPUT_DIRECTORY_<CONFIG>`
+property on all the targets. See that target property for additional
+information.
diff --git a/Help/variable/CMAKE_POLICY_DEFAULT_CMPNNNN.rst b/Help/variable/CMAKE_POLICY_DEFAULT_CMPNNNN.rst
new file mode 100644
index 000000000..43582be94
--- /dev/null
+++ b/Help/variable/CMAKE_POLICY_DEFAULT_CMPNNNN.rst
@@ -0,0 +1,17 @@
+CMAKE_POLICY_DEFAULT_CMP<NNNN>
+------------------------------
+
+Default for CMake Policy ``CMP<NNNN>`` when it is otherwise left unset.
+
+Commands :command:`cmake_minimum_required(VERSION)` and
+:command:`cmake_policy(VERSION)` by default leave policies introduced after
+the given version unset. Set ``CMAKE_POLICY_DEFAULT_CMP<NNNN>`` to ``OLD``
+or ``NEW`` to specify the default for policy ``CMP<NNNN>``, where ``<NNNN>``
+is the policy number.
+
+This variable should not be set by a project in CMake code; use
+:command:`cmake_policy(SET)` instead. Users running CMake may set this
+variable in the cache (e.g. ``-DCMAKE_POLICY_DEFAULT_CMP<NNNN>=<OLD|NEW>``)
+to set a policy not otherwise set by the project. Set to ``OLD`` to quiet a
+policy warning while using old behavior or to ``NEW`` to try building the
+project with new behavior.
diff --git a/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst b/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst
new file mode 100644
index 000000000..582f9e495
--- /dev/null
+++ b/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst
@@ -0,0 +1,23 @@
+CMAKE_POLICY_WARNING_CMP<NNNN>
+------------------------------
+
+Explicitly enable or disable the warning when CMake Policy ``CMP<NNNN>``
+is not set. This is meaningful only for the few policies that do not
+warn by default:
+
+* ``CMAKE_POLICY_WARNING_CMP0025`` controls the warning for
+ policy :policy:`CMP0025`.
+* ``CMAKE_POLICY_WARNING_CMP0047`` controls the warning for
+ policy :policy:`CMP0047`.
+* ``CMAKE_POLICY_WARNING_CMP0056`` controls the warning for
+ policy :policy:`CMP0056`.
+* ``CMAKE_POLICY_WARNING_CMP0060`` controls the warning for
+ policy :policy:`CMP0060`.
+* ``CMAKE_POLICY_WARNING_CMP0065`` controls the warning for
+ policy :policy:`CMP0065`.
+
+This variable should not be set by a project in CMake code. Project
+developers running CMake may set this variable in their cache to
+enable the warning (e.g. ``-DCMAKE_POLICY_WARNING_CMP<NNNN>=ON``).
+Alternatively, running :manual:`cmake(1)` with the ``--debug-output``,
+``--trace``, or ``--trace-expand`` option will also enable the warning.
diff --git a/Help/variable/CMAKE_POSITION_INDEPENDENT_CODE.rst b/Help/variable/CMAKE_POSITION_INDEPENDENT_CODE.rst
new file mode 100644
index 000000000..43b1397eb
--- /dev/null
+++ b/Help/variable/CMAKE_POSITION_INDEPENDENT_CODE.rst
@@ -0,0 +1,9 @@
+CMAKE_POSITION_INDEPENDENT_CODE
+-------------------------------
+
+Default value for :prop_tgt:`POSITION_INDEPENDENT_CODE` of targets.
+
+This variable is used to initialize the
+:prop_tgt:`POSITION_INDEPENDENT_CODE` property on all the targets.
+See that target property for additional information. If set, it's
+value is also used by the :command:`try_compile` command.
diff --git a/Help/variable/CMAKE_PREFIX_PATH.rst b/Help/variable/CMAKE_PREFIX_PATH.rst
new file mode 100644
index 000000000..c2a4a6038
--- /dev/null
+++ b/Help/variable/CMAKE_PREFIX_PATH.rst
@@ -0,0 +1,15 @@
+CMAKE_PREFIX_PATH
+-----------------
+
+:ref:`;-list <CMake Language Lists>` of directories specifying installation
+*prefixes* to be searched by the :command:`find_package`,
+:command:`find_program`, :command:`find_library`, :command:`find_file`, and
+:command:`find_path` commands. Each command will add appropriate
+subdirectories (like ``bin``, ``lib``, or ``include``) as specified in its own
+documentation.
+
+By default this is empty. It is intended to be set by the project.
+
+See also :variable:`CMAKE_SYSTEM_PREFIX_PATH`, :variable:`CMAKE_INCLUDE_PATH`,
+:variable:`CMAKE_LIBRARY_PATH`, :variable:`CMAKE_PROGRAM_PATH`, and
+:variable:`CMAKE_IGNORE_PATH`.
diff --git a/Help/variable/CMAKE_PROGRAM_PATH.rst b/Help/variable/CMAKE_PROGRAM_PATH.rst
new file mode 100644
index 000000000..799e1192c
--- /dev/null
+++ b/Help/variable/CMAKE_PROGRAM_PATH.rst
@@ -0,0 +1,7 @@
+CMAKE_PROGRAM_PATH
+------------------
+
+:ref:`;-list <CMake Language Lists>` of directories specifying a search path
+for the :command:`find_program` command. By default it is empty, it is
+intended to be set by the project. See also
+:variable:`CMAKE_SYSTEM_PROGRAM_PATH` and :variable:`CMAKE_PREFIX_PATH`.
diff --git a/Help/variable/CMAKE_PROJECT_NAME.rst b/Help/variable/CMAKE_PROJECT_NAME.rst
new file mode 100644
index 000000000..431e9f302
--- /dev/null
+++ b/Help/variable/CMAKE_PROJECT_NAME.rst
@@ -0,0 +1,7 @@
+CMAKE_PROJECT_NAME
+------------------
+
+The name of the current project.
+
+This specifies name of the current project from the closest inherited
+:command:`project` command.
diff --git a/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE.rst b/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE.rst
new file mode 100644
index 000000000..ba9df5a34
--- /dev/null
+++ b/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE.rst
@@ -0,0 +1,6 @@
+CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE
+------------------------------------
+
+A CMake language file or module to be included by the :command:`project`
+command. This is is intended for injecting custom code into project
+builds without modifying their source.
diff --git a/Help/variable/CMAKE_RANLIB.rst b/Help/variable/CMAKE_RANLIB.rst
new file mode 100644
index 000000000..82672e9ae
--- /dev/null
+++ b/Help/variable/CMAKE_RANLIB.rst
@@ -0,0 +1,7 @@
+CMAKE_RANLIB
+------------
+
+Name of randomizing tool for static libraries.
+
+This specifies name of the program that randomizes libraries on UNIX,
+not used on Windows, but may be present.
diff --git a/Help/variable/CMAKE_ROOT.rst b/Help/variable/CMAKE_ROOT.rst
new file mode 100644
index 000000000..1d0a8af80
--- /dev/null
+++ b/Help/variable/CMAKE_ROOT.rst
@@ -0,0 +1,8 @@
+CMAKE_ROOT
+----------
+
+Install directory for running cmake.
+
+This is the install root for the running CMake and the ``Modules``
+directory can be found here. This is commonly used in this format:
+``${CMAKE_ROOT}/Modules``
diff --git a/Help/variable/CMAKE_RUNTIME_OUTPUT_DIRECTORY.rst b/Help/variable/CMAKE_RUNTIME_OUTPUT_DIRECTORY.rst
new file mode 100644
index 000000000..6253d4a34
--- /dev/null
+++ b/Help/variable/CMAKE_RUNTIME_OUTPUT_DIRECTORY.rst
@@ -0,0 +1,9 @@
+CMAKE_RUNTIME_OUTPUT_DIRECTORY
+------------------------------
+
+Where to put all the :ref:`RUNTIME <Runtime Output Artifacts>`
+target files when built.
+
+This variable is used to initialize the :prop_tgt:`RUNTIME_OUTPUT_DIRECTORY`
+property on all the targets. See that target property for additional
+information.
diff --git a/Help/variable/CMAKE_RUNTIME_OUTPUT_DIRECTORY_CONFIG.rst b/Help/variable/CMAKE_RUNTIME_OUTPUT_DIRECTORY_CONFIG.rst
new file mode 100644
index 000000000..080dea667
--- /dev/null
+++ b/Help/variable/CMAKE_RUNTIME_OUTPUT_DIRECTORY_CONFIG.rst
@@ -0,0 +1,9 @@
+CMAKE_RUNTIME_OUTPUT_DIRECTORY_<CONFIG>
+---------------------------------------
+
+Where to put all the :ref:`RUNTIME <Runtime Output Artifacts>`
+target files when built for a specific configuration.
+
+This variable is used to initialize the
+:prop_tgt:`RUNTIME_OUTPUT_DIRECTORY_<CONFIG>` property on all the targets.
+See that target property for additional information.
diff --git a/Help/variable/CMAKE_SCRIPT_MODE_FILE.rst b/Help/variable/CMAKE_SCRIPT_MODE_FILE.rst
new file mode 100644
index 000000000..981af60cf
--- /dev/null
+++ b/Help/variable/CMAKE_SCRIPT_MODE_FILE.rst
@@ -0,0 +1,9 @@
+CMAKE_SCRIPT_MODE_FILE
+----------------------
+
+Full path to the :manual:`cmake(1)` ``-P`` script file currently being
+processed.
+
+When run in :manual:`cmake(1)` ``-P`` script mode, CMake sets this variable to
+the full path of the script file. When run to configure a ``CMakeLists.txt``
+file, this variable is not set.
diff --git a/Help/variable/CMAKE_SHARED_LIBRARY_PREFIX.rst b/Help/variable/CMAKE_SHARED_LIBRARY_PREFIX.rst
new file mode 100644
index 000000000..8afabafe5
--- /dev/null
+++ b/Help/variable/CMAKE_SHARED_LIBRARY_PREFIX.rst
@@ -0,0 +1,8 @@
+CMAKE_SHARED_LIBRARY_PREFIX
+---------------------------
+
+The prefix for shared libraries that you link to.
+
+The prefix to use for the name of a shared library, ``lib`` on UNIX.
+
+``CMAKE_SHARED_LIBRARY_PREFIX_<LANG>`` overrides this for language ``<LANG>``.
diff --git a/Help/variable/CMAKE_SHARED_LIBRARY_SUFFIX.rst b/Help/variable/CMAKE_SHARED_LIBRARY_SUFFIX.rst
new file mode 100644
index 000000000..1f96a328e
--- /dev/null
+++ b/Help/variable/CMAKE_SHARED_LIBRARY_SUFFIX.rst
@@ -0,0 +1,9 @@
+CMAKE_SHARED_LIBRARY_SUFFIX
+---------------------------
+
+The suffix for shared libraries that you link to.
+
+The suffix to use for the end of a shared library filename, ``.dll`` on
+Windows.
+
+``CMAKE_SHARED_LIBRARY_SUFFIX_<LANG>`` overrides this for language ``<LANG>``.
diff --git a/Help/variable/CMAKE_SHARED_LINKER_FLAGS.rst b/Help/variable/CMAKE_SHARED_LINKER_FLAGS.rst
new file mode 100644
index 000000000..fce950c75
--- /dev/null
+++ b/Help/variable/CMAKE_SHARED_LINKER_FLAGS.rst
@@ -0,0 +1,6 @@
+CMAKE_SHARED_LINKER_FLAGS
+-------------------------
+
+Linker flags to be used to create shared libraries.
+
+These flags will be used by the linker when creating a shared library.
diff --git a/Help/variable/CMAKE_SHARED_LINKER_FLAGS_CONFIG.rst b/Help/variable/CMAKE_SHARED_LINKER_FLAGS_CONFIG.rst
new file mode 100644
index 000000000..4bf87a0b6
--- /dev/null
+++ b/Help/variable/CMAKE_SHARED_LINKER_FLAGS_CONFIG.rst
@@ -0,0 +1,7 @@
+CMAKE_SHARED_LINKER_FLAGS_<CONFIG>
+----------------------------------
+
+Flags to be used when linking a shared library.
+
+Same as ``CMAKE_C_FLAGS_*`` but used by the linker when creating shared
+libraries.
diff --git a/Help/variable/CMAKE_SHARED_MODULE_PREFIX.rst b/Help/variable/CMAKE_SHARED_MODULE_PREFIX.rst
new file mode 100644
index 000000000..d6eef9866
--- /dev/null
+++ b/Help/variable/CMAKE_SHARED_MODULE_PREFIX.rst
@@ -0,0 +1,8 @@
+CMAKE_SHARED_MODULE_PREFIX
+--------------------------
+
+The prefix for loadable modules that you link to.
+
+The prefix to use for the name of a loadable module on this platform.
+
+``CMAKE_SHARED_MODULE_PREFIX_<LANG>`` overrides this for language ``<LANG>``.
diff --git a/Help/variable/CMAKE_SHARED_MODULE_SUFFIX.rst b/Help/variable/CMAKE_SHARED_MODULE_SUFFIX.rst
new file mode 100644
index 000000000..81515c3cf
--- /dev/null
+++ b/Help/variable/CMAKE_SHARED_MODULE_SUFFIX.rst
@@ -0,0 +1,9 @@
+CMAKE_SHARED_MODULE_SUFFIX
+--------------------------
+
+The suffix for shared libraries that you link to.
+
+The suffix to use for the end of a loadable module filename on this
+platform
+
+``CMAKE_SHARED_MODULE_SUFFIX_<LANG>`` overrides this for language ``<LANG>``.
diff --git a/Help/variable/CMAKE_SIZEOF_VOID_P.rst b/Help/variable/CMAKE_SIZEOF_VOID_P.rst
new file mode 100644
index 000000000..f5464d1d4
--- /dev/null
+++ b/Help/variable/CMAKE_SIZEOF_VOID_P.rst
@@ -0,0 +1,8 @@
+CMAKE_SIZEOF_VOID_P
+-------------------
+
+Size of a ``void`` pointer.
+
+This is set to the size of a pointer on the target machine, and is determined
+by a try compile. If a 64-bit size is found, then the library search
+path is modified to look for 64-bit libraries first.
diff --git a/Help/variable/CMAKE_SKIP_BUILD_RPATH.rst b/Help/variable/CMAKE_SKIP_BUILD_RPATH.rst
new file mode 100644
index 000000000..8da610030
--- /dev/null
+++ b/Help/variable/CMAKE_SKIP_BUILD_RPATH.rst
@@ -0,0 +1,10 @@
+CMAKE_SKIP_BUILD_RPATH
+----------------------
+
+Do not include RPATHs in the build tree.
+
+Normally CMake uses the build tree for the RPATH when building
+executables etc on systems that use RPATH. When the software is
+installed the executables etc are relinked by CMake to have the
+install RPATH. If this variable is set to true then the software is
+always built with no RPATH.
diff --git a/Help/variable/CMAKE_SKIP_INSTALL_ALL_DEPENDENCY.rst b/Help/variable/CMAKE_SKIP_INSTALL_ALL_DEPENDENCY.rst
new file mode 100644
index 000000000..80a68c972
--- /dev/null
+++ b/Help/variable/CMAKE_SKIP_INSTALL_ALL_DEPENDENCY.rst
@@ -0,0 +1,11 @@
+CMAKE_SKIP_INSTALL_ALL_DEPENDENCY
+---------------------------------
+
+Don't make the ``install`` target depend on the ``all`` target.
+
+By default, the ``install`` target depends on the ``all`` target. This
+has the effect, that when ``make install`` is invoked or ``INSTALL`` is
+built, first the ``all`` target is built, then the installation starts.
+If :variable:`CMAKE_SKIP_INSTALL_ALL_DEPENDENCY` is set to ``TRUE``, this
+dependency is not created, so the installation process will start immediately,
+independent from whether the project has been completely built or not.
diff --git a/Help/variable/CMAKE_SKIP_INSTALL_RPATH.rst b/Help/variable/CMAKE_SKIP_INSTALL_RPATH.rst
new file mode 100644
index 000000000..cc0ac21ee
--- /dev/null
+++ b/Help/variable/CMAKE_SKIP_INSTALL_RPATH.rst
@@ -0,0 +1,14 @@
+CMAKE_SKIP_INSTALL_RPATH
+------------------------
+
+Do not include RPATHs in the install tree.
+
+Normally CMake uses the build tree for the RPATH when building
+executables etc on systems that use RPATH. When the software is
+installed the executables etc are relinked by CMake to have the
+install RPATH. If this variable is set to true then the software is
+always installed without RPATH, even if RPATH is enabled when
+building. This can be useful for example to allow running tests from
+the build directory with RPATH enabled before the installation step.
+To omit RPATH in both the build and install steps, use
+:variable:`CMAKE_SKIP_RPATH` instead.
diff --git a/Help/variable/CMAKE_SKIP_INSTALL_RULES.rst b/Help/variable/CMAKE_SKIP_INSTALL_RULES.rst
new file mode 100644
index 000000000..44966f32f
--- /dev/null
+++ b/Help/variable/CMAKE_SKIP_INSTALL_RULES.rst
@@ -0,0 +1,8 @@
+CMAKE_SKIP_INSTALL_RULES
+------------------------
+
+Whether to disable generation of installation rules.
+
+If ``TRUE``, cmake will neither generate installaton rules nor
+will it generate ``cmake_install.cmake`` files. This variable is ``FALSE`` by
+default.
diff --git a/Help/variable/CMAKE_SKIP_RPATH.rst b/Help/variable/CMAKE_SKIP_RPATH.rst
new file mode 100644
index 000000000..d7ce8e43d
--- /dev/null
+++ b/Help/variable/CMAKE_SKIP_RPATH.rst
@@ -0,0 +1,10 @@
+CMAKE_SKIP_RPATH
+----------------
+
+If true, do not add run time path information.
+
+If this is set to ``TRUE``, then the rpath information is not added to
+compiled executables. The default is to add rpath information if the
+platform supports it. This allows for easy running from the build
+tree. To omit RPATH in the install step, but not the build step, use
+:variable:`CMAKE_SKIP_INSTALL_RPATH` instead.
diff --git a/Help/variable/CMAKE_SOURCE_DIR.rst b/Help/variable/CMAKE_SOURCE_DIR.rst
new file mode 100644
index 000000000..416fbe1a8
--- /dev/null
+++ b/Help/variable/CMAKE_SOURCE_DIR.rst
@@ -0,0 +1,13 @@
+CMAKE_SOURCE_DIR
+----------------
+
+The path to the top level of the source tree.
+
+This is the full path to the top level of the current CMake source
+tree. For an in-source build, this would be the same as
+:variable:`CMAKE_BINARY_DIR`.
+
+When run in -P script mode, CMake sets the variables
+:variable:`CMAKE_BINARY_DIR`, :variable:`CMAKE_SOURCE_DIR`,
+:variable:`CMAKE_CURRENT_BINARY_DIR` and
+:variable:`CMAKE_CURRENT_SOURCE_DIR` to the current working directory.
diff --git a/Help/variable/CMAKE_STAGING_PREFIX.rst b/Help/variable/CMAKE_STAGING_PREFIX.rst
new file mode 100644
index 000000000..1310e9471
--- /dev/null
+++ b/Help/variable/CMAKE_STAGING_PREFIX.rst
@@ -0,0 +1,14 @@
+CMAKE_STAGING_PREFIX
+--------------------
+
+This variable may be set to a path to install to when cross-compiling. This can
+be useful if the path in :variable:`CMAKE_SYSROOT` is read-only, or otherwise
+should remain pristine.
+
+The ``CMAKE_STAGING_PREFIX`` location is also used as a search prefix by the
+``find_*`` commands. This can be controlled by setting the
+:variable:`CMAKE_FIND_NO_INSTALL_PREFIX` variable.
+
+If any RPATH/RUNPATH entries passed to the linker contain the
+``CMAKE_STAGING_PREFIX``, the matching path fragments are replaced with the
+:variable:`CMAKE_INSTALL_PREFIX`.
diff --git a/Help/variable/CMAKE_STANDARD_LIBRARIES.rst b/Help/variable/CMAKE_STANDARD_LIBRARIES.rst
new file mode 100644
index 000000000..9c728cdbc
--- /dev/null
+++ b/Help/variable/CMAKE_STANDARD_LIBRARIES.rst
@@ -0,0 +1,7 @@
+CMAKE_STANDARD_LIBRARIES
+------------------------
+
+Libraries linked into every executable and shared library.
+
+This is the list of libraries that are linked into all executables and
+libraries.
diff --git a/Help/variable/CMAKE_STATIC_LIBRARY_PREFIX.rst b/Help/variable/CMAKE_STATIC_LIBRARY_PREFIX.rst
new file mode 100644
index 000000000..714b5cc3b
--- /dev/null
+++ b/Help/variable/CMAKE_STATIC_LIBRARY_PREFIX.rst
@@ -0,0 +1,8 @@
+CMAKE_STATIC_LIBRARY_PREFIX
+---------------------------
+
+The prefix for static libraries that you link to.
+
+The prefix to use for the name of a static library, ``lib`` on UNIX.
+
+``CMAKE_STATIC_LIBRARY_PREFIX_<LANG>`` overrides this for language ``<LANG>``.
diff --git a/Help/variable/CMAKE_STATIC_LIBRARY_SUFFIX.rst b/Help/variable/CMAKE_STATIC_LIBRARY_SUFFIX.rst
new file mode 100644
index 000000000..28dc09dd3
--- /dev/null
+++ b/Help/variable/CMAKE_STATIC_LIBRARY_SUFFIX.rst
@@ -0,0 +1,9 @@
+CMAKE_STATIC_LIBRARY_SUFFIX
+---------------------------
+
+The suffix for static libraries that you link to.
+
+The suffix to use for the end of a static library filename, ``.lib`` on
+Windows.
+
+``CMAKE_STATIC_LIBRARY_SUFFIX_<LANG>`` overrides this for language ``<LANG>``.
diff --git a/Help/variable/CMAKE_STATIC_LINKER_FLAGS.rst b/Help/variable/CMAKE_STATIC_LINKER_FLAGS.rst
new file mode 100644
index 000000000..9c38673aa
--- /dev/null
+++ b/Help/variable/CMAKE_STATIC_LINKER_FLAGS.rst
@@ -0,0 +1,6 @@
+CMAKE_STATIC_LINKER_FLAGS
+-------------------------
+
+Linker flags to be used to create static libraries.
+
+These flags will be used by the linker when creating a static library.
diff --git a/Help/variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG.rst b/Help/variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG.rst
new file mode 100644
index 000000000..b9f8003c7
--- /dev/null
+++ b/Help/variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG.rst
@@ -0,0 +1,7 @@
+CMAKE_STATIC_LINKER_FLAGS_<CONFIG>
+----------------------------------
+
+Flags to be used when linking a static library.
+
+Same as ``CMAKE_C_FLAGS_*`` but used by the linker when creating static
+libraries.
diff --git a/Help/variable/CMAKE_SYSROOT.rst b/Help/variable/CMAKE_SYSROOT.rst
new file mode 100644
index 000000000..7aa04506c
--- /dev/null
+++ b/Help/variable/CMAKE_SYSROOT.rst
@@ -0,0 +1,12 @@
+CMAKE_SYSROOT
+-------------
+
+Path to pass to the compiler in the ``--sysroot`` flag.
+
+The ``CMAKE_SYSROOT`` content is passed to the compiler in the ``--sysroot``
+flag, if supported. The path is also stripped from the RPATH/RUNPATH if
+necessary on installation. The ``CMAKE_SYSROOT`` is also used to prefix
+paths searched by the ``find_*`` commands.
+
+This variable may only be set in a toolchain file specified by
+the :variable:`CMAKE_TOOLCHAIN_FILE` variable.
diff --git a/Help/variable/CMAKE_SYSTEM.rst b/Help/variable/CMAKE_SYSTEM.rst
new file mode 100644
index 000000000..c7d0d8a5d
--- /dev/null
+++ b/Help/variable/CMAKE_SYSTEM.rst
@@ -0,0 +1,10 @@
+CMAKE_SYSTEM
+------------
+
+Composite name of operating system CMake is compiling for.
+
+This variable is the composite of :variable:`CMAKE_SYSTEM_NAME` and
+:variable:`CMAKE_SYSTEM_VERSION`, e.g.
+``${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_VERSION}``. If
+:variable:`CMAKE_SYSTEM_VERSION` is not set, then this variable is
+the same as :variable:`CMAKE_SYSTEM_NAME`.
diff --git a/Help/variable/CMAKE_SYSTEM_APPBUNDLE_PATH.rst b/Help/variable/CMAKE_SYSTEM_APPBUNDLE_PATH.rst
new file mode 100644
index 000000000..3c6687c6e
--- /dev/null
+++ b/Help/variable/CMAKE_SYSTEM_APPBUNDLE_PATH.rst
@@ -0,0 +1,7 @@
+CMAKE_SYSTEM_APPBUNDLE_PATH
+---------------------------
+
+Search path for OS X application bundles used by the :command:`find_program`,
+and :command:`find_package` commands. By default it contains the standard
+directories for the current system. It is *not* intended to be modified by
+the project, use :variable:`CMAKE_APPBUNDLE_PATH` for this.
diff --git a/Help/variable/CMAKE_SYSTEM_FRAMEWORK_PATH.rst b/Help/variable/CMAKE_SYSTEM_FRAMEWORK_PATH.rst
new file mode 100644
index 000000000..1e8b0d947
--- /dev/null
+++ b/Help/variable/CMAKE_SYSTEM_FRAMEWORK_PATH.rst
@@ -0,0 +1,8 @@
+CMAKE_SYSTEM_FRAMEWORK_PATH
+---------------------------
+
+Search path for OS X frameworks used by the :command:`find_library`,
+:command:`find_package`, :command:`find_path`, and :command:`find_file`
+commands. By default it contains the standard directories for the
+current system. It is *not* intended to be modified by the project,
+use :variable:`CMAKE_FRAMEWORK_PATH` for this.
diff --git a/Help/variable/CMAKE_SYSTEM_IGNORE_PATH.rst b/Help/variable/CMAKE_SYSTEM_IGNORE_PATH.rst
new file mode 100644
index 000000000..4ad7e33ce
--- /dev/null
+++ b/Help/variable/CMAKE_SYSTEM_IGNORE_PATH.rst
@@ -0,0 +1,18 @@
+CMAKE_SYSTEM_IGNORE_PATH
+------------------------
+
+:ref:`;-list <CMake Language Lists>` of directories to be *ignored* by
+the :command:`find_program`, :command:`find_library`, :command:`find_file`,
+and :command:`find_path` commands. This is useful in cross-compiling
+environments where some system directories contain incompatible but
+possibly linkable libraries. For example, on cross-compiled cluster
+environments, this allows a user to ignore directories containing
+libraries meant for the front-end machine.
+
+By default this contains a list of directories containing incompatible
+binaries for the host system. See the :variable:`CMAKE_IGNORE_PATH` variable
+that is intended to be set by the project.
+
+See also the :variable:`CMAKE_SYSTEM_PREFIX_PATH`,
+:variable:`CMAKE_SYSTEM_LIBRARY_PATH`, :variable:`CMAKE_SYSTEM_INCLUDE_PATH`,
+and :variable:`CMAKE_SYSTEM_PROGRAM_PATH` variables.
diff --git a/Help/variable/CMAKE_SYSTEM_INCLUDE_PATH.rst b/Help/variable/CMAKE_SYSTEM_INCLUDE_PATH.rst
new file mode 100644
index 000000000..2c14345c0
--- /dev/null
+++ b/Help/variable/CMAKE_SYSTEM_INCLUDE_PATH.rst
@@ -0,0 +1,8 @@
+CMAKE_SYSTEM_INCLUDE_PATH
+-------------------------
+
+:ref:`;-list <CMake Language Lists>` of directories specifying a search path
+for the :command:`find_file` and :command:`find_path` commands. By default
+this contains the standard directories for the current system. It is *not*
+intended to be modified by the project; use :variable:`CMAKE_INCLUDE_PATH` for
+this. See also :variable:`CMAKE_SYSTEM_PREFIX_PATH`.
diff --git a/Help/variable/CMAKE_SYSTEM_LIBRARY_PATH.rst b/Help/variable/CMAKE_SYSTEM_LIBRARY_PATH.rst
new file mode 100644
index 000000000..3969cb94c
--- /dev/null
+++ b/Help/variable/CMAKE_SYSTEM_LIBRARY_PATH.rst
@@ -0,0 +1,8 @@
+CMAKE_SYSTEM_LIBRARY_PATH
+-------------------------
+
+:ref:`;-list <CMake Language Lists>` of directories specifying a search path
+for the :command:`find_library` command. By default this contains the
+standard directories for the current system. It is *not* intended to be
+modified by the project; use :variable:`CMAKE_LIBRARY_PATH` for this.
+See also :variable:`CMAKE_SYSTEM_PREFIX_PATH`.
diff --git a/Help/variable/CMAKE_SYSTEM_NAME.rst b/Help/variable/CMAKE_SYSTEM_NAME.rst
new file mode 100644
index 000000000..c3a42e5b4
--- /dev/null
+++ b/Help/variable/CMAKE_SYSTEM_NAME.rst
@@ -0,0 +1,20 @@
+CMAKE_SYSTEM_NAME
+-----------------
+
+The name of the operating system for which CMake is to build.
+See the :variable:`CMAKE_SYSTEM_VERSION` variable for the OS version.
+
+System Name for Host Builds
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+``CMAKE_SYSTEM_NAME`` is by default set to the same value as the
+:variable:`CMAKE_HOST_SYSTEM_NAME` variable so that the build
+targets the host system.
+
+System Name for Cross Compiling
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+``CMAKE_SYSTEM_NAME`` may be set explicitly when first configuring a new build
+tree in order to enable :ref:`cross compiling <Cross Compiling Toolchain>`.
+In this case the :variable:`CMAKE_SYSTEM_VERSION` variable must also be
+set explicitly.
diff --git a/Help/variable/CMAKE_SYSTEM_PREFIX_PATH.rst b/Help/variable/CMAKE_SYSTEM_PREFIX_PATH.rst
new file mode 100644
index 000000000..e74dfad18
--- /dev/null
+++ b/Help/variable/CMAKE_SYSTEM_PREFIX_PATH.rst
@@ -0,0 +1,18 @@
+CMAKE_SYSTEM_PREFIX_PATH
+------------------------
+
+:ref:`;-list <CMake Language Lists>` of directories specifying installation
+*prefixes* to be searched by the :command:`find_package`,
+:command:`find_program`, :command:`find_library`, :command:`find_file`, and
+:command:`find_path` commands. Each command will add appropriate
+subdirectories (like ``bin``, ``lib``, or ``include``) as specified in its own
+documentation.
+
+By default this contains the standard directories for the current system, the
+:variable:`CMAKE_INSTALL_PREFIX`, and the :variable:`CMAKE_STAGING_PREFIX`.
+It is *not* intended to be modified by the project; use
+:variable:`CMAKE_PREFIX_PATH` for this.
+
+See also :variable:`CMAKE_SYSTEM_INCLUDE_PATH`,
+:variable:`CMAKE_SYSTEM_LIBRARY_PATH`, :variable:`CMAKE_SYSTEM_PROGRAM_PATH`,
+and :variable:`CMAKE_SYSTEM_IGNORE_PATH`.
diff --git a/Help/variable/CMAKE_SYSTEM_PROCESSOR.rst b/Help/variable/CMAKE_SYSTEM_PROCESSOR.rst
new file mode 100644
index 000000000..09280dee6
--- /dev/null
+++ b/Help/variable/CMAKE_SYSTEM_PROCESSOR.rst
@@ -0,0 +1,10 @@
+CMAKE_SYSTEM_PROCESSOR
+----------------------
+
+The name of the CPU CMake is building for.
+
+This variable is the same as :variable:`CMAKE_HOST_SYSTEM_PROCESSOR` if
+you build for the host system instead of the target system when
+cross compiling.
+
+* The :generator:`Green Hills MULTI` generator sets this to ``ARM`` by default.
diff --git a/Help/variable/CMAKE_SYSTEM_PROGRAM_PATH.rst b/Help/variable/CMAKE_SYSTEM_PROGRAM_PATH.rst
new file mode 100644
index 000000000..cf1b83e80
--- /dev/null
+++ b/Help/variable/CMAKE_SYSTEM_PROGRAM_PATH.rst
@@ -0,0 +1,8 @@
+CMAKE_SYSTEM_PROGRAM_PATH
+-------------------------
+
+:ref:`;-list <CMake Language Lists>` of directories specifying a search path
+for the :command:`find_program` command. By default this contains the
+standard directories for the current system. It is *not* intended to be
+modified by the project; use :variable:`CMAKE_PROGRAM_PATH` for this.
+See also :variable:`CMAKE_SYSTEM_PREFIX_PATH`.
diff --git a/Help/variable/CMAKE_SYSTEM_VERSION.rst b/Help/variable/CMAKE_SYSTEM_VERSION.rst
new file mode 100644
index 000000000..aba8ca32b
--- /dev/null
+++ b/Help/variable/CMAKE_SYSTEM_VERSION.rst
@@ -0,0 +1,28 @@
+CMAKE_SYSTEM_VERSION
+--------------------
+
+The version of the operating system for which CMake is to build.
+See the :variable:`CMAKE_SYSTEM_NAME` variable for the OS name.
+
+System Version for Host Builds
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When the :variable:`CMAKE_SYSTEM_NAME` variable takes its default value
+then ``CMAKE_SYSTEM_VERSION`` is by default set to the same value as the
+:variable:`CMAKE_HOST_SYSTEM_VERSION` variable so that the build targets
+the host system version.
+
+In the case of a host build then ``CMAKE_SYSTEM_VERSION`` may be set
+explicitly when first configuring a new build tree in order to enable
+targeting the build for a different version of the host operating system
+than is actually running on the host. This is allowed and not considered
+cross compiling so long as the binaries built for the specified OS version
+can still run on the host.
+
+System Version for Cross Compiling
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When the :variable:`CMAKE_SYSTEM_NAME` variable is set explicitly to
+enable :ref:`cross compiling <Cross Compiling Toolchain>` then the
+value of ``CMAKE_SYSTEM_VERSION`` must also be set explicitly to specify
+the target system version.
diff --git a/Help/variable/CMAKE_TOOLCHAIN_FILE.rst b/Help/variable/CMAKE_TOOLCHAIN_FILE.rst
new file mode 100644
index 000000000..168ee74c7
--- /dev/null
+++ b/Help/variable/CMAKE_TOOLCHAIN_FILE.rst
@@ -0,0 +1,9 @@
+CMAKE_TOOLCHAIN_FILE
+--------------------
+
+Path to toolchain file supplied to :manual:`cmake(1)`.
+
+This variable is specified on the command line when cross-compiling with CMake.
+It is the path to a file which is read early in the CMake run and which
+specifies locations for compilers and toolchain utilities, and other target
+platform and compiler related information.
diff --git a/Help/variable/CMAKE_TRY_COMPILE_CONFIGURATION.rst b/Help/variable/CMAKE_TRY_COMPILE_CONFIGURATION.rst
new file mode 100644
index 000000000..d731f02c0
--- /dev/null
+++ b/Help/variable/CMAKE_TRY_COMPILE_CONFIGURATION.rst
@@ -0,0 +1,10 @@
+CMAKE_TRY_COMPILE_CONFIGURATION
+-------------------------------
+
+Build configuration used for :command:`try_compile` and :command:`try_run`
+projects.
+
+Projects built by :command:`try_compile` and :command:`try_run` are built
+synchronously during the CMake configuration step. Therefore a specific build
+configuration must be chosen even if the generated build system
+supports multiple configurations.
diff --git a/Help/variable/CMAKE_TWEAK_VERSION.rst b/Help/variable/CMAKE_TWEAK_VERSION.rst
new file mode 100644
index 000000000..be2e0500f
--- /dev/null
+++ b/Help/variable/CMAKE_TWEAK_VERSION.rst
@@ -0,0 +1,11 @@
+CMAKE_TWEAK_VERSION
+-------------------
+
+Defined to ``0`` for compatibility with code written for older
+CMake versions that may have defined higher values.
+
+.. note::
+
+ In CMake versions 2.8.2 through 2.8.12, this variable holds
+ the fourth version number component of the
+ :variable:`CMAKE_VERSION` variable.
diff --git a/Help/variable/CMAKE_USER_MAKE_RULES_OVERRIDE.rst b/Help/variable/CMAKE_USER_MAKE_RULES_OVERRIDE.rst
new file mode 100644
index 000000000..9af0d97d4
--- /dev/null
+++ b/Help/variable/CMAKE_USER_MAKE_RULES_OVERRIDE.rst
@@ -0,0 +1,23 @@
+CMAKE_USER_MAKE_RULES_OVERRIDE
+------------------------------
+
+Specify a CMake file that overrides platform information.
+
+CMake loads the specified file while enabling support for each
+language from either the :command:`project` or :command:`enable_language`
+commands. It is loaded after CMake's builtin compiler and platform information
+modules have been loaded but before the information is used. The file
+may set platform information variables to override CMake's defaults.
+
+This feature is intended for use only in overriding information
+variables that must be set before CMake builds its first test project
+to check that the compiler for a language works. It should not be
+used to load a file in cases that a normal :command:`include` will work. Use
+it only as a last resort for behavior that cannot be achieved any
+other way. For example, one may set ``CMAKE_C_FLAGS_INIT`` to change the
+default value used to initialize :variable:`CMAKE_C_FLAGS <CMAKE_<LANG>_FLAGS>`
+before it is cached. The override file should NOT be used to set anything
+that could be set after languages are enabled, such as variables like
+:variable:`CMAKE_RUNTIME_OUTPUT_DIRECTORY` that affect the placement of
+binaries. Information set in the file will be used for :command:`try_compile`
+and :command:`try_run` builds too.
diff --git a/Help/variable/CMAKE_USER_MAKE_RULES_OVERRIDE_LANG.rst b/Help/variable/CMAKE_USER_MAKE_RULES_OVERRIDE_LANG.rst
new file mode 100644
index 000000000..e7139ac3c
--- /dev/null
+++ b/Help/variable/CMAKE_USER_MAKE_RULES_OVERRIDE_LANG.rst
@@ -0,0 +1,8 @@
+CMAKE_USER_MAKE_RULES_OVERRIDE_<LANG>
+-------------------------------------
+
+Specify a CMake file that overrides platform information for ``<LANG>``.
+
+This is a language-specific version of
+:variable:`CMAKE_USER_MAKE_RULES_OVERRIDE` loaded only when enabling language
+``<LANG>``.
diff --git a/Help/variable/CMAKE_USE_RELATIVE_PATHS.rst b/Help/variable/CMAKE_USE_RELATIVE_PATHS.rst
new file mode 100644
index 000000000..06fe0fbc6
--- /dev/null
+++ b/Help/variable/CMAKE_USE_RELATIVE_PATHS.rst
@@ -0,0 +1,5 @@
+CMAKE_USE_RELATIVE_PATHS
+------------------------
+
+This variable has no effect. The partially implemented effect it
+had in previous releases was removed in CMake 3.4.
diff --git a/Help/variable/CMAKE_VERBOSE_MAKEFILE.rst b/Help/variable/CMAKE_VERBOSE_MAKEFILE.rst
new file mode 100644
index 000000000..232a2fd0f
--- /dev/null
+++ b/Help/variable/CMAKE_VERBOSE_MAKEFILE.rst
@@ -0,0 +1,9 @@
+CMAKE_VERBOSE_MAKEFILE
+----------------------
+
+Enable verbose output from Makefile builds.
+
+This variable is a cache entry initialized (to ``FALSE``) by
+the :command:`project` command. Users may enable the option
+in their local build tree to get more verbose output from
+Makefile builds and show each command line as it is launched.
diff --git a/Help/variable/CMAKE_VERSION.rst b/Help/variable/CMAKE_VERSION.rst
new file mode 100644
index 000000000..bbb1d91be
--- /dev/null
+++ b/Help/variable/CMAKE_VERSION.rst
@@ -0,0 +1,51 @@
+CMAKE_VERSION
+-------------
+
+The CMake version string as three non-negative integer components
+separated by ``.`` and possibly followed by ``-`` and other information.
+The first two components represent the feature level and the third
+component represents either a bug-fix level or development date.
+
+Release versions and release candidate versions of CMake use the format::
+
+ <major>.<minor>.<patch>[-rc<n>]
+
+where the ``<patch>`` component is less than ``20000000``. Development
+versions of CMake use the format::
+
+ <major>.<minor>.<date>[-<id>]
+
+where the ``<date>`` component is of format ``CCYYMMDD`` and ``<id>``
+may contain arbitrary text. This represents development as of a
+particular date following the ``<major>.<minor>`` feature release.
+
+Individual component values are also available in variables:
+
+* :variable:`CMAKE_MAJOR_VERSION`
+* :variable:`CMAKE_MINOR_VERSION`
+* :variable:`CMAKE_PATCH_VERSION`
+* :variable:`CMAKE_TWEAK_VERSION`
+
+Use the :command:`if` command ``VERSION_LESS``, ``VERSION_EQUAL``, or
+``VERSION_GREATER`` operators to compare version string values against
+``CMAKE_VERSION`` using a component-wise test. Version component
+values may be 10 or larger so do not attempt to compare version
+strings as floating-point numbers.
+
+.. note::
+
+ CMake versions 2.8.2 through 2.8.12 used three components for the
+ feature level. Release versions represented the bug-fix level in a
+ fourth component, i.e. ``<major>.<minor>.<patch>[.<tweak>][-rc<n>]``.
+ Development versions represented the development date in the fourth
+ component, i.e. ``<major>.<minor>.<patch>.<date>[-<id>]``.
+
+ CMake versions prior to 2.8.2 used three components for the
+ feature level and had no bug-fix component. Release versions
+ used an even-valued second component, i.e.
+ ``<major>.<even-minor>.<patch>[-rc<n>]``. Development versions
+ used an odd-valued second component with the development date as
+ the third component, i.e. ``<major>.<odd-minor>.<date>``.
+
+ The ``CMAKE_VERSION`` variable is defined by CMake 2.6.3 and higher.
+ Earlier versions defined only the individual component variables.
diff --git a/Help/variable/CMAKE_VISIBILITY_INLINES_HIDDEN.rst b/Help/variable/CMAKE_VISIBILITY_INLINES_HIDDEN.rst
new file mode 100644
index 000000000..150baccc1
--- /dev/null
+++ b/Help/variable/CMAKE_VISIBILITY_INLINES_HIDDEN.rst
@@ -0,0 +1,5 @@
+CMAKE_VISIBILITY_INLINES_HIDDEN
+-------------------------------
+
+Default value for the :prop_tgt:`VISIBILITY_INLINES_HIDDEN` target
+property when a target is created.
diff --git a/Help/variable/CMAKE_VS_DEVENV_COMMAND.rst b/Help/variable/CMAKE_VS_DEVENV_COMMAND.rst
new file mode 100644
index 000000000..14cc50ac6
--- /dev/null
+++ b/Help/variable/CMAKE_VS_DEVENV_COMMAND.rst
@@ -0,0 +1,14 @@
+CMAKE_VS_DEVENV_COMMAND
+-----------------------
+
+The generators for :generator:`Visual Studio 7` and above set this
+variable to the ``devenv.com`` command installed with the corresponding
+Visual Studio version. Note that this variable may be empty on
+Visual Studio Express editions because they do not provide this tool.
+
+This variable is not defined by other generators even if ``devenv.com``
+is installed on the computer.
+
+The :variable:`CMAKE_VS_MSBUILD_COMMAND` is also provided for
+:generator:`Visual Studio 10 2010` and above.
+See also the :variable:`CMAKE_MAKE_PROGRAM` variable.
diff --git a/Help/variable/CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD.rst b/Help/variable/CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD.rst
new file mode 100644
index 000000000..f54472ad1
--- /dev/null
+++ b/Help/variable/CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD.rst
@@ -0,0 +1,8 @@
+CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD
+-----------------------------------------
+
+Include ``INSTALL`` target to default build.
+
+In Visual Studio solution, by default the ``INSTALL`` target will not be part
+of the default build. Setting this variable will enable the ``INSTALL`` target
+to be part of the default build.
diff --git a/Help/variable/CMAKE_VS_INTEL_Fortran_PROJECT_VERSION.rst b/Help/variable/CMAKE_VS_INTEL_Fortran_PROJECT_VERSION.rst
new file mode 100644
index 000000000..0be10e5a0
--- /dev/null
+++ b/Help/variable/CMAKE_VS_INTEL_Fortran_PROJECT_VERSION.rst
@@ -0,0 +1,7 @@
+CMAKE_VS_INTEL_Fortran_PROJECT_VERSION
+--------------------------------------
+
+When generating for :generator:`Visual Studio 7` or greater with the Intel
+Fortran plugin installed, this specifies the ``.vfproj`` project file format
+version. This is intended for internal use by CMake and should not be
+used by project code.
diff --git a/Help/variable/CMAKE_VS_MSBUILD_COMMAND.rst b/Help/variable/CMAKE_VS_MSBUILD_COMMAND.rst
new file mode 100644
index 000000000..58f2bef4c
--- /dev/null
+++ b/Help/variable/CMAKE_VS_MSBUILD_COMMAND.rst
@@ -0,0 +1,13 @@
+CMAKE_VS_MSBUILD_COMMAND
+------------------------
+
+The generators for :generator:`Visual Studio 10 2010` and above set this
+variable to the ``MSBuild.exe`` command installed with the corresponding
+Visual Studio version.
+
+This variable is not defined by other generators even if ``MSBuild.exe``
+is installed on the computer.
+
+The :variable:`CMAKE_VS_DEVENV_COMMAND` is also provided for the
+non-Express editions of Visual Studio.
+See also the :variable:`CMAKE_MAKE_PROGRAM` variable.
diff --git a/Help/variable/CMAKE_VS_MSDEV_COMMAND.rst b/Help/variable/CMAKE_VS_MSDEV_COMMAND.rst
new file mode 100644
index 000000000..718baaf82
--- /dev/null
+++ b/Help/variable/CMAKE_VS_MSDEV_COMMAND.rst
@@ -0,0 +1,10 @@
+CMAKE_VS_MSDEV_COMMAND
+----------------------
+
+The :generator:`Visual Studio 6` generator sets this variable to the
+``msdev.exe`` command installed with Visual Studio 6.
+
+This variable is not defined by other generators even if ``msdev.exe``
+is installed on the computer.
+
+See also the :variable:`CMAKE_MAKE_PROGRAM` variable.
diff --git a/Help/variable/CMAKE_VS_NsightTegra_VERSION.rst b/Help/variable/CMAKE_VS_NsightTegra_VERSION.rst
new file mode 100644
index 000000000..386c3a9de
--- /dev/null
+++ b/Help/variable/CMAKE_VS_NsightTegra_VERSION.rst
@@ -0,0 +1,7 @@
+CMAKE_VS_NsightTegra_VERSION
+----------------------------
+
+When using a Visual Studio generator with the
+:variable:`CMAKE_SYSTEM_NAME` variable set to ``Android``,
+this variable contains the version number of the
+installed NVIDIA Nsight Tegra Visual Studio Edition.
diff --git a/Help/variable/CMAKE_VS_PLATFORM_NAME.rst b/Help/variable/CMAKE_VS_PLATFORM_NAME.rst
new file mode 100644
index 000000000..c6f8d411c
--- /dev/null
+++ b/Help/variable/CMAKE_VS_PLATFORM_NAME.rst
@@ -0,0 +1,7 @@
+CMAKE_VS_PLATFORM_NAME
+----------------------
+
+Visual Studio target platform name.
+
+VS 8 and above allow project files to specify a target platform.
+CMake provides the name of the chosen platform in this variable.
diff --git a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET.rst b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET.rst
new file mode 100644
index 000000000..144a41dc6
--- /dev/null
+++ b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET.rst
@@ -0,0 +1,10 @@
+CMAKE_VS_PLATFORM_TOOLSET
+-------------------------
+
+Visual Studio Platform Toolset name.
+
+VS 10 and above use MSBuild under the hood and support multiple
+compiler toolchains. CMake may specify a toolset explicitly, such as
+``v110`` for VS 11 or ``Windows7.1SDK`` for 64-bit support in VS 10
+Express. CMake provides the name of the chosen toolset in this
+variable.
diff --git a/Help/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION.rst b/Help/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION.rst
new file mode 100644
index 000000000..e0be3a43e
--- /dev/null
+++ b/Help/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION.rst
@@ -0,0 +1,12 @@
+CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION
+----------------------------------------
+
+Visual Studio Windows Target Platform Version.
+
+When targeting Windows 10 and above Visual Studio 2015 and above support
+specification of a target Windows version to select a corresponding SDK.
+The :variable:`CMAKE_SYSTEM_VERSION` variable may be set to specify a
+version. Otherwise CMake computes a default version based on the Windows
+SDK versions available. The chosen Windows target version number is provided
+in ``CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION``. If no Windows 10 SDK
+is available this value will be empty.
diff --git a/Help/variable/CMAKE_WARN_DEPRECATED.rst b/Help/variable/CMAKE_WARN_DEPRECATED.rst
new file mode 100644
index 000000000..4a224fa5c
--- /dev/null
+++ b/Help/variable/CMAKE_WARN_DEPRECATED.rst
@@ -0,0 +1,10 @@
+CMAKE_WARN_DEPRECATED
+---------------------
+
+Whether to issue warnings for deprecated functionality.
+
+If not ``FALSE``, use of deprecated functionality will issue warnings.
+If this variable is not set, CMake behaves as if it were set to ``TRUE``.
+
+When running :manual:`cmake(1)`, this option can be enabled with the
+``-Wdeprecated`` option, or disabled with the ``-Wno-deprecated`` option.
diff --git a/Help/variable/CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION.rst b/Help/variable/CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION.rst
new file mode 100644
index 000000000..81c1158c2
--- /dev/null
+++ b/Help/variable/CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION.rst
@@ -0,0 +1,9 @@
+CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION
+------------------------------------------
+
+Ask ``cmake_install.cmake`` script to warn each time a file with absolute
+``INSTALL DESTINATION`` is encountered.
+
+This variable is used by CMake-generated ``cmake_install.cmake`` scripts.
+If one sets this variable to ``ON`` while running the script, it may get
+warning messages from the script.
diff --git a/Help/variable/CMAKE_WIN32_EXECUTABLE.rst b/Help/variable/CMAKE_WIN32_EXECUTABLE.rst
new file mode 100644
index 000000000..b96abba7b
--- /dev/null
+++ b/Help/variable/CMAKE_WIN32_EXECUTABLE.rst
@@ -0,0 +1,7 @@
+CMAKE_WIN32_EXECUTABLE
+----------------------
+
+Default value for :prop_tgt:`WIN32_EXECUTABLE` of targets.
+
+This variable is used to initialize the :prop_tgt:`WIN32_EXECUTABLE` property
+on all the targets. See that target property for additional information.
diff --git a/Help/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.rst b/Help/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.rst
new file mode 100644
index 000000000..1636842d9
--- /dev/null
+++ b/Help/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.rst
@@ -0,0 +1,6 @@
+CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
+--------------------------------
+
+Default value for :prop_tgt:`WINDOWS_EXPORT_ALL_SYMBOLS` target property.
+This variable is used to initialize the property on each target as it is
+created.
diff --git a/Help/variable/CMAKE_XCODE_ATTRIBUTE_an-attribute.rst b/Help/variable/CMAKE_XCODE_ATTRIBUTE_an-attribute.rst
new file mode 100644
index 000000000..be683d668
--- /dev/null
+++ b/Help/variable/CMAKE_XCODE_ATTRIBUTE_an-attribute.rst
@@ -0,0 +1,16 @@
+CMAKE_XCODE_ATTRIBUTE_<an-attribute>
+------------------------------------
+
+Set Xcode target attributes directly.
+
+Tell the :generator:`Xcode` generator to set '<an-attribute>' to a given value
+in the generated Xcode project. Ignored on other generators.
+
+See the :prop_tgt:`XCODE_ATTRIBUTE_<an-attribute>` target property
+to set attributes on a specific target.
+
+Contents of ``CMAKE_XCODE_ATTRIBUTE_<an-attribute>`` may use
+"generator expressions" with the syntax ``$<...>``. See the
+:manual:`cmake-generator-expressions(7)` manual for available
+expressions. See the :manual:`cmake-buildsystem(7)` manual
+for more on defining buildsystem properties.
diff --git a/Help/variable/CMAKE_XCODE_PLATFORM_TOOLSET.rst b/Help/variable/CMAKE_XCODE_PLATFORM_TOOLSET.rst
new file mode 100644
index 000000000..210da52d5
--- /dev/null
+++ b/Help/variable/CMAKE_XCODE_PLATFORM_TOOLSET.rst
@@ -0,0 +1,9 @@
+CMAKE_XCODE_PLATFORM_TOOLSET
+----------------------------
+
+Xcode compiler selection.
+
+:generator:`Xcode` supports selection of a compiler from one of the installed
+toolsets. CMake provides the name of the chosen toolset in this
+variable, if any is explicitly selected (e.g. via the :manual:`cmake(1)`
+``-T`` option).
diff --git a/Help/variable/CPACK_ABSOLUTE_DESTINATION_FILES.rst b/Help/variable/CPACK_ABSOLUTE_DESTINATION_FILES.rst
new file mode 100644
index 000000000..928fe4589
--- /dev/null
+++ b/Help/variable/CPACK_ABSOLUTE_DESTINATION_FILES.rst
@@ -0,0 +1,10 @@
+CPACK_ABSOLUTE_DESTINATION_FILES
+--------------------------------
+
+List of files which have been installed using an ``ABSOLUTE DESTINATION`` path.
+
+This variable is a Read-Only variable which is set internally by CPack
+during installation and before packaging using
+:variable:`CMAKE_ABSOLUTE_DESTINATION_FILES` defined in ``cmake_install.cmake``
+scripts. The value can be used within CPack project configuration
+file and/or ``CPack<GEN>.cmake`` file of ``<GEN>`` generator.
diff --git a/Help/variable/CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY.rst b/Help/variable/CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY.rst
new file mode 100644
index 000000000..6cf75e443
--- /dev/null
+++ b/Help/variable/CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY.rst
@@ -0,0 +1,8 @@
+CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY
+------------------------------------------
+
+Boolean toggle to include/exclude top level directory (component case).
+
+Similar usage as :variable:`CPACK_INCLUDE_TOPLEVEL_DIRECTORY` but for the
+component case. See :variable:`CPACK_INCLUDE_TOPLEVEL_DIRECTORY`
+documentation for the detail.
diff --git a/Help/variable/CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION.rst b/Help/variable/CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION.rst
new file mode 100644
index 000000000..5dad6bd68
--- /dev/null
+++ b/Help/variable/CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION.rst
@@ -0,0 +1,11 @@
+CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION
+-------------------------------------------
+
+Ask CPack to error out as soon as a file with absolute ``INSTALL DESTINATION``
+is encountered.
+
+The fatal error is emitted before the installation of the offending
+file takes place. Some CPack generators, like NSIS, enforce this
+internally. This variable triggers the definition
+of :variable:`CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION` when CPack
+runs.
diff --git a/Help/variable/CPACK_INCLUDE_TOPLEVEL_DIRECTORY.rst b/Help/variable/CPACK_INCLUDE_TOPLEVEL_DIRECTORY.rst
new file mode 100644
index 000000000..b8e9105a4
--- /dev/null
+++ b/Help/variable/CPACK_INCLUDE_TOPLEVEL_DIRECTORY.rst
@@ -0,0 +1,20 @@
+CPACK_INCLUDE_TOPLEVEL_DIRECTORY
+--------------------------------
+
+Boolean toggle to include/exclude top level directory.
+
+When preparing a package CPack installs the item under the so-called
+top level directory. The purpose of is to include (set to ``1`` or ``ON`` or
+``TRUE``) the top level directory in the package or not (set to ``0`` or
+``OFF`` or ``FALSE``).
+
+Each CPack generator has a built-in default value for this variable.
+E.g. Archive generators (ZIP, TGZ, ...) includes the top level
+whereas RPM or DEB don't. The user may override the default value by
+setting this variable.
+
+There is a similar variable
+:variable:`CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY` which may be used
+to override the behavior for the component packaging
+case which may have different default value for historical (now
+backward compatibility) reason.
diff --git a/Help/variable/CPACK_INSTALL_SCRIPT.rst b/Help/variable/CPACK_INSTALL_SCRIPT.rst
new file mode 100644
index 000000000..12a48a40d
--- /dev/null
+++ b/Help/variable/CPACK_INSTALL_SCRIPT.rst
@@ -0,0 +1,8 @@
+CPACK_INSTALL_SCRIPT
+--------------------
+
+Extra CMake script provided by the user.
+
+If set this CMake script will be executed by CPack during its local
+[CPack-private] installation which is done right before packaging the
+files. The script is not called by e.g.: ``make install``.
diff --git a/Help/variable/CPACK_PACKAGING_INSTALL_PREFIX.rst b/Help/variable/CPACK_PACKAGING_INSTALL_PREFIX.rst
new file mode 100644
index 000000000..f423e2e7f
--- /dev/null
+++ b/Help/variable/CPACK_PACKAGING_INSTALL_PREFIX.rst
@@ -0,0 +1,15 @@
+CPACK_PACKAGING_INSTALL_PREFIX
+------------------------------
+
+The prefix used in the built package.
+
+Each CPack generator has a default value (like ``/usr``). This default
+value may be overwritten from the ``CMakeLists.txt`` or the :manual:`cpack(1)`
+command line by setting an alternative value. Example:
+
+::
+
+ set(CPACK_PACKAGING_INSTALL_PREFIX "/opt")
+
+This is not the same purpose as :variable:`CMAKE_INSTALL_PREFIX` which is used
+when installing from the build tree without building a package.
diff --git a/Help/variable/CPACK_SET_DESTDIR.rst b/Help/variable/CPACK_SET_DESTDIR.rst
new file mode 100644
index 000000000..27fd355ce
--- /dev/null
+++ b/Help/variable/CPACK_SET_DESTDIR.rst
@@ -0,0 +1,31 @@
+CPACK_SET_DESTDIR
+-----------------
+
+Boolean toggle to make CPack use ``DESTDIR`` mechanism when packaging.
+
+``DESTDIR`` means DESTination DIRectory. It is commonly used by makefile
+users in order to install software at non-default location. It is a
+basic relocation mechanism that should not be used on Windows (see
+:variable:`CMAKE_INSTALL_PREFIX` documentation). It is usually invoked like
+this:
+
+::
+
+ make DESTDIR=/home/john install
+
+which will install the concerned software using the installation
+prefix, e.g. ``/usr/local`` prepended with the ``DESTDIR`` value which
+finally gives ``/home/john/usr/local``. When preparing a package, CPack
+first installs the items to be packaged in a local (to the build tree)
+directory by using the same ``DESTDIR`` mechanism. Nevertheless, if
+``CPACK_SET_DESTDIR`` is set then CPack will set ``DESTDIR`` before doing the
+local install. The most noticeable difference is that without
+``CPACK_SET_DESTDIR``, CPack uses :variable:`CPACK_PACKAGING_INSTALL_PREFIX`
+as a prefix whereas with ``CPACK_SET_DESTDIR`` set, CPack will use
+:variable:`CMAKE_INSTALL_PREFIX` as a prefix.
+
+Manually setting ``CPACK_SET_DESTDIR`` may help (or simply be necessary)
+if some install rules uses absolute ``DESTINATION`` (see CMake
+:command:`install` command). However, starting with CPack/CMake 2.8.3 RPM
+and DEB installers tries to handle ``DESTDIR`` automatically so that it is
+seldom necessary for the user to set it.
diff --git a/Help/variable/CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION.rst b/Help/variable/CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION.rst
new file mode 100644
index 000000000..3fc5cca0e
--- /dev/null
+++ b/Help/variable/CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION.rst
@@ -0,0 +1,9 @@
+CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION
+------------------------------------------
+
+Ask CPack to warn each time a file with absolute ``INSTALL DESTINATION`` is
+encountered.
+
+This variable triggers the definition of
+:variable:`CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION` when CPack runs
+``cmake_install.cmake`` scripts.
diff --git a/Help/variable/CTEST_BINARY_DIRECTORY.rst b/Help/variable/CTEST_BINARY_DIRECTORY.rst
new file mode 100644
index 000000000..fd8461fd6
--- /dev/null
+++ b/Help/variable/CTEST_BINARY_DIRECTORY.rst
@@ -0,0 +1,5 @@
+CTEST_BINARY_DIRECTORY
+----------------------
+
+Specify the CTest ``BuildDirectory`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_BUILD_COMMAND.rst b/Help/variable/CTEST_BUILD_COMMAND.rst
new file mode 100644
index 000000000..7b13ba06b
--- /dev/null
+++ b/Help/variable/CTEST_BUILD_COMMAND.rst
@@ -0,0 +1,5 @@
+CTEST_BUILD_COMMAND
+-------------------
+
+Specify the CTest ``MakeCommand`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_BUILD_NAME.rst b/Help/variable/CTEST_BUILD_NAME.rst
new file mode 100644
index 000000000..d25d84c0a
--- /dev/null
+++ b/Help/variable/CTEST_BUILD_NAME.rst
@@ -0,0 +1,5 @@
+CTEST_BUILD_NAME
+----------------
+
+Specify the CTest ``BuildName`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_BZR_COMMAND.rst b/Help/variable/CTEST_BZR_COMMAND.rst
new file mode 100644
index 000000000..474d6213e
--- /dev/null
+++ b/Help/variable/CTEST_BZR_COMMAND.rst
@@ -0,0 +1,5 @@
+CTEST_BZR_COMMAND
+-----------------
+
+Specify the CTest ``BZRCommand`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_BZR_UPDATE_OPTIONS.rst b/Help/variable/CTEST_BZR_UPDATE_OPTIONS.rst
new file mode 100644
index 000000000..d0f957980
--- /dev/null
+++ b/Help/variable/CTEST_BZR_UPDATE_OPTIONS.rst
@@ -0,0 +1,5 @@
+CTEST_BZR_UPDATE_OPTIONS
+------------------------
+
+Specify the CTest ``BZRUpdateOptions`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_CHANGE_ID.rst b/Help/variable/CTEST_CHANGE_ID.rst
new file mode 100644
index 000000000..a423f4900
--- /dev/null
+++ b/Help/variable/CTEST_CHANGE_ID.rst
@@ -0,0 +1,9 @@
+CTEST_CHANGE_ID
+---------------
+
+Specify the CTest ``ChangeId`` setting
+in a :manual:`ctest(1)` dashboard client script.
+
+This setting allows CTest to pass arbitrary information about this
+build up to CDash. One use of this feature is to allow CDash to
+post comments on your pull request if anything goes wrong with your build.
diff --git a/Help/variable/CTEST_CHECKOUT_COMMAND.rst b/Help/variable/CTEST_CHECKOUT_COMMAND.rst
new file mode 100644
index 000000000..da256f24f
--- /dev/null
+++ b/Help/variable/CTEST_CHECKOUT_COMMAND.rst
@@ -0,0 +1,5 @@
+CTEST_CHECKOUT_COMMAND
+----------------------
+
+Tell the :command:`ctest_start` command how to checkout or initialize
+the source directory in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_CONFIGURATION_TYPE.rst b/Help/variable/CTEST_CONFIGURATION_TYPE.rst
new file mode 100644
index 000000000..c905480c0
--- /dev/null
+++ b/Help/variable/CTEST_CONFIGURATION_TYPE.rst
@@ -0,0 +1,5 @@
+CTEST_CONFIGURATION_TYPE
+------------------------
+
+Specify the CTest ``DefaultCTestConfigurationType`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_CONFIGURE_COMMAND.rst b/Help/variable/CTEST_CONFIGURE_COMMAND.rst
new file mode 100644
index 000000000..5561b6dcf
--- /dev/null
+++ b/Help/variable/CTEST_CONFIGURE_COMMAND.rst
@@ -0,0 +1,5 @@
+CTEST_CONFIGURE_COMMAND
+-----------------------
+
+Specify the CTest ``ConfigureCommand`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_COVERAGE_COMMAND.rst b/Help/variable/CTEST_COVERAGE_COMMAND.rst
new file mode 100644
index 000000000..0491d4204
--- /dev/null
+++ b/Help/variable/CTEST_COVERAGE_COMMAND.rst
@@ -0,0 +1,60 @@
+CTEST_COVERAGE_COMMAND
+----------------------
+
+Specify the CTest ``CoverageCommand`` setting
+in a :manual:`ctest(1)` dashboard client script.
+
+Cobertura
+'''''''''
+
+Using `Cobertura`_ as the coverage generation within your multi-module
+Java project can generate a series of XML files.
+
+The Cobertura Coverage parser expects to read the coverage data from a
+single XML file which contains the coverage data for all modules.
+Cobertura has a program with the ability to merge given ``cobertura.ser`` files
+and then another program to generate a combined XML file from the previous
+merged file. For command line testing, this can be done by hand prior to
+CTest looking for the coverage files. For script builds,
+set the ``CTEST_COVERAGE_COMMAND`` variable to point to a file which will
+perform these same steps, such as a ``.sh`` or ``.bat`` file.
+
+.. code-block:: cmake
+
+ set(CTEST_COVERAGE_COMMAND .../run-coverage-and-consolidate.sh)
+
+where the ``run-coverage-and-consolidate.sh`` script is perhaps created by
+the :command:`configure_file` command and might contain the following code:
+
+.. code-block:: bash
+
+ #!/usr/bin/env bash
+ CoberturaFiles="$(find "/path/to/source" -name "cobertura.ser")"
+ SourceDirs="$(find "/path/to/source" -name "java" -type d)"
+ cobertura-merge --datafile coberturamerge.ser $CoberturaFiles
+ cobertura-report --datafile coberturamerge.ser --destination . \
+ --format xml $SourceDirs
+
+The script uses ``find`` to capture the paths to all of the ``cobertura.ser``
+files found below the project's source directory. It keeps the list of files
+and supplies it as an argument to the ``cobertura-merge`` program. The
+``--datafile`` argument signifies where the result of the merge will be kept.
+
+The combined ``coberturamerge.ser`` file is then used to generate the XML report
+using the ``cobertura-report`` program. The call to the cobertura-report
+program requires some named arguments.
+
+``--datafila``
+ path to the merged ``.ser`` file
+
+``--destination``
+ path to put the output files(s)
+
+``--format``
+ file format to write output in: xml or html
+
+The rest of the supplied arguments consist of the full paths to the
+``/src/main/java`` directories of each module within the souce tree. These
+directories are needed and should not be forgotten.
+
+.. _`Cobertura`: http://cobertura.github.io/cobertura/
diff --git a/Help/variable/CTEST_COVERAGE_EXTRA_FLAGS.rst b/Help/variable/CTEST_COVERAGE_EXTRA_FLAGS.rst
new file mode 100644
index 000000000..298195508
--- /dev/null
+++ b/Help/variable/CTEST_COVERAGE_EXTRA_FLAGS.rst
@@ -0,0 +1,5 @@
+CTEST_COVERAGE_EXTRA_FLAGS
+--------------------------
+
+Specify the CTest ``CoverageExtraFlags`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_CURL_OPTIONS.rst b/Help/variable/CTEST_CURL_OPTIONS.rst
new file mode 100644
index 000000000..fc5dfc488
--- /dev/null
+++ b/Help/variable/CTEST_CURL_OPTIONS.rst
@@ -0,0 +1,5 @@
+CTEST_CURL_OPTIONS
+------------------
+
+Specify the CTest ``CurlOptions`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_CUSTOM_COVERAGE_EXCLUDE.rst b/Help/variable/CTEST_CUSTOM_COVERAGE_EXCLUDE.rst
new file mode 100644
index 000000000..d5893c9f8
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_COVERAGE_EXCLUDE.rst
@@ -0,0 +1,7 @@
+CTEST_CUSTOM_COVERAGE_EXCLUDE
+-----------------------------
+
+A list of regular expressions which will be used to exclude files by their
+path from coverage output by the :command:`ctest_coverage` command.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_ERROR_EXCEPTION.rst b/Help/variable/CTEST_CUSTOM_ERROR_EXCEPTION.rst
new file mode 100644
index 000000000..cd65ae327
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_ERROR_EXCEPTION.rst
@@ -0,0 +1,7 @@
+CTEST_CUSTOM_ERROR_EXCEPTION
+----------------------------
+
+A list of regular expressions which will be used to exclude when detecting
+error messages in build outputs by the :command:`ctest_test` command.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_ERROR_MATCH.rst b/Help/variable/CTEST_CUSTOM_ERROR_MATCH.rst
new file mode 100644
index 000000000..558f5e580
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_ERROR_MATCH.rst
@@ -0,0 +1,7 @@
+CTEST_CUSTOM_ERROR_MATCH
+------------------------
+
+A list of regular expressions which will be used to detect error messages in
+build outputs by the :command:`ctest_test` command.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_ERROR_POST_CONTEXT.rst b/Help/variable/CTEST_CUSTOM_ERROR_POST_CONTEXT.rst
new file mode 100644
index 000000000..614859bc8
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_ERROR_POST_CONTEXT.rst
@@ -0,0 +1,7 @@
+CTEST_CUSTOM_ERROR_POST_CONTEXT
+-------------------------------
+
+The number of lines to include as context which follow an error message by the
+:command:`ctest_test` command. The default is 10.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_ERROR_PRE_CONTEXT.rst b/Help/variable/CTEST_CUSTOM_ERROR_PRE_CONTEXT.rst
new file mode 100644
index 000000000..74dc47ad2
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_ERROR_PRE_CONTEXT.rst
@@ -0,0 +1,7 @@
+CTEST_CUSTOM_ERROR_PRE_CONTEXT
+------------------------------
+
+The number of lines to include as context which precede an error message by
+the :command:`ctest_test` command. The default is 10.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE.rst b/Help/variable/CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE.rst
new file mode 100644
index 000000000..5aeae88a4
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE.rst
@@ -0,0 +1,8 @@
+CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE
+--------------------------------------------
+
+When saving a failing test's output, this is the maximum size, in bytes, that
+will be collected by the :command:`ctest_test` command. Defaults to 307200
+(300 KiB).
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS.rst b/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS.rst
new file mode 100644
index 000000000..920cb0476
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS.rst
@@ -0,0 +1,8 @@
+CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS
+-------------------------------------
+
+The maximum number of errors in a single build step which will be detected.
+After this, the :command:`ctest_test` command will truncate the output.
+Defaults to 50.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS.rst b/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS.rst
new file mode 100644
index 000000000..a1f1cc14b
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS.rst
@@ -0,0 +1,8 @@
+CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS
+---------------------------------------
+
+The maximum number of warnings in a single build step which will be detected.
+After this, the :command:`ctest_test` command will truncate the output.
+Defaults to 50.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE.rst b/Help/variable/CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE.rst
new file mode 100644
index 000000000..1fbb8c53f
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE.rst
@@ -0,0 +1,8 @@
+CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE
+--------------------------------------------
+
+When saving a passing test's output, this is the maximum size, in bytes, that
+will be collected by the :command:`ctest_test` command. Defaults to 1024
+(1 KiB).
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_MEMCHECK_IGNORE.rst b/Help/variable/CTEST_CUSTOM_MEMCHECK_IGNORE.rst
new file mode 100644
index 000000000..578576cd6
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_MEMCHECK_IGNORE.rst
@@ -0,0 +1,7 @@
+CTEST_CUSTOM_MEMCHECK_IGNORE
+----------------------------
+
+A list of regular expressions to use to exclude tests during the
+:command:`ctest_memcheck` command.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_POST_MEMCHECK.rst b/Help/variable/CTEST_CUSTOM_POST_MEMCHECK.rst
new file mode 100644
index 000000000..40291febd
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_POST_MEMCHECK.rst
@@ -0,0 +1,6 @@
+CTEST_CUSTOM_POST_MEMCHECK
+--------------------------
+
+A list of commands to run at the end of the :command:`ctest_memcheck` command.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_POST_TEST.rst b/Help/variable/CTEST_CUSTOM_POST_TEST.rst
new file mode 100644
index 000000000..791292cd0
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_POST_TEST.rst
@@ -0,0 +1,6 @@
+CTEST_CUSTOM_POST_TEST
+----------------------
+
+A list of commands to run at the end of the :command:`ctest_test` command.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_PRE_MEMCHECK.rst b/Help/variable/CTEST_CUSTOM_PRE_MEMCHECK.rst
new file mode 100644
index 000000000..00de8aa2b
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_PRE_MEMCHECK.rst
@@ -0,0 +1,7 @@
+CTEST_CUSTOM_PRE_MEMCHECK
+-------------------------
+
+A list of commands to run at the start of the :command:`ctest_memcheck`
+command.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_PRE_TEST.rst b/Help/variable/CTEST_CUSTOM_PRE_TEST.rst
new file mode 100644
index 000000000..6af7152ef
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_PRE_TEST.rst
@@ -0,0 +1,6 @@
+CTEST_CUSTOM_PRE_TEST
+----------------------
+
+A list of commands to run at the start of the :command:`ctest_test` command.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_TEST_IGNORE.rst b/Help/variable/CTEST_CUSTOM_TEST_IGNORE.rst
new file mode 100644
index 000000000..6114e608c
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_TEST_IGNORE.rst
@@ -0,0 +1,7 @@
+CTEST_CUSTOM_TEST_IGNORE
+------------------------
+
+A list of regular expressions to use to exclude tests during the
+:command:`ctest_test` command.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_WARNING_EXCEPTION.rst b/Help/variable/CTEST_CUSTOM_WARNING_EXCEPTION.rst
new file mode 100644
index 000000000..36fa37d92
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_WARNING_EXCEPTION.rst
@@ -0,0 +1,7 @@
+CTEST_CUSTOM_WARNING_EXCEPTION
+------------------------------
+
+A list of regular expressions which will be used to exclude when detecting
+warning messages in build outputs by the :command:`ctest_test` command.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_WARNING_MATCH.rst b/Help/variable/CTEST_CUSTOM_WARNING_MATCH.rst
new file mode 100644
index 000000000..a35be96b5
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_WARNING_MATCH.rst
@@ -0,0 +1,7 @@
+CTEST_CUSTOM_WARNING_MATCH
+--------------------------
+
+A list of regular expressions which will be used to detect warning messages in
+build outputs by the :command:`ctest_test` command.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_XXX.txt b/Help/variable/CTEST_CUSTOM_XXX.txt
new file mode 100644
index 000000000..02d15474a
--- /dev/null
+++ b/Help/variable/CTEST_CUSTOM_XXX.txt
@@ -0,0 +1,2 @@
+It is initialized by :manual:`ctest(1)`, but may be edited in a ``CTestCustom``
+file. See :command:`ctest_read_custom_files` documentation.
diff --git a/Help/variable/CTEST_CVS_CHECKOUT.rst b/Help/variable/CTEST_CVS_CHECKOUT.rst
new file mode 100644
index 000000000..6431c0266
--- /dev/null
+++ b/Help/variable/CTEST_CVS_CHECKOUT.rst
@@ -0,0 +1,4 @@
+CTEST_CVS_CHECKOUT
+------------------
+
+Deprecated. Use :variable:`CTEST_CHECKOUT_COMMAND` instead.
diff --git a/Help/variable/CTEST_CVS_COMMAND.rst b/Help/variable/CTEST_CVS_COMMAND.rst
new file mode 100644
index 000000000..049700b3a
--- /dev/null
+++ b/Help/variable/CTEST_CVS_COMMAND.rst
@@ -0,0 +1,5 @@
+CTEST_CVS_COMMAND
+-----------------
+
+Specify the CTest ``CVSCommand`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_CVS_UPDATE_OPTIONS.rst b/Help/variable/CTEST_CVS_UPDATE_OPTIONS.rst
new file mode 100644
index 000000000..d7f2f7c2c
--- /dev/null
+++ b/Help/variable/CTEST_CVS_UPDATE_OPTIONS.rst
@@ -0,0 +1,5 @@
+CTEST_CVS_UPDATE_OPTIONS
+------------------------
+
+Specify the CTest ``CVSUpdateOptions`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_DROP_LOCATION.rst b/Help/variable/CTEST_DROP_LOCATION.rst
new file mode 100644
index 000000000..c0f22158d
--- /dev/null
+++ b/Help/variable/CTEST_DROP_LOCATION.rst
@@ -0,0 +1,5 @@
+CTEST_DROP_LOCATION
+-------------------
+
+Specify the CTest ``DropLocation`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_DROP_METHOD.rst b/Help/variable/CTEST_DROP_METHOD.rst
new file mode 100644
index 000000000..50fbd4de9
--- /dev/null
+++ b/Help/variable/CTEST_DROP_METHOD.rst
@@ -0,0 +1,5 @@
+CTEST_DROP_METHOD
+-----------------
+
+Specify the CTest ``DropMethod`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_DROP_SITE.rst b/Help/variable/CTEST_DROP_SITE.rst
new file mode 100644
index 000000000..d15d99be2
--- /dev/null
+++ b/Help/variable/CTEST_DROP_SITE.rst
@@ -0,0 +1,5 @@
+CTEST_DROP_SITE
+---------------
+
+Specify the CTest ``DropSite`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_DROP_SITE_CDASH.rst b/Help/variable/CTEST_DROP_SITE_CDASH.rst
new file mode 100644
index 000000000..22b977632
--- /dev/null
+++ b/Help/variable/CTEST_DROP_SITE_CDASH.rst
@@ -0,0 +1,5 @@
+CTEST_DROP_SITE_CDASH
+---------------------
+
+Specify the CTest ``IsCDash`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_DROP_SITE_PASSWORD.rst b/Help/variable/CTEST_DROP_SITE_PASSWORD.rst
new file mode 100644
index 000000000..904d2c8a8
--- /dev/null
+++ b/Help/variable/CTEST_DROP_SITE_PASSWORD.rst
@@ -0,0 +1,5 @@
+CTEST_DROP_SITE_PASSWORD
+------------------------
+
+Specify the CTest ``DropSitePassword`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_DROP_SITE_USER.rst b/Help/variable/CTEST_DROP_SITE_USER.rst
new file mode 100644
index 000000000..a860a03fe
--- /dev/null
+++ b/Help/variable/CTEST_DROP_SITE_USER.rst
@@ -0,0 +1,5 @@
+CTEST_DROP_SITE_USER
+--------------------
+
+Specify the CTest ``DropSiteUser`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_EXTRA_COVERAGE_GLOB.rst b/Help/variable/CTEST_EXTRA_COVERAGE_GLOB.rst
new file mode 100644
index 000000000..286f7dfed
--- /dev/null
+++ b/Help/variable/CTEST_EXTRA_COVERAGE_GLOB.rst
@@ -0,0 +1,7 @@
+CTEST_EXTRA_COVERAGE_GLOB
+-------------------------
+
+A list of regular expressions which will be used to find files which should be
+covered by the :command:`ctest_coverage` command.
+
+.. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_GIT_COMMAND.rst b/Help/variable/CTEST_GIT_COMMAND.rst
new file mode 100644
index 000000000..eb83792ec
--- /dev/null
+++ b/Help/variable/CTEST_GIT_COMMAND.rst
@@ -0,0 +1,5 @@
+CTEST_GIT_COMMAND
+-----------------
+
+Specify the CTest ``GITCommand`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_GIT_UPDATE_CUSTOM.rst b/Help/variable/CTEST_GIT_UPDATE_CUSTOM.rst
new file mode 100644
index 000000000..0c479e604
--- /dev/null
+++ b/Help/variable/CTEST_GIT_UPDATE_CUSTOM.rst
@@ -0,0 +1,5 @@
+CTEST_GIT_UPDATE_CUSTOM
+-----------------------
+
+Specify the CTest ``GITUpdateCustom`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_GIT_UPDATE_OPTIONS.rst b/Help/variable/CTEST_GIT_UPDATE_OPTIONS.rst
new file mode 100644
index 000000000..4590a786d
--- /dev/null
+++ b/Help/variable/CTEST_GIT_UPDATE_OPTIONS.rst
@@ -0,0 +1,5 @@
+CTEST_GIT_UPDATE_OPTIONS
+------------------------
+
+Specify the CTest ``GITUpdateOptions`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_HG_COMMAND.rst b/Help/variable/CTEST_HG_COMMAND.rst
new file mode 100644
index 000000000..3854950af
--- /dev/null
+++ b/Help/variable/CTEST_HG_COMMAND.rst
@@ -0,0 +1,5 @@
+CTEST_HG_COMMAND
+----------------
+
+Specify the CTest ``HGCommand`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_HG_UPDATE_OPTIONS.rst b/Help/variable/CTEST_HG_UPDATE_OPTIONS.rst
new file mode 100644
index 000000000..9049c1f45
--- /dev/null
+++ b/Help/variable/CTEST_HG_UPDATE_OPTIONS.rst
@@ -0,0 +1,5 @@
+CTEST_HG_UPDATE_OPTIONS
+-----------------------
+
+Specify the CTest ``HGUpdateOptions`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_MEMORYCHECK_COMMAND.rst b/Help/variable/CTEST_MEMORYCHECK_COMMAND.rst
new file mode 100644
index 000000000..8c199bac2
--- /dev/null
+++ b/Help/variable/CTEST_MEMORYCHECK_COMMAND.rst
@@ -0,0 +1,5 @@
+CTEST_MEMORYCHECK_COMMAND
+-------------------------
+
+Specify the CTest ``MemoryCheckCommand`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_MEMORYCHECK_COMMAND_OPTIONS.rst b/Help/variable/CTEST_MEMORYCHECK_COMMAND_OPTIONS.rst
new file mode 100644
index 000000000..3e26ab515
--- /dev/null
+++ b/Help/variable/CTEST_MEMORYCHECK_COMMAND_OPTIONS.rst
@@ -0,0 +1,5 @@
+CTEST_MEMORYCHECK_COMMAND_OPTIONS
+---------------------------------
+
+Specify the CTest ``MemoryCheckCommandOptions`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_MEMORYCHECK_SANITIZER_OPTIONS.rst b/Help/variable/CTEST_MEMORYCHECK_SANITIZER_OPTIONS.rst
new file mode 100644
index 000000000..2de5fb6b8
--- /dev/null
+++ b/Help/variable/CTEST_MEMORYCHECK_SANITIZER_OPTIONS.rst
@@ -0,0 +1,5 @@
+CTEST_MEMORYCHECK_SANITIZER_OPTIONS
+-----------------------------------
+
+Specify the CTest ``MemoryCheckSanitizerOptions`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_MEMORYCHECK_SUPPRESSIONS_FILE.rst b/Help/variable/CTEST_MEMORYCHECK_SUPPRESSIONS_FILE.rst
new file mode 100644
index 000000000..1147ee8e8
--- /dev/null
+++ b/Help/variable/CTEST_MEMORYCHECK_SUPPRESSIONS_FILE.rst
@@ -0,0 +1,5 @@
+CTEST_MEMORYCHECK_SUPPRESSIONS_FILE
+-----------------------------------
+
+Specify the CTest ``MemoryCheckSuppressionFile`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_MEMORYCHECK_TYPE.rst b/Help/variable/CTEST_MEMORYCHECK_TYPE.rst
new file mode 100644
index 000000000..b96329354
--- /dev/null
+++ b/Help/variable/CTEST_MEMORYCHECK_TYPE.rst
@@ -0,0 +1,8 @@
+CTEST_MEMORYCHECK_TYPE
+----------------------
+
+Specify the CTest ``MemoryCheckType`` setting
+in a :manual:`ctest(1)` dashboard client script.
+Valid values are ``Valgrind``, ``Purify``, ``BoundsChecker``, and
+``ThreadSanitizer``, ``AddressSanitizer``, ``MemorySanitizer``, and
+``UndefinedBehaviorSanitizer``.
diff --git a/Help/variable/CTEST_NIGHTLY_START_TIME.rst b/Help/variable/CTEST_NIGHTLY_START_TIME.rst
new file mode 100644
index 000000000..bc802764e
--- /dev/null
+++ b/Help/variable/CTEST_NIGHTLY_START_TIME.rst
@@ -0,0 +1,5 @@
+CTEST_NIGHTLY_START_TIME
+------------------------
+
+Specify the CTest ``NightlyStartTime`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_P4_CLIENT.rst b/Help/variable/CTEST_P4_CLIENT.rst
new file mode 100644
index 000000000..347ea549e
--- /dev/null
+++ b/Help/variable/CTEST_P4_CLIENT.rst
@@ -0,0 +1,5 @@
+CTEST_P4_CLIENT
+---------------
+
+Specify the CTest ``P4Client`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_P4_COMMAND.rst b/Help/variable/CTEST_P4_COMMAND.rst
new file mode 100644
index 000000000..defab12be
--- /dev/null
+++ b/Help/variable/CTEST_P4_COMMAND.rst
@@ -0,0 +1,5 @@
+CTEST_P4_COMMAND
+----------------
+
+Specify the CTest ``P4Command`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_P4_OPTIONS.rst b/Help/variable/CTEST_P4_OPTIONS.rst
new file mode 100644
index 000000000..fee4ce2d8
--- /dev/null
+++ b/Help/variable/CTEST_P4_OPTIONS.rst
@@ -0,0 +1,5 @@
+CTEST_P4_OPTIONS
+----------------
+
+Specify the CTest ``P4Options`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_P4_UPDATE_OPTIONS.rst b/Help/variable/CTEST_P4_UPDATE_OPTIONS.rst
new file mode 100644
index 000000000..0e2790fb5
--- /dev/null
+++ b/Help/variable/CTEST_P4_UPDATE_OPTIONS.rst
@@ -0,0 +1,5 @@
+CTEST_P4_UPDATE_OPTIONS
+-----------------------
+
+Specify the CTest ``P4UpdateOptions`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_SCP_COMMAND.rst b/Help/variable/CTEST_SCP_COMMAND.rst
new file mode 100644
index 000000000..0f128b14a
--- /dev/null
+++ b/Help/variable/CTEST_SCP_COMMAND.rst
@@ -0,0 +1,5 @@
+CTEST_SCP_COMMAND
+-----------------
+
+Specify the CTest ``SCPCommand`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_SITE.rst b/Help/variable/CTEST_SITE.rst
new file mode 100644
index 000000000..8a5ec253d
--- /dev/null
+++ b/Help/variable/CTEST_SITE.rst
@@ -0,0 +1,5 @@
+CTEST_SITE
+----------
+
+Specify the CTest ``Site`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_SOURCE_DIRECTORY.rst b/Help/variable/CTEST_SOURCE_DIRECTORY.rst
new file mode 100644
index 000000000..b6837d1a0
--- /dev/null
+++ b/Help/variable/CTEST_SOURCE_DIRECTORY.rst
@@ -0,0 +1,5 @@
+CTEST_SOURCE_DIRECTORY
+----------------------
+
+Specify the CTest ``SourceDirectory`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_SVN_COMMAND.rst b/Help/variable/CTEST_SVN_COMMAND.rst
new file mode 100644
index 000000000..af9014361
--- /dev/null
+++ b/Help/variable/CTEST_SVN_COMMAND.rst
@@ -0,0 +1,5 @@
+CTEST_SVN_COMMAND
+-----------------
+
+Specify the CTest ``SVNCommand`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_SVN_OPTIONS.rst b/Help/variable/CTEST_SVN_OPTIONS.rst
new file mode 100644
index 000000000..76551dc11
--- /dev/null
+++ b/Help/variable/CTEST_SVN_OPTIONS.rst
@@ -0,0 +1,5 @@
+CTEST_SVN_OPTIONS
+-----------------
+
+Specify the CTest ``SVNOptions`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_SVN_UPDATE_OPTIONS.rst b/Help/variable/CTEST_SVN_UPDATE_OPTIONS.rst
new file mode 100644
index 000000000..5f01a193a
--- /dev/null
+++ b/Help/variable/CTEST_SVN_UPDATE_OPTIONS.rst
@@ -0,0 +1,5 @@
+CTEST_SVN_UPDATE_OPTIONS
+------------------------
+
+Specify the CTest ``SVNUpdateOptions`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_TEST_LOAD.rst b/Help/variable/CTEST_TEST_LOAD.rst
new file mode 100644
index 000000000..80823fe4e
--- /dev/null
+++ b/Help/variable/CTEST_TEST_LOAD.rst
@@ -0,0 +1,7 @@
+CTEST_TEST_LOAD
+---------------
+
+Specify the ``TestLoad`` setting in the :ref:`CTest Test Step`
+of a :manual:`ctest(1)` dashboard client script. This sets the
+default value for the ``TEST_LOAD`` option of the :command:`ctest_test`
+command.
diff --git a/Help/variable/CTEST_TEST_TIMEOUT.rst b/Help/variable/CTEST_TEST_TIMEOUT.rst
new file mode 100644
index 000000000..c031437f0
--- /dev/null
+++ b/Help/variable/CTEST_TEST_TIMEOUT.rst
@@ -0,0 +1,5 @@
+CTEST_TEST_TIMEOUT
+------------------
+
+Specify the CTest ``TimeOut`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_TRIGGER_SITE.rst b/Help/variable/CTEST_TRIGGER_SITE.rst
new file mode 100644
index 000000000..de9242807
--- /dev/null
+++ b/Help/variable/CTEST_TRIGGER_SITE.rst
@@ -0,0 +1,5 @@
+CTEST_TRIGGER_SITE
+------------------
+
+Specify the CTest ``TriggerSite`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_UPDATE_COMMAND.rst b/Help/variable/CTEST_UPDATE_COMMAND.rst
new file mode 100644
index 000000000..90155d07f
--- /dev/null
+++ b/Help/variable/CTEST_UPDATE_COMMAND.rst
@@ -0,0 +1,5 @@
+CTEST_UPDATE_COMMAND
+--------------------
+
+Specify the CTest ``UpdateCommand`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_UPDATE_OPTIONS.rst b/Help/variable/CTEST_UPDATE_OPTIONS.rst
new file mode 100644
index 000000000..e43d61d1c
--- /dev/null
+++ b/Help/variable/CTEST_UPDATE_OPTIONS.rst
@@ -0,0 +1,5 @@
+CTEST_UPDATE_OPTIONS
+--------------------
+
+Specify the CTest ``UpdateOptions`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_UPDATE_VERSION_ONLY.rst b/Help/variable/CTEST_UPDATE_VERSION_ONLY.rst
new file mode 100644
index 000000000..e646e6eea
--- /dev/null
+++ b/Help/variable/CTEST_UPDATE_VERSION_ONLY.rst
@@ -0,0 +1,5 @@
+CTEST_UPDATE_VERSION_ONLY
+-------------------------
+
+Specify the CTest ``UpdateVersionOnly`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_USE_LAUNCHERS.rst b/Help/variable/CTEST_USE_LAUNCHERS.rst
new file mode 100644
index 000000000..9f48a2e42
--- /dev/null
+++ b/Help/variable/CTEST_USE_LAUNCHERS.rst
@@ -0,0 +1,5 @@
+CTEST_USE_LAUNCHERS
+-------------------
+
+Specify the CTest ``UseLaunchers`` setting
+in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CYGWIN.rst b/Help/variable/CYGWIN.rst
new file mode 100644
index 000000000..0039e071f
--- /dev/null
+++ b/Help/variable/CYGWIN.rst
@@ -0,0 +1,6 @@
+CYGWIN
+------
+
+``True`` for Cygwin.
+
+Set to ``true`` when using Cygwin.
diff --git a/Help/variable/ENV.rst b/Help/variable/ENV.rst
new file mode 100644
index 000000000..368152aeb
--- /dev/null
+++ b/Help/variable/ENV.rst
@@ -0,0 +1,7 @@
+ENV
+---
+
+Access environment variables.
+
+Use the syntax ``$ENV{VAR}`` to read environment variable ``VAR``. See also
+the :command:`set` command to set ``ENV{VAR}``.
diff --git a/Help/variable/EXECUTABLE_OUTPUT_PATH.rst b/Help/variable/EXECUTABLE_OUTPUT_PATH.rst
new file mode 100644
index 000000000..26d3e92a1
--- /dev/null
+++ b/Help/variable/EXECUTABLE_OUTPUT_PATH.rst
@@ -0,0 +1,8 @@
+EXECUTABLE_OUTPUT_PATH
+----------------------
+
+Old executable location variable.
+
+The target property :prop_tgt:`RUNTIME_OUTPUT_DIRECTORY` supercedes this
+variable for a target if it is set. Executable targets are otherwise placed in
+this directory.
diff --git a/Help/variable/GHS-MULTI.rst b/Help/variable/GHS-MULTI.rst
new file mode 100644
index 000000000..0f91be8ad
--- /dev/null
+++ b/Help/variable/GHS-MULTI.rst
@@ -0,0 +1,4 @@
+GHS-MULTI
+---------
+
+True when using Green Hills MULTI
diff --git a/Help/variable/LIBRARY_OUTPUT_PATH.rst b/Help/variable/LIBRARY_OUTPUT_PATH.rst
new file mode 100644
index 000000000..ba02911e6
--- /dev/null
+++ b/Help/variable/LIBRARY_OUTPUT_PATH.rst
@@ -0,0 +1,9 @@
+LIBRARY_OUTPUT_PATH
+-------------------
+
+Old library location variable.
+
+The target properties :prop_tgt:`ARCHIVE_OUTPUT_DIRECTORY`,
+:prop_tgt:`LIBRARY_OUTPUT_DIRECTORY`, and :prop_tgt:`RUNTIME_OUTPUT_DIRECTORY`
+supercede this variable for a target if they are set. Library targets are
+otherwise placed in this directory.
diff --git a/Help/variable/MINGW.rst b/Help/variable/MINGW.rst
new file mode 100644
index 000000000..6d29be462
--- /dev/null
+++ b/Help/variable/MINGW.rst
@@ -0,0 +1,6 @@
+MINGW
+-----
+
+``True`` when using MinGW
+
+Set to ``true`` when the compiler is some version of MinGW.
diff --git a/Help/variable/MSVC.rst b/Help/variable/MSVC.rst
new file mode 100644
index 000000000..913ed080c
--- /dev/null
+++ b/Help/variable/MSVC.rst
@@ -0,0 +1,6 @@
+MSVC
+----
+
+``True`` when using Microsoft Visual C++.
+
+Set to ``true`` when the compiler is some version of Microsoft Visual C++.
diff --git a/Help/variable/MSVC10.rst b/Help/variable/MSVC10.rst
new file mode 100644
index 000000000..33692ad20
--- /dev/null
+++ b/Help/variable/MSVC10.rst
@@ -0,0 +1,6 @@
+MSVC10
+------
+
+``True`` when using Microsoft Visual C++ 10.0
+
+Set to ``true`` when the compiler is version 10.0 of Microsoft Visual C++.
diff --git a/Help/variable/MSVC11.rst b/Help/variable/MSVC11.rst
new file mode 100644
index 000000000..3ab606d41
--- /dev/null
+++ b/Help/variable/MSVC11.rst
@@ -0,0 +1,6 @@
+MSVC11
+------
+
+``True`` when using Microsoft Visual C++ 11.0
+
+Set to ``true`` when the compiler is version 11.0 of Microsoft Visual C++.
diff --git a/Help/variable/MSVC12.rst b/Help/variable/MSVC12.rst
new file mode 100644
index 000000000..15fa64b96
--- /dev/null
+++ b/Help/variable/MSVC12.rst
@@ -0,0 +1,6 @@
+MSVC12
+------
+
+``True`` when using Microsoft Visual C++ 12.0.
+
+Set to ``true`` when the compiler is version 12.0 of Microsoft Visual C++.
diff --git a/Help/variable/MSVC14.rst b/Help/variable/MSVC14.rst
new file mode 100644
index 000000000..0b9125de6
--- /dev/null
+++ b/Help/variable/MSVC14.rst
@@ -0,0 +1,6 @@
+MSVC14
+------
+
+``True`` when using Microsoft Visual C++ 14.0.
+
+Set to ``true`` when the compiler is version 14.0 of Microsoft Visual C++.
diff --git a/Help/variable/MSVC60.rst b/Help/variable/MSVC60.rst
new file mode 100644
index 000000000..14f09cfad
--- /dev/null
+++ b/Help/variable/MSVC60.rst
@@ -0,0 +1,6 @@
+MSVC60
+------
+
+``True`` when using Microsoft Visual C++ 6.0.
+
+Set to ``true`` when the compiler is version 6.0 of Microsoft Visual C++.
diff --git a/Help/variable/MSVC70.rst b/Help/variable/MSVC70.rst
new file mode 100644
index 000000000..76fa96fa9
--- /dev/null
+++ b/Help/variable/MSVC70.rst
@@ -0,0 +1,6 @@
+MSVC70
+------
+
+``True`` when using Microsoft Visual C++ 7.0.
+
+Set to ``true`` when the compiler is version 7.0 of Microsoft Visual C++.
diff --git a/Help/variable/MSVC71.rst b/Help/variable/MSVC71.rst
new file mode 100644
index 000000000..d69d4fc10
--- /dev/null
+++ b/Help/variable/MSVC71.rst
@@ -0,0 +1,6 @@
+MSVC71
+------
+
+``True`` when using Microsoft Visual C++ 7.1.
+
+Set to ``true`` when the compiler is version 7.1 of Microsoft Visual C++.
diff --git a/Help/variable/MSVC80.rst b/Help/variable/MSVC80.rst
new file mode 100644
index 000000000..b17777c79
--- /dev/null
+++ b/Help/variable/MSVC80.rst
@@ -0,0 +1,6 @@
+MSVC80
+------
+
+``True`` when using Microsoft Visual C++ 8.0.
+
+Set to ``true`` when the compiler is version 8.0 of Microsoft Visual C++.
diff --git a/Help/variable/MSVC90.rst b/Help/variable/MSVC90.rst
new file mode 100644
index 000000000..7162d6c4e
--- /dev/null
+++ b/Help/variable/MSVC90.rst
@@ -0,0 +1,6 @@
+MSVC90
+------
+
+``True`` when using Microsoft Visual C++ 9.0.
+
+Set to ``true`` when the compiler is version 9.0 of Microsoft Visual C++.
diff --git a/Help/variable/MSVC_IDE.rst b/Help/variable/MSVC_IDE.rst
new file mode 100644
index 000000000..027d1bc8c
--- /dev/null
+++ b/Help/variable/MSVC_IDE.rst
@@ -0,0 +1,7 @@
+MSVC_IDE
+--------
+
+``True`` when using the Microsoft Visual C++ IDE.
+
+Set to ``true`` when the target platform is the Microsoft Visual C++ IDE, as
+opposed to the command line compiler.
diff --git a/Help/variable/MSVC_VERSION.rst b/Help/variable/MSVC_VERSION.rst
new file mode 100644
index 000000000..ef3b0b558
--- /dev/null
+++ b/Help/variable/MSVC_VERSION.rst
@@ -0,0 +1,16 @@
+MSVC_VERSION
+------------
+
+The version of Microsoft Visual C/C++ being used if any.
+
+Known version numbers are::
+
+ 1200 = VS 6.0
+ 1300 = VS 7.0
+ 1310 = VS 7.1
+ 1400 = VS 8.0
+ 1500 = VS 9.0
+ 1600 = VS 10.0
+ 1700 = VS 11.0
+ 1800 = VS 12.0
+ 1900 = VS 14.0
diff --git a/Help/variable/PROJECT-NAME_BINARY_DIR.rst b/Help/variable/PROJECT-NAME_BINARY_DIR.rst
new file mode 100644
index 000000000..49bc55878
--- /dev/null
+++ b/Help/variable/PROJECT-NAME_BINARY_DIR.rst
@@ -0,0 +1,8 @@
+<PROJECT-NAME>_BINARY_DIR
+-------------------------
+
+Top level binary directory for the named project.
+
+A variable is created with the name used in the :command:`project` command,
+and is the binary directory for the project. This can be useful when
+:command:`add_subdirectory` is used to connect several projects.
diff --git a/Help/variable/PROJECT-NAME_SOURCE_DIR.rst b/Help/variable/PROJECT-NAME_SOURCE_DIR.rst
new file mode 100644
index 000000000..4df3e223c
--- /dev/null
+++ b/Help/variable/PROJECT-NAME_SOURCE_DIR.rst
@@ -0,0 +1,8 @@
+<PROJECT-NAME>_SOURCE_DIR
+-------------------------
+
+Top level source directory for the named project.
+
+A variable is created with the name used in the :command:`project` command,
+and is the source directory for the project. This can be useful when
+:command:`add_subdirectory` is used to connect several projects.
diff --git a/Help/variable/PROJECT-NAME_VERSION.rst b/Help/variable/PROJECT-NAME_VERSION.rst
new file mode 100644
index 000000000..0f6ed514b
--- /dev/null
+++ b/Help/variable/PROJECT-NAME_VERSION.rst
@@ -0,0 +1,11 @@
+<PROJECT-NAME>_VERSION
+----------------------
+
+Value given to the ``VERSION`` option of the most recent call to the
+:command:`project` command with project name ``<PROJECT-NAME>``, if any.
+
+See also the component-wise version variables
+:variable:`<PROJECT-NAME>_VERSION_MAJOR`,
+:variable:`<PROJECT-NAME>_VERSION_MINOR`,
+:variable:`<PROJECT-NAME>_VERSION_PATCH`, and
+:variable:`<PROJECT-NAME>_VERSION_TWEAK`.
diff --git a/Help/variable/PROJECT-NAME_VERSION_MAJOR.rst b/Help/variable/PROJECT-NAME_VERSION_MAJOR.rst
new file mode 100644
index 000000000..9e2d755a6
--- /dev/null
+++ b/Help/variable/PROJECT-NAME_VERSION_MAJOR.rst
@@ -0,0 +1,5 @@
+<PROJECT-NAME>_VERSION_MAJOR
+----------------------------
+
+First version number component of the :variable:`<PROJECT-NAME>_VERSION`
+variable as set by the :command:`project` command.
diff --git a/Help/variable/PROJECT-NAME_VERSION_MINOR.rst b/Help/variable/PROJECT-NAME_VERSION_MINOR.rst
new file mode 100644
index 000000000..fa2cdab58
--- /dev/null
+++ b/Help/variable/PROJECT-NAME_VERSION_MINOR.rst
@@ -0,0 +1,5 @@
+<PROJECT-NAME>_VERSION_MINOR
+----------------------------
+
+Second version number component of the :variable:`<PROJECT-NAME>_VERSION`
+variable as set by the :command:`project` command.
diff --git a/Help/variable/PROJECT-NAME_VERSION_PATCH.rst b/Help/variable/PROJECT-NAME_VERSION_PATCH.rst
new file mode 100644
index 000000000..85b5e6bdb
--- /dev/null
+++ b/Help/variable/PROJECT-NAME_VERSION_PATCH.rst
@@ -0,0 +1,5 @@
+<PROJECT-NAME>_VERSION_PATCH
+----------------------------
+
+Third version number component of the :variable:`<PROJECT-NAME>_VERSION`
+variable as set by the :command:`project` command.
diff --git a/Help/variable/PROJECT-NAME_VERSION_TWEAK.rst b/Help/variable/PROJECT-NAME_VERSION_TWEAK.rst
new file mode 100644
index 000000000..65c404482
--- /dev/null
+++ b/Help/variable/PROJECT-NAME_VERSION_TWEAK.rst
@@ -0,0 +1,5 @@
+<PROJECT-NAME>_VERSION_TWEAK
+----------------------------
+
+Fourth version number component of the :variable:`<PROJECT-NAME>_VERSION`
+variable as set by the :command:`project` command.
diff --git a/Help/variable/PROJECT_BINARY_DIR.rst b/Help/variable/PROJECT_BINARY_DIR.rst
new file mode 100644
index 000000000..09e9ef218
--- /dev/null
+++ b/Help/variable/PROJECT_BINARY_DIR.rst
@@ -0,0 +1,6 @@
+PROJECT_BINARY_DIR
+------------------
+
+Full path to build directory for project.
+
+This is the binary directory of the most recent :command:`project` command.
diff --git a/Help/variable/PROJECT_NAME.rst b/Help/variable/PROJECT_NAME.rst
new file mode 100644
index 000000000..61aa8bc00
--- /dev/null
+++ b/Help/variable/PROJECT_NAME.rst
@@ -0,0 +1,6 @@
+PROJECT_NAME
+------------
+
+Name of the project given to the project command.
+
+This is the name given to the most recent :command:`project` command.
diff --git a/Help/variable/PROJECT_SOURCE_DIR.rst b/Help/variable/PROJECT_SOURCE_DIR.rst
new file mode 100644
index 000000000..27f2838ee
--- /dev/null
+++ b/Help/variable/PROJECT_SOURCE_DIR.rst
@@ -0,0 +1,6 @@
+PROJECT_SOURCE_DIR
+------------------
+
+Top level source directory for the current project.
+
+This is the source directory of the most recent :command:`project` command.
diff --git a/Help/variable/PROJECT_VERSION.rst b/Help/variable/PROJECT_VERSION.rst
new file mode 100644
index 000000000..234558dbd
--- /dev/null
+++ b/Help/variable/PROJECT_VERSION.rst
@@ -0,0 +1,11 @@
+PROJECT_VERSION
+---------------
+
+Value given to the ``VERSION`` option of the most recent call to the
+:command:`project` command, if any.
+
+See also the component-wise version variables
+:variable:`PROJECT_VERSION_MAJOR`,
+:variable:`PROJECT_VERSION_MINOR`,
+:variable:`PROJECT_VERSION_PATCH`, and
+:variable:`PROJECT_VERSION_TWEAK`.
diff --git a/Help/variable/PROJECT_VERSION_MAJOR.rst b/Help/variable/PROJECT_VERSION_MAJOR.rst
new file mode 100644
index 000000000..4b6072c54
--- /dev/null
+++ b/Help/variable/PROJECT_VERSION_MAJOR.rst
@@ -0,0 +1,5 @@
+PROJECT_VERSION_MAJOR
+---------------------
+
+First version number component of the :variable:`PROJECT_VERSION`
+variable as set by the :command:`project` command.
diff --git a/Help/variable/PROJECT_VERSION_MINOR.rst b/Help/variable/PROJECT_VERSION_MINOR.rst
new file mode 100644
index 000000000..5f31220f4
--- /dev/null
+++ b/Help/variable/PROJECT_VERSION_MINOR.rst
@@ -0,0 +1,5 @@
+PROJECT_VERSION_MINOR
+---------------------
+
+Second version number component of the :variable:`PROJECT_VERSION`
+variable as set by the :command:`project` command.
diff --git a/Help/variable/PROJECT_VERSION_PATCH.rst b/Help/variable/PROJECT_VERSION_PATCH.rst
new file mode 100644
index 000000000..ac72ec051
--- /dev/null
+++ b/Help/variable/PROJECT_VERSION_PATCH.rst
@@ -0,0 +1,5 @@
+PROJECT_VERSION_PATCH
+---------------------
+
+Third version number component of the :variable:`PROJECT_VERSION`
+variable as set by the :command:`project` command.
diff --git a/Help/variable/PROJECT_VERSION_TWEAK.rst b/Help/variable/PROJECT_VERSION_TWEAK.rst
new file mode 100644
index 000000000..d7f96d6ce
--- /dev/null
+++ b/Help/variable/PROJECT_VERSION_TWEAK.rst
@@ -0,0 +1,5 @@
+PROJECT_VERSION_TWEAK
+---------------------
+
+Fourth version number component of the :variable:`PROJECT_VERSION`
+variable as set by the :command:`project` command.
diff --git a/Help/variable/UNIX.rst b/Help/variable/UNIX.rst
new file mode 100644
index 000000000..0877b7c07
--- /dev/null
+++ b/Help/variable/UNIX.rst
@@ -0,0 +1,7 @@
+UNIX
+----
+
+``True`` for UNIX and UNIX like operating systems.
+
+Set to ``true`` when the target system is UNIX or UNIX like (i.e.
+:variable:`APPLE` and :variable:`CYGWIN`).
diff --git a/Help/variable/WIN32.rst b/Help/variable/WIN32.rst
new file mode 100644
index 000000000..218906955
--- /dev/null
+++ b/Help/variable/WIN32.rst
@@ -0,0 +1,6 @@
+WIN32
+-----
+
+``True`` on Windows systems, including Win64.
+
+Set to ``true`` when the target system is Windows.
diff --git a/Help/variable/WINCE.rst b/Help/variable/WINCE.rst
new file mode 100644
index 000000000..54ff7dee2
--- /dev/null
+++ b/Help/variable/WINCE.rst
@@ -0,0 +1,5 @@
+WINCE
+-----
+
+True when the :variable:`CMAKE_SYSTEM_NAME` variable is set
+to ``WindowsCE``.
diff --git a/Help/variable/WINDOWS_PHONE.rst b/Help/variable/WINDOWS_PHONE.rst
new file mode 100644
index 000000000..61d91b00a
--- /dev/null
+++ b/Help/variable/WINDOWS_PHONE.rst
@@ -0,0 +1,5 @@
+WINDOWS_PHONE
+-------------
+
+True when the :variable:`CMAKE_SYSTEM_NAME` variable is set
+to ``WindowsPhone``.
diff --git a/Help/variable/WINDOWS_STORE.rst b/Help/variable/WINDOWS_STORE.rst
new file mode 100644
index 000000000..dae3b539b
--- /dev/null
+++ b/Help/variable/WINDOWS_STORE.rst
@@ -0,0 +1,5 @@
+WINDOWS_STORE
+-------------
+
+True when the :variable:`CMAKE_SYSTEM_NAME` variable is set
+to ``WindowsStore``.
diff --git a/Help/variable/XCODE_VERSION.rst b/Help/variable/XCODE_VERSION.rst
new file mode 100644
index 000000000..b85d41e91
--- /dev/null
+++ b/Help/variable/XCODE_VERSION.rst
@@ -0,0 +1,7 @@
+XCODE_VERSION
+-------------
+
+Version of Xcode (:generator:`Xcode` generator only).
+
+Under the Xcode generator, this is the version of Xcode as specified
+in ``Xcode.app/Contents/version.plist`` (such as ``3.1.2``).
diff --git a/Licenses/LGPLv2.1.txt b/Licenses/LGPLv2.1.txt
new file mode 100644
index 000000000..4362b4915
--- /dev/null
+++ b/Licenses/LGPLv2.1.txt
@@ -0,0 +1,502 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/Licenses/README.rst b/Licenses/README.rst
new file mode 100644
index 000000000..e798f7821
--- /dev/null
+++ b/Licenses/README.rst
@@ -0,0 +1,7 @@
+Licenses
+========
+
+The CMake source tree is distributed under terms of the BSD 3-Clause license.
+
+This directory contains other license files that need to be packaged with
+binary distributions when certain third-party libraries are included.
diff --git a/Modules/AddFileDependencies.cmake b/Modules/AddFileDependencies.cmake
index e88025c14..4d01a526c 100644
--- a/Modules/AddFileDependencies.cmake
+++ b/Modules/AddFileDependencies.cmake
@@ -1,6 +1,10 @@
-# - ADD_FILE_DEPENDENCIES(source_file depend_files...)
-# Adds the given files as dependencies to source_file
+#.rst:
+# AddFileDependencies
+# -------------------
+#
+# ADD_FILE_DEPENDENCIES(source_file depend_files...)
#
+# Adds the given files as dependencies to source_file
#=============================================================================
# Copyright 2006-2009 Kitware, Inc.
diff --git a/Modules/AutogenInfo.cmake.in b/Modules/AutogenInfo.cmake.in
new file mode 100644
index 000000000..7d894202e
--- /dev/null
+++ b/Modules/AutogenInfo.cmake.in
@@ -0,0 +1,26 @@
+set(AM_SOURCES @_cpp_files@ )
+set(AM_RCC_SOURCES @_rcc_files@ )
+set(AM_RCC_INPUTS @_qt_rcc_inputs@)
+set(AM_SKIP_MOC @_skip_moc@ )
+set(AM_SKIP_UIC @_skip_uic@ )
+set(AM_HEADERS @_moc_headers@ )
+set(AM_MOC_COMPILE_DEFINITIONS @_moc_compile_defs@)
+set(AM_MOC_INCLUDES @_moc_incs@)
+set(AM_MOC_OPTIONS @_moc_options@)
+set(AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE "@CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE@")
+set(AM_CMAKE_BINARY_DIR "@CMAKE_BINARY_DIR@/")
+set(AM_CMAKE_SOURCE_DIR "@CMAKE_SOURCE_DIR@/")
+set(AM_QT_MOC_EXECUTABLE "@_qt_moc_executable@")
+set(AM_QT_UIC_EXECUTABLE "@_qt_uic_executable@")
+set(AM_QT_RCC_EXECUTABLE "@_qt_rcc_executable@")
+set(AM_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@/")
+set(AM_CMAKE_CURRENT_BINARY_DIR "@CMAKE_CURRENT_BINARY_DIR@/")
+set(AM_QT_VERSION_MAJOR "@_target_qt_version@")
+set(AM_TARGET_NAME @_moc_target_name@)
+set(AM_ORIGIN_TARGET_NAME @_origin_target_name@)
+set(AM_RELAXED_MODE "@_moc_relaxed_mode@")
+set(AM_UIC_TARGET_OPTIONS @_uic_target_options@)
+set(AM_UIC_OPTIONS_FILES @_qt_uic_options_files@)
+set(AM_UIC_OPTIONS_OPTIONS @_qt_uic_options_options@)
+set(AM_RCC_OPTIONS_FILES @_qt_rcc_options_files@)
+set(AM_RCC_OPTIONS_OPTIONS @_qt_rcc_options_options@)
diff --git a/Modules/AutomocInfo.cmake.in b/Modules/AutomocInfo.cmake.in
deleted file mode 100644
index 9cff735fb..000000000
--- a/Modules/AutomocInfo.cmake.in
+++ /dev/null
@@ -1,14 +0,0 @@
-set(AM_SOURCES @_moc_files@ )
-set(AM_HEADERS @_moc_headers@ )
-set(AM_MOC_COMPILE_DEFINITIONS @_moc_compile_defs@)
-set(AM_MOC_INCLUDES @_moc_incs@)
-set(AM_MOC_OPTIONS @_moc_options@)
-set(AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE "@CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE@")
-set(AM_CMAKE_BINARY_DIR "@CMAKE_BINARY_DIR@/")
-set(AM_CMAKE_SOURCE_DIR "@CMAKE_SOURCE_DIR@/")
-set(AM_QT_MOC_EXECUTABLE "@_qt_moc_executable@")
-set(AM_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@/")
-set(AM_CMAKE_CURRENT_BINARY_DIR "@CMAKE_CURRENT_BINARY_DIR@/")
-set(AM_QT_VERSION_MAJOR "@_target_qt_version@")
-set(AM_TARGET_NAME @_moc_target_name@)
-set(AM_RELAXED_MODE "@_moc_relaxed_mode@")
diff --git a/Modules/BasicConfigVersion-AnyNewerVersion.cmake.in b/Modules/BasicConfigVersion-AnyNewerVersion.cmake.in
index b1c4fdf81..bc78016df 100644
--- a/Modules/BasicConfigVersion-AnyNewerVersion.cmake.in
+++ b/Modules/BasicConfigVersion-AnyNewerVersion.cmake.in
@@ -9,22 +9,22 @@
set(PACKAGE_VERSION "@CVF_VERSION@")
-if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
+if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
set(PACKAGE_VERSION_COMPATIBLE TRUE)
- if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
+ if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
set(PACKAGE_VERSION_EXACT TRUE)
endif()
endif()
# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
-if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "")
+if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "")
return()
endif()
# check that the installed version has the same 32/64bit-ness as the one which is currently searching:
-if(NOT "${CMAKE_SIZEOF_VOID_P}" STREQUAL "@CMAKE_SIZEOF_VOID_P@")
+if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "@CMAKE_SIZEOF_VOID_P@")
math(EXPR installedBits "@CMAKE_SIZEOF_VOID_P@ * 8")
set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
set(PACKAGE_VERSION_UNSUITABLE TRUE)
diff --git a/Modules/BasicConfigVersion-ExactVersion.cmake.in b/Modules/BasicConfigVersion-ExactVersion.cmake.in
index 63f3f0339..de4a23af0 100644
--- a/Modules/BasicConfigVersion-ExactVersion.cmake.in
+++ b/Modules/BasicConfigVersion-ExactVersion.cmake.in
@@ -11,36 +11,36 @@
set(PACKAGE_VERSION "@CVF_VERSION@")
-if("@CVF_VERSION@" MATCHES "^([0-9]+\\.[0-9]+\\.[0-9]+)\\..*") # strip the tweak version
+if("@CVF_VERSION@" MATCHES "^([0-9]+\\.[0-9]+\\.[0-9]+)\\.") # strip the tweak version
set(CVF_VERSION_NO_TWEAK "${CMAKE_MATCH_1}")
else()
set(CVF_VERSION_NO_TWEAK "@CVF_VERSION@")
endif()
-if("${PACKAGE_FIND_VERSION}" MATCHES "^([0-9]+\\.[0-9]+\\.[0-9]+)\\..*") # strip the tweak version
+if(PACKAGE_FIND_VERSION MATCHES "^([0-9]+\\.[0-9]+\\.[0-9]+)\\.") # strip the tweak version
set(REQUESTED_VERSION_NO_TWEAK "${CMAKE_MATCH_1}")
else()
set(REQUESTED_VERSION_NO_TWEAK "${PACKAGE_FIND_VERSION}")
endif()
-if("${REQUESTED_VERSION_NO_TWEAK}" STREQUAL "${CVF_VERSION_NO_TWEAK}")
+if(REQUESTED_VERSION_NO_TWEAK STREQUAL CVF_VERSION_NO_TWEAK)
set(PACKAGE_VERSION_COMPATIBLE TRUE)
else()
set(PACKAGE_VERSION_COMPATIBLE FALSE)
endif()
-if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
+if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
set(PACKAGE_VERSION_EXACT TRUE)
endif()
# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
-if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "")
+if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "")
return()
endif()
# check that the installed version has the same 32/64bit-ness as the one which is currently searching:
-if(NOT "${CMAKE_SIZEOF_VOID_P}" STREQUAL "@CMAKE_SIZEOF_VOID_P@")
+if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "@CMAKE_SIZEOF_VOID_P@")
math(EXPR installedBits "@CMAKE_SIZEOF_VOID_P@ * 8")
set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
set(PACKAGE_VERSION_UNSUITABLE TRUE)
diff --git a/Modules/BasicConfigVersion-SameMajorVersion.cmake.in b/Modules/BasicConfigVersion-SameMajorVersion.cmake.in
index 4acd9bb5e..a32245dd5 100644
--- a/Modules/BasicConfigVersion-SameMajorVersion.cmake.in
+++ b/Modules/BasicConfigVersion-SameMajorVersion.cmake.in
@@ -11,7 +11,7 @@
set(PACKAGE_VERSION "@CVF_VERSION@")
-if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
+if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
@@ -21,25 +21,25 @@ else()
set(CVF_VERSION_MAJOR "@CVF_VERSION@")
endif()
- if("${PACKAGE_FIND_VERSION_MAJOR}" STREQUAL "${CVF_VERSION_MAJOR}")
+ if(PACKAGE_FIND_VERSION_MAJOR STREQUAL CVF_VERSION_MAJOR)
set(PACKAGE_VERSION_COMPATIBLE TRUE)
else()
set(PACKAGE_VERSION_COMPATIBLE FALSE)
endif()
- if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
+ if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
set(PACKAGE_VERSION_EXACT TRUE)
endif()
endif()
# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
-if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "")
+if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "")
return()
endif()
# check that the installed version has the same 32/64bit-ness as the one which is currently searching:
-if(NOT "${CMAKE_SIZEOF_VOID_P}" STREQUAL "@CMAKE_SIZEOF_VOID_P@")
+if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "@CMAKE_SIZEOF_VOID_P@")
math(EXPR installedBits "@CMAKE_SIZEOF_VOID_P@ * 8")
set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
set(PACKAGE_VERSION_UNSUITABLE TRUE)
diff --git a/Modules/BundleUtilities.cmake b/Modules/BundleUtilities.cmake
index 0f6cd059e..45dda40c8 100644
--- a/Modules/BundleUtilities.cmake
+++ b/Modules/BundleUtilities.cmake
@@ -1,146 +1,208 @@
-# - Functions to help assemble a standalone bundle application.
+#.rst:
+# BundleUtilities
+# ---------------
+#
+# Functions to help assemble a standalone bundle application.
+#
# A collection of CMake utility functions useful for dealing with .app
# bundles on the Mac and bundle-like directories on any OS.
#
# The following functions are provided by this module:
-# fixup_bundle
-# copy_and_fixup_bundle
-# verify_app
-# get_bundle_main_executable
-# get_dotapp_dir
-# get_bundle_and_executable
-# get_bundle_all_executables
-# get_item_key
-# clear_bundle_keys
-# set_bundle_key_values
-# get_bundle_keys
-# copy_resolved_item_into_bundle
-# copy_resolved_framework_into_bundle
-# fixup_bundle_item
-# verify_bundle_prerequisites
-# verify_bundle_symlinks
+#
+# ::
+#
+# fixup_bundle
+# copy_and_fixup_bundle
+# verify_app
+# get_bundle_main_executable
+# get_dotapp_dir
+# get_bundle_and_executable
+# get_bundle_all_executables
+# get_item_key
+# get_item_rpaths
+# clear_bundle_keys
+# set_bundle_key_values
+# get_bundle_keys
+# copy_resolved_item_into_bundle
+# copy_resolved_framework_into_bundle
+# fixup_bundle_item
+# verify_bundle_prerequisites
+# verify_bundle_symlinks
+#
# Requires CMake 2.6 or greater because it uses function, break and
-# PARENT_SCOPE. Also depends on GetPrerequisites.cmake.
+# PARENT_SCOPE. Also depends on GetPrerequisites.cmake.
+#
+# ::
+#
+# FIXUP_BUNDLE(<app> <libs> <dirs>)
#
-# FIXUP_BUNDLE(<app> <libs> <dirs>)
# Fix up a bundle in-place and make it standalone, such that it can be
-# drag-n-drop copied to another machine and run on that machine as long as all
-# of the system libraries are compatible.
+# drag-n-drop copied to another machine and run on that machine as long
+# as all of the system libraries are compatible.
+#
+# If you pass plugins to fixup_bundle as the libs parameter, you should
+# install them or copy them into the bundle before calling fixup_bundle.
+# The "libs" parameter is a list of libraries that must be fixed up, but
+# that cannot be determined by otool output analysis. (i.e., plugins)
+#
+# Gather all the keys for all the executables and libraries in a bundle,
+# and then, for each key, copy each prerequisite into the bundle. Then
+# fix each one up according to its own list of prerequisites.
+#
+# Then clear all the keys and call verify_app on the final bundle to
+# ensure that it is truly standalone.
+#
+# ::
+#
+# COPY_AND_FIXUP_BUNDLE(<src> <dst> <libs> <dirs>)
#
-# If you pass plugins to fixup_bundle as the libs parameter, you should install
-# them or copy them into the bundle before calling fixup_bundle. The "libs"
-# parameter is a list of libraries that must be fixed up, but that cannot be
-# determined by otool output analysis. (i.e., plugins)
+# Makes a copy of the bundle <src> at location <dst> and then fixes up
+# the new copied bundle in-place at <dst>...
#
-# Gather all the keys for all the executables and libraries in a bundle, and
-# then, for each key, copy each prerequisite into the bundle. Then fix each one
-# up according to its own list of prerequisites.
+# ::
#
-# Then clear all the keys and call verify_app on the final bundle to ensure
-# that it is truly standalone.
+# VERIFY_APP(<app>)
#
-# COPY_AND_FIXUP_BUNDLE(<src> <dst> <libs> <dirs>)
-# Makes a copy of the bundle <src> at location <dst> and then fixes up the
-# new copied bundle in-place at <dst>...
+# Verifies that an application <app> appears valid based on running
+# analysis tools on it. Calls "message(FATAL_ERROR" if the application
+# is not verified.
#
-# VERIFY_APP(<app>)
-# Verifies that an application <app> appears valid based on running analysis
-# tools on it. Calls "message(FATAL_ERROR" if the application is not verified.
+# ::
#
-# GET_BUNDLE_MAIN_EXECUTABLE(<bundle> <result_var>)
-# The result will be the full path name of the bundle's main executable file
-# or an "error:" prefixed string if it could not be determined.
+# GET_BUNDLE_MAIN_EXECUTABLE(<bundle> <result_var>)
#
-# GET_DOTAPP_DIR(<exe> <dotapp_dir_var>)
-# Returns the nearest parent dir whose name ends with ".app" given the full
-# path to an executable. If there is no such parent dir, then simply return
-# the dir containing the executable.
+# The result will be the full path name of the bundle's main executable
+# file or an "error:" prefixed string if it could not be determined.
+#
+# ::
+#
+# GET_DOTAPP_DIR(<exe> <dotapp_dir_var>)
+#
+# Returns the nearest parent dir whose name ends with ".app" given the
+# full path to an executable. If there is no such parent dir, then
+# simply return the dir containing the executable.
#
# The returned directory may or may not exist.
#
-# GET_BUNDLE_AND_EXECUTABLE(<app> <bundle_var> <executable_var> <valid_var>)
+# ::
+#
+# GET_BUNDLE_AND_EXECUTABLE(<app> <bundle_var> <executable_var> <valid_var>)
+#
# Takes either a ".app" directory name or the name of an executable
# nested inside a ".app" directory and returns the path to the ".app"
# directory in <bundle_var> and the path to its main executable in
# <executable_var>
#
-# GET_BUNDLE_ALL_EXECUTABLES(<bundle> <exes_var>)
-# Scans the given bundle recursively for all executable files and accumulates
-# them into a variable.
+# ::
+#
+# GET_BUNDLE_ALL_EXECUTABLES(<bundle> <exes_var>)
+#
+# Scans the given bundle recursively for all executable files and
+# accumulates them into a variable.
+#
+# ::
+#
+# GET_ITEM_KEY(<item> <key_var>)
+#
+# Given a file (item) name, generate a key that should be unique
+# considering the set of libraries that need copying or fixing up to
+# make a bundle standalone. This is essentially the file name including
+# extension with "." replaced by "_"
+#
+# This key is used as a prefix for CMake variables so that we can
+# associate a set of variables with a given item based on its key.
#
-# GET_ITEM_KEY(<item> <key_var>)
-# Given a file (item) name, generate a key that should be unique considering
-# the set of libraries that need copying or fixing up to make a bundle
-# standalone. This is essentially the file name including extension with "."
-# replaced by "_"
+# ::
#
-# This key is used as a prefix for CMake variables so that we can associate a
-# set of variables with a given item based on its key.
+# CLEAR_BUNDLE_KEYS(<keys_var>)
#
-# CLEAR_BUNDLE_KEYS(<keys_var>)
-# Loop over the list of keys, clearing all the variables associated with each
-# key. After the loop, clear the list of keys itself.
+# Loop over the list of keys, clearing all the variables associated with
+# each key. After the loop, clear the list of keys itself.
#
-# Caller of get_bundle_keys should call clear_bundle_keys when done with list
-# of keys.
+# Caller of get_bundle_keys should call clear_bundle_keys when done with
+# list of keys.
#
-# SET_BUNDLE_KEY_VALUES(<keys_var> <context> <item> <exepath> <dirs>
-# <copyflag>)
-# Add a key to the list (if necessary) for the given item. If added,
+# ::
+#
+# SET_BUNDLE_KEY_VALUES(<keys_var> <context> <item> <exepath> <dirs>
+# <copyflag> [<rpaths>])
+#
+# Add a key to the list (if necessary) for the given item. If added,
# also set all the variables associated with that key.
#
-# GET_BUNDLE_KEYS(<app> <libs> <dirs> <keys_var>)
-# Loop over all the executable and library files within the bundle (and given
-# as extra <libs>) and accumulate a list of keys representing them. Set
-# values associated with each key such that we can loop over all of them and
-# copy prerequisite libs into the bundle and then do appropriate
-# install_name_tool fixups.
-#
-# COPY_RESOLVED_ITEM_INTO_BUNDLE(<resolved_item> <resolved_embedded_item>)
-# Copy a resolved item into the bundle if necessary. Copy is not necessary if
-# the resolved_item is "the same as" the resolved_embedded_item.
-#
-# COPY_RESOLVED_FRAMEWORK_INTO_BUNDLE(<resolved_item> <resolved_embedded_item>)
-# Copy a resolved framework into the bundle if necessary. Copy is not necessary
-# if the resolved_item is "the same as" the resolved_embedded_item.
-#
-# By default, BU_COPY_FULL_FRAMEWORK_CONTENTS is not set. If you want full
-# frameworks embedded in your bundles, set BU_COPY_FULL_FRAMEWORK_CONTENTS to
-# ON before calling fixup_bundle. By default,
-# COPY_RESOLVED_FRAMEWORK_INTO_BUNDLE copies the framework dylib itself plus
-# the framework Resources directory.
-#
-# FIXUP_BUNDLE_ITEM(<resolved_embedded_item> <exepath> <dirs>)
-# Get the direct/non-system prerequisites of the resolved embedded item. For
-# each prerequisite, change the way it is referenced to the value of the
-# _EMBEDDED_ITEM keyed variable for that prerequisite. (Most likely changing to
-# an "@executable_path" style reference.)
-#
-# This function requires that the resolved_embedded_item be "inside" the bundle
-# already. In other words, if you pass plugins to fixup_bundle as the libs
-# parameter, you should install them or copy them into the bundle before
-# calling fixup_bundle. The "libs" parameter is a list of libraries that must
-# be fixed up, but that cannot be determined by otool output analysis. (i.e.,
-# plugins)
-#
-# Also, change the id of the item being fixed up to its own _EMBEDDED_ITEM
-# value.
+# ::
+#
+# GET_BUNDLE_KEYS(<app> <libs> <dirs> <keys_var>)
+#
+# Loop over all the executable and library files within the bundle (and
+# given as extra <libs>) and accumulate a list of keys representing
+# them. Set values associated with each key such that we can loop over
+# all of them and copy prerequisite libs into the bundle and then do
+# appropriate install_name_tool fixups.
+#
+# ::
+#
+# COPY_RESOLVED_ITEM_INTO_BUNDLE(<resolved_item> <resolved_embedded_item>)
+#
+# Copy a resolved item into the bundle if necessary. Copy is not
+# necessary if the resolved_item is "the same as" the
+# resolved_embedded_item.
+#
+# ::
+#
+# COPY_RESOLVED_FRAMEWORK_INTO_BUNDLE(<resolved_item> <resolved_embedded_item>)
+#
+# Copy a resolved framework into the bundle if necessary. Copy is not
+# necessary if the resolved_item is "the same as" the
+# resolved_embedded_item.
+#
+# By default, BU_COPY_FULL_FRAMEWORK_CONTENTS is not set. If you want
+# full frameworks embedded in your bundles, set
+# BU_COPY_FULL_FRAMEWORK_CONTENTS to ON before calling fixup_bundle. By
+# default, COPY_RESOLVED_FRAMEWORK_INTO_BUNDLE copies the framework
+# dylib itself plus the framework Resources directory.
+#
+# ::
+#
+# FIXUP_BUNDLE_ITEM(<resolved_embedded_item> <exepath> <dirs>)
+#
+# Get the direct/non-system prerequisites of the resolved embedded item.
+# For each prerequisite, change the way it is referenced to the value of
+# the _EMBEDDED_ITEM keyed variable for that prerequisite. (Most likely
+# changing to an "@executable_path" style reference.)
+#
+# This function requires that the resolved_embedded_item be "inside" the
+# bundle already. In other words, if you pass plugins to fixup_bundle
+# as the libs parameter, you should install them or copy them into the
+# bundle before calling fixup_bundle. The "libs" parameter is a list of
+# libraries that must be fixed up, but that cannot be determined by
+# otool output analysis. (i.e., plugins)
+#
+# Also, change the id of the item being fixed up to its own
+# _EMBEDDED_ITEM value.
#
# Accumulate changes in a local variable and make *one* call to
-# install_name_tool at the end of the function with all the changes at once.
+# install_name_tool at the end of the function with all the changes at
+# once.
#
# If the BU_CHMOD_BUNDLE_ITEMS variable is set then bundle items will be
# marked writable before install_name_tool tries to change them.
#
-# VERIFY_BUNDLE_PREREQUISITES(<bundle> <result_var> <info_var>)
-# Verifies that the sum of all prerequisites of all files inside the bundle
-# are contained within the bundle or are "system" libraries, presumed to exist
-# everywhere.
+# ::
+#
+# VERIFY_BUNDLE_PREREQUISITES(<bundle> <result_var> <info_var>)
+#
+# Verifies that the sum of all prerequisites of all files inside the
+# bundle are contained within the bundle or are "system" libraries,
+# presumed to exist everywhere.
#
-# VERIFY_BUNDLE_SYMLINKS(<bundle> <result_var> <info_var>)
-# Verifies that any symlinks found in the bundle point to other files that are
-# already also in the bundle... Anything that points to an external file causes
-# this function to fail the verification.
+# ::
+#
+# VERIFY_BUNDLE_SYMLINKS(<bundle> <result_var> <info_var>)
+#
+# Verifies that any symlinks found in the bundle point to other files
+# that are already also in the bundle... Anything that points to an
+# external file causes this function to fail the verification.
#=============================================================================
# Copyright 2008-2009 Kitware, Inc.
@@ -174,8 +236,9 @@ function(get_bundle_main_executable bundle result_var)
#
set(eol_char "E")
file(READ "${bundle}/Contents/Info.plist" info_plist)
- string(REGEX REPLACE ";" "\\\\;" info_plist "${info_plist}")
- string(REGEX REPLACE "\n" "${eol_char};" info_plist "${info_plist}")
+ string(REPLACE ";" "\\;" info_plist "${info_plist}")
+ string(REPLACE "\n" "${eol_char};" info_plist "${info_plist}")
+ string(REPLACE "\r" "${eol_char};" info_plist "${info_plist}")
# Scan the lines for "<key>CFBundleExecutable</key>" - the line after that
# is the name of the main executable.
@@ -186,7 +249,7 @@ function(get_bundle_main_executable bundle result_var)
break()
endif()
- if(line MATCHES "^.*<key>CFBundleExecutable</key>.*$")
+ if(line MATCHES "<key>CFBundleExecutable</key>")
set(line_is_main_executable 1)
endif()
endforeach()
@@ -226,7 +289,7 @@ endfunction()
function(get_dotapp_dir exe dotapp_dir_var)
set(s "${exe}")
- if(s MATCHES "^.*/.*\\.app/.*$")
+ if(s MATCHES "/.*\\.app/")
# If there is a ".app" parent directory,
# ascend until we hit it:
# (typical of a Mac bundle executable)
@@ -316,7 +379,25 @@ endfunction()
function(get_bundle_all_executables bundle exes_var)
set(exes "")
- file(GLOB_RECURSE file_list "${bundle}/*")
+ if(UNIX)
+ find_program(find_cmd "find")
+ mark_as_advanced(find_cmd)
+ endif()
+
+ # find command is much quicker than checking every file one by one on Unix
+ # which can take long time for large bundles, and since anyway we expect
+ # executable to have execute flag set we can narrow the list much quicker.
+ if(find_cmd)
+ execute_process(COMMAND "${find_cmd}" "${bundle}"
+ -type f \( -perm -0100 -o -perm -0010 -o -perm -0001 \)
+ OUTPUT_VARIABLE file_list
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ string(REPLACE "\n" ";" file_list "${file_list}")
+ else()
+ file(GLOB_RECURSE file_list "${bundle}/*")
+ endif()
+
foreach(f ${file_list})
is_file_executable("${f}" is_executable)
if(is_executable)
@@ -328,12 +409,37 @@ function(get_bundle_all_executables bundle exes_var)
endfunction()
+function(get_item_rpaths item rpaths_var)
+ if(APPLE)
+ find_program(otool_cmd "otool")
+ mark_as_advanced(otool_cmd)
+ endif()
+
+ if(otool_cmd)
+ execute_process(
+ COMMAND "${otool_cmd}" -l "${item}"
+ OUTPUT_VARIABLE load_cmds_ov
+ )
+ string(REGEX REPLACE "[^\n]+cmd LC_RPATH\n[^\n]+\n[^\n]+path ([^\n]+) \\(offset[^\n]+\n" "rpath \\1\n" load_cmds_ov "${load_cmds_ov}")
+ string(REGEX MATCHALL "rpath [^\n]+" load_cmds_ov "${load_cmds_ov}")
+ string(REGEX REPLACE "rpath " "" load_cmds_ov "${load_cmds_ov}")
+ if(load_cmds_ov)
+ foreach(rpath ${load_cmds_ov})
+ gp_append_unique(${rpaths_var} "${rpath}")
+ endforeach()
+ endif()
+ endif()
+
+ set(${rpaths_var} ${${rpaths_var}} PARENT_SCOPE)
+endfunction()
+
+
function(get_item_key item key_var)
get_filename_component(item_name "${item}" NAME)
if(WIN32)
string(TOLOWER "${item_name}" item_name)
endif()
- string(REGEX REPLACE "\\." "_" ${key_var} "${item_name}")
+ string(REPLACE "." "_" ${key_var} "${item_name}")
set(${key_var} ${${key_var}} PARENT_SCOPE)
endfunction()
@@ -346,12 +452,18 @@ function(clear_bundle_keys keys_var)
set(${key}_EMBEDDED_ITEM PARENT_SCOPE)
set(${key}_RESOLVED_EMBEDDED_ITEM PARENT_SCOPE)
set(${key}_COPYFLAG PARENT_SCOPE)
+ set(${key}_RPATHS PARENT_SCOPE)
endforeach()
set(${keys_var} PARENT_SCOPE)
endfunction()
function(set_bundle_key_values keys_var context item exepath dirs copyflag)
+ if(ARGC GREATER 6)
+ set(rpaths "${ARGV6}")
+ else()
+ set(rpaths "")
+ endif()
get_filename_component(item_name "${item}" NAME)
get_item_key("${item}" key)
@@ -361,10 +473,12 @@ function(set_bundle_key_values keys_var context item exepath dirs copyflag)
list(LENGTH ${keys_var} length_after)
if(NOT length_before EQUAL length_after)
- gp_resolve_item("${context}" "${item}" "${exepath}" "${dirs}" resolved_item)
+ gp_resolve_item("${context}" "${item}" "${exepath}" "${dirs}" resolved_item "${rpaths}")
gp_item_default_embedded_path("${item}" default_embedded_path)
+ get_item_rpaths("${resolved_item}" item_rpaths)
+
if(item MATCHES "[^/]+\\.framework/")
# For frameworks, construct the name under the embedded path from the
# opening "${item_name}.framework/" to the closing "/${item_name}":
@@ -400,6 +514,8 @@ function(set_bundle_key_values keys_var context item exepath dirs copyflag)
set(${key}_EMBEDDED_ITEM "${embedded_item}" PARENT_SCOPE)
set(${key}_RESOLVED_EMBEDDED_ITEM "${resolved_embedded_item}" PARENT_SCOPE)
set(${key}_COPYFLAG "${copyflag}" PARENT_SCOPE)
+ set(${key}_RPATHS "${item_rpaths}" PARENT_SCOPE)
+ set(${key}_RDEP_RPATHS "${rpaths}" PARENT_SCOPE)
else()
#message("warning: item key '${key}' already in the list, subsequent references assumed identical to first")
endif()
@@ -420,18 +536,27 @@ function(get_bundle_keys app libs dirs keys_var)
#
get_bundle_all_executables("${bundle}" exes)
+ # Set keys for main executable first:
+ #
+ set_bundle_key_values(${keys_var} "${executable}" "${executable}" "${exepath}" "${dirs}" 0)
+
+ # Get rpaths specified by main executable:
+ #
+ get_item_key("${executable}" executable_key)
+ set(main_rpaths "${${executable_key}_RPATHS}")
+
# For each extra lib, accumulate a key as well and then also accumulate
# any of its prerequisites. (Extra libs are typically dynamically loaded
# plugins: libraries that are prerequisites for full runtime functionality
# but that do not show up in otool -L output...)
#
foreach(lib ${libs})
- set_bundle_key_values(${keys_var} "${lib}" "${lib}" "${exepath}" "${dirs}" 0)
+ set_bundle_key_values(${keys_var} "${lib}" "${lib}" "${exepath}" "${dirs}" 0 "${main_rpaths}")
set(prereqs "")
- get_prerequisites("${lib}" prereqs 1 1 "${exepath}" "${dirs}")
+ get_prerequisites("${lib}" prereqs 1 1 "${exepath}" "${dirs}" "${main_rpaths}")
foreach(pr ${prereqs})
- set_bundle_key_values(${keys_var} "${lib}" "${pr}" "${exepath}" "${dirs}" 1)
+ set_bundle_key_values(${keys_var} "${lib}" "${pr}" "${exepath}" "${dirs}" 1 "${main_rpaths}")
endforeach()
endforeach()
@@ -440,16 +565,27 @@ function(get_bundle_keys app libs dirs keys_var)
# binaries in the bundle have been analyzed.
#
foreach(exe ${exes})
- # Add the exe itself to the keys:
+ # Main executable is scanned first above:
#
- set_bundle_key_values(${keys_var} "${exe}" "${exe}" "${exepath}" "${dirs}" 0)
+ if(NOT "${exe}" STREQUAL "${executable}")
+ # Add the exe itself to the keys:
+ #
+ set_bundle_key_values(${keys_var} "${exe}" "${exe}" "${exepath}" "${dirs}" 0 "${main_rpaths}")
+
+ # Get rpaths specified by executable:
+ #
+ get_item_key("${exe}" exe_key)
+ set(exe_rpaths "${main_rpaths}" "${${exe_key}_RPATHS}")
+ else()
+ set(exe_rpaths "${main_rpaths}")
+ endif()
# Add each prerequisite to the keys:
#
set(prereqs "")
- get_prerequisites("${exe}" prereqs 1 1 "${exepath}" "${dirs}")
+ get_prerequisites("${exe}" prereqs 1 1 "${exepath}" "${dirs}" "${exe_rpaths}")
foreach(pr ${prereqs})
- set_bundle_key_values(${keys_var} "${exe}" "${pr}" "${exepath}" "${dirs}" 1)
+ set_bundle_key_values(${keys_var} "${exe}" "${pr}" "${exepath}" "${dirs}" 1 "${exe_rpaths}")
endforeach()
endforeach()
@@ -463,6 +599,8 @@ function(get_bundle_keys app libs dirs keys_var)
set(${key}_EMBEDDED_ITEM "${${key}_EMBEDDED_ITEM}" PARENT_SCOPE)
set(${key}_RESOLVED_EMBEDDED_ITEM "${${key}_RESOLVED_EMBEDDED_ITEM}" PARENT_SCOPE)
set(${key}_COPYFLAG "${${key}_COPYFLAG}" PARENT_SCOPE)
+ set(${key}_RPATHS "${${key}_RPATHS}" PARENT_SCOPE)
+ set(${key}_RDEP_RPATHS "${${key}_RDEP_RPATHS}" PARENT_SCOPE)
endforeach()
endif()
endfunction()
@@ -518,12 +656,45 @@ function(copy_resolved_framework_into_bundle resolved_item resolved_embedded_ite
execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${resolved_item}" "${resolved_embedded_item}")
# Plus Resources, if they exist:
- string(REGEX REPLACE "^(.*)/[^/]+/[^/]+/[^/]+$" "\\1/Resources" resolved_resources "${resolved_item}")
- string(REGEX REPLACE "^(.*)/[^/]+/[^/]+/[^/]+$" "\\1/Resources" resolved_embedded_resources "${resolved_embedded_item}")
+ string(REGEX REPLACE "^(.*)/[^/]+$" "\\1/Resources" resolved_resources "${resolved_item}")
+ string(REGEX REPLACE "^(.*)/[^/]+$" "\\1/Resources" resolved_embedded_resources "${resolved_embedded_item}")
if(EXISTS "${resolved_resources}")
#message(STATUS "copying COMMAND ${CMAKE_COMMAND} -E copy_directory '${resolved_resources}' '${resolved_embedded_resources}'")
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory "${resolved_resources}" "${resolved_embedded_resources}")
endif()
+
+ # Some frameworks e.g. Qt put Info.plist in wrong place, so when it is
+ # missing in resources, copy it from other well known incorrect locations:
+ if(NOT EXISTS "${resolved_resources}/Info.plist")
+ # Check for Contents/Info.plist in framework root (older Qt SDK):
+ string(REGEX REPLACE "^(.*)/[^/]+/[^/]+/[^/]+$" "\\1/Contents/Info.plist" resolved_info_plist "${resolved_item}")
+ string(REGEX REPLACE "^(.*)/[^/]+$" "\\1/Resources/Info.plist" resolved_embedded_info_plist "${resolved_embedded_item}")
+ if(EXISTS "${resolved_info_plist}")
+ #message(STATUS "copying COMMAND ${CMAKE_COMMAND} -E copy_directory '${resolved_info_plist}' '${resolved_embedded_info_plist}'")
+ execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${resolved_info_plist}" "${resolved_embedded_info_plist}")
+ endif()
+ endif()
+
+ # Check if framework is versioned and fix it layout
+ string(REGEX REPLACE "^.*/([^/]+)/[^/]+$" "\\1" resolved_embedded_version "${resolved_embedded_item}")
+ string(REGEX REPLACE "^(.*)/[^/]+/[^/]+$" "\\1" resolved_embedded_versions "${resolved_embedded_item}")
+ string(REGEX REPLACE "^.*/([^/]+)/[^/]+/[^/]+$" "\\1" resolved_embedded_versions_basename "${resolved_embedded_item}")
+ if(resolved_embedded_versions_basename STREQUAL "Versions")
+ # Ensure Current symlink points to the framework version
+ if(NOT EXISTS "${resolved_embedded_versions}/Current")
+ execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${resolved_embedded_version}" "${resolved_embedded_versions}/Current")
+ endif()
+ # Restore symlinks in framework root pointing to current framework
+ # binary and resources:
+ string(REGEX REPLACE "^(.*)/[^/]+/[^/]+/[^/]+$" "\\1" resolved_embedded_root "${resolved_embedded_item}")
+ string(REGEX REPLACE "^.*/([^/]+)$" "\\1" resolved_embedded_item_basename "${resolved_embedded_item}")
+ if(NOT EXISTS "${resolved_embedded_root}/${resolved_embedded_item_basename}")
+ execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "Versions/Current/${resolved_embedded_item_basename}" "${resolved_embedded_root}/${resolved_embedded_item_basename}")
+ endif()
+ if(NOT EXISTS "${resolved_embedded_root}/Resources")
+ execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "Versions/Current/Resources" "${resolved_embedded_root}/Resources")
+ endif()
+ endif()
endif()
if(UNIX AND NOT APPLE)
file(RPATH_REMOVE FILE "${resolved_embedded_item}")
@@ -568,8 +739,10 @@ function(fixup_bundle_item resolved_embedded_item exepath dirs)
message(FATAL_ERROR "cannot fixup an item that is not in the bundle...")
endif()
+ set(rpaths "${${ikey}_RPATHS}" "${${ikey}_RDEP_RPATHS}")
+
set(prereqs "")
- get_prerequisites("${resolved_embedded_item}" prereqs 1 0 "${exepath}" "${dirs}")
+ get_prerequisites("${resolved_embedded_item}" prereqs 1 0 "${exepath}" "${dirs}" "${rpaths}")
set(changes "")
@@ -589,12 +762,33 @@ function(fixup_bundle_item resolved_embedded_item exepath dirs)
execute_process(COMMAND chmod u+w "${resolved_embedded_item}")
endif()
+ # Only if install_name_tool supports -delete_rpath:
+ #
+ execute_process(COMMAND install_name_tool
+ OUTPUT_VARIABLE install_name_tool_usage
+ ERROR_VARIABLE install_name_tool_usage
+ )
+ if(install_name_tool_usage MATCHES ".*-delete_rpath.*")
+ foreach(rpath ${${ikey}_RPATHS})
+ set(changes ${changes} -delete_rpath "${rpath}")
+ endforeach()
+ endif()
+
+ if(${ikey}_EMBEDDED_ITEM)
+ set(changes ${changes} -id "${${ikey}_EMBEDDED_ITEM}")
+ endif()
+
# Change this item's id and all of its references in one call
# to install_name_tool:
#
- execute_process(COMMAND install_name_tool
- ${changes} -id "${${ikey}_EMBEDDED_ITEM}" "${resolved_embedded_item}"
- )
+ if(changes)
+ set(cmd install_name_tool ${changes} "${resolved_embedded_item}")
+ execute_process(COMMAND ${cmd} RESULT_VARIABLE install_name_tool_result)
+ if(NOT install_name_tool_result EQUAL 0)
+ string(REPLACE ";" "' '" msg "'${cmd}'")
+ message(FATAL_ERROR "Command failed:\n ${msg}")
+ endif()
+ endif()
endfunction()
@@ -685,10 +879,8 @@ function(verify_bundle_prerequisites bundle result_var info_var)
get_bundle_main_executable("${bundle}" main_bundle_exe)
- file(GLOB_RECURSE file_list "${bundle}/*")
+ get_bundle_all_executables("${bundle}" file_list)
foreach(f ${file_list})
- is_file_executable("${f}" is_executable)
- if(is_executable)
get_filename_component(exepath "${f}" PATH)
math(EXPR count "${count} + 1")
@@ -727,7 +919,6 @@ function(verify_bundle_prerequisites bundle result_var info_var)
set(result 0)
set(info ${info} "external prerequisites found:\nf='${f}'\nexternal_prereqs='${external_prereqs}'\n")
endif()
- endif()
endforeach()
if(result)
diff --git a/Modules/CMakeASMInformation.cmake b/Modules/CMakeASMInformation.cmake
index dce162496..0e547c467 100644
--- a/Modules/CMakeASMInformation.cmake
+++ b/Modules/CMakeASMInformation.cmake
@@ -50,6 +50,24 @@ if(NOT _INCLUDED_FILE)
include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME} OPTIONAL)
endif()
+# This should be included before the _INIT variables are
+# used to initialize the cache. Since the rule variables
+# have if blocks on them, users can still define them here.
+# But, it should still be after the platform file so changes can
+# be made to those values.
+
+if(CMAKE_USER_MAKE_RULES_OVERRIDE)
+ # Save the full path of the file so try_compile can use it.
+ include(${CMAKE_USER_MAKE_RULES_OVERRIDE} RESULT_VARIABLE _override)
+ set(CMAKE_USER_MAKE_RULES_OVERRIDE "${_override}")
+endif()
+
+if(CMAKE_USER_MAKE_RULES_OVERRIDE_ASM)
+ # Save the full path of the file so try_compile can use it.
+ include(${CMAKE_USER_MAKE_RULES_OVERRIDE_ASM} RESULT_VARIABLE _override)
+ set(CMAKE_USER_MAKE_RULES_OVERRIDE_ASM "${_override}")
+endif()
+
# Set default assembler file extensions:
if(NOT CMAKE_ASM${ASM_DIALECT}_SOURCE_FILE_EXTENSIONS)
set(CMAKE_ASM${ASM_DIALECT}_SOURCE_FILE_EXTENSIONS s;S;asm)
@@ -90,7 +108,7 @@ mark_as_advanced(CMAKE_ASM${ASM_DIALECT}_FLAGS
if(NOT CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT)
- set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <DEFINES> <FLAGS> -o <OBJECT> -c <SOURCE>")
+ set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
endif()
if(NOT CMAKE_ASM${ASM_DIALECT}_CREATE_STATIC_LIBRARY)
diff --git a/Modules/CMakeASM_MASMInformation.cmake b/Modules/CMakeASM_MASMInformation.cmake
index eb105ab10..bd76b9842 100644
--- a/Modules/CMakeASM_MASMInformation.cmake
+++ b/Modules/CMakeASM_MASMInformation.cmake
@@ -18,7 +18,7 @@ set(ASM_DIALECT "_MASM")
set(CMAKE_ASM${ASM_DIALECT}_SOURCE_FILE_EXTENSIONS asm)
-set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <FLAGS> /c /Fo <OBJECT> <SOURCE>")
+set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> /c /Fo <OBJECT> <SOURCE>")
include(CMakeASMInformation)
set(ASM_DIALECT)
diff --git a/Modules/CMakeAddFortranSubdirectory.cmake b/Modules/CMakeAddFortranSubdirectory.cmake
index abd910055..2e5a76f4c 100644
--- a/Modules/CMakeAddFortranSubdirectory.cmake
+++ b/Modules/CMakeAddFortranSubdirectory.cmake
@@ -1,29 +1,37 @@
-# - Use MinGW gfortran from VS if a fortran compiler is not found.
-# The 'add_fortran_subdirectory' function adds a subdirectory
-# to a project that contains a fortran only sub-project. The module
-# will check the current compiler and see if it can support fortran.
-# If no fortran compiler is found and the compiler is MSVC, then
-# this module will find the MinGW gfortran. It will then use
-# an external project to build with the MinGW tools. It will also
-# create imported targets for the libraries created. This will only
-# work if the fortran code is built into a dll, so BUILD_SHARED_LIBS
-# is turned on in the project. In addition the CMAKE_GNUtoMS option
-# is set to on, so that the MS .lib files are created.
-# Usage is as follows:
-# cmake_add_fortran_subdirectory(
-# <subdir> # name of subdirectory
-# PROJECT <project_name> # project name in subdir top CMakeLists.txt
-# ARCHIVE_DIR <dir> # dir where project places .lib files
-# RUNTIME_DIR <dir> # dir where project places .dll files
-# LIBRARIES <lib>... # names of library targets to import
-# LINK_LIBRARIES # link interface libraries for LIBRARIES
-# [LINK_LIBS <lib> <dep>...]...
-# CMAKE_COMMAND_LINE ... # extra command line flags to pass to cmake
-# NO_EXTERNAL_INSTALL # skip installation of external project
-# )
-# Relative paths in ARCHIVE_DIR and RUNTIME_DIR are interpreted with respect
-# to the build directory corresponding to the source directory in which the
-# function is invoked.
+#.rst:
+# CMakeAddFortranSubdirectory
+# ---------------------------
+#
+# Use MinGW gfortran from VS if a fortran compiler is not found.
+#
+# The 'add_fortran_subdirectory' function adds a subdirectory to a
+# project that contains a fortran only sub-project. The module will
+# check the current compiler and see if it can support fortran. If no
+# fortran compiler is found and the compiler is MSVC, then this module
+# will find the MinGW gfortran. It will then use an external project to
+# build with the MinGW tools. It will also create imported targets for
+# the libraries created. This will only work if the fortran code is
+# built into a dll, so BUILD_SHARED_LIBS is turned on in the project.
+# In addition the CMAKE_GNUtoMS option is set to on, so that the MS .lib
+# files are created. Usage is as follows:
+#
+# ::
+#
+# cmake_add_fortran_subdirectory(
+# <subdir> # name of subdirectory
+# PROJECT <project_name> # project name in subdir top CMakeLists.txt
+# ARCHIVE_DIR <dir> # dir where project places .lib files
+# RUNTIME_DIR <dir> # dir where project places .dll files
+# LIBRARIES <lib>... # names of library targets to import
+# LINK_LIBRARIES # link interface libraries for LIBRARIES
+# [LINK_LIBS <lib> <dep>...]...
+# CMAKE_COMMAND_LINE ... # extra command line flags to pass to cmake
+# NO_EXTERNAL_INSTALL # skip installation of external project
+# )
+#
+# Relative paths in ARCHIVE_DIR and RUNTIME_DIR are interpreted with
+# respect to the build directory corresponding to the source directory
+# in which the function is invoked.
#
# Limitations:
#
diff --git a/Modules/CMakeBackwardCompatibilityCXX.cmake b/Modules/CMakeBackwardCompatibilityCXX.cmake
index cfc1d91f9..f1db46e54 100644
--- a/Modules/CMakeBackwardCompatibilityCXX.cmake
+++ b/Modules/CMakeBackwardCompatibilityCXX.cmake
@@ -1,10 +1,17 @@
-# - define a bunch of backwards compatibility variables
-# CMAKE_ANSI_CXXFLAGS - flag for ansi c++
-# CMAKE_HAS_ANSI_STRING_STREAM - has <strstream>
-# include(TestForANSIStreamHeaders)
-# include(CheckIncludeFileCXX)
-# include(TestForSTDNamespace)
-# include(TestForANSIForScope)
+#.rst:
+# CMakeBackwardCompatibilityCXX
+# -----------------------------
+#
+# define a bunch of backwards compatibility variables
+#
+# ::
+#
+# CMAKE_ANSI_CXXFLAGS - flag for ansi c++
+# CMAKE_HAS_ANSI_STRING_STREAM - has <strstream>
+# include(TestForANSIStreamHeaders)
+# include(CheckIncludeFileCXX)
+# include(TestForSTDNamespace)
+# include(TestForANSIForScope)
#=============================================================================
# Copyright 2002-2009 Kitware, Inc.
@@ -24,15 +31,15 @@ if(NOT CMAKE_SKIP_COMPATIBILITY_TESTS)
if(NOT CMAKE_COMPILER_IS_GNUCXX)
include(TestCXXAcceptsFlag)
set(CMAKE_TRY_ANSI_CXX_FLAGS "")
- if(CMAKE_SYSTEM MATCHES "IRIX.*")
+ if(CMAKE_SYSTEM_NAME MATCHES "IRIX")
set(CMAKE_TRY_ANSI_CXX_FLAGS "-LANG:std")
endif()
- if(CMAKE_SYSTEM MATCHES "OSF.*")
+ if(CMAKE_SYSTEM_NAME MATCHES "OSF")
set(CMAKE_TRY_ANSI_CXX_FLAGS "-std strict_ansi -nopure_cname")
endif()
# if CMAKE_TRY_ANSI_CXX_FLAGS has something in it, see
# if the compiler accepts it
- if( CMAKE_TRY_ANSI_CXX_FLAGS MATCHES ".+")
+ if(NOT CMAKE_TRY_ANSI_CXX_FLAGS STREQUAL "")
CHECK_CXX_ACCEPTS_FLAG(${CMAKE_TRY_ANSI_CXX_FLAGS} CMAKE_CXX_ACCEPTS_FLAGS)
# if the compiler liked the flag then set CMAKE_ANSI_CXXFLAGS
# to the flag
diff --git a/Modules/CMakeCCompiler.cmake.in b/Modules/CMakeCCompiler.cmake.in
index c41adc956..f109a1479 100644
--- a/Modules/CMakeCCompiler.cmake.in
+++ b/Modules/CMakeCCompiler.cmake.in
@@ -2,7 +2,16 @@ set(CMAKE_C_COMPILER "@CMAKE_C_COMPILER@")
set(CMAKE_C_COMPILER_ARG1 "@CMAKE_C_COMPILER_ARG1@")
set(CMAKE_C_COMPILER_ID "@CMAKE_C_COMPILER_ID@")
set(CMAKE_C_COMPILER_VERSION "@CMAKE_C_COMPILER_VERSION@")
+set(CMAKE_C_COMPILER_WRAPPER "@CMAKE_C_COMPILER_WRAPPER@")
+set(CMAKE_C_STANDARD_COMPUTED_DEFAULT "@CMAKE_C_STANDARD_COMPUTED_DEFAULT@")
+set(CMAKE_C_COMPILE_FEATURES "@CMAKE_C_COMPILE_FEATURES@")
+set(CMAKE_C90_COMPILE_FEATURES "@CMAKE_C90_COMPILE_FEATURES@")
+set(CMAKE_C99_COMPILE_FEATURES "@CMAKE_C99_COMPILE_FEATURES@")
+set(CMAKE_C11_COMPILE_FEATURES "@CMAKE_C11_COMPILE_FEATURES@")
+
set(CMAKE_C_PLATFORM_ID "@CMAKE_C_PLATFORM_ID@")
+set(CMAKE_C_SIMULATE_ID "@CMAKE_C_SIMULATE_ID@")
+set(CMAKE_C_SIMULATE_VERSION "@CMAKE_C_SIMULATE_VERSION@")
@SET_MSVC_C_ARCHITECTURE_ID@
set(CMAKE_AR "@CMAKE_AR@")
set(CMAKE_RANLIB "@CMAKE_RANLIB@")
@@ -24,7 +33,7 @@ if(CMAKE_COMPILER_IS_MINGW)
set(MINGW 1)
endif()
set(CMAKE_C_COMPILER_ID_RUN 1)
-set(CMAKE_C_SOURCE_FILE_EXTENSIONS c)
+set(CMAKE_C_SOURCE_FILE_EXTENSIONS c;m)
set(CMAKE_C_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
set(CMAKE_C_LINKER_PREFERENCE 10)
@@ -45,12 +54,14 @@ if(CMAKE_C_LIBRARY_ARCHITECTURE)
set(CMAKE_LIBRARY_ARCHITECTURE "@CMAKE_C_LIBRARY_ARCHITECTURE@")
endif()
+set(CMAKE_C_CL_SHOWINCLUDES_PREFIX "@CMAKE_C_CL_SHOWINCLUDES_PREFIX@")
+if(CMAKE_C_CL_SHOWINCLUDES_PREFIX)
+ set(CMAKE_CL_SHOWINCLUDES_PREFIX "${CMAKE_C_CL_SHOWINCLUDES_PREFIX}")
+endif()
+
@CMAKE_C_SYSROOT_FLAG_CODE@
@CMAKE_C_OSX_DEPLOYMENT_TARGET_FLAG_CODE@
set(CMAKE_C_IMPLICIT_LINK_LIBRARIES "@CMAKE_C_IMPLICIT_LINK_LIBRARIES@")
set(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "@CMAKE_C_IMPLICIT_LINK_DIRECTORIES@")
set(CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@")
-
-@SET_CMAKE_CMCLDEPS_EXECUTABLE@
-@SET_CMAKE_CL_SHOWINCLUDE_PREFIX@
diff --git a/Modules/CMakeCCompilerId.c.in b/Modules/CMakeCCompilerId.c.in
index 66a558265..5bfe0fdfa 100644
--- a/Modules/CMakeCCompilerId.c.in
+++ b/Modules/CMakeCCompilerId.c.in
@@ -2,212 +2,42 @@
# error "A C++ compiler has been selected for C."
#endif
-/* Version number components: V=Version, R=Revision, P=Patch
- Version date components: YYYY=Year, MM=Month, DD=Day */
-
#if defined(__18CXX)
# define ID_VOID_MAIN
#endif
-#if defined(__INTEL_COMPILER) || defined(__ICC)
-# define COMPILER_ID "Intel"
- /* __INTEL_COMPILER = VRP */
-# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100)
-# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10)
-# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10)
-# if defined(__INTEL_COMPILER_BUILD_DATE)
- /* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */
-# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE)
-# endif
-
-#elif defined(__PATHCC__)
-# define COMPILER_ID "PathScale"
-# define COMPILER_VERSION_MAJOR DEC(__PATHCC__)
-# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__)
-# if defined(__PATHCC_PATCHLEVEL__)
-# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__)
-# endif
-
-#elif defined(__clang__)
-# define COMPILER_ID "Clang"
-# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
-# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
-# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
-
-#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__)
-# define COMPILER_ID "Embarcadero"
-# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF)
-# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF)
-# define COMPILER_VERSION_PATCH HEX(__CODEGEARC_VERSION__ & 0xFFFF)
-
-#elif defined(__BORLANDC__)
-# define COMPILER_ID "Borland"
- /* __BORLANDC__ = 0xVRR */
-# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8)
-# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF)
-
-#elif defined(__WATCOMC__)
-# define COMPILER_ID "Watcom"
- /* __WATCOMC__ = VVRR */
-# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100)
-# define COMPILER_VERSION_MINOR DEC(__WATCOMC__ % 100)
-
-#elif defined(__SUNPRO_C)
-# define COMPILER_ID "SunPro"
-# if __SUNPRO_C >= 0x5100
- /* __SUNPRO_C = 0xVRRP */
-# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>12)
-# define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xFF)
-# define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF)
-# else
- /* __SUNPRO_C = 0xVRP */
-# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>8)
-# define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xF)
-# define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF)
-# endif
-
-#elif defined(__HP_cc)
-# define COMPILER_ID "HP"
- /* __HP_cc = VVRRPP */
-# define COMPILER_VERSION_MAJOR DEC(__HP_cc/10000)
-# define COMPILER_VERSION_MINOR DEC(__HP_cc/100 % 100)
-# define COMPILER_VERSION_PATCH DEC(__HP_cc % 100)
-
-#elif defined(__DECC)
-# define COMPILER_ID "Compaq"
- /* __DECC_VER = VVRRTPPPP */
-# define COMPILER_VERSION_MAJOR DEC(__DECC_VER/10000000)
-# define COMPILER_VERSION_MINOR DEC(__DECC_VER/100000 % 100)
-# define COMPILER_VERSION_PATCH DEC(__DECC_VER % 10000)
-
-#elif defined(__IBMC__)
-# if defined(__COMPILER_VER__)
-# define COMPILER_ID "zOS"
-# else
-# if __IBMC__ >= 800
-# define COMPILER_ID "XL"
-# else
-# define COMPILER_ID "VisualAge"
-# endif
- /* __IBMC__ = VRP */
-# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100)
-# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10)
-# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10)
-# endif
-
-#elif defined(__PGI)
-# define COMPILER_ID "PGI"
-# define COMPILER_VERSION_MAJOR DEC(__PGIC__)
-# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__)
-# if defined(__PGIC_PATCHLEVEL__)
-# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__)
-# endif
-
-#elif defined(_CRAYC)
-# define COMPILER_ID "Cray"
-# define COMPILER_VERSION_MAJOR DEC(_RELEASE)
-# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR)
-
-#elif defined(__TI_COMPILER_VERSION__)
-# define COMPILER_ID "TI"
- /* __TI_COMPILER_VERSION__ = VVVRRRPPP */
-# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000)
-# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000)
-# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000)
-
-#elif defined(__TINYC__)
-# define COMPILER_ID "TinyCC"
-
-#elif defined(__SCO_VERSION__)
-# define COMPILER_ID "SCO"
-
-#elif defined(__GNUC__)
-# define COMPILER_ID "GNU"
-# define COMPILER_VERSION_MAJOR DEC(__GNUC__)
-# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__)
-# if defined(__GNUC_PATCHLEVEL__)
-# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
-# endif
-
-#elif defined(_MSC_VER)
-# define COMPILER_ID "MSVC"
- /* _MSC_VER = VVRR */
-# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100)
-# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100)
-# if defined(_MSC_FULL_VER)
-# if _MSC_VER >= 1400
- /* _MSC_FULL_VER = VVRRPPPPP */
-# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000)
-# else
- /* _MSC_FULL_VER = VVRRPPPP */
-# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000)
-# endif
-# endif
-# if defined(_MSC_BUILD)
-# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD)
-# endif
-
-/* Analog VisualDSP++ >= 4.5.6 */
-#elif defined(__VISUALDSPVERSION__)
-# define COMPILER_ID "ADSP"
- /* __VISUALDSPVERSION__ = 0xVVRRPP00 */
-# define COMPILER_VERSION_MAJOR HEX(__VISUALDSPVERSION__>>24)
-# define COMPILER_VERSION_MINOR HEX(__VISUALDSPVERSION__>>16 & 0xFF)
-# define COMPILER_VERSION_PATCH HEX(__VISUALDSPVERSION__>>8 & 0xFF)
-
-/* Analog VisualDSP++ < 4.5.6 */
-#elif defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__)
-# define COMPILER_ID "ADSP"
-
-/* IAR Systems compiler for embedded systems.
- http://www.iar.com */
-#elif defined(__IAR_SYSTEMS_ICC__ ) || defined(__IAR_SYSTEMS_ICC)
-# define COMPILER_ID "IAR"
-
-/* sdcc, the small devices C compiler for embedded systems,
- http://sdcc.sourceforge.net */
-#elif defined(SDCC)
-# define COMPILER_ID "SDCC"
- /* SDCC = VRP */
-# define COMPILER_VERSION_MAJOR DEC(SDCC/100)
-# define COMPILER_VERSION_MINOR DEC(SDCC/10 % 10)
-# define COMPILER_VERSION_PATCH DEC(SDCC % 10)
-
-#elif defined(_SGI_COMPILER_VERSION) || defined(_COMPILER_VERSION)
-# define COMPILER_ID "MIPSpro"
-# if defined(_SGI_COMPILER_VERSION)
- /* _SGI_COMPILER_VERSION = VRP */
-# define COMPILER_VERSION_MAJOR DEC(_SGI_COMPILER_VERSION/100)
-# define COMPILER_VERSION_MINOR DEC(_SGI_COMPILER_VERSION/10 % 10)
-# define COMPILER_VERSION_PATCH DEC(_SGI_COMPILER_VERSION % 10)
-# else
- /* _COMPILER_VERSION = VRP */
-# define COMPILER_VERSION_MAJOR DEC(_COMPILER_VERSION/100)
-# define COMPILER_VERSION_MINOR DEC(_COMPILER_VERSION/10 % 10)
-# define COMPILER_VERSION_PATCH DEC(_COMPILER_VERSION % 10)
-# endif
-
-/* This compiler is either not known or is too old to define an
- identification macro. Try to identify the platform and guess that
- it is the native compiler. */
-#elif defined(__sgi)
-# define COMPILER_ID "MIPSpro"
-
-#elif defined(__hpux) || defined(__hpua)
-# define COMPILER_ID "HP"
-
-#else /* unknown compiler */
-# define COMPILER_ID ""
-
-#endif
+@CMAKE_C_COMPILER_ID_CONTENT@
/* Construct the string literal in pieces to prevent the source from
getting matched. Store it in a pointer rather than an array
because some compilers will just produce instructions to fill the
array rather than assigning a pointer to a static array. */
char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
+#ifdef SIMULATE_ID
+char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]";
+#endif
+
+#ifdef __QNXNTO__
+char const* qnxnto = "INFO" ":" "qnxnto[]";
+#endif
+
+#if defined(__CRAYXE) || defined(__CRAYXC)
+char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]";
+#endif
@CMAKE_C_COMPILER_ID_PLATFORM_CONTENT@
+@CMAKE_C_COMPILER_ID_ERROR_FOR_TEST@
+
+const char* info_language_dialect_default = "INFO" ":" "dialect_default["
+#if !defined(__STDC_VERSION__)
+ "90"
+#elif __STDC_VERSION__ >= 201000L
+ "11"
+#elif __STDC_VERSION__ >= 199901L
+ "99"
+#else
+#endif
+"]";
/*--------------------------------------------------------------------------*/
@@ -223,6 +53,16 @@ int main(int argc, char* argv[])
#ifdef COMPILER_VERSION_MAJOR
require += info_version[argc];
#endif
+#ifdef SIMULATE_ID
+ require += info_simulate[argc];
+#endif
+#ifdef SIMULATE_VERSION_MAJOR
+ require += info_simulate_version[argc];
+#endif
+#if defined(__CRAYXE) || defined(__CRAYXC)
+ require += info_cray[argc];
+#endif
+ require += info_language_dialect_default[argc];
(void)argv;
return require;
}
diff --git a/Modules/CMakeCInformation.cmake b/Modules/CMakeCInformation.cmake
index ce5ce4409..fa87ca84c 100644
--- a/Modules/CMakeCInformation.cmake
+++ b/Modules/CMakeCInformation.cmake
@@ -18,6 +18,8 @@
# It also loads a system - compiler - processor (or target hardware)
# specific file, which is mainly useful for crosscompiling and embedded systems.
+include(CMakeLanguageInformation)
+
# some compilers use different extensions (e.g. sdcc uses .rel)
# so set the extension here first so it can be overridden by the compiler specific file
if(UNIX)
@@ -34,7 +36,7 @@ if(CMAKE_C_COMPILER_ID)
endif()
set(CMAKE_BASE_NAME)
-get_filename_component(CMAKE_BASE_NAME ${CMAKE_C_COMPILER} NAME_WE)
+get_filename_component(CMAKE_BASE_NAME "${CMAKE_C_COMPILER}" NAME_WE)
if(CMAKE_COMPILER_IS_GNUCC)
set(CMAKE_BASE_NAME gcc)
endif()
@@ -60,6 +62,12 @@ if (NOT _INCLUDED_FILE)
include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME}
OPTIONAL RESULT_VARIABLE _INCLUDED_FILE)
endif ()
+
+# load any compiler-wrapper specific information
+if (CMAKE_C_COMPILER_WRAPPER)
+ __cmake_include_compiler_wrapper(C)
+endif ()
+
# We specify the compiler information in the system file for some
# platforms, but this language may not have been enabled when the file
# was first included. Include it again to get the language info.
@@ -119,16 +127,16 @@ if(NOT CMAKE_NOT_USING_CONFIG_FLAGS)
set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG_INIT}" CACHE STRING
"Flags used by the compiler during debug builds.")
set (CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL_INIT}" CACHE STRING
- "Flags used by the compiler during release minsize builds.")
+ "Flags used by the compiler during release builds for minimum size.")
set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE_INIT}" CACHE STRING
- "Flags used by the compiler during release builds (/MD /Ob1 /Oi /Ot /Oy /Gs will produce slightly less optimized but smaller files).")
+ "Flags used by the compiler during release builds.")
set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO_INIT}" CACHE STRING
- "Flags used by the compiler during Release with Debug Info builds.")
+ "Flags used by the compiler during release builds with debug info.")
endif()
if(CMAKE_C_STANDARD_LIBRARIES_INIT)
set(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES_INIT}"
- CACHE STRING "Libraries linked by defalut with all C applications.")
+ CACHE STRING "Libraries linked by default with all C applications.")
mark_as_advanced(CMAKE_C_STANDARD_LIBRARIES)
endif()
@@ -175,10 +183,10 @@ endif()
# Create a static archive incrementally for large object file counts.
# If CMAKE_C_CREATE_STATIC_LIBRARY is set it will override these.
if(NOT DEFINED CMAKE_C_ARCHIVE_CREATE)
- set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> cr <TARGET> <LINK_FLAGS> <OBJECTS>")
+ set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
endif()
if(NOT DEFINED CMAKE_C_ARCHIVE_APPEND)
- set(CMAKE_C_ARCHIVE_APPEND "<CMAKE_AR> r <TARGET> <LINK_FLAGS> <OBJECTS>")
+ set(CMAKE_C_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
endif()
if(NOT DEFINED CMAKE_C_ARCHIVE_FINISH)
set(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
@@ -187,7 +195,7 @@ endif()
# compile a C file into an object file
if(NOT CMAKE_C_COMPILE_OBJECT)
set(CMAKE_C_COMPILE_OBJECT
- "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -o <OBJECT> -c <SOURCE>")
+ "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
endif()
if(NOT CMAKE_C_LINK_EXECUTABLE)
diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in
index 9287b8194..9e90aea59 100644
--- a/Modules/CMakeCXXCompiler.cmake.in
+++ b/Modules/CMakeCXXCompiler.cmake.in
@@ -2,7 +2,16 @@ set(CMAKE_CXX_COMPILER "@CMAKE_CXX_COMPILER@")
set(CMAKE_CXX_COMPILER_ARG1 "@CMAKE_CXX_COMPILER_ARG1@")
set(CMAKE_CXX_COMPILER_ID "@CMAKE_CXX_COMPILER_ID@")
set(CMAKE_CXX_COMPILER_VERSION "@CMAKE_CXX_COMPILER_VERSION@")
+set(CMAKE_CXX_COMPILER_WRAPPER "@CMAKE_CXX_COMPILER_WRAPPER@")
+set(CMAKE_CXX_STANDARD_COMPUTED_DEFAULT "@CMAKE_CXX_STANDARD_COMPUTED_DEFAULT@")
+set(CMAKE_CXX_COMPILE_FEATURES "@CMAKE_CXX_COMPILE_FEATURES@")
+set(CMAKE_CXX98_COMPILE_FEATURES "@CMAKE_CXX98_COMPILE_FEATURES@")
+set(CMAKE_CXX11_COMPILE_FEATURES "@CMAKE_CXX11_COMPILE_FEATURES@")
+set(CMAKE_CXX14_COMPILE_FEATURES "@CMAKE_CXX14_COMPILE_FEATURES@")
+
set(CMAKE_CXX_PLATFORM_ID "@CMAKE_CXX_PLATFORM_ID@")
+set(CMAKE_CXX_SIMULATE_ID "@CMAKE_CXX_SIMULATE_ID@")
+set(CMAKE_CXX_SIMULATE_VERSION "@CMAKE_CXX_SIMULATE_VERSION@")
@SET_MSVC_CXX_ARCHITECTURE_ID@
set(CMAKE_AR "@CMAKE_AR@")
set(CMAKE_RANLIB "@CMAKE_RANLIB@")
@@ -25,7 +34,7 @@ if(CMAKE_COMPILER_IS_MINGW)
endif()
set(CMAKE_CXX_COMPILER_ID_RUN 1)
set(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;hpp;HPP;H;o;O;obj;OBJ;def;DEF;rc;RC)
-set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;m;mm;CPP)
+set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;mm;CPP)
set(CMAKE_CXX_LINKER_PREFERENCE 30)
set(CMAKE_CXX_LINKER_PREFERENCE_PROPAGATES 1)
@@ -46,12 +55,14 @@ if(CMAKE_CXX_LIBRARY_ARCHITECTURE)
set(CMAKE_LIBRARY_ARCHITECTURE "@CMAKE_CXX_LIBRARY_ARCHITECTURE@")
endif()
+set(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX "@CMAKE_CXX_CL_SHOWINCLUDES_PREFIX@")
+if(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX)
+ set(CMAKE_CL_SHOWINCLUDES_PREFIX "${CMAKE_CXX_CL_SHOWINCLUDES_PREFIX}")
+endif()
+
@CMAKE_CXX_SYSROOT_FLAG_CODE@
@CMAKE_CXX_OSX_DEPLOYMENT_TARGET_FLAG_CODE@
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "@CMAKE_CXX_IMPLICIT_LINK_LIBRARIES@")
set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "@CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES@")
set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@")
-
-@SET_CMAKE_CMCLDEPS_EXECUTABLE@
-@SET_CMAKE_CL_SHOWINCLUDE_PREFIX@
diff --git a/Modules/CMakeCXXCompilerId.cpp.in b/Modules/CMakeCXXCompilerId.cpp.in
index 5e87715c0..3e5c0fcff 100644
--- a/Modules/CMakeCXXCompilerId.cpp.in
+++ b/Modules/CMakeCXXCompilerId.cpp.in
@@ -5,202 +5,37 @@
# error "A C compiler has been selected for C++."
#endif
-/* Version number components: V=Version, R=Revision, P=Patch
- Version date components: YYYY=Year, MM=Month, DD=Day */
-
-#if defined(__COMO__)
-# define COMPILER_ID "Comeau"
- /* __COMO_VERSION__ = VRR */
-# define COMPILER_VERSION_MAJOR DEC(__COMO_VERSION__ / 100)
-# define COMPILER_VERSION_MINOR DEC(__COMO_VERSION__ % 100)
-
-#elif defined(__INTEL_COMPILER) || defined(__ICC)
-# define COMPILER_ID "Intel"
- /* __INTEL_COMPILER = VRP */
-# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100)
-# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10)
-# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10)
-# if defined(__INTEL_COMPILER_BUILD_DATE)
- /* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */
-# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE)
-# endif
-
-#elif defined(__PATHCC__)
-# define COMPILER_ID "PathScale"
-# define COMPILER_VERSION_MAJOR DEC(__PATHCC__)
-# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__)
-# if defined(__PATHCC_PATCHLEVEL__)
-# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__)
-# endif
-
-#elif defined(__clang__)
-# define COMPILER_ID "Clang"
-# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
-# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
-# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
-
-#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__)
-# define COMPILER_ID "Embarcadero"
-# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF)
-# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF)
-# define COMPILER_VERSION_PATCH HEX(__CODEGEARC_VERSION__ & 0xFFFF)
-
-#elif defined(__BORLANDC__)
-# define COMPILER_ID "Borland"
- /* __BORLANDC__ = 0xVRR */
-# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8)
-# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF)
-
-#elif defined(__WATCOMC__)
-# define COMPILER_ID "Watcom"
- /* __WATCOMC__ = VVRR */
-# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100)
-# define COMPILER_VERSION_MINOR DEC(__WATCOMC__ % 100)
-
-#elif defined(__SUNPRO_CC)
-# define COMPILER_ID "SunPro"
-# if __SUNPRO_CC >= 0x5100
- /* __SUNPRO_CC = 0xVRRP */
-# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>12)
-# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xFF)
-# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF)
-# else
- /* __SUNPRO_CC = 0xVRP */
-# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>8)
-# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xF)
-# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF)
-# endif
-
-#elif defined(__HP_aCC)
-# define COMPILER_ID "HP"
- /* __HP_aCC = VVRRPP */
-# define COMPILER_VERSION_MAJOR DEC(__HP_aCC/10000)
-# define COMPILER_VERSION_MINOR DEC(__HP_aCC/100 % 100)
-# define COMPILER_VERSION_PATCH DEC(__HP_aCC % 100)
-
-#elif defined(__DECCXX)
-# define COMPILER_ID "Compaq"
- /* __DECCXX_VER = VVRRTPPPP */
-# define COMPILER_VERSION_MAJOR DEC(__DECCXX_VER/10000000)
-# define COMPILER_VERSION_MINOR DEC(__DECCXX_VER/100000 % 100)
-# define COMPILER_VERSION_PATCH DEC(__DECCXX_VER % 10000)
-
-#elif defined(__IBMCPP__)
-# if defined(__COMPILER_VER__)
-# define COMPILER_ID "zOS"
-# else
-# if __IBMCPP__ >= 800
-# define COMPILER_ID "XL"
-# else
-# define COMPILER_ID "VisualAge"
-# endif
- /* __IBMCPP__ = VRP */
-# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
-# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
-# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
-# endif
-
-#elif defined(__PGI)
-# define COMPILER_ID "PGI"
-# define COMPILER_VERSION_MAJOR DEC(__PGIC__)
-# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__)
-# if defined(__PGIC_PATCHLEVEL__)
-# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__)
-# endif
-
-#elif defined(_CRAYC)
-# define COMPILER_ID "Cray"
-# define COMPILER_VERSION_MAJOR DEC(_RELEASE)
-# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR)
-
-#elif defined(__TI_COMPILER_VERSION__)
-# define COMPILER_ID "TI"
- /* __TI_COMPILER_VERSION__ = VVVRRRPPP */
-# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000)
-# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000)
-# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000)
-
-#elif defined(__SCO_VERSION__)
-# define COMPILER_ID "SCO"
-
-#elif defined(__GNUC__)
-# define COMPILER_ID "GNU"
-# define COMPILER_VERSION_MAJOR DEC(__GNUC__)
-# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__)
-# if defined(__GNUC_PATCHLEVEL__)
-# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
-# endif
-
-#elif defined(_MSC_VER)
-# define COMPILER_ID "MSVC"
- /* _MSC_VER = VVRR */
-# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100)
-# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100)
-# if defined(_MSC_FULL_VER)
-# if _MSC_VER >= 1400
- /* _MSC_FULL_VER = VVRRPPPPP */
-# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000)
-# else
- /* _MSC_FULL_VER = VVRRPPPP */
-# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000)
-# endif
-# endif
-# if defined(_MSC_BUILD)
-# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD)
-# endif
-
-/* Analog VisualDSP++ >= 4.5.6 */
-#elif defined(__VISUALDSPVERSION__)
-# define COMPILER_ID "ADSP"
- /* __VISUALDSPVERSION__ = 0xVVRRPP00 */
-# define COMPILER_VERSION_MAJOR HEX(__VISUALDSPVERSION__>>24)
-# define COMPILER_VERSION_MINOR HEX(__VISUALDSPVERSION__>>16 & 0xFF)
-# define COMPILER_VERSION_PATCH HEX(__VISUALDSPVERSION__>>8 & 0xFF)
-
-/* Analog VisualDSP++ < 4.5.6 */
-#elif defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__)
-# define COMPILER_ID "ADSP"
-
-/* IAR Systems compiler for embedded systems.
- http://www.iar.com */
-#elif defined(__IAR_SYSTEMS_ICC__ ) || defined(__IAR_SYSTEMS_ICC)
-# define COMPILER_ID "IAR"
-
-#elif defined(_SGI_COMPILER_VERSION) || defined(_COMPILER_VERSION)
-# define COMPILER_ID "MIPSpro"
-# if defined(_SGI_COMPILER_VERSION)
- /* _SGI_COMPILER_VERSION = VRP */
-# define COMPILER_VERSION_MAJOR DEC(_SGI_COMPILER_VERSION/100)
-# define COMPILER_VERSION_MINOR DEC(_SGI_COMPILER_VERSION/10 % 10)
-# define COMPILER_VERSION_PATCH DEC(_SGI_COMPILER_VERSION % 10)
-# else
- /* _COMPILER_VERSION = VRP */
-# define COMPILER_VERSION_MAJOR DEC(_COMPILER_VERSION/100)
-# define COMPILER_VERSION_MINOR DEC(_COMPILER_VERSION/10 % 10)
-# define COMPILER_VERSION_PATCH DEC(_COMPILER_VERSION % 10)
-# endif
-
-/* This compiler is either not known or is too old to define an
- identification macro. Try to identify the platform and guess that
- it is the native compiler. */
-#elif defined(__sgi)
-# define COMPILER_ID "MIPSpro"
-
-#elif defined(__hpux) || defined(__hpua)
-# define COMPILER_ID "HP"
-
-#else /* unknown compiler */
-# define COMPILER_ID ""
-
-#endif
+@CMAKE_CXX_COMPILER_ID_CONTENT@
/* Construct the string literal in pieces to prevent the source from
getting matched. Store it in a pointer rather than an array
because some compilers will just produce instructions to fill the
array rather than assigning a pointer to a static array. */
char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
+#ifdef SIMULATE_ID
+char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]";
+#endif
+
+#ifdef __QNXNTO__
+char const* qnxnto = "INFO" ":" "qnxnto[]";
+#endif
+
+#if defined(__CRAYXE) || defined(__CRAYXC)
+char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]";
+#endif
@CMAKE_CXX_COMPILER_ID_PLATFORM_CONTENT@
+@CMAKE_CXX_COMPILER_ID_ERROR_FOR_TEST@
+
+const char* info_language_dialect_default = "INFO" ":" "dialect_default["
+#if __cplusplus >= 201402L
+ "14"
+#elif __cplusplus >= 201103L
+ "11"
+#else
+ "98"
+#endif
+"]";
/*--------------------------------------------------------------------------*/
@@ -212,6 +47,16 @@ int main(int argc, char* argv[])
#ifdef COMPILER_VERSION_MAJOR
require += info_version[argc];
#endif
+#ifdef SIMULATE_ID
+ require += info_simulate[argc];
+#endif
+#ifdef SIMULATE_VERSION_MAJOR
+ require += info_simulate_version[argc];
+#endif
+#if defined(__CRAYXE) || defined(__CRAYXC)
+ require += info_cray[argc];
+#endif
+ require += info_language_dialect_default[argc];
(void)argv;
return require;
}
diff --git a/Modules/CMakeCXXInformation.cmake b/Modules/CMakeCXXInformation.cmake
index 933c15a82..b35280f96 100644
--- a/Modules/CMakeCXXInformation.cmake
+++ b/Modules/CMakeCXXInformation.cmake
@@ -18,6 +18,8 @@
# It also loads a system - compiler - processor (or target hardware)
# specific file, which is mainly useful for crosscompiling and embedded systems.
+include(CMakeLanguageInformation)
+
# some compilers use different extensions (e.g. sdcc uses .rel)
# so set the extension here first so it can be overridden by the compiler specific file
if(UNIX)
@@ -34,7 +36,7 @@ if(CMAKE_CXX_COMPILER_ID)
endif()
set(CMAKE_BASE_NAME)
-get_filename_component(CMAKE_BASE_NAME ${CMAKE_CXX_COMPILER} NAME_WE)
+get_filename_component(CMAKE_BASE_NAME "${CMAKE_CXX_COMPILER}" NAME_WE)
# since the gnu compiler has several names force g++
if(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_BASE_NAME g++)
@@ -59,6 +61,12 @@ if (NOT _INCLUDED_FILE)
include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME} OPTIONAL
RESULT_VARIABLE _INCLUDED_FILE)
endif ()
+
+# load any compiler-wrapper specific information
+if (CMAKE_CXX_COMPILER_WRAPPER)
+ __cmake_include_compiler_wrapper(CXX)
+endif ()
+
# We specify the compiler information in the system file for some
# platforms, but this language may not have been enabled when the file
# was first included. Include it again to get the language info.
@@ -209,17 +217,17 @@ if(NOT CMAKE_NOT_USING_CONFIG_FLAGS)
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG_INIT}" CACHE STRING
"Flags used by the compiler during debug builds.")
set (CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL_INIT}" CACHE STRING
- "Flags used by the compiler during release minsize builds.")
+ "Flags used by the compiler during release builds for minimum size.")
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE_INIT}" CACHE STRING
- "Flags used by the compiler during release builds (/MD /Ob1 /Oi /Ot /Oy /Gs will produce slightly less optimized but smaller files).")
+ "Flags used by the compiler during release builds.")
set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT}" CACHE STRING
- "Flags used by the compiler during Release with Debug Info builds.")
+ "Flags used by the compiler during release builds with debug info.")
endif()
if(CMAKE_CXX_STANDARD_LIBRARIES_INIT)
set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES_INIT}"
- CACHE STRING "Libraries linked by defalut with all C++ applications.")
+ CACHE STRING "Libraries linked by default with all C++ applications.")
mark_as_advanced(CMAKE_CXX_STANDARD_LIBRARIES)
endif()
@@ -266,10 +274,10 @@ endif()
# Create a static archive incrementally for large object file counts.
# If CMAKE_CXX_CREATE_STATIC_LIBRARY is set it will override these.
if(NOT DEFINED CMAKE_CXX_ARCHIVE_CREATE)
- set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> cr <TARGET> <LINK_FLAGS> <OBJECTS>")
+ set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
endif()
if(NOT DEFINED CMAKE_CXX_ARCHIVE_APPEND)
- set(CMAKE_CXX_ARCHIVE_APPEND "<CMAKE_AR> r <TARGET> <LINK_FLAGS> <OBJECTS>")
+ set(CMAKE_CXX_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
endif()
if(NOT DEFINED CMAKE_CXX_ARCHIVE_FINISH)
set(CMAKE_CXX_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
@@ -278,7 +286,7 @@ endif()
# compile a C++ file into an object file
if(NOT CMAKE_CXX_COMPILE_OBJECT)
set(CMAKE_CXX_COMPILE_OBJECT
- "<CMAKE_CXX_COMPILER> <DEFINES> <FLAGS> -o <OBJECT> -c <SOURCE>")
+ "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
endif()
if(NOT CMAKE_CXX_LINK_EXECUTABLE)
@@ -287,7 +295,6 @@ if(NOT CMAKE_CXX_LINK_EXECUTABLE)
endif()
mark_as_advanced(
-CMAKE_BUILD_TOOL
CMAKE_VERBOSE_MAKEFILE
CMAKE_CXX_FLAGS
CMAKE_CXX_FLAGS_RELEASE
diff --git a/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake b/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake
new file mode 100644
index 000000000..07d8b1e3f
--- /dev/null
+++ b/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake
@@ -0,0 +1,45 @@
+
+#=============================================================================
+# Copyright 2006-2011 Kitware, Inc.
+# Copyright 2006 Alexander Neundorf <neundorf@kde.org>
+# Copyright 2011 Matthias Kretz <kretz@kde.org>
+# Copyright 2013 Rolf Eike Beer <eike@sf-mail.de>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# Do NOT include this module directly into any of your code. It is meant as
+# a library for Check*CompilerFlag.cmake modules. It's content may change in
+# any way between releases.
+
+macro (CHECK_COMPILER_FLAG_COMMON_PATTERNS _VAR)
+ set(${_VAR}
+ FAIL_REGEX "[Uu]nrecogni[sz]ed .*option" # GNU, NAG
+ FAIL_REGEX "unknown .*option" # Clang
+ FAIL_REGEX "optimization flag .* not supported" # Clang
+ FAIL_REGEX "ignoring unknown option" # MSVC, Intel
+ FAIL_REGEX "warning D9002" # MSVC, any lang
+ FAIL_REGEX "option.*not supported" # Intel
+ FAIL_REGEX "invalid argument .*option" # Intel
+ FAIL_REGEX "ignoring option .*argument required" # Intel
+ FAIL_REGEX "ignoring option .*argument is of wrong type" # Intel
+ FAIL_REGEX "[Uu]nknown option" # HP
+ FAIL_REGEX "[Ww]arning: [Oo]ption" # SunPro
+ FAIL_REGEX "command option .* is not recognized" # XL
+ FAIL_REGEX "command option .* contains an incorrect subargument" # XL
+ FAIL_REGEX "not supported in this configuration. ignored" # AIX
+ FAIL_REGEX "File with unknown suffix passed to linker" # PGI
+ FAIL_REGEX "[Uu]nknown switch" # PGI
+ FAIL_REGEX "WARNING: unknown flag:" # Open64
+ FAIL_REGEX "Incorrect command line option:" # Borland
+ FAIL_REGEX "Warning: illegal option" # SunStudio 12
+ FAIL_REGEX "[Ww]arning: Invalid suboption" # Fujitsu
+ )
+endmacro ()
diff --git a/Modules/CMakeClDeps.cmake b/Modules/CMakeClDeps.cmake
deleted file mode 100644
index 0214ead2b..000000000
--- a/Modules/CMakeClDeps.cmake
+++ /dev/null
@@ -1,34 +0,0 @@
-
-#=============================================================================
-# Copyright 2012 Kitware, Inc.
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-# (To distribute this file outside of CMake, substitute the full
-# License text for the above reference.)
-
-#
-# When using Ninja cl.exe is wrapped by cmcldeps to extract the included
-# headers for dependency tracking.
-#
-# cmcldeps path is set, and cmcldeps needs to know the localized string
-# in front of each include path, so it can remove it.
-#
-
-if(MSVC_C_ARCHITECTURE_ID AND CMAKE_GENERATOR MATCHES "Ninja" AND CMAKE_C_COMPILER AND CMAKE_COMMAND)
- string(REPLACE "cmake.exe" "cmcldeps.exe" CMAKE_CMCLDEPS_EXECUTABLE ${CMAKE_COMMAND})
- set(showdir ${CMAKE_BINARY_DIR}/CMakeFiles/ShowIncludes)
- file(WRITE ${showdir}/foo.h "\n")
- file(WRITE ${showdir}/main.c "#include \"foo.h\" \nint main(){}\n")
- execute_process(COMMAND ${CMAKE_C_COMPILER} /nologo /showIncludes ${showdir}/main.c
- WORKING_DIRECTORY ${showdir} OUTPUT_VARIABLE outLine)
- string(REGEX MATCH "\n([^:]*:[^:]*:[ \t]*)" tmp "${outLine}")
- set(localizedPrefix "${CMAKE_MATCH_1}")
- set(SET_CMAKE_CMCLDEPS_EXECUTABLE "set(CMAKE_CMCLDEPS_EXECUTABLE \"${CMAKE_CMCLDEPS_EXECUTABLE}\")")
- set(SET_CMAKE_CL_SHOWINCLUDE_PREFIX "set(CMAKE_CL_SHOWINCLUDE_PREFIX \"${localizedPrefix}\")")
-endif()
diff --git a/Modules/CMakeCommonLanguageInclude.cmake b/Modules/CMakeCommonLanguageInclude.cmake
index e945aa7c8..fa025a892 100644
--- a/Modules/CMakeCommonLanguageInclude.cmake
+++ b/Modules/CMakeCommonLanguageInclude.cmake
@@ -16,9 +16,11 @@
# cache values that can be initialized in the platform-compiler.cmake file
# it may be included by more than one language.
-set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS_INIT} $ENV{LDFLAGS}"
- CACHE STRING "Flags used by the linker.")
-
+if(NOT "x$ENV{LDFLAGS}" STREQUAL "x")
+ set (CMAKE_EXE_LINKER_FLAGS_INIT "${CMAKE_EXE_LINKER_FLAGS_INIT} $ENV{LDFLAGS}")
+ set (CMAKE_SHARED_LINKER_FLAGS_INIT "${CMAKE_SHARED_LINKER_FLAGS_INIT} $ENV{LDFLAGS}")
+ set (CMAKE_MODULE_LINKER_FLAGS_INIT "${CMAKE_MODULE_LINKER_FLAGS_INIT} $ENV{LDFLAGS}")
+endif()
if(NOT CMAKE_NOT_USING_CONFIG_FLAGS)
# default build type is none
@@ -82,24 +84,27 @@ if(NOT CMAKE_NOT_USING_CONFIG_FLAGS)
${CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO_INIT} CACHE STRING
"Flags used by the linker during Release with Debug Info builds.")
endif()
+
+# executable linker flags
+set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS_INIT}"
+ CACHE STRING "Flags used by the linker.")
+
# shared linker flags
-set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS_INIT} $ENV{LDFLAGS}"
+set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS_INIT}"
CACHE STRING "Flags used by the linker during the creation of dll's.")
# module linker flags
-set (CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS_INIT} $ENV{LDFLAGS}"
+set (CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS_INIT}"
CACHE STRING "Flags used by the linker during the creation of modules.")
# static linker flags
set (CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS_INIT}"
CACHE STRING "Flags used by the linker during the creation of static libraries.")
-set(CMAKE_BUILD_TOOL ${CMAKE_MAKE_PROGRAM} CACHE INTERNAL
- "What is the target build tool cmake is generating for.")
-
+# Alias the build tool variable for backward compatibility.
+set(CMAKE_BUILD_TOOL ${CMAKE_MAKE_PROGRAM})
mark_as_advanced(
-CMAKE_BUILD_TOOL
CMAKE_VERBOSE_MAKEFILE
CMAKE_EXE_LINKER_FLAGS
@@ -126,4 +131,3 @@ CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL
CMAKE_STATIC_LINKER_FLAGS_RELEASE
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO
)
-
diff --git a/Modules/CMakeCompilerIdDetection.cmake b/Modules/CMakeCompilerIdDetection.cmake
new file mode 100644
index 000000000..cbc005570
--- /dev/null
+++ b/Modules/CMakeCompilerIdDetection.cmake
@@ -0,0 +1,158 @@
+
+#=============================================================================
+# Copyright 2014 Stephen Kelly <steveire@gmail.com>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+function(_readFile file)
+ include(${file})
+ get_filename_component(name ${file} NAME_WE)
+ string(REGEX REPLACE "-.*" "" CompilerId ${name})
+ set(_compiler_id_version_compute_${CompilerId} ${_compiler_id_version_compute} PARENT_SCOPE)
+ set(_compiler_id_simulate_${CompilerId} ${_compiler_id_simulate} PARENT_SCOPE)
+ set(_compiler_id_pp_test_${CompilerId} ${_compiler_id_pp_test} PARENT_SCOPE)
+endfunction()
+
+include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake)
+
+function(compiler_id_detection outvar lang)
+
+ if (NOT lang STREQUAL Fortran)
+ file(GLOB lang_files
+ "${CMAKE_ROOT}/Modules/Compiler/*-DetermineCompiler.cmake")
+ set(nonlang CXX)
+ if (lang STREQUAL CXX)
+ set(nonlang C)
+ endif()
+
+ file(GLOB nonlang_files
+ "${CMAKE_ROOT}/Modules/Compiler/*-${nonlang}-DetermineCompiler.cmake")
+ list(REMOVE_ITEM lang_files ${nonlang_files})
+ endif()
+
+ set(files ${lang_files})
+ if (files)
+ foreach(file ${files})
+ _readFile(${file})
+ endforeach()
+
+ set(options ID_STRING VERSION_STRINGS ID_DEFINE PLATFORM_DEFAULT_COMPILER)
+ set(oneValueArgs PREFIX)
+ cmake_parse_arguments(CID "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+ if (CID_UNPARSED_ARGUMENTS)
+ message(FATAL_ERROR "Unrecognized arguments: \"${CID_UNPARSED_ARGUMENTS}\"")
+ endif()
+
+ # Order is relevant here. For example, compilers which pretend to be
+ # GCC must appear before the actual GCC.
+ if (lang STREQUAL CXX)
+ list(APPEND ordered_compilers
+ Comeau
+ )
+ endif()
+ list(APPEND ordered_compilers
+ Intel
+ PathScale
+ Embarcadero
+ Borland
+ Watcom
+ OpenWatcom
+ SunPro
+ HP
+ Compaq
+ zOS
+ XL
+ VisualAge
+ PGI
+ Cray
+ TI
+ Fujitsu
+ )
+ if (lang STREQUAL C)
+ list(APPEND ordered_compilers
+ TinyCC
+ )
+ endif()
+ list(APPEND ordered_compilers
+ SCO
+ AppleClang
+ Clang
+ GNU
+ MSVC
+ ADSP
+ IAR
+ ARMCC
+ )
+ if (lang STREQUAL C)
+ list(APPEND ordered_compilers
+ SDCC
+ )
+ endif()
+ list(APPEND ordered_compilers
+ MIPSpro)
+
+ if(CID_ID_DEFINE)
+ foreach(Id ${ordered_compilers})
+ set(CMAKE_${lang}_COMPILER_ID_CONTENT "${CMAKE_${lang}_COMPILER_ID_CONTENT}# define ${CID_PREFIX}COMPILER_IS_${Id} 0\n")
+ endforeach()
+ endif()
+
+ set(pp_if "#if")
+ if (CID_VERSION_STRINGS)
+ set(CMAKE_${lang}_COMPILER_ID_CONTENT "${CMAKE_${lang}_COMPILER_ID_CONTENT}\n/* Version number components: V=Version, R=Revision, P=Patch
+ Version date components: YYYY=Year, MM=Month, DD=Day */\n")
+ endif()
+
+ foreach(Id ${ordered_compilers})
+ if (NOT _compiler_id_pp_test_${Id})
+ message(FATAL_ERROR "No preprocessor test for \"${Id}\"")
+ endif()
+ set(id_content "${pp_if} ${_compiler_id_pp_test_${Id}}\n")
+ if (CID_ID_STRING)
+ set(PREFIX ${CID_PREFIX})
+ string(CONFIGURE "${_compiler_id_simulate_${Id}}" SIMULATE_BLOCK @ONLY)
+ set(id_content "${id_content}# define ${CID_PREFIX}COMPILER_ID \"${Id}\"${SIMULATE_BLOCK}")
+ endif()
+ if (CID_ID_DEFINE)
+ set(id_content "${id_content}# undef ${CID_PREFIX}COMPILER_IS_${Id}\n")
+ set(id_content "${id_content}# define ${CID_PREFIX}COMPILER_IS_${Id} 1\n")
+ endif()
+ if (CID_VERSION_STRINGS)
+ set(PREFIX ${CID_PREFIX})
+ set(MACRO_DEC DEC)
+ set(MACRO_HEX HEX)
+ string(CONFIGURE "${_compiler_id_version_compute_${Id}}" VERSION_BLOCK @ONLY)
+ set(id_content "${id_content}${VERSION_BLOCK}\n")
+ endif()
+ set(CMAKE_${lang}_COMPILER_ID_CONTENT "${CMAKE_${lang}_COMPILER_ID_CONTENT}\n${id_content}")
+ set(pp_if "#elif")
+ endforeach()
+
+ if (CID_PLATFORM_DEFAULT_COMPILER)
+ set(platform_compiler_detection "
+/* These compilers are either not known or too old to define an
+ identification macro. Try to identify the platform and guess that
+ it is the native compiler. */
+#elif defined(__sgi)
+# define ${CID_PREFIX}COMPILER_ID \"MIPSpro\"
+
+#elif defined(__hpux) || defined(__hpua)
+# define ${CID_PREFIX}COMPILER_ID \"HP\"
+
+#else /* unknown compiler */
+# define ${CID_PREFIX}COMPILER_ID \"\"")
+ endif()
+
+ set(CMAKE_${lang}_COMPILER_ID_CONTENT "${CMAKE_${lang}_COMPILER_ID_CONTENT}\n${platform_compiler_detection}\n#endif")
+ endif()
+
+ set(${outvar} ${CMAKE_${lang}_COMPILER_ID_CONTENT} PARENT_SCOPE)
+endfunction()
diff --git a/Modules/CMakeConfigurableFile.in b/Modules/CMakeConfigurableFile.in
index 4cf74a12b..df2c382e9 100644
--- a/Modules/CMakeConfigurableFile.in
+++ b/Modules/CMakeConfigurableFile.in
@@ -1,2 +1 @@
@CMAKE_CONFIGURABLE_FILE_CONTENT@
-
diff --git a/Modules/CMakeDependentOption.cmake b/Modules/CMakeDependentOption.cmake
index 990728f9f..7e9f183f1 100644
--- a/Modules/CMakeDependentOption.cmake
+++ b/Modules/CMakeDependentOption.cmake
@@ -1,15 +1,23 @@
-# - Macro to provide an option dependent on other options.
+#.rst:
+# CMakeDependentOption
+# --------------------
+#
+# Macro to provide an option dependent on other options.
+#
# This macro presents an option to the user only if a set of other
-# conditions are true. When the option is not presented a default
-# value is used, but any value set by the user is preserved for when
-# the option is presented again.
-# Example invocation:
-# CMAKE_DEPENDENT_OPTION(USE_FOO "Use Foo" ON
-# "USE_BAR;NOT USE_ZOT" OFF)
-# If USE_BAR is true and USE_ZOT is false, this provides an option called
-# USE_FOO that defaults to ON. Otherwise, it sets USE_FOO to OFF. If
-# the status of USE_BAR or USE_ZOT ever changes, any value for the
-# USE_FOO option is saved so that when the option is re-enabled it
+# conditions are true. When the option is not presented a default value
+# is used, but any value set by the user is preserved for when the
+# option is presented again. Example invocation:
+#
+# ::
+#
+# CMAKE_DEPENDENT_OPTION(USE_FOO "Use Foo" ON
+# "USE_BAR;NOT USE_ZOT" OFF)
+#
+# If USE_BAR is true and USE_ZOT is false, this provides an option
+# called USE_FOO that defaults to ON. Otherwise, it sets USE_FOO to
+# OFF. If the status of USE_BAR or USE_ZOT ever changes, any value for
+# the USE_FOO option is saved so that when the option is re-enabled it
# retains its old value.
#=============================================================================
diff --git a/Modules/CMakeDetermineASMCompiler.cmake b/Modules/CMakeDetermineASMCompiler.cmake
index 0fecb5db6..91111d299 100644
--- a/Modules/CMakeDetermineASMCompiler.cmake
+++ b/Modules/CMakeDetermineASMCompiler.cmake
@@ -18,7 +18,7 @@ include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake)
if(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER)
# prefer the environment variable ASM
- if($ENV{ASM${ASM_DIALECT}} MATCHES ".+")
+ if(NOT $ENV{ASM${ASM_DIALECT}} STREQUAL "")
set(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT "$ENV{ASM${ASM_DIALECT}}")
endif()
@@ -48,22 +48,7 @@ if(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER)
_cmake_find_compiler(ASM${ASM_DIALECT})
else()
-
- # we only get here if CMAKE_ASM${ASM_DIALECT}_COMPILER was specified using -D or a pre-made CMakeCache.txt
- # (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE
- #
- # if a compiler was specified by the user but without path,
- # now try to find it with the full path
- # if it is found, force it into the cache,
- # if not, don't overwrite the setting (which was given by the user) with "NOTFOUND"
- get_filename_component(_CMAKE_USER_ASM${ASM_DIALECT}_COMPILER_PATH "${CMAKE_ASM${ASM_DIALECT}_COMPILER}" PATH)
- if(NOT _CMAKE_USER_ASM${ASM_DIALECT}_COMPILER_PATH)
- find_program(CMAKE_ASM${ASM_DIALECT}_COMPILER_WITH_PATH NAMES ${CMAKE_ASM${ASM_DIALECT}_COMPILER})
- mark_as_advanced(CMAKE_ASM${ASM_DIALECT}_COMPILER_WITH_PATH)
- if(CMAKE_ASM${ASM_DIALECT}_COMPILER_WITH_PATH)
- set(CMAKE_ASM${ASM_DIALECT}_COMPILER ${CMAKE_ASM${ASM_DIALECT}_COMPILER_WITH_PATH} CACHE FILEPATH "Assembler" FORCE)
- endif()
- endif()
+ _cmake_find_compiler_path(ASM${ASM_DIALECT})
endif()
mark_as_advanced(CMAKE_ASM${ASM_DIALECT}_COMPILER)
@@ -107,6 +92,10 @@ if(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER_ID)
set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_IAR )
set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_IAR "IAR Assembler")
+ list(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS ARMCC)
+ set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_ARMCC )
+ set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_ARMCC "(ARM Compiler)|(ARM Assembler)")
+
include(CMakeDetermineCompilerId)
CMAKE_DETERMINE_COMPILER_ID_VENDOR(ASM${ASM_DIALECT})
@@ -124,7 +113,7 @@ endif()
# e.g. powerpc-linux-gas, arm-elf-gas or i586-mingw32msvc-gas , optionally
# with a 3-component version number at the end
# The other tools of the toolchain usually have the same prefix
-# NAME_WE cannot be used since then this test will fail for names lile
+# NAME_WE cannot be used since then this test will fail for names like
# "arm-unknown-nto-qnx6.3.0-gas.exe", where BASENAME would be
# "arm-unknown-nto-qnx6" instead of the correct "arm-unknown-nto-qnx6.3.0-"
if (NOT _CMAKE_TOOLCHAIN_PREFIX)
@@ -167,7 +156,7 @@ set(_CMAKE_ASM_COMPILER_ENV_VAR "${CMAKE_ASM${ASM_DIALECT}_COMPILER_ENV_VAR}")
# configure variables set in this file for fast reload later on
configure_file(${CMAKE_ROOT}/Modules/CMakeASMCompiler.cmake.in
- ${CMAKE_PLATFORM_INFO_DIR}/CMakeASM${ASM_DIALECT}Compiler.cmake IMMEDIATE @ONLY)
+ ${CMAKE_PLATFORM_INFO_DIR}/CMakeASM${ASM_DIALECT}Compiler.cmake @ONLY)
set(_CMAKE_ASM_COMPILER)
set(_CMAKE_ASM_COMPILER_ARG1)
diff --git a/Modules/CMakeDetermineASM_MASMCompiler.cmake b/Modules/CMakeDetermineASM_MASMCompiler.cmake
index 665a65cc5..142ef950a 100644
--- a/Modules/CMakeDetermineASM_MASMCompiler.cmake
+++ b/Modules/CMakeDetermineASM_MASMCompiler.cmake
@@ -17,7 +17,8 @@
set(ASM_DIALECT "_MASM")
# if we are using the 64bit cl compiler, assume we also want the 64bit assembler
-if(CMAKE_CL_64)
+if(";${CMAKE_VS_PLATFORM_NAME};${MSVC_C_ARCHITECTURE_ID};${MSVC_CXX_ARCHITECTURE_ID};"
+ MATCHES ";(Win64|Itanium|x64|IA64);")
set(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT ml64)
else()
set(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT ml)
diff --git a/Modules/CMakeDetermineCCompiler.cmake b/Modules/CMakeDetermineCCompiler.cmake
index 8769c668b..e0b54686a 100644
--- a/Modules/CMakeDetermineCCompiler.cmake
+++ b/Modules/CMakeDetermineCCompiler.cmake
@@ -42,12 +42,13 @@ endif()
if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
elseif("${CMAKE_GENERATOR}" MATCHES "Xcode")
set(CMAKE_C_COMPILER_XCODE_TYPE sourcecode.c.c)
+ _cmake_find_compiler_path(C)
else()
if(NOT CMAKE_C_COMPILER)
set(CMAKE_C_COMPILER_INIT NOTFOUND)
# prefer the environment variable CC
- if($ENV{CC} MATCHES ".+")
+ if(NOT $ENV{CC} STREQUAL "")
get_filename_component(CMAKE_C_COMPILER_INIT $ENV{CC} PROGRAM PROGRAM_ARGS CMAKE_C_FLAGS_ENV_INIT)
if(CMAKE_C_FLAGS_ENV_INIT)
set(CMAKE_C_COMPILER_ARG1 "${CMAKE_C_FLAGS_ENV_INIT}" CACHE STRING "First argument to C compiler")
@@ -72,37 +73,14 @@ else()
_cmake_find_compiler(C)
else()
-
- # we only get here if CMAKE_C_COMPILER was specified using -D or a pre-made CMakeCache.txt
- # (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE
- # if CMAKE_C_COMPILER is a list of length 2, use the first item as
- # CMAKE_C_COMPILER and the 2nd one as CMAKE_C_COMPILER_ARG1
-
- list(LENGTH CMAKE_C_COMPILER _CMAKE_C_COMPILER_LIST_LENGTH)
- if("${_CMAKE_C_COMPILER_LIST_LENGTH}" EQUAL 2)
- list(GET CMAKE_C_COMPILER 1 CMAKE_C_COMPILER_ARG1)
- list(GET CMAKE_C_COMPILER 0 CMAKE_C_COMPILER)
- endif()
-
- # if a compiler was specified by the user but without path,
- # now try to find it with the full path
- # if it is found, force it into the cache,
- # if not, don't overwrite the setting (which was given by the user) with "NOTFOUND"
- # if the C compiler already had a path, reuse it for searching the CXX compiler
- get_filename_component(_CMAKE_USER_C_COMPILER_PATH "${CMAKE_C_COMPILER}" PATH)
- if(NOT _CMAKE_USER_C_COMPILER_PATH)
- find_program(CMAKE_C_COMPILER_WITH_PATH NAMES ${CMAKE_C_COMPILER})
- mark_as_advanced(CMAKE_C_COMPILER_WITH_PATH)
- if(CMAKE_C_COMPILER_WITH_PATH)
- set(CMAKE_C_COMPILER ${CMAKE_C_COMPILER_WITH_PATH} CACHE STRING "C compiler" FORCE)
- endif()
- endif()
+ _cmake_find_compiler_path(C)
endif()
mark_as_advanced(CMAKE_C_COMPILER)
# Each entry in this list is a set of extra flags to try
# adding to the compile line to see if it helps produce
# a valid identification file.
+ set(CMAKE_C_COMPILER_ID_TEST_FLAGS_FIRST)
set(CMAKE_C_COMPILER_ID_TEST_FLAGS
# Try compiling to an object file only.
"-c"
@@ -118,25 +96,34 @@ if(NOT CMAKE_C_COMPILER_ID_RUN)
# Try to identify the compiler.
set(CMAKE_C_COMPILER_ID)
+ set(CMAKE_C_PLATFORM_ID)
file(READ ${CMAKE_ROOT}/Modules/CMakePlatformId.h.in
CMAKE_C_COMPILER_ID_PLATFORM_CONTENT)
# The IAR compiler produces weird output.
- # See http://www.cmake.org/Bug/view.php?id=10176#c19598
+ # See https://cmake.org/Bug/view.php?id=10176#c19598
list(APPEND CMAKE_C_COMPILER_ID_VENDORS IAR)
set(CMAKE_C_COMPILER_ID_VENDOR_FLAGS_IAR )
set(CMAKE_C_COMPILER_ID_VENDOR_REGEX_IAR "IAR .+ Compiler")
+ # Match the link line from xcodebuild output of the form
+ # Ld ...
+ # ...
+ # /path/to/cc ...CompilerIdC/...
+ # to extract the compiler front-end for the language.
+ set(CMAKE_C_COMPILER_ID_TOOL_MATCH_REGEX "\nLd[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]*-o[^\r\n]*CompilerIdC/(\\./)?(CompilerIdC.xctest/)?CompilerIdC[ \t\n\\\"]")
+ set(CMAKE_C_COMPILER_ID_TOOL_MATCH_INDEX 2)
+
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
CMAKE_DETERMINE_COMPILER_ID(C CFLAGS CMakeCCompilerId.c)
# Set old compiler and platform id variables.
- if("${CMAKE_C_COMPILER_ID}" MATCHES "GNU")
+ if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
set(CMAKE_COMPILER_IS_GNUCC 1)
endif()
- if("${CMAKE_C_PLATFORM_ID}" MATCHES "MinGW")
+ if(CMAKE_C_PLATFORM_ID MATCHES "MinGW")
set(CMAKE_COMPILER_IS_MINGW 1)
- elseif("${CMAKE_C_PLATFORM_ID}" MATCHES "Cygwin")
+ elseif(CMAKE_C_PLATFORM_ID MATCHES "Cygwin")
set(CMAKE_COMPILER_IS_CYGWIN 1)
endif()
endif()
@@ -149,15 +136,23 @@ endif ()
# e.g. powerpc-linux-gcc, arm-elf-gcc or i586-mingw32msvc-gcc, optionally
# with a 3-component version number at the end (e.g. arm-eabi-gcc-4.5.2).
# The other tools of the toolchain usually have the same prefix
-# NAME_WE cannot be used since then this test will fail for names lile
+# NAME_WE cannot be used since then this test will fail for names like
# "arm-unknown-nto-qnx6.3.0-gcc.exe", where BASENAME would be
# "arm-unknown-nto-qnx6" instead of the correct "arm-unknown-nto-qnx6.3.0-"
if (CMAKE_CROSSCOMPILING AND NOT _CMAKE_TOOLCHAIN_PREFIX)
- if("${CMAKE_C_COMPILER_ID}" MATCHES "GNU")
+ if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
get_filename_component(COMPILER_BASENAME "${CMAKE_C_COMPILER}" NAME)
- if (COMPILER_BASENAME MATCHES "^(.+-)g?cc(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$")
+ if (COMPILER_BASENAME MATCHES "^(.+-)(clang|g?cc)(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$")
set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
+ elseif(CMAKE_C_COMPILER_ID MATCHES "Clang")
+ if(CMAKE_C_COMPILER_TARGET)
+ set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_C_COMPILER_TARGET}-)
+ endif()
+ elseif(COMPILER_BASENAME MATCHES "qcc(\\.exe)?$")
+ if(CMAKE_C_COMPILER_TARGET MATCHES "gcc_nto([^_le]+)(le)?")
+ set(_CMAKE_TOOLCHAIN_PREFIX nto${CMAKE_MATCH_1}-)
+ endif()
endif ()
# if "llvm-" is part of the prefix, remove it, since llvm doesn't have its own binutils
@@ -165,7 +160,7 @@ if (CMAKE_CROSSCOMPILING AND NOT _CMAKE_TOOLCHAIN_PREFIX)
if ("${_CMAKE_TOOLCHAIN_PREFIX}" MATCHES "(.+-)?llvm-$")
set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
endif ()
- elseif("${CMAKE_C_COMPILER_ID}" MATCHES "TI")
+ elseif(CMAKE_C_COMPILER_ID MATCHES "TI")
# TI compilers are named e.g. cl6x, cl470 or armcl.exe
get_filename_component(COMPILER_BASENAME "${CMAKE_C_COMPILER}" NAME)
if (COMPILER_BASENAME MATCHES "^(.+)?cl([^.]+)?(\\.exe)?$")
@@ -176,15 +171,15 @@ if (CMAKE_CROSSCOMPILING AND NOT _CMAKE_TOOLCHAIN_PREFIX)
endif ()
-include(${CMAKE_ROOT}/Modules/CMakeClDeps.cmake)
include(CMakeFindBinUtils)
if(MSVC_C_ARCHITECTURE_ID)
set(SET_MSVC_C_ARCHITECTURE_ID
"set(MSVC_C_ARCHITECTURE_ID ${MSVC_C_ARCHITECTURE_ID})")
endif()
+
# configure variables set in this file for fast reload later on
configure_file(${CMAKE_ROOT}/Modules/CMakeCCompiler.cmake.in
${CMAKE_PLATFORM_INFO_DIR}/CMakeCCompiler.cmake
- @ONLY IMMEDIATE # IMMEDIATE must be here for compatibility mode <= 2.0
+ @ONLY
)
set(CMAKE_C_COMPILER_ENV_VAR "CC")
diff --git a/Modules/CMakeDetermineCXXCompiler.cmake b/Modules/CMakeDetermineCXXCompiler.cmake
index c79ba898d..3c9bbc26a 100644
--- a/Modules/CMakeDetermineCXXCompiler.cmake
+++ b/Modules/CMakeDetermineCXXCompiler.cmake
@@ -41,12 +41,13 @@ endif()
if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
elseif("${CMAKE_GENERATOR}" MATCHES "Xcode")
set(CMAKE_CXX_COMPILER_XCODE_TYPE sourcecode.cpp.cpp)
+ _cmake_find_compiler_path(CXX)
else()
if(NOT CMAKE_CXX_COMPILER)
set(CMAKE_CXX_COMPILER_INIT NOTFOUND)
# prefer the environment variable CXX
- if($ENV{CXX} MATCHES ".+")
+ if(NOT $ENV{CXX} STREQUAL "")
get_filename_component(CMAKE_CXX_COMPILER_INIT $ENV{CXX} PROGRAM PROGRAM_ARGS CMAKE_CXX_FLAGS_ENV_INIT)
if(CMAKE_CXX_FLAGS_ENV_INIT)
set(CMAKE_CXX_COMPILER_ARG1 "${CMAKE_CXX_FLAGS_ENV_INIT}" CACHE STRING "First argument to CXX compiler")
@@ -70,38 +71,14 @@ else()
_cmake_find_compiler(CXX)
else()
-
- # we only get here if CMAKE_CXX_COMPILER was specified using -D or a pre-made CMakeCache.txt
- # (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE
- #
- # if CMAKE_CXX_COMPILER is a list of length 2, use the first item as
- # CMAKE_CXX_COMPILER and the 2nd one as CMAKE_CXX_COMPILER_ARG1
-
- list(LENGTH CMAKE_CXX_COMPILER _CMAKE_CXX_COMPILER_LIST_LENGTH)
- if("${_CMAKE_CXX_COMPILER_LIST_LENGTH}" EQUAL 2)
- list(GET CMAKE_CXX_COMPILER 1 CMAKE_CXX_COMPILER_ARG1)
- list(GET CMAKE_CXX_COMPILER 0 CMAKE_CXX_COMPILER)
- endif()
-
- # if a compiler was specified by the user but without path,
- # now try to find it with the full path
- # if it is found, force it into the cache,
- # if not, don't overwrite the setting (which was given by the user) with "NOTFOUND"
- # if the CXX compiler already had a path, reuse it for searching the C compiler
- get_filename_component(_CMAKE_USER_CXX_COMPILER_PATH "${CMAKE_CXX_COMPILER}" PATH)
- if(NOT _CMAKE_USER_CXX_COMPILER_PATH)
- find_program(CMAKE_CXX_COMPILER_WITH_PATH NAMES ${CMAKE_CXX_COMPILER})
- mark_as_advanced(CMAKE_CXX_COMPILER_WITH_PATH)
- if(CMAKE_CXX_COMPILER_WITH_PATH)
- set(CMAKE_CXX_COMPILER ${CMAKE_CXX_COMPILER_WITH_PATH} CACHE STRING "CXX compiler" FORCE)
- endif()
- endif()
+ _cmake_find_compiler_path(CXX)
endif()
mark_as_advanced(CMAKE_CXX_COMPILER)
# Each entry in this list is a set of extra flags to try
# adding to the compile line to see if it helps produce
# a valid identification file.
+ set(CMAKE_CXX_COMPILER_ID_TEST_FLAGS_FIRST)
set(CMAKE_CXX_COMPILER_ID_TEST_FLAGS
# Try compiling to an object file only.
"-c"
@@ -114,25 +91,34 @@ if(NOT CMAKE_CXX_COMPILER_ID_RUN)
# Try to identify the compiler.
set(CMAKE_CXX_COMPILER_ID)
+ set(CMAKE_CXX_PLATFORM_ID)
file(READ ${CMAKE_ROOT}/Modules/CMakePlatformId.h.in
CMAKE_CXX_COMPILER_ID_PLATFORM_CONTENT)
# The IAR compiler produces weird output.
- # See http://www.cmake.org/Bug/view.php?id=10176#c19598
+ # See https://cmake.org/Bug/view.php?id=10176#c19598
list(APPEND CMAKE_CXX_COMPILER_ID_VENDORS IAR)
set(CMAKE_CXX_COMPILER_ID_VENDOR_FLAGS_IAR )
set(CMAKE_CXX_COMPILER_ID_VENDOR_REGEX_IAR "IAR .+ Compiler")
+ # Match the link line from xcodebuild output of the form
+ # Ld ...
+ # ...
+ # /path/to/cc ...CompilerIdCXX/...
+ # to extract the compiler front-end for the language.
+ set(CMAKE_CXX_COMPILER_ID_TOOL_MATCH_REGEX "\nLd[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]*-o[^\r\n]*CompilerIdCXX/(\\./)?(CompilerIdCXX.xctest/)?CompilerIdCXX[ \t\n\\\"]")
+ set(CMAKE_CXX_COMPILER_ID_TOOL_MATCH_INDEX 2)
+
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
CMAKE_DETERMINE_COMPILER_ID(CXX CXXFLAGS CMakeCXXCompilerId.cpp)
# Set old compiler and platform id variables.
- if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(CMAKE_COMPILER_IS_GNUCXX 1)
endif()
- if("${CMAKE_CXX_PLATFORM_ID}" MATCHES "MinGW")
+ if(CMAKE_CXX_PLATFORM_ID MATCHES "MinGW")
set(CMAKE_COMPILER_IS_MINGW 1)
- elseif("${CMAKE_CXX_PLATFORM_ID}" MATCHES "Cygwin")
+ elseif(CMAKE_CXX_PLATFORM_ID MATCHES "Cygwin")
set(CMAKE_COMPILER_IS_CYGWIN 1)
endif()
endif()
@@ -145,17 +131,25 @@ endif ()
# e.g. powerpc-linux-g++, arm-elf-g++ or i586-mingw32msvc-g++ , optionally
# with a 3-component version number at the end (e.g. arm-eabi-gcc-4.5.2).
# The other tools of the toolchain usually have the same prefix
-# NAME_WE cannot be used since then this test will fail for names lile
+# NAME_WE cannot be used since then this test will fail for names like
# "arm-unknown-nto-qnx6.3.0-gcc.exe", where BASENAME would be
# "arm-unknown-nto-qnx6" instead of the correct "arm-unknown-nto-qnx6.3.0-"
if (CMAKE_CROSSCOMPILING AND NOT _CMAKE_TOOLCHAIN_PREFIX)
- if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
+ if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
get_filename_component(COMPILER_BASENAME "${CMAKE_CXX_COMPILER}" NAME)
- if (COMPILER_BASENAME MATCHES "^(.+-)[gc]\\+\\+(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$")
+ if (COMPILER_BASENAME MATCHES "^(.+-)(clan)?[gc]\\+\\+(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$")
set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
+ elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
+ if(CMAKE_CXX_COMPILER_TARGET)
+ set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_CXX_COMPILER_TARGET}-)
+ endif()
+ elseif(COMPILER_BASENAME MATCHES "QCC(\\.exe)?$")
+ if(CMAKE_CXX_COMPILER_TARGET MATCHES "gcc_nto([^_le]+)(le)?")
+ set(_CMAKE_TOOLCHAIN_PREFIX nto${CMAKE_MATCH_1}-)
+ endif()
endif ()
# if "llvm-" is part of the prefix, remove it, since llvm doesn't have its own binutils
@@ -175,16 +169,16 @@ if (CMAKE_CROSSCOMPILING AND NOT _CMAKE_TOOLCHAIN_PREFIX)
endif ()
-include(${CMAKE_ROOT}/Modules/CMakeClDeps.cmake)
include(CMakeFindBinUtils)
if(MSVC_CXX_ARCHITECTURE_ID)
set(SET_MSVC_CXX_ARCHITECTURE_ID
"set(MSVC_CXX_ARCHITECTURE_ID ${MSVC_CXX_ARCHITECTURE_ID})")
endif()
+
# configure all variables set in this file
configure_file(${CMAKE_ROOT}/Modules/CMakeCXXCompiler.cmake.in
${CMAKE_PLATFORM_INFO_DIR}/CMakeCXXCompiler.cmake
- @ONLY IMMEDIATE # IMMEDIATE must be here for compatibility mode <= 2.0
+ @ONLY
)
set(CMAKE_CXX_COMPILER_ENV_VAR "CXX")
diff --git a/Modules/CMakeDetermineCompileFeatures.cmake b/Modules/CMakeDetermineCompileFeatures.cmake
new file mode 100644
index 000000000..2bb7a74e7
--- /dev/null
+++ b/Modules/CMakeDetermineCompileFeatures.cmake
@@ -0,0 +1,94 @@
+
+#=============================================================================
+# Copyright 2013 Stephen Kelly <steveire@gmail.com>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+function(cmake_determine_compile_features lang)
+
+ if(lang STREQUAL C AND COMMAND cmake_record_c_compile_features)
+ message(STATUS "Detecting ${lang} compile features")
+
+ set(CMAKE_C90_COMPILE_FEATURES)
+ set(CMAKE_C99_COMPILE_FEATURES)
+ set(CMAKE_C11_COMPILE_FEATURES)
+
+ include("${CMAKE_ROOT}/Modules/Internal/FeatureTesting.cmake")
+
+ cmake_record_c_compile_features()
+
+ if(NOT _result EQUAL 0)
+ message(STATUS "Detecting ${lang} compile features - failed")
+ return()
+ endif()
+
+ if (CMAKE_C99_COMPILE_FEATURES AND CMAKE_C11_COMPILE_FEATURES)
+ list(REMOVE_ITEM CMAKE_C11_COMPILE_FEATURES ${CMAKE_C99_COMPILE_FEATURES})
+ endif()
+ if (CMAKE_C90_COMPILE_FEATURES AND CMAKE_C99_COMPILE_FEATURES)
+ list(REMOVE_ITEM CMAKE_C99_COMPILE_FEATURES ${CMAKE_C90_COMPILE_FEATURES})
+ endif()
+
+ if(NOT CMAKE_C_COMPILE_FEATURES)
+ set(CMAKE_C_COMPILE_FEATURES
+ ${CMAKE_C90_COMPILE_FEATURES}
+ ${CMAKE_C99_COMPILE_FEATURES}
+ ${CMAKE_C11_COMPILE_FEATURES}
+ )
+ endif()
+
+ set(CMAKE_C_COMPILE_FEATURES ${CMAKE_C_COMPILE_FEATURES} PARENT_SCOPE)
+ set(CMAKE_C90_COMPILE_FEATURES ${CMAKE_C90_COMPILE_FEATURES} PARENT_SCOPE)
+ set(CMAKE_C99_COMPILE_FEATURES ${CMAKE_C99_COMPILE_FEATURES} PARENT_SCOPE)
+ set(CMAKE_C11_COMPILE_FEATURES ${CMAKE_C11_COMPILE_FEATURES} PARENT_SCOPE)
+
+ message(STATUS "Detecting ${lang} compile features - done")
+
+ elseif(lang STREQUAL CXX AND COMMAND cmake_record_cxx_compile_features)
+ message(STATUS "Detecting ${lang} compile features")
+
+ set(CMAKE_CXX98_COMPILE_FEATURES)
+ set(CMAKE_CXX11_COMPILE_FEATURES)
+ set(CMAKE_CXX14_COMPILE_FEATURES)
+
+ include("${CMAKE_ROOT}/Modules/Internal/FeatureTesting.cmake")
+
+ cmake_record_cxx_compile_features()
+
+ if(NOT _result EQUAL 0)
+ message(STATUS "Detecting ${lang} compile features - failed")
+ return()
+ endif()
+
+ if (CMAKE_CXX11_COMPILE_FEATURES AND CMAKE_CXX14_COMPILE_FEATURES)
+ list(REMOVE_ITEM CMAKE_CXX14_COMPILE_FEATURES ${CMAKE_CXX11_COMPILE_FEATURES})
+ endif()
+ if (CMAKE_CXX98_COMPILE_FEATURES AND CMAKE_CXX11_COMPILE_FEATURES)
+ list(REMOVE_ITEM CMAKE_CXX11_COMPILE_FEATURES ${CMAKE_CXX98_COMPILE_FEATURES})
+ endif()
+
+ if(NOT CMAKE_CXX_COMPILE_FEATURES)
+ set(CMAKE_CXX_COMPILE_FEATURES
+ ${CMAKE_CXX98_COMPILE_FEATURES}
+ ${CMAKE_CXX11_COMPILE_FEATURES}
+ ${CMAKE_CXX14_COMPILE_FEATURES}
+ )
+ endif()
+
+ set(CMAKE_CXX_COMPILE_FEATURES ${CMAKE_CXX_COMPILE_FEATURES} PARENT_SCOPE)
+ set(CMAKE_CXX98_COMPILE_FEATURES ${CMAKE_CXX98_COMPILE_FEATURES} PARENT_SCOPE)
+ set(CMAKE_CXX11_COMPILE_FEATURES ${CMAKE_CXX11_COMPILE_FEATURES} PARENT_SCOPE)
+ set(CMAKE_CXX14_COMPILE_FEATURES ${CMAKE_CXX14_COMPILE_FEATURES} PARENT_SCOPE)
+
+ message(STATUS "Detecting ${lang} compile features - done")
+ endif()
+
+endfunction()
diff --git a/Modules/CMakeDetermineCompiler.cmake b/Modules/CMakeDetermineCompiler.cmake
index f522c4408..85c866276 100644
--- a/Modules/CMakeDetermineCompiler.cmake
+++ b/Modules/CMakeDetermineCompiler.cmake
@@ -65,21 +65,66 @@ macro(_cmake_find_compiler lang)
endif()
find_program(CMAKE_${lang}_COMPILER NAMES ${CMAKE_${lang}_COMPILER_LIST} DOC "${lang} compiler")
if(CMAKE_${lang}_COMPILER_INIT AND NOT CMAKE_${lang}_COMPILER)
- set(CMAKE_${lang}_COMPILER "${CMAKE_${lang}_COMPILER_INIT}" CACHE FILEPATH "${lang} compiler" FORCE)
+ set_property(CACHE CMAKE_${lang}_COMPILER PROPERTY VALUE "${CMAKE_${lang}_COMPILER_INIT}")
endif()
unset(_${lang}_COMPILER_HINTS)
unset(_languages)
# Look for a make tool provided by Xcode
- if(CMAKE_${lang}_COMPILER STREQUAL "CMAKE_${lang}_COMPILER-NOTFOUND" AND CMAKE_HOST_APPLE)
- foreach(comp ${CMAKE_${lang}_COMPILER_LIST})
- execute_process(COMMAND xcrun --find ${comp}
+ if(CMAKE_HOST_APPLE)
+ macro(_query_xcrun compiler_name result_var_keyword result_var)
+ if(NOT "x${result_var_keyword}" STREQUAL "xRESULT_VAR")
+ message(FATAL_ERROR "Bad arguments to macro")
+ endif()
+ execute_process(COMMAND xcrun --find ${compiler_name}
OUTPUT_VARIABLE _xcrun_out OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_VARIABLE _xcrun_err)
- if(_xcrun_out)
- set_property(CACHE CMAKE_${lang}_COMPILER PROPERTY VALUE "${_xcrun_out}")
- break()
+ set("${result_var}" "${_xcrun_out}")
+ endmacro()
+
+ set(xcrun_result)
+ if (CMAKE_${lang}_COMPILER MATCHES "^/usr/bin/(.+)$")
+ _query_xcrun("${CMAKE_MATCH_1}" RESULT_VAR xcrun_result)
+ elseif (CMAKE_${lang}_COMPILER STREQUAL "CMAKE_${lang}_COMPILER-NOTFOUND")
+ foreach(comp ${CMAKE_${lang}_COMPILER_LIST})
+ _query_xcrun("${comp}" RESULT_VAR xcrun_result)
+ if(xcrun_result)
+ break()
+ endif()
+ endforeach()
+ endif()
+ if (xcrun_result)
+ set_property(CACHE CMAKE_${lang}_COMPILER PROPERTY VALUE "${xcrun_result}")
+ endif()
+ endif()
+endmacro()
+
+macro(_cmake_find_compiler_path lang)
+ if(CMAKE_${lang}_COMPILER)
+ # we only get here if CMAKE_${lang}_COMPILER was specified using -D or a pre-made CMakeCache.txt
+ # (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE
+ # if CMAKE_${lang}_COMPILER is a list of length 2, use the first item as
+ # CMAKE_${lang}_COMPILER and the 2nd one as CMAKE_${lang}_COMPILER_ARG1
+ list(LENGTH CMAKE_${lang}_COMPILER _CMAKE_${lang}_COMPILER_LIST_LENGTH)
+ if("${_CMAKE_${lang}_COMPILER_LIST_LENGTH}" EQUAL 2)
+ list(GET CMAKE_${lang}_COMPILER 1 CMAKE_${lang}_COMPILER_ARG1)
+ list(GET CMAKE_${lang}_COMPILER 0 CMAKE_${lang}_COMPILER)
+ endif()
+ unset(_CMAKE_${lang}_COMPILER_LIST_LENGTH)
+
+ # find the compiler in the PATH if necessary
+ get_filename_component(_CMAKE_USER_${lang}_COMPILER_PATH "${CMAKE_${lang}_COMPILER}" PATH)
+ if(NOT _CMAKE_USER_${lang}_COMPILER_PATH)
+ find_program(CMAKE_${lang}_COMPILER_WITH_PATH NAMES ${CMAKE_${lang}_COMPILER})
+ if(CMAKE_${lang}_COMPILER_WITH_PATH)
+ set(CMAKE_${lang}_COMPILER ${CMAKE_${lang}_COMPILER_WITH_PATH})
+ get_property(_CMAKE_${lang}_COMPILER_CACHED CACHE CMAKE_${lang}_COMPILER PROPERTY TYPE)
+ if(_CMAKE_${lang}_COMPILER_CACHED)
+ set(CMAKE_${lang}_COMPILER "${CMAKE_${lang}_COMPILER}" CACHE STRING "${lang} compiler" FORCE)
+ endif()
+ unset(_CMAKE_${lang}_COMPILER_CACHED)
endif()
- endforeach()
+ unset(CMAKE_${lang}_COMPILER_WITH_PATH CACHE)
+ endif()
endif()
endmacro()
diff --git a/Modules/CMakeDetermineCompilerABI.cmake b/Modules/CMakeDetermineCompilerABI.cmake
index 5d35ce378..344ae475d 100644
--- a/Modules/CMakeDetermineCompilerABI.cmake
+++ b/Modules/CMakeDetermineCompilerABI.cmake
@@ -26,15 +26,17 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src)
set(BIN "${CMAKE_PLATFORM_INFO_DIR}/CMakeDetermineCompilerABI_${lang}.bin")
set(CMAKE_FLAGS )
if(DEFINED CMAKE_${lang}_VERBOSE_FLAG)
- set(CMAKE_FLAGS "-DCMAKE_EXE_LINKER_FLAGS=${CMAKE_${lang}_VERBOSE_FLAG}")
+ set(CMAKE_FLAGS "-DEXE_LINKER_FLAGS=${CMAKE_${lang}_VERBOSE_FLAG}")
+ endif()
+ if(NOT "x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xMSVC")
+ # Avoid adding our own platform standard libraries for compilers
+ # from which we might detect implicit link libraries.
+ list(APPEND CMAKE_FLAGS "-DCMAKE_${lang}_STANDARD_LIBRARIES=")
endif()
try_compile(CMAKE_${lang}_ABI_COMPILED
${CMAKE_BINARY_DIR} ${src}
- CMAKE_FLAGS "${CMAKE_FLAGS}"
- "-DCMAKE_${lang}_STANDARD_LIBRARIES="
- # We need ignore these warnings because some platforms need
- # CMAKE_${lang}_STANDARD_LIBRARIES to link properly and we
- # don't care when we are just determining the ABI.
+ CMAKE_FLAGS ${CMAKE_FLAGS}
+ # Ignore unused flags when we are just determining the ABI.
"--no-warn-unused-cli"
OUTPUT_VARIABLE OUTPUT
COPY_FILE "${BIN}"
@@ -50,13 +52,13 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src)
message(STATUS "Detecting ${lang} compiler ABI info - done")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Detecting ${lang} compiler ABI info compiled with the following output:\n${OUTPUT}\n\n")
- file(STRINGS "${BIN}" ABI_STRINGS LIMIT_COUNT 2 REGEX "INFO:[^[]*\\[")
+ file(STRINGS "${BIN}" ABI_STRINGS LIMIT_COUNT 2 REGEX "INFO:[A-Za-z0-9_]+\\[[^]]*\\]")
foreach(info ${ABI_STRINGS})
- if("${info}" MATCHES ".*INFO:sizeof_dptr\\[0*([^]]*)\\].*")
- string(REGEX REPLACE ".*INFO:sizeof_dptr\\[0*([^]]*)\\].*" "\\1" ABI_SIZEOF_DPTR "${info}")
+ if("${info}" MATCHES "INFO:sizeof_dptr\\[0*([^]]*)\\]")
+ set(ABI_SIZEOF_DPTR "${CMAKE_MATCH_1}")
endif()
- if("${info}" MATCHES ".*INFO:abi\\[([^]]*)\\].*")
- string(REGEX REPLACE ".*INFO:abi\\[([^]]*)\\].*" "\\1" ABI_NAME "${info}")
+ if("${info}" MATCHES "INFO:abi\\[([^]]*)\\]")
+ set(ABI_NAME "${CMAKE_MATCH_1}")
endif()
endforeach()
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index dd0c2bdcf..feae1c425 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -27,32 +27,60 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
else()
set(CMAKE_${lang}_COMPILER_ID_FLAGS $ENV{${flagvar}})
endif()
- string(REGEX REPLACE " " ";" CMAKE_${lang}_COMPILER_ID_FLAGS_LIST "${CMAKE_${lang}_COMPILER_ID_FLAGS}")
+ string(REPLACE " " ";" CMAKE_${lang}_COMPILER_ID_FLAGS_LIST "${CMAKE_${lang}_COMPILER_ID_FLAGS}")
# Compute the directory in which to run the test.
set(CMAKE_${lang}_COMPILER_ID_DIR ${CMAKE_PLATFORM_INFO_DIR}/CompilerId${lang})
# Try building with no extra flags and then try each set
# of helper flags. Stop when the compiler is identified.
- foreach(flags "" ${CMAKE_${lang}_COMPILER_ID_TEST_FLAGS})
- if(NOT CMAKE_${lang}_COMPILER_ID)
- CMAKE_DETERMINE_COMPILER_ID_BUILD("${lang}" "${flags}" "${src}")
- foreach(file ${COMPILER_${lang}_PRODUCED_FILES})
- CMAKE_DETERMINE_COMPILER_ID_CHECK("${lang}" "${CMAKE_${lang}_COMPILER_ID_DIR}/${file}" "${src}")
- endforeach()
+ foreach(flags ${CMAKE_${lang}_COMPILER_ID_TEST_FLAGS_FIRST}
+ ""
+ ${CMAKE_${lang}_COMPILER_ID_TEST_FLAGS})
+ CMAKE_DETERMINE_COMPILER_ID_BUILD("${lang}" "${flags}" "${src}")
+ CMAKE_DETERMINE_COMPILER_ID_MATCH_VENDOR("${lang}" "${COMPILER_${lang}_PRODUCED_OUTPUT}")
+ if(CMAKE_${lang}_COMPILER_ID)
+ break()
+ endif()
+ foreach(file ${COMPILER_${lang}_PRODUCED_FILES})
+ CMAKE_DETERMINE_COMPILER_ID_CHECK("${lang}" "${CMAKE_${lang}_COMPILER_ID_DIR}/${file}" "${src}")
+ endforeach()
+ if(CMAKE_${lang}_COMPILER_ID)
+ break()
endif()
endforeach()
# If the compiler is still unknown, try to query its vendor.
- if(NOT CMAKE_${lang}_COMPILER_ID)
+ if(CMAKE_${lang}_COMPILER AND NOT CMAKE_${lang}_COMPILER_ID)
CMAKE_DETERMINE_COMPILER_ID_VENDOR(${lang})
endif()
+ if (COMPILER_QNXNTO AND CMAKE_${lang}_COMPILER_ID STREQUAL "GNU")
+ execute_process(
+ COMMAND "${CMAKE_${lang}_COMPILER}"
+ -V
+ OUTPUT_VARIABLE output ERROR_VARIABLE output
+ RESULT_VARIABLE result
+ TIMEOUT 10
+ )
+ if (output MATCHES "targets available")
+ set(CMAKE_${lang}_COMPILER_ID QCC)
+ # http://community.qnx.com/sf/discussion/do/listPosts/projects.community/discussion.qnx_momentics_community_support.topc3555?_pagenum=2
+ # The qcc driver does not itself have a version.
+ endif()
+ endif()
+
# if the format is unknown after all files have been checked, put "Unknown" in the cache
if(NOT CMAKE_EXECUTABLE_FORMAT)
set(CMAKE_EXECUTABLE_FORMAT "Unknown" CACHE INTERNAL "Executable file format")
endif()
+ if(CMAKE_GENERATOR STREQUAL "Ninja" AND MSVC_${lang}_ARCHITECTURE_ID)
+ CMAKE_DETERMINE_MSVC_SHOWINCLUDES_PREFIX(${lang})
+ else()
+ set(CMAKE_${lang}_CL_SHOWINCLUDES_PREFIX "")
+ endif()
+
# Display the final identification result.
if(CMAKE_${lang}_COMPILER_ID)
if(CMAKE_${lang}_COMPILER_VERSION)
@@ -67,25 +95,39 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
endif()
# Check if compiler id detection gave us the compiler tool.
- if(NOT CMAKE_${lang}_COMPILER)
- if(CMAKE_${lang}_COMPILER_ID_TOOL)
- set(CMAKE_${lang}_COMPILER "${CMAKE_${lang}_COMPILER_ID_TOOL}" PARENT_SCOPE)
- else()
- set(CMAKE_${lang}_COMPILER "CMAKE_${lang}_COMPILER-NOTFOUND" PARENT_SCOPE)
- endif()
+ if(CMAKE_${lang}_COMPILER_ID_TOOL)
+ set(CMAKE_${lang}_COMPILER "${CMAKE_${lang}_COMPILER_ID_TOOL}" PARENT_SCOPE)
+ elseif(NOT CMAKE_${lang}_COMPILER)
+ set(CMAKE_${lang}_COMPILER "CMAKE_${lang}_COMPILER-NOTFOUND" PARENT_SCOPE)
endif()
set(CMAKE_${lang}_COMPILER_ID "${CMAKE_${lang}_COMPILER_ID}" PARENT_SCOPE)
set(CMAKE_${lang}_PLATFORM_ID "${CMAKE_${lang}_PLATFORM_ID}" PARENT_SCOPE)
set(MSVC_${lang}_ARCHITECTURE_ID "${MSVC_${lang}_ARCHITECTURE_ID}"
PARENT_SCOPE)
+ set(CMAKE_${lang}_CL_SHOWINCLUDES_PREFIX "${CMAKE_${lang}_CL_SHOWINCLUDES_PREFIX}" PARENT_SCOPE)
set(CMAKE_${lang}_COMPILER_VERSION "${CMAKE_${lang}_COMPILER_VERSION}" PARENT_SCOPE)
+ set(CMAKE_${lang}_COMPILER_WRAPPER "${CMAKE_${lang}_COMPILER_WRAPPER}" PARENT_SCOPE)
+ set(CMAKE_${lang}_SIMULATE_ID "${CMAKE_${lang}_SIMULATE_ID}" PARENT_SCOPE)
+ set(CMAKE_${lang}_SIMULATE_VERSION "${CMAKE_${lang}_SIMULATE_VERSION}" PARENT_SCOPE)
+ set(CMAKE_${lang}_STANDARD_COMPUTED_DEFAULT "${CMAKE_${lang}_STANDARD_COMPUTED_DEFAULT}" PARENT_SCOPE)
endfunction()
+include(CMakeCompilerIdDetection)
+
#-----------------------------------------------------------------------------
# Function to write the compiler id source file.
function(CMAKE_DETERMINE_COMPILER_ID_WRITE lang src)
- file(READ ${CMAKE_ROOT}/Modules/${src}.in ID_CONTENT_IN)
+ find_file(src_in ${src}.in PATHS ${CMAKE_ROOT}/Modules ${CMAKE_MODULE_PATH} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
+ file(READ ${src_in} ID_CONTENT_IN)
+
+ compiler_id_detection(CMAKE_${lang}_COMPILER_ID_CONTENT ${lang}
+ ID_STRING
+ VERSION_STRINGS
+ PLATFORM_DEFAULT_COMPILER
+ )
+
+ unset(src_in CACHE)
string(CONFIGURE "${ID_CONTENT_IN}" ID_CONTENT_OUT @ONLY)
file(WRITE ${CMAKE_${lang}_COMPILER_ID_DIR}/${src} "${ID_CONTENT_OUT}")
endfunction()
@@ -107,12 +149,30 @@ Id flags: ${testflags}
")
# Compile the compiler identification source.
- if("${CMAKE_GENERATOR}" MATCHES "Visual Studio ([0-9]+)")
+ if(CMAKE_GENERATOR STREQUAL "Visual Studio 6" AND
+ lang STREQUAL "Fortran")
+ set(CMAKE_${lang}_COMPILER_ID_RESULT 1)
+ set(CMAKE_${lang}_COMPILER_ID_OUTPUT "No Intel Fortran in VS 6")
+ elseif("${CMAKE_GENERATOR}" MATCHES "Visual Studio ([0-9]+)")
set(vs_version ${CMAKE_MATCH_1})
set(id_platform ${CMAKE_VS_PLATFORM_NAME})
set(id_lang "${lang}")
set(id_cl cl.exe)
- if(NOT "${vs_version}" VERSION_LESS 10)
+ if(CMAKE_VS_PLATFORM_NAME STREQUAL "Tegra-Android")
+ set(v NsightTegra)
+ set(ext vcxproj)
+ if(lang STREQUAL CXX)
+ set(id_gcc g++)
+ set(id_clang clang++)
+ else()
+ set(id_gcc gcc)
+ set(id_clang clang)
+ endif()
+ elseif(lang STREQUAL Fortran)
+ set(v Intel)
+ set(ext vfproj)
+ set(id_cl ifort.exe)
+ elseif(NOT "${vs_version}" VERSION_LESS 10)
set(v 10)
set(ext vcxproj)
elseif(NOT "${vs_version}" VERSION_LESS 7)
@@ -123,14 +183,38 @@ Id flags: ${testflags}
set(v 6)
set(ext dsp)
endif()
- if("${id_platform}" STREQUAL "Itanium")
- set(id_platform ia64)
- endif()
if(CMAKE_VS_PLATFORM_TOOLSET)
- set(id_toolset "<PlatformToolset>${CMAKE_VS_PLATFORM_TOOLSET}</PlatformToolset>")
+ if(CMAKE_VS_PLATFORM_NAME STREQUAL "Tegra-Android")
+ set(id_toolset "<NdkToolchainVersion>${CMAKE_VS_PLATFORM_TOOLSET}</NdkToolchainVersion>")
+ else()
+ set(id_toolset "<PlatformToolset>${CMAKE_VS_PLATFORM_TOOLSET}</PlatformToolset>")
+ if(CMAKE_VS_PLATFORM_TOOLSET MATCHES "Intel")
+ set(id_cl icl.exe)
+ endif()
+ endif()
else()
set(id_toolset "")
endif()
+ if(CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone")
+ set(id_system "<ApplicationType>Windows Phone</ApplicationType>")
+ elseif(CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
+ set(id_system "<ApplicationType>Windows Store</ApplicationType>")
+ else()
+ set(id_system "")
+ endif()
+ if(id_system AND CMAKE_SYSTEM_VERSION)
+ set(id_system_version "<ApplicationTypeRevision>${CMAKE_SYSTEM_VERSION}</ApplicationTypeRevision>")
+ else()
+ set(id_system_version "")
+ endif()
+ if(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION)
+ set(id_WindowsTargetPlatformVersion "<WindowsTargetPlatformVersion>${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}</WindowsTargetPlatformVersion>")
+ endif()
+ if(id_platform STREQUAL ARM)
+ set(id_WindowsSDKDesktopARMSupport "<WindowsSDKDesktopARMSupport>true</WindowsSDKDesktopARMSupport>")
+ else()
+ set(id_WindowsSDKDesktopARMSupport "")
+ endif()
if(CMAKE_VS_WINCE_VERSION)
set(id_entrypoint "mainACRTStartup")
if("${vs_version}" VERSION_LESS 9)
@@ -141,27 +225,37 @@ Id flags: ${testflags}
else()
set(id_subsystem 1)
endif()
- if("${CMAKE_MAKE_PROGRAM}" MATCHES "[Mm][Ss][Bb][Uu][Ii][Ll][Dd]")
- set(build /p:Configuration=Debug /p:Platform=@id_platform@ /p:VisualStudioVersion=${vs_version}.0)
- elseif("${CMAKE_MAKE_PROGRAM}" MATCHES "[Mm][Ss][Dd][Ee][Vv]")
- set(build /make)
- else()
- set(build /build Debug)
- endif()
set(id_dir ${CMAKE_${lang}_COMPILER_ID_DIR})
- get_filename_component(id_src "${src}" NAME)
+ set(id_src "${src}")
configure_file(${CMAKE_ROOT}/Modules/CompilerId/VS-${v}.${ext}.in
- ${id_dir}/CompilerId${lang}.${ext} @ONLY IMMEDIATE)
- execute_process(
- COMMAND ${CMAKE_MAKE_PROGRAM} CompilerId${lang}.${ext} ${build}
- WORKING_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR}
- OUTPUT_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
- ERROR_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
- RESULT_VARIABLE CMAKE_${lang}_COMPILER_ID_RESULT
- )
+ ${id_dir}/CompilerId${lang}.${ext} @ONLY)
+ if(CMAKE_VS_MSBUILD_COMMAND AND NOT lang STREQUAL "Fortran")
+ set(command "${CMAKE_VS_MSBUILD_COMMAND}" "CompilerId${lang}.${ext}"
+ "/p:Configuration=Debug" "/p:Platform=${id_platform}" "/p:VisualStudioVersion=${vs_version}.0"
+ )
+ elseif(CMAKE_VS_DEVENV_COMMAND)
+ set(command "${CMAKE_VS_DEVENV_COMMAND}" "CompilerId${lang}.${ext}" "/build" "Debug")
+ elseif(CMAKE_VS_MSDEV_COMMAND)
+ set(command "${CMAKE_VS_MSDEV_COMMAND}" "CompilerId${lang}.${ext}" "/make")
+ else()
+ set(command "")
+ endif()
+ if(command)
+ execute_process(
+ COMMAND ${command}
+ WORKING_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR}
+ OUTPUT_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
+ ERROR_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
+ RESULT_VARIABLE CMAKE_${lang}_COMPILER_ID_RESULT
+ )
+ else()
+ set(CMAKE_${lang}_COMPILER_ID_RESULT 1)
+ set(CMAKE_${lang}_COMPILER_ID_OUTPUT "VS environment not known to support ${lang}")
+ endif()
# Match the compiler location line printed out.
if("${CMAKE_${lang}_COMPILER_ID_OUTPUT}" MATCHES "CMAKE_${lang}_COMPILER=([^%\r\n]+)[\r\n]")
- set(_comp "${CMAKE_MATCH_1}")
+ # Strip VS diagnostic output from the end of the line.
+ string(REGEX REPLACE " \\(TaskId:[0-9]*\\)$" "" _comp "${CMAKE_MATCH_1}")
if(EXISTS "${_comp}")
file(TO_CMAKE_PATH "${_comp}" _comp)
set(CMAKE_${lang}_COMPILER_ID_TOOL "${_comp}" PARENT_SCOPE)
@@ -171,12 +265,27 @@ Id flags: ${testflags}
set(id_lang "${lang}")
set(id_type ${CMAKE_${lang}_COMPILER_XCODE_TYPE})
set(id_dir ${CMAKE_${lang}_COMPILER_ID_DIR})
- get_filename_component(id_src "${src}" NAME)
+ set(id_src "${src}")
if(CMAKE_XCODE_PLATFORM_TOOLSET)
set(id_toolset "GCC_VERSION = ${CMAKE_XCODE_PLATFORM_TOOLSET};")
else()
set(id_toolset "")
endif()
+ if(CMAKE_OSX_DEPLOYMENT_TARGET)
+ set(id_deployment_target
+ "MACOSX_DEPLOYMENT_TARGET = \"${CMAKE_OSX_DEPLOYMENT_TARGET}\";")
+ else()
+ set(id_deployment_target "")
+ endif()
+ set(id_product_type "com.apple.product-type.tool")
+ if(CMAKE_OSX_SYSROOT)
+ set(id_sdkroot "SDKROOT = \"${CMAKE_OSX_SYSROOT}\";")
+ if(CMAKE_OSX_SYSROOT MATCHES "(^|/)[Ii][Pp][Hh][Oo][Nn][Ee]")
+ set(id_product_type "com.apple.product-type.bundle.unit-test")
+ endif()
+ else()
+ set(id_sdkroot "")
+ endif()
if(NOT ${XCODE_VERSION} VERSION_LESS 3)
set(v 3)
set(ext xcodeproj)
@@ -188,7 +297,7 @@ Id flags: ${testflags}
set(ext xcode)
endif()
configure_file(${CMAKE_ROOT}/Modules/CompilerId/Xcode-${v}.pbxproj.in
- ${id_dir}/CompilerId${lang}.${ext}/project.pbxproj @ONLY IMMEDIATE)
+ ${id_dir}/CompilerId${lang}.${ext}/project.pbxproj @ONLY)
unset(_ENV_MACOSX_DEPLOYMENT_TARGET)
if(DEFINED ENV{MACOSX_DEPLOYMENT_TARGET})
set(_ENV_MACOSX_DEPLOYMENT_TARGET "$ENV{MACOSX_DEPLOYMENT_TARGET}")
@@ -204,45 +313,33 @@ Id flags: ${testflags}
set(ENV{MACOSX_DEPLOYMENT_TARGET} "${_ENV_MACOSX_DEPLOYMENT_TARGET}")
endif()
- # Match the link line from xcodebuild output of the form
- # Ld ...
- # ...
- # /path/to/cc ...CompilerId${lang}/...
- # to extract the compiler front-end for the language.
- if("${CMAKE_${lang}_COMPILER_ID_OUTPUT}" MATCHES "\nLd[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]*-o[^\r\n]*CompilerId${lang}/(\\./)?CompilerId${lang}[ \t\n\\\"]")
- set(_comp "${CMAKE_MATCH_2}")
- if(EXISTS "${_comp}")
- set(CMAKE_${lang}_COMPILER_ID_TOOL "${_comp}" PARENT_SCOPE)
+ if(DEFINED CMAKE_${lang}_COMPILER_ID_TOOL_MATCH_REGEX)
+ if("${CMAKE_${lang}_COMPILER_ID_OUTPUT}" MATCHES "${CMAKE_${lang}_COMPILER_ID_TOOL_MATCH_REGEX}")
+ set(_comp "${CMAKE_MATCH_${CMAKE_${lang}_COMPILER_ID_TOOL_MATCH_INDEX}}")
+ if(EXISTS "${_comp}")
+ set(CMAKE_${lang}_COMPILER_ID_TOOL "${_comp}" PARENT_SCOPE)
+ endif()
endif()
endif()
else()
- if(COMMAND EXECUTE_PROCESS)
- execute_process(
- COMMAND ${CMAKE_${lang}_COMPILER}
- ${CMAKE_${lang}_COMPILER_ID_ARG1}
- ${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}
- ${testflags}
- "${src}"
- WORKING_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR}
- OUTPUT_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
- ERROR_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
- RESULT_VARIABLE CMAKE_${lang}_COMPILER_ID_RESULT
- )
- else()
- exec_program(
- ${CMAKE_${lang}_COMPILER} ${CMAKE_${lang}_COMPILER_ID_DIR}
- ARGS ${CMAKE_${lang}_COMPILER_ID_ARG1}
- ${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}
- ${testflags}
- \"${src}\"
- OUTPUT_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
- RETURN_VALUE CMAKE_${lang}_COMPILER_ID_RESULT
- )
- endif()
+ execute_process(
+ COMMAND "${CMAKE_${lang}_COMPILER}"
+ ${CMAKE_${lang}_COMPILER_ID_ARG1}
+ ${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}
+ ${testflags}
+ "${src}"
+ WORKING_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR}
+ OUTPUT_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
+ ERROR_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
+ RESULT_VARIABLE CMAKE_${lang}_COMPILER_ID_RESULT
+ )
endif()
# Check the result of compilation.
- if(CMAKE_${lang}_COMPILER_ID_RESULT)
+ if(CMAKE_${lang}_COMPILER_ID_RESULT
+ # Intel Fortran warns and ignores preprocessor lines without /fpp
+ OR CMAKE_${lang}_COMPILER_ID_OUTPUT MATCHES "Bad # preprocessor line"
+ )
# Compilation failed.
set(MSG
"Compiling the ${lang} compiler identification source file \"${src}\" failed.
@@ -259,6 +356,7 @@ ${CMAKE_${lang}_COMPILER_ID_OUTPUT}
# No output files should be inspected.
set(COMPILER_${lang}_PRODUCED_FILES)
+ set(COMPILER_${lang}_PRODUCED_OUTPUT)
else()
# Compilation succeeded.
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
@@ -274,7 +372,13 @@ ${CMAKE_${lang}_COMPILER_ID_OUTPUT}
# binary dir.
file(GLOB files
RELATIVE ${CMAKE_${lang}_COMPILER_ID_DIR}
- ${CMAKE_${lang}_COMPILER_ID_DIR}/*)
+
+ # normal case
+ ${CMAKE_${lang}_COMPILER_ID_DIR}/*
+
+ # com.apple.package-type.bundle.unit-test
+ ${CMAKE_${lang}_COMPILER_ID_DIR}/*.xctest/*
+ )
list(REMOVE_ITEM files "${src}")
set(COMPILER_${lang}_PRODUCED_FILES "")
foreach(file ${files})
@@ -293,10 +397,24 @@ ${CMAKE_${lang}_COMPILER_ID_OUTPUT}
"${src}\" did not produce an executable in \""
"${CMAKE_${lang}_COMPILER_ID_DIR}\".\n\n")
endif()
+
+ set(COMPILER_${lang}_PRODUCED_OUTPUT "${CMAKE_${lang}_COMPILER_ID_OUTPUT}")
endif()
# Return the files produced by the compilation.
set(COMPILER_${lang}_PRODUCED_FILES "${COMPILER_${lang}_PRODUCED_FILES}" PARENT_SCOPE)
+ set(COMPILER_${lang}_PRODUCED_OUTPUT "${COMPILER_${lang}_PRODUCED_OUTPUT}" PARENT_SCOPE)
+endfunction()
+
+#-----------------------------------------------------------------------------
+# Function to extract the compiler id from compiler output.
+function(CMAKE_DETERMINE_COMPILER_ID_MATCH_VENDOR lang output)
+ foreach(vendor ${CMAKE_${lang}_COMPILER_ID_MATCH_VENDORS})
+ if(output MATCHES "${CMAKE_${lang}_COMPILER_ID_MATCH_VENDOR_REGEX_${vendor}}")
+ set(CMAKE_${lang}_COMPILER_ID "${vendor}")
+ endif()
+ endforeach()
+ set(CMAKE_${lang}_COMPILER_ID "${CMAKE_${lang}_COMPILER_ID}" PARENT_SCOPE)
endfunction()
#-----------------------------------------------------------------------------
@@ -307,33 +425,88 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file)
# Read the compiler identification string from the executable file.
set(COMPILER_ID)
set(COMPILER_VERSION)
+ set(COMPILER_VERSION_MAJOR 0)
+ set(COMPILER_VERSION_MINOR 0)
+ set(COMPILER_VERSION_PATCH 0)
+ set(COMPILER_VERSION_TWEAK 0)
+ set(HAVE_COMPILER_VERSION_MAJOR 0)
+ set(HAVE_COMPILER_VERSION_MINOR 0)
+ set(HAVE_COMPILER_VERSION_PATCH 0)
+ set(HAVE_COMPILER_VERSION_TWEAK 0)
+ set(COMPILER_WRAPPER)
+ set(DIGIT_VALUE_1 1)
+ set(DIGIT_VALUE_2 10)
+ set(DIGIT_VALUE_3 100)
+ set(DIGIT_VALUE_4 1000)
+ set(DIGIT_VALUE_5 10000)
+ set(DIGIT_VALUE_6 100000)
+ set(DIGIT_VALUE_7 1000000)
+ set(DIGIT_VALUE_8 10000000)
set(PLATFORM_ID)
+ set(ARCHITECTURE_ID)
+ set(SIMULATE_ID)
+ set(SIMULATE_VERSION)
file(STRINGS ${file}
- CMAKE_${lang}_COMPILER_ID_STRINGS LIMIT_COUNT 4 REGEX "INFO:")
- set(HAVE_COMPILER_TWICE 0)
+ CMAKE_${lang}_COMPILER_ID_STRINGS LIMIT_COUNT 38 REGEX "INFO:[A-Za-z0-9_]+\\[[^]]*\\]")
+ set(COMPILER_ID_TWICE)
foreach(info ${CMAKE_${lang}_COMPILER_ID_STRINGS})
- if("${info}" MATCHES ".*INFO:compiler\\[([^]\"]*)\\].*")
+ if("${info}" MATCHES "INFO:compiler\\[([^]\"]*)\\]")
if(COMPILER_ID)
set(COMPILER_ID_TWICE 1)
endif()
- string(REGEX REPLACE ".*INFO:compiler\\[([^]]*)\\].*" "\\1"
- COMPILER_ID "${info}")
+ set(COMPILER_ID "${CMAKE_MATCH_1}")
endif()
- if("${info}" MATCHES ".*INFO:platform\\[([^]\"]*)\\].*")
- string(REGEX REPLACE ".*INFO:platform\\[([^]]*)\\].*" "\\1"
- PLATFORM_ID "${info}")
+ if("${info}" MATCHES "INFO:platform\\[([^]\"]*)\\]")
+ set(PLATFORM_ID "${CMAKE_MATCH_1}")
endif()
- if("${info}" MATCHES ".*INFO:arch\\[([^]\"]*)\\].*")
- string(REGEX REPLACE ".*INFO:arch\\[([^]]*)\\].*" "\\1"
- ARCHITECTURE_ID "${info}")
+ if("${info}" MATCHES "INFO:arch\\[([^]\"]*)\\]")
+ set(ARCHITECTURE_ID "${CMAKE_MATCH_1}")
endif()
- if("${info}" MATCHES ".*INFO:compiler_version\\[([^]\"]*)\\].*")
- string(REGEX REPLACE ".*INFO:compiler_version\\[([^]]*)\\].*" "\\1" COMPILER_VERSION "${info}")
- string(REGEX REPLACE "^0+([0-9])" "\\1" COMPILER_VERSION "${COMPILER_VERSION}")
+ if("${info}" MATCHES "INFO:compiler_version\\[([^]\"]*)\\]")
+ string(REGEX REPLACE "^0+([0-9])" "\\1" COMPILER_VERSION "${CMAKE_MATCH_1}")
string(REGEX REPLACE "\\.0+([0-9])" ".\\1" COMPILER_VERSION "${COMPILER_VERSION}")
endif()
+ foreach(comp MAJOR MINOR PATCH TWEAK)
+ foreach(digit 1 2 3 4 5 6 7 8 9)
+ if("${info}" MATCHES "INFO:compiler_version_${comp}_digit_${digit}\\[([0-9])\\]")
+ set(value ${CMAKE_MATCH_1})
+ math(EXPR COMPILER_VERSION_${comp} "${COMPILER_VERSION_${comp}} + ${value} * ${DIGIT_VALUE_${digit}}")
+ set(HAVE_COMPILER_VERSION_${comp} 1)
+ endif()
+ endforeach()
+ endforeach()
+ if("${info}" MATCHES "INFO:compiler_wrapper\\[([^]\"]*)\\]")
+ set(COMPILER_WRAPPER "${CMAKE_MATCH_1}")
+ endif()
+ if("${info}" MATCHES "INFO:simulate\\[([^]\"]*)\\]")
+ set(SIMULATE_ID "${CMAKE_MATCH_1}")
+ endif()
+ if("${info}" MATCHES "INFO:simulate_version\\[([^]\"]*)\\]")
+ string(REGEX REPLACE "^0+([0-9])" "\\1" SIMULATE_VERSION "${CMAKE_MATCH_1}")
+ string(REGEX REPLACE "\\.0+([0-9])" ".\\1" SIMULATE_VERSION "${SIMULATE_VERSION}")
+ endif()
+ if("${info}" MATCHES "INFO:qnxnto\\[\\]")
+ set(COMPILER_QNXNTO 1)
+ endif()
+ if("${info}" MATCHES "INFO:dialect_default\\[([^]\"]*)\\]")
+ set(CMAKE_${lang}_STANDARD_COMPUTED_DEFAULT "${CMAKE_MATCH_1}")
+ endif()
endforeach()
+ # Construct compiler version from components if needed.
+ if(NOT DEFINED COMPILER_VERSION AND HAVE_COMPILER_VERSION_MAJOR)
+ set(COMPILER_VERSION "${COMPILER_VERSION_MAJOR}")
+ if(HAVE_COMPILER_VERSION_MINOR)
+ set(COMPILER_VERSION "${COMPILER_VERSION}.${COMPILER_VERSION_MINOR}")
+ if(HAVE_COMPILER_VERSION_PATCH)
+ set(COMPILER_VERSION "${COMPILER_VERSION}.${COMPILER_VERSION_PATCH}")
+ if(HAVE_COMPILER_VERSION_TWEAK)
+ set(COMPILER_VERSION "${COMPILER_VERSION}.${COMPILER_VERSION_TWEAK}")
+ endif()
+ endif()
+ endif()
+ endif()
+
# Detect the exact architecture from the PE header.
if(WIN32)
# The offset to the PE signature is stored at 0x3c.
@@ -358,8 +531,6 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file)
set(ARCHITECTURE_ID "SH4")
elseif(peheader STREQUAL "50450000a801")
set(ARCHITECTURE_ID "SH5")
- elseif(peheader STREQUAL "50450000c201")
- set(ARCHITECTURE_ID "THUMB")
endif()
endif()
@@ -369,6 +540,8 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file)
set(CMAKE_${lang}_PLATFORM_ID "${PLATFORM_ID}")
set(MSVC_${lang}_ARCHITECTURE_ID "${ARCHITECTURE_ID}")
set(CMAKE_${lang}_COMPILER_VERSION "${COMPILER_VERSION}")
+ set(CMAKE_${lang}_SIMULATE_ID "${SIMULATE_ID}")
+ set(CMAKE_${lang}_SIMULATE_VERSION "${SIMULATE_VERSION}")
endif()
# Check the compiler identification string.
@@ -417,7 +590,12 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file)
set(MSVC_${lang}_ARCHITECTURE_ID "${MSVC_${lang}_ARCHITECTURE_ID}"
PARENT_SCOPE)
set(CMAKE_${lang}_COMPILER_VERSION "${CMAKE_${lang}_COMPILER_VERSION}" PARENT_SCOPE)
+ set(CMAKE_${lang}_COMPILER_WRAPPER "${COMPILER_WRAPPER}" PARENT_SCOPE)
+ set(CMAKE_${lang}_SIMULATE_ID "${CMAKE_${lang}_SIMULATE_ID}" PARENT_SCOPE)
+ set(CMAKE_${lang}_SIMULATE_VERSION "${CMAKE_${lang}_SIMULATE_VERSION}" PARENT_SCOPE)
set(CMAKE_EXECUTABLE_FORMAT "${CMAKE_EXECUTABLE_FORMAT}" PARENT_SCOPE)
+ set(COMPILER_QNXNTO "${COMPILER_QNXNTO}" PARENT_SCOPE)
+ set(CMAKE_${lang}_STANDARD_COMPUTED_DEFAULT "${CMAKE_${lang}_STANDARD_COMPUTED_DEFAULT}" PARENT_SCOPE)
endfunction()
#-----------------------------------------------------------------------------
@@ -444,7 +622,7 @@ function(CMAKE_DETERMINE_COMPILER_ID_VENDOR lang)
set(flags ${CMAKE_${lang}_COMPILER_ID_VENDOR_FLAGS_${vendor}})
set(regex ${CMAKE_${lang}_COMPILER_ID_VENDOR_REGEX_${vendor}})
execute_process(
- COMMAND ${CMAKE_${lang}_COMPILER}
+ COMMAND "${CMAKE_${lang}_COMPILER}"
${CMAKE_${lang}_COMPILER_ID_ARG1}
${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}
${flags}
@@ -473,3 +651,27 @@ function(CMAKE_DETERMINE_COMPILER_ID_VENDOR lang)
endif()
endforeach()
endfunction()
+
+function(CMAKE_DETERMINE_MSVC_SHOWINCLUDES_PREFIX lang)
+ # Run this MSVC-compatible compiler to detect what the /showIncludes
+ # option displays. We can use a C source even with the C++ compiler
+ # because MSVC-compatible compilers handle both and show the same output.
+ set(showdir ${CMAKE_BINARY_DIR}/CMakeFiles/ShowIncludes)
+ file(WRITE ${showdir}/foo.h "\n")
+ file(WRITE ${showdir}/main.c "#include \"foo.h\" \nint main(){}\n")
+ execute_process(
+ COMMAND "${CMAKE_${lang}_COMPILER}"
+ ${CMAKE_${lang}_COMPILER_ID_ARG1}
+ ${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}
+ /nologo /showIncludes /c main.c
+ WORKING_DIRECTORY ${showdir}
+ OUTPUT_VARIABLE out
+ ERROR_VARIABLE err
+ RESULT_VARIABLE res
+ )
+ if(res EQUAL 0 AND "${out}" MATCHES "\n([^:]*:[^:]*:[ \t]*)")
+ set(CMAKE_${lang}_CL_SHOWINCLUDES_PREFIX "${CMAKE_MATCH_1}" PARENT_SCOPE)
+ else()
+ set(CMAKE_${lang}_CL_SHOWINCLUDES_PREFIX "" PARENT_SCOPE)
+ endif()
+endfunction()
diff --git a/Modules/CMakeDetermineFortranCompiler.cmake b/Modules/CMakeDetermineFortranCompiler.cmake
index 4d3fb9076..ccafb0779 100644
--- a/Modules/CMakeDetermineFortranCompiler.cmake
+++ b/Modules/CMakeDetermineFortranCompiler.cmake
@@ -26,16 +26,13 @@ if(NOT CMAKE_Fortran_COMPILER_NAMES)
endif()
if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
- set(CMAKE_Fortran_COMPILER_ID_RUN 1)
- set(CMAKE_Fortran_PLATFORM_ID "Windows")
- set(CMAKE_Fortran_COMPILER_ID "Intel")
- set(CMAKE_Fortran_COMPILER "${CMAKE_GENERATOR_FC}")
elseif("${CMAKE_GENERATOR}" MATCHES "Xcode")
set(CMAKE_Fortran_COMPILER_XCODE_TYPE sourcecode.fortran.f90)
+ _cmake_find_compiler_path(Fortran)
else()
if(NOT CMAKE_Fortran_COMPILER)
# prefer the environment variable CC
- if($ENV{FC} MATCHES ".+")
+ if(NOT $ENV{FC} STREQUAL "")
get_filename_component(CMAKE_Fortran_COMPILER_INIT $ENV{FC} PROGRAM PROGRAM_ARGS CMAKE_Fortran_FLAGS_ENV_INIT)
if(CMAKE_Fortran_FLAGS_ENV_INIT)
set(CMAKE_Fortran_COMPILER_ARG1 "${CMAKE_Fortran_FLAGS_ENV_INIT}" CACHE STRING "First argument to Fortran compiler")
@@ -57,6 +54,7 @@ else()
if(NOT CMAKE_Fortran_COMPILER_INIT)
# Known compilers:
# f77/f90/f95: generic compiler names
+ # ftn: Cray fortran compiler wrapper
# g77: GNU Fortran 77 compiler
# gfortran: putative GNU Fortran 95+ compiler (in progress)
# fort77: native F77 compiler under HP-UX (and some older Crays)
@@ -76,6 +74,7 @@ else()
# then 77 or older compilers, gnu is always last in the group,
# so if you paid for a compiler it is picked by default.
set(CMAKE_Fortran_COMPILER_LIST
+ ftn
ifort ifc af95 af90 efc f95 pathf2003 pathf95 pgf95 pgfortran lf95 xlf95
fort gfortran gfortran-4 g95 f90 pathf90 pgf90 xlf90 epcf90 fort77
frt pgf77 xlf fl32 af77 g77 f77
@@ -94,37 +93,17 @@ else()
_cmake_find_compiler(Fortran)
else()
- # we only get here if CMAKE_Fortran_COMPILER was specified using -D or a pre-made CMakeCache.txt
- # (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE
- # if CMAKE_Fortran_COMPILER is a list of length 2, use the first item as
- # CMAKE_Fortran_COMPILER and the 2nd one as CMAKE_Fortran_COMPILER_ARG1
-
- list(LENGTH CMAKE_Fortran_COMPILER _CMAKE_Fortran_COMPILER_LIST_LENGTH)
- if("${_CMAKE_Fortran_COMPILER_LIST_LENGTH}" EQUAL 2)
- list(GET CMAKE_Fortran_COMPILER 1 CMAKE_Fortran_COMPILER_ARG1)
- list(GET CMAKE_Fortran_COMPILER 0 CMAKE_Fortran_COMPILER)
- endif()
-
- # if a compiler was specified by the user but without path,
- # now try to find it with the full path
- # if it is found, force it into the cache,
- # if not, don't overwrite the setting (which was given by the user) with "NOTFOUND"
- # if the C compiler already had a path, reuse it for searching the CXX compiler
- get_filename_component(_CMAKE_USER_Fortran_COMPILER_PATH "${CMAKE_Fortran_COMPILER}" PATH)
- if(NOT _CMAKE_USER_Fortran_COMPILER_PATH)
- find_program(CMAKE_Fortran_COMPILER_WITH_PATH NAMES ${CMAKE_Fortran_COMPILER})
- mark_as_advanced(CMAKE_Fortran_COMPILER_WITH_PATH)
- if(CMAKE_Fortran_COMPILER_WITH_PATH)
- set(CMAKE_Fortran_COMPILER ${CMAKE_Fortran_COMPILER_WITH_PATH}
- CACHE STRING "Fortran compiler" FORCE)
- endif()
- endif()
+ _cmake_find_compiler_path(Fortran)
endif()
mark_as_advanced(CMAKE_Fortran_COMPILER)
# Each entry in this list is a set of extra flags to try
# adding to the compile line to see if it helps produce
# a valid identification executable.
+ set(CMAKE_Fortran_COMPILER_ID_TEST_FLAGS_FIRST
+ # Get verbose output to help distinguish compilers.
+ "-v"
+ )
set(CMAKE_Fortran_COMPILER_ID_TEST_FLAGS
# Try compiling to an object file only.
"-c"
@@ -138,6 +117,10 @@ endif()
if(NOT CMAKE_Fortran_COMPILER_ID_RUN)
set(CMAKE_Fortran_COMPILER_ID_RUN 1)
+ # Table of per-vendor compiler output regular expressions.
+ list(APPEND CMAKE_Fortran_COMPILER_ID_MATCH_VENDORS CCur)
+ set(CMAKE_Fortran_COMPILER_ID_MATCH_VENDOR_REGEX_CCur "Concurrent Fortran [0-9]+ Compiler")
+
# Table of per-vendor compiler id flags with expected output.
list(APPEND CMAKE_Fortran_COMPILER_ID_VENDORS Compaq)
set(CMAKE_Fortran_COMPILER_ID_VENDOR_FLAGS_Compaq "-what")
@@ -146,6 +129,55 @@ if(NOT CMAKE_Fortran_COMPILER_ID_RUN)
set(CMAKE_Fortran_COMPILER_ID_VENDOR_FLAGS_NAG "-V")
set(CMAKE_Fortran_COMPILER_ID_VENDOR_REGEX_NAG "NAG Fortran Compiler")
+ # Match the link line from xcodebuild output of the form
+ # Ld ...
+ # ...
+ # /path/to/cc ...CompilerIdFortran/...
+ # to extract the compiler front-end for the language.
+ set(CMAKE_Fortran_COMPILER_ID_TOOL_MATCH_REGEX "\nLd[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]*-o[^\r\n]*CompilerIdFortran/(\\./)?(CompilerIdFortran.xctest/)?CompilerIdFortran[ \t\n\\\"]")
+ set(CMAKE_Fortran_COMPILER_ID_TOOL_MATCH_INDEX 2)
+
+ set(_version_info "")
+ foreach(m MAJOR MINOR PATCH TWEAK)
+ set(_COMP "_${m}")
+ set(_version_info "${_version_info}
+#if defined(COMPILER_VERSION${_COMP})")
+ foreach(d 1 2 3 4 5 6 7 8)
+ set(_version_info "${_version_info}
+# undef DEC
+# undef HEX
+# define DEC(n) DEC_${d}(n)
+# define HEX(n) HEX_${d}(n)
+# if COMPILER_VERSION${_COMP} == 0
+ PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[0]'
+# elif COMPILER_VERSION${_COMP} == 1
+ PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[1]'
+# elif COMPILER_VERSION${_COMP} == 2
+ PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[2]'
+# elif COMPILER_VERSION${_COMP} == 3
+ PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[3]'
+# elif COMPILER_VERSION${_COMP} == 4
+ PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[4]'
+# elif COMPILER_VERSION${_COMP} == 5
+ PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[5]'
+# elif COMPILER_VERSION${_COMP} == 6
+ PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[6]'
+# elif COMPILER_VERSION${_COMP} == 7
+ PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[7]'
+# elif COMPILER_VERSION${_COMP} == 8
+ PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[8]'
+# elif COMPILER_VERSION${_COMP} == 9
+ PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[9]'
+# endif
+")
+ endforeach()
+ set(_version_info "${_version_info}
+#endif")
+ endforeach()
+ set(CMAKE_Fortran_COMPILER_ID_VERSION_INFO "${_version_info}")
+ unset(_version_info)
+ unset(_COMP)
+
# Try to identify the compiler.
set(CMAKE_Fortran_COMPILER_ID)
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
@@ -157,7 +189,7 @@ if(NOT CMAKE_Fortran_COMPILER_ID_RUN)
ARGS ${CMAKE_Fortran_COMPILER_ID_FLAGS_LIST} -E "\"${CMAKE_ROOT}/Modules/CMakeTestGNU.c\""
OUTPUT_VARIABLE CMAKE_COMPILER_OUTPUT RETURN_VALUE CMAKE_COMPILER_RETURN)
if(NOT CMAKE_COMPILER_RETURN)
- if("${CMAKE_COMPILER_OUTPUT}" MATCHES ".*THIS_IS_GNU.*" )
+ if("${CMAKE_COMPILER_OUTPUT}" MATCHES "THIS_IS_GNU")
set(CMAKE_Fortran_COMPILER_ID "GNU")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the Fortran compiler is GNU succeeded with "
@@ -168,10 +200,10 @@ if(NOT CMAKE_Fortran_COMPILER_ID_RUN)
"the following output:\n${CMAKE_COMPILER_OUTPUT}\n\n")
endif()
if(NOT CMAKE_Fortran_PLATFORM_ID)
- if("${CMAKE_COMPILER_OUTPUT}" MATCHES ".*THIS_IS_MINGW.*" )
+ if("${CMAKE_COMPILER_OUTPUT}" MATCHES "THIS_IS_MINGW")
set(CMAKE_Fortran_PLATFORM_ID "MinGW")
endif()
- if("${CMAKE_COMPILER_OUTPUT}" MATCHES ".*THIS_IS_CYGWIN.*" )
+ if("${CMAKE_COMPILER_OUTPUT}" MATCHES "THIS_IS_CYGWIN")
set(CMAKE_Fortran_PLATFORM_ID "Cygwin")
endif()
endif()
@@ -179,12 +211,12 @@ if(NOT CMAKE_Fortran_COMPILER_ID_RUN)
endif()
# Set old compiler and platform id variables.
- if("${CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU")
+ if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
set(CMAKE_COMPILER_IS_GNUG77 1)
endif()
- if("${CMAKE_Fortran_PLATFORM_ID}" MATCHES "MinGW")
+ if(CMAKE_Fortran_PLATFORM_ID MATCHES "MinGW")
set(CMAKE_COMPILER_IS_MINGW 1)
- elseif("${CMAKE_Fortran_PLATFORM_ID}" MATCHES "Cygwin")
+ elseif(CMAKE_Fortran_PLATFORM_ID MATCHES "Cygwin")
set(CMAKE_COMPILER_IS_CYGWIN 1)
endif()
endif()
@@ -197,12 +229,12 @@ endif ()
# e.g. powerpc-linux-gfortran, arm-elf-gfortran or i586-mingw32msvc-gfortran , optionally
# with a 3-component version number at the end (e.g. arm-eabi-gcc-4.5.2).
# The other tools of the toolchain usually have the same prefix
-# NAME_WE cannot be used since then this test will fail for names lile
+# NAME_WE cannot be used since then this test will fail for names like
# "arm-unknown-nto-qnx6.3.0-gcc.exe", where BASENAME would be
# "arm-unknown-nto-qnx6" instead of the correct "arm-unknown-nto-qnx6.3.0-"
if (CMAKE_CROSSCOMPILING AND NOT _CMAKE_TOOLCHAIN_PREFIX)
- if("${CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU")
+ if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
get_filename_component(COMPILER_BASENAME "${CMAKE_Fortran_COMPILER}" NAME)
if (COMPILER_BASENAME MATCHES "^(.+-)g?fortran(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$")
set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
@@ -226,6 +258,6 @@ endif()
# configure variables set in this file for fast reload later on
configure_file(${CMAKE_ROOT}/Modules/CMakeFortranCompiler.cmake.in
${CMAKE_PLATFORM_INFO_DIR}/CMakeFortranCompiler.cmake
- @ONLY IMMEDIATE # IMMEDIATE must be here for compatibility mode <= 2.0
+ @ONLY
)
set(CMAKE_Fortran_COMPILER_ENV_VAR "FC")
diff --git a/Modules/CMakeDetermineJavaCompiler.cmake b/Modules/CMakeDetermineJavaCompiler.cmake
index ae9f5fcaf..f6578016a 100644
--- a/Modules/CMakeDetermineJavaCompiler.cmake
+++ b/Modules/CMakeDetermineJavaCompiler.cmake
@@ -18,7 +18,7 @@
if(NOT CMAKE_Java_COMPILER)
# prefer the environment variable CC
- if($ENV{JAVA_COMPILER} MATCHES ".+")
+ if(NOT $ENV{JAVA_COMPILER} STREQUAL "")
get_filename_component(CMAKE_Java_COMPILER_INIT $ENV{JAVA_COMPILER} PROGRAM PROGRAM_ARGS CMAKE_Java_FLAGS_ENV_INIT)
if(CMAKE_Java_FLAGS_ENV_INIT)
set(CMAKE_Java_COMPILER_ARG1 "${CMAKE_Java_FLAGS_ENV_INIT}" CACHE STRING "First argument to Java compiler")
@@ -28,14 +28,14 @@ if(NOT CMAKE_Java_COMPILER)
endif()
endif()
- if($ENV{JAVA_RUNTIME} MATCHES ".+")
+ if(NOT $ENV{JAVA_RUNTIME} STREQUAL "")
get_filename_component(CMAKE_Java_RUNTIME_INIT $ENV{JAVA_RUNTIME} PROGRAM PROGRAM_ARGS CMAKE_Java_FLAGS_ENV_INIT)
if(NOT EXISTS ${CMAKE_Java_RUNTIME_INIT})
message(SEND_ERROR "Could not find compiler set in environment variable JAVA_RUNTIME:\n$ENV{JAVA_RUNTIME}.")
endif()
endif()
- if($ENV{JAVA_ARCHIVE} MATCHES ".+")
+ if(NOT $ENV{JAVA_ARCHIVE} STREQUAL "")
get_filename_component(CMAKE_Java_ARCHIVE_INIT $ENV{JAVA_ARCHIVE} PROGRAM PROGRAM_ARGS CMAKE_Java_FLAGS_ENV_INIT)
if(NOT EXISTS ${CMAKE_Java_ARCHIVE_INIT})
message(SEND_ERROR "Could not find compiler set in environment variable JAVA_ARCHIVE:\n$ENV{JAVA_ARCHIVE}.")
@@ -100,5 +100,5 @@ mark_as_advanced(CMAKE_Java_COMPILER)
# configure variables set in this file for fast reload later on
configure_file(${CMAKE_ROOT}/Modules/CMakeJavaCompiler.cmake.in
- ${CMAKE_PLATFORM_INFO_DIR}/CMakeJavaCompiler.cmake IMMEDIATE @ONLY)
+ ${CMAKE_PLATFORM_INFO_DIR}/CMakeJavaCompiler.cmake @ONLY)
set(CMAKE_Java_COMPILER_ENV_VAR "JAVA_COMPILER")
diff --git a/Modules/CMakeDetermineRCCompiler.cmake b/Modules/CMakeDetermineRCCompiler.cmake
index c4600c7fe..e5414eb99 100644
--- a/Modules/CMakeDetermineRCCompiler.cmake
+++ b/Modules/CMakeDetermineRCCompiler.cmake
@@ -20,7 +20,7 @@
# as a default compiler
if(NOT CMAKE_RC_COMPILER)
# prefer the environment variable RC
- if($ENV{RC} MATCHES ".+")
+ if(NOT $ENV{RC} STREQUAL "")
get_filename_component(CMAKE_RC_COMPILER_INIT $ENV{RC} PROGRAM PROGRAM_ARGS CMAKE_RC_FLAGS_ENV_INIT)
if(CMAKE_RC_FLAGS_ENV_INIT)
set(CMAKE_RC_COMPILER_ARG1 "${CMAKE_RC_FLAGS_ENV_INIT}" CACHE STRING "First argument to RC compiler")
@@ -63,5 +63,5 @@ endif()
# configure variables set in this file for fast reload later on
configure_file(${CMAKE_ROOT}/Modules/CMakeRCCompiler.cmake.in
- ${CMAKE_PLATFORM_INFO_DIR}/CMakeRCCompiler.cmake IMMEDIATE)
+ ${CMAKE_PLATFORM_INFO_DIR}/CMakeRCCompiler.cmake)
set(CMAKE_RC_COMPILER_ENV_VAR "RC")
diff --git a/Modules/CMakeDetermineSwiftCompiler.cmake b/Modules/CMakeDetermineSwiftCompiler.cmake
new file mode 100644
index 000000000..bff1ae9cd
--- /dev/null
+++ b/Modules/CMakeDetermineSwiftCompiler.cmake
@@ -0,0 +1,53 @@
+
+#=============================================================================
+# Copyright 2002-2015 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake)
+
+if("${CMAKE_GENERATOR}" STREQUAL "Xcode")
+ if(XCODE_VERSION VERSION_LESS 6.1)
+ message(FATAL_ERROR "Swift language not supported by Xcode ${XCODE_VERSION}")
+ endif()
+ set(CMAKE_Swift_COMPILER_XCODE_TYPE sourcecode.swift)
+ _cmake_find_compiler_path(Swift)
+else()
+ message(FATAL_ERROR "Swift language not supported by \"${CMAKE_GENERATOR}\" generator")
+endif()
+
+# Build a small source file to identify the compiler.
+if(NOT CMAKE_Swift_COMPILER_ID_RUN)
+ set(CMAKE_Swift_COMPILER_ID_RUN 1)
+
+ list(APPEND CMAKE_Swift_COMPILER_ID_MATCH_VENDORS Apple)
+ set(CMAKE_Swift_COMPILER_ID_MATCH_VENDOR_REGEX_Apple "com.apple.xcode.tools.swift.compiler")
+
+ set(CMAKE_Swift_COMPILER_ID_TOOL_MATCH_REGEX "\nCompileSwiftSources[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]* -c[^\r\n]*CompilerIdSwift/CompilerId/main.swift")
+ set(CMAKE_Swift_COMPILER_ID_TOOL_MATCH_INDEX 2)
+
+ # Try to identify the compiler.
+ set(CMAKE_Swift_COMPILER_ID)
+ include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
+ CMAKE_DETERMINE_COMPILER_ID(Swift "" CompilerId/main.swift)
+endif()
+
+if (NOT _CMAKE_TOOLCHAIN_LOCATION)
+ get_filename_component(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_Swift_COMPILER}" PATH)
+endif ()
+
+include(CMakeFindBinUtils)
+
+# configure variables set in this file for fast reload later on
+configure_file(${CMAKE_ROOT}/Modules/CMakeSwiftCompiler.cmake.in
+ ${CMAKE_PLATFORM_INFO_DIR}/CMakeSwiftCompiler.cmake
+ @ONLY
+ )
diff --git a/Modules/CMakeDetermineSystem.cmake b/Modules/CMakeDetermineSystem.cmake
index 3a95d2a6f..d9f7579e3 100644
--- a/Modules/CMakeDetermineSystem.cmake
+++ b/Modules/CMakeDetermineSystem.cmake
@@ -47,9 +47,14 @@ if(CMAKE_HOST_UNIX)
if(CMAKE_UNAME)
exec_program(uname ARGS -s OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_NAME)
exec_program(uname ARGS -r OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_VERSION)
- if(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|CYGWIN.*")
+ if(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|CYGWIN.*|Darwin|^GNU$")
exec_program(uname ARGS -m OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
RETURN_VALUE val)
+ if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin" AND
+ CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "Power Macintosh")
+ # OS X ppc 'uname -m' may report 'Power Macintosh' instead of 'powerpc'
+ set(CMAKE_HOST_SYSTEM_PROCESSOR "powerpc")
+ endif()
elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "OpenBSD")
exec_program(arch ARGS -s OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
RETURN_VALUE val)
@@ -67,8 +72,8 @@ if(CMAKE_HOST_UNIX)
endif()
set(CMAKE_UNAME ${CMAKE_UNAME} CACHE INTERNAL "uname command")
# processor may have double quote in the name, and that needs to be removed
- string(REGEX REPLACE "\"" "" CMAKE_HOST_SYSTEM_PROCESSOR "${CMAKE_HOST_SYSTEM_PROCESSOR}")
- string(REGEX REPLACE "/" "_" CMAKE_HOST_SYSTEM_PROCESSOR "${CMAKE_HOST_SYSTEM_PROCESSOR}")
+ string(REPLACE "\"" "" CMAKE_HOST_SYSTEM_PROCESSOR "${CMAKE_HOST_SYSTEM_PROCESSOR}")
+ string(REPLACE "/" "_" CMAKE_HOST_SYSTEM_PROCESSOR "${CMAKE_HOST_SYSTEM_PROCESSOR}")
endif()
else()
if(CMAKE_HOST_WIN32)
@@ -118,7 +123,9 @@ elseif(CMAKE_VS_WINCE_VERSION)
set(PRESET_CMAKE_SYSTEM_NAME TRUE)
else()
set(CMAKE_SYSTEM_NAME "${CMAKE_HOST_SYSTEM_NAME}")
- set(CMAKE_SYSTEM_VERSION "${CMAKE_HOST_SYSTEM_VERSION}")
+ if(NOT DEFINED CMAKE_SYSTEM_VERSION)
+ set(CMAKE_SYSTEM_VERSION "${CMAKE_HOST_SYSTEM_VERSION}")
+ endif()
set(CMAKE_SYSTEM_PROCESSOR "${CMAKE_HOST_SYSTEM_PROCESSOR}")
set(CMAKE_CROSSCOMPILING FALSE)
set(PRESET_CMAKE_SYSTEM_NAME FALSE)
@@ -174,13 +181,13 @@ if(CMAKE_BINARY_DIR)
# if a toolchain file is used, it needs to be included in the configured file,
# so settings done there are also available if they don't go in the cache and in try_compile()
set(INCLUDE_CMAKE_TOOLCHAIN_FILE_IF_REQUIRED)
- if(DEFINED CMAKE_TOOLCHAIN_FILE)
+ if(CMAKE_TOOLCHAIN_FILE)
set(INCLUDE_CMAKE_TOOLCHAIN_FILE_IF_REQUIRED "include(\"${CMAKE_TOOLCHAIN_FILE}\")")
endif()
# configure variables set in this file for fast reload, the template file is defined at the top of this file
configure_file(${CMAKE_ROOT}/Modules/CMakeSystem.cmake.in
${CMAKE_PLATFORM_INFO_DIR}/CMakeSystem.cmake
- IMMEDIATE @ONLY)
+ @ONLY)
endif()
diff --git a/Modules/CMakeDetermineVSServicePack.cmake b/Modules/CMakeDetermineVSServicePack.cmake
index f49482e7f..688608479 100644
--- a/Modules/CMakeDetermineVSServicePack.cmake
+++ b/Modules/CMakeDetermineVSServicePack.cmake
@@ -1,22 +1,32 @@
-# - Determine the Visual Studio service pack of the 'cl' in use.
-# The functionality of this module has been superseded by the platform
-# variable CMAKE_<LANG>_COMPILER_VERSION that contains the compiler version
-# number.
+#.rst:
+# CMakeDetermineVSServicePack
+# ---------------------------
+#
+# Deprecated. Do not use.
+#
+# The functionality of this module has been superseded by the
+# :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable that contains
+# the compiler version number.
+#
+# Determine the Visual Studio service pack of the 'cl' in use.
+#
+# Usage::
+#
+# if(MSVC)
+# include(CMakeDetermineVSServicePack)
+# DetermineVSServicePack( my_service_pack )
+# if( my_service_pack )
+# message(STATUS "Detected: ${my_service_pack}")
+# endif()
+# endif()
#
-# Usage:
-# if(MSVC)
-# include(CMakeDetermineVSServicePack)
-# DetermineVSServicePack( my_service_pack )
-# if( my_service_pack )
-# message(STATUS "Detected: ${my_service_pack}")
-# endif()
-# endif()
# Function DetermineVSServicePack sets the given variable to one of the
-# following values or an empty string if unknown:
-# vc80, vc80sp1
-# vc90, vc90sp1
-# vc100, vc100sp1
-# vc110, vc110sp1, vc110sp2
+# following values or an empty string if unknown::
+#
+# vc80, vc80sp1
+# vc90, vc90sp1
+# vc100, vc100sp1
+# vc110, vc110sp1, vc110sp2, vc110sp3, vc110sp4
#=============================================================================
# Copyright 2009-2013 Kitware, Inc.
@@ -33,6 +43,13 @@
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
+if(NOT CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.8)
+ message(DEPRECATION
+ "This module is deprecated and should not be used. "
+ "Use the CMAKE_<LANG>_COMPILER_VERSION variable instead."
+ )
+endif()
+
# [INTERNAL]
# Please do not call this function directly
function(_DetermineVSServicePackFromCompiler _OUT_VAR _cl_version)
@@ -56,6 +73,8 @@ function(_DetermineVSServicePackFromCompiler _OUT_VAR _cl_version)
set(_version "vc110sp2")
elseif(${_cl_version} VERSION_EQUAL "17.00.60610.1")
set(_version "vc110sp3")
+ elseif(${_cl_version} VERSION_EQUAL "17.00.61030")
+ set(_version "vc110sp4")
else()
set(_version "")
endif()
@@ -74,27 +93,14 @@ function(_DetermineVSServicePack_FastCheckVersionWithCompiler _SUCCESS_VAR _VER
OUTPUT_QUIET
)
- string(REGEX MATCH "Compiler Version [0-9]+.[0-9]+.[0-9]+.[0-9]+"
- _cl_version "${_output}")
-
- if(_cl_version)
- string(REGEX MATCHALL "[0-9]+"
- _cl_version_list "${_cl_version}")
- list(GET _cl_version_list 0 _major)
- list(GET _cl_version_list 1 _minor)
- list(GET _cl_version_list 2 _patch)
- list(GET _cl_version_list 3 _tweak)
-
+ if(_output MATCHES "Compiler Version (([0-9]+)\\.([0-9]+)\\.([0-9]+)(\\.([0-9]+))?)")
+ set(_cl_version ${CMAKE_MATCH_1})
+ set(_major ${CMAKE_MATCH_2})
+ set(_minor ${CMAKE_MATCH_3})
if("${_major}${_minor}" STREQUAL "${MSVC_VERSION}")
- set(_cl_version ${_major}.${_minor}.${_patch}.${_tweak})
- else()
- unset(_cl_version)
- endif()
- endif()
-
- if(_cl_version)
set(${_SUCCESS_VAR} true PARENT_SCOPE)
set(${_VERSION_VAR} ${_cl_version} PARENT_SCOPE)
+ endif()
endif()
endif()
endfunction()
@@ -115,20 +121,9 @@ function(_DetermineVSServicePack_CheckVersionWithTryCompile _SUCCESS_VAR _VERSI
file(REMOVE "${CMAKE_BINARY_DIR}/return0.cc")
- string(REGEX MATCH "Compiler Version [0-9]+.[0-9]+.[0-9]+.[0-9]+"
- _cl_version "${_output}")
-
- if(_cl_version)
- string(REGEX MATCHALL "[0-9]+"
- _cl_version_list "${_cl_version}")
-
- list(GET _cl_version_list 0 _major)
- list(GET _cl_version_list 1 _minor)
- list(GET _cl_version_list 2 _patch)
- list(GET _cl_version_list 3 _tweak)
-
+ if(_output MATCHES "Compiler Version (([0-9]+)\\.([0-9]+)\\.([0-9]+)(\\.([0-9]+))?)")
set(${_SUCCESS_VAR} true PARENT_SCOPE)
- set(${_VERSION_VAR} ${_major}.${_minor}.${_patch}.${_tweak} PARENT_SCOPE)
+ set(${_VERSION_VAR} "${CMAKE_MATCH_1}" PARENT_SCOPE)
endif()
endfunction()
diff --git a/Modules/CMakeExpandImportedTargets.cmake b/Modules/CMakeExpandImportedTargets.cmake
index f5c009cad..28f2e468d 100644
--- a/Modules/CMakeExpandImportedTargets.cmake
+++ b/Modules/CMakeExpandImportedTargets.cmake
@@ -1,19 +1,38 @@
-# CMAKE_EXPAND_IMPORTED_TARGETS(<var> LIBRARIES lib1 lib2...libN
-# [CONFIGURATION <config>] )
+#.rst:
+# CMakeExpandImportedTargets
+# --------------------------
+#
+# Deprecated. Do not use.
+#
+# This module was once needed to expand imported targets to the underlying
+# libraries they reference on disk for use with the :command:`try_compile`
+# and :command:`try_run` commands. These commands now support imported
+# libraries in their ``LINK_LIBRARIES`` options (since CMake 2.8.11
+# for :command:`try_compile` and since CMake 3.2 for :command:`try_run`).
+#
+# This module does not support the policy :policy:`CMP0022` ``NEW``
+# behavior or use of the :prop_tgt:`INTERFACE_LINK_LIBRARIES` property
+# because :manual:`generator expressions <cmake-generator-expressions(7)>`
+# cannot be evaluated during configuration.
+#
+# ::
+#
+# CMAKE_EXPAND_IMPORTED_TARGETS(<var> LIBRARIES lib1 lib2...libN
+# [CONFIGURATION <config>])
#
# CMAKE_EXPAND_IMPORTED_TARGETS() takes a list of libraries and replaces
-# all imported targets contained in this list with their actual file paths
-# of the referenced libraries on disk, including the libraries from their
-# link interfaces.
-# If a CONFIGURATION is given, it uses the respective configuration of the
-# imported targets if it exists. If no CONFIGURATION is given, it uses
-# the first configuration from ${CMAKE_CONFIGURATION_TYPES} if set, otherwise
-# ${CMAKE_BUILD_TYPE}.
-# This macro is used by all Check*.cmake files which use
-# try_compile() or try_run() and support CMAKE_REQUIRED_LIBRARIES , so that
-# these checks support imported targets in CMAKE_REQUIRED_LIBRARIES:
-# cmake_expand_imported_targets(expandedLibs LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}
-# CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}" )
+# all imported targets contained in this list with their actual file
+# paths of the referenced libraries on disk, including the libraries
+# from their link interfaces. If a CONFIGURATION is given, it uses the
+# respective configuration of the imported targets if it exists. If no
+# CONFIGURATION is given, it uses the first configuration from
+# ${CMAKE_CONFIGURATION_TYPES} if set, otherwise ${CMAKE_BUILD_TYPE}.
+#
+# ::
+#
+# cmake_expand_imported_targets(expandedLibs
+# LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}
+# CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}" )
#=============================================================================
@@ -63,7 +82,11 @@ function(CMAKE_EXPAND_IMPORTED_TARGETS _RESULT )
set(_CCSR_NEW_REQ_LIBS )
set(_CHECK_FOR_IMPORTED_TARGETS FALSE)
foreach(_CURRENT_LIB ${_CCSR_REQ_LIBS})
- get_target_property(_importedConfigs "${_CURRENT_LIB}" IMPORTED_CONFIGURATIONS)
+ if(TARGET "${_CURRENT_LIB}")
+ get_target_property(_importedConfigs "${_CURRENT_LIB}" IMPORTED_CONFIGURATIONS)
+ else()
+ set(_importedConfigs "")
+ endif()
if (_importedConfigs)
# message(STATUS "Detected imported target ${_CURRENT_LIB}")
# Ok, so this is an imported target.
@@ -115,7 +138,11 @@ function(CMAKE_EXPAND_IMPORTED_TARGETS _RESULT )
# all remaining imported target names (there shouldn't be any left anyway).
set(_CCSR_NEW_REQ_LIBS )
foreach(_CURRENT_LIB ${_CCSR_REQ_LIBS})
- get_target_property(_importedConfigs "${_CURRENT_LIB}" IMPORTED_CONFIGURATIONS)
+ if(TARGET "${_CURRENT_LIB}")
+ get_target_property(_importedConfigs "${_CURRENT_LIB}" IMPORTED_CONFIGURATIONS)
+ else()
+ set(_importedConfigs "")
+ endif()
if (NOT _importedConfigs)
list(APPEND _CCSR_NEW_REQ_LIBS "${_CURRENT_LIB}" )
# message(STATUS "final: appending ${_CURRENT_LIB}")
diff --git a/Modules/CMakeExportBuildSettings.cmake b/Modules/CMakeExportBuildSettings.cmake
index a18f95062..a8dd8c282 100644
--- a/Modules/CMakeExportBuildSettings.cmake
+++ b/Modules/CMakeExportBuildSettings.cmake
@@ -27,9 +27,9 @@ endif()
# loaded by another project using CMAKE_IMPORT_BUILD_SETTINGS. Now it
# creates a file that refuses to load (with comment explaining why).
macro(CMAKE_EXPORT_BUILD_SETTINGS SETTINGS_FILE)
- if(${SETTINGS_FILE} MATCHES ".+")
+ if(NOT ${SETTINGS_FILE} STREQUAL "")
configure_file(${CMAKE_ROOT}/Modules/CMakeBuildSettings.cmake.in
- ${SETTINGS_FILE} @ONLY IMMEDIATE)
+ ${SETTINGS_FILE} @ONLY)
else()
message(SEND_ERROR "CMAKE_EXPORT_BUILD_SETTINGS called with no argument.")
endif()
diff --git a/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake b/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake
index 365d381ef..3bfb876f1 100644
--- a/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake
+++ b/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake
@@ -26,11 +26,18 @@ macro(_DETERMINE_GCC_SYSTEM_INCLUDE_DIRS _lang _resultIncludeDirs _resultDefines
if (${_lang} STREQUAL "c++")
set(_compilerExecutable "${CMAKE_CXX_COMPILER}")
set(_arg1 "${CMAKE_CXX_COMPILER_ARG1}")
+
+ if (CMAKE_CXX_FLAGS MATCHES "(-stdlib=[^ ]+)")
+ set(_stdlib "${CMAKE_MATCH_1}")
+ endif ()
+ if (CMAKE_CXX_FLAGS MATCHES "(-std=[^ ]+)")
+ set(_stdver "${CMAKE_MATCH_1}")
+ endif ()
else ()
set(_compilerExecutable "${CMAKE_C_COMPILER}")
set(_arg1 "${CMAKE_C_COMPILER_ARG1}")
endif ()
- execute_process(COMMAND ${_compilerExecutable} ${_arg1} -v -E -x ${_lang} -dD dummy
+ execute_process(COMMAND ${_compilerExecutable} ${_arg1} ${_stdver} ${_stdlib} -v -E -x ${_lang} -dD dummy
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/CMakeFiles
ERROR_VARIABLE _gccOutput
OUTPUT_VARIABLE _gccStdout )
@@ -90,10 +97,12 @@ set(ENV{LANG} C)
# Now check for C, works for gcc and Intel compiler at least
if (NOT CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS)
- if ("${CMAKE_C_COMPILER_ID}" MATCHES GNU OR "${CMAKE_C_COMPILER_ID}" MATCHES Intel OR "${CMAKE_C_COMPILER_ID}" MATCHES Clang)
+ if (CMAKE_C_COMPILER_ID MATCHES GNU OR CMAKE_C_COMPILER_ID MATCHES Intel OR CMAKE_C_COMPILER_ID MATCHES Clang)
_DETERMINE_GCC_SYSTEM_INCLUDE_DIRS(c _dirs _defines)
set(CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS "${_dirs}" CACHE INTERNAL "C compiler system include directories")
set(CMAKE_EXTRA_GENERATOR_C_SYSTEM_DEFINED_MACROS "${_defines}" CACHE INTERNAL "C compiler system defined macros")
+ elseif ("${CMAKE_C_COMPILER_ID}" MATCHES MSVC)
+ set(CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS "$ENV{INCLUDE}" CACHE INTERNAL "C compiler system include directories")
endif ()
endif ()
@@ -103,6 +112,8 @@ if (NOT CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS)
_DETERMINE_GCC_SYSTEM_INCLUDE_DIRS(c++ _dirs _defines)
set(CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS "${_dirs}" CACHE INTERNAL "CXX compiler system include directories")
set(CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_DEFINED_MACROS "${_defines}" CACHE INTERNAL "CXX compiler system defined macros")
+ elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES MSVC)
+ set(CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS "$ENV{INCLUDE}" CACHE INTERNAL "CXX compiler system include directories")
endif ()
endif ()
diff --git a/Modules/CMakeFindBinUtils.cmake b/Modules/CMakeFindBinUtils.cmake
index e70c013be..376a6dcf7 100644
--- a/Modules/CMakeFindBinUtils.cmake
+++ b/Modules/CMakeFindBinUtils.cmake
@@ -30,9 +30,13 @@
# License text for the above reference.)
# if it's the MS C/CXX compiler, search for link
-if("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC"
- OR "${CMAKE_C_COMPILER_ID}" MATCHES "MSVC"
- OR "${CMAKE_GENERATOR}" MATCHES "Visual Studio")
+if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC"
+ OR "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC"
+ OR "x${CMAKE_Fortran_SIMULATE_ID}" STREQUAL "xMSVC"
+ OR "x${CMAKE_C_COMPILER_ID}" STREQUAL "xMSVC"
+ OR "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC"
+ OR (CMAKE_GENERATOR MATCHES "Visual Studio"
+ AND NOT CMAKE_VS_PLATFORM_NAME STREQUAL "Tegra-Android"))
find_program(CMAKE_LINKER NAMES link HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
@@ -40,7 +44,12 @@ if("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC"
# in all other cases search for ar, ranlib, etc.
else()
-
+ if(CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN)
+ set(_CMAKE_TOOLCHAIN_LOCATION ${_CMAKE_TOOLCHAIN_LOCATION} ${CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN}/bin)
+ endif()
+ if(CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN)
+ set(_CMAKE_TOOLCHAIN_LOCATION ${_CMAKE_TOOLCHAIN_LOCATION} ${CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN}/bin)
+ endif()
find_program(CMAKE_AR NAMES ${_CMAKE_TOOLCHAIN_PREFIX}ar${_CMAKE_TOOLCHAIN_SUFFIX} HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
find_program(CMAKE_RANLIB NAMES ${_CMAKE_TOOLCHAIN_PREFIX}ranlib HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
@@ -58,9 +67,7 @@ else()
endif()
-
-# on Apple there really should be install_name_tool
-if(APPLE)
+if(CMAKE_PLATFORM_HAS_INSTALLNAME)
find_program(CMAKE_INSTALL_NAME_TOOL NAMES install_name_tool HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
if(NOT CMAKE_INSTALL_NAME_TOOL)
diff --git a/Modules/CMakeFindDependencyMacro.cmake b/Modules/CMakeFindDependencyMacro.cmake
new file mode 100644
index 000000000..73efaae7c
--- /dev/null
+++ b/Modules/CMakeFindDependencyMacro.cmake
@@ -0,0 +1,85 @@
+#.rst:
+# CMakeFindDependencyMacro
+# -------------------------
+#
+# ::
+#
+# find_dependency(<dep> [<version> [EXACT]])
+#
+#
+# ``find_dependency()`` wraps a :command:`find_package` call for a package
+# dependency. It is designed to be used in a <package>Config.cmake file, and it
+# forwards the correct parameters for EXACT, QUIET and REQUIRED which were
+# passed to the original :command:`find_package` call. It also sets an
+# informative diagnostic message if the dependency could not be found.
+#
+
+#=============================================================================
+# Copyright 2013 Stephen Kelly <steveire@gmail.com>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+macro(find_dependency dep)
+ if (NOT ${dep}_FOUND)
+ set(cmake_fd_version)
+ if (${ARGC} GREATER 1)
+ if ("${ARGV1}" STREQUAL "")
+ message(FATAL_ERROR "Invalid arguments to find_dependency. VERSION is empty")
+ endif()
+ if ("${ARGV1}" STREQUAL EXACT)
+ message(FATAL_ERROR "Invalid arguments to find_dependency. EXACT may only be specified if a VERSION is specified")
+ endif()
+ set(cmake_fd_version ${ARGV1})
+ endif()
+ set(cmake_fd_exact_arg)
+ if(${ARGC} GREATER 2)
+ if (NOT "${ARGV2}" STREQUAL EXACT)
+ message(FATAL_ERROR "Invalid arguments to find_dependency")
+ endif()
+ set(cmake_fd_exact_arg EXACT)
+ endif()
+ if(${ARGC} GREATER 3)
+ message(FATAL_ERROR "Invalid arguments to find_dependency")
+ endif()
+ set(cmake_fd_quiet_arg)
+ if(${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY)
+ set(cmake_fd_quiet_arg QUIET)
+ endif()
+ set(cmake_fd_required_arg)
+ if(${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED)
+ set(cmake_fd_required_arg REQUIRED)
+ endif()
+
+ get_property(cmake_fd_alreadyTransitive GLOBAL PROPERTY
+ _CMAKE_${dep}_TRANSITIVE_DEPENDENCY
+ )
+
+ find_package(${dep} ${cmake_fd_version}
+ ${cmake_fd_exact_arg}
+ ${cmake_fd_quiet_arg}
+ ${cmake_fd_required_arg}
+ )
+
+ if(NOT DEFINED cmake_fd_alreadyTransitive OR cmake_fd_alreadyTransitive)
+ set_property(GLOBAL PROPERTY _CMAKE_${dep}_TRANSITIVE_DEPENDENCY TRUE)
+ endif()
+
+ if (NOT ${dep}_FOUND)
+ set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "${CMAKE_FIND_PACKAGE_NAME} could not be found because dependency ${dep} could not be found.")
+ set(${CMAKE_FIND_PACKAGE_NAME}_FOUND False)
+ return()
+ endif()
+ set(cmake_fd_version)
+ set(cmake_fd_required_arg)
+ set(cmake_fd_quiet_arg)
+ set(cmake_fd_exact_arg)
+ endif()
+endmacro()
diff --git a/Modules/CMakeFindEclipseCDT4.cmake b/Modules/CMakeFindEclipseCDT4.cmake
index ae174544b..85c1fdf5b 100644
--- a/Modules/CMakeFindEclipseCDT4.cmake
+++ b/Modules/CMakeFindEclipseCDT4.cmake
@@ -19,18 +19,6 @@ find_program(CMAKE_ECLIPSE_EXECUTABLE NAMES eclipse DOC "The Eclipse executable"
function(_FIND_ECLIPSE_VERSION)
# This code is in a function so the variables used here have only local scope
- if(CMAKE_ECLIPSE_EXECUTABLE)
- # use REALPATH to resolve symlinks (http://public.kitware.com/Bug/view.php?id=13036)
- get_filename_component(_REALPATH_CMAKE_ECLIPSE_EXECUTABLE "${CMAKE_ECLIPSE_EXECUTABLE}" REALPATH)
- get_filename_component(_ECLIPSE_DIR "${_REALPATH_CMAKE_ECLIPSE_EXECUTABLE}" PATH)
- file(GLOB _ECLIPSE_FEATURE_DIR "${_ECLIPSE_DIR}/features/org.eclipse.platform*")
- if(APPLE AND NOT _ECLIPSE_FEATURE_DIR)
- file(GLOB _ECLIPSE_FEATURE_DIR "${_ECLIPSE_DIR}/../../../features/org.eclipse.platform*")
- endif()
- if("${_ECLIPSE_FEATURE_DIR}" MATCHES ".+org.eclipse.platform_([0-9]+\\.[0-9]+).+")
- set(_ECLIPSE_VERSION ${CMAKE_MATCH_1})
- endif()
- endif()
# Set up a map with the names of the Eclipse releases:
set(_ECLIPSE_VERSION_NAME_ "Unknown" )
@@ -41,15 +29,34 @@ function(_FIND_ECLIPSE_VERSION)
set(_ECLIPSE_VERSION_NAME_3.6 "Helios" )
set(_ECLIPSE_VERSION_NAME_3.7 "Indigo" )
set(_ECLIPSE_VERSION_NAME_4.2 "Juno" )
+ set(_ECLIPSE_VERSION_NAME_4.3 "Kepler" )
+
+ if(NOT DEFINED CMAKE_ECLIPSE_VERSION)
+ if(CMAKE_ECLIPSE_EXECUTABLE)
+ # use REALPATH to resolve symlinks (http://public.kitware.com/Bug/view.php?id=13036)
+ get_filename_component(_REALPATH_CMAKE_ECLIPSE_EXECUTABLE "${CMAKE_ECLIPSE_EXECUTABLE}" REALPATH)
+ get_filename_component(_ECLIPSE_DIR "${_REALPATH_CMAKE_ECLIPSE_EXECUTABLE}" PATH)
+ file(GLOB _ECLIPSE_FEATURE_DIR "${_ECLIPSE_DIR}/features/org.eclipse.platform*")
+ if(APPLE AND NOT _ECLIPSE_FEATURE_DIR)
+ file(GLOB _ECLIPSE_FEATURE_DIR "${_ECLIPSE_DIR}/../../../features/org.eclipse.platform*")
+ endif()
+ if("${_ECLIPSE_FEATURE_DIR}" MATCHES ".+org.eclipse.platform_([0-9]+\\.[0-9]+).+")
+ set(_ECLIPSE_VERSION ${CMAKE_MATCH_1})
+ endif()
+ endif()
+
+ if(_ECLIPSE_VERSION)
+ message(STATUS "Found Eclipse version ${_ECLIPSE_VERSION} (${_ECLIPSE_VERSION_NAME_${_ECLIPSE_VERSION}})")
+ else()
+ set(_ECLIPSE_VERSION "3.6" )
+ message(STATUS "Could not determine Eclipse version, assuming at least ${_ECLIPSE_VERSION} (${_ECLIPSE_VERSION_NAME_${_ECLIPSE_VERSION}}). Adjust CMAKE_ECLIPSE_VERSION if this is wrong.")
+ endif()
- if(_ECLIPSE_VERSION)
- message(STATUS "Found Eclipse version ${_ECLIPSE_VERSION} (${_ECLIPSE_VERSION_NAME_${_ECLIPSE_VERSION}})")
+ set(CMAKE_ECLIPSE_VERSION "${_ECLIPSE_VERSION} (${_ECLIPSE_VERSION_NAME_${_ECLIPSE_VERSION}})" CACHE STRING "The version of Eclipse. If Eclipse has not been found, 3.6 (Helios) is assumed.")
else()
- set(_ECLIPSE_VERSION "3.6" )
- message(STATUS "Could not determine Eclipse version, assuming at least ${_ECLIPSE_VERSION} (${_ECLIPSE_VERSION_NAME_${_ECLIPSE_VERSION}}). Adjust CMAKE_ECLIPSE_VERSION if this is wrong.")
+ message(STATUS "Eclipse version is set to ${CMAKE_ECLIPSE_VERSION}. Adjust CMAKE_ECLIPSE_VERSION if this is wrong.")
endif()
- set(CMAKE_ECLIPSE_VERSION "${_ECLIPSE_VERSION} (${_ECLIPSE_VERSION_NAME_${_ECLIPSE_VERSION}})" CACHE STRING "The version of Eclipse. If Eclipse has not been found, 3.6 (Helios) is assumed.")
set_property(CACHE CMAKE_ECLIPSE_VERSION PROPERTY STRINGS "3.2 (${_ECLIPSE_VERSION_NAME_3.2})"
"3.3 (${_ECLIPSE_VERSION_NAME_3.3})"
"3.4 (${_ECLIPSE_VERSION_NAME_3.4})"
@@ -57,20 +64,21 @@ function(_FIND_ECLIPSE_VERSION)
"3.6 (${_ECLIPSE_VERSION_NAME_3.6})"
"3.7 (${_ECLIPSE_VERSION_NAME_3.7})"
"4.2 (${_ECLIPSE_VERSION_NAME_4.2})"
+ "4.3 (${_ECLIPSE_VERSION_NAME_4.3})"
)
endfunction()
-_FIND_ECLIPSE_VERSION()
+_find_eclipse_version()
# Try to find out how many CPUs we have and set the -j argument for make accordingly
set(_CMAKE_ECLIPSE_INITIAL_MAKE_ARGS "")
include(ProcessorCount)
-PROCESSORCOUNT(_CMAKE_ECLIPSE_PROCESSOR_COUNT)
+processorcount(_CMAKE_ECLIPSE_PROCESSOR_COUNT)
# Only set -j if we are under UNIX and if the make-tool used actually has "make" in the name
# (we may also get here in the future e.g. for ninja)
-if("${_CMAKE_ECLIPSE_PROCESSOR_COUNT}" GREATER 1 AND UNIX AND "${CMAKE_MAKE_PROGRAM}" MATCHES make)
+if("${_CMAKE_ECLIPSE_PROCESSOR_COUNT}" GREATER 1 AND CMAKE_HOST_UNIX AND "${CMAKE_MAKE_PROGRAM}" MATCHES make)
set(_CMAKE_ECLIPSE_INITIAL_MAKE_ARGS "-j${_CMAKE_ECLIPSE_PROCESSOR_COUNT}")
endif()
diff --git a/Modules/CMakeFindFrameworks.cmake b/Modules/CMakeFindFrameworks.cmake
index 7fdeb84be..6a8bcd454 100644
--- a/Modules/CMakeFindFrameworks.cmake
+++ b/Modules/CMakeFindFrameworks.cmake
@@ -1,4 +1,8 @@
-# - helper module to find OSX frameworks
+#.rst:
+# CMakeFindFrameworks
+# -------------------
+#
+# helper module to find OSX frameworks
#=============================================================================
# Copyright 2003-2009 Kitware, Inc.
diff --git a/Modules/CMakeFindJavaCommon.cmake b/Modules/CMakeFindJavaCommon.cmake
new file mode 100644
index 000000000..fcf038970
--- /dev/null
+++ b/Modules/CMakeFindJavaCommon.cmake
@@ -0,0 +1,41 @@
+
+#=============================================================================
+# Copyright 2013-2014 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# Do not include this module directly from code outside CMake!
+set(_JAVA_HOME "")
+if(JAVA_HOME AND IS_DIRECTORY "${JAVA_HOME}")
+ set(_JAVA_HOME "${JAVA_HOME}")
+ set(_JAVA_HOME_EXPLICIT 1)
+else()
+ set(_ENV_JAVA_HOME "")
+ if(DEFINED ENV{JAVA_HOME})
+ file(TO_CMAKE_PATH "$ENV{JAVA_HOME}" _ENV_JAVA_HOME)
+ endif()
+ if(_ENV_JAVA_HOME AND IS_DIRECTORY "${_ENV_JAVA_HOME}")
+ set(_JAVA_HOME "${_ENV_JAVA_HOME}")
+ set(_JAVA_HOME_EXPLICIT 1)
+ else()
+ set(_CMD_JAVA_HOME "")
+ if(APPLE AND EXISTS /usr/libexec/java_home)
+ execute_process(COMMAND /usr/libexec/java_home
+ OUTPUT_VARIABLE _CMD_JAVA_HOME OUTPUT_STRIP_TRAILING_WHITESPACE)
+ endif()
+ if(_CMD_JAVA_HOME AND IS_DIRECTORY "${_CMD_JAVA_HOME}")
+ set(_JAVA_HOME "${_CMD_JAVA_HOME}")
+ set(_JAVA_HOME_EXPLICIT 0)
+ endif()
+ unset(_CMD_JAVA_HOME)
+ endif()
+ unset(_ENV_JAVA_HOME)
+endif()
diff --git a/Modules/CMakeFindKate.cmake b/Modules/CMakeFindKate.cmake
new file mode 100644
index 000000000..4dcdb2841
--- /dev/null
+++ b/Modules/CMakeFindKate.cmake
@@ -0,0 +1,31 @@
+
+#=============================================================================
+# Copyright 2009 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# This file is included in CMakeSystemSpecificInformation.cmake if
+# the Eclipse CDT4 extra generator has been selected.
+
+
+# Try to find out how many CPUs we have and set the -j argument for make accordingly
+
+include(ProcessorCount)
+processorcount(_CMAKE_KATE_PROCESSOR_COUNT)
+
+# Only set -j if we are under UNIX and if the make-tool used actually has "make" in the name
+# (we may also get here in the future e.g. for ninja)
+if("${_CMAKE_KATE_PROCESSOR_COUNT}" GREATER 1 AND CMAKE_HOST_UNIX AND "${CMAKE_MAKE_PROGRAM}" MATCHES make)
+ set(_CMAKE_KATE_INITIAL_MAKE_ARGS "-j${_CMAKE_KATE_PROCESSOR_COUNT}")
+endif()
+
+# This variable is used by the Eclipse generator and appended to the make invocation commands.
+set(CMAKE_KATE_MAKE_ARGUMENTS "${_CMAKE_KATE_INITIAL_MAKE_ARGS}" CACHE STRING "Additional command line arguments when Kate invokes make. Enter e.g. -j<some_number> to get parallel builds")
diff --git a/Modules/CMakeFindPackageMode.cmake b/Modules/CMakeFindPackageMode.cmake
index e5216f4e0..26731dc6e 100644
--- a/Modules/CMakeFindPackageMode.cmake
+++ b/Modules/CMakeFindPackageMode.cmake
@@ -1,12 +1,30 @@
-# This file is executed by cmake when invoked with --find-package.
-# It expects that the following variables are set using -D:
-# NAME = name of the package
-# COMPILER_ID = the CMake compiler ID for which the result is, i.e. GNU/Intel/Clang/MSVC, etc.
-# LANGUAGE = language for which the result will be used, i.e. C/CXX/Fortan/ASM
-# MODE = EXIST : only check for existence of the given package
-# COMPILE : print the flags needed for compiling an object file which uses the given package
-# LINK : print the flags needed for linking when using the given package
-# QUIET = if TRUE, don't print anything
+#.rst:
+# CMakeFindPackageMode
+# --------------------
+#
+#
+#
+# This file is executed by cmake when invoked with --find-package. It
+# expects that the following variables are set using -D:
+#
+# ``NAME``
+# name of the package
+# ``COMPILER_ID``
+# the CMake compiler ID for which the result is,
+# i.e. GNU/Intel/Clang/MSVC, etc.
+# ``LANGUAGE``
+# language for which the result will be used,
+# i.e. C/CXX/Fortan/ASM
+# ``MODE``
+# ``EXIST``
+# only check for existence of the given package
+# ``COMPILE``
+# print the flags needed for compiling an object file which uses
+# the given package
+# ``LINK``
+# print the flags needed for linking when using the given package
+# ``QUIET``
+# if TRUE, don't print anything
#=============================================================================
# Copyright 2006-2011 Alexander Neundorf, <neundorf@kde.org>
@@ -84,15 +102,18 @@ if(UNIX)
# guess Debian multiarch if it has not been set:
if(EXISTS /etc/debian_version)
- if(NOT CMAKE_${LANGUAGE}_LANGUAGE_ARCHITECTURE )
+ if(NOT CMAKE_${LANGUAGE}_LIBRARY_ARCHITECTURE )
file(GLOB filesInLib RELATIVE /lib /lib/*-linux-gnu* )
foreach(file ${filesInLib})
if("${file}" MATCHES "${CMAKE_LIBRARY_ARCHITECTURE_REGEX}")
- set(CMAKE_${LANGUAGE}_LANGUAGE_ARCHITECTURE ${file})
+ set(CMAKE_${LANGUAGE}_LIBRARY_ARCHITECTURE ${file})
break()
endif()
endforeach()
endif()
+ if(NOT CMAKE_LIBRARY_ARCHITECTURE)
+ set(CMAKE_LIBRARY_ARCHITECTURE ${CMAKE_${LANGUAGE}_LIBRARY_ARCHITECTURE})
+ endif()
endif()
endif()
diff --git a/Modules/CMakeFindXCode.cmake b/Modules/CMakeFindXCode.cmake
index 5c4f59639..da0b97b0d 100644
--- a/Modules/CMakeFindXCode.cmake
+++ b/Modules/CMakeFindXCode.cmake
@@ -12,9 +12,5 @@
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
-find_program(CMAKE_MAKE_PROGRAM
- NAMES xcodebuild
- PATHS
- /usr/bin
- )
-mark_as_advanced(CMAKE_MAKE_PROGRAM)
+# Empty placeholder for input dependencies in existing
+# build trees produced by older versions of CMake.
diff --git a/Modules/CMakeForceCompiler.cmake b/Modules/CMakeForceCompiler.cmake
index 207c8ad35..faa0dc58c 100644
--- a/Modules/CMakeForceCompiler.cmake
+++ b/Modules/CMakeForceCompiler.cmake
@@ -1,33 +1,68 @@
-# This module defines macros intended for use by cross-compiling
-# toolchain files when CMake is not able to automatically detect the
-# compiler identification.
+#.rst:
+# CMakeForceCompiler
+# ------------------
+#
+# Discouraged. Avoid using this module if possible. It will be deprecated
+# by a future version of CMake once alternatives have been provided for all
+# toolchain file use cases.
+#
+# The macros provided by this module were once intended for use by
+# cross-compiling toolchain files when CMake was not able to automatically
+# detect the compiler identification. Since the introduction of this module,
+# CMake's compiler identification capabilities have improved and can now be
+# taught to recognize any compiler. Furthermore, the suite of information
+# CMake detects from a compiler is now too extensive to be provided by
+# toolchain files using these macros.
+#
+# The only known remaining use case for these macros is to write toolchain
+# files for cross-compilers that cannot link binaries without special flags or
+# custom linker scripts. These macros cause CMake to skip checks it normally
+# performs as part of enabling a language and introspecting the toolchain.
+# However, skipping these checks may limit some generation functionality.
+#
+# -------------------------------------------------------------------------
#
# Macro CMAKE_FORCE_C_COMPILER has the following signature:
-# CMAKE_FORCE_C_COMPILER(<compiler> <compiler-id>)
-# It sets CMAKE_C_COMPILER to the given compiler and the cmake
-# internal variable CMAKE_C_COMPILER_ID to the given compiler-id.
-# It also bypasses the check for working compiler and basic compiler
-# information tests.
+#
+# ::
+#
+# CMAKE_FORCE_C_COMPILER(<compiler> <compiler-id>)
+#
+# It sets CMAKE_C_COMPILER to the given compiler and the cmake internal
+# variable CMAKE_C_COMPILER_ID to the given compiler-id. It also
+# bypasses the check for working compiler and basic compiler information
+# tests.
#
# Macro CMAKE_FORCE_CXX_COMPILER has the following signature:
-# CMAKE_FORCE_CXX_COMPILER(<compiler> <compiler-id>)
+#
+# ::
+#
+# CMAKE_FORCE_CXX_COMPILER(<compiler> <compiler-id>)
+#
# It sets CMAKE_CXX_COMPILER to the given compiler and the cmake
-# internal variable CMAKE_CXX_COMPILER_ID to the given compiler-id.
-# It also bypasses the check for working compiler and basic compiler
+# internal variable CMAKE_CXX_COMPILER_ID to the given compiler-id. It
+# also bypasses the check for working compiler and basic compiler
# information tests.
#
# Macro CMAKE_FORCE_Fortran_COMPILER has the following signature:
-# CMAKE_FORCE_Fortran_COMPILER(<compiler> <compiler-id>)
+#
+# ::
+#
+# CMAKE_FORCE_Fortran_COMPILER(<compiler> <compiler-id>)
+#
# It sets CMAKE_Fortran_COMPILER to the given compiler and the cmake
# internal variable CMAKE_Fortran_COMPILER_ID to the given compiler-id.
# It also bypasses the check for working compiler and basic compiler
# information tests.
#
# So a simple toolchain file could look like this:
-# include (CMakeForceCompiler)
-# set(CMAKE_SYSTEM_NAME Generic)
-# CMAKE_FORCE_C_COMPILER (chc12 MetrowerksHicross)
-# CMAKE_FORCE_CXX_COMPILER (chc12 MetrowerksHicross)
+#
+# ::
+#
+# include (CMakeForceCompiler)
+# set(CMAKE_SYSTEM_NAME Generic)
+# CMAKE_FORCE_C_COMPILER (chc12 MetrowerksHicross)
+# CMAKE_FORCE_CXX_COMPILER (chc12 MetrowerksHicross)
#=============================================================================
# Copyright 2007-2009 Kitware, Inc.
@@ -49,7 +84,7 @@ macro(CMAKE_FORCE_C_COMPILER compiler id)
set(CMAKE_C_COMPILER_FORCED TRUE)
# Set old compiler id variables.
- if("${CMAKE_C_COMPILER_ID}" MATCHES "GNU")
+ if(CMAKE_C_COMPILER_ID MATCHES "GNU")
set(CMAKE_COMPILER_IS_GNUCC 1)
endif()
endmacro()
@@ -73,7 +108,7 @@ macro(CMAKE_FORCE_Fortran_COMPILER compiler id)
set(CMAKE_Fortran_COMPILER_FORCED TRUE)
# Set old compiler id variables.
- if("${CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU")
+ if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
set(CMAKE_COMPILER_IS_GNUG77 1)
endif()
endmacro()
diff --git a/Modules/CMakeFortranCompiler.cmake.in b/Modules/CMakeFortranCompiler.cmake.in
index d193881d9..2a4bea494 100644
--- a/Modules/CMakeFortranCompiler.cmake.in
+++ b/Modules/CMakeFortranCompiler.cmake.in
@@ -1,7 +1,11 @@
set(CMAKE_Fortran_COMPILER "@CMAKE_Fortran_COMPILER@")
set(CMAKE_Fortran_COMPILER_ARG1 "@CMAKE_Fortran_COMPILER_ARG1@")
set(CMAKE_Fortran_COMPILER_ID "@CMAKE_Fortran_COMPILER_ID@")
+set(CMAKE_Fortran_COMPILER_VERSION "@CMAKE_Fortran_COMPILER_VERSION@")
+set(CMAKE_Fortran_COMPILER_WRAPPER "@CMAKE_Fortran_COMPILER_WRAPPER@")
set(CMAKE_Fortran_PLATFORM_ID "@CMAKE_Fortran_PLATFORM_ID@")
+set(CMAKE_Fortran_SIMULATE_ID "@CMAKE_Fortran_SIMULATE_ID@")
+set(CMAKE_Fortran_SIMULATE_VERSION "@CMAKE_Fortran_SIMULATE_VERSION@")
@SET_MSVC_Fortran_ARCHITECTURE_ID@
set(CMAKE_AR "@CMAKE_AR@")
set(CMAKE_RANLIB "@CMAKE_RANLIB@")
diff --git a/Modules/CMakeFortranCompilerABI.F b/Modules/CMakeFortranCompilerABI.F
index 7e24553fb..b34c28484 100644
--- a/Modules/CMakeFortranCompilerABI.F
+++ b/Modules/CMakeFortranCompilerABI.F
@@ -10,16 +10,24 @@
PRINT *, 'INFO:sizeof_dptr[8]'
#elif defined(_M_AMD64)
PRINT *, 'INFO:sizeof_dptr[8]'
+#elif defined(__x86_64__)
+ PRINT *, 'INFO:sizeof_dptr[8]'
#elif defined(_ILP32)
PRINT *, 'INFO:sizeof_dptr[4]'
#elif defined(_M_IX86)
PRINT *, 'INFO:sizeof_dptr[4]'
+#elif defined(__i386__)
+ PRINT *, 'INFO:sizeof_dptr[4]'
#elif defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 8
PRINT *, 'INFO:sizeof_dptr[8]'
#elif defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 4
PRINT *, 'INFO:sizeof_dptr[4]'
+#elif defined(__SIZEOF_SIZE_T__) && __SIZEOF_SIZE_T__ == 8
+ PRINT *, 'INFO:sizeof_dptr[8]'
+#elif defined(__SIZEOF_SIZE_T__) && __SIZEOF_SIZE_T__ == 4
+ PRINT *, 'INFO:sizeof_dptr[4]'
#endif
#if 0
diff --git a/Modules/CMakeFortranCompilerId.F.in b/Modules/CMakeFortranCompilerId.F.in
index f84852aeb..67cda3b61 100644
--- a/Modules/CMakeFortranCompilerId.F.in
+++ b/Modules/CMakeFortranCompilerId.F.in
@@ -4,28 +4,92 @@
#endif
#if defined(__INTEL_COMPILER) || defined(__ICC)
PRINT *, 'INFO:compiler[Intel]'
-#elif defined(__SUNPRO_F90) || defined(__SUNPRO_F95)
+# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100)
+# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10)
+# if defined(__INTEL_COMPILER_UPDATE)
+# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER_UPDATE)
+# else
+# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10)
+# endif
+# if defined(__INTEL_COMPILER_BUILD_DATE)
+# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE)
+# endif
+
+# if defined(_MSC_VER)
+ PRINT *, 'INFO:simulate[MSVC]'
+# if _MSC_VER >= 1900
+ PRINT *, 'INFO:simulate_version[019.00]'
+# elif _MSC_VER >= 1800
+ PRINT *, 'INFO:simulate_version[018.00]'
+# elif _MSC_VER >= 1700
+ PRINT *, 'INFO:simulate_version[017.00]'
+# elif _MSC_VER >= 1600
+ PRINT *, 'INFO:simulate_version[016.00]'
+# elif _MSC_VER >= 1500
+ PRINT *, 'INFO:simulate_version[015.00]'
+# elif _MSC_VER >= 1400
+ PRINT *, 'INFO:simulate_version[014.00]'
+# elif _MSC_VER >= 1310
+ PRINT *, 'INFO:simulate_version[013.01]'
+# else
+ PRINT *, 'INFO:simulate_version[013.00]'
+# endif
+# endif
+#elif defined(__SUNPRO_F95)
+ PRINT *, 'INFO:compiler[SunPro]'
+# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_F95>>8)
+# define COMPILER_VERSION_MINOR HEX(__SUNPRO_F95>>4 & 0xF)
+# define COMPILER_VERSION_PATCH HEX(__SUNPRO_F95 & 0xF)
+#elif defined(__SUNPRO_F90)
PRINT *, 'INFO:compiler[SunPro]'
+# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_F90>>8)
+# define COMPILER_VERSION_MINOR HEX(__SUNPRO_F90>>4 & 0xF)
+# define COMPILER_VERSION_PATCH HEX(__SUNPRO_F90 & 0xF)
#elif defined(_CRAYFTN)
PRINT *, 'INFO:compiler[Cray]'
+# define COMPILER_VERSION_MAJOR DEC(_RELEASE_MAJOR)
+# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR)
#elif defined(__G95__)
PRINT *, 'INFO:compiler[G95]'
+# define COMPILER_VERSION_MAJOR DEC(__G95__)
+# define COMPILER_VERSION_MINOR DEC(__G95_MINOR__)
#elif defined(__PATHSCALE__)
PRINT *, 'INFO:compiler[PathScale]'
+# define COMPILER_VERSION_MAJOR DEC(__PATHCC__)
+# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__)
+# if defined(__PATHCC_PATCHLEVEL__)
+# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__)
+# endif
#elif defined(__ABSOFT__)
PRINT *, 'INFO:compiler[Absoft]'
#elif defined(__GNUC__)
PRINT *, 'INFO:compiler[GNU]'
+# define COMPILER_VERSION_MAJOR DEC(__GNUC__)
+# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__)
+# if defined(__GNUC_PATCHLEVEL__)
+# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
+# endif
#elif defined(__IBMC__)
# if defined(__COMPILER_VER__)
PRINT *, 'INFO:compiler[zOS]'
# elif __IBMC__ >= 800
PRINT *, 'INFO:compiler[XL]'
+# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100)
+# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10)
+# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10)
# else
PRINT *, 'INFO:compiler[VisualAge]'
+# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100)
+# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10)
+# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10)
# endif
#elif defined(__PGI)
PRINT *, 'INFO:compiler[PGI]'
+# define COMPILER_VERSION_MAJOR DEC(__PGIC__)
+# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__)
+# if defined(__PGIC_PATCHLEVEL__)
+# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__)
+# endif
#elif defined(_SGI_COMPILER_VERSION) || defined(_COMPILER_VERSION)
PRINT *, 'INFO:compiler[MIPSpro]'
# if 0
@@ -46,6 +110,9 @@
# endif
PRINT *, 'INFO:compiler[]'
#endif
+#if defined(__CRAYXE) || defined(__CRAYXC)
+ PRINT *, 'INFO:compiler_wrapper[CrayPrgEnv]'
+#endif
#if 0
! Identify the platform
@@ -116,4 +183,26 @@
PRINT *, 'INFO:arch[X86]'
# endif
#endif
+
+#if 0
+! Encode compiler version digits
+#endif
+#define DEC_8(n) (((n) / 10000000) % 10)
+#define DEC_7(n) (((n) / 1000000) % 10)
+#define DEC_6(n) (((n) / 100000) % 10)
+#define DEC_5(n) (((n) / 10000) % 10)
+#define DEC_4(n) (((n) / 1000) % 10)
+#define DEC_3(n) (((n) / 100) % 10)
+#define DEC_2(n) (((n) / 10) % 10)
+#define DEC_1(n) (((n) ) % 10)
+#define HEX_8(n) ((n)>>28 & 0xF)
+#define HEX_7(n) ((n)>>24 & 0xF)
+#define HEX_6(n) ((n)>>20 & 0xF)
+#define HEX_5(n) ((n)>>16 & 0xF)
+#define HEX_4(n) ((n)>>12 & 0xF)
+#define HEX_3(n) ((n)>>8 & 0xF)
+#define HEX_2(n) ((n)>>4 & 0xF)
+#define HEX_1(n) ((n) & 0xF)
+@CMAKE_Fortran_COMPILER_ID_VERSION_INFO@
+
END
diff --git a/Modules/CMakeFortranInformation.cmake b/Modules/CMakeFortranInformation.cmake
index 512ec4864..1fd097235 100644
--- a/Modules/CMakeFortranInformation.cmake
+++ b/Modules/CMakeFortranInformation.cmake
@@ -12,6 +12,8 @@
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
+include(CMakeLanguageInformation)
+
# This file sets the basic flags for the Fortran language in CMake.
# It also loads the available platform file for the system-compiler
# if it exists.
@@ -24,7 +26,7 @@ if(CMAKE_Fortran_COMPILER_ID)
endif()
set(CMAKE_BASE_NAME)
-get_filename_component(CMAKE_BASE_NAME ${CMAKE_Fortran_COMPILER} NAME_WE)
+get_filename_component(CMAKE_BASE_NAME "${CMAKE_Fortran_COMPILER}" NAME_WE)
# since the gnu compiler has several names force g++
if(CMAKE_COMPILER_IS_GNUG77)
set(CMAKE_BASE_NAME g77)
@@ -36,6 +38,12 @@ if (NOT _INCLUDED_FILE)
include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME} OPTIONAL
RESULT_VARIABLE _INCLUDED_FILE)
endif ()
+
+# load any compiler-wrapper specific information
+if (CMAKE_Fortran_COMPILER_WRAPPER)
+ __cmake_include_compiler_wrapper(Fortran)
+endif ()
+
# We specify the compiler information in the system file for some
# platforms, but this language may not have been enabled when the file
# was first included. Include it again to get the language info.
@@ -194,10 +202,10 @@ endif()
# Create a static archive incrementally for large object file counts.
# If CMAKE_Fortran_CREATE_STATIC_LIBRARY is set it will override these.
if(NOT DEFINED CMAKE_Fortran_ARCHIVE_CREATE)
- set(CMAKE_Fortran_ARCHIVE_CREATE "<CMAKE_AR> cr <TARGET> <LINK_FLAGS> <OBJECTS>")
+ set(CMAKE_Fortran_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
endif()
if(NOT DEFINED CMAKE_Fortran_ARCHIVE_APPEND)
- set(CMAKE_Fortran_ARCHIVE_APPEND "<CMAKE_AR> r <TARGET> <LINK_FLAGS> <OBJECTS>")
+ set(CMAKE_Fortran_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
endif()
if(NOT DEFINED CMAKE_Fortran_ARCHIVE_FINISH)
set(CMAKE_Fortran_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
@@ -207,7 +215,7 @@ endif()
# (put -o after -c to workaround bug in at least one mpif77 wrapper)
if(NOT CMAKE_Fortran_COMPILE_OBJECT)
set(CMAKE_Fortran_COMPILE_OBJECT
- "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -c <SOURCE> -o <OBJECT>")
+ "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -c <SOURCE> -o <OBJECT>")
endif()
# link a fortran program
@@ -218,7 +226,7 @@ endif()
if(CMAKE_Fortran_STANDARD_LIBRARIES_INIT)
set(CMAKE_Fortran_STANDARD_LIBRARIES "${CMAKE_Fortran_STANDARD_LIBRARIES_INIT}"
- CACHE STRING "Libraries linked by defalut with all Fortran applications.")
+ CACHE STRING "Libraries linked by default with all Fortran applications.")
mark_as_advanced(CMAKE_Fortran_STANDARD_LIBRARIES)
endif()
@@ -226,11 +234,11 @@ if(NOT CMAKE_NOT_USING_CONFIG_FLAGS)
set (CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG_INIT}" CACHE STRING
"Flags used by the compiler during debug builds.")
set (CMAKE_Fortran_FLAGS_MINSIZEREL "${CMAKE_Fortran_FLAGS_MINSIZEREL_INIT}" CACHE STRING
- "Flags used by the compiler during release minsize builds.")
+ "Flags used by the compiler during release builds for minimum size.")
set (CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE_INIT}" CACHE STRING
- "Flags used by the compiler during release builds (/MD /Ob1 /Oi /Ot /Oy /Gs will produce slightly less optimized but smaller files).")
+ "Flags used by the compiler during release builds.")
set (CMAKE_Fortran_FLAGS_RELWITHDEBINFO "${CMAKE_Fortran_FLAGS_RELWITHDEBINFO_INIT}" CACHE STRING
- "Flags used by the compiler during Release with Debug Info builds.")
+ "Flags used by the compiler during release builds with debug info.")
endif()
diff --git a/Modules/CMakeGenericSystem.cmake b/Modules/CMakeGenericSystem.cmake
index 8a14aea60..5ae757d69 100644
--- a/Modules/CMakeGenericSystem.cmake
+++ b/Modules/CMakeGenericSystem.cmake
@@ -44,7 +44,7 @@ set (CMAKE_SKIP_INSTALL_RPATH "NO" CACHE BOOL
set(CMAKE_VERBOSE_MAKEFILE FALSE CACHE BOOL "If this value is on, makefiles will be generated without the .SILENT directive, and all commands will be echoed to the console during the make. This is useful for debugging only. With Visual Studio IDE projects all commands are done without /nologo.")
-if(CMAKE_GENERATOR MATCHES "Makefiles")
+if(CMAKE_GENERATOR MATCHES "Make")
set(CMAKE_COLOR_MAKEFILE ON CACHE BOOL
"Enable/Disable color output during build."
)
@@ -52,6 +52,9 @@ if(CMAKE_GENERATOR MATCHES "Makefiles")
if(DEFINED CMAKE_RULE_MESSAGES)
set_property(GLOBAL PROPERTY RULE_MESSAGES ${CMAKE_RULE_MESSAGES})
endif()
+ if(DEFINED CMAKE_TARGET_MESSAGES)
+ set_property(GLOBAL PROPERTY TARGET_MESSAGES ${CMAKE_TARGET_MESSAGES})
+ endif()
if(CMAKE_GENERATOR MATCHES "Unix Makefiles")
set(CMAKE_EXPORT_COMPILE_COMMANDS OFF CACHE BOOL
"Enable/Disable output of compile commands during generation."
diff --git a/Modules/CMakeGraphVizOptions.cmake b/Modules/CMakeGraphVizOptions.cmake
index e4af54c0a..ff182672e 100644
--- a/Modules/CMakeGraphVizOptions.cmake
+++ b/Modules/CMakeGraphVizOptions.cmake
@@ -1,72 +1,112 @@
-##section Variables specific to the graphviz support
-##end
-##module
-# - The builtin graphviz support of CMake.
-# CMake can generate graphviz files, showing the dependencies between
-# the targets in a project and also external libraries which are linked
-# against.
-# When CMake is run with the --graphiz=foo option, it will produce
-# * a foo.dot file showing all dependencies in the project
-# * a foo.dot.<target> file for each target, file showing on which other targets the respective target depends
-# * a foo.dot.<target>.dependers file, showing which other targets depend on the respective target
-#
-# This can result in huge graphs. Using the file CMakeGraphVizOptions.cmake
-# the look and content of the generated graphs can be influenced.
-# This file is searched first in ${CMAKE_BINARY_DIR} and then in
-# ${CMAKE_SOURCE_DIR}. If found, it is read and the variables set in it
-# are used to adjust options for the generated graphviz files.
-##end
-#
-##variable
-# GRAPHVIZ_GRAPH_TYPE - The graph type
-# Mandatory : NO
-# Default : "digraph"
-##end
-##variable
-# GRAPHVIZ_GRAPH_NAME - The graph name.
-# Mandatory : NO
-# Default : "GG"
-##end
-##variable
-# GRAPHVIZ_GRAPH_HEADER - The header written at the top of the graphviz file.
-# Mandatory : NO
-# Default : "node [n fontsize = "12"];"
-##end
-##variable
-# GRAPHVIZ_NODE_PREFIX - The prefix for each node in the graphviz file.
-# Mandatory : NO
-# Default : "node"
-##end
-##variable
-# GRAPHVIZ_EXECUTABLES - Set this to FALSE to exclude executables from the generated graphs.
-# Mandatory : NO
-# Default : TRUE
-##end
-##variable
-# GRAPHVIZ_STATIC_LIBS - Set this to FALSE to exclude static libraries from the generated graphs.
-# Mandatory : NO
-# Default : TRUE
-##end
-##variable
-# GRAPHVIZ_SHARED_LIBS - Set this to FALSE to exclude shared libraries from the generated graphs.
-# Mandatory : NO
-# Default : TRUE
-##end
-##variable
-# GRAPHVIZ_MODULE_LIBS - Set this to FALSE to exclude static libraries from the generated graphs.
-# Mandatory : NO
-# Default : TRUE
-##end
-##variable
-# GRAPHVIZ_EXTERNAL_LIBS - Set this to FALSE to exclude external libraries from the generated graphs.
-# Mandatory : NO
-# Default : TRUE
-##end
-##variable
-# GRAPHVIZ_IGNORE_TARGETS - A list of regular expressions for ignoring targets.
-# Mandatory : NO
-# Default : empty
-##end
+#.rst:
+# CMakeGraphVizOptions
+# --------------------
+#
+# The builtin graphviz support of CMake.
+#
+# Variables specific to the graphviz support
+# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#
+# CMake
+# can generate graphviz files, showing the dependencies between the
+# targets in a project and also external libraries which are linked
+# against. When CMake is run with the --graphviz=foo option, it will
+# produce
+#
+# * a foo.dot file showing all dependencies in the project
+# * a foo.dot.<target> file for each target, file showing on which other targets the respective target depends
+# * a foo.dot.<target>.dependers file, showing which other targets depend on the respective target
+#
+# This can result in huge graphs. Using the file
+# CMakeGraphVizOptions.cmake the look and content of the generated
+# graphs can be influenced. This file is searched first in
+# ${CMAKE_BINARY_DIR} and then in ${CMAKE_SOURCE_DIR}. If found, it is
+# read and the variables set in it are used to adjust options for the
+# generated graphviz files.
+#
+# .. variable:: GRAPHVIZ_GRAPH_TYPE
+#
+# The graph type
+#
+# * Mandatory : NO
+# * Default : "digraph"
+#
+# .. variable:: GRAPHVIZ_GRAPH_NAME
+#
+# The graph name.
+#
+# * Mandatory : NO
+# * Default : "GG"
+#
+# .. variable:: GRAPHVIZ_GRAPH_HEADER
+#
+# The header written at the top of the graphviz file.
+#
+# * Mandatory : NO
+# * Default : "node [n fontsize = "12"];"
+#
+# .. variable:: GRAPHVIZ_NODE_PREFIX
+#
+# The prefix for each node in the graphviz file.
+#
+# * Mandatory : NO
+# * Default : "node"
+#
+# .. variable:: GRAPHVIZ_EXECUTABLES
+#
+# Set this to FALSE to exclude executables from the generated graphs.
+#
+# * Mandatory : NO
+# * Default : TRUE
+#
+# .. variable:: GRAPHVIZ_STATIC_LIBS
+#
+# Set this to FALSE to exclude static libraries from the generated graphs.
+#
+# * Mandatory : NO
+# * Default : TRUE
+#
+# .. variable:: GRAPHVIZ_SHARED_LIBS
+#
+# Set this to FALSE to exclude shared libraries from the generated graphs.
+#
+# * Mandatory : NO
+# * Default : TRUE
+#
+# .. variable:: GRAPHVIZ_MODULE_LIBS
+#
+# Set this to FALSE to exclude module libraries from the generated graphs.
+#
+# * Mandatory : NO
+# * Default : TRUE
+#
+# .. variable:: GRAPHVIZ_EXTERNAL_LIBS
+#
+# Set this to FALSE to exclude external libraries from the generated graphs.
+#
+# * Mandatory : NO
+# * Default : TRUE
+#
+# .. variable:: GRAPHVIZ_IGNORE_TARGETS
+#
+# A list of regular expressions for ignoring targets.
+#
+# * Mandatory : NO
+# * Default : empty
+#
+# .. variable:: GRAPHVIZ_GENERATE_PER_TARGET
+#
+# Set this to FALSE to exclude per target graphs ``foo.dot.<target>``.
+#
+# * Mandatory : NO
+# * Default : TRUE
+#
+# .. variable:: GRAPHVIZ_GENERATE_DEPENDERS
+#
+# Set this to FALSE to exclude depender graphs ``foo.dot.<target>.dependers``.
+#
+# * Mandatory : NO
+# * Default : TRUE
#=============================================================================
# Copyright 2007-2009 Kitware, Inc.
diff --git a/Modules/CMakeIOSInstallCombined.cmake b/Modules/CMakeIOSInstallCombined.cmake
new file mode 100644
index 000000000..1256f563e
--- /dev/null
+++ b/Modules/CMakeIOSInstallCombined.cmake
@@ -0,0 +1,307 @@
+
+#=============================================================================
+# Copyright 2014-2015 Ruslan Baratov, Gregor Jasny
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# Function to print messages of this module
+function(_ios_install_combined_message)
+ message("[iOS combined] " ${ARGN})
+endfunction()
+
+# Get build settings for the current target/config/SDK by running
+# `xcodebuild -sdk ... -showBuildSettings` and parsing it's output
+function(_ios_install_combined_get_build_setting sdk variable resultvar)
+ if("${sdk}" STREQUAL "")
+ message(FATAL_ERROR "`sdk` is empty")
+ endif()
+
+ if("${variable}" STREQUAL "")
+ message(FATAL_ERROR "`variable` is empty")
+ endif()
+
+ if("${resultvar}" STREQUAL "")
+ message(FATAL_ERROR "`resultvar` is empty")
+ endif()
+
+ set(
+ cmd
+ xcodebuild -showBuildSettings
+ -sdk "${sdk}"
+ -target "${CURRENT_TARGET}"
+ -config "${CURRENT_CONFIG}"
+ )
+
+ execute_process(
+ COMMAND ${cmd}
+ WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
+ RESULT_VARIABLE result
+ OUTPUT_VARIABLE output
+ )
+
+ if(NOT result EQUAL 0)
+ message(FATAL_ERROR "Command failed (${result}): ${cmd}")
+ endif()
+
+ if(NOT output MATCHES " ${variable} = ([^\n]*)")
+ if("${variable}" STREQUAL "VALID_ARCHS")
+ # VALID_ARCHS may be unset by user for given SDK
+ # (e.g. for build without simulator).
+ set("${resultvar}" "" PARENT_SCOPE)
+ return()
+ else()
+ message(FATAL_ERROR "${variable} not found.")
+ endif()
+ endif()
+
+ set("${resultvar}" "${CMAKE_MATCH_1}" PARENT_SCOPE)
+endfunction()
+
+# Get architectures of given SDK (iphonesimulator/iphoneos)
+function(_ios_install_combined_get_valid_archs sdk resultvar)
+ cmake_policy(SET CMP0007 NEW)
+
+ if("${resultvar}" STREQUAL "")
+ message(FATAL_ERROR "`resultvar` is empty")
+ endif()
+
+ _ios_install_combined_get_build_setting("${sdk}" "VALID_ARCHS" valid_archs)
+
+ separate_arguments(valid_archs)
+ list(REMOVE_ITEM valid_archs "") # remove empty elements
+ list(REMOVE_DUPLICATES valid_archs)
+
+ string(REPLACE ";" " " printable "${valid_archs}")
+ _ios_install_combined_message("Architectures (${sdk}): ${printable}")
+
+ set("${resultvar}" "${valid_archs}" PARENT_SCOPE)
+endfunction()
+
+# Final target can contain more architectures that specified by SDK. This
+# function will run 'lipo -info' and parse output. Result will be returned
+# as a CMake list.
+function(_ios_install_combined_get_real_archs filename resultvar)
+ set(cmd "${_lipo_path}" -info "${filename}")
+ execute_process(
+ COMMAND ${cmd}
+ RESULT_VARIABLE result
+ OUTPUT_VARIABLE output
+ ERROR_VARIABLE output
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_STRIP_TRAILING_WHITESPACE
+ )
+ if(NOT result EQUAL 0)
+ message(
+ FATAL_ERROR "Command failed (${result}): ${cmd}\n\nOutput:\n${output}"
+ )
+ endif()
+
+ if(NOT output MATCHES "(Architectures in the fat file: [^\n]+ are|Non-fat file: [^\n]+ is architecture): ([^\n]*)")
+ message(FATAL_ERROR "Could not detect architecture from: ${output}")
+ endif()
+
+ separate_arguments(CMAKE_MATCH_2)
+ set(${resultvar} ${CMAKE_MATCH_2} PARENT_SCOPE)
+endfunction()
+
+# Run build command for the given SDK
+function(_ios_install_combined_build sdk)
+ if("${sdk}" STREQUAL "")
+ message(FATAL_ERROR "`sdk` is empty")
+ endif()
+
+ _ios_install_combined_message("Build `${CURRENT_TARGET}` for `${sdk}`")
+
+ execute_process(
+ COMMAND
+ "${CMAKE_COMMAND}"
+ --build
+ .
+ --target "${CURRENT_TARGET}"
+ --config ${CURRENT_CONFIG}
+ --
+ -sdk "${sdk}"
+ WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
+ RESULT_VARIABLE result
+ )
+
+ if(NOT result EQUAL 0)
+ message(FATAL_ERROR "Build failed")
+ endif()
+endfunction()
+
+# Remove given architecture from file. This step needed only in rare cases
+# when target was built in "unusual" way. Emit warning message.
+function(_ios_install_combined_remove_arch lib arch)
+ _ios_install_combined_message(
+ "Warning! Unexpected architecture `${arch}` detected and will be removed "
+ "from file `${lib}`")
+ set(cmd "${_lipo_path}" -remove ${arch} -output ${lib} ${lib})
+ execute_process(
+ COMMAND ${cmd}
+ RESULT_VARIABLE result
+ OUTPUT_VARIABLE output
+ ERROR_VARIABLE output
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_STRIP_TRAILING_WHITESPACE
+ )
+ if(NOT result EQUAL 0)
+ message(
+ FATAL_ERROR "Command failed (${result}): ${cmd}\n\nOutput:\n${output}"
+ )
+ endif()
+endfunction()
+
+# Check that 'lib' contains only 'archs' architectures (remove others).
+function(_ios_install_combined_keep_archs lib archs)
+ _ios_install_combined_get_real_archs("${lib}" real_archs)
+ set(archs_to_remove ${real_archs})
+ list(REMOVE_ITEM archs_to_remove ${archs})
+ foreach(x ${archs_to_remove})
+ _ios_install_combined_remove_arch("${lib}" "${x}")
+ endforeach()
+endfunction()
+
+function(_ios_install_combined_detect_sdks this_sdk_var corr_sdk_var)
+ cmake_policy(SET CMP0057 NEW)
+
+ set(this_sdk "$ENV{PLATFORM_NAME}")
+ if("${this_sdk}" STREQUAL "")
+ message(FATAL_ERROR "Environment variable PLATFORM_NAME is empty")
+ endif()
+
+ set(all_platforms "$ENV{SUPPORTED_PLATFORMS}")
+ if("${all_platforms}" STREQUAL "")
+ message(FATAL_ERROR "Environment variable SUPPORTED_PLATFORMS is empty")
+ endif()
+
+ separate_arguments(all_platforms)
+ if(NOT this_sdk IN_LIST all_platforms)
+ message(FATAL_ERROR "`${this_sdk}` not found in `${all_platforms}`")
+ endif()
+
+ list(REMOVE_ITEM all_platforms "" "${this_sdk}")
+ list(LENGTH all_platforms all_platforms_length)
+ if(NOT all_platforms_length EQUAL 1)
+ message(FATAL_ERROR "Expected one element: ${all_platforms}")
+ endif()
+
+ set(${this_sdk_var} "${this_sdk}" PARENT_SCOPE)
+ set(${corr_sdk_var} "${all_platforms}" PARENT_SCOPE)
+endfunction()
+
+# Create combined binary for the given target.
+#
+# Preconditions:
+# * Target already installed at ${destination}
+# for the ${PLATFORM_NAME} platform
+#
+# This function will:
+# * Run build for the lacking platform, i.e. opposite to the ${PLATFORM_NAME}
+# * Fuse both libraries by running lipo
+function(ios_install_combined target destination)
+ if("${target}" STREQUAL "")
+ message(FATAL_ERROR "`target` is empty")
+ endif()
+
+ if("${destination}" STREQUAL "")
+ message(FATAL_ERROR "`destination` is empty")
+ endif()
+
+ if(NOT IS_ABSOLUTE "${destination}")
+ message(FATAL_ERROR "`destination` is not absolute: ${destination}")
+ endif()
+
+ if(IS_DIRECTORY "${destination}" OR IS_SYMLINK "${destination}")
+ message(FATAL_ERROR "`destination` is no regular file: ${destination}")
+ endif()
+
+ if("${CMAKE_BINARY_DIR}" STREQUAL "")
+ message(FATAL_ERROR "`CMAKE_BINARY_DIR` is empty")
+ endif()
+
+ if(NOT IS_DIRECTORY "${CMAKE_BINARY_DIR}")
+ message(FATAL_ERROR "Is not a directory: ${CMAKE_BINARY_DIR}")
+ endif()
+
+ if("${CMAKE_INSTALL_CONFIG_NAME}" STREQUAL "")
+ message(FATAL_ERROR "CMAKE_INSTALL_CONFIG_NAME is empty")
+ endif()
+
+ set(cmd xcrun -f lipo)
+ execute_process(
+ COMMAND ${cmd}
+ RESULT_VARIABLE result
+ OUTPUT_VARIABLE output
+ ERROR_VARIABLE output
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_STRIP_TRAILING_WHITESPACE
+ )
+ if(NOT result EQUAL 0)
+ message(
+ FATAL_ERROR "Command failed (${result}): ${cmd}\n\nOutput:\n${output}"
+ )
+ endif()
+ set(_lipo_path ${output})
+
+ set(CURRENT_CONFIG "${CMAKE_INSTALL_CONFIG_NAME}")
+ set(CURRENT_TARGET "${target}")
+
+ _ios_install_combined_message("Target: ${CURRENT_TARGET}")
+ _ios_install_combined_message("Config: ${CURRENT_CONFIG}")
+ _ios_install_combined_message("Destination: ${destination}")
+
+ # Get SDKs
+ _ios_install_combined_detect_sdks(this_sdk corr_sdk)
+
+ # Get architectures of the target
+ _ios_install_combined_get_valid_archs("${corr_sdk}" corr_valid_archs)
+ _ios_install_combined_get_valid_archs("${this_sdk}" this_valid_archs)
+
+ # Return if there are no valid architectures for the SDK.
+ # (note that library already installed)
+ if("${corr_valid_archs}" STREQUAL "")
+ _ios_install_combined_message(
+ "No architectures detected for `${corr_sdk}` (skip)"
+ )
+ return()
+ endif()
+
+ # Trigger build of corresponding target
+ _ios_install_combined_build("${corr_sdk}")
+
+ # Get location of the library in build directory
+ _ios_install_combined_get_build_setting(
+ "${corr_sdk}" "CONFIGURATION_BUILD_DIR" corr_build_dir)
+ _ios_install_combined_get_build_setting(
+ "${corr_sdk}" "EXECUTABLE_PATH" corr_executable_path)
+ set(corr "${corr_build_dir}/${corr_executable_path}")
+
+ _ios_install_combined_keep_archs("${corr}" "${corr_valid_archs}")
+ _ios_install_combined_keep_archs("${destination}" "${this_valid_archs}")
+
+ _ios_install_combined_message("Current: ${destination}")
+ _ios_install_combined_message("Corresponding: ${corr}")
+
+ set(cmd "${_lipo_path}" -create ${corr} ${destination} -output ${destination})
+
+ execute_process(
+ COMMAND ${cmd}
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+ RESULT_VARIABLE result
+ )
+
+ if(NOT result EQUAL 0)
+ message(FATAL_ERROR "Command failed: ${cmd}")
+ endif()
+
+ _ios_install_combined_message("Install done: ${destination}")
+endfunction()
diff --git a/Modules/CMakeImportBuildSettings.cmake b/Modules/CMakeImportBuildSettings.cmake
index 60b887aed..edecc1fa0 100644
--- a/Modules/CMakeImportBuildSettings.cmake
+++ b/Modules/CMakeImportBuildSettings.cmake
@@ -17,8 +17,7 @@
# This macro used to load build settings from another project that
# stored settings using the CMAKE_EXPORT_BUILD_SETTINGS macro.
macro(CMAKE_IMPORT_BUILD_SETTINGS SETTINGS_FILE)
- if(${SETTINGS_FILE} MATCHES ".+")
- else()
+ if("${SETTINGS_FILE}" STREQUAL "")
message(SEND_ERROR "CMAKE_IMPORT_BUILD_SETTINGS called with no argument.")
endif()
endmacro()
diff --git a/Modules/CMakeLanguageInformation.cmake b/Modules/CMakeLanguageInformation.cmake
new file mode 100644
index 000000000..e03d149c0
--- /dev/null
+++ b/Modules/CMakeLanguageInformation.cmake
@@ -0,0 +1,37 @@
+
+#=============================================================================
+# Copyright 2015 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# This file contains common code blocks used by all the language information
+# files
+
+# load any compiler-wrapper specific information
+macro(__cmake_include_compiler_wrapper lang)
+ set(_INCLUDED_WRAPPER_FILE 0)
+ if (CMAKE_${lang}_COMPILER_ID)
+ include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_${lang}_COMPILER_WRAPPER}-${CMAKE_${lang}_COMPILER_ID}-${lang} OPTIONAL RESULT_VARIABLE _INCLUDED_WRAPPER_FILE)
+ endif()
+ if (NOT _INCLUDED_WRAPPER_FILE)
+ include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_${lang}_COMPILER_WRAPPER}-${lang} OPTIONAL RESULT_VARIABLE _INCLUDED_WRAPPER_FILE)
+ endif ()
+
+ # No platform - wrapper - lang information so maybe there's just wrapper - lang information
+ if(NOT _INCLUDED_WRAPPER_FILE)
+ if (CMAKE_${lang}_COMPILER_ID)
+ include(Compiler/${CMAKE_${lang}_COMPILER_WRAPPER}-${CMAKE_${lang}_COMPILER_ID}-${lang} OPTIONAL RESULT_VARIABLE _INCLUDED_WRAPPER_FILE)
+ endif()
+ if (NOT _INCLUDED_WRAPPER_FILE)
+ include(Compiler/${CMAKE_${lang}_COMPILER_WRAPPER}-${lang} OPTIONAL RESULT_VARIABLE _INCLUDED_WRAPPER_FILE)
+ endif ()
+ endif ()
+endmacro ()
diff --git a/Modules/CMakeNinjaFindMake.cmake b/Modules/CMakeNinjaFindMake.cmake
index c3ca7671c..2f35cf407 100644
--- a/Modules/CMakeNinjaFindMake.cmake
+++ b/Modules/CMakeNinjaFindMake.cmake
@@ -12,6 +12,7 @@
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
-find_program(CMAKE_MAKE_PROGRAM ninja
+find_program(CMAKE_MAKE_PROGRAM
+ NAMES ninja-build ninja
DOC "Program used to build from build.ninja files.")
mark_as_advanced(CMAKE_MAKE_PROGRAM)
diff --git a/Modules/CMakePackageConfigHelpers.cmake b/Modules/CMakePackageConfigHelpers.cmake
index d042d5e0f..206ea7a48 100644
--- a/Modules/CMakePackageConfigHelpers.cmake
+++ b/Modules/CMakePackageConfigHelpers.cmake
@@ -1,134 +1,202 @@
-# - CONFIGURE_PACKAGE_CONFIG_FILE(), WRITE_BASIC_PACKAGE_VERSION_FILE()
-#
-# CONFIGURE_PACKAGE_CONFIG_FILE(<input> <output> INSTALL_DESTINATION <path>
-# [PATH_VARS <var1> <var2> ... <varN>]
-# [NO_SET_AND_CHECK_MACRO]
-# [NO_CHECK_REQUIRED_COMPONENTS_MACRO])
-#
-# CONFIGURE_PACKAGE_CONFIG_FILE() should be used instead of the plain
-# configure_file() command when creating the <Name>Config.cmake or <Name>-config.cmake
-# file for installing a project or library. It helps making the resulting package
-# relocatable by avoiding hardcoded paths in the installed Config.cmake file.
-#
-# In a FooConfig.cmake file there may be code like this to make the
-# install destinations know to the using project:
-# set(FOO_INCLUDE_DIR "@CMAKE_INSTALL_FULL_INCLUDEDIR@" )
-# set(FOO_DATA_DIR "@CMAKE_INSTALL_PREFIX@/@RELATIVE_DATA_INSTALL_DIR@" )
-# set(FOO_ICONS_DIR "@CMAKE_INSTALL_PREFIX@/share/icons" )
-# ...logic to determine installedPrefix from the own location...
-# set(FOO_CONFIG_DIR "${installedPrefix}/@CONFIG_INSTALL_DIR@" )
-# All 4 options shown above are not sufficient, since the first 3 hardcode
-# the absolute directory locations, and the 4th case works only if the logic
-# to determine the installedPrefix is correct, and if CONFIG_INSTALL_DIR contains
-# a relative path, which in general cannot be guaranteed.
-# This has the effect that the resulting FooConfig.cmake file would work poorly
-# under Windows and OSX, where users are used to choose the install location
-# of a binary package at install time, independent from how CMAKE_INSTALL_PREFIX
-# was set at build/cmake time.
-#
-# Using CONFIGURE_PACKAGE_CONFIG_FILE() helps. If used correctly, it makes the
-# resulting FooConfig.cmake file relocatable.
-# Usage:
-# 1. write a FooConfig.cmake.in file as you are used to
-# 2. insert a line containing only the string "@PACKAGE_INIT@"
-# 3. instead of set(FOO_DIR "@SOME_INSTALL_DIR@"), use set(FOO_DIR "@PACKAGE_SOME_INSTALL_DIR@")
-# (this must be after the @PACKAGE_INIT@ line)
-# 4. instead of using the normal configure_file(), use CONFIGURE_PACKAGE_CONFIG_FILE()
-#
-# The <input> and <output> arguments are the input and output file, the same way
-# as in configure_file().
-#
-# The <path> given to INSTALL_DESTINATION must be the destination where the FooConfig.cmake
-# file will be installed to. This can either be a relative or absolute path, both work.
-#
-# The variables <var1> to <varN> given as PATH_VARS are the variables which contain
-# install destinations. For each of them the macro will create a helper variable
-# PACKAGE_<var...>. These helper variables must be used
-# in the FooConfig.cmake.in file for setting the installed location. They are calculated
-# by CONFIGURE_PACKAGE_CONFIG_FILE() so that they are always relative to the
-# installed location of the package. This works both for relative and also for absolute locations.
-# For absolute locations it works only if the absolute location is a subdirectory
-# of CMAKE_INSTALL_PREFIX.
-#
-# By default configure_package_config_file() also generates two helper macros,
-# set_and_check() and check_required_components() into the FooConfig.cmake file.
-#
-# set_and_check() should be used instead of the normal set()
-# command for setting directories and file locations. Additionally to setting the
-# variable it also checks that the referenced file or directory actually exists
-# and fails with a FATAL_ERROR otherwise. This makes sure that the created
-# FooConfig.cmake file does not contain wrong references.
-# When using the NO_SET_AND_CHECK_MACRO, this macro is not generated into the
-# FooConfig.cmake file.
-#
-# check_required_components(<package_name>) should be called at the end of the
-# FooConfig.cmake file if the package supports components.
-# This macro checks whether all requested, non-optional components have been found,
-# and if this is not the case, sets the Foo_FOUND variable to FALSE, so that the package
-# is considered to be not found.
-# It does that by testing the Foo_<Component>_FOUND variables for all requested
-# required components.
-# When using the NO_CHECK_REQUIRED_COMPONENTS option, this macro is not generated
-# into the FooConfig.cmake file.
-#
-# For an example see below the documentation for WRITE_BASIC_PACKAGE_VERSION_FILE().
-#
-#
-# WRITE_BASIC_PACKAGE_VERSION_FILE( filename VERSION major.minor.patch COMPATIBILITY (AnyNewerVersion|SameMajorVersion|ExactVersion) )
-#
-# Writes a file for use as <package>ConfigVersion.cmake file to <filename>.
-# See the documentation of find_package() for details on this.
-# filename is the output filename, it should be in the build tree.
-# major.minor.patch is the version number of the project to be installed
-# The COMPATIBILITY mode AnyNewerVersion means that the installed package version
-# will be considered compatible if it is newer or exactly the same as the requested version.
-# This mode should be used for packages which are fully backward compatible,
-# also across major versions.
-# If SameMajorVersion is used instead, then the behaviour differs from AnyNewerVersion
-# in that the major version number must be the same as requested, e.g. version 2.0 will
-# not be considered compatible if 1.0 is requested.
-# This mode should be used for packages which guarantee backward compatibility within the
-# same major version.
-# If ExactVersion is used, then the package is only considered compatible if the requested
-# version matches exactly its own version number (not considering the tweak version).
-# For example, version 1.2.3 of a package is only considered compatible to requested version 1.2.3.
-# This mode is for packages without compatibility guarantees.
-# If your project has more elaborated version matching rules, you will need to write your
-# own custom ConfigVersion.cmake file instead of using this macro.
-#
-# Internally, this macro executes configure_file() to create the resulting
-# version file. Depending on the COMPATIBLITY, either the file
-# BasicConfigVersion-SameMajorVersion.cmake.in or BasicConfigVersion-AnyNewerVersion.cmake.in
-# is used. Please note that these two files are internal to CMake and you should
-# not call configure_file() on them yourself, but they can be used as starting
-# point to create more sophisticted custom ConfigVersion.cmake files.
-#
-#
-# Example using both configure_package_config_file() and write_basic_package_version_file():
-# CMakeLists.txt:
-# set(INCLUDE_INSTALL_DIR include/ ... CACHE )
-# set(LIB_INSTALL_DIR lib/ ... CACHE )
-# set(SYSCONFIG_INSTALL_DIR etc/foo/ ... CACHE )
-# ...
-# include(CMakePackageConfigHelpers)
-# configure_package_config_file(FooConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake
-# INSTALL_DESTINATION ${LIB_INSTALL_DIR}/Foo/cmake
-# PATH_VARS INCLUDE_INSTALL_DIR SYSCONFIG_INSTALL_DIR)
-# write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake
-# VERSION 1.2.3
-# COMPATIBILITY SameMajorVersion )
-# install(FILES ${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake
-# DESTINATION ${LIB_INSTALL_DIR}/Foo/cmake )
-#
-# With a FooConfig.cmake.in:
-# set(FOO_VERSION x.y.z)
-# ...
-# @PACKAGE_INIT@
-# ...
-# set_and_check(FOO_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
-# set_and_check(FOO_SYSCONFIG_DIR "@PACKAGE_SYSCONFIG_INSTALL_DIR@")
-#
-# check_required_components(Foo)
+#.rst:
+# CMakePackageConfigHelpers
+# -------------------------
+#
+# Helpers functions for creating config files that can be included by other
+# projects to find and use a package.
+#
+# Adds the :command:`configure_package_config_file()` and
+# :command:`write_basic_package_version_file()` commands.
+#
+# Generating a Package Configuration File
+# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#
+# .. command:: configure_package_config_file
+#
+# Create a config file for a project::
+#
+# configure_package_config_file(<input> <output>
+# INSTALL_DESTINATION <path>
+# [PATH_VARS <var1> <var2> ... <varN>]
+# [NO_SET_AND_CHECK_MACRO]
+# [NO_CHECK_REQUIRED_COMPONENTS_MACRO]
+# [INSTALL_PREFIX <path>]
+# )
+#
+# ``configure_package_config_file()`` should be used instead of the plain
+# :command:`configure_file()` command when creating the ``<Name>Config.cmake``
+# or ``<Name>-config.cmake`` file for installing a project or library. It helps
+# making the resulting package relocatable by avoiding hardcoded paths in the
+# installed ``Config.cmake`` file.
+#
+# In a ``FooConfig.cmake`` file there may be code like this to make the install
+# destinations know to the using project:
+#
+# .. code-block:: cmake
+#
+# set(FOO_INCLUDE_DIR "@CMAKE_INSTALL_FULL_INCLUDEDIR@" )
+# set(FOO_DATA_DIR "@CMAKE_INSTALL_PREFIX@/@RELATIVE_DATA_INSTALL_DIR@" )
+# set(FOO_ICONS_DIR "@CMAKE_INSTALL_PREFIX@/share/icons" )
+# ...logic to determine installedPrefix from the own location...
+# set(FOO_CONFIG_DIR "${installedPrefix}/@CONFIG_INSTALL_DIR@" )
+#
+# All 4 options shown above are not sufficient, since the first 3 hardcode the
+# absolute directory locations, and the 4th case works only if the logic to
+# determine the ``installedPrefix`` is correct, and if ``CONFIG_INSTALL_DIR``
+# contains a relative path, which in general cannot be guaranteed. This has the
+# effect that the resulting ``FooConfig.cmake`` file would work poorly under
+# Windows and OSX, where users are used to choose the install location of a
+# binary package at install time, independent from how
+# :variable:`CMAKE_INSTALL_PREFIX` was set at build/cmake time.
+#
+# Using ``configure_package_config_file`` helps. If used correctly, it makes
+# the resulting ``FooConfig.cmake`` file relocatable. Usage:
+#
+# 1. write a ``FooConfig.cmake.in`` file as you are used to
+# 2. insert a line containing only the string ``@PACKAGE_INIT@``
+# 3. instead of ``set(FOO_DIR "@SOME_INSTALL_DIR@")``, use
+# ``set(FOO_DIR "@PACKAGE_SOME_INSTALL_DIR@")`` (this must be after the
+# ``@PACKAGE_INIT@`` line)
+# 4. instead of using the normal :command:`configure_file()`, use
+# ``configure_package_config_file()``
+#
+#
+#
+# The ``<input>`` and ``<output>`` arguments are the input and output file, the
+# same way as in :command:`configure_file()`.
+#
+# The ``<path>`` given to ``INSTALL_DESTINATION`` must be the destination where
+# the ``FooConfig.cmake`` file will be installed to. This path can either be
+# absolute, or relative to the ``INSTALL_PREFIX`` path.
+#
+# The variables ``<var1>`` to ``<varN>`` given as ``PATH_VARS`` are the
+# variables which contain install destinations. For each of them the macro will
+# create a helper variable ``PACKAGE_<var...>``. These helper variables must be
+# used in the ``FooConfig.cmake.in`` file for setting the installed location.
+# They are calculated by ``configure_package_config_file`` so that they are
+# always relative to the installed location of the package. This works both for
+# relative and also for absolute locations. For absolute locations it works
+# only if the absolute location is a subdirectory of ``INSTALL_PREFIX``.
+#
+# If the ``INSTALL_PREFIX`` argument is passed, this is used as base path to
+# calculate all the relative paths. The ``<path>`` argument must be an absolute
+# path. If this argument is not passed, the :variable:`CMAKE_INSTALL_PREFIX`
+# variable will be used instead. The default value is good when generating a
+# FooConfig.cmake file to use your package from the install tree. When
+# generating a FooConfig.cmake file to use your package from the build tree this
+# option should be used.
+#
+# By default ``configure_package_config_file`` also generates two helper macros,
+# ``set_and_check()`` and ``check_required_components()`` into the
+# ``FooConfig.cmake`` file.
+#
+# ``set_and_check()`` should be used instead of the normal ``set()`` command for
+# setting directories and file locations. Additionally to setting the variable
+# it also checks that the referenced file or directory actually exists and fails
+# with a ``FATAL_ERROR`` otherwise. This makes sure that the created
+# ``FooConfig.cmake`` file does not contain wrong references.
+# When using the ``NO_SET_AND_CHECK_MACRO``, this macro is not generated
+# into the ``FooConfig.cmake`` file.
+#
+# ``check_required_components(<package_name>)`` should be called at the end of
+# the ``FooConfig.cmake`` file if the package supports components. This macro
+# checks whether all requested, non-optional components have been found, and if
+# this is not the case, sets the ``Foo_FOUND`` variable to ``FALSE``, so that
+# the package is considered to be not found. It does that by testing the
+# ``Foo_<Component>_FOUND`` variables for all requested required components.
+# When using the ``NO_CHECK_REQUIRED_COMPONENTS_MACRO`` option, this macro is
+# not generated into the ``FooConfig.cmake`` file.
+#
+# For an example see below the documentation for
+# :command:`write_basic_package_version_file()`.
+#
+# Generating a Package Version File
+# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#
+# .. command:: write_basic_package_version_file
+#
+# Create a version file for a project::
+#
+# write_basic_package_version_file(<filename>
+# [VERSION <major.minor.patch>]
+# COMPATIBILITY <AnyNewerVersion|SameMajorVersion|ExactVersion> )
+#
+#
+# Writes a file for use as ``<package>ConfigVersion.cmake`` file to
+# ``<filename>``. See the documentation of :command:`find_package()` for
+# details on this.
+#
+# ``<filename>`` is the output filename, it should be in the build tree.
+# ``<major.minor.patch>`` is the version number of the project to be installed.
+#
+# If no ``VERSION`` is given, the :variable:`PROJECT_VERSION` variable is used.
+# If this hasn't been set, it errors out.
+#
+# The ``COMPATIBILITY`` mode ``AnyNewerVersion`` means that the installed
+# package version will be considered compatible if it is newer or exactly the
+# same as the requested version. This mode should be used for packages which
+# are fully backward compatible, also across major versions.
+# If ``SameMajorVersion`` is used instead, then the behaviour differs from
+# ``AnyNewerVersion`` in that the major version number must be the same as
+# requested, e.g. version 2.0 will not be considered compatible if 1.0 is
+# requested. This mode should be used for packages which guarantee backward
+# compatibility within the same major version.
+# If ``ExactVersion`` is used, then the package is only considered compatible if
+# the requested version matches exactly its own version number (not considering
+# the tweak version). For example, version 1.2.3 of a package is only
+# considered compatible to requested version 1.2.3. This mode is for packages
+# without compatibility guarantees.
+# If your project has more elaborated version matching rules, you will need to
+# write your own custom ``ConfigVersion.cmake`` file instead of using this
+# macro.
+#
+# Internally, this macro executes :command:`configure_file()` to create the
+# resulting version file. Depending on the ``COMPATIBLITY``, either the file
+# ``BasicConfigVersion-SameMajorVersion.cmake.in`` or
+# ``BasicConfigVersion-AnyNewerVersion.cmake.in`` is used. Please note that
+# these two files are internal to CMake and you should not call
+# :command:`configure_file()` on them yourself, but they can be used as starting
+# point to create more sophisticted custom ``ConfigVersion.cmake`` files.
+#
+# Example Generating Package Files
+# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#
+# Example using both :command:`configure_package_config_file` and
+# ``write_basic_package_version_file()``:
+#
+# ``CMakeLists.txt``:
+#
+# .. code-block:: cmake
+#
+# set(INCLUDE_INSTALL_DIR include/ ... CACHE )
+# set(LIB_INSTALL_DIR lib/ ... CACHE )
+# set(SYSCONFIG_INSTALL_DIR etc/foo/ ... CACHE )
+# ...
+# include(CMakePackageConfigHelpers)
+# configure_package_config_file(FooConfig.cmake.in
+# ${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake
+# INSTALL_DESTINATION ${LIB_INSTALL_DIR}/Foo/cmake
+# PATH_VARS INCLUDE_INSTALL_DIR SYSCONFIG_INSTALL_DIR)
+# write_basic_package_version_file(
+# ${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake
+# VERSION 1.2.3
+# COMPATIBILITY SameMajorVersion )
+# install(FILES ${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake
+# ${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake
+# DESTINATION ${LIB_INSTALL_DIR}/Foo/cmake )
+#
+# ``FooConfig.cmake.in``:
+#
+# .. code-block:: cmake
+#
+# set(FOO_VERSION x.y.z)
+# ...
+# @PACKAGE_INIT@
+# ...
+# set_and_check(FOO_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
+# set_and_check(FOO_SYSCONFIG_DIR "@PACKAGE_SYSCONFIG_INSTALL_DIR@")
+#
+# check_required_components(Foo)
#=============================================================================
@@ -152,10 +220,9 @@ macro(WRITE_BASIC_PACKAGE_VERSION_FILE)
write_basic_config_version_file(${ARGN})
endmacro()
-
function(CONFIGURE_PACKAGE_CONFIG_FILE _inputFile _outputFile)
set(options NO_SET_AND_CHECK_MACRO NO_CHECK_REQUIRED_COMPONENTS_MACRO)
- set(oneValueArgs INSTALL_DESTINATION )
+ set(oneValueArgs INSTALL_DESTINATION INSTALL_PREFIX)
set(multiValueArgs PATH_VARS )
cmake_parse_arguments(CCF "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
@@ -168,20 +235,30 @@ function(CONFIGURE_PACKAGE_CONFIG_FILE _inputFile _outputFile)
message(FATAL_ERROR "No INSTALL_DESTINATION given to CONFIGURE_PACKAGE_CONFIG_FILE()")
endif()
+ if(DEFINED CCF_INSTALL_PREFIX)
+ if(IS_ABSOLUTE "${CCF_INSTALL_PREFIX}")
+ set(installPrefix "${CCF_INSTALL_PREFIX}")
+ else()
+ message(FATAL_ERROR "INSTALL_PREFIX must be an absolute path")
+ endif()
+ else()
+ set(installPrefix "${CMAKE_INSTALL_PREFIX}")
+ endif()
+
if(IS_ABSOLUTE "${CCF_INSTALL_DESTINATION}")
set(absInstallDir "${CCF_INSTALL_DESTINATION}")
else()
- set(absInstallDir "${CMAKE_INSTALL_PREFIX}/${CCF_INSTALL_DESTINATION}")
+ set(absInstallDir "${installPrefix}/${CCF_INSTALL_DESTINATION}")
endif()
- file(RELATIVE_PATH PACKAGE_RELATIVE_PATH "${absInstallDir}" "${CMAKE_INSTALL_PREFIX}" )
+ file(RELATIVE_PATH PACKAGE_RELATIVE_PATH "${absInstallDir}" "${installPrefix}" )
foreach(var ${CCF_PATH_VARS})
if(NOT DEFINED ${var})
message(FATAL_ERROR "Variable ${var} does not exist")
else()
if(IS_ABSOLUTE "${${var}}")
- string(REPLACE "${CMAKE_INSTALL_PREFIX}" "\${PACKAGE_PREFIX_DIR}"
+ string(REPLACE "${installPrefix}" "\${PACKAGE_PREFIX_DIR}"
PACKAGE_${var} "${${var}}")
else()
set(PACKAGE_${var} "\${PACKAGE_PREFIX_DIR}/${${var}}")
@@ -207,7 +284,7 @@ get_filename_component(PACKAGE_PREFIX_DIR \"\${CMAKE_CURRENT_LIST_DIR}/${PACKAGE
get_filename_component(_realCurr \"\${CMAKE_CURRENT_LIST_DIR}\" REALPATH)
get_filename_component(_realOrig \"${absInstallDir}\" REALPATH)
if(_realCurr STREQUAL _realOrig)
- set(PACKAGE_PREFIX_DIR \"${CMAKE_INSTALL_PREFIX}\")
+ set(PACKAGE_PREFIX_DIR \"${installPrefix}\")
endif()
unset(_realOrig)
unset(_realCurr)
diff --git a/Modules/CMakeParseArguments.cmake b/Modules/CMakeParseArguments.cmake
index 016da0c97..fc64ab9a2 100644
--- a/Modules/CMakeParseArguments.cmake
+++ b/Modules/CMakeParseArguments.cmake
@@ -1,64 +1,11 @@
-# CMAKE_PARSE_ARGUMENTS(<prefix> <options> <one_value_keywords> <multi_value_keywords> args...)
+#.rst:
+# CMakeParseArguments
+# -------------------
#
-# CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions for
-# parsing the arguments given to that macro or function.
-# It processes the arguments and defines a set of variables which hold the
-# values of the respective options.
-#
-# The <options> argument contains all options for the respective macro,
-# i.e. keywords which can be used when calling the macro without any value
-# following, like e.g. the OPTIONAL keyword of the install() command.
-#
-# The <one_value_keywords> argument contains all keywords for this macro
-# which are followed by one value, like e.g. DESTINATION keyword of the
-# install() command.
-#
-# The <multi_value_keywords> argument contains all keywords for this macro
-# which can be followed by more than one value, like e.g. the TARGETS or
-# FILES keywords of the install() command.
-#
-# When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the
-# keywords listed in <options>, <one_value_keywords> and
-# <multi_value_keywords> a variable composed of the given <prefix>
-# followed by "_" and the name of the respective keyword.
-# These variables will then hold the respective value from the argument list.
-# For the <options> keywords this will be TRUE or FALSE.
-#
-# All remaining arguments are collected in a variable
-# <prefix>_UNPARSED_ARGUMENTS, this can be checked afterwards to see whether
-# your macro was called with unrecognized parameters.
-#
-# As an example here a my_install() macro, which takes similar arguments as the
-# real install() command:
-#
-# function(MY_INSTALL)
-# set(options OPTIONAL FAST)
-# set(oneValueArgs DESTINATION RENAME)
-# set(multiValueArgs TARGETS CONFIGURATIONS)
-# cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
-# ...
-#
-# Assume my_install() has been called like this:
-# my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub)
-#
-# After the cmake_parse_arguments() call the macro will have set the following
-# variables:
-# MY_INSTALL_OPTIONAL = TRUE
-# MY_INSTALL_FAST = FALSE (this option was not used when calling my_install()
-# MY_INSTALL_DESTINATION = "bin"
-# MY_INSTALL_RENAME = "" (was not used)
-# MY_INSTALL_TARGETS = "foo;bar"
-# MY_INSTALL_CONFIGURATIONS = "" (was not used)
-# MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL"
-#
-# You can then continue and process these variables.
-#
-# Keywords terminate lists of values, e.g. if directly after a one_value_keyword
-# another recognized keyword follows, this is interpreted as the beginning of
-# the new option.
-# E.g. my_install(TARGETS foo DESTINATION OPTIONAL) would result in
-# MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION would
-# be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor.
+# This module once implemented the :command:`cmake_parse_arguments` command
+# that is now implemented natively by CMake. It is now an empty placeholder
+# for compatibility with projects that include it to get the command from
+# CMake 3.4 and lower.
#=============================================================================
# Copyright 2010 Alexander Neundorf <neundorf@kde.org>
@@ -72,67 +19,3 @@
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
-
-
-if(__CMAKE_PARSE_ARGUMENTS_INCLUDED)
- return()
-endif()
-set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE)
-
-
-function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames)
- # first set all result variables to empty/FALSE
- foreach(arg_name ${_singleArgNames} ${_multiArgNames})
- set(${prefix}_${arg_name})
- endforeach()
-
- foreach(option ${_optionNames})
- set(${prefix}_${option} FALSE)
- endforeach()
-
- set(${prefix}_UNPARSED_ARGUMENTS)
-
- set(insideValues FALSE)
- set(currentArgName)
-
- # now iterate over all arguments and fill the result variables
- foreach(currentArg ${ARGN})
- list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword
- list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword
- list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword
-
- if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1)
- if(insideValues)
- if("${insideValues}" STREQUAL "SINGLE")
- set(${prefix}_${currentArgName} ${currentArg})
- set(insideValues FALSE)
- elseif("${insideValues}" STREQUAL "MULTI")
- list(APPEND ${prefix}_${currentArgName} ${currentArg})
- endif()
- else()
- list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg})
- endif()
- else()
- if(NOT ${optionIndex} EQUAL -1)
- set(${prefix}_${currentArg} TRUE)
- set(insideValues FALSE)
- elseif(NOT ${singleArgIndex} EQUAL -1)
- set(currentArgName ${currentArg})
- set(${prefix}_${currentArgName})
- set(insideValues "SINGLE")
- elseif(NOT ${multiArgIndex} EQUAL -1)
- set(currentArgName ${currentArg})
- set(${prefix}_${currentArgName})
- set(insideValues "MULTI")
- endif()
- endif()
-
- endforeach()
-
- # propagate the result variables to the caller:
- foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames})
- set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE)
- endforeach()
- set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE)
-
-endfunction()
diff --git a/Modules/CMakeParseImplicitLinkInfo.cmake b/Modules/CMakeParseImplicitLinkInfo.cmake
index 4724a8c7b..59092bd2c 100644
--- a/Modules/CMakeParseImplicitLinkInfo.cmake
+++ b/Modules/CMakeParseImplicitLinkInfo.cmake
@@ -31,7 +31,7 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var fwk_var log_var obj
# Construct a regex to match linker lines. It must match both the
# whole line and just the command (argv[0]).
set(linker_regex "^( *|.*[/\\])(${linker}|([^/\\]+-)?ld|collect2)[^/\\]*( |$)")
- set(linker_exclude_regex "collect2 version ")
+ set(linker_exclude_regex "collect2 version |^[A-Za-z0-9_]+=")
set(log "${log} link line regex: [${linker_regex}]\n")
string(REGEX REPLACE "\r?\n" ";" output_lines "${text}")
foreach(line IN LISTS output_lines)
@@ -64,9 +64,9 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var fwk_var log_var obj
string(REGEX REPLACE "^-L" "" dir "${arg}")
list(APPEND implicit_dirs_tmp ${dir})
set(log "${log} arg [${arg}] ==> dir [${dir}]\n")
- elseif("${arg}" MATCHES "^-l[^:]")
+ elseif("${arg}" MATCHES "^-l([^:].*)$")
# Unix library.
- string(REGEX REPLACE "^-l" "" lib "${arg}")
+ set(lib "${CMAKE_MATCH_1}")
list(APPEND implicit_libs_tmp ${lib})
set(log "${log} arg [${arg}] ==> lib [${lib}]\n")
elseif("${arg}" MATCHES "^(.:)?[/\\].*\\.a$")
@@ -97,11 +97,10 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var fwk_var log_var obj
endif()
endforeach()
break()
- elseif("${line}" MATCHES "LPATH(=| is:? )")
+ elseif("${line}" MATCHES "LPATH(=| is:? *)(.*)$")
set(log "${log} LPATH line: [${line}]\n")
# HP search path.
- string(REGEX REPLACE ".*LPATH(=| is:? *)" "" paths "${line}")
- string(REPLACE ":" ";" paths "${paths}")
+ string(REPLACE ":" ";" paths "${CMAKE_MATCH_2}")
list(APPEND implicit_dirs_tmp ${paths})
set(log "${log} dirs [${paths}]\n")
else()
@@ -125,7 +124,7 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var fwk_var log_var obj
# We remove items that are not language-specific.
set(implicit_libs "")
foreach(lib IN LISTS implicit_libs_tmp)
- if("${lib}" MATCHES "^(crt.*\\.o|gcc.*|System.*)$")
+ if("x${lib}" MATCHES "^x(crt.*\\.o|gcc.*|System.*)$")
set(log "${log} remove lib [${lib}]\n")
elseif(IS_ABSOLUTE "${lib}")
get_filename_component(abs "${lib}" ABSOLUTE)
diff --git a/Modules/CMakePlatformId.h.in b/Modules/CMakePlatformId.h.in
index 69171c2a3..da99b9e6d 100644
--- a/Modules/CMakePlatformId.h.in
+++ b/Modules/CMakePlatformId.h.in
@@ -1,3 +1,6 @@
+#define STRINGIFY_HELPER(X) #X
+#define STRINGIFY(X) STRINGIFY_HELPER(X)
+
/* Identify known platforms by name. */
#if defined(__linux) || defined(__linux__) || defined(linux)
# define PLATFORM_ID "Linux"
@@ -74,6 +77,23 @@
#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX)
# define PLATFORM_ID "Xenix"
+#elif defined(__WATCOMC__)
+# if defined(__LINUX__)
+# define PLATFORM_ID "Linux"
+
+# elif defined(__DOS__)
+# define PLATFORM_ID "DOS"
+
+# elif defined(__OS2__)
+# define PLATFORM_ID "OS2"
+
+# elif defined(__WINDOWS__)
+# define PLATFORM_ID "Windows3x"
+
+# else /* unknown platform */
+# define PLATFORM_ID ""
+# endif
+
#else /* unknown platform */
# define PLATFORM_ID ""
@@ -95,7 +115,13 @@
# define ARCHITECTURE_ID "X86"
# elif defined(_M_ARM)
-# define ARCHITECTURE_ID "ARM"
+# if _M_ARM == 4
+# define ARCHITECTURE_ID "ARMV4I"
+# elif _M_ARM == 5
+# define ARCHITECTURE_ID "ARMV5I"
+# else
+# define ARCHITECTURE_ID "ARMV" STRINGIFY(_M_ARM)
+# endif
# elif defined(_M_MIPS)
# define ARCHITECTURE_ID "MIPS"
@@ -107,6 +133,17 @@
# define ARCHITECTURE_ID ""
# endif
+#elif defined(__WATCOMC__)
+# if defined(_M_I86)
+# define ARCHITECTURE_ID "I86"
+
+# elif defined(_M_IX86)
+# define ARCHITECTURE_ID "X86"
+
+# else /* unknown architecture */
+# define ARCHITECTURE_ID ""
+# endif
+
#else
# define ARCHITECTURE_ID ""
#endif
@@ -151,6 +188,24 @@ char const info_version[] = {
']','\0'};
#endif
+/* Construct a string literal encoding the version number components. */
+#ifdef SIMULATE_VERSION_MAJOR
+char const info_simulate_version[] = {
+ 'I', 'N', 'F', 'O', ':',
+ 's','i','m','u','l','a','t','e','_','v','e','r','s','i','o','n','[',
+ SIMULATE_VERSION_MAJOR,
+# ifdef SIMULATE_VERSION_MINOR
+ '.', SIMULATE_VERSION_MINOR,
+# ifdef SIMULATE_VERSION_PATCH
+ '.', SIMULATE_VERSION_PATCH,
+# ifdef SIMULATE_VERSION_TWEAK
+ '.', SIMULATE_VERSION_TWEAK,
+# endif
+# endif
+# endif
+ ']','\0'};
+#endif
+
/* Construct the string literal in pieces to prevent the source from
getting matched. Store it in a pointer rather than an array
because some compilers will just produce instructions to fill the
diff --git a/Modules/CMakePrintHelpers.cmake b/Modules/CMakePrintHelpers.cmake
index ef5d857b6..474fa41b9 100644
--- a/Modules/CMakePrintHelpers.cmake
+++ b/Modules/CMakePrintHelpers.cmake
@@ -1,29 +1,40 @@
-# - Convenience macros for printing properties and variables, useful e.g. for debugging.
+#.rst:
+# CMakePrintHelpers
+# -----------------
#
+# Convenience macros for printing properties and variables, useful e.g. for debugging.
#
-# CMAKE_PRINT_PROPERTIES([TARGETS target1 .. targetN]
-# [SOURCES source1 .. sourceN]
-# [DIRECTORIES dir1 .. dirN]
-# [TESTS test1 .. testN]
-# [CACHE_ENTRIES entry1 .. entryN]
-# PROPERTIES prop1 .. propN )
+# ::
+#
+# CMAKE_PRINT_PROPERTIES([TARGETS target1 .. targetN]
+# [SOURCES source1 .. sourceN]
+# [DIRECTORIES dir1 .. dirN]
+# [TESTS test1 .. testN]
+# [CACHE_ENTRIES entry1 .. entryN]
+# PROPERTIES prop1 .. propN )
#
# This macro prints the values of the properties of the given targets,
-# source files, directories, tests or cache entries. Exactly one of the
-# scope keywords must be used.
-# Example:
-# cmake_print_properties(TARGETS foo bar PROPERTIES LOCATION INTERFACE_INCLUDE_DIRS)
-# This will print the LOCATION and INTERFACE_INCLUDE_DIRS properties for both
-# targets foo and bar.
+# source files, directories, tests or cache entries. Exactly one of the
+# scope keywords must be used. Example::
+#
+# cmake_print_properties(TARGETS foo bar PROPERTIES
+# LOCATION INTERFACE_INCLUDE_DIRS)
+#
+# This will print the LOCATION and INTERFACE_INCLUDE_DIRS properties for
+# both targets foo and bar.
+#
#
#
-# CMAKE_PRINT_VARIABLES(var1 var2 .. varN)
+# CMAKE_PRINT_VARIABLES(var1 var2 .. varN)
#
# This macro will print the name of each variable followed by its value.
-# Example:
-# cmake_print_variables(CMAKE_C_COMPILER CMAKE_MAJOR_VERSION THIS_ONE_DOES_NOT_EXIST)
-# Gives:
-# -- CMAKE_C_COMPILER="/usr/bin/gcc" ; CMAKE_MAJOR_VERSION="2" ; THIS_ONE_DOES_NOT_EXIST=""
+# Example::
+#
+# cmake_print_variables(CMAKE_C_COMPILER CMAKE_MAJOR_VERSION DOES_NOT_EXIST)
+#
+# Gives::
+#
+# -- CMAKE_C_COMPILER="/usr/bin/gcc" ; CMAKE_MAJOR_VERSION="2" ; DOES_NOT_EXIST=""
#=============================================================================
# Copyright 2013 Alexander Neundorf, <neundorf@kde.org>
diff --git a/Modules/CMakePrintSystemInformation.cmake b/Modules/CMakePrintSystemInformation.cmake
index e0c73346b..355c47dac 100644
--- a/Modules/CMakePrintSystemInformation.cmake
+++ b/Modules/CMakePrintSystemInformation.cmake
@@ -1,7 +1,11 @@
-# - print system information
-# This file can be used for diagnostic purposes
-# just include it in a project to see various internal CMake
-# variables.
+#.rst:
+# CMakePrintSystemInformation
+# ---------------------------
+#
+# print system information
+#
+# This file can be used for diagnostic purposes just include it in a
+# project to see various internal CMake variables.
#=============================================================================
# Copyright 2002-2009 Kitware, Inc.
diff --git a/Modules/CMakePushCheckState.cmake b/Modules/CMakePushCheckState.cmake
index b37b706ac..bf4ec0e9c 100644
--- a/Modules/CMakePushCheckState.cmake
+++ b/Modules/CMakePushCheckState.cmake
@@ -1,30 +1,37 @@
-# This module defines three macros:
-# CMAKE_PUSH_CHECK_STATE()
-# CMAKE_POP_CHECK_STATE()
-# and
-# CMAKE_RESET_CHECK_STATE()
-# These macros can be used to save, restore and reset (i.e., clear contents)
-# the state of the variables
-# CMAKE_REQUIRED_FLAGS, CMAKE_REQUIRED_DEFINITIONS, CMAKE_REQUIRED_LIBRARIES
-# and CMAKE_REQUIRED_INCLUDES used by the various Check-files coming with CMake,
-# like e.g. check_function_exists() etc.
-# The variable contents are pushed on a stack, pushing multiple times is supported.
-# This is useful e.g. when executing such tests in a Find-module, where they have to be set,
-# but after the Find-module has been executed they should have the same value
-# as they had before.
+#.rst:
+# CMakePushCheckState
+# -------------------
#
-# CMAKE_PUSH_CHECK_STATE() macro receives optional argument RESET. Whether it's specified,
-# CMAKE_PUSH_CHECK_STATE() will set all CMAKE_REQUIRED_* variables to empty values, same
-# as CMAKE_RESET_CHECK_STATE() call will do.
+#
+#
+# This module defines three macros: CMAKE_PUSH_CHECK_STATE()
+# CMAKE_POP_CHECK_STATE() and CMAKE_RESET_CHECK_STATE() These macros can
+# be used to save, restore and reset (i.e., clear contents) the state of
+# the variables CMAKE_REQUIRED_FLAGS, CMAKE_REQUIRED_DEFINITIONS,
+# CMAKE_REQUIRED_LIBRARIES and CMAKE_REQUIRED_INCLUDES used by the
+# various Check-files coming with CMake, like e.g.
+# check_function_exists() etc. The variable contents are pushed on a
+# stack, pushing multiple times is supported. This is useful e.g. when
+# executing such tests in a Find-module, where they have to be set, but
+# after the Find-module has been executed they should have the same
+# value as they had before.
+#
+# CMAKE_PUSH_CHECK_STATE() macro receives optional argument RESET.
+# Whether it's specified, CMAKE_PUSH_CHECK_STATE() will set all
+# CMAKE_REQUIRED_* variables to empty values, same as
+# CMAKE_RESET_CHECK_STATE() call will do.
#
# Usage:
-# cmake_push_check_state(RESET)
-# set(CMAKE_REQUIRED_DEFINITIONS -DSOME_MORE_DEF)
-# check_function_exists(...)
-# cmake_reset_check_state()
-# set(CMAKE_REQUIRED_DEFINITIONS -DANOTHER_DEF)
-# check_function_exists(...)
-# cmake_pop_check_state()
+#
+# ::
+#
+# cmake_push_check_state(RESET)
+# set(CMAKE_REQUIRED_DEFINITIONS -DSOME_MORE_DEF)
+# check_function_exists(...)
+# cmake_reset_check_state()
+# set(CMAKE_REQUIRED_DEFINITIONS -DANOTHER_DEF)
+# check_function_exists(...)
+# cmake_pop_check_state()
#=============================================================================
# Copyright 2006-2011 Alexander Neundorf, <neundorf@kde.org>
@@ -46,6 +53,7 @@ macro(CMAKE_RESET_CHECK_STATE)
set(CMAKE_REQUIRED_DEFINITIONS)
set(CMAKE_REQUIRED_LIBRARIES)
set(CMAKE_REQUIRED_FLAGS)
+ set(CMAKE_REQUIRED_QUIET)
endmacro()
@@ -61,6 +69,7 @@ macro(CMAKE_PUSH_CHECK_STATE)
set(_CMAKE_REQUIRED_DEFINITIONS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_DEFINITIONS})
set(_CMAKE_REQUIRED_LIBRARIES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_LIBRARIES})
set(_CMAKE_REQUIRED_FLAGS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_FLAGS})
+ set(_CMAKE_REQUIRED_QUIET_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_QUIET})
if (ARGC GREATER 0 AND ARGV0 STREQUAL "RESET")
cmake_reset_check_state()
@@ -77,6 +86,7 @@ macro(CMAKE_POP_CHECK_STATE)
set(CMAKE_REQUIRED_DEFINITIONS ${_CMAKE_REQUIRED_DEFINITIONS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
set(CMAKE_REQUIRED_LIBRARIES ${_CMAKE_REQUIRED_LIBRARIES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
set(CMAKE_REQUIRED_FLAGS ${_CMAKE_REQUIRED_FLAGS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
+ set(CMAKE_REQUIRED_QUIET ${_CMAKE_REQUIRED_QUIET_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
math(EXPR _CMAKE_PUSH_CHECK_STATE_COUNTER "${_CMAKE_PUSH_CHECK_STATE_COUNTER}-1")
endif()
diff --git a/Modules/CMakeRCCompiler.cmake.in b/Modules/CMakeRCCompiler.cmake.in
index 0fc314220..8257cd6a1 100644
--- a/Modules/CMakeRCCompiler.cmake.in
+++ b/Modules/CMakeRCCompiler.cmake.in
@@ -1,6 +1,6 @@
set(CMAKE_RC_COMPILER "@CMAKE_RC_COMPILER@")
set(CMAKE_RC_COMPILER_ARG1 "@CMAKE_RC_COMPILER_ARG1@")
set(CMAKE_RC_COMPILER_LOADED 1)
-set(CMAKE_RC_SOURCE_FILE_EXTENSIONS rc)
+set(CMAKE_RC_SOURCE_FILE_EXTENSIONS rc;RC)
set(CMAKE_RC_OUTPUT_EXTENSION @CMAKE_RC_OUTPUT_EXTENSION@)
set(CMAKE_RC_COMPILER_ENV_VAR "RC")
diff --git a/Modules/CMakeRCInformation.cmake b/Modules/CMakeRCInformation.cmake
index 8ffe50aba..94abd4be8 100644
--- a/Modules/CMakeRCInformation.cmake
+++ b/Modules/CMakeRCInformation.cmake
@@ -13,15 +13,16 @@
# License text for the above reference.)
-# This file sets the basic flags for the Fortran language in CMake.
+# This file sets the basic flags for the Windows Resource Compiler.
# It also loads the available platform file for the system-compiler
# if it exists.
# make sure we don't use CMAKE_BASE_NAME from somewhere else
set(CMAKE_BASE_NAME)
-get_filename_component(CMAKE_BASE_NAME ${CMAKE_RC_COMPILER} NAME_WE)
-if("${CMAKE_BASE_NAME}" MATCHES "windres")
- set(CMAKE_BASE_NAME "windres")
+if(CMAKE_RC_COMPILER MATCHES "windres[^/]*$")
+ set(CMAKE_BASE_NAME "windres")
+else()
+ get_filename_component(CMAKE_BASE_NAME ${CMAKE_RC_COMPILER} NAME_WE)
endif()
set(CMAKE_SYSTEM_AND_RC_COMPILER_INFO_FILE
${CMAKE_ROOT}/Modules/Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME}.cmake)
@@ -30,7 +31,7 @@ include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME} OPTIONAL)
set (CMAKE_RC_FLAGS "$ENV{RCFLAGS} ${CMAKE_RC_FLAGS_INIT}" CACHE STRING
- "Flags for Fortran compiler.")
+ "Flags for Windows Resource Compiler.")
# These are the only types of flags that should be passed to the rc
# command, if COMPILE_FLAGS is used on a target this will be used
@@ -43,7 +44,7 @@ set(CMAKE_INCLUDE_FLAG_RC "-I")
# compile a Resource file into an object file
if(NOT CMAKE_RC_COMPILE_OBJECT)
set(CMAKE_RC_COMPILE_OBJECT
- "<CMAKE_RC_COMPILER> <FLAGS> <DEFINES> /fo<OBJECT> <SOURCE>")
+ "<CMAKE_RC_COMPILER> <DEFINES> <INCLUDES> <FLAGS> /fo<OBJECT> <SOURCE>")
endif()
mark_as_advanced(
diff --git a/Modules/CMakeSwiftCompiler.cmake.in b/Modules/CMakeSwiftCompiler.cmake.in
new file mode 100644
index 000000000..45f0a3105
--- /dev/null
+++ b/Modules/CMakeSwiftCompiler.cmake.in
@@ -0,0 +1,5 @@
+set(CMAKE_Swift_COMPILER "@CMAKE_Swift_COMPILER@")
+set(CMAKE_Swift_COMPILER_ID "@CMAKE_Swift_COMPILER_ID@")
+
+set(CMAKE_Swift_COMPILER_ID_RUN 1)
+set(CMAKE_Swift_SOURCE_FILE_EXTENSIONS swift)
diff --git a/Modules/CMakeSwiftInformation.cmake b/Modules/CMakeSwiftInformation.cmake
new file mode 100644
index 000000000..61ad92834
--- /dev/null
+++ b/Modules/CMakeSwiftInformation.cmake
@@ -0,0 +1,41 @@
+
+#=============================================================================
+# Copyright 2004-2015 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+set(CMAKE_Swift_OUTPUT_EXTENSION .o)
+
+# Load compiler-specific information.
+if(CMAKE_Swift_COMPILER_ID)
+ include(Compiler/${CMAKE_Swift_COMPILER_ID}-Swift OPTIONAL)
+endif()
+
+# load the system- and compiler specific files
+if(CMAKE_Swift_COMPILER_ID)
+ # load a hardware specific file, mostly useful for embedded compilers
+ if(CMAKE_SYSTEM_PROCESSOR)
+ include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_Swift_COMPILER_ID}-Swift-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL)
+ endif()
+ include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_Swift_COMPILER_ID}-Swift OPTIONAL)
+endif()
+
+# for most systems a module is the same as a shared library
+# so unless the variable CMAKE_MODULE_EXISTS is set just
+# copy the values from the LIBRARY variables
+if(NOT CMAKE_MODULE_EXISTS)
+ set(CMAKE_SHARED_MODULE_Swift_FLAGS ${CMAKE_SHARED_LIBRARY_Swift_FLAGS})
+ set(CMAKE_SHARED_MODULE_CREATE_Swift_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_Swift_FLAGS})
+endif()
+
+include(CMakeCommonLanguageInclude)
+
+set(CMAKE_Swift_INFORMATION_LOADED 1)
diff --git a/Modules/CMakeSystemSpecificInitialize.cmake b/Modules/CMakeSystemSpecificInitialize.cmake
new file mode 100644
index 000000000..5327ac19b
--- /dev/null
+++ b/Modules/CMakeSystemSpecificInitialize.cmake
@@ -0,0 +1,20 @@
+
+#=============================================================================
+# Copyright 2002-2014 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# This file is included by cmGlobalGenerator::EnableLanguage.
+# It is included before the compiler has been determined.
+
+include(Platform/${CMAKE_SYSTEM_NAME}-Initialize OPTIONAL)
+
+set(CMAKE_SYSTEM_SPECIFIC_INITIALIZE_LOADED 1)
diff --git a/Modules/CMakeTestCCompiler.cmake b/Modules/CMakeTestCCompiler.cmake
index 2c751471a..29a58bdc9 100644
--- a/Modules/CMakeTestCCompiler.cmake
+++ b/Modules/CMakeTestCCompiler.cmake
@@ -73,12 +73,15 @@ else()
# Try to identify the ABI and configure it into CMakeCCompiler.cmake
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
CMAKE_DETERMINE_COMPILER_ABI(C ${CMAKE_ROOT}/Modules/CMakeCCompilerABI.c)
+ # Try to identify the compiler features
+ include(${CMAKE_ROOT}/Modules/CMakeDetermineCompileFeatures.cmake)
+ CMAKE_DETERMINE_COMPILE_FEATURES(C)
# Re-configure to save learned information.
configure_file(
${CMAKE_ROOT}/Modules/CMakeCCompiler.cmake.in
${CMAKE_PLATFORM_INFO_DIR}/CMakeCCompiler.cmake
- @ONLY IMMEDIATE # IMMEDIATE must be here for compatibility mode <= 2.0
+ @ONLY
)
include(${CMAKE_PLATFORM_INFO_DIR}/CMakeCCompiler.cmake)
diff --git a/Modules/CMakeTestCXXCompiler.cmake b/Modules/CMakeTestCXXCompiler.cmake
index a5cdf5669..81561b2cb 100644
--- a/Modules/CMakeTestCXXCompiler.cmake
+++ b/Modules/CMakeTestCXXCompiler.cmake
@@ -66,12 +66,15 @@ else()
# Try to identify the ABI and configure it into CMakeCXXCompiler.cmake
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
CMAKE_DETERMINE_COMPILER_ABI(CXX ${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp)
+ # Try to identify the compiler features
+ include(${CMAKE_ROOT}/Modules/CMakeDetermineCompileFeatures.cmake)
+ CMAKE_DETERMINE_COMPILE_FEATURES(CXX)
# Re-configure to save learned information.
configure_file(
${CMAKE_ROOT}/Modules/CMakeCXXCompiler.cmake.in
${CMAKE_PLATFORM_INFO_DIR}/CMakeCXXCompiler.cmake
- @ONLY IMMEDIATE # IMMEDIATE must be here for compatibility mode <= 2.0
+ @ONLY
)
include(${CMAKE_PLATFORM_INFO_DIR}/CMakeCXXCompiler.cmake)
diff --git a/Modules/CMakeTestFortranCompiler.cmake b/Modules/CMakeTestFortranCompiler.cmake
index b9e77c5f5..b50e83276 100644
--- a/Modules/CMakeTestFortranCompiler.cmake
+++ b/Modules/CMakeTestFortranCompiler.cmake
@@ -98,7 +98,7 @@ else()
configure_file(
${CMAKE_ROOT}/Modules/CMakeFortranCompiler.cmake.in
${CMAKE_PLATFORM_INFO_DIR}/CMakeFortranCompiler.cmake
- @ONLY IMMEDIATE # IMMEDIATE must be here for compatibility mode <= 2.0
+ @ONLY
)
include(${CMAKE_PLATFORM_INFO_DIR}/CMakeFortranCompiler.cmake)
diff --git a/Modules/CMakeTestSwiftCompiler.cmake b/Modules/CMakeTestSwiftCompiler.cmake
new file mode 100644
index 000000000..89849fb8c
--- /dev/null
+++ b/Modules/CMakeTestSwiftCompiler.cmake
@@ -0,0 +1,65 @@
+
+#=============================================================================
+# Copyright 2003-2015 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+if(CMAKE_Swift_COMPILER_FORCED)
+ # The compiler configuration was forced by the user.
+ # Assume the user has configured all compiler information.
+ set(CMAKE_Swift_COMPILER_WORKS TRUE)
+ return()
+endif()
+
+include(CMakeTestCompilerCommon)
+
+# Remove any cached result from an older CMake version.
+# We now store this in CMakeSwiftCompiler.cmake.
+unset(CMAKE_Swift_COMPILER_WORKS CACHE)
+
+# This file is used by EnableLanguage in cmGlobalGenerator to
+# determine that that selected C++ compiler can actually compile
+# and link the most basic of programs. If not, a fatal error
+# is set and cmake stops processing commands and will not generate
+# any makefiles or projects.
+if(NOT CMAKE_Swift_COMPILER_WORKS)
+ PrintTestCompilerStatus("Swift" "")
+ file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/main.swift
+ "import Foundation\n"
+ "print(\"CMake\")\n")
+ try_compile(CMAKE_Swift_COMPILER_WORKS ${CMAKE_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/main.swift
+ OUTPUT_VARIABLE __CMAKE_Swift_COMPILER_OUTPUT)
+ # Move result from cache to normal variable.
+ set(CMAKE_Swift_COMPILER_WORKS ${CMAKE_Swift_COMPILER_WORKS})
+ unset(CMAKE_Swift_COMPILER_WORKS CACHE)
+ set(Swift_TEST_WAS_RUN 1)
+endif()
+
+if(NOT CMAKE_Swift_COMPILER_WORKS)
+ PrintTestCompilerStatus("Swift" " -- broken")
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Determining if the Swift compiler works failed with "
+ "the following output:\n${__CMAKE_Swift_COMPILER_OUTPUT}\n\n")
+ message(FATAL_ERROR "The Swift compiler \"${CMAKE_Swift_COMPILER}\" "
+ "is not able to compile a simple test program.\nIt fails "
+ "with the following output:\n ${__CMAKE_Swift_COMPILER_OUTPUT}\n\n"
+ "CMake will not be able to correctly generate this project.")
+else()
+ if(Swift_TEST_WAS_RUN)
+ PrintTestCompilerStatus("Swift" " -- works")
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Determining if the Swift compiler works passed with "
+ "the following output:\n${__CMAKE_Swift_COMPILER_OUTPUT}\n\n")
+ endif()
+endif()
+
+unset(__CMAKE_Swift_COMPILER_OUTPUT)
diff --git a/Modules/CMakeVS10FindMake.cmake b/Modules/CMakeVS10FindMake.cmake
deleted file mode 100644
index 189b62698..000000000
--- a/Modules/CMakeVS10FindMake.cmake
+++ /dev/null
@@ -1,54 +0,0 @@
-
-#=============================================================================
-# Copyright 2007-2009 Kitware, Inc.
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-# (To distribute this file outside of CMake, substitute the full
-# License text for the above reference.)
-
-# Look for devenv as a build program. We need to use this to support
-# Intel Fortran integration into VS. MSBuild can not be used for that case
-# since Intel Fortran uses the older devenv file format.
-find_program(CMAKE_MAKE_PROGRAM
- NAMES devenv
- HINTS
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0\\Setup\\VS;EnvironmentDirectory]
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0\\Setup;Dbghelp_path]
- "$ENV{ProgramFiles}/Microsoft Visual Studio 10.0/Common7/IDE"
- "$ENV{ProgramFiles}/Microsoft Visual Studio10.0/Common7/IDE"
- "$ENV{ProgramFiles}/Microsoft Visual Studio 10/Common7/IDE"
- "$ENV{ProgramFiles}/Microsoft Visual Studio10/Common7/IDE"
- "$ENV{ProgramFiles} (x86)/Microsoft Visual Studio 10.0/Common7/IDE"
- "$ENV{ProgramFiles} (x86)/Microsoft Visual Studio10.0/Common7/IDE"
- "$ENV{ProgramFiles} (x86)/Microsoft Visual Studio 10/Common7/IDE"
- "$ENV{ProgramFiles} (x86)/Microsoft Visual Studio10/Common7/IDE"
- "/Program Files/Microsoft Visual Studio 10.0/Common7/IDE/"
- "/Program Files/Microsoft Visual Studio 10/Common7/IDE/"
- )
-
-# if devenv is not found, then use MSBuild.
-# it is expected that if devenv is not found, then we are
-# dealing with Visual Studio Express. VCExpress has random
-# failures when being run as a command line build tool which
-# causes the compiler checks and try-compile stuff to fail. MSbuild
-# is a better choice for this. However, VCExpress does not support
-# cross compiling needed for Win CE.
-if(NOT CMAKE_CROSSCOMPILING)
- find_program(CMAKE_MAKE_PROGRAM
- NAMES MSBuild
- HINTS
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0\\Setup\\VS;ProductDir]
- "$ENV{SYSTEMROOT}/Microsoft.NET/Framework/[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0;CLR Version]/"
- "c:/WINDOWS/Microsoft.NET/Framework/[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0;CLR Version]/"
- "$ENV{SYSTEMROOT}/Microsoft.NET/Framework/[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\10.0;CLR Version]/")
-endif()
-
-mark_as_advanced(CMAKE_MAKE_PROGRAM)
-set(MSVC10 1)
-set(MSVC_VERSION 1600)
diff --git a/Modules/CMakeVS11FindMake.cmake b/Modules/CMakeVS11FindMake.cmake
deleted file mode 100644
index 2df015d40..000000000
--- a/Modules/CMakeVS11FindMake.cmake
+++ /dev/null
@@ -1,53 +0,0 @@
-
-#=============================================================================
-# Copyright 2007-2011 Kitware, Inc.
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-# (To distribute this file outside of CMake, substitute the full
-# License text for the above reference.)
-
-# Look for devenv as a build program. We need to use this to support
-# Intel Fortran integration into VS. MSBuild can not be used for that case
-# since Intel Fortran uses the older devenv file format.
-find_program(CMAKE_MAKE_PROGRAM
- NAMES devenv
- HINTS
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\11.0\\Setup\\VS;EnvironmentDirectory]
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\11.0\\Setup;Dbghelp_path]
- "$ENV{ProgramFiles}/Microsoft Visual Studio 11.0/Common7/IDE"
- "$ENV{ProgramFiles}/Microsoft Visual Studio11.0/Common7/IDE"
- "$ENV{ProgramFiles}/Microsoft Visual Studio 11/Common7/IDE"
- "$ENV{ProgramFiles}/Microsoft Visual Studio11/Common7/IDE"
- "$ENV{ProgramFiles} (x86)/Microsoft Visual Studio 11.0/Common7/IDE"
- "$ENV{ProgramFiles} (x86)/Microsoft Visual Studio11.0/Common7/IDE"
- "$ENV{ProgramFiles} (x86)/Microsoft Visual Studio 11/Common7/IDE"
- "$ENV{ProgramFiles} (x86)/Microsoft Visual Studio11/Common7/IDE"
- "/Program Files/Microsoft Visual Studio 11.0/Common7/IDE/"
- "/Program Files/Microsoft Visual Studio 11/Common7/IDE/"
- )
-
-# if devenv is not found, then use MSBuild.
-# it is expected that if devenv is not found, then we are
-# dealing with Visual Studio Express.
-if(NOT CMAKE_CROSSCOMPILING)
- set(_FDIR "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VC7;FrameworkDir32]")
- set(_FVER "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VC7;FrameworkVer32]")
- find_program(CMAKE_MAKE_PROGRAM
- NAMES MSBuild
- HINTS
- ${_FDIR}/${_FVER}
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\11.0\\Setup\\VS;ProductDir]
- "$ENV{SYSTEMROOT}/Microsoft.NET/Framework/[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\11.0;CLR Version]/"
- "c:/WINDOWS/Microsoft.NET/Framework/[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\11.0;CLR Version]/"
- "$ENV{SYSTEMROOT}/Microsoft.NET/Framework/[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\11.0;CLR Version]/")
-endif()
-
-mark_as_advanced(CMAKE_MAKE_PROGRAM)
-set(MSVC11 1)
-set(MSVC_VERSION 1700)
diff --git a/Modules/CMakeVS12FindMake.cmake b/Modules/CMakeVS12FindMake.cmake
deleted file mode 100644
index 338d9a236..000000000
--- a/Modules/CMakeVS12FindMake.cmake
+++ /dev/null
@@ -1,27 +0,0 @@
-
-#=============================================================================
-# Copyright 2007-2013 Kitware, Inc.
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-# (To distribute this file outside of CMake, substitute the full
-# License text for the above reference.)
-
-# Always use MSBuild because:
-# - devenv treats command-line builds as recently-loaded projects in the IDE
-# - devenv does not appear to support non-standard platform toolsets
-# If we need devenv for Intel Fortran in the future we should add
-# a special case when Fortran is enabled.
-find_program(CMAKE_MAKE_PROGRAM
- NAMES MSBuild
- HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\12.0;MSBuildToolsPath]"
- )
-
-mark_as_advanced(CMAKE_MAKE_PROGRAM)
-set(MSVC12 1)
-set(MSVC_VERSION 1800)
diff --git a/Modules/CMakeVS6FindMake.cmake b/Modules/CMakeVS6FindMake.cmake
deleted file mode 100644
index 40bf5b172..000000000
--- a/Modules/CMakeVS6FindMake.cmake
+++ /dev/null
@@ -1,25 +0,0 @@
-
-#=============================================================================
-# Copyright 2002-2009 Kitware, Inc.
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-# (To distribute this file outside of CMake, substitute the full
-# License text for the above reference.)
-
-find_program(CMAKE_MAKE_PROGRAM
- NAMES msdev
- PATHS
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\6.0\\Setup;VsCommonDir]/MSDev98/Bin
- "c:/Program Files/Microsoft Visual Studio/Common/MSDev98/Bin"
- "c:/Program Files/Microsoft Visual Studio/Common/MSDev98/Bin"
- "/Program Files/Microsoft Visual Studio/Common/MSDev98/Bin"
- )
-mark_as_advanced(CMAKE_MAKE_PROGRAM)
-set(MSVC60 1)
-set(MSVC_VERSION 1200)
diff --git a/Modules/CMakeVS71FindMake.cmake b/Modules/CMakeVS71FindMake.cmake
deleted file mode 100644
index 945c3faf8..000000000
--- a/Modules/CMakeVS71FindMake.cmake
+++ /dev/null
@@ -1,26 +0,0 @@
-
-#=============================================================================
-# Copyright 2003-2009 Kitware, Inc.
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-# (To distribute this file outside of CMake, substitute the full
-# License text for the above reference.)
-
-find_program(CMAKE_MAKE_PROGRAM
- NAMES devenv
- PATHS
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\7.1\\Setup\\VS;EnvironmentDirectory]
- "$ENV{ProgramFiles}/Microsoft Visual Studio .NET/Common7/IDE"
- "c:/Program Files/Microsoft Visual Studio .NET/Common7/IDE"
- "c:/Program Files/Microsoft Visual Studio.NET/Common7/IDE"
- "/Program Files/Microsoft Visual Studio .NET/Common7/IDE/"
- )
-mark_as_advanced(CMAKE_MAKE_PROGRAM)
-set(MSVC71 1)
-set(MSVC_VERSION 1310)
diff --git a/Modules/CMakeVS7FindMake.cmake b/Modules/CMakeVS7FindMake.cmake
deleted file mode 100644
index 218c5f2df..000000000
--- a/Modules/CMakeVS7FindMake.cmake
+++ /dev/null
@@ -1,25 +0,0 @@
-
-#=============================================================================
-# Copyright 2002-2009 Kitware, Inc.
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-# (To distribute this file outside of CMake, substitute the full
-# License text for the above reference.)
-
-find_program(CMAKE_MAKE_PROGRAM
- NAMES devenv
- PATHS
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\7.0\\Setup\\VS;EnvironmentDirectory]
- "c:/Program Files/Microsoft Visual Studio .NET/Common7/IDE"
- "c:/Program Files/Microsoft Visual Studio.NET/Common7/IDE"
- "/Program Files/Microsoft Visual Studio .NET/Common7/IDE/"
- )
-mark_as_advanced(CMAKE_MAKE_PROGRAM)
-set(MSVC70 1)
-set(MSVC_VERSION 1300)
diff --git a/Modules/CMakeVS8FindMake.cmake b/Modules/CMakeVS8FindMake.cmake
deleted file mode 100644
index 31df0268d..000000000
--- a/Modules/CMakeVS8FindMake.cmake
+++ /dev/null
@@ -1,34 +0,0 @@
-
-#=============================================================================
-# Copyright 2004-2009 Kitware, Inc.
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-# (To distribute this file outside of CMake, substitute the full
-# License text for the above reference.)
-
-# VCExpress does not support cross compiling, which is necessary for Win CE
-set( _CMAKE_MAKE_PROGRAM_NAMES devenv)
-if(NOT CMAKE_CROSSCOMPILING)
- set( _CMAKE_MAKE_PROGRAM_NAMES ${_CMAKE_MAKE_PROGRAM_NAMES} VCExpress)
-endif()
-
-find_program(CMAKE_MAKE_PROGRAM
- NAMES ${_CMAKE_MAKE_PROGRAM_NAMES}
- HINTS
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\8.0\\Setup\\VS;EnvironmentDirectory]
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\8.0\\Setup;Dbghelp_path]
- "$ENV{ProgramFiles}/Microsoft Visual Studio 8/Common7/IDE"
- "$ENV{ProgramFiles}/Microsoft Visual Studio8/Common7/IDE"
- "$ENV{ProgramFiles} (x86)/Microsoft Visual Studio 8/Common7/IDE"
- "$ENV{ProgramFiles} (x86)/Microsoft Visual Studio8/Common7/IDE"
- "/Program Files/Microsoft Visual Studio 8/Common7/IDE/"
- )
-mark_as_advanced(CMAKE_MAKE_PROGRAM)
-set(MSVC80 1)
-set(MSVC_VERSION 1400)
diff --git a/Modules/CMakeVS9FindMake.cmake b/Modules/CMakeVS9FindMake.cmake
deleted file mode 100644
index 35e9f981a..000000000
--- a/Modules/CMakeVS9FindMake.cmake
+++ /dev/null
@@ -1,39 +0,0 @@
-
-#=============================================================================
-# Copyright 2007-2009 Kitware, Inc.
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-# (To distribute this file outside of CMake, substitute the full
-# License text for the above reference.)
-
-# VCExpress does not support cross compiling, which is necessary for Win CE
-set( _CMAKE_MAKE_PROGRAM_NAMES devenv)
-if(NOT CMAKE_CROSSCOMPILING)
- set( _CMAKE_MAKE_PROGRAM_NAMES ${_CMAKE_MAKE_PROGRAM_NAMES} VCExpress)
-endif()
-
-find_program(CMAKE_MAKE_PROGRAM
- NAMES ${_CMAKE_MAKE_PROGRAM_NAMES}
- HINTS
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\9.0\\Setup\\VS;EnvironmentDirectory]
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\9.0\\Setup;Dbghelp_path]
- "$ENV{ProgramFiles}/Microsoft Visual Studio 9.0/Common7/IDE"
- "$ENV{ProgramFiles}/Microsoft Visual Studio9.0/Common7/IDE"
- "$ENV{ProgramFiles}/Microsoft Visual Studio 9/Common7/IDE"
- "$ENV{ProgramFiles}/Microsoft Visual Studio9/Common7/IDE"
- "$ENV{ProgramFiles} (x86)/Microsoft Visual Studio 9.0/Common7/IDE"
- "$ENV{ProgramFiles} (x86)/Microsoft Visual Studio9.0/Common7/IDE"
- "$ENV{ProgramFiles} (x86)/Microsoft Visual Studio 9/Common7/IDE"
- "$ENV{ProgramFiles} (x86)/Microsoft Visual Studio9/Common7/IDE"
- "/Program Files/Microsoft Visual Studio 9.0/Common7/IDE/"
- "/Program Files/Microsoft Visual Studio 9/Common7/IDE/"
- )
-mark_as_advanced(CMAKE_MAKE_PROGRAM)
-set(MSVC90 1)
-set(MSVC_VERSION 1500)
diff --git a/Modules/CMakeVerifyManifest.cmake b/Modules/CMakeVerifyManifest.cmake
index aebe77ea1..bff4e1e94 100644
--- a/Modules/CMakeVerifyManifest.cmake
+++ b/Modules/CMakeVerifyManifest.cmake
@@ -1,14 +1,19 @@
+#.rst:
+# CMakeVerifyManifest
+# -------------------
+#
+#
+#
# CMakeVerifyManifest.cmake
#
-# This script is used to verify that embeded manifests and
-# side by side manifests for a project match. To run this
-# script, cd to a directory and run the script with cmake -P.
-# On the command line you can pass in versions that are OK even
-# if not found in the .manifest files. For example,
-# cmake -Dallow_versions=8.0.50608.0 -PCmakeVerifyManifest.cmake
-# could be used to allow an embeded manifest of 8.0.50608.0
-# to be used in a project even if that version was not found
-# in the .manifest file.
+# This script is used to verify that embeded manifests and side by side
+# manifests for a project match. To run this script, cd to a directory
+# and run the script with cmake -P. On the command line you can pass in
+# versions that are OK even if not found in the .manifest files. For
+# example, cmake -Dallow_versions=8.0.50608.0
+# -PCmakeVerifyManifest.cmake could be used to allow an embeded manifest
+# of 8.0.50608.0 to be used in a project even if that version was not
+# found in the .manifest file.
# This script first recursively globs *.manifest files from
# the current directory. Then globs *.exe and *.dll. Each
diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake
index b0260ab16..77f854d5e 100644
--- a/Modules/CPack.cmake
+++ b/Modules/CPack.cmake
@@ -1,275 +1,279 @@
-##section Variables common to all CPack generators
-##end
-##module
-# - Build binary and source package installers.
-# The CPack module generates binary and source installers in a variety
-# of formats using the cpack program. Inclusion of the CPack module
-# adds two new targets to the resulting makefiles, package and
+#.rst:
+# CPack
+# -----
+#
+# Build binary and source package installers.
+#
+# Variables common to all CPack generators
+# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#
+# The
+# CPack module generates binary and source installers in a variety of
+# formats using the cpack program. Inclusion of the CPack module adds
+# two new targets to the resulting makefiles, package and
# package_source, which build the binary and source installers,
-# respectively. The generated binary installers contain everything
+# respectively. The generated binary installers contain everything
# installed via CMake's INSTALL command (and the deprecated
# INSTALL_FILES, INSTALL_PROGRAMS, and INSTALL_TARGETS commands).
#
# For certain kinds of binary installers (including the graphical
# installers on Mac OS X and Windows), CPack generates installers that
-# allow users to select individual application components to
-# install. See CPackComponent module for that.
+# allow users to select individual application components to install.
+# See CPackComponent module for that.
#
# The CPACK_GENERATOR variable has different meanings in different
-# contexts. In your CMakeLists.txt file, CPACK_GENERATOR is a
-# *list of generators*: when run with no other arguments, CPack
-# will iterate over that list and produce one package for each
-# generator. In a CPACK_PROJECT_CONFIG_FILE, though, CPACK_GENERATOR
-# is a *string naming a single generator*. If you need per-cpack-
-# generator logic to control *other* cpack settings, then you need
-# a CPACK_PROJECT_CONFIG_FILE.
+# contexts. In your CMakeLists.txt file, CPACK_GENERATOR is a *list of
+# generators*: when run with no other arguments, CPack will iterate over
+# that list and produce one package for each generator. In a
+# CPACK_PROJECT_CONFIG_FILE, though, CPACK_GENERATOR is a *string naming
+# a single generator*. If you need per-cpack- generator logic to
+# control *other* cpack settings, then you need a
+# CPACK_PROJECT_CONFIG_FILE.
#
# The CMake source tree itself contains a CPACK_PROJECT_CONFIG_FILE.
# See the top level file CMakeCPackOptions.cmake.in for an example.
#
-# If set, the CPACK_PROJECT_CONFIG_FILE is included automatically
-# on a per-generator basis. It only need contain overrides.
+# If set, the CPACK_PROJECT_CONFIG_FILE is included automatically on a
+# per-generator basis. It only need contain overrides.
#
# Here's how it works:
-# - cpack runs
-# - it includes CPackConfig.cmake
-# - it iterates over the generators listed in that file's
-# CPACK_GENERATOR list variable (unless told to use just a
-# specific one via -G on the command line...)
-#
-# - foreach generator, it then
-# - sets CPACK_GENERATOR to the one currently being iterated
-# - includes the CPACK_PROJECT_CONFIG_FILE
-# - produces the package for that generator
-#
-# This is the key: For each generator listed in CPACK_GENERATOR
-# in CPackConfig.cmake, cpack will *reset* CPACK_GENERATOR
-# internally to *the one currently being used* and then include
-# the CPACK_PROJECT_CONFIG_FILE.
-#
-# Before including this CPack module in your CMakeLists.txt file,
-# there are a variety of variables that can be set to customize
-# the resulting installers. The most commonly-used variables are:
-##end
-#
-##variable
-# CPACK_PACKAGE_NAME - The name of the package (or application). If
-# not specified, defaults to the project name.
-##end
-#
-##variable
-# CPACK_PACKAGE_VENDOR - The name of the package vendor. (e.g.,
-# "Kitware").
-##end
-#
-##variable
-# CPACK_PACKAGE_DIRECTORY - The directory in which CPack is doing its
-# packaging. If it is not set then this will default (internally) to the
-# build dir. This variable may be defined in CPack config file or from
-# the cpack command line option "-B". If set the command line option
-# override the value found in the config file.
-##end
-#
-##variable
-# CPACK_PACKAGE_VERSION_MAJOR - Package major Version
-##end
-#
-##variable
-# CPACK_PACKAGE_VERSION_MINOR - Package minor Version
-##end
-#
-##variable
-# CPACK_PACKAGE_VERSION_PATCH - Package patch Version
-##end
-#
-##variable
-# CPACK_PACKAGE_DESCRIPTION_FILE - A text file used to describe the
-# project. Used, for example, the introduction screen of a
-# CPack-generated Windows installer to describe the project.
-##end
-#
-##variable
-# CPACK_PACKAGE_DESCRIPTION_SUMMARY - Short description of the
-# project (only a few words).
-##end
-#
-##variable
-# CPACK_PACKAGE_FILE_NAME - The name of the package file to generate,
-# not including the extension. For example, cmake-2.6.1-Linux-i686.
-# The default value is
-#
-# ${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_SYSTEM_NAME}.
-##end
-#
-##variable
-# CPACK_PACKAGE_INSTALL_DIRECTORY - Installation directory on the
-# target system. This may be used by some CPack generators
-# like NSIS to create an installation directory e.g., "CMake 2.5"
-# below the installation prefix. All installed element will be
+#
+# * cpack runs
+# * it includes CPackConfig.cmake
+# * it iterates over the generators listed in that file's
+# CPACK_GENERATOR list variable (unless told to use just a
+# specific one via -G on the command line...)
+# * foreach generator, it then
+#
+# - sets CPACK_GENERATOR to the one currently being iterated
+# - includes the CPACK_PROJECT_CONFIG_FILE
+# - produces the package for that generator
+#
+# This is the key: For each generator listed in CPACK_GENERATOR in
+# CPackConfig.cmake, cpack will *reset* CPACK_GENERATOR internally to
+# *the one currently being used* and then include the
+# CPACK_PROJECT_CONFIG_FILE.
+#
+# Before including this CPack module in your CMakeLists.txt file, there
+# are a variety of variables that can be set to customize the resulting
+# installers. The most commonly-used variables are:
+#
+# .. variable:: CPACK_PACKAGE_NAME
+#
+# The name of the package (or application). If not specified, defaults to
+# the project name.
+#
+# .. variable:: CPACK_PACKAGE_VENDOR
+#
+# The name of the package vendor. (e.g., "Kitware").
+#
+# .. variable:: CPACK_PACKAGE_DIRECTORY
+#
+# The directory in which CPack is doing its packaging. If it is not set
+# then this will default (internally) to the build dir. This variable may
+# be defined in CPack config file or from the cpack command line option
+# "-B". If set the command line option override the value found in the
+# config file.
+#
+# .. variable:: CPACK_PACKAGE_VERSION_MAJOR
+#
+# Package major Version
+#
+# .. variable:: CPACK_PACKAGE_VERSION_MINOR
+#
+# Package minor Version
+#
+# .. variable:: CPACK_PACKAGE_VERSION_PATCH
+#
+# Package patch Version
+#
+# .. variable:: CPACK_PACKAGE_DESCRIPTION_FILE
+#
+# A text file used to describe the project. Used, for example, the
+# introduction screen of a CPack-generated Windows installer to describe
+# the project.
+#
+# .. variable:: CPACK_PACKAGE_DESCRIPTION_SUMMARY
+#
+# Short description of the project (only a few words).
+#
+# .. variable:: CPACK_PACKAGE_FILE_NAME
+#
+# The name of the package file to generate, not including the
+# extension. For example, cmake-2.6.1-Linux-i686. The default value is::
+#
+# ${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_SYSTEM_NAME}.
+#
+# .. variable:: CPACK_PACKAGE_INSTALL_DIRECTORY
+#
+# Installation directory on the target system. This may be used by some
+# CPack generators like NSIS to create an installation directory e.g.,
+# "CMake 2.5" below the installation prefix. All installed element will be
# put inside this directory.
-##end
-#
-##variable
-# CPACK_PACKAGE_ICON - A branding image that will be displayed inside
-# the installer (used by GUI installers).
-##end
-#
-##variable
-# CPACK_PROJECT_CONFIG_FILE - CPack-time project CPack configuration
-# file. This file included at cpack time, once per
-# generator after CPack has set CPACK_GENERATOR to the actual generator
-# being used. It allows per-generator setting of CPACK_* variables at
-# cpack time.
-##end
-#
-##variable
-# CPACK_RESOURCE_FILE_LICENSE - License to be embedded in the installer. It
-# will typically be displayed to the user by the produced installer
-# (often with an explicit "Accept" button, for graphical installers)
-# prior to installation. This license file is NOT added to installed
-# file but is used by some CPack generators like NSIS. If you want
-# to install a license file (may be the same as this one)
-# along with your project you must add an appropriate CMake INSTALL
+#
+# .. variable:: CPACK_PACKAGE_ICON
+#
+# A branding image that will be displayed inside the installer (used by GUI
+# installers).
+#
+# .. variable:: CPACK_PROJECT_CONFIG_FILE
+#
+# CPack-time project CPack configuration file. This file included at cpack
+# time, once per generator after CPack has set CPACK_GENERATOR to the
+# actual generator being used. It allows per-generator setting of CPACK_*
+# variables at cpack time.
+#
+# .. variable:: CPACK_RESOURCE_FILE_LICENSE
+#
+# License to be embedded in the installer. It will typically be displayed
+# to the user by the produced installer (often with an explicit "Accept"
+# button, for graphical installers) prior to installation. This license
+# file is NOT added to installed file but is used by some CPack generators
+# like NSIS. If you want to install a license file (may be the same as this
+# one) along with your project you must add an appropriate CMake INSTALL
# command in your CMakeLists.txt.
-##end
-#
-##variable
-# CPACK_RESOURCE_FILE_README - ReadMe file to be embedded in the installer. It
-# typically describes in some detail the purpose of the project
-# during the installation. Not all CPack generators uses
-# this file.
-##end
-#
-##variable
-# CPACK_RESOURCE_FILE_WELCOME - Welcome file to be embedded in the
-# installer. It welcomes users to this installer.
-# Typically used in the graphical installers on Windows and Mac OS X.
-##end
-#
-##variable
-# CPACK_MONOLITHIC_INSTALL - Disables the component-based
-# installation mechanism. When set the component specification is ignored
-# and all installed items are put in a single "MONOLITHIC" package.
-# Some CPack generators do monolithic packaging by default and
-# may be asked to do component packaging by setting
-# CPACK_<GENNAME>_COMPONENT_INSTALL to 1/TRUE.
-##end
-#
-##variable
-# CPACK_GENERATOR - List of CPack generators to use. If not
-# specified, CPack will create a set of options CPACK_BINARY_<GENNAME> (e.g.,
-# CPACK_BINARY_NSIS) allowing the user to enable/disable individual
-# generators. This variable may be used on the command line
-# as well as in:
-#
-# cpack -D CPACK_GENERATOR="ZIP;TGZ" /path/to/build/tree
-##end
-#
-##variable
-# CPACK_OUTPUT_CONFIG_FILE - The name of the CPack binary configuration
-# file. This file is the CPack configuration generated by the CPack module
-# for binary installers. Defaults to CPackConfig.cmake.
-##end
-#
-##variable
-# CPACK_PACKAGE_EXECUTABLES - Lists each of the executables and associated
-# text label to be used to create Start Menu shortcuts. For example,
-# setting this to the list ccmake;CMake will
-# create a shortcut named "CMake" that will execute the installed
-# executable ccmake. Not all CPack generators use it (at least NSIS and
-# OSXX11 do).
-##end
-#
-##variable
-# CPACK_STRIP_FILES - List of files to be stripped. Starting with
-# CMake 2.6.0 CPACK_STRIP_FILES will be a boolean variable which
-# enables stripping of all files (a list of files evaluates to TRUE
-# in CMake, so this change is compatible).
-##end
+#
+# .. variable:: CPACK_RESOURCE_FILE_README
+#
+# ReadMe file to be embedded in the installer. It typically describes in
+# some detail the purpose of the project during the installation. Not all
+# CPack generators uses this file.
+#
+# .. variable:: CPACK_RESOURCE_FILE_WELCOME
+#
+# Welcome file to be embedded in the installer. It welcomes users to this
+# installer. Typically used in the graphical installers on Windows and Mac
+# OS X.
+#
+# .. variable:: CPACK_MONOLITHIC_INSTALL
+#
+# Disables the component-based installation mechanism. When set the
+# component specification is ignored and all installed items are put in a
+# single "MONOLITHIC" package. Some CPack generators do monolithic
+# packaging by default and may be asked to do component packaging by
+# setting CPACK_<GENNAME>_COMPONENT_INSTALL to 1/TRUE.
+#
+# .. variable:: CPACK_GENERATOR
+#
+# List of CPack generators to use. If not specified, CPack will create a
+# set of options CPACK_BINARY_<GENNAME> (e.g., CPACK_BINARY_NSIS) allowing
+# the user to enable/disable individual generators. This variable may be
+# used on the command line as well as in::
+#
+# cpack -D CPACK_GENERATOR="ZIP;TGZ" /path/to/build/tree
+#
+# .. variable:: CPACK_OUTPUT_CONFIG_FILE
+#
+# The name of the CPack binary configuration file. This file is the CPack
+# configuration generated by the CPack module for binary
+# installers. Defaults to CPackConfig.cmake.
+#
+# .. variable:: CPACK_PACKAGE_EXECUTABLES
+#
+# Lists each of the executables and associated text label to be used to
+# create Start Menu shortcuts. For example, setting this to the list
+# ccmake;CMake will create a shortcut named "CMake" that will execute the
+# installed executable ccmake. Not all CPack generators use it (at least
+# NSIS, WIX and OSXX11 do).
+#
+# .. variable:: CPACK_STRIP_FILES
+#
+# List of files to be stripped. Starting with CMake 2.6.0 CPACK_STRIP_FILES
+# will be a boolean variable which enables stripping of all files (a list
+# of files evaluates to TRUE in CMake, so this change is compatible).
+#
+# .. variable:: CPACK_VERBATIM_VARIABLES
+#
+# If set to TRUE, values of variables prefixed with CPACK_ will be escaped
+# before being written to the configuration files, so that the cpack program
+# receives them exactly as they were specified. If not, characters like quotes
+# and backslashes can cause parsing errors or alter the value received by the
+# cpack program. Defaults to FALSE for backwards compatibility.
+#
+# * Mandatory : NO
+# * Default : FALSE
#
# The following CPack variables are specific to source packages, and
# will not affect binary packages:
#
-##variable
-# CPACK_SOURCE_PACKAGE_FILE_NAME - The name of the source package. For
-# example cmake-2.6.1.
-##end
-#
-##variable
-# CPACK_SOURCE_STRIP_FILES - List of files in the source tree that
-# will be stripped. Starting with CMake 2.6.0
-# CPACK_SOURCE_STRIP_FILES will be a boolean variable which enables
-# stripping of all files (a list of files evaluates to TRUE in CMake,
-# so this change is compatible).
-##end
-#
-##variable
-# CPACK_SOURCE_GENERATOR - List of generators used for the source
-# packages. As with CPACK_GENERATOR, if this is not specified then
-# CPack will create a set of options (e.g., CPACK_SOURCE_ZIP)
-# allowing users to select which packages will be generated.
-##end
-#
-##variable
-# CPACK_SOURCE_OUTPUT_CONFIG_FILE - The name of the CPack source
-# configuration file. This file is the CPack configuration generated by the
-# CPack module for source installers. Defaults to CPackSourceConfig.cmake.
-##end
-#
-##variable
-# CPACK_SOURCE_IGNORE_FILES - Pattern of files in the source tree
-# that won't be packaged when building a source package. This is a
-# list of regular expression patterns (that must be properly escaped),
-# e.g., /CVS/;/\\.svn/;\\.swp$;\\.#;/#;.*~;cscope.*
-##end
+# .. variable:: CPACK_SOURCE_PACKAGE_FILE_NAME
+#
+# The name of the source package. For example cmake-2.6.1.
+#
+# .. variable:: CPACK_SOURCE_STRIP_FILES
+#
+# List of files in the source tree that will be stripped. Starting with
+# CMake 2.6.0 CPACK_SOURCE_STRIP_FILES will be a boolean variable which
+# enables stripping of all files (a list of files evaluates to TRUE in
+# CMake, so this change is compatible).
+#
+# .. variable:: CPACK_SOURCE_GENERATOR
+#
+# List of generators used for the source packages. As with CPACK_GENERATOR,
+# if this is not specified then CPack will create a set of options (e.g.,
+# CPACK_SOURCE_ZIP) allowing users to select which packages will be
+# generated.
+#
+# .. variable:: CPACK_SOURCE_OUTPUT_CONFIG_FILE
+#
+# The name of the CPack source configuration file. This file is the CPack
+# configuration generated by the CPack module for source
+# installers. Defaults to CPackSourceConfig.cmake.
+#
+# .. variable:: CPACK_SOURCE_IGNORE_FILES
+#
+# Pattern of files in the source tree that won't be packaged when building
+# a source package. This is a list of regular expression patterns (that
+# must be properly escaped), e.g.,
+# /CVS/;/\\.svn/;\\.swp$;\\.#;/#;.*~;cscope.*
#
# The following variables are for advanced uses of CPack:
#
-##variable
-# CPACK_CMAKE_GENERATOR - What CMake generator should be used if the
-# project is CMake project. Defaults to the value of CMAKE_GENERATOR
-# few users will want to change this setting.
-##end
-#
-##variable
-# CPACK_INSTALL_CMAKE_PROJECTS - List of four values that specify
-# what project to install. The four values are: Build directory,
-# Project Name, Project Component, Directory. If omitted, CPack will
-# build an installer that installers everything.
-##end
-#
-##variable
-# CPACK_SYSTEM_NAME - System name, defaults to the value of
-# ${CMAKE_SYSTEM_NAME}.
-##end
-#
-##variable
-# CPACK_PACKAGE_VERSION - Package full version, used internally. By
-# default, this is built from CPACK_PACKAGE_VERSION_MAJOR,
-# CPACK_PACKAGE_VERSION_MINOR, and CPACK_PACKAGE_VERSION_PATCH.
-##end
-#
-##variable
-# CPACK_TOPLEVEL_TAG - Directory for the installed files.
-##end
-#
-##variable
-# CPACK_INSTALL_COMMANDS - Extra commands to install components.
-##end
-#
-##variable
-# CPACK_INSTALLED_DIRECTORIES - Extra directories to install.
-##end
-#
-##variable
-# CPACK_PACKAGE_INSTALL_REGISTRY_KEY - Registry key used when
-# installing this project. This is only used by installer for Windows.
-# The default value is based on the installation directory.
-##end
-##variable
-# CPACK_CREATE_DESKTOP_LINKS - List of desktop links to create.
-##end
+# .. variable:: CPACK_CMAKE_GENERATOR
+#
+# What CMake generator should be used if the project is CMake
+# project. Defaults to the value of CMAKE_GENERATOR few users will want to
+# change this setting.
+#
+# .. variable:: CPACK_INSTALL_CMAKE_PROJECTS
+#
+# List of four values that specify what project to install. The four values
+# are: Build directory, Project Name, Project Component, Directory. If
+# omitted, CPack will build an installer that installs everything.
+#
+# .. variable:: CPACK_SYSTEM_NAME
+#
+# System name, defaults to the value of ${CMAKE_SYSTEM_NAME}.
+#
+# .. variable:: CPACK_PACKAGE_VERSION
+#
+# Package full version, used internally. By default, this is built from
+# CPACK_PACKAGE_VERSION_MAJOR, CPACK_PACKAGE_VERSION_MINOR, and
+# CPACK_PACKAGE_VERSION_PATCH.
+#
+# .. variable:: CPACK_TOPLEVEL_TAG
+#
+# Directory for the installed files.
+#
+# .. variable:: CPACK_INSTALL_COMMANDS
+#
+# Extra commands to install components.
+#
+# .. variable:: CPACK_INSTALLED_DIRECTORIES
+#
+# Extra directories to install.
#
+# .. variable:: CPACK_PACKAGE_INSTALL_REGISTRY_KEY
+#
+# Registry key used when installing this project. This is only used by
+# installer for Windows. The default value is based on the installation
+# directory.
+#
+# .. variable:: CPACK_CREATE_DESKTOP_LINKS
+#
+# List of desktop links to create.
+# Each desktop link requires a corresponding start menu shortcut
+# as created by :variable:`CPACK_PACKAGE_EXECUTABLES`.
#=============================================================================
# Copyright 2006-2009 Kitware, Inc.
@@ -306,49 +310,68 @@ endif()
include(CPackComponent)
# Macro for setting values if a user did not overwrite them
+# Mangles CMake-special characters. Only kept for backwards compatibility.
macro(cpack_set_if_not_set name value)
- if(NOT DEFINED "${name}")
- set(${name} "${value}")
- endif()
+ message(DEPRECATION "cpack_set_if_not_set is obsolete; do not use.")
+ _cpack_set_default("${name}" "${value}")
endmacro()
-# cpack_encode_variables - Macro to encode variables for the configuration file
+# cpack_encode_variables - Function to encode variables for the configuration file
# find any variable that starts with CPACK and create a variable
# _CPACK_OTHER_VARIABLES_ that contains SET commands for
# each cpack variable. _CPACK_OTHER_VARIABLES_ is then
# used as an @ replacment in configure_file for the CPackConfig.
-macro(cpack_encode_variables)
- set(_CPACK_OTHER_VARIABLES_)
+function(cpack_encode_variables)
+ set(commands "")
get_cmake_property(res VARIABLES)
foreach(var ${res})
- if("xxx${var}" MATCHES "xxxCPACK")
- set(_CPACK_OTHER_VARIABLES_
- "${_CPACK_OTHER_VARIABLES_}\nSET(${var} \"${${var}}\")")
+ if(var MATCHES "^CPACK")
+ if(CPACK_VERBATIM_VARIABLES)
+ _cpack_escape_for_cmake(value "${${var}}")
+ else()
+ set(value "${${var}}")
endif()
+
+ set(commands "${commands}\nSET(${var} \"${value}\")")
+ endif()
endforeach()
-endmacro()
+
+ set(_CPACK_OTHER_VARIABLES_ "${commands}" PARENT_SCOPE)
+endfunction()
+
+# Internal use functions
+function(_cpack_set_default name value)
+ if(NOT DEFINED "${name}")
+ set("${name}" "${value}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+function(_cpack_escape_for_cmake var value)
+ string(REGEX REPLACE "([\\\$\"])" "\\\\\\1" escaped "${value}")
+ set("${var}" "${escaped}" PARENT_SCOPE)
+endfunction()
# Set the package name
-cpack_set_if_not_set(CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}")
-cpack_set_if_not_set(CPACK_PACKAGE_VERSION_MAJOR "0")
-cpack_set_if_not_set(CPACK_PACKAGE_VERSION_MINOR "1")
-cpack_set_if_not_set(CPACK_PACKAGE_VERSION_PATCH "1")
-cpack_set_if_not_set(CPACK_PACKAGE_VERSION
+_cpack_set_default(CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}")
+_cpack_set_default(CPACK_PACKAGE_VERSION_MAJOR "0")
+_cpack_set_default(CPACK_PACKAGE_VERSION_MINOR "1")
+_cpack_set_default(CPACK_PACKAGE_VERSION_PATCH "1")
+_cpack_set_default(CPACK_PACKAGE_VERSION
"${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
-cpack_set_if_not_set(CPACK_PACKAGE_VENDOR "Humanity")
-cpack_set_if_not_set(CPACK_PACKAGE_DESCRIPTION_SUMMARY
+_cpack_set_default(CPACK_PACKAGE_VENDOR "Humanity")
+_cpack_set_default(CPACK_PACKAGE_DESCRIPTION_SUMMARY
"${CMAKE_PROJECT_NAME} built using CMake")
-cpack_set_if_not_set(CPACK_PACKAGE_DESCRIPTION_FILE
+_cpack_set_default(CPACK_PACKAGE_DESCRIPTION_FILE
"${CMAKE_ROOT}/Templates/CPack.GenericDescription.txt")
-cpack_set_if_not_set(CPACK_RESOURCE_FILE_LICENSE
+_cpack_set_default(CPACK_RESOURCE_FILE_LICENSE
"${CMAKE_ROOT}/Templates/CPack.GenericLicense.txt")
-cpack_set_if_not_set(CPACK_RESOURCE_FILE_README
+_cpack_set_default(CPACK_RESOURCE_FILE_README
"${CMAKE_ROOT}/Templates/CPack.GenericDescription.txt")
-cpack_set_if_not_set(CPACK_RESOURCE_FILE_WELCOME
+_cpack_set_default(CPACK_RESOURCE_FILE_WELCOME
"${CMAKE_ROOT}/Templates/CPack.GenericWelcome.txt")
-cpack_set_if_not_set(CPACK_MODULE_PATH "${CMAKE_MODULE_PATH}")
+_cpack_set_default(CPACK_MODULE_PATH "${CMAKE_MODULE_PATH}")
if(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL)
set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
@@ -359,29 +382,34 @@ if(CPACK_NSIS_MODIFY_PATH)
endif()
set(__cpack_system_name ${CMAKE_SYSTEM_NAME})
-if(${__cpack_system_name} MATCHES Windows)
- if(CMAKE_CL_64)
+if(__cpack_system_name MATCHES "Windows")
+ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(__cpack_system_name win64)
else()
set(__cpack_system_name win32)
endif()
endif()
-cpack_set_if_not_set(CPACK_SYSTEM_NAME "${__cpack_system_name}")
+_cpack_set_default(CPACK_SYSTEM_NAME "${__cpack_system_name}")
# Root dir: default value should be the string literal "$PROGRAMFILES"
# for backwards compatibility. Projects may set this value to anything.
-set(__cpack_root_default "$PROGRAMFILES")
-cpack_set_if_not_set(CPACK_NSIS_INSTALL_ROOT "${__cpack_root_default}")
+# When creating 64 bit binaries we set the default value to "$PROGRAMFILES64"
+if("x${__cpack_system_name}" STREQUAL "xwin64")
+ set(__cpack_root_default "$PROGRAMFILES64")
+else()
+ set(__cpack_root_default "$PROGRAMFILES")
+endif()
+_cpack_set_default(CPACK_NSIS_INSTALL_ROOT "${__cpack_root_default}")
# <project>-<major>.<minor>.<patch>-<release>-<platform>.<pkgtype>
-cpack_set_if_not_set(CPACK_PACKAGE_FILE_NAME
+_cpack_set_default(CPACK_PACKAGE_FILE_NAME
"${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_SYSTEM_NAME}")
-cpack_set_if_not_set(CPACK_PACKAGE_INSTALL_DIRECTORY
+_cpack_set_default(CPACK_PACKAGE_INSTALL_DIRECTORY
"${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION}")
-cpack_set_if_not_set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY
+_cpack_set_default(CPACK_PACKAGE_INSTALL_REGISTRY_KEY
"${CPACK_PACKAGE_INSTALL_DIRECTORY}")
-cpack_set_if_not_set(CPACK_PACKAGE_DEFAULT_LOCATION "/")
-cpack_set_if_not_set(CPACK_PACKAGE_RELOCATABLE "true")
+_cpack_set_default(CPACK_PACKAGE_DEFAULT_LOCATION "/")
+_cpack_set_default(CPACK_PACKAGE_RELOCATABLE "true")
# always force to exactly "true" or "false" for CPack.Info.plist.in:
if(CPACK_PACKAGE_RELOCATABLE)
@@ -407,15 +435,16 @@ macro(cpack_optional_append _list _cond _item)
endif()
endmacro()
-##variable
-# CPACK_BINARY_<GENNAME> - CPack generated options for binary generators. The
-# CPack.cmake module generates (when CPACK_GENERATOR is not set)
-# a set of CMake options (see CMake option command) which may then be used to
-# select the CPack generator(s) to be used when launching the package target.
-##end
-# Provide options to choose generators
-# we might check here if the required tools for the generates exist
-# and set the defaults according to the results
+#.rst:
+# .. variable:: CPACK_BINARY_<GENNAME>
+#
+# CPack generated options for binary generators. The CPack.cmake module
+# generates (when CPACK_GENERATOR is not set) a set of CMake options (see
+# CMake option command) which may then be used to select the CPack
+# generator(s) to be used when launching the package target.
+#
+# Provide options to choose generators we might check here if the required
+# tools for the generates exist and set the defaults according to the results
if(NOT CPACK_GENERATOR)
if(UNIX)
if(CYGWIN)
@@ -424,35 +453,41 @@ if(NOT CPACK_GENERATOR)
if(APPLE)
option(CPACK_BINARY_BUNDLE "Enable to build OSX bundles" OFF)
option(CPACK_BINARY_DRAGNDROP "Enable to build OSX Drag And Drop package" OFF)
- option(CPACK_BINARY_PACKAGEMAKER "Enable to build PackageMaker packages" ON)
option(CPACK_BINARY_OSXX11 "Enable to build OSX X11 packages" OFF)
+ option(CPACK_BINARY_PACKAGEMAKER "Enable to build PackageMaker packages" OFF)
else()
option(CPACK_BINARY_TZ "Enable to build TZ packages" ON)
endif()
- option(CPACK_BINARY_STGZ "Enable to build STGZ packages" ON)
- option(CPACK_BINARY_TGZ "Enable to build TGZ packages" ON)
- option(CPACK_BINARY_TBZ2 "Enable to build TBZ2 packages" OFF)
option(CPACK_BINARY_DEB "Enable to build Debian packages" OFF)
- option(CPACK_BINARY_RPM "Enable to build RPM packages" OFF)
option(CPACK_BINARY_NSIS "Enable to build NSIS packages" OFF)
+ option(CPACK_BINARY_RPM "Enable to build RPM packages" OFF)
+ option(CPACK_BINARY_STGZ "Enable to build STGZ packages" ON)
+ option(CPACK_BINARY_TBZ2 "Enable to build TBZ2 packages" OFF)
+ option(CPACK_BINARY_TGZ "Enable to build TGZ packages" ON)
+ option(CPACK_BINARY_TXZ "Enable to build TXZ packages" OFF)
endif()
else()
+ option(CPACK_BINARY_7Z "Enable to build 7-Zip packages" OFF)
option(CPACK_BINARY_NSIS "Enable to build NSIS packages" ON)
option(CPACK_BINARY_WIX "Enable to build WiX packages" OFF)
option(CPACK_BINARY_ZIP "Enable to build ZIP packages" OFF)
endif()
+ option(CPACK_BINARY_IFW "Enable to build IFW packages" OFF)
+ cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_7Z 7Z)
cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_BUNDLE Bundle)
- cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_DRAGNDROP DragNDrop)
- cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_PACKAGEMAKER PackageMaker)
- cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_OSXX11 OSXX11)
cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_CYGWIN CygwinBinary)
cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_DEB DEB)
- cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_RPM RPM)
+ cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_DRAGNDROP DragNDrop)
+ cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_IFW IFW)
cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_NSIS NSIS)
+ cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_OSXX11 OSXX11)
+ cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_PACKAGEMAKER PackageMaker)
+ cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_RPM RPM)
cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_STGZ STGZ)
- cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_TGZ TGZ)
cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_TBZ2 TBZ2)
+ cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_TGZ TGZ)
+ cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_TXZ TXZ)
cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_TZ TZ)
cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_WIX WIX)
cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_ZIP ZIP)
@@ -467,33 +502,57 @@ if(NOT CPACK_SOURCE_GENERATOR)
else()
option(CPACK_SOURCE_TBZ2 "Enable to build TBZ2 source packages" ON)
option(CPACK_SOURCE_TGZ "Enable to build TGZ source packages" ON)
+ option(CPACK_SOURCE_TXZ "Enable to build TXZ source packages" ON)
option(CPACK_SOURCE_TZ "Enable to build TZ source packages" ON)
option(CPACK_SOURCE_ZIP "Enable to build ZIP source packages" OFF)
endif()
else()
+ option(CPACK_SOURCE_7Z "Enable to build 7-Zip source packages" ON)
option(CPACK_SOURCE_ZIP "Enable to build ZIP source packages" ON)
endif()
+ cpack_optional_append(CPACK_SOURCE_GENERATOR CPACK_SOURCE_7Z 7Z)
cpack_optional_append(CPACK_SOURCE_GENERATOR CPACK_SOURCE_CYGWIN CygwinSource)
- cpack_optional_append(CPACK_SOURCE_GENERATOR CPACK_SOURCE_TGZ TGZ)
cpack_optional_append(CPACK_SOURCE_GENERATOR CPACK_SOURCE_TBZ2 TBZ2)
+ cpack_optional_append(CPACK_SOURCE_GENERATOR CPACK_SOURCE_TGZ TGZ)
+ cpack_optional_append(CPACK_SOURCE_GENERATOR CPACK_SOURCE_TXZ TXZ)
cpack_optional_append(CPACK_SOURCE_GENERATOR CPACK_SOURCE_TZ TZ)
cpack_optional_append(CPACK_SOURCE_GENERATOR CPACK_SOURCE_ZIP ZIP)
endif()
# mark the above options as advanced
-mark_as_advanced(CPACK_BINARY_CYGWIN CPACK_BINARY_PACKAGEMAKER CPACK_BINARY_OSXX11
- CPACK_BINARY_STGZ CPACK_BINARY_TGZ CPACK_BINARY_TBZ2
- CPACK_BINARY_DEB CPACK_BINARY_RPM CPACK_BINARY_TZ
- CPACK_BINARY_NSIS CPACK_BINARY_WIX CPACK_BINARY_ZIP CPACK_BINARY_BUNDLE
- CPACK_SOURCE_CYGWIN CPACK_SOURCE_TBZ2 CPACK_SOURCE_TGZ
- CPACK_SOURCE_TZ CPACK_SOURCE_ZIP CPACK_BINARY_DRAGNDROP)
+mark_as_advanced(
+ CPACK_BINARY_7Z
+ CPACK_BINARY_BUNDLE
+ CPACK_BINARY_CYGWIN
+ CPACK_BINARY_DEB
+ CPACK_BINARY_DRAGNDROP
+ CPACK_BINARY_IFW
+ CPACK_BINARY_NSIS
+ CPACK_BINARY_OSXX11
+ CPACK_BINARY_PACKAGEMAKER
+ CPACK_BINARY_RPM
+ CPACK_BINARY_STGZ
+ CPACK_BINARY_TBZ2
+ CPACK_BINARY_TGZ
+ CPACK_BINARY_TXZ
+ CPACK_BINARY_TZ
+ CPACK_BINARY_WIX
+ CPACK_BINARY_ZIP
+ CPACK_SOURCE_7Z
+ CPACK_SOURCE_CYGWIN
+ CPACK_SOURCE_TBZ2
+ CPACK_SOURCE_TGZ
+ CPACK_SOURCE_TXZ
+ CPACK_SOURCE_TZ
+ CPACK_SOURCE_ZIP
+ )
# Set some other variables
-cpack_set_if_not_set(CPACK_INSTALL_CMAKE_PROJECTS
+_cpack_set_default(CPACK_INSTALL_CMAKE_PROJECTS
"${CMAKE_BINARY_DIR};${CMAKE_PROJECT_NAME};ALL;/")
-cpack_set_if_not_set(CPACK_CMAKE_GENERATOR "${CMAKE_GENERATOR}")
-cpack_set_if_not_set(CPACK_TOPLEVEL_TAG "${CPACK_SYSTEM_NAME}")
+_cpack_set_default(CPACK_CMAKE_GENERATOR "${CMAKE_GENERATOR}")
+_cpack_set_default(CPACK_TOPLEVEL_TAG "${CPACK_SYSTEM_NAME}")
# if the user has set CPACK_NSIS_DISPLAY_NAME remember it
if(DEFINED CPACK_NSIS_DISPLAY_NAME)
set(CPACK_NSIS_DISPLAY_NAME_SET TRUE)
@@ -502,30 +561,33 @@ endif()
# explicitly, then use that as the default
# value of CPACK_NSIS_PACKAGE_NAME instead
# of CPACK_PACKAGE_INSTALL_DIRECTORY
-cpack_set_if_not_set(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}")
+_cpack_set_default(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}")
if(CPACK_NSIS_DISPLAY_NAME_SET)
- string(REPLACE "\\" "\\\\"
- _NSIS_DISPLAY_NAME_TMP "${CPACK_NSIS_DISPLAY_NAME}")
- cpack_set_if_not_set(CPACK_NSIS_PACKAGE_NAME "${_NSIS_DISPLAY_NAME_TMP}")
+ _cpack_set_default(CPACK_NSIS_PACKAGE_NAME "${CPACK_NSIS_DISPLAY_NAME}")
else()
- cpack_set_if_not_set(CPACK_NSIS_PACKAGE_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}")
+ _cpack_set_default(CPACK_NSIS_PACKAGE_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}")
endif()
-cpack_set_if_not_set(CPACK_OUTPUT_CONFIG_FILE
+_cpack_set_default(CPACK_OUTPUT_CONFIG_FILE
"${CMAKE_BINARY_DIR}/CPackConfig.cmake")
-cpack_set_if_not_set(CPACK_SOURCE_OUTPUT_CONFIG_FILE
+_cpack_set_default(CPACK_SOURCE_OUTPUT_CONFIG_FILE
"${CMAKE_BINARY_DIR}/CPackSourceConfig.cmake")
-cpack_set_if_not_set(CPACK_SET_DESTDIR OFF)
-cpack_set_if_not_set(CPACK_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
+_cpack_set_default(CPACK_SET_DESTDIR OFF)
+_cpack_set_default(CPACK_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
-cpack_set_if_not_set(CPACK_NSIS_INSTALLER_ICON_CODE "")
-cpack_set_if_not_set(CPACK_NSIS_INSTALLER_MUI_ICON_CODE "")
+_cpack_set_default(CPACK_NSIS_INSTALLER_ICON_CODE "")
+_cpack_set_default(CPACK_NSIS_INSTALLER_MUI_ICON_CODE "")
# WiX specific variables
-cpack_set_if_not_set(CPACK_WIX_SIZEOF_VOID_P "${CMAKE_SIZEOF_VOID_P}")
+_cpack_set_default(CPACK_WIX_SIZEOF_VOID_P "${CMAKE_SIZEOF_VOID_P}")
+
+# set sysroot so SDK tools can be used
+if(CMAKE_OSX_SYSROOT)
+ _cpack_set_default(CPACK_OSX_SYSROOT "${_CMAKE_OSX_SYSROOT_PATH}")
+endif()
if(DEFINED CPACK_COMPONENTS_ALL)
if(CPACK_MONOLITHIC_INSTALL)
@@ -561,16 +623,23 @@ set(CPACK_COMPONENT_UNSPECIFIED_HIDDEN TRUE)
set(CPACK_COMPONENT_UNSPECIFIED_REQUIRED TRUE)
cpack_encode_variables()
-configure_file("${cpack_input_file}" "${CPACK_OUTPUT_CONFIG_FILE}" @ONLY IMMEDIATE)
+configure_file("${cpack_input_file}" "${CPACK_OUTPUT_CONFIG_FILE}" @ONLY)
# Generate source file
-cpack_set_if_not_set(CPACK_SOURCE_INSTALLED_DIRECTORIES
+_cpack_set_default(CPACK_SOURCE_INSTALLED_DIRECTORIES
"${CMAKE_SOURCE_DIR};/")
-cpack_set_if_not_set(CPACK_SOURCE_TOPLEVEL_TAG "${CPACK_SYSTEM_NAME}-Source")
-cpack_set_if_not_set(CPACK_SOURCE_PACKAGE_FILE_NAME
+_cpack_set_default(CPACK_SOURCE_TOPLEVEL_TAG "${CPACK_SYSTEM_NAME}-Source")
+_cpack_set_default(CPACK_SOURCE_PACKAGE_FILE_NAME
"${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-Source")
-cpack_set_if_not_set(CPACK_SOURCE_IGNORE_FILES
- "/CVS/;/\\\\\\\\.svn/;/\\\\\\\\.bzr/;/\\\\\\\\.hg/;/\\\\\\\\.git/;\\\\\\\\.swp$;\\\\\\\\.#;/#")
+
+set(__cpack_source_ignore_files_default
+ "/CVS/;/\\.svn/;/\\.bzr/;/\\.hg/;/\\.git/;\\.swp$;\\.#;/#")
+if(NOT CPACK_VERBATIM_VARIABLES)
+ _cpack_escape_for_cmake(__cpack_source_ignore_files_default
+ "${__cpack_source_ignore_files_default}")
+endif()
+_cpack_set_default(CPACK_SOURCE_IGNORE_FILES "${__cpack_source_ignore_files_default}")
+
set(CPACK_INSTALL_CMAKE_PROJECTS "${CPACK_SOURCE_INSTALL_CMAKE_PROJECTS}")
set(CPACK_INSTALLED_DIRECTORIES "${CPACK_SOURCE_INSTALLED_DIRECTORIES}")
set(CPACK_GENERATOR "${CPACK_SOURCE_GENERATOR}")
@@ -581,4 +650,4 @@ set(CPACK_STRIP_FILES "${CPACK_SOURCE_STRIP_FILES}")
cpack_encode_variables()
configure_file("${cpack_source_input_file}"
- "${CPACK_SOURCE_OUTPUT_CONFIG_FILE}" @ONLY IMMEDIATE)
+ "${CPACK_SOURCE_OUTPUT_CONFIG_FILE}" @ONLY)
diff --git a/Modules/CPackBundle.cmake b/Modules/CPackBundle.cmake
index 0da51e30b..b41221612 100644
--- a/Modules/CPackBundle.cmake
+++ b/Modules/CPackBundle.cmake
@@ -1,36 +1,68 @@
-##section Variables specific to CPack Bundle generator
-##end
-##module
-# - CPack Bundle generator (Mac OS X) specific options
+#.rst:
+# CPackBundle
+# -----------
+#
+# CPack Bundle generator (Mac OS X) specific options
+#
+# Variables specific to CPack Bundle generator
+# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#
# Installers built on Mac OS X using the Bundle generator use the
-# aforementioned DragNDrop (CPACK_DMG_xxx) variables, plus
-# the following Bundle-specific parameters (CPACK_BUNDLE_xxx).
-##end
-#
-##variable
-# CPACK_BUNDLE_NAME - The name of the generated bundle. This
-# appears in the OSX finder as the bundle name. Required.
-##end
-#
-##variable
-# CPACK_BUNDLE_PLIST - Path to an OSX plist file that will be used
-# for the generated bundle. This assumes that the caller has generated
-# or specified their own Info.plist file. Required.
-##end
-#
-##variable
-# CPACK_BUNDLE_ICON - Path to an OSX icon file that will be used as
-# the icon for the generated bundle. This is the icon that appears in the
-# OSX finder for the bundle, and in the OSX dock when the bundle is opened.
-# Required.
-##end
-#
-##variable
-# CPACK_BUNDLE_STARTUP_COMMAND - Path to a startup script. This is a path to
-# an executable or script that will be run whenever an end-user double-clicks
-# the generated bundle in the OSX Finder. Optional.
-##end
+# aforementioned DragNDrop (CPACK_DMG_xxx) variables, plus the following
+# Bundle-specific parameters (CPACK_BUNDLE_xxx).
+#
+# .. variable:: CPACK_BUNDLE_NAME
+#
+# The name of the generated bundle. This appears in the OSX finder as the
+# bundle name. Required.
+#
+# .. variable:: CPACK_BUNDLE_PLIST
+#
+# Path to an OSX plist file that will be used for the generated bundle. This
+# assumes that the caller has generated or specified their own Info.plist
+# file. Required.
+#
+# .. variable:: CPACK_BUNDLE_ICON
+#
+# Path to an OSX icon file that will be used as the icon for the generated
+# bundle. This is the icon that appears in the OSX finder for the bundle, and
+# in the OSX dock when the bundle is opened. Required.
+#
+# .. variable:: CPACK_BUNDLE_STARTUP_COMMAND
+#
+# Path to a startup script. This is a path to an executable or script that
+# will be run whenever an end-user double-clicks the generated bundle in the
+# OSX Finder. Optional.
+#
+# .. variable:: CPACK_BUNDLE_APPLE_CERT_APP
+#
+# The name of your Apple supplied code signing certificate for the application.
+# The name usually takes the form "Developer ID Application: [Name]" or
+# "3rd Party Mac Developer Application: [Name]". If this variable is not set
+# the application will not be signed.
+#
+# .. variable:: CPACK_BUNDLE_APPLE_ENTITLEMENTS
+#
+# The name of the plist file that contains your apple entitlements for sandboxing
+# your application. This file is required for submission to the Mac App Store.
+#
+# .. variable:: CPACK_BUNDLE_APPLE_CODESIGN_FILES
+#
+# A list of additional files that you wish to be signed. You do not need to
+# list the main application folder, or the main executable. You should
+# list any frameworks and plugins that are included in your app bundle.
+#
+# .. variable:: CPACK_BUNDLE_APPLE_CODESIGN_PARAMETER
+#
+# Additional parameter that will passed to codesign.
+# Default value: "--deep -f"
+#
+# .. variable:: CPACK_COMMAND_CODESIGN
+#
+# Path to the codesign(1) command used to sign applications with an
+# Apple cert. This variable can be used to override the automatically
+# detected command (or specify its location if the auto-detection fails
+# to find it.)
#=============================================================================
# Copyright 2006-2009 Kitware, Inc.
diff --git a/Modules/CPackComponent.cmake b/Modules/CPackComponent.cmake
index c85cfb454..96d5609ee 100644
--- a/Modules/CPackComponent.cmake
+++ b/Modules/CPackComponent.cmake
@@ -1,265 +1,288 @@
-##section Variables concerning CPack Components
-##end
-##module
-# - Build binary and source package installers
+#.rst:
+# CPackComponent
+# --------------
#
-# The CPackComponent module is the module which handles
-# the component part of CPack. See CPack module for
-# general information about CPack.
+# Build binary and source package installers
+#
+# Variables concerning CPack Components
+# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#
+# The CPackComponent module is the module which handles the component
+# part of CPack. See CPack module for general information about CPack.
#
# For certain kinds of binary installers (including the graphical
# installers on Mac OS X and Windows), CPack generates installers that
-# allow users to select individual application components to
-# install. The contents of each of the components are identified by
-# the COMPONENT argument of CMake's INSTALL command. These components
-# can be annotated with user-friendly names and descriptions,
-# inter-component dependencies, etc., and grouped in various ways to
-# customize the resulting installer. See the cpack_add_* commands,
-# described below, for more information about component-specific
-# installations.
+# allow users to select individual application components to install.
+# The contents of each of the components are identified by the COMPONENT
+# argument of CMake's INSTALL command. These components can be
+# annotated with user-friendly names and descriptions, inter-component
+# dependencies, etc., and grouped in various ways to customize the
+# resulting installer. See the cpack_add_* commands, described below,
+# for more information about component-specific installations.
#
# Component-specific installation allows users to select specific sets
-# of components to install during the install process. Installation
-# components are identified by the COMPONENT argument of CMake's
-# INSTALL commands, and should be further described by the following
-# CPack commands:
-##end
-#
-##variable
-# CPACK_COMPONENTS_ALL - The list of component to install.
-#
-#The default value of this variable is computed by CPack
-#and contains all components defined by the project. The
-#user may set it to only include the specified components.
-##end
-#
-##variable
-# CPACK_<GENNAME>_COMPONENT_INSTALL - Enable/Disable component install for
-# CPack generator <GENNAME>.
-#
-#Each CPack Generator (RPM, DEB, ARCHIVE, NSIS, DMG, etc...) has a legacy
-#default behavior. e.g. RPM builds monolithic whereas NSIS builds component.
-#One can change the default behavior by setting this variable to 0/1 or OFF/ON.
-##end
-##variable
-# CPACK_COMPONENTS_GROUPING - Specify how components are grouped for multi-package
-# component-aware CPack generators.
-#
-#Some generators like RPM or ARCHIVE family (TGZ, ZIP, ...) generates several
-#packages files when asked for component packaging. They group the component
-#differently depending on the value of this variable:
-# - ONE_PER_GROUP (default): creates one package file per component group
-# - ALL_COMPONENTS_IN_ONE : creates a single package with all (requested) component
-# - IGNORE : creates one package per component, i.e. IGNORE component group
-#One can specify different grouping for different CPack generator by using
-#a CPACK_PROJECT_CONFIG_FILE.
-##end
-##variable
-# CPACK_COMPONENT_<compName>_DISPLAY_NAME - The name to be displayed for a component.
-##end
-##variable
-# CPACK_COMPONENT_<compName>_DESCRIPTION - The description of a component.
-##end
-##variable
-# CPACK_COMPONENT_<compName>_GROUP - The group of a component.
-##end
-##variable
-# CPACK_COMPONENT_<compName>_DEPENDS - The dependencies (list of components)
-# on which this component depends.
-##end
-##variable
-# CPACK_COMPONENT_<compName>_REQUIRED - True is this component is required.
-##end
-##macro
-#cpack_add_component - Describes a CPack installation component
-#named by the COMPONENT argument to a CMake INSTALL command.
-#
-# cpack_add_component(compname
-# [DISPLAY_NAME name]
-# [DESCRIPTION description]
-# [HIDDEN | REQUIRED | DISABLED ]
-# [GROUP group]
-# [DEPENDS comp1 comp2 ... ]
-# [INSTALL_TYPES type1 type2 ... ]
-# [DOWNLOADED]
-# [ARCHIVE_FILE filename])
-#
-#The cmake_add_component command describes an installation
-#component, which the user can opt to install or remove as part of
-#the graphical installation process. compname is the name of the
-#component, as provided to the COMPONENT argument of one or more
-#CMake INSTALL commands.
-#
-#DISPLAY_NAME is the displayed name of the component, used in
-#graphical installers to display the component name. This value can
-#be any string.
-#
-#DESCRIPTION is an extended description of the component, used in
-#graphical installers to give the user additional information about
-#the component. Descriptions can span multiple lines using "\n" as
-#the line separator. Typically, these descriptions should be no
-#more than a few lines long.
-#
-#HIDDEN indicates that this component will be hidden in the
-#graphical installer, so that the user cannot directly change
-#whether it is installed or not.
-#
-#REQUIRED indicates that this component is required, and therefore
-#will always be installed. It will be visible in the graphical
-#installer, but it cannot be unselected. (Typically, required
-#components are shown greyed out).
-#
-#DISABLED indicates that this component should be disabled
-#(unselected) by default. The user is free to select this component
-#for installation, unless it is also HIDDEN.
-#
-#DEPENDS lists the components on which this component depends. If
-#this component is selected, then each of the components listed
-#must also be selected. The dependency information is encoded
-#within the installer itself, so that users cannot install
-#inconsistent sets of components.
-#
-#GROUP names the component group of which this component is a
-#part. If not provided, the component will be a standalone
-#component, not part of any component group. Component groups are
-#described with the cpack_add_component_group command, detailed
-#below.
-#
-#INSTALL_TYPES lists the installation types of which this component
-#is a part. When one of these installations types is selected, this
-#component will automatically be selected. Installation types are
-#described with the cpack_add_install_type command, detailed below.
-#
-#DOWNLOADED indicates that this component should be downloaded
-#on-the-fly by the installer, rather than packaged in with the
-#installer itself. For more information, see the cpack_configure_downloads
-# command.
-#
-#ARCHIVE_FILE provides a name for the archive file created by CPack
-#to be used for downloaded components. If not supplied, CPack will
-#create a file with some name based on CPACK_PACKAGE_FILE_NAME and
-#the name of the component. See cpack_configure_downloads for more
-#information.
-##end
-#
-##macro
-#cpack_add_component_group - Describes a group of related CPack
-#installation components.
-#
-# cpack_add_component_group(groupname
-# [DISPLAY_NAME name]
-# [DESCRIPTION description]
-# [PARENT_GROUP parent]
-# [EXPANDED]
-# [BOLD_TITLE])
-#
-#The cpack_add_component_group describes a group of installation
-#components, which will be placed together within the listing of
-#options. Typically, component groups allow the user to
-#select/deselect all of the components within a single group via a
-#single group-level option. Use component groups to reduce the
-#complexity of installers with many options. groupname is an
-#arbitrary name used to identify the group in the GROUP argument of
-#the cpack_add_component command, which is used to place a
-#component in a group. The name of the group must not conflict with
-#the name of any component.
-#
-#DISPLAY_NAME is the displayed name of the component group, used in
-#graphical installers to display the component group name. This
-#value can be any string.
-#
-#DESCRIPTION is an extended description of the component group,
-#used in graphical installers to give the user additional
-#information about the components within that group. Descriptions
-#can span multiple lines using "\n" as the line
-#separator. Typically, these descriptions should be no more than a
-#few lines long.
-#
-#PARENT_GROUP, if supplied, names the parent group of this group.
-#Parent groups are used to establish a hierarchy of groups,
-#providing an arbitrary hierarchy of groups.
-#
-#EXPANDED indicates that, by default, the group should show up as
-#"expanded", so that the user immediately sees all of the
-#components within the group. Otherwise, the group will initially
-#show up as a single entry.
-#
-#BOLD_TITLE indicates that the group title should appear in bold,
-#to call the user's attention to the group.
-##end
-#
-##macro
-#cpack_add_install_type - Add a new installation type containing a
-#set of predefined component selections to the graphical installer.
-#
-# cpack_add_install_type(typename
-# [DISPLAY_NAME name])
-#
-#The cpack_add_install_type command identifies a set of preselected
-#components that represents a common use case for an
-#application. For example, a "Developer" install type might include
-#an application along with its header and library files, while an
-#"End user" install type might just include the application's
-#executable. Each component identifies itself with one or more
-#install types via the INSTALL_TYPES argument to
-#cpack_add_component.
-#
-#DISPLAY_NAME is the displayed name of the install type, which will
-#typically show up in a drop-down box within a graphical
-#installer. This value can be any string.
-##end
-#
-##macro
-#cpack_configure_downloads - Configure CPack to download selected
-#components on-the-fly as part of the installation process.
-#
-# cpack_configure_downloads(site
-# [UPLOAD_DIRECTORY dirname]
-# [ALL]
-# [ADD_REMOVE|NO_ADD_REMOVE])
-#
-#The cpack_configure_downloads command configures installation-time
-#downloads of selected components. For each downloadable component,
-#CPack will create an archive containing the contents of that
-#component, which should be uploaded to the given site. When the
-#user selects that component for installation, the installer will
-#download and extract the component in place. This feature is
-#useful for creating small installers that only download the
-#requested components, saving bandwidth. Additionally, the
-#installers are small enough that they will be installed as part of
-#the normal installation process, and the "Change" button in
-#Windows Add/Remove Programs control panel will allow one to add or
-#remove parts of the application after the original
-#installation. On Windows, the downloaded-components functionality
-#requires the ZipDLL plug-in for NSIS, available at:
-#
-# http://nsis.sourceforge.net/ZipDLL_plug-in
-#
-#On Mac OS X, installers that download components on-the-fly can
-#only be built and installed on system using Mac OS X 10.5 or
-#later.
-#
-#The site argument is a URL where the archives for downloadable
-#components will reside, e.g., http://www.cmake.org/files/2.6.1/installer/
-#All of the archives produced by CPack should be uploaded to that location.
-#
-#UPLOAD_DIRECTORY is the local directory where CPack will create the
-#various archives for each of the components. The contents of this
-#directory should be uploaded to a location accessible by the URL given
-#in the site argument. If omitted, CPack will use the directory
-#CPackUploads inside the CMake binary directory to store the generated
-#archives.
-#
-#The ALL flag indicates that all components be downloaded. Otherwise, only
-#those components explicitly marked as DOWNLOADED or that have a specified
-#ARCHIVE_FILE will be downloaded. Additionally, the ALL option implies
-#ADD_REMOVE (unless NO_ADD_REMOVE is specified).
-#
-#ADD_REMOVE indicates that CPack should install a copy of the installer
-#that can be called from Windows' Add/Remove Programs dialog (via the
-#"Modify" button) to change the set of installed components. NO_ADD_REMOVE
-#turns off this behavior. This option is ignored on Mac OS X.
-##endmacro
+# of components to install during the install process. Installation
+# components are identified by the COMPONENT argument of CMake's INSTALL
+# commands, and should be further described by the following CPack
+# commands:
+#
+# .. variable:: CPACK_COMPONENTS_ALL
+#
+# The list of component to install.
+#
+# The default value of this variable is computed by CPack and contains all
+# components defined by the project. The user may set it to only include the
+# specified components.
+#
+# .. variable:: CPACK_<GENNAME>_COMPONENT_INSTALL
+#
+# Enable/Disable component install for CPack generator <GENNAME>.
+#
+# Each CPack Generator (RPM, DEB, ARCHIVE, NSIS, DMG, etc...) has a legacy
+# default behavior. e.g. RPM builds monolithic whereas NSIS builds
+# component. One can change the default behavior by setting this variable to
+# 0/1 or OFF/ON.
+#
+# .. variable:: CPACK_COMPONENTS_GROUPING
+#
+# Specify how components are grouped for multi-package component-aware CPack
+# generators.
+#
+# Some generators like RPM or ARCHIVE family (TGZ, ZIP, ...) generates
+# several packages files when asked for component packaging. They group
+# the component differently depending on the value of this variable:
+#
+# * ONE_PER_GROUP (default): creates one package file per component group
+# * ALL_COMPONENTS_IN_ONE : creates a single package with all (requested) component
+# * IGNORE : creates one package per component, i.e. IGNORE component group
+#
+# One can specify different grouping for different CPack generator by
+# using a CPACK_PROJECT_CONFIG_FILE.
+#
+# .. variable:: CPACK_COMPONENT_<compName>_DISPLAY_NAME
+#
+# The name to be displayed for a component.
+#
+# .. variable:: CPACK_COMPONENT_<compName>_DESCRIPTION
+#
+# The description of a component.
+#
+# .. variable:: CPACK_COMPONENT_<compName>_GROUP
+#
+# The group of a component.
+#
+# .. variable:: CPACK_COMPONENT_<compName>_DEPENDS
+#
+# The dependencies (list of components) on which this component depends.
+#
+# .. variable:: CPACK_COMPONENT_<compName>_REQUIRED
+#
+# True is this component is required.
+#
+# .. command:: cpack_add_component
+#
+# Describes a CPack installation
+# component named by the COMPONENT argument to a CMake INSTALL command.
+#
+# ::
+#
+# cpack_add_component(compname
+# [DISPLAY_NAME name]
+# [DESCRIPTION description]
+# [HIDDEN | REQUIRED | DISABLED ]
+# [GROUP group]
+# [DEPENDS comp1 comp2 ... ]
+# [INSTALL_TYPES type1 type2 ... ]
+# [DOWNLOADED]
+# [ARCHIVE_FILE filename])
+#
+#
+#
+# The cmake_add_component command describes an installation component,
+# which the user can opt to install or remove as part of the graphical
+# installation process. compname is the name of the component, as
+# provided to the COMPONENT argument of one or more CMake INSTALL
+# commands.
+#
+# DISPLAY_NAME is the displayed name of the component, used in graphical
+# installers to display the component name. This value can be any
+# string.
+#
+# DESCRIPTION is an extended description of the component, used in
+# graphical installers to give the user additional information about the
+# component. Descriptions can span multiple lines using ``\n`` as the
+# line separator. Typically, these descriptions should be no more than
+# a few lines long.
+#
+# HIDDEN indicates that this component will be hidden in the graphical
+# installer, so that the user cannot directly change whether it is
+# installed or not.
+#
+# REQUIRED indicates that this component is required, and therefore will
+# always be installed. It will be visible in the graphical installer,
+# but it cannot be unselected. (Typically, required components are
+# shown greyed out).
+#
+# DISABLED indicates that this component should be disabled (unselected)
+# by default. The user is free to select this component for
+# installation, unless it is also HIDDEN.
+#
+# DEPENDS lists the components on which this component depends. If this
+# component is selected, then each of the components listed must also be
+# selected. The dependency information is encoded within the installer
+# itself, so that users cannot install inconsistent sets of components.
+#
+# GROUP names the component group of which this component is a part. If
+# not provided, the component will be a standalone component, not part
+# of any component group. Component groups are described with the
+# cpack_add_component_group command, detailed below.
+#
+# INSTALL_TYPES lists the installation types of which this component is
+# a part. When one of these installations types is selected, this
+# component will automatically be selected. Installation types are
+# described with the cpack_add_install_type command, detailed below.
+#
+# DOWNLOADED indicates that this component should be downloaded
+# on-the-fly by the installer, rather than packaged in with the
+# installer itself. For more information, see the
+# cpack_configure_downloads command.
+#
+# ARCHIVE_FILE provides a name for the archive file created by CPack to
+# be used for downloaded components. If not supplied, CPack will create
+# a file with some name based on CPACK_PACKAGE_FILE_NAME and the name of
+# the component. See cpack_configure_downloads for more information.
+#
+# .. command:: cpack_add_component_group
+#
+# Describes a group of related CPack installation components.
+#
+# ::
+#
+# cpack_add_component_group(groupname
+# [DISPLAY_NAME name]
+# [DESCRIPTION description]
+# [PARENT_GROUP parent]
+# [EXPANDED]
+# [BOLD_TITLE])
+#
+#
+#
+# The cpack_add_component_group describes a group of installation
+# components, which will be placed together within the listing of
+# options. Typically, component groups allow the user to
+# select/deselect all of the components within a single group via a
+# single group-level option. Use component groups to reduce the
+# complexity of installers with many options. groupname is an arbitrary
+# name used to identify the group in the GROUP argument of the
+# cpack_add_component command, which is used to place a component in a
+# group. The name of the group must not conflict with the name of any
+# component.
+#
+# DISPLAY_NAME is the displayed name of the component group, used in
+# graphical installers to display the component group name. This value
+# can be any string.
+#
+# DESCRIPTION is an extended description of the component group, used in
+# graphical installers to give the user additional information about the
+# components within that group. Descriptions can span multiple lines
+# using ``\n`` as the line separator. Typically, these descriptions
+# should be no more than a few lines long.
+#
+# PARENT_GROUP, if supplied, names the parent group of this group.
+# Parent groups are used to establish a hierarchy of groups, providing
+# an arbitrary hierarchy of groups.
+#
+# EXPANDED indicates that, by default, the group should show up as
+# "expanded", so that the user immediately sees all of the components
+# within the group. Otherwise, the group will initially show up as a
+# single entry.
+#
+# BOLD_TITLE indicates that the group title should appear in bold, to
+# call the user's attention to the group.
+#
+# .. command:: cpack_add_install_type
+#
+# Add a new installation type containing
+# a set of predefined component selections to the graphical installer.
+#
+# ::
+#
+# cpack_add_install_type(typename
+# [DISPLAY_NAME name])
+#
+#
+#
+# The cpack_add_install_type command identifies a set of preselected
+# components that represents a common use case for an application. For
+# example, a "Developer" install type might include an application along
+# with its header and library files, while an "End user" install type
+# might just include the application's executable. Each component
+# identifies itself with one or more install types via the INSTALL_TYPES
+# argument to cpack_add_component.
+#
+# DISPLAY_NAME is the displayed name of the install type, which will
+# typically show up in a drop-down box within a graphical installer.
+# This value can be any string.
+#
+# .. command:: cpack_configure_downloads
+#
+# Configure CPack to download
+# selected components on-the-fly as part of the installation process.
+#
+# ::
+#
+# cpack_configure_downloads(site
+# [UPLOAD_DIRECTORY dirname]
+# [ALL]
+# [ADD_REMOVE|NO_ADD_REMOVE])
+#
+#
+#
+# The cpack_configure_downloads command configures installation-time
+# downloads of selected components. For each downloadable component,
+# CPack will create an archive containing the contents of that
+# component, which should be uploaded to the given site. When the user
+# selects that component for installation, the installer will download
+# and extract the component in place. This feature is useful for
+# creating small installers that only download the requested components,
+# saving bandwidth. Additionally, the installers are small enough that
+# they will be installed as part of the normal installation process, and
+# the "Change" button in Windows Add/Remove Programs control panel will
+# allow one to add or remove parts of the application after the original
+# installation. On Windows, the downloaded-components functionality
+# requires the ZipDLL plug-in for NSIS, available at:
+#
+# ::
+#
+# http://nsis.sourceforge.net/ZipDLL_plug-in
+#
+#
+#
+# On Mac OS X, installers that download components on-the-fly can only
+# be built and installed on system using Mac OS X 10.5 or later.
+#
+# The site argument is a URL where the archives for downloadable
+# components will reside, e.g.,
+# https://cmake.org/files/2.6.1/installer/ All of the archives
+# produced by CPack should be uploaded to that location.
+#
+# UPLOAD_DIRECTORY is the local directory where CPack will create the
+# various archives for each of the components. The contents of this
+# directory should be uploaded to a location accessible by the URL given
+# in the site argument. If omitted, CPack will use the directory
+# CPackUploads inside the CMake binary directory to store the generated
+# archives.
+#
+# The ALL flag indicates that all components be downloaded. Otherwise,
+# only those components explicitly marked as DOWNLOADED or that have a
+# specified ARCHIVE_FILE will be downloaded. Additionally, the ALL
+# option implies ADD_REMOVE (unless NO_ADD_REMOVE is specified).
+#
+# ADD_REMOVE indicates that CPack should install a copy of the installer
+# that can be called from Windows' Add/Remove Programs dialog (via the
+# "Modify" button) to change the set of installed components.
+# NO_ADD_REMOVE turns off this behavior. This option is ignored on Mac
+# OS X.
#=============================================================================
# Copyright 2006-2009 Kitware, Inc.
@@ -278,7 +301,7 @@
if(NOT CPackComponent_CMake_INCLUDED)
set(CPackComponent_CMake_INCLUDED 1)
-# Argument-parsing macro from http://www.cmake.org/Wiki/CMakeMacroParseArguments
+# Argument-parsing macro from https://cmake.org/Wiki/CMakeMacroParseArguments
macro(cpack_parse_arguments prefix arg_names option_names)
set(${prefix}_DEFAULT_ARGS)
foreach(arg_name ${arg_names})
@@ -352,17 +375,17 @@ endmacro()
# Macro that adds a component to the CPack installer
macro(cpack_add_component compname)
- string(TOUPPER ${compname} CPACK_ADDCOMP_UNAME)
- cpack_parse_arguments(CPACK_COMPONENT_${CPACK_ADDCOMP_UNAME}
+ string(TOUPPER ${compname} _CPACK_ADDCOMP_UNAME)
+ cpack_parse_arguments(CPACK_COMPONENT_${_CPACK_ADDCOMP_UNAME}
"DISPLAY_NAME;DESCRIPTION;GROUP;DEPENDS;INSTALL_TYPES;ARCHIVE_FILE"
"HIDDEN;REQUIRED;DISABLED;DOWNLOADED"
${ARGN}
)
- if (CPACK_COMPONENT_${CPACK_ADDCOMP_UNAME}_DOWNLOADED)
- set(CPACK_ADDCOMP_STR "\n# Configuration for downloaded component \"${compname}\"\n")
+ if (CPACK_COMPONENT_${_CPACK_ADDCOMP_UNAME}_DOWNLOADED)
+ set(_CPACK_ADDCOMP_STR "\n# Configuration for downloaded component \"${compname}\"\n")
else ()
- set(CPACK_ADDCOMP_STR "\n# Configuration for component \"${compname}\"\n")
+ set(_CPACK_ADDCOMP_STR "\n# Configuration for component \"${compname}\"\n")
endif ()
if(NOT CPACK_MONOLITHIC_INSTALL)
@@ -371,51 +394,51 @@ macro(cpack_add_component compname)
# take care of any components that have been added after the CPack
# moduled was included.
if(NOT CPACK_COMPONENTS_ALL_SET_BY_USER)
- get_cmake_property(CPACK_ADDCOMP_COMPONENTS COMPONENTS)
- set(CPACK_ADDCOMP_STR "${CPACK_ADDCOMP_STR}\nSET(CPACK_COMPONENTS_ALL")
- foreach(COMP ${CPACK_ADDCOMP_COMPONENTS})
- set(CPACK_ADDCOMP_STR "${CPACK_ADDCOMP_STR} ${COMP}")
+ get_cmake_property(_CPACK_ADDCOMP_COMPONENTS COMPONENTS)
+ set(_CPACK_ADDCOMP_STR "${_CPACK_ADDCOMP_STR}\nSET(CPACK_COMPONENTS_ALL")
+ foreach(COMP ${_CPACK_ADDCOMP_COMPONENTS})
+ set(_CPACK_ADDCOMP_STR "${_CPACK_ADDCOMP_STR} ${COMP}")
endforeach()
- set(CPACK_ADDCOMP_STR "${CPACK_ADDCOMP_STR})\n")
+ set(_CPACK_ADDCOMP_STR "${_CPACK_ADDCOMP_STR})\n")
endif()
endif()
cpack_append_string_variable_set_command(
- CPACK_COMPONENT_${CPACK_ADDCOMP_UNAME}_DISPLAY_NAME
- CPACK_ADDCOMP_STR)
+ CPACK_COMPONENT_${_CPACK_ADDCOMP_UNAME}_DISPLAY_NAME
+ _CPACK_ADDCOMP_STR)
cpack_append_string_variable_set_command(
- CPACK_COMPONENT_${CPACK_ADDCOMP_UNAME}_DESCRIPTION
- CPACK_ADDCOMP_STR)
+ CPACK_COMPONENT_${_CPACK_ADDCOMP_UNAME}_DESCRIPTION
+ _CPACK_ADDCOMP_STR)
cpack_append_variable_set_command(
- CPACK_COMPONENT_${CPACK_ADDCOMP_UNAME}_GROUP
- CPACK_ADDCOMP_STR)
+ CPACK_COMPONENT_${_CPACK_ADDCOMP_UNAME}_GROUP
+ _CPACK_ADDCOMP_STR)
cpack_append_variable_set_command(
- CPACK_COMPONENT_${CPACK_ADDCOMP_UNAME}_DEPENDS
- CPACK_ADDCOMP_STR)
+ CPACK_COMPONENT_${_CPACK_ADDCOMP_UNAME}_DEPENDS
+ _CPACK_ADDCOMP_STR)
cpack_append_variable_set_command(
- CPACK_COMPONENT_${CPACK_ADDCOMP_UNAME}_INSTALL_TYPES
- CPACK_ADDCOMP_STR)
+ CPACK_COMPONENT_${_CPACK_ADDCOMP_UNAME}_INSTALL_TYPES
+ _CPACK_ADDCOMP_STR)
cpack_append_string_variable_set_command(
- CPACK_COMPONENT_${CPACK_ADDCOMP_UNAME}_ARCHIVE_FILE
- CPACK_ADDCOMP_STR)
+ CPACK_COMPONENT_${_CPACK_ADDCOMP_UNAME}_ARCHIVE_FILE
+ _CPACK_ADDCOMP_STR)
cpack_append_option_set_command(
- CPACK_COMPONENT_${CPACK_ADDCOMP_UNAME}_HIDDEN
- CPACK_ADDCOMP_STR)
+ CPACK_COMPONENT_${_CPACK_ADDCOMP_UNAME}_HIDDEN
+ _CPACK_ADDCOMP_STR)
cpack_append_option_set_command(
- CPACK_COMPONENT_${CPACK_ADDCOMP_UNAME}_REQUIRED
- CPACK_ADDCOMP_STR)
+ CPACK_COMPONENT_${_CPACK_ADDCOMP_UNAME}_REQUIRED
+ _CPACK_ADDCOMP_STR)
cpack_append_option_set_command(
- CPACK_COMPONENT_${CPACK_ADDCOMP_UNAME}_DISABLED
- CPACK_ADDCOMP_STR)
+ CPACK_COMPONENT_${_CPACK_ADDCOMP_UNAME}_DISABLED
+ _CPACK_ADDCOMP_STR)
cpack_append_option_set_command(
- CPACK_COMPONENT_${CPACK_ADDCOMP_UNAME}_DOWNLOADED
- CPACK_ADDCOMP_STR)
+ CPACK_COMPONENT_${_CPACK_ADDCOMP_UNAME}_DOWNLOADED
+ _CPACK_ADDCOMP_STR)
# Backward compatibility issue.
# Write to config iff the macros is used after CPack.cmake has been
# included, other it's not necessary because the variables
# will be encoded by cpack_encode_variables.
if(CPack_CMake_INCLUDED)
- file(APPEND "${CPACK_OUTPUT_CONFIG_FILE}" "${CPACK_ADDCOMP_STR}")
+ file(APPEND "${CPACK_OUTPUT_CONFIG_FILE}" "${_CPACK_ADDCOMP_STR}")
endif()
endmacro()
@@ -423,7 +446,7 @@ endmacro()
macro(cpack_add_component_group grpname)
string(TOUPPER ${grpname} CPACK_ADDGRP_UNAME)
cpack_parse_arguments(CPACK_COMPONENT_GROUP_${CPACK_ADDGRP_UNAME}
- "DISPLAY_NAME;DESCRIPTION"
+ "DISPLAY_NAME;DESCRIPTION;PARENT_GROUP"
"EXPANDED;BOLD_TITLE"
${ARGN}
)
@@ -435,6 +458,9 @@ macro(cpack_add_component_group grpname)
cpack_append_string_variable_set_command(
CPACK_COMPONENT_GROUP_${CPACK_ADDGRP_UNAME}_DESCRIPTION
CPACK_ADDGRP_STR)
+ cpack_append_string_variable_set_command(
+ CPACK_COMPONENT_GROUP_${CPACK_ADDGRP_UNAME}_PARENT_GROUP
+ CPACK_ADDGRP_STR)
cpack_append_option_set_command(
CPACK_COMPONENT_GROUP_${CPACK_ADDGRP_UNAME}_EXPANDED
CPACK_ADDGRP_STR)
diff --git a/Modules/CPackCygwin.cmake b/Modules/CPackCygwin.cmake
index 7ed7f678b..abfc1f619 100644
--- a/Modules/CPackCygwin.cmake
+++ b/Modules/CPackCygwin.cmake
@@ -1,23 +1,27 @@
-##section Variables specific to CPack Cygwin generator
-##end
-##module
-# - Cygwin CPack generator (Cygwin).
-# The following variable is specific to installers build on
-# and/or for Cygwin:
-##end
-#
-##variable
-# CPACK_CYGWIN_PATCH_NUMBER - The Cygwin patch number.
-# FIXME: This documentation is incomplete.
-##end
-##variable
-# CPACK_CYGWIN_PATCH_FILE - The Cygwin patch file.
-# FIXME: This documentation is incomplete.
-##end
-##variable
-# CPACK_CYGWIN_BUILD_SCRIPT - The Cygwin build script.
-# FIXME: This documentation is incomplete.
-##end
+#.rst:
+# CPackCygwin
+# -----------
+#
+# Cygwin CPack generator (Cygwin).
+#
+# Variables specific to CPack Cygwin generator
+# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#
+# The
+# following variable is specific to installers build on and/or for
+# Cygwin:
+#
+# .. variable:: CPACK_CYGWIN_PATCH_NUMBER
+#
+# The Cygwin patch number. FIXME: This documentation is incomplete.
+#
+# .. variable:: CPACK_CYGWIN_PATCH_FILE
+#
+# The Cygwin patch file. FIXME: This documentation is incomplete.
+#
+# .. variable:: CPACK_CYGWIN_BUILD_SCRIPT
+#
+# The Cygwin build script. FIXME: This documentation is incomplete.
#=============================================================================
# Copyright 2006-2012 Kitware, Inc.
diff --git a/Modules/CPackDMG.cmake b/Modules/CPackDMG.cmake
index e866bab80..e34f8cd1a 100644
--- a/Modules/CPackDMG.cmake
+++ b/Modules/CPackDMG.cmake
@@ -1,60 +1,100 @@
-##section Variables specific to CPack DragNDrop generator
-##end
-##module
-# - DragNDrop CPack generator (Mac OS X).
-# The following variables are specific to the DragNDrop installers
-# built on Mac OS X:
-##end
-#
-##variable
-# CPACK_DMG_VOLUME_NAME - The volume name of the generated disk
-# image. Defaults to CPACK_PACKAGE_FILE_NAME.
-##end
-#
-##variable
-# CPACK_DMG_FORMAT - The disk image format. Common values are UDRO
-# (UDIF read-only), UDZO (UDIF zlib-compressed) or UDBZ (UDIF
-# bzip2-compressed). Refer to hdiutil(1) for more information on
-# other available formats.
-##end
-#
-##variable
-# CPACK_DMG_DS_STORE - Path to a custom DS_Store file. This .DS_Store
-# file e.g. can be used to specify the Finder window
-# position/geometry and layout (such as hidden toolbars, placement of the
-# icons etc.). This file has to be generated by the Finder (either manually or
-# through OSA-script) using a normal folder from which the .DS_Store
-# file can then be extracted.
-##end
-#
-##variable
-# CPACK_DMG_BACKGROUND_IMAGE - Path to a background image file. This
-# file will be used as the background for the Finder Window when the disk
-# image is opened. By default no background image is set. The background
-# image is applied after applying the custom .DS_Store file.
-##end
-#
-##variable
-# CPACK_COMMAND_HDIUTIL - Path to the hdiutil(1) command used to
-# operate on disk image files on Mac OS X. This variable can be used
-# to override the automatically detected command (or specify its
-# location if the auto-detection fails to find it.)
-##end
-#
-##variable
-# CPACK_COMMAND_SETFILE - Path to the SetFile(1) command used to set
-# extended attributes on files and directories on Mac OS X. This
-# variable can be used to override the automatically detected
-# command (or specify its location if the auto-detection fails to
-# find it.)
-##end
-#
-##variable
-# CPACK_COMMAND_REZ - Path to the Rez(1) command used to compile
-# resources on Mac OS X. This variable can be used to override the
+#.rst:
+# CPackDMG
+# --------
+#
+# DragNDrop CPack generator (Mac OS X).
+#
+# Variables specific to CPack DragNDrop generator
+# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#
+# The following variables are specific to the DragNDrop installers built
+# on Mac OS X:
+#
+# .. variable:: CPACK_DMG_VOLUME_NAME
+#
+# The volume name of the generated disk image. Defaults to
+# CPACK_PACKAGE_FILE_NAME.
+#
+# .. variable:: CPACK_DMG_FORMAT
+#
+# The disk image format. Common values are UDRO (UDIF read-only), UDZO (UDIF
+# zlib-compressed) or UDBZ (UDIF bzip2-compressed). Refer to hdiutil(1) for
+# more information on other available formats.
+#
+# .. variable:: CPACK_DMG_DS_STORE
+#
+# Path to a custom DS_Store file. This .DS_Store file e.g. can be used to
+# specify the Finder window position/geometry and layout (such as hidden
+# toolbars, placement of the icons etc.). This file has to be generated by
+# the Finder (either manually or through AppleScript) using a normal folder
+# from which the .DS_Store file can then be extracted.
+#
+# .. variable:: CPACK_DMG_DS_STORE_SETUP_SCRIPT
+#
+# Path to a custom AppleScript file. This AppleScript is used to generate
+# a .DS_Store file which specifies the Finder window position/geometry and
+# layout (such as hidden toolbars, placement of the icons etc.).
+# By specifying a custom AppleScript there is no need to use
+# CPACK_DMG_DS_STORE, as the .DS_Store that is generated by the AppleScript
+# will be packaged.
+#
+# .. variable:: CPACK_DMG_BACKGROUND_IMAGE
+#
+# Path to an image file to be used as the background. This file will be
+# copied to .background/background.<ext>, where ext is the original image file
+# extension. The background image is installed into the image before
+# CPACK_DMG_DS_STORE_SETUP_SCRIPT is executed or CPACK_DMG_DS_STORE is
+# installed. By default no background image is set.
+#
+# .. variable:: CPACK_DMG_SLA_DIR
+#
+# Directory where license and menu files for different languages are stored.
+# Setting this causes CPack to look for a ``<language>.menu.txt`` and
+# ``<language>.license.txt`` file for every language defined in
+# ``CPACK_DMG_SLA_LANGUAGES``. If both this variable and
+# ``CPACK_RESOURCE_FILE_LICENSE`` are set, CPack will only look for the menu
+# files and use the same license file for all languages.
+#
+# .. variable:: CPACK_DMG_SLA_LANGUAGES
+#
+# Languages for which a license agreement is provided when mounting the
+# generated DMG. A menu file consists of 9 lines of text. The first line is
+# is the name of the language itself, uppercase, in English (e.g. German).
+# The other lines are translations of the following strings:
+#
+# - Agree
+# - Disagree
+# - Print
+# - Save...
+# - You agree to the terms of the License Agreement when you click the
+# "Agree" button.
+# - Software License Agreement
+# - This text cannot be saved. The disk may be full or locked, or the file
+# may be locked.
+# - Unable to print. Make sure you have selected a printer.
+#
+# For every language in this list, CPack will try to find files
+# ``<language>.menu.txt`` and ``<language>.license.txt`` in the directory
+# specified by the :variable:`CPACK_DMG_SLA_DIR` variable.
+#
+# .. variable:: CPACK_COMMAND_HDIUTIL
+#
+# Path to the hdiutil(1) command used to operate on disk image files on Mac
+# OS X. This variable can be used to override the automatically detected
+# command (or specify its location if the auto-detection fails to find it.)
+#
+# .. variable:: CPACK_COMMAND_SETFILE
+#
+# Path to the SetFile(1) command used to set extended attributes on files and
+# directories on Mac OS X. This variable can be used to override the
# automatically detected command (or specify its location if the
# auto-detection fails to find it.)
-##end
+#
+# .. variable:: CPACK_COMMAND_REZ
+#
+# Path to the Rez(1) command used to compile resources on Mac OS X. This
+# variable can be used to override the automatically detected command (or
+# specify its location if the auto-detection fails to find it.)
#=============================================================================
# Copyright 2006-2012 Kitware, Inc.
diff --git a/Modules/CPackDeb.cmake b/Modules/CPackDeb.cmake
index 75ff3bef1..2aaef6161 100644
--- a/Modules/CPackDeb.cmake
+++ b/Modules/CPackDeb.cmake
@@ -1,170 +1,400 @@
-##section Variables specific to CPack Debian (DEB) generator
-##end
-##module
-# - The builtin (binary) CPack Deb generator (Unix only)
+#.rst:
+# CPackDeb
+# --------
+#
+# The builtin (binary) CPack Deb generator (Unix only)
+#
+# Variables specific to CPack Debian (DEB) generator
+# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#
# CPackDeb may be used to create Deb package using CPack.
-# CPackDeb is a CPack generator thus it uses the CPACK_XXX variables
-# used by CPack : http://www.cmake.org/Wiki/CMake:CPackConfiguration.
-# CPackDeb generator should work on any linux host but it will
-# produce better deb package when Debian specific tools 'dpkg-xxx'
-# are usable on the build system.
-#
-# CPackDeb has specific features which are controlled by
-# the specifics CPACK_DEBIAN_XXX variables.You'll find a detailed usage on
-# the wiki:
-# http://www.cmake.org/Wiki/CMake:CPackPackageGenerators#DEB_.28UNIX_only.29
+# CPackDeb is a CPack generator thus it uses the ``CPACK_XXX`` variables
+# used by CPack : https://cmake.org/Wiki/CMake:CPackConfiguration.
+# CPackDeb generator should work on any linux host but it will produce
+# better deb package when Debian specific tools 'dpkg-xxx' are usable on
+# the build system.
+#
+# CPackDeb has specific features which are controlled by the specifics
+# :code:`CPACK_DEBIAN_XXX` variables.
+#
+# :code:`CPACK_DEBIAN_<COMPONENT>_XXXX` variables may be used in order to have
+# **component** specific values. Note however that ``<COMPONENT>`` refers to the
+# **grouping name** written in upper case. It may be either a component name or
+# a component GROUP name.
+#
+# You'll find a detailed usage on the wiki:
+# https://cmake.org/Wiki/CMake:CPackPackageGenerators#DEB_.28UNIX_only.29 .
# However as a handy reminder here comes the list of specific variables:
-##end
-#
-##variable
-# CPACK_DEBIAN_PACKAGE_NAME
-# Mandatory : YES
-# Default : CPACK_PACKAGE_NAME (lower case)
-# The debian package summary
-##end
-##variable
-# CPACK_DEBIAN_PACKAGE_VERSION
-# Mandatory : YES
-# Default : CPACK_PACKAGE_VERSION
-# The debian package version
-##end
-##variable
-# CPACK_DEBIAN_PACKAGE_ARCHITECTURE
-# Mandatory : YES
-# Default : Output of dpkg --print-architecture (or i386 if dpkg is not found)
-# The debian package architecture
-##end
-##variable
-# CPACK_DEBIAN_PACKAGE_DEPENDS
-# Mandatory : NO
-# Default : -
-# May be used to set deb dependencies.
-##end
-##variable
-# CPACK_DEBIAN_PACKAGE_MAINTAINER
-# Mandatory : YES
-# Default : CPACK_PACKAGE_CONTACT
-# The debian package maintainer
-##end
-##variable
-# CPACK_DEBIAN_PACKAGE_DESCRIPTION
-# Mandatory : YES
-# Default : CPACK_PACKAGE_DESCRIPTION_SUMMARY
-# The debian package description
-##end
-##variable
-# CPACK_DEBIAN_PACKAGE_SECTION
-# Mandatory : YES
-# Default : 'devel'
-# The debian package section
-##end
-##variable
-# CPACK_DEBIAN_PACKAGE_PRIORITY
-# Mandatory : YES
-# Default : 'optional'
-# The debian package priority
-##end
-##variable
-# CPACK_DEBIAN_PACKAGE_HOMEPAGE
-# Mandatory : NO
-# Default : -
-# The URL of the web site for this package, preferably (when applicable) the
-# site from which the original source can be obtained and any additional
-# upstream documentation or information may be found.
-# The content of this field is a simple URL without any surrounding
-# characters such as <>.
-##end
-##variable
-# CPACK_DEBIAN_PACKAGE_SHLIBDEPS
-# Mandatory : NO
-# Default : OFF
-# May be set to ON in order to use dpkg-shlibdeps to generate
-# better package dependency list.
-# You may need set CMAKE_INSTALL_RPATH toi appropriate value
-# if you use this feature, because if you don't dpkg-shlibdeps
-# may fail to find your own shared libs.
-# See http://www.cmake.org/Wiki/CMake_RPATH_handling.
-##end
-##variable
-# CPACK_DEBIAN_PACKAGE_DEBUG
-# Mandatory : NO
-# Default : -
-# May be set when invoking cpack in order to trace debug information
-# during CPackDeb run.
-##end
-##variable
-# CPACK_DEBIAN_PACKAGE_PREDEPENDS
-# Mandatory : NO
-# Default : -
-# see http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps
-# This field is like Depends, except that it also forces dpkg to complete installation of
-# the packages named before even starting the installation of the package which declares
-# the pre-dependency.
-##end
-##variable
-# CPACK_DEBIAN_PACKAGE_ENHANCES
-# Mandatory : NO
-# Default : -
-# see http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps
-# This field is similar to Suggests but works in the opposite direction.
-# It is used to declare that a package can enhance the functionality of another package.
-##end
-##variable
-# CPACK_DEBIAN_PACKAGE_BREAKS
-# Mandatory : NO
-# Default : -
-# see http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps
-# When one binary package declares that it breaks another, dpkg will refuse to allow the
-# package which declares Breaks be installed unless the broken package is deconfigured first,
-# and it will refuse to allow the broken package to be reconfigured.
-##end
-##variable
-# CPACK_DEBIAN_PACKAGE_CONFLICTS
-# Mandatory : NO
-# Default : -
-# see http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps
-# When one binary package declares a conflict with another using a Conflicts field,
-# dpkg will refuse to allow them to be installed on the system at the same time.
-##end
-##variable
-# CPACK_DEBIAN_PACKAGE_PROVIDES
-# Mandatory : NO
-# Default : -
-# see http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps
-# A virtual package is one which appears in the Provides control field of another package.
-##end
-##variable
-# CPACK_DEBIAN_PACKAGE_REPLACES
-# Mandatory : NO
-# Default : -
-# see http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps
-# Packages can declare in their control file that they should overwrite
-# files in certain other packages, or completely replace other packages.
-##end
-##variable
-# CPACK_DEBIAN_PACKAGE_RECOMMENDS
-# Mandatory : NO
-# Default : -
-# see http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps
-# Allows packages to declare a strong, but not absolute, dependency on other packages.
-##end
-##variable
-# CPACK_DEBIAN_PACKAGE_SUGGESTS
-# Mandatory : NO
-# Default : -
-# see http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps
-# Allows packages to declare a suggested package install grouping.
-##end
-##variable
-# CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
-# Mandatory : NO
-# Default : -
-# This variable allow advanced user to add custom script to the control.tar.gz
-# Typical usage is for conffiles, postinst, postrm, prerm.
-# Usage: set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
-# "${CMAKE_CURRENT_SOURCE_DIR/prerm;${CMAKE_CURRENT_SOURCE_DIR}/postrm")
-##end
-
+#
+# .. variable:: CPACK_DEBIAN_PACKAGE_NAME
+# CPACK_DEBIAN_<COMPONENT>_PACKAGE_NAME
+#
+# Set Package control field (variable is automatically transformed to lower
+# case).
+#
+# * Mandatory : YES
+# * Default :
+#
+# - :variable:`CPACK_PACKAGE_NAME` for non-component based
+# installations
+# - :variable:`CPACK_DEBIAN_PACKAGE_NAME` suffixed with -<COMPONENT>
+# for component-based installations.
+#
+# See https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Source
+#
+#
+# .. variable:: CPACK_DEBIAN_PACKAGE_VERSION
+#
+# The Debian package version
+#
+# * Mandatory : YES
+# * Default : :variable:`CPACK_PACKAGE_VERSION`
+#
+#
+# .. variable:: CPACK_DEBIAN_PACKAGE_ARCHITECTURE
+#
+# The Debian package architecture
+#
+# * Mandatory : YES
+# * Default : Output of :code:`dpkg --print-architecture` (or :code:`i386`
+# if :code:`dpkg` is not found)
+#
+#
+# .. variable:: CPACK_DEBIAN_PACKAGE_DEPENDS
+# CPACK_DEBIAN_<COMPONENT>_PACKAGE_DEPENDS
+#
+# Sets the Debian dependencies of this package.
+#
+# * Mandatory : NO
+# * Default :
+#
+# - An empty string for non-component based installations
+# - :variable:`CPACK_DEBIAN_PACKAGE_DEPENDS` for component-based
+# installations.
+#
+# .. note::
+#
+# If :variable:`CPACK_DEBIAN_PACKAGE_SHLIBDEPS` or
+# more specifically :variable:`CPACK_DEBIAN_<COMPONENT>_PACKAGE_SHLIBDEPS`
+# is set for this component, the discovered dependencies will be appended
+# to :variable:`CPACK_DEBIAN_<COMPONENT>_PACKAGE_DEPENDS` instead of
+# :variable:`CPACK_DEBIAN_PACKAGE_DEPENDS`. If
+# :variable:`CPACK_DEBIAN_<COMPONENT>_PACKAGE_DEPENDS` is an empty string,
+# only the automatically discovered dependencies will be set for this
+# component.
+#
+# Example::
+#
+# set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.3.1-6), libc6 (< 2.4)")
+#
+#
+# .. variable:: CPACK_DEBIAN_PACKAGE_MAINTAINER
+#
+# The Debian package maintainer
+#
+# * Mandatory : YES
+# * Default : :code:`CPACK_PACKAGE_CONTACT`
+#
+#
+# .. variable:: CPACK_DEBIAN_PACKAGE_DESCRIPTION
+# CPACK_COMPONENT_<COMPONENT>_DESCRIPTION
+#
+# The Debian package description
+#
+# * Mandatory : YES
+# * Default :
+#
+# - :variable:`CPACK_DEBIAN_PACKAGE_DESCRIPTION` if set or
+# - :variable:`CPACK_PACKAGE_DESCRIPTION_SUMMARY`
+#
+#
+# .. variable:: CPACK_DEBIAN_PACKAGE_SECTION
+# CPACK_DEBIAN_<COMPONENT>_PACKAGE_SECTION
+#
+# Set Section control field e.g. admin, devel, doc, ...
+#
+# * Mandatory : YES
+# * Default : 'devel'
+#
+# See https://www.debian.org/doc/debian-policy/ch-archive.html#s-subsections
+#
+#
+# .. variable:: CPACK_DEBIAN_COMPRESSION_TYPE
+#
+# The compression used for creating the Debian package.
+# Possible values are: lzma, xz, bzip2 and gzip.
+#
+# * Mandatory : YES
+# * Default : 'gzip'
+#
+#
+# .. variable:: CPACK_DEBIAN_PACKAGE_PRIORITY
+# CPACK_DEBIAN_<COMPONENT>_PACKAGE_PRIORITY
+#
+# Set Priority control field e.g. required, important, standard, optional,
+# extra
+#
+# * Mandatory : YES
+# * Default : 'optional'
+#
+# See https://www.debian.org/doc/debian-policy/ch-archive.html#s-priorities
+#
+#
+# .. variable:: CPACK_DEBIAN_PACKAGE_HOMEPAGE
+#
+# The URL of the web site for this package, preferably (when applicable) the
+# site from which the original source can be obtained and any additional
+# upstream documentation or information may be found.
+#
+# * Mandatory : NO
+# * Default : -
+#
+# .. note::
+#
+# The content of this field is a simple URL without any surrounding
+# characters such as <>.
+#
+#
+# .. variable:: CPACK_DEBIAN_PACKAGE_SHLIBDEPS
+# CPACK_DEBIAN_<COMPONENT>_PACKAGE_SHLIBDEPS
+#
+# May be set to ON in order to use :code:`dpkg-shlibdeps` to generate
+# better package dependency list.
+#
+# * Mandatory : NO
+# * Default :
+#
+# - :variable:`CPACK_DEBIAN_PACKAGE_SHLIBDEPS` if set or
+# - OFF
+#
+# .. note::
+#
+# You may need set :variable:`CMAKE_INSTALL_RPATH` to an appropriate value
+# if you use this feature, because if you don't :code:`dpkg-shlibdeps`
+# may fail to find your own shared libs.
+# See https://cmake.org/Wiki/CMake_RPATH_handling.
+#
+#
+# .. variable:: CPACK_DEBIAN_PACKAGE_DEBUG
+#
+# May be set when invoking cpack in order to trace debug information
+# during CPackDeb run.
+#
+# * Mandatory : NO
+# * Default : -
+#
+# .. variable:: CPACK_DEBIAN_PACKAGE_PREDEPENDS
+# CPACK_DEBIAN_<COMPONENT>_PACKAGE_PREDEPENDS
+#
+# Sets the `Pre-Depends` field of the Debian package.
+# Like :variable:`Depends <CPACK_DEBIAN_PACKAGE_DEPENDS>`, except that it
+# also forces :code:`dpkg` to complete installation of the packages named
+# before even starting the installation of the package which declares the
+# pre-dependency.
+#
+# * Mandatory : NO
+# * Default :
+#
+# - An empty string for non-component based installations
+# - :variable:`CPACK_DEBIAN_PACKAGE_PREDEPENDS` for component-based
+# installations.
+#
+# See http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps
+#
+# .. variable:: CPACK_DEBIAN_PACKAGE_ENHANCES
+# CPACK_DEBIAN_<COMPONENT>_PACKAGE_ENHANCES
+#
+# Sets the `Enhances` field of the Debian package.
+# Similar to :variable:`Suggests <CPACK_DEBIAN_PACKAGE_SUGGESTS>` but works
+# in the opposite direction: declares that a package can enhance the
+# functionality of another package.
+#
+# * Mandatory : NO
+# * Default :
+#
+# - An empty string for non-component based installations
+# - :variable:`CPACK_DEBIAN_PACKAGE_ENHANCES` for component-based
+# installations.
+#
+# See http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps
+#
+# .. variable:: CPACK_DEBIAN_PACKAGE_BREAKS
+# CPACK_DEBIAN_<COMPONENT>_PACKAGE_BREAKS
+#
+# Sets the `Breaks` field of the Debian package.
+# When a binary package (P) declares that it breaks other packages (B),
+# :code:`dpkg` will not allow the package (P) which declares `Breaks` be
+# **unpacked** unless the packages that will be broken (B) are deconfigured
+# first.
+# As long as the package (P) is configured, the previously deconfigured
+# packages (B) cannot be reconfigured again.
+#
+# * Mandatory : NO
+# * Default :
+#
+# - An empty string for non-component based installations
+# - :variable:`CPACK_DEBIAN_PACKAGE_BREAKS` for component-based
+# installations.
+#
+# See https://www.debian.org/doc/debian-policy/ch-relationships.html#s-breaks
+#
+#
+# .. variable:: CPACK_DEBIAN_PACKAGE_CONFLICTS
+# CPACK_DEBIAN_<COMPONENT>_PACKAGE_CONFLICTS
+#
+# Sets the `Conflicts` field of the Debian package.
+# When one binary package declares a conflict with another using a `Conflicts`
+# field, :code:`dpkg` will not allow them to be unpacked on the system at
+# the same time.
+#
+# * Mandatory : NO
+# * Default :
+#
+# - An empty string for non-component based installations
+# - :variable:`CPACK_DEBIAN_PACKAGE_CONFLICTS` for component-based
+# installations.
+#
+# See https://www.debian.org/doc/debian-policy/ch-relationships.html#s-conflicts
+#
+# .. note::
+#
+# This is a stronger restriction than
+# :variable:`Breaks <CPACK_DEBIAN_PACKAGE_BREAKS>`, which prevents the
+# broken package from being configured while the breaking package is in
+# the "Unpacked" state but allows both packages to be unpacked at the same
+# time.
+#
+# .. variable:: CPACK_DEBIAN_PACKAGE_PROVIDES
+# CPACK_DEBIAN_<COMPONENT>_PACKAGE_PROVIDES
+#
+# Sets the `Provides` field of the Debian package.
+# A virtual package is one which appears in the `Provides` control field of
+# another package.
+#
+# * Mandatory : NO
+# * Default :
+#
+# - An empty string for non-component based installations
+# - :variable:`CPACK_DEBIAN_PACKAGE_PROVIDES` for component-based
+# installations.
+#
+# See https://www.debian.org/doc/debian-policy/ch-relationships.html#s-virtual
+#
+#
+# .. variable:: CPACK_DEBIAN_PACKAGE_REPLACES
+# CPACK_DEBIAN_<COMPONENT>_PACKAGE_REPLACES
+#
+# Sets the `Replaces` field of the Debian package.
+# Packages can declare in their control file that they should overwrite
+# files in certain other packages, or completely replace other packages.
+#
+# * Mandatory : NO
+# * Default :
+#
+# - An empty string for non-component based installations
+# - :variable:`CPACK_DEBIAN_PACKAGE_REPLACES` for component-based
+# installations.
+#
+# See http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps
+#
+#
+# .. variable:: CPACK_DEBIAN_PACKAGE_RECOMMENDS
+# CPACK_DEBIAN_<COMPONENT>_PACKAGE_RECOMMENDS
+#
+# Sets the `Recommends` field of the Debian package.
+# Allows packages to declare a strong, but not absolute, dependency on other
+# packages.
+#
+# * Mandatory : NO
+# * Default :
+#
+# - An empty string for non-component based installations
+# - :variable:`CPACK_DEBIAN_PACKAGE_RECOMMENDS` for component-based
+# installations.
+#
+# See http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps
+#
+#
+# .. variable:: CPACK_DEBIAN_PACKAGE_SUGGESTS
+# CPACK_DEBIAN_<COMPONENT>_PACKAGE_SUGGESTS
+#
+# Sets the `Suggests` field of the Debian package.
+# Allows packages to declare a suggested package install grouping.
+#
+# * Mandatory : NO
+# * Default :
+#
+# - An empty string for non-component based installations
+# - :variable:`CPACK_DEBIAN_PACKAGE_SUGGESTS` for component-based
+# installations.
+#
+# See http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps
+#
+#
+# .. variable:: CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
+# CPACK_DEBIAN_<COMPONENT>_PACKAGE_CONTROL_EXTRA
+#
+# This variable allow advanced user to add custom script to the
+# control.tar.gz.
+# Typical usage is for conffiles, postinst, postrm, prerm.
+#
+# * Mandatory : NO
+# * Default : -
+#
+# Usage::
+#
+# set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
+# "${CMAKE_CURRENT_SOURCE_DIR/prerm;${CMAKE_CURRENT_SOURCE_DIR}/postrm")
+#
+# .. note::
+#
+# The original permissions of the files will be used in the final
+# package unless the variable
+# :variable:`CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION` is set.
+# In particular, the scripts should have the proper executable
+# flag prior to the generation of the package.
+#
+# .. variable:: CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION
+# CPACK_DEBIAN_<COMPONENT>_PACKAGE_CONTROL_STRICT_PERMISSION
+#
+# This variable indicates if the Debian policy on control files should be
+# strictly followed.
+#
+# * Mandatory : NO
+# * Default : FALSE
+#
+# Usage::
+#
+# set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE)
+#
+# .. note::
+#
+# This overrides the permissions on the original files, following the rules
+# set by Debian policy
+# https://www.debian.org/doc/debian-policy/ch-files.html#s-permissions-owners
+#
+# .. variable:: CPACK_DEBIAN_PACKAGE_SOURCE
+# CPACK_DEBIAN_<COMPONENT>_PACKAGE_SOURCE
+#
+# Sets the ``Source`` field of the binary Debian package.
+# When the binary package name is not the same as the source package name
+# (in particular when several components/binaries are generated from one
+# source) the source from which the binary has been generated should be
+# indicated with the field ``Source``.
+#
+# * Mandatory : NO
+# * Default :
+#
+# - An empty string for non-component based installations
+# - :variable:`CPACK_DEBIAN_PACKAGE_SOURCE` for component-based
+# installations.
+#
+# See https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Source
+#
+# .. note::
+#
+# This value is not interpreted. It is possible to pass an optional
+# revision number of the referenced source package as well.
#=============================================================================
# Copyright 2007-2009 Kitware, Inc.
@@ -193,227 +423,356 @@ if(NOT UNIX)
message(FATAL_ERROR "CPackDeb.cmake may only be used under UNIX.")
endif()
-# CPACK_DEBIAN_PACKAGE_SHLIBDEPS
-# If specify OFF, only user depends are used
-if(NOT DEFINED CPACK_DEBIAN_PACKAGE_SHLIBDEPS)
- set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS OFF)
-endif()
+function(cpack_deb_prepare_package_vars)
+ # CPACK_DEBIAN_PACKAGE_SHLIBDEPS
+ # If specify OFF, only user depends are used
+ if(NOT DEFINED CPACK_DEBIAN_PACKAGE_SHLIBDEPS)
+ set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS OFF)
+ endif()
-find_program(FAKEROOT_EXECUTABLE fakeroot)
-if(FAKEROOT_EXECUTABLE)
- set(CPACK_DEBIAN_FAKEROOT_EXECUTABLE ${FAKEROOT_EXECUTABLE})
-endif()
+ set(WDIR "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_DEB_PACKAGE_COMPONENT_PART_PATH}")
-if(CPACK_DEBIAN_PACKAGE_SHLIBDEPS)
- # dpkg-shlibdeps is a Debian utility for generating dependency list
- find_program(SHLIBDEPS_EXECUTABLE dpkg-shlibdeps)
-
- # Check version of the dpkg-shlibdeps tool using CPackRPM method
- if(SHLIBDEPS_EXECUTABLE)
- execute_process(COMMAND ${SHLIBDEPS_EXECUTABLE} --version
- OUTPUT_VARIABLE _TMP_VERSION
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- string(REGEX MATCH "dpkg-shlibdeps version ([0-9]+\\.[0-9]+\\.[0-9]+)"
- SHLIBDEPS_EXECUTABLE_VERSION
- ${_TMP_VERSION})
- set(SHLIBDEPS_EXECUTABLE_VERSION "${CMAKE_MATCH_1}")
- if(CPACK_DEBIAN_PACKAGE_DEBUG)
- message( "CPackDeb Debug: dpkg-shlibdeps version is <${SHLIBDEPS_EXECUTABLE_VERSION}>")
+ # per component automatic discover: some of the component might not have
+ # binaries.
+ if(CPACK_DEB_PACKAGE_COMPONENT)
+ string(TOUPPER "${CPACK_DEB_PACKAGE_COMPONENT}" _local_component_name)
+ set(_component_shlibdeps_var "CPACK_DEBIAN_${_local_component_name}_PACKAGE_SHLIBDEPS")
+
+ # if set, overrides the global configuration
+ if(DEFINED ${_component_shlibdeps_var})
+ set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS "${${_component_shlibdeps_var}}")
+ if(CPACK_DEBIAN_PACKAGE_DEBUG)
+ message("CPackDeb Debug: component '${CPACK_DEB_PACKAGE_COMPONENT}' dpkg-shlibdeps set to ${CPACK_DEBIAN_PACKAGE_SHLIBDEPS}")
+ endif()
endif()
+ endif()
- # Generating binary list - Get type of all install files
- execute_process(COMMAND find -type f
- COMMAND xargs file
- WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}"
- OUTPUT_VARIABLE CPACK_DEB_INSTALL_FILES)
-
- # Convert to CMake list
- string(REGEX REPLACE "\n" ";" CPACK_DEB_INSTALL_FILES ${CPACK_DEB_INSTALL_FILES})
-
- # Only dynamically linked ELF files are included
- # Extract only file name infront of ":"
- foreach ( _FILE ${CPACK_DEB_INSTALL_FILES})
- if ( ${_FILE} MATCHES "ELF.*dynamically linked")
- string(REGEX MATCH "(^.*):" _FILE_NAME ${_FILE})
- list(APPEND CPACK_DEB_BINARY_FILES ${CMAKE_MATCH_1})
+ if(CPACK_DEBIAN_PACKAGE_SHLIBDEPS)
+ # dpkg-shlibdeps is a Debian utility for generating dependency list
+ find_program(SHLIBDEPS_EXECUTABLE dpkg-shlibdeps)
+
+ if(SHLIBDEPS_EXECUTABLE)
+ # Check version of the dpkg-shlibdeps tool using CPackRPM method
+ execute_process(COMMAND env LC_ALL=C ${SHLIBDEPS_EXECUTABLE} --version
+ OUTPUT_VARIABLE _TMP_VERSION
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if(_TMP_VERSION MATCHES "dpkg-shlibdeps version ([0-9]+\\.[0-9]+\\.[0-9]+)")
+ set(SHLIBDEPS_EXECUTABLE_VERSION "${CMAKE_MATCH_1}")
+ else()
+ set(SHLIBDEPS_EXECUTABLE_VERSION "")
endif()
- endforeach()
- message( "CPackDeb: - Generating dependency list")
-
- # Create blank control file for running dpkg-shlibdeps
- # There might be some other way to invoke dpkg-shlibdeps without creating this file
- # but standard debian package should not have anything that can collide with this file or directory
- file(MAKE_DIRECTORY ${CPACK_TEMPORARY_DIRECTORY}/debian)
- file(WRITE ${CPACK_TEMPORARY_DIRECTORY}/debian/control "")
-
- # Execute dpkg-shlibdeps
- # --ignore-missing-info : allow dpkg-shlibdeps to run even if some libs do not belong to a package
- # -O : print to STDOUT
- execute_process(COMMAND ${SHLIBDEPS_EXECUTABLE} --ignore-missing-info -O ${CPACK_DEB_BINARY_FILES}
- WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}"
- OUTPUT_VARIABLE SHLIBDEPS_OUTPUT
- RESULT_VARIABLE SHLIBDEPS_RESULT
- ERROR_VARIABLE SHLIBDEPS_ERROR
- OUTPUT_STRIP_TRAILING_WHITESPACE )
- if(CPACK_DEBIAN_PACKAGE_DEBUG)
- # dpkg-shlibdeps will throw some warnings if some input files are not binary
- message( "CPackDeb Debug: dpkg-shlibdeps warnings \n${SHLIBDEPS_ERROR}")
- endif()
- if (NOT SHLIBDEPS_RESULT EQUAL 0)
- message (FATAL_ERROR "CPackDeb: dpkg-shlibdeps: ${SHLIBDEPS_ERROR}")
- endif ()
+ if(CPACK_DEBIAN_PACKAGE_DEBUG)
+ message("CPackDeb Debug: dpkg-shlibdeps --version output is '${_TMP_VERSION}'")
+ message("CPackDeb Debug: dpkg-shlibdeps version is <${SHLIBDEPS_EXECUTABLE_VERSION}>")
+ endif()
- #Get rid of prefix generated by dpkg-shlibdeps
- string (REGEX REPLACE "^.*Depends=" "" CPACK_DEBIAN_PACKAGE_AUTO_DEPENDS ${SHLIBDEPS_OUTPUT})
+ # Generating binary list - Get type of all install files
+ cmake_policy(PUSH)
+ # Tell file(GLOB_RECURSE) not to follow directory symlinks
+ # even if the project does not set this policy to NEW.
+ cmake_policy(SET CMP0009 NEW)
+ file(GLOB_RECURSE FILE_PATHS_ LIST_DIRECTORIES false RELATIVE "${WDIR}" "${WDIR}/*")
+ cmake_policy(POP)
+
+ # get file info so that we can determine if file is executable or not
+ unset(CPACK_DEB_INSTALL_FILES)
+ foreach(FILE_ IN LISTS FILE_PATHS_)
+ execute_process(COMMAND file "./${FILE_}"
+ WORKING_DIRECTORY "${WDIR}"
+ OUTPUT_VARIABLE INSTALL_FILE_)
+ list(APPEND CPACK_DEB_INSTALL_FILES "${INSTALL_FILE_}")
+ endforeach()
+
+ # Only dynamically linked ELF files are included
+ # Extract only file name infront of ":"
+ foreach(_FILE ${CPACK_DEB_INSTALL_FILES})
+ if( ${_FILE} MATCHES "ELF.*dynamically linked")
+ string(REGEX MATCH "(^.*):" _FILE_NAME "${_FILE}")
+ list(APPEND CPACK_DEB_BINARY_FILES "${CMAKE_MATCH_1}")
+ set(CONTAINS_EXECUTABLE_FILES_ TRUE)
+ endif()
+ endforeach()
+
+ if(CONTAINS_EXECUTABLE_FILES_)
+ message("CPackDeb: - Generating dependency list")
+
+ # Create blank control file for running dpkg-shlibdeps
+ # There might be some other way to invoke dpkg-shlibdeps without creating this file
+ # but standard debian package should not have anything that can collide with this file or directory
+ file(MAKE_DIRECTORY ${CPACK_TEMPORARY_DIRECTORY}/debian)
+ file(WRITE ${CPACK_TEMPORARY_DIRECTORY}/debian/control "")
+
+ # Add --ignore-missing-info if the tool supports it
+ execute_process(COMMAND env LC_ALL=C ${SHLIBDEPS_EXECUTABLE} --help
+ OUTPUT_VARIABLE _TMP_HELP
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if(_TMP_HELP MATCHES "--ignore-missing-info")
+ set(IGNORE_MISSING_INFO_FLAG "--ignore-missing-info")
+ endif()
+
+ # Execute dpkg-shlibdeps
+ # --ignore-missing-info : allow dpkg-shlibdeps to run even if some libs do not belong to a package
+ # -O : print to STDOUT
+ execute_process(COMMAND ${SHLIBDEPS_EXECUTABLE} ${IGNORE_MISSING_INFO_FLAG} -O ${CPACK_DEB_BINARY_FILES}
+ WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}"
+ OUTPUT_VARIABLE SHLIBDEPS_OUTPUT
+ RESULT_VARIABLE SHLIBDEPS_RESULT
+ ERROR_VARIABLE SHLIBDEPS_ERROR
+ OUTPUT_STRIP_TRAILING_WHITESPACE )
+ if(CPACK_DEBIAN_PACKAGE_DEBUG)
+ # dpkg-shlibdeps will throw some warnings if some input files are not binary
+ message( "CPackDeb Debug: dpkg-shlibdeps warnings \n${SHLIBDEPS_ERROR}")
+ endif()
+ if(NOT SHLIBDEPS_RESULT EQUAL 0)
+ message (FATAL_ERROR "CPackDeb: dpkg-shlibdeps: '${SHLIBDEPS_ERROR}';\n"
+ "executed command: '${SHLIBDEPS_EXECUTABLE} ${IGNORE_MISSING_INFO_FLAG} -O ${CPACK_DEB_BINARY_FILES}';\n"
+ "found files: '${INSTALL_FILE_}';\n"
+ "files info: '${CPACK_DEB_INSTALL_FILES}';\n"
+ "binary files: '${CPACK_DEB_BINARY_FILES}'")
+ endif()
+
+ #Get rid of prefix generated by dpkg-shlibdeps
+ string(REGEX REPLACE "^.*Depends=" "" CPACK_DEBIAN_PACKAGE_AUTO_DEPENDS "${SHLIBDEPS_OUTPUT}")
+
+ if(CPACK_DEBIAN_PACKAGE_DEBUG)
+ message("CPackDeb Debug: Found dependency: ${CPACK_DEBIAN_PACKAGE_AUTO_DEPENDS} from output ${SHLIBDEPS_OUTPUT}")
+ endif()
+
+ # Remove blank control file
+ # Might not be safe if package actual contain file or directory named debian
+ file(REMOVE_RECURSE "${CPACK_TEMPORARY_DIRECTORY}/debian")
+ else()
+ if(CPACK_DEBIAN_PACKAGE_DEBUG)
+ message(AUTHOR_WARNING "CPackDeb Debug: Using only user-provided depends because package does not contain executable files that link to shared libraries.")
+ endif()
+ endif()
+ else()
+ message("CPackDeb: Using only user-provided dependencies because dpkg-shlibdeps is not found.")
+ endif()
+ else()
if(CPACK_DEBIAN_PACKAGE_DEBUG)
- message( "CPackDeb Debug: Found dependency: ${CPACK_DEBIAN_PACKAGE_AUTO_DEPENDS}")
+ message("CPackDeb Debug: Using only user-provided dependencies")
endif()
+ endif()
- # Remove blank control file
- # Might not be safe if package actual contain file or directory named debian
- file(REMOVE_RECURSE "${CPACK_TEMPORARY_DIRECTORY}/debian")
+ # Let's define the control file found in debian package:
- # Append user depend if set
- if (CPACK_DEBIAN_PACKAGE_DEPENDS)
- set (CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_AUTO_DEPENDS}, ${CPACK_DEBIAN_PACKAGE_DEPENDS}")
- else ()
- set (CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_AUTO_DEPENDS}")
- endif ()
+ # Binary package:
+ # http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-binarycontrolfiles
- else ()
- if(CPACK_DEBIAN_PACKAGE_DEBUG)
- message( "CPackDeb Debug: Using only user-provided depends because dpkg-shlibdeps is not found.")
- endif()
+ # DEBIAN/control
+ # debian policy enforce lower case for package name
+ # Package: (mandatory)
+ if(NOT CPACK_DEBIAN_PACKAGE_NAME)
+ string(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_DEBIAN_PACKAGE_NAME)
endif()
-else ()
- if(CPACK_DEBIAN_PACKAGE_DEBUG)
- message( "CPackDeb Debug: Using only user-provided depends")
+ # Version: (mandatory)
+ if(NOT CPACK_DEBIAN_PACKAGE_VERSION)
+ if(NOT CPACK_PACKAGE_VERSION)
+ message(FATAL_ERROR "CPackDeb: Debian package requires a package version")
+ endif()
+ set(CPACK_DEBIAN_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION})
endif()
-endif()
-# Let's define the control file found in debian package:
+ # Architecture: (mandatory)
+ if(NOT CPACK_DEBIAN_PACKAGE_ARCHITECTURE)
+ # There is no such thing as i686 architecture on debian, you should use i386 instead
+ # $ dpkg --print-architecture
+ find_program(DPKG_CMD dpkg)
+ if(NOT DPKG_CMD)
+ message(STATUS "CPackDeb: Can not find dpkg in your path, default to i386.")
+ set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE i386)
+ endif()
+ execute_process(COMMAND "${DPKG_CMD}" --print-architecture
+ OUTPUT_VARIABLE CPACK_DEBIAN_PACKAGE_ARCHITECTURE
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ endif()
-# Binary package:
-# http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-binarycontrolfiles
+ # Source: (optional)
+ # in case several packages are constructed from a unique source
+ # (multipackaging), the source may be indicated as well.
+ # The source might contain a version if the generated package
+ # version is different from the source version
+ if(NOT CPACK_DEBIAN_PACKAGE_SOURCE)
+ set(CPACK_DEBIAN_PACKAGE_SOURCE "")
+ endif()
-# DEBIAN/control
-# debian policy enforce lower case for package name
-# Package: (mandatory)
-if(NOT CPACK_DEBIAN_PACKAGE_NAME)
- string(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_DEBIAN_PACKAGE_NAME)
-endif()
+ # have a look at get_property(result GLOBAL PROPERTY ENABLED_FEATURES),
+ # this returns the successful find_package() calls, maybe this can help
+ # Depends:
+ # You should set: DEBIAN_PACKAGE_DEPENDS
+ # TODO: automate 'objdump -p | grep NEEDED'
+
+ # if per-component variable, overrides the global CPACK_DEBIAN_PACKAGE_${variable_type_}
+ # automatic dependency discovery will be performed afterwards.
+ if(CPACK_DEB_PACKAGE_COMPONENT)
+ foreach(value_type_ DEPENDS RECOMMENDS SUGGESTS PREDEPENDS ENHANCES BREAKS CONFLICTS PROVIDES REPLACES SOURCE SECTION PRIORITY NAME)
+ set(_component_var "CPACK_DEBIAN_${_local_component_name}_PACKAGE_${value_type_}")
+
+ # if set, overrides the global variable
+ if(DEFINED ${_component_var})
+ set(CPACK_DEBIAN_PACKAGE_${value_type_} "${${_component_var}}")
+ if(CPACK_DEBIAN_PACKAGE_DEBUG)
+ message("CPackDeb Debug: component '${_local_component_name}' ${value_type_} "
+ "value set to '${CPACK_DEBIAN_PACKAGE_${value_type_}}'")
+ endif()
+ endif()
+ endforeach()
+ endif()
-# Version: (mandatory)
-if(NOT CPACK_DEBIAN_PACKAGE_VERSION)
- if(NOT CPACK_PACKAGE_VERSION)
- message(FATAL_ERROR "CPackDeb: Debian package requires a package version")
+ # at this point, the CPACK_DEBIAN_PACKAGE_DEPENDS is properly set
+ # to the minimal dependency of the package
+ # Append automatically discovered dependencies .
+ if(NOT "${CPACK_DEBIAN_PACKAGE_AUTO_DEPENDS}" STREQUAL "")
+ if (CPACK_DEBIAN_PACKAGE_DEPENDS)
+ set (CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_AUTO_DEPENDS}, ${CPACK_DEBIAN_PACKAGE_DEPENDS}")
+ else ()
+ set (CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_AUTO_DEPENDS}")
+ endif ()
endif()
- set(CPACK_DEBIAN_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION})
-endif()
-# Architecture: (mandatory)
-if(NOT CPACK_DEBIAN_PACKAGE_ARCHITECTURE)
- # There is no such thing as i686 architecture on debian, you should use i386 instead
- # $ dpkg --print-architecture
- find_program(DPKG_CMD dpkg)
- if(NOT DPKG_CMD)
- message(STATUS "CPackDeb: Can not find dpkg in your path, default to i386.")
- set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE i386)
+ if(NOT CPACK_DEBIAN_PACKAGE_DEPENDS)
+ message(STATUS "CPACK_DEBIAN_PACKAGE_DEPENDS not set, the package will have no dependencies.")
endif()
- execute_process(COMMAND "${DPKG_CMD}" --print-architecture
- OUTPUT_VARIABLE CPACK_DEBIAN_PACKAGE_ARCHITECTURE
- OUTPUT_STRIP_TRAILING_WHITESPACE
- )
-endif()
-# have a look at get_property(result GLOBAL PROPERTY ENABLED_FEATURES),
-# this returns the successful find_package() calls, maybe this can help
-# Depends:
-# You should set: DEBIAN_PACKAGE_DEPENDS
-# TODO: automate 'objdump -p | grep NEEDED'
-if(NOT CPACK_DEBIAN_PACKAGE_DEPENDS)
- message(STATUS "CPACK_DEBIAN_PACKAGE_DEPENDS not set, the package will have no dependencies.")
-endif()
+ # Maintainer: (mandatory)
+ if(NOT CPACK_DEBIAN_PACKAGE_MAINTAINER)
+ if(NOT CPACK_PACKAGE_CONTACT)
+ message(FATAL_ERROR "CPackDeb: Debian package requires a maintainer for a package, set CPACK_PACKAGE_CONTACT or CPACK_DEBIAN_PACKAGE_MAINTAINER")
+ endif()
+ set(CPACK_DEBIAN_PACKAGE_MAINTAINER ${CPACK_PACKAGE_CONTACT})
+ endif()
-# Maintainer: (mandatory)
-if(NOT CPACK_DEBIAN_PACKAGE_MAINTAINER)
- if(NOT CPACK_PACKAGE_CONTACT)
- message(FATAL_ERROR "CPackDeb: Debian package requires a maintainer for a package, set CPACK_PACKAGE_CONTACT or CPACK_DEBIAN_PACKAGE_MAINTAINER")
+ # Description: (mandatory)
+ if(NOT CPACK_DEB_PACKAGE_COMPONENT)
+ if(NOT CPACK_DEBIAN_PACKAGE_DESCRIPTION)
+ if(NOT CPACK_PACKAGE_DESCRIPTION_SUMMARY)
+ message(FATAL_ERROR "CPackDeb: Debian package requires a summary for a package, set CPACK_PACKAGE_DESCRIPTION_SUMMARY or CPACK_DEBIAN_PACKAGE_DESCRIPTION")
+ endif()
+ set(CPACK_DEBIAN_PACKAGE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION_SUMMARY})
+ endif()
+ else()
+ set(component_description_var CPACK_COMPONENT_${_local_component_name}_DESCRIPTION)
+
+ # component description overrides package description
+ if(${component_description_var})
+ set(CPACK_DEBIAN_PACKAGE_DESCRIPTION ${${component_description_var}})
+ elseif(NOT CPACK_DEBIAN_PACKAGE_DESCRIPTION)
+ if(NOT CPACK_PACKAGE_DESCRIPTION_SUMMARY)
+ message(FATAL_ERROR "CPackDeb: Debian package requires a summary for a package, set CPACK_PACKAGE_DESCRIPTION_SUMMARY or CPACK_DEBIAN_PACKAGE_DESCRIPTION or ${component_description_var}")
+ endif()
+ set(CPACK_DEBIAN_PACKAGE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION_SUMMARY})
+ endif()
endif()
- set(CPACK_DEBIAN_PACKAGE_MAINTAINER ${CPACK_PACKAGE_CONTACT})
-endif()
-# Description: (mandatory)
-if(NOT CPACK_DEBIAN_PACKAGE_DESCRIPTION)
- if(NOT CPACK_PACKAGE_DESCRIPTION_SUMMARY)
- message(FATAL_ERROR "CPackDeb: Debian package requires a summary for a package, set CPACK_PACKAGE_DESCRIPTION_SUMMARY or CPACK_DEBIAN_PACKAGE_DESCRIPTION")
+ # Section: (recommended)
+ if(NOT CPACK_DEBIAN_PACKAGE_SECTION)
+ set(CPACK_DEBIAN_PACKAGE_SECTION "devel")
endif()
- set(CPACK_DEBIAN_PACKAGE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION_SUMMARY})
-endif()
-# Section: (recommended)
-if(NOT CPACK_DEBIAN_PACKAGE_SECTION)
- set(CPACK_DEBIAN_PACKAGE_SECTION "devel")
-endif()
+ # Priority: (recommended)
+ if(NOT CPACK_DEBIAN_PACKAGE_PRIORITY)
+ set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
+ endif()
-# Priority: (recommended)
-if(NOT CPACK_DEBIAN_PACKAGE_PRIORITY)
- set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
-endif()
+ # Compression: (recommended)
+ if(NOT CPACK_DEBIAN_COMPRESSION_TYPE)
+ set(CPACK_DEBIAN_COMPRESSION_TYPE "gzip")
+ endif()
-# Recommends:
-# You should set: CPACK_DEBIAN_PACKAGE_RECOMMENDS
-
-# Suggests:
-# You should set: CPACK_DEBIAN_PACKAGE_SUGGESTS
-
-# CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
-# This variable allow advanced user to add custom script to the control.tar.gz (inside the .deb archive)
-# Typical examples are:
-# - conffiles
-# - postinst
-# - postrm
-# - prerm"
-# Usage:
-# set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
-# "${CMAKE_CURRENT_SOURCE_DIR/prerm;${CMAKE_CURRENT_SOURCE_DIR}/postrm")
-
-# Are we packaging components ?
-if(CPACK_DEB_PACKAGE_COMPONENT)
- set(CPACK_DEB_PACKAGE_COMPONENT_PART_NAME "-${CPACK_DEB_PACKAGE_COMPONENT}")
- string(TOLOWER "${CPACK_PACKAGE_NAME}${CPACK_DEB_PACKAGE_COMPONENT_PART_NAME}" CPACK_DEBIAN_PACKAGE_NAME)
-else()
- set(CPACK_DEB_PACKAGE_COMPONENT_PART_NAME "")
-endif()
-set(WDIR "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_DEB_PACKAGE_COMPONENT_PART_PATH}")
-
-# Print out some debug information if we were asked for that
-if(CPACK_DEBIAN_PACKAGE_DEBUG)
- message("CPackDeb:Debug: CPACK_TOPLEVEL_DIRECTORY = ${CPACK_TOPLEVEL_DIRECTORY}")
- message("CPackDeb:Debug: CPACK_TOPLEVEL_TAG = ${CPACK_TOPLEVEL_TAG}")
- message("CPackDeb:Debug: CPACK_TEMPORARY_DIRECTORY = ${CPACK_TEMPORARY_DIRECTORY}")
- message("CPackDeb:Debug: CPACK_OUTPUT_FILE_NAME = ${CPACK_OUTPUT_FILE_NAME}")
- message("CPackDeb:Debug: CPACK_OUTPUT_FILE_PATH = ${CPACK_OUTPUT_FILE_PATH}")
- message("CPackDeb:Debug: CPACK_PACKAGE_FILE_NAME = ${CPACK_PACKAGE_FILE_NAME}")
- message("CPackDeb:Debug: CPACK_PACKAGE_INSTALL_DIRECTORY = ${CPACK_PACKAGE_INSTALL_DIRECTORY}")
- message("CPackDeb:Debug: CPACK_TEMPORARY_PACKAGE_FILE_NAME = ${CPACK_TEMPORARY_PACKAGE_FILE_NAME}")
-endif()
+ # Recommends:
+ # You should set: CPACK_DEBIAN_PACKAGE_RECOMMENDS
+
+ # Suggests:
+ # You should set: CPACK_DEBIAN_PACKAGE_SUGGESTS
+
+ # CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
+ # This variable allow advanced user to add custom script to the control.tar.gz (inside the .deb archive)
+ # Typical examples are:
+ # - conffiles
+ # - postinst
+ # - postrm
+ # - prerm
+ # Usage:
+ # set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
+ # "${CMAKE_CURRENT_SOURCE_DIR/prerm;${CMAKE_CURRENT_SOURCE_DIR}/postrm")
+
+ # Are we packaging components ?
+ if(CPACK_DEB_PACKAGE_COMPONENT)
+ # override values with per component version if set
+ foreach(VAR_NAME_ "PACKAGE_CONTROL_EXTRA" "PACKAGE_CONTROL_STRICT_PERMISSION")
+ if(CPACK_DEBIAN_${_local_component_name}_${VAR_NAME_})
+ set(CPACK_DEBIAN_${VAR_NAME_} "${CPACK_DEBIAN_${_local_component_name}_${VAR_NAME_}}")
+ endif()
+ endforeach()
-# For debian source packages:
-# debian/control
-# http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-sourcecontrolfiles
+ if(CPACK_DEBIAN_${_local_component_name}_PACKAGE_NAME)
+ string(TOLOWER "${CPACK_DEBIAN_${_local_component_name}_PACKAGE_NAME}" CPACK_DEBIAN_PACKAGE_NAME)
+ else()
+ string(TOLOWER "${CPACK_DEBIAN_PACKAGE_NAME}-${CPACK_DEB_PACKAGE_COMPONENT}" CPACK_DEBIAN_PACKAGE_NAME)
+ endif()
+ endif()
-# .dsc
-# http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-debiansourcecontrolfiles
+ # Print out some debug information if we were asked for that
+ if(CPACK_DEBIAN_PACKAGE_DEBUG)
+ message("CPackDeb:Debug: CPACK_TOPLEVEL_DIRECTORY = '${CPACK_TOPLEVEL_DIRECTORY}'")
+ message("CPackDeb:Debug: CPACK_TOPLEVEL_TAG = '${CPACK_TOPLEVEL_TAG}'")
+ message("CPackDeb:Debug: CPACK_TEMPORARY_DIRECTORY = '${CPACK_TEMPORARY_DIRECTORY}'")
+ message("CPackDeb:Debug: CPACK_OUTPUT_FILE_NAME = '${CPACK_OUTPUT_FILE_NAME}'")
+ message("CPackDeb:Debug: CPACK_OUTPUT_FILE_PATH = '${CPACK_OUTPUT_FILE_PATH}'")
+ message("CPackDeb:Debug: CPACK_PACKAGE_FILE_NAME = '${CPACK_PACKAGE_FILE_NAME}'")
+ message("CPackDeb:Debug: CPACK_PACKAGE_INSTALL_DIRECTORY = '${CPACK_PACKAGE_INSTALL_DIRECTORY}'")
+ message("CPackDeb:Debug: CPACK_TEMPORARY_PACKAGE_FILE_NAME = '${CPACK_TEMPORARY_PACKAGE_FILE_NAME}'")
+ message("CPackDeb:Debug: CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION = '${CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION}'")
+ message("CPackDeb:Debug: CPACK_DEBIAN_PACKAGE_SOURCE = '${CPACK_DEBIAN_PACKAGE_SOURCE}'")
+ endif()
-# Builds-Depends:
-#if(NOT CPACK_DEBIAN_PACKAGE_BUILDS_DEPENDS)
-# set(CPACK_DEBIAN_PACKAGE_BUILDS_DEPENDS
-# "debhelper (>> 5.0.0), libncurses5-dev, tcl8.4"
-# )
-#endif()
+ # For debian source packages:
+ # debian/control
+ # http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-sourcecontrolfiles
+
+ # .dsc
+ # http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-debiansourcecontrolfiles
+
+ # Builds-Depends:
+ #if(NOT CPACK_DEBIAN_PACKAGE_BUILDS_DEPENDS)
+ # set(CPACK_DEBIAN_PACKAGE_BUILDS_DEPENDS
+ # "debhelper (>> 5.0.0), libncurses5-dev, tcl8.4"
+ # )
+ #endif()
+
+ # move variables to parent scope so that they may be used to create debian package
+ set(GEN_CPACK_DEBIAN_PACKAGE_NAME "${CPACK_DEBIAN_PACKAGE_NAME}" PARENT_SCOPE)
+ set(GEN_CPACK_DEBIAN_PACKAGE_VERSION "${CPACK_DEBIAN_PACKAGE_VERSION}" PARENT_SCOPE)
+ set(GEN_CPACK_DEBIAN_PACKAGE_SECTION "${CPACK_DEBIAN_PACKAGE_SECTION}" PARENT_SCOPE)
+ set(GEN_CPACK_DEBIAN_PACKAGE_PRIORITY "${CPACK_DEBIAN_PACKAGE_PRIORITY}" PARENT_SCOPE)
+ set(GEN_CPACK_DEBIAN_PACKAGE_ARCHITECTURE "${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}" PARENT_SCOPE)
+ set(GEN_CPACK_DEBIAN_PACKAGE_MAINTAINER "${CPACK_DEBIAN_PACKAGE_MAINTAINER}" PARENT_SCOPE)
+ set(GEN_CPACK_DEBIAN_PACKAGE_DESCRIPTION "${CPACK_DEBIAN_PACKAGE_DESCRIPTION}" PARENT_SCOPE)
+ set(GEN_CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS}" PARENT_SCOPE)
+ set(GEN_CPACK_DEBIAN_COMPRESSION_TYPE "${CPACK_DEBIAN_COMPRESSION_TYPE}" PARENT_SCOPE)
+ set(GEN_CPACK_DEBIAN_PACKAGE_RECOMMENDS "${CPACK_DEBIAN_PACKAGE_RECOMMENDS}" PARENT_SCOPE)
+ set(GEN_CPACK_DEBIAN_PACKAGE_SUGGESTS "${CPACK_DEBIAN_PACKAGE_SUGGESTS}" PARENT_SCOPE)
+ set(GEN_CPACK_DEBIAN_PACKAGE_HOMEPAGE "${CPACK_DEBIAN_PACKAGE_HOMEPAGE}" PARENT_SCOPE)
+ set(GEN_CPACK_DEBIAN_PACKAGE_PREDEPENDS "${CPACK_DEBIAN_PACKAGE_PREDEPENDS}" PARENT_SCOPE)
+ set(GEN_CPACK_DEBIAN_PACKAGE_ENHANCES "${CPACK_DEBIAN_PACKAGE_ENHANCES}" PARENT_SCOPE)
+ set(GEN_CPACK_DEBIAN_PACKAGE_BREAKS "${CPACK_DEBIAN_PACKAGE_BREAKS}" PARENT_SCOPE)
+ set(GEN_CPACK_DEBIAN_PACKAGE_CONFLICTS "${CPACK_DEBIAN_PACKAGE_CONFLICTS}" PARENT_SCOPE)
+ set(GEN_CPACK_DEBIAN_PACKAGE_PROVIDES "${CPACK_DEBIAN_PACKAGE_PROVIDES}" PARENT_SCOPE)
+ set(GEN_CPACK_DEBIAN_PACKAGE_REPLACES "${CPACK_DEBIAN_PACKAGE_REPLACES}" PARENT_SCOPE)
+ set(GEN_CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA}" PARENT_SCOPE)
+ set(GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION
+ "${CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION}" PARENT_SCOPE)
+ set(GEN_CPACK_DEBIAN_PACKAGE_SOURCE
+ "${CPACK_DEBIAN_PACKAGE_SOURCE}" PARENT_SCOPE)
+ set(GEN_WDIR "${WDIR}" PARENT_SCOPE)
+endfunction()
+
+cpack_deb_prepare_package_vars()
diff --git a/Modules/CPackIFW.cmake b/Modules/CPackIFW.cmake
new file mode 100644
index 000000000..6649933b6
--- /dev/null
+++ b/Modules/CPackIFW.cmake
@@ -0,0 +1,614 @@
+#.rst:
+# CPackIFW
+# --------
+#
+# .. _QtIFW: http://doc.qt.io/qtinstallerframework/index.html
+#
+# This module looks for the location of the command line utilities supplied with
+# the Qt Installer Framework (QtIFW_).
+#
+# The module also defines several commands to control the behavior of the
+# CPack ``IFW`` generator.
+#
+#
+# Overview
+# ^^^^^^^^
+#
+# CPack ``IFW`` generator helps you to create online and offline
+# binary cross-platform installers with a graphical user interface.
+#
+# CPack IFW generator prepares project installation and generates configuration
+# and meta information for QtIFW_ tools.
+#
+# The QtIFW_ provides a set of tools and utilities to create
+# installers for the supported desktop Qt platforms: Linux, Microsoft Windows,
+# and Mac OS X.
+#
+# You should also install QtIFW_ to use CPack ``IFW`` generator.
+# If you don't use a default path for the installation, please set
+# the used path in the variable ``QTIFWDIR``.
+#
+# Variables
+# ^^^^^^^^^
+#
+# You can use the following variables to change behavior of CPack ``IFW`` generator.
+#
+# Debug
+# """"""
+#
+# .. variable:: CPACK_IFW_VERBOSE
+#
+# Set to ``ON`` to enable addition debug output.
+# By default is ``OFF``.
+#
+# Package
+# """""""
+#
+# .. variable:: CPACK_IFW_PACKAGE_TITLE
+#
+# Name of the installer as displayed on the title bar.
+# By default used :variable:`CPACK_PACKAGE_DESCRIPTION_SUMMARY`.
+#
+# .. variable:: CPACK_IFW_PACKAGE_PUBLISHER
+#
+# Publisher of the software (as shown in the Windows Control Panel).
+# By default used :variable:`CPACK_PACKAGE_VENDOR`.
+#
+# .. variable:: CPACK_IFW_PRODUCT_URL
+#
+# URL to a page that contains product information on your web site.
+#
+# .. variable:: CPACK_IFW_PACKAGE_ICON
+#
+# Filename for a custom installer icon. The actual file is '.icns' (Mac OS X),
+# '.ico' (Windows). No functionality on Unix.
+#
+# .. variable:: CPACK_IFW_PACKAGE_WINDOW_ICON
+#
+# Filename for a custom window icon in PNG format for the Installer application.
+#
+# .. variable:: CPACK_IFW_PACKAGE_LOGO
+#
+# Filename for a logo is used as QWizard::LogoPixmap.
+#
+# .. variable:: CPACK_IFW_PACKAGE_START_MENU_DIRECTORY
+#
+# Name of the default program group for the product in the Windows Start menu.
+#
+# By default used :variable:`CPACK_IFW_PACKAGE_NAME`.
+#
+# .. variable:: CPACK_IFW_TARGET_DIRECTORY
+#
+# Default target directory for installation.
+# By default used "@ApplicationsDir@/:variable:`CPACK_PACKAGE_INSTALL_DIRECTORY`"
+#
+# You can use predefined variables.
+#
+# .. variable:: CPACK_IFW_ADMIN_TARGET_DIRECTORY
+#
+# Default target directory for installation with administrator rights.
+#
+# You can use predefined variables.
+#
+# .. variable:: CPACK_IFW_PACKAGE_GROUP
+#
+# The group, which will be used to configure the root package
+#
+# .. variable:: CPACK_IFW_PACKAGE_NAME
+#
+# The root package name, which will be used if configuration group is not
+# specified
+#
+# .. variable:: CPACK_IFW_PACKAGE_MAINTENANCE_TOOL_NAME
+#
+# Filename of the generated maintenance tool.
+# The platform-specific executable file extension is appended.
+#
+# By default used QtIFW_ defaults (``maintenancetool``).
+#
+# .. variable:: CPACK_IFW_PACKAGE_MAINTENANCE_TOOL_INI_FILE
+#
+# Filename for the configuration of the generated maintenance tool.
+#
+# By default used QtIFW_ defaults (``maintenancetool.ini``).
+#
+# .. variable:: CPACK_IFW_PACKAGE_ALLOW_NON_ASCII_CHARACTERS
+#
+# Set to ``ON`` if the installation path can contain non-ASCII characters.
+#
+# Is ``ON`` for QtIFW_ less 2.0 tools.
+#
+# .. variable:: CPACK_IFW_PACKAGE_ALLOW_SPACE_IN_PATH
+#
+# Set to ``OFF`` if the installation path cannot contain space characters.
+#
+# Is ``ON`` for QtIFW_ less 2.0 tools.
+#
+# .. variable:: CPACK_IFW_PACKAGE_CONTROL_SCRIPT
+#
+# Filename for a custom installer control script.
+#
+# .. variable:: CPACK_IFW_REPOSITORIES_ALL
+#
+# The list of remote repositories.
+#
+# The default value of this variable is computed by CPack and contains
+# all repositories added with command :command:`cpack_ifw_add_repository`
+#
+# .. variable:: CPACK_IFW_DOWNLOAD_ALL
+#
+# If this is ``ON`` all components will be downloaded.
+# By default is ``OFF`` or used value
+# from ``CPACK_DOWNLOAD_ALL`` if set
+#
+# Components
+# """"""""""
+#
+# .. variable:: CPACK_IFW_RESOLVE_DUPLICATE_NAMES
+#
+# Resolve duplicate names when installing components with groups.
+#
+# .. variable:: CPACK_IFW_PACKAGES_DIRECTORIES
+#
+# Additional prepared packages dirs that will be used to resolve
+# dependent components.
+#
+# Tools
+# """"""""
+#
+# .. variable:: CPACK_IFW_FRAMEWORK_VERSION
+#
+# The version of used QtIFW_ tools.
+#
+# .. variable:: CPACK_IFW_BINARYCREATOR_EXECUTABLE
+#
+# The path to "binarycreator" command line client.
+#
+# This variable is cached and can be configured user if need.
+#
+# .. variable:: CPACK_IFW_REPOGEN_EXECUTABLE
+#
+# The path to "repogen" command line client.
+#
+# This variable is cached and can be configured user if need.
+#
+# Commands
+# ^^^^^^^^^
+#
+# The module defines the following commands:
+#
+# --------------------------------------------------------------------------
+#
+# .. command:: cpack_ifw_configure_component
+#
+# Sets the arguments specific to the CPack IFW generator.
+#
+# ::
+#
+# cpack_ifw_configure_component(<compname> [COMMON]
+# [NAME <name>]
+# [VERSION <version>]
+# [SCRIPT <script>]
+# [PRIORITY <priority>]
+# [DEPENDS <com_id> ...]
+# [LICENSES <display_name> <file_path> ...])
+#
+# This command should be called after cpack_add_component command.
+#
+# ``COMMON`` if set, then the component will be packaged and installed as part
+# of a group to which it belongs.
+#
+# ``VERSION`` is version of component.
+# By default used :variable:`CPACK_PACKAGE_VERSION`.
+#
+# ``SCRIPT`` is a relative or absolute path to operations script
+# for this component.
+#
+# ``NAME`` is used to create domain-like identification for this component.
+# By default used origin component name.
+#
+# ``PRIORITY`` is priority of the component in the tree.
+#
+# ``DEPENDS`` list of dependency component identifiers in QtIFW_ style.
+#
+# ``LICENSES`` pair of <display_name> and <file_path> of license text for this
+# component. You can specify more then one license.
+#
+# --------------------------------------------------------------------------
+#
+# .. command:: cpack_ifw_configure_component_group
+#
+# Sets the arguments specific to the CPack IFW generator.
+#
+# ::
+#
+# cpack_ifw_configure_component_group(<grpname>
+# [VERSION <version>]
+# [NAME <name>]
+# [SCRIPT <script>]
+# [PRIORITY <priority>]
+# [LICENSES <display_name> <file_path> ...])
+#
+# This command should be called after cpack_add_component_group command.
+#
+# ``VERSION`` is version of component group.
+# By default used :variable:`CPACK_PACKAGE_VERSION`.
+#
+# ``NAME`` is used to create domain-like identification for this component group.
+# By default used origin component group name.
+#
+# ``SCRIPT`` is a relative or absolute path to operations script
+# for this component group.
+#
+# ``PRIORITY`` is priority of the component group in the tree.
+#
+# ``LICENSES`` pair of <display_name> and <file_path> of license text for this
+# component group. You can specify more then one license.
+#
+# --------------------------------------------------------------------------
+#
+# .. command:: cpack_ifw_add_repository
+#
+# Add QtIFW_ specific remote repository.
+#
+# ::
+#
+# cpack_ifw_add_repository(<reponame> [DISABLED]
+# URL <url>
+# [USERNAME <username>]
+# [PASSWORD <password>]
+# [DISPLAY_NAME <display_name>])
+#
+# This macro will also add the <reponame> repository
+# to a variable :variable:`CPACK_IFW_REPOSITORIES_ALL`
+#
+# ``DISABLED`` if set, then the repository will be disabled by default.
+#
+# ``URL`` is points to a list of available components.
+#
+# ``USERNAME`` is used as user on a protected repository.
+#
+# ``PASSWORD`` is password to use on a protected repository.
+#
+# ``DISPLAY_NAME`` is string to display instead of the URL.
+#
+# Example usage
+# ^^^^^^^^^^^^^
+#
+# .. code-block:: cmake
+#
+# set(CPACK_PACKAGE_NAME "MyPackage")
+# set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "MyPackage Installation Example")
+# set(CPACK_PACKAGE_VERSION "1.0.0") # Version of installer
+#
+# include(CPack)
+# include(CPackIFW)
+#
+# cpack_add_component(myapp
+# DISPLAY_NAME "MyApp"
+# DESCRIPTION "My Application")
+# cpack_ifw_configure_component(myapp
+# VERSION "1.2.3" # Version of component
+# SCRIPT "operations.qs")
+# cpack_add_component(mybigplugin
+# DISPLAY_NAME "MyBigPlugin"
+# DESCRIPTION "My Big Downloadable Plugin"
+# DOWNLOADED)
+# cpack_ifw_add_repository(myrepo
+# URL "http://example.com/ifw/repo/myapp"
+# DISPLAY_NAME "My Application Repository")
+#
+#
+# Online installer
+# ^^^^^^^^^^^^^^^^
+#
+# By default CPack IFW generator makes offline installer. This means that all
+# components will be packaged into a binary file.
+#
+# To make a component downloaded, you must set the ``DOWNLOADED`` option in
+# :command:`cpack_add_component`.
+#
+# Then you would use the command :command:`cpack_configure_downloads`.
+# If you set ``ALL`` option all components will be downloaded.
+#
+# You also can use command :command:`cpack_ifw_add_repository` and
+# variable :variable:`CPACK_IFW_DOWNLOAD_ALL` for more specific configuration.
+#
+# CPack IFW generator creates "repository" dir in current binary dir. You
+# would copy content of this dir to specified ``site`` (``url``).
+#
+# See Also
+# ^^^^^^^^
+#
+# Qt Installer Framework Manual:
+#
+# Index page
+# http://doc.qt.io/qtinstallerframework/index.html
+#
+# Component Scripting
+# http://doc.qt.io/qtinstallerframework/scripting.html
+#
+# Predefined Variables
+# http://doc.qt.io/qtinstallerframework/scripting.html#predefined-variables
+#
+# Download Qt Installer Framework for you platform from Qt site:
+# http://download.qt.io/official_releases/qt-installer-framework
+#
+
+#=============================================================================
+# Copyright 2014 Kitware, Inc.
+# Copyright 2014 Konstantin Podsvirov <konstantin@podsvirov.pro>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+#=============================================================================
+# Search Qt Installer Framework tools
+#=============================================================================
+
+# Default path
+
+set(_CPACK_IFW_PATHS
+ "${QTIFWDIR}"
+ "$ENV{QTIFWDIR}"
+ "${QTDIR}"
+ "$ENV{QTIFWDIR}")
+if(WIN32)
+ list(APPEND _CPACK_IFW_PATHS
+ "$ENV{HOMEDRIVE}/Qt"
+ "C:/Qt")
+else()
+ list(APPEND _CPACK_IFW_PATHS
+ "$ENV{HOME}/Qt"
+ "/opt/Qt")
+endif()
+
+set(_CPACK_IFW_SUFFIXES
+# Common
+ "bin"
+# Second branch
+ "QtIFW2.3.0/bin"
+ "QtIFW2.2.0/bin"
+ "QtIFW2.1.0/bin"
+ "QtIFW2.0.0/bin"
+# First branch
+ "QtIFW-1.6.0/bin"
+ "QtIFW-1.5.0/bin"
+ "QtIFW-1.4.0/bin"
+ "QtIFW-1.3.0/bin")
+
+# Look for 'binarycreator'
+
+find_program(CPACK_IFW_BINARYCREATOR_EXECUTABLE
+ NAMES binarycreator
+ PATHS ${_CPACK_IFW_PATHS}
+ PATH_SUFFIXES ${_CPACK_IFW_SUFFIXES}
+ DOC "QtIFW binarycreator command line client")
+
+mark_as_advanced(CPACK_IFW_BINARYCREATOR_EXECUTABLE)
+
+# Look for 'repogen'
+
+find_program(CPACK_IFW_REPOGEN_EXECUTABLE
+ NAMES repogen
+ PATHS ${_CPACK_IFW_PATHS}
+ PATH_SUFFIXES ${_CPACK_IFW_SUFFIXES}
+ DOC "QtIFW repogen command line client"
+ )
+mark_as_advanced(CPACK_IFW_REPOGEN_EXECUTABLE)
+
+# Look for 'installerbase'
+
+find_program(CPACK_IFW_INSTALLERBASE_EXECUTABLE
+ NAMES installerbase
+ PATHS ${_CPACK_IFW_PATHS}
+ PATH_SUFFIXES ${_CPACK_IFW_SUFFIXES}
+ DOC "QtIFW installer executable base"
+ )
+mark_as_advanced(CPACK_IFW_INSTALLERBASE_EXECUTABLE)
+
+# Look for 'devtool' (appeared in the second branch)
+
+find_program(CPACK_IFW_DEVTOOL_EXECUTABLE
+ NAMES devtool
+ PATHS ${_CPACK_IFW_PATHS}
+ PATH_SUFFIXES ${_CPACK_IFW_SUFFIXES}
+ DOC "QtIFW devtool command line client"
+ )
+mark_as_advanced(CPACK_IFW_DEVTOOL_EXECUTABLE)
+
+#
+## Next code is included only once
+#
+
+if(NOT CPackIFW_CMake_INCLUDED)
+set(CPackIFW_CMake_INCLUDED 1)
+
+#=============================================================================
+# Framework version
+#=============================================================================
+
+if(CPACK_IFW_INSTALLERBASE_EXECUTABLE AND CPACK_IFW_DEVTOOL_EXECUTABLE)
+ execute_process(COMMAND
+ "${CPACK_IFW_INSTALLERBASE_EXECUTABLE}" --framework-version
+ OUTPUT_VARIABLE CPACK_IFW_FRAMEWORK_VERSION)
+ if(CPACK_IFW_FRAMEWORK_VERSION)
+ string(REPLACE " " ""
+ CPACK_IFW_FRAMEWORK_VERSION "${CPACK_IFW_FRAMEWORK_VERSION}")
+ string(REPLACE "\t" ""
+ CPACK_IFW_FRAMEWORK_VERSION "${CPACK_IFW_FRAMEWORK_VERSION}")
+ string(REPLACE "\n" ""
+ CPACK_IFW_FRAMEWORK_VERSION "${CPACK_IFW_FRAMEWORK_VERSION}")
+ if(CPACK_IFW_VERBOSE)
+ message(STATUS "Found QtIFW ${CPACK_IFW_FRAMEWORK_VERSION} version")
+ endif()
+ endif()
+endif()
+
+#=============================================================================
+# Macro definition
+#=============================================================================
+
+# Macro definition based on CPackComponent
+
+if(NOT CPackComponent_CMake_INCLUDED)
+ include(CPackComponent)
+endif()
+
+if(NOT __CMAKE_PARSE_ARGUMENTS_INCLUDED)
+ include(CMakeParseArguments)
+endif()
+
+# Resolve full filename for script file
+macro(_cpack_ifw_resolve_script _variable)
+ set(_ifw_script_macro ${_variable})
+ set(_ifw_script_file ${${_ifw_script_macro}})
+ if(DEFINED ${_ifw_script_macro})
+ get_filename_component(${_ifw_script_macro} ${_ifw_script_file} ABSOLUTE)
+ set(_ifw_script_file ${${_ifw_script_macro}})
+ if(NOT EXISTS ${_ifw_script_file})
+ message(WARNING "CPack IFW: script file \"${_ifw_script_file}\" is not exists")
+ set(${_ifw_script_macro})
+ endif()
+ endif()
+endmacro()
+
+# Resolve full path to lisense file
+macro(_cpack_ifw_resolve_lisenses _variable)
+ if(${_variable})
+ set(_ifw_license_file FALSE)
+ set(_ifw_licenses_fix)
+ foreach(_ifw_licenses_arg ${${_variable}})
+ if(_ifw_license_file)
+ get_filename_component(_ifw_licenses_arg "${_ifw_licenses_arg}" ABSOLUTE)
+ set(_ifw_license_file FALSE)
+ else()
+ set(_ifw_license_file TRUE)
+ endif()
+ list(APPEND _ifw_licenses_fix "${_ifw_licenses_arg}")
+ endforeach(_ifw_licenses_arg)
+ set(${_variable} "${_ifw_licenses_fix}")
+ endif()
+endmacro()
+
+# Macro for configure component
+macro(cpack_ifw_configure_component compname)
+
+ string(TOUPPER ${compname} _CPACK_IFWCOMP_UNAME)
+
+ set(_IFW_OPT COMMON)
+ set(_IFW_ARGS VERSION SCRIPT NAME PRIORITY)
+ set(_IFW_MULTI_ARGS DEPENDS LICENSES)
+ cmake_parse_arguments(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME} "${_IFW_OPT}" "${_IFW_ARGS}" "${_IFW_MULTI_ARGS}" ${ARGN})
+
+ _cpack_ifw_resolve_script(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_SCRIPT)
+ _cpack_ifw_resolve_lisenses(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_LICENSES)
+
+ set(_CPACK_IFWCOMP_STR "\n# Configuration for IFW component \"${compname}\"\n")
+
+ foreach(_IFW_ARG_NAME ${_IFW_OPT})
+ cpack_append_option_set_command(
+ CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_${_IFW_ARG_NAME}
+ _CPACK_IFWCOMP_STR)
+ endforeach()
+
+ foreach(_IFW_ARG_NAME ${_IFW_ARGS})
+ cpack_append_string_variable_set_command(
+ CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_${_IFW_ARG_NAME}
+ _CPACK_IFWCOMP_STR)
+ endforeach()
+
+ foreach(_IFW_ARG_NAME ${_IFW_MULTI_ARGS})
+ cpack_append_variable_set_command(
+ CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_${_IFW_ARG_NAME}
+ _CPACK_IFWCOMP_STR)
+ endforeach()
+
+ if(CPack_CMake_INCLUDED)
+ file(APPEND "${CPACK_OUTPUT_CONFIG_FILE}" "${_CPACK_IFWCOMP_STR}")
+ endif()
+
+endmacro()
+
+# Macro for configure group
+macro(cpack_ifw_configure_component_group grpname)
+
+ string(TOUPPER ${grpname} _CPACK_IFWGRP_UNAME)
+
+ set(_IFW_OPT)
+ set(_IFW_ARGS NAME VERSION SCRIPT PRIORITY)
+ set(_IFW_MULTI_ARGS LICENSES)
+ cmake_parse_arguments(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME} "${_IFW_OPT}" "${_IFW_ARGS}" "${_IFW_MULTI_ARGS}" ${ARGN})
+
+ _cpack_ifw_resolve_script(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_SCRIPT)
+ _cpack_ifw_resolve_lisenses(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_LICENSES)
+
+ set(_CPACK_IFWGRP_STR "\n# Configuration for IFW component group \"${grpname}\"\n")
+
+ foreach(_IFW_ARG_NAME ${_IFW_ARGS})
+ cpack_append_string_variable_set_command(
+ CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_${_IFW_ARG_NAME}
+ _CPACK_IFWGRP_STR)
+ endforeach()
+
+ foreach(_IFW_ARG_NAME ${_IFW_MULTI_ARGS})
+ cpack_append_variable_set_command(
+ CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_${_IFW_ARG_NAME}
+ _CPACK_IFWGRP_STR)
+ endforeach()
+
+ if(CPack_CMake_INCLUDED)
+ file(APPEND "${CPACK_OUTPUT_CONFIG_FILE}" "${_CPACK_IFWGRP_STR}")
+ endif()
+endmacro()
+
+# Macro for adding repository
+macro(cpack_ifw_add_repository reponame)
+
+ string(TOUPPER ${reponame} _CPACK_IFWREPO_UNAME)
+
+ set(_IFW_OPT DISABLED)
+ set(_IFW_ARGS URL USERNAME PASSWORD DISPLAY_NAME)
+ set(_IFW_MULTI_ARGS)
+ cmake_parse_arguments(CPACK_IFW_REPOSITORY_${_CPACK_IFWREPO_UNAME} "${_IFW_OPT}" "${_IFW_ARGS}" "${_IFW_MULTI_ARGS}" ${ARGN})
+
+ set(_CPACK_IFWREPO_STR "\n# Configuration for IFW repository \"${reponame}\"\n")
+
+ foreach(_IFW_ARG_NAME ${_IFW_OPT})
+ cpack_append_option_set_command(
+ CPACK_IFW_REPOSITORY_${_CPACK_IFWREPO_UNAME}_${_IFW_ARG_NAME}
+ _CPACK_IFWREPO_STR)
+ endforeach()
+
+ foreach(_IFW_ARG_NAME ${_IFW_ARGS})
+ cpack_append_string_variable_set_command(
+ CPACK_IFW_REPOSITORY_${_CPACK_IFWREPO_UNAME}_${_IFW_ARG_NAME}
+ _CPACK_IFWREPO_STR)
+ endforeach()
+
+ foreach(_IFW_ARG_NAME ${_IFW_MULTI_ARGS})
+ cpack_append_variable_set_command(
+ CPACK_IFW_REPOSITORY_${_CPACK_IFWREPO_UNAME}_${_IFW_ARG_NAME}
+ _CPACK_IFWREPO_STR)
+ endforeach()
+
+ list(APPEND CPACK_IFW_REPOSITORIES_ALL ${reponame})
+ set(_CPACK_IFWREPO_STR "${_CPACK_IFWREPO_STR}list(APPEND CPACK_IFW_REPOSITORIES_ALL ${reponame})\n")
+
+ if(CPack_CMake_INCLUDED)
+ file(APPEND "${CPACK_OUTPUT_CONFIG_FILE}" "${_CPACK_IFWREPO_STR}")
+ endif()
+
+endmacro()
+
+# Resolve package control script
+_cpack_ifw_resolve_script(CPACK_IFW_PACKAGE_CONTROL_SCRIPT)
+
+endif() # NOT CPackIFW_CMake_INCLUDED
diff --git a/Modules/CPackNSIS.cmake b/Modules/CPackNSIS.cmake
index d14005369..db5984a66 100644
--- a/Modules/CPackNSIS.cmake
+++ b/Modules/CPackNSIS.cmake
@@ -1,134 +1,130 @@
-##section Variables specific to CPack NSIS generator
-##end
-##module
-# - CPack NSIS generator specific options
+#.rst:
+# CPackNSIS
+# ---------
+#
+# CPack NSIS generator specific options
+#
+# Variables specific to CPack NSIS generator
+# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#
# The following variables are specific to the graphical installers built
# on Windows using the Nullsoft Installation System.
-##end
-#
-##variable
-# CPACK_NSIS_INSTALL_ROOT - The default installation directory presented
-# to the end user by the NSIS installer is under this root dir. The full
-# directory presented to the end user is:
-# ${CPACK_NSIS_INSTALL_ROOT}/${CPACK_PACKAGE_INSTALL_DIRECTORY}
-##end
-#
-##variable
-# CPACK_NSIS_MUI_ICON - An icon filename.
-# The name of a *.ico file used as the main icon for the generated
-# install program.
-##end
-#
-##variable
-# CPACK_NSIS_MUI_UNIICON - An icon filename.
-# The name of a *.ico file used as the main icon for the generated
-# uninstall program.
-##end
-#
-##variable
-# CPACK_NSIS_INSTALLER_MUI_ICON_CODE - undocumented.
-##end
-#
-##variable
-# CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS - Extra NSIS commands that
-# will be added to the beginning of the install Section, before your
-# install tree is available on the target system.
-##end
-#
-##variable
-# CPACK_NSIS_EXTRA_INSTALL_COMMANDS - Extra NSIS commands that
-# will be added to the end of the install Section, after your
-# install tree is available on the target system.
-##end
-#
-##variable
-# CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS - Extra NSIS commands that will
-# be added to the uninstall Section, before your install tree is
-# removed from the target system.
-##end
-#
-##variable
-# CPACK_NSIS_COMPRESSOR - The arguments that will be passed to the
-# NSIS SetCompressor command.
-##end
-#
-##variable
-# CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL - Ask about uninstalling
-# previous versions first.
-# If this is set to "ON", then an installer will look for previous
-# installed versions and if one is found, ask the user whether to
-# uninstall it before proceeding with the install.
-##end
-#
-##variable
-# CPACK_NSIS_MODIFY_PATH - Modify PATH toggle.
-# If this is set to "ON", then an extra page
-# will appear in the installer that will allow the user to choose
-# whether the program directory should be added to the system PATH
-# variable.
-##end
-#
-##variable
-# CPACK_NSIS_DISPLAY_NAME - The display name string that appears in
-# the Windows Add/Remove Program control panel
-##end
-#
-##variable
-# CPACK_NSIS_PACKAGE_NAME - The title displayed at the top of the
-# installer.
-##end
-#
-##variable
-# CPACK_NSIS_INSTALLED_ICON_NAME - A path to the executable that
-# contains the installer icon.
-##end
-#
-##variable
-# CPACK_NSIS_HELP_LINK - URL to a web site providing assistance in
-# installing your application.
-##end
-#
-##variable
-# CPACK_NSIS_URL_INFO_ABOUT - URL to a web site providing more
-# information about your application.
-##end
-#
-##variable
-# CPACK_NSIS_CONTACT - Contact information for questions and comments
-# about the installation process.
-##end
-#
-##variable
-# CPACK_NSIS_CREATE_ICONS_EXTRA - Additional NSIS commands for
-# creating start menu shortcuts.
-##end
-#
-##variable
-# CPACK_NSIS_DELETE_ICONS_EXTRA -Additional NSIS commands to
-# uninstall start menu shortcuts.
-##end
-#
-##variable
-# CPACK_NSIS_EXECUTABLES_DIRECTORY - Creating NSIS start menu links
-# assumes that they are in 'bin' unless this variable is set.
-# For example, you would set this to 'exec' if your executables are
-# in an exec directory.
-##end
-#
-##variable
-# CPACK_NSIS_MUI_FINISHPAGE_RUN - Specify an executable to add an option
-# to run on the finish page of the NSIS installer.
-##end
-##variable
-# CPACK_NSIS_MENU_LINKS - Specify links in [application] menu.
-# This should contain a list of pair "link" "link name". The link
-# may be an URL or a path relative to installation prefix.
-# Like:
-# set(CPACK_NSIS_MENU_LINKS
-# "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake.html" "CMake Help"
-# "http://www.cmake.org" "CMake Web Site")
-##end
+#
+# .. variable:: CPACK_NSIS_INSTALL_ROOT
+#
+# The default installation directory presented to the end user by the NSIS
+# installer is under this root dir. The full directory presented to the end
+# user is: ${CPACK_NSIS_INSTALL_ROOT}/${CPACK_PACKAGE_INSTALL_DIRECTORY}
+#
+# .. variable:: CPACK_NSIS_MUI_ICON
+#
+# An icon filename. The name of a ``*.ico`` file used as the main icon for the
+# generated install program.
+#
+# .. variable:: CPACK_NSIS_MUI_UNIICON
+#
+# An icon filename. The name of a ``*.ico`` file used as the main icon for the
+# generated uninstall program.
+#
+# .. variable:: CPACK_NSIS_INSTALLER_MUI_ICON_CODE
+#
+# undocumented.
+#
+# .. variable:: CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP
+#
+# The filename of a bitmap to use as the NSIS MUI_WELCOMEFINISHPAGE_BITMAP.
+#
+# .. variable:: CPACK_NSIS_MUI_UNWELCOMEFINISHPAGE_BITMAP
+#
+# The filename of a bitmap to use as the NSIS MUI_UNWELCOMEFINISHPAGE_BITMAP.
+#
+# .. variable:: CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS
+#
+# Extra NSIS commands that will be added to the beginning of the install
+# Section, before your install tree is available on the target system.
+#
+# .. variable:: CPACK_NSIS_EXTRA_INSTALL_COMMANDS
+#
+# Extra NSIS commands that will be added to the end of the install Section,
+# after your install tree is available on the target system.
+#
+# .. variable:: CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS
+#
+# Extra NSIS commands that will be added to the uninstall Section, before
+# your install tree is removed from the target system.
+#
+# .. variable:: CPACK_NSIS_COMPRESSOR
+#
+# The arguments that will be passed to the NSIS SetCompressor command.
+#
+# .. variable:: CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL
+#
+# Ask about uninstalling previous versions first. If this is set to "ON",
+# then an installer will look for previous installed versions and if one is
+# found, ask the user whether to uninstall it before proceeding with the
+# install.
+#
+# .. variable:: CPACK_NSIS_MODIFY_PATH
+#
+# Modify PATH toggle. If this is set to "ON", then an extra page will appear
+# in the installer that will allow the user to choose whether the program
+# directory should be added to the system PATH variable.
+#
+# .. variable:: CPACK_NSIS_DISPLAY_NAME
+#
+# The display name string that appears in the Windows Add/Remove Program
+# control panel
+#
+# .. variable:: CPACK_NSIS_PACKAGE_NAME
+#
+# The title displayed at the top of the installer.
+#
+# .. variable:: CPACK_NSIS_INSTALLED_ICON_NAME
+#
+# A path to the executable that contains the installer icon.
+#
+# .. variable:: CPACK_NSIS_HELP_LINK
+#
+# URL to a web site providing assistance in installing your application.
+#
+# .. variable:: CPACK_NSIS_URL_INFO_ABOUT
+#
+# URL to a web site providing more information about your application.
+#
+# .. variable:: CPACK_NSIS_CONTACT
+#
+# Contact information for questions and comments about the installation
+# process.
+#
+# .. variable:: CPACK_NSIS_CREATE_ICONS_EXTRA
+#
+# Additional NSIS commands for creating start menu shortcuts.
+#
+# .. variable:: CPACK_NSIS_DELETE_ICONS_EXTRA
+#
+# Additional NSIS commands to uninstall start menu shortcuts.
+#
+# .. variable:: CPACK_NSIS_EXECUTABLES_DIRECTORY
+#
+# Creating NSIS start menu links assumes that they are in 'bin' unless this
+# variable is set. For example, you would set this to 'exec' if your
+# executables are in an exec directory.
+#
+# .. variable:: CPACK_NSIS_MUI_FINISHPAGE_RUN
+#
+# Specify an executable to add an option to run on the finish page of the
+# NSIS installer.
+#
+# .. variable:: CPACK_NSIS_MENU_LINKS
+#
+# Specify links in [application] menu. This should contain a list of pair
+# "link" "link name". The link may be an URL or a path relative to
+# installation prefix. Like::
+#
+# set(CPACK_NSIS_MENU_LINKS
+# "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake.html"
+# "CMake Help" "https://cmake.org" "CMake Web Site")
+#
#=============================================================================
# Copyright 2006-2009 Kitware, Inc.
diff --git a/Modules/CPackPackageMaker.cmake b/Modules/CPackPackageMaker.cmake
index 98ca9e2d5..416042519 100644
--- a/Modules/CPackPackageMaker.cmake
+++ b/Modules/CPackPackageMaker.cmake
@@ -1,25 +1,27 @@
-##section Variables specific to CPack PackageMaker generator
-##end
-##module
-# - PackageMaker CPack generator (Mac OS X).
-# The following variable is specific to installers built on Mac OS X
-# using PackageMaker:
-##end
+#.rst:
+# CPackPackageMaker
+# -----------------
#
-##variable
-# CPACK_OSX_PACKAGE_VERSION - The version of Mac OS X that the
-# resulting PackageMaker archive should be compatible with. Different
-# versions of Mac OS X support different
-# features. For example, CPack can only build component-based
-# installers for Mac OS X 10.4 or newer, and can only build
-# installers that download component son-the-fly for Mac OS X 10.5
-# or newer. If left blank, this value will be set to the minimum
-# version of Mac OS X that supports the requested features. Set this
-# variable to some value (e.g., 10.4) only if you want to guarantee
-# that your installer will work on that version of Mac OS X, and
-# don't mind missing extra features available in the installer
-# shipping with later versions of Mac OS X.
-##end
+# PackageMaker CPack generator (Mac OS X).
+#
+# Variables specific to CPack PackageMaker generator
+# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#
+# The following variable is specific to installers built on Mac
+# OS X using PackageMaker:
+#
+# .. variable:: CPACK_OSX_PACKAGE_VERSION
+#
+# The version of Mac OS X that the resulting PackageMaker archive should be
+# compatible with. Different versions of Mac OS X support different
+# features. For example, CPack can only build component-based installers for
+# Mac OS X 10.4 or newer, and can only build installers that download
+# component son-the-fly for Mac OS X 10.5 or newer. If left blank, this value
+# will be set to the minimum version of Mac OS X that supports the requested
+# features. Set this variable to some value (e.g., 10.4) only if you want to
+# guarantee that your installer will work on that version of Mac OS X, and
+# don't mind missing extra features available in the installer shipping with
+# later versions of Mac OS X.
#=============================================================================
# Copyright 2006-2012 Kitware, Inc.
diff --git a/Modules/CPackRPM.cmake b/Modules/CPackRPM.cmake
index bf5b5bc62..7fb11c3b4 100644
--- a/Modules/CPackRPM.cmake
+++ b/Modules/CPackRPM.cmake
@@ -1,248 +1,560 @@
-##section Variables specific to CPack RPM generator
-##end
-##module
-# - The builtin (binary) CPack RPM generator (Unix only)
-# CPackRPM may be used to create RPM package using CPack.
-# CPackRPM is a CPack generator thus it uses the CPACK_XXX variables
-# used by CPack : http://www.cmake.org/Wiki/CMake:CPackConfiguration
-#
-# However CPackRPM has specific features which are controlled by
-# the specifics CPACK_RPM_XXX variables. CPackRPM is a component aware
+#.rst:
+# CPackRPM
+# --------
+#
+# The builtin (binary) CPack RPM generator (Unix only)
+#
+# Variables specific to CPack RPM generator
+# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#
+# CPackRPM may be used to create RPM package using CPack. CPackRPM is a
+# CPack generator thus it uses the CPACK_XXX variables used by CPack :
+# https://cmake.org/Wiki/CMake:CPackConfiguration
+#
+# However CPackRPM has specific features which are controlled by the
+# specifics CPACK_RPM_XXX variables. CPackRPM is a component aware
# generator so when CPACK_RPM_COMPONENT_INSTALL is ON some more
-# CPACK_RPM_<ComponentName>_XXXX variables may be used in order
-# to have component specific values. Note however that <componentName>
-# refers to the **grouping name**. This may be either a component name
-# or a component GROUP name.
-# Usually those vars correspond to RPM spec file entities, one may find
-# information about spec files here http://www.rpm.org/wiki/Docs.
-# You'll find a detailed usage of CPackRPM on the wiki:
-# http://www.cmake.org/Wiki/CMake:CPackPackageGenerators#RPM_.28Unix_Only.29
+# CPACK_RPM_<ComponentName>_XXXX variables may be used in order to have
+# component specific values. Note however that <componentName> refers
+# to the **grouping name**. This may be either a component name or a
+# component GROUP name. Usually those vars correspond to RPM spec file
+# entities, one may find information about spec files here
+# http://www.rpm.org/wiki/Docs. You'll find a detailed usage of
+# CPackRPM on the wiki:
+#
+# ::
+#
+# https://cmake.org/Wiki/CMake:CPackPackageGenerators#RPM_.28Unix_Only.29
+#
# However as a handy reminder here comes the list of specific variables:
-##end
-#
-##variable
-# CPACK_RPM_PACKAGE_SUMMARY - The RPM package summary.
-# Mandatory : YES
-# Default : CPACK_PACKAGE_DESCRIPTION_SUMMARY
-##end
-##variable
-# CPACK_RPM_PACKAGE_NAME - The RPM package name.
-# Mandatory : YES
-# Default : CPACK_PACKAGE_NAME
-##end
-##variable
-# CPACK_RPM_PACKAGE_VERSION - The RPM package version.
-# Mandatory : YES
-# Default : CPACK_PACKAGE_VERSION
-##end
-##variable
-# CPACK_RPM_PACKAGE_ARCHITECTURE - The RPM package architecture.
-# Mandatory : NO
-# Default : -
-# This may be set to "noarch" if you
-# know you are building a noarch package.
-##end
-##variable
-# CPACK_RPM_PACKAGE_RELEASE - The RPM package release.
-# Mandatory : YES
-# Default : 1
-# This is the numbering of the RPM package
-# itself, i.e. the version of the packaging and not the version of the
-# content (see CPACK_RPM_PACKAGE_VERSION). One may change the default
-# value if the previous packaging was buggy and/or you want to put here
-# a fancy Linux distro specific numbering.
-##end
-##variable
-# CPACK_RPM_PACKAGE_LICENSE - The RPM package license policy.
-# Mandatory : YES
-# Default : "unknown"
-##end
-##variable
-# CPACK_RPM_PACKAGE_GROUP - The RPM package group.
-# Mandatory : YES
-# Default : "unknown"
-##end
-##variable
-# CPACK_RPM_PACKAGE_VENDOR - The RPM package vendor.
-# Mandatory : YES
-# Default : CPACK_PACKAGE_VENDOR if set or "unknown"
-##end
-##variable
-# CPACK_RPM_PACKAGE_URL - The projects URL.
-# Mandatory : NO
-# Default : -
-##end
-##variable
-# CPACK_RPM_PACKAGE_DESCRIPTION - RPM package description.
-# Mandatory : YES
-# Default : CPACK_PACKAGE_DESCRIPTION_FILE if set or "no package description available"
-##end
-##variable
-# CPACK_RPM_COMPRESSION_TYPE - RPM compression type.
-# Mandatory : NO
-# Default : -
-# May be used to override RPM compression type to be used
-# to build the RPM. For example some Linux distribution now default
-# to lzma or xz compression whereas older cannot use such RPM.
-# Using this one can enforce compression type to be used.
-# Possible value are: lzma, xz, bzip2 and gzip.
-##end
-##variable
-# CPACK_RPM_PACKAGE_REQUIRES - RPM spec requires field.
-# Mandatory : NO
-# Default : -
-# May be used to set RPM dependencies (requires).
-# Note that you must enclose the complete requires string between quotes,
-# for example:
-# set(CPACK_RPM_PACKAGE_REQUIRES "python >= 2.5.0, cmake >= 2.8")
-# The required package list of an RPM file could be printed with
-# rpm -qp --requires file.rpm
-##end
-##variable
-# CPACK_RPM_PACKAGE_SUGGESTS - RPM spec suggest field.
-# Mandatory : NO
-# Default : -
-# May be used to set weak RPM dependencies (suggests).
-# Note that you must enclose the complete requires string between quotes.
-##end
-##variable
-# CPACK_RPM_PACKAGE_PROVIDES - RPM spec provides field.
-# Mandatory : NO
-# Default : -
-# May be used to set RPM dependencies (provides).
-# The provided package list of an RPM file could be printed with
-# rpm -qp --provides file.rpm
-##end
-##variable
-# CPACK_RPM_PACKAGE_OBSOLETES - RPM spec obsoletes field.
-# Mandatory : NO
-# Default : -
-# May be used to set RPM packages that are obsoleted by this one.
-##end
-##variable
-# CPACK_RPM_PACKAGE_RELOCATABLE - build a relocatable RPM.
-# Mandatory : NO
-# Default : CPACK_PACKAGE_RELOCATABLE
-# If this variable is set to TRUE or ON CPackRPM will try
-# to build a relocatable RPM package. A relocatable RPM may
-# be installed using rpm --prefix or --relocate in order to
-# install it at an alternate place see rpm(8).
-# Note that currently this may fail if CPACK_SET_DESTDIR is set to ON.
-# If CPACK_SET_DESTDIR is set then you will get a warning message
-# but if there is file installed with absolute path you'll get
-# unexpected behavior.
-##end
-##variable
-# CPACK_RPM_SPEC_INSTALL_POST - [deprecated].
-# Mandatory : NO
-# Default : -
-# This way of specifying post-install script is deprecated use
-# CPACK_RPM_POST_INSTALL_SCRIPT_FILE
-# May be used to set an RPM post-install command inside the spec file.
-# For example setting it to "/bin/true" may be used to prevent
-# rpmbuild to strip binaries.
-##end
-##variable
-# CPACK_RPM_SPEC_MORE_DEFINE - RPM extended spec definitions lines.
-# Mandatory : NO
-# Default : -
-# May be used to add any %define lines to the generated spec file.
-##end
-##variable
-# CPACK_RPM_PACKAGE_DEBUG - Toggle CPackRPM debug output.
-# Mandatory : NO
-# Default : -
-# May be set when invoking cpack in order to trace debug information
-# during CPack RPM run. For example you may launch CPack like this
-# cpack -D CPACK_RPM_PACKAGE_DEBUG=1 -G RPM
-##end
-##variable
-# CPACK_RPM_USER_BINARY_SPECFILE - A user provided spec file.
-# Mandatory : NO
-# Default : -
-# May be set by the user in order to specify a USER binary spec file
-# to be used by CPackRPM instead of generating the file.
-# The specified file will be processed by configure_file( @ONLY).
-# One can provide a component specific file by setting
-# CPACK_RPM_<componentName>_USER_BINARY_SPECFILE.
-##end
-##variable
-# CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE - Spec file template.
-# Mandatory : NO
-# Default : -
-# If set CPack will generate a template for USER specified binary
-# spec file and stop with an error. For example launch CPack like this
-# cpack -D CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE=1 -G RPM
-# The user may then use this file in order to hand-craft is own
-# binary spec file which may be used with CPACK_RPM_USER_BINARY_SPECFILE.
-##end
-##variable
-# CPACK_RPM_PRE_INSTALL_SCRIPT_FILE
-# CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE
-# Mandatory : NO
-# Default : -
-# May be used to embed a pre (un)installation script in the spec file.
-# The refered script file(s) will be read and directly
-# put after the %pre or %preun section
-# If CPACK_RPM_COMPONENT_INSTALL is set to ON the (un)install script for
-# each component can be overridden with
-# CPACK_RPM_<COMPONENT>_PRE_INSTALL_SCRIPT_FILE and
-# CPACK_RPM_<COMPONENT>_PRE_UNINSTALL_SCRIPT_FILE
-# One may verify which scriptlet has been included with
-# rpm -qp --scripts package.rpm
-##end
-##variable
-# CPACK_RPM_POST_INSTALL_SCRIPT_FILE
-# CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE
-# Mandatory : NO
-# Default : -
-# May be used to embed a post (un)installation script in the spec file.
-# The refered script file(s) will be read and directly
-# put after the %post or %postun section
-# If CPACK_RPM_COMPONENT_INSTALL is set to ON the (un)install script for
-# each component can be overridden with
-# CPACK_RPM_<COMPONENT>_POST_INSTALL_SCRIPT_FILE and
-# CPACK_RPM_<COMPONENT>_POST_UNINSTALL_SCRIPT_FILE
-# One may verify which scriptlet has been included with
-# rpm -qp --scripts package.rpm
-##end
-##variable
-# CPACK_RPM_USER_FILELIST
-# CPACK_RPM_<COMPONENT>_USER_FILELIST
-# Mandatory : NO
-# Default : -
-# May be used to explicitly specify %(<directive>) file line
-# in the spec file. Like %config(noreplace) or any other directive
-# that be found in the %files section. Since CPackRPM is generating
-# the list of files (and directories) the user specified files of
-# the CPACK_RPM_<COMPONENT>_USER_FILELIST list will be removed from the generated list.
-##end
-##variable
-# CPACK_RPM_CHANGELOG_FILE - RPM changelog file.
-# Mandatory : NO
-# Default : -
-# May be used to embed a changelog in the spec file.
-# The refered file will be read and directly put after the %changelog
-# section.
-##end
-##variable
-# CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST - list of path to be excluded.
-# Mandatory : NO
-# Default : /etc /etc/init.d /usr /usr/share /usr/share/doc /usr/bin /usr/lib /usr/lib64 /usr/include
-# May be used to exclude path (directories or files) from the auto-generated
-# list of paths discovered by CPack RPM. The defaut value contains a reasonable
-# set of values if the variable is not defined by the user. If the variable
-# is defined by the user then CPackRPM will NOT any of the default path.
-# If you want to add some path to the default list then you can use
-# CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION variable.
-##end
-##variable
-# CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION - additional list of path to be excluded.
-# Mandatory : NO
-# Default : -
-# May be used to add more exclude path (directories or files) from the initial
-# default list of excluded paths. See CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST.
-##end
+#
+# .. variable:: CPACK_RPM_PACKAGE_SUMMARY
+# CPACK_RPM_<component>_PACKAGE_SUMMARY
+#
+# The RPM package summary.
+#
+# * Mandatory : YES
+# * Default : CPACK_PACKAGE_DESCRIPTION_SUMMARY
+#
+# .. variable:: CPACK_RPM_PACKAGE_NAME
+# CPACK_RPM_<component>_PACKAGE_NAME
+#
+# The RPM package name.
+#
+# * Mandatory : YES
+# * Default : CPACK_PACKAGE_NAME
+#
+# .. variable:: CPACK_RPM_PACKAGE_VERSION
+#
+# The RPM package version.
+#
+# * Mandatory : YES
+# * Default : CPACK_PACKAGE_VERSION
+#
+# .. variable:: CPACK_RPM_PACKAGE_ARCHITECTURE
+# CPACK_RPM_<component>_PACKAGE_ARCHITECTURE
+#
+# The RPM package architecture.
+#
+# * Mandatory : YES
+# * Default : Native architecture output by "uname -m"
+#
+# This may be set to "noarch" if you know you are building a noarch package.
+#
+# .. variable:: CPACK_RPM_PACKAGE_RELEASE
+#
+# The RPM package release.
+#
+# * Mandatory : YES
+# * Default : 1
+#
+# This is the numbering of the RPM package itself, i.e. the version of the
+# packaging and not the version of the content (see
+# CPACK_RPM_PACKAGE_VERSION). One may change the default value if the
+# previous packaging was buggy and/or you want to put here a fancy Linux
+# distro specific numbering.
+#
+# .. variable:: CPACK_RPM_PACKAGE_LICENSE
+#
+# The RPM package license policy.
+#
+# * Mandatory : YES
+# * Default : "unknown"
+#
+# .. variable:: CPACK_RPM_PACKAGE_GROUP
+# CPACK_RPM_<component>_PACKAGE_GROUP
+#
+# The RPM package group.
+#
+# * Mandatory : YES
+# * Default : "unknown"
+#
+# .. variable:: CPACK_RPM_PACKAGE_VENDOR
+#
+# The RPM package vendor.
+#
+# * Mandatory : YES
+# * Default : CPACK_PACKAGE_VENDOR if set or "unknown"
+#
+# .. variable:: CPACK_RPM_PACKAGE_URL
+# CPACK_RPM_<component>_PACKAGE_URL
+#
+# The projects URL.
+#
+# * Mandatory : NO
+# * Default : -
+#
+# .. variable:: CPACK_RPM_PACKAGE_DESCRIPTION
+# CPACK_RPM_<component>_PACKAGE_DESCRIPTION
+#
+# RPM package description.
+#
+# * Mandatory : YES
+# * Default : CPACK_COMPONENT_<compName>_DESCRIPTION (component based installers
+# only) if set, CPACK_PACKAGE_DESCRIPTION_FILE if set or "no package
+# description available"
+#
+# .. variable:: CPACK_RPM_COMPRESSION_TYPE
+#
+# RPM compression type.
+#
+# * Mandatory : NO
+# * Default : -
+#
+# May be used to override RPM compression type to be used to build the
+# RPM. For example some Linux distribution now default to lzma or xz
+# compression whereas older cannot use such RPM. Using this one can enforce
+# compression type to be used. Possible value are: lzma, xz, bzip2 and gzip.
+#
+# .. variable:: CPACK_RPM_PACKAGE_AUTOREQ
+# CPACK_RPM_<component>_PACKAGE_AUTOREQ
+#
+# RPM spec autoreq field.
+#
+# * Mandatory : NO
+# * Default : -
+#
+# May be used to enable (1, yes) or disable (0, no) automatic shared libraries
+# dependency detection. Dependencies are added to requires list.
+#
+# .. note::
+#
+# By defalut automatic dependency detection is enabled by rpm generator.
+#
+# .. variable:: CPACK_RPM_PACKAGE_AUTOPROV
+# CPACK_RPM_<component>_PACKAGE_AUTOPROV
+#
+# RPM spec autoprov field.
+#
+# * Mandatory : NO
+# * Default : -
+#
+# May be used to enable (1, yes) or disable (0, no) automatic listing of shared
+# libraries that are provided by the package. Shared libraries are added to
+# provides list.
+#
+# .. note::
+#
+# By defalut automatic provides detection is enabled by rpm generator.
+#
+# .. variable:: CPACK_RPM_PACKAGE_AUTOREQPROV
+# CPACK_RPM_<component>_PACKAGE_AUTOREQPROV
+#
+# RPM spec autoreqprov field.
+#
+# * Mandatory : NO
+# * Default : -
+#
+# Variable enables/disables autoreq and autoprov at the same time.
+# See :variable:`CPACK_RPM_PACKAGE_AUTOREQ` and :variable:`CPACK_RPM_PACKAGE_AUTOPROV`
+# for more details.
+#
+# .. note::
+#
+# By defalut automatic detection feature is enabled by rpm.
+#
+# .. variable:: CPACK_RPM_PACKAGE_REQUIRES
+# CPACK_RPM_<component>_PACKAGE_REQUIRES
+#
+# RPM spec requires field.
+#
+# * Mandatory : NO
+# * Default : -
+#
+# May be used to set RPM dependencies (requires). Note that you must enclose
+# the complete requires string between quotes, for example::
+#
+# set(CPACK_RPM_PACKAGE_REQUIRES "python >= 2.5.0, cmake >= 2.8")
+#
+# The required package list of an RPM file could be printed with::
+#
+# rpm -qp --requires file.rpm
+#
+# .. variable:: CPACK_RPM_PACKAGE_CONFLICTS
+# CPACK_RPM_<component>_PACKAGE_CONFLICTS
+#
+# RPM spec conflicts field.
+#
+# * Mandatory : NO
+# * Default : -
+#
+# May be used to set negative RPM dependencies (conflicts). Note that you must enclose
+# the complete requires string between quotes, for example::
+#
+# set(CPACK_RPM_PACKAGE_CONFLICTS "libxml2")
+#
+# The conflicting package list of an RPM file could be printed with::
+#
+# rpm -qp --conflicts file.rpm
+#
+# .. variable:: CPACK_RPM_PACKAGE_REQUIRES_PRE
+# CPACK_RPM_<component>_PACKAGE_REQUIRES_PRE
+#
+# RPM spec requires(pre) field.
+#
+# * Mandatory : NO
+# * Default : -
+#
+# May be used to set RPM preinstall dependencies (requires(pre)). Note that you must enclose
+# the complete requires string between quotes, for example::
+#
+# set(CPACK_RPM_PACKAGE_REQUIRES_PRE "shadow-utils, initscripts")
+#
+# .. variable:: CPACK_RPM_PACKAGE_REQUIRES_POST
+# CPACK_RPM_<component>_PACKAGE_REQUIRES_POST
+#
+# RPM spec requires(post) field.
+#
+# * Mandatory : NO
+# * Default : -
+#
+# May be used to set RPM postinstall dependencies (requires(post)). Note that you must enclose
+# the complete requires string between quotes, for example::
+#
+# set(CPACK_RPM_PACKAGE_REQUIRES_POST "shadow-utils, initscripts")
+#
+#
+# .. variable:: CPACK_RPM_PACKAGE_REQUIRES_POSTUN
+# CPACK_RPM_<component>_PACKAGE_REQUIRES_POSTUN
+#
+# RPM spec requires(postun) field.
+#
+# * Mandatory : NO
+# * Default : -
+#
+# May be used to set RPM postuninstall dependencies (requires(postun)). Note that you must enclose
+# the complete requires string between quotes, for example::
+#
+# set(CPACK_RPM_PACKAGE_REQUIRES_POSTUN "shadow-utils, initscripts")
+#
+#
+# .. variable:: CPACK_RPM_PACKAGE_REQUIRES_PREUN
+# CPACK_RPM_<component>_PACKAGE_REQUIRES_PREUN
+#
+# RPM spec requires(preun) field.
+#
+# * Mandatory : NO
+# * Default : -
+#
+# May be used to set RPM preuninstall dependencies (requires(preun)). Note that you must enclose
+# the complete requires string between quotes, for example::
+#
+# set(CPACK_RPM_PACKAGE_REQUIRES_PREUN "shadow-utils, initscripts")
+#
+# .. variable:: CPACK_RPM_PACKAGE_SUGGESTS
+# CPACK_RPM_<component>_PACKAGE_SUGGESTS
+#
+# RPM spec suggest field.
+#
+# * Mandatory : NO
+# * Default : -
+#
+# May be used to set weak RPM dependencies (suggests). Note that you must
+# enclose the complete requires string between quotes.
+#
+# .. variable:: CPACK_RPM_PACKAGE_PROVIDES
+# CPACK_RPM_<component>_PACKAGE_PROVIDES
+#
+# RPM spec provides field.
+#
+# * Mandatory : NO
+# * Default : -
+#
+# May be used to set RPM dependencies (provides). The provided package list
+# of an RPM file could be printed with::
+#
+# rpm -qp --provides file.rpm
+#
+# .. variable:: CPACK_RPM_PACKAGE_OBSOLETES
+# CPACK_RPM_<component>_PACKAGE_OBSOLETES
+#
+# RPM spec obsoletes field.
+#
+# * Mandatory : NO
+# * Default : -
+#
+# May be used to set RPM packages that are obsoleted by this one.
+#
+# .. variable:: CPACK_RPM_PACKAGE_RELOCATABLE
+#
+# build a relocatable RPM.
+#
+# * Mandatory : NO
+# * Default : CPACK_PACKAGE_RELOCATABLE
+#
+# If this variable is set to TRUE or ON CPackRPM will try
+# to build a relocatable RPM package. A relocatable RPM may
+# be installed using::
+#
+# rpm --prefix or --relocate
+#
+# in order to install it at an alternate place see rpm(8). Note that
+# currently this may fail if CPACK_SET_DESTDIR is set to ON. If
+# CPACK_SET_DESTDIR is set then you will get a warning message but if there
+# is file installed with absolute path you'll get unexpected behavior.
+#
+# .. variable:: CPACK_RPM_SPEC_INSTALL_POST
+#
+# * Mandatory : NO
+# * Default : -
+# * Deprecated: YES
+#
+# This way of specifying post-install script is deprecated, use
+# CPACK_RPM_POST_INSTALL_SCRIPT_FILE.
+# May be used to set an RPM post-install command inside the spec file.
+# For example setting it to "/bin/true" may be used to prevent
+# rpmbuild to strip binaries.
+#
+# .. variable:: CPACK_RPM_SPEC_MORE_DEFINE
+#
+# RPM extended spec definitions lines.
+#
+# * Mandatory : NO
+# * Default : -
+#
+# May be used to add any %define lines to the generated spec file.
+#
+# .. variable:: CPACK_RPM_PACKAGE_DEBUG
+#
+# Toggle CPackRPM debug output.
+#
+# * Mandatory : NO
+# * Default : -
+#
+# May be set when invoking cpack in order to trace debug information
+# during CPack RPM run. For example you may launch CPack like this::
+#
+# cpack -D CPACK_RPM_PACKAGE_DEBUG=1 -G RPM
+#
+# .. variable:: CPACK_RPM_USER_BINARY_SPECFILE
+#
+# A user provided spec file.
+#
+# * Mandatory : NO
+# * Default : -
+#
+# May be set by the user in order to specify a USER binary spec file
+# to be used by CPackRPM instead of generating the file.
+# The specified file will be processed by configure_file( @ONLY).
+# One can provide a component specific file by setting
+# CPACK_RPM_<componentName>_USER_BINARY_SPECFILE.
+#
+# .. variable:: CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE
+#
+# Spec file template.
+#
+# * Mandatory : NO
+# * Default : -
+#
+# If set CPack will generate a template for USER specified binary
+# spec file and stop with an error. For example launch CPack like this::
+#
+# cpack -D CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE=1 -G RPM
+#
+# The user may then use this file in order to hand-craft is own
+# binary spec file which may be used with CPACK_RPM_USER_BINARY_SPECFILE.
+#
+# .. variable:: CPACK_RPM_PRE_INSTALL_SCRIPT_FILE
+# CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE
+#
+# * Mandatory : NO
+# * Default : -
+#
+# May be used to embed a pre (un)installation script in the spec file.
+# The refered script file(s) will be read and directly
+# put after the %pre or %preun section
+# If CPACK_RPM_COMPONENT_INSTALL is set to ON the (un)install script for
+# each component can be overridden with
+# CPACK_RPM_<COMPONENT>_PRE_INSTALL_SCRIPT_FILE and
+# CPACK_RPM_<COMPONENT>_PRE_UNINSTALL_SCRIPT_FILE.
+# One may verify which scriptlet has been included with::
+#
+# rpm -qp --scripts package.rpm
+#
+# .. variable:: CPACK_RPM_POST_INSTALL_SCRIPT_FILE
+# CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE
+#
+# * Mandatory : NO
+# * Default : -
+#
+# May be used to embed a post (un)installation script in the spec file.
+# The refered script file(s) will be read and directly
+# put after the %post or %postun section.
+# If CPACK_RPM_COMPONENT_INSTALL is set to ON the (un)install script for
+# each component can be overridden with
+# CPACK_RPM_<COMPONENT>_POST_INSTALL_SCRIPT_FILE and
+# CPACK_RPM_<COMPONENT>_POST_UNINSTALL_SCRIPT_FILE.
+# One may verify which scriptlet has been included with::
+#
+# rpm -qp --scripts package.rpm
+#
+# .. variable:: CPACK_RPM_USER_FILELIST
+# CPACK_RPM_<COMPONENT>_USER_FILELIST
+#
+# * Mandatory : NO
+# * Default : -
+#
+# May be used to explicitly specify %(<directive>) file line
+# in the spec file. Like %config(noreplace) or any other directive
+# that be found in the %files section. Since CPackRPM is generating
+# the list of files (and directories) the user specified files of
+# the CPACK_RPM_<COMPONENT>_USER_FILELIST list will be removed from
+# the generated list.
+#
+# .. variable:: CPACK_RPM_CHANGELOG_FILE
+#
+# RPM changelog file.
+#
+# * Mandatory : NO
+# * Default : -
+#
+# May be used to embed a changelog in the spec file.
+# The refered file will be read and directly put after the %changelog
+# section.
+#
+# .. variable:: CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST
+#
+# list of path to be excluded.
+#
+# * Mandatory : NO
+# * Default : /etc /etc/init.d /usr /usr/share /usr/share/doc /usr/bin /usr/lib /usr/lib64 /usr/include
+#
+# May be used to exclude path (directories or files) from the auto-generated
+# list of paths discovered by CPack RPM. The defaut value contains a
+# reasonable set of values if the variable is not defined by the user. If the
+# variable is defined by the user then CPackRPM will NOT any of the default
+# path. If you want to add some path to the default list then you can use
+# CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION variable.
+#
+# .. variable:: CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION
+#
+# additional list of path to be excluded.
+#
+# * Mandatory : NO
+# * Default : -
+#
+# May be used to add more exclude path (directories or files) from the initial
+# default list of excluded paths. See CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST.
+#
+# .. variable:: CPACK_RPM_RELOCATION_PATHS
+#
+# * Mandatory : NO
+# * Default : -
+#
+# May be used to specify more than one relocation path per relocatable RPM.
+# Variable contains a list of relocation paths that if relative are prefixed
+# by the value of CPACK_RPM_<COMPONENT>_PACKAGE_PREFIX or by the value of
+# CPACK_PACKAGING_INSTALL_PREFIX if the component version is not provided.
+# Variable is not component based as its content can be used to set a different
+# path prefix for e.g. binary dir and documentation dir at the same time.
+# Only prefixes that are required by a certain component are added to that
+# component - component must contain at least one file/directory/symbolic link
+# with CPACK_RPM_RELOCATION_PATHS prefix for a certain relocation path
+# to be added. Package will not contain any relocation paths if there are no
+# files/directories/symbolic links on any of the provided prefix locations.
+# Packages that either do not contain any relocation paths or contain
+# files/directories/symbolic links that are outside relocation paths print
+# out an AUTHOR_WARNING that RPM will be partially relocatable.
+#
+# .. variable:: CPACK_RPM_<COMPONENT>_PACKAGE_PREFIX
+#
+# * Mandatory : NO
+# * Default : CPACK_PACKAGING_INSTALL_PREFIX
+#
+# May be used to set per component CPACK_PACKAGING_INSTALL_PREFIX for
+# relocatable RPM packages.
+#
+# .. variable:: CPACK_RPM_NO_INSTALL_PREFIX_RELOCATION
+# CPACK_RPM_NO_<COMPONENT>_INSTALL_PREFIX_RELOCATION
+#
+# * Mandatory : NO
+# * Default : CPACK_PACKAGING_INSTALL_PREFIX or CPACK_RPM_<COMPONENT>_PACKAGE_PREFIX
+# are treated as one of relocation paths
+#
+# May be used to remove CPACK_PACKAGING_INSTALL_PREFIX and CPACK_RPM_<COMPONENT>_PACKAGE_PREFIX
+# from relocatable RPM prefix paths.
+#
+# .. variable:: CPACK_RPM_ADDITIONAL_MAN_DIRS
+#
+# * Mandatory : NO
+# * Default : -
+#
+# May be used to set additional man dirs that could potentially be compressed
+# by brp-compress RPM macro. Variable content must be a list of regular
+# expressions that point to directories containing man files or to man files
+# directly. Note that in order to compress man pages a path must also be
+# present in brp-compress RPM script and that brp-compress script must be
+# added to RPM configuration by the operating system.
+#
+# Regular expressions that are added by default were taken from brp-compress
+# RPM macro:
+#
+# - /usr/man/man.*
+# - /usr/man/.*/man.*
+# - /usr/info.*
+# - /usr/share/man/man.*
+# - /usr/share/man/.*/man.*
+# - /usr/share/info.*
+# - /usr/kerberos/man.*
+# - /usr/X11R6/man/man.*
+# - /usr/lib/perl5/man/man.*
+# - /usr/share/doc/.*/man/man.*
+# - /usr/lib/.*/man/man.*
+#
+# Packaging of Symbolic Links
+# ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#
+# CPackRPM supports packaging of symbolic links::
+#
+# execute_process(COMMAND ${CMAKE_COMMAND}
+# -E create_symlink <relative_path_location> <symlink_name>)
+# install(FILES ${CMAKE_CURRENT_BINARY_DIR}/<symlink_name>
+# DESTINATION <symlink_location> COMPONENT libraries)
+#
+# Symbolic links will be optimized (paths will be shortened if possible)
+# before being added to the package or if multiple relocation paths are
+# detected, a post install symlink relocation script will be generated.
+#
+# Symbolic links may point to locations that are not packaged by the same
+# package (either a different component or even not packaged at all) but
+# those locations will be treated as if they were a part of the package
+# while determining if symlink should be either created or present in a
+# post install script - depending on relocation paths.
+#
+# Currenty there are a few limitations though:
+#
+# * Only symbolic links with relative path can be packaged.
+#
+# * For component based packaging component interdependency is not checked
+# when processing symbolic links. Symbolic links pointing to content of
+# a different component are treated the same way as if pointing to location
+# that will not be packaged.
+#
+# * Symbolic links pointing to a location through one or more intermediate
+# symbolic links will not be handled differently - if the intermediate
+# symbolic link(s) is also on a relocatable path, relocating it during
+# package installation may cause initial symbolic link to point to an
+# invalid location.
#=============================================================================
# Copyright 2007-2009 Kitware, Inc.
@@ -259,6 +571,471 @@
# Author: Eric Noulard with the help of Alexander Neundorf.
+function(cpack_rpm_prepare_relocation_paths)
+ # set appropriate prefix, remove possible trailing slash and convert backslashes to slashes
+ if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_PREFIX)
+ file(TO_CMAKE_PATH "${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_PREFIX}" PATH_PREFIX)
+ else()
+ file(TO_CMAKE_PATH "${CPACK_PACKAGING_INSTALL_PREFIX}" PATH_PREFIX)
+ endif()
+
+ set(RPM_RELOCATION_PATHS "${CPACK_RPM_RELOCATION_PATHS}")
+ list(REMOVE_DUPLICATES RPM_RELOCATION_PATHS)
+
+ # set base path prefix
+ if(EXISTS "${WDIR}/${PATH_PREFIX}")
+ if(NOT CPACK_RPM_NO_INSTALL_PREFIX_RELOCATION AND
+ NOT CPACK_RPM_NO_${CPACK_RPM_PACKAGE_COMPONENT}_INSTALL_PREFIX_RELOCATION)
+ set(TMP_RPM_PREFIXES "${TMP_RPM_PREFIXES}Prefix: ${PATH_PREFIX}\n")
+ list(APPEND RPM_USED_PACKAGE_PREFIXES "${PATH_PREFIX}")
+
+ if(CPACK_RPM_PACKAGE_DEBUG)
+ message("CPackRPM:Debug: removing '${PATH_PREFIX}' from relocation paths")
+ endif()
+ endif()
+ endif()
+
+ # set other path prefixes
+ foreach(RELOCATION_PATH ${RPM_RELOCATION_PATHS})
+ if(IS_ABSOLUTE "${RELOCATION_PATH}")
+ set(PREPARED_RELOCATION_PATH "${RELOCATION_PATH}")
+ else()
+ set(PREPARED_RELOCATION_PATH "${PATH_PREFIX}/${RELOCATION_PATH}")
+ endif()
+
+ if(EXISTS "${WDIR}/${PREPARED_RELOCATION_PATH}")
+ set(TMP_RPM_PREFIXES "${TMP_RPM_PREFIXES}Prefix: ${PREPARED_RELOCATION_PATH}\n")
+ list(APPEND RPM_USED_PACKAGE_PREFIXES "${PREPARED_RELOCATION_PATH}")
+ endif()
+ endforeach()
+
+ # warn about all the paths that are not relocatable
+ cmake_policy(PUSH)
+ # Tell file(GLOB_RECURSE) not to follow directory symlinks
+ # even if the project does not set this policy to NEW.
+ cmake_policy(SET CMP0009 NEW)
+ file(GLOB_RECURSE FILE_PATHS_ "${WDIR}/*")
+ cmake_policy(POP)
+ foreach(TMP_PATH ${FILE_PATHS_})
+ string(LENGTH "${WDIR}" WDIR_LEN)
+ string(SUBSTRING "${TMP_PATH}" ${WDIR_LEN} -1 TMP_PATH)
+ unset(TMP_PATH_FOUND_)
+
+ foreach(RELOCATION_PATH ${RPM_USED_PACKAGE_PREFIXES})
+ file(RELATIVE_PATH REL_PATH_ "${RELOCATION_PATH}" "${TMP_PATH}")
+ string(SUBSTRING "${REL_PATH_}" 0 2 PREFIX_)
+
+ if(NOT "${PREFIX_}" STREQUAL "..")
+ set(TPM_PATH_FOUND_ TRUE)
+ break()
+ endif()
+ endforeach()
+
+ if(NOT TPM_PATH_FOUND_)
+ message(AUTHOR_WARNING "CPackRPM:Warning: Path ${TMP_PATH} is not on one of the relocatable paths! Package will be partially relocatable.")
+ endif()
+ endforeach()
+
+ set(RPM_USED_PACKAGE_PREFIXES "${RPM_USED_PACKAGE_PREFIXES}" PARENT_SCOPE)
+ set(TMP_RPM_PREFIXES "${TMP_RPM_PREFIXES}" PARENT_SCOPE)
+endfunction()
+
+function(cpack_rpm_prepare_content_list)
+ # get files list
+ cmake_policy(PUSH)
+ cmake_policy(SET CMP0009 NEW)
+ file(GLOB_RECURSE CPACK_RPM_INSTALL_FILES LIST_DIRECTORIES true RELATIVE "${WDIR}" "${WDIR}/*")
+ cmake_policy(POP)
+ set(CPACK_RPM_INSTALL_FILES "/${CPACK_RPM_INSTALL_FILES}")
+ string(REPLACE ";" ";/" CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}")
+
+ # if we are creating a relocatable package, omit parent directories of
+ # CPACK_RPM_PACKAGE_PREFIX. This is achieved by building a "filter list"
+ # which is passed to the find command that generates the content-list
+ if(CPACK_RPM_PACKAGE_RELOCATABLE)
+ # get a list of the elements in CPACK_RPM_PACKAGE_PREFIXES that are
+ # destinct parent paths of other relocation paths and remove the
+ # final element (so the install-prefix dir itself is not omitted
+ # from the RPM's content-list)
+ list(SORT RPM_USED_PACKAGE_PREFIXES)
+ set(_DISTINCT_PATH "NOT_SET")
+ foreach(_RPM_RELOCATION_PREFIX ${RPM_USED_PACKAGE_PREFIXES})
+ if(NOT "${_RPM_RELOCATION_PREFIX}" MATCHES "${_DISTINCT_PATH}/.*")
+ set(_DISTINCT_PATH "${_RPM_RELOCATION_PREFIX}")
+
+ string(REPLACE "/" ";" _CPACK_RPM_PACKAGE_PREFIX_ELEMS " ${_RPM_RELOCATION_PREFIX}")
+ list(REMOVE_AT _CPACK_RPM_PACKAGE_PREFIX_ELEMS -1)
+ unset(_TMP_LIST)
+ # Now generate all of the parent dirs of the relocation path
+ foreach(_PREFIX_PATH_ELEM ${_CPACK_RPM_PACKAGE_PREFIX_ELEMS})
+ list(APPEND _TMP_LIST "${_PREFIX_PATH_ELEM}")
+ string(REPLACE ";" "/" _OMIT_DIR "${_TMP_LIST}")
+ separate_arguments(_OMIT_DIR)
+ list(APPEND _RPM_DIRS_TO_OMIT ${_OMIT_DIR})
+ endforeach()
+ endif()
+ endforeach()
+ endif()
+
+ if(CPACK_RPM_PACKAGE_DEBUG)
+ message("CPackRPM:Debug: Initial list of path to OMIT in RPM: ${_RPM_DIRS_TO_OMIT}")
+ endif()
+
+ if(NOT DEFINED CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST)
+ set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST /etc /etc/init.d /usr /usr/share /usr/share/doc /usr/bin /usr/lib /usr/lib64 /usr/include)
+ if(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION)
+ message("CPackRPM:Debug: Adding ${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION} to builtin omit list.")
+ list(APPEND CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST "${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION}")
+ endif()
+ endif()
+
+ if(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST)
+ if(CPACK_RPM_PACKAGE_DEBUG)
+ message("CPackRPM:Debug: CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST= ${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST}")
+ endif()
+ list(APPEND _RPM_DIRS_TO_OMIT ${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST})
+ endif()
+
+ if(CPACK_RPM_PACKAGE_DEBUG)
+ message("CPackRPM:Debug: Final list of path to OMIT in RPM: ${_RPM_DIRS_TO_OMIT}")
+ endif()
+
+ list(REMOVE_ITEM CPACK_RPM_INSTALL_FILES ${_RPM_DIRS_TO_OMIT})
+
+ # add man paths that will be compressed
+ # (copied from /usr/lib/rpm/brp-compress - script that does the actual
+ # compressing)
+ list(APPEND MAN_LOCATIONS "/usr/man/man.*" "/usr/man/.*/man.*" "/usr/info.*"
+ "/usr/share/man/man.*" "/usr/share/man/.*/man.*" "/usr/share/info.*"
+ "/usr/kerberos/man.*" "/usr/X11R6/man/man.*" "/usr/lib/perl5/man/man.*"
+ "/usr/share/doc/.*/man/man.*" "/usr/lib/.*/man/man.*")
+
+ if(CPACK_RPM_ADDITIONAL_MAN_DIRS)
+ if(CPACK_RPM_PACKAGE_DEBUG)
+ message("CPackRPM:Debug: CPACK_RPM_ADDITIONAL_MAN_DIRS= ${CPACK_RPM_ADDITIONAL_MAN_DIRS}")
+ endif()
+ list(APPEND MAN_LOCATIONS ${CPACK_RPM_ADDITIONAL_MAN_DIRS})
+ endif()
+
+ foreach(PACK_LOCATION IN LISTS CPACK_RPM_INSTALL_FILES)
+ foreach(MAN_LOCATION IN LISTS MAN_LOCATIONS)
+ # man pages are files inside a certain location
+ if(PACK_LOCATION MATCHES "${MAN_LOCATION}/"
+ AND NOT IS_DIRECTORY "${WDIR}${PACK_LOCATION}"
+ AND NOT IS_SYMLINK "${WDIR}${PACK_LOCATION}")
+ list(FIND CPACK_RPM_INSTALL_FILES "${PACK_LOCATION}" INDEX)
+ # insert file location that covers compressed man pages
+ # even if using a wildcard causes duplicates as those are
+ # handled by RPM and we still keep the same file list
+ # in spec file - wildcard only represents file type (e.g. .gz)
+ list(INSERT CPACK_RPM_INSTALL_FILES ${INDEX} "${PACK_LOCATION}*")
+ # remove file location that doesn't cover compressed man pages
+ math(EXPR INDEX ${INDEX}+1)
+ list(REMOVE_AT CPACK_RPM_INSTALL_FILES ${INDEX})
+
+ break()
+ endif()
+ endforeach()
+ endforeach()
+
+ set(CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}" PARENT_SCOPE)
+endfunction()
+
+function(cpack_rpm_symlink_get_relocation_prefixes LOCATION PACKAGE_PREFIXES RETURN_VARIABLE)
+ foreach(PKG_PREFIX IN LISTS PACKAGE_PREFIXES)
+ string(REGEX MATCH "^${PKG_PREFIX}/.*" FOUND_ "${LOCATION}")
+ if(FOUND_)
+ list(APPEND TMP_PREFIXES "${PKG_PREFIX}")
+ endif()
+ endforeach()
+
+ set(${RETURN_VARIABLE} "${TMP_PREFIXES}" PARENT_SCOPE)
+endfunction()
+
+function(cpack_rpm_symlink_create_relocation_script PACKAGE_PREFIXES)
+ list(LENGTH PACKAGE_PREFIXES LAST_INDEX)
+ set(SORTED_PACKAGE_PREFIXES "${PACKAGE_PREFIXES}")
+ list(SORT SORTED_PACKAGE_PREFIXES)
+ list(REVERSE SORTED_PACKAGE_PREFIXES)
+ math(EXPR LAST_INDEX ${LAST_INDEX}-1)
+
+ foreach(SYMLINK_INDEX RANGE ${LAST_INDEX})
+ list(GET SORTED_PACKAGE_PREFIXES ${SYMLINK_INDEX} SRC_PATH)
+ list(FIND PACKAGE_PREFIXES "${SRC_PATH}" SYMLINK_INDEX) # reverse magic
+ string(LENGTH "${SRC_PATH}" SRC_PATH_LEN)
+
+ set(PARTS_CNT 0)
+ set(SCRIPT_PART "if [ \"$RPM_INSTALL_PREFIX${SYMLINK_INDEX}\" != \"${SRC_PATH}\" ]; then\n")
+
+ # both paths relocated
+ foreach(POINT_INDEX RANGE ${LAST_INDEX})
+ list(GET SORTED_PACKAGE_PREFIXES ${POINT_INDEX} POINT_PATH)
+ list(FIND PACKAGE_PREFIXES "${POINT_PATH}" POINT_INDEX) # reverse magic
+ string(LENGTH "${POINT_PATH}" POINT_PATH_LEN)
+
+ if(_RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_${POINT_INDEX})
+ if("${SYMLINK_INDEX}" EQUAL "${POINT_INDEX}")
+ set(INDENT "")
+ else()
+ set(SCRIPT_PART "${SCRIPT_PART} if [ \"$RPM_INSTALL_PREFIX${POINT_INDEX}\" != \"${POINT_PATH}\" ]; then\n")
+ set(INDENT " ")
+ endif()
+
+ foreach(RELOCATION_NO IN LISTS _RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_${POINT_INDEX})
+ math(EXPR PARTS_CNT ${PARTS_CNT}+1)
+
+ math(EXPR RELOCATION_INDEX ${RELOCATION_NO}-1)
+ list(GET _RPM_RELOCATION_SCRIPT_PAIRS ${RELOCATION_INDEX} RELOCATION_SCRIPT_PAIR)
+ string(FIND "${RELOCATION_SCRIPT_PAIR}" ":" SPLIT_INDEX)
+
+ math(EXPR SRC_PATH_END ${SPLIT_INDEX}-${SRC_PATH_LEN})
+ string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} ${SRC_PATH_LEN} ${SRC_PATH_END} SYMLINK_)
+
+ math(EXPR POINT_PATH_START ${SPLIT_INDEX}+1+${POINT_PATH_LEN})
+ string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} ${POINT_PATH_START} -1 POINT_)
+
+ set(SCRIPT_PART "${SCRIPT_PART} ${INDENT}if [ -z \"$CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}\" ]; then\n")
+ set(SCRIPT_PART "${SCRIPT_PART} ${INDENT}ln -s \"$RPM_INSTALL_PREFIX${POINT_INDEX}${POINT_}\" \"$RPM_INSTALL_PREFIX${SYMLINK_INDEX}${SYMLINK_}\"\n")
+ set(SCRIPT_PART "${SCRIPT_PART} ${INDENT}CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}=true\n")
+ set(SCRIPT_PART "${SCRIPT_PART} ${INDENT}fi\n")
+ endforeach()
+
+ if(NOT "${SYMLINK_INDEX}" EQUAL "${POINT_INDEX}")
+ set(SCRIPT_PART "${SCRIPT_PART} fi\n")
+ endif()
+ endif()
+ endforeach()
+
+ # source path relocated
+ if(_RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_X)
+ foreach(RELOCATION_NO IN LISTS _RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_X)
+ math(EXPR PARTS_CNT ${PARTS_CNT}+1)
+
+ math(EXPR RELOCATION_INDEX ${RELOCATION_NO}-1)
+ list(GET _RPM_RELOCATION_SCRIPT_PAIRS ${RELOCATION_INDEX} RELOCATION_SCRIPT_PAIR)
+ string(FIND "${RELOCATION_SCRIPT_PAIR}" ":" SPLIT_INDEX)
+
+ math(EXPR SRC_PATH_END ${SPLIT_INDEX}-${SRC_PATH_LEN})
+ string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} ${SRC_PATH_LEN} ${SRC_PATH_END} SYMLINK_)
+
+ math(EXPR POINT_PATH_START ${SPLIT_INDEX}+1)
+ string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} ${POINT_PATH_START} -1 POINT_)
+
+ set(SCRIPT_PART "${SCRIPT_PART} if [ -z \"$CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}\" ]; then\n")
+ set(SCRIPT_PART "${SCRIPT_PART} ln -s \"${POINT_}\" \"$RPM_INSTALL_PREFIX${SYMLINK_INDEX}${SYMLINK_}\"\n")
+ set(SCRIPT_PART "${SCRIPT_PART} CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}=true\n")
+ set(SCRIPT_PART "${SCRIPT_PART} fi\n")
+ endforeach()
+ endif()
+
+ if(PARTS_CNT)
+ set(SCRIPT "${SCRIPT_PART}")
+ set(SCRIPT "${SCRIPT}fi\n")
+ endif()
+ endforeach()
+
+ # point path relocated
+ foreach(POINT_INDEX RANGE ${LAST_INDEX})
+ list(GET SORTED_PACKAGE_PREFIXES ${POINT_INDEX} POINT_PATH)
+ list(FIND PACKAGE_PREFIXES "${POINT_PATH}" POINT_INDEX) # reverse magic
+ string(LENGTH "${POINT_PATH}" POINT_PATH_LEN)
+
+ if(_RPM_RELOCATION_SCRIPT_X_${POINT_INDEX})
+ set(SCRIPT "${SCRIPT}if [ \"$RPM_INSTALL_PREFIX${POINT_INDEX}\" != \"${POINT_PATH}\" ]; then\n")
+
+ foreach(RELOCATION_NO IN LISTS _RPM_RELOCATION_SCRIPT_X_${POINT_INDEX})
+ math(EXPR RELOCATION_INDEX ${RELOCATION_NO}-1)
+ list(GET _RPM_RELOCATION_SCRIPT_PAIRS ${RELOCATION_INDEX} RELOCATION_SCRIPT_PAIR)
+ string(FIND "${RELOCATION_SCRIPT_PAIR}" ":" SPLIT_INDEX)
+
+ string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} 0 ${SPLIT_INDEX} SYMLINK_)
+
+ math(EXPR POINT_PATH_START ${SPLIT_INDEX}+1+${POINT_PATH_LEN})
+ string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} ${POINT_PATH_START} -1 POINT_)
+
+ set(SCRIPT "${SCRIPT} if [ -z \"$CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}\" ]; then\n")
+ set(SCRIPT "${SCRIPT} ln -s \"$RPM_INSTALL_PREFIX${POINT_INDEX}${POINT_}\" \"${SYMLINK_}\"\n")
+ set(SCRIPT "${SCRIPT} CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}=true\n")
+ set(SCRIPT "${SCRIPT} fi\n")
+ endforeach()
+
+ set(SCRIPT "${SCRIPT}fi\n")
+ endif()
+ endforeach()
+
+ # no path relocated
+ if(_RPM_RELOCATION_SCRIPT_X_X)
+ foreach(RELOCATION_NO IN LISTS _RPM_RELOCATION_SCRIPT_X_X)
+ math(EXPR RELOCATION_INDEX ${RELOCATION_NO}-1)
+ list(GET _RPM_RELOCATION_SCRIPT_PAIRS ${RELOCATION_INDEX} RELOCATION_SCRIPT_PAIR)
+ string(FIND "${RELOCATION_SCRIPT_PAIR}" ":" SPLIT_INDEX)
+
+ string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} 0 ${SPLIT_INDEX} SYMLINK_)
+
+ math(EXPR POINT_PATH_START ${SPLIT_INDEX}+1)
+ string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} ${POINT_PATH_START} -1 POINT_)
+
+ set(SCRIPT "${SCRIPT}if [ -z \"$CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}\" ]; then\n")
+ set(SCRIPT "${SCRIPT} ln -s \"${POINT_}\" \"${SYMLINK_}\"\n")
+ set(SCRIPT "${SCRIPT}fi\n")
+ endforeach()
+ endif()
+
+ set(RPM_SYMLINK_POSTINSTALL "${SCRIPT}" PARENT_SCOPE)
+endfunction()
+
+function(cpack_rpm_symlink_add_for_relocation_script PACKAGE_PREFIXES SYMLINK SYMLINK_RELOCATION_PATHS POINT POINT_RELOCATION_PATHS)
+ list(LENGTH SYMLINK_RELOCATION_PATHS SYMLINK_PATHS_COUTN)
+ list(LENGTH POINT_RELOCATION_PATHS POINT_PATHS_COUNT)
+
+ list(APPEND _RPM_RELOCATION_SCRIPT_PAIRS "${SYMLINK}:${POINT}")
+ list(LENGTH _RPM_RELOCATION_SCRIPT_PAIRS PAIR_NO)
+
+ if(SYMLINK_PATHS_COUTN)
+ foreach(SYMLINK_RELOC_PATH IN LISTS SYMLINK_RELOCATION_PATHS)
+ list(FIND PACKAGE_PREFIXES "${SYMLINK_RELOC_PATH}" SYMLINK_INDEX)
+
+ # source path relocated
+ list(APPEND _RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_X "${PAIR_NO}")
+ list(APPEND RELOCATION_VARS "_RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_X")
+
+ foreach(POINT_RELOC_PATH IN LISTS POINT_RELOCATION_PATHS)
+ list(FIND PACKAGE_PREFIXES "${POINT_RELOC_PATH}" POINT_INDEX)
+
+ # both paths relocated
+ list(APPEND _RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_${POINT_INDEX} "${PAIR_NO}")
+ list(APPEND RELOCATION_VARS "_RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_${POINT_INDEX}")
+
+ # point path relocated
+ list(APPEND _RPM_RELOCATION_SCRIPT_X_${POINT_INDEX} "${PAIR_NO}")
+ list(APPEND RELOCATION_VARS "_RPM_RELOCATION_SCRIPT_X_${POINT_INDEX}")
+ endforeach()
+ endforeach()
+ elseif(POINT_PATHS_COUNT)
+ foreach(POINT_RELOC_PATH IN LISTS POINT_RELOCATION_PATHS)
+ list(FIND PACKAGE_PREFIXES "${POINT_RELOC_PATH}" POINT_INDEX)
+
+ # point path relocated
+ list(APPEND _RPM_RELOCATION_SCRIPT_X_${POINT_INDEX} "${PAIR_NO}")
+ list(APPEND RELOCATION_VARS "_RPM_RELOCATION_SCRIPT_X_${POINT_INDEX}")
+ endforeach()
+ endif()
+
+ # no path relocated
+ list(APPEND _RPM_RELOCATION_SCRIPT_X_X "${PAIR_NO}")
+ list(APPEND RELOCATION_VARS "_RPM_RELOCATION_SCRIPT_X_X")
+
+ # place variables into parent scope
+ foreach(VAR IN LISTS RELOCATION_VARS)
+ set(${VAR} "${${VAR}}" PARENT_SCOPE)
+ endforeach()
+ set(_RPM_RELOCATION_SCRIPT_PAIRS "${_RPM_RELOCATION_SCRIPT_PAIRS}" PARENT_SCOPE)
+ set(REQUIRES_SYMLINK_RELOCATION_SCRIPT "true" PARENT_SCOPE)
+ set(DIRECTIVE "%ghost " PARENT_SCOPE)
+endfunction()
+
+function(cpack_rpm_prepare_install_files INSTALL_FILES_LIST WDIR PACKAGE_PREFIXES IS_RELOCATABLE)
+ # Prepend directories in ${CPACK_RPM_INSTALL_FILES} with %dir
+ # This is necessary to avoid duplicate files since rpmbuild does
+ # recursion on its own when encountering a pathname which is a directory
+ # which is not flagged as %dir
+ string(STRIP "${INSTALL_FILES_LIST}" INSTALL_FILES_LIST)
+ string(REPLACE "\n" ";" INSTALL_FILES_LIST
+ "${INSTALL_FILES_LIST}")
+ string(REPLACE "\"" "" INSTALL_FILES_LIST
+ "${INSTALL_FILES_LIST}")
+ string(LENGTH "${WDIR}" WDR_LEN_)
+
+ list(SORT INSTALL_FILES_LIST) # make file order consistent on all platforms
+
+ foreach(F IN LISTS INSTALL_FILES_LIST)
+ unset(DIRECTIVE)
+
+ if(IS_SYMLINK "${WDIR}/${F}")
+ if(IS_RELOCATABLE)
+ # check that symlink has relocatable format
+ get_filename_component(SYMLINK_LOCATION_ "${WDIR}/${F}" DIRECTORY)
+ execute_process(COMMAND ls -la "${WDIR}/${F}"
+ WORKING_DIRECTORY "${WDIR}"
+ OUTPUT_VARIABLE SYMLINK_POINT_
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ string(FIND "${SYMLINK_POINT_}" "->" SYMLINK_POINT_INDEX_ REVERSE)
+ math(EXPR SYMLINK_POINT_INDEX_ ${SYMLINK_POINT_INDEX_}+3)
+ string(LENGTH "${SYMLINK_POINT_}" SYMLINK_POINT_LENGTH_)
+
+ # get destination path
+ string(SUBSTRING "${SYMLINK_POINT_}" ${SYMLINK_POINT_INDEX_} ${SYMLINK_POINT_LENGTH_} SYMLINK_POINT_)
+
+ # check if path is relative or absolute
+ string(SUBSTRING "${SYMLINK_POINT_}" 0 1 SYMLINK_IS_ABSOLUTE_)
+
+ if(${SYMLINK_IS_ABSOLUTE_} STREQUAL "/")
+ # prevent absolute paths from having /../ or /./ section inside of them
+ get_filename_component(SYMLINK_POINT_ "${SYMLINK_POINT_}" ABSOLUTE)
+ else()
+ # handle relative path
+ get_filename_component(SYMLINK_POINT_ "${SYMLINK_LOCATION_}/${SYMLINK_POINT_}" ABSOLUTE)
+ endif()
+
+ string(SUBSTRING "${SYMLINK_POINT_}" ${WDR_LEN_} -1 SYMLINK_POINT_WD_)
+
+ cpack_rpm_symlink_get_relocation_prefixes("${F}" "${PACKAGE_PREFIXES}" "SYMLINK_RELOCATIONS")
+ cpack_rpm_symlink_get_relocation_prefixes("${SYMLINK_POINT_WD_}" "${PACKAGE_PREFIXES}" "POINT_RELOCATIONS")
+
+ list(LENGTH SYMLINK_RELOCATIONS SYMLINK_RELOCATIONS_COUNT)
+ list(LENGTH POINT_RELOCATIONS POINT_RELOCATIONS_COUNT)
+
+ if(SYMLINK_RELOCATIONS_COUNT AND POINT_RELOCATIONS_COUNT)
+ # find matching
+ foreach(SYMLINK_RELOCATION_PREFIX IN LISTS SYMLINK_RELOCATIONS)
+ list(FIND POINT_RELOCATIONS "${SYMLINK_RELOCATION_PREFIX}" FOUND_INDEX)
+ if(NOT ${FOUND_INDEX} EQUAL -1)
+ break()
+ endif()
+ endforeach()
+
+ if(NOT ${FOUND_INDEX} EQUAL -1)
+ # symlinks have the same subpath
+ if(${SYMLINK_RELOCATIONS_COUNT} EQUAL 1 AND ${POINT_RELOCATIONS_COUNT} EQUAL 1)
+ # permanent symlink
+ get_filename_component(SYMLINK_LOCATION_ "${F}" DIRECTORY)
+ file(RELATIVE_PATH FINAL_PATH_ ${SYMLINK_LOCATION_} ${SYMLINK_POINT_WD_})
+ execute_process(COMMAND "${CMAKE_COMMAND}" -E create_symlink "${FINAL_PATH_}" "${WDIR}/${F}")
+ else()
+ # relocation subpaths
+ cpack_rpm_symlink_add_for_relocation_script("${PACKAGE_PREFIXES}" "${F}" "${SYMLINK_RELOCATIONS}"
+ "${SYMLINK_POINT_WD_}" "${POINT_RELOCATIONS}")
+ endif()
+ else()
+ # not on the same relocation path
+ cpack_rpm_symlink_add_for_relocation_script("${PACKAGE_PREFIXES}" "${F}" "${SYMLINK_RELOCATIONS}"
+ "${SYMLINK_POINT_WD_}" "${POINT_RELOCATIONS}")
+ endif()
+ elseif(POINT_RELOCATIONS_COUNT)
+ # point is relocatable
+ cpack_rpm_symlink_add_for_relocation_script("${PACKAGE_PREFIXES}" "${F}" "${SYMLINK_RELOCATIONS}"
+ "${SYMLINK_POINT_WD_}" "${POINT_RELOCATIONS}")
+ else()
+ # is not relocatable or points to non relocatable path - permanent symlink
+ execute_process(COMMAND "${CMAKE_COMMAND}" -E create_symlink "${SYMLINK_POINT_WD_}" "${WDIR}/${F}")
+ endif()
+ endif()
+ elseif(IS_DIRECTORY "${WDIR}/${F}")
+ set(DIRECTIVE "%dir ")
+ endif()
+
+ set(INSTALL_FILES "${INSTALL_FILES}${DIRECTIVE}\"${F}\"\n")
+ endforeach()
+
+ if(REQUIRES_SYMLINK_RELOCATION_SCRIPT)
+ cpack_rpm_symlink_create_relocation_script("${PACKAGE_PREFIXES}")
+ endif()
+
+ set(RPM_SYMLINK_POSTINSTALL "${RPM_SYMLINK_POSTINSTALL}" PARENT_SCOPE)
+ set(CPACK_RPM_INSTALL_FILES "${INSTALL_FILES}" PARENT_SCOPE)
+endfunction()
+
if(CMAKE_BINARY_DIR)
message(FATAL_ERROR "CPackRPM.cmake may only be used by CPack internally.")
endif()
@@ -267,640 +1044,625 @@ if(NOT UNIX)
message(FATAL_ERROR "CPackRPM.cmake may only be used under UNIX.")
endif()
-# rpmbuild is the basic command for building RPM package
-# it may be a simple (symbolic) link to rpm command.
-find_program(RPMBUILD_EXECUTABLE rpmbuild)
-
-# Check version of the rpmbuild tool this would be easier to
-# track bugs with users and CPackRPM debug mode.
-# We may use RPM version in order to check for available version dependent features
-if(RPMBUILD_EXECUTABLE)
- execute_process(COMMAND ${RPMBUILD_EXECUTABLE} --version
- OUTPUT_VARIABLE _TMP_VERSION
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- string(REGEX REPLACE "^.* " ""
- RPMBUILD_EXECUTABLE_VERSION
- ${_TMP_VERSION})
+function(cpack_rpm_generate_package)
+ # rpmbuild is the basic command for building RPM package
+ # it may be a simple (symbolic) link to rpm command.
+ find_program(RPMBUILD_EXECUTABLE rpmbuild)
+
+ # Check version of the rpmbuild tool this would be easier to
+ # track bugs with users and CPackRPM debug mode.
+ # We may use RPM version in order to check for available version dependent features
+ if(RPMBUILD_EXECUTABLE)
+ execute_process(COMMAND ${RPMBUILD_EXECUTABLE} --version
+ OUTPUT_VARIABLE _TMP_VERSION
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ string(REGEX REPLACE "^.* " ""
+ RPMBUILD_EXECUTABLE_VERSION
+ ${_TMP_VERSION})
+ if(CPACK_RPM_PACKAGE_DEBUG)
+ message("CPackRPM:Debug: rpmbuild version is <${RPMBUILD_EXECUTABLE_VERSION}>")
+ endif()
+ endif()
+
+ if(NOT RPMBUILD_EXECUTABLE)
+ message(FATAL_ERROR "RPM package requires rpmbuild executable")
+ endif()
+
+ # Display lsb_release output if DEBUG mode enable
+ # This will help to diagnose problem with CPackRPM
+ # because we will know on which kind of Linux we are
if(CPACK_RPM_PACKAGE_DEBUG)
- message("CPackRPM:Debug: rpmbuild version is <${RPMBUILD_EXECUTABLE_VERSION}>")
+ find_program(LSB_RELEASE_EXECUTABLE lsb_release)
+ if(LSB_RELEASE_EXECUTABLE)
+ execute_process(COMMAND ${LSB_RELEASE_EXECUTABLE} -a
+ OUTPUT_VARIABLE _TMP_LSB_RELEASE_OUTPUT
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ string(REGEX REPLACE "\n" ", "
+ LSB_RELEASE_OUTPUT
+ ${_TMP_LSB_RELEASE_OUTPUT})
+ else ()
+ set(LSB_RELEASE_OUTPUT "lsb_release not installed/found!")
+ endif()
+ message("CPackRPM:Debug: LSB_RELEASE = ${LSB_RELEASE_OUTPUT}")
endif()
-endif()
-if(NOT RPMBUILD_EXECUTABLE)
- message(FATAL_ERROR "RPM package requires rpmbuild executable")
-endif()
+ # We may use RPM version in the future in order
+ # to shut down warning about space in buildtree
+ # some recent RPM version should support space in different places.
+ # not checked [yet].
+ if(CPACK_TOPLEVEL_DIRECTORY MATCHES ".* .*")
+ message(FATAL_ERROR "${RPMBUILD_EXECUTABLE} can't handle paths with spaces, use a build directory without spaces for building RPMs.")
+ endif()
-# Display lsb_release output if DEBUG mode enable
-# This will help to diagnose problem with CPackRPM
-# because we will know on which kind of Linux we are
-if(CPACK_RPM_PACKAGE_DEBUG)
- find_program(LSB_RELEASE_EXECUTABLE lsb_release)
- if(LSB_RELEASE_EXECUTABLE)
- execute_process(COMMAND ${LSB_RELEASE_EXECUTABLE} -a
- OUTPUT_VARIABLE _TMP_LSB_RELEASE_OUTPUT
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- string(REGEX REPLACE "\n" ", "
- LSB_RELEASE_OUTPUT
- ${_TMP_LSB_RELEASE_OUTPUT})
- else ()
- set(LSB_RELEASE_OUTPUT "lsb_release not installed/found!")
+ # If rpmbuild is found
+ # we try to discover alien since we may be on non RPM distro like Debian.
+ # In this case we may try to to use more advanced features
+ # like generating RPM directly from DEB using alien.
+ # FIXME feature not finished (yet)
+ find_program(ALIEN_EXECUTABLE alien)
+ if(ALIEN_EXECUTABLE)
+ message(STATUS "alien found, we may be on a Debian based distro.")
endif()
- message("CPackRPM:Debug: LSB_RELEASE = ${LSB_RELEASE_OUTPUT}")
-endif()
-# We may use RPM version in the future in order
-# to shut down warning about space in buildtree
-# some recent RPM version should support space in different places.
-# not checked [yet].
-if(CPACK_TOPLEVEL_DIRECTORY MATCHES ".* .*")
- message(FATAL_ERROR "${RPMBUILD_EXECUTABLE} can't handle paths with spaces, use a build directory without spaces for building RPMs.")
-endif()
+ # Are we packaging components ?
+ if(CPACK_RPM_PACKAGE_COMPONENT)
+ string(TOUPPER ${CPACK_RPM_PACKAGE_COMPONENT} CPACK_RPM_PACKAGE_COMPONENT_UPPER)
+ endif()
-# If rpmbuild is found
-# we try to discover alien since we may be on non RPM distro like Debian.
-# In this case we may try to to use more advanced features
-# like generating RPM directly from DEB using alien.
-# FIXME feature not finished (yet)
-find_program(ALIEN_EXECUTABLE alien)
-if(ALIEN_EXECUTABLE)
- message(STATUS "alien found, we may be on a Debian based distro.")
-endif()
+ set(WDIR "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}")
-# Are we packaging components ?
-if(CPACK_RPM_PACKAGE_COMPONENT)
- set(CPACK_RPM_PACKAGE_COMPONENT_PART_NAME "-${CPACK_RPM_PACKAGE_COMPONENT}")
-else()
- set(CPACK_RPM_PACKAGE_COMPONENT_PART_NAME "")
-endif()
+ #
+ # Use user-defined RPM specific variables value
+ # or generate reasonable default value from
+ # CPACK_xxx generic values.
+ # The variables comes from the needed (mandatory or not)
+ # values found in the RPM specification file aka ".spec" file.
+ # The variables which may/should be defined are:
+ #
-set(WDIR "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}")
+ # CPACK_RPM_PACKAGE_SUMMARY (mandatory)
-#
-# Use user-defined RPM specific variables value
-# or generate reasonable default value from
-# CPACK_xxx generic values.
-# The variables comes from the needed (mandatory or not)
-# values found in the RPM specification file aka ".spec" file.
-# The variables which may/should be defined are:
-#
+ #Check for component summary first.
+ #If not set, it will use regular package summary logic.
+ if(CPACK_RPM_PACKAGE_COMPONENT)
+ if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_SUMMARY)
+ set(CPACK_RPM_PACKAGE_SUMMARY ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_SUMMARY})
+ endif()
+ endif()
-# CPACK_RPM_PACKAGE_SUMMARY (mandatory)
-if(NOT CPACK_RPM_PACKAGE_SUMMARY)
- # if neither var is defined lets use the name as summary
- if(NOT CPACK_PACKAGE_DESCRIPTION_SUMMARY)
- string(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_RPM_PACKAGE_SUMMARY)
+ if(NOT CPACK_RPM_PACKAGE_SUMMARY)
+ if(CPACK_PACKAGE_DESCRIPTION_SUMMARY)
+ set(CPACK_RPM_PACKAGE_SUMMARY ${CPACK_PACKAGE_DESCRIPTION_SUMMARY})
+ else()
+ # if neither var is defined lets use the name as summary
+ string(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_RPM_PACKAGE_SUMMARY)
+ endif()
+ endif()
+
+ # CPACK_RPM_PACKAGE_NAME (mandatory)
+
+ if(NOT CPACK_RPM_PACKAGE_NAME)
+ string(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_RPM_PACKAGE_NAME)
+ endif()
+
+ if(CPACK_RPM_PACKAGE_COMPONENT)
+ if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_NAME)
+ set(CPACK_RPM_PACKAGE_NAME ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_NAME})
+ else()
+ set(CPACK_RPM_PACKAGE_NAME ${CPACK_RPM_PACKAGE_NAME}-${CPACK_RPM_PACKAGE_COMPONENT})
+ endif()
+ endif()
+
+ # CPACK_RPM_PACKAGE_VERSION (mandatory)
+ if(NOT CPACK_RPM_PACKAGE_VERSION)
+ if(NOT CPACK_PACKAGE_VERSION)
+ message(FATAL_ERROR "RPM package requires a package version")
+ endif()
+ set(CPACK_RPM_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION})
+ endif()
+ # Replace '-' in version with '_'
+ # '-' character is an Illegal RPM version character
+ # it is illegal because it is used to separate
+ # RPM "Version" from RPM "Release"
+ string(REPLACE "-" "_" CPACK_RPM_PACKAGE_VERSION ${CPACK_RPM_PACKAGE_VERSION})
+
+ # CPACK_RPM_PACKAGE_ARCHITECTURE (mandatory)
+ if(NOT CPACK_RPM_PACKAGE_ARCHITECTURE)
+ execute_process(COMMAND uname "-m"
+ OUTPUT_VARIABLE CPACK_RPM_PACKAGE_ARCHITECTURE
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
else()
- set(CPACK_RPM_PACKAGE_SUMMARY ${CPACK_PACKAGE_DESCRIPTION_SUMMARY})
+ if(CPACK_RPM_PACKAGE_DEBUG)
+ message("CPackRPM:Debug: using user-specified build arch = ${CPACK_RPM_PACKAGE_ARCHITECTURE}")
+ endif()
endif()
-endif()
-# CPACK_RPM_PACKAGE_NAME (mandatory)
-if(NOT CPACK_RPM_PACKAGE_NAME)
- string(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_RPM_PACKAGE_NAME)
-endif()
+ set(_CPACK_RPM_PACKAGE_ARCHITECTURE ${CPACK_RPM_PACKAGE_ARCHITECTURE})
-# CPACK_RPM_PACKAGE_VERSION (mandatory)
-if(NOT CPACK_RPM_PACKAGE_VERSION)
- if(NOT CPACK_PACKAGE_VERSION)
- message(FATAL_ERROR "RPM package requires a package version")
+ #prefer component architecture
+ if(CPACK_RPM_PACKAGE_COMPONENT)
+ if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_ARCHITECTURE)
+ set(_CPACK_RPM_PACKAGE_ARCHITECTURE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_ARCHITECTURE})
+ if(CPACK_RPM_PACKAGE_DEBUG)
+ message("CPackRPM:Debug: using component build arch = ${_CPACK_RPM_PACKAGE_ARCHITECTURE}")
+ endif()
+ endif()
endif()
- set(CPACK_RPM_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION})
-endif()
-# Replace '-' in version with '_'
-# '-' character is an Illegal RPM version character
-# it is illegal because it is used to separate
-# RPM "Version" from RPM "Release"
-string(REPLACE "-" "_" CPACK_RPM_PACKAGE_VERSION ${CPACK_RPM_PACKAGE_VERSION})
-
-# CPACK_RPM_PACKAGE_ARCHITECTURE (optional)
-if(CPACK_RPM_PACKAGE_ARCHITECTURE)
- set(TMP_RPM_BUILDARCH "Buildarch: ${CPACK_RPM_PACKAGE_ARCHITECTURE}")
- if(CPACK_RPM_PACKAGE_DEBUG)
- message("CPackRPM:Debug: using user-specified build arch = ${CPACK_RPM_PACKAGE_ARCHITECTURE}")
+ if(${_CPACK_RPM_PACKAGE_ARCHITECTURE} STREQUAL "noarch")
+ set(TMP_RPM_BUILDARCH "Buildarch: ${_CPACK_RPM_PACKAGE_ARCHITECTURE}")
+ else()
+ set(TMP_RPM_BUILDARCH "")
endif()
-else()
- set(TMP_RPM_BUILDARCH "")
-endif()
-# CPACK_RPM_PACKAGE_RELEASE
-# The RPM release is the numbering of the RPM package ITSELF
-# this is the version of the PACKAGING and NOT the version
-# of the CONTENT of the package.
-# You may well need to generate a new RPM package release
-# without changing the version of the packaged software.
-# This is the case when the packaging is buggy (not) the software :=)
-# If not set, 1 is a good candidate
-if(NOT CPACK_RPM_PACKAGE_RELEASE)
- set(CPACK_RPM_PACKAGE_RELEASE 1)
-endif()
+ # CPACK_RPM_PACKAGE_RELEASE
+ # The RPM release is the numbering of the RPM package ITSELF
+ # this is the version of the PACKAGING and NOT the version
+ # of the CONTENT of the package.
+ # You may well need to generate a new RPM package release
+ # without changing the version of the packaged software.
+ # This is the case when the packaging is buggy (not) the software :=)
+ # If not set, 1 is a good candidate
+ if(NOT CPACK_RPM_PACKAGE_RELEASE)
+ set(CPACK_RPM_PACKAGE_RELEASE 1)
+ endif()
-# CPACK_RPM_PACKAGE_LICENSE
-if(NOT CPACK_RPM_PACKAGE_LICENSE)
- set(CPACK_RPM_PACKAGE_LICENSE "unknown")
-endif()
+ # CPACK_RPM_PACKAGE_LICENSE
+ if(NOT CPACK_RPM_PACKAGE_LICENSE)
+ set(CPACK_RPM_PACKAGE_LICENSE "unknown")
+ endif()
-# CPACK_RPM_PACKAGE_GROUP
-if(NOT CPACK_RPM_PACKAGE_GROUP)
- set(CPACK_RPM_PACKAGE_GROUP "unknown")
-endif()
+ # CPACK_RPM_PACKAGE_GROUP
-# CPACK_RPM_PACKAGE_VENDOR
-if(NOT CPACK_RPM_PACKAGE_VENDOR)
- if(CPACK_PACKAGE_VENDOR)
- set(CPACK_RPM_PACKAGE_VENDOR "${CPACK_PACKAGE_VENDOR}")
- else()
- set(CPACK_RPM_PACKAGE_VENDOR "unknown")
+ #Check for component group first.
+ #If not set, it will use regular package group logic.
+ if(CPACK_RPM_PACKAGE_COMPONENT)
+ if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_GROUP)
+ set(CPACK_RPM_PACKAGE_GROUP ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_GROUP})
+ endif()
endif()
-endif()
-# CPACK_RPM_PACKAGE_SOURCE
-# The name of the source tarball in case we generate a source RPM
-
-# CPACK_RPM_PACKAGE_DESCRIPTION
-# The variable content may be either
-# - explicitly given by the user or
-# - filled with the content of CPACK_PACKAGE_DESCRIPTION_FILE
-# if it is defined
-# - set to a default value
-#
-if (NOT CPACK_RPM_PACKAGE_DESCRIPTION)
- if (CPACK_PACKAGE_DESCRIPTION_FILE)
- file(READ ${CPACK_PACKAGE_DESCRIPTION_FILE} CPACK_RPM_PACKAGE_DESCRIPTION)
- else ()
- set(CPACK_RPM_PACKAGE_DESCRIPTION "no package description available")
- endif ()
-endif ()
-
-# CPACK_RPM_COMPRESSION_TYPE
-#
-if (CPACK_RPM_COMPRESSION_TYPE)
- if(CPACK_RPM_PACKAGE_DEBUG)
- message("CPackRPM:Debug: User Specified RPM compression type: ${CPACK_RPM_COMPRESSION_TYPE}")
- endif()
- if(CPACK_RPM_COMPRESSION_TYPE STREQUAL "lzma")
- set(CPACK_RPM_COMPRESSION_TYPE_TMP "%define _binary_payload w9.lzdio")
- endif()
- if(CPACK_RPM_COMPRESSION_TYPE STREQUAL "xz")
- set(CPACK_RPM_COMPRESSION_TYPE_TMP "%define _binary_payload w7.xzdio")
- endif()
- if(CPACK_RPM_COMPRESSION_TYPE STREQUAL "bzip2")
- set(CPACK_RPM_COMPRESSION_TYPE_TMP "%define _binary_payload w9.bzdio")
- endif()
- if(CPACK_RPM_COMPRESSION_TYPE STREQUAL "gzip")
- set(CPACK_RPM_COMPRESSION_TYPE_TMP "%define _binary_payload w9.gzdio")
- endif()
-else()
- set(CPACK_RPM_COMPRESSION_TYPE_TMP "")
-endif()
+ if(NOT CPACK_RPM_PACKAGE_GROUP)
+ set(CPACK_RPM_PACKAGE_GROUP "unknown")
+ endif()
-if(CPACK_PACKAGE_RELOCATABLE)
- set(CPACK_RPM_PACKAGE_RELOCATABLE TRUE)
-endif()
-if(CPACK_RPM_PACKAGE_RELOCATABLE)
- if(CPACK_RPM_PACKAGE_DEBUG)
- message("CPackRPM:Debug: Trying to build a relocatable package")
+ # CPACK_RPM_PACKAGE_VENDOR
+ if(NOT CPACK_RPM_PACKAGE_VENDOR)
+ if(CPACK_PACKAGE_VENDOR)
+ set(CPACK_RPM_PACKAGE_VENDOR "${CPACK_PACKAGE_VENDOR}")
+ else()
+ set(CPACK_RPM_PACKAGE_VENDOR "unknown")
+ endif()
+ endif()
+
+ # CPACK_RPM_PACKAGE_SOURCE
+ # The name of the source tarball in case we generate a source RPM
+
+ # CPACK_RPM_PACKAGE_DESCRIPTION
+ # The variable content may be either
+ # - explicitly given by the user or
+ # - filled with the content of CPACK_PACKAGE_DESCRIPTION_FILE
+ # if it is defined
+ # - set to a default value
+ #
+
+ #Check for a component description first.
+ #If not set, it will use regular package description logic.
+ if(CPACK_RPM_PACKAGE_COMPONENT)
+ if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_DESCRIPTION)
+ set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_DESCRIPTION})
+ elseif(CPACK_COMPONENT_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_DESCRIPTION)
+ set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_COMPONENT_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_DESCRIPTION})
+ endif()
endif()
- if(CPACK_SET_DESTDIR AND (NOT CPACK_SET_DESTDIR STREQUAL "I_ON"))
- message("CPackRPM:Warning: CPACK_SET_DESTDIR is set (=${CPACK_SET_DESTDIR}) while requesting a relocatable package (CPACK_RPM_PACKAGE_RELOCATABLE is set): this is not supported, the package won't be relocatable.")
+
+ if(NOT CPACK_RPM_PACKAGE_DESCRIPTION)
+ if(CPACK_PACKAGE_DESCRIPTION_FILE)
+ file(READ ${CPACK_PACKAGE_DESCRIPTION_FILE} CPACK_RPM_PACKAGE_DESCRIPTION)
+ else ()
+ set(CPACK_RPM_PACKAGE_DESCRIPTION "no package description available")
+ endif ()
+ endif ()
+
+ # CPACK_RPM_COMPRESSION_TYPE
+ #
+ if (CPACK_RPM_COMPRESSION_TYPE)
+ if(CPACK_RPM_PACKAGE_DEBUG)
+ message("CPackRPM:Debug: User Specified RPM compression type: ${CPACK_RPM_COMPRESSION_TYPE}")
+ endif()
+ if(CPACK_RPM_COMPRESSION_TYPE STREQUAL "lzma")
+ set(CPACK_RPM_COMPRESSION_TYPE_TMP "%define _binary_payload w9.lzdio")
+ endif()
+ if(CPACK_RPM_COMPRESSION_TYPE STREQUAL "xz")
+ set(CPACK_RPM_COMPRESSION_TYPE_TMP "%define _binary_payload w7.xzdio")
+ endif()
+ if(CPACK_RPM_COMPRESSION_TYPE STREQUAL "bzip2")
+ set(CPACK_RPM_COMPRESSION_TYPE_TMP "%define _binary_payload w9.bzdio")
+ endif()
+ if(CPACK_RPM_COMPRESSION_TYPE STREQUAL "gzip")
+ set(CPACK_RPM_COMPRESSION_TYPE_TMP "%define _binary_payload w9.gzdio")
+ endif()
else()
- set(CPACK_RPM_PACKAGE_PREFIX ${CPACK_PACKAGING_INSTALL_PREFIX})
+ set(CPACK_RPM_COMPRESSION_TYPE_TMP "")
endif()
-endif()
-# Check if additional fields for RPM spec header are given
-# There may be some COMPONENT specific variables as well
-# If component specific var is not provided we use the global one
-# for each component
-foreach(_RPM_SPEC_HEADER URL REQUIRES SUGGESTS PROVIDES OBSOLETES PREFIX CONFLICTS AUTOPROV AUTOREQ AUTOREQPROV)
+ if(CPACK_PACKAGE_RELOCATABLE OR CPACK_RPM_PACKAGE_RELOCATABLE)
if(CPACK_RPM_PACKAGE_DEBUG)
- message("CPackRPM:Debug: processing ${_RPM_SPEC_HEADER}")
+ message("CPackRPM:Debug: Trying to build a relocatable package")
endif()
- if(CPACK_RPM_PACKAGE_COMPONENT)
- if(DEFINED CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER})
- if(CPACK_RPM_PACKAGE_DEBUG)
- message("CPackRPM:Debug: using CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER}")
- endif()
- set(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER}})
- else()
- if(DEFINED CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER})
+ if(CPACK_SET_DESTDIR AND (NOT CPACK_SET_DESTDIR STREQUAL "I_ON"))
+ message("CPackRPM:Warning: CPACK_SET_DESTDIR is set (=${CPACK_SET_DESTDIR}) while requesting a relocatable package (CPACK_RPM_PACKAGE_RELOCATABLE is set): this is not supported, the package won't be relocatable.")
+ set(CPACK_RPM_PACKAGE_RELOCATABLE FALSE)
+ else()
+ set(CPACK_RPM_PACKAGE_PREFIX ${CPACK_PACKAGING_INSTALL_PREFIX}) # kept for back compatibility (provided external RPM spec files)
+ cpack_rpm_prepare_relocation_paths()
+ set(CPACK_RPM_PACKAGE_RELOCATABLE TRUE)
+ endif()
+ endif()
+
+ # Check if additional fields for RPM spec header are given
+ # There may be some COMPONENT specific variables as well
+ # If component specific var is not provided we use the global one
+ # for each component
+ foreach(_RPM_SPEC_HEADER URL REQUIRES SUGGESTS PROVIDES OBSOLETES PREFIX CONFLICTS AUTOPROV AUTOREQ AUTOREQPROV REQUIRES_PRE REQUIRES_POST REQUIRES_PREUN REQUIRES_POSTUN)
+ if(CPACK_RPM_PACKAGE_DEBUG)
+ message("CPackRPM:Debug: processing ${_RPM_SPEC_HEADER}")
+ endif()
+ if(CPACK_RPM_PACKAGE_COMPONENT)
+ if(DEFINED CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER})
if(CPACK_RPM_PACKAGE_DEBUG)
- message("CPackRPM:Debug: CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER} not defined")
- message("CPackRPM:Debug: using CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}")
+ message("CPackRPM:Debug: using CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER}")
+ endif()
+ set(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER}})
+ else()
+ if(DEFINED CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER})
+ if(CPACK_RPM_PACKAGE_DEBUG)
+ message("CPackRPM:Debug: CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER} not defined")
+ message("CPackRPM:Debug: using CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}")
+ endif()
+ set(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}})
endif()
- set(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}})
+ endif()
+ else()
+ if(DEFINED CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER})
+ if(CPACK_RPM_PACKAGE_DEBUG)
+ message("CPackRPM:Debug: using CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}")
endif()
- endif()
- else()
- if(DEFINED CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER})
- if(CPACK_RPM_PACKAGE_DEBUG)
- message("CPackRPM:Debug: using CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}")
+ set(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}})
endif()
- set(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}})
- endif()
+ endif()
+
+ # Treat the RPM Spec keyword iff it has been properly defined
+ if(DEFINED CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP)
+ # Transform NAME --> Name e.g. PROVIDES --> Provides
+ # The Upper-case first letter and lowercase tail is the
+ # appropriate value required in the final RPM spec file.
+ string(SUBSTRING ${_RPM_SPEC_HEADER} 1 -1 _PACKAGE_HEADER_TAIL)
+ string(TOLOWER "${_PACKAGE_HEADER_TAIL}" _PACKAGE_HEADER_TAIL)
+ string(SUBSTRING ${_RPM_SPEC_HEADER} 0 1 _PACKAGE_HEADER_NAME)
+ set(_PACKAGE_HEADER_NAME "${_PACKAGE_HEADER_NAME}${_PACKAGE_HEADER_TAIL}")
+ # The following keywords require parentheses around the "pre" or "post" suffix in the final RPM spec file.
+ set(SCRIPTS_REQUIREMENTS_LIST REQUIRES_PRE REQUIRES_POST REQUIRES_PREUN REQUIRES_POSTUN)
+ list(FIND SCRIPTS_REQUIREMENTS_LIST ${_RPM_SPEC_HEADER} IS_SCRIPTS_REQUIREMENT_FOUND)
+ if(NOT ${IS_SCRIPTS_REQUIREMENT_FOUND} EQUAL -1)
+ string(REPLACE "_" "(" _PACKAGE_HEADER_NAME "${_PACKAGE_HEADER_NAME}")
+ set(_PACKAGE_HEADER_NAME "${_PACKAGE_HEADER_NAME})")
+ endif()
+ if(CPACK_RPM_PACKAGE_DEBUG)
+ message("CPackRPM:Debug: User defined ${_PACKAGE_HEADER_NAME}:\n ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP}")
+ endif()
+ set(TMP_RPM_${_RPM_SPEC_HEADER} "${_PACKAGE_HEADER_NAME}: ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP}")
+ unset(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP)
endif()
+ endforeach()
- # Treat the RPM Spec keyword iff it has been properly defined
- if(DEFINED CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP)
- # Transform NAME --> Name e.g. PROVIDES --> Provides
- # The Upper-case first letter and lowercase tail is the
- # appropriate value required in the final RPM spec file.
- string(LENGTH ${_RPM_SPEC_HEADER} _PACKAGE_HEADER_STRLENGTH)
- math(EXPR _PACKAGE_HEADER_STRLENGTH "${_PACKAGE_HEADER_STRLENGTH} - 1")
- string(SUBSTRING ${_RPM_SPEC_HEADER} 1 ${_PACKAGE_HEADER_STRLENGTH} _PACKAGE_HEADER_TAIL)
- string(TOLOWER "${_PACKAGE_HEADER_TAIL}" _PACKAGE_HEADER_TAIL)
- string(SUBSTRING ${_RPM_SPEC_HEADER} 0 1 _PACKAGE_HEADER_NAME)
- set(_PACKAGE_HEADER_NAME "${_PACKAGE_HEADER_NAME}${_PACKAGE_HEADER_TAIL}")
+ # CPACK_RPM_SPEC_INSTALL_POST
+ # May be used to define a RPM post intallation script
+ # for example setting it to "/bin/true" may prevent
+ # rpmbuild from stripping binaries.
+ if(CPACK_RPM_SPEC_INSTALL_POST)
if(CPACK_RPM_PACKAGE_DEBUG)
- message("CPackRPM:Debug: User defined ${_PACKAGE_HEADER_NAME}:\n ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP}")
+ message("CPackRPM:Debug: User defined CPACK_RPM_SPEC_INSTALL_POST = ${CPACK_RPM_SPEC_INSTALL_POST}")
endif()
- set(TMP_RPM_${_RPM_SPEC_HEADER} "${_PACKAGE_HEADER_NAME}: ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP}")
- else()
- # Do not forget to unset previously set header (from previous component)
- unset(TMP_RPM_${_RPM_SPEC_HEADER})
+ set(TMP_RPM_SPEC_INSTALL_POST "%define __spec_install_post ${CPACK_RPM_SPEC_INSTALL_POST}")
endif()
-endforeach()
-# CPACK_RPM_SPEC_INSTALL_POST
-# May be used to define a RPM post intallation script
-# for example setting it to "/bin/true" may prevent
-# rpmbuild from stripping binaries.
-if(CPACK_RPM_SPEC_INSTALL_POST)
- if(CPACK_RPM_PACKAGE_DEBUG)
- message("CPackRPM:Debug: User defined CPACK_RPM_SPEC_INSTALL_POST = ${CPACK_RPM_SPEC_INSTALL_POST}")
- endif()
- set(TMP_RPM_SPEC_INSTALL_POST "%define __spec_install_post ${CPACK_RPM_SPEC_INSTALL_POST}")
-endif()
-
-# CPACK_RPM_POST_INSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_POST_INSTALL_SCRIPT_FILE)
-# CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_POST_UNINSTALL_SCRIPT_FILE)
-# May be used to embed a post (un)installation script in the spec file.
-# The refered script file(s) will be read and directly
-# put after the %post or %postun section
-if(CPACK_RPM_PACKAGE_COMPONENT)
- if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_POST_INSTALL_SCRIPT_FILE)
- set(CPACK_RPM_POST_INSTALL_READ_FILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_POST_INSTALL_SCRIPT_FILE})
+ # CPACK_RPM_POST_INSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_POST_INSTALL_SCRIPT_FILE)
+ # CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_POST_UNINSTALL_SCRIPT_FILE)
+ # May be used to embed a post (un)installation script in the spec file.
+ # The refered script file(s) will be read and directly
+ # put after the %post or %postun section
+ if(CPACK_RPM_PACKAGE_COMPONENT)
+ if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_POST_INSTALL_SCRIPT_FILE)
+ set(CPACK_RPM_POST_INSTALL_READ_FILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_POST_INSTALL_SCRIPT_FILE})
+ else()
+ set(CPACK_RPM_POST_INSTALL_READ_FILE ${CPACK_RPM_POST_INSTALL_SCRIPT_FILE})
+ endif()
+ if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_POST_UNINSTALL_SCRIPT_FILE)
+ set(CPACK_RPM_POST_UNINSTALL_READ_FILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_POST_UNINSTALL_SCRIPT_FILE})
+ else()
+ set(CPACK_RPM_POST_UNINSTALL_READ_FILE ${CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE})
+ endif()
else()
set(CPACK_RPM_POST_INSTALL_READ_FILE ${CPACK_RPM_POST_INSTALL_SCRIPT_FILE})
- endif()
- if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_POST_UNINSTALL_SCRIPT_FILE)
- set(CPACK_RPM_POST_UNINSTALL_READ_FILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_POST_UNINSTALL_SCRIPT_FILE})
- else()
set(CPACK_RPM_POST_UNINSTALL_READ_FILE ${CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE})
endif()
-else()
- set(CPACK_RPM_POST_INSTALL_READ_FILE ${CPACK_RPM_POST_INSTALL_SCRIPT_FILE})
- set(CPACK_RPM_POST_UNINSTALL_READ_FILE ${CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE})
-endif()
-# Handle post-install file if it has been specified
-if(CPACK_RPM_POST_INSTALL_READ_FILE)
- if(EXISTS ${CPACK_RPM_POST_INSTALL_READ_FILE})
- file(READ ${CPACK_RPM_POST_INSTALL_READ_FILE} CPACK_RPM_SPEC_POSTINSTALL)
+ # Handle post-install file if it has been specified
+ if(CPACK_RPM_POST_INSTALL_READ_FILE)
+ if(EXISTS ${CPACK_RPM_POST_INSTALL_READ_FILE})
+ file(READ ${CPACK_RPM_POST_INSTALL_READ_FILE} CPACK_RPM_SPEC_POSTINSTALL)
+ else()
+ message("CPackRPM:Warning: CPACK_RPM_POST_INSTALL_SCRIPT_FILE <${CPACK_RPM_POST_INSTALL_READ_FILE}> does not exists - ignoring")
+ endif()
else()
- message("CPackRPM:Warning: CPACK_RPM_POST_INSTALL_SCRIPT_FILE <${CPACK_RPM_POST_INSTALL_READ_FILE}> does not exists - ignoring")
+ # reset SPEC var value if no post install file has been specified
+ # (either globally or component-wise)
+ set(CPACK_RPM_SPEC_POSTINSTALL "")
endif()
-else()
- # reset SPEC var value if no post install file has been specified
- # (either globally or component-wise)
- set(CPACK_RPM_SPEC_POSTINSTALL "")
-endif()
-# Handle post-uninstall file if it has been specified
-if(CPACK_RPM_POST_UNINSTALL_READ_FILE)
- if(EXISTS ${CPACK_RPM_POST_UNINSTALL_READ_FILE})
- file(READ ${CPACK_RPM_POST_UNINSTALL_READ_FILE} CPACK_RPM_SPEC_POSTUNINSTALL)
+ # Handle post-uninstall file if it has been specified
+ if(CPACK_RPM_POST_UNINSTALL_READ_FILE)
+ if(EXISTS ${CPACK_RPM_POST_UNINSTALL_READ_FILE})
+ file(READ ${CPACK_RPM_POST_UNINSTALL_READ_FILE} CPACK_RPM_SPEC_POSTUNINSTALL)
+ else()
+ message("CPackRPM:Warning: CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE <${CPACK_RPM_POST_UNINSTALL_READ_FILE}> does not exists - ignoring")
+ endif()
else()
- message("CPackRPM:Warning: CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE <${CPACK_RPM_POST_UNINSTALL_READ_FILE}> does not exists - ignoring")
+ # reset SPEC var value if no post uninstall file has been specified
+ # (either globally or component-wise)
+ set(CPACK_RPM_SPEC_POSTUNINSTALL "")
endif()
-else()
- # reset SPEC var value if no post uninstall file has been specified
- # (either globally or component-wise)
- set(CPACK_RPM_SPEC_POSTUNINSTALL "")
-endif()
-# CPACK_RPM_PRE_INSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_PRE_INSTALL_SCRIPT_FILE)
-# CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_PRE_UNINSTALL_SCRIPT_FILE)
-# May be used to embed a pre (un)installation script in the spec file.
-# The refered script file(s) will be read and directly
-# put after the %pre or %preun section
-if(CPACK_RPM_PACKAGE_COMPONENT)
- if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_INSTALL_SCRIPT_FILE)
- set(CPACK_RPM_PRE_INSTALL_READ_FILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_INSTALL_SCRIPT_FILE})
+ # CPACK_RPM_PRE_INSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_PRE_INSTALL_SCRIPT_FILE)
+ # CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_PRE_UNINSTALL_SCRIPT_FILE)
+ # May be used to embed a pre (un)installation script in the spec file.
+ # The refered script file(s) will be read and directly
+ # put after the %pre or %preun section
+ if(CPACK_RPM_PACKAGE_COMPONENT)
+ if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_INSTALL_SCRIPT_FILE)
+ set(CPACK_RPM_PRE_INSTALL_READ_FILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_INSTALL_SCRIPT_FILE})
+ else()
+ set(CPACK_RPM_PRE_INSTALL_READ_FILE ${CPACK_RPM_PRE_INSTALL_SCRIPT_FILE})
+ endif()
+ if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_UNINSTALL_SCRIPT_FILE)
+ set(CPACK_RPM_PRE_UNINSTALL_READ_FILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_UNINSTALL_SCRIPT_FILE})
+ else()
+ set(CPACK_RPM_PRE_UNINSTALL_READ_FILE ${CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE})
+ endif()
else()
set(CPACK_RPM_PRE_INSTALL_READ_FILE ${CPACK_RPM_PRE_INSTALL_SCRIPT_FILE})
- endif()
- if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_UNINSTALL_SCRIPT_FILE)
- set(CPACK_RPM_PRE_UNINSTALL_READ_FILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_UNINSTALL_SCRIPT_FILE})
- else()
set(CPACK_RPM_PRE_UNINSTALL_READ_FILE ${CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE})
endif()
-else()
- set(CPACK_RPM_PRE_INSTALL_READ_FILE ${CPACK_RPM_PRE_INSTALL_SCRIPT_FILE})
- set(CPACK_RPM_PRE_UNINSTALL_READ_FILE ${CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE})
-endif()
-# Handle pre-install file if it has been specified
-if(CPACK_RPM_PRE_INSTALL_READ_FILE)
- if(EXISTS ${CPACK_RPM_PRE_INSTALL_READ_FILE})
- file(READ ${CPACK_RPM_PRE_INSTALL_READ_FILE} CPACK_RPM_SPEC_PREINSTALL)
+ # Handle pre-install file if it has been specified
+ if(CPACK_RPM_PRE_INSTALL_READ_FILE)
+ if(EXISTS ${CPACK_RPM_PRE_INSTALL_READ_FILE})
+ file(READ ${CPACK_RPM_PRE_INSTALL_READ_FILE} CPACK_RPM_SPEC_PREINSTALL)
+ else()
+ message("CPackRPM:Warning: CPACK_RPM_PRE_INSTALL_SCRIPT_FILE <${CPACK_RPM_PRE_INSTALL_READ_FILE}> does not exists - ignoring")
+ endif()
else()
- message("CPackRPM:Warning: CPACK_RPM_PRE_INSTALL_SCRIPT_FILE <${CPACK_RPM_PRE_INSTALL_READ_FILE}> does not exists - ignoring")
+ # reset SPEC var value if no pre-install file has been specified
+ # (either globally or component-wise)
+ set(CPACK_RPM_SPEC_PREINSTALL "")
endif()
-else()
- # reset SPEC var value if no pre-install file has been specified
- # (either globally or component-wise)
- set(CPACK_RPM_SPEC_PREINSTALL "")
-endif()
-# Handle pre-uninstall file if it has been specified
-if(CPACK_RPM_PRE_UNINSTALL_READ_FILE)
- if(EXISTS ${CPACK_RPM_PRE_UNINSTALL_READ_FILE})
- file(READ ${CPACK_RPM_PRE_UNINSTALL_READ_FILE} CPACK_RPM_SPEC_PREUNINSTALL)
+ # Handle pre-uninstall file if it has been specified
+ if(CPACK_RPM_PRE_UNINSTALL_READ_FILE)
+ if(EXISTS ${CPACK_RPM_PRE_UNINSTALL_READ_FILE})
+ file(READ ${CPACK_RPM_PRE_UNINSTALL_READ_FILE} CPACK_RPM_SPEC_PREUNINSTALL)
+ else()
+ message("CPackRPM:Warning: CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE <${CPACK_RPM_PRE_UNINSTALL_READ_FILE}> does not exists - ignoring")
+ endif()
else()
- message("CPackRPM:Warning: CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE <${CPACK_RPM_PRE_UNINSTALL_READ_FILE}> does not exists - ignoring")
+ # reset SPEC var value if no pre-uninstall file has been specified
+ # (either globally or component-wise)
+ set(CPACK_RPM_SPEC_PREUNINSTALL "")
endif()
-else()
- # reset SPEC var value if no pre-uninstall file has been specified
- # (either globally or component-wise)
- set(CPACK_RPM_SPEC_PREUNINSTALL "")
-endif()
-# CPACK_RPM_CHANGELOG_FILE
-# May be used to embed a changelog in the spec file.
-# The refered file will be read and directly put after the %changelog section
-if(CPACK_RPM_CHANGELOG_FILE)
- if(EXISTS ${CPACK_RPM_CHANGELOG_FILE})
- file(READ ${CPACK_RPM_CHANGELOG_FILE} CPACK_RPM_SPEC_CHANGELOG)
+ # CPACK_RPM_CHANGELOG_FILE
+ # May be used to embed a changelog in the spec file.
+ # The refered file will be read and directly put after the %changelog section
+ if(CPACK_RPM_CHANGELOG_FILE)
+ if(EXISTS ${CPACK_RPM_CHANGELOG_FILE})
+ file(READ ${CPACK_RPM_CHANGELOG_FILE} CPACK_RPM_SPEC_CHANGELOG)
+ else()
+ message(SEND_ERROR "CPackRPM:Warning: CPACK_RPM_CHANGELOG_FILE <${CPACK_RPM_CHANGELOG_FILE}> does not exists - ignoring")
+ endif()
else()
- message(SEND_ERROR "CPackRPM:Warning: CPACK_RPM_CHANGELOG_FILE <${CPACK_RPM_CHANGELOG_FILE}> does not exists - ignoring")
+ set(CPACK_RPM_SPEC_CHANGELOG "* Sun Jul 4 2010 Eric Noulard <eric.noulard@gmail.com> - ${CPACK_RPM_PACKAGE_VERSION}-${CPACK_RPM_PACKAGE_RELEASE}\n Generated by CPack RPM (no Changelog file were provided)")
endif()
-else()
- set(CPACK_RPM_SPEC_CHANGELOG "* Sun Jul 4 2010 Eric Noulard <eric.noulard@gmail.com> - ${CPACK_RPM_PACKAGE_VERSION}-${CPACK_RPM_PACKAGE_RELEASE}\n Generated by CPack RPM (no Changelog file were provided)")
-endif()
-# CPACK_RPM_SPEC_MORE_DEFINE
-# This is a generated spec rpm file spaceholder
-if(CPACK_RPM_SPEC_MORE_DEFINE)
- if(CPACK_RPM_PACKAGE_DEBUG)
- message("CPackRPM:Debug: User defined more define spec line specified:\n ${CPACK_RPM_SPEC_MORE_DEFINE}")
+ # CPACK_RPM_SPEC_MORE_DEFINE
+ # This is a generated spec rpm file spaceholder
+ if(CPACK_RPM_SPEC_MORE_DEFINE)
+ if(CPACK_RPM_PACKAGE_DEBUG)
+ message("CPackRPM:Debug: User defined more define spec line specified:\n ${CPACK_RPM_SPEC_MORE_DEFINE}")
+ endif()
endif()
-endif()
-# Now we may create the RPM build tree structure
-set(CPACK_RPM_ROOTDIR "${CPACK_TOPLEVEL_DIRECTORY}")
-message(STATUS "CPackRPM:Debug: Using CPACK_RPM_ROOTDIR=${CPACK_RPM_ROOTDIR}")
-# Prepare RPM build tree
-file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR})
-file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/tmp)
-file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/BUILD)
-file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/RPMS)
-file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/SOURCES)
-file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/SPECS)
-file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/SRPMS)
-
-#set(CPACK_RPM_FILE_NAME "${CPACK_RPM_PACKAGE_NAME}-${CPACK_RPM_PACKAGE_VERSION}-${CPACK_RPM_PACKAGE_RELEASE}-${CPACK_RPM_PACKAGE_ARCHITECTURE}.rpm")
-set(CPACK_RPM_FILE_NAME "${CPACK_OUTPUT_FILE_NAME}")
-# it seems rpmbuild can't handle spaces in the path
-# neither escaping (as below) nor putting quotes around the path seem to help
-#string(REGEX REPLACE " " "\\\\ " CPACK_RPM_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}")
-set(CPACK_RPM_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}")
-
-# if we are creating a relocatable package, omit parent directories of
-# CPACK_RPM_PACKAGE_PREFIX. This is achieved by building a "filter list"
-# which is passed to the find command that generates the content-list
-if(CPACK_RPM_PACKAGE_RELOCATABLE)
- # get a list of the elements in CPACK_RPM_PACKAGE_PREFIX and remove
- # the final element (so the install-prefix dir itself is not omitted
- # from the RPM's content-list)
- string(REPLACE "/" ";" _CPACK_RPM_PACKAGE_PREFIX_ELEMS ".${CPACK_RPM_PACKAGE_PREFIX}")
- list(REMOVE_AT _CPACK_RPM_PACKAGE_PREFIX_ELEMS -1)
- # Now generate all of the parent dirs of CPACK_RPM_PACKAGE_PREFIX
- foreach(_ELEM ${_CPACK_RPM_PACKAGE_PREFIX_ELEMS})
- list(APPEND _TMP_LIST "${_ELEM}")
- string(REPLACE ";" "/" _OMIT_DIR "${_TMP_LIST}")
- set(_OMIT_DIR "-o -path ${_OMIT_DIR}")
- separate_arguments(_OMIT_DIR)
- list(APPEND _RPM_DIRS_TO_OMIT ${_OMIT_DIR})
- endforeach()
-endif()
-
-if (CPACK_RPM_PACKAGE_DEBUG)
- message("CPackRPM:Debug: Initial list of path to OMIT in RPM: ${_RPM_DIRS_TO_OMIT}")
-endif()
-
-if (NOT DEFINED CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST)
- set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST /etc /etc/init.d /usr /usr/share /usr/share/doc /usr/bin /usr/lib /usr/lib64 /usr/include)
- if (CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION)
- message("CPackRPM:Debug: Adding ${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION} to builtin omit list.")
- list(APPEND CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST "${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION}")
+ # Now we may create the RPM build tree structure
+ set(CPACK_RPM_ROOTDIR "${CPACK_TOPLEVEL_DIRECTORY}")
+ message(STATUS "CPackRPM:Debug: Using CPACK_RPM_ROOTDIR=${CPACK_RPM_ROOTDIR}")
+ # Prepare RPM build tree
+ file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR})
+ file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/tmp)
+ file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/BUILD)
+ file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/RPMS)
+ file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/SOURCES)
+ file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/SPECS)
+ file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/SRPMS)
+
+ #set(CPACK_RPM_FILE_NAME "${CPACK_RPM_PACKAGE_NAME}-${CPACK_RPM_PACKAGE_VERSION}-${CPACK_RPM_PACKAGE_RELEASE}-${_CPACK_RPM_PACKAGE_ARCHITECTURE}.rpm")
+ set(CPACK_RPM_FILE_NAME "${CPACK_OUTPUT_FILE_NAME}")
+ # it seems rpmbuild can't handle spaces in the path
+ # neither escaping (as below) nor putting quotes around the path seem to help
+ #string(REGEX REPLACE " " "\\\\ " CPACK_RPM_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}")
+ set(CPACK_RPM_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}")
+
+ cpack_rpm_prepare_content_list()
+
+ # In component case, put CPACK_ABSOLUTE_DESTINATION_FILES_<COMPONENT>
+ # into CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL
+ # otherwise, put CPACK_ABSOLUTE_DESTINATION_FILES
+ # This must be done BEFORE the CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL handling
+ if(CPACK_RPM_PACKAGE_COMPONENT)
+ if(CPACK_ABSOLUTE_DESTINATION_FILES)
+ set(COMPONENT_FILES_TAG "CPACK_ABSOLUTE_DESTINATION_FILES_${CPACK_RPM_PACKAGE_COMPONENT}")
+ set(CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL "${${COMPONENT_FILES_TAG}}")
+ if(CPACK_RPM_PACKAGE_DEBUG)
+ message("CPackRPM:Debug: Handling Absolute Destination Files: <${CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL}>")
+ message("CPackRPM:Debug: in component = ${CPACK_RPM_PACKAGE_COMPONENT}")
+ endif()
+ endif()
+ else()
+ if(CPACK_ABSOLUTE_DESTINATION_FILES)
+ set(CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL "${CPACK_ABSOLUTE_DESTINATION_FILES}")
+ endif()
endif()
-endif()
-if(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST)
- if (CPACK_RPM_PACKAGE_DEBUG)
- message("CPackRPM:Debug: CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST= ${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST}")
- endif()
- foreach(_DIR ${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST})
- list(APPEND _RPM_DIRS_TO_OMIT "-o;-path;.${_DIR}")
- endforeach()
-endif()
-if (CPACK_RPM_PACKAGE_DEBUG)
- message("CPackRPM:Debug: Final list of path to OMIT in RPM: ${_RPM_DIRS_TO_OMIT}")
-endif()
-
-# Use files tree to construct files command (spec file)
-# We should not forget to include symlinks (thus -o -type l)
-# We should include directory as well (thus -type d)
-# but not the main local dir "." (thus -a -not -name ".")
-# We must remove the './' due to the local search and escape the
-# file name by enclosing it between double quotes (thus the sed)
-# Then we must authorize any man pages extension (adding * at the end)
-# because rpmbuild may automatically compress those files
-execute_process(COMMAND find . -type f -o -type l -o (-type d -a -not ( -name "." ${_RPM_DIRS_TO_OMIT} ) )
- COMMAND sed s:.*/man.*/.*:&*:
- COMMAND sed s/\\.\\\(.*\\\)/\"\\1\"/
- WORKING_DIRECTORY "${WDIR}"
- OUTPUT_VARIABLE CPACK_RPM_INSTALL_FILES)
-
-# In component case, put CPACK_ABSOLUTE_DESTINATION_FILES_<COMPONENT>
-# into CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL
-# otherwise, put CPACK_ABSOLUTE_DESTINATION_FILES
-# This must be done BEFORE the CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL handling
-if(CPACK_RPM_PACKAGE_COMPONENT)
- if(CPACK_ABSOLUTE_DESTINATION_FILES)
- set(COMPONENT_FILES_TAG "CPACK_ABSOLUTE_DESTINATION_FILES_${CPACK_RPM_PACKAGE_COMPONENT}")
- set(CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL "${${COMPONENT_FILES_TAG}}")
- if(CPACK_RPM_PACKAGE_DEBUG)
- message("CPackRPM:Debug: Handling Absolute Destination Files: <${CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL}>")
- message("CPackRPM:Debug: in component = ${CPACK_RPM_PACKAGE_COMPONENT}")
- endif()
- endif()
-else()
- if(CPACK_ABSOLUTE_DESTINATION_FILES)
- set(CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL "${CPACK_ABSOLUTE_DESTINATION_FILES}")
+ # In component case, set CPACK_RPM_USER_FILELIST_INTERNAL with CPACK_RPM_<COMPONENT>_USER_FILELIST.
+ if(CPACK_RPM_PACKAGE_COMPONENT)
+ if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_USER_FILELIST)
+ set(CPACK_RPM_USER_FILELIST_INTERNAL ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_USER_FILELIST})
+ if(CPACK_RPM_PACKAGE_DEBUG)
+ message("CPackRPM:Debug: Handling User Filelist: <${CPACK_RPM_USER_FILELIST_INTERNAL}>")
+ message("CPackRPM:Debug: in component = ${CPACK_RPM_PACKAGE_COMPONENT}")
+ endif()
+ else()
+ set(CPACK_RPM_USER_FILELIST_INTERNAL "")
+ endif()
+ else()
+ if(CPACK_RPM_USER_FILELIST)
+ set(CPACK_RPM_USER_FILELIST_INTERNAL "${CPACK_RPM_USER_FILELIST}")
+ else()
+ set(CPACK_RPM_USER_FILELIST_INTERNAL "")
+ endif()
endif()
-endif()
-# In component case, set CPACK_RPM_USER_FILELIST_INTERNAL with CPACK_RPM_<COMPONENT>_USER_FILELIST.
-if(CPACK_RPM_PACKAGE_COMPONENT)
- if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_USER_FILELIST)
- set(CPACK_RPM_USER_FILELIST_INTERNAL ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_USER_FILELIST})
+ # Handle user specified file line list in CPACK_RPM_USER_FILELIST_INTERNAL
+ # Remove those files from CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL
+ # or CPACK_RPM_INSTALL_FILES,
+ # hence it must be done before these auto-generated lists are processed.
+ if(CPACK_RPM_USER_FILELIST_INTERNAL)
if(CPACK_RPM_PACKAGE_DEBUG)
message("CPackRPM:Debug: Handling User Filelist: <${CPACK_RPM_USER_FILELIST_INTERNAL}>")
- message("CPackRPM:Debug: in component = ${CPACK_RPM_PACKAGE_COMPONENT}")
endif()
- else()
- set(CPACK_RPM_USER_FILELIST_INTERNAL "")
- endif()
-else()
- if(CPACK_RPM_USER_FILELIST)
- set(CPACK_RPM_USER_FILELIST_INTERNAL "${CPACK_RPM_USER_FILELIST}")
- else()
- set(CPACK_RPM_USER_FILELIST_INTERNAL "")
- endif()
-endif()
-# Handle user specified file line list in CPACK_RPM_USER_FILELIST_INTERNAL
-# Remove those files from CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL
-# or CPACK_RPM_INSTALL_FILES,
-# hence it must be done before these auto-generated lists are processed.
-if(CPACK_RPM_USER_FILELIST_INTERNAL)
- if(CPACK_RPM_PACKAGE_DEBUG)
- message("CPackRPM:Debug: Handling User Filelist: <${CPACK_RPM_USER_FILELIST_INTERNAL}>")
+ # Create CMake list from CPACK_RPM_INSTALL_FILES
+ string(STRIP "${CPACK_RPM_INSTALL_FILES}" CPACK_RPM_INSTALL_FILES_LIST)
+ string(REPLACE "\n" ";" CPACK_RPM_INSTALL_FILES_LIST
+ "${CPACK_RPM_INSTALL_FILES_LIST}")
+ string(REPLACE "\"" "" CPACK_RPM_INSTALL_FILES_LIST
+ "${CPACK_RPM_INSTALL_FILES_LIST}")
+
+ set(CPACK_RPM_USER_INSTALL_FILES "")
+ foreach(F IN LISTS CPACK_RPM_USER_FILELIST_INTERNAL)
+ string(REGEX REPLACE "%[A-Za-z0-9\(\),-]* " "" F_PATH ${F})
+ string(REGEX MATCH "%[A-Za-z0-9\(\),-]*" F_PREFIX ${F})
+
+ if(CPACK_RPM_PACKAGE_DEBUG)
+ message("CPackRPM:Debug: F_PREFIX=<${F_PREFIX}>, F_PATH=<${F_PATH}>")
+ endif()
+ if(F_PREFIX)
+ set(F_PREFIX "${F_PREFIX} ")
+ endif()
+ # Rebuild the user list file
+ set(CPACK_RPM_USER_INSTALL_FILES "${CPACK_RPM_USER_INSTALL_FILES}${F_PREFIX}\"${F_PATH}\"\n")
+
+ # Remove from CPACK_RPM_INSTALL_FILES and CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL
+ list(REMOVE_ITEM CPACK_RPM_INSTALL_FILES_LIST ${F_PATH})
+ # ABSOLUTE destination files list may not exists at all
+ if (CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL)
+ list(REMOVE_ITEM CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL ${F_PATH})
+ endif()
+
+ endforeach()
+
+ # Rebuild CPACK_RPM_INSTALL_FILES
+ set(CPACK_RPM_INSTALL_FILES "")
+ foreach(F IN LISTS CPACK_RPM_INSTALL_FILES_LIST)
+ set(CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}\"${F}\"\n")
+ endforeach()
+ else()
+ set(CPACK_RPM_USER_INSTALL_FILES "")
endif()
- # Create CMake list from CPACK_RPM_INSTALL_FILES
- string(STRIP "${CPACK_RPM_INSTALL_FILES}" CPACK_RPM_INSTALL_FILES_LIST)
- string(REPLACE "\n" ";" CPACK_RPM_INSTALL_FILES_LIST
- "${CPACK_RPM_INSTALL_FILES_LIST}")
- string(REPLACE "\"" "" CPACK_RPM_INSTALL_FILES_LIST
- "${CPACK_RPM_INSTALL_FILES_LIST}")
-
- set(CPACK_RPM_USER_INSTALL_FILES "")
- foreach(F IN LISTS CPACK_RPM_USER_FILELIST_INTERNAL)
- string(REGEX REPLACE "%[A-Za-z0-9\(\),-]* " "" F_PATH ${F})
- string(REGEX MATCH "%[A-Za-z0-9\(\),-]*" F_PREFIX ${F})
-
+ if (CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL)
if(CPACK_RPM_PACKAGE_DEBUG)
- message("CPackRPM:Debug: F_PREFIX=<${F_PREFIX}>, F_PATH=<${F_PATH}>")
- endif()
- if(F_PREFIX)
- set(F_PREFIX "${F_PREFIX} ")
+ message("CPackRPM:Debug: Handling Absolute Destination Files: ${CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL}")
endif()
- # Rebuild the user list file
- set(CPACK_RPM_USER_INSTALL_FILES "${CPACK_RPM_USER_INSTALL_FILES}${F_PREFIX}\"${F_PATH}\"\n")
-
- # Remove from CPACK_RPM_INSTALL_FILES and CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL
- list(REMOVE_ITEM CPACK_RPM_INSTALL_FILES_LIST ${F_PATH})
- # ABSOLUTE destination files list may not exists at all
- if (CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL)
- list(REMOVE_ITEM CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL ${F_PATH})
+ # Remove trailing space
+ string(STRIP "${CPACK_RPM_INSTALL_FILES}" CPACK_RPM_INSTALL_FILES_LIST)
+ # Transform endline separated - string into CMake List
+ string(REPLACE "\n" ";" CPACK_RPM_INSTALL_FILES_LIST "${CPACK_RPM_INSTALL_FILES_LIST}")
+ # Remove unecessary quotes
+ string(REPLACE "\"" "" CPACK_RPM_INSTALL_FILES_LIST "${CPACK_RPM_INSTALL_FILES_LIST}")
+ # Remove ABSOLUTE install file from INSTALL FILE LIST
+ list(REMOVE_ITEM CPACK_RPM_INSTALL_FILES_LIST ${CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL})
+ # Rebuild INSTALL_FILES
+ set(CPACK_RPM_INSTALL_FILES "")
+ foreach(F IN LISTS CPACK_RPM_INSTALL_FILES_LIST)
+ set(CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}\"${F}\"\n")
+ endforeach()
+ # Build ABSOLUTE_INSTALL_FILES
+ set(CPACK_RPM_ABSOLUTE_INSTALL_FILES "")
+ foreach(F IN LISTS CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL)
+ set(CPACK_RPM_ABSOLUTE_INSTALL_FILES "${CPACK_RPM_ABSOLUTE_INSTALL_FILES}%config \"${F}\"\n")
+ endforeach()
+ if(CPACK_RPM_PACKAGE_DEBUG)
+ message("CPackRPM:Debug: CPACK_RPM_ABSOLUTE_INSTALL_FILES=${CPACK_RPM_ABSOLUTE_INSTALL_FILES}")
+ message("CPackRPM:Debug: CPACK_RPM_INSTALL_FILES=${CPACK_RPM_INSTALL_FILES}")
endif()
+ else()
+ # reset vars in order to avoid leakage of value(s) from one component to another
+ set(CPACK_RPM_ABSOLUTE_INSTALL_FILES "")
+ endif()
- endforeach()
+ # Prepare install files
+ cpack_rpm_prepare_install_files(
+ "${CPACK_RPM_INSTALL_FILES}"
+ "${WDIR}"
+ "${RPM_USED_PACKAGE_PREFIXES}"
+ "${CPACK_RPM_PACKAGE_RELOCATABLE}"
+ )
- # Rebuild CPACK_RPM_INSTALL_FILES
- set(CPACK_RPM_INSTALL_FILES "")
- foreach(F IN LISTS CPACK_RPM_INSTALL_FILES_LIST)
- set(CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}\"${F}\"\n")
- endforeach()
-else()
- set(CPACK_RPM_USER_INSTALL_FILES "")
-endif()
+ # The name of the final spec file to be used by rpmbuild
+ set(CPACK_RPM_BINARY_SPECFILE "${CPACK_RPM_ROOTDIR}/SPECS/${CPACK_RPM_PACKAGE_NAME}.spec")
-if (CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL)
+ # Print out some debug information if we were asked for that
if(CPACK_RPM_PACKAGE_DEBUG)
- message("CPackRPM:Debug: Handling Absolute Destination Files: ${CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL}")
- endif()
- # Remove trailing space
- string(STRIP "${CPACK_RPM_INSTALL_FILES}" CPACK_RPM_INSTALL_FILES_LIST)
- # Transform endline separated - string into CMake List
- string(REPLACE "\n" ";" CPACK_RPM_INSTALL_FILES_LIST "${CPACK_RPM_INSTALL_FILES_LIST}")
- # Remove unecessary quotes
- string(REPLACE "\"" "" CPACK_RPM_INSTALL_FILES_LIST "${CPACK_RPM_INSTALL_FILES_LIST}")
- # Remove ABSOLUTE install file from INSTALL FILE LIST
- list(REMOVE_ITEM CPACK_RPM_INSTALL_FILES_LIST ${CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL})
- # Rebuild INSTALL_FILES
- set(CPACK_RPM_INSTALL_FILES "")
- foreach(F IN LISTS CPACK_RPM_INSTALL_FILES_LIST)
- set(CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}\"${F}\"\n")
- endforeach()
- # Build ABSOLUTE_INSTALL_FILES
- set(CPACK_RPM_ABSOLUTE_INSTALL_FILES "")
- foreach(F IN LISTS CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL)
- set(CPACK_RPM_ABSOLUTE_INSTALL_FILES "${CPACK_RPM_ABSOLUTE_INSTALL_FILES}%config \"${F}\"\n")
- endforeach()
- if(CPACK_RPM_PACKAGE_DEBUG)
- message("CPackRPM:Debug: CPACK_RPM_ABSOLUTE_INSTALL_FILES=${CPACK_RPM_ABSOLUTE_INSTALL_FILES}")
- message("CPackRPM:Debug: CPACK_RPM_INSTALL_FILES=${CPACK_RPM_INSTALL_FILES}")
+ message("CPackRPM:Debug: CPACK_TOPLEVEL_DIRECTORY = ${CPACK_TOPLEVEL_DIRECTORY}")
+ message("CPackRPM:Debug: CPACK_TOPLEVEL_TAG = ${CPACK_TOPLEVEL_TAG}")
+ message("CPackRPM:Debug: CPACK_TEMPORARY_DIRECTORY = ${CPACK_TEMPORARY_DIRECTORY}")
+ message("CPackRPM:Debug: CPACK_OUTPUT_FILE_NAME = ${CPACK_OUTPUT_FILE_NAME}")
+ message("CPackRPM:Debug: CPACK_OUTPUT_FILE_PATH = ${CPACK_OUTPUT_FILE_PATH}")
+ message("CPackRPM:Debug: CPACK_PACKAGE_FILE_NAME = ${CPACK_PACKAGE_FILE_NAME}")
+ message("CPackRPM:Debug: CPACK_RPM_BINARY_SPECFILE = ${CPACK_RPM_BINARY_SPECFILE}")
+ message("CPackRPM:Debug: CPACK_PACKAGE_INSTALL_DIRECTORY = ${CPACK_PACKAGE_INSTALL_DIRECTORY}")
+ message("CPackRPM:Debug: CPACK_TEMPORARY_PACKAGE_FILE_NAME = ${CPACK_TEMPORARY_PACKAGE_FILE_NAME}")
endif()
-else()
- # reset vars in order to avoid leakage of value(s) from one component to another
- set(CPACK_RPM_ABSOLUTE_INSTALL_FILES "")
-endif()
-# Prepend directories in ${CPACK_RPM_INSTALL_FILES} with %dir
-# This is necessary to avoid duplicate files since rpmbuild do
-# recursion on its own when encountering a pathname which is a directory
-# which is not flagged as %dir
-string(STRIP "${CPACK_RPM_INSTALL_FILES}" CPACK_RPM_INSTALL_FILES_LIST)
-string(REPLACE "\n" ";" CPACK_RPM_INSTALL_FILES_LIST
- "${CPACK_RPM_INSTALL_FILES_LIST}")
-string(REPLACE "\"" "" CPACK_RPM_INSTALL_FILES_LIST
- "${CPACK_RPM_INSTALL_FILES_LIST}")
-set(CPACK_RPM_INSTALL_FILES "")
-foreach(F IN LISTS CPACK_RPM_INSTALL_FILES_LIST)
- if(IS_DIRECTORY "${WDIR}/${F}")
- set(CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}%dir \"${F}\"\n")
- else()
- set(CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}\"${F}\"\n")
- endif()
-endforeach()
-set(CPACK_RPM_INSTALL_FILES_LIST "")
-
-# The name of the final spec file to be used by rpmbuild
-set(CPACK_RPM_BINARY_SPECFILE "${CPACK_RPM_ROOTDIR}/SPECS/${CPACK_RPM_PACKAGE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.spec")
-
-# Print out some debug information if we were asked for that
-if(CPACK_RPM_PACKAGE_DEBUG)
- message("CPackRPM:Debug: CPACK_TOPLEVEL_DIRECTORY = ${CPACK_TOPLEVEL_DIRECTORY}")
- message("CPackRPM:Debug: CPACK_TOPLEVEL_TAG = ${CPACK_TOPLEVEL_TAG}")
- message("CPackRPM:Debug: CPACK_TEMPORARY_DIRECTORY = ${CPACK_TEMPORARY_DIRECTORY}")
- message("CPackRPM:Debug: CPACK_OUTPUT_FILE_NAME = ${CPACK_OUTPUT_FILE_NAME}")
- message("CPackRPM:Debug: CPACK_OUTPUT_FILE_PATH = ${CPACK_OUTPUT_FILE_PATH}")
- message("CPackRPM:Debug: CPACK_PACKAGE_FILE_NAME = ${CPACK_PACKAGE_FILE_NAME}")
- message("CPackRPM:Debug: CPACK_RPM_BINARY_SPECFILE = ${CPACK_RPM_BINARY_SPECFILE}")
- message("CPackRPM:Debug: CPACK_PACKAGE_INSTALL_DIRECTORY = ${CPACK_PACKAGE_INSTALL_DIRECTORY}")
- message("CPackRPM:Debug: CPACK_TEMPORARY_PACKAGE_FILE_NAME = ${CPACK_TEMPORARY_PACKAGE_FILE_NAME}")
-endif()
+ #
+ # USER generated/provided spec file handling.
+ #
-# protect @ in pathname in order to avoid their
-# interpretation during the configure_file step
-set(CPACK_RPM_INSTALL_FILES_LIST "${CPACK_RPM_INSTALL_FILES}")
-set(PROTECTED_AT "@")
-string(REPLACE "@" "\@PROTECTED_AT\@" CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES_LIST}")
-set(CPACK_RPM_INSTALL_FILES_LIST "")
-
-#
-# USER generated/provided spec file handling.
-#
-
-# We can have a component specific spec file.
-if(CPACK_RPM_PACKAGE_COMPONENT AND CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_USER_BINARY_SPECFILE)
- set(CPACK_RPM_USER_BINARY_SPECFILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_USER_BINARY_SPECFILE})
-endif()
+ # We can have a component specific spec file.
+ if(CPACK_RPM_PACKAGE_COMPONENT AND CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_USER_BINARY_SPECFILE)
+ set(CPACK_RPM_USER_BINARY_SPECFILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_USER_BINARY_SPECFILE})
+ endif()
-# We should generate a USER spec file template:
-# - either because the user asked for it : CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE
-# - or the user did not provide one : NOT CPACK_RPM_USER_BINARY_SPECFILE
-if(CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE OR NOT CPACK_RPM_USER_BINARY_SPECFILE)
- file(WRITE ${CPACK_RPM_BINARY_SPECFILE}.in
+ # We should generate a USER spec file template:
+ # - either because the user asked for it : CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE
+ # - or the user did not provide one : NOT CPACK_RPM_USER_BINARY_SPECFILE
+ if(CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE OR NOT CPACK_RPM_USER_BINARY_SPECFILE)
+ file(WRITE ${CPACK_RPM_BINARY_SPECFILE}.in
"# -*- rpm-spec -*-
BuildRoot: \@CPACK_RPM_DIRECTORY\@/\@CPACK_PACKAGE_FILE_NAME\@\@CPACK_RPM_PACKAGE_COMPONENT_PART_PATH\@
Summary: \@CPACK_RPM_PACKAGE_SUMMARY\@
-Name: \@CPACK_RPM_PACKAGE_NAME\@\@CPACK_RPM_PACKAGE_COMPONENT_PART_NAME\@
+Name: \@CPACK_RPM_PACKAGE_NAME\@
Version: \@CPACK_RPM_PACKAGE_VERSION\@
Release: \@CPACK_RPM_PACKAGE_RELEASE\@
License: \@CPACK_RPM_PACKAGE_LICENSE\@
@@ -908,6 +1670,10 @@ Group: \@CPACK_RPM_PACKAGE_GROUP\@
Vendor: \@CPACK_RPM_PACKAGE_VENDOR\@
\@TMP_RPM_URL\@
\@TMP_RPM_REQUIRES\@
+\@TMP_RPM_REQUIRES_PRE\@
+\@TMP_RPM_REQUIRES_POST\@
+\@TMP_RPM_REQUIRES_PREUN\@
+\@TMP_RPM_REQUIRES_POSTUN\@
\@TMP_RPM_PROVIDES\@
\@TMP_RPM_OBSOLETES\@
\@TMP_RPM_CONFLICTS\@
@@ -915,7 +1681,7 @@ Vendor: \@CPACK_RPM_PACKAGE_VENDOR\@
\@TMP_RPM_AUTOREQ\@
\@TMP_RPM_AUTOREQPROV\@
\@TMP_RPM_BUILDARCH\@
-\@TMP_RPM_PREFIX\@
+\@TMP_RPM_PREFIXES\@
%define _rpmdir \@CPACK_RPM_DIRECTORY\@
%define _rpmfilename \@CPACK_RPM_FILE_NAME\@
@@ -947,6 +1713,7 @@ mv \"\@CPACK_TOPLEVEL_DIRECTORY\@/tmpBBroot\" $RPM_BUILD_ROOT
%clean
%post
+\@RPM_SYMLINK_POSTINSTALL\@
\@CPACK_RPM_SPEC_POSTINSTALL\@
%postun
@@ -967,53 +1734,54 @@ mv \"\@CPACK_TOPLEVEL_DIRECTORY\@/tmpBBroot\" $RPM_BUILD_ROOT
%changelog
\@CPACK_RPM_SPEC_CHANGELOG\@
")
- # Stop here if we were asked to only generate a template USER spec file
- # The generated file may then be used as a template by user who wants
- # to customize their own spec file.
- if(CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE)
- message(FATAL_ERROR "CPackRPM: STOP here Generated USER binary spec file templare is: ${CPACK_RPM_BINARY_SPECFILE}.in")
+ # Stop here if we were asked to only generate a template USER spec file
+ # The generated file may then be used as a template by user who wants
+ # to customize their own spec file.
+ if(CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE)
+ message(FATAL_ERROR "CPackRPM: STOP here Generated USER binary spec file templare is: ${CPACK_RPM_BINARY_SPECFILE}.in")
+ endif()
endif()
-endif()
-# After that we may either use a user provided spec file
-# or generate one using appropriate variables value.
-if(CPACK_RPM_USER_BINARY_SPECFILE)
- # User may have specified SPECFILE just use it
- message("CPackRPM: Will use USER specified spec file: ${CPACK_RPM_USER_BINARY_SPECFILE}")
- # The user provided file is processed for @var replacement
- configure_file(${CPACK_RPM_USER_BINARY_SPECFILE} ${CPACK_RPM_BINARY_SPECFILE} @ONLY)
-else()
- # No User specified spec file, will use the generated spec file
- message("CPackRPM: Will use GENERATED spec file: ${CPACK_RPM_BINARY_SPECFILE}")
- # Note the just created file is processed for @var replacement
- configure_file(${CPACK_RPM_BINARY_SPECFILE}.in ${CPACK_RPM_BINARY_SPECFILE} @ONLY)
-endif()
+ # After that we may either use a user provided spec file
+ # or generate one using appropriate variables value.
+ if(CPACK_RPM_USER_BINARY_SPECFILE)
+ # User may have specified SPECFILE just use it
+ message("CPackRPM: Will use USER specified spec file: ${CPACK_RPM_USER_BINARY_SPECFILE}")
+ # The user provided file is processed for @var replacement
+ configure_file(${CPACK_RPM_USER_BINARY_SPECFILE} ${CPACK_RPM_BINARY_SPECFILE} @ONLY)
+ else()
+ # No User specified spec file, will use the generated spec file
+ message("CPackRPM: Will use GENERATED spec file: ${CPACK_RPM_BINARY_SPECFILE}")
+ # Note the just created file is processed for @var replacement
+ configure_file(${CPACK_RPM_BINARY_SPECFILE}.in ${CPACK_RPM_BINARY_SPECFILE} @ONLY)
+ endif()
-# remove AT protection
-unset(PROTECTED_AT)
-
-if(RPMBUILD_EXECUTABLE)
- # Now call rpmbuild using the SPECFILE
- execute_process(
- COMMAND "${RPMBUILD_EXECUTABLE}" -bb
- --define "_topdir ${CPACK_RPM_DIRECTORY}"
- --buildroot "${CPACK_RPM_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}"
- "${CPACK_RPM_BINARY_SPECFILE}"
- WORKING_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}"
- RESULT_VARIABLE CPACK_RPMBUILD_EXEC_RESULT
- ERROR_FILE "${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.err"
- OUTPUT_FILE "${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.out")
- if(CPACK_RPM_PACKAGE_DEBUG OR CPACK_RPMBUILD_EXEC_RESULT)
- file(READ ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.err RPMBUILDERR)
- file(READ ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.out RPMBUILDOUT)
- message("CPackRPM:Debug: You may consult rpmbuild logs in: ")
- message("CPackRPM:Debug: - ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.err")
- message("CPackRPM:Debug: *** ${RPMBUILDERR} ***")
- message("CPackRPM:Debug: - ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.out")
- message("CPackRPM:Debug: *** ${RPMBUILDERR} ***")
- endif()
-else()
- if(ALIEN_EXECUTABLE)
- message(FATAL_ERROR "RPM packaging through alien not done (yet)")
+ if(RPMBUILD_EXECUTABLE)
+ # Now call rpmbuild using the SPECFILE
+ execute_process(
+ COMMAND "${RPMBUILD_EXECUTABLE}" -bb
+ --define "_topdir ${CPACK_RPM_DIRECTORY}"
+ --buildroot "${CPACK_RPM_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}"
+ --target "${_CPACK_RPM_PACKAGE_ARCHITECTURE}"
+ "${CPACK_RPM_BINARY_SPECFILE}"
+ WORKING_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}"
+ RESULT_VARIABLE CPACK_RPMBUILD_EXEC_RESULT
+ ERROR_FILE "${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.err"
+ OUTPUT_FILE "${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.out")
+ if(CPACK_RPM_PACKAGE_DEBUG OR CPACK_RPMBUILD_EXEC_RESULT)
+ file(READ ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.err RPMBUILDERR)
+ file(READ ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.out RPMBUILDOUT)
+ message("CPackRPM:Debug: You may consult rpmbuild logs in: ")
+ message("CPackRPM:Debug: - ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.err")
+ message("CPackRPM:Debug: *** ${RPMBUILDERR} ***")
+ message("CPackRPM:Debug: - ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.out")
+ message("CPackRPM:Debug: *** ${RPMBUILDOUT} ***")
+ endif()
+ else()
+ if(ALIEN_EXECUTABLE)
+ message(FATAL_ERROR "RPM packaging through alien not done (yet)")
+ endif()
endif()
-endif()
+endfunction()
+
+cpack_rpm_generate_package()
diff --git a/Modules/CPackWIX.cmake b/Modules/CPackWIX.cmake
index fce25f07a..499400515 100644
--- a/Modules/CPackWIX.cmake
+++ b/Modules/CPackWIX.cmake
@@ -1,110 +1,245 @@
-##section Variables specific to CPack WiX generator
-##end
-##module
-# - CPack WiX generator specific options
-#
-# The following variables are specific to the installers built
-# on Windows using WiX.
-##end
-##variable
-# CPACK_WIX_UPGRADE_GUID - Upgrade GUID (Product/@UpgradeCode)
-#
-# Will be automatically generated unless explicitly provided.
-#
-# It should be explicitly set to a constant generated
-# gloabally unique identifier (GUID) to allow your installers
-# to replace existing installations that use the same GUID.
-#
-# You may for example explicitly set this variable in
-# your CMakeLists.txt to the value that has been generated per default.
-# You should not use GUIDs that you did not generate yourself or which may
-# belong to other projects.
-#
-# A GUID shall have the following fixed length syntax:
-# XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
+#.rst:
+# CPackWIX
+# --------
+#
+# CPack WiX generator specific options
+#
+# Variables specific to CPack WiX generator
+# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#
+# The following variables are specific to the installers built on
+# Windows using WiX.
+#
+# .. variable:: CPACK_WIX_UPGRADE_GUID
+#
+# Upgrade GUID (``Product/@UpgradeCode``)
+#
+# Will be automatically generated unless explicitly provided.
+#
+# It should be explicitly set to a constant generated globally unique
+# identifier (GUID) to allow your installers to replace existing
+# installations that use the same GUID.
+#
+# You may for example explicitly set this variable in your
+# CMakeLists.txt to the value that has been generated per default. You
+# should not use GUIDs that you did not generate yourself or which may
+# belong to other projects.
+#
+# A GUID shall have the following fixed length syntax::
+#
+# XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
+#
# (each X represents an uppercase hexadecimal digit)
-##end
-##variable
-# CPACK_WIX_PRODUCT_GUID - Product GUID (Product/@Id)
#
-# Will be automatically generated unless explicitly provided.
+# .. variable:: CPACK_WIX_PRODUCT_GUID
+#
+# Product GUID (``Product/@Id``)
+#
+# Will be automatically generated unless explicitly provided.
+#
+# If explicitly provided this will set the Product Id of your installer.
+#
+# The installer will abort if it detects a pre-existing installation that
+# uses the same GUID.
+#
+# The GUID shall use the syntax described for CPACK_WIX_UPGRADE_GUID.
+#
+# .. variable:: CPACK_WIX_LICENSE_RTF
+#
+# RTF License File
+#
+# If CPACK_RESOURCE_FILE_LICENSE has an .rtf extension it is used as-is.
+#
+# If CPACK_RESOURCE_FILE_LICENSE has an .txt extension it is implicitly
+# converted to RTF by the WiX Generator.
+# The expected encoding of the .txt file is UTF-8.
+#
+# With CPACK_WIX_LICENSE_RTF you can override the license file used by the
+# WiX Generator in case CPACK_RESOURCE_FILE_LICENSE is in an unsupported
+# format or the .txt -> .rtf conversion does not work as expected.
+#
+# .. variable:: CPACK_WIX_PRODUCT_ICON
+#
+# The Icon shown next to the program name in Add/Remove programs.
+#
+# If set, this icon is used in place of the default icon.
+#
+# .. variable:: CPACK_WIX_UI_REF
+#
+# This variable allows you to override the Id of the ``<UIRef>`` element
+# in the WiX template.
+#
+# The default is ``WixUI_InstallDir`` in case no CPack components have
+# been defined and ``WixUI_FeatureTree`` otherwise.
+#
+# .. variable:: CPACK_WIX_UI_BANNER
+#
+# The bitmap will appear at the top of all installer pages other than the
+# welcome and completion dialogs.
+#
+# If set, this image will replace the default banner image.
+#
+# This image must be 493 by 58 pixels.
+#
+# .. variable:: CPACK_WIX_UI_DIALOG
+#
+# Background bitmap used on the welcome and completion dialogs.
+#
+# If this variable is set, the installer will replace the default dialog
+# image.
+#
+# This image must be 493 by 312 pixels.
+#
+# .. variable:: CPACK_WIX_PROGRAM_MENU_FOLDER
+#
+# Start menu folder name for launcher.
+#
+# If this variable is not set, it will be initialized with CPACK_PACKAGE_NAME
+#
+# .. variable:: CPACK_WIX_CULTURES
+#
+# Language(s) of the installer
+#
+# Languages are compiled into the WixUI extension library. To use them,
+# simply provide the name of the culture. If you specify more than one
+# culture identifier in a comma or semicolon delimited list, the first one
+# that is found will be used. You can find a list of supported languages at:
+# http://wix.sourceforge.net/manual-wix3/WixUI_localization.htm
+#
+# .. variable:: CPACK_WIX_TEMPLATE
+#
+# Template file for WiX generation
+#
+# If this variable is set, the specified template will be used to generate
+# the WiX wxs file. This should be used if further customization of the
+# output is required.
+#
+# If this variable is not set, the default MSI template included with CMake
+# will be used.
+#
+# .. variable:: CPACK_WIX_PATCH_FILE
+#
+# Optional list of XML files with fragments to be inserted into
+# generated WiX sources
+#
+# This optional variable can be used to specify an XML file that the
+# WiX generator will use to inject fragments into its generated
+# source files.
+#
+# Patch files understood by the CPack WiX generator
+# roughly follow this RELAX NG compact schema:
+#
+# .. code-block:: none
+#
+# start = CPackWiXPatch
+#
+# CPackWiXPatch = element CPackWiXPatch { CPackWiXFragment* }
+#
+# CPackWiXFragment = element CPackWiXFragment
+# {
+# attribute Id { string },
+# fragmentContent*
+# }
+#
+# fragmentContent = element * - CPackWiXFragment
+# {
+# (attribute * { text } | text | fragmentContent)*
+# }
+#
+# Currently fragments can be injected into most
+# Component, File and Directory elements.
+#
+# The following additional special Ids can be used:
+#
+# * ``#PRODUCT`` for the ``<Product>`` element.
+# * ``#PRODUCTFEATURE`` for the root ``<Feature>`` element.
+#
+# The following example illustrates how this works.
+#
+# Given that the WiX generator creates the following XML element:
#
-# If explicitly provided this will set the Product Id of your installer.
+# .. code-block:: xml
#
-# The installer will abort if it detects a pre-existing installation that uses
-# the same GUID.
+# <Component Id="CM_CP_applications.bin.my_libapp.exe" Guid="*"/>
#
-# The GUID shall use the syntax described for CPACK_WIX_UPGRADE_GUID.
-##end
-##variable
-# CPACK_WIX_LICENSE_RTF - RTF License File
+# The following XML patch file may be used to inject an Environment element
+# into it:
#
-# If CPACK_RESOURCE_FILE_LICENSE has an .rtf extension
-# it is used as-is.
+# .. code-block:: xml
#
-# If CPACK_RESOURCE_FILE_LICENSE has an .txt extension
-# it is implicitly converted to RTF by the WiX Generator.
+# <CPackWiXPatch>
+# <CPackWiXFragment Id="CM_CP_applications.bin.my_libapp.exe">
+# <Environment Id="MyEnvironment" Action="set"
+# Name="MyVariableName" Value="MyVariableValue"/>
+# </CPackWiXFragment>
+# </CPackWiXPatch>
#
-# With CPACK_WIX_LICENSE_RTF you can override the license file used
-# by the WiX Generator in case CPACK_RESOURCE_FILE_LICENSE
-# is in an unsupported format or the .txt -> .rtf
-# conversion does not work as expected.
+# .. variable:: CPACK_WIX_EXTRA_SOURCES
#
-##end
+# Extra WiX source files
#
-##variable
-# CPACK_WIX_PRODUCT_ICON - The Icon shown next to the program name in Add/Remove programs.
+# This variable provides an optional list of extra WiX source files (.wxs)
+# that should be compiled and linked. The full path to source files is
+# required.
#
-# If set, this icon is used in place of the default icon.
+# .. variable:: CPACK_WIX_EXTRA_OBJECTS
#
-##end
+# Extra WiX object files or libraries
#
-##variable
-# CPACK_WIX_UI_BANNER - The bitmap will appear at the top of all installer pages other than the welcome and completion dialogs.
+# This variable provides an optional list of extra WiX object (.wixobj)
+# and/or WiX library (.wixlib) files. The full path to objects and libraries
+# is required.
#
-# If set, this image will replace the default banner image.
+# .. variable:: CPACK_WIX_EXTENSIONS
#
-# This image must be 493 by 58 pixels.
+# This variable provides a list of additional extensions for the WiX
+# tools light and candle.
#
-##end
+# .. variable:: CPACK_WIX_<TOOL>_EXTENSIONS
#
-##variable
-# CPACK_WIX_UI_DIALOG - Background bitmap used on the welcome and completion dialogs.
+# This is the tool specific version of CPACK_WIX_EXTENSIONS.
+# ``<TOOL>`` can be either LIGHT or CANDLE.
#
-# If this variable is set, the installer will replace the default dialog image.
+# .. variable:: CPACK_WIX_<TOOL>_EXTRA_FLAGS
#
-# This image must be 493 by 312 pixels.
+# This list variable allows you to pass additional
+# flags to the WiX tool ``<TOOL>``.
#
-##end
+# Use it at your own risk.
+# Future versions of CPack may generate flags which may be in conflict
+# with your own flags.
#
-##variable
-# CPACK_WIX_PROGRAM_MENU_FOLDER - Start menu folder name for launcher.
+# ``<TOOL>`` can be either LIGHT or CANDLE.
#
-# If this variable is not set, it will be initialized with CPACK_PACKAGE_NAME
+# .. variable:: CPACK_WIX_CMAKE_PACKAGE_REGISTRY
#
-##end
-##variable
-# CPACK_WIX_CULTURES - Language(s) of the installer
+# If this variable is set the generated installer will create
+# an entry in the windows registry key
+# ``HKEY_LOCAL_MACHINE\Software\Kitware\CMake\Packages\<package>``
+# The value for ``<package>`` is provided by this variable.
#
-# Languages are compiled into the WixUI extension library. To use them,
-# simply provide the name of the culture. If you specify more than one
-# culture identifier in a comma or semicolon delimited list, the first one
-# that is found will be used. You can find a list of supported languages at:
-# http://wix.sourceforge.net/manual-wix3/WixUI_localization.htm
+# Assuming you also install a CMake configuration file this will
+# allow other CMake projects to find your package with
+# the :command:`find_package` command.
#
-##end
-##variable
-# CPACK_WIX_TEMPLATE - Template file for WiX generation
+# .. variable:: CPACK_WIX_PROPERTY_<PROPERTY>
#
-# If this variable is set, the specified template will be used to generate the WiX wxs file.
-# This should be used if further customization of the output is required.
+# This variable can be used to provide a value for
+# the Windows Installer property ``<PROPERTY>``
#
-# If this variable is not set, the default MSI template included with CMake will be used.
+# The following list contains some example properties that can be used to
+# customize information under
+# "Programs and Features" (also known as "Add or Remove Programs")
#
-##end
+# * ARPCOMMENTS - Comments
+# * ARPHELPLINK - Help and support information URL
+# * ARPURLINFOABOUT - General information URL
+# * URLUPDATEINFO - Update information URL
+# * ARPHELPTELEPHONE - Help and support telephone number
+# * ARPSIZE - Size (in kilobytes) of the application
#=============================================================================
-# Copyright 2012 Kitware, Inc.
+# Copyright 2014-2015 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
diff --git a/Modules/CTest.cmake b/Modules/CTest.cmake
index 5cd62f607..8278c5c4b 100644
--- a/Modules/CTest.cmake
+++ b/Modules/CTest.cmake
@@ -1,49 +1,52 @@
-# - Configure a project for testing with CTest/CDash
-# Include this module in the top CMakeLists.txt file of a project to
-# enable testing with CTest and dashboard submissions to CDash:
-# project(MyProject)
-# ...
-# include(CTest)
-# The module automatically creates a BUILD_TESTING option that selects
-# whether to enable testing support (ON by default). After including
-# the module, use code like
-# if(BUILD_TESTING)
-# # ... CMake code to create tests ...
-# endif()
-# to creating tests when testing is enabled.
-#
-# To enable submissions to a CDash server, create a CTestConfig.cmake
-# file at the top of the project with content such as
-# set(CTEST_PROJECT_NAME "MyProject")
-# set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC")
-# set(CTEST_DROP_METHOD "http")
-# set(CTEST_DROP_SITE "my.cdash.org")
-# set(CTEST_DROP_LOCATION "/submit.php?project=MyProject")
-# set(CTEST_DROP_SITE_CDASH TRUE)
-# (the CDash server can provide the file to a project administrator
-# who configures 'MyProject').
-# Settings in the config file are shared by both this CTest module and
-# the CTest command-line tool's dashboard script mode (ctest -S).
-#
-# While building a project for submission to CDash, CTest scans the
-# build output for errors and warnings and reports them with
-# surrounding context from the build log. This generic approach works
-# for all build tools, but does not give details about the command
-# invocation that produced a given problem. One may get more detailed
-# reports by adding
-# set(CTEST_USE_LAUNCHERS 1)
-# to the CTestConfig.cmake file. When this option is enabled, the
-# CTest module tells CMake's Makefile generators to invoke every
-# command in the generated build system through a CTest launcher
-# program. (Currently the CTEST_USE_LAUNCHERS option is ignored on
-# non-Makefile generators.) During a manual build each launcher
-# transparently runs the command it wraps. During a CTest-driven
-# build for submission to CDash each launcher reports detailed
-# information when its command fails or warns.
-# (Setting CTEST_USE_LAUNCHERS in CTestConfig.cmake is convenient, but
-# also adds the launcher overhead even for manual builds. One may
-# instead set it in a CTest dashboard script and add it to the CMake
-# cache for the build tree.)
+#[=======================================================================[.rst:
+CTest
+-----
+
+Configure a project for testing with CTest/CDash
+
+Include this module in the top CMakeLists.txt file of a project to
+enable testing with CTest and dashboard submissions to CDash::
+
+ project(MyProject)
+ ...
+ include(CTest)
+
+The module automatically creates a ``BUILD_TESTING`` option that selects
+whether to enable testing support (``ON`` by default). After including
+the module, use code like::
+
+ if(BUILD_TESTING)
+ # ... CMake code to create tests ...
+ endif()
+
+to creating tests when testing is enabled.
+
+To enable submissions to a CDash server, create a ``CTestConfig.cmake``
+file at the top of the project with content such as::
+
+ set(CTEST_PROJECT_NAME "MyProject")
+ set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC")
+ set(CTEST_DROP_METHOD "http")
+ set(CTEST_DROP_SITE "my.cdash.org")
+ set(CTEST_DROP_LOCATION "/submit.php?project=MyProject")
+ set(CTEST_DROP_SITE_CDASH TRUE)
+
+(the CDash server can provide the file to a project administrator who
+configures ``MyProject``). Settings in the config file are shared by
+both this ``CTest`` module and the :manual:`ctest(1)` command-line
+:ref:`Dashboard Client` mode (``ctest -S``).
+
+While building a project for submission to CDash, CTest scans the
+build output for errors and warnings and reports them with surrounding
+context from the build log. This generic approach works for all build
+tools, but does not give details about the command invocation that
+produced a given problem. One may get more detailed reports by setting
+the :variable:`CTEST_USE_LAUNCHERS` variable::
+
+ set(CTEST_USE_LAUNCHERS 1)
+
+in the ``CTestConfig.cmake`` file.
+#]=======================================================================]
#=============================================================================
# Copyright 2005-2009 Kitware, Inc.
@@ -130,6 +133,7 @@ if(BUILD_TESTING)
find_program(BZRCOMMAND bzr)
find_program(HGCOMMAND hg)
find_program(GITCOMMAND git)
+ find_program(P4COMMAND p4)
if(NOT UPDATE_TYPE)
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CVS")
@@ -161,6 +165,9 @@ if(BUILD_TESTING)
elseif("${_update_type}" STREQUAL "git")
set(UPDATE_COMMAND "${GITCOMMAND}")
set(UPDATE_OPTIONS "${GIT_UPDATE_OPTIONS}")
+ elseif("${_update_type}" STREQUAL "p4")
+ set(UPDATE_COMMAND "${P4COMMAND}")
+ set(UPDATE_OPTIONS "${P4_UPDATE_OPTIONS}")
endif()
set(DART_TESTING_TIMEOUT 1500 CACHE STRING
@@ -221,7 +228,7 @@ if(BUILD_TESTING)
"${CMAKE_CXX_COMPILER}" ${DART_NAME_COMPONENT})
else()
get_filename_component(DART_CXX_NAME
- "${CMAKE_BUILD_TOOL}" ${DART_NAME_COMPONENT})
+ "${CMAKE_MAKE_PROGRAM}" ${DART_NAME_COMPONENT})
endif()
if(DART_CXX_NAME MATCHES "msdev")
set(DART_CXX_NAME "vs60")
@@ -256,6 +263,7 @@ if(BUILD_TESTING)
CVS_UPDATE_OPTIONS
DART_TESTING_TIMEOUT
GITCOMMAND
+ P4COMMAND
HGCOMMAND
MAKECOMMAND
MEMORYCHECK_COMMAND
diff --git a/Modules/CTestCoverageCollectGCOV.cmake b/Modules/CTestCoverageCollectGCOV.cmake
new file mode 100644
index 000000000..ef3aa7639
--- /dev/null
+++ b/Modules/CTestCoverageCollectGCOV.cmake
@@ -0,0 +1,204 @@
+#.rst:
+# CTestCoverageCollectGCOV
+# ------------------------
+#
+# This module provides the function ``ctest_coverage_collect_gcov``.
+# The function will run gcov on the .gcda files in a binary tree and then
+# package all of the .gcov files into a tar file with a data.json that
+# contains the source and build directories for CDash to use in parsing
+# the coverage data. In addtion the Labels.json files for targets that
+# have coverage information are also put in the tar file for CDash to
+# asign the correct labels. This file can be sent to a CDash server for
+# display with the
+# :command:`ctest_submit(CDASH_UPLOAD)` command.
+#
+# .. command:: cdash_coverage_collect_gcov
+#
+# ::
+#
+# ctest_coverage_collect_gcov(TARBALL <tarfile>
+# [SOURCE <source_dir>][BUILD <build_dir>]
+# [GCOV_COMMAND <gcov_command>]
+# [GCOV_OPTIONS <options>...]
+# )
+#
+# Run gcov and package a tar file for CDash. The options are:
+#
+# ``TARBALL <tarfile>``
+# Specify the location of the ``.tar`` file to be created for later
+# upload to CDash. Relative paths will be interpreted with respect
+# to the top-level build directory.
+#
+# ``SOURCE <source_dir>``
+# Specify the top-level source directory for the build.
+# Default is the value of :variable:`CTEST_SOURCE_DIRECTORY`.
+#
+# ``BUILD <build_dir>``
+# Specify the top-level build directory for the build.
+# Default is the value of :variable:`CTEST_BINARY_DIRECTORY`.
+#
+# ``GCOV_COMMAND <gcov_command>``
+# Specify the full path to the ``gcov`` command on the machine.
+# Default is the value of :variable:`CTEST_COVERAGE_COMMAND`.
+#
+# ``GCOV_OPTIONS <options>...``
+# Specify options to be passed to gcov. The ``gcov`` command
+# is run as ``gcov <options>... -o <gcov-dir> <file>.gcda``.
+# If not specified, the default option is just ``-b``.
+#
+# ``QUIET``
+# Suppress non-error messages that otherwise would have been
+# printed out by this function.
+
+#=============================================================================
+# Copyright 2014-2015 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+include(CMakeParseArguments)
+function(ctest_coverage_collect_gcov)
+ set(options QUIET)
+ set(oneValueArgs TARBALL SOURCE BUILD GCOV_COMMAND)
+ set(multiValueArgs GCOV_OPTIONS)
+ cmake_parse_arguments(GCOV "${options}" "${oneValueArgs}"
+ "${multiValueArgs}" "" ${ARGN} )
+ if(NOT DEFINED GCOV_TARBALL)
+ message(FATAL_ERROR
+ "TARBALL must be specified. for ctest_coverage_collect_gcov")
+ endif()
+ if(NOT DEFINED GCOV_SOURCE)
+ set(source_dir "${CTEST_SOURCE_DIRECTORY}")
+ else()
+ set(source_dir "${GCOV_SOURCE}")
+ endif()
+ if(NOT DEFINED GCOV_BUILD)
+ set(binary_dir "${CTEST_BINARY_DIRECTORY}")
+ else()
+ set(binary_dir "${GCOV_BUILD}")
+ endif()
+ if(NOT DEFINED GCOV_GCOV_COMMAND)
+ set(gcov_command "${CTEST_COVERAGE_COMMAND}")
+ else()
+ set(gcov_command "${GCOV_GCOV_COMMAND}")
+ endif()
+ # run gcov on each gcda file in the binary tree
+ set(gcda_files)
+ set(label_files)
+ # look for gcda files in the target directories
+ # could do a glob from the top of the binary tree but
+ # this will be faster and only look where the files will be
+ file(STRINGS "${binary_dir}/CMakeFiles/TargetDirectories.txt" target_dirs
+ ENCODING UTF-8)
+ foreach(target_dir ${target_dirs})
+ file(GLOB_RECURSE gfiles RELATIVE ${binary_dir} "${target_dir}/*.gcda")
+ list(LENGTH gfiles len)
+ # if we have gcda files then also grab the labels file for that target
+ if(${len} GREATER 0)
+ file(GLOB_RECURSE lfiles RELATIVE ${binary_dir}
+ "${target_dir}/Labels.json")
+ list(APPEND gcda_files ${gfiles})
+ list(APPEND label_files ${lfiles})
+ endif()
+ endforeach()
+ # return early if no coverage files were found
+ list(LENGTH gcda_files len)
+ if(len EQUAL 0)
+ if (NOT GCOV_QUIET)
+ message("ctest_coverage_collect_gcov: No .gcda files found, "
+ "ignoring coverage request.")
+ endif()
+ return()
+ endif()
+ # setup the dir for the coverage files
+ set(coverage_dir "${binary_dir}/Testing/CoverageInfo")
+ file(MAKE_DIRECTORY "${coverage_dir}")
+ # call gcov on each .gcda file
+ foreach (gcda_file ${gcda_files})
+ # get the directory of the gcda file
+ get_filename_component(gcda_file ${binary_dir}/${gcda_file} ABSOLUTE)
+ get_filename_component(gcov_dir ${gcda_file} DIRECTORY)
+ # run gcov, this will produce the .gcov file in the current
+ # working directory
+ if(NOT DEFINED GCOV_GCOV_OPTIONS)
+ set(GCOV_GCOV_OPTIONS -b)
+ endif()
+ execute_process(COMMAND
+ ${gcov_command} ${GCOV_GCOV_OPTIONS} -o ${gcov_dir} ${gcda_file}
+ OUTPUT_VARIABLE out
+ RESULT_VARIABLE res
+ WORKING_DIRECTORY ${coverage_dir})
+ endforeach()
+ if(NOT "${res}" EQUAL 0)
+ if (NOT GCOV_QUIET)
+ message(STATUS "Error running gcov: ${res} ${out}")
+ endif()
+ endif()
+ # create json file with project information
+ file(WRITE ${coverage_dir}/data.json
+ "{
+ \"Source\": \"${source_dir}\",
+ \"Binary\": \"${binary_dir}\"
+}")
+ # collect the gcov files
+ set(unfiltered_gcov_files)
+ file(GLOB_RECURSE unfiltered_gcov_files RELATIVE ${binary_dir} "${coverage_dir}/*.gcov")
+
+ set(gcov_files)
+ foreach(gcov_file ${unfiltered_gcov_files})
+ file(STRINGS ${binary_dir}/${gcov_file} first_line LIMIT_COUNT 1 ENCODING UTF-8)
+
+ set(is_excluded false)
+ if(first_line MATCHES "^ -: 0:Source:(.*)$")
+ set(source_file ${CMAKE_MATCH_1})
+ elseif(NOT GCOV_QUIET)
+ message(STATUS "Could not determine source file corresponding to: ${gcov_file}")
+ endif()
+
+ foreach(exclude_entry IN LISTS CTEST_CUSTOM_COVERAGE_EXCLUDE)
+ if(source_file MATCHES "${exclude_entry}")
+ set(is_excluded true)
+
+ if(NOT GCOV_QUIET)
+ message("Excluding coverage for: ${source_file} which matches ${exclude_entry}")
+ endif()
+
+ break()
+ endif()
+ endforeach()
+
+ if(NOT is_excluded)
+ list(APPEND gcov_files ${gcov_file})
+ endif()
+ endforeach()
+
+ # tar up the coverage info with the same date so that the md5
+ # sum will be the same for the tar file independent of file time
+ # stamps
+ string(REPLACE ";" "\n" gcov_files "${gcov_files}")
+ string(REPLACE ";" "\n" label_files "${label_files}")
+ file(WRITE "${coverage_dir}/coverage_file_list.txt"
+ "${gcov_files}
+${coverage_dir}/data.json
+${label_files}
+")
+
+ if (GCOV_QUIET)
+ set(tar_opts "cfj")
+ else()
+ set(tar_opts "cvfj")
+ endif()
+
+ execute_process(COMMAND
+ ${CMAKE_COMMAND} -E tar ${tar_opts} ${GCOV_TARBALL}
+ "--mtime=1970-01-01 0:0:0 UTC"
+ "--format=gnutar"
+ --files-from=${coverage_dir}/coverage_file_list.txt
+ WORKING_DIRECTORY ${binary_dir})
+endfunction()
diff --git a/Modules/CTestScriptMode.cmake b/Modules/CTestScriptMode.cmake
index 42d3764cb..b4347242d 100644
--- a/Modules/CTestScriptMode.cmake
+++ b/Modules/CTestScriptMode.cmake
@@ -1,3 +1,9 @@
+#.rst:
+# CTestScriptMode
+# ---------------
+#
+#
+#
# This file is read by ctest in script mode (-S)
#=============================================================================
diff --git a/Modules/CTestTargets.cmake b/Modules/CTestTargets.cmake
index 5b6e062d0..115785017 100644
--- a/Modules/CTestTargets.cmake
+++ b/Modules/CTestTargets.cmake
@@ -67,6 +67,7 @@ if(NOT _CTEST_TARGETS_ADDED)
foreach(mode Experimental Nightly Continuous NightlyMemoryCheck)
add_custom_target(${mode}
${CMAKE_CTEST_COMMAND} ${__conf_types} -D ${mode}
+ USES_TERMINAL
)
set_property(TARGET ${mode} PROPERTY RULE_LAUNCH_CUSTOM "")
set_property(TARGET ${mode} PROPERTY FOLDER "CTestDashboardTargets")
@@ -82,6 +83,7 @@ if(NOT _CTEST_TARGETS_ADDED)
)
add_custom_target(${mode}${testtype}
${CMAKE_CTEST_COMMAND} ${__conf_types} -D ${mode}${testtype}
+ USES_TERMINAL
)
set_property(TARGET ${mode}${testtype} PROPERTY RULE_LAUNCH_CUSTOM "")
set_property(TARGET ${mode}${testtype} PROPERTY FOLDER "CTestDashboardTargets")
@@ -94,6 +96,7 @@ if(NOT _CTEST_TARGETS_ADDED)
if(CTEST_TEST_TARGET_ALIAS)
add_custom_target(${CTEST_TEST_TARGET_ALIAS}
${CMAKE_CTEST_COMMAND} ${__conf_types}
+ USES_TERMINAL
)
endif()
endif()
diff --git a/Modules/CTestUseLaunchers.cmake b/Modules/CTestUseLaunchers.cmake
index 24f5f2e16..c79119f95 100644
--- a/Modules/CTestUseLaunchers.cmake
+++ b/Modules/CTestUseLaunchers.cmake
@@ -1,21 +1,27 @@
-# - Set the RULE_LAUNCH_* global properties when CTEST_USE_LAUNCHERS is on.
+#.rst:
+# CTestUseLaunchers
+# -----------------
+#
+# Set the RULE_LAUNCH_* global properties when CTEST_USE_LAUNCHERS is on.
+#
# CTestUseLaunchers is automatically included when you include(CTest).
-# However, it is split out into its own module file so projects
-# can use the CTEST_USE_LAUNCHERS functionality independently.
+# However, it is split out into its own module file so projects can use
+# the CTEST_USE_LAUNCHERS functionality independently.
#
# To use launchers, set CTEST_USE_LAUNCHERS to ON in a ctest -S
# dashboard script, and then also set it in the cache of the configured
-# project. Both cmake and ctest need to know the value of it for the launchers
-# to work properly. CMake needs to know in order to generate proper build
-# rules, and ctest, in order to produce the proper error and warning
-# analysis.
+# project. Both cmake and ctest need to know the value of it for the
+# launchers to work properly. CMake needs to know in order to generate
+# proper build rules, and ctest, in order to produce the proper error
+# and warning analysis.
#
-# For convenience, you may set the ENV variable CTEST_USE_LAUNCHERS_DEFAULT
-# in your ctest -S script, too. Then, as long as your CMakeLists uses
-# include(CTest) or include(CTestUseLaunchers), it will use the value of the
-# ENV variable to initialize a CTEST_USE_LAUNCHERS cache variable. This cache
-# variable initialization only occurs if CTEST_USE_LAUNCHERS is not already
-# defined.
+# For convenience, you may set the ENV variable
+# CTEST_USE_LAUNCHERS_DEFAULT in your ctest -S script, too. Then, as
+# long as your CMakeLists uses include(CTest) or
+# include(CTestUseLaunchers), it will use the value of the ENV variable
+# to initialize a CTEST_USE_LAUNCHERS cache variable. This cache
+# variable initialization only occurs if CTEST_USE_LAUNCHERS is not
+# already defined.
#=============================================================================
# Copyright 2008-2012 Kitware, Inc.
@@ -40,9 +46,31 @@ if(NOT "${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
endif()
if(CTEST_USE_LAUNCHERS)
- set(CTEST_LAUNCH_COMPILE "\"${CMAKE_CTEST_COMMAND}\" --launch --target-name <TARGET_NAME> --build-dir <CMAKE_CURRENT_BINARY_DIR> --output <OBJECT> --source <SOURCE> --language <LANGUAGE> --")
- set(CTEST_LAUNCH_LINK "\"${CMAKE_CTEST_COMMAND}\" --launch --target-name <TARGET_NAME> --build-dir <CMAKE_CURRENT_BINARY_DIR> --output <TARGET> --target-type <TARGET_TYPE> --language <LANGUAGE> --")
- set(CTEST_LAUNCH_CUSTOM "\"${CMAKE_CTEST_COMMAND}\" --launch --target-name <TARGET_NAME> --build-dir <CMAKE_CURRENT_BINARY_DIR> --output <OUTPUT> --")
+ set(__launch_common_options
+ "--target-name <TARGET_NAME> --build-dir <CMAKE_CURRENT_BINARY_DIR>")
+
+ set(__launch_compile_options
+ "${__launch_common_options} --output <OBJECT> --source <SOURCE> --language <LANGUAGE>")
+
+ set(__launch_link_options
+ "${__launch_common_options} --output <TARGET> --target-type <TARGET_TYPE> --language <LANGUAGE>")
+
+ set(__launch_custom_options
+ "${__launch_common_options} --output <OUTPUT>")
+
+ if("${CMAKE_GENERATOR}" MATCHES "Ninja")
+ set(__launch_compile_options "${__launch_compile_options} --filter-prefix <CMAKE_CL_SHOWINCLUDES_PREFIX>")
+ endif()
+
+ set(CTEST_LAUNCH_COMPILE
+ "\"${CMAKE_CTEST_COMMAND}\" --launch ${__launch_compile_options} --")
+
+ set(CTEST_LAUNCH_LINK
+ "\"${CMAKE_CTEST_COMMAND}\" --launch ${__launch_link_options} --")
+
+ set(CTEST_LAUNCH_CUSTOM
+ "\"${CMAKE_CTEST_COMMAND}\" --launch ${__launch_custom_options} --")
+
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CTEST_LAUNCH_COMPILE}")
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "${CTEST_LAUNCH_LINK}")
set_property(GLOBAL PROPERTY RULE_LAUNCH_CUSTOM "${CTEST_LAUNCH_CUSTOM}")
diff --git a/Modules/CheckCCompilerFlag.cmake b/Modules/CheckCCompilerFlag.cmake
index bc15e9a0b..53f345473 100644
--- a/Modules/CheckCCompilerFlag.cmake
+++ b/Modules/CheckCCompilerFlag.cmake
@@ -1,14 +1,23 @@
-# - Check whether the C compiler supports a given flag.
+#.rst:
+# CheckCCompilerFlag
+# ------------------
+#
+# Check whether the C compiler supports a given flag.
+#
# CHECK_C_COMPILER_FLAG(<flag> <var>)
-# <flag> - the compiler flag
-# <var> - variable to store the result
-# This internally calls the check_c_source_compiles macro and
-# sets CMAKE_REQUIRED_DEFINITIONS to <flag>.
-# See help for CheckCSourceCompiles for a listing of variables
-# that can otherwise modify the build.
-# The result only tells that the compiler does not give an error message when
-# it encounters the flag. If the flag has any effect or even a specific one is
-# beyond the scope of this module.
+#
+# ::
+#
+# <flag> - the compiler flag
+# <var> - variable to store the result
+# Will be created as an internal cache variable.
+#
+# This internally calls the check_c_source_compiles macro and sets
+# CMAKE_REQUIRED_DEFINITIONS to <flag>. See help for
+# CheckCSourceCompiles for a listing of variables that can otherwise
+# modify the build. The result only tells that the compiler does not
+# give an error message when it encounters the flag. If the flag has
+# any effect or even a specific one is beyond the scope of this module.
#=============================================================================
# Copyright 2006-2011 Kitware, Inc.
@@ -26,36 +35,30 @@
# License text for the above reference.)
include(CheckCSourceCompiles)
+include(CMakeCheckCompilerFlagCommonPatterns)
macro (CHECK_C_COMPILER_FLAG _FLAG _RESULT)
set(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
set(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}")
+
# Normalize locale during test compilation.
set(_CheckCCompilerFlag_LOCALE_VARS LC_ALL LC_MESSAGES LANG)
foreach(v ${_CheckCCompilerFlag_LOCALE_VARS})
set(_CheckCCompilerFlag_SAVED_${v} "$ENV{${v}}")
set(ENV{${v}} C)
endforeach()
+ CHECK_COMPILER_FLAG_COMMON_PATTERNS(_CheckCCompilerFlag_COMMON_PATTERNS)
CHECK_C_SOURCE_COMPILES("int main(void) { return 0; }" ${_RESULT}
# Some compilers do not fail with a bad flag
FAIL_REGEX "command line option .* is valid for .* but not for C" # GNU
- FAIL_REGEX "unrecognized .*option" # GNU
- FAIL_REGEX "unknown .*option" # Clang
- FAIL_REGEX "ignoring unknown option" # MSVC
- FAIL_REGEX "warning D9002" # MSVC, any lang
- FAIL_REGEX "option.*not supported" # Intel
- FAIL_REGEX "invalid argument .*option" # Intel
- FAIL_REGEX "ignoring option .*argument required" # Intel
- FAIL_REGEX "[Uu]nknown option" # HP
- FAIL_REGEX "[Ww]arning: [Oo]ption" # SunPro
- FAIL_REGEX "command option .* is not recognized" # XL
- FAIL_REGEX "WARNING: unknown flag:" # Open64
+ ${_CheckCCompilerFlag_COMMON_PATTERNS}
)
foreach(v ${_CheckCCompilerFlag_LOCALE_VARS})
set(ENV{${v}} ${_CheckCCompilerFlag_SAVED_${v}})
unset(_CheckCCompilerFlag_SAVED_${v})
endforeach()
unset(_CheckCCompilerFlag_LOCALE_VARS)
+ unset(_CheckCCompilerFlag_COMMON_PATTERNS)
set (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
endmacro ()
diff --git a/Modules/CheckCSourceCompiles.cmake b/Modules/CheckCSourceCompiles.cmake
index 86a4565ce..c2b172311 100644
--- a/Modules/CheckCSourceCompiles.cmake
+++ b/Modules/CheckCSourceCompiles.cmake
@@ -1,15 +1,28 @@
-# - Check if given C source compiles and links into an executable
+#.rst:
+# CheckCSourceCompiles
+# --------------------
+#
+# Check if given C source compiles and links into an executable
+#
# CHECK_C_SOURCE_COMPILES(<code> <var> [FAIL_REGEX <fail-regex>])
-# <code> - source code to try to compile, must define 'main'
-# <var> - variable to store whether the source code compiled
-# <fail-regex> - fail if test output matches this regex
-# The following variables may be set before calling this macro to
-# modify the way the check is run:
#
-# CMAKE_REQUIRED_FLAGS = string of compile command line flags
-# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
-# CMAKE_REQUIRED_INCLUDES = list of include directories
-# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+# ::
+#
+# <code> - source code to try to compile, must define 'main'
+# <var> - variable to store whether the source code compiled
+# Will be created as an internal cache variable.
+# <fail-regex> - fail if test output matches this regex
+#
+# The following variables may be set before calling this macro to modify
+# the way the check is run:
+#
+# ::
+#
+# CMAKE_REQUIRED_FLAGS = string of compile command line flags
+# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
+# CMAKE_REQUIRED_INCLUDES = list of include directories
+# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+# CMAKE_REQUIRED_QUIET = execute quietly without messages
#=============================================================================
# Copyright 2005-2009 Kitware, Inc.
@@ -27,7 +40,7 @@
macro(CHECK_C_SOURCE_COMPILES SOURCE VAR)
- if("${VAR}" MATCHES "^${VAR}$")
+ if(NOT DEFINED "${VAR}")
set(_FAIL_REGEX)
set(_key)
foreach(arg ${ARGN})
@@ -56,7 +69,9 @@ macro(CHECK_C_SOURCE_COMPILES SOURCE VAR)
file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c"
"${SOURCE}\n")
- message(STATUS "Performing Test ${VAR}")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Performing Test ${VAR}")
+ endif()
try_compile(${VAR}
${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c
@@ -74,13 +89,17 @@ macro(CHECK_C_SOURCE_COMPILES SOURCE VAR)
if(${VAR})
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
- message(STATUS "Performing Test ${VAR} - Success")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Performing Test ${VAR} - Success")
+ endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
- "Performing C SOURCE FILE Test ${VAR} succeded with the following output:\n"
+ "Performing C SOURCE FILE Test ${VAR} succeeded with the following output:\n"
"${OUTPUT}\n"
"Source file was:\n${SOURCE}\n")
else()
- message(STATUS "Performing Test ${VAR} - Failed")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Performing Test ${VAR} - Failed")
+ endif()
set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing C SOURCE FILE Test ${VAR} failed with the following output:\n"
diff --git a/Modules/CheckCSourceRuns.cmake b/Modules/CheckCSourceRuns.cmake
index e3a091fb3..5afeab685 100644
--- a/Modules/CheckCSourceRuns.cmake
+++ b/Modules/CheckCSourceRuns.cmake
@@ -1,15 +1,28 @@
-# - Check if the given C source code compiles and runs.
+#.rst:
+# CheckCSourceRuns
+# ----------------
+#
+# Check if the given C source code compiles and runs.
+#
# CHECK_C_SOURCE_RUNS(<code> <var>)
-# <code> - source code to try to compile
-# <var> - variable to store the result
-# (1 for success, empty for failure)
-# The following variables may be set before calling this macro to
-# modify the way the check is run:
#
-# CMAKE_REQUIRED_FLAGS = string of compile command line flags
-# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
-# CMAKE_REQUIRED_INCLUDES = list of include directories
-# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+# ::
+#
+# <code> - source code to try to compile
+# <var> - variable to store the result
+# (1 for success, empty for failure)
+# Will be created as an internal cache variable.
+#
+# The following variables may be set before calling this macro to modify
+# the way the check is run:
+#
+# ::
+#
+# CMAKE_REQUIRED_FLAGS = string of compile command line flags
+# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
+# CMAKE_REQUIRED_INCLUDES = list of include directories
+# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+# CMAKE_REQUIRED_QUIET = execute quietly without messages
#=============================================================================
# Copyright 2006-2009 Kitware, Inc.
@@ -27,7 +40,7 @@
macro(CHECK_C_SOURCE_RUNS SOURCE VAR)
- if("${VAR}" MATCHES "^${VAR}$")
+ if(NOT DEFINED "${VAR}")
set(MACRO_CHECK_FUNCTION_DEFINITIONS
"-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
if(CMAKE_REQUIRED_LIBRARIES)
@@ -45,7 +58,9 @@ macro(CHECK_C_SOURCE_RUNS SOURCE VAR)
file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c"
"${SOURCE}\n")
- message(STATUS "Performing Test ${VAR}")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Performing Test ${VAR}")
+ endif()
try_run(${VAR}_EXITCODE ${VAR}_COMPILED
${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c
@@ -62,9 +77,11 @@ macro(CHECK_C_SOURCE_RUNS SOURCE VAR)
# if the return value was 0 then it worked
if("${${VAR}_EXITCODE}" EQUAL 0)
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
- message(STATUS "Performing Test ${VAR} - Success")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Performing Test ${VAR} - Success")
+ endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
- "Performing C SOURCE FILE Test ${VAR} succeded with the following output:\n"
+ "Performing C SOURCE FILE Test ${VAR} succeeded with the following output:\n"
"${OUTPUT}\n"
"Return value: ${${VAR}}\n"
"Source file was:\n${SOURCE}\n")
@@ -75,7 +92,9 @@ macro(CHECK_C_SOURCE_RUNS SOURCE VAR)
set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
endif()
- message(STATUS "Performing Test ${VAR} - Failed")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Performing Test ${VAR} - Failed")
+ endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing C SOURCE FILE Test ${VAR} failed with the following output:\n"
"${OUTPUT}\n"
diff --git a/Modules/CheckCXXCompilerFlag.cmake b/Modules/CheckCXXCompilerFlag.cmake
index eee3a701e..fab3a053d 100644
--- a/Modules/CheckCXXCompilerFlag.cmake
+++ b/Modules/CheckCXXCompilerFlag.cmake
@@ -1,14 +1,22 @@
-# - Check whether the CXX compiler supports a given flag.
+#.rst:
+# CheckCXXCompilerFlag
+# --------------------
+#
+# Check whether the CXX compiler supports a given flag.
+#
# CHECK_CXX_COMPILER_FLAG(<flag> <var>)
-# <flag> - the compiler flag
-# <var> - variable to store the result
-# This internally calls the check_cxx_source_compiles macro and
-# sets CMAKE_REQUIRED_DEFINITIONS to <flag>.
-# See help for CheckCXXSourceCompiles for a listing of variables
-# that can otherwise modify the build.
-# The result only tells that the compiler does not give an error message when
-# it encounters the flag. If the flag has any effect or even a specific one is
-# beyond the scope of this module.
+#
+# ::
+#
+# <flag> - the compiler flag
+# <var> - variable to store the result
+#
+# This internally calls the check_cxx_source_compiles macro and sets
+# CMAKE_REQUIRED_DEFINITIONS to <flag>. See help for
+# CheckCXXSourceCompiles for a listing of variables that can otherwise
+# modify the build. The result only tells that the compiler does not
+# give an error message when it encounters the flag. If the flag has
+# any effect or even a specific one is beyond the scope of this module.
#=============================================================================
# Copyright 2006-2010 Kitware, Inc.
@@ -26,6 +34,7 @@
# License text for the above reference.)
include(CheckCXXSourceCompiles)
+include(CMakeCheckCompilerFlagCommonPatterns)
macro (CHECK_CXX_COMPILER_FLAG _FLAG _RESULT)
set(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
@@ -37,28 +46,18 @@ macro (CHECK_CXX_COMPILER_FLAG _FLAG _RESULT)
set(_CheckCXXCompilerFlag_SAVED_${v} "$ENV{${v}}")
set(ENV{${v}} C)
endforeach()
- CHECK_CXX_SOURCE_COMPILES("int main() { return 0;}" ${_RESULT}
+ CHECK_COMPILER_FLAG_COMMON_PATTERNS(_CheckCXXCompilerFlag_COMMON_PATTERNS)
+ CHECK_CXX_SOURCE_COMPILES("int main() { return 0; }" ${_RESULT}
# Some compilers do not fail with a bad flag
FAIL_REGEX "command line option .* is valid for .* but not for C\\\\+\\\\+" # GNU
- FAIL_REGEX "unrecognized .*option" # GNU
- FAIL_REGEX "unknown .*option" # Clang
- FAIL_REGEX "ignoring unknown option" # MSVC
- FAIL_REGEX "warning D9002" # MSVC, any lang
- FAIL_REGEX "option.*not supported" # Intel
- FAIL_REGEX "invalid argument .*option" # Intel
- FAIL_REGEX "ignoring option .*argument required" # Intel
- FAIL_REGEX "[Uu]nknown option" # HP
- FAIL_REGEX "[Ww]arning: [Oo]ption" # SunPro
- FAIL_REGEX "command option .* is not recognized" # XL
- FAIL_REGEX "not supported in this configuration; ignored" # AIX
- FAIL_REGEX "File with unknown suffix passed to linker" # PGI
- FAIL_REGEX "WARNING: unknown flag:" # Open64
+ ${_CheckCXXCompilerFlag_COMMON_PATTERNS}
)
foreach(v ${_CheckCXXCompilerFlag_LOCALE_VARS})
set(ENV{${v}} ${_CheckCXXCompilerFlag_SAVED_${v}})
unset(_CheckCXXCompilerFlag_SAVED_${v})
endforeach()
unset(_CheckCXXCompilerFlag_LOCALE_VARS)
+ unset(_CheckCXXCompilerFlag_COMMON_PATTERNS)
set (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
endmacro ()
diff --git a/Modules/CheckCXXSourceCompiles.cmake b/Modules/CheckCXXSourceCompiles.cmake
index 734c0839b..f8736e216 100644
--- a/Modules/CheckCXXSourceCompiles.cmake
+++ b/Modules/CheckCXXSourceCompiles.cmake
@@ -1,15 +1,28 @@
-# - Check if given C++ source compiles and links into an executable
+#.rst:
+# CheckCXXSourceCompiles
+# ----------------------
+#
+# Check if given C++ source compiles and links into an executable
+#
# CHECK_CXX_SOURCE_COMPILES(<code> <var> [FAIL_REGEX <fail-regex>])
-# <code> - source code to try to compile, must define 'main'
-# <var> - variable to store whether the source code compiled
-# <fail-regex> - fail if test output matches this regex
-# The following variables may be set before calling this macro to
-# modify the way the check is run:
#
-# CMAKE_REQUIRED_FLAGS = string of compile command line flags
-# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
-# CMAKE_REQUIRED_INCLUDES = list of include directories
-# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+# ::
+#
+# <code> - source code to try to compile, must define 'main'
+# <var> - variable to store whether the source code compiled
+# Will be created as an internal cache variable.
+# <fail-regex> - fail if test output matches this regex
+#
+# The following variables may be set before calling this macro to modify
+# the way the check is run:
+#
+# ::
+#
+# CMAKE_REQUIRED_FLAGS = string of compile command line flags
+# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
+# CMAKE_REQUIRED_INCLUDES = list of include directories
+# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+# CMAKE_REQUIRED_QUIET = execute quietly without messages
#=============================================================================
# Copyright 2005-2009 Kitware, Inc.
@@ -27,7 +40,7 @@
macro(CHECK_CXX_SOURCE_COMPILES SOURCE VAR)
- if("${VAR}" MATCHES "^${VAR}$")
+ if(NOT DEFINED "${VAR}")
set(_FAIL_REGEX)
set(_key)
foreach(arg ${ARGN})
@@ -57,7 +70,9 @@ macro(CHECK_CXX_SOURCE_COMPILES SOURCE VAR)
file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx"
"${SOURCE}\n")
- message(STATUS "Performing Test ${VAR}")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Performing Test ${VAR}")
+ endif()
try_compile(${VAR}
${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx
@@ -75,13 +90,17 @@ macro(CHECK_CXX_SOURCE_COMPILES SOURCE VAR)
if(${VAR})
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
- message(STATUS "Performing Test ${VAR} - Success")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Performing Test ${VAR} - Success")
+ endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
- "Performing C++ SOURCE FILE Test ${VAR} succeded with the following output:\n"
+ "Performing C++ SOURCE FILE Test ${VAR} succeeded with the following output:\n"
"${OUTPUT}\n"
"Source file was:\n${SOURCE}\n")
else()
- message(STATUS "Performing Test ${VAR} - Failed")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Performing Test ${VAR} - Failed")
+ endif()
set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing C++ SOURCE FILE Test ${VAR} failed with the following output:\n"
diff --git a/Modules/CheckCXXSourceRuns.cmake b/Modules/CheckCXXSourceRuns.cmake
index 9e401f18e..84b661d15 100644
--- a/Modules/CheckCXXSourceRuns.cmake
+++ b/Modules/CheckCXXSourceRuns.cmake
@@ -1,15 +1,28 @@
-# - Check if the given C++ source code compiles and runs.
+#.rst:
+# CheckCXXSourceRuns
+# ------------------
+#
+# Check if the given C++ source code compiles and runs.
+#
# CHECK_CXX_SOURCE_RUNS(<code> <var>)
-# <code> - source code to try to compile
-# <var> - variable to store the result
-# (1 for success, empty for failure)
-# The following variables may be set before calling this macro to
-# modify the way the check is run:
#
-# CMAKE_REQUIRED_FLAGS = string of compile command line flags
-# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
-# CMAKE_REQUIRED_INCLUDES = list of include directories
-# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+# ::
+#
+# <code> - source code to try to compile
+# <var> - variable to store the result
+# (1 for success, empty for failure)
+# Will be created as an internal cache variable.
+#
+# The following variables may be set before calling this macro to modify
+# the way the check is run:
+#
+# ::
+#
+# CMAKE_REQUIRED_FLAGS = string of compile command line flags
+# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
+# CMAKE_REQUIRED_INCLUDES = list of include directories
+# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+# CMAKE_REQUIRED_QUIET = execute quietly without messages
#=============================================================================
# Copyright 2006-2009 Kitware, Inc.
@@ -27,7 +40,7 @@
macro(CHECK_CXX_SOURCE_RUNS SOURCE VAR)
- if("${VAR}" MATCHES "^${VAR}$")
+ if(NOT DEFINED "${VAR}")
set(MACRO_CHECK_FUNCTION_DEFINITIONS
"-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
if(CMAKE_REQUIRED_LIBRARIES)
@@ -45,7 +58,9 @@ macro(CHECK_CXX_SOURCE_RUNS SOURCE VAR)
file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx"
"${SOURCE}\n")
- message(STATUS "Performing Test ${VAR}")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Performing Test ${VAR}")
+ endif()
try_run(${VAR}_EXITCODE ${VAR}_COMPILED
${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx
@@ -63,9 +78,11 @@ macro(CHECK_CXX_SOURCE_RUNS SOURCE VAR)
# if the return value was 0 then it worked
if("${${VAR}_EXITCODE}" EQUAL 0)
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
- message(STATUS "Performing Test ${VAR} - Success")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Performing Test ${VAR} - Success")
+ endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
- "Performing C++ SOURCE FILE Test ${VAR} succeded with the following output:\n"
+ "Performing C++ SOURCE FILE Test ${VAR} succeeded with the following output:\n"
"${OUTPUT}\n"
"Return value: ${${VAR}}\n"
"Source file was:\n${SOURCE}\n")
@@ -76,7 +93,9 @@ macro(CHECK_CXX_SOURCE_RUNS SOURCE VAR)
set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
endif()
- message(STATUS "Performing Test ${VAR} - Failed")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Performing Test ${VAR} - Failed")
+ endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing C++ SOURCE FILE Test ${VAR} failed with the following output:\n"
"${OUTPUT}\n"
diff --git a/Modules/CheckCXXSymbolExists.cmake b/Modules/CheckCXXSymbolExists.cmake
index 210097378..084fbb422 100644
--- a/Modules/CheckCXXSymbolExists.cmake
+++ b/Modules/CheckCXXSymbolExists.cmake
@@ -1,26 +1,33 @@
-# - Check if a symbol exists as a function, variable, or macro in C++
+#.rst:
+# CheckCXXSymbolExists
+# --------------------
+#
+# Check if a symbol exists as a function, variable, or macro in C++
+#
# CHECK_CXX_SYMBOL_EXISTS(<symbol> <files> <variable>)
#
# Check that the <symbol> is available after including given header
-# <files> and store the result in a <variable>. Specify the list
-# of files in one argument as a semicolon-separated list.
-# CHECK_CXX_SYMBOL_EXISTS() can be used to check in C++ files, as opposed
-# to CHECK_SYMBOL_EXISTS(), which works only for C.
+# <files> and store the result in a <variable>. Specify the list of
+# files in one argument as a semicolon-separated list.
+# CHECK_CXX_SYMBOL_EXISTS() can be used to check in C++ files, as
+# opposed to CHECK_SYMBOL_EXISTS(), which works only for C.
#
# If the header files define the symbol as a macro it is considered
-# available and assumed to work. If the header files declare the
-# symbol as a function or variable then the symbol must also be
-# available for linking. If the symbol is a type or enum value
-# it will not be recognized (consider using CheckTypeSize or
-# CheckCSourceCompiles).
-#
-# The following variables may be set before calling this macro to
-# modify the way the check is run:
-#
-# CMAKE_REQUIRED_FLAGS = string of compile command line flags
-# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
-# CMAKE_REQUIRED_INCLUDES = list of include directories
-# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+# available and assumed to work. If the header files declare the symbol
+# as a function or variable then the symbol must also be available for
+# linking. If the symbol is a type or enum value it will not be
+# recognized (consider using CheckTypeSize or CheckCSourceCompiles).
+#
+# The following variables may be set before calling this macro to modify
+# the way the check is run:
+#
+# ::
+#
+# CMAKE_REQUIRED_FLAGS = string of compile command line flags
+# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
+# CMAKE_REQUIRED_INCLUDES = list of include directories
+# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+# CMAKE_REQUIRED_QUIET = execute quietly without messages
#=============================================================================
# Copyright 2003-2011 Kitware, Inc.
diff --git a/Modules/CheckForPthreads.c b/Modules/CheckForPthreads.c
index 7250fbff6..344c81bee 100644
--- a/Modules/CheckForPthreads.c
+++ b/Modules/CheckForPthreads.c
@@ -16,8 +16,8 @@ int main(int ac, char*av[]){
pthread_create(&tid[0], 0, runner, (void*)1);
pthread_create(&tid[1], 0, runner, (void*)2);
-#if defined(__BEOS__) && !defined(__ZETA__) // (no usleep on BeOS 5.)
- usleep(1); // for strange behavior on single-processor sun
+#if defined(__BEOS__) && !defined(__ZETA__) /* (no usleep on BeOS 5.) */
+ usleep(1); /* for strange behavior on single-processor sun */
#endif
pthread_join(tid[0], 0);
@@ -31,7 +31,7 @@ void* runner(void* args)
int cc;
for ( cc = 0; cc < 10; cc ++ )
{
- printf("%d CC: %d\n", (int)args, cc);
+ printf("%p CC: %d\n", args, cc);
}
res ++;
return 0;
diff --git a/Modules/CheckFortranCompilerFlag.cmake b/Modules/CheckFortranCompilerFlag.cmake
new file mode 100644
index 000000000..53fd8d64d
--- /dev/null
+++ b/Modules/CheckFortranCompilerFlag.cmake
@@ -0,0 +1,66 @@
+#.rst:
+# CheckFortranCompilerFlag
+# ------------------------
+#
+# Check whether the Fortran compiler supports a given flag.
+#
+# CHECK_Fortran_COMPILER_FLAG(<flag> <var>)
+#
+# ::
+#
+# <flag> - the compiler flag
+# <var> - variable to store the result
+# Will be created as an internal cache variable.
+#
+# This internally calls the check_fortran_source_compiles macro and
+# sets CMAKE_REQUIRED_DEFINITIONS to <flag>. See help for
+# CheckFortranSourceCompiles for a listing of variables that can
+# otherwise modify the build. The result only tells that the compiler
+# does not give an error message when it encounters the flag. If the
+# flag has any effect or even a specific one is beyond the scope of
+# this module.
+
+#=============================================================================
+# Copyright 2015 Nicolas Bock <nicolasbock@gmail.com>
+# Copyright 2006-2011 Kitware, Inc.
+# Copyright 2006 Alexander Neundorf <neundorf@kde.org>
+# Copyright 2011 Matthias Kretz <kretz@kde.org>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+include(CheckFortranSourceCompiles)
+include(CMakeCheckCompilerFlagCommonPatterns)
+
+macro (CHECK_Fortran_COMPILER_FLAG _FLAG _RESULT)
+ set(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
+ set(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}")
+
+ # Normalize locale during test compilation.
+ set(_CheckFortranCompilerFlag_LOCALE_VARS LC_ALL LC_MESSAGES LANG)
+ foreach(v ${_CheckFortranCompilerFlag_LOCALE_VARS})
+ set(_CheckFortranCompilerFlag_SAVED_${v} "$ENV{${v}}")
+ set(ENV{${v}} C)
+ endforeach()
+ CHECK_COMPILER_FLAG_COMMON_PATTERNS(_CheckFortranCompilerFlag_COMMON_PATTERNS)
+ CHECK_Fortran_SOURCE_COMPILES(" program test\n stop\n end program" ${_RESULT}
+ # Some compilers do not fail with a bad flag
+ FAIL_REGEX "command line option .* is valid for .* but not for Fortran" # GNU
+ ${_CheckFortranCompilerFlag_COMMON_PATTERNS}
+ )
+ foreach(v ${_CheckFortranCompilerFlag_LOCALE_VARS})
+ set(ENV{${v}} ${_CheckFortranCompilerFlag_SAVED_${v}})
+ unset(_CheckFortranCompilerFlag_SAVED_${v})
+ endforeach()
+ unset(_CheckFortranCompilerFlag_LOCALE_VARS)
+ unset(_CheckFortranCompilerFlag_COMMON_PATTERNS)
+
+ set (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
+endmacro ()
diff --git a/Modules/CheckFortranFunctionExists.cmake b/Modules/CheckFortranFunctionExists.cmake
index 45dd7bebe..bd52f61b6 100644
--- a/Modules/CheckFortranFunctionExists.cmake
+++ b/Modules/CheckFortranFunctionExists.cmake
@@ -1,13 +1,25 @@
-# - Check if the Fortran function exists.
+#.rst:
+# CheckFortranFunctionExists
+# --------------------------
+#
+# macro which checks if the Fortran function exists
+#
# CHECK_FORTRAN_FUNCTION_EXISTS(FUNCTION VARIABLE)
-# - macro which checks if the Fortran function exists
-# FUNCTION - the name of the Fortran function
-# VARIABLE - variable to store the result
#
-# The following variables may be set before calling this macro to
-# modify the way the check is run:
+# ::
+#
+# FUNCTION - the name of the Fortran function
+# VARIABLE - variable to store the result
+# Will be created as an internal cache variable.
+#
+#
+#
+# The following variables may be set before calling this macro to modify
+# the way the check is run:
+#
+# ::
#
-# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
#=============================================================================
# Copyright 2007-2009 Kitware, Inc.
diff --git a/Modules/CheckFortranSourceCompiles.cmake b/Modules/CheckFortranSourceCompiles.cmake
new file mode 100644
index 000000000..0bdcffa8c
--- /dev/null
+++ b/Modules/CheckFortranSourceCompiles.cmake
@@ -0,0 +1,111 @@
+#.rst:
+# CheckFortranSourceCompiles
+# --------------------------
+#
+# Check if given Fortran source compiles and links into an executable::
+#
+# CHECK_Fortran_SOURCE_COMPILES(<code> <var> [FAIL_REGEX <fail-regex>])
+#
+# The arguments are:
+#
+# ``<code>``
+# Source code to try to compile. It must define a PROGRAM entry point.
+# ``<var>``
+# Variable to store whether the source code compiled.
+# Will be created as an internal cache variable.
+# ``<fail-regex>``
+# Fail if test output matches this regex.
+#
+# The following variables may be set before calling this macro to modify
+# the way the check is run::
+#
+# CMAKE_REQUIRED_FLAGS = string of compile command line flags
+# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
+# CMAKE_REQUIRED_INCLUDES = list of include directories
+# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+# CMAKE_REQUIRED_QUIET = execute quietly without messages
+
+#=============================================================================
+# Copyright 2005-2009 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+
+
+macro(CHECK_Fortran_SOURCE_COMPILES SOURCE VAR)
+ if(NOT DEFINED "${VAR}")
+ set(_FAIL_REGEX)
+ set(_key)
+ foreach(arg ${ARGN})
+ if("${arg}" MATCHES "^(FAIL_REGEX)$")
+ set(_key "${arg}")
+ elseif(_key)
+ list(APPEND _${_key} "${arg}")
+ else()
+ message(FATAL_ERROR "Unknown argument:\n ${arg}\n")
+ endif()
+ endforeach()
+ set(MACRO_CHECK_FUNCTION_DEFINITIONS
+ "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
+ if(CMAKE_REQUIRED_LIBRARIES)
+ set(CHECK_Fortran_SOURCE_COMPILES_ADD_LIBRARIES
+ LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
+ else()
+ set(CHECK_Fortran_SOURCE_COMPILES_ADD_LIBRARIES)
+ endif()
+ if(CMAKE_REQUIRED_INCLUDES)
+ set(CHECK_Fortran_SOURCE_COMPILES_ADD_INCLUDES
+ "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
+ else()
+ set(CHECK_Fortran_SOURCE_COMPILES_ADD_INCLUDES)
+ endif()
+ file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.F"
+ "${SOURCE}\n")
+
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Performing Test ${VAR}")
+ endif()
+ try_compile(${VAR}
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.F
+ COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+ ${CHECK_Fortran_SOURCE_COMPILES_ADD_LIBRARIES}
+ CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
+ "${CHECK_Fortran_SOURCE_COMPILES_ADD_INCLUDES}"
+ OUTPUT_VARIABLE OUTPUT)
+
+ foreach(_regex ${_FAIL_REGEX})
+ if("${OUTPUT}" MATCHES "${_regex}")
+ set(${VAR} 0)
+ endif()
+ endforeach()
+
+ if(${VAR})
+ set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Performing Test ${VAR} - Success")
+ endif()
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Performing Fortran SOURCE FILE Test ${VAR} succeeded with the following output:\n"
+ "${OUTPUT}\n"
+ "Source file was:\n${SOURCE}\n")
+ else()
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Performing Test ${VAR} - Failed")
+ endif()
+ set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Performing Fortran SOURCE FILE Test ${VAR} failed with the following output:\n"
+ "${OUTPUT}\n"
+ "Source file was:\n${SOURCE}\n")
+ endif()
+ endif()
+endmacro()
diff --git a/Modules/CheckFunctionExists.c b/Modules/CheckFunctionExists.c
index 607b3e8c6..fd29618ce 100644
--- a/Modules/CheckFunctionExists.c
+++ b/Modules/CheckFunctionExists.c
@@ -1,5 +1,8 @@
#ifdef CHECK_FUNCTION_EXISTS
+#ifdef __cplusplus
+extern "C"
+#endif
char CHECK_FUNCTION_EXISTS();
#ifdef __CLASSIC_C__
int main(){
diff --git a/Modules/CheckFunctionExists.cmake b/Modules/CheckFunctionExists.cmake
index ead135441..5dd37517a 100644
--- a/Modules/CheckFunctionExists.cmake
+++ b/Modules/CheckFunctionExists.cmake
@@ -1,18 +1,27 @@
-# - Check if a C function can be linked
+#.rst:
+# CheckFunctionExists
+# -------------------
+#
+# Check if a C function can be linked
+#
# CHECK_FUNCTION_EXISTS(<function> <variable>)
#
# Check that the <function> is provided by libraries on the system and
# store the result in a <variable>. This does not verify that any
-# system header file declares the function, only that it can be found
-# at link time (consider using CheckSymbolExists).
+# system header file declares the function, only that it can be found at
+# link time (consider using CheckSymbolExists).
+# <variable> will be created as an internal cache variable.
+#
+# The following variables may be set before calling this macro to modify
+# the way the check is run:
#
-# The following variables may be set before calling this macro to
-# modify the way the check is run:
+# ::
#
-# CMAKE_REQUIRED_FLAGS = string of compile command line flags
-# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
-# CMAKE_REQUIRED_INCLUDES = list of include directories
-# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+# CMAKE_REQUIRED_FLAGS = string of compile command line flags
+# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
+# CMAKE_REQUIRED_INCLUDES = list of include directories
+# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+# CMAKE_REQUIRED_QUIET = execute quietly without messages
#=============================================================================
# Copyright 2002-2011 Kitware, Inc.
@@ -30,10 +39,12 @@
macro(CHECK_FUNCTION_EXISTS FUNCTION VARIABLE)
- if("${VARIABLE}" MATCHES "^${VARIABLE}$")
+ if(NOT DEFINED "${VARIABLE}" OR "x${${VARIABLE}}" STREQUAL "x${VARIABLE}")
set(MACRO_CHECK_FUNCTION_DEFINITIONS
"-DCHECK_FUNCTION_EXISTS=${FUNCTION} ${CMAKE_REQUIRED_FLAGS}")
- message(STATUS "Looking for ${FUNCTION}")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Looking for ${FUNCTION}")
+ endif()
if(CMAKE_REQUIRED_LIBRARIES)
set(CHECK_FUNCTION_EXISTS_ADD_LIBRARIES
LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
@@ -46,22 +57,38 @@ macro(CHECK_FUNCTION_EXISTS FUNCTION VARIABLE)
else()
set(CHECK_FUNCTION_EXISTS_ADD_INCLUDES)
endif()
+
+ if(CMAKE_C_COMPILER_LOADED)
+ set(_cfe_source ${CMAKE_ROOT}/Modules/CheckFunctionExists.c)
+ elseif(CMAKE_CXX_COMPILER_LOADED)
+ set(_cfe_source ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckFunctionExists/CheckFunctionExists.cxx)
+ configure_file(${CMAKE_ROOT}/Modules/CheckFunctionExists.c "${_cfe_source}" COPYONLY)
+ else()
+ message(FATAL_ERROR "CHECK_FUNCTION_EXISTS needs either C or CXX language enabled")
+ endif()
+
try_compile(${VARIABLE}
${CMAKE_BINARY_DIR}
- ${CMAKE_ROOT}/Modules/CheckFunctionExists.c
+ ${_cfe_source}
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
${CHECK_FUNCTION_EXISTS_ADD_LIBRARIES}
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
"${CHECK_FUNCTION_EXISTS_ADD_INCLUDES}"
OUTPUT_VARIABLE OUTPUT)
+ unset(_cfe_source)
+
if(${VARIABLE})
set(${VARIABLE} 1 CACHE INTERNAL "Have function ${FUNCTION}")
- message(STATUS "Looking for ${FUNCTION} - found")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Looking for ${FUNCTION} - found")
+ endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the function ${FUNCTION} exists passed with the following output:\n"
"${OUTPUT}\n\n")
else()
- message(STATUS "Looking for ${FUNCTION} - not found")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Looking for ${FUNCTION} - not found")
+ endif()
set(${VARIABLE} "" CACHE INTERNAL "Have function ${FUNCTION}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the function ${FUNCTION} exists failed with the following output:\n"
diff --git a/Modules/CheckIncludeFile.cmake b/Modules/CheckIncludeFile.cmake
index 8067e65ce..ef1e39d69 100644
--- a/Modules/CheckIncludeFile.cmake
+++ b/Modules/CheckIncludeFile.cmake
@@ -1,19 +1,35 @@
-# - Check if the include file exists.
-# CHECK_INCLUDE_FILE(INCLUDE VARIABLE)
-# - macro which checks the include file exists.
-# INCLUDE - name of include file
-# VARIABLE - variable to return result
+#.rst:
+# CheckIncludeFile
+# ----------------
#
-# an optional third argument is the CFlags to add to the compile line
-# or you can use CMAKE_REQUIRED_FLAGS
+# Provides a macro to check if a header file can be included in ``C``.
#
-# The following variables may be set before calling this macro to
-# modify the way the check is run:
+# .. command:: CHECK_INCLUDE_FILE
#
-# CMAKE_REQUIRED_FLAGS = string of compile command line flags
-# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
-# CMAKE_REQUIRED_INCLUDES = list of include directories
+# ::
#
+# CHECK_INCLUDE_FILE(<include> <variable> [<flags>])
+#
+# Check if the given ``<include>`` file may be included in a ``C``
+# source file and store the result in an internal cache entry named
+# ``<variable>``. The optional third argument may be used to add
+# compilation flags to the check (or use ``CMAKE_REQUIRED_FLAGS`` below).
+#
+# The following variables may be set before calling this macro to modify
+# the way the check is run:
+#
+# ``CMAKE_REQUIRED_FLAGS``
+# string of compile command line flags
+# ``CMAKE_REQUIRED_DEFINITIONS``
+# list of macros to define (-DFOO=bar)
+# ``CMAKE_REQUIRED_INCLUDES``
+# list of include directories
+# ``CMAKE_REQUIRED_QUIET``
+# execute quietly without messages
+#
+# See the :module:`CheckIncludeFiles` module to check for multiple headers
+# at once. See the :module:`CheckIncludeFileCXX` module to check for headers
+# using the ``CXX`` language.
#=============================================================================
# Copyright 2002-2009 Kitware, Inc.
@@ -29,7 +45,7 @@
# License text for the above reference.)
macro(CHECK_INCLUDE_FILE INCLUDE VARIABLE)
- if("${VARIABLE}" MATCHES "^${VARIABLE}$")
+ if(NOT DEFINED "${VARIABLE}")
if(CMAKE_REQUIRED_INCLUDES)
set(CHECK_INCLUDE_FILE_C_INCLUDE_DIRS "-DINCLUDE_DIRECTORIES=${CMAKE_REQUIRED_INCLUDES}")
else()
@@ -38,8 +54,10 @@ macro(CHECK_INCLUDE_FILE INCLUDE VARIABLE)
set(MACRO_CHECK_INCLUDE_FILE_FLAGS ${CMAKE_REQUIRED_FLAGS})
set(CHECK_INCLUDE_FILE_VAR ${INCLUDE})
configure_file(${CMAKE_ROOT}/Modules/CheckIncludeFile.c.in
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.c IMMEDIATE)
- message(STATUS "Looking for ${INCLUDE}")
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.c)
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Looking for ${INCLUDE}")
+ endif()
if(${ARGC} EQUAL 3)
set(CMAKE_C_FLAGS_SAVE ${CMAKE_C_FLAGS})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ARGV2}")
@@ -59,14 +77,18 @@ macro(CHECK_INCLUDE_FILE INCLUDE VARIABLE)
endif()
if(${VARIABLE})
- message(STATUS "Looking for ${INCLUDE} - found")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Looking for ${INCLUDE} - found")
+ endif()
set(${VARIABLE} 1 CACHE INTERNAL "Have include ${INCLUDE}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the include file ${INCLUDE} "
"exists passed with the following output:\n"
"${OUTPUT}\n\n")
else()
- message(STATUS "Looking for ${INCLUDE} - not found")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Looking for ${INCLUDE} - not found")
+ endif()
set(${VARIABLE} "" CACHE INTERNAL "Have include ${INCLUDE}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the include file ${INCLUDE} "
diff --git a/Modules/CheckIncludeFileCXX.cmake b/Modules/CheckIncludeFileCXX.cmake
index 22c2d1ac7..9a6df3b74 100644
--- a/Modules/CheckIncludeFileCXX.cmake
+++ b/Modules/CheckIncludeFileCXX.cmake
@@ -1,19 +1,34 @@
-# - Check if the include file exists.
-# CHECK_INCLUDE_FILE_CXX(INCLUDE VARIABLE)
+#.rst:
+# CheckIncludeFileCXX
+# -------------------
#
-# INCLUDE - name of include file
-# VARIABLE - variable to return result
+# Provides a macro to check if a header file can be included in ``CXX``.
#
-# An optional third argument is the CFlags to add to the compile line
-# or you can use CMAKE_REQUIRED_FLAGS.
+# .. command:: CHECK_INCLUDE_FILE_CXX
#
-# The following variables may be set before calling this macro to
-# modify the way the check is run:
+# ::
#
-# CMAKE_REQUIRED_FLAGS = string of compile command line flags
-# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
-# CMAKE_REQUIRED_INCLUDES = list of include directories
+# CHECK_INCLUDE_FILE_CXX(<include> <variable> [<flags>])
#
+# Check if the given ``<include>`` file may be included in a ``CXX``
+# source file and store the result in an internal cache entry named
+# ``<variable>``. The optional third argument may be used to add
+# compilation flags to the check (or use ``CMAKE_REQUIRED_FLAGS`` below).
+#
+# The following variables may be set before calling this macro to modify
+# the way the check is run:
+#
+# ``CMAKE_REQUIRED_FLAGS``
+# string of compile command line flags
+# ``CMAKE_REQUIRED_DEFINITIONS``
+# list of macros to define (-DFOO=bar)
+# ``CMAKE_REQUIRED_INCLUDES``
+# list of include directories
+# ``CMAKE_REQUIRED_QUIET``
+# execute quietly without messages
+#
+# See modules :module:`CheckIncludeFile` and :module:`CheckIncludeFiles`
+# to check for one or more ``C`` headers.
#=============================================================================
# Copyright 2002-2009 Kitware, Inc.
@@ -29,7 +44,7 @@
# License text for the above reference.)
macro(CHECK_INCLUDE_FILE_CXX INCLUDE VARIABLE)
- if("${VARIABLE}" MATCHES "^${VARIABLE}$")
+ if(NOT DEFINED "${VARIABLE}" OR "x${${VARIABLE}}" STREQUAL "x${VARIABLE}")
if(CMAKE_REQUIRED_INCLUDES)
set(CHECK_INCLUDE_FILE_CXX_INCLUDE_DIRS "-DINCLUDE_DIRECTORIES=${CMAKE_REQUIRED_INCLUDES}")
else()
@@ -38,8 +53,10 @@ macro(CHECK_INCLUDE_FILE_CXX INCLUDE VARIABLE)
set(MACRO_CHECK_INCLUDE_FILE_FLAGS ${CMAKE_REQUIRED_FLAGS})
set(CHECK_INCLUDE_FILE_VAR ${INCLUDE})
configure_file(${CMAKE_ROOT}/Modules/CheckIncludeFile.cxx.in
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx IMMEDIATE)
- message(STATUS "Looking for C++ include ${INCLUDE}")
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx)
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Looking for C++ include ${INCLUDE}")
+ endif()
if(${ARGC} EQUAL 3)
set(CMAKE_CXX_FLAGS_SAVE ${CMAKE_CXX_FLAGS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARGV2}")
@@ -59,14 +76,18 @@ macro(CHECK_INCLUDE_FILE_CXX INCLUDE VARIABLE)
endif()
if(${VARIABLE})
- message(STATUS "Looking for C++ include ${INCLUDE} - found")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Looking for C++ include ${INCLUDE} - found")
+ endif()
set(${VARIABLE} 1 CACHE INTERNAL "Have include ${INCLUDE}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the include file ${INCLUDE} "
"exists passed with the following output:\n"
"${OUTPUT}\n\n")
else()
- message(STATUS "Looking for C++ include ${INCLUDE} - not found")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Looking for C++ include ${INCLUDE} - not found")
+ endif()
set(${VARIABLE} "" CACHE INTERNAL "Have include ${INCLUDE}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the include file ${INCLUDE} "
diff --git a/Modules/CheckIncludeFiles.cmake b/Modules/CheckIncludeFiles.cmake
index daf2dd0ea..843cd35ef 100644
--- a/Modules/CheckIncludeFiles.cmake
+++ b/Modules/CheckIncludeFiles.cmake
@@ -1,16 +1,35 @@
-# - Check if the files can be included
+#.rst:
+# CheckIncludeFiles
+# -----------------
#
-# CHECK_INCLUDE_FILES(INCLUDE VARIABLE)
+# Provides a macro to check if a list of one or more header files can
+# be included together in ``C``.
#
-# INCLUDE - list of files to include
-# VARIABLE - variable to return result
+# .. command:: CHECK_INCLUDE_FILES
#
-# The following variables may be set before calling this macro to
-# modify the way the check is run:
+# ::
#
-# CMAKE_REQUIRED_FLAGS = string of compile command line flags
-# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
-# CMAKE_REQUIRED_INCLUDES = list of include directories
+# CHECK_INCLUDE_FILES("<includes>" <variable>)
+#
+# Check if the given ``<includes>`` list may be included together
+# in a ``C`` source file and store the result in an internal cache
+# entry named ``<variable>``. Specify the ``<includes>`` argument
+# as a :ref:`;-list <CMake Language Lists>` of header file names.
+#
+# The following variables may be set before calling this macro to modify
+# the way the check is run:
+#
+# ``CMAKE_REQUIRED_FLAGS``
+# string of compile command line flags
+# ``CMAKE_REQUIRED_DEFINITIONS``
+# list of macros to define (-DFOO=bar)
+# ``CMAKE_REQUIRED_INCLUDES``
+# list of include directories
+# ``CMAKE_REQUIRED_QUIET``
+# execute quietly without messages
+#
+# See modules :module:`CheckIncludeFile` and :module:`CheckIncludeFileCXX`
+# to check for a single header file in ``C`` or ``CXX`` languages.
#=============================================================================
# Copyright 2003-2012 Kitware, Inc.
@@ -26,7 +45,7 @@
# License text for the above reference.)
macro(CHECK_INCLUDE_FILES INCLUDE VARIABLE)
- if("${VARIABLE}" MATCHES "^${VARIABLE}$")
+ if(NOT DEFINED "${VARIABLE}")
set(CMAKE_CONFIGURABLE_FILE_CONTENT "/* */\n")
if(CMAKE_REQUIRED_INCLUDES)
set(CHECK_INCLUDE_FILES_INCLUDE_DIRS "-DINCLUDE_DIRECTORIES=${CMAKE_REQUIRED_INCLUDES}")
@@ -40,9 +59,9 @@ macro(CHECK_INCLUDE_FILES INCLUDE VARIABLE)
"${CMAKE_CONFIGURABLE_FILE_CONTENT}#include <${FILE}>\n")
endforeach()
set(CMAKE_CONFIGURABLE_FILE_CONTENT
- "${CMAKE_CONFIGURABLE_FILE_CONTENT}\n\nint main(){return 0;}\n")
+ "${CMAKE_CONFIGURABLE_FILE_CONTENT}\n\nint main(void){return 0;}\n")
configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in"
- "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFiles.c" @ONLY IMMEDIATE)
+ "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFiles.c" @ONLY)
set(_INCLUDE ${INCLUDE}) # remove empty elements
if("${_INCLUDE}" MATCHES "^([^;]+);.+;([^;]+)$")
@@ -54,7 +73,9 @@ macro(CHECK_INCLUDE_FILES INCLUDE VARIABLE)
set(_description "include file ${_INCLUDE}")
endif()
- message(STATUS "Looking for ${_description}")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Looking for ${_description}")
+ endif()
try_compile(${VARIABLE}
${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFiles.c
@@ -64,14 +85,18 @@ macro(CHECK_INCLUDE_FILES INCLUDE VARIABLE)
"${CHECK_INCLUDE_FILES_INCLUDE_DIRS}"
OUTPUT_VARIABLE OUTPUT)
if(${VARIABLE})
- message(STATUS "Looking for ${_description} - found")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Looking for ${_description} - found")
+ endif()
set(${VARIABLE} 1 CACHE INTERNAL "Have include ${INCLUDE}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if files ${INCLUDE} "
"exist passed with the following output:\n"
"${OUTPUT}\n\n")
else()
- message(STATUS "Looking for ${_description} - not found")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Looking for ${_description} - not found")
+ endif()
set(${VARIABLE} "" CACHE INTERNAL "Have includes ${INCLUDE}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if files ${INCLUDE} "
diff --git a/Modules/CheckLanguage.cmake b/Modules/CheckLanguage.cmake
index 87a401813..99c809b7a 100644
--- a/Modules/CheckLanguage.cmake
+++ b/Modules/CheckLanguage.cmake
@@ -1,19 +1,32 @@
-# - Check if a language can be enabled
+#.rst:
+# CheckLanguage
+# -------------
+#
+# Check if a language can be enabled
+#
# Usage:
-# check_language(<lang>)
+#
+# ::
+#
+# check_language(<lang>)
+#
# where <lang> is a language that may be passed to enable_language()
# such as "Fortran". If CMAKE_<lang>_COMPILER is already defined the
# check does nothing. Otherwise it tries enabling the language in a
# test project. The result is cached in CMAKE_<lang>_COMPILER as the
-# compiler that was found, or NOTFOUND if the language cannot be enabled.
+# compiler that was found, or NOTFOUND if the language cannot be
+# enabled.
#
# Example:
-# check_language(Fortran)
-# if(CMAKE_Fortran_COMPILER)
-# enable_language(Fortran)
-# else()
-# message(STATUS "No Fortran support")
-# endif()
+#
+# ::
+#
+# check_language(Fortran)
+# if(CMAKE_Fortran_COMPILER)
+# enable_language(Fortran)
+# else()
+# message(STATUS "No Fortran support")
+# endif()
#=============================================================================
# Copyright 2009-2012 Kitware, Inc.
@@ -34,7 +47,7 @@ macro(check_language lang)
message(STATUS ${_desc})
file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/Check${lang})
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/Check${lang}/CMakeLists.txt"
- "cmake_minimum_required(VERSION 2.8)
+ "cmake_minimum_required(VERSION ${CMAKE_VERSION})
project(Check${lang} ${lang})
file(WRITE \"\${CMAKE_CURRENT_BINARY_DIR}/result.cmake\"
\"set(CMAKE_${lang}_COMPILER \\\"\${CMAKE_${lang}_COMPILER}\\\")\\n\"
diff --git a/Modules/CheckLibraryExists.cmake b/Modules/CheckLibraryExists.cmake
index fb7d0ec01..6b538233e 100644
--- a/Modules/CheckLibraryExists.cmake
+++ b/Modules/CheckLibraryExists.cmake
@@ -1,17 +1,30 @@
-# - Check if the function exists.
+#.rst:
+# CheckLibraryExists
+# ------------------
+#
+# Check if the function exists.
+#
# CHECK_LIBRARY_EXISTS (LIBRARY FUNCTION LOCATION VARIABLE)
#
-# LIBRARY - the name of the library you are looking for
-# FUNCTION - the name of the function
-# LOCATION - location where the library should be found
-# VARIABLE - variable to store the result
+# ::
+#
+# LIBRARY - the name of the library you are looking for
+# FUNCTION - the name of the function
+# LOCATION - location where the library should be found
+# VARIABLE - variable to store the result
+# Will be created as an internal cache variable.
+#
+#
+#
+# The following variables may be set before calling this macro to modify
+# the way the check is run:
#
-# The following variables may be set before calling this macro to
-# modify the way the check is run:
+# ::
#
-# CMAKE_REQUIRED_FLAGS = string of compile command line flags
-# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
-# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+# CMAKE_REQUIRED_FLAGS = string of compile command line flags
+# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
+# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+# CMAKE_REQUIRED_QUIET = execute quietly without messages
#=============================================================================
# Copyright 2002-2009 Kitware, Inc.
@@ -29,34 +42,51 @@
macro(CHECK_LIBRARY_EXISTS LIBRARY FUNCTION LOCATION VARIABLE)
- if("${VARIABLE}" MATCHES "^${VARIABLE}$")
+ if(NOT DEFINED "${VARIABLE}")
set(MACRO_CHECK_LIBRARY_EXISTS_DEFINITION
"-DCHECK_FUNCTION_EXISTS=${FUNCTION} ${CMAKE_REQUIRED_FLAGS}")
- message(STATUS "Looking for ${FUNCTION} in ${LIBRARY}")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Looking for ${FUNCTION} in ${LIBRARY}")
+ endif()
set(CHECK_LIBRARY_EXISTS_LIBRARIES ${LIBRARY})
if(CMAKE_REQUIRED_LIBRARIES)
set(CHECK_LIBRARY_EXISTS_LIBRARIES
${CHECK_LIBRARY_EXISTS_LIBRARIES} ${CMAKE_REQUIRED_LIBRARIES})
endif()
+
+ if(CMAKE_C_COMPILER_LOADED)
+ set(_cle_source ${CMAKE_ROOT}/Modules/CheckFunctionExists.c)
+ elseif(CMAKE_CXX_COMPILER_LOADED)
+ set(_cle_source ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckLibraryExists/CheckFunctionExists.cxx)
+ configure_file(${CMAKE_ROOT}/Modules/CheckFunctionExists.c "${_cle_source}" COPYONLY)
+ else()
+ message(FATAL_ERROR "CHECK_FUNCTION_EXISTS needs either C or CXX language enabled")
+ endif()
+
try_compile(${VARIABLE}
${CMAKE_BINARY_DIR}
- ${CMAKE_ROOT}/Modules/CheckFunctionExists.c
+ ${_cle_source}
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
LINK_LIBRARIES ${CHECK_LIBRARY_EXISTS_LIBRARIES}
CMAKE_FLAGS
-DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_LIBRARY_EXISTS_DEFINITION}
-DLINK_DIRECTORIES:STRING=${LOCATION}
OUTPUT_VARIABLE OUTPUT)
+ unset(_cle_source)
if(${VARIABLE})
- message(STATUS "Looking for ${FUNCTION} in ${LIBRARY} - found")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Looking for ${FUNCTION} in ${LIBRARY} - found")
+ endif()
set(${VARIABLE} 1 CACHE INTERNAL "Have library ${LIBRARY}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the function ${FUNCTION} exists in the ${LIBRARY} "
"passed with the following output:\n"
"${OUTPUT}\n\n")
else()
- message(STATUS "Looking for ${FUNCTION} in ${LIBRARY} - not found")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Looking for ${FUNCTION} in ${LIBRARY} - not found")
+ endif()
set(${VARIABLE} "" CACHE INTERNAL "Have library ${LIBRARY}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the function ${FUNCTION} exists in the ${LIBRARY} "
diff --git a/Modules/CheckPrototypeDefinition.cmake b/Modules/CheckPrototypeDefinition.cmake
index 2342b3c4f..e203d4c3f 100644
--- a/Modules/CheckPrototypeDefinition.cmake
+++ b/Modules/CheckPrototypeDefinition.cmake
@@ -1,23 +1,40 @@
-# - Check if the protoype we expect is correct.
+#.rst:
+# CheckPrototypeDefinition
+# ------------------------
+#
+# Check if the protoype we expect is correct.
+#
# check_prototype_definition(FUNCTION PROTOTYPE RETURN HEADER VARIABLE)
-# FUNCTION - The name of the function (used to check if prototype exists)
-# PROTOTYPE- The prototype to check.
-# RETURN - The return value of the function.
-# HEADER - The header files required.
-# VARIABLE - The variable to store the result.
+#
+# ::
+#
+# FUNCTION - The name of the function (used to check if prototype exists)
+# PROTOTYPE- The prototype to check.
+# RETURN - The return value of the function.
+# HEADER - The header files required.
+# VARIABLE - The variable to store the result.
+# Will be created as an internal cache variable.
+#
# Example:
-# check_prototype_definition(getpwent_r
-# "struct passwd *getpwent_r(struct passwd *src, char *buf, int buflen)"
-# "NULL"
-# "unistd.h;pwd.h"
-# SOLARIS_GETPWENT_R)
-# The following variables may be set before calling this macro to
-# modify the way the check is run:
#
-# CMAKE_REQUIRED_FLAGS = string of compile command line flags
-# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
-# CMAKE_REQUIRED_INCLUDES = list of include directories
-# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+# ::
+#
+# check_prototype_definition(getpwent_r
+# "struct passwd *getpwent_r(struct passwd *src, char *buf, int buflen)"
+# "NULL"
+# "unistd.h;pwd.h"
+# SOLARIS_GETPWENT_R)
+#
+# The following variables may be set before calling this macro to modify
+# the way the check is run:
+#
+# ::
+#
+# CMAKE_REQUIRED_FLAGS = string of compile command line flags
+# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
+# CMAKE_REQUIRED_INCLUDES = list of include directories
+# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+# CMAKE_REQUIRED_QUIET = execute quietly without messages
#=============================================================================
# Copyright 2005-2009 Kitware, Inc.
@@ -40,7 +57,7 @@ get_filename_component(__check_proto_def_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)
function(CHECK_PROTOTYPE_DEFINITION _FUNCTION _PROTOTYPE _RETURN _HEADER _VARIABLE)
- if ("${_VARIABLE}" MATCHES "^${_VARIABLE}$")
+ if (NOT DEFINED ${_VARIABLE})
set(CHECK_PROTOTYPE_DEFINITION_CONTENT "/* */\n")
set(CHECK_PROTOTYPE_DEFINITION_FLAGS ${CMAKE_REQUIRED_FLAGS})
@@ -82,12 +99,16 @@ function(CHECK_PROTOTYPE_DEFINITION _FUNCTION _PROTOTYPE _RETURN _HEADER _VARIAB
if (${_VARIABLE})
set(${_VARIABLE} 1 CACHE INTERNAL "Have correct prototype for ${_FUNCTION}")
- message(STATUS "Checking prototype ${_FUNCTION} for ${_VARIABLE} - True")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Checking prototype ${_FUNCTION} for ${_VARIABLE} - True")
+ endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the prototype ${_FUNCTION} exists for ${_VARIABLE} passed with the following output:\n"
"${OUTPUT}\n\n")
else ()
- message(STATUS "Checking prototype ${_FUNCTION} for ${_VARIABLE} - False")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Checking prototype ${_FUNCTION} for ${_VARIABLE} - False")
+ endif()
set(${_VARIABLE} 0 CACHE INTERNAL "Have correct prototype for ${_FUNCTION}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the prototype ${_FUNCTION} exists for ${_VARIABLE} failed with the following output:\n"
diff --git a/Modules/CheckStructHasMember.cmake b/Modules/CheckStructHasMember.cmake
index ea2891c8b..6c1520592 100644
--- a/Modules/CheckStructHasMember.cmake
+++ b/Modules/CheckStructHasMember.cmake
@@ -1,19 +1,39 @@
-# - Check if the given struct or class has the specified member variable
-# CHECK_STRUCT_HAS_MEMBER (STRUCT MEMBER HEADER VARIABLE)
+#.rst:
+# CheckStructHasMember
+# --------------------
#
-# STRUCT - the name of the struct or class you are interested in
-# MEMBER - the member which existence you want to check
-# HEADER - the header(s) where the prototype should be declared
-# VARIABLE - variable to store the result
+# Check if the given struct or class has the specified member variable
#
-# The following variables may be set before calling this macro to
-# modify the way the check is run:
+# ::
#
-# CMAKE_REQUIRED_FLAGS = string of compile command line flags
-# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
-# CMAKE_REQUIRED_INCLUDES = list of include directories
+# CHECK_STRUCT_HAS_MEMBER(<struct> <member> <header> <variable>
+# [LANGUAGE <language>])
#
-# Example: CHECK_STRUCT_HAS_MEMBER("struct timeval" tv_sec sys/select.h HAVE_TIMEVAL_TV_SEC)
+# ::
+#
+# <struct> - the name of the struct or class you are interested in
+# <member> - the member which existence you want to check
+# <header> - the header(s) where the prototype should be declared
+# <variable> - variable to store the result
+# <language> - the compiler to use (C or CXX)
+#
+#
+#
+# The following variables may be set before calling this macro to modify
+# the way the check is run:
+#
+# ::
+#
+# CMAKE_REQUIRED_FLAGS = string of compile command line flags
+# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
+# CMAKE_REQUIRED_INCLUDES = list of include directories
+# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+# CMAKE_REQUIRED_QUIET = execute quietly without messages
+#
+#
+#
+# Example: CHECK_STRUCT_HAS_MEMBER("struct timeval" tv_sec sys/select.h
+# HAVE_TIMEVAL_TV_SEC LANGUAGE C)
#=============================================================================
# Copyright 2007-2009 Kitware, Inc.
@@ -29,6 +49,7 @@
# License text for the above reference.)
include(CheckCSourceCompiles)
+include(CheckCXXSourceCompiles)
macro (CHECK_STRUCT_HAS_MEMBER _STRUCT _MEMBER _HEADER _RESULT)
set(_INCLUDE_FILES)
@@ -36,16 +57,28 @@ macro (CHECK_STRUCT_HAS_MEMBER _STRUCT _MEMBER _HEADER _RESULT)
set(_INCLUDE_FILES "${_INCLUDE_FILES}#include <${it}>\n")
endforeach ()
+ if("x${ARGN}" STREQUAL "x")
+ set(_lang C)
+ elseif("x${ARGN}" MATCHES "^xLANGUAGE;([a-zA-Z]+)$")
+ set(_lang "${CMAKE_MATCH_1}")
+ else()
+ message(FATAL_ERROR "Unknown arguments:\n ${ARGN}\n")
+ endif()
+
set(_CHECK_STRUCT_MEMBER_SOURCE_CODE "
${_INCLUDE_FILES}
int main()
{
- ${_STRUCT}* tmp;
- tmp->${_MEMBER};
- return 0;
+ (void)sizeof(((${_STRUCT} *)0)->${_MEMBER});
+ return 0;
}
")
- CHECK_C_SOURCE_COMPILES("${_CHECK_STRUCT_MEMBER_SOURCE_CODE}" ${_RESULT})
+ if("${_lang}" STREQUAL "C")
+ CHECK_C_SOURCE_COMPILES("${_CHECK_STRUCT_MEMBER_SOURCE_CODE}" ${_RESULT})
+ elseif("${_lang}" STREQUAL "CXX")
+ CHECK_CXX_SOURCE_COMPILES("${_CHECK_STRUCT_MEMBER_SOURCE_CODE}" ${_RESULT})
+ else()
+ message(FATAL_ERROR "Unknown language:\n ${_lang}\nSupported languages: C, CXX.\n")
+ endif()
endmacro ()
-
diff --git a/Modules/CheckSymbolExists.cmake b/Modules/CheckSymbolExists.cmake
index 0969bc562..c4dff3faa 100644
--- a/Modules/CheckSymbolExists.cmake
+++ b/Modules/CheckSymbolExists.cmake
@@ -1,26 +1,35 @@
-# - Check if a symbol exists as a function, variable, or macro
+#.rst:
+# CheckSymbolExists
+# -----------------
+#
+# Check if a symbol exists as a function, variable, or macro
+#
# CHECK_SYMBOL_EXISTS(<symbol> <files> <variable>)
#
# Check that the <symbol> is available after including given header
-# <files> and store the result in a <variable>. Specify the list
-# of files in one argument as a semicolon-separated list.
+# <files> and store the result in a <variable>. Specify the list of
+# files in one argument as a semicolon-separated list.
+# <variable> will be created as an internal cache variable.
#
# If the header files define the symbol as a macro it is considered
-# available and assumed to work. If the header files declare the
-# symbol as a function or variable then the symbol must also be
-# available for linking. If the symbol is a type or enum value
-# it will not be recognized (consider using CheckTypeSize or
-# CheckCSourceCompiles).
-# If the check needs to be done in C++, consider using CHECK_CXX_SYMBOL_EXISTS(),
-# which does the same as CHECK_SYMBOL_EXISTS(), but in C++.
+# available and assumed to work. If the header files declare the symbol
+# as a function or variable then the symbol must also be available for
+# linking. If the symbol is a type or enum value it will not be
+# recognized (consider using CheckTypeSize or CheckCSourceCompiles). If
+# the check needs to be done in C++, consider using
+# CHECK_CXX_SYMBOL_EXISTS(), which does the same as
+# CHECK_SYMBOL_EXISTS(), but in C++.
#
-# The following variables may be set before calling this macro to
-# modify the way the check is run:
+# The following variables may be set before calling this macro to modify
+# the way the check is run:
#
-# CMAKE_REQUIRED_FLAGS = string of compile command line flags
-# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
-# CMAKE_REQUIRED_INCLUDES = list of include directories
-# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+# ::
+#
+# CMAKE_REQUIRED_FLAGS = string of compile command line flags
+# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
+# CMAKE_REQUIRED_INCLUDES = list of include directories
+# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+# CMAKE_REQUIRED_QUIET = execute quietly without messages
#=============================================================================
# Copyright 2003-2011 Kitware, Inc.
@@ -35,14 +44,18 @@
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
-
-
macro(CHECK_SYMBOL_EXISTS SYMBOL FILES VARIABLE)
- _CHECK_SYMBOL_EXISTS("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.c" "${SYMBOL}" "${FILES}" "${VARIABLE}" )
+ if(CMAKE_C_COMPILER_LOADED)
+ _CHECK_SYMBOL_EXISTS("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.c" "${SYMBOL}" "${FILES}" "${VARIABLE}" )
+ elseif(CMAKE_CXX_COMPILER_LOADED)
+ _CHECK_SYMBOL_EXISTS("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.cxx" "${SYMBOL}" "${FILES}" "${VARIABLE}" )
+ else()
+ message(FATAL_ERROR "CHECK_SYMBOL_EXISTS needs either C or CXX language enabled")
+ endif()
endmacro()
macro(_CHECK_SYMBOL_EXISTS SOURCEFILE SYMBOL FILES VARIABLE)
- if("${VARIABLE}" MATCHES "^${VARIABLE}$")
+ if(NOT DEFINED "${VARIABLE}" OR "x${${VARIABLE}}" STREQUAL "x${VARIABLE}")
set(CMAKE_CONFIGURABLE_FILE_CONTENT "/* */\n")
set(MACRO_CHECK_SYMBOL_EXISTS_FLAGS ${CMAKE_REQUIRED_FLAGS})
if(CMAKE_REQUIRED_LIBRARIES)
@@ -65,9 +78,11 @@ macro(_CHECK_SYMBOL_EXISTS SOURCEFILE SYMBOL FILES VARIABLE)
"${CMAKE_CONFIGURABLE_FILE_CONTENT}\nint main(int argc, char** argv)\n{\n (void)argv;\n#ifndef ${SYMBOL}\n return ((int*)(&${SYMBOL}))[argc];\n#else\n (void)argc;\n return 0;\n#endif\n}\n")
configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in"
- "${SOURCEFILE}" @ONLY IMMEDIATE)
+ "${SOURCEFILE}" @ONLY)
- message(STATUS "Looking for ${SYMBOL}")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Looking for ${SYMBOL}")
+ endif()
try_compile(${VARIABLE}
${CMAKE_BINARY_DIR}
"${SOURCEFILE}"
@@ -78,7 +93,9 @@ macro(_CHECK_SYMBOL_EXISTS SOURCEFILE SYMBOL FILES VARIABLE)
"${CMAKE_SYMBOL_EXISTS_INCLUDES}"
OUTPUT_VARIABLE OUTPUT)
if(${VARIABLE})
- message(STATUS "Looking for ${SYMBOL} - found")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Looking for ${SYMBOL} - found")
+ endif()
set(${VARIABLE} 1 CACHE INTERNAL "Have symbol ${SYMBOL}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the ${SYMBOL} "
@@ -86,7 +103,9 @@ macro(_CHECK_SYMBOL_EXISTS SOURCEFILE SYMBOL FILES VARIABLE)
"${OUTPUT}\nFile ${SOURCEFILE}:\n"
"${CMAKE_CONFIGURABLE_FILE_CONTENT}\n")
else()
- message(STATUS "Looking for ${SYMBOL} - not found")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Looking for ${SYMBOL} - not found")
+ endif()
set(${VARIABLE} "" CACHE INTERNAL "Have symbol ${SYMBOL}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the ${SYMBOL} "
diff --git a/Modules/CheckTypeSize.cmake b/Modules/CheckTypeSize.cmake
index 2d0eab51c..5938d6c9a 100644
--- a/Modules/CheckTypeSize.cmake
+++ b/Modules/CheckTypeSize.cmake
@@ -1,42 +1,69 @@
-# - Check sizeof a type
-# CHECK_TYPE_SIZE(TYPE VARIABLE [BUILTIN_TYPES_ONLY])
-# Check if the type exists and determine its size.
-# On return, "HAVE_${VARIABLE}" holds the existence of the type,
-# and "${VARIABLE}" holds one of the following:
-# <size> = type has non-zero size <size>
-# "0" = type has arch-dependent size (see below)
-# "" = type does not exist
-# Furthermore, the variable "${VARIABLE}_CODE" holds C preprocessor
-# code to define the macro "${VARIABLE}" to the size of the type, or
-# leave the macro undefined if the type does not exist.
-#
-# The variable "${VARIABLE}" may be "0" when CMAKE_OSX_ARCHITECTURES
-# has multiple architectures for building OS X universal binaries.
-# This indicates that the type size varies across architectures.
-# In this case "${VARIABLE}_CODE" contains C preprocessor tests
-# mapping from each architecture macro to the corresponding type size.
-# The list of architecture macros is stored in "${VARIABLE}_KEYS", and
-# the value for each key is stored in "${VARIABLE}-${KEY}".
+#.rst:
+# CheckTypeSize
+# -------------
+#
+# Check sizeof a type
+#
+# ::
+#
+# CHECK_TYPE_SIZE(TYPE VARIABLE [BUILTIN_TYPES_ONLY]
+# [LANGUAGE <language>])
+#
+# Check if the type exists and determine its size. On return,
+# "HAVE_${VARIABLE}" holds the existence of the type, and "${VARIABLE}"
+# holds one of the following:
+#
+# ::
+#
+# <size> = type has non-zero size <size>
+# "0" = type has arch-dependent size (see below)
+# "" = type does not exist
+#
+# Both ``HAVE_${VARIABLE}`` and ``${VARIABLE}`` will be created as internal
+# cache variables.
+#
+# Furthermore, the variable "${VARIABLE}_CODE" holds C preprocessor code
+# to define the macro "${VARIABLE}" to the size of the type, or leave
+# the macro undefined if the type does not exist.
+#
+# The variable "${VARIABLE}" may be "0" when CMAKE_OSX_ARCHITECTURES has
+# multiple architectures for building OS X universal binaries. This
+# indicates that the type size varies across architectures. In this
+# case "${VARIABLE}_CODE" contains C preprocessor tests mapping from
+# each architecture macro to the corresponding type size. The list of
+# architecture macros is stored in "${VARIABLE}_KEYS", and the value for
+# each key is stored in "${VARIABLE}-${KEY}".
#
# If the BUILTIN_TYPES_ONLY option is not given, the macro checks for
# headers <sys/types.h>, <stdint.h>, and <stddef.h>, and saves results
-# in HAVE_SYS_TYPES_H, HAVE_STDINT_H, and HAVE_STDDEF_H. The type
-# size check automatically includes the available headers, thus
-# supporting checks of types defined in the headers.
+# in HAVE_SYS_TYPES_H, HAVE_STDINT_H, and HAVE_STDDEF_H. The type size
+# check automatically includes the available headers, thus supporting
+# checks of types defined in the headers.
+#
+# If LANGUAGE is set, the specified compiler will be used to perform the
+# check. Acceptable values are C and CXX
#
-# Despite the name of the macro you may use it to check the size of
-# more complex expressions, too. To check e.g. for the size of a struct
+# Despite the name of the macro you may use it to check the size of more
+# complex expressions, too. To check e.g. for the size of a struct
# member you can do something like this:
-# check_type_size("((struct something*)0)->member" SIZEOF_MEMBER)
#
-# The following variables may be set before calling this macro to
-# modify the way the check is run:
+# ::
+#
+# check_type_size("((struct something*)0)->member" SIZEOF_MEMBER)
+#
+#
+#
+# The following variables may be set before calling this macro to modify
+# the way the check is run:
+#
+# ::
#
-# CMAKE_REQUIRED_FLAGS = string of compile command line flags
-# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
-# CMAKE_REQUIRED_INCLUDES = list of include directories
-# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
-# CMAKE_EXTRA_INCLUDE_FILES = list of extra headers to include
+# CMAKE_REQUIRED_FLAGS = string of compile command line flags
+# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
+# CMAKE_REQUIRED_INCLUDES = list of include directories
+# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+# CMAKE_REQUIRED_QUIET = execute quietly without messages
+# CMAKE_EXTRA_INCLUDE_FILES = list of extra headers to include
#=============================================================================
# Copyright 2002-2009 Kitware, Inc.
@@ -52,16 +79,19 @@
# License text for the above reference.)
include(CheckIncludeFile)
+include(CheckIncludeFileCXX)
cmake_policy(PUSH)
-cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
+cmake_policy(SET CMP0054 NEW)
get_filename_component(__check_type_size_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)
#-----------------------------------------------------------------------------
# Helper function. DO NOT CALL DIRECTLY.
-function(__check_type_size_impl type var map builtin)
- message(STATUS "Check size of ${type}")
+function(__check_type_size_impl type var map builtin language)
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Check size of ${type}")
+ endif()
# Include header files.
set(headers)
@@ -82,8 +112,13 @@ function(__check_type_size_impl type var map builtin)
# Perform the check.
-
- set(src ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize/${var}.c)
+ if(language STREQUAL "C")
+ set(src ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize/${var}.c)
+ elseif(language STREQUAL "CXX")
+ set(src ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize/${var}.cpp)
+ else()
+ message(FATAL_ERROR "Unknown language:\n ${language}\nSupported languages: C, CXX.\n")
+ endif()
set(bin ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize/${var}.bin)
configure_file(${__check_type_size_dir}/CheckTypeSize.c.in ${src} @ONLY)
try_compile(HAVE_${var} ${CMAKE_BINARY_DIR} ${src}
@@ -110,7 +145,7 @@ function(__check_type_size_impl type var map builtin)
foreach(info ${strings})
if("${info}" MATCHES "${regex_size}")
# Get the type size.
- string(REGEX REPLACE "${regex_size}" "\\1" size "${info}")
+ set(size "${CMAKE_MATCH_1}")
if(first)
set(${var} ${size})
elseif(NOT "${size}" STREQUAL "${${var}}")
@@ -140,13 +175,17 @@ function(__check_type_size_impl type var map builtin)
message(SEND_ERROR "CHECK_TYPE_SIZE found different results, consider setting CMAKE_OSX_ARCHITECTURES or CMAKE_TRY_COMPILE_OSX_ARCHITECTURES to one or no architecture !")
endif()
- message(STATUS "Check size of ${type} - done")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Check size of ${type} - done")
+ endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining size of ${type} passed with the following output:\n${output}\n\n")
set(${var} "${${var}}" CACHE INTERNAL "CHECK_TYPE_SIZE: sizeof(${type})")
else()
# The check failed to compile.
- message(STATUS "Check size of ${type} - failed")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Check size of ${type} - failed")
+ endif()
file(READ ${src} content)
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining size of ${type} failed with the following output:\n${output}\n${src}:\n${content}\n\n")
@@ -157,21 +196,57 @@ endfunction()
#-----------------------------------------------------------------------------
macro(CHECK_TYPE_SIZE TYPE VARIABLE)
+ # parse arguments
+ unset(doing)
+ foreach(arg ${ARGN})
+ if("x${arg}" STREQUAL "xBUILTIN_TYPES_ONLY")
+ set(_CHECK_TYPE_SIZE_${arg} 1)
+ unset(doing)
+ elseif("x${arg}" STREQUAL "xLANGUAGE") # change to MATCHES for more keys
+ set(doing "${arg}")
+ set(_CHECK_TYPE_SIZE_${doing} "")
+ elseif("x${doing}" STREQUAL "xLANGUAGE")
+ set(_CHECK_TYPE_SIZE_${doing} "${arg}")
+ unset(doing)
+ else()
+ message(FATAL_ERROR "Unknown argument:\n ${arg}\n")
+ endif()
+ endforeach()
+ if("x${doing}" MATCHES "^x(LANGUAGE)$")
+ message(FATAL_ERROR "Missing argument:\n ${doing} arguments requires a value\n")
+ endif()
+ if(DEFINED _CHECK_TYPE_SIZE_LANGUAGE)
+ if(NOT "x${_CHECK_TYPE_SIZE_LANGUAGE}" MATCHES "^x(C|CXX)$")
+ message(FATAL_ERROR "Unknown language:\n ${_CHECK_TYPE_SIZE_LANGUAGE}.\nSupported languages: C, CXX.\n")
+ endif()
+ set(_language ${_CHECK_TYPE_SIZE_LANGUAGE})
+ else()
+ set(_language C)
+ endif()
+
# Optionally check for standard headers.
- if("${ARGV2}" STREQUAL "BUILTIN_TYPES_ONLY")
+ if(_CHECK_TYPE_SIZE_BUILTIN_TYPES_ONLY)
set(_builtin 0)
else()
set(_builtin 1)
- check_include_file(sys/types.h HAVE_SYS_TYPES_H)
- check_include_file(stdint.h HAVE_STDINT_H)
- check_include_file(stddef.h HAVE_STDDEF_H)
+ if(_language STREQUAL "C")
+ check_include_file(sys/types.h HAVE_SYS_TYPES_H)
+ check_include_file(stdint.h HAVE_STDINT_H)
+ check_include_file(stddef.h HAVE_STDDEF_H)
+ elseif(_language STREQUAL "CXX")
+ check_include_file_cxx(sys/types.h HAVE_SYS_TYPES_H)
+ check_include_file_cxx(stdint.h HAVE_STDINT_H)
+ check_include_file_cxx(stddef.h HAVE_STDDEF_H)
+ endif()
endif()
+ unset(_CHECK_TYPE_SIZE_BUILTIN_TYPES_ONLY)
+ unset(_CHECK_TYPE_SIZE_LANGUAGE)
# Compute or load the size or size map.
set(${VARIABLE}_KEYS)
set(_map_file ${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CheckTypeSize/${VARIABLE}.cmake)
if(NOT DEFINED HAVE_${VARIABLE})
- __check_type_size_impl(${TYPE} ${VARIABLE} ${_map_file} ${_builtin})
+ __check_type_size_impl(${TYPE} ${VARIABLE} ${_map_file} ${_builtin} ${_language})
endif()
include(${_map_file} OPTIONAL)
set(_map_file)
diff --git a/Modules/CheckVariableExists.cmake b/Modules/CheckVariableExists.cmake
index a21e65f26..f3e05e41b 100644
--- a/Modules/CheckVariableExists.cmake
+++ b/Modules/CheckVariableExists.cmake
@@ -1,17 +1,33 @@
-# - Check if the variable exists.
-# CHECK_VARIABLE_EXISTS(VAR VARIABLE)
+#.rst:
+# CheckVariableExists
+# -------------------
+#
+# Check if the variable exists.
+#
+# ::
+#
+# CHECK_VARIABLE_EXISTS(VAR VARIABLE)
+#
+#
+#
+# ::
+#
+# VAR - the name of the variable
+# VARIABLE - variable to store the result
+# Will be created as an internal cache variable.
#
-# VAR - the name of the variable
-# VARIABLE - variable to store the result
#
# This macro is only for C variables.
#
-# The following variables may be set before calling this macro to
-# modify the way the check is run:
+# The following variables may be set before calling this macro to modify
+# the way the check is run:
#
-# CMAKE_REQUIRED_FLAGS = string of compile command line flags
-# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
-# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+# ::
+#
+# CMAKE_REQUIRED_FLAGS = string of compile command line flags
+# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
+# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+# CMAKE_REQUIRED_QUIET = execute quietly without messages
#=============================================================================
# Copyright 2002-2009 Kitware, Inc.
@@ -29,10 +45,12 @@
macro(CHECK_VARIABLE_EXISTS VAR VARIABLE)
- if("${VARIABLE}" MATCHES "^${VARIABLE}$")
+ if(NOT DEFINED "${VARIABLE}")
set(MACRO_CHECK_VARIABLE_DEFINITIONS
"-DCHECK_VARIABLE_EXISTS=${VAR} ${CMAKE_REQUIRED_FLAGS}")
- message(STATUS "Looking for ${VAR}")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Looking for ${VAR}")
+ endif()
if(CMAKE_REQUIRED_LIBRARIES)
set(CHECK_VARIABLE_EXISTS_ADD_LIBRARIES
LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
@@ -48,13 +66,17 @@ macro(CHECK_VARIABLE_EXISTS VAR VARIABLE)
OUTPUT_VARIABLE OUTPUT)
if(${VARIABLE})
set(${VARIABLE} 1 CACHE INTERNAL "Have variable ${VAR}")
- message(STATUS "Looking for ${VAR} - found")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Looking for ${VAR} - found")
+ endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the variable ${VAR} exists passed with the following output:\n"
"${OUTPUT}\n\n")
else()
set(${VARIABLE} "" CACHE INTERNAL "Have variable ${VAR}")
- message(STATUS "Looking for ${VAR} - not found")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Looking for ${VAR} - not found")
+ endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the variable ${VAR} exists failed with the following output:\n"
"${OUTPUT}\n\n")
diff --git a/Modules/Compiler/ADSP-DetermineCompiler.cmake b/Modules/Compiler/ADSP-DetermineCompiler.cmake
new file mode 100644
index 000000000..0340f6904
--- /dev/null
+++ b/Modules/Compiler/ADSP-DetermineCompiler.cmake
@@ -0,0 +1,10 @@
+
+set(_compiler_id_pp_test "defined(__VISUALDSPVERSION__) || defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__)")
+
+set(_compiler_id_version_compute "
+#if defined(__VISUALDSPVERSION__)
+ /* __VISUALDSPVERSION__ = 0xVVRRPP00 */
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_HEX@(__VISUALDSPVERSION__>>24)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_HEX@(__VISUALDSPVERSION__>>16 & 0xFF)
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_HEX@(__VISUALDSPVERSION__>>8 & 0xFF)
+#endif")
diff --git a/Modules/Compiler/ARMCC-ASM.cmake b/Modules/Compiler/ARMCC-ASM.cmake
new file mode 100644
index 000000000..8e3cfc5c8
--- /dev/null
+++ b/Modules/Compiler/ARMCC-ASM.cmake
@@ -0,0 +1,7 @@
+include(Compiler/ARMCC)
+
+set(CMAKE_ASM_OUTPUT_EXTENSION ".o")
+set(CMAKE_ASM_OUTPUT_EXTENSION_REPLACE 1)
+
+set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> <FLAGS> -o <OBJECT> <SOURCE>")
+set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS s;asm;msa)
diff --git a/Modules/Compiler/ARMCC-C.cmake b/Modules/Compiler/ARMCC-C.cmake
new file mode 100644
index 000000000..dcdcaab4a
--- /dev/null
+++ b/Modules/Compiler/ARMCC-C.cmake
@@ -0,0 +1,2 @@
+include(Compiler/ARMCC)
+__compiler_armcc(C)
diff --git a/Modules/Compiler/ARMCC-CXX.cmake b/Modules/Compiler/ARMCC-CXX.cmake
new file mode 100644
index 000000000..811fc93bd
--- /dev/null
+++ b/Modules/Compiler/ARMCC-CXX.cmake
@@ -0,0 +1,2 @@
+include(Compiler/ARMCC)
+__compiler_armcc(CXX)
diff --git a/Modules/Compiler/ARMCC-DetermineCompiler.cmake b/Modules/Compiler/ARMCC-DetermineCompiler.cmake
new file mode 100644
index 000000000..a3667d7c2
--- /dev/null
+++ b/Modules/Compiler/ARMCC-DetermineCompiler.cmake
@@ -0,0 +1,16 @@
+# ARMCC Toolchain
+set(_compiler_id_pp_test "defined(__ARMCC_VERSION)")
+
+set(_compiler_id_version_compute "
+#if __ARMCC_VERSION >= 1000000
+ /* __ARMCC_VERSION = VRRPPPP */
+ # define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__ARMCC_VERSION/1000000)
+ # define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__ARMCC_VERSION/10000 % 100)
+ # define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__ARMCC_VERSION % 10000)
+#else
+ /* __ARMCC_VERSION = VRPPPP */
+ # define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__ARMCC_VERSION/100000)
+ # define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__ARMCC_VERSION/10000 % 10)
+ # define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__ARMCC_VERSION % 10000)
+#endif
+")
diff --git a/Modules/Compiler/ARMCC.cmake b/Modules/Compiler/ARMCC.cmake
new file mode 100644
index 000000000..3cf628c0d
--- /dev/null
+++ b/Modules/Compiler/ARMCC.cmake
@@ -0,0 +1,36 @@
+if(_ARMCC_CMAKE_LOADED)
+ return()
+endif()
+set(_ARMCC_CMAKE_LOADED TRUE)
+
+# See ARM Compiler documentation at:
+# http://infocenter.arm.com/help/topic/com.arm.doc.set.swdev/index.html
+
+get_filename_component(_CMAKE_C_TOOLCHAIN_LOCATION "${CMAKE_C_COMPILER}" PATH)
+get_filename_component(_CMAKE_CXX_TOOLCHAIN_LOCATION "${CMAKE_CXX_COMPILER}" PATH)
+
+set(CMAKE_EXECUTABLE_SUFFIX ".elf")
+
+find_program(CMAKE_ARMCC_LINKER armlink HINTS "${_CMAKE_C_TOOLCHAIN_LOCATION}" "${_CMAKE_CXX_TOOLCHAIN_LOCATION}" )
+find_program(CMAKE_ARMCC_AR armar HINTS "${_CMAKE_C_TOOLCHAIN_LOCATION}" "${_CMAKE_CXX_TOOLCHAIN_LOCATION}" )
+
+set(CMAKE_LINKER "${CMAKE_ARMCC_LINKER}" CACHE FILEPATH "The ARMCC linker" FORCE)
+mark_as_advanced(CMAKE_ARMCC_LINKER)
+set(CMAKE_AR "${CMAKE_ARMCC_AR}" CACHE FILEPATH "The ARMCC archiver" FORCE)
+mark_as_advanced(CMAKE_ARMCC_AR)
+
+macro(__compiler_armcc lang)
+ set(CMAKE_${lang}_FLAGS_INIT "")
+ set(CMAKE_${lang}_FLAGS_DEBUG_INIT "-g")
+ set(CMAKE_${lang}_FLAGS_MINSIZEREL_INIT "-Ospace -DNDEBUG")
+ set(CMAKE_${lang}_FLAGS_RELEASE_INIT "-Otime -DNDEBUG")
+ set(CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT "-O2 -g")
+
+ set(CMAKE_${lang}_OUTPUT_EXTENSION ".o")
+ set(CMAKE_${lang}_OUTPUT_EXTENSION_REPLACE 1)
+
+ set(CMAKE_${lang}_LINK_EXECUTABLE "<CMAKE_LINKER> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> <OBJECTS> -o <TARGET> --list <TARGET_BASE>.map")
+ set(CMAKE_${lang}_CREATE_STATIC_LIBRARY "<CMAKE_AR> --create -cr <TARGET> <LINK_FLAGS> <OBJECTS>")
+
+ set(CMAKE_DEPFILE_FLAGS_${lang} "--depend=<DEPFILE> --depend_single_line --no_depend_system_headers")
+endmacro()
diff --git a/Modules/Compiler/AppleClang-ASM.cmake b/Modules/Compiler/AppleClang-ASM.cmake
new file mode 100644
index 000000000..f52bde05e
--- /dev/null
+++ b/Modules/Compiler/AppleClang-ASM.cmake
@@ -0,0 +1 @@
+include(Compiler/Clang-ASM)
diff --git a/Modules/Compiler/AppleClang-C-FeatureTests.cmake b/Modules/Compiler/AppleClang-C-FeatureTests.cmake
new file mode 100644
index 000000000..e80b526f1
--- /dev/null
+++ b/Modules/Compiler/AppleClang-C-FeatureTests.cmake
@@ -0,0 +1,11 @@
+
+set(_cmake_oldestSupported "((__clang_major__ * 100) + __clang_minor__) >= 400")
+
+set(AppleClang_C11 "${_cmake_oldestSupported} && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L")
+set(_cmake_feature_test_c_static_assert "${AppleClang_C11}")
+set(AppleClang_C99 "${_cmake_oldestSupported} && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L")
+set(_cmake_feature_test_c_restrict "${AppleClang_C99}")
+set(_cmake_feature_test_c_variadic_macros "${AppleClang_C99}")
+
+set(AppleClang_C90 "${_cmake_oldestSupported}")
+set(_cmake_feature_test_c_function_prototypes "${AppleClang_C90}")
diff --git a/Modules/Compiler/AppleClang-C.cmake b/Modules/Compiler/AppleClang-C.cmake
new file mode 100644
index 000000000..1cc72c0e5
--- /dev/null
+++ b/Modules/Compiler/AppleClang-C.cmake
@@ -0,0 +1,42 @@
+include(Compiler/Clang)
+__compiler_clang(C)
+
+if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.0)
+ set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90")
+ set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90")
+
+ set(CMAKE_C99_STANDARD_COMPILE_OPTION "-std=c99")
+ set(CMAKE_C99_EXTENSION_COMPILE_OPTION "-std=gnu99")
+
+ set(CMAKE_C11_STANDARD_COMPILE_OPTION "-std=c11")
+ set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu11")
+endif()
+
+if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.0)
+ if (NOT CMAKE_C_COMPILER_FORCED)
+ if (NOT CMAKE_C_STANDARD_COMPUTED_DEFAULT)
+ message(FATAL_ERROR "CMAKE_C_STANDARD_COMPUTED_DEFAULT should be set for ${CMAKE_C_COMPILER_ID} (${CMAKE_C_COMPILER}) version ${CMAKE_C_COMPILER_VERSION}")
+ endif()
+ set(CMAKE_C_STANDARD_DEFAULT ${CMAKE_C_STANDARD_COMPUTED_DEFAULT})
+ elseif(NOT DEFINED CMAKE_C_STANDARD_DEFAULT)
+ # Compiler id was forced so just guess the default standard level.
+ set(CMAKE_C_STANDARD_DEFAULT 99)
+ endif()
+endif()
+
+macro(cmake_record_c_compile_features)
+ macro(_get_appleclang_features std_version list)
+ record_compiler_features(C "${std_version}" ${list})
+ endmacro()
+
+ set(_result 0)
+ if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.0)
+ _get_appleclang_features(${CMAKE_C11_STANDARD_COMPILE_OPTION} CMAKE_C11_COMPILE_FEATURES)
+ if (_result EQUAL 0)
+ _get_appleclang_features(${CMAKE_C99_STANDARD_COMPILE_OPTION} CMAKE_C99_COMPILE_FEATURES)
+ endif()
+ if (_result EQUAL 0)
+ _get_appleclang_features(${CMAKE_C90_STANDARD_COMPILE_OPTION} CMAKE_C90_COMPILE_FEATURES)
+ endif()
+ endif()
+endmacro()
diff --git a/Modules/Compiler/AppleClang-CXX-FeatureTests.cmake b/Modules/Compiler/AppleClang-CXX-FeatureTests.cmake
new file mode 100644
index 000000000..f67082c6a
--- /dev/null
+++ b/Modules/Compiler/AppleClang-CXX-FeatureTests.cmake
@@ -0,0 +1,52 @@
+
+# No known reference for AppleClang versions.
+# Generic reference: http://clang.llvm.org/cxx_status.html
+# http://clang.llvm.org/docs/LanguageExtensions.html
+
+# Note: CXX compiler in Xcode 4.3 does not set __apple_build_version__ and so is
+# not recognized as AppleClang.
+# Xcode_43 - Apple clang version 3.1 (tags/Apple/clang-318.0.61) (based on LLVM 3.1svn)
+# Xcode_44 - Apple clang version 4.0 (tags/Apple/clang-421.0.60) (based on LLVM 3.1svn)
+# Xcode_45 - Apple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn)
+# Xcode_46 - Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)
+# Xcode_50 - Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
+# Xcode_51 - Apple LLVM version 5.1 (clang-503.0.38) (based on LLVM 3.4svn)
+# Xcode_60 - Apple LLVM version 6.0 (clang-600.0.51) (based on LLVM 3.5svn)
+# Xcode_61 - Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
+
+# There is some non-correspondance. __has_feature(cxx_user_literals) is
+# false for AppleClang 4.0 and 4.1, although it is reported as
+# supported in the reference link for Clang 3.1. The compiler does not pass
+# the CompileFeatures/cxx_user_literals.cpp test.
+# cxx_attributes is listed as not supported until Clang 3.3. It works without
+# warning with AppleClang 5.0, but issues a gcc-compat warning for
+# AppleClang 4.0-4.2.
+# cxx_alignof and cxx_alignas tests work for early AppleClang versions, though
+# they are listed as supported for Clang 3.3 and later.
+
+set(_cmake_oldestSupported "((__clang_major__ * 100) + __clang_minor__) >= 400")
+
+include("${CMAKE_CURRENT_LIST_DIR}/Clang-CXX-TestableFeatures.cmake")
+
+set(AppleClang51_CXX14 "((__clang_major__ * 100) + __clang_minor__) >= 501 && __cplusplus > 201103L")
+# http://llvm.org/bugs/show_bug.cgi?id=19242
+set(_cmake_feature_test_cxx_attribute_deprecated "${AppleClang51_CXX14}")
+# http://llvm.org/bugs/show_bug.cgi?id=19698
+set(_cmake_feature_test_cxx_decltype_auto "${AppleClang51_CXX14}")
+set(_cmake_feature_test_cxx_digit_separators "${AppleClang51_CXX14}")
+# http://llvm.org/bugs/show_bug.cgi?id=19674
+set(_cmake_feature_test_cxx_generic_lambdas "${AppleClang51_CXX14}")
+
+set(AppleClang40_CXX11 "${_cmake_oldestSupported} && __cplusplus >= 201103L")
+set(_cmake_feature_test_cxx_enum_forward_declarations "${AppleClang40_CXX11}")
+set(_cmake_feature_test_cxx_sizeof_member "${AppleClang40_CXX11}")
+set(_cmake_feature_test_cxx_extended_friend_declarations "${AppleClang40_CXX11}")
+set(_cmake_feature_test_cxx_extern_templates "${AppleClang40_CXX11}")
+set(_cmake_feature_test_cxx_func_identifier "${AppleClang40_CXX11}")
+set(_cmake_feature_test_cxx_inline_namespaces "${AppleClang40_CXX11}")
+set(_cmake_feature_test_cxx_long_long_type "${AppleClang40_CXX11}")
+set(_cmake_feature_test_cxx_right_angle_brackets "${AppleClang40_CXX11}")
+set(_cmake_feature_test_cxx_variadic_macros "${AppleClang40_CXX11}")
+
+set(AppleClang_CXX98 "${_cmake_oldestSupported} && __cplusplus >= 199711L")
+set(_cmake_feature_test_cxx_template_template_parameters "${AppleClang_CXX98}")
diff --git a/Modules/Compiler/AppleClang-CXX.cmake b/Modules/Compiler/AppleClang-CXX.cmake
new file mode 100644
index 000000000..95bc79adc
--- /dev/null
+++ b/Modules/Compiler/AppleClang-CXX.cmake
@@ -0,0 +1,56 @@
+include(Compiler/Clang)
+__compiler_clang(CXX)
+
+if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
+ set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
+endif()
+
+if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.0)
+ set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "-std=c++98")
+ set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "-std=gnu++98")
+
+ set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++11")
+ set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++11")
+endif()
+
+if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.1)
+ set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++14")
+ set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++14")
+elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.1)
+ # AppleClang 5.0 knows this flag, but does not set a __cplusplus macro greater than 201103L
+ set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++1y")
+ set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++1y")
+endif()
+
+if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.0)
+ if (NOT CMAKE_CXX_COMPILER_FORCED)
+ if (NOT CMAKE_CXX_STANDARD_COMPUTED_DEFAULT)
+ message(FATAL_ERROR "CMAKE_CXX_STANDARD_COMPUTED_DEFAULT should be set for ${CMAKE_CXX_COMPILER_ID} (${CMAKE_CXX_COMPILER}) version ${CMAKE_CXX_COMPILER_VERSION}")
+ endif()
+ set(CMAKE_CXX_STANDARD_DEFAULT ${CMAKE_CXX_STANDARD_COMPUTED_DEFAULT})
+ elseif(NOT DEFINED CMAKE_CXX_STANDARD_DEFAULT)
+ # Compiler id was forced so just guess the default standard level.
+ set(CMAKE_CXX_STANDARD_DEFAULT 98)
+ endif()
+endif()
+
+
+macro(cmake_record_cxx_compile_features)
+ macro(_get_appleclang_features std_version list)
+ record_compiler_features(CXX "${std_version}" ${list})
+ endmacro()
+
+ set(_result 0)
+ if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.0)
+ set(_result 0)
+ if(CMAKE_CXX14_STANDARD_COMPILE_OPTION)
+ _get_appleclang_features(${CMAKE_CXX14_STANDARD_COMPILE_OPTION} CMAKE_CXX14_COMPILE_FEATURES)
+ endif()
+ if (_result EQUAL 0)
+ _get_appleclang_features(${CMAKE_CXX11_STANDARD_COMPILE_OPTION} CMAKE_CXX11_COMPILE_FEATURES)
+ endif()
+ if (_result EQUAL 0)
+ _get_appleclang_features(${CMAKE_CXX98_STANDARD_COMPILE_OPTION} CMAKE_CXX98_COMPILE_FEATURES)
+ endif()
+ endif()
+endmacro()
diff --git a/Modules/Compiler/AppleClang-DetermineCompiler.cmake b/Modules/Compiler/AppleClang-DetermineCompiler.cmake
new file mode 100644
index 000000000..397f95cbe
--- /dev/null
+++ b/Modules/Compiler/AppleClang-DetermineCompiler.cmake
@@ -0,0 +1,7 @@
+
+set(_compiler_id_pp_test "defined(__clang__) && defined(__apple_build_version__)")
+
+include("${CMAKE_CURRENT_LIST_DIR}/Clang-DetermineCompilerInternal.cmake")
+
+set(_compiler_id_version_compute "${_compiler_id_version_compute}
+# define @PREFIX@COMPILER_VERSION_TWEAK @MACRO_DEC@(__apple_build_version__)")
diff --git a/Modules/Compiler/Borland-DetermineCompiler.cmake b/Modules/Compiler/Borland-DetermineCompiler.cmake
new file mode 100644
index 000000000..ef3083b4d
--- /dev/null
+++ b/Modules/Compiler/Borland-DetermineCompiler.cmake
@@ -0,0 +1,7 @@
+
+set(_compiler_id_pp_test "defined(__BORLANDC__)")
+
+set(_compiler_id_version_compute "
+ /* __BORLANDC__ = 0xVRR */
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_HEX@(__BORLANDC__>>8)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_HEX@(__BORLANDC__ & 0xFF)")
diff --git a/Modules/Compiler/CCur-Fortran.cmake b/Modules/Compiler/CCur-Fortran.cmake
new file mode 100644
index 000000000..6ec06ae11
--- /dev/null
+++ b/Modules/Compiler/CCur-Fortran.cmake
@@ -0,0 +1 @@
+include(Compiler/GNU-Fortran)
diff --git a/Modules/Compiler/Clang-C-FeatureTests.cmake b/Modules/Compiler/Clang-C-FeatureTests.cmake
new file mode 100644
index 000000000..99c2252c8
--- /dev/null
+++ b/Modules/Compiler/Clang-C-FeatureTests.cmake
@@ -0,0 +1,11 @@
+
+set(_cmake_oldestSupported "((__clang_major__ * 100) + __clang_minor__) >= 304")
+
+set(Clang_C11 "${_cmake_oldestSupported} && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L")
+set(_cmake_feature_test_c_static_assert "${Clang_C11}")
+set(Clang_C99 "${_cmake_oldestSupported} && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L")
+set(_cmake_feature_test_c_restrict "${Clang_C99}")
+set(_cmake_feature_test_c_variadic_macros "${Clang_C99}")
+
+set(Clang_C90 "${_cmake_oldestSupported}")
+set(_cmake_feature_test_c_function_prototypes "${Clang_C90}")
diff --git a/Modules/Compiler/Clang-C.cmake b/Modules/Compiler/Clang-C.cmake
index 98fcd0b3f..d8b77430a 100644
--- a/Modules/Compiler/Clang-C.cmake
+++ b/Modules/Compiler/Clang-C.cmake
@@ -1,2 +1,51 @@
include(Compiler/Clang)
__compiler_clang(C)
+
+cmake_policy(GET CMP0025 appleClangPolicy)
+if(WIN32 OR (APPLE AND NOT appleClangPolicy STREQUAL NEW))
+ return()
+endif()
+
+if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4)
+ set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90")
+ set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90")
+
+ set(CMAKE_C99_STANDARD_COMPILE_OPTION "-std=c99")
+ set(CMAKE_C99_EXTENSION_COMPILE_OPTION "-std=gnu99")
+
+ set(CMAKE_C11_STANDARD_COMPILE_OPTION "-std=c11")
+ set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu11")
+endif()
+
+if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4)
+ if (NOT CMAKE_C_COMPILER_FORCED)
+ if (NOT CMAKE_C_STANDARD_COMPUTED_DEFAULT)
+ message(FATAL_ERROR "CMAKE_C_STANDARD_COMPUTED_DEFAULT should be set for ${CMAKE_C_COMPILER_ID} (${CMAKE_C_COMPILER}) version ${CMAKE_C_COMPILER_VERSION}")
+ endif()
+ set(CMAKE_C_STANDARD_DEFAULT ${CMAKE_C_STANDARD_COMPUTED_DEFAULT})
+ elseif(NOT DEFINED CMAKE_C_STANDARD_DEFAULT)
+ # Compiler id was forced so just guess the default standard level.
+ if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.6)
+ set(CMAKE_C_STANDARD_DEFAULT 11)
+ else()
+ set(CMAKE_C_STANDARD_DEFAULT 99)
+ endif()
+ endif()
+endif()
+
+macro(cmake_record_c_compile_features)
+ macro(_get_clang_features std_version list)
+ record_compiler_features(C "${std_version}" ${list})
+ endmacro()
+
+ set(_result 0)
+ if (UNIX AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4)
+ _get_clang_features(${CMAKE_C11_STANDARD_COMPILE_OPTION} CMAKE_C11_COMPILE_FEATURES)
+ if (_result EQUAL 0)
+ _get_clang_features(${CMAKE_C99_STANDARD_COMPILE_OPTION} CMAKE_C99_COMPILE_FEATURES)
+ endif()
+ if (_result EQUAL 0)
+ _get_clang_features(${CMAKE_C90_STANDARD_COMPILE_OPTION} CMAKE_C90_COMPILE_FEATURES)
+ endif()
+ endif()
+endmacro()
diff --git a/Modules/Compiler/Clang-CXX-FeatureTests.cmake b/Modules/Compiler/Clang-CXX-FeatureTests.cmake
new file mode 100644
index 000000000..df2e1a8e0
--- /dev/null
+++ b/Modules/Compiler/Clang-CXX-FeatureTests.cmake
@@ -0,0 +1,34 @@
+
+# Reference: http://clang.llvm.org/cxx_status.html
+# http://clang.llvm.org/docs/LanguageExtensions.html
+
+set(_cmake_oldestSupported "((__clang_major__ * 100) + __clang_minor__) >= 304")
+
+include("${CMAKE_CURRENT_LIST_DIR}/Clang-CXX-TestableFeatures.cmake")
+
+set(Clang34_CXX14 "((__clang_major__ * 100) + __clang_minor__) >= 304 && __cplusplus > 201103L")
+# http://llvm.org/bugs/show_bug.cgi?id=19242
+set(_cmake_feature_test_cxx_attribute_deprecated "${Clang34_CXX14}")
+# http://llvm.org/bugs/show_bug.cgi?id=19698
+set(_cmake_feature_test_cxx_decltype_auto "${Clang34_CXX14}")
+set(_cmake_feature_test_cxx_digit_separators "${Clang34_CXX14}")
+# http://llvm.org/bugs/show_bug.cgi?id=19674
+set(_cmake_feature_test_cxx_generic_lambdas "${Clang34_CXX14}")
+
+# TODO: Should be supported by Clang 3.1
+set(Clang31_CXX11 "${_cmake_oldestSupported} && __cplusplus >= 201103L")
+set(_cmake_feature_test_cxx_enum_forward_declarations "${Clang31_CXX11}")
+set(_cmake_feature_test_cxx_sizeof_member "${Clang31_CXX11}")
+# TODO: Should be supported by Clang 2.9
+set(Clang29_CXX11 "${_cmake_oldestSupported} && __cplusplus >= 201103L")
+set(_cmake_feature_test_cxx_extended_friend_declarations "${Clang29_CXX11}")
+set(_cmake_feature_test_cxx_extern_templates "${Clang29_CXX11}")
+set(_cmake_feature_test_cxx_func_identifier "${Clang29_CXX11}")
+set(_cmake_feature_test_cxx_inline_namespaces "${Clang29_CXX11}")
+set(_cmake_feature_test_cxx_long_long_type "${Clang29_CXX11}")
+set(_cmake_feature_test_cxx_right_angle_brackets "${Clang29_CXX11}")
+set(_cmake_feature_test_cxx_variadic_macros "${Clang29_CXX11}")
+
+# TODO: Should be supported forever?
+set(Clang_CXX98 "${_cmake_oldestSupported} && __cplusplus >= 199711L")
+set(_cmake_feature_test_cxx_template_template_parameters "${Clang_CXX98}")
diff --git a/Modules/Compiler/Clang-CXX-TestableFeatures.cmake b/Modules/Compiler/Clang-CXX-TestableFeatures.cmake
new file mode 100644
index 000000000..b39475ce4
--- /dev/null
+++ b/Modules/Compiler/Clang-CXX-TestableFeatures.cmake
@@ -0,0 +1,54 @@
+
+set(testable_features
+ cxx_alias_templates
+ cxx_alignas
+ cxx_attributes
+ cxx_auto_type
+ cxx_binary_literals
+ cxx_constexpr
+ cxx_contextual_conversions
+ cxx_decltype
+ cxx_decltype_incomplete_return_types
+ cxx_default_function_template_args
+ cxx_defaulted_functions
+ cxx_delegating_constructors
+ cxx_deleted_functions
+ cxx_explicit_conversions
+ cxx_generalized_initializers
+ cxx_inheriting_constructors
+ cxx_lambdas
+ cxx_local_type_template_args
+ cxx_noexcept
+ cxx_nonstatic_member_init
+ cxx_nullptr
+ cxx_range_for
+ cxx_raw_string_literals
+ cxx_reference_qualified_functions
+ cxx_relaxed_constexpr
+ cxx_return_type_deduction
+ cxx_rvalue_references
+ cxx_static_assert
+ cxx_strong_enums
+ cxx_thread_local
+ cxx_unicode_literals
+ cxx_unrestricted_unions
+ cxx_user_literals
+ cxx_variable_templates
+ cxx_variadic_templates
+)
+
+foreach(feature ${testable_features})
+ set(_cmake_feature_test_${feature} "${_cmake_oldestSupported} && __has_feature(${feature})")
+endforeach()
+
+unset(testable_features)
+
+set(_cmake_feature_test_cxx_aggregate_default_initializers "${_cmake_oldestSupported} && __has_feature(cxx_aggregate_nsdmi)")
+
+set(_cmake_feature_test_cxx_trailing_return_types "${_cmake_oldestSupported} && __has_feature(cxx_trailing_return)")
+set(_cmake_feature_test_cxx_alignof "${_cmake_oldestSupported} && __has_feature(cxx_alignas)")
+set(_cmake_feature_test_cxx_final "${_cmake_oldestSupported} && __has_feature(cxx_override_control)")
+set(_cmake_feature_test_cxx_override "${_cmake_oldestSupported} && __has_feature(cxx_override_control)")
+set(_cmake_feature_test_cxx_uniform_initialization "${_cmake_oldestSupported} && __has_feature(cxx_generalized_initializers)")
+set(_cmake_feature_test_cxx_defaulted_move_initializers "${_cmake_oldestSupported} && __has_feature(cxx_defaulted_functions)")
+set(_cmake_feature_test_cxx_lambda_init_captures "${_cmake_oldestSupported} && __has_feature(cxx_init_captures)")
diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake
index 972d889aa..dc6271198 100644
--- a/Modules/Compiler/Clang-CXX.cmake
+++ b/Modules/Compiler/Clang-CXX.cmake
@@ -1,4 +1,61 @@
include(Compiler/Clang)
__compiler_clang(CXX)
-set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
+if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
+ set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
+endif()
+
+cmake_policy(GET CMP0025 appleClangPolicy)
+if(APPLE AND NOT appleClangPolicy STREQUAL NEW)
+ return()
+endif()
+
+if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 2.1)
+ set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "-std=c++98")
+ set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "-std=gnu++98")
+endif()
+
+if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.1)
+ set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++11")
+ set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++11")
+elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 2.1)
+ set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++0x")
+ set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++0x")
+endif()
+
+if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5)
+ set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++14")
+ set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++14")
+elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4)
+ set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++1y")
+ set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++1y")
+endif()
+
+if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4)
+ if (NOT CMAKE_CXX_COMPILER_FORCED)
+ if (NOT CMAKE_CXX_STANDARD_COMPUTED_DEFAULT)
+ message(FATAL_ERROR "CMAKE_CXX_STANDARD_COMPUTED_DEFAULT should be set for ${CMAKE_CXX_COMPILER_ID} (${CMAKE_CXX_COMPILER}) version ${CMAKE_CXX_COMPILER_VERSION}")
+ endif()
+ set(CMAKE_CXX_STANDARD_DEFAULT ${CMAKE_CXX_STANDARD_COMPUTED_DEFAULT})
+ elseif(NOT DEFINED CMAKE_CXX_STANDARD_DEFAULT)
+ # Compiler id was forced so just guess the default standard level.
+ set(CMAKE_CXX_STANDARD_DEFAULT 98)
+ endif()
+endif()
+
+macro(cmake_record_cxx_compile_features)
+ macro(_get_clang_features std_version list)
+ record_compiler_features(CXX "${std_version}" ${list})
+ endmacro()
+
+ set(_result 0)
+ if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4)
+ _get_clang_features(${CMAKE_CXX14_STANDARD_COMPILE_OPTION} CMAKE_CXX14_COMPILE_FEATURES)
+ if (_result EQUAL 0)
+ _get_clang_features(${CMAKE_CXX11_STANDARD_COMPILE_OPTION} CMAKE_CXX11_COMPILE_FEATURES)
+ endif()
+ if (_result EQUAL 0)
+ _get_clang_features(${CMAKE_CXX98_STANDARD_COMPILE_OPTION} CMAKE_CXX98_COMPILE_FEATURES)
+ endif()
+ endif()
+endmacro()
diff --git a/Modules/Compiler/Clang-DetermineCompiler.cmake b/Modules/Compiler/Clang-DetermineCompiler.cmake
new file mode 100644
index 000000000..89df1b6dc
--- /dev/null
+++ b/Modules/Compiler/Clang-DetermineCompiler.cmake
@@ -0,0 +1,4 @@
+
+set(_compiler_id_pp_test "defined(__clang__)")
+
+include("${CMAKE_CURRENT_LIST_DIR}/Clang-DetermineCompilerInternal.cmake")
diff --git a/Modules/Compiler/Clang-DetermineCompilerInternal.cmake b/Modules/Compiler/Clang-DetermineCompilerInternal.cmake
new file mode 100644
index 000000000..08c12305d
--- /dev/null
+++ b/Modules/Compiler/Clang-DetermineCompilerInternal.cmake
@@ -0,0 +1,15 @@
+
+set(_compiler_id_version_compute "
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__clang_major__)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__clang_minor__)
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__clang_patchlevel__)
+# if defined(_MSC_VER)
+ /* _MSC_VER = VVRR */
+# define @PREFIX@SIMULATE_VERSION_MAJOR @MACRO_DEC@(_MSC_VER / 100)
+# define @PREFIX@SIMULATE_VERSION_MINOR @MACRO_DEC@(_MSC_VER % 100)
+# endif")
+
+set(_compiler_id_simulate "
+# if defined(_MSC_VER)
+# define @PREFIX@SIMULATE_ID \"MSVC\"
+# endif")
diff --git a/Modules/Compiler/Clang.cmake b/Modules/Compiler/Clang.cmake
index ec4562a3d..701089cbf 100644
--- a/Modules/Compiler/Clang.cmake
+++ b/Modules/Compiler/Clang.cmake
@@ -18,11 +18,24 @@ if(__COMPILER_CLANG)
endif()
set(__COMPILER_CLANG 1)
-include(Compiler/GNU)
+if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC"
+ OR "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
+ macro(__compiler_clang lang)
+ endmacro()
+else()
+ include(Compiler/GNU)
-macro(__compiler_clang lang)
- __compiler_gnu(${lang})
- set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE")
- set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ")
- set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY "-fvisibility=")
-endmacro()
+ macro(__compiler_clang lang)
+ __compiler_gnu(${lang})
+ set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE")
+ set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ")
+ set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY "-fvisibility=")
+ if(CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.4.0)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_TARGET "-target ")
+ set(CMAKE_${lang}_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN "-gcc-toolchain ")
+ else()
+ set(CMAKE_${lang}_COMPILE_OPTIONS_TARGET "--target=")
+ set(CMAKE_${lang}_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN "--gcc-toolchain=")
+ endif()
+ endmacro()
+endif()
diff --git a/Modules/Compiler/Comeau-CXX-DetermineCompiler.cmake b/Modules/Compiler/Comeau-CXX-DetermineCompiler.cmake
new file mode 100644
index 000000000..2265e5ea8
--- /dev/null
+++ b/Modules/Compiler/Comeau-CXX-DetermineCompiler.cmake
@@ -0,0 +1,7 @@
+
+set(_compiler_id_pp_test "defined(__COMO__)")
+
+set(_compiler_id_version_compute "
+ /* __COMO_VERSION__ = VRR */
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__COMO_VERSION__ / 100)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__COMO_VERSION__ % 100)")
diff --git a/Modules/Compiler/Compaq-C-DetermineCompiler.cmake b/Modules/Compiler/Compaq-C-DetermineCompiler.cmake
new file mode 100644
index 000000000..02e99dca0
--- /dev/null
+++ b/Modules/Compiler/Compaq-C-DetermineCompiler.cmake
@@ -0,0 +1,8 @@
+
+set(_compiler_id_pp_test "defined(__DECC)")
+
+set(_compiler_id_version_compute "
+ /* __DECC_VER = VVRRTPPPP */
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__DECC_VER/10000000)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__DECC_VER/100000 % 100)
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__DECC_VER % 10000)")
diff --git a/Modules/Compiler/Compaq-CXX-DetermineCompiler.cmake b/Modules/Compiler/Compaq-CXX-DetermineCompiler.cmake
new file mode 100644
index 000000000..c7d0565ce
--- /dev/null
+++ b/Modules/Compiler/Compaq-CXX-DetermineCompiler.cmake
@@ -0,0 +1,8 @@
+
+set(_compiler_id_pp_test "defined(__DECCXX)")
+
+set(_compiler_id_version_compute "
+ /* __DECCXX_VER = VVRRTPPPP */
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__DECCXX_VER/10000000)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__DECCXX_VER/100000 % 100)
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__DECCXX_VER % 10000)")
diff --git a/Modules/Compiler/Cray-DetermineCompiler.cmake b/Modules/Compiler/Cray-DetermineCompiler.cmake
new file mode 100644
index 000000000..660229425
--- /dev/null
+++ b/Modules/Compiler/Cray-DetermineCompiler.cmake
@@ -0,0 +1,6 @@
+
+set(_compiler_id_pp_test "defined(_CRAYC)")
+
+set(_compiler_id_version_compute "
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(_RELEASE_MAJOR)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(_RELEASE_MINOR)")
diff --git a/Modules/Compiler/CrayPrgEnv-C.cmake b/Modules/Compiler/CrayPrgEnv-C.cmake
new file mode 100644
index 000000000..6b461ce06
--- /dev/null
+++ b/Modules/Compiler/CrayPrgEnv-C.cmake
@@ -0,0 +1,11 @@
+if(__craylinux_crayprgenv_c)
+ return()
+endif()
+set(__craylinux_crayprgenv_c 1)
+
+include(Compiler/CrayPrgEnv)
+macro(__CrayPrgEnv_setup_C compiler_cmd link_cmd)
+ __CrayPrgEnv_setup(C
+ ${CMAKE_ROOT}/Modules/CMakeCCompilerABI.c
+ ${compiler_cmd} ${link_cmd})
+endmacro()
diff --git a/Modules/Compiler/CrayPrgEnv-CXX.cmake b/Modules/Compiler/CrayPrgEnv-CXX.cmake
new file mode 100644
index 000000000..aad85b67e
--- /dev/null
+++ b/Modules/Compiler/CrayPrgEnv-CXX.cmake
@@ -0,0 +1,11 @@
+if(__craylinux_crayprgenv_cxx)
+ return()
+endif()
+set(__craylinux_crayprgenv_cxx 1)
+
+include(Compiler/CrayPrgEnv)
+macro(__CrayPrgEnv_setup_CXX compiler_cmd link_cmd)
+ __CrayPrgEnv_setup(CXX
+ ${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp
+ ${compiler_cmd} ${link_cmd})
+endmacro()
diff --git a/Modules/Compiler/CrayPrgEnv-Cray-C.cmake b/Modules/Compiler/CrayPrgEnv-Cray-C.cmake
new file mode 100644
index 000000000..547a4b4d5
--- /dev/null
+++ b/Modules/Compiler/CrayPrgEnv-Cray-C.cmake
@@ -0,0 +1,7 @@
+if(__craylinux_crayprgenv_cray_c)
+ return()
+endif()
+set(__craylinux_crayprgenv_cray_c 1)
+
+include(Compiler/CrayPrgEnv-C)
+__CrayPrgEnv_setup_C("/opt/cray/cce/.*/ccfe" "/opt/cray/cce/.*/ld")
diff --git a/Modules/Compiler/CrayPrgEnv-Cray-CXX.cmake b/Modules/Compiler/CrayPrgEnv-Cray-CXX.cmake
new file mode 100644
index 000000000..df8452c15
--- /dev/null
+++ b/Modules/Compiler/CrayPrgEnv-Cray-CXX.cmake
@@ -0,0 +1,7 @@
+if(__craylinux_crayprgenv_cray_cxx)
+ return()
+endif()
+set(__craylinux_crayprgenv_cray_cxx 1)
+
+include(Compiler/CrayPrgEnv-CXX)
+__CrayPrgEnv_setup_CXX("/opt/cray/cce/.*/ccfe" "/opt/cray/cce/.*/ld")
diff --git a/Modules/Compiler/CrayPrgEnv-Cray-Fortran.cmake b/Modules/Compiler/CrayPrgEnv-Cray-Fortran.cmake
new file mode 100644
index 000000000..9f46a04c8
--- /dev/null
+++ b/Modules/Compiler/CrayPrgEnv-Cray-Fortran.cmake
@@ -0,0 +1,7 @@
+if(__craylinux_crayprgenv_cray_fortran)
+ return()
+endif()
+set(__craylinux_crayprgenv_cray_fortran 1)
+
+include(Compiler/CrayPrgEnv-Fortran)
+__CrayPrgEnv_setup_Fortran("/opt/cray/cce/.*/ftnfe" "/opt/cray/cce/.*/ld")
diff --git a/Modules/Compiler/CrayPrgEnv-Fortran.cmake b/Modules/Compiler/CrayPrgEnv-Fortran.cmake
new file mode 100644
index 000000000..9c4d2694a
--- /dev/null
+++ b/Modules/Compiler/CrayPrgEnv-Fortran.cmake
@@ -0,0 +1,11 @@
+if(__craylinux_crayprgenv_fortran)
+ return()
+endif()
+set(__craylinux_crayprgenv_fortran 1)
+
+include(Compiler/CrayPrgEnv)
+macro(__CrayPrgEnv_setup_Fortran compiler_cmd link_cmd)
+ __CrayPrgEnv_setup(Fortran
+ ${CMAKE_ROOT}/Modules/CMakeFortranCompilerABI.F
+ ${compiler_cmd} ${link_cmd})
+endmacro()
diff --git a/Modules/Compiler/CrayPrgEnv-GNU-C.cmake b/Modules/Compiler/CrayPrgEnv-GNU-C.cmake
new file mode 100644
index 000000000..248081b87
--- /dev/null
+++ b/Modules/Compiler/CrayPrgEnv-GNU-C.cmake
@@ -0,0 +1,7 @@
+if(__craylinux_crayprgenv_gnu_c)
+ return()
+endif()
+set(__craylinux_crayprgenv_gnu_c 1)
+
+include(Compiler/CrayPrgEnv-C)
+__CrayPrgEnv_setup_C("/opt/gcc/.*/cc1" "/opt/gcc/.*/collect2")
diff --git a/Modules/Compiler/CrayPrgEnv-GNU-CXX.cmake b/Modules/Compiler/CrayPrgEnv-GNU-CXX.cmake
new file mode 100644
index 000000000..be4eb6d54
--- /dev/null
+++ b/Modules/Compiler/CrayPrgEnv-GNU-CXX.cmake
@@ -0,0 +1,7 @@
+if(__craylinux_crayprgenv_gnu_cxx)
+ return()
+endif()
+set(__craylinux_crayprgenv_gnu_cxx 1)
+
+include(Compiler/CrayPrgEnv-CXX)
+__CrayPrgEnv_setup_CXX("/opt/gcc/.*/cc1plus" "/opt/gcc/.*/collect2")
diff --git a/Modules/Compiler/CrayPrgEnv-GNU-Fortran.cmake b/Modules/Compiler/CrayPrgEnv-GNU-Fortran.cmake
new file mode 100644
index 000000000..8bd23ff88
--- /dev/null
+++ b/Modules/Compiler/CrayPrgEnv-GNU-Fortran.cmake
@@ -0,0 +1,7 @@
+if(__craylinux_crayprgenv_gnu_fortran)
+ return()
+endif()
+set(__craylinux_crayprgenv_gnu_fortran 1)
+
+include(Compiler/CrayPrgEnv-Fortran)
+__CrayPrgEnv_setup_Fortran("/opt/gcc/.*/f951" "/opt/gcc/.*/collect2")
diff --git a/Modules/Compiler/CrayPrgEnv-Intel-C.cmake b/Modules/Compiler/CrayPrgEnv-Intel-C.cmake
new file mode 100644
index 000000000..83c4e3801
--- /dev/null
+++ b/Modules/Compiler/CrayPrgEnv-Intel-C.cmake
@@ -0,0 +1,7 @@
+if(__craylinux_crayprgenv_intel_c)
+ return()
+endif()
+set(__craylinux_crayprgenv_intel_c 1)
+
+include(Compiler/CrayPrgEnv-C)
+__CrayPrgEnv_setup_C("/opt/intel/.*/mcpcom" "^ld ")
diff --git a/Modules/Compiler/CrayPrgEnv-Intel-CXX.cmake b/Modules/Compiler/CrayPrgEnv-Intel-CXX.cmake
new file mode 100644
index 000000000..3c3c3e63f
--- /dev/null
+++ b/Modules/Compiler/CrayPrgEnv-Intel-CXX.cmake
@@ -0,0 +1,7 @@
+if(__craylinux_crayprgenv_intel_cxx)
+ return()
+endif()
+set(__craylinux_crayprgenv_intel_cxx 1)
+
+include(Compiler/CrayPrgEnv-CXX)
+__CrayPrgEnv_setup_CXX("/opt/intel/.*/mcpcom" "^ld ")
diff --git a/Modules/Compiler/CrayPrgEnv-Intel-Fortran.cmake b/Modules/Compiler/CrayPrgEnv-Intel-Fortran.cmake
new file mode 100644
index 000000000..08a316d2c
--- /dev/null
+++ b/Modules/Compiler/CrayPrgEnv-Intel-Fortran.cmake
@@ -0,0 +1,7 @@
+if(__craylinux_crayprgenv_intel_fortran)
+ return()
+endif()
+set(__craylinux_crayprgenv_intel_fortran 1)
+
+include(Compiler/CrayPrgEnv-Fortran)
+__CrayPrgEnv_setup_Fortran("/opt/intel/.*/fortcom" "^ld ")
diff --git a/Modules/Compiler/CrayPrgEnv-PGI-C.cmake b/Modules/Compiler/CrayPrgEnv-PGI-C.cmake
new file mode 100644
index 000000000..f45767caf
--- /dev/null
+++ b/Modules/Compiler/CrayPrgEnv-PGI-C.cmake
@@ -0,0 +1,7 @@
+if(__craylinux_crayprgenv_pgi_c)
+ return()
+endif()
+set(__craylinux_crayprgenv_pgi_c 1)
+
+include(Compiler/CrayPrgEnv-C)
+__CrayPrgEnv_setup_C("/opt/pgi/[^ ]*/pgc" "/usr/bin/ld")
diff --git a/Modules/Compiler/CrayPrgEnv-PGI-CXX.cmake b/Modules/Compiler/CrayPrgEnv-PGI-CXX.cmake
new file mode 100644
index 000000000..a2a286f8c
--- /dev/null
+++ b/Modules/Compiler/CrayPrgEnv-PGI-CXX.cmake
@@ -0,0 +1,7 @@
+if(__craylinux_crayprgenv_pgi_cxx)
+ return()
+endif()
+set(__craylinux_crayprgenv_pgi_cxx 1)
+
+include(Compiler/CrayPrgEnv-CXX)
+__CrayPrgEnv_setup_CXX("/opt/pgi/[^ ]*/pgcpp" "/usr/bin/ld")
diff --git a/Modules/Compiler/CrayPrgEnv-PGI-Fortran.cmake b/Modules/Compiler/CrayPrgEnv-PGI-Fortran.cmake
new file mode 100644
index 000000000..f6ba7c0fa
--- /dev/null
+++ b/Modules/Compiler/CrayPrgEnv-PGI-Fortran.cmake
@@ -0,0 +1,7 @@
+if(__craylinux_crayprgenv_pgi_fortran)
+ return()
+endif()
+set(__craylinux_crayprgenv_pgi_fortran 1)
+
+include(Compiler/CrayPrgEnv-Fortran)
+__CrayPrgEnv_setup_Fortran("/opt/pgi/[^ ]*/pgf" "/usr/bin/ld")
diff --git a/Modules/Compiler/CrayPrgEnv.cmake b/Modules/Compiler/CrayPrgEnv.cmake
new file mode 100644
index 000000000..fa39b009a
--- /dev/null
+++ b/Modules/Compiler/CrayPrgEnv.cmake
@@ -0,0 +1,91 @@
+# Guard against multiple inclusions
+if(__craylinux_crayprgenv)
+ return()
+endif()
+set(__craylinux_crayprgenv 1)
+
+macro(__cray_extract_args cmd tag_regex out_var make_absolute)
+ string(REGEX MATCHALL "${tag_regex}" args "${cmd}")
+ foreach(arg IN LISTS args)
+ string(REGEX REPLACE "^${tag_regex}$" "\\2" param "${arg}")
+ if(make_absolute)
+ get_filename_component(param "${param}" ABSOLUTE)
+ endif()
+ list(APPEND ${out_var} ${param})
+ endforeach()
+endmacro()
+
+function(__cray_extract_implicit src compiler_cmd link_cmd lang include_dirs_var link_dirs_var link_libs_var)
+ set(BIN "${CMAKE_PLATFORM_INFO_DIR}/CrayExtractImplicit_${lang}.bin")
+ execute_process(
+ COMMAND ${CMAKE_${lang}_COMPILER} ${CMAKE_${lang}_VERBOSE_FLAG} -o ${BIN}
+ RESULT_VARIABLE result
+ OUTPUT_VARIABLE output
+ ERROR_VARIABLE error
+ )
+ if(EXISTS "${BIN}")
+ file(REMOVE "${BIN}")
+ endif()
+ set(include_dirs)
+ set(link_dirs)
+ set(link_libs)
+ string(REGEX REPLACE "\r?\n" ";" output_lines "${output}\n${error}")
+ foreach(line IN LISTS output_lines)
+ if("${line}" MATCHES "${compiler_cmd}")
+ __cray_extract_args("${line}" " -(I ?|isystem )([^ ]*)" include_dirs 1)
+ set(processed_include 1)
+ endif()
+ if("${line}" MATCHES "${link_cmd}")
+ __cray_extract_args("${line}" " -(L ?)([^ ]*)" link_dirs 1)
+ __cray_extract_args("${line}" " -(l ?)([^ ]*)" link_libs 0)
+ set(processed_link 1)
+ endif()
+ if(processed_include AND processed_link)
+ break()
+ endif()
+ endforeach()
+
+ set(${include_dirs_var} "${include_dirs}" PARENT_SCOPE)
+ set(${link_dirs_var} "${link_dirs}" PARENT_SCOPE)
+ set(${link_libs_var} "${link_libs}" PARENT_SCOPE)
+ set(CRAY_${lang}_EXTRACTED_IMPLICIT 1 CACHE INTERNAL "" FORCE)
+endfunction()
+
+macro(__CrayPrgEnv_setup lang test_src compiler_cmd link_cmd)
+ if(DEFINED ENV{CRAYPE_VERSION})
+ message(STATUS "Cray Programming Environment $ENV{CRAYPE_VERSION} ${lang}")
+ elseif(DEFINED ENV{ASYNCPE_VERSION})
+ message(STATUS "Cray XT Programming Environment $ENV{ASYNCPE_VERSION} ${lang}")
+ endif()
+
+ # Flags for the Cray wrappers
+ set(CMAKE_STATIC_LIBRARY_LINK_${lang}_FLAGS "-static")
+ set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "")
+ set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared")
+ set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-dynamic")
+
+ # If the link type is not explicitly specified in the environment then
+ # the Cray wrappers assume that the code will be built staticly so
+ # we check the following condition(s) are NOT met
+ # Compiler flags are explicitly dynamic
+ # Env var is dynamic and compiler flags are not explicitly static
+ if(NOT (((CMAKE_${lang}_FLAGS MATCHES "(^| )-dynamic($| )") OR
+ (CMAKE_EXE_LINKER_FLAGS MATCHES "(^| )-dynamic($| )"))
+ OR
+ (("$ENV{CRAYPE_LINK_TYPE}" STREQUAL "dynamic") AND
+ NOT ((CMAKE_${lang}_FLAGS MATCHES "(^| )-static($| )") OR
+ (CMAKE_EXE_LINKER_FLAGS MATCHES "(^| )-static($| )")))))
+ set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
+ set(BUILD_SHARED_LIBS FALSE CACHE BOOL "")
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
+ set(CMAKE_LINK_SEARCH_START_STATIC TRUE)
+ endif()
+ if(NOT CRAY_${lang}_EXTRACTED_IMPLICIT)
+ __cray_extract_implicit(
+ ${test_src} ${compiler_cmd} ${link_cmd} ${lang}
+ CMAKE_${lang}_IMPLICIT_INCLUDE_DIRECTORIES
+ CMAKE_${lang}_IMPLICIT_LINK_DIRECTORIES
+ CMAKE_${lang}_IMPLICIT_LINK_LIBRARIES
+ )
+ endif()
+endmacro()
diff --git a/Modules/Compiler/Embarcadero-DetermineCompiler.cmake b/Modules/Compiler/Embarcadero-DetermineCompiler.cmake
new file mode 100644
index 000000000..8375624e9
--- /dev/null
+++ b/Modules/Compiler/Embarcadero-DetermineCompiler.cmake
@@ -0,0 +1,7 @@
+
+set(_compiler_id_pp_test "defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__)")
+
+set(_compiler_id_version_compute "
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_HEX@(__CODEGEARC_VERSION__>>24 & 0x00FF)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_HEX@(__CODEGEARC_VERSION__>>16 & 0x00FF)
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__CODEGEARC_VERSION__ & 0xFFFF)")
diff --git a/Modules/Compiler/Fujitsu-DetermineCompiler.cmake b/Modules/Compiler/Fujitsu-DetermineCompiler.cmake
new file mode 100644
index 000000000..73ee38c87
--- /dev/null
+++ b/Modules/Compiler/Fujitsu-DetermineCompiler.cmake
@@ -0,0 +1,2 @@
+
+set(_compiler_id_pp_test "defined(__FUJITSU) || defined(__FCC_VERSION) || defined(__fcc_version)")
diff --git a/Modules/Compiler/GHS-C.cmake b/Modules/Compiler/GHS-C.cmake
new file mode 100644
index 000000000..e97d62c22
--- /dev/null
+++ b/Modules/Compiler/GHS-C.cmake
@@ -0,0 +1,27 @@
+set(CMAKE_C_VERBOSE_FLAG "-v")
+
+set(CMAKE_C_FLAGS_INIT "")
+set(CMAKE_C_FLAGS_DEBUG_INIT "-Odebug -g")
+set(CMAKE_C_FLAGS_MINSIZEREL_INIT "-Ospace")
+set(CMAKE_C_FLAGS_RELEASE_INIT "-O")
+set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-O -g")
+
+set(CMAKE_C_GHS_KERNEL_FLAGS_DEBUG_INIT "-ldebug ${CMAKE_C_FLAGS_DEBUG_INIT}")
+set(CMAKE_C_GHS_KERNEL_FLAGS_MINSIZEREL_INIT "${CMAKE_C_FLAGS_MINSIZEREL_INIT}")
+set(CMAKE_C_GHS_KERNEL_FLAGS_RELEASE_INIT "${CMAKE_C_FLAGS_RELEASE_INIT}")
+set(CMAKE_C_GHS_KERNEL_FLAGS_RELWITHDEBINFO_INIT
+ "-ldebug ${CMAKE_C_FLAGS_RELWITHDEBINFO_INIT}")
+
+if(NOT CMAKE_NOT_USING_CONFIG_FLAGS)
+ set (CMAKE_C_GHS_KERNEL_FLAGS_DEBUG "${CMAKE_C_GHS_KERNEL_FLAGS_DEBUG_INIT}"
+ CACHE STRING "Kernel flags used by the compiler during debug builds.")
+ set (CMAKE_C_GHS_KERNEL_FLAGS_MINSIZEREL
+ "${CMAKE_C_GHS_KERNEL_FLAGS_MINSIZEREL_INIT}" CACHE STRING
+ "Kernel flags used by the compiler during release builds for minimum size.")
+ set (CMAKE_C_GHS_KERNEL_FLAGS_RELEASE
+ "${CMAKE_C_GHS_KERNEL_FLAGS_RELEASE_INIT}"
+ CACHE STRING "Kernel flags used by the compiler during release builds.")
+ set (CMAKE_C_GHS_KERNEL_FLAGS_RELWITHDEBINFO
+ "${CMAKE_C_GHS_KERNEL_FLAGS_RELWITHDEBINFO_INIT}" CACHE STRING
+ "Kernel flags used by the compiler during release builds with debug info.")
+endif()
diff --git a/Modules/Compiler/GHS-CXX.cmake b/Modules/Compiler/GHS-CXX.cmake
new file mode 100644
index 000000000..71a0dec78
--- /dev/null
+++ b/Modules/Compiler/GHS-CXX.cmake
@@ -0,0 +1,31 @@
+set(CMAKE_CXX_VERBOSE_FLAG "-v")
+
+set(CMAKE_CXX_FLAGS_INIT "")
+set(CMAKE_CXX_FLAGS_DEBUG_INIT "-Odebug -g")
+set(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "-Ospace")
+set(CMAKE_CXX_FLAGS_RELEASE_INIT "-O")
+set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-O -g")
+
+set(CMAKE_CXX_GHS_KERNEL_FLAGS_DEBUG_INIT
+ "-ldebug ${CMAKE_CXX_FLAGS_DEBUG_INIT}")
+set(CMAKE_CXX_GHS_KERNEL_FLAGS_MINSIZEREL_INIT
+ "${CMAKE_CXX_FLAGS_MINSIZEREL_INIT}")
+set(CMAKE_CXX_GHS_KERNEL_FLAGS_RELEASE_INIT
+ "${CMAKE_CXX_FLAGS_RELEASE_INIT}")
+set(CMAKE_CXX_GHS_KERNEL_FLAGS_RELWITHDEBINFO_INIT
+ "-ldebug ${CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT}")
+
+if(NOT CMAKE_NOT_USING_CONFIG_FLAGS)
+ set (CMAKE_CXX_GHS_KERNEL_FLAGS_DEBUG
+ "${CMAKE_CXX_GHS_KERNEL_FLAGS_DEBUG_INIT}"
+ CACHE STRING "Kernel flags used by the compiler during debug builds.")
+ set (CMAKE_CXX_GHS_KERNEL_FLAGS_MINSIZEREL
+ "${CMAKE_CXX_GHS_KERNEL_FLAGS_MINSIZEREL_INIT}" CACHE STRING
+ "Kernel flags used by the compiler during release builds for minimum size.")
+ set (CMAKE_CXX_GHS_KERNEL_FLAGS_RELEASE
+ "${CMAKE_CXX_GHS_KERNEL_FLAGS_RELEASE_INIT}"
+ CACHE STRING "Kernel flags used by the compiler during release builds.")
+ set (CMAKE_CXX_GHS_KERNEL_FLAGS_RELWITHDEBINFO
+ "${CMAKE_CXX_GHS_KERNEL_FLAGS_RELWITHDEBINFO_INIT}" CACHE STRING
+ "Kernel flags used by the compiler during release builds with debug info.")
+endif()
diff --git a/Modules/Compiler/GHS-DetermineCompiler.cmake b/Modules/Compiler/GHS-DetermineCompiler.cmake
new file mode 100644
index 000000000..56d24e266
--- /dev/null
+++ b/Modules/Compiler/GHS-DetermineCompiler.cmake
@@ -0,0 +1,6 @@
+set(_compiler_id_pp_test "defined(__INTEGRITY)")
+
+set(_compiler_id_version_compute "
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__INTEGRITY_MAJOR_VERSION)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__INTEGRITY_MINOR_VERSION)
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__INTEGRITY_PATCH_VERSION)")
diff --git a/Modules/Compiler/GNU-C-FeatureTests.cmake b/Modules/Compiler/GNU-C-FeatureTests.cmake
new file mode 100644
index 000000000..b3fe33f14
--- /dev/null
+++ b/Modules/Compiler/GNU-C-FeatureTests.cmake
@@ -0,0 +1,17 @@
+
+set(_cmake_oldestSupported "(__GNUC__ * 100 + __GNUC_MINOR__) >= 404")
+
+# GNU 4.7 correctly sets __STDC_VERSION__ to 201112L, but GNU 4.6 sets it
+# to 201000L. As the former is strictly greater than the latter, test only
+# for the latter. If in the future CMake learns about a C feature which was
+# introduced with GNU 4.7, that should test for the correct version, similar
+# to the distinction between __cplusplus and __GXX_EXPERIMENTAL_CXX0X__ tests.
+set(GNU46_C11 "(__GNUC__ * 100 + __GNUC_MINOR__) >= 406 && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201000L")
+set(_cmake_feature_test_c_static_assert "${GNU46_C11}")
+# Since 4.4 at least:
+set(GNU44_C99 "(__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L")
+set(_cmake_feature_test_c_restrict "${GNU44_C99}")
+set(_cmake_feature_test_c_variadic_macros "${GNU44_C99}")
+
+set(GNU_C90 "${_cmake_oldestSupported}")
+set(_cmake_feature_test_c_function_prototypes "${GNU_C90}")
diff --git a/Modules/Compiler/GNU-C.cmake b/Modules/Compiler/GNU-C.cmake
index 9a5137a4b..2c478da21 100644
--- a/Modules/Compiler/GNU-C.cmake
+++ b/Modules/Compiler/GNU-C.cmake
@@ -1,2 +1,59 @@
include(Compiler/GNU)
__compiler_gnu(C)
+
+if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.5)
+ set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90")
+ set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90")
+elseif (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.4)
+ set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c89")
+ set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu89")
+endif()
+
+if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.4)
+ set(CMAKE_C99_STANDARD_COMPILE_OPTION "-std=c99")
+ set(CMAKE_C99_EXTENSION_COMPILE_OPTION "-std=gnu99")
+endif()
+
+if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.7)
+ set(CMAKE_C11_STANDARD_COMPILE_OPTION "-std=c11")
+ set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu11")
+elseif (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.6)
+ set(CMAKE_C11_STANDARD_COMPILE_OPTION "-std=c1x")
+ set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu1x")
+endif()
+
+if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.4)
+ if (NOT CMAKE_C_COMPILER_FORCED)
+ if (NOT CMAKE_C_STANDARD_COMPUTED_DEFAULT)
+ message(FATAL_ERROR "CMAKE_C_STANDARD_COMPUTED_DEFAULT should be set for ${CMAKE_C_COMPILER_ID} (${CMAKE_C_COMPILER}) version ${CMAKE_C_COMPILER_VERSION}")
+ endif()
+ set(CMAKE_C_STANDARD_DEFAULT ${CMAKE_C_STANDARD_COMPUTED_DEFAULT})
+ elseif(NOT DEFINED CMAKE_C_STANDARD_DEFAULT)
+ # Compiler id was forced so just guess the default standard level.
+ if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0)
+ set(CMAKE_C_STANDARD_DEFAULT 11)
+ else()
+ set(CMAKE_C_STANDARD_DEFAULT 90)
+ endif()
+ endif()
+endif()
+
+
+macro(cmake_record_c_compile_features)
+ macro(_get_gcc_features std_version list)
+ record_compiler_features(C "${std_version}" ${list})
+ endmacro()
+
+ set(_result 0)
+ if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.6)
+ _get_gcc_features(${CMAKE_C11_STANDARD_COMPILE_OPTION} CMAKE_C11_COMPILE_FEATURES)
+ endif()
+ if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.4)
+ if (_result EQUAL 0)
+ _get_gcc_features(${CMAKE_C99_STANDARD_COMPILE_OPTION} CMAKE_C99_COMPILE_FEATURES)
+ endif()
+ if (_result EQUAL 0)
+ _get_gcc_features(${CMAKE_C90_STANDARD_COMPILE_OPTION} CMAKE_C90_COMPILE_FEATURES)
+ endif()
+ endif()
+endmacro()
diff --git a/Modules/Compiler/GNU-CXX-FeatureTests.cmake b/Modules/Compiler/GNU-CXX-FeatureTests.cmake
new file mode 100644
index 000000000..d18adaff0
--- /dev/null
+++ b/Modules/Compiler/GNU-CXX-FeatureTests.cmake
@@ -0,0 +1,109 @@
+
+# Reference: http://gcc.gnu.org/projects/cxx0x.html
+# http://gcc.gnu.org/projects/cxx1y.html
+
+set(_cmake_oldestSupported "(__GNUC__ * 100 + __GNUC_MINOR__) >= 404")
+
+set(GNU50_CXX14 "(__GNUC__ * 100 + __GNUC_MINOR__) >= 500 && __cplusplus >= 201402L")
+set(_cmake_feature_test_cxx_variable_templates "${GNU50_CXX14}")
+set(_cmake_feature_test_cxx_relaxed_constexpr "${GNU50_CXX14}")
+set(_cmake_feature_test_cxx_aggregate_default_initializers "${GNU50_CXX14}")
+
+# GNU 4.9 in c++14 mode sets __cplusplus to 201300L, so don't test for the
+# correct value of it below.
+# https://patchwork.ozlabs.org/patch/382470/
+set(GNU49_CXX14 "(__GNUC__ * 100 + __GNUC_MINOR__) >= 409 && __cplusplus > 201103L")
+set(_cmake_feature_test_cxx_contextual_conversions "${GNU49_CXX14}")
+set(_cmake_feature_test_cxx_attribute_deprecated "${GNU49_CXX14}")
+set(_cmake_feature_test_cxx_decltype_auto "${GNU49_CXX14}")
+set(_cmake_feature_test_cxx_digit_separators "${GNU49_CXX14}")
+set(_cmake_feature_test_cxx_generic_lambdas "${GNU49_CXX14}")
+set(_cmake_feature_test_cxx_lambda_init_captures "${GNU49_CXX14}")
+# GNU 4.3 supports binary literals as an extension, but may warn about
+# use of extensions prior to GNU 4.9
+# http://stackoverflow.com/questions/16334024/difference-between-gcc-binary-literals-and-c14-ones
+set(_cmake_feature_test_cxx_binary_literals "${GNU49_CXX14}")
+# The feature below is documented as available in GNU 4.8 (by implementing an
+# earlier draft of the standard paper), but that version of the compiler
+# does not set __cplusplus to a value greater than 201103L until GNU 4.9:
+# http://gcc.gnu.org/onlinedocs/gcc-4.8.2/cpp/Standard-Predefined-Macros.html#Standard-Predefined-Macros
+# http://gcc.gnu.org/onlinedocs/gcc-4.9.0/cpp/Standard-Predefined-Macros.html#Standard-Predefined-Macros
+# So, CMake only reports availability for it with GNU 4.9 or later.
+set(_cmake_feature_test_cxx_return_type_deduction "${GNU49_CXX14}")
+
+# Introduced in GCC 4.8.1
+set(GNU481_CXX11 "((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40801) && __cplusplus >= 201103L")
+set(_cmake_feature_test_cxx_decltype_incomplete_return_types "${GNU481_CXX11}")
+set(_cmake_feature_test_cxx_reference_qualified_functions "${GNU481_CXX11}")
+set(GNU48_CXX11 "(__GNUC__ * 100 + __GNUC_MINOR__) >= 408 && __cplusplus >= 201103L")
+set(_cmake_feature_test_cxx_alignas "${GNU48_CXX11}")
+# The alignof feature works with GNU 4.7 and -std=c++11, but it is documented
+# as available with GNU 4.8, so treat that as true.
+set(_cmake_feature_test_cxx_alignof "${GNU48_CXX11}")
+set(_cmake_feature_test_cxx_attributes "${GNU48_CXX11}")
+set(_cmake_feature_test_cxx_inheriting_constructors "${GNU48_CXX11}")
+set(_cmake_feature_test_cxx_thread_local "${GNU48_CXX11}")
+set(GNU47_CXX11 "(__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && __cplusplus >= 201103L")
+set(_cmake_feature_test_cxx_alias_templates "${GNU47_CXX11}")
+set(_cmake_feature_test_cxx_delegating_constructors "${GNU47_CXX11}")
+set(_cmake_feature_test_cxx_extended_friend_declarations "${GNU47_CXX11}")
+set(_cmake_feature_test_cxx_final "${GNU47_CXX11}")
+set(_cmake_feature_test_cxx_nonstatic_member_init "${GNU47_CXX11}")
+set(_cmake_feature_test_cxx_override "${GNU47_CXX11}")
+set(_cmake_feature_test_cxx_user_literals "${GNU47_CXX11}")
+# NOTE: C++11 was ratified in September 2011. GNU 4.7 is the first minor
+# release following that (March 2012), and the first minor release to
+# support -std=c++11. Prior to that, support for C++11 features is technically
+# experiemental and possibly incomplete (see for example the note below about
+# cxx_variadic_template_template_parameters)
+# GNU does not define __cplusplus correctly before version 4.7.
+# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=1773
+# __GXX_EXPERIMENTAL_CXX0X__ is defined in prior versions, but may not be
+# defined in the future.
+set(GNU_CXX0X_DEFINED "(__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__))")
+set(GNU46_CXX11 "(__GNUC__ * 100 + __GNUC_MINOR__) >= 406 && ${GNU_CXX0X_DEFINED}")
+set(_cmake_feature_test_cxx_constexpr "${GNU46_CXX11}")
+set(_cmake_feature_test_cxx_defaulted_move_initializers "${GNU46_CXX11}")
+set(_cmake_feature_test_cxx_enum_forward_declarations "${GNU46_CXX11}")
+set(_cmake_feature_test_cxx_noexcept "${GNU46_CXX11}")
+set(_cmake_feature_test_cxx_nullptr "${GNU46_CXX11}")
+set(_cmake_feature_test_cxx_range_for "${GNU46_CXX11}")
+set(_cmake_feature_test_cxx_unrestricted_unions "${GNU46_CXX11}")
+set(GNU45_CXX11 "(__GNUC__ * 100 + __GNUC_MINOR__) >= 405 && ${GNU_CXX0X_DEFINED}")
+set(_cmake_feature_test_cxx_explicit_conversions "${GNU45_CXX11}")
+set(_cmake_feature_test_cxx_lambdas "${GNU45_CXX11}")
+set(_cmake_feature_test_cxx_local_type_template_args "${GNU45_CXX11}")
+set(_cmake_feature_test_cxx_raw_string_literals "${GNU45_CXX11}")
+set(GNU44_CXX11 "(__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && ${GNU_CXX0X_DEFINED}")
+set(_cmake_feature_test_cxx_auto_type "${GNU44_CXX11}")
+set(_cmake_feature_test_cxx_defaulted_functions "${GNU44_CXX11}")
+set(_cmake_feature_test_cxx_deleted_functions "${GNU44_CXX11}")
+set(_cmake_feature_test_cxx_generalized_initializers "${GNU44_CXX11}")
+set(_cmake_feature_test_cxx_inline_namespaces "${GNU44_CXX11}")
+set(_cmake_feature_test_cxx_sizeof_member "${GNU44_CXX11}")
+set(_cmake_feature_test_cxx_strong_enums "${GNU44_CXX11}")
+set(_cmake_feature_test_cxx_trailing_return_types "${GNU44_CXX11}")
+set(_cmake_feature_test_cxx_unicode_literals "${GNU44_CXX11}")
+set(_cmake_feature_test_cxx_uniform_initialization "${GNU44_CXX11}")
+set(_cmake_feature_test_cxx_variadic_templates "${GNU44_CXX11}")
+# TODO: If features are ever recorded for GNU 4.3, there should possibly
+# be a new feature added like cxx_variadic_template_template_parameters,
+# which is implemented by GNU 4.4, but not 4.3. cxx_variadic_templates is
+# actually implemented by GNU 4.3, but variadic template template parameters
+# 'completes' it, so that is the version we record as having the variadic
+# templates capability in CMake. See
+# http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2555.pdf
+# TODO: Should be supported by GNU 4.3
+set(GNU43_CXX11 "${_cmake_oldestSupported} && ${GNU_CXX0X_DEFINED}")
+set(_cmake_feature_test_cxx_decltype "${GNU43_CXX11}")
+set(_cmake_feature_test_cxx_default_function_template_args "${GNU43_CXX11}")
+set(_cmake_feature_test_cxx_long_long_type "${GNU43_CXX11}")
+set(_cmake_feature_test_cxx_right_angle_brackets "${GNU43_CXX11}")
+set(_cmake_feature_test_cxx_rvalue_references "${GNU43_CXX11}")
+set(_cmake_feature_test_cxx_static_assert "${GNU43_CXX11}")
+# TODO: Should be supported since GNU 3.4?
+set(_cmake_feature_test_cxx_extern_templates "${_cmake_oldestSupported} && ${GNU_CXX0X_DEFINED}")
+# TODO: Should be supported forever?
+set(_cmake_feature_test_cxx_func_identifier "${_cmake_oldestSupported} && ${GNU_CXX0X_DEFINED}")
+set(_cmake_feature_test_cxx_variadic_macros "${_cmake_oldestSupported} && ${GNU_CXX0X_DEFINED}")
+set(_cmake_feature_test_cxx_template_template_parameters "${_cmake_oldestSupported} && __cplusplus")
diff --git a/Modules/Compiler/GNU-CXX.cmake b/Modules/Compiler/GNU-CXX.cmake
index 33d6093a1..e1c555b4b 100644
--- a/Modules/Compiler/GNU-CXX.cmake
+++ b/Modules/Compiler/GNU-CXX.cmake
@@ -10,3 +10,57 @@ else()
set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
endif()
endif()
+
+if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4)
+ # Supported since 4.3
+ set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "-std=c++98")
+ set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "-std=gnu++98")
+endif()
+
+if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7)
+ set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++11")
+ set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++11")
+elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4)
+ # 4.3 supports 0x variants
+ set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++0x")
+ set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++0x")
+endif()
+
+if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)
+ set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++14")
+ set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++14")
+elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
+ set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++1y")
+ set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++1y")
+endif()
+
+if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4)
+ if (NOT CMAKE_CXX_COMPILER_FORCED)
+ if (NOT CMAKE_CXX_STANDARD_COMPUTED_DEFAULT)
+ message(FATAL_ERROR "CMAKE_CXX_STANDARD_COMPUTED_DEFAULT should be set for ${CMAKE_CXX_COMPILER_ID} (${CMAKE_CXX_COMPILER}) version ${CMAKE_CXX_COMPILER_VERSION}")
+ endif()
+ set(CMAKE_CXX_STANDARD_DEFAULT ${CMAKE_CXX_STANDARD_COMPUTED_DEFAULT})
+ elseif(NOT DEFINED CMAKE_CXX_STANDARD_DEFAULT)
+ # Compiler id was forced so just guess the default standard level.
+ set(CMAKE_CXX_STANDARD_DEFAULT 98)
+ endif()
+endif()
+
+macro(cmake_record_cxx_compile_features)
+ macro(_get_gcc_features std_version list)
+ record_compiler_features(CXX "${std_version}" ${list})
+ endmacro()
+
+ set(_result 0)
+ if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
+ _get_gcc_features(${CMAKE_CXX14_STANDARD_COMPILE_OPTION} CMAKE_CXX14_COMPILE_FEATURES)
+ endif()
+ if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4)
+ if (_result EQUAL 0)
+ _get_gcc_features(${CMAKE_CXX11_STANDARD_COMPILE_OPTION} CMAKE_CXX11_COMPILE_FEATURES)
+ endif()
+ if (_result EQUAL 0)
+ _get_gcc_features(${CMAKE_CXX98_STANDARD_COMPILE_OPTION} CMAKE_CXX98_COMPILE_FEATURES)
+ endif()
+ endif()
+endmacro()
diff --git a/Modules/Compiler/GNU-DetermineCompiler.cmake b/Modules/Compiler/GNU-DetermineCompiler.cmake
new file mode 100644
index 000000000..6ddc56698
--- /dev/null
+++ b/Modules/Compiler/GNU-DetermineCompiler.cmake
@@ -0,0 +1,11 @@
+
+set(_compiler_id_pp_test "defined(__GNUC__)")
+
+set(_compiler_id_version_compute "
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__GNUC__)
+# if defined(__GNUC_MINOR__)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__GNUC_MINOR__)
+# endif
+# if defined(__GNUC_PATCHLEVEL__)
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__GNUC_PATCHLEVEL__)
+# endif")
diff --git a/Modules/Compiler/GNU-Fortran.cmake b/Modules/Compiler/GNU-Fortran.cmake
index 313ccbd02..e9c8a594a 100644
--- a/Modules/Compiler/GNU-Fortran.cmake
+++ b/Modules/Compiler/GNU-Fortran.cmake
@@ -8,10 +8,8 @@ set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree-form")
set(CMAKE_Fortran_FLAGS_MINSIZEREL_INIT "-Os")
set(CMAKE_Fortran_FLAGS_RELEASE_INIT "-O3")
-# We require updates to CMake C++ code to support preprocessing rules
-# for Fortran.
-set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE)
-set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE)
+# No -isystem for Fortran because it will not find .mod files.
+unset(CMAKE_INCLUDE_SYSTEM_FLAG_Fortran)
# Fortran-specific feature flags.
set(CMAKE_Fortran_MODDIR_FLAG -J)
diff --git a/Modules/Compiler/GNU.cmake b/Modules/Compiler/GNU.cmake
index 504704dad..764fbf990 100644
--- a/Modules/Compiler/GNU.cmake
+++ b/Modules/Compiler/GNU.cmake
@@ -30,6 +30,7 @@ macro(__compiler_gnu lang)
endif()
set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-fPIC")
set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared")
+ set(CMAKE_${lang}_COMPILE_OPTIONS_SYSROOT "--sysroot=")
# Older versions of gcc (< 4.5) contain a bug causing them to report a missing
# header file as a warning if depfiles are enabled, causing check_header_file
@@ -49,8 +50,8 @@ macro(__compiler_gnu lang)
set(CMAKE_${lang}_FLAGS_MINSIZEREL_INIT "-Os -DNDEBUG")
set(CMAKE_${lang}_FLAGS_RELEASE_INIT "-O3 -DNDEBUG")
set(CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT "-O2 -g -DNDEBUG")
- set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
- set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
+ set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+ set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
if(NOT APPLE)
set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ")
endif()
diff --git a/Modules/Compiler/HP-C-DetermineCompiler.cmake b/Modules/Compiler/HP-C-DetermineCompiler.cmake
new file mode 100644
index 000000000..426979990
--- /dev/null
+++ b/Modules/Compiler/HP-C-DetermineCompiler.cmake
@@ -0,0 +1,8 @@
+
+set(_compiler_id_pp_test "defined(__HP_cc)")
+
+set(_compiler_id_version_compute "
+ /* __HP_cc = VVRRPP */
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__HP_cc/10000)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__HP_cc/100 % 100)
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__HP_cc % 100)")
diff --git a/Modules/Compiler/HP-C.cmake b/Modules/Compiler/HP-C.cmake
index 6dddcbae1..b42ba2be8 100644
--- a/Modules/Compiler/HP-C.cmake
+++ b/Modules/Compiler/HP-C.cmake
@@ -1,4 +1,4 @@
set(CMAKE_C_VERBOSE_FLAG "-v")
-set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
-set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
+set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
diff --git a/Modules/Compiler/HP-CXX-DetermineCompiler.cmake b/Modules/Compiler/HP-CXX-DetermineCompiler.cmake
new file mode 100644
index 000000000..3d4d7e494
--- /dev/null
+++ b/Modules/Compiler/HP-CXX-DetermineCompiler.cmake
@@ -0,0 +1,8 @@
+
+set(_compiler_id_pp_test "defined(__HP_aCC)")
+
+set(_compiler_id_version_compute "
+ /* __HP_aCC = VVRRPP */
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__HP_aCC/10000)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__HP_aCC/100 % 100)
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__HP_aCC % 100)")
diff --git a/Modules/Compiler/HP-CXX.cmake b/Modules/Compiler/HP-CXX.cmake
index 44470cae0..7548754d3 100644
--- a/Modules/Compiler/HP-CXX.cmake
+++ b/Modules/Compiler/HP-CXX.cmake
@@ -1,4 +1,13 @@
set(CMAKE_CXX_VERBOSE_FLAG "-v")
-set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
-set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
+set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+
+# HP aCC since version 3.80 supports the flag +hpxstd98 to get ANSI C++98
+# template support. It is known that version 6.25 doesn't need that flag.
+# Current assumption: the flag is needed for every version from 3.80 to 4
+# to get it working.
+if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4 AND
+ NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.80)
+ set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "+hpxstd98")
+endif()
diff --git a/Modules/Compiler/HP-Fortran.cmake b/Modules/Compiler/HP-Fortran.cmake
index cc56b4611..a6ca2c2b8 100644
--- a/Modules/Compiler/HP-Fortran.cmake
+++ b/Modules/Compiler/HP-Fortran.cmake
@@ -1,3 +1,6 @@
set(CMAKE_Fortran_VERBOSE_FLAG "-v")
set(CMAKE_Fortran_FORMAT_FIXED_FLAG "+source=fixed")
set(CMAKE_Fortran_FORMAT_FREE_FLAG "+source=free")
+
+set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
+set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
diff --git a/Modules/Compiler/IAR-ASM.cmake b/Modules/Compiler/IAR-ASM.cmake
index 66fb052df..844c30e50 100644
--- a/Modules/Compiler/IAR-ASM.cmake
+++ b/Modules/Compiler/IAR-ASM.cmake
@@ -2,7 +2,7 @@
include(Compiler/IAR)
-set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> <SOURCE> <DEFINES> <FLAGS> -o <OBJECT>")
+set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>")
if("${IAR_TARGET_ARCHITECTURE}" STREQUAL "ARM")
set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS s;asm;msa)
diff --git a/Modules/Compiler/IAR-C.cmake b/Modules/Compiler/IAR-C.cmake
index da29447c4..d2c7df9ed 100644
--- a/Modules/Compiler/IAR-C.cmake
+++ b/Modules/Compiler/IAR-C.cmake
@@ -3,9 +3,9 @@
include(Compiler/IAR)
-set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> <SOURCE> <DEFINES> <FLAGS> -o <OBJECT>")
-set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <SOURCE> <DEFINES> <FLAGS> --preprocess=cnl <PREPROCESSED_SOURCE>")
-set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <SOURCE> <DEFINES> <FLAGS> -lAH <ASSEMBLY_SOURCE> -o <OBJECT>.dummy")
+set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>")
+set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> --preprocess=cnl <PREPROCESSED_SOURCE>")
+set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -lAH <ASSEMBLY_SOURCE> -o <OBJECT>.dummy")
# The toolchains for ARM and AVR are quite different:
if("${IAR_TARGET_ARCHITECTURE}" STREQUAL "ARM")
diff --git a/Modules/Compiler/IAR-CXX.cmake b/Modules/Compiler/IAR-CXX.cmake
index eae9d1b77..03ecdf1d8 100644
--- a/Modules/Compiler/IAR-CXX.cmake
+++ b/Modules/Compiler/IAR-CXX.cmake
@@ -2,10 +2,10 @@
include(Compiler/IAR)
-set(CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER> <SOURCE> <DEFINES> <FLAGS> -o <OBJECT>")
+set(CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>")
-set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <SOURCE> <DEFINES> <FLAGS> --preprocess=cnl <PREPROCESSED_SOURCE>")
-set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> <SOURCE> <DEFINES> <FLAGS> -lAH <ASSEMBLY_SOURCE> -o <OBJECT>.dummy")
+set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> --preprocess=cnl <PREPROCESSED_SOURCE>")
+set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -lAH <ASSEMBLY_SOURCE> -o <OBJECT>.dummy")
diff --git a/Modules/Compiler/IAR-DetermineCompiler.cmake b/Modules/Compiler/IAR-DetermineCompiler.cmake
new file mode 100644
index 000000000..c39810a24
--- /dev/null
+++ b/Modules/Compiler/IAR-DetermineCompiler.cmake
@@ -0,0 +1,4 @@
+
+# IAR Systems compiler for embedded systems.
+# http://www.iar.com
+set(_compiler_id_pp_test "defined(__IAR_SYSTEMS_ICC__ ) || defined(__IAR_SYSTEMS_ICC)")
diff --git a/Modules/Compiler/IAR.cmake b/Modules/Compiler/IAR.cmake
index 00e47133c..8c6c3f600 100644
--- a/Modules/Compiler/IAR.cmake
+++ b/Modules/Compiler/IAR.cmake
@@ -1,6 +1,6 @@
# This file is processed when the IAR compiler is used for a C or C++ file
# Documentation can be downloaded here: http://www.iar.com/website1/1.0.1.0/675/1/
-# The initial feature request is here: http://www.cmake.org/Bug/view.php?id=10176
+# The initial feature request is here: https://cmake.org/Bug/view.php?id=10176
# It also contains additional links and information.
if(_IAR_CMAKE_LOADED)
@@ -39,7 +39,7 @@ endif()
if(NOT IAR_TARGET_ARCHITECTURE)
message(FATAL_ERROR "The IAR compiler for this architecture is not yet supported "
- " by CMake. Please go to http://www.cmake.org/Bug and enter a feature request there.")
+ " by CMake. Please go to https://cmake.org/Bug and enter a feature request there.")
endif()
set(CMAKE_LINKER "${CMAKE_IAR_LINKER}" CACHE FILEPATH "The IAR linker" FORCE)
diff --git a/Modules/Compiler/IBMCPP-C-DetermineVersionInternal.cmake b/Modules/Compiler/IBMCPP-C-DetermineVersionInternal.cmake
new file mode 100644
index 000000000..899e284ad
--- /dev/null
+++ b/Modules/Compiler/IBMCPP-C-DetermineVersionInternal.cmake
@@ -0,0 +1,6 @@
+
+set(_compiler_id_version_compute "
+ /* __IBMC__ = VRP */
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__IBMC__/100)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__IBMC__/10 % 10)
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__IBMC__ % 10)")
diff --git a/Modules/Compiler/IBMCPP-CXX-DetermineVersionInternal.cmake b/Modules/Compiler/IBMCPP-CXX-DetermineVersionInternal.cmake
new file mode 100644
index 000000000..73aa2b4f9
--- /dev/null
+++ b/Modules/Compiler/IBMCPP-CXX-DetermineVersionInternal.cmake
@@ -0,0 +1,6 @@
+
+set(_compiler_id_version_compute "
+ /* __IBMCPP__ = VRP */
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__IBMCPP__/100)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__IBMCPP__/10 % 10)
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__IBMCPP__ % 10)")
diff --git a/Modules/Compiler/Intel-C.cmake b/Modules/Compiler/Intel-C.cmake
index 5b43db9f4..dfba4b2ce 100644
--- a/Modules/Compiler/Intel-C.cmake
+++ b/Modules/Compiler/Intel-C.cmake
@@ -6,9 +6,7 @@ set(CMAKE_C_FLAGS_MINSIZEREL_INIT "-Os -DNDEBUG")
set(CMAKE_C_FLAGS_RELEASE_INIT "-O3 -DNDEBUG")
set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-O2 -g -DNDEBUG")
-if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 12.0)
- set(CMAKE_C_COMPILE_OPTIONS_VISIBILITY "-fvisibility=")
-endif()
+set(CMAKE_DEPFILE_FLAGS_C "-MMD -MT <OBJECT> -MF <DEPFILE>")
-set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
-set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
+set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
diff --git a/Modules/Compiler/Intel-CXX.cmake b/Modules/Compiler/Intel-CXX.cmake
index 35bb3ec04..794769527 100644
--- a/Modules/Compiler/Intel-CXX.cmake
+++ b/Modules/Compiler/Intel-CXX.cmake
@@ -6,9 +6,7 @@ set(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "-Os -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELEASE_INIT "-O3 -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-O2 -g -DNDEBUG")
-if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.0)
- set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY "-fvisibility=")
-endif()
+set(CMAKE_DEPFILE_FLAGS_CXX "-MMD -MT <OBJECT> -MF <DEPFILE>")
-set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
-set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
+set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
diff --git a/Modules/Compiler/Intel-DetermineCompiler.cmake b/Modules/Compiler/Intel-DetermineCompiler.cmake
new file mode 100644
index 000000000..d7e453211
--- /dev/null
+++ b/Modules/Compiler/Intel-DetermineCompiler.cmake
@@ -0,0 +1,26 @@
+
+set(_compiler_id_pp_test "defined(__INTEL_COMPILER) || defined(__ICC)")
+
+set(_compiler_id_version_compute "
+ /* __INTEL_COMPILER = VRP */
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__INTEL_COMPILER/100)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__INTEL_COMPILER/10 % 10)
+# if defined(__INTEL_COMPILER_UPDATE)
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__INTEL_COMPILER_UPDATE)
+# else
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__INTEL_COMPILER % 10)
+# endif
+# if defined(__INTEL_COMPILER_BUILD_DATE)
+ /* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */
+# define @PREFIX@COMPILER_VERSION_TWEAK @MACRO_DEC@(__INTEL_COMPILER_BUILD_DATE)
+# endif
+# if defined(_MSC_VER)
+ /* _MSC_VER = VVRR */
+# define @PREFIX@SIMULATE_VERSION_MAJOR @MACRO_DEC@(_MSC_VER / 100)
+# define @PREFIX@SIMULATE_VERSION_MINOR @MACRO_DEC@(_MSC_VER % 100)
+# endif")
+
+set(_compiler_id_simulate "
+# if defined(_MSC_VER)
+# define @PREFIX@SIMULATE_ID \"MSVC\"
+# endif")
diff --git a/Modules/Compiler/Intel-Fortran.cmake b/Modules/Compiler/Intel-Fortran.cmake
index 84f6182a7..671d284dd 100644
--- a/Modules/Compiler/Intel-Fortran.cmake
+++ b/Modules/Compiler/Intel-Fortran.cmake
@@ -7,3 +7,6 @@ set(CMAKE_Fortran_MODDIR_FLAG "-module ")
set(CMAKE_Fortran_VERBOSE_FLAG "-v")
set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-fixed")
set(CMAKE_Fortran_FORMAT_FREE_FLAG "-free")
+
+set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
diff --git a/Modules/Compiler/MIPSpro-DetermineCompiler.cmake b/Modules/Compiler/MIPSpro-DetermineCompiler.cmake
new file mode 100644
index 000000000..9e485532b
--- /dev/null
+++ b/Modules/Compiler/MIPSpro-DetermineCompiler.cmake
@@ -0,0 +1,15 @@
+
+set(_compiler_id_pp_test "defined(_SGI_COMPILER_VERSION) || defined(_COMPILER_VERSION)")
+
+set(_compiler_id_version_compute "
+# if defined(_SGI_COMPILER_VERSION)
+ /* _SGI_COMPILER_VERSION = VRP */
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(_SGI_COMPILER_VERSION/100)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(_SGI_COMPILER_VERSION/10 % 10)
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(_SGI_COMPILER_VERSION % 10)
+# else
+ /* _COMPILER_VERSION = VRP */
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(_COMPILER_VERSION/100)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(_COMPILER_VERSION/10 % 10)
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(_COMPILER_VERSION % 10)
+# endif")
diff --git a/Modules/Compiler/MSVC-CXX-FeatureTests.cmake b/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
new file mode 100644
index 000000000..ad1d14bd0
--- /dev/null
+++ b/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
@@ -0,0 +1,111 @@
+
+# Reference: http://msdn.microsoft.com/en-us/library/vstudio/hh567368.aspx
+# http://blogs.msdn.com/b/vcblog/archive/2013/06/28/c-11-14-stl-features-fixes-and-breaking-changes-in-vs-2013.aspx
+# http://blogs.msdn.com/b/vcblog/archive/2014/11/17/c-11-14-17-features-in-vs-2015-preview.aspx
+# http://www.visualstudio.com/en-us/news/vs2015-preview-vs.aspx
+# http://blogs.msdn.com/b/vcblog/archive/2015/04/29/c-11-14-17-features-in-vs-2015-rc.aspx
+# http://blogs.msdn.com/b/vcblog/archive/2015/06/19/c-11-14-17-features-in-vs-2015-rtm.aspx
+
+
+set(_cmake_oldestSupported "_MSC_VER >= 1600")
+
+set(MSVC_2015 "_MSC_VER >= 1900")
+set(_cmake_feature_test_cxx_alignas "${MSVC_2015}")
+set(_cmake_feature_test_cxx_alignof "${MSVC_2015}")
+set(_cmake_feature_test_cxx_attributes "${MSVC_2015}")
+set(_cmake_feature_test_cxx_attribute_deprecated "${MSVC_2015}")
+set(_cmake_feature_test_cxx_binary_literals "${MSVC_2015}")
+set(_cmake_feature_test_cxx_constexpr "${MSVC_2015}")
+set(_cmake_feature_test_cxx_decltype_auto "${MSVC_2015}")
+set(_cmake_feature_test_cxx_digit_separators "${MSVC_2015}")
+set(_cmake_feature_test_cxx_func_identifier "${MSVC_2015}")
+set(_cmake_feature_test_cxx_nonstatic_member_init "${MSVC_2015}")
+# Microsoft calls this 'rvalue references v3'
+set(_cmake_feature_test_cxx_defaulted_move_initializers "${MSVC_2015}")
+set(_cmake_feature_test_cxx_generic_lambdas "${MSVC_2015}")
+set(_cmake_feature_test_cxx_inheriting_constructors "${MSVC_2015}")
+set(_cmake_feature_test_cxx_inline_namespaces "${MSVC_2015}")
+set(_cmake_feature_test_cxx_lambda_init_captures "${MSVC_2015}")
+set(_cmake_feature_test_cxx_noexcept "${MSVC_2015}")
+set(_cmake_feature_test_cxx_return_type_deduction "${MSVC_2015}")
+set(_cmake_feature_test_cxx_sizeof_member "${MSVC_2015}")
+set(_cmake_feature_test_cxx_thread_local "${MSVC_2015}")
+set(_cmake_feature_test_cxx_unicode_literals "${MSVC_2015}")
+set(_cmake_feature_test_cxx_unrestricted_unions "${MSVC_2015}")
+set(_cmake_feature_test_cxx_user_literals "${MSVC_2015}")
+set(_cmake_feature_test_cxx_reference_qualified_functions "${MSVC_2015}")
+# "The copies and moves don't interact precisely like the Standard says they
+# should. For example, deletion of moves is specified to also suppress
+# copies, but Visual C++ in Visual Studio 2013 does not."
+# http://blogs.msdn.com/b/vcblog/archive/2014/11/17/c-11-14-17-features-in-vs-2015-preview.aspx
+# lists this as 'partial' in 2013
+set(_cmake_feature_test_cxx_deleted_functions "${MSVC_2015}")
+
+set(MSVC_2013_v30723 "_MSC_FULL_VER >= 180030723")
+# http://blogs.msdn.com/b/vcblog/archive/2014/11/17/c-11-14-17-features-in-vs-2015-preview.aspx
+# Note 1. While previous version of VisualStudio said they supported these
+# they silently produced bad code, and are now marked as having partial
+# support in previous versions. The footnote says the support will be complete
+# in MSVC 2015, so support the feature for that version, assuming that is true.
+# The blog post also says that VS 2013 Update 3 generates an error in cases
+# that previously produced bad code.
+set(_cmake_feature_test_cxx_generalized_initializers "${MSVC_2013_v30723}")
+
+set(MSVC_2013 "_MSC_VER >= 1800")
+set(_cmake_feature_test_cxx_alias_templates "${MSVC_2013}")
+# Microsoft now states they support contextual conversions in 2013 and above.
+# See footnote 6 at:
+# http://blogs.msdn.com/b/vcblog/archive/2014/11/17/c-11-14-17-features-in-vs-2015-preview.aspx
+set(_cmake_feature_test_cxx_contextual_conversions "${MSVC_2013}")
+set(_cmake_feature_test_cxx_default_function_template_args "${MSVC_2013}")
+set(_cmake_feature_test_cxx_defaulted_functions "${MSVC_2013}")
+set(_cmake_feature_test_cxx_delegating_constructors "${MSVC_2013}")
+set(_cmake_feature_test_cxx_explicit_conversions "${MSVC_2013}")
+set(_cmake_feature_test_cxx_raw_string_literals "${MSVC_2013}")
+set(_cmake_feature_test_cxx_uniform_initialization "${MSVC_2013}")
+# Support is documented, but possibly partly broken:
+# https://msdn.microsoft.com/en-us/library/hh567368.aspx
+# http://thread.gmane.org/gmane.comp.lib.boost.devel/244986/focus=245333
+set(_cmake_feature_test_cxx_variadic_templates "${MSVC_2013}")
+
+set(MSVC_2012 "_MSC_VER >= 1700")
+set(_cmake_feature_test_cxx_enum_forward_declarations "${MSVC_2012}")
+set(_cmake_feature_test_cxx_final "${MSVC_2012}")
+set(_cmake_feature_test_cxx_range_for "${MSVC_2012}")
+set(_cmake_feature_test_cxx_strong_enums "${MSVC_2012}")
+
+set(MSVC_2010 "_MSC_VER >= 1600")
+set(_cmake_feature_test_cxx_auto_type "${MSVC_2010}")
+set(_cmake_feature_test_cxx_decltype "${MSVC_2010}")
+set(_cmake_feature_test_cxx_extended_friend_declarations "${MSVC_2010}")
+set(_cmake_feature_test_cxx_extern_templates "${MSVC_2010}")
+set(_cmake_feature_test_cxx_lambdas "${MSVC_2010}")
+set(_cmake_feature_test_cxx_local_type_template_args "${MSVC_2010}")
+set(_cmake_feature_test_cxx_long_long_type "${MSVC_2010}")
+set(_cmake_feature_test_cxx_nullptr "${MSVC_2010}")
+set(_cmake_feature_test_cxx_override "${MSVC_2010}")
+set(_cmake_feature_test_cxx_right_angle_brackets "${MSVC_2010}")
+set(_cmake_feature_test_cxx_rvalue_references "${MSVC_2010}")
+set(_cmake_feature_test_cxx_static_assert "${MSVC_2010}")
+set(_cmake_feature_test_cxx_template_template_parameters "${MSVC_2010}")
+set(_cmake_feature_test_cxx_trailing_return_types "${MSVC_2010}")
+set(_cmake_feature_test_cxx_variadic_macros "${MSVC_2010}")
+
+# Currently unsupported:
+# set(_cmake_feature_test_cxx_relaxed_constexpr )
+# 'NSDMIs for aggregates'
+# set(_cmake_feature_test_cxx_aggregate_default_initializers )
+# set(_cmake_feature_test_cxx_variable_templates )
+
+# In theory decltype incomplete return types was added in 2012
+# but without support for decltype_auto and return type deduction this
+# feature is unusable. This remains so as of VS 2015 Preview.
+# set(_cmake_feature_test_cxx_decltype_incomplete_return_types )
+
+# Unset all the variables that we don't need exposed.
+# _cmake_oldestSupported is required by WriteCompilerDetectionHeader
+set(MSVC_2015)
+set(MSVC_2013_v30723)
+set(MSVC_2013)
+set(MSVC_2012)
+set(MSVC_2010)
diff --git a/Modules/Compiler/MSVC-CXX.cmake b/Modules/Compiler/MSVC-CXX.cmake
new file mode 100644
index 000000000..82ce06989
--- /dev/null
+++ b/Modules/Compiler/MSVC-CXX.cmake
@@ -0,0 +1,9 @@
+
+if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 16.0)
+ # MSVC has no specific language level or flags to change it.
+ set(CMAKE_CXX_STANDARD_DEFAULT "")
+endif()
+
+macro(cmake_record_cxx_compile_features)
+ record_compiler_features(CXX "" CMAKE_CXX_COMPILE_FEATURES)
+endmacro()
diff --git a/Modules/Compiler/MSVC-DetermineCompiler.cmake b/Modules/Compiler/MSVC-DetermineCompiler.cmake
new file mode 100644
index 000000000..313de89fa
--- /dev/null
+++ b/Modules/Compiler/MSVC-DetermineCompiler.cmake
@@ -0,0 +1,19 @@
+
+set(_compiler_id_pp_test "defined(_MSC_VER)")
+
+set(_compiler_id_version_compute "
+ /* _MSC_VER = VVRR */
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(_MSC_VER / 100)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(_MSC_VER % 100)
+# if defined(_MSC_FULL_VER)
+# if _MSC_VER >= 1400
+ /* _MSC_FULL_VER = VVRRPPPPP */
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(_MSC_FULL_VER % 100000)
+# else
+ /* _MSC_FULL_VER = VVRRPPPP */
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(_MSC_FULL_VER % 10000)
+# endif
+# endif
+# if defined(_MSC_BUILD)
+# define @PREFIX@COMPILER_VERSION_TWEAK @MACRO_DEC@(_MSC_BUILD)
+# endif")
diff --git a/Modules/Compiler/OpenWatcom-DetermineCompiler.cmake b/Modules/Compiler/OpenWatcom-DetermineCompiler.cmake
new file mode 100644
index 000000000..2ed116c09
--- /dev/null
+++ b/Modules/Compiler/OpenWatcom-DetermineCompiler.cmake
@@ -0,0 +1,10 @@
+
+set(_compiler_id_pp_test "defined(__WATCOMC__)")
+
+set(_compiler_id_version_compute "
+ /* __WATCOMC__ = VVRP + 1100 */
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@((__WATCOMC__ - 1100) / 100)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@((__WATCOMC__ / 10) % 10)
+# if (__WATCOMC__ % 10) > 0
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__WATCOMC__ % 10)
+# endif")
diff --git a/Modules/Compiler/PGI-DetermineCompiler.cmake b/Modules/Compiler/PGI-DetermineCompiler.cmake
new file mode 100644
index 000000000..8d3dc9ca6
--- /dev/null
+++ b/Modules/Compiler/PGI-DetermineCompiler.cmake
@@ -0,0 +1,9 @@
+
+set(_compiler_id_pp_test "defined(__PGI)")
+
+set(_compiler_id_version_compute "
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__PGIC__)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__PGIC_MINOR__)
+# if defined(__PGIC_PATCHLEVEL__)
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__PGIC_PATCHLEVEL__)
+# endif")
diff --git a/Modules/Compiler/PGI-Fortran.cmake b/Modules/Compiler/PGI-Fortran.cmake
index 264c23e74..2866254fe 100644
--- a/Modules/Compiler/PGI-Fortran.cmake
+++ b/Modules/Compiler/PGI-Fortran.cmake
@@ -7,9 +7,4 @@ set(CMAKE_Fortran_FORMAT_FREE_FLAG "-Mfreeform")
set(CMAKE_Fortran_FLAGS_INIT "${CMAKE_Fortran_FLAGS_INIT} -Mpreprocess -Kieee")
set(CMAKE_Fortran_FLAGS_DEBUG_INIT "${CMAKE_Fortran_FLAGS_DEBUG_INIT} -Mbounds")
-# We require updates to CMake C++ code to support preprocessing rules
-# for Fortran.
-set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE)
-set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE)
-
set(CMAKE_Fortran_MODDIR_FLAG "-module ")
diff --git a/Modules/Compiler/PGI.cmake b/Modules/Compiler/PGI.cmake
index 162e3c9b8..797945f9a 100644
--- a/Modules/Compiler/PGI.cmake
+++ b/Modules/Compiler/PGI.cmake
@@ -30,6 +30,6 @@ macro(__compiler_pgi lang)
set(CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT "-O2 -gopt")
# Preprocessing and assembly rules.
- set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
- set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
+ set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+ set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
endmacro()
diff --git a/Modules/Compiler/PathScale-DetermineCompiler.cmake b/Modules/Compiler/PathScale-DetermineCompiler.cmake
new file mode 100644
index 000000000..4eb81dec7
--- /dev/null
+++ b/Modules/Compiler/PathScale-DetermineCompiler.cmake
@@ -0,0 +1,9 @@
+
+set(_compiler_id_pp_test "defined(__PATHCC__)")
+
+set(_compiler_id_version_compute "
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__PATHCC__)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__PATHCC_MINOR__)
+# if defined(__PATHCC_PATCHLEVEL__)
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__PATHCC_PATCHLEVEL__)
+# endif")
diff --git a/Modules/Compiler/QCC-C.cmake b/Modules/Compiler/QCC-C.cmake
new file mode 100644
index 000000000..ae4a2f491
--- /dev/null
+++ b/Modules/Compiler/QCC-C.cmake
@@ -0,0 +1,2 @@
+include(Compiler/QCC)
+__compiler_qcc(C)
diff --git a/Modules/Compiler/QCC-CXX.cmake b/Modules/Compiler/QCC-CXX.cmake
new file mode 100644
index 000000000..e86d1fa47
--- /dev/null
+++ b/Modules/Compiler/QCC-CXX.cmake
@@ -0,0 +1,12 @@
+include(Compiler/QCC)
+__compiler_qcc(CXX)
+
+# If the toolchain uses qcc for CMAKE_CXX_COMPILER instead of QCC, the
+# default for the driver is not c++.
+set(CMAKE_CXX_COMPILE_OBJECT
+ "<CMAKE_CXX_COMPILER> -lang-c++ <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
+
+set(CMAKE_CXX_LINK_EXECUTABLE
+ "<CMAKE_CXX_COMPILER> -lang-c++ <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+
+set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
diff --git a/Modules/Compiler/QCC.cmake b/Modules/Compiler/QCC.cmake
new file mode 100644
index 000000000..76477e4bb
--- /dev/null
+++ b/Modules/Compiler/QCC.cmake
@@ -0,0 +1,24 @@
+
+#=============================================================================
+# Copyright 2002-2014 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+include(Compiler/GNU)
+
+macro(__compiler_qcc lang)
+ __compiler_gnu(${lang})
+
+ # http://www.qnx.com/developers/docs/6.4.0/neutrino/utilities/q/qcc.html#examples
+ set(CMAKE_${lang}_COMPILE_OPTIONS_TARGET "-V")
+
+ set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-Wp,-isystem,")
+ set(CMAKE_DEPFILE_FLAGS_${lang} "-Wc,-MMD,<DEPFILE>,-MT,<OBJECT>,-MF,<DEPFILE>")
+endmacro()
diff --git a/Modules/Compiler/SCO-DetermineCompiler.cmake b/Modules/Compiler/SCO-DetermineCompiler.cmake
new file mode 100644
index 000000000..a44b22b71
--- /dev/null
+++ b/Modules/Compiler/SCO-DetermineCompiler.cmake
@@ -0,0 +1,2 @@
+
+set(_compiler_id_pp_test "defined(__SCO_VERSION__)")
diff --git a/Modules/Compiler/SDCC-C-DetermineCompiler.cmake b/Modules/Compiler/SDCC-C-DetermineCompiler.cmake
new file mode 100644
index 000000000..1d7dd78d8
--- /dev/null
+++ b/Modules/Compiler/SDCC-C-DetermineCompiler.cmake
@@ -0,0 +1,10 @@
+
+# sdcc, the small devices C compiler for embedded systems,
+# http://sdcc.sourceforge.net */
+set(_compiler_id_pp_test "defined(SDCC)")
+
+set(_compiler_id_version_compute "
+ /* SDCC = VRP */
+# define COMPILER_VERSION_MAJOR @MACRO_DEC@(SDCC/100)
+# define COMPILER_VERSION_MINOR @MACRO_DEC@(SDCC/10 % 10)
+# define COMPILER_VERSION_PATCH @MACRO_DEC@(SDCC % 10)")
diff --git a/Modules/Compiler/SunPro-C-DetermineCompiler.cmake b/Modules/Compiler/SunPro-C-DetermineCompiler.cmake
new file mode 100644
index 000000000..e9d7457e7
--- /dev/null
+++ b/Modules/Compiler/SunPro-C-DetermineCompiler.cmake
@@ -0,0 +1,15 @@
+
+set(_compiler_id_pp_test "defined(__SUNPRO_C)")
+
+set(_compiler_id_version_compute "
+# if __SUNPRO_C >= 0x5100
+ /* __SUNPRO_C = 0xVRRP */
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_HEX@(__SUNPRO_C>>12)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_HEX@(__SUNPRO_C>>4 & 0xFF)
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_HEX@(__SUNPRO_C & 0xF)
+# else
+ /* __SUNPRO_CC = 0xVRP */
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_HEX@(__SUNPRO_C>>8)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_HEX@(__SUNPRO_C>>4 & 0xF)
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_HEX@(__SUNPRO_C & 0xF)
+# endif")
diff --git a/Modules/Compiler/SunPro-C.cmake b/Modules/Compiler/SunPro-C.cmake
index c5b5203fd..c4529833d 100644
--- a/Modules/Compiler/SunPro-C.cmake
+++ b/Modules/Compiler/SunPro-C.cmake
@@ -1,7 +1,6 @@
set(CMAKE_C_VERBOSE_FLAG "-#")
set(CMAKE_C_COMPILE_OPTIONS_PIC -KPIC)
-set(CMAKE_C_COMPILE_OPTIONS_PIE -KPIE)
set(CMAKE_SHARED_LIBRARY_C_FLAGS "-KPIC")
set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-G")
set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-R")
@@ -23,5 +22,5 @@ foreach(type SHARED_LIBRARY SHARED_MODULE EXE)
set(CMAKE_${type}_LINK_DYNAMIC_C_FLAGS "-Bdynamic")
endforeach()
-set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
-set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
+set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
diff --git a/Modules/Compiler/SunPro-CXX-DetermineCompiler.cmake b/Modules/Compiler/SunPro-CXX-DetermineCompiler.cmake
new file mode 100644
index 000000000..5c23a957e
--- /dev/null
+++ b/Modules/Compiler/SunPro-CXX-DetermineCompiler.cmake
@@ -0,0 +1,15 @@
+
+set(_compiler_id_pp_test "defined(__SUNPRO_CC)")
+
+set(_compiler_id_version_compute "
+# if __SUNPRO_CC >= 0x5100
+ /* __SUNPRO_CC = 0xVRRP */
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_HEX@(__SUNPRO_CC>>12)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_HEX@(__SUNPRO_CC>>4 & 0xFF)
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_HEX@(__SUNPRO_CC & 0xF)
+# else
+ /* __SUNPRO_CC = 0xVRP */
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_HEX@(__SUNPRO_CC>>8)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_HEX@(__SUNPRO_CC>>4 & 0xF)
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_HEX@(__SUNPRO_CC & 0xF)
+# endif")
diff --git a/Modules/Compiler/SunPro-CXX-FeatureTests.cmake b/Modules/Compiler/SunPro-CXX-FeatureTests.cmake
new file mode 100644
index 000000000..8e97e1d05
--- /dev/null
+++ b/Modules/Compiler/SunPro-CXX-FeatureTests.cmake
@@ -0,0 +1,52 @@
+
+# Based on GNU 4.8.2
+# http://docs.oracle.com/cd/E37069_01/html/E37071/gncix.html
+# Reference: http://gcc.gnu.org/projects/cxx0x.html
+
+set(_cmake_oldestSupported "__SUNPRO_CC >= 0x5130")
+
+set(SolarisStudio124_CXX11 "(__SUNPRO_CC >= 0x5130) && __cplusplus >= 201103L")
+set(_cmake_feature_test_cxx_alignas "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_alignof "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_attributes "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_inheriting_constructors "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_thread_local "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_alias_templates "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_delegating_constructors "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_extended_friend_declarations "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_final "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_noexcept "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_nonstatic_member_init "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_override "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_constexpr "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_defaulted_move_initializers "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_enum_forward_declarations "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_nullptr "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_range_for "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_unrestricted_unions "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_explicit_conversions "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_lambdas "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_local_type_template_args "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_raw_string_literals "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_auto_type "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_defaulted_functions "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_deleted_functions "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_generalized_initializers "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_inline_namespaces "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_sizeof_member "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_strong_enums "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_trailing_return_types "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_unicode_literals "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_uniform_initialization "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_variadic_templates "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_decltype "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_default_function_template_args "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_long_long_type "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_right_angle_brackets "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_rvalue_references "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_static_assert "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_extern_templates "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_func_identifier "${SolarisStudio124_CXX11}")
+set(_cmake_feature_test_cxx_variadic_macros "${SolarisStudio124_CXX11}")
+
+set(_cmake_feature_test_cxx_template_template_parameters "${_cmake_oldestSupported} && __cplusplus")
diff --git a/Modules/Compiler/SunPro-CXX.cmake b/Modules/Compiler/SunPro-CXX.cmake
index 59687129a..b4a5591b4 100644
--- a/Modules/Compiler/SunPro-CXX.cmake
+++ b/Modules/Compiler/SunPro-CXX.cmake
@@ -1,7 +1,6 @@
set(CMAKE_CXX_VERBOSE_FLAG "-v")
set(CMAKE_CXX_COMPILE_OPTIONS_PIC -KPIC)
-set(CMAKE_CXX_COMPILE_OPTIONS_PIE -KPIE)
set(CMAKE_SHARED_LIBRARY_CXX_FLAGS "-KPIC")
set(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "-G")
set(CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG "-R")
@@ -23,11 +22,42 @@ foreach(type SHARED_LIBRARY SHARED_MODULE EXE)
set(CMAKE_${type}_LINK_DYNAMIC_CXX_FLAGS "-Bdynamic")
endforeach()
-set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
-set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
+set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
# Create archives with "CC -xar" in case user adds "-instances=extern"
# so that template instantiations are available to archive members.
set(CMAKE_CXX_CREATE_STATIC_LIBRARY
"<CMAKE_CXX_COMPILER> -xar -o <TARGET> <OBJECTS> "
"<CMAKE_RANLIB> <TARGET> ")
+
+if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.13)
+ set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++11")
+ set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=c++11")
+endif()
+
+if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.13)
+ if (NOT CMAKE_CXX_COMPILER_FORCED)
+ if (NOT CMAKE_CXX_STANDARD_COMPUTED_DEFAULT)
+ message(FATAL_ERROR "CMAKE_CXX_STANDARD_COMPUTED_DEFAULT should be set for ${CMAKE_CXX_COMPILER_ID} (${CMAKE_CXX_COMPILER}) version ${CMAKE_CXX_COMPILER_VERSION}")
+ endif()
+ set(CMAKE_CXX_STANDARD_DEFAULT ${CMAKE_CXX_STANDARD_COMPUTED_DEFAULT})
+ elseif(NOT DEFINED CMAKE_CXX_STANDARD_DEFAULT)
+ # Compiler id was forced so just guess the default standard level.
+ set(CMAKE_CXX_STANDARD_DEFAULT 98)
+ endif()
+endif()
+
+macro(cmake_record_cxx_compile_features)
+ macro(_get_solaris_studio_features std_version list)
+ record_compiler_features(CXX "${std_version}" ${list})
+ endmacro()
+
+ set(_result 0)
+ if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.13)
+ _get_solaris_studio_features(${CMAKE_CXX11_STANDARD_COMPILE_OPTION} CMAKE_CXX11_COMPILE_FEATURES)
+ if (_result EQUAL 0)
+ _get_solaris_studio_features("" CMAKE_CXX98_COMPILE_FEATURES)
+ endif()
+ endif()
+endmacro()
diff --git a/Modules/Compiler/SunPro-Fortran.cmake b/Modules/Compiler/SunPro-Fortran.cmake
index 18e75b9e3..610e19176 100644
--- a/Modules/Compiler/SunPro-Fortran.cmake
+++ b/Modules/Compiler/SunPro-Fortran.cmake
@@ -2,6 +2,7 @@ set(CMAKE_Fortran_VERBOSE_FLAG "-v")
set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-fixed")
set(CMAKE_Fortran_FORMAT_FREE_FLAG "-free")
+set(CMAKE_Fortran_COMPILE_OPTIONS_PIC "-KPIC")
set(CMAKE_SHARED_LIBRARY_Fortran_FLAGS "-KPIC")
set(CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS "-G")
set(CMAKE_SHARED_LIBRARY_RUNTIME_Fortran_FLAG "-R")
@@ -16,3 +17,6 @@ set(CMAKE_Fortran_FLAGS_RELEASE_INIT "-xO3 -DNDEBUG")
set(CMAKE_Fortran_FLAGS_RELWITHDEBINFO_INIT "-g -xO2 -DNDEBUG")
set(CMAKE_Fortran_MODDIR_FLAG "-moddir=")
set(CMAKE_Fortran_MODPATH_FLAG "-M")
+
+set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -F <SOURCE> -o <PREPROCESSED_SOURCE>")
+set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
diff --git a/Modules/Compiler/TI-ASM.cmake b/Modules/Compiler/TI-ASM.cmake
index e097626b6..a566d70e1 100644
--- a/Modules/Compiler/TI-ASM.cmake
+++ b/Modules/Compiler/TI-ASM.cmake
@@ -2,7 +2,7 @@ set(CMAKE_LIBRARY_PATH_FLAG "--search_path=")
set(CMAKE_LINK_LIBRARY_FLAG "--library=")
set(CMAKE_INCLUDE_FLAG_ASM "--include_path=")
-set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> --compile_only --asm_file=<SOURCE> <DEFINES> <FLAGS> --output_file=<OBJECT>")
+set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> --compile_only --asm_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<OBJECT>")
set(CMAKE_ASM_LINK_EXECUTABLE "<CMAKE_ASM_COMPILER> <OBJECTS> --run_linker --output_file=<TARGET> <CMAKE_ASM_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>")
set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS asm;s;abs)
diff --git a/Modules/Compiler/TI-C.cmake b/Modules/Compiler/TI-C.cmake
index b5809942e..479666c72 100644
--- a/Modules/Compiler/TI-C.cmake
+++ b/Modules/Compiler/TI-C.cmake
@@ -2,9 +2,9 @@ set(CMAKE_LIBRARY_PATH_FLAG "--search_path=")
set(CMAKE_LINK_LIBRARY_FLAG "--library=")
set(CMAKE_INCLUDE_FLAG_C "--include_path=")
-set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> --compile_only --skip_assembler --c_file=<SOURCE> <DEFINES> <FLAGS> --output_file=<ASSEMBLY_SOURCE>")
-set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> --preproc_only --c_file=<SOURCE> <DEFINES> <FLAGS> --output_file=<PREPROCESSED_SOURCE>")
+set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> --compile_only --skip_assembler --c_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<ASSEMBLY_SOURCE>")
+set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> --preproc_only --c_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<PREPROCESSED_SOURCE>")
-set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> --compile_only --c_file=<SOURCE> <DEFINES> <FLAGS> --output_file=<OBJECT>")
+set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> --compile_only --c_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<OBJECT>")
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> -r <TARGET> <OBJECTS>")
set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> --run_linker --output_file=<TARGET> --map_file=<TARGET>.map <CMAKE_C_LINK_FLAGS> <LINK_LIBRARIES> <LINK_FLAGS> <OBJECTS>")
diff --git a/Modules/Compiler/TI-CXX.cmake b/Modules/Compiler/TI-CXX.cmake
index 8cf5ac37e..4104c3b18 100644
--- a/Modules/Compiler/TI-CXX.cmake
+++ b/Modules/Compiler/TI-CXX.cmake
@@ -2,9 +2,9 @@ set(CMAKE_LIBRARY_PATH_FLAG "--search_path=")
set(CMAKE_LINK_LIBRARY_FLAG "--library=")
set(CMAKE_INCLUDE_FLAG_CXX "--include_path=")
-set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> --compile_only --skip_assembler --cpp_file=<SOURCE> <DEFINES> <FLAGS> --output_file=<ASSEMBLY_SOURCE>")
-set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> --preproc_only --cpp_file=<SOURCE> <DEFINES> <FLAGS> --output_file=<PREPROCESSED_SOURCE>")
+set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> --compile_only --skip_assembler --cpp_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<ASSEMBLY_SOURCE>")
+set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> --preproc_only --cpp_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<PREPROCESSED_SOURCE>")
-set(CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER> --compile_only --cpp_file=<SOURCE> <DEFINES> <FLAGS> --output_file=<OBJECT>")
+set(CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER> --compile_only --cpp_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<OBJECT>")
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> -r <TARGET> <OBJECTS>")
set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> --run_linker --output_file=<TARGET> --map_file=<TARGET>.map <CMAKE_CXX_LINK_FLAGS> <LINK_LIBRARIES> <LINK_FLAGS> <OBJECTS>")
diff --git a/Modules/Compiler/TI-DetermineCompiler.cmake b/Modules/Compiler/TI-DetermineCompiler.cmake
new file mode 100644
index 000000000..19aa9e3d4
--- /dev/null
+++ b/Modules/Compiler/TI-DetermineCompiler.cmake
@@ -0,0 +1,8 @@
+
+set(_compiler_id_pp_test "defined(__TI_COMPILER_VERSION__)")
+
+set(_compiler_id_version_compute "
+ /* __TI_COMPILER_VERSION__ = VVVRRRPPP */
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__TI_COMPILER_VERSION__/1000000)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__TI_COMPILER_VERSION__/1000 % 1000)
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__TI_COMPILER_VERSION__ % 1000)")
diff --git a/Modules/Compiler/TinyCC-C-DetermineCompiler.cmake b/Modules/Compiler/TinyCC-C-DetermineCompiler.cmake
new file mode 100644
index 000000000..8d6de7e44
--- /dev/null
+++ b/Modules/Compiler/TinyCC-C-DetermineCompiler.cmake
@@ -0,0 +1,2 @@
+
+set(_compiler_id_pp_test "defined(__TINYC__)")
diff --git a/Modules/Compiler/VisualAge-C-DetermineCompiler.cmake b/Modules/Compiler/VisualAge-C-DetermineCompiler.cmake
new file mode 100644
index 000000000..97c226313
--- /dev/null
+++ b/Modules/Compiler/VisualAge-C-DetermineCompiler.cmake
@@ -0,0 +1,4 @@
+
+set(_compiler_id_pp_test "defined(__IBMC__) && !defined(__COMPILER_VER__) && __IBMC__ < 800")
+
+include("${CMAKE_CURRENT_LIST_DIR}/IBMCPP-C-DetermineVersionInternal.cmake")
diff --git a/Modules/Compiler/VisualAge-CXX-DetermineCompiler.cmake b/Modules/Compiler/VisualAge-CXX-DetermineCompiler.cmake
new file mode 100644
index 000000000..cd5349968
--- /dev/null
+++ b/Modules/Compiler/VisualAge-CXX-DetermineCompiler.cmake
@@ -0,0 +1,4 @@
+
+set(_compiler_id_pp_test "defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ < 800")
+
+include("${CMAKE_CURRENT_LIST_DIR}/IBMCPP-CXX-DetermineVersionInternal.cmake")
diff --git a/Modules/Compiler/Watcom-DetermineCompiler.cmake b/Modules/Compiler/Watcom-DetermineCompiler.cmake
new file mode 100644
index 000000000..153e350db
--- /dev/null
+++ b/Modules/Compiler/Watcom-DetermineCompiler.cmake
@@ -0,0 +1,10 @@
+
+set(_compiler_id_pp_test "defined(__WATCOMC__) && __WATCOMC__ < 1200")
+
+set(_compiler_id_version_compute "
+ /* __WATCOMC__ = VVRR */
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__WATCOMC__ / 100)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@((__WATCOMC__ / 10) % 10)
+# if (__WATCOMC__ % 10) > 0
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__WATCOMC__ % 10)
+# endif")
diff --git a/Modules/Compiler/XL-ASM.cmake b/Modules/Compiler/XL-ASM.cmake
index 07507f9be..212179e34 100644
--- a/Modules/Compiler/XL-ASM.cmake
+++ b/Modules/Compiler/XL-ASM.cmake
@@ -1,9 +1,8 @@
set(CMAKE_ASM_VERBOSE_FLAG "-V")
# -qthreaded = Ensures that all optimizations will be thread-safe
-# -qalias=noansi = Turns off type-based aliasing completely (safer optimizer)
# -qhalt=e = Halt on error messages (rather than just severe errors)
-set(CMAKE_ASM_FLAGS_INIT "-qthreaded -qalias=noansi -qhalt=e -qsourcetype=assembler")
+set(CMAKE_ASM_FLAGS_INIT "-qthreaded -qhalt=e -qsourcetype=assembler")
set(CMAKE_ASM_FLAGS_DEBUG_INIT "-g")
set(CMAKE_ASM_FLAGS_RELEASE_INIT "-O -DNDEBUG")
diff --git a/Modules/Compiler/XL-C-DetermineCompiler.cmake b/Modules/Compiler/XL-C-DetermineCompiler.cmake
new file mode 100644
index 000000000..3f4e05c55
--- /dev/null
+++ b/Modules/Compiler/XL-C-DetermineCompiler.cmake
@@ -0,0 +1,4 @@
+
+set(_compiler_id_pp_test "defined(__IBMC__) && !defined(__COMPILER_VER__) && __IBMC__ >= 800")
+
+include("${CMAKE_CURRENT_LIST_DIR}/IBMCPP-C-DetermineVersionInternal.cmake")
diff --git a/Modules/Compiler/XL-C.cmake b/Modules/Compiler/XL-C.cmake
index 09a55291e..97dd01789 100644
--- a/Modules/Compiler/XL-C.cmake
+++ b/Modules/Compiler/XL-C.cmake
@@ -4,6 +4,5 @@ set(CMAKE_C_FLAGS_RELEASE_INIT "${CMAKE_C_FLAGS_RELEASE_INIT} -DNDEBUG")
set(CMAKE_C_FLAGS_MINSIZEREL_INIT "${CMAKE_C_FLAGS_MINSIZEREL_INIT} -DNDEBUG")
# -qthreaded = Ensures that all optimizations will be thread-safe
-# -qalias=noansi = Turns off type-based aliasing completely (safer optimizer)
# -qhalt=e = Halt on error messages (rather than just severe errors)
-set(CMAKE_C_FLAGS_INIT "-qthreaded -qalias=noansi -qhalt=e")
+set(CMAKE_C_FLAGS_INIT "-qthreaded -qhalt=e")
diff --git a/Modules/Compiler/XL-CXX-DetermineCompiler.cmake b/Modules/Compiler/XL-CXX-DetermineCompiler.cmake
new file mode 100644
index 000000000..dffa4bc21
--- /dev/null
+++ b/Modules/Compiler/XL-CXX-DetermineCompiler.cmake
@@ -0,0 +1,4 @@
+
+set(_compiler_id_pp_test "defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ >= 800")
+
+include("${CMAKE_CURRENT_LIST_DIR}/IBMCPP-CXX-DetermineVersionInternal.cmake")
diff --git a/Modules/Compiler/XL-CXX.cmake b/Modules/Compiler/XL-CXX.cmake
index 6c842cd77..41372c15b 100644
--- a/Modules/Compiler/XL-CXX.cmake
+++ b/Modules/Compiler/XL-CXX.cmake
@@ -8,4 +8,4 @@ set(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "${CMAKE_CXX_FLAGS_MINSIZEREL_INIT} -DNDEBUG
set(CMAKE_CXX_FLAGS_INIT "-qthreaded -qhalt=e")
set(CMAKE_CXX_COMPILE_OBJECT
- "<CMAKE_CXX_COMPILER> -+ <DEFINES> <FLAGS> -o <OBJECT> -c <SOURCE>")
+ "<CMAKE_CXX_COMPILER> -+ <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
diff --git a/Modules/Compiler/XL-Fortran.cmake b/Modules/Compiler/XL-Fortran.cmake
index f1c9158b2..ae9df4e4b 100644
--- a/Modules/Compiler/XL-Fortran.cmake
+++ b/Modules/Compiler/XL-Fortran.cmake
@@ -12,6 +12,6 @@ set(CMAKE_Fortran_DEFINE_FLAG "-WF,-D")
# -qhalt=e = Halt on error messages (rather than just severe errors)
set(CMAKE_Fortran_FLAGS_INIT "-qthreaded -qhalt=e")
-# We require updates to CMake C++ code to support preprocessing rules for Fortran.
+# xlf: 1501-214 (W) command option E reserved for future use - ignored
set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE)
set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE)
diff --git a/Modules/Compiler/XL.cmake b/Modules/Compiler/XL.cmake
index 7bf5020ac..bf4f5541c 100644
--- a/Modules/Compiler/XL.cmake
+++ b/Modules/Compiler/XL.cmake
@@ -33,8 +33,8 @@ macro(__compiler_xl lang)
set(CMAKE_${lang}_FLAGS_RELEASE_INIT "-O")
set(CMAKE_${lang}_FLAGS_MINSIZEREL_INIT "-O")
set(CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT "-g")
- set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
- set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
+ set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+ set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
# CMAKE_XL_CreateExportList is part of the AIX XL compilers but not the linux ones.
# If we found the tool, we'll use it to create exports, otherwise stick with the regular
diff --git a/Modules/Compiler/zOS-C-DetermineCompiler.cmake b/Modules/Compiler/zOS-C-DetermineCompiler.cmake
new file mode 100644
index 000000000..daa378198
--- /dev/null
+++ b/Modules/Compiler/zOS-C-DetermineCompiler.cmake
@@ -0,0 +1,4 @@
+
+set(_compiler_id_pp_test "defined(__IBMC__) && defined(__COMPILER_VER__)")
+
+include("${CMAKE_CURRENT_LIST_DIR}/IBMCPP-C-DetermineVersionInternal.cmake")
diff --git a/Modules/Compiler/zOS-CXX-DetermineCompiler.cmake b/Modules/Compiler/zOS-CXX-DetermineCompiler.cmake
new file mode 100644
index 000000000..a08ff5713
--- /dev/null
+++ b/Modules/Compiler/zOS-CXX-DetermineCompiler.cmake
@@ -0,0 +1,4 @@
+
+set(_compiler_id_pp_test "defined(__IBMCPP__) && defined(__COMPILER_VER__)")
+
+include("${CMAKE_CURRENT_LIST_DIR}/IBMCPP-CXX-DetermineVersionInternal.cmake")
diff --git a/Modules/CompilerId/VS-10.vcxproj.in b/Modules/CompilerId/VS-10.vcxproj.in
index 1a7a53942..2870a11ca 100644
--- a/Modules/CompilerId/VS-10.vcxproj.in
+++ b/Modules/CompilerId/VS-10.vcxproj.in
@@ -10,6 +10,10 @@
<ProjectGuid>{CAE07175-D007-4FC3-BFE8-47B392814159}</ProjectGuid>
<RootNamespace>CompilerId@id_lang@</RootNamespace>
<Keyword>Win32Proj</Keyword>
+ @id_system@
+ @id_system_version@
+ @id_WindowsTargetPlatformVersion@
+ @id_WindowsSDKDesktopARMSupport@
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|@id_platform@'" Label="Configuration">
diff --git a/Modules/CompilerId/VS-Intel.vfproj.in b/Modules/CompilerId/VS-Intel.vfproj.in
new file mode 100644
index 000000000..044dd202d
--- /dev/null
+++ b/Modules/CompilerId/VS-Intel.vfproj.in
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<VisualStudioProject
+ ProjectCreator="Intel Fortran"
+ Keyword="Console Application"
+ Version="@CMAKE_VS_INTEL_Fortran_PROJECT_VERSION@"
+ ProjectIdGuid="{AB67BAB7-D7AE-4E97-B492-FE5420447509}"
+ >
+ <Platforms>
+ <Platform Name="@id_platform@"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|@id_platform@"
+ OutputDirectory="."
+ IntermediateDirectory="$(ConfigurationName)"
+ >
+ <Tool
+ Name="VFFortranCompilerTool"
+ DebugInformationFormat="debugEnabled"
+ Optimization="optimizeDisabled"
+ Preprocess="preprocessYes"
+ RuntimeLibrary="rtMultiThreadedDebugDLL"
+ />
+ <Tool
+ Name="VFLinkerTool"
+ LinkIncremental="linkIncrementalNo"
+ GenerateDebugInformation="true"
+ SubSystem="subSystemConsole"
+ />
+ <Tool
+ Name="VFPostBuildEventTool"
+ CommandLine="for %%i in (@id_cl@) do @echo CMAKE_@id_lang@_COMPILER=%%~$PATH:i"
+ />
+ </Configuration>
+ </Configurations>
+ <Files>
+ <Filter Name="Source Files" Filter="F">
+ <File RelativePath="@id_src@"/>
+ </Filter>
+ </Files>
+ <Globals/>
+</VisualStudioProject>
diff --git a/Modules/CompilerId/VS-NsightTegra.vcxproj.in b/Modules/CompilerId/VS-NsightTegra.vcxproj.in
new file mode 100644
index 000000000..b7389ebab
--- /dev/null
+++ b/Modules/CompilerId/VS-NsightTegra.vcxproj.in
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Label="NsightTegraProject">
+ <NsightTegraProjectRevisionNumber>6</NsightTegraProjectRevisionNumber>
+ </PropertyGroup>
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|@id_platform@">
+ <Configuration>Debug</Configuration>
+ <Platform>@id_platform@</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{CAE07175-D007-4FC3-BFE8-47B392814159}</ProjectGuid>
+ <RootNamespace>CompilerId@id_lang@</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|@id_platform@'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ @id_toolset@
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|@id_platform@'">.\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|@id_platform@'">$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|@id_platform@'">false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|@id_platform@'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ </Link>
+ <PostBuildEvent>
+ <Command>
+if "$(ToolchainName)"=="gcc" (
+ for %%i in ($(ToolchainPrebuiltRoot)\bin\*@id_gcc@.exe) do (
+ @echo CMAKE_@id_lang@_COMPILER=%%i
+ goto :done
+ )
+)
+if "$(ToolchainName)"=="clang" (
+ for %%i in ($(ToolchainPrebuiltRoot)\bin\*@id_clang@.exe) do (
+ @echo CMAKE_@id_lang@_COMPILER=%%i
+ goto :done
+ )
+)
+:done
+</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="@id_src@" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/Modules/CompilerId/Xcode-3.pbxproj.in b/Modules/CompilerId/Xcode-3.pbxproj.in
index 6f861ebf4..20f3da312 100644
--- a/Modules/CompilerId/Xcode-3.pbxproj.in
+++ b/Modules/CompilerId/Xcode-3.pbxproj.in
@@ -29,7 +29,7 @@
);
name = CompilerId@id_lang@;
productName = CompilerId@id_lang@;
- productType = "com.apple.product-type.tool";
+ productType = "@id_product_type@";
};
08FB7793FE84155DC02AAC07 = {
isa = PBXProject;
@@ -79,11 +79,13 @@
1DEB928A08733DD80010E9CD = {
isa = XCBuildConfiguration;
buildSettings = {
- ARCHS = "$(ARCHS_STANDARD_32_BIT)";
ONLY_ACTIVE_ARCH = YES;
+ CODE_SIGNING_REQUIRED = NO;
CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)";
SYMROOT = .;
@id_toolset@
+ @id_deployment_target@
+ @id_sdkroot@
};
name = Debug;
};
diff --git a/Modules/CompilerId/main.swift.in b/Modules/CompilerId/main.swift.in
new file mode 100644
index 000000000..13f0ba037
--- /dev/null
+++ b/Modules/CompilerId/main.swift.in
@@ -0,0 +1 @@
+print("CMakeSwiftCompilerId")
diff --git a/Modules/Dart.cmake b/Modules/Dart.cmake
index bd744b003..db487d8f5 100644
--- a/Modules/Dart.cmake
+++ b/Modules/Dart.cmake
@@ -1,12 +1,22 @@
-# - Configure a project for testing with CTest or old Dart Tcl Client
+#.rst:
+# Dart
+# ----
+#
+# Configure a project for testing with CTest or old Dart Tcl Client
+#
# This file is the backwards-compatibility version of the CTest module.
# It supports using the old Dart 1 Tcl client for driving dashboard
-# submissions as well as testing with CTest. This module should be included
-# in the CMakeLists.txt file at the top of a project. Typical usage:
-# include(Dart)
-# if(BUILD_TESTING)
-# # ... testing related CMake code ...
-# endif()
+# submissions as well as testing with CTest. This module should be
+# included in the CMakeLists.txt file at the top of a project. Typical
+# usage:
+#
+# ::
+#
+# include(Dart)
+# if(BUILD_TESTING)
+# # ... testing related CMake code ...
+# endif()
+#
# The BUILD_TESTING option is created by the Dart module to determine
# whether testing support should be enabled. The default is ON.
diff --git a/Modules/DartConfiguration.tcl.in b/Modules/DartConfiguration.tcl.in
index 9e49ac776..2da835427 100644
--- a/Modules/DartConfiguration.tcl.in
+++ b/Modules/DartConfiguration.tcl.in
@@ -37,6 +37,9 @@ ConfigureCommand: "@CMAKE_COMMAND@" "@PROJECT_SOURCE_DIR@"
MakeCommand: @MAKECOMMAND@
DefaultCTestConfigurationType: @DEFAULT_CTEST_CONFIGURATION_TYPE@
+# version control
+UpdateVersionOnly: @CTEST_UPDATE_VERSION_ONLY@
+
# CVS options
# Default is "-d -P -A"
CVSCommand: @CVSCOMMAND@
@@ -52,6 +55,13 @@ GITCommand: @GITCOMMAND@
GITUpdateOptions: @GIT_UPDATE_OPTIONS@
GITUpdateCustom: @CTEST_GIT_UPDATE_CUSTOM@
+# Perforce options
+P4Command: @P4COMMAND@
+P4Client: @CTEST_P4_CLIENT@
+P4Options: @CTEST_P4_OPTIONS@
+P4UpdateOptions: @CTEST_P4_UPDATE_OPTIONS@
+P4UpdateCustom: @CTEST_P4_UPDATE_CUSTOM@
+
# Generic update command
UpdateCommand: @UPDATE_COMMAND@
UpdateOptions: @UPDATE_OPTIONS@
@@ -59,11 +69,14 @@ UpdateType: @UPDATE_TYPE@
# Compiler info
Compiler: @CMAKE_CXX_COMPILER@
+CompilerVersion: @CMAKE_CXX_COMPILER_VERSION@
# Dynamic analysis (MemCheck)
PurifyCommand: @PURIFYCOMMAND@
ValgrindCommand: @VALGRIND_COMMAND@
ValgrindCommandOptions: @VALGRIND_COMMAND_OPTIONS@
+MemoryCheckType: @MEMORYCHECK_TYPE@
+MemoryCheckSanitizerOptions: @MEMORYCHECK_SANITIZER_OPTIONS@
MemoryCheckCommand: @MEMORYCHECK_COMMAND@
MemoryCheckCommandOptions: @MEMORYCHECK_COMMAND_OPTIONS@
MemoryCheckSuppressionFile: @MEMORYCHECK_SUPPRESSIONS_FILE@
@@ -83,6 +96,10 @@ SlurmRunCommand: @SLURM_SRUN_COMMAND@
# Currently set to 25 minutes
TimeOut: @DART_TESTING_TIMEOUT@
+# During parallel testing CTest will not start a new test if doing
+# so would cause the system load to exceed this value.
+TestLoad: @CTEST_TEST_LOAD@
+
UseLaunchers: @CTEST_USE_LAUNCHERS@
CurlOptions: @CTEST_CURL_OPTIONS@
# warning, if you add new options here that have to do with submit,
diff --git a/Modules/DeployQt4.cmake b/Modules/DeployQt4.cmake
index 5f8a9fbf3..de475e45f 100644
--- a/Modules/DeployQt4.cmake
+++ b/Modules/DeployQt4.cmake
@@ -1,68 +1,103 @@
-# - Functions to help assemble a standalone Qt4 executable.
-# A collection of CMake utility functions useful for deploying
-# Qt4 executables.
+#.rst:
+# DeployQt4
+# ---------
+#
+# Functions to help assemble a standalone Qt4 executable.
+#
+# A collection of CMake utility functions useful for deploying Qt4
+# executables.
#
# The following functions are provided by this module:
-# write_qt4_conf
-# resolve_qt4_paths
-# fixup_qt4_executable
-# install_qt4_plugin_path
-# install_qt4_plugin
-# install_qt4_executable
+#
+# ::
+#
+# write_qt4_conf
+# resolve_qt4_paths
+# fixup_qt4_executable
+# install_qt4_plugin_path
+# install_qt4_plugin
+# install_qt4_executable
+#
# Requires CMake 2.6 or greater because it uses function and
-# PARENT_SCOPE. Also depends on BundleUtilities.cmake.
+# PARENT_SCOPE. Also depends on BundleUtilities.cmake.
+#
+# ::
+#
+# WRITE_QT4_CONF(<qt_conf_dir> <qt_conf_contents>)
#
-# WRITE_QT4_CONF(<qt_conf_dir> <qt_conf_contents>)
# Writes a qt.conf file with the <qt_conf_contents> into <qt_conf_dir>.
#
-# RESOLVE_QT4_PATHS(<paths_var> [<executable_path>])
+# ::
+#
+# RESOLVE_QT4_PATHS(<paths_var> [<executable_path>])
+#
# Loop through <paths_var> list and if any don't exist resolve them
-# relative to the <executable_path> (if supplied) or the CMAKE_INSTALL_PREFIX.
+# relative to the <executable_path> (if supplied) or the
+# CMAKE_INSTALL_PREFIX.
+#
+# ::
#
-# FIXUP_QT4_EXECUTABLE(<executable> [<qtplugins> <libs> <dirs> <plugins_dir> <request_qt_conf>])
-# Copies Qt plugins, writes a Qt configuration file (if needed) and fixes up a
-# Qt4 executable using BundleUtilities so it is standalone and can be
-# drag-and-drop copied to another machine as long as all of the system
-# libraries are compatible.
+# FIXUP_QT4_EXECUTABLE(<executable>
+# [<qtplugins> <libs> <dirs> <plugins_dir> <request_qt_conf>])
+#
+# Copies Qt plugins, writes a Qt configuration file (if needed) and
+# fixes up a Qt4 executable using BundleUtilities so it is standalone
+# and can be drag-and-drop copied to another machine as long as all of
+# the system libraries are compatible.
#
# <executable> should point to the executable to be fixed-up.
#
-# <qtplugins> should contain a list of the names or paths of any Qt plugins
-# to be installed.
+# <qtplugins> should contain a list of the names or paths of any Qt
+# plugins to be installed.
#
-# <libs> will be passed to BundleUtilities and should be a list of any already
-# installed plugins, libraries or executables to also be fixed-up.
+# <libs> will be passed to BundleUtilities and should be a list of any
+# already installed plugins, libraries or executables to also be
+# fixed-up.
#
-# <dirs> will be passed to BundleUtilities and should contain and directories
-# to be searched to find library dependencies.
+# <dirs> will be passed to BundleUtilities and should contain and
+# directories to be searched to find library dependencies.
#
# <plugins_dir> allows an custom plugins directory to be used.
#
-# <request_qt_conf> will force a qt.conf file to be written even if not needed.
+# <request_qt_conf> will force a qt.conf file to be written even if not
+# needed.
+#
+# ::
+#
+# INSTALL_QT4_PLUGIN_PATH(plugin executable copy installed_plugin_path_var
+# <plugins_dir> <component> <configurations>)
#
-# INSTALL_QT4_PLUGIN_PATH(plugin executable copy installed_plugin_path_var <plugins_dir> <component> <configurations>)
# Install (or copy) a resolved <plugin> to the default plugins directory
# (or <plugins_dir>) relative to <executable> and store the result in
# <installed_plugin_path_var>.
#
# If <copy> is set to TRUE then the plugins will be copied rather than
-# installed. This is to allow this module to be used at CMake time rather than
-# install time.
+# installed. This is to allow this module to be used at CMake time
+# rather than install time.
#
# If <component> is set then anything installed will use this COMPONENT.
#
-# INSTALL_QT4_PLUGIN(plugin executable copy installed_plugin_path_var <plugins_dir> <component>)
-# Install (or copy) an unresolved <plugin> to the default plugins directory
-# (or <plugins_dir>) relative to <executable> and store the result in
-# <installed_plugin_path_var>. See documentation of INSTALL_QT4_PLUGIN_PATH.
-#
-# INSTALL_QT4_EXECUTABLE(<executable> [<qtplugins> <libs> <dirs> <plugins_dir> <request_qt_conf> <component>])
-# Installs Qt plugins, writes a Qt configuration file (if needed) and fixes up
-# a Qt4 executable using BundleUtilities so it is standalone and can be
-# drag-and-drop copied to another machine as long as all of the system
-# libraries are compatible. The executable will be fixed-up at install time.
-# <component> is the COMPONENT used for bundle fixup and plugin installation.
-# See documentation of FIXUP_QT4_BUNDLE.
+# ::
+#
+# INSTALL_QT4_PLUGIN(plugin executable copy installed_plugin_path_var
+# <plugins_dir> <component>)
+#
+# Install (or copy) an unresolved <plugin> to the default plugins
+# directory (or <plugins_dir>) relative to <executable> and store the
+# result in <installed_plugin_path_var>. See documentation of
+# INSTALL_QT4_PLUGIN_PATH.
+#
+# ::
+#
+# INSTALL_QT4_EXECUTABLE(<executable>
+# [<qtplugins> <libs> <dirs> <plugins_dir> <request_qt_conf> <component>])
+#
+# Installs Qt plugins, writes a Qt configuration file (if needed) and
+# fixes up a Qt4 executable using BundleUtilities so it is standalone
+# and can be drag-and-drop copied to another machine as long as all of
+# the system libraries are compatible. The executable will be fixed-up
+# at install time. <component> is the COMPONENT used for bundle fixup
+# and plugin installation. See documentation of FIXUP_QT4_BUNDLE.
#=============================================================================
# Copyright 2011 Mike McQuaid <mike@mikemcquaid.com>
@@ -91,7 +126,10 @@ function(write_qt4_conf qt_conf_dir qt_conf_contents)
endfunction()
function(resolve_qt4_paths paths_var)
- set(executable_path ${ARGV1})
+ unset(executable_path)
+ if(ARGC GREATER 1)
+ set(executable_path ${ARGV1})
+ endif()
set(paths_resolved)
foreach(path ${${paths_var}})
@@ -109,11 +147,26 @@ function(resolve_qt4_paths paths_var)
endfunction()
function(fixup_qt4_executable executable)
- set(qtplugins ${ARGV1})
- set(libs ${ARGV2})
- set(dirs ${ARGV3})
- set(plugins_dir ${ARGV4})
- set(request_qt_conf ${ARGV5})
+ unset(qtplugins)
+ if(ARGC GREATER 1)
+ set(qtplugins ${ARGV1})
+ endif()
+ unset(libs)
+ if(ARGC GREATER 2)
+ set(libs ${ARGV2})
+ endif()
+ unset(dirs)
+ if(ARGC GREATER 3)
+ set(dirs ${ARGV3})
+ endif()
+ unset(plugins_dir)
+ if(ARGC GREATER 4)
+ set(plugins_dir ${ARGV4})
+ endif()
+ unset(request_qt_conf)
+ if(ARGC GREATER 5)
+ set(request_qt_conf ${ARGV5})
+ endif()
message(STATUS "fixup_qt4_executable")
message(STATUS " executable='${executable}'")
@@ -134,7 +187,7 @@ function(fixup_qt4_executable executable)
set(qt_conf_dir "${executable}/Contents/Resources")
set(executable_path "${executable}")
set(write_qt_conf TRUE)
- if(NOT plugins_dir)
+ if(NOT DEFINED plugins_dir)
set(plugins_dir "${DeployQt4_apple_plugins_dir}")
endif()
else()
@@ -169,9 +222,19 @@ function(fixup_qt4_executable executable)
endfunction()
function(install_qt4_plugin_path plugin executable copy installed_plugin_path_var)
- set(plugins_dir ${ARGV4})
- set(component ${ARGV5})
- set(configurations ${ARGV6})
+ unset(plugins_dir)
+ if(ARGC GREATER 4)
+ set(plugins_dir ${ARGV4})
+ endif()
+ unset(component)
+ if(ARGC GREATER 5)
+ set(component ${ARGV5})
+ endif()
+ unset(configurations)
+ if(ARGC GREATER 6)
+ set(configurations ${ARGV6})
+ endif()
+
if(EXISTS "${plugin}")
if(APPLE)
if(NOT plugins_dir)
@@ -218,8 +281,15 @@ function(install_qt4_plugin_path plugin executable copy installed_plugin_path_va
endfunction()
function(install_qt4_plugin plugin executable copy installed_plugin_path_var)
- set(plugins_dir ${ARGV4})
- set(component ${ARGV5})
+ unset(plugins_dir)
+ if(ARGC GREATER 4)
+ set(plugins_dir ${ARGV4})
+ endif()
+ unset(component)
+ if(ARGC GREATER 5)
+ set(component ${ARGV5})
+ endif()
+
if(EXISTS "${plugin}")
install_qt4_plugin_path("${plugin}" "${executable}" "${copy}" "${installed_plugin_path_var}" "${plugins_dir}" "${component}")
else()
@@ -252,12 +322,31 @@ function(install_qt4_plugin plugin executable copy installed_plugin_path_var)
endfunction()
function(install_qt4_executable executable)
- set(qtplugins ${ARGV1})
- set(libs ${ARGV2})
- set(dirs ${ARGV3})
- set(plugins_dir ${ARGV4})
- set(request_qt_conf ${ARGV5})
- set(component ${ARGV6})
+ unset(qtplugins)
+ if(ARGC GREATER 1)
+ set(qtplugins ${ARGV1})
+ endif()
+ unset(libs)
+ if(ARGC GREATER 2)
+ set(libs ${ARGV2})
+ endif()
+ unset(dirs)
+ if(ARGC GREATER 3)
+ set(dirs ${ARGV3})
+ endif()
+ unset(plugins_dir)
+ if(ARGC GREATER 4)
+ set(plugins_dir ${ARGV4})
+ endif()
+ unset(request_qt_conf)
+ if(ARGC GREATER 5)
+ set(request_qt_conf ${ARGV5})
+ endif()
+ unset(component)
+ if(ARGC GREATER 6)
+ set(component ${ARGV6})
+ endif()
+
if(QT_LIBRARY_DIR)
list(APPEND dirs "${QT_LIBRARY_DIR}")
endif()
diff --git a/Modules/Documentation.cmake b/Modules/Documentation.cmake
index d1c3afe47..be6aaea69 100644
--- a/Modules/Documentation.cmake
+++ b/Modules/Documentation.cmake
@@ -1,6 +1,11 @@
-# - DocumentationVTK.cmake
-# This file provides support for the VTK documentation framework.
-# It relies on several tools (Doxygen, Perl, etc).
+#.rst:
+# Documentation
+# -------------
+#
+# DocumentationVTK.cmake
+#
+# This file provides support for the VTK documentation framework. It
+# relies on several tools (Doxygen, Perl, etc).
#=============================================================================
# Copyright 2001-2009 Kitware, Inc.
diff --git a/Modules/ExternalData.cmake b/Modules/ExternalData.cmake
index 50669bd29..a3f460d0a 100644
--- a/Modules/ExternalData.cmake
+++ b/Modules/ExternalData.cmake
@@ -1,149 +1,319 @@
-# - Manage data files stored outside source tree
-# Use this module to unambiguously reference data files stored outside the
-# source tree and fetch them at build time from arbitrary local and remote
-# content-addressed locations. Functions provided by this module recognize
-# arguments with the syntax "DATA{<name>}" as references to external data,
-# replace them with full paths to local copies of those data, and create build
-# rules to fetch and update the local copies.
-#
-# The DATA{} syntax is literal and the <name> is a full or relative path
-# within the source tree. The source tree must contain either a real data
-# file at <name> or a "content link" at <name><ext> containing a hash of the
-# real file using a hash algorithm corresponding to <ext>. For example, the
-# argument "DATA{img.png}" may be satisfied by either a real "img.png" file in
-# the current source directory or a "img.png.md5" file containing its MD5 sum.
-#
-# The 'ExternalData_Expand_Arguments' function evaluates DATA{} references
-# in its arguments and constructs a new list of arguments:
-# ExternalData_Expand_Arguments(
-# <target> # Name of data management target
-# <outVar> # Output variable
-# [args...] # Input arguments, DATA{} allowed
-# )
-# It replaces each DATA{} reference in an argument with the full path of a
-# real data file on disk that will exist after the <target> builds.
-#
-# The 'ExternalData_Add_Test' function wraps around the CMake add_test()
-# command but supports DATA{} references in its arguments:
-# ExternalData_Add_Test(
-# <target> # Name of data management target
-# ... # Arguments of add_test(), DATA{} allowed
-# )
-# It passes its arguments through ExternalData_Expand_Arguments and then
-# invokes add_test() using the results.
-#
-# The 'ExternalData_Add_Target' function creates a custom target to manage
-# local instances of data files stored externally:
-# ExternalData_Add_Target(
-# <target> # Name of data management target
-# )
-# It creates custom commands in the target as necessary to make data files
-# available for each DATA{} reference previously evaluated by other functions
-# provided by this module. A list of URL templates must be provided in the
-# variable ExternalData_URL_TEMPLATES using the placeholders "%(algo)" and
-# "%(hash)" in each template. Data fetch rules try each URL template in order
-# by substituting the hash algorithm name for "%(algo)" and the hash value for
-# "%(hash)".
-#
-# The following hash algorithms are supported:
-# %(algo) <ext> Description
-# ------- ----- -----------
-# MD5 .md5 Message-Digest Algorithm 5, RFC 1321
-# SHA1 .sha1 US Secure Hash Algorithm 1, RFC 3174
-# SHA224 .sha224 US Secure Hash Algorithms, RFC 4634
-# SHA256 .sha256 US Secure Hash Algorithms, RFC 4634
-# SHA384 .sha384 US Secure Hash Algorithms, RFC 4634
-# SHA512 .sha512 US Secure Hash Algorithms, RFC 4634
-# Note that the hashes are used only for unique data identification and
-# download verification. This is not security software.
-#
-# Example usage:
-# include(ExternalData)
-# set(ExternalData_URL_TEMPLATES "file:///local/%(algo)/%(hash)"
-# "http://data.org/%(algo)/%(hash)")
-# ExternalData_Add_Test(MyData
-# NAME MyTest
-# COMMAND MyExe DATA{MyInput.png}
-# )
-# ExternalData_Add_Target(MyData)
-# When test "MyTest" runs the "DATA{MyInput.png}" argument will be replaced by
-# the full path to a real instance of the data file "MyInput.png" on disk. If
-# the source tree contains a content link such as "MyInput.png.md5" then the
-# "MyData" target creates a real "MyInput.png" in the build tree.
-#
-# The DATA{} syntax can be told to fetch a file series using the form
-# "DATA{<name>,:}", where the ":" is literal. If the source tree contains a
-# group of files or content links named like a series then a reference to one
-# member adds rules to fetch all of them. Although all members of a series
-# are fetched, only the file originally named by the DATA{} argument is
-# substituted for it. The default configuration recognizes file series names
-# ending with "#.ext", "_#.ext", ".#.ext", or "-#.ext" where "#" is a sequence
-# of decimal digits and ".ext" is any single extension. Configure it with a
-# regex that parses <number> and <suffix> parts from the end of <name>:
-# ExternalData_SERIES_PARSE = regex of the form (<number>)(<suffix>)$
-# For more complicated cases set:
-# ExternalData_SERIES_PARSE = regex with at least two () groups
-# ExternalData_SERIES_PARSE_PREFIX = <prefix> regex group number, if any
-# ExternalData_SERIES_PARSE_NUMBER = <number> regex group number
-# ExternalData_SERIES_PARSE_SUFFIX = <suffix> regex group number
-# Configure series number matching with a regex that matches the
-# <number> part of series members named <prefix><number><suffix>:
-# ExternalData_SERIES_MATCH = regex matching <number> in all series members
-# Note that the <suffix> of a series does not include a hash-algorithm
-# extension.
-#
-# The DATA{} syntax can alternatively match files associated with the named
-# file and contained in the same directory. Associated files may be specified
-# by options using the syntax DATA{<name>,<opt1>,<opt2>,...}. Each option may
-# specify one file by name or specify a regular expression to match file names
-# using the syntax REGEX:<regex>. For example, the arguments
-# DATA{MyData/MyInput.mhd,MyInput.img} # File pair
-# DATA{MyData/MyFrames00.png,REGEX:MyFrames[0-9]+\\.png} # Series
-# will pass MyInput.mha and MyFrames00.png on the command line but ensure
-# that the associated files are present next to them.
-#
-# The DATA{} syntax may reference a directory using a trailing slash and a
-# list of associated files. The form DATA{<name>/,<opt1>,<opt2>,...} adds
-# rules to fetch any files in the directory that match one of the associated
-# file options. For example, the argument DATA{MyDataDir/,REGEX:.*} will pass
-# the full path to a MyDataDir directory on the command line and ensure that
-# the directory contains files corresponding to every file or content link in
-# the MyDataDir source directory.
-#
-# The variable ExternalData_LINK_CONTENT may be set to the name of a supported
-# hash algorithm to enable automatic conversion of real data files referenced
-# by the DATA{} syntax into content links. For each such <file> a content
-# link named "<file><ext>" is created. The original file is renamed to the
-# form ".ExternalData_<algo>_<hash>" to stage it for future transmission to
-# one of the locations in the list of URL templates (by means outside the
-# scope of this module). The data fetch rule created for the content link
-# will use the staged object if it cannot be found using any URL template.
-#
-# The variable ExternalData_OBJECT_STORES may be set to a list of local
-# directories that store objects using the layout <dir>/%(algo)/%(hash).
-# These directories will be searched first for a needed object. If the object
-# is not available in any store then it will be fetched remotely using the URL
-# templates and added to the first local store listed. If no stores are
-# specified the default is a location inside the build tree.
-#
-# The variable ExternalData_SOURCE_ROOT may be set to the highest source
-# directory containing any path named by a DATA{} reference. The default is
-# CMAKE_SOURCE_DIR. ExternalData_SOURCE_ROOT and CMAKE_SOURCE_DIR must refer
-# to directories within a single source distribution (e.g. they come together
-# in one tarball).
-#
-# The variable ExternalData_BINARY_ROOT may be set to the directory to hold
-# the real data files named by expanded DATA{} references. The default is
-# CMAKE_BINARY_DIR. The directory layout will mirror that of content links
-# under ExternalData_SOURCE_ROOT.
-#
-# Variables ExternalData_TIMEOUT_INACTIVITY and ExternalData_TIMEOUT_ABSOLUTE
-# set the download inactivity and absolute timeouts, in seconds. The defaults
-# are 60 seconds and 300 seconds, respectively. Set either timeout to 0
-# seconds to disable enforcement.
+#[=======================================================================[.rst:
+ExternalData
+------------
+
+.. only:: html
+
+ .. contents::
+
+Manage data files stored outside source tree
+
+Introduction
+^^^^^^^^^^^^
+
+Use this module to unambiguously reference data files stored outside
+the source tree and fetch them at build time from arbitrary local and
+remote content-addressed locations. Functions provided by this module
+recognize arguments with the syntax ``DATA{<name>}`` as references to
+external data, replace them with full paths to local copies of those
+data, and create build rules to fetch and update the local copies.
+
+For example:
+
+.. code-block:: cmake
+
+ include(ExternalData)
+ set(ExternalData_URL_TEMPLATES "file:///local/%(algo)/%(hash)"
+ "file:////host/share/%(algo)/%(hash)"
+ "http://data.org/%(algo)/%(hash)")
+ ExternalData_Add_Test(MyData
+ NAME MyTest
+ COMMAND MyExe DATA{MyInput.png}
+ )
+ ExternalData_Add_Target(MyData)
+
+When test ``MyTest`` runs the ``DATA{MyInput.png}`` argument will be
+replaced by the full path to a real instance of the data file
+``MyInput.png`` on disk. If the source tree contains a content link
+such as ``MyInput.png.md5`` then the ``MyData`` target creates a real
+``MyInput.png`` in the build tree.
+
+Module Functions
+^^^^^^^^^^^^^^^^
+
+.. command:: ExternalData_Expand_Arguments
+
+ The ``ExternalData_Expand_Arguments`` function evaluates ``DATA{}``
+ references in its arguments and constructs a new list of arguments::
+
+ ExternalData_Expand_Arguments(
+ <target> # Name of data management target
+ <outVar> # Output variable
+ [args...] # Input arguments, DATA{} allowed
+ )
+
+ It replaces each ``DATA{}`` reference in an argument with the full path of
+ a real data file on disk that will exist after the ``<target>`` builds.
+
+.. command:: ExternalData_Add_Test
+
+ The ``ExternalData_Add_Test`` function wraps around the CMake
+ :command:`add_test` command but supports ``DATA{}`` references in
+ its arguments::
+
+ ExternalData_Add_Test(
+ <target> # Name of data management target
+ ... # Arguments of add_test(), DATA{} allowed
+ )
+
+ It passes its arguments through ``ExternalData_Expand_Arguments`` and then
+ invokes the :command:`add_test` command using the results.
+
+.. command:: ExternalData_Add_Target
+
+ The ``ExternalData_Add_Target`` function creates a custom target to
+ manage local instances of data files stored externally::
+
+ ExternalData_Add_Target(
+ <target> # Name of data management target
+ )
+
+ It creates custom commands in the target as necessary to make data
+ files available for each ``DATA{}`` reference previously evaluated by
+ other functions provided by this module.
+ Data files may be fetched from one of the URL templates specified in
+ the ``ExternalData_URL_TEMPLATES`` variable, or may be found locally
+ in one of the paths specified in the ``ExternalData_OBJECT_STORES``
+ variable.
+
+Module Variables
+^^^^^^^^^^^^^^^^
+
+The following variables configure behavior. They should be set before
+calling any of the functions provided by this module.
+
+.. variable:: ExternalData_BINARY_ROOT
+
+ The ``ExternalData_BINARY_ROOT`` variable may be set to the directory to
+ hold the real data files named by expanded ``DATA{}`` references. The
+ default is ``CMAKE_BINARY_DIR``. The directory layout will mirror that of
+ content links under ``ExternalData_SOURCE_ROOT``.
+
+.. variable:: ExternalData_CUSTOM_SCRIPT_<key>
+
+ Specify a full path to a ``.cmake`` custom fetch script identified by
+ ``<key>`` in entries of the ``ExternalData_URL_TEMPLATES`` list.
+ See `Custom Fetch Scripts`_.
+
+.. variable:: ExternalData_LINK_CONTENT
+
+ The ``ExternalData_LINK_CONTENT`` variable may be set to the name of a
+ supported hash algorithm to enable automatic conversion of real data
+ files referenced by the ``DATA{}`` syntax into content links. For each
+ such ``<file>`` a content link named ``<file><ext>`` is created. The
+ original file is renamed to the form ``.ExternalData_<algo>_<hash>`` to
+ stage it for future transmission to one of the locations in the list
+ of URL templates (by means outside the scope of this module). The
+ data fetch rule created for the content link will use the staged
+ object if it cannot be found using any URL template.
+
+.. variable:: ExternalData_NO_SYMLINKS
+
+ The real data files named by expanded ``DATA{}`` references may be made
+ available under ``ExternalData_BINARY_ROOT`` using symbolic links on
+ some platforms. The ``ExternalData_NO_SYMLINKS`` variable may be set
+ to disable use of symbolic links and enable use of copies instead.
+
+.. variable:: ExternalData_OBJECT_STORES
+
+ The ``ExternalData_OBJECT_STORES`` variable may be set to a list of local
+ directories that store objects using the layout ``<dir>/%(algo)/%(hash)``.
+ These directories will be searched first for a needed object. If the
+ object is not available in any store then it will be fetched remotely
+ using the URL templates and added to the first local store listed. If
+ no stores are specified the default is a location inside the build
+ tree.
+
+.. variable:: ExternalData_SERIES_PARSE
+ ExternalData_SERIES_PARSE_PREFIX
+ ExternalData_SERIES_PARSE_NUMBER
+ ExternalData_SERIES_PARSE_SUFFIX
+ ExternalData_SERIES_MATCH
+
+ See `Referencing File Series`_.
+
+.. variable:: ExternalData_SOURCE_ROOT
+
+ The ``ExternalData_SOURCE_ROOT`` variable may be set to the highest source
+ directory containing any path named by a ``DATA{}`` reference. The
+ default is ``CMAKE_SOURCE_DIR``. ``ExternalData_SOURCE_ROOT`` and
+ ``CMAKE_SOURCE_DIR`` must refer to directories within a single source
+ distribution (e.g. they come together in one tarball).
+
+.. variable:: ExternalData_TIMEOUT_ABSOLUTE
+
+ The ``ExternalData_TIMEOUT_ABSOLUTE`` variable sets the download
+ absolute timeout, in seconds, with a default of ``300`` seconds.
+ Set to ``0`` to disable enforcement.
+
+.. variable:: ExternalData_TIMEOUT_INACTIVITY
+
+ The ``ExternalData_TIMEOUT_INACTIVITY`` variable sets the download
+ inactivity timeout, in seconds, with a default of ``60`` seconds.
+ Set to ``0`` to disable enforcement.
+
+.. variable:: ExternalData_URL_ALGO_<algo>_<key>
+
+ Specify a custom URL component to be substituted for URL template
+ placeholders of the form ``%(algo:<key>)``, where ``<key>`` is a
+ valid C identifier, when fetching an object referenced via hash
+ algorithm ``<algo>``. If not defined, the default URL component
+ is just ``<algo>`` for any ``<key>``.
+
+.. variable:: ExternalData_URL_TEMPLATES
+
+ The ``ExternalData_URL_TEMPLATES`` may be set to provide a list of
+ of URL templates using the placeholders ``%(algo)`` and ``%(hash)``
+ in each template. Data fetch rules try each URL template in order
+ by substituting the hash algorithm name for ``%(algo)`` and the hash
+ value for ``%(hash)``. Alternatively one may use ``%(algo:<key>)``
+ with ``ExternalData_URL_ALGO_<algo>_<key>`` variables to gain more
+ flexibility in remote URLs.
+
+Referencing Files
+^^^^^^^^^^^^^^^^^
+
+Referencing Single Files
+""""""""""""""""""""""""
+
+The ``DATA{}`` syntax is literal and the ``<name>`` is a full or relative path
+within the source tree. The source tree must contain either a real
+data file at ``<name>`` or a "content link" at ``<name><ext>`` containing a
+hash of the real file using a hash algorithm corresponding to ``<ext>``.
+For example, the argument ``DATA{img.png}`` may be satisfied by either a
+real ``img.png`` file in the current source directory or a ``img.png.md5``
+file containing its MD5 sum.
+
+Referencing File Series
+"""""""""""""""""""""""
+
+The ``DATA{}`` syntax can be told to fetch a file series using the form
+``DATA{<name>,:}``, where the ``:`` is literal. If the source tree
+contains a group of files or content links named like a series then a
+reference to one member adds rules to fetch all of them. Although all
+members of a series are fetched, only the file originally named by the
+``DATA{}`` argument is substituted for it. The default configuration
+recognizes file series names ending with ``#.ext``, ``_#.ext``, ``.#.ext``,
+or ``-#.ext`` where ``#`` is a sequence of decimal digits and ``.ext`` is
+any single extension. Configure it with a regex that parses ``<number>``
+and ``<suffix>`` parts from the end of ``<name>``::
+
+ ExternalData_SERIES_PARSE = regex of the form (<number>)(<suffix>)$
+
+For more complicated cases set::
+
+ ExternalData_SERIES_PARSE = regex with at least two () groups
+ ExternalData_SERIES_PARSE_PREFIX = <prefix> regex group number, if any
+ ExternalData_SERIES_PARSE_NUMBER = <number> regex group number
+ ExternalData_SERIES_PARSE_SUFFIX = <suffix> regex group number
+
+Configure series number matching with a regex that matches the
+``<number>`` part of series members named ``<prefix><number><suffix>``::
+
+ ExternalData_SERIES_MATCH = regex matching <number> in all series members
+
+Note that the ``<suffix>`` of a series does not include a hash-algorithm
+extension.
+
+Referencing Associated Files
+""""""""""""""""""""""""""""
+
+The ``DATA{}`` syntax can alternatively match files associated with the
+named file and contained in the same directory. Associated files may
+be specified by options using the syntax
+``DATA{<name>,<opt1>,<opt2>,...}``. Each option may specify one file by
+name or specify a regular expression to match file names using the
+syntax ``REGEX:<regex>``. For example, the arguments::
+
+ DATA{MyData/MyInput.mhd,MyInput.img} # File pair
+ DATA{MyData/MyFrames00.png,REGEX:MyFrames[0-9]+\\.png} # Series
+
+will pass ``MyInput.mha`` and ``MyFrames00.png`` on the command line but
+ensure that the associated files are present next to them.
+
+Referencing Directories
+"""""""""""""""""""""""
+
+The ``DATA{}`` syntax may reference a directory using a trailing slash and
+a list of associated files. The form ``DATA{<name>/,<opt1>,<opt2>,...}``
+adds rules to fetch any files in the directory that match one of the
+associated file options. For example, the argument
+``DATA{MyDataDir/,REGEX:.*}`` will pass the full path to a ``MyDataDir``
+directory on the command line and ensure that the directory contains
+files corresponding to every file or content link in the ``MyDataDir``
+source directory. In order to match associated files in subdirectories,
+specify a ``RECURSE:`` option, e.g. ``DATA{MyDataDir/,RECURSE:,REGEX:.*}``.
+
+Hash Algorithms
+^^^^^^^^^^^^^^^
+
+The following hash algorithms are supported::
+
+ %(algo) <ext> Description
+ ------- ----- -----------
+ MD5 .md5 Message-Digest Algorithm 5, RFC 1321
+ SHA1 .sha1 US Secure Hash Algorithm 1, RFC 3174
+ SHA224 .sha224 US Secure Hash Algorithms, RFC 4634
+ SHA256 .sha256 US Secure Hash Algorithms, RFC 4634
+ SHA384 .sha384 US Secure Hash Algorithms, RFC 4634
+ SHA512 .sha512 US Secure Hash Algorithms, RFC 4634
+
+Note that the hashes are used only for unique data identification and
+download verification.
+
+.. _`ExternalData Custom Fetch Scripts`:
+
+Custom Fetch Scripts
+^^^^^^^^^^^^^^^^^^^^
+
+When a data file must be fetched from one of the URL templates
+specified in the ``ExternalData_URL_TEMPLATES`` variable, it is
+normally downloaded using the :command:`file(DOWNLOAD)` command.
+One may specify usage of a custom fetch script by using a URL
+template of the form ``ExternalDataCustomScript://<key>/<loc>``.
+The ``<key>`` must be a C identifier, and the ``<loc>`` must
+contain the ``%(algo)`` and ``%(hash)`` placeholders.
+A variable corresponding to the key, ``ExternalData_CUSTOM_SCRIPT_<key>``,
+must be set to the full path to a ``.cmake`` script file. The script
+will be included to perform the actual fetch, and provided with
+the following variables:
+
+.. variable:: ExternalData_CUSTOM_LOCATION
+
+ When a custom fetch script is loaded, this variable is set to the
+ location part of the URL, which will contain the substituted hash
+ algorithm name and content hash value.
+
+.. variable:: ExternalData_CUSTOM_FILE
+
+ When a custom fetch script is loaded, this variable is set to the
+ full path to a file in which the script must store the fetched
+ content. The name of the file is unspecified and should not be
+ interpreted in any way.
+
+The custom fetch script is expected to store fetched content in the
+file or set a variable:
+
+.. variable:: ExternalData_CUSTOM_ERROR
+
+ When a custom fetch script fails to fetch the requested content,
+ it must set this variable to a short one-line message describing
+ the reason for failure.
+
+#]=======================================================================]
#=============================================================================
-# Copyright 2010-2013 Kitware, Inc.
+# Copyright 2010-2015 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
@@ -162,12 +332,63 @@ function(ExternalData_add_test target)
endfunction()
function(ExternalData_add_target target)
- if(NOT ExternalData_URL_TEMPLATES)
- message(FATAL_ERROR "ExternalData_URL_TEMPLATES is not set!")
+ if(NOT ExternalData_URL_TEMPLATES AND NOT ExternalData_OBJECT_STORES)
+ message(FATAL_ERROR
+ "Neither ExternalData_URL_TEMPLATES nor ExternalData_OBJECT_STORES is set!")
endif()
if(NOT ExternalData_OBJECT_STORES)
set(ExternalData_OBJECT_STORES ${CMAKE_BINARY_DIR}/ExternalData/Objects)
endif()
+ set(_ExternalData_CONFIG_CODE "")
+
+ # Store custom script configuration.
+ foreach(url_template IN LISTS ExternalData_URL_TEMPLATES)
+ if("${url_template}" MATCHES "^ExternalDataCustomScript://([^/]*)/(.*)$")
+ set(key "${CMAKE_MATCH_1}")
+ if(key MATCHES "^[A-Za-z_][A-Za-z0-9_]*$")
+ if(ExternalData_CUSTOM_SCRIPT_${key})
+ if(IS_ABSOLUTE "${ExternalData_CUSTOM_SCRIPT_${key}}")
+ string(CONCAT _ExternalData_CONFIG_CODE "${_ExternalData_CONFIG_CODE}\n"
+ "set(ExternalData_CUSTOM_SCRIPT_${key} \"${ExternalData_CUSTOM_SCRIPT_${key}}\")")
+ else()
+ message(FATAL_ERROR
+ "No ExternalData_CUSTOM_SCRIPT_${key} is not set to a full path:\n"
+ " ${ExternalData_CUSTOM_SCRIPT_${key}}")
+ endif()
+ else()
+ message(FATAL_ERROR
+ "No ExternalData_CUSTOM_SCRIPT_${key} is set for URL template:\n"
+ " ${url_template}")
+ endif()
+ else()
+ message(FATAL_ERROR
+ "Bad ExternalDataCustomScript key '${key}' in URL template:\n"
+ " ${url_template}\n"
+ "The key must be a valid C identifier.")
+ endif()
+ endif()
+
+ # Store custom algorithm name to URL component maps.
+ if("${url_template}" MATCHES "%\\(algo:([^)]*)\\)")
+ set(key "${CMAKE_MATCH_1}")
+ if(key MATCHES "^[A-Za-z_][A-Za-z0-9_]*$")
+ string(REPLACE "|" ";" _algos "${_ExternalData_REGEX_ALGO}")
+ foreach(algo ${_algos})
+ if(DEFINED ExternalData_URL_ALGO_${algo}_${key})
+ string(CONCAT _ExternalData_CONFIG_CODE "${_ExternalData_CONFIG_CODE}\n"
+ "set(ExternalData_URL_ALGO_${algo}_${key} \"${ExternalData_URL_ALGO_${algo}_${key}}\")")
+ endif()
+ endforeach()
+ else()
+ message(FATAL_ERROR
+ "Bad %(algo:${key}) in URL template:\n"
+ " ${url_template}\n"
+ "The transform name must be a valid C identifier.")
+ endif()
+ endif()
+ endforeach()
+
+ # Store configuration for use by build-time script.
set(config ${CMAKE_CURRENT_BINARY_DIR}/${target}_config.cmake)
configure_file(${_ExternalData_SELF_DIR}/ExternalData_config.cmake.in ${config} @ONLY)
@@ -251,8 +472,7 @@ function(ExternalData_expand_arguments target outArgsVar)
foreach(piece IN LISTS pieces)
if("x${piece}" MATCHES "^x${data_regex}$")
# Replace this DATA{}-piece with a file path.
- string(REGEX REPLACE "${data_regex}" "\\1" data "${piece}")
- _ExternalData_arg("${target}" "${piece}" "${data}" file)
+ _ExternalData_arg("${target}" "${piece}" "${CMAKE_MATCH_1}" file)
set(outArg "${outArg}${file}")
else()
# No replacement needed for this piece.
@@ -381,19 +601,23 @@ function(_ExternalData_arg target arg options var_file)
set(external "") # Entries external to the source tree.
set(internal "") # Entries internal to the source tree.
set(have_original ${data_is_directory})
+ set(have_original_as_dir 0)
# Process options.
set(series_option "")
+ set(recurse_option "")
set(associated_files "")
set(associated_regex "")
foreach(opt ${options})
- if("x${opt}" MATCHES "^xREGEX:[^:/]+$")
- # Regular expression to match associated files.
- string(REGEX REPLACE "^REGEX:" "" regex "${opt}")
- list(APPEND associated_regex "${regex}")
+ # Regular expression to match associated files.
+ if("x${opt}" MATCHES "^xREGEX:([^:/]+)$")
+ list(APPEND associated_regex "${CMAKE_MATCH_1}")
elseif(opt STREQUAL ":")
# Activate series matching.
set(series_option "${opt}")
+ elseif(opt STREQUAL "RECURSE:")
+ # Activate recursive matching in directories.
+ set(recurse_option "${opt}")
elseif("x${opt}" MATCHES "^[^][:/*?]+$")
# Specific associated file.
list(APPEND associated_files "${opt}")
@@ -410,6 +634,9 @@ function(_ExternalData_arg target arg options var_file)
if(associated_files OR associated_regex)
message(FATAL_ERROR "Series option \"${series_option}\" not allowed with associated files.")
endif()
+ if(recurse_option)
+ message(FATAL_ERROR "Recurse option \"${recurse_option}\" allowed only with directories.")
+ endif()
# Load a whole file series.
_ExternalData_arg_series()
elseif(data_is_directory)
@@ -422,6 +649,9 @@ function(_ExternalData_arg target arg options var_file)
"must list associated files.")
endif()
else()
+ if(recurse_option)
+ message(FATAL_ERROR "Recurse option \"${recurse_option}\" allowed only with directories.")
+ endif()
# Load the named data file.
_ExternalData_arg_single()
if(associated_files OR associated_regex)
@@ -431,11 +661,18 @@ function(_ExternalData_arg target arg options var_file)
endif()
if(NOT have_original)
- message(FATAL_ERROR "Data file referenced by argument\n"
+ if(have_original_as_dir)
+ set(msg_kind FATAL_ERROR)
+ set(msg "that is directory instead of a file!")
+ else()
+ set(msg_kind AUTHOR_WARNING)
+ set(msg "that does not exist as a file (with or without an extension)!")
+ endif()
+ message(${msg_kind} "Data file referenced by argument\n"
" ${arg}\n"
"corresponds to source tree path\n"
" ${reldata}\n"
- "that does not exist as a file (with or without an extension)!")
+ "${msg}")
endif()
if(external)
@@ -462,11 +699,18 @@ macro(_ExternalData_arg_associated)
set(reldir "${reldir}/")
endif()
_ExternalData_exact_regex(reldir_regex "${reldir}")
+ if(recurse_option)
+ set(glob GLOB_RECURSE)
+ set(reldir_regex "${reldir_regex}(.+/)?")
+ else()
+ set(glob GLOB)
+ endif()
# Find files named explicitly.
foreach(file ${associated_files})
_ExternalData_exact_regex(file_regex "${file}")
- _ExternalData_arg_find_files("${reldir}${file}" "${reldir_regex}${file_regex}")
+ _ExternalData_arg_find_files(${glob} "${reldir}${file}"
+ "${reldir_regex}${file_regex}")
endforeach()
# Find files matching the given regular expressions.
@@ -476,13 +720,13 @@ macro(_ExternalData_arg_associated)
set(all "${all}${sep}${reldir_regex}${regex}")
set(sep "|")
endforeach()
- _ExternalData_arg_find_files("${reldir}" "${all}")
+ _ExternalData_arg_find_files(${glob} "${reldir}" "${all}")
endmacro()
macro(_ExternalData_arg_single)
# Match only the named data by itself.
_ExternalData_exact_regex(data_regex "${reldata}")
- _ExternalData_arg_find_files("${reldata}" "${data_regex}")
+ _ExternalData_arg_find_files(GLOB "${reldata}" "${data_regex}")
endmacro()
macro(_ExternalData_arg_series)
@@ -537,12 +781,15 @@ macro(_ExternalData_arg_series)
# Then match base, number, and extension.
_ExternalData_exact_regex(series_base "${relbase}")
_ExternalData_exact_regex(series_ext "${ext}")
- _ExternalData_arg_find_files("${relbase}*${ext}"
+ _ExternalData_arg_find_files(GLOB "${relbase}*${ext}"
"${series_base}${series_match}${series_ext}")
endmacro()
-function(_ExternalData_arg_find_files pattern regex)
- file(GLOB globbed RELATIVE "${top_src}" "${top_src}/${pattern}*")
+function(_ExternalData_arg_find_files glob pattern regex)
+ cmake_policy(PUSH)
+ cmake_policy(SET CMP0009 NEW)
+ file(${glob} globbed RELATIVE "${top_src}" "${top_src}/${pattern}*")
+ cmake_policy(POP)
foreach(entry IN LISTS globbed)
if("x${entry}" MATCHES "^x(.*)(\\.(${_ExternalData_REGEX_EXT}))$")
set(relname "${CMAKE_MATCH_1}")
@@ -552,27 +799,33 @@ function(_ExternalData_arg_find_files pattern regex)
set(alg "")
endif()
if("x${relname}" MATCHES "^x${regex}$" # matches
- AND NOT IS_DIRECTORY "${top_src}/${entry}" # not a directory
AND NOT "x${relname}" MATCHES "(^x|/)\\.ExternalData_" # not staged obj
)
- set(name "${top_src}/${relname}")
- set(file "${top_bin}/${relname}")
- if(alg)
- list(APPEND external "${file}|${name}|${alg}")
- elseif(ExternalData_LINK_CONTENT)
- _ExternalData_link_content("${name}" alg)
- list(APPEND external "${file}|${name}|${alg}")
- elseif(NOT top_same)
- list(APPEND internal "${file}|${name}")
- endif()
- if("${relname}" STREQUAL "${reldata}")
- set(have_original 1)
+ if(IS_DIRECTORY "${top_src}/${entry}")
+ if("${relname}" STREQUAL "${reldata}")
+ set(have_original_as_dir 1)
+ endif()
+ else()
+ set(name "${top_src}/${relname}")
+ set(file "${top_bin}/${relname}")
+ if(alg)
+ list(APPEND external "${file}|${name}|${alg}")
+ elseif(ExternalData_LINK_CONTENT)
+ _ExternalData_link_content("${name}" alg)
+ list(APPEND external "${file}|${name}|${alg}")
+ elseif(NOT top_same)
+ list(APPEND internal "${file}|${name}")
+ endif()
+ if("${relname}" STREQUAL "${reldata}")
+ set(have_original 1)
+ endif()
endif()
endif()
endforeach()
set(external "${external}" PARENT_SCOPE)
set(internal "${internal}" PARENT_SCOPE)
set(have_original "${have_original}" PARENT_SCOPE)
+ set(have_original_as_dir "${have_original_as_dir}" PARENT_SCOPE)
endfunction()
#-----------------------------------------------------------------------------
@@ -585,8 +838,9 @@ endif()
if(ExternalData_CONFIG)
include(${ExternalData_CONFIG})
endif()
-if(NOT ExternalData_URL_TEMPLATES)
- message(FATAL_ERROR "No ExternalData_URL_TEMPLATES set!")
+if(NOT ExternalData_URL_TEMPLATES AND NOT ExternalData_OBJECT_STORES)
+ message(FATAL_ERROR
+ "Neither ExternalData_URL_TEMPLATES nor ExternalData_OBJECT_STORES is set!")
endif()
function(_ExternalData_link_or_copy src dst)
@@ -595,7 +849,7 @@ function(_ExternalData_link_or_copy src dst)
file(MAKE_DIRECTORY "${dst_dir}")
_ExternalData_random(random)
set(tmp "${dst}.tmp${random}")
- if(UNIX)
+ if(UNIX AND NOT ExternalData_NO_SYMLINKS)
# Create a symbolic link.
set(tgt "${src}")
if(relative_top)
@@ -661,6 +915,30 @@ function(_ExternalData_download_file url file err_var msg_var)
set("${msg_var}" "${msg}" PARENT_SCOPE)
endfunction()
+function(_ExternalData_custom_fetch key loc file err_var msg_var)
+ if(NOT ExternalData_CUSTOM_SCRIPT_${key})
+ set(err 1)
+ set(msg "No ExternalData_CUSTOM_SCRIPT_${key} set!")
+ elseif(NOT EXISTS "${ExternalData_CUSTOM_SCRIPT_${key}}")
+ set(err 1)
+ set(msg "No '${ExternalData_CUSTOM_SCRIPT_${key}}' exists!")
+ else()
+ set(ExternalData_CUSTOM_LOCATION "${loc}")
+ set(ExternalData_CUSTOM_FILE "${file}")
+ unset(ExternalData_CUSTOM_ERROR)
+ include("${ExternalData_CUSTOM_SCRIPT_${key}}")
+ if(DEFINED ExternalData_CUSTOM_ERROR)
+ set(err 1)
+ set(msg "${ExternalData_CUSTOM_ERROR}")
+ else()
+ set(err 0)
+ set(msg "no error")
+ endif()
+ endif()
+ set("${err_var}" "${err}" PARENT_SCOPE)
+ set("${msg_var}" "${msg}" PARENT_SCOPE)
+endfunction()
+
function(_ExternalData_download_object name hash algo var_obj)
# Search all object stores for an existing object.
foreach(dir ${ExternalData_OBJECT_STORES})
@@ -683,8 +961,22 @@ function(_ExternalData_download_object name hash algo var_obj)
foreach(url_template IN LISTS ExternalData_URL_TEMPLATES)
string(REPLACE "%(hash)" "${hash}" url_tmp "${url_template}")
string(REPLACE "%(algo)" "${algo}" url "${url_tmp}")
+ if(url MATCHES "^(.*)%\\(algo:([A-Za-z_][A-Za-z0-9_]*)\\)(.*)$")
+ set(lhs "${CMAKE_MATCH_1}")
+ set(key "${CMAKE_MATCH_2}")
+ set(rhs "${CMAKE_MATCH_3}")
+ if(DEFINED ExternalData_URL_ALGO_${algo}_${key})
+ set(url "${lhs}${ExternalData_URL_ALGO_${algo}_${key}}${rhs}")
+ else()
+ set(url "${lhs}${algo}${rhs}")
+ endif()
+ endif()
message(STATUS "Fetching \"${url}\"")
- _ExternalData_download_file("${url}" "${tmp}" err errMsg)
+ if(url MATCHES "^ExternalDataCustomScript://([A-Za-z_][A-Za-z0-9_]*)/(.*)$")
+ _ExternalData_custom_fetch("${CMAKE_MATCH_1}" "${CMAKE_MATCH_2}" "${tmp}" err errMsg)
+ else()
+ _ExternalData_download_file("${url}" "${tmp}" err errMsg)
+ endif()
set(tried "${tried}\n ${url}")
if(err)
set(tried "${tried} (${errMsg})")
@@ -714,6 +1006,9 @@ function(_ExternalData_download_object name hash algo var_obj)
set(obj "${staged}")
message(STATUS "Staged object: \"${obj}\"")
else()
+ if(NOT tried)
+ set(tried "\n (No ExternalData_URL_TEMPLATES given)")
+ endif()
message(FATAL_ERROR "Object ${algo}=${hash} not found at:${tried}")
endif()
diff --git a/Modules/ExternalData_config.cmake.in b/Modules/ExternalData_config.cmake.in
index 0858f5368..18be6b31a 100644
--- a/Modules/ExternalData_config.cmake.in
+++ b/Modules/ExternalData_config.cmake.in
@@ -2,3 +2,5 @@ set(ExternalData_OBJECT_STORES "@ExternalData_OBJECT_STORES@")
set(ExternalData_URL_TEMPLATES "@ExternalData_URL_TEMPLATES@")
set(ExternalData_TIMEOUT_INACTIVITY "@ExternalData_TIMEOUT_INACTIVITY@")
set(ExternalData_TIMEOUT_ABSOLUTE "@ExternalData_TIMEOUT_ABSOLUTE@")
+set(ExternalData_NO_SYMLINKS "@ExternalData_NO_SYMLINKS@")
+@_ExternalData_CONFIG_CODE@
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 0781ea146..249658d62 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -1,166 +1,375 @@
-# - Create custom targets to build projects in external trees
-# The 'ExternalProject_Add' function creates a custom target to drive
-# download, update/patch, configure, build, install and test steps of an
-# external project:
-# ExternalProject_Add(<name> # Name for custom target
-# [DEPENDS projects...] # Targets on which the project depends
-# [PREFIX dir] # Root dir for entire project
-# [LIST_SEPARATOR sep] # Sep to be replaced by ; in cmd lines
-# [TMP_DIR dir] # Directory to store temporary files
-# [STAMP_DIR dir] # Directory to store step timestamps
-# #--Download step--------------
-# [DOWNLOAD_NAME fname] # File name to store (if not end of URL)
-# [DOWNLOAD_DIR dir] # Directory to store downloaded files
-# [DOWNLOAD_COMMAND cmd...] # Command to download source tree
-# [CVS_REPOSITORY cvsroot] # CVSROOT of CVS repository
-# [CVS_MODULE mod] # Module to checkout from CVS repo
-# [CVS_TAG tag] # Tag to checkout from CVS repo
-# [SVN_REPOSITORY url] # URL of Subversion repo
-# [SVN_REVISION rev] # Revision to checkout from Subversion repo
-# [SVN_USERNAME john ] # Username for Subversion checkout and update
-# [SVN_PASSWORD doe ] # Password for Subversion checkout and update
-# [SVN_TRUST_CERT 1 ] # Trust the Subversion server site certificate
-# [GIT_REPOSITORY url] # URL of git repo
-# [GIT_TAG tag] # Git branch name, commit id or tag
-# [HG_REPOSITORY url] # URL of mercurial repo
-# [HG_TAG tag] # Mercurial branch name, commit id or tag
-# [URL /.../src.tgz] # Full path or URL of source
-# [URL_HASH ALGO=value] # Hash of file at URL
-# [URL_MD5 md5] # Equivalent to URL_HASH MD5=md5
-# [TLS_VERIFY bool] # Should certificate for https be checked
-# [TLS_CAINFO file] # Path to a certificate authority file
-# [TIMEOUT seconds] # Time allowed for file download operations
-# #--Update/Patch step----------
-# [UPDATE_COMMAND cmd...] # Source work-tree update command
-# [PATCH_COMMAND cmd...] # Command to patch downloaded source
-# #--Configure step-------------
-# [SOURCE_DIR dir] # Source dir to be used for build
-# [CONFIGURE_COMMAND cmd...] # Build tree configuration command
-# [CMAKE_COMMAND /.../cmake] # Specify alternative cmake executable
-# [CMAKE_GENERATOR gen] # Specify generator for native build
-# [CMAKE_GENERATOR_TOOLSET t] # Generator-specific toolset name
-# [CMAKE_ARGS args...] # Arguments to CMake command line
-# [CMAKE_CACHE_ARGS args...] # Initial cache arguments, of the form -Dvar:string=on
-# #--Build step-----------------
-# [BINARY_DIR dir] # Specify build dir location
-# [BUILD_COMMAND cmd...] # Command to drive the native build
-# [BUILD_IN_SOURCE 1] # Use source dir for build dir
-# #--Install step---------------
-# [INSTALL_DIR dir] # Installation prefix
-# [INSTALL_COMMAND cmd...] # Command to drive install after build
-# #--Test step------------------
-# [TEST_BEFORE_INSTALL 1] # Add test step executed before install step
-# [TEST_AFTER_INSTALL 1] # Add test step executed after install step
-# [TEST_COMMAND cmd...] # Command to drive test
-# #--Output logging-------------
-# [LOG_DOWNLOAD 1] # Wrap download in script to log output
-# [LOG_UPDATE 1] # Wrap update in script to log output
-# [LOG_CONFIGURE 1] # Wrap configure in script to log output
-# [LOG_BUILD 1] # Wrap build in script to log output
-# [LOG_TEST 1] # Wrap test in script to log output
-# [LOG_INSTALL 1] # Wrap install in script to log output
-# #--Custom targets-------------
-# [STEP_TARGETS st1 st2 ...] # Generate custom targets for these steps
-# )
-# The *_DIR options specify directories for the project, with default
-# directories computed as follows.
-# If the PREFIX option is given to ExternalProject_Add() or the EP_PREFIX
-# directory property is set, then an external project is built and installed
-# under the specified prefix:
-# TMP_DIR = <prefix>/tmp
-# STAMP_DIR = <prefix>/src/<name>-stamp
-# DOWNLOAD_DIR = <prefix>/src
-# SOURCE_DIR = <prefix>/src/<name>
-# BINARY_DIR = <prefix>/src/<name>-build
-# INSTALL_DIR = <prefix>
-# Otherwise, if the EP_BASE directory property is set then components
-# of an external project are stored under the specified base:
-# TMP_DIR = <base>/tmp/<name>
-# STAMP_DIR = <base>/Stamp/<name>
-# DOWNLOAD_DIR = <base>/Download/<name>
-# SOURCE_DIR = <base>/Source/<name>
-# BINARY_DIR = <base>/Build/<name>
-# INSTALL_DIR = <base>/Install/<name>
-# If no PREFIX, EP_PREFIX, or EP_BASE is specified then the default
-# is to set PREFIX to "<name>-prefix".
-# Relative paths are interpreted with respect to the build directory
-# corresponding to the source directory in which ExternalProject_Add is
-# invoked.
-#
-# If SOURCE_DIR is explicitly set to an existing directory the project
-# will be built from it.
-# Otherwise a download step must be specified using one of the
-# DOWNLOAD_COMMAND, CVS_*, SVN_*, or URL options.
-# The URL option may refer locally to a directory or source tarball,
-# or refer to a remote tarball (e.g. http://.../src.tgz).
-#
-# The 'ExternalProject_Add_Step' function adds a custom step to an external
-# project:
-# ExternalProject_Add_Step(<name> <step> # Names of project and custom step
-# [COMMAND cmd...] # Command line invoked by this step
-# [COMMENT "text..."] # Text printed when step executes
-# [DEPENDEES steps...] # Steps on which this step depends
-# [DEPENDERS steps...] # Steps that depend on this step
-# [DEPENDS files...] # Files on which this step depends
-# [ALWAYS 1] # No stamp file, step always runs
-# [WORKING_DIRECTORY dir] # Working directory for command
-# [LOG 1] # Wrap step in script to log output
-# )
-# The command line, comment, and working directory of every standard
-# and custom step is processed to replace tokens
-# <SOURCE_DIR>,
-# <BINARY_DIR>,
-# <INSTALL_DIR>,
-# and <TMP_DIR>
-# with corresponding property values.
-#
-# Any builtin step that specifies a "<step>_COMMAND cmd..." or custom
-# step that specifies a "COMMAND cmd..." may specify additional command
-# lines using the form "COMMAND cmd...". At build time the commands will
-# be executed in order and aborted if any one fails. For example:
-# ... BUILD_COMMAND make COMMAND echo done ...
-# specifies to run "make" and then "echo done" during the build step.
-# Whether the current working directory is preserved between commands
-# is not defined. Behavior of shell operators like "&&" is not defined.
-#
-# The 'ExternalProject_Get_Property' function retrieves external project
-# target properties:
-# ExternalProject_Get_Property(<name> [prop1 [prop2 [...]]])
-# It stores property values in variables of the same name.
-# Property names correspond to the keyword argument names of
-# 'ExternalProject_Add'.
-#
-# The 'ExternalProject_Add_StepTargets' function generates custom targets for
-# the steps listed:
-# ExternalProject_Add_StepTargets(<name> [step1 [step2 [...]]])
-#
-# If STEP_TARGETS is set then ExternalProject_Add_StepTargets is automatically
-# called at the end of matching calls to ExternalProject_Add_Step. Pass
-# STEP_TARGETS explicitly to individual ExternalProject_Add calls, or
-# implicitly to all ExternalProject_Add calls by setting the directory property
-# EP_STEP_TARGETS.
-#
-# If STEP_TARGETS is not set, clients may still manually call
-# ExternalProject_Add_StepTargets after calling ExternalProject_Add or
-# ExternalProject_Add_Step.
-#
-# This functionality is provided to make it easy to drive the steps
-# independently of each other by specifying targets on build command lines.
-# For example, you may be submitting to a sub-project based dashboard, where
-# you want to drive the configure portion of the build, then submit to the
-# dashboard, followed by the build portion, followed by tests. If you invoke
-# a custom target that depends on a step halfway through the step dependency
-# chain, then all the previous steps will also run to ensure everything is
-# up to date.
-#
-# For example, to drive configure, build and test steps independently for each
-# ExternalProject_Add call in your project, write the following line prior to
-# any ExternalProject_Add calls in your CMakeLists file:
-#
-# set_property(DIRECTORY PROPERTY EP_STEP_TARGETS configure build test)
+#[=======================================================================[.rst:
+ExternalProject
+---------------
+
+Create custom targets to build projects in external trees
+
+.. command:: ExternalProject_Add
+
+ The ``ExternalProject_Add`` function creates a custom target to drive
+ download, update/patch, configure, build, install and test steps of an
+ external project::
+
+ ExternalProject_Add(<name> [<option>...])
+
+ General options are:
+
+ ``DEPENDS <projects>...``
+ Targets on which the project depends
+ ``PREFIX <dir>``
+ Root dir for entire project
+ ``LIST_SEPARATOR <sep>``
+ Sep to be replaced by ; in cmd lines
+ ``TMP_DIR <dir>``
+ Directory to store temporary files
+ ``STAMP_DIR <dir>``
+ Directory to store step timestamps
+ ``EXCLUDE_FROM_ALL 1``
+ The "all" target does not depend on this
+
+ Download step options are:
+
+ ``DOWNLOAD_NAME <fname>``
+ File name to store (if not end of URL)
+ ``DOWNLOAD_DIR <dir>``
+ Directory to store downloaded files
+ ``DOWNLOAD_COMMAND <cmd>...``
+ Command to download source tree
+ ``DOWNLOAD_NO_PROGRESS 1``
+ Disable download progress reports
+ ``CVS_REPOSITORY <cvsroot>``
+ CVSROOT of CVS repository
+ ``CVS_MODULE <mod>``
+ Module to checkout from CVS repo
+ ``CVS_TAG <tag>``
+ Tag to checkout from CVS repo
+ ``SVN_REPOSITORY <url>``
+ URL of Subversion repo
+ ``SVN_REVISION -r<rev>``
+ Revision to checkout from Subversion repo
+ ``SVN_USERNAME <username>``
+ Username for Subversion checkout and update
+ ``SVN_PASSWORD <password>``
+ Password for Subversion checkout and update
+ ``SVN_TRUST_CERT 1``
+ Trust the Subversion server site certificate
+ ``GIT_REPOSITORY <url>``
+ URL of git repo
+ ``GIT_TAG <tag>``
+ Git branch name, commit id or tag
+ ``GIT_REMOTE_NAME <name>``
+ The optional name of the remote, default to ``origin``
+ ``GIT_SUBMODULES <module>...``
+ Git submodules that shall be updated, all if empty
+ ``HG_REPOSITORY <url>``
+ URL of mercurial repo
+ ``HG_TAG <tag>``
+ Mercurial branch name, commit id or tag
+ ``URL /.../src.tgz``
+ Full path or URL of source
+ ``URL_HASH ALGO=value``
+ Hash of file at URL
+ ``URL_MD5 md5``
+ Equivalent to URL_HASH MD5=md5
+ ``TLS_VERIFY <bool>``
+ Should certificate for https be checked
+ ``TLS_CAINFO <file>``
+ Path to a certificate authority file
+ ``TIMEOUT <seconds>``
+ Time allowed for file download operations
+
+ Update/Patch step options are:
+
+ ``UPDATE_COMMAND <cmd>...``
+ Source work-tree update command
+ ``UPDATE_DISCONNECTED 1``
+ Never update automatically from the remote repository
+ ``PATCH_COMMAND <cmd>...``
+ Command to patch downloaded source
+
+ Configure step options are:
+
+ ``SOURCE_DIR <dir>``
+ Source dir to be used for build
+ ``CONFIGURE_COMMAND <cmd>...``
+ Build tree configuration command
+ ``CMAKE_COMMAND /.../cmake``
+ Specify alternative cmake executable
+ ``CMAKE_GENERATOR <gen>``
+ Specify generator for native build
+ ``CMAKE_GENERATOR_PLATFORM <platform>``
+ Generator-specific platform name
+ ``CMAKE_GENERATOR_TOOLSET <toolset>``
+ Generator-specific toolset name
+ ``CMAKE_ARGS <arg>...``
+ Arguments to CMake command line.
+ These arguments are passed to CMake command line, and can contain
+ arguments other than cache values, see also
+ :manual:`CMake Options <cmake(1)>`. Arguments in the form
+ ``-Dvar:string=on`` are always passed to the command line, and
+ therefore cannot be changed by the user.
+ Arguments may use
+ :manual:`generator expressions <cmake-generator-expressions(7)>`.
+ ``CMAKE_CACHE_ARGS <arg>...``
+ Initial cache arguments, of the form ``-Dvar:string=on``.
+ These arguments are written in a pre-load a script that populates
+ CMake cache, see also :manual:`cmake -C <cmake(1)>`. This allows to
+ overcome command line length limits.
+ These arguments are :command:`set` using the ``FORCE`` argument,
+ and therefore cannot be changed by the user.
+ Arguments may use
+ :manual:`generator expressions <cmake-generator-expressions(7)>`.
+ ``CMAKE_CACHE_DEFAULT_ARGS <arg>...``
+ Initial default cache arguments, of the form ``-Dvar:string=on``.
+ These arguments are written in a pre-load a script that populates
+ CMake cache, see also :manual:`cmake -C <cmake(1)>`. This allows to
+ overcome command line length limits.
+ These arguments can be used as default value that will be set if no
+ previous value is found in the cache, and that the user can change
+ later.
+ Arguments may use
+ :manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+ Build step options are:
+
+ ``BINARY_DIR <dir>``
+ Specify build dir location
+ ``BUILD_COMMAND <cmd>...``
+ Command to drive the native build
+ ``BUILD_IN_SOURCE 1``
+ Use source dir for build dir
+ ``BUILD_ALWAYS 1``
+ No stamp file, build step always runs
+ ``BUILD_BYPRODUCTS <file>...``
+ Files that will be generated by the build command but may or may
+ not have their modification time updated by subsequent builds.
+
+ Install step options are:
+
+ ``INSTALL_DIR <dir>``
+ Installation prefix
+ ``INSTALL_COMMAND <cmd>...``
+ Command to drive install after build
+
+ Test step options are:
+
+ ``TEST_BEFORE_INSTALL 1``
+ Add test step executed before install step
+ ``TEST_AFTER_INSTALL 1``
+ Add test step executed after install step
+ ``TEST_EXCLUDE_FROM_MAIN 1``
+ Main target does not depend on the test step
+ ``TEST_COMMAND <cmd>...``
+ Command to drive test
+
+ Output logging options are:
+
+ ``LOG_DOWNLOAD 1``
+ Wrap download in script to log output
+ ``LOG_UPDATE 1``
+ Wrap update in script to log output
+ ``LOG_CONFIGURE 1``
+ Wrap configure in script to log output
+ ``LOG_BUILD 1``
+ Wrap build in script to log output
+ ``LOG_TEST 1``
+ Wrap test in script to log output
+ ``LOG_INSTALL 1``
+ Wrap install in script to log output
+
+ Steps can be given direct access to the terminal if possible. With
+ the :generator:`Ninja` generator, this places the steps in the
+ ``console`` :prop_gbl:`pool <JOB_POOLS>`. Options are:
+
+ ``USES_TERMINAL_DOWNLOAD 1``
+ Give download terminal access.
+ ``USES_TERMINAL_UPDATE 1``
+ Give update terminal access.
+ ``USES_TERMINAL_CONFIGURE 1``
+ Give configure terminal access.
+ ``USES_TERMINAL_BUILD 1``
+ Give build terminal access.
+ ``USES_TERMINAL_TEST 1``
+ Give test terminal access.
+ ``USES_TERMINAL_INSTALL 1``
+ Give install terminal access.
+
+ Other options are:
+
+ ``STEP_TARGETS <step-target>...``
+ Generate custom targets for these steps
+ ``INDEPENDENT_STEP_TARGETS <step-target>...``
+ Generate custom targets for these steps that do not depend on other
+ external projects even if a dependency is set
+
+ The ``*_DIR`` options specify directories for the project, with default
+ directories computed as follows. If the ``PREFIX`` option is given to
+ ``ExternalProject_Add()`` or the ``EP_PREFIX`` directory property is set,
+ then an external project is built and installed under the specified prefix::
+
+ TMP_DIR = <prefix>/tmp
+ STAMP_DIR = <prefix>/src/<name>-stamp
+ DOWNLOAD_DIR = <prefix>/src
+ SOURCE_DIR = <prefix>/src/<name>
+ BINARY_DIR = <prefix>/src/<name>-build
+ INSTALL_DIR = <prefix>
+
+ Otherwise, if the ``EP_BASE`` directory property is set then components
+ of an external project are stored under the specified base::
+
+ TMP_DIR = <base>/tmp/<name>
+ STAMP_DIR = <base>/Stamp/<name>
+ DOWNLOAD_DIR = <base>/Download/<name>
+ SOURCE_DIR = <base>/Source/<name>
+ BINARY_DIR = <base>/Build/<name>
+ INSTALL_DIR = <base>/Install/<name>
+
+ If no ``PREFIX``, ``EP_PREFIX``, or ``EP_BASE`` is specified then the
+ default is to set ``PREFIX`` to ``<name>-prefix``. Relative paths are
+ interpreted with respect to the build directory corresponding to the
+ source directory in which ``ExternalProject_Add`` is invoked.
+
+ If ``SOURCE_DIR`` is explicitly set to an existing directory the project
+ will be built from it. Otherwise a download step must be specified
+ using one of the ``DOWNLOAD_COMMAND``, ``CVS_*``, ``SVN_*``, or ``URL``
+ options. The ``URL`` option may refer locally to a directory or source
+ tarball, or refer to a remote tarball (e.g. ``http://.../src.tgz``).
+
+ If ``UPDATE_DISCONNECTED`` is set, the update step is not executed
+ automatically when building the main target. The update step can still
+ be added as a step target and called manually. This is useful if you
+ want to allow to build the project when you are disconnected from the
+ network (you might still need the network for the download step).
+ This is disabled by default.
+ The directory property ``EP_UPDATE_DISCONNECTED`` can be used to change
+ the default value for all the external projects in the current
+ directory and its subdirectories.
+
+.. command:: ExternalProject_Add_Step
+
+ The ``ExternalProject_Add_Step`` function adds a custom step to an
+ external project::
+
+ ExternalProject_Add_Step(<name> <step> [<option>...])
+
+ Options are:
+
+ ``COMMAND <cmd>...``
+ Command line invoked by this step
+ ``COMMENT "<text>..."``
+ Text printed when step executes
+ ``DEPENDEES <step>...``
+ Steps on which this step depends
+ ``DEPENDERS <step>...``
+ Steps that depend on this step
+ ``DEPENDS <file>...``
+ Files on which this step depends
+ ``BYPRODUCTS <file>...``
+ Files that will be generated by this step but may or may not
+ have their modification time updated by subsequent builds.
+ ``ALWAYS 1``
+ No stamp file, step always runs
+ ``EXCLUDE_FROM_MAIN 1``
+ Main target does not depend on this step
+ ``WORKING_DIRECTORY <dir>``
+ Working directory for command
+ ``LOG 1``
+ Wrap step in script to log output
+ ``USES_TERMINAL 1``
+ Give the step direct access to the terminal if possible.
+
+ The command line, comment, working directory, and byproducts of every
+ standard and custom step are processed to replace tokens ``<SOURCE_DIR>``,
+ ``<BINARY_DIR>``, ``<INSTALL_DIR>``, and ``<TMP_DIR>`` with
+ corresponding property values.
+
+Any builtin step that specifies a ``<step>_COMMAND cmd...`` or custom
+step that specifies a ``COMMAND cmd...`` may specify additional command
+lines using the form ``COMMAND cmd...``. At build time the commands
+will be executed in order and aborted if any one fails. For example::
+
+ ... BUILD_COMMAND make COMMAND echo done ...
+
+specifies to run ``make`` and then ``echo done`` during the build step.
+Whether the current working directory is preserved between commands is
+not defined. Behavior of shell operators like ``&&`` is not defined.
+
+Arguments to ``<step>_COMMAND`` or ``COMMAND`` options may use
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+.. command:: ExternalProject_Get_Property
+
+ The ``ExternalProject_Get_Property`` function retrieves external project
+ target properties::
+
+ ExternalProject_Get_Property(<name> [prop1 [prop2 [...]]])
+
+ It stores property values in variables of the same name. Property
+ names correspond to the keyword argument names of
+ ``ExternalProject_Add``.
+
+.. command:: ExternalProject_Add_StepTargets
+
+ The ``ExternalProject_Add_StepTargets`` function generates custom
+ targets for the steps listed::
+
+ ExternalProject_Add_StepTargets(<name> [NO_DEPENDS] [step1 [step2 [...]]])
+
+If ``NO_DEPENDS`` is set, the target will not depend on the
+dependencies of the complete project. This is usually safe to use for
+the download, update, and patch steps that do not require that all the
+dependencies are updated and built. Using ``NO_DEPENDS`` for other
+of the default steps might break parallel builds, so you should avoid,
+it. For custom steps, you should consider whether or not the custom
+commands requires that the dependencies are configured, built and
+installed.
+
+If ``STEP_TARGETS`` or ``INDEPENDENT_STEP_TARGETS`` is set then
+``ExternalProject_Add_StepTargets`` is automatically called at the end
+of matching calls to ``ExternalProject_Add_Step``. Pass
+``STEP_TARGETS`` or ``INDEPENDENT_STEP_TARGETS`` explicitly to
+individual ``ExternalProject_Add`` calls, or implicitly to all
+``ExternalProject_Add`` calls by setting the directory properties
+``EP_STEP_TARGETS`` and ``EP_INDEPENDENT_STEP_TARGETS``. The
+``INDEPENDENT`` version of the argument and of the property will call
+``ExternalProject_Add_StepTargets`` with the ``NO_DEPENDS`` argument.
+
+If ``STEP_TARGETS`` and ``INDEPENDENT_STEP_TARGETS`` are not set,
+clients may still manually call ``ExternalProject_Add_StepTargets``
+after calling ``ExternalProject_Add`` or ``ExternalProject_Add_Step``.
+
+This functionality is provided to make it easy to drive the steps
+independently of each other by specifying targets on build command
+lines. For example, you may be submitting to a sub-project based
+dashboard, where you want to drive the configure portion of the build,
+then submit to the dashboard, followed by the build portion, followed
+by tests. If you invoke a custom target that depends on a step
+halfway through the step dependency chain, then all the previous steps
+will also run to ensure everything is up to date.
+
+For example, to drive configure, build and test steps independently
+for each ``ExternalProject_Add`` call in your project, write the following
+line prior to any ``ExternalProject_Add`` calls in your ``CMakeLists.txt``
+file::
+
+ set_property(DIRECTORY PROPERTY EP_STEP_TARGETS configure build test)
+
+.. command:: ExternalProject_Add_StepDependencies
+
+ The ``ExternalProject_Add_StepDependencies`` function add some
+ dependencies for some external project step::
+
+ ExternalProject_Add_StepDependencies(<name> <step> [target1 [target2 [...]]])
+
+ This function takes care to set both target and file level
+ dependencies, and will ensure that parallel builds will not break.
+ It should be used instead of :command:`add_dependencies()` when adding
+ a dependency for some of the step targets generated by
+ ``ExternalProject``.
+#]=======================================================================]
#=============================================================================
-# Copyright 2008-2012 Kitware, Inc.
+# Copyright 2008-2013 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
@@ -176,18 +385,18 @@
math(EXPR _ep_documentation_line_count "${CMAKE_CURRENT_LIST_LINE} - 16")
file(STRINGS "${CMAKE_CURRENT_LIST_FILE}" lines
LIMIT_COUNT ${_ep_documentation_line_count}
- REGEX "^# ( \\[[A-Z0-9_]+ [^]]*\\] +#.*$|[A-Za-z0-9_]+\\()")
+ REGEX "^\\.\\. command:: [A-Za-z0-9_]+|^ ``[A-Z0-9_]+ .*``$")
foreach(line IN LISTS lines)
- if("${line}" MATCHES "^# [A-Za-z0-9_]+\\(")
+ if("${line}" MATCHES "^\\.\\. command:: ([A-Za-z0-9_]+)")
if(_ep_func)
set(_ep_keywords_${_ep_func} "${_ep_keywords_${_ep_func}})$")
endif()
- string(REGEX REPLACE "^# ([A-Za-z0-9_]+)\\(.*" "\\1" _ep_func "${line}")
+ set(_ep_func "${CMAKE_MATCH_1}")
#message("function [${_ep_func}]")
set(_ep_keywords_${_ep_func} "^(")
set(_ep_keyword_sep)
- else()
- string(REGEX REPLACE "^# \\[([A-Z0-9_]+) .*" "\\1" _ep_key "${line}")
+ elseif("${line}" MATCHES "^ ``([A-Z0-9_]+) .*``$")
+ set(_ep_key "${CMAKE_MATCH_1}")
#message(" keyword [${_ep_key}]")
set(_ep_keywords_${_ep_func}
"${_ep_keywords_${_ep_func}}${_ep_keyword_sep}${_ep_key}")
@@ -216,7 +425,7 @@ function(_ep_parse_arguments f name ns args)
set(is_value 1)
if(arg MATCHES "^[A-Z][A-Z0-9_][A-Z0-9_]+$" AND
- NOT ((arg STREQUAL "${key}") AND (key STREQUAL "COMMAND")) AND
+ NOT (("x${arg}x" STREQUAL "x${key}x") AND ("x${key}x" STREQUAL "xCOMMANDx")) AND
NOT arg MATCHES "^(TRUE|FALSE)$")
if(_ep_keywords_${f} AND arg MATCHES "${_ep_keywords_${f}}")
set(is_value 0)
@@ -266,12 +475,28 @@ define_property(DIRECTORY PROPERTY "EP_STEP_TARGETS" INHERITED
BRIEF_DOCS
"List of ExternalProject steps that automatically get corresponding targets"
FULL_DOCS
+ "These targets will be dependent on the main target dependencies"
+ "See documentation of the ExternalProject_Add_StepTargets() function in the "
+ "ExternalProject module."
+ )
+
+define_property(DIRECTORY PROPERTY "EP_INDEPENDENT_STEP_TARGETS" INHERITED
+ BRIEF_DOCS
+ "List of ExternalProject steps that automatically get corresponding targets"
+ FULL_DOCS
+ "These targets will not be dependent on the main target dependencies"
"See documentation of the ExternalProject_Add_StepTargets() function in the "
"ExternalProject module."
)
+define_property(DIRECTORY PROPERTY "EP_UPDATE_DISCONNECTED" INHERITED
+ BRIEF_DOCS "Never update automatically from the remote repo."
+ FULL_DOCS
+ "See documentation of the ExternalProject_Add() function in the "
+ "ExternalProject module."
+ )
-function(_ep_write_gitclone_script script_filename source_dir git_EXECUTABLE git_repository git_tag src_name work_dir gitclone_infofile gitclone_stampfile)
+function(_ep_write_gitclone_script script_filename source_dir git_EXECUTABLE git_repository git_tag git_remote_name git_submodules src_name work_dir gitclone_infofile gitclone_stampfile)
file(WRITE ${script_filename}
"if(\"${git_tag}\" STREQUAL \"\")
message(FATAL_ERROR \"Tag for git checkout should not be empty.\")
@@ -301,7 +526,7 @@ set(error_code 1)
set(number_of_tries 0)
while(error_code AND number_of_tries LESS 3)
execute_process(
- COMMAND \"${git_EXECUTABLE}\" clone \"${git_repository}\" \"${src_name}\"
+ COMMAND \"${git_EXECUTABLE}\" clone --origin \"${git_remote_name}\" \"${git_repository}\" \"${src_name}\"
WORKING_DIRECTORY \"${work_dir}\"
RESULT_VARIABLE error_code
)
@@ -325,7 +550,7 @@ if(error_code)
endif()
execute_process(
- COMMAND \"${git_EXECUTABLE}\" submodule init
+ COMMAND \"${git_EXECUTABLE}\" submodule init ${git_submodules}
WORKING_DIRECTORY \"${work_dir}/${src_name}\"
RESULT_VARIABLE error_code
)
@@ -334,7 +559,7 @@ if(error_code)
endif()
execute_process(
- COMMAND \"${git_EXECUTABLE}\" submodule update --recursive
+ COMMAND \"${git_EXECUTABLE}\" submodule update --recursive ${git_submodules}
WORKING_DIRECTORY \"${work_dir}/${src_name}\"
RESULT_VARIABLE error_code
)
@@ -386,7 +611,7 @@ if(error_code)
endif()
execute_process(
- COMMAND \"${hg_EXECUTABLE}\" clone \"${hg_repository}\" \"${src_name}\"
+ COMMAND \"${hg_EXECUTABLE}\" clone -U \"${hg_repository}\" \"${src_name}\"
WORKING_DIRECTORY \"${work_dir}\"
RESULT_VARIABLE error_code
)
@@ -422,7 +647,12 @@ endif()
endfunction()
-function(_ep_write_gitupdate_script script_filename git_EXECUTABLE git_tag git_repository work_dir)
+function(_ep_write_gitupdate_script script_filename git_EXECUTABLE git_tag git_remote_name git_submodules git_repository work_dir)
+ if(NOT GIT_VERSION_STRING VERSION_LESS 1.7.6)
+ set(git_stash_save_options --all --quiet)
+ else()
+ set(git_stash_save_options --quiet)
+ endif()
file(WRITE ${script_filename}
"if(\"${git_tag}\" STREQUAL \"\")
message(FATAL_ERROR \"Tag for git checkout should not be empty.\")
@@ -433,6 +663,7 @@ execute_process(
WORKING_DIRECTORY \"${work_dir}\"
RESULT_VARIABLE error_code
OUTPUT_VARIABLE head_sha
+ OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(error_code)
message(FATAL_ERROR \"Failed to get the hash for HEAD\")
@@ -451,6 +682,17 @@ else()
set(is_remote_ref 0)
endif()
+# Tag is in the form <remote>/<tag> (i.e. origin/master) we must strip
+# the remote from the tag.
+if(\"\${show_ref_output}\" MATCHES \"refs/remotes/${git_tag}\")
+ string(REGEX MATCH \"^([^/]+)/(.+)$\" _unused \"${git_tag}\")
+ set(git_remote \"\${CMAKE_MATCH_1}\")
+ set(git_tag \"\${CMAKE_MATCH_2}\")
+else()
+ set(git_remote \"${git_remote_name}\")
+ set(git_tag \"${git_tag}\")
+endif()
+
# This will fail if the tag does not exist (it probably has not been fetched
# yet).
execute_process(
@@ -458,6 +700,7 @@ execute_process(
WORKING_DIRECTORY \"${work_dir}\"
RESULT_VARIABLE error_code
OUTPUT_VARIABLE tag_sha
+ OUTPUT_STRIP_TRAILING_WHITESPACE
)
# Is the hash checkout out that we want?
@@ -471,17 +714,98 @@ if(error_code OR is_remote_ref OR NOT (\"\${tag_sha}\" STREQUAL \"\${head_sha}\"
message(FATAL_ERROR \"Failed to fetch repository '${git_repository}'\")
endif()
- execute_process(
- COMMAND \"${git_EXECUTABLE}\" checkout ${git_tag}
- WORKING_DIRECTORY \"${work_dir}\"
- RESULT_VARIABLE error_code
- )
- if(error_code)
- message(FATAL_ERROR \"Failed to checkout tag: '${git_tag}'\")
+ if(is_remote_ref)
+ # Check if stash is needed
+ execute_process(
+ COMMAND \"${git_EXECUTABLE}\" status --porcelain
+ WORKING_DIRECTORY \"${work_dir}\"
+ RESULT_VARIABLE error_code
+ OUTPUT_VARIABLE repo_status
+ )
+ if(error_code)
+ message(FATAL_ERROR \"Failed to get the status\")
+ endif()
+ string(LENGTH \"\${repo_status}\" need_stash)
+
+ # If not in clean state, stash changes in order to be able to be able to
+ # perform git pull --rebase
+ if(need_stash)
+ execute_process(
+ COMMAND \"${git_EXECUTABLE}\" stash save ${git_stash_save_options}
+ WORKING_DIRECTORY \"${work_dir}\"
+ RESULT_VARIABLE error_code
+ )
+ if(error_code)
+ message(FATAL_ERROR \"Failed to stash changes\")
+ endif()
+ endif()
+
+ # Pull changes from the remote branch
+ execute_process(
+ COMMAND \"${git_EXECUTABLE}\" rebase \${git_remote}/\${git_tag}
+ WORKING_DIRECTORY \"${work_dir}\"
+ RESULT_VARIABLE error_code
+ )
+ if(error_code)
+ # Rebase failed: Restore previous state.
+ execute_process(
+ COMMAND \"${git_EXECUTABLE}\" rebase --abort
+ WORKING_DIRECTORY \"${work_dir}\"
+ )
+ if(need_stash)
+ execute_process(
+ COMMAND \"${git_EXECUTABLE}\" stash pop --index --quiet
+ WORKING_DIRECTORY \"${work_dir}\"
+ )
+ endif()
+ message(FATAL_ERROR \"\\nFailed to rebase in: '${work_dir}/${src_name}'.\\nYou will have to resolve the conflicts manually\")
+ endif()
+
+ if(need_stash)
+ execute_process(
+ COMMAND \"${git_EXECUTABLE}\" stash pop --index --quiet
+ WORKING_DIRECTORY \"${work_dir}\"
+ RESULT_VARIABLE error_code
+ )
+ if(error_code)
+ # Stash pop --index failed: Try again dropping the index
+ execute_process(
+ COMMAND \"${git_EXECUTABLE}\" reset --hard --quiet
+ WORKING_DIRECTORY \"${work_dir}\"
+ RESULT_VARIABLE error_code
+ )
+ execute_process(
+ COMMAND \"${git_EXECUTABLE}\" stash pop --quiet
+ WORKING_DIRECTORY \"${work_dir}\"
+ RESULT_VARIABLE error_code
+ )
+ if(error_code)
+ # Stash pop failed: Restore previous state.
+ execute_process(
+ COMMAND \"${git_EXECUTABLE}\" reset --hard --quiet \${head_sha}
+ WORKING_DIRECTORY \"${work_dir}\"
+ )
+ execute_process(
+ COMMAND \"${git_EXECUTABLE}\" stash pop --index --quiet
+ WORKING_DIRECTORY \"${work_dir}\"
+ )
+ message(FATAL_ERROR \"\\nFailed to unstash changes in: '${work_dir}/${src_name}'.\\nYou will have to resolve the conflicts manually\")
+ endif()
+ endif()
+ endif()
+ else()
+ execute_process(
+ COMMAND \"${git_EXECUTABLE}\" checkout ${git_tag}
+ WORKING_DIRECTORY \"${work_dir}\"
+ RESULT_VARIABLE error_code
+ )
+ if(error_code)
+ message(FATAL_ERROR \"Failed to checkout tag: '${git_tag}'\")
+ endif()
endif()
execute_process(
- COMMAND \"${git_EXECUTABLE}\" submodule update --recursive
+ COMMAND \"${git_EXECUTABLE}\" submodule update --recursive ${git_submodules}
WORKING_DIRECTORY \"${work_dir}/${src_name}\"
RESULT_VARIABLE error_code
)
@@ -495,7 +819,7 @@ endif()
endfunction(_ep_write_gitupdate_script)
-function(_ep_write_downloadfile_script script_filename remote local timeout hash tls_verify tls_cainfo)
+function(_ep_write_downloadfile_script script_filename remote local timeout no_progress hash tls_verify tls_cainfo)
if(timeout)
set(timeout_args TIMEOUT ${timeout})
set(timeout_msg "${timeout} seconds")
@@ -504,11 +828,25 @@ function(_ep_write_downloadfile_script script_filename remote local timeout hash
set(timeout_msg "none")
endif()
+ if(no_progress)
+ set(show_progress "")
+ else()
+ set(show_progress "SHOW_PROGRESS")
+ endif()
+
if("${hash}" MATCHES "${_ep_hash_regex}")
- set(hash_args EXPECTED_HASH ${CMAKE_MATCH_1}=${CMAKE_MATCH_2})
+ string(CONCAT hash_check
+ "if(EXISTS \"${local}\")\n"
+ " file(\"${CMAKE_MATCH_1}\" \"${local}\" hash_value)\n"
+ " if(\"x\${hash_value}\" STREQUAL \"x${CMAKE_MATCH_2}\")\n"
+ " return()\n"
+ " endif()\n"
+ "endif()\n"
+ )
else()
- set(hash_args "# no EXPECTED_HASH")
+ set(hash_check "")
endif()
+
# check for curl globals in the project
if(DEFINED CMAKE_TLS_VERIFY)
set(tls_verify "set(CMAKE_TLS_VERIFY ${CMAKE_TLS_VERIFY})")
@@ -532,7 +870,7 @@ function(_ep_write_downloadfile_script script_filename remote local timeout hash
endif()
file(WRITE ${script_filename}
-"message(STATUS \"downloading...
+"${hash_check}message(STATUS \"downloading...
src='${remote}'
dst='${local}'
timeout='${timeout_msg}'\")
@@ -543,8 +881,7 @@ ${tls_cainfo}
file(DOWNLOAD
\"${remote}\"
\"${local}\"
- SHOW_PROGRESS
- ${hash_args}
+ ${show_progress}
${timeout_args}
STATUS status
LOG log)
@@ -567,13 +904,31 @@ message(STATUS \"downloading... done\")
endfunction()
-function(_ep_write_verifyfile_script script_filename local hash)
+function(_ep_write_verifyfile_script script_filename local hash retries download_script)
if("${hash}" MATCHES "${_ep_hash_regex}")
set(algo "${CMAKE_MATCH_1}")
string(TOLOWER "${CMAKE_MATCH_2}" expect_value)
set(script_content "set(expect_value \"${expect_value}\")
-file(${algo} \"\${file}\" actual_value)
-if(\"\${actual_value}\" STREQUAL \"\${expect_value}\")
+set(attempt 0)
+set(succeeded 0)
+while(\${attempt} LESS ${retries} OR \${attempt} EQUAL ${retries} AND NOT \${succeeded})
+ file(${algo} \"\${file}\" actual_value)
+ if(\"\${actual_value}\" STREQUAL \"\${expect_value}\")
+ set(succeeded 1)
+ elseif(\${attempt} LESS ${retries})
+ message(STATUS \"${algo} hash of \${file}
+does not match expected value
+ expected: \${expect_value}
+ actual: \${actual_value}
+Retrying download.
+\")
+ file(REMOVE \"\${file}\")
+ execute_process(COMMAND \${CMAKE_COMMAND} -P \"${download_script}\")
+ endif()
+ math(EXPR attempt \"\${attempt} + 1\")
+endwhile()
+
+if(\${succeeded})
message(STATUS \"verifying file... done\")
else()
message(FATAL_ERROR \"error: ${algo} hash of
@@ -597,7 +952,7 @@ endfunction()
function(_ep_write_extractfile_script script_filename name filename directory)
set(args "")
- if(filename MATCHES "(\\.|=)(bz2|tar\\.gz|tgz|zip)$")
+ if(filename MATCHES "(\\.|=)(7z|tar\\.bz2|tar\\.gz|tar\\.xz|tbz2|tgz|txz|zip)$")
set(args xfz)
endif()
@@ -606,7 +961,7 @@ function(_ep_write_extractfile_script script_filename name filename directory)
endif()
if(args STREQUAL "")
- message(SEND_ERROR "error: do not know how to extract '${filename}' -- known types are .bz2, .tar, .tar.gz, .tgz and .zip")
+ message(SEND_ERROR "error: do not know how to extract '${filename}' -- known types are .7z, .tar, .tar.bz2, .tar.gz, .tar.xz, .tbz2, .tgz, .txz and .zip")
return()
endif()
@@ -761,23 +1116,25 @@ macro(_ep_replace_location_tags target_name)
endmacro()
-function(_ep_write_initial_cache target_name script_filename args)
- # Write out values into an initial cache, that will be passed to CMake with -C
+function(_ep_command_line_to_initial_cache var args force)
set(script_initial_cache "")
set(regex "^([^:]+):([^=]+)=(.*)$")
set(setArg "")
+ set(forceArg "")
+ if(force)
+ set(forceArg "FORCE")
+ endif()
foreach(line ${args})
- if("${line}" MATCHES "^-D")
+ if("${line}" MATCHES "^-D(.*)")
+ set(line "${CMAKE_MATCH_1}")
if(setArg)
# This is required to build up lists in variables, or complete an entry
- set(setArg "${setArg}${accumulator}\" CACHE ${type} \"Initial cache\" FORCE)")
+ set(setArg "${setArg}${accumulator}\" CACHE ${type} \"Initial cache\" ${forceArg})")
set(script_initial_cache "${script_initial_cache}\n${setArg}")
set(accumulator "")
set(setArg "")
endif()
- string(REGEX REPLACE "^-D" "" line ${line})
if("${line}" MATCHES "${regex}")
- string(REGEX MATCH "${regex}" match "${line}")
set(name "${CMAKE_MATCH_1}")
set(type "${CMAKE_MATCH_2}")
set(value "${CMAKE_MATCH_3}")
@@ -792,16 +1149,19 @@ function(_ep_write_initial_cache target_name script_filename args)
endforeach()
# Catch the final line of the args
if(setArg)
- set(setArg "${setArg}${accumulator}\" CACHE ${type} \"Initial cache\" FORCE)")
+ set(setArg "${setArg}${accumulator}\" CACHE ${type} \"Initial cache\" ${forceArg})")
set(script_initial_cache "${script_initial_cache}\n${setArg}")
endif()
+ set(${var} ${script_initial_cache} PARENT_SCOPE)
+endfunction()
+
+
+function(_ep_write_initial_cache target_name script_filename script_initial_cache)
+ # Write out values into an initial cache, that will be passed to CMake with -C
# Replace location tags.
_ep_replace_location_tags(${target_name} script_initial_cache)
# Write out the initial cache file to the location specified.
- if(NOT EXISTS "${script_filename}.in")
- file(WRITE "${script_filename}.in" "\@script_initial_cache\@\n")
- endif()
- configure_file("${script_filename}.in" "${script_filename}")
+ file(GENERATE OUTPUT "${script_filename}" CONTENT "${script_initial_cache}")
endfunction()
@@ -858,7 +1218,7 @@ function(_ep_get_build_command name step cmd_var)
if(step STREQUAL "INSTALL")
set(args install)
endif()
- if(step STREQUAL "TEST")
+ if("x${step}x" STREQUAL "xTESTx")
set(args test)
endif()
else()
@@ -869,14 +1229,35 @@ function(_ep_get_build_command name step cmd_var)
else()
set(cmd "${CMAKE_COMMAND}")
endif()
- set(args --build ${binary_dir} --config ${CMAKE_CFG_INTDIR})
+ set(args --build ".")
+ if(CMAKE_CONFIGURATION_TYPES)
+ if (CMAKE_CFG_INTDIR AND
+ NOT CMAKE_CFG_INTDIR STREQUAL "." AND
+ NOT CMAKE_CFG_INTDIR MATCHES "\\$")
+ # CMake 3.4 and below used the CMAKE_CFG_INTDIR placeholder value
+ # provided by multi-configuration generators. Some projects were
+ # taking advantage of that undocumented implementation detail to
+ # specify a specific configuration here. They should use
+ # BUILD_COMMAND to change the default command instead, but for
+ # compatibility honor the value.
+ set(config ${CMAKE_CFG_INTDIR})
+ message(AUTHOR_WARNING "CMAKE_CFG_INTDIR should not be set by project code.\n"
+ "To get a non-default build command, use the BUILD_COMMAND option.")
+ else()
+ set(config $<CONFIG>)
+ endif()
+ list(APPEND args --config ${config})
+ endif()
if(step STREQUAL "INSTALL")
list(APPEND args --target install)
endif()
# But for "TEST" drive the project with corresponding "ctest".
- if(step STREQUAL "TEST")
+ if("x${step}x" STREQUAL "xTESTx")
string(REGEX REPLACE "^(.*/)cmake([^/]*)$" "\\1ctest\\2" cmd "${cmd}")
set(args "")
+ if(CMAKE_CONFIGURATION_TYPES)
+ list(APPEND args -C ${config})
+ endif()
endif()
endif()
else()
@@ -890,7 +1271,7 @@ function(_ep_get_build_command name step cmd_var)
if(step STREQUAL "INSTALL")
set(args install)
endif()
- if(step STREQUAL "TEST")
+ if("x${step}x" STREQUAL "xTESTx")
set(args test)
endif()
endif()
@@ -913,7 +1294,7 @@ function(_ep_write_log_script name step cmd_var)
set(make "")
set(code_cygpath_make "")
- if("${command}" MATCHES "^\\$\\(MAKE\\)")
+ if(command MATCHES "^\\$\\(MAKE\\)")
# GNU make recognizes the string "$(MAKE)" as recursive make, so
# ensure that it appears directly in the makefile.
string(REGEX REPLACE "^\\$\\(MAKE\\)" "\${make}" command "${command}")
@@ -945,7 +1326,7 @@ endif()
# Wrap multiple 'COMMAND' lines up into a second-level wrapper
# script so all output can be sent to one log file.
- if("${command}" MATCHES ";COMMAND;")
+ if(command MATCHES "(^|;)COMMAND;")
set(code_execute_process "
${code_cygpath_make}
execute_process(COMMAND \${command} RESULT_VARIABLE result)
@@ -962,7 +1343,9 @@ endif()
set(sep "")
foreach(arg IN LISTS command)
if("x${arg}" STREQUAL "xCOMMAND")
- set(code "${code}set(command \"${cmd}\")${code_execute_process}")
+ if(NOT "x${cmd}" STREQUAL "x")
+ set(code "${code}set(command \"${cmd}\")${code_execute_process}")
+ endif()
set(cmd "")
set(sep "")
else()
@@ -971,14 +1354,14 @@ endif()
endif()
endforeach()
set(code "${code}set(command \"${cmd}\")${code_execute_process}")
- file(WRITE ${stamp_dir}/${name}-${step}-impl.cmake "${code}")
- set(command ${CMAKE_COMMAND} "-Dmake=\${make}" "-Dconfig=\${config}" -P ${stamp_dir}/${name}-${step}-impl.cmake)
+ file(GENERATE OUTPUT "${stamp_dir}/${name}-${step}-$<CONFIG>-impl.cmake" CONTENT "${code}")
+ set(command ${CMAKE_COMMAND} "-Dmake=\${make}" "-Dconfig=\${config}" -P ${stamp_dir}/${name}-${step}-$<CONFIG>-impl.cmake)
endif()
# Wrap the command in a script to log output to files.
- set(script ${stamp_dir}/${name}-${step}.cmake)
+ set(script ${stamp_dir}/${name}-${step}-$<CONFIG>.cmake)
set(logbase ${stamp_dir}/${name}-${step})
- file(WRITE ${script} "
+ set(code "
${code_cygpath_make}
set(command \"${command}\")
execute_process(
@@ -992,13 +1375,14 @@ if(result)
foreach(arg IN LISTS command)
set(msg \"\${msg} '\${arg}'\")
endforeach()
- set(msg \"\${msg}\\nSee also\\n ${logbase}-*.log\\n\")
+ set(msg \"\${msg}\\nSee also\\n ${logbase}-*.log\")
message(FATAL_ERROR \"\${msg}\")
else()
- set(msg \"${name} ${step} command succeeded. See also ${logbase}-*.log\\n\")
+ set(msg \"${name} ${step} command succeeded. See also ${logbase}-*.log\")
message(STATUS \"\${msg}\")
endif()
")
+ file(GENERATE OUTPUT "${script}" CONTENT "${code}")
set(command ${CMAKE_COMMAND} ${make} ${config} -P ${script})
set(${cmd_var} "${command}" PARENT_SCOPE)
endfunction()
@@ -1032,17 +1416,28 @@ endfunction()
function(ExternalProject_Add_StepTargets name)
set(steps ${ARGN})
-
+ if(ARGC GREATER 1 AND "${ARGV1}" STREQUAL "NO_DEPENDS")
+ set(no_deps 1)
+ list(REMOVE_AT steps 0)
+ endif()
foreach(step ${steps})
+ if(no_deps AND "${step}" MATCHES "^(configure|build|install|test)$")
+ message(AUTHOR_WARNING "Using NO_DEPENDS for \"${step}\" step might break parallel builds")
+ endif()
_ep_get_step_stampfile(${name} ${step} stamp_file)
add_custom_target(${name}-${step}
DEPENDS ${stamp_file})
+ set_property(TARGET ${name}-${step} PROPERTY _EP_IS_EXTERNAL_PROJECT_STEP 1)
+ set_property(TARGET ${name}-${step} PROPERTY LABELS ${name})
+ set_property(TARGET ${name}-${step} PROPERTY FOLDER "ExternalProjectTargets/${name}")
# Depend on other external projects (target-level).
- get_property(deps TARGET ${name} PROPERTY _EP_DEPENDS)
- foreach(arg IN LISTS deps)
- add_dependencies(${name}-${step} ${arg})
- endforeach()
+ if(NOT no_deps)
+ get_property(deps TARGET ${name} PROPERTY _EP_DEPENDS)
+ foreach(arg IN LISTS deps)
+ add_dependencies(${name}-${step} ${arg})
+ endforeach()
+ endif()
endforeach()
endfunction()
@@ -1054,14 +1449,17 @@ function(ExternalProject_Add_Step name step)
set(complete_stamp_file "${cmf_dir}${cfgdir}/${name}-complete")
_ep_get_step_stampfile(${name} ${step} stamp_file)
- add_custom_command(APPEND
- OUTPUT ${complete_stamp_file}
- DEPENDS ${stamp_file}
- )
-
_ep_parse_arguments(ExternalProject_Add_Step
${name} _EP_${step}_ "${ARGN}")
+ get_property(exclude_from_main TARGET ${name} PROPERTY _EP_${step}_EXCLUDE_FROM_MAIN)
+ if(NOT exclude_from_main)
+ add_custom_command(APPEND
+ OUTPUT ${complete_stamp_file}
+ DEPENDS ${stamp_file}
+ )
+ endif()
+
# Steps depending on this step.
get_property(dependers TARGET ${name} PROPERTY _EP_${step}_DEPENDERS)
foreach(depender IN LISTS dependers)
@@ -1075,6 +1473,9 @@ function(ExternalProject_Add_Step name step)
# Dependencies on files.
get_property(depends TARGET ${name} PROPERTY _EP_${step}_DEPENDS)
+ # Byproducts of the step.
+ get_property(byproducts TARGET ${name} PROPERTY _EP_${step}_BYPRODUCTS)
+
# Dependencies on steps.
get_property(dependees TARGET ${name} PROPERTY _EP_${step}_DEPENDEES)
foreach(dependee IN LISTS dependees)
@@ -1098,7 +1499,7 @@ function(ExternalProject_Add_Step name step)
endif()
# Replace location tags.
- _ep_replace_location_tags(${name} comment command work_dir)
+ _ep_replace_location_tags(${name} comment command work_dir byproducts)
# Custom comment?
get_property(comment_set TARGET ${name} PROPERTY _EP_${step}_COMMENT SET)
@@ -1106,11 +1507,28 @@ function(ExternalProject_Add_Step name step)
get_property(comment TARGET ${name} PROPERTY _EP_${step}_COMMENT)
endif()
+ # Uses terminal?
+ get_property(uses_terminal TARGET ${name} PROPERTY _EP_${step}_USES_TERMINAL)
+ if(uses_terminal)
+ set(uses_terminal USES_TERMINAL)
+ else()
+ set(uses_terminal "")
+ endif()
+
# Run every time?
get_property(always TARGET ${name} PROPERTY _EP_${step}_ALWAYS)
if(always)
set_property(SOURCE ${stamp_file} PROPERTY SYMBOLIC 1)
set(touch)
+ # Remove any existing stamp in case the option changed in an existing tree.
+ if(CMAKE_CONFIGURATION_TYPES)
+ foreach(cfg ${CMAKE_CONFIGURATION_TYPES})
+ string(REPLACE "/${CMAKE_CFG_INTDIR}" "/${cfg}" stamp_file_config "${stamp_file}")
+ file(REMOVE ${stamp_file_config})
+ endforeach()
+ else()
+ file(REMOVE ${stamp_file})
+ endif()
else()
set(touch ${CMAKE_COMMAND} -E touch ${stamp_file})
endif()
@@ -1121,15 +1539,27 @@ function(ExternalProject_Add_Step name step)
_ep_write_log_script(${name} ${step} command)
endif()
+ if("${command}" STREQUAL "")
+ # Some generators (i.e. Xcode) will not generate a file level target
+ # if no command is set, and therefore the dependencies on this
+ # target will be broken.
+ # The empty command is replaced by an echo command here in order to
+ # avoid this issue.
+ set(command ${CMAKE_COMMAND} -E echo_append)
+ endif()
+
add_custom_command(
OUTPUT ${stamp_file}
+ BYPRODUCTS ${byproducts}
COMMENT ${comment}
COMMAND ${command}
COMMAND ${touch}
DEPENDS ${depends}
WORKING_DIRECTORY ${work_dir}
VERBATIM
+ ${uses_terminal}
)
+ set_property(TARGET ${name} APPEND PROPERTY _EP_STEPS ${step})
# Add custom "step target"?
get_property(step_targets TARGET ${name} PROPERTY _EP_STEP_TARGETS)
@@ -1142,6 +1572,69 @@ function(ExternalProject_Add_Step name step)
break()
endif()
endforeach()
+
+ get_property(independent_step_targets TARGET ${name} PROPERTY _EP_INDEPENDENT_STEP_TARGETS)
+ if(NOT independent_step_targets)
+ get_property(independent_step_targets DIRECTORY PROPERTY EP_INDEPENDENT_STEP_TARGETS)
+ endif()
+ foreach(st ${independent_step_targets})
+ if("${st}" STREQUAL "${step}")
+ ExternalProject_Add_StepTargets(${name} NO_DEPENDS ${step})
+ break()
+ endif()
+ endforeach()
+endfunction()
+
+
+function(ExternalProject_Add_StepDependencies name step)
+ set(dependencies ${ARGN})
+
+ # Sanity checks on "name" and "step".
+ if(NOT TARGET ${name})
+ message(FATAL_ERROR "Cannot find target \"${name}\". Perhaps it has not yet been created using ExternalProject_Add.")
+ endif()
+
+ get_property(type TARGET ${name} PROPERTY TYPE)
+ if(NOT type STREQUAL "UTILITY")
+ message(FATAL_ERROR "Target \"${name}\" was not generated by ExternalProject_Add.")
+ endif()
+
+ get_property(is_ep TARGET ${name} PROPERTY _EP_IS_EXTERNAL_PROJECT)
+ if(NOT is_ep)
+ message(FATAL_ERROR "Target \"${name}\" was not generated by ExternalProject_Add.")
+ endif()
+
+ get_property(steps TARGET ${name} PROPERTY _EP_STEPS)
+ list(FIND steps ${step} is_step)
+ if(NOT is_step)
+ message(FATAL_ERROR "External project \"${name}\" does not have a step \"${step}\".")
+ endif()
+
+ if(TARGET ${name}-${step})
+ get_property(type TARGET ${name}-${step} PROPERTY TYPE)
+ if(NOT type STREQUAL "UTILITY")
+ message(FATAL_ERROR "Target \"${name}-${step}\" was not generated by ExternalProject_Add_StepTargets.")
+ endif()
+ get_property(is_ep_step TARGET ${name}-${step} PROPERTY _EP_IS_EXTERNAL_PROJECT_STEP)
+ if(NOT is_ep_step)
+ message(FATAL_ERROR "Target \"${name}-${step}\" was not generated by ExternalProject_Add_StepTargets.")
+ endif()
+ endif()
+
+ # Always add file-level dependency, but add target-level dependency
+ # only if the target exists for that step.
+ _ep_get_step_stampfile(${name} ${step} stamp_file)
+ foreach(dep ${dependencies})
+ add_custom_command(APPEND
+ OUTPUT ${stamp_file}
+ DEPENDS ${dep})
+ if(TARGET ${name}-${step})
+ foreach(dep ${dependencies})
+ add_dependencies(${name}-${step} ${dep})
+ endforeach()
+ endif()
+ endforeach()
+
endfunction()
@@ -1163,20 +1656,6 @@ function(_ep_add_mkdir_command name)
endfunction()
-function(_ep_get_git_version git_EXECUTABLE git_version_var)
- if(git_EXECUTABLE)
- execute_process(
- COMMAND "${git_EXECUTABLE}" --version
- OUTPUT_VARIABLE ov
- ERROR_VARIABLE ev
- OUTPUT_STRIP_TRAILING_WHITESPACE
- )
- string(REGEX REPLACE "^git version (.+)$" "\\1" version "${ov}")
- set(${git_version_var} "${version}" PARENT_SCOPE)
- endif()
-endfunction()
-
-
function(_ep_is_dir_empty dir empty_var)
file(GLOB gr "${dir}/*")
if("${gr}" STREQUAL "")
@@ -1209,7 +1688,7 @@ function(_ep_add_download_command name)
if(cmd_set)
set(work_dir ${download_dir})
elseif(cvs_repository)
- find_package(CVS)
+ find_package(CVS QUIET)
if(NOT CVS_EXECUTABLE)
message(FATAL_ERROR "error: could not find cvs for checkout of ${name}")
endif()
@@ -1236,7 +1715,7 @@ function(_ep_add_download_command name)
set(cmd ${CVS_EXECUTABLE} -d ${cvs_repository} -q co ${cvs_tag} -d ${src_name} ${cvs_module})
list(APPEND depends ${stamp_dir}/${name}-cvsinfo.txt)
elseif(svn_repository)
- find_package(Subversion)
+ find_package(Subversion QUIET)
if(NOT Subversion_SVN_EXECUTABLE)
message(FATAL_ERROR "error: could not find svn for checkout of ${name}")
endif()
@@ -1272,22 +1751,28 @@ function(_ep_add_download_command name)
--non-interactive ${svn_trust_cert_args} ${svn_user_pw_args} ${src_name})
list(APPEND depends ${stamp_dir}/${name}-svninfo.txt)
elseif(git_repository)
- find_package(Git)
+ unset(CMAKE_MODULE_PATH) # Use CMake builtin find module
+ find_package(Git QUIET)
if(NOT GIT_EXECUTABLE)
message(FATAL_ERROR "error: could not find git for clone of ${name}")
endif()
# The git submodule update '--recursive' flag requires git >= v1.6.5
#
- _ep_get_git_version("${GIT_EXECUTABLE}" git_version)
- if(git_version VERSION_LESS 1.6.5)
- message(FATAL_ERROR "error: git version 1.6.5 or later required for 'git submodule update --recursive': git_version='${git_version}'")
+ if(GIT_VERSION_STRING VERSION_LESS 1.6.5)
+ message(FATAL_ERROR "error: git version 1.6.5 or later required for 'git submodule update --recursive': GIT_VERSION_STRING='${GIT_VERSION_STRING}'")
endif()
get_property(git_tag TARGET ${name} PROPERTY _EP_GIT_TAG)
if(NOT git_tag)
set(git_tag "master")
endif()
+ get_property(git_submodules TARGET ${name} PROPERTY _EP_GIT_SUBMODULES)
+
+ get_property(git_remote_name TARGET ${name} PROPERTY _EP_GIT_REMOTE_NAME)
+ if(NOT git_remote_name)
+ set(git_remote_name "origin")
+ endif()
# For the download step, and the git clone operation, only the repository
# should be recorded in a configured RepositoryInfo file. If the repo
@@ -1312,14 +1797,14 @@ function(_ep_add_download_command name)
# The script will delete the source directory and then call git clone.
#
_ep_write_gitclone_script(${tmp_dir}/${name}-gitclone.cmake ${source_dir}
- ${GIT_EXECUTABLE} ${git_repository} ${git_tag} ${src_name} ${work_dir}
+ ${GIT_EXECUTABLE} ${git_repository} ${git_tag} ${git_remote_name} "${git_submodules}" ${src_name} ${work_dir}
${stamp_dir}/${name}-gitinfo.txt ${stamp_dir}/${name}-gitclone-lastrun.txt
)
set(comment "Performing download step (git clone) for '${name}'")
set(cmd ${CMAKE_COMMAND} -P ${tmp_dir}/${name}-gitclone.cmake)
list(APPEND depends ${stamp_dir}/${name}-gitinfo.txt)
elseif(hg_repository)
- find_package(Hg)
+ find_package(Hg QUIET)
if(NOT HG_EXECUTABLE)
message(FATAL_ERROR "error: could not find hg for clone of ${name}")
endif()
@@ -1376,6 +1861,8 @@ function(_ep_add_download_command name)
set(repository "external project URL")
set(module "${url}")
set(tag "${hash}")
+ set(retries 0)
+ set(download_script "")
configure_file(
"${CMAKE_ROOT}/Modules/RepositoryInfo.txt.in"
"${stamp_dir}/${name}-urlinfo.txt"
@@ -1393,28 +1880,30 @@ function(_ep_add_download_command name)
if("x${fname}" STREQUAL "x")
string(REGEX MATCH "[^/\\?]*$" fname "${url}")
endif()
- if(NOT "${fname}" MATCHES "(\\.|=)(bz2|tar|tgz|tar\\.gz|zip)$")
- string(REGEX MATCH "([^/\\?]+(\\.|=)(bz2|tar|tgz|tar\\.gz|zip))/.*$" match_result "${url}")
+ if(NOT "${fname}" MATCHES "(\\.|=)(7z|tar|tar\\.bz2|tar\\.gz|tar\\.xz|tbz2|tgz|txz|zip)$")
+ string(REGEX MATCH "([^/\\?]+(\\.|=)(7z|tar|tar\\.bz2|tar\\.gz|tar\\.xz|tbz2|tgz|txz|zip))/.*$" match_result "${url}")
set(fname "${CMAKE_MATCH_1}")
endif()
- if(NOT "${fname}" MATCHES "(\\.|=)(bz2|tar|tgz|tar\\.gz|zip)$")
+ if(NOT "${fname}" MATCHES "(\\.|=)(7z|tar|tar\\.bz2|tar\\.gz|tar\\.xz|tbz2|tgz|txz|zip)$")
message(FATAL_ERROR "Could not extract tarball filename from url:\n ${url}")
endif()
string(REPLACE ";" "-" fname "${fname}")
set(file ${download_dir}/${fname})
get_property(timeout TARGET ${name} PROPERTY _EP_TIMEOUT)
+ get_property(no_progress TARGET ${name} PROPERTY _EP_DOWNLOAD_NO_PROGRESS)
get_property(tls_verify TARGET ${name} PROPERTY _EP_TLS_VERIFY)
get_property(tls_cainfo TARGET ${name} PROPERTY _EP_TLS_CAINFO)
- _ep_write_downloadfile_script("${stamp_dir}/download-${name}.cmake"
- "${url}" "${file}" "${timeout}" "${hash}" "${tls_verify}" "${tls_cainfo}")
- set(cmd ${CMAKE_COMMAND} -P ${stamp_dir}/download-${name}.cmake
+ set(download_script "${stamp_dir}/download-${name}.cmake")
+ _ep_write_downloadfile_script("${download_script}" "${url}" "${file}" "${timeout}" "${no_progress}" "${hash}" "${tls_verify}" "${tls_cainfo}")
+ set(cmd ${CMAKE_COMMAND} -P "${download_script}"
COMMAND)
+ set(retries 3)
set(comment "Performing download step (download, verify and extract) for '${name}'")
else()
set(file "${url}")
set(comment "Performing download step (verify and extract) for '${name}'")
endif()
- _ep_write_verifyfile_script("${stamp_dir}/verify-${name}.cmake" "${file}" "${hash}")
+ _ep_write_verifyfile_script("${stamp_dir}/verify-${name}.cmake" "${file}" "${hash}" "${retries}" "${download_script}")
list(APPEND cmd ${CMAKE_COMMAND} -P ${stamp_dir}/verify-${name}.cmake
COMMAND)
_ep_write_extractfile_script("${stamp_dir}/extract-${name}.cmake" "${name}" "${file}" "${source_dir}")
@@ -1423,7 +1912,18 @@ function(_ep_add_download_command name)
else()
_ep_is_dir_empty("${source_dir}" empty)
if(${empty})
- message(SEND_ERROR "error: no download info for '${name}' -- please specify existing/non-empty SOURCE_DIR or one of URL, CVS_REPOSITORY and CVS_MODULE, SVN_REPOSITORY, GIT_REPOSITORY, HG_REPOSITORY or DOWNLOAD_COMMAND")
+ message(SEND_ERROR
+ "No download info given for '${name}' and its source directory:\n"
+ " ${source_dir}\n"
+ "is not an existing non-empty directory. Please specify one of:\n"
+ " * SOURCE_DIR with an existing non-empty directory\n"
+ " * URL\n"
+ " * GIT_REPOSITORY\n"
+ " * HG_REPOSITORY\n"
+ " * CVS_REPOSITORY and CVS_MODULE\n"
+ " * SVN_REVISION\n"
+ " * DOWNLOAD_COMMAND"
+ )
endif()
endif()
@@ -1434,6 +1934,14 @@ function(_ep_add_download_command name)
set(log "")
endif()
+ get_property(uses_terminal TARGET ${name} PROPERTY
+ _EP_USES_TERMINAL_DOWNLOAD)
+ if(uses_terminal)
+ set(uses_terminal USES_TERMINAL 1)
+ else()
+ set(uses_terminal "")
+ endif()
+
ExternalProject_Add_Step(${name} download
COMMENT ${comment}
COMMAND ${cmd}
@@ -1441,6 +1949,7 @@ function(_ep_add_download_command name)
DEPENDS ${depends}
DEPENDEES mkdir
${log}
+ ${uses_terminal}
)
endfunction()
@@ -1454,6 +1963,12 @@ function(_ep_add_update_command name)
get_property(svn_repository TARGET ${name} PROPERTY _EP_SVN_REPOSITORY)
get_property(git_repository TARGET ${name} PROPERTY _EP_GIT_REPOSITORY)
get_property(hg_repository TARGET ${name} PROPERTY _EP_HG_REPOSITORY )
+ get_property(update_disconnected_set TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED SET)
+ if(update_disconnected_set)
+ get_property(update_disconnected TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED)
+ else()
+ get_property(update_disconnected DIRECTORY PROPERTY EP_UPDATE_DISCONNECTED)
+ endif()
set(work_dir)
set(comment)
@@ -1503,8 +2018,13 @@ function(_ep_add_update_command name)
if(NOT git_tag)
set(git_tag "master")
endif()
+ get_property(git_remote_name TARGET ${name} PROPERTY _EP_GIT_REMOTE_NAME)
+ if(NOT git_remote_name)
+ set(git_remote_name "origin")
+ endif()
+ get_property(git_submodules TARGET ${name} PROPERTY _EP_GIT_SUBMODULES)
_ep_write_gitupdate_script(${tmp_dir}/${name}-gitupdate.cmake
- ${GIT_EXECUTABLE} ${git_tag} ${git_repository} ${work_dir}
+ ${GIT_EXECUTABLE} ${git_tag} ${git_remote_name} "${git_submodules}" ${git_repository} ${work_dir}
)
set(cmd ${CMAKE_COMMAND} -P ${tmp_dir}/${name}-gitupdate.cmake)
set(always 1)
@@ -1538,14 +2058,40 @@ Update to Mercurial >= 2.1.1.
set(log "")
endif()
+ get_property(uses_terminal TARGET ${name} PROPERTY
+ _EP_USES_TERMINAL_UPDATE)
+ if(uses_terminal)
+ set(uses_terminal USES_TERMINAL 1)
+ else()
+ set(uses_terminal "")
+ endif()
+
ExternalProject_Add_Step(${name} update
COMMENT ${comment}
COMMAND ${cmd}
ALWAYS ${always}
+ EXCLUDE_FROM_MAIN ${update_disconnected}
WORKING_DIRECTORY ${work_dir}
DEPENDEES download
${log}
+ ${uses_terminal}
+ )
+
+ if(always AND update_disconnected)
+ _ep_get_step_stampfile(${name} skip-update skip-update_stamp_file)
+ string(REPLACE "Performing" "Skipping" comment "${comment}")
+ ExternalProject_Add_Step(${name} skip-update
+ COMMENT ${comment}
+ ALWAYS 1
+ EXCLUDE_FROM_MAIN 1
+ WORKING_DIRECTORY ${work_dir}
+ DEPENDEES download
+ ${log}
+ ${uses_terminal}
)
+ set_property(SOURCE ${skip-update_stamp_file} PROPERTY SYMBOLIC 1)
+ endif()
+
endfunction()
@@ -1577,10 +2123,13 @@ function(_ep_add_configure_command name)
set(file_deps)
get_property(deps TARGET ${name} PROPERTY _EP_DEPENDS)
foreach(dep IN LISTS deps)
- get_property(is_ep TARGET ${dep} PROPERTY _EP_IS_EXTERNAL_PROJECT)
- if(is_ep)
- _ep_get_step_stampfile(${dep} "done" done_stamp_file)
- list(APPEND file_deps ${done_stamp_file})
+ get_property(dep_type TARGET ${dep} PROPERTY TYPE)
+ if(dep_type STREQUAL "UTILITY")
+ get_property(is_ep TARGET ${dep} PROPERTY _EP_IS_EXTERNAL_PROJECT)
+ if(is_ep)
+ _ep_get_step_stampfile(${dep} "done" done_stamp_file)
+ list(APPEND file_deps ${done_stamp_file})
+ endif()
endif()
endforeach()
@@ -1598,18 +2147,31 @@ function(_ep_add_configure_command name)
get_property(cmake_args TARGET ${name} PROPERTY _EP_CMAKE_ARGS)
list(APPEND cmd ${cmake_args})
- # If there are any CMAKE_CACHE_ARGS, write an initial cache and use it
+ # If there are any CMAKE_CACHE_ARGS or CMAKE_CACHE_DEFAULT_ARGS,
+ # write an initial cache and use it
get_property(cmake_cache_args TARGET ${name} PROPERTY _EP_CMAKE_CACHE_ARGS)
- if(cmake_cache_args)
- set(_ep_cache_args_script "${tmp_dir}/${name}-cache.cmake")
- _ep_write_initial_cache(${name} "${_ep_cache_args_script}" "${cmake_cache_args}")
+ get_property(cmake_cache_default_args TARGET ${name} PROPERTY _EP_CMAKE_CACHE_DEFAULT_ARGS)
+
+ if(cmake_cache_args OR cmake_cache_default_args)
+ set(_ep_cache_args_script "${tmp_dir}/${name}-cache-$<CONFIG>.cmake")
+ if(cmake_cache_args)
+ _ep_command_line_to_initial_cache(script_initial_cache_force "${cmake_cache_args}" 1)
+ endif()
+ if(cmake_cache_default_args)
+ _ep_command_line_to_initial_cache(script_initial_cache_default "${cmake_cache_default_args}" 0)
+ endif()
+ _ep_write_initial_cache(${name} "${_ep_cache_args_script}" "${script_initial_cache_force}${script_initial_cache_default}")
list(APPEND cmd "-C${_ep_cache_args_script}")
endif()
get_target_property(cmake_generator ${name} _EP_CMAKE_GENERATOR)
+ get_target_property(cmake_generator_platform ${name} _EP_CMAKE_GENERATOR_PLATFORM)
get_target_property(cmake_generator_toolset ${name} _EP_CMAKE_GENERATOR_TOOLSET)
if(cmake_generator)
list(APPEND cmd "-G${cmake_generator}")
+ if(cmake_generator_platform)
+ list(APPEND cmd "-A${cmake_generator_platform}")
+ endif()
if(cmake_generator_toolset)
list(APPEND cmd "-T${cmake_generator_toolset}")
endif()
@@ -1619,6 +2181,12 @@ function(_ep_add_configure_command name)
else()
list(APPEND cmd "-G${CMAKE_GENERATOR}")
endif()
+ if(cmake_generator_platform)
+ message(FATAL_ERROR "Option CMAKE_GENERATOR_PLATFORM not allowed without CMAKE_GENERATOR.")
+ endif()
+ if(CMAKE_GENERATOR_PLATFORM)
+ list(APPEND cmd "-A${CMAKE_GENERATOR_PLATFORM}")
+ endif()
if(cmake_generator_toolset)
message(FATAL_ERROR "Option CMAKE_GENERATOR_TOOLSET not allowed without CMAKE_GENERATOR.")
endif()
@@ -1648,12 +2216,33 @@ function(_ep_add_configure_command name)
set(log "")
endif()
+ get_property(uses_terminal TARGET ${name} PROPERTY
+ _EP_USES_TERMINAL_CONFIGURE)
+ if(uses_terminal)
+ set(uses_terminal USES_TERMINAL 1)
+ else()
+ set(uses_terminal "")
+ endif()
+
+ get_property(update_disconnected_set TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED SET)
+ if(update_disconnected_set)
+ get_property(update_disconnected TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED)
+ else()
+ get_property(update_disconnected DIRECTORY PROPERTY EP_UPDATE_DISCONNECTED)
+ endif()
+ if(update_disconnected)
+ set(update_dep skip-update)
+ else()
+ set(update_dep update)
+ endif()
+
ExternalProject_Add_Step(${name} configure
COMMAND ${cmd}
WORKING_DIRECTORY ${binary_dir}
- DEPENDEES update patch
+ DEPENDEES ${update_dep} patch
DEPENDS ${file_deps}
${log}
+ ${uses_terminal}
)
endfunction()
@@ -1675,11 +2264,31 @@ function(_ep_add_build_command name)
set(log "")
endif()
+ get_property(uses_terminal TARGET ${name} PROPERTY
+ _EP_USES_TERMINAL_BUILD)
+ if(uses_terminal)
+ set(uses_terminal USES_TERMINAL 1)
+ else()
+ set(uses_terminal "")
+ endif()
+
+ get_property(build_always TARGET ${name} PROPERTY _EP_BUILD_ALWAYS)
+ if(build_always)
+ set(always 1)
+ else()
+ set(always 0)
+ endif()
+
+ get_property(build_byproducts TARGET ${name} PROPERTY _EP_BUILD_BYPRODUCTS)
+
ExternalProject_Add_Step(${name} build
COMMAND ${cmd}
+ BYPRODUCTS ${build_byproducts}
WORKING_DIRECTORY ${binary_dir}
DEPENDEES configure
+ ALWAYS ${always}
${log}
+ ${uses_terminal}
)
endfunction()
@@ -1701,11 +2310,20 @@ function(_ep_add_install_command name)
set(log "")
endif()
+ get_property(uses_terminal TARGET ${name} PROPERTY
+ _EP_USES_TERMINAL_INSTALL)
+ if(uses_terminal)
+ set(uses_terminal USES_TERMINAL 1)
+ else()
+ set(uses_terminal "")
+ endif()
+
ExternalProject_Add_Step(${name} install
COMMAND ${cmd}
WORKING_DIRECTORY ${binary_dir}
DEPENDEES build
${log}
+ ${uses_terminal}
)
endfunction()
@@ -1715,12 +2333,13 @@ function(_ep_add_test_command name)
get_property(before TARGET ${name} PROPERTY _EP_TEST_BEFORE_INSTALL)
get_property(after TARGET ${name} PROPERTY _EP_TEST_AFTER_INSTALL)
+ get_property(exclude TARGET ${name} PROPERTY _EP_TEST_EXCLUDE_FROM_MAIN)
get_property(cmd_set TARGET ${name} PROPERTY _EP_TEST_COMMAND SET)
# Only actually add the test step if one of the test related properties is
# explicitly set. (i.e. the test step is omitted unless requested...)
#
- if(cmd_set OR before OR after)
+ if(cmd_set OR before OR after OR exclude)
if(cmd_set)
get_property(cmd TARGET ${name} PROPERTY _EP_TEST_COMMAND)
else()
@@ -1728,9 +2347,21 @@ function(_ep_add_test_command name)
endif()
if(before)
- set(dep_args DEPENDEES build DEPENDERS install)
+ set(dependees_args DEPENDEES build)
else()
- set(dep_args DEPENDEES install)
+ set(dependees_args DEPENDEES install)
+ endif()
+
+ if(exclude)
+ set(dependers_args "")
+ set(exclude_args EXCLUDE_FROM_MAIN 1)
+ else()
+ if(before)
+ set(dependers_args DEPENDERS install)
+ else()
+ set(dependers_args "")
+ endif()
+ set(exclude_args "")
endif()
get_property(log TARGET ${name} PROPERTY _EP_LOG_TEST)
@@ -1740,11 +2371,22 @@ function(_ep_add_test_command name)
set(log "")
endif()
+ get_property(uses_terminal TARGET ${name} PROPERTY
+ _EP_USES_TERMINAL_TEST)
+ if(uses_terminal)
+ set(uses_terminal USES_TERMINAL 1)
+ else()
+ set(uses_terminal "")
+ endif()
+
ExternalProject_Add_Step(${name} test
COMMAND ${cmd}
WORKING_DIRECTORY ${binary_dir}
- ${dep_args}
+ ${dependees_args}
+ ${dependers_args}
+ ${exclude_args}
${log}
+ ${uses_terminal}
)
endif()
endfunction()
@@ -1757,13 +2399,25 @@ function(ExternalProject_Add name)
set(cmf_dir ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles)
set(complete_stamp_file "${cmf_dir}${cfgdir}/${name}-complete")
+ # The "ALL" option to add_custom_target just tells it to not set the
+ # EXCLUDE_FROM_ALL target property. Later, if the EXCLUDE_FROM_ALL
+ # argument was passed, we explicitly set it for the target.
add_custom_target(${name} ALL DEPENDS ${complete_stamp_file})
set_property(TARGET ${name} PROPERTY _EP_IS_EXTERNAL_PROJECT 1)
+ set_property(TARGET ${name} PROPERTY LABELS ${name})
+ set_property(TARGET ${name} PROPERTY FOLDER "ExternalProjectTargets/${name}")
+
_ep_parse_arguments(ExternalProject_Add ${name} _EP_ "${ARGN}")
_ep_set_directories(${name})
_ep_get_step_stampfile(${name} "done" done_stamp_file)
_ep_get_step_stampfile(${name} "install" install_stamp_file)
+ # Set the EXCLUDE_FROM_ALL target property if required.
+ get_property(exclude_from_all TARGET ${name} PROPERTY _EP_EXCLUDE_FROM_ALL)
+ if(exclude_from_all)
+ set_property(TARGET ${name} PROPERTY EXCLUDE_FROM_ALL TRUE)
+ endif()
+
# The 'complete' step depends on all other steps and creates a
# 'done' mark. A dependent external project's 'configure' step
# depends on the 'done' mark so that it rebuilds when this project
diff --git a/Modules/FeatureSummary.cmake b/Modules/FeatureSummary.cmake
index 5d98ac3cf..dc3108623 100644
--- a/Modules/FeatureSummary.cmake
+++ b/Modules/FeatureSummary.cmake
@@ -1,171 +1,271 @@
-# - Macros for generating a summary of enabled/disabled features
+#.rst:
+# FeatureSummary
+# --------------
#
-# This module provides the macros feature_summary(), set_package_properties() and
-# add_feature_info().
-# For compatibility it also still provides set_package_info(), set_feature_info(),
+# Macros for generating a summary of enabled/disabled features
+#
+#
+#
+# This module provides the macros feature_summary(),
+# set_package_properties() and add_feature_info(). For compatibility it
+# also still provides set_package_info(), set_feature_info(),
# print_enabled_features() and print_disabled_features().
#
# These macros can be used to generate a summary of enabled and disabled
# packages and/or feature for a build tree:
#
-# -- The following OPTIONAL packages have been found:
-# LibXml2 (required version >= 2.4) , XML processing library. , <http://xmlsoft.org>
-# * Enables HTML-import in MyWordProcessor
-# * Enables odt-export in MyWordProcessor
-# PNG , A PNG image library. , <http://www.libpng.org/pub/png/>
-# * Enables saving screenshots
-# -- The following OPTIONAL packages have not been found:
-# Lua51 , The Lua scripting language. , <http://www.lua.org>
-# * Enables macros in MyWordProcessor
-# Foo , Foo provides cool stuff.
-#
-#
-# FEATURE_SUMMARY( [FILENAME <file>]
-# [APPEND]
-# [VAR <variable_name>]
-# [INCLUDE_QUIET_PACKAGES]
-# [FATAL_ON_MISSING_REQUIRED_PACKAGES]
-# [DESCRIPTION "Found packages:"]
-# WHAT (ALL | PACKAGES_FOUND | PACKAGES_NOT_FOUND
-# | ENABLED_FEATURES | DISABLED_FEATURES]
-# )
-#
-# The FEATURE_SUMMARY() macro can be used to print information about enabled
-# or disabled packages or features of a project.
-# By default, only the names of the features/packages will be printed and their
-# required version when one was specified. Use SET_PACKAGE_PROPERTIES() to add more
-# useful information, like e.g. a download URL for the respective package or their
-# purpose in the project.
-#
-# The WHAT option is the only mandatory option. Here you specify what information
-# will be printed:
-# ALL: print everything
-# ENABLED_FEATURES: the list of all features which are enabled
-# DISABLED_FEATURES: the list of all features which are disabled
-# PACKAGES_FOUND: the list of all packages which have been found
-# PACKAGES_NOT_FOUND: the list of all packages which have not been found
-# OPTIONAL_PACKAGES_FOUND: only those packages which have been found which have the type OPTIONAL
-# OPTIONAL_PACKAGES_NOT_FOUND: only those packages which have not been found which have the type OPTIONAL
-# RECOMMENDED_PACKAGES_FOUND: only those packages which have been found which have the type RECOMMENDED
-# RECOMMENDED_PACKAGES_NOT_FOUND: only those packages which have not been found which have the type RECOMMENDED
-# REQUIRED_PACKAGES_FOUND: only those packages which have been found which have the type REQUIRED
-# REQUIRED_PACKAGES_NOT_FOUND: only those packages which have not been found which have the type REQUIRED
-# RUNTIME_PACKAGES_FOUND: only those packages which have been found which have the type RUNTIME
-# RUNTIME_PACKAGES_NOT_FOUND: only those packages which have not been found which have the type RUNTIME
-#
-# If a FILENAME is given, the information is printed into this file. If APPEND
-# is used, it is appended to this file, otherwise the file is overwritten if
-# it already existed.
-# If the VAR option is used, the information is "printed" into the specified
-# variable.
-# If FILENAME is not used, the information is printed to the terminal.
-# Using the DESCRIPTION option a description or headline can be set which will
-# be printed above the actual content.
-# If INCLUDE_QUIET_PACKAGES is given, packages which have been searched with find_package(... QUIET) will
-# also be listed. By default they are skipped.
-# If FATAL_ON_MISSING_REQUIRED_PACKAGES is given, CMake will abort if a package which is marked as REQUIRED
-# has not been found.
+# ::
+#
+# -- The following OPTIONAL packages have been found:
+# LibXml2 (required version >= 2.4), XML processing lib, <http://xmlsoft.org>
+# * Enables HTML-import in MyWordProcessor
+# * Enables odt-export in MyWordProcessor
+# PNG , A PNG image library. , <http://www.libpng.org/pub/png/>
+# * Enables saving screenshots
+# -- The following OPTIONAL packages have not been found:
+# Lua51 , The Lua scripting language. , <http://www.lua.org>
+# * Enables macros in MyWordProcessor
+# Foo , Foo provides cool stuff.
+#
+#
+#
+#
+#
+# ::
+#
+# FEATURE_SUMMARY( [FILENAME <file>]
+# [APPEND]
+# [VAR <variable_name>]
+# [INCLUDE_QUIET_PACKAGES]
+# [FATAL_ON_MISSING_REQUIRED_PACKAGES]
+# [DESCRIPTION "Found packages:"]
+# WHAT (ALL | PACKAGES_FOUND | PACKAGES_NOT_FOUND
+# | ENABLED_FEATURES | DISABLED_FEATURES)
+# )
+#
+#
+#
+# The FEATURE_SUMMARY() macro can be used to print information about
+# enabled or disabled packages or features of a project. By default,
+# only the names of the features/packages will be printed and their
+# required version when one was specified. Use SET_PACKAGE_PROPERTIES()
+# to add more useful information, like e.g. a download URL for the
+# respective package or their purpose in the project.
+#
+# The WHAT option is the only mandatory option. Here you specify what
+# information will be printed:
+#
+# ``ALL``
+# print everything
+# ``ENABLED_FEATURES``
+# the list of all features which are enabled
+# ``DISABLED_FEATURES``
+# the list of all features which are disabled
+# ``PACKAGES_FOUND``
+# the list of all packages which have been found
+# ``PACKAGES_NOT_FOUND``
+# the list of all packages which have not been found
+# ``OPTIONAL_PACKAGES_FOUND``
+# only those packages which have been found which have the type OPTIONAL
+# ``OPTIONAL_PACKAGES_NOT_FOUND``
+# only those packages which have not been found which have the type OPTIONAL
+# ``RECOMMENDED_PACKAGES_FOUND``
+# only those packages which have been found which have the type RECOMMENDED
+# ``RECOMMENDED_PACKAGES_NOT_FOUND``
+# only those packages which have not been found which have the type RECOMMENDED
+# ``REQUIRED_PACKAGES_FOUND``
+# only those packages which have been found which have the type REQUIRED
+# ``REQUIRED_PACKAGES_NOT_FOUND``
+# only those packages which have not been found which have the type REQUIRED
+# ``RUNTIME_PACKAGES_FOUND``
+# only those packages which have been found which have the type RUNTIME
+# ``RUNTIME_PACKAGES_NOT_FOUND``
+# only those packages which have not been found which have the type RUNTIME
+#
+# With the exception of the ``ALL`` value, these values can be combined
+# in order to customize the output. For example:
+#
+# ::
+#
+# feature_summary(WHAT ENABLED_FEATURES DISABLED_FEATURES)
+#
+#
+#
+# If a FILENAME is given, the information is printed into this file. If
+# APPEND is used, it is appended to this file, otherwise the file is
+# overwritten if it already existed. If the VAR option is used, the
+# information is "printed" into the specified variable. If FILENAME is
+# not used, the information is printed to the terminal. Using the
+# DESCRIPTION option a description or headline can be set which will be
+# printed above the actual content. If INCLUDE_QUIET_PACKAGES is given,
+# packages which have been searched with find_package(... QUIET) will
+# also be listed. By default they are skipped. If
+# FATAL_ON_MISSING_REQUIRED_PACKAGES is given, CMake will abort if a
+# package which is marked as REQUIRED has not been found.
#
# Example 1, append everything to a file:
-# feature_summary(WHAT ALL
-# FILENAME ${CMAKE_BINARY_DIR}/all.log APPEND)
-#
-# Example 2, print the enabled features into the variable enabledFeaturesText, including QUIET packages:
-# feature_summary(WHAT ENABLED_FEATURES
-# INCLUDE_QUIET_PACKAGES
-# DESCRIPTION "Enabled Features:"
-# VAR enabledFeaturesText)
-# message(STATUS "${enabledFeaturesText}")
-#
-#
-# SET_PACKAGE_PROPERTIES(<name> PROPERTIES [ URL <url> ]
-# [ DESCRIPTION <description> ]
-# [ TYPE (RUNTIME|OPTIONAL|RECOMMENDED|REQUIRED) ]
-# [ PURPOSE <purpose> ]
-# )
-#
-# Use this macro to set up information about the named package, which can
-# then be displayed via FEATURE_SUMMARY().
-# This can be done either directly in the Find-module or in the project
-# which uses the module after the find_package() call.
-# The features for which information can be set are added automatically by the
-# find_package() command.
-#
-# URL: this should be the homepage of the package, or something similar. Ideally this is set
-# already directly in the Find-module.
-#
-# DESCRIPTION: A short description what that package is, at most one sentence.
+#
+# ::
+#
+# feature_summary(WHAT ALL
+# FILENAME ${CMAKE_BINARY_DIR}/all.log APPEND)
+#
+#
+#
+# Example 2, print the enabled features into the variable
+# enabledFeaturesText, including QUIET packages:
+#
+# ::
+#
+# feature_summary(WHAT ENABLED_FEATURES
+# INCLUDE_QUIET_PACKAGES
+# DESCRIPTION "Enabled Features:"
+# VAR enabledFeaturesText)
+# message(STATUS "${enabledFeaturesText}")
+#
+#
+#
+#
+#
+# ::
+#
+# SET_PACKAGE_PROPERTIES(<name> PROPERTIES
+# [ URL <url> ]
+# [ DESCRIPTION <description> ]
+# [ TYPE (RUNTIME|OPTIONAL|RECOMMENDED|REQUIRED) ]
+# [ PURPOSE <purpose> ]
+# )
+#
+#
+#
+# Use this macro to set up information about the named package, which
+# can then be displayed via FEATURE_SUMMARY(). This can be done either
+# directly in the Find-module or in the project which uses the module
+# after the find_package() call. The features for which information can
+# be set are added automatically by the find_package() command.
+#
+# URL: this should be the homepage of the package, or something similar.
# Ideally this is set already directly in the Find-module.
#
-# TYPE: What type of dependency has the using project on that package. Default is OPTIONAL.
-# In this case it is a package which can be used by the project when available at buildtime,
-# but it also work without. RECOMMENDED is similar to OPTIONAL, i.e. the project will build
-# if the package is not present, but the functionality of the resulting binaries will be severly
-# limited. If a REQUIRED package is not available at buildtime, the project may not even build. This
-# can be combined with the FATAL_ON_MISSING_REQUIRED_PACKAGES argument for feature_summary().
-# Last, a RUNTIME package is a package which is actually not used at all during the build, but
-# which is required for actually running the resulting binaries. So if such a package is missing,
-# the project can still be built, but it may not work later on. If set_package_properties() is called
-# multiple times for the same package with different TYPEs, the TYPE is only changed to higher
-# TYPEs ( RUNTIME < OPTIONAL < RECOMMENDED < REQUIRED ), lower TYPEs are ignored.
-# The TYPE property is project-specific, so it cannot be set by the Find-module, but must be set in the project.
-#
-# PURPOSE: This describes which features this package enables in the project, i.e. it tells the user
-# what functionality he gets in the resulting binaries.
-# If set_package_properties() is called multiple times for a package, all PURPOSE properties are appended
-# to a list of purposes of the package in the project.
-# As the TYPE property, also the PURPOSE property
-# is project-specific, so it cannot be set by the Find-module, but must be set in the project.
+# DESCRIPTION: A short description what that package is, at most one
+# sentence. Ideally this is set already directly in the Find-module.
+#
+# TYPE: What type of dependency has the using project on that package.
+# Default is OPTIONAL. In this case it is a package which can be used
+# by the project when available at buildtime, but it also work without.
+# RECOMMENDED is similar to OPTIONAL, i.e. the project will build if
+# the package is not present, but the functionality of the resulting
+# binaries will be severly limited. If a REQUIRED package is not
+# available at buildtime, the project may not even build. This can be
+# combined with the FATAL_ON_MISSING_REQUIRED_PACKAGES argument for
+# feature_summary(). Last, a RUNTIME package is a package which is
+# actually not used at all during the build, but which is required for
+# actually running the resulting binaries. So if such a package is
+# missing, the project can still be built, but it may not work later on.
+# If set_package_properties() is called multiple times for the same
+# package with different TYPEs, the TYPE is only changed to higher TYPEs
+# ( RUNTIME < OPTIONAL < RECOMMENDED < REQUIRED ), lower TYPEs are
+# ignored. The TYPE property is project-specific, so it cannot be set
+# by the Find-module, but must be set in the project.
+#
+# PURPOSE: This describes which features this package enables in the
+# project, i.e. it tells the user what functionality he gets in the
+# resulting binaries. If set_package_properties() is called multiple
+# times for a package, all PURPOSE properties are appended to a list of
+# purposes of the package in the project. As the TYPE property, also
+# the PURPOSE property is project-specific, so it cannot be set by the
+# Find-module, but must be set in the project.
+#
#
#
# Example for setting the info for a package:
-# find_package(LibXml2)
-# set_package_properties(LibXml2 PROPERTIES DESCRIPTION "A XML processing library."
-# URL "http://xmlsoft.org/")
-#
-# set_package_properties(LibXml2 PROPERTIES TYPE RECOMMENDED
-# PURPOSE "Enables HTML-import in MyWordProcessor")
-# ...
-# set_package_properties(LibXml2 PROPERTIES TYPE OPTIONAL
-# PURPOSE "Enables odt-export in MyWordProcessor")
-#
-# find_package(DBUS)
-# set_package_properties(DBUS PROPERTIES TYPE RUNTIME
-# PURPOSE "Necessary to disable the screensaver during a presentation" )
-#
-# ADD_FEATURE_INFO(<name> <enabled> <description>)
-# Use this macro to add information about a feature with the given <name>.
-# <enabled> contains whether this feature is enabled or not, <description>
-# is a text describing the feature.
-# The information can be displayed using feature_summary() for ENABLED_FEATURES
-# and DISABLED_FEATURES respectively.
+#
+# ::
+#
+# find_package(LibXml2)
+# set_package_properties(LibXml2 PROPERTIES
+# DESCRIPTION "A XML processing library."
+# URL "http://xmlsoft.org/")
+#
+#
+#
+# ::
+#
+# set_package_properties(LibXml2 PROPERTIES
+# TYPE RECOMMENDED
+# PURPOSE "Enables HTML-import in MyWordProcessor")
+# ...
+# set_package_properties(LibXml2 PROPERTIES
+# TYPE OPTIONAL
+# PURPOSE "Enables odt-export in MyWordProcessor")
+#
+#
+#
+# ::
+#
+# find_package(DBUS)
+# set_package_properties(DBUS PROPERTIES
+# TYPE RUNTIME
+# PURPOSE "Necessary to disable the screensaver during a presentation" )
+#
+#
+#
+# ::
+#
+# ADD_FEATURE_INFO(<name> <enabled> <description>)
+#
+# Use this macro to add information about a feature with the given
+# <name>. <enabled> contains whether this feature is enabled or not,
+# <description> is a text describing the feature. The information can
+# be displayed using feature_summary() for ENABLED_FEATURES and
+# DISABLED_FEATURES respectively.
#
# Example for setting the info for a feature:
-# option(WITH_FOO "Help for foo" ON)
-# add_feature_info(Foo WITH_FOO "The Foo feature provides very cool stuff.")
#
+# ::
+#
+# option(WITH_FOO "Help for foo" ON)
+# add_feature_info(Foo WITH_FOO "The Foo feature provides very cool stuff.")
+#
+#
+#
+#
+#
+# The following macros are provided for compatibility with previous
+# CMake versions:
+#
+# ::
+#
+# SET_PACKAGE_INFO(<name> <description> [<url> [<purpose>] ] )
+#
+# Use this macro to set up information about the named package, which
+# can then be displayed via FEATURE_SUMMARY(). This can be done either
+# directly in the Find-module or in the project which uses the module
+# after the find_package() call. The features for which information can
+# be set are added automatically by the find_package() command.
+#
+# ::
#
-# The following macros are provided for compatibility with previous CMake versions:
+# PRINT_ENABLED_FEATURES()
#
-# SET_PACKAGE_INFO(<name> <description> [<url> [<purpose>] ] )
-# Use this macro to set up information about the named package, which can
-# then be displayed via FEATURE_SUMMARY().
-# This can be done either directly in the Find-module or in the project
-# which uses the module after the find_package() call.
-# The features for which information can be set are added automatically by the
-# find_package() command.
+# Does the same as FEATURE_SUMMARY(WHAT ENABLED_FEATURES DESCRIPTION
+# "Enabled features:")
#
-# PRINT_ENABLED_FEATURES()
-# Does the same as FEATURE_SUMMARY(WHAT ENABLED_FEATURES DESCRIPTION "Enabled features:")
+# ::
#
-# PRINT_DISABLED_FEATURES()
-# Does the same as FEATURE_SUMMARY(WHAT DISABLED_FEATURES DESCRIPTION "Disabled features:")
+# PRINT_DISABLED_FEATURES()
+#
+# Does the same as FEATURE_SUMMARY(WHAT DISABLED_FEATURES DESCRIPTION
+# "Disabled features:")
+#
+# ::
+#
+# SET_FEATURE_INFO(<name> <description> [<url>] )
#
-# SET_FEATURE_INFO(<name> <description> [<url>] )
# Does the same as SET_PACKAGE_INFO(<name> <description> <url> )
#=============================================================================
-# Copyright 2007-2009 Kitware, Inc.
+# Copyright 2007-2015 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
@@ -279,6 +379,9 @@ function(_FS_GET_FEATURE_SUMMARY _property _var _includeQuiet)
set(_currentFeatureText "")
get_property(_EnabledFeatures GLOBAL PROPERTY ${_property})
+ if(_EnabledFeatures)
+ list(REMOVE_DUPLICATES _EnabledFeatures)
+ endif(_EnabledFeatures)
foreach(_currentFeature ${_EnabledFeatures})
@@ -299,6 +402,12 @@ function(_FS_GET_FEATURE_SUMMARY _property _var _includeQuiet)
set(includeThisOne FALSE)
endif()
endif()
+ get_property(_isTransitiveDepend
+ GLOBAL PROPERTY _CMAKE_${_currentFeature}_TRANSITIVE_DEPENDENCY
+ )
+ if(_isTransitiveDepend)
+ set(includeThisOne FALSE)
+ endif()
if(includeThisOne)
@@ -334,8 +443,8 @@ endfunction()
function(FEATURE_SUMMARY)
# CMAKE_PARSE_ARGUMENTS(<prefix> <options> <one_value_keywords> <multi_value_keywords> args...)
set(options APPEND INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)
- set(oneValueArgs FILENAME VAR DESCRIPTION WHAT)
- set(multiValueArgs ) # none
+ set(oneValueArgs FILENAME VAR DESCRIPTION)
+ set(multiValueArgs WHAT)
CMAKE_PARSE_ARGUMENTS(_FS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN})
@@ -368,23 +477,42 @@ function(FEATURE_SUMMARY)
set(requiredPackagesNotFound TRUE)
endif()
- elseif("${_FS_WHAT}" STREQUAL "ALL")
+ else()
+ if("${_FS_WHAT}" STREQUAL "ALL")
- set(allWhatParts "ENABLED_FEATURES"
- "RUNTIME_PACKAGES_FOUND"
- "OPTIONAL_PACKAGES_FOUND"
- "RECOMMENDED_PACKAGES_FOUND"
- "REQUIRED_PACKAGES_FOUND"
+ set(allWhatParts "ENABLED_FEATURES"
+ "RUNTIME_PACKAGES_FOUND"
+ "OPTIONAL_PACKAGES_FOUND"
+ "RECOMMENDED_PACKAGES_FOUND"
+ "REQUIRED_PACKAGES_FOUND"
- "DISABLED_FEATURES"
- "RUNTIME_PACKAGES_NOT_FOUND"
- "OPTIONAL_PACKAGES_NOT_FOUND"
- "RECOMMENDED_PACKAGES_NOT_FOUND"
- "REQUIRED_PACKAGES_NOT_FOUND"
- )
+ "DISABLED_FEATURES"
+ "RUNTIME_PACKAGES_NOT_FOUND"
+ "OPTIONAL_PACKAGES_NOT_FOUND"
+ "RECOMMENDED_PACKAGES_NOT_FOUND"
+ "REQUIRED_PACKAGES_NOT_FOUND"
+ )
+
+ else()
+ set(allWhatParts)
+ foreach(part ${_FS_WHAT})
+ list(FIND validWhatParts "${part}" indexInList)
+ if(NOT "${indexInList}" STREQUAL "-1")
+ list(APPEND allWhatParts "${part}")
+ else()
+ if("${part}" STREQUAL "ALL")
+ message(FATAL_ERROR "The WHAT argument of FEATURE_SUMMARY() contains ALL, which cannot be combined with other values.")
+ else()
+ message(FATAL_ERROR "The WHAT argument of FEATURE_SUMMARY() contains ${part}, which is not a valid value.")
+ endif()
+ endif()
+ endforeach()
+ endif()
set(title_ENABLED_FEATURES "The following features have been enabled:")
set(title_DISABLED_FEATURES "The following features have been disabled:")
+ set(title_PACKAGES_FOUND "The following packages have been found:")
+ set(title_PACKAGES_NOT_FOUND "The following packages have not been found:")
set(title_OPTIONAL_PACKAGES_FOUND "The following OPTIONAL packages have been found:")
set(title_OPTIONAL_PACKAGES_NOT_FOUND "The following OPTIONAL packages have not been found:")
set(title_RECOMMENDED_PACKAGES_FOUND "The following RECOMMENDED packages have been found:")
@@ -405,8 +533,6 @@ function(FEATURE_SUMMARY)
endif()
endif()
endforeach()
- else()
- message(FATAL_ERROR "The WHAT argument of FEATURE_SUMMARY() is set to ${_FS_WHAT}, which is not a valid value.")
endif()
if(_FS_FILENAME)
@@ -436,13 +562,19 @@ endfunction()
# The stuff below is only kept for compatibility
function(SET_PACKAGE_INFO _name _desc)
- set(_url "${ARGV2}")
- set(_purpose "${ARGV3}")
+ unset(_url)
+ unset(_purpose)
+ if(ARGC GREATER 2)
+ set(_url "${ARGV2}")
+ endif()
+ if(ARGC GREATER 3)
+ set(_purpose "${ARGV3}")
+ endif()
set_property(GLOBAL PROPERTY _CMAKE_${_name}_DESCRIPTION "${_desc}" )
- if(_url MATCHES ".+")
+ if(NOT _url STREQUAL "")
set_property(GLOBAL PROPERTY _CMAKE_${_name}_URL "${_url}" )
endif()
- if(_purpose MATCHES ".+")
+ if(NOT _purpose STREQUAL "")
set_property(GLOBAL APPEND PROPERTY _CMAKE_${_name}_PURPOSE "${_purpose}" )
endif()
endfunction()
diff --git a/Modules/FindALSA.cmake b/Modules/FindALSA.cmake
index 60b0f56e6..5c30eb923 100644
--- a/Modules/FindALSA.cmake
+++ b/Modules/FindALSA.cmake
@@ -1,15 +1,25 @@
-# - Find alsa
+#.rst:
+# FindALSA
+# --------
+#
+# Find alsa
+#
# Find the alsa libraries (asound)
#
-# This module defines the following variables:
-# ALSA_FOUND - True if ALSA_INCLUDE_DIR & ALSA_LIBRARY are found
-# ALSA_LIBRARIES - Set when ALSA_LIBRARY is found
-# ALSA_INCLUDE_DIRS - Set when ALSA_INCLUDE_DIR is found
+# ::
+#
+# This module defines the following variables:
+# ALSA_FOUND - True if ALSA_INCLUDE_DIR & ALSA_LIBRARY are found
+# ALSA_LIBRARIES - Set when ALSA_LIBRARY is found
+# ALSA_INCLUDE_DIRS - Set when ALSA_INCLUDE_DIR is found
+#
+#
#
-# ALSA_INCLUDE_DIR - where to find asoundlib.h, etc.
-# ALSA_LIBRARY - the asound library
-# ALSA_VERSION_STRING - the version of alsa found (since CMake 2.8.8)
+# ::
#
+# ALSA_INCLUDE_DIR - where to find asoundlib.h, etc.
+# ALSA_LIBRARY - the asound library
+# ALSA_VERSION_STRING - the version of alsa found (since CMake 2.8.8)
#=============================================================================
# Copyright 2009-2011 Kitware, Inc.
diff --git a/Modules/FindASPELL.cmake b/Modules/FindASPELL.cmake
index 5b383c4d3..2a3f228fd 100644
--- a/Modules/FindASPELL.cmake
+++ b/Modules/FindASPELL.cmake
@@ -1,11 +1,18 @@
-# - Try to find ASPELL
+#.rst:
+# FindASPELL
+# ----------
+#
+# Try to find ASPELL
+#
# Once done this will define
#
-# ASPELL_FOUND - system has ASPELL
-# ASPELL_EXECUTABLE - the ASPELL executable
-# ASPELL_INCLUDE_DIR - the ASPELL include directory
-# ASPELL_LIBRARIES - The libraries needed to use ASPELL
-# ASPELL_DEFINITIONS - Compiler switches required for using ASPELL
+# ::
+#
+# ASPELL_FOUND - system has ASPELL
+# ASPELL_EXECUTABLE - the ASPELL executable
+# ASPELL_INCLUDE_DIR - the ASPELL include directory
+# ASPELL_LIBRARIES - The libraries needed to use ASPELL
+# ASPELL_DEFINITIONS - Compiler switches required for using ASPELL
#=============================================================================
# Copyright 2006-2009 Kitware, Inc.
diff --git a/Modules/FindAVIFile.cmake b/Modules/FindAVIFile.cmake
index 93fa40004..566107585 100644
--- a/Modules/FindAVIFile.cmake
+++ b/Modules/FindAVIFile.cmake
@@ -1,13 +1,20 @@
-# - Locate AVIFILE library and include paths
+#.rst:
+# FindAVIFile
+# -----------
+#
+# Locate AVIFILE library and include paths
+#
# AVIFILE (http://avifile.sourceforge.net/)is a set of libraries for
-# i386 machines
-# to use various AVI codecs. Support is limited beyond Linux. Windows
-# provides native AVI support, and so doesn't need this library.
-# This module defines
-# AVIFILE_INCLUDE_DIR, where to find avifile.h , etc.
-# AVIFILE_LIBRARIES, the libraries to link against
-# AVIFILE_DEFINITIONS, definitions to use when compiling
-# AVIFILE_FOUND, If false, don't try to use AVIFILE
+# i386 machines to use various AVI codecs. Support is limited beyond
+# Linux. Windows provides native AVI support, and so doesn't need this
+# library. This module defines
+#
+# ::
+#
+# AVIFILE_INCLUDE_DIR, where to find avifile.h , etc.
+# AVIFILE_LIBRARIES, the libraries to link against
+# AVIFILE_DEFINITIONS, definitions to use when compiling
+# AVIFILE_FOUND, If false, don't try to use AVIFILE
#=============================================================================
# Copyright 2002-2009 Kitware, Inc.
diff --git a/Modules/FindArmadillo.cmake b/Modules/FindArmadillo.cmake
index 4758534d7..454977197 100644
--- a/Modules/FindArmadillo.cmake
+++ b/Modules/FindArmadillo.cmake
@@ -1,20 +1,32 @@
-# - Find Armadillo
+#.rst:
+# FindArmadillo
+# -------------
+#
+# Find Armadillo
+#
# Find the Armadillo C++ library
#
# Using Armadillo:
-# find_package(Armadillo REQUIRED)
-# include_directories(${ARMADILLO_INCLUDE_DIRS})
-# add_executable(foo foo.cc)
-# target_link_libraries(foo ${ARMADILLO_LIBRARIES})
+#
+# ::
+#
+# find_package(Armadillo REQUIRED)
+# include_directories(${ARMADILLO_INCLUDE_DIRS})
+# add_executable(foo foo.cc)
+# target_link_libraries(foo ${ARMADILLO_LIBRARIES})
+#
# This module sets the following variables:
-# ARMADILLO_FOUND - set to true if the library is found
-# ARMADILLO_INCLUDE_DIRS - list of required include directories
-# ARMADILLO_LIBRARIES - list of libraries to be linked
-# ARMADILLO_VERSION_MAJOR - major version number
-# ARMADILLO_VERSION_MINOR - minor version number
-# ARMADILLO_VERSION_PATCH - patch version number
-# ARMADILLO_VERSION_STRING - version number as a string (ex: "1.0.4")
-# ARMADILLO_VERSION_NAME - name of the version (ex: "Antipodean Antileech")
+#
+# ::
+#
+# ARMADILLO_FOUND - set to true if the library is found
+# ARMADILLO_INCLUDE_DIRS - list of required include directories
+# ARMADILLO_LIBRARIES - list of libraries to be linked
+# ARMADILLO_VERSION_MAJOR - major version number
+# ARMADILLO_VERSION_MINOR - minor version number
+# ARMADILLO_VERSION_PATCH - patch version number
+# ARMADILLO_VERSION_STRING - version number as a string (ex: "1.0.4")
+# ARMADILLO_VERSION_NAME - name of the version (ex: "Antipodean Antileech")
#=============================================================================
# Copyright 2011 Clement Creusot <creusot@cs.york.ac.uk>
diff --git a/Modules/FindBISON.cmake b/Modules/FindBISON.cmake
index 4a3e68c68..7d81276c8 100644
--- a/Modules/FindBISON.cmake
+++ b/Modules/FindBISON.cmake
@@ -1,37 +1,76 @@
-# - Find bison executable and provides macros to generate custom build rules
+#.rst:
+# FindBISON
+# ---------
+#
+# Find ``bison`` executable and provide a macro to generate custom build rules.
+#
# The module defines the following variables:
#
-# BISON_EXECUTABLE - path to the bison program
-# BISON_VERSION - version of bison
-# BISON_FOUND - true if the program was found
-#
-# The minimum required version of bison can be specified using the
-# standard CMake syntax, e.g. find_package(BISON 2.1.3)
-#
-# If bison is found, the module defines the macros:
-# BISON_TARGET(<Name> <YaccInput> <CodeOutput> [VERBOSE <file>]
-# [COMPILE_FLAGS <string>])
-# which will create a custom rule to generate a parser. <YaccInput> is
-# the path to a yacc file. <CodeOutput> is the name of the source file
-# generated by bison. A header file is also be generated, and contains
-# the token list. If COMPILE_FLAGS option is specified, the next
-# parameter is added in the bison command line. if VERBOSE option is
-# specified, <file> is created and contains verbose descriptions of the
-# grammar and parser. The macro defines a set of variables:
-# BISON_${Name}_DEFINED - true is the macro ran successfully
-# BISON_${Name}_INPUT - The input source file, an alias for <YaccInput>
-# BISON_${Name}_OUTPUT_SOURCE - The source file generated by bison
-# BISON_${Name}_OUTPUT_HEADER - The header file generated by bison
-# BISON_${Name}_OUTPUTS - The sources files generated by bison
-# BISON_${Name}_COMPILE_FLAGS - Options used in the bison command line
-#
-# ====================================================================
-# Example:
+# ``BISON_EXECUTABLE``
+# path to the ``bison`` program
+#
+# ``BISON_VERSION``
+# version of ``bison``
+#
+# ``BISON_FOUND``
+# true if the program was found
+#
+# The minimum required version of ``bison`` can be specified using the
+# standard CMake syntax, e.g. ``find_package(BISON 2.1.3)``.
+#
+# If ``bison`` is found, the module defines the macro::
+#
+# BISON_TARGET(<Name> <YaccInput> <CodeOutput>
+# [COMPILE_FLAGS <flags>]
+# [DEFINES_FILE <file>]
+# [VERBOSE <file>]
+# )
+#
+# which will create a custom rule to generate a parser. ``<YaccInput>`` is
+# the path to a yacc file. ``<CodeOutput>`` is the name of the source file
+# generated by bison. A header file is also be generated, and contains
+# the token list.
+#
+# The options are:
+#
+# ``COMPILE_FLAGS <flags>``
+# Specify flags to be added to the ``bison`` command line.
+#
+# ``DEFINES_FILE <file>``
+# Specify a non-default header ``<file>`` to be generated by ``bison``.
+#
+# ``VERBOSE <file>``
+# Tell ``bison`` to write verbose descriptions of the grammar and
+# parser to the given ``<file>``.
+#
+# The macro defines the following variables:
+#
+# ``BISON_<Name>_DEFINED``
+# true is the macro ran successfully
+#
+# ``BISON_<Name>_INPUT``
+# The input source file, an alias for <YaccInput>
+#
+# ``BISON_<Name>_OUTPUT_SOURCE``
+# The source file generated by bison
+#
+# ``BISON_<Name>_OUTPUT_HEADER``
+# The header file generated by bison
+#
+# ``BISON_<Name>_OUTPUTS``
+# The sources files generated by bison
+#
+# ``BISON_<Name>_COMPILE_FLAGS``
+# Options used in the ``bison`` command line
+#
+# Example usage:
+#
+# .. code-block:: cmake
#
# find_package(BISON)
-# BISON_TARGET(MyParser parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp)
+# BISON_TARGET(MyParser parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp
+# DEFINES_FILE ${CMAKE_CURRENT_BINARY_DIR}/parser.h)
# add_executable(Foo main.cpp ${BISON_MyParser_OUTPUTS})
-# ====================================================================
#=============================================================================
# Copyright 2009 Kitware, Inc.
@@ -50,6 +89,8 @@
find_program(BISON_EXECUTABLE NAMES bison win_bison DOC "path to the bison executable")
mark_as_advanced(BISON_EXECUTABLE)
+include(CMakeParseArguments)
+
if(BISON_EXECUTABLE)
# the bison commands should be executed with the C locale, otherwise
# the message (which are parsed) may be translated
@@ -68,16 +109,13 @@ if(BISON_EXECUTABLE)
message(SEND_ERROR "Command \"${BISON_EXECUTABLE} --version\" failed with output:\n${BISON_version_error}")
else()
# Bison++
- if("${BISON_version_output}" MATCHES "^bison\\+\\+")
- string(REGEX REPLACE "^bison\\+\\+ Version ([^,]+).*" "\\1"
- BISON_VERSION "${BISON_version_output}")
+ if("${BISON_version_output}" MATCHES "^bison\\+\\+ Version ([^,]+)")
+ set(BISON_VERSION "${CMAKE_MATCH_1}")
# GNU Bison
- elseif("${BISON_version_output}" MATCHES "^bison[^+]")
- string(REGEX REPLACE "^bison \\(GNU Bison\\) ([^\n]+)\n.*" "\\1"
- BISON_VERSION "${BISON_version_output}")
- elseif("${BISON_version_output}" MATCHES "^GNU Bison ")
- string(REGEX REPLACE "^GNU Bison (version )?([^\n]+).*" "\\2"
- BISON_VERSION "${BISON_version_output}")
+ elseif("${BISON_version_output}" MATCHES "^bison \\(GNU Bison\\) ([^\n]+)\n")
+ set(BISON_VERSION "${CMAKE_MATCH_1}")
+ elseif("${BISON_version_output}" MATCHES "^GNU Bison (version )?([^\n]+)")
+ set(BISON_VERSION "${CMAKE_MATCH_2}")
endif()
endif()
@@ -107,6 +145,12 @@ if(BISON_EXECUTABLE)
list(APPEND BISON_TARGET_cmdopt ${BISON_TARGET_extraopts})
endmacro()
+ # internal macro
+ macro(BISON_TARGET_option_defines Header)
+ set(BISON_TARGET_output_header "${Header}")
+ list(APPEND BISON_TARGET_cmdopt --defines=${BISON_TARGET_output_header})
+ endmacro()
+
#============================================================
# BISON_TARGET (public macro)
#============================================================
@@ -115,51 +159,61 @@ if(BISON_EXECUTABLE)
set(BISON_TARGET_output_header "")
set(BISON_TARGET_cmdopt "")
set(BISON_TARGET_outputs "${BisonOutput}")
- if(NOT ${ARGC} EQUAL 3 AND NOT ${ARGC} EQUAL 5 AND NOT ${ARGC} EQUAL 7)
+
+ # Parsing parameters
+ set(BISON_TARGET_PARAM_OPTIONS)
+ set(BISON_TARGET_PARAM_ONE_VALUE_KEYWORDS
+ VERBOSE
+ COMPILE_FLAGS
+ DEFINES_FILE
+ )
+ set(BISON_TARGET_PARAM_MULTI_VALUE_KEYWORDS)
+ cmake_parse_arguments(
+ BISON_TARGET_ARG
+ "${BISON_TARGET_PARAM_OPTIONS}"
+ "${BISON_TARGET_PARAM_ONE_VALUE_KEYWORDS}"
+ "${BISON_TARGET_PARAM_MULTI_VALUE_KEYWORDS}"
+ ${ARGN}
+ )
+
+ if(NOT "${BISON_TARGET_ARG_UNPARSED_ARGUMENTS}" STREQUAL "")
message(SEND_ERROR "Usage")
else()
- # Parsing parameters
- if(${ARGC} GREATER 5 OR ${ARGC} EQUAL 5)
- if("${ARGV3}" STREQUAL "VERBOSE")
- BISON_TARGET_option_verbose(${Name} ${BisonOutput} "${ARGV4}")
- endif()
- if("${ARGV3}" STREQUAL "COMPILE_FLAGS")
- BISON_TARGET_option_extraopts("${ARGV4}")
- endif()
+ if(NOT "${BISON_TARGET_ARG_VERBOSE}" STREQUAL "")
+ BISON_TARGET_option_verbose(${Name} ${BisonOutput} "${BISON_TARGET_ARG_VERBOSE}")
endif()
-
- if(${ARGC} EQUAL 7)
- if("${ARGV5}" STREQUAL "VERBOSE")
- BISON_TARGET_option_verbose(${Name} ${BisonOutput} "${ARGV6}")
- endif()
-
- if("${ARGV5}" STREQUAL "COMPILE_FLAGS")
- BISON_TARGET_option_extraopts("${ARGV6}")
- endif()
+ if(NOT "${BISON_TARGET_ARG_COMPILE_FLAGS}" STREQUAL "")
+ BISON_TARGET_option_extraopts("${BISON_TARGET_ARG_COMPILE_FLAGS}")
+ endif()
+ if(NOT "${BISON_TARGET_ARG_DEFINES_FILE}" STREQUAL "")
+ BISON_TARGET_option_defines("${BISON_TARGET_ARG_DEFINES_FILE}")
endif()
- # Header's name generated by bison (see option -d)
- list(APPEND BISON_TARGET_cmdopt "-d")
- string(REGEX REPLACE "^(.*)(\\.[^.]*)$" "\\2" _fileext "${ARGV2}")
- string(REPLACE "c" "h" _fileext ${_fileext})
- string(REGEX REPLACE "^(.*)(\\.[^.]*)$" "\\1${_fileext}"
- BISON_${Name}_OUTPUT_HEADER "${ARGV2}")
- list(APPEND BISON_TARGET_outputs "${BISON_${Name}_OUTPUT_HEADER}")
+ if("${BISON_TARGET_output_header}" STREQUAL "")
+ # Header's name generated by bison (see option -d)
+ list(APPEND BISON_TARGET_cmdopt "-d")
+ string(REGEX REPLACE "^(.*)(\\.[^.]*)$" "\\2" _fileext "${BisonOutput}")
+ string(REPLACE "c" "h" _fileext ${_fileext})
+ string(REGEX REPLACE "^(.*)(\\.[^.]*)$" "\\1${_fileext}"
+ BISON_TARGET_output_header "${BisonOutput}")
+ endif()
+ list(APPEND BISON_TARGET_outputs "${BISON_TARGET_output_header}")
add_custom_command(OUTPUT ${BISON_TARGET_outputs}
${BISON_TARGET_extraoutputs}
COMMAND ${BISON_EXECUTABLE}
- ARGS ${BISON_TARGET_cmdopt} -o ${ARGV2} ${ARGV1}
- DEPENDS ${ARGV1}
+ ARGS ${BISON_TARGET_cmdopt} -o ${BisonOutput} ${BisonInput}
+ DEPENDS ${BisonInput}
COMMENT "[BISON][${Name}] Building parser with bison ${BISON_VERSION}"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
# define target variables
set(BISON_${Name}_DEFINED TRUE)
- set(BISON_${Name}_INPUT ${ARGV1})
+ set(BISON_${Name}_INPUT ${BisonInput})
set(BISON_${Name}_OUTPUTS ${BISON_TARGET_outputs})
set(BISON_${Name}_COMPILE_FLAGS ${BISON_TARGET_cmdopt})
set(BISON_${Name}_OUTPUT_SOURCE "${BisonOutput}")
+ set(BISON_${Name}_OUTPUT_HEADER "${BISON_TARGET_output_header}")
endif()
endmacro()
diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake
index f8a284d71..416b666b9 100644
--- a/Modules/FindBLAS.cmake
+++ b/Modules/FindBLAS.cmake
@@ -1,31 +1,41 @@
-# - Find BLAS library
-# This module finds an installed fortran library that implements the BLAS
-# linear-algebra interface (see http://www.netlib.org/blas/).
-# The list of libraries searched for is taken
-# from the autoconf macro file, acx_blas.m4 (distributed at
+#.rst:
+# FindBLAS
+# --------
+#
+# Find BLAS library
+#
+# This module finds an installed fortran library that implements the
+# BLAS linear-algebra interface (see http://www.netlib.org/blas/). The
+# list of libraries searched for is taken from the autoconf macro file,
+# acx_blas.m4 (distributed at
# http://ac-archive.sourceforge.net/ac-archive/acx_blas.html).
#
# This module sets the following variables:
-# BLAS_FOUND - set to true if a library implementing the BLAS interface
-# is found
-# BLAS_LINKER_FLAGS - uncached list of required linker flags (excluding -l
-# and -L).
-# BLAS_LIBRARIES - uncached list of libraries (using full path name) to
-# link against to use BLAS
-# BLAS95_LIBRARIES - uncached list of libraries (using full path name)
-# to link against to use BLAS95 interface
-# BLAS95_FOUND - set to true if a library implementing the BLAS f95 interface
-# is found
-# BLA_STATIC if set on this determines what kind of linkage we do (static)
-# BLA_VENDOR if set checks only the specified vendor, if not set checks
-# all the possibilities
-# BLA_F95 if set on tries to find the f95 interfaces for BLAS/LAPACK
-##########
-### List of vendors (BLA_VENDOR) valid in this module
-## Goto,ATLAS PhiPACK,CXML,DXML,SunPerf,SCSL,SGIMATH,IBMESSL,Intel10_32 (intel mkl v10 32 bit),Intel10_64lp (intel mkl v10 64 bit,lp thread model, lp64 model),
-## Intel10_64lp_seq (intel mkl v10 64 bit,sequential code, lp64 model),
-## Intel( older versions of mkl 32 and 64 bit), ACML,ACML_MP,ACML_GPU,Apple, NAS, Generic
-# C/CXX should be enabled to use Intel mkl
+#
+# ::
+#
+# BLAS_FOUND - set to true if a library implementing the BLAS interface
+# is found
+# BLAS_LINKER_FLAGS - uncached list of required linker flags (excluding -l
+# and -L).
+# BLAS_LIBRARIES - uncached list of libraries (using full path name) to
+# link against to use BLAS
+# BLAS95_LIBRARIES - uncached list of libraries (using full path name)
+# to link against to use BLAS95 interface
+# BLAS95_FOUND - set to true if a library implementing the BLAS f95 interface
+# is found
+# BLA_STATIC if set on this determines what kind of linkage we do (static)
+# BLA_VENDOR if set checks only the specified vendor, if not set checks
+# all the possibilities
+# BLA_F95 if set on tries to find the f95 interfaces for BLAS/LAPACK
+#
+# ######### ## List of vendors (BLA_VENDOR) valid in this module #
+# Goto,ATLAS PhiPACK,CXML,DXML,SunPerf,SCSL,SGIMATH,IBMESSL,Intel10_32
+# (intel mkl v10 32 bit),Intel10_64lp (intel mkl v10 64 bit,lp thread
+# model, lp64 model), # Intel10_64lp_seq (intel mkl v10 64
+# bit,sequential code, lp64 model), # Intel( older versions of mkl 32
+# and 64 bit), ACML,ACML_MP,ACML_GPU,Apple, NAS, Generic C/CXX should be
+# enabled to use Intel mkl
#=============================================================================
# Copyright 2007-2009 Kitware, Inc.
@@ -42,6 +52,9 @@
include(${CMAKE_CURRENT_LIST_DIR}/CheckFunctionExists.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/CheckFortranFunctionExists.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake)
+cmake_push_check_state()
+set(CMAKE_REQUIRED_QUIET ${BLAS_FIND_QUIETLY})
set(_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
@@ -137,7 +150,7 @@ endmacro()
set(BLAS_LINKER_FLAGS)
set(BLAS_LIBRARIES)
set(BLAS95_LIBRARIES)
-if ($ENV{BLA_VENDOR} MATCHES ".+")
+if (NOT $ENV{BLA_VENDOR} STREQUAL "")
set(BLA_VENDOR $ENV{BLA_VENDOR})
else ()
if(NOT BLA_VENDOR)
@@ -275,7 +288,7 @@ if (BLA_VENDOR STREQUAL "IBMESSL" OR BLA_VENDOR STREQUAL "All")
endif ()
#BLAS in acml library?
-if (BLA_VENDOR MATCHES "ACML.*" OR BLA_VENDOR STREQUAL "All")
+if (BLA_VENDOR MATCHES "ACML" OR BLA_VENDOR STREQUAL "All")
if( ((BLA_VENDOR STREQUAL "ACML") AND (NOT BLAS_ACML_LIB_DIRS)) OR
((BLA_VENDOR STREQUAL "ACML_MP") AND (NOT BLAS_ACML_MP_LIB_DIRS)) OR
((BLA_VENDOR STREQUAL "ACML_GPU") AND (NOT BLAS_ACML_GPU_LIB_DIRS))
@@ -452,7 +465,7 @@ if (BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All")
endif ()
#BLAS in intel mkl 10 library? (em64t 64bit)
-if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All")
+if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All")
if (NOT WIN32)
set(LM "-lm")
endif ()
@@ -469,8 +482,45 @@ if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All")
set(BLAS_mkl_SEARCH_SYMBOL SGEMM)
set(_LIBRARIES BLAS95_LIBRARIES)
if (WIN32)
- list(APPEND BLAS_SEARCH_LIBS
- "mkl_blas95 mkl_intel_c mkl_intel_thread mkl_core libguide40")
+ if (BLA_STATIC)
+ set(BLAS_mkl_DLL_SUFFIX "")
+ else()
+ set(BLAS_mkl_DLL_SUFFIX "_dll")
+ endif()
+
+ # Find the main file (32-bit or 64-bit)
+ set(BLAS_SEARCH_LIBS_WIN_MAIN "")
+ if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
+ list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN
+ "mkl_blas95${BLAS_mkl_DLL_SUFFIX} mkl_intel_c${BLAS_mkl_DLL_SUFFIX}")
+ endif()
+ if (BLA_VENDOR MATCHES "^Intel10_64lp" OR BLA_VENDOR STREQUAL "All")
+ list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN
+ "mkl_blas95_lp64${BLAS_mkl_DLL_SUFFIX} mkl_intel_lp64${BLAS_mkl_DLL_SUFFIX}")
+ endif ()
+
+ # Add threading/sequential libs
+ set(BLAS_SEARCH_LIBS_WIN_THREAD "")
+ if (BLA_VENDOR MATCHES "_seq$" OR BLA_VENDOR STREQUAL "All")
+ list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
+ "mkl_sequential${BLAS_mkl_DLL_SUFFIX}")
+ endif()
+ if (NOT BLA_VENDOR MATCHES "_seq$" OR BLA_VENDOR STREQUAL "All")
+ # old version
+ list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
+ "libguide40 mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}")
+ # mkl >= 10.3
+ list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
+ "libiomp5md mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}")
+ endif()
+
+ # Cartesian product of the above
+ foreach (MAIN ${BLAS_SEARCH_LIBS_WIN_MAIN})
+ foreach (THREAD ${BLAS_SEARCH_LIBS_WIN_THREAD})
+ list(APPEND BLAS_SEARCH_LIBS
+ "${MAIN} ${THREAD} mkl_core${BLAS_mkl_DLL_SUFFIX}")
+ endforeach()
+ endforeach()
else ()
if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
list(APPEND BLAS_SEARCH_LIBS
@@ -482,7 +532,7 @@ if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All")
"mkl_blas95 mkl_intel_lp64 mkl_intel_thread mkl_core guide")
# mkl >= 10.3
- if (CMAKE_C_COMPILER MATCHES ".+gcc.*")
+ if (CMAKE_C_COMPILER MATCHES ".+gcc")
list(APPEND BLAS_SEARCH_LIBS
"mkl_blas95_lp64 mkl_intel_lp64 mkl_gnu_thread mkl_core gomp")
else ()
@@ -490,17 +540,54 @@ if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All")
"mkl_blas95_lp64 mkl_intel_lp64 mkl_intel_thread mkl_core iomp5")
endif ()
endif ()
- endif ()
- if (BLA_VENDOR STREQUAL "Intel10_64lp_seq" OR BLA_VENDOR STREQUAL "All")
- list(APPEND BLAS_SEARCH_LIBS
- "mkl_blas95_lp64 mkl_intel_lp64 mkl_sequential mkl_core")
+ if (BLA_VENDOR STREQUAL "Intel10_64lp_seq" OR BLA_VENDOR STREQUAL "All")
+ list(APPEND BLAS_SEARCH_LIBS
+ "mkl_intel_lp64 mkl_sequential mkl_core")
+ endif ()
endif ()
else ()
set(BLAS_mkl_SEARCH_SYMBOL sgemm)
set(_LIBRARIES BLAS_LIBRARIES)
if (WIN32)
- list(APPEND BLAS_SEARCH_LIBS
- "mkl_c_dll mkl_intel_thread_dll mkl_core_dll libguide40")
+ if (BLA_STATIC)
+ set(BLAS_mkl_DLL_SUFFIX "")
+ else()
+ set(BLAS_mkl_DLL_SUFFIX "_dll")
+ endif()
+
+ # Find the main file (32-bit or 64-bit)
+ set(BLAS_SEARCH_LIBS_WIN_MAIN "")
+ if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
+ list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN
+ "mkl_intel_c${BLAS_mkl_DLL_SUFFIX}")
+ endif()
+ if (BLA_VENDOR MATCHES "^Intel10_64lp" OR BLA_VENDOR STREQUAL "All")
+ list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN
+ "mkl_intel_lp64${BLAS_mkl_DLL_SUFFIX}")
+ endif ()
+
+ # Add threading/sequential libs
+ set(BLAS_SEARCH_LIBS_WIN_THREAD "")
+ if (NOT BLA_VENDOR MATCHES "_seq$" OR BLA_VENDOR STREQUAL "All")
+ # old version
+ list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
+ "libguide40 mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}")
+ # mkl >= 10.3
+ list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
+ "libiomp5md mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}")
+ endif()
+ if (BLA_VENDOR MATCHES "_seq$" OR BLA_VENDOR STREQUAL "All")
+ list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
+ "mkl_sequential${BLAS_mkl_DLL_SUFFIX}")
+ endif()
+
+ # Cartesian product of the above
+ foreach (MAIN ${BLAS_SEARCH_LIBS_WIN_MAIN})
+ foreach (THREAD ${BLAS_SEARCH_LIBS_WIN_THREAD})
+ list(APPEND BLAS_SEARCH_LIBS
+ "${MAIN} ${THREAD} mkl_core${BLAS_mkl_DLL_SUFFIX}")
+ endforeach()
+ endforeach()
else ()
if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
list(APPEND BLAS_SEARCH_LIBS
@@ -513,7 +600,7 @@ if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All")
"mkl_intel_lp64 mkl_intel_thread mkl_core guide")
# mkl >= 10.3
- if (CMAKE_C_COMPILER MATCHES ".+gcc.*")
+ if (CMAKE_C_COMPILER MATCHES ".+gcc")
list(APPEND BLAS_SEARCH_LIBS
"mkl_intel_lp64 mkl_gnu_thread mkl_core gomp")
else ()
@@ -521,6 +608,10 @@ if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All")
"mkl_intel_lp64 mkl_intel_thread mkl_core iomp5")
endif ()
endif ()
+ if (BLA_VENDOR STREQUAL "Intel10_64lp_seq" OR BLA_VENDOR STREQUAL "All")
+ list(APPEND BLAS_SEARCH_LIBS
+ "mkl_intel_lp64 mkl_sequential mkl_core")
+ endif ()
#older vesions of intel mkl libs
if (BLA_VENDOR STREQUAL "Intel" OR BLA_VENDOR STREQUAL "All")
@@ -532,10 +623,6 @@ if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All")
"mkl_em64t")
endif ()
endif ()
- if (BLA_VENDOR STREQUAL "Intel10_64lp_seq" OR BLA_VENDOR STREQUAL "All")
- list(APPEND BLAS_SEARCH_LIBS
- "mkl_intel_lp64 mkl_sequential mkl_core")
- endif ()
endif ()
foreach (IT ${BLAS_SEARCH_LIBS})
@@ -603,4 +690,5 @@ else()
endif()
endif()
+cmake_pop_check_state()
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
diff --git a/Modules/FindBZip2.cmake b/Modules/FindBZip2.cmake
index 9fb29d0f4..6af42ddb5 100644
--- a/Modules/FindBZip2.cmake
+++ b/Modules/FindBZip2.cmake
@@ -1,11 +1,18 @@
-# - Try to find BZip2
+#.rst:
+# FindBZip2
+# ---------
+#
+# Try to find BZip2
+#
# Once done this will define
#
-# BZIP2_FOUND - system has BZip2
-# BZIP2_INCLUDE_DIR - the BZip2 include directory
-# BZIP2_LIBRARIES - Link these to use BZip2
-# BZIP2_NEED_PREFIX - this is set if the functions are prefixed with BZ2_
-# BZIP2_VERSION_STRING - the version of BZip2 found (since CMake 2.8.8)
+# ::
+#
+# BZIP2_FOUND - system has BZip2
+# BZIP2_INCLUDE_DIR - the BZip2 include directory
+# BZIP2_LIBRARIES - Link these to use BZip2
+# BZIP2_NEED_PREFIX - this is set if the functions are prefixed with BZ2_
+# BZIP2_VERSION_STRING - the version of BZip2 found (since CMake 2.8.8)
#=============================================================================
# Copyright 2006-2012 Kitware, Inc.
@@ -49,8 +56,14 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(BZip2
VERSION_VAR BZIP2_VERSION_STRING)
if (BZIP2_FOUND)
- include(${CMAKE_CURRENT_LIST_DIR}/CheckLibraryExists.cmake)
- CHECK_LIBRARY_EXISTS("${BZIP2_LIBRARIES}" BZ2_bzCompressInit "" BZIP2_NEED_PREFIX)
+ include(${CMAKE_CURRENT_LIST_DIR}/CheckSymbolExists.cmake)
+ include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake)
+ cmake_push_check_state()
+ set(CMAKE_REQUIRED_QUIET ${BZip2_FIND_QUIETLY})
+ set(CMAKE_REQUIRED_INCLUDES ${BZIP2_INCLUDE_DIR})
+ set(CMAKE_REQUIRED_LIBRARIES ${BZIP2_LIBRARIES})
+ CHECK_SYMBOL_EXISTS(BZ2_bzCompressInit "bzlib.h" BZIP2_NEED_PREFIX)
+ cmake_pop_check_state()
endif ()
mark_as_advanced(BZIP2_INCLUDE_DIR)
diff --git a/Modules/FindBacktrace.cmake b/Modules/FindBacktrace.cmake
new file mode 100644
index 000000000..cb4f60a57
--- /dev/null
+++ b/Modules/FindBacktrace.cmake
@@ -0,0 +1,101 @@
+#.rst:
+# FindBacktrace
+# -------------
+#
+# Find provider for backtrace(3).
+#
+# Checks if OS supports backtrace(3) via either libc or custom library.
+# This module defines the following variables:
+#
+# ``Backtrace_HEADER``
+# The header file needed for backtrace(3). Cached.
+# Could be forcibly set by user.
+# ``Backtrace_INCLUDE_DIRS``
+# The include directories needed to use backtrace(3) header.
+# ``Backtrace_LIBRARIES``
+# The libraries (linker flags) needed to use backtrace(3), if any.
+# ``Backtrace_FOUND``
+# Is set if and only if backtrace(3) support detected.
+#
+# The following cache variables are also available to set or use:
+#
+# ``Backtrace_LIBRARY``
+# The external library providing backtrace, if any.
+# ``Backtrace_INCLUDE_DIR``
+# The directory holding the backtrace(3) header.
+#
+# Typical usage is to generate of header file using configure_file() with the
+# contents like the following::
+#
+# #cmakedefine01 Backtrace_FOUND
+# #if Backtrace_FOUND
+# # include <${Backtrace_HEADER}>
+# #endif
+#
+# And then reference that generated header file in actual source.
+
+#=============================================================================
+# Copyright 2013 Vadim Zhukov
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+
+include(CMakePushCheckState)
+include(CheckSymbolExists)
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+
+# List of variables to be provided to find_package_handle_standard_args()
+set(_Backtrace_STD_ARGS Backtrace_INCLUDE_DIR)
+
+if(Backtrace_HEADER)
+ set(_Backtrace_HEADER_TRY "${Backtrace_HEADER}")
+else(Backtrace_HEADER)
+ set(_Backtrace_HEADER_TRY "execinfo.h")
+endif(Backtrace_HEADER)
+
+find_path(Backtrace_INCLUDE_DIR "${_Backtrace_HEADER_TRY}")
+set(Backtrace_INCLUDE_DIRS ${Backtrace_INCLUDE_DIR})
+
+if (NOT DEFINED Backtrace_LIBRARY)
+ # First, check if we already have backtrace(), e.g., in libc
+ cmake_push_check_state(RESET)
+ set(CMAKE_REQUIRED_INCLUDES ${Backtrace_INCLUDE_DIRS})
+ set(CMAKE_REQUIRED_QUIET ${Backtrace_FIND_QUIETLY})
+ check_symbol_exists("backtrace" "${_Backtrace_HEADER_TRY}" _Backtrace_SYM_FOUND)
+ cmake_pop_check_state()
+endif()
+
+if(_Backtrace_SYM_FOUND)
+ # Avoid repeating the message() call below each time CMake is run.
+ if(NOT Backtrace_FIND_QUIETLY AND NOT DEFINED Backtrace_LIBRARY)
+ message(STATUS "backtrace facility detected in default set of libraries")
+ endif()
+ set(Backtrace_LIBRARY "" CACHE FILEPATH "Library providing backtrace(3), empty for default set of libraries")
+else()
+ # Check for external library, for non-glibc systems
+ if(Backtrace_INCLUDE_DIR)
+ # OpenBSD has libbacktrace renamed to libexecinfo
+ find_library(Backtrace_LIBRARY "execinfo")
+ elseif() # respect user wishes
+ set(_Backtrace_HEADER_TRY "backtrace.h")
+ find_path(Backtrace_INCLUDE_DIR ${_Backtrace_HEADER_TRY})
+ find_library(Backtrace_LIBRARY "backtrace")
+ endif()
+
+ # Prepend list with library path as it's more common practice
+ set(_Backtrace_STD_ARGS Backtrace_LIBRARY ${_Backtrace_STD_ARGS})
+endif()
+
+set(Backtrace_LIBRARIES ${Backtrace_LIBRARY})
+set(Backtrace_HEADER "${_Backtrace_HEADER_TRY}" CACHE STRING "Header providing backtrace(3) facility")
+
+find_package_handle_standard_args(Backtrace FOUND_VAR Backtrace_FOUND REQUIRED_VARS ${_Backtrace_STD_ARGS})
+mark_as_advanced(Backtrace_HEADER Backtrace_INCLUDE_DIR Backtrace_LIBRARY)
diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake
index 914a0a5b5..728dcdfdf 100644
--- a/Modules/FindBoost.cmake
+++ b/Modules/FindBoost.cmake
@@ -1,136 +1,204 @@
-# - Find Boost include dirs and libraries
-# Use this module by invoking find_package with the form:
-# find_package(Boost
-# [version] [EXACT] # Minimum or EXACT version e.g. 1.36.0
-# [REQUIRED] # Fail with error if Boost is not found
-# [COMPONENTS <libs>...] # Boost libraries by their canonical name
-# ) # e.g. "date_time" for "libboost_date_time"
+#.rst:
+# FindBoost
+# ---------
+#
+# Find Boost include dirs and libraries
+#
+# Use this module by invoking find_package with the form::
+#
+# find_package(Boost
+# [version] [EXACT] # Minimum or EXACT version e.g. 1.36.0
+# [REQUIRED] # Fail with error if Boost is not found
+# [COMPONENTS <libs>...] # Boost libraries by their canonical name
+# ) # e.g. "date_time" for "libboost_date_time"
+#
# This module finds headers and requested component libraries OR a CMake
# package configuration file provided by a "Boost CMake" build. For the
# latter case skip to the "Boost CMake" section below. For the former
-# case results are reported in variables:
-# Boost_FOUND - True if headers and requested libraries were found
-# Boost_INCLUDE_DIRS - Boost include directories
-# Boost_LIBRARY_DIRS - Link directories for Boost libraries
-# Boost_LIBRARIES - Boost component libraries to be linked
-# Boost_<C>_FOUND - True if component <C> was found (<C> is upper-case)
-# Boost_<C>_LIBRARY - Libraries to link for component <C> (may include
-# target_link_libraries debug/optimized keywords)
-# Boost_VERSION - BOOST_VERSION value from boost/version.hpp
-# Boost_LIB_VERSION - Version string appended to library filenames
-# Boost_MAJOR_VERSION - Boost major version number (X in X.y.z)
-# Boost_MINOR_VERSION - Boost minor version number (Y in x.Y.z)
-# Boost_SUBMINOR_VERSION - Boost subminor version number (Z in x.y.Z)
-# Boost_LIB_DIAGNOSTIC_DEFINITIONS (Windows)
-# - Pass to add_definitions() to have diagnostic
-# information about Boost's automatic linking
-# displayed during compilation
+# case results are reported in variables::
+#
+# Boost_FOUND - True if headers and requested libraries were found
+# Boost_INCLUDE_DIRS - Boost include directories
+# Boost_LIBRARY_DIRS - Link directories for Boost libraries
+# Boost_LIBRARIES - Boost component libraries to be linked
+# Boost_<C>_FOUND - True if component <C> was found (<C> is upper-case)
+# Boost_<C>_LIBRARY - Libraries to link for component <C> (may include
+# target_link_libraries debug/optimized keywords)
+# Boost_VERSION - BOOST_VERSION value from boost/version.hpp
+# Boost_LIB_VERSION - Version string appended to library filenames
+# Boost_MAJOR_VERSION - Boost major version number (X in X.y.z)
+# Boost_MINOR_VERSION - Boost minor version number (Y in x.Y.z)
+# Boost_SUBMINOR_VERSION - Boost subminor version number (Z in x.y.Z)
+# Boost_LIB_DIAGNOSTIC_DEFINITIONS (Windows)
+# - Pass to add_definitions() to have diagnostic
+# information about Boost's automatic linking
+# displayed during compilation
+#
+# This module reads hints about search locations from variables::
+#
+# BOOST_ROOT - Preferred installation prefix
+# (or BOOSTROOT)
+# BOOST_INCLUDEDIR - Preferred include directory e.g. <prefix>/include
+# BOOST_LIBRARYDIR - Preferred library directory e.g. <prefix>/lib
+# Boost_NO_SYSTEM_PATHS - Set to ON to disable searching in locations not
+# specified by these hint variables. Default is OFF.
+# Boost_ADDITIONAL_VERSIONS
+# - List of Boost versions not known to this module
+# (Boost install locations may contain the version)
+#
+# and saves search results persistently in CMake cache entries::
+#
+# Boost_INCLUDE_DIR - Directory containing Boost headers
+# Boost_LIBRARY_DIR_RELEASE - Directory containing release Boost libraries
+# Boost_LIBRARY_DIR_DEBUG - Directory containing debug Boost libraries
+# Boost_<C>_LIBRARY_DEBUG - Component <C> library debug variant
+# Boost_<C>_LIBRARY_RELEASE - Component <C> library release variant
+#
+# The following :prop_tgt:`IMPORTED` targets are also defined::
+#
+# Boost::boost - Target for header-only dependencies
+# (Boost include directory)
+# Boost::<C> - Target for specific component dependency
+# (shared or static library); <C> is lower-
+# case
+# Boost::diagnostic_definitions - interface target to enable diagnostic
+# information about Boost's automatic linking
+# during compilation (adds BOOST_LIB_DIAGNOSTIC)
+# Boost::disable_autolinking - interface target to disable automatic
+# linking with MSVC (adds BOOST_ALL_NO_LIB)
+# Boost::dynamic_linking - interface target to enable dynamic linking
+# linking with MSVC (adds BOOST_ALL_DYN_LINK)
+#
+# Implicit dependencies such as Boost::filesystem requiring
+# Boost::system will be automatically detected and satisfied, even
+# if system is not specified when using find_package and if
+# Boost::system is not added to target_link_libraries. If using
+# Boost::thread, then Thread::Thread will also be added automatically.
+#
+# It is important to note that the imported targets behave differently
+# than variables created by this module: multiple calls to
+# find_package(Boost) in the same directory or sub-directories with
+# different options (e.g. static or shared) will not override the
+# values of the targets created by the first call.
+#
+# Users may set these hints or results as cache entries. Projects
+# should not read these entries directly but instead use the above
+# result variables. Note that some hint names start in upper-case
+# "BOOST". One may specify these as environment variables if they are
+# not specified as CMake variables or cache entries.
+#
+# This module first searches for the Boost header files using the above
+# hint variables (excluding BOOST_LIBRARYDIR) and saves the result in
+# Boost_INCLUDE_DIR. Then it searches for requested component libraries
+# using the above hints (excluding BOOST_INCLUDEDIR and
+# Boost_ADDITIONAL_VERSIONS), "lib" directories near Boost_INCLUDE_DIR,
+# and the library name configuration settings below. It saves the
+# library directories in Boost_LIBRARY_DIR_DEBUG and
+# Boost_LIBRARY_DIR_RELEASE and individual library
+# locations in Boost_<C>_LIBRARY_DEBUG and Boost_<C>_LIBRARY_RELEASE.
+# When one changes settings used by previous searches in the same build
+# tree (excluding environment variables) this module discards previous
+# search results affected by the changes and searches again.
+#
+# Boost libraries come in many variants encoded in their file name.
+# Users or projects may tell this module which variant to find by
+# setting variables::
+#
+# Boost_USE_MULTITHREADED - Set to OFF to use the non-multithreaded
+# libraries ('mt' tag). Default is ON.
+# Boost_USE_STATIC_LIBS - Set to ON to force the use of the static
+# libraries. Default is OFF.
+# Boost_USE_STATIC_RUNTIME - Set to ON or OFF to specify whether to use
+# libraries linked statically to the C++ runtime
+# ('s' tag). Default is platform dependent.
+# Boost_USE_DEBUG_RUNTIME - Set to ON or OFF to specify whether to use
+# libraries linked to the MS debug C++ runtime
+# ('g' tag). Default is ON.
+# Boost_USE_DEBUG_PYTHON - Set to ON to use libraries compiled with a
+# debug Python build ('y' tag). Default is OFF.
+# Boost_USE_STLPORT - Set to ON to use libraries compiled with
+# STLPort ('p' tag). Default is OFF.
+# Boost_USE_STLPORT_DEPRECATED_NATIVE_IOSTREAMS
+# - Set to ON to use libraries compiled with
+# STLPort deprecated "native iostreams"
+# ('n' tag). Default is OFF.
+# Boost_COMPILER - Set to the compiler-specific library suffix
+# (e.g. "-gcc43"). Default is auto-computed
+# for the C++ compiler in use.
+# Boost_THREADAPI - Suffix for "thread" component library name,
+# such as "pthread" or "win32". Names with
+# and without this suffix will both be tried.
+# Boost_NAMESPACE - Alternate namespace used to build boost with
+# e.g. if set to "myboost", will search for
+# myboost_thread instead of boost_thread.
#
-# This module reads hints about search locations from variables:
-# BOOST_ROOT - Preferred installation prefix
-# (or BOOSTROOT)
-# BOOST_INCLUDEDIR - Preferred include directory e.g. <prefix>/include
-# BOOST_LIBRARYDIR - Preferred library directory e.g. <prefix>/lib
-# Boost_NO_SYSTEM_PATHS - Set to ON to disable searching in locations not
-# specified by these hint variables. Default is OFF.
-# Boost_ADDITIONAL_VERSIONS
-# - List of Boost versions not known to this module
-# (Boost install locations may contain the version)
-# and saves search results persistently in CMake cache entries:
-# Boost_INCLUDE_DIR - Directory containing Boost headers
-# Boost_LIBRARY_DIR - Directory containing Boost libraries
-# Boost_<C>_LIBRARY_DEBUG - Component <C> library debug variant
-# Boost_<C>_LIBRARY_RELEASE - Component <C> library release variant
-# Users may set these hints or results as cache entries. Projects should
-# not read these entries directly but instead use the above result variables.
-# Note that some hint names start in upper-case "BOOST". One may specify
-# these as environment variables if they are not specified as CMake variables
-# or cache entries.
+# Other variables one may set to control this module are::
#
-# This module first searches for the Boost header files using the above hint
-# variables (excluding BOOST_LIBRARYDIR) and saves the result in
-# Boost_INCLUDE_DIR. Then it searches for requested component libraries using
-# the above hints (excluding BOOST_INCLUDEDIR and Boost_ADDITIONAL_VERSIONS),
-# "lib" directories near Boost_INCLUDE_DIR, and the library name configuration
-# settings below. It saves the library directory in Boost_LIBRARY_DIR and
-# individual library locations in Boost_<C>_LIBRARY_DEBUG and
-# Boost_<C>_LIBRARY_RELEASE. When one changes settings used by previous
-# searches in the same build tree (excluding environment variables) this
-# module discards previous search results affected by the changes and searches
-# again.
+# Boost_DEBUG - Set to ON to enable debug output from FindBoost.
+# Please enable this before filing any bug report.
+# Boost_DETAILED_FAILURE_MSG
+# - Set to ON to add detailed information to the
+# failure message even when the REQUIRED option
+# is not given to the find_package call.
+# Boost_REALPATH - Set to ON to resolve symlinks for discovered
+# libraries to assist with packaging. For example,
+# the "system" component library may be resolved to
+# "/usr/lib/libboost_system.so.1.42.0" instead of
+# "/usr/lib/libboost_system.so". This does not
+# affect linking and should not be enabled unless
+# the user needs this information.
+# Boost_LIBRARY_DIR - Default value for Boost_LIBRARY_DIR_RELEASE and
+# Boost_LIBRARY_DIR_DEBUG.
#
-# Boost libraries come in many variants encoded in their file name. Users or
-# projects may tell this module which variant to find by setting variables:
-# Boost_USE_MULTITHREADED - Set to OFF to use the non-multithreaded
-# libraries ('mt' tag). Default is ON.
-# Boost_USE_STATIC_LIBS - Set to ON to force the use of the static
-# libraries. Default is OFF.
-# Boost_USE_STATIC_RUNTIME - Set to ON or OFF to specify whether to use
-# libraries linked statically to the C++ runtime
-# ('s' tag). Default is platform dependent.
-# Boost_USE_DEBUG_PYTHON - Set to ON to use libraries compiled with a
-# debug Python build ('y' tag). Default is OFF.
-# Boost_USE_STLPORT - Set to ON to use libraries compiled with
-# STLPort ('p' tag). Default is OFF.
-# Boost_USE_STLPORT_DEPRECATED_NATIVE_IOSTREAMS
-# - Set to ON to use libraries compiled with
-# STLPort deprecated "native iostreams"
-# ('n' tag). Default is OFF.
-# Boost_COMPILER - Set to the compiler-specific library suffix
-# (e.g. "-gcc43"). Default is auto-computed
-# for the C++ compiler in use.
-# Boost_THREADAPI - Suffix for "thread" component library name,
-# such as "pthread" or "win32". Names with
-# and without this suffix will both be tried.
-# Other variables one may set to control this module are:
-# Boost_DEBUG - Set to ON to enable debug output from FindBoost.
-# Please enable this before filing any bug report.
-# Boost_DETAILED_FAILURE_MSG
-# - Set to ON to add detailed information to the
-# failure message even when the REQUIRED option
-# is not given to the find_package call.
-# Boost_REALPATH - Set to ON to resolve symlinks for discovered
-# libraries to assist with packaging. For example,
-# the "system" component library may be resolved to
-# "/usr/lib/libboost_system.so.1.42.0" instead of
-# "/usr/lib/libboost_system.so". This does not
-# affect linking and should not be enabled unless
-# the user needs this information.
# On Visual Studio and Borland compilers Boost headers request automatic
-# linking to corresponding libraries. This requires matching libraries to be
-# linked explicitly or available in the link library search path. In this
-# case setting Boost_USE_STATIC_LIBS to OFF may not achieve dynamic linking.
-# Boost automatic linking typically requests static libraries with a few
-# exceptions (such as Boost.Python). Use
-# add_definitions(${Boost_LIB_DIAGNOSTIC_DEFINITIONS})
+# linking to corresponding libraries. This requires matching libraries
+# to be linked explicitly or available in the link library search path.
+# In this case setting Boost_USE_STATIC_LIBS to OFF may not achieve
+# dynamic linking. Boost automatic linking typically requests static
+# libraries with a few exceptions (such as Boost.Python). Use::
+#
+# add_definitions(${Boost_LIB_DIAGNOSTIC_DEFINITIONS})
+#
# to ask Boost to report information about automatic linking requests.
#
-# Example to find Boost headers only:
-# find_package(Boost 1.36.0)
-# if(Boost_FOUND)
-# include_directories(${Boost_INCLUDE_DIRS})
-# add_executable(foo foo.cc)
-# endif()
-# Example to find Boost headers and some libraries:
-# set(Boost_USE_STATIC_LIBS ON)
-# set(Boost_USE_MULTITHREADED ON)
-# set(Boost_USE_STATIC_RUNTIME OFF)
-# find_package(Boost 1.36.0 COMPONENTS date_time filesystem system ...)
-# if(Boost_FOUND)
-# include_directories(${Boost_INCLUDE_DIRS})
-# add_executable(foo foo.cc)
-# target_link_libraries(foo ${Boost_LIBRARIES})
-# endif()
+# Example to find Boost headers only::
+#
+# find_package(Boost 1.36.0)
+# if(Boost_FOUND)
+# include_directories(${Boost_INCLUDE_DIRS})
+# add_executable(foo foo.cc)
+# endif()
+#
+# Example to find Boost libraries and use imported targets::
+#
+# find_package(Boost 1.56 REQUIRED COMPONENTS
+# date_time filesystem iostreams)
+# add_executable(foo foo.cc)
+# target_link_libraries(foo Boost::date_time Boost::filesystem
+# Boost::iostreams)
#
-# Boost CMake ----------------------------------------------------------
+# Example to find Boost headers and some *static* libraries::
+#
+# set(Boost_USE_STATIC_LIBS ON) # only find static libs
+# set(Boost_USE_MULTITHREADED ON)
+# set(Boost_USE_STATIC_RUNTIME OFF)
+# find_package(Boost 1.36.0 COMPONENTS date_time filesystem system ...)
+# if(Boost_FOUND)
+# include_directories(${Boost_INCLUDE_DIRS})
+# add_executable(foo foo.cc)
+# target_link_libraries(foo ${Boost_LIBRARIES})
+# endif()
+#
+# Boost CMake
+# ^^^^^^^^^^^
#
# If Boost was built using the boost-cmake project it provides a package
-# configuration file for use with find_package's Config mode. This module
-# looks for the package configuration file called BoostConfig.cmake or
-# boost-config.cmake and stores the result in cache entry "Boost_DIR". If
-# found, the package configuration file is loaded and this module returns with
-# no further action. See documentation of the Boost CMake package
-# configuration for details on what it provides.
+# configuration file for use with find_package's Config mode. This
+# module looks for the package configuration file called
+# BoostConfig.cmake or boost-config.cmake and stores the result in cache
+# entry "Boost_DIR". If found, the package configuration file is loaded
+# and this module returns with no further action. See documentation of
+# the Boost CMake package configuration for details on what it provides.
#
# Set Boost_NO_BOOST_CMAKE to ON to disable the search for boost-cmake.
@@ -254,6 +322,14 @@ macro(_Boost_ADJUST_LIB_VARS basename)
)
endmacro()
+# Detect changes in used variables.
+# Compares the current variable value with the last one.
+# In short form:
+# v != v_LAST -> CHANGED = 1
+# v is defined, v_LAST not -> CHANGED = 1
+# v is not defined, but v_LAST is -> CHANGED = 1
+# otherwise -> CHANGED = 0
+# CHANGED is returned in variable named ${changed_var}
macro(_Boost_CHANGE_DETECT changed_var)
set(${changed_var} 0)
foreach(v ${ARGN})
@@ -276,18 +352,33 @@ macro(_Boost_CHANGE_DETECT changed_var)
endforeach()
endmacro()
-macro(_Boost_FIND_LIBRARY var)
+#
+# Find the given library (var).
+# Use 'build_type' to support different lib paths for RELEASE or DEBUG builds
+#
+macro(_Boost_FIND_LIBRARY var build_type)
+
find_library(${var} ${ARGN})
- # If we found the first library save Boost_LIBRARY_DIR.
- if(${var} AND NOT Boost_LIBRARY_DIR)
- get_filename_component(_dir "${${var}}" PATH)
- set(Boost_LIBRARY_DIR "${_dir}" CACHE PATH "Boost library directory" FORCE)
+ if(${var})
+ # If this is the first library found then save Boost_LIBRARY_DIR_[RELEASE,DEBUG].
+ if(NOT Boost_LIBRARY_DIR_${build_type})
+ get_filename_component(_dir "${${var}}" PATH)
+ set(Boost_LIBRARY_DIR_${build_type} "${_dir}" CACHE PATH "Boost library directory ${build_type}" FORCE)
+ endif()
+ elseif(_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT)
+ # Try component-specific hints but do not save Boost_LIBRARY_DIR_[RELEASE,DEBUG].
+ find_library(${var} HINTS ${_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT} ${ARGN})
endif()
- # If Boost_LIBRARY_DIR is known then search only there.
- if(Boost_LIBRARY_DIR)
- set(_boost_LIBRARY_SEARCH_DIRS ${Boost_LIBRARY_DIR} NO_DEFAULT_PATH)
+ # If Boost_LIBRARY_DIR_[RELEASE,DEBUG] is known then search only there.
+ if(Boost_LIBRARY_DIR_${build_type})
+ set(_boost_LIBRARY_SEARCH_DIRS_${build_type} ${Boost_LIBRARY_DIR_${build_type}} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
+ if(Boost_DEBUG)
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ " Boost_LIBRARY_DIR_${build_type} = ${Boost_LIBRARY_DIR_${build_type}}"
+ " _boost_LIBRARY_SEARCH_DIRS_${build_type} = ${_boost_LIBRARY_SEARCH_DIRS_${build_type}}")
+ endif()
endif()
endmacro()
@@ -341,14 +432,18 @@ endfunction()
# Guesses Boost's compiler prefix used in built library names
# Returns the guess by setting the variable pointed to by _ret
function(_Boost_GUESS_COMPILER_PREFIX _ret)
- if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel"
- OR "${CMAKE_CXX_COMPILER}" MATCHES "icl"
- OR "${CMAKE_CXX_COMPILER}" MATCHES "icpc")
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "Intel"
+ OR CMAKE_CXX_COMPILER MATCHES "icl"
+ OR CMAKE_CXX_COMPILER MATCHES "icpc")
if(WIN32)
set (_boost_COMPILER "-iw")
else()
set (_boost_COMPILER "-il")
endif()
+ elseif (GHSMULTI)
+ set(_boost_COMPILER "-ghs")
+ elseif (MSVC14)
+ set(_boost_COMPILER "-vc140")
elseif (MSVC12)
set(_boost_COMPILER "-vc120")
elseif (MSVC11)
@@ -367,7 +462,7 @@ function(_Boost_GUESS_COMPILER_PREFIX _ret)
set(_boost_COMPILER "-vc6") # yes, this is correct
elseif (BORLAND)
set(_boost_COMPILER "-bcb")
- elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "SunPro")
+ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "SunPro")
set(_boost_COMPILER "-sw")
elseif (MINGW)
if(${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION} VERSION_LESS 1.34)
@@ -412,6 +507,282 @@ function(_Boost_GUESS_COMPILER_PREFIX _ret)
endfunction()
#
+# Get component dependencies. Requires the dependencies to have been
+# defined for the Boost release version.
+#
+# component - the component to check
+# _ret - list of library dependencies
+#
+function(_Boost_COMPONENT_DEPENDENCIES component _ret)
+ # Note: to add a new Boost release, run
+ #
+ # % cmake -DBOOST_DIR=/path/to/boost/source -P Utilities/Scripts/BoostScanDeps.cmake
+ #
+ # The output may be added in a new block below. If it's the same as
+ # the previous release, simply update the version range of the block
+ # for the previous release.
+ #
+ # This information was originally generated by running
+ # BoostScanDeps.cmake against every boost release to date supported
+ # by FindBoost:
+ #
+ # % for version in /path/to/boost/sources/*
+ # do
+ # cmake -DBOOST_DIR=$version -P Utilities/Scripts/BoostScanDeps.cmake
+ # done
+ #
+ # The output was then updated by search and replace with these regexes:
+ #
+ # - Strip message(STATUS) prefix dashes
+ # s;^-- ;;
+ # - Indent
+ # s;^set(; set(;;
+ # - Add conditionals
+ # s;Scanning /path/to/boost/sources/boost_\(.*\)_\(.*\)_\(.*); elseif(NOT Boost_VERSION VERSION_LESS \10\20\3 AND Boost_VERSION VERSION_LESS xxxx);
+ #
+ # This results in the logic seen below, but will require the xxxx
+ # replacing with the following Boost release version (or the next
+ # minor version to be released, e.g. 1.59 was the latest at the time
+ # of writing, making 1.60 the next, so 106000 is the needed version
+ # number). Identical consecutive releases were then merged together
+ # by updating the end range of the first block and removing the
+ # following redundant blocks.
+ #
+ # Running the script against all historical releases should be
+ # required only if the BoostScanDeps.cmake script logic is changed.
+ # The addition of a new release should only require it to be run
+ # against the new release.
+ set(_Boost_IMPORTED_TARGETS TRUE)
+ if(NOT Boost_VERSION VERSION_LESS 103300 AND Boost_VERSION VERSION_LESS 103500)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex thread)
+ set(_Boost_REGEX_DEPENDENCIES thread)
+ set(_Boost_WAVE_DEPENDENCIES filesystem thread)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(NOT Boost_VERSION VERSION_LESS 103500 AND Boost_VERSION VERSION_LESS 103600)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system thread)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(NOT Boost_VERSION VERSION_LESS 103600 AND Boost_VERSION VERSION_LESS 103800)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system thread)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(NOT Boost_VERSION VERSION_LESS 103800 AND Boost_VERSION VERSION_LESS 104300)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization)
+ set(_Boost_THREAD_DEPENDENCIES date_time)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system thread date_time)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(NOT Boost_VERSION VERSION_LESS 104300 AND Boost_VERSION VERSION_LESS 104400)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization)
+ set(_Boost_THREAD_DEPENDENCIES date_time)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system thread date_time)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(NOT Boost_VERSION VERSION_LESS 104400 AND Boost_VERSION VERSION_LESS 104500)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random serialization)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization)
+ set(_Boost_THREAD_DEPENDENCIES date_time)
+ set(_Boost_WAVE_DEPENDENCIES serialization filesystem system thread date_time)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(NOT Boost_VERSION VERSION_LESS 104500 AND Boost_VERSION VERSION_LESS 104700)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization)
+ set(_Boost_THREAD_DEPENDENCIES date_time)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread date_time)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(NOT Boost_VERSION VERSION_LESS 104700 AND Boost_VERSION VERSION_LESS 104800)
+ set(_Boost_CHRONO_DEPENDENCIES system)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization)
+ set(_Boost_THREAD_DEPENDENCIES date_time)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread date_time)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(NOT Boost_VERSION VERSION_LESS 104800 AND Boost_VERSION VERSION_LESS 105000)
+ set(_Boost_CHRONO_DEPENDENCIES system)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization)
+ set(_Boost_THREAD_DEPENDENCIES date_time)
+ set(_Boost_TIMER_DEPENDENCIES chrono system)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread date_time)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(NOT Boost_VERSION VERSION_LESS 105000 AND Boost_VERSION VERSION_LESS 105300)
+ set(_Boost_CHRONO_DEPENDENCIES system)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization)
+ set(_Boost_THREAD_DEPENDENCIES chrono system date_time)
+ set(_Boost_TIMER_DEPENDENCIES chrono system)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(NOT Boost_VERSION VERSION_LESS 105300 AND Boost_VERSION VERSION_LESS 105400)
+ set(_Boost_ATOMIC_DEPENDENCIES thread chrono system date_time)
+ set(_Boost_CHRONO_DEPENDENCIES system)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization)
+ set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
+ set(_Boost_TIMER_DEPENDENCIES chrono system)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(NOT Boost_VERSION VERSION_LESS 105400 AND Boost_VERSION VERSION_LESS 105500)
+ set(_Boost_ATOMIC_DEPENDENCIES thread chrono system date_time)
+ set(_Boost_CHRONO_DEPENDENCIES system)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization)
+ set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
+ set(_Boost_TIMER_DEPENDENCIES chrono system)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(NOT Boost_VERSION VERSION_LESS 105500 AND Boost_VERSION VERSION_LESS 105600)
+ set(_Boost_CHRONO_DEPENDENCIES system)
+ set(_Boost_COROUTINE_DEPENDENCIES context system)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization)
+ set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
+ set(_Boost_TIMER_DEPENDENCIES chrono system)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(NOT Boost_VERSION VERSION_LESS 105600 AND Boost_VERSION VERSION_LESS 105900)
+ set(_Boost_CHRONO_DEPENDENCIES system)
+ set(_Boost_COROUTINE_DEPENDENCIES context system)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization)
+ set(_Boost_RANDOM_DEPENDENCIES system)
+ set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
+ set(_Boost_TIMER_DEPENDENCIES chrono system)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(NOT Boost_VERSION VERSION_LESS 105900 AND Boost_VERSION VERSION_LESS 106000)
+ set(_Boost_CHRONO_DEPENDENCIES system)
+ set(_Boost_COROUTINE_DEPENDENCIES context system)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono atomic)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization)
+ set(_Boost_RANDOM_DEPENDENCIES system)
+ set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
+ set(_Boost_TIMER_DEPENDENCIES chrono system)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(NOT Boost_VERSION VERSION_LESS 106000 AND Boost_VERSION VERSION_LESS 106200)
+ set(_Boost_CHRONO_DEPENDENCIES system)
+ set(_Boost_COROUTINE_DEPENDENCIES context system)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization)
+ set(_Boost_RANDOM_DEPENDENCIES system)
+ set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
+ set(_Boost_TIMER_DEPENDENCIES chrono system)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ else()
+ message(WARNING "Imported targets not available for Boost version ${Boost_VERSION}")
+ set(_Boost_IMPORTED_TARGETS FALSE)
+ endif()
+
+ string(TOUPPER ${component} uppercomponent)
+ set(${_ret} ${_Boost_${uppercomponent}_DEPENDENCIES} PARENT_SCOPE)
+ set(_Boost_IMPORTED_TARGETS ${_Boost_IMPORTED_TARGETS} PARENT_SCOPE)
+
+ string(REGEX REPLACE ";" " " _boost_DEPS_STRING "${_Boost_${uppercomponent}_DEPENDENCIES}")
+ if (NOT _boost_DEPS_STRING)
+ set(_boost_DEPS_STRING "(none)")
+ endif()
+ # message(STATUS "Dependencies for Boost::${component}: ${_boost_DEPS_STRING}")
+endfunction()
+
+#
+# Determine if any missing dependencies require adding to the component list.
+#
+# Sets _Boost_${COMPONENT}_DEPENDENCIES for each required component,
+# plus _Boost_IMPORTED_TARGETS (TRUE if imported targets should be
+# defined; FALSE if dependency information is unavailable).
+#
+# componentvar - the component list variable name
+# extravar - the indirect dependency list variable name
+#
+#
+function(_Boost_MISSING_DEPENDENCIES componentvar extravar)
+ # _boost_unprocessed_components - list of components requiring processing
+ # _boost_processed_components - components already processed (or currently being processed)
+ # _boost_new_components - new components discovered for future processing
+ #
+ list(APPEND _boost_unprocessed_components ${${componentvar}})
+
+ while(_boost_unprocessed_components)
+ list(APPEND _boost_processed_components ${_boost_unprocessed_components})
+ foreach(component ${_boost_unprocessed_components})
+ string(TOUPPER ${component} uppercomponent)
+ set(${_ret} ${_Boost_${uppercomponent}_DEPENDENCIES} PARENT_SCOPE)
+ _Boost_COMPONENT_DEPENDENCIES("${component}" _Boost_${uppercomponent}_DEPENDENCIES)
+ set(_Boost_${uppercomponent}_DEPENDENCIES ${_Boost_${uppercomponent}_DEPENDENCIES} PARENT_SCOPE)
+ set(_Boost_IMPORTED_TARGETS ${_Boost_IMPORTED_TARGETS} PARENT_SCOPE)
+ foreach(componentdep ${_Boost_${uppercomponent}_DEPENDENCIES})
+ list(FIND _boost_processed_components "${componentdep}" _boost_component_found)
+ list(FIND _boost_new_components "${componentdep}" _boost_component_new)
+ if (_boost_component_found EQUAL -1 AND _boost_component_new EQUAL -1)
+ list(APPEND _boost_new_components ${componentdep})
+ endif()
+ endforeach()
+ endforeach()
+ set(_boost_unprocessed_components ${_boost_new_components})
+ unset(_boost_new_components)
+ endwhile()
+ set(_boost_extra_components ${_boost_processed_components})
+ if(_boost_extra_components AND ${componentvar})
+ list(REMOVE_ITEM _boost_extra_components ${${componentvar}})
+ endif()
+ set(${componentvar} ${_boost_processed_components} PARENT_SCOPE)
+ set(${extravar} ${_boost_extra_components} PARENT_SCOPE)
+endfunction()
+
+#
# End functions/macros
#
#-------------------------------------------------------------------------------
@@ -420,9 +791,22 @@ endfunction()
# main.
#-------------------------------------------------------------------------------
+
+# If the user sets Boost_LIBRARY_DIR, use it as the default for both
+# configurations.
+if(NOT Boost_LIBRARY_DIR_RELEASE AND Boost_LIBRARY_DIR)
+ set(Boost_LIBRARY_DIR_RELEASE "${Boost_LIBRARY_DIR}")
+endif()
+if(NOT Boost_LIBRARY_DIR_DEBUG AND Boost_LIBRARY_DIR)
+ set(Boost_LIBRARY_DIR_DEBUG "${Boost_LIBRARY_DIR}")
+endif()
+
if(NOT DEFINED Boost_USE_MULTITHREADED)
set(Boost_USE_MULTITHREADED TRUE)
endif()
+if(NOT DEFINED Boost_USE_DEBUG_RUNTIME)
+ set(Boost_USE_DEBUG_RUNTIME TRUE)
+endif()
# Check the version of Boost against the requested version.
if(Boost_FIND_VERSION AND NOT Boost_FIND_VERSION_MINOR)
@@ -438,14 +822,20 @@ if(Boost_FIND_VERSION_EXACT)
else()
# The user has not requested an exact version. Among known
# versions, find those that are acceptable to the user request.
+ #
+ # Note: When adding a new Boost release, also update the dependency
+ # information in _Boost_COMPONENT_DEPENDENCIES. See the
+ # instructions at the top of _Boost_COMPONENT_DEPENDENCIES.
set(_Boost_KNOWN_VERSIONS ${Boost_ADDITIONAL_VERSIONS}
- "1.56.0" "1.56" "1.55.0" "1.55" "1.54.0" "1.54"
- "1.53.0" "1.53" "1.52.0" "1.52" "1.51.0" "1.51"
+ "1.61.0" "1.61" "1.60.0" "1.60"
+ "1.59.0" "1.59" "1.58.0" "1.58" "1.57.0" "1.57" "1.56.0" "1.56" "1.55.0" "1.55"
+ "1.54.0" "1.54" "1.53.0" "1.53" "1.52.0" "1.52" "1.51.0" "1.51"
"1.50.0" "1.50" "1.49.0" "1.49" "1.48.0" "1.48" "1.47.0" "1.47" "1.46.1"
"1.46.0" "1.46" "1.45.0" "1.45" "1.44.0" "1.44" "1.43.0" "1.43" "1.42.0" "1.42"
"1.41.0" "1.41" "1.40.0" "1.40" "1.39.0" "1.39" "1.38.0" "1.38" "1.37.0" "1.37"
"1.36.1" "1.36.0" "1.36" "1.35.1" "1.35.0" "1.35" "1.34.1" "1.34.0"
"1.34" "1.33.1" "1.33.0" "1.33")
+
set(_boost_TEST_VERSIONS)
if(Boost_FIND_VERSION)
set(_Boost_FIND_VERSION_SHORT "${Boost_FIND_VERSION_MAJOR}.${Boost_FIND_VERSION_MINOR}")
@@ -487,6 +877,16 @@ if(Boost_DEBUG)
"Boost_NO_SYSTEM_PATHS = ${Boost_NO_SYSTEM_PATHS}")
endif()
+# Supply Boost_LIB_DIAGNOSTIC_DEFINITIONS as a convenience target. It
+# will only contain any interface definitions on WIN32, but is created
+# on all platforms to keep end user code free from platform dependent
+# code. Also provide convenience targets to disable autolinking and
+# enable dynamic linking.
+if(NOT TARGET Boost::diagnostic_definitions)
+ add_library(Boost::diagnostic_definitions INTERFACE IMPORTED)
+ add_library(Boost::disable_autolinking INTERFACE IMPORTED)
+ add_library(Boost::dynamic_linking INTERFACE IMPORTED)
+endif()
if(WIN32)
# In windows, automatic linking is performed, so you do not have
# to specify the libraries. If you are linking to a dynamic
@@ -506,6 +906,12 @@ if(WIN32)
# code to emit a #pragma message each time a library is selected
# for linking.
set(Boost_LIB_DIAGNOSTIC_DEFINITIONS "-DBOOST_LIB_DIAGNOSTIC")
+ set_target_properties(Boost::diagnostic_definitions PROPERTIES
+ INTERFACE_COMPILE_DEFINITIONS "BOOST_LIB_DIAGNOSTIC")
+ set_target_properties(Boost::disable_autolinking PROPERTIES
+ INTERFACE_COMPILE_DEFINITIONS "BOOST_ALL_NO_LIB")
+ set_target_properties(Boost::dynamic_linking PROPERTIES
+ INTERFACE_COMPILE_DEFINITIONS "BOOST_ALL_DYN_LINK")
endif()
_Boost_CHECK_SPELLING(Boost_ROOT)
@@ -594,12 +1000,12 @@ if(NOT Boost_INCLUDE_DIR)
set(_boost_BOOSTIFIED_VERSION)
# Transform 1.35 => 1_35 and 1.36.0 => 1_36_0
- if(_boost_VER MATCHES "[0-9]+\\.[0-9]+\\.[0-9]+")
- string(REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\1_\\2_\\3"
- _boost_BOOSTIFIED_VERSION ${_boost_VER})
- elseif(_boost_VER MATCHES "[0-9]+\\.[0-9]+")
- string(REGEX REPLACE "([0-9]+)\\.([0-9]+)" "\\1_\\2"
- _boost_BOOSTIFIED_VERSION ${_boost_VER})
+ if(_boost_VER MATCHES "([0-9]+)\\.([0-9]+)\\.([0-9]+)")
+ set(_boost_BOOSTIFIED_VERSION
+ "${CMAKE_MATCH_1}_${CMAKE_MATCH_2}_${CMAKE_MATCH_3}")
+ elseif(_boost_VER MATCHES "([0-9]+)\\.([0-9]+)")
+ set(_boost_BOOSTIFIED_VERSION
+ "${CMAKE_MATCH_1}_${CMAKE_MATCH_2}")
endif()
list(APPEND _boost_PATH_SUFFIXES
@@ -647,7 +1053,7 @@ if(Boost_INCLUDE_DIR)
set(_Boost_VERSION_REGEX "([0-9]+)")
set(_Boost_LIB_VERSION_REGEX "\"([0-9_]+)\"")
foreach(v VERSION LIB_VERSION)
- if("${_boost_VERSION_HPP_CONTENTS}" MATCHES ".*#define BOOST_${v} ${_Boost_${v}_REGEX}.*")
+ if("${_boost_VERSION_HPP_CONTENTS}" MATCHES "#define BOOST_${v} ${_Boost_${v}_REGEX}")
set(Boost_${v} "${CMAKE_MATCH_1}")
endif()
endforeach()
@@ -702,10 +1108,25 @@ else()
endif()
# ------------------------------------------------------------------------
+# Prefix initialization
+# ------------------------------------------------------------------------
+
+set(Boost_LIB_PREFIX "")
+if ( (GHSMULTI AND Boost_USE_STATIC_LIBS) OR
+ (WIN32 AND Boost_USE_STATIC_LIBS AND NOT CYGWIN) )
+ set(Boost_LIB_PREFIX "lib")
+endif()
+
+if ( NOT Boost_NAMESPACE )
+ set(Boost_NAMESPACE "boost")
+endif()
+
+# ------------------------------------------------------------------------
# Suffix initialization and compiler suffix detection.
# ------------------------------------------------------------------------
set(_Boost_VARS_NAME
+ Boost_NAMESPACE
Boost_COMPILER
Boost_THREADAPI
Boost_USE_DEBUG_PYTHON
@@ -718,11 +1139,6 @@ set(_Boost_VARS_NAME
_Boost_CHANGE_DETECT(_Boost_CHANGE_LIBNAME ${_Boost_VARS_NAME})
# Setting some more suffixes for the library
-set(Boost_LIB_PREFIX "")
-if ( WIN32 AND Boost_USE_STATIC_LIBS AND NOT CYGWIN)
- set(Boost_LIB_PREFIX "lib")
-endif()
-
if (Boost_COMPILER)
set(_boost_COMPILER ${Boost_COMPILER})
if(Boost_DEBUG)
@@ -764,7 +1180,7 @@ if(Boost_USE_STATIC_RUNTIME)
endif()
# g using debug versions of the standard and runtime
# support libraries
-if(WIN32)
+if(WIN32 AND Boost_USE_DEBUG_RUNTIME)
if(MSVC OR "${CMAKE_CXX_COMPILER}" MATCHES "icl"
OR "${CMAKE_CXX_COMPILER}" MATCHES "icpc")
set(_boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}g")
@@ -798,49 +1214,56 @@ endif()
# ------------------------------------------------------------------------
# Begin finding boost libraries
# ------------------------------------------------------------------------
-set(_Boost_VARS_LIB BOOST_LIBRARYDIR Boost_LIBRARY_DIR)
-_Boost_CHANGE_DETECT(_Boost_CHANGE_LIBDIR ${_Boost_VARS_DIR} ${_Boost_VARS_LIB} Boost_INCLUDE_DIR)
-# Clear Boost_LIBRARY_DIR if it did not change but other input affecting the
-# location did. We will find a new one based on the new inputs.
-if(_Boost_CHANGE_LIBDIR AND NOT _Boost_LIBRARY_DIR_CHANGED)
- unset(Boost_LIBRARY_DIR CACHE)
-endif()
-if(Boost_LIBRARY_DIR)
- set(_boost_LIBRARY_SEARCH_DIRS ${Boost_LIBRARY_DIR} NO_DEFAULT_PATH)
-else()
- set(_boost_LIBRARY_SEARCH_DIRS "")
- if(BOOST_LIBRARYDIR)
- list(APPEND _boost_LIBRARY_SEARCH_DIRS ${BOOST_LIBRARYDIR})
- elseif(_ENV_BOOST_LIBRARYDIR)
- list(APPEND _boost_LIBRARY_SEARCH_DIRS ${_ENV_BOOST_LIBRARYDIR})
+set(_Boost_VARS_LIB "")
+foreach(c DEBUG RELEASE)
+ set(_Boost_VARS_LIB_${c} BOOST_LIBRARYDIR Boost_LIBRARY_DIR_${c})
+ list(APPEND _Boost_VARS_LIB ${_Boost_VARS_LIB_${c}})
+ _Boost_CHANGE_DETECT(_Boost_CHANGE_LIBDIR_${c} ${_Boost_VARS_DIR} ${_Boost_VARS_LIB_${c}} Boost_INCLUDE_DIR)
+ # Clear Boost_LIBRARY_DIR_${c} if it did not change but other input affecting the
+ # location did. We will find a new one based on the new inputs.
+ if(_Boost_CHANGE_LIBDIR_${c} AND NOT _Boost_LIBRARY_DIR_${c}_CHANGED)
+ unset(Boost_LIBRARY_DIR_${c} CACHE)
endif()
- if(BOOST_ROOT)
- list(APPEND _boost_LIBRARY_SEARCH_DIRS ${BOOST_ROOT}/lib ${BOOST_ROOT}/stage/lib)
- elseif(_ENV_BOOST_ROOT)
- list(APPEND _boost_LIBRARY_SEARCH_DIRS ${_ENV_BOOST_ROOT}/lib ${_ENV_BOOST_ROOT}/stage/lib)
- endif()
-
- list(APPEND _boost_LIBRARY_SEARCH_DIRS
- ${Boost_INCLUDE_DIR}/lib
- ${Boost_INCLUDE_DIR}/../lib
- ${Boost_INCLUDE_DIR}/stage/lib
- )
- if( Boost_NO_SYSTEM_PATHS )
- list(APPEND _boost_LIBRARY_SEARCH_DIRS NO_CMAKE_SYSTEM_PATH)
+ # If Boost_LIBRARY_DIR_[RELEASE,DEBUG] is set, prefer its value.
+ if(Boost_LIBRARY_DIR_${c})
+ set(_boost_LIBRARY_SEARCH_DIRS_${c} ${Boost_LIBRARY_DIR_${c}} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
else()
- list(APPEND _boost_LIBRARY_SEARCH_DIRS PATHS
- C:/boost/lib
- C:/boost
- /sw/local/lib
+ set(_boost_LIBRARY_SEARCH_DIRS_${c} "")
+ if(BOOST_LIBRARYDIR)
+ list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} ${BOOST_LIBRARYDIR})
+ elseif(_ENV_BOOST_LIBRARYDIR)
+ list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} ${_ENV_BOOST_LIBRARYDIR})
+ endif()
+
+ if(BOOST_ROOT)
+ list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} ${BOOST_ROOT}/lib ${BOOST_ROOT}/stage/lib)
+ elseif(_ENV_BOOST_ROOT)
+ list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} ${_ENV_BOOST_ROOT}/lib ${_ENV_BOOST_ROOT}/stage/lib)
+ endif()
+
+ list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c}
+ ${Boost_INCLUDE_DIR}/lib
+ ${Boost_INCLUDE_DIR}/../lib
+ ${Boost_INCLUDE_DIR}/stage/lib
)
+ if( Boost_NO_SYSTEM_PATHS )
+ list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} NO_CMAKE_SYSTEM_PATH)
+ else()
+ list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} PATHS
+ C:/boost/lib
+ C:/boost
+ /sw/local/lib
+ )
+ endif()
endif()
-endif()
+endforeach()
if(Boost_DEBUG)
message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
- "_boost_LIBRARY_SEARCH_DIRS = ${_boost_LIBRARY_SEARCH_DIRS}")
+ "_boost_LIBRARY_SEARCH_DIRS_RELEASE = ${_boost_LIBRARY_SEARCH_DIRS_RELEASE}"
+ "_boost_LIBRARY_SEARCH_DIRS_DEBUG = ${_boost_LIBRARY_SEARCH_DIRS_DEBUG}")
endif()
# Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES
@@ -887,6 +1310,17 @@ if(Boost_VERSION AND Boost_FIND_COMPONENTS)
endif()
endif()
+# Additional components may be required via component dependencies.
+# Add any missing components to the list.
+_Boost_MISSING_DEPENDENCIES(Boost_FIND_COMPONENTS _Boost_EXTRA_FIND_COMPONENTS)
+
+# If thread is required, get the thread libs as a dependency
+list(FIND Boost_FIND_COMPONENTS thread _Boost_THREAD_DEPENDENCY_LIBS)
+if(NOT _Boost_THREAD_DEPENDENCY_LIBS EQUAL -1)
+ include(CMakeFindDependencyMacro)
+ find_dependency(Threads)
+endif()
+
# If the user changed any of our control inputs flush previous results.
if(_Boost_CHANGE_LIBDIR OR _Boost_CHANGE_LIBNAME)
foreach(COMPONENT ${_Boost_COMPONENTS_SEARCHED})
@@ -906,22 +1340,45 @@ foreach(COMPONENT ${Boost_FIND_COMPONENTS})
set( _boost_docstring_release "Boost ${COMPONENT} library (release)")
set( _boost_docstring_debug "Boost ${COMPONENT} library (debug)")
+ # Compute component-specific hints.
+ set(_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT "")
+ if(${COMPONENT} STREQUAL "mpi" OR ${COMPONENT} STREQUAL "mpi_python" OR
+ ${COMPONENT} STREQUAL "graph_parallel")
+ foreach(lib ${MPI_CXX_LIBRARIES} ${MPI_C_LIBRARIES})
+ if(IS_ABSOLUTE "${lib}")
+ get_filename_component(libdir "${lib}" PATH)
+ string(REPLACE "\\" "/" libdir "${libdir}")
+ list(APPEND _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT ${libdir})
+ endif()
+ endforeach()
+ endif()
+
+ # Consolidate and report component-specific hints.
+ if(_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT)
+ list(REMOVE_DUPLICATES _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT)
+ if(Boost_DEBUG)
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ "Component-specific library search paths for ${COMPONENT}: "
+ "${_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT}")
+ endif()
+ endif()
+
#
# Find RELEASE libraries
#
set(_boost_RELEASE_NAMES
- ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}-${Boost_LIB_VERSION}
- ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}
- ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}-${Boost_LIB_VERSION}
- ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}
- ${Boost_LIB_PREFIX}boost_${COMPONENT} )
+ ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}-${Boost_LIB_VERSION}
+ ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}
+ ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}-${Boost_LIB_VERSION}
+ ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}
+ ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT} )
if(_boost_STATIC_RUNTIME_WORKAROUND)
set(_boost_RELEASE_STATIC_ABI_TAG "-s${_boost_RELEASE_ABI_TAG}")
list(APPEND _boost_RELEASE_NAMES
- ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}-${Boost_LIB_VERSION}
- ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}
- ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}-${Boost_LIB_VERSION}
- ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG} )
+ ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}-${Boost_LIB_VERSION}
+ ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}
+ ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}-${Boost_LIB_VERSION}
+ ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG} )
endif()
if(Boost_THREADAPI AND ${COMPONENT} STREQUAL "thread")
_Boost_PREPEND_LIST_WITH_THREADAPI(_boost_RELEASE_NAMES ${_boost_RELEASE_NAMES})
@@ -931,10 +1388,16 @@ foreach(COMPONENT ${Boost_FIND_COMPONENTS})
"Searching for ${UPPERCOMPONENT}_LIBRARY_RELEASE: ${_boost_RELEASE_NAMES}")
endif()
+ # if Boost_LIBRARY_DIR_RELEASE is not defined,
+ # but Boost_LIBRARY_DIR_DEBUG is, look there first for RELEASE libs
+ if(NOT Boost_LIBRARY_DIR_RELEASE AND Boost_LIBRARY_DIR_DEBUG)
+ list(INSERT _boost_LIBRARY_SEARCH_DIRS_RELEASE 0 ${Boost_LIBRARY_DIR_DEBUG})
+ endif()
+
# Avoid passing backslashes to _Boost_FIND_LIBRARY due to macro re-parsing.
- string(REPLACE "\\" "/" _boost_LIBRARY_SEARCH_DIRS_tmp "${_boost_LIBRARY_SEARCH_DIRS}")
+ string(REPLACE "\\" "/" _boost_LIBRARY_SEARCH_DIRS_tmp "${_boost_LIBRARY_SEARCH_DIRS_RELEASE}")
- _Boost_FIND_LIBRARY(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE
+ _Boost_FIND_LIBRARY(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE RELEASE
NAMES ${_boost_RELEASE_NAMES}
HINTS ${_boost_LIBRARY_SEARCH_DIRS_tmp}
NAMES_PER_DIR
@@ -945,19 +1408,19 @@ foreach(COMPONENT ${Boost_FIND_COMPONENTS})
# Find DEBUG libraries
#
set(_boost_DEBUG_NAMES
- ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}-${Boost_LIB_VERSION}
- ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}
- ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}-${Boost_LIB_VERSION}
- ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}
- ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}
- ${Boost_LIB_PREFIX}boost_${COMPONENT} )
+ ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}-${Boost_LIB_VERSION}
+ ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}
+ ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}-${Boost_LIB_VERSION}
+ ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}
+ ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}
+ ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT} )
if(_boost_STATIC_RUNTIME_WORKAROUND)
set(_boost_DEBUG_STATIC_ABI_TAG "-s${_boost_DEBUG_ABI_TAG}")
list(APPEND _boost_DEBUG_NAMES
- ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}-${Boost_LIB_VERSION}
- ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}
- ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}-${Boost_LIB_VERSION}
- ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG} )
+ ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}-${Boost_LIB_VERSION}
+ ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}
+ ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}-${Boost_LIB_VERSION}
+ ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG} )
endif()
if(Boost_THREADAPI AND ${COMPONENT} STREQUAL "thread")
_Boost_PREPEND_LIST_WITH_THREADAPI(_boost_DEBUG_NAMES ${_boost_DEBUG_NAMES})
@@ -967,10 +1430,16 @@ foreach(COMPONENT ${Boost_FIND_COMPONENTS})
"Searching for ${UPPERCOMPONENT}_LIBRARY_DEBUG: ${_boost_DEBUG_NAMES}")
endif()
+ # if Boost_LIBRARY_DIR_DEBUG is not defined,
+ # but Boost_LIBRARY_DIR_RELEASE is, look there first for DEBUG libs
+ if(NOT Boost_LIBRARY_DIR_DEBUG AND Boost_LIBRARY_DIR_RELEASE)
+ list(INSERT _boost_LIBRARY_SEARCH_DIRS_DEBUG 0 ${Boost_LIBRARY_DIR_RELEASE})
+ endif()
+
# Avoid passing backslashes to _Boost_FIND_LIBRARY due to macro re-parsing.
- string(REPLACE "\\" "/" _boost_LIBRARY_SEARCH_DIRS_tmp "${_boost_LIBRARY_SEARCH_DIRS}")
+ string(REPLACE "\\" "/" _boost_LIBRARY_SEARCH_DIRS_tmp "${_boost_LIBRARY_SEARCH_DIRS_DEBUG}")
- _Boost_FIND_LIBRARY(Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG
+ _Boost_FIND_LIBRARY(Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG DEBUG
NAMES ${_boost_DEBUG_NAMES}
HINTS ${_boost_LIBRARY_SEARCH_DIRS_tmp}
NAMES_PER_DIR
@@ -996,7 +1465,16 @@ endif()
# ------------------------------------------------------------------------
set(Boost_INCLUDE_DIRS ${Boost_INCLUDE_DIR})
-set(Boost_LIBRARY_DIRS ${Boost_LIBRARY_DIR})
+set(Boost_LIBRARY_DIRS)
+if(Boost_LIBRARY_DIR_RELEASE)
+ list(APPEND Boost_LIBRARY_DIRS ${Boost_LIBRARY_DIR_RELEASE})
+endif()
+if(Boost_LIBRARY_DIR_DEBUG)
+ list(APPEND Boost_LIBRARY_DIRS ${Boost_LIBRARY_DIR_DEBUG})
+endif()
+if(Boost_LIBRARY_DIRS)
+ list(REMOVE_DUPLICATES Boost_LIBRARY_DIRS)
+endif()
# The above setting of Boost_FOUND was based only on the header files.
# Update it for the requested component libraries.
@@ -1012,6 +1490,10 @@ if(Boost_FOUND)
list(APPEND _Boost_MISSING_COMPONENTS ${COMPONENT})
endif()
endforeach()
+ if(_Boost_MISSING_COMPONENTS AND _Boost_EXTRA_FIND_COMPONENTS)
+ # Optional indirect dependencies are not counted as missing.
+ list(REMOVE_ITEM _Boost_MISSING_COMPONENTS ${_Boost_EXTRA_FIND_COMPONENTS})
+ endif()
if(Boost_DEBUG)
message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] Boost_FOUND = ${Boost_FOUND}")
@@ -1030,7 +1512,7 @@ if(Boost_FOUND)
"${Boost_ERROR_REASON} Boost libraries:\n")
foreach(COMPONENT ${_Boost_MISSING_COMPONENTS})
set(Boost_ERROR_REASON
- "${Boost_ERROR_REASON} boost_${COMPONENT}\n")
+ "${Boost_ERROR_REASON} ${Boost_NAMESPACE}_${COMPONENT}\n")
endforeach()
list(LENGTH Boost_FIND_COMPONENTS Boost_NUM_COMPONENTS_WANTED)
@@ -1086,6 +1568,70 @@ else()
endif()
# ------------------------------------------------------------------------
+# Add imported targets
+# ------------------------------------------------------------------------
+
+if(Boost_FOUND AND _Boost_IMPORTED_TARGETS)
+ # For header-only libraries
+ if(NOT TARGET Boost::boost)
+ add_library(Boost::boost INTERFACE IMPORTED)
+ if(Boost_INCLUDE_DIRS)
+ set_target_properties(Boost::boost PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}")
+ endif()
+ endif()
+
+ foreach(COMPONENT ${Boost_FIND_COMPONENTS})
+ if(NOT TARGET Boost::${COMPONENT})
+ string(TOUPPER ${COMPONENT} UPPERCOMPONENT)
+ if(Boost_${UPPERCOMPONENT}_FOUND)
+ if(Boost_USE_STATIC_LIBS)
+ add_library(Boost::${COMPONENT} STATIC IMPORTED)
+ else()
+ # Even if Boost_USE_STATIC_LIBS is OFF, we might have static
+ # libraries as a result.
+ add_library(Boost::${COMPONENT} UNKNOWN IMPORTED)
+ endif()
+ if(Boost_INCLUDE_DIRS)
+ set_target_properties(Boost::${COMPONENT} PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}")
+ endif()
+ if(EXISTS "${Boost_${UPPERCOMPONENT}_LIBRARY}")
+ set_target_properties(Boost::${COMPONENT} PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
+ IMPORTED_LOCATION "${Boost_${UPPERCOMPONENT}_LIBRARY}")
+ endif()
+ if(EXISTS "${Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG}")
+ set_property(TARGET Boost::${COMPONENT} APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS DEBUG)
+ set_target_properties(Boost::${COMPONENT} PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX"
+ IMPORTED_LOCATION_DEBUG "${Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG}")
+ endif()
+ if(EXISTS "${Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE}")
+ set_property(TARGET Boost::${COMPONENT} APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS RELEASE)
+ set_target_properties(Boost::${COMPONENT} PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
+ IMPORTED_LOCATION_RELEASE "${Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE}")
+ endif()
+ if(_Boost_${UPPERCOMPONENT}_DEPENDENCIES)
+ unset(_Boost_${UPPERCOMPONENT}_TARGET_DEPENDENCIES)
+ foreach(dep ${_Boost_${UPPERCOMPONENT}_DEPENDENCIES})
+ list(APPEND _Boost_${UPPERCOMPONENT}_TARGET_DEPENDENCIES Boost::${dep})
+ endforeach()
+ if(COMPONENT STREQUAL "thread")
+ list(APPEND _Boost_${UPPERCOMPONENT}_TARGET_DEPENDENCIES Threads::Threads)
+ endif()
+ set_target_properties(Boost::${COMPONENT} PROPERTIES
+ INTERFACE_LINK_LIBRARIES "${_Boost_${UPPERCOMPONENT}_TARGET_DEPENDENCIES}")
+ endif()
+ endif()
+ endif()
+ endforeach()
+endif()
+
+# ------------------------------------------------------------------------
# Notification to end user about what was found
# ------------------------------------------------------------------------
diff --git a/Modules/FindBullet.cmake b/Modules/FindBullet.cmake
index 1a27fc32b..fc848fae0 100644
--- a/Modules/FindBullet.cmake
+++ b/Modules/FindBullet.cmake
@@ -1,17 +1,36 @@
-# - Try to find the Bullet physics engine
+#.rst:
+# FindBullet
+# ----------
#
-# This module defines the following variables
+# Try to find the Bullet physics engine
#
-# BULLET_FOUND - Was bullet found
-# BULLET_INCLUDE_DIRS - the Bullet include directories
-# BULLET_LIBRARIES - Link to this, by default it includes
-# all bullet components (Dynamics,
-# Collision, LinearMath, & SoftBody)
#
-# This module accepts the following variables
#
-# BULLET_ROOT - Can be set to bullet install path or Windows build path
+# ::
#
+# This module defines the following variables
+#
+#
+#
+# ::
+#
+# BULLET_FOUND - Was bullet found
+# BULLET_INCLUDE_DIRS - the Bullet include directories
+# BULLET_LIBRARIES - Link to this, by default it includes
+# all bullet components (Dynamics,
+# Collision, LinearMath, & SoftBody)
+#
+#
+#
+# ::
+#
+# This module accepts the following variables
+#
+#
+#
+# ::
+#
+# BULLET_ROOT - Can be set to bullet install path or Windows build path
#=============================================================================
# Copyright 2009 Kitware, Inc.
diff --git a/Modules/FindCABLE.cmake b/Modules/FindCABLE.cmake
index 3e2d5d3bb..5cea109ad 100644
--- a/Modules/FindCABLE.cmake
+++ b/Modules/FindCABLE.cmake
@@ -1,14 +1,24 @@
-# - Find CABLE
+#.rst:
+# FindCABLE
+# ---------
+#
+# Find CABLE
+#
# This module finds if CABLE is installed and determines where the
-# include files and libraries are. This code sets the following variables:
+# include files and libraries are. This code sets the following
+# variables:
+#
+# ::
+#
+# CABLE the path to the cable executable
+# CABLE_TCL_LIBRARY the path to the Tcl wrapper library
+# CABLE_INCLUDE_DIR the path to the include directory
+#
#
-# CABLE the path to the cable executable
-# CABLE_TCL_LIBRARY the path to the Tcl wrapper library
-# CABLE_INCLUDE_DIR the path to the include directory
#
# To build Tcl wrappers, you should add shared library and link it to
-# ${CABLE_TCL_LIBRARY}. You should also add ${CABLE_INCLUDE_DIR} as
-# an include directory.
+# ${CABLE_TCL_LIBRARY}. You should also add ${CABLE_INCLUDE_DIR} as an
+# include directory.
#=============================================================================
# Copyright 2001-2009 Kitware, Inc.
diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake
index 2705d3271..fe8b18ee3 100644
--- a/Modules/FindCUDA.cmake
+++ b/Modules/FindCUDA.cmake
@@ -1,292 +1,325 @@
-# - Tools for building CUDA C files: libraries and build dependencies.
-# This script locates the NVIDIA CUDA C tools. It should work on linux, windows,
-# and mac and should be reasonably up to date with CUDA C releases.
+#.rst:
+# FindCUDA
+# --------
#
-# This script makes use of the standard find_package arguments of <VERSION>,
-# REQUIRED and QUIET. CUDA_FOUND will report if an acceptable version of CUDA
-# was found.
+# Tools for building CUDA C files: libraries and build dependencies.
#
-# The script will prompt the user to specify CUDA_TOOLKIT_ROOT_DIR if the prefix
-# cannot be determined by the location of nvcc in the system path and REQUIRED
-# is specified to find_package(). To use a different installed version of the
-# toolkit set the environment variable CUDA_BIN_PATH before running cmake
-# (e.g. CUDA_BIN_PATH=/usr/local/cuda1.0 instead of the default /usr/local/cuda)
-# or set CUDA_TOOLKIT_ROOT_DIR after configuring. If you change the value of
-# CUDA_TOOLKIT_ROOT_DIR, various components that depend on the path will be
-# relocated.
+# This script locates the NVIDIA CUDA C tools. It should work on linux,
+# windows, and mac and should be reasonably up to date with CUDA C
+# releases.
+#
+# This script makes use of the standard find_package arguments of
+# <VERSION>, REQUIRED and QUIET. CUDA_FOUND will report if an
+# acceptable version of CUDA was found.
+#
+# The script will prompt the user to specify CUDA_TOOLKIT_ROOT_DIR if
+# the prefix cannot be determined by the location of nvcc in the system
+# path and REQUIRED is specified to find_package(). To use a different
+# installed version of the toolkit set the environment variable
+# CUDA_BIN_PATH before running cmake (e.g.
+# CUDA_BIN_PATH=/usr/local/cuda1.0 instead of the default
+# /usr/local/cuda) or set CUDA_TOOLKIT_ROOT_DIR after configuring. If
+# you change the value of CUDA_TOOLKIT_ROOT_DIR, various components that
+# depend on the path will be relocated.
#
# It might be necessary to set CUDA_TOOLKIT_ROOT_DIR manually on certain
-# platforms, or to use a cuda runtime not installed in the default location. In
-# newer versions of the toolkit the cuda library is included with the graphics
-# driver- be sure that the driver version matches what is needed by the cuda
-# runtime version.
+# platforms, or to use a cuda runtime not installed in the default
+# location. In newer versions of the toolkit the cuda library is
+# included with the graphics driver- be sure that the driver version
+# matches what is needed by the cuda runtime version.
+#
+# The following variables affect the behavior of the macros in the
+# script (in alphebetical order). Note that any of these flags can be
+# changed multiple times in the same directory before calling
+# CUDA_ADD_EXECUTABLE, CUDA_ADD_LIBRARY, CUDA_COMPILE, CUDA_COMPILE_PTX,
+# CUDA_COMPILE_FATBIN, CUDA_COMPILE_CUBIN or CUDA_WRAP_SRCS::
+#
+# CUDA_64_BIT_DEVICE_CODE (Default matches host bit size)
+# -- Set to ON to compile for 64 bit device code, OFF for 32 bit device code.
+# Note that making this different from the host code when generating object
+# or C files from CUDA code just won't work, because size_t gets defined by
+# nvcc in the generated source. If you compile to PTX and then load the
+# file yourself, you can mix bit sizes between device and host.
+#
+# CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE (Default ON)
+# -- Set to ON if you want the custom build rule to be attached to the source
+# file in Visual Studio. Turn OFF if you add the same cuda file to multiple
+# targets.
+#
+# This allows the user to build the target from the CUDA file; however, bad
+# things can happen if the CUDA source file is added to multiple targets.
+# When performing parallel builds it is possible for the custom build
+# command to be run more than once and in parallel causing cryptic build
+# errors. VS runs the rules for every source file in the target, and a
+# source can have only one rule no matter how many projects it is added to.
+# When the rule is run from multiple targets race conditions can occur on
+# the generated file. Eventually everything will get built, but if the user
+# is unaware of this behavior, there may be confusion. It would be nice if
+# this script could detect the reuse of source files across multiple targets
+# and turn the option off for the user, but no good solution could be found.
+#
+# CUDA_BUILD_CUBIN (Default OFF)
+# -- Set to ON to enable and extra compilation pass with the -cubin option in
+# Device mode. The output is parsed and register, shared memory usage is
+# printed during build.
#
-# The following variables affect the behavior of the macros in the script (in
-# alphebetical order). Note that any of these flags can be changed multiple
-# times in the same directory before calling CUDA_ADD_EXECUTABLE,
-# CUDA_ADD_LIBRARY, CUDA_COMPILE, CUDA_COMPILE_PTX or CUDA_WRAP_SRCS.
+# CUDA_BUILD_EMULATION (Default OFF for device mode)
+# -- Set to ON for Emulation mode. -D_DEVICEEMU is defined for CUDA C files
+# when CUDA_BUILD_EMULATION is TRUE.
#
-# CUDA_64_BIT_DEVICE_CODE (Default matches host bit size)
-# -- Set to ON to compile for 64 bit device code, OFF for 32 bit device code.
-# Note that making this different from the host code when generating object
-# or C files from CUDA code just won't work, because size_t gets defined by
-# nvcc in the generated source. If you compile to PTX and then load the
-# file yourself, you can mix bit sizes between device and host.
+# CUDA_GENERATED_OUTPUT_DIR (Default CMAKE_CURRENT_BINARY_DIR)
+# -- Set to the path you wish to have the generated files placed. If it is
+# blank output files will be placed in CMAKE_CURRENT_BINARY_DIR.
+# Intermediate files will always be placed in
+# CMAKE_CURRENT_BINARY_DIR/CMakeFiles.
#
-# CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE (Default ON)
-# -- Set to ON if you want the custom build rule to be attached to the source
-# file in Visual Studio. Turn OFF if you add the same cuda file to multiple
-# targets.
+# CUDA_HOST_COMPILATION_CPP (Default ON)
+# -- Set to OFF for C compilation of host code.
#
-# This allows the user to build the target from the CUDA file; however, bad
-# things can happen if the CUDA source file is added to multiple targets.
-# When performing parallel builds it is possible for the custom build
-# command to be run more than once and in parallel causing cryptic build
-# errors. VS runs the rules for every source file in the target, and a
-# source can have only one rule no matter how many projects it is added to.
-# When the rule is run from multiple targets race conditions can occur on
-# the generated file. Eventually everything will get built, but if the user
-# is unaware of this behavior, there may be confusion. It would be nice if
-# this script could detect the reuse of source files across multiple targets
-# and turn the option off for the user, but no good solution could be found.
+# CUDA_HOST_COMPILER (Default CMAKE_C_COMPILER, $(VCInstallDir)/bin for VS)
+# -- Set the host compiler to be used by nvcc. Ignored if -ccbin or
+# --compiler-bindir is already present in the CUDA_NVCC_FLAGS or
+# CUDA_NVCC_FLAGS_<CONFIG> variables. For Visual Studio targets
+# $(VCInstallDir)/bin is a special value that expands out to the path when
+# the command is run from withing VS.
#
-# CUDA_BUILD_CUBIN (Default OFF)
-# -- Set to ON to enable and extra compilation pass with the -cubin option in
-# Device mode. The output is parsed and register, shared memory usage is
-# printed during build.
+# CUDA_NVCC_FLAGS
+# CUDA_NVCC_FLAGS_<CONFIG>
+# -- Additional NVCC command line arguments. NOTE: multiple arguments must be
+# semi-colon delimited (e.g. --compiler-options;-Wall)
#
-# CUDA_BUILD_EMULATION (Default OFF for device mode)
-# -- Set to ON for Emulation mode. -D_DEVICEEMU is defined for CUDA C files
-# when CUDA_BUILD_EMULATION is TRUE.
+# CUDA_PROPAGATE_HOST_FLAGS (Default ON)
+# -- Set to ON to propagate CMAKE_{C,CXX}_FLAGS and their configuration
+# dependent counterparts (e.g. CMAKE_C_FLAGS_DEBUG) automatically to the
+# host compiler through nvcc's -Xcompiler flag. This helps make the
+# generated host code match the rest of the system better. Sometimes
+# certain flags give nvcc problems, and this will help you turn the flag
+# propagation off. This does not affect the flags supplied directly to nvcc
+# via CUDA_NVCC_FLAGS or through the OPTION flags specified through
+# CUDA_ADD_LIBRARY, CUDA_ADD_EXECUTABLE, or CUDA_WRAP_SRCS. Flags used for
+# shared library compilation are not affected by this flag.
#
-# CUDA_GENERATED_OUTPUT_DIR (Default CMAKE_CURRENT_BINARY_DIR)
-# -- Set to the path you wish to have the generated files placed. If it is
-# blank output files will be placed in CMAKE_CURRENT_BINARY_DIR.
-# Intermediate files will always be placed in
-# CMAKE_CURRENT_BINARY_DIR/CMakeFiles.
+# CUDA_SEPARABLE_COMPILATION (Default OFF)
+# -- If set this will enable separable compilation for all CUDA runtime object
+# files. If used outside of CUDA_ADD_EXECUTABLE and CUDA_ADD_LIBRARY
+# (e.g. calling CUDA_WRAP_SRCS directly),
+# CUDA_COMPUTE_SEPARABLE_COMPILATION_OBJECT_FILE_NAME and
+# CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS should be called.
#
-# CUDA_HOST_COMPILATION_CPP (Default ON)
-# -- Set to OFF for C compilation of host code.
+# CUDA_SOURCE_PROPERTY_FORMAT
+# -- If this source file property is set, it can override the format specified
+# to CUDA_WRAP_SRCS (OBJ, PTX, CUBIN, or FATBIN). If an input source file
+# is not a .cu file, setting this file will cause it to be treated as a .cu
+# file. See documentation for set_source_files_properties on how to set
+# this property.
#
-# CUDA_HOST_COMPILER (Default CMAKE_C_COMPILER, $(VCInstallDir)/bin for VS)
-# -- Set the host compiler to be used by nvcc. Ignored if -ccbin or
-# --compiler-bindir is already present in the CUDA_NVCC_FLAGS or
-# CUDA_NVCC_FLAGS_<CONFIG> variables. For Visual Studio targets
-# $(VCInstallDir)/bin is a special value that expands out to the path when
-# the command is run from withing VS.
+# CUDA_USE_STATIC_CUDA_RUNTIME (Default ON)
+# -- When enabled the static version of the CUDA runtime library will be used
+# in CUDA_LIBRARIES. If the version of CUDA configured doesn't support
+# this option, then it will be silently disabled.
#
-# CUDA_NVCC_FLAGS
-# CUDA_NVCC_FLAGS_<CONFIG>
-# -- Additional NVCC command line arguments. NOTE: multiple arguments must be
-# semi-colon delimited (e.g. --compiler-options;-Wall)
+# CUDA_VERBOSE_BUILD (Default OFF)
+# -- Set to ON to see all the commands used when building the CUDA file. When
+# using a Makefile generator the value defaults to VERBOSE (run make
+# VERBOSE=1 to see output), although setting CUDA_VERBOSE_BUILD to ON will
+# always print the output.
#
-# CUDA_PROPAGATE_HOST_FLAGS (Default ON)
-# -- Set to ON to propagate CMAKE_{C,CXX}_FLAGS and their configuration
-# dependent counterparts (e.g. CMAKE_C_FLAGS_DEBUG) automatically to the
-# host compiler through nvcc's -Xcompiler flag. This helps make the
-# generated host code match the rest of the system better. Sometimes
-# certain flags give nvcc problems, and this will help you turn the flag
-# propagation off. This does not affect the flags supplied directly to nvcc
-# via CUDA_NVCC_FLAGS or through the OPTION flags specified through
-# CUDA_ADD_LIBRARY, CUDA_ADD_EXECUTABLE, or CUDA_WRAP_SRCS. Flags used for
-# shared library compilation are not affected by this flag.
+# The script creates the following macros (in alphebetical order)::
#
-# CUDA_SEPARABLE_COMPILATION (Default OFF)
-# -- If set this will enable separable compilation for all CUDA runtime object
-# files. If used outside of CUDA_ADD_EXECUTABLE and CUDA_ADD_LIBRARY
-# (e.g. calling CUDA_WRAP_SRCS directly),
-# CUDA_COMPUTE_SEPARABLE_COMPILATION_OBJECT_FILE_NAME and
-# CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS should be called.
+# CUDA_ADD_CUFFT_TO_TARGET( cuda_target )
+# -- Adds the cufft library to the target (can be any target). Handles whether
+# you are in emulation mode or not.
#
-# CUDA_VERBOSE_BUILD (Default OFF)
-# -- Set to ON to see all the commands used when building the CUDA file. When
-# using a Makefile generator the value defaults to VERBOSE (run make
-# VERBOSE=1 to see output), although setting CUDA_VERBOSE_BUILD to ON will
-# always print the output.
+# CUDA_ADD_CUBLAS_TO_TARGET( cuda_target )
+# -- Adds the cublas library to the target (can be any target). Handles
+# whether you are in emulation mode or not.
#
-# The script creates the following macros (in alphebetical order):
+# CUDA_ADD_EXECUTABLE( cuda_target file0 file1 ...
+# [WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL] [OPTIONS ...] )
+# -- Creates an executable "cuda_target" which is made up of the files
+# specified. All of the non CUDA C files are compiled using the standard
+# build rules specified by CMAKE and the cuda files are compiled to object
+# files using nvcc and the host compiler. In addition CUDA_INCLUDE_DIRS is
+# added automatically to include_directories(). Some standard CMake target
+# calls can be used on the target after calling this macro
+# (e.g. set_target_properties and target_link_libraries), but setting
+# properties that adjust compilation flags will not affect code compiled by
+# nvcc. Such flags should be modified before calling CUDA_ADD_EXECUTABLE,
+# CUDA_ADD_LIBRARY or CUDA_WRAP_SRCS.
#
-# CUDA_ADD_CUFFT_TO_TARGET( cuda_target )
-# -- Adds the cufft library to the target (can be any target). Handles whether
-# you are in emulation mode or not.
+# CUDA_ADD_LIBRARY( cuda_target file0 file1 ...
+# [STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] [OPTIONS ...] )
+# -- Same as CUDA_ADD_EXECUTABLE except that a library is created.
#
-# CUDA_ADD_CUBLAS_TO_TARGET( cuda_target )
-# -- Adds the cublas library to the target (can be any target). Handles
-# whether you are in emulation mode or not.
+# CUDA_BUILD_CLEAN_TARGET()
+# -- Creates a convience target that deletes all the dependency files
+# generated. You should make clean after running this target to ensure the
+# dependency files get regenerated.
#
-# CUDA_ADD_EXECUTABLE( cuda_target file0 file1 ...
-# [WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL] [OPTIONS ...] )
-# -- Creates an executable "cuda_target" which is made up of the files
-# specified. All of the non CUDA C files are compiled using the standard
-# build rules specified by CMAKE and the cuda files are compiled to object
-# files using nvcc and the host compiler. In addition CUDA_INCLUDE_DIRS is
-# added automatically to include_directories(). Some standard CMake target
-# calls can be used on the target after calling this macro
-# (e.g. set_target_properties and target_link_libraries), but setting
-# properties that adjust compilation flags will not affect code compiled by
-# nvcc. Such flags should be modified before calling CUDA_ADD_EXECUTABLE,
-# CUDA_ADD_LIBRARY or CUDA_WRAP_SRCS.
+# CUDA_COMPILE( generated_files file0 file1 ... [STATIC | SHARED | MODULE]
+# [OPTIONS ...] )
+# -- Returns a list of generated files from the input source files to be used
+# with ADD_LIBRARY or ADD_EXECUTABLE.
#
-# CUDA_ADD_LIBRARY( cuda_target file0 file1 ...
-# [STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] [OPTIONS ...] )
-# -- Same as CUDA_ADD_EXECUTABLE except that a library is created.
+# CUDA_COMPILE_PTX( generated_files file0 file1 ... [OPTIONS ...] )
+# -- Returns a list of PTX files generated from the input source files.
#
-# CUDA_BUILD_CLEAN_TARGET()
-# -- Creates a convience target that deletes all the dependency files
-# generated. You should make clean after running this target to ensure the
-# dependency files get regenerated.
+# CUDA_COMPILE_FATBIN( generated_files file0 file1 ... [OPTIONS ...] )
+# -- Returns a list of FATBIN files generated from the input source files.
#
-# CUDA_COMPILE( generated_files file0 file1 ... [STATIC | SHARED | MODULE]
-# [OPTIONS ...] )
-# -- Returns a list of generated files from the input source files to be used
-# with ADD_LIBRARY or ADD_EXECUTABLE.
+# CUDA_COMPILE_CUBIN( generated_files file0 file1 ... [OPTIONS ...] )
+# -- Returns a list of CUBIN files generated from the input source files.
#
-# CUDA_COMPILE_PTX( generated_files file0 file1 ... [OPTIONS ...] )
-# -- Returns a list of PTX files generated from the input source files.
+# CUDA_COMPUTE_SEPARABLE_COMPILATION_OBJECT_FILE_NAME( output_file_var
+# cuda_target
+# object_files )
+# -- Compute the name of the intermediate link file used for separable
+# compilation. This file name is typically passed into
+# CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS. output_file_var is produced
+# based on cuda_target the list of objects files that need separable
+# compilation as specified by object_files. If the object_files list is
+# empty, then output_file_var will be empty. This function is called
+# automatically for CUDA_ADD_LIBRARY and CUDA_ADD_EXECUTABLE. Note that
+# this is a function and not a macro.
#
-# CUDA_COMPUTE_SEPARABLE_COMPILATION_OBJECT_FILE_NAME( output_file_var
-# cuda_target
-# object_files )
-# -- Compute the name of the intermediate link file used for separable
-# compilation. This file name is typically passed into
-# CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS. output_file_var is produced
-# based on cuda_target the list of objects files that need separable
-# compilation as specified by object_files. If the object_files list is
-# empty, then output_file_var will be empty. This function is called
-# automatically for CUDA_ADD_LIBRARY and CUDA_ADD_EXECUTABLE. Note that
-# this is a function and not a macro.
+# CUDA_INCLUDE_DIRECTORIES( path0 path1 ... )
+# -- Sets the directories that should be passed to nvcc
+# (e.g. nvcc -Ipath0 -Ipath1 ... ). These paths usually contain other .cu
+# files.
#
-# CUDA_INCLUDE_DIRECTORIES( path0 path1 ... )
-# -- Sets the directories that should be passed to nvcc
-# (e.g. nvcc -Ipath0 -Ipath1 ... ). These paths usually contain other .cu
-# files.
#
#
-# CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS( output_file_var cuda_target
-# nvcc_flags object_files)
+# CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS( output_file_var cuda_target
+# nvcc_flags object_files)
#
-# -- Generates the link object required by separable compilation from the given
-# object files. This is called automatically for CUDA_ADD_EXECUTABLE and
-# CUDA_ADD_LIBRARY, but can be called manually when using CUDA_WRAP_SRCS
-# directly. When called from CUDA_ADD_LIBRARY or CUDA_ADD_EXECUTABLE the
-# nvcc_flags passed in are the same as the flags passed in via the OPTIONS
-# argument. The only nvcc flag added automatically is the bitness flag as
-# specified by CUDA_64_BIT_DEVICE_CODE. Note that this is a function
-# instead of a macro.
+# -- Generates the link object required by separable compilation from the given
+# object files. This is called automatically for CUDA_ADD_EXECUTABLE and
+# CUDA_ADD_LIBRARY, but can be called manually when using CUDA_WRAP_SRCS
+# directly. When called from CUDA_ADD_LIBRARY or CUDA_ADD_EXECUTABLE the
+# nvcc_flags passed in are the same as the flags passed in via the OPTIONS
+# argument. The only nvcc flag added automatically is the bitness flag as
+# specified by CUDA_64_BIT_DEVICE_CODE. Note that this is a function
+# instead of a macro.
#
-# CUDA_WRAP_SRCS ( cuda_target format generated_files file0 file1 ...
-# [STATIC | SHARED | MODULE] [OPTIONS ...] )
-# -- This is where all the magic happens. CUDA_ADD_EXECUTABLE,
-# CUDA_ADD_LIBRARY, CUDA_COMPILE, and CUDA_COMPILE_PTX all call this
-# function under the hood.
+# CUDA_WRAP_SRCS ( cuda_target format generated_files file0 file1 ...
+# [STATIC | SHARED | MODULE] [OPTIONS ...] )
+# -- This is where all the magic happens. CUDA_ADD_EXECUTABLE,
+# CUDA_ADD_LIBRARY, CUDA_COMPILE, and CUDA_COMPILE_PTX all call this
+# function under the hood.
#
-# Given the list of files (file0 file1 ... fileN) this macro generates
-# custom commands that generate either PTX or linkable objects (use "PTX" or
-# "OBJ" for the format argument to switch). Files that don't end with .cu
-# or have the HEADER_FILE_ONLY property are ignored.
+# Given the list of files (file0 file1 ... fileN) this macro generates
+# custom commands that generate either PTX or linkable objects (use "PTX" or
+# "OBJ" for the format argument to switch). Files that don't end with .cu
+# or have the HEADER_FILE_ONLY property are ignored.
#
-# The arguments passed in after OPTIONS are extra command line options to
-# give to nvcc. You can also specify per configuration options by
-# specifying the name of the configuration followed by the options. General
-# options must preceed configuration specific options. Not all
-# configurations need to be specified, only the ones provided will be used.
+# The arguments passed in after OPTIONS are extra command line options to
+# give to nvcc. You can also specify per configuration options by
+# specifying the name of the configuration followed by the options. General
+# options must preceed configuration specific options. Not all
+# configurations need to be specified, only the ones provided will be used.
#
-# OPTIONS -DFLAG=2 "-DFLAG_OTHER=space in flag"
-# DEBUG -g
-# RELEASE --use_fast_math
-# RELWITHDEBINFO --use_fast_math;-g
-# MINSIZEREL --use_fast_math
+# OPTIONS -DFLAG=2 "-DFLAG_OTHER=space in flag"
+# DEBUG -g
+# RELEASE --use_fast_math
+# RELWITHDEBINFO --use_fast_math;-g
+# MINSIZEREL --use_fast_math
#
-# For certain configurations (namely VS generating object files with
-# CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE set to ON), no generated file will
-# be produced for the given cuda file. This is because when you add the
-# cuda file to Visual Studio it knows that this file produces an object file
-# and will link in the resulting object file automatically.
+# For certain configurations (namely VS generating object files with
+# CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE set to ON), no generated file will
+# be produced for the given cuda file. This is because when you add the
+# cuda file to Visual Studio it knows that this file produces an object file
+# and will link in the resulting object file automatically.
#
-# This script will also generate a separate cmake script that is used at
-# build time to invoke nvcc. This is for several reasons.
+# This script will also generate a separate cmake script that is used at
+# build time to invoke nvcc. This is for several reasons.
#
-# 1. nvcc can return negative numbers as return values which confuses
-# Visual Studio into thinking that the command succeeded. The script now
-# checks the error codes and produces errors when there was a problem.
+# 1. nvcc can return negative numbers as return values which confuses
+# Visual Studio into thinking that the command succeeded. The script now
+# checks the error codes and produces errors when there was a problem.
#
-# 2. nvcc has been known to not delete incomplete results when it
-# encounters problems. This confuses build systems into thinking the
-# target was generated when in fact an unusable file exists. The script
-# now deletes the output files if there was an error.
+# 2. nvcc has been known to not delete incomplete results when it
+# encounters problems. This confuses build systems into thinking the
+# target was generated when in fact an unusable file exists. The script
+# now deletes the output files if there was an error.
#
-# 3. By putting all the options that affect the build into a file and then
-# make the build rule dependent on the file, the output files will be
-# regenerated when the options change.
+# 3. By putting all the options that affect the build into a file and then
+# make the build rule dependent on the file, the output files will be
+# regenerated when the options change.
#
-# This script also looks at optional arguments STATIC, SHARED, or MODULE to
-# determine when to target the object compilation for a shared library.
-# BUILD_SHARED_LIBS is ignored in CUDA_WRAP_SRCS, but it is respected in
-# CUDA_ADD_LIBRARY. On some systems special flags are added for building
-# objects intended for shared libraries. A preprocessor macro,
-# <target_name>_EXPORTS is defined when a shared library compilation is
-# detected.
+# This script also looks at optional arguments STATIC, SHARED, or MODULE to
+# determine when to target the object compilation for a shared library.
+# BUILD_SHARED_LIBS is ignored in CUDA_WRAP_SRCS, but it is respected in
+# CUDA_ADD_LIBRARY. On some systems special flags are added for building
+# objects intended for shared libraries. A preprocessor macro,
+# <target_name>_EXPORTS is defined when a shared library compilation is
+# detected.
#
-# Flags passed into add_definitions with -D or /D are passed along to nvcc.
+# Flags passed into add_definitions with -D or /D are passed along to nvcc.
#
-# The script defines the following variables:
#
-# CUDA_VERSION_MAJOR -- The major version of cuda as reported by nvcc.
-# CUDA_VERSION_MINOR -- The minor version.
-# CUDA_VERSION
-# CUDA_VERSION_STRING -- CUDA_VERSION_MAJOR.CUDA_VERSION_MINOR
#
-# CUDA_TOOLKIT_ROOT_DIR -- Path to the CUDA Toolkit (defined if not set).
-# CUDA_SDK_ROOT_DIR -- Path to the CUDA SDK. Use this to find files in the
-# SDK. This script will not directly support finding
-# specific libraries or headers, as that isn't
-# supported by NVIDIA. If you want to change
-# libraries when the path changes see the
-# FindCUDA.cmake script for an example of how to clear
-# these variables. There are also examples of how to
-# use the CUDA_SDK_ROOT_DIR to locate headers or
-# libraries, if you so choose (at your own risk).
-# CUDA_INCLUDE_DIRS -- Include directory for cuda headers. Added automatically
-# for CUDA_ADD_EXECUTABLE and CUDA_ADD_LIBRARY.
-# CUDA_LIBRARIES -- Cuda RT library.
-# CUDA_CUFFT_LIBRARIES -- Device or emulation library for the Cuda FFT
-# implementation (alternative to:
-# CUDA_ADD_CUFFT_TO_TARGET macro)
-# CUDA_CUBLAS_LIBRARIES -- Device or emulation library for the Cuda BLAS
-# implementation (alterative to:
-# CUDA_ADD_CUBLAS_TO_TARGET macro).
-# CUDA_cupti_LIBRARY -- CUDA Profiling Tools Interface library.
-# Only available for CUDA version 4.0+.
-# CUDA_curand_LIBRARY -- CUDA Random Number Generation library.
-# Only available for CUDA version 3.2+.
-# CUDA_cusparse_LIBRARY -- CUDA Sparse Matrix library.
-# Only available for CUDA version 3.2+.
-# CUDA_npp_LIBRARY -- NVIDIA Performance Primitives library.
-# Only available for CUDA version 4.0+.
-# CUDA_nppc_LIBRARY -- NVIDIA Performance Primitives library (core).
-# Only available for CUDA version 5.5+.
-# CUDA_nppi_LIBRARY -- NVIDIA Performance Primitives library (image processing).
-# Only available for CUDA version 5.5+.
-# CUDA_npps_LIBRARY -- NVIDIA Performance Primitives library (signal processing).
-# Only available for CUDA version 5.5+.
-# CUDA_nvcuvenc_LIBRARY -- CUDA Video Encoder library.
-# Only available for CUDA version 3.2+.
-# Windows only.
-# CUDA_nvcuvid_LIBRARY -- CUDA Video Decoder library.
-# Only available for CUDA version 3.2+.
-# Windows only.
+# The script defines the following variables::
#
+# CUDA_VERSION_MAJOR -- The major version of cuda as reported by nvcc.
+# CUDA_VERSION_MINOR -- The minor version.
+# CUDA_VERSION
+# CUDA_VERSION_STRING -- CUDA_VERSION_MAJOR.CUDA_VERSION_MINOR
#
-# James Bigler, NVIDIA Corp (nvidia.com - jbigler)
-# Abe Stephens, SCI Institute -- http://www.sci.utah.edu/~abe/FindCuda.html
+# CUDA_TOOLKIT_ROOT_DIR -- Path to the CUDA Toolkit (defined if not set).
+# CUDA_SDK_ROOT_DIR -- Path to the CUDA SDK. Use this to find files in the
+# SDK. This script will not directly support finding
+# specific libraries or headers, as that isn't
+# supported by NVIDIA. If you want to change
+# libraries when the path changes see the
+# FindCUDA.cmake script for an example of how to clear
+# these variables. There are also examples of how to
+# use the CUDA_SDK_ROOT_DIR to locate headers or
+# libraries, if you so choose (at your own risk).
+# CUDA_INCLUDE_DIRS -- Include directory for cuda headers. Added automatically
+# for CUDA_ADD_EXECUTABLE and CUDA_ADD_LIBRARY.
+# CUDA_LIBRARIES -- Cuda RT library.
+# CUDA_CUFFT_LIBRARIES -- Device or emulation library for the Cuda FFT
+# implementation (alternative to:
+# CUDA_ADD_CUFFT_TO_TARGET macro)
+# CUDA_CUBLAS_LIBRARIES -- Device or emulation library for the Cuda BLAS
+# implementation (alterative to:
+# CUDA_ADD_CUBLAS_TO_TARGET macro).
+# CUDA_cudart_static_LIBRARY -- Statically linkable cuda runtime library.
+# Only available for CUDA version 5.5+
+# CUDA_cupti_LIBRARY -- CUDA Profiling Tools Interface library.
+# Only available for CUDA version 4.0+.
+# CUDA_curand_LIBRARY -- CUDA Random Number Generation library.
+# Only available for CUDA version 3.2+.
+# CUDA_cusolver_LIBRARY -- CUDA Direct Solver library.
+# Only available for CUDA version 7.0+.
+# CUDA_cusparse_LIBRARY -- CUDA Sparse Matrix library.
+# Only available for CUDA version 3.2+.
+# CUDA_npp_LIBRARY -- NVIDIA Performance Primitives lib.
+# Only available for CUDA version 4.0+.
+# CUDA_nppc_LIBRARY -- NVIDIA Performance Primitives lib (core).
+# Only available for CUDA version 5.5+.
+# CUDA_nppi_LIBRARY -- NVIDIA Performance Primitives lib (image processing).
+# Only available for CUDA version 5.5+.
+# CUDA_npps_LIBRARY -- NVIDIA Performance Primitives lib (signal processing).
+# Only available for CUDA version 5.5+.
+# CUDA_nvcuvenc_LIBRARY -- CUDA Video Encoder library.
+# Only available for CUDA version 3.2+.
+# Windows only.
+# CUDA_nvcuvid_LIBRARY -- CUDA Video Decoder library.
+# Only available for CUDA version 3.2+.
+# Windows only.
#
-# Copyright (c) 2008 - 2009 NVIDIA Corporation. All rights reserved.
+
+# James Bigler, NVIDIA Corp (nvidia.com - jbigler)
+# Abe Stephens, SCI Institute -- http://www.sci.utah.edu/~abe/FindCuda.html
+#
+# Copyright (c) 2008 - 2009 NVIDIA Corporation. All rights reserved.
#
-# Copyright (c) 2007-2009
-# Scientific Computing and Imaging Institute, University of Utah
+# Copyright (c) 2007-2009
+# Scientific Computing and Imaging Institute, University of Utah
#
-# This code is licensed under the MIT License. See the FindCUDA.cmake script
-# for the text of the license.
+# This code is licensed under the MIT License. See the FindCUDA.cmake script
+# for the text of the license.
# The MIT License
#
@@ -313,11 +346,6 @@
# FindCUDA.cmake
-# We need to have at least this version to support the VERSION_LESS argument to 'if' (2.6.2) and unset (2.6.3)
-cmake_policy(PUSH)
-cmake_minimum_required(VERSION 2.6.3)
-cmake_policy(POP)
-
# This macro helps us find the location of helper files we will need the full path to
macro(CUDA_FIND_HELPER_FILE _name _extension)
set(_full_name "${_name}.${_extension}")
@@ -440,7 +468,31 @@ set(CUDA_NVCC_FLAGS "" CACHE STRING "Semi-colon delimit multiple arguments.")
if(CMAKE_GENERATOR MATCHES "Visual Studio")
set(CUDA_HOST_COMPILER "$(VCInstallDir)bin" CACHE FILEPATH "Host side compiler used by NVCC")
else()
- set(CUDA_HOST_COMPILER "${CMAKE_C_COMPILER}" CACHE FILEPATH "Host side compiler used by NVCC")
+ if(APPLE
+ AND "${CMAKE_C_COMPILER_ID}" MATCHES "Clang"
+ AND "${CMAKE_C_COMPILER}" MATCHES "/cc$")
+ # Using cc which is symlink to clang may let NVCC think it is GCC and issue
+ # unhandled -dumpspecs option to clang. Also in case neither
+ # CMAKE_C_COMPILER is defined (project does not use C language) nor
+ # CUDA_HOST_COMPILER is specified manually we should skip -ccbin and let
+ # nvcc use its own default C compiler.
+ # Only care about this on APPLE with clang to avoid
+ # following symlinks to things like ccache
+ if(DEFINED CMAKE_C_COMPILER AND NOT DEFINED CUDA_HOST_COMPILER)
+ get_filename_component(c_compiler_realpath "${CMAKE_C_COMPILER}" REALPATH)
+ # if the real path does not end up being clang then
+ # go back to using CMAKE_C_COMPILER
+ if(NOT "${c_compiler_realpath}" MATCHES "/clang$")
+ set(c_compiler_realpath "${CMAKE_C_COMPILER}")
+ endif()
+ else()
+ set(c_compiler_realpath "")
+ endif()
+ set(CUDA_HOST_COMPILER "${c_compiler_realpath}" CACHE FILEPATH "Host side compiler used by NVCC")
+ else()
+ set(CUDA_HOST_COMPILER "${CMAKE_C_COMPILER}"
+ CACHE FILEPATH "Host side compiler used by NVCC")
+ endif()
endif()
# Propagate the host flags to the host compiler via -Xcompiler
@@ -459,6 +511,10 @@ mark_as_advanced(
CUDA_HOST_COMPILATION_CPP
CUDA_NVCC_FLAGS
CUDA_PROPAGATE_HOST_FLAGS
+ CUDA_BUILD_CUBIN
+ CUDA_BUILD_EMULATION
+ CUDA_VERBOSE_BUILD
+ CUDA_SEPARABLE_COMPILATION
)
# Makefile and similar generators don't define CMAKE_CONFIGURATION_TYPES, so we
@@ -481,25 +537,23 @@ endforeach()
###############################################################################
###############################################################################
-# Check to see if the CUDA_TOOLKIT_ROOT_DIR and CUDA_SDK_ROOT_DIR have changed,
-# if they have then clear the cache variables, so that will be detected again.
-if(NOT "${CUDA_TOOLKIT_ROOT_DIR}" STREQUAL "${CUDA_TOOLKIT_ROOT_DIR_INTERNAL}")
- unset(CUDA_NVCC_EXECUTABLE CACHE)
+macro(cuda_unset_include_and_libraries)
unset(CUDA_TOOLKIT_INCLUDE CACHE)
unset(CUDA_CUDART_LIBRARY CACHE)
+ unset(CUDA_CUDA_LIBRARY CACHE)
# Make sure you run this before you unset CUDA_VERSION.
if(CUDA_VERSION VERSION_EQUAL "3.0")
# This only existed in the 3.0 version of the CUDA toolkit
unset(CUDA_CUDARTEMU_LIBRARY CACHE)
endif()
- unset(CUDA_VERSION CACHE)
- unset(CUDA_CUDA_LIBRARY CACHE)
- unset(CUDA_cupti_LIBRARY CACHE)
+ unset(CUDA_cudart_static_LIBRARY CACHE)
unset(CUDA_cublas_LIBRARY CACHE)
unset(CUDA_cublasemu_LIBRARY CACHE)
unset(CUDA_cufft_LIBRARY CACHE)
unset(CUDA_cufftemu_LIBRARY CACHE)
+ unset(CUDA_cupti_LIBRARY CACHE)
unset(CUDA_curand_LIBRARY CACHE)
+ unset(CUDA_cusolver_LIBRARY CACHE)
unset(CUDA_cusparse_LIBRARY CACHE)
unset(CUDA_npp_LIBRARY CACHE)
unset(CUDA_nppc_LIBRARY CACHE)
@@ -507,6 +561,21 @@ if(NOT "${CUDA_TOOLKIT_ROOT_DIR}" STREQUAL "${CUDA_TOOLKIT_ROOT_DIR_INTERNAL}")
unset(CUDA_npps_LIBRARY CACHE)
unset(CUDA_nvcuvenc_LIBRARY CACHE)
unset(CUDA_nvcuvid_LIBRARY CACHE)
+
+ unset(CUDA_USE_STATIC_CUDA_RUNTIME CACHE)
+endmacro()
+
+# Check to see if the CUDA_TOOLKIT_ROOT_DIR and CUDA_SDK_ROOT_DIR have changed,
+# if they have then clear the cache variables, so that will be detected again.
+if(NOT "${CUDA_TOOLKIT_ROOT_DIR}" STREQUAL "${CUDA_TOOLKIT_ROOT_DIR_INTERNAL}")
+ unset(CUDA_TOOLKIT_TARGET_DIR CACHE)
+ unset(CUDA_NVCC_EXECUTABLE CACHE)
+ cuda_unset_include_and_libraries()
+ unset(CUDA_VERSION CACHE)
+endif()
+
+if(NOT "${CUDA_TOOLKIT_TARGET_DIR}" STREQUAL "${CUDA_TOOLKIT_TARGET_DIR_INTERNAL}")
+ cuda_unset_include_and_libraries()
endif()
if(NOT "${CUDA_SDK_ROOT_DIR}" STREQUAL "${CUDA_SDK_ROOT_DIR_INTERNAL}")
@@ -581,10 +650,30 @@ endif()
# Always set this convenience variable
set(CUDA_VERSION_STRING "${CUDA_VERSION}")
+# Support for arm cross compilation with CUDA 5.5
+if(CUDA_VERSION VERSION_GREATER "5.0" AND CMAKE_CROSSCOMPILING AND CMAKE_SYSTEM_PROCESSOR MATCHES "arm" AND EXISTS "${CUDA_TOOLKIT_ROOT_DIR}/targets/armv7-linux-gnueabihf")
+ set(CUDA_TOOLKIT_TARGET_DIR "${CUDA_TOOLKIT_ROOT_DIR}/targets/armv7-linux-gnueabihf" CACHE PATH "Toolkit target location.")
+# Support for aarch64 cross compilation with CUDA 7.0
+elseif(CUDA_VERSION VERSION_GREATER "6.5" AND CMAKE_CROSSCOMPILING AND CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64" AND EXISTS "${CUDA_TOOLKIT_ROOT_DIR}/targets/aarch64-linux")
+ set(CUDA_TOOLKIT_TARGET_DIR "${CUDA_TOOLKIT_ROOT_DIR}/targets/aarch64-linux" CACHE PATH "Toolkit target location.")
+else()
+ set(CUDA_TOOLKIT_TARGET_DIR "${CUDA_TOOLKIT_ROOT_DIR}" CACHE PATH "Toolkit target location.")
+endif()
+mark_as_advanced(CUDA_TOOLKIT_TARGET_DIR)
+
+# Target CPU architecture
+if(CUDA_VERSION VERSION_GREATER "5.0" AND CMAKE_CROSSCOMPILING AND CMAKE_SYSTEM_PROCESSOR MATCHES "arm")
+ set(_cuda_target_cpu_arch_initial "ARM")
+else()
+ set(_cuda_target_cpu_arch_initial "")
+endif()
+set(CUDA_TARGET_CPU_ARCH ${_cuda_target_cpu_arch_initial} CACHE STRING "Specify the name of the class of CPU architecture for which the input files must be compiled.")
+mark_as_advanced(CUDA_TARGET_CPU_ARCH)
+
# CUDA_TOOLKIT_INCLUDE
find_path(CUDA_TOOLKIT_INCLUDE
device_functions.h # Header included in toolkit
- PATHS "${CUDA_TOOLKIT_ROOT_DIR}"
+ PATHS "${CUDA_TOOLKIT_TARGET_DIR}" "${CUDA_TOOLKIT_ROOT_DIR}"
ENV CUDA_PATH
ENV CUDA_INC_PATH
PATH_SUFFIXES include
@@ -608,7 +697,7 @@ macro(cuda_find_library_local_first_with_path_ext _var _names _doc _path_ext )
# (lib/Win32) and the old path (lib).
find_library(${_var}
NAMES ${_names}
- PATHS "${CUDA_TOOLKIT_ROOT_DIR}"
+ PATHS "${CUDA_TOOLKIT_TARGET_DIR}" "${CUDA_TOOLKIT_ROOT_DIR}"
ENV CUDA_PATH
ENV CUDA_LIB_PATH
PATH_SUFFIXES ${_cuda_64bit_lib_dir} "${_path_ext}lib/Win32" "${_path_ext}lib" "${_path_ext}libWin32"
@@ -641,6 +730,49 @@ if(CUDA_VERSION VERSION_EQUAL "3.0")
CUDA_CUDARTEMU_LIBRARY
)
endif()
+if(NOT CUDA_VERSION VERSION_LESS "5.5")
+ cuda_find_library_local_first(CUDA_cudart_static_LIBRARY cudart_static "static CUDA runtime library")
+ mark_as_advanced(CUDA_cudart_static_LIBRARY)
+endif()
+if(CUDA_cudart_static_LIBRARY)
+ # Set whether to use the static cuda runtime.
+ option(CUDA_USE_STATIC_CUDA_RUNTIME "Use the static version of the CUDA runtime library if available" ON)
+else()
+ option(CUDA_USE_STATIC_CUDA_RUNTIME "Use the static version of the CUDA runtime library if available" OFF)
+endif()
+
+if(CUDA_USE_STATIC_CUDA_RUNTIME)
+ if(UNIX)
+ # Check for the dependent libraries. Here we look for pthreads.
+ if (DEFINED CMAKE_THREAD_PREFER_PTHREAD)
+ set(_cuda_cmake_thread_prefer_pthread ${CMAKE_THREAD_PREFER_PTHREAD})
+ endif()
+ set(CMAKE_THREAD_PREFER_PTHREAD 1)
+
+ # Many of the FindXYZ CMake comes with makes use of try_compile with int main(){return 0;}
+ # as the source file. Unfortunately this causes a warning with -Wstrict-prototypes and
+ # -Werror causes the try_compile to fail. We will just temporarily disable other flags
+ # when doing the find_package command here.
+ set(_cuda_cmake_c_flags ${CMAKE_C_FLAGS})
+ set(CMAKE_C_FLAGS "-fPIC")
+ find_package(Threads REQUIRED)
+ set(CMAKE_C_FLAGS ${_cuda_cmake_c_flags})
+
+ if (DEFINED _cuda_cmake_thread_prefer_pthread)
+ set(CMAKE_THREAD_PREFER_PTHREAD ${_cuda_cmake_thread_prefer_pthread})
+ unset(_cuda_cmake_thread_prefer_pthread)
+ else()
+ unset(CMAKE_THREAD_PREFER_PTHREAD)
+ endif()
+ if (NOT APPLE)
+ # Here is librt that has things such as, clock_gettime, shm_open, and shm_unlink.
+ find_library(CUDA_rt_LIBRARY rt)
+ if (NOT CUDA_rt_LIBRARY)
+ message(WARNING "Expecting to find librt for libcudart_static, but didn't find it.")
+ endif()
+ endif()
+ endif()
+endif()
# CUPTI library showed up in cuda toolkit 4.0
if(NOT CUDA_VERSION VERSION_LESS "4.0")
@@ -648,24 +780,29 @@ if(NOT CUDA_VERSION VERSION_LESS "4.0")
mark_as_advanced(CUDA_cupti_LIBRARY)
endif()
+# Set the CUDA_LIBRARIES variable. This is the set of stuff to link against if you are
+# using the CUDA runtime. For the dynamic version of the runtime, most of the
+# dependencies are brough in, but for the static version there are additional libraries
+# and linker commands needed.
+# Initialize to empty
+set(CUDA_LIBRARIES)
+
# If we are using emulation mode and we found the cudartemu library then use
# that one instead of cudart.
if(CUDA_BUILD_EMULATION AND CUDA_CUDARTEMU_LIBRARY)
- set(CUDA_LIBRARIES ${CUDA_CUDARTEMU_LIBRARY})
-else()
- set(CUDA_LIBRARIES ${CUDA_CUDART_LIBRARY})
-endif()
-if(APPLE)
- # We need to add the path to cudart to the linker using rpath, since the
- # library name for the cuda libraries is prepended with @rpath.
- if(CUDA_BUILD_EMULATION AND CUDA_CUDARTEMU_LIBRARY)
- get_filename_component(_cuda_path_to_cudart "${CUDA_CUDARTEMU_LIBRARY}" PATH)
- else()
- get_filename_component(_cuda_path_to_cudart "${CUDA_CUDART_LIBRARY}" PATH)
+ list(APPEND CUDA_LIBRARIES ${CUDA_CUDARTEMU_LIBRARY})
+elseif(CUDA_USE_STATIC_CUDA_RUNTIME AND CUDA_cudart_static_LIBRARY)
+ list(APPEND CUDA_LIBRARIES ${CUDA_cudart_static_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS})
+ if (CUDA_rt_LIBRARY)
+ list(APPEND CUDA_LIBRARIES ${CUDA_rt_LIBRARY})
endif()
- if(_cuda_path_to_cudart)
- list(APPEND CUDA_LIBRARIES -Wl,-rpath "-Wl,${_cuda_path_to_cudart}")
+ if(APPLE)
+ # We need to add the default path to the driver (libcuda.dylib) as an rpath, so that
+ # the static cuda runtime can find it at runtime.
+ list(APPEND CUDA_LIBRARIES -Wl,-rpath,/usr/local/cuda/lib)
endif()
+else()
+ list(APPEND CUDA_LIBRARIES ${CUDA_CUDART_LIBRARY})
endif()
# 1.1 toolkit on linux doesn't appear to have a separate library on
@@ -718,6 +855,10 @@ if(CUDA_VERSION VERSION_GREATER "5.0")
elseif(NOT CUDA_VERSION VERSION_LESS "4.0")
find_cuda_helper_libs(npp)
endif()
+if(NOT CUDA_VERSION VERSION_LESS "7.0")
+ # cusolver showed up in version 7.0
+ find_cuda_helper_libs(cusolver)
+endif()
if (CUDA_BUILD_EMULATION)
set(CUDA_CUFFT_LIBRARIES ${CUDA_cufftemu_LIBRARY})
@@ -799,6 +940,8 @@ set(CUDA_FOUND TRUE)
set(CUDA_TOOLKIT_ROOT_DIR_INTERNAL "${CUDA_TOOLKIT_ROOT_DIR}" CACHE INTERNAL
"This is the value of the last time CUDA_TOOLKIT_ROOT_DIR was set successfully." FORCE)
+set(CUDA_TOOLKIT_TARGET_DIR_INTERNAL "${CUDA_TOOLKIT_TARGET_DIR}" CACHE INTERNAL
+ "This is the value of the last time CUDA_TOOLKIT_TARGET_DIR was set successfully." FORCE)
set(CUDA_SDK_ROOT_DIR_INTERNAL "${CUDA_SDK_ROOT_DIR}" CACHE INTERNAL
"This is the value of the last time CUDA_SDK_ROOT_DIR was set successfully." FORCE)
@@ -844,15 +987,15 @@ macro(CUDA_GET_SOURCES_AND_OPTIONS _sources _cmake_options _options)
set( ${_options} )
set( _found_options FALSE )
foreach(arg ${ARGN})
- if(arg STREQUAL "OPTIONS")
+ if("x${arg}" STREQUAL "xOPTIONS")
set( _found_options TRUE )
elseif(
- arg STREQUAL "WIN32" OR
- arg STREQUAL "MACOSX_BUNDLE" OR
- arg STREQUAL "EXCLUDE_FROM_ALL" OR
- arg STREQUAL "STATIC" OR
- arg STREQUAL "SHARED" OR
- arg STREQUAL "MODULE"
+ "x${arg}" STREQUAL "xWIN32" OR
+ "x${arg}" STREQUAL "xMACOSX_BUNDLE" OR
+ "x${arg}" STREQUAL "xEXCLUDE_FROM_ALL" OR
+ "x${arg}" STREQUAL "xSTATIC" OR
+ "x${arg}" STREQUAL "xSHARED" OR
+ "x${arg}" STREQUAL "xMODULE"
)
list(APPEND ${_cmake_options} ${arg})
else()
@@ -948,7 +1091,7 @@ function(CUDA_COMPUTE_BUILD_PATH path build_path)
endif()
endif()
- # This recipie is from cmLocalGenerator::CreateSafeUniqueObjectFileName in the
+ # This recipe is from cmLocalGenerator::CreateSafeUniqueObjectFileName in the
# CMake source.
# Remove leading /
@@ -977,7 +1120,7 @@ endfunction()
# a .cpp or .ptx file.
# INPUT:
# cuda_target - Target name
-# format - PTX or OBJ
+# format - PTX, CUBIN, FATBIN or OBJ
# FILE1 .. FILEN - The remaining arguments are the sources to be wrapped.
# OPTIONS - Extra options to NVCC
# OUTPUT:
@@ -1023,6 +1166,10 @@ macro(CUDA_WRAP_SRCS cuda_target format generated_files)
set(nvcc_flags ${nvcc_flags} -m32)
endif()
+ if(CUDA_TARGET_CPU_ARCH)
+ set(nvcc_flags ${nvcc_flags} "--target-cpu-architecture=${CUDA_TARGET_CPU_ARCH}")
+ endif()
+
# This needs to be passed in at this stage, because VS needs to fill out the
# value of VCInstallDir from within VS. Note that CCBIN is only used if
# -ccbin or --compiler-bindir isn't used and CUDA_HOST_COMPILER matches
@@ -1131,6 +1278,19 @@ macro(CUDA_WRAP_SRCS cuda_target format generated_files)
set(_cuda_nvcc_flags_config "${_cuda_nvcc_flags_config}\nset(CUDA_NVCC_FLAGS_${config_upper} ${CUDA_NVCC_FLAGS_${config_upper}} ;; ${CUDA_WRAP_OPTION_NVCC_FLAGS_${config_upper}})")
endforeach()
+ # Process the C++11 flag. If the host sets the flag, we need to add it to nvcc and
+ # remove it from the host. This is because -Xcompile -std=c++ will choke nvcc (it uses
+ # the C preprocessor). In order to get this to work correctly, we need to use nvcc's
+ # specific c++11 flag.
+ if( "${_cuda_host_flags}" MATCHES "-std=c\\+\\+11")
+ # Add the c++11 flag to nvcc if it isn't already present. Note that we only look at
+ # the main flag instead of the configuration specific flags.
+ if( NOT "${CUDA_NVCC_FLAGS}" MATCHES "-std;c\\+\\+11" )
+ list(APPEND nvcc_flags --std c++11)
+ endif()
+ string(REGEX REPLACE "[-]+std=c\\+\\+11" "" _cuda_host_flags "${_cuda_host_flags}")
+ endif()
+
# Get the list of definitions from the directory property
get_directory_property(CUDA_NVCC_DEFINITIONS COMPILE_DEFINITIONS)
if(CUDA_NVCC_DEFINITIONS)
@@ -1151,24 +1311,36 @@ macro(CUDA_WRAP_SRCS cuda_target format generated_files)
foreach(file ${ARGN})
# Ignore any file marked as a HEADER_FILE_ONLY
get_source_file_property(_is_header ${file} HEADER_FILE_ONLY)
- if(${file} MATCHES ".*\\.cu$" AND NOT _is_header)
+ # Allow per source file overrides of the format. Also allows compiling non-.cu files.
+ get_source_file_property(_cuda_source_format ${file} CUDA_SOURCE_PROPERTY_FORMAT)
+ if((${file} MATCHES "\\.cu$" OR _cuda_source_format) AND NOT _is_header)
- # Allow per source file overrides of the format.
- get_source_file_property(_cuda_source_format ${file} CUDA_SOURCE_PROPERTY_FORMAT)
if(NOT _cuda_source_format)
set(_cuda_source_format ${format})
endif()
-
- if( ${_cuda_source_format} MATCHES "PTX" )
- set( compile_to_ptx ON )
- elseif( ${_cuda_source_format} MATCHES "OBJ")
- set( compile_to_ptx OFF )
+ # If file isn't a .cu file, we need to tell nvcc to treat it as such.
+ if(NOT ${file} MATCHES "\\.cu$")
+ set(cuda_language_flag -x=cu)
else()
- message( FATAL_ERROR "Invalid format flag passed to CUDA_WRAP_SRCS for file '${file}': '${_cuda_source_format}'. Use OBJ or PTX.")
+ set(cuda_language_flag)
endif()
+ if( ${_cuda_source_format} MATCHES "OBJ")
+ set( cuda_compile_to_external_module OFF )
+ else()
+ set( cuda_compile_to_external_module ON )
+ if( ${_cuda_source_format} MATCHES "PTX" )
+ set( cuda_compile_to_external_module_type "ptx" )
+ elseif( ${_cuda_source_format} MATCHES "CUBIN")
+ set( cuda_compile_to_external_module_type "cubin" )
+ elseif( ${_cuda_source_format} MATCHES "FATBIN")
+ set( cuda_compile_to_external_module_type "fatbin" )
+ else()
+ message( FATAL_ERROR "Invalid format flag passed to CUDA_WRAP_SRCS or set with CUDA_SOURCE_PROPERTY_FORMAT file property for file '${file}': '${_cuda_source_format}'. Use OBJ, PTX, CUBIN or FATBIN.")
+ endif()
+ endif()
- if(compile_to_ptx)
+ if(cuda_compile_to_external_module)
# Don't use any of the host compilation flags for PTX targets.
set(CUDA_HOST_FLAGS)
set(CUDA_NVCC_FLAGS_CONFIG)
@@ -1183,7 +1355,7 @@ macro(CUDA_WRAP_SRCS cuda_target format generated_files)
if(CUDA_GENERATED_OUTPUT_DIR)
set(cuda_compile_output_dir "${CUDA_GENERATED_OUTPUT_DIR}")
else()
- if ( compile_to_ptx )
+ if ( cuda_compile_to_external_module )
set(cuda_compile_output_dir "${CMAKE_CURRENT_BINARY_DIR}")
else()
set(cuda_compile_output_dir "${cuda_compile_intermediate_directory}")
@@ -1193,10 +1365,10 @@ macro(CUDA_WRAP_SRCS cuda_target format generated_files)
# Add a custom target to generate a c or ptx file. ######################
get_filename_component( basename ${file} NAME )
- if( compile_to_ptx )
+ if( cuda_compile_to_external_module )
set(generated_file_path "${cuda_compile_output_dir}")
- set(generated_file_basename "${cuda_target}_generated_${basename}.ptx")
- set(format_flag "-ptx")
+ set(generated_file_basename "${cuda_target}_generated_${basename}.${cuda_compile_to_external_module_type}")
+ set(format_flag "-${cuda_compile_to_external_module_type}")
file(MAKE_DIRECTORY "${cuda_compile_output_dir}")
else()
set(generated_file_path "${cuda_compile_output_dir}/${CMAKE_CFG_INTDIR}")
@@ -1219,7 +1391,7 @@ macro(CUDA_WRAP_SRCS cuda_target format generated_files)
set(custom_target_script "${cuda_compile_intermediate_directory}/${generated_file_basename}.cmake")
# Setup properties for obj files:
- if( NOT compile_to_ptx )
+ if( NOT cuda_compile_to_external_module )
set_source_files_properties("${generated_file}"
PROPERTIES
EXTERNAL_OBJECT true # This is an object file not to be compiled, but only be linked.
@@ -1234,7 +1406,7 @@ macro(CUDA_WRAP_SRCS cuda_target format generated_files)
set(source_file "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
endif()
- if( NOT compile_to_ptx AND CUDA_SEPARABLE_COMPILATION)
+ if( NOT cuda_compile_to_external_module AND CUDA_SEPARABLE_COMPILATION)
list(APPEND ${cuda_target}_SEPARABLE_COMPILATION_OBJECTS "${generated_file}")
endif()
@@ -1251,7 +1423,7 @@ macro(CUDA_WRAP_SRCS cuda_target format generated_files)
# Build the NVCC made dependency file ###################################
set(build_cubin OFF)
if ( NOT CUDA_BUILD_EMULATION AND CUDA_BUILD_CUBIN )
- if ( NOT compile_to_ptx )
+ if ( NOT cuda_compile_to_external_module )
set ( build_cubin ON )
endif()
endif()
@@ -1278,12 +1450,17 @@ macro(CUDA_WRAP_SRCS cuda_target format generated_files)
# Create up the comment string
file(RELATIVE_PATH generated_file_relative_path "${CMAKE_BINARY_DIR}" "${generated_file}")
- if(compile_to_ptx)
- set(cuda_build_comment_string "Building NVCC ptx file ${generated_file_relative_path}")
+ if(cuda_compile_to_external_module)
+ set(cuda_build_comment_string "Building NVCC ${cuda_compile_to_external_module_type} file ${generated_file_relative_path}")
else()
set(cuda_build_comment_string "Building NVCC (${cuda_build_type}) object ${generated_file_relative_path}")
endif()
+ set(_verbatim VERBATIM)
+ if(ccbin_flags MATCHES "\\$\\(VCInstallDir\\)")
+ set(_verbatim "")
+ endif()
+
# Build the generated file and dependency file ##########################
add_custom_command(
OUTPUT ${generated_file}
@@ -1302,6 +1479,7 @@ macro(CUDA_WRAP_SRCS cuda_target format generated_files)
-P "${custom_target_script}"
WORKING_DIRECTORY "${cuda_compile_intermediate_directory}"
COMMENT "${cuda_build_comment_string}"
+ ${_verbatim}
)
# Make sure the build system knows the file is generated.
@@ -1323,10 +1501,10 @@ endmacro()
function(_cuda_get_important_host_flags important_flags flag_string)
if(CMAKE_GENERATOR MATCHES "Visual Studio")
- string(REGEX MATCHALL "/M[DT][d]?" flags ${flag_string})
+ string(REGEX MATCHALL "/M[DT][d]?" flags "${flag_string}")
list(APPEND ${important_flags} ${flags})
else()
- string(REGEX MATCHALL "-fPIC" flags ${flag_string})
+ string(REGEX MATCHALL "-fPIC" flags "${flag_string}")
list(APPEND ${important_flags} ${flags})
endif()
set(${important_flags} ${${important_flags}} PARENT_SCOPE)
@@ -1372,18 +1550,40 @@ function(CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS output_file cuda_target options
# If -ccbin, --compiler-bindir has been specified, don't do anything. Otherwise add it here.
list( FIND nvcc_flags "-ccbin" ccbin_found0 )
list( FIND nvcc_flags "--compiler-bindir" ccbin_found1 )
- if( ccbin_found0 LESS 0 AND ccbin_found1 LESS 0 )
- list(APPEND nvcc_flags -ccbin "\"${CUDA_HOST_COMPILER}\"")
+ if( ccbin_found0 LESS 0 AND ccbin_found1 LESS 0 AND CUDA_HOST_COMPILER )
+ # Match VERBATIM check below.
+ if(CUDA_HOST_COMPILER MATCHES "\\$\\(VCInstallDir\\)")
+ list(APPEND nvcc_flags -ccbin "\"${CUDA_HOST_COMPILER}\"")
+ else()
+ list(APPEND nvcc_flags -ccbin "${CUDA_HOST_COMPILER}")
+ endif()
endif()
+
+ # Create a list of flags specified by CUDA_NVCC_FLAGS_${CONFIG} and CMAKE_${CUDA_C_OR_CXX}_FLAGS*
+ set(config_specific_flags)
set(flags)
foreach(config ${CUDA_configuration_types})
string(TOUPPER ${config} config_upper)
+ # Add config specific flags
+ foreach(f ${CUDA_NVCC_FLAGS_${config_upper}})
+ list(APPEND config_specific_flags $<$<CONFIG:${config}>:${f}>)
+ endforeach()
set(important_host_flags)
- _cuda_get_important_host_flags(important_host_flags ${CMAKE_${CUDA_C_OR_CXX}_FLAGS_${config_upper}})
+ _cuda_get_important_host_flags(important_host_flags "${CMAKE_${CUDA_C_OR_CXX}_FLAGS_${config_upper}}")
foreach(f ${important_host_flags})
list(APPEND flags $<$<CONFIG:${config}>:-Xcompiler> $<$<CONFIG:${config}>:${f}>)
endforeach()
endforeach()
+ # Add CMAKE_${CUDA_C_OR_CXX}_FLAGS
+ set(important_host_flags)
+ _cuda_get_important_host_flags(important_host_flags "${CMAKE_${CUDA_C_OR_CXX}_FLAGS}")
+ foreach(f ${important_host_flags})
+ list(APPEND flags -Xcompiler ${f})
+ endforeach()
+
+ # Add our general CUDA_NVCC_FLAGS with the configuration specifig flags
+ set(nvcc_flags ${CUDA_NVCC_FLAGS} ${config_specific_flags} ${nvcc_flags})
+
file(RELATIVE_PATH output_file_relative_path "${CMAKE_BINARY_DIR}" "${output_file}")
# Some generators don't handle the multiple levels of custom command
@@ -1391,12 +1591,16 @@ function(CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS output_file cuda_target options
# we work around that issue by compiling the intermediate link object as a
# pre-link custom command in that situation.
set(do_obj_build_rule TRUE)
- if (MSVC_VERSION GREATER 1599)
- # VS 2010 and 2012 have this problem. If future versions fix this issue,
- # it should still work, it just won't be as nice as the other method.
+ if (MSVC_VERSION GREATER 1599 AND MSVC_VERSION LESS 1800)
+ # VS 2010 and 2012 have this problem.
set(do_obj_build_rule FALSE)
endif()
+ set(_verbatim VERBATIM)
+ if(nvcc_flags MATCHES "\\$\\(VCInstallDir\\)")
+ set(_verbatim "")
+ endif()
+
if (do_obj_build_rule)
add_custom_command(
OUTPUT ${output_file}
@@ -1404,13 +1608,17 @@ function(CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS output_file cuda_target options
COMMAND ${CUDA_NVCC_EXECUTABLE} ${nvcc_flags} -dlink ${object_files} -o ${output_file}
${flags}
COMMENT "Building NVCC intermediate link file ${output_file_relative_path}"
+ ${_verbatim}
)
else()
+ get_filename_component(output_file_dir "${output_file}" DIRECTORY)
add_custom_command(
TARGET ${cuda_target}
PRE_LINK
COMMAND ${CMAKE_COMMAND} -E echo "Building NVCC intermediate link file ${output_file_relative_path}"
+ COMMAND ${CMAKE_COMMAND} -E make_directory "${output_file_dir}"
COMMAND ${CUDA_NVCC_EXECUTABLE} ${nvcc_flags} ${flags} -dlink ${object_files} -o "${output_file}"
+ ${_verbatim}
)
endif()
endif()
@@ -1509,21 +1717,29 @@ endmacro()
###############################################################################
###############################################################################
-# CUDA COMPILE
+# (Internal) helper for manually added cuda source files with specific targets
###############################################################################
###############################################################################
-macro(CUDA_COMPILE generated_files)
+macro(cuda_compile_base cuda_target format generated_files)
# Separate the sources from the options
CUDA_GET_SOURCES_AND_OPTIONS(_sources _cmake_options _options ${ARGN})
# Create custom commands and targets for each file.
- CUDA_WRAP_SRCS( cuda_compile OBJ _generated_files ${_sources} ${_cmake_options}
+ CUDA_WRAP_SRCS( ${cuda_target} ${format} _generated_files ${_sources} ${_cmake_options}
OPTIONS ${_options} )
set( ${generated_files} ${_generated_files})
endmacro()
+###############################################################################
+###############################################################################
+# CUDA COMPILE
+###############################################################################
+###############################################################################
+macro(CUDA_COMPILE generated_files)
+ cuda_compile_base(cuda_compile OBJ ${generated_files} ${ARGN})
+endmacro()
###############################################################################
###############################################################################
@@ -1531,17 +1747,28 @@ endmacro()
###############################################################################
###############################################################################
macro(CUDA_COMPILE_PTX generated_files)
+ cuda_compile_base(cuda_compile_ptx PTX ${generated_files} ${ARGN})
+endmacro()
- # Separate the sources from the options
- CUDA_GET_SOURCES_AND_OPTIONS(_sources _cmake_options _options ${ARGN})
- # Create custom commands and targets for each file.
- CUDA_WRAP_SRCS( cuda_compile_ptx PTX _generated_files ${_sources} ${_cmake_options}
- OPTIONS ${_options} )
-
- set( ${generated_files} ${_generated_files})
+###############################################################################
+###############################################################################
+# CUDA COMPILE FATBIN
+###############################################################################
+###############################################################################
+macro(CUDA_COMPILE_FATBIN generated_files)
+ cuda_compile_base(cuda_compile_fatbin FATBIN ${generated_files} ${ARGN})
+endmacro()
+###############################################################################
+###############################################################################
+# CUDA COMPILE CUBIN
+###############################################################################
+###############################################################################
+macro(CUDA_COMPILE_CUBIN generated_files)
+ cuda_compile_base(cuda_compile_cubin CUBIN ${generated_files} ${ARGN})
endmacro()
+
###############################################################################
###############################################################################
# CUDA ADD CUFFT TO TARGET
diff --git a/Modules/FindCUDA/make2cmake.cmake b/Modules/FindCUDA/make2cmake.cmake
index 1b53d177d..c433fa8ed 100644
--- a/Modules/FindCUDA/make2cmake.cmake
+++ b/Modules/FindCUDA/make2cmake.cmake
@@ -37,12 +37,11 @@
file(READ ${input_file} depend_text)
-if (${depend_text} MATCHES ".+")
+if (NOT "${depend_text}" STREQUAL "")
# message("FOUND DEPENDS")
- # Remember, four backslashes is escaped to one backslash in the string.
- string(REGEX REPLACE "\\\\ " " " depend_text ${depend_text})
+ string(REPLACE "\\ " " " depend_text ${depend_text})
# This works for the nvcc -M generated dependency files.
string(REGEX REPLACE "^.* : " "" depend_text ${depend_text})
diff --git a/Modules/FindCUDA/parse_cubin.cmake b/Modules/FindCUDA/parse_cubin.cmake
index 94be7e2cb..626c8a2e4 100644
--- a/Modules/FindCUDA/parse_cubin.cmake
+++ b/Modules/FindCUDA/parse_cubin.cmake
@@ -37,11 +37,10 @@
file(READ ${input_file} file_text)
-if (${file_text} MATCHES ".+")
+if (NOT "${file_text}" STREQUAL "")
- # Remember, four backslashes is escaped to one backslash in the string.
- string(REGEX REPLACE ";" "\\\\;" file_text ${file_text})
- string(REGEX REPLACE "\ncode" ";code" file_text ${file_text})
+ string(REPLACE ";" "\\;" file_text ${file_text})
+ string(REPLACE "\ncode" ";code" file_text ${file_text})
list(LENGTH file_text len)
@@ -57,7 +56,7 @@ if (${file_text} MATCHES ".+")
# Extract kernel names.
if (${entry} MATCHES "[^g]name = ([^ ]+)")
- string(REGEX REPLACE ".* = ([^ ]+)" "\\1" entry ${entry})
+ set(entry "${CMAKE_MATCH_1}")
# Check to see if the kernel name starts with "_"
set(skip FALSE)
@@ -76,19 +75,19 @@ if (${file_text} MATCHES ".+")
# Registers
if (${entry} MATCHES "reg([ ]+)=([ ]+)([^ ]+)")
- string(REGEX REPLACE ".*([ ]+)=([ ]+)([^ ]+)" "\\3" entry ${entry})
+ set(entry "${CMAKE_MATCH_3}")
message("Registers: ${entry}")
endif()
# Local memory
if (${entry} MATCHES "lmem([ ]+)=([ ]+)([^ ]+)")
- string(REGEX REPLACE ".*([ ]+)=([ ]+)([^ ]+)" "\\3" entry ${entry})
+ set(entry "${CMAKE_MATCH_3}")
message("Local: ${entry}")
endif()
# Shared memory
if (${entry} MATCHES "smem([ ]+)=([ ]+)([^ ]+)")
- string(REGEX REPLACE ".*([ ]+)=([ ]+)([^ ]+)" "\\3" entry ${entry})
+ set(entry "${CMAKE_MATCH_3}")
message("Shared: ${entry}")
endif()
diff --git a/Modules/FindCUDA/run_nvcc.cmake b/Modules/FindCUDA/run_nvcc.cmake
index f0aac8487..80323091d 100644
--- a/Modules/FindCUDA/run_nvcc.cmake
+++ b/Modules/FindCUDA/run_nvcc.cmake
@@ -62,7 +62,7 @@ set(cmake_dependency_file "@cmake_dependency_file@") # path
set(CUDA_make2cmake "@CUDA_make2cmake@") # path
set(CUDA_parse_cubin "@CUDA_parse_cubin@") # path
set(build_cubin @build_cubin@) # bool
-set(CUDA_HOST_COMPILER "@CUDA_HOST_COMPILER@") # bool
+set(CUDA_HOST_COMPILER "@CUDA_HOST_COMPILER@") # path
# We won't actually use these variables for now, but we need to set this, in
# order to force this file to be run again if it changes.
set(generated_file_path "@generated_file_path@") # path
@@ -75,6 +75,7 @@ set(CUDA_NVCC_FLAGS @CUDA_NVCC_FLAGS@ ;; @CUDA_WRAP_OPTION_NVCC_FLAGS@) # list
set(nvcc_flags @nvcc_flags@) # list
set(CUDA_NVCC_INCLUDE_ARGS "@CUDA_NVCC_INCLUDE_ARGS@") # list (needs to be in quotes to handle spaces properly).
set(format_flag "@format_flag@") # string
+set(cuda_language_flag @cuda_language_flag@) # list
if(build_cubin AND NOT generated_cubin_file)
message(FATAL_ERROR "You must specify generated_cubin_file on the command line")
@@ -106,7 +107,7 @@ list(APPEND CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS_${build_configuration}})
# Any -ccbin existing in CUDA_NVCC_FLAGS gets highest priority
list( FIND CUDA_NVCC_FLAGS "-ccbin" ccbin_found0 )
list( FIND CUDA_NVCC_FLAGS "--compiler-bindir" ccbin_found1 )
-if( ccbin_found0 LESS 0 AND ccbin_found1 LESS 0 )
+if( ccbin_found0 LESS 0 AND ccbin_found1 LESS 0 AND CUDA_HOST_COMPILER )
if (CUDA_HOST_COMPILER STREQUAL "$(VCInstallDir)bin" AND DEFINED CCBIN)
set(CCBIN -ccbin "${CCBIN}")
else()
@@ -126,7 +127,7 @@ endif()
# and other return variables are present after executing the process.
macro(cuda_execute_process status command)
set(_command ${command})
- if(NOT _command STREQUAL "COMMAND")
+ if(NOT "x${_command}" STREQUAL "xCOMMAND")
message(FATAL_ERROR "Malformed call to cuda_execute_process. Missing COMMAND as second argument. (command = ${command})")
endif()
if(verbose)
@@ -238,6 +239,7 @@ cuda_execute_process(
"Generating ${generated_file}"
COMMAND "${CUDA_NVCC_EXECUTABLE}"
"${source_file}"
+ ${cuda_language_flag}
${format_flag} -o "${generated_file}"
${CCBIN}
${nvcc_flags}
diff --git a/Modules/FindCURL.cmake b/Modules/FindCURL.cmake
index 0fb8f45d4..209fd877d 100644
--- a/Modules/FindCURL.cmake
+++ b/Modules/FindCURL.cmake
@@ -1,10 +1,17 @@
-# - Find curl
+#.rst:
+# FindCURL
+# --------
+#
+# Find curl
+#
# Find the native CURL headers and libraries.
#
-# CURL_INCLUDE_DIRS - where to find curl/curl.h, etc.
-# CURL_LIBRARIES - List of libraries when using curl.
-# CURL_FOUND - True if curl found.
-# CURL_VERSION_STRING - the version of curl found (since CMake 2.8.8)
+# ::
+#
+# CURL_INCLUDE_DIRS - where to find curl/curl.h, etc.
+# CURL_LIBRARIES - List of libraries when using curl.
+# CURL_FOUND - True if curl found.
+# CURL_VERSION_STRING - the version of curl found (since CMake 2.8.8)
#=============================================================================
# Copyright 2006-2009 Kitware, Inc.
diff --git a/Modules/FindCVS.cmake b/Modules/FindCVS.cmake
index 07079bb5a..6f545dfd5 100644
--- a/Modules/FindCVS.cmake
+++ b/Modules/FindCVS.cmake
@@ -1,11 +1,24 @@
+#.rst:
+# FindCVS
+# -------
+#
+#
+#
# The module defines the following variables:
-# CVS_EXECUTABLE - path to cvs command line client
-# CVS_FOUND - true if the command line client was found
+#
+# ::
+#
+# CVS_EXECUTABLE - path to cvs command line client
+# CVS_FOUND - true if the command line client was found
+#
# Example usage:
-# find_package(CVS)
-# if(CVS_FOUND)
-# message("CVS found: ${CVS_EXECUTABLE}")
-# endif()
+#
+# ::
+#
+# find_package(CVS)
+# if(CVS_FOUND)
+# message("CVS found: ${CVS_EXECUTABLE}")
+# endif()
#=============================================================================
# Copyright 2008-2009 Kitware, Inc.
diff --git a/Modules/FindCoin3D.cmake b/Modules/FindCoin3D.cmake
index bbda87b3a..f90860c81 100644
--- a/Modules/FindCoin3D.cmake
+++ b/Modules/FindCoin3D.cmake
@@ -1,13 +1,19 @@
-# - Find Coin3D (Open Inventor)
-# Coin3D is an implementation of the Open Inventor API.
-# It provides data structures and algorithms for 3D visualization
-# http://www.coin3d.org/
+#.rst:
+# FindCoin3D
+# ----------
+#
+# Find Coin3D (Open Inventor)
+#
+# Coin3D is an implementation of the Open Inventor API. It provides
+# data structures and algorithms for 3D visualization.
#
# This module defines the following variables
-# COIN3D_FOUND - system has Coin3D - Open Inventor
-# COIN3D_INCLUDE_DIRS - where the Inventor include directory can be found
-# COIN3D_LIBRARIES - Link to this to use Coin3D
#
+# ::
+#
+# COIN3D_FOUND - system has Coin3D - Open Inventor
+# COIN3D_INCLUDE_DIRS - where the Inventor include directory can be found
+# COIN3D_LIBRARIES - Link to this to use Coin3D
#=============================================================================
# Copyright 2008-2009 Kitware, Inc.
diff --git a/Modules/FindCups.cmake b/Modules/FindCups.cmake
index 53ab031cf..51eb7c58e 100644
--- a/Modules/FindCups.cmake
+++ b/Modules/FindCups.cmake
@@ -1,12 +1,19 @@
-# - Try to find the Cups printing system
+#.rst:
+# FindCups
+# --------
+#
+# Try to find the Cups printing system
+#
# Once done this will define
#
-# CUPS_FOUND - system has Cups
-# CUPS_INCLUDE_DIR - the Cups include directory
-# CUPS_LIBRARIES - Libraries needed to use Cups
-# CUPS_VERSION_STRING - version of Cups found (since CMake 2.8.8)
-# Set CUPS_REQUIRE_IPP_DELETE_ATTRIBUTE to TRUE if you need a version which
-# features this function (i.e. at least 1.1.19)
+# ::
+#
+# CUPS_FOUND - system has Cups
+# CUPS_INCLUDE_DIR - the Cups include directory
+# CUPS_LIBRARIES - Libraries needed to use Cups
+# CUPS_VERSION_STRING - version of Cups found (since CMake 2.8.8)
+# Set CUPS_REQUIRE_IPP_DELETE_ATTRIBUTE to TRUE if you need a version which
+# features this function (i.e. at least 1.1.19)
#=============================================================================
# Copyright 2006-2009 Kitware, Inc.
@@ -29,9 +36,13 @@ find_library(CUPS_LIBRARIES NAMES cups )
if (CUPS_INCLUDE_DIR AND CUPS_LIBRARIES AND CUPS_REQUIRE_IPP_DELETE_ATTRIBUTE)
include(${CMAKE_CURRENT_LIST_DIR}/CheckLibraryExists.cmake)
+ include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake)
+ cmake_push_check_state()
+ set(CMAKE_REQUIRED_QUIET ${Cups_FIND_QUIETLY})
# ippDeleteAttribute is new in cups-1.1.19 (and used by kdeprint)
CHECK_LIBRARY_EXISTS(cups ippDeleteAttribute "" CUPS_HAS_IPP_DELETE_ATTRIBUTE)
+ cmake_pop_check_state()
endif ()
if (CUPS_INCLUDE_DIR AND EXISTS "${CUPS_INCLUDE_DIR}/cups/cups.h")
@@ -41,9 +52,8 @@ if (CUPS_INCLUDE_DIR AND EXISTS "${CUPS_INCLUDE_DIR}/cups/cups.h")
unset(CUPS_VERSION_STRING)
foreach(VPART MAJOR MINOR PATCH)
foreach(VLINE ${cups_version_str})
- if(VLINE MATCHES "^#[\t ]*define[\t ]+CUPS_VERSION_${VPART}")
- string(REGEX REPLACE "^#[\t ]*define[\t ]+CUPS_VERSION_${VPART}[\t ]+([0-9]+)$" "\\1"
- CUPS_VERSION_PART "${VLINE}")
+ if(VLINE MATCHES "^#[\t ]*define[\t ]+CUPS_VERSION_${VPART}[\t ]+([0-9]+)$")
+ set(CUPS_VERSION_PART "${CMAKE_MATCH_1}")
if(CUPS_VERSION_STRING)
set(CUPS_VERSION_STRING "${CUPS_VERSION_STRING}.${CUPS_VERSION_PART}")
else()
diff --git a/Modules/FindCurses.cmake b/Modules/FindCurses.cmake
index 09d1ba401..e236c2445 100644
--- a/Modules/FindCurses.cmake
+++ b/Modules/FindCurses.cmake
@@ -1,19 +1,44 @@
-# - Find the curses include file and library
+#.rst:
+# FindCurses
+# ----------
#
-# CURSES_FOUND - system has Curses
-# CURSES_INCLUDE_DIR - the Curses include directory
-# CURSES_LIBRARIES - The libraries needed to use Curses
-# CURSES_HAVE_CURSES_H - true if curses.h is available
-# CURSES_HAVE_NCURSES_H - true if ncurses.h is available
-# CURSES_HAVE_NCURSES_NCURSES_H - true if ncurses/ncurses.h is available
-# CURSES_HAVE_NCURSES_CURSES_H - true if ncurses/curses.h is available
-# CURSES_LIBRARY - set for backwards compatibility with 2.4 CMake
+# Find the curses or ncurses include file and library.
#
-# Set CURSES_NEED_NCURSES to TRUE before the find_package() command if NCurses
-# functionality is required.
+# Result Variables
+# ^^^^^^^^^^^^^^^^
+#
+# This module defines the following variables:
+#
+# ``CURSES_FOUND``
+# True if Curses is found.
+# ``CURSES_INCLUDE_DIRS``
+# The include directories needed to use Curses.
+# ``CURSES_LIBRARIES``
+# The libraries needed to use Curses.
+# ``CURSES_HAVE_CURSES_H``
+# True if curses.h is available.
+# ``CURSES_HAVE_NCURSES_H``
+# True if ncurses.h is available.
+# ``CURSES_HAVE_NCURSES_NCURSES_H``
+# True if ``ncurses/ncurses.h`` is available.
+# ``CURSES_HAVE_NCURSES_CURSES_H``
+# True if ``ncurses/curses.h`` is available.
+#
+# Set ``CURSES_NEED_NCURSES`` to ``TRUE`` before the
+# ``find_package(Curses)`` call if NCurses functionality is required.
+#
+# Backward Compatibility
+# ^^^^^^^^^^^^^^^^^^^^^^
+#
+# The following variable are provided for backward compatibility:
+#
+# ``CURSES_INCLUDE_DIR``
+# Path to Curses include. Use ``CURSES_INCLUDE_DIRS`` instead.
+# ``CURSES_LIBRARY``
+# Path to Curses library. Use ``CURSES_LIBRARIES`` instead.
#=============================================================================
-# Copyright 2001-2009 Kitware, Inc.
+# Copyright 2001-2014 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
@@ -25,12 +50,14 @@
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
+include(${CMAKE_CURRENT_LIST_DIR}/CheckLibraryExists.cmake)
+
find_library(CURSES_CURSES_LIBRARY NAMES curses )
find_library(CURSES_NCURSES_LIBRARY NAMES ncurses )
set(CURSES_USE_NCURSES FALSE)
-if(CURSES_NCURSES_LIBRARY AND NOT CURSES_CURSES_LIBRARY)
+if(CURSES_NCURSES_LIBRARY AND ((NOT CURSES_CURSES_LIBRARY) OR CURSES_NEED_NCURSES))
set(CURSES_USE_NCURSES TRUE)
endif()
# http://cygwin.com/ml/cygwin-announce/2010-01/msg00002.html
@@ -56,7 +83,9 @@ endif()
# prefix as the library was found, if still not found, try curses.h with the
# default search paths.
if(CURSES_CURSES_LIBRARY AND CURSES_NEED_NCURSES)
- include(${CMAKE_CURRENT_LIST_DIR}/CheckLibraryExists.cmake)
+ include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake)
+ cmake_push_check_state()
+ set(CMAKE_REQUIRED_QUIET ${Curses_FIND_QUIETLY})
CHECK_LIBRARY_EXISTS("${CURSES_CURSES_LIBRARY}"
wsyncup "" CURSES_CURSES_HAS_WSYNCUP)
@@ -67,77 +96,94 @@ if(CURSES_CURSES_LIBRARY AND CURSES_NEED_NCURSES)
set(CURSES_USE_NCURSES TRUE)
endif()
endif()
+ cmake_pop_check_state()
endif()
-
-if(NOT CURSES_USE_NCURSES)
- find_file(CURSES_HAVE_CURSES_H curses.h )
- find_path(CURSES_CURSES_H_PATH curses.h )
- get_filename_component(_cursesLibDir "${CURSES_CURSES_LIBRARY}" PATH)
+if(CURSES_USE_NCURSES)
+ get_filename_component(_cursesLibDir "${CURSES_NCURSES_LIBRARY}" PATH)
get_filename_component(_cursesParentDir "${_cursesLibDir}" PATH)
- # for compatibility with older FindCurses.cmake this has to be in the cache
- # FORCE must not be used since this would break builds which preload a cache wqith these variables set
- set(CURSES_INCLUDE_PATH "${CURSES_CURSES_H_PATH}"
- CACHE FILEPATH "The curses include path")
- set(CURSES_LIBRARY "${CURSES_CURSES_LIBRARY}"
- CACHE FILEPATH "The curses library")
+ # Use CURSES_NCURSES_INCLUDE_PATH if set, for compatibility.
+ if(CURSES_NCURSES_INCLUDE_PATH)
+ find_path(CURSES_INCLUDE_PATH
+ NAMES ncurses/ncurses.h ncurses/curses.h ncurses.h curses.h
+ PATHS ${CURSES_NCURSES_INCLUDE_PATH}
+ NO_DEFAULT_PATH
+ )
+ endif()
+
+ find_path(CURSES_INCLUDE_PATH
+ NAMES ncurses/ncurses.h ncurses/curses.h ncurses.h curses.h
+ HINTS "${_cursesParentDir}/include"
+ )
+
+ # Previous versions of FindCurses provided these values.
+ if(NOT DEFINED CURSES_LIBRARY)
+ set(CURSES_LIBRARY "${CURSES_NCURSES_LIBRARY}")
+ endif()
+
+ CHECK_LIBRARY_EXISTS("${CURSES_NCURSES_LIBRARY}"
+ cbreak "" CURSES_NCURSES_HAS_CBREAK)
+ if(NOT CURSES_NCURSES_HAS_CBREAK)
+ find_library(CURSES_EXTRA_LIBRARY tinfo HINTS "${_cursesLibDir}")
+ find_library(CURSES_EXTRA_LIBRARY tinfo )
+ endif()
else()
-# we need to find ncurses
- get_filename_component(_cursesLibDir "${CURSES_NCURSES_LIBRARY}" PATH)
+ get_filename_component(_cursesLibDir "${CURSES_CURSES_LIBRARY}" PATH)
get_filename_component(_cursesParentDir "${_cursesLibDir}" PATH)
- find_file(CURSES_HAVE_NCURSES_H ncurses.h)
- find_file(CURSES_HAVE_NCURSES_NCURSES_H ncurses/ncurses.h)
- find_file(CURSES_HAVE_NCURSES_CURSES_H ncurses/curses.h)
- find_file(CURSES_HAVE_CURSES_H curses.h
- HINTS "${_cursesParentDir}/include")
-
- find_path(CURSES_NCURSES_INCLUDE_PATH ncurses.h ncurses/ncurses.h
- ncurses/curses.h)
- find_path(CURSES_NCURSES_INCLUDE_PATH curses.h
- HINTS "${_cursesParentDir}/include")
-
- # for compatibility with older FindCurses.cmake this has to be in the cache
- # FORCE must not be used since this would break builds which preload
- # however if the value of the variable has NOTFOUND in it, then
- # it is OK to force, and we need to force in order to have it work.
- # a cache wqith these variables set
- # only put ncurses include and library into
- # variables if they are found
- if(NOT CURSES_NCURSES_INCLUDE_PATH AND CURSES_HAVE_NCURSES_NCURSES_H)
- get_filename_component(CURSES_NCURSES_INCLUDE_PATH
- "${CURSES_HAVE_NCURSES_NCURSES_H}" PATH)
+ find_path(CURSES_INCLUDE_PATH
+ NAMES curses.h
+ HINTS "${_cursesParentDir}/include"
+ )
+
+ # Previous versions of FindCurses provided these values.
+ if(NOT DEFINED CURSES_CURSES_H_PATH)
+ set(CURSES_CURSES_H_PATH "${CURSES_INCLUDE_PATH}")
endif()
- if(CURSES_NCURSES_INCLUDE_PATH AND CURSES_NCURSES_LIBRARY)
- set( FORCE_IT )
- if(CURSES_INCLUDE_PATH MATCHES NOTFOUND)
- set(FORCE_IT FORCE)
- endif()
- set(CURSES_INCLUDE_PATH "${CURSES_NCURSES_INCLUDE_PATH}"
- CACHE FILEPATH "The curses include path" ${FORCE_IT})
- set( FORCE_IT)
- if(CURSES_LIBRARY MATCHES NOTFOUND)
- set(FORCE_IT FORCE)
- endif()
- set(CURSES_LIBRARY "${CURSES_NCURSES_LIBRARY}"
- CACHE FILEPATH "The curses library" ${FORCE_IT})
+ if(NOT DEFINED CURSES_LIBRARY)
+ set(CURSES_LIBRARY "${CURSES_CURSES_LIBRARY}")
endif()
-
endif()
-find_library(CURSES_EXTRA_LIBRARY cur_colr HINTS "${_cursesLibDir}")
-find_library(CURSES_EXTRA_LIBRARY cur_colr )
+# Report whether each possible header name exists in the include directory.
+if(NOT DEFINED CURSES_HAVE_NCURSES_NCURSES_H)
+ if(EXISTS "${CURSES_INCLUDE_PATH}/ncurses/ncurses.h")
+ set(CURSES_HAVE_NCURSES_NCURSES_H "${CURSES_INCLUDE_PATH}/ncurses/ncurses.h")
+ else()
+ set(CURSES_HAVE_NCURSES_NCURSES_H "CURSES_HAVE_NCURSES_NCURSES_H-NOTFOUND")
+ endif()
+endif()
+if(NOT DEFINED CURSES_HAVE_NCURSES_CURSES_H)
+ if(EXISTS "${CURSES_INCLUDE_PATH}/ncurses/curses.h")
+ set(CURSES_HAVE_NCURSES_CURSES_H "${CURSES_INCLUDE_PATH}/ncurses/curses.h")
+ else()
+ set(CURSES_HAVE_NCURSES_CURSES_H "CURSES_HAVE_NCURSES_CURSES_H-NOTFOUND")
+ endif()
+endif()
+if(NOT DEFINED CURSES_HAVE_NCURSES_H)
+ if(EXISTS "${CURSES_INCLUDE_PATH}/ncurses.h")
+ set(CURSES_HAVE_NCURSES_H "${CURSES_INCLUDE_PATH}/ncurses.h")
+ else()
+ set(CURSES_HAVE_NCURSES_H "CURSES_HAVE_NCURSES_H-NOTFOUND")
+ endif()
+endif()
+if(NOT DEFINED CURSES_HAVE_CURSES_H)
+ if(EXISTS "${CURSES_INCLUDE_PATH}/curses.h")
+ set(CURSES_HAVE_CURSES_H "${CURSES_INCLUDE_PATH}/curses.h")
+ else()
+ set(CURSES_HAVE_CURSES_H "CURSES_HAVE_CURSES_H-NOTFOUND")
+ endif()
+endif()
find_library(CURSES_FORM_LIBRARY form HINTS "${_cursesLibDir}")
find_library(CURSES_FORM_LIBRARY form )
-# for compatibility with older FindCurses.cmake this has to be in the cache
-# FORCE must not be used since this would break builds which preload a cache
-# qith these variables set
-set(FORM_LIBRARY "${CURSES_FORM_LIBRARY}"
- CACHE FILEPATH "The curses form library")
+# Previous versions of FindCurses provided these values.
+if(NOT DEFINED FORM_LIBRARY)
+ set(FORM_LIBRARY "${CURSES_FORM_LIBRARY}")
+endif()
# Need to provide the *_LIBRARIES
set(CURSES_LIBRARIES ${CURSES_LIBRARY})
@@ -150,8 +196,9 @@ if(CURSES_FORM_LIBRARY)
set(CURSES_LIBRARIES ${CURSES_LIBRARIES} ${CURSES_FORM_LIBRARY})
endif()
-# Proper name is *_INCLUDE_DIR
-set(CURSES_INCLUDE_DIR ${CURSES_INCLUDE_PATH})
+# Provide the *_INCLUDE_DIRS result.
+set(CURSES_INCLUDE_DIRS ${CURSES_INCLUDE_PATH})
+set(CURSES_INCLUDE_DIR ${CURSES_INCLUDE_PATH}) # compatibility
# handle the QUIETLY and REQUIRED arguments and set CURSES_FOUND to TRUE if
# all listed variables are TRUE
@@ -161,16 +208,7 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(Curses DEFAULT_MSG
mark_as_advanced(
CURSES_INCLUDE_PATH
- CURSES_LIBRARY
- CURSES_CURSES_INCLUDE_PATH
CURSES_CURSES_LIBRARY
- CURSES_NCURSES_INCLUDE_PATH
CURSES_NCURSES_LIBRARY
CURSES_EXTRA_LIBRARY
- FORM_LIBRARY
- CURSES_LIBRARIES
- CURSES_INCLUDE_DIR
- CURSES_CURSES_HAS_WSYNCUP
- CURSES_NCURSES_HAS_WSYNCUP
)
-
diff --git a/Modules/FindCxxTest.cmake b/Modules/FindCxxTest.cmake
index 48de64afd..bc0dfbcca 100644
--- a/Modules/FindCxxTest.cmake
+++ b/Modules/FindCxxTest.cmake
@@ -1,88 +1,138 @@
-# - Find CxxTest
-# Find the CxxTest suite and declare a helper macro for creating unit tests
-# and integrating them with CTest.
-# For more details on CxxTest see http://cxxtest.tigris.org
+#.rst:
+# FindCxxTest
+# -----------
+#
+# Find CxxTest
+#
+# Find the CxxTest suite and declare a helper macro for creating unit
+# tests and integrating them with CTest. For more details on CxxTest
+# see http://cxxtest.tigris.org
#
# INPUT Variables
#
-# CXXTEST_USE_PYTHON [deprecated since 1.3]
-# Only used in the case both Python & Perl
-# are detected on the system to control
-# which CxxTest code generator is used.
-# Valid only for CxxTest version 3.
+# ::
+#
+# CXXTEST_USE_PYTHON [deprecated since 1.3]
+# Only used in the case both Python & Perl
+# are detected on the system to control
+# which CxxTest code generator is used.
+# Valid only for CxxTest version 3.
+#
+#
+#
+# ::
+#
+# NOTE: In older versions of this Find Module,
+# this variable controlled if the Python test
+# generator was used instead of the Perl one,
+# regardless of which scripting language the
+# user had installed.
+#
+#
+#
+# ::
+#
+# CXXTEST_TESTGEN_ARGS (since CMake 2.8.3)
+# Specify a list of options to pass to the CxxTest code
+# generator. If not defined, --error-printer is
+# passed.
#
-# NOTE: In older versions of this Find Module,
-# this variable controlled if the Python test
-# generator was used instead of the Perl one,
-# regardless of which scripting language the
-# user had installed.
#
-# CXXTEST_TESTGEN_ARGS (since CMake 2.8.3)
-# Specify a list of options to pass to the CxxTest code
-# generator. If not defined, --error-printer is
-# passed.
#
# OUTPUT Variables
#
-# CXXTEST_FOUND
-# True if the CxxTest framework was found
-# CXXTEST_INCLUDE_DIRS
-# Where to find the CxxTest include directory
-# CXXTEST_PERL_TESTGEN_EXECUTABLE
-# The perl-based test generator
-# CXXTEST_PYTHON_TESTGEN_EXECUTABLE
-# The python-based test generator
-# CXXTEST_TESTGEN_EXECUTABLE (since CMake 2.8.3)
-# The test generator that is actually used (chosen using user preferences
-# and interpreters found in the system)
-# CXXTEST_TESTGEN_INTERPRETER (since CMake 2.8.3)
-# The full path to the Perl or Python executable on the system
+# ::
+#
+# CXXTEST_FOUND
+# True if the CxxTest framework was found
+# CXXTEST_INCLUDE_DIRS
+# Where to find the CxxTest include directory
+# CXXTEST_PERL_TESTGEN_EXECUTABLE
+# The perl-based test generator
+# CXXTEST_PYTHON_TESTGEN_EXECUTABLE
+# The python-based test generator
+# CXXTEST_TESTGEN_EXECUTABLE (since CMake 2.8.3)
+# The test generator that is actually used (chosen using user preferences
+# and interpreters found in the system)
+# CXXTEST_TESTGEN_INTERPRETER (since CMake 2.8.3)
+# The full path to the Perl or Python executable on the system
+#
+#
#
# MACROS for optional use by CMake users:
#
-# CXXTEST_ADD_TEST(<test_name> <gen_source_file> <input_files_to_testgen...>)
-# Creates a CxxTest runner and adds it to the CTest testing suite
-# Parameters:
-# test_name The name of the test
-# gen_source_file The generated source filename to be
-# generated by CxxTest
-# input_files_to_testgen The list of header files containing the
-# CxxTest::TestSuite's to be included in
-# this runner
-#
-# #==============
-# Example Usage:
-#
-# find_package(CxxTest)
-# if(CXXTEST_FOUND)
-# include_directories(${CXXTEST_INCLUDE_DIR})
-# enable_testing()
-#
-# CXXTEST_ADD_TEST(unittest_foo foo_test.cc
-# ${CMAKE_CURRENT_SOURCE_DIR}/foo_test.h)
-# target_link_libraries(unittest_foo foo) # as needed
-# endif()
-#
-# This will (if CxxTest is found):
-# 1. Invoke the testgen executable to autogenerate foo_test.cc in the
-# binary tree from "foo_test.h" in the current source directory.
-# 2. Create an executable and test called unittest_foo.
-#
-# #=============
-# Example foo_test.h:
-#
-# #include <cxxtest/TestSuite.h>
-#
-# class MyTestSuite : public CxxTest::TestSuite
-# {
-# public:
-# void testAddition( void )
-# {
-# TS_ASSERT( 1 + 1 > 1 );
-# TS_ASSERT_EQUALS( 1 + 1, 2 );
-# }
-# };
+# ::
+#
+# CXXTEST_ADD_TEST(<test_name> <gen_source_file> <input_files_to_testgen...>)
+# Creates a CxxTest runner and adds it to the CTest testing suite
+# Parameters:
+# test_name The name of the test
+# gen_source_file The generated source filename to be
+# generated by CxxTest
+# input_files_to_testgen The list of header files containing the
+# CxxTest::TestSuite's to be included in
+# this runner
+#
+#
+#
+# ::
+#
+# #==============
+# Example Usage:
+#
+#
+#
+# ::
+#
+# find_package(CxxTest)
+# if(CXXTEST_FOUND)
+# include_directories(${CXXTEST_INCLUDE_DIR})
+# enable_testing()
+#
+#
+#
+# ::
+#
+# CXXTEST_ADD_TEST(unittest_foo foo_test.cc
+# ${CMAKE_CURRENT_SOURCE_DIR}/foo_test.h)
+# target_link_libraries(unittest_foo foo) # as needed
+# endif()
+#
+#
+#
+# ::
+#
+# This will (if CxxTest is found):
+# 1. Invoke the testgen executable to autogenerate foo_test.cc in the
+# binary tree from "foo_test.h" in the current source directory.
+# 2. Create an executable and test called unittest_foo.
+#
+#
+#
+# ::
+#
+# #=============
+# Example foo_test.h:
+#
+#
+#
+# ::
+#
+# #include <cxxtest/TestSuite.h>
+#
+#
+#
+# ::
#
+# class MyTestSuite : public CxxTest::TestSuite
+# {
+# public:
+# void testAddition( void )
+# {
+# TS_ASSERT( 1 + 1 > 1 );
+# TS_ASSERT_EQUALS( 1 + 1, 2 );
+# }
+# };
#=============================================================================
# Copyright 2008-2010 Kitware, Inc.
diff --git a/Modules/FindCygwin.cmake b/Modules/FindCygwin.cmake
index d7ab7cc80..5cb533b0b 100644
--- a/Modules/FindCygwin.cmake
+++ b/Modules/FindCygwin.cmake
@@ -1,5 +1,8 @@
-# - this module looks for Cygwin
+#.rst:
+# FindCygwin
+# ----------
#
+# this module looks for Cygwin
#=============================================================================
# Copyright 2001-2009 Kitware, Inc.
diff --git a/Modules/FindDCMTK.cmake b/Modules/FindDCMTK.cmake
index 361d09e8b..63d253d90 100644
--- a/Modules/FindDCMTK.cmake
+++ b/Modules/FindDCMTK.cmake
@@ -1,15 +1,79 @@
-# - find DCMTK libraries and applications
+#.rst:
+# FindDCMTK
+# ---------
#
-
-# DCMTK_INCLUDE_DIRS - Directories to include to use DCMTK
+# Find DCMTK libraries and applications
+#
+# The module defines the following variables::
+#
+# DCMTK_INCLUDE_DIRS - Directories to include to use DCMTK
# DCMTK_LIBRARIES - Files to link against to use DCMTK
# DCMTK_FOUND - If false, don't try to use DCMTK
# DCMTK_DIR - (optional) Source directory for DCMTK
#
-# DCMTK_DIR can be used to make it simpler to find the various include
-# directories and compiled libraries if you've just compiled it in the
-# source tree. Just set it to the root of the tree where you extracted
-# the source (default to /usr/include/dcmtk/)
+# Compatibility
+# ^^^^^^^^^^^^^
+#
+# This module is able to find a version of DCMTK that does or does not export
+# a *DCMTKConfig.cmake* file. It applies a two step process:
+#
+# * Step 1: Attempt to find DCMTK version providing a *DCMTKConfig.cmake* file.
+# * Step 2: If step 1 failed, rely on *FindDCMTK.cmake* to set `DCMTK_*` variables details below.
+#
+#
+# `Recent DCMTK
+# <http://git.dcmtk.org/web?p=dcmtk.git;a=commit;h=662ae187c493c6b9a73dd5e3875372cebd0c11fe>`_
+# provides a *DCMTKConfig.cmake* :manual:`package configuration file
+# <cmake-packages(7)>`. To exclusively use the package configuration file
+# (recommended when possible), pass the `NO_MODULE` option to
+# :command:`find_package`. For example, `find_package(DCMTK NO_MODULE)`.
+# This requires official DCMTK snapshot *3.6.1_20140617* or newer.
+#
+#
+# Until all clients update to the more recent DCMTK, build systems will need
+# to support different versions of DCMTK.
+#
+# On any given system, the following combinations of DCMTK versions could be
+# considered:
+#
+# +--------+---------------------+-----------------------+-------------------+
+# | | SYSTEM DCMTK | LOCAL DCMTK | Supported ? |
+# +--------+---------------------+-----------------------+-------------------+
+# | Case A | NA | [ ] DCMTKConfig | YES |
+# +--------+---------------------+-----------------------+-------------------+
+# | Case B | NA | [X] DCMTKConfig | YES |
+# +--------+---------------------+-----------------------+-------------------+
+# | Case C | [ ] DCMTKConfig | NA | YES |
+# +--------+---------------------+-----------------------+-------------------+
+# | Case D | [X] DCMTKConfig | NA | YES |
+# +--------+---------------------+-----------------------+-------------------+
+# | Case E | [ ] DCMTKConfig | [ ] DCMTKConfig | YES (*) |
+# +--------+---------------------+-----------------------+-------------------+
+# | Case F | [X] DCMTKConfig | [ ] DCMTKConfig | NO |
+# +--------+---------------------+-----------------------+-------------------+
+# | Case G | [ ] DCMTKConfig | [X] DCMTKConfig | YES |
+# +--------+---------------------+-----------------------+-------------------+
+# | Case H | [X] DCMTKConfig | [X] DCMTKConfig | YES |
+# +--------+---------------------+-----------------------+-------------------+
+#
+# (*) See Troubleshooting section.
+#
+# Legend:
+#
+# NA ...............: Means that no System or Local DCMTK is available
+#
+# [ ] DCMTKConfig ..: Means that the version of DCMTK does NOT export a DCMTKConfig.cmake file.
+#
+# [X] DCMTKConfig ..: Means that the version of DCMTK exports a DCMTKConfig.cmake file.
+#
+#
+# Troubleshooting
+# ^^^^^^^^^^^^^^^
+#
+# What to do if my project finds a different version of DCMTK?
+#
+# Remove DCMTK entry from the CMake cache per :command:`find_package`
+# documentation.
#=============================================================================
# Copyright 2004-2009 Kitware, Inc.
@@ -32,50 +96,142 @@
# Modified for EasyViz by Thomas Sondergaard.
#
-if(NOT DCMTK_FOUND AND NOT DCMTK_DIR)
- set(DCMTK_DIR
- "/usr/include/dcmtk/"
- CACHE
- PATH
- "Root of DCMTK source tree (optional).")
- mark_as_advanced(DCMTK_DIR)
+set(_dcmtk_dir_description "The directory of DCMTK build or install tree.")
+
+# Ensure that DCMTK_DIR is set to a reasonable default value
+# so that DCMTK libraries can be found on a standard Unix distribution.
+# It also overwrite the value of DCMTK_DIR after this one has been
+# set by a successful discovery of DCMTK by the unpatched FindDCMTK.cmake module
+# distributed with CMake (as of 0167cea)
+if(NOT DCMTK_DIR OR DCMTK_DIR STREQUAL "/usr/include/dcmtk")
+ set(DCMTK_DIR "/usr" CACHE PATH ${_dcmtk_dir_description} FORCE)
+endif()
+
+set(_SAVED_DCMTK_DIR ${DCMTK_DIR})
+
+#
+# Step1: Attempt to find a version of DCMTK providing a DCMTKConfig.cmake file.
+#
+if(NOT DCMTK_FIND_QUIETLY)
+ message(STATUS "Trying to find DCMTK expecting DCMTKConfig.cmake")
endif()
+find_package(DCMTK QUIET NO_MODULE)
+if(DCMTK_FOUND
+ AND NOT "x" STREQUAL "x${DCMTK_LIBRARIES}"
+ AND NOT "x" STREQUAL "x${DCMTK_INCLUDE_DIRS}")
+ if(NOT DCMTK_FIND_QUIETLY)
+ message(STATUS "Trying to find DCMTK expecting DCMTKConfig.cmake - ok")
+ endif()
+ return()
+else()
+ if(NOT DCMTK_FIND_QUIETLY)
+ message(STATUS "Trying to find DCMTK expecting DCMTKConfig.cmake - failed")
+ endif()
+endif()
+
+if(NOT DCMTK_FIND_QUIETLY)
+ message(STATUS "Trying to find DCMTK relying on FindDCMTK.cmake")
+endif()
+# Restore the value reset by the previous call to 'find_package(DCMTK QUIET NO_MODULE)'
+set(DCMTK_DIR ${_SAVED_DCMTK_DIR} CACHE PATH ${_dcmtk_dir_description} FORCE)
+
+
+#
+# Step2: Attempt to find a version of DCMTK that does NOT provide a DCMTKConfig.cmake file.
+#
+
+# prefer DCMTK_DIR over default system paths like /usr/lib
+if(DCMTK_DIR)
+ set(CMAKE_PREFIX_PATH ${DCMTK_DIR}/lib ${CMAKE_PREFIX_PATH}) # this is given to FIND_LIBRARY or FIND_PATH
+endif()
+
+# Find all libraries, store debug and release separately
foreach(lib
- dcmdata
- dcmimage
- dcmimgle
- dcmjpeg
- dcmnet
dcmpstat
- dcmqrdb
- dcmsign
dcmsr
+ dcmsign
dcmtls
+ dcmqrdb
+ dcmnet
+ dcmjpeg
+ dcmimage
+ dcmimgle
+ dcmdata
+ oflog
+ ofstd
ijg12
ijg16
ijg8
- ofstd)
+ )
- find_library(DCMTK_${lib}_LIBRARY
+ # Find Release libraries
+ find_library(DCMTK_${lib}_LIBRARY_RELEASE
${lib}
PATHS
${DCMTK_DIR}/${lib}/libsrc
${DCMTK_DIR}/${lib}/libsrc/Release
- ${DCMTK_DIR}/${lib}/libsrc/Debug
${DCMTK_DIR}/${lib}/Release
+ ${DCMTK_DIR}/lib
+ ${DCMTK_DIR}/lib/Release
+ ${DCMTK_DIR}/dcmjpeg/lib${lib}/Release
+ NO_DEFAULT_PATH
+ )
+
+ # Find Debug libraries
+ find_library(DCMTK_${lib}_LIBRARY_DEBUG
+ ${lib}${DCMTK_CMAKE_DEBUG_POSTFIX}
+ PATHS
+ ${DCMTK_DIR}/${lib}/libsrc
+ ${DCMTK_DIR}/${lib}/libsrc/Debug
${DCMTK_DIR}/${lib}/Debug
- ${DCMTK_DIR}/lib)
+ ${DCMTK_DIR}/lib
+ ${DCMTK_DIR}/lib/Debug
+ ${DCMTK_DIR}/dcmjpeg/lib${lib}/Debug
+ NO_DEFAULT_PATH
+ )
- mark_as_advanced(DCMTK_${lib}_LIBRARY)
+ mark_as_advanced(DCMTK_${lib}_LIBRARY_RELEASE)
+ mark_as_advanced(DCMTK_${lib}_LIBRARY_DEBUG)
+
+ # Add libraries to variable according to build type
+ if(DCMTK_${lib}_LIBRARY_RELEASE)
+ list(APPEND DCMTK_LIBRARIES optimized ${DCMTK_${lib}_LIBRARY_RELEASE})
+ endif()
- if(DCMTK_${lib}_LIBRARY)
- list(APPEND DCMTK_LIBRARIES ${DCMTK_${lib}_LIBRARY})
+ if(DCMTK_${lib}_LIBRARY_DEBUG)
+ list(APPEND DCMTK_LIBRARIES debug ${DCMTK_${lib}_LIBRARY_DEBUG})
endif()
endforeach()
+set(CMAKE_THREAD_LIBS_INIT)
+if(DCMTK_oflog_LIBRARY_RELEASE OR DCMTK_oflog_LIBRARY_DEBUG)
+ # Hack - Not having a DCMTKConfig.cmake file to read the settings from, we will attempt to
+ # find the library in all cases.
+ # Ideally, pthread library should be discovered only if DCMTK_WITH_THREADS is enabled.
+ set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
+ find_package(Threads)
+endif()
+
+if(CMAKE_THREAD_LIBS_INIT)
+ list(APPEND DCMTK_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
+endif()
+
+#
+# SPECIFIC CASE FOR DCMTK BUILD DIR as DCMTK_DIR
+# (as opposed to a DCMTK install dir)
+# Have to find the source directory.
+if(EXISTS ${DCMTK_DIR}/CMakeCache.txt)
+ load_cache(${DCMTK_DIR} READ_WITH_PREFIX "EXT"
+ DCMTK_SOURCE_DIR)
+ if(NOT EXISTS ${EXTDCMTK_SOURCE_DIR})
+ message(FATAL_ERROR
+ "DCMTK build directory references
+nonexistant DCMTK source directory ${EXTDCMTK_SOURCE_DIR}")
+ endif()
+endif()
set(DCMTK_config_TEST_HEADER osconfig.h)
set(DCMTK_dcmdata_TEST_HEADER dctypes.h)
@@ -89,6 +245,10 @@ set(DCMTK_dcmsign_TEST_HEADER sicert.h)
set(DCMTK_dcmsr_TEST_HEADER dsrtree.h)
set(DCMTK_dcmtls_TEST_HEADER tlslayer.h)
set(DCMTK_ofstd_TEST_HEADER ofstdinc.h)
+set(DCMTK_oflog_TEST_HEADER oflog.h)
+set(DCMTK_dcmjpls_TEST_HEADER djlsutil.h)
+
+set(DCMTK_INCLUDE_DIR_NAMES)
foreach(dir
config
@@ -96,31 +256,47 @@ foreach(dir
dcmimage
dcmimgle
dcmjpeg
+ dcmjpls
dcmnet
dcmpstat
dcmqrdb
dcmsign
dcmsr
dcmtls
- ofstd)
+ ofstd
+ oflog)
+ if(EXTDCMTK_SOURCE_DIR)
+ set(SOURCE_DIR_PATH
+ ${EXTDCMTK_SOURCE_DIR}/${dir}/include/dcmtk/${dir})
+ endif()
find_path(DCMTK_${dir}_INCLUDE_DIR
${DCMTK_${dir}_TEST_HEADER}
PATHS
${DCMTK_DIR}/${dir}/include
${DCMTK_DIR}/${dir}
- ${DCMTK_DIR}/include/${dir}
${DCMTK_DIR}/include/dcmtk/${dir}
${DCMTK_DIR}/${dir}/include/dcmtk/${dir}
+ ${DCMTK_DIR}/include/${dir}
+ ${SOURCE_DIR_PATH}
)
mark_as_advanced(DCMTK_${dir}_INCLUDE_DIR)
+ list(APPEND DCMTK_INCLUDE_DIR_NAMES DCMTK_${dir}_INCLUDE_DIR)
if(DCMTK_${dir}_INCLUDE_DIR)
+ # add the 'include' path so eg
+ #include "dcmtk/dcmimgle/dcmimage.h"
+ # works
+ get_filename_component(_include ${DCMTK_${dir}_INCLUDE_DIR} PATH)
+ get_filename_component(_include ${_include} PATH)
list(APPEND
DCMTK_INCLUDE_DIRS
- ${DCMTK_${dir}_INCLUDE_DIR})
+ ${DCMTK_${dir}_INCLUDE_DIR}
+ ${_include})
endif()
endforeach()
+list(APPEND DCMTK_INCLUDE_DIRS ${DCMTK_DIR}/include)
+
if(WIN32)
list(APPEND DCMTK_LIBRARIES netapi32 wsock32)
endif()
@@ -134,21 +310,31 @@ if(DCMTK_ofstd_INCLUDE_DIR)
mark_as_advanced(DCMTK_dcmtk_INCLUDE_DIR)
endif()
-include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
-find_package_handle_standard_args(DCMTK DEFAULT_MSG
- DCMTK_config_INCLUDE_DIR
- DCMTK_ofstd_INCLUDE_DIR
- DCMTK_ofstd_LIBRARY
- DCMTK_dcmdata_INCLUDE_DIR
- DCMTK_dcmdata_LIBRARY
- DCMTK_dcmimgle_INCLUDE_DIR
- DCMTK_dcmimgle_LIBRARY)
-
# Compatibility: This variable is deprecated
set(DCMTK_INCLUDE_DIR ${DCMTK_INCLUDE_DIRS})
-foreach(executable dcmdump dcmdjpeg dcmdrle)
- string(TOUPPER ${executable} EXECUTABLE)
- find_program(DCMTK_${EXECUTABLE}_EXECUTABLE ${executable} ${DCMTK_DIR}/bin)
- mark_as_advanced(DCMTK_${EXECUTABLE}_EXECUTABLE)
-endforeach()
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(DCMTK
+ REQUIRED_VARS ${DCMTK_INCLUDE_DIR_NAMES} DCMTK_LIBRARIES
+ FAIL_MESSAGE "Please set DCMTK_DIR and re-run configure")
+
+# Workaround bug in packaging of DCMTK 3.6.0 on Debian.
+# See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=637687
+if(DCMTK_FOUND AND UNIX AND NOT APPLE)
+ include(CheckCXXSourceCompiles)
+ set(CMAKE_REQUIRED_FLAGS )
+ set(CMAKE_REQUIRED_DEFINITIONS )
+ set(CMAKE_REQUIRED_INCLUDES ${DCMTK_INCLUDE_DIRS})
+ set(CMAKE_REQUIRED_LIBRARIES ${DCMTK_LIBRARIES})
+ set(CMAKE_REQUIRED_QUIET ${DCMTK_FIND_QUIETLY})
+ check_cxx_source_compiles("#include <dcmtk/config/osconfig.h>\n#include <dcmtk/ofstd/ofstream.h>\nint main(int,char*[]){return 0;}"
+ DCMTK_HAVE_CONFIG_H_OPTIONAL
+ )
+ if(NOT DCMTK_HAVE_CONFIG_H_OPTIONAL)
+ set(DCMTK_DEFINITIONS "HAVE_CONFIG_H")
+ endif()
+endif()
+
+if(NOT DCMTK_FIND_QUIETLY)
+ message(STATUS "Trying to find DCMTK relying on FindDCMTK.cmake - ok")
+endif()
diff --git a/Modules/FindDart.cmake b/Modules/FindDart.cmake
index a2b2926a7..ea01fc223 100644
--- a/Modules/FindDart.cmake
+++ b/Modules/FindDart.cmake
@@ -1,7 +1,11 @@
-# - Find DART
-# This module looks for the dart testing software and sets DART_ROOT
-# to point to where it found it.
+#.rst:
+# FindDart
+# --------
#
+# Find DART
+#
+# This module looks for the dart testing software and sets DART_ROOT to
+# point to where it found it.
#=============================================================================
# Copyright 2001-2009 Kitware, Inc.
diff --git a/Modules/FindDevIL.cmake b/Modules/FindDevIL.cmake
index dacc60422..865d061c5 100644
--- a/Modules/FindDevIL.cmake
+++ b/Modules/FindDevIL.cmake
@@ -1,23 +1,32 @@
+#.rst:
+# FindDevIL
+# ---------
+#
+#
+#
# This module locates the developer's image library.
# http://openil.sourceforge.net/
#
# This module sets:
-# IL_LIBRARIES - the name of the IL library. These include the full path to
-# the core DevIL library. This one has to be linked into the
-# application.
-# ILU_LIBRARIES - the name of the ILU library. Again, the full path. This
-# library is for filters and effects, not actual loading. It
-# doesn't have to be linked if the functionality it provides
-# is not used.
-# ILUT_LIBRARIES - the name of the ILUT library. Full path. This part of the
-# library interfaces with OpenGL. It is not strictly needed
-# in applications.
-# IL_INCLUDE_DIR - where to find the il.h, ilu.h and ilut.h files.
-# IL_FOUND - this is set to TRUE if all the above variables were set.
-# This will be set to false if ILU or ILUT are not found,
-# even if they are not needed. In most systems, if one
-# library is found all the others are as well. That's the
-# way the DevIL developers release it.
+#
+# ::
+#
+# IL_LIBRARIES - the name of the IL library. These include the full path to
+# the core DevIL library. This one has to be linked into the
+# application.
+# ILU_LIBRARIES - the name of the ILU library. Again, the full path. This
+# library is for filters and effects, not actual loading. It
+# doesn't have to be linked if the functionality it provides
+# is not used.
+# ILUT_LIBRARIES - the name of the ILUT library. Full path. This part of the
+# library interfaces with OpenGL. It is not strictly needed
+# in applications.
+# IL_INCLUDE_DIR - where to find the il.h, ilu.h and ilut.h files.
+# IL_FOUND - this is set to TRUE if all the above variables were set.
+# This will be set to false if ILU or ILUT are not found,
+# even if they are not needed. In most systems, if one
+# library is found all the others are as well. That's the
+# way the DevIL developers release it.
#=============================================================================
# Copyright 2008-2009 Kitware, Inc.
@@ -40,7 +49,7 @@ include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
find_path(IL_INCLUDE_DIR il.h
PATH_SUFFIXES include IL
- DOC "The path the the directory that contains il.h"
+ DOC "The path to the directory that contains il.h"
)
#message("IL_INCLUDE_DIR is ${IL_INCLUDE_DIR}")
diff --git a/Modules/FindDoxygen.cmake b/Modules/FindDoxygen.cmake
index d2ede6ab9..d34941aa2 100644
--- a/Modules/FindDoxygen.cmake
+++ b/Modules/FindDoxygen.cmake
@@ -1,23 +1,45 @@
-# - This module looks for Doxygen and the path to Graphviz's dot
+#.rst:
+# FindDoxygen
+# -----------
+#
+# This module looks for Doxygen and the path to Graphviz's dot
+#
# Doxygen is a documentation generation tool. Please see
# http://www.doxygen.org
#
# This module accepts the following optional variables:
#
-# DOXYGEN_SKIP_DOT = If true this module will skip trying to find Dot
-# (an optional component often used by Doxygen)
+# ::
+#
+# DOXYGEN_SKIP_DOT = If true this module will skip trying to find Dot
+# (an optional component often used by Doxygen)
+#
+#
#
# This modules defines the following variables:
#
-# DOXYGEN_EXECUTABLE = The path to the doxygen command.
-# DOXYGEN_FOUND = Was Doxygen found or not?
-# DOXYGEN_VERSION = The version reported by doxygen --version
+# ::
#
-# DOXYGEN_DOT_EXECUTABLE = The path to the dot program used by doxygen.
-# DOXYGEN_DOT_FOUND = Was Dot found or not?
-# DOXYGEN_DOT_PATH = The path to dot not including the executable
+# DOXYGEN_EXECUTABLE = The path to the doxygen command.
+# DOXYGEN_FOUND = Was Doxygen found or not?
+# DOXYGEN_VERSION = The version reported by doxygen --version
#
#
+#
+# ::
+#
+# DOXYGEN_DOT_EXECUTABLE = The path to the dot program used by doxygen.
+# DOXYGEN_DOT_FOUND = Was Dot found or not?
+#
+# For compatibility with older versions of CMake, the now-deprecated
+# variable ``DOXYGEN_DOT_PATH`` is set to the path to the directory
+# containing ``dot`` as reported in ``DOXYGEN_DOT_EXECUTABLE``.
+# The path may have forward slashes even on Windows and is not
+# suitable for direct substitution into a ``Doxyfile.in`` template.
+# If you need this value, use :command:`get_filename_component`
+# to compute it from ``DOXYGEN_DOT_EXECUTABLE`` directly, and
+# perhaps the :command:`file(TO_NATIVE_PATH)` command to prepare
+# the path for a Doxygen configuration file.
#=============================================================================
# Copyright 2001-2009 Kitware, Inc.
@@ -88,12 +110,18 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(Doxygen REQUIRED_VARS DOXYGEN_EXECUTABLE VERSI
# Find Dot...
#
+set(_x86 "(x86)")
+file(GLOB _Doxygen_GRAPHVIZ_BIN_DIRS
+ "$ENV{ProgramFiles}/Graphviz*/bin"
+ "$ENV{ProgramFiles${_x86}}/Graphviz*/bin"
+ )
+unset(_x86)
+
if(NOT DOXYGEN_SKIP_DOT)
find_program(DOXYGEN_DOT_EXECUTABLE
NAMES dot
PATHS
- "$ENV{ProgramFiles}/Graphviz 2.21/bin"
- "C:/Program Files/Graphviz 2.21/bin"
+ ${_Doxygen_GRAPHVIZ_BIN_DIRS}
"$ENV{ProgramFiles}/ATT/Graphviz/bin"
"C:/Program Files/ATT/Graphviz/bin"
[HKEY_LOCAL_MACHINE\\SOFTWARE\\ATT\\Graphviz;InstallPath]/bin
@@ -106,7 +134,7 @@ if(NOT DOXYGEN_SKIP_DOT)
if(DOXYGEN_DOT_EXECUTABLE)
set(DOXYGEN_DOT_FOUND TRUE)
# The Doxyfile wants the path to Dot, not the entire path and executable
- get_filename_component(DOXYGEN_DOT_PATH "${DOXYGEN_DOT_EXECUTABLE}" PATH CACHE)
+ get_filename_component(DOXYGEN_DOT_PATH "${DOXYGEN_DOT_EXECUTABLE}" PATH)
endif()
endif()
@@ -140,5 +168,4 @@ set (DOT ${DOXYGEN_DOT_EXECUTABLE} )
mark_as_advanced(
DOXYGEN_EXECUTABLE
DOXYGEN_DOT_EXECUTABLE
- DOXYGEN_DOT_PATH
)
diff --git a/Modules/FindEXPAT.cmake b/Modules/FindEXPAT.cmake
index c681a0dfd..653094cd3 100644
--- a/Modules/FindEXPAT.cmake
+++ b/Modules/FindEXPAT.cmake
@@ -1,9 +1,16 @@
-# - Find expat
+#.rst:
+# FindEXPAT
+# ---------
+#
+# Find expat
+#
# Find the native EXPAT headers and libraries.
#
-# EXPAT_INCLUDE_DIRS - where to find expat.h, etc.
-# EXPAT_LIBRARIES - List of libraries when using expat.
-# EXPAT_FOUND - True if expat found.
+# ::
+#
+# EXPAT_INCLUDE_DIRS - where to find expat.h, etc.
+# EXPAT_LIBRARIES - List of libraries when using expat.
+# EXPAT_FOUND - True if expat found.
#=============================================================================
# Copyright 2006-2009 Kitware, Inc.
@@ -31,9 +38,8 @@ if (EXPAT_INCLUDE_DIR AND EXISTS "${EXPAT_INCLUDE_DIR}/expat.h")
unset(EXPAT_VERSION_STRING)
foreach(VPART MAJOR MINOR MICRO)
foreach(VLINE ${expat_version_str})
- if(VLINE MATCHES "^#[\t ]*define[\t ]+XML_${VPART}_VERSION")
- string(REGEX REPLACE "^#[\t ]*define[\t ]+XML_${VPART}_VERSION[\t ]+([0-9]+)$" "\\1"
- EXPAT_VERSION_PART "${VLINE}")
+ if(VLINE MATCHES "^#[\t ]*define[\t ]+XML_${VPART}_VERSION[\t ]+([0-9]+)$")
+ set(EXPAT_VERSION_PART "${CMAKE_MATCH_1}")
if(EXPAT_VERSION_STRING)
set(EXPAT_VERSION_STRING "${EXPAT_VERSION_STRING}.${EXPAT_VERSION_PART}")
else()
diff --git a/Modules/FindFLEX.cmake b/Modules/FindFLEX.cmake
index 79a3a1e6c..ca6649359 100644
--- a/Modules/FindFLEX.cmake
+++ b/Modules/FindFLEX.cmake
@@ -1,53 +1,97 @@
-# - Find flex executable and provides a macro to generate custom build rules
+#.rst:
+# FindFLEX
+# --------
+#
+# Find flex executable and provides a macro to generate custom build rules
+#
+#
#
# The module defines the following variables:
-# FLEX_FOUND - true is flex executable is found
-# FLEX_EXECUTABLE - the path to the flex executable
-# FLEX_VERSION - the version of flex
-# FLEX_LIBRARIES - The flex libraries
-# FLEX_INCLUDE_DIRS - The path to the flex headers
+#
+# ::
+#
+# FLEX_FOUND - true is flex executable is found
+# FLEX_EXECUTABLE - the path to the flex executable
+# FLEX_VERSION - the version of flex
+# FLEX_LIBRARIES - The flex libraries
+# FLEX_INCLUDE_DIRS - The path to the flex headers
+#
+#
#
# The minimum required version of flex can be specified using the
-# standard syntax, e.g. find_package(FLEX 2.5.13)
+# standard syntax, e.g. find_package(FLEX 2.5.13)
+#
#
#
# If flex is found on the system, the module provides the macro:
-# FLEX_TARGET(Name FlexInput FlexOutput [COMPILE_FLAGS <string>])
-# which creates a custom command to generate the <FlexOutput> file from
-# the <FlexInput> file. If COMPILE_FLAGS option is specified, the next
-# parameter is added to the flex command line. Name is an alias used to
-# get details of this custom command. Indeed the macro defines the
-# following variables:
-# FLEX_${Name}_DEFINED - true is the macro ran successfully
-# FLEX_${Name}_OUTPUTS - the source file generated by the custom rule, an
-# alias for FlexOutput
-# FLEX_${Name}_INPUT - the flex source file, an alias for ${FlexInput}
-#
-# Flex scanners oftenly use tokens defined by Bison: the code generated
-# by Flex depends of the header generated by Bison. This module also
+#
+# ::
+#
+# FLEX_TARGET(Name FlexInput FlexOutput
+# [COMPILE_FLAGS <string>]
+# [DEFINES_FILE <string>]
+# )
+#
+# which creates a custom command to generate the <FlexOutput> file from
+# the <FlexInput> file. If COMPILE_FLAGS option is specified, the next
+# parameter is added to the flex command line. If flex is configured to
+# output a header file, the DEFINES_FILE option may be used to specify its
+# name. Name is an alias used to get details of this custom command.
+# Indeed the macro defines the following variables:
+#
+# ::
+#
+# FLEX_${Name}_DEFINED - true is the macro ran successfully
+# FLEX_${Name}_OUTPUTS - the source file generated by the custom rule, an
+# alias for FlexOutput
+# FLEX_${Name}_INPUT - the flex source file, an alias for ${FlexInput}
+# FLEX_${Name}_OUTPUT_HEADER - the header flex output, if any.
+#
+#
+#
+# Flex scanners oftenly use tokens defined by Bison: the code generated
+# by Flex depends of the header generated by Bison. This module also
# defines a macro:
-# ADD_FLEX_BISON_DEPENDENCY(FlexTarget BisonTarget)
-# which adds the required dependency between a scanner and a parser
-# where <FlexTarget> and <BisonTarget> are the first parameters of
+#
+# ::
+#
+# ADD_FLEX_BISON_DEPENDENCY(FlexTarget BisonTarget)
+#
+# which adds the required dependency between a scanner and a parser
+# where <FlexTarget> and <BisonTarget> are the first parameters of
# respectively FLEX_TARGET and BISON_TARGET macros.
#
-# ====================================================================
-# Example:
+# ::
+#
+# ====================================================================
+# Example:
+#
+#
+#
+# ::
+#
+# find_package(BISON)
+# find_package(FLEX)
+#
+#
+#
+# ::
#
-# find_package(BISON)
-# find_package(FLEX)
+# BISON_TARGET(MyParser parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp)
+# FLEX_TARGET(MyScanner lexer.l ${CMAKE_CURRENT_BINARY_DIR}/lexer.cpp)
+# ADD_FLEX_BISON_DEPENDENCY(MyScanner MyParser)
#
-# BISON_TARGET(MyParser parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp)
-# FLEX_TARGET(MyScanner lexer.l ${CMAKE_CURRENT_BINARY_DIR}/lexer.cpp)
-# ADD_FLEX_BISON_DEPENDENCY(MyScanner MyParser)
#
-# include_directories(${CMAKE_CURRENT_BINARY_DIR})
-# add_executable(Foo
-# Foo.cc
-# ${BISON_MyParser_OUTPUTS}
-# ${FLEX_MyScanner_OUTPUTS}
-# )
-# ====================================================================
+#
+# ::
+#
+# include_directories(${CMAKE_CURRENT_BINARY_DIR})
+# add_executable(Foo
+# Foo.cc
+# ${BISON_MyParser_OUTPUTS}
+# ${FLEX_MyScanner_OUTPUTS}
+# )
+# ====================================================================
#=============================================================================
# Copyright 2009 Kitware, Inc.
@@ -74,6 +118,8 @@ find_path(FLEX_INCLUDE_DIR FlexLexer.h
mark_as_advanced(FL_LIBRARY FLEX_INCLUDE_DIR)
+include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake)
+
set(FLEX_INCLUDE_DIRS ${FLEX_INCLUDE_DIR})
set(FLEX_LIBRARIES ${FL_LIBRARY})
@@ -106,31 +152,55 @@ if(FLEX_EXECUTABLE)
#============================================================
#
macro(FLEX_TARGET Name Input Output)
- set(FLEX_TARGET_usage "FLEX_TARGET(<Name> <Input> <Output> [COMPILE_FLAGS <string>]")
- if(${ARGC} GREATER 3)
- if(${ARGC} EQUAL 5)
- if("${ARGV3}" STREQUAL "COMPILE_FLAGS")
- set(FLEX_EXECUTABLE_opts "${ARGV4}")
- separate_arguments(FLEX_EXECUTABLE_opts)
- else()
- message(SEND_ERROR ${FLEX_TARGET_usage})
- endif()
+ set(FLEX_TARGET_outputs "${Output}")
+ set(FLEX_EXECUTABLE_opts "")
+
+ set(FLEX_TARGET_PARAM_OPTIONS)
+ set(FLEX_TARGET_PARAM_ONE_VALUE_KEYWORDS
+ COMPILE_FLAGS
+ DEFINES_FILE
+ )
+ set(FLEX_TARGET_PARAM_MULTI_VALUE_KEYWORDS)
+
+ cmake_parse_arguments(
+ FLEX_TARGET_ARG
+ "${FLEX_TARGET_PARAM_OPTIONS}"
+ "${FLEX_TARGET_PARAM_ONE_VALUE_KEYWORDS}"
+ "${FLEX_TARGET_MULTI_VALUE_KEYWORDS}"
+ ${ARGN}
+ )
+
+ set(FLEX_TARGET_usage "FLEX_TARGET(<Name> <Input> <Output> [COMPILE_FLAGS <string>] [DEFINES_FILE <string>]")
+
+ if(NOT "${FLEX_TARGET_ARG_UNPARSED_ARGUMENTS}" STREQUAL "")
+ message(SEND_ERROR ${FLEX_TARGET_usage})
+ else()
+ if(NOT "${FLEX_TARGET_ARG_COMPILE_FLAGS}" STREQUAL "")
+ set(FLEX_EXECUTABLE_opts "${FLEX_TARGET_ARG_COMPILE_FLAGS}")
+ separate_arguments(FLEX_EXECUTABLE_opts)
+ endif()
+ if(NOT "${FLEX_TARGET_ARG_DEFINES_FILE}" STREQUAL "")
+ list(APPEND FLEX_TARGET_outputs "${FLEX_TARGET_ARG_DEFINES_FILE}")
+ list(APPEND FLEX_EXECUTABLE_opts --header-file=${FLEX_TARGET_ARG_DEFINES_FILE})
+ endif()
+
+ add_custom_command(OUTPUT ${FLEX_TARGET_outputs}
+ COMMAND ${FLEX_EXECUTABLE}
+ ARGS ${FLEX_EXECUTABLE_opts} -o${Output} ${Input}
+ DEPENDS ${Input}
+ COMMENT "[FLEX][${Name}] Building scanner with flex ${FLEX_VERSION}"
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+
+ set(FLEX_${Name}_DEFINED TRUE)
+ set(FLEX_${Name}_OUTPUTS ${Output})
+ set(FLEX_${Name}_INPUT ${Input})
+ set(FLEX_${Name}_COMPILE_FLAGS ${FLEX_EXECUTABLE_opts})
+ if("${FLEX_TARGET_ARG_DEFINES_FILE}" STREQUAL "")
+ set(FLEX_${Name}_OUTPUT_HEADER "")
else()
- message(SEND_ERROR ${FLEX_TARGET_usage})
+ set(FLEX_${Name}_OUTPUT_HEADER ${FLEX_TARGET_ARG_DEFINES_FILE})
endif()
endif()
-
- add_custom_command(OUTPUT ${Output}
- COMMAND ${FLEX_EXECUTABLE}
- ARGS ${FLEX_EXECUTABLE_opts} -o${Output} ${Input}
- DEPENDS ${Input}
- COMMENT "[FLEX][${Name}] Building scanner with flex ${FLEX_VERSION}"
- WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
-
- set(FLEX_${Name}_DEFINED TRUE)
- set(FLEX_${Name}_OUTPUTS ${Output})
- set(FLEX_${Name}_INPUT ${Input})
- set(FLEX_${Name}_COMPILE_FLAGS ${FLEX_EXECUTABLE_opts})
endmacro()
#============================================================
@@ -142,11 +212,11 @@ if(FLEX_EXECUTABLE)
macro(ADD_FLEX_BISON_DEPENDENCY FlexTarget BisonTarget)
if(NOT FLEX_${FlexTarget}_OUTPUTS)
- message(SEND_ERROR "Flex target `${FlexTarget}' does not exists.")
+ message(SEND_ERROR "Flex target `${FlexTarget}' does not exist.")
endif()
if(NOT BISON_${BisonTarget}_OUTPUT_HEADER)
- message(SEND_ERROR "Bison target `${BisonTarget}' does not exists.")
+ message(SEND_ERROR "Bison target `${BisonTarget}' does not exist.")
endif()
set_source_files_properties(${FLEX_${FlexTarget}_OUTPUTS}
diff --git a/Modules/FindFLTK.cmake b/Modules/FindFLTK.cmake
index 92c14daed..ad0bf9889 100644
--- a/Modules/FindFLTK.cmake
+++ b/Modules/FindFLTK.cmake
@@ -1,33 +1,58 @@
-# - Find the native FLTK includes and library
+#.rst:
+# FindFLTK
+# --------
#
-# By default FindFLTK.cmake will search for all of the FLTK components and
-# add them to the FLTK_LIBRARIES variable.
+# Find the native FLTK includes and library
#
-# You can limit the components which get placed in FLTK_LIBRARIES by
-# defining one or more of the following three options:
#
-# FLTK_SKIP_OPENGL, set to true to disable searching for opengl and
-# the FLTK GL library
-# FLTK_SKIP_FORMS, set to true to disable searching for fltk_forms
-# FLTK_SKIP_IMAGES, set to true to disable searching for fltk_images
#
-# FLTK_SKIP_FLUID, set to true if the fluid binary need not be present
-# at build time
+# By default FindFLTK.cmake will search for all of the FLTK components
+# and add them to the FLTK_LIBRARIES variable.
+#
+# ::
+#
+# You can limit the components which get placed in FLTK_LIBRARIES by
+# defining one or more of the following three options:
+#
+#
+#
+# ::
+#
+# FLTK_SKIP_OPENGL, set to true to disable searching for opengl and
+# the FLTK GL library
+# FLTK_SKIP_FORMS, set to true to disable searching for fltk_forms
+# FLTK_SKIP_IMAGES, set to true to disable searching for fltk_images
+#
+#
+#
+# ::
+#
+# FLTK_SKIP_FLUID, set to true if the fluid binary need not be present
+# at build time
+#
+#
#
# The following variables will be defined:
-# FLTK_FOUND, True if all components not skipped were found
-# FLTK_INCLUDE_DIR, where to find include files
-# FLTK_LIBRARIES, list of fltk libraries you should link against
-# FLTK_FLUID_EXECUTABLE, where to find the Fluid tool
-# FLTK_WRAP_UI, This enables the FLTK_WRAP_UI command
+#
+# ::
+#
+# FLTK_FOUND, True if all components not skipped were found
+# FLTK_INCLUDE_DIR, where to find include files
+# FLTK_LIBRARIES, list of fltk libraries you should link against
+# FLTK_FLUID_EXECUTABLE, where to find the Fluid tool
+# FLTK_WRAP_UI, This enables the FLTK_WRAP_UI command
+#
+#
#
# The following cache variables are assigned but should not be used.
# See the FLTK_LIBRARIES variable instead.
#
-# FLTK_BASE_LIBRARY = the full path to fltk.lib
-# FLTK_GL_LIBRARY = the full path to fltk_gl.lib
-# FLTK_FORMS_LIBRARY = the full path to fltk_forms.lib
-# FLTK_IMAGES_LIBRARY = the full path to fltk_images.lib
+# ::
+#
+# FLTK_BASE_LIBRARY = the full path to fltk.lib
+# FLTK_GL_LIBRARY = the full path to fltk_gl.lib
+# FLTK_FORMS_LIBRARY = the full path to fltk_forms.lib
+# FLTK_IMAGES_LIBRARY = the full path to fltk_images.lib
#=============================================================================
# Copyright 2001-2009 Kitware, Inc.
@@ -106,21 +131,6 @@ if(NOT FLTK_DIR)
/usr/local/fltk
/usr/X11R6/include
- # Read from the CMakeSetup registry entries. It is likely that
- # FLTK will have been recently built.
- # TODO: Is this really a good idea? I can already hear the user screaming, "But
- # it worked when I configured the build LAST week!"
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild1]
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild2]
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild3]
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild4]
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild5]
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild6]
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild7]
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild8]
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild9]
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild10]
-
# Help the user find it if we cannot.
DOC "The ${FLTK_DIR_STRING}"
)
@@ -260,9 +270,7 @@ endif()
OUTPUT_VARIABLE FLTK_IMAGES_LDFLAGS)
set(FLTK_LIBS_EXTRACT_REGEX ".*-lfltk_images (.*) -lfltk.*")
if("${FLTK_IMAGES_LDFLAGS}" MATCHES "${FLTK_LIBS_EXTRACT_REGEX}")
- string(REGEX REPLACE "${FLTK_LIBS_EXTRACT_REGEX}" "\\1"
- FLTK_IMAGES_LIBS "${FLTK_IMAGES_LDFLAGS}")
- string(REGEX REPLACE " +" ";" FLTK_IMAGES_LIBS "${FLTK_IMAGES_LIBS}")
+ string(REGEX REPLACE " +" ";" FLTK_IMAGES_LIBS "${CMAKE_MATCH_1}")
# The EXEC_PROGRAM will not be inherited into subdirectories from
# the file that originally included this module. Save the answer.
set(FLTK_IMAGES_LIBS "${FLTK_IMAGES_LIBS}" CACHE INTERNAL
diff --git a/Modules/FindFLTK2.cmake b/Modules/FindFLTK2.cmake
index 09f6925cc..154729f05 100644
--- a/Modules/FindFLTK2.cmake
+++ b/Modules/FindFLTK2.cmake
@@ -1,14 +1,26 @@
-# - Find the native FLTK2 includes and library
+#.rst:
+# FindFLTK2
+# ---------
+#
+# Find the native FLTK2 includes and library
+#
# The following settings are defined
-# FLTK2_FLUID_EXECUTABLE, where to find the Fluid tool
-# FLTK2_WRAP_UI, This enables the FLTK2_WRAP_UI command
-# FLTK2_INCLUDE_DIR, where to find include files
-# FLTK2_LIBRARIES, list of fltk2 libraries
-# FLTK2_FOUND, Don't use FLTK2 if false.
+#
+# ::
+#
+# FLTK2_FLUID_EXECUTABLE, where to find the Fluid tool
+# FLTK2_WRAP_UI, This enables the FLTK2_WRAP_UI command
+# FLTK2_INCLUDE_DIR, where to find include files
+# FLTK2_LIBRARIES, list of fltk2 libraries
+# FLTK2_FOUND, Don't use FLTK2 if false.
+#
# The following settings should not be used in general.
-# FLTK2_BASE_LIBRARY = the full path to fltk2.lib
-# FLTK2_GL_LIBRARY = the full path to fltk2_gl.lib
-# FLTK2_IMAGES_LIBRARY = the full path to fltk2_images.lib
+#
+# ::
+#
+# FLTK2_BASE_LIBRARY = the full path to fltk2.lib
+# FLTK2_GL_LIBRARY = the full path to fltk2_gl.lib
+# FLTK2_IMAGES_LIBRARY = the full path to fltk2_images.lib
#=============================================================================
# Copyright 2007-2009 Kitware, Inc.
@@ -84,19 +96,6 @@ if(NOT FLTK2_DIR)
/usr/local/fltk2
/usr/X11R6/include
- # Read from the CMakeSetup registry entries. It is likely that
- # FLTK2 will have been recently built.
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild1]
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild2]
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild3]
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild4]
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild5]
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild6]
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild7]
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild8]
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild9]
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild10]
-
# Help the user find it if we cannot.
DOC "The ${FLTK2_DIR_STRING}"
)
@@ -214,9 +213,7 @@ if(FLTK2_DIR)
OUTPUT_VARIABLE FLTK2_IMAGES_LDFLAGS)
set(FLTK2_LIBS_EXTRACT_REGEX ".*-lfltk2_images (.*) -lfltk2.*")
if("${FLTK2_IMAGES_LDFLAGS}" MATCHES "${FLTK2_LIBS_EXTRACT_REGEX}")
- string(REGEX REPLACE "${FLTK2_LIBS_EXTRACT_REGEX}" "\\1"
- FLTK2_IMAGES_LIBS "${FLTK2_IMAGES_LDFLAGS}")
- string(REGEX REPLACE " +" ";" FLTK2_IMAGES_LIBS "${FLTK2_IMAGES_LIBS}")
+ string(REGEX REPLACE " +" ";" FLTK2_IMAGES_LIBS "${CMAKE_MATCH_1}")
# The EXEC_PROGRAM will not be inherited into subdirectories from
# the file that originally included this module. Save the answer.
set(FLTK2_IMAGES_LIBS "${FLTK2_IMAGES_LIBS}" CACHE INTERNAL
diff --git a/Modules/FindFreetype.cmake b/Modules/FindFreetype.cmake
index ccea99165..7d46d1563 100644
--- a/Modules/FindFreetype.cmake
+++ b/Modules/FindFreetype.cmake
@@ -1,16 +1,25 @@
-# - Locate FreeType library
+#.rst:
+# FindFreetype
+# ------------
+#
+# Locate FreeType library
+#
# This module defines
-# FREETYPE_LIBRARIES, the library to link against
-# FREETYPE_FOUND, if false, do not try to link to FREETYPE
-# FREETYPE_INCLUDE_DIRS, where to find headers.
-# FREETYPE_VERSION_STRING, the version of freetype found (since CMake 2.8.8)
-# This is the concatenation of the paths:
-# FREETYPE_INCLUDE_DIR_ft2build
-# FREETYPE_INCLUDE_DIR_freetype2
#
-# $FREETYPE_DIR is an environment variable that would
-# correspond to the ./configure --prefix=$FREETYPE_DIR
-# used in building FREETYPE.
+# ::
+#
+# FREETYPE_LIBRARIES, the library to link against
+# FREETYPE_FOUND, if false, do not try to link to FREETYPE
+# FREETYPE_INCLUDE_DIRS, where to find headers.
+# FREETYPE_VERSION_STRING, the version of freetype found (since CMake 2.8.8)
+# This is the concatenation of the paths:
+# FREETYPE_INCLUDE_DIR_ft2build
+# FREETYPE_INCLUDE_DIR_freetype2
+#
+#
+#
+# $FREETYPE_DIR is an environment variable that would correspond to the
+# ./configure --prefix=$FREETYPE_DIR used in building FREETYPE.
#=============================================================================
# Copyright 2007-2009 Kitware, Inc.
@@ -42,7 +51,9 @@
# wants explicit full paths and this trickery doesn't work too well.
# I'm going to attempt to cut out the middleman and hope
# everything still works.
-find_path(FREETYPE_INCLUDE_DIR_ft2build ft2build.h
+find_path(
+ FREETYPE_INCLUDE_DIR_ft2build
+ ft2build.h
HINTS
ENV FREETYPE_DIR
PATHS
@@ -53,10 +64,17 @@ find_path(FREETYPE_INCLUDE_DIR_ft2build ft2build.h
ENV GTKMM_BASEPATH
[HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]
- PATH_SUFFIXES include/freetype2 include
+ PATH_SUFFIXES
+ include/freetype2
+ include
+ freetype2
)
-find_path(FREETYPE_INCLUDE_DIR_freetype2 freetype/config/ftheader.h
+find_path(
+ FREETYPE_INCLUDE_DIR_freetype2
+ NAMES
+ freetype/config/ftheader.h
+ config/ftheader.h
HINTS
ENV FREETYPE_DIR
PATHS
@@ -67,14 +85,19 @@ find_path(FREETYPE_INCLUDE_DIR_freetype2 freetype/config/ftheader.h
ENV GTKMM_BASEPATH
[HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]
- PATH_SUFFIXES include/freetype2 include
+ PATH_SUFFIXES
+ include/freetype2
+ include
+ freetype2
)
find_library(FREETYPE_LIBRARY
- NAMES freetype libfreetype freetype219
+ NAMES
+ freetype
+ libfreetype
+ freetype219
HINTS
ENV FREETYPE_DIR
- PATH_SUFFIXES lib
PATHS
/usr/X11R6
/usr/local/X11R6
@@ -83,41 +106,59 @@ find_library(FREETYPE_LIBRARY
ENV GTKMM_BASEPATH
[HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]
[HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]
+ PATH_SUFFIXES
+ lib
)
# set the user variables
if(FREETYPE_INCLUDE_DIR_ft2build AND FREETYPE_INCLUDE_DIR_freetype2)
set(FREETYPE_INCLUDE_DIRS "${FREETYPE_INCLUDE_DIR_ft2build};${FREETYPE_INCLUDE_DIR_freetype2}")
+ list(REMOVE_DUPLICATES FREETYPE_INCLUDE_DIRS)
endif()
set(FREETYPE_LIBRARIES "${FREETYPE_LIBRARY}")
-if(FREETYPE_INCLUDE_DIR_freetype2 AND EXISTS "${FREETYPE_INCLUDE_DIR_freetype2}/freetype/freetype.h")
- file(STRINGS "${FREETYPE_INCLUDE_DIR_freetype2}/freetype/freetype.h" freetype_version_str
- REGEX "^#[\t ]*define[\t ]+FREETYPE_(MAJOR|MINOR|PATCH)[\t ]+[0-9]+$")
+if(EXISTS "${FREETYPE_INCLUDE_DIR_freetype2}/freetype/freetype.h")
+ set(FREETYPE_H "${FREETYPE_INCLUDE_DIR_freetype2}/freetype/freetype.h")
+elseif(EXISTS "${FREETYPE_INCLUDE_DIR_freetype2}/freetype.h")
+ set(FREETYPE_H "${FREETYPE_INCLUDE_DIR_freetype2}/freetype.h")
+endif()
+
+if(FREETYPE_INCLUDE_DIR_freetype2 AND FREETYPE_H)
+ file(STRINGS "${FREETYPE_H}" freetype_version_str
+ REGEX "^#[\t ]*define[\t ]+FREETYPE_(MAJOR|MINOR|PATCH)[\t ]+[0-9]+$")
- unset(FREETYPE_VERSION_STRING)
- foreach(VPART MAJOR MINOR PATCH)
- foreach(VLINE ${freetype_version_str})
- if(VLINE MATCHES "^#[\t ]*define[\t ]+FREETYPE_${VPART}")
- string(REGEX REPLACE "^#[\t ]*define[\t ]+FREETYPE_${VPART}[\t ]+([0-9]+)$" "\\1"
- FREETYPE_VERSION_PART "${VLINE}")
- if(FREETYPE_VERSION_STRING)
- set(FREETYPE_VERSION_STRING "${FREETYPE_VERSION_STRING}.${FREETYPE_VERSION_PART}")
- else()
- set(FREETYPE_VERSION_STRING "${FREETYPE_VERSION_PART}")
- endif()
- unset(FREETYPE_VERSION_PART)
- endif()
- endforeach()
+ unset(FREETYPE_VERSION_STRING)
+ foreach(VPART MAJOR MINOR PATCH)
+ foreach(VLINE ${freetype_version_str})
+ if(VLINE MATCHES "^#[\t ]*define[\t ]+FREETYPE_${VPART}[\t ]+([0-9]+)$")
+ set(FREETYPE_VERSION_PART "${CMAKE_MATCH_1}")
+ if(FREETYPE_VERSION_STRING)
+ set(FREETYPE_VERSION_STRING "${FREETYPE_VERSION_STRING}.${FREETYPE_VERSION_PART}")
+ else()
+ set(FREETYPE_VERSION_STRING "${FREETYPE_VERSION_PART}")
+ endif()
+ unset(FREETYPE_VERSION_PART)
+ endif()
endforeach()
+ endforeach()
endif()
# handle the QUIETLY and REQUIRED arguments and set FREETYPE_FOUND to TRUE if
# all listed variables are TRUE
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(Freetype
- REQUIRED_VARS FREETYPE_LIBRARY FREETYPE_INCLUDE_DIRS
- VERSION_VAR FREETYPE_VERSION_STRING)
-mark_as_advanced(FREETYPE_LIBRARY FREETYPE_INCLUDE_DIR_freetype2 FREETYPE_INCLUDE_DIR_ft2build)
+find_package_handle_standard_args(
+ Freetype
+ REQUIRED_VARS
+ FREETYPE_LIBRARY
+ FREETYPE_INCLUDE_DIRS
+ VERSION_VAR
+ FREETYPE_VERSION_STRING
+)
+
+mark_as_advanced(
+ FREETYPE_LIBRARY
+ FREETYPE_INCLUDE_DIR_freetype2
+ FREETYPE_INCLUDE_DIR_ft2build
+)
diff --git a/Modules/FindGCCXML.cmake b/Modules/FindGCCXML.cmake
index 05f08a639..48618e289 100644
--- a/Modules/FindGCCXML.cmake
+++ b/Modules/FindGCCXML.cmake
@@ -1,7 +1,16 @@
-# - Find the GCC-XML front-end executable.
+#.rst:
+# FindGCCXML
+# ----------
+#
+# Find the GCC-XML front-end executable.
+#
+#
#
# This module will define the following variables:
-# GCCXML - the GCC-XML front-end executable.
+#
+# ::
+#
+# GCCXML - the GCC-XML front-end executable.
#=============================================================================
# Copyright 2001-2009 Kitware, Inc.
diff --git a/Modules/FindGDAL.cmake b/Modules/FindGDAL.cmake
index 6e898474b..bf374f930 100644
--- a/Modules/FindGDAL.cmake
+++ b/Modules/FindGDAL.cmake
@@ -1,14 +1,26 @@
+#.rst:
+# FindGDAL
+# --------
+#
+#
+#
# Locate gdal
#
# This module accepts the following environment variables:
#
-# GDAL_DIR or GDAL_ROOT - Specify the location of GDAL
+# ::
+#
+# GDAL_DIR or GDAL_ROOT - Specify the location of GDAL
+#
+#
#
# This module defines the following CMake variables:
#
-# GDAL_FOUND - True if libgdal is found
-# GDAL_LIBRARY - A variable pointing to the GDAL library
-# GDAL_INCLUDE_DIR - Where to find the headers
+# ::
+#
+# GDAL_FOUND - True if libgdal is found
+# GDAL_LIBRARY - A variable pointing to the GDAL library
+# GDAL_INCLUDE_DIR - Where to find the headers
#=============================================================================
# Copyright 2007-2009 Kitware, Inc.
@@ -78,9 +90,9 @@ if(UNIX)
exec_program(${GDAL_CONFIG} ARGS --libs OUTPUT_VARIABLE GDAL_CONFIG_LIBS)
if(GDAL_CONFIG_LIBS)
string(REGEX MATCHALL "-l[^ ]+" _gdal_dashl ${GDAL_CONFIG_LIBS})
- string(REGEX REPLACE "-l" "" _gdal_lib "${_gdal_dashl}")
+ string(REPLACE "-l" "" _gdal_lib "${_gdal_dashl}")
string(REGEX MATCHALL "-L[^ ]+" _gdal_dashL ${GDAL_CONFIG_LIBS})
- string(REGEX REPLACE "-L" "" _gdal_libpath "${_gdal_dashL}")
+ string(REPLACE "-L" "" _gdal_libpath "${_gdal_dashL}")
endif()
endif()
endif()
diff --git a/Modules/FindGIF.cmake b/Modules/FindGIF.cmake
index 90ff7377f..7bbb8cfcd 100644
--- a/Modules/FindGIF.cmake
+++ b/Modules/FindGIF.cmake
@@ -1,14 +1,19 @@
-# This module searches giflib and defines
-# GIF_LIBRARIES - libraries to link to in order to use GIF
-# GIF_FOUND, if false, do not try to link
-# GIF_INCLUDE_DIR, where to find the headers
-# GIF_VERSION, reports either version 4 or 3 (for everything before version 4)
+#.rst:
+# FindGIF
+# -------
+#
+#
+#
+# This module searches giflib and defines GIF_LIBRARIES - libraries to
+# link to in order to use GIF GIF_FOUND, if false, do not try to link
+# GIF_INCLUDE_DIR, where to find the headers GIF_VERSION, reports either
+# version 4 or 3 (for everything before version 4)
#
# The minimum required version of giflib can be specified using the
-# standard syntax, e.g. find_package(GIF 4)
+# standard syntax, e.g. find_package(GIF 4)
#
-# $GIF_DIR is an environment variable that would
-# correspond to the ./configure --prefix=$GIF_DIR
+# $GIF_DIR is an environment variable that would correspond to the
+# ./configure --prefix=$GIF_DIR
#=============================================================================
# Copyright 2007-2009 Kitware, Inc.
@@ -61,6 +66,7 @@ if(GIF_INCLUDE_DIR)
include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/CheckStructHasMember.cmake)
CMAKE_PUSH_CHECK_STATE()
+ set(CMAKE_REQUIRED_QUIET ${GIF_FIND_QUIETLY})
set(GIF_VERSION 3)
set(CMAKE_REQUIRED_INCLUDES "${GIF_INCLUDE_DIR}")
CHECK_STRUCT_HAS_MEMBER(GifFileType UserData gif_lib.h GIF_GifFileType_UserData )
diff --git a/Modules/FindGLEW.cmake b/Modules/FindGLEW.cmake
index 37dff0324..f42182fca 100644
--- a/Modules/FindGLEW.cmake
+++ b/Modules/FindGLEW.cmake
@@ -1,8 +1,25 @@
-# - Find the OpenGL Extension Wrangler Library (GLEW)
+#.rst:
+# FindGLEW
+# --------
+#
+# Find the OpenGL Extension Wrangler Library (GLEW)
+#
+# IMPORTED Targets
+# ^^^^^^^^^^^^^^^^
+#
+# This module defines the :prop_tgt:`IMPORTED` target ``GLEW::GLEW``,
+# if GLEW has been found.
+#
+# Result Variables
+# ^^^^^^^^^^^^^^^^
+#
# This module defines the following variables:
-# GLEW_INCLUDE_DIRS - include directories for GLEW
-# GLEW_LIBRARIES - libraries to link against GLEW
-# GLEW_FOUND - true if GLEW has been found and can be used
+#
+# ::
+#
+# GLEW_INCLUDE_DIRS - include directories for GLEW
+# GLEW_LIBRARIES - libraries to link against GLEW
+# GLEW_FOUND - true if GLEW has been found and can be used
#=============================================================================
# Copyright 2012 Benjamin Eikel
@@ -27,4 +44,11 @@ include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
find_package_handle_standard_args(GLEW
REQUIRED_VARS GLEW_INCLUDE_DIR GLEW_LIBRARY)
+if(GLEW_FOUND AND NOT TARGET GLEW::GLEW)
+ add_library(GLEW::GLEW UNKNOWN IMPORTED)
+ set_target_properties(GLEW::GLEW PROPERTIES
+ IMPORTED_LOCATION "${GLEW_LIBRARY}"
+ INTERFACE_INCLUDE_DIRECTORIES "${GLEW_INCLUDE_DIRS}")
+endif()
+
mark_as_advanced(GLEW_INCLUDE_DIR GLEW_LIBRARY)
diff --git a/Modules/FindGLUT.cmake b/Modules/FindGLUT.cmake
index 843d1389f..c9f7597f4 100644
--- a/Modules/FindGLUT.cmake
+++ b/Modules/FindGLUT.cmake
@@ -1,11 +1,35 @@
-# - try to find glut library and include files
-# GLUT_INCLUDE_DIR, where to find GL/glut.h, etc.
-# GLUT_LIBRARIES, the libraries to link against
-# GLUT_FOUND, If false, do not try to use GLUT.
+#.rst:
+# FindGLUT
+# --------
+#
+# try to find glut library and include files.
+#
+# IMPORTED Targets
+# ^^^^^^^^^^^^^^^^
+#
+# This module defines the :prop_tgt:`IMPORTED` targets:
+#
+# ``GLUT::GLUT``
+# Defined if the system has GLUT.
+#
+# Result Variables
+# ^^^^^^^^^^^^^^^^
+#
+# This module sets the following variables:
+#
+# ::
+#
+# GLUT_INCLUDE_DIR, where to find GL/glut.h, etc.
+# GLUT_LIBRARIES, the libraries to link against
+# GLUT_FOUND, If false, do not try to use GLUT.
+#
# Also defined, but not for general use are:
-# GLUT_glut_LIBRARY = the full path to the glut library.
-# GLUT_Xmu_LIBRARY = the full path to the Xmu library.
-# GLUT_Xi_LIBRARY = the full path to the Xi Library.
+#
+# ::
+#
+# GLUT_glut_LIBRARY = the full path to the glut library.
+# GLUT_Xmu_LIBRARY = the full path to the Xmu library.
+# GLUT_Xi_LIBRARY = the full path to the Xi Library.
#=============================================================================
# Copyright 2001-2009 Kitware, Inc.
@@ -31,13 +55,21 @@ if (WIN32)
else ()
if (APPLE)
- # These values for Apple could probably do with improvement.
- find_path( GLUT_INCLUDE_DIR glut.h
- /System/Library/Frameworks/GLUT.framework/Versions/A/Headers
- ${OPENGL_LIBRARY_DIR}
- )
- set(GLUT_glut_LIBRARY "-framework GLUT" CACHE STRING "GLUT library for OSX")
- set(GLUT_cocoa_LIBRARY "-framework Cocoa" CACHE STRING "Cocoa framework for OSX")
+ find_path(GLUT_INCLUDE_DIR glut.h ${OPENGL_LIBRARY_DIR})
+ find_library(GLUT_glut_LIBRARY GLUT DOC "GLUT library for OSX")
+ find_library(GLUT_cocoa_LIBRARY Cocoa DOC "Cocoa framework for OSX")
+
+ if(GLUT_cocoa_LIBRARY AND NOT TARGET GLUT::Cocoa)
+ add_library(GLUT::Cocoa UNKNOWN IMPORTED)
+ # Cocoa should always be a Framework, but we check to make sure.
+ if(GLUT_cocoa_LIBRARY MATCHES "/([^/]+)\\.framework$")
+ set_target_properties(GLUT::Cocoa PROPERTIES
+ IMPORTED_LOCATION "${GLUT_cocoa_LIBRARY}/${CMAKE_MATCH_1}")
+ else()
+ set_target_properties(GLUT::Cocoa PROPERTIES
+ IMPORTED_LOCATION "${GLUT_cocoa_LIBRARY}")
+ endif()
+ endif()
else ()
if (BEOS)
@@ -55,6 +87,18 @@ else ()
/usr/openwin/lib
)
+ if(GLUT_Xi_LIBRARY AND NOT TARGET GLUT::Xi)
+ add_library(GLUT::Xi UNKNOWN IMPORTED)
+ set_target_properties(GLUT::Xi PROPERTIES
+ IMPORTED_LOCATION "${GLUT_Xi_LIBRARY}")
+ endif()
+
+ if(GLUT_Xmu_LIBRARY AND NOT TARGET GLUT::Xmu)
+ add_library(GLUT::Xmu UNKNOWN IMPORTED)
+ set_target_properties(GLUT::Xmu PROPERTIES
+ IMPORTED_LOCATION "${GLUT_Xmu_LIBRARY}")
+ endif()
+
endif ()
find_path( GLUT_INCLUDE_DIR GL/glut.h
@@ -91,6 +135,34 @@ if (GLUT_FOUND)
${GLUT_cocoa_LIBRARY}
)
+ if(NOT TARGET GLUT::GLUT)
+ add_library(GLUT::GLUT UNKNOWN IMPORTED)
+ set_target_properties(GLUT::GLUT PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${GLUT_INCLUDE_DIR}")
+ if(GLUT_glut_LIBRARY MATCHES "/([^/]+)\\.framework$")
+ set_target_properties(GLUT::GLUT PROPERTIES
+ IMPORTED_LOCATION "${GLUT_glut_LIBRARY}/${CMAKE_MATCH_1}")
+ else()
+ set_target_properties(GLUT::GLUT PROPERTIES
+ IMPORTED_LOCATION "${GLUT_glut_LIBRARY}")
+ endif()
+
+ if(TARGET GLUT::Xmu)
+ set_property(TARGET GLUT::GLUT APPEND
+ PROPERTY INTERFACE_LINK_LIBRARIES GLUT::Xmu)
+ endif()
+
+ if(TARGET GLUT::Xi)
+ set_property(TARGET GLUT::GLUT APPEND
+ PROPERTY INTERFACE_LINK_LIBRARIES GLUT::Xi)
+ endif()
+
+ if(TARGET GLUT::Cocoa)
+ set_property(TARGET GLUT::GLUT APPEND
+ PROPERTY INTERFACE_LINK_LIBRARIES GLUT::Cocoa)
+ endif()
+ endif()
+
#The following deprecated settings are for backwards compatibility with CMake1.4
set (GLUT_LIBRARY ${GLUT_LIBRARIES})
set (GLUT_INCLUDE_PATH ${GLUT_INCLUDE_DIR})
diff --git a/Modules/FindGSL.cmake b/Modules/FindGSL.cmake
new file mode 100644
index 000000000..ef125c061
--- /dev/null
+++ b/Modules/FindGSL.cmake
@@ -0,0 +1,238 @@
+#.rst:
+# FindGSL
+# --------
+#
+# Find the native GSL includes and libraries.
+#
+# The GNU Scientific Library (GSL) is a numerical library for C and C++
+# programmers. It is free software under the GNU General Public
+# License.
+#
+# Imported Targets
+# ^^^^^^^^^^^^^^^^
+#
+# If GSL is found, this module defines the following :prop_tgt:`IMPORTED`
+# targets::
+#
+# GSL::gsl - The main GSL library.
+# GSL::gslcblas - The CBLAS support library used by GSL.
+#
+# Result Variables
+# ^^^^^^^^^^^^^^^^
+#
+# This module will set the following variables in your project::
+#
+# GSL_FOUND - True if GSL found on the local system
+# GSL_INCLUDE_DIRS - Location of GSL header files.
+# GSL_LIBRARIES - The GSL libraries.
+# GSL_VERSION - The version of the discovered GSL install.
+#
+# Hints
+# ^^^^^
+#
+# Set ``GSL_ROOT_DIR`` to a directory that contains a GSL installation.
+#
+# This script expects to find libraries at ``$GSL_ROOT_DIR/lib`` and the GSL
+# headers at ``$GSL_ROOT_DIR/include/gsl``. The library directory may
+# optionally provide Release and Debug folders. For Unix-like systems, this
+# script will use ``$GSL_ROOT_DIR/bin/gsl-config`` (if found) to aid in the
+# discovery GSL.
+#
+# Cache Variables
+# ^^^^^^^^^^^^^^^
+#
+# This module may set the following variables depending on platform and type
+# of GSL installation discovered. These variables may optionally be set to
+# help this module find the correct files::
+#
+# GSL_CLBAS_LIBRARY - Location of the GSL CBLAS library.
+# GSL_CBLAS_LIBRARY_DEBUG - Location of the debug GSL CBLAS library (if any).
+# GSL_CONFIG_EXECUTABLE - Location of the ``gsl-config`` script (if any).
+# GSL_LIBRARY - Location of the GSL library.
+# GSL_LIBRARY_DEBUG - Location of the debug GSL library (if any).
+#
+
+#=============================================================================
+# Copyright 2014 Kelly Thompson <kgt@lanl.gov>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# Include these modules to handle the QUIETLY and REQUIRED arguments.
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+
+#=============================================================================
+# If the user has provided ``GSL_ROOT_DIR``, use it! Choose items found
+# at this location over system locations.
+if( EXISTS "$ENV{GSL_ROOT_DIR}" )
+ file( TO_CMAKE_PATH "$ENV{GSL_ROOT_DIR}" GSL_ROOT_DIR )
+ set( GSL_ROOT_DIR "${GSL_ROOT_DIR}" CACHE PATH "Prefix for GSL installation." )
+endif()
+if( NOT EXISTS "${GSL_ROOT_DIR}" )
+ set( GSL_USE_PKGCONFIG ON )
+endif()
+
+#=============================================================================
+# As a first try, use the PkgConfig module. This will work on many
+# *NIX systems. See :module:`findpkgconfig`
+# This will return ``GSL_INCLUDEDIR`` and ``GSL_LIBDIR`` used below.
+if( GSL_USE_PKGCONFIG )
+ find_package(PkgConfig)
+ pkg_check_modules( GSL QUIET gsl )
+
+ if( EXISTS "${GSL_INCLUDEDIR}" )
+ get_filename_component( GSL_ROOT_DIR "${GSL_INCLUDEDIR}" DIRECTORY CACHE)
+ endif()
+endif()
+
+#=============================================================================
+# Set GSL_INCLUDE_DIRS and GSL_LIBRARIES. If we skipped the PkgConfig step, try
+# to find the libraries at $GSL_ROOT_DIR (if provided) or in standard system
+# locations. These find_library and find_path calls will prefer custom
+# locations over standard locations (HINTS). If the requested file is not found
+# at the HINTS location, standard system locations will be still be searched
+# (/usr/lib64 (Redhat), lib/i386-linux-gnu (Debian)).
+
+find_path( GSL_INCLUDE_DIR
+ NAMES gsl/gsl_sf.h
+ HINTS ${GSL_ROOT_DIR}/include ${GSL_INCLUDEDIR}
+)
+find_library( GSL_LIBRARY
+ NAMES gsl
+ HINTS ${GSL_ROOT_DIR}/lib ${GSL_LIBDIR}
+ PATH_SUFFIXES Release Debug
+)
+find_library( GSL_CBLAS_LIBRARY
+ NAMES gslcblas cblas
+ HINTS ${GSL_ROOT_DIR}/lib ${GSL_LIBDIR}
+ PATH_SUFFIXES Release Debug
+)
+# Do we also have debug versions?
+find_library( GSL_LIBRARY_DEBUG
+ NAMES gsl
+ HINTS ${GSL_ROOT_DIR}/lib ${GSL_LIBDIR}
+ PATH_SUFFIXES Debug
+)
+find_library( GSL_CBLAS_LIBRARY_DEBUG
+ NAMES gslcblas cblas
+ HINTS ${GSL_ROOT_DIR}/lib ${GSL_LIBDIR}
+ PATH_SUFFIXES Debug
+)
+set( GSL_INCLUDE_DIRS ${GSL_INCLUDE_DIR} )
+set( GSL_LIBRARIES ${GSL_LIBRARY} ${GSL_CBLAS_LIBRARY} )
+
+# If we didn't use PkgConfig, try to find the version via gsl-config or by
+# reading gsl_version.h.
+if( NOT GSL_VERSION )
+ # 1. If gsl-config exists, query for the version.
+ find_program( GSL_CONFIG_EXECUTABLE
+ NAMES gsl-config
+ HINTS "${GSL_ROOT_DIR}/bin"
+ )
+ if( EXISTS "${GSL_CONFIG_EXECUTABLE}" )
+ execute_process(
+ COMMAND "${GSL_CONFIG_EXECUTABLE}" --version
+ OUTPUT_VARIABLE GSL_VERSION
+ OUTPUT_STRIP_TRAILING_WHITESPACE )
+ endif()
+
+ # 2. If gsl-config is not available, try looking in gsl/gsl_version.h
+ if( NOT GSL_VERSION AND EXISTS "${GSL_INCLUDE_DIRS}/gsl/gsl_version.h" )
+ file( STRINGS "${GSL_INCLUDE_DIRS}/gsl/gsl_version.h" gsl_version_h_contents REGEX "define GSL_VERSION" )
+ string( REGEX REPLACE ".*([0-9].[0-9][0-9]).*" "\\1" GSL_VERSION ${gsl_version_h_contents} )
+ endif()
+
+ # might also try scraping the directory name for a regex match "gsl-X.X"
+endif()
+
+#=============================================================================
+# handle the QUIETLY and REQUIRED arguments and set GSL_FOUND to TRUE if all
+# listed variables are TRUE
+find_package_handle_standard_args( GSL
+ FOUND_VAR
+ GSL_FOUND
+ REQUIRED_VARS
+ GSL_INCLUDE_DIR
+ GSL_LIBRARY
+ GSL_CBLAS_LIBRARY
+ VERSION_VAR
+ GSL_VERSION
+ )
+
+mark_as_advanced( GSL_ROOT_DIR GSL_VERSION GSL_LIBRARY GSL_INCLUDE_DIR
+ GSL_CBLAS_LIBRARY GSL_LIBRARY_DEBUG GSL_CBLAS_LIBRARY_DEBUG
+ GSL_USE_PKGCONFIG GSL_CONFIG )
+
+#=============================================================================
+# Register imported libraries:
+# 1. If we can find a Windows .dll file (or if we can find both Debug and
+# Release libraries), we will set appropriate target properties for these.
+# 2. However, for most systems, we will only register the import location and
+# include directory.
+
+# Look for dlls, or Release and Debug libraries.
+if(WIN32)
+ string( REPLACE ".lib" ".dll" GSL_LIBRARY_DLL "${GSL_LIBRARY}" )
+ string( REPLACE ".lib" ".dll" GSL_CBLAS_LIBRARY_DLL "${GSL_CBLAS_LIBRARY}" )
+ string( REPLACE ".lib" ".dll" GSL_LIBRARY_DEBUG_DLL "${GSL_LIBRARY_DEBUG}" )
+ string( REPLACE ".lib" ".dll" GSL_CBLAS_LIBRARY_DEBUG_DLL "${GSL_CBLAS_LIBRARY_DEBUG}" )
+endif()
+
+if( GSL_FOUND AND NOT TARGET GSL::gsl )
+ if( EXISTS "${GSL_LIBRARY_DLL}" AND EXISTS "${GSL_CBLAS_LIBRARY_DLL}")
+
+ # Windows systems with dll libraries.
+ add_library( GSL::gsl SHARED IMPORTED )
+ add_library( GSL::gslcblas SHARED IMPORTED )
+
+ # Windows with dlls, but only Release libraries.
+ set_target_properties( GSL::gslcblas PROPERTIES
+ IMPORTED_LOCATION_RELEASE "${GSL_CBLAS_LIBRARY_DLL}"
+ IMPORTED_IMPLIB "${GSL_CBLAS_LIBRARY}"
+ INTERFACE_INCLUDE_DIRECTORIES "${GSL_INCLUDE_DIRS}"
+ IMPORTED_CONFIGURATIONS Release
+ IMPORTED_LINK_INTERFACE_LANGUAGES "C" )
+ set_target_properties( GSL::gsl PROPERTIES
+ IMPORTED_LOCATION_RELEASE "${GSL_LIBRARY_DLL}"
+ IMPORTED_IMPLIB "${GSL_LIBRARY}"
+ INTERFACE_INCLUDE_DIRECTORIES "${GSL_INCLUDE_DIRS}"
+ IMPORTED_CONFIGURATIONS Release
+ IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+ INTERFACE_LINK_LIBRARIES GSL::gslcblas )
+
+ # If we have both Debug and Release libraries
+ if( EXISTS "${GSL_LIBRARY_DEBUG_DLL}" AND EXISTS "${GSL_CBLAS_LIBRARY_DEBUG_DLL}")
+ set_property( TARGET GSL::gslcblas APPEND PROPERTY IMPORTED_CONFIGURATIONS Debug )
+ set_target_properties( GSL::gslcblas PROPERTIES
+ IMPORTED_LOCATION_DEBUG "${GSL_CBLAS_LIBRARY_DEBUG_DLL}"
+ IMPORTED_IMPLIB_DEBUG "${GSL_CBLAS_LIBRARY_DEBUG}" )
+ set_property( TARGET GSL::gsl APPEND PROPERTY IMPORTED_CONFIGURATIONS Debug )
+ set_target_properties( GSL::gsl PROPERTIES
+ IMPORTED_LOCATION_DEBUG "${GSL_LIBRARY_DEBUG_DLL}"
+ IMPORTED_IMPLIB_DEBUG "${GSL_LIBRARY_DEBUG}" )
+ endif()
+
+ else()
+
+ # For all other environments (ones without dll libraries), create
+ # the imported library targets.
+ add_library( GSL::gsl UNKNOWN IMPORTED )
+ add_library( GSL::gslcblas UNKNOWN IMPORTED )
+ set_target_properties( GSL::gslcblas PROPERTIES
+ IMPORTED_LOCATION "${GSL_CBLAS_LIBRARY}"
+ INTERFACE_INCLUDE_DIRECTORIES "${GSL_INCLUDE_DIRS}"
+ IMPORTED_LINK_INTERFACE_LANGUAGES "C" )
+ set_target_properties( GSL::gsl PROPERTIES
+ IMPORTED_LOCATION "${GSL_LIBRARY}"
+ INTERFACE_INCLUDE_DIRECTORIES "${GSL_INCLUDE_DIRS}"
+ IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+ INTERFACE_LINK_LIBRARIES GSL::gslcblas )
+ endif()
+endif()
diff --git a/Modules/FindGTK.cmake b/Modules/FindGTK.cmake
index 8a44ade41..01bca76c4 100644
--- a/Modules/FindGTK.cmake
+++ b/Modules/FindGTK.cmake
@@ -1,8 +1,15 @@
-# - try to find GTK (and glib) and GTKGLArea
-# GTK_INCLUDE_DIR - Directories to include to use GTK
-# GTK_LIBRARIES - Files to link against to use GTK
-# GTK_FOUND - GTK was found
-# GTK_GL_FOUND - GTK's GL features were found
+#.rst:
+# FindGTK
+# -------
+#
+# try to find GTK (and glib) and GTKGLArea
+#
+# ::
+#
+# GTK_INCLUDE_DIR - Directories to include to use GTK
+# GTK_LIBRARIES - Files to link against to use GTK
+# GTK_FOUND - GTK was found
+# GTK_GL_FOUND - GTK's GL features were found
#=============================================================================
# Copyright 2001-2009 Kitware, Inc.
diff --git a/Modules/FindGTK2.cmake b/Modules/FindGTK2.cmake
index 77aac6dae..6e4a7f2f9 100644
--- a/Modules/FindGTK2.cmake
+++ b/Modules/FindGTK2.cmake
@@ -1,56 +1,99 @@
-# - FindGTK2.cmake
-# This module can find the GTK2 widget libraries and several of its other
-# optional components like gtkmm, glade, and glademm.
+#.rst:
+# FindGTK2
+# --------
+#
+# FindGTK2.cmake
+#
+# This module can find the GTK2 widget libraries and several of its
+# other optional components like gtkmm, glade, and glademm.
#
# NOTE: If you intend to use version checking, CMake 2.6.2 or later is
-# required.
#
-# Specify one or more of the following components
-# as you call this find module. See example below.
+# ::
+#
+# required.
+#
+#
+#
+# Specify one or more of the following components as you call this find
+# module. See example below.
+#
+# ::
+#
+# gtk
+# gtkmm
+# glade
+# glademm
+#
#
-# gtk
-# gtkmm
-# glade
-# glademm
#
# The following variables will be defined for your use
#
-# GTK2_FOUND - Were all of your specified components found?
-# GTK2_INCLUDE_DIRS - All include directories
-# GTK2_LIBRARIES - All libraries
-# GTK2_DEFINITIONS - Additional compiler flags
+# ::
+#
+# GTK2_FOUND - Were all of your specified components found?
+# GTK2_INCLUDE_DIRS - All include directories
+# GTK2_LIBRARIES - All libraries
+# GTK2_TARGETS - All imported targets
+# GTK2_DEFINITIONS - Additional compiler flags
+#
+#
+#
+# ::
+#
+# GTK2_VERSION - The version of GTK2 found (x.y.z)
+# GTK2_MAJOR_VERSION - The major version of GTK2
+# GTK2_MINOR_VERSION - The minor version of GTK2
+# GTK2_PATCH_VERSION - The patch version of GTK2
+#
#
-# GTK2_VERSION - The version of GTK2 found (x.y.z)
-# GTK2_MAJOR_VERSION - The major version of GTK2
-# GTK2_MINOR_VERSION - The minor version of GTK2
-# GTK2_PATCH_VERSION - The patch version of GTK2
#
# Optional variables you can define prior to calling this module:
#
-# GTK2_DEBUG - Enables verbose debugging of the module
-# GTK2_ADDITIONAL_SUFFIXES - Allows defining additional directories to
-# search for include files
+# ::
+#
+# GTK2_DEBUG - Enables verbose debugging of the module
+# GTK2_ADDITIONAL_SUFFIXES - Allows defining additional directories to
+# search for include files
+#
+#
+#
+# ================= Example Usage:
+#
+# ::
+#
+# Call find_package() once, here are some examples to pick from:
+#
#
-#=================
-# Example Usage:
#
-# Call find_package() once, here are some examples to pick from:
+# ::
#
-# Require GTK 2.6 or later
-# find_package(GTK2 2.6 REQUIRED gtk)
+# Require GTK 2.6 or later
+# find_package(GTK2 2.6 REQUIRED gtk)
#
-# Require GTK 2.10 or later and Glade
-# find_package(GTK2 2.10 REQUIRED gtk glade)
#
-# Search for GTK/GTKMM 2.8 or later
-# find_package(GTK2 2.8 COMPONENTS gtk gtkmm)
#
-# if(GTK2_FOUND)
-# include_directories(${GTK2_INCLUDE_DIRS})
-# add_executable(mygui mygui.cc)
-# target_link_libraries(mygui ${GTK2_LIBRARIES})
-# endif()
+# ::
#
+# Require GTK 2.10 or later and Glade
+# find_package(GTK2 2.10 REQUIRED gtk glade)
+#
+#
+#
+# ::
+#
+# Search for GTK/GTKMM 2.8 or later
+# find_package(GTK2 2.8 COMPONENTS gtk gtkmm)
+#
+#
+#
+# ::
+#
+# if(GTK2_FOUND)
+# include_directories(${GTK2_INCLUDE_DIRS})
+# add_executable(mygui mygui.cc)
+# target_link_libraries(mygui ${GTK2_LIBRARIES})
+# endif()
#=============================================================================
# Copyright 2009 Kitware, Inc.
@@ -66,7 +109,10 @@
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
-# Version 1.5 (UNRELEASED) (CMake 2.8.12)
+# Version 1.6 (CMake 3.0)
+# * Create targets for each library
+# * Do not link libfreetype
+# Version 1.5 (CMake 2.8.12)
# * 14236: Detect gthread library
# Detect pangocairo on windows
# Detect pangocairo with gtk module instead of with gtkmm
@@ -130,6 +176,7 @@
#=============================================================
include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake)
function(_GTK2_GET_VERSION _OUT_major _OUT_minor _OUT_micro _gtkversion_hdr)
file(STRINGS ${_gtkversion_hdr} _contents REGEX "#define GTK_M[A-Z]+_VERSION[ \t]+")
@@ -156,6 +203,43 @@ function(_GTK2_GET_VERSION _OUT_major _OUT_minor _OUT_micro _gtkversion_hdr)
endif()
endfunction()
+
+#=============================================================
+# _GTK2_SIGCXX_GET_VERSION
+# Internal function to parse the version number in
+# sigc++config.h
+# _OUT_major = Major version number
+# _OUT_minor = Minor version number
+# _OUT_micro = Micro version number
+# _sigcxxversion_hdr = Header file to parse
+#=============================================================
+
+function(_GTK2_SIGCXX_GET_VERSION _OUT_major _OUT_minor _OUT_micro _sigcxxversion_hdr)
+ file(STRINGS ${_sigcxxversion_hdr} _contents REGEX "#define SIGCXX_M[A-Z]+_VERSION[ \t]+")
+ if(_contents)
+ string(REGEX REPLACE ".*#define SIGCXX_MAJOR_VERSION[ \t]+([0-9]+).*" "\\1" ${_OUT_major} "${_contents}")
+ string(REGEX REPLACE ".*#define SIGCXX_MINOR_VERSION[ \t]+([0-9]+).*" "\\1" ${_OUT_minor} "${_contents}")
+ string(REGEX REPLACE ".*#define SIGCXX_MICRO_VERSION[ \t]+([0-9]+).*" "\\1" ${_OUT_micro} "${_contents}")
+
+ if(NOT ${_OUT_major} MATCHES "[0-9]+")
+ message(FATAL_ERROR "Version parsing failed for SIGCXX_MAJOR_VERSION!")
+ endif()
+ if(NOT ${_OUT_minor} MATCHES "[0-9]+")
+ message(FATAL_ERROR "Version parsing failed for SIGCXX_MINOR_VERSION!")
+ endif()
+ if(NOT ${_OUT_micro} MATCHES "[0-9]+")
+ message(FATAL_ERROR "Version parsing failed for SIGCXX_MICRO_VERSION!")
+ endif()
+
+ set(${_OUT_major} ${${_OUT_major}} PARENT_SCOPE)
+ set(${_OUT_minor} ${${_OUT_minor}} PARENT_SCOPE)
+ set(${_OUT_micro} ${${_OUT_micro}} PARENT_SCOPE)
+ else()
+ message(FATAL_ERROR "Include file ${_gtkversion_hdr} does not exist")
+ endif()
+endfunction()
+
+
#=============================================================
# _GTK2_FIND_INCLUDE_DIR
# Internal function to find the GTK include directories
@@ -214,13 +298,15 @@ function(_GTK2_FIND_INCLUDE_DIR _var _hdr)
message(STATUS "Adding ${_gtk2_arch_dir} to search path for multiarch support")
endif()
endif()
- find_path(${_var}_INCLUDE_DIR ${_hdr}
+ find_path(GTK2_${_var}_INCLUDE_DIR ${_hdr}
PATHS
${_gtk2_arch_dir}
/usr/local/lib64
/usr/local/lib
/usr/lib64
/usr/lib
+ /usr/X11R6/include
+ /usr/X11R6/lib
/opt/gnome/include
/opt/gnome/lib
/opt/openwin/include
@@ -240,9 +326,10 @@ function(_GTK2_FIND_INCLUDE_DIR _var _hdr)
PATH_SUFFIXES
${_suffixes}
)
+ mark_as_advanced(GTK2_${_var}_INCLUDE_DIR)
- if(${_var}_INCLUDE_DIR)
- set(GTK2_INCLUDE_DIRS ${GTK2_INCLUDE_DIRS} ${${_var}_INCLUDE_DIR} PARENT_SCOPE)
+ if(GTK2_${_var}_INCLUDE_DIR)
+ set(GTK2_INCLUDE_DIRS ${GTK2_INCLUDE_DIRS} ${GTK2_${_var}_INCLUDE_DIR} PARENT_SCOPE)
endif()
endfunction()
@@ -332,10 +419,10 @@ function(_GTK2_FIND_LIBRARY _var _lib _expand_vc _append_version)
if(GTK2_DEBUG)
message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
- "While searching for ${_var}_LIBRARY, our proposed library list is ${_lib_list}")
+ "While searching for GTK2_${_var}_LIBRARY, our proposed library list is ${_lib_list}")
endif()
- find_library(${_var}_LIBRARY_RELEASE
+ find_library(GTK2_${_var}_LIBRARY_RELEASE
NAMES ${_lib_list}
PATHS
/opt/gnome/lib
@@ -349,10 +436,10 @@ function(_GTK2_FIND_LIBRARY _var _lib _expand_vc _append_version)
if(_expand_vc AND MSVC)
if(GTK2_DEBUG)
message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
- "While searching for ${_var}_LIBRARY_DEBUG our proposed library list is ${_libd_list}")
+ "While searching for GTK2_${_var}_LIBRARY_DEBUG our proposed library list is ${_libd_list}")
endif()
- find_library(${_var}_LIBRARY_DEBUG
+ find_library(GTK2_${_var}_LIBRARY_DEBUG
NAMES ${_libd_list}
PATHS
$ENV{GTKMM_BASEPATH}/lib
@@ -361,24 +448,155 @@ function(_GTK2_FIND_LIBRARY _var _lib _expand_vc _append_version)
)
endif()
- select_library_configurations(${_var})
+ select_library_configurations(GTK2_${_var})
- set(${_var}_LIBRARY ${${_var}_LIBRARY} PARENT_SCOPE)
+ set(GTK2_${_var}_LIBRARY ${GTK2_${_var}_LIBRARY} PARENT_SCOPE)
+ set(GTK2_${_var}_FOUND ${GTK2_${_var}_FOUND} PARENT_SCOPE)
- set(GTK2_LIBRARIES ${GTK2_LIBRARIES} ${${_var}_LIBRARY})
- set(GTK2_LIBRARIES ${GTK2_LIBRARIES} PARENT_SCOPE)
+ if(GTK2_${_var}_FOUND)
+ set(GTK2_LIBRARIES ${GTK2_LIBRARIES} ${GTK2_${_var}_LIBRARY})
+ set(GTK2_LIBRARIES ${GTK2_LIBRARIES} PARENT_SCOPE)
+ endif()
if(GTK2_DEBUG)
message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
- "${_var}_LIBRARY_RELEASE = \"${${_var}_LIBRARY_RELEASE}\"")
+ "GTK2_${_var}_LIBRARY_RELEASE = \"${GTK2_${_var}_LIBRARY_RELEASE}\"")
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "GTK2_${_var}_LIBRARY_DEBUG = \"${GTK2_${_var}_LIBRARY_DEBUG}\"")
message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
- "${_var}_LIBRARY_DEBUG = \"${${_var}_LIBRARY_DEBUG}\"")
+ "GTK2_${_var}_LIBRARY = \"${GTK2_${_var}_LIBRARY}\"")
message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
- "${_var}_LIBRARY = \"${${_var}_LIBRARY}\"")
+ "GTK2_${_var}_FOUND = \"${GTK2_${_var}_FOUND}\"")
+ endif()
+
+endfunction()
+
+
+function(_GTK2_ADD_TARGET_DEPENDS_INTERNAL _var _property)
+ if(GTK2_DEBUG)
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "_GTK2_ADD_TARGET_DEPENDS_INTERNAL( ${_var} ${_property} )")
+ endif()
+
+ string(TOLOWER "${_var}" _basename)
+
+ if (TARGET GTK2::${_basename})
+ foreach(_depend ${ARGN})
+ set(_valid_depends)
+ if (TARGET GTK2::${_depend})
+ list(APPEND _valid_depends GTK2::${_depend})
+ endif()
+ if (_valid_depends)
+ set_property(TARGET GTK2::${_basename} APPEND PROPERTY ${_property} "${_valid_depends}")
+ endif()
+ set(_valid_depends)
+ endforeach()
+ endif()
+endfunction()
+
+function(_GTK2_ADD_TARGET_DEPENDS _var)
+ if(GTK2_DEBUG)
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "_GTK2_ADD_TARGET_DEPENDS( ${_var} )")
+ endif()
+
+ string(TOLOWER "${_var}" _basename)
+
+ if(TARGET GTK2::${_basename})
+ get_target_property(_configs GTK2::${_basename} IMPORTED_CONFIGURATIONS)
+ _GTK2_ADD_TARGET_DEPENDS_INTERNAL(${_var} INTERFACE_LINK_LIBRARIES ${ARGN})
+ foreach(_config ${_configs})
+ _GTK2_ADD_TARGET_DEPENDS_INTERNAL(${_var} IMPORTED_LINK_INTERFACE_LIBRARIES_${_config} ${ARGN})
+ endforeach()
+ endif()
+endfunction()
+
+function(_GTK2_ADD_TARGET_INCLUDE_DIRS _var)
+ if(GTK2_DEBUG)
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "_GTK2_ADD_TARGET_INCLUDE_DIRS( ${_var} )")
+ endif()
+
+ string(TOLOWER "${_var}" _basename)
+
+ if(TARGET GTK2::${_basename})
+ foreach(_include ${ARGN})
+ set_property(TARGET GTK2::${_basename} APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${_include}")
+ endforeach()
endif()
+endfunction()
+
+#=============================================================
+# _GTK2_ADD_TARGET
+# Internal function to create targets for GTK2
+# _var = target to create
+#=============================================================
+function(_GTK2_ADD_TARGET _var)
+ if(GTK2_DEBUG)
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "_GTK2_ADD_TARGET( ${_var} )")
+ endif()
+
+ string(TOLOWER "${_var}" _basename)
+
+ cmake_parse_arguments(_${_var} "" "" "GTK2_DEPENDS;GTK2_OPTIONAL_DEPENDS;OPTIONAL_INCLUDES" ${ARGN})
+
+ if(GTK2_${_var}_FOUND AND NOT TARGET GTK2::${_basename})
+ # Do not create the target if dependencies are missing
+ foreach(_dep ${_${_var}_GTK2_DEPENDS})
+ if(NOT TARGET GTK2::${_dep})
+ return()
+ endif()
+ endforeach()
+
+ add_library(GTK2::${_basename} UNKNOWN IMPORTED)
+
+ set(GTK2_TARGETS ${GTK2_TARGETS} GTK2::${_basename})
+ set(GTK2_TARGETS ${GTK2_TARGETS} PARENT_SCOPE)
+
+ if(GTK2_${_var}_LIBRARY_RELEASE)
+ set_property(TARGET GTK2::${_basename} APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
+ set_property(TARGET GTK2::${_basename} PROPERTY IMPORTED_LOCATION_RELEASE "${GTK2_${_var}_LIBRARY_RELEASE}" )
+ endif()
+
+ if(GTK2_${_var}_LIBRARY_DEBUG)
+ set_property(TARGET GTK2::${_basename} APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
+ set_property(TARGET GTK2::${_basename} PROPERTY IMPORTED_LOCATION_DEBUG "${GTK2_${_var}_LIBRARY_DEBUG}" )
+ endif()
+
+ if(GTK2_${_var}_INCLUDE_DIR)
+ set_property(TARGET GTK2::${_basename} APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${GTK2_${_var}_INCLUDE_DIR}")
+ endif()
+
+ if(GTK2_${_var}CONFIG_INCLUDE_DIR AND NOT "x${GTK2_${_var}CONFIG_INCLUDE_DIR}" STREQUAL "x${GTK2_${_var}_INCLUDE_DIR}")
+ set_property(TARGET GTK2::${_basename} APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${GTK2_${_var}CONFIG_INCLUDE_DIR}")
+ endif()
+ if(GTK2_DEFINITIONS)
+ set_property(TARGET GTK2::${_basename} PROPERTY INTERFACE_COMPILE_DEFINITIONS "${GTK2_DEFINITIONS}")
+ endif()
+
+ if(_${_var}_GTK2_DEPENDS)
+ _GTK2_ADD_TARGET_DEPENDS(${_var} ${_${_var}_GTK2_DEPENDS} ${_${_var}_GTK2_OPTIONAL_DEPENDS})
+ endif()
+
+ if(_${_var}_OPTIONAL_INCLUDES)
+ foreach(_D ${_${_var}_OPTIONAL_INCLUDES})
+ if(_D)
+ _GTK2_ADD_TARGET_INCLUDE_DIRS(${_var} ${_D})
+ endif()
+ endforeach()
+ endif()
+
+ if(GTK2_USE_IMPORTED_TARGETS)
+ set(GTK2_${_var}_LIBRARY GTK2::${_basename} PARENT_SCOPE)
+ endif()
+
+ endif()
endfunction()
+
+
#=============================================================
#
@@ -388,6 +606,7 @@ endfunction()
set(GTK2_FOUND)
set(GTK2_INCLUDE_DIRS)
set(GTK2_LIBRARIES)
+set(GTK2_TARGETS)
set(GTK2_DEFINITIONS)
if(NOT GTK2_FIND_COMPONENTS)
@@ -399,13 +618,12 @@ endif()
# If specified, enforce version number
#
if(GTK2_FIND_VERSION)
- cmake_minimum_required(VERSION 2.6.2)
set(GTK2_FAILED_VERSION_CHECK true)
if(GTK2_DEBUG)
message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
"Searching for version ${GTK2_FIND_VERSION}")
endif()
- _GTK2_FIND_INCLUDE_DIR(GTK2_GTK gtk/gtk.h)
+ _GTK2_FIND_INCLUDE_DIR(GTK gtk/gtk.h)
if(GTK2_GTK_INCLUDE_DIR)
_GTK2_GET_VERSION(GTK2_MAJOR_VERSION
GTK2_MINOR_VERSION
@@ -446,104 +664,209 @@ if(GTK2_FIND_VERSION)
endif()
#
+# On MSVC, according to https://wiki.gnome.org/gtkmm/MSWindows, the /vd2 flag needs to be
+# passed to the compiler in order to use gtkmm
+#
+if(MSVC)
+ foreach(_GTK2_component ${GTK2_FIND_COMPONENTS})
+ if(_GTK2_component STREQUAL "gtkmm")
+ set(GTK2_DEFINITIONS "/vd2")
+ elseif(_GTK2_component STREQUAL "glademm")
+ set(GTK2_DEFINITIONS "/vd2")
+ endif()
+ endforeach()
+endif()
+
+#
# Find all components
#
-find_package(Freetype)
-list(APPEND GTK2_INCLUDE_DIRS ${FREETYPE_INCLUDE_DIRS})
-list(APPEND GTK2_LIBRARIES ${FREETYPE_LIBRARIES})
+find_package(Freetype QUIET)
+if(FREETYPE_INCLUDE_DIR_ft2build AND FREETYPE_INCLUDE_DIR_freetype2)
+ list(APPEND GTK2_INCLUDE_DIRS ${FREETYPE_INCLUDE_DIR_ft2build} ${FREETYPE_INCLUDE_DIR_freetype2})
+endif()
foreach(_GTK2_component ${GTK2_FIND_COMPONENTS})
if(_GTK2_component STREQUAL "gtk")
- _GTK2_FIND_INCLUDE_DIR(GTK2_GTK gtk/gtk.h)
+ # Left for compatibility with previous versions.
+ _GTK2_FIND_INCLUDE_DIR(FONTCONFIG fontconfig/fontconfig.h)
+ _GTK2_FIND_INCLUDE_DIR(X11 X11/Xlib.h)
- if(UNIX)
- _GTK2_FIND_LIBRARY (GTK2_GTK gtk-x11 false true)
- _GTK2_FIND_LIBRARY (GTK2_GDK gdk-x11 false true)
- else()
- _GTK2_FIND_LIBRARY (GTK2_GTK gtk-win32 false true)
- _GTK2_FIND_LIBRARY (GTK2_GDK gdk-win32 false true)
- endif()
-
- _GTK2_FIND_INCLUDE_DIR(GTK2_GDK gdk/gdk.h)
- _GTK2_FIND_INCLUDE_DIR(GTK2_GDKCONFIG gdkconfig.h)
+ _GTK2_FIND_INCLUDE_DIR(GLIB glib.h)
+ _GTK2_FIND_INCLUDE_DIR(GLIBCONFIG glibconfig.h)
+ _GTK2_FIND_LIBRARY (GLIB glib false true)
+ _GTK2_ADD_TARGET (GLIB)
- _GTK2_FIND_INCLUDE_DIR(GTK2_CAIRO cairo.h)
- _GTK2_FIND_LIBRARY (GTK2_CAIRO cairo false false)
+ _GTK2_FIND_INCLUDE_DIR(GOBJECT glib-object.h)
+ _GTK2_FIND_LIBRARY (GOBJECT gobject false true)
+ _GTK2_ADD_TARGET (GOBJECT GTK2_DEPENDS glib)
- _GTK2_FIND_INCLUDE_DIR(GTK2_FONTCONFIG fontconfig/fontconfig.h)
+ _GTK2_FIND_INCLUDE_DIR(ATK atk/atk.h)
+ _GTK2_FIND_LIBRARY (ATK atk false true)
+ _GTK2_ADD_TARGET (ATK GTK2_DEPENDS gobject glib)
- _GTK2_FIND_INCLUDE_DIR(GTK2_PANGO pango/pango.h)
- _GTK2_FIND_LIBRARY (GTK2_PANGO pango false true)
+ _GTK2_FIND_LIBRARY (GIO gio false true)
+ _GTK2_ADD_TARGET (GIO GTK2_DEPENDS gobject glib)
- _GTK2_FIND_LIBRARY (GTK2_PANGOCAIRO pangocairo false true)
+ _GTK2_FIND_LIBRARY (GTHREAD gthread false true)
+ _GTK2_ADD_TARGET (GTHREAD GTK2_DEPENDS glib)
- _GTK2_FIND_LIBRARY (GTK2_PANGOFT2 pangoft2 false true)
+ _GTK2_FIND_LIBRARY (GMODULE gmodule false true)
+ _GTK2_ADD_TARGET (GMODULE GTK2_DEPENDS glib)
- _GTK2_FIND_LIBRARY (GTK2_PANGOXFT pangoxft false true)
+ _GTK2_FIND_INCLUDE_DIR(GDK_PIXBUF gdk-pixbuf/gdk-pixbuf.h)
+ _GTK2_FIND_LIBRARY (GDK_PIXBUF gdk_pixbuf false true)
+ _GTK2_ADD_TARGET (GDK_PIXBUF GTK2_DEPENDS gobject glib)
- _GTK2_FIND_INCLUDE_DIR(GTK2_GDK_PIXBUF gdk-pixbuf/gdk-pixbuf.h)
- _GTK2_FIND_LIBRARY (GTK2_GDK_PIXBUF gdk_pixbuf false true)
+ _GTK2_FIND_INCLUDE_DIR(CAIRO cairo.h)
+ _GTK2_FIND_LIBRARY (CAIRO cairo false false)
+ _GTK2_ADD_TARGET (CAIRO)
- _GTK2_FIND_LIBRARY (GTK2_GTHREAD gthread false true)
+ _GTK2_FIND_INCLUDE_DIR(PANGO pango/pango.h)
+ _GTK2_FIND_LIBRARY (PANGO pango false true)
+ _GTK2_ADD_TARGET (PANGO GTK2_DEPENDS gobject glib)
- _GTK2_FIND_LIBRARY (GTK2_GMODULE gmodule false true)
+ _GTK2_FIND_LIBRARY (PANGOCAIRO pangocairo false true)
+ _GTK2_ADD_TARGET (PANGOCAIRO GTK2_DEPENDS pango cairo gobject glib)
- _GTK2_FIND_LIBRARY (GTK2_GIO gio false true)
+ _GTK2_FIND_LIBRARY (PANGOFT2 pangoft2 false true)
+ _GTK2_ADD_TARGET (PANGOFT2 GTK2_DEPENDS pango gobject glib
+ OPTIONAL_INCLUDES ${FREETYPE_INCLUDE_DIR_ft2build} ${FREETYPE_INCLUDE_DIR_freetype2}
+ ${GTK2_FONTCONFIG_INCLUDE_DIR}
+ ${GTK2_X11_INCLUDE_DIR})
- _GTK2_FIND_INCLUDE_DIR(GTK2_ATK atk/atk.h)
- _GTK2_FIND_LIBRARY (GTK2_ATK atk false true)
+ _GTK2_FIND_LIBRARY (PANGOXFT pangoxft false true)
+ _GTK2_ADD_TARGET (PANGOXFT GTK2_DEPENDS pangoft2 pango gobject glib
+ OPTIONAL_INCLUDES ${FREETYPE_INCLUDE_DIR_ft2build} ${FREETYPE_INCLUDE_DIR_freetype2}
+ ${GTK2_FONTCONFIG_INCLUDE_DIR}
+ ${GTK2_X11_INCLUDE_DIR})
- _GTK2_FIND_INCLUDE_DIR(GTK2_GOBJECT gobject/gobject.h)
- _GTK2_FIND_LIBRARY (GTK2_GOBJECT gobject false true)
+ _GTK2_FIND_INCLUDE_DIR(GDK gdk/gdk.h)
+ _GTK2_FIND_INCLUDE_DIR(GDKCONFIG gdkconfig.h)
+ if(UNIX)
+ if(APPLE)
+ _GTK2_FIND_LIBRARY (GDK gdk-quartz false true)
+ endif()
+ if(NOT GTK2_GDK_FOUND)
+ _GTK2_FIND_LIBRARY (GDK gdk-x11 false true)
+ endif()
+ else()
+ _GTK2_FIND_LIBRARY (GDK gdk-win32 false true)
+ endif()
+ _GTK2_ADD_TARGET (GDK GTK2_DEPENDS pango gdk_pixbuf gobject glib
+ GTK2_OPTIONAL_DEPENDS pangocairo cairo)
- _GTK2_FIND_INCLUDE_DIR(GTK2_GLIB glib.h)
- _GTK2_FIND_INCLUDE_DIR(GTK2_GLIBCONFIG glibconfig.h)
- _GTK2_FIND_LIBRARY (GTK2_GLIB glib false true)
+ _GTK2_FIND_INCLUDE_DIR(GTK gtk/gtk.h)
+ if(UNIX)
+ if(APPLE)
+ _GTK2_FIND_LIBRARY (GTK gtk-quartz false true)
+ endif()
+ if(NOT GTK2_GTK_FOUND)
+ _GTK2_FIND_LIBRARY (GTK gtk-x11 false true)
+ endif()
+ else()
+ _GTK2_FIND_LIBRARY (GTK gtk-win32 false true)
+ endif()
+ _GTK2_ADD_TARGET (GTK GTK2_DEPENDS gdk atk pangoft2 pango gdk_pixbuf gthread gobject glib
+ GTK2_OPTIONAL_DEPENDS gio pangocairo cairo)
elseif(_GTK2_component STREQUAL "gtkmm")
- _GTK2_FIND_INCLUDE_DIR(GTK2_GTKMM gtkmm.h)
- _GTK2_FIND_INCLUDE_DIR(GTK2_GTKMMCONFIG gtkmmconfig.h)
- _GTK2_FIND_LIBRARY (GTK2_GTKMM gtkmm true true)
-
- _GTK2_FIND_INCLUDE_DIR(GTK2_GDKMM gdkmm.h)
- _GTK2_FIND_INCLUDE_DIR(GTK2_GDKMMCONFIG gdkmmconfig.h)
- _GTK2_FIND_LIBRARY (GTK2_GDKMM gdkmm true true)
-
- _GTK2_FIND_INCLUDE_DIR(GTK2_PANGOMM pangomm.h)
- _GTK2_FIND_INCLUDE_DIR(GTK2_PANGOMMCONFIG pangommconfig.h)
- _GTK2_FIND_LIBRARY (GTK2_PANGOMM pangomm true true)
-
- _GTK2_FIND_INCLUDE_DIR(GTK2_CAIROMM cairomm/cairomm.h)
- _GTK2_FIND_INCLUDE_DIR(GTK2_CAIROMMCONFIG cairommconfig.h)
- _GTK2_FIND_LIBRARY (GTK2_CAIROMM cairomm true true)
-
- _GTK2_FIND_INCLUDE_DIR(GTK2_GIOMM giomm.h)
- _GTK2_FIND_INCLUDE_DIR(GTK2_GIOMMCONFIG giommconfig.h)
- _GTK2_FIND_LIBRARY (GTK2_GIOMM giomm true true)
-
- _GTK2_FIND_INCLUDE_DIR(GTK2_ATKMM atkmm.h)
- _GTK2_FIND_LIBRARY (GTK2_ATKMM atkmm true true)
-
- _GTK2_FIND_INCLUDE_DIR(GTK2_GLIBMM glibmm.h)
- _GTK2_FIND_INCLUDE_DIR(GTK2_GLIBMMCONFIG glibmmconfig.h)
- _GTK2_FIND_LIBRARY (GTK2_GLIBMM glibmm true true)
+ _GTK2_FIND_INCLUDE_DIR(SIGC++ sigc++/sigc++.h)
+ _GTK2_FIND_INCLUDE_DIR(SIGC++CONFIG sigc++config.h)
+ _GTK2_FIND_LIBRARY (SIGC++ sigc true true)
+ _GTK2_ADD_TARGET (SIGC++)
+ # Since sigc++ 2.5.1 c++11 support is required
+ if(GTK2_SIGC++CONFIG_INCLUDE_DIR)
+ _GTK2_SIGCXX_GET_VERSION(GTK2_SIGC++_VERSION_MAJOR
+ GTK2_SIGC++_VERSION_MINOR
+ GTK2_SIGC++_VERSION_MICRO
+ ${GTK2_SIGC++CONFIG_INCLUDE_DIR}/sigc++config.h)
+ if(NOT ${GTK2_SIGC++_VERSION_MAJOR}.${GTK2_SIGC++_VERSION_MINOR}.${GTK2_SIGC++_VERSION_MICRO} VERSION_LESS 2.5.1)
+ # These are the features needed by clients in order to include the
+ # project headers:
+ set_property(TARGET GTK2::sigc++
+ PROPERTY INTERFACE_COMPILE_FEATURES cxx_alias_templates
+ cxx_auto_type
+ cxx_decltype
+ cxx_deleted_functions
+ cxx_noexcept
+ cxx_nullptr
+ cxx_right_angle_brackets
+ cxx_rvalue_references
+ cxx_variadic_templates)
+ endif()
+ endif()
- _GTK2_FIND_INCLUDE_DIR(GTK2_SIGC++ sigc++/sigc++.h)
- _GTK2_FIND_INCLUDE_DIR(GTK2_SIGC++CONFIG sigc++config.h)
- _GTK2_FIND_LIBRARY (GTK2_SIGC++ sigc true true)
+ _GTK2_FIND_INCLUDE_DIR(GLIBMM glibmm.h)
+ _GTK2_FIND_INCLUDE_DIR(GLIBMMCONFIG glibmmconfig.h)
+ _GTK2_FIND_LIBRARY (GLIBMM glibmm true true)
+ _GTK2_ADD_TARGET (GLIBMM GTK2_DEPENDS gobject sigc++ glib)
+
+ _GTK2_FIND_INCLUDE_DIR(GIOMM giomm.h)
+ _GTK2_FIND_INCLUDE_DIR(GIOMMCONFIG giommconfig.h)
+ _GTK2_FIND_LIBRARY (GIOMM giomm true true)
+ _GTK2_ADD_TARGET (GIOMM GTK2_DEPENDS gio glibmm gobject sigc++ glib)
+
+ _GTK2_FIND_INCLUDE_DIR(ATKMM atkmm.h)
+ _GTK2_FIND_LIBRARY (ATKMM atkmm true true)
+ _GTK2_ADD_TARGET (ATKMM GTK2_DEPENDS atk glibmm gobject sigc++ glib)
+
+ _GTK2_FIND_INCLUDE_DIR(CAIROMM cairomm/cairomm.h)
+ _GTK2_FIND_INCLUDE_DIR(CAIROMMCONFIG cairommconfig.h)
+ _GTK2_FIND_LIBRARY (CAIROMM cairomm true true)
+ _GTK2_ADD_TARGET (CAIROMM GTK2_DEPENDS cairo sigc++
+ OPTIONAL_INCLUDES ${FREETYPE_INCLUDE_DIR_ft2build} ${FREETYPE_INCLUDE_DIR_freetype2}
+ ${GTK2_FONTCONFIG_INCLUDE_DIR}
+ ${GTK2_X11_INCLUDE_DIR})
+
+ _GTK2_FIND_INCLUDE_DIR(PANGOMM pangomm.h)
+ _GTK2_FIND_INCLUDE_DIR(PANGOMMCONFIG pangommconfig.h)
+ _GTK2_FIND_LIBRARY (PANGOMM pangomm true true)
+ _GTK2_ADD_TARGET (PANGOMM GTK2_DEPENDS glibmm sigc++ pango gobject glib
+ GTK2_OPTIONAL_DEPENDS cairomm pangocairo cairo
+ OPTIONAL_INCLUDES ${FREETYPE_INCLUDE_DIR_ft2build} ${FREETYPE_INCLUDE_DIR_freetype2}
+ ${GTK2_FONTCONFIG_INCLUDE_DIR}
+ ${GTK2_X11_INCLUDE_DIR})
+
+ _GTK2_FIND_INCLUDE_DIR(GDKMM gdkmm.h)
+ _GTK2_FIND_INCLUDE_DIR(GDKMMCONFIG gdkmmconfig.h)
+ _GTK2_FIND_LIBRARY (GDKMM gdkmm true true)
+ _GTK2_ADD_TARGET (GDKMM GTK2_DEPENDS pangomm gtk glibmm sigc++ gdk atk pangoft2 gdk_pixbuf pango gobject glib
+ GTK2_OPTIONAL_DEPENDS giomm cairomm gio pangocairo cairo
+ OPTIONAL_INCLUDES ${FREETYPE_INCLUDE_DIR_ft2build} ${FREETYPE_INCLUDE_DIR_freetype2}
+ ${GTK2_FONTCONFIG_INCLUDE_DIR}
+ ${GTK2_X11_INCLUDE_DIR})
+
+ _GTK2_FIND_INCLUDE_DIR(GTKMM gtkmm.h)
+ _GTK2_FIND_INCLUDE_DIR(GTKMMCONFIG gtkmmconfig.h)
+ _GTK2_FIND_LIBRARY (GTKMM gtkmm true true)
+ _GTK2_ADD_TARGET (GTKMM GTK2_DEPENDS atkmm gdkmm pangomm gtk glibmm sigc++ gdk atk pangoft2 gdk_pixbuf pango gthread gobject glib
+ GTK2_OPTIONAL_DEPENDS giomm cairomm gio pangocairo cairo
+ OPTIONAL_INCLUDES ${FREETYPE_INCLUDE_DIR_ft2build} ${FREETYPE_INCLUDE_DIR_freetype2}
+ ${GTK2_FONTCONFIG_INCLUDE_DIR}
+ ${GTK2_X11_INCLUDE_DIR})
elseif(_GTK2_component STREQUAL "glade")
- _GTK2_FIND_INCLUDE_DIR(GTK2_GLADE glade/glade.h)
- _GTK2_FIND_LIBRARY (GTK2_GLADE glade false true)
+ _GTK2_FIND_INCLUDE_DIR(GLADE glade/glade.h)
+ _GTK2_FIND_LIBRARY (GLADE glade false true)
+ _GTK2_ADD_TARGET (GLADE GTK2_DEPENDS gtk gdk atk gio pangoft2 gdk_pixbuf pango gobject glib
+ GTK2_OPTIONAL_DEPENDS pangocairo cairo
+ OPTIONAL_INCLUDES ${FREETYPE_INCLUDE_DIR_ft2build} ${FREETYPE_INCLUDE_DIR_freetype2}
+ ${GTK2_FONTCONFIG_INCLUDE_DIR}
+ ${GTK2_X11_INCLUDE_DIR})
elseif(_GTK2_component STREQUAL "glademm")
- _GTK2_FIND_INCLUDE_DIR(GTK2_GLADEMM libglademm.h)
- _GTK2_FIND_INCLUDE_DIR(GTK2_GLADEMMCONFIG libglademmconfig.h)
- _GTK2_FIND_LIBRARY (GTK2_GLADEMM glademm true true)
+ _GTK2_FIND_INCLUDE_DIR(GLADEMM libglademm.h)
+ _GTK2_FIND_INCLUDE_DIR(GLADEMMCONFIG libglademmconfig.h)
+ _GTK2_FIND_LIBRARY (GLADEMM glademm true true)
+ _GTK2_ADD_TARGET (GLADEMM GTK2_DEPENDS gtkmm glade atkmm gdkmm giomm pangomm glibmm sigc++ gtk gdk atk pangoft2 gdk_pixbuf pango gthread gobject glib
+ GTK2_OPTIONAL_DEPENDS giomm cairomm gio pangocairo cairo
+ OPTIONAL_INCLUDES ${FREETYPE_INCLUDE_DIR_ft2build} ${FREETYPE_INCLUDE_DIR_freetype2}
+ ${GTK2_FONTCONFIG_INCLUDE_DIR}
+ ${GTK2_X11_INCLUDE_DIR})
else()
message(FATAL_ERROR "Unknown GTK2 component ${_component}")
@@ -562,20 +885,6 @@ if(NOT GTK2_FIND_VERSION AND GTK2_GTK_INCLUDE_DIR)
endif()
#
-# On MSVC, according to https://wiki.gnome.org/gtkmm/MSWindows, the /vd2 flag needs to be
-# passed to the compiler in order to use gtkmm
-#
-if(MSVC)
- foreach(_GTK2_component ${GTK2_FIND_COMPONENTS})
- if(_GTK2_component STREQUAL "gtkmm")
- set(GTK2_DEFINITIONS "/vd2")
- elseif(_GTK2_component STREQUAL "glademm")
- set(GTK2_DEFINITIONS "/vd2")
- endif()
- endforeach()
-endif()
-
-#
# Try to enforce components
#
@@ -586,6 +895,8 @@ include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
foreach(_GTK2_component ${GTK2_FIND_COMPONENTS})
string(TOUPPER ${_GTK2_component} _COMPONENT_UPPER)
+ set(GTK2_${_COMPONENT_UPPER}_FIND_QUIETLY ${GTK2_FIND_QUIETLY})
+
if(_GTK2_component STREQUAL "gtk")
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "Some or all of the gtk libraries were not found."
GTK2_GTK_LIBRARY
@@ -613,6 +924,8 @@ foreach(_GTK2_component ${GTK2_FIND_COMPONENTS})
GTK2_GLIBMMCONFIG_INCLUDE_DIR
GTK2_GLIBMM_LIBRARY
+ FREETYPE_INCLUDE_DIR_ft2build
+ FREETYPE_INCLUDE_DIR_freetype2
)
elseif(_GTK2_component STREQUAL "glade")
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "The glade library was not found."
@@ -632,6 +945,11 @@ foreach(_GTK2_component ${GTK2_FIND_COMPONENTS})
endif()
endforeach()
+if(GTK2_USE_IMPORTED_TARGETS)
+ set(GTK2_LIBRARIES ${GTK2_TARGETS})
+endif()
+
+
if(_GTK2_did_we_find_everything AND NOT GTK2_VERSION_CHECK_FAILED)
set(GTK2_FOUND true)
else()
@@ -643,6 +961,7 @@ else()
set(GTK2_VERSION_PATCH)
set(GTK2_INCLUDE_DIRS)
set(GTK2_LIBRARIES)
+ set(GTK2_TARGETS)
set(GTK2_DEFINITIONS)
endif()
diff --git a/Modules/FindGTest.cmake b/Modules/FindGTest.cmake
index d531dd12d..ca49e4aca 100644
--- a/Modules/FindGTest.cmake
+++ b/Modules/FindGTest.cmake
@@ -1,58 +1,95 @@
+#.rst:
+# FindGTest
+# ---------
+#
# Locate the Google C++ Testing Framework.
#
-# Defines the following variables:
+# Imported targets
+# ^^^^^^^^^^^^^^^^
+#
+# This module defines the following :prop_tgt:`IMPORTED` targets:
+#
+# ``GTest::GTest``
+# The Google Test ``gtest`` library, if found; adds Thread::Thread
+# automatically
+# ``GTest::Main``
+# The Google Test ``gtest_main`` library, if found
+#
+#
+# Result variables
+# ^^^^^^^^^^^^^^^^
+#
+# This module will set the following variables in your project:
+#
+# ``GTEST_FOUND``
+# Found the Google Testing framework
+# ``GTEST_INCLUDE_DIRS``
+# the directory containing the Google Test headers
+#
+# The library variables below are set as normal variables. These
+# contain debug/optimized keywords when a debugging library is found.
+#
+# ``GTEST_LIBRARIES``
+# The Google Test ``gtest`` library; note it also requires linking
+# with an appropriate thread library
+# ``GTEST_MAIN_LIBRARIES``
+# The Google Test ``gtest_main`` library
+# ``GTEST_BOTH_LIBRARIES``
+# Both ``gtest`` and ``gtest_main``
#
-# GTEST_FOUND - Found the Google Testing framework
-# GTEST_INCLUDE_DIRS - Include directories
+# Cache variables
+# ^^^^^^^^^^^^^^^
#
-# Also defines the library variables below as normal
-# variables. These contain debug/optimized keywords when
-# a debugging library is found.
+# The following cache variables may also be set:
#
-# GTEST_BOTH_LIBRARIES - Both libgtest & libgtest-main
-# GTEST_LIBRARIES - libgtest
-# GTEST_MAIN_LIBRARIES - libgtest-main
+# ``GTEST_ROOT``
+# The root directory of the Google Test installation (may also be
+# set as an environment variable)
+# ``GTEST_MSVC_SEARCH``
+# If compiling with MSVC, this variable can be set to ``MD`` or
+# ``MT`` (the default) to enable searching a GTest build tree
#
-# Accepts the following variables as input:
#
-# GTEST_ROOT - (as a CMake or environment variable)
-# The root directory of the gtest install prefix
+# Example usage
+# ^^^^^^^^^^^^^
#
-# GTEST_MSVC_SEARCH - If compiling with MSVC, this variable can be set to
-# "MD" or "MT" to enable searching a GTest build tree
-# (defaults: "MD")
+# ::
#
-#-----------------------
-# Example Usage:
+# enable_testing()
+# find_package(GTest REQUIRED)
#
-# enable_testing()
-# find_package(GTest REQUIRED)
-# include_directories(${GTEST_INCLUDE_DIRS})
+# add_executable(foo foo.cc)
+# target_link_libraries(foo GTest::GTest GTest::Main)
#
-# add_executable(foo foo.cc)
-# target_link_libraries(foo ${GTEST_BOTH_LIBRARIES})
+# add_test(AllTestsInFoo foo)
#
-# add_test(AllTestsInFoo foo)
#
-#-----------------------
+# Deeper integration with CTest
+# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#
-# If you would like each Google test to show up in CTest as
-# a test you may use the following macro.
-# NOTE: It will slow down your tests by running an executable
-# for each test and test fixture. You will also have to rerun
-# CMake after adding or removing tests or test fixtures.
+# If you would like each Google test to show up in CTest as a test you
+# may use the following macro::
#
-# GTEST_ADD_TESTS(executable extra_args ARGN)
-# executable = The path to the test executable
-# extra_args = Pass a list of extra arguments to be passed to
-# executable enclosed in quotes (or "" for none)
-# ARGN = A list of source files to search for tests & test
-# fixtures.
+# GTEST_ADD_TESTS(executable extra_args files...)
#
-# Example:
-# set(FooTestArgs --foo 1 --bar 2)
-# add_executable(FooTest FooUnitTest.cc)
-# GTEST_ADD_TESTS(FooTest "${FooTestArgs}" FooUnitTest.cc)
+# ``executable``
+# the path to the test executable
+# ``extra_args``
+# a list of extra arguments to be passed to executable enclosed in
+# quotes (or ``""`` for none)
+# ``files...``
+# a list of source files to search for tests and test fixtures. Or
+# ``AUTO`` to find them from executable target
+#
+# However, note that this macro will slow down your tests by running
+# an executable for each test and test fixture. You will also have to
+# re-run CMake after adding or removing tests or test fixtures.
+#
+# Example usage::
+#
+# set(FooTestArgs --foo 1 --bar 2)
+# add_executable(FooTest FooUnitTest.cc)
+# GTEST_ADD_TESTS(FooTest "${FooTestArgs}" AUTO)
#=============================================================================
# Copyright 2009 Kitware, Inc.
@@ -75,12 +112,30 @@ function(GTEST_ADD_TESTS executable extra_args)
if(NOT ARGN)
message(FATAL_ERROR "Missing ARGN: Read the documentation for GTEST_ADD_TESTS")
endif()
+ if(ARGN STREQUAL "AUTO")
+ # obtain sources used for building that executable
+ get_property(ARGN TARGET ${executable} PROPERTY SOURCES)
+ endif()
+ set(gtest_case_name_regex ".*\\( *([A-Za-z_0-9]+) *, *([A-Za-z_0-9]+) *\\).*")
+ set(gtest_test_type_regex "(TYPED_TEST|TEST_?[FP]?)")
foreach(source ${ARGN})
file(READ "${source}" contents)
- string(REGEX MATCHALL "TEST_?F?\\(([A-Za-z_0-9 ,]+)\\)" found_tests ${contents})
+ string(REGEX MATCHALL "${gtest_test_type_regex} *\\(([A-Za-z_0-9 ,]+)\\)" found_tests ${contents})
foreach(hit ${found_tests})
- string(REGEX REPLACE ".*\\( *([A-Za-z_0-9]+), *([A-Za-z_0-9]+) *\\).*" "\\1.\\2" test_name ${hit})
- add_test(${test_name} ${executable} --gtest_filter=${test_name} ${extra_args})
+ string(REGEX MATCH "${gtest_test_type_regex}" test_type ${hit})
+
+ # Parameterized tests have a different signature for the filter
+ if("x${test_type}" STREQUAL "xTEST_P")
+ string(REGEX REPLACE ${gtest_case_name_regex} "*/\\1.\\2/*" test_name ${hit})
+ elseif("x${test_type}" STREQUAL "xTEST_F" OR "x${test_type}" STREQUAL "xTEST")
+ string(REGEX REPLACE ${gtest_case_name_regex} "\\1.\\2" test_name ${hit})
+ elseif("x${test_type}" STREQUAL "xTYPED_TEST")
+ string(REGEX REPLACE ${gtest_case_name_regex} "\\1/*.\\2" test_name ${hit})
+ else()
+ message(WARNING "Could not parse GTest ${hit} for adding to CTest.")
+ continue()
+ endif()
+ add_test(NAME ${test_name} COMMAND ${executable} --gtest_filter=${test_name} ${extra_args})
endforeach()
endforeach()
endfunction()
@@ -154,5 +209,60 @@ if(GTEST_FOUND)
_gtest_append_debugs(GTEST_LIBRARIES GTEST_LIBRARY)
_gtest_append_debugs(GTEST_MAIN_LIBRARIES GTEST_MAIN_LIBRARY)
set(GTEST_BOTH_LIBRARIES ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES})
-endif()
+ include(CMakeFindDependencyMacro)
+ find_dependency(Threads)
+
+ if(NOT TARGET GTest::GTest)
+ add_library(GTest::GTest UNKNOWN IMPORTED)
+ set_target_properties(GTest::GTest PROPERTIES
+ INTERFACE_LINK_LIBRARIES "Threads::Threads")
+ if(GTEST_INCLUDE_DIRS)
+ set_target_properties(GTest::GTest PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${GTEST_INCLUDE_DIRS}")
+ endif()
+ if(EXISTS "${GTEST_LIBRARY}")
+ set_target_properties(GTest::GTest PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
+ IMPORTED_LOCATION "${GTEST_LIBRARY}")
+ endif()
+ if(EXISTS "${GTEST_LIBRARY_DEBUG}")
+ set_property(TARGET GTest::GTest APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS DEBUG)
+ set_target_properties(GTest::GTest PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX"
+ IMPORTED_LOCATION_DEBUG "${GTEST_LIBRARY_DEBUG}")
+ endif()
+ if(EXISTS "${GTEST_LIBRARY_RELEASE}")
+ set_property(TARGET GTest::GTest APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS RELEASE)
+ set_target_properties(GTest::GTest PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
+ IMPORTED_LOCATION_RELEASE "${GTEST_LIBRARY_RELEASE}")
+ endif()
+ endif()
+ if(NOT TARGET GTest::Main)
+ add_library(GTest::Main UNKNOWN IMPORTED)
+ set_target_properties(GTest::Main PROPERTIES
+ INTERFACE_LINK_LIBRARIES "GTest::GTest")
+ if(EXISTS "${GTEST_MAIN_LIBRARY}")
+ set_target_properties(GTest::Main PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
+ IMPORTED_LOCATION "${GTEST_MAIN_LIBRARY}")
+ endif()
+ if(EXISTS "${GTEST_MAIN_LIBRARY_DEBUG}")
+ set_property(TARGET GTest::Main APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS DEBUG)
+ set_target_properties(GTest::Main PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX"
+ IMPORTED_LOCATION_DEBUG "${GTEST_MAIN_LIBRARY_DEBUG}")
+ endif()
+ if(EXISTS "${GTEST_MAIN_LIBRARY_RELEASE}")
+ set_property(TARGET GTest::Main APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS RELEASE)
+ set_target_properties(GTest::Main PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
+ IMPORTED_LOCATION_RELEASE "${GTEST_MAIN_LIBRARY_RELEASE}")
+ endif()
+ endif()
+endif()
diff --git a/Modules/FindGettext.cmake b/Modules/FindGettext.cmake
index 1a6bd39dd..ac53c3fe3 100644
--- a/Modules/FindGettext.cmake
+++ b/Modules/FindGettext.cmake
@@ -1,29 +1,58 @@
-# - Find GNU gettext tools
-# This module looks for the GNU gettext tools. This module defines the
+#.rst:
+# FindGettext
+# -----------
+#
+# Find GNU gettext tools
+#
+# This module looks for the GNU gettext tools. This module defines the
# following values:
-# GETTEXT_MSGMERGE_EXECUTABLE: the full path to the msgmerge tool.
-# GETTEXT_MSGFMT_EXECUTABLE: the full path to the msgfmt tool.
-# GETTEXT_FOUND: True if gettext has been found.
-# GETTEXT_VERSION_STRING: the version of gettext found (since CMake 2.8.8)
+#
+# ::
+#
+# GETTEXT_MSGMERGE_EXECUTABLE: the full path to the msgmerge tool.
+# GETTEXT_MSGFMT_EXECUTABLE: the full path to the msgfmt tool.
+# GETTEXT_FOUND: True if gettext has been found.
+# GETTEXT_VERSION_STRING: the version of gettext found (since CMake 2.8.8)
+#
+#
#
# Additionally it provides the following macros:
-# GETTEXT_CREATE_TRANSLATIONS ( outputFile [ALL] file1 ... fileN )
-# This will create a target "translations" which will convert the
-# given input po files into the binary output mo file. If the
-# ALL option is used, the translations will also be created when
-# building the default target.
-# GETTEXT_PROCESS_POT( <potfile> [ALL] [INSTALL_DESTINATION <destdir>] LANGUAGES <lang1> <lang2> ... )
-# Process the given pot file to mo files.
-# If INSTALL_DESTINATION is given then automatically install rules will be created,
-# the language subdirectory will be taken into account (by default use share/locale/).
-# If ALL is specified, the pot file is processed when building the all traget.
-# It creates a custom target "potfile".
-# GETTEXT_PROCESS_PO_FILES( <lang> [ALL] [INSTALL_DESTINATION <dir>] PO_FILES <po1> <po2> ... )
-# Process the given po files to mo files for the given language.
-# If INSTALL_DESTINATION is given then automatically install rules will be created,
-# the language subdirectory will be taken into account (by default use share/locale/).
-# If ALL is specified, the po files are processed when building the all traget.
-# It creates a custom target "pofiles".
+#
+# GETTEXT_CREATE_TRANSLATIONS ( outputFile [ALL] file1 ... fileN )
+#
+# ::
+#
+# This will create a target "translations" which will convert the
+# given input po files into the binary output mo file. If the
+# ALL option is used, the translations will also be created when
+# building the default target.
+#
+# GETTEXT_PROCESS_POT_FILE( <potfile> [ALL] [INSTALL_DESTINATION <destdir>]
+# LANGUAGES <lang1> <lang2> ... )
+#
+# ::
+#
+# Process the given pot file to mo files.
+# If INSTALL_DESTINATION is given then automatically install rules will
+# be created, the language subdirectory will be taken into account
+# (by default use share/locale/).
+# If ALL is specified, the pot file is processed when building the all traget.
+# It creates a custom target "potfile".
+#
+# GETTEXT_PROCESS_PO_FILES( <lang> [ALL] [INSTALL_DESTINATION <dir>]
+# PO_FILES <po1> <po2> ... )
+#
+# ::
+#
+# Process the given po files to mo files for the given language.
+# If INSTALL_DESTINATION is given then automatically install rules will
+# be created, the language subdirectory will be taken into account
+# (by default use share/locale/).
+# If ALL is specified, the po files are processed when building the all traget.
+# It creates a custom target "pofiles".
+#
+# .. note::
+# If you wish to use the Gettext library (libintl), use :module:`FindIntl`.
#=============================================================================
# Copyright 2007-2009 Kitware, Inc.
@@ -48,8 +77,8 @@ if(GETTEXT_MSGMERGE_EXECUTABLE)
OUTPUT_VARIABLE gettext_version
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (gettext_version MATCHES "^msgmerge \\(.*\\) [0-9]")
- string(REGEX REPLACE "^msgmerge \\([^\\)]*\\) ([0-9\\.]+[^ \n]*).*" "\\1" GETTEXT_VERSION_STRING "${gettext_version}")
+ if (gettext_version MATCHES "^msgmerge \\([^\\)]*\\) ([0-9\\.]+[^ \n]*)")
+ set(GETTEXT_VERSION_STRING "${CMAKE_MATCH_1}")
endif()
unset(gettext_version)
endif()
diff --git a/Modules/FindGit.cmake b/Modules/FindGit.cmake
index 41d2a7a8c..d18f965ee 100644
--- a/Modules/FindGit.cmake
+++ b/Modules/FindGit.cmake
@@ -1,15 +1,27 @@
+#.rst:
+# FindGit
+# -------
+#
# The module defines the following variables:
-# GIT_EXECUTABLE - path to git command line client
-# GIT_FOUND - true if the command line client was found
-# GIT_VERSION_STRING - the version of git found (since CMake 2.8.8)
+#
+# ``GIT_EXECUTABLE``
+# Path to Git command-line client.
+# ``Git_FOUND``, ``GIT_FOUND``
+# True if the Git command-line client was found.
+# ``GIT_VERSION_STRING``
+# The version of Git found.
+#
# Example usage:
-# find_package(Git)
-# if(GIT_FOUND)
-# message("git found: ${GIT_EXECUTABLE}")
-# endif()
+#
+# .. code-block:: cmake
+#
+# find_package(Git)
+# if(Git_FOUND)
+# message("Git found: ${GIT_EXECUTABLE}")
+# endif()
#=============================================================================
-# Copyright 2010 Kitware, Inc.
+# Copyright 2010-2016 Kitware, Inc.
# Copyright 2012 Rolf Eike Beer <eike@sf-mail.de>
#
# Distributed under the OSI-approved BSD License (the "License");
@@ -32,16 +44,25 @@ set(git_names git eg)
if(WIN32)
if(NOT CMAKE_GENERATOR MATCHES "MSYS")
set(git_names git.cmd git eg.cmd eg)
+ # GitHub search path for Windows
+ set(github_path "$ENV{LOCALAPPDATA}/Github/PortableGit*/bin")
+ file(GLOB github_path "${github_path}")
+ # SourceTree search path for Windows
+ set(_git_sourcetree_path "$ENV{LOCALAPPDATA}/Atlassian/SourceTree/git_local/bin")
endif()
endif()
find_program(GIT_EXECUTABLE
NAMES ${git_names}
+ PATHS ${github_path} ${_git_sourcetree_path}
PATH_SUFFIXES Git/cmd Git/bin
- DOC "git command line client"
+ DOC "Git command line client"
)
mark_as_advanced(GIT_EXECUTABLE)
+unset(git_names)
+unset(_git_sourcetree_path)
+
if(GIT_EXECUTABLE)
execute_process(COMMAND ${GIT_EXECUTABLE} --version
OUTPUT_VARIABLE git_version
@@ -53,7 +74,7 @@ if(GIT_EXECUTABLE)
unset(git_version)
endif()
-# Handle the QUIETLY and REQUIRED arguments and set GIT_FOUND to TRUE if
+# Handle the QUIETLY and REQUIRED arguments and set Git_FOUND to TRUE if
# all listed variables are TRUE
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
diff --git a/Modules/FindGnuTLS.cmake b/Modules/FindGnuTLS.cmake
index 7315f1dd4..4d94ffc5d 100644
--- a/Modules/FindGnuTLS.cmake
+++ b/Modules/FindGnuTLS.cmake
@@ -1,11 +1,19 @@
-# - Try to find the GNU Transport Layer Security library (gnutls)
+#.rst:
+# FindGnuTLS
+# ----------
+#
+# Try to find the GNU Transport Layer Security library (gnutls)
+#
+#
#
# Once done this will define
#
-# GNUTLS_FOUND - System has gnutls
-# GNUTLS_INCLUDE_DIR - The gnutls include directory
-# GNUTLS_LIBRARIES - The libraries needed to use gnutls
-# GNUTLS_DEFINITIONS - Compiler switches required for using gnutls
+# ::
+#
+# GNUTLS_FOUND - System has gnutls
+# GNUTLS_INCLUDE_DIR - The gnutls include directory
+# GNUTLS_LIBRARIES - The libraries needed to use gnutls
+# GNUTLS_DEFINITIONS - Compiler switches required for using gnutls
#=============================================================================
# Copyright 2009 Kitware, Inc.
diff --git a/Modules/FindGnuplot.cmake b/Modules/FindGnuplot.cmake
index f2f9dd059..067604fc1 100644
--- a/Modules/FindGnuplot.cmake
+++ b/Modules/FindGnuplot.cmake
@@ -1,10 +1,20 @@
-# - this module looks for gnuplot
+#.rst:
+# FindGnuplot
+# -----------
+#
+# this module looks for gnuplot
+#
+#
#
# Once done this will define
#
-# GNUPLOT_FOUND - system has Gnuplot
-# GNUPLOT_EXECUTABLE - the Gnuplot executable
-# GNUPLOT_VERSION_STRING - the version of Gnuplot found (since CMake 2.8.8)
+# ::
+#
+# GNUPLOT_FOUND - system has Gnuplot
+# GNUPLOT_EXECUTABLE - the Gnuplot executable
+# GNUPLOT_VERSION_STRING - the version of Gnuplot found (since CMake 2.8.8)
+#
+#
#
# GNUPLOT_VERSION_STRING will not work for old versions like 3.7.1.
diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake
index 0c246a1df..9f6e666a0 100644
--- a/Modules/FindHDF5.cmake
+++ b/Modules/FindHDF5.cmake
@@ -1,51 +1,72 @@
-# - Find HDF5, a library for reading and writing self describing array data.
+#.rst:
+# FindHDF5
+# --------
+#
+# Find HDF5, a library for reading and writing self describing array data.
+#
+#
#
# This module invokes the HDF5 wrapper compiler that should be installed
-# alongside HDF5. Depending upon the HDF5 Configuration, the wrapper compiler
-# is called either h5cc or h5pcc. If this succeeds, the module will then call
-# the compiler with the -show argument to see what flags are used when compiling
-# an HDF5 client application.
+# alongside HDF5. Depending upon the HDF5 Configuration, the wrapper
+# compiler is called either h5cc or h5pcc. If this succeeds, the module
+# will then call the compiler with the -show argument to see what flags
+# are used when compiling an HDF5 client application.
#
-# The module will optionally accept the COMPONENTS argument. If no COMPONENTS
-# are specified, then the find module will default to finding only the HDF5 C
-# library. If one or more COMPONENTS are specified, the module will attempt to
-# find the language bindings for the specified components. The only valid
-# components are C, CXX, Fortran, HL, and Fortran_HL. If the COMPONENTS
-# argument is not given, the module will attempt to find only the C bindings.
+# The module will optionally accept the COMPONENTS argument. If no
+# COMPONENTS are specified, then the find module will default to finding
+# only the HDF5 C library. If one or more COMPONENTS are specified, the
+# module will attempt to find the language bindings for the specified
+# components. The only valid components are C, CXX, Fortran, HL, and
+# Fortran_HL. If the COMPONENTS argument is not given, the module will
+# attempt to find only the C bindings.
#
-# On UNIX systems, this module will read the variable HDF5_USE_STATIC_LIBRARIES
-# to determine whether or not to prefer a static link to a dynamic link for HDF5
-# and all of it's dependencies. To use this feature, make sure that the
-# HDF5_USE_STATIC_LIBRARIES variable is set before the call to find_package.
+# On UNIX systems, this module will read the variable
+# HDF5_USE_STATIC_LIBRARIES to determine whether or not to prefer a
+# static link to a dynamic link for HDF5 and all of it's dependencies.
+# To use this feature, make sure that the HDF5_USE_STATIC_LIBRARIES
+# variable is set before the call to find_package.
#
-# To provide the module with a hint about where to find your HDF5 installation,
-# you can set the environment variable HDF5_ROOT. The Find module will then
-# look in this path when searching for HDF5 executables, paths, and libraries.
+# To provide the module with a hint about where to find your HDF5
+# installation, you can set the environment variable HDF5_ROOT. The
+# Find module will then look in this path when searching for HDF5
+# executables, paths, and libraries.
#
-# In addition to finding the includes and libraries required to compile an HDF5
-# client application, this module also makes an effort to find tools that come
-# with the HDF5 distribution that may be useful for regression testing.
+# Both the serial and parallel HDF5 wrappers are considered and the first
+# directory to contain either one will be used. In the event that both appear
+# in the same directory the serial version is preferentially selected. This
+# behavior can be reversed by setting the variable HDF5_PREFER_PARALLEL to
+# true.
+#
+# In addition to finding the includes and libraries required to compile
+# an HDF5 client application, this module also makes an effort to find
+# tools that come with the HDF5 distribution that may be useful for
+# regression testing.
#
# This module will define the following variables:
-# HDF5_INCLUDE_DIRS - Location of the hdf5 includes
-# HDF5_INCLUDE_DIR - Location of the hdf5 includes (deprecated)
-# HDF5_DEFINITIONS - Required compiler definitions for HDF5
-# HDF5_C_LIBRARIES - Required libraries for the HDF5 C bindings.
-# HDF5_CXX_LIBRARIES - Required libraries for the HDF5 C++ bindings
-# HDF5_Fortran_LIBRARIES - Required libraries for the HDF5 Fortran bindings
-# HDF5_HL_LIBRARIES - Required libraries for the HDF5 high level API
-# HDF5_Fortran_HL_LIBRARIES - Required libraries for the high level Fortran
-# bindings.
-# HDF5_LIBRARIES - Required libraries for all requested bindings
-# HDF5_FOUND - true if HDF5 was found on the system
-# HDF5_LIBRARY_DIRS - the full set of library directories
-# HDF5_IS_PARALLEL - Whether or not HDF5 was found with parallel IO support
-# HDF5_C_COMPILER_EXECUTABLE - the path to the HDF5 C wrapper compiler
-# HDF5_CXX_COMPILER_EXECUTABLE - the path to the HDF5 C++ wrapper compiler
-# HDF5_Fortran_COMPILER_EXECUTABLE - the path to the HDF5 Fortran wrapper compiler
-# HDF5_DIFF_EXECUTABLE - the path to the HDF5 dataset comparison tool
+#
+# ::
+#
+# HDF5_INCLUDE_DIRS - Location of the hdf5 includes
+# HDF5_INCLUDE_DIR - Location of the hdf5 includes (deprecated)
+# HDF5_DEFINITIONS - Required compiler definitions for HDF5
+# HDF5_C_LIBRARIES - Required libraries for the HDF5 C bindings.
+# HDF5_CXX_LIBRARIES - Required libraries for the HDF5 C++ bindings
+# HDF5_Fortran_LIBRARIES - Required libraries for the HDF5 Fortran bindings
+# HDF5_HL_LIBRARIES - Required libraries for the HDF5 high level API
+# HDF5_Fortran_HL_LIBRARIES - Required libraries for the high level Fortran
+# bindings.
+# HDF5_LIBRARIES - Required libraries for all requested bindings
+# HDF5_FOUND - true if HDF5 was found on the system
+# HDF5_VERSION - HDF5 version in format Major.Minor.Release
+# HDF5_LIBRARY_DIRS - the full set of library directories
+# HDF5_IS_PARALLEL - Whether or not HDF5 was found with parallel IO support
+# HDF5_C_COMPILER_EXECUTABLE - the path to the HDF5 C wrapper compiler
+# HDF5_CXX_COMPILER_EXECUTABLE - the path to the HDF5 C++ wrapper compiler
+# HDF5_Fortran_COMPILER_EXECUTABLE - the path to the HDF5 Fortran wrapper compiler
+# HDF5_DIFF_EXECUTABLE - the path to the HDF5 dataset comparison tool
#=============================================================================
+# Copyright 2015 Axel Huebl, Helmholtz-Zentrum Dresden - Rossendorf
# Copyright 2009 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
@@ -88,28 +109,43 @@ else()
endforeach()
endif()
+# Determine whether to search for serial or parallel executable first
+if(HDF5_PREFER_PARALLEL)
+ set(HDF5_C_COMPILER_NAMES h5pcc h5cc)
+ set(HDF5_CXX_COMPILER_NAMES h5pc++ h5c++)
+ set(HDF5_Fortran_COMPILER_NAMES h5pfc h5fc)
+else()
+ set(HDF5_C_COMPILER_NAMES h5cc h5pcc)
+ set(HDF5_CXX_COMPILER_NAMES h5c++ h5pc++)
+ set(HDF5_Fortran_COMPILER_NAMES h5fc h5pfc)
+endif()
+
# try to find the HDF5 wrapper compilers
find_program( HDF5_C_COMPILER_EXECUTABLE
- NAMES h5cc h5pcc
+ NAMES ${HDF5_C_COMPILER_NAMES} NAMES_PER_DIR
HINTS ENV HDF5_ROOT
PATH_SUFFIXES bin Bin
DOC "HDF5 Wrapper compiler. Used only to detect HDF5 compile flags." )
mark_as_advanced( HDF5_C_COMPILER_EXECUTABLE )
find_program( HDF5_CXX_COMPILER_EXECUTABLE
- NAMES h5c++ h5pc++
+ NAMES ${HDF5_CXX_COMPILER_NAMES} NAMES_PER_DIR
HINTS ENV HDF5_ROOT
PATH_SUFFIXES bin Bin
DOC "HDF5 C++ Wrapper compiler. Used only to detect HDF5 compile flags." )
mark_as_advanced( HDF5_CXX_COMPILER_EXECUTABLE )
find_program( HDF5_Fortran_COMPILER_EXECUTABLE
- NAMES h5fc h5pfc
+ NAMES ${HDF5_Fortran_COMPILER_NAMES} NAMES_PER_DIR
HINTS ENV HDF5_ROOT
PATH_SUFFIXES bin Bin
DOC "HDF5 Fortran Wrapper compiler. Used only to detect HDF5 compile flags." )
mark_as_advanced( HDF5_Fortran_COMPILER_EXECUTABLE )
+unset(HDF5_C_COMPILER_NAMES)
+unset(HDF5_CXX_COMPILER_NAMES)
+unset(HDF5_Fortran_COMPILER_NAMES)
+
find_program( HDF5_DIFF_EXECUTABLE
NAMES h5diff
HINTS ENV HDF5_ROOT
@@ -149,7 +185,7 @@ macro( _HDF5_parse_compile_line
)
foreach( IPATH ${include_path_flags} )
string( REGEX REPLACE "^-I" "" IPATH ${IPATH} )
- string( REGEX REPLACE "//" "/" IPATH ${IPATH} )
+ string( REPLACE "//" "/" IPATH ${IPATH} )
list( APPEND ${include_paths} ${IPATH} )
endforeach()
@@ -166,7 +202,7 @@ macro( _HDF5_parse_compile_line
foreach( LPATH ${library_path_flags} )
string( REGEX REPLACE "^-L" "" LPATH ${LPATH} )
- string( REGEX REPLACE "//" "/" LPATH ${LPATH} )
+ string( REPLACE "//" "/" LPATH ${LPATH} )
list( APPEND ${library_paths} ${LPATH} )
endforeach()
@@ -210,6 +246,8 @@ if( NOT HDF5_FOUND )
_HDF5_invoke_compiler( C HDF5_C_COMPILE_LINE HDF5_C_RETURN_VALUE )
_HDF5_invoke_compiler( CXX HDF5_CXX_COMPILE_LINE HDF5_CXX_RETURN_VALUE )
_HDF5_invoke_compiler( Fortran HDF5_Fortran_COMPILE_LINE HDF5_Fortran_RETURN_VALUE )
+ set(HDF5_HL_COMPILE_LINE ${HDF5_C_COMPILE_LINE})
+ set(HDF5_Fortran_HL_COMPILE_LINE ${HDF5_Fortran_COMPILE_LINE})
# seed the initial lists of libraries to find with items we know we need
set( HDF5_C_LIBRARY_NAMES_INIT hdf5 )
@@ -217,7 +255,7 @@ if( NOT HDF5_FOUND )
set( HDF5_CXX_LIBRARY_NAMES_INIT hdf5_cpp ${HDF5_C_LIBRARY_NAMES_INIT} )
set( HDF5_Fortran_LIBRARY_NAMES_INIT hdf5_fortran
${HDF5_C_LIBRARY_NAMES_INIT} )
- set( HDF5_Fortran_HL_LIBRARY_NAMES_INIT hdf5hl_fortran
+ set( HDF5_Fortran_HL_LIBRARY_NAMES_INIT hdf5hl_fortran hdf5_hl
${HDF5_Fortran_LIBRARY_NAMES_INIT} )
foreach( LANGUAGE ${HDF5_LANGUAGE_BINDINGS} )
@@ -240,7 +278,7 @@ if( NOT HDF5_FOUND )
list( APPEND HDF5_DEFINITIONS ${HDF5_${LANGUAGE}_DEFINITIONS} )
# find the HDF5 include directories
- if(${LANGUAGE} MATCHES "Fortran.*")
+ if(${LANGUAGE} MATCHES "Fortran")
set(HDF5_INCLUDE_FILENAME hdf5.mod)
else()
set(HDF5_INCLUDE_FILENAME hdf5.h)
@@ -269,7 +307,7 @@ if( NOT HDF5_FOUND )
if( UNIX AND HDF5_USE_STATIC_LIBRARIES )
# According to bug 1643 on the CMake bug tracker, this is the
# preferred method for searching for a static library.
- # See http://www.cmake.org/Bug/view.php?id=1643. We search
+ # See https://cmake.org/Bug/view.php?id=1643. We search
# first for the full static library name, but fall back to a
# generic search on the name if the static search fails.
set( THIS_LIBRARY_SEARCH_DEBUG lib${LIB}d.a ${LIB}d )
@@ -322,15 +360,28 @@ if( NOT HDF5_FOUND )
# If the HDF5 include directory was found, open H5pubconf.h to determine if
# HDF5 was compiled with parallel IO support
set( HDF5_IS_PARALLEL FALSE )
+ set( HDF5_VERSION "" )
foreach( _dir IN LISTS HDF5_INCLUDE_DIRS )
- if( EXISTS "${_dir}/H5pubconf.h" )
- file( STRINGS "${_dir}/H5pubconf.h"
+ foreach(_hdr "${_dir}/H5pubconf.h" "${_dir}/H5pubconf-64.h" "${_dir}/H5pubconf-32.h")
+ if( EXISTS "${_hdr}" )
+ file( STRINGS "${_hdr}"
HDF5_HAVE_PARALLEL_DEFINE
REGEX "HAVE_PARALLEL 1" )
if( HDF5_HAVE_PARALLEL_DEFINE )
set( HDF5_IS_PARALLEL TRUE )
endif()
+ unset(HDF5_HAVE_PARALLEL_DEFINE)
+
+ file( STRINGS "${_hdr}"
+ HDF5_VERSION_DEFINE
+ REGEX "^[ \t]*#[ \t]*define[ \t]+H5_VERSION[ \t]+" )
+ if( "${HDF5_VERSION_DEFINE}" MATCHES
+ "H5_VERSION[ \t]+\"([0-9]+\\.[0-9]+\\.[0-9]+).*\"" )
+ set( HDF5_VERSION "${CMAKE_MATCH_1}" )
+ endif()
+ unset(HDF5_VERSION_DEFINE)
endif()
+ endforeach()
endforeach()
set( HDF5_IS_PARALLEL ${HDF5_IS_PARALLEL} CACHE BOOL
"HDF5 library compiled with parallel IO support" )
@@ -344,8 +395,7 @@ if( NOT HDF5_FOUND )
endif()
-find_package_handle_standard_args( HDF5 DEFAULT_MSG
- HDF5_LIBRARIES
- HDF5_INCLUDE_DIRS
+find_package_handle_standard_args( HDF5
+ REQUIRED_VARS HDF5_LIBRARIES HDF5_INCLUDE_DIRS
+ VERSION_VAR HDF5_VERSION
)
-
diff --git a/Modules/FindHSPELL.cmake b/Modules/FindHSPELL.cmake
index 71e55dad4..231653353 100644
--- a/Modules/FindHSPELL.cmake
+++ b/Modules/FindHSPELL.cmake
@@ -1,14 +1,25 @@
-# - Try to find Hspell
+#.rst:
+# FindHSPELL
+# ----------
+#
+# Try to find Hspell
+#
# Once done this will define
#
-# HSPELL_FOUND - system has Hspell
-# HSPELL_INCLUDE_DIR - the Hspell include directory
-# HSPELL_LIBRARIES - The libraries needed to use Hspell
-# HSPELL_DEFINITIONS - Compiler switches required for using Hspell
+# ::
+#
+# HSPELL_FOUND - system has Hspell
+# HSPELL_INCLUDE_DIR - the Hspell include directory
+# HSPELL_LIBRARIES - The libraries needed to use Hspell
+# HSPELL_DEFINITIONS - Compiler switches required for using Hspell
+#
+#
+#
+# ::
#
-# HSPELL_VERSION_STRING - The version of Hspell found (x.y)
-# HSPELL_MAJOR_VERSION - the major version of Hspell
-# HSPELL_MINOR_VERSION - The minor version of Hspell
+# HSPELL_VERSION_STRING - The version of Hspell found (x.y)
+# HSPELL_MAJOR_VERSION - the major version of Hspell
+# HSPELL_MINOR_VERSION - The minor version of Hspell
#=============================================================================
# Copyright 2006-2009 Kitware, Inc.
diff --git a/Modules/FindHTMLHelp.cmake b/Modules/FindHTMLHelp.cmake
index c69e9e948..4e39a34ef 100644
--- a/Modules/FindHTMLHelp.cmake
+++ b/Modules/FindHTMLHelp.cmake
@@ -1,9 +1,16 @@
-# - This module looks for Microsoft HTML Help Compiler
+#.rst:
+# FindHTMLHelp
+# ------------
+#
+# This module looks for Microsoft HTML Help Compiler
+#
# It defines:
-# HTML_HELP_COMPILER : full path to the Compiler (hhc.exe)
-# HTML_HELP_INCLUDE_PATH : include path to the API (htmlhelp.h)
-# HTML_HELP_LIBRARY : full path to the library (htmlhelp.lib)
#
+# ::
+#
+# HTML_HELP_COMPILER : full path to the Compiler (hhc.exe)
+# HTML_HELP_INCLUDE_PATH : include path to the API (htmlhelp.h)
+# HTML_HELP_LIBRARY : full path to the library (htmlhelp.lib)
#=============================================================================
# Copyright 2002-2009 Kitware, Inc.
diff --git a/Modules/FindHg.cmake b/Modules/FindHg.cmake
index a6a4aef24..bdbb79b19 100644
--- a/Modules/FindHg.cmake
+++ b/Modules/FindHg.cmake
@@ -1,16 +1,47 @@
+#.rst:
+# FindHg
+# ------
+#
+# Extract information from a mercurial working copy.
+#
# The module defines the following variables:
-# HG_EXECUTABLE - path to mercurial command line client (hg)
-# HG_FOUND - true if the command line client was found
-# HG_VERSION_STRING - the version of mercurial found
+#
+# ::
+#
+# HG_EXECUTABLE - path to mercurial command line client (hg)
+# HG_FOUND - true if the command line client was found
+# HG_VERSION_STRING - the version of mercurial found
+#
+# If the command line client executable is found the following macro is defined:
+#
+# ::
+#
+# HG_WC_INFO(<dir> <var-prefix>)
+#
+# Hg_WC_INFO extracts information of a mercurial working copy
+# at a given location. This macro defines the following variables:
+#
+# ::
+#
+# <var-prefix>_WC_CHANGESET - current changeset
+# <var-prefix>_WC_REVISION - current revision
+#
# Example usage:
-# find_package(Hg)
-# if(HG_FOUND)
-# message("hg found: ${HG_EXECUTABLE}")
-# endif()
+#
+# ::
+#
+# find_package(Hg)
+# if(HG_FOUND)
+# message("hg found: ${HG_EXECUTABLE}")
+# HG_WC_INFO(${PROJECT_SOURCE_DIR} Project)
+# message("Current revision is ${Project_WC_REVISION}")
+# message("Current changeset is ${Project_WC_CHANGESET}")
+# endif()
#=============================================================================
# Copyright 2010-2012 Kitware, Inc.
# Copyright 2012 Rolf Eike Beer <eike@sf-mail.de>
+# Copyright 2014 Matthaeus G. Chajdas
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
@@ -24,20 +55,51 @@
find_program(HG_EXECUTABLE
NAMES hg
+ PATHS
+ [HKEY_LOCAL_MACHINE\\Software\\TortoiseHG]
PATH_SUFFIXES Mercurial
DOC "hg command line client"
)
mark_as_advanced(HG_EXECUTABLE)
if(HG_EXECUTABLE)
+ set(_saved_lc_all "$ENV{LC_ALL}")
+ set(ENV{LC_ALL} "C")
+
+ set(_saved_language "$ENV{LANGUAGE}")
+ set(ENV{LANGUAGE})
+
execute_process(COMMAND ${HG_EXECUTABLE} --version
OUTPUT_VARIABLE hg_version
ERROR_QUIET
+ RESULT_VARIABLE hg_result
OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ set(ENV{LC_ALL} ${_saved_lc_all})
+ set(ENV{LANGUAGE} ${_saved_language})
+
+ if(hg_result MATCHES "is not a valid Win32 application")
+ set_property(CACHE HG_EXECUTABLE PROPERTY VALUE "HG_EXECUTABLE-NOTFOUND")
+ endif()
if(hg_version MATCHES "^Mercurial Distributed SCM \\(version ([0-9][^)]*)\\)")
set(HG_VERSION_STRING "${CMAKE_MATCH_1}")
endif()
unset(hg_version)
+
+ macro(HG_WC_INFO dir prefix)
+ execute_process(COMMAND ${HG_EXECUTABLE} id -i -n
+ WORKING_DIRECTORY ${dir}
+ RESULT_VARIABLE hg_id_result
+ ERROR_VARIABLE hg_id_error
+ OUTPUT_VARIABLE ${prefix}_WC_DATA
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if(NOT ${hg_id_result} EQUAL 0)
+ message(SEND_ERROR "Command \"${HG_EXECUTBALE} id -n\" in directory ${dir} failed with output:\n${hg_id_error}")
+ endif()
+
+ string(REGEX REPLACE "([0-9a-f]+)\\+? [0-9]+\\+?" "\\1" ${prefix}_WC_CHANGESET ${${prefix}_WC_DATA})
+ string(REGEX REPLACE "[0-9a-f]+\\+? ([0-9]+)\\+?" "\\1" ${prefix}_WC_REVISION ${${prefix}_WC_DATA})
+ endmacro(HG_WC_INFO)
endif()
# Handle the QUIETLY and REQUIRED arguments and set HG_FOUND to TRUE if
diff --git a/Modules/FindITK.cmake b/Modules/FindITK.cmake
deleted file mode 100644
index 2929a764c..000000000
--- a/Modules/FindITK.cmake
+++ /dev/null
@@ -1,57 +0,0 @@
-# - Find an ITK installation or build tree.
-
-# When ITK is found, the ITKConfig.cmake file is sourced to setup the
-# location and configuration of ITK. Please read this file, or
-# ITKConfig.cmake.in from the ITK source tree for the full list of
-# definitions. Of particular interest is ITK_USE_FILE, a CMake source file
-# that can be included to set the include directories, library directories,
-# and preprocessor macros. In addition to the variables read from
-# ITKConfig.cmake, this find module also defines
-# ITK_DIR - The directory containing ITKConfig.cmake.
-# This is either the root of the build tree,
-# or the lib/InsightToolkit directory.
-# This is the only cache entry.
-#
-# ITK_FOUND - Whether ITK was found. If this is true,
-# ITK_DIR is okay.
-#
-# USE_ITK_FILE - The full path to the UseITK.cmake file.
-# This is provided for backward
-# compatibility. Use ITK_USE_FILE
-# instead.
-
-#=============================================================================
-# Copyright 2001-2010 Kitware, Inc.
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-# (To distribute this file outside of CMake, substitute the full
-# License text for the above reference.)
-
-# Use the Config mode of the find_package() command to find ITKConfig.
-# If this succeeds (possibly because ITK_DIR is already set), the
-# command will have already loaded ITKConfig.cmake and set ITK_FOUND.
-if(NOT ITK_FOUND)
- set(_ITK_REQUIRED "")
- if(ITK_FIND_REQUIRED)
- set(_ITK_REQUIRED REQUIRED)
- endif()
- set(_ITK_QUIET "")
- if(ITK_FIND_QUIETLY)
- set(_ITK_QUIET QUIET)
- endif()
- find_package(ITK ${_ITK_REQUIRED} ${_ITK_QUIET} NO_MODULE
- NAMES ITK InsightToolkit
- CONFIGS ITKConfig.cmake
- )
-endif()
-
-if(ITK_FOUND)
- # Set USE_ITK_FILE for backward-compatibility.
- set(USE_ITK_FILE ${ITK_USE_FILE})
-endif()
diff --git a/Modules/FindIce.cmake b/Modules/FindIce.cmake
new file mode 100644
index 000000000..3fa6cab4d
--- /dev/null
+++ b/Modules/FindIce.cmake
@@ -0,0 +1,521 @@
+#.rst:
+# FindIce
+# -------
+#
+# Find the ZeroC Internet Communication Engine (ICE) programs,
+# libraries and datafiles.
+#
+# This module supports multiple components.
+# Components can include any of: ``Freeze``, ``Glacier2``, ``Ice``,
+# ``IceBox``, ``IceDB``, ``IceGrid``, ``IcePatch``, ``IceSSL``,
+# ``IceStorm``, ``IceUtil``, ``IceXML``, or ``Slice``.
+#
+# This module reports information about the Ice installation in
+# several variables. General variables::
+#
+# Ice_VERSION - Ice release version
+# Ice_FOUND - true if the main programs and libraries were found
+# Ice_LIBRARIES - component libraries to be linked
+# Ice_INCLUDE_DIRS - the directories containing the Ice headers
+# Ice_SLICE_DIRS - the directories containing the Ice slice interface
+# definitions
+#
+# Imported targets::
+#
+# Ice::<C>
+#
+# Where ``<C>`` is the name of an Ice component, for example
+# ``Ice::Glacier2``.
+#
+# Ice slice programs are reported in::
+#
+# Ice_SLICE2CPP_EXECUTABLE - path to slice2cpp executable
+# Ice_SLICE2CS_EXECUTABLE - path to slice2cs executable
+# Ice_SLICE2FREEZEJ_EXECUTABLE - path to slice2freezej executable
+# Ice_SLICE2FREEZE_EXECUTABLE - path to slice2freeze executable
+# Ice_SLICE2HTML_EXECUTABLE - path to slice2html executable
+# Ice_SLICE2JAVA_EXECUTABLE - path to slice2java executable
+# Ice_SLICE2JS_EXECUTABLE - path to slice2js executable
+# Ice_SLICE2PHP_EXECUTABLE - path to slice2php executable
+# Ice_SLICE2PY_EXECUTABLE - path to slice2py executable
+# Ice_SLICE2RB_EXECUTABLE - path to slice2rb executable
+#
+# Ice programs are reported in::
+#
+# Ice_GLACIER2ROUTER_EXECUTABLE - path to glacier2router executable
+# Ice_ICEBOX_EXECUTABLE - path to icebox executable
+# Ice_ICEBOXADMIN_EXECUTABLE - path to iceboxadmin executable
+# Ice_ICEBOXD_EXECUTABLE - path to iceboxd executable
+# Ice_ICEBOXNET_EXECUTABLE - path to iceboxnet executable
+# Ice_ICEGRIDADMIN_EXECUTABLE - path to icegridadmin executable
+# Ice_ICEGRIDNODE_EXECUTABLE - path to icegridnode executable
+# Ice_ICEGRIDNODED_EXECUTABLE - path to icegridnoded executable
+# Ice_ICEGRIDREGISTRY_EXECUTABLE - path to icegridregistry executable
+# Ice_ICEGRIDREGISTRYD_EXECUTABLE - path to icegridregistryd executable
+# Ice_ICEPATCH2CALC_EXECUTABLE - path to icepatch2calc executable
+# Ice_ICEPATCH2CLIENT_EXECUTABLE - path to icepatch2client executable
+# Ice_ICEPATCH2SERVER_EXECUTABLE - path to icepatch2server executable
+# Ice_ICESERVICEINSTALL_EXECUTABLE - path to iceserviceinstall executable
+# Ice_ICESTORMADMIN_EXECUTABLE - path to icestormadmin executable
+# Ice_ICESTORMMIGRATE_EXECUTABLE - path to icestormmigrate executable
+#
+# Ice db programs (Windows only; standard system versions on all other
+# platforms) are reported in::
+#
+# Ice_DB_ARCHIVE_EXECUTABLE - path to db_archive executable
+# Ice_DB_CHECKPOINT_EXECUTABLE - path to db_checkpoint executable
+# Ice_DB_DEADLOCK_EXECUTABLE - path to db_deadlock executable
+# Ice_DB_DUMP_EXECUTABLE - path to db_dump executable
+# Ice_DB_HOTBACKUP_EXECUTABLE - path to db_hotbackup executable
+# Ice_DB_LOAD_EXECUTABLE - path to db_load executable
+# Ice_DB_LOG_VERIFY_EXECUTABLE - path to db_log_verify executable
+# Ice_DB_PRINTLOG_EXECUTABLE - path to db_printlog executable
+# Ice_DB_RECOVER_EXECUTABLE - path to db_recover executable
+# Ice_DB_STAT_EXECUTABLE - path to db_stat executable
+# Ice_DB_TUNER_EXECUTABLE - path to db_tuner executable
+# Ice_DB_UPGRADE_EXECUTABLE - path to db_upgrade executable
+# Ice_DB_VERIFY_EXECUTABLE - path to db_verify executable
+# Ice_DUMPDB_EXECUTABLE - path to dumpdb executable
+# Ice_TRANSFORMDB_EXECUTABLE - path to transformdb executable
+#
+# Ice component libraries are reported in::
+#
+# Ice_<C>_FOUND - ON if component was found
+# Ice_<C>_LIBRARIES - libraries for component
+#
+# Note that ``<C>`` is the uppercased name of the component.
+#
+# This module reads hints about search results from::
+#
+# Ice_HOME - the root of the Ice installation
+#
+# The environment variable ``ICE_HOME`` may also be used; the
+# Ice_HOME variable takes precedence.
+#
+# The following cache variables may also be set::
+#
+# Ice_<P>_EXECUTABLE - the path to executable <P>
+# Ice_INCLUDE_DIR - the directory containing the Ice headers
+# Ice_SLICE_DIR - the directory containing the Ice slice interface
+# definitions
+# Ice_<C>_LIBRARY - the library for component <C>
+#
+# .. note::
+#
+# In most cases none of the above variables will require setting,
+# unless multiple Ice versions are available and a specific version
+# is required. On Windows, the most recent version of Ice will be
+# found through the registry. On Unix, the programs, headers and
+# libraries will usually be in standard locations, but Ice_SLICE_DIRS
+# might not be automatically detected (commonly known locations are
+# searched). All the other variables are defaulted using Ice_HOME,
+# if set. It's possible to set Ice_HOME and selectively specify
+# alternative locations for the other components; this might be
+# required for e.g. newer versions of Visual Studio if the
+# heuristics are not sufficient to identify the correct programs and
+# libraries for the specific Visual Studio version.
+#
+# Other variables one may set to control this module are::
+#
+# Ice_DEBUG - Set to ON to enable debug output from FindIce.
+
+# Written by Roger Leigh <rleigh@codelibre.net>
+
+#=============================================================================
+# Copyright 2014-2015 University of Dundee
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# The Ice checks are contained in a function due to the large number
+# of temporary variables needed.
+function(_Ice_FIND)
+ # Released versions of Ice, including generic short forms
+ set(ice_versions
+ 3
+ 3.6
+ 3.6.0
+ 3.5
+ 3.5.1
+ 3.5.0
+ 3.4
+ 3.4.2
+ 3.4.1
+ 3.4.0
+ 3.3
+ 3.3.1
+ 3.3.0)
+
+ # Set up search paths, taking compiler into account. Search Ice_HOME,
+ # with ICE_HOME in the environment as a fallback if unset.
+ if(Ice_HOME)
+ list(APPEND ice_roots "${Ice_HOME}")
+ else()
+ if(NOT "$ENV{ICE_HOME}" STREQUAL "")
+ file(TO_CMAKE_PATH "$ENV{ICE_HOME}" NATIVE_PATH)
+ list(APPEND ice_roots "${NATIVE_PATH}")
+ set(Ice_HOME "${NATIVE_PATH}"
+ CACHE PATH "Location of the Ice installation" FORCE)
+ endif()
+ endif()
+
+ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ # 64-bit path suffix
+ set(_x64 "/x64")
+ # 64-bit library directory
+ set(_lib64 "lib64")
+ endif()
+
+ if(MSVC_VERSION)
+ # VS 8.0
+ if(NOT MSVC_VERSION VERSION_LESS 1400 AND MSVC_VERSION VERSION_LESS 1500)
+ set(vcver "vc80")
+ set(vcyear "2005")
+ # VS 9.0
+ elseif(NOT MSVC_VERSION VERSION_LESS 1500 AND MSVC_VERSION VERSION_LESS 1600)
+ set(vcver "vc90")
+ set(vcyear "2008")
+ # VS 10.0
+ elseif(NOT MSVC_VERSION VERSION_LESS 1600 AND MSVC_VERSION VERSION_LESS 1700)
+ set(vcver "vc100")
+ # VS 11.0
+ elseif(NOT MSVC_VERSION VERSION_LESS 1700 AND MSVC_VERSION VERSION_LESS 1800)
+ set(vcver "vc110")
+ # VS 12.0
+ elseif(NOT MSVC_VERSION VERSION_LESS 1800 AND MSVC_VERSION VERSION_LESS 1900)
+ set(vcver "vc120")
+ # VS 14.0
+ elseif(NOT MSVC_VERSION VERSION_LESS 1900 AND MSVC_VERSION VERSION_LESS 2000)
+ set(vcver "vc140")
+ endif()
+ endif()
+
+ # For compatibility with ZeroC Windows builds.
+ if(vcver)
+ # Earlier Ice (3.3) builds don't use vcnnn subdirectories, but are harmless to check.
+ list(APPEND ice_binary_suffixes "bin/${vcver}${_x64}" "bin/${vcver}")
+ list(APPEND ice_library_suffixes "lib/${vcver}${_x64}" "lib/${vcver}")
+ endif()
+ # Generic 64-bit and 32-bit directories
+ list(APPEND ice_binary_suffixes "bin${_x64}" "bin")
+ list(APPEND ice_library_suffixes "${_lib64}" "lib${_x64}" "lib")
+ list(APPEND ice_include_suffixes "include")
+ list(APPEND ice_slice_suffixes "slice")
+
+ # On Windows, look in the registry for install locations. Different
+ # versions of Ice install support different compiler versions.
+ if(vcver)
+ foreach(ice_version ${ice_versions})
+ # Ice 3.3 releases use a Visual Studio year suffix and value is
+ # enclosed in double quotes, though only the leading quote is
+ # returned by get_filename_component.
+ unset(ice_location)
+ if(vcyear)
+ get_filename_component(ice_location
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ZeroC\\Ice ${ice_version} for Visual Studio ${vcyear};InstallDir]"
+ PATH)
+ if(ice_location AND NOT ("${ice_location}" STREQUAL "/registry" OR "${ice_location}" STREQUAL "/"))
+ string(REGEX REPLACE "^\"(.*)\"?$" "\\1" ice_location "${ice_location}")
+ get_filename_component(ice_location "${ice_location}" ABSOLUTE)
+ else()
+ unset(ice_location)
+ endif()
+ endif()
+ # Ice 3.4+ releases don't use a suffix
+ if(NOT ice_location OR "${ice_location}" STREQUAL "/registry")
+ get_filename_component(ice_location
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ZeroC\\Ice ${ice_version};InstallDir]"
+ ABSOLUTE)
+ endif()
+
+ if(ice_location AND NOT "${ice_location}" STREQUAL "/registry")
+ list(APPEND ice_roots "${ice_location}")
+ endif()
+ endforeach()
+ else()
+ foreach(ice_version ${ice_versions})
+ # Prefer 64-bit variants if present (and using a 64-bit compiler)
+ list(APPEND ice_roots "/opt/Ice-${ice_version}")
+ endforeach()
+ endif()
+
+ set(db_programs
+ db_archive
+ db_checkpoint
+ db_deadlock
+ db_dump
+ db_hotbackup
+ db_load
+ db_log_verify
+ db_printlog
+ db_recover
+ db_stat
+ db_tuner
+ db_upgrade
+ db_verify
+ dumpdb
+ transformdb)
+
+ set(ice_programs
+ glacier2router
+ icebox
+ iceboxadmin
+ iceboxd
+ iceboxnet
+ icegridadmin
+ icegridnode
+ icegridnoded
+ icegridregistry
+ icegridregistryd
+ icepatch2calc
+ icepatch2client
+ icepatch2server
+ iceserviceinstall
+ icestormadmin
+ icestormmigrate)
+
+ set(slice_programs
+ slice2cpp
+ slice2cs
+ slice2freezej
+ slice2freeze
+ slice2html
+ slice2java
+ slice2js
+ slice2php
+ slice2py
+ slice2rb)
+
+ # Find all Ice programs
+ foreach(program ${db_programs} ${ice_programs} ${slice_programs})
+ string(TOUPPER "${program}" program_upcase)
+ set(cache_var "Ice_${program_upcase}_EXECUTABLE")
+ set(program_var "Ice_${program_upcase}_EXECUTABLE")
+ find_program("${cache_var}" "${program}"
+ HINTS ${ice_roots}
+ PATH_SUFFIXES ${ice_binary_suffixes}
+ DOC "Ice ${program} executable")
+ mark_as_advanced(cache_var)
+ set("${program_var}" "${${cache_var}}" PARENT_SCOPE)
+ endforeach()
+
+ # Get version.
+ if(Ice_SLICE2CPP_EXECUTABLE)
+ # Execute in C locale for safety
+ set(_Ice_SAVED_LC_ALL "$ENV{LC_ALL}")
+ set(ENV{LC_ALL} C)
+
+ execute_process(COMMAND ${Ice_SLICE2CPP_EXECUTABLE} --version
+ ERROR_VARIABLE Ice_VERSION_SLICE2CPP_FULL
+ ERROR_STRIP_TRAILING_WHITESPACE)
+
+ # restore the previous LC_ALL
+ set(ENV{LC_ALL} ${_Ice_SAVED_LC_ALL})
+
+ # Make short version
+ string(REGEX REPLACE "^(.*)\\.[^.]*$" "\\1" Ice_VERSION_SLICE2CPP_SHORT "${Ice_VERSION_SLICE2CPP_FULL}")
+ set(Ice_VERSION "${Ice_VERSION_SLICE2CPP_FULL}" PARENT_SCOPE)
+ endif()
+
+ if(NOT Ice_FIND_QUIETLY)
+ message(STATUS "Ice version: ${Ice_VERSION_SLICE2CPP_FULL}")
+ endif()
+
+ # Find include directory
+ find_path(Ice_INCLUDE_DIR
+ NAMES "Ice/Ice.h"
+ HINTS ${ice_roots}
+ PATH_SUFFIXES ${ice_include_suffixes}
+ DOC "Ice include directory")
+ set(Ice_INCLUDE_DIR "${Ice_INCLUDE_DIR}" PARENT_SCOPE)
+
+ # In common use on Linux, MacOS X (homebrew) and FreeBSD; prefer
+ # version-specific dir
+ list(APPEND ice_slice_paths
+ /usr/local/share /usr/share)
+ list(APPEND ice_slice_suffixes
+ "Ice-${Ice_VERSION_SLICE2CPP_FULL}/slice"
+ "Ice-${Ice_VERSION_SLICE2CPP_SHORT}/slice"
+ Ice)
+
+ # Find slice directory
+ find_path(Ice_SLICE_DIR
+ NAMES "Ice/Connection.ice"
+ HINTS ${ice_roots}
+ ${ice_slice_paths}
+ PATH_SUFFIXES ${ice_slice_suffixes}
+ NO_DEFAULT_PATH
+ DOC "Ice slice directory")
+ set(Ice_SLICE_DIR "${Ice_SLICE_DIR}" PARENT_SCOPE)
+
+ # Find all Ice libraries
+ set(Ice_REQUIRED_LIBS_FOUND ON)
+ foreach(component ${Ice_FIND_COMPONENTS})
+ string(TOUPPER "${component}" component_upcase)
+ set(component_cache "Ice_${component_upcase}_LIBRARY")
+ set(component_found "${component_upcase}_FOUND")
+ find_library("${component_cache}" "${component}"
+ HINTS ${ice_roots}
+ PATH_SUFFIXES ${ice_library_suffixes}
+ DOC "Ice ${component} library")
+ mark_as_advanced("${component_cache}")
+ if(${component_cache})
+ set("${component_found}" ON)
+ list(APPEND Ice_LIBRARY "${${component_cache}}")
+ endif()
+ mark_as_advanced("${component_found}")
+ set("${component_cache}" "${${component_cache}}" PARENT_SCOPE)
+ set("${component_found}" "${${component_found}}" PARENT_SCOPE)
+ if(${component_found})
+ if (Ice_FIND_REQUIRED_${component})
+ list(APPEND Ice_LIBS_FOUND "${component} (required)")
+ else()
+ list(APPEND Ice_LIBS_FOUND "${component} (optional)")
+ endif()
+ else()
+ if (Ice_FIND_REQUIRED_${component})
+ set(Ice_REQUIRED_LIBS_FOUND OFF)
+ list(APPEND Ice_LIBS_NOTFOUND "${component} (required)")
+ else()
+ list(APPEND Ice_LIBS_NOTFOUND "${component} (optional)")
+ endif()
+ endif()
+ endforeach()
+ set(_Ice_REQUIRED_LIBS_FOUND "${Ice_REQUIRED_LIBS_FOUND}" PARENT_SCOPE)
+ set(Ice_LIBRARY "${Ice_LIBRARY}" PARENT_SCOPE)
+
+ if(NOT Ice_FIND_QUIETLY)
+ if(Ice_LIBS_FOUND)
+ message(STATUS "Found the following Ice libraries:")
+ foreach(found ${Ice_LIBS_FOUND})
+ message(STATUS " ${found}")
+ endforeach()
+ endif()
+ if(Ice_LIBS_NOTFOUND)
+ message(STATUS "The following Ice libraries were not found:")
+ foreach(notfound ${Ice_LIBS_NOTFOUND})
+ message(STATUS " ${notfound}")
+ endforeach()
+ endif()
+ endif()
+
+ if(Ice_DEBUG)
+ message(STATUS "--------FindIce.cmake search debug--------")
+ message(STATUS "ICE binary path search order: ${ice_roots}")
+ message(STATUS "ICE include path search order: ${ice_roots}")
+ message(STATUS "ICE slice path search order: ${ice_roots} ${ice_slice_paths}")
+ message(STATUS "ICE library path search order: ${ice_roots}")
+ message(STATUS "----------------")
+ endif()
+endfunction()
+
+_Ice_FIND()
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Ice
+ FOUND_VAR Ice_FOUND
+ REQUIRED_VARS Ice_SLICE2CPP_EXECUTABLE
+ Ice_INCLUDE_DIR
+ Ice_SLICE_DIR
+ Ice_LIBRARY
+ _Ice_REQUIRED_LIBS_FOUND
+ VERSION_VAR Ice_VERSION
+ FAIL_MESSAGE "Failed to find all Ice components")
+
+unset(_Ice_REQUIRED_LIBS_FOUND)
+
+if(Ice_FOUND)
+ set(Ice_INCLUDE_DIRS "${Ice_INCLUDE_DIR}")
+ set(Ice_SLICE_DIRS "${Ice_SLICE_DIR}")
+ set(Ice_LIBRARIES "${Ice_LIBRARY}")
+ foreach(_Ice_component ${Ice_FIND_COMPONENTS})
+ string(TOUPPER "${_Ice_component}" _Ice_component_upcase)
+ set(_Ice_component_cache "Ice_${_Ice_component_upcase}_LIBRARY")
+ set(_Ice_component_lib "Ice_${_Ice_component_upcase}_LIBRARIES")
+ set(_Ice_component_found "${_Ice_component_upcase}_FOUND")
+ set(_Ice_imported_target "Ice::${_Ice_component}")
+ if(${_Ice_component_found})
+ set("${_Ice_component_lib}" "${${_Ice_component_cache}}")
+ if(NOT TARGET ${_Ice_imported_target})
+ add_library(${_Ice_imported_target} UNKNOWN IMPORTED)
+ set_target_properties(${_Ice_imported_target} PROPERTIES
+ IMPORTED_LOCATION "${${_Ice_component_cache}}"
+ INTERFACE_INCLUDE_DIRECTORIES "${Ice_INCLUDE_DIR}")
+ endif()
+ endif()
+ unset(_Ice_component_upcase)
+ unset(_Ice_component_cache)
+ unset(_Ice_component_lib)
+ unset(_Ice_component_found)
+ unset(_Ice_imported_target)
+ endforeach()
+endif()
+
+if(Ice_DEBUG)
+ message(STATUS "--------FindIce.cmake results debug--------")
+ message(STATUS "Ice_VERSION number: ${Ice_VERSION}")
+ message(STATUS "Ice_HOME directory: ${Ice_HOME}")
+ message(STATUS "Ice_INCLUDE_DIR directory: ${Ice_INCLUDE_DIR}")
+ message(STATUS "Ice_SLICE_DIR directory: ${Ice_SLICE_DIR}")
+ message(STATUS "Ice_LIBRARIES: ${Ice_LIBRARIES}")
+
+ message(STATUS "slice2cpp executable: ${Ice_SLICE2CPP_EXECUTABLE}")
+ message(STATUS "slice2cs executable: ${Ice_SLICE2CS_EXECUTABLE}")
+ message(STATUS "slice2freezej executable: ${Ice_SLICE2FREEZEJ_EXECUTABLE}")
+ message(STATUS "slice2freeze executable: ${Ice_SLICE2FREEZE_EXECUTABLE}")
+ message(STATUS "slice2html executable: ${Ice_SLICE2HTML_EXECUTABLE}")
+ message(STATUS "slice2java executable: ${Ice_SLICE2JAVA_EXECUTABLE}")
+ message(STATUS "slice2js executable: ${Ice_SLICE2JS_EXECUTABLE}")
+ message(STATUS "slice2php executable: ${Ice_SLICE2PHP_EXECUTABLE}")
+ message(STATUS "slice2py executable: ${Ice_SLICE2PY_EXECUTABLE}")
+ message(STATUS "slice2rb executable: ${Ice_SLICE2RB_EXECUTABLE}")
+ message(STATUS "glacier2router executable: ${Ice_GLACIER2ROUTER_EXECUTABLE}")
+
+ message(STATUS "icebox executable: ${Ice_ICEBOX_EXECUTABLE}")
+ message(STATUS "iceboxadmin executable: ${Ice_ICEBOXADMIN_EXECUTABLE}")
+ message(STATUS "iceboxd executable: ${Ice_ICEBOXD_EXECUTABLE}")
+ message(STATUS "iceboxnet executable: ${Ice_ICEBOXNET_EXECUTABLE}")
+ message(STATUS "icegridadmin executable: ${Ice_ICEGRIDADMIN_EXECUTABLE}")
+ message(STATUS "icegridnode executable: ${Ice_ICEGRIDNODE_EXECUTABLE}")
+ message(STATUS "icegridnoded executable: ${Ice_ICEGRIDNODED_EXECUTABLE}")
+ message(STATUS "icegridregistry executable: ${Ice_ICEGRIDREGISTRY_EXECUTABLE}")
+ message(STATUS "icegridregistryd executable: ${Ice_ICEGRIDREGISTRYD_EXECUTABLE}")
+ message(STATUS "icepatch2calc executable: ${Ice_ICEPATCH2CALC_EXECUTABLE}")
+ message(STATUS "icepatch2client executable: ${Ice_ICEPATCH2CLIENT_EXECUTABLE}")
+ message(STATUS "icepatch2server executable: ${Ice_ICEPATCH2SERVER_EXECUTABLE}")
+ message(STATUS "iceserviceinstall executable: ${Ice_ICESERVICEINSTALL_EXECUTABLE}")
+ message(STATUS "icestormadmin executable: ${Ice_ICESTORMADMIN_EXECUTABLE}")
+ message(STATUS "icestormmigrate executable: ${Ice_ICESTORMMIGRATE_EXECUTABLE}")
+
+ message(STATUS "db_archive executable: ${Ice_DB_ARCHIVE_EXECUTABLE}")
+ message(STATUS "db_checkpoint executable: ${Ice_DB_CHECKPOINT_EXECUTABLE}")
+ message(STATUS "db_deadlock executable: ${Ice_DB_DEADLOCK_EXECUTABLE}")
+ message(STATUS "db_dump executable: ${Ice_DB_DUMP_EXECUTABLE}")
+ message(STATUS "db_hotbackup executable: ${Ice_DB_HOTBACKUP_EXECUTABLE}")
+ message(STATUS "db_load executable: ${Ice_DB_LOAD_EXECUTABLE}")
+ message(STATUS "db_log_verify executable: ${Ice_DB_LOG_VERIFY_EXECUTABLE}")
+ message(STATUS "db_printlog executable: ${Ice_DB_PRINTLOG_EXECUTABLE}")
+ message(STATUS "db_recover executable: ${Ice_DB_RECOVER_EXECUTABLE}")
+ message(STATUS "db_stat executable: ${Ice_DB_STAT_EXECUTABLE}")
+ message(STATUS "db_tuner executable: ${Ice_DB_TUNER_EXECUTABLE}")
+ message(STATUS "db_upgrade executable: ${Ice_DB_UPGRADE_EXECUTABLE}")
+ message(STATUS "db_verify executable: ${Ice_DB_VERIFY_EXECUTABLE}")
+ message(STATUS "dumpdb executable: ${Ice_DUMPDB_EXECUTABLE}")
+ message(STATUS "transformdb executable: ${Ice_TRANSFORMDB_EXECUTABLE}")
+
+ foreach(component ${Ice_FIND_COMPONENTS})
+ string(TOUPPER "${component}" component_upcase)
+ set(component_lib "Ice_${component_upcase}_LIBRARIES")
+ set(component_found "${component_upcase}_FOUND")
+ message(STATUS "${component} library found: ${${component_found}}")
+ message(STATUS "${component} library: ${${component_lib}}")
+ endforeach()
+ message(STATUS "----------------")
+endif()
diff --git a/Modules/FindIcotool.cmake b/Modules/FindIcotool.cmake
index 8c101778d..a7c5a64ec 100644
--- a/Modules/FindIcotool.cmake
+++ b/Modules/FindIcotool.cmake
@@ -1,10 +1,17 @@
-# - Find icotool
-# This module looks for icotool. This module defines the
-# following values:
-# ICOTOOL_EXECUTABLE: the full path to the icotool tool.
-# ICOTOOL_FOUND: True if icotool has been found.
-# ICOTOOL_VERSION_STRING: the version of icotool found.
+#.rst:
+# FindIcotool
+# -----------
#
+# Find icotool
+#
+# This module looks for icotool. This module defines the following
+# values:
+#
+# ::
+#
+# ICOTOOL_EXECUTABLE: the full path to the icotool tool.
+# ICOTOOL_FOUND: True if icotool has been found.
+# ICOTOOL_VERSION_STRING: the version of icotool found.
#=============================================================================
# Copyright 2012 Aleksey Avdeev <solo@altlinux.ru>
@@ -30,7 +37,7 @@ if(ICOTOOL_EXECUTABLE)
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
- if("${_icotool_version}" MATCHES "^icotool \\([^\\)]*\\) ([0-9\\.]+[^ \n]*).*")
+ if("${_icotool_version}" MATCHES "^icotool \\([^\\)]*\\) ([0-9\\.]+[^ \n]*)")
set( ICOTOOL_VERSION_STRING
"${CMAKE_MATCH_1}"
)
diff --git a/Modules/FindImageMagick.cmake b/Modules/FindImageMagick.cmake
index 7c6cce786..65458b7cf 100644
--- a/Modules/FindImageMagick.cmake
+++ b/Modules/FindImageMagick.cmake
@@ -1,58 +1,84 @@
-# - Find the ImageMagick binary suite.
-# This module will search for a set of ImageMagick tools specified
-# as components in the FIND_PACKAGE call. Typical components include,
-# but are not limited to (future versions of ImageMagick might have
+#.rst:
+# FindImageMagick
+# ---------------
+#
+# Find the ImageMagick binary suite.
+#
+# This module will search for a set of ImageMagick tools specified as
+# components in the FIND_PACKAGE call. Typical components include, but
+# are not limited to (future versions of ImageMagick might have
# additional components not listed here):
#
-# animate
-# compare
-# composite
-# conjure
-# convert
-# display
-# identify
-# import
-# mogrify
-# montage
-# stream
+# ::
+#
+# animate
+# compare
+# composite
+# conjure
+# convert
+# display
+# identify
+# import
+# mogrify
+# montage
+# stream
+#
+#
#
# If no component is specified in the FIND_PACKAGE call, then it only
-# searches for the ImageMagick executable directory. This code defines
+# searches for the ImageMagick executable directory. This code defines
# the following variables:
#
-# ImageMagick_FOUND - TRUE if all components are found.
-# ImageMagick_EXECUTABLE_DIR - Full path to executables directory.
-# ImageMagick_<component>_FOUND - TRUE if <component> is found.
-# ImageMagick_<component>_EXECUTABLE - Full path to <component> executable.
-# ImageMagick_VERSION_STRING - the version of ImageMagick found
-# (since CMake 2.8.8)
+# ::
+#
+# ImageMagick_FOUND - TRUE if all components are found.
+# ImageMagick_EXECUTABLE_DIR - Full path to executables directory.
+# ImageMagick_<component>_FOUND - TRUE if <component> is found.
+# ImageMagick_<component>_EXECUTABLE - Full path to <component> executable.
+# ImageMagick_VERSION_STRING - the version of ImageMagick found
+# (since CMake 2.8.8)
+#
+#
#
# ImageMagick_VERSION_STRING will not work for old versions like 5.2.3.
#
# There are also components for the following ImageMagick APIs:
#
-# Magick++
-# MagickWand
-# MagickCore
+# ::
+#
+# Magick++
+# MagickWand
+# MagickCore
+#
+#
#
# For these components the following variables are set:
#
-# ImageMagick_FOUND - TRUE if all components are found.
-# ImageMagick_INCLUDE_DIRS - Full paths to all include dirs.
-# ImageMagick_LIBRARIES - Full paths to all libraries.
-# ImageMagick_<component>_FOUND - TRUE if <component> is found.
-# ImageMagick_<component>_INCLUDE_DIRS - Full path to <component> include dirs.
-# ImageMagick_<component>_LIBRARIES - Full path to <component> libraries.
+# ::
+#
+# ImageMagick_FOUND - TRUE if all components are found.
+# ImageMagick_INCLUDE_DIRS - Full paths to all include dirs.
+# ImageMagick_LIBRARIES - Full paths to all libraries.
+# ImageMagick_<component>_FOUND - TRUE if <component> is found.
+# ImageMagick_<component>_INCLUDE_DIRS - Full path to <component> include dirs.
+# ImageMagick_<component>_LIBRARIES - Full path to <component> libraries.
+#
+#
#
# Example Usages:
-# find_package(ImageMagick)
-# find_package(ImageMagick COMPONENTS convert)
-# find_package(ImageMagick COMPONENTS convert mogrify display)
-# find_package(ImageMagick COMPONENTS Magick++)
-# find_package(ImageMagick COMPONENTS Magick++ convert)
#
-# Note that the standard FIND_PACKAGE features are supported
-# (i.e., QUIET, REQUIRED, etc.).
+# ::
+#
+# find_package(ImageMagick)
+# find_package(ImageMagick COMPONENTS convert)
+# find_package(ImageMagick COMPONENTS convert mogrify display)
+# find_package(ImageMagick COMPONENTS Magick++)
+# find_package(ImageMagick COMPONENTS Magick++ convert)
+#
+#
+#
+# Note that the standard FIND_PACKAGE features are supported (i.e.,
+# QUIET, REQUIRED, etc.).
#=============================================================================
# Copyright 2007-2009 Kitware, Inc.
@@ -69,34 +95,68 @@
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
+find_package(PkgConfig QUIET)
+
#---------------------------------------------------------------------
# Helper functions
#---------------------------------------------------------------------
function(FIND_IMAGEMAGICK_API component header)
set(ImageMagick_${component}_FOUND FALSE PARENT_SCOPE)
+ pkg_check_modules(PC_${component} QUIET ${component})
+
find_path(ImageMagick_${component}_INCLUDE_DIR
NAMES ${header}
+ HINTS
+ ${PC_${component}_INCLUDEDIR}
+ ${PC_${component}_INCLUDE_DIRS}
+ PATHS
+ ${ImageMagick_INCLUDE_DIRS}
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]/include"
+ PATH_SUFFIXES
+ ImageMagick ImageMagick-6
+ DOC "Path to the ImageMagick arch-independent include dir."
+ )
+ find_path(ImageMagick_${component}_ARCH_INCLUDE_DIR
+ NAMES magick/magick-baseconfig.h
+ HINTS
+ ${PC_${component}_INCLUDEDIR}
+ ${PC_${component}_INCLUDE_DIRS}
PATHS
${ImageMagick_INCLUDE_DIRS}
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]/include"
PATH_SUFFIXES
ImageMagick ImageMagick-6
- DOC "Path to the ImageMagick include dir."
+ DOC "Path to the ImageMagick arch-specific include dir."
)
find_library(ImageMagick_${component}_LIBRARY
NAMES ${ARGN}
+ HINTS
+ ${PC_${component}_LIBDIR}
+ ${PC_${component}_LIB_DIRS}
PATHS
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]/lib"
DOC "Path to the ImageMagick Magick++ library."
)
+ # old version have only indep dir
if(ImageMagick_${component}_INCLUDE_DIR AND ImageMagick_${component}_LIBRARY)
set(ImageMagick_${component}_FOUND TRUE PARENT_SCOPE)
- list(APPEND ImageMagick_INCLUDE_DIRS
+ # Construct per-component include directories.
+ set(ImageMagick_${component}_INCLUDE_DIRS
${ImageMagick_${component}_INCLUDE_DIR}
)
+ if(ImageMagick_${component}_ARCH_INCLUDE_DIR)
+ list(APPEND ImageMagick_${component}_INCLUDE_DIRS
+ ${ImageMagick_${component}_ARCH_INCLUDE_DIR})
+ endif()
+ list(REMOVE_DUPLICATES ImageMagick_${component}_INCLUDE_DIRS)
+ set(ImageMagick_${component}_INCLUDE_DIRS
+ ${ImageMagick_${component}_INCLUDE_DIRS} PARENT_SCOPE)
+
+ # Add the per-component include directories to the full include dirs.
+ list(APPEND ImageMagick_INCLUDE_DIRS ${ImageMagick_${component}_INCLUDE_DIRS})
list(REMOVE_DUPLICATES ImageMagick_INCLUDE_DIRS)
set(ImageMagick_INCLUDE_DIRS ${ImageMagick_INCLUDE_DIRS} PARENT_SCOPE)
@@ -195,8 +255,8 @@ if(ImageMagick_mogrify_EXECUTABLE)
OUTPUT_VARIABLE imagemagick_version
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
- if(imagemagick_version MATCHES "^Version: ImageMagick [0-9]")
- string(REGEX REPLACE "^Version: ImageMagick ([-0-9\\.]+).*" "\\1" ImageMagick_VERSION_STRING "${imagemagick_version}")
+ if(imagemagick_version MATCHES "^Version: ImageMagick ([-0-9\\.]+)")
+ set(ImageMagick_VERSION_STRING "${CMAKE_MATCH_1}")
endif()
unset(imagemagick_version)
endif()
diff --git a/Modules/FindIntl.cmake b/Modules/FindIntl.cmake
new file mode 100644
index 000000000..cd2ec63ad
--- /dev/null
+++ b/Modules/FindIntl.cmake
@@ -0,0 +1,69 @@
+#.rst:
+# FindIntl
+# --------
+#
+# Find the Gettext libintl headers and libraries.
+#
+# This module reports information about the Gettext libintl
+# installation in several variables. General variables::
+#
+# Intl_FOUND - true if the libintl headers and libraries were found
+# Intl_INCLUDE_DIRS - the directory containing the libintl headers
+# Intl_LIBRARIES - libintl libraries to be linked
+#
+# The following cache variables may also be set::
+#
+# Intl_INCLUDE_DIR - the directory containing the libintl headers
+# Intl_LIBRARY - the libintl library (if any)
+#
+# .. note::
+# On some platforms, such as Linux with GNU libc, the gettext
+# functions are present in the C standard library and libintl
+# is not required. ``Intl_LIBRARIES`` will be empty in this
+# case.
+#
+# .. note::
+# If you wish to use the Gettext tools (``msgmerge``,
+# ``msgfmt``, etc.), use :module:`FindGettext`.
+
+
+# Written by Roger Leigh <rleigh@codelibre.net>
+
+#=============================================================================
+# Copyright 2014 Roger Leigh <rleigh@codelibre.net>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# Find include directory
+find_path(Intl_INCLUDE_DIR
+ NAMES "libintl.h"
+ DOC "libintl include directory")
+mark_as_advanced(Intl_INCLUDE_DIR)
+
+# Find all Intl libraries
+find_library(Intl_LIBRARY "intl"
+ DOC "libintl libraries (if not in the C library)")
+mark_as_advanced(Intl_LIBRARY)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Intl
+ FOUND_VAR Intl_FOUND
+ REQUIRED_VARS Intl_INCLUDE_DIR
+ FAIL_MESSAGE "Failed to find Gettext libintl")
+
+if(Intl_FOUND)
+ set(Intl_INCLUDE_DIRS "${Intl_INCLUDE_DIR}")
+ if(Intl_LIBRARY)
+ set(Intl_LIBRARIES "${Intl_LIBRARY}")
+ else()
+ unset(Intl_LIBRARIES)
+ endif()
+endif()
diff --git a/Modules/FindJNI.cmake b/Modules/FindJNI.cmake
index 9d708ca15..135038c5b 100644
--- a/Modules/FindJNI.cmake
+++ b/Modules/FindJNI.cmake
@@ -1,17 +1,26 @@
-# - Find JNI java libraries.
+#.rst:
+# FindJNI
+# -------
+#
+# Find JNI java libraries.
+#
# This module finds if Java is installed and determines where the
-# include files and libraries are. It also determines what the name of
-# the library is. This code sets the following variables:
+# include files and libraries are. It also determines what the name of
+# the library is. The caller may set variable JAVA_HOME to specify a
+# Java installation prefix explicitly.
+#
+# This module sets the following result variables:
#
-# JNI_INCLUDE_DIRS = the include dirs to use
-# JNI_LIBRARIES = the libraries to use
-# JNI_FOUND = TRUE if JNI headers and libraries were found.
-# JAVA_AWT_LIBRARY = the path to the jawt library
-# JAVA_JVM_LIBRARY = the path to the jvm library
-# JAVA_INCLUDE_PATH = the include path to jni.h
-# JAVA_INCLUDE_PATH2 = the include path to jni_md.h
-# JAVA_AWT_INCLUDE_PATH = the include path to jawt.h
+# ::
#
+# JNI_INCLUDE_DIRS = the include dirs to use
+# JNI_LIBRARIES = the libraries to use
+# JNI_FOUND = TRUE if JNI headers and libraries were found.
+# JAVA_AWT_LIBRARY = the path to the jawt library
+# JAVA_JVM_LIBRARY = the path to the jvm library
+# JAVA_INCLUDE_PATH = the include path to jni.h
+# JAVA_INCLUDE_PATH2 = the include path to jni_md.h
+# JAVA_AWT_INCLUDE_PATH = the include path to jawt.h
#=============================================================================
# Copyright 2001-2009 Kitware, Inc.
@@ -33,7 +42,11 @@ macro(java_append_library_directories _var)
# 1.6.0_18 + icedtea patches. However, it would be much better to base the
# guess on the first part of the GNU config.guess platform triplet.
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- set(_java_libarch "amd64")
+ if(CMAKE_LIBRARY_ARCHITECTURE STREQUAL "x86_64-linux-gnux32")
+ set(_java_libarch "x32" "amd64" "i386")
+ else()
+ set(_java_libarch "amd64" "i386")
+ endif()
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^i.86$")
set(_java_libarch "i386")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^alpha")
@@ -44,11 +57,13 @@ macro(java_append_library_directories _var)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips")
# mips* machines are bi-endian mostly so processor does not tell
# endianess of the underlying system.
- set(_java_libarch "${CMAKE_SYSTEM_PROCESSOR}" "mips" "mipsel" "mipseb")
+ set(_java_libarch "${CMAKE_SYSTEM_PROCESSOR}" "mips" "mipsel" "mipseb" "mips64" "mips64el" "mipsn32" "mipsn32el")
+ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64le")
+ set(_java_libarch "ppc64" "ppc64le")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64")
- set(_java_libarch "ppc64")
+ set(_java_libarch "ppc64" "ppc")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)")
- set(_java_libarch "ppc")
+ set(_java_libarch "ppc" "ppc64")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^sparc")
# Both flavours can run on the same processor
set(_java_libarch "${CMAKE_SYSTEM_PROCESSOR}" "sparc" "sparcv9")
@@ -85,22 +100,38 @@ macro(java_append_library_directories _var)
endforeach()
endmacro()
+include(${CMAKE_CURRENT_LIST_DIR}/CMakeFindJavaCommon.cmake)
+
+# Save CMAKE_FIND_FRAMEWORK
+if(DEFINED CMAKE_FIND_FRAMEWORK)
+ set(_JNI_CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK})
+else()
+ unset(_JNI_CMAKE_FIND_FRAMEWORK)
+endif()
+
+if(_JAVA_HOME_EXPLICIT)
+ set(CMAKE_FIND_FRAMEWORK NEVER)
+endif()
+
+set(JAVA_AWT_LIBRARY_DIRECTORIES)
+if(_JAVA_HOME)
+ JAVA_APPEND_LIBRARY_DIRECTORIES(JAVA_AWT_LIBRARY_DIRECTORIES
+ ${_JAVA_HOME}/jre/lib/{libarch}
+ ${_JAVA_HOME}/jre/lib
+ ${_JAVA_HOME}/lib/{libarch}
+ ${_JAVA_HOME}/lib
+ ${_JAVA_HOME}
+ )
+endif()
get_filename_component(java_install_version
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit;CurrentVersion]" NAME)
-set(JAVA_AWT_LIBRARY_DIRECTORIES
+list(APPEND JAVA_AWT_LIBRARY_DIRECTORIES
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.4;JavaHome]/lib"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.3;JavaHome]/lib"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\${java_install_version};JavaHome]/lib"
)
-
-file(TO_CMAKE_PATH "$ENV{JAVA_HOME}" _JAVA_HOME)
-
JAVA_APPEND_LIBRARY_DIRECTORIES(JAVA_AWT_LIBRARY_DIRECTORIES
- ${_JAVA_HOME}/jre/lib/{libarch}
- ${_JAVA_HOME}/jre/lib
- ${_JAVA_HOME}/lib
- ${_JAVA_HOME}
/usr/lib
/usr/local/lib
/usr/lib/jvm/java/lib
@@ -125,24 +156,31 @@ JAVA_APPEND_LIBRARY_DIRECTORIES(JAVA_AWT_LIBRARY_DIRECTORIES
/usr/local/jre-1.7.0/lib/{libarch}
/usr/local/jdk-1.6.0/jre/lib/{libarch}
/usr/local/jre-1.6.0/lib/{libarch}
+ # SuSE specific paths for default JVM
+ /usr/lib64/jvm/java/jre/lib/{libarch}
+ /usr/lib64/jvm/jre/lib/{libarch}
)
set(JAVA_JVM_LIBRARY_DIRECTORIES)
foreach(dir ${JAVA_AWT_LIBRARY_DIRECTORIES})
- set(JAVA_JVM_LIBRARY_DIRECTORIES
- ${JAVA_JVM_LIBRARY_DIRECTORIES}
+ list(APPEND JAVA_JVM_LIBRARY_DIRECTORIES
"${dir}"
"${dir}/client"
"${dir}/server"
+ # IBM SDK, Java Technology Edition, specific paths
+ "${dir}/j9vm"
+ "${dir}/default"
)
endforeach()
-
-set(JAVA_AWT_INCLUDE_DIRECTORIES
+set(JAVA_AWT_INCLUDE_DIRECTORIES)
+if(_JAVA_HOME)
+ list(APPEND JAVA_AWT_INCLUDE_DIRECTORIES ${_JAVA_HOME}/include)
+endif()
+list(APPEND JAVA_AWT_INCLUDE_DIRECTORIES
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.4;JavaHome]/include"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.3;JavaHome]/include"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\${java_install_version};JavaHome]/include"
- ${_JAVA_HOME}/include
/usr/include
/usr/local/include
/usr/lib/java/include
@@ -161,13 +199,15 @@ set(JAVA_AWT_INCLUDE_DIRECTORIES
# OpenBSD specific path for default JVM
/usr/local/jdk-1.7.0/include
/usr/local/jdk-1.6.0/include
+ # SuSE specific paths for default JVM
+ /usr/lib64/jvm/java/include
)
foreach(JAVA_PROG "${JAVA_RUNTIME}" "${JAVA_COMPILE}" "${JAVA_ARCHIVE}")
get_filename_component(jpath "${JAVA_PROG}" PATH)
foreach(JAVA_INC_PATH ../include ../java/include ../share/java/include)
if(EXISTS ${jpath}/${JAVA_INC_PATH})
- set(JAVA_AWT_INCLUDE_DIRECTORIES ${JAVA_AWT_INCLUDE_DIRECTORIES} "${jpath}/${JAVA_INC_PATH}")
+ list(APPEND JAVA_AWT_INCLUDE_DIRECTORIES "${jpath}/${JAVA_INC_PATH}")
endif()
endforeach()
foreach(JAVA_LIB_PATH
@@ -175,54 +215,55 @@ foreach(JAVA_PROG "${JAVA_RUNTIME}" "${JAVA_COMPILE}" "${JAVA_ARCHIVE}")
../java/lib ../java/jre/lib ../java/jre/lib/i386
../share/java/lib ../share/java/jre/lib ../share/java/jre/lib/i386)
if(EXISTS ${jpath}/${JAVA_LIB_PATH})
- set(JAVA_AWT_LIBRARY_DIRECTORIES ${JAVA_AWT_LIBRARY_DIRECTORIES} "${jpath}/${JAVA_LIB_PATH}")
+ list(APPEND JAVA_AWT_LIBRARY_DIRECTORIES "${jpath}/${JAVA_LIB_PATH}")
endif()
endforeach()
endforeach()
if(APPLE)
- if(EXISTS ~/Library/Frameworks/JavaVM.framework)
- set(JAVA_HAVE_FRAMEWORK 1)
- endif()
- if(EXISTS /Library/Frameworks/JavaVM.framework)
- set(JAVA_HAVE_FRAMEWORK 1)
+ if(CMAKE_FIND_FRAMEWORK STREQUAL "ONLY")
+ set(_JNI_SEARCHES FRAMEWORK)
+ elseif(CMAKE_FIND_FRAMEWORK STREQUAL "NEVER")
+ set(_JNI_SEARCHES NORMAL)
+ elseif(CMAKE_FIND_FRAMEWORK STREQUAL "LAST")
+ set(_JNI_SEARCHES NORMAL FRAMEWORK)
+ else()
+ set(_JNI_SEARCHES FRAMEWORK NORMAL)
endif()
- if(EXISTS /System/Library/Frameworks/JavaVM.framework)
- set(JAVA_HAVE_FRAMEWORK 1)
- endif()
-
- if(JAVA_HAVE_FRAMEWORK)
- if(NOT JAVA_AWT_LIBRARY)
- set (JAVA_AWT_LIBRARY "-framework JavaVM" CACHE FILEPATH "Java Frameworks" FORCE)
- endif()
+ set(_JNI_FRAMEWORK_JVM NAMES JavaVM)
+ set(_JNI_FRAMEWORK_JAWT "${_JNI_FRAMEWORK_JVM}")
+else()
+ set(_JNI_SEARCHES NORMAL)
+endif()
- if(NOT JAVA_JVM_LIBRARY)
- set (JAVA_JVM_LIBRARY "-framework JavaVM" CACHE FILEPATH "Java Frameworks" FORCE)
- endif()
+set(_JNI_NORMAL_JVM
+ NAMES jvm
+ PATHS ${JAVA_JVM_LIBRARY_DIRECTORIES}
+ )
- if(NOT JAVA_AWT_INCLUDE_PATH)
- if(EXISTS /System/Library/Frameworks/JavaVM.framework/Headers/jawt.h)
- set (JAVA_AWT_INCLUDE_PATH "/System/Library/Frameworks/JavaVM.framework/Headers" CACHE FILEPATH "jawt.h location" FORCE)
- endif()
- endif()
+set(_JNI_NORMAL_JAWT
+ NAMES jawt
+ PATHS ${JAVA_AWT_LIBRARY_DIRECTORIES}
+ )
- # If using "-framework JavaVM", prefer its headers *before* the others in
- # JAVA_AWT_INCLUDE_DIRECTORIES... (*prepend* to the list here)
- #
- set(JAVA_AWT_INCLUDE_DIRECTORIES
- ~/Library/Frameworks/JavaVM.framework/Headers
- /Library/Frameworks/JavaVM.framework/Headers
- /System/Library/Frameworks/JavaVM.framework/Headers
- ${JAVA_AWT_INCLUDE_DIRECTORIES}
- )
+foreach(search ${_JNI_SEARCHES})
+ find_library(JAVA_JVM_LIBRARY ${_JNI_${search}_JVM})
+ find_library(JAVA_AWT_LIBRARY ${_JNI_${search}_JAWT})
+ if(JAVA_JVM_LIBRARY)
+ break()
endif()
+endforeach()
+unset(_JNI_SEARCHES)
+unset(_JNI_FRAMEWORK_JVM)
+unset(_JNI_FRAMEWORK_JAWT)
+unset(_JNI_NORMAL_JVM)
+unset(_JNI_NORMAL_JAWT)
+
+# Find headers matching the library.
+if("${JAVA_JVM_LIBRARY};${JAVA_AWT_LIBRARY};" MATCHES "(/JavaVM.framework|-framework JavaVM);")
+ set(CMAKE_FIND_FRAMEWORK ONLY)
else()
- find_library(JAVA_AWT_LIBRARY jawt
- PATHS ${JAVA_AWT_LIBRARY_DIRECTORIES}
- )
- find_library(JAVA_JVM_LIBRARY NAMES jvm JavaVM
- PATHS ${JAVA_JVM_LIBRARY_DIRECTORIES}
- )
+ set(CMAKE_FIND_FRAMEWORK NEVER)
endif()
# add in the include path
@@ -230,8 +271,10 @@ find_path(JAVA_INCLUDE_PATH jni.h
${JAVA_AWT_INCLUDE_DIRECTORIES}
)
-find_path(JAVA_INCLUDE_PATH2 jni_md.h
+find_path(JAVA_INCLUDE_PATH2 NAMES jni_md.h jniport.h
+ PATHS
${JAVA_INCLUDE_PATH}
+ ${JAVA_INCLUDE_PATH}/darwin
${JAVA_INCLUDE_PATH}/win32
${JAVA_INCLUDE_PATH}/linux
${JAVA_INCLUDE_PATH}/freebsd
@@ -239,12 +282,21 @@ find_path(JAVA_INCLUDE_PATH2 jni_md.h
${JAVA_INCLUDE_PATH}/solaris
${JAVA_INCLUDE_PATH}/hp-ux
${JAVA_INCLUDE_PATH}/alpha
+ ${JAVA_INCLUDE_PATH}/aix
)
find_path(JAVA_AWT_INCLUDE_PATH jawt.h
${JAVA_INCLUDE_PATH}
)
+# Restore CMAKE_FIND_FRAMEWORK
+if(DEFINED _JNI_CMAKE_FIND_FRAMEWORK)
+ set(CMAKE_FIND_FRAMEWORK ${_JNI_CMAKE_FIND_FRAMEWORK})
+ unset(_JNI_CMAKE_FIND_FRAMEWORK)
+else()
+ unset(CMAKE_FIND_FRAMEWORK)
+endif()
+
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(JNI DEFAULT_MSG JAVA_AWT_LIBRARY JAVA_JVM_LIBRARY
JAVA_INCLUDE_PATH JAVA_INCLUDE_PATH2 JAVA_AWT_INCLUDE_PATH)
diff --git a/Modules/FindJPEG.cmake b/Modules/FindJPEG.cmake
index 7c1f0fd94..86bb6e505 100644
--- a/Modules/FindJPEG.cmake
+++ b/Modules/FindJPEG.cmake
@@ -1,11 +1,22 @@
-# - Find JPEG
-# Find the native JPEG includes and library
-# This module defines
-# JPEG_INCLUDE_DIR, where to find jpeglib.h, etc.
-# JPEG_LIBRARIES, the libraries needed to use JPEG.
-# JPEG_FOUND, If false, do not try to use JPEG.
+#.rst:
+# FindJPEG
+# --------
+#
+# Find JPEG
+#
+# Find the native JPEG includes and library This module defines
+#
+# ::
+#
+# JPEG_INCLUDE_DIR, where to find jpeglib.h, etc.
+# JPEG_LIBRARIES, the libraries needed to use JPEG.
+# JPEG_FOUND, If false, do not try to use JPEG.
+#
# also defined, but not for general use are
-# JPEG_LIBRARY, where to find the JPEG library.
+#
+# ::
+#
+# JPEG_LIBRARY, where to find the JPEG library.
#=============================================================================
# Copyright 2001-2009 Kitware, Inc.
@@ -22,7 +33,7 @@
find_path(JPEG_INCLUDE_DIR jpeglib.h)
-set(JPEG_NAMES ${JPEG_NAMES} jpeg)
+set(JPEG_NAMES ${JPEG_NAMES} jpeg libjpeg)
find_library(JPEG_LIBRARY NAMES ${JPEG_NAMES} )
# handle the QUIETLY and REQUIRED arguments and set JPEG_FOUND to TRUE if
diff --git a/Modules/FindJasper.cmake b/Modules/FindJasper.cmake
index 136056b84..0f325f039 100644
--- a/Modules/FindJasper.cmake
+++ b/Modules/FindJasper.cmake
@@ -1,10 +1,17 @@
-# - Try to find the Jasper JPEG2000 library
+#.rst:
+# FindJasper
+# ----------
+#
+# Try to find the Jasper JPEG2000 library
+#
# Once done this will define
#
-# JASPER_FOUND - system has Jasper
-# JASPER_INCLUDE_DIR - the Jasper include directory
-# JASPER_LIBRARIES - the libraries needed to use Jasper
-# JASPER_VERSION_STRING - the version of Jasper found (since CMake 2.8.8)
+# ::
+#
+# JASPER_FOUND - system has Jasper
+# JASPER_INCLUDE_DIR - the Jasper include directory
+# JASPER_LIBRARIES - the libraries needed to use Jasper
+# JASPER_VERSION_STRING - the version of Jasper found (since CMake 2.8.8)
#=============================================================================
# Copyright 2006-2009 Kitware, Inc.
diff --git a/Modules/FindJava.cmake b/Modules/FindJava.cmake
index 2f02b7a4b..cc67df662 100644
--- a/Modules/FindJava.cmake
+++ b/Modules/FindJava.cmake
@@ -1,46 +1,72 @@
-# - Find Java
+#.rst:
+# FindJava
+# --------
+#
+# Find Java
+#
# This module finds if Java is installed and determines where the
-# include files and libraries are. This code sets the following
-# variables:
-#
-# Java_JAVA_EXECUTABLE = the full path to the Java runtime
-# Java_JAVAC_EXECUTABLE = the full path to the Java compiler
-# Java_JAVAH_EXECUTABLE = the full path to the Java header generator
-# Java_JAVADOC_EXECUTABLE = the full path to the Java documention generator
-# Java_JAR_EXECUTABLE = the full path to the Java archiver
-# Java_VERSION_STRING = Version of the package found (java version), eg. 1.6.0_12
-# Java_VERSION_MAJOR = The major version of the package found.
-# Java_VERSION_MINOR = The minor version of the package found.
-# Java_VERSION_PATCH = The patch version of the package found.
-# Java_VERSION_TWEAK = The tweak version of the package found (after '_')
-# Java_VERSION = This is set to: $major.$minor.$patch(.$tweak)
+# include files and libraries are. The caller may set variable JAVA_HOME
+# to specify a Java installation prefix explicitly.
+#
+#
+# Specify one or more of the following components as you call this find module. See example below.
+#
+# ::
+#
+# Runtime = User just want to execute some Java byte-compiled
+# Development = Development tools (java, javac, javah and javadoc), includes Runtime component
+# IdlJ = idl compiler for Java
+# JarSigner = signer tool for jar
+#
+#
+# This module sets the following result variables:
+#
+# ::
+#
+# Java_JAVA_EXECUTABLE = the full path to the Java runtime
+# Java_JAVAC_EXECUTABLE = the full path to the Java compiler
+# Java_JAVAH_EXECUTABLE = the full path to the Java header generator
+# Java_JAVADOC_EXECUTABLE = the full path to the Java documention generator
+# Java_IDLJ_EXECUTABLE = the full path to the Java idl compiler
+# Java_JAR_EXECUTABLE = the full path to the Java archiver
+# Java_JARSIGNER_EXECUTABLE = the full path to the Java jar signer
+# Java_VERSION_STRING = Version of java found, eg. 1.6.0_12
+# Java_VERSION_MAJOR = The major version of the package found.
+# Java_VERSION_MINOR = The minor version of the package found.
+# Java_VERSION_PATCH = The patch version of the package found.
+# Java_VERSION_TWEAK = The tweak version of the package found (after '_')
+# Java_VERSION = This is set to: $major.$minor.$patch(.$tweak)
+#
+#
#
# The minimum required version of Java can be specified using the
-# standard CMake syntax, e.g. find_package(Java 1.5)
+# standard CMake syntax, e.g. find_package(Java 1.5)
#
-# NOTE: ${Java_VERSION} and ${Java_VERSION_STRING} are not guaranteed to be
-# identical. For example some java version may return:
-# Java_VERSION_STRING = 1.5.0_17
-# and
-# Java_VERSION = 1.5.0.17
+# NOTE: ${Java_VERSION} and ${Java_VERSION_STRING} are not guaranteed to
+# be identical. For example some java version may return:
+# Java_VERSION_STRING = 1.5.0_17 and Java_VERSION = 1.5.0.17
#
-# another example is the Java OEM, with:
-# Java_VERSION_STRING = 1.6.0-oem
-# and
-# Java_VERSION = 1.6.0
+# another example is the Java OEM, with: Java_VERSION_STRING = 1.6.0-oem
+# and Java_VERSION = 1.6.0
#
# For these components the following variables are set:
#
-# Java_FOUND - TRUE if all components are found.
-# Java_INCLUDE_DIRS - Full paths to all include dirs.
-# Java_LIBRARIES - Full paths to all libraries.
-# Java_<component>_FOUND - TRUE if <component> is found.
+# ::
+#
+# Java_FOUND - TRUE if all components are found.
+# Java_INCLUDE_DIRS - Full paths to all include dirs.
+# Java_LIBRARIES - Full paths to all libraries.
+# Java_<component>_FOUND - TRUE if <component> is found.
+#
+#
#
# Example Usages:
-# find_package(Java)
-# find_package(Java COMPONENTS Runtime)
-# find_package(Java COMPONENTS Development)
#
+# ::
+#
+# find_package(Java)
+# find_package(Java COMPONENTS Runtime)
+# find_package(Java COMPONENTS Development)
#=============================================================================
# Copyright 2002-2009 Kitware, Inc.
@@ -56,8 +82,14 @@
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
+include(${CMAKE_CURRENT_LIST_DIR}/CMakeFindJavaCommon.cmake)
+
# The HINTS option should only be used for values computed from the system.
-set(_JAVA_HINTS
+set(_JAVA_HINTS)
+if(_JAVA_HOME)
+ list(APPEND _JAVA_HINTS ${_JAVA_HOME}/bin)
+endif()
+list(APPEND _JAVA_HINTS
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\2.0;JavaHome]/bin"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.9;JavaHome]/bin"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.8;JavaHome]/bin"
@@ -66,7 +98,6 @@ set(_JAVA_HINTS
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.5;JavaHome]/bin"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.4;JavaHome]/bin"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.3;JavaHome]/bin"
- $ENV{JAVA_HOME}/bin
)
# Hard-coded guesses should still go in PATHS. This ensures that the user
# environment can always override hard guesses.
@@ -97,10 +128,13 @@ if(Java_JAVA_EXECUTABLE)
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_STRIP_TRAILING_WHITESPACE)
if( res )
- if(${Java_FIND_REQUIRED})
+ if(var MATCHES "No Java runtime present, requesting install")
+ set_property(CACHE Java_JAVA_EXECUTABLE
+ PROPERTY VALUE "Java_JAVA_EXECUTABLE-NOTFOUND")
+ elseif(${Java_FIND_REQUIRED})
message( FATAL_ERROR "Error executing java -version" )
else()
- message( STATUS "Warning, could not run java --version")
+ message( STATUS "Warning, could not run java -version")
endif()
else()
# extract major/minor version and patch level from "java -version" output
@@ -110,18 +144,15 @@ if(Java_JAVA_EXECUTABLE)
# 3. GCJ 1.5
# 4. Kaffe 1.4.2
# 5. OpenJDK 1.7.x on OpenBSD
- if(var MATCHES "java version \"[0-9]+\\.[0-9]+\\.[0-9_.]+.*\".*")
+ if(var MATCHES "java version \"([0-9]+\\.[0-9]+\\.[0-9_.]+.*)\"")
# This is most likely Sun / OpenJDK, or maybe GCJ-java compat layer
- string( REGEX REPLACE ".* version \"([0-9]+\\.[0-9]+\\.[0-9_.]+.*)\".*"
- "\\1" Java_VERSION_STRING "${var}" )
- elseif(var MATCHES "java full version \"kaffe-[0-9]+\\.[0-9]+\\.[0-9_]+\".*")
+ set(Java_VERSION_STRING "${CMAKE_MATCH_1}")
+ elseif(var MATCHES "java full version \"kaffe-([0-9]+\\.[0-9]+\\.[0-9_]+)\"")
# Kaffe style
- string( REGEX REPLACE "java full version \"kaffe-([0-9]+\\.[0-9]+\\.[0-9_]+).*"
- "\\1" Java_VERSION_STRING "${var}" )
- elseif(var MATCHES "openjdk version \"[0-9]+\\.[0-9]+\\.[0-9_]+\".*")
+ set(Java_VERSION_STRING "${CMAKE_MATCH_1}")
+ elseif(var MATCHES "openjdk version \"([0-9]+\\.[0-9]+\\.[0-9_]+.*)\"")
# OpenJDK ver 1.7.x on OpenBSD
- string( REGEX REPLACE "openjdk version \"([0-9]+\\.[0-9]+\\.[0-9_]+).*"
- "\\1" Java_VERSION_STRING "${var}" )
+ set(Java_VERSION_STRING "${CMAKE_MATCH_1}")
else()
if(NOT Java_FIND_QUIETLY)
message(WARNING "regex not supported: ${var}. Please report")
@@ -166,28 +197,61 @@ find_program(Java_JAVADOC_EXECUTABLE
PATHS ${_JAVA_PATHS}
)
+find_program(Java_IDLJ_EXECUTABLE
+ NAMES idlj
+ HINTS ${_JAVA_HINTS}
+ PATHS ${_JAVA_PATHS}
+)
+
+find_program(Java_JARSIGNER_EXECUTABLE
+ NAMES jarsigner
+ HINTS ${_JAVA_HINTS}
+ PATHS ${_JAVA_PATHS}
+)
+
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
if(Java_FIND_COMPONENTS)
+ set(_JAVA_REQUIRED_VARS)
foreach(component ${Java_FIND_COMPONENTS})
# User just want to execute some Java byte-compiled
- if(component STREQUAL "Runtime")
- find_package_handle_standard_args(Java
- REQUIRED_VARS Java_JAVA_EXECUTABLE
- VERSION_VAR Java_VERSION
- )
+ If(component STREQUAL "Runtime")
+ list(APPEND _JAVA_REQUIRED_VARS Java_JAVA_EXECUTABLE)
+ if(Java_JAVA_EXECUTABLE)
+ set(Java_Runtime_FOUND TRUE)
+ endif()
elseif(component STREQUAL "Development")
- find_package_handle_standard_args(Java
- REQUIRED_VARS Java_JAVA_EXECUTABLE Java_JAR_EXECUTABLE Java_JAVAC_EXECUTABLE
- Java_JAVAH_EXECUTABLE Java_JAVADOC_EXECUTABLE
- VERSION_VAR Java_VERSION
- )
+ list(APPEND _JAVA_REQUIRED_VARS Java_JAVA_EXECUTABLE Java_JAVAC_EXECUTABLE
+ Java_JAVAH_EXECUTABLE Java_JAVADOC_EXECUTABLE)
+ if(Java_JAVA_EXECUTABLE AND Java_JAVAC_EXECUTABLE
+ AND Java_JAVAH_EXECUTABLE AND Java_JAVADOC_EXECUTABLE)
+ set(Java_Development_FOUND TRUE)
+ endif()
+ elseif(component STREQUAL "IdlJ")
+ list(APPEND _JAVA_REQUIRED_VARS Java_IDLJ_EXECUTABLE)
+ if(Java_IDLJ_EXECUTABLE)
+ set(Java_IdlJ_FOUND TRUE)
+ endif()
+ elseif(component STREQUAL "JarSigner")
+ list(APPEND _JAVA_REQUIRED_VARS Java_JARSIGNER_EXECUTABLE)
+ if(Java_JARSIGNER_EXECUTABLE)
+ set(Java_JarSigner_FOUND TRUE)
+ endif()
else()
message(FATAL_ERROR "Comp: ${component} is not handled")
endif()
- set(Java_${component}_FOUND TRUE)
endforeach()
+ list (REMOVE_DUPLICATES _JAVA_REQUIRED_VARS)
+ find_package_handle_standard_args(Java
+ REQUIRED_VARS ${_JAVA_REQUIRED_VARS} HANDLE_COMPONENTS
+ VERSION_VAR Java_VERSION
+ )
+ if(Java_FOUND)
+ foreach(component ${Java_FIND_COMPONENTS})
+ set(Java_${component}_FOUND TRUE)
+ endforeach()
+ endif()
else()
- # Check for everything
+ # Check for Development
find_package_handle_standard_args(Java
REQUIRED_VARS Java_JAVA_EXECUTABLE Java_JAR_EXECUTABLE Java_JAVAC_EXECUTABLE
Java_JAVAH_EXECUTABLE Java_JAVADOC_EXECUTABLE
@@ -202,6 +266,8 @@ mark_as_advanced(
Java_JAVAC_EXECUTABLE
Java_JAVAH_EXECUTABLE
Java_JAVADOC_EXECUTABLE
+ Java_IDLJ_EXECUTABLE
+ Java_JARSIGNER_EXECUTABLE
)
# LEGACY
diff --git a/Modules/FindKDE3.cmake b/Modules/FindKDE3.cmake
index 70eccef60..dda453050 100644
--- a/Modules/FindKDE3.cmake
+++ b/Modules/FindKDE3.cmake
@@ -1,64 +1,135 @@
-# - Find the KDE3 include and library dirs, KDE preprocessors and define a some macros
+#.rst:
+# FindKDE3
+# --------
+#
+# Find the KDE3 include and library dirs, KDE preprocessors and define a some macros
+#
+#
#
# This module defines the following variables:
-# KDE3_DEFINITIONS - compiler definitions required for compiling KDE software
-# KDE3_INCLUDE_DIR - the KDE include directory
-# KDE3_INCLUDE_DIRS - the KDE and the Qt include directory, for use with include_directories()
-# KDE3_LIB_DIR - the directory where the KDE libraries are installed, for use with link_directories()
-# QT_AND_KDECORE_LIBS - this contains both the Qt and the kdecore library
-# KDE3_DCOPIDL_EXECUTABLE - the dcopidl executable
-# KDE3_DCOPIDL2CPP_EXECUTABLE - the dcopidl2cpp executable
-# KDE3_KCFGC_EXECUTABLE - the kconfig_compiler executable
-# KDE3_FOUND - set to TRUE if all of the above has been found
+#
+# ``KDE3_DEFINITIONS``
+# compiler definitions required for compiling KDE software
+# ``KDE3_INCLUDE_DIR``
+# the KDE include directory
+# ``KDE3_INCLUDE_DIRS``
+# the KDE and the Qt include directory, for use with include_directories()
+# ``KDE3_LIB_DIR``
+# the directory where the KDE libraries are installed, for use with link_directories()
+# ``QT_AND_KDECORE_LIBS``
+# this contains both the Qt and the kdecore library
+# ``KDE3_DCOPIDL_EXECUTABLE``
+# the dcopidl executable
+# ``KDE3_DCOPIDL2CPP_EXECUTABLE``
+# the dcopidl2cpp executable
+# ``KDE3_KCFGC_EXECUTABLE``
+# the kconfig_compiler executable
+# ``KDE3_FOUND``
+# set to TRUE if all of the above has been found
#
# The following user adjustable options are provided:
#
-# KDE3_BUILD_TESTS - enable this to build KDE testcases
+# ``KDE3_BUILD_TESTS``
+# enable this to build KDE testcases
+#
+# It also adds the following macros (from KDE3Macros.cmake) SRCS_VAR is
+# always the variable which contains the list of source files for your
+# application or library.
+#
+# KDE3_AUTOMOC(file1 ... fileN)
+#
+# ::
+#
+# Call this if you want to have automatic moc file handling.
+# This means if you include "foo.moc" in the source file foo.cpp
+# a moc file for the header foo.h will be created automatically.
+# You can set the property SKIP_AUTOMAKE using set_source_files_properties()
+# to exclude some files in the list from being processed.
+#
+#
+#
+# KDE3_ADD_MOC_FILES(SRCS_VAR file1 ... fileN )
+#
+# ::
+#
+# If you don't use the KDE3_AUTOMOC() macro, for the files
+# listed here moc files will be created (named "foo.moc.cpp")
+#
+#
+#
+# KDE3_ADD_DCOP_SKELS(SRCS_VAR header1.h ... headerN.h )
+#
+# ::
+#
+# Use this to generate DCOP skeletions from the listed headers.
+#
+#
+#
+# KDE3_ADD_DCOP_STUBS(SRCS_VAR header1.h ... headerN.h )
+#
+# ::
#
+# Use this to generate DCOP stubs from the listed headers.
#
-# It also adds the following macros (from KDE3Macros.cmake)
-# SRCS_VAR is always the variable which contains the list of source files for your application or library.
#
-# KDE3_AUTOMOC(file1 ... fileN)
-# Call this if you want to have automatic moc file handling.
-# This means if you include "foo.moc" in the source file foo.cpp
-# a moc file for the header foo.h will be created automatically.
-# You can set the property SKIP_AUTOMAKE using set_source_files_properties()
-# to exclude some files in the list from being processed.
#
-# KDE3_ADD_MOC_FILES(SRCS_VAR file1 ... fileN )
-# If you don't use the KDE3_AUTOMOC() macro, for the files
-# listed here moc files will be created (named "foo.moc.cpp")
+# KDE3_ADD_UI_FILES(SRCS_VAR file1.ui ... fileN.ui )
#
-# KDE3_ADD_DCOP_SKELS(SRCS_VAR header1.h ... headerN.h )
-# Use this to generate DCOP skeletions from the listed headers.
+# ::
#
-# KDE3_ADD_DCOP_STUBS(SRCS_VAR header1.h ... headerN.h )
-# Use this to generate DCOP stubs from the listed headers.
+# Use this to add the Qt designer ui files to your application/library.
+#
+#
+#
+# KDE3_ADD_KCFG_FILES(SRCS_VAR file1.kcfgc ... fileN.kcfgc )
+#
+# ::
+#
+# Use this to add KDE kconfig compiler files to your application/library.
#
-# KDE3_ADD_UI_FILES(SRCS_VAR file1.ui ... fileN.ui )
-# Use this to add the Qt designer ui files to your application/library.
#
-# KDE3_ADD_KCFG_FILES(SRCS_VAR file1.kcfgc ... fileN.kcfgc )
-# Use this to add KDE kconfig compiler files to your application/library.
#
# KDE3_INSTALL_LIBTOOL_FILE(target)
-# This will create and install a simple libtool file for the given target.
#
-# KDE3_ADD_EXECUTABLE(name file1 ... fileN )
-# Currently identical to add_executable(), may provide some advanced features in the future.
+# ::
+#
+# This will create and install a simple libtool file for the given target.
+#
+#
+#
+# KDE3_ADD_EXECUTABLE(name file1 ... fileN )
+#
+# ::
+#
+# Currently identical to add_executable(), may provide some advanced
+# features in the future.
+#
+#
+#
+# KDE3_ADD_KPART(name [WITH_PREFIX] file1 ... fileN )
+#
+# ::
+#
+# Create a KDE plugin (KPart, kioslave, etc.) from the given source files.
+# If WITH_PREFIX is given, the resulting plugin will have the prefix "lib",
+# otherwise it won't.
+# It creates and installs an appropriate libtool la-file.
+#
+#
+#
+# KDE3_ADD_KDEINIT_EXECUTABLE(name file1 ... fileN )
+#
+# ::
+#
+# Create a KDE application in the form of a module loadable via kdeinit.
+# A library named kdeinit_<name> will be created and a small executable
+# which links to it.
+#
#
-# KDE3_ADD_KPART(name [WITH_PREFIX] file1 ... fileN )
-# Create a KDE plugin (KPart, kioslave, etc.) from the given source files.
-# If WITH_PREFIX is given, the resulting plugin will have the prefix "lib", otherwise it won't.
-# It creates and installs an appropriate libtool la-file.
#
-# KDE3_ADD_KDEINIT_EXECUTABLE(name file1 ... fileN )
-# Create a KDE application in the form of a module loadable via kdeinit.
-# A library named kdeinit_<name> will be created and a small executable which links to it.
+# The option KDE3_ENABLE_FINAL to enable all-in-one compilation is no
+# longer supported.
#
-# The option KDE3_ENABLE_FINAL to enable all-in-one compilation is
-# no longer supported.
#
#
# Author: Alexander Neundorf <neundorf@kde.org>
@@ -124,7 +195,7 @@ if(KDECONFIG_EXECUTABLE)
if ("${kde_version}" MATCHES "KDE: 3\\.")
execute_process(COMMAND ${KDECONFIG_EXECUTABLE} --prefix
OUTPUT_VARIABLE kdedir )
- string(REGEX REPLACE "\n" "" KDE3PREFIX "${kdedir}")
+ string(REPLACE "\n" "" KDE3PREFIX "${kdedir}")
endif ()
endif()
diff --git a/Modules/FindKDE4.cmake b/Modules/FindKDE4.cmake
index c653a04cd..55301667b 100644
--- a/Modules/FindKDE4.cmake
+++ b/Modules/FindKDE4.cmake
@@ -1,11 +1,24 @@
-# Find KDE4 and provide all necessary variables and macros to compile software for it.
-# It looks for KDE 4 in the following directories in the given order:
-# CMAKE_INSTALL_PREFIX
-# KDEDIRS
-# /opt/kde4
+#.rst:
+# FindKDE4
+# --------
#
-# Please look in FindKDE4Internal.cmake and KDE4Macros.cmake for more information.
-# They are installed with the KDE 4 libraries in $KDEDIRS/share/apps/cmake/modules/.
+#
+#
+# Find KDE4 and provide all necessary variables and macros to compile
+# software for it. It looks for KDE 4 in the following directories in
+# the given order:
+#
+# ::
+#
+# CMAKE_INSTALL_PREFIX
+# KDEDIRS
+# /opt/kde4
+#
+#
+#
+# Please look in FindKDE4Internal.cmake and KDE4Macros.cmake for more
+# information. They are installed with the KDE 4 libraries in
+# $KDEDIRS/share/apps/cmake/modules/.
#
# Author: Alexander Neundorf <neundorf@kde.org>
@@ -92,7 +105,7 @@ if (KDE4_DATA_DIR)
endif ()
# use FindKDE4Internal.cmake to do the rest
- find_package(KDE4Internal ${_req} ${_quiet})
+ find_package(KDE4Internal ${_req} ${_quiet} NO_POLICY_SCOPE)
else ()
if (KDE4_FIND_REQUIRED)
message(FATAL_ERROR "ERROR: cmake/modules/FindKDE4Internal.cmake not found in ${_data_DIR}")
diff --git a/Modules/FindLAPACK.cmake b/Modules/FindLAPACK.cmake
index 3167850db..b11edc334 100644
--- a/Modules/FindLAPACK.cmake
+++ b/Modules/FindLAPACK.cmake
@@ -1,27 +1,37 @@
-# - Find LAPACK library
-# This module finds an installed fortran library that implements the LAPACK
-# linear-algebra interface (see http://www.netlib.org/lapack/).
+#.rst:
+# FindLAPACK
+# ----------
#
-# The approach follows that taken for the autoconf macro file, acx_lapack.m4
-# (distributed at http://ac-archive.sourceforge.net/ac-archive/acx_lapack.html).
+# Find LAPACK library
+#
+# This module finds an installed fortran library that implements the
+# LAPACK linear-algebra interface (see http://www.netlib.org/lapack/).
+#
+# The approach follows that taken for the autoconf macro file,
+# acx_lapack.m4 (distributed at
+# http://ac-archive.sourceforge.net/ac-archive/acx_lapack.html).
#
# This module sets the following variables:
-# LAPACK_FOUND - set to true if a library implementing the LAPACK interface
-# is found
-# LAPACK_LINKER_FLAGS - uncached list of required linker flags (excluding -l
-# and -L).
-# LAPACK_LIBRARIES - uncached list of libraries (using full path name) to
-# link against to use LAPACK
-# LAPACK95_LIBRARIES - uncached list of libraries (using full path name) to
-# link against to use LAPACK95
-# LAPACK95_FOUND - set to true if a library implementing the LAPACK f95
-# interface is found
-# BLA_STATIC if set on this determines what kind of linkage we do (static)
-# BLA_VENDOR if set checks only the specified vendor, if not set checks
-# all the possibilities
-# BLA_F95 if set on tries to find the f95 interfaces for BLAS/LAPACK
-### List of vendors (BLA_VENDOR) valid in this module
-## Intel(mkl), ACML,Apple, NAS, Generic
+#
+# ::
+#
+# LAPACK_FOUND - set to true if a library implementing the LAPACK interface
+# is found
+# LAPACK_LINKER_FLAGS - uncached list of required linker flags (excluding -l
+# and -L).
+# LAPACK_LIBRARIES - uncached list of libraries (using full path name) to
+# link against to use LAPACK
+# LAPACK95_LIBRARIES - uncached list of libraries (using full path name) to
+# link against to use LAPACK95
+# LAPACK95_FOUND - set to true if a library implementing the LAPACK f95
+# interface is found
+# BLA_STATIC if set on this determines what kind of linkage we do (static)
+# BLA_VENDOR if set checks only the specified vendor, if not set checks
+# all the possibilities
+# BLA_F95 if set on tries to find the f95 interfaces for BLAS/LAPACK
+#
+# ## List of vendors (BLA_VENDOR) valid in this module # Intel(mkl),
+# ACML,Apple, NAS, Generic
#=============================================================================
# Copyright 2007-2009 Kitware, Inc.
@@ -44,6 +54,10 @@ include(${CMAKE_CURRENT_LIST_DIR}/CheckFunctionExists.cmake)
else ()
include(${CMAKE_CURRENT_LIST_DIR}/CheckFortranFunctionExists.cmake)
endif ()
+include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake)
+
+cmake_push_check_state()
+set(CMAKE_REQUIRED_QUIET ${LAPACK_FIND_QUIETLY})
set(LAPACK_FOUND FALSE)
set(LAPACK95_FOUND FALSE)
@@ -145,7 +159,7 @@ endif()
if(BLAS_FOUND)
set(LAPACK_LINKER_FLAGS ${BLAS_LINKER_FLAGS})
- if ($ENV{BLA_VENDOR} MATCHES ".+")
+ if (NOT $ENV{BLA_VENDOR} STREQUAL "")
set(BLA_VENDOR $ENV{BLA_VENDOR})
else ()
if(NOT BLA_VENDOR)
@@ -169,7 +183,7 @@ endif ()
#acml lapack
- if (BLA_VENDOR MATCHES "ACML.*" OR BLA_VENDOR STREQUAL "All")
+ if (BLA_VENDOR MATCHES "ACML" OR BLA_VENDOR STREQUAL "All")
if (BLAS_LIBRARIES MATCHES ".+acml.+")
set (LAPACK_LIBRARIES ${BLAS_LIBRARIES})
endif ()
@@ -219,7 +233,7 @@ if (BLA_VENDOR STREQUAL "Generic" OR
endif ()
endif ()
#intel lapack
-if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All")
+if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All")
if (NOT WIN32)
set(LM "-lm")
endif ()
@@ -229,57 +243,61 @@ if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All")
else()
find_package(Threads REQUIRED)
endif()
+
+ set(LAPACK_SEARCH_LIBS "")
+
if (BLA_F95)
- if(NOT LAPACK95_LIBRARIES)
- # old
- check_lapack_libraries(
- LAPACK95_LIBRARIES
- LAPACK
- cheev
- ""
- "mkl_lapack95"
- "${BLAS95_LIBRARIES}"
- "${CMAKE_THREAD_LIBS_INIT};${LM}"
- )
- endif()
- if(NOT LAPACK95_LIBRARIES)
- # new >= 10.3
- check_lapack_libraries(
- LAPACK95_LIBRARIES
- LAPACK
- CHEEV
- ""
- "mkl_intel_lp64"
- "${BLAS95_LIBRARIES}"
- "${CMAKE_THREAD_LIBS_INIT};${LM}"
- )
- endif()
+ set(LAPACK_mkl_SEARCH_SYMBOL "CHEEV")
+ set(_LIBRARIES LAPACK95_LIBRARIES)
+ set(_BLAS_LIBRARIES ${BLAS95_LIBRARIES})
+
+ # old
+ list(APPEND LAPACK_SEARCH_LIBS
+ "mkl_lapack95")
+ # new >= 10.3
+ list(APPEND LAPACK_SEARCH_LIBS
+ "mkl_intel_c")
+ list(APPEND LAPACK_SEARCH_LIBS
+ "mkl_intel_lp64")
else()
- if(NOT LAPACK_LIBRARIES)
- # old
- check_lapack_libraries(
- LAPACK_LIBRARIES
- LAPACK
- cheev
- ""
- "mkl_lapack"
- "${BLAS_LIBRARIES}"
- "${CMAKE_THREAD_LIBS_INIT};${LM}"
- )
- endif()
- if(NOT LAPACK_LIBRARIES)
- # new >= 10.3
+ set(LAPACK_mkl_SEARCH_SYMBOL "cheev")
+ set(_LIBRARIES LAPACK_LIBRARIES)
+ set(_BLAS_LIBRARIES ${BLAS_LIBRARIES})
+
+ # old
+ list(APPEND LAPACK_SEARCH_LIBS
+ "mkl_lapack")
+ # new >= 10.3
+ list(APPEND LAPACK_SEARCH_LIBS
+ "mkl_gf_lp64")
+ endif()
+
+ # First try empty lapack libs
+ if (NOT ${_LIBRARIES})
+ check_lapack_libraries(
+ ${_LIBRARIES}
+ BLAS
+ ${LAPACK_mkl_SEARCH_SYMBOL}
+ ""
+ ""
+ "${_BLAS_LIBRARIES}"
+ "${CMAKE_THREAD_LIBS_INIT};${LM}"
+ )
+ endif ()
+ # Then try the search libs
+ foreach (IT ${LAPACK_SEARCH_LIBS})
+ if (NOT ${_LIBRARIES})
check_lapack_libraries(
- LAPACK_LIBRARIES
- LAPACK
- cheev
+ ${_LIBRARIES}
+ BLAS
+ ${LAPACK_mkl_SEARCH_SYMBOL}
""
- "mkl_gf_lp64"
- "${BLAS_LIBRARIES}"
+ "${IT}"
+ "${_BLAS_LIBRARIES}"
"${CMAKE_THREAD_LIBS_INIT};${LM}"
)
- endif()
- endif()
+ endif ()
+ endforeach ()
endif ()
endif()
else()
@@ -333,4 +351,5 @@ else()
endif()
endif()
+cmake_pop_check_state()
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_lapack_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
diff --git a/Modules/FindLATEX.cmake b/Modules/FindLATEX.cmake
index bc752a95a..ae83733c2 100644
--- a/Modules/FindLATEX.cmake
+++ b/Modules/FindLATEX.cmake
@@ -1,18 +1,57 @@
-# - Find Latex
-# This module finds if Latex is installed and determines where the
-# executables are. This code sets the following variables:
+#.rst:
+# FindLATEX
+# ---------
#
-# LATEX_COMPILER: path to the LaTeX compiler
-# PDFLATEX_COMPILER: path to the PdfLaTeX compiler
-# BIBTEX_COMPILER: path to the BibTeX compiler
-# MAKEINDEX_COMPILER: path to the MakeIndex compiler
-# DVIPS_CONVERTER: path to the DVIPS converter
-# PS2PDF_CONVERTER: path to the PS2PDF converter
-# LATEX2HTML_CONVERTER: path to the LaTeX2Html converter
+# Find Latex
#
+# This module finds an installed Latex and determines the location
+# of the compiler. Additionally the module looks for Latex-related
+# software like BibTeX.
+#
+# This module sets the following result variables::
+#
+# LATEX_FOUND: whether found Latex and requested components
+# LATEX_<component>_FOUND: whether found <component>
+# LATEX_COMPILER: path to the LaTeX compiler
+# PDFLATEX_COMPILER: path to the PdfLaTeX compiler
+# XELATEX_COMPILER: path to the XeLaTeX compiler
+# LUALATEX_COMPILER: path to the LuaLaTeX compiler
+# BIBTEX_COMPILER: path to the BibTeX compiler
+# BIBER_COMPILER: path to the Biber compiler
+# MAKEINDEX_COMPILER: path to the MakeIndex compiler
+# XINDY_COMPILER: path to the xindy compiler
+# DVIPS_CONVERTER: path to the DVIPS converter
+# DVIPDF_CONVERTER: path to the DVIPDF converter
+# PS2PDF_CONVERTER: path to the PS2PDF converter
+# PDFTOPS_CONVERTER: path to the pdftops converter
+# LATEX2HTML_CONVERTER: path to the LaTeX2Html converter
+# HTLATEX_COMPILER: path to the htlatex compiler
+#
+# Possible components are::
+#
+# PDFLATEX
+# XELATEX
+# LUALATEX
+# BIBTEX
+# BIBER
+# MAKEINDEX
+# XINDY
+# DVIPS
+# DVIPDF
+# PS2PDF
+# PDFTOPS
+# LATEX2HTML
+# HTLATEX
+#
+# Example Usages::
+#
+# find_package(LATEX)
+# find_package(LATEX COMPONENTS PDFLATEX)
+# find_package(LATEX COMPONENTS BIBTEX PS2PDF)
#=============================================================================
-# Copyright 2002-2009 Kitware, Inc.
+# Copyright 2002-2015 Kitware, Inc.
+# Copyright 2014-2015 Christoph Grüninger <foss@grueninger.de>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
@@ -25,9 +64,7 @@
# License text for the above reference.)
if (WIN32)
-
# Try to find the MikTex binary path (look for its package manager).
-
find_path(MIKTEX_BINARY_PATH mpm.exe
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MiK\\MiKTeX\\CurrentVersion\\MiKTeX;Install Root]/miktex/bin"
DOC
@@ -36,7 +73,6 @@ if (WIN32)
mark_as_advanced(MIKTEX_BINARY_PATH)
# Try to find the GhostScript binary path (look for gswin32).
-
get_filename_component(GHOSTSCRIPT_BINARY_PATH_FROM_REGISTERY_8_00
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\AFPL Ghostscript\\8.00;GS_DLL]" PATH
)
@@ -57,70 +93,198 @@ if (WIN32)
DOC "Path to the GhostScript library directory."
)
mark_as_advanced(GHOSTSCRIPT_LIBRARY_PATH)
-
endif ()
+# try to find Latex and the related programs
find_program(LATEX_COMPILER
NAMES latex
PATHS ${MIKTEX_BINARY_PATH}
/usr/bin
)
+# find pdflatex
find_program(PDFLATEX_COMPILER
NAMES pdflatex
PATHS ${MIKTEX_BINARY_PATH}
/usr/bin
)
+if (PDFLATEX_COMPILER)
+ set(LATEX_PDFLATEX_FOUND TRUE)
+else()
+ set(LATEX_PDFLATEX_FOUND FALSE)
+endif()
+
+# find xelatex
+find_program(XELATEX_COMPILER
+ NAMES xelatex
+ PATHS ${MIKTEX_BINARY_PATH}
+ /usr/bin
+)
+if (XELATEX_COMPILER)
+ set(LATEX_XELATEX_FOUND TRUE)
+else()
+ set(LATEX_XELATEX_FOUND FALSE)
+endif()
+
+# find lualatex
+find_program(LUALATEX_COMPILER
+ NAMES lualatex
+ PATHS ${MIKTEX_BINARY_PATH}
+ /usr/bin
+)
+if (LUALATEX_COMPILER)
+ set(LATEX_LUALATEX_FOUND TRUE)
+else()
+ set(LATEX_LUALATEX_FOUND FALSE)
+endif()
+# find bibtex
find_program(BIBTEX_COMPILER
NAMES bibtex
PATHS ${MIKTEX_BINARY_PATH}
/usr/bin
)
+if (BIBTEX_COMPILER)
+ set(LATEX_BIBTEX_FOUND TRUE)
+else()
+ set(LATEX_BIBTEX_FOUND FALSE)
+endif()
+# find biber
+find_program(BIBER_COMPILER
+ NAMES biber
+ PATHS ${MIKTEX_BINARY_PATH}
+ /usr/bin
+)
+if (BIBER_COMPILER)
+ set(LATEX_BIBER_FOUND TRUE)
+else()
+ set(LATEX_BIBER_FOUND FALSE)
+endif()
+
+# find makeindex
find_program(MAKEINDEX_COMPILER
NAMES makeindex
PATHS ${MIKTEX_BINARY_PATH}
/usr/bin
)
+if (MAKEINDEX_COMPILER)
+ set(LATEX_MAKEINDEX_FOUND TRUE)
+else()
+ set(LATEX_MAKEINDEX_FOUND FALSE)
+endif()
+# find xindy
+find_program(XINDY_COMPILER
+ NAMES xindy
+ PATHS ${MIKTEX_BINARY_PATH}
+ /usr/bin
+)
+if (XINDY_COMPILER)
+ set(LATEX_XINDY_FOUND TRUE)
+else()
+ set(LATEX_XINDY_FOUND FALSE)
+endif()
+
+# find dvips
find_program(DVIPS_CONVERTER
NAMES dvips
PATHS ${MIKTEX_BINARY_PATH}
/usr/bin
)
+if (DVIPS_CONVERTER)
+ set(LATEX_DVIPS_FOUND TRUE)
+else()
+ set(LATEX_DVIPS_FOUND FALSE)
+endif()
+# find dvipdf
find_program(DVIPDF_CONVERTER
NAMES dvipdfm dvipdft dvipdf
PATHS ${MIKTEX_BINARY_PATH}
/usr/bin
)
+if (DVIPDF_CONVERTER)
+ set(LATEX_DVIPDF_FOUND TRUE)
+else()
+ set(LATEX_DVIPDF_FOUND FALSE)
+endif()
+# find ps2pdf
if (WIN32)
find_program(PS2PDF_CONVERTER
- NAMES ps2pdf14.bat
+ NAMES ps2pdf14.bat ps2pdf14 ps2pdf
PATHS ${GHOSTSCRIPT_LIBRARY_PATH}
+ ${MIKTEX_BINARY_PATH}
)
else ()
find_program(PS2PDF_CONVERTER
NAMES ps2pdf14 ps2pdf
)
endif ()
+if (PS2PDF_CONVERTER)
+ set(LATEX_PS2PDF_FOUND TRUE)
+else()
+ set(LATEX_PS2PDF_FOUND FALSE)
+endif()
+
+# find pdftops
+find_program(PDFTOPS_CONVERTER
+ NAMES pdftops
+ PATHS ${MIKTEX_BINARY_PATH}
+ /usr/bin
+)
+if (PDFTOPS_CONVERTER)
+ set(LATEX_PDFTOPS_FOUND TRUE)
+else()
+ set(LATEX_PDFTOPS_FOUND FALSE)
+endif()
+# find latex2html
find_program(LATEX2HTML_CONVERTER
NAMES latex2html
PATHS ${MIKTEX_BINARY_PATH}
/usr/bin
)
+if (LATEX2HTML_CONVERTER)
+ set(LATEX_LATEX2HTML_FOUND TRUE)
+else()
+ set(LATEX_LATEX2HTML_FOUND FALSE)
+endif()
+
+# find htlatex
+find_program(HTLATEX_COMPILER
+ NAMES htlatex
+ PATHS ${MIKTEX_BINARY_PATH}
+ /usr/bin
+)
+if (HTLATEX_COMPILER)
+ set(LATEX_HTLATEX_FOUND TRUE)
+else()
+ set(LATEX_HTLATEX_FOUND FALSE)
+endif()
mark_as_advanced(
LATEX_COMPILER
PDFLATEX_COMPILER
+ XELATEX_COMPILER
+ LUALATEX_COMPILER
BIBTEX_COMPILER
+ BIBER_COMPILER
MAKEINDEX_COMPILER
+ XINDY_COMPILER
DVIPS_CONVERTER
DVIPDF_CONVERTER
PS2PDF_CONVERTER
+ PDFTOPS_CONVERTER
LATEX2HTML_CONVERTER
+ HTLATEX_COMPILER
+)
+
+# handle variables for found Latex and its components
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+find_package_handle_standard_args(LATEX
+ REQUIRED_VARS LATEX_COMPILER
+ HANDLE_COMPONENTS
)
diff --git a/Modules/FindLibArchive.cmake b/Modules/FindLibArchive.cmake
index be931c525..471a4f188 100644
--- a/Modules/FindLibArchive.cmake
+++ b/Modules/FindLibArchive.cmake
@@ -1,10 +1,17 @@
-# - Find libarchive library and headers
+#.rst:
+# FindLibArchive
+# --------------
+#
+# Find libarchive library and headers
+#
# The module defines the following variables:
#
-# LibArchive_FOUND - true if libarchive was found
-# LibArchive_INCLUDE_DIRS - include search path
-# LibArchive_LIBRARIES - libraries to link
-# LibArchive_VERSION - libarchive 3-component version number
+# ::
+#
+# LibArchive_FOUND - true if libarchive was found
+# LibArchive_INCLUDE_DIRS - include search path
+# LibArchive_LIBRARIES - libraries to link
+# LibArchive_VERSION - libarchive 3-component version number
#=============================================================================
# Copyright 2010 Kitware, Inc.
diff --git a/Modules/FindLibLZMA.cmake b/Modules/FindLibLZMA.cmake
index 837e63324..742b851cd 100644
--- a/Modules/FindLibLZMA.cmake
+++ b/Modules/FindLibLZMA.cmake
@@ -1,16 +1,23 @@
-# - Find LibLZMA
+#.rst:
+# FindLibLZMA
+# -----------
+#
+# Find LibLZMA
+#
# Find LibLZMA headers and library
#
-# LIBLZMA_FOUND - True if liblzma is found.
-# LIBLZMA_INCLUDE_DIRS - Directory where liblzma headers are located.
-# LIBLZMA_LIBRARIES - Lzma libraries to link against.
-# LIBLZMA_HAS_AUTO_DECODER - True if lzma_auto_decoder() is found (required).
-# LIBLZMA_HAS_EASY_ENCODER - True if lzma_easy_encoder() is found (required).
-# LIBLZMA_HAS_LZMA_PRESET - True if lzma_lzma_preset() is found (required).
-# LIBLZMA_VERSION_MAJOR - The major version of lzma
-# LIBLZMA_VERSION_MINOR - The minor version of lzma
-# LIBLZMA_VERSION_PATCH - The patch version of lzma
-# LIBLZMA_VERSION_STRING - version number as a string (ex: "5.0.3")
+# ::
+#
+# LIBLZMA_FOUND - True if liblzma is found.
+# LIBLZMA_INCLUDE_DIRS - Directory where liblzma headers are located.
+# LIBLZMA_LIBRARIES - Lzma libraries to link against.
+# LIBLZMA_HAS_AUTO_DECODER - True if lzma_auto_decoder() is found (required).
+# LIBLZMA_HAS_EASY_ENCODER - True if lzma_easy_encoder() is found (required).
+# LIBLZMA_HAS_LZMA_PRESET - True if lzma_lzma_preset() is found (required).
+# LIBLZMA_VERSION_MAJOR - The major version of lzma
+# LIBLZMA_VERSION_MINOR - The minor version of lzma
+# LIBLZMA_VERSION_PATCH - The patch version of lzma
+# LIBLZMA_VERSION_STRING - version number as a string (ex: "5.0.3")
#=============================================================================
# Copyright 2008 Per Øyvind Karlsen <peroyvind@mandriva.org>
@@ -48,9 +55,12 @@ endif()
# Avoid using old codebase
if (LIBLZMA_LIBRARY)
include(${CMAKE_CURRENT_LIST_DIR}/CheckLibraryExists.cmake)
+ set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET})
+ set(CMAKE_REQUIRED_QUIET ${LibLZMA_FIND_QUIETLY})
CHECK_LIBRARY_EXISTS(${LIBLZMA_LIBRARY} lzma_auto_decoder "" LIBLZMA_HAS_AUTO_DECODER)
CHECK_LIBRARY_EXISTS(${LIBLZMA_LIBRARY} lzma_easy_encoder "" LIBLZMA_HAS_EASY_ENCODER)
CHECK_LIBRARY_EXISTS(${LIBLZMA_LIBRARY} lzma_lzma_preset "" LIBLZMA_HAS_LZMA_PRESET)
+ set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE})
endif ()
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
diff --git a/Modules/FindLibXml2.cmake b/Modules/FindLibXml2.cmake
index 858496e09..73224286d 100644
--- a/Modules/FindLibXml2.cmake
+++ b/Modules/FindLibXml2.cmake
@@ -1,12 +1,19 @@
-# - Try to find the LibXml2 xml processing library
+#.rst:
+# FindLibXml2
+# -----------
+#
+# Try to find the LibXml2 xml processing library
+#
# Once done this will define
#
-# LIBXML2_FOUND - System has LibXml2
-# LIBXML2_INCLUDE_DIR - The LibXml2 include directory
-# LIBXML2_LIBRARIES - The libraries needed to use LibXml2
-# LIBXML2_DEFINITIONS - Compiler switches required for using LibXml2
-# LIBXML2_XMLLINT_EXECUTABLE - The XML checking tool xmllint coming with LibXml2
-# LIBXML2_VERSION_STRING - the version of LibXml2 found (since CMake 2.8.8)
+# ::
+#
+# LIBXML2_FOUND - System has LibXml2
+# LIBXML2_INCLUDE_DIR - The LibXml2 include directory
+# LIBXML2_LIBRARIES - The libraries needed to use LibXml2
+# LIBXML2_DEFINITIONS - Compiler switches required for using LibXml2
+# LIBXML2_XMLLINT_EXECUTABLE - The XML checking tool xmllint coming with LibXml2
+# LIBXML2_VERSION_STRING - the version of LibXml2 found (since CMake 2.8.8)
#=============================================================================
# Copyright 2006-2009 Kitware, Inc.
diff --git a/Modules/FindLibXslt.cmake b/Modules/FindLibXslt.cmake
index 7d142f430..2416341fb 100644
--- a/Modules/FindLibXslt.cmake
+++ b/Modules/FindLibXslt.cmake
@@ -1,14 +1,26 @@
-# - Try to find the LibXslt library
+#.rst:
+# FindLibXslt
+# -----------
+#
+# Try to find the LibXslt library
+#
# Once done this will define
#
-# LIBXSLT_FOUND - system has LibXslt
-# LIBXSLT_INCLUDE_DIR - the LibXslt include directory
-# LIBXSLT_LIBRARIES - Link these to LibXslt
-# LIBXSLT_DEFINITIONS - Compiler switches required for using LibXslt
-# LIBXSLT_VERSION_STRING - version of LibXslt found (since CMake 2.8.8)
-# Additionally, the following two variables are set (but not required for using xslt):
-# LIBXSLT_EXSLT_LIBRARIES - Link to these if you need to link against the exslt library
-# LIBXSLT_XSLTPROC_EXECUTABLE - Contains the full path to the xsltproc executable if found
+# ::
+#
+# LIBXSLT_FOUND - system has LibXslt
+# LIBXSLT_INCLUDE_DIR - the LibXslt include directory
+# LIBXSLT_LIBRARIES - Link these to LibXslt
+# LIBXSLT_DEFINITIONS - Compiler switches required for using LibXslt
+# LIBXSLT_VERSION_STRING - version of LibXslt found (since CMake 2.8.8)
+#
+# Additionally, the following two variables are set (but not required
+# for using xslt):
+#
+# ``LIBXSLT_EXSLT_LIBRARIES``
+# Link to these if you need to link against the exslt library.
+# ``LIBXSLT_XSLTPROC_EXECUTABLE``
+# Contains the full path to the xsltproc executable if found.
#=============================================================================
# Copyright 2006-2009 Kitware, Inc.
diff --git a/Modules/FindLua.cmake b/Modules/FindLua.cmake
new file mode 100644
index 000000000..731f5f222
--- /dev/null
+++ b/Modules/FindLua.cmake
@@ -0,0 +1,171 @@
+#.rst:
+# FindLua
+# -------
+#
+#
+#
+# Locate Lua library This module defines
+#
+# ::
+#
+# LUA_FOUND - if false, do not try to link to Lua
+# LUA_LIBRARIES - both lua and lualib
+# LUA_INCLUDE_DIR - where to find lua.h
+# LUA_VERSION_STRING - the version of Lua found
+# LUA_VERSION_MAJOR - the major version of Lua
+# LUA_VERSION_MINOR - the minor version of Lua
+# LUA_VERSION_PATCH - the patch version of Lua
+#
+#
+#
+# Note that the expected include convention is
+#
+# ::
+#
+# #include "lua.h"
+#
+# and not
+#
+# ::
+#
+# #include <lua/lua.h>
+#
+# This is because, the lua location is not standardized and may exist in
+# locations other than lua/
+
+#=============================================================================
+# Copyright 2007-2009 Kitware, Inc.
+# Copyright 2013 Rolf Eike Beer <eike@sf-mail.de>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+unset(_lua_include_subdirs)
+unset(_lua_library_names)
+
+# this is a function only to have all the variables inside go away automatically
+function(set_lua_version_vars)
+ set(LUA_VERSIONS5 5.3 5.2 5.1 5.0)
+
+ if (Lua_FIND_VERSION_EXACT)
+ if (Lua_FIND_VERSION_COUNT GREATER 1)
+ set(lua_append_versions ${Lua_FIND_VERSION_MAJOR}.${Lua_FIND_VERSION_MINOR})
+ endif ()
+ elseif (Lua_FIND_VERSION)
+ # once there is a different major version supported this should become a loop
+ if (NOT Lua_FIND_VERSION_MAJOR GREATER 5)
+ if (Lua_FIND_VERSION_COUNT EQUAL 1)
+ set(lua_append_versions ${LUA_VERSIONS5})
+ else ()
+ foreach (subver IN LISTS LUA_VERSIONS5)
+ if (NOT subver VERSION_LESS ${Lua_FIND_VERSION})
+ list(APPEND lua_append_versions ${subver})
+ endif ()
+ endforeach ()
+ endif ()
+ endif ()
+ else ()
+ # once there is a different major version supported this should become a loop
+ set(lua_append_versions ${LUA_VERSIONS5})
+ endif ()
+
+ foreach (ver IN LISTS lua_append_versions)
+ string(REGEX MATCH "^([0-9]+)\\.([0-9]+)$" _ver "${ver}")
+ list(APPEND _lua_include_subdirs
+ include/lua${CMAKE_MATCH_1}${CMAKE_MATCH_2}
+ include/lua${CMAKE_MATCH_1}.${CMAKE_MATCH_2}
+ include/lua-${CMAKE_MATCH_1}.${CMAKE_MATCH_2}
+ )
+ list(APPEND _lua_library_names
+ lua${CMAKE_MATCH_1}${CMAKE_MATCH_2}
+ lua${CMAKE_MATCH_1}.${CMAKE_MATCH_2}
+ lua-${CMAKE_MATCH_1}.${CMAKE_MATCH_2}
+ )
+ endforeach ()
+
+ set(_lua_include_subdirs "${_lua_include_subdirs}" PARENT_SCOPE)
+ set(_lua_library_names "${_lua_library_names}" PARENT_SCOPE)
+endfunction(set_lua_version_vars)
+
+set_lua_version_vars()
+
+find_path(LUA_INCLUDE_DIR lua.h
+ HINTS
+ ENV LUA_DIR
+ PATH_SUFFIXES ${_lua_include_subdirs} include/lua include
+ PATHS
+ ~/Library/Frameworks
+ /Library/Frameworks
+ /sw # Fink
+ /opt/local # DarwinPorts
+ /opt/csw # Blastwave
+ /opt
+)
+unset(_lua_include_subdirs)
+
+find_library(LUA_LIBRARY
+ NAMES ${_lua_library_names} lua
+ HINTS
+ ENV LUA_DIR
+ PATH_SUFFIXES lib
+ PATHS
+ ~/Library/Frameworks
+ /Library/Frameworks
+ /sw
+ /opt/local
+ /opt/csw
+ /opt
+)
+unset(_lua_library_names)
+
+if (LUA_LIBRARY)
+ # include the math library for Unix
+ if (UNIX AND NOT APPLE AND NOT BEOS)
+ find_library(LUA_MATH_LIBRARY m)
+ set(LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}")
+ # For Windows and Mac, don't need to explicitly include the math library
+ else ()
+ set(LUA_LIBRARIES "${LUA_LIBRARY}")
+ endif ()
+endif ()
+
+if (LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h")
+ # At least 5.[012] have different ways to express the version
+ # so all of them need to be tested. Lua 5.2 defines LUA_VERSION
+ # and LUA_RELEASE as joined by the C preprocessor, so avoid those.
+ file(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_strings
+ REGEX "^#define[ \t]+LUA_(RELEASE[ \t]+\"Lua [0-9]|VERSION([ \t]+\"Lua [0-9]|_[MR])).*")
+
+ string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MAJOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_MAJOR ";${lua_version_strings};")
+ if (LUA_VERSION_MAJOR MATCHES "^[0-9]+$")
+ string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MINOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_MINOR ";${lua_version_strings};")
+ string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_RELEASE[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_PATCH ";${lua_version_strings};")
+ set(LUA_VERSION_STRING "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}.${LUA_VERSION_PATCH}")
+ else ()
+ string(REGEX REPLACE ".*;#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" LUA_VERSION_STRING ";${lua_version_strings};")
+ if (NOT LUA_VERSION_STRING MATCHES "^[0-9.]+$")
+ string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" LUA_VERSION_STRING ";${lua_version_strings};")
+ endif ()
+ string(REGEX REPLACE "^([0-9]+)\\.[0-9.]*$" "\\1" LUA_VERSION_MAJOR "${LUA_VERSION_STRING}")
+ string(REGEX REPLACE "^[0-9]+\\.([0-9]+)[0-9.]*$" "\\1" LUA_VERSION_MINOR "${LUA_VERSION_STRING}")
+ string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]).*" "\\1" LUA_VERSION_PATCH "${LUA_VERSION_STRING}")
+ endif ()
+
+ unset(lua_version_strings)
+endif()
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+# handle the QUIETLY and REQUIRED arguments and set LUA_FOUND to TRUE if
+# all listed variables are TRUE
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua
+ REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR
+ VERSION_VAR LUA_VERSION_STRING)
+
+mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARY LUA_MATH_LIBRARY)
diff --git a/Modules/FindLua50.cmake b/Modules/FindLua50.cmake
index 0276a98f4..666d90960 100644
--- a/Modules/FindLua50.cmake
+++ b/Modules/FindLua50.cmake
@@ -1,15 +1,33 @@
-# Locate Lua library
-# This module defines
-# LUA50_FOUND, if false, do not try to link to Lua
-# LUA_LIBRARIES, both lua and lualib
-# LUA_INCLUDE_DIR, where to find lua.h and lualib.h (and probably lauxlib.h)
+#.rst:
+# FindLua50
+# ---------
+#
+#
+#
+# Locate Lua library This module defines
+#
+# ::
+#
+# LUA50_FOUND, if false, do not try to link to Lua
+# LUA_LIBRARIES, both lua and lualib
+# LUA_INCLUDE_DIR, where to find lua.h and lualib.h (and probably lauxlib.h)
+#
+#
#
# Note that the expected include convention is
-# #include "lua.h"
+#
+# ::
+#
+# #include "lua.h"
+#
# and not
-# #include <lua/lua.h>
-# This is because, the lua location is not standardized and may exist
-# in locations other than lua/
+#
+# ::
+#
+# #include <lua/lua.h>
+#
+# This is because, the lua location is not standardized and may exist in
+# locations other than lua/
#=============================================================================
# Copyright 2007-2009 Kitware, Inc.
diff --git a/Modules/FindLua51.cmake b/Modules/FindLua51.cmake
index a2bf0c0ef..5b9ff91a7 100644
--- a/Modules/FindLua51.cmake
+++ b/Modules/FindLua51.cmake
@@ -1,16 +1,34 @@
-# Locate Lua library
-# This module defines
-# LUA51_FOUND, if false, do not try to link to Lua
-# LUA_LIBRARIES
-# LUA_INCLUDE_DIR, where to find lua.h
-# LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8)
+#.rst:
+# FindLua51
+# ---------
+#
+#
+#
+# Locate Lua library This module defines
+#
+# ::
+#
+# LUA51_FOUND, if false, do not try to link to Lua
+# LUA_LIBRARIES
+# LUA_INCLUDE_DIR, where to find lua.h
+# LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8)
+#
+#
#
# Note that the expected include convention is
-# #include "lua.h"
+#
+# ::
+#
+# #include "lua.h"
+#
# and not
-# #include <lua/lua.h>
-# This is because, the lua location is not standardized and may exist
-# in locations other than lua/
+#
+# ::
+#
+# #include <lua/lua.h>
+#
+# This is because, the lua location is not standardized and may exist in
+# locations other than lua/
#=============================================================================
# Copyright 2007-2009 Kitware, Inc.
@@ -54,7 +72,7 @@ find_library(LUA_LIBRARY
if(LUA_LIBRARY)
# include the math library for Unix
- if(UNIX AND NOT APPLE AND NOT BEOS)
+ if(UNIX AND NOT APPLE AND NOT BEOS AND NOT HAIKU)
find_library(LUA_MATH_LIBRARY m)
set( LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries")
# For Windows and Mac, don't need to explicitly include the math library
diff --git a/Modules/FindMFC.cmake b/Modules/FindMFC.cmake
index 4ff7586dc..35476289f 100644
--- a/Modules/FindMFC.cmake
+++ b/Modules/FindMFC.cmake
@@ -1,7 +1,16 @@
-# - Find MFC on Windows
-# Find the native MFC - i.e. decide if an application can link to the MFC
-# libraries.
-# MFC_FOUND - Was MFC support found
+#.rst:
+# FindMFC
+# -------
+#
+# Find MFC on Windows
+#
+# Find the native MFC - i.e. decide if an application can link to the
+# MFC libraries.
+#
+# ::
+#
+# MFC_FOUND - Was MFC support found
+#
# You don't need to include anything or link anything to use it.
#=============================================================================
@@ -27,7 +36,7 @@ if(WIN32 AND NOT UNIX AND NOT BORLAND AND NOT MINGW)
endif()
if(MFC_ATTEMPT_TRY_COMPILE)
- if("MFC_HAVE_MFC" MATCHES "^MFC_HAVE_MFC$")
+ if(NOT DEFINED MFC_HAVE_MFC)
set(CHECK_INCLUDE_FILE_VAR "afxwin.h")
configure_file(${CMAKE_ROOT}/Modules/CheckIncludeFile.cxx.in
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx)
diff --git a/Modules/FindMPEG.cmake b/Modules/FindMPEG.cmake
index f99f87b87..26ee8dd43 100644
--- a/Modules/FindMPEG.cmake
+++ b/Modules/FindMPEG.cmake
@@ -1,11 +1,23 @@
-# - Find the native MPEG includes and library
+#.rst:
+# FindMPEG
+# --------
+#
+# Find the native MPEG includes and library
+#
# This module defines
-# MPEG_INCLUDE_DIR, where to find MPEG.h, etc.
-# MPEG_LIBRARIES, the libraries required to use MPEG.
-# MPEG_FOUND, If false, do not try to use MPEG.
+#
+# ::
+#
+# MPEG_INCLUDE_DIR, where to find MPEG.h, etc.
+# MPEG_LIBRARIES, the libraries required to use MPEG.
+# MPEG_FOUND, If false, do not try to use MPEG.
+#
# also defined, but not for general use are
-# MPEG_mpeg2_LIBRARY, where to find the MPEG library.
-# MPEG_vo_LIBRARY, where to find the vo library.
+#
+# ::
+#
+# MPEG_mpeg2_LIBRARY, where to find the MPEG library.
+# MPEG_vo_LIBRARY, where to find the vo library.
#=============================================================================
# Copyright 2002-2009 Kitware, Inc.
diff --git a/Modules/FindMPEG2.cmake b/Modules/FindMPEG2.cmake
index fc01c4c1d..f2f207610 100644
--- a/Modules/FindMPEG2.cmake
+++ b/Modules/FindMPEG2.cmake
@@ -1,11 +1,23 @@
-# - Find the native MPEG2 includes and library
+#.rst:
+# FindMPEG2
+# ---------
+#
+# Find the native MPEG2 includes and library
+#
# This module defines
-# MPEG2_INCLUDE_DIR, path to mpeg2dec/mpeg2.h, etc.
-# MPEG2_LIBRARIES, the libraries required to use MPEG2.
-# MPEG2_FOUND, If false, do not try to use MPEG2.
+#
+# ::
+#
+# MPEG2_INCLUDE_DIR, path to mpeg2dec/mpeg2.h, etc.
+# MPEG2_LIBRARIES, the libraries required to use MPEG2.
+# MPEG2_FOUND, If false, do not try to use MPEG2.
+#
# also defined, but not for general use are
-# MPEG2_mpeg2_LIBRARY, where to find the MPEG2 library.
-# MPEG2_vo_LIBRARY, where to find the vo library.
+#
+# ::
+#
+# MPEG2_mpeg2_LIBRARY, where to find the MPEG2 library.
+# MPEG2_vo_LIBRARY, where to find the vo library.
#=============================================================================
# Copyright 2003-2009 Kitware, Inc.
diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake
index 0eb86a80a..48adf3c1e 100644
--- a/Modules/FindMPI.cmake
+++ b/Modules/FindMPI.cmake
@@ -1,64 +1,88 @@
-# - Find a Message Passing Interface (MPI) implementation
+#.rst:
+# FindMPI
+# -------
+#
+# Find a Message Passing Interface (MPI) implementation
+#
# The Message Passing Interface (MPI) is a library used to write
-# high-performance distributed-memory parallel applications, and
-# is typically deployed on a cluster. MPI is a standard interface
-# (defined by the MPI forum) for which many implementations are
-# available. All of them have somewhat different include paths,
-# libraries to link against, etc., and this module tries to smooth
-# out those differences.
+# high-performance distributed-memory parallel applications, and is
+# typically deployed on a cluster. MPI is a standard interface (defined
+# by the MPI forum) for which many implementations are available. All
+# of them have somewhat different include paths, libraries to link
+# against, etc., and this module tries to smooth out those differences.
#
# === Variables ===
#
-# This module will set the following variables per language in your project,
-# where <lang> is one of C, CXX, or Fortran:
-# MPI_<lang>_FOUND TRUE if FindMPI found MPI flags for <lang>
-# MPI_<lang>_COMPILER MPI Compiler wrapper for <lang>
-# MPI_<lang>_COMPILE_FLAGS Compilation flags for MPI programs
-# MPI_<lang>_INCLUDE_PATH Include path(s) for MPI header
-# MPI_<lang>_LINK_FLAGS Linking flags for MPI programs
-# MPI_<lang>_LIBRARIES All libraries to link MPI programs against
+# This module will set the following variables per language in your
+# project, where <lang> is one of C, CXX, or Fortran:
+#
+# ::
+#
+# MPI_<lang>_FOUND TRUE if FindMPI found MPI flags for <lang>
+# MPI_<lang>_COMPILER MPI Compiler wrapper for <lang>
+# MPI_<lang>_COMPILE_FLAGS Compilation flags for MPI programs
+# MPI_<lang>_INCLUDE_PATH Include path(s) for MPI header
+# MPI_<lang>_LINK_FLAGS Linking flags for MPI programs
+# MPI_<lang>_LIBRARIES All libraries to link MPI programs against
+#
# Additionally, FindMPI sets the following variables for running MPI
# programs from the command line:
-# MPIEXEC Executable for running MPI programs
-# MPIEXEC_NUMPROC_FLAG Flag to pass to MPIEXEC before giving
-# it the number of processors to run on
-# MPIEXEC_PREFLAGS Flags to pass to MPIEXEC directly
-# before the executable to run.
-# MPIEXEC_POSTFLAGS Flags to pass to MPIEXEC after other flags
+#
+# ::
+#
+# MPIEXEC Executable for running MPI programs
+# MPIEXEC_NUMPROC_FLAG Flag to pass to MPIEXEC before giving
+# it the number of processors to run on
+# MPIEXEC_PREFLAGS Flags to pass to MPIEXEC directly
+# before the executable to run.
+# MPIEXEC_POSTFLAGS Flags to pass to MPIEXEC after other flags
+#
# === Usage ===
#
# To use this module, simply call FindMPI from a CMakeLists.txt file, or
-# run find_package(MPI), then run CMake. If you are happy with the auto-
-# detected configuration for your language, then you're done. If not, you
-# have two options:
-# 1. Set MPI_<lang>_COMPILER to the MPI wrapper (mpicc, etc.) of your
-# choice and reconfigure. FindMPI will attempt to determine all the
-# necessary variables using THAT compiler's compile and link flags.
-# 2. If this fails, or if your MPI implementation does not come with
-# a compiler wrapper, then set both MPI_<lang>_LIBRARIES and
-# MPI_<lang>_INCLUDE_PATH. You may also set any other variables
-# listed above, but these two are required. This will circumvent
-# autodetection entirely.
-# When configuration is successful, MPI_<lang>_COMPILER will be set to the
-# compiler wrapper for <lang>, if it was found. MPI_<lang>_FOUND and other
-# variables above will be set if any MPI implementation was found for <lang>,
-# regardless of whether a compiler was found.
-#
-# When using MPIEXEC to execute MPI applications, you should typically use
-# all of the MPIEXEC flags as follows:
-# ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} PROCS
-# ${MPIEXEC_PREFLAGS} EXECUTABLE ${MPIEXEC_POSTFLAGS} ARGS
-# where PROCS is the number of processors on which to execute the program,
-# EXECUTABLE is the MPI program, and ARGS are the arguments to pass to the
-# MPI program.
+# run find_package(MPI), then run CMake. If you are happy with the
+# auto- detected configuration for your language, then you're done. If
+# not, you have two options:
+#
+# ::
+#
+# 1. Set MPI_<lang>_COMPILER to the MPI wrapper (mpicc, etc.) of your
+# choice and reconfigure. FindMPI will attempt to determine all the
+# necessary variables using THAT compiler's compile and link flags.
+# 2. If this fails, or if your MPI implementation does not come with
+# a compiler wrapper, then set both MPI_<lang>_LIBRARIES and
+# MPI_<lang>_INCLUDE_PATH. You may also set any other variables
+# listed above, but these two are required. This will circumvent
+# autodetection entirely.
+#
+# When configuration is successful, MPI_<lang>_COMPILER will be set to
+# the compiler wrapper for <lang>, if it was found. MPI_<lang>_FOUND
+# and other variables above will be set if any MPI implementation was
+# found for <lang>, regardless of whether a compiler was found.
+#
+# When using MPIEXEC to execute MPI applications, you should typically
+# use all of the MPIEXEC flags as follows:
+#
+# ::
+#
+# ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} PROCS
+# ${MPIEXEC_PREFLAGS} EXECUTABLE ${MPIEXEC_POSTFLAGS} ARGS
+#
+# where PROCS is the number of processors on which to execute the
+# program, EXECUTABLE is the MPI program, and ARGS are the arguments to
+# pass to the MPI program.
#
# === Backward Compatibility ===
#
# For backward compatibility with older versions of FindMPI, these
# variables are set, but deprecated:
-# MPI_FOUND MPI_COMPILER MPI_LIBRARY
-# MPI_COMPILE_FLAGS MPI_INCLUDE_PATH MPI_EXTRA_LIBRARY
-# MPI_LINK_FLAGS MPI_LIBRARIES
+#
+# ::
+#
+# MPI_FOUND MPI_COMPILER MPI_LIBRARY
+# MPI_COMPILE_FLAGS MPI_INCLUDE_PATH MPI_EXTRA_LIBRARY
+# MPI_LINK_FLAGS MPI_LIBRARIES
+#
# In new projects, please use the MPI_<lang>_XXX equivalents.
#=============================================================================
@@ -78,7 +102,6 @@
# include this to handle the QUIETLY and REQUIRED arguments
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
-include(${CMAKE_CURRENT_LIST_DIR}/GetPrerequisites.cmake)
#
# This part detects MPI compilers, attempting to wade through the mess of compiler names in
@@ -136,7 +159,7 @@ set(_MPI_XL_Fortran_COMPILER_NAMES mpixlf95 mpixlf95_r mpxlf95 mpxlf95
# or if we know it matches the regular compiler.
foreach (lang C CXX Fortran)
foreach (id GNU Intel PGI XL)
- if (NOT CMAKE_${lang}_COMPILER_ID OR "${CMAKE_${lang}_COMPILER_ID}" STREQUAL "${id}")
+ if (NOT CMAKE_${lang}_COMPILER_ID OR CMAKE_${lang}_COMPILER_ID STREQUAL id)
list(APPEND _MPI_${lang}_COMPILER_NAMES ${_MPI_${id}_${lang}_COMPILER_NAMES})
endif()
unset(_MPI_${id}_${lang}_COMPILER_NAMES) # clean up the namespace here
@@ -150,6 +173,13 @@ set(_MPI_EXEC_NAMES mpiexec mpirun lamexec srun)
# Grab the path to MPI from the registry if we're on windows.
set(_MPI_PREFIX_PATH)
if(WIN32)
+ # MSMPI
+ file(TO_CMAKE_PATH "$ENV{MSMPI_BIN}" msmpi_bin_path) # The default path ends with a '\' and doesn't mix with ';' when appending.
+ list(APPEND _MPI_PREFIX_PATH "${msmpi_bin_path}")
+ unset(msmpi_bin_path)
+ list(APPEND _MPI_PREFIX_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MPI;InstallRoot]/Bin")
+ list(APPEND _MPI_PREFIX_PATH "$ENV{MSMPI_INC}/..") # The SDK is installed separately from the runtime
+ # MPICH
list(APPEND _MPI_PREFIX_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH\\SMPD;binary]/..")
list(APPEND _MPI_PREFIX_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH2;Path]")
list(APPEND _MPI_PREFIX_PATH "$ENV{ProgramW6432}/MPICH2/")
@@ -164,6 +194,21 @@ foreach(SystemPrefixDir ${CMAKE_SYSTEM_PREFIX_PATH})
endforeach()
endforeach()
+function (_mpi_check_compiler compiler options cmdvar resvar)
+ execute_process(
+ COMMAND "${compiler}" ${options}
+ OUTPUT_VARIABLE cmdline OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_VARIABLE cmdline ERROR_STRIP_TRAILING_WHITESPACE
+ RESULT_VARIABLE success)
+ # Intel MPI 5.0.1 will return a zero return code even when the
+ # argument to the MPI compiler wrapper is unknown. Attempt to
+ # catch this case.
+ if(cmdline MATCHES "undefined reference" OR cmdline MATCHES "unrecognized")
+ set(success 255 )
+ endif()
+ set(${cmdvar} "${cmdline}" PARENT_SCOPE)
+ set(${resvar} "${success}" PARENT_SCOPE)
+endfunction()
#
# interrogate_mpi_compiler(lang try_libs)
@@ -196,12 +241,7 @@ function (interrogate_mpi_compiler lang try_libs)
if (MPI_${lang}_COMPILER)
# Check whether the -showme:compile option works. This indicates that we have either OpenMPI
# or a newer version of LAM-MPI, and implies that -showme:link will also work.
- execute_process(
- COMMAND ${MPI_${lang}_COMPILER} -showme:compile
- OUTPUT_VARIABLE MPI_COMPILE_CMDLINE OUTPUT_STRIP_TRAILING_WHITESPACE
- ERROR_VARIABLE MPI_COMPILE_CMDLINE ERROR_STRIP_TRAILING_WHITESPACE
- RESULT_VARIABLE MPI_COMPILER_RETURN)
-
+ _mpi_check_compiler("${MPI_${lang}_COMPILER}" "-showme:compile" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN)
if (MPI_COMPILER_RETURN EQUAL 0)
# If we appear to have -showme:compile, then we should
# also have -showme:link. Try it.
@@ -233,20 +273,12 @@ function (interrogate_mpi_compiler lang try_libs)
# Older versions of LAM-MPI have "-showme". Try to find that.
if (NOT MPI_COMPILER_RETURN EQUAL 0)
- execute_process(
- COMMAND ${MPI_${lang}_COMPILER} -showme
- OUTPUT_VARIABLE MPI_COMPILE_CMDLINE OUTPUT_STRIP_TRAILING_WHITESPACE
- ERROR_VARIABLE MPI_COMPILE_CMDLINE ERROR_STRIP_TRAILING_WHITESPACE
- RESULT_VARIABLE MPI_COMPILER_RETURN)
+ _mpi_check_compiler("${MPI_${lang}_COMPILER}" "-showme" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN)
endif()
# MVAPICH uses -compile-info and -link-info. Try them.
if (NOT MPI_COMPILER_RETURN EQUAL 0)
- execute_process(
- COMMAND ${MPI_${lang}_COMPILER} -compile-info
- OUTPUT_VARIABLE MPI_COMPILE_CMDLINE OUTPUT_STRIP_TRAILING_WHITESPACE
- ERROR_VARIABLE MPI_COMPILE_CMDLINE ERROR_STRIP_TRAILING_WHITESPACE
- RESULT_VARIABLE MPI_COMPILER_RETURN)
+ _mpi_check_compiler("${MPI_${lang}_COMPILER}" "-compile-info" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN)
# If we have compile-info, also have link-info.
if (MPI_COMPILER_RETURN EQUAL 0)
@@ -266,11 +298,7 @@ function (interrogate_mpi_compiler lang try_libs)
# MPICH just uses "-show". Try it.
if (NOT MPI_COMPILER_RETURN EQUAL 0)
- execute_process(
- COMMAND ${MPI_${lang}_COMPILER} -show
- OUTPUT_VARIABLE MPI_COMPILE_CMDLINE OUTPUT_STRIP_TRAILING_WHITESPACE
- ERROR_VARIABLE MPI_COMPILE_CMDLINE ERROR_STRIP_TRAILING_WHITESPACE
- RESULT_VARIABLE MPI_COMPILER_RETURN)
+ _mpi_check_compiler("${MPI_${lang}_COMPILER}" "-show" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN)
endif()
if (MPI_COMPILER_RETURN EQUAL 0)
@@ -306,7 +334,7 @@ function (interrogate_mpi_compiler lang try_libs)
string(REGEX MATCHALL "(^| )-I([^\" ]+|\"[^\"]+\")" MPI_ALL_INCLUDE_PATHS "${MPI_COMPILE_CMDLINE}")
foreach(IPATH ${MPI_ALL_INCLUDE_PATHS})
string(REGEX REPLACE "^ ?-I" "" IPATH ${IPATH})
- string(REGEX REPLACE "//" "/" IPATH ${IPATH})
+ string(REPLACE "//" "/" IPATH ${IPATH})
list(APPEND MPI_INCLUDE_PATH_WORK ${IPATH})
endforeach()
@@ -330,7 +358,7 @@ function (interrogate_mpi_compiler lang try_libs)
set(MPI_LINK_PATH)
foreach(LPATH ${MPI_ALL_LINK_PATHS})
string(REGEX REPLACE "^(| |-Wl,)-L" "" LPATH ${LPATH})
- string(REGEX REPLACE "//" "/" LPATH ${LPATH})
+ string(REPLACE "//" "/" LPATH ${LPATH})
list(APPEND MPI_LINK_PATH ${LPATH})
endforeach()
@@ -341,7 +369,7 @@ function (interrogate_mpi_compiler lang try_libs)
endif()
# Extract linker flags from the link command line
- string(REGEX MATCHALL "(^| )-Wl,([^\" ]+|\"[^\"]+\")" MPI_ALL_LINK_FLAGS "${MPI_LINK_CMDLINE}")
+ string(REGEX MATCHALL "(^| )(-Wl,|-Xlinker )([^\" ]+|\"[^\"]+\")" MPI_ALL_LINK_FLAGS "${MPI_LINK_CMDLINE}")
set(MPI_LINK_FLAGS_WORK)
foreach(FLAG ${MPI_ALL_LINK_FLAGS})
if (MPI_LINK_FLAGS_WORK)
@@ -354,19 +382,14 @@ function (interrogate_mpi_compiler lang try_libs)
# Extract the set of libraries to link against from the link command
# line
string(REGEX MATCHALL "(^| )-l([^\" ]+|\"[^\"]+\")" MPI_LIBNAMES "${MPI_LINK_CMDLINE}")
+
# add the compiler implicit directories because some compilers
# such as the intel compiler have libraries that show up
# in the showme list that can only be found in the implicit
- # link directories of the compiler. Do this for C++ and C
- # compilers if the implicit link directories are defined.
- if (DEFINED CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES)
- set(MPI_LINK_PATH
- "${MPI_LINK_PATH};${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES}")
- endif ()
-
- if (DEFINED CMAKE_C_IMPLICIT_LINK_DIRECTORIES)
+ # link directories of the compiler.
+ if (DEFINED CMAKE_${lang}_IMPLICIT_LINK_DIRECTORIES)
set(MPI_LINK_PATH
- "${MPI_LINK_PATH};${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
+ "${MPI_LINK_PATH};${CMAKE_${lang}_IMPLICIT_LINK_DIRECTORIES}")
endif ()
# Determine full path names for all of the libraries that one needs
@@ -404,16 +427,18 @@ function (interrogate_mpi_compiler lang try_libs)
# Decide between 32-bit and 64-bit libraries for Microsoft's MPI
if("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
- set(MS_MPI_ARCH_DIR amd64)
+ set(MS_MPI_ARCH_DIR x64)
+ set(MS_MPI_ARCH_DIR2 amd64)
else()
- set(MS_MPI_ARCH_DIR i386)
+ set(MS_MPI_ARCH_DIR x86)
+ set(MS_MPI_ARCH_DIR2 i386)
endif()
set(MPI_LIB "MPI_LIB-NOTFOUND" CACHE FILEPATH "Cleared" FORCE)
find_library(MPI_LIB
NAMES mpi mpich mpich2 msmpi
HINTS ${_MPI_BASE_DIR} ${_MPI_PREFIX_PATH}
- PATH_SUFFIXES lib lib/${MS_MPI_ARCH_DIR} Lib Lib/${MS_MPI_ARCH_DIR})
+ PATH_SUFFIXES lib lib/${MS_MPI_ARCH_DIR} Lib Lib/${MS_MPI_ARCH_DIR} Lib/${MS_MPI_ARCH_DIR2})
set(MPI_LIBRARIES_WORK ${MPI_LIB})
# Right now, we only know about the extra libs for C++.
@@ -503,6 +528,7 @@ endfunction()
# Most mpi distros have some form of mpiexec which gives us something we can reliably look for.
find_program(MPIEXEC
NAMES ${_MPI_EXEC_NAMES}
+ HINTS ${MPI_HOME} $ENV{MPI_HOME}
PATHS ${_MPI_PREFIX_PATH}
PATH_SUFFIXES bin
DOC "Executable for running MPI programs.")
@@ -551,21 +577,22 @@ foreach (lang C CXX Fortran)
if (CMAKE_${lang}_COMPILER_WORKS)
# If the user supplies a compiler *name* instead of an absolute path, assume that we need to find THAT compiler.
if (MPI_${lang}_COMPILER)
- is_file_executable(MPI_${lang}_COMPILER MPI_COMPILER_IS_EXECUTABLE)
- if (NOT MPI_COMPILER_IS_EXECUTABLE)
+ if (NOT IS_ABSOLUTE "${MPI_${lang}_COMPILER}")
# Get rid of our default list of names and just search for the name the user wants.
set(_MPI_${lang}_COMPILER_NAMES ${MPI_${lang}_COMPILER})
set(MPI_${lang}_COMPILER "MPI_${lang}_COMPILER-NOTFOUND" CACHE FILEPATH "Cleared" FORCE)
- # If the user specifies a compiler, we don't want to try to search libraries either.
- set(try_libs FALSE)
endif()
+ # If the user specifies a compiler, we don't want to try to search libraries either.
+ set(try_libs FALSE)
else()
set(try_libs TRUE)
endif()
find_program(MPI_${lang}_COMPILER
NAMES ${_MPI_${lang}_COMPILER_NAMES}
- PATHS "${MPI_HOME}/bin" "$ENV{MPI_HOME}/bin" ${_MPI_PREFIX_PATH})
+ HINTS ${_MPI_BASE_DIR}/bin
+ PATHS ${_MPI_PREFIX_PATH}
+ )
interrogate_mpi_compiler(${lang} ${try_libs})
mark_as_advanced(MPI_${lang}_COMPILER)
diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake
index 803848806..7a36719fb 100644
--- a/Modules/FindMatlab.cmake
+++ b/Modules/FindMatlab.cmake
@@ -1,13 +1,210 @@
-# - this module looks for Matlab
-# Defines:
-# MATLAB_INCLUDE_DIR: include path for mex.h, engine.h
-# MATLAB_LIBRARIES: required libraries: libmex, etc
-# MATLAB_MEX_LIBRARY: path to libmex.lib
-# MATLAB_MX_LIBRARY: path to libmx.lib
-# MATLAB_ENG_LIBRARY: path to libeng.lib
+#.rst:
+# FindMatlab
+# ----------
+#
+# Finds Matlab installations and provides Matlab tools and libraries to cmake.
+#
+# This package first intention is to find the libraries associated with Matlab
+# in order to be able to build Matlab extensions (mex files). It can also be
+# used:
+#
+# * run specific commands in Matlab
+# * declare Matlab unit test
+# * retrieve various information from Matlab (mex extensions, versions and
+# release queries, ...)
+#
+# The module supports the following components:
+#
+# * ``MX_LIBRARY`` and ``ENG_LIBRARY`` respectively the MX and ENG libraries of
+# Matlab
+# * ``MAIN_PROGRAM`` the Matlab binary program.
+#
+# .. note::
+#
+# The version given to the :command:`find_package` directive is the Matlab
+# **version**, which should not be confused with the Matlab *release* name
+# (eg. `R2014`).
+# The :command:`matlab_get_version_from_release_name` and
+# :command:`matlab_get_release_name_from_version` allow a mapping
+# from the release name to the version.
+#
+# The variable :variable:`Matlab_ROOT_DIR` may be specified in order to give
+# the path of the desired Matlab version. Otherwise, the behaviour is platform
+# specific:
+#
+# * Windows: The installed versions of Matlab are retrieved from the
+# Windows registry
+# * OS X: The installed versions of Matlab are given by the MATLAB
+# paths in ``/Application``. If no such application is found, it falls back
+# to the one that might be accessible from the PATH.
+# * Unix: The desired Matlab should be accessible from the PATH.
+#
+# Additional information is provided when :variable:`MATLAB_FIND_DEBUG` is set.
+# When a Matlab binary is found automatically and the ``MATLAB_VERSION``
+# is not given, the version is queried from Matlab directly.
+# On Windows, it can make a window running Matlab appear.
+#
+# The mapping of the release names and the version of Matlab is performed by
+# defining pairs (name, version). The variable
+# :variable:`MATLAB_ADDITIONAL_VERSIONS` may be provided before the call to
+# the :command:`find_package` in order to handle additional versions.
+#
+# A Matlab scripts can be added to the set of tests using the
+# :command:`matlab_add_unit_test`. By default, the Matlab unit test framework
+# will be used (>= 2013a) to run this script, but regular ``.m`` files
+# returning an exit code can be used as well (0 indicating a success).
+#
+# Module Input Variables
+# ^^^^^^^^^^^^^^^^^^^^^^
+#
+# Users or projects may set the following variables to configure the module
+# behaviour:
+#
+# :variable:`Matlab_ROOT_DIR`
+# the root of the Matlab installation.
+# :variable:`MATLAB_FIND_DEBUG`
+# outputs debug information
+# :variable:`MATLAB_ADDITIONAL_VERSIONS`
+# additional versions of Matlab for the automatic retrieval of the installed
+# versions.
+#
+# Variables defined by the module
+# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#
+# Result variables
+# """"""""""""""""
+#
+# ``Matlab_FOUND``
+# ``TRUE`` if the Matlab installation is found, ``FALSE``
+# otherwise. All variable below are defined if Matlab is found.
+# ``Matlab_ROOT_DIR``
+# the final root of the Matlab installation determined by the FindMatlab
+# module.
+# ``Matlab_MAIN_PROGRAM``
+# the Matlab binary program. Available only if the component ``MAIN_PROGRAM``
+# is given in the :command:`find_package` directive.
+# ``Matlab_INCLUDE_DIRS``
+# the path of the Matlab libraries headers
+# ``Matlab_MEX_LIBRARY``
+# library for mex, always available.
+# ``Matlab_MX_LIBRARY``
+# mx library of Matlab (arrays). Available only if the component
+# ``MX_LIBRARY`` has been requested.
+# ``Matlab_ENG_LIBRARY``
+# Matlab engine library. Available only if the component ``ENG_LIBRARY``
+# is requested.
+# ``Matlab_LIBRARIES``
+# the whole set of libraries of Matlab
+# ``Matlab_MEX_COMPILER``
+# the mex compiler of Matlab. Currently not used.
+# Available only if the component ``MEX_COMPILER`` is asked
+#
+# Cached variables
+# """"""""""""""""
+#
+# ``Matlab_MEX_EXTENSION``
+# the extension of the mex files for the current platform (given by Matlab).
+# ``Matlab_ROOT_DIR``
+# the location of the root of the Matlab installation found. If this value
+# is changed by the user, the result variables are recomputed.
+#
+# Provided macros
+# ^^^^^^^^^^^^^^^
+#
+# :command:`matlab_get_version_from_release_name`
+# returns the version from the release name
+# :command:`matlab_get_release_name_from_version`
+# returns the release name from the Matlab version
+#
+# Provided functions
+# ^^^^^^^^^^^^^^^^^^
+#
+# :command:`matlab_add_mex`
+# adds a target compiling a MEX file.
+# :command:`matlab_add_unit_test`
+# adds a Matlab unit test file as a test to the project.
+# :command:`matlab_extract_all_installed_versions_from_registry`
+# parses the registry for all Matlab versions. Available on Windows only.
+# The part of the registry parsed is dependent on the host processor
+# :command:`matlab_get_all_valid_matlab_roots_from_registry`
+# returns all the possible Matlab paths, according to a previously
+# given list. Only the existing/accessible paths are kept. This is mainly
+# useful for the searching all possible Matlab installation.
+# :command:`matlab_get_mex_suffix`
+# returns the suffix to be used for the mex files
+# (platform/architecture dependant)
+# :command:`matlab_get_version_from_matlab_run`
+# returns the version of Matlab, given the full directory of the Matlab
+# program.
+#
+#
+# Known issues
+# ^^^^^^^^^^^^
+#
+# **Symbol clash in a MEX target**
+# By default, every symbols inside a MEX
+# file defined with the command :command:`matlab_add_mex` have hidden
+# visibility, except for the entry point. This is the default behaviour of
+# the MEX compiler, which lowers the risk of symbol collision between the
+# libraries shipped with Matlab, and the libraries to which the MEX file is
+# linking to. This is also the default on Windows platforms.
+#
+# However, this is not sufficient in certain case, where for instance your
+# MEX file is linking against libraries that are already loaded by Matlab,
+# even if those libraries have different SONAMES.
+# A possible solution is to hide the symbols of the libraries to which the
+# MEX target is linking to. This can be achieved in GNU GCC compilers with
+# the linker option ``-Wl,--exclude-libs,ALL``.
+#
+# **Tests using GPU resources**
+# in case your MEX file is using the GPU and
+# in order to be able to run unit tests on this MEX file, the GPU resources
+# should be properly released by Matlab. A possible solution is to make
+# Matlab aware of the use of the GPU resources in the session, which can be
+# performed by a command such as ``D = gpuDevice()`` at the beginning of
+# the test script (or via a fixture).
+#
+#
+# Reference
+# ^^^^^^^^^
+#
+# .. variable:: Matlab_ROOT_DIR
+#
+# The root folder of the Matlab installation. If set before the call to
+# :command:`find_package`, the module will look for the components in that
+# path. If not set, then an automatic search of Matlab
+# will be performed. If set, it should point to a valid version of Matlab.
+#
+# .. variable:: MATLAB_FIND_DEBUG
+#
+# If set, the lookup of Matlab and the intermediate configuration steps are
+# outputted to the console.
+#
+# .. variable:: MATLAB_ADDITIONAL_VERSIONS
+#
+# If set, specifies additional versions of Matlab that may be looked for.
+# The variable should be a list of strings, organised by pairs of release
+# name and versions, such as follows::
+#
+# set(MATLAB_ADDITIONAL_VERSIONS
+# "release_name1=corresponding_version1"
+# "release_name2=corresponding_version2"
+# ...
+# )
+#
+# Example::
+#
+# set(MATLAB_ADDITIONAL_VERSIONS
+# "R2013b=8.2"
+# "R2013a=8.1"
+# "R2012b=8.0")
+#
+# The order of entries in this list matters when several versions of
+# Matlab are installed. The priority is set according to the ordering in
+# this list.
#=============================================================================
-# Copyright 2005-2009 Kitware, Inc.
+# Copyright 2014-2015 Raffi Enficiaud, Max Planck Society
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
@@ -19,102 +216,1250 @@
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
-set(MATLAB_FOUND 0)
-if(WIN32)
- if(${CMAKE_GENERATOR} MATCHES "Visual Studio 6")
- set(MATLAB_ROOT "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MathWorks\\MATLAB\\7.0;MATLABROOT]/extern/lib/win32/microsoft/msvc60")
+set(_FindMatlab_SELF_DIR "${CMAKE_CURRENT_LIST_DIR}")
+
+include(FindPackageHandleStandardArgs)
+include(CheckCXXCompilerFlag)
+
+
+# The currently supported versions. Other version can be added by the user by
+# providing MATLAB_ADDITIONAL_VERSIONS
+if(NOT MATLAB_ADDITIONAL_VERSIONS)
+ set(MATLAB_ADDITIONAL_VERSIONS)
+endif()
+
+set(MATLAB_VERSIONS_MAPPING
+ "R2015b=8.6"
+ "R2015a=8.5"
+ "R2014b=8.4"
+ "R2014a=8.3"
+ "R2013b=8.2"
+ "R2013a=8.1"
+ "R2012b=8.0"
+ "R2012a=7.14"
+
+ "R2011b=7.13"
+ "R2011a=7.12"
+ "R2010b=7.11"
+
+ ${MATLAB_ADDITIONAL_VERSIONS}
+ )
+
+
+# temporary folder for all Matlab runs
+set(_matlab_temporary_folder ${CMAKE_BINARY_DIR}/Matlab)
+
+if(NOT EXISTS "${_matlab_temporary_folder}")
+ file(MAKE_DIRECTORY "${_matlab_temporary_folder}")
+endif()
+
+#.rst:
+# .. command:: matlab_get_version_from_release_name
+#
+# Returns the version of Matlab (17.58) from a release name (R2017k)
+macro (matlab_get_version_from_release_name release_name version_name)
+
+ string(REGEX MATCHALL "${release_name}=([0-9]+\\.?[0-9]*)" _matched ${MATLAB_VERSIONS_MAPPING})
+
+ set(${version_name} "")
+ if(NOT _matched STREQUAL "")
+ set(${version_name} ${CMAKE_MATCH_1})
else()
- if(${CMAKE_GENERATOR} MATCHES "Visual Studio 7")
- # Assume people are generally using 7.1,
- # if using 7.0 need to link to: ../extern/lib/win32/microsoft/msvc70
- set(MATLAB_ROOT "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MathWorks\\MATLAB\\7.0;MATLABROOT]/extern/lib/win32/microsoft/msvc71")
- else()
- if(${CMAKE_GENERATOR} MATCHES "Borland")
- # Same here, there are also: bcc50 and bcc51 directories
- set(MATLAB_ROOT "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MathWorks\\MATLAB\\7.0;MATLABROOT]/extern/lib/win32/microsoft/bcc54")
- else()
- if(MATLAB_FIND_REQUIRED)
- message(FATAL_ERROR "Generator not compatible: ${CMAKE_GENERATOR}")
- endif()
+ message(WARNING "The release name ${release_name} is not registered")
+ endif()
+ unset(_matched)
+
+endmacro()
+
+
+
+
+
+#.rst:
+# .. command:: matlab_get_release_name_from_version
+#
+# Returns the release name (R2017k) from the version of Matlab (17.58)
+macro (matlab_get_release_name_from_version version release_name)
+
+ set(${release_name} "")
+ foreach(_var IN LISTS MATLAB_VERSIONS_MAPPING)
+ string(REGEX MATCHALL "(.+)=${version}" _matched ${_var})
+ if(NOT _matched STREQUAL "")
+ set(${release_name} ${CMAKE_MATCH_1})
+ break()
+ endif()
+ endforeach(_var)
+
+ unset(_var)
+ unset(_matched)
+ if(${release_name} STREQUAL "")
+ message(WARNING "The version ${version} is not registered")
+ endif()
+
+endmacro()
+
+
+
+
+
+# extracts all the supported release names (R2017k...) of Matlab
+# internal use
+macro(matlab_get_supported_releases list_releases)
+ set(${list_releases})
+ foreach(_var IN LISTS MATLAB_VERSIONS_MAPPING)
+ string(REGEX MATCHALL "(.+)=([0-9]+\\.?[0-9]*)" _matched ${_var})
+ if(NOT _matched STREQUAL "")
+ list(APPEND ${list_releases} ${CMAKE_MATCH_1})
+ endif()
+ unset(_matched)
+ unset(CMAKE_MATCH_1)
+ endforeach(_var)
+ unset(_var)
+endmacro()
+
+
+
+# extracts all the supported versions of Matlab
+# internal use
+macro(matlab_get_supported_versions list_versions)
+ set(${list_versions})
+ foreach(_var IN LISTS MATLAB_VERSIONS_MAPPING)
+ string(REGEX MATCHALL "(.+)=([0-9]+\\.?[0-9]*)" _matched ${_var})
+ if(NOT _matched STREQUAL "")
+ list(APPEND ${list_versions} ${CMAKE_MATCH_2})
+ endif()
+ unset(_matched)
+ unset(CMAKE_MATCH_1)
+ endforeach(_var)
+ unset(_var)
+endmacro()
+
+
+#.rst:
+# .. command:: matlab_extract_all_installed_versions_from_registry
+#
+# This function parses the registry and founds the Matlab versions that are
+# installed. The found versions are returned in `matlab_versions`.
+# Set `win64` to `TRUE` if the 64 bit version of Matlab should be looked for
+# The returned list contains all versions under
+# ``HKLM\\SOFTWARE\\Mathworks\\MATLAB`` or an empty list in case an error
+# occurred (or nothing found).
+#
+# .. note::
+#
+# Only the versions are provided. No check is made over the existence of the
+# installation referenced in the registry,
+#
+function(matlab_extract_all_installed_versions_from_registry win64 matlab_versions)
+
+ if(NOT CMAKE_HOST_WIN32)
+ message(FATAL_ERROR "This macro can only be called by a windows host (call to reg.exe")
+ endif()
+
+
+ if(${win64} AND ${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "64")
+ set(APPEND_REG "/reg:64")
+ else()
+ set(APPEND_REG "/reg:32")
+ endif()
+
+ # /reg:64 should be added on 64 bits capable OSs in order to enable the
+ # redirection of 64 bits applications
+ execute_process(
+ COMMAND reg query HKEY_LOCAL_MACHINE\\SOFTWARE\\Mathworks\\MATLAB /f * /k ${APPEND_REG}
+ RESULT_VARIABLE resultMatlab
+ OUTPUT_VARIABLE varMatlab
+ ERROR_VARIABLE errMatlab
+ INPUT_FILE NUL
+ )
+
+
+ set(matlabs_from_registry)
+ if(${resultMatlab} EQUAL 0)
+
+ string(
+ REGEX MATCHALL "MATLAB\\\\([0-9]+(\\.[0-9]+)?)"
+ matlab_versions_regex ${varMatlab})
+
+ foreach(match IN LISTS matlab_versions_regex)
+ string(
+ REGEX MATCH "MATLAB\\\\(([0-9]+)(\\.([0-9]+))?)"
+ current_match ${match})
+
+ set(_matlab_current_version ${CMAKE_MATCH_1})
+ set(current_matlab_version_major ${CMAKE_MATCH_2})
+ set(current_matlab_version_minor ${CMAKE_MATCH_4})
+ if(NOT current_matlab_version_minor)
+ set(current_matlab_version_minor "0")
endif()
+
+ list(APPEND matlabs_from_registry ${_matlab_current_version})
+ unset(_matlab_current_version)
+ endforeach(match)
+
+ endif()
+
+ if(matlabs_from_registry)
+ list(REMOVE_DUPLICATES matlabs_from_registry)
+ list(SORT matlabs_from_registry)
+ list(REVERSE matlabs_from_registry)
+ endif()
+
+ set(${matlab_versions} ${matlabs_from_registry} PARENT_SCOPE)
+
+endfunction()
+
+
+
+# (internal)
+macro(extract_matlab_versions_from_registry_brute_force matlab_versions)
+ # get the supported versions
+ set(matlab_supported_versions)
+ matlab_get_supported_versions(matlab_supported_versions)
+
+
+ # this is a manual population of the versions we want to look for
+ # this can be done as is, but preferably with the call to
+ # matlab_get_supported_versions and variable
+
+ # populating the versions we want to look for
+ # set(matlab_supported_versions)
+
+ # # Matlab 7
+ # set(matlab_major 7)
+ # foreach(current_matlab_minor RANGE 4 20)
+ # list(APPEND matlab_supported_versions "${matlab_major}.${current_matlab_minor}")
+ # endforeach(current_matlab_minor)
+
+ # # Matlab 8
+ # set(matlab_major 8)
+ # foreach(current_matlab_minor RANGE 0 5)
+ # list(APPEND matlab_supported_versions "${matlab_major}.${current_matlab_minor}")
+ # endforeach(current_matlab_minor)
+
+ # # taking into account the possible additional versions provided by the user
+ # if(DEFINED MATLAB_ADDITIONAL_VERSIONS)
+ # list(APPEND matlab_supported_versions MATLAB_ADDITIONAL_VERSIONS)
+ # endif()
+
+
+ # we order from more recent to older
+ if(matlab_supported_versions)
+ list(REMOVE_DUPLICATES matlab_supported_versions)
+ list(SORT matlab_supported_versions)
+ list(REVERSE matlab_supported_versions)
+ endif()
+
+
+ set(${matlab_versions} ${matlab_supported_versions})
+
+
+endmacro()
+
+
+
+
+#.rst:
+# .. command:: matlab_get_all_valid_matlab_roots_from_registry
+#
+# Populates the Matlab root with valid versions of Matlab.
+# The returned matlab_roots is organized in pairs
+# ``(version_number,matlab_root_path)``.
+#
+# ::
+#
+# matlab_get_all_valid_matlab_roots_from_registry(
+# matlab_versions
+# matlab_roots)
+#
+# ``matlab_versions``
+# the versions of each of the Matlab installations
+# ``matlab_roots``
+# the location of each of the Matlab installations
+function(matlab_get_all_valid_matlab_roots_from_registry matlab_versions matlab_roots)
+
+ # The matlab_versions comes either from
+ # extract_matlab_versions_from_registry_brute_force or
+ # matlab_extract_all_installed_versions_from_registry.
+
+
+ set(_matlab_roots_list )
+ foreach(_matlab_current_version ${matlab_versions})
+ get_filename_component(
+ current_MATLAB_ROOT
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MathWorks\\MATLAB\\${_matlab_current_version};MATLABROOT]"
+ ABSOLUTE)
+
+ if(EXISTS ${current_MATLAB_ROOT})
+ list(APPEND _matlab_roots_list ${_matlab_current_version} ${current_MATLAB_ROOT})
+ endif()
+
+ endforeach(_matlab_current_version)
+ unset(_matlab_current_version)
+ set(${matlab_roots} ${_matlab_roots_list} PARENT_SCOPE)
+ unset(_matlab_roots_list)
+endfunction()
+
+#.rst:
+# .. command:: matlab_get_mex_suffix
+#
+# Returns the extension of the mex files (the suffixes).
+# This function should not be called before the appropriate Matlab root has
+# been found.
+#
+# ::
+#
+# matlab_get_mex_suffix(
+# matlab_root
+# mex_suffix)
+#
+# ``matlab_root``
+# the root of the Matlab installation
+# ``mex_suffix``
+# the variable name in which the suffix will be returned.
+function(matlab_get_mex_suffix matlab_root mex_suffix)
+
+ # todo setup the extension properly. Currently I do not know if this is
+ # sufficient for all win32 distributions.
+ # there is also CMAKE_EXECUTABLE_SUFFIX that could be tweaked
+ set(mexext_suffix "")
+ if(WIN32)
+ list(APPEND mexext_suffix ".bat")
+ endif()
+
+ # we first try without suffix, since cmake does not understand a list with
+ # one empty string element
+ find_program(
+ Matlab_MEXEXTENSIONS_PROG
+ NAMES mexext
+ PATHS ${matlab_root}/bin
+ DOC "Matlab MEX extension provider"
+ NO_DEFAULT_PATH
+ )
+
+ foreach(current_mexext_suffix IN LISTS mexext_suffix)
+ if(NOT DEFINED Matlab_MEXEXTENSIONS_PROG OR NOT Matlab_MEXEXTENSIONS_PROG)
+ # this call should populate the cache automatically
+ find_program(
+ Matlab_MEXEXTENSIONS_PROG
+ "mexext${current_mexext_suffix}"
+ PATHS ${matlab_root}/bin
+ DOC "Matlab MEX extension provider"
+ NO_DEFAULT_PATH
+ )
+ endif()
+ endforeach(current_mexext_suffix)
+
+
+ # the program has been found?
+ if((NOT Matlab_MEXEXTENSIONS_PROG) OR (NOT EXISTS ${Matlab_MEXEXTENSIONS_PROG}))
+ if(MATLAB_FIND_DEBUG)
+ message(WARNING "[MATLAB] Cannot found mexext program. Matlab root is ${matlab_root}")
+ endif()
+ unset(Matlab_MEXEXTENSIONS_PROG CACHE)
+ return()
+ endif()
+
+ set(_matlab_mex_extension)
+
+ set(devnull)
+ if(UNIX)
+ set(devnull INPUT_FILE /dev/null)
+ elseif(WIN32)
+ set(devnull INPUT_FILE NUL)
+ endif()
+
+ execute_process(
+ COMMAND ${Matlab_MEXEXTENSIONS_PROG}
+ OUTPUT_VARIABLE _matlab_mex_extension
+ ERROR_VARIABLE _matlab_mex_extension_error
+ ${devnull})
+ string(STRIP ${_matlab_mex_extension} _matlab_mex_extension)
+
+ unset(Matlab_MEXEXTENSIONS_PROG CACHE)
+ set(${mex_suffix} ${_matlab_mex_extension} PARENT_SCOPE)
+endfunction()
+
+
+
+
+#.rst:
+# .. command:: matlab_get_version_from_matlab_run
+#
+# This function runs Matlab program specified on arguments and extracts its
+# version.
+#
+# ::
+#
+# matlab_get_version_from_matlab_run(
+# matlab_binary_path
+# matlab_list_versions)
+#
+# ``matlab_binary_path``
+# the location of the `matlab` binary executable
+# ``matlab_list_versions``
+# the version extracted from Matlab
+function(matlab_get_version_from_matlab_run matlab_binary_program matlab_list_versions)
+
+ set(${matlab_list_versions} "" PARENT_SCOPE)
+
+
+ if(MATLAB_FIND_DEBUG)
+ message(STATUS "[MATLAB] Determining the version of Matlab from ${matlab_binary_program}")
+ endif()
+
+ if(EXISTS "${_matlab_temporary_folder}/matlabVersionLog.cmaketmp")
+ if(MATLAB_FIND_DEBUG)
+ message(STATUS "[MATLAB] Removing previous ${_matlab_temporary_folder}/matlabVersionLog.cmaketmp file")
endif()
+ file(REMOVE "${_matlab_temporary_folder}/matlabVersionLog.cmaketmp")
+ endif()
+
+
+ # the log file is needed since on windows the command executes in a new
+ # window and it is not possible to get back the answer of Matlab
+ # the -wait command is needed on windows, otherwise the call returns
+ # immediately after the program launches itself.
+ if(WIN32)
+ set(_matlab_additional_commands "-wait")
endif()
- find_library(MATLAB_MEX_LIBRARY
- libmex
- ${MATLAB_ROOT}
+
+ set(devnull)
+ if(UNIX)
+ set(devnull INPUT_FILE /dev/null)
+ elseif(WIN32)
+ set(devnull INPUT_FILE NUL)
+ endif()
+
+ # timeout set to 30 seconds, in case it does not start
+ # note as said before OUTPUT_VARIABLE cannot be used in a platform
+ # independent manner however, not setting it would flush the output of Matlab
+ # in the current console (unix variant)
+ execute_process(
+ COMMAND "${matlab_binary_program}" -nosplash -nojvm ${_matlab_additional_commands} -logfile "matlabVersionLog.cmaketmp" -nodesktop -nodisplay -r "version, exit"
+ OUTPUT_VARIABLE _matlab_version_from_cmd_dummy
+ RESULT_VARIABLE _matlab_result_version_call
+ ERROR_VARIABLE _matlab_result_version_call_error
+ TIMEOUT 30
+ WORKING_DIRECTORY "${_matlab_temporary_folder}"
+ ${devnull}
)
- find_library(MATLAB_MX_LIBRARY
- libmx
- ${MATLAB_ROOT}
+
+
+ if(${_matlab_result_version_call})
+ if(MATLAB_FIND_DEBUG)
+ message(WARNING "[MATLAB] Unable to determine the version of Matlab. Matlab call returned with error ${_matlab_result_version_call}.")
+ endif()
+ return()
+ elseif(NOT EXISTS "${_matlab_temporary_folder}/matlabVersionLog.cmaketmp")
+ if(MATLAB_FIND_DEBUG)
+ message(WARNING "[MATLAB] Unable to determine the version of Matlab. The log file does not exist.")
+ endif()
+ return()
+ endif()
+
+ # if successful, read back the log
+ file(READ "${_matlab_temporary_folder}/matlabVersionLog.cmaketmp" _matlab_version_from_cmd)
+ file(REMOVE "${_matlab_temporary_folder}/matlabVersionLog.cmaketmp")
+
+ set(index -1)
+ string(FIND ${_matlab_version_from_cmd} "ans" index)
+ if(index EQUAL -1)
+
+ if(MATLAB_FIND_DEBUG)
+ message(WARNING "[MATLAB] Cannot find the version of Matlab returned by the run.")
+ endif()
+
+ else()
+ set(matlab_list_of_all_versions_tmp)
+
+ string(SUBSTRING ${_matlab_version_from_cmd} ${index} -1 substring_ans)
+ string(
+ REGEX MATCHALL "ans[\r\n\t ]*=[\r\n\t ]*([0-9]+(\\.[0-9]+)?)"
+ matlab_versions_regex
+ ${substring_ans})
+ foreach(match IN LISTS matlab_versions_regex)
+ string(
+ REGEX MATCH "ans[\r\n\t ]*=[\r\n\t ]*(([0-9]+)(\\.([0-9]+))?)"
+ current_match ${match})
+
+ list(APPEND matlab_list_of_all_versions_tmp ${CMAKE_MATCH_1})
+ endforeach()
+ if(matlab_list_of_all_versions_tmp)
+ list(REMOVE_DUPLICATES matlab_list_of_all_versions_tmp)
+ endif()
+ set(${matlab_list_versions} ${matlab_list_of_all_versions_tmp} PARENT_SCOPE)
+
+ endif()
+
+endfunction()
+
+
+#.rst:
+# .. command:: matlab_add_unit_test
+#
+# Adds a Matlab unit test to the test set of cmake/ctest.
+# This command requires the component ``MAIN_PROGRAM``.
+# The unit test uses the Matlab unittest framework (default, available
+# starting Matlab 2013b+) except if the option ``NO_UNITTEST_FRAMEWORK``
+# is given.
+#
+# The function expects one Matlab test script file to be given.
+# In the case ``NO_UNITTEST_FRAMEWORK`` is given, the unittest script file
+# should contain the script to be run, plus an exit command with the exit
+# value. This exit value will be passed to the ctest framework (0 success,
+# non 0 failure). Additional arguments accepted by :command:`add_test` can be
+# passed through ``TEST_ARGS`` (eg. ``CONFIGURATION <config> ...``).
+#
+# ::
+#
+# matlab_add_unit_test(
+# NAME <name>
+# UNITTEST_FILE matlab_file_containing_unittest.m
+# [UNITTEST_PRECOMMAND matlab_command_to_run]
+# [TIMEOUT timeout]
+# [ADDITIONAL_PATH path1 [path2 ...]]
+# [MATLAB_ADDITIONAL_STARTUP_OPTIONS option1 [option2 ...]]
+# [TEST_ARGS arg1 [arg2 ...]]
+# [NO_UNITTEST_FRAMEWORK]
+# )
+#
+# The function arguments are:
+#
+# ``NAME``
+# name of the unittest in ctest.
+# ``UNITTEST_FILE``
+# the matlab unittest file. Its path will be automatically
+# added to the Matlab path.
+# ``UNITTEST_PRECOMMAND``
+# Matlab script command to be ran before the file
+# containing the test (eg. GPU device initialisation based on CMake
+# variables).
+# ``TIMEOUT``
+# the test timeout in seconds. Defaults to 180 seconds as the
+# Matlab unit test may hang.
+# ``ADDITIONAL_PATH``
+# a list of paths to add to the Matlab path prior to
+# running the unit test.
+# ``MATLAB_ADDITIONAL_STARTUP_OPTIONS``
+# a list of additional option in order
+# to run Matlab from the command line.
+# ``TEST_ARGS``
+# Additional options provided to the add_test command. These
+# options are added to the default options (eg. "CONFIGURATIONS Release")
+# ``NO_UNITTEST_FRAMEWORK``
+# when set, indicates that the test should not
+# use the unittest framework of Matlab (available for versions >= R2013a).
+#
+function(matlab_add_unit_test)
+
+ if(NOT Matlab_MAIN_PROGRAM)
+ message(FATAL_ERROR "[MATLAB] This functionality needs the MAIN_PROGRAM component (not default)")
+ endif()
+
+ set(options NO_UNITTEST_FRAMEWORK)
+ set(oneValueArgs NAME UNITTEST_PRECOMMAND UNITTEST_FILE TIMEOUT)
+ set(multiValueArgs ADDITIONAL_PATH MATLAB_ADDITIONAL_STARTUP_OPTIONS TEST_ARGS)
+
+ set(prefix _matlab_unittest_prefix)
+ cmake_parse_arguments(${prefix} "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
+
+ if(NOT ${prefix}_NAME)
+ message(FATAL_ERROR "[MATLAB] The Matlab test name cannot be empty")
+ endif()
+
+ add_test(NAME ${${prefix}_NAME}
+ COMMAND ${CMAKE_COMMAND}
+ -Dtest_name=${${prefix}_NAME}
+ -Dadditional_paths=${${prefix}_ADDITIONAL_PATH}
+ -Dtest_timeout=${${prefix}_TIMEOUT}
+ -Doutput_directory=${_matlab_temporary_folder}
+ -DMatlab_PROGRAM=${Matlab_MAIN_PROGRAM}
+ -Dno_unittest_framework=${${prefix}_NO_UNITTEST_FRAMEWORK}
+ -DMatlab_ADDITIONNAL_STARTUP_OPTIONS=${${prefix}_MATLAB_ADDITIONAL_STARTUP_OPTIONS}
+ -Dunittest_file_to_run=${${prefix}_UNITTEST_FILE}
+ -Dcmd_to_run_before_test=${${prefix}_UNITTEST_PRECOMMAND}
+ -P ${_FindMatlab_SELF_DIR}/MatlabTestsRedirect.cmake
+ ${${prefix}_TEST_ARGS}
+ ${${prefix}_UNPARSED_ARGUMENTS}
+ )
+endfunction()
+
+
+#.rst:
+# .. command:: matlab_add_mex
+#
+# Adds a Matlab MEX target.
+# This commands compiles the given sources with the current tool-chain in
+# order to produce a MEX file. The final name of the produced output may be
+# specified, as well as additional link libraries, and a documentation entry
+# for the MEX file. Remaining arguments of the call are passed to the
+# :command:`add_library` command.
+#
+# ::
+#
+# matlab_add_mex(
+# NAME <name>
+# SRC src1 [src2 ...]
+# [OUTPUT_NAME output_name]
+# [DOCUMENTATION file.txt]
+# [LINK_TO target1 target2 ...]
+# [...]
+# )
+#
+# ``NAME``
+# name of the target.
+# ``SRC``
+# list of tje source files.
+# ``LINK_TO``
+# a list of additional link dependencies. The target links to ``libmex``
+# by default. If ``Matlab_MX_LIBRARY`` is defined, it also
+# links to ``libmx``.
+# ``OUTPUT_NAME``
+# if given, overrides the default name. The default name is
+# the name of the target without any prefix and
+# with ``Matlab_MEX_EXTENSION`` suffix.
+# ``DOCUMENTATION``
+# if given, the file ``file.txt`` will be considered as
+# being the documentation file for the MEX file. This file is copied into
+# the same folder without any processing, with the same name as the final
+# mex file, and with extension `.m`. In that case, typing ``help <name>``
+# in Matlab prints the documentation contained in this file.
+#
+# The documentation file is not processed and should be in the following
+# format:
+#
+# ::
+#
+# % This is the documentation
+# function ret = mex_target_output_name(input1)
+#
+function(matlab_add_mex )
+
+ if(NOT WIN32)
+ # we do not need all this on Windows
+ # pthread options
+ check_cxx_compiler_flag(-pthread HAS_MINUS_PTHREAD)
+ # we should use try_compile instead, the link flags are discarded from
+ # this compiler_flag function.
+ #check_cxx_compiler_flag(-Wl,--exclude-libs,ALL HAS_SYMBOL_HIDING_CAPABILITY)
+
+ endif()
+
+ set(oneValueArgs NAME DOCUMENTATION OUTPUT_NAME)
+ set(multiValueArgs LINK_TO SRC)
+
+ set(prefix _matlab_addmex_prefix)
+ cmake_parse_arguments(${prefix} "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
+
+ if(NOT ${prefix}_NAME)
+ message(FATAL_ERROR "[MATLAB] The MEX target name cannot be empty")
+ endif()
+
+ if(NOT ${prefix}_OUTPUT_NAME)
+ set(${prefix}_OUTPUT_NAME ${${prefix}_NAME})
+ endif()
+
+ add_library(${${prefix}_NAME}
+ SHARED
+ ${${prefix}_SRC}
+ ${${prefix}_DOCUMENTATION}
+ ${${prefix}_UNPARSED_ARGUMENTS})
+ target_include_directories(${${prefix}_NAME} PRIVATE ${Matlab_INCLUDE_DIRS})
+
+ if(DEFINED Matlab_MX_LIBRARY)
+ target_link_libraries(${${prefix}_NAME} ${Matlab_MX_LIBRARY})
+ endif()
+
+ target_link_libraries(${${prefix}_NAME} ${Matlab_MEX_LIBRARY} ${${prefix}_LINK_TO})
+ set_target_properties(${${prefix}_NAME}
+ PROPERTIES
+ PREFIX ""
+ OUTPUT_NAME ${${prefix}_OUTPUT_NAME}
+ SUFFIX ".${Matlab_MEX_EXTENSION}")
+
+
+ # documentation
+ if(NOT ${${prefix}_DOCUMENTATION} STREQUAL "")
+ get_target_property(output_name ${${prefix}_NAME} OUTPUT_NAME)
+ add_custom_command(
+ TARGET ${${prefix}_NAME}
+ PRE_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different ${${prefix}_DOCUMENTATION} $<TARGET_FILE_DIR:${${prefix}_NAME}>/${output_name}.m
+ COMMENT "Copy ${${prefix}_NAME} documentation file into the output folder"
)
- find_library(MATLAB_ENG_LIBRARY
- libeng
- ${MATLAB_ROOT}
+ endif() # documentation
+
+ # entry point in the mex file + taking care of visibility and symbol clashes.
+ if(WIN32)
+ set_target_properties(${${prefix}_NAME}
+ PROPERTIES
+ DEFINE_SYMBOL "DLL_EXPORT_SYM=__declspec(dllexport)")
+ else()
+
+ if(HAS_MINUS_PTHREAD AND NOT APPLE)
+ # Apparently, compiling with -pthread generated the proper link flags
+ # and some defines at compilation
+ target_compile_options(${${prefix}_NAME} PRIVATE "-pthread")
+ endif()
+
+
+ # if we do not do that, the symbols linked from eg. boost remain weak and
+ # then clash with the ones defined in the matlab process. So by default
+ # the symbols are hidden.
+ # This also means that for shared libraries (like MEX), the entry point
+ # should be explicitly declared with default visibility, otherwise Matlab
+ # cannot find the entry point.
+ # Note that this is particularly meaningful if the MEX wrapper itself
+ # contains symbols that are clashing with Matlab (that are compiled in the
+ # MEX file). In order to propagate the visibility options to the libraries
+ # to which the MEX file is linked against, the -Wl,--exclude-libs,ALL
+ # option should also be specified.
+
+ set_target_properties(${${prefix}_NAME}
+ PROPERTIES
+ CXX_VISIBILITY_PRESET "hidden"
+ C_VISIBILITY_PRESET "hidden"
+ VISIBILITY_INLINES_HIDDEN ON
)
- find_path(MATLAB_INCLUDE_DIR
- "mex.h"
- "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MathWorks\\MATLAB\\7.0;MATLABROOT]/extern/include"
+ # get_target_property(
+ # _previous_link_flags
+ # ${${prefix}_NAME}
+ # LINK_FLAGS)
+ # if(NOT _previous_link_flags)
+ # set(_previous_link_flags)
+ # endif()
+
+ # if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+ # set_target_properties(${${prefix}_NAME}
+ # PROPERTIES
+ # LINK_FLAGS "${_previous_link_flags} -Wl,--exclude-libs,ALL"
+ # # -Wl,--version-script=${_FindMatlab_SELF_DIR}/MatlabLinuxVisibility.map"
+ # )
+ # elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+ # # in this case, all other symbols become hidden.
+ # set_target_properties(${${prefix}_NAME}
+ # PROPERTIES
+ # LINK_FLAGS "${_previous_link_flags} -Wl,-exported_symbol,_mexFunction"
+ # #-Wl,-exported_symbols_list,${_FindMatlab_SELF_DIR}/MatlabOSXVisilibity.map"
+ # )
+ # endif()
+
+
+
+ set_target_properties(${${prefix}_NAME}
+ PROPERTIES
+ DEFINE_SYMBOL "DLL_EXPORT_SYM=__attribute__ ((visibility (\"default\")))"
)
-else()
- if(CMAKE_SIZEOF_VOID_P EQUAL 4)
- # Regular x86
- set(MATLAB_ROOT
- /usr/local/matlab-7sp1/bin/glnx86/
- /opt/matlab-7sp1/bin/glnx86/
- $ENV{HOME}/matlab-7sp1/bin/glnx86/
- $ENV{HOME}/redhat-matlab/bin/glnx86/
+
+
+ endif()
+
+endfunction()
+
+
+# (internal)
+# Used to get the version of matlab, using caching. This basically transforms the
+# output of the root list, with possible unknown version, to a version
+#
+function(_Matlab_get_version_from_root matlab_root matlab_known_version matlab_final_version)
+
+ # if the version is not trivial, we query matlab for that
+ # we keep track of the location of matlab that induced this version
+ #if(NOT DEFINED Matlab_PROG_VERSION_STRING_AUTO_DETECT)
+ # set(Matlab_PROG_VERSION_STRING_AUTO_DETECT "" CACHE INTERNAL "internal matlab location for the discovered version")
+ #endif()
+
+ if(NOT ${matlab_known_version} STREQUAL "NOTFOUND")
+ # the version is known, we just return it
+ set(${matlab_final_version} ${matlab_known_version} PARENT_SCOPE)
+ set(Matlab_VERSION_STRING_INTERNAL ${matlab_known_version} CACHE INTERNAL "Matlab version (automatically determined)" FORCE)
+ return()
+ endif()
+
+ #
+ set(_matlab_current_program ${Matlab_MAIN_PROGRAM})
+
+ # do we already have a matlab program?
+ if(NOT _matlab_current_program)
+
+ set(_find_matlab_options)
+ if(matlab_root AND EXISTS ${matlab_root})
+ set(_find_matlab_options PATHS ${matlab_root} ${matlab_root}/bin NO_DEFAULT_PATH)
+ endif()
+
+ find_program(
+ _matlab_current_program
+ matlab
+ ${_find_matlab_options}
+ DOC "Matlab main program"
)
+ endif()
+
+ if(NOT _matlab_current_program OR NOT EXISTS ${_matlab_current_program})
+ # if not found, clear the dependent variables
+ if(MATLAB_FIND_DEBUG)
+ message(WARNING "[MATLAB] Cannot find the main matlab program under ${matlab_root}")
+ endif()
+ set(Matlab_PROG_VERSION_STRING_AUTO_DETECT "" CACHE INTERNAL "internal matlab location for the discovered version" FORCE)
+ set(Matlab_VERSION_STRING_INTERNAL "" CACHE INTERNAL "internal matlab location for the discovered version" FORCE)
+ unset(_matlab_current_program)
+ unset(_matlab_current_program CACHE)
+ return()
+ endif()
+
+ # full real path for path comparison
+ get_filename_component(_matlab_main_real_path_tmp "${_matlab_current_program}" REALPATH)
+ unset(_matlab_current_program)
+ unset(_matlab_current_program CACHE)
+
+ # is it the same as the previous one?
+ if(_matlab_main_real_path_tmp STREQUAL Matlab_PROG_VERSION_STRING_AUTO_DETECT)
+ set(${matlab_final_version} ${Matlab_VERSION_STRING_INTERNAL} PARENT_SCOPE)
+ return()
+ endif()
+
+ # update the location of the program
+ set(Matlab_PROG_VERSION_STRING_AUTO_DETECT ${_matlab_main_real_path_tmp} CACHE INTERNAL "internal matlab location for the discovered version" FORCE)
+
+ set(matlab_list_of_all_versions)
+ matlab_get_version_from_matlab_run("${Matlab_PROG_VERSION_STRING_AUTO_DETECT}" matlab_list_of_all_versions)
+
+ list(GET matlab_list_of_all_versions 0 _matlab_version_tmp)
+
+ # set the version into the cache
+ set(Matlab_VERSION_STRING_INTERNAL ${_matlab_version_tmp} CACHE INTERNAL "Matlab version (automatically determined)" FORCE)
+
+ # warning, just in case several versions found (should not happen)
+ list(LENGTH matlab_list_of_all_versions list_of_all_versions_length)
+ if((${list_of_all_versions_length} GREATER 1) AND MATLAB_FIND_DEBUG)
+ message(WARNING "[MATLAB] Found several versions, taking the first one (versions found ${matlab_list_of_all_versions})")
+ endif()
+
+ # return the updated value
+ set(${matlab_final_version} ${Matlab_VERSION_STRING_INTERNAL} PARENT_SCOPE)
+
+endfunction()
+
+
+
+
+
+
+
+# ###################################
+# Exploring the possible Matlab_ROOTS
+
+# this variable will get all Matlab installations found in the current system.
+set(_matlab_possible_roots)
+
+
+
+if(Matlab_ROOT_DIR)
+ # if the user specifies a possible root, we keep this one
+
+ if(NOT EXISTS ${Matlab_ROOT_DIR})
+ # if Matlab_ROOT_DIR specified but erroneous
+ if(MATLAB_FIND_DEBUG)
+ message(WARNING "[MATLAB] the specified path for Matlab_ROOT_DIR does not exist (${Matlab_ROOT_DIR})")
+ endif()
else()
- # AMD64:
- set(MATLAB_ROOT
- /usr/local/matlab-7sp1/bin/glnxa64/
- /opt/matlab-7sp1/bin/glnxa64/
- $ENV{HOME}/matlab7_64/bin/glnxa64/
- $ENV{HOME}/matlab-7sp1/bin/glnxa64/
- $ENV{HOME}/redhat-matlab/bin/glnxa64/
- )
+ # NOTFOUND indicates the code below to search for the version automatically
+ if("${Matlab_VERSION_STRING_INTERNAL}" STREQUAL "")
+ list(APPEND _matlab_possible_roots "NOTFOUND" ${Matlab_ROOT_DIR}) # empty version
+ else()
+ list(APPEND _matlab_possible_roots ${Matlab_VERSION_STRING_INTERNAL} ${Matlab_ROOT_DIR}) # cached version
+ endif()
+ endif()
+
+
+else()
+
+ # if the user does not specify the possible installation root, we look for
+ # one installation using the appropriate heuristics
+
+ if(WIN32)
+
+ # On WIN32, we look for Matlab installation in the registry
+ # if unsuccessful, we look for all known revision and filter the existing
+ # ones.
+
+ # testing if we are able to extract the needed information from the registry
+ set(_matlab_versions_from_registry)
+ matlab_extract_all_installed_versions_from_registry(CMAKE_CL_64 _matlab_versions_from_registry)
+
+ # the returned list is empty, doing the search on all known versions
+ if(NOT _matlab_versions_from_registry)
+
+ if(MATLAB_FIND_DEBUG)
+ message(STATUS "[MATLAB] Search for Matlab from the registry unsuccessful, testing all supported versions")
+ endif()
+
+ extract_matlab_versions_from_registry_brute_force(_matlab_versions_from_registry)
+ endif()
+
+ # filtering the results with the registry keys
+ matlab_get_all_valid_matlab_roots_from_registry("${_matlab_versions_from_registry}" _matlab_possible_roots)
+ unset(_matlab_versions_from_registry)
+
+ elseif(APPLE)
+
+ # on mac, we look for the /Application paths
+ # this corresponds to the behaviour on Windows. On Linux, we do not have
+ # any other guess.
+ matlab_get_supported_releases(_matlab_releases)
+ if(MATLAB_FIND_DEBUG)
+ message(STATUS "[MATLAB] Matlab supported versions ${_matlab_releases}. If more version should be supported "
+ "the variable MATLAB_ADDITIONAL_VERSIONS can be set according to the documentation")
+ endif()
+
+ foreach(_matlab_current_release IN LISTS _matlab_releases)
+ set(_matlab_full_string "/Applications/MATLAB_${_matlab_current_release}.app")
+ if(EXISTS ${_matlab_full_string})
+ set(_matlab_current_version)
+ matlab_get_version_from_release_name("${_matlab_current_release}" _matlab_current_version)
+ if(MATLAB_FIND_DEBUG)
+ message(STATUS "[MATLAB] Found version ${_matlab_current_release} (${_matlab_current_version}) in ${_matlab_full_string}")
+ endif()
+ list(APPEND _matlab_possible_roots ${_matlab_current_version} ${_matlab_full_string})
+ unset(_matlab_current_version)
+ endif()
+
+ unset(_matlab_full_string)
+ endforeach(_matlab_current_release)
+
+ unset(_matlab_current_release)
+ unset(_matlab_releases)
+
endif()
- find_library(MATLAB_MEX_LIBRARY
- mex
- ${MATLAB_ROOT}
- )
- find_library(MATLAB_MX_LIBRARY
- mx
- ${MATLAB_ROOT}
- )
- find_library(MATLAB_ENG_LIBRARY
- eng
- ${MATLAB_ROOT}
- )
- find_path(MATLAB_INCLUDE_DIR
- "mex.h"
- "/usr/local/matlab-7sp1/extern/include/"
- "/opt/matlab-7sp1/extern/include/"
- "$ENV{HOME}/matlab-7sp1/extern/include/"
- "$ENV{HOME}/redhat-matlab/extern/include/"
- )
endif()
-# This is common to UNIX and Win32:
-set(MATLAB_LIBRARIES
- ${MATLAB_MEX_LIBRARY}
- ${MATLAB_MX_LIBRARY}
- ${MATLAB_ENG_LIBRARY}
+
+
+list(LENGTH _matlab_possible_roots _numbers_of_matlab_roots)
+if(_numbers_of_matlab_roots EQUAL 0)
+ # if we have not found anything, we fall back on the PATH
+
+
+ # At this point, we have no other choice than trying to find it from PATH.
+ # If set by the user, this wont change
+ find_program(
+ _matlab_main_tmp
+ NAMES matlab)
+
+
+ if(_matlab_main_tmp)
+ # we then populate the list of roots, with empty version
+ if(MATLAB_FIND_DEBUG)
+ message(STATUS "[MATLAB] matlab found from PATH: ${_matlab_main_tmp}")
+ endif()
+
+ # resolve symlinks
+ get_filename_component(_matlab_current_location "${_matlab_main_tmp}" REALPATH)
+
+ # get the directory (the command below has to be run twice)
+ # this will be the matlab root
+ get_filename_component(_matlab_current_location "${_matlab_current_location}" DIRECTORY)
+ get_filename_component(_matlab_current_location "${_matlab_current_location}" DIRECTORY) # Matlab should be in bin
+
+ list(APPEND _matlab_possible_roots "NOTFOUND" ${_matlab_current_location})
+
+ unset(_matlab_current_location)
+
+ endif()
+ unset(_matlab_main_tmp CACHE)
+
+endif()
+
+
+
+
+
+if(MATLAB_FIND_DEBUG)
+ message(STATUS "[MATLAB] Matlab root folders are ${_matlab_possible_roots}")
+endif()
+
+
+
+
+
+# take the first possible Matlab root
+list(LENGTH _matlab_possible_roots _numbers_of_matlab_roots)
+set(Matlab_VERSION_STRING "NOTFOUND")
+if(_numbers_of_matlab_roots GREATER 0)
+ list(GET _matlab_possible_roots 0 Matlab_VERSION_STRING)
+ list(GET _matlab_possible_roots 1 Matlab_ROOT_DIR)
+
+ # adding a warning in case of ambiguity
+ if(_numbers_of_matlab_roots GREATER 2 AND MATLAB_FIND_DEBUG)
+ message(WARNING "[MATLAB] Found several distributions of Matlab. Setting the current version to ${Matlab_VERSION_STRING} (located ${Matlab_ROOT_DIR})."
+ " If this is not the desired behaviour, provide the -DMatlab_ROOT_DIR=... on the command line")
+ endif()
+endif()
+
+
+# check if the root changed against the previous defined one, if so
+# clear all the cached variables
+if(DEFINED Matlab_ROOT_DIR_LAST_CACHED)
+
+ if(NOT Matlab_ROOT_DIR_LAST_CACHED STREQUAL Matlab_ROOT_DIR)
+ set(_Matlab_cached_vars
+ Matlab_INCLUDE_DIRS
+ Matlab_MEX_LIBRARY
+ Matlab_MEX_COMPILER
+ Matlab_MAIN_PROGRAM
+ Matlab_MX_LIBRARY
+ Matlab_ENG_LIBRARY
+ Matlab_MEX_EXTENSION
+
+ # internal
+ Matlab_MEXEXTENSIONS_PROG
+ Matlab_ROOT_DIR_LAST_CACHED
+ #Matlab_PROG_VERSION_STRING_AUTO_DETECT
+ Matlab_VERSION_STRING_INTERNAL
+ )
+ foreach(_var IN LISTS _Matlab_cached_vars)
+ if(DEFINED ${_var})
+ unset(${_var} CACHE)
+ endif()
+ endforeach()
+ endif()
+endif()
+
+set(Matlab_ROOT_DIR_LAST_CACHED ${Matlab_ROOT_DIR} CACHE INTERNAL "last Matlab root dir location")
+set(Matlab_ROOT_DIR ${Matlab_ROOT_DIR} CACHE PATH "Matlab installation root path" FORCE)
+
+# Fix the version, in case this one is NOTFOUND
+_Matlab_get_version_from_root(
+ "${Matlab_ROOT_DIR}"
+ ${Matlab_VERSION_STRING}
+ Matlab_VERSION_STRING
)
-if(MATLAB_INCLUDE_DIR AND MATLAB_LIBRARIES)
- set(MATLAB_FOUND 1)
+
+
+
+if(MATLAB_FIND_DEBUG)
+ message(STATUS "[MATLAB] Current version is ${Matlab_VERSION_STRING} located ${Matlab_ROOT_DIR}")
+endif()
+
+
+
+if(Matlab_ROOT_DIR)
+ file(TO_CMAKE_PATH ${Matlab_ROOT_DIR} Matlab_ROOT_DIR)
+endif()
+
+if(CMAKE_SIZEOF_VOID_P EQUAL 4)
+ set(_matlab_64Build FALSE)
+else()
+ set(_matlab_64Build TRUE)
+endif()
+
+if(APPLE)
+ set(_matlab_bin_prefix "mac") # i should be for intel
+ set(_matlab_bin_suffix_32bits "i")
+ set(_matlab_bin_suffix_64bits "i64")
+elseif(UNIX)
+ set(_matlab_bin_prefix "gln")
+ set(_matlab_bin_suffix_32bits "x86")
+ set(_matlab_bin_suffix_64bits "xa64")
+else()
+ set(_matlab_bin_prefix "win")
+ set(_matlab_bin_suffix_32bits "32")
+ set(_matlab_bin_suffix_64bits "64")
+endif()
+
+
+
+set(MATLAB_INCLUDE_DIR_TO_LOOK ${Matlab_ROOT_DIR}/extern/include)
+if(_matlab_64Build)
+ set(_matlab_current_suffix ${_matlab_bin_suffix_64bits})
+else()
+ set(_matlab_current_suffix ${_matlab_bin_suffix_32bits})
+endif()
+
+set(Matlab_BINARIES_DIR
+ ${Matlab_ROOT_DIR}/bin/${_matlab_bin_prefix}${_matlab_current_suffix})
+set(Matlab_EXTERN_LIBRARY_DIR
+ ${Matlab_ROOT_DIR}/extern/lib/${_matlab_bin_prefix}${_matlab_current_suffix})
+
+if(WIN32)
+ set(_matlab_lib_dir_for_search ${Matlab_EXTERN_LIBRARY_DIR}/microsoft)
+ set(_matlab_lib_prefix_for_search "lib")
+else()
+ set(_matlab_lib_dir_for_search ${Matlab_BINARIES_DIR})
+ set(_matlab_lib_prefix_for_search "lib")
+endif()
+
+unset(_matlab_64Build)
+
+
+if(NOT DEFINED Matlab_MEX_EXTENSION)
+ set(_matlab_mex_extension "")
+ matlab_get_mex_suffix("${Matlab_ROOT_DIR}" _matlab_mex_extension)
+
+ # This variable goes to the cache.
+ set(Matlab_MEX_EXTENSION ${_matlab_mex_extension} CACHE STRING "Extensions for the mex targets (automatically given by Matlab)")
+ unset(_matlab_mex_extension)
+endif()
+
+
+if(MATLAB_FIND_DEBUG)
+ message(STATUS "[MATLAB] [DEBUG]_matlab_lib_prefix_for_search = ${_matlab_lib_prefix_for_search} | _matlab_lib_dir_for_search = ${_matlab_lib_dir_for_search}")
endif()
-mark_as_advanced(
- MATLAB_LIBRARIES
- MATLAB_MEX_LIBRARY
- MATLAB_MX_LIBRARY
- MATLAB_ENG_LIBRARY
- MATLAB_INCLUDE_DIR
- MATLAB_FOUND
- MATLAB_ROOT
+
+
+# internal
+# This small stub around find_library is to prevent any pollution of CMAKE_FIND_LIBRARY_PREFIXES in the global scope.
+# This is the function to be used below instead of the find_library directives.
+function(_Matlab_find_library _matlab_library_prefix)
+ set(CMAKE_FIND_LIBRARY_PREFIXES ${CMAKE_FIND_LIBRARY_PREFIXES} ${_matlab_library_prefix})
+ find_library(${ARGN})
+endfunction()
+
+
+set(_matlab_required_variables)
+
+
+# the MEX library/header are required
+find_path(
+ Matlab_INCLUDE_DIRS
+ mex.h
+ PATHS ${MATLAB_INCLUDE_DIR_TO_LOOK}
+ NO_DEFAULT_PATH
+ )
+list(APPEND _matlab_required_variables Matlab_INCLUDE_DIRS)
+
+_Matlab_find_library(
+ ${_matlab_lib_prefix_for_search}
+ Matlab_MEX_LIBRARY
+ mex
+ PATHS ${_matlab_lib_dir_for_search}
+ NO_DEFAULT_PATH
)
+
+list(APPEND _matlab_required_variables Matlab_MEX_LIBRARY)
+
+# the MEX extension is required
+list(APPEND _matlab_required_variables Matlab_MEX_EXTENSION)
+
+# the matlab root is required
+list(APPEND _matlab_required_variables Matlab_ROOT_DIR)
+
+
+# component Mex Compiler
+list(FIND Matlab_FIND_COMPONENTS MEX_COMPILER _matlab_find_mex_compiler)
+if(_matlab_find_mex_compiler GREATER -1)
+ find_program(
+ Matlab_MEX_COMPILER
+ "mex"
+ PATHS ${Matlab_BINARIES_DIR}
+ DOC "Matlab MEX compiler"
+ NO_DEFAULT_PATH
+ )
+
+ if(Matlab_MEX_COMPILER)
+ set(Matlab_MEX_COMPILER_FOUND TRUE)
+ endif()
+endif()
+unset(_matlab_find_mex_compiler)
+
+# component Matlab program
+list(FIND Matlab_FIND_COMPONENTS MAIN_PROGRAM _matlab_find_matlab_program)
+if(_matlab_find_matlab_program GREATER -1)
+
+ find_program(
+ Matlab_MAIN_PROGRAM
+ matlab
+ PATHS ${Matlab_ROOT_DIR} ${Matlab_ROOT_DIR}/bin
+ DOC "Matlab main program"
+ NO_DEFAULT_PATH
+ )
+
+ if(Matlab_MAIN_PROGRAM)
+ set(Matlab_MAIN_PROGRAM_FOUND TRUE)
+ endif()
+
+endif()
+unset(_matlab_find_matlab_program)
+
+# Component MX library
+list(FIND Matlab_FIND_COMPONENTS MX_LIBRARY _matlab_find_mx)
+if(_matlab_find_mx GREATER -1)
+ _Matlab_find_library(
+ ${_matlab_lib_prefix_for_search}
+ Matlab_MX_LIBRARY
+ mx
+ PATHS ${_matlab_lib_dir_for_search}
+ NO_DEFAULT_PATH
+ )
+
+ if(Matlab_MX_LIBRARY)
+ set(Matlab_MX_LIBRARY_FOUND TRUE)
+ endif()
+endif()
+unset(_matlab_find_mx)
+
+
+# Component ENG library
+list(FIND Matlab_FIND_COMPONENTS ENG_LIBRARY _matlab_find_eng)
+if(_matlab_find_eng GREATER -1)
+ _Matlab_find_library(
+ ${_matlab_lib_prefix_for_search}
+ Matlab_ENG_LIBRARY
+ eng
+ PATHS ${_matlab_lib_dir_for_search}
+ NO_DEFAULT_PATH
+ )
+ if(Matlab_ENG_LIBRARY)
+ set(Matlab_ENG_LIBRARY_FOUND TRUE)
+ endif()
+endif()
+unset(_matlab_find_eng)
+
+
+
+
+
+unset(_matlab_lib_dir_for_search)
+
+
+set(Matlab_LIBRARIES ${Matlab_MEX_LIBRARY} ${Matlab_MX_LIBRARY} ${Matlab_ENG_LIBRARY})
+
+
+find_package_handle_standard_args(
+ Matlab
+ FOUND_VAR Matlab_FOUND
+ REQUIRED_VARS ${_matlab_required_variables}
+ VERSION_VAR Matlab_VERSION_STRING
+ HANDLE_COMPONENTS)
+
+unset(_matlab_required_variables)
+unset(_matlab_bin_prefix)
+unset(_matlab_bin_suffix_32bits)
+unset(_matlab_bin_suffix_64bits)
+unset(_matlab_current_suffix)
+unset(_matlab_lib_dir_for_search)
+unset(_matlab_lib_prefix_for_search)
+
+if(Matlab_INCLUDE_DIRS AND Matlab_LIBRARIES)
+ mark_as_advanced(
+ #Matlab_LIBRARIES
+ Matlab_MEX_LIBRARY
+ Matlab_MX_LIBRARY
+ Matlab_ENG_LIBRARY
+ Matlab_INCLUDE_DIRS
+ Matlab_FOUND
+ #Matlab_ROOT_DIR
+ #Matlab_VERSION_STRING
+ Matlab_MAIN_PROGRAM
+ #Matlab_MEX_EXTENSION
+ Matlab_MEXEXTENSIONS_PROG
+ Matlab_MEX_EXTENSION
+ #Matlab_BINARIES_DIR
+ )
+endif()
diff --git a/Modules/FindMotif.cmake b/Modules/FindMotif.cmake
index 5065e3a2d..a08ece444 100644
--- a/Modules/FindMotif.cmake
+++ b/Modules/FindMotif.cmake
@@ -1,8 +1,16 @@
-# - Try to find Motif (or lesstif)
+#.rst:
+# FindMotif
+# ---------
+#
+# Try to find Motif (or lesstif)
+#
# Once done this will define:
-# MOTIF_FOUND - system has MOTIF
-# MOTIF_INCLUDE_DIR - include paths to use Motif
-# MOTIF_LIBRARIES - Link these to use Motif
+#
+# ::
+#
+# MOTIF_FOUND - system has MOTIF
+# MOTIF_INCLUDE_DIR - include paths to use Motif
+# MOTIF_LIBRARIES - Link these to use Motif
#=============================================================================
# Copyright 2005-2009 Kitware, Inc.
diff --git a/Modules/FindOpenAL.cmake b/Modules/FindOpenAL.cmake
index 78fd632a5..eb63cef5a 100644
--- a/Modules/FindOpenAL.cmake
+++ b/Modules/FindOpenAL.cmake
@@ -1,14 +1,18 @@
-# Locate OpenAL
-# This module defines
-# OPENAL_LIBRARY
-# OPENAL_FOUND, if false, do not try to link to OpenAL
-# OPENAL_INCLUDE_DIR, where to find the headers
+#.rst:
+# FindOpenAL
+# ----------
#
-# $OPENALDIR is an environment variable that would
-# correspond to the ./configure --prefix=$OPENALDIR
-# used in building OpenAL.
#
-# Created by Eric Wing. This was influenced by the FindSDL.cmake module.
+#
+# Locate OpenAL This module defines OPENAL_LIBRARY OPENAL_FOUND, if
+# false, do not try to link to OpenAL OPENAL_INCLUDE_DIR, where to find
+# the headers
+#
+# $OPENALDIR is an environment variable that would correspond to the
+# ./configure --prefix=$OPENALDIR used in building OpenAL.
+#
+# Created by Eric Wing. This was influenced by the FindSDL.cmake
+# module.
#=============================================================================
# Copyright 2005-2009 Kitware, Inc.
@@ -75,11 +79,17 @@ find_path(OPENAL_INCLUDE_DIR al.h
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Creative\ Labs\\OpenAL\ 1.1\ Software\ Development\ Kit\\1.00.0000;InstallDir]
)
+if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(_OpenAL_ARCH_DIR libs/Win64)
+else()
+ set(_OpenAL_ARCH_DIR libs/Win32)
+endif()
+
find_library(OPENAL_LIBRARY
NAMES OpenAL al openal OpenAL32
HINTS
ENV OPENALDIR
- PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64
+ PATH_SUFFIXES lib64 lib libs64 libs ${_OpenAL_ARCH_DIR}
PATHS
~/Library/Frameworks
/Library/Frameworks
@@ -90,6 +100,7 @@ find_library(OPENAL_LIBRARY
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Creative\ Labs\\OpenAL\ 1.1\ Software\ Development\ Kit\\1.00.0000;InstallDir]
)
+unset(_OpenAL_ARCH_DIR)
# handle the QUIETLY and REQUIRED arguments and set OPENAL_FOUND to TRUE if
# all listed variables are TRUE
diff --git a/Modules/FindOpenCL.cmake b/Modules/FindOpenCL.cmake
new file mode 100644
index 000000000..4d3ed842c
--- /dev/null
+++ b/Modules/FindOpenCL.cmake
@@ -0,0 +1,136 @@
+#.rst:
+# FindOpenCL
+# ----------
+#
+# Try to find OpenCL
+#
+# Once done this will define::
+#
+# OpenCL_FOUND - True if OpenCL was found
+# OpenCL_INCLUDE_DIRS - include directories for OpenCL
+# OpenCL_LIBRARIES - link against this library to use OpenCL
+# OpenCL_VERSION_STRING - Highest supported OpenCL version (eg. 1.2)
+# OpenCL_VERSION_MAJOR - The major version of the OpenCL implementation
+# OpenCL_VERSION_MINOR - The minor version of the OpenCL implementation
+#
+# The module will also define two cache variables::
+#
+# OpenCL_INCLUDE_DIR - the OpenCL include directory
+# OpenCL_LIBRARY - the path to the OpenCL library
+#
+
+#=============================================================================
+# Copyright 2014 Matthaeus G. Chajdas
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+function(_FIND_OPENCL_VERSION)
+ include(CheckSymbolExists)
+ include(CMakePushCheckState)
+ set(CMAKE_REQUIRED_QUIET ${OpenCL_FIND_QUIETLY})
+
+ CMAKE_PUSH_CHECK_STATE()
+ foreach(VERSION "2_0" "1_2" "1_1" "1_0")
+ set(CMAKE_REQUIRED_INCLUDES "${OpenCL_INCLUDE_DIR}")
+
+ if(APPLE)
+ CHECK_SYMBOL_EXISTS(
+ CL_VERSION_${VERSION}
+ "${OpenCL_INCLUDE_DIR}/OpenCL/cl.h"
+ OPENCL_VERSION_${VERSION})
+ else()
+ CHECK_SYMBOL_EXISTS(
+ CL_VERSION_${VERSION}
+ "${OpenCL_INCLUDE_DIR}/CL/cl.h"
+ OPENCL_VERSION_${VERSION})
+ endif()
+
+ if(OPENCL_VERSION_${VERSION})
+ string(REPLACE "_" "." VERSION "${VERSION}")
+ set(OpenCL_VERSION_STRING ${VERSION} PARENT_SCOPE)
+ string(REGEX MATCHALL "[0-9]+" version_components "${VERSION}")
+ list(GET version_components 0 major_version)
+ list(GET version_components 1 minor_version)
+ set(OpenCL_VERSION_MAJOR ${major_version} PARENT_SCOPE)
+ set(OpenCL_VERSION_MINOR ${minor_version} PARENT_SCOPE)
+ break()
+ endif()
+ endforeach()
+ CMAKE_POP_CHECK_STATE()
+endfunction()
+
+find_path(OpenCL_INCLUDE_DIR
+ NAMES
+ CL/cl.h OpenCL/cl.h
+ PATHS
+ ENV "PROGRAMFILES(X86)"
+ ENV AMDAPPSDKROOT
+ ENV INTELOCLSDKROOT
+ ENV NVSDKCOMPUTE_ROOT
+ ENV CUDA_PATH
+ ENV ATISTREAMSDKROOT
+ PATH_SUFFIXES
+ include
+ OpenCL/common/inc
+ "AMD APP/include")
+
+_FIND_OPENCL_VERSION()
+
+if(WIN32)
+ if(CMAKE_SIZEOF_VOID_P EQUAL 4)
+ find_library(OpenCL_LIBRARY
+ NAMES OpenCL
+ PATHS
+ ENV "PROGRAMFILES(X86)"
+ ENV AMDAPPSDKROOT
+ ENV INTELOCLSDKROOT
+ ENV CUDA_PATH
+ ENV NVSDKCOMPUTE_ROOT
+ ENV ATISTREAMSDKROOT
+ PATH_SUFFIXES
+ "AMD APP/lib/x86"
+ lib/x86
+ lib/Win32
+ OpenCL/common/lib/Win32)
+ elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ find_library(OpenCL_LIBRARY
+ NAMES OpenCL
+ PATHS
+ ENV "PROGRAMFILES(X86)"
+ ENV AMDAPPSDKROOT
+ ENV INTELOCLSDKROOT
+ ENV CUDA_PATH
+ ENV NVSDKCOMPUTE_ROOT
+ ENV ATISTREAMSDKROOT
+ PATH_SUFFIXES
+ "AMD APP/lib/x86_64"
+ lib/x86_64
+ lib/x64
+ OpenCL/common/lib/x64)
+ endif()
+else()
+ find_library(OpenCL_LIBRARY
+ NAMES OpenCL)
+endif()
+
+set(OpenCL_LIBRARIES ${OpenCL_LIBRARY})
+set(OpenCL_INCLUDE_DIRS ${OpenCL_INCLUDE_DIR})
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+find_package_handle_standard_args(
+ OpenCL
+ FOUND_VAR OpenCL_FOUND
+ REQUIRED_VARS OpenCL_LIBRARY OpenCL_INCLUDE_DIR
+ VERSION_VAR OpenCL_VERSION_STRING)
+
+mark_as_advanced(
+ OpenCL_INCLUDE_DIR
+ OpenCL_LIBRARY)
diff --git a/Modules/FindOpenGL.cmake b/Modules/FindOpenGL.cmake
index 83fcc3dc7..93e488bf9 100644
--- a/Modules/FindOpenGL.cmake
+++ b/Modules/FindOpenGL.cmake
@@ -1,19 +1,39 @@
-# - Try to find OpenGL
-# Once done this will define
+#.rst:
+# FindOpenGL
+# ----------
#
-# OPENGL_FOUND - system has OpenGL
-# OPENGL_XMESA_FOUND - system has XMESA
-# OPENGL_GLU_FOUND - system has GLU
-# OPENGL_INCLUDE_DIR - the GL include directory
-# OPENGL_LIBRARIES - Link these to use OpenGL and GLU
+# FindModule for OpenGL and GLU.
#
-# If you want to use just GL you can use these values
-# OPENGL_gl_LIBRARY - Path to OpenGL Library
-# OPENGL_glu_LIBRARY - Path to GLU Library
+# Result Variables
+# ^^^^^^^^^^^^^^^^
#
-# On OSX default to using the framework version of opengl
-# People will have to change the cache values of OPENGL_glu_LIBRARY
-# and OPENGL_gl_LIBRARY to use OpenGL with X11 on OSX
+# This module sets the following variables:
+#
+# ``OPENGL_FOUND``
+# True, if the system has OpenGL.
+# ``OPENGL_XMESA_FOUND``
+# True, if the system has XMESA.
+# ``OPENGL_GLU_FOUND``
+# True, if the system has GLU.
+# ``OPENGL_INCLUDE_DIR``
+# Path to the OpenGL include directory.
+# ``OPENGL_LIBRARIES``
+# Paths to the OpenGL and GLU libraries.
+#
+# If you want to use just GL you can use these values:
+#
+# ``OPENGL_gl_LIBRARY``
+# Path to the OpenGL library.
+# ``OPENGL_glu_LIBRARY``
+# Path to the GLU library.
+#
+# OSX Specific
+# ^^^^^^^^^^^^
+#
+# On OSX default to using the framework version of OpenGL. People will
+# have to change the cache values of OPENGL_glu_LIBRARY and
+# OPENGL_gl_LIBRARY to use OpenGL with X11 on OSX.
+
#=============================================================================
# Copyright 2001-2009 Kitware, Inc.
@@ -51,9 +71,11 @@ elseif (WIN32)
elseif (APPLE)
- find_library(OPENGL_gl_LIBRARY OpenGL DOC "OpenGL lib for OSX")
- find_library(OPENGL_glu_LIBRARY AGL DOC "AGL lib for OSX")
- find_path(OPENGL_INCLUDE_DIR OpenGL/gl.h DOC "Include for OpenGL on OSX")
+ # The OpenGL.framework provides both gl and glu
+ find_library(OPENGL_gl_LIBRARY OpenGL DOC "OpenGL library for OS X")
+ find_library(OPENGL_glu_LIBRARY OpenGL DOC
+ "GLU library for OS X (usually same as OpenGL library)")
+ find_path(OPENGL_INCLUDE_DIR OpenGL/gl.h DOC "Include for OpenGL on OS X")
list(APPEND _OpenGL_REQUIRED_VARS OPENGL_INCLUDE_DIR)
else()
@@ -108,19 +130,6 @@ else()
unset(_OPENGL_INCLUDE_PATH)
unset(_OPENGL_LIB_PATH)
- # On Unix OpenGL most certainly always requires X11.
- # Feel free to tighten up these conditions if you don't
- # think this is always true.
-
- if (OPENGL_gl_LIBRARY)
- if(NOT X11_FOUND)
- include(${CMAKE_CURRENT_LIST_DIR}/FindX11.cmake)
- endif()
- if (X11_FOUND)
- set (OPENGL_LIBRARIES ${X11_LIBRARIES})
- endif ()
- endif ()
-
find_library(OPENGL_glu_LIBRARY
NAMES GLU MesaGLU
PATHS ${OPENGL_gl_LIBRARY}
@@ -142,7 +151,9 @@ if(OPENGL_gl_LIBRARY)
set( OPENGL_LIBRARIES ${OPENGL_gl_LIBRARY} ${OPENGL_LIBRARIES})
if(OPENGL_glu_LIBRARY)
set( OPENGL_GLU_FOUND "YES" )
- set( OPENGL_LIBRARIES ${OPENGL_glu_LIBRARY} ${OPENGL_LIBRARIES} )
+ if(NOT "${OPENGL_glu_LIBRARY}" STREQUAL "${OPENGL_gl_LIBRARY}")
+ set( OPENGL_LIBRARIES ${OPENGL_glu_LIBRARY} ${OPENGL_LIBRARIES} )
+ endif()
else()
set( OPENGL_GLU_FOUND "NO" )
endif()
diff --git a/Modules/FindOpenMP.cmake b/Modules/FindOpenMP.cmake
index 8afad6822..ee4bdd6c8 100644
--- a/Modules/FindOpenMP.cmake
+++ b/Modules/FindOpenMP.cmake
@@ -1,21 +1,34 @@
-# - Finds OpenMP support
-# This module can be used to detect OpenMP support in a compiler.
-# If the compiler supports OpenMP, the flags required to compile with
+#.rst:
+# FindOpenMP
+# ----------
+#
+# Finds OpenMP support
+#
+# This module can be used to detect OpenMP support in a compiler. If
+# the compiler supports OpenMP, the flags required to compile with
# OpenMP support are returned in variables for the different languages.
# The variables may be empty if the compiler does not need a special
# flag to support OpenMP.
#
# The following variables are set:
-# OpenMP_C_FLAGS - flags to add to the C compiler for OpenMP support
-# OpenMP_CXX_FLAGS - flags to add to the CXX compiler for OpenMP support
-# OPENMP_FOUND - true if openmp is detected
#
-# Supported compilers can be found at http://openmp.org/wp/openmp-compilers/
+# ::
+#
+# OpenMP_C_FLAGS - flags to add to the C compiler for OpenMP support
+# OpenMP_CXX_FLAGS - flags to add to the CXX compiler for OpenMP support
+# OpenMP_Fortran_FLAGS - flags to add to the Fortran compiler for OpenMP support
+# OPENMP_FOUND - true if openmp is detected
+#
+#
+#
+# Supported compilers can be found at
+# http://openmp.org/wp/openmp-compilers/
#=============================================================================
# Copyright 2009 Kitware, Inc.
# Copyright 2008-2009 André Rigland Brodtkorb <Andre.Brodtkorb@ifi.uio.no>
# Copyright 2012 Rolf Eike Beer <eike@sf-mail.de>
+# Copyright 2014 Nicolas Bock <nicolasbock@gmail.com>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
@@ -28,6 +41,8 @@
# License text for the above reference.)
set(_OPENMP_REQUIRED_VARS)
+set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET})
+set(CMAKE_REQUIRED_QUIET ${OpenMP_FIND_QUIETLY})
function(_OPENMP_FLAG_CANDIDATES LANG)
set(OpenMP_FLAG_CANDIDATES
@@ -35,6 +50,8 @@ function(_OPENMP_FLAG_CANDIDATES LANG)
" "
#GNU
"-fopenmp"
+ #Clang
+ "-fopenmp=libomp"
#Microsoft Visual Studio
"/openmp"
#Intel windows
@@ -52,11 +69,15 @@ function(_OPENMP_FLAG_CANDIDATES LANG)
)
set(OMP_FLAG_GNU "-fopenmp")
+ set(OMP_FLAG_Clang "-fopenmp=libomp")
set(OMP_FLAG_HP "+Oopenmp")
if(WIN32)
set(OMP_FLAG_Intel "-Qopenmp")
- else()
+ elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "Intel" AND
+ "${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS "15.0.0.20140528")
set(OMP_FLAG_Intel "-openmp")
+ else()
+ set(OMP_FLAG_Intel "-qopenmp")
endif()
set(OMP_FLAG_MIPSpro "-mp")
set(OMP_FLAG_MSVC "/openmp")
@@ -90,6 +111,17 @@ int main() {
}
")
+# same in Fortran
+set(OpenMP_Fortran_TEST_SOURCE
+ "
+ program test
+ use omp_lib
+ integer :: n
+ n = omp_get_num_threads()
+ end program test
+ "
+ )
+
# check c compiler
if(CMAKE_C_COMPILER_LOADED)
# if these are set then do not try to find them again,
@@ -105,7 +137,9 @@ if(CMAKE_C_COMPILER_LOADED)
set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
set(CMAKE_REQUIRED_FLAGS "${FLAG}")
unset(OpenMP_FLAG_DETECTED CACHE)
- message(STATUS "Try OpenMP C flag = [${FLAG}]")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Try OpenMP C flag = [${FLAG}]")
+ endif()
check_c_source_compiles("${OpenMP_C_TEST_SOURCE}" OpenMP_FLAG_DETECTED)
set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}")
if(OpenMP_FLAG_DETECTED)
@@ -139,7 +173,9 @@ if(CMAKE_CXX_COMPILER_LOADED)
set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
set(CMAKE_REQUIRED_FLAGS "${FLAG}")
unset(OpenMP_FLAG_DETECTED CACHE)
- message(STATUS "Try OpenMP CXX flag = [${FLAG}]")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Try OpenMP CXX flag = [${FLAG}]")
+ endif()
check_cxx_source_compiles("${OpenMP_CXX_TEST_SOURCE}" OpenMP_FLAG_DETECTED)
set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}")
if(OpenMP_FLAG_DETECTED)
@@ -156,6 +192,42 @@ if(CMAKE_CXX_COMPILER_LOADED)
unset(OpenMP_CXX_TEST_SOURCE)
endif()
+# check Fortran compiler
+if(CMAKE_Fortran_COMPILER_LOADED)
+ # if these are set then do not try to find them again,
+ # by avoiding any try_compiles for the flags
+ if(OpenMP_Fortran_FLAGS)
+ unset(OpenMP_Fortran_FLAG_CANDIDATES)
+ else()
+ _OPENMP_FLAG_CANDIDATES("Fortran")
+ include(${CMAKE_CURRENT_LIST_DIR}/CheckFortranSourceCompiles.cmake)
+ endif()
+
+ foreach(FLAG IN LISTS OpenMP_Fortran_FLAG_CANDIDATES)
+ set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
+ set(CMAKE_REQUIRED_FLAGS "${FLAG}")
+ unset(OpenMP_FLAG_DETECTED CACHE)
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Try OpenMP Fortran flag = [${FLAG}]")
+ endif()
+ check_fortran_source_compiles("${OpenMP_Fortran_TEST_SOURCE}" OpenMP_FLAG_DETECTED)
+ set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}")
+ if(OpenMP_FLAG_DETECTED)
+ set(OpenMP_Fortran_FLAGS_INTERNAL "${FLAG}")
+ break()
+ endif()
+ endforeach()
+
+ set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_INTERNAL}"
+ CACHE STRING "Fortran compiler flags for OpenMP parallization")
+
+ list(APPEND _OPENMP_REQUIRED_VARS OpenMP_Fortran_FLAGS)
+ unset(OpenMP_Fortran_FLAG_CANDIDATES)
+ unset(OpenMP_Fortran_TEST_SOURCE)
+endif()
+
+set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE})
+
if(_OPENMP_REQUIRED_VARS)
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
diff --git a/Modules/FindOpenSSL.cmake b/Modules/FindOpenSSL.cmake
index 9851f67ad..8b4b9883a 100644
--- a/Modules/FindOpenSSL.cmake
+++ b/Modules/FindOpenSSL.cmake
@@ -1,13 +1,43 @@
-# - Try to find the OpenSSL encryption library
-# Once done this will define
+#.rst:
+# FindOpenSSL
+# -----------
#
-# OPENSSL_ROOT_DIR - Set this variable to the root installation of OpenSSL
+# Find the OpenSSL encryption library.
#
-# Read-Only variables:
-# OPENSSL_FOUND - system has the OpenSSL library
-# OPENSSL_INCLUDE_DIR - the OpenSSL include directory
-# OPENSSL_LIBRARIES - The libraries needed to use OpenSSL
-# OPENSSL_VERSION - This is set to $major.$minor.$revision$path (eg. 0.9.8s)
+# Imported Targets
+# ^^^^^^^^^^^^^^^^
+#
+# This module defines the following :prop_tgt:`IMPORTED` targets:
+#
+# ``OpenSSL::SSL``
+# The OpenSSL ``ssl`` library, if found.
+# ``OpenSSL::Crypto``
+# The OpenSSL ``crypto`` library, if found.
+#
+# Result Variables
+# ^^^^^^^^^^^^^^^^
+#
+# This module will set the following variables in your project:
+#
+# ``OPENSSL_FOUND``
+# System has the OpenSSL library.
+# ``OPENSSL_INCLUDE_DIR``
+# The OpenSSL include directory.
+# ``OPENSSL_CRYPTO_LIBRARY``
+# The OpenSSL crypto library.
+# ``OPENSSL_SSL_LIBRARY``
+# The OpenSSL SSL library.
+# ``OPENSSL_LIBRARIES``
+# All OpenSSL libraries.
+# ``OPENSSL_VERSION``
+# This is set to ``$major.$minor.$revision$patch`` (e.g. ``0.9.8s``).
+#
+# Hints
+# ^^^^^
+#
+# Set ``OPENSSL_ROOT_DIR`` to the root directory of an OpenSSL installation.
+# Set ``OPENSSL_USE_STATIC_LIBS`` to ``TRUE`` to look for static libraries.
+# Set ``OPENSSL_MSVC_STATIC_RT`` set ``TRUE`` to choose the MT version of the lib.
#=============================================================================
# Copyright 2006-2009 Kitware, Inc.
@@ -29,6 +59,16 @@ if (UNIX)
pkg_check_modules(_OPENSSL QUIET openssl)
endif ()
+# Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES
+if(OPENSSL_USE_STATIC_LIBS)
+ set(_openssl_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ if(WIN32)
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ else()
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .a )
+ endif()
+endif()
+
if (WIN32)
# http://www.slproweb.com/products/Win32OpenSSL.html
set(_OPENSSL_ROOT_HINTS
@@ -47,10 +87,6 @@ if (WIN32)
"C:/OpenSSL-Win64/"
)
unset(_programfiles)
- set(_OPENSSL_ROOT_HINTS_AND_PATHS
- HINTS ${_OPENSSL_ROOT_HINTS}
- PATHS ${_OPENSSL_ROOT_PATHS}
- )
else ()
set(_OPENSSL_ROOT_HINTS
${OPENSSL_ROOT_DIR}
@@ -58,12 +94,17 @@ else ()
)
endif ()
+set(_OPENSSL_ROOT_HINTS_AND_PATHS
+ HINTS ${_OPENSSL_ROOT_HINTS}
+ PATHS ${_OPENSSL_ROOT_PATHS}
+ )
+
find_path(OPENSSL_INCLUDE_DIR
NAMES
openssl/ssl.h
+ ${_OPENSSL_ROOT_HINTS_AND_PATHS}
HINTS
${_OPENSSL_INCLUDEDIR}
- ${_OPENSSL_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
include
)
@@ -73,7 +114,7 @@ if(WIN32 AND NOT CYGWIN)
# /MD and /MDd are the standard values - if someone wants to use
# others, the libnames have to change here too
# use also ssl and ssleay32 in debug as fallback for openssl < 0.9.8b
- # TODO: handle /MT and static lib
+ # enable OPENSSL_MSVC_STATIC_RT to get the libs build /MT (Multithreaded no-DLL)
# In Visual C++ naming convention each of these four kinds of Windows libraries has it's standard suffix:
# * MD for dynamic-release
# * MDd for dynamic-debug
@@ -84,49 +125,63 @@ if(WIN32 AND NOT CYGWIN)
# We are using the libraries located in the VC subdir instead of the parent directory eventhough :
# libeay32MD.lib is identical to ../libeay32.lib, and
# ssleay32MD.lib is identical to ../ssleay32.lib
+ # enable OPENSSL_USE_STATIC_LIBS to use the static libs located in lib/VC/static
+
+ if (OPENSSL_MSVC_STATIC_RT)
+ set(_OPENSSL_MSVC_RT_MODE "MT")
+ else ()
+ set(_OPENSSL_MSVC_RT_MODE "MD")
+ endif ()
+
+ if(OPENSSL_USE_STATIC_LIBS)
+ set(_OPENSSL_PATH_SUFFIXES
+ "lib"
+ "VC/static"
+ "lib/VC/static"
+ )
+ else()
+ set(_OPENSSL_PATH_SUFFIXES
+ "lib"
+ "VC"
+ "lib/VC"
+ )
+ endif ()
+
find_library(LIB_EAY_DEBUG
NAMES
- libeay32MDd
+ libeay32${_OPENSSL_MSVC_RT_MODE}d
libeay32d
${_OPENSSL_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
- "lib"
- "VC"
- "lib/VC"
+ ${_OPENSSL_PATH_SUFFIXES}
)
find_library(LIB_EAY_RELEASE
NAMES
- libeay32MD
+ libeay32${_OPENSSL_MSVC_RT_MODE}
libeay32
${_OPENSSL_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
- "lib"
- "VC"
- "lib/VC"
+ ${_OPENSSL_PATH_SUFFIXES}
)
find_library(SSL_EAY_DEBUG
NAMES
- ssleay32MDd
+ ssleay32${_OPENSSL_MSVC_RT_MODE}d
ssleay32d
${_OPENSSL_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
- "lib"
- "VC"
- "lib/VC"
+ ${_OPENSSL_PATH_SUFFIXES}
)
find_library(SSL_EAY_RELEASE
NAMES
- ssleay32MD
+ ssleay32${_OPENSSL_MSVC_RT_MODE}
ssleay32
ssl
${_OPENSSL_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
- "lib"
- "VC"
- "lib/VC"
+ ${_OPENSSL_PATH_SUFFIXES}
)
set(LIB_EAY_LIBRARY_DEBUG "${LIB_EAY_DEBUG}")
@@ -138,15 +193,15 @@ if(WIN32 AND NOT CYGWIN)
select_library_configurations(LIB_EAY)
select_library_configurations(SSL_EAY)
- set( OPENSSL_LIBRARIES ${SSL_EAY_LIBRARY} ${LIB_EAY_LIBRARY} )
+ mark_as_advanced(LIB_EAY_LIBRARY_DEBUG LIB_EAY_LIBRARY_RELEASE
+ SSL_EAY_LIBRARY_DEBUG SSL_EAY_LIBRARY_RELEASE)
+ set(OPENSSL_SSL_LIBRARY ${SSL_EAY_LIBRARY} )
+ set(OPENSSL_CRYPTO_LIBRARY ${LIB_EAY_LIBRARY} )
+ set(OPENSSL_LIBRARIES ${SSL_EAY_LIBRARY} ${LIB_EAY_LIBRARY} )
elseif(MINGW)
# same player, for MinGW
- set(LIB_EAY_NAMES libeay32)
- set(SSL_EAY_NAMES ssleay32)
- if(CMAKE_CROSSCOMPILING)
- list(APPEND LIB_EAY_NAMES crypto)
- list(APPEND SSL_EAY_NAMES ssl)
- endif()
+ set(LIB_EAY_NAMES crypto libeay32)
+ set(SSL_EAY_NAMES ssl ssleay32)
find_library(LIB_EAY
NAMES
${LIB_EAY_NAMES}
@@ -166,7 +221,9 @@ if(WIN32 AND NOT CYGWIN)
)
mark_as_advanced(SSL_EAY LIB_EAY)
- set( OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY} )
+ set(OPENSSL_SSL_LIBRARY ${SSL_EAY} )
+ set(OPENSSL_CRYPTO_LIBRARY ${LIB_EAY} )
+ set(OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY} )
unset(LIB_EAY_NAMES)
unset(SSL_EAY_NAMES)
else()
@@ -174,9 +231,9 @@ if(WIN32 AND NOT CYGWIN)
find_library(LIB_EAY
NAMES
libeay32
+ ${_OPENSSL_ROOT_HINTS_AND_PATHS}
HINTS
${_OPENSSL_LIBDIR}
- ${_OPENSSL_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
lib
)
@@ -184,15 +241,17 @@ if(WIN32 AND NOT CYGWIN)
find_library(SSL_EAY
NAMES
ssleay32
+ ${_OPENSSL_ROOT_HINTS_AND_PATHS}
HINTS
${_OPENSSL_LIBDIR}
- ${_OPENSSL_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
lib
)
mark_as_advanced(SSL_EAY LIB_EAY)
- set( OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY} )
+ set(OPENSSL_SSL_LIBRARY ${SSL_EAY} )
+ set(OPENSSL_CRYPTO_LIBRARY ${LIB_EAY} )
+ set(OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY} )
endif()
else()
@@ -201,9 +260,9 @@ else()
ssl
ssleay32
ssleay32MD
+ ${_OPENSSL_ROOT_HINTS_AND_PATHS}
HINTS
${_OPENSSL_LIBDIR}
- ${_OPENSSL_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
lib
)
@@ -211,9 +270,9 @@ else()
find_library(OPENSSL_CRYPTO_LIBRARY
NAMES
crypto
+ ${_OPENSSL_ROOT_HINTS_AND_PATHS}
HINTS
${_OPENSSL_LIBDIR}
- ${_OPENSSL_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
lib
)
@@ -260,11 +319,9 @@ function(from_hex HEX DEC)
endfunction()
if (OPENSSL_INCLUDE_DIR)
- if (_OPENSSL_VERSION)
- set(OPENSSL_VERSION "${_OPENSSL_VERSION}")
- elseif(OPENSSL_INCLUDE_DIR AND EXISTS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h")
+ if(OPENSSL_INCLUDE_DIR AND EXISTS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h")
file(STRINGS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h" openssl_version_str
- REGEX "^#define[\t ]+OPENSSL_VERSION_NUMBER[\t ]+0x([0-9a-fA-F])+.*")
+ REGEX "^#[\t ]*define[\t ]+OPENSSL_VERSION_NUMBER[\t ]+0x([0-9a-fA-F])+.*")
# The version number is encoded as 0xMNNFFPPS: major minor fix patch status
# The status gives if this is a developer or prerelease and is ignored here.
@@ -317,3 +374,71 @@ else ()
endif ()
mark_as_advanced(OPENSSL_INCLUDE_DIR OPENSSL_LIBRARIES)
+
+if(OPENSSL_FOUND)
+ if(NOT TARGET OpenSSL::Crypto AND
+ (EXISTS "${OPENSSL_CRYPTO_LIBRARY}" OR
+ EXISTS "${LIB_EAY_LIBRARY_DEBUG}" OR
+ EXISTS "${LIB_EAY_LIBRARY_RELEASE}")
+ )
+ add_library(OpenSSL::Crypto UNKNOWN IMPORTED)
+ set_target_properties(OpenSSL::Crypto PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${OPENSSL_INCLUDE_DIR}")
+ if(EXISTS "${OPENSSL_CRYPTO_LIBRARY}")
+ set_target_properties(OpenSSL::Crypto PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+ IMPORTED_LOCATION "${OPENSSL_CRYPTO_LIBRARY}")
+ endif()
+ if(EXISTS "${LIB_EAY_LIBRARY_DEBUG}")
+ set_property(TARGET OpenSSL::Crypto APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS DEBUG)
+ set_target_properties(OpenSSL::Crypto PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C"
+ IMPORTED_LOCATION_DEBUG "${LIB_EAY_LIBRARY_DEBUG}")
+ endif()
+ if(EXISTS "${LIB_EAY_LIBRARY_RELEASE}")
+ set_property(TARGET OpenSSL::Crypto APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS RELEASE)
+ set_target_properties(OpenSSL::Crypto PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C"
+ IMPORTED_LOCATION_RELEASE "${LIB_EAY_LIBRARY_RELEASE}")
+ endif()
+ endif()
+ if(NOT TARGET OpenSSL::SSL AND
+ (EXISTS "${OPENSSL_SSL_LIBRARY}" OR
+ EXISTS "${SSL_EAY_LIBRARY_DEBUG}" OR
+ EXISTS "${SSL_EAY_LIBRARY_RELEASE}")
+ )
+ add_library(OpenSSL::SSL UNKNOWN IMPORTED)
+ set_target_properties(OpenSSL::SSL PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${OPENSSL_INCLUDE_DIR}")
+ if(EXISTS "${OPENSSL_SSL_LIBRARY}")
+ set_target_properties(OpenSSL::SSL PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+ IMPORTED_LOCATION "${OPENSSL_SSL_LIBRARY}")
+ endif()
+ if(EXISTS "${SSL_EAY_LIBRARY_DEBUG}")
+ set_property(TARGET OpenSSL::SSL APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS DEBUG)
+ set_target_properties(OpenSSL::SSL PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C"
+ IMPORTED_LOCATION_DEBUG "${SSL_EAY_LIBRARY_DEBUG}")
+ endif()
+ if(EXISTS "${SSL_EAY_LIBRARY_RELEASE}")
+ set_property(TARGET OpenSSL::SSL APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS RELEASE)
+ set_target_properties(OpenSSL::SSL PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C"
+ IMPORTED_LOCATION_RELEASE "${SSL_EAY_LIBRARY_RELEASE}")
+ endif()
+ if(TARGET OpenSSL::Crypto)
+ set_target_properties(OpenSSL::SSL PROPERTIES
+ INTERFACE_LINK_LIBRARIES OpenSSL::Crypto)
+ endif()
+ endif()
+endif()
+
+# Restore the original find library ordering
+if(OPENSSL_USE_STATIC_LIBS)
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ${_openssl_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
+endif()
diff --git a/Modules/FindOpenSceneGraph.cmake b/Modules/FindOpenSceneGraph.cmake
index 7affca8a2..5a800e476 100644
--- a/Modules/FindOpenSceneGraph.cmake
+++ b/Modules/FindOpenSceneGraph.cmake
@@ -1,55 +1,99 @@
-# - Find OpenSceneGraph
-# This module searches for the OpenSceneGraph core "osg" library as well as
-# OpenThreads, and whatever additional COMPONENTS (nodekits) that you specify.
-# See http://www.openscenegraph.org
+#.rst:
+# FindOpenSceneGraph
+# ------------------
#
-# NOTE: To use this module effectively you must either require CMake >= 2.6.3
-# with cmake_minimum_required(VERSION 2.6.3) or download and place
-# FindOpenThreads.cmake, Findosg_functions.cmake, Findosg.cmake,
-# and Find<etc>.cmake files into your CMAKE_MODULE_PATH.
+# Find OpenSceneGraph
#
-#==================================
+# This module searches for the OpenSceneGraph core "osg" library as well
+# as OpenThreads, and whatever additional COMPONENTS (nodekits) that you
+# specify.
+#
+# ::
+#
+# See http://www.openscenegraph.org
+#
+#
+#
+# NOTE: To use this module effectively you must either require CMake >=
+# 2.6.3 with cmake_minimum_required(VERSION 2.6.3) or download and place
+# FindOpenThreads.cmake, Findosg_functions.cmake, Findosg.cmake, and
+# Find<etc>.cmake files into your CMAKE_MODULE_PATH.
+#
+# ==================================
#
# This module accepts the following variables (note mixed case)
#
-# OpenSceneGraph_DEBUG - Enable debugging output
+# ::
+#
+# OpenSceneGraph_DEBUG - Enable debugging output
+#
#
-# OpenSceneGraph_MARK_AS_ADVANCED - Mark cache variables as advanced
-# automatically
#
-# The following environment variables are also respected for finding the OSG
-# and it's various components. CMAKE_PREFIX_PATH can also be used for this
-# (see find_library() CMake documentation).
+# ::
#
-# <MODULE>_DIR (where MODULE is of the form "OSGVOLUME" and there is a FindosgVolume.cmake file)
-# OSG_DIR
-# OSGDIR
-# OSG_ROOT
+# OpenSceneGraph_MARK_AS_ADVANCED - Mark cache variables as advanced
+# automatically
#
-# [CMake 2.8.10]:
-# The CMake variable OSG_DIR can now be used as well to influence detection, instead of needing
-# to specify an environment variable.
+#
+#
+# The following environment variables are also respected for finding the
+# OSG and it's various components. CMAKE_PREFIX_PATH can also be used
+# for this (see find_library() CMake documentation).
+#
+# ``<MODULE>_DIR``
+# (where MODULE is of the form "OSGVOLUME" and there is a FindosgVolume.cmake file)
+# ``OSG_DIR``
+# ..
+# ``OSGDIR``
+# ..
+# ``OSG_ROOT``
+# ..
+#
+#
+# [CMake 2.8.10]: The CMake variable OSG_DIR can now be used as well to
+# influence detection, instead of needing to specify an environment
+# variable.
#
# This module defines the following output variables:
#
-# OPENSCENEGRAPH_FOUND - Was the OSG and all of the specified components found?
+# ::
+#
+# OPENSCENEGRAPH_FOUND - Was the OSG and all of the specified components found?
+#
#
-# OPENSCENEGRAPH_VERSION - The version of the OSG which was found
#
-# OPENSCENEGRAPH_INCLUDE_DIRS - Where to find the headers
+# ::
#
-# OPENSCENEGRAPH_LIBRARIES - The OSG libraries
+# OPENSCENEGRAPH_VERSION - The version of the OSG which was found
#
-#==================================
-# Example Usage:
#
-# find_package(OpenSceneGraph 2.0.0 REQUIRED osgDB osgUtil)
-# # libOpenThreads & libosg automatically searched
-# include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS})
#
-# add_executable(foo foo.cc)
-# target_link_libraries(foo ${OPENSCENEGRAPH_LIBRARIES})
+# ::
#
+# OPENSCENEGRAPH_INCLUDE_DIRS - Where to find the headers
+#
+#
+#
+# ::
+#
+# OPENSCENEGRAPH_LIBRARIES - The OSG libraries
+#
+#
+#
+# ================================== Example Usage:
+#
+# ::
+#
+# find_package(OpenSceneGraph 2.0.0 REQUIRED osgDB osgUtil)
+# # libOpenThreads & libosg automatically searched
+# include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS})
+#
+#
+#
+# ::
+#
+# add_executable(foo foo.cc)
+# target_link_libraries(foo ${OPENSCENEGRAPH_LIBRARIES})
#=============================================================================
# Copyright 2009 Kitware, Inc.
@@ -160,8 +204,11 @@ foreach(_osg_module ${_osg_modules_to_process})
find_package(${_osg_module} ${_osg_quiet})
string(TOUPPER ${_osg_module} _osg_module_UC)
- list(APPEND OPENSCENEGRAPH_INCLUDE_DIR ${${_osg_module_UC}_INCLUDE_DIR})
- list(APPEND OPENSCENEGRAPH_LIBRARIES ${${_osg_module_UC}_LIBRARIES})
+ # append to list if module was found OR is required
+ if( ${_osg_module_UC}_FOUND OR OpenSceneGraph_FIND_REQUIRED )
+ list(APPEND OPENSCENEGRAPH_INCLUDE_DIR ${${_osg_module_UC}_INCLUDE_DIR})
+ list(APPEND OPENSCENEGRAPH_LIBRARIES ${${_osg_module_UC}_LIBRARIES})
+ endif()
if(OpenSceneGraph_MARK_AS_ADVANCED)
OSG_MARK_AS_ADVANCED(${_osg_module})
diff --git a/Modules/FindOpenThreads.cmake b/Modules/FindOpenThreads.cmake
index e0599604a..69bab3dd0 100644
--- a/Modules/FindOpenThreads.cmake
+++ b/Modules/FindOpenThreads.cmake
@@ -1,23 +1,25 @@
-# OpenThreads is a C++ based threading library. Its largest userbase
+#.rst:
+# FindOpenThreads
+# ---------------
+#
+#
+#
+# OpenThreads is a C++ based threading library. Its largest userbase
# seems to OpenSceneGraph so you might notice I accept OSGDIR as an
-# environment path.
-# I consider this part of the Findosg* suite used to find OpenSceneGraph
-# components.
-# Each component is separate and you must opt in to each module.
+# environment path. I consider this part of the Findosg* suite used to
+# find OpenSceneGraph components. Each component is separate and you
+# must opt in to each module.
#
-# Locate OpenThreads
-# This module defines
-# OPENTHREADS_LIBRARY
+# Locate OpenThreads This module defines OPENTHREADS_LIBRARY
# OPENTHREADS_FOUND, if false, do not try to link to OpenThreads
# OPENTHREADS_INCLUDE_DIR, where to find the headers
#
-# $OPENTHREADS_DIR is an environment variable that would
-# correspond to the ./configure --prefix=$OPENTHREADS_DIR
-# used in building osg.
+# $OPENTHREADS_DIR is an environment variable that would correspond to
+# the ./configure --prefix=$OPENTHREADS_DIR used in building osg.
#
-# [CMake 2.8.10]:
-# The CMake variables OPENTHREADS_DIR or OSG_DIR can now be used as well to influence
-# detection, instead of needing to specify an environment variable.
+# [CMake 2.8.10]: The CMake variables OPENTHREADS_DIR or OSG_DIR can now
+# be used as well to influence detection, instead of needing to specify
+# an environment variable.
#
# Created by Eric Wing.
diff --git a/Modules/FindPHP4.cmake b/Modules/FindPHP4.cmake
index 4267ac155..25fff8c73 100644
--- a/Modules/FindPHP4.cmake
+++ b/Modules/FindPHP4.cmake
@@ -1,11 +1,17 @@
-# - Find PHP4
-# This module finds if PHP4 is installed and determines where the include files
-# and libraries are. It also determines what the name of the library is. This
-# code sets the following variables:
+#.rst:
+# FindPHP4
+# --------
#
-# PHP4_INCLUDE_PATH = path to where php.h can be found
-# PHP4_EXECUTABLE = full path to the php4 binary
+# Find PHP4
#
+# This module finds if PHP4 is installed and determines where the
+# include files and libraries are. It also determines what the name of
+# the library is. This code sets the following variables:
+#
+# ::
+#
+# PHP4_INCLUDE_PATH = path to where php.h can be found
+# PHP4_EXECUTABLE = full path to the php4 binary
#=============================================================================
# Copyright 2004-2009 Kitware, Inc.
@@ -40,7 +46,7 @@ if(PHP4_FOUND_INCLUDE_PATH)
foreach(php4_path Zend main TSRM)
set(php4_paths ${php4_paths} "${PHP4_FOUND_INCLUDE_PATH}/${php4_path}")
endforeach()
- set(PHP4_INCLUDE_PATH "${php4_paths}" INTERNAL "PHP4 include paths")
+ set(PHP4_INCLUDE_PATH "${php4_paths}")
endif()
find_program(PHP4_EXECUTABLE NAMES php4 php )
diff --git a/Modules/FindPNG.cmake b/Modules/FindPNG.cmake
index a2577d26b..cae41acd9 100644
--- a/Modules/FindPNG.cmake
+++ b/Modules/FindPNG.cmake
@@ -1,22 +1,50 @@
-# - Find the native PNG includes and library
+#.rst:
+# FindPNG
+# -------
#
-# This module searches libpng, the library for working with PNG images.
+# Find libpng, the official reference library for the PNG image format.
#
-# It defines the following variables
-# PNG_INCLUDE_DIRS, where to find png.h, etc.
-# PNG_LIBRARIES, the libraries to link against to use PNG.
-# PNG_DEFINITIONS - You should add_definitons(${PNG_DEFINITIONS}) before compiling code that includes png library files.
-# PNG_FOUND, If false, do not try to use PNG.
-# PNG_VERSION_STRING - the version of the PNG library found (since CMake 2.8.8)
-# Also defined, but not for general use are
-# PNG_LIBRARY, where to find the PNG library.
-# For backward compatiblity the variable PNG_INCLUDE_DIR is also set. It has the same value as PNG_INCLUDE_DIRS.
+# Imported targets
+# ^^^^^^^^^^^^^^^^
#
-# Since PNG depends on the ZLib compression library, none of the above will be
-# defined unless ZLib can be found.
+# This module defines the following :prop_tgt:`IMPORTED` target:
+#
+# ``PNG::PNG``
+# The libpng library, if found.
+#
+# Result variables
+# ^^^^^^^^^^^^^^^^
+#
+# This module will set the following variables in your project:
+#
+# ``PNG_INCLUDE_DIRS``
+# where to find png.h, etc.
+# ``PNG_LIBRARIES``
+# the libraries to link against to use PNG.
+# ``PNG_DEFINITIONS``
+# You should add_definitons(${PNG_DEFINITIONS}) before compiling code
+# that includes png library files.
+# ``PNG_FOUND``
+# If false, do not try to use PNG.
+# ``PNG_VERSION_STRING``
+# the version of the PNG library found (since CMake 2.8.8)
+#
+# Obsolete variables
+# ^^^^^^^^^^^^^^^^^^
+#
+# The following variables may also be set, for backwards compatibility:
+#
+# ``PNG_LIBRARY``
+# where to find the PNG library.
+# ``PNG_INCLUDE_DIR``
+# where to find the PNG headers (same as PNG_INCLUDE_DIRS)
+#
+# Since PNG depends on the ZLib compression library, none of the above
+# will be defined unless ZLib can be found.
#=============================================================================
# Copyright 2002-2009 Kitware, Inc.
+# Copyright 2016 Raumfeld
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
@@ -41,10 +69,8 @@ if(ZLIB_FOUND)
list(APPEND PNG_NAMES png libpng)
unset(PNG_NAMES_DEBUG)
set(_PNG_VERSION_SUFFIXES 17 16 15 14 12)
- if (PNG_FIND_VERSION MATCHES "^[0-9]+\\.[0-9]+(\\..*)?$")
- string(REGEX REPLACE
- "^([0-9]+)\\.([0-9]+).*" "\\1\\2"
- _PNG_VERSION_SUFFIX_MIN "${PNG_FIND_VERSION}")
+ if (PNG_FIND_VERSION MATCHES "^([0-9]+)\\.([0-9]+)(\\..*)?$")
+ set(_PNG_VERSION_SUFFIX_MIN "${CMAKE_MATCH_1}${CMAKE_MATCH_2}")
if (PNG_FIND_VERSION_EXACT)
set(_PNG_VERSION_SUFFIXES ${_PNG_VERSION_SUFFIX_MIN})
else ()
@@ -89,6 +115,32 @@ if(ZLIB_FOUND)
endif()
endif ()
+ if(NOT TARGET PNG::PNG)
+ add_library(PNG::PNG UNKNOWN IMPORTED)
+ set_target_properties(PNG::PNG PROPERTIES
+ INTERFACE_COMPILE_DEFINITIONS "${PNG_DEFINITIONS}"
+ INTERFACE_INCLUDE_DIRECTORIES "${PNG_INCLUDE_DIRS}"
+ INTERFACE_LINK_LIBRARIES ZLIB::ZLIB)
+ if(EXISTS "${PNG_LIBRARY}")
+ set_target_properties(PNG::PNG PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+ IMPORTED_LOCATION "${PNG_LIBRARY}")
+ endif()
+ if(EXISTS "${PNG_LIBRARY_DEBUG}")
+ set_property(TARGET PNG::PNG APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS DEBUG)
+ set_target_properties(PNG::PNG PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C"
+ IMPORTED_LOCATION_DEBUG "${PNG_LIBRARY_DEBUG}")
+ endif()
+ if(EXISTS "${PNG_LIBRARY_RELEASE}")
+ set_property(TARGET PNG::PNG APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS RELEASE)
+ set_target_properties(PNG::PNG PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C"
+ IMPORTED_LOCATION_RELEASE "${PNG_LIBRARY_RELEASE}")
+ endif()
+ endif()
endif ()
if (PNG_PNG_INCLUDE_DIR AND EXISTS "${PNG_PNG_INCLUDE_DIR}/png.h")
diff --git a/Modules/FindPackageHandleStandardArgs.cmake b/Modules/FindPackageHandleStandardArgs.cmake
index 70423a7e4..fe2dbeaa6 100644
--- a/Modules/FindPackageHandleStandardArgs.cmake
+++ b/Modules/FindPackageHandleStandardArgs.cmake
@@ -1,90 +1,130 @@
-# FIND_PACKAGE_HANDLE_STANDARD_ARGS(<name> ... )
-#
-# This function is intended to be used in FindXXX.cmake modules files.
-# It handles the REQUIRED, QUIET and version-related arguments to find_package().
-# It also sets the <packagename>_FOUND variable.
-# The package is considered found if all variables <var1>... listed contain
-# valid results, e.g. valid filepaths.
-#
-# There are two modes of this function. The first argument in both modes is
-# the name of the Find-module where it is called (in original casing).
-#
-# The first simple mode looks like this:
-# FIND_PACKAGE_HANDLE_STANDARD_ARGS(<name> (DEFAULT_MSG|"Custom failure message") <var1>...<varN> )
-# If the variables <var1> to <varN> are all valid, then <UPPERCASED_NAME>_FOUND
-# will be set to TRUE.
-# If DEFAULT_MSG is given as second argument, then the function will generate
-# itself useful success and error messages. You can also supply a custom error message
-# for the failure case. This is not recommended.
-#
-# The second mode is more powerful and also supports version checking:
-# FIND_PACKAGE_HANDLE_STANDARD_ARGS(NAME [FOUND_VAR <resultVar>]
-# [REQUIRED_VARS <var1>...<varN>]
-# [VERSION_VAR <versionvar>]
-# [HANDLE_COMPONENTS]
-# [CONFIG_MODE]
-# [FAIL_MESSAGE "Custom failure message"] )
-#
-# In this mode, the name of the result-variable can be set either to either
-# <UPPERCASED_NAME>_FOUND or <OriginalCase_Name>_FOUND using the FOUND_VAR option.
-# Other names for the result-variable are not allowed.
-# So for a Find-module named FindFooBar.cmake, the two possible names are
-# FooBar_FOUND and FOOBAR_FOUND. It is recommended to use the original case version.
-# If the FOUND_VAR option is not used, the default is <UPPERCASED_NAME>_FOUND.
-#
-# As in the simple mode, if <var1> through <varN> are all valid,
-# <packagename>_FOUND will be set to TRUE.
-# After REQUIRED_VARS the variables which are required for this package are listed.
-# Following VERSION_VAR the name of the variable can be specified which holds
-# the version of the package which has been found. If this is done, this version
-# will be checked against the (potentially) specified required version used
-# in the find_package() call. The EXACT keyword is also handled. The default
-# messages include information about the required version and the version
-# which has been actually found, both if the version is ok or not.
-# If the package supports components, use the HANDLE_COMPONENTS option to enable
-# handling them. In this case, find_package_handle_standard_args() will report
-# which components have been found and which are missing, and the <packagename>_FOUND
-# variable will be set to FALSE if any of the required components (i.e. not the
-# ones listed after OPTIONAL_COMPONENTS) are missing.
-# Use the option CONFIG_MODE if your FindXXX.cmake module is a wrapper for
-# a find_package(... NO_MODULE) call. In this case VERSION_VAR will be set
-# to <NAME>_VERSION and the macro will automatically check whether the
-# Config module was found.
-# Via FAIL_MESSAGE a custom failure message can be specified, if this is not
-# used, the default message will be displayed.
-#
-# Example for mode 1:
-#
-# find_package_handle_standard_args(LibXml2 DEFAULT_MSG LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR)
-#
-# LibXml2 is considered to be found, if both LIBXML2_LIBRARY and
-# LIBXML2_INCLUDE_DIR are valid. Then also LIBXML2_FOUND is set to TRUE.
-# If it is not found and REQUIRED was used, it fails with FATAL_ERROR,
-# independent whether QUIET was used or not.
-# If it is found, success will be reported, including the content of <var1>.
-# On repeated Cmake runs, the same message won't be printed again.
-#
-# Example for mode 2:
-#
-# find_package_handle_standard_args(LibXslt FOUND_VAR LibXslt_FOUND
-# REQUIRED_VARS LibXslt_LIBRARIES LibXslt_INCLUDE_DIRS
-# VERSION_VAR LibXslt_VERSION_STRING)
-# In this case, LibXslt is considered to be found if the variable(s) listed
-# after REQUIRED_VAR are all valid, i.e. LibXslt_LIBRARIES and LibXslt_INCLUDE_DIRS
-# in this case. The result will then be stored in LibXslt_FOUND .
-# Also the version of LibXslt will be checked by using the version contained
-# in LibXslt_VERSION_STRING.
-# Since no FAIL_MESSAGE is given, the default messages will be printed.
-#
-# Another example for mode 2:
-#
-# find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4)
-# find_package_handle_standard_args(Automoc4 CONFIG_MODE)
-# In this case, FindAutmoc4.cmake wraps a call to find_package(Automoc4 NO_MODULE)
-# and adds an additional search directory for automoc4.
-# Here the result will be stored in AUTOMOC4_FOUND.
-# The following FIND_PACKAGE_HANDLE_STANDARD_ARGS() call produces a proper
-# success/error message.
+#[=======================================================================[.rst:
+FindPackageHandleStandardArgs
+-----------------------------
+
+This module provides a function intended to be used in :ref:`Find Modules`
+implementing :command:`find_package(<PackageName>)` calls. It handles the
+``REQUIRED``, ``QUIET`` and version-related arguments of ``find_package``.
+It also sets the ``<PackageName>_FOUND`` variable. The package is
+considered found if all variables listed contain valid results, e.g.
+valid filepaths.
+
+.. command:: find_package_handle_standard_args
+
+ There are two signatures::
+
+ find_package_handle_standard_args(<PackageName>
+ (DEFAULT_MSG|<custom-failure-message>)
+ <required-var>...
+ )
+
+ find_package_handle_standard_args(<PackageName>
+ [FOUND_VAR <result-var>]
+ [REQUIRED_VARS <required-var>...]
+ [VERSION_VAR <version-var>]
+ [HANDLE_COMPONENTS]
+ [CONFIG_MODE]
+ [FAIL_MESSAGE <custom-failure-message>]
+ )
+
+ The ``<PackageName>_FOUND`` variable will be set to ``TRUE`` if all
+ the variables ``<required-var>...`` are valid and any optional
+ constraints are satisfied, and ``FALSE`` otherwise. A success or
+ failure message may be displayed based on the results and on
+ whether the ``REQUIRED`` and/or ``QUIET`` option was given to
+ the :command:`find_package` call.
+
+ The options are:
+
+ ``(DEFAULT_MSG|<custom-failure-message>)``
+ In the simple signature this specifies the failure message.
+ Use ``DEFAULT_MSG`` to ask for a default message to be computed
+ (recommended). Not valid in the full signature.
+
+ ``FOUND_VAR <result-var>``
+ Obsolete. Specifies either ``<PackageName>_FOUND`` or
+ ``<PACKAGENAME>_FOUND`` as the result variable. This exists only
+ for compatibility with older versions of CMake and is now ignored.
+ Result variables of both names are always set for compatibility.
+
+ ``REQUIRED_VARS <required-var>...``
+ Specify the variables which are required for this package.
+ These may be named in the generated failure message asking the
+ user to set the missing variable values. Therefore these should
+ typically be cache entries such as ``FOO_LIBRARY`` and not output
+ variables like ``FOO_LIBRARIES``.
+
+ ``VERSION_VAR <version-var>``
+ Specify the name of a variable that holds the version of the package
+ that has been found. This version will be checked against the
+ (potentially) specified required version given to the
+ :command:`find_package` call, including its ``EXACT`` option.
+ The default messages include information about the required
+ version and the version which has been actually found, both
+ if the version is ok or not.
+
+ ``HANDLE_COMPONENTS``
+ Enable handling of package components. In this case, the command
+ will report which components have been found and which are missing,
+ and the ``<PackageName>_FOUND`` variable will be set to ``FALSE``
+ if any of the required components (i.e. not the ones listed after
+ the ``OPTIONAL_COMPONENTS`` option of :command:`find_package`) are
+ missing.
+
+ ``CONFIG_MODE``
+ Specify that the calling find module is a wrapper around a
+ call to ``find_package(<PackageName> NO_MODULE)``. This implies
+ a ``VERSION_VAR`` value of ``<PackageName>_VERSION``. The command
+ will automatically check whether the package configuration file
+ was found.
+
+ ``FAIL_MESSAGE <custom-failure-message>``
+ Specify a custom failure message instead of using the default
+ generated message. Not recommended.
+
+Example for the simple signature:
+
+.. code-block:: cmake
+
+ find_package_handle_standard_args(LibXml2 DEFAULT_MSG
+ LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR)
+
+The ``LibXml2`` package is considered to be found if both
+``LIBXML2_LIBRARY`` and ``LIBXML2_INCLUDE_DIR`` are valid.
+Then also ``LibXml2_FOUND`` is set to ``TRUE``. If it is not found
+and ``REQUIRED`` was used, it fails with a
+:command:`message(FATAL_ERROR)`, independent whether ``QUIET`` was
+used or not. If it is found, success will be reported, including
+the content of the first ``<required-var>``. On repeated CMake runs,
+the same message will not be printed again.
+
+Example for the full signature:
+
+.. code-block:: cmake
+
+ find_package_handle_standard_args(LibArchive
+ REQUIRED_VARS LibArchive_LIBRARY LibArchive_INCLUDE_DIR
+ VERSION_VAR LibArchive_VERSION)
+
+In this case, the ``LibArchive`` package is considered to be found if
+both ``LibArchive_LIBRARY`` and ``LibArchive_INCLUDE_DIR`` are valid.
+Also the version of ``LibArchive`` will be checked by using the version
+contained in ``LibArchive_VERSION``. Since no ``FAIL_MESSAGE`` is given,
+the default messages will be printed.
+
+Another example for the full signature:
+
+.. code-block:: cmake
+
+ find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4)
+ find_package_handle_standard_args(Automoc4 CONFIG_MODE)
+
+In this case, a ``FindAutmoc4.cmake`` module wraps a call to
+``find_package(Automoc4 NO_MODULE)`` and adds an additional search
+directory for ``automoc4``. Then the call to
+``find_package_handle_standard_args`` produces a proper success/failure
+message.
+#]=======================================================================]
#=============================================================================
# Copyright 2007-2009 Kitware, Inc.
@@ -173,7 +213,7 @@ function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
# now that we collected all arguments, process them
- if("${FPHSA_FAIL_MESSAGE}" STREQUAL "DEFAULT_MSG")
+ if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG")
set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}")
endif()
@@ -209,17 +249,21 @@ function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
set(MISSING_VARS "")
set(DETAILS "")
# check if all passed variables are valid
- unset(${_FOUND_VAR})
+ set(FPHSA_FOUND_${_NAME} TRUE)
foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS})
if(NOT ${_CURRENT_VAR})
- set(${_FOUND_VAR} FALSE)
+ set(FPHSA_FOUND_${_NAME} FALSE)
set(MISSING_VARS "${MISSING_VARS} ${_CURRENT_VAR}")
else()
set(DETAILS "${DETAILS}[${${_CURRENT_VAR}}]")
endif()
endforeach()
- if(NOT "${${_FOUND_VAR}}" STREQUAL "FALSE")
- set(${_FOUND_VAR} TRUE)
+ if(FPHSA_FOUND_${_NAME})
+ set(${_NAME}_FOUND TRUE)
+ set(${_NAME_UPPER}_FOUND TRUE)
+ else()
+ set(${_NAME}_FOUND FALSE)
+ set(${_NAME_UPPER}_FOUND FALSE)
endif()
# component handling
@@ -243,7 +287,7 @@ function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
set(MISSING_COMPONENTS_MSG "${MISSING_COMPONENTS_MSG} ${comp}")
if(${_NAME}_FIND_REQUIRED_${comp})
- set(${_FOUND_VAR} FALSE)
+ set(${_NAME}_FOUND FALSE)
set(MISSING_VARS "${MISSING_VARS} ${comp}")
endif()
@@ -256,21 +300,50 @@ function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
# version handling:
set(VERSION_MSG "")
set(VERSION_OK TRUE)
- set(VERSION ${${FPHSA_VERSION_VAR}} )
- if (${_NAME}_FIND_VERSION)
+ set(VERSION ${${FPHSA_VERSION_VAR}})
- if(VERSION)
+ # check with DEFINED here as the requested or found version may be "0"
+ if (DEFINED ${_NAME}_FIND_VERSION)
+ if(DEFINED ${FPHSA_VERSION_VAR})
if(${_NAME}_FIND_VERSION_EXACT) # exact version required
- if (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}")
- set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"")
- set(VERSION_OK FALSE)
+ # count the dots in the version string
+ string(REGEX REPLACE "[^.]" "" _VERSION_DOTS "${VERSION}")
+ # add one dot because there is one dot more than there are components
+ string(LENGTH "${_VERSION_DOTS}." _VERSION_DOTS)
+ if (_VERSION_DOTS GREATER ${_NAME}_FIND_VERSION_COUNT)
+ # Because of the C++ implementation of find_package() ${_NAME}_FIND_VERSION_COUNT
+ # is at most 4 here. Therefore a simple lookup table is used.
+ if (${_NAME}_FIND_VERSION_COUNT EQUAL 1)
+ set(_VERSION_REGEX "[^.]*")
+ elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 2)
+ set(_VERSION_REGEX "[^.]*\\.[^.]*")
+ elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 3)
+ set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*")
+ else ()
+ set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*")
+ endif ()
+ string(REGEX REPLACE "^(${_VERSION_REGEX})\\..*" "\\1" _VERSION_HEAD "${VERSION}")
+ unset(_VERSION_REGEX)
+ if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _VERSION_HEAD)
+ set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"")
+ set(VERSION_OK FALSE)
+ else ()
+ set(VERSION_MSG "(found suitable exact version \"${VERSION}\")")
+ endif ()
+ unset(_VERSION_HEAD)
else ()
- set(VERSION_MSG "(found suitable exact version \"${VERSION}\")")
+ if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL VERSION)
+ set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"")
+ set(VERSION_OK FALSE)
+ else ()
+ set(VERSION_MSG "(found suitable exact version \"${VERSION}\")")
+ endif ()
endif ()
+ unset(_VERSION_DOTS)
else() # minimum version specified:
- if ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}")
+ if (${_NAME}_FIND_VERSION VERSION_GREATER VERSION)
set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"")
set(VERSION_OK FALSE)
else ()
@@ -297,12 +370,12 @@ function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
if(VERSION_OK)
set(DETAILS "${DETAILS}[v${VERSION}(${${_NAME}_FIND_VERSION})]")
else()
- set(${_FOUND_VAR} FALSE)
+ set(${_NAME}_FOUND FALSE)
endif()
# print the result:
- if (${_FOUND_VAR})
+ if (${_NAME}_FOUND)
FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}")
else ()
@@ -318,6 +391,6 @@ function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
endif ()
- set(${_FOUND_VAR} ${${_FOUND_VAR}} PARENT_SCOPE)
-
+ set(${_NAME}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE)
+ set(${_NAME_UPPER}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE)
endfunction()
diff --git a/Modules/FindPackageMessage.cmake b/Modules/FindPackageMessage.cmake
index 5cea43e35..a0349d3db 100644
--- a/Modules/FindPackageMessage.cmake
+++ b/Modules/FindPackageMessage.cmake
@@ -1,22 +1,30 @@
+#.rst:
+# FindPackageMessage
+# ------------------
+#
+#
+#
# FIND_PACKAGE_MESSAGE(<name> "message for user" "find result details")
#
-# This macro is intended to be used in FindXXX.cmake modules files.
-# It will print a message once for each unique find result.
-# This is useful for telling the user where a package was found.
-# The first argument specifies the name (XXX) of the package.
-# The second argument specifies the message to display.
-# The third argument lists details about the find result so that
-# if they change the message will be displayed again.
-# The macro also obeys the QUIET argument to the find_package command.
+# This macro is intended to be used in FindXXX.cmake modules files. It
+# will print a message once for each unique find result. This is useful
+# for telling the user where a package was found. The first argument
+# specifies the name (XXX) of the package. The second argument
+# specifies the message to display. The third argument lists details
+# about the find result so that if they change the message will be
+# displayed again. The macro also obeys the QUIET argument to the
+# find_package command.
#
# Example:
#
-# if(X11_FOUND)
-# FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}"
-# "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]")
-# else()
-# ...
-# endif()
+# ::
+#
+# if(X11_FOUND)
+# FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}"
+# "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]")
+# else()
+# ...
+# endif()
#=============================================================================
# Copyright 2008-2009 Kitware, Inc.
@@ -34,7 +42,7 @@
function(FIND_PACKAGE_MESSAGE pkg msg details)
# Avoid printing a message repeatedly for the same find result.
if(NOT ${pkg}_FIND_QUIETLY)
- string(REGEX REPLACE "[\n]" "" details "${details}")
+ string(REPLACE "\n" "" details "${details}")
set(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg})
if(NOT "${details}" STREQUAL "${${DETAILS_VAR}}")
# The message has not yet been printed.
diff --git a/Modules/FindPerl.cmake b/Modules/FindPerl.cmake
index 5eaf20768..70284b6f7 100644
--- a/Modules/FindPerl.cmake
+++ b/Modules/FindPerl.cmake
@@ -1,9 +1,16 @@
-# - Find perl
+#.rst:
+# FindPerl
+# --------
+#
+# Find perl
+#
# this module looks for Perl
#
-# PERL_EXECUTABLE - the full path to perl
-# PERL_FOUND - If false, don't attempt to use perl.
-# PERL_VERSION_STRING - version of perl found (since CMake 2.8.8)
+# ::
+#
+# PERL_EXECUTABLE - the full path to perl
+# PERL_FOUND - If false, don't attempt to use perl.
+# PERL_VERSION_STRING - version of perl found (since CMake 2.8.8)
#=============================================================================
# Copyright 2001-2009 Kitware, Inc.
@@ -63,9 +70,9 @@ if(PERL_EXECUTABLE)
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(NOT PERL_VERSION_RESULT_VARIABLE AND PERL_VERSION_OUTPUT_VARIABLE MATCHES "This is perl.*[ \\(]v([0-9\\._]+)[ \\)]")
- string(REGEX REPLACE ".*This is perl.*[ \\(]v([0-9\\._]+)[ \\)].*" "\\1" PERL_VERSION_STRING ${PERL_VERSION_OUTPUT_VARIABLE})
+ set(PERL_VERSION_STRING "${CMAKE_MATCH_1}")
elseif(NOT PERL_VERSION_RESULT_VARIABLE AND PERL_VERSION_OUTPUT_VARIABLE MATCHES "This is perl, version ([0-9\\._]+) +")
- string(REGEX REPLACE ".*This is perl, version ([0-9\\._]+) +.*" "\\1" PERL_VERSION_STRING ${PERL_VERSION_OUTPUT_VARIABLE})
+ set(PERL_VERSION_STRING "${CMAKE_MATCH_1}")
endif()
endif()
endif()
diff --git a/Modules/FindPerlLibs.cmake b/Modules/FindPerlLibs.cmake
index 492f04770..54ccd249f 100644
--- a/Modules/FindPerlLibs.cmake
+++ b/Modules/FindPerlLibs.cmake
@@ -1,27 +1,41 @@
-# - Find Perl libraries
-# This module finds if PERL is installed and determines where the include files
-# and libraries are. It also determines what the name of the library is. This
-# code sets the following variables:
+#.rst:
+# FindPerlLibs
+# ------------
+#
+# Find Perl libraries
+#
+# This module finds if PERL is installed and determines where the
+# include files and libraries are. It also determines what the name of
+# the library is. This code sets the following variables:
+#
+# ::
+#
+# PERLLIBS_FOUND = True if perl.h & libperl were found
+# PERL_INCLUDE_PATH = path to where perl.h is found
+# PERL_LIBRARY = path to libperl
+# PERL_EXECUTABLE = full path to the perl binary
+#
#
-# PERLLIBS_FOUND = True if perl.h & libperl were found
-# PERL_INCLUDE_PATH = path to where perl.h is found
-# PERL_LIBRARY = path to libperl
-# PERL_EXECUTABLE = full path to the perl binary
#
# The minimum required version of Perl can be specified using the
-# standard syntax, e.g. find_package(PerlLibs 6.0)
+# standard syntax, e.g. find_package(PerlLibs 6.0)
+#
+# ::
+#
+# The following variables are also available if needed
+# (introduced after CMake 2.6.4)
+#
#
-# The following variables are also available if needed
-# (introduced after CMake 2.6.4)
#
-# PERL_SITESEARCH = path to the sitesearch install dir
-# PERL_SITELIB = path to the sitelib install directory
-# PERL_VENDORARCH = path to the vendor arch install directory
-# PERL_VENDORLIB = path to the vendor lib install directory
-# PERL_ARCHLIB = path to the arch lib install directory
-# PERL_PRIVLIB = path to the priv lib install directory
-# PERL_EXTRA_C_FLAGS = Compilation flags used to build perl
+# ::
#
+# PERL_SITESEARCH = path to the sitesearch install dir
+# PERL_SITELIB = path to the sitelib install directory
+# PERL_VENDORARCH = path to the vendor arch install directory
+# PERL_VENDORLIB = path to the vendor lib install directory
+# PERL_ARCHLIB = path to the arch lib install directory
+# PERL_PRIVLIB = path to the priv lib install directory
+# PERL_EXTRA_C_FLAGS = Compilation flags used to build perl
#=============================================================================
# Copyright 2004-2009 Kitware, Inc.
diff --git a/Modules/FindPhysFS.cmake b/Modules/FindPhysFS.cmake
index a2d6abf9b..ff584c7ff 100644
--- a/Modules/FindPhysFS.cmake
+++ b/Modules/FindPhysFS.cmake
@@ -1,12 +1,15 @@
-# Locate PhysFS library
-# This module defines
-# PHYSFS_LIBRARY, the name of the library to link against
-# PHYSFS_FOUND, if false, do not try to link to PHYSFS
-# PHYSFS_INCLUDE_DIR, where to find physfs.h
+#.rst:
+# FindPhysFS
+# ----------
#
-# $PHYSFSDIR is an environment variable that would
-# correspond to the ./configure --prefix=$PHYSFSDIR
-# used in building PHYSFS.
+#
+#
+# Locate PhysFS library This module defines PHYSFS_LIBRARY, the name of
+# the library to link against PHYSFS_FOUND, if false, do not try to link
+# to PHYSFS PHYSFS_INCLUDE_DIR, where to find physfs.h
+#
+# $PHYSFSDIR is an environment variable that would correspond to the
+# ./configure --prefix=$PHYSFSDIR used in building PHYSFS.
#
# Created by Eric Wing.
diff --git a/Modules/FindPike.cmake b/Modules/FindPike.cmake
index 5b48ab4e7..2d6a03d45 100644
--- a/Modules/FindPike.cmake
+++ b/Modules/FindPike.cmake
@@ -1,11 +1,17 @@
-# - Find Pike
-# This module finds if PIKE is installed and determines where the include files
-# and libraries are. It also determines what the name of the library is. This
-# code sets the following variables:
+#.rst:
+# FindPike
+# --------
#
-# PIKE_INCLUDE_PATH = path to where program.h is found
-# PIKE_EXECUTABLE = full path to the pike binary
+# Find Pike
#
+# This module finds if PIKE is installed and determines where the
+# include files and libraries are. It also determines what the name of
+# the library is. This code sets the following variables:
+#
+# ::
+#
+# PIKE_INCLUDE_PATH = path to where program.h is found
+# PIKE_EXECUTABLE = full path to the pike binary
#=============================================================================
# Copyright 2004-2009 Kitware, Inc.
diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake
index 2766f9780..447c52622 100644
--- a/Modules/FindPkgConfig.cmake
+++ b/Modules/FindPkgConfig.cmake
@@ -1,79 +1,21 @@
-# - a pkg-config module for CMake
+#.rst:
+# FindPkgConfig
+# -------------
#
-# Usage:
-# pkg_check_modules(<PREFIX> [REQUIRED] [QUIET] <MODULE> [<MODULE>]*)
-# checks for all the given modules
-#
-# pkg_search_module(<PREFIX> [REQUIRED] [QUIET] <MODULE> [<MODULE>]*)
-# checks for given modules and uses the first working one
-#
-# When the 'REQUIRED' argument was set, macros will fail with an error
-# when module(s) could not be found
-#
-# When the 'QUIET' argument is set, no status messages will be printed.
-#
-# It sets the following variables:
-# PKG_CONFIG_FOUND ... if pkg-config executable was found
-# PKG_CONFIG_EXECUTABLE ... pathname of the pkg-config program
-# PKG_CONFIG_VERSION_STRING ... the version of the pkg-config program found
-# (since CMake 2.8.8)
-#
-# For the following variables two sets of values exist; first one is the
-# common one and has the given PREFIX. The second set contains flags
-# which are given out when pkgconfig was called with the '--static'
-# option.
-# <XPREFIX>_FOUND ... set to 1 if module(s) exist
-# <XPREFIX>_LIBRARIES ... only the libraries (w/o the '-l')
-# <XPREFIX>_LIBRARY_DIRS ... the paths of the libraries (w/o the '-L')
-# <XPREFIX>_LDFLAGS ... all required linker flags
-# <XPREFIX>_LDFLAGS_OTHER ... all other linker flags
-# <XPREFIX>_INCLUDE_DIRS ... the '-I' preprocessor flags (w/o the '-I')
-# <XPREFIX>_CFLAGS ... all required cflags
-# <XPREFIX>_CFLAGS_OTHER ... the other compiler flags
-#
-# <XPREFIX> = <PREFIX> for common case
-# <XPREFIX> = <PREFIX>_STATIC for static linking
-#
-# There are some special variables whose prefix depends on the count
-# of given modules. When there is only one module, <PREFIX> stays
-# unchanged. When there are multiple modules, the prefix will be
-# changed to <PREFIX>_<MODNAME>:
-# <XPREFIX>_VERSION ... version of the module
-# <XPREFIX>_PREFIX ... prefix-directory of the module
-# <XPREFIX>_INCLUDEDIR ... include-dir of the module
-# <XPREFIX>_LIBDIR ... lib-dir of the module
-#
-# <XPREFIX> = <PREFIX> when |MODULES| == 1, else
-# <XPREFIX> = <PREFIX>_<MODNAME>
-#
-# A <MODULE> parameter can have the following formats:
-# {MODNAME} ... matches any version
-# {MODNAME}>={VERSION} ... at least version <VERSION> is required
-# {MODNAME}={VERSION} ... exactly version <VERSION> is required
-# {MODNAME}<={VERSION} ... modules must not be newer than <VERSION>
-#
-# Examples
-# pkg_check_modules (GLIB2 glib-2.0)
-#
-# pkg_check_modules (GLIB2 glib-2.0>=2.10)
-# requires at least version 2.10 of glib2 and defines e.g.
-# GLIB2_VERSION=2.10.3
-#
-# pkg_check_modules (FOO glib-2.0>=2.10 gtk+-2.0)
-# requires both glib2 and gtk2, and defines e.g.
-# FOO_glib-2.0_VERSION=2.10.3
-# FOO_gtk+-2.0_VERSION=2.8.20
+# A `pkg-config` module for CMake.
#
-# pkg_check_modules (XRENDER REQUIRED xrender)
-# defines e.g.:
-# XRENDER_LIBRARIES=Xrender;X11
-# XRENDER_STATIC_LIBRARIES=Xrender;X11;pthread;Xau;Xdmcp
+# Finds the ``pkg-config`` executable and add the
+# :command:`pkg_check_modules` and :command:`pkg_search_module`
+# commands.
#
-# pkg_search_module (BAR libxml-2.0 libxml2 libxml>=2)
+# In order to find the ``pkg-config`` executable, it uses the
+# :variable:`PKG_CONFIG_EXECUTABLE` variable or the ``PKG_CONFIG``
+# environment variable first.
#=============================================================================
-# Copyright 2006-2009 Kitware, Inc.
-# Copyright 2006 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+# Copyright 2006-2014 Kitware, Inc.
+# Copyright 2014 Christoph Grüninger <foss@grueninger.de>
+# Copyright 2006 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
@@ -88,6 +30,10 @@
### Common stuff ####
set(PKG_CONFIG_VERSION 1)
+# find pkg-config, use PKG_CONFIG if set
+if((NOT PKG_CONFIG_EXECUTABLE) AND (NOT "$ENV{PKG_CONFIG}" STREQUAL ""))
+ set(PKG_CONFIG_EXECUTABLE "$ENV{PKG_CONFIG}" CACHE FILEPATH "pkg-config executable")
+endif()
find_program(PKG_CONFIG_EXECUTABLE NAMES pkg-config DOC "pkg-config executable")
mark_as_advanced(PKG_CONFIG_EXECUTABLE)
@@ -124,14 +70,14 @@ macro(_pkgconfig_invoke _pkglist _prefix _varname _regexp)
execute_process(
COMMAND ${PKG_CONFIG_EXECUTABLE} ${ARGN} ${_pkglist}
OUTPUT_VARIABLE _pkgconfig_invoke_result
- RESULT_VARIABLE _pkgconfig_failed)
+ RESULT_VARIABLE _pkgconfig_failed
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
if (_pkgconfig_failed)
set(_pkgconfig_${_varname} "")
_pkgconfig_unset(${_prefix}_${_varname})
else()
string(REGEX REPLACE "[\r\n]" " " _pkgconfig_invoke_result "${_pkgconfig_invoke_result}")
- string(REGEX REPLACE " +$" "" _pkgconfig_invoke_result "${_pkgconfig_invoke_result}")
if (NOT ${_regexp} STREQUAL "")
string(REGEX REPLACE "${_regexp}" " " _pkgconfig_invoke_result "${_pkgconfig_invoke_result}")
@@ -145,6 +91,26 @@ macro(_pkgconfig_invoke _pkglist _prefix _varname _regexp)
endif()
endmacro()
+#[========================================[.rst:
+.. command:: pkg_get_variable
+
+ Retrieves the value of a variable from a package::
+
+ pkg_get_variable(<RESULT> <MODULE> <VARIABLE>)
+
+ For example:
+
+ .. code-block:: cmake
+
+ pkg_get_variable(GI_GIRDIR gobject-introspection-1.0 girdir)
+#]========================================]
+function (pkg_get_variable result pkg variable)
+ _pkgconfig_invoke("${pkg}" "prefix" "result" "" "--variable=${variable}")
+ set("${result}"
+ "${prefix_result}"
+ PARENT_SCOPE)
+endfunction ()
+
# Invokes pkgconfig two times; once without '--static' and once with
# '--static'
macro(_pkgconfig_invoke_dyn _pkglist _prefix _varname cleanup_regexp)
@@ -153,9 +119,20 @@ macro(_pkgconfig_invoke_dyn _pkglist _prefix _varname cleanup_regexp)
endmacro()
# Splits given arguments into options and a package list
-macro(_pkgconfig_parse_options _result _is_req _is_silent)
+macro(_pkgconfig_parse_options _result _is_req _is_silent _no_cmake_path _no_cmake_environment_path)
set(${_is_req} 0)
set(${_is_silent} 0)
+ set(${_no_cmake_path} 0)
+ set(${_no_cmake_environment_path} 0)
+ if(DEFINED PKG_CONFIG_USE_CMAKE_PREFIX_PATH)
+ if(NOT PKG_CONFIG_USE_CMAKE_PREFIX_PATH)
+ set(${_no_cmake_path} 1)
+ set(${_no_cmake_environment_path} 1)
+ endif()
+ elseif(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 3.1)
+ set(${_no_cmake_path} 1)
+ set(${_no_cmake_environment_path} 1)
+ endif()
foreach(_pkg ${ARGN})
if (_pkg STREQUAL "REQUIRED")
@@ -164,15 +141,48 @@ macro(_pkgconfig_parse_options _result _is_req _is_silent)
if (_pkg STREQUAL "QUIET")
set(${_is_silent} 1)
endif ()
+ if (_pkg STREQUAL "NO_CMAKE_PATH")
+ set(${_no_cmake_path} 1)
+ endif()
+ if (_pkg STREQUAL "NO_CMAKE_ENVIRONMENT_PATH")
+ set(${_no_cmake_environment_path} 1)
+ endif()
endforeach()
set(${_result} ${ARGN})
list(REMOVE_ITEM ${_result} "REQUIRED")
list(REMOVE_ITEM ${_result} "QUIET")
+ list(REMOVE_ITEM ${_result} "NO_CMAKE_PATH")
+ list(REMOVE_ITEM ${_result} "NO_CMAKE_ENVIRONMENT_PATH")
endmacro()
+# Add the content of a variable or an environment variable to a list of
+# paths
+# Usage:
+# - _pkgconfig_add_extra_path(_extra_paths VAR)
+# - _pkgconfig_add_extra_path(_extra_paths ENV VAR)
+function(_pkgconfig_add_extra_path _extra_paths_var _var)
+ set(_is_env 0)
+ if(ARGC GREATER 2 AND _var STREQUAL "ENV")
+ set(_var ${ARGV2})
+ set(_is_env 1)
+ endif()
+ if(NOT _is_env)
+ if(NOT "${${_var}}" STREQUAL "")
+ list(APPEND ${_extra_paths_var} ${${_var}})
+ endif()
+ else()
+ if(NOT "$ENV{${_var}}" STREQUAL "")
+ file(TO_CMAKE_PATH "$ENV{${_var}}" _path)
+ list(APPEND ${_extra_paths_var} ${_path})
+ unset(_path)
+ endif()
+ endif()
+ set(${_extra_paths_var} ${${_extra_paths_var}} PARENT_SCOPE)
+endfunction()
+
###
-macro(_pkg_check_modules_internal _is_required _is_silent _prefix)
+macro(_pkg_check_modules_internal _is_required _is_silent _no_cmake_path _no_cmake_environment_path _prefix)
_pkgconfig_unset(${_prefix}_FOUND)
_pkgconfig_unset(${_prefix}_VERSION)
_pkgconfig_unset(${_prefix}_PREFIX)
@@ -202,24 +212,96 @@ macro(_pkg_check_modules_internal _is_required _is_silent _prefix)
# give out status message telling checked module
if (NOT ${_is_silent})
if (_pkg_check_modules_cnt EQUAL 1)
- message(STATUS "checking for module '${_pkg_check_modules_list}'")
+ message(STATUS "Checking for module '${_pkg_check_modules_list}'")
else()
- message(STATUS "checking for modules '${_pkg_check_modules_list}'")
+ message(STATUS "Checking for modules '${_pkg_check_modules_list}'")
endif()
endif()
set(_pkg_check_modules_packages)
set(_pkg_check_modules_failed)
+ set(_extra_paths)
+
+ if(NOT _no_cmake_path)
+ _pkgconfig_add_extra_path(_extra_paths CMAKE_PREFIX_PATH)
+ _pkgconfig_add_extra_path(_extra_paths CMAKE_FRAMEWORK_PATH)
+ _pkgconfig_add_extra_path(_extra_paths CMAKE_APPBUNDLE_PATH)
+ endif()
+
+ if(NOT _no_cmake_environment_path)
+ _pkgconfig_add_extra_path(_extra_paths ENV CMAKE_PREFIX_PATH)
+ _pkgconfig_add_extra_path(_extra_paths ENV CMAKE_FRAMEWORK_PATH)
+ _pkgconfig_add_extra_path(_extra_paths ENV CMAKE_APPBUNDLE_PATH)
+ endif()
+
+ if(NOT "${_extra_paths}" STREQUAL "")
+ # Save the PKG_CONFIG_PATH environment variable, and add paths
+ # from the CMAKE_PREFIX_PATH variables
+ set(_pkgconfig_path_old "$ENV{PKG_CONFIG_PATH}")
+ set(_pkgconfig_path "${_pkgconfig_path_old}")
+ if(NOT "${_pkgconfig_path}" STREQUAL "")
+ file(TO_CMAKE_PATH "${_pkgconfig_path}" _pkgconfig_path)
+ endif()
+
+ # Create a list of the possible pkgconfig subfolder (depending on
+ # the system
+ set(_lib_dirs)
+ if(NOT DEFINED CMAKE_SYSTEM_NAME
+ OR (CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU)$"
+ AND NOT CMAKE_CROSSCOMPILING))
+ if(EXISTS "/etc/debian_version") # is this a debian system ?
+ if(CMAKE_LIBRARY_ARCHITECTURE)
+ list(APPEND _lib_dirs "lib/${CMAKE_LIBRARY_ARCHITECTURE}/pkgconfig")
+ endif()
+ else()
+ # not debian, chech the FIND_LIBRARY_USE_LIB64_PATHS property
+ get_property(uselib64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
+ if(uselib64)
+ list(APPEND _lib_dirs "lib64/pkgconfig")
+ endif()
+ endif()
+ endif()
+ list(APPEND _lib_dirs "lib/pkgconfig")
+ list(APPEND _lib_dirs "share/pkgconfig")
+
+ # Check if directories exist and eventually append them to the
+ # pkgconfig path list
+ foreach(_prefix_dir ${_extra_paths})
+ foreach(_lib_dir ${_lib_dirs})
+ if(EXISTS "${_prefix_dir}/${_lib_dir}")
+ list(APPEND _pkgconfig_path "${_prefix_dir}/${_lib_dir}")
+ list(REMOVE_DUPLICATES _pkgconfig_path)
+ endif()
+ endforeach()
+ endforeach()
+
+ # Prepare and set the environment variable
+ if(NOT "${_pkgconfig_path}" STREQUAL "")
+ # remove empty values from the list
+ list(REMOVE_ITEM _pkgconfig_path "")
+ file(TO_NATIVE_PATH "${_pkgconfig_path}" _pkgconfig_path)
+ if(UNIX)
+ string(REPLACE ";" ":" _pkgconfig_path "${_pkgconfig_path}")
+ string(REPLACE "\\ " " " _pkgconfig_path "${_pkgconfig_path}")
+ endif()
+ set(ENV{PKG_CONFIG_PATH} "${_pkgconfig_path}")
+ endif()
+
+ # Unset variables
+ unset(_lib_dirs)
+ unset(_pkgconfig_path)
+ endif()
+
# iterate through module list and check whether they exist and match the required version
foreach (_pkg_check_modules_pkg ${_pkg_check_modules_list})
set(_pkg_check_modules_exist_query)
# check whether version is given
- if (_pkg_check_modules_pkg MATCHES ".*(>=|=|<=).*")
- string(REGEX REPLACE "(.*[^><])(>=|=|<=)(.*)" "\\1" _pkg_check_modules_pkg_name "${_pkg_check_modules_pkg}")
- string(REGEX REPLACE "(.*[^><])(>=|=|<=)(.*)" "\\2" _pkg_check_modules_pkg_op "${_pkg_check_modules_pkg}")
- string(REGEX REPLACE "(.*[^><])(>=|=|<=)(.*)" "\\3" _pkg_check_modules_pkg_ver "${_pkg_check_modules_pkg}")
+ if (_pkg_check_modules_pkg MATCHES "(.*[^><])(>=|=|<=)(.*)")
+ set(_pkg_check_modules_pkg_name "${CMAKE_MATCH_1}")
+ set(_pkg_check_modules_pkg_op "${CMAKE_MATCH_2}")
+ set(_pkg_check_modules_pkg_ver "${CMAKE_MATCH_3}")
else()
set(_pkg_check_modules_pkg_name "${_pkg_check_modules_pkg}")
set(_pkg_check_modules_pkg_op)
@@ -247,7 +329,7 @@ macro(_pkg_check_modules_internal _is_required _is_silent _prefix)
if (_pkg_check_modules_pkg_op)
list(APPEND _pkg_check_modules_exist_query "${_pkg_check_modules_pkg_ver}")
else()
- list(APPEND _pkg_check_modules_exist_query --exists)
+ list(APPEND _pkg_check_modules_exist_query --exists --print-errors --short-errors)
endif()
_pkgconfig_unset(${_prefix}_${_pkg_check_modules_pkg_name}_VERSION)
@@ -261,12 +343,14 @@ macro(_pkg_check_modules_internal _is_required _is_silent _prefix)
# execute the query
execute_process(
COMMAND ${PKG_CONFIG_EXECUTABLE} ${_pkg_check_modules_exist_query}
- RESULT_VARIABLE _pkgconfig_retval)
+ RESULT_VARIABLE _pkgconfig_retval
+ ERROR_VARIABLE _pkgconfig_error
+ ERROR_STRIP_TRAILING_WHITESPACE)
# evaluate result and tell failures
if (_pkgconfig_retval)
if(NOT ${_is_silent})
- message(STATUS " package '${_pkg_check_modules_pkg}' not found")
+ message(STATUS " ${_pkgconfig_error}")
endif()
set(_pkg_check_modules_failed 1)
@@ -276,7 +360,7 @@ macro(_pkg_check_modules_internal _is_required _is_silent _prefix)
if(_pkg_check_modules_failed)
# fail when requested
if (${_is_required})
- message(SEND_ERROR "A required package was not found")
+ message(FATAL_ERROR "A required package was not found")
endif ()
else()
# when we are here, we checked whether requested modules
@@ -295,12 +379,15 @@ macro(_pkg_check_modules_internal _is_required _is_silent _prefix)
endif()
_pkgconfig_invoke(${_pkg_check_modules_pkg} "${_pkg_check_prefix}" VERSION "" --modversion )
- _pkgconfig_invoke(${_pkg_check_modules_pkg} "${_pkg_check_prefix}" PREFIX "" --variable=prefix )
- _pkgconfig_invoke(${_pkg_check_modules_pkg} "${_pkg_check_prefix}" INCLUDEDIR "" --variable=includedir )
- _pkgconfig_invoke(${_pkg_check_modules_pkg} "${_pkg_check_prefix}" LIBDIR "" --variable=libdir )
+ pkg_get_variable("${_pkg_check_prefix}_PREFIX" ${_pkg_check_modules_pkg} "prefix")
+ pkg_get_variable("${_pkg_check_prefix}_INCLUDEDIR" ${_pkg_check_modules_pkg} "includedir")
+ pkg_get_variable("${_pkg_check_prefix}_LIBDIR" ${_pkg_check_modules_pkg} "libdir")
+ foreach (variable IN ITEMS PREFIX INCLUDEDIR LIBDIR)
+ _pkgconfig_set("${_pkg_check_prefix}_${variable}" "${${_pkg_check_prefix}_${variable}}")
+ endforeach ()
if (NOT ${_is_silent})
- message(STATUS " found ${_pkg_check_modules_pkg}, version ${_pkgconfig_VERSION}")
+ message(STATUS " Found ${_pkg_check_modules_pkg}, version ${_pkgconfig_VERSION}")
endif ()
endforeach()
@@ -314,6 +401,14 @@ macro(_pkg_check_modules_internal _is_required _is_silent _prefix)
_pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" CFLAGS "" --cflags )
_pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" CFLAGS_OTHER "" --cflags-only-other )
endif()
+
+ if(NOT "${_extra_paths}" STREQUAL "")
+ # Restore the environment variable
+ set(ENV{PKG_CONFIG_PATH} "${_pkgconfig_path_old}")
+ endif()
+
+ unset(_extra_paths)
+ unset(_pkgconfig_path_old)
else()
if (${_is_required})
message(SEND_ERROR "pkg-config tool not found")
@@ -325,32 +420,148 @@ endmacro()
### User visible macros start here
###
-###
+#[========================================[.rst:
+.. command:: pkg_check_modules
+
+ Checks for all the given modules. ::
+
+ pkg_check_modules(<PREFIX> [REQUIRED] [QUIET]
+ [NO_CMAKE_PATH] [NO_CMAKE_ENVIRONMENT_PATH]
+ <MODULE> [<MODULE>]*)
+
+
+ When the ``REQUIRED`` argument was set, macros will fail with an error
+ when module(s) could not be found.
+
+ When the ``QUIET`` argument is set, no status messages will be printed.
+
+ By default, if :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` is 3.1 or
+ later, or if :variable:`PKG_CONFIG_USE_CMAKE_PREFIX_PATH` is set, the
+ :variable:`CMAKE_PREFIX_PATH`, :variable:`CMAKE_FRAMEWORK_PATH`, and
+ :variable:`CMAKE_APPBUNDLE_PATH` cache and environment variables will
+ be added to ``pkg-config`` search path.
+ The ``NO_CMAKE_PATH`` and ``NO_CMAKE_ENVIRONMENT_PATH`` arguments
+ disable this behavior for the cache variables and the environment
+ variables, respectively.
+
+ It sets the following variables: ::
+
+ PKG_CONFIG_FOUND ... if pkg-config executable was found
+ PKG_CONFIG_EXECUTABLE ... pathname of the pkg-config program
+ PKG_CONFIG_VERSION_STRING ... the version of the pkg-config program found
+ (since CMake 2.8.8)
+
+ For the following variables two sets of values exist; first one is the
+ common one and has the given PREFIX. The second set contains flags
+ which are given out when ``pkg-config`` was called with the ``--static``
+ option. ::
+
+ <XPREFIX>_FOUND ... set to 1 if module(s) exist
+ <XPREFIX>_LIBRARIES ... only the libraries (w/o the '-l')
+ <XPREFIX>_LIBRARY_DIRS ... the paths of the libraries (w/o the '-L')
+ <XPREFIX>_LDFLAGS ... all required linker flags
+ <XPREFIX>_LDFLAGS_OTHER ... all other linker flags
+ <XPREFIX>_INCLUDE_DIRS ... the '-I' preprocessor flags (w/o the '-I')
+ <XPREFIX>_CFLAGS ... all required cflags
+ <XPREFIX>_CFLAGS_OTHER ... the other compiler flags
+
+ ::
+
+ <XPREFIX> = <PREFIX> for common case
+ <XPREFIX> = <PREFIX>_STATIC for static linking
+
+ There are some special variables whose prefix depends on the count of
+ given modules. When there is only one module, <PREFIX> stays
+ unchanged. When there are multiple modules, the prefix will be
+ changed to <PREFIX>_<MODNAME>: ::
+
+ <XPREFIX>_VERSION ... version of the module
+ <XPREFIX>_PREFIX ... prefix-directory of the module
+ <XPREFIX>_INCLUDEDIR ... include-dir of the module
+ <XPREFIX>_LIBDIR ... lib-dir of the module
+
+ ::
+
+ <XPREFIX> = <PREFIX> when |MODULES| == 1, else
+ <XPREFIX> = <PREFIX>_<MODNAME>
+
+ A <MODULE> parameter can have the following formats: ::
+
+ {MODNAME} ... matches any version
+ {MODNAME}>={VERSION} ... at least version <VERSION> is required
+ {MODNAME}={VERSION} ... exactly version <VERSION> is required
+ {MODNAME}<={VERSION} ... modules must not be newer than <VERSION>
+
+ Examples
+
+ .. code-block:: cmake
+
+ pkg_check_modules (GLIB2 glib-2.0)
+
+ .. code-block:: cmake
+
+ pkg_check_modules (GLIB2 glib-2.0>=2.10)
+
+ Requires at least version 2.10 of glib2 and defines e.g.
+ ``GLIB2_VERSION=2.10.3``
+
+ .. code-block:: cmake
+
+ pkg_check_modules (FOO glib-2.0>=2.10 gtk+-2.0)
+
+ Requires both glib2 and gtk2, and defines e.g.
+ ``FOO_glib-2.0_VERSION=2.10.3`` and ``FOO_gtk+-2.0_VERSION=2.8.20``
+
+ .. code-block:: cmake
+
+ pkg_check_modules (XRENDER REQUIRED xrender)
+
+ Defines for example::
+
+ XRENDER_LIBRARIES=Xrender;X11``
+ XRENDER_STATIC_LIBRARIES=Xrender;X11;pthread;Xau;Xdmcp
+#]========================================]
macro(pkg_check_modules _prefix _module0)
# check cached value
if (NOT DEFINED __pkg_config_checked_${_prefix} OR __pkg_config_checked_${_prefix} LESS ${PKG_CONFIG_VERSION} OR NOT ${_prefix}_FOUND)
- _pkgconfig_parse_options (_pkg_modules _pkg_is_required _pkg_is_silent "${_module0}" ${ARGN})
- _pkg_check_modules_internal("${_pkg_is_required}" "${_pkg_is_silent}" "${_prefix}" ${_pkg_modules})
+ _pkgconfig_parse_options (_pkg_modules _pkg_is_required _pkg_is_silent _no_cmake_path _no_cmake_environment_path "${_module0}" ${ARGN})
+ _pkg_check_modules_internal("${_pkg_is_required}" "${_pkg_is_silent}" ${_no_cmake_path} ${_no_cmake_environment_path} "${_prefix}" ${_pkg_modules})
_pkgconfig_set(__pkg_config_checked_${_prefix} ${PKG_CONFIG_VERSION})
endif()
endmacro()
-###
+
+#[========================================[.rst:
+.. command:: pkg_search_module
+
+ Same as :command:`pkg_check_modules`, but instead it checks for given
+ modules and uses the first working one. ::
+
+ pkg_search_module(<PREFIX> [REQUIRED] [QUIET]
+ [NO_CMAKE_PATH] [NO_CMAKE_ENVIRONMENT_PATH]
+ <MODULE> [<MODULE>]*)
+
+ Examples
+
+ .. code-block:: cmake
+
+ pkg_search_module (BAR libxml-2.0 libxml2 libxml>=2)
+#]========================================]
macro(pkg_search_module _prefix _module0)
# check cached value
if (NOT DEFINED __pkg_config_checked_${_prefix} OR __pkg_config_checked_${_prefix} LESS ${PKG_CONFIG_VERSION} OR NOT ${_prefix}_FOUND)
set(_pkg_modules_found 0)
- _pkgconfig_parse_options(_pkg_modules_alt _pkg_is_required _pkg_is_silent "${_module0}" ${ARGN})
+ _pkgconfig_parse_options(_pkg_modules_alt _pkg_is_required _pkg_is_silent _no_cmake_path _no_cmake_environment_path "${_module0}" ${ARGN})
if (NOT ${_pkg_is_silent})
- message(STATUS "checking for one of the modules '${_pkg_modules_alt}'")
+ message(STATUS "Checking for one of the modules '${_pkg_modules_alt}'")
endif ()
# iterate through all modules and stop at the first working one.
foreach(_pkg_alt ${_pkg_modules_alt})
if(NOT _pkg_modules_found)
- _pkg_check_modules_internal(0 1 "${_prefix}" "${_pkg_alt}")
+ _pkg_check_modules_internal(0 1 ${_no_cmake_path} ${_no_cmake_environment_path} "${_prefix}" "${_pkg_alt}")
endif()
if (${_prefix}_FOUND)
@@ -368,6 +579,26 @@ macro(pkg_search_module _prefix _module0)
endif()
endmacro()
+
+#[========================================[.rst:
+.. variable:: PKG_CONFIG_EXECUTABLE
+
+ Path to the pkg-config executable.
+
+
+.. variable:: PKG_CONFIG_USE_CMAKE_PREFIX_PATH
+
+ Whether :command:`pkg_check_modules` and :command:`pkg_search_module`
+ should add the paths in :variable:`CMAKE_PREFIX_PATH`,
+ :variable:`CMAKE_FRAMEWORK_PATH`, and :variable:`CMAKE_APPBUNDLE_PATH`
+ cache and environment variables to ``pkg-config`` search path.
+
+ If this variable is not set, this behavior is enabled by default if
+ :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` is 3.1 or later, disabled
+ otherwise.
+#]========================================]
+
+
### Local Variables:
### mode: cmake
### End:
diff --git a/Modules/FindPostgreSQL.cmake b/Modules/FindPostgreSQL.cmake
index e3c898b98..d05d3da7c 100644
--- a/Modules/FindPostgreSQL.cmake
+++ b/Modules/FindPostgreSQL.cmake
@@ -1,11 +1,17 @@
-# - Find the PostgreSQL installation.
-# In Windows, we make the assumption that, if the PostgreSQL files are installed, the default directory
-# will be C:\Program Files\PostgreSQL.
+#.rst:
+# FindPostgreSQL
+# --------------
+#
+# Find the PostgreSQL installation.
#
# This module defines
-# PostgreSQL_LIBRARIES - the PostgreSQL libraries needed for linking
-# PostgreSQL_INCLUDE_DIRS - the directories of the PostgreSQL headers
-# PostgreSQL_VERSION_STRING - the version of PostgreSQL found (since CMake 2.8.8)
+#
+# ::
+#
+# PostgreSQL_LIBRARIES - the PostgreSQL libraries needed for linking
+# PostgreSQL_INCLUDE_DIRS - the directories of the PostgreSQL headers
+# PostgreSQL_LIBRARY_DIRS - the link directories for PostgreSQL libraries
+# PostgreSQL_VERSION_STRING - the version of PostgreSQL found (since CMake 2.8.8)
#=============================================================================
# Copyright 2004-2009 Kitware, Inc.
@@ -31,7 +37,7 @@
# In Windows the default installation of PostgreSQL uses that as part of the path.
# E.g C:\Program Files\PostgreSQL\8.4.
# Currently, the following version numbers are known to this module:
-# "9.1" "9.0" "8.4" "8.3" "8.2" "8.1" "8.0"
+# "9.4" "9.3" "9.2" "9.1" "9.0" "8.4" "8.3" "8.2" "8.1" "8.0"
#
# To use this variable just do something like this:
# set(PostgreSQL_ADDITIONAL_VERSIONS "9.2" "8.4.4")
@@ -75,19 +81,27 @@ set(PostgreSQL_ROOT_DIR_MESSAGE "Set the PostgreSQL_ROOT system variable to wher
set(PostgreSQL_KNOWN_VERSIONS ${PostgreSQL_ADDITIONAL_VERSIONS}
- "9.1" "9.0" "8.4" "8.3" "8.2" "8.1" "8.0")
+ "9.5" "9.4" "9.3" "9.2" "9.1" "9.0" "8.4" "8.3" "8.2" "8.1" "8.0")
# Define additional search paths for root directories.
-if ( WIN32 )
- foreach (suffix ${PostgreSQL_KNOWN_VERSIONS} )
- set(PostgreSQL_ADDITIONAL_SEARCH_PATHS ${PostgreSQL_ADDITIONAL_SEARCH_PATHS} "C:/Program Files/PostgreSQL/${suffix}" )
- endforeach()
-endif()
set( PostgreSQL_ROOT_DIRECTORIES
ENV PostgreSQL_ROOT
${PostgreSQL_ROOT}
- ${PostgreSQL_ADDITIONAL_SEARCH_PATHS}
)
+foreach(suffix ${PostgreSQL_KNOWN_VERSIONS})
+ if(WIN32)
+ list(APPEND PostgreSQL_LIBRARY_ADDITIONAL_SEARCH_SUFFIXES
+ "PostgreSQL/${suffix}/lib")
+ list(APPEND PostgreSQL_INCLUDE_ADDITIONAL_SEARCH_SUFFIXES
+ "PostgreSQL/${suffix}/include")
+ list(APPEND PostgreSQL_TYPE_ADDITIONAL_SEARCH_SUFFIXES
+ "PostgreSQL/${suffix}/include/server")
+ endif()
+ if(UNIX)
+ list(APPEND PostgreSQL_TYPE_ADDITIONAL_SEARCH_SUFFIXES
+ "postgresql/${suffix}/server")
+ endif()
+endforeach()
#
# Look for an installation.
@@ -101,6 +115,7 @@ find_path(PostgreSQL_INCLUDE_DIR
pgsql
postgresql
include
+ ${PostgreSQL_INCLUDE_ADDITIONAL_SEARCH_SUFFIXES}
# Help the user find it if we cannot.
DOC "The ${PostgreSQL_INCLUDE_DIR_MESSAGE}"
)
@@ -115,6 +130,7 @@ find_path(PostgreSQL_TYPE_INCLUDE_DIR
pgsql/server
postgresql/server
include/server
+ ${PostgreSQL_TYPE_ADDITIONAL_SEARCH_SUFFIXES}
# Help the user find it if we cannot.
DOC "The ${PostgreSQL_INCLUDE_DIR_MESSAGE}"
)
@@ -125,24 +141,37 @@ set (PostgreSQL_LIBRARY_TO_FIND pq)
set (PostgreSQL_LIB_PREFIX "")
if ( WIN32 )
set (PostgreSQL_LIB_PREFIX ${PostgreSQL_LIB_PREFIX} "lib")
- set ( PostgreSQL_LIBRARY_TO_FIND ${PostgreSQL_LIB_PREFIX}${PostgreSQL_LIBRARY_TO_FIND})
+ set (PostgreSQL_LIBRARY_TO_FIND ${PostgreSQL_LIB_PREFIX}${PostgreSQL_LIBRARY_TO_FIND})
endif()
-find_library( PostgreSQL_LIBRARY
+find_library(PostgreSQL_LIBRARY
NAMES ${PostgreSQL_LIBRARY_TO_FIND}
PATHS
${PostgreSQL_ROOT_DIRECTORIES}
PATH_SUFFIXES
lib
+ ${PostgreSQL_LIBRARY_ADDITIONAL_SEARCH_SUFFIXES}
+ # Help the user find it if we cannot.
+ DOC "The ${PostgreSQL_LIBRARY_DIR_MESSAGE}"
)
get_filename_component(PostgreSQL_LIBRARY_DIR ${PostgreSQL_LIBRARY} PATH)
-if (PostgreSQL_INCLUDE_DIR AND EXISTS "${PostgreSQL_INCLUDE_DIR}/pg_config.h")
- file(STRINGS "${PostgreSQL_INCLUDE_DIR}/pg_config.h" pgsql_version_str
- REGEX "^#define[\t ]+PG_VERSION[\t ]+\".*\"")
-
- string(REGEX REPLACE "^#define[\t ]+PG_VERSION[\t ]+\"([^\"]*)\".*" "\\1"
- PostgreSQL_VERSION_STRING "${pgsql_version_str}")
+if (PostgreSQL_INCLUDE_DIR)
+ # Some platforms include multiple pg_config.hs for multi-lib configurations
+ # This is a temporary workaround. A better solution would be to compile
+ # a dummy c file and extract the value of the symbol.
+ file(GLOB _PG_CONFIG_HEADERS "${PostgreSQL_INCLUDE_DIR}/pg_config*.h")
+ foreach(_PG_CONFIG_HEADER ${_PG_CONFIG_HEADERS})
+ if(EXISTS "${_PG_CONFIG_HEADER}")
+ file(STRINGS "${_PG_CONFIG_HEADER}" pgsql_version_str
+ REGEX "^#define[\t ]+PG_VERSION[\t ]+\".*\"")
+ if(pgsql_version_str)
+ string(REGEX REPLACE "^#define[\t ]+PG_VERSION[\t ]+\"([^\"]*)\".*"
+ "\\1" PostgreSQL_VERSION_STRING "${pgsql_version_str}")
+ break()
+ endif()
+ endif()
+ endforeach()
unset(pgsql_version_str)
endif()
@@ -151,18 +180,13 @@ include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
find_package_handle_standard_args(PostgreSQL
REQUIRED_VARS PostgreSQL_LIBRARY PostgreSQL_INCLUDE_DIR PostgreSQL_TYPE_INCLUDE_DIR
VERSION_VAR PostgreSQL_VERSION_STRING)
-set( PostgreSQL_FOUND ${POSTGRESQL_FOUND})
+set(PostgreSQL_FOUND ${POSTGRESQL_FOUND})
# Now try to get the include and library path.
if(PostgreSQL_FOUND)
-
set(PostgreSQL_INCLUDE_DIRS ${PostgreSQL_INCLUDE_DIR} ${PostgreSQL_TYPE_INCLUDE_DIR} )
set(PostgreSQL_LIBRARY_DIRS ${PostgreSQL_LIBRARY_DIR} )
set(PostgreSQL_LIBRARIES ${PostgreSQL_LIBRARY_TO_FIND})
-
- #message("Final PostgreSQL include dir: ${PostgreSQL_INCLUDE_DIRS}")
- #message("Final PostgreSQL library dir: ${PostgreSQL_LIBRARY_DIRS}")
- #message("Final PostgreSQL libraries: ${PostgreSQL_LIBRARIES}")
endif()
mark_as_advanced(PostgreSQL_INCLUDE_DIR PostgreSQL_TYPE_INCLUDE_DIR PostgreSQL_LIBRARY )
diff --git a/Modules/FindProducer.cmake b/Modules/FindProducer.cmake
index 30990629b..aef84eac7 100644
--- a/Modules/FindProducer.cmake
+++ b/Modules/FindProducer.cmake
@@ -1,27 +1,30 @@
-# Though Producer isn't directly part of OpenSceneGraph, its primary user
-# is OSG so I consider this part of the Findosg* suite used to find
-# OpenSceneGraph components. You'll notice that I accept OSGDIR as an
+#.rst:
+# FindProducer
+# ------------
+#
+#
+#
+# Though Producer isn't directly part of OpenSceneGraph, its primary
+# user is OSG so I consider this part of the Findosg* suite used to find
+# OpenSceneGraph components. You'll notice that I accept OSGDIR as an
# environment path.
#
-# Each component is separate and you must opt in to each module. You must
-# also opt into OpenGL (and OpenThreads?) as these
-# modules won't do it for you. This is to allow you control over your own
-# system piece by piece in case you need to opt out of certain components
-# or change the Find behavior for a particular module (perhaps because the
-# default FindOpenGL.cmake module doesn't work with your system as an
-# example).
+# Each component is separate and you must opt in to each module. You
+# must also opt into OpenGL (and OpenThreads?) as these modules won't do
+# it for you. This is to allow you control over your own system piece
+# by piece in case you need to opt out of certain components or change
+# the Find behavior for a particular module (perhaps because the default
+# FindOpenGL.cmake module doesn't work with your system as an example).
# If you want to use a more convenient module that includes everything,
-# use the FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+# use the FindOpenSceneGraph.cmake instead of the Findosg*.cmake
+# modules.
#
-# Locate Producer
-# This module defines
-# PRODUCER_LIBRARY
-# PRODUCER_FOUND, if false, do not try to link to Producer
-# PRODUCER_INCLUDE_DIR, where to find the headers
+# Locate Producer This module defines PRODUCER_LIBRARY PRODUCER_FOUND,
+# if false, do not try to link to Producer PRODUCER_INCLUDE_DIR, where
+# to find the headers
#
-# $PRODUCER_DIR is an environment variable that would
-# correspond to the ./configure --prefix=$PRODUCER_DIR
-# used in building osg.
+# $PRODUCER_DIR is an environment variable that would correspond to the
+# ./configure --prefix=$PRODUCER_DIR used in building osg.
#
# Created by Eric Wing.
diff --git a/Modules/FindProtobuf.cmake b/Modules/FindProtobuf.cmake
index 2972198b3..2f13b09a8 100644
--- a/Modules/FindProtobuf.cmake
+++ b/Modules/FindProtobuf.cmake
@@ -1,63 +1,94 @@
+#.rst:
+# FindProtobuf
+# ------------
+#
# Locate and configure the Google Protocol Buffers library.
#
# The following variables can be set and are optional:
#
-# PROTOBUF_SRC_ROOT_FOLDER - When compiling with MSVC, if this cache variable is set
-# the protobuf-default VS project build locations
-# (vsprojects/Debug & vsprojects/Release) will be searched
-# for libraries and binaries.
-#
-# PROTOBUF_IMPORT_DIRS - List of additional directories to be searched for
-# imported .proto files. (New in CMake 2.8.8)
+# ``PROTOBUF_SRC_ROOT_FOLDER``
+# When compiling with MSVC, if this cache variable is set
+# the protobuf-default VS project build locations
+# (vsprojects/Debug and vsprojects/Release
+# or vsprojects/x64/Debug and vsprojects/x64/Release)
+# will be searched for libraries and binaries.
+# ``PROTOBUF_IMPORT_DIRS``
+# List of additional directories to be searched for
+# imported .proto files.
#
# Defines the following variables:
#
-# PROTOBUF_FOUND - Found the Google Protocol Buffers library (libprotobuf & header files)
-# PROTOBUF_INCLUDE_DIRS - Include directories for Google Protocol Buffers
-# PROTOBUF_LIBRARIES - The protobuf libraries
-# [New in CMake 2.8.5]
-# PROTOBUF_PROTOC_LIBRARIES - The protoc libraries
-# PROTOBUF_LITE_LIBRARIES - The protobuf-lite libraries
+# ``PROTOBUF_FOUND``
+# Found the Google Protocol Buffers library
+# (libprotobuf & header files)
+# ``PROTOBUF_INCLUDE_DIRS``
+# Include directories for Google Protocol Buffers
+# ``PROTOBUF_LIBRARIES``
+# The protobuf libraries
+# ``PROTOBUF_PROTOC_LIBRARIES``
+# The protoc libraries
+# ``PROTOBUF_LITE_LIBRARIES``
+# The protobuf-lite libraries
#
# The following cache variables are also available to set or use:
-# PROTOBUF_LIBRARY - The protobuf library
-# PROTOBUF_PROTOC_LIBRARY - The protoc library
-# PROTOBUF_INCLUDE_DIR - The include directory for protocol buffers
-# PROTOBUF_PROTOC_EXECUTABLE - The protoc compiler
-# [New in CMake 2.8.5]
-# PROTOBUF_LIBRARY_DEBUG - The protobuf library (debug)
-# PROTOBUF_PROTOC_LIBRARY_DEBUG - The protoc library (debug)
-# PROTOBUF_LITE_LIBRARY - The protobuf lite library
-# PROTOBUF_LITE_LIBRARY_DEBUG - The protobuf lite library (debug)
-#
-# ====================================================================
-# Example:
+#
+# ``PROTOBUF_LIBRARY``
+# The protobuf library
+# ``PROTOBUF_PROTOC_LIBRARY``
+# The protoc library
+# ``PROTOBUF_INCLUDE_DIR``
+# The include directory for protocol buffers
+# ``PROTOBUF_PROTOC_EXECUTABLE``
+# The protoc compiler
+# ``PROTOBUF_LIBRARY_DEBUG``
+# The protobuf library (debug)
+# ``PROTOBUF_PROTOC_LIBRARY_DEBUG``
+# The protoc library (debug)
+# ``PROTOBUF_LITE_LIBRARY``
+# The protobuf lite library
+# ``PROTOBUF_LITE_LIBRARY_DEBUG``
+# The protobuf lite library (debug)
+#
+# Example:
+#
+# .. code-block:: cmake
#
# find_package(Protobuf REQUIRED)
# include_directories(${PROTOBUF_INCLUDE_DIRS})
-#
# include_directories(${CMAKE_CURRENT_BINARY_DIR})
-# PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS foo.proto)
+# protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS foo.proto)
+# protobuf_generate_python(PROTO_PY foo.proto)
# add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS})
# target_link_libraries(bar ${PROTOBUF_LIBRARIES})
#
-# NOTE: You may need to link against pthreads, depending
-# on the platform.
+# .. note::
+# The ``protobuf_generate_cpp`` and ``protobuf_generate_python``
+# functions and :command:`add_executable` or :command:`add_library`
+# calls only work properly within the same directory.
#
-# NOTE: The PROTOBUF_GENERATE_CPP macro & add_executable() or add_library()
-# calls only work properly within the same directory.
+# .. command:: protobuf_generate_cpp
#
-# ====================================================================
+# Add custom commands to process ``.proto`` files to C++::
#
-# PROTOBUF_GENERATE_CPP (public function)
-# SRCS = Variable to define with autogenerated
-# source files
-# HDRS = Variable to define with autogenerated
-# header files
-# ARGN = proto files
+# protobuf_generate_cpp (<SRCS> <HDRS> [<ARGN>...])
#
-# ====================================================================
-
+# ``SRCS``
+# Variable to define with autogenerated source files
+# ``HDRS``
+# Variable to define with autogenerated header files
+# ``ARGN``
+# ``.proto`` files
+#
+# .. command:: protobuf_generate_python
+#
+# Add custom commands to process ``.proto`` files to Python::
+#
+# protobuf_generate_python (<PY> [<ARGN>...])
+#
+# ``PY``
+# Variable to define with autogenerated Python files
+# ``ARGN``
+# ``.proto`` filess
#=============================================================================
# Copyright 2009 Kitware, Inc.
@@ -118,7 +149,7 @@ function(PROTOBUF_GENERATE_CPP SRCS HDRS)
"${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h"
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
ARGS --cpp_out ${CMAKE_CURRENT_BINARY_DIR} ${_protobuf_include_path} ${ABS_FIL}
- DEPENDS ${ABS_FIL}
+ DEPENDS ${ABS_FIL} ${PROTOBUF_PROTOC_EXECUTABLE}
COMMENT "Running C++ protocol buffer compiler on ${FIL}"
VERBATIM )
endforeach()
@@ -128,18 +159,69 @@ function(PROTOBUF_GENERATE_CPP SRCS HDRS)
set(${HDRS} ${${HDRS}} PARENT_SCOPE)
endfunction()
+function(PROTOBUF_GENERATE_PYTHON SRCS)
+ if(NOT ARGN)
+ message(SEND_ERROR "Error: PROTOBUF_GENERATE_PYTHON() called without any proto files")
+ return()
+ endif()
+
+ if(PROTOBUF_GENERATE_CPP_APPEND_PATH)
+ # Create an include path for each file specified
+ foreach(FIL ${ARGN})
+ get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
+ get_filename_component(ABS_PATH ${ABS_FIL} PATH)
+ list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
+ if(${_contains_already} EQUAL -1)
+ list(APPEND _protobuf_include_path -I ${ABS_PATH})
+ endif()
+ endforeach()
+ else()
+ set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
+ endif()
+
+ if(DEFINED PROTOBUF_IMPORT_DIRS)
+ foreach(DIR ${PROTOBUF_IMPORT_DIRS})
+ get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
+ list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
+ if(${_contains_already} EQUAL -1)
+ list(APPEND _protobuf_include_path -I ${ABS_PATH})
+ endif()
+ endforeach()
+ endif()
+
+ set(${SRCS})
+ foreach(FIL ${ARGN})
+ get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
+ get_filename_component(FIL_WE ${FIL} NAME_WE)
+
+ list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}_pb2.py")
+ add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}_pb2.py"
+ COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} --python_out ${CMAKE_CURRENT_BINARY_DIR} ${_protobuf_include_path} ${ABS_FIL}
+ DEPENDS ${ABS_FIL} ${PROTOBUF_PROTOC_EXECUTABLE}
+ COMMENT "Running Python protocol buffer compiler on ${FIL}"
+ VERBATIM )
+ endforeach()
+
+ set(${SRCS} ${${SRCS}} PARENT_SCOPE)
+endfunction()
+
+if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(_PROTOBUF_ARCH_DIR x64/)
+endif()
+
# Internal function: search for normal library as well as a debug one
# if the debug one is specified also include debug/optimized keywords
# in *_LIBRARIES variable
function(_protobuf_find_libraries name filename)
find_library(${name}_LIBRARY
NAMES ${filename}
- PATHS ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/Release)
+ PATHS ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Release)
mark_as_advanced(${name}_LIBRARY)
find_library(${name}_LIBRARY_DEBUG
NAMES ${filename}
- PATHS ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/Debug)
+ PATHS ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Debug)
mark_as_advanced(${name}_LIBRARY_DEBUG)
if(NOT ${name}_LIBRARY_DEBUG)
@@ -216,14 +298,14 @@ find_program(PROTOBUF_PROTOC_EXECUTABLE
NAMES protoc
DOC "The Google Protocol Buffers Compiler"
PATHS
- ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/Release
- ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/Debug
+ ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Release
+ ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Debug
)
mark_as_advanced(PROTOBUF_PROTOC_EXECUTABLE)
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(PROTOBUF DEFAULT_MSG
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Protobuf DEFAULT_MSG
PROTOBUF_LIBRARY PROTOBUF_INCLUDE_DIR)
if(PROTOBUF_FOUND)
diff --git a/Modules/FindPythonInterp.cmake b/Modules/FindPythonInterp.cmake
index 7fb65b869..e194185f2 100644
--- a/Modules/FindPythonInterp.cmake
+++ b/Modules/FindPythonInterp.cmake
@@ -1,18 +1,37 @@
-# - Find python interpreter
-# This module finds if Python interpreter is installed and determines where the
-# executables are. This code sets the following variables:
+#.rst:
+# FindPythonInterp
+# ----------------
#
-# PYTHONINTERP_FOUND - Was the Python executable found
-# PYTHON_EXECUTABLE - path to the Python interpreter
+# Find python interpreter
#
-# PYTHON_VERSION_STRING - Python version found e.g. 2.5.2
-# PYTHON_VERSION_MAJOR - Python major version found e.g. 2
-# PYTHON_VERSION_MINOR - Python minor version found e.g. 5
-# PYTHON_VERSION_PATCH - Python patch version found e.g. 2
+# This module finds if Python interpreter is installed and determines
+# where the executables are. This code sets the following variables:
#
-# The Python_ADDITIONAL_VERSIONS variable can be used to specify a list of
-# version numbers that should be taken into account when searching for Python.
-# You need to set this variable before calling find_package(PythonInterp).
+# ::
+#
+# PYTHONINTERP_FOUND - Was the Python executable found
+# PYTHON_EXECUTABLE - path to the Python interpreter
+#
+#
+#
+# ::
+#
+# PYTHON_VERSION_STRING - Python version found e.g. 2.5.2
+# PYTHON_VERSION_MAJOR - Python major version found e.g. 2
+# PYTHON_VERSION_MINOR - Python minor version found e.g. 5
+# PYTHON_VERSION_PATCH - Python patch version found e.g. 2
+#
+#
+#
+# The Python_ADDITIONAL_VERSIONS variable can be used to specify a list
+# of version numbers that should be taken into account when searching
+# for Python. You need to set this variable before calling
+# find_package(PythonInterp).
+#
+# If calling both ``find_package(PythonInterp)`` and
+# ``find_package(PythonLibs)``, call ``find_package(PythonInterp)`` first to
+# get the currently active Python version by default with a consistent version
+# of PYTHON_LIBRARIES.
#=============================================================================
# Copyright 2005-2010 Kitware, Inc.
@@ -33,42 +52,47 @@ unset(_Python_NAMES)
set(_PYTHON1_VERSIONS 1.6 1.5)
set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
-set(_PYTHON3_VERSIONS 3.3 3.2 3.1 3.0)
+set(_PYTHON3_VERSIONS 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
if(PythonInterp_FIND_VERSION)
- if(PythonInterp_FIND_VERSION MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+.*)?$")
- string(REGEX REPLACE "^([0-9]+\\.[0-9]+).*" "\\1" _PYTHON_FIND_MAJ_MIN "${PythonInterp_FIND_VERSION}")
- string(REGEX REPLACE "^([0-9]+).*" "\\1" _PYTHON_FIND_MAJ "${_PYTHON_FIND_MAJ_MIN}")
- list(APPEND _Python_NAMES python${_PYTHON_FIND_MAJ_MIN} python${_PYTHON_FIND_MAJ})
+ if(PythonInterp_FIND_VERSION_COUNT GREATER 1)
+ set(_PYTHON_FIND_MAJ_MIN "${PythonInterp_FIND_VERSION_MAJOR}.${PythonInterp_FIND_VERSION_MINOR}")
+ list(APPEND _Python_NAMES
+ python${_PYTHON_FIND_MAJ_MIN}
+ python${PythonInterp_FIND_VERSION_MAJOR})
unset(_PYTHON_FIND_OTHER_VERSIONS)
if(NOT PythonInterp_FIND_VERSION_EXACT)
- foreach(_PYTHON_V ${_PYTHON${_PYTHON_FIND_MAJ}_VERSIONS})
+ foreach(_PYTHON_V ${_PYTHON${PythonInterp_FIND_VERSION_MAJOR}_VERSIONS})
if(NOT _PYTHON_V VERSION_LESS _PYTHON_FIND_MAJ_MIN)
list(APPEND _PYTHON_FIND_OTHER_VERSIONS ${_PYTHON_V})
endif()
endforeach()
endif()
unset(_PYTHON_FIND_MAJ_MIN)
- unset(_PYTHON_FIND_MAJ)
else()
- list(APPEND _Python_NAMES python${PythonInterp_FIND_VERSION})
- set(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON${PythonInterp_FIND_VERSION}_VERSIONS})
+ list(APPEND _Python_NAMES python${PythonInterp_FIND_VERSION_MAJOR})
+ set(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON${PythonInterp_FIND_VERSION_MAJOR}_VERSIONS})
endif()
else()
set(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON3_VERSIONS} ${_PYTHON2_VERSIONS} ${_PYTHON1_VERSIONS})
endif()
-
-list(APPEND _Python_NAMES python)
-
-# Search for the current active python version first
find_program(PYTHON_EXECUTABLE NAMES ${_Python_NAMES})
# Set up the versions we know about, in the order we will search. Always add
# the user supplied additional versions to the front.
-set(_Python_VERSIONS
- ${Python_ADDITIONAL_VERSIONS}
- ${_PYTHON_FIND_OTHER_VERSIONS}
- )
+set(_Python_VERSIONS ${Python_ADDITIONAL_VERSIONS})
+# If FindPythonInterp has already found the major and minor version,
+# insert that version next to get consistent versions of the interpreter and
+# library.
+if(DEFINED PYTHONLIBS_VERSION_STRING)
+ string(REPLACE "." ";" _PYTHONLIBS_VERSION "${PYTHONLIBS_VERSION_STRING}")
+ list(GET _PYTHONLIBS_VERSION 0 _PYTHONLIBS_VERSION_MAJOR)
+ list(GET _PYTHONLIBS_VERSION 1 _PYTHONLIBS_VERSION_MINOR)
+ list(APPEND _Python_VERSIONS ${_PYTHONLIBS_VERSION_MAJOR}.${_PYTHONLIBS_VERSION_MINOR})
+endif()
+# Search for the current active python version first
+list(APPEND _Python_VERSIONS ";")
+list(APPEND _Python_VERSIONS ${_PYTHON_FIND_OTHER_VERSIONS})
unset(_PYTHON_FIND_OTHER_VERSIONS)
unset(_PYTHON1_VERSIONS)
@@ -77,7 +101,7 @@ unset(_PYTHON3_VERSIONS)
# Search for newest python version if python executable isn't found
if(NOT PYTHON_EXECUTABLE)
- foreach(_CURRENT_VERSION ${_Python_VERSIONS})
+ foreach(_CURRENT_VERSION IN LISTS _Python_VERSIONS)
set(_Python_NAMES python${_CURRENT_VERSION})
if(WIN32)
list(APPEND _Python_NAMES python)
@@ -115,8 +139,8 @@ if(PYTHON_EXECUTABLE)
string(REGEX REPLACE " .*" "" PYTHON_VERSION_STRING "${_VERSION}")
string(REGEX REPLACE "^([0-9]+)\\.[0-9]+.*" "\\1" PYTHON_VERSION_MAJOR "${PYTHON_VERSION_STRING}")
string(REGEX REPLACE "^[0-9]+\\.([0-9])+.*" "\\1" PYTHON_VERSION_MINOR "${PYTHON_VERSION_STRING}")
- if(PYTHON_VERSION_STRING MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+.*")
- string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" PYTHON_VERSION_PATCH "${PYTHON_VERSION_STRING}")
+ if(PYTHON_VERSION_STRING MATCHES "^[0-9]+\\.[0-9]+\\.([0-9]+)")
+ set(PYTHON_VERSION_PATCH "${CMAKE_MATCH_1}")
else()
set(PYTHON_VERSION_PATCH "0")
endif()
@@ -125,8 +149,8 @@ if(PYTHON_EXECUTABLE)
# this is older.
set(PYTHON_VERSION_STRING "1.4")
set(PYTHON_VERSION_MAJOR "1")
- set(PYTHON_VERSION_MAJOR "4")
- set(PYTHON_VERSION_MAJOR "0")
+ set(PYTHON_VERSION_MINOR "4")
+ set(PYTHON_VERSION_PATCH "0")
endif()
endif()
unset(_PYTHON_VERSION_RESULT)
diff --git a/Modules/FindPythonLibs.cmake b/Modules/FindPythonLibs.cmake
index bffa9fb4f..ab92f8683 100644
--- a/Modules/FindPythonLibs.cmake
+++ b/Modules/FindPythonLibs.cmake
@@ -1,23 +1,41 @@
-# - Find python libraries
+#.rst:
+# FindPythonLibs
+# --------------
+#
+# Find python libraries
+#
# This module finds if Python is installed and determines where the
-# include files and libraries are. It also determines what the name of
-# the library is. This code sets the following variables:
+# include files and libraries are. It also determines what the name of
+# the library is. This code sets the following variables:
+#
+# ::
+#
+# PYTHONLIBS_FOUND - have the Python libs been found
+# PYTHON_LIBRARIES - path to the python library
+# PYTHON_INCLUDE_PATH - path to where Python.h is found (deprecated)
+# PYTHON_INCLUDE_DIRS - path to where Python.h is found
+# PYTHON_DEBUG_LIBRARIES - path to the debug library (deprecated)
+# PYTHONLIBS_VERSION_STRING - version of the Python libs found (since CMake 2.8.8)
+#
+#
#
-# PYTHONLIBS_FOUND - have the Python libs been found
-# PYTHON_LIBRARIES - path to the python library
-# PYTHON_INCLUDE_PATH - path to where Python.h is found (deprecated)
-# PYTHON_INCLUDE_DIRS - path to where Python.h is found
-# PYTHON_DEBUG_LIBRARIES - path to the debug library (deprecated)
-# PYTHONLIBS_VERSION_STRING - version of the Python libs found (since CMake 2.8.8)
+# The Python_ADDITIONAL_VERSIONS variable can be used to specify a list
+# of version numbers that should be taken into account when searching
+# for Python. You need to set this variable before calling
+# find_package(PythonLibs).
#
-# The Python_ADDITIONAL_VERSIONS variable can be used to specify a list of
-# version numbers that should be taken into account when searching for Python.
-# You need to set this variable before calling find_package(PythonLibs).
+# If you'd like to specify the installation of Python to use, you should
+# modify the following cache variables:
#
-# If you'd like to specify the installation of Python to use, you should modify
-# the following cache variables:
-# PYTHON_LIBRARY - path to the python library
-# PYTHON_INCLUDE_DIR - path to where Python.h is found
+# ::
+#
+# PYTHON_LIBRARY - path to the python library
+# PYTHON_INCLUDE_DIR - path to where Python.h is found
+#
+# If calling both ``find_package(PythonInterp)`` and
+# ``find_package(PythonLibs)``, call ``find_package(PythonInterp)`` first to
+# get the currently active Python version by default with a consistent version
+# of PYTHON_LIBRARIES.
#=============================================================================
# Copyright 2001-2009 Kitware, Inc.
@@ -32,18 +50,45 @@
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
+# Use the executable's path as a hint
+set(_Python_LIBRARY_PATH_HINT)
+if(PYTHON_EXECUTABLE)
+ if(WIN32)
+ get_filename_component(_Python_PREFIX ${PYTHON_EXECUTABLE} PATH)
+ if(_Python_PREFIX)
+ set(_Python_LIBRARY_PATH_HINT ${_Python_PREFIX}/libs)
+ endif()
+ unset(_Python_PREFIX)
+ else()
+ get_filename_component(_Python_PREFIX ${PYTHON_EXECUTABLE} PATH)
+ get_filename_component(_Python_PREFIX ${_Python_PREFIX} PATH)
+ if(_Python_PREFIX)
+ set(_Python_LIBRARY_PATH_HINT ${_Python_PREFIX}/lib)
+ endif()
+ unset(_Python_PREFIX)
+ endif()
+endif()
+
include(${CMAKE_CURRENT_LIST_DIR}/CMakeFindFrameworks.cmake)
# Search for the python framework on Apple.
CMAKE_FIND_FRAMEWORKS(Python)
+# Save CMAKE_FIND_FRAMEWORK
+if(DEFINED CMAKE_FIND_FRAMEWORK)
+ set(_PythonLibs_CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK})
+else()
+ unset(_PythonLibs_CMAKE_FIND_FRAMEWORK)
+endif()
+# To avoid picking up the system Python.h pre-maturely.
+set(CMAKE_FIND_FRAMEWORK LAST)
+
set(_PYTHON1_VERSIONS 1.6 1.5)
set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
-set(_PYTHON3_VERSIONS 3.3 3.2 3.1 3.0)
+set(_PYTHON3_VERSIONS 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
if(PythonLibs_FIND_VERSION)
- if(PythonLibs_FIND_VERSION MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+.*)?$")
- string(REGEX REPLACE "^([0-9]+\\.[0-9]+).*" "\\1" _PYTHON_FIND_MAJ_MIN "${PythonLibs_FIND_VERSION}")
- string(REGEX REPLACE "^([0-9]+).*" "\\1" _PYTHON_FIND_MAJ "${_PYTHON_FIND_MAJ_MIN}")
+ if(PythonLibs_FIND_VERSION_COUNT GREATER 1)
+ set(_PYTHON_FIND_MAJ_MIN "${PythonLibs_FIND_VERSION_MAJOR}.${PythonLibs_FIND_VERSION_MINOR}")
unset(_PYTHON_FIND_OTHER_VERSIONS)
if(PythonLibs_FIND_VERSION_EXACT)
if(_PYTHON_FIND_MAJ_MIN STREQUAL PythonLibs_FIND_VERSION)
@@ -52,16 +97,15 @@ if(PythonLibs_FIND_VERSION)
set(_PYTHON_FIND_OTHER_VERSIONS "${PythonLibs_FIND_VERSION}" "${_PYTHON_FIND_MAJ_MIN}")
endif()
else()
- foreach(_PYTHON_V ${_PYTHON${_PYTHON_FIND_MAJ}_VERSIONS})
+ foreach(_PYTHON_V ${_PYTHON${PythonLibs_FIND_VERSION_MAJOR}_VERSIONS})
if(NOT _PYTHON_V VERSION_LESS _PYTHON_FIND_MAJ_MIN)
list(APPEND _PYTHON_FIND_OTHER_VERSIONS ${_PYTHON_V})
endif()
endforeach()
endif()
unset(_PYTHON_FIND_MAJ_MIN)
- unset(_PYTHON_FIND_MAJ)
else()
- set(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON${PythonLibs_FIND_VERSION}_VERSIONS})
+ set(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON${PythonLibs_FIND_VERSION_MAJOR}_VERSIONS})
endif()
else()
set(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON3_VERSIONS} ${_PYTHON2_VERSIONS} ${_PYTHON1_VERSIONS})
@@ -69,10 +113,14 @@ endif()
# Set up the versions we know about, in the order we will search. Always add
# the user supplied additional versions to the front.
-set(_Python_VERSIONS
- ${Python_ADDITIONAL_VERSIONS}
- ${_PYTHON_FIND_OTHER_VERSIONS}
- )
+# If FindPythonInterp has already found the major and minor version,
+# insert that version between the user supplied versions and the stock
+# version list.
+set(_Python_VERSIONS ${Python_ADDITIONAL_VERSIONS})
+if(DEFINED PYTHON_VERSION_MAJOR AND DEFINED PYTHON_VERSION_MINOR)
+ list(APPEND _Python_VERSIONS ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR})
+endif()
+list(APPEND _Python_VERSIONS ${_PYTHON_FIND_OTHER_VERSIONS})
unset(_PYTHON_FIND_OTHER_VERSIONS)
unset(_PYTHON1_VERSIONS)
@@ -84,6 +132,7 @@ foreach(_CURRENT_VERSION ${_Python_VERSIONS})
if(WIN32)
find_library(PYTHON_DEBUG_LIBRARY
NAMES python${_CURRENT_VERSION_NO_DOTS}_d python
+ HINTS ${_Python_LIBRARY_PATH_HINT}
PATHS
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs/Debug
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs/Debug
@@ -92,14 +141,24 @@ foreach(_CURRENT_VERSION ${_Python_VERSIONS})
)
endif()
+ set(PYTHON_FRAMEWORK_LIBRARIES)
+ if(Python_FRAMEWORKS AND NOT PYTHON_LIBRARY)
+ foreach(dir ${Python_FRAMEWORKS})
+ list(APPEND PYTHON_FRAMEWORK_LIBRARIES
+ ${dir}/Versions/${_CURRENT_VERSION}/lib)
+ endforeach()
+ endif()
find_library(PYTHON_LIBRARY
NAMES
- python${_CURRENT_VERSION_NO_DOTS}
- python${_CURRENT_VERSION}mu
- python${_CURRENT_VERSION}m
- python${_CURRENT_VERSION}u
- python${_CURRENT_VERSION}
+ python${_CURRENT_VERSION_NO_DOTS}
+ python${_CURRENT_VERSION}mu
+ python${_CURRENT_VERSION}m
+ python${_CURRENT_VERSION}u
+ python${_CURRENT_VERSION}
+ HINTS
+ ${_Python_LIBRARY_PATH_HINT}
PATHS
+ ${PYTHON_FRAMEWORK_LIBRARIES}
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs
# Avoid finding the .dll in the PATH. We want the .lib.
@@ -114,33 +173,42 @@ foreach(_CURRENT_VERSION ${_Python_VERSIONS})
PATH_SUFFIXES python${_CURRENT_VERSION}/config
)
- # For backward compatibility, honour value of PYTHON_INCLUDE_PATH, if
- # PYTHON_INCLUDE_DIR is not set.
- if(DEFINED PYTHON_INCLUDE_PATH AND NOT DEFINED PYTHON_INCLUDE_DIR)
- set(PYTHON_INCLUDE_DIR "${PYTHON_INCLUDE_PATH}" CACHE PATH
- "Path to where Python.h is found" FORCE)
- endif()
+ # Don't search for include dir until library location is known
+ if(PYTHON_LIBRARY)
- set(PYTHON_FRAMEWORK_INCLUDES)
- if(Python_FRAMEWORKS AND NOT PYTHON_INCLUDE_DIR)
- foreach(dir ${Python_FRAMEWORKS})
- set(PYTHON_FRAMEWORK_INCLUDES ${PYTHON_FRAMEWORK_INCLUDES}
- ${dir}/Versions/${_CURRENT_VERSION}/include/python${_CURRENT_VERSION})
- endforeach()
- endif()
+ # Use the library's install prefix as a hint
+ set(_Python_INCLUDE_PATH_HINT)
+ get_filename_component(_Python_PREFIX ${PYTHON_LIBRARY} PATH)
+ get_filename_component(_Python_PREFIX ${_Python_PREFIX} PATH)
+ if(_Python_PREFIX)
+ set(_Python_INCLUDE_PATH_HINT ${_Python_PREFIX}/include)
+ endif()
+ unset(_Python_PREFIX)
+
+ # Add framework directories to the search paths
+ set(PYTHON_FRAMEWORK_INCLUDES)
+ if(Python_FRAMEWORKS AND NOT PYTHON_INCLUDE_DIR)
+ foreach(dir ${Python_FRAMEWORKS})
+ list(APPEND PYTHON_FRAMEWORK_INCLUDES
+ ${dir}/Versions/${_CURRENT_VERSION}/include)
+ endforeach()
+ endif()
- find_path(PYTHON_INCLUDE_DIR
- NAMES Python.h
- PATHS
- ${PYTHON_FRAMEWORK_INCLUDES}
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/include
- [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/include
- PATH_SUFFIXES
- python${_CURRENT_VERSION}mu
- python${_CURRENT_VERSION}m
- python${_CURRENT_VERSION}u
- python${_CURRENT_VERSION}
- )
+ find_path(PYTHON_INCLUDE_DIR
+ NAMES Python.h
+ HINTS
+ ${_Python_INCLUDE_PATH_HINT}
+ PATHS
+ ${PYTHON_FRAMEWORK_INCLUDES}
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/include
+ [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/include
+ PATH_SUFFIXES
+ python${_CURRENT_VERSION}mu
+ python${_CURRENT_VERSION}m
+ python${_CURRENT_VERSION}u
+ python${_CURRENT_VERSION}
+ )
+ endif()
# For backward compatibility, set PYTHON_INCLUDE_PATH.
set(PYTHON_INCLUDE_PATH "${PYTHON_INCLUDE_DIR}")
@@ -158,6 +226,9 @@ foreach(_CURRENT_VERSION ${_Python_VERSIONS})
endif()
endforeach()
+unset(_Python_INCLUDE_PATH_HINT)
+unset(_Python_LIBRARY_PATH_HINT)
+
mark_as_advanced(
PYTHON_DEBUG_LIBRARY
PYTHON_LIBRARY
@@ -182,6 +253,14 @@ SELECT_LIBRARY_CONFIGURATIONS(PYTHON)
# for historical reasons.
unset(PYTHON_FOUND)
+# Restore CMAKE_FIND_FRAMEWORK
+if(DEFINED _PythonLibs_CMAKE_FIND_FRAMEWORK)
+ set(CMAKE_FIND_FRAMEWORK ${_PythonLibs_CMAKE_FIND_FRAMEWORK})
+ unset(_PythonLibs_CMAKE_FIND_FRAMEWORK)
+else()
+ unset(CMAKE_FIND_FRAMEWORK)
+endif()
+
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PythonLibs
REQUIRED_VARS PYTHON_LIBRARIES PYTHON_INCLUDE_DIRS
diff --git a/Modules/FindQt.cmake b/Modules/FindQt.cmake
index 54b7c6f97..41b727158 100644
--- a/Modules/FindQt.cmake
+++ b/Modules/FindQt.cmake
@@ -1,21 +1,34 @@
-# - Searches for all installed versions of Qt.
+#.rst:
+# FindQt
+# ------
+#
+# Searches for all installed versions of Qt.
+#
# This should only be used if your project can work with multiple
-# versions of Qt. If not, you should just directly use FindQt4 or FindQt3.
-# If multiple versions of Qt are found on the machine, then
-# The user must set the option DESIRED_QT_VERSION to the version
-# they want to use. If only one version of qt is found on the machine,
-# then the DESIRED_QT_VERSION is set to that version and the
-# matching FindQt3 or FindQt4 module is included.
-# Once the user sets DESIRED_QT_VERSION, then the FindQt3 or FindQt4 module
-# is included.
+# versions of Qt. If not, you should just directly use FindQt4 or
+# FindQt3. If multiple versions of Qt are found on the machine, then
+# The user must set the option DESIRED_QT_VERSION to the version they
+# want to use. If only one version of qt is found on the machine, then
+# the DESIRED_QT_VERSION is set to that version and the matching FindQt3
+# or FindQt4 module is included. Once the user sets DESIRED_QT_VERSION,
+# then the FindQt3 or FindQt4 module is included.
+#
+# This module can only detect and switch between Qt versions 3 and 4. It
+# cannot handle Qt5 or any later versions.
+#
+# ::
+#
+# QT_REQUIRED if this is set to TRUE then if CMake can
+# not find Qt4 or Qt3 an error is raised
+# and a message is sent to the user.
+#
+#
#
-# QT_REQUIRED if this is set to TRUE then if CMake can
-# not find Qt4 or Qt3 an error is raised
-# and a message is sent to the user.
+# ::
#
-# DESIRED_QT_VERSION OPTION is created
-# QT4_INSTALLED is set to TRUE if qt4 is found.
-# QT3_INSTALLED is set to TRUE if qt3 is found.
+# DESIRED_QT_VERSION OPTION is created
+# QT4_INSTALLED is set to TRUE if qt4 is found.
+# QT3_INSTALLED is set to TRUE if qt3 is found.
#=============================================================================
# Copyright 2001-2009 Kitware, Inc.
@@ -69,7 +82,11 @@ endif()
set(GLOB_TEMP_VAR)
if (Qt_FIND_VERSION)
- set(DESIRED_QT_VERSION "${Qt_FIND_VERSION}")
+ if (Qt_FIND_VERSION MATCHES "^([34])(\\.[0-9]+.*)?$")
+ set(DESIRED_QT_VERSION ${CMAKE_MATCH_1})
+ else ()
+ message(FATAL_ERROR "FindQt was called with invalid version '${Qt_FIND_VERSION}'. Only Qt major versions 3 or 4 are supported. If you do not need to support both Qt3 and Qt4 in your source consider calling find_package(Qt3) or find_package(Qt4) instead of find_package(Qt) instead.")
+ endif ()
endif ()
# now find qmake
@@ -77,7 +94,7 @@ find_program(QT_QMAKE_EXECUTABLE_FINDQT NAMES qmake PATHS "${QT_SEARCH_PATH}/bin
if(QT_QMAKE_EXECUTABLE_FINDQT)
exec_program(${QT_QMAKE_EXECUTABLE_FINDQT} ARGS "-query QT_VERSION"
OUTPUT_VARIABLE QTVERSION)
- if(QTVERSION MATCHES "4.*")
+ if(QTVERSION MATCHES "4")
set(QT_QMAKE_EXECUTABLE ${QT_QMAKE_EXECUTABLE_FINDQT} CACHE PATH "Qt4 qmake program.")
set(QT4_INSTALLED TRUE)
endif()
@@ -144,12 +161,12 @@ else()
endif()
endif()
-if(DESIRED_QT_VERSION MATCHES 3)
+if(DESIRED_QT_VERSION EQUAL 3)
set(Qt3_FIND_REQUIRED ${Qt_FIND_REQUIRED})
set(Qt3_FIND_QUIETLY ${Qt_FIND_QUIETLY})
include(${CMAKE_CURRENT_LIST_DIR}/FindQt3.cmake)
endif()
-if(DESIRED_QT_VERSION MATCHES 4)
+if(DESIRED_QT_VERSION EQUAL 4)
set(Qt4_FIND_REQUIRED ${Qt_FIND_REQUIRED})
set(Qt4_FIND_QUIETLY ${Qt_FIND_QUIETLY})
include(${CMAKE_CURRENT_LIST_DIR}/FindQt4.cmake)
@@ -169,9 +186,9 @@ else()
endif()
if(NOT QT_FOUND AND DESIRED_QT_VERSION)
if(QT_REQUIRED)
- message(FATAL_ERROR "CMake was unable to find Qt version: ${DESIRED_QT_VERSION}. Set advanced values QT_QMAKE_EXECUTABLE and QT${DESIRED_QT_VERSION}_QGLOBAL_FILE, if those are set then QT_QT_LIBRARY or QT_LIBRARY_DIR.")
+ message(FATAL_ERROR "CMake was unable to find Qt version: ${DESIRED_QT_VERSION}. Set advanced values QT_QMAKE_EXECUTABLE and QT${DESIRED_QT_VERSION}_QGLOBAL_H_FILE, if those are set then QT_QT_LIBRARY or QT_LIBRARY_DIR.")
else()
- message( "CMake was unable to find desired Qt version: ${DESIRED_QT_VERSION}. Set advanced values QT_QMAKE_EXECUTABLE and QT${DESIRED_QT_VERSION}_QGLOBAL_FILE.")
+ message( "CMake was unable to find desired Qt version: ${DESIRED_QT_VERSION}. Set advanced values QT_QMAKE_EXECUTABLE and QT${DESIRED_QT_VERSION}_QGLOBAL_H_FILE.")
endif()
endif()
endif()
diff --git a/Modules/FindQt3.cmake b/Modules/FindQt3.cmake
index 4fc8e406c..86997ba30 100644
--- a/Modules/FindQt3.cmake
+++ b/Modules/FindQt3.cmake
@@ -1,20 +1,34 @@
-# - Locate Qt include paths and libraries
+#.rst:
+# FindQt3
+# -------
+#
+# Locate Qt include paths and libraries
+#
# This module defines:
-# QT_INCLUDE_DIR - where to find qt.h, etc.
-# QT_LIBRARIES - the libraries to link against to use Qt.
-# QT_DEFINITIONS - definitions to use when
-# compiling code that uses Qt.
-# QT_FOUND - If false, don't try to use Qt.
-# QT_VERSION_STRING - the version of Qt found
#
-# If you need the multithreaded version of Qt, set QT_MT_REQUIRED to TRUE
+# ::
+#
+# QT_INCLUDE_DIR - where to find qt.h, etc.
+# QT_LIBRARIES - the libraries to link against to use Qt.
+# QT_DEFINITIONS - definitions to use when
+# compiling code that uses Qt.
+# QT_FOUND - If false, don't try to use Qt.
+# QT_VERSION_STRING - the version of Qt found
+#
+#
+#
+# If you need the multithreaded version of Qt, set QT_MT_REQUIRED to
+# TRUE
#
# Also defined, but not for general use are:
-# QT_MOC_EXECUTABLE, where to find the moc tool.
-# QT_UIC_EXECUTABLE, where to find the uic tool.
-# QT_QT_LIBRARY, where to find the Qt library.
-# QT_QTMAIN_LIBRARY, where to find the qtmain
-# library. This is only required by Qt3 on Windows.
+#
+# ::
+#
+# QT_MOC_EXECUTABLE, where to find the moc tool.
+# QT_UIC_EXECUTABLE, where to find the uic tool.
+# QT_QT_LIBRARY, where to find the Qt library.
+# QT_QTMAIN_LIBRARY, where to find the qtmain
+# library. This is only required by Qt3 on Windows.
# These are around for backwards compatibility
# they will be set
@@ -147,7 +161,7 @@ find_library(QT_QASSISTANTCLIENT_LIBRARY
# Qt 3 should prefer QTDIR over the PATH
find_program(QT_MOC_EXECUTABLE
- NAMES moc-qt3 moc moc3 moc3-mt
+ NAMES moc-qt3 moc3 moc3-mt moc
HINTS
ENV QTDIR
PATHS
@@ -172,7 +186,7 @@ endif()
# Qt 3 should prefer QTDIR over the PATH
find_program(QT_UIC_EXECUTABLE
- NAMES uic-qt3 uic uic3 uic3-mt
+ NAMES uic-qt3 uic3 uic3-mt uic
HINTS
ENV QTDIR
PATHS
@@ -281,12 +295,12 @@ if(QT_UIC_EXECUTABLE)
endif()
set(_QT_UIC_VERSION_3 FALSE)
-if("${QTVERSION_UIC}" MATCHES ".* 3..*")
+if("${QTVERSION_UIC}" MATCHES " 3.")
set(_QT_UIC_VERSION_3 TRUE)
endif()
set(_QT_MOC_VERSION_3 FALSE)
-if("${QTVERSION_MOC}" MATCHES ".* 3..*")
+if("${QTVERSION_MOC}" MATCHES " 3.")
set(_QT_MOC_VERSION_3 TRUE)
endif()
diff --git a/Modules/FindQt4.cmake b/Modules/FindQt4.cmake
index 1d17ba3ae..11091b537 100644
--- a/Modules/FindQt4.cmake
+++ b/Modules/FindQt4.cmake
@@ -1,349 +1,299 @@
-# - Find Qt 4
-# This module can be used to find Qt4.
-# The most important issue is that the Qt4 qmake is available via the system path.
-# This qmake is then used to detect basically everything else.
-# This module defines a number of key variables and macros.
-# The variable QT_USE_FILE is set which is the path to a CMake file that can be included
-# to compile Qt 4 applications and libraries. It sets up the compilation
-# environment for include directories, preprocessor defines and populates a
-# QT_LIBRARIES variable.
+#.rst:
+# FindQt4
+# -------
+#
+# Finding and Using Qt4
+# ^^^^^^^^^^^^^^^^^^^^^
+#
+# This module can be used to find Qt4. The most important issue is that
+# the Qt4 qmake is available via the system path. This qmake is then
+# used to detect basically everything else. This module defines a
+# number of :prop_tgt:`IMPORTED` targets, macros and variables.
#
# Typical usage could be something like:
-# find_package(Qt4 4.4.3 REQUIRED QtCore QtGui QtXml)
-# include(${QT_USE_FILE})
-# add_executable(myexe main.cpp)
-# target_link_libraries(myexe ${QT_LIBRARIES})
-#
-# The minimum required version can be specified using the standard find_package()-syntax
-# (see example above).
-# For compatibility with older versions of FindQt4.cmake it is also possible to
-# set the variable QT_MIN_VERSION to the minimum required version of Qt4 before the
-# find_package(Qt4) command.
-# If both are used, the version used in the find_package() command overrides the
-# one from QT_MIN_VERSION.
-#
-# When using the components argument, QT_USE_QT* variables are automatically set
-# for the QT_USE_FILE to pick up. If one wishes to manually set them, the
-# available ones to set include:
-# QT_DONT_USE_QTCORE
-# QT_DONT_USE_QTGUI
-# QT_USE_QT3SUPPORT
-# QT_USE_QTASSISTANT
-# QT_USE_QAXCONTAINER
-# QT_USE_QAXSERVER
-# QT_USE_QTDESIGNER
-# QT_USE_QTMOTIF
-# QT_USE_QTMAIN
-# QT_USE_QTMULTIMEDIA
-# QT_USE_QTNETWORK
-# QT_USE_QTNSPLUGIN
-# QT_USE_QTOPENGL
-# QT_USE_QTSQL
-# QT_USE_QTXML
-# QT_USE_QTSVG
-# QT_USE_QTTEST
-# QT_USE_QTUITOOLS
-# QT_USE_QTDBUS
-# QT_USE_QTSCRIPT
-# QT_USE_QTASSISTANTCLIENT
-# QT_USE_QTHELP
-# QT_USE_QTWEBKIT
-# QT_USE_QTXMLPATTERNS
-# QT_USE_PHONON
-# QT_USE_QTSCRIPTTOOLS
-# QT_USE_QTDECLARATIVE
-#
-# QT_USE_IMPORTED_TARGETS
-# If this variable is set to TRUE, FindQt4.cmake will create imported
-# library targets for the various Qt libraries and set the
-# library variables like QT_QTCORE_LIBRARY to point at these imported
-# targets instead of the library file on disk. This provides much better
-# handling of the release and debug versions of the Qt libraries and is
-# also always backwards compatible, except for the case that dependencies
-# of libraries are exported, these will then also list the names of the
-# imported targets as dependency and not the file location on disk. This
-# is much more flexible, but requires that FindQt4.cmake is executed before
-# such an exported dependency file is processed.
-#
-# Note that if using IMPORTED targets, the qtmain.lib static library is
-# automatically linked on Windows. To disable that globally, set the
-# QT4_NO_LINK_QTMAIN variable before finding Qt4. To disable that for a
-# particular executable, set the QT4_NO_LINK_QTMAIN target property to
-# True on the executable.
-#
-# QT_INCLUDE_DIRS_NO_SYSTEM
-# If this variable is set to TRUE, the Qt include directories
-# in the QT_USE_FILE will NOT have the SYSTEM keyword set.
-#
-# There are also some files that need processing by some Qt tools such as moc
-# and uic. Listed below are macros that may be used to process those files.
-#
-# macro QT4_WRAP_CPP(outfiles inputfile ... OPTIONS ...)
-# create moc code from a list of files containing Qt class with
-# the Q_OBJECT declaration. Per-directory preprocessor definitions
-# are also added. Options may be given to moc, such as those found
-# when executing "moc -help".
-#
-# macro QT4_WRAP_UI(outfiles inputfile ... OPTIONS ...)
-# create code from a list of Qt designer ui files.
-# Options may be given to uic, such as those found
-# when executing "uic -help"
-#
-# macro QT4_ADD_RESOURCES(outfiles inputfile ... OPTIONS ...)
-# create code from a list of Qt resource files.
-# Options may be given to rcc, such as those found
-# when executing "rcc -help"
-#
-# macro QT4_GENERATE_MOC(inputfile outputfile )
-# creates a rule to run moc on infile and create outfile.
-# Use this if for some reason QT4_WRAP_CPP() isn't appropriate, e.g.
-# because you need a custom filename for the moc file or something similar.
-#
-# macro QT4_AUTOMOC(sourcefile1 sourcefile2 ... )
-# The qt4_automoc macro is obsolete. Use the CMAKE_AUTOMOC feature instead.
-# This macro is still experimental.
-# It can be used to have moc automatically handled.
-# So if you have the files foo.h and foo.cpp, and in foo.h a
-# a class uses the Q_OBJECT macro, moc has to run on it. If you don't
-# want to use QT4_WRAP_CPP() (which is reliable and mature), you can insert
-# #include "foo.moc"
-# in foo.cpp and then give foo.cpp as argument to QT4_AUTOMOC(). This will the
-# scan all listed files at cmake-time for such included moc files and if it finds
-# them cause a rule to be generated to run moc at build time on the
-# accompanying header file foo.h.
-# If a source file has the SKIP_AUTOMOC property set it will be ignored by this macro.
-#
-# You should have a look on the AUTOMOC property for targets to achieve the same results.
-#
-# macro QT4_ADD_DBUS_INTERFACE(outfiles interface basename)
-# Create the interface header and implementation files with the
-# given basename from the given interface xml file and add it to
-# the list of sources.
-#
-# You can pass additional parameters to the qdbusxml2cpp call by setting
-# properties on the input file:
-#
-# INCLUDE the given file will be included in the generate interface header
-#
-# CLASSNAME the generated class is named accordingly
-#
-# NO_NAMESPACE the generated class is not wrapped in a namespace
-#
-# macro QT4_ADD_DBUS_INTERFACES(outfiles inputfile ... )
-# Create the interface header and implementation files
-# for all listed interface xml files.
-# The basename will be automatically determined from the name of the xml file.
-#
-# The source file properties described for QT4_ADD_DBUS_INTERFACE also apply here.
-#
-# macro QT4_ADD_DBUS_ADAPTOR(outfiles xmlfile parentheader parentclassname [basename] [classname])
-# create a dbus adaptor (header and implementation file) from the xml file
-# describing the interface, and add it to the list of sources. The adaptor
-# forwards the calls to a parent class, defined in parentheader and named
-# parentclassname. The name of the generated files will be
-# <basename>adaptor.{cpp,h} where basename defaults to the basename of the xml file.
-# If <classname> is provided, then it will be used as the classname of the
-# adaptor itself.
-#
-# macro QT4_GENERATE_DBUS_INTERFACE( header [interfacename] OPTIONS ...)
-# generate the xml interface file from the given header.
-# If the optional argument interfacename is omitted, the name of the
-# interface file is constructed from the basename of the header with
-# the suffix .xml appended.
-# Options may be given to qdbuscpp2xml, such as those found when executing "qdbuscpp2xml --help"
-#
-# macro QT4_CREATE_TRANSLATION( qm_files directories ... sources ...
-# ts_files ... OPTIONS ...)
-# out: qm_files
-# in: directories sources ts_files
-# options: flags to pass to lupdate, such as -extensions to specify
-# extensions for a directory scan.
-# generates commands to create .ts (vie lupdate) and .qm
-# (via lrelease) - files from directories and/or sources. The ts files are
-# created and/or updated in the source tree (unless given with full paths).
-# The qm files are generated in the build tree.
-# Updating the translations can be done by adding the qm_files
-# to the source list of your library/executable, so they are
-# always updated, or by adding a custom target to control when
-# they get updated/generated.
-#
-# macro QT4_ADD_TRANSLATION( qm_files ts_files ... )
-# out: qm_files
-# in: ts_files
-# generates commands to create .qm from .ts - files. The generated
-# filenames can be found in qm_files. The ts_files
-# must exist and are not updated in any way.
-#
-# function QT4_USE_MODULES( target [link_type] modules...)
-# This function is obsolete. Use target_link_libraries with IMPORTED targets instead.
-# Make <target> use the <modules> from Qt. Using a Qt module means
-# to link to the library, add the relevant include directories for the module,
-# and add the relevant compiler defines for using the module.
-# Modules are roughly equivalent to components of Qt4, so usage would be
-# something like:
-# qt4_use_modules(myexe Core Gui Declarative)
-# to use QtCore, QtGui and QtDeclarative. The optional <link_type> argument can
-# be specified as either LINK_PUBLIC or LINK_PRIVATE to specify the same argument
-# to the target_link_libraries call.
-#
-#
-# Below is a detailed list of variables that FindQt4.cmake sets.
-# QT_FOUND If false, don't try to use Qt.
-# Qt4_FOUND If false, don't try to use Qt 4.
-# QT4_FOUND If false, don't try to use Qt 4. This variable is for compatibility only.
-#
-# QT_VERSION_MAJOR The major version of Qt found.
-# QT_VERSION_MINOR The minor version of Qt found.
-# QT_VERSION_PATCH The patch version of Qt found.
-#
-# QT_EDITION Set to the edition of Qt (i.e. DesktopLight)
-# QT_EDITION_DESKTOPLIGHT True if QT_EDITION == DesktopLight
-# QT_QTCORE_FOUND True if QtCore was found.
-# QT_QTGUI_FOUND True if QtGui was found.
-# QT_QT3SUPPORT_FOUND True if Qt3Support was found.
-# QT_QTASSISTANT_FOUND True if QtAssistant was found.
-# QT_QTASSISTANTCLIENT_FOUND True if QtAssistantClient was found.
-# QT_QAXCONTAINER_FOUND True if QAxContainer was found (Windows only).
-# QT_QAXSERVER_FOUND True if QAxServer was found (Windows only).
-# QT_QTDBUS_FOUND True if QtDBus was found.
-# QT_QTDESIGNER_FOUND True if QtDesigner was found.
-# QT_QTDESIGNERCOMPONENTS True if QtDesignerComponents was found.
-# QT_QTHELP_FOUND True if QtHelp was found.
-# QT_QTMOTIF_FOUND True if QtMotif was found.
-# QT_QTMULTIMEDIA_FOUND True if QtMultimedia was found (since Qt 4.6.0).
-# QT_QTNETWORK_FOUND True if QtNetwork was found.
-# QT_QTNSPLUGIN_FOUND True if QtNsPlugin was found.
-# QT_QTOPENGL_FOUND True if QtOpenGL was found.
-# QT_QTSQL_FOUND True if QtSql was found.
-# QT_QTSVG_FOUND True if QtSvg was found.
-# QT_QTSCRIPT_FOUND True if QtScript was found.
-# QT_QTSCRIPTTOOLS_FOUND True if QtScriptTools was found.
-# QT_QTTEST_FOUND True if QtTest was found.
-# QT_QTUITOOLS_FOUND True if QtUiTools was found.
-# QT_QTWEBKIT_FOUND True if QtWebKit was found.
-# QT_QTXML_FOUND True if QtXml was found.
-# QT_QTXMLPATTERNS_FOUND True if QtXmlPatterns was found.
-# QT_PHONON_FOUND True if phonon was found.
-# QT_QTDECLARATIVE_FOUND True if QtDeclarative was found.
-#
-# QT_MAC_USE_COCOA For Mac OS X, its whether Cocoa or Carbon is used.
-# In general, this should not be used, but its useful
-# when having platform specific code.
-#
-# QT_DEFINITIONS Definitions to use when compiling code that uses Qt.
-# You do not need to use this if you include QT_USE_FILE.
-# The QT_USE_FILE will also define QT_DEBUG and QT_NO_DEBUG
-# to fit your current build type. Those are not contained
-# in QT_DEFINITIONS.
-#
-# QT_INCLUDES List of paths to all include directories of
-# Qt4 QT_INCLUDE_DIR and QT_QTCORE_INCLUDE_DIR are
-# always in this variable even if NOTFOUND,
-# all other INCLUDE_DIRS are
-# only added if they are found.
-# You do not need to use this if you include QT_USE_FILE.
-#
-#
-# Include directories for the Qt modules are listed here.
-# You do not need to use these variables if you include QT_USE_FILE.
-#
-# QT_INCLUDE_DIR Path to "include" of Qt4
-# QT_QT3SUPPORT_INCLUDE_DIR Path to "include/Qt3Support"
-# QT_QTASSISTANT_INCLUDE_DIR Path to "include/QtAssistant"
-# QT_QTASSISTANTCLIENT_INCLUDE_DIR Path to "include/QtAssistant"
-# QT_QAXCONTAINER_INCLUDE_DIR Path to "include/ActiveQt" (Windows only)
-# QT_QAXSERVER_INCLUDE_DIR Path to "include/ActiveQt" (Windows only)
-# QT_QTCORE_INCLUDE_DIR Path to "include/QtCore"
-# QT_QTDBUS_INCLUDE_DIR Path to "include/QtDBus"
-# QT_QTDESIGNER_INCLUDE_DIR Path to "include/QtDesigner"
-# QT_QTDESIGNERCOMPONENTS_INCLUDE_DIR Path to "include/QtDesigner"
-# QT_QTGUI_INCLUDE_DIR Path to "include/QtGui"
-# QT_QTHELP_INCLUDE_DIR Path to "include/QtHelp"
-# QT_QTMOTIF_INCLUDE_DIR Path to "include/QtMotif"
-# QT_QTMULTIMEDIA_INCLUDE_DIR Path to "include/QtMultimedia"
-# QT_QTNETWORK_INCLUDE_DIR Path to "include/QtNetwork"
-# QT_QTNSPLUGIN_INCLUDE_DIR Path to "include/QtNsPlugin"
-# QT_QTOPENGL_INCLUDE_DIR Path to "include/QtOpenGL"
-# QT_QTSCRIPT_INCLUDE_DIR Path to "include/QtScript"
-# QT_QTSQL_INCLUDE_DIR Path to "include/QtSql"
-# QT_QTSVG_INCLUDE_DIR Path to "include/QtSvg"
-# QT_QTTEST_INCLUDE_DIR Path to "include/QtTest"
-# QT_QTWEBKIT_INCLUDE_DIR Path to "include/QtWebKit"
-# QT_QTXML_INCLUDE_DIR Path to "include/QtXml"
-# QT_QTXMLPATTERNS_INCLUDE_DIR Path to "include/QtXmlPatterns"
-# QT_PHONON_INCLUDE_DIR Path to "include/phonon"
-# QT_QTSCRIPTTOOLS_INCLUDE_DIR Path to "include/QtScriptTools"
-# QT_QTDECLARATIVE_INCLUDE_DIR Path to "include/QtDeclarative"
-#
-# QT_BINARY_DIR Path to "bin" of Qt4
-# QT_LIBRARY_DIR Path to "lib" of Qt4
-# QT_PLUGINS_DIR Path to "plugins" for Qt4
-# QT_TRANSLATIONS_DIR Path to "translations" of Qt4
-# QT_IMPORTS_DIR Path to "imports" of Qt4
-# QT_DOC_DIR Path to "doc" of Qt4
-# QT_MKSPECS_DIR Path to "mkspecs" of Qt4
#
+# .. code-block:: cmake
+#
+# set(CMAKE_AUTOMOC ON)
+# set(CMAKE_INCLUDE_CURRENT_DIR ON)
+# find_package(Qt4 4.4.3 REQUIRED QtGui QtXml)
+# add_executable(myexe main.cpp)
+# target_link_libraries(myexe Qt4::QtGui Qt4::QtXml)
+#
+# .. note::
+#
+# When using :prop_tgt:`IMPORTED` targets, the qtmain.lib static library is
+# automatically linked on Windows for :prop_tgt:`WIN32 <WIN32_EXECUTABLE>`
+# executables. To disable that globally, set the
+# ``QT4_NO_LINK_QTMAIN`` variable before finding Qt4. To disable that
+# for a particular executable, set the ``QT4_NO_LINK_QTMAIN`` target
+# property to ``TRUE`` on the executable.
+#
+# Qt Build Tools
+# ^^^^^^^^^^^^^^
+#
+# Qt relies on some bundled tools for code generation, such as ``moc`` for
+# meta-object code generation,``uic`` for widget layout and population,
+# and ``rcc`` for virtual filesystem content generation. These tools may be
+# automatically invoked by :manual:`cmake(1)` if the appropriate conditions
+# are met. See :manual:`cmake-qt(7)` for more.
+#
+# Qt Macros
+# ^^^^^^^^^
+#
+# In some cases it can be necessary or useful to invoke the Qt build tools in a
+# more-manual way. Several macros are available to add targets for such uses.
+#
+# ::
+#
+# macro QT4_WRAP_CPP(outfiles inputfile ... [TARGET tgt] OPTIONS ...)
+# create moc code from a list of files containing Qt class with
+# the Q_OBJECT declaration. Per-directory preprocessor definitions
+# are also added. If the <tgt> is specified, the
+# INTERFACE_INCLUDE_DIRECTORIES and INTERFACE_COMPILE_DEFINITIONS from
+# the <tgt> are passed to moc. Options may be given to moc, such as
+# those found when executing "moc -help".
+#
+#
+# ::
+#
+# macro QT4_WRAP_UI(outfiles inputfile ... OPTIONS ...)
+# create code from a list of Qt designer ui files.
+# Options may be given to uic, such as those found
+# when executing "uic -help"
+#
+#
+# ::
+#
+# macro QT4_ADD_RESOURCES(outfiles inputfile ... OPTIONS ...)
+# create code from a list of Qt resource files.
+# Options may be given to rcc, such as those found
+# when executing "rcc -help"
+#
+#
+# ::
+#
+# macro QT4_GENERATE_MOC(inputfile outputfile [TARGET tgt])
+# creates a rule to run moc on infile and create outfile.
+# Use this if for some reason QT4_WRAP_CPP() isn't appropriate, e.g.
+# because you need a custom filename for the moc file or something
+# similar. If the <tgt> is specified, the
+# INTERFACE_INCLUDE_DIRECTORIES and INTERFACE_COMPILE_DEFINITIONS from
+# the <tgt> are passed to moc.
+#
+#
+# ::
+#
+# macro QT4_ADD_DBUS_INTERFACE(outfiles interface basename)
+# Create the interface header and implementation files with the
+# given basename from the given interface xml file and add it to
+# the list of sources.
+#
+# You can pass additional parameters to the qdbusxml2cpp call by setting
+# properties on the input file:
+#
+# INCLUDE the given file will be included in the generate interface header
+#
+# CLASSNAME the generated class is named accordingly
+#
+# NO_NAMESPACE the generated class is not wrapped in a namespace
+#
+#
+# ::
+#
+# macro QT4_ADD_DBUS_INTERFACES(outfiles inputfile ... )
+# Create the interface header and implementation files
+# for all listed interface xml files.
+# The basename will be automatically determined from the name
+# of the xml file.
+#
+# The source file properties described for
+# QT4_ADD_DBUS_INTERFACE also apply here.
+#
+#
+# ::
+#
+# macro QT4_ADD_DBUS_ADAPTOR(outfiles xmlfile parentheader parentclassname
+# [basename] [classname])
+# create a dbus adaptor (header and implementation file) from the xml file
+# describing the interface, and add it to the list of sources. The adaptor
+# forwards the calls to a parent class, defined in parentheader and named
+# parentclassname. The name of the generated files will be
+# <basename>adaptor.{cpp,h} where basename defaults to the basename of the
+# xml file.
+# If <classname> is provided, then it will be used as the classname of the
+# adaptor itself.
+#
+#
+# ::
+#
+# macro QT4_GENERATE_DBUS_INTERFACE( header [interfacename] OPTIONS ...)
+# generate the xml interface file from the given header.
+# If the optional argument interfacename is omitted, the name of the
+# interface file is constructed from the basename of the header with
+# the suffix .xml appended.
+# Options may be given to qdbuscpp2xml, such as those found when
+# executing "qdbuscpp2xml --help"
+#
+#
+# ::
+#
+# macro QT4_CREATE_TRANSLATION( qm_files directories ... sources ...
+# ts_files ... OPTIONS ...)
+# out: qm_files
+# in: directories sources ts_files
+# options: flags to pass to lupdate, such as -extensions to specify
+# extensions for a directory scan.
+# generates commands to create .ts (vie lupdate) and .qm
+# (via lrelease) - files from directories and/or sources. The ts files are
+# created and/or updated in the source tree (unless given with full paths).
+# The qm files are generated in the build tree.
+# Updating the translations can be done by adding the qm_files
+# to the source list of your library/executable, so they are
+# always updated, or by adding a custom target to control when
+# they get updated/generated.
+#
+#
+# ::
+#
+# macro QT4_ADD_TRANSLATION( qm_files ts_files ... )
+# out: qm_files
+# in: ts_files
+# generates commands to create .qm from .ts - files. The generated
+# filenames can be found in qm_files. The ts_files
+# must exist and are not updated in any way.
+#
+#
+# ::
+#
+# macro QT4_AUTOMOC(sourcefile1 sourcefile2 ... [TARGET tgt])
+# The qt4_automoc macro is obsolete. Use the CMAKE_AUTOMOC feature instead.
+# This macro is still experimental.
+# It can be used to have moc automatically handled.
+# So if you have the files foo.h and foo.cpp, and in foo.h a
+# a class uses the Q_OBJECT macro, moc has to run on it. If you don't
+# want to use QT4_WRAP_CPP() (which is reliable and mature), you can insert
+# #include "foo.moc"
+# in foo.cpp and then give foo.cpp as argument to QT4_AUTOMOC(). This will
+# scan all listed files at cmake-time for such included moc files and if it
+# finds them cause a rule to be generated to run moc at build time on the
+# accompanying header file foo.h.
+# If a source file has the SKIP_AUTOMOC property set it will be ignored by
+# this macro.
+# If the <tgt> is specified, the INTERFACE_INCLUDE_DIRECTORIES and
+# INTERFACE_COMPILE_DEFINITIONS from the <tgt> are passed to moc.
+#
+#
+# ::
+#
+# function QT4_USE_MODULES( target [link_type] modules...)
+# This function is obsolete. Use target_link_libraries with IMPORTED targets
+# instead.
+# Make <target> use the <modules> from Qt. Using a Qt module means
+# to link to the library, add the relevant include directories for the
+# module, and add the relevant compiler defines for using the module.
+# Modules are roughly equivalent to components of Qt4, so usage would be
+# something like:
+# qt4_use_modules(myexe Core Gui Declarative)
+# to use QtCore, QtGui and QtDeclarative. The optional <link_type> argument
+# can be specified as either LINK_PUBLIC or LINK_PRIVATE to specify the
+# same argument to the target_link_libraries call.
+#
+#
+# IMPORTED Targets
+# ^^^^^^^^^^^^^^^^
+#
+# A particular Qt library may be used by using the corresponding
+# :prop_tgt:`IMPORTED` target with the :command:`target_link_libraries`
+# command:
+#
+# .. code-block:: cmake
+#
+# target_link_libraries(myexe Qt4::QtGui Qt4::QtXml)
+#
+# Using a target in this way causes :cmake(1)` to use the appropriate include
+# directories and compile definitions for the target when compiling ``myexe``.
+#
+# Targets are aware of their dependencies, so for example it is not necessary
+# to list ``Qt4::QtCore`` if another Qt library is listed, and it is not
+# necessary to list ``Qt4::QtGui`` if ``Qt4::QtDeclarative`` is listed.
+# Targets may be tested for existence in the usual way with the
+# :command:`if(TARGET)` command.
#
# The Qt toolkit may contain both debug and release libraries.
-# In that case, the following library variables will contain both.
-# You do not need to use these variables if you include QT_USE_FILE,
-# and use QT_LIBRARIES.
-#
-# QT_QT3SUPPORT_LIBRARY The Qt3Support library
-# QT_QTASSISTANT_LIBRARY The QtAssistant library
-# QT_QTASSISTANTCLIENT_LIBRARY The QtAssistantClient library
-# QT_QAXCONTAINER_LIBRARY The QAxContainer library (Windows only)
-# QT_QAXSERVER_LIBRARY The QAxServer library (Windows only)
-# QT_QTCORE_LIBRARY The QtCore library
-# QT_QTDBUS_LIBRARY The QtDBus library
-# QT_QTDESIGNER_LIBRARY The QtDesigner library
-# QT_QTDESIGNERCOMPONENTS_LIBRARY The QtDesignerComponents library
-# QT_QTGUI_LIBRARY The QtGui library
-# QT_QTHELP_LIBRARY The QtHelp library
-# QT_QTMOTIF_LIBRARY The QtMotif library
-# QT_QTMULTIMEDIA_LIBRARY The QtMultimedia library
-# QT_QTNETWORK_LIBRARY The QtNetwork library
-# QT_QTNSPLUGIN_LIBRARY The QtNsPLugin library
-# QT_QTOPENGL_LIBRARY The QtOpenGL library
-# QT_QTSCRIPT_LIBRARY The QtScript library
-# QT_QTSQL_LIBRARY The QtSql library
-# QT_QTSVG_LIBRARY The QtSvg library
-# QT_QTTEST_LIBRARY The QtTest library
-# QT_QTUITOOLS_LIBRARY The QtUiTools library
-# QT_QTWEBKIT_LIBRARY The QtWebKit library
-# QT_QTXML_LIBRARY The QtXml library
-# QT_QTXMLPATTERNS_LIBRARY The QtXmlPatterns library
-# QT_QTMAIN_LIBRARY The qtmain library for Windows
-# QT_PHONON_LIBRARY The phonon library
-# QT_QTSCRIPTTOOLS_LIBRARY The QtScriptTools library
-#
-# The QtDeclarative library: QT_QTDECLARATIVE_LIBRARY
-#
-# also defined, but NOT for general use are
-# QT_MOC_EXECUTABLE Where to find the moc tool.
-# QT_UIC_EXECUTABLE Where to find the uic tool.
-# QT_UIC3_EXECUTABLE Where to find the uic3 tool.
-# QT_RCC_EXECUTABLE Where to find the rcc tool
-# QT_DBUSCPP2XML_EXECUTABLE Where to find the qdbuscpp2xml tool.
-# QT_DBUSXML2CPP_EXECUTABLE Where to find the qdbusxml2cpp tool.
-# QT_LUPDATE_EXECUTABLE Where to find the lupdate tool.
-# QT_LRELEASE_EXECUTABLE Where to find the lrelease tool.
-# QT_QCOLLECTIONGENERATOR_EXECUTABLE Where to find the qcollectiongenerator tool.
-# QT_DESIGNER_EXECUTABLE Where to find the Qt designer tool.
-# QT_LINGUIST_EXECUTABLE Where to find the Qt linguist tool.
-#
-#
-# These are around for backwards compatibility
-# they will be set
-# QT_WRAP_CPP Set true if QT_MOC_EXECUTABLE is found
-# QT_WRAP_UI Set true if QT_UIC_EXECUTABLE is found
-#
-# These variables do _NOT_ have any effect anymore (compared to FindQt.cmake)
-# QT_MT_REQUIRED Qt4 is now always multithreaded
-#
-# These variables are set to "" Because Qt structure changed
-# (They make no sense in Qt4)
-# QT_QT_LIBRARY Qt-Library is now split
+# :manual:`cmake(1)` will choose the appropriate version based on the build
+# configuration.
+#
+# ``Qt4::QtCore``
+# The QtCore target
+# ``Qt4::QtGui``
+# The QtGui target
+# ``Qt4::Qt3Support``
+# The Qt3Support target
+# ``Qt4::QtAssistant``
+# The QtAssistant target
+# ``Qt4::QtAssistantClient``
+# The QtAssistantClient target
+# ``Qt4::QAxContainer``
+# The QAxContainer target (Windows only)
+# ``Qt4::QAxServer``
+# The QAxServer target (Windows only)
+# ``Qt4::QtDBus``
+# The QtDBus target
+# ``Qt4::QtDesigner``
+# The QtDesigner target
+# ``Qt4::QtDesignerComponents``
+# The QtDesignerComponents target
+# ``Qt4::QtHelp``
+# The QtHelp target
+# ``Qt4::QtMotif``
+# The QtMotif target
+# ``Qt4::QtMultimedia``
+# The QtMultimedia target
+# ``Qt4::QtNetwork``
+# The QtNetwork target
+# ``Qt4::QtNsPLugin``
+# The QtNsPLugin target
+# ``Qt4::QtOpenGL``
+# The QtOpenGL target
+# ``Qt4::QtScript``
+# The QtScript target
+# ``Qt4::QtScriptTools``
+# The QtScriptTools target
+# ``Qt4::QtSql``
+# The QtSql target
+# ``Qt4::QtSvg``
+# The QtSvg target
+# ``Qt4::QtTest``
+# The QtTest target
+# ``Qt4::QtUiTools``
+# The QtUiTools target
+# ``Qt4::QtWebKit``
+# The QtWebKit target
+# ``Qt4::QtXml``
+# The QtXml target
+# ``Qt4::QtXmlPatterns``
+# The QtXmlPatterns target
+# ``Qt4::phonon``
+# The phonon target
+#
+# Result Variables
+# ^^^^^^^^^^^^^^^^
+#
+# Below is a detailed list of variables that FindQt4.cmake sets.
+#
+# ``Qt4_FOUND``
+# If false, don't try to use Qt 4.
+# ``QT_FOUND``
+# If false, don't try to use Qt. This variable is for compatibility only.
+# ``QT4_FOUND``
+# If false, don't try to use Qt 4. This variable is for compatibility only.
+# ``QT_VERSION_MAJOR``
+# The major version of Qt found.
+# ``QT_VERSION_MINOR``
+# The minor version of Qt found.
+# ``QT_VERSION_PATCH``
+# The patch version of Qt found.
#=============================================================================
# Copyright 2005-2009 Kitware, Inc.
@@ -392,6 +342,7 @@ endif()
include(${CMAKE_CURRENT_LIST_DIR}/CheckCXXSymbolExists.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/MacroAddFileDependencies.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake)
set(QT_USE_FILE ${CMAKE_ROOT}/Modules/UseQt4.cmake)
@@ -574,7 +525,21 @@ set(QT4_INSTALLED_VERSION_TOO_OLD FALSE)
set(_QT4_QMAKE_NAMES qmake qmake4 qmake-qt4 qmake-mac)
_qt4_find_qmake("${_QT4_QMAKE_NAMES}" QT_QMAKE_EXECUTABLE QTVERSION)
-if (QT_QMAKE_EXECUTABLE AND QTVERSION)
+if (QT_QMAKE_EXECUTABLE AND
+ QTVERSION VERSION_GREATER 3 AND QTVERSION VERSION_LESS 5)
+
+ if (Qt5Core_FOUND)
+ # Qt5CoreConfig sets QT_MOC_EXECUTABLE as a non-cache variable to the Qt 5
+ # path to moc. Unset that variable when Qt 4 and 5 are used together, so
+ # that when find_program looks for moc, it is not set to the Qt 5 version.
+ # If FindQt4 has already put the Qt 4 path in the cache, the unset()
+ # command 'unhides' the (correct) cache variable.
+ unset(QT_MOC_EXECUTABLE)
+ endif()
+ if (QT_QMAKE_EXECUTABLE_LAST)
+ string(COMPARE NOTEQUAL "${QT_QMAKE_EXECUTABLE_LAST}" "${QT_QMAKE_EXECUTABLE}" QT_QMAKE_CHANGED)
+ endif()
+ set(QT_QMAKE_EXECUTABLE_LAST "${QT_QMAKE_EXECUTABLE}" CACHE INTERNAL "" FORCE)
_qt4_get_version_components("${QTVERSION}" QT_VERSION_MAJOR QT_VERSION_MINOR QT_VERSION_PATCH)
@@ -594,7 +559,8 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
set(QT_MKSPECS_DIR NOTFOUND)
find_path(QT_MKSPECS_DIR NAMES qconfig.pri
HINTS ${qt_cross_paths} ${qt_mkspecs_dirs}
- DOC "The location of the Qt mkspecs containing qconfig.pri")
+ DOC "The location of the Qt mkspecs containing qconfig.pri"
+ NO_CMAKE_FIND_ROOT_PATH)
endif()
if(EXISTS "${QT_MKSPECS_DIR}/qconfig.pri")
@@ -656,9 +622,13 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
set(QT_LIBRARY_DIR ${QT_LIBRARY_DIR_TMP} CACHE INTERNAL "Qt library dir" FORCE)
set(QT_QTCORE_FOUND 1)
else()
- message(WARNING "${QT_QMAKE_EXECUTABLE} reported QT_INSTALL_LIBS as \"${QT_LIBRARY_DIR_TMP}\" "
- "but QtCore could not be found there. "
- "Qt is NOT installed correctly for the target build environment.")
+ if(NOT Qt4_FIND_QUIETLY)
+ message(WARNING
+ "${QT_QMAKE_EXECUTABLE} reported QT_INSTALL_LIBS as "
+ "\"${QT_LIBRARY_DIR_TMP}\" "
+ "but QtCore could not be found there. "
+ "Qt is NOT installed correctly for the target build environment.")
+ endif()
set(Qt4_FOUND FALSE)
if(Qt4_FIND_REQUIRED)
message( FATAL_ERROR "Could NOT find QtCore. Check ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log for more details.")
@@ -750,7 +720,8 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
endforeach()
find_path(QT_PLUGINS_DIR NAMES accessible imageformats sqldrivers codecs designer
HINTS ${qt_cross_paths} ${qt_plugins_dir}
- DOC "The location of the Qt plugins")
+ DOC "The location of the Qt plugins"
+ NO_CMAKE_FIND_ROOT_PATH)
endif ()
# ask qmake for the translations directory
@@ -770,6 +741,7 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
find_path(QT_IMPORTS_DIR NAMES Qt
HINTS ${qt_cross_paths} ${qt_imports_dir}
DOC "The location of the Qt imports"
+ NO_CMAKE_FIND_ROOT_PATH
NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)
mark_as_advanced(QT_IMPORTS_DIR)
@@ -788,11 +760,10 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
# Find out what window system we're using
#
#############################################
- # Save required variable
- set(CMAKE_REQUIRED_INCLUDES_SAVE ${CMAKE_REQUIRED_INCLUDES})
- set(CMAKE_REQUIRED_FLAGS_SAVE ${CMAKE_REQUIRED_FLAGS})
+ cmake_push_check_state()
# Add QT_INCLUDE_DIR to CMAKE_REQUIRED_INCLUDES
set(CMAKE_REQUIRED_INCLUDES "${CMAKE_REQUIRED_INCLUDES};${QT_INCLUDE_DIR}")
+ set(CMAKE_REQUIRED_QUIET ${Qt4_FIND_QUIETLY})
# Check for Window system symbols (note: only one should end up being set)
CHECK_CXX_SYMBOL_EXISTS(Q_WS_X11 "QtCore/qglobal.h" Q_WS_X11)
CHECK_CXX_SYMBOL_EXISTS(Q_WS_WIN "QtCore/qglobal.h" Q_WS_WIN)
@@ -812,9 +783,7 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
endif ()
endif ()
- # Restore CMAKE_REQUIRED_INCLUDES and CMAKE_REQUIRED_FLAGS variables
- set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES_SAVE})
- set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS_SAVE})
+ cmake_pop_check_state()
#
#############################################
@@ -1011,20 +980,24 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
endmacro()
macro(_qt4_add_target_depends _QT_MODULE)
- get_target_property(_configs Qt4::${_QT_MODULE} IMPORTED_CONFIGURATIONS)
- _qt4_add_target_depends_internal(${_QT_MODULE} INTERFACE_LINK_LIBRARIES ${ARGN})
- foreach(_config ${_configs})
- _qt4_add_target_depends_internal(${_QT_MODULE} IMPORTED_LINK_INTERFACE_LIBRARIES_${_config} ${ARGN})
- endforeach()
- set(_configs)
+ if (TARGET Qt4::${_QT_MODULE})
+ get_target_property(_configs Qt4::${_QT_MODULE} IMPORTED_CONFIGURATIONS)
+ _qt4_add_target_depends_internal(${_QT_MODULE} INTERFACE_LINK_LIBRARIES ${ARGN})
+ foreach(_config ${_configs})
+ _qt4_add_target_depends_internal(${_QT_MODULE} IMPORTED_LINK_INTERFACE_LIBRARIES_${_config} ${ARGN})
+ endforeach()
+ set(_configs)
+ endif()
endmacro()
macro(_qt4_add_target_private_depends _QT_MODULE)
- get_target_property(_configs ${_QT_MODULE} IMPORTED_CONFIGURATIONS)
- foreach(_config ${_configs})
- _qt4_add_target_depends_internal(${_QT_MODULE} IMPORTED_LINK_DEPENDENT_LIBRARIES_${_config} ${ARGN})
- endforeach()
- set(_configs)
+ if (TARGET Qt4::${_QT_MODULE})
+ get_target_property(_configs Qt4::${_QT_MODULE} IMPORTED_CONFIGURATIONS)
+ foreach(_config ${_configs})
+ _qt4_add_target_depends_internal(${_QT_MODULE} IMPORTED_LINK_DEPENDENT_LIBRARIES_${_config} ${ARGN})
+ endforeach()
+ set(_configs)
+ endif()
endmacro()
@@ -1036,6 +1009,10 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
"${QT_MKSPECS_DIR}/default"
${QT_INCLUDE_DIR}
)
+ set_property(TARGET Qt4::QtCore APPEND PROPERTY
+ INTERFACE_COMPILE_DEFINITIONS
+ $<$<NOT:$<CONFIG:Debug>>:QT_NO_DEBUG>
+ )
set_property(TARGET Qt4::QtCore PROPERTY
INTERFACE_QT_MAJOR_VERSION 4
)
@@ -1156,71 +1133,34 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
set(QT_LINGUIST_EXECUTABLE NOTFOUND)
endif()
- find_program(QT_MOC_EXECUTABLE
- NAMES moc-qt4 moc moc4
- PATHS ${QT_BINARY_DIR}
- NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
- )
-
- find_program(QT_UIC_EXECUTABLE
- NAMES uic-qt4 uic uic4
- PATHS ${QT_BINARY_DIR}
- NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
- )
-
- find_program(QT_UIC3_EXECUTABLE
- NAMES uic3
- PATHS ${QT_BINARY_DIR}
- NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
- )
-
- find_program(QT_RCC_EXECUTABLE
- NAMES rcc
- PATHS ${QT_BINARY_DIR}
- NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
- )
-
- find_program(QT_DBUSCPP2XML_EXECUTABLE
- NAMES qdbuscpp2xml
- PATHS ${QT_BINARY_DIR}
- NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
- )
-
- find_program(QT_DBUSXML2CPP_EXECUTABLE
- NAMES qdbusxml2cpp
- PATHS ${QT_BINARY_DIR}
- NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
- )
-
- find_program(QT_LUPDATE_EXECUTABLE
- NAMES lupdate-qt4 lupdate lupdate4
- PATHS ${QT_BINARY_DIR}
- NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
- )
-
- find_program(QT_LRELEASE_EXECUTABLE
- NAMES lrelease-qt4 lrelease lrelease4
- PATHS ${QT_BINARY_DIR}
- NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
- )
-
- find_program(QT_QCOLLECTIONGENERATOR_EXECUTABLE
- NAMES qcollectiongenerator-qt4 qcollectiongenerator
- PATHS ${QT_BINARY_DIR}
- NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
- )
-
- find_program(QT_DESIGNER_EXECUTABLE
- NAMES designer-qt4 designer designer4
- PATHS ${QT_BINARY_DIR}
- NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
- )
+ macro(_find_qt4_program VAR NAME)
+ find_program(${VAR}
+ NAMES ${ARGN}
+ PATHS ${QT_BINARY_DIR}
+ NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
+ )
+ if (${VAR} AND NOT TARGET ${NAME})
+ add_executable(${NAME} IMPORTED)
+ set_property(TARGET ${NAME} PROPERTY IMPORTED_LOCATION ${${VAR}})
+ endif()
+ endmacro()
- find_program(QT_LINGUIST_EXECUTABLE
- NAMES linguist-qt4 linguist linguist4
- PATHS ${QT_BINARY_DIR}
- NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
- )
+ _find_qt4_program(QT_MOC_EXECUTABLE Qt4::moc moc-qt4 moc4 moc)
+ _find_qt4_program(QT_UIC_EXECUTABLE Qt4::uic uic-qt4 uic4 uic)
+ _find_qt4_program(QT_UIC3_EXECUTABLE Qt4::uic3 uic3)
+ _find_qt4_program(QT_RCC_EXECUTABLE Qt4::rcc rcc)
+ _find_qt4_program(QT_DBUSCPP2XML_EXECUTABLE Qt4::qdbuscpp2xml qdbuscpp2xml)
+ _find_qt4_program(QT_DBUSXML2CPP_EXECUTABLE Qt4::qdbusxml2cpp qdbusxml2cpp)
+ _find_qt4_program(QT_LUPDATE_EXECUTABLE Qt4::lupdate lupdate-qt4 lupdate4 lupdate)
+ _find_qt4_program(QT_LRELEASE_EXECUTABLE Qt4::lrelease lrelease-qt4 lrelease4 lrelease)
+ _find_qt4_program(QT_QCOLLECTIONGENERATOR_EXECUTABLE Qt4::qcollectiongenerator qcollectiongenerator-qt4 qcollectiongenerator)
+ _find_qt4_program(QT_DESIGNER_EXECUTABLE Qt4::designer designer-qt4 designer4 designer)
+ _find_qt4_program(QT_LINGUIST_EXECUTABLE Qt4::linguist linguist-qt4 linguist4 linguist)
+
+ if (NOT TARGET Qt4::qmake)
+ add_executable(Qt4::qmake IMPORTED)
+ set_property(TARGET Qt4::qmake PROPERTY IMPORTED_LOCATION ${QT_QMAKE_EXECUTABLE})
+ endif()
if (QT_MOC_EXECUTABLE)
set(QT_WRAP_CPP "YES")
@@ -1260,14 +1200,14 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
set( QT_PLUGIN_TYPES accessible bearer codecs decorations designer gfxdrivers graphicssystems iconengines imageformats inputmethods mousedrivers phonon_backend script sqldrivers )
set( QT_ACCESSIBLE_PLUGINS qtaccessiblecompatwidgets qtaccessiblewidgets )
- set( QT_BEARER_PLUGINS qcorewlanbearer qgenericbearer )
+ set( QT_BEARER_PLUGINS qcorewlanbearer qgenericbearer qnativewifibearer )
set( QT_CODECS_PLUGINS qcncodecs qjpcodecs qkrcodecs qtwcodecs )
set( QT_DECORATIONS_PLUGINS qdecorationdefault qdecorationwindows )
set( QT_DESIGNER_PLUGINS arthurplugin containerextension customwidgetplugin phononwidgets qdeclarativeview qt3supportwidgets qwebview taskmenuextension worldtimeclockplugin )
set( QT_GRAPHICSDRIVERS_PLUGINS qgfxtransformed qgfxvnc qscreenvfb )
set( QT_GRAPHICSSYSTEMS_PLUGINS qglgraphicssystem qtracegraphicssystem )
set( QT_ICONENGINES_PLUGINS qsvgicon )
- set( QT_IMAGEFORMATS_PLUGINS qgif qjpeg qmng qico qsvg qtiff )
+ set( QT_IMAGEFORMATS_PLUGINS qgif qjpeg qmng qico qsvg qtiff qtga )
set( QT_INPUTMETHODS_PLUGINS qimsw_multi )
set( QT_MOUSEDRIVERS_PLUGINS qwstslibmousehandler )
if(APPLE)
@@ -1281,7 +1221,7 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
set( QT_PHONON_PLUGINS ${QT_PHONON_BACKEND_PLUGINS} )
set( QT_QT3SUPPORT_PLUGINS qtaccessiblecompatwidgets )
set( QT_QTCORE_PLUGINS ${QT_BEARER_PLUGINS} ${QT_CODECS_PLUGINS} )
- set( QT_QTGUI_PLUGINS qtaccessiblewidgets qgif qjpeg qmng qico qtiff ${QT_DECORATIONS_PLUGINS} ${QT_GRAPHICSDRIVERS_PLUGINS} ${QT_GRAPHICSSYSTEMS_PLUGINS} ${QT_INPUTMETHODS_PLUGINS} ${QT_MOUSEDRIVERS_PLUGINS} )
+ set( QT_QTGUI_PLUGINS qtaccessiblewidgets ${QT_IMAGEFORMATS_PLUGINS} ${QT_DECORATIONS_PLUGINS} ${QT_GRAPHICSDRIVERS_PLUGINS} ${QT_GRAPHICSSYSTEMS_PLUGINS} ${QT_INPUTMETHODS_PLUGINS} ${QT_MOUSEDRIVERS_PLUGINS} )
set( QT_QTSCRIPT_PLUGINS ${QT_SCRIPT_PLUGINS} )
set( QT_QTSQL_PLUGINS ${QT_SQLDRIVERS_PLUGINS} )
set( QT_QTSVG_PLUGINS qsvg qsvgicon )
@@ -1381,7 +1321,7 @@ endif()
if (NOT QT_VERSION_MAJOR EQUAL 4)
set(VERSION_MSG "Found unsuitable Qt version \"${QTVERSION}\" from ${QT_QMAKE_EXECUTABLE}")
- set(QT4_FOUND FALSE)
+ set(Qt4_FOUND FALSE)
if(Qt4_FIND_REQUIRED)
message( FATAL_ERROR "${VERSION_MSG}, this code requires Qt 4.x")
else()
diff --git a/Modules/FindQuickTime.cmake b/Modules/FindQuickTime.cmake
index 42a0dce77..27792691b 100644
--- a/Modules/FindQuickTime.cmake
+++ b/Modules/FindQuickTime.cmake
@@ -1,11 +1,15 @@
-# Locate QuickTime
-# This module defines
-# QUICKTIME_LIBRARY
+#.rst:
+# FindQuickTime
+# -------------
+#
+#
+#
+# Locate QuickTime This module defines QUICKTIME_LIBRARY
# QUICKTIME_FOUND, if false, do not try to link to gdal
# QUICKTIME_INCLUDE_DIR, where to find the headers
#
-# $QUICKTIME_DIR is an environment variable that would
-# correspond to the ./configure --prefix=$QUICKTIME_DIR
+# $QUICKTIME_DIR is an environment variable that would correspond to the
+# ./configure --prefix=$QUICKTIME_DIR
#
# Created by Eric Wing.
diff --git a/Modules/FindRTI.cmake b/Modules/FindRTI.cmake
index 60990b767..1aad0a80a 100644
--- a/Modules/FindRTI.cmake
+++ b/Modules/FindRTI.cmake
@@ -1,17 +1,32 @@
-# - Try to find M&S HLA RTI libraries
-# This module finds if any HLA RTI is installed and locates the standard RTI
-# include files and libraries.
+#.rst:
+# FindRTI
+# -------
+#
+# Try to find M&S HLA RTI libraries
+#
+# This module finds if any HLA RTI is installed and locates the standard
+# RTI include files and libraries.
+#
+# RTI is a simulation infrastructure standardized by IEEE and SISO. It
+# has a well defined C++ API that assures that simulation applications
+# are independent on a particular RTI implementation.
+#
+# ::
+#
+# http://en.wikipedia.org/wiki/Run-Time_Infrastructure_(simulation)
+#
#
-# RTI is a simulation infrastructure standardized by IEEE and SISO. It has a
-# well defined C++ API that assures that simulation applications are
-# independent on a particular RTI implementation.
-# http://en.wikipedia.org/wiki/Run-Time_Infrastructure_(simulation)
#
# This code sets the following variables:
-# RTI_INCLUDE_DIR = the directory where RTI includes file are found
-# RTI_LIBRARIES = The libraries to link against to use RTI
-# RTI_DEFINITIONS = -DRTI_USES_STD_FSTREAM
-# RTI_FOUND = Set to FALSE if any HLA RTI was not found
+#
+# ::
+#
+# RTI_INCLUDE_DIR = the directory where RTI includes file are found
+# RTI_LIBRARIES = The libraries to link against to use RTI
+# RTI_DEFINITIONS = -DRTI_USES_STD_FSTREAM
+# RTI_FOUND = Set to FALSE if any HLA RTI was not found
+#
+#
#
# Report problems to <certi-devel@nongnu.org>
diff --git a/Modules/FindRuby.cmake b/Modules/FindRuby.cmake
index c02158f13..e5ea210e1 100644
--- a/Modules/FindRuby.cmake
+++ b/Modules/FindRuby.cmake
@@ -1,20 +1,34 @@
-# - Find Ruby
-# This module finds if Ruby is installed and determines where the include files
-# and libraries are. Ruby 1.8 and 1.9 are supported.
+#.rst:
+# FindRuby
+# --------
+#
+# Find Ruby
+#
+# This module finds if Ruby is installed and determines where the
+# include files and libraries are. Ruby 1.8, 1.9, 2.0 and 2.1 are
+# supported.
#
# The minimum required version of Ruby can be specified using the
-# standard syntax, e.g. find_package(Ruby 1.8)
+# standard syntax, e.g. find_package(Ruby 1.8)
#
-# It also determines what the name of the library is. This
-# code sets the following variables:
+# It also determines what the name of the library is. This code sets
+# the following variables:
#
-# RUBY_EXECUTABLE = full path to the ruby binary
-# RUBY_INCLUDE_DIRS = include dirs to be used when using the ruby library
-# RUBY_LIBRARY = full path to the ruby library
-# RUBY_VERSION = the version of ruby which was found, e.g. "1.8.7"
-# RUBY_FOUND = set to true if ruby ws found successfully
+# ``RUBY_EXECUTABLE``
+# full path to the ruby binary
+# ``RUBY_INCLUDE_DIRS``
+# include dirs to be used when using the ruby library
+# ``RUBY_LIBRARY``
+# full path to the ruby library
+# ``RUBY_VERSION``
+# the version of ruby which was found, e.g. "1.8.7"
+# ``RUBY_FOUND``
+# set to true if ruby ws found successfully
#
-# RUBY_INCLUDE_PATH = same as RUBY_INCLUDE_DIRS, only provided for compatibility reasons, don't use it
+# Also:
+#
+# ``RUBY_INCLUDE_PATH``
+# same as RUBY_INCLUDE_DIRS, only provided for compatibility reasons, don't use it
#=============================================================================
# Copyright 2004-2009 Kitware, Inc.
@@ -44,7 +58,7 @@
set(_RUBY_POSSIBLE_EXECUTABLE_NAMES ruby)
# if 1.9 is required, don't look for ruby18 and ruby1.8, default to version 1.8
-if(Ruby_FIND_VERSION_MAJOR AND Ruby_FIND_VERSION_MINOR)
+if(DEFINED Ruby_FIND_VERSION_MAJOR AND DEFINED Ruby_FIND_VERSION_MINOR)
set(Ruby_FIND_VERSION_SHORT_NODOT "${Ruby_FIND_VERSION_MAJOR}${RUBY_FIND_VERSION_MINOR}")
# we can't construct that if only major version is given
set(_RUBY_POSSIBLE_EXECUTABLE_NAMES
@@ -56,6 +70,8 @@ else()
endif()
if(NOT Ruby_FIND_VERSION_EXACT)
+ list(APPEND _RUBY_POSSIBLE_EXECUTABLE_NAMES ruby2.1 ruby21)
+ list(APPEND _RUBY_POSSIBLE_EXECUTABLE_NAMES ruby2.0 ruby20)
list(APPEND _RUBY_POSSIBLE_EXECUTABLE_NAMES ruby1.9 ruby19)
# if we want a version below 1.9, also look for ruby 1.8
@@ -68,14 +84,13 @@ endif()
find_program(RUBY_EXECUTABLE NAMES ${_RUBY_POSSIBLE_EXECUTABLE_NAMES})
-
if(RUBY_EXECUTABLE AND NOT RUBY_VERSION_MAJOR)
function(_RUBY_CONFIG_VAR RBVAR OUTVAR)
execute_process(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print RbConfig::CONFIG['${RBVAR}']"
RESULT_VARIABLE _RUBY_SUCCESS
OUTPUT_VARIABLE _RUBY_OUTPUT
ERROR_QUIET)
- if(_RUBY_SUCCESS OR NOT _RUBY_OUTPUT)
+ if(_RUBY_SUCCESS OR _RUBY_OUTPUT STREQUAL "")
execute_process(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print Config::CONFIG['${RBVAR}']"
RESULT_VARIABLE _RUBY_SUCCESS
OUTPUT_VARIABLE _RUBY_OUTPUT
@@ -94,6 +109,7 @@ if(RUBY_EXECUTABLE AND NOT RUBY_VERSION_MAJOR)
_RUBY_CONFIG_VAR("archdir" RUBY_ARCH_DIR)
_RUBY_CONFIG_VAR("arch" RUBY_ARCH)
_RUBY_CONFIG_VAR("rubyhdrdir" RUBY_HDR_DIR)
+ _RUBY_CONFIG_VAR("rubyarchhdrdir" RUBY_ARCHHDR_DIR)
_RUBY_CONFIG_VAR("libdir" RUBY_POSSIBLE_LIB_DIR)
_RUBY_CONFIG_VAR("rubylibdir" RUBY_RUBY_LIB_DIR)
@@ -115,7 +131,8 @@ if(RUBY_EXECUTABLE AND NOT RUBY_VERSION_MAJOR)
set(RUBY_VERSION_MINOR ${RUBY_VERSION_MINOR} CACHE PATH "The Ruby minor version" FORCE)
set(RUBY_VERSION_PATCH ${RUBY_VERSION_PATCH} CACHE PATH "The Ruby patch version" FORCE)
set(RUBY_ARCH_DIR ${RUBY_ARCH_DIR} CACHE PATH "The Ruby arch dir" FORCE)
- set(RUBY_HDR_DIR ${RUBY_HDR_DIR} CACHE PATH "The Ruby header dir (1.9)" FORCE)
+ set(RUBY_HDR_DIR ${RUBY_HDR_DIR} CACHE PATH "The Ruby header dir (1.9+)" FORCE)
+ set(RUBY_ARCHHDR_DIR ${RUBY_ARCHHDR_DIR} CACHE PATH "The Ruby arch header dir (2.0+)" FORCE)
set(RUBY_POSSIBLE_LIB_DIR ${RUBY_POSSIBLE_LIB_DIR} CACHE PATH "The Ruby lib dir" FORCE)
set(RUBY_RUBY_LIB_DIR ${RUBY_RUBY_LIB_DIR} CACHE PATH "The Ruby ruby-lib dir" FORCE)
set(RUBY_SITEARCH_DIR ${RUBY_SITEARCH_DIR} CACHE PATH "The Ruby site arch dir" FORCE)
@@ -128,6 +145,7 @@ if(RUBY_EXECUTABLE AND NOT RUBY_VERSION_MAJOR)
RUBY_ARCH_DIR
RUBY_ARCH
RUBY_HDR_DIR
+ RUBY_ARCHHDR_DIR
RUBY_POSSIBLE_LIB_DIR
RUBY_RUBY_LIB_DIR
RUBY_SITEARCH_DIR
@@ -149,10 +167,20 @@ if(RUBY_EXECUTABLE AND NOT RUBY_VERSION_MAJOR)
set(RUBY_VERSION_MINOR 8)
set(RUBY_VERSION_PATCH 0)
# check whether we found 1.9.x
- if(${RUBY_EXECUTABLE} MATCHES "ruby1.?9" OR RUBY_HDR_DIR)
+ if(${RUBY_EXECUTABLE} MATCHES "ruby1.?9")
set(RUBY_VERSION_MAJOR 1)
set(RUBY_VERSION_MINOR 9)
endif()
+ # check whether we found 2.0.x
+ if(${RUBY_EXECUTABLE} MATCHES "ruby2.?0")
+ set(RUBY_VERSION_MAJOR 2)
+ set(RUBY_VERSION_MINOR 0)
+ endif()
+ # check whether we found 2.1.x
+ if(${RUBY_EXECUTABLE} MATCHES "ruby2.?1")
+ set(RUBY_VERSION_MAJOR 2)
+ set(RUBY_VERSION_MINOR 1)
+ endif()
endif()
if(RUBY_VERSION_MAJOR)
@@ -178,6 +206,7 @@ if( "${Ruby_FIND_VERSION_SHORT_NODOT}" GREATER 18 OR "${_RUBY_VERSION_SHORT_NO
HINTS
${RUBY_HDR_DIR}/${RUBY_ARCH}
${RUBY_ARCH_DIR}
+ ${RUBY_ARCHHDR_DIR}
)
set(RUBY_INCLUDE_DIRS ${RUBY_INCLUDE_DIRS} ${RUBY_CONFIG_INCLUDE_DIR} )
@@ -205,11 +234,16 @@ if(WIN32)
set( _RUBY_MSVC_RUNTIME "90" )
endif()
+ set(_RUBY_ARCH_PREFIX "")
+ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(_RUBY_ARCH_PREFIX "x64-")
+ endif()
+
list(APPEND _RUBY_POSSIBLE_LIB_NAMES
- "msvcr${_RUBY_MSVC_RUNTIME}-ruby${_RUBY_NODOT_VERSION}"
- "msvcr${_RUBY_MSVC_RUNTIME}-ruby${_RUBY_NODOT_VERSION}-static"
- "msvcrt-ruby${_RUBY_NODOT_VERSION}"
- "msvcrt-ruby${_RUBY_NODOT_VERSION}-static" )
+ "${_RUBY_ARCH_PREFIX}msvcr${_RUBY_MSVC_RUNTIME}-ruby${_RUBY_NODOT_VERSION}"
+ "${_RUBY_ARCH_PREFIX}msvcr${_RUBY_MSVC_RUNTIME}-ruby${_RUBY_NODOT_VERSION}-static"
+ "${_RUBY_ARCH_PREFIX}msvcrt-ruby${_RUBY_NODOT_VERSION}"
+ "${_RUBY_ARCH_PREFIX}msvcrt-ruby${_RUBY_NODOT_VERSION}-static" )
endif()
find_library(RUBY_LIBRARY NAMES ${_RUBY_POSSIBLE_LIB_NAMES} HINTS ${RUBY_POSSIBLE_LIB_DIR} )
diff --git a/Modules/FindSDL.cmake b/Modules/FindSDL.cmake
index fec142ed5..45ca1d449 100644
--- a/Modules/FindSDL.cmake
+++ b/Modules/FindSDL.cmake
@@ -1,57 +1,72 @@
-# - Locate SDL library
+#.rst:
+# FindSDL
+# -------
+#
+# Locate SDL library
+#
# This module defines
-# SDL_LIBRARY, the name of the library to link against
-# SDL_FOUND, if false, do not try to link to SDL
-# SDL_INCLUDE_DIR, where to find SDL.h
-# SDL_VERSION_STRING, human-readable string containing the version of SDL
-#
-# This module responds to the the flag:
-# SDL_BUILDING_LIBRARY
-# If this is defined, then no SDL_main will be linked in because
-# only applications need main().
-# Otherwise, it is assumed you are building an application and this
-# module will attempt to locate and set the the proper link flags
-# as part of the returned SDL_LIBRARY variable.
+#
+# ::
+#
+# SDL_LIBRARY, the name of the library to link against
+# SDL_FOUND, if false, do not try to link to SDL
+# SDL_INCLUDE_DIR, where to find SDL.h
+# SDL_VERSION_STRING, human-readable string containing the version of SDL
+#
+#
+#
+# This module responds to the flag:
+#
+# ::
+#
+# SDL_BUILDING_LIBRARY
+# If this is defined, then no SDL_main will be linked in because
+# only applications need main().
+# Otherwise, it is assumed you are building an application and this
+# module will attempt to locate and set the proper link flags
+# as part of the returned SDL_LIBRARY variable.
+#
+#
#
# Don't forget to include SDLmain.h and SDLmain.m your project for the
-# OS X framework based version. (Other versions link to -lSDLmain which
+# OS X framework based version. (Other versions link to -lSDLmain which
# this module will try to find on your behalf.) Also for OS X, this
# module will automatically add the -framework Cocoa on your behalf.
#
#
-# Additional Note: If you see an empty SDL_LIBRARY_TEMP in your configuration
-# and no SDL_LIBRARY, it means CMake did not find your SDL library
-# (SDL.dll, libsdl.so, SDL.framework, etc).
-# Set SDL_LIBRARY_TEMP to point to your SDL library, and configure again.
-# Similarly, if you see an empty SDLMAIN_LIBRARY, you should set this value
-# as appropriate. These values are used to generate the final SDL_LIBRARY
-# variable, but when these values are unset, SDL_LIBRARY does not get created.
+#
+# Additional Note: If you see an empty SDL_LIBRARY_TEMP in your
+# configuration and no SDL_LIBRARY, it means CMake did not find your SDL
+# library (SDL.dll, libsdl.so, SDL.framework, etc). Set
+# SDL_LIBRARY_TEMP to point to your SDL library, and configure again.
+# Similarly, if you see an empty SDLMAIN_LIBRARY, you should set this
+# value as appropriate. These values are used to generate the final
+# SDL_LIBRARY variable, but when these values are unset, SDL_LIBRARY
+# does not get created.
#
#
-# $SDLDIR is an environment variable that would
-# correspond to the ./configure --prefix=$SDLDIR
-# used in building SDL.
-# l.e.galup 9-20-02
#
-# Modified by Eric Wing.
-# Added code to assist with automated building by using environmental variables
-# and providing a more controlled/consistent search behavior.
-# Added new modifications to recognize OS X frameworks and
-# additional Unix paths (FreeBSD, etc).
-# Also corrected the header search path to follow "proper" SDL guidelines.
-# Added a search for SDLmain which is needed by some platforms.
-# Added a search for threads which is needed by some platforms.
-# Added needed compile switches for MinGW.
+# $SDLDIR is an environment variable that would correspond to the
+# ./configure --prefix=$SDLDIR used in building SDL. l.e.galup 9-20-02
+#
+# Modified by Eric Wing. Added code to assist with automated building
+# by using environmental variables and providing a more
+# controlled/consistent search behavior. Added new modifications to
+# recognize OS X frameworks and additional Unix paths (FreeBSD, etc).
+# Also corrected the header search path to follow "proper" SDL
+# guidelines. Added a search for SDLmain which is needed by some
+# platforms. Added a search for threads which is needed by some
+# platforms. Added needed compile switches for MinGW.
#
# On OSX, this will prefer the Framework version (if found) over others.
-# People will have to manually change the cache values of
-# SDL_LIBRARY to override this selection or set the CMake environment
+# People will have to manually change the cache values of SDL_LIBRARY to
+# override this selection or set the CMake environment
# CMAKE_INCLUDE_PATH to modify the search paths.
#
# Note that the header path has changed from SDL/SDL.h to just SDL.h
-# This needed to change because "proper" SDL convention
-# is #include "SDL.h", not <SDL/SDL.h>. This is done for portability
-# reasons because not all systems place things in SDL/ (see FreeBSD).
+# This needed to change because "proper" SDL convention is #include
+# "SDL.h", not <SDL/SDL.h>. This is done for portability reasons
+# because not all systems place things in SDL/ (see FreeBSD).
#=============================================================================
# Copyright 2003-2009 Kitware, Inc.
@@ -70,20 +85,28 @@
find_path(SDL_INCLUDE_DIR SDL.h
HINTS
ENV SDLDIR
- PATH_SUFFIXES include/SDL include/SDL12 include/SDL11 include
+ PATH_SUFFIXES SDL SDL12 SDL11
+ # path suffixes to search inside ENV{SDLDIR}
+ include/SDL include/SDL12 include/SDL11 include
)
+if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(VC_LIB_PATH_SUFFIX lib/x64)
+else()
+ set(VC_LIB_PATH_SUFFIX lib/x86)
+endif()
+
# SDL-1.1 is the name used by FreeBSD ports...
# don't confuse it for the version number.
find_library(SDL_LIBRARY_TEMP
NAMES SDL SDL-1.1
HINTS
ENV SDLDIR
- PATH_SUFFIXES lib
+ PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
)
if(NOT SDL_BUILDING_LIBRARY)
- if(NOT ${SDL_INCLUDE_DIR} MATCHES ".framework")
+ if(NOT SDL_INCLUDE_DIR MATCHES ".framework")
# Non-OS X framework versions expect you to also dynamically link to
# SDLmain. This is mainly for Windows and OS X. Other (Unix) platforms
# seem to provide SDLmain for compatibility even though they don't
@@ -92,7 +115,7 @@ if(NOT SDL_BUILDING_LIBRARY)
NAMES SDLmain SDLmain-1.1
HINTS
ENV SDLDIR
- PATH_SUFFIXES lib
+ PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
PATHS
/sw
/opt/local
diff --git a/Modules/FindSDL_image.cmake b/Modules/FindSDL_image.cmake
index 30d74acfb..49b5e40c1 100644
--- a/Modules/FindSDL_image.cmake
+++ b/Modules/FindSDL_image.cmake
@@ -1,20 +1,35 @@
-# - Locate SDL_image library
+#.rst:
+# FindSDL_image
+# -------------
+#
+# Locate SDL_image library
+#
# This module defines:
-# SDL_IMAGE_LIBRARIES, the name of the library to link against
-# SDL_IMAGE_INCLUDE_DIRS, where to find the headers
-# SDL_IMAGE_FOUND, if false, do not try to link against
-# SDL_IMAGE_VERSION_STRING - human-readable string containing the version of SDL_image
+#
+# ::
+#
+# SDL_IMAGE_LIBRARIES, the name of the library to link against
+# SDL_IMAGE_INCLUDE_DIRS, where to find the headers
+# SDL_IMAGE_FOUND, if false, do not try to link against
+# SDL_IMAGE_VERSION_STRING - human-readable string containing the
+# version of SDL_image
+#
+#
#
# For backward compatiblity the following variables are also set:
-# SDLIMAGE_LIBRARY (same value as SDL_IMAGE_LIBRARIES)
-# SDLIMAGE_INCLUDE_DIR (same value as SDL_IMAGE_INCLUDE_DIRS)
-# SDLIMAGE_FOUND (same value as SDL_IMAGE_FOUND)
#
-# $SDLDIR is an environment variable that would
-# correspond to the ./configure --prefix=$SDLDIR
-# used in building SDL.
+# ::
#
-# Created by Eric Wing. This was influenced by the FindSDL.cmake
+# SDLIMAGE_LIBRARY (same value as SDL_IMAGE_LIBRARIES)
+# SDLIMAGE_INCLUDE_DIR (same value as SDL_IMAGE_INCLUDE_DIRS)
+# SDLIMAGE_FOUND (same value as SDL_IMAGE_FOUND)
+#
+#
+#
+# $SDLDIR is an environment variable that would correspond to the
+# ./configure --prefix=$SDLDIR used in building SDL.
+#
+# Created by Eric Wing. This was influenced by the FindSDL.cmake
# module, but with modifications to recognize OS X frameworks and
# additional Unix paths (FreeBSD, etc).
@@ -40,9 +55,17 @@ find_path(SDL_IMAGE_INCLUDE_DIR SDL_image.h
HINTS
ENV SDLIMAGEDIR
ENV SDLDIR
- PATH_SUFFIXES include/SDL include/SDL12 include/SDL11 include
+ PATH_SUFFIXES SDL
+ # path suffixes to search inside ENV{SDLDIR}
+ include/SDL include/SDL12 include/SDL11 include
)
+if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(VC_LIB_PATH_SUFFIX lib/x64)
+else()
+ set(VC_LIB_PATH_SUFFIX lib/x86)
+endif()
+
if(NOT SDL_IMAGE_LIBRARY AND SDLIMAGE_LIBRARY)
set(SDL_IMAGE_LIBRARY ${SDLIMAGE_LIBRARY} CACHE FILEPATH "file cache entry
initialized from old variable name")
@@ -52,7 +75,7 @@ find_library(SDL_IMAGE_LIBRARY
HINTS
ENV SDLIMAGEDIR
ENV SDLDIR
- PATH_SUFFIXES lib
+ PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
)
if(SDL_IMAGE_INCLUDE_DIR AND EXISTS "${SDL_IMAGE_INCLUDE_DIR}/SDL_image.h")
diff --git a/Modules/FindSDL_mixer.cmake b/Modules/FindSDL_mixer.cmake
index 8ca7cc33c..9e11796f7 100644
--- a/Modules/FindSDL_mixer.cmake
+++ b/Modules/FindSDL_mixer.cmake
@@ -1,20 +1,35 @@
-# - Locate SDL_mixer library
+#.rst:
+# FindSDL_mixer
+# -------------
+#
+# Locate SDL_mixer library
+#
# This module defines:
-# SDL_MIXER_LIBRARIES, the name of the library to link against
-# SDL_MIXER_INCLUDE_DIRS, where to find the headers
-# SDL_MIXER_FOUND, if false, do not try to link against
-# SDL_MIXER_VERSION_STRING - human-readable string containing the version of SDL_mixer
+#
+# ::
+#
+# SDL_MIXER_LIBRARIES, the name of the library to link against
+# SDL_MIXER_INCLUDE_DIRS, where to find the headers
+# SDL_MIXER_FOUND, if false, do not try to link against
+# SDL_MIXER_VERSION_STRING - human-readable string containing the
+# version of SDL_mixer
+#
+#
#
# For backward compatiblity the following variables are also set:
-# SDLMIXER_LIBRARY (same value as SDL_MIXER_LIBRARIES)
-# SDLMIXER_INCLUDE_DIR (same value as SDL_MIXER_INCLUDE_DIRS)
-# SDLMIXER_FOUND (same value as SDL_MIXER_FOUND)
#
-# $SDLDIR is an environment variable that would
-# correspond to the ./configure --prefix=$SDLDIR
-# used in building SDL.
+# ::
#
-# Created by Eric Wing. This was influenced by the FindSDL.cmake
+# SDLMIXER_LIBRARY (same value as SDL_MIXER_LIBRARIES)
+# SDLMIXER_INCLUDE_DIR (same value as SDL_MIXER_INCLUDE_DIRS)
+# SDLMIXER_FOUND (same value as SDL_MIXER_FOUND)
+#
+#
+#
+# $SDLDIR is an environment variable that would correspond to the
+# ./configure --prefix=$SDLDIR used in building SDL.
+#
+# Created by Eric Wing. This was influenced by the FindSDL.cmake
# module, but with modifications to recognize OS X frameworks and
# additional Unix paths (FreeBSD, etc).
@@ -40,9 +55,17 @@ find_path(SDL_MIXER_INCLUDE_DIR SDL_mixer.h
HINTS
ENV SDLMIXERDIR
ENV SDLDIR
- PATH_SUFFIXES include/SDL include/SDL12 include/SDL11 include
+ PATH_SUFFIXES SDL
+ # path suffixes to search inside ENV{SDLDIR}
+ include/SDL include/SDL12 include/SDL11 include
)
+if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(VC_LIB_PATH_SUFFIX lib/x64)
+else()
+ set(VC_LIB_PATH_SUFFIX lib/x86)
+endif()
+
if(NOT SDL_MIXER_LIBRARY AND SDLMIXER_LIBRARY)
set(SDL_MIXER_LIBRARY ${SDLMIXER_LIBRARY} CACHE FILEPATH "file cache entry
initialized from old variable name")
@@ -52,7 +75,7 @@ find_library(SDL_MIXER_LIBRARY
HINTS
ENV SDLMIXERDIR
ENV SDLDIR
- PATH_SUFFIXES lib
+ PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
)
if(SDL_MIXER_INCLUDE_DIR AND EXISTS "${SDL_MIXER_INCLUDE_DIR}/SDL_mixer.h")
diff --git a/Modules/FindSDL_net.cmake b/Modules/FindSDL_net.cmake
index ca707af8d..ef23573e8 100644
--- a/Modules/FindSDL_net.cmake
+++ b/Modules/FindSDL_net.cmake
@@ -1,20 +1,34 @@
-# - Locate SDL_net library
+#.rst:
+# FindSDL_net
+# -----------
+#
+# Locate SDL_net library
+#
# This module defines:
-# SDL_NET_LIBRARIES, the name of the library to link against
-# SDL_NET_INCLUDE_DIRS, where to find the headers
-# SDL_NET_FOUND, if false, do not try to link against
-# SDL_NET_VERSION_STRING - human-readable string containing the version of SDL_net
+#
+# ::
+#
+# SDL_NET_LIBRARIES, the name of the library to link against
+# SDL_NET_INCLUDE_DIRS, where to find the headers
+# SDL_NET_FOUND, if false, do not try to link against
+# SDL_NET_VERSION_STRING - human-readable string containing the version of SDL_net
+#
+#
#
# For backward compatiblity the following variables are also set:
-# SDLNET_LIBRARY (same value as SDL_NET_LIBRARIES)
-# SDLNET_INCLUDE_DIR (same value as SDL_NET_INCLUDE_DIRS)
-# SDLNET_FOUND (same value as SDL_NET_FOUND)
#
-# $SDLDIR is an environment variable that would
-# correspond to the ./configure --prefix=$SDLDIR
-# used in building SDL.
+# ::
#
-# Created by Eric Wing. This was influenced by the FindSDL.cmake
+# SDLNET_LIBRARY (same value as SDL_NET_LIBRARIES)
+# SDLNET_INCLUDE_DIR (same value as SDL_NET_INCLUDE_DIRS)
+# SDLNET_FOUND (same value as SDL_NET_FOUND)
+#
+#
+#
+# $SDLDIR is an environment variable that would correspond to the
+# ./configure --prefix=$SDLDIR used in building SDL.
+#
+# Created by Eric Wing. This was influenced by the FindSDL.cmake
# module, but with modifications to recognize OS X frameworks and
# additional Unix paths (FreeBSD, etc).
@@ -40,9 +54,17 @@ find_path(SDL_NET_INCLUDE_DIR SDL_net.h
HINTS
ENV SDLNETDIR
ENV SDLDIR
- PATH_SUFFIXES include/SDL include/SDL12 include/SDL11 include
+ PATH_SUFFIXES SDL
+ # path suffixes to search inside ENV{SDLDIR}
+ include/SDL include/SDL12 include/SDL11 include
)
+if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(VC_LIB_PATH_SUFFIX lib/x64)
+else()
+ set(VC_LIB_PATH_SUFFIX lib/x86)
+endif()
+
if(NOT SDL_NET_LIBRARY AND SDLNET_LIBRARY)
set(SDL_NET_LIBRARY ${SDLNET_LIBRARY} CACHE FILEPATH "file cache entry
initialized from old variable name")
@@ -52,7 +74,7 @@ find_library(SDL_NET_LIBRARY
HINTS
ENV SDLNETDIR
ENV SDLDIR
- PATH_SUFFIXES lib
+ PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
)
if(SDL_NET_INCLUDE_DIR AND EXISTS "${SDL_NET_INCLUDE_DIR}/SDL_net.h")
diff --git a/Modules/FindSDL_sound.cmake b/Modules/FindSDL_sound.cmake
index efd26580b..494d358b3 100644
--- a/Modules/FindSDL_sound.cmake
+++ b/Modules/FindSDL_sound.cmake
@@ -1,59 +1,81 @@
-# - Locates the SDL_sound library
+#.rst:
+# FindSDL_sound
+# -------------
#
-# This module depends on SDL being found and
-# must be called AFTER FindSDL.cmake is called.
+# Locates the SDL_sound library
+#
+#
+#
+# This module depends on SDL being found and must be called AFTER
+# FindSDL.cmake is called.
#
# This module defines
-# SDL_SOUND_INCLUDE_DIR, where to find SDL_sound.h
-# SDL_SOUND_FOUND, if false, do not try to link to SDL_sound
-# SDL_SOUND_LIBRARIES, this contains the list of libraries that you need
-# to link against. This is a read-only variable and is marked INTERNAL.
-# SDL_SOUND_EXTRAS, this is an optional variable for you to add your own
-# flags to SDL_SOUND_LIBRARIES. This is prepended to SDL_SOUND_LIBRARIES.
-# This is available mostly for cases this module failed to anticipate for
-# and you must add additional flags. This is marked as ADVANCED.
-# SDL_SOUND_VERSION_STRING, human-readable string containing the version of SDL_sound
+#
+# ::
+#
+# SDL_SOUND_INCLUDE_DIR, where to find SDL_sound.h
+# SDL_SOUND_FOUND, if false, do not try to link to SDL_sound
+# SDL_SOUND_LIBRARIES, this contains the list of libraries that you need
+# to link against. This is a read-only variable and is marked INTERNAL.
+# SDL_SOUND_EXTRAS, this is an optional variable for you to add your own
+# flags to SDL_SOUND_LIBRARIES. This is prepended to SDL_SOUND_LIBRARIES.
+# This is available mostly for cases this module failed to anticipate for
+# and you must add additional flags. This is marked as ADVANCED.
+# SDL_SOUND_VERSION_STRING, human-readable string containing the
+# version of SDL_sound
+#
+#
#
# This module also defines (but you shouldn't need to use directly)
-# SDL_SOUND_LIBRARY, the name of just the SDL_sound library you would link
-# against. Use SDL_SOUND_LIBRARIES for you link instructions and not this one.
+#
+# ::
+#
+# SDL_SOUND_LIBRARY, the name of just the SDL_sound library you would link
+# against. Use SDL_SOUND_LIBRARIES for you link instructions and not this one.
+#
# And might define the following as needed
-# MIKMOD_LIBRARY
-# MODPLUG_LIBRARY
-# OGG_LIBRARY
-# VORBIS_LIBRARY
-# SMPEG_LIBRARY
-# FLAC_LIBRARY
-# SPEEX_LIBRARY
#
-# Typically, you should not use these variables directly, and you should use
-# SDL_SOUND_LIBRARIES which contains SDL_SOUND_LIBRARY and the other audio libraries
-# (if needed) to successfully compile on your system.
+# ::
+#
+# MIKMOD_LIBRARY
+# MODPLUG_LIBRARY
+# OGG_LIBRARY
+# VORBIS_LIBRARY
+# SMPEG_LIBRARY
+# FLAC_LIBRARY
+# SPEEX_LIBRARY
+#
+#
+#
+# Typically, you should not use these variables directly, and you should
+# use SDL_SOUND_LIBRARIES which contains SDL_SOUND_LIBRARY and the other
+# audio libraries (if needed) to successfully compile on your system.
#
-# Created by Eric Wing.
-# This module is a bit more complicated than the other FindSDL* family modules.
-# The reason is that SDL_sound can be compiled in a large variety of different ways
-# which are independent of platform. SDL_sound may dynamically link against other 3rd
-# party libraries to get additional codec support, such as Ogg Vorbis, SMPEG, ModPlug,
-# MikMod, FLAC, Speex, and potentially others.
-# Under some circumstances which I don't fully understand,
-# there seems to be a requirement
-# that dependent libraries of libraries you use must also be explicitly
-# linked against in order to successfully compile. SDL_sound does not currently
-# have any system in place to know how it was compiled.
-# So this CMake module does the hard work in trying to discover which 3rd party
-# libraries are required for building (if any).
-# This module uses a brute force approach to create a test program that uses SDL_sound,
-# and then tries to build it. If the build fails, it parses the error output for
-# known symbol names to figure out which libraries are needed.
+# Created by Eric Wing. This module is a bit more complicated than the
+# other FindSDL* family modules. The reason is that SDL_sound can be
+# compiled in a large variety of different ways which are independent of
+# platform. SDL_sound may dynamically link against other 3rd party
+# libraries to get additional codec support, such as Ogg Vorbis, SMPEG,
+# ModPlug, MikMod, FLAC, Speex, and potentially others. Under some
+# circumstances which I don't fully understand, there seems to be a
+# requirement that dependent libraries of libraries you use must also be
+# explicitly linked against in order to successfully compile. SDL_sound
+# does not currently have any system in place to know how it was
+# compiled. So this CMake module does the hard work in trying to
+# discover which 3rd party libraries are required for building (if any).
+# This module uses a brute force approach to create a test program that
+# uses SDL_sound, and then tries to build it. If the build fails, it
+# parses the error output for known symbol names to figure out which
+# libraries are needed.
#
-# Responds to the $SDLDIR and $SDLSOUNDDIR environmental variable that would
-# correspond to the ./configure --prefix=$SDLDIR used in building SDL.
+# Responds to the $SDLDIR and $SDLSOUNDDIR environmental variable that
+# would correspond to the ./configure --prefix=$SDLDIR used in building
+# SDL.
#
# On OSX, this will prefer the Framework version (if found) over others.
-# People will have to manually change the cache values of
-# SDL_LIBRARY to override this selectionor set the CMake environment
-# CMAKE_INCLUDE_PATH to modify the search paths.
+# People will have to manually change the cache values of SDL_LIBRARY to
+# override this selectionor set the CMake environment CMAKE_INCLUDE_PATH
+# to modify the search paths.
#=============================================================================
# Copyright 2005-2009 Kitware, Inc.
@@ -77,7 +99,9 @@ find_path(SDL_SOUND_INCLUDE_DIR SDL_sound.h
HINTS
ENV SDLSOUNDDIR
ENV SDLDIR
- PATH_SUFFIXES include/SDL include/SDL12 include/SDL11 include
+ PATH_SUFFIXES SDL
+ # path suffixes to search inside ENV{SDLDIR}
+ include/SDL include/SDL12 include/SDL11 include
)
find_library(SDL_SOUND_LIBRARY
@@ -85,7 +109,7 @@ find_library(SDL_SOUND_LIBRARY
HINTS
ENV SDLSOUNDDIR
ENV SDLDIR
- PATH_SUFFIXES lib
+ PATH_SUFFIXES lib VisualC/win32lib
)
if(SDL_FOUND AND SDL_SOUND_INCLUDE_DIR AND SDL_SOUND_LIBRARY)
@@ -160,7 +184,7 @@ if(SDL_FOUND AND SDL_SOUND_INCLUDE_DIR AND SDL_SOUND_LIBRARY)
# in the SDL_LIBRARY string after the "-framework".
# But if I quote the stuff in INCLUDE_DIRECTORIES, it doesn't work.
file(WRITE ${PROJECT_BINARY_DIR}/CMakeTmp/CMakeLists.txt
- "cmake_minimum_required(VERSION 2.8)
+ "cmake_minimum_required(VERSION ${CMAKE_VERSION})
project(DetermineSoundLibs)
include_directories(${SDL_INCLUDE_DIR} ${SDL_SOUND_INCLUDE_DIR})
add_executable(DetermineSoundLibs DetermineSoundLibs.c)
diff --git a/Modules/FindSDL_ttf.cmake b/Modules/FindSDL_ttf.cmake
index bb0ca9147..4b527fabe 100644
--- a/Modules/FindSDL_ttf.cmake
+++ b/Modules/FindSDL_ttf.cmake
@@ -1,20 +1,34 @@
-# - Locate SDL_ttf library
+#.rst:
+# FindSDL_ttf
+# -----------
+#
+# Locate SDL_ttf library
+#
# This module defines:
-# SDL_TTF_LIBRARIES, the name of the library to link against
-# SDL_TTF_INCLUDE_DIRS, where to find the headers
-# SDL_TTF_FOUND, if false, do not try to link against
-# SDL_TTF_VERSION_STRING - human-readable string containing the version of SDL_ttf
+#
+# ::
+#
+# SDL_TTF_LIBRARIES, the name of the library to link against
+# SDL_TTF_INCLUDE_DIRS, where to find the headers
+# SDL_TTF_FOUND, if false, do not try to link against
+# SDL_TTF_VERSION_STRING - human-readable string containing the version of SDL_ttf
+#
+#
#
# For backward compatiblity the following variables are also set:
-# SDLTTF_LIBRARY (same value as SDL_TTF_LIBRARIES)
-# SDLTTF_INCLUDE_DIR (same value as SDL_TTF_INCLUDE_DIRS)
-# SDLTTF_FOUND (same value as SDL_TTF_FOUND)
#
-# $SDLDIR is an environment variable that would
-# correspond to the ./configure --prefix=$SDLDIR
-# used in building SDL.
+# ::
#
-# Created by Eric Wing. This was influenced by the FindSDL.cmake
+# SDLTTF_LIBRARY (same value as SDL_TTF_LIBRARIES)
+# SDLTTF_INCLUDE_DIR (same value as SDL_TTF_INCLUDE_DIRS)
+# SDLTTF_FOUND (same value as SDL_TTF_FOUND)
+#
+#
+#
+# $SDLDIR is an environment variable that would correspond to the
+# ./configure --prefix=$SDLDIR used in building SDL.
+#
+# Created by Eric Wing. This was influenced by the FindSDL.cmake
# module, but with modifications to recognize OS X frameworks and
# additional Unix paths (FreeBSD, etc).
@@ -40,9 +54,17 @@ find_path(SDL_TTF_INCLUDE_DIR SDL_ttf.h
HINTS
ENV SDLTTFDIR
ENV SDLDIR
- PATH_SUFFIXES include/SDL include/SDL12 include/SDL11 include
+ PATH_SUFFIXES SDL
+ # path suffixes to search inside ENV{SDLDIR}
+ include/SDL include/SDL12 include/SDL11 include
)
+if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(VC_LIB_PATH_SUFFIX lib/x64)
+else()
+ set(VC_LIB_PATH_SUFFIX lib/x86)
+endif()
+
if(NOT SDL_TTF_LIBRARY AND SDLTTF_LIBRARY)
set(SDL_TTF_LIBRARY ${SDLTTF_LIBRARY} CACHE FILEPATH "file cache entry
initialized from old variable name")
@@ -52,7 +74,7 @@ find_library(SDL_TTF_LIBRARY
HINTS
ENV SDLTTFDIR
ENV SDLDIR
- PATH_SUFFIXES lib
+ PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
)
if(SDL_TTF_INCLUDE_DIR AND EXISTS "${SDL_TTF_INCLUDE_DIR}/SDL_ttf.h")
diff --git a/Modules/FindSWIG.cmake b/Modules/FindSWIG.cmake
index db60b888c..818d1f213 100644
--- a/Modules/FindSWIG.cmake
+++ b/Modules/FindSWIG.cmake
@@ -1,21 +1,31 @@
-# - Find SWIG
+#.rst:
+# FindSWIG
+# --------
+#
+# Find SWIG
+#
# This module finds an installed SWIG. It sets the following variables:
-# SWIG_FOUND - set to true if SWIG is found
-# SWIG_DIR - the directory where swig is installed
-# SWIG_EXECUTABLE - the path to the swig executable
-# SWIG_VERSION - the version number of the swig executable
#
-# The minimum required version of SWIG can be specified using the
-# standard syntax, e.g. find_package(SWIG 1.1)
+# ::
+#
+# SWIG_FOUND - set to true if SWIG is found
+# SWIG_DIR - the directory where swig is installed
+# SWIG_EXECUTABLE - the path to the swig executable
+# SWIG_VERSION - the version number of the swig executable
#
-# All information is collected from the SWIG_EXECUTABLE so the
-# version to be found can be changed from the command line by
-# means of setting SWIG_EXECUTABLE
#
+#
+# The minimum required version of SWIG can be specified using the
+# standard syntax, e.g. find_package(SWIG 1.1)
+#
+# All information is collected from the SWIG_EXECUTABLE so the version
+# to be found can be changed from the command line by means of setting
+# SWIG_EXECUTABLE
#=============================================================================
# Copyright 2004-2009 Kitware, Inc.
# Copyright 2011 Mathieu Malaterre <mathieu.malaterre@gmail.com>
+# Copyright 2014 Sylvain Joubert <joubert.sy@gmail.com>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
@@ -27,7 +37,7 @@
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
-find_program(SWIG_EXECUTABLE NAMES swig2.0 swig)
+find_program(SWIG_EXECUTABLE NAMES swig3.0 swig2.0 swig)
if(SWIG_EXECUTABLE)
execute_process(COMMAND ${SWIG_EXECUTABLE} -swiglib
@@ -43,11 +53,9 @@ if(SWIG_EXECUTABLE)
endif()
else()
string(REGEX REPLACE "[\n\r]+" ";" SWIG_swiglib_output ${SWIG_swiglib_output})
- # force the path to be computed each time in case SWIG_EXECUTABLE has changed.
- set(SWIG_DIR SWIG_DIR-NOTFOUND)
- find_path(SWIG_DIR swig.swg PATHS ${SWIG_swiglib_output})
+ find_path(SWIG_DIR swig.swg PATHS ${SWIG_swiglib_output} NO_CMAKE_FIND_ROOT_PATH)
if(SWIG_DIR)
- set(SWIG_USE_FILE ${CMAKE_ROOT}/Modules/UseSWIG.cmake)
+ set(SWIG_USE_FILE ${CMAKE_CURRENT_LIST_DIR}/UseSWIG.cmake)
execute_process(COMMAND ${SWIG_EXECUTABLE} -version
OUTPUT_VARIABLE SWIG_version_output
ERROR_VARIABLE SWIG_version_output
@@ -66,3 +74,5 @@ endif()
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SWIG REQUIRED_VARS SWIG_EXECUTABLE SWIG_DIR
VERSION_VAR SWIG_VERSION )
+
+mark_as_advanced(SWIG_DIR SWIG_VERSION)
diff --git a/Modules/FindSelfPackers.cmake b/Modules/FindSelfPackers.cmake
index fd2864251..238be89a0 100644
--- a/Modules/FindSelfPackers.cmake
+++ b/Modules/FindSelfPackers.cmake
@@ -1,9 +1,16 @@
-# - Find upx
-# This module looks for some executable packers (i.e. software that
+#.rst:
+# FindSelfPackers
+# ---------------
+#
+# Find upx
+#
+# This module looks for some executable packers (i.e. software that
# compress executables or shared libs into on-the-fly self-extracting
-# executables or shared libs.
-# Examples:
-# UPX: http://wildsau.idv.uni-linz.ac.at/mfx/upx.html
+# executables or shared libs. Examples:
+#
+# ::
+#
+# UPX: http://wildsau.idv.uni-linz.ac.at/mfx/upx.html
#=============================================================================
# Copyright 2001-2009 Kitware, Inc.
diff --git a/Modules/FindSquish.cmake b/Modules/FindSquish.cmake
index b79780577..51e279d23 100644
--- a/Modules/FindSquish.cmake
+++ b/Modules/FindSquish.cmake
@@ -1,63 +1,120 @@
+#.rst:
+# FindSquish
+# ----------
#
-# ---- Find Squish
-# This module can be used to find Squish. Currently Squish versions 3 and 4 are supported.
+# -- Typical Use
#
-# ---- Variables and Macros
-# SQUISH_FOUND If false, don't try to use Squish
-# SQUISH_VERSION The full version of Squish found
-# SQUISH_VERSION_MAJOR The major version of Squish found
-# SQUISH_VERSION_MINOR The minor version of Squish found
-# SQUISH_VERSION_PATCH The patch version of Squish found
#
-# SQUISH_INSTALL_DIR The Squish installation directory (containing bin, lib, etc)
-# SQUISH_SERVER_EXECUTABLE The squishserver executable
-# SQUISH_CLIENT_EXECUTABLE The squishrunner executable
#
-# SQUISH_INSTALL_DIR_FOUND Was the install directory found?
-# SQUISH_SERVER_EXECUTABLE_FOUND Was the server executable found?
-# SQUISH_CLIENT_EXECUTABLE_FOUND Was the client executable found?
+# This module can be used to find Squish. Currently Squish versions 3
+# and 4 are supported.
+#
+# ::
+#
+# SQUISH_FOUND If false, don't try to use Squish
+# SQUISH_VERSION The full version of Squish found
+# SQUISH_VERSION_MAJOR The major version of Squish found
+# SQUISH_VERSION_MINOR The minor version of Squish found
+# SQUISH_VERSION_PATCH The patch version of Squish found
+#
+#
+#
+# ::
+#
+# SQUISH_INSTALL_DIR The Squish installation directory
+# (containing bin, lib, etc)
+# SQUISH_SERVER_EXECUTABLE The squishserver executable
+# SQUISH_CLIENT_EXECUTABLE The squishrunner executable
+#
+#
+#
+# ::
+#
+# SQUISH_INSTALL_DIR_FOUND Was the install directory found?
+# SQUISH_SERVER_EXECUTABLE_FOUND Was the server executable found?
+# SQUISH_CLIENT_EXECUTABLE_FOUND Was the client executable found?
+#
+#
+#
+# It provides the function squish_v4_add_test() for adding a squish test
+# to cmake using Squish 4.x:
+#
+# ::
+#
+# squish_v4_add_test(cmakeTestName
+# AUT targetName SUITE suiteName TEST squishTestName
+# [SETTINGSGROUP group] [PRE_COMMAND command] [POST_COMMAND command] )
#
-# It provides the function squish_v4_add_test() for adding a squish test to cmake using Squish 4.x:
#
-# squish_v4_add_test(cmakeTestName AUT targetName SUITE suiteName TEST squishTestName
-# [SETTINGSGROUP group] [PRE_COMMAND command] [POST_COMMAND command] )
#
# The arguments have the following meaning:
-# cmakeTestName: this will be used as the first argument for add_test()
-# AUT targetName: the name of the cmake target which will be used as AUT, i.e. the
-# executable which will be tested.
-# SUITE suiteName: this is either the full path to the squish suite, or just the
-# last directory of the suite, i.e. the suite name. In this case
-# the CMakeLists.txt which calls squish_add_test() must be located
-# in the parent directory of the suite directory.
-# TEST squishTestName: the name of the squish test, i.e. the name of the subdirectory
-# of the test inside the suite directory.
-# SETTINGSGROUP group: if specified, the given settings group will be used for executing the test.
-# If not specified, the groupname will be "CTest_<username>"
-# PRE_COMMAND command: if specified, the given command will be executed before starting the squish test.
-# POST_COMMAND command: same as PRE_COMMAND, but after the squish test has been executed.
-#
-# ---- Typical Use
+#
+# ``cmakeTestName``
+# this will be used as the first argument for add_test()
+# ``AUT targetName``
+# the name of the cmake target which will be used as AUT, i.e. the
+# executable which will be tested.
+# ``SUITE suiteName``
+# this is either the full path to the squish suite, or just the
+# last directory of the suite, i.e. the suite name. In this case
+# the CMakeLists.txt which calls squish_add_test() must be located
+# in the parent directory of the suite directory.
+# ``TEST squishTestName``
+# the name of the squish test, i.e. the name of the subdirectory
+# of the test inside the suite directory.
+# ``SETTINGSGROUP group``
+# if specified, the given settings group will be used for executing the test.
+# If not specified, the groupname will be "CTest_<username>"
+# ``PRE_COMMAND command``
+# if specified, the given command will be executed before starting the squish test.
+# ``POST_COMMAND command``
+# same as PRE_COMMAND, but after the squish test has been executed.
+#
+#
+#
+# ::
+#
+# enable_testing()
+# find_package(Squish 4.0)
+# if (SQUISH_FOUND)
+# squish_v4_add_test(myTestName
+# AUT myApp
+# SUITE ${CMAKE_SOURCE_DIR}/tests/mySuite
+# TEST someSquishTest
+# SETTINGSGROUP myGroup
+# )
+# endif ()
+#
+#
+#
+#
+#
+# For users of Squish version 3.x the macro squish_v3_add_test() is
+# provided:
+#
+# ::
+#
+# squish_v3_add_test(testName applicationUnderTest testCase envVars testWrapper)
+# Use this macro to add a test using Squish 3.x.
+#
+#
+#
+# ::
+#
# enable_testing()
-# find_package(Squish 4.0)
+# find_package(Squish)
# if (SQUISH_FOUND)
-# squish_v4_add_test(myTestName AUT myApp SUITE ${CMAKE_SOURCE_DIR}/tests/mySuite TEST someSquishTest SETTINGSGROUP myGroup )
+# squish_v3_add_test(myTestName myApplication testCase envVars testWrapper)
# endif ()
#
#
-# For users of Squish version 3.x the macro squish_v3_add_test() is provided:
-# squish_v3_add_test(testName applicationUnderTest testCase envVars testWrapper)
-# Use this macro to add a test using Squish 3.x.
#
-# ---- Typical Use
-# enable_testing()
-# find_package(Squish)
-# if (SQUISH_FOUND)
-# squish_v3_add_test(myTestName myApplication testCase envVars testWrapper)
-# endif ()
+# macro SQUISH_ADD_TEST(testName applicationUnderTest testCase envVars
+# testWrapper)
+#
+# ::
#
-# macro SQUISH_ADD_TEST(testName applicationUnderTest testCase envVars testWrapper)
-# This is deprecated. Use SQUISH_V3_ADD_TEST() if you are using Squish 3.x instead.
+# This is deprecated. Use SQUISH_V3_ADD_TEST() if you are using Squish 3.x instead.
#=============================================================================
@@ -139,7 +196,7 @@ if(SQUISH_CLIENT_EXECUTABLE)
execute_process(COMMAND "${SQUISH_CLIENT_EXECUTABLE}" --version
OUTPUT_VARIABLE _squishVersionOutput
ERROR_QUIET )
- if("${_squishVersionOutput}" MATCHES "([0-9]+)\\.([0-9]+)\\.([0-9]+).*$")
+ if("${_squishVersionOutput}" MATCHES "([0-9]+)\\.([0-9]+)\\.([0-9]+)")
set(SQUISH_VERSION_MAJOR "${CMAKE_MATCH_1}")
set(SQUISH_VERSION_MINOR "${CMAKE_MATCH_2}")
set(SQUISH_VERSION_PATCH "${CMAKE_MATCH_3}")
@@ -156,7 +213,7 @@ else()
endif()
# record if Squish was found
-include(FindPackageHandleStandardArgs)
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
find_package_handle_standard_args(Squish REQUIRED_VARS SQUISH_INSTALL_DIR SQUISH_CLIENT_EXECUTABLE SQUISH_SERVER_EXECUTABLE
VERSION_VAR SQUISH_VERSION )
diff --git a/Modules/FindSubversion.cmake b/Modules/FindSubversion.cmake
index f1bfc75bc..0d13318bd 100644
--- a/Modules/FindSubversion.cmake
+++ b/Modules/FindSubversion.cmake
@@ -1,37 +1,62 @@
-# - Extract information from a subversion working copy
+#.rst:
+# FindSubversion
+# --------------
+#
+# Extract information from a subversion working copy
+#
# The module defines the following variables:
-# Subversion_SVN_EXECUTABLE - path to svn command line client
-# Subversion_VERSION_SVN - version of svn command line client
-# Subversion_FOUND - true if the command line client was found
-# SUBVERSION_FOUND - same as Subversion_FOUND, set for compatiblity reasons
+#
+# ::
+#
+# Subversion_SVN_EXECUTABLE - path to svn command line client
+# Subversion_VERSION_SVN - version of svn command line client
+# Subversion_FOUND - true if the command line client was found
+# SUBVERSION_FOUND - same as Subversion_FOUND, set for compatiblity reasons
+#
+#
#
# The minimum required version of Subversion can be specified using the
-# standard syntax, e.g. find_package(Subversion 1.4)
+# standard syntax, e.g. find_package(Subversion 1.4)
#
# If the command line client executable is found two macros are defined:
-# Subversion_WC_INFO(<dir> <var-prefix>)
-# Subversion_WC_LOG(<dir> <var-prefix>)
-# Subversion_WC_INFO extracts information of a subversion working copy at
-# a given location. This macro defines the following variables:
-# <var-prefix>_WC_URL - url of the repository (at <dir>)
-# <var-prefix>_WC_ROOT - root url of the repository
-# <var-prefix>_WC_REVISION - current revision
-# <var-prefix>_WC_LAST_CHANGED_AUTHOR - author of last commit
-# <var-prefix>_WC_LAST_CHANGED_DATE - date of last commit
-# <var-prefix>_WC_LAST_CHANGED_REV - revision of last commit
-# <var-prefix>_WC_INFO - output of command `svn info <dir>'
+#
+# ::
+#
+# Subversion_WC_INFO(<dir> <var-prefix>)
+# Subversion_WC_LOG(<dir> <var-prefix>)
+#
+# Subversion_WC_INFO extracts information of a subversion working copy
+# at a given location. This macro defines the following variables:
+#
+# ::
+#
+# <var-prefix>_WC_URL - url of the repository (at <dir>)
+# <var-prefix>_WC_ROOT - root url of the repository
+# <var-prefix>_WC_REVISION - current revision
+# <var-prefix>_WC_LAST_CHANGED_AUTHOR - author of last commit
+# <var-prefix>_WC_LAST_CHANGED_DATE - date of last commit
+# <var-prefix>_WC_LAST_CHANGED_REV - revision of last commit
+# <var-prefix>_WC_INFO - output of command `svn info <dir>'
+#
# Subversion_WC_LOG retrieves the log message of the base revision of a
-# subversion working copy at a given location. This macro defines the
+# subversion working copy at a given location. This macro defines the
# variable:
-# <var-prefix>_LAST_CHANGED_LOG - last log of base revision
+#
+# ::
+#
+# <var-prefix>_LAST_CHANGED_LOG - last log of base revision
+#
# Example usage:
-# find_package(Subversion)
-# if(SUBVERSION_FOUND)
-# Subversion_WC_INFO(${PROJECT_SOURCE_DIR} Project)
-# message("Current revision is ${Project_WC_REVISION}")
-# Subversion_WC_LOG(${PROJECT_SOURCE_DIR} Project)
-# message("Last changed log is ${Project_LAST_CHANGED_LOG}")
-# endif()
+#
+# ::
+#
+# find_package(Subversion)
+# if(SUBVERSION_FOUND)
+# Subversion_WC_INFO(${PROJECT_SOURCE_DIR} Project)
+# message("Current revision is ${Project_WC_REVISION}")
+# Subversion_WC_LOG(${PROJECT_SOURCE_DIR} Project)
+# message("Last changed log is ${Project_LAST_CHANGED_LOG}")
+# endif()
#=============================================================================
# Copyright 2006-2009 Kitware, Inc.
@@ -48,6 +73,8 @@
# License text for the above reference.)
find_program(Subversion_SVN_EXECUTABLE svn
+ PATHS
+ [HKEY_LOCAL_MACHINE\\Software\\TortoiseSVN;Directory]/bin
DOC "subversion command line client")
mark_as_advanced(Subversion_SVN_EXECUTABLE)
diff --git a/Modules/FindTCL.cmake b/Modules/FindTCL.cmake
index 37e43d05a..a83e277b0 100644
--- a/Modules/FindTCL.cmake
+++ b/Modules/FindTCL.cmake
@@ -1,35 +1,45 @@
-# - Find Tcl includes and libraries.
-# This module finds if Tcl is installed and determines where the
-# include files and libraries are. It also determines what the name of
-# the library is. This code sets the following variables:
-# TCL_FOUND = Tcl was found
-# TK_FOUND = Tk was found
-# TCLTK_FOUND = Tcl and Tk were found
-# TCL_LIBRARY = path to Tcl library (tcl tcl80)
-# TCL_INCLUDE_PATH = path to where tcl.h can be found
-# TCL_TCLSH = path to tclsh binary (tcl tcl80)
-# TK_LIBRARY = path to Tk library (tk tk80 etc)
-# TK_INCLUDE_PATH = path to where tk.h can be found
-# TK_WISH = full path to the wish executable
+#.rst:
+# FindTCL
+# -------
#
-# In an effort to remove some clutter and clear up some issues for people
-# who are not necessarily Tcl/Tk gurus/developpers, some variables were
-# moved or removed. Changes compared to CMake 2.4 are:
-# - The stub libraries are now found in FindTclStub.cmake
-# => they were only useful for people writing Tcl/Tk extensions.
-# - TCL_LIBRARY_DEBUG and TK_LIBRARY_DEBUG were removed.
-# => these libs are not packaged by default with Tcl/Tk distributions.
-# Even when Tcl/Tk is built from source, several flavors of debug libs
-# are created and there is no real reason to pick a single one
-# specifically (say, amongst tcl84g, tcl84gs, or tcl84sgx).
-# Let's leave that choice to the user by allowing him to assign
-# TCL_LIBRARY to any Tcl library, debug or not.
-# - TK_INTERNAL_PATH was removed.
-# => this ended up being only a Win32 variable, and there is a lot of
-# confusion regarding the location of this file in an installed Tcl/Tk
-# tree anyway (see 8.5 for example). If you need the internal path at
-# this point it is safer you ask directly where the *source* tree is
-# and dig from there.
+# TK_INTERNAL_PATH was removed.
+#
+# This module finds if Tcl is installed and determines where the include
+# files and libraries are. It also determines what the name of the
+# library is. This code sets the following variables:
+#
+# ::
+#
+# TCL_FOUND = Tcl was found
+# TK_FOUND = Tk was found
+# TCLTK_FOUND = Tcl and Tk were found
+# TCL_LIBRARY = path to Tcl library (tcl tcl80)
+# TCL_INCLUDE_PATH = path to where tcl.h can be found
+# TCL_TCLSH = path to tclsh binary (tcl tcl80)
+# TK_LIBRARY = path to Tk library (tk tk80 etc)
+# TK_INCLUDE_PATH = path to where tk.h can be found
+# TK_WISH = full path to the wish executable
+#
+#
+#
+# In an effort to remove some clutter and clear up some issues for
+# people who are not necessarily Tcl/Tk gurus/developpers, some
+# variables were moved or removed. Changes compared to CMake 2.4 are:
+#
+# ::
+#
+# => they were only useful for people writing Tcl/Tk extensions.
+# => these libs are not packaged by default with Tcl/Tk distributions.
+# Even when Tcl/Tk is built from source, several flavors of debug libs
+# are created and there is no real reason to pick a single one
+# specifically (say, amongst tcl84g, tcl84gs, or tcl84sgx).
+# Let's leave that choice to the user by allowing him to assign
+# TCL_LIBRARY to any Tcl library, debug or not.
+# => this ended up being only a Win32 variable, and there is a lot of
+# confusion regarding the location of this file in an installed Tcl/Tk
+# tree anyway (see 8.5 for example). If you need the internal path at
+# this point it is safer you ask directly where the *source* tree is
+# and dig from there.
#=============================================================================
# Copyright 2001-2009 Kitware, Inc.
diff --git a/Modules/FindTIFF.cmake b/Modules/FindTIFF.cmake
index b48fb0e1d..e60049848 100644
--- a/Modules/FindTIFF.cmake
+++ b/Modules/FindTIFF.cmake
@@ -1,14 +1,44 @@
-# - Find TIFF library
-# Find the native TIFF includes and library
-# This module defines
-# TIFF_INCLUDE_DIR, where to find tiff.h, etc.
-# TIFF_LIBRARIES, libraries to link against to use TIFF.
-# TIFF_FOUND, If false, do not try to use TIFF.
-# also defined, but not for general use are
-# TIFF_LIBRARY, where to find the TIFF library.
+#.rst:
+# FindTIFF
+# --------
+#
+# Find the TIFF library (libtiff).
+#
+# Imported targets
+# ^^^^^^^^^^^^^^^^
+#
+# This module defines the following :prop_tgt:`IMPORTED` targets:
+#
+# ``TIFF::TIFF``
+# The TIFF library, if found.
+#
+# Result variables
+# ^^^^^^^^^^^^^^^^
+#
+# This module will set the following variables in your project:
+#
+# ``TIFF_FOUND``
+# true if the TIFF headers and libraries were found
+# ``TIFF_INCLUDE_DIR``
+# the directory containing the TIFF headers
+# ``TIFF_INCLUDE_DIRS``
+# the directory containing the TIFF headers
+# ``TIFF_LIBRARIES``
+# TIFF libraries to be linked
+#
+# Cache variables
+# ^^^^^^^^^^^^^^^
+#
+# The following cache variables may also be set:
+#
+# ``TIFF_INCLUDE_DIR``
+# the directory containing the TIFF headers
+# ``TIFF_LIBRARY``
+# the path to the TIFF library
#=============================================================================
# Copyright 2002-2009 Kitware, Inc.
+# Copyright 2015 University of Dundee
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
@@ -23,7 +53,19 @@
find_path(TIFF_INCLUDE_DIR tiff.h)
set(TIFF_NAMES ${TIFF_NAMES} tiff libtiff tiff3 libtiff3)
-find_library(TIFF_LIBRARY NAMES ${TIFF_NAMES} )
+foreach(name ${TIFF_NAMES})
+ list(APPEND TIFF_NAMES_DEBUG "${name}d")
+endforeach()
+
+if(NOT TIFF_LIBRARY)
+ find_library(TIFF_LIBRARY_RELEASE NAMES ${TIFF_NAMES})
+ find_library(TIFF_LIBRARY_DEBUG NAMES ${TIFF_NAMES_DEBUG})
+ include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
+ select_library_configurations(TIFF)
+ mark_as_advanced(TIFF_LIBRARY_RELEASE TIFF_LIBRARY_DEBUG)
+endif()
+unset(TIFF_NAMES)
+unset(TIFF_NAMES_DEBUG)
if(TIFF_INCLUDE_DIR AND EXISTS "${TIFF_INCLUDE_DIR}/tiffvers.h")
file(STRINGS "${TIFF_INCLUDE_DIR}/tiffvers.h" tiff_version_str
@@ -42,7 +84,35 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(TIFF
VERSION_VAR TIFF_VERSION_STRING)
if(TIFF_FOUND)
- set( TIFF_LIBRARIES ${TIFF_LIBRARY} )
+ set(TIFF_LIBRARIES ${TIFF_LIBRARY})
+ set(TIFF_INCLUDE_DIRS "${TIFF_INCLUDE_DIR}")
+
+ if(NOT TARGET TIFF::TIFF)
+ add_library(TIFF::TIFF UNKNOWN IMPORTED)
+ if(TIFF_INCLUDE_DIRS)
+ set_target_properties(TIFF::TIFF PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${TIFF_INCLUDE_DIRS}")
+ endif()
+ if(EXISTS "${TIFF_LIBRARY}")
+ set_target_properties(TIFF::TIFF PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+ IMPORTED_LOCATION "${TIFF_LIBRARY}")
+ endif()
+ if(EXISTS "${TIFF_LIBRARY_DEBUG}")
+ set_property(TARGET TIFF::TIFF APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS DEBUG)
+ set_target_properties(TIFF::TIFF PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C"
+ IMPORTED_LOCATION_DEBUG "${TIFF_LIBRARY_DEBUG}")
+ endif()
+ if(EXISTS "${TIFF_LIBRARY_RELEASE}")
+ set_property(TARGET TIFF::TIFF APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS RELEASE)
+ set_target_properties(TIFF::TIFF PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C"
+ IMPORTED_LOCATION_RELEASE "${TIFF_LIBRARY_RELEASE}")
+ endif()
+ endif()
endif()
mark_as_advanced(TIFF_INCLUDE_DIR TIFF_LIBRARY)
diff --git a/Modules/FindTclStub.cmake b/Modules/FindTclStub.cmake
index 8dda94a79..3c24f9721 100644
--- a/Modules/FindTclStub.cmake
+++ b/Modules/FindTclStub.cmake
@@ -1,25 +1,45 @@
-# - Find Tcl stub libraries.
-# This module finds Tcl stub libraries. It first finds Tcl include files and
-# libraries by calling FindTCL.cmake.
-# How to Use the Tcl Stubs Library:
-# http://tcl.activestate.com/doc/howto/stubs.html
+#.rst:
+# FindTclStub
+# -----------
+#
+# TCL_STUB_LIBRARY_DEBUG and TK_STUB_LIBRARY_DEBUG were removed.
+#
+# This module finds Tcl stub libraries. It first finds Tcl include
+# files and libraries by calling FindTCL.cmake. How to Use the Tcl
+# Stubs Library:
+#
+# ::
+#
+# http://tcl.activestate.com/doc/howto/stubs.html
+#
# Using Stub Libraries:
-# http://safari.oreilly.com/0130385603/ch48lev1sec3
+#
+# ::
+#
+# http://safari.oreilly.com/0130385603/ch48lev1sec3
+#
# This code sets the following variables:
-# TCL_STUB_LIBRARY = path to Tcl stub library
-# TK_STUB_LIBRARY = path to Tk stub library
-# TTK_STUB_LIBRARY = path to ttk stub library
-#
-# In an effort to remove some clutter and clear up some issues for people
-# who are not necessarily Tcl/Tk gurus/developpers, some variables were
-# moved or removed. Changes compared to CMake 2.4 are:
-# - TCL_STUB_LIBRARY_DEBUG and TK_STUB_LIBRARY_DEBUG were removed.
-# => these libs are not packaged by default with Tcl/Tk distributions.
-# Even when Tcl/Tk is built from source, several flavors of debug libs
-# are created and there is no real reason to pick a single one
-# specifically (say, amongst tclstub84g, tclstub84gs, or tclstub84sgx).
-# Let's leave that choice to the user by allowing him to assign
-# TCL_STUB_LIBRARY to any Tcl library, debug or not.
+#
+# ::
+#
+# TCL_STUB_LIBRARY = path to Tcl stub library
+# TK_STUB_LIBRARY = path to Tk stub library
+# TTK_STUB_LIBRARY = path to ttk stub library
+#
+#
+#
+# In an effort to remove some clutter and clear up some issues for
+# people who are not necessarily Tcl/Tk gurus/developpers, some
+# variables were moved or removed. Changes compared to CMake 2.4 are:
+#
+# ::
+#
+# => these libs are not packaged by default with Tcl/Tk distributions.
+# Even when Tcl/Tk is built from source, several flavors of debug libs
+# are created and there is no real reason to pick a single one
+# specifically (say, amongst tclstub84g, tclstub84gs, or tclstub84sgx).
+# Let's leave that choice to the user by allowing him to assign
+# TCL_STUB_LIBRARY to any Tcl library, debug or not.
#=============================================================================
# Copyright 2008-2009 Kitware, Inc.
diff --git a/Modules/FindTclsh.cmake b/Modules/FindTclsh.cmake
index 0f091e60d..2fd5332aa 100644
--- a/Modules/FindTclsh.cmake
+++ b/Modules/FindTclsh.cmake
@@ -1,11 +1,20 @@
-# - Find tclsh
-# This module finds if TCL is installed and determines where the
-# include files and libraries are. It also determines what the name of
-# the library is. This code sets the following variables:
-# TCLSH_FOUND = TRUE if tclsh has been found
-# TCL_TCLSH = the path to the tclsh executable
-# In cygwin, look for the cygwin version first. Don't look for it later to
-# avoid finding the cygwin version on a Win32 build.
+#.rst:
+# FindTclsh
+# ---------
+#
+# Find tclsh
+#
+# This module finds if TCL is installed and determines where the include
+# files and libraries are. It also determines what the name of the
+# library is. This code sets the following variables:
+#
+# ::
+#
+# TCLSH_FOUND = TRUE if tclsh has been found
+# TCL_TCLSH = the path to the tclsh executable
+#
+# In cygwin, look for the cygwin version first. Don't look for it later
+# to avoid finding the cygwin version on a Win32 build.
#=============================================================================
# Copyright 2001-2009 Kitware, Inc.
diff --git a/Modules/FindThreads.cmake b/Modules/FindThreads.cmake
index f03908ea0..c6079231f 100644
--- a/Modules/FindThreads.cmake
+++ b/Modules/FindThreads.cmake
@@ -1,15 +1,45 @@
-# - This module determines the thread library of the system.
+#.rst:
+# FindThreads
+# -----------
+#
+# This module determines the thread library of the system.
+#
# The following variables are set
-# CMAKE_THREAD_LIBS_INIT - the thread library
-# CMAKE_USE_SPROC_INIT - are we using sproc?
-# CMAKE_USE_WIN32_THREADS_INIT - using WIN32 threads?
-# CMAKE_USE_PTHREADS_INIT - are we using pthreads
-# CMAKE_HP_PTHREADS_INIT - are we using hp pthreads
+#
+# ::
+#
+# CMAKE_THREAD_LIBS_INIT - the thread library
+# CMAKE_USE_SPROC_INIT - are we using sproc?
+# CMAKE_USE_WIN32_THREADS_INIT - using WIN32 threads?
+# CMAKE_USE_PTHREADS_INIT - are we using pthreads
+# CMAKE_HP_PTHREADS_INIT - are we using hp pthreads
+#
+# The following import target is created
+#
+# ::
+#
+# Threads::Threads
+#
# For systems with multiple thread libraries, caller can set
-# CMAKE_THREAD_PREFER_PTHREAD
+#
+# ::
+#
+# CMAKE_THREAD_PREFER_PTHREAD
+#
+# If the use of the -pthread compiler and linker flag is prefered then the
+# caller can set
+#
+# ::
+#
+# THREADS_PREFER_PTHREAD_FLAG
+#
+# Please note that the compiler flag can only be used with the imported
+# target. Use of both the imported target as well as this switch is highly
+# recommended for new code.
#=============================================================================
# Copyright 2002-2009 Kitware, Inc.
+# Copyright 2011-2015 Rolf Eike Beer <eike@sf-mail.de>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
@@ -21,22 +51,95 @@
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
-include (CheckIncludeFiles)
include (CheckLibraryExists)
include (CheckSymbolExists)
set(Threads_FOUND FALSE)
+set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET})
+set(CMAKE_REQUIRED_QUIET ${Threads_FIND_QUIETLY})
+
+if(CMAKE_C_COMPILER_LOADED)
+ include (CheckIncludeFile)
+elseif(CMAKE_CXX_COMPILER_LOADED)
+ include (CheckIncludeFileCXX)
+else()
+ message(FATAL_ERROR "FindThreads only works if either C or CXX language is enabled")
+endif()
# Do we have sproc?
-if(CMAKE_SYSTEM MATCHES IRIX AND NOT CMAKE_THREAD_PREFER_PTHREAD)
+if(CMAKE_SYSTEM_NAME MATCHES IRIX AND NOT CMAKE_THREAD_PREFER_PTHREAD)
+ include (CheckIncludeFiles)
CHECK_INCLUDE_FILES("sys/types.h;sys/prctl.h" CMAKE_HAVE_SPROC_H)
endif()
+# Internal helper macro.
+# Do NOT even think about using it outside of this file!
+macro(_check_threads_lib LIBNAME FUNCNAME VARNAME)
+ if(NOT Threads_FOUND)
+ CHECK_LIBRARY_EXISTS(${LIBNAME} ${FUNCNAME} "" ${VARNAME})
+ if(${VARNAME})
+ set(CMAKE_THREAD_LIBS_INIT "-l${LIBNAME}")
+ set(CMAKE_HAVE_THREADS_LIBRARY 1)
+ set(Threads_FOUND TRUE)
+ endif()
+ endif ()
+endmacro()
+
+# Internal helper macro.
+# Do NOT even think about using it outside of this file!
+macro(_check_pthreads_flag)
+ if(NOT Threads_FOUND)
+ # If we did not found -lpthread, -lpthread, or -lthread, look for -pthread
+ if(NOT DEFINED THREADS_HAVE_PTHREAD_ARG)
+ message(STATUS "Check if compiler accepts -pthread")
+ if(CMAKE_C_COMPILER_LOADED)
+ set(_threads_src ${CMAKE_CURRENT_LIST_DIR}/CheckForPthreads.c)
+ elseif(CMAKE_CXX_COMPILER_LOADED)
+ set(_threads_src ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindThreads/CheckForPthreads.cxx)
+ configure_file(${CMAKE_CURRENT_LIST_DIR}/CheckForPthreads.c "${_threads_src}" COPYONLY)
+ endif()
+ try_run(THREADS_PTHREAD_ARG THREADS_HAVE_PTHREAD_ARG
+ ${CMAKE_BINARY_DIR}
+ ${_threads_src}
+ CMAKE_FLAGS -DLINK_LIBRARIES:STRING=-pthread
+ COMPILE_OUTPUT_VARIABLE OUTPUT)
+ unset(_threads_src)
+
+ if(THREADS_HAVE_PTHREAD_ARG)
+ if(THREADS_PTHREAD_ARG STREQUAL "2")
+ set(Threads_FOUND TRUE)
+ message(STATUS "Check if compiler accepts -pthread - yes")
+ else()
+ message(STATUS "Check if compiler accepts -pthread - no")
+ file(APPEND
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Determining if compiler accepts -pthread returned ${THREADS_PTHREAD_ARG} instead of 2. The compiler had the following output:\n${OUTPUT}\n\n")
+ endif()
+ else()
+ message(STATUS "Check if compiler accepts -pthread - no")
+ file(APPEND
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Determining if compiler accepts -pthread failed with the following output:\n${OUTPUT}\n\n")
+ endif()
+
+ endif()
+
+ if(THREADS_HAVE_PTHREAD_ARG)
+ set(Threads_FOUND TRUE)
+ set(CMAKE_THREAD_LIBS_INIT "-pthread")
+ endif()
+ endif()
+endmacro()
+
if(CMAKE_HAVE_SPROC_H AND NOT CMAKE_THREAD_PREFER_PTHREAD)
# We have sproc
set(CMAKE_USE_SPROC_INIT 1)
else()
# Do we have pthreads?
- CHECK_INCLUDE_FILES("pthread.h" CMAKE_HAVE_PTHREAD_H)
+ if(CMAKE_C_COMPILER_LOADED)
+ CHECK_INCLUDE_FILE("pthread.h" CMAKE_HAVE_PTHREAD_H)
+ else()
+ CHECK_INCLUDE_FILE_CXX("pthread.h" CMAKE_HAVE_PTHREAD_H)
+ endif()
if(CMAKE_HAVE_PTHREAD_H)
#
@@ -51,72 +154,25 @@ else()
set(CMAKE_THREAD_LIBS_INIT "")
set(CMAKE_HAVE_THREADS_LIBRARY 1)
set(Threads_FOUND TRUE)
- endif()
-
- if(NOT CMAKE_HAVE_THREADS_LIBRARY)
- # Do we have -lpthreads
- CHECK_LIBRARY_EXISTS(pthreads pthread_create "" CMAKE_HAVE_PTHREADS_CREATE)
- if(CMAKE_HAVE_PTHREADS_CREATE)
- set(CMAKE_THREAD_LIBS_INIT "-lpthreads")
- set(CMAKE_HAVE_THREADS_LIBRARY 1)
- set(Threads_FOUND TRUE)
- endif()
-
- # Ok, how about -lpthread
- CHECK_LIBRARY_EXISTS(pthread pthread_create "" CMAKE_HAVE_PTHREAD_CREATE)
- if(CMAKE_HAVE_PTHREAD_CREATE)
- set(CMAKE_THREAD_LIBS_INIT "-lpthread")
- set(CMAKE_HAVE_THREADS_LIBRARY 1)
- set(Threads_FOUND TRUE)
- endif()
-
- if(CMAKE_SYSTEM MATCHES "SunOS.*")
- # On sun also check for -lthread
- CHECK_LIBRARY_EXISTS(thread thr_create "" CMAKE_HAVE_THR_CREATE)
- if(CMAKE_HAVE_THR_CREATE)
- set(CMAKE_THREAD_LIBS_INIT "-lthread")
- set(CMAKE_HAVE_THREADS_LIBRARY 1)
- set(Threads_FOUND TRUE)
- endif()
+ else()
+
+ # Check for -pthread first if enabled. This is the recommended
+ # way, but not backwards compatible as one must also pass -pthread
+ # as compiler flag then.
+ if (THREADS_PREFER_PTHREAD_FLAG)
+ _check_pthreads_flag()
+ endif ()
+
+ _check_threads_lib(pthreads pthread_create CMAKE_HAVE_PTHREADS_CREATE)
+ _check_threads_lib(pthread pthread_create CMAKE_HAVE_PTHREAD_CREATE)
+ if(CMAKE_SYSTEM_NAME MATCHES "SunOS")
+ # On sun also check for -lthread
+ _check_threads_lib(thread thr_create CMAKE_HAVE_THR_CREATE)
endif()
endif()
endif()
- if(NOT CMAKE_HAVE_THREADS_LIBRARY)
- # If we did not found -lpthread, -lpthread, or -lthread, look for -pthread
- if("THREADS_HAVE_PTHREAD_ARG" MATCHES "^THREADS_HAVE_PTHREAD_ARG")
- message(STATUS "Check if compiler accepts -pthread")
- try_run(THREADS_PTHREAD_ARG THREADS_HAVE_PTHREAD_ARG
- ${CMAKE_BINARY_DIR}
- ${CMAKE_ROOT}/Modules/CheckForPthreads.c
- CMAKE_FLAGS -DLINK_LIBRARIES:STRING=-pthread
- COMPILE_OUTPUT_VARIABLE OUTPUT)
-
- if(THREADS_HAVE_PTHREAD_ARG)
- if(THREADS_PTHREAD_ARG STREQUAL "2")
- set(Threads_FOUND TRUE)
- message(STATUS "Check if compiler accepts -pthread - yes")
- else()
- message(STATUS "Check if compiler accepts -pthread - no")
- file(APPEND
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
- "Determining if compiler accepts -pthread returned ${THREADS_PTHREAD_ARG} instead of 2. The compiler had the following output:\n${OUTPUT}\n\n")
- endif()
- else()
- message(STATUS "Check if compiler accepts -pthread - no")
- file(APPEND
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
- "Determining if compiler accepts -pthread failed with the following output:\n${OUTPUT}\n\n")
- endif()
-
- endif()
-
- if(THREADS_HAVE_PTHREAD_ARG)
- set(Threads_FOUND TRUE)
- set(CMAKE_THREAD_LIBS_INIT "-pthread")
- endif()
-
- endif()
+ _check_pthreads_flag()
endif()
endif()
@@ -125,13 +181,13 @@ if(CMAKE_THREAD_LIBS_INIT OR CMAKE_HAVE_LIBC_CREATE)
set(Threads_FOUND TRUE)
endif()
-if(CMAKE_SYSTEM MATCHES "Windows")
+if(CMAKE_SYSTEM_NAME MATCHES "Windows")
set(CMAKE_USE_WIN32_THREADS_INIT 1)
set(Threads_FOUND TRUE)
endif()
if(CMAKE_USE_PTHREADS_INIT)
- if(CMAKE_SYSTEM MATCHES "HP-UX-*")
+ if(CMAKE_SYSTEM_NAME MATCHES "HP-UX")
# Use libcma if it exists and can be used. It provides more
# symbols than the plain pthread library. CMA threads
# have actually been deprecated:
@@ -149,12 +205,12 @@ if(CMAKE_USE_PTHREADS_INIT)
set(CMAKE_USE_PTHREADS_INIT 1)
endif()
- if(CMAKE_SYSTEM MATCHES "OSF1-V*")
+ if(CMAKE_SYSTEM MATCHES "OSF1-V")
set(CMAKE_USE_PTHREADS_INIT 0)
set(CMAKE_THREAD_LIBS_INIT )
endif()
- if(CMAKE_SYSTEM MATCHES "CYGWIN_NT*")
+ if(CMAKE_SYSTEM MATCHES "CYGWIN_NT")
set(CMAKE_USE_PTHREADS_INIT 1)
set(Threads_FOUND TRUE)
set(CMAKE_THREAD_LIBS_INIT )
@@ -162,5 +218,18 @@ if(CMAKE_USE_PTHREADS_INIT)
endif()
endif()
+set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE})
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Threads DEFAULT_MSG Threads_FOUND)
+
+if(THREADS_FOUND AND NOT TARGET Threads::Threads)
+ add_library(Threads::Threads INTERFACE IMPORTED)
+
+ if(THREADS_HAVE_PTHREAD_ARG)
+ set_property(TARGET Threads::Threads PROPERTY INTERFACE_COMPILE_OPTIONS "-pthread")
+ endif()
+
+ if(CMAKE_THREAD_LIBS_INIT)
+ set_property(TARGET Threads::Threads PROPERTY INTERFACE_LINK_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}")
+ endif()
+endif()
diff --git a/Modules/FindUnixCommands.cmake b/Modules/FindUnixCommands.cmake
index 87caadc09..869ba38d9 100644
--- a/Modules/FindUnixCommands.cmake
+++ b/Modules/FindUnixCommands.cmake
@@ -1,9 +1,14 @@
-# - Find unix commands from cygwin
-# This module looks for some usual Unix commands.
+#.rst:
+# FindUnixCommands
+# ----------------
#
+# Find Unix commands, including the ones from Cygwin
+#
+# This module looks for the Unix commands bash, cp, gzip, mv, rm, and tar
+# and stores the result in the variables BASH, CP, GZIP, MV, RM, and TAR.
#=============================================================================
-# Copyright 2001-2009 Kitware, Inc.
+# Copyright 2001-2014 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
@@ -91,3 +96,8 @@ find_program(TAR
mark_as_advanced(
TAR
)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+find_package_handle_standard_args(UnixCommands
+ REQUIRED_VARS BASH CP GZIP MV RM TAR
+)
diff --git a/Modules/FindVTK.cmake b/Modules/FindVTK.cmake
deleted file mode 100644
index 085d60d04..000000000
--- a/Modules/FindVTK.cmake
+++ /dev/null
@@ -1,141 +0,0 @@
-# - Find a VTK installation or build tree.
-# The following variables are set if VTK is found. If VTK is not
-# found, VTK_FOUND is set to false.
-# VTK_FOUND - Set to true when VTK is found.
-# VTK_USE_FILE - CMake file to use VTK.
-# VTK_MAJOR_VERSION - The VTK major version number.
-# VTK_MINOR_VERSION - The VTK minor version number
-# (odd non-release).
-# VTK_BUILD_VERSION - The VTK patch level
-# (meaningless for odd minor).
-# VTK_INCLUDE_DIRS - Include directories for VTK
-# VTK_LIBRARY_DIRS - Link directories for VTK libraries
-# VTK_KITS - List of VTK kits, in CAPS
-# (COMMON,IO,) etc.
-# VTK_LANGUAGES - List of wrapped languages, in CAPS
-# (TCL, PYHTON,) etc.
-# The following cache entries must be set by the user to locate VTK:
-# VTK_DIR - The directory containing VTKConfig.cmake.
-# This is either the root of the build tree,
-# or the lib/vtk directory. This is the
-# only cache entry.
-# The following variables are set for backward compatibility and
-# should not be used in new code:
-# USE_VTK_FILE - The full path to the UseVTK.cmake file.
-# This is provided for backward
-# compatibility. Use VTK_USE_FILE
-# instead.
-#
-
-#=============================================================================
-# Copyright 2001-2009 Kitware, Inc.
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-# (To distribute this file outside of CMake, substitute the full
-# License text for the above reference.)
-
-# Assume not found.
-set(VTK_FOUND 0)
-
-# VTK 4.0 did not provide VTKConfig.cmake.
-if("${VTK_FIND_VERSION}" VERSION_LESS 4.1)
- set(_VTK_40_ALLOW 1)
- if(VTK_FIND_VERSION)
- set(_VTK_40_ONLY 1)
- endif()
-endif()
-
-# Construct consistent error messages for use below.
-set(VTK_DIR_DESCRIPTION "directory containing VTKConfig.cmake. This is either the root of the build tree, or PREFIX/lib/vtk for an installation.")
-if(_VTK_40_ALLOW)
- set(VTK_DIR_DESCRIPTION "${VTK_DIR_DESCRIPTION} For VTK 4.0, this is the location of UseVTK.cmake. This is either the root of the build tree or PREFIX/include/vtk for an installation.")
-endif()
-set(VTK_DIR_MESSAGE "VTK not found. Set the VTK_DIR cmake cache entry to the ${VTK_DIR_DESCRIPTION}")
-
-# Check whether VTK 4.0 has already been found.
-if(_VTK_40_ALLOW AND VTK_DIR)
- if(EXISTS ${VTK_DIR}/UseVTK.cmake AND NOT EXISTS ${VTK_DIR}/VTKConfig.cmake)
- set(VTK_FOUND 1)
- include(${CMAKE_CURRENT_LIST_DIR}/UseVTKConfig40.cmake) # No VTKConfig; load VTK 4.0 settings.
- endif()
-endif()
-
-# Use the Config mode of the find_package() command to find VTKConfig.
-# If this succeeds (possibly because VTK_DIR is already set), the
-# command will have already loaded VTKConfig.cmake and set VTK_FOUND.
-if(NOT _VTK_40_ONLY AND NOT VTK_FOUND)
- find_package(VTK QUIET NO_MODULE)
-endif()
-
-# Special search for VTK 4.0.
-if(_VTK_40_ALLOW AND NOT VTK_DIR)
- # Old scripts may set these directories in the CMakeCache.txt file.
- # They can tell us where to find VTKConfig.cmake.
- set(VTK_DIR_SEARCH_LEGACY "")
- if(VTK_BINARY_PATH AND USE_BUILT_VTK)
- set(VTK_DIR_SEARCH_LEGACY ${VTK_DIR_SEARCH_LEGACY} ${VTK_BINARY_PATH})
- endif()
- if(VTK_INSTALL_PATH AND USE_INSTALLED_VTK)
- set(VTK_DIR_SEARCH_LEGACY ${VTK_DIR_SEARCH_LEGACY}
- ${VTK_INSTALL_PATH}/lib/vtk)
- endif()
-
- # Look for UseVTK.cmake in build trees or under <prefix>/include/vtk.
- find_path(VTK_DIR
- NAMES UseVTK.cmake
- PATH_SUFFIXES vtk-4.0 vtk
- HINTS ENV VTK_DIR
-
- PATHS
-
- # Support legacy cache files.
- ${VTK_DIR_SEARCH_LEGACY}
-
- # Read from the CMakeSetup registry entries. It is likely that
- # VTK will have been recently built.
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild1]
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild2]
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild3]
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild4]
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild5]
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild6]
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild7]
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild8]
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild9]
- [HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild10]
-
- # Help the user find it if we cannot.
- DOC "The ${VTK_DIR_DESCRIPTION}"
- )
-
- if(VTK_DIR)
- if(EXISTS ${VTK_DIR}/UseVTK.cmake AND NOT EXISTS ${VTK_DIR}/VTKConfig.cmake)
- set(VTK_FOUND 1)
- include(${CMAKE_CURRENT_LIST_DIR}/UseVTKConfig40.cmake) # No VTKConfig; load VTK 4.0 settings.
- else()
- # We found the wrong version. Pretend we did not find it.
- set(VTK_DIR "VTK_DIR-NOTFOUND" CACHE PATH "The ${VTK_DIR_DESCRIPTION}" FORCE)
- endif()
- endif()
-endif()
-
-#-----------------------------------------------------------------------------
-if(VTK_FOUND)
- # Set USE_VTK_FILE for backward-compatibility.
- set(USE_VTK_FILE ${VTK_USE_FILE})
-else()
- # VTK not found, explain to the user how to specify its location.
- if(VTK_FIND_REQUIRED)
- message(FATAL_ERROR ${VTK_DIR_MESSAGE})
- else()
- if(NOT VTK_FIND_QUIETLY)
- message(STATUS ${VTK_DIR_MESSAGE})
- endif()
- endif()
-endif()
diff --git a/Modules/FindWget.cmake b/Modules/FindWget.cmake
index 4da98b149..b303b407d 100644
--- a/Modules/FindWget.cmake
+++ b/Modules/FindWget.cmake
@@ -1,8 +1,15 @@
-# - Find wget
-# This module looks for wget. This module defines the
-# following values:
-# WGET_EXECUTABLE: the full path to the wget tool.
-# WGET_FOUND: True if wget has been found.
+#.rst:
+# FindWget
+# --------
+#
+# Find wget
+#
+# This module looks for wget. This module defines the following values:
+#
+# ::
+#
+# WGET_EXECUTABLE: the full path to the wget tool.
+# WGET_FOUND: True if wget has been found.
#=============================================================================
# Copyright 2001-2009 Kitware, Inc.
diff --git a/Modules/FindWish.cmake b/Modules/FindWish.cmake
index 11b29f249..df301b412 100644
--- a/Modules/FindWish.cmake
+++ b/Modules/FindWish.cmake
@@ -1,9 +1,18 @@
-# - Find wish installation
-# This module finds if TCL is installed and determines where the
-# include files and libraries are. It also determines what the name of
-# the library is. This code sets the following variables:
+#.rst:
+# FindWish
+# --------
+#
+# Find wish installation
+#
+# This module finds if TCL is installed and determines where the include
+# files and libraries are. It also determines what the name of the
+# library is. This code sets the following variables:
+#
+# ::
+#
+# TK_WISH = the path to the wish executable
+#
#
-# TK_WISH = the path to the wish executable
#
# if UNIX is defined, then it will look for the cygwin version first
diff --git a/Modules/FindX11.cmake b/Modules/FindX11.cmake
index 131d97994..90c1499c3 100644
--- a/Modules/FindX11.cmake
+++ b/Modules/FindX11.cmake
@@ -1,45 +1,55 @@
-# - Find X11 installation
+#.rst:
+# FindX11
+# -------
+#
+# Find X11 installation
+#
# Try to find X11 on UNIX systems. The following values are defined
-# X11_FOUND - True if X11 is available
-# X11_INCLUDE_DIR - include directories to use X11
-# X11_LIBRARIES - link against these to use X11
+#
+# ::
+#
+# X11_FOUND - True if X11 is available
+# X11_INCLUDE_DIR - include directories to use X11
+# X11_LIBRARIES - link against these to use X11
#
# and also the following more fine grained variables:
-# Include paths: X11_ICE_INCLUDE_PATH, X11_ICE_LIB, X11_ICE_FOUND
-# X11_SM_INCLUDE_PATH, X11_SM_LIB, X11_SM_FOUND
-# X11_X11_INCLUDE_PATH, X11_X11_LIB
-# X11_Xaccessrules_INCLUDE_PATH, X11_Xaccess_FOUND
-# X11_Xaccessstr_INCLUDE_PATH, X11_Xaccess_FOUND
-# X11_Xau_INCLUDE_PATH, X11_Xau_LIB, X11_Xau_FOUND
-# X11_Xcomposite_INCLUDE_PATH, X11_Xcomposite_LIB, X11_Xcomposite_FOUND
-# X11_Xcursor_INCLUDE_PATH, X11_Xcursor_LIB, X11_Xcursor_FOUND
-# X11_Xdamage_INCLUDE_PATH, X11_Xdamage_LIB, X11_Xdamage_FOUND
-# X11_Xdmcp_INCLUDE_PATH, X11_Xdmcp_LIB, X11_Xdmcp_FOUND
-# X11_Xext_LIB, X11_Xext_FOUND
-# X11_dpms_INCLUDE_PATH, (in X11_Xext_LIB), X11_dpms_FOUND
-# X11_XShm_INCLUDE_PATH, (in X11_Xext_LIB), X11_XShm_FOUND
-# X11_Xshape_INCLUDE_PATH, (in X11_Xext_LIB), X11_Xshape_FOUND
-# X11_xf86misc_INCLUDE_PATH, X11_Xxf86misc_LIB, X11_xf86misc_FOUND
-# X11_xf86vmode_INCLUDE_PATH, X11_Xxf86vm_LIB X11_xf86vmode_FOUND
-# X11_Xfixes_INCLUDE_PATH, X11_Xfixes_LIB, X11_Xfixes_FOUND
-# X11_Xft_INCLUDE_PATH, X11_Xft_LIB, X11_Xft_FOUND
-# X11_Xi_INCLUDE_PATH, X11_Xi_LIB, X11_Xi_FOUND
-# X11_Xinerama_INCLUDE_PATH, X11_Xinerama_LIB, X11_Xinerama_FOUND
-# X11_Xinput_INCLUDE_PATH, X11_Xinput_LIB, X11_Xinput_FOUND
-# X11_Xkb_INCLUDE_PATH, X11_Xkb_FOUND
-# X11_Xkblib_INCLUDE_PATH, X11_Xkb_FOUND
-# X11_Xkbfile_INCLUDE_PATH, X11_Xkbfile_LIB, X11_Xkbfile_FOUND
-# X11_Xmu_INCLUDE_PATH, X11_Xmu_LIB, X11_Xmu_FOUND
-# X11_Xpm_INCLUDE_PATH, X11_Xpm_LIB, X11_Xpm_FOUND
-# X11_XTest_INCLUDE_PATH, X11_XTest_LIB, X11_XTest_FOUND
-# X11_Xrandr_INCLUDE_PATH, X11_Xrandr_LIB, X11_Xrandr_FOUND
-# X11_Xrender_INCLUDE_PATH, X11_Xrender_LIB, X11_Xrender_FOUND
-# X11_Xscreensaver_INCLUDE_PATH, X11_Xscreensaver_LIB, X11_Xscreensaver_FOUND
-# X11_Xt_INCLUDE_PATH, X11_Xt_LIB, X11_Xt_FOUND
-# X11_Xutil_INCLUDE_PATH, X11_Xutil_FOUND
-# X11_Xv_INCLUDE_PATH, X11_Xv_LIB, X11_Xv_FOUND
-# X11_XSync_INCLUDE_PATH, (in X11_Xext_LIB), X11_XSync_FOUND
-
+#
+# ::
+#
+# X11_ICE_INCLUDE_PATH, X11_ICE_LIB, X11_ICE_FOUND
+# X11_SM_INCLUDE_PATH, X11_SM_LIB, X11_SM_FOUND
+# X11_X11_INCLUDE_PATH, X11_X11_LIB
+# X11_Xaccessrules_INCLUDE_PATH, X11_Xaccess_FOUND
+# X11_Xaccessstr_INCLUDE_PATH, X11_Xaccess_FOUND
+# X11_Xau_INCLUDE_PATH, X11_Xau_LIB, X11_Xau_FOUND
+# X11_Xcomposite_INCLUDE_PATH, X11_Xcomposite_LIB, X11_Xcomposite_FOUND
+# X11_Xcursor_INCLUDE_PATH, X11_Xcursor_LIB, X11_Xcursor_FOUND
+# X11_Xdamage_INCLUDE_PATH, X11_Xdamage_LIB, X11_Xdamage_FOUND
+# X11_Xdmcp_INCLUDE_PATH, X11_Xdmcp_LIB, X11_Xdmcp_FOUND
+# X11_Xext_LIB, X11_Xext_FOUND
+# X11_dpms_INCLUDE_PATH, (in X11_Xext_LIB), X11_dpms_FOUND
+# X11_XShm_INCLUDE_PATH, (in X11_Xext_LIB), X11_XShm_FOUND
+# X11_Xshape_INCLUDE_PATH, (in X11_Xext_LIB), X11_Xshape_FOUND
+# X11_xf86misc_INCLUDE_PATH, X11_Xxf86misc_LIB, X11_xf86misc_FOUND
+# X11_xf86vmode_INCLUDE_PATH, X11_Xxf86vm_LIB X11_xf86vmode_FOUND
+# X11_Xfixes_INCLUDE_PATH, X11_Xfixes_LIB, X11_Xfixes_FOUND
+# X11_Xft_INCLUDE_PATH, X11_Xft_LIB, X11_Xft_FOUND
+# X11_Xi_INCLUDE_PATH, X11_Xi_LIB, X11_Xi_FOUND
+# X11_Xinerama_INCLUDE_PATH, X11_Xinerama_LIB, X11_Xinerama_FOUND
+# X11_Xinput_INCLUDE_PATH, X11_Xinput_LIB, X11_Xinput_FOUND
+# X11_Xkb_INCLUDE_PATH, X11_Xkb_FOUND
+# X11_Xkblib_INCLUDE_PATH, X11_Xkb_FOUND
+# X11_Xkbfile_INCLUDE_PATH, X11_Xkbfile_LIB, X11_Xkbfile_FOUND
+# X11_Xmu_INCLUDE_PATH, X11_Xmu_LIB, X11_Xmu_FOUND
+# X11_Xpm_INCLUDE_PATH, X11_Xpm_LIB, X11_Xpm_FOUND
+# X11_XTest_INCLUDE_PATH, X11_XTest_LIB, X11_XTest_FOUND
+# X11_Xrandr_INCLUDE_PATH, X11_Xrandr_LIB, X11_Xrandr_FOUND
+# X11_Xrender_INCLUDE_PATH, X11_Xrender_LIB, X11_Xrender_FOUND
+# X11_Xscreensaver_INCLUDE_PATH, X11_Xscreensaver_LIB, X11_Xscreensaver_FOUND
+# X11_Xt_INCLUDE_PATH, X11_Xt_LIB, X11_Xt_FOUND
+# X11_Xutil_INCLUDE_PATH, X11_Xutil_FOUND
+# X11_Xv_INCLUDE_PATH, X11_Xv_LIB, X11_Xv_FOUND
+# X11_XSync_INCLUDE_PATH, (in X11_Xext_LIB), X11_XSync_FOUND
#=============================================================================
# Copyright 2001-2009 Kitware, Inc.
@@ -60,6 +70,8 @@ if (UNIX)
# found in tcl on the mac
set(CMAKE_FIND_FRAMEWORK_SAVE ${CMAKE_FIND_FRAMEWORK})
set(CMAKE_FIND_FRAMEWORK NEVER)
+ set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET})
+ set(CMAKE_REQUIRED_QUIET ${X11_FIND_QUIETLY})
set(X11_INC_SEARCH_PATH
/usr/pkg/xorg/include
/usr/X11R6/include
@@ -494,6 +506,7 @@ if (UNIX)
X11_XSync_INCLUDE_PATH
)
set(CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK_SAVE})
+ set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE})
endif ()
# X11_FIND_REQUIRED_<component> could be checked too
diff --git a/Modules/FindXCTest.cmake b/Modules/FindXCTest.cmake
new file mode 100644
index 000000000..3cd9c22bc
--- /dev/null
+++ b/Modules/FindXCTest.cmake
@@ -0,0 +1,196 @@
+#[=======================================================================[.rst:
+FindXCTest
+----------
+
+Functions to help creating and executing XCTest bundles.
+
+An XCTest bundle is a CFBundle with a special product-type
+and bundle extension. The Mac Developer Library provides more
+information in the `Testing with Xcode`_ document.
+
+.. _Testing with Xcode: http://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/
+
+Module Functions
+^^^^^^^^^^^^^^^^
+
+.. command:: xctest_add_bundle
+
+ The ``xctest_add_bundle`` function creates a XCTest bundle named
+ <target> which will test the target <testee>. Supported target types
+ for testee are Frameworks and App Bundles::
+
+ xctest_add_bundle(
+ <target> # Name of the XCTest bundle
+ <testee> # Target name of the testee
+ )
+
+.. command:: xctest_add_test
+
+ The ``xctest_add_test`` function adds an XCTest bundle to the
+ project to be run by :manual:`ctest(1)`. The test will be named
+ <name> and tests <bundle>::
+
+ xctest_add_test(
+ <name> # Test name
+ <bundle> # Target name of XCTest bundle
+ )
+
+Module Variables
+^^^^^^^^^^^^^^^^
+
+The following variables are set by including this module:
+
+.. variable:: XCTest_FOUND
+
+ True if the XCTest Framework and executable were found.
+
+.. variable:: XCTest_EXECUTABLE
+
+ The path to the xctest command line tool used to execute XCTest bundles.
+
+.. variable:: XCTest_INCLUDE_DIRS
+
+ The directory containing the XCTest Framework headers.
+
+.. variable:: XCTest_LIBRARIES
+
+ The location of the XCTest Framework.
+
+#]=======================================================================]
+
+#=============================================================================
+# Copyright 2015 Gregor Jasny
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+find_path(XCTest_INCLUDE_DIR
+ NAMES "XCTest/XCTest.h"
+ DOC "XCTest include directory")
+mark_as_advanced(XCTest_INCLUDE_DIR)
+
+find_library(XCTest_LIBRARY
+ NAMES XCTest
+ DOC "XCTest Framework library")
+mark_as_advanced(XCTest_LIBRARY)
+
+execute_process(
+ COMMAND xcrun --find xctest
+ OUTPUT_VARIABLE _xcrun_out OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_VARIABLE _xcrun_err)
+if(_xcrun_out)
+ set(XCTest_EXECUTABLE "${_xcrun_out}" CACHE FILEPATH "XCTest executable")
+ mark_as_advanced(XCTest_EXECUTABLE)
+endif()
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+find_package_handle_standard_args(XCTest
+ FOUND_VAR XCTest_FOUND
+ REQUIRED_VARS XCTest_LIBRARY XCTest_INCLUDE_DIR XCTest_EXECUTABLE)
+
+if(XCTest_FOUND)
+ set(XCTest_INCLUDE_DIRS "${XCTest_INCLUDE_DIR}")
+ set(XCTest_LIBRARIES "${XCTest_LIBRARY}")
+endif(XCTest_FOUND)
+
+
+function(xctest_add_bundle target testee)
+ if(NOT XCTest_FOUND)
+ message(FATAL_ERROR "XCTest is required to create a XCTest Bundle.")
+ endif(NOT XCTest_FOUND)
+
+ if(NOT CMAKE_OSX_SYSROOT)
+ message(FATAL_ERROR "Adding XCTest bundles requires CMAKE_OSX_SYSROOT to be set.")
+ endif()
+
+ add_library(${target} MODULE ${ARGN})
+
+ set_target_properties(${target} PROPERTIES
+ BUNDLE TRUE
+ XCTEST TRUE
+ XCTEST_TESTEE ${testee})
+
+ target_link_libraries(${target} PRIVATE "-framework Foundation")
+ target_link_libraries(${target} PRIVATE ${XCTest_LIBRARIES})
+ target_include_directories(${target} PRIVATE ${XCTest_INCLUDE_DIRS})
+
+ # retrieve testee target type
+ if(NOT TARGET ${testee})
+ message(FATAL_ERROR "${testee} is not a target.")
+ endif()
+ get_property(_testee_type TARGET ${testee} PROPERTY TYPE)
+ get_property(_testee_framework TARGET ${testee} PROPERTY FRAMEWORK)
+ get_property(_testee_macosx_bundle TARGET ${testee} PROPERTY MACOSX_BUNDLE)
+
+ if(_testee_type STREQUAL "SHARED_LIBRARY" AND _testee_framework)
+ # testee is a Framework
+ target_link_libraries(${target} PRIVATE ${testee})
+
+ elseif(_testee_type STREQUAL "EXECUTABLE" AND _testee_macosx_bundle)
+ # testee is an App Bundle
+ add_dependencies(${target} ${testee})
+ if(XCODE)
+ set_target_properties(${target} PROPERTIES
+ XCODE_ATTRIBUTE_BUNDLE_LOADER "$(TEST_HOST)"
+ XCODE_ATTRIBUTE_TEST_HOST "$<TARGET_FILE:${testee}>")
+ else(XCODE)
+ target_link_libraries(${target}
+ PRIVATE -bundle_loader $<TARGET_FILE:${testee}>)
+ endif(XCODE)
+
+ else()
+ message(FATAL_ERROR "Testee ${testee} is of unsupported type.")
+ endif()
+endfunction(xctest_add_bundle)
+
+
+function(xctest_add_test name bundle)
+ if(NOT XCTest_EXECUTABLE)
+ message(FATAL_ERROR "XCTest executable is required to register a test.")
+ endif()
+
+ # check that bundle is a XCTest Bundle
+
+ if(NOT TARGET ${bundle})
+ message(FATAL_ERROR "${bundle} is not a target.")
+ endif(NOT TARGET ${bundle})
+
+ get_property(_test_type TARGET ${bundle} PROPERTY TYPE)
+ get_property(_test_bundle TARGET ${bundle} PROPERTY BUNDLE)
+ get_property(_test_xctest TARGET ${bundle} PROPERTY XCTEST)
+
+ if(NOT _test_type STREQUAL "MODULE_LIBRARY"
+ OR NOT _test_xctest OR NOT _test_bundle)
+ message(FATAL_ERROR "Test ${bundle} is not an XCTest Bundle")
+ endif()
+
+ # get and check testee properties
+
+ get_property(_testee TARGET ${bundle} PROPERTY XCTEST_TESTEE)
+ if(NOT TARGET ${_testee})
+ message(FATAL_ERROR "${_testee} is not a target.")
+ endif()
+
+ get_property(_testee_type TARGET ${_testee} PROPERTY TYPE)
+ get_property(_testee_framework TARGET ${_testee} PROPERTY FRAMEWORK)
+
+ # register test
+
+ add_test(
+ NAME ${name}
+ COMMAND ${XCTest_EXECUTABLE} $<TARGET_LINKER_FILE_DIR:${bundle}>/../..)
+
+ # point loader to testee in case rpath is disabled
+
+ if(_testee_type STREQUAL "SHARED_LIBRARY" AND _testee_framework)
+ set_property(TEST ${name} APPEND PROPERTY
+ ENVIRONMENT DYLD_FRAMEWORK_PATH=$<TARGET_LINKER_FILE_DIR:${_testee}>/..)
+ endif()
+endfunction(xctest_add_test)
diff --git a/Modules/FindXMLRPC.cmake b/Modules/FindXMLRPC.cmake
index c80249b56..14917547d 100644
--- a/Modules/FindXMLRPC.cmake
+++ b/Modules/FindXMLRPC.cmake
@@ -1,16 +1,32 @@
-# - Find xmlrpc
+#.rst:
+# FindXMLRPC
+# ----------
+#
+# Find xmlrpc
+#
# Find the native XMLRPC headers and libraries.
-# XMLRPC_INCLUDE_DIRS - where to find xmlrpc.h, etc.
-# XMLRPC_LIBRARIES - List of libraries when using xmlrpc.
-# XMLRPC_FOUND - True if xmlrpc found.
+#
+# ::
+#
+# XMLRPC_INCLUDE_DIRS - where to find xmlrpc.h, etc.
+# XMLRPC_LIBRARIES - List of libraries when using xmlrpc.
+# XMLRPC_FOUND - True if xmlrpc found.
+#
# XMLRPC modules may be specified as components for this find module.
# Modules may be listed by running "xmlrpc-c-config". Modules include:
-# c++ C++ wrapper code
-# libwww-client libwww-based client
-# cgi-server CGI-based server
-# abyss-server ABYSS-based server
+#
+# ::
+#
+# c++ C++ wrapper code
+# libwww-client libwww-based client
+# cgi-server CGI-based server
+# abyss-server ABYSS-based server
+#
# Typical usage:
-# find_package(XMLRPC REQUIRED libwww-client)
+#
+# ::
+#
+# find_package(XMLRPC REQUIRED libwww-client)
#=============================================================================
# Copyright 2001-2009 Kitware, Inc.
@@ -61,10 +77,9 @@ if(XMLRPC_FOUND)
# Look for -I options.
set(XMLRPC_INCLUDE_DIRS)
foreach(flag ${XMLRPC_C_CONFIG_CFLAGS})
- if("${flag}" MATCHES "^-I")
- string(REGEX REPLACE "^-I" "" DIR "${flag}")
- file(TO_CMAKE_PATH "${DIR}" DIR)
- set(XMLRPC_INCLUDE_DIRS ${XMLRPC_INCLUDE_DIRS} "${DIR}")
+ if("${flag}" MATCHES "^-I(.+)")
+ file(TO_CMAKE_PATH "${CMAKE_MATCH_1}" DIR)
+ list(APPEND XMLRPC_INCLUDE_DIRS "${DIR}")
endif()
endforeach()
else()
@@ -99,13 +114,11 @@ if(XMLRPC_FOUND)
set(XMLRPC_LIBRARY_DIRS)
set(XMLRPC_LIBRARY_NAMES)
foreach(flag ${XMLRPC_C_CONFIG_LIBS})
- if("${flag}" MATCHES "^-L")
- string(REGEX REPLACE "^-L" "" DIR "${flag}")
- file(TO_CMAKE_PATH "${DIR}" DIR)
- set(XMLRPC_LIBRARY_DIRS ${XMLRPC_LIBRARY_DIRS} "${DIR}")
- elseif("${flag}" MATCHES "^-l")
- string(REGEX REPLACE "^-l" "" NAME "${flag}")
- set(XMLRPC_LIBRARY_NAMES ${XMLRPC_LIBRARY_NAMES} "${NAME}")
+ if("${flag}" MATCHES "^-L(.+)")
+ file(TO_CMAKE_PATH "${CMAKE_MATCH_1}" DIR)
+ list(APPEND XMLRPC_LIBRARY_DIRS "${DIR}")
+ elseif("${flag}" MATCHES "^-l(.+)")
+ list(APPEND XMLRPC_LIBRARY_NAMES "${CMAKE_MATCH_1}")
endif()
endforeach()
diff --git a/Modules/FindXalanC.cmake b/Modules/FindXalanC.cmake
new file mode 100644
index 000000000..016b7aabd
--- /dev/null
+++ b/Modules/FindXalanC.cmake
@@ -0,0 +1,162 @@
+#.rst:
+# FindXalanC
+# -----------
+#
+# Find the Apache Xalan-C++ XSL transform processor headers and libraries.
+#
+# Imported targets
+# ^^^^^^^^^^^^^^^^
+#
+# This module defines the following :prop_tgt:`IMPORTED` targets:
+#
+# ``XalanC::XalanC``
+# The Xalan-C++ ``xalan-c`` library, if found.
+#
+# Result variables
+# ^^^^^^^^^^^^^^^^
+#
+# This module will set the following variables in your project:
+#
+# ``XalanC_FOUND``
+# true if the Xalan headers and libraries were found
+# ``XalanC_VERSION``
+# Xalan release version
+# ``XalanC_INCLUDE_DIRS``
+# the directory containing the Xalan headers; note
+# ``XercesC_INCLUDE_DIRS`` is also required
+# ``XalanC_LIBRARIES``
+# Xalan libraries to be linked; note ``XercesC_LIBRARIES`` is also
+# required
+#
+# Cache variables
+# ^^^^^^^^^^^^^^^
+#
+# The following cache variables may also be set:
+#
+# ``XalanC_INCLUDE_DIR``
+# the directory containing the Xalan headers
+# ``XalanC_LIBRARY``
+# the Xalan library
+
+# Written by Roger Leigh <rleigh@codelibre.net>
+
+#=============================================================================
+# Copyright 2016 University of Dundee
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+function(_XalanC_GET_VERSION version_hdr)
+ file(STRINGS ${version_hdr} _contents REGEX "^[ \t]*#define XALAN_VERSION_.*")
+ if(_contents)
+ string(REGEX REPLACE "[^*]*#define XALAN_VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" XalanC_MAJOR "${_contents}")
+ string(REGEX REPLACE "[^*]*#define XALAN_VERSION_MINOR[ \t]+([0-9]+).*" "\\1" XalanC_MINOR "${_contents}")
+ string(REGEX REPLACE "[^*]*#define XALAN_VERSION_REVISION[ \t]+([0-9]+).*" "\\1" XalanC_PATCH "${_contents}")
+
+ if(NOT XalanC_MAJOR MATCHES "^[0-9]+$")
+ message(FATAL_ERROR "Version parsing failed for XALAN_VERSION_MAJOR!")
+ endif()
+ if(NOT XalanC_MINOR MATCHES "^[0-9]+$")
+ message(FATAL_ERROR "Version parsing failed for XALAN_VERSION_MINOR!")
+ endif()
+ if(NOT XalanC_PATCH MATCHES "^[0-9]+$")
+ message(FATAL_ERROR "Version parsing failed for XALAN_VERSION_REVISION!")
+ endif()
+
+ set(XalanC_VERSION "${XalanC_MAJOR}.${XalanC_MINOR}.${XalanC_PATCH}" PARENT_SCOPE)
+ set(XalanC_VERSION_MAJOR "${XalanC_MAJOR}" PARENT_SCOPE)
+ set(XalanC_VERSION_MINOR "${XalanC_MINOR}" PARENT_SCOPE)
+ set(XalanC_VERSION_PATCH "${XalanC_PATCH}" PARENT_SCOPE)
+ else()
+ message(FATAL_ERROR "Include file ${version_hdr} does not exist or does not contain expected version information")
+ endif()
+endfunction()
+
+# Find include directory
+find_path(XalanC_INCLUDE_DIR
+ NAMES "xalanc/XalanTransformer/XalanTransformer.hpp"
+ DOC "Xalan-C++ include directory")
+mark_as_advanced(XalanC_INCLUDE_DIR)
+
+if(XalanC_INCLUDE_DIR)
+ _XalanC_GET_VERSION("${XalanC_INCLUDE_DIR}/xalanc/Include/XalanVersion.hpp")
+endif()
+
+if(NOT XalanC_LIBRARY)
+ # Find all XalanC libraries
+ find_library(XalanC_LIBRARY_RELEASE
+ NAMES "Xalan-C" "xalan-c"
+ "Xalan-C_${XalanC_VERSION_MAJOR}"
+ "Xalan-C_${XalanC_VERSION_MAJOR}_${XalanC_VERSION_MINOR}"
+ DOC "Xalan-C++ libraries (release)")
+ find_library(XalanC_LIBRARY_DEBUG
+ NAMES "Xalan-CD" "xalan-cd"
+ "Xalan-C_${XalanC_VERSION_MAJOR}D"
+ "Xalan-C_${XalanC_VERSION_MAJOR}_${XalanC_VERSION_MINOR}D"
+ DOC "Xalan-C++ libraries (debug)")
+ include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
+ select_library_configurations(XalanC)
+ mark_as_advanced(XalanC_LIBRARY_RELEASE XalanC_LIBRARY_DEBUG)
+endif()
+
+unset(XalanC_VERSION_MAJOR)
+unset(XalanC_VERSION_MINOR)
+unset(XalanC_VERSION_PATCH)
+
+unset(XalanC_XERCESC_REQUIRED)
+if(XalanC_FIND_REQUIRED)
+ set(XalanC_XERCESC_REQUIRED REQUIRED)
+endif()
+find_package(XercesC ${XalanC_XERCESC_REQUIRED})
+unset(XalanC_XERCESC_REQUIRED)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(XalanC
+ FOUND_VAR XalanC_FOUND
+ REQUIRED_VARS XalanC_LIBRARY
+ XalanC_INCLUDE_DIR
+ XalanC_VERSION
+ XercesC_FOUND
+ VERSION_VAR XalanC_VERSION
+ FAIL_MESSAGE "Failed to find XalanC")
+
+if(XalanC_FOUND)
+ set(XalanC_INCLUDE_DIRS "${XalanC_INCLUDE_DIR}" ${XercesC_INCLUDE_DIRS})
+ set(XalanC_LIBRARIES "${XalanC_LIBRARY}" ${XercesC_LIBRARIES})
+
+ # For header-only libraries
+ if(NOT TARGET XalanC::XalanC)
+ add_library(XalanC::XalanC UNKNOWN IMPORTED)
+ if(XalanC_INCLUDE_DIRS)
+ set_target_properties(XalanC::XalanC PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${XalanC_INCLUDE_DIRS}")
+ endif()
+ if(EXISTS "${XalanC_LIBRARY}")
+ set_target_properties(XalanC::XalanC PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
+ IMPORTED_LOCATION "${XalanC_LIBRARY}")
+ endif()
+ if(EXISTS "${XalanC_LIBRARY_DEBUG}")
+ set_property(TARGET XalanC::XalanC APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS DEBUG)
+ set_target_properties(XalanC::XalanC PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX"
+ IMPORTED_LOCATION_DEBUG "${XalanC_LIBRARY_DEBUG}")
+ endif()
+ if(EXISTS "${XalanC_LIBRARY_RELEASE}")
+ set_property(TARGET XalanC::XalanC APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS RELEASE)
+ set_target_properties(XalanC::XalanC PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
+ IMPORTED_LOCATION_RELEASE "${XalanC_LIBRARY_RELEASE}")
+ endif()
+ set_target_properties(XalanC::XalanC PROPERTIES INTERFACE_LINK_LIBRARIES XercesC::XercesC)
+ endif()
+endif()
diff --git a/Modules/FindXercesC.cmake b/Modules/FindXercesC.cmake
new file mode 100644
index 000000000..a4b80e512
--- /dev/null
+++ b/Modules/FindXercesC.cmake
@@ -0,0 +1,140 @@
+#.rst:
+# FindXercesC
+# -----------
+#
+# Find the Apache Xerces-C++ validating XML parser headers and libraries.
+#
+# Imported targets
+# ^^^^^^^^^^^^^^^^
+#
+# This module defines the following :prop_tgt:`IMPORTED` targets:
+#
+# ``XercesC::XercesC``
+# The Xerces-C++ ``xerces-c`` library, if found.
+#
+# Result variables
+# ^^^^^^^^^^^^^^^^
+#
+# This module will set the following variables in your project:
+#
+# ``XercesC_FOUND``
+# true if the Xerces headers and libraries were found
+# ``XercesC_VERSION``
+# Xerces release version
+# ``XercesC_INCLUDE_DIRS``
+# the directory containing the Xerces headers
+# ``XercesC_LIBRARIES``
+# Xerces libraries to be linked
+#
+# Cache variables
+# ^^^^^^^^^^^^^^^
+#
+# The following cache variables may also be set:
+#
+# ``XercesC_INCLUDE_DIR``
+# the directory containing the Xerces headers
+# ``XercesC_LIBRARY``
+# the Xerces library
+
+# Written by Roger Leigh <rleigh@codelibre.net>
+
+#=============================================================================
+# Copyright 2014-2015 University of Dundee
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+function(_XercesC_GET_VERSION version_hdr)
+ file(STRINGS ${version_hdr} _contents REGEX "^[ \t]*#define XERCES_VERSION_.*")
+ if(_contents)
+ string(REGEX REPLACE ".*#define XERCES_VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" XercesC_MAJOR "${_contents}")
+ string(REGEX REPLACE ".*#define XERCES_VERSION_MINOR[ \t]+([0-9]+).*" "\\1" XercesC_MINOR "${_contents}")
+ string(REGEX REPLACE ".*#define XERCES_VERSION_REVISION[ \t]+([0-9]+).*" "\\1" XercesC_PATCH "${_contents}")
+
+ if(NOT XercesC_MAJOR MATCHES "^[0-9]+$")
+ message(FATAL_ERROR "Version parsing failed for XERCES_VERSION_MAJOR!")
+ endif()
+ if(NOT XercesC_MINOR MATCHES "^[0-9]+$")
+ message(FATAL_ERROR "Version parsing failed for XERCES_VERSION_MINOR!")
+ endif()
+ if(NOT XercesC_PATCH MATCHES "^[0-9]+$")
+ message(FATAL_ERROR "Version parsing failed for XERCES_VERSION_REVISION!")
+ endif()
+
+ set(XercesC_VERSION "${XercesC_MAJOR}.${XercesC_MINOR}.${XercesC_PATCH}" PARENT_SCOPE)
+ else()
+ message(FATAL_ERROR "Include file ${version_hdr} does not exist or does not contain expected version information")
+ endif()
+endfunction()
+
+# Find include directory
+find_path(XercesC_INCLUDE_DIR
+ NAMES "xercesc/util/PlatformUtils.hpp"
+ DOC "Xerces-C++ include directory")
+mark_as_advanced(XercesC_INCLUDE_DIR)
+
+if(NOT XercesC_LIBRARY)
+ # Find all XercesC libraries
+ find_library(XercesC_LIBRARY_RELEASE
+ NAMES "xerces-c" "xerces-c_3"
+ DOC "Xerces-C++ libraries (release)")
+ find_library(XercesC_LIBRARY_DEBUG
+ NAMES "xerces-cd" "xerces-c_3D" "xerces-c_3_1D"
+ DOC "Xerces-C++ libraries (debug)")
+ include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
+ select_library_configurations(XercesC)
+ mark_as_advanced(XercesC_LIBRARY_RELEASE XercesC_LIBRARY_DEBUG)
+endif()
+
+if(XercesC_INCLUDE_DIR)
+ _XercesC_GET_VERSION("${XercesC_INCLUDE_DIR}/xercesc/util/XercesVersion.hpp")
+endif()
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(XercesC
+ FOUND_VAR XercesC_FOUND
+ REQUIRED_VARS XercesC_LIBRARY
+ XercesC_INCLUDE_DIR
+ XercesC_VERSION
+ VERSION_VAR XercesC_VERSION
+ FAIL_MESSAGE "Failed to find XercesC")
+
+if(XercesC_FOUND)
+ set(XercesC_INCLUDE_DIRS "${XercesC_INCLUDE_DIR}")
+ set(XercesC_LIBRARIES "${XercesC_LIBRARY}")
+
+ # For header-only libraries
+ if(NOT TARGET XercesC::XercesC)
+ add_library(XercesC::XercesC UNKNOWN IMPORTED)
+ if(XercesC_INCLUDE_DIRS)
+ set_target_properties(XercesC::XercesC PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${XercesC_INCLUDE_DIRS}")
+ endif()
+ if(EXISTS "${XercesC_LIBRARY}")
+ set_target_properties(XercesC::XercesC PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
+ IMPORTED_LOCATION "${XercesC_LIBRARY}")
+ endif()
+ if(EXISTS "${XercesC_LIBRARY_DEBUG}")
+ set_property(TARGET XercesC::XercesC APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS DEBUG)
+ set_target_properties(XercesC::XercesC PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX"
+ IMPORTED_LOCATION_DEBUG "${XercesC_LIBRARY_DEBUG}")
+ endif()
+ if(EXISTS "${XercesC_LIBRARY_RELEASE}")
+ set_property(TARGET XercesC::XercesC APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS RELEASE)
+ set_target_properties(XercesC::XercesC PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
+ IMPORTED_LOCATION_RELEASE "${XercesC_LIBRARY_RELEASE}")
+ endif()
+ endif()
+endif()
diff --git a/Modules/FindZLIB.cmake b/Modules/FindZLIB.cmake
index 00b9c64da..a57f45008 100644
--- a/Modules/FindZLIB.cmake
+++ b/Modules/FindZLIB.cmake
@@ -1,25 +1,50 @@
-# - Find zlib
+#.rst:
+# FindZLIB
+# --------
+#
# Find the native ZLIB includes and library.
-# Once done this will define
#
-# ZLIB_INCLUDE_DIRS - where to find zlib.h, etc.
-# ZLIB_LIBRARIES - List of libraries when using zlib.
-# ZLIB_FOUND - True if zlib found.
+# IMPORTED Targets
+# ^^^^^^^^^^^^^^^^
+#
+# This module defines :prop_tgt:`IMPORTED` target ``ZLIB::ZLIB``, if
+# ZLIB has been found.
+#
+# Result Variables
+# ^^^^^^^^^^^^^^^^
+#
+# This module defines the following variables:
+#
+# ::
+#
+# ZLIB_INCLUDE_DIRS - where to find zlib.h, etc.
+# ZLIB_LIBRARIES - List of libraries when using zlib.
+# ZLIB_FOUND - True if zlib found.
#
-# ZLIB_VERSION_STRING - The version of zlib found (x.y.z)
-# ZLIB_VERSION_MAJOR - The major version of zlib
-# ZLIB_VERSION_MINOR - The minor version of zlib
-# ZLIB_VERSION_PATCH - The patch version of zlib
-# ZLIB_VERSION_TWEAK - The tweak version of zlib
+# ::
+#
+# ZLIB_VERSION_STRING - The version of zlib found (x.y.z)
+# ZLIB_VERSION_MAJOR - The major version of zlib
+# ZLIB_VERSION_MINOR - The minor version of zlib
+# ZLIB_VERSION_PATCH - The patch version of zlib
+# ZLIB_VERSION_TWEAK - The tweak version of zlib
+#
+# Backward Compatibility
+# ^^^^^^^^^^^^^^^^^^^^^^
#
# The following variable are provided for backward compatibility
#
-# ZLIB_MAJOR_VERSION - The major version of zlib
-# ZLIB_MINOR_VERSION - The minor version of zlib
-# ZLIB_PATCH_VERSION - The patch version of zlib
+# ::
+#
+# ZLIB_MAJOR_VERSION - The major version of zlib
+# ZLIB_MINOR_VERSION - The minor version of zlib
+# ZLIB_PATCH_VERSION - The patch version of zlib
#
-# An includer may set ZLIB_ROOT to a zlib installation root to tell
-# this module where to look.
+# Hints
+# ^^^^^
+#
+# A user may set ``ZLIB_ROOT`` to a zlib installation root to tell this
+# module where to look.
#=============================================================================
# Copyright 2001-2011 Kitware, Inc.
@@ -49,14 +74,28 @@ set(_ZLIB_SEARCH_NORMAL
)
list(APPEND _ZLIB_SEARCHES _ZLIB_SEARCH_NORMAL)
-set(ZLIB_NAMES z zlib zdll zlib1 zlibd zlibd1)
+set(ZLIB_NAMES z zlib zdll zlib1)
+set(ZLIB_NAMES_DEBUG zlibd zlibd1)
# Try each search configuration.
foreach(search ${_ZLIB_SEARCHES})
- find_path(ZLIB_INCLUDE_DIR NAMES zlib.h ${${search}} PATH_SUFFIXES include)
- find_library(ZLIB_LIBRARY NAMES ${ZLIB_NAMES} ${${search}} PATH_SUFFIXES lib)
+ find_path(ZLIB_INCLUDE_DIR NAMES zlib.h ${${search}} PATH_SUFFIXES include)
endforeach()
+# Allow ZLIB_LIBRARY to be set manually, as the location of the zlib library
+if(NOT ZLIB_LIBRARY)
+ foreach(search ${_ZLIB_SEARCHES})
+ find_library(ZLIB_LIBRARY_RELEASE NAMES ${ZLIB_NAMES} ${${search}} PATH_SUFFIXES lib)
+ find_library(ZLIB_LIBRARY_DEBUG NAMES ${ZLIB_NAMES_DEBUG} ${${search}} PATH_SUFFIXES lib)
+ endforeach()
+
+ include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
+ select_library_configurations(ZLIB)
+endif()
+
+unset(ZLIB_NAMES)
+unset(ZLIB_NAMES_DEBUG)
+
mark_as_advanced(ZLIB_LIBRARY ZLIB_INCLUDE_DIR)
if(ZLIB_INCLUDE_DIR AND EXISTS "${ZLIB_INCLUDE_DIR}/zlib.h")
@@ -69,7 +108,7 @@ if(ZLIB_INCLUDE_DIR AND EXISTS "${ZLIB_INCLUDE_DIR}/zlib.h")
# only append a TWEAK version if it exists:
set(ZLIB_VERSION_TWEAK "")
- if( "${ZLIB_H}" MATCHES "^.*ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+).*$")
+ if( "${ZLIB_H}" MATCHES "ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+)")
set(ZLIB_VERSION_TWEAK "${CMAKE_MATCH_1}")
set(ZLIB_VERSION_STRING "${ZLIB_VERSION_STRING}.${ZLIB_VERSION_TWEAK}")
endif()
@@ -87,6 +126,33 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZLIB REQUIRED_VARS ZLIB_LIBRARY ZLIB_INCLUDE_D
if(ZLIB_FOUND)
set(ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR})
- set(ZLIB_LIBRARIES ${ZLIB_LIBRARY})
-endif()
+ if(NOT ZLIB_LIBRARIES)
+ set(ZLIB_LIBRARIES ${ZLIB_LIBRARY})
+ endif()
+
+ if(NOT TARGET ZLIB::ZLIB)
+ add_library(ZLIB::ZLIB UNKNOWN IMPORTED)
+ set_target_properties(ZLIB::ZLIB PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${ZLIB_INCLUDE_DIRS}")
+
+ if(ZLIB_LIBRARY_RELEASE)
+ set_property(TARGET ZLIB::ZLIB APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS RELEASE)
+ set_target_properties(ZLIB::ZLIB PROPERTIES
+ IMPORTED_LOCATION_RELEASE "${ZLIB_LIBRARY_RELEASE}")
+ endif()
+
+ if(ZLIB_LIBRARY_DEBUG)
+ set_property(TARGET ZLIB::ZLIB APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS DEBUG)
+ set_target_properties(ZLIB::ZLIB PROPERTIES
+ IMPORTED_LOCATION_DEBUG "${ZLIB_LIBRARY_DEBUG}")
+ endif()
+
+ if(NOT ZLIB_LIBRARY_RELEASE AND NOT ZLIB_LIBRARY_DEBUG)
+ set_property(TARGET ZLIB::ZLIB APPEND PROPERTY
+ IMPORTED_LOCATION "${ZLIB_LIBRARY}")
+ endif()
+ endif()
+endif()
diff --git a/Modules/Findosg.cmake b/Modules/Findosg.cmake
index bc1e48a6e..5ab2846fc 100644
--- a/Modules/Findosg.cmake
+++ b/Modules/Findosg.cmake
@@ -1,31 +1,37 @@
+#.rst:
+# Findosg
+# -------
#
-# NOTE: It is highly recommended that you use the new FindOpenSceneGraph.cmake
-# introduced in CMake 2.6.3 and not use this Find module directly.
-#
-# This is part of the Findosg* suite used to find OpenSceneGraph components.
-# Each component is separate and you must opt in to each module. You must
-# also opt into OpenGL and OpenThreads (and Producer if needed) as these
-# modules won't do it for you. This is to allow you control over your own
-# system piece by piece in case you need to opt out of certain components
-# or change the Find behavior for a particular module (perhaps because the
-# default FindOpenGL.cmake module doesn't work with your system as an
-# example).
-# If you want to use a more convenient module that includes everything,
-# use the FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
-#
-# Locate osg
-# This module defines
-#
-# OSG_FOUND - Was the Osg found?
-# OSG_INCLUDE_DIR - Where to find the headers
-# OSG_LIBRARIES - The libraries to link against for the OSG (use this)
-#
-# OSG_LIBRARY - The OSG library
-# OSG_LIBRARY_DEBUG - The OSG debug library
-#
-# $OSGDIR is an environment variable that would
-# correspond to the ./configure --prefix=$OSGDIR
-# used in building osg.
+#
+#
+#
+#
+# NOTE: It is highly recommended that you use the new
+# FindOpenSceneGraph.cmake introduced in CMake 2.6.3 and not use this
+# Find module directly.
+#
+# This is part of the Findosg* suite used to find OpenSceneGraph
+# components. Each component is separate and you must opt in to each
+# module. You must also opt into OpenGL and OpenThreads (and Producer
+# if needed) as these modules won't do it for you. This is to allow you
+# control over your own system piece by piece in case you need to opt
+# out of certain components or change the Find behavior for a particular
+# module (perhaps because the default FindOpenGL.cmake module doesn't
+# work with your system as an example). If you want to use a more
+# convenient module that includes everything, use the
+# FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+#
+# Locate osg This module defines
+#
+# OSG_FOUND - Was the Osg found? OSG_INCLUDE_DIR - Where to find the
+# headers OSG_LIBRARIES - The libraries to link against for the OSG (use
+# this)
+#
+# OSG_LIBRARY - The OSG library OSG_LIBRARY_DEBUG - The OSG debug
+# library
+#
+# $OSGDIR is an environment variable that would correspond to the
+# ./configure --prefix=$OSGDIR used in building osg.
#
# Created by Eric Wing.
diff --git a/Modules/FindosgAnimation.cmake b/Modules/FindosgAnimation.cmake
index 121aefcec..403e68e76 100644
--- a/Modules/FindosgAnimation.cmake
+++ b/Modules/FindosgAnimation.cmake
@@ -1,27 +1,31 @@
-# This is part of the Findosg* suite used to find OpenSceneGraph components.
-# Each component is separate and you must opt in to each module. You must
-# also opt into OpenGL and OpenThreads (and Producer if needed) as these
-# modules won't do it for you. This is to allow you control over your own
-# system piece by piece in case you need to opt out of certain components
-# or change the Find behavior for a particular module (perhaps because the
-# default FindOpenGL.cmake module doesn't work with your system as an
-# example).
-# If you want to use a more convenient module that includes everything,
-# use the FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
-#
-# Locate osgAnimation
-# This module defines
-#
-# OSGANIMATION_FOUND - Was osgAnimation found?
-# OSGANIMATION_INCLUDE_DIR - Where to find the headers
-# OSGANIMATION_LIBRARIES - The libraries to link against for the OSG (use this)
-#
-# OSGANIMATION_LIBRARY - The OSG library
-# OSGANIMATION_LIBRARY_DEBUG - The OSG debug library
-#
-# $OSGDIR is an environment variable that would
-# correspond to the ./configure --prefix=$OSGDIR
-# used in building osg.
+#.rst:
+# FindosgAnimation
+# ----------------
+#
+#
+#
+# This is part of the Findosg* suite used to find OpenSceneGraph
+# components. Each component is separate and you must opt in to each
+# module. You must also opt into OpenGL and OpenThreads (and Producer
+# if needed) as these modules won't do it for you. This is to allow you
+# control over your own system piece by piece in case you need to opt
+# out of certain components or change the Find behavior for a particular
+# module (perhaps because the default FindOpenGL.cmake module doesn't
+# work with your system as an example). If you want to use a more
+# convenient module that includes everything, use the
+# FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+#
+# Locate osgAnimation This module defines
+#
+# OSGANIMATION_FOUND - Was osgAnimation found? OSGANIMATION_INCLUDE_DIR
+# - Where to find the headers OSGANIMATION_LIBRARIES - The libraries to
+# link against for the OSG (use this)
+#
+# OSGANIMATION_LIBRARY - The OSG library OSGANIMATION_LIBRARY_DEBUG -
+# The OSG debug library
+#
+# $OSGDIR is an environment variable that would correspond to the
+# ./configure --prefix=$OSGDIR used in building osg.
#
# Created by Eric Wing.
diff --git a/Modules/FindosgDB.cmake b/Modules/FindosgDB.cmake
index 1ed94a108..0e5bdef82 100644
--- a/Modules/FindosgDB.cmake
+++ b/Modules/FindosgDB.cmake
@@ -1,27 +1,31 @@
-# This is part of the Findosg* suite used to find OpenSceneGraph components.
-# Each component is separate and you must opt in to each module. You must
-# also opt into OpenGL and OpenThreads (and Producer if needed) as these
-# modules won't do it for you. This is to allow you control over your own
-# system piece by piece in case you need to opt out of certain components
-# or change the Find behavior for a particular module (perhaps because the
-# default FindOpenGL.cmake module doesn't work with your system as an
-# example).
-# If you want to use a more convenient module that includes everything,
-# use the FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
-#
-# Locate osgDB
-# This module defines
-#
-# OSGDB_FOUND - Was osgDB found?
-# OSGDB_INCLUDE_DIR - Where to find the headers
-# OSGDB_LIBRARIES - The libraries to link against for the osgDB (use this)
-#
-# OSGDB_LIBRARY - The osgDB library
-# OSGDB_LIBRARY_DEBUG - The osgDB debug library
-#
-# $OSGDIR is an environment variable that would
-# correspond to the ./configure --prefix=$OSGDIR
-# used in building osg.
+#.rst:
+# FindosgDB
+# ---------
+#
+#
+#
+# This is part of the Findosg* suite used to find OpenSceneGraph
+# components. Each component is separate and you must opt in to each
+# module. You must also opt into OpenGL and OpenThreads (and Producer
+# if needed) as these modules won't do it for you. This is to allow you
+# control over your own system piece by piece in case you need to opt
+# out of certain components or change the Find behavior for a particular
+# module (perhaps because the default FindOpenGL.cmake module doesn't
+# work with your system as an example). If you want to use a more
+# convenient module that includes everything, use the
+# FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+#
+# Locate osgDB This module defines
+#
+# OSGDB_FOUND - Was osgDB found? OSGDB_INCLUDE_DIR - Where to find the
+# headers OSGDB_LIBRARIES - The libraries to link against for the osgDB
+# (use this)
+#
+# OSGDB_LIBRARY - The osgDB library OSGDB_LIBRARY_DEBUG - The osgDB
+# debug library
+#
+# $OSGDIR is an environment variable that would correspond to the
+# ./configure --prefix=$OSGDIR used in building osg.
#
# Created by Eric Wing.
diff --git a/Modules/FindosgFX.cmake b/Modules/FindosgFX.cmake
index 1f1d59f46..7b2cb76c1 100644
--- a/Modules/FindosgFX.cmake
+++ b/Modules/FindosgFX.cmake
@@ -1,27 +1,31 @@
-# This is part of the Findosg* suite used to find OpenSceneGraph components.
-# Each component is separate and you must opt in to each module. You must
-# also opt into OpenGL and OpenThreads (and Producer if needed) as these
-# modules won't do it for you. This is to allow you control over your own
-# system piece by piece in case you need to opt out of certain components
-# or change the Find behavior for a particular module (perhaps because the
-# default FindOpenGL.cmake module doesn't work with your system as an
-# example).
-# If you want to use a more convenient module that includes everything,
-# use the FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
-#
-# Locate osgFX
-# This module defines
-#
-# OSGFX_FOUND - Was osgFX found?
-# OSGFX_INCLUDE_DIR - Where to find the headers
-# OSGFX_LIBRARIES - The libraries to link against for the osgFX (use this)
-#
-# OSGFX_LIBRARY - The osgFX library
-# OSGFX_LIBRARY_DEBUG - The osgFX debug library
-#
-# $OSGDIR is an environment variable that would
-# correspond to the ./configure --prefix=$OSGDIR
-# used in building osg.
+#.rst:
+# FindosgFX
+# ---------
+#
+#
+#
+# This is part of the Findosg* suite used to find OpenSceneGraph
+# components. Each component is separate and you must opt in to each
+# module. You must also opt into OpenGL and OpenThreads (and Producer
+# if needed) as these modules won't do it for you. This is to allow you
+# control over your own system piece by piece in case you need to opt
+# out of certain components or change the Find behavior for a particular
+# module (perhaps because the default FindOpenGL.cmake module doesn't
+# work with your system as an example). If you want to use a more
+# convenient module that includes everything, use the
+# FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+#
+# Locate osgFX This module defines
+#
+# OSGFX_FOUND - Was osgFX found? OSGFX_INCLUDE_DIR - Where to find the
+# headers OSGFX_LIBRARIES - The libraries to link against for the osgFX
+# (use this)
+#
+# OSGFX_LIBRARY - The osgFX library OSGFX_LIBRARY_DEBUG - The osgFX
+# debug library
+#
+# $OSGDIR is an environment variable that would correspond to the
+# ./configure --prefix=$OSGDIR used in building osg.
#
# Created by Eric Wing.
diff --git a/Modules/FindosgGA.cmake b/Modules/FindosgGA.cmake
index e60f7f5a7..2e80ff2fa 100644
--- a/Modules/FindosgGA.cmake
+++ b/Modules/FindosgGA.cmake
@@ -1,27 +1,31 @@
-# This is part of the Findosg* suite used to find OpenSceneGraph components.
-# Each component is separate and you must opt in to each module. You must
-# also opt into OpenGL and OpenThreads (and Producer if needed) as these
-# modules won't do it for you. This is to allow you control over your own
-# system piece by piece in case you need to opt out of certain components
-# or change the Find behavior for a particular module (perhaps because the
-# default FindOpenGL.cmake module doesn't work with your system as an
-# example).
-# If you want to use a more convenient module that includes everything,
-# use the FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
-#
-# Locate osgGA
-# This module defines
-#
-# OSGGA_FOUND - Was osgGA found?
-# OSGGA_INCLUDE_DIR - Where to find the headers
-# OSGGA_LIBRARIES - The libraries to link against for the osgGA (use this)
-#
-# OSGGA_LIBRARY - The osgGA library
-# OSGGA_LIBRARY_DEBUG - The osgGA debug library
-#
-# $OSGDIR is an environment variable that would
-# correspond to the ./configure --prefix=$OSGDIR
-# used in building osg.
+#.rst:
+# FindosgGA
+# ---------
+#
+#
+#
+# This is part of the Findosg* suite used to find OpenSceneGraph
+# components. Each component is separate and you must opt in to each
+# module. You must also opt into OpenGL and OpenThreads (and Producer
+# if needed) as these modules won't do it for you. This is to allow you
+# control over your own system piece by piece in case you need to opt
+# out of certain components or change the Find behavior for a particular
+# module (perhaps because the default FindOpenGL.cmake module doesn't
+# work with your system as an example). If you want to use a more
+# convenient module that includes everything, use the
+# FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+#
+# Locate osgGA This module defines
+#
+# OSGGA_FOUND - Was osgGA found? OSGGA_INCLUDE_DIR - Where to find the
+# headers OSGGA_LIBRARIES - The libraries to link against for the osgGA
+# (use this)
+#
+# OSGGA_LIBRARY - The osgGA library OSGGA_LIBRARY_DEBUG - The osgGA
+# debug library
+#
+# $OSGDIR is an environment variable that would correspond to the
+# ./configure --prefix=$OSGDIR used in building osg.
#
# Created by Eric Wing.
diff --git a/Modules/FindosgIntrospection.cmake b/Modules/FindosgIntrospection.cmake
index a430ad6e9..1b52a6a24 100644
--- a/Modules/FindosgIntrospection.cmake
+++ b/Modules/FindosgIntrospection.cmake
@@ -1,27 +1,32 @@
-# This is part of the Findosg* suite used to find OpenSceneGraph components.
-# Each component is separate and you must opt in to each module. You must
-# also opt into OpenGL and OpenThreads (and Producer if needed) as these
-# modules won't do it for you. This is to allow you control over your own
-# system piece by piece in case you need to opt out of certain components
-# or change the Find behavior for a particular module (perhaps because the
-# default FindOpenGL.cmake module doesn't work with your system as an
-# example).
-# If you want to use a more convenient module that includes everything,
-# use the FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
-#
-# Locate osgINTROSPECTION
-# This module defines
+#.rst:
+# FindosgIntrospection
+# --------------------
+#
+#
+#
+# This is part of the Findosg* suite used to find OpenSceneGraph
+# components. Each component is separate and you must opt in to each
+# module. You must also opt into OpenGL and OpenThreads (and Producer
+# if needed) as these modules won't do it for you. This is to allow you
+# control over your own system piece by piece in case you need to opt
+# out of certain components or change the Find behavior for a particular
+# module (perhaps because the default FindOpenGL.cmake module doesn't
+# work with your system as an example). If you want to use a more
+# convenient module that includes everything, use the
+# FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+#
+# Locate osgINTROSPECTION This module defines
#
# OSGINTROSPECTION_FOUND - Was osgIntrospection found?
# OSGINTROSPECTION_INCLUDE_DIR - Where to find the headers
-# OSGINTROSPECTION_LIBRARIES - The libraries to link for osgIntrospection (use this)
+# OSGINTROSPECTION_LIBRARIES - The libraries to link for
+# osgIntrospection (use this)
#
# OSGINTROSPECTION_LIBRARY - The osgIntrospection library
# OSGINTROSPECTION_LIBRARY_DEBUG - The osgIntrospection debug library
#
-# $OSGDIR is an environment variable that would
-# correspond to the ./configure --prefix=$OSGDIR
-# used in building osg.
+# $OSGDIR is an environment variable that would correspond to the
+# ./configure --prefix=$OSGDIR used in building osg.
#
# Created by Eric Wing.
diff --git a/Modules/FindosgManipulator.cmake b/Modules/FindosgManipulator.cmake
index 32d6def7b..6f5408241 100644
--- a/Modules/FindosgManipulator.cmake
+++ b/Modules/FindosgManipulator.cmake
@@ -1,27 +1,32 @@
-# This is part of the Findosg* suite used to find OpenSceneGraph components.
-# Each component is separate and you must opt in to each module. You must
-# also opt into OpenGL and OpenThreads (and Producer if needed) as these
-# modules won't do it for you. This is to allow you control over your own
-# system piece by piece in case you need to opt out of certain components
-# or change the Find behavior for a particular module (perhaps because the
-# default FindOpenGL.cmake module doesn't work with your system as an
-# example).
-# If you want to use a more convenient module that includes everything,
-# use the FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
-#
-# Locate osgManipulator
-# This module defines
+#.rst:
+# FindosgManipulator
+# ------------------
+#
+#
+#
+# This is part of the Findosg* suite used to find OpenSceneGraph
+# components. Each component is separate and you must opt in to each
+# module. You must also opt into OpenGL and OpenThreads (and Producer
+# if needed) as these modules won't do it for you. This is to allow you
+# control over your own system piece by piece in case you need to opt
+# out of certain components or change the Find behavior for a particular
+# module (perhaps because the default FindOpenGL.cmake module doesn't
+# work with your system as an example). If you want to use a more
+# convenient module that includes everything, use the
+# FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+#
+# Locate osgManipulator This module defines
#
# OSGMANIPULATOR_FOUND - Was osgManipulator found?
# OSGMANIPULATOR_INCLUDE_DIR - Where to find the headers
-# OSGMANIPULATOR_LIBRARIES - The libraries to link for osgManipulator (use this)
+# OSGMANIPULATOR_LIBRARIES - The libraries to link for osgManipulator
+# (use this)
#
# OSGMANIPULATOR_LIBRARY - The osgManipulator library
# OSGMANIPULATOR_LIBRARY_DEBUG - The osgManipulator debug library
#
-# $OSGDIR is an environment variable that would
-# correspond to the ./configure --prefix=$OSGDIR
-# used in building osg.
+# $OSGDIR is an environment variable that would correspond to the
+# ./configure --prefix=$OSGDIR used in building osg.
#
# Created by Eric Wing.
diff --git a/Modules/FindosgParticle.cmake b/Modules/FindosgParticle.cmake
index 1a6ae0b93..82e9a1364 100644
--- a/Modules/FindosgParticle.cmake
+++ b/Modules/FindosgParticle.cmake
@@ -1,27 +1,31 @@
-# This is part of the Findosg* suite used to find OpenSceneGraph components.
-# Each component is separate and you must opt in to each module. You must
-# also opt into OpenGL and OpenThreads (and Producer if needed) as these
-# modules won't do it for you. This is to allow you control over your own
-# system piece by piece in case you need to opt out of certain components
-# or change the Find behavior for a particular module (perhaps because the
-# default FindOpenGL.cmake module doesn't work with your system as an
-# example).
-# If you want to use a more convenient module that includes everything,
-# use the FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
-#
-# Locate osgParticle
-# This module defines
-#
-# OSGPARTICLE_FOUND - Was osgParticle found?
-# OSGPARTICLE_INCLUDE_DIR - Where to find the headers
-# OSGPARTICLE_LIBRARIES - The libraries to link for osgParticle (use this)
+#.rst:
+# FindosgParticle
+# ---------------
+#
+#
+#
+# This is part of the Findosg* suite used to find OpenSceneGraph
+# components. Each component is separate and you must opt in to each
+# module. You must also opt into OpenGL and OpenThreads (and Producer
+# if needed) as these modules won't do it for you. This is to allow you
+# control over your own system piece by piece in case you need to opt
+# out of certain components or change the Find behavior for a particular
+# module (perhaps because the default FindOpenGL.cmake module doesn't
+# work with your system as an example). If you want to use a more
+# convenient module that includes everything, use the
+# FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+#
+# Locate osgParticle This module defines
+#
+# OSGPARTICLE_FOUND - Was osgParticle found? OSGPARTICLE_INCLUDE_DIR -
+# Where to find the headers OSGPARTICLE_LIBRARIES - The libraries to
+# link for osgParticle (use this)
#
# OSGPARTICLE_LIBRARY - The osgParticle library
# OSGPARTICLE_LIBRARY_DEBUG - The osgParticle debug library
#
-# $OSGDIR is an environment variable that would
-# correspond to the ./configure --prefix=$OSGDIR
-# used in building osg.
+# $OSGDIR is an environment variable that would correspond to the
+# ./configure --prefix=$OSGDIR used in building osg.
#
# Created by Eric Wing.
diff --git a/Modules/FindosgPresentation.cmake b/Modules/FindosgPresentation.cmake
index 412502a8c..1cd57b301 100644
--- a/Modules/FindosgPresentation.cmake
+++ b/Modules/FindosgPresentation.cmake
@@ -1,30 +1,35 @@
-# This is part of the Findosg* suite used to find OpenSceneGraph components.
-# Each component is separate and you must opt in to each module. You must
-# also opt into OpenGL and OpenThreads (and Producer if needed) as these
-# modules won't do it for you. This is to allow you control over your own
-# system piece by piece in case you need to opt out of certain components
-# or change the Find behavior for a particular module (perhaps because the
-# default FindOpenGL.cmake module doesn't work with your system as an
-# example).
-# If you want to use a more convenient module that includes everything,
-# use the FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
-#
-# Locate osgPresentation
-# This module defines
+#.rst:
+# FindosgPresentation
+# -------------------
+#
+#
+#
+# This is part of the Findosg* suite used to find OpenSceneGraph
+# components. Each component is separate and you must opt in to each
+# module. You must also opt into OpenGL and OpenThreads (and Producer
+# if needed) as these modules won't do it for you. This is to allow you
+# control over your own system piece by piece in case you need to opt
+# out of certain components or change the Find behavior for a particular
+# module (perhaps because the default FindOpenGL.cmake module doesn't
+# work with your system as an example). If you want to use a more
+# convenient module that includes everything, use the
+# FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+#
+# Locate osgPresentation This module defines
#
# OSGPRESENTATION_FOUND - Was osgPresentation found?
# OSGPRESENTATION_INCLUDE_DIR - Where to find the headers
-# OSGPRESENTATION_LIBRARIES - The libraries to link for osgPresentation (use this)
+# OSGPRESENTATION_LIBRARIES - The libraries to link for osgPresentation
+# (use this)
#
# OSGPRESENTATION_LIBRARY - The osgPresentation library
# OSGPRESENTATION_LIBRARY_DEBUG - The osgPresentation debug library
#
-# $OSGDIR is an environment variable that would
-# correspond to the ./configure --prefix=$OSGDIR
-# used in building osg.
+# $OSGDIR is an environment variable that would correspond to the
+# ./configure --prefix=$OSGDIR used in building osg.
#
-# Created by Eric Wing.
-# Modified to work with osgPresentation by Robert Osfield, January 2012.
+# Created by Eric Wing. Modified to work with osgPresentation by Robert
+# Osfield, January 2012.
#=============================================================================
# Copyright 2007-2009 Kitware, Inc.
diff --git a/Modules/FindosgProducer.cmake b/Modules/FindosgProducer.cmake
index ea561a036..ad4902b86 100644
--- a/Modules/FindosgProducer.cmake
+++ b/Modules/FindosgProducer.cmake
@@ -1,27 +1,31 @@
-# This is part of the Findosg* suite used to find OpenSceneGraph components.
-# Each component is separate and you must opt in to each module. You must
-# also opt into OpenGL and OpenThreads (and Producer if needed) as these
-# modules won't do it for you. This is to allow you control over your own
-# system piece by piece in case you need to opt out of certain components
-# or change the Find behavior for a particular module (perhaps because the
-# default FindOpenGL.cmake module doesn't work with your system as an
-# example).
-# If you want to use a more convenient module that includes everything,
-# use the FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
-#
-# Locate osgProducer
-# This module defines
-#
-# OSGPRODUCER_FOUND - Was osgProducer found?
-# OSGPRODUCER_INCLUDE_DIR - Where to find the headers
-# OSGPRODUCER_LIBRARIES - The libraries to link for osgProducer (use this)
+#.rst:
+# FindosgProducer
+# ---------------
+#
+#
+#
+# This is part of the Findosg* suite used to find OpenSceneGraph
+# components. Each component is separate and you must opt in to each
+# module. You must also opt into OpenGL and OpenThreads (and Producer
+# if needed) as these modules won't do it for you. This is to allow you
+# control over your own system piece by piece in case you need to opt
+# out of certain components or change the Find behavior for a particular
+# module (perhaps because the default FindOpenGL.cmake module doesn't
+# work with your system as an example). If you want to use a more
+# convenient module that includes everything, use the
+# FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+#
+# Locate osgProducer This module defines
+#
+# OSGPRODUCER_FOUND - Was osgProducer found? OSGPRODUCER_INCLUDE_DIR -
+# Where to find the headers OSGPRODUCER_LIBRARIES - The libraries to
+# link for osgProducer (use this)
#
# OSGPRODUCER_LIBRARY - The osgProducer library
# OSGPRODUCER_LIBRARY_DEBUG - The osgProducer debug library
#
-# $OSGDIR is an environment variable that would
-# correspond to the ./configure --prefix=$OSGDIR
-# used in building osg.
+# $OSGDIR is an environment variable that would correspond to the
+# ./configure --prefix=$OSGDIR used in building osg.
#
# Created by Eric Wing.
diff --git a/Modules/FindosgQt.cmake b/Modules/FindosgQt.cmake
index c7e8fee64..b5c1718c8 100644
--- a/Modules/FindosgQt.cmake
+++ b/Modules/FindosgQt.cmake
@@ -1,30 +1,33 @@
-# This is part of the Findosg* suite used to find OpenSceneGraph components.
-# Each component is separate and you must opt in to each module. You must
-# also opt into OpenGL and OpenThreads (and Producer if needed) as these
-# modules won't do it for you. This is to allow you control over your own
-# system piece by piece in case you need to opt out of certain components
-# or change the Find behavior for a particular module (perhaps because the
-# default FindOpenGL.cmake module doesn't work with your system as an
-# example).
-# If you want to use a more convenient module that includes everything,
-# use the FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
-#
-# Locate osgQt
-# This module defines
-#
-# OSGQT_FOUND - Was osgQt found?
-# OSGQT_INCLUDE_DIR - Where to find the headers
-# OSGQT_LIBRARIES - The libraries to link for osgQt (use this)
-#
-# OSGQT_LIBRARY - The osgQt library
-# OSGQT_LIBRARY_DEBUG - The osgQt debug library
-#
-# $OSGDIR is an environment variable that would
-# correspond to the ./configure --prefix=$OSGDIR
-# used in building osg.
-#
-# Created by Eric Wing.
-# Modified to work with osgQt by Robert Osfield, January 2012.
+#.rst:
+# FindosgQt
+# ---------
+#
+#
+#
+# This is part of the Findosg* suite used to find OpenSceneGraph
+# components. Each component is separate and you must opt in to each
+# module. You must also opt into OpenGL and OpenThreads (and Producer
+# if needed) as these modules won't do it for you. This is to allow you
+# control over your own system piece by piece in case you need to opt
+# out of certain components or change the Find behavior for a particular
+# module (perhaps because the default FindOpenGL.cmake module doesn't
+# work with your system as an example). If you want to use a more
+# convenient module that includes everything, use the
+# FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+#
+# Locate osgQt This module defines
+#
+# OSGQT_FOUND - Was osgQt found? OSGQT_INCLUDE_DIR - Where to find the
+# headers OSGQT_LIBRARIES - The libraries to link for osgQt (use this)
+#
+# OSGQT_LIBRARY - The osgQt library OSGQT_LIBRARY_DEBUG - The osgQt
+# debug library
+#
+# $OSGDIR is an environment variable that would correspond to the
+# ./configure --prefix=$OSGDIR used in building osg.
+#
+# Created by Eric Wing. Modified to work with osgQt by Robert Osfield,
+# January 2012.
#=============================================================================
# Copyright 2007-2009 Kitware, Inc.
diff --git a/Modules/FindosgShadow.cmake b/Modules/FindosgShadow.cmake
index f3be0bfdf..b0d22e7af 100644
--- a/Modules/FindosgShadow.cmake
+++ b/Modules/FindosgShadow.cmake
@@ -1,27 +1,31 @@
-# This is part of the Findosg* suite used to find OpenSceneGraph components.
-# Each component is separate and you must opt in to each module. You must
-# also opt into OpenGL and OpenThreads (and Producer if needed) as these
-# modules won't do it for you. This is to allow you control over your own
-# system piece by piece in case you need to opt out of certain components
-# or change the Find behavior for a particular module (perhaps because the
-# default FindOpenGL.cmake module doesn't work with your system as an
-# example).
-# If you want to use a more convenient module that includes everything,
-# use the FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
-#
-# Locate osgShadow
-# This module defines
-#
-# OSGSHADOW_FOUND - Was osgShadow found?
-# OSGSHADOW_INCLUDE_DIR - Where to find the headers
-# OSGSHADOW_LIBRARIES - The libraries to link for osgShadow (use this)
-#
-# OSGSHADOW_LIBRARY - The osgShadow library
-# OSGSHADOW_LIBRARY_DEBUG - The osgShadow debug library
-#
-# $OSGDIR is an environment variable that would
-# correspond to the ./configure --prefix=$OSGDIR
-# used in building osg.
+#.rst:
+# FindosgShadow
+# -------------
+#
+#
+#
+# This is part of the Findosg* suite used to find OpenSceneGraph
+# components. Each component is separate and you must opt in to each
+# module. You must also opt into OpenGL and OpenThreads (and Producer
+# if needed) as these modules won't do it for you. This is to allow you
+# control over your own system piece by piece in case you need to opt
+# out of certain components or change the Find behavior for a particular
+# module (perhaps because the default FindOpenGL.cmake module doesn't
+# work with your system as an example). If you want to use a more
+# convenient module that includes everything, use the
+# FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+#
+# Locate osgShadow This module defines
+#
+# OSGSHADOW_FOUND - Was osgShadow found? OSGSHADOW_INCLUDE_DIR - Where
+# to find the headers OSGSHADOW_LIBRARIES - The libraries to link for
+# osgShadow (use this)
+#
+# OSGSHADOW_LIBRARY - The osgShadow library OSGSHADOW_LIBRARY_DEBUG -
+# The osgShadow debug library
+#
+# $OSGDIR is an environment variable that would correspond to the
+# ./configure --prefix=$OSGDIR used in building osg.
#
# Created by Eric Wing.
diff --git a/Modules/FindosgSim.cmake b/Modules/FindosgSim.cmake
index 19cd17582..ce088dc6d 100644
--- a/Modules/FindosgSim.cmake
+++ b/Modules/FindosgSim.cmake
@@ -1,27 +1,31 @@
-# This is part of the Findosg* suite used to find OpenSceneGraph components.
-# Each component is separate and you must opt in to each module. You must
-# also opt into OpenGL and OpenThreads (and Producer if needed) as these
-# modules won't do it for you. This is to allow you control over your own
-# system piece by piece in case you need to opt out of certain components
-# or change the Find behavior for a particular module (perhaps because the
-# default FindOpenGL.cmake module doesn't work with your system as an
-# example).
-# If you want to use a more convenient module that includes everything,
-# use the FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
-#
-# Locate osgSim
-# This module defines
-#
-# OSGSIM_FOUND - Was osgSim found?
-# OSGSIM_INCLUDE_DIR - Where to find the headers
-# OSGSIM_LIBRARIES - The libraries to link for osgSim (use this)
-#
-# OSGSIM_LIBRARY - The osgSim library
-# OSGSIM_LIBRARY_DEBUG - The osgSim debug library
-#
-# $OSGDIR is an environment variable that would
-# correspond to the ./configure --prefix=$OSGDIR
-# used in building osg.
+#.rst:
+# FindosgSim
+# ----------
+#
+#
+#
+# This is part of the Findosg* suite used to find OpenSceneGraph
+# components. Each component is separate and you must opt in to each
+# module. You must also opt into OpenGL and OpenThreads (and Producer
+# if needed) as these modules won't do it for you. This is to allow you
+# control over your own system piece by piece in case you need to opt
+# out of certain components or change the Find behavior for a particular
+# module (perhaps because the default FindOpenGL.cmake module doesn't
+# work with your system as an example). If you want to use a more
+# convenient module that includes everything, use the
+# FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+#
+# Locate osgSim This module defines
+#
+# OSGSIM_FOUND - Was osgSim found? OSGSIM_INCLUDE_DIR - Where to find
+# the headers OSGSIM_LIBRARIES - The libraries to link for osgSim (use
+# this)
+#
+# OSGSIM_LIBRARY - The osgSim library OSGSIM_LIBRARY_DEBUG - The osgSim
+# debug library
+#
+# $OSGDIR is an environment variable that would correspond to the
+# ./configure --prefix=$OSGDIR used in building osg.
#
# Created by Eric Wing.
diff --git a/Modules/FindosgTerrain.cmake b/Modules/FindosgTerrain.cmake
index 4b7249e62..bfde773ef 100644
--- a/Modules/FindosgTerrain.cmake
+++ b/Modules/FindosgTerrain.cmake
@@ -1,27 +1,31 @@
-# This is part of the Findosg* suite used to find OpenSceneGraph components.
-# Each component is separate and you must opt in to each module. You must
-# also opt into OpenGL and OpenThreads (and Producer if needed) as these
-# modules won't do it for you. This is to allow you control over your own
-# system piece by piece in case you need to opt out of certain components
-# or change the Find behavior for a particular module (perhaps because the
-# default FindOpenGL.cmake module doesn't work with your system as an
-# example).
-# If you want to use a more convenient module that includes everything,
-# use the FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
-#
-# Locate osgTerrain
-# This module defines
-#
-# OSGTERRAIN_FOUND - Was osgTerrain found?
-# OSGTERRAIN_INCLUDE_DIR - Where to find the headers
-# OSGTERRAIN_LIBRARIES - The libraries to link for osgTerrain (use this)
-#
-# OSGTERRAIN_LIBRARY - The osgTerrain library
-# OSGTERRAIN_LIBRARY_DEBUG - The osgTerrain debug library
-#
-# $OSGDIR is an environment variable that would
-# correspond to the ./configure --prefix=$OSGDIR
-# used in building osg.
+#.rst:
+# FindosgTerrain
+# --------------
+#
+#
+#
+# This is part of the Findosg* suite used to find OpenSceneGraph
+# components. Each component is separate and you must opt in to each
+# module. You must also opt into OpenGL and OpenThreads (and Producer
+# if needed) as these modules won't do it for you. This is to allow you
+# control over your own system piece by piece in case you need to opt
+# out of certain components or change the Find behavior for a particular
+# module (perhaps because the default FindOpenGL.cmake module doesn't
+# work with your system as an example). If you want to use a more
+# convenient module that includes everything, use the
+# FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+#
+# Locate osgTerrain This module defines
+#
+# OSGTERRAIN_FOUND - Was osgTerrain found? OSGTERRAIN_INCLUDE_DIR -
+# Where to find the headers OSGTERRAIN_LIBRARIES - The libraries to link
+# for osgTerrain (use this)
+#
+# OSGTERRAIN_LIBRARY - The osgTerrain library OSGTERRAIN_LIBRARY_DEBUG -
+# The osgTerrain debug library
+#
+# $OSGDIR is an environment variable that would correspond to the
+# ./configure --prefix=$OSGDIR used in building osg.
#
# Created by Eric Wing.
diff --git a/Modules/FindosgText.cmake b/Modules/FindosgText.cmake
index 41683c728..32cd115c1 100644
--- a/Modules/FindosgText.cmake
+++ b/Modules/FindosgText.cmake
@@ -1,27 +1,31 @@
-# This is part of the Findosg* suite used to find OpenSceneGraph components.
-# Each component is separate and you must opt in to each module. You must
-# also opt into OpenGL and OpenThreads (and Producer if needed) as these
-# modules won't do it for you. This is to allow you control over your own
-# system piece by piece in case you need to opt out of certain components
-# or change the Find behavior for a particular module (perhaps because the
-# default FindOpenGL.cmake module doesn't work with your system as an
-# example).
-# If you want to use a more convenient module that includes everything,
-# use the FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
-#
-# Locate osgText
-# This module defines
-#
-# OSGTEXT_FOUND - Was osgText found?
-# OSGTEXT_INCLUDE_DIR - Where to find the headers
-# OSGTEXT_LIBRARIES - The libraries to link for osgText (use this)
-#
-# OSGTEXT_LIBRARY - The osgText library
-# OSGTEXT_LIBRARY_DEBUG - The osgText debug library
-#
-# $OSGDIR is an environment variable that would
-# correspond to the ./configure --prefix=$OSGDIR
-# used in building osg.
+#.rst:
+# FindosgText
+# -----------
+#
+#
+#
+# This is part of the Findosg* suite used to find OpenSceneGraph
+# components. Each component is separate and you must opt in to each
+# module. You must also opt into OpenGL and OpenThreads (and Producer
+# if needed) as these modules won't do it for you. This is to allow you
+# control over your own system piece by piece in case you need to opt
+# out of certain components or change the Find behavior for a particular
+# module (perhaps because the default FindOpenGL.cmake module doesn't
+# work with your system as an example). If you want to use a more
+# convenient module that includes everything, use the
+# FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+#
+# Locate osgText This module defines
+#
+# OSGTEXT_FOUND - Was osgText found? OSGTEXT_INCLUDE_DIR - Where to find
+# the headers OSGTEXT_LIBRARIES - The libraries to link for osgText (use
+# this)
+#
+# OSGTEXT_LIBRARY - The osgText library OSGTEXT_LIBRARY_DEBUG - The
+# osgText debug library
+#
+# $OSGDIR is an environment variable that would correspond to the
+# ./configure --prefix=$OSGDIR used in building osg.
#
# Created by Eric Wing.
diff --git a/Modules/FindosgUtil.cmake b/Modules/FindosgUtil.cmake
index 85c117723..97974255c 100644
--- a/Modules/FindosgUtil.cmake
+++ b/Modules/FindosgUtil.cmake
@@ -1,27 +1,31 @@
-# This is part of the Findosg* suite used to find OpenSceneGraph components.
-# Each component is separate and you must opt in to each module. You must
-# also opt into OpenGL and OpenThreads (and Producer if needed) as these
-# modules won't do it for you. This is to allow you control over your own
-# system piece by piece in case you need to opt out of certain components
-# or change the Find behavior for a particular module (perhaps because the
-# default FindOpenGL.cmake module doesn't work with your system as an
-# example).
-# If you want to use a more convenient module that includes everything,
-# use the FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
-#
-# Locate osgUtil
-# This module defines
-#
-# OSGUTIL_FOUND - Was osgUtil found?
-# OSGUTIL_INCLUDE_DIR - Where to find the headers
-# OSGUTIL_LIBRARIES - The libraries to link for osgUtil (use this)
-#
-# OSGUTIL_LIBRARY - The osgUtil library
-# OSGUTIL_LIBRARY_DEBUG - The osgUtil debug library
-#
-# $OSGDIR is an environment variable that would
-# correspond to the ./configure --prefix=$OSGDIR
-# used in building osg.
+#.rst:
+# FindosgUtil
+# -----------
+#
+#
+#
+# This is part of the Findosg* suite used to find OpenSceneGraph
+# components. Each component is separate and you must opt in to each
+# module. You must also opt into OpenGL and OpenThreads (and Producer
+# if needed) as these modules won't do it for you. This is to allow you
+# control over your own system piece by piece in case you need to opt
+# out of certain components or change the Find behavior for a particular
+# module (perhaps because the default FindOpenGL.cmake module doesn't
+# work with your system as an example). If you want to use a more
+# convenient module that includes everything, use the
+# FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+#
+# Locate osgUtil This module defines
+#
+# OSGUTIL_FOUND - Was osgUtil found? OSGUTIL_INCLUDE_DIR - Where to find
+# the headers OSGUTIL_LIBRARIES - The libraries to link for osgUtil (use
+# this)
+#
+# OSGUTIL_LIBRARY - The osgUtil library OSGUTIL_LIBRARY_DEBUG - The
+# osgUtil debug library
+#
+# $OSGDIR is an environment variable that would correspond to the
+# ./configure --prefix=$OSGDIR used in building osg.
#
# Created by Eric Wing.
diff --git a/Modules/FindosgViewer.cmake b/Modules/FindosgViewer.cmake
index d2252f4df..b3555302d 100644
--- a/Modules/FindosgViewer.cmake
+++ b/Modules/FindosgViewer.cmake
@@ -1,27 +1,31 @@
-# This is part of the Findosg* suite used to find OpenSceneGraph components.
-# Each component is separate and you must opt in to each module. You must
-# also opt into OpenGL and OpenThreads (and Producer if needed) as these
-# modules won't do it for you. This is to allow you control over your own
-# system piece by piece in case you need to opt out of certain components
-# or change the Find behavior for a particular module (perhaps because the
-# default FindOpenGL.cmake module doesn't work with your system as an
-# example).
-# If you want to use a more convenient module that includes everything,
-# use the FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
-#
-# Locate osgViewer
-# This module defines
-#
-# OSGVIEWER_FOUND - Was osgViewer found?
-# OSGVIEWER_INCLUDE_DIR - Where to find the headers
-# OSGVIEWER_LIBRARIES - The libraries to link for osgViewer (use this)
-#
-# OSGVIEWER_LIBRARY - The osgViewer library
-# OSGVIEWER_LIBRARY_DEBUG - The osgViewer debug library
-#
-# $OSGDIR is an environment variable that would
-# correspond to the ./configure --prefix=$OSGDIR
-# used in building osg.
+#.rst:
+# FindosgViewer
+# -------------
+#
+#
+#
+# This is part of the Findosg* suite used to find OpenSceneGraph
+# components. Each component is separate and you must opt in to each
+# module. You must also opt into OpenGL and OpenThreads (and Producer
+# if needed) as these modules won't do it for you. This is to allow you
+# control over your own system piece by piece in case you need to opt
+# out of certain components or change the Find behavior for a particular
+# module (perhaps because the default FindOpenGL.cmake module doesn't
+# work with your system as an example). If you want to use a more
+# convenient module that includes everything, use the
+# FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+#
+# Locate osgViewer This module defines
+#
+# OSGVIEWER_FOUND - Was osgViewer found? OSGVIEWER_INCLUDE_DIR - Where
+# to find the headers OSGVIEWER_LIBRARIES - The libraries to link for
+# osgViewer (use this)
+#
+# OSGVIEWER_LIBRARY - The osgViewer library OSGVIEWER_LIBRARY_DEBUG -
+# The osgViewer debug library
+#
+# $OSGDIR is an environment variable that would correspond to the
+# ./configure --prefix=$OSGDIR used in building osg.
#
# Created by Eric Wing.
diff --git a/Modules/FindosgVolume.cmake b/Modules/FindosgVolume.cmake
index ae2d95c39..8d3ad6c5d 100644
--- a/Modules/FindosgVolume.cmake
+++ b/Modules/FindosgVolume.cmake
@@ -1,27 +1,31 @@
-# This is part of the Findosg* suite used to find OpenSceneGraph components.
-# Each component is separate and you must opt in to each module. You must
-# also opt into OpenGL and OpenThreads (and Producer if needed) as these
-# modules won't do it for you. This is to allow you control over your own
-# system piece by piece in case you need to opt out of certain components
-# or change the Find behavior for a particular module (perhaps because the
-# default FindOpenGL.cmake module doesn't work with your system as an
-# example).
-# If you want to use a more convenient module that includes everything,
-# use the FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
-#
-# Locate osgVolume
-# This module defines
-#
-# OSGVOLUME_FOUND - Was osgVolume found?
-# OSGVOLUME_INCLUDE_DIR - Where to find the headers
-# OSGVOLUME_LIBRARIES - The libraries to link for osgVolume (use this)
-#
-# OSGVOLUME_LIBRARY - The osgVolume library
-# OSGVOLUME_LIBRARY_DEBUG - The osgVolume debug library
-#
-# $OSGDIR is an environment variable that would
-# correspond to the ./configure --prefix=$OSGDIR
-# used in building osg.
+#.rst:
+# FindosgVolume
+# -------------
+#
+#
+#
+# This is part of the Findosg* suite used to find OpenSceneGraph
+# components. Each component is separate and you must opt in to each
+# module. You must also opt into OpenGL and OpenThreads (and Producer
+# if needed) as these modules won't do it for you. This is to allow you
+# control over your own system piece by piece in case you need to opt
+# out of certain components or change the Find behavior for a particular
+# module (perhaps because the default FindOpenGL.cmake module doesn't
+# work with your system as an example). If you want to use a more
+# convenient module that includes everything, use the
+# FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+#
+# Locate osgVolume This module defines
+#
+# OSGVOLUME_FOUND - Was osgVolume found? OSGVOLUME_INCLUDE_DIR - Where
+# to find the headers OSGVOLUME_LIBRARIES - The libraries to link for
+# osgVolume (use this)
+#
+# OSGVOLUME_LIBRARY - The osgVolume library OSGVOLUME_LIBRARY_DEBUG -
+# The osgVolume debug library
+#
+# $OSGDIR is an environment variable that would correspond to the
+# ./configure --prefix=$OSGDIR used in building osg.
#
# Created by Eric Wing.
diff --git a/Modules/FindosgWidget.cmake b/Modules/FindosgWidget.cmake
index cb2e12fca..ec3c3bca9 100644
--- a/Modules/FindosgWidget.cmake
+++ b/Modules/FindosgWidget.cmake
@@ -1,29 +1,34 @@
-# This is part of the Findosg* suite used to find OpenSceneGraph components.
-# Each component is separate and you must opt in to each module. You must
-# also opt into OpenGL and OpenThreads (and Producer if needed) as these
-# modules won't do it for you. This is to allow you control over your own
-# system piece by piece in case you need to opt out of certain components
-# or change the Find behavior for a particular module (perhaps because the
-# default FindOpenGL.cmake module doesn't work with your system as an
-# example).
-# If you want to use a more convenient module that includes everything,
-# use the FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
-#
-# Locate osgWidget
-# This module defines
-#
-# OSGWIDGET_FOUND - Was osgWidget found?
-# OSGWIDGET_INCLUDE_DIR - Where to find the headers
-# OSGWIDGET_LIBRARIES - The libraries to link for osgWidget (use this)
-#
-# OSGWIDGET_LIBRARY - The osgWidget library
-# OSGWIDGET_LIBRARY_DEBUG - The osgWidget debug library
-#
-# $OSGDIR is an environment variable that would
-# correspond to the ./configure --prefix=$OSGDIR
-# used in building osg.
-#
-# FindosgWidget.cmake tweaked from Findosg* suite as created by Eric Wing.
+#.rst:
+# FindosgWidget
+# -------------
+#
+#
+#
+# This is part of the Findosg* suite used to find OpenSceneGraph
+# components. Each component is separate and you must opt in to each
+# module. You must also opt into OpenGL and OpenThreads (and Producer
+# if needed) as these modules won't do it for you. This is to allow you
+# control over your own system piece by piece in case you need to opt
+# out of certain components or change the Find behavior for a particular
+# module (perhaps because the default FindOpenGL.cmake module doesn't
+# work with your system as an example). If you want to use a more
+# convenient module that includes everything, use the
+# FindOpenSceneGraph.cmake instead of the Findosg*.cmake modules.
+#
+# Locate osgWidget This module defines
+#
+# OSGWIDGET_FOUND - Was osgWidget found? OSGWIDGET_INCLUDE_DIR - Where
+# to find the headers OSGWIDGET_LIBRARIES - The libraries to link for
+# osgWidget (use this)
+#
+# OSGWIDGET_LIBRARY - The osgWidget library OSGWIDGET_LIBRARY_DEBUG -
+# The osgWidget debug library
+#
+# $OSGDIR is an environment variable that would correspond to the
+# ./configure --prefix=$OSGDIR used in building osg.
+#
+# FindosgWidget.cmake tweaked from Findosg* suite as created by Eric
+# Wing.
#=============================================================================
# Copyright 2007-2009 Kitware, Inc.
diff --git a/Modules/Findosg_functions.cmake b/Modules/Findosg_functions.cmake
index 2e908379f..d10fae92f 100644
--- a/Modules/Findosg_functions.cmake
+++ b/Modules/Findosg_functions.cmake
@@ -1,8 +1,14 @@
+#.rst:
+# Findosg_functions
+# -----------------
+#
+#
+#
+#
#
# This CMake file contains two macros to assist with searching for OSG
# libraries and nodekits. Please see FindOpenSceneGraph.cmake for full
# documentation.
-#
#=============================================================================
# Copyright 2009 Kitware, Inc.
diff --git a/Modules/FindwxWidgets.cmake b/Modules/FindwxWidgets.cmake
index 37a894c4d..49ce57e49 100644
--- a/Modules/FindwxWidgets.cmake
+++ b/Modules/FindwxWidgets.cmake
@@ -1,79 +1,108 @@
-# - Find a wxWidgets (a.k.a., wxWindows) installation.
+#.rst:
+# FindwxWidgets
+# -------------
+#
+# Find a wxWidgets (a.k.a., wxWindows) installation.
+#
# This module finds if wxWidgets is installed and selects a default
-# configuration to use. wxWidgets is a modular library. To specify the
-# modules that you will use, you need to name them as components to
-# the package:
+# configuration to use. wxWidgets is a modular library. To specify the
+# modules that you will use, you need to name them as components to the
+# package:
#
# find_package(wxWidgets COMPONENTS core base ...)
#
-# There are two search branches: a windows style and a unix style. For
-# windows, the following variables are searched for and set to
-# defaults in case of multiple choices. Change them if the defaults
-# are not desired (i.e., these are the only variables you should
-# change to select a configuration):
+# There are two search branches: a windows style and a unix style. For
+# windows, the following variables are searched for and set to defaults
+# in case of multiple choices. Change them if the defaults are not
+# desired (i.e., these are the only variables you should change to
+# select a configuration):
+#
+# ::
+#
+# wxWidgets_ROOT_DIR - Base wxWidgets directory
+# (e.g., C:/wxWidgets-2.6.3).
+# wxWidgets_LIB_DIR - Path to wxWidgets libraries
+# (e.g., C:/wxWidgets-2.6.3/lib/vc_lib).
+# wxWidgets_CONFIGURATION - Configuration to use
+# (e.g., msw, mswd, mswu, mswunivud, etc.)
+# wxWidgets_EXCLUDE_COMMON_LIBRARIES
+# - Set to TRUE to exclude linking of
+# commonly required libs (e.g., png tiff
+# jpeg zlib regex expat).
+#
#
-# wxWidgets_ROOT_DIR - Base wxWidgets directory
-# (e.g., C:/wxWidgets-2.6.3).
-# wxWidgets_LIB_DIR - Path to wxWidgets libraries
-# (e.g., C:/wxWidgets-2.6.3/lib/vc_lib).
-# wxWidgets_CONFIGURATION - Configuration to use
-# (e.g., msw, mswd, mswu, mswunivud, etc.)
-# wxWidgets_EXCLUDE_COMMON_LIBRARIES
-# - Set to TRUE to exclude linking of
-# commonly required libs (e.g., png tiff
-# jpeg zlib regex expat).
#
-# For unix style it uses the wx-config utility. You can select between
+# For unix style it uses the wx-config utility. You can select between
# debug/release, unicode/ansi, universal/non-universal, and
# static/shared in the QtDialog or ccmake interfaces by turning ON/OFF
# the following variables:
#
-# wxWidgets_USE_DEBUG
-# wxWidgets_USE_UNICODE
-# wxWidgets_USE_UNIVERSAL
-# wxWidgets_USE_STATIC
+# ::
+#
+# wxWidgets_USE_DEBUG
+# wxWidgets_USE_UNICODE
+# wxWidgets_USE_UNIVERSAL
+# wxWidgets_USE_STATIC
+#
+#
#
# There is also a wxWidgets_CONFIG_OPTIONS variable for all other
-# options that need to be passed to the wx-config utility. For
-# example, to use the base toolkit found in the /usr/local path, set
-# the variable (before calling the FIND_PACKAGE command) as such:
+# options that need to be passed to the wx-config utility. For example,
+# to use the base toolkit found in the /usr/local path, set the variable
+# (before calling the FIND_PACKAGE command) as such:
+#
+# ::
#
-# set(wxWidgets_CONFIG_OPTIONS --toolkit=base --prefix=/usr)
+# set(wxWidgets_CONFIG_OPTIONS --toolkit=base --prefix=/usr)
+#
+#
+#
+# The following are set after the configuration is done for both windows
+# and unix style:
+#
+# ::
+#
+# wxWidgets_FOUND - Set to TRUE if wxWidgets was found.
+# wxWidgets_INCLUDE_DIRS - Include directories for WIN32
+# i.e., where to find "wx/wx.h" and
+# "wx/setup.h"; possibly empty for unices.
+# wxWidgets_LIBRARIES - Path to the wxWidgets libraries.
+# wxWidgets_LIBRARY_DIRS - compile time link dirs, useful for
+# rpath on UNIX. Typically an empty string
+# in WIN32 environment.
+# wxWidgets_DEFINITIONS - Contains defines required to compile/link
+# against WX, e.g. WXUSINGDLL
+# wxWidgets_DEFINITIONS_DEBUG- Contains defines required to compile/link
+# against WX debug builds, e.g. __WXDEBUG__
+# wxWidgets_CXX_FLAGS - Include dirs and compiler flags for
+# unices, empty on WIN32. Essentially
+# "`wx-config --cxxflags`".
+# wxWidgets_USE_FILE - Convenience include file.
#
-# The following are set after the configuration is done for both
-# windows and unix style:
#
-# wxWidgets_FOUND - Set to TRUE if wxWidgets was found.
-# wxWidgets_INCLUDE_DIRS - Include directories for WIN32
-# i.e., where to find "wx/wx.h" and
-# "wx/setup.h"; possibly empty for unices.
-# wxWidgets_LIBRARIES - Path to the wxWidgets libraries.
-# wxWidgets_LIBRARY_DIRS - compile time link dirs, useful for
-# rpath on UNIX. Typically an empty string
-# in WIN32 environment.
-# wxWidgets_DEFINITIONS - Contains defines required to compile/link
-# against WX, e.g. WXUSINGDLL
-# wxWidgets_DEFINITIONS_DEBUG- Contains defines required to compile/link
-# against WX debug builds, e.g. __WXDEBUG__
-# wxWidgets_CXX_FLAGS - Include dirs and compiler flags for
-# unices, empty on WIN32. Essentially
-# "`wx-config --cxxflags`".
-# wxWidgets_USE_FILE - Convenience include file.
#
# Sample usage:
-# # Note that for MinGW users the order of libs is important!
-# find_package(wxWidgets COMPONENTS net gl core base)
-# if(wxWidgets_FOUND)
-# include(${wxWidgets_USE_FILE})
-# # and for each of your dependent executable/library targets:
-# target_link_libraries(<YourTarget> ${wxWidgets_LIBRARIES})
-# endif()
+#
+# ::
+#
+# # Note that for MinGW users the order of libs is important!
+# find_package(wxWidgets COMPONENTS net gl core base)
+# if(wxWidgets_FOUND)
+# include(${wxWidgets_USE_FILE})
+# # and for each of your dependent executable/library targets:
+# target_link_libraries(<YourTarget> ${wxWidgets_LIBRARIES})
+# endif()
+#
+#
#
# If wxWidgets is required (i.e., not an optional part):
-# find_package(wxWidgets REQUIRED net gl core base)
-# include(${wxWidgets_USE_FILE})
-# # and for each of your dependent executable/library targets:
-# target_link_libraries(<YourTarget> ${wxWidgets_LIBRARIES})
+#
+# ::
+#
+# find_package(wxWidgets REQUIRED net gl core base)
+# include(${wxWidgets_USE_FILE})
+# # and for each of your dependent executable/library targets:
+# target_link_libraries(<YourTarget> ${wxWidgets_LIBRARIES})
#=============================================================================
# Copyright 2004-2009 Kitware, Inc.
@@ -159,18 +188,6 @@ set(wxWidgets_LIBRARIES "")
set(wxWidgets_LIBRARY_DIRS "")
set(wxWidgets_CXX_FLAGS "")
-# Using SYSTEM with INCLUDE_DIRECTORIES in conjunction with wxWidgets on
-# the Mac produces compiler errors. Set wxWidgets_INCLUDE_DIRS_NO_SYSTEM
-# to prevent UsewxWidgets.cmake from using SYSTEM.
-#
-# See cmake mailing list discussions for more info:
-# http://www.cmake.org/pipermail/cmake/2008-April/021115.html
-# http://www.cmake.org/pipermail/cmake/2008-April/021146.html
-#
-if(APPLE OR CMAKE_CXX_PLATFORM_ID MATCHES "OpenBSD")
- set(wxWidgets_INCLUDE_DIRS_NO_SYSTEM 1)
-endif()
-
# DEPRECATED: This is a patch to support the DEPRECATED use of
# wxWidgets_USE_LIBS.
#
@@ -200,13 +217,12 @@ else()
endif()
#=====================================================================
+# Determine whether unix or win32 paths should be used
#=====================================================================
-if(WIN32 AND NOT CYGWIN AND NOT MSYS)
+if(WIN32 AND NOT CYGWIN AND NOT MSYS AND NOT CMAKE_CROSSCOMPILING)
set(wxWidgets_FIND_STYLE "win32")
else()
- if(UNIX OR MSYS)
- set(wxWidgets_FIND_STYLE "unix")
- endif()
+ set(wxWidgets_FIND_STYLE "unix")
endif()
#=====================================================================
@@ -274,6 +290,8 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
# Find wxWidgets multilib base libraries.
find_library(WX_base${_DBG}
NAMES
+ wxbase31${_UCD}${_DBG}
+ wxbase30${_UCD}${_DBG}
wxbase29${_UCD}${_DBG}
wxbase28${_UCD}${_DBG}
wxbase27${_UCD}${_DBG}
@@ -286,6 +304,8 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
foreach(LIB net odbc xml)
find_library(WX_${LIB}${_DBG}
NAMES
+ wxbase31${_UCD}${_DBG}_${LIB}
+ wxbase30${_UCD}${_DBG}_${LIB}
wxbase29${_UCD}${_DBG}_${LIB}
wxbase28${_UCD}${_DBG}_${LIB}
wxbase27${_UCD}${_DBG}_${LIB}
@@ -300,6 +320,8 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
# Find wxWidgets monolithic library.
find_library(WX_mono${_DBG}
NAMES
+ wxmsw${_UNV}31${_UCD}${_DBG}
+ wxmsw${_UNV}30${_UCD}${_DBG}
wxmsw${_UNV}29${_UCD}${_DBG}
wxmsw${_UNV}28${_UCD}${_DBG}
wxmsw${_UNV}27${_UCD}${_DBG}
@@ -315,6 +337,8 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
stc ribbon propgrid webview)
find_library(WX_${LIB}${_DBG}
NAMES
+ wxmsw${_UNV}31${_UCD}${_DBG}_${LIB}
+ wxmsw${_UNV}30${_UCD}${_DBG}_${LIB}
wxmsw${_UNV}29${_UCD}${_DBG}_${LIB}
wxmsw${_UNV}28${_UCD}${_DBG}_${LIB}
wxmsw${_UNV}27${_UCD}${_DBG}_${LIB}
@@ -354,7 +378,7 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
# Clear wxWidgets multilib libraries.
foreach(LIB core adv aui html media xrc dbgrid gl qa richtext
- stc ribbon propgrid)
+ webview stc ribbon propgrid)
WX_CLEAR_LIB(WX_${LIB}${_DBG})
endforeach()
endmacro()
@@ -428,6 +452,10 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
D:/
ENV ProgramFiles
PATH_SUFFIXES
+ wxWidgets-3.0.2
+ wxWidgets-3.0.1
+ wxWidgets-3.0.0
+ wxWidgets-2.9.5
wxWidgets-2.9.4
wxWidgets-2.9.3
wxWidgets-2.9.2
@@ -475,6 +503,8 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
# settings.
if(MINGW)
set(WX_LIB_DIR_PREFIX gcc)
+ elseif(CMAKE_CL_64)
+ set(WX_LIB_DIR_PREFIX vc_x64)
else()
set(WX_LIB_DIR_PREFIX vc)
endif()
@@ -523,7 +553,7 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
if(WX_LIB_DIR)
# If building shared libs, define WXUSINGDLL to use dllimport.
- if(WX_LIB_DIR MATCHES ".*[dD][lL][lL].*")
+ if(WX_LIB_DIR MATCHES "[dD][lL][lL]")
set(wxWidgets_DEFINITIONS WXUSINGDLL)
DBG_MSG_V("detected SHARED/DLL tree WX_LIB_DIR=${WX_LIB_DIR}")
endif()
@@ -631,7 +661,7 @@ else()
if(_wx_result EQUAL 0)
foreach(_opt_name debug static unicode universal)
string(TOUPPER ${_opt_name} _upper_opt_name)
- if(_wx_selected_config MATCHES ".*${_opt_name}.*")
+ if(_wx_selected_config MATCHES "${_opt_name}")
set(wxWidgets_DEFAULT_${_upper_opt_name} ON)
else()
set(wxWidgets_DEFAULT_${_upper_opt_name} OFF)
@@ -702,7 +732,8 @@ else()
# UNIX: Start actual work.
#-----------------------------------------------------------------
# Support cross-compiling, only search in the target platform.
- find_program(wxWidgets_CONFIG_EXECUTABLE wx-config
+ find_program(wxWidgets_CONFIG_EXECUTABLE
+ NAMES wx-config wx-config-3.1 wx-config-3.0 wx-config-2.9 wx-config-2.8
DOC "Location of wxWidgets library configuration provider binary (wx-config)."
ONLY_CMAKE_FIND_ROOT_PATH
)
@@ -818,6 +849,28 @@ else()
endif()
endif()
+# Check if a specfic version was requested by find_package().
+if(wxWidgets_FOUND)
+ find_file(_filename wx/version.h PATHS ${wxWidgets_INCLUDE_DIRS} NO_DEFAULT_PATH)
+ dbg_msg("_filename: ${_filename}")
+
+ if(NOT _filename)
+ message(FATAL_ERROR "wxWidgets wx/version.h file not found in ${wxWidgets_INCLUDE_DIRS}.")
+ endif()
+
+ file(READ ${_filename} _wx_version_h)
+
+ string(REGEX REPLACE "^(.*\n)?#define +wxMAJOR_VERSION +([0-9]+).*"
+ "\\2" wxWidgets_VERSION_MAJOR "${_wx_version_h}" )
+ string(REGEX REPLACE "^(.*\n)?#define +wxMINOR_VERSION +([0-9]+).*"
+ "\\2" wxWidgets_VERSION_MINOR "${_wx_version_h}" )
+ string(REGEX REPLACE "^(.*\n)?#define +wxRELEASE_NUMBER +([0-9]+).*"
+ "\\2" wxWidgets_VERSION_PATCH "${_wx_version_h}" )
+ set(wxWidgets_VERSION_STRING
+ "${wxWidgets_VERSION_MAJOR}.${wxWidgets_VERSION_MINOR}.${wxWidgets_VERSION_PATCH}" )
+ dbg_msg("wxWidgets_VERSION_STRING: ${wxWidgets_VERSION_STRING}")
+endif()
+
# Debug output:
DBG_MSG("wxWidgets_FOUND : ${wxWidgets_FOUND}")
DBG_MSG("wxWidgets_INCLUDE_DIRS : ${wxWidgets_INCLUDE_DIRS}")
@@ -828,10 +881,13 @@ DBG_MSG("wxWidgets_USE_FILE : ${wxWidgets_USE_FILE}")
#=====================================================================
#=====================================================================
+
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(wxWidgets DEFAULT_MSG wxWidgets_FOUND)
-# Maintain consistency with all other variables.
-set(wxWidgets_FOUND ${WXWIDGETS_FOUND})
+
+find_package_handle_standard_args(wxWidgets
+ REQUIRED_VARS wxWidgets_LIBRARIES wxWidgets_INCLUDE_DIRS
+ VERSION_VAR wxWidgets_VERSION_STRING
+ )
#=====================================================================
# Macros for use in wxWidgets apps.
diff --git a/Modules/FindwxWindows.cmake b/Modules/FindwxWindows.cmake
index 868d20c73..6e441c3a4 100644
--- a/Modules/FindwxWindows.cmake
+++ b/Modules/FindwxWindows.cmake
@@ -1,51 +1,81 @@
-# - Find wxWindows (wxWidgets) installation
-# This module finds if wxWindows/wxWidgets is installed and determines where
-# the include files and libraries are. It also determines what the name of
-# the library is.
-# Please note this file is DEPRECATED and replaced by FindwxWidgets.cmake.
-# This code sets the following variables:
-#
-# WXWINDOWS_FOUND = system has WxWindows
-# WXWINDOWS_LIBRARIES = path to the wxWindows libraries
-# on Unix/Linux with additional
-# linker flags from
-# "wx-config --libs"
-# CMAKE_WXWINDOWS_CXX_FLAGS = Compiler flags for wxWindows,
-# essentially "`wx-config --cxxflags`"
-# on Linux
-# WXWINDOWS_INCLUDE_DIR = where to find "wx/wx.h" and "wx/setup.h"
-# WXWINDOWS_LINK_DIRECTORIES = link directories, useful for rpath on
-# Unix
-# WXWINDOWS_DEFINITIONS = extra defines
-#
-# OPTIONS
-# If you need OpenGL support please
-# set(WXWINDOWS_USE_GL 1)
+#.rst:
+# FindwxWindows
+# -------------
+#
+# Find wxWindows (wxWidgets) installation
+#
+# This module finds if wxWindows/wxWidgets is installed and determines
+# where the include files and libraries are. It also determines what
+# the name of the library is. Please note this file is DEPRECATED and
+# replaced by FindwxWidgets.cmake. This code sets the following
+# variables:
+#
+# ::
+#
+# WXWINDOWS_FOUND = system has WxWindows
+# WXWINDOWS_LIBRARIES = path to the wxWindows libraries
+# on Unix/Linux with additional
+# linker flags from
+# "wx-config --libs"
+# CMAKE_WXWINDOWS_CXX_FLAGS = Compiler flags for wxWindows,
+# essentially "`wx-config --cxxflags`"
+# on Linux
+# WXWINDOWS_INCLUDE_DIR = where to find "wx/wx.h" and "wx/setup.h"
+# WXWINDOWS_LINK_DIRECTORIES = link directories, useful for rpath on
+# Unix
+# WXWINDOWS_DEFINITIONS = extra defines
+#
+#
+#
+# OPTIONS If you need OpenGL support please
+#
+# ::
+#
+# set(WXWINDOWS_USE_GL 1)
+#
# in your CMakeLists.txt *before* you include this file.
#
-# HAVE_ISYSTEM - true required to replace -I by -isystem on g++
+# ::
+#
+# HAVE_ISYSTEM - true required to replace -I by -isystem on g++
+#
+#
#
# For convenience include Use_wxWindows.cmake in your project's
-# CMakeLists.txt using include(${CMAKE_CURRENT_LIST_DIR}/Use_wxWindows.cmake).
+# CMakeLists.txt using
+# include(${CMAKE_CURRENT_LIST_DIR}/Use_wxWindows.cmake).
#
# USAGE
-# set(WXWINDOWS_USE_GL 1)
-# find_package(wxWindows)
#
-# NOTES
-# wxWidgets 2.6.x is supported for monolithic builds
-# e.g. compiled in wx/build/msw dir as:
-# nmake -f makefile.vc BUILD=debug SHARED=0 USE_OPENGL=1 MONOLITHIC=1
+# ::
+#
+# set(WXWINDOWS_USE_GL 1)
+# find_package(wxWindows)
+#
+#
+#
+# NOTES wxWidgets 2.6.x is supported for monolithic builds e.g.
+# compiled in wx/build/msw dir as:
+#
+# ::
+#
+# nmake -f makefile.vc BUILD=debug SHARED=0 USE_OPENGL=1 MONOLITHIC=1
+#
+#
#
# DEPRECATED
#
-# CMAKE_WX_CAN_COMPILE
-# WXWINDOWS_LIBRARY
-# CMAKE_WX_CXX_FLAGS
-# WXWINDOWS_INCLUDE_PATH
+# ::
+#
+# CMAKE_WX_CAN_COMPILE
+# WXWINDOWS_LIBRARY
+# CMAKE_WX_CXX_FLAGS
+# WXWINDOWS_INCLUDE_PATH
+#
+#
#
-# AUTHOR
-# Jan Woetzel <http://www.mip.informatik.uni-kiel.de/~jw> (07/2003-01/2006)
+# AUTHOR Jan Woetzel <http://www.mip.informatik.uni-kiel.de/~jw>
+# (07/2003-01/2006)
#=============================================================================
# Copyright 2000-2009 Kitware, Inc.
diff --git a/Modules/FortranCInterface.cmake b/Modules/FortranCInterface.cmake
index c59e1f839..70c3fd7c0 100644
--- a/Modules/FortranCInterface.cmake
+++ b/Modules/FortranCInterface.cmake
@@ -1,85 +1,129 @@
-# - Fortran/C Interface Detection
+#.rst:
+# FortranCInterface
+# -----------------
+#
+# Fortran/C Interface Detection
+#
# This module automatically detects the API by which C and Fortran
# languages interact. Variables indicate if the mangling is found:
-# FortranCInterface_GLOBAL_FOUND = Global subroutines and functions
-# FortranCInterface_MODULE_FOUND = Module subroutines and functions
-# (declared by "MODULE PROCEDURE")
+#
+# ::
+#
+# FortranCInterface_GLOBAL_FOUND = Global subroutines and functions
+# FortranCInterface_MODULE_FOUND = Module subroutines and functions
+# (declared by "MODULE PROCEDURE")
+#
# A function is provided to generate a C header file containing macros
# to mangle symbol names:
-# FortranCInterface_HEADER(<file>
-# [MACRO_NAMESPACE <macro-ns>]
-# [SYMBOL_NAMESPACE <ns>]
-# [SYMBOLS [<module>:]<function> ...])
+#
+# ::
+#
+# FortranCInterface_HEADER(<file>
+# [MACRO_NAMESPACE <macro-ns>]
+# [SYMBOL_NAMESPACE <ns>]
+# [SYMBOLS [<module>:]<function> ...])
+#
# It generates in <file> definitions of the following macros:
-# #define FortranCInterface_GLOBAL (name,NAME) ...
-# #define FortranCInterface_GLOBAL_(name,NAME) ...
-# #define FortranCInterface_MODULE (mod,name, MOD,NAME) ...
-# #define FortranCInterface_MODULE_(mod,name, MOD,NAME) ...
-# These macros mangle four categories of Fortran symbols,
-# respectively:
-# - Global symbols without '_': call mysub()
-# - Global symbols with '_' : call my_sub()
-# - Module symbols without '_': use mymod; call mysub()
-# - Module symbols with '_' : use mymod; call my_sub()
+#
+# ::
+#
+# #define FortranCInterface_GLOBAL (name,NAME) ...
+# #define FortranCInterface_GLOBAL_(name,NAME) ...
+# #define FortranCInterface_MODULE (mod,name, MOD,NAME) ...
+# #define FortranCInterface_MODULE_(mod,name, MOD,NAME) ...
+#
+# These macros mangle four categories of Fortran symbols, respectively:
+#
+# ::
+#
+# - Global symbols without '_': call mysub()
+# - Global symbols with '_' : call my_sub()
+# - Module symbols without '_': use mymod; call mysub()
+# - Module symbols with '_' : use mymod; call my_sub()
+#
# If mangling for a category is not known, its macro is left undefined.
-# All macros require raw names in both lower case and upper case.
-# The MACRO_NAMESPACE option replaces the default "FortranCInterface_"
+# All macros require raw names in both lower case and upper case. The
+# MACRO_NAMESPACE option replaces the default "FortranCInterface_"
# prefix with a given namespace "<macro-ns>".
#
# The SYMBOLS option lists symbols to mangle automatically with C
# preprocessor definitions:
-# <function> ==> #define <ns><function> ...
-# <module>:<function> ==> #define <ns><module>_<function> ...
+#
+# ::
+#
+# <function> ==> #define <ns><function> ...
+# <module>:<function> ==> #define <ns><module>_<function> ...
+#
# If the mangling for some symbol is not known then no preprocessor
-# definition is created, and a warning is displayed.
-# The SYMBOL_NAMESPACE option prefixes all preprocessor definitions
+# definition is created, and a warning is displayed. The
+# SYMBOL_NAMESPACE option prefixes all preprocessor definitions
# generated by the SYMBOLS option with a given namespace "<ns>".
#
# Example usage:
-# include(FortranCInterface)
-# FortranCInterface_HEADER(FC.h MACRO_NAMESPACE "FC_")
-# This creates a "FC.h" header that defines mangling macros
-# FC_GLOBAL(), FC_GLOBAL_(), FC_MODULE(), and FC_MODULE_().
+#
+# ::
+#
+# include(FortranCInterface)
+# FortranCInterface_HEADER(FC.h MACRO_NAMESPACE "FC_")
+#
+# This creates a "FC.h" header that defines mangling macros FC_GLOBAL(),
+# FC_GLOBAL_(), FC_MODULE(), and FC_MODULE_().
#
# Example usage:
-# include(FortranCInterface)
-# FortranCInterface_HEADER(FCMangle.h
-# MACRO_NAMESPACE "FC_"
-# SYMBOL_NAMESPACE "FC_"
-# SYMBOLS mysub mymod:my_sub)
+#
+# ::
+#
+# include(FortranCInterface)
+# FortranCInterface_HEADER(FCMangle.h
+# MACRO_NAMESPACE "FC_"
+# SYMBOL_NAMESPACE "FC_"
+# SYMBOLS mysub mymod:my_sub)
+#
# This creates a "FCMangle.h" header that defines the same FC_*()
# mangling macros as the previous example plus preprocessor symbols
# FC_mysub and FC_mymod_my_sub.
#
# Another function is provided to verify that the Fortran and C/C++
# compilers work together:
-# FortranCInterface_VERIFY([CXX] [QUIET])
-# It tests whether a simple test executable using Fortran and C (and
-# C++ when the CXX option is given) compiles and links successfully.
-# The result is stored in the cache entry FortranCInterface_VERIFIED_C
-# (or FortranCInterface_VERIFIED_CXX if CXX is given) as a boolean.
-# If the check fails and QUIET is not given the function terminates
-# with a FATAL_ERROR message describing the problem. The purpose of
-# this check is to stop a build early for incompatible compiler
-# combinations. The test is built in the Release configuration.
-#
-# FortranCInterface is aware of possible GLOBAL and MODULE manglings
-# for many Fortran compilers, but it also provides an interface to
-# specify new possible manglings. Set the variables
-# FortranCInterface_GLOBAL_SYMBOLS
-# FortranCInterface_MODULE_SYMBOLS
-# before including FortranCInterface to specify manglings of the
-# symbols "MySub", "My_Sub", "MyModule:MySub", and "My_Module:My_Sub".
-# For example, the code:
-# set(FortranCInterface_GLOBAL_SYMBOLS mysub_ my_sub__ MYSUB_)
-# # ^^^^^ ^^^^^^ ^^^^^
-# set(FortranCInterface_MODULE_SYMBOLS
-# __mymodule_MOD_mysub __my_module_MOD_my_sub)
-# # ^^^^^^^^ ^^^^^ ^^^^^^^^^ ^^^^^^
-# include(FortranCInterface)
+#
+# ::
+#
+# FortranCInterface_VERIFY([CXX] [QUIET])
+#
+# It tests whether a simple test executable using Fortran and C (and C++
+# when the CXX option is given) compiles and links successfully. The
+# result is stored in the cache entry FortranCInterface_VERIFIED_C (or
+# FortranCInterface_VERIFIED_CXX if CXX is given) as a boolean. If the
+# check fails and QUIET is not given the function terminates with a
+# FATAL_ERROR message describing the problem. The purpose of this check
+# is to stop a build early for incompatible compiler combinations. The
+# test is built in the Release configuration.
+#
+# FortranCInterface is aware of possible GLOBAL and MODULE manglings for
+# many Fortran compilers, but it also provides an interface to specify
+# new possible manglings. Set the variables
+#
+# ::
+#
+# FortranCInterface_GLOBAL_SYMBOLS
+# FortranCInterface_MODULE_SYMBOLS
+#
+# before including FortranCInterface to specify manglings of the symbols
+# "MySub", "My_Sub", "MyModule:MySub", and "My_Module:My_Sub". For
+# example, the code:
+#
+# ::
+#
+# set(FortranCInterface_GLOBAL_SYMBOLS mysub_ my_sub__ MYSUB_)
+# # ^^^^^ ^^^^^^ ^^^^^
+# set(FortranCInterface_MODULE_SYMBOLS
+# __mymodule_MOD_mysub __my_module_MOD_my_sub)
+# # ^^^^^^^^ ^^^^^ ^^^^^^^^^ ^^^^^^
+# include(FortranCInterface)
+#
# tells FortranCInterface to try given GLOBAL and MODULE manglings.
-# (The carets point at raw symbol names for clarity in this example
-# but are not needed.)
+# (The carets point at raw symbol names for clarity in this example but
+# are not needed.)
#=============================================================================
# Copyright 2008-2009 Kitware, Inc.
@@ -100,9 +144,8 @@ if(FortranCInterface_SOURCE_DIR)
return()
endif()
-# Use CMake 2.8.0 behavior for this module regardless of including context.
cmake_policy(PUSH)
-cmake_policy(VERSION 2.8.0)
+cmake_policy(SET CMP0007 NEW)
#-----------------------------------------------------------------------------
# Verify that C and Fortran are available.
@@ -284,7 +327,7 @@ function(FortranCInterface_VERIFY)
# Error if compilers are incompatible.
if(NOT FortranCInterface_VERIFIED_${lang} AND NOT quiet)
file(READ "${FortranCInterface_BINARY_DIR}/Verify${lang}/output.txt" _output)
- string(REGEX REPLACE "\n" "\n " _output "${_output}")
+ string(REPLACE "\n" "\n " _output "${_output}")
message(FATAL_ERROR
"The Fortran compiler:\n ${CMAKE_Fortran_COMPILER}\n"
"and the ${lang} compiler:\n ${CMAKE_${lang}_COMPILER}\n"
diff --git a/Modules/FortranCInterface/CMakeLists.txt b/Modules/FortranCInterface/CMakeLists.txt
index d35a72ce8..721a262ee 100644
--- a/Modules/FortranCInterface/CMakeLists.txt
+++ b/Modules/FortranCInterface/CMakeLists.txt
@@ -9,7 +9,7 @@
# See the License for more information.
#=============================================================================
-cmake_minimum_required(VERSION 2.6.3)
+cmake_minimum_required(VERSION ${CMAKE_VERSION})
project(FortranCInterface C Fortran)
include(${FortranCInterface_BINARY_DIR}/Input.cmake OPTIONAL)
@@ -71,7 +71,7 @@ endif()
# Generate C symbol sources.
set(symbol_sources)
-if(NOT "${CMAKE_Fortran_COMPILER_ID}" MATCHES "^(PathScale|Cray)$")
+if(NOT CMAKE_Fortran_COMPILER_ID MATCHES "^(PathScale|Cray)$")
# Provide mymodule_ and my_module_ init symbols because:
# - PGI Fortran uses module init symbols
# but not for:
diff --git a/Modules/FortranCInterface/Detect.cmake b/Modules/FortranCInterface/Detect.cmake
index 798c44caa..bee7dae35 100644
--- a/Modules/FortranCInterface/Detect.cmake
+++ b/Modules/FortranCInterface/Detect.cmake
@@ -49,7 +49,7 @@ unset(FortranCInterface_COMPILED CACHE)
# Locate the sample project executable.
if(FortranCInterface_COMPILED)
find_program(FortranCInterface_EXE
- NAMES FortranCInterface
+ NAMES FortranCInterface${CMAKE_EXECUTABLE_SUFFIX}
PATHS ${FortranCInterface_BINARY_DIR} ${FortranCInterface_BINARY_DIR}/Debug
NO_DEFAULT_PATH
)
@@ -67,11 +67,10 @@ endif()
set(FortranCInterface_SYMBOLS)
if(FortranCInterface_EXE)
file(STRINGS "${FortranCInterface_EXE}" _info_strings
- LIMIT_COUNT 8 REGEX "INFO:[^[]*\\[")
+ LIMIT_COUNT 8 REGEX "INFO:[A-Za-z0-9_]+\\[[^]]*\\]")
foreach(info ${_info_strings})
- if("${info}" MATCHES ".*INFO:symbol\\[([^]]*)\\].*")
- string(REGEX REPLACE ".*INFO:symbol\\[([^]]*)\\].*" "\\1" symbol "${info}")
- list(APPEND FortranCInterface_SYMBOLS ${symbol})
+ if("${info}" MATCHES "INFO:symbol\\[([^]]*)\\]")
+ list(APPEND FortranCInterface_SYMBOLS ${CMAKE_MATCH_1})
endif()
endforeach()
elseif(NOT _result)
diff --git a/Modules/FortranCInterface/Verify/CMakeLists.txt b/Modules/FortranCInterface/Verify/CMakeLists.txt
index e969f2408..cde3c5312 100644
--- a/Modules/FortranCInterface/Verify/CMakeLists.txt
+++ b/Modules/FortranCInterface/Verify/CMakeLists.txt
@@ -9,7 +9,7 @@
# See the License for more information.
#=============================================================================
-cmake_minimum_required(VERSION 2.7)
+cmake_minimum_required(VERSION ${CMAKE_VERSION})
project(VerifyFortranC C Fortran)
option(VERIFY_CXX "Whether to verify C++ and Fortran" OFF)
diff --git a/Modules/GNUInstallDirs.cmake b/Modules/GNUInstallDirs.cmake
index 0302e4bef..b42084eda 100644
--- a/Modules/GNUInstallDirs.cmake
+++ b/Modules/GNUInstallDirs.cmake
@@ -1,34 +1,107 @@
-# - Define GNU standard installation directories
-# Provides install directory variables as defined for GNU software:
-# http://www.gnu.org/prep/standards/html_node/Directory-Variables.html
+#.rst:
+# GNUInstallDirs
+# --------------
+#
+# Define GNU standard installation directories
+#
+# Provides install directory variables as defined by the
+# `GNU Coding Standards`_.
+#
+# .. _`GNU Coding Standards`: https://www.gnu.org/prep/standards/html_node/Directory-Variables.html
+#
+# Result Variables
+# ^^^^^^^^^^^^^^^^
+#
# Inclusion of this module defines the following variables:
-# CMAKE_INSTALL_<dir> - destination for files of a given type
-# CMAKE_INSTALL_FULL_<dir> - corresponding absolute path
-# where <dir> is one of:
-# BINDIR - user executables (bin)
-# SBINDIR - system admin executables (sbin)
-# LIBEXECDIR - program executables (libexec)
-# SYSCONFDIR - read-only single-machine data (etc)
-# SHAREDSTATEDIR - modifiable architecture-independent data (com)
-# LOCALSTATEDIR - modifiable single-machine data (var)
-# LIBDIR - object code libraries (lib or lib64 or lib/<multiarch-tuple> on Debian)
-# INCLUDEDIR - C header files (include)
-# OLDINCLUDEDIR - C header files for non-gcc (/usr/include)
-# DATAROOTDIR - read-only architecture-independent data root (share)
-# DATADIR - read-only architecture-independent data (DATAROOTDIR)
-# INFODIR - info documentation (DATAROOTDIR/info)
-# LOCALEDIR - locale-dependent data (DATAROOTDIR/locale)
-# MANDIR - man documentation (DATAROOTDIR/man)
-# DOCDIR - documentation root (DATAROOTDIR/doc/PROJECT_NAME)
-# Each CMAKE_INSTALL_<dir> value may be passed to the DESTINATION options of
-# install() commands for the corresponding file type. If the includer does
-# not define a value the above-shown default will be used and the value will
-# appear in the cache for editing by the user.
-# Each CMAKE_INSTALL_FULL_<dir> value contains an absolute path constructed
-# from the corresponding destination by prepending (if necessary) the value
-# of CMAKE_INSTALL_PREFIX.
+#
+# ``CMAKE_INSTALL_<dir>``
+#
+# Destination for files of a given type. This value may be passed to
+# the ``DESTINATION`` options of :command:`install` commands for the
+# corresponding file type.
+#
+# ``CMAKE_INSTALL_FULL_<dir>``
+#
+# The absolute path generated from the corresponding ``CMAKE_INSTALL_<dir>``
+# value. If the value is not already an absolute path, an absolute path
+# is constructed typically by prepending the value of the
+# :variable:`CMAKE_INSTALL_PREFIX` variable. However, there are some
+# `special cases`_ as documented below.
+#
+# where ``<dir>`` is one of:
+#
+# ``BINDIR``
+# user executables (``bin``)
+# ``SBINDIR``
+# system admin executables (``sbin``)
+# ``LIBEXECDIR``
+# program executables (``libexec``)
+# ``SYSCONFDIR``
+# read-only single-machine data (``etc``)
+# ``SHAREDSTATEDIR``
+# modifiable architecture-independent data (``com``)
+# ``LOCALSTATEDIR``
+# modifiable single-machine data (``var``)
+# ``LIBDIR``
+# object code libraries (``lib`` or ``lib64``
+# or ``lib/<multiarch-tuple>`` on Debian)
+# ``INCLUDEDIR``
+# C header files (``include``)
+# ``OLDINCLUDEDIR``
+# C header files for non-gcc (``/usr/include``)
+# ``DATAROOTDIR``
+# read-only architecture-independent data root (``share``)
+# ``DATADIR``
+# read-only architecture-independent data (``DATAROOTDIR``)
+# ``INFODIR``
+# info documentation (``DATAROOTDIR/info``)
+# ``LOCALEDIR``
+# locale-dependent data (``DATAROOTDIR/locale``)
+# ``MANDIR``
+# man documentation (``DATAROOTDIR/man``)
+# ``DOCDIR``
+# documentation root (``DATAROOTDIR/doc/PROJECT_NAME``)
+#
+# If the includer does not define a value the above-shown default will be
+# used and the value will appear in the cache for editing by the user.
+#
+# Special Cases
+# ^^^^^^^^^^^^^
+#
+# The following values of :variable:`CMAKE_INSTALL_PREFIX` are special:
+#
+# ``/``
+#
+# For ``<dir>`` other than the ``SYSCONFDIR`` and ``LOCALSTATEDIR``,
+# the value of ``CMAKE_INSTALL_<dir>`` is prefixed with ``usr/`` if
+# it is not user-specified as an absolute path. For example, the
+# ``INCLUDEDIR`` value ``include`` becomes ``usr/include``.
+# This is required by the `GNU Coding Standards`_, which state:
+#
+# When building the complete GNU system, the prefix will be empty
+# and ``/usr`` will be a symbolic link to ``/``.
+#
+# ``/usr``
+#
+# For ``<dir>`` equal to ``SYSCONFDIR`` or ``LOCALSTATEDIR``, the
+# ``CMAKE_INSTALL_FULL_<dir>`` is computed by prepending just ``/``
+# to the value of ``CMAKE_INSTALL_<dir>`` if it is not user-specified
+# as an absolute path. For example, the ``SYSCONFDIR`` value ``etc``
+# becomes ``/etc``. This is required by the `GNU Coding Standards`_.
+#
+# ``/opt/...``
+#
+# For ``<dir>`` equal to ``SYSCONFDIR`` or ``LOCALSTATEDIR``, the
+# ``CMAKE_INSTALL_FULL_<dir>`` is computed by *appending* the prefix
+# to the value of ``CMAKE_INSTALL_<dir>`` if it is not user-specified
+# as an absolute path. For example, the ``SYSCONFDIR`` value ``etc``
+# becomes ``/etc/opt/...``. This is defined by the
+# `Filesystem Hierarchy Standard`_.
+#
+# .. _`Filesystem Hierarchy Standard`: https://refspecs.linuxfoundation.org/FHS_3.0/fhs/index.html
#=============================================================================
+# Copyright 2015 Alex Turbov <i.zaufi@gmail.com>
# Copyright 2011 Nikita Krupen'ko <krnekit@gmail.com>
# Copyright 2011 Kitware, Inc.
#
@@ -68,7 +141,31 @@ if(NOT DEFINED CMAKE_INSTALL_LOCALSTATEDIR)
set(CMAKE_INSTALL_LOCALSTATEDIR "var" CACHE PATH "modifiable single-machine data (var)")
endif()
-if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
+# We check if the variable was manually set and not cached, in order to
+# allow projects to set the values as normal variables before including
+# GNUInstallDirs to avoid having the entries cached or user-editable. It
+# replaces the "if(NOT DEFINED CMAKE_INSTALL_XXX)" checks in all the
+# other cases.
+# If CMAKE_INSTALL_LIBDIR is defined, if _libdir_set is false, then the
+# variable is a normal one, otherwise it is a cache one.
+get_property(_libdir_set CACHE CMAKE_INSTALL_LIBDIR PROPERTY TYPE SET)
+if(NOT DEFINED CMAKE_INSTALL_LIBDIR OR (_libdir_set
+ AND DEFINED _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX
+ AND NOT "${_GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX}" STREQUAL "${CMAKE_INSTALL_PREFIX}"))
+ # If CMAKE_INSTALL_LIBDIR is not defined, it is always executed.
+ # Otherwise:
+ # * if _libdir_set is false it is not executed (meaning that it is
+ # not a cache variable)
+ # * if _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX is not defined it is
+ # not executed
+ # * if _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX and
+ # CMAKE_INSTALL_PREFIX are the same string it is not executed.
+ # _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX is updated after the
+ # execution, of this part of code, therefore at the next inclusion
+ # of the file, CMAKE_INSTALL_LIBDIR is defined, and the 2 strings
+ # are equal, meaning that the if is not executed the code the
+ # second time.
+
set(_LIBDIR_DEFAULT "lib")
# Override this default 'lib' with 'lib64' iff:
# - we are on Linux system but NOT cross-compiling
@@ -77,13 +174,30 @@ if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
# reason is: amd64 ABI: http://www.x86-64.org/documentation/abi.pdf
# For Debian with multiarch, use 'lib/${CMAKE_LIBRARY_ARCHITECTURE}' if
# CMAKE_LIBRARY_ARCHITECTURE is set (which contains e.g. "i386-linux-gnu"
+ # and CMAKE_INSTALL_PREFIX is "/usr"
# See http://wiki.debian.org/Multiarch
- if(CMAKE_SYSTEM_NAME MATCHES "Linux"
+ if(DEFINED _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX)
+ set(__LAST_LIBDIR_DEFAULT "lib")
+ # __LAST_LIBDIR_DEFAULT is the default value that we compute from
+ # _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX, not a cache entry for
+ # the value that was last used as the default.
+ # This value is used to figure out whether the user changed the
+ # CMAKE_INSTALL_LIBDIR value manually, or if the value was the
+ # default one. When CMAKE_INSTALL_PREFIX changes, the value is
+ # updated to the new default, unless the user explicitly changed it.
+ endif()
+ if(CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU)$"
AND NOT CMAKE_CROSSCOMPILING)
if (EXISTS "/etc/debian_version") # is this a debian system ?
- if(CMAKE_LIBRARY_ARCHITECTURE)
- set(_LIBDIR_DEFAULT "lib/${CMAKE_LIBRARY_ARCHITECTURE}")
- endif()
+ if(CMAKE_LIBRARY_ARCHITECTURE)
+ if("${CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/?$")
+ set(_LIBDIR_DEFAULT "lib/${CMAKE_LIBRARY_ARCHITECTURE}")
+ endif()
+ if(DEFINED _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX
+ AND "${_GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/?$")
+ set(__LAST_LIBDIR_DEFAULT "lib/${CMAKE_LIBRARY_ARCHITECTURE}")
+ endif()
+ endif()
else() # not debian, rely on CMAKE_SIZEOF_VOID_P:
if(NOT DEFINED CMAKE_SIZEOF_VOID_P)
message(AUTHOR_WARNING
@@ -92,12 +206,25 @@ if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
else()
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
set(_LIBDIR_DEFAULT "lib64")
+ if(DEFINED _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX)
+ set(__LAST_LIBDIR_DEFAULT "lib64")
+ endif()
endif()
endif()
endif()
endif()
- set(CMAKE_INSTALL_LIBDIR "${_LIBDIR_DEFAULT}" CACHE PATH "object code libraries (${_LIBDIR_DEFAULT})")
+ if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
+ set(CMAKE_INSTALL_LIBDIR "${_LIBDIR_DEFAULT}" CACHE PATH "object code libraries (${_LIBDIR_DEFAULT})")
+ elseif(DEFINED __LAST_LIBDIR_DEFAULT
+ AND "${__LAST_LIBDIR_DEFAULT}" STREQUAL "${CMAKE_INSTALL_LIBDIR}")
+ set_property(CACHE CMAKE_INSTALL_LIBDIR PROPERTY VALUE "${_LIBDIR_DEFAULT}")
+ endif()
endif()
+# Save for next run
+set(_GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" CACHE INTERNAL "CMAKE_INSTALL_PREFIX during last run")
+unset(_libdir_set)
+unset(__LAST_LIBDIR_DEFAULT)
+
if(NOT DEFINED CMAKE_INSTALL_INCLUDEDIR)
set(CMAKE_INSTALL_INCLUDEDIR "include" CACHE PATH "C header files (include)")
@@ -121,9 +248,26 @@ if(NOT CMAKE_INSTALL_DATADIR)
set(CMAKE_INSTALL_DATADIR "${CMAKE_INSTALL_DATAROOTDIR}")
endif()
-if(NOT CMAKE_INSTALL_INFODIR)
- set(CMAKE_INSTALL_INFODIR "" CACHE PATH "info documentation (DATAROOTDIR/info)")
- set(CMAKE_INSTALL_INFODIR "${CMAKE_INSTALL_DATAROOTDIR}/info")
+if(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
+ if(NOT CMAKE_INSTALL_INFODIR)
+ set(CMAKE_INSTALL_INFODIR "" CACHE PATH "info documentation (info)")
+ set(CMAKE_INSTALL_INFODIR "info")
+ endif()
+
+ if(NOT CMAKE_INSTALL_MANDIR)
+ set(CMAKE_INSTALL_MANDIR "" CACHE PATH "man documentation (man)")
+ set(CMAKE_INSTALL_MANDIR "man")
+ endif()
+else()
+ if(NOT CMAKE_INSTALL_INFODIR)
+ set(CMAKE_INSTALL_INFODIR "" CACHE PATH "info documentation (DATAROOTDIR/info)")
+ set(CMAKE_INSTALL_INFODIR "${CMAKE_INSTALL_DATAROOTDIR}/info")
+ endif()
+
+ if(NOT CMAKE_INSTALL_MANDIR)
+ set(CMAKE_INSTALL_MANDIR "" CACHE PATH "man documentation (DATAROOTDIR/man)")
+ set(CMAKE_INSTALL_MANDIR "${CMAKE_INSTALL_DATAROOTDIR}/man")
+ endif()
endif()
if(NOT CMAKE_INSTALL_LOCALEDIR)
@@ -131,11 +275,6 @@ if(NOT CMAKE_INSTALL_LOCALEDIR)
set(CMAKE_INSTALL_LOCALEDIR "${CMAKE_INSTALL_DATAROOTDIR}/locale")
endif()
-if(NOT CMAKE_INSTALL_MANDIR)
- set(CMAKE_INSTALL_MANDIR "" CACHE PATH "man documentation (DATAROOTDIR/man)")
- set(CMAKE_INSTALL_MANDIR "${CMAKE_INSTALL_DATAROOTDIR}/man")
-endif()
-
if(NOT CMAKE_INSTALL_DOCDIR)
set(CMAKE_INSTALL_DOCDIR "" CACHE PATH "documentation root (DATAROOTDIR/doc/PROJECT_NAME)")
set(CMAKE_INSTALL_DOCDIR "${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME}")
@@ -180,8 +319,35 @@ foreach(dir
MANDIR
DOCDIR
)
- if(NOT IS_ABSOLUTE ${CMAKE_INSTALL_${dir}})
- set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_${dir}}")
+ if(NOT IS_ABSOLUTE "${CMAKE_INSTALL_${dir}}")
+ # Handle special cases:
+ # - CMAKE_INSTALL_PREFIX == /
+ # - CMAKE_INSTALL_PREFIX == /usr
+ # - CMAKE_INSTALL_PREFIX == /opt/...
+ if("${CMAKE_INSTALL_PREFIX}" STREQUAL "/")
+ if("${dir}" STREQUAL "SYSCONFDIR" OR "${dir}" STREQUAL "LOCALSTATEDIR")
+ set(CMAKE_INSTALL_FULL_${dir} "/${CMAKE_INSTALL_${dir}}")
+ else()
+ if (NOT "${CMAKE_INSTALL_${dir}}" MATCHES "^usr/")
+ set(CMAKE_INSTALL_${dir} "usr/${CMAKE_INSTALL_${dir}}")
+ endif()
+ set(CMAKE_INSTALL_FULL_${dir} "/${CMAKE_INSTALL_${dir}}")
+ endif()
+ elseif("${CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/?$")
+ if("${dir}" STREQUAL "SYSCONFDIR" OR "${dir}" STREQUAL "LOCALSTATEDIR")
+ set(CMAKE_INSTALL_FULL_${dir} "/${CMAKE_INSTALL_${dir}}")
+ else()
+ set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_${dir}}")
+ endif()
+ elseif("${CMAKE_INSTALL_PREFIX}" MATCHES "^/opt/.*")
+ if("${dir}" STREQUAL "SYSCONFDIR" OR "${dir}" STREQUAL "LOCALSTATEDIR")
+ set(CMAKE_INSTALL_FULL_${dir} "/${CMAKE_INSTALL_${dir}}${CMAKE_INSTALL_PREFIX}")
+ else()
+ set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_${dir}}")
+ endif()
+ else()
+ set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_${dir}}")
+ endif()
else()
set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_${dir}}")
endif()
diff --git a/Modules/GenerateExportHeader.cmake b/Modules/GenerateExportHeader.cmake
index 4ef14ac28..4f4efbcf3 100644
--- a/Modules/GenerateExportHeader.cmake
+++ b/Modules/GenerateExportHeader.cmake
@@ -1,133 +1,182 @@
-# - Function for generation of export macros for libraries
-# This module provides the function GENERATE_EXPORT_HEADER() and the
-# accompanying ADD_COMPILER_EXPORT_FLAGS() function.
-#
-# The GENERATE_EXPORT_HEADER function can be used to generate a file suitable
-# for preprocessor inclusion which contains EXPORT macros to be used in
-# library classes.
-#
-# GENERATE_EXPORT_HEADER( LIBRARY_TARGET
-# [BASE_NAME <base_name>]
-# [EXPORT_MACRO_NAME <export_macro_name>]
-# [EXPORT_FILE_NAME <export_file_name>]
-# [DEPRECATED_MACRO_NAME <deprecated_macro_name>]
-# [NO_EXPORT_MACRO_NAME <no_export_macro_name>]
-# [STATIC_DEFINE <static_define>]
-# [NO_DEPRECATED_MACRO_NAME <no_deprecated_macro_name>]
-# [DEFINE_NO_DEPRECATED]
-# [PREFIX_NAME <prefix_name>]
-# )
-#
-# ADD_COMPILER_EXPORT_FLAGS( [<output_variable>] )
-#
-# By default GENERATE_EXPORT_HEADER() generates macro names in a file name
-# determined by the name of the library. The ADD_COMPILER_EXPORT_FLAGS function
-# adds -fvisibility=hidden to CMAKE_CXX_FLAGS if supported, and is a no-op on
-# Windows which does not need extra compiler flags for exporting support. You
-# may optionally pass a single argument to ADD_COMPILER_EXPORT_FLAGS that will
-# be populated with the required CXX_FLAGS required to enable visibility support
-# for the compiler/architecture in use.
-#
-# This means that in the simplest case, users of these functions will be
-# equivalent to:
-#
-# add_compiler_export_flags()
-# add_library(somelib someclass.cpp)
-# generate_export_header(somelib)
-# install(TARGETS somelib DESTINATION ${LIBRARY_INSTALL_DIR})
-# install(FILES
-# someclass.h
-# ${PROJECT_BINARY_DIR}/somelib_export.h DESTINATION ${INCLUDE_INSTALL_DIR}
-# )
+#.rst:
+# GenerateExportHeader
+# --------------------
+#
+# Function for generation of export macros for libraries
+#
+# This module provides the function GENERATE_EXPORT_HEADER().
+#
+# The ``GENERATE_EXPORT_HEADER`` function can be used to generate a file
+# suitable for preprocessor inclusion which contains EXPORT macros to be
+# used in library classes::
+#
+# GENERATE_EXPORT_HEADER( LIBRARY_TARGET
+# [BASE_NAME <base_name>]
+# [EXPORT_MACRO_NAME <export_macro_name>]
+# [EXPORT_FILE_NAME <export_file_name>]
+# [DEPRECATED_MACRO_NAME <deprecated_macro_name>]
+# [NO_EXPORT_MACRO_NAME <no_export_macro_name>]
+# [STATIC_DEFINE <static_define>]
+# [NO_DEPRECATED_MACRO_NAME <no_deprecated_macro_name>]
+# [DEFINE_NO_DEPRECATED]
+# [PREFIX_NAME <prefix_name>]
+# )
+#
+#
+# The target properties :prop_tgt:`CXX_VISIBILITY_PRESET <<LANG>_VISIBILITY_PRESET>`
+# and :prop_tgt:`VISIBILITY_INLINES_HIDDEN` can be used to add the appropriate
+# compile flags for targets. See the documentation of those target properties,
+# and the convenience variables
+# :variable:`CMAKE_CXX_VISIBILITY_PRESET <CMAKE_<LANG>_VISIBILITY_PRESET>` and
+# :variable:`CMAKE_VISIBILITY_INLINES_HIDDEN`.
+#
+# By default ``GENERATE_EXPORT_HEADER()`` generates macro names in a file
+# name determined by the name of the library. This means that in the
+# simplest case, users of ``GenerateExportHeader`` will be equivalent to:
+#
+# .. code-block:: cmake
+#
+# set(CMAKE_CXX_VISIBILITY_PRESET hidden)
+# set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
+# add_library(somelib someclass.cpp)
+# generate_export_header(somelib)
+# install(TARGETS somelib DESTINATION ${LIBRARY_INSTALL_DIR})
+# install(FILES
+# someclass.h
+# ${PROJECT_BINARY_DIR}/somelib_export.h DESTINATION ${INCLUDE_INSTALL_DIR}
+# )
+#
#
# And in the ABI header files:
#
-# #include "somelib_export.h"
-# class SOMELIB_EXPORT SomeClass {
-# ...
-# };
+# .. code-block:: c++
#
-# The CMake fragment will generate a file in the ${CMAKE_CURRENT_BINARY_DIR}
-# called somelib_export.h containing the macros SOMELIB_EXPORT, SOMELIB_NO_EXPORT,
-# SOMELIB_DEPRECATED, SOMELIB_DEPRECATED_EXPORT and SOMELIB_DEPRECATED_NO_EXPORT.
-# The resulting file should be installed with other headers in the library.
+# #include "somelib_export.h"
+# class SOMELIB_EXPORT SomeClass {
+# ...
+# };
#
-# The BASE_NAME argument can be used to override the file name and the names
-# used for the macros
#
-# add_library(somelib someclass.cpp)
-# generate_export_header(somelib
-# BASE_NAME other_name
-# )
+# The CMake fragment will generate a file in the
+# ``${CMAKE_CURRENT_BINARY_DIR}`` called ``somelib_export.h`` containing the
+# macros ``SOMELIB_EXPORT``, ``SOMELIB_NO_EXPORT``, ``SOMELIB_DEPRECATED``,
+# ``SOMELIB_DEPRECATED_EXPORT`` and ``SOMELIB_DEPRECATED_NO_EXPORT``. The
+# resulting file should be installed with other headers in the library.
#
-# Generates a file called other_name_export.h containing the macros
-# OTHER_NAME_EXPORT, OTHER_NAME_NO_EXPORT and OTHER_NAME_DEPRECATED etc.
+# The ``BASE_NAME`` argument can be used to override the file name and the
+# names used for the macros:
#
-# The BASE_NAME may be overridden by specifiying other options in the function.
-# For example:
+# .. code-block:: cmake
+#
+# add_library(somelib someclass.cpp)
+# generate_export_header(somelib
+# BASE_NAME other_name
+# )
+#
+#
+# Generates a file called ``other_name_export.h`` containing the macros
+# ``OTHER_NAME_EXPORT``, ``OTHER_NAME_NO_EXPORT`` and ``OTHER_NAME_DEPRECATED``
+# etc.
+#
+# The ``BASE_NAME`` may be overridden by specifiying other options in the
+# function. For example:
+#
+# .. code-block:: cmake
+#
+# add_library(somelib someclass.cpp)
+# generate_export_header(somelib
+# EXPORT_MACRO_NAME OTHER_NAME_EXPORT
+# )
+#
+#
+# creates the macro ``OTHER_NAME_EXPORT`` instead of ``SOMELIB_EXPORT``, but
+# other macros and the generated file name is as default:
+#
+# .. code-block:: cmake
#
-# add_library(somelib someclass.cpp)
-# generate_export_header(somelib
-# EXPORT_MACRO_NAME OTHER_NAME_EXPORT
-# )
+# add_library(somelib someclass.cpp)
+# generate_export_header(somelib
+# DEPRECATED_MACRO_NAME KDE_DEPRECATED
+# )
#
-# creates the macro OTHER_NAME_EXPORT instead of SOMELIB_EXPORT, but other macros
-# and the generated file name is as default.
#
-# add_library(somelib someclass.cpp)
-# generate_export_header(somelib
-# DEPRECATED_MACRO_NAME KDE_DEPRECATED
-# )
+# creates the macro ``KDE_DEPRECATED`` instead of ``SOMELIB_DEPRECATED``.
#
-# creates the macro KDE_DEPRECATED instead of SOMELIB_DEPRECATED.
+# If ``LIBRARY_TARGET`` is a static library, macros are defined without
+# values.
#
-# If LIBRARY_TARGET is a static library, macros are defined without values.
+# If the same sources are used to create both a shared and a static
+# library, the uppercased symbol ``${BASE_NAME}_STATIC_DEFINE`` should be
+# used when building the static library:
#
-# If the same sources are used to create both a shared and a static library, the
-# uppercased symbol ${BASE_NAME}_STATIC_DEFINE should be used when building the
-# static library
+# .. code-block:: cmake
#
-# add_library(shared_variant SHARED ${lib_SRCS})
-# add_library(static_variant ${lib_SRCS})
-# generate_export_header(shared_variant BASE_NAME libshared_and_static)
-# set_target_properties(static_variant PROPERTIES
-# COMPILE_FLAGS -DLIBSHARED_AND_STATIC_STATIC_DEFINE)
+# add_library(shared_variant SHARED ${lib_SRCS})
+# add_library(static_variant ${lib_SRCS})
+# generate_export_header(shared_variant BASE_NAME libshared_and_static)
+# set_target_properties(static_variant PROPERTIES
+# COMPILE_FLAGS -DLIBSHARED_AND_STATIC_STATIC_DEFINE)
#
-# This will cause the export macros to expand to nothing when building the
-# static library.
+# This will cause the export macros to expand to nothing when building
+# the static library.
#
-# If DEFINE_NO_DEPRECATED is specified, then a macro ${BASE_NAME}_NO_DEPRECATED
-# will be defined
-# This macro can be used to remove deprecated code from preprocessor output.
+# If ``DEFINE_NO_DEPRECATED`` is specified, then a macro
+# ``${BASE_NAME}_NO_DEPRECATED`` will be defined This macro can be used to
+# remove deprecated code from preprocessor output:
+#
+# .. code-block:: cmake
+#
+# option(EXCLUDE_DEPRECATED "Exclude deprecated parts of the library" FALSE)
+# if (EXCLUDE_DEPRECATED)
+# set(NO_BUILD_DEPRECATED DEFINE_NO_DEPRECATED)
+# endif()
+# generate_export_header(somelib ${NO_BUILD_DEPRECATED})
#
-# option(EXCLUDE_DEPRECATED "Exclude deprecated parts of the library" FALSE)
-# if (EXCLUDE_DEPRECATED)
-# set(NO_BUILD_DEPRECATED DEFINE_NO_DEPRECATED)
-# endif()
-# generate_export_header(somelib ${NO_BUILD_DEPRECATED})
#
# And then in somelib:
#
-# class SOMELIB_EXPORT SomeClass
-# {
-# public:
-# #ifndef SOMELIB_NO_DEPRECATED
-# SOMELIB_DEPRECATED void oldMethod();
-# #endif
-# };
+# .. code-block:: c++
+#
+# class SOMELIB_EXPORT SomeClass
+# {
+# public:
+# #ifndef SOMELIB_NO_DEPRECATED
+# SOMELIB_DEPRECATED void oldMethod();
+# #endif
+# };
#
-# #ifndef SOMELIB_NO_DEPRECATED
-# void SomeClass::oldMethod() { }
-# #endif
+# .. code-block:: c++
#
-# If PREFIX_NAME is specified, the argument will be used as a prefix to all
-# generated macros.
+# #ifndef SOMELIB_NO_DEPRECATED
+# void SomeClass::oldMethod() { }
+# #endif
+#
+#
+# If ``PREFIX_NAME`` is specified, the argument will be used as a prefix to
+# all generated macros.
#
# For example:
#
-# generate_export_header(somelib PREFIX_NAME VTK_)
+# .. code-block:: cmake
+#
+# generate_export_header(somelib PREFIX_NAME VTK_)
#
-# Generates the macros VTK_SOMELIB_EXPORT etc.
+# Generates the macros ``VTK_SOMELIB_EXPORT`` etc.
+#
+# ::
+#
+# ADD_COMPILER_EXPORT_FLAGS( [<output_variable>] )
+#
+# The ``ADD_COMPILER_EXPORT_FLAGS`` function adds ``-fvisibility=hidden`` to
+# :variable:`CMAKE_CXX_FLAGS <CMAKE_<LANG>_FLAGS>` if supported, and is a no-op
+# on Windows which does not need extra compiler flags for exporting support.
+# You may optionally pass a single argument to ``ADD_COMPILER_EXPORT_FLAGS``
+# that will be populated with the ``CXX_FLAGS`` required to enable visibility
+# support for the compiler/architecture in use.
+#
+# This function is deprecated. Set the target properties
+# :prop_tgt:`CXX_VISIBILITY_PRESET <<LANG>_VISIBILITY_PRESET>` and
+# :prop_tgt:`VISIBILITY_INLINES_HIDDEN` instead.
#=============================================================================
# Copyright 2011 Stephen Kelly <steveire@gmail.com>
@@ -164,14 +213,13 @@ macro(_test_compiler_hidden_visibility)
# Exclude XL here because it misinterprets -fvisibility=hidden even though
# the check_cxx_compiler_flag passes
- # http://www.cdash.org/CDash/testDetails.php?test=109109951&build=1419259
if(NOT GCC_TOO_OLD
AND NOT _INTEL_TOO_OLD
AND NOT WIN32
AND NOT CYGWIN
- AND NOT "${CMAKE_CXX_COMPILER_ID}" MATCHES XL
- AND NOT "${CMAKE_CXX_COMPILER_ID}" MATCHES PGI
- AND NOT "${CMAKE_CXX_COMPILER_ID}" MATCHES Watcom)
+ AND NOT CMAKE_CXX_COMPILER_ID MATCHES XL
+ AND NOT CMAKE_CXX_COMPILER_ID MATCHES PGI
+ AND NOT CMAKE_CXX_COMPILER_ID MATCHES Watcom)
check_cxx_compiler_flag(-fvisibility=hidden COMPILER_HAS_HIDDEN_VISIBILITY)
check_cxx_compiler_flag(-fvisibility-inlines-hidden
COMPILER_HAS_HIDDEN_INLINE_VISIBILITY)
@@ -182,11 +230,15 @@ macro(_test_compiler_hidden_visibility)
endmacro()
macro(_test_compiler_has_deprecated)
- if("${CMAKE_CXX_COMPILER_ID}" MATCHES Borland
- OR "${CMAKE_CXX_COMPILER_ID}" MATCHES HP
+ # NOTE: Some Embarcadero compilers silently compile __declspec(deprecated)
+ # without error, but this is not a documented feature and the attribute does
+ # not actually generate any warnings.
+ if(CMAKE_CXX_COMPILER_ID MATCHES Borland
+ OR CMAKE_CXX_COMPILER_ID MATCHES Embarcadero
+ OR CMAKE_CXX_COMPILER_ID MATCHES HP
OR GCC_TOO_OLD
- OR "${CMAKE_CXX_COMPILER_ID}" MATCHES PGI
- OR "${CMAKE_CXX_COMPILER_ID}" MATCHES Watcom)
+ OR CMAKE_CXX_COMPILER_ID MATCHES PGI
+ OR CMAKE_CXX_COMPILER_ID MATCHES Watcom)
set(COMPILER_HAS_DEPRECATED "" CACHE INTERNAL
"Compiler support for a deprecated attribute")
else()
@@ -220,7 +272,7 @@ macro(_DO_SET_MACRO_VALUES TARGET_LIBRARY)
get_property(type TARGET ${TARGET_LIBRARY} PROPERTY TYPE)
if(NOT ${type} STREQUAL "STATIC_LIBRARY")
- if(WIN32)
+ if(WIN32 OR CYGWIN)
set(DEFINE_EXPORT "__declspec(dllexport)")
set(DEFINE_IMPORT "__declspec(dllimport)")
elseif(COMPILER_HAS_HIDDEN_VISIBILITY AND USE_COMPILER_HIDDEN_VISIBILITY)
@@ -315,6 +367,7 @@ function(GENERATE_EXPORT_HEADER TARGET_LIBRARY)
get_property(type TARGET ${TARGET_LIBRARY} PROPERTY TYPE)
if(NOT ${type} STREQUAL "STATIC_LIBRARY"
AND NOT ${type} STREQUAL "SHARED_LIBRARY"
+ AND NOT ${type} STREQUAL "OBJECT_LIBRARY"
AND NOT ${type} STREQUAL "MODULE_LIBRARY")
message(WARNING "This macro can only be used with libraries")
return()
@@ -326,6 +379,9 @@ function(GENERATE_EXPORT_HEADER TARGET_LIBRARY)
endfunction()
function(add_compiler_export_flags)
+ if(NOT CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.12)
+ message(DEPRECATION "The add_compiler_export_flags function is obsolete. Use the CXX_VISIBILITY_PRESET and VISIBILITY_INLINES_HIDDEN target properties instead.")
+ endif()
_test_compiler_hidden_visibility()
_test_compiler_has_deprecated()
@@ -343,7 +399,7 @@ function(add_compiler_export_flags)
# Either return the extra flags needed in the supplied argument, or to the
# CMAKE_CXX_FLAGS if no argument is supplied.
- if(ARGV0)
+ if(ARGC GREATER 0)
set(${ARGV0} "${EXTRA_FLAGS}" PARENT_SCOPE)
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_FLAGS}" PARENT_SCOPE)
diff --git a/Modules/GetPrerequisites.cmake b/Modules/GetPrerequisites.cmake
index 9e89788fe..391e7f8fa 100644
--- a/Modules/GetPrerequisites.cmake
+++ b/Modules/GetPrerequisites.cmake
@@ -1,111 +1,166 @@
-# - Functions to analyze and list executable file prerequisites.
-# This module provides functions to list the .dll, .dylib or .so
-# files that an executable or shared library file depends on. (Its
+#.rst:
+# GetPrerequisites
+# ----------------
+#
+# Functions to analyze and list executable file prerequisites.
+#
+# This module provides functions to list the .dll, .dylib or .so files
+# that an executable or shared library file depends on. (Its
# prerequisites.)
#
-# It uses various tools to obtain the list of required shared library files:
-# dumpbin (Windows)
-# objdump (MinGW on Windows)
-# ldd (Linux/Unix)
-# otool (Mac OSX)
+# It uses various tools to obtain the list of required shared library
+# files:
+#
+# ::
+#
+# dumpbin (Windows)
+# objdump (MinGW on Windows)
+# ldd (Linux/Unix)
+# otool (Mac OSX)
+#
# The following functions are provided by this module:
-# get_prerequisites
-# list_prerequisites
-# list_prerequisites_by_glob
-# gp_append_unique
-# is_file_executable
-# gp_item_default_embedded_path
-# (projects can override with gp_item_default_embedded_path_override)
-# gp_resolve_item
-# (projects can override with gp_resolve_item_override)
-# gp_resolved_file_type
-# (projects can override with gp_resolved_file_type_override)
-# gp_file_type
-# Requires CMake 2.6 or greater because it uses function, break, return and
-# PARENT_SCOPE.
-#
-# GET_PREREQUISITES(<target> <prerequisites_var> <exclude_system> <recurse>
-# <exepath> <dirs>)
-# Get the list of shared library files required by <target>. The list in
-# the variable named <prerequisites_var> should be empty on first entry to
-# this function. On exit, <prerequisites_var> will contain the list of
-# required shared library files.
-#
-# <target> is the full path to an executable file. <prerequisites_var> is the
-# name of a CMake variable to contain the results. <exclude_system> must be 0
-# or 1 indicating whether to include or exclude "system" prerequisites. If
-# <recurse> is set to 1 all prerequisites will be found recursively, if set to
-# 0 only direct prerequisites are listed. <exepath> is the path to the top
-# level executable used for @executable_path replacment on the Mac. <dirs> is
-# a list of paths where libraries might be found: these paths are searched
-# first when a target without any path info is given. Then standard system
-# locations are also searched: PATH, Framework locations, /usr/lib...
-#
-# LIST_PREREQUISITES(<target> [<recurse> [<exclude_system> [<verbose>]]])
-# Print a message listing the prerequisites of <target>.
#
-# <target> is the name of a shared library or executable target or the full
-# path to a shared library or executable file. If <recurse> is set to 1 all
+# ::
+#
+# get_prerequisites
+# list_prerequisites
+# list_prerequisites_by_glob
+# gp_append_unique
+# is_file_executable
+# gp_item_default_embedded_path
+# (projects can override with gp_item_default_embedded_path_override)
+# gp_resolve_item
+# (projects can override with gp_resolve_item_override)
+# gp_resolved_file_type
+# (projects can override with gp_resolved_file_type_override)
+# gp_file_type
+#
+# Requires CMake 2.6 or greater because it uses function, break, return
+# and PARENT_SCOPE.
+#
+# ::
+#
+# GET_PREREQUISITES(<target> <prerequisites_var> <exclude_system> <recurse>
+# <exepath> <dirs> [<rpaths>])
+#
+# Get the list of shared library files required by <target>. The list
+# in the variable named <prerequisites_var> should be empty on first
+# entry to this function. On exit, <prerequisites_var> will contain the
+# list of required shared library files.
+#
+# <target> is the full path to an executable file. <prerequisites_var>
+# is the name of a CMake variable to contain the results.
+# <exclude_system> must be 0 or 1 indicating whether to include or
+# exclude "system" prerequisites. If <recurse> is set to 1 all
# prerequisites will be found recursively, if set to 0 only direct
-# prerequisites are listed. <exclude_system> must be 0 or 1 indicating whether
-# to include or exclude "system" prerequisites. With <verbose> set to 0 only
-# the full path names of the prerequisites are printed, set to 1 extra
-# informatin will be displayed.
-#
-# LIST_PREREQUISITES_BY_GLOB(<glob_arg> <glob_exp>)
-# Print the prerequisites of shared library and executable files matching a
-# globbing pattern. <glob_arg> is GLOB or GLOB_RECURSE and <glob_exp> is a
-# globbing expression used with "file(GLOB" or "file(GLOB_RECURSE" to retrieve
-# a list of matching files. If a matching file is executable, its prerequisites
-# are listed.
+# prerequisites are listed. <exepath> is the path to the top level
+# executable used for @executable_path replacment on the Mac. <dirs> is
+# a list of paths where libraries might be found: these paths are
+# searched first when a target without any path info is given. Then
+# standard system locations are also searched: PATH, Framework
+# locations, /usr/lib...
+#
+# ::
+#
+# LIST_PREREQUISITES(<target> [<recurse> [<exclude_system> [<verbose>]]])
+#
+# Print a message listing the prerequisites of <target>.
+#
+# <target> is the name of a shared library or executable target or the
+# full path to a shared library or executable file. If <recurse> is set
+# to 1 all prerequisites will be found recursively, if set to 0 only
+# direct prerequisites are listed. <exclude_system> must be 0 or 1
+# indicating whether to include or exclude "system" prerequisites. With
+# <verbose> set to 0 only the full path names of the prerequisites are
+# printed, set to 1 extra informatin will be displayed.
+#
+# ::
+#
+# LIST_PREREQUISITES_BY_GLOB(<glob_arg> <glob_exp>)
+#
+# Print the prerequisites of shared library and executable files
+# matching a globbing pattern. <glob_arg> is GLOB or GLOB_RECURSE and
+# <glob_exp> is a globbing expression used with "file(GLOB" or
+# "file(GLOB_RECURSE" to retrieve a list of matching files. If a
+# matching file is executable, its prerequisites are listed.
#
# Any additional (optional) arguments provided are passed along as the
# optional arguments to the list_prerequisites calls.
#
-# GP_APPEND_UNIQUE(<list_var> <value>)
-# Append <value> to the list variable <list_var> only if the value is not
-# already in the list.
+# ::
+#
+# GP_APPEND_UNIQUE(<list_var> <value>)
+#
+# Append <value> to the list variable <list_var> only if the value is
+# not already in the list.
+#
+# ::
+#
+# IS_FILE_EXECUTABLE(<file> <result_var>)
#
-# IS_FILE_EXECUTABLE(<file> <result_var>)
-# Return 1 in <result_var> if <file> is a binary executable, 0 otherwise.
+# Return 1 in <result_var> if <file> is a binary executable, 0
+# otherwise.
+#
+# ::
+#
+# GP_ITEM_DEFAULT_EMBEDDED_PATH(<item> <default_embedded_path_var>)
#
-# GP_ITEM_DEFAULT_EMBEDDED_PATH(<item> <default_embedded_path_var>)
# Return the path that others should refer to the item by when the item
# is embedded inside a bundle.
#
# Override on a per-project basis by providing a project-specific
# gp_item_default_embedded_path_override function.
#
-# GP_RESOLVE_ITEM(<context> <item> <exepath> <dirs> <resolved_item_var>)
+# ::
+#
+# GP_RESOLVE_ITEM(<context> <item> <exepath> <dirs> <resolved_item_var>
+# [<rpaths>])
+#
# Resolve an item into an existing full path file.
#
# Override on a per-project basis by providing a project-specific
# gp_resolve_item_override function.
#
-# GP_RESOLVED_FILE_TYPE(<original_file> <file> <exepath> <dirs> <type_var>)
-# Return the type of <file> with respect to <original_file>. String
-# describing type of prerequisite is returned in variable named <type_var>.
+# ::
+#
+# GP_RESOLVED_FILE_TYPE(<original_file> <file> <exepath> <dirs> <type_var>
+# [<rpaths>])
+#
+# Return the type of <file> with respect to <original_file>. String
+# describing type of prerequisite is returned in variable named
+# <type_var>.
#
# Use <exepath> and <dirs> if necessary to resolve non-absolute <file>
# values -- but only for non-embedded items.
#
# Possible types are:
-# system
-# local
-# embedded
-# other
+#
+# ::
+#
+# system
+# local
+# embedded
+# other
+#
# Override on a per-project basis by providing a project-specific
# gp_resolved_file_type_override function.
#
-# GP_FILE_TYPE(<original_file> <file> <type_var>)
-# Return the type of <file> with respect to <original_file>. String
-# describing type of prerequisite is returned in variable named <type_var>.
+# ::
+#
+# GP_FILE_TYPE(<original_file> <file> <type_var>)
+#
+# Return the type of <file> with respect to <original_file>. String
+# describing type of prerequisite is returned in variable named
+# <type_var>.
#
# Possible types are:
-# system
-# local
-# embedded
-# other
+#
+# ::
+#
+# system
+# local
+# embedded
+# other
#=============================================================================
# Copyright 2008-2009 Kitware, Inc.
@@ -124,7 +179,7 @@ function(gp_append_unique list_var value)
set(contains 0)
foreach(item ${${list_var}})
- if("${item}" STREQUAL "${value}")
+ if(item STREQUAL "${value}")
set(contains 1)
break()
endif()
@@ -174,9 +229,14 @@ function(is_file_executable file result_var)
if(file_cmd)
execute_process(COMMAND "${file_cmd}" "${file_full}"
+ RESULT_VARIABLE file_rv
OUTPUT_VARIABLE file_ov
+ ERROR_VARIABLE file_ev
OUTPUT_STRIP_TRAILING_WHITESPACE
)
+ if(NOT file_rv STREQUAL "0")
+ message(FATAL_ERROR "${file_cmd} failed: ${file_rv}\n${file_ev}")
+ endif()
# Replace the name of the file in the output with a placeholder token
# (the string " _file_full_ ") so that just in case the path name of
@@ -205,6 +265,13 @@ function(is_file_executable file result_var)
return()
endif()
+ # "file" version 5.22 does not print "(used shared libraries)"
+ # but uses "interpreter"
+ if("${file_ov}" MATCHES "shared object.*interpreter")
+ set(${result_var} 1 PARENT_SCOPE)
+ return()
+ endif()
+
else()
message(STATUS "warning: No 'file' command, skipping execute_process...")
endif()
@@ -268,6 +335,11 @@ endfunction()
function(gp_resolve_item context item exepath dirs resolved_item_var)
set(resolved 0)
set(resolved_item "${item}")
+ if(ARGC GREATER 5)
+ set(rpaths "${ARGV5}")
+ else()
+ set(rpaths "")
+ endif()
# Is it already resolved?
#
@@ -276,7 +348,7 @@ function(gp_resolve_item context item exepath dirs resolved_item_var)
endif()
if(NOT resolved)
- if(item MATCHES "@executable_path")
+ if(item MATCHES "^@executable_path")
#
# @executable_path references are assumed relative to exepath
#
@@ -294,7 +366,7 @@ function(gp_resolve_item context item exepath dirs resolved_item_var)
endif()
if(NOT resolved)
- if(item MATCHES "@loader_path")
+ if(item MATCHES "^@loader_path")
#
# @loader_path references are assumed relative to the
# PATH of the given "context" (presumably another library)
@@ -314,7 +386,7 @@ function(gp_resolve_item context item exepath dirs resolved_item_var)
endif()
if(NOT resolved)
- if(item MATCHES "@rpath")
+ if(item MATCHES "^@rpath")
#
# @rpath references are relative to the paths built into the binaries with -rpath
# We handle this case like we do for other Unixes
@@ -322,9 +394,9 @@ function(gp_resolve_item context item exepath dirs resolved_item_var)
string(REPLACE "@rpath/" "" norpath_item "${item}")
set(ri "ri-NOTFOUND")
- find_file(ri "${norpath_item}" ${exepath} ${dirs} NO_DEFAULT_PATH)
+ find_file(ri "${norpath_item}" ${exepath} ${dirs} ${rpaths} NO_DEFAULT_PATH)
if(ri)
- #message(STATUS "info: 'find_file' in exepath/dirs (${ri})")
+ #message(STATUS "info: 'find_file' in exepath/dirs/rpaths (${ri})")
set(resolved 1)
set(resolved_item "${ri}")
set(ri "ri-NOTFOUND")
@@ -418,6 +490,11 @@ endfunction()
function(gp_resolved_file_type original_file file exepath dirs type_var)
+ if(ARGC GREATER 5)
+ set(rpaths "${ARGV5}")
+ else()
+ set(rpaths "")
+ endif()
#message(STATUS "**")
if(NOT IS_ABSOLUTE "${original_file}")
@@ -436,7 +513,7 @@ function(gp_resolved_file_type original_file file exepath dirs type_var)
if(NOT is_embedded)
if(NOT IS_ABSOLUTE "${file}")
- gp_resolve_item("${original_file}" "${file}" "${exepath}" "${dirs}" resolved_file)
+ gp_resolve_item("${original_file}" "${file}" "${exepath}" "${dirs}" resolved_file "${rpaths}")
endif()
string(TOLOWER "${original_file}" original_lower)
@@ -456,12 +533,12 @@ function(gp_resolved_file_type original_file file exepath dirs type_var)
if(WIN32)
string(TOLOWER "$ENV{SystemRoot}" sysroot)
- string(REGEX REPLACE "\\\\" "/" sysroot "${sysroot}")
+ file(TO_CMAKE_PATH "${sysroot}" sysroot)
string(TOLOWER "$ENV{windir}" windir)
- string(REGEX REPLACE "\\\\" "/" windir "${windir}")
+ file(TO_CMAKE_PATH "${windir}" windir)
- if(lower MATCHES "^(${sysroot}/sys(tem|wow)|${windir}/sys(tem|wow)|(.*/)*msvc[^/]+dll)")
+ if(lower MATCHES "^(api-ms-win-|${sysroot}/sys(tem|wow)|${windir}/sys(tem|wow)|(.*/)*msvc[^/]+dll)")
set(is_system 1)
endif()
@@ -471,15 +548,25 @@ function(gp_resolved_file_type original_file file exepath dirs type_var)
if(CYGPATH_EXECUTABLE)
execute_process(COMMAND ${CYGPATH_EXECUTABLE} -W
+ RESULT_VARIABLE env_rv
OUTPUT_VARIABLE env_windir
+ ERROR_VARIABLE env_ev
OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if(NOT env_rv STREQUAL "0")
+ message(FATAL_ERROR "${CYGPATH_EXECUTABLE} -W failed: ${env_rv}\n${env_ev}")
+ endif()
execute_process(COMMAND ${CYGPATH_EXECUTABLE} -S
+ RESULT_VARIABLE env_rv
OUTPUT_VARIABLE env_sysdir
+ ERROR_VARIABLE env_ev
OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if(NOT env_rv STREQUAL "0")
+ message(FATAL_ERROR "${CYGPATH_EXECUTABLE} -S failed: ${env_rv}\n${env_ev}")
+ endif()
string(TOLOWER "${env_windir}" windir)
string(TOLOWER "${env_sysdir}" sysroot)
- if(lower MATCHES "^(${sysroot}/sys(tem|wow)|${windir}/sys(tem|wow)|(.*/)*msvc[^/]+dll)")
+ if(lower MATCHES "^(api-ms-win-|${sysroot}/sys(tem|wow)|${windir}/sys(tem|wow)|(.*/)*msvc[^/]+dll)")
set(is_system 1)
endif()
endif()
@@ -489,14 +576,14 @@ function(gp_resolved_file_type original_file file exepath dirs type_var)
if(NOT is_system)
get_filename_component(original_path "${original_lower}" PATH)
get_filename_component(path "${lower}" PATH)
- if("${original_path}" STREQUAL "${path}")
+ if(original_path STREQUAL path)
set(is_local 1)
else()
string(LENGTH "${original_path}/" original_length)
string(LENGTH "${lower}" path_length)
if(${path_length} GREATER ${original_length})
string(SUBSTRING "${lower}" 0 ${original_length} path)
- if("${original_path}/" STREQUAL "${path}")
+ if("${original_path}/" STREQUAL path)
set(is_embedded 1)
endif()
endif()
@@ -559,6 +646,11 @@ endfunction()
function(get_prerequisites target prerequisites_var exclude_system recurse exepath dirs)
set(verbose 0)
set(eol_char "E")
+ if(ARGC GREATER 6)
+ set(rpaths "${ARGV6}")
+ else()
+ set(rpaths "")
+ endif()
if(NOT IS_ABSOLUTE "${target}")
message("warning: target '${target}' is not absolute...")
@@ -584,7 +676,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
# Try to choose the right tool by default. Caller can set gp_tool prior to
# calling this function to force using a different tool.
#
- if("${gp_tool}" STREQUAL "")
+ if(NOT gp_tool)
set(gp_tool "ldd")
if(APPLE)
@@ -608,45 +700,38 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
return()
endif()
- set(gp_tool_known 0)
+ set(gp_cmd_maybe_filter) # optional command to pre-filter gp_tool results
- if("${gp_tool}" STREQUAL "ldd")
+ if(gp_tool STREQUAL "ldd")
set(gp_cmd_args "")
set(gp_regex "^[\t ]*[^\t ]+ => ([^\t\(]+) .*${eol_char}$")
set(gp_regex_error "not found${eol_char}$")
set(gp_regex_fallback "^[\t ]*([^\t ]+) => ([^\t ]+).*${eol_char}$")
set(gp_regex_cmp_count 1)
- set(gp_tool_known 1)
- endif()
-
- if("${gp_tool}" STREQUAL "otool")
+ elseif(gp_tool STREQUAL "otool")
set(gp_cmd_args "-L")
set(gp_regex "^\t([^\t]+) \\(compatibility version ([0-9]+.[0-9]+.[0-9]+), current version ([0-9]+.[0-9]+.[0-9]+)\\)${eol_char}$")
set(gp_regex_error "")
set(gp_regex_fallback "")
set(gp_regex_cmp_count 3)
- set(gp_tool_known 1)
- endif()
-
- if("${gp_tool}" STREQUAL "dumpbin")
+ elseif(gp_tool STREQUAL "dumpbin")
set(gp_cmd_args "/dependents")
set(gp_regex "^ ([^ ].*[Dd][Ll][Ll])${eol_char}$")
set(gp_regex_error "")
set(gp_regex_fallback "")
set(gp_regex_cmp_count 1)
- set(gp_tool_known 1)
- endif()
-
- if("${gp_tool}" STREQUAL "objdump")
+ elseif(gp_tool STREQUAL "objdump")
set(gp_cmd_args "-p")
set(gp_regex "^\t*DLL Name: (.*\\.[Dd][Ll][Ll])${eol_char}$")
set(gp_regex_error "")
set(gp_regex_fallback "")
set(gp_regex_cmp_count 1)
- set(gp_tool_known 1)
- endif()
-
- if(NOT gp_tool_known)
+ # objdump generaates copious output so we create a grep filter to pre-filter results
+ find_program(gp_grep_cmd grep)
+ if(gp_grep_cmd)
+ set(gp_cmd_maybe_filter COMMAND ${gp_grep_cmd} "^[[:blank:]]*DLL Name: ")
+ endif()
+ else()
message(STATUS "warning: gp_tool='${gp_tool}' is an unknown tool...")
message(STATUS "CMake function get_prerequisites needs more code to handle '${gp_tool}'")
message(STATUS "Valid gp_tool values are dumpbin, ldd, objdump and otool.")
@@ -654,7 +739,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
endif()
- if("${gp_tool}" STREQUAL "dumpbin")
+ if(gp_tool STREQUAL "dumpbin")
# When running dumpbin, it also needs the "Common7/IDE" directory in the
# PATH. It will already be in the PATH if being run from a Visual Studio
# command prompt. Add it to the PATH here in case we are running from a
@@ -669,7 +754,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
set(gp_found_cmd_dlls_dir 0)
file(TO_CMAKE_PATH "$ENV{PATH}" env_path)
foreach(gp_env_path_element ${env_path})
- if("${gp_env_path_element}" STREQUAL "${gp_cmd_dlls_dir}")
+ if(gp_env_path_element STREQUAL gp_cmd_dlls_dir)
set(gp_found_cmd_dlls_dir 1)
endif()
endforeach()
@@ -683,11 +768,13 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
#
# </setup-gp_tool-vars>
- if("${gp_tool}" STREQUAL "ldd")
+ if(gp_tool STREQUAL "ldd")
set(old_ld_env "$ENV{LD_LIBRARY_PATH}")
- foreach(dir ${exepath} ${dirs})
- set(ENV{LD_LIBRARY_PATH} "${dir}:$ENV{LD_LIBRARY_PATH}")
+ set(new_ld_env "${exepath}")
+ foreach(dir ${dirs})
+ set(new_ld_env "${new_ld_env}:${dir}")
endforeach()
+ set(ENV{LD_LIBRARY_PATH} "${new_ld_env}:$ENV{LD_LIBRARY_PATH}")
endif()
@@ -700,10 +787,21 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
#
execute_process(
COMMAND ${gp_cmd} ${gp_cmd_args} ${target}
+ ${gp_cmd_maybe_filter}
+ RESULT_VARIABLE gp_rv
OUTPUT_VARIABLE gp_cmd_ov
+ ERROR_VARIABLE gp_ev
)
+ if(NOT gp_rv STREQUAL "0")
+ if(gp_tool STREQUAL "dumpbin")
+ # dumpbin error messages seem to go to stdout
+ message(FATAL_ERROR "${gp_cmd} failed: ${gp_rv}\n${gp_ev}\n${gp_cmd_ov}")
+ else()
+ message(FATAL_ERROR "${gp_cmd} failed: ${gp_rv}\n${gp_ev}")
+ endif()
+ endif()
- if("${gp_tool}" STREQUAL "ldd")
+ if(gp_tool STREQUAL "ldd")
set(ENV{LD_LIBRARY_PATH} "${old_ld_env}")
endif()
@@ -717,17 +815,22 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
# Convert to a list of lines:
#
- string(REGEX REPLACE ";" "\\\\;" candidates "${gp_cmd_ov}")
- string(REGEX REPLACE "\n" "${eol_char};" candidates "${candidates}")
+ string(REPLACE ";" "\\;" candidates "${gp_cmd_ov}")
+ string(REPLACE "\n" "${eol_char};" candidates "${candidates}")
# check for install id and remove it from list, since otool -L can include a
# reference to itself
set(gp_install_id)
- if("${gp_tool}" STREQUAL "otool")
+ if(gp_tool STREQUAL "otool")
execute_process(
COMMAND otool -D ${target}
+ RESULT_VARIABLE otool_rv
OUTPUT_VARIABLE gp_install_id_ov
+ ERROR_VARIABLE otool_ev
)
+ if(NOT otool_rv STREQUAL "0")
+ message(FATAL_ERROR "otool -D failed: ${otool_rv}\n${otool_ev}")
+ endif()
# second line is install name
string(REGEX REPLACE ".*:\n" "" gp_install_id "${gp_install_id_ov}")
if(gp_install_id)
@@ -773,15 +876,15 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
#
set(add_item 1)
- if("${item}" STREQUAL "${gp_install_id}")
+ if(item STREQUAL gp_install_id)
set(add_item 0)
endif()
if(add_item AND ${exclude_system})
set(type "")
- gp_resolved_file_type("${target}" "${item}" "${exepath}" "${dirs}" type)
+ gp_resolved_file_type("${target}" "${item}" "${exepath}" "${dirs}" type "${rpaths}")
- if("${type}" STREQUAL "system")
+ if(type STREQUAL "system")
set(add_item 0)
endif()
endif()
@@ -800,7 +903,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
# that the analysis tools can simply accept it as input.
#
if(NOT list_length_before_append EQUAL list_length_after_append)
- gp_resolve_item("${target}" "${item}" "${exepath}" "${dirs}" resolved_item)
+ gp_resolve_item("${target}" "${item}" "${exepath}" "${dirs}" resolved_item "${rpaths}")
set(unseen_prereqs ${unseen_prereqs} "${resolved_item}")
endif()
endif()
@@ -819,7 +922,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
if(${recurse})
set(more_inputs ${unseen_prereqs})
foreach(input ${more_inputs})
- get_prerequisites("${input}" ${prerequisites_var} ${exclude_system} ${recurse} "${exepath}" "${dirs}")
+ get_prerequisites("${input}" ${prerequisites_var} ${exclude_system} ${recurse} "${exepath}" "${dirs}" "${rpaths}")
endforeach()
endif()
@@ -828,22 +931,22 @@ endfunction()
function(list_prerequisites target)
- if("${ARGV1}" STREQUAL "")
- set(all 1)
- else()
+ if(ARGC GREATER 1 AND NOT "${ARGV1}" STREQUAL "")
set(all "${ARGV1}")
+ else()
+ set(all 1)
endif()
- if("${ARGV2}" STREQUAL "")
- set(exclude_system 0)
- else()
+ if(ARGC GREATER 2 AND NOT "${ARGV2}" STREQUAL "")
set(exclude_system "${ARGV2}")
+ else()
+ set(exclude_system 0)
endif()
- if("${ARGV3}" STREQUAL "")
- set(verbose 0)
- else()
+ if(ARGC GREATER 3 AND NOT "${ARGV3}" STREQUAL "")
set(verbose "${ARGV3}")
+ else()
+ set(verbose 0)
endif()
set(count 0)
diff --git a/Modules/InstallRequiredSystemLibraries.cmake b/Modules/InstallRequiredSystemLibraries.cmake
index 2479d68b5..2ff9aed4b 100644
--- a/Modules/InstallRequiredSystemLibraries.cmake
+++ b/Modules/InstallRequiredSystemLibraries.cmake
@@ -1,30 +1,50 @@
-# By including this file, all library files listed in the variable
-# CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS will be installed with
-# install(PROGRAMS ...) into bin for WIN32 and lib
-# for non-WIN32. If CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP is set to TRUE
-# before including this file, then the INSTALL command is not called.
-# The user can use the variable CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS to use a
-# custom install command and install them however they want.
-# If it is the MSVC compiler, then the microsoft run
-# time libraries will be found and automatically added to the
-# CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS, and installed.
-# If CMAKE_INSTALL_DEBUG_LIBRARIES is set and it is the MSVC
-# compiler, then the debug libraries are installed when available.
-# If CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY is set then only the debug
-# libraries are installed when both debug and release are available.
-# If CMAKE_INSTALL_MFC_LIBRARIES is set then the MFC run time
-# libraries are installed as well as the CRT run time libraries.
-# If CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION is set then the libraries are
-# installed to that directory rather than the default.
-# If CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS is NOT set, then this file
-# warns about required files that do not exist. You can set this variable to
-# ON before including this file to avoid the warning. For example, the Visual
-# Studio Express editions do not include the redistributable files, so if you
-# include this file on a machine with only VS Express installed, you'll get
-# the warning.
+#.rst:
+# InstallRequiredSystemLibraries
+# ------------------------------
+#
+# Include this module to search for compiler-provided system runtime
+# libraries and add install rules for them. Some optional variables
+# may be set prior to including the module to adjust behavior:
+#
+# ``CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS``
+# Specify additional runtime libraries that may not be detected.
+# After inclusion any detected libraries will be appended to this.
+#
+# ``CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP``
+# Set to TRUE to skip calling the :command:`install(PROGRAMS)` command to
+# allow the includer to specify its own install rule, using the value of
+# ``CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS`` to get the list of libraries.
+#
+# ``CMAKE_INSTALL_DEBUG_LIBRARIES``
+# Set to TRUE to install the debug runtime libraries when available
+# with MSVC tools.
+#
+# ``CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY``
+# Set to TRUE to install only the debug runtime libraries with MSVC
+# tools even if the release runtime libraries are also available.
+#
+# ``CMAKE_INSTALL_MFC_LIBRARIES``
+# Set to TRUE to install the MSVC MFC runtime libraries.
+#
+# ``CMAKE_INSTALL_OPENMP_LIBRARIES``
+# Set to TRUE to install the MSVC OpenMP runtime libraries
+#
+# ``CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION``
+# Specify the :command:`install(PROGRAMS)` command ``DESTINATION``
+# option. If not specified, the default is ``bin`` on Windows
+# and ``lib`` elsewhere.
+#
+# ``CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS``
+# Set to TRUE to disable warnings about required library files that
+# do not exist. (For example, Visual Studio Express editions may
+# not provide the redistributable files.)
+#
+# ``CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT``
+# Specify the :command:`install(PROGRAMS)` command ``COMPONENT``
+# option. If not specified, no such option will be used.
#=============================================================================
-# Copyright 2006-2009 Kitware, Inc.
+# Copyright 2006-2015 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
@@ -89,6 +109,8 @@ if(MSVC)
"${MSVC80_CRT_DIR}/msvcp80.dll"
"${MSVC80_CRT_DIR}/msvcr80.dll"
)
+ else()
+ set(__install__libs)
endif()
if(CMAKE_INSTALL_DEBUG_LIBRARIES)
@@ -127,6 +149,8 @@ if(MSVC)
"${MSVC90_CRT_DIR}/msvcp90.dll"
"${MSVC90_CRT_DIR}/msvcr90.dll"
)
+ else()
+ set(__install__libs)
endif()
if(CMAKE_INSTALL_DEBUG_LIBRARIES)
@@ -152,7 +176,8 @@ if(MSVC)
"${msvc_install_dir}/../../VC/redist"
"${base_dir}/VC/redist"
"$ENV{ProgramFiles}/Microsoft Visual Studio ${v}.0/VC/redist"
- "$ENV{ProgramFiles(x86)}/Microsoft Visual Studio ${v}.0/VC/redist"
+ set(programfilesx86 "ProgramFiles(x86)")
+ "$ENV{${programfilesx86}}/Microsoft Visual Studio ${v}.0/VC/redist"
)
mark_as_advanced(MSVC${v}_REDIST_DIR)
set(MSVC${v}_CRT_DIR "${MSVC${v}_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC${v}0.CRT")
@@ -160,8 +185,14 @@ if(MSVC)
if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
set(__install__libs
"${MSVC${v}_CRT_DIR}/msvcp${v}0.dll"
- "${MSVC${v}_CRT_DIR}/msvcr${v}0.dll"
)
+ if(NOT v VERSION_LESS 14)
+ list(APPEND __install__libs "${MSVC${v}_CRT_DIR}/vcruntime${v}0.dll")
+ else()
+ list(APPEND __install__libs "${MSVC${v}_CRT_DIR}/msvcr${v}0.dll")
+ endif()
+ else()
+ set(__install__libs)
endif()
if(CMAKE_INSTALL_DEBUG_LIBRARIES)
@@ -169,8 +200,12 @@ if(MSVC)
"${MSVC${v}_REDIST_DIR}/Debug_NonRedist/${CMAKE_MSVC_ARCH}/Microsoft.VC${v}0.DebugCRT")
set(__install__libs ${__install__libs}
"${MSVC${v}_CRT_DIR}/msvcp${v}0d.dll"
- "${MSVC${v}_CRT_DIR}/msvcr${v}0d.dll"
)
+ if(NOT v VERSION_LESS 14)
+ list(APPEND __install__libs "${MSVC${v}_CRT_DIR}/vcruntime${v}0d.dll")
+ else()
+ list(APPEND __install__libs "${MSVC${v}_CRT_DIR}/msvcr${v}0d.dll")
+ endif()
endif()
endmacro()
@@ -186,6 +221,10 @@ if(MSVC)
MSVCRT_FILES_FOR_VERSION(12)
endif()
+ if(MSVC14)
+ MSVCRT_FILES_FOR_VERSION(14)
+ endif()
+
if(CMAKE_INSTALL_MFC_LIBRARIES)
if(MSVC70)
set(__install__libs ${__install__libs}
@@ -290,25 +329,37 @@ if(MSVC)
macro(MFC_FILES_FOR_VERSION version)
set(v "${version}")
+ # Multi-Byte Character Set versions of MFC are available as optional
+ # addon since Visual Studio 12. So for version 12 or higher, check
+ # whether they are available and exclude them if they are not.
+
if(CMAKE_INSTALL_DEBUG_LIBRARIES)
set(MSVC${v}_MFC_DIR
"${MSVC${v}_REDIST_DIR}/Debug_NonRedist/${CMAKE_MSVC_ARCH}/Microsoft.VC${v}0.DebugMFC")
set(__install__libs ${__install__libs}
- "${MSVC${v}_MFC_DIR}/mfc${v}0d.dll"
"${MSVC${v}_MFC_DIR}/mfc${v}0ud.dll"
- "${MSVC${v}_MFC_DIR}/mfcm${v}0d.dll"
"${MSVC${v}_MFC_DIR}/mfcm${v}0ud.dll"
)
+ if("${v}" LESS 12 OR EXISTS "${MSVC${v}_MFC_DIR}/mfc${v}0d.dll")
+ set(__install__libs ${__install__libs}
+ "${MSVC${v}_MFC_DIR}/mfc${v}0d.dll"
+ "${MSVC${v}_MFC_DIR}/mfcm${v}0d.dll"
+ )
+ endif()
endif()
set(MSVC${v}_MFC_DIR "${MSVC${v}_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC${v}0.MFC")
if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
set(__install__libs ${__install__libs}
- "${MSVC${v}_MFC_DIR}/mfc${v}0.dll"
"${MSVC${v}_MFC_DIR}/mfc${v}0u.dll"
- "${MSVC${v}_MFC_DIR}/mfcm${v}0.dll"
"${MSVC${v}_MFC_DIR}/mfcm${v}0u.dll"
)
+ if("${v}" LESS 12 OR EXISTS "${MSVC${v}_MFC_DIR}/mfc${v}0.dll")
+ set(__install__libs ${__install__libs}
+ "${MSVC${v}_MFC_DIR}/mfc${v}0.dll"
+ "${MSVC${v}_MFC_DIR}/mfcm${v}0.dll"
+ )
+ endif()
endif()
# include the language dll's as well as the actuall dll's
@@ -338,6 +389,44 @@ if(MSVC)
if(MSVC12)
MFC_FILES_FOR_VERSION(12)
endif()
+
+ if(MSVC14)
+ MFC_FILES_FOR_VERSION(14)
+ endif()
+ endif()
+
+ # MSVC 8 was the first version with OpenMP
+ # Furthermore, there is no debug version of this
+ if(CMAKE_INSTALL_OPENMP_LIBRARIES)
+ macro(OPENMP_FILES_FOR_VERSION version_a version_b)
+ set(va "${version_a}")
+ set(vb "${version_b}")
+ set(MSVC${va}_OPENMP_DIR "${MSVC${va}_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC${vb}.OPENMP")
+
+ if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
+ set(__install__libs ${__install__libs}
+ "${MSVC${va}_OPENMP_DIR}/vcomp${vb}.dll")
+ endif()
+ endmacro()
+
+ if(MSVC80)
+ OPENMP_FILES_FOR_VERSION(80 80)
+ endif()
+ if(MSVC90)
+ OPENMP_FILES_FOR_VERSION(90 90)
+ endif()
+ if(MSVC10)
+ OPENMP_FILES_FOR_VERSION(10 100)
+ endif()
+ if(MSVC11)
+ OPENMP_FILES_FOR_VERSION(11 110)
+ endif()
+ if(MSVC12)
+ OPENMP_FILES_FOR_VERSION(12 120)
+ endif()
+ if(MSVC14)
+ OPENMP_FILES_FOR_VERSION(14 140)
+ endif()
endif()
foreach(lib
@@ -361,18 +450,18 @@ endif()
if(WATCOM)
get_filename_component( CompilerPath ${CMAKE_C_COMPILER} PATH )
- if(WATCOM17)
- set( __install__libs ${CompilerPath}/clbr17.dll
- ${CompilerPath}/mt7r17.dll ${CompilerPath}/plbr17.dll )
- endif()
- if(WATCOM18)
- set( __install__libs ${CompilerPath}/clbr18.dll
- ${CompilerPath}/mt7r18.dll ${CompilerPath}/plbr18.dll )
- endif()
- if(WATCOM19)
- set( __install__libs ${CompilerPath}/clbr19.dll
- ${CompilerPath}/mt7r19.dll ${CompilerPath}/plbr19.dll )
+ if(CMAKE_C_COMPILER_VERSION)
+ set(_compiler_version ${CMAKE_C_COMPILER_VERSION})
+ else()
+ set(_compiler_version ${CMAKE_CXX_COMPILER_VERSION})
endif()
+ string(REGEX MATCHALL "[0-9]+" _watcom_version_list "${_compiler_version}")
+ list(GET _watcom_version_list 0 _watcom_major)
+ list(GET _watcom_version_list 1 _watcom_minor)
+ set( __install__libs
+ ${CompilerPath}/clbr${_watcom_major}${_watcom_minor}.dll
+ ${CompilerPath}/mt7r${_watcom_major}${_watcom_minor}.dll
+ ${CompilerPath}/plbr${_watcom_major}${_watcom_minor}.dll )
foreach(lib
${__install__libs}
)
@@ -404,7 +493,13 @@ if(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS)
set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION lib)
endif()
endif()
+ if(CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT)
+ set(_CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT
+ COMPONENT ${CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT})
+ endif()
install(PROGRAMS ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS}
- DESTINATION ${CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION})
+ DESTINATION ${CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION}
+ ${_CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT}
+ )
endif()
endif()
diff --git a/Modules/IntelVSImplicitPath/CMakeLists.txt b/Modules/IntelVSImplicitPath/CMakeLists.txt
index 96dc4e612..d11570447 100644
--- a/Modules/IntelVSImplicitPath/CMakeLists.txt
+++ b/Modules/IntelVSImplicitPath/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required (VERSION 2.8)
+cmake_minimum_required(VERSION ${CMAKE_VERSION})
project(IntelFortranImplicit Fortran)
add_custom_command(
OUTPUT output.cmake
diff --git a/Modules/Internal/FeatureTesting.cmake b/Modules/Internal/FeatureTesting.cmake
new file mode 100644
index 000000000..86b89b25c
--- /dev/null
+++ b/Modules/Internal/FeatureTesting.cmake
@@ -0,0 +1,60 @@
+
+macro(record_compiler_features lang compile_flags feature_list)
+ include("${CMAKE_ROOT}/Modules/Compiler/${CMAKE_${lang}_COMPILER_ID}-${lang}-FeatureTests.cmake" OPTIONAL)
+
+ string(TOLOWER ${lang} lang_lc)
+ file(REMOVE "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.bin")
+ file(WRITE "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.${lang_lc}" "
+ const char features[] = {\"\\n\"\n")
+
+ get_property(known_features GLOBAL PROPERTY CMAKE_${lang}_KNOWN_FEATURES)
+
+ foreach(feature ${known_features})
+ if (_cmake_feature_test_${feature})
+ if (${_cmake_feature_test_${feature}} STREQUAL 1)
+ set(_feature_condition "\"1\" ")
+ else()
+ set(_feature_condition "#if ${_cmake_feature_test_${feature}}\n\"1\"\n#else\n\"0\"\n#endif\n")
+ endif()
+ file(APPEND "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.${lang_lc}" "\"${lang}_FEATURE:\"\n${_feature_condition}\"${feature}\\n\"\n")
+ endif()
+ endforeach()
+ file(APPEND "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.${lang_lc}"
+ "\n};\n\nint main(int argc, char** argv) { (void)argv; return features[argc]; }\n")
+
+ try_compile(CMAKE_${lang}_FEATURE_TEST
+ ${CMAKE_BINARY_DIR} "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.${lang_lc}"
+ COMPILE_DEFINITIONS "${compile_flags}"
+ OUTPUT_VARIABLE _output
+ COPY_FILE "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.bin"
+ COPY_FILE_ERROR _copy_error
+ )
+ if(CMAKE_${lang}_FEATURE_TEST AND NOT _copy_error)
+ set(_result 0)
+ else()
+ set(_result 255)
+ endif()
+ unset(CMAKE_${lang}_FEATURE_TEST CACHE)
+
+ if (_result EQUAL 0)
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "\n\nDetecting ${lang} [${compile_flags}] compiler features compiled with the following output:\n${_output}\n\n")
+ if(EXISTS "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.bin")
+ file(STRINGS "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.bin"
+ features REGEX "${lang}_FEATURE:.*")
+ foreach(info ${features})
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ " Feature record: ${info}\n")
+ string(REPLACE "${lang}_FEATURE:" "" info ${info})
+ string(SUBSTRING ${info} 0 1 has_feature)
+ if(has_feature)
+ string(REGEX REPLACE "^1" "" feature ${info})
+ list(APPEND ${feature_list} ${feature})
+ endif()
+ endforeach()
+ endif()
+ else()
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Detecting ${lang} [${compile_flags}] compiler features failed to compile with the following output:\n${_output}\n${_copy_error}\n\n")
+ endif()
+endmacro()
diff --git a/Modules/MacroAddFileDependencies.cmake b/Modules/MacroAddFileDependencies.cmake
index d0605a114..38df1d3a9 100644
--- a/Modules/MacroAddFileDependencies.cmake
+++ b/Modules/MacroAddFileDependencies.cmake
@@ -1,10 +1,16 @@
-# - MACRO_ADD_FILE_DEPENDENCIES(<_file> depend_files...)
-# Using the macro MACRO_ADD_FILE_DEPENDENCIES() is discouraged. There are usually
-# better ways to specify the correct dependencies.
+#.rst:
+# MacroAddFileDependencies
+# ------------------------
#
-# MACRO_ADD_FILE_DEPENDENCIES(<_file> depend_files...) is just a convenience
-# wrapper around the OBJECT_DEPENDS source file property. You can just
-# use set_property(SOURCE <file> APPEND PROPERTY OBJECT_DEPENDS depend_files) instead.
+# MACRO_ADD_FILE_DEPENDENCIES(<_file> depend_files...)
+#
+# Using the macro MACRO_ADD_FILE_DEPENDENCIES() is discouraged. There
+# are usually better ways to specify the correct dependencies.
+#
+# MACRO_ADD_FILE_DEPENDENCIES(<_file> depend_files...) is just a
+# convenience wrapper around the OBJECT_DEPENDS source file property.
+# You can just use set_property(SOURCE <file> APPEND PROPERTY
+# OBJECT_DEPENDS depend_files) instead.
#=============================================================================
# Copyright 2006-2009 Kitware, Inc.
diff --git a/Modules/MatlabTestsRedirect.cmake b/Modules/MatlabTestsRedirect.cmake
new file mode 100644
index 000000000..77b7afe69
--- /dev/null
+++ b/Modules/MatlabTestsRedirect.cmake
@@ -0,0 +1,91 @@
+# This is an undocumented internal helper for the FindMatlab
+# module ``matlab_add_unit_test`` command.
+
+#=============================================================================
+# Copyright 2014-2015 Raffi Enficiaud, Max Planck Society
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+
+# Usage: cmake
+# -Dtest_timeout=180
+# -Doutput_directory=
+# -Dadditional_paths=""
+# -Dno_unittest_framework=""
+# -DMatlab_PROGRAM=matlab_exe_location
+# -DMatlab_ADDITIONNAL_STARTUP_OPTIONS=""
+# -Dtest_name=name_of_the_test
+# -Dcmd_to_run_before_test=""
+# -Dunittest_file_to_run
+# -P FindMatlab_TestsRedirect.cmake
+
+set(Matlab_UNIT_TESTS_CMD -nosplash -nojvm -nodesktop -nodisplay ${Matlab_ADDITIONNAL_STARTUP_OPTIONS})
+if(WIN32)
+ set(Matlab_UNIT_TESTS_CMD ${Matlab_UNIT_TESTS_CMD} -wait)
+endif()
+
+if(NOT test_timeout)
+ set(test_timeout 180)
+endif()
+
+if(NOT cmd_to_run_before_test)
+ set(cmd_to_run_before_test)
+endif()
+
+get_filename_component(unittest_file_directory "${unittest_file_to_run}" DIRECTORY)
+get_filename_component(unittest_file_to_run_name "${unittest_file_to_run}" NAME_WE)
+
+set(concat_string '${unittest_file_directory}')
+foreach(s IN LISTS additional_paths)
+ if(NOT "${s}" STREQUAL "")
+ set(concat_string "${concat_string}, '${s}'")
+ endif()
+endforeach()
+
+set(unittest_to_run "runtests('${unittest_file_to_run_name}'), exit(max([ans(1,:).Failed]))")
+if(no_unittest_framework)
+ set(unittest_to_run "try, ${unittest_file_to_run_name}, catch err, disp('An exception has been thrown during the execution'), disp(err), disp(err.stack), exit(1), end, exit(0)")
+endif()
+
+set(Matlab_SCRIPT_TO_RUN
+ "addpath(${concat_string}), path, ${cmd_to_run_before_test}, ${unittest_to_run}"
+ )
+
+set(Matlab_LOG_FILE "${output_directory}/${test_name}.log")
+
+set(devnull)
+if(UNIX)
+ set(devnull INPUT_FILE /dev/null)
+elseif(WIN32)
+ set(devnull INPUT_FILE NUL)
+endif()
+
+execute_process(
+ COMMAND "${Matlab_PROGRAM}" ${Matlab_UNIT_TESTS_CMD} -logfile "${test_name}.log" -r "${Matlab_SCRIPT_TO_RUN}"
+ RESULT_VARIABLE res
+ TIMEOUT ${test_timeout}
+ OUTPUT_QUIET # we do not want the output twice
+ WORKING_DIRECTORY "${output_directory}"
+ ${devnull}
+ )
+
+if(NOT EXISTS ${Matlab_LOG_FILE})
+ message( FATAL_ERROR "[MATLAB] ERROR: cannot find the log file ${Matlab_LOG_FILE}")
+endif()
+
+# print the output in any case.
+file(READ ${Matlab_LOG_FILE} matlab_log_content)
+message("Matlab test ${name_of_the_test} output:\n${matlab_log_content}") # if we put FATAL_ERROR here, the file is indented.
+
+
+if(NOT (res EQUAL 0))
+ message( FATAL_ERROR "[MATLAB] TEST FAILED" )
+endif()
diff --git a/Modules/NSIS.template.in b/Modules/NSIS.template.in
index 76310af31..1ef3d28c7 100644
--- a/Modules/NSIS.template.in
+++ b/Modules/NSIS.template.in
@@ -542,6 +542,8 @@ FunctionEnd
; Define some macro setting for the gui
@CPACK_NSIS_INSTALLER_MUI_ICON_CODE@
@CPACK_NSIS_INSTALLER_ICON_CODE@
+@CPACK_NSIS_INSTALLER_MUI_WELCOMEFINISH_CODE@
+@CPACK_NSIS_INSTALLER_MUI_UNWELCOMEFINISH_CODE@
@CPACK_NSIS_INSTALLER_MUI_COMPONENTS_DESC@
@CPACK_NSIS_INSTALLER_MUI_FINISHPAGE_RUN_CODE@
diff --git a/Modules/Platform/AIX-GNU.cmake b/Modules/Platform/AIX-GNU.cmake
index e5d9434b5..d6f5331dd 100644
--- a/Modules/Platform/AIX-GNU.cmake
+++ b/Modules/Platform/AIX-GNU.cmake
@@ -18,10 +18,20 @@ if(__AIX_COMPILER_GNU)
endif()
set(__AIX_COMPILER_GNU 1)
+#
+# By default, runtime linking is enabled. All shared objects specified on the command line
+# will be listed, even if there are no symbols referenced, in the output file.
+set (CMAKE_SHARED_LINKER_FLAGS_INIT "-Wl,-brtl")
+set (CMAKE_MODULE_LINKER_FLAGS_INIT "-Wl,-brtl")
+set (CMAKE_EXE_LINKER_FLAGS_INIT "-Wl,-brtl")
+
+
macro(__aix_compiler_gnu lang)
set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG "-Wl,-blibpath:")
set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG_SEP ":")
set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS} -Wl,-G,-bnoipath")
- set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-Wl,-brtl,-bnoipath,-bexpall") # +s, flag for exe link to use shared lib
+ set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-Wl,-bexpall")
set(CMAKE_${lang}_USE_IMPLICIT_LINK_DIRECTORIES_IN_RUNTIME_PATH 1)
+
+ set(CMAKE_${lang}_LINK_FLAGS "-Wl,-bnoipath")
endmacro()
diff --git a/Modules/Platform/AIX-XL.cmake b/Modules/Platform/AIX-XL.cmake
index abf385569..5470441f9 100644
--- a/Modules/Platform/AIX-XL.cmake
+++ b/Modules/Platform/AIX-XL.cmake
@@ -18,11 +18,21 @@ if(__AIX_COMPILER_XL)
endif()
set(__AIX_COMPILER_XL 1)
+#
+# By default, runtime linking is enabled. All shared objects specified on the command line
+# will be listed, even if there are no symbols referenced, in the output file.
+set(CMAKE_SHARED_LINKER_FLAGS_INIT "-Wl,-brtl")
+set(CMAKE_MODULE_LINKER_FLAGS_INIT "-Wl,-brtl")
+set(CMAKE_EXE_LINKER_FLAGS_INIT "-Wl,-brtl")
+
+
macro(__aix_compiler_xl lang)
set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG "-Wl,-blibpath:")
set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG_SEP ":")
set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-G -Wl,-bnoipath") # -shared
- set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-Wl,-brtl,-bnoipath,-bexpall") # +s, flag for exe link to use shared lib
+ set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-Wl,-bexpall")
set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS " ")
set(CMAKE_SHARED_MODULE_${lang}_FLAGS " ")
+
+ set(CMAKE_${lang}_LINK_FLAGS "-Wl,-bnoipath")
endmacro()
diff --git a/Modules/Platform/ARTOS-GNU-C.cmake b/Modules/Platform/ARTOS-GNU-C.cmake
new file mode 100644
index 000000000..967d0e7c0
--- /dev/null
+++ b/Modules/Platform/ARTOS-GNU-C.cmake
@@ -0,0 +1,9 @@
+# Define ARTOS to select proper behaviour and tell preprocessor to accept C++ style comments.
+set(CMAKE_C_FLAGS_INIT "-DARTOS -Xp -+")
+# ac doesn't support -g properly and doesn't support the normal gcc optimization options. Just use the defaults set by ac.
+set(CMAKE_C_FLAGS_DEBUG_INIT "")
+set(CMAKE_C_FLAGS_MINSIZEREL_INIT "-DNDEBUG")
+set(CMAKE_C_FLAGS_RELEASE_INIT "-DNDEBUG")
+set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-DNDEBUG")
+# Most projects expect the stdio functions to be available.
+set(CMAKE_C_STANDARD_LIBRARIES_INIT "stdio.a")
diff --git a/Modules/Platform/ARTOS.cmake b/Modules/Platform/ARTOS.cmake
new file mode 100644
index 000000000..f9365d6ce
--- /dev/null
+++ b/Modules/Platform/ARTOS.cmake
@@ -0,0 +1,17 @@
+# Support for ARTOS RTOS (locamation.com)
+set(CMAKE_LINK_LIBRARY_SUFFIX "")
+set(CMAKE_STATIC_LIBRARY_PREFIX "")
+set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
+set(CMAKE_SHARED_LIBRARY_PREFIX "")
+set(CMAKE_SHARED_LIBRARY_SUFFIX ".a")
+set(CMAKE_EXECUTABLE_SUFFIX ".x")
+set(CMAKE_DL_LIBS "")
+
+set(CMAKE_FIND_LIBRARY_PREFIXES "")
+set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
+
+# ARTOS does not support shared libs
+set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
+
+set(CMAKE_C_LINK_SHARED_LIBRARY )
+set(CMAKE_C_LINK_MODULE_LIBRARY )
diff --git a/Modules/Platform/Android.cmake b/Modules/Platform/Android.cmake
new file mode 100644
index 000000000..1bdad0403
--- /dev/null
+++ b/Modules/Platform/Android.cmake
@@ -0,0 +1,15 @@
+include(Platform/Linux)
+
+# Android has soname, but binary names must end in ".so" so we cannot append
+# a version number. Also we cannot portably represent symlinks on the host.
+set(CMAKE_PLATFORM_NO_VERSIONED_SONAME 1)
+
+# Android reportedly ignores RPATH, and we cannot predict the install
+# location anyway.
+set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "")
+
+# Nsight Tegra Visual Studio Edition takes care of
+# prefixing library names with '-l'.
+if(CMAKE_VS_PLATFORM_NAME STREQUAL "Tegra-Android")
+ set(CMAKE_LINK_LIBRARY_FLAG "")
+endif()
diff --git a/Modules/Platform/BlueGeneQ-base.cmake b/Modules/Platform/BlueGeneQ-base.cmake
new file mode 100644
index 000000000..9372166e8
--- /dev/null
+++ b/Modules/Platform/BlueGeneQ-base.cmake
@@ -0,0 +1,177 @@
+
+#=============================================================================
+# Copyright 2010 Kitware, Inc.
+# Copyright 2010 Todd Gamblin <tgamblin@llnl.gov>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+#
+# Blue Gene/Q base platform file.
+#
+# NOTE: Do not set your platform to "BlueGeneQ-base". This file is
+# included by the real platform files. Use one of these two platforms
+# instead:
+#
+# BlueGeneQ-dynamic For dynamically linked executables
+# BlueGeneQ-static For statically linked executables
+#
+# The platform you choose doesn't affect whether or not you can build
+# shared or static libraries -- it ONLY changs whether exeuatbles are linked
+# statically or dynamically.
+#
+# This platform file tries its best to adhere to the behavior of the MPI
+# compiler wrappers included with the latest BG/P drivers.
+#
+
+#
+# This adds directories that find commands should specifically ignore
+# for cross compiles. Most of these directories are the includeand
+# lib directories for the frontend on BG/P systems. Not ignoring
+# these can cause things like FindX11 to find a frontend PPC version
+# mistakenly. We use this on BG instead of re-rooting because backend
+# libraries are typically strewn about the filesystem, and we can't
+# re-root ALL backend libraries to a single place.
+#
+set(CMAKE_SYSTEM_IGNORE_PATH
+ /lib /lib64 /include
+ /usr/lib /usr/lib64 /usr/include
+ /usr/local/lib /usr/local/lib64 /usr/local/include
+ /usr/X11/lib /usr/X11/lib64 /usr/X11/include
+ /usr/lib/X11 /usr/lib64/X11 /usr/include/X11
+ /usr/X11R6/lib /usr/X11R6/lib64 /usr/X11R6/include
+ /usr/X11R7/lib /usr/X11R7/lib64 /usr/X11R7/include
+)
+
+#
+# Indicate that this is a unix-like system
+#
+set(UNIX 1)
+
+#
+# Library prefixes, suffixes, extra libs.
+#
+set(CMAKE_LINK_LIBRARY_SUFFIX "")
+set(CMAKE_STATIC_LIBRARY_PREFIX "lib") # lib
+set(CMAKE_STATIC_LIBRARY_SUFFIX ".a") # .a
+
+set(CMAKE_SHARED_LIBRARY_PREFIX "lib") # lib
+set(CMAKE_SHARED_LIBRARY_SUFFIX ".so") # .so
+set(CMAKE_EXECUTABLE_SUFFIX "") # .exe
+
+set(CMAKE_DL_LIBS "dl")
+
+#
+# BG/Q supports dynamic libraries regardless of whether we're building
+# static or dynamic *executables*.
+#
+set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)
+set(CMAKE_FIND_LIBRARY_PREFIXES "lib")
+
+#
+# For BGQ builds, we're cross compiling, but we don't want to re-root things
+# (e.g. with CMAKE_FIND_ROOT_PATH) because users may have libraries anywhere on
+# the shared filesystems, and this may lie outside the root. Instead, we set the
+# system directories so that the various system BG CNK library locations are
+# searched first. This is not the clearest thing in the world, given IBM's driver
+# layout, but this should cover all the standard ones.
+#
+macro(__BlueGeneQ_common_setup compiler_id lang)
+ # Need to use the version of the comm lib compiled with the right compiler.
+ set(__BlueGeneQ_commlib_dir gcc)
+ if (${compiler_id} STREQUAL XL)
+ set(__BlueGeneQ_commlib_dir xl)
+ endif()
+
+ set(CMAKE_SYSTEM_LIBRARY_PATH
+ /bgsys/drivers/ppcfloor/comm/default/lib # default comm layer (used by mpi compiler wrappers)
+ /bgsys/drivers/ppcfloor/comm/${__BlueGeneQ_commlib_dir}/lib # PAMI, other lower-level comm libraries
+ /bgsys/drivers/ppcfloor/gnu-linux/lib # CNK python installation directory
+ /bgsys/drivers/ppcfloor/gnu-linux/powerpc64-bgq-linux/lib # CNK Linux image -- standard runtime libs, pthread, etc.
+ )
+
+ # Add all the system include paths.
+ set(CMAKE_SYSTEM_INCLUDE_PATH
+ /bgsys/drivers/ppcfloor/comm/sys/include
+ /bgsys/drivers/ppcfloor/
+ /bgsys/drivers/ppcfloor/spi/include
+ /bgsys/drivers/ppcfloor/spi/include/kernel/cnk
+ /bgsys/drivers/ppcfloor/comm/${__BlueGeneQ_commlib_dir}/include
+ )
+
+ # Ensure that the system directories are included with the regular compilers, as users will expect this
+ # to do the same thing as the MPI compilers, which add these flags.
+ set(BGQ_SYSTEM_INCLUDES "")
+ foreach(dir ${CMAKE_SYSTEM_INCLUDE_PATH})
+ set(BGQ_SYSTEM_INCLUDES "${BGQ_SYSTEM_INCLUDES} -I${dir}")
+ endforeach()
+ set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> <DEFINES> ${BGQ_SYSTEM_INCLUDES} <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
+ set(CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER> <DEFINES> ${BGQ_SYSTEM_INCLUDES} <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
+
+ #
+ # Code below does setup for shared libraries. That this is done
+ # regardless of whether the platform is static or dynamic -- you can make
+ # shared libraries even if you intend to make static executables, you just
+ # can't make a dynamic executable if you use the static platform file.
+ #
+ if (${compiler_id} STREQUAL XL)
+ # Flags for XL compilers if we explicitly detected XL
+ set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-qpic")
+ set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-qmkshrobj -qnostaticlink")
+ else()
+ # Assume flags for GNU compilers (if the ID is GNU *or* anything else).
+ set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-fPIC")
+ set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared")
+ endif()
+
+ # Both toolchains use the GNU linker on BG/P, so these options are shared.
+ set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG "-Wl,-rpath,")
+ set(CMAKE_SHARED_LIBRARY_RPATH_LINK_${lang}_FLAG "-Wl,-rpath-link,")
+ set(CMAKE_SHARED_LIBRARY_SONAME_${lang}_FLAG "-Wl,-soname,")
+ set(CMAKE_EXE_EXPORTS_${lang}_FLAG "-Wl,--export-dynamic")
+ set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "") # +s, flag for exe link to use shared lib
+ set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG_SEP ":") # : or empty
+
+endmacro()
+
+#
+# This macro needs to be called for dynamic library support. Unfortunately on BG,
+# We can't support both static and dynamic links in the same platform file. The
+# dynamic link platform file needs to call this explicitly to set up dynamic linking.
+#
+macro(__BlueGeneQ_setup_dynamic compiler_id lang)
+ __BlueGeneQ_common_setup(${compiler_id} ${lang})
+
+ if (${compiler_id} STREQUAL XL)
+ set(BGQ_${lang}_DYNAMIC_EXE_FLAGS "-qnostaticlink -qnostaticlink=libgcc")
+ else()
+ set(BGQ_${lang}_DYNAMIC_EXE_FLAGS "-dynamic")
+ endif()
+
+ # For dynamic executables, need to provide special BG/Q arguments.
+ set(BGQ_${lang}_DEFAULT_EXE_FLAGS
+ "<FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+ set(CMAKE_${lang}_LINK_EXECUTABLE
+ "<CMAKE_${lang}_COMPILER> -Wl,-relax ${BGQ_${lang}_DYNAMIC_EXE_FLAGS} ${BGQ_${lang}_DEFAULT_EXE_FLAGS}")
+endmacro()
+
+#
+# This macro needs to be called for static builds. Right now it just adds -Wl,-relax
+# to the link line.
+#
+macro(__BlueGeneQ_setup_static compiler_id lang)
+ __BlueGeneQ_common_setup(${compiler_id} ${lang})
+
+ # For static executables, use default link settings.
+ set(BGQ_${lang}_DEFAULT_EXE_FLAGS
+ "<FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+ set(CMAKE_${lang}_LINK_EXECUTABLE
+ "<CMAKE_${lang}_COMPILER> -Wl,-relax ${BGQ_${lang}_DEFAULT_EXE_FLAGS}")
+endmacro()
diff --git a/Modules/Platform/BlueGeneQ-dynamic-GNU-C.cmake b/Modules/Platform/BlueGeneQ-dynamic-GNU-C.cmake
new file mode 100644
index 000000000..102ac80ee
--- /dev/null
+++ b/Modules/Platform/BlueGeneQ-dynamic-GNU-C.cmake
@@ -0,0 +1,16 @@
+
+#=============================================================================
+# Copyright 2010 Kitware, Inc.
+# Copyright 2010 Todd Gamblin <tgamblin@llnl.gov>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+__BlueGeneQ_setup_dynamic(GNU C)
diff --git a/Modules/Platform/BlueGeneQ-dynamic-GNU-CXX.cmake b/Modules/Platform/BlueGeneQ-dynamic-GNU-CXX.cmake
new file mode 100644
index 000000000..cd8ab246f
--- /dev/null
+++ b/Modules/Platform/BlueGeneQ-dynamic-GNU-CXX.cmake
@@ -0,0 +1,16 @@
+
+#=============================================================================
+# Copyright 2010 Kitware, Inc.
+# Copyright 2010 Todd Gamblin <tgamblin@llnl.gov>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+__BlueGeneQ_setup_dynamic(GNU CXX)
diff --git a/Modules/Platform/BlueGeneQ-dynamic-GNU-Fortran.cmake b/Modules/Platform/BlueGeneQ-dynamic-GNU-Fortran.cmake
new file mode 100644
index 000000000..c029f0fb2
--- /dev/null
+++ b/Modules/Platform/BlueGeneQ-dynamic-GNU-Fortran.cmake
@@ -0,0 +1,16 @@
+
+#=============================================================================
+# Copyright 2010 Kitware, Inc.
+# Copyright 2010 Todd Gamblin <tgamblin@llnl.gov>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+__BlueGeneQ_setup_dynamic(GNU Fortran)
diff --git a/Modules/Platform/BlueGeneQ-dynamic-XL-C.cmake b/Modules/Platform/BlueGeneQ-dynamic-XL-C.cmake
new file mode 100644
index 000000000..0077313d4
--- /dev/null
+++ b/Modules/Platform/BlueGeneQ-dynamic-XL-C.cmake
@@ -0,0 +1,16 @@
+
+#=============================================================================
+# Copyright 2010 Kitware, Inc.
+# Copyright 2010 Todd Gamblin <tgamblin@llnl.gov>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+__BlueGeneQ_setup_dynamic(XL C)
diff --git a/Modules/Platform/BlueGeneQ-dynamic-XL-CXX.cmake b/Modules/Platform/BlueGeneQ-dynamic-XL-CXX.cmake
new file mode 100644
index 000000000..0f43cb256
--- /dev/null
+++ b/Modules/Platform/BlueGeneQ-dynamic-XL-CXX.cmake
@@ -0,0 +1,16 @@
+
+#=============================================================================
+# Copyright 2010 Kitware, Inc.
+# Copyright 2010 Todd Gamblin <tgamblin@llnl.gov>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+__BlueGeneQ_setup_dynamic(XL CXX)
diff --git a/Modules/Platform/BlueGeneQ-dynamic-XL-Fortran.cmake b/Modules/Platform/BlueGeneQ-dynamic-XL-Fortran.cmake
new file mode 100644
index 000000000..12e446e11
--- /dev/null
+++ b/Modules/Platform/BlueGeneQ-dynamic-XL-Fortran.cmake
@@ -0,0 +1,16 @@
+
+#=============================================================================
+# Copyright 2010 Kitware, Inc.
+# Copyright 2010 Todd Gamblin <tgamblin@llnl.gov>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+__BlueGeneQ_setup_dynamic(XL Fortran)
diff --git a/Modules/Platform/BlueGeneQ-dynamic.cmake b/Modules/Platform/BlueGeneQ-dynamic.cmake
new file mode 100644
index 000000000..02839003f
--- /dev/null
+++ b/Modules/Platform/BlueGeneQ-dynamic.cmake
@@ -0,0 +1,17 @@
+
+#=============================================================================
+# Copyright 2010 Kitware, Inc.
+# Copyright 2010 Todd Gamblin <tgamblin@llnl.gov>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+include(Platform/BlueGeneQ-base)
+set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a")
diff --git a/Modules/Platform/BlueGeneQ-static-GNU-C.cmake b/Modules/Platform/BlueGeneQ-static-GNU-C.cmake
new file mode 100644
index 000000000..70c84bace
--- /dev/null
+++ b/Modules/Platform/BlueGeneQ-static-GNU-C.cmake
@@ -0,0 +1,16 @@
+
+#=============================================================================
+# Copyright 2010 Kitware, Inc.
+# Copyright 2010 Todd Gamblin <tgamblin@llnl.gov>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+__BlueGeneQ_setup_static(GNU C)
diff --git a/Modules/Platform/BlueGeneQ-static-GNU-CXX.cmake b/Modules/Platform/BlueGeneQ-static-GNU-CXX.cmake
new file mode 100644
index 000000000..8f991de11
--- /dev/null
+++ b/Modules/Platform/BlueGeneQ-static-GNU-CXX.cmake
@@ -0,0 +1,16 @@
+
+#=============================================================================
+# Copyright 2010 Kitware, Inc.
+# Copyright 2010 Todd Gamblin <tgamblin@llnl.gov>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+__BlueGeneQ_setup_static(GNU CXX)
diff --git a/Modules/Platform/BlueGeneQ-static-GNU-Fortran.cmake b/Modules/Platform/BlueGeneQ-static-GNU-Fortran.cmake
new file mode 100644
index 000000000..24dd9e755
--- /dev/null
+++ b/Modules/Platform/BlueGeneQ-static-GNU-Fortran.cmake
@@ -0,0 +1,16 @@
+
+#=============================================================================
+# Copyright 2010 Kitware, Inc.
+# Copyright 2010 Todd Gamblin <tgamblin@llnl.gov>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+__BlueGeneQ_setup_static(GNU Fortran)
diff --git a/Modules/Platform/BlueGeneQ-static-XL-C.cmake b/Modules/Platform/BlueGeneQ-static-XL-C.cmake
new file mode 100644
index 000000000..5555a6875
--- /dev/null
+++ b/Modules/Platform/BlueGeneQ-static-XL-C.cmake
@@ -0,0 +1,16 @@
+
+#=============================================================================
+# Copyright 2010 Kitware, Inc.
+# Copyright 2010 Todd Gamblin <tgamblin@llnl.gov>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+__BlueGeneQ_setup_static(XL C)
diff --git a/Modules/Platform/BlueGeneQ-static-XL-CXX.cmake b/Modules/Platform/BlueGeneQ-static-XL-CXX.cmake
new file mode 100644
index 000000000..07c3c3d11
--- /dev/null
+++ b/Modules/Platform/BlueGeneQ-static-XL-CXX.cmake
@@ -0,0 +1,16 @@
+
+#=============================================================================
+# Copyright 2010 Kitware, Inc.
+# Copyright 2010 Todd Gamblin <tgamblin@llnl.gov>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+__BlueGeneQ_setup_static(XL CXX)
diff --git a/Modules/Platform/BlueGeneQ-static-XL-Fortran.cmake b/Modules/Platform/BlueGeneQ-static-XL-Fortran.cmake
new file mode 100644
index 000000000..6f99933cb
--- /dev/null
+++ b/Modules/Platform/BlueGeneQ-static-XL-Fortran.cmake
@@ -0,0 +1,16 @@
+
+#=============================================================================
+# Copyright 2010 Kitware, Inc.
+# Copyright 2010 Todd Gamblin <tgamblin@llnl.gov>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+__BlueGeneQ_setup_static(XL Fortran)
diff --git a/Modules/Platform/BlueGeneQ-static.cmake b/Modules/Platform/BlueGeneQ-static.cmake
new file mode 100644
index 000000000..30b530d89
--- /dev/null
+++ b/Modules/Platform/BlueGeneQ-static.cmake
@@ -0,0 +1,17 @@
+
+#=============================================================================
+# Copyright 2010 Kitware, Inc.
+# Copyright 2010 Todd Gamblin <tgamblin@llnl.gov>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+include(Platform/BlueGeneQ-base)
+set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
diff --git a/Modules/Platform/CYGWIN-GNU.cmake b/Modules/Platform/CYGWIN-GNU.cmake
index fe25ab214..1a46c1031 100644
--- a/Modules/Platform/CYGWIN-GNU.cmake
+++ b/Modules/Platform/CYGWIN-GNU.cmake
@@ -25,7 +25,6 @@ set(CMAKE_CREATE_WIN32_EXE "-mwindows")
set(CMAKE_GNULD_IMAGE_VERSION
"-Wl,--major-image-version,<TARGET_VERSION_MAJOR>,--minor-image-version,<TARGET_VERSION_MINOR>")
set(CMAKE_GENERATOR_RC windres)
-enable_language(RC)
macro(__cygwin_compiler_gnu lang)
# Binary link rules.
set(CMAKE_${lang}_CREATE_SHARED_MODULE
@@ -53,4 +52,10 @@ macro(__cygwin_compiler_gnu lang)
# TODO: Is -Wl,--enable-auto-import now always default?
set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS} -Wl,--enable-auto-import")
set(CMAKE_SHARED_MODULE_CREATE_${lang}_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS}")
+
+ if(NOT CMAKE_RC_COMPILER_INIT)
+ set(CMAKE_RC_COMPILER_INIT windres)
+ endif()
+
+ enable_language(RC)
endmacro()
diff --git a/Modules/Platform/CYGWIN-windres.cmake b/Modules/Platform/CYGWIN-windres.cmake
index 01d6be3df..7d787dddf 100644
--- a/Modules/Platform/CYGWIN-windres.cmake
+++ b/Modules/Platform/CYGWIN-windres.cmake
@@ -1 +1 @@
-set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> -O coff <FLAGS> <DEFINES> <SOURCE> <OBJECT>")
+set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> -O coff <DEFINES> <INCLUDES> <FLAGS> <SOURCE> <OBJECT>")
diff --git a/Modules/Platform/CrayLinuxEnvironment.cmake b/Modules/Platform/CrayLinuxEnvironment.cmake
new file mode 100644
index 000000000..97771a268
--- /dev/null
+++ b/Modules/Platform/CrayLinuxEnvironment.cmake
@@ -0,0 +1,143 @@
+# Compute Node Linux doesn't quite work the same as native Linux so all of this
+# needs to be custom. We use the variables defined through Cray's environment
+# modules to set up the right paths for things.
+
+set(UNIX 1)
+
+if(DEFINED ENV{CRAYOS_VERSION})
+ set(CMAKE_SYSTEM_VERSION "$ENV{CRAYOS_VERSION}")
+elseif(DEFINED ENV{XTOS_VERSION})
+ set(CMAKE_SYSTEM_VERSION "$ENV{XTOS_VERSION}")
+else()
+ message(FATAL_ERROR "Neither the CRAYOS_VERSION or XTOS_VERSION environment variables are defined. This platform file should be used inside the Cray Linux Environment for targeting compute nodes (NIDs)")
+endif()
+
+# Guard against multiple messages
+if(NOT __CrayLinuxEnvironment_message)
+ set(__CrayLinuxEnvironment_message 1)
+ message(STATUS "Cray Linux Environment ${CMAKE_SYSTEM_VERSION}")
+endif()
+
+# All cray systems are x86 CPUs and have been for quite some time
+# Note: this may need to change in the future with 64-bit ARM
+set(CMAKE_SYSTEM_PROCESSOR "x86_64")
+
+set(CMAKE_SHARED_LIBRARY_PREFIX "lib")
+set(CMAKE_SHARED_LIBRARY_SUFFIX ".so")
+set(CMAKE_STATIC_LIBRARY_PREFIX "lib")
+set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
+
+set(CMAKE_FIND_LIBRARY_PREFIXES "lib")
+
+# Don't override shared lib support if it's already been set and possibly
+# overridden elsewhere by the CrayPrgEnv module
+if(NOT CMAKE_FIND_LIBRARY_SUFFIXES)
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a")
+ set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)
+endif()
+
+set(CMAKE_DL_LIBS dl)
+
+# Note: Much of this is pulled from UnixPaths.cmake but adjusted to the Cray
+# environment accordingly
+
+# Get the install directory of the running cmake to the search directories
+# CMAKE_ROOT is CMAKE_INSTALL_PREFIX/share/cmake, so we need to go two levels up
+get_filename_component(__cmake_install_dir "${CMAKE_ROOT}" PATH)
+get_filename_component(__cmake_install_dir "${__cmake_install_dir}" PATH)
+
+# Note: Some Cray's have the SYSROOT_DIR variable defined, pointing to a copy
+# of the NIDs userland. If so, then we'll use it. Otherwise, just assume
+# the userland from the login node is ok
+
+# List common installation prefixes. These will be used for all
+# search types.
+list(APPEND CMAKE_SYSTEM_PREFIX_PATH
+ # Standard
+ $ENV{SYSROOT_DIR}/usr/local $ENV{SYSROOT_DIR}/usr $ENV{SYSROOT_DIR}/
+
+ # CMake install location
+ "${__cmake_install_dir}"
+ )
+if (NOT CMAKE_FIND_NO_INSTALL_PREFIX)
+ list(APPEND CMAKE_SYSTEM_PREFIX_PATH
+ # Project install destination.
+ "${CMAKE_INSTALL_PREFIX}"
+ )
+ if(CMAKE_STAGING_PREFIX)
+ list(APPEND CMAKE_SYSTEM_PREFIX_PATH
+ # User-supplied staging prefix.
+ "${CMAKE_STAGING_PREFIX}"
+ )
+ endif()
+endif()
+
+list(APPEND CMAKE_SYSTEM_INCLUDE_PATH
+ $ENV{SYSROOT_DIR}/usr/include
+ $ENV{SYSROOT_DIR}/usr/include/X11
+)
+list(APPEND CMAKE_SYSTEM_LIBRARY_PATH
+ $ENV{SYSROOT_DIR}/usr/local/lib64
+ $ENV{SYSROOT_DIR}/usr/lib64
+ $ENV{SYSROOT_DIR}/lib64
+)
+list(APPEND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES
+ $ENV{SYSROOT_DIR}/usr/local/lib64
+ $ENV{SYSROOT_DIR}/usr/lib64
+ $ENV{SYSROOT_DIR}/lib64
+)
+
+# Compute the intersection of several lists
+function(__cray_list_intersect OUTPUT INPUT0)
+ if(ARGC EQUAL 2)
+ list(APPEND ${OUTPUT} ${${INPUT0}})
+ else()
+ foreach(I IN LISTS ${INPUT0})
+ set(__is_common 1)
+ foreach(L IN LISTS ARGN)
+ list(FIND ${L} "${I}" __idx)
+ if(__idx EQUAL -1)
+ set(__is_common 0)
+ break()
+ endif()
+ endforeach()
+ if(__is_common)
+ list(APPEND ${OUTPUT} "${I}")
+ endif()
+ endforeach()
+ endif()
+ set(${OUTPUT} ${${OUTPUT}} PARENT_SCOPE)
+endfunction()
+
+macro(__list_clean_dupes var)
+ if(${var})
+ list(REMOVE_DUPLICATES ${var})
+ endif()
+endmacro()
+
+get_property(__langs GLOBAL PROPERTY ENABLED_LANGUAGES)
+set(__cray_inc_path_vars)
+set(__cray_lib_path_vars)
+foreach(__lang IN LISTS __langs)
+ list(APPEND __cray_inc_path_vars CMAKE_${__lang}_IMPLICIT_INCLUDE_DIRECTORIES)
+ list(APPEND __cray_lib_path_vars CMAKE_${__lang}_IMPLICIT_LINK_DIRECTORIES)
+endforeach()
+if(__cray_inc_path_vars)
+ __cray_list_intersect(__cray_implicit_include_dirs ${__cray_inc_path_vars})
+ if(__cray_implicit_include_dirs)
+ list(INSERT CMAKE_SYSTEM_INCLUDE_PATH 0 ${__cray_implicit_include_dirs})
+ endif()
+endif()
+if(__cray_lib_path_vars)
+ __cray_list_intersect(__cray_implicit_library_dirs ${__cray_lib_path_vars})
+ if(__cray_implicit_library_dirs)
+ list(INSERT CMAKE_SYSTEM_LIBRARY_PATH 0 ${__cray_implicit_library_dirs})
+ endif()
+endif()
+__list_clean_dupes(CMAKE_SYSTEM_PREFIX_PATH)
+__list_clean_dupes(CMAKE_SYSTEM_INCLUDE_PATH)
+__list_clean_dupes(CMAKE_SYSTEM_LIBRARY_PATH)
+__list_clean_dupes(CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES)
+
+# Enable use of lib64 search path variants by default.
+set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS TRUE)
diff --git a/Modules/Platform/Darwin-AppleClang-C.cmake b/Modules/Platform/Darwin-AppleClang-C.cmake
new file mode 100644
index 000000000..3216b2909
--- /dev/null
+++ b/Modules/Platform/Darwin-AppleClang-C.cmake
@@ -0,0 +1,6 @@
+include(Platform/Darwin-Clang-C)
+if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.2)
+ set(CMAKE_C_SYSTEM_FRAMEWORK_SEARCH_FLAG "-iframework ")
+else()
+ unset(CMAKE_C_SYSTEM_FRAMEWORK_SEARCH_FLAG)
+endif()
diff --git a/Modules/Platform/Darwin-AppleClang-CXX.cmake b/Modules/Platform/Darwin-AppleClang-CXX.cmake
new file mode 100644
index 000000000..3fedf8c07
--- /dev/null
+++ b/Modules/Platform/Darwin-AppleClang-CXX.cmake
@@ -0,0 +1,6 @@
+include(Platform/Darwin-Clang-CXX)
+if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.2)
+ set(CMAKE_CXX_SYSTEM_FRAMEWORK_SEARCH_FLAG "-iframework ")
+else()
+ unset(CMAKE_CXX_SYSTEM_FRAMEWORK_SEARCH_FLAG)
+endif()
diff --git a/Modules/Platform/Darwin-Clang.cmake b/Modules/Platform/Darwin-Clang.cmake
index 528873cfd..4cded47a1 100644
--- a/Modules/Platform/Darwin-Clang.cmake
+++ b/Modules/Platform/Darwin-Clang.cmake
@@ -24,4 +24,7 @@ macro(__darwin_compiler_clang lang)
set(CMAKE_SHARED_MODULE_CREATE_${lang}_FLAGS "-bundle -Wl,-headerpad_max_install_names")
set(CMAKE_${lang}_SYSROOT_FLAG "-isysroot")
set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG "-mmacosx-version-min=")
+ if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.1)
+ set(CMAKE_${lang}_SYSTEM_FRAMEWORK_SEARCH_FLAG "-iframework ")
+ endif()
endmacro()
diff --git a/Modules/Platform/Darwin-GNU-Fortran.cmake b/Modules/Platform/Darwin-GNU-Fortran.cmake
index f4b509a13..6724f9bc1 100644
--- a/Modules/Platform/Darwin-GNU-Fortran.cmake
+++ b/Modules/Platform/Darwin-GNU-Fortran.cmake
@@ -14,6 +14,8 @@
include(Platform/Darwin-GNU)
__darwin_compiler_gnu(Fortran)
+cmake_gnu_set_sysroot_flag(Fortran)
+cmake_gnu_set_osx_deployment_target_flag(Fortran)
set(CMAKE_Fortran_OSX_COMPATIBILITY_VERSION_FLAG "-compatibility_version ")
set(CMAKE_Fortran_OSX_CURRENT_VERSION_FLAG "-current_version ")
diff --git a/Modules/Platform/Darwin-GNU.cmake b/Modules/Platform/Darwin-GNU.cmake
index 5fee7e3ae..87d1d2394 100644
--- a/Modules/Platform/Darwin-GNU.cmake
+++ b/Modules/Platform/Darwin-GNU.cmake
@@ -23,6 +23,10 @@ macro(__darwin_compiler_gnu lang)
# GNU does not have -shared on OS X
set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-dynamiclib -Wl,-headerpad_max_install_names")
set(CMAKE_SHARED_MODULE_CREATE_${lang}_FLAGS "-bundle -Wl,-headerpad_max_install_names")
+
+ if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 4.3)
+ set(CMAKE_${lang}_SYSTEM_FRAMEWORK_SEARCH_FLAG "-iframework ")
+ endif()
endmacro()
macro(cmake_gnu_set_sysroot_flag lang)
diff --git a/Modules/Platform/Darwin-Initialize.cmake b/Modules/Platform/Darwin-Initialize.cmake
new file mode 100644
index 000000000..a08411bcc
--- /dev/null
+++ b/Modules/Platform/Darwin-Initialize.cmake
@@ -0,0 +1,155 @@
+# Ask xcode-select where to find /Developer or fall back to ancient location.
+execute_process(COMMAND xcode-select -print-path
+ OUTPUT_VARIABLE _stdout
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_VARIABLE _stderr
+ RESULT_VARIABLE _failed)
+if(NOT _failed AND IS_DIRECTORY ${_stdout})
+ set(OSX_DEVELOPER_ROOT ${_stdout})
+elseif(IS_DIRECTORY "/Developer")
+ set(OSX_DEVELOPER_ROOT "/Developer")
+else()
+ set(OSX_DEVELOPER_ROOT "")
+endif()
+
+execute_process(COMMAND sw_vers -productVersion
+ OUTPUT_VARIABLE CURRENT_OSX_VERSION
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+# Save CMAKE_OSX_ARCHITECTURES from the environment.
+set(CMAKE_OSX_ARCHITECTURES "$ENV{CMAKE_OSX_ARCHITECTURES}" CACHE STRING
+ "Build architectures for OSX")
+
+#----------------------------------------------------------------------------
+# _CURRENT_OSX_VERSION - as a two-component string: 10.5, 10.6, ...
+#
+string(REGEX REPLACE "^([0-9]+\\.[0-9]+).*$" "\\1"
+ _CURRENT_OSX_VERSION "${CURRENT_OSX_VERSION}")
+
+#----------------------------------------------------------------------------
+# CMAKE_OSX_DEPLOYMENT_TARGET
+
+# Set cache variable - end user may change this during ccmake or cmake-gui configure.
+if(_CURRENT_OSX_VERSION VERSION_GREATER 10.3)
+ set(CMAKE_OSX_DEPLOYMENT_TARGET "$ENV{MACOSX_DEPLOYMENT_TARGET}" CACHE STRING
+ "Minimum OS X version to target for deployment (at runtime); newer APIs weak linked. Set to empty string for default value.")
+endif()
+
+#----------------------------------------------------------------------------
+# CMAKE_OSX_SYSROOT
+
+if(CMAKE_OSX_SYSROOT)
+ # Use the existing value without further computation to choose a default.
+ set(_CMAKE_OSX_SYSROOT_DEFAULT "${CMAKE_OSX_SYSROOT}")
+elseif(NOT "x$ENV{SDKROOT}" STREQUAL "x" AND
+ (NOT "x$ENV{SDKROOT}" MATCHES "/" OR IS_DIRECTORY "$ENV{SDKROOT}"))
+ # Use the value of SDKROOT from the environment.
+ set(_CMAKE_OSX_SYSROOT_DEFAULT "$ENV{SDKROOT}")
+elseif("${CMAKE_GENERATOR}" MATCHES Xcode
+ OR CMAKE_OSX_DEPLOYMENT_TARGET
+ OR CMAKE_OSX_ARCHITECTURES MATCHES "[^;]"
+ OR NOT EXISTS "/usr/include/sys/types.h")
+ # Find installed SDKs in either Xcode-4.3+ or pre-4.3 SDKs directory.
+ set(_CMAKE_OSX_SDKS_DIR "")
+ if(OSX_DEVELOPER_ROOT)
+ foreach(d Platforms/MacOSX.platform/Developer/SDKs SDKs)
+ file(GLOB _CMAKE_OSX_SDKS ${OSX_DEVELOPER_ROOT}/${d}/*)
+ if(_CMAKE_OSX_SDKS)
+ set(_CMAKE_OSX_SDKS_DIR ${OSX_DEVELOPER_ROOT}/${d})
+ break()
+ endif()
+ endforeach()
+ endif()
+
+ if(_CMAKE_OSX_SDKS_DIR)
+ # Select SDK for current OSX version accounting for the known
+ # specially named SDKs.
+ set(_CMAKE_OSX_SDKS_VER_SUFFIX_10.4 "u")
+ set(_CMAKE_OSX_SDKS_VER_SUFFIX_10.3 ".9")
+
+ # find the latest SDK
+ set(_CMAKE_OSX_LATEST_SDK_VERSION "0.0")
+ file(GLOB _CMAKE_OSX_SDKS RELATIVE "${_CMAKE_OSX_SDKS_DIR}" "${_CMAKE_OSX_SDKS_DIR}/MacOSX*.sdk")
+ foreach(_SDK ${_CMAKE_OSX_SDKS})
+ if(_SDK MATCHES "MacOSX([0-9]+\\.[0-9]+)[^/]*\\.sdk" AND CMAKE_MATCH_1 VERSION_GREATER ${_CMAKE_OSX_LATEST_SDK_VERSION})
+ set(_CMAKE_OSX_LATEST_SDK_VERSION "${CMAKE_MATCH_1}")
+ endif()
+ endforeach()
+
+ # pick an SDK that works
+ set(_CMAKE_OSX_SYSROOT_DEFAULT)
+ foreach(ver ${CMAKE_OSX_DEPLOYMENT_TARGET}
+ ${_CURRENT_OSX_VERSION}
+ ${_CMAKE_OSX_LATEST_SDK_VERSION})
+ set(_CMAKE_OSX_DEPLOYMENT_TARGET ${ver})
+ set(_CMAKE_OSX_SDKS_VER ${_CMAKE_OSX_DEPLOYMENT_TARGET}${_CMAKE_OSX_SDKS_VER_SUFFIX_${_CMAKE_OSX_DEPLOYMENT_TARGET}})
+ set(_CMAKE_OSX_SYSROOT_CHECK "${_CMAKE_OSX_SDKS_DIR}/MacOSX${_CMAKE_OSX_SDKS_VER}.sdk")
+ if(IS_DIRECTORY "${_CMAKE_OSX_SYSROOT_CHECK}")
+ set(_CMAKE_OSX_SYSROOT_DEFAULT "${_CMAKE_OSX_SYSROOT_CHECK}")
+ break()
+ endif()
+ endforeach()
+
+ if(CMAKE_OSX_DEPLOYMENT_TARGET AND
+ NOT CMAKE_OSX_DEPLOYMENT_TARGET VERSION_EQUAL ${_CMAKE_OSX_DEPLOYMENT_TARGET})
+ set(_CMAKE_OSX_SDKS_VER ${CMAKE_OSX_DEPLOYMENT_TARGET}${_CMAKE_OSX_SDKS_VER_SUFFIX_${CMAKE_OSX_DEPLOYMENT_TARGET}})
+ set(_CMAKE_OSX_SYSROOT_CHECK "${_CMAKE_OSX_SDKS_DIR}/MacOSX${_CMAKE_OSX_SDKS_VER}.sdk")
+ message(WARNING
+ "CMAKE_OSX_DEPLOYMENT_TARGET is '${CMAKE_OSX_DEPLOYMENT_TARGET}' "
+ "but the matching SDK does not exist at:\n \"${_CMAKE_OSX_SYSROOT_CHECK}\"\n"
+ "Instead using SDK:\n \"${_CMAKE_OSX_SYSROOT_DEFAULT}\"."
+ )
+ endif()
+ if(NOT CMAKE_OSX_DEPLOYMENT_TARGET AND _CURRENT_OSX_VERSION VERSION_LESS _CMAKE_OSX_DEPLOYMENT_TARGET)
+ set(CMAKE_OSX_DEPLOYMENT_TARGET ${_CURRENT_OSX_VERSION} CACHE STRING
+ "Minimum OS X version to target for deployment (at runtime); newer APIs weak linked. Set to empty string for default value." FORCE)
+ endif()
+ else()
+ # Assume developer files are in root (such as Xcode 4.5 command-line tools).
+ set(_CMAKE_OSX_SYSROOT_DEFAULT "")
+ endif()
+endif()
+
+# Set cache variable - end user may change this during ccmake or cmake-gui configure.
+# Choose the type based on the current value.
+set(_CMAKE_OSX_SYSROOT_TYPE STRING)
+foreach(v CMAKE_OSX_SYSROOT _CMAKE_OSX_SYSROOT_DEFAULT)
+ if("x${${v}}" MATCHES "/")
+ set(_CMAKE_OSX_SYSROOT_TYPE PATH)
+ break()
+ endif()
+endforeach()
+set(CMAKE_OSX_SYSROOT "${_CMAKE_OSX_SYSROOT_DEFAULT}" CACHE ${_CMAKE_OSX_SYSROOT_TYPE}
+ "The product will be built against the headers and libraries located inside the indicated SDK.")
+
+# Transform the cached value to something we can use.
+set(_CMAKE_OSX_SYSROOT_ORIG "${CMAKE_OSX_SYSROOT}")
+set(_CMAKE_OSX_SYSROOT_PATH "")
+if(CMAKE_OSX_SYSROOT)
+ if("x${CMAKE_OSX_SYSROOT}" MATCHES "/")
+ # This is a path to the SDK. Make sure it exists.
+ if(NOT IS_DIRECTORY "${CMAKE_OSX_SYSROOT}")
+ message(WARNING "Ignoring CMAKE_OSX_SYSROOT value:\n ${CMAKE_OSX_SYSROOT}\n"
+ "because the directory does not exist.")
+ set(CMAKE_OSX_SYSROOT "")
+ set(_CMAKE_OSX_SYSROOT_ORIG "")
+ endif()
+ set(_CMAKE_OSX_SYSROOT_PATH "${CMAKE_OSX_SYSROOT}")
+ else()
+ # Transform the sdk name into a path.
+ execute_process(
+ COMMAND xcodebuild -sdk ${CMAKE_OSX_SYSROOT} -version Path
+ OUTPUT_VARIABLE _stdout
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_VARIABLE _stderr
+ RESULT_VARIABLE _failed
+ )
+ if(NOT _failed AND IS_DIRECTORY "${_stdout}")
+ set(_CMAKE_OSX_SYSROOT_PATH "${_stdout}")
+ # For non-Xcode generators use the path.
+ if(NOT "${CMAKE_GENERATOR}" MATCHES "Xcode")
+ set(CMAKE_OSX_SYSROOT "${_CMAKE_OSX_SYSROOT_PATH}")
+ endif()
+ endif()
+ endif()
+endif()
diff --git a/Modules/Platform/Darwin-Intel-C.cmake b/Modules/Platform/Darwin-Intel-C.cmake
new file mode 100644
index 000000000..81c630f4a
--- /dev/null
+++ b/Modules/Platform/Darwin-Intel-C.cmake
@@ -0,0 +1,2 @@
+include(Platform/Darwin-Intel)
+__darwin_compiler_intel(C)
diff --git a/Modules/Platform/Darwin-Intel-CXX.cmake b/Modules/Platform/Darwin-Intel-CXX.cmake
new file mode 100644
index 000000000..90ae53be3
--- /dev/null
+++ b/Modules/Platform/Darwin-Intel-CXX.cmake
@@ -0,0 +1,2 @@
+include(Platform/Darwin-Intel)
+__darwin_compiler_intel(CXX)
diff --git a/Modules/Platform/Darwin-Intel-Fortran.cmake b/Modules/Platform/Darwin-Intel-Fortran.cmake
index 6bd45f15c..a604bb69f 100644
--- a/Modules/Platform/Darwin-Intel-Fortran.cmake
+++ b/Modules/Platform/Darwin-Intel-Fortran.cmake
@@ -11,5 +11,8 @@
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
+include(Platform/Darwin-Intel)
+__darwin_compiler_intel(Fortran)
+
set(CMAKE_Fortran_OSX_COMPATIBILITY_VERSION_FLAG "-compatibility_version ")
set(CMAKE_Fortran_OSX_CURRENT_VERSION_FLAG "-current_version ")
diff --git a/Modules/Platform/Darwin-Intel.cmake b/Modules/Platform/Darwin-Intel.cmake
new file mode 100644
index 000000000..42f115412
--- /dev/null
+++ b/Modules/Platform/Darwin-Intel.cmake
@@ -0,0 +1,29 @@
+
+#=============================================================================
+# Copyright 2002-2014 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# This module is shared by multiple languages; use include blocker.
+if(__DARWIN_COMPILER_INTEL)
+ return()
+endif()
+set(__DARWIN_COMPILER_INTEL 1)
+
+macro(__darwin_compiler_intel lang)
+ set(CMAKE_${lang}_VERBOSE_FLAG "-v -Wl,-v") # also tell linker to print verbose output
+ set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-dynamiclib -Wl,-headerpad_max_install_names")
+ set(CMAKE_SHARED_MODULE_CREATE_${lang}_FLAGS "-bundle -Wl,-headerpad_max_install_names")
+
+ if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 12.0)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY "-fvisibility=")
+ endif()
+endmacro()
diff --git a/Modules/Platform/Darwin-NAG-Fortran.cmake b/Modules/Platform/Darwin-NAG-Fortran.cmake
index 4c28e625c..e3ac9b51f 100644
--- a/Modules/Platform/Darwin-NAG-Fortran.cmake
+++ b/Modules/Platform/Darwin-NAG-Fortran.cmake
@@ -16,7 +16,7 @@ set(CMAKE_Fortran_VERBOSE_FLAG "-Wl,-v") # Runs gcc under the hood.
# Need -fpp explicitly on case-insensitive filesystem.
set(CMAKE_Fortran_COMPILE_OBJECT
- "<CMAKE_Fortran_COMPILER> -fpp -o <OBJECT> <DEFINES> <FLAGS> -c <SOURCE>")
+ "<CMAKE_Fortran_COMPILER> -fpp -o <OBJECT> <DEFINES> <INCLUDES> <FLAGS> -c <SOURCE>")
set(CMAKE_Fortran_OSX_COMPATIBILITY_VERSION_FLAG "-Wl,-compatibility_version -Wl,")
set(CMAKE_Fortran_OSX_CURRENT_VERSION_FLAG "-Wl,-current_version -Wl,")
diff --git a/Modules/Platform/Darwin-icc.cmake b/Modules/Platform/Darwin-icc.cmake
deleted file mode 100644
index 6a46f8e02..000000000
--- a/Modules/Platform/Darwin-icc.cmake
+++ /dev/null
@@ -1,131 +0,0 @@
-set(CMAKE_C_CREATE_SHARED_LIBRARY_FORBIDDEN_FLAGS "" )
-set(CMAKE_CXX_CREATE_SHARED_LIBRARY_FORBIDDEN_FLAGS "")
-
-# Setup for Leopard Compatibility
-exec_program(sw_vers ARGS -productVersion OUTPUT_VARIABLE _OSX_VERSION)
-# message (STATUS "_OSX_VERSION: ${_OSX_VERSION}")
-if ( _OSX_VERSION MATCHES "^10.4" )
- #if(CMAKE_COMPILER_IS_GNUCC)
- set (CMAKE_C_FLAGS_INIT "")
- set (CMAKE_C_FLAGS_DEBUG_INIT "-gdwarf-2")
- set (CMAKE_C_FLAGS_MINSIZEREL_INIT "-Os -DNDEBUG")
- set (CMAKE_C_FLAGS_RELEASE_INIT "-O3 -DNDEBUG")
- set (CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-O2 -gdwarf-2")
- set (CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
- set (CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
- # endif()
-
-# if(CMAKE_COMPILER_IS_GNUCXX)
- set (CMAKE_CXX_FLAGS_INIT "")
- set (CMAKE_CXX_FLAGS_DEBUG_INIT "-gdwarf-2")
- set (CMAKE_CXX_FLAGS_MINSIZEREL_INIT "-Os -DNDEBUG")
- set (CMAKE_CXX_FLAGS_RELEASE_INIT "-O3 -DNDEBUG")
- set (CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-O2 -gdwarf-2")
- set (CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
- set (CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
-# endif()
-endif ()
-
-
-set(CMAKE_SHARED_LIBRARY_PREFIX "lib")
-set(CMAKE_SHARED_LIBRARY_SUFFIX ".dylib")
-set(CMAKE_SHARED_MODULE_PREFIX "lib")
-set(CMAKE_SHARED_MODULE_SUFFIX ".so")
-set(CMAKE_MODULE_EXISTS 1)
-set(CMAKE_DL_LIBS "")
-set(CMAKE_C_LINK_FLAGS "-Wl,-headerpad_max_install_names")
-set(CMAKE_CXX_LINK_FLAGS "-Wl,-headerpad_max_install_names")
-set(CMAKE_PLATFORM_HAS_INSTALLNAME 1)
-set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-dynamiclib -Wl,-headerpad_max_install_names")
-set(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "-bundle -Wl,-headerpad_max_install_names")
-set(CMAKE_FIND_LIBRARY_SUFFIXES ".dylib" ".so" ".a")
-
-
-# setup for universal binaries if sysroot exists
-if(EXISTS /Developer/SDKs/MacOSX10.4u.sdk)
- # set the sysroot to be used if CMAKE_OSX_ARCHITECTURES
- # has more than one value
- set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.4u.sdk CACHE STRING
- "isysroot used for universal binary support")
- # set _CMAKE_OSX_MACHINE to umame -m
- exec_program(uname ARGS -m OUTPUT_VARIABLE _CMAKE_OSX_MACHINE)
-
- # check for environment variable CMAKE_OSX_ARCHITECTURES
- # if it is set.
- if(NOT "$ENV{CMAKE_OSX_ARCHITECTURES}" STREQUAL "")
- set(_CMAKE_OSX_MACHINE "$ENV{CMAKE_OSX_ARCHITECTURES}")
- endif()
- # now put _CMAKE_OSX_MACHINE into the cache
- set(CMAKE_OSX_ARCHITECTURES ${_CMAKE_OSX_MACHINE}
- CACHE STRING "Build architectures for OSX")
-endif()
-
-
-if("${CMAKE_BACKWARDS_COMPATIBILITY}" MATCHES "^1\\.[0-6]$")
- set(CMAKE_SHARED_MODULE_CREATE_C_FLAGS
- "${CMAKE_SHARED_MODULE_CREATE_C_FLAGS} -flat_namespace -undefined suppress")
-endif()
-
-if(NOT XCODE)
- # Enable shared library versioning. This flag is not actually referenced
- # but the fact that the setting exists will cause the generators to support
- # soname computation.
- set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-install_name")
- set(CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG "-install_name")
- set(CMAKE_SHARED_LIBRARY_SONAME_Fortran_FLAG "-install_name")
-endif()
-
-# Xcode does not support -isystem yet.
-if(XCODE)
- set(CMAKE_INCLUDE_SYSTEM_FLAG_C)
- set(CMAKE_INCLUDE_SYSTEM_FLAG_CXX)
-endif()
-
-set(CMAKE_MacOSX_Content_COMPILE_OBJECT "\"${CMAKE_COMMAND}\" -E copy_if_different <SOURCE> <OBJECT>")
-
-set(CMAKE_C_CREATE_SHARED_LIBRARY
- "<CMAKE_C_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS> <LINK_FLAGS> -o <TARGET> <SONAME_FLAG> <TARGET_INSTALLNAME_DIR><TARGET_SONAME> <OBJECTS> <LINK_LIBRARIES>")
-set(CMAKE_CXX_CREATE_SHARED_LIBRARY
- "<CMAKE_CXX_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <LINK_FLAGS> -o <TARGET> <SONAME_FLAG> <TARGET_INSTALLNAME_DIR><TARGET_SONAME> <OBJECTS> <LINK_LIBRARIES>")
-set(CMAKE_Fortran_CREATE_SHARED_LIBRARY
- "<CMAKE_Fortran_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS> <LINK_FLAGS> -o <TARGET> <SONAME_FLAG> <TARGET_INSTALLNAME_DIR><TARGET_SONAME> <OBJECTS> <LINK_LIBRARIES>")
-
-set(CMAKE_CXX_CREATE_SHARED_MODULE
- "<CMAKE_CXX_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS> <LINK_FLAGS> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
-
-set(CMAKE_C_CREATE_SHARED_MODULE
- "<CMAKE_C_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_MODULE_CREATE_C_FLAGS> <LINK_FLAGS> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
-
-set(CMAKE_Fortran_CREATE_SHARED_MODULE
- "<CMAKE_Fortran_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_MODULE_CREATE_Fortran_FLAGS> <LINK_FLAGS> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
-
-
-# We can use $ENV{INTEL_LICENSE_FILE} to try and get at the installation location for ICC.
-# We also need to consider to use cce (which is the 64bit compiler) and not JUST the 32bit compiler.
-# I have no idea what the best way to do that would be.
-
-
-# default to searching for frameworks first
-if(NOT DEFINED CMAKE_FIND_FRAMEWORK)
- set(CMAKE_FIND_FRAMEWORK FIRST)
-endif()
-# set up the default search directories for frameworks
-set(CMAKE_SYSTEM_FRAMEWORK_PATH
- ~/Library/Frameworks
- /Library/Frameworks
- /Network/Library/Frameworks
- /System/Library/Frameworks)
-
-# default to searching for application bundles first
-if(NOT DEFINED CMAKE_FIND_APPBUNDLE)
- set(CMAKE_FIND_APPBUNDLE FIRST)
-endif()
-# set up the default search directories for application bundles
-set(CMAKE_SYSTEM_APPBUNDLE_PATH
- ~/Applications
- /Applications
- /Developer/Applications)
-
-include(Platform/UnixPaths)
-set(CMAKE_SYSTEM_INCLUDE_PATH ${CMAKE_SYSTEM_INCLUDE_PATH} /sw/include)
-set(CMAKE_SYSTEM_LIBRARY_PATH ${CMAKE_SYSTEM_LIBRARY_PATH} /sw/lib)
diff --git a/Modules/Platform/Darwin-icpc.cmake b/Modules/Platform/Darwin-icpc.cmake
deleted file mode 100644
index 549feb7f5..000000000
--- a/Modules/Platform/Darwin-icpc.cmake
+++ /dev/null
@@ -1,3 +0,0 @@
-get_filename_component(CURRENT_SOURCE_PARENT ${CMAKE_CURRENT_LIST_FILE} PATH)
-#message (STATUS "CURRENT_SOURCE_PARENT: ${CURRENT_SOURCE_PARENT}")
-include ( ${CURRENT_SOURCE_PARENT}/Darwin-icc.cmake)
diff --git a/Modules/Platform/Darwin.cmake b/Modules/Platform/Darwin.cmake
index 72844b531..bb085ac7c 100644
--- a/Modules/Platform/Darwin.cmake
+++ b/Modules/Platform/Darwin.cmake
@@ -53,7 +53,7 @@ set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-dynamiclib -Wl,-headerpad_max_install_
set(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "-bundle -Wl,-headerpad_max_install_names")
set(CMAKE_SHARED_MODULE_LOADER_C_FLAG "-Wl,-bundle_loader,")
set(CMAKE_SHARED_MODULE_LOADER_CXX_FLAG "-Wl,-bundle_loader,")
-set(CMAKE_FIND_LIBRARY_SUFFIXES ".dylib" ".so" ".a")
+set(CMAKE_FIND_LIBRARY_SUFFIXES ".tbd" ".dylib" ".so" ".a")
# hack: if a new cmake (which uses CMAKE_INSTALL_NAME_TOOL) runs on an old build tree
# (where install_name_tool was hardcoded) and where CMAKE_INSTALL_NAME_TOOL isn't in the cache
@@ -64,149 +64,14 @@ if(NOT DEFINED CMAKE_INSTALL_NAME_TOOL)
mark_as_advanced(CMAKE_INSTALL_NAME_TOOL)
endif()
-# Ask xcode-select where to find /Developer or fall back to ancient location.
-execute_process(COMMAND xcode-select -print-path
- OUTPUT_VARIABLE _stdout
- OUTPUT_STRIP_TRAILING_WHITESPACE
- ERROR_VARIABLE _stderr
- RESULT_VARIABLE _failed)
-if(NOT _failed AND IS_DIRECTORY ${_stdout})
- set(OSX_DEVELOPER_ROOT ${_stdout})
-elseif(IS_DIRECTORY "/Developer")
- set(OSX_DEVELOPER_ROOT "/Developer")
-else()
- set(OSX_DEVELOPER_ROOT "")
-endif()
-
-execute_process(COMMAND sw_vers -productVersion
- OUTPUT_VARIABLE CURRENT_OSX_VERSION
- OUTPUT_STRIP_TRAILING_WHITESPACE)
-
-# Save CMAKE_OSX_ARCHITECTURES from the environment.
-set(CMAKE_OSX_ARCHITECTURES "$ENV{CMAKE_OSX_ARCHITECTURES}" CACHE STRING
- "Build architectures for OSX")
-
-#----------------------------------------------------------------------------
-# _CURRENT_OSX_VERSION - as a two-component string: 10.5, 10.6, ...
-#
-string(REGEX REPLACE "^([0-9]+\\.[0-9]+).*$" "\\1"
- _CURRENT_OSX_VERSION "${CURRENT_OSX_VERSION}")
-
-#----------------------------------------------------------------------------
-# CMAKE_OSX_DEPLOYMENT_TARGET
-
-# Set cache variable - end user may change this during ccmake or cmake-gui configure.
-if(_CURRENT_OSX_VERSION VERSION_GREATER 10.3)
- set(CMAKE_OSX_DEPLOYMENT_TARGET "$ENV{MACOSX_DEPLOYMENT_TARGET}" CACHE STRING
- "Minimum OS X version to target for deployment (at runtime); newer APIs weak linked. Set to empty string for default value.")
-endif()
-
-#----------------------------------------------------------------------------
-# CMAKE_OSX_SYSROOT
-
-if(CMAKE_OSX_SYSROOT)
- # Use the existing value without further computation to choose a default.
- set(_CMAKE_OSX_SYSROOT_DEFAULT "${CMAKE_OSX_SYSROOT}")
-elseif(NOT "x$ENV{SDKROOT}" STREQUAL "x" AND
- (NOT "x$ENV{SDKROOT}" MATCHES "/" OR IS_DIRECTORY "$ENV{SDKROOT}"))
- # Use the value of SDKROOT from the environment.
- set(_CMAKE_OSX_SYSROOT_DEFAULT "$ENV{SDKROOT}")
-elseif("${CMAKE_GENERATOR}" MATCHES Xcode
- OR CMAKE_OSX_DEPLOYMENT_TARGET
- OR CMAKE_OSX_ARCHITECTURES MATCHES "[^;]"
- OR NOT EXISTS "/usr/include/sys/types.h")
- # Find installed SDKs in either Xcode-4.3+ or pre-4.3 SDKs directory.
- set(_CMAKE_OSX_SDKS_DIR "")
- if(OSX_DEVELOPER_ROOT)
- foreach(d Platforms/MacOSX.platform/Developer/SDKs SDKs)
- file(GLOB _CMAKE_OSX_SDKS ${OSX_DEVELOPER_ROOT}/${d}/*)
- if(_CMAKE_OSX_SDKS)
- set(_CMAKE_OSX_SDKS_DIR ${OSX_DEVELOPER_ROOT}/${d})
- break()
- endif()
- endforeach()
- endif()
-
- if(_CMAKE_OSX_SDKS_DIR)
- # Select SDK for current OSX version accounting for the known
- # specially named SDKs.
- set(_CMAKE_OSX_SDKS_VER_SUFFIX_10.4 "u")
- set(_CMAKE_OSX_SDKS_VER_SUFFIX_10.3 ".9")
- if(CMAKE_OSX_DEPLOYMENT_TARGET)
- set(_CMAKE_OSX_SDKS_VER ${CMAKE_OSX_DEPLOYMENT_TARGET}${_CMAKE_OSX_SDKS_VER_SUFFIX_${CMAKE_OSX_DEPLOYMENT_TARGET}})
- set(_CMAKE_OSX_SYSROOT_CHECK "${_CMAKE_OSX_SDKS_DIR}/MacOSX${_CMAKE_OSX_SDKS_VER}.sdk")
- if(IS_DIRECTORY "${_CMAKE_OSX_SYSROOT_CHECK}")
- set(_CMAKE_OSX_SYSROOT_DEFAULT "${_CMAKE_OSX_SYSROOT_CHECK}")
- else()
- set(_CMAKE_OSX_SDKS_VER ${_CURRENT_OSX_VERSION}${_CMAKE_OSX_SDKS_VER_SUFFIX_${_CURRENT_OSX_VERSION}})
- set(_CMAKE_OSX_SYSROOT_DEFAULT "${_CMAKE_OSX_SDKS_DIR}/MacOSX${_CMAKE_OSX_SDKS_VER}.sdk")
- message(WARNING
- "CMAKE_OSX_DEPLOYMENT_TARGET is '${CMAKE_OSX_DEPLOYMENT_TARGET}' "
- "but the matching SDK does not exist at:\n \"${_CMAKE_OSX_SYSROOT_CHECK}\"\n"
- "Instead using SDK:\n \"${_CMAKE_OSX_SYSROOT_DEFAULT}\"\n"
- "matching the host OS X version."
- )
- endif()
- else()
- set(_CMAKE_OSX_SDKS_VER ${_CURRENT_OSX_VERSION}${_CMAKE_OSX_SDKS_VER_SUFFIX_${_CURRENT_OSX_VERSION}})
- set(_CMAKE_OSX_SYSROOT_DEFAULT "${_CMAKE_OSX_SDKS_DIR}/MacOSX${_CMAKE_OSX_SDKS_VER}.sdk")
- endif()
- else()
- # Assume developer files are in root (such as Xcode 4.5 command-line tools).
- set(_CMAKE_OSX_SYSROOT_DEFAULT "")
- endif()
-endif()
-
-# Set cache variable - end user may change this during ccmake or cmake-gui configure.
-# Choose the type based on the current value.
-set(_CMAKE_OSX_SYSROOT_TYPE STRING)
-foreach(v CMAKE_OSX_SYSROOT _CMAKE_OSX_SYSROOT_DEFAULT)
- if("x${${v}}" MATCHES "/")
- set(_CMAKE_OSX_SYSROOT_TYPE PATH)
- break()
- endif()
-endforeach()
-set(CMAKE_OSX_SYSROOT "${_CMAKE_OSX_SYSROOT_DEFAULT}" CACHE ${_CMAKE_OSX_SYSROOT_TYPE}
- "The product will be built against the headers and libraries located inside the indicated SDK.")
-
-# Transform the cached value to something we can use.
-set(_CMAKE_OSX_SYSROOT_ORIG "${CMAKE_OSX_SYSROOT}")
-set(_CMAKE_OSX_SYSROOT_PATH "")
-if(CMAKE_OSX_SYSROOT)
- if("x${CMAKE_OSX_SYSROOT}" MATCHES "/")
- # This is a path to the SDK. Make sure it exists.
- if(NOT IS_DIRECTORY "${CMAKE_OSX_SYSROOT}")
- message(WARNING "Ignoring CMAKE_OSX_SYSROOT value:\n ${CMAKE_OSX_SYSROOT}\n"
- "because the directory does not exist.")
- set(CMAKE_OSX_SYSROOT "")
- set(_CMAKE_OSX_SYSROOT_ORIG "")
- endif()
- set(_CMAKE_OSX_SYSROOT_PATH "${CMAKE_OSX_SYSROOT}")
- else()
- # Transform the sdk name into a path.
- execute_process(
- COMMAND xcodebuild -sdk ${CMAKE_OSX_SYSROOT} -version Path
- OUTPUT_VARIABLE _stdout
- OUTPUT_STRIP_TRAILING_WHITESPACE
- ERROR_VARIABLE _stderr
- RESULT_VARIABLE _failed
- )
- if(NOT _failed AND IS_DIRECTORY "${_stdout}")
- set(_CMAKE_OSX_SYSROOT_PATH "${_stdout}")
- # For non-Xcode generators use the path.
- if(NOT "${CMAKE_GENERATOR}" MATCHES "Xcode")
- set(CMAKE_OSX_SYSROOT "${_CMAKE_OSX_SYSROOT_PATH}")
- endif()
- endif()
- endif()
-endif()
-
# Make sure the combination of SDK and Deployment Target are allowed
if(CMAKE_OSX_DEPLOYMENT_TARGET)
- if("${_CMAKE_OSX_SYSROOT_PATH}" MATCHES "^.*/MacOSX([0-9]+\\.[0-9]+)[^/]*\\.sdk")
+ if("${_CMAKE_OSX_SYSROOT_PATH}" MATCHES "/MacOSX([0-9]+\\.[0-9]+)[^/]*\\.sdk")
set(_sdk_ver "${CMAKE_MATCH_1}")
elseif("${_CMAKE_OSX_SYSROOT_ORIG}" MATCHES "^macosx([0-9]+\\.[0-9]+)$")
set(_sdk_ver "${CMAKE_MATCH_1}")
+ elseif("${_CMAKE_OSX_SYSROOT_ORIG}" STREQUAL "/")
+ set(_sdk_ver "${_CURRENT_OSX_VERSION}")
else()
message(FATAL_ERROR
"CMAKE_OSX_DEPLOYMENT_TARGET is '${CMAKE_OSX_DEPLOYMENT_TARGET}' "
@@ -223,11 +88,6 @@ if(CMAKE_OSX_DEPLOYMENT_TARGET)
endif()
endif()
-if("${CMAKE_BACKWARDS_COMPATIBILITY}" MATCHES "^1\\.[0-6]$")
- set(CMAKE_SHARED_MODULE_CREATE_C_FLAGS
- "${CMAKE_SHARED_MODULE_CREATE_C_FLAGS} -flat_namespace -undefined suppress")
-endif()
-
# Enable shared library versioning.
set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-install_name")
@@ -268,6 +128,11 @@ set(CMAKE_C_CREATE_MACOSX_FRAMEWORK
set(CMAKE_CXX_CREATE_MACOSX_FRAMEWORK
"<CMAKE_CXX_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <LINK_FLAGS> -o <TARGET> <SONAME_FLAG> <TARGET_INSTALLNAME_DIR><TARGET_SONAME> <OBJECTS> <LINK_LIBRARIES>")
+# Set default framework search path flag for languages known to use a
+# preprocessor that may find headers in frameworks.
+set(CMAKE_C_FRAMEWORK_SEARCH_FLAG -F)
+set(CMAKE_CXX_FRAMEWORK_SEARCH_FLAG -F)
+set(CMAKE_Fortran_FRAMEWORK_SEARCH_FLAG -F)
# default to searching for frameworks first
if(NOT DEFINED CMAKE_FIND_FRAMEWORK)
@@ -301,6 +166,21 @@ if(_CMAKE_OSX_SYSROOT_PATH)
${_CMAKE_OSX_SYSROOT_PATH}/Network/Library/Frameworks
${_CMAKE_OSX_SYSROOT_PATH}/System/Library/Frameworks
)
+ # add platform developer framework path if exists
+ foreach(_path
+ # Xcode 6
+ ${_CMAKE_OSX_SYSROOT_PATH}/../../Library/Frameworks
+ # Xcode 5 iOS
+ ${_CMAKE_OSX_SYSROOT_PATH}/Developer/Library/Frameworks
+ # Xcode 5 OSX
+ ${_CMAKE_OSX_SYSROOT_PATH}/../../../../../Library/Frameworks
+ )
+ get_filename_component(_abolute_path "${_path}" ABSOLUTE)
+ if(EXISTS "${_abolute_path}")
+ list(APPEND CMAKE_SYSTEM_FRAMEWORK_PATH "${_abolute_path}")
+ break()
+ endif()
+ endforeach()
endif()
list(APPEND CMAKE_SYSTEM_FRAMEWORK_PATH
/Library/Frameworks
@@ -341,7 +221,9 @@ foreach(_path
list(APPEND _apps_paths "${_apps}")
endif()
endforeach()
-list(REMOVE_DUPLICATES _apps_paths)
+if(_apps_paths)
+ list(REMOVE_DUPLICATES _apps_paths)
+endif()
set(CMAKE_SYSTEM_APPBUNDLE_PATH
${_apps_paths})
unset(_apps_paths)
diff --git a/Modules/Platform/Euros.cmake b/Modules/Platform/Euros.cmake
new file mode 100644
index 000000000..4c7b18277
--- /dev/null
+++ b/Modules/Platform/Euros.cmake
@@ -0,0 +1,19 @@
+# Support for EUROS RTOS (euros-embedded.com)
+set(CMAKE_LINK_LIBRARY_SUFFIX "")
+set(CMAKE_STATIC_LIBRARY_PREFIX "")
+set(CMAKE_STATIC_LIBRARY_SUFFIX ".lib")
+set(CMAKE_SHARED_LIBRARY_PREFIX "")
+set(CMAKE_SHARED_LIBRARY_SUFFIX ".lib")
+set(CMAKE_EXECUTABLE_SUFFIX ".elf")
+set(CMAKE_DL_LIBS "")
+
+set(CMAKE_FIND_LIBRARY_PREFIXES "")
+set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib")
+
+# EUROS RTOS does not support shared libs
+set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
+
+set(CMAKE_CXX_LINK_SHARED_LIBRARY )
+set(CMAKE_CXX_LINK_MODULE_LIBRARY )
+set(CMAKE_C_LINK_SHARED_LIBRARY )
+set(CMAKE_C_LINK_MODULE_LIBRARY )
diff --git a/Modules/Platform/GHS-MULTI-Initialize.cmake b/Modules/Platform/GHS-MULTI-Initialize.cmake
new file mode 100644
index 000000000..9eb7a8abe
--- /dev/null
+++ b/Modules/Platform/GHS-MULTI-Initialize.cmake
@@ -0,0 +1,51 @@
+
+#=============================================================================
+# Copyright 2015 Geoffrey Viola <geoffrey.viola@asirobots.com>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+#Setup Greenhills MULTI specific compilation information
+
+if (NOT GHS_INT_DIRECTORY)
+ #Assume the C:/ghs/int#### directory that is latest is prefered
+ set(GHS_EXPECTED_ROOT "C:/ghs")
+ if (EXISTS ${GHS_EXPECTED_ROOT})
+ FILE(GLOB GHS_CANDIDATE_INT_DIRS RELATIVE
+ ${GHS_EXPECTED_ROOT} ${GHS_EXPECTED_ROOT}/*)
+ string(REGEX MATCHALL "int[0-9][0-9][0-9][0-9]" GHS_CANDIDATE_INT_DIRS
+ ${GHS_CANDIDATE_INT_DIRS})
+ if (GHS_CANDIDATE_INT_DIRS)
+ list(SORT GHS_CANDIDATE_INT_DIRS)
+ list(GET GHS_CANDIDATE_INT_DIRS -1 GHS_INT_DIRECTORY)
+ string(CONCAT GHS_INT_DIRECTORY ${GHS_EXPECTED_ROOT} "/"
+ ${GHS_INT_DIRECTORY})
+ endif ()
+ endif ()
+
+ #Try to look for known registry values
+ if (NOT GHS_INT_DIRECTORY)
+ find_path(GHS_INT_DIRECTORY INTEGRITY.ld PATHS
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\GreenHillsSoftware6433c345;InstallLocation]" #int1122
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\GreenHillsSoftware289b6625;InstallLocation]" #int1104
+ )
+ endif ()
+
+ set(GHS_INT_DIRECTORY ${GHS_INT_DIRECTORY} CACHE PATH
+ "Path to integrity directory")
+endif ()
+
+set(GHS_OS_DIR ${GHS_INT_DIRECTORY} CACHE PATH "OS directory")
+set(GHS_PRIMARY_TARGET "arm_integrity.tgt" CACHE STRING "target for compilation")
+set(GHS_BSP_NAME "simarm" CACHE STRING "BSP name")
+set(GHS_CUSTOMIZATION "" CACHE FILEPATH "optional GHS customization")
+mark_as_advanced(GHS_CUSTOMIZATION)
+set(GHS_GPJ_MACROS "" CACHE STRING "optional GHS macros generated in the .gpjs for legacy reasons")
+mark_as_advanced(GHS_GPJ_MACROS)
diff --git a/Modules/Platform/GHS-MULTI.cmake b/Modules/Platform/GHS-MULTI.cmake
new file mode 100644
index 000000000..211cf3eb2
--- /dev/null
+++ b/Modules/Platform/GHS-MULTI.cmake
@@ -0,0 +1,27 @@
+
+#=============================================================================
+# Copyright 2015 Geoffrey Viola <geoffrey.viola@asirobots.com>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# This module is shared by multiple languages; use include blocker.
+
+if(__GHSMULTI)
+ return()
+endif()
+set(__GHSMULTI 1)
+
+set(GHSMULTI 1)
+
+set(CMAKE_FIND_LIBRARY_PREFIXES "")
+set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
+
+include(Platform/WindowsPaths)
diff --git a/Modules/Platform/Generic-SDCC-C.cmake b/Modules/Platform/Generic-SDCC-C.cmake
index 588bf32d9..a1ca81243 100644
--- a/Modules/Platform/Generic-SDCC-C.cmake
+++ b/Modules/Platform/Generic-SDCC-C.cmake
@@ -38,7 +38,7 @@ if(NOT DEFINED CMAKE_EXE_LINKER_FLAGS_INIT)
endif()
# compile a C file into an object file
-set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -o <OBJECT> -c <SOURCE>")
+set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
# link object files to an executable
set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <OBJECTS> --out-fmt-ihx -o <TARGET> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>")
diff --git a/Modules/Platform/HP-UX-GNU-ASM.cmake b/Modules/Platform/HP-UX-GNU-ASM.cmake
new file mode 100644
index 000000000..613b8596e
--- /dev/null
+++ b/Modules/Platform/HP-UX-GNU-ASM.cmake
@@ -0,0 +1,2 @@
+include(Platform/HP-UX-GNU)
+__hpux_compiler_gnu(ASM)
diff --git a/Modules/Platform/HP-UX-GNU.cmake b/Modules/Platform/HP-UX-GNU.cmake
index eb909fe99..6c717842a 100644
--- a/Modules/Platform/HP-UX-GNU.cmake
+++ b/Modules/Platform/HP-UX-GNU.cmake
@@ -20,8 +20,10 @@ set(__HPUX_COMPILER_GNU 1)
macro(__hpux_compiler_gnu lang)
set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS} -Wl,-E,-b,+nodefaultrpath")
- set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-Wl,+s,-E,+nodefaultrpath")
+ set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-Wl,-E")
set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG "-Wl,+b")
set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG_SEP ":")
set(CMAKE_SHARED_LIBRARY_SONAME_${lang}_FLAG "-Wl,+h")
+
+ set(CMAKE_${lang}_LINK_FLAGS "-Wl,+s,+nodefaultrpath")
endmacro()
diff --git a/Modules/Platform/HP-UX-HP-C.cmake b/Modules/Platform/HP-UX-HP-C.cmake
index 100093590..7610383d3 100644
--- a/Modules/Platform/HP-UX-HP-C.cmake
+++ b/Modules/Platform/HP-UX-HP-C.cmake
@@ -1,6 +1,6 @@
include(Platform/HP-UX-HP)
__hpux_compiler_hp(C)
-set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
-set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
-set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> <DEFINES> -Aa -Ae <FLAGS> -o <OBJECT> -c <SOURCE>")
+set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
+set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> <DEFINES> -Aa -Ae <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
diff --git a/Modules/Platform/HP-UX-HP-CXX.cmake b/Modules/Platform/HP-UX-HP-CXX.cmake
index dfa1e4e45..6d90191cb 100644
--- a/Modules/Platform/HP-UX-HP-CXX.cmake
+++ b/Modules/Platform/HP-UX-HP-CXX.cmake
@@ -1,9 +1,9 @@
include(Platform/HP-UX-HP)
__hpux_compiler_hp(CXX)
-set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE
- "<CMAKE_CXX_COMPILER> <DEFINES> <FLAGS> -S <SOURCE>"
+ "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE>"
"mv `basename \"<SOURCE>\" | sed 's/\\.[^./]*$$//'`.s <ASSEMBLY_SOURCE>"
"rm -f `basename \"<SOURCE>\" | sed 's/\\.[^./]*$$//'`.o"
)
diff --git a/Modules/Platform/HP-UX-HP-Fortran.cmake b/Modules/Platform/HP-UX-HP-Fortran.cmake
index 30acab807..12007e422 100644
--- a/Modules/Platform/HP-UX-HP-Fortran.cmake
+++ b/Modules/Platform/HP-UX-HP-Fortran.cmake
@@ -1,2 +1,5 @@
include(Platform/HP-UX-HP)
__hpux_compiler_hp(Fortran)
+
+set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
diff --git a/Modules/Platform/HP-UX-HP.cmake b/Modules/Platform/HP-UX-HP.cmake
index 871ea1323..3935c31c1 100644
--- a/Modules/Platform/HP-UX-HP.cmake
+++ b/Modules/Platform/HP-UX-HP.cmake
@@ -22,10 +22,12 @@ macro(__hpux_compiler_hp lang)
set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "+Z")
set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "+Z")
set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-Wl,-E,+nodefaultrpath -b -L/usr/lib")
- set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-Wl,+s,-E,+nodefaultrpath")
+ set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-Wl,-E")
set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG "-Wl,+b")
set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG_SEP ":")
set(CMAKE_SHARED_LIBRARY_SONAME_${lang}_FLAG "-Wl,+h")
set(CMAKE_${lang}_FLAGS_INIT "")
+
+ set(CMAKE_${lang}_LINK_FLAGS "-Wl,+s,+nodefaultrpath")
endmacro()
diff --git a/Modules/Platform/HP-UX.cmake b/Modules/Platform/HP-UX.cmake
index 65cc7310d..88932ad67 100644
--- a/Modules/Platform/HP-UX.cmake
+++ b/Modules/Platform/HP-UX.cmake
@@ -1,9 +1,11 @@
set(CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH /usr/lib)
-set(CMAKE_SHARED_LIBRARY_SUFFIX ".sl") # .so
+if(NOT CMAKE_SYSTEM_PROCESSOR STREQUAL "ia64")
+ set(CMAKE_SHARED_LIBRARY_SUFFIX ".sl") # .so
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ".sl" ".so" ".a")
+ set(CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES ".so")
+endif()
set(CMAKE_DL_LIBS "dld")
-set(CMAKE_FIND_LIBRARY_SUFFIXES ".sl" ".so" ".a")
-set(CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES ".so")
# The HP linker needs to find transitive shared library dependencies
# in the -L path. Therefore the runtime path must be added to the
@@ -33,18 +35,11 @@ list(APPEND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES
# Initialize C and CXX link type selection flags. These flags are
# used when building a shared library, shared module, or executable
# that links to other libraries to select whether to use the static or
-# shared versions of the libraries. Note that C modules and shared
-# libs are built using ld directly so we leave off the "-Wl," portion.
-foreach(type SHARED_LIBRARY SHARED_MODULE)
- set(CMAKE_${type}_LINK_STATIC_C_FLAGS "-a archive")
- set(CMAKE_${type}_LINK_DYNAMIC_C_FLAGS "-a default")
-endforeach()
-foreach(type EXE)
- set(CMAKE_${type}_LINK_STATIC_C_FLAGS "-Wl,-a,archive")
- set(CMAKE_${type}_LINK_DYNAMIC_C_FLAGS "-Wl,-a,default")
-endforeach()
+# shared versions of the libraries.
foreach(type SHARED_LIBRARY SHARED_MODULE EXE)
- set(CMAKE_${type}_LINK_STATIC_CXX_FLAGS "-Wl,-a,archive")
- set(CMAKE_${type}_LINK_DYNAMIC_CXX_FLAGS "-Wl,-a,default")
+ foreach(lang C CXX)
+ set(CMAKE_${type}_LINK_STATIC_${lang}_FLAGS "-Wl,-a,archive")
+ set(CMAKE_${type}_LINK_DYNAMIC_${lang}_FLAGS "-Wl,-a,default")
+ endforeach()
endforeach()
diff --git a/Modules/Platform/Haiku.cmake b/Modules/Platform/Haiku.cmake
index 8987783ff..dfc2664d3 100644
--- a/Modules/Platform/Haiku.cmake
+++ b/Modules/Platform/Haiku.cmake
@@ -1,24 +1,130 @@
-set(BEOS 1)
+# process only once
+if(HAIKU)
+ return()
+endif()
+
+set(HAIKU 1)
+set(UNIX 1)
-set(CMAKE_DL_LIBS root be)
-set(CMAKE_C_COMPILE_OPTIONS_PIC "-fPIC")
-set(CMAKE_C_COMPILE_OPTIONS_PIE "-fPIE")
+set(CMAKE_DL_LIBS "")
set(CMAKE_SHARED_LIBRARY_C_FLAGS "-fPIC")
-set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-nostart")
+set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-shared")
set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,")
set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":")
+set(CMAKE_SHARED_LIBRARY_RPATH_LINK_C_FLAG "-Wl,-rpath-link,")
set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-Wl,-soname,")
+set(CMAKE_EXE_EXPORTS_C_FLAG "-Wl,--export-dynamic")
+
+# Determine, if the C or C++ compiler is configured for a secondary
+# architecture. If so, that will change the search paths we set below. We check
+# whether the compiler's library search paths contain a
+# "/boot/system/develop/lib/<subdir>/", which we assume to be the secondary
+# architecture specific subdirectory and extract the name of the architecture
+# accordingly.
+
+# First of all, find a C or C++ compiler we can run. The "arg1" is necessary
+# here for compilers such as "distcc gcc-x86" or "ccache gcc-x86"
+# TODO See CMakeDetermineCompilerId.cmake for some more things we may want to do.
+if(CMAKE_C_COMPILER)
+ set(__HAIKU_COMPILER ${CMAKE_C_COMPILER})
+ string (STRIP "${CMAKE_C_COMPILER_ARG1}" __HAIKU_COMPILER_FLAGS)
+else()
+ set(__HAIKU_COMPILER ${CMAKE_CXX_COMPILER})
+ string (STRIP "${CMAKE_CXX_COMPILER_ARG1}" __HAIKU_COMPILER_FLAGS)
+endif()
+
+
+execute_process(
+ COMMAND ${__HAIKU_COMPILER} ${__HAIKU_COMPILER_FLAGS} -print-search-dirs
+ OUTPUT_VARIABLE _HAIKU_SEARCH_DIRS
+ RESULT_VARIABLE _HAIKU_SEARCH_DIRS_FOUND
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+string(REGEX MATCH "libraries: =?([^\n]*:)?/boot/system/develop/lib/([^/]*)/?(:?\n+)" _dummy "${_HAIKU_SEARCH_DIRS}\n")
+set(CMAKE_HAIKU_SECONDARY_ARCH "${CMAKE_MATCH_2}")
+
+if(NOT CMAKE_HAIKU_SECONDARY_ARCH)
+ set(CMAKE_HAIKU_SECONDARY_ARCH_SUBDIR "")
+ unset(CMAKE_HAIKU_SECONDARY_ARCH)
+else()
+ set(CMAKE_HAIKU_SECONDARY_ARCH_SUBDIR "/${CMAKE_HAIKU_SECONDARY_ARCH}")
+
+ # Override CMAKE_*LIBRARY_ARCHITECTURE. This will cause FIND_LIBRARY to search
+ # the libraries in the correct subdirectory first. It still isn't completely
+ # correct, since the parent directories shouldn't be searched at all. The
+ # primary architecture library might still be found, if there isn't one
+ # installed for the secondary architecture or it is installed in a less
+ # specific location.
+ set(CMAKE_LIBRARY_ARCHITECTURE ${CMAKE_HAIKU_SECONDARY_ARCH})
+ set(CMAKE_C_LIBRARY_ARCHITECTURE ${CMAKE_HAIKU_SECONDARY_ARCH})
+ set(CMAKE_CXX_LIBRARY_ARCHITECTURE ${CMAKE_HAIKU_SECONDARY_ARCH})
+endif()
+
+list(APPEND CMAKE_SYSTEM_PREFIX_PATH
+ /boot/system/non-packaged
+ /boot/system
+ )
+
+LIST(APPEND CMAKE_HAIKU_COMMON_INCLUDE_DIRECTORIES
+ /boot/system/non-packaged/develop/headers${CMAKE_HAIKU_SECONDARY_ARCH_SUBDIR}
+ /boot/system/develop/headers/os
+ /boot/system/develop/headers/os/app
+ /boot/system/develop/headers/os/device
+ /boot/system/develop/headers/os/drivers
+ /boot/system/develop/headers/os/game
+ /boot/system/develop/headers/os/interface
+ /boot/system/develop/headers/os/kernel
+ /boot/system/develop/headers/os/locale
+ /boot/system/develop/headers/os/mail
+ /boot/system/develop/headers/os/media
+ /boot/system/develop/headers/os/midi
+ /boot/system/develop/headers/os/midi2
+ /boot/system/develop/headers/os/net
+ /boot/system/develop/headers/os/opengl
+ /boot/system/develop/headers/os/storage
+ /boot/system/develop/headers/os/support
+ /boot/system/develop/headers/os/translation
+ /boot/system/develop/headers/os/add-ons/graphics
+ /boot/system/develop/headers/os/add-ons/input_server
+ /boot/system/develop/headers/os/add-ons/screen_saver
+ /boot/system/develop/headers/os/add-ons/tracker
+ /boot/system/develop/headers/os/be_apps/Deskbar
+ /boot/system/develop/headers/os/be_apps/NetPositive
+ /boot/system/develop/headers/os/be_apps/Tracker
+ /boot/system/develop/headers/3rdparty
+ /boot/system/develop/headers/bsd
+ /boot/system/develop/headers/glibc
+ /boot/system/develop/headers/gnu
+ /boot/system/develop/headers/posix
+ /boot/system/develop/headers${CMAKE_HAIKU_SECONDARY_ARCH_SUBDIR}
+ )
+IF (CMAKE_HAIKU_SECONDARY_ARCH)
+ LIST(APPEND CMAKE_HAIKU_COMMON_INCLUDE_DIRECTORIES
+ /boot/system/develop/headers
+ )
+ENDIF (CMAKE_HAIKU_SECONDARY_ARCH)
+
+LIST(APPEND CMAKE_HAIKU_C_INCLUDE_DIRECTORIES
+ ${CMAKE_HAIKU_COMMON_INCLUDE_DIRECTORIES}
+ )
+
+LIST(APPEND CMAKE_HAIKU_CXX_INCLUDE_DIRECTORIES
+ ${CMAKE_HAIKU_COMMON_INCLUDE_DIRECTORIES})
+
+LIST(APPEND CMAKE_SYSTEM_INCLUDE_PATH ${CMAKE_HAIKU_C_INCLUDE_DIRECTORIES})
+
+LIST(APPEND CMAKE_HAIKU_DEVELOP_LIB_DIRECTORIES
+ /boot/system/non-packaged/develop/lib${CMAKE_HAIKU_SECONDARY_ARCH_SUBDIR}
+ /boot/system/develop/lib${CMAKE_HAIKU_SECONDARY_ARCH_SUBDIR}
+ )
+
+LIST(APPEND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES
+ ${CMAKE_HAIKU_DEVELOP_LIB_DIRECTORIES}
+ )
-include(Platform/UnixPaths)
-list(APPEND CMAKE_SYSTEM_PREFIX_PATH /boot/common)
-list(APPEND CMAKE_SYSTEM_INCLUDE_PATH /boot/common/include)
-list(APPEND CMAKE_SYSTEM_LIBRARY_PATH /boot/common/lib)
-list(APPEND CMAKE_SYSTEM_PROGRAM_PATH /boot/common/bin)
-list(APPEND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES /boot/common/lib)
-list(APPEND CMAKE_SYSTEM_INCLUDE_PATH /boot/develop/headers/3rdparty)
-list(APPEND CMAKE_SYSTEM_LIBRARY_PATH /boot/develop/lib/x86)
+LIST(APPEND CMAKE_SYSTEM_LIBRARY_PATH ${CMAKE_HAIKU_DEVELOP_LIB_DIRECTORIES})
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
- set(CMAKE_INSTALL_PREFIX "/boot/common" CACHE PATH
+ set(CMAKE_INSTALL_PREFIX "/boot/system" CACHE PATH
"Install path prefix, prepended onto install directories." FORCE)
endif()
diff --git a/Modules/Platform/IRIX.cmake b/Modules/Platform/IRIX.cmake
index 03e98ccfd..12b0f3774 100644
--- a/Modules/Platform/IRIX.cmake
+++ b/Modules/Platform/IRIX.cmake
@@ -31,6 +31,14 @@ if(NOT CMAKE_COMPILER_IS_GNUCXX)
)
endif()
+if(NOT CMAKE_COMPILER_IS_GNUG77)
+ set (CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+ set (CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE
+ "<CMAKE_Fortran_COMPILER> <FLAGS> -S <SOURCE>"
+ "mv `basename \"<SOURCE>\" | sed 's/\\.[^./]*$$//'`.s <ASSEMBLY_SOURCE>"
+ )
+endif()
+
# Initialize C link type selection flags. These flags are used when
# building a shared library, shared module, or executable that links
# to other libraries to select whether to use the static or shared
diff --git a/Modules/Platform/IRIX64.cmake b/Modules/Platform/IRIX64.cmake
index 5acbd81fa..ee9b96e89 100644
--- a/Modules/Platform/IRIX64.cmake
+++ b/Modules/Platform/IRIX64.cmake
@@ -44,17 +44,17 @@ endif()
include(Platform/UnixPaths)
if(NOT CMAKE_COMPILER_IS_GNUCC)
- set (CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+ set (CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
set (CMAKE_C_CREATE_ASSEMBLY_SOURCE
- "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -S <SOURCE>"
+ "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE>"
"mv `basename \"<SOURCE>\" | sed 's/\\.[^./]*$$//'`.s <ASSEMBLY_SOURCE>"
)
endif()
if(NOT CMAKE_COMPILER_IS_GNUCXX)
- set (CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+ set (CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
set (CMAKE_CXX_CREATE_ASSEMBLY_SOURCE
- "<CMAKE_CXX_COMPILER> <DEFINES> <FLAGS> -S <SOURCE>"
+ "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE>"
"mv `basename \"<SOURCE>\" | sed 's/\\.[^./]*$$//'`.s <ASSEMBLY_SOURCE>"
)
endif()
diff --git a/Modules/Platform/Linux-CCur-Fortran.cmake b/Modules/Platform/Linux-CCur-Fortran.cmake
new file mode 100644
index 000000000..ceecc2f69
--- /dev/null
+++ b/Modules/Platform/Linux-CCur-Fortran.cmake
@@ -0,0 +1 @@
+include(Platform/Linux-GNU-Fortran)
diff --git a/Modules/Platform/Linux-GNU-Fortran.cmake b/Modules/Platform/Linux-GNU-Fortran.cmake
index 68e95404b..85e12265a 100644
--- a/Modules/Platform/Linux-GNU-Fortran.cmake
+++ b/Modules/Platform/Linux-GNU-Fortran.cmake
@@ -1,2 +1,3 @@
include(Platform/Linux-GNU)
__linux_compiler_gnu(Fortran)
+set(CMAKE_SHARED_LIBRARY_LINK_Fortran_FLAGS "")
diff --git a/Modules/Platform/Linux-Intel-C.cmake b/Modules/Platform/Linux-Intel-C.cmake
index d1694d64a..449493a78 100644
--- a/Modules/Platform/Linux-Intel-C.cmake
+++ b/Modules/Platform/Linux-Intel-C.cmake
@@ -1,2 +1,3 @@
include(Platform/Linux-Intel)
__linux_compiler_intel(C)
+set(CMAKE_INCLUDE_SYSTEM_FLAG_C "-isystem ")
diff --git a/Modules/Platform/Linux-Intel-CXX.cmake b/Modules/Platform/Linux-Intel-CXX.cmake
index 66df3ac2a..142b6cf5c 100644
--- a/Modules/Platform/Linux-Intel-CXX.cmake
+++ b/Modules/Platform/Linux-Intel-CXX.cmake
@@ -1,2 +1,3 @@
include(Platform/Linux-Intel)
__linux_compiler_intel(CXX)
+set(CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-isystem ")
diff --git a/Modules/Platform/Linux-Intel-Fortran.cmake b/Modules/Platform/Linux-Intel-Fortran.cmake
index bb671eeb2..0c9523c8c 100644
--- a/Modules/Platform/Linux-Intel-Fortran.cmake
+++ b/Modules/Platform/Linux-Intel-Fortran.cmake
@@ -1,4 +1,4 @@
include(Platform/Linux-Intel)
__linux_compiler_intel(Fortran)
-set(CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS} -i_dynamic -nofor_main")
-set(CMAKE_SHARED_LIBRARY_LINK_Fortran_FLAGS "-i_dynamic")
+set(CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS} -nofor_main")
+set(CMAKE_SHARED_LIBRARY_LINK_Fortran_FLAGS "")
diff --git a/Modules/Platform/Linux-Intel.cmake b/Modules/Platform/Linux-Intel.cmake
index 2394f1050..20fddb422 100644
--- a/Modules/Platform/Linux-Intel.cmake
+++ b/Modules/Platform/Linux-Intel.cmake
@@ -47,4 +47,8 @@ macro(__linux_compiler_intel lang)
"${XIAR} cr <TARGET> <LINK_FLAGS> <OBJECTS> "
"${XIAR} -s <TARGET> ")
endif()
+
+ if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 12.0)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY "-fvisibility=")
+ endif()
endmacro()
diff --git a/Modules/Platform/Linux-PGI.cmake b/Modules/Platform/Linux-PGI.cmake
index 3cbb35c72..baa2248a5 100644
--- a/Modules/Platform/Linux-PGI.cmake
+++ b/Modules/Platform/Linux-PGI.cmake
@@ -21,7 +21,7 @@ set(__LINUX_COMPILER_PGI 1)
macro(__linux_compiler_pgi lang)
# Shared library compile and link flags.
set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC")
- set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE")
+ set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "")
set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-fPIC")
set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared")
endmacro()
diff --git a/Modules/Platform/Linux-XL-C.cmake b/Modules/Platform/Linux-XL-C.cmake
index f1c584ce5..d595e44f7 100644
--- a/Modules/Platform/Linux-XL-C.cmake
+++ b/Modules/Platform/Linux-XL-C.cmake
@@ -1 +1,2 @@
set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-qmkshrobj")
+set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-Wl,-export-dynamic")
diff --git a/Modules/Platform/Linux-XL-CXX.cmake b/Modules/Platform/Linux-XL-CXX.cmake
index abd3fa497..5ceb25591 100644
--- a/Modules/Platform/Linux-XL-CXX.cmake
+++ b/Modules/Platform/Linux-XL-CXX.cmake
@@ -1 +1,2 @@
set(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "-qmkshrobj")
+set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "-Wl,-export-dynamic")
diff --git a/Modules/Platform/Linux-XL-Fortran.cmake b/Modules/Platform/Linux-XL-Fortran.cmake
index cdd1f702b..a87899131 100644
--- a/Modules/Platform/Linux-XL-Fortran.cmake
+++ b/Modules/Platform/Linux-XL-Fortran.cmake
@@ -1 +1,2 @@
set(CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS "-qmkshrobj")
+set(CMAKE_SHARED_LIBRARY_LINK_Fortran_FLAGS "-Wl,-export-dynamic")
diff --git a/Modules/Platform/Linux.cmake b/Modules/Platform/Linux.cmake
index fe8e0039f..e40a74fab 100644
--- a/Modules/Platform/Linux.cmake
+++ b/Modules/Platform/Linux.cmake
@@ -52,6 +52,6 @@ include(Platform/UnixPaths)
# Debian has lib64 paths only for compatibility so they should not be
# searched.
-if(EXISTS "/etc/debian_version")
+if(NOT CMAKE_CROSSCOMPILING AND EXISTS "/etc/debian_version")
set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS FALSE)
endif()
diff --git a/Modules/Platform/MirBSD.cmake b/Modules/Platform/MirBSD.cmake
new file mode 100644
index 000000000..7637f9bc7
--- /dev/null
+++ b/Modules/Platform/MirBSD.cmake
@@ -0,0 +1 @@
+include(Platform/OpenBSD)
diff --git a/Modules/Platform/OSF1.cmake b/Modules/Platform/OSF1.cmake
index 9c3255e36..f2ad6129c 100644
--- a/Modules/Platform/OSF1.cmake
+++ b/Modules/Platform/OSF1.cmake
@@ -2,7 +2,7 @@ set(CMAKE_DL_LIBS "")
if(CMAKE_SYSTEM MATCHES "OSF1-1.[012]")
endif()
-if(CMAKE_SYSTEM MATCHES "OSF1-1.*")
+if(CMAKE_SYSTEM MATCHES "OSF1-1")
# OSF/1 1.3 from OSF using ELF, and derivatives, including AD2
set(CMAKE_C_COMPILE_OPTIONS_PIC "-fpic")
set(CMAKE_C_COMPILE_OPTIONS_PIE "-fpie")
@@ -12,7 +12,7 @@ endif()
-if(CMAKE_SYSTEM MATCHES "OSF1-V.*")
+if(CMAKE_SYSTEM MATCHES "OSF1-V")
set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-shared -Wl,-expect_unresolved,\\*") # -shared
if(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG "-Wl,-rpath,")
diff --git a/Modules/Platform/OpenBSD.cmake b/Modules/Platform/OpenBSD.cmake
index 53cabedde..7ac6c7e84 100644
--- a/Modules/Platform/OpenBSD.cmake
+++ b/Modules/Platform/OpenBSD.cmake
@@ -10,13 +10,29 @@ if(NOT CMAKE_PLATFORM_RUNTIME_PATH)
ERROR_QUIET)
string(REGEX REPLACE ".*search\\ directories:\\ ([^\n]*).*" "\\1"
LDCONFIG_HINTS "${LDCONFIG_HINTS}")
- string(REGEX REPLACE ":" ";"
+ string(REPLACE ":" ";"
CMAKE_PLATFORM_RUNTIME_PATH
"${LDCONFIG_HINTS}")
endif()
set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_OPENBSD_VERSIONING 1)
+# OpenBSD has no multilib
+set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS FALSE)
+
# OpenBSD policy requires that shared libraries be installed without
# executable permission.
set(CMAKE_INSTALL_SO_NO_EXE 1)
+
+if($ENV{LOCALBASE})
+ set(OPENBSD_LOCALBASE $ENV{LOCALBASE})
+else()
+ set(OPENBSD_LOCALBASE /usr/local)
+endif()
+if($ENV{X11BASE})
+ set(OPENBSD_X11BASE $ENV{X11BASE})
+else()
+ set(OPENBSD_X11BASE /usr/X11R6)
+endif()
+
+list(APPEND CMAKE_SYSTEM_PREFIX_PATH ${OPENBSD_LOCALBASE})
diff --git a/Modules/Platform/QNX.cmake b/Modules/Platform/QNX.cmake
index 2598411cd..ebc4609a3 100644
--- a/Modules/Platform/QNX.cmake
+++ b/Modules/Platform/QNX.cmake
@@ -1,18 +1,9 @@
set(QNXNTO 1)
-# The QNX GCC does not seem to have -isystem so remove the flag.
-set(CMAKE_INCLUDE_SYSTEM_FLAG_C)
-set(CMAKE_INCLUDE_SYSTEM_FLAG_CXX)
+include(Platform/GNU)
+unset(CMAKE_LIBRARY_ARCHITECTURE_REGEX)
set(CMAKE_DL_LIBS "")
-set(CMAKE_SHARED_LIBRARY_C_FLAGS "")
-set(CMAKE_SHARED_LIBRARY_CXX_FLAGS "")
-set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-shared")
-set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,")
-set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":")
-set(CMAKE_SHARED_LIBRARY_RPATH_LINK_C_FLAG "-Wl,-rpath-link,")
-set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-Wl,-soname,")
-set(CMAKE_EXE_EXPORTS_C_FLAG "-Wl,--export-dynamic")
# Shared libraries with no builtin soname may not be linked safely by
# specifying the file path.
@@ -26,8 +17,3 @@ foreach(type SHARED_LIBRARY SHARED_MODULE EXE)
set(CMAKE_${type}_LINK_STATIC_C_FLAGS "-Wl,-Bstatic")
set(CMAKE_${type}_LINK_DYNAMIC_C_FLAGS "-Wl,-Bdynamic")
endforeach()
-# force the language to be c++ since qnx only has gcc and not g++ and c++?
-set(CMAKE_CXX_COMPILE_OBJECT
- "<CMAKE_CXX_COMPILER> -x c++ <DEFINES> <FLAGS> -o <OBJECT> -c <SOURCE>")
-
-include(Platform/UnixPaths)
diff --git a/Modules/Platform/SunOS.cmake b/Modules/Platform/SunOS.cmake
index da20f97a1..58398c06f 100644
--- a/Modules/Platform/SunOS.cmake
+++ b/Modules/Platform/SunOS.cmake
@@ -1,4 +1,4 @@
-if(CMAKE_SYSTEM MATCHES "SunOS-4.*")
+if(CMAKE_SYSTEM MATCHES "SunOS-4")
set(CMAKE_C_COMPILE_OPTIONS_PIC "-PIC")
set(CMAKE_C_COMPILE_OPTIONS_PIE "-PIE")
set(CMAKE_SHARED_LIBRARY_C_FLAGS "-PIC")
@@ -7,22 +7,8 @@ if(CMAKE_SYSTEM MATCHES "SunOS-4.*")
set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":")
endif()
-if(CMAKE_COMPILER_IS_GNUCXX)
- if(CMAKE_COMPILER_IS_GNUCC)
- set(CMAKE_CXX_CREATE_SHARED_LIBRARY
- "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
- else()
- # Take default rule from CMakeDefaultMakeRuleVariables.cmake.
- endif()
-endif()
include(Platform/UnixPaths)
-# Add the compiler's implicit link directories.
-if("${CMAKE_C_COMPILER_ID} ${CMAKE_CXX_COMPILER_ID}" MATCHES SunPro)
- list(APPEND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES
- /opt/SUNWspro/lib /opt/SUNWspro/prod/lib /usr/ccs/lib)
-endif()
-
# The Sun linker needs to find transitive shared library dependencies
# in the -L path.
set(CMAKE_LINK_DEPENDENT_LIBRARY_DIRS 1)
diff --git a/Modules/Platform/UnixPaths.cmake b/Modules/Platform/UnixPaths.cmake
index ccb266330..20ee1d111 100644
--- a/Modules/Platform/UnixPaths.cmake
+++ b/Modules/Platform/UnixPaths.cmake
@@ -37,10 +37,19 @@ list(APPEND CMAKE_SYSTEM_PREFIX_PATH
# CMake install location
"${_CMAKE_INSTALL_DIR}"
-
- # Project install destination.
- "${CMAKE_INSTALL_PREFIX}"
)
+if (NOT CMAKE_FIND_NO_INSTALL_PREFIX)
+ list(APPEND CMAKE_SYSTEM_PREFIX_PATH
+ # Project install destination.
+ "${CMAKE_INSTALL_PREFIX}"
+ )
+ if(CMAKE_STAGING_PREFIX)
+ list(APPEND CMAKE_SYSTEM_PREFIX_PATH
+ # User-supplied staging prefix.
+ "${CMAKE_STAGING_PREFIX}"
+ )
+ endif()
+endif()
# List common include file locations not under the common prefixes.
list(APPEND CMAKE_SYSTEM_INCLUDE_PATH
@@ -74,7 +83,7 @@ list(APPEND CMAKE_SYSTEM_PROGRAM_PATH
)
list(APPEND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES
- /lib /usr/lib /usr/lib32 /usr/lib64
+ /lib /lib32 /lib64 /usr/lib /usr/lib32 /usr/lib64
)
list(APPEND CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES
diff --git a/Modules/Platform/Windows-Clang-C.cmake b/Modules/Platform/Windows-Clang-C.cmake
new file mode 100644
index 000000000..d00710579
--- /dev/null
+++ b/Modules/Platform/Windows-Clang-C.cmake
@@ -0,0 +1,2 @@
+include(Platform/Windows-Clang)
+__windows_compiler_clang(C)
diff --git a/Modules/Platform/Windows-Clang-CXX.cmake b/Modules/Platform/Windows-Clang-CXX.cmake
new file mode 100644
index 000000000..2c3688a36
--- /dev/null
+++ b/Modules/Platform/Windows-Clang-CXX.cmake
@@ -0,0 +1,2 @@
+include(Platform/Windows-Clang)
+__windows_compiler_clang(CXX)
diff --git a/Modules/Platform/Windows-Clang.cmake b/Modules/Platform/Windows-Clang.cmake
new file mode 100644
index 000000000..da19a3d07
--- /dev/null
+++ b/Modules/Platform/Windows-Clang.cmake
@@ -0,0 +1,32 @@
+
+#=============================================================================
+# Copyright 2001-2013 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# This module is shared by multiple languages; use include blocker.
+if(__WINDOWS_CLANG)
+ return()
+endif()
+set(__WINDOWS_CLANG 1)
+
+if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC"
+ OR "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
+ include(Platform/Windows-MSVC)
+ macro(__windows_compiler_clang lang)
+ __windows_compiler_msvc(${lang})
+ endmacro()
+else()
+ include(Platform/Windows-GNU)
+ macro(__windows_compiler_clang lang)
+ __windows_compiler_gnu(${lang})
+ endmacro()
+endif()
diff --git a/Modules/Platform/Windows-Embarcadero.cmake b/Modules/Platform/Windows-Embarcadero.cmake
index 26b3c0cab..102e3a651 100644
--- a/Modules/Platform/Windows-Embarcadero.cmake
+++ b/Modules/Platform/Windows-Embarcadero.cmake
@@ -74,6 +74,16 @@ set (CMAKE_MODULE_LINKER_FLAGS_INIT ${CMAKE_SHARED_LINKER_FLAGS_INIT})
set (CMAKE_MODULE_LINKER_FLAGS_DEBUG_INIT ${CMAKE_SHARED_LINKER_FLAGS_DEBUG_INIT})
set (CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO_INIT ${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO_INIT})
+# The Borland link tool does not support multiple concurrent
+# invocations within a single working directory.
+if(NOT DEFINED CMAKE_JOB_POOL_LINK)
+ set(CMAKE_JOB_POOL_LINK BCC32LinkPool)
+ get_property(_bccjp GLOBAL PROPERTY JOB_POOLS)
+ if(NOT _bccjp MATCHES "BCC32LinkPool=")
+ set_property(GLOBAL APPEND PROPERTY JOB_POOLS BCC32LinkPool=1)
+ endif()
+ unset(_bccjp)
+endif()
macro(__embarcadero_language lang)
set(CMAKE_${lang}_COMPILE_OPTIONS_DLL "${_tD}") # Note: This variable is a ';' separated list
@@ -84,7 +94,7 @@ macro(__embarcadero_language lang)
# place <DEFINES> outside the response file because Borland refuses
# to parse quotes from the response file.
set(CMAKE_${lang}_COMPILE_OBJECT
- "<CMAKE_${lang}_COMPILER> ${_tR} <DEFINES> -DWIN32 -o<OBJECT> <FLAGS> ${_COMPILE_${lang}} <SOURCE>"
+ "<CMAKE_${lang}_COMPILER> ${_tR} -DWIN32 <DEFINES> <INCLUDES> <FLAGS> -o<OBJECT> ${_COMPILE_${lang}} <SOURCE>"
)
set(CMAKE_${lang}_LINK_EXECUTABLE
@@ -95,7 +105,7 @@ macro(__embarcadero_language lang)
# place <DEFINES> outside the response file because Borland refuses
# to parse quotes from the response file.
set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE
- "cpp32 <DEFINES> -DWIN32 <FLAGS> -o<PREPROCESSED_SOURCE> ${_COMPILE_${lang}} <SOURCE>"
+ "cpp32 -DWIN32 <DEFINES> <INCLUDES> <FLAGS> -o<PREPROCESSED_SOURCE> ${_COMPILE_${lang}} <SOURCE>"
)
# Borland >= 5.6 allows -P option for cpp32, <= 5.5 does not
diff --git a/Modules/Platform/Windows-GNU.cmake b/Modules/Platform/Windows-GNU.cmake
index 2bb7a2076..d8a423e55 100644
--- a/Modules/Platform/Windows-GNU.cmake
+++ b/Modules/Platform/Windows-GNU.cmake
@@ -61,14 +61,12 @@ if(NOT CMAKE_GENERATOR_RC AND CMAKE_GENERATOR MATCHES "Unix Makefiles")
set(CMAKE_GENERATOR_RC windres)
endif()
-enable_language(RC)
-
macro(__windows_compiler_gnu lang)
if(MSYS OR MINGW)
# Create archiving rules to support large object file lists for static libraries.
- set(CMAKE_${lang}_ARCHIVE_CREATE "<CMAKE_AR> cr <TARGET> <LINK_FLAGS> <OBJECTS>")
- set(CMAKE_${lang}_ARCHIVE_APPEND "<CMAKE_AR> r <TARGET> <LINK_FLAGS> <OBJECTS>")
+ set(CMAKE_${lang}_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
+ set(CMAKE_${lang}_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
set(CMAKE_${lang}_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
# Initialize C link type selection flags. These flags are used when
@@ -87,6 +85,7 @@ macro(__windows_compiler_gnu lang)
set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "")
set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_OBJECTS ${__WINDOWS_GNU_LD_RESPONSE})
+ set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_LIBRARIES ${__WINDOWS_GNU_LD_RESPONSE})
set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_INCLUDES 1)
# We prefer "@" for response files but it is not supported by gcc 3.
@@ -103,16 +102,18 @@ macro(__windows_compiler_gnu lang)
endif()
# The GNU 3.x compilers do not support response files (only linkers).
set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_INCLUDES 0)
- elseif(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_OBJECTS)
+ # Link libraries are generated only for the front-end.
+ set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_LIBRARIES 0)
+ else()
# Use "@" to pass the response file to the front-end.
set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "@")
endif()
# Binary link rules.
set(CMAKE_${lang}_CREATE_SHARED_MODULE
- "<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_MODULE_${lang}_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_MODULE_CREATE_${lang}_FLAGS> -o <TARGET> ${CMAKE_GNULD_IMAGE_VERSION} <OBJECTS> <LINK_LIBRARIES>")
+ "<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_MODULE_${lang}_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_MODULE_CREATE_${lang}_FLAGS> -o <TARGET> ${CMAKE_GNULD_IMAGE_VERSION} <OBJECTS> <LINK_LIBRARIES>")
set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
- "<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <OBJECTS> <LINK_LIBRARIES>")
+ "<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <OBJECTS> <LINK_LIBRARIES>")
set(CMAKE_${lang}_LINK_EXECUTABLE
"<CMAKE_${lang}_COMPILER> <FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>")
@@ -136,6 +137,12 @@ macro(__windows_compiler_gnu lang)
)
endforeach()
endif()
+
+ if(NOT CMAKE_RC_COMPILER_INIT AND NOT CMAKE_GENERATOR_RC)
+ set(CMAKE_RC_COMPILER_INIT windres)
+ endif()
+
+ enable_language(RC)
endmacro()
macro(__windows_compiler_gnu_abi lang)
@@ -151,6 +158,7 @@ macro(__windows_compiler_gnu_abi lang)
find_program(CMAKE_GNUtoMS_VCVARS NAMES vcvars32.bat
DOC "Visual Studio vcvars32.bat"
PATHS
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\12.0\\Setup\\VC;ProductDir]/bin"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\11.0\\Setup\\VC;ProductDir]/bin"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0\\Setup\\VC;ProductDir]/bin"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\9.0\\Setup\\VC;ProductDir]/bin"
@@ -160,9 +168,10 @@ macro(__windows_compiler_gnu_abi lang)
)
set(CMAKE_GNUtoMS_ARCH x86)
elseif("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
- find_program(CMAKE_GNUtoMS_VCVARS NAMES vcvarsamd64.bat
+ find_program(CMAKE_GNUtoMS_VCVARS NAMES vcvars64.bat vcvarsamd64.bat
DOC "Visual Studio vcvarsamd64.bat"
PATHS
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\12.0\\Setup\\VC;ProductDir]/bin/amd64"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\11.0\\Setup\\VC;ProductDir]/bin/amd64"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0\\Setup\\VC;ProductDir]/bin/amd64"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\9.0\\Setup\\VC;ProductDir]/bin/amd64"
diff --git a/Modules/Platform/Windows-Intel-CXX.cmake b/Modules/Platform/Windows-Intel-CXX.cmake
index ec5f0aec6..84cd303ec 100644
--- a/Modules/Platform/Windows-Intel-CXX.cmake
+++ b/Modules/Platform/Windows-Intel-CXX.cmake
@@ -1,4 +1,3 @@
include(Platform/Windows-Intel)
set(_COMPILE_CXX " /TP")
-set(_FLAGS_CXX " /EHsc /GR")
__windows_compiler_intel(CXX)
diff --git a/Modules/Platform/Windows-Intel-Fortran.cmake b/Modules/Platform/Windows-Intel-Fortran.cmake
index 40523ffe5..0f9a10a79 100644
--- a/Modules/Platform/Windows-Intel-Fortran.cmake
+++ b/Modules/Platform/Windows-Intel-Fortran.cmake
@@ -5,7 +5,7 @@ set(CMAKE_Fortran_MODDIR_FLAG "-module:")
set(CMAKE_Fortran_STANDARD_LIBRARIES_INIT "user32.lib")
__windows_compiler_intel(Fortran)
set (CMAKE_Fortran_FLAGS_INIT "/W1 /nologo /fpp /libs:dll /threads")
-set (CMAKE_Fortran_FLAGS_DEBUG_INIT "/debug:full /dbglibs")
+set (CMAKE_Fortran_FLAGS_DEBUG_INIT "/Od /debug:full /dbglibs")
set (CMAKE_Fortran_FLAGS_MINSIZEREL_INIT "/O1 /D NDEBUG")
set (CMAKE_Fortran_FLAGS_RELEASE_INIT "/O2 /D NDEBUG")
set (CMAKE_Fortran_FLAGS_RELWITHDEBINFO_INIT "/O2 /debug:full /D NDEBUG")
diff --git a/Modules/Platform/Windows-Intel.cmake b/Modules/Platform/Windows-Intel.cmake
index 69a7f2ff0..34e6b377b 100644
--- a/Modules/Platform/Windows-Intel.cmake
+++ b/Modules/Platform/Windows-Intel.cmake
@@ -18,92 +18,11 @@ if(__WINDOWS_INTEL)
endif()
set(__WINDOWS_INTEL 1)
-# make sure to enable languages after setting configuration types
-enable_language(RC)
-set(CMAKE_COMPILE_RESOURCE "rc <FLAGS> /fo<OBJECT> <SOURCE>")
-
-set(CMAKE_LIBRARY_PATH_FLAG "-LIBPATH:")
-set(CMAKE_LINK_LIBRARY_FLAG "")
-set(WIN32 1)
-if(CMAKE_VERBOSE_MAKEFILE)
- set(CMAKE_CL_NOLOGO)
-else()
- set(CMAKE_CL_NOLOGO "/nologo")
-endif()
-set(CMAKE_COMPILE_RESOURCE "rc <FLAGS> /fo<OBJECT> <SOURCE>")
-set(CMAKE_CREATE_WIN32_EXE /subsystem:windows)
-set(CMAKE_CREATE_CONSOLE_EXE /subsystem:console)
-
-# default to Debug builds
-#set(CMAKE_BUILD_TYPE_INIT Debug)
-set(CMAKE_BUILD_TYPE_INIT Release)
-
-set(CMAKE_C_STANDARD_LIBRARIES_INIT "kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib")
-set(CMAKE_CXX_STANDARD_LIBRARIES_INIT "${CMAKE_C_STANDARD_LIBRARIES_INIT}")
-
-# executable linker flags
-set (CMAKE_LINK_DEF_FILE_FLAG "/DEF:")
-if(MSVC_C_ARCHITECTURE_ID)
- set(_MACHINE_ARCH_FLAG "/machine:${MSVC_C_ARCHITECTURE_ID}")
-elseif(MSVC_CXX_ARCHITECTURE_ID)
- set(_MACHINE_ARCH_FLAG "/machine:${MSVC_CXX_ARCHITECTURE_ID}")
-elseif(MSVC_Fortran_ARCHITECTURE_ID)
- set(_MACHINE_ARCH_FLAG "/machine:${MSVC_Fortran_ARCHITECTURE_ID}")
-endif()
-set (CMAKE_EXE_LINKER_FLAGS_INIT "/INCREMENTAL:YES ${_MACHINE_ARCH_FLAG}")
-set (CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT "/debug")
-set (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO_INIT "/debug")
-
-set (CMAKE_SHARED_LINKER_FLAGS_INIT ${CMAKE_EXE_LINKER_FLAGS_INIT})
-set (CMAKE_SHARED_LINKER_FLAGS_DEBUG_INIT ${CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT})
-set (CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO_INIT ${CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT})
-set (CMAKE_MODULE_LINKER_FLAGS_INIT ${CMAKE_SHARED_LINKER_FLAGS_INIT})
-set (CMAKE_MODULE_LINKER_FLAGS_DEBUG_INIT ${CMAKE_SHARED_LINKER_FLAGS_DEBUG_INIT})
-set (CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO_INIT ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO_INIT})
-
-include("${CMAKE_PLATFORM_INFO_DIR}/CMakeIntelInformation.cmake" OPTIONAL)
-
-if(NOT _INTEL_XILINK_TEST_RUN)
- execute_process(COMMAND xilink /?
- ERROR_VARIABLE _XILINK_ERR
- OUTPUT_VARIABLE _XILINK_HELP)
- if(_XILINK_HELP MATCHES MANIFEST)
- set(_INTEL_COMPILER_SUPPORTS_MANIFEST 1)
- endif()
- if(NOT EXISTS "${CMAKE_PLATFORM_INFO_DIR}/CMakeIntelInformation.cmake")
- file(WRITE ${CMAKE_PLATFORM_INFO_DIR}/CMakeIntelInformation.cmake
- "
-set(_INTEL_XILINK_TEST_RUN 1)
-set(_INTEL_COMPILER_SUPPORTS_MANIFEST ${_INTEL_COMPILER_SUPPORTS_MANIFEST})
-")
- endif()
-endif()
-
+include(Platform/Windows-MSVC)
macro(__windows_compiler_intel lang)
- set(CMAKE_${lang}_COMPILE_OBJECT
- "<CMAKE_${lang}_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO}${_COMPILE_${lang}} /Fo<OBJECT> /Fd<OBJECT_DIR>/ <DEFINES> <FLAGS> -c <SOURCE>${CMAKE_END_TEMP_FILE}")
- set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE
- "<CMAKE_${lang}_COMPILER> > <PREPROCESSED_SOURCE> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO}${_COMPILE_${lang}} <DEFINES> <FLAGS> -E <SOURCE>${CMAKE_END_TEMP_FILE}")
- set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_OBJECTS 1)
- set(CMAKE_${lang}_CREATE_STATIC_LIBRARY "lib ${CMAKE_CL_NOLOGO} <LINK_FLAGS> /out:<TARGET> <OBJECTS> ")
- set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
- "xilink ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /dll <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
- set(CMAKE_${lang}_CREATE_SHARED_MODULE "${CMAKE_${lang}_CREATE_SHARED_LIBRARY}")
- set(CMAKE_${lang}_COMPILER_LINKER_OPTION_FLAG_EXECUTABLE "/link")
- set(CMAKE_${lang}_LINK_EXECUTABLE
- "<CMAKE_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} <FLAGS> /Fe<TARGET> <OBJECTS> /link /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
- set(CMAKE_${lang}_FLAGS_INIT "/DWIN32 /D_WINDOWS /W3 /Zm1000${_FLAGS_${lang}}")
- set(CMAKE_${lang}_FLAGS_DEBUG_INIT "/D_DEBUG /MDd /Zi /Od /RTC1")
- set(CMAKE_${lang}_FLAGS_MINSIZEREL_INIT "/DNDEBUG /MD /O1")
- set(CMAKE_${lang}_FLAGS_RELEASE_INIT "/DNDEBUG /MD /O2")
- set(CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT "/DNDEBUG /MD /Zi /O2")
-
- if(_INTEL_COMPILER_SUPPORTS_MANIFEST)
- set(CMAKE_${lang}_LINK_EXECUTABLE
- "<CMAKE_COMMAND> -E vs_link_exe ${CMAKE_${lang}_LINK_EXECUTABLE}")
- set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
- "<CMAKE_COMMAND> -E vs_link_dll ${CMAKE_${lang}_CREATE_SHARED_LIBRARY}")
- set(CMAKE_${lang}_CREATE_SHARED_MODULE
- "<CMAKE_COMMAND> -E vs_link_dll ${CMAKE_${lang}_CREATE_SHARED_MODULE}")
- endif()
+ __windows_compiler_msvc(${lang})
+ string(REPLACE "<CMAKE_LINKER> /lib" "lib" CMAKE_${lang}_CREATE_STATIC_LIBRARY "${CMAKE_${lang}_CREATE_STATIC_LIBRARY}")
+ foreach(rule CREATE_SHARED_LIBRARY CREATE_SHARED_MODULE LINK_EXECUTABLE)
+ string(REPLACE "<CMAKE_LINKER>" "xilink" CMAKE_${lang}_${rule} "${CMAKE_${lang}_${rule}}")
+ endforeach()
endmacro()
diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake
index 6e02e4aca..a61413a87 100644
--- a/Modules/Platform/Windows-MSVC.cmake
+++ b/Modules/Platform/Windows-MSVC.cmake
@@ -36,28 +36,25 @@ else()
set(CMAKE_CL_NOLOGO "/nologo")
endif()
-set(WIN32 1)
-
-if(CMAKE_SYSTEM_NAME MATCHES "WindowsCE")
- set(CMAKE_CREATE_WIN32_EXE "/subsystem:windowsce /entry:WinMainCRTStartup")
- set(CMAKE_CREATE_CONSOLE_EXE "/subsystem:windowsce /entry:mainACRTStartup")
- set(WINCE 1)
+if(CMAKE_SYSTEM_NAME STREQUAL "WindowsCE")
+ set(CMAKE_CREATE_WIN32_EXE "/entry:WinMainCRTStartup")
+ set(CMAKE_CREATE_CONSOLE_EXE "/entry:mainACRTStartup")
+ set(_PLATFORM_LINK_FLAGS " /subsystem:windowsce")
else()
set(CMAKE_CREATE_WIN32_EXE "/subsystem:windows")
set(CMAKE_CREATE_CONSOLE_EXE "/subsystem:console")
+ set(_PLATFORM_LINK_FLAGS "")
endif()
+set(CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS 1)
if(CMAKE_GENERATOR MATCHES "Visual Studio 6")
set (CMAKE_NO_BUILD_TYPE 1)
+ set(CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS 0) # not implemented for VS6
endif()
if(NOT CMAKE_NO_BUILD_TYPE AND CMAKE_GENERATOR MATCHES "Visual Studio")
set (CMAKE_NO_BUILD_TYPE 1)
endif()
-# make sure to enable languages after setting configuration types
-enable_language(RC)
-set(CMAKE_COMPILE_RESOURCE "rc <FLAGS> /fo<OBJECT> <SOURCE>")
-
if("${CMAKE_GENERATOR}" MATCHES "Visual Studio")
set(MSVC_IDE 1)
else()
@@ -65,7 +62,13 @@ else()
endif()
if(NOT MSVC_VERSION)
- if(CMAKE_C_COMPILER_VERSION)
+ if(CMAKE_C_SIMULATE_VERSION)
+ set(_compiler_version ${CMAKE_C_SIMULATE_VERSION})
+ elseif(CMAKE_CXX_SIMULATE_VERSION)
+ set(_compiler_version ${CMAKE_CXX_SIMULATE_VERSION})
+ elseif(CMAKE_Fortran_SIMULATE_VERSION)
+ set(_compiler_version ${CMAKE_Fortran_SIMULATE_VERSION})
+ elseif(CMAKE_C_COMPILER_VERSION)
set(_compiler_version ${CMAKE_C_COMPILER_VERSION})
else()
set(_compiler_version ${CMAKE_CXX_COMPILER_VERSION})
@@ -79,6 +82,7 @@ if(NOT MSVC_VERSION)
set(MSVC10)
set(MSVC11)
set(MSVC12)
+ set(MSVC14)
set(MSVC60)
set(MSVC70)
set(MSVC71)
@@ -86,7 +90,9 @@ if(NOT MSVC_VERSION)
set(MSVC90)
set(CMAKE_COMPILER_2005)
set(CMAKE_COMPILER_SUPPORTS_PDBTYPE)
- if(NOT "${_compiler_version}" VERSION_LESS 18)
+ if(NOT "${_compiler_version}" VERSION_LESS 19)
+ set(MSVC14 1)
+ elseif(NOT "${_compiler_version}" VERSION_LESS 18)
set(MSVC12 1)
elseif(NOT "${_compiler_version}" VERSION_LESS 17)
set(MSVC11 1)
@@ -123,14 +129,18 @@ endif()
# default to Debug builds
set(CMAKE_BUILD_TYPE_INIT Debug)
+# Compute an architecture family from the architecture id.
+foreach(lang C CXX)
+ set(_MSVC_${lang}_ARCHITECTURE_FAMILY "${MSVC_${lang}_ARCHITECTURE_ID}")
+ if(_MSVC_${lang}_ARCHITECTURE_FAMILY MATCHES "^ARM")
+ set(_MSVC_${lang}_ARCHITECTURE_FAMILY "ARM")
+ elseif(_MSVC_${lang}_ARCHITECTURE_FAMILY MATCHES "^SH")
+ set(_MSVC_${lang}_ARCHITECTURE_FAMILY "SHx")
+ endif()
+endforeach()
+
if(WINCE)
foreach(lang C CXX)
- set(_MSVC_${lang}_ARCHITECTURE_FAMILY "${MSVC_${lang}_ARCHITECTURE_ID}")
- if(_MSVC_${lang}_ARCHITECTURE_FAMILY STREQUAL "THUMB")
- set(_MSVC_${lang}_ARCHITECTURE_FAMILY "ARM")
- elseif(_MSVC_${lang}_ARCHITECTURE_FAMILY MATCHES "^SH")
- set(_MSVC_${lang}_ARCHITECTURE_FAMILY "SHx")
- endif()
string(TOUPPER "${_MSVC_${lang}_ARCHITECTURE_FAMILY}" _MSVC_${lang}_ARCHITECTURE_FAMILY_UPPER)
endforeach()
@@ -142,22 +152,48 @@ if(WINCE)
message(FATAL_ERROR "Invalid Windows CE version: ${CMAKE_SYSTEM_VERSION}")
endif()
- set(_PLATFORM_DEFINES "/D_WIN32_WCE=0x${_CE_VERSION} /DUNDER_CE")
+ set(_PLATFORM_DEFINES "/D_WIN32_WCE=0x${_CE_VERSION} /DUNDER_CE /DWINCE")
set(_PLATFORM_DEFINES_C " /D${_MSVC_C_ARCHITECTURE_FAMILY} /D_${_MSVC_C_ARCHITECTURE_FAMILY_UPPER}_")
set(_PLATFORM_DEFINES_CXX " /D${_MSVC_CXX_ARCHITECTURE_FAMILY} /D_${_MSVC_CXX_ARCHITECTURE_FAMILY_UPPER}_")
set(_RTC1 "")
+ set(_FLAGS_C "")
set(_FLAGS_CXX " /GR /EHsc")
+
+ foreach(lang C CXX)
+ if(_MSVC_${lang}_ARCHITECTURE_FAMILY STREQUAL "ARM")
+ set(_PLATFORM_DEFINES_${lang} "${_PLATFORM_DEFINES_${lang}} /D${MSVC_${lang}_ARCHITECTURE_ID}")
+ if(MSVC_${lang}_ARCHITECTURE_ID MATCHES "^ARMV([45])I$")
+ set(_FLAGS_${lang} "${_FLAGS_${lang}} /QRarch${CMAKE_MATCH_1}T")
+ endif()
+ endif()
+ endforeach()
+
set(CMAKE_C_STANDARD_LIBRARIES_INIT "coredll.lib ole32.lib oleaut32.lib uuid.lib commctrl.lib")
set(CMAKE_EXE_LINKER_FLAGS_INIT "${CMAKE_EXE_LINKER_FLAGS_INIT} /NODEFAULTLIB:libc.lib /NODEFAULTLIB:oldnames.lib")
if (MSVC_VERSION LESS 1600)
set(CMAKE_C_STANDARD_LIBRARIES_INIT "${CMAKE_C_STANDARD_LIBRARIES_INIT} corelibc.lib")
endif ()
+elseif(WINDOWS_PHONE OR WINDOWS_STORE)
+ set(_PLATFORM_DEFINES "/DWIN32")
+ set(_FLAGS_C " /DUNICODE /D_UNICODE")
+ set(_FLAGS_CXX " /DUNICODE /D_UNICODE /GR /EHsc")
+ if(WINDOWS_STORE AND MSVC_VERSION GREATER 1899)
+ set(CMAKE_C_STANDARD_LIBRARIES_INIT "WindowsApp.lib")
+ elseif(WINDOWS_PHONE)
+ set(CMAKE_C_STANDARD_LIBRARIES_INIT "WindowsPhoneCore.lib RuntimeObject.lib PhoneAppModelHost.lib")
+ elseif(_MSVC_C_ARCHITECTURE_FAMILY STREQUAL "ARM" OR _MSVC_CXX_ARCHITECTURE_FAMILY STREQUAL "ARM")
+ set(CMAKE_C_STANDARD_LIBRARIES_INIT "kernel32.lib user32.lib")
+ else()
+ set(CMAKE_C_STANDARD_LIBRARIES_INIT "kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib")
+ endif()
else()
set(_PLATFORM_DEFINES "/DWIN32")
- if(MSVC_VERSION GREATER 1310)
+ if(_MSVC_C_ARCHITECTURE_FAMILY STREQUAL "ARM" OR _MSVC_CXX_ARCHITECTURE_FAMILY STREQUAL "ARM")
+ set(CMAKE_C_STANDARD_LIBRARIES_INIT "kernel32.lib user32.lib")
+ elseif(MSVC_VERSION GREATER 1310)
set(_RTC1 "/RTC1")
set(_FLAGS_CXX " /GR /EHsc")
set(CMAKE_C_STANDARD_LIBRARIES_INIT "kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib")
@@ -178,20 +214,38 @@ set(CMAKE_CXX_STANDARD_LIBRARIES_INIT "${CMAKE_C_STANDARD_LIBRARIES_INIT}")
# executable linker flags
set (CMAKE_LINK_DEF_FILE_FLAG "/DEF:")
# set the machine type
-set(_MACHINE_ARCH_FLAG ${MSVC_C_ARCHITECTURE_ID})
-if(NOT _MACHINE_ARCH_FLAG)
- set(_MACHINE_ARCH_FLAG ${MSVC_CXX_ARCHITECTURE_ID})
+if(MSVC_C_ARCHITECTURE_ID)
+ if(MSVC_C_ARCHITECTURE_ID MATCHES "^ARMV.I")
+ set(_MACHINE_ARCH_FLAG "/machine:THUMB")
+ elseif(_MSVC_C_ARCHITECTURE_FAMILY STREQUAL "ARM")
+ set(_MACHINE_ARCH_FLAG "/machine:ARM")
+ else()
+ set(_MACHINE_ARCH_FLAG "/machine:${MSVC_C_ARCHITECTURE_ID}")
+ endif()
+elseif(MSVC_CXX_ARCHITECTURE_ID)
+ if(MSVC_CXX_ARCHITECTURE_ID MATCHES "^ARMV.I")
+ set(_MACHINE_ARCH_FLAG "/machine:THUMB")
+ elseif(_MSVC_CXX_ARCHITECTURE_FAMILY STREQUAL "ARM")
+ set(_MACHINE_ARCH_FLAG "/machine:ARM")
+ else()
+ set(_MACHINE_ARCH_FLAG "/machine:${MSVC_CXX_ARCHITECTURE_ID}")
+ endif()
+elseif(MSVC_Fortran_ARCHITECTURE_ID)
+ set(_MACHINE_ARCH_FLAG "/machine:${MSVC_Fortran_ARCHITECTURE_ID}")
endif()
-set (CMAKE_EXE_LINKER_FLAGS_INIT
- "${CMAKE_EXE_LINKER_FLAGS_INIT} /machine:${_MACHINE_ARCH_FLAG}")
+set(CMAKE_EXE_LINKER_FLAGS_INIT "${CMAKE_EXE_LINKER_FLAGS_INIT} ${_MACHINE_ARCH_FLAG}")
+set(CMAKE_STATIC_LINKER_FLAGS_INIT "${CMAKE_STATIC_LINKER_FLAGS_INIT} ${_MACHINE_ARCH_FLAG}")
+unset(_MACHINE_ARCH_FLAG)
# add /debug and /INCREMENTAL:YES to DEBUG and RELWITHDEBINFO also add pdbtype
# on versions that support it
set( MSVC_INCREMENTAL_YES_FLAG "")
-if(NOT MSVC_INCREMENTAL_DEFAULT)
- set( MSVC_INCREMENTAL_YES_FLAG "/INCREMENTAL:YES")
-else()
- set( MSVC_INCREMENTAL_YES_FLAG "/INCREMENTAL" )
+if(NOT WINDOWS_PHONE AND NOT WINDOWS_STORE)
+ if(NOT MSVC_INCREMENTAL_DEFAULT)
+ set( MSVC_INCREMENTAL_YES_FLAG "/INCREMENTAL:YES")
+ else()
+ set( MSVC_INCREMENTAL_YES_FLAG "/INCREMENTAL" )
+ endif()
endif()
if (CMAKE_COMPILER_SUPPORTS_PDBTYPE)
@@ -209,7 +263,7 @@ set(CMAKE_EXE_LINKER_FLAGS_RELEASE_INIT "/INCREMENTAL:NO")
# shared linker flags
set (CMAKE_SHARED_LINKER_FLAGS_INIT ${CMAKE_EXE_LINKER_FLAGS_INIT})
set (CMAKE_SHARED_LINKER_FLAGS_DEBUG_INIT ${CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT})
-set (CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO_INIT ${CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT})
+set (CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO_INIT ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO_INIT})
set (CMAKE_SHARED_LINKER_FLAGS_RELEASE_INIT ${CMAKE_EXE_LINKER_FLAGS_RELEASE_INIT})
set (CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL_INIT ${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL_INIT})
# module linker flags
@@ -220,31 +274,43 @@ set (CMAKE_MODULE_LINKER_FLAGS_RELEASE_INIT ${CMAKE_EXE_LINKER_FLAGS_RELEASE_INI
set (CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL_INIT ${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL_INIT})
macro(__windows_compiler_msvc lang)
- if(NOT "${CMAKE_${lang}_COMPILER_VERSION}" VERSION_LESS 14)
+ if(NOT MSVC_VERSION LESS 1400)
# for 2005 make sure the manifest is put in the dll with mt
- set(_CMAKE_VS_LINK_DLL "<CMAKE_COMMAND> -E vs_link_dll ")
- set(_CMAKE_VS_LINK_EXE "<CMAKE_COMMAND> -E vs_link_exe ")
+ set(_CMAKE_VS_LINK_DLL "<CMAKE_COMMAND> -E vs_link_dll --intdir=<OBJECT_DIR> --manifests <MANIFESTS> -- ")
+ set(_CMAKE_VS_LINK_EXE "<CMAKE_COMMAND> -E vs_link_exe --intdir=<OBJECT_DIR> --manifests <MANIFESTS> -- ")
endif()
set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
- "${_CMAKE_VS_LINK_DLL}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /dll /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <LINK_FLAGS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
+ "${_CMAKE_VS_LINK_DLL}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /dll /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
set(CMAKE_${lang}_CREATE_SHARED_MODULE ${CMAKE_${lang}_CREATE_SHARED_LIBRARY})
set(CMAKE_${lang}_CREATE_STATIC_LIBRARY "<CMAKE_LINKER> /lib ${CMAKE_CL_NOLOGO} <LINK_FLAGS> /out:<TARGET> <OBJECTS> ")
set(CMAKE_${lang}_COMPILE_OBJECT
- "<CMAKE_${lang}_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO}${_COMPILE_${lang}} <FLAGS> <DEFINES> /Fo<OBJECT> /Fd<OBJECT_DIR>/${_FS_${lang}} -c <SOURCE>${CMAKE_END_TEMP_FILE}")
+ "<CMAKE_${lang}_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO}${_COMPILE_${lang}} <DEFINES> <INCLUDES> <FLAGS> /Fo<OBJECT> /Fd<TARGET_COMPILE_PDB>${_FS_${lang}} -c <SOURCE>${CMAKE_END_TEMP_FILE}")
set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE
- "<CMAKE_${lang}_COMPILER> > <PREPROCESSED_SOURCE> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO}${_COMPILE_${lang}} <FLAGS> <DEFINES> -E <SOURCE>${CMAKE_END_TEMP_FILE}")
+ "<CMAKE_${lang}_COMPILER> > <PREPROCESSED_SOURCE> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO}${_COMPILE_${lang}} <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE>${CMAKE_END_TEMP_FILE}")
set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE
- "<CMAKE_${lang}_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO}${_COMPILE_${lang}} <FLAGS> <DEFINES> /FoNUL /FAs /Fa<ASSEMBLY_SOURCE> /c <SOURCE>${CMAKE_END_TEMP_FILE}")
+ "<CMAKE_${lang}_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO}${_COMPILE_${lang}} <DEFINES> <INCLUDES> <FLAGS> /FoNUL /FAs /Fa<ASSEMBLY_SOURCE> /c <SOURCE>${CMAKE_END_TEMP_FILE}")
set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_OBJECTS 1)
set(CMAKE_${lang}_LINK_EXECUTABLE
- "${_CMAKE_VS_LINK_EXE}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
+ "${_CMAKE_VS_LINK_EXE}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
set(CMAKE_${lang}_FLAGS_INIT "${_PLATFORM_DEFINES}${_PLATFORM_DEFINES_${lang}} /D_WINDOWS /W3${_FLAGS_${lang}}")
set(CMAKE_${lang}_FLAGS_DEBUG_INIT "/D_DEBUG /MDd /Zi /Ob0 /Od ${_RTC1}")
set(CMAKE_${lang}_FLAGS_RELEASE_INIT "/MD /O2 /Ob2 /D NDEBUG")
set(CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT "/MD /Zi /O2 /Ob1 /D NDEBUG")
set(CMAKE_${lang}_FLAGS_MINSIZEREL_INIT "/MD /O1 /Ob1 /D NDEBUG")
+ set(CMAKE_${lang}_LINKER_SUPPORTS_PDB ON)
+ set(CMAKE_NINJA_DEPTYPE_${lang} msvc)
+
+ if(NOT CMAKE_RC_COMPILER_INIT)
+ set(CMAKE_RC_COMPILER_INIT rc)
+ endif()
+ if(NOT CMAKE_RC_FLAGS_INIT)
+ set(CMAKE_RC_FLAGS_INIT "${_PLATFORM_DEFINES} ${_PLATFORM_DEFINES_${lang}}")
+ endif()
+
+ enable_language(RC)
+ set(CMAKE_NINJA_CMCLDEPS_RC 1)
endmacro()
diff --git a/Modules/Platform/Windows-df.cmake b/Modules/Platform/Windows-df.cmake
index 8dfb61057..0beba732d 100644
--- a/Modules/Platform/Windows-df.cmake
+++ b/Modules/Platform/Windows-df.cmake
@@ -24,9 +24,6 @@ set(CMAKE_Fortran_CREATE_STATIC_LIBRARY "lib ${CMAKE_CL_NOLOGO} <LINK_FLAGS> /o
set(CMAKE_Fortran_COMPILE_OBJECT
"<CMAKE_Fortran_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO} /object:<OBJECT> <FLAGS> /compile_only <SOURCE>${CMAKE_END_TEMP_FILE}")
-set(CMAKE_COMPILE_RESOURCE "rc <FLAGS> /fo<OBJECT> <SOURCE>")
-
-set(CMAKE_${lang}_COMPILER_LINKER_OPTION_FLAG_EXECUTABLE "/link")
set(CMAKE_Fortran_LINK_EXECUTABLE
"<CMAKE_Fortran_COMPILER> ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} <FLAGS> /exe:<TARGET> <OBJECTS> /link <CMAKE_Fortran_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
@@ -63,7 +60,7 @@ endif ()
set (CMAKE_SHARED_LINKER_FLAGS_INIT ${CMAKE_EXE_LINKER_FLAGS_INIT})
set (CMAKE_SHARED_LINKER_FLAGS_DEBUG_INIT ${CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT})
-set (CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO_INIT ${CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT})
+set (CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO_INIT ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO_INIT})
set (CMAKE_MODULE_LINKER_FLAGS_INIT ${CMAKE_SHARED_LINKER_FLAGS_INIT})
set (CMAKE_MODULE_LINKER_FLAGS_DEBUG_INIT ${CMAKE_SHARED_LINKER_FLAGS_DEBUG_INIT})
set (CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO_INIT ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO_INIT})
diff --git a/Modules/Platform/Windows-wcl386.cmake b/Modules/Platform/Windows-wcl386.cmake
index 8a03b2972..3bc54449e 100644
--- a/Modules/Platform/Windows-wcl386.cmake
+++ b/Modules/Platform/Windows-wcl386.cmake
@@ -12,13 +12,15 @@ else()
set(CMAKE_LIB_QUIET "-q")
endif()
+set(CMAKE_EXE_LINKER_FLAGS_INIT)
set(CMAKE_CREATE_WIN32_EXE "system nt_win" )
set(CMAKE_CREATE_CONSOLE_EXE "system nt" )
-
-set (CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT "debug all" )
-set (CMAKE_SHARED_LINKER_FLAGS_DEBUG_INIT "debug all" )
-set (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO_INIT "debug all" )
-set (CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO_INIT "debug all" )
+set(CMAKE_SHARED_LINKER_FLAGS_INIT "system nt_dll")
+set(CMAKE_MODULE_LINKER_FLAGS_INIT "system nt_dll")
+foreach(type SHARED MODULE EXE)
+ set(CMAKE_${type}_LINKER_FLAGS_DEBUG_INIT "debug all opt map")
+ set(CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO_INIT "debug all opt map")
+endforeach()
set(CMAKE_C_COMPILE_OPTIONS_DLL "-bd") # Note: This variable is a ';' separated list
set(CMAKE_SHARED_LIBRARY_C_FLAGS "-bd") # ... while this is a space separated string.
@@ -26,50 +28,54 @@ set(CMAKE_SHARED_LIBRARY_C_FLAGS "-bd") # ... while this is a space separated st
set(CMAKE_RC_COMPILER "rc" )
set(CMAKE_BUILD_TYPE_INIT Debug)
-set (CMAKE_CXX_FLAGS_INIT "-w=3 -xs")
-set (CMAKE_CXX_FLAGS_DEBUG_INIT "-br -bm -d2")
-set (CMAKE_CXX_FLAGS_MINSIZEREL_INIT "-br -bm -os -dNDEBUG")
-set (CMAKE_CXX_FLAGS_RELEASE_INIT "-br -bm -ot -dNDEBUG")
-set (CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-br -bm -d2 -ot -dNDEBUG")
-set (CMAKE_C_FLAGS_INIT "-w=3 ")
-set (CMAKE_C_FLAGS_DEBUG_INIT "-br -bm -d2 -od")
-set (CMAKE_C_FLAGS_MINSIZEREL_INIT "-br -bm -os -dNDEBUG")
-set (CMAKE_C_FLAGS_RELEASE_INIT "-br -bm -ot -dNDEBUG")
-set (CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-br -bm -d2 -ot -dNDEBUG")
-set (CMAKE_C_STANDARD_LIBRARIES_INIT "library clbrdll.lib library plbrdll.lib library kernel32.lib library user32.lib library gdi32.lib library winspool.lib library comdlg32.lib library advapi32.lib library shell32.lib library ole32.lib library oleaut32.lib library uuid.lib library odbc32.lib library odbccp32.lib")
-set (CMAKE_CXX_STANDARD_LIBRARIES_INIT "${CMAKE_C_STANDARD_LIBRARIES_INIT}")
+
+# single/multi-threaded /-bm
+# static/DLL run-time libraries /-br
+# default is setup for multi-threaded + DLL run-time libraries
+set (CMAKE_C_FLAGS_INIT "-bt=nt -w3 -dWIN32 -br -bm")
+set (CMAKE_CXX_FLAGS_INIT "-bt=nt -xs -w3 -dWIN32 -br -bm")
+foreach(lang C CXX)
+ set (CMAKE_${lang}_FLAGS_DEBUG_INIT "-d2")
+ set (CMAKE_${lang}_FLAGS_MINSIZEREL_INIT "-s -os -d0 -dNDEBUG")
+ set (CMAKE_${lang}_FLAGS_RELEASE_INIT "-s -ot -d0 -dNDEBUG")
+ set (CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT "-s -ot -d1 -dNDEBUG")
+endforeach()
+
+foreach(type CREATE_SHARED_LIBRARY CREATE_SHARED_MODULE LINK_EXECUTABLE)
+ set(CMAKE_C_${type}_USE_WATCOM_QUOTE 1)
+ set(CMAKE_CXX_${type}_USE_WATCOM_QUOTE 1)
+endforeach()
set(CMAKE_C_CREATE_IMPORT_LIBRARY
- "wlib -c -q -n -b <TARGET_IMPLIB> +'<TARGET_UNQUOTED>'")
+ "wlib -c -q -n -b <TARGET_IMPLIB> +<TARGET_QUOTED>")
set(CMAKE_CXX_CREATE_IMPORT_LIBRARY ${CMAKE_C_CREATE_IMPORT_LIBRARY})
set(CMAKE_C_LINK_EXECUTABLE
- "wlink ${CMAKE_START_TEMP_FILE} ${CMAKE_WLINK_QUIET} name '<TARGET_UNQUOTED>' <LINK_FLAGS> option caseexact file {<OBJECTS>} <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
+ "wlink ${CMAKE_START_TEMP_FILE} ${CMAKE_WLINK_QUIET} name <TARGET> <LINK_FLAGS> file {<OBJECTS>} <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
set(CMAKE_CXX_LINK_EXECUTABLE ${CMAKE_C_LINK_EXECUTABLE})
# compile a C++ file into an object file
set(CMAKE_CXX_COMPILE_OBJECT
- "<CMAKE_CXX_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_WCL_QUIET} <FLAGS> -dWIN32 -d+ <DEFINES> -fo<OBJECT> -c -cc++ <SOURCE>${CMAKE_END_TEMP_FILE}")
+ "<CMAKE_CXX_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_WCL_QUIET} -d+ <DEFINES> <INCLUDES> <FLAGS> -fo<OBJECT> -c -cc++ <SOURCE>${CMAKE_END_TEMP_FILE}")
# compile a C file into an object file
set(CMAKE_C_COMPILE_OBJECT
- "<CMAKE_C_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_WCL_QUIET} <FLAGS> -dWIN32 -d+ <DEFINES> -fo<OBJECT> -c -cc <SOURCE>${CMAKE_END_TEMP_FILE}")
+ "<CMAKE_C_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_WCL_QUIET} -d+ <DEFINES> <INCLUDES> <FLAGS> -fo<OBJECT> -c -cc <SOURCE>${CMAKE_END_TEMP_FILE}")
# preprocess a C source file
set(CMAKE_C_CREATE_PREPROCESSED_SOURCE
- "<CMAKE_C_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_WCL_QUIET} <FLAGS> -dWIN32 -d+ <DEFINES> -fo<PREPROCESSED_SOURCE> -pl -cc <SOURCE>${CMAKE_END_TEMP_FILE}")
+ "<CMAKE_C_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_WCL_QUIET} -d+ <DEFINES> <INCLUDES> <FLAGS> -fo<PREPROCESSED_SOURCE> -pl -cc <SOURCE>${CMAKE_END_TEMP_FILE}")
# preprocess a C++ source file
set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE
- "<CMAKE_CXX_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_WCL_QUIET} <FLAGS> -dWIN32 -d+ <DEFINES> -fo<PREPROCESSED_SOURCE> -pl -cc++ <SOURCE>${CMAKE_END_TEMP_FILE}")
+ "<CMAKE_CXX_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_WCL_QUIET} -d+ <DEFINES> <INCLUDES> <FLAGS> -fo<PREPROCESSED_SOURCE> -pl -cc++ <SOURCE>${CMAKE_END_TEMP_FILE}")
-set(CMAKE_CXX_CREATE_SHARED_MODULE
- "wlink ${CMAKE_START_TEMP_FILE} system nt_dll ${CMAKE_WLINK_QUIET} name '<TARGET_UNQUOTED>' <LINK_FLAGS> option caseexact file {<OBJECTS>} <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
set(CMAKE_CXX_CREATE_SHARED_LIBRARY
- ${CMAKE_CXX_CREATE_SHARED_MODULE}
- ${CMAKE_CXX_CREATE_IMPORT_LIBRARY})
+ "wlink ${CMAKE_START_TEMP_FILE} ${CMAKE_WLINK_QUIET} name <TARGET> <LINK_FLAGS> option implib=<TARGET_IMPLIB> file {<OBJECTS>} <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
+string(REPLACE " option implib=<TARGET_IMPLIB>" ""
+ CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_LIBRARY}")
# create a C shared library
set(CMAKE_C_CREATE_SHARED_LIBRARY ${CMAKE_CXX_CREATE_SHARED_LIBRARY})
@@ -78,7 +84,7 @@ set(CMAKE_C_CREATE_SHARED_LIBRARY ${CMAKE_CXX_CREATE_SHARED_LIBRARY})
set(CMAKE_C_CREATE_SHARED_MODULE ${CMAKE_CXX_CREATE_SHARED_MODULE})
# create a C++ static library
-set(CMAKE_CXX_CREATE_STATIC_LIBRARY "wlib ${CMAKE_LIB_QUIET} -c -n -b '<TARGET_UNQUOTED>' <LINK_FLAGS> <OBJECTS> ")
+set(CMAKE_CXX_CREATE_STATIC_LIBRARY "wlib ${CMAKE_LIB_QUIET} -c -n -b <TARGET_QUOTED> <LINK_FLAGS> <OBJECTS> ")
# create a C static library
set(CMAKE_C_CREATE_STATIC_LIBRARY ${CMAKE_CXX_CREATE_STATIC_LIBRARY})
@@ -87,23 +93,27 @@ if(NOT _CMAKE_WATCOM_VERSION)
set(_CMAKE_WATCOM_VERSION 1)
if(CMAKE_C_COMPILER_VERSION)
set(_compiler_version ${CMAKE_C_COMPILER_VERSION})
+ set(_compiler_id ${CMAKE_C_COMPILER_ID})
else()
set(_compiler_version ${CMAKE_CXX_COMPILER_VERSION})
+ set(_compiler_id ${CMAKE_CXX_COMPILER_ID})
endif()
set(WATCOM16)
set(WATCOM17)
set(WATCOM18)
set(WATCOM19)
- if("${_compiler_version}" LESS 12.70)
- set(WATCOM16 1)
- endif()
- if("${_compiler_version}" EQUAL 12.70)
- set(WATCOM17 1)
- endif()
- if("${_compiler_version}" EQUAL 12.80)
- set(WATCOM18 1)
- endif()
- if("${_compiler_version}" EQUAL 12.90)
- set(WATCOM19 1)
+ if("${_compiler_id}" STREQUAL "OpenWatcom")
+ if("${_compiler_version}" VERSION_LESS 1.7)
+ set(WATCOM16 1)
+ endif()
+ if("${_compiler_version}" VERSION_EQUAL 1.7)
+ set(WATCOM17 1)
+ endif()
+ if("${_compiler_version}" VERSION_EQUAL 1.8)
+ set(WATCOM18 1)
+ endif()
+ if("${_compiler_version}" VERSION_EQUAL 1.9)
+ set(WATCOM19 1)
+ endif()
endif()
endif()
diff --git a/Modules/Platform/Windows-windres.cmake b/Modules/Platform/Windows-windres.cmake
index 01d6be3df..7d787dddf 100644
--- a/Modules/Platform/Windows-windres.cmake
+++ b/Modules/Platform/Windows-windres.cmake
@@ -1 +1 @@
-set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> -O coff <FLAGS> <DEFINES> <SOURCE> <OBJECT>")
+set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> -O coff <DEFINES> <INCLUDES> <FLAGS> <SOURCE> <OBJECT>")
diff --git a/Modules/Platform/Windows.cmake b/Modules/Platform/Windows.cmake
index b158a9dfb..9a937a7e8 100644
--- a/Modules/Platform/Windows.cmake
+++ b/Modules/Platform/Windows.cmake
@@ -1,5 +1,13 @@
set(WIN32 1)
+if(CMAKE_SYSTEM_NAME STREQUAL "WindowsCE")
+ set(WINCE 1)
+elseif(CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone")
+ set(WINDOWS_PHONE 1)
+elseif(CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
+ set(WINDOWS_STORE 1)
+endif()
+
set(CMAKE_STATIC_LIBRARY_PREFIX "")
set(CMAKE_STATIC_LIBRARY_SUFFIX ".lib")
set(CMAKE_SHARED_LIBRARY_PREFIX "") # lib
diff --git a/Modules/Platform/WindowsCE-MSVC.cmake b/Modules/Platform/WindowsCE-MSVC.cmake
deleted file mode 100644
index d28b4aba0..000000000
--- a/Modules/Platform/WindowsCE-MSVC.cmake
+++ /dev/null
@@ -1 +0,0 @@
-include(Platform/Windows-MSVC)
diff --git a/Modules/Platform/WindowsPaths.cmake b/Modules/Platform/WindowsPaths.cmake
index fc921d793..eafa8fa1d 100644
--- a/Modules/Platform/WindowsPaths.cmake
+++ b/Modules/Platform/WindowsPaths.cmake
@@ -28,56 +28,51 @@ set(__WINDOWS_PATHS_INCLUDED 1)
# Windows 64-bit Binary:
# ENV{ProgramFiles(x86)} = [C:\Program Files (x86)]
# ENV{ProgramFiles} = [C:\Program Files]
-# ENV{ProgramW6432} = <not set>
-# (executed from cygwin):
-# ENV{ProgramFiles(x86)} = <not set>
-# ENV{ProgramFiles} = [C:\Program Files]
-# ENV{ProgramW6432} = <not set>
+# ENV{ProgramW6432} = [C:\Program Files] or <not set>
#
-# Windows 32-bit Binary:
+# Windows 32-bit Binary on 64-bit Windows:
# ENV{ProgramFiles(x86)} = [C:\Program Files (x86)]
# ENV{ProgramFiles} = [C:\Program Files (x86)]
# ENV{ProgramW6432} = [C:\Program Files]
-# (executed from cygwin):
-# ENV{ProgramFiles(x86)} = <not set>
-# ENV{ProgramFiles} = [C:\Program Files (x86)]
-# ENV{ProgramW6432} = [C:\Program Files]
-if(DEFINED "ENV{ProgramW6432}")
- # 32-bit binary on 64-bit windows.
- # The 64-bit program files are in ProgramW6432.
- list(APPEND CMAKE_SYSTEM_PREFIX_PATH "$ENV{ProgramW6432}")
-
- # The 32-bit program files are in ProgramFiles.
- if(DEFINED "ENV{ProgramFiles}")
- list(APPEND CMAKE_SYSTEM_PREFIX_PATH "$ENV{ProgramFiles}")
+set(_programfiles "")
+foreach(v "ProgramW6432" "ProgramFiles" "ProgramFiles(x86)")
+ if(DEFINED "ENV{${v}}")
+ file(TO_CMAKE_PATH "$ENV{${v}}" _env_programfiles)
+ list(APPEND _programfiles "${_env_programfiles}")
+ unset(_env_programfiles)
endif()
-else()
- # 64-bit binary, or 32-bit binary on 32-bit windows.
- if(DEFINED "ENV{ProgramFiles}")
- list(APPEND CMAKE_SYSTEM_PREFIX_PATH "$ENV{ProgramFiles}")
- endif()
- if(DEFINED "ENV{ProgramFiles(x86)}")
- # 64-bit binary. 32-bit program files are in ProgramFiles(x86).
- list(APPEND CMAKE_SYSTEM_PREFIX_PATH "$ENV{ProgramFiles(x86)}")
- elseif(DEFINED "ENV{SystemDrive}")
- # Guess the 32-bit program files location.
- if(EXISTS "$ENV{SystemDrive}/Program Files (x86)")
- list(APPEND CMAKE_SYSTEM_PREFIX_PATH
- "$ENV{SystemDrive}/Program Files (x86)")
+endforeach()
+if(DEFINED "ENV{SystemDrive}")
+ foreach(d "Program Files" "Program Files (x86)")
+ if(EXISTS "$ENV{SystemDrive}/${d}")
+ list(APPEND _programfiles "$ENV{SystemDrive}/${d}")
endif()
- endif()
+ endforeach()
+endif()
+if(_programfiles)
+ list(REMOVE_DUPLICATES _programfiles)
+ list(APPEND CMAKE_SYSTEM_PREFIX_PATH ${_programfiles})
endif()
+unset(_programfiles)
# Add the CMake install location.
get_filename_component(_CMAKE_INSTALL_DIR "${CMAKE_ROOT}" PATH)
get_filename_component(_CMAKE_INSTALL_DIR "${_CMAKE_INSTALL_DIR}" PATH)
list(APPEND CMAKE_SYSTEM_PREFIX_PATH "${_CMAKE_INSTALL_DIR}")
-# Add other locations.
-list(APPEND CMAKE_SYSTEM_PREFIX_PATH
- # Project install destination.
- "${CMAKE_INSTALL_PREFIX}"
- )
+if (NOT CMAKE_FIND_NO_INSTALL_PREFIX)
+ # Add other locations.
+ list(APPEND CMAKE_SYSTEM_PREFIX_PATH
+ # Project install destination.
+ "${CMAKE_INSTALL_PREFIX}"
+ )
+ if (CMAKE_STAGING_PREFIX)
+ list(APPEND CMAKE_SYSTEM_PREFIX_PATH
+ # User-supplied staging prefix.
+ "${CMAKE_STAGING_PREFIX}"
+ )
+ endif()
+endif()
if(CMAKE_CROSSCOMPILING AND NOT CMAKE_HOST_SYSTEM_NAME MATCHES "Windows")
# MinGW (useful when cross compiling from linux with CMAKE_FIND_ROOT_PATH set)
@@ -88,8 +83,17 @@ list(APPEND CMAKE_SYSTEM_INCLUDE_PATH
)
# mingw can also link against dlls which can also be in /bin, so list this too
+if (NOT CMAKE_FIND_NO_INSTALL_PREFIX)
+ list(APPEND CMAKE_SYSTEM_LIBRARY_PATH
+ "${CMAKE_INSTALL_PREFIX}/bin"
+ )
+ if (CMAKE_STAGING_PREFIX)
+ list(APPEND CMAKE_SYSTEM_LIBRARY_PATH
+ "${CMAKE_STAGING_PREFIX}/bin"
+ )
+ endif()
+endif()
list(APPEND CMAKE_SYSTEM_LIBRARY_PATH
- "${CMAKE_INSTALL_PREFIX}/bin"
"${_CMAKE_INSTALL_DIR}/bin"
/bin
)
diff --git a/Modules/Platform/WindowsPhone-MSVC-C.cmake b/Modules/Platform/WindowsPhone-MSVC-C.cmake
new file mode 100644
index 000000000..ce8060bed
--- /dev/null
+++ b/Modules/Platform/WindowsPhone-MSVC-C.cmake
@@ -0,0 +1 @@
+include(Platform/Windows-MSVC-C)
diff --git a/Modules/Platform/WindowsPhone-MSVC-CXX.cmake b/Modules/Platform/WindowsPhone-MSVC-CXX.cmake
new file mode 100644
index 000000000..281eadc10
--- /dev/null
+++ b/Modules/Platform/WindowsPhone-MSVC-CXX.cmake
@@ -0,0 +1 @@
+include(Platform/Windows-MSVC-CXX)
diff --git a/Modules/Platform/WindowsPhone.cmake b/Modules/Platform/WindowsPhone.cmake
new file mode 100644
index 000000000..65b2eaed4
--- /dev/null
+++ b/Modules/Platform/WindowsPhone.cmake
@@ -0,0 +1 @@
+include(Platform/Windows)
diff --git a/Modules/Platform/WindowsStore-MSVC-C.cmake b/Modules/Platform/WindowsStore-MSVC-C.cmake
new file mode 100644
index 000000000..ce8060bed
--- /dev/null
+++ b/Modules/Platform/WindowsStore-MSVC-C.cmake
@@ -0,0 +1 @@
+include(Platform/Windows-MSVC-C)
diff --git a/Modules/Platform/WindowsStore-MSVC-CXX.cmake b/Modules/Platform/WindowsStore-MSVC-CXX.cmake
new file mode 100644
index 000000000..281eadc10
--- /dev/null
+++ b/Modules/Platform/WindowsStore-MSVC-CXX.cmake
@@ -0,0 +1 @@
+include(Platform/Windows-MSVC-CXX)
diff --git a/Modules/Platform/WindowsStore.cmake b/Modules/Platform/WindowsStore.cmake
new file mode 100644
index 000000000..65b2eaed4
--- /dev/null
+++ b/Modules/Platform/WindowsStore.cmake
@@ -0,0 +1 @@
+include(Platform/Windows)
diff --git a/Modules/Platform/eCos.cmake b/Modules/Platform/eCos.cmake
index a20382692..e1279ef22 100644
--- a/Modules/Platform/eCos.cmake
+++ b/Modules/Platform/eCos.cmake
@@ -28,7 +28,7 @@ include(Platform/UnixPaths)
# eCos can be built only with gcc
get_property(_IN_TC GLOBAL PROPERTY IN_TRY_COMPILE)
-if(CMAKE_C_COMPILER AND NOT "${CMAKE_C_COMPILER_ID}" MATCHES "GNU" AND NOT _IN_TC)
+if(CMAKE_C_COMPILER AND NOT CMAKE_C_COMPILER_ID MATCHES "GNU" AND NOT _IN_TC)
message(FATAL_ERROR "GNU gcc is required for eCos")
endif()
if(CMAKE_CXX_COMPILER AND NOT "${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU" AND NOT _IN_TC)
diff --git a/Modules/ProcessorCount.cmake b/Modules/ProcessorCount.cmake
index 0d1dfda16..2c5d5aeb1 100644
--- a/Modules/ProcessorCount.cmake
+++ b/Modules/ProcessorCount.cmake
@@ -1,30 +1,41 @@
-# - ProcessorCount(var)
+#.rst:
+# ProcessorCount
+# --------------
+#
+# ProcessorCount(var)
+#
# Determine the number of processors/cores and save value in ${var}
#
-# Sets the variable named ${var} to the number of physical cores available on
-# the machine if the information can be determined. Otherwise it is set to 0.
-# Currently this functionality is implemented for AIX, cygwin, FreeBSD, HPUX,
-# IRIX, Linux, Mac OS X, QNX, Sun and Windows.
+# Sets the variable named ${var} to the number of physical cores
+# available on the machine if the information can be determined.
+# Otherwise it is set to 0. Currently this functionality is implemented
+# for AIX, cygwin, FreeBSD, HPUX, IRIX, Linux, Mac OS X, QNX, Sun and
+# Windows.
#
# This function is guaranteed to return a positive integer (>=1) if it
-# succeeds. It returns 0 if there's a problem determining the processor count.
+# succeeds. It returns 0 if there's a problem determining the processor
+# count.
#
# Example use, in a ctest -S dashboard script:
#
-# include(ProcessorCount)
-# ProcessorCount(N)
-# if(NOT N EQUAL 0)
-# set(CTEST_BUILD_FLAGS -j${N})
-# set(ctest_test_args ${ctest_test_args} PARALLEL_LEVEL ${N})
-# endif()
+# ::
+#
+# include(ProcessorCount)
+# ProcessorCount(N)
+# if(NOT N EQUAL 0)
+# set(CTEST_BUILD_FLAGS -j${N})
+# set(ctest_test_args ${ctest_test_args} PARALLEL_LEVEL ${N})
+# endif()
#
-# This function is intended to offer an approximation of the value of the
-# number of compute cores available on the current machine, such that you
-# may use that value for parallel building and parallel testing. It is meant
-# to help utilize as much of the machine as seems reasonable. Of course,
-# knowledge of what else might be running on the machine simultaneously
-# should be used when deciding whether to request a machine's full capacity
-# all for yourself.
+#
+#
+# This function is intended to offer an approximation of the value of
+# the number of compute cores available on the current machine, such
+# that you may use that value for parallel building and parallel
+# testing. It is meant to help utilize as much of the machine as seems
+# reasonable. Of course, knowledge of what else might be running on the
+# machine simultaneously should be used when deciding whether to request
+# a machine's full capacity all for yourself.
# A more reliable way might be to compile a small C program that uses the CPUID
# instruction, but that again requires compiler support or compiling assembler
@@ -92,7 +103,23 @@ function(ProcessorCount var)
OUTPUT_VARIABLE machinfo_output)
string(REGEX MATCHALL "Number of CPUs = ([0-9]+)" procs "${machinfo_output}")
set(count "${CMAKE_MATCH_1}")
+ if(NOT count)
+ string(REGEX MATCHALL "([0-9]+) logical processors" procs "${machinfo_output}")
+ set(count "${CMAKE_MATCH_1}")
+ endif()
#message("ProcessorCount: trying machinfo '${ProcessorCount_cmd_machinfo}'")
+ else()
+ find_program(ProcessorCount_cmd_mpsched mpsched)
+ mark_as_advanced(ProcessorCount_cmd_mpsched)
+ if(ProcessorCount_cmd_mpsched)
+ execute_process(COMMAND ${ProcessorCount_cmd_mpsched} -s
+ OUTPUT_QUIET
+ ERROR_STRIP_TRAILING_WHITESPACE
+ ERROR_VARIABLE mpsched_output)
+ string(REGEX MATCHALL "Processor Count *: *([0-9]+)" procs "${mpsched_output}")
+ set(count "${CMAKE_MATCH_1}")
+ #message("ProcessorCount: trying mpsched -s '${ProcessorCount_cmd_mpsched}'")
+ endif()
endif()
endif()
@@ -144,17 +171,30 @@ function(ProcessorCount var)
endif()
if(NOT count)
- # Sun (systems where uname -X emits "NumCPU" in its output):
- find_program(ProcessorCount_cmd_uname uname)
- mark_as_advanced(ProcessorCount_cmd_uname)
- if(ProcessorCount_cmd_uname)
- execute_process(COMMAND ${ProcessorCount_cmd_uname} -X
+ # Sun (systems where psrinfo tool is available)
+ find_program(ProcessorCount_cmd_psrinfo psrinfo PATHS /usr/sbin /sbin)
+ mark_as_advanced(ProcessorCount_cmd_psrinfo)
+ if (ProcessorCount_cmd_psrinfo)
+ execute_process(COMMAND ${ProcessorCount_cmd_psrinfo} -p -v
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
- OUTPUT_VARIABLE uname_X_output)
- string(REGEX MATCHALL "NumCPU = ([0-9]+)" procs "${uname_X_output}")
+ OUTPUT_VARIABLE psrinfo_output)
+ string(REGEX MATCH "([0-9]+) virtual processor" procs "${psrinfo_output}")
set(count "${CMAKE_MATCH_1}")
- #message("ProcessorCount: trying uname -X '${ProcessorCount_cmd_uname}'")
+ #message("ProcessorCount: trying psrinfo -p -v '${ProcessorCount_cmd_prvinfo}'")
+ else()
+ # Sun (systems where uname -X emits "NumCPU" in its output):
+ find_program(ProcessorCount_cmd_uname uname)
+ mark_as_advanced(ProcessorCount_cmd_uname)
+ if(ProcessorCount_cmd_uname)
+ execute_process(COMMAND ${ProcessorCount_cmd_uname} -X
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ OUTPUT_VARIABLE uname_X_output)
+ string(REGEX MATCHALL "NumCPU = ([0-9]+)" procs "${uname_X_output}")
+ set(count "${CMAKE_MATCH_1}")
+ #message("ProcessorCount: trying uname -X '${ProcessorCount_cmd_uname}'")
+ endif()
endif()
endif()
@@ -171,6 +211,20 @@ function(ProcessorCount var)
endif()
endif()
+ if(NOT count)
+ # Haiku
+ find_program(ProcessorCount_cmd_sysinfo sysinfo)
+ if(ProcessorCount_cmd_sysinfo)
+ execute_process(COMMAND ${ProcessorCount_cmd_sysinfo}
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ OUTPUT_VARIABLE sysinfo_X_output)
+ string(REGEX MATCHALL "\nCPU #[0-9]+:" procs "\n${sysinfo_X_output}")
+ list(LENGTH procs count)
+ #message("ProcessorCount: trying sysinfo '${ProcessorCount_cmd_sysinfo}'")
+ endif()
+ endif()
+
# Since cygwin builds of CMake do not define WIN32 anymore, but they still
# run on Windows, and will still have this env var defined:
#
diff --git a/Modules/Qt4ConfigDependentSettings.cmake b/Modules/Qt4ConfigDependentSettings.cmake
index 88dc8ec5d..03fb8449a 100644
--- a/Modules/Qt4ConfigDependentSettings.cmake
+++ b/Modules/Qt4ConfigDependentSettings.cmake
@@ -1,3 +1,9 @@
+#.rst:
+# Qt4ConfigDependentSettings
+# --------------------------
+#
+#
+#
# This file is included by FindQt4.cmake, don't include it directly.
#=============================================================================
diff --git a/Modules/Qt4Macros.cmake b/Modules/Qt4Macros.cmake
index f1aedd743..3b0a6cc26 100644
--- a/Modules/Qt4Macros.cmake
+++ b/Modules/Qt4Macros.cmake
@@ -1,3 +1,9 @@
+#.rst:
+# Qt4Macros
+# ---------
+#
+#
+#
# This file is included by FindQt4.cmake, don't include it directly.
#=============================================================================
@@ -59,8 +65,8 @@ macro (QT4_MAKE_OUTPUT_FILE infile prefix ext outfile )
else()
file(RELATIVE_PATH rel ${CMAKE_CURRENT_SOURCE_DIR} ${infile})
endif()
- if(WIN32 AND rel MATCHES "^[a-zA-Z]:") # absolute path
- string(REGEX REPLACE "^([a-zA-Z]):(.*)$" "\\1_\\2" rel "${rel}")
+ if(WIN32 AND rel MATCHES "^([a-zA-Z]):(.*)$") # absolute path
+ set(rel "${CMAKE_MATCH_1}_${CMAKE_MATCH_2}")
endif()
set(_outfile "${CMAKE_CURRENT_BINARY_DIR}/${rel}")
string(REPLACE ".." "__" _outfile ${_outfile})
@@ -97,7 +103,7 @@ endmacro()
# helper macro to set up a moc rule
-macro (QT4_CREATE_MOC_COMMAND infile outfile moc_flags moc_options moc_target)
+function (QT4_CREATE_MOC_COMMAND infile outfile moc_flags moc_options moc_target)
# For Windows, create a parameters file to work around command line length limit
# Pass the parameters in a file. Set the working directory to
# be that containing the parameters file and reference it by
@@ -114,6 +120,7 @@ macro (QT4_CREATE_MOC_COMMAND infile outfile moc_flags moc_options moc_target)
string (REPLACE ";" "\n" _moc_parameters "${_moc_parameters}")
if(moc_target)
+ set (_moc_parameters_file ${_moc_parameters_file}$<$<BOOL:$<CONFIGURATION>>:_$<CONFIGURATION>>)
set(targetincludes "$<TARGET_PROPERTY:${moc_target},INCLUDE_DIRECTORIES>")
set(targetdefines "$<TARGET_PROPERTY:${moc_target},COMPILE_DEFINITIONS>")
@@ -128,16 +135,18 @@ macro (QT4_CREATE_MOC_COMMAND infile outfile moc_flags moc_options moc_target)
set(targetincludes)
set(targetdefines)
else()
- file(WRITE ${_moc_parameters_file} "${_moc_parameters}\n")
+ set(CMAKE_CONFIGURABLE_FILE_CONTENT "${_moc_parameters}")
+ configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in"
+ "${_moc_parameters_file}" @ONLY)
endif()
set(_moc_extra_parameters_file @${_moc_parameters_file})
add_custom_command(OUTPUT ${outfile}
- COMMAND ${QT_MOC_EXECUTABLE} ${_moc_extra_parameters_file}
- DEPENDS ${infile}
+ COMMAND Qt4::moc ${_moc_extra_parameters_file}
+ DEPENDS ${infile} ${_moc_parameters_file}
${_moc_working_dir}
VERBATIM)
-endmacro ()
+endfunction ()
macro (QT4_GENERATE_MOC infile outfile )
@@ -149,7 +158,7 @@ macro (QT4_GENERATE_MOC infile outfile )
set(_outfile "${CMAKE_CURRENT_BINARY_DIR}/${outfile}")
endif()
- if ("x${ARGV2}" STREQUAL "xTARGET")
+ if (${ARGC} GREATER 3 AND "x${ARGV2}" STREQUAL "xTARGET")
set(moc_target ${ARGV3})
endif()
QT4_CREATE_MOC_COMMAND(${abs_infile} ${_outfile} "${moc_flags}" "" "${moc_target}")
@@ -184,7 +193,7 @@ macro (QT4_WRAP_UI outfiles )
get_filename_component(infile ${it} ABSOLUTE)
set(outfile ${CMAKE_CURRENT_BINARY_DIR}/ui_${outfile}.h)
add_custom_command(OUTPUT ${outfile}
- COMMAND ${QT_UIC_EXECUTABLE}
+ COMMAND Qt4::uic
ARGS ${ui_options} -o ${outfile} ${infile}
MAIN_DEPENDENCY ${infile} VERBATIM)
set(${outfiles} ${${outfiles}} ${outfile})
@@ -223,7 +232,7 @@ macro (QT4_ADD_RESOURCES outfiles )
# let's make a configured file and add it as a dependency so cmake is run
# again when dependencies need to be recomputed.
QT4_MAKE_OUTPUT_FILE("${infile}" "" "qrc.depends" out_depends)
- configure_file("${infile}" "${out_depends}" COPY_ONLY)
+ configure_file("${infile}" "${out_depends}" COPYONLY)
else()
# The .qrc file does not exist (yet). Let's add a dependency and hope
# that it will be generated later
@@ -231,7 +240,7 @@ macro (QT4_ADD_RESOURCES outfiles )
endif()
add_custom_command(OUTPUT ${outfile}
- COMMAND ${QT_RCC_EXECUTABLE}
+ COMMAND Qt4::rcc
ARGS ${rcc_options} -name ${outfilename} -o ${outfile} ${infile}
MAIN_DEPENDENCY ${infile}
DEPENDS ${_RC_DEPENDS} "${out_depends}" VERBATIM)
@@ -265,7 +274,7 @@ macro(QT4_ADD_DBUS_INTERFACE _sources _interface _basename)
endif()
add_custom_command(OUTPUT "${_impl}" "${_header}"
- COMMAND ${QT_DBUSXML2CPP_EXECUTABLE} ${_params} -p ${_basename} ${_infile}
+ COMMAND Qt4::qdbusxml2cpp ${_params} -p ${_basename} ${_infile}
DEPENDS ${_infile} VERBATIM)
set_source_files_properties("${_impl}" PROPERTIES SKIP_AUTOMOC TRUE)
@@ -311,7 +320,7 @@ macro(QT4_GENERATE_DBUS_INTERFACE _header) # _customName OPTIONS -some -options
endif ()
add_custom_command(OUTPUT ${_target}
- COMMAND ${QT_DBUSCPP2XML_EXECUTABLE} ${_qt4_dbus_options} ${_in_file} -o ${_target}
+ COMMAND Qt4::qdbuscpp2xml ${_qt4_dbus_options} ${_in_file} -o ${_target}
DEPENDS ${_in_file} VERBATIM
)
endmacro()
@@ -320,7 +329,10 @@ endmacro()
macro(QT4_ADD_DBUS_ADAPTOR _sources _xml_file _include _parentClass) # _optionalBasename _optionalClassName)
get_filename_component(_infile ${_xml_file} ABSOLUTE)
- set(_optionalBasename "${ARGV4}")
+ unset(_optionalBasename)
+ if(${ARGC} GREATER 4)
+ set(_optionalBasename "${ARGV4}")
+ endif()
if (_optionalBasename)
set(_basename ${_optionalBasename} )
else ()
@@ -328,19 +340,22 @@ macro(QT4_ADD_DBUS_ADAPTOR _sources _xml_file _include _parentClass) # _optional
string(TOLOWER ${_basename} _basename)
endif ()
- set(_optionalClassName "${ARGV5}")
+ unset(_optionalClassName)
+ if(${ARGC} GREATER 5)
+ set(_optionalClassName "${ARGV5}")
+ endif()
set(_header "${CMAKE_CURRENT_BINARY_DIR}/${_basename}.h")
set(_impl "${CMAKE_CURRENT_BINARY_DIR}/${_basename}.cpp")
set(_moc "${CMAKE_CURRENT_BINARY_DIR}/${_basename}.moc")
if(_optionalClassName)
add_custom_command(OUTPUT "${_impl}" "${_header}"
- COMMAND ${QT_DBUSXML2CPP_EXECUTABLE} -m -a ${_basename} -c ${_optionalClassName} -i ${_include} -l ${_parentClass} ${_infile}
+ COMMAND Qt4::qdbusxml2cpp -m -a ${_basename} -c ${_optionalClassName} -i ${_include} -l ${_parentClass} ${_infile}
DEPENDS ${_infile} VERBATIM
)
else()
add_custom_command(OUTPUT "${_impl}" "${_header}"
- COMMAND ${QT_DBUSXML2CPP_EXECUTABLE} -m -a ${_basename} -i ${_include} -l ${_parentClass} ${_infile}
+ COMMAND Qt4::qdbusxml2cpp -m -a ${_basename} -i ${_include} -l ${_parentClass} ${_infile}
DEPENDS ${_infile} VERBATIM
)
endif()
@@ -355,15 +370,7 @@ endmacro()
macro(QT4_AUTOMOC)
if(NOT CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.11)
- if(CMAKE_WARN_DEPRECATED)
- set(messageType WARNING)
- endif()
- if(CMAKE_ERROR_DEPRECATED)
- set(messageType FATAL_ERROR)
- endif()
- if(messageType)
- message(${messageType} "The qt4_automoc macro is obsolete. Use the CMAKE_AUTOMOC feature instead.")
- endif()
+ message(DEPRECATION "The qt4_automoc macro is obsolete. Use the CMAKE_AUTOMOC feature instead.")
endif()
QT4_GET_MOC_FLAGS(_moc_INCS)
@@ -434,18 +441,19 @@ macro(QT4_CREATE_TRANSLATION _qm_files)
set(_ts_pro ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_ts_name}_lupdate.pro)
set(_pro_srcs)
foreach(_pro_src ${_my_sources})
- set(_pro_srcs "${_pro_srcs} \"${_pro_src}\"")
+ set(_pro_srcs "${_pro_srcs} \\\n \"${_pro_src}\"")
endforeach()
set(_pro_includes)
get_directory_property(_inc_DIRS INCLUDE_DIRECTORIES)
+ list(REMOVE_DUPLICATES _inc_DIRS)
foreach(_pro_include ${_inc_DIRS})
get_filename_component(_abs_include "${_pro_include}" ABSOLUTE)
- set(_pro_includes "${_pro_includes} \"${_abs_include}\"")
+ set(_pro_includes "${_pro_includes} \\\n \"${_abs_include}\"")
endforeach()
- file(WRITE ${_ts_pro} "SOURCES = ${_pro_srcs}\nINCLUDEPATH = ${_pro_includes}\n")
+ file(WRITE ${_ts_pro} "SOURCES =${_pro_srcs}\nINCLUDEPATH =${_pro_includes}\n")
endif()
add_custom_command(OUTPUT ${_ts_file}
- COMMAND ${QT_LUPDATE_EXECUTABLE}
+ COMMAND Qt4::lupdate
ARGS ${_lupdate_options} ${_ts_pro} ${_my_dirs} -ts ${_ts_file}
DEPENDS ${_my_sources} ${_ts_pro} VERBATIM)
endforeach()
@@ -466,7 +474,7 @@ macro(QT4_ADD_TRANSLATION _qm_files)
endif()
add_custom_command(OUTPUT ${qm}
- COMMAND ${QT_LRELEASE_EXECUTABLE}
+ COMMAND Qt4::lrelease
ARGS ${_abs_FILE} -qm ${qm}
DEPENDS ${_abs_FILE} VERBATIM
)
@@ -476,15 +484,7 @@ endmacro()
function(qt4_use_modules _target _link_type)
if(NOT CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.11)
- if(CMAKE_WARN_DEPRECATED)
- set(messageType WARNING)
- endif()
- if(CMAKE_ERROR_DEPRECATED)
- set(messageType FATAL_ERROR)
- endif()
- if(messageType)
- message(${messageType} "The qt4_use_modules function is obsolete. Use target_link_libraries with IMPORTED targets instead.")
- endif()
+ message(DEPRECATION "The qt4_use_modules function is obsolete. Use target_link_libraries with IMPORTED targets instead.")
endif()
if ("${_link_type}" STREQUAL "LINK_PUBLIC" OR "${_link_type}" STREQUAL "LINK_PRIVATE")
set(modules ${ARGN})
diff --git a/Modules/SelectLibraryConfigurations.cmake b/Modules/SelectLibraryConfigurations.cmake
index 297e1d3bd..d7108562b 100644
--- a/Modules/SelectLibraryConfigurations.cmake
+++ b/Modules/SelectLibraryConfigurations.cmake
@@ -1,20 +1,28 @@
+#.rst:
+# SelectLibraryConfigurations
+# ---------------------------
+#
+#
+#
# select_library_configurations( basename )
#
-# This macro takes a library base name as an argument, and will choose good
-# values for basename_LIBRARY, basename_LIBRARIES, basename_LIBRARY_DEBUG, and
-# basename_LIBRARY_RELEASE depending on what has been found and set. If only
-# basename_LIBRARY_RELEASE is defined, basename_LIBRARY will be set to the
-# release value, and basename_LIBRARY_DEBUG will be set to
-# basename_LIBRARY_DEBUG-NOTFOUND. If only basename_LIBRARY_DEBUG is defined,
-# then basename_LIBRARY will take the debug value, and basename_LIBRARY_RELEASE
-# will be set to basename_LIBRARY_RELEASE-NOTFOUND.
+# This macro takes a library base name as an argument, and will choose
+# good values for basename_LIBRARY, basename_LIBRARIES,
+# basename_LIBRARY_DEBUG, and basename_LIBRARY_RELEASE depending on what
+# has been found and set. If only basename_LIBRARY_RELEASE is defined,
+# basename_LIBRARY will be set to the release value, and
+# basename_LIBRARY_DEBUG will be set to basename_LIBRARY_DEBUG-NOTFOUND.
+# If only basename_LIBRARY_DEBUG is defined, then basename_LIBRARY will
+# take the debug value, and basename_LIBRARY_RELEASE will be set to
+# basename_LIBRARY_RELEASE-NOTFOUND.
#
-# If the generator supports configuration types, then basename_LIBRARY and
-# basename_LIBRARIES will be set with debug and optimized flags specifying the
-# library to be used for the given configuration. If no build type has been set
-# or the generator in use does not support configuration types, then
-# basename_LIBRARY and basename_LIBRARIES will take only the release value, or
-# the debug value if the release one is not set.
+# If the generator supports configuration types, then basename_LIBRARY
+# and basename_LIBRARIES will be set with debug and optimized flags
+# specifying the library to be used for the given configuration. If no
+# build type has been set or the generator in use does not support
+# configuration types, then basename_LIBRARY and basename_LIBRARIES will
+# take only the release value, or the debug value if the release one is
+# not set.
#=============================================================================
# Copyright 2009 Will Dicharry <wdicharry@stellarscience.com>
diff --git a/Modules/Squish4RunTestCase.sh b/Modules/Squish4RunTestCase.sh
index abd5debd2..39a390733 100755
--- a/Modules/Squish4RunTestCase.sh
+++ b/Modules/Squish4RunTestCase.sh
@@ -11,11 +11,11 @@ SETTINGSGROUP=$7
$SQUISHSERVER --stop > /dev/null 2>&1
echo "Adding AUT... $SQUISHSERVER --settingsGroup $SETTINGSGROUP --config addAUT $AUT $AUTDIR"
-$SQUISHSERVER --settingsGroup "$SETTINGSGROUP" --config addAUT "$AUT" "$AUTDIR" || exit -1
+$SQUISHSERVER --settingsGroup "$SETTINGSGROUP" --config addAUT "$AUT" "$AUTDIR" || exit 255
# sleep 1
echo "Starting the squish server... $SQUISHSERVER --daemon"
-$SQUISHSERVER --daemon || exit -1
+$SQUISHSERVER --daemon || exit 255
# sleep 2
echo "Running the test case...$SQUISHRUNNER --settingsGroup $SETTINGSGROUP --testsuite $TESTSUITE --testcase $TESTCASE"
diff --git a/Modules/SquishTestScript.cmake b/Modules/SquishTestScript.cmake
index f794b3eee..d6487499e 100644
--- a/Modules/SquishTestScript.cmake
+++ b/Modules/SquishTestScript.cmake
@@ -1,13 +1,18 @@
+#.rst:
+# SquishTestScript
+# ----------------
#
-# This script launches a GUI test using Squish. You should not call
-# the script directly; instead, you should access it via the
-# SQUISH_ADD_TEST macro that is defined in FindSquish.cmake.
#
-# This script starts the Squish server, launches the test on the
-# client, and finally stops the squish server. If any of these steps
-# fail (including if the tests do not pass) then a fatal error is
-# raised.
#
+#
+#
+# This script launches a GUI test using Squish. You should not call the
+# script directly; instead, you should access it via the SQUISH_ADD_TEST
+# macro that is defined in FindSquish.cmake.
+#
+# This script starts the Squish server, launches the test on the client,
+# and finally stops the squish server. If any of these steps fail
+# (including if the tests do not pass) then a fatal error is raised.
#=============================================================================
# Copyright 2008-2009 Kitware, Inc.
diff --git a/Modules/TestBigEndian.cmake b/Modules/TestBigEndian.cmake
index 193df8fda..fcb41abe1 100644
--- a/Modules/TestBigEndian.cmake
+++ b/Modules/TestBigEndian.cmake
@@ -1,8 +1,15 @@
-# - Define macro to determine endian type
+#.rst:
+# TestBigEndian
+# -------------
+#
+# Define macro to determine endian type
+#
# Check if the system is big endian or little endian
-# TEST_BIG_ENDIAN(VARIABLE)
-# VARIABLE - variable to store the result to
#
+# ::
+#
+# TEST_BIG_ENDIAN(VARIABLE)
+# VARIABLE - variable to store the result to
#=============================================================================
# Copyright 2002-2009 Kitware, Inc.
@@ -18,7 +25,7 @@
# License text for the above reference.)
macro(TEST_BIG_ENDIAN VARIABLE)
- if("HAVE_${VARIABLE}" MATCHES "^HAVE_${VARIABLE}$")
+ if(NOT DEFINED HAVE_${VARIABLE})
message(STATUS "Check if the system is big endian")
message(STATUS "Searching 16 bit integer")
@@ -51,7 +58,7 @@ macro(TEST_BIG_ENDIAN VARIABLE)
configure_file("${CMAKE_ROOT}/Modules/TestEndianess.c.in"
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/TestEndianess.c"
- IMMEDIATE @ONLY)
+ @ONLY)
file(READ "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/TestEndianess.c"
TEST_ENDIANESS_FILE_CONTENT)
diff --git a/Modules/TestCXXAcceptsFlag.cmake b/Modules/TestCXXAcceptsFlag.cmake
index 2694737ef..c814187d5 100644
--- a/Modules/TestCXXAcceptsFlag.cmake
+++ b/Modules/TestCXXAcceptsFlag.cmake
@@ -1,11 +1,19 @@
-# - Test CXX compiler for a flag
-# Check if the CXX compiler accepts a flag
+#.rst:
+# TestCXXAcceptsFlag
+# ------------------
#
-# Macro CHECK_CXX_ACCEPTS_FLAG(FLAGS VARIABLE) -
-# checks if the function exists
-# FLAGS - the flags to try
-# VARIABLE - variable to store the result
+# Deprecated. See :module:`CheckCXXCompilerFlag`.
#
+# Check if the CXX compiler accepts a flag.
+#
+# .. code-block:: cmake
+#
+# CHECK_CXX_ACCEPTS_FLAG(<flags> <variable>)
+#
+# ``<flags>``
+# the flags to try
+# ``<variable>``
+# variable to store the result
#=============================================================================
# Copyright 2002-2009 Kitware, Inc.
diff --git a/Modules/TestForANSIForScope.cmake b/Modules/TestForANSIForScope.cmake
index 9b4d51cda..78fff9f74 100644
--- a/Modules/TestForANSIForScope.cmake
+++ b/Modules/TestForANSIForScope.cmake
@@ -1,7 +1,15 @@
-# - Check for ANSI for scope support
-# Check if the compiler restricts the scope of variables declared in a for-init-statement to the loop body.
-# CMAKE_NO_ANSI_FOR_SCOPE - holds result
+#.rst:
+# TestForANSIForScope
+# -------------------
#
+# Check for ANSI for scope support
+#
+# Check if the compiler restricts the scope of variables declared in a
+# for-init-statement to the loop body.
+#
+# ::
+#
+# CMAKE_NO_ANSI_FOR_SCOPE - holds result
#=============================================================================
# Copyright 2002-2009 Kitware, Inc.
@@ -16,7 +24,7 @@
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
-if("CMAKE_ANSI_FOR_SCOPE" MATCHES "^CMAKE_ANSI_FOR_SCOPE$")
+if(NOT DEFINED CMAKE_ANSI_FOR_SCOPE)
message(STATUS "Check for ANSI scope")
try_compile(CMAKE_ANSI_FOR_SCOPE ${CMAKE_BINARY_DIR}
${CMAKE_ROOT}/Modules/TestForAnsiForScope.cxx
diff --git a/Modules/TestForANSIStreamHeaders.cmake b/Modules/TestForANSIStreamHeaders.cmake
index 060b3a43a..c13000b70 100644
--- a/Modules/TestForANSIStreamHeaders.cmake
+++ b/Modules/TestForANSIStreamHeaders.cmake
@@ -1,7 +1,15 @@
-# - Test for compiler support of ANSI stream headers iostream, etc.
-# check if the compiler supports the standard ANSI iostream header (without the .h)
-# CMAKE_NO_ANSI_STREAM_HEADERS - defined by the results
+#.rst:
+# TestForANSIStreamHeaders
+# ------------------------
#
+# Test for compiler support of ANSI stream headers iostream, etc.
+#
+# check if the compiler supports the standard ANSI iostream header
+# (without the .h)
+#
+# ::
+#
+# CMAKE_NO_ANSI_STREAM_HEADERS - defined by the results
#=============================================================================
# Copyright 2002-2009 Kitware, Inc.
diff --git a/Modules/TestForSSTREAM.cmake b/Modules/TestForSSTREAM.cmake
index db39c1e70..fe18ea2a7 100644
--- a/Modules/TestForSSTREAM.cmake
+++ b/Modules/TestForSSTREAM.cmake
@@ -1,7 +1,14 @@
-# - Test for compiler support of ANSI sstream header
+#.rst:
+# TestForSSTREAM
+# --------------
+#
+# Test for compiler support of ANSI sstream header
+#
# check if the compiler supports the standard ANSI sstream header
-# CMAKE_NO_ANSI_STRING_STREAM - defined by the results
#
+# ::
+#
+# CMAKE_NO_ANSI_STRING_STREAM - defined by the results
#=============================================================================
# Copyright 2006-2009 Kitware, Inc.
@@ -16,7 +23,7 @@
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
-if("CMAKE_HAS_ANSI_STRING_STREAM" MATCHES "^CMAKE_HAS_ANSI_STRING_STREAM$")
+if(NOT DEFINED CMAKE_HAS_ANSI_STRING_STREAM)
message(STATUS "Check for sstream")
try_compile(CMAKE_HAS_ANSI_STRING_STREAM ${CMAKE_BINARY_DIR}
${CMAKE_ROOT}/Modules/TestForSSTREAM.cxx
diff --git a/Modules/TestForSTDNamespace.cmake b/Modules/TestForSTDNamespace.cmake
index 6a7564445..0d907744a 100644
--- a/Modules/TestForSTDNamespace.cmake
+++ b/Modules/TestForSTDNamespace.cmake
@@ -1,7 +1,14 @@
-# - Test for std:: namespace support
+#.rst:
+# TestForSTDNamespace
+# -------------------
+#
+# Test for std:: namespace support
+#
# check if the compiler supports std:: on stl classes
-# CMAKE_NO_STD_NAMESPACE - defined by the results
#
+# ::
+#
+# CMAKE_NO_STD_NAMESPACE - defined by the results
#=============================================================================
# Copyright 2002-2009 Kitware, Inc.
@@ -16,7 +23,7 @@
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
-if("CMAKE_STD_NAMESPACE" MATCHES "^CMAKE_STD_NAMESPACE$")
+if(NOT DEFINED CMAKE_STD_NAMESPACE)
message(STATUS "Check for STD namespace")
try_compile(CMAKE_STD_NAMESPACE ${CMAKE_BINARY_DIR}
${CMAKE_ROOT}/Modules/TestForSTDNamespace.cxx
diff --git a/Modules/UseEcos.cmake b/Modules/UseEcos.cmake
index 0c4fee4e1..3bd92ca23 100644
--- a/Modules/UseEcos.cmake
+++ b/Modules/UseEcos.cmake
@@ -1,20 +1,29 @@
-# - This module defines variables and macros required to build eCos application.
+#.rst:
+# UseEcos
+# -------
+#
+# This module defines variables and macros required to build eCos application.
+#
# This file contains the following macros:
# ECOS_ADD_INCLUDE_DIRECTORIES() - add the eCos include dirs
-# ECOS_ADD_EXECUTABLE(name source1 ... sourceN ) - create an eCos executable
-# ECOS_ADJUST_DIRECTORY(VAR source1 ... sourceN ) - adjusts the path of the source files and puts the result into VAR
+# ECOS_ADD_EXECUTABLE(name source1 ... sourceN ) - create an eCos
+# executable ECOS_ADJUST_DIRECTORY(VAR source1 ... sourceN ) - adjusts
+# the path of the source files and puts the result into VAR
+#
+# Macros for selecting the toolchain: ECOS_USE_ARM_ELF_TOOLS() - enable
+# the ARM ELF toolchain for the directory where it is called
+# ECOS_USE_I386_ELF_TOOLS() - enable the i386 ELF toolchain for the
+# directory where it is called ECOS_USE_PPC_EABI_TOOLS() - enable the
+# PowerPC toolchain for the directory where it is called
+#
+# It contains the following variables: ECOS_DEFINITIONS
+# ECOSCONFIG_EXECUTABLE ECOS_CONFIG_FILE - defaults to ecos.ecc, if your
+# eCos configuration file has a different name, adjust this variable for
+# internal use only:
#
-# Macros for selecting the toolchain:
-# ECOS_USE_ARM_ELF_TOOLS() - enable the ARM ELF toolchain for the directory where it is called
-# ECOS_USE_I386_ELF_TOOLS() - enable the i386 ELF toolchain for the directory where it is called
-# ECOS_USE_PPC_EABI_TOOLS() - enable the PowerPC toolchain for the directory where it is called
+# ::
#
-# It contains the following variables:
-# ECOS_DEFINITIONS
-# ECOSCONFIG_EXECUTABLE
-# ECOS_CONFIG_FILE - defaults to ecos.ecc, if your eCos configuration file has a different name, adjust this variable
-# for internal use only:
-# ECOS_ADD_TARGET_LIB
+# ECOS_ADD_TARGET_LIB
#=============================================================================
# Copyright 2006-2009 Kitware, Inc.
diff --git a/Modules/UseJava.cmake b/Modules/UseJava.cmake
index c0fd07cbd..475ad5ee0 100644
--- a/Modules/UseJava.cmake
+++ b/Modules/UseJava.cmake
@@ -1,193 +1,373 @@
-# - Use Module for Java
-# This file provides functions for Java. It is assumed that FindJava.cmake
-# has already been loaded. See FindJava.cmake for information on how to
-# load Java into your CMake project.
-#
-# add_jar(target_name
-# [SOURCES] source1 [source2 ...] [resource1 ...]
-# [INCLUDE_JARS jar1 [jar2 ...]]
-# [ENTRY_POINT entry]
-# [VERSION version]
-# [OUTPUT_NAME name]
-# [OUTPUT_DIR dir]
-# )
-#
-# This command creates a <target_name>.jar. It compiles the given source files
-# (source) and adds the given resource files (resource) to the jar file. If
-# only resource files are given then just a jar file is created. The list of
-# include jars are added to the classpath when compiling the java sources and
-# also to the dependencies of the target. INCLUDE_JARS also accepts other
-# target names created by add_jar. For backwards compatibility, jar files
-# listed as sources are ignored (as they have been since the first version of
-# this module).
+#.rst:
+# UseJava
+# -------
+#
+# Use Module for Java
+#
+# This file provides functions for Java. It is assumed that
+# FindJava.cmake has already been loaded. See FindJava.cmake for
+# information on how to load Java into your CMake project.
+#
+# ::
+#
+# add_jar(target_name
+# [SOURCES] source1 [source2 ...] [resource1 ...]
+# [INCLUDE_JARS jar1 [jar2 ...]]
+# [ENTRY_POINT entry]
+# [VERSION version]
+# [OUTPUT_NAME name]
+# [OUTPUT_DIR dir]
+# )
+#
+# This command creates a <target_name>.jar. It compiles the given
+# source files (source) and adds the given resource files (resource) to
+# the jar file. Source files can be java files or listing files
+# (prefixed by '@'). If only resource files are given then just a jar file
+# is created. The list of include jars are added to the classpath when
+# compiling the java sources and also to the dependencies of the target.
+# INCLUDE_JARS also accepts other target names created by add_jar. For
+# backwards compatibility, jar files listed as sources are ignored (as
+# they have been since the first version of this module).
#
# The default OUTPUT_DIR can also be changed by setting the variable
# CMAKE_JAVA_TARGET_OUTPUT_DIR.
#
# Additional instructions:
-# To add compile flags to the target you can set these flags with
-# the following variable:
#
-# set(CMAKE_JAVA_COMPILE_FLAGS -nowarn)
+# ::
+#
+# To add compile flags to the target you can set these flags with
+# the following variable:
+#
+#
+#
+# ::
+#
+# set(CMAKE_JAVA_COMPILE_FLAGS -nowarn)
+#
+#
+#
+# ::
+#
+# To add a path or a jar file to the class path you can do this
+# with the CMAKE_JAVA_INCLUDE_PATH variable.
+#
+#
+#
+# ::
+#
+# set(CMAKE_JAVA_INCLUDE_PATH /usr/share/java/shibboleet.jar)
+#
+#
+#
+# ::
+#
+# To use a different output name for the target you can set it with:
+#
+#
+#
+# ::
+#
+# add_jar(foobar foobar.java OUTPUT_NAME shibboleet.jar)
+#
+#
+#
+# ::
+#
+# To use a different output directory than CMAKE_CURRENT_BINARY_DIR
+# you can set it with:
+#
+#
+#
+# ::
+#
+# add_jar(foobar foobar.java OUTPUT_DIR ${PROJECT_BINARY_DIR}/bin)
+#
+#
+#
+# ::
+#
+# To define an entry point in your jar you can set it with the ENTRY_POINT
+# named argument:
+#
+#
+#
+# ::
+#
+# add_jar(example ENTRY_POINT com/examples/MyProject/Main)
+#
#
-# To add a path or a jar file to the class path you can do this
-# with the CMAKE_JAVA_INCLUDE_PATH variable.
#
-# set(CMAKE_JAVA_INCLUDE_PATH /usr/share/java/shibboleet.jar)
+# ::
#
-# To use a different output name for the target you can set it with:
+# To define a custom manifest for the jar, you can set it with the manifest
+# named argument:
#
-# add_jar(foobar foobar.java OUTPUT_NAME shibboleet.jar)
#
-# To use a different output directory than CMAKE_CURRENT_BINARY_DIR
-# you can set it with:
#
-# add_jar(foobar foobar.java OUTPUT_DIR ${PROJECT_BINARY_DIR}/bin)
+# ::
#
-# To define an entry point in your jar you can set it with the ENTRY_POINT
-# named argument:
+# add_jar(example MANIFEST /path/to/manifest)
#
-# add_jar(example ENTRY_POINT com/examples/MyProject/Main)
#
-# To add a VERSION to the target output name you can set it using
-# the VERSION named argument to add_jar. This will create a jar file with the
-# name shibboleet-1.0.0.jar and will create a symlink shibboleet.jar
-# pointing to the jar with the version information.
#
-# add_jar(shibboleet shibbotleet.java VERSION 1.2.0)
+# ::
#
-# If the target is a JNI library, utilize the following commands to
-# create a JNI symbolic link:
+# To add a VERSION to the target output name you can set it using
+# the VERSION named argument to add_jar. This will create a jar file with the
+# name shibboleet-1.0.0.jar and will create a symlink shibboleet.jar
+# pointing to the jar with the version information.
#
-# set(CMAKE_JNI_TARGET TRUE)
-# add_jar(shibboleet shibbotleet.java VERSION 1.2.0)
-# install_jar(shibboleet ${LIB_INSTALL_DIR}/shibboleet)
-# install_jni_symlink(shibboleet ${JAVA_LIB_INSTALL_DIR})
#
-# If a single target needs to produce more than one jar from its
-# java source code, to prevent the accumulation of duplicate class
-# files in subsequent jars, set/reset CMAKE_JAR_CLASSES_PREFIX prior
-# to calling the add_jar() function:
#
-# set(CMAKE_JAR_CLASSES_PREFIX com/redhat/foo)
-# add_jar(foo foo.java)
+# ::
+#
+# add_jar(shibboleet shibbotleet.java VERSION 1.2.0)
+#
+#
+#
+# ::
+#
+# If the target is a JNI library, utilize the following commands to
+# create a JNI symbolic link:
+#
+#
+#
+# ::
+#
+# set(CMAKE_JNI_TARGET TRUE)
+# add_jar(shibboleet shibbotleet.java VERSION 1.2.0)
+# install_jar(shibboleet ${LIB_INSTALL_DIR}/shibboleet)
+# install_jni_symlink(shibboleet ${JAVA_LIB_INSTALL_DIR})
+#
+#
+#
+# ::
+#
+# If a single target needs to produce more than one jar from its
+# java source code, to prevent the accumulation of duplicate class
+# files in subsequent jars, set/reset CMAKE_JAR_CLASSES_PREFIX prior
+# to calling the add_jar() function:
+#
+#
+#
+# ::
+#
+# set(CMAKE_JAR_CLASSES_PREFIX com/redhat/foo)
+# add_jar(foo foo.java)
+#
+#
+#
+# ::
+#
+# set(CMAKE_JAR_CLASSES_PREFIX com/redhat/bar)
+# add_jar(bar bar.java)
+#
#
-# set(CMAKE_JAR_CLASSES_PREFIX com/redhat/bar)
-# add_jar(bar bar.java)
#
# Target Properties:
-# The add_jar() functions sets some target properties. You can get these
-# properties with the
-# get_property(TARGET <target_name> PROPERTY <propery_name>)
-# command.
-#
-# INSTALL_FILES The files which should be installed. This is used by
-# install_jar().
-# JNI_SYMLINK The JNI symlink which should be installed.
-# This is used by install_jni_symlink().
-# JAR_FILE The location of the jar file so that you can include
-# it.
-# CLASS_DIR The directory where the class files can be found. For
-# example to use them with javah.
-#
-# find_jar(<VAR>
-# name | NAMES name1 [name2 ...]
-# [PATHS path1 [path2 ... ENV var]]
-# [VERSIONS version1 [version2]]
-# [DOC "cache documentation string"]
-# )
-#
-# This command is used to find a full path to the named jar. A cache
-# entry named by <VAR> is created to stor the result of this command. If
-# the full path to a jar is found the result is stored in the variable
-# and the search will not repeated unless the variable is cleared. If
-# nothing is found, the result will be <VAR>-NOTFOUND, and the search
-# will be attempted again next time find_jar is invoked with the same
-# variable.
-# The name of the full path to a file that is searched for is specified
-# by the names listed after NAMES argument. Additional search locations
-# can be specified after the PATHS argument. If you require special a
-# version of a jar file you can specify it with the VERSIONS argument.
-# The argument after DOC will be used for the documentation string in
-# the cache.
-#
-# install_jar(TARGET_NAME DESTINATION)
+#
+# ::
+#
+# The add_jar() functions sets some target properties. You can get these
+# properties with the
+# get_property(TARGET <target_name> PROPERTY <propery_name>)
+# command.
+#
+#
+#
+# ::
+#
+# INSTALL_FILES The files which should be installed. This is used by
+# install_jar().
+# JNI_SYMLINK The JNI symlink which should be installed.
+# This is used by install_jni_symlink().
+# JAR_FILE The location of the jar file so that you can include
+# it.
+# CLASSDIR The directory where the class files can be found. For
+# example to use them with javah.
+#
+# ::
+#
+# find_jar(<VAR>
+# name | NAMES name1 [name2 ...]
+# [PATHS path1 [path2 ... ENV var]]
+# [VERSIONS version1 [version2]]
+# [DOC "cache documentation string"]
+# )
+#
+# This command is used to find a full path to the named jar. A cache
+# entry named by <VAR> is created to stor the result of this command.
+# If the full path to a jar is found the result is stored in the
+# variable and the search will not repeated unless the variable is
+# cleared. If nothing is found, the result will be <VAR>-NOTFOUND, and
+# the search will be attempted again next time find_jar is invoked with
+# the same variable. The name of the full path to a file that is
+# searched for is specified by the names listed after NAMES argument.
+# Additional search locations can be specified after the PATHS argument.
+# If you require special a version of a jar file you can specify it with
+# the VERSIONS argument. The argument after DOC will be used for the
+# documentation string in the cache.
+#
+# ::
+#
+# install_jar(target_name destination)
+# install_jar(target_name DESTINATION destination [COMPONENT component])
#
# This command installs the TARGET_NAME files to the given DESTINATION.
# It should be called in the same scope as add_jar() or it will fail.
#
-# install_jni_symlink(TARGET_NAME DESTINATION)
+# ::
+#
+# install_jni_symlink(target_name destination)
+# install_jni_symlink(target_name DESTINATION destination [COMPONENT component])
#
# This command installs the TARGET_NAME JNI symlinks to the given
-# DESTINATION. It should be called in the same scope as add_jar()
-# or it will fail.
-#
-# create_javadoc(<VAR>
-# PACKAGES pkg1 [pkg2 ...]
-# [SOURCEPATH <sourcepath>]
-# [CLASSPATH <classpath>]
-# [INSTALLPATH <install path>]
-# [DOCTITLE "the documentation title"]
-# [WINDOWTITLE "the title of the document"]
-# [AUTHOR TRUE|FALSE]
-# [USE TRUE|FALSE]
-# [VERSION TRUE|FALSE]
-# )
+# DESTINATION. It should be called in the same scope as add_jar() or it
+# will fail.
+#
+# ::
+#
+# create_javadoc(<VAR>
+# PACKAGES pkg1 [pkg2 ...]
+# [SOURCEPATH <sourcepath>]
+# [CLASSPATH <classpath>]
+# [INSTALLPATH <install path>]
+# [DOCTITLE "the documentation title"]
+# [WINDOWTITLE "the title of the document"]
+# [AUTHOR TRUE|FALSE]
+# [USE TRUE|FALSE]
+# [VERSION TRUE|FALSE]
+# )
#
-# Create java documentation based on files or packages. For more
+# Create java documentation based on files or packages. For more
# details please read the javadoc manpage.
#
-# There are two main signatures for create_javadoc. The first
-# signature works with package names on a path with source files:
-#
-# Example:
-# create_javadoc(my_example_doc
-# PACKAGES com.exmaple.foo com.example.bar
-# SOURCEPATH "${CMAKE_CURRENT_SOURCE_DIR}"
-# CLASSPATH ${CMAKE_JAVA_INCLUDE_PATH}
-# WINDOWTITLE "My example"
-# DOCTITLE "<h1>My example</h1>"
-# AUTHOR TRUE
-# USE TRUE
-# VERSION TRUE
-# )
+# There are two main signatures for create_javadoc. The first signature
+# works with package names on a path with source files:
+#
+# ::
+#
+# Example:
+# create_javadoc(my_example_doc
+# PACKAGES com.exmaple.foo com.example.bar
+# SOURCEPATH "${CMAKE_CURRENT_SOURCE_DIR}"
+# CLASSPATH ${CMAKE_JAVA_INCLUDE_PATH}
+# WINDOWTITLE "My example"
+# DOCTITLE "<h1>My example</h1>"
+# AUTHOR TRUE
+# USE TRUE
+# VERSION TRUE
+# )
+#
+#
#
# The second signature for create_javadoc works on a given list of
# files.
#
-# create_javadoc(<VAR>
-# FILES file1 [file2 ...]
-# [CLASSPATH <classpath>]
-# [INSTALLPATH <install path>]
-# [DOCTITLE "the documentation title"]
-# [WINDOWTITLE "the title of the document"]
-# [AUTHOR TRUE|FALSE]
-# [USE TRUE|FALSE]
-# [VERSION TRUE|FALSE]
-# )
+# ::
+#
+# create_javadoc(<VAR>
+# FILES file1 [file2 ...]
+# [CLASSPATH <classpath>]
+# [INSTALLPATH <install path>]
+# [DOCTITLE "the documentation title"]
+# [WINDOWTITLE "the title of the document"]
+# [AUTHOR TRUE|FALSE]
+# [USE TRUE|FALSE]
+# [VERSION TRUE|FALSE]
+# )
+#
+#
#
# Example:
-# create_javadoc(my_example_doc
-# FILES ${example_SRCS}
-# CLASSPATH ${CMAKE_JAVA_INCLUDE_PATH}
-# WINDOWTITLE "My example"
-# DOCTITLE "<h1>My example</h1>"
-# AUTHOR TRUE
-# USE TRUE
-# VERSION TRUE
-# )
-#
-# Both signatures share most of the options. These options are the
-# same as what you can find in the javadoc manpage. Please look at
-# the manpage for CLASSPATH, DOCTITLE, WINDOWTITLE, AUTHOR, USE and
-# VERSION.
+#
+# ::
+#
+# create_javadoc(my_example_doc
+# FILES ${example_SRCS}
+# CLASSPATH ${CMAKE_JAVA_INCLUDE_PATH}
+# WINDOWTITLE "My example"
+# DOCTITLE "<h1>My example</h1>"
+# AUTHOR TRUE
+# USE TRUE
+# VERSION TRUE
+# )
+#
+#
+#
+# Both signatures share most of the options. These options are the same
+# as what you can find in the javadoc manpage. Please look at the
+# manpage for CLASSPATH, DOCTITLE, WINDOWTITLE, AUTHOR, USE and VERSION.
#
# The documentation will be by default installed to
#
-# ${CMAKE_INSTALL_PREFIX}/share/javadoc/<VAR>
+# ::
+#
+# ${CMAKE_INSTALL_PREFIX}/share/javadoc/<VAR>
+#
+#
#
# if you don't set the INSTALLPATH.
#
+# ::
+#
+# create_javah(TARGET <target>
+# GENERATED_FILES <VAR>
+# CLASSES <class>...
+# [CLASSPATH <classpath>...]
+# [DEPENDS <depend>...]
+# [OUTPUT_NAME <path>|OUTPUT_DIR <path>]
+# )
+#
+# Create C header files from java classes. These files provide the connective glue
+# that allow your Java and C code to interact.
+#
+# There are two main signatures for create_javah. The first signature
+# returns generated files throught variable specified by GENERATED_FILES option:
+#
+# ::
+#
+# Example:
+# Create_javah(GENERATED_FILES files_headers
+# CLASSES org.cmake.HelloWorld
+# CLASSPATH hello.jar
+# )
+#
+#
+#
+# The second signature for create_javah creates a target which encapsulates
+# header files generation.
+#
+# ::
+#
+# Example:
+# Create_javah(TARGET target_headers
+# CLASSES org.cmake.HelloWorld
+# CLASSPATH hello.jar
+# )
+#
+#
+#
+# Both signatures share same options.
+#
+# ``CLASSES <class>...``
+# Specifies Java classes used to generate headers.
+#
+# ``CLASSPATH <classpath>...``
+# Specifies various paths to look up classes. Here .class files, jar files or targets
+# created by command add_jar can be used.
+#
+# ``DEPENDS <depend>...``
+# Targets on which the javah target depends
+#
+# ``OUTPUT_NAME <path>``
+# Concatenates the resulting header files for all the classes listed by option CLASSES
+# into <path>. Same behavior as option '-o' of javah tool.
+#
+# ``OUTPUT_DIR <path>``
+# Sets the directory where the header files will be generated. Same behavior as option
+# '-d' of javah tool. If not specified, ${CMAKE_CURRENT_BINARY_DIR} is used as output directory.
#=============================================================================
# Copyright 2013 OpenGamma Ltd. <graham@opengamma.com>
@@ -222,6 +402,13 @@ set(_JAVA_SYMLINK_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/UseJavaSymlinks.cmake)
function(add_jar _TARGET_NAME)
+ cmake_parse_arguments(_add_jar
+ ""
+ "VERSION;OUTPUT_DIR;OUTPUT_NAME;ENTRY_POINT;MANIFEST"
+ "SOURCES;INCLUDE_JARS"
+ ${ARGN}
+ )
+
# In CMake < 2.8.12, add_jar used variables which were set prior to calling
# add_jar for customizing the behavior of add_jar. In order to be backwards
# compatible, check if any of those variables are set, and use them to
@@ -229,28 +416,21 @@ function(add_jar _TARGET_NAME)
# argument will override the value set here.)
#
# New features should use named arguments only.
- if(DEFINED CMAKE_JAVA_TARGET_VERSION)
+ if(NOT DEFINED _add_jar_VERSION AND DEFINED CMAKE_JAVA_TARGET_VERSION)
set(_add_jar_VERSION "${CMAKE_JAVA_TARGET_VERSION}")
endif()
- if(DEFINED CMAKE_JAVA_TARGET_OUTPUT_DIR)
+ if(NOT DEFINED _add_jar_OUTPUT_DIR AND DEFINED CMAKE_JAVA_TARGET_OUTPUT_DIR)
set(_add_jar_OUTPUT_DIR "${CMAKE_JAVA_TARGET_OUTPUT_DIR}")
endif()
- if(DEFINED CMAKE_JAVA_TARGET_OUTPUT_NAME)
+ if(NOT DEFINED _add_jar_OUTPUT_NAME AND DEFINED CMAKE_JAVA_TARGET_OUTPUT_NAME)
set(_add_jar_OUTPUT_NAME "${CMAKE_JAVA_TARGET_OUTPUT_NAME}")
# reset
set(CMAKE_JAVA_TARGET_OUTPUT_NAME)
endif()
- if(DEFINED CMAKE_JAVA_JAR_ENTRY_POINT)
+ if(NOT DEFINED _add_jar_ENTRY_POINT AND DEFINED CMAKE_JAVA_JAR_ENTRY_POINT)
set(_add_jar_ENTRY_POINT "${CMAKE_JAVA_JAR_ENTRY_POINT}")
endif()
- cmake_parse_arguments(_add_jar
- ""
- "VERSION;OUTPUT_DIR;OUTPUT_NAME;ENTRY_POINT"
- "SOURCES;INCLUDE_JARS"
- ${ARGN}
- )
-
set(_JAVA_SOURCE_FILES ${_add_jar_SOURCES} ${_add_jar_UNPARSED_ARGUMENTS})
if (NOT DEFINED _add_jar_OUTPUT_DIR)
@@ -262,6 +442,11 @@ function(add_jar _TARGET_NAME)
set(_ENTRY_POINT_VALUE ${_add_jar_ENTRY_POINT})
endif ()
+ if (_add_jar_MANIFEST)
+ set(_MANIFEST_OPTION m)
+ get_filename_component (_MANIFEST_VALUE "${_add_jar_MANIFEST}" ABSOLUTE)
+ endif ()
+
if (LIBRARY_OUTPUT_PATH)
set(CMAKE_JAVA_LIBRARY_OUTPUT_PATH ${LIBRARY_OUTPUT_PATH})
else ()
@@ -275,7 +460,7 @@ function(add_jar _TARGET_NAME)
${CMAKE_JAVA_LIBRARY_OUTPUT_PATH}
)
- if (WIN32 AND NOT CYGWIN AND CMAKE_HOST_SYSTEM_NAME MATCHES "Windows")
+ if (CMAKE_HOST_WIN32 AND NOT CYGWIN AND CMAKE_HOST_SYSTEM_NAME MATCHES "Windows")
set(CMAKE_JAVA_INCLUDE_FLAG_SEP ";")
else ()
set(CMAKE_JAVA_INCLUDE_FLAG_SEP ":")
@@ -300,16 +485,22 @@ function(add_jar _TARGET_NAME)
set(_JAVA_CLASS_FILES)
set(_JAVA_COMPILE_FILES)
+ set(_JAVA_COMPILE_FILELISTS)
set(_JAVA_DEPENDS)
set(_JAVA_COMPILE_DEPENDS)
set(_JAVA_RESOURCE_FILES)
+ set(_JAVA_RESOURCE_FILES_RELATIVE)
foreach(_JAVA_SOURCE_FILE ${_JAVA_SOURCE_FILES})
get_filename_component(_JAVA_EXT ${_JAVA_SOURCE_FILE} EXT)
get_filename_component(_JAVA_FILE ${_JAVA_SOURCE_FILE} NAME_WE)
get_filename_component(_JAVA_PATH ${_JAVA_SOURCE_FILE} PATH)
get_filename_component(_JAVA_FULL ${_JAVA_SOURCE_FILE} ABSOLUTE)
- if (_JAVA_EXT MATCHES ".java")
+ if (_JAVA_SOURCE_FILE MATCHES "^@(.+)$")
+ get_filename_component(_JAVA_FULL ${CMAKE_MATCH_1} ABSOLUTE)
+ list(APPEND _JAVA_COMPILE_FILELISTS ${_JAVA_FULL})
+
+ elseif (_JAVA_EXT MATCHES ".java")
file(RELATIVE_PATH _JAVA_REL_BINARY_PATH ${_add_jar_OUTPUT_DIR} ${_JAVA_FULL})
file(RELATIVE_PATH _JAVA_REL_SOURCE_PATH ${CMAKE_CURRENT_SOURCE_DIR} ${_JAVA_FULL})
string(LENGTH ${_JAVA_REL_BINARY_PATH} _BIN_LEN)
@@ -339,7 +530,8 @@ function(add_jar _TARGET_NAME)
__java_copy_file(${CMAKE_CURRENT_SOURCE_DIR}/${_JAVA_SOURCE_FILE}
${CMAKE_JAVA_CLASS_OUTPUT_PATH}/${_JAVA_SOURCE_FILE}
"Copying ${_JAVA_SOURCE_FILE} to the build directory")
- list(APPEND _JAVA_RESOURCE_FILES ${_JAVA_SOURCE_FILE})
+ list(APPEND _JAVA_RESOURCE_FILES ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/${_JAVA_SOURCE_FILE})
+ list(APPEND _JAVA_RESOURCE_FILES_RELATIVE ${_JAVA_SOURCE_FILE})
endif ()
endforeach()
@@ -367,11 +559,21 @@ function(add_jar _TARGET_NAME)
file(WRITE ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist "")
endif()
- if (_JAVA_COMPILE_FILES)
- # Create the list of files to compile.
- set(_JAVA_SOURCES_FILE ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_sources)
- string(REPLACE ";" "\"\n\"" _JAVA_COMPILE_STRING "\"${_JAVA_COMPILE_FILES}\"")
- file(WRITE ${_JAVA_SOURCES_FILE} ${_JAVA_COMPILE_STRING})
+ if (_JAVA_COMPILE_FILES OR _JAVA_COMPILE_FILELISTS)
+ set (_JAVA_SOURCES_FILELISTS)
+
+ if (_JAVA_COMPILE_FILES)
+ # Create the list of files to compile.
+ set(_JAVA_SOURCES_FILE ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_sources)
+ string(REPLACE ";" "\"\n\"" _JAVA_COMPILE_STRING "\"${_JAVA_COMPILE_FILES}\"")
+ file(WRITE ${_JAVA_SOURCES_FILE} ${_JAVA_COMPILE_STRING})
+ list (APPEND _JAVA_SOURCES_FILELISTS "@${_JAVA_SOURCES_FILE}")
+ endif()
+ if (_JAVA_COMPILE_FILELISTS)
+ foreach (_JAVA_FILELIST IN LISTS _JAVA_COMPILE_FILELISTS)
+ list (APPEND _JAVA_SOURCES_FILELISTS "@${_JAVA_FILELIST}")
+ endforeach()
+ endif()
# Compile the java files and create a list of class files
add_custom_command(
@@ -381,9 +583,9 @@ function(add_jar _TARGET_NAME)
${CMAKE_JAVA_COMPILE_FLAGS}
-classpath "${CMAKE_JAVA_INCLUDE_PATH_FINAL}"
-d ${CMAKE_JAVA_CLASS_OUTPUT_PATH}
- @${_JAVA_SOURCES_FILE}
+ ${_JAVA_SOURCES_FILELISTS}
COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME}
- DEPENDS ${_JAVA_COMPILE_FILES} ${_JAVA_COMPILE_DEPENDS}
+ DEPENDS ${_JAVA_COMPILE_FILES} ${_JAVA_COMPILE_FILELISTS} ${_JAVA_COMPILE_DEPENDS}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Building Java objects for ${_TARGET_NAME}.jar"
)
@@ -405,8 +607,8 @@ function(add_jar _TARGET_NAME)
add_custom_command(
OUTPUT ${_JAVA_JAR_OUTPUT_PATH}
COMMAND ${Java_JAR_EXECUTABLE}
- -cf${_ENTRY_POINT_OPTION} ${_JAVA_JAR_OUTPUT_PATH} ${_ENTRY_POINT_VALUE}
- ${_JAVA_RESOURCE_FILES} @java_class_filelist
+ -cf${_ENTRY_POINT_OPTION}${_MANIFEST_OPTION} ${_JAVA_JAR_OUTPUT_PATH} ${_ENTRY_POINT_VALUE} ${_MANIFEST_VALUE}
+ ${_JAVA_RESOURCE_FILES_RELATIVE} @java_class_filelist
COMMAND ${CMAKE_COMMAND}
-D_JAVA_TARGET_DIR=${_add_jar_OUTPUT_DIR}
-D_JAVA_TARGET_OUTPUT_NAME=${_JAVA_TARGET_OUTPUT_NAME}
@@ -425,8 +627,8 @@ function(add_jar _TARGET_NAME)
add_custom_command(
OUTPUT ${_JAVA_JAR_OUTPUT_PATH}
COMMAND ${Java_JAR_EXECUTABLE}
- -cf${_ENTRY_POINT_OPTION} ${_JAVA_JAR_OUTPUT_PATH} ${_ENTRY_POINT_VALUE}
- ${_JAVA_RESOURCE_FILES} @java_class_filelist
+ -cf${_ENTRY_POINT_OPTION}${_MANIFEST_OPTION} ${_JAVA_JAR_OUTPUT_PATH} ${_ENTRY_POINT_VALUE} ${_MANIFEST_VALUE}
+ ${_JAVA_RESOURCE_FILES_RELATIVE} @java_class_filelist
COMMAND ${CMAKE_COMMAND}
-D_JAVA_TARGET_DIR=${_add_jar_OUTPUT_DIR}
-D_JAVA_TARGET_OUTPUT_NAME=${_JAVA_TARGET_OUTPUT_NAME}
@@ -488,7 +690,26 @@ function(add_jar _TARGET_NAME)
endfunction()
-function(INSTALL_JAR _TARGET_NAME _DESTINATION)
+function(INSTALL_JAR _TARGET_NAME)
+ if (ARGC EQUAL 2)
+ set (_DESTINATION ${ARGV1})
+ else()
+ cmake_parse_arguments(_install_jar
+ ""
+ "DESTINATION;COMPONENT"
+ ""
+ ${ARGN})
+ if (_install_jar_DESTINATION)
+ set (_DESTINATION ${_install_jar_DESTINATION})
+ else()
+ message(SEND_ERROR "install_jar: ${_TARGET_NAME}: DESTINATION must be specified.")
+ endif()
+
+ if (_install_jar_COMPONENT)
+ set (_COMPONENT COMPONENT ${_install_jar_COMPONENT})
+ endif()
+ endif()
+
get_property(__FILES
TARGET
${_TARGET_NAME}
@@ -502,13 +723,33 @@ function(INSTALL_JAR _TARGET_NAME _DESTINATION)
${__FILES}
DESTINATION
${_DESTINATION}
+ ${_COMPONENT}
)
else ()
- message(SEND_ERROR "The target ${_TARGET_NAME} is not known in this scope.")
+ message(SEND_ERROR "install_jar: The target ${_TARGET_NAME} is not known in this scope.")
endif ()
endfunction()
-function(INSTALL_JNI_SYMLINK _TARGET_NAME _DESTINATION)
+function(INSTALL_JNI_SYMLINK _TARGET_NAME)
+ if (ARGC EQUAL 2)
+ set (_DESTINATION ${ARGV1})
+ else()
+ cmake_parse_arguments(_install_jni_symlink
+ ""
+ "DESTINATION;COMPONENT"
+ ""
+ ${ARGN})
+ if (_install_jni_symlink_DESTINATION)
+ set (_DESTINATION ${_install_jni_symlink_DESTINATION})
+ else()
+ message(SEND_ERROR "install_jni_symlink: ${_TARGET_NAME}: DESTINATION must be specified.")
+ endif()
+
+ if (_install_jni_symlink_COMPONENT)
+ set (_COMPONENT COMPONENT ${_install_jni_symlink_COMPONENT})
+ endif()
+ endif()
+
get_property(__SYMLINK
TARGET
${_TARGET_NAME}
@@ -522,9 +763,10 @@ function(INSTALL_JNI_SYMLINK _TARGET_NAME _DESTINATION)
${__SYMLINK}
DESTINATION
${_DESTINATION}
+ ${_COMPONENT}
)
else ()
- message(SEND_ERROR "The target ${_TARGET_NAME} is not known in this scope.")
+ message(SEND_ERROR "install_jni_symlink: The target ${_TARGET_NAME} is not known in this scope.")
endif ()
endfunction()
@@ -948,3 +1190,101 @@ function(create_javadoc _target)
DESTINATION ${_javadoc_installpath}
)
endfunction()
+
+function (create_javah)
+ cmake_parse_arguments(_create_javah
+ ""
+ "TARGET;GENERATED_FILES;OUTPUT_NAME;OUTPUT_DIR"
+ "CLASSES;CLASSPATH;DEPENDS"
+ ${ARGN})
+
+ # ckeck parameters
+ if (NOT _create_javah_TARGET AND NOT _create_javah_GENERATED_FILES)
+ message (FATAL_ERROR "create_javah: TARGET or GENERATED_FILES must be specified.")
+ endif()
+ if (_create_javah_OUTPUT_NAME AND _create_javah_OUTPUT_DIR)
+ message (FATAL_ERROR "create_javah: OUTPUT_NAME and OUTPUT_DIR are mutually exclusive.")
+ endif()
+
+ if (NOT _create_javah_CLASSES)
+ message (FATAL_ERROR "create_javah: CLASSES is a required parameter.")
+ endif()
+
+ set (_output_files)
+ if (WIN32 AND NOT CYGWIN AND CMAKE_HOST_SYSTEM_NAME MATCHES "Windows")
+ set(_classpath_sep "$<SEMICOLON>")
+ else ()
+ set(_classpath_sep ":")
+ endif()
+
+ # handle javah options
+ set (_javah_options)
+
+ if (_create_javah_CLASSPATH)
+ # CLASSPATH can specify directories, jar files or targets created with add_jar command
+ set (_classpath)
+ foreach (_path IN LISTS _create_javah_CLASSPATH)
+ if (TARGET ${_path})
+ get_target_property (_jar_path ${_path} JAR_FILE)
+ if (_jar_path)
+ list (APPEND _classpath "${_jar_path}")
+ list (APPEND _create_javah_DEPENDS "${_path}")
+ else()
+ message(SEND_ERROR "create_javah: CLASSPATH target ${_path} is not a jar.")
+ endif()
+ elseif (EXISTS "${_path}")
+ list (APPEND _classpath "${_path}")
+ if (NOT IS_DIRECTORY "${_path}")
+ list (APPEND _create_javah_DEPENDS "${_path}")
+ endif()
+ else()
+ message(SEND_ERROR "create_javah: CLASSPATH entry ${_path} does not exist.")
+ endif()
+ endforeach()
+ string (REPLACE ";" "${_classpath_sep}" _classpath "${_classpath}")
+ list (APPEND _javah_options -classpath "${_classpath}")
+ endif()
+
+ if (_create_javah_OUTPUT_DIR)
+ list (APPEND _javah_options -d "${_create_javah_OUTPUT_DIR}")
+ endif()
+
+ if (_create_javah_OUTPUT_NAME)
+ list (APPEND _javah_options -o "${_create_javah_OUTPUT_NAME}")
+ set (_output_files "${_create_javah_OUTPUT_NAME}")
+
+ get_filename_component (_create_javah_OUTPUT_DIR "${_create_javah_OUTPUT_NAME}" DIRECTORY)
+ get_filename_component (_create_javah_OUTPUT_DIR "${_create_javah_OUTPUT_DIR}" ABSOLUTE)
+ endif()
+
+ if (NOT _create_javah_OUTPUT_DIR)
+ set (_create_javah_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+ endif()
+
+ if (NOT _create_javah_OUTPUT_NAME)
+ # compute output names
+ foreach (_class IN LISTS _create_javah_CLASSES)
+ string (REPLACE "." "_" _c_header "${_class}")
+ set (_c_header "${_create_javah_OUTPUT_DIR}/${_c_header}.h")
+ list (APPEND _output_files "${_c_header}")
+ endforeach()
+ endif()
+
+ # finalize custom command arguments
+ if (_create_javah_DEPENDS)
+ list (INSERT _create_javah_DEPENDS 0 DEPENDS)
+ endif()
+
+ add_custom_command (OUTPUT ${_output_files}
+ COMMAND "${Java_JAVAH_EXECUTABLE}" ${_javah_options} -jni ${_create_javah_CLASSES}
+ ${_create_javah_DEPENDS}
+ WORKING_DIRECTORY ${_create_javah_OUTPUT_DIR}
+ COMMENT "Building C header files from classes...")
+
+ if (_create_javah_TARGET)
+ add_custom_target (${_create_javah_TARGET} ALL DEPENDS ${_output_files})
+ endif()
+ if (_create_javah_GENERATED_FILES)
+ set (${_create_javah_GENERATED_FILES} ${_output_files} PARENT_SCOPE)
+ endif()
+endfunction()
diff --git a/Modules/UseJavaClassFilelist.cmake b/Modules/UseJavaClassFilelist.cmake
index 6f3a4e7a9..e8e6f014c 100644
--- a/Modules/UseJavaClassFilelist.cmake
+++ b/Modules/UseJavaClassFilelist.cmake
@@ -1,8 +1,14 @@
+#.rst:
+# UseJavaClassFilelist
+# --------------------
#
-# This script create a list of compiled Java class files to be added to a
-# jar file. This avoids including cmake files which get created in the
-# binary directory.
#
+#
+#
+#
+# This script create a list of compiled Java class files to be added to
+# a jar file. This avoids including cmake files which get created in
+# the binary directory.
#=============================================================================
# Copyright 2010-2011 Andreas schneider <asn@redhat.com>
diff --git a/Modules/UseJavaSymlinks.cmake b/Modules/UseJavaSymlinks.cmake
index 88dd7689c..90ffdd535 100644
--- a/Modules/UseJavaSymlinks.cmake
+++ b/Modules/UseJavaSymlinks.cmake
@@ -1,6 +1,12 @@
+#.rst:
+# UseJavaSymlinks
+# ---------------
+#
+#
#
-# Helper script for UseJava.cmake
#
+#
+# Helper script for UseJava.cmake
#=============================================================================
# Copyright 2010-2011 Andreas schneider <asn@redhat.com>
diff --git a/Modules/UsePkgConfig.cmake b/Modules/UsePkgConfig.cmake
index b1569f9da..6a38502ca 100644
--- a/Modules/UsePkgConfig.cmake
+++ b/Modules/UsePkgConfig.cmake
@@ -1,15 +1,21 @@
-# - Obsolete pkg-config module for CMake, use FindPkgConfig instead.
+#.rst:
+# UsePkgConfig
+# ------------
+#
+# Obsolete pkg-config module for CMake, use FindPkgConfig instead.
+#
+#
#
# This module defines the following macro:
#
# PKGCONFIG(package includedir libdir linkflags cflags)
#
-# Calling PKGCONFIG will fill the desired information into the 4 given arguments,
-# e.g. PKGCONFIG(libart-2.0 LIBART_INCLUDE_DIR LIBART_LINK_DIR LIBART_LINK_FLAGS LIBART_CFLAGS)
-# if pkg-config was NOT found or the specified software package doesn't exist, the
-# variable will be empty when the function returns, otherwise they will contain
+# Calling PKGCONFIG will fill the desired information into the 4 given
+# arguments, e.g. PKGCONFIG(libart-2.0 LIBART_INCLUDE_DIR
+# LIBART_LINK_DIR LIBART_LINK_FLAGS LIBART_CFLAGS) if pkg-config was NOT
+# found or the specified software package doesn't exist, the variable
+# will be empty when the function returns, otherwise they will contain
# the respective information
-#
#=============================================================================
# Copyright 2006-2009 Kitware, Inc.
diff --git a/Modules/UseQt4.cmake b/Modules/UseQt4.cmake
index f05a3d5f3..cba22af8c 100644
--- a/Modules/UseQt4.cmake
+++ b/Modules/UseQt4.cmake
@@ -1,7 +1,12 @@
-# - Use Module for QT4
-# Sets up C and C++ to use Qt 4. It is assumed that FindQt.cmake
-# has already been loaded. See FindQt.cmake for information on
-# how to load Qt 4 into your CMake project.
+#.rst:
+# UseQt4
+# ------
+#
+# Use Module for QT4
+#
+# Sets up C and C++ to use Qt 4. It is assumed that FindQt.cmake has
+# already been loaded. See FindQt.cmake for information on how to load
+# Qt 4 into your CMake project.
#=============================================================================
# Copyright 2005-2009 Kitware, Inc.
@@ -17,13 +22,7 @@
# License text for the above reference.)
add_definitions(${QT_DEFINITIONS})
-set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG QT_DEBUG)
-set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_RELEASE QT_NO_DEBUG)
-set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_RELWITHDEBINFO QT_NO_DEBUG)
-set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_MINSIZEREL QT_NO_DEBUG)
-if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
- set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS QT_NO_DEBUG)
-endif()
+set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS $<$<NOT:$<CONFIG:Debug>>:QT_NO_DEBUG>)
if(QT_INCLUDE_DIRS_NO_SYSTEM)
include_directories(${QT_INCLUDE_DIR})
@@ -58,7 +57,7 @@ endif ()
# list dependent modules, so dependent libraries are added
set(QT_QT3SUPPORT_MODULE_DEPENDS QTGUI QTSQL QTXML QTNETWORK QTCORE)
-set(QT_QTSVG_MODULE_DEPENDS QTGUI QTXML QTCORE)
+set(QT_QTSVG_MODULE_DEPENDS QTGUI QTCORE)
set(QT_QTUITOOLS_MODULE_DEPENDS QTGUI QTXML QTCORE)
set(QT_QTHELP_MODULE_DEPENDS QTGUI QTSQL QTXML QTNETWORK QTCORE)
if(QT_QTDBUS_FOUND)
@@ -99,7 +98,9 @@ foreach(module QT3SUPPORT QTOPENGL QTASSISTANT QTDESIGNER QTMOTIF QTNSPLUGIN
include_directories(SYSTEM ${QT_${module}_INCLUDE_DIR})
endif(QT_INCLUDE_DIRS_NO_SYSTEM)
endif()
- set(QT_LIBRARIES ${QT_LIBRARIES} ${QT_${module}_LIBRARY})
+ if(QT_USE_${module} OR QT_IS_STATIC)
+ set(QT_LIBRARIES ${QT_LIBRARIES} ${QT_${module}_LIBRARY})
+ endif()
set(QT_LIBRARIES_PLUGINS ${QT_LIBRARIES_PLUGINS} ${QT_${module}_PLUGINS})
if(QT_IS_STATIC)
set(QT_LIBRARIES ${QT_LIBRARIES} ${QT_${module}_LIB_DEPENDENCIES})
diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake
index 2a095854c..d757f65f7 100644
--- a/Modules/UseSWIG.cmake
+++ b/Modules/UseSWIG.cmake
@@ -1,23 +1,48 @@
-# - SWIG module for CMake
-# Defines the following macros:
-# SWIG_ADD_MODULE(name language [ files ])
-# - Define swig module with given name and specified language
-# SWIG_LINK_LIBRARIES(name [ libraries ])
-# - Link libraries to swig module
-# All other macros are for internal use only.
-# To get the actual name of the swig module,
-# use: ${SWIG_MODULE_${name}_REAL_NAME}.
-# Set Source files properties such as CPLUSPLUS and SWIG_FLAGS to specify
-# special behavior of SWIG. Also global CMAKE_SWIG_FLAGS can be used to add
-# special flags to all swig calls.
+#.rst:
+# UseSWIG
+# -------
+#
+# Defines the following macros for use with SWIG:
+#
+# ::
+#
+# SWIG_ADD_MODULE(name language [ files ])
+# - Define swig module with given name and specified language
+# SWIG_LINK_LIBRARIES(name [ libraries ])
+# - Link libraries to swig module
+#
+# Source files properties on module files can be set before the invocation
+# of the SWIG_ADD_MODULE macro to specify special behavior of SWIG.
+#
+# The source file property CPLUSPLUS calls SWIG in c++ mode, e.g.::
+#
+# set_property(SOURCE mymod.i PROPERTY CPLUSPLUS ON)
+# swig_add_module(mymod python mymod.i)
+#
+# The source file property SWIG_FLAGS adds custom flags to the SWIG executable.
+#
+# The source-file property SWIG_MODULE_NAME have to be provided to specify the actual
+# import name of the module in the target language if it cannot be scanned automatically
+# from source or different from the module file basename.::
+#
+# set_property(SOURCE mymod.i PROPERTY SWIG_MODULE_NAME mymod_realname)
+#
+# To get the name of the swig module target library, use: ${SWIG_MODULE_${name}_REAL_NAME}.
+#
+# Also some variables can be set to specify special behavior of SWIG.
+#
+# CMAKE_SWIG_FLAGS can be used to add special flags to all swig calls.
+#
# Another special variable is CMAKE_SWIG_OUTDIR, it allows one to specify
# where to write all the swig generated module (swig -outdir option)
-# The name-specific variable SWIG_MODULE_<name>_EXTRA_DEPS may be used
-# to specify extra dependencies for the generated modules.
-# If the source file generated by swig need some special flag you can use
-# set_source_files_properties( ${swig_generated_file_fullname}
-# PROPERTIES COMPILE_FLAGS "-bla")
-
+#
+# The name-specific variable SWIG_MODULE_<name>_EXTRA_DEPS may be used to specify extra
+# dependencies for the generated modules.
+#
+# If the source file generated by swig need some special flag you can use::
+#
+# set_source_files_properties( ${swig_generated_file_fullname}
+# PROPERTIES COMPILE_FLAGS "-bla")
#=============================================================================
# Copyright 2004-2009 Kitware, Inc.
@@ -48,15 +73,22 @@ macro(SWIG_MODULE_INITIALIZE name language)
set(SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG "${swig_lowercase_language}")
set(SWIG_MODULE_${name}_REAL_NAME "${name}")
- if("${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "UNKNOWN")
+ if (";${CMAKE_SWIG_FLAGS};" MATCHES ";-noproxy;")
+ set (SWIG_MODULE_${name}_NOPROXY TRUE)
+ endif ()
+ if("x${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "xUNKNOWN")
message(FATAL_ERROR "SWIG Error: Language \"${language}\" not found")
- elseif("${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "PYTHON")
- # when swig is used without the -interface it will produce in the module.py
- # a 'import _modulename' statement, which implies having a corresponding
- # _modulename.so (*NIX), _modulename.pyd (Win32).
+ elseif("x${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "xPYTHON" AND NOT SWIG_MODULE_${name}_NOPROXY)
+ # swig will produce a module.py containing an 'import _modulename' statement,
+ # which implies having a corresponding _modulename.so (*NIX), _modulename.pyd (Win32),
+ # unless the -noproxy flag is used
set(SWIG_MODULE_${name}_REAL_NAME "_${name}")
- elseif("${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "PERL")
+ elseif("x${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "xPERL")
set(SWIG_MODULE_${name}_EXTRA_FLAGS "-shadow")
+ elseif("x${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "xCSHARP")
+ # This makes sure that the name used in the generated DllImport
+ # matches the library name created by CMake
+ set(SWIG_MODULE_${name}_EXTRA_FLAGS "-dllimport;${name}")
endif()
endmacro()
@@ -70,7 +102,30 @@ macro(SWIG_GET_EXTRA_OUTPUT_FILES language outfiles generatedpath infile)
get_source_file_property(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename
${infile} SWIG_MODULE_NAME)
if(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename STREQUAL "NOTFOUND")
- get_filename_component(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename "${infile}" NAME_WE)
+
+ # try to get module name from "%module foo" syntax
+ if ( EXISTS ${infile} )
+ file ( STRINGS ${infile} _MODULE_NAME REGEX "[ ]*%module[ ]*[a-zA-Z0-9_]+.*" )
+ endif ()
+ if ( _MODULE_NAME )
+ string ( REGEX REPLACE "[ ]*%module[ ]*([a-zA-Z0-9_]+).*" "\\1" _MODULE_NAME "${_MODULE_NAME}" )
+ set(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename "${_MODULE_NAME}")
+
+ else ()
+ # try to get module name from "%module (options=...) foo" syntax
+ if ( EXISTS ${infile} )
+ file ( STRINGS ${infile} _MODULE_NAME REGEX "[ ]*%module[ ]*\\(.*\\)[ ]*[a-zA-Z0-9_]+.*" )
+ endif ()
+ if ( _MODULE_NAME )
+ string ( REGEX REPLACE "[ ]*%module[ ]*\\(.*\\)[ ]*([a-zA-Z0-9_]+).*" "\\1" _MODULE_NAME "${_MODULE_NAME}" )
+ set(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename "${_MODULE_NAME}")
+
+ else ()
+ # fallback to file basename
+ get_filename_component(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename ${infile} NAME_WE)
+ endif ()
+ endif ()
+
endif()
foreach(it ${SWIG_${language}_EXTRA_FILE_EXTENSION})
set(${outfiles} ${${outfiles}}
@@ -83,7 +138,6 @@ endmacro()
#
macro(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile)
set(swig_full_infile ${infile})
- get_filename_component(swig_source_file_path "${infile}" PATH)
get_filename_component(swig_source_file_name_we "${infile}" NAME_WE)
get_source_file_property(swig_source_file_generated ${infile} GENERATED)
get_source_file_property(swig_source_file_cplusplus ${infile} CPLUSPLUS)
@@ -91,47 +145,22 @@ macro(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile)
if("${swig_source_file_flags}" STREQUAL "NOTFOUND")
set(swig_source_file_flags "")
endif()
- set(swig_source_file_fullname "${infile}")
- if(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_SOURCE_DIR}")
- string(REGEX REPLACE
- "^${CMAKE_CURRENT_SOURCE_DIR}" ""
- swig_source_file_relative_path
- "${swig_source_file_path}")
- else()
- if(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_BINARY_DIR}")
- string(REGEX REPLACE
- "^${CMAKE_CURRENT_BINARY_DIR}" ""
- swig_source_file_relative_path
- "${swig_source_file_path}")
- set(swig_source_file_generated 1)
- else()
- set(swig_source_file_relative_path "${swig_source_file_path}")
- if(swig_source_file_generated)
- set(swig_source_file_fullname "${CMAKE_CURRENT_BINARY_DIR}/${infile}")
- else()
- set(swig_source_file_fullname "${CMAKE_CURRENT_SOURCE_DIR}/${infile}")
- endif()
- endif()
- endif()
+ get_filename_component(swig_source_file_fullname "${infile}" ABSOLUTE)
- set(swig_generated_file_fullname
- "${CMAKE_CURRENT_BINARY_DIR}")
- if(swig_source_file_relative_path)
- set(swig_generated_file_fullname
- "${swig_generated_file_fullname}/${swig_source_file_relative_path}")
- endif()
# If CMAKE_SWIG_OUTDIR was specified then pass it to -outdir
if(CMAKE_SWIG_OUTDIR)
set(swig_outdir ${CMAKE_SWIG_OUTDIR})
else()
set(swig_outdir ${CMAKE_CURRENT_BINARY_DIR})
endif()
- SWIG_GET_EXTRA_OUTPUT_FILES(${SWIG_MODULE_${name}_LANGUAGE}
- swig_extra_generated_files
- "${swig_outdir}"
- "${infile}")
+ if (NOT SWIG_MODULE_${name}_NOPROXY)
+ SWIG_GET_EXTRA_OUTPUT_FILES(${SWIG_MODULE_${name}_LANGUAGE}
+ swig_extra_generated_files
+ "${swig_outdir}"
+ "${swig_source_file_fullname}")
+ endif()
set(swig_generated_file_fullname
- "${swig_generated_file_fullname}/${swig_source_file_name_we}")
+ "${swig_outdir}/${swig_source_file_name_we}")
# add the language into the name of the file (i.e. TCL_wrap)
# this allows for the same .i file to be wrapped into different languages
set(swig_generated_file_fullname
@@ -148,6 +177,7 @@ macro(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile)
#message("Full path to source file: ${swig_source_file_fullname}")
#message("Full path to the output file: ${swig_generated_file_fullname}")
get_directory_property(cmake_include_directories INCLUDE_DIRECTORIES)
+ list(REMOVE_DUPLICATES cmake_include_directories)
set(swig_include_dirs)
foreach(it ${cmake_include_directories})
set(swig_include_dirs ${swig_include_dirs} "-I${it}")
@@ -192,7 +222,7 @@ macro(SWIG_ADD_MODULE name language)
set(swig_dot_i_sources)
set(swig_other_sources)
foreach(it ${ARGN})
- if(${it} MATCHES ".*\\.i$")
+ if(${it} MATCHES "\\.i$")
set(swig_dot_i_sources ${swig_dot_i_sources} "${it}")
else()
set(swig_other_sources ${swig_other_sources} "${it}")
@@ -211,8 +241,14 @@ macro(SWIG_ADD_MODULE name language)
MODULE
${swig_generated_sources}
${swig_other_sources})
+ set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES NO_SONAME ON)
string(TOLOWER "${language}" swig_lowercase_language)
- if ("${swig_lowercase_language}" STREQUAL "java")
+ if ("${swig_lowercase_language}" STREQUAL "octave")
+ set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "")
+ set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".oct")
+ elseif ("${swig_lowercase_language}" STREQUAL "go")
+ set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "")
+ elseif ("${swig_lowercase_language}" STREQUAL "java")
if (APPLE)
# In java you want:
# System.loadLibrary("LIBRARY");
@@ -222,8 +258,9 @@ macro(SWIG_ADD_MODULE name language)
# Linux : libLIBRARY.so
set_target_properties (${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".jnilib")
endif ()
- endif ()
- if ("${swig_lowercase_language}" STREQUAL "python")
+ elseif ("${swig_lowercase_language}" STREQUAL "lua")
+ set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "")
+ elseif ("${swig_lowercase_language}" STREQUAL "python")
# this is only needed for the python case where a _modulename.so is generated
set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "")
# Python extension modules on Windows must have the extension ".pyd"
@@ -237,6 +274,19 @@ macro(SWIG_ADD_MODULE name language)
if(WIN32 AND NOT CYGWIN)
set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".pyd")
endif()
+ elseif ("${swig_lowercase_language}" STREQUAL "r")
+ set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "")
+ elseif ("${swig_lowercase_language}" STREQUAL "ruby")
+ # In ruby you want:
+ # require 'LIBRARY'
+ # then ruby will look for a library whose name is platform dependent, namely
+ # MacOS : LIBRARY.bundle
+ # Windows: LIBRARY.dll
+ # Linux : LIBRARY.so
+ set_target_properties (${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "")
+ if (APPLE)
+ set_target_properties (${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".bundle")
+ endif ()
endif ()
endmacro()
diff --git a/Modules/UseVTK40.cmake b/Modules/UseVTK40.cmake
deleted file mode 100644
index d6bdaaa52..000000000
--- a/Modules/UseVTK40.cmake
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-
-#=============================================================================
-# Copyright 2002-2009 Kitware, Inc.
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-# (To distribute this file outside of CMake, substitute the full
-# License text for the above reference.)
-
-# This is an implementation detail for using VTK 4.0 with the
-# FindVTK.cmake module. Do not include directly by name. This should
-# be included only when FindVTK.cmake sets the VTK_USE_FILE variable
-# to point here.
-
-# Add compiler flags needed to use VTK.
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${VTK_REQUIRED_C_FLAGS}")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${VTK_REQUIRED_CXX_FLAGS}")
-
-# Add include directories needed to use VTK.
-include_directories(${VTK_INCLUDE_DIRS})
-
-# Add link directories needed to use VTK.
-link_directories(${VTK_LIBRARY_DIRS})
diff --git a/Modules/UseVTKBuildSettings40.cmake b/Modules/UseVTKBuildSettings40.cmake
deleted file mode 100644
index 474f67c9c..000000000
--- a/Modules/UseVTKBuildSettings40.cmake
+++ /dev/null
@@ -1,38 +0,0 @@
-#
-
-#=============================================================================
-# Copyright 2002-2009 Kitware, Inc.
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-# (To distribute this file outside of CMake, substitute the full
-# License text for the above reference.)
-
-# Implementation detail for FindVTK.cmake to let it provide a
-# VTK_BUILD_SETTINGS_FILE for VTK 4.0.
-
-set(CMAKE_BUILD_SETTING_CMAKE_MAJOR_VERSION "${VTK40_CMAKE_MAJOR_VERSION}")
-set(CMAKE_BUILD_SETTING_CMAKE_MINOR_VERSION "${VTK40_CMAKE_MINOR_VERSION}")
-set(CMAKE_BUILD_SETTING_PROJECT_NAME "VTK")
-
-set(CMAKE_BUILD_SETTING_C_COMPILER "${VTK40_CMAKE_C_COMPILER}")
-set(CMAKE_BUILD_SETTING_C_FLAGS "${VTK40_CMAKE_C_FLAGS}")
-set(CMAKE_BUILD_SETTING_C_FLAGS_DEBUG "${VTK40_CMAKE_C_FLAGS_DEBUG}")
-set(CMAKE_BUILD_SETTING_C_FLAGS_RELEASE "${VTK40_CMAKE_C_FLAGS_RELEASE}")
-set(CMAKE_BUILD_SETTING_C_FLAGS_MINSIZEREL "${VTK40_CMAKE_C_FLAGS_MINSIZEREL}")
-set(CMAKE_BUILD_SETTING_C_FLAGS_RELWITHDEBINFO "${VTK40_CMAKE_C_FLAGS_RELWITHDEBINFO}")
-
-set(CMAKE_BUILD_SETTING_CXX_COMPILER "${VTK40_CMAKE_CXX_COMPILER}")
-set(CMAKE_BUILD_SETTING_CXX_FLAGS "${VTK40_CMAKE_CXX_FLAGS}")
-set(CMAKE_BUILD_SETTING_CXX_FLAGS_DEBUG "${VTK40_CMAKE_CXX_FLAGS_DEBUG}")
-set(CMAKE_BUILD_SETTING_CXX_FLAGS_RELEASE "${VTK40_CMAKE_CXX_FLAGS_RELEASE}")
-set(CMAKE_BUILD_SETTING_CXX_FLAGS_MINSIZEREL "${VTK40_CMAKE_CXX_FLAGS_MINSIZEREL}")
-set(CMAKE_BUILD_SETTING_CXX_FLAGS_RELWITHDEBINFO "${VTK40_CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
-
-set(CMAKE_BUILD_SETTING_BUILD_TYPE "${VTK40_CMAKE_BUILD_TYPE}")
-set(CMAKE_BUILD_SETTING_BUILD_TOOL "${VTK40_CMAKE_BUILD_TOOL}")
diff --git a/Modules/UseVTKConfig40.cmake b/Modules/UseVTKConfig40.cmake
deleted file mode 100644
index 554b8c447..000000000
--- a/Modules/UseVTKConfig40.cmake
+++ /dev/null
@@ -1,409 +0,0 @@
-#
-
-#=============================================================================
-# Copyright 2002-2009 Kitware, Inc.
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-# (To distribute this file outside of CMake, substitute the full
-# License text for the above reference.)
-
-# This is an implementation detail for using VTK 4.0 with the
-# FindVTK.cmake module. Do not include directly.
-
-# Hard-code the version number since it isn't provided by VTK 4.0.
-set(VTK_MAJOR_VERSION 4)
-set(VTK_MINOR_VERSION 0)
-set(VTK_BUILD_VERSION 2)
-
-# Provide a new UseVTK file that doesn't do a full LOAD_CACHE.
-set(VTK_USE_FILE ${CMAKE_ROOT}/Modules/UseVTK40.cmake)
-
-# Provide a build settings file.
-set(VTK_BUILD_SETTINGS_FILE ${CMAKE_ROOT}/Modules/UseVTKBuildSettings40.cmake)
-
-# There are no CMake extensions for VTK 4.0.
-set(VTK_CMAKE_EXTENSIONS_DIR "")
-
-# grep "VTK40_" UseVTKConfig40.cmake |sed 's/.*VTK40_\([A-Za-z0-9_]*\).*/ \1/'
-load_cache(${VTK_DIR} READ_WITH_PREFIX VTK40_
- BUILD_SHARED_LIBS
- CMAKE_BUILD_TOOL
- CMAKE_BUILD_TYPE
- CMAKE_CACHE_MAJOR_VERSION
- CMAKE_CACHE_MINOR_VERSION
- CMAKE_CXX_COMPILER
- CMAKE_CXX_FLAGS
- CMAKE_CXX_FLAGS_DEBUG
- CMAKE_CXX_FLAGS_MINSIZEREL
- CMAKE_CXX_FLAGS_RELEASE
- CMAKE_CXX_FLAGS_RELWITHDEBINFO
- CMAKE_C_COMPILER
- CMAKE_C_FLAGS
- CMAKE_C_FLAGS_DEBUG
- CMAKE_C_FLAGS_MINSIZEREL
- CMAKE_C_FLAGS_RELEASE
- CMAKE_C_FLAGS_RELWITHDEBINFO
- CMAKE_INSTALL_PREFIX
- CMAKE_Xutil_INCLUDE_PATH
- EXECUTABLE_OUTPUT_PATH
- JAVA_INCLUDE_PATH2
- LIBRARY_OUTPUT_PATH
- MPIRUN
- MPI_INCLUDE_PATH
- MPI_POSTFLAGS
- MPI_PREFLAGS
- OPENGL_INCLUDE_DIR
- OSMESA_INCLUDE_PATH
- PYTHON_INCLUDE_PATH
- TCL_INCLUDE_PATH
- VLI_INCLUDE_PATH_FOR_VG500
- VLI_INCLUDE_PATH_FOR_VP1000
- VTK_BINARY_DIR
- VTK_DEBUG_LEAKS
- VTK_HAVE_VG500
- VTK_HAVE_VP1000
- VTK_MANGLE_MESA
- VTK_OPENGL_HAS_OSMESA
- VTK_PARSE_JAVA_EXE
- VTK_SOURCE_DIR
- VTK_USE_64BIT_IDS
- VTK_USE_ANSI_STDLIB
- VTK_USE_HYBRID
- VTK_USE_MATROX_IMAGING
- VTK_USE_MPI
- VTK_USE_PARALLEL
- VTK_USE_PATENTED
- VTK_USE_RENDERING
- VTK_USE_VIDEO_FOR_WINDOWS
- VTK_USE_VOLUMEPRO
- VTK_USE_X
- VTK_WRAP_JAVA
- VTK_WRAP_JAVA_EXE
- VTK_WRAP_PYTHON
- VTK_WRAP_PYTHON_EXE
- VTK_WRAP_TCL
- VTK_WRAP_TCL_EXE
- vtkCommonJava_LIB_DEPENDS
- vtkCommonPython_LIB_DEPENDS
- vtkCommonTCL_LIB_DEPENDS
- vtkCommon_LIB_DEPENDS
- vtkFilteringJava_LIB_DEPENDS
- vtkFilteringPython_LIB_DEPENDS
- vtkFilteringTCL_LIB_DEPENDS
- vtkFiltering_LIB_DEPENDS
- vtkGraphicsJava_LIB_DEPENDS
- vtkGraphicsPython_LIB_DEPENDS
- vtkGraphicsTCL_LIB_DEPENDS
- vtkGraphics_LIB_DEPENDS
- vtkHybridJava_LIB_DEPENDS
- vtkHybridPython_LIB_DEPENDS
- vtkHybridTCL_LIB_DEPENDS
- vtkHybrid_LIB_DEPENDS
- vtkIOJava_LIB_DEPENDS
- vtkIOPython_LIB_DEPENDS
- vtkIOTCL_LIB_DEPENDS
- vtkIO_LIB_DEPENDS
- vtkImagingJava_LIB_DEPENDS
- vtkImagingPython_LIB_DEPENDS
- vtkImagingTCL_LIB_DEPENDS
- vtkImaging_LIB_DEPENDS
- vtkParallelJava_LIB_DEPENDS
- vtkParallelPython_LIB_DEPENDS
- vtkParallelTCL_LIB_DEPENDS
- vtkParallel_LIB_DEPENDS
- vtkPatentedJava_LIB_DEPENDS
- vtkPatentedPython_LIB_DEPENDS
- vtkPatentedTCL_LIB_DEPENDS
- vtkPatented_LIB_DEPENDS
- vtkRenderingJava_LIB_DEPENDS
- vtkRenderingPythonTkWidgets_LIB_DEPENDS
- vtkRenderingPython_LIB_DEPENDS
- vtkRenderingTCL_LIB_DEPENDS
- vtkRendering_LIB_DEPENDS
- vtkjpeg_LIB_DEPENDS
- vtkpng_LIB_DEPENDS
- vtkzlib_LIB_DEPENDS
-)
-
-# Copy needed settings from the VTK 4.0 cache.
-set(VTK_BUILD_SHARED ${VTK40_BUILD_SHARED_LIBS})
-set(VTK_DEBUG_LEAKS ${VTK40_VTK_DEBUG_LEAKS})
-set(VTK_HAVE_VG500 ${VTK40_VTK_HAVE_VG500})
-set(VTK_HAVE_VP1000 ${VTK40_VTK_HAVE_VP1000})
-set(VTK_USE_MANGLED_MESA ${VTK40_VTK_MANGLE_MESA})
-set(VTK_MPIRUN_EXE ${VTK40_MPIRUN})
-set(VTK_MPI_POSTFLAGS ${VTK40_MPI_POSTFLAGS})
-set(VTK_MPI_PREFLAGS ${VTK40_MPI_PREFLAGS})
-set(VTK_OPENGL_HAS_OSMESA ${VTK40_VTK_OPENGL_HAS_OSMESA})
-set(VTK_USE_64BIT_IDS ${VTK40_VTK_USE_64BIT_IDS})
-set(VTK_USE_ANSI_STDLIB ${VTK40_VTK_USE_ANSI_STDLIB})
-set(VTK_USE_HYBRID ${VTK40_VTK_USE_HYBRID})
-set(VTK_USE_MATROX_IMAGING ${VTK40_VTK_USE_MATROX_IMAGING})
-set(VTK_USE_MPI ${VTK40_VTK_USE_MPI})
-set(VTK_USE_PARALLEL ${VTK40_VTK_USE_PARALLEL})
-set(VTK_USE_PATENTED ${VTK40_VTK_USE_PATENTED})
-set(VTK_USE_RENDERING ${VTK40_VTK_USE_RENDERING})
-set(VTK_USE_VIDEO_FOR_WINDOWS ${VTK40_VTK_USE_VIDEO_FOR_WINDOWS})
-set(VTK_USE_VOLUMEPRO ${VTK40_VTK_USE_VOLUMEPRO})
-set(VTK_USE_X ${VTK40_VTK_USE_X})
-set(VTK_WRAP_JAVA ${VTK40_VTK_WRAP_JAVA})
-set(VTK_WRAP_PYTHON ${VTK40_VTK_WRAP_PYTHON})
-set(VTK_WRAP_TCL ${VTK40_VTK_WRAP_TCL})
-
-# Create the list of available kits.
-set(VTK_KITS COMMON FILTERING GRAPHICS IMAGING IO)
-if(VTK_USE_RENDERING)
- set(VTK_KITS ${VTK_KITS} RENDERING)
-endif()
-if(VTK_USE_HYBRID)
- set(VTK_KITS ${VTK_KITS} HYBRID)
-endif()
-if(VTK_USE_PARALLEL)
- set(VTK_KITS ${VTK_KITS} PARALLEL)
-endif()
-if(VTK_USE_PATENTED)
- set(VTK_KITS ${VTK_KITS} PATENTED)
-endif()
-
-# Create the list of available languages.
-set(VTK_LANGUAGES "")
-if(VTK_WRAP_TCL)
- set(VTK_LANGUAGES ${VTK_LANGUAGES} TCL)
-endif()
-if(VTK_WRAP_PYTHON)
- set(VTK_LANGUAGES ${VTK_LANGUAGES} PYTHON)
-endif()
-if(VTK_WRAP_JAVA)
- set(VTK_LANGUAGES ${VTK_LANGUAGES} JAVA)
-endif()
-
-# Include directories for other projects installed on the system and
-# used by VTK.
-set(VTK_INCLUDE_DIRS_SYS "")
-if(VTK_USE_RENDERING)
- set(VTK_INCLUDE_DIRS_SYS ${VTK_INCLUDE_DIRS_SYS}
- ${VTK40_OPENGL_INCLUDE_PATH} ${VTK40_OPENGL_INCLUDE_DIR})
- if(VTK_USE_X)
- set(VTK_INCLUDE_DIRS_SYS ${VTK_INCLUDE_DIRS_SYS}
- ${VTK40_CMAKE_Xlib_INCLUDE_PATH} ${VTK40_CMAKE_Xutil_INCLUDE_PATH})
- endif()
-endif()
-
-if(VTK_OPENGL_HAS_OSMESA)
- set(VTK_INCLUDE_DIRS_SYS ${VTK_INCLUDE_DIRS_SYS}
- ${VTK40_OSMESA_INCLUDE_PATH})
-endif()
-
-if(VTK_USE_MPI)
- set(VTK_INCLUDE_DIRS_SYS ${VTK_INCLUDE_DIRS_SYS} ${VTK40_MPI_INCLUDE_PATH})
-endif()
-
-if(VTK_WRAP_TCL)
- set(VTK_INCLUDE_DIRS_SYS ${VTK_INCLUDE_DIRS_SYS} ${VTK40_TCL_INCLUDE_PATH})
-endif()
-
-if(VTK_WRAP_PYTHON)
- set(VTK_INCLUDE_DIRS_SYS ${VTK_INCLUDE_DIRS_SYS} ${VTK40_PYTHON_INCLUDE_PATH})
-endif()
-
-if(VTK_WRAP_JAVA)
- set(VTK_INCLUDE_DIRS_SYS ${VTK_INCLUDE_DIRS_SYS}
- ${VTK40_JAVA_INCLUDE_PATH} ${VTK40_JAVA_INCLUDE_PATH2})
-endif()
-
-if(VTK_HAVE_VG500)
- set(VTK_INCLUDE_DIRS_SYS ${VTK_INCLUDE_DIRS_SYS}
- ${VTK40_VLI_INCLUDE_PATH_FOR_VG500})
-endif()
-
-if(VTK_HAVE_VP1000)
- set(VTK_INCLUDE_DIRS_SYS ${VTK_INCLUDE_DIRS_SYS}
- ${VTK40_VLI_INCLUDE_PATH_FOR_VP1000})
-endif()
-
-# See if this is a build tree or install tree.
-if(EXISTS ${VTK_DIR}/Common)
- # This is a VTK 4.0 build tree.
-
- set(VTK_LIBRARY_DIRS ${VTK40_LIBRARY_OUTPUT_PATH})
-
- # Determine the include directories needed.
- set(VTK_INCLUDE_DIRS ${VTK40_VTK_BINARY_DIR})
- if(VTK_USE_PARALLEL)
- set(VTK_INCLUDE_DIRS ${VTK_INCLUDE_DIRS} ${VTK40_VTK_SOURCE_DIR}/Parallel)
- endif()
- if(VTK_USE_HYBRID)
- set(VTK_INCLUDE_DIRS ${VTK_INCLUDE_DIRS} ${VTK40_VTK_SOURCE_DIR}/Hybrid)
- endif()
- if(VTK_USE_PATENTED)
- set(VTK_INCLUDE_DIRS ${VTK_INCLUDE_DIRS} ${VTK40_VTK_SOURCE_DIR}/Patented)
- endif()
- if(VTK_USE_RENDERING)
- set(VTK_INCLUDE_DIRS ${VTK_INCLUDE_DIRS} ${VTK40_VTK_SOURCE_DIR}/Rendering)
- endif()
-
- # These directories are always needed.
- set(VTK_INCLUDE_DIRS ${VTK_INCLUDE_DIRS}
- ${VTK40_VTK_SOURCE_DIR}/IO
- ${VTK40_VTK_SOURCE_DIR}/Imaging
- ${VTK40_VTK_SOURCE_DIR}/Graphics
- ${VTK40_VTK_SOURCE_DIR}/Filtering
- ${VTK40_VTK_SOURCE_DIR}/Common)
-
- # Give access to a few utilities.
- set(VTK_INCLUDE_DIRS ${VTK_INCLUDE_DIRS}
- ${VTK40_VTK_BINARY_DIR}/Utilities/png
- ${VTK40_VTK_SOURCE_DIR}/Utilities/png
- ${VTK40_VTK_BINARY_DIR}/Utilities/zlib
- ${VTK40_VTK_SOURCE_DIR}/Utilities/zlib)
-
- # Executable locations.
- if(VTK_WRAP_TCL)
- set(VTK_TCL_EXE ${VTK40_EXECUTABLE_OUTPUT_PATH}/vtk)
- set(VTK_WRAP_TCL_EXE ${VTK40_VTK_WRAP_TCL_EXE})
- set(VTK_TCL_HOME ${VTK40_VTK_SOURCE_DIR}/Wrapping/Tcl)
- endif()
- if(VTK_WRAP_PYTHON)
- set(VTK_WRAP_PYTHON_EXE ${VTK40_VTK_WRAP_PYTHON_EXE})
- endif()
- if(VTK_WRAP_JAVA)
- set(VTK_PARSE_JAVA_EXE ${VTK40_VTK_PARSE_JAVA_EXE})
- set(VTK_WRAP_JAVA_EXE ${VTK40_VTK_WRAP_JAVA_EXE})
- endif()
-
-else()
- # This is a VTK 4.0 install tree.
-
- set(VTK_INCLUDE_DIRS ${VTK_DIR})
- set(VTK_LIBRARY_DIRS ${VTK40_CMAKE_INSTALL_PREFIX}/lib/vtk)
-
- # Executable locations.
- if(VTK_WRAP_TCL)
- set(VTK_TCL_EXE ${VTK40_CMAKE_INSTALL_PREFIX}/bin/vtk)
- set(VTK_WRAP_TCL_EXE ${VTK40_CMAKE_INSTALL_PREFIX}/bin/vtkWrapTcl)
- set(VTK_TCL_HOME ${VTK40_CMAKE_INSTALL_PREFIX}/lib/vtk/tcl)
- endif()
- if(VTK_WRAP_PYTHON)
- set(VTK_WRAP_PYTHON_EXE ${VTK40_CMAKE_INSTALL_PREFIX}/bin/vtkWrapPython)
- endif()
- if(VTK_WRAP_JAVA)
- set(VTK_PARSE_JAVA_EXE ${VTK40_CMAKE_INSTALL_PREFIX}/bin/vtkParseJava)
- set(VTK_WRAP_JAVA_EXE ${VTK40_CMAKE_INSTALL_PREFIX}/bin/vtkWrapJava)
- endif()
-endif()
-
-# Add the system include directories last.
-set(VTK_INCLUDE_DIRS ${VTK_INCLUDE_DIRS} ${VTK_INCLUDE_DIRS_SYS})
-
-# Find the required C and C++ compiler flags.
-if(CMAKE_COMPILER_IS_GNUCXX)
- if(WIN32)
- # The platform is gcc on cygwin.
- set(VTK_REQUIRED_CXX_FLAGS "${VTK_REQUIRED_CXX_FLAGS} -mwin32")
- set(VTK_REQUIRED_C_FLAGS "${VTK_REQUIRED_C_FLAGS} -mwin32")
- endif()
-else()
- if(CMAKE_ANSI_CFLAGS)
- set(VTK_REQUIRED_C_FLAGS "${VTK_REQUIRED_C_FLAGS} ${CMAKE_ANSI_CFLAGS}")
- endif()
- if(CMAKE_SYSTEM MATCHES "OSF1-V.*")
- set(VTK_REQUIRED_CXX_FLAGS
- "${VTK_REQUIRED_CXX_FLAGS} -timplicit_local -no_implicit_include")
- endif()
-endif()
-
-if(VTK_USE_X)
- if(CMAKE_X_CFLAGS)
- set(VTK_REQUIRED_C_FLAGS "${VTK_REQUIRED_C_FLAGS} ${CMAKE_X_CFLAGS}")
- set(VTK_REQUIRED_CXX_FLAGS "${VTK_REQUIRED_CXX_FLAGS} ${CMAKE_X_CFLAGS}")
- endif()
-endif()
-
-# Copy library dependencies.
-set(vtkCommonJava_LIB_DEPENDS "${VTK40_vtkCommonJava_LIB_DEPENDS}")
-set(vtkCommonPython_LIB_DEPENDS "${VTK40_vtkCommonPython_LIB_DEPENDS}")
-set(vtkCommonTCL_LIB_DEPENDS "${VTK40_vtkCommonTCL_LIB_DEPENDS}")
-set(vtkCommon_LIB_DEPENDS "${VTK40_vtkCommon_LIB_DEPENDS}")
-set(vtkFilteringJava_LIB_DEPENDS "${VTK40_vtkFilteringJava_LIB_DEPENDS}")
-set(vtkFilteringPython_LIB_DEPENDS "${VTK40_vtkFilteringPython_LIB_DEPENDS}")
-set(vtkFilteringTCL_LIB_DEPENDS "${VTK40_vtkFilteringTCL_LIB_DEPENDS}")
-set(vtkFiltering_LIB_DEPENDS "${VTK40_vtkFiltering_LIB_DEPENDS}")
-set(vtkGraphicsJava_LIB_DEPENDS "${VTK40_vtkGraphicsJava_LIB_DEPENDS}")
-set(vtkGraphicsPython_LIB_DEPENDS "${VTK40_vtkGraphicsPython_LIB_DEPENDS}")
-set(vtkGraphicsTCL_LIB_DEPENDS "${VTK40_vtkGraphicsTCL_LIB_DEPENDS}")
-set(vtkGraphics_LIB_DEPENDS "${VTK40_vtkGraphics_LIB_DEPENDS}")
-set(vtkHybridJava_LIB_DEPENDS "${VTK40_vtkHybridJava_LIB_DEPENDS}")
-set(vtkHybridPython_LIB_DEPENDS "${VTK40_vtkHybridPython_LIB_DEPENDS}")
-set(vtkHybridTCL_LIB_DEPENDS "${VTK40_vtkHybridTCL_LIB_DEPENDS}")
-set(vtkHybrid_LIB_DEPENDS "${VTK40_vtkHybrid_LIB_DEPENDS}")
-set(vtkIOJava_LIB_DEPENDS "${VTK40_vtkIOJava_LIB_DEPENDS}")
-set(vtkIOPython_LIB_DEPENDS "${VTK40_vtkIOPython_LIB_DEPENDS}")
-set(vtkIOTCL_LIB_DEPENDS "${VTK40_vtkIOTCL_LIB_DEPENDS}")
-set(vtkIO_LIB_DEPENDS "${VTK40_vtkIO_LIB_DEPENDS}")
-set(vtkImagingJava_LIB_DEPENDS "${VTK40_vtkImagingJava_LIB_DEPENDS}")
-set(vtkImagingPython_LIB_DEPENDS "${VTK40_vtkImagingPython_LIB_DEPENDS}")
-set(vtkImagingTCL_LIB_DEPENDS "${VTK40_vtkImagingTCL_LIB_DEPENDS}")
-set(vtkImaging_LIB_DEPENDS "${VTK40_vtkImaging_LIB_DEPENDS}")
-set(vtkParallelJava_LIB_DEPENDS "${VTK40_vtkParallelJava_LIB_DEPENDS}")
-set(vtkParallelPython_LIB_DEPENDS "${VTK40_vtkParallelPython_LIB_DEPENDS}")
-set(vtkParallelTCL_LIB_DEPENDS "${VTK40_vtkParallelTCL_LIB_DEPENDS}")
-set(vtkParallel_LIB_DEPENDS "${VTK40_vtkParallel_LIB_DEPENDS}")
-set(vtkPatentedJava_LIB_DEPENDS "${VTK40_vtkPatentedJava_LIB_DEPENDS}")
-set(vtkPatentedPython_LIB_DEPENDS "${VTK40_vtkPatentedPython_LIB_DEPENDS}")
-set(vtkPatentedTCL_LIB_DEPENDS "${VTK40_vtkPatentedTCL_LIB_DEPENDS}")
-set(vtkPatented_LIB_DEPENDS "${VTK40_vtkPatented_LIB_DEPENDS}")
-set(vtkRenderingJava_LIB_DEPENDS "${VTK40_vtkRenderingJava_LIB_DEPENDS}")
-set(vtkRenderingPythonTkWidgets_LIB_DEPENDS "${VTK40_vtkRenderingPythonTkWidgets_LIB_DEPENDS}")
-set(vtkRenderingPython_LIB_DEPENDS "${VTK40_vtkRenderingPython_LIB_DEPENDS}")
-set(vtkRenderingTCL_LIB_DEPENDS "${VTK40_vtkRenderingTCL_LIB_DEPENDS}")
-set(vtkRendering_LIB_DEPENDS "${VTK40_vtkRendering_LIB_DEPENDS}")
-set(vtkjpeg_LIB_DEPENDS "${VTK40_vtkjpeg_LIB_DEPENDS}")
-set(vtkpng_LIB_DEPENDS "${VTK40_vtkpng_LIB_DEPENDS}")
-set(vtkzlib_LIB_DEPENDS "${VTK40_vtkzlib_LIB_DEPENDS}")
-
-# List of VTK configuration variables set above.
-# grep "^[ ]*set(VTK" UseVTKConfig40.cmake |sed 's/[ ]*set(\([^ ]*\) .*/ \1/'
-set(VTK_SETTINGS
- VTK_BUILD_SHARED
- VTK_BUILD_VERSION
- VTK_DEBUG_LEAKS
- VTK_HAVE_VG500
- VTK_HAVE_VP1000
- VTK_INCLUDE_DIRS
- VTK_KITS
- VTK_LANGUAGES
- VTK_LIBRARY_DIRS
- VTK_MAJOR_VERSION
- VTK_MANGLE_MESA
- VTK_MINOR_VERSION
- VTK_MPIRUN_EXE
- VTK_MPI_POSTFLAGS
- VTK_MPI_PREFLAGS
- VTK_OPENGL_HAS_OSMESA
- VTK_PARSE_JAVA_EXE
- VTK_TCL_EXE
- VTK_TCL_HOME
- VTK_USE_64BIT_IDS
- VTK_USE_ANSI_STDLIB
- VTK_USE_HYBRID
- VTK_USE_MATROX_IMAGING
- VTK_USE_MPI
- VTK_USE_PARALLEL
- VTK_USE_PATENTED
- VTK_USE_RENDERING
- VTK_USE_VIDEO_FOR_WINDOWS
- VTK_USE_VOLUMEPRO
- VTK_USE_X
- VTK_WRAP_JAVA
- VTK_WRAP_JAVA_EXE
- VTK_WRAP_PYTHON
- VTK_WRAP_PYTHON_EXE
- VTK_WRAP_TCL
- VTK_WRAP_TCL_EXE
-)
diff --git a/Modules/Use_wxWindows.cmake b/Modules/Use_wxWindows.cmake
index 6c95681e2..d3025ac12 100644
--- a/Modules/Use_wxWindows.cmake
+++ b/Modules/Use_wxWindows.cmake
@@ -1,17 +1,32 @@
+#.rst:
+# Use_wxWindows
+# -------------
+#
+#
+#
+#
+# This convenience include finds if wxWindows is installed and set the
+# appropriate libs, incdirs, flags etc. author Jan Woetzel <jw -at-
+# mip.informatik.uni-kiel.de> (07/2003)
#
-# This convenience include finds if wxWindows is installed
-# and set the appropriate libs, incdirs, flags etc.
-# author Jan Woetzel <jw -at- mip.informatik.uni-kiel.de> (07/2003)
-##
-# -----------------------------------------------------
# USAGE:
-# just include Use_wxWindows.cmake
-# in your projects CMakeLists.txt
+#
+# ::
+#
+# just include Use_wxWindows.cmake
+# in your projects CMakeLists.txt
+#
# include( ${CMAKE_MODULE_PATH}/Use_wxWindows.cmake)
-##
-# if you are sure you need GL then
+#
+# ::
+#
+# if you are sure you need GL then
+#
# set(WXWINDOWS_USE_GL 1)
-# *before* you include this file.
+#
+# ::
+#
+# *before* you include this file.
#=============================================================================
# Copyright 2003-2009 Kitware, Inc.
diff --git a/Modules/UsewxWidgets.cmake b/Modules/UsewxWidgets.cmake
index bb8c29b3e..b3633a6c2 100644
--- a/Modules/UsewxWidgets.cmake
+++ b/Modules/UsewxWidgets.cmake
@@ -1,19 +1,38 @@
-# - Convenience include for using wxWidgets library.
-# Determines if wxWidgets was FOUND and sets the appropriate libs, incdirs,
-# flags, etc. INCLUDE_DIRECTORIES and LINK_DIRECTORIES are called.
+#.rst:
+# UsewxWidgets
+# ------------
+#
+# Convenience include for using wxWidgets library.
+#
+# Determines if wxWidgets was FOUND and sets the appropriate libs,
+# incdirs, flags, etc. INCLUDE_DIRECTORIES and LINK_DIRECTORIES are
+# called.
#
# USAGE
-# # Note that for MinGW users the order of libs is important!
-# find_package(wxWidgets REQUIRED net gl core base)
-# include(${wxWidgets_USE_FILE})
-# # and for each of your dependent executable/library targets:
-# target_link_libraries(<YourTarget> ${wxWidgets_LIBRARIES})
+#
+# ::
+#
+# # Note that for MinGW users the order of libs is important!
+# find_package(wxWidgets REQUIRED net gl core base)
+# include(${wxWidgets_USE_FILE})
+# # and for each of your dependent executable/library targets:
+# target_link_libraries(<YourTarget> ${wxWidgets_LIBRARIES})
+#
+#
#
# DEPRECATED
-# LINK_LIBRARIES is not called in favor of adding dependencies per target.
+#
+# ::
+#
+# LINK_LIBRARIES is not called in favor of adding dependencies per target.
+#
+#
#
# AUTHOR
-# Jan Woetzel <jw -at- mip.informatik.uni-kiel.de>
+#
+# ::
+#
+# Jan Woetzel <jw -at- mip.informatik.uni-kiel.de>
#=============================================================================
# Copyright 2004-2009 Kitware, Inc.
@@ -69,8 +88,11 @@ if (wxWidgets_FOUND)
endif()
if (wxWidgets_CXX_FLAGS)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${wxWidgets_CXX_FLAGS}")
- MSG("wxWidgets_CXX_FLAGS=${wxWidgets_CXX_FLAGS}")
+ # Flags are expected to be a string here, not a list.
+ string(REPLACE ";" " " wxWidgets_CXX_FLAGS_str "${wxWidgets_CXX_FLAGS}")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${wxWidgets_CXX_FLAGS_str}")
+ MSG("wxWidgets_CXX_FLAGS=${wxWidgets_CXX_FLAGS_str}")
+ unset(wxWidgets_CXX_FLAGS_str)
endif()
# DEPRECATED JW
diff --git a/Modules/WIX.template.in b/Modules/WIX.template.in
index 0bc7e10ce..c4fc83afa 100644
--- a/Modules/WIX.template.in
+++ b/Modules/WIX.template.in
@@ -39,6 +39,9 @@
<FeatureRef Id="ProductFeature"/>
- <UIRef Id="WixUI_InstallDir" />
+ <UIRef Id="$(var.CPACK_WIX_UI_REF)" />
+
+ <?include "properties.wxi"?>
+ <?include "product_fragment.wxi"?>
</Product>
</Wix>
diff --git a/Modules/WriteBasicConfigVersionFile.cmake b/Modules/WriteBasicConfigVersionFile.cmake
index 4466cd797..bf55eb964 100644
--- a/Modules/WriteBasicConfigVersionFile.cmake
+++ b/Modules/WriteBasicConfigVersionFile.cmake
@@ -1,4 +1,17 @@
-# WRITE_BASIC_CONFIG_VERSION_FILE( filename VERSION major.minor.patch COMPATIBILITY (AnyNewerVersion|SameMajorVersion) )
+#.rst:
+# WriteBasicConfigVersionFile
+# ---------------------------
+#
+#
+#
+# ::
+#
+# WRITE_BASIC_CONFIG_VERSION_FILE( filename
+# [VERSION major.minor.patch]
+# COMPATIBILITY (AnyNewerVersion|SameMajorVersion)
+# )
+#
+#
#
# Deprecated, see WRITE_BASIC_PACKAGE_VERSION_FILE(), it is identical.
@@ -36,7 +49,11 @@ function(WRITE_BASIC_CONFIG_VERSION_FILE _filename)
endif()
if("${CVF_VERSION}" STREQUAL "")
- message(FATAL_ERROR "No VERSION specified for WRITE_BASIC_CONFIG_VERSION_FILE()")
+ if ("${PROJECT_VERSION}" STREQUAL "")
+ message(FATAL_ERROR "No VERSION specified for WRITE_BASIC_CONFIG_VERSION_FILE()")
+ else()
+ set(CVF_VERSION "${PROJECT_VERSION}")
+ endif()
endif()
configure_file("${versionTemplateFile}" "${_filename}" @ONLY)
diff --git a/Modules/WriteCompilerDetectionHeader.cmake b/Modules/WriteCompilerDetectionHeader.cmake
new file mode 100644
index 000000000..a3b73bb89
--- /dev/null
+++ b/Modules/WriteCompilerDetectionHeader.cmake
@@ -0,0 +1,664 @@
+#.rst:
+# WriteCompilerDetectionHeader
+# ----------------------------
+#
+# This module provides the function write_compiler_detection_header().
+#
+# The ``WRITE_COMPILER_DETECTION_HEADER`` function can be used to generate
+# a file suitable for preprocessor inclusion which contains macros to be
+# used in source code::
+#
+# write_compiler_detection_header(
+# FILE <file>
+# PREFIX <prefix>
+# [OUTPUT_FILES_VAR <output_files_var> OUTPUT_DIR <output_dir>]
+# COMPILERS <compiler> [...]
+# FEATURES <feature> [...]
+# [VERSION <version>]
+# [PROLOG <prolog>]
+# [EPILOG <epilog>]
+# )
+#
+# The ``write_compiler_detection_header`` function generates the
+# file ``<file>`` with macros which all have the prefix ``<prefix>``.
+#
+# By default, all content is written directly to the ``<file>``. The
+# ``OUTPUT_FILES_VAR`` may be specified to cause the compiler-specific
+# content to be written to separate files. The separate files are then
+# available in the ``<output_files_var>`` and may be consumed by the caller
+# for installation for example. The ``OUTPUT_DIR`` specifies a relative
+# path from the main ``<file>`` to the compiler-specific files. For example:
+#
+# .. code-block:: cmake
+#
+# write_compiler_detection_header(
+# FILE climbingstats_compiler_detection.h
+# PREFIX ClimbingStats
+# OUTPUT_FILES_VAR support_files
+# OUTPUT_DIR compilers
+# COMPILERS GNU Clang MSVC
+# FEATURES cxx_variadic_templates
+# )
+# install(FILES
+# ${CMAKE_CURRENT_BINARY_DIR}/climbingstats_compiler_detection.h
+# DESTINATION include
+# )
+# install(FILES
+# ${support_files}
+# DESTINATION include/compilers
+# )
+#
+#
+# ``VERSION`` may be used to specify the API version to be generated.
+# Future versions of CMake may introduce alternative APIs. A given
+# API is selected by any ``<version>`` value greater than or equal
+# to the version of CMake that introduced the given API and less
+# than the version of CMake that introduced its succeeding API.
+# The value of the :variable:`CMAKE_MINIMUM_REQUIRED_VERSION`
+# variable is used if no explicit version is specified.
+# (As of CMake version |release| there is only one API version.)
+#
+# ``PROLOG`` may be specified as text content to write at the start of the
+# header. ``EPILOG`` may be specified as text content to write at the end
+# of the header
+#
+# At least one ``<compiler>`` and one ``<feature>`` must be listed. Compilers
+# which are known to CMake, but not specified are detected and a preprocessor
+# ``#error`` is generated for them. A preprocessor macro matching
+# ``<PREFIX>_COMPILER_IS_<compiler>`` is generated for each compiler
+# known to CMake to contain the value ``0`` or ``1``.
+#
+# Possible compiler identifiers are documented with the
+# :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
+# Available features in this version of CMake are listed in the
+# :prop_gbl:`CMAKE_C_KNOWN_FEATURES` and
+# :prop_gbl:`CMAKE_CXX_KNOWN_FEATURES` global properties.
+#
+# See the :manual:`cmake-compile-features(7)` manual for information on
+# compile features.
+#
+# Feature Test Macros
+# ===================
+#
+# For each compiler, a preprocessor macro is generated matching
+# ``<PREFIX>_COMPILER_IS_<compiler>`` which has the content either ``0``
+# or ``1``, depending on the compiler in use. Preprocessor macros for
+# compiler version components are generated matching
+# ``<PREFIX>_COMPILER_VERSION_MAJOR`` ``<PREFIX>_COMPILER_VERSION_MINOR``
+# and ``<PREFIX>_COMPILER_VERSION_PATCH`` containing decimal values
+# for the corresponding compiler version components, if defined.
+#
+# A preprocessor test is generated based on the compiler version
+# denoting whether each feature is enabled. A preprocessor macro
+# matching ``<PREFIX>_COMPILER_<FEATURE>``, where ``<FEATURE>`` is the
+# upper-case ``<feature>`` name, is generated to contain the value
+# ``0`` or ``1`` depending on whether the compiler in use supports the
+# feature:
+#
+# .. code-block:: cmake
+#
+# write_compiler_detection_header(
+# FILE climbingstats_compiler_detection.h
+# PREFIX ClimbingStats
+# COMPILERS GNU Clang AppleClang MSVC
+# FEATURES cxx_variadic_templates
+# )
+#
+# .. code-block:: c++
+#
+# #if ClimbingStats_COMPILER_CXX_VARIADIC_TEMPLATES
+# template<typename... T>
+# void someInterface(T t...) { /* ... */ }
+# #else
+# // Compatibility versions
+# template<typename T1>
+# void someInterface(T1 t1) { /* ... */ }
+# template<typename T1, typename T2>
+# void someInterface(T1 t1, T2 t2) { /* ... */ }
+# template<typename T1, typename T2, typename T3>
+# void someInterface(T1 t1, T2 t2, T3 t3) { /* ... */ }
+# #endif
+#
+# Symbol Macros
+# =============
+#
+# Some additional symbol-defines are created for particular features for
+# use as symbols which may be conditionally defined empty:
+#
+# .. code-block:: c++
+#
+# class MyClass ClimbingStats_FINAL
+# {
+# ClimbingStats_CONSTEXPR int someInterface() { return 42; }
+# };
+#
+# The ``ClimbingStats_FINAL`` macro will expand to ``final`` if the
+# compiler (and its flags) support the ``cxx_final`` feature, and the
+# ``ClimbingStats_CONSTEXPR`` macro will expand to ``constexpr``
+# if ``cxx_constexpr`` is supported.
+#
+# The following features generate corresponding symbol defines:
+#
+# ========================== =================================== =================
+# Feature Define Symbol
+# ========================== =================================== =================
+# ``c_restrict`` ``<PREFIX>_RESTRICT`` ``restrict``
+# ``cxx_constexpr`` ``<PREFIX>_CONSTEXPR`` ``constexpr``
+# ``cxx_deleted_functions`` ``<PREFIX>_DELETED_FUNCTION`` ``= delete``
+# ``cxx_extern_templates`` ``<PREFIX>_EXTERN_TEMPLATE`` ``extern``
+# ``cxx_final`` ``<PREFIX>_FINAL`` ``final``
+# ``cxx_noexcept`` ``<PREFIX>_NOEXCEPT`` ``noexcept``
+# ``cxx_noexcept`` ``<PREFIX>_NOEXCEPT_EXPR(X)`` ``noexcept(X)``
+# ``cxx_override`` ``<PREFIX>_OVERRIDE`` ``override``
+# ========================== =================================== =================
+#
+# Compatibility Implementation Macros
+# ===================================
+#
+# Some features are suitable for wrapping in a macro with a backward
+# compatibility implementation if the compiler does not support the feature.
+#
+# When the ``cxx_static_assert`` feature is not provided by the compiler,
+# a compatibility implementation is available via the
+# ``<PREFIX>_STATIC_ASSERT(COND)`` and
+# ``<PREFIX>_STATIC_ASSERT_MSG(COND, MSG)`` function-like macros. The macros
+# expand to ``static_assert`` where that compiler feature is available, and
+# to a compatibility implementation otherwise. In the first form, the
+# condition is stringified in the message field of ``static_assert``. In
+# the second form, the message ``MSG`` is passed to the message field of
+# ``static_assert``, or ignored if using the backward compatibility
+# implementation.
+#
+# The ``cxx_attribute_deprecated`` feature provides a macro definition
+# ``<PREFIX>_DEPRECATED``, which expands to either the standard
+# ``[[deprecated]]`` attribute or a compiler-specific decorator such
+# as ``__attribute__((__deprecated__))`` used by GNU compilers.
+#
+# The ``cxx_alignas`` feature provides a macro definition
+# ``<PREFIX>_ALIGNAS`` which expands to either the standard ``alignas``
+# decorator or a compiler-specific decorator such as
+# ``__attribute__ ((__aligned__))`` used by GNU compilers.
+#
+# The ``cxx_alignof`` feature provides a macro definition
+# ``<PREFIX>_ALIGNOF`` which expands to either the standard ``alignof``
+# decorator or a compiler-specific decorator such as ``__alignof__``
+# used by GNU compilers.
+#
+# ============================= ================================ =====================
+# Feature Define Symbol
+# ============================= ================================ =====================
+# ``cxx_alignas`` ``<PREFIX>_ALIGNAS`` ``alignas``
+# ``cxx_alignof`` ``<PREFIX>_ALIGNOF`` ``alignof``
+# ``cxx_nullptr`` ``<PREFIX>_NULLPTR`` ``nullptr``
+# ``cxx_static_assert`` ``<PREFIX>_STATIC_ASSERT`` ``static_assert``
+# ``cxx_static_assert`` ``<PREFIX>_STATIC_ASSERT_MSG`` ``static_assert``
+# ``cxx_attribute_deprecated`` ``<PREFIX>_DEPRECATED`` ``[[deprecated]]``
+# ``cxx_attribute_deprecated`` ``<PREFIX>_DEPRECATED_MSG`` ``[[deprecated]]``
+# ``cxx_thread_local`` ``<PREFIX>_THREAD_LOCAL`` ``thread_local``
+# ============================= ================================ =====================
+#
+# A use-case which arises with such deprecation macros is the deprecation
+# of an entire library. In that case, all public API in the library may
+# be decorated with the ``<PREFIX>_DEPRECATED`` macro. This results in
+# very noisy build output when building the library itself, so the macro
+# may be may be defined to empty in that case when building the deprecated
+# library:
+#
+# .. code-block:: cmake
+#
+# add_library(compat_support ${srcs})
+# target_compile_definitions(compat_support
+# PRIVATE
+# CompatSupport_DEPRECATED=
+# )
+
+#=============================================================================
+# Copyright 2014 Stephen Kelly <steveire@gmail.com>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/CMakeCompilerIdDetection.cmake)
+
+function(_load_compiler_variables CompilerId lang)
+ include("${CMAKE_ROOT}/Modules/Compiler/${CompilerId}-${lang}-FeatureTests.cmake" OPTIONAL)
+ set(_cmake_oldestSupported_${CompilerId} ${_cmake_oldestSupported} PARENT_SCOPE)
+ foreach(feature ${ARGN})
+ set(_cmake_feature_test_${CompilerId}_${feature} ${_cmake_feature_test_${feature}} PARENT_SCOPE)
+ endforeach()
+ include("${CMAKE_ROOT}/Modules/Compiler/${CompilerId}-${lang}-DetermineCompiler.cmake" OPTIONAL
+ RESULT_VARIABLE determinedCompiler)
+ if (NOT determinedCompiler)
+ include("${CMAKE_ROOT}/Modules/Compiler/${CompilerId}-DetermineCompiler.cmake" OPTIONAL)
+ endif()
+ set(_compiler_id_version_compute_${CompilerId} ${_compiler_id_version_compute} PARENT_SCOPE)
+endfunction()
+
+function(write_compiler_detection_header
+ file_keyword file_arg
+ prefix_keyword prefix_arg
+ )
+ if (NOT "x${file_keyword}" STREQUAL "xFILE")
+ message(FATAL_ERROR "write_compiler_detection_header: FILE parameter missing.")
+ endif()
+ if (NOT "x${prefix_keyword}" STREQUAL "xPREFIX")
+ message(FATAL_ERROR "write_compiler_detection_header: PREFIX parameter missing.")
+ endif()
+ set(options)
+ set(oneValueArgs VERSION EPILOG PROLOG OUTPUT_FILES_VAR OUTPUT_DIR)
+ set(multiValueArgs COMPILERS FEATURES)
+ cmake_parse_arguments(_WCD "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+ if (NOT _WCD_COMPILERS)
+ message(FATAL_ERROR "Invalid arguments. write_compiler_detection_header requires at least one compiler.")
+ endif()
+ if (NOT _WCD_FEATURES)
+ message(FATAL_ERROR "Invalid arguments. write_compiler_detection_header requires at least one feature.")
+ endif()
+
+ if(_WCD_UNPARSED_ARGUMENTS)
+ message(FATAL_ERROR "Unparsed arguments: ${_WCD_UNPARSED_ARGUMENTS}")
+ endif()
+
+ if (prefix_arg STREQUAL "")
+ message(FATAL_ERROR "A prefix must be specified")
+ endif()
+ string(MAKE_C_IDENTIFIER ${prefix_arg} cleaned_prefix)
+ if (NOT prefix_arg STREQUAL cleaned_prefix)
+ message(FATAL_ERROR "The prefix must be a valid C identifier.")
+ endif()
+
+ if(NOT _WCD_VERSION)
+ set(_WCD_VERSION ${CMAKE_MINIMUM_REQUIRED_VERSION})
+ endif()
+ set(_min_version 3.1.0) # Version which introduced this function
+ if (_WCD_VERSION VERSION_LESS _min_version)
+ set(err "VERSION compatibility for write_compiler_detection_header is set to ${_WCD_VERSION}, which is too low.")
+ set(err "${err} It must be set to at least ${_min_version}. ")
+ set(err "${err} Either set the VERSION parameter to the write_compiler_detection_header function, or update")
+ set(err "${err} your minimum required CMake version with the cmake_minimum_required command.")
+ message(FATAL_ERROR "${err}")
+ endif()
+
+ if(_WCD_OUTPUT_FILES_VAR)
+ if(NOT _WCD_OUTPUT_DIR)
+ message(FATAL_ERROR "If OUTPUT_FILES_VAR is specified, then OUTPUT_DIR must also be specified.")
+ endif()
+ endif()
+ if(_WCD_OUTPUT_DIR)
+ if(NOT _WCD_OUTPUT_FILES_VAR)
+ message(FATAL_ERROR "If OUTPUT_DIR is specified, then OUTPUT_FILES_VAR must also be specified.")
+ endif()
+ get_filename_component(main_file_dir ${file_arg} DIRECTORY)
+ if (NOT IS_ABSOLUTE ${main_file_dir})
+ set(main_file_dir "${CMAKE_CURRENT_BINARY_DIR}/${main_file_dir}")
+ endif()
+ if (NOT IS_ABSOLUTE ${_WCD_OUTPUT_DIR})
+ set(_WCD_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/${_WCD_OUTPUT_DIR}")
+ endif()
+ get_filename_component(out_file_dir ${_WCD_OUTPUT_DIR} ABSOLUTE)
+ string(FIND ${out_file_dir} ${main_file_dir} idx)
+ if (NOT idx EQUAL 0)
+ message(FATAL_ERROR "The compiler-specific output directory must be within the same directory as the main file.")
+ endif()
+
+ if (main_file_dir STREQUAL out_file_dir)
+ unset(_WCD_OUTPUT_DIR)
+ else()
+ string(REPLACE "${main_file_dir}/" "" _WCD_OUTPUT_DIR "${out_file_dir}/")
+ endif()
+ endif()
+
+ set(compilers
+ GNU
+ Clang
+ AppleClang
+ MSVC
+ SunPro
+ )
+
+ set(_hex_compilers ADSP Borland Embarcadero SunPro)
+
+ foreach(_comp ${_WCD_COMPILERS})
+ list(FIND compilers ${_comp} idx)
+ if (idx EQUAL -1)
+ message(FATAL_ERROR "Unsupported compiler ${_comp}.")
+ endif()
+ if (NOT _need_hex_conversion)
+ list(FIND _hex_compilers ${_comp} idx)
+ if (NOT idx EQUAL -1)
+ set(_need_hex_conversion TRUE)
+ endif()
+ endif()
+ endforeach()
+
+ set(file_content "
+// This is a generated file. Do not edit!
+
+#ifndef ${prefix_arg}_COMPILER_DETECTION_H
+#define ${prefix_arg}_COMPILER_DETECTION_H
+")
+
+ if (_WCD_PROLOG)
+ set(file_content "${file_content}\n${_WCD_PROLOG}\n")
+ endif()
+
+ if (_need_hex_conversion)
+ set(file_content "${file_content}
+#define ${prefix_arg}_DEC(X) (X)
+#define ${prefix_arg}_HEX(X) ( \\
+ ((X)>>28 & 0xF) * 10000000 + \\
+ ((X)>>24 & 0xF) * 1000000 + \\
+ ((X)>>20 & 0xF) * 100000 + \\
+ ((X)>>16 & 0xF) * 10000 + \\
+ ((X)>>12 & 0xF) * 1000 + \\
+ ((X)>>8 & 0xF) * 100 + \\
+ ((X)>>4 & 0xF) * 10 + \\
+ ((X) & 0xF) \\
+ )\n")
+ endif()
+
+ foreach(feature ${_WCD_FEATURES})
+ if (feature MATCHES "^cxx_")
+ list(APPEND _langs CXX)
+ list(APPEND CXX_features ${feature})
+ elseif (feature MATCHES "^c_")
+ list(APPEND _langs C)
+ list(APPEND C_features ${feature})
+ else()
+ message(FATAL_ERROR "Unsupported feature ${feature}.")
+ endif()
+ endforeach()
+ list(REMOVE_DUPLICATES _langs)
+
+ if(_WCD_OUTPUT_FILES_VAR)
+ get_filename_component(main_file_name ${file_arg} NAME)
+ set(compiler_file_content_
+"#ifndef ${prefix_arg}_COMPILER_DETECTION_H
+# error This file may only be included from ${main_file_name}
+#endif\n")
+ endif()
+
+ foreach(_lang ${_langs})
+ set(target_compilers)
+ foreach(compiler ${_WCD_COMPILERS})
+ _load_compiler_variables(${compiler} ${_lang} ${${_lang}_features})
+ if(_cmake_oldestSupported_${compiler})
+ list(APPEND target_compilers ${compiler})
+ endif()
+ endforeach()
+
+ get_property(known_features GLOBAL PROPERTY CMAKE_${_lang}_KNOWN_FEATURES)
+ foreach(feature ${${_lang}_features})
+ list(FIND known_features ${feature} idx)
+ if (idx EQUAL -1)
+ message(FATAL_ERROR "Unsupported feature ${feature}.")
+ endif()
+ endforeach()
+
+ if(_lang STREQUAL CXX)
+ set(file_content "${file_content}\n#ifdef __cplusplus\n")
+ else()
+ set(file_content "${file_content}\n#ifndef __cplusplus\n")
+ endif()
+
+ compiler_id_detection(ID_CONTENT ${_lang} PREFIX ${prefix_arg}_
+ ID_DEFINE
+ )
+
+ set(file_content "${file_content}${ID_CONTENT}\n")
+
+ set(pp_if "if")
+ foreach(compiler ${target_compilers})
+ set(file_content "${file_content}\n# ${pp_if} ${prefix_arg}_COMPILER_IS_${compiler}\n")
+
+ if(_WCD_OUTPUT_FILES_VAR)
+ set(compile_file_name "${_WCD_OUTPUT_DIR}${prefix_arg}_COMPILER_INFO_${compiler}_${_lang}.h")
+ set(file_content "${file_content}\n# include \"${compile_file_name}\"\n")
+ endif()
+
+ if(_WCD_OUTPUT_FILES_VAR)
+ set(compiler_file_content compiler_file_content_${compiler}_${_lang})
+ else()
+ set(compiler_file_content file_content)
+ endif()
+
+ set(${compiler_file_content} "${${compiler_file_content}}
+# if !(${_cmake_oldestSupported_${compiler}})
+# error Unsupported compiler version
+# endif\n")
+
+ set(PREFIX ${prefix_arg}_)
+ if (_need_hex_conversion)
+ set(MACRO_DEC ${prefix_arg}_DEC)
+ set(MACRO_HEX ${prefix_arg}_HEX)
+ else()
+ set(MACRO_DEC)
+ set(MACRO_HEX)
+ endif()
+ string(CONFIGURE "${_compiler_id_version_compute_${compiler}}" VERSION_BLOCK @ONLY)
+ set(${compiler_file_content} "${${compiler_file_content}}${VERSION_BLOCK}\n")
+ set(PREFIX)
+ set(MACRO_DEC)
+ set(MACRO_HEX)
+
+ set(pp_if "elif")
+ foreach(feature ${${_lang}_features})
+ string(TOUPPER ${feature} feature_upper)
+ set(feature_PP "COMPILER_${feature_upper}")
+ set(_define_item "\n# define ${prefix_arg}_${feature_PP} 0\n")
+ if (_cmake_feature_test_${compiler}_${feature} STREQUAL "1")
+ set(_define_item "\n# define ${prefix_arg}_${feature_PP} 1\n")
+ elseif (_cmake_feature_test_${compiler}_${feature})
+ set(_define_item "\n# define ${prefix_arg}_${feature_PP} 0\n")
+ set(_define_item "\n# if ${_cmake_feature_test_${compiler}_${feature}}\n# define ${prefix_arg}_${feature_PP} 1\n# else${_define_item}# endif\n")
+ endif()
+ set(${compiler_file_content} "${${compiler_file_content}}${_define_item}")
+ endforeach()
+ endforeach()
+ if(pp_if STREQUAL "elif")
+ set(file_content "${file_content}
+# else
+# error Unsupported compiler
+# endif\n")
+ endif()
+ foreach(feature ${${_lang}_features})
+ string(TOUPPER ${feature} feature_upper)
+ set(feature_PP "COMPILER_${feature_upper}")
+ set(def_name ${prefix_arg}_${feature_PP})
+ if (feature STREQUAL c_restrict)
+ set(def_value "${prefix_arg}_RESTRICT")
+ set(file_content "${file_content}
+# if ${def_name}
+# define ${def_value} restrict
+# else
+# define ${def_value}
+# endif
+\n")
+ endif()
+ if (feature STREQUAL cxx_constexpr)
+ set(def_value "${prefix_arg}_CONSTEXPR")
+ set(file_content "${file_content}
+# if ${def_name}
+# define ${def_value} constexpr
+# else
+# define ${def_value}
+# endif
+\n")
+ endif()
+ if (feature STREQUAL cxx_final)
+ set(def_value "${prefix_arg}_FINAL")
+ set(file_content "${file_content}
+# if ${def_name}
+# define ${def_value} final
+# else
+# define ${def_value}
+# endif
+\n")
+ endif()
+ if (feature STREQUAL cxx_override)
+ set(def_value "${prefix_arg}_OVERRIDE")
+ set(file_content "${file_content}
+# if ${def_name}
+# define ${def_value} override
+# else
+# define ${def_value}
+# endif
+\n")
+ endif()
+ if (feature STREQUAL cxx_static_assert)
+ set(def_value "${prefix_arg}_STATIC_ASSERT(X)")
+ set(def_value_msg "${prefix_arg}_STATIC_ASSERT_MSG(X, MSG)")
+ set(static_assert_struct "template<bool> struct ${prefix_arg}StaticAssert;\ntemplate<> struct ${prefix_arg}StaticAssert<true>{};\n")
+ set(def_standard "# define ${def_value} static_assert(X, #X)\n# define ${def_value_msg} static_assert(X, MSG)")
+ set(def_alternative "${static_assert_struct}# define ${def_value} sizeof(${prefix_arg}StaticAssert<X>)\n# define ${def_value_msg} sizeof(${prefix_arg}StaticAssert<X>)")
+ set(file_content "${file_content}# if ${def_name}\n${def_standard}\n# else\n${def_alternative}\n# endif\n\n")
+ endif()
+ if (feature STREQUAL cxx_alignas)
+ set(def_value "${prefix_arg}_ALIGNAS(X)")
+ set(file_content "${file_content}
+# if ${def_name}
+# define ${def_value} alignas(X)
+# elif ${prefix_arg}_COMPILER_IS_GNU || ${prefix_arg}_COMPILER_IS_Clang || ${prefix_arg}_COMPILER_IS_AppleClang
+# define ${def_value} __attribute__ ((__aligned__(X)))
+# elif ${prefix_arg}_COMPILER_IS_MSVC
+# define ${def_value} __declspec(align(X))
+# else
+# define ${def_value}
+# endif
+\n")
+ endif()
+ if (feature STREQUAL cxx_alignof)
+ set(def_value "${prefix_arg}_ALIGNOF(X)")
+ set(file_content "${file_content}
+# if ${def_name}
+# define ${def_value} alignof(X)
+# elif ${prefix_arg}_COMPILER_IS_GNU || ${prefix_arg}_COMPILER_IS_Clang || ${prefix_arg}_COMPILER_IS_AppleClang
+# define ${def_value} __alignof__(X)
+# elif ${prefix_arg}_COMPILER_IS_MSVC
+# define ${def_value} __alignof(X)
+# endif
+\n")
+ endif()
+ if (feature STREQUAL cxx_deleted_functions)
+ set(def_value "${prefix_arg}_DELETED_FUNCTION")
+ set(file_content "${file_content}
+# if ${def_name}
+# define ${def_value} = delete
+# else
+# define ${def_value}
+# endif
+\n")
+ endif()
+ if (feature STREQUAL cxx_extern_templates)
+ set(def_value "${prefix_arg}_EXTERN_TEMPLATE")
+ set(file_content "${file_content}
+# if ${def_name}
+# define ${def_value} extern
+# else
+# define ${def_value}
+# endif
+\n")
+ endif()
+ if (feature STREQUAL cxx_noexcept)
+ set(def_value "${prefix_arg}_NOEXCEPT")
+ set(file_content "${file_content}
+# if ${def_name}
+# define ${def_value} noexcept
+# define ${def_value}_EXPR(X) noexcept(X)
+# else
+# define ${def_value}
+# define ${def_value}_EXPR(X)
+# endif
+\n")
+ endif()
+ if (feature STREQUAL cxx_nullptr)
+ set(def_value "${prefix_arg}_NULLPTR")
+ set(file_content "${file_content}
+# if ${def_name}
+# define ${def_value} nullptr
+# else
+# define ${def_value} 0
+# endif
+\n")
+ endif()
+ if (feature STREQUAL cxx_thread_local)
+ set(def_value "${prefix_arg}_THREAD_LOCAL")
+ set(file_content "${file_content}
+# if ${def_name}
+# define ${def_value} thread_local
+# elif ${prefix_arg}_COMPILER_IS_GNU || ${prefix_arg}_COMPILER_IS_Clang || ${prefix_arg}_COMPILER_IS_AppleClang
+# define ${def_value} __thread
+# elif ${prefix_arg}_COMPILER_IS_MSVC
+# define ${def_value} __declspec(thread)
+# else
+// ${def_value} not defined for this configuration.
+# endif
+\n")
+ endif()
+ if (feature STREQUAL cxx_attribute_deprecated)
+ set(def_name ${prefix_arg}_${feature_PP})
+ set(def_value "${prefix_arg}_DEPRECATED")
+ set(file_content "${file_content}
+# ifndef ${def_value}
+# if ${def_name}
+# define ${def_value} [[deprecated]]
+# define ${def_value}_MSG(MSG) [[deprecated(MSG)]]
+# elif ${prefix_arg}_COMPILER_IS_GNU || ${prefix_arg}_COMPILER_IS_Clang
+# define ${def_value} __attribute__((__deprecated__))
+# define ${def_value}_MSG(MSG) __attribute__((__deprecated__(MSG)))
+# elif ${prefix_arg}_COMPILER_IS_MSVC
+# define ${def_value} __declspec(deprecated)
+# define ${def_value}_MSG(MSG) __declspec(deprecated(MSG))
+# else
+# define ${def_value}
+# define ${def_value}_MSG(MSG)
+# endif
+# endif
+\n")
+ endif()
+ endforeach()
+
+ set(file_content "${file_content}#endif\n")
+
+ endforeach()
+
+ if(_WCD_OUTPUT_FILES_VAR)
+ foreach(compiler ${_WCD_COMPILERS})
+ foreach(_lang ${_langs})
+ if(compiler_file_content_${compiler}_${_lang})
+ set(CMAKE_CONFIGURABLE_FILE_CONTENT "${compiler_file_content_}")
+ set(CMAKE_CONFIGURABLE_FILE_CONTENT "${CMAKE_CONFIGURABLE_FILE_CONTENT}${compiler_file_content_${compiler}_${_lang}}")
+
+ set(compile_file_name "${_WCD_OUTPUT_DIR}${prefix_arg}_COMPILER_INFO_${compiler}_${_lang}.h")
+ set(full_path "${main_file_dir}/${compile_file_name}")
+ list(APPEND ${_WCD_OUTPUT_FILES_VAR} ${full_path})
+ configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in"
+ "${full_path}"
+ @ONLY
+ )
+ endif()
+ endforeach()
+ endforeach()
+ set(${_WCD_OUTPUT_FILES_VAR} ${${_WCD_OUTPUT_FILES_VAR}} PARENT_SCOPE)
+ endif()
+
+ if (_WCD_EPILOG)
+ set(file_content "${file_content}\n${_WCD_EPILOG}\n")
+ endif()
+ set(file_content "${file_content}\n#endif")
+
+ set(CMAKE_CONFIGURABLE_FILE_CONTENT ${file_content})
+ configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in"
+ "${file_arg}"
+ @ONLY
+ )
+endfunction()
diff --git a/Modules/exportheader.cmake.in b/Modules/exportheader.cmake.in
index 80a879d7e..118de16d6 100644
--- a/Modules/exportheader.cmake.in
+++ b/Modules/exportheader.cmake.in
@@ -23,8 +23,14 @@
#ifndef @DEPRECATED_MACRO_NAME@
# define @DEPRECATED_MACRO_NAME@ @DEFINE_DEPRECATED@
-# define @DEPRECATED_MACRO_NAME@_EXPORT @EXPORT_MACRO_NAME@ @DEFINE_DEPRECATED@
-# define @DEPRECATED_MACRO_NAME@_NO_EXPORT @NO_EXPORT_MACRO_NAME@ @DEFINE_DEPRECATED@
+#endif
+
+#ifndef @DEPRECATED_MACRO_NAME@_EXPORT
+# define @DEPRECATED_MACRO_NAME@_EXPORT @EXPORT_MACRO_NAME@ @DEPRECATED_MACRO_NAME@
+#endif
+
+#ifndef @DEPRECATED_MACRO_NAME@_NO_EXPORT
+# define @DEPRECATED_MACRO_NAME@_NO_EXPORT @NO_EXPORT_MACRO_NAME@ @DEPRECATED_MACRO_NAME@
#endif
#cmakedefine01 DEFINE_NO_DEPRECATED
diff --git a/Modules/readme.txt b/Modules/readme.txt
index 2f119947e..1e0c13b6a 100644
--- a/Modules/readme.txt
+++ b/Modules/readme.txt
@@ -1,172 +1,4 @@
-For more information about how to contribute modules to CMake, see this page:
-http://www.itk.org/Wiki/CMake:Module_Maintainers
-
-Note to authors of FindXxx.cmake files
-
-We would like all FindXxx.cmake files to produce consistent variable names.
-
-Please use the following consistent variable names for general use.
-
-Xxx_INCLUDE_DIRS The final set of include directories listed in one variable for use by client code.
- This should not be a cache entry.
-Xxx_LIBRARIES The libraries to link against to use Xxx. These should include full paths.
- This should not be a cache entry.
-Xxx_DEFINITIONS Definitions to use when compiling code that uses Xxx. This really shouldn't include options such
- as (-DHAS_JPEG)that a client source-code file uses to decide whether to #include <jpeg.h>
-Xxx_EXECUTABLE Where to find the Xxx tool.
-Xxx_Yyy_EXECUTABLE Where to find the Yyy tool that comes with Xxx.
-Xxx_LIBRARY_DIRS Optionally, the final set of library directories listed in one variable for use by client code.
- This should not be a cache entry.
-Xxx_ROOT_DIR Where to find the base directory of Xxx.
-Xxx_VERSION_Yy Expect Version Yy if true. Make sure at most one of these is ever true.
-Xxx_WRAP_Yy If False, do not try to use the relevant CMake wrapping command.
-Xxx_Yy_FOUND If False, optional Yy part of Xxx sytem is not available.
-Xxx_FOUND Set to false, or undefined, if we haven't found, or don't want to use Xxx.
-Xxx_NOT_FOUND_MESSAGE Should be set by config-files in the case that it has set Xxx_FOUND to FALSE.
- The contained message will be printed by the find_package() command and by
- find_package_handle_standard_args() to inform the user about the problem.
-Xxx_RUNTIME_LIBRARY_DIRS Optionally, the runtime library search path for use when running an executable linked to
- shared libraries.
- The list should be used by user code to create the PATH on windows or LD_LIBRARY_PATH on unix.
- This should not be a cache entry.
-Xxx_VERSION_STRING A human-readable string containing the version of the package found, if any.
-Xxx_VERSION_MAJOR The major version of the package found, if any.
-Xxx_VERSION_MINOR The minor version of the package found, if any.
-Xxx_VERSION_PATCH The patch version of the package found, if any.
-
-You do not have to provide all of the above variables. You should provide Xxx_FOUND under most circumstances.
-If Xxx is a library, then Xxx_LIBRARIES, should also be defined, and Xxx_INCLUDE_DIRS should usually be
-defined (I guess libm.a might be an exception)
-
-The following names should not usually be used in CMakeLists.txt files, but they may be usefully modified in
-users' CMake Caches to control stuff.
-
-Xxx_LIBRARY Name of Xxx Library. A User may set this and Xxx_INCLUDE_DIR to ignore to force non-use of Xxx.
-Xxx_Yy_LIBRARY Name of Yy library that is part of the Xxx system. It may or may not be required to use Xxx.
-Xxx_INCLUDE_DIR Where to find xxx.h, etc. (Xxx_INCLUDE_PATH was considered bad because a path includes an
- actual filename.)
-Xxx_Yy_INCLUDE_DIR Where to find xxx_yy.h, etc.
-
-For tidiness's sake, try to keep as many options as possible out of the cache, leaving at least one option which can be
-used to disable use of the module, or locate a not-found library (e.g. Xxx_ROOT_DIR).
-For the same reason, mark most cache options as advanced.
-
-If you need other commands to do special things then it should still begin with Xxx_. This gives a sort of namespace
-effect and keeps things tidy for the user. You should put comments describing all the exported settings, plus
-descriptions of any the users can use to control stuff.
-
-You really should also provide backwards compatibility any old settings that were actually in use.
-Make sure you comment them as deprecated, so that no-one starts using them.
-
-To correctly document a module, create a comment block at the top with # comments.
-There are three types of comments that can be in the block:
-
-1. The brief description of the module, this is done by:
-# - a small description
-
-2. A paragraph of text. This is done with all text that has a single
-space between the # and the text. To create a new paragraph, just
-put a # with no text on the line.
-
-3. A verbatim line. This is done with two spaces between the # and the text.
-
-For example:
+See the "Find Modules" section of the cmake-developer(7) manual page.
-# - This is a cool module
-# This module does really cool stuff.
-# It can do even more than you think.
-#
-# It even needs to paragraphs to tell you about it.
-# And it defines the following variables:
-# VAR_COOL - this is great isn't it?
-# VAR_REALLY_COOL - cool right?
-#
-
-Test the documentation formatting by running "cmake --help-module FindXxx".
-Edit the comments until the output of this command looks satisfactory.
-
-To have a .cmake file in this directory NOT show up in the
-modules documentation, you should start the file with a blank
-line.
-
-After the documentation, leave a *BLANK* line, and then add a
-copyright and licence notice block like this one:
-
-#=============================================================================
-# Copyright 2009-2011 Your Name
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-# (To distribute this file outside of CMake, substitute the full
-# License text for the above reference.)
-
-The layout of the notice block is strictly enforced by the ModuleNotices test.
-Only the year range and name may be changed freely.
-
-A FindXxx.cmake module will typically be loaded by the command
-
- FIND_PACKAGE(Xxx [major[.minor[.patch[.tweak]]]] [EXACT]
- [QUIET] [[REQUIRED|COMPONENTS] [components...]])
-
-If any version numbers are given to the command it will set the
-following variables before loading the module:
-
- Xxx_FIND_VERSION = full requested version string
- Xxx_FIND_VERSION_MAJOR = major version if requested, else 0
- Xxx_FIND_VERSION_MINOR = minor version if requested, else 0
- Xxx_FIND_VERSION_PATCH = patch version if requested, else 0
- Xxx_FIND_VERSION_TWEAK = tweak version if requested, else 0
- Xxx_FIND_VERSION_COUNT = number of version components, 0 to 4
- Xxx_FIND_VERSION_EXACT = true if EXACT option was given
-
-If the find module supports versioning it should locate a version of
-the package that is compatible with the version requested. If a
-compatible version of the package cannot be found the module should
-not report success. The version of the package found should be stored
-in "Xxx_VERSION..." version variables documented by the module.
-
-If the QUIET option is given to the command it will set the variable
-Xxx_FIND_QUIETLY to true before loading the FindXxx.cmake module. If
-this variable is set the module should not complain about not being
-able to find the package. If the
-REQUIRED option is given to the command it will set the variable
-Xxx_FIND_REQUIRED to true before loading the FindXxx.cmake module. If
-this variable is set the module should issue a FATAL_ERROR if the
-package cannot be found.
-If neither the QUIET nor REQUIRED options are given then the
-FindXxx.cmake module should look for the package and complain without
-error if the module is not found.
-
-FIND_PACKAGE() will set the variable CMAKE_FIND_PACKAGE_NAME to
-contain the actual name of the package.
-
-A package can provide sub-components.
-Those components can be listed after the COMPONENTS (or REQUIRED)
-or OPTIONAL_COMPONENTS keywords. The set of all listed components will be
-specified in a Xxx_FIND_COMPONENTS variable.
-For each package-specific component, say Yyy, a variable Xxx_FIND_REQUIRED_Yyy
-will be set to true if it listed after COMPONENTS and it will be set to false
-if it was listed after OPTIONAL_COMPONENTS.
-Using those variables a FindXxx.cmake module and also a XxxConfig.cmake package
-configuration file can determine whether and which components have been requested,
-and whether they were requested as required or as optional.
-For each of the requested components a Xxx_Yyy_FOUND variable should be set
-accordingly.
-The per-package Xxx_FOUND variable should be only set to true if all requested
-required components have been found. A missing optional component should not
-keep the Xxx_FOUND variable from being set to true.
-If the package provides Xxx_INCLUDE_DIRS and Xxx_LIBRARIES variables, the include
-dirs and libraries for all components which were requested and which have been
-found should be added to those two variables.
-
-To get this behaviour you can use the FIND_PACKAGE_HANDLE_STANDARD_ARGS()
-macro, as an example see FindJPEG.cmake.
-
-For internal implementation, it's a generally accepted convention that variables starting with
-underscore are for temporary use only. (variable starting with an underscore
-are not intended as a reserved prefix).
+For more information about how to contribute modules to CMake, see this page:
+https://cmake.org/Wiki/CMake:Module_Maintainers
diff --git a/Packaging/CMakeDMGBackground.tif b/Packaging/CMakeDMGBackground.tif
new file mode 100644
index 000000000..91c4b1309
--- /dev/null
+++ b/Packaging/CMakeDMGBackground.tif
Binary files differ
diff --git a/Packaging/CMakeDMGSetup.scpt b/Packaging/CMakeDMGSetup.scpt
new file mode 100644
index 000000000..c7ddcfb28
--- /dev/null
+++ b/Packaging/CMakeDMGSetup.scpt
@@ -0,0 +1,42 @@
+on run argv
+ set image_name to item 1 of argv
+
+ tell application "Finder"
+ tell disk image_name
+
+ -- open the image the first time and save a DS_Store with just
+ -- background and icon setup
+ open
+ set current view of container window to icon view
+ set theViewOptions to the icon view options of container window
+ set background picture of theViewOptions to file ".background:background.tif"
+ set arrangement of theViewOptions to not arranged
+ set icon size of theViewOptions to 128
+ delay 1
+ close
+
+ -- next setup the position of the app and Applications symlink
+ -- plus hide all the window decoration
+ open
+ update without registering applications
+ tell container window
+ set sidebar width to 0
+ set statusbar visible to false
+ set toolbar visible to false
+ set the bounds to { 400, 100, 900, 465 }
+ set position of item "CMake.app" to { 133, 200 }
+ set position of item "Applications" to { 378, 200 }
+ end tell
+ update without registering applications
+ delay 1
+ close
+
+ -- one last open and close so you can see everything looks correct
+ open
+ delay 5
+ close
+
+ end tell
+ delay 1
+end tell
+end run
diff --git a/README.rst b/README.rst
new file mode 100644
index 000000000..9599a04b0
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,99 @@
+CMake
+*****
+
+Introduction
+============
+
+CMake is a cross-platform, open-source build system generator.
+For full documentation visit the `CMake Home Page`_ and the
+`CMake Documentation Page`_.
+
+.. _`CMake Home Page`: https://cmake.org
+.. _`CMake Documentation Page`: https://cmake.org/cmake/help/documentation.html
+
+CMake is maintained and supported by `Kitware`_ and developed in
+collaboration with a productive community of contributors.
+
+.. _`Kitware`: http://www.kitware.com/cmake
+
+License
+=======
+
+CMake is distributed under the OSI-approved BSD 3-clause License.
+See `Copyright.txt`_ for details.
+
+.. _`Copyright.txt`: Copyright.txt
+
+Building CMake
+==============
+
+Supported Platforms
+-------------------
+
+MS Windows, Mac OS X, Linux, FreeBSD, Solaris, HP-UX, IRIX, BeOS, QNX
+
+Other UNIX-like operating systems may work too out of the box, if not
+it should not be a major problem to port CMake to this platform.
+Subscribe and post to the `CMake Users List`_ to ask if others have
+had experience with the platform.
+
+.. _`CMake Users List`: https://cmake.org/mailman/listinfo/cmake
+
+Building CMake from Scratch
+---------------------------
+
+UNIX/Mac OSX/MinGW/MSYS/Cygwin
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+You need to have a compiler and a make installed.
+Run the ``bootstrap`` script you find in the source directory of CMake.
+You can use the ``--help`` option to see the supported options.
+You may use the ``--prefix=<install_prefix>`` option to specify a custom
+installation directory for CMake. You can run the ``bootstrap`` script from
+within the CMake source directory or any other build directory of your
+choice. Once this has finished successfully, run ``make`` and
+``make install``. In summary::
+
+ $ ./bootstrap && make && make install
+
+Windows
+^^^^^^^
+
+You need to download and install a binary release of CMake in order to build
+CMake. You can get these releases from the `CMake Download Page`_ . Then
+proceed with the instructions below.
+
+.. _`CMake Download Page`: https://cmake.org/cmake/resources/software.html
+
+Building CMake with CMake
+-------------------------
+
+You can build CMake as any other project with a CMake-based build system:
+run the installed CMake on the sources of this CMake with your preferred
+options and generators. Then build it and install it.
+For instructions how to do this, see documentation on `Running CMake`_.
+
+.. _`Running CMake`: https://cmake.org/cmake/help/runningcmake.html
+
+Reporting Bugs
+==============
+
+If you have found a bug:
+
+1. If you have a patch, please read the `CONTRIBUTING.rst`_ document.
+
+2. Otherwise, please join the `CMake Users List`_ and ask about
+ the expected and observed behaviors to determine if it is really
+ a bug.
+
+3. Finally, if the issue is not resolved by the above steps, open
+ an entry in the `CMake Issue Tracker`_.
+
+.. _`CMake Issue Tracker`: https://cmake.org/Bug
+
+Contributing
+============
+
+See `CONTRIBUTING.rst`_ for instructions to contribute.
+
+.. _`CONTRIBUTING.rst`: CONTRIBUTING.rst
diff --git a/Readme.txt b/Readme.txt
deleted file mode 100644
index 11926bc53..000000000
--- a/Readme.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-This is CMake, the cross-platform, open-source make system.
-CMake is distributed under the BSD License, see Copyright.txt.
-For documentation see the Docs/ directory once you have built CMake
-or visit http://www.cmake.org.
-
-
-Building CMake
-==============
-
-
-Supported Platforms
--------------------
-
-MS Windows, Mac OS X, Linux, FreeBSD, Solaris, HP-UX, IRIX, BeOS, QNX
-
-Other UNIX-like operating systems may work too out of the box, if not
-it shouldn't be a major problem to port CMake to this platform. Contact the
-CMake mailing list in this case: http://www.cmake.org/mailman/listinfo/cmake
-
-
-If you don't have any previous version of CMake already installed
---------------------------------------------------------------
-
-* UNIX/Mac OSX/MinGW/MSYS/Cygwin:
-
-You need to have a compiler and a make installed.
-Run the bootstrap script you find the in the source directory of CMake.
-You can use the --help option to see the supported options.
-You may want to use the --prefix=<install_prefix> option to specify a custom
-installation directory for CMake. You can run the bootstrap script from
-within the CMake source directory or any other build directory of your
-choice. Once this has finished successfully, run make and make install.
-So basically it's the same as you may be used to from autotools-based
-projects:
-
-$ ./bootstrap; make; make install
-
-
-* Other Windows:
-
-You need to download and install a binary release of CMake in order to build
-CMake. You can get these releases from
-http://www.cmake.org/HTML/Download.html . Then proceed with the instructions
-below.
-
-
-You already have a version of CMake installed
----------------------------------------------
-
-You can build CMake as any other project with a CMake-based build system:
-run the installed CMake on the sources of this CMake with your preferred
-options and generators. Then build it and install it.
-For instructions how to do this, see http://www.cmake.org/HTML/RunningCMake.html
diff --git a/Source/CMakeInstallDestinations.cmake b/Source/CMakeInstallDestinations.cmake
new file mode 100644
index 000000000..2f9d95ae5
--- /dev/null
+++ b/Source/CMakeInstallDestinations.cmake
@@ -0,0 +1,43 @@
+# Keep formatting here consistent with bootstrap script expectations.
+if(BEOS)
+ set(CMAKE_DATA_DIR_DEFAULT "share/cmake-${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}") # HAIKU
+ set(CMAKE_MAN_DIR_DEFAULT "documentation/man") # HAIKU
+ set(CMAKE_DOC_DIR_DEFAULT "documentation/doc/cmake-${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}") # HAIKU
+ set(CMAKE_XDGDATA_DIR_DEFAULT "share") # HAIKU
+elseif(CYGWIN)
+ set(CMAKE_DATA_DIR_DEFAULT "share/cmake-${CMake_VERSION}") # CYGWIN
+ set(CMAKE_DOC_DIR_DEFAULT "share/doc/cmake-${CMake_VERSION}") # CYGWIN
+ set(CMAKE_MAN_DIR_DEFAULT "share/man") # CYGWIN
+ set(CMAKE_XDGDATA_DIR_DEFAULT "share") # CYGWIN
+else()
+ set(CMAKE_DATA_DIR_DEFAULT "share/cmake-${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}") # OTHER
+ set(CMAKE_DOC_DIR_DEFAULT "doc/cmake-${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}") # OTHER
+ set(CMAKE_MAN_DIR_DEFAULT "man") # OTHER
+ set(CMAKE_XDGDATA_DIR_DEFAULT "share") # OTHER
+endif()
+
+set(CMAKE_DATA_DIR_DESC "data")
+set(CMAKE_DOC_DIR_DESC "docs")
+set(CMAKE_MAN_DIR_DESC "man pages")
+set(CMAKE_XDGDATA_DIR_DESC "XDG specific files")
+
+foreach(v
+ CMAKE_DATA_DIR
+ CMAKE_DOC_DIR
+ CMAKE_MAN_DIR
+ CMAKE_XDGDATA_DIR
+ )
+ # Populate the cache with empty values so we know when the user sets them.
+ set(${v} "" CACHE STRING "")
+ set_property(CACHE ${v} PROPERTY HELPSTRING
+ "Location under install prefix for ${${v}_DESC} (default \"${${v}_DEFAULT}\")"
+ )
+ set_property(CACHE ${v} PROPERTY ADVANCED 1)
+
+ # Use the default when the user did not set this variable.
+ if(NOT ${v})
+ set(${v} "${${v}_DEFAULT}")
+ endif()
+ # Remove leading slash to treat as relative to install prefix.
+ string(REGEX REPLACE "^/" "" ${v} "${${v}}")
+endforeach()
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 8412e3e86..4ef0e8047 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -18,12 +18,38 @@ else()
endif()
if(HAVE_ELF_H)
set(CMAKE_USE_ELF_PARSER 1)
+elseif(HAIKU)
+ # On Haiku, we need to include elf32.h from the private headers
+ set(CMake_HAIKU_INCLUDE_DIRS
+ /boot/system/develop/headers/private/system
+ /boot/system/develop/headers/private/system/arch/x86
+ )
+
+ set(CMAKE_REQUIRED_INCLUDES ${CMake_HAIKU_INCLUDE_DIRS})
+ CHECK_INCLUDE_FILE("elf32.h" HAVE_ELF32_H)
+ unset(CMAKE_REQUIRED_INCLUDES)
+
+ if(HAVE_ELF32_H)
+ set(CMAKE_USE_ELF_PARSER 1)
+ else()
+ unset(CMake_HAIKU_INCLUDE_DIRS)
+ set(CMAKE_USE_ELF_PARSER)
+ endif()
else()
set(CMAKE_USE_ELF_PARSER)
endif()
+if(APPLE)
+ set(CMAKE_USE_MACH_PARSER 1)
+endif()
+
set(EXECUTABLE_OUTPUT_PATH ${CMake_BIN_DIR})
+# ensure Unicode friendly APIs are used on Windows
+if(WIN32)
+ add_definitions(-DUNICODE -D_UNICODE)
+endif()
+
# configure the .h file
configure_file(
"${CMake_SOURCE_DIR}/Source/cmConfigure.cmake.h.in"
@@ -38,6 +64,12 @@ configure_file(
"${CMake_BINARY_DIR}/Source/CPack/cmCPackConfigure.h"
)
+# Tell CMake executable in the build tree where to find the source tree.
+configure_file(
+ "${CMake_SOURCE_DIR}/Source/CMakeSourceDir.txt.in"
+ "${CMake_BINARY_DIR}/CMakeFiles/CMakeSourceDir.txt" @ONLY
+ )
+
# add the include path to find the .h
include_directories(
"${CMake_BINARY_DIR}/Source"
@@ -46,6 +78,7 @@ include_directories(
${CMAKE_EXPAT_INCLUDES}
${CMAKE_TAR_INCLUDES}
${CMAKE_COMPRESS_INCLUDES}
+ ${CMake_HAIKU_INCLUDE_DIRS}
)
# let cmake know it is supposed to use it
@@ -55,7 +88,7 @@ option(CMAKE_REGENERATE_YACCLEX
"Regenerate YACC and LEXX files" OFF)
mark_as_advanced(CMAKE_REGENERATE_YACCLEX)
if(CMAKE_REGENERATE_YACCLEX)
- set(parsersLexers cmDependsFortran cmCommandArgument cmExpr)
+ set(parsersLexers cmFortran cmCommandArgument cmExpr)
find_program(YACC_EXECUTABLE
NAMES yacc bison
PATHS /usr/bin
@@ -111,21 +144,29 @@ if(CMAKE_USE_ELF_PARSER)
set(ELF_SRCS cmELF.h cmELF.cxx)
endif()
+# Check if we can build the Mach-O parser.
+if(CMAKE_USE_MACH_PARSER)
+ set(MACH_SRCS cmMachO.h cmMachO.cxx)
+endif()
+
#
# Sources for CMakeLib
#
set(SRCS
- cmStandardIncludes.cxx
cmArchiveWrite.cxx
cmBootstrapCommands1.cxx
cmBootstrapCommands2.cxx
cmCacheManager.cxx
cmCacheManager.h
- cmCommands.cxx
+ "${CMAKE_CURRENT_BINARY_DIR}/cmCommands.cxx"
+ cmCLocaleEnvironmentScope.h
+ cmCLocaleEnvironmentScope.cxx
cmCommands.h
cmCommandArgumentLexer.cxx
cmCommandArgumentParser.cxx
cmCommandArgumentParserHelper.cxx
+ cmCommonTargetGenerator.cxx
+ cmCommonTargetGenerator.h
cmComputeComponentGraph.cxx
cmComputeComponentGraph.h
cmComputeLinkDepends.cxx
@@ -134,8 +175,12 @@ set(SRCS
cmComputeLinkInformation.h
cmComputeTargetDepends.h
cmComputeTargetDepends.cxx
+ cmCPackPropertiesGenerator.h
+ cmCPackPropertiesGenerator.cxx
cmCryptoHash.cxx
cmCryptoHash.h
+ cmCurl.cxx
+ cmCurl.h
cmCustomCommand.cxx
cmCustomCommand.h
cmCustomCommandGenerator.cxx
@@ -148,9 +193,6 @@ set(SRCS
cmDependsC.h
cmDependsFortran.cxx
cmDependsFortran.h
- cmDependsFortranLexer.cxx
- cmDependsFortranParser.cxx
- cmDependsFortranParser.h
cmDependsJava.cxx
cmDependsJava.h
cmDependsJavaLexer.cxx
@@ -159,16 +201,7 @@ set(SRCS
cmDependsJavaParserHelper.h
cmDocumentation.cxx
cmDocumentationFormatter.cxx
- cmDocumentationFormatterHTML.cxx
- cmDocumentationFormatterDocbook.cxx
- cmDocumentationFormatterMan.cxx
- cmDocumentationFormatterText.cxx
- cmDocumentationFormatterUsage.cxx
cmDocumentationSection.cxx
- cmDocumentCompileDefinitions.h
- cmDocumentGeneratorExpressions.h
- cmDocumentLocationUndefined.h
- cmDocumentVariables.cxx
cmDynamicLoader.cxx
cmDynamicLoader.h
${ELF_SRCS}
@@ -187,27 +220,52 @@ set(SRCS
cmExportSet.cxx
cmExportSetMap.h
cmExportSetMap.cxx
+ cmExternalMakefileProjectGenerator.cxx
+ cmExternalMakefileProjectGenerator.h
cmExtraCodeBlocksGenerator.cxx
cmExtraCodeBlocksGenerator.h
+ cmExtraCodeLiteGenerator.cxx
+ cmExtraCodeLiteGenerator.h
cmExtraEclipseCDT4Generator.cxx
cmExtraEclipseCDT4Generator.h
+ cmExtraKateGenerator.cxx
+ cmExtraKateGenerator.h
cmExtraSublimeTextGenerator.cxx
cmExtraSublimeTextGenerator.h
+ cmFileLock.cxx
+ cmFileLock.h
+ cmFileLockPool.cxx
+ cmFileLockPool.h
+ cmFileLockResult.cxx
+ cmFileLockResult.h
cmFileTimeComparison.cxx
cmFileTimeComparison.h
+ cmFortranLexer.cxx
+ cmFortranLexer.h
+ cmFortranParser.cxx
+ cmFortranParser.h
+ cmFortranParserImpl.cxx
cmGeneratedFileStream.cxx
+ cmGeneratorExpressionContext.cxx
+ cmGeneratorExpressionContext.h
cmGeneratorExpressionDAGChecker.cxx
cmGeneratorExpressionDAGChecker.h
+ cmGeneratorExpressionEvaluationFile.cxx
+ cmGeneratorExpressionEvaluationFile.h
cmGeneratorExpressionEvaluator.cxx
cmGeneratorExpressionEvaluator.h
cmGeneratorExpressionLexer.cxx
cmGeneratorExpressionLexer.h
+ cmGeneratorExpressionNode.cxx
+ cmGeneratorExpressionNode.h
cmGeneratorExpressionParser.cxx
cmGeneratorExpressionParser.h
cmGeneratorExpression.cxx
cmGeneratorExpression.h
cmGeneratorTarget.cxx
cmGeneratorTarget.h
+ cmGlobalCommonGenerator.cxx
+ cmGlobalCommonGenerator.h
cmGlobalGenerator.cxx
cmGlobalGenerator.h
cmGlobalGeneratorFactory.h
@@ -219,6 +277,8 @@ set(SRCS
cmInstallGenerator.h
cmInstallGenerator.cxx
cmInstallExportGenerator.cxx
+ cmInstalledFile.h
+ cmInstalledFile.cxx
cmInstallFilesGenerator.h
cmInstallFilesGenerator.cxx
cmInstallScriptGenerator.h
@@ -227,14 +287,18 @@ set(SRCS
cmInstallTargetGenerator.cxx
cmInstallDirectoryGenerator.h
cmInstallDirectoryGenerator.cxx
+ cmLinkedTree.h
+ cmLinkItem.h
cmListFileCache.cxx
cmListFileCache.h
cmListFileLexer.c
+ cmLocalCommonGenerator.cxx
+ cmLocalCommonGenerator.h
cmLocalGenerator.cxx
cmLocalGenerator.h
cmLocalUnixMakefileGenerator3.cxx
- cmMakeDepend.cxx
- cmMakeDepend.h
+ cmLocale.h
+ ${MACH_SRCS}
cmMakefile.cxx
cmMakefile.h
cmMakefileTargetGenerator.cxx
@@ -243,6 +307,8 @@ set(SRCS
cmMakefileUtilityTargetGenerator.cxx
cmOSXBundleGenerator.cxx
cmOSXBundleGenerator.h
+ cmOutputConverter.cxx
+ cmOutputConverter.h
cmNewLineStyle.h
cmNewLineStyle.cxx
cmOrderDirectories.cxx
@@ -259,8 +325,12 @@ set(SRCS
cmPropertyDefinitionMap.h
cmPropertyMap.cxx
cmPropertyMap.h
- cmQtAutomoc.cxx
- cmQtAutomoc.h
+ cmQtAutoGeneratorInitializer.cxx
+ cmQtAutoGeneratorInitializer.h
+ cmQtAutoGenerators.cxx
+ cmQtAutoGenerators.h
+ cmRST.cxx
+ cmRST.h
cmScriptGenerator.h
cmScriptGenerator.cxx
cmSourceFile.cxx
@@ -269,6 +339,8 @@ set(SRCS
cmSourceFileLocation.h
cmSourceGroup.cxx
cmSourceGroup.h
+ cmState.cxx
+ cmState.h
cmSystemTools.cxx
cmSystemTools.h
cmTarget.cxx
@@ -278,6 +350,7 @@ set(SRCS
cmTest.h
cmTestGenerator.cxx
cmTestGenerator.h
+ cmUuid.cxx
cmVariableWatch.cxx
cmVariableWatch.h
cmVersion.cxx
@@ -286,17 +359,65 @@ set(SRCS
cmXMLParser.h
cmXMLSafe.cxx
cmXMLSafe.h
+ cmXMLWriter.cxx
+ cmXMLWriter.h
cmake.cxx
cmake.h
- cmakewizard.cxx
- cmakewizard.h
+ cm_get_date.h
+ cm_get_date.c
cm_sha2.h
cm_sha2.c
cm_utf8.h
cm_utf8.c
)
+set(COMMAND_INCLUDES "#include \"cmTargetPropCommandBase.cxx\"\n")
+list(APPEND SRCS cmTargetPropCommandBase.cxx)
+set_property(SOURCE cmTargetPropCommandBase.cxx PROPERTY HEADER_FILE_ONLY ON)
+set(NEW_COMMANDS "")
+foreach(command_file
+ cmAddCompileOptionsCommand
+ cmAuxSourceDirectoryCommand
+ cmBuildNameCommand
+ cmCMakeHostSystemInformationCommand
+ cmElseIfCommand
+ cmExportCommand
+ cmExportLibraryDependenciesCommand
+ cmFLTKWrapUICommand
+ cmIncludeExternalMSProjectCommand
+ cmInstallProgramsCommand
+ cmLinkLibrariesCommand
+ cmLoadCacheCommand
+ cmOutputRequiredFilesCommand
+ cmQTWrapCPPCommand
+ cmQTWrapUICommand
+ cmRemoveCommand
+ cmRemoveDefinitionsCommand
+ cmSourceGroupCommand
+ cmSubdirDependsCommand
+ cmTargetCompileDefinitionsCommand
+ cmTargetCompileFeaturesCommand
+ cmTargetCompileOptionsCommand
+ cmTargetIncludeDirectoriesCommand
+ cmTargetSourcesCommand
+ cmUseMangledMesaCommand
+ cmUtilitySourceCommand
+ cmVariableRequiresCommand
+ cmVariableWatchCommand
+ cmWriteFileCommand
+ # This one must be last because it includes windows.h and
+ # windows.h #defines GetCurrentDirectory which is a member
+ # of cmMakefile
+ cmLoadCommandCommand
+ )
+ set(COMMAND_INCLUDES "${COMMAND_INCLUDES}#include \"${command_file}.cxx\"\n")
+ set(NEW_COMMANDS "${NEW_COMMANDS}commands.push_back(new ${command_file});\n")
+ list(APPEND SRCS ${command_file}.cxx)
+ set_property(SOURCE ${command_file}.cxx PROPERTY HEADER_FILE_ONLY ON)
+endforeach()
+configure_file(cmCommands.cxx.in ${CMAKE_CURRENT_BINARY_DIR}/cmCommands.cxx @ONLY)
+
# Kdevelop only works on UNIX and not windows
if(UNIX)
set(SRCS ${SRCS} cmGlobalKdevelopGenerator.cxx)
@@ -318,6 +439,7 @@ if (WIN32)
set(SRCS ${SRCS}
cmCallVisualStudioMacro.cxx
cmCallVisualStudioMacro.h
+ bindexplib.cxx
)
if(NOT UNIX)
@@ -352,9 +474,10 @@ if (WIN32)
cmGlobalVisualStudio11Generator.cxx
cmGlobalVisualStudio12Generator.h
cmGlobalVisualStudio12Generator.cxx
+ cmGlobalVisualStudio14Generator.h
+ cmGlobalVisualStudio14Generator.cxx
cmGlobalVisualStudioGenerator.cxx
cmGlobalVisualStudioGenerator.h
- cmGlobalWatcomWMakeGenerator.cxx
cmIDEFlagTable.h
cmIDEOptions.cxx
cmIDEOptions.h
@@ -370,12 +493,31 @@ if (WIN32)
cmVisualStudioSlnParser.cxx
cmVisualStudioWCEPlatformParser.h
cmVisualStudioWCEPlatformParser.cxx
- cmWin32ProcessExecution.cxx
- cmWin32ProcessExecution.h
+ cmGlobalGhsMultiGenerator.cxx
+ cmGlobalGhsMultiGenerator.h
+ cmLocalGhsMultiGenerator.cxx
+ cmLocalGhsMultiGenerator.h
+ cmGhsMultiTargetGenerator.cxx
+ cmGhsMultiTargetGenerator.h
+ cmGhsMultiGpj.cxx
+ cmGhsMultiGpj.h
)
+
+ # Add a manifest file to executables on Windows to allow for
+ # GetVersion to work properly on Windows 8 and above.
+ set(MANIFEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/cmake.version.manifest)
endif()
endif ()
+# Watcom support
+if(WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ set_property(SOURCE cmake.cxx APPEND PROPERTY COMPILE_DEFINITIONS CMAKE_USE_WMAKE)
+ list(APPEND SRCS
+ cmGlobalWatcomWMakeGenerator.cxx
+ cmGlobalWatcomWMakeGenerator.h
+ )
+endif()
+
# Ninja support
set(SRCS ${SRCS}
cmGlobalNinjaGenerator.cxx
@@ -390,28 +532,52 @@ set(SRCS ${SRCS}
cmNinjaUtilityTargetGenerator.cxx
cmNinjaUtilityTargetGenerator.h
)
-if(WIN32 AND NOT CYGWIN AND NOT BORLAND)
+
+if(WIN32 AND NOT CYGWIN)
set_source_files_properties(cmcldeps.cxx PROPERTIES COMPILE_DEFINITIONS _WIN32_WINNT=0x0501)
- add_executable(cmcldeps cmcldeps.cxx)
+ add_executable(cmcldeps cmcldeps.cxx ${MANIFEST_FILE})
target_link_libraries(cmcldeps CMakeLib)
install(TARGETS cmcldeps DESTINATION bin)
endif()
+foreach(v CURL_CA_BUNDLE CURL_CA_PATH)
+ if(${v})
+ set_property(SOURCE cmCurl.cxx APPEND PROPERTY COMPILE_DEFINITIONS ${v}="${${v}}")
+ endif()
+endforeach()
+
+foreach(check
+ STAT_HAS_ST_MTIM
+ STAT_HAS_ST_MTIMESPEC
+ )
+ if(KWSYS_CXX_${check}_COMPILED) # abuse KWSys check cache entry
+ set(CMake_${check} 1)
+ else()
+ set(CMake_${check} 0)
+ endif()
+ set_property(SOURCE cmFileTimeComparison.cxx APPEND PROPERTY
+ COMPILE_DEFINITIONS CMake_${check}=${CMake_${check}})
+endforeach()
+
# create a library used by the command line and the GUI
add_library(CMakeLib ${SRCS})
target_link_libraries(CMakeLib cmsys
${CMAKE_EXPAT_LIBRARIES} ${CMAKE_ZLIB_LIBRARIES}
${CMAKE_TAR_LIBRARIES} ${CMAKE_COMPRESS_LIBRARIES}
- ${CMAKE_CURL_LIBRARIES} )
+ ${CMAKE_CURL_LIBRARIES}
+ ${CMAKE_JSONCPP_LIBRARIES}
+ ${CMake_KWIML_LIBRARIES}
+ )
# On Apple we need CoreFoundation
if(APPLE)
target_link_libraries(CMakeLib "-framework CoreFoundation")
endif()
-# On some platforms we need the rpcrt4 library for the VS 7 generators.
-if(CMAKE_BUILD_ON_VISUAL_STUDIO OR MINGW)
- target_link_libraries(CMakeLib rpcrt4)
+if(WIN32 AND NOT UNIX)
+ # We need the rpcrt4 library on Windows.
+ # We need the crypt32 library on Windows for crypto/cert APIs.
+ target_link_libraries(CMakeLib rpcrt4 crypt32)
endif()
#
@@ -435,10 +601,15 @@ set(CTEST_SRCS cmCTest.cxx
CTest/cmCTestConfigureHandler.cxx
CTest/cmCTestCoverageCommand.cxx
CTest/cmCTestCoverageHandler.cxx
+ CTest/cmCTestCurl.cxx
CTest/cmParseMumpsCoverage.cxx
CTest/cmParseCacheCoverage.cxx
CTest/cmParseGTMCoverage.cxx
+ CTest/cmParseJacocoCoverage.cxx
+ CTest/cmParseBlanketJSCoverage.cxx
CTest/cmParsePHPCoverage.cxx
+ CTest/cmParseCoberturaCoverage.cxx
+ CTest/cmParseDelphiCoverage.cxx
CTest/cmCTestEmptyBinaryDirectoryCommand.cxx
CTest/cmCTestGenericHandler.cxx
CTest/cmCTestHandlerCommand.cxx
@@ -475,6 +646,8 @@ set(CTEST_SRCS cmCTest.cxx
CTest/cmCTestGIT.h
CTest/cmCTestHG.cxx
CTest/cmCTestHG.h
+ CTest/cmCTestP4.cxx
+ CTest/cmCTestP4.h
)
# Build CTestLib
@@ -491,13 +664,16 @@ set(CPACK_SRCS
CPack/cmCPackGenerator.cxx
CPack/cmCPackLog.cxx
CPack/cmCPackNSISGenerator.cxx
+ CPack/IFW/cmCPackIFWPackage.cxx
+ CPack/IFW/cmCPackIFWInstaller.cxx
+ CPack/IFW/cmCPackIFWGenerator.cxx
CPack/cmCPackSTGZGenerator.cxx
CPack/cmCPackTGZGenerator.cxx
+ CPack/cmCPackTXZGenerator.cxx
CPack/cmCPackTarBZip2Generator.cxx
CPack/cmCPackTarCompressGenerator.cxx
CPack/cmCPackZIPGenerator.cxx
- CPack/cmCPackDocumentVariables.cxx
- CPack/cmCPackDocumentMacros.cxx
+ CPack/cmCPack7zGenerator.cxx
)
if(CYGWIN)
@@ -517,8 +693,25 @@ endif()
if(WIN32)
set(CPACK_SRCS ${CPACK_SRCS}
CPack/WiX/cmCPackWIXGenerator.cxx
- CPack/WiX/cmWIXSourceWriter.cxx
+ CPack/WiX/cmCPackWIXGenerator.h
+ CPack/WiX/cmWIXAccessControlList.cxx
+ CPack/WiX/cmWIXAccessControlList.h
+ CPack/WiX/cmWIXDirectoriesSourceWriter.cxx
+ CPack/WiX/cmWIXDirectoriesSourceWriter.h
+ CPack/WiX/cmWIXFeaturesSourceWriter.cxx
+ CPack/WiX/cmWIXFeaturesSourceWriter.h
+ CPack/WiX/cmWIXFilesSourceWriter.cxx
+ CPack/WiX/cmWIXFilesSourceWriter.h
+ CPack/WiX/cmWIXPatch.cxx
+ CPack/WiX/cmWIXPatch.h
+ CPack/WiX/cmWIXPatchParser.cxx
+ CPack/WiX/cmWIXPatchParser.h
CPack/WiX/cmWIXRichTextFormatWriter.cxx
+ CPack/WiX/cmWIXRichTextFormatWriter.h
+ CPack/WiX/cmWIXShortcut.cxx
+ CPack/WiX/cmWIXShortcut.h
+ CPack/WiX/cmWIXSourceWriter.cxx
+ CPack/WiX/cmWIXSourceWriter.h
)
endif()
@@ -534,6 +727,22 @@ endif()
# Build CPackLib
add_library(CPackLib ${CPACK_SRCS})
target_link_libraries(CPackLib CMakeLib)
+if(APPLE)
+ # Some compilers produce errors in the CoreServices framework headers.
+ # Ideally such errors should be fixed by either the compiler vendor
+ # or the framework source, but we try to workaround it and build anyway.
+ # If it does not work, build with reduced functionality and warn.
+ check_include_file("CoreServices/CoreServices.h" HAVE_CoreServices)
+ if(HAVE_CoreServices)
+ set_property(SOURCE CPack/cmCPackDragNDropGenerator.cxx PROPERTY COMPILE_DEFINITIONS HAVE_CoreServices)
+ target_link_libraries(CPackLib "-framework CoreServices")
+ else()
+ message(WARNING "This compiler does not appear to support\n"
+ " #include <CoreServices/CoreServices.h>\n"
+ "Some CPack functionality may be limited.\n"
+ "See CMakeFiles/CMakeError.log for details of the failure.")
+ endif()
+endif()
if(APPLE)
add_executable(cmakexbuild cmakexbuild.cxx)
@@ -545,25 +754,15 @@ if(APPLE)
endif()
# Build CMake executable
-add_executable(cmake cmakemain.cxx)
+add_executable(cmake cmakemain.cxx cmcmd.cxx cmcmd.h ${MANIFEST_FILE})
target_link_libraries(cmake CMakeLib)
-# Build special executable for running programs on Windows 98.
-# Included on any Windows (unconditional packaging required!).
-if(WIN32)
- if(NOT UNIX)
- add_executable(cmw9xcom cmw9xcom.cxx)
- target_link_libraries(cmw9xcom CMakeLib)
- install(TARGETS cmw9xcom DESTINATION bin)
- endif()
-endif()
-
# Build CTest executable
-add_executable(ctest ctest.cxx)
+add_executable(ctest ctest.cxx ${MANIFEST_FILE})
target_link_libraries(ctest CTestLib)
# Build CPack executable
-add_executable(cpack CPack/cpack.cxx)
+add_executable(cpack CPack/cpack.cxx ${MANIFEST_FILE})
target_link_libraries(cpack CPackLib)
# Curses GUI
@@ -580,9 +779,17 @@ endif()
include (${CMake_BINARY_DIR}/Source/LocalUserOptions.cmake OPTIONAL)
include (${CMake_SOURCE_DIR}/Source/LocalUserOptions.cmake OPTIONAL)
-install(TARGETS cmake ctest cpack DESTINATION bin)
+# Install tools
+
+set(_tools cmake ctest cpack)
+
if(APPLE)
- install(TARGETS cmakexbuild DESTINATION bin)
+ list(APPEND _tools cmakexbuild)
endif()
+foreach(_tool ${_tools})
+ CMake_OPTIONAL_COMPONENT(${_tool})
+ install(TARGETS ${_tool} DESTINATION bin ${COMPONENT})
+endforeach()
+
install(FILES cmCPluginAPI.h DESTINATION ${CMAKE_DATA_DIR}/include)
diff --git a/Source/CMakeSourceDir.txt.in b/Source/CMakeSourceDir.txt.in
new file mode 100644
index 000000000..5e6a988c0
--- /dev/null
+++ b/Source/CMakeSourceDir.txt.in
@@ -0,0 +1 @@
+@CMake_SOURCE_DIR@
diff --git a/Source/CMakeVersion.bash b/Source/CMakeVersion.bash
index 4794e608d..853b0ca28 100755
--- a/Source/CMakeVersion.bash
+++ b/Source/CMakeVersion.bash
@@ -3,5 +3,5 @@
if test "x$1" = "x-f"; then shift ; n='*' ; else n='\{8\}' ; fi
if test "$#" -gt 0; then echo 1>&2 "usage: CMakeVersion.bash [-f]"; exit 1; fi
sed -i -e '
-s/\(^set(CMake_VERSION_TWEAK\) [0-9]'"$n"'\(.*\)/\1 '"$(date +%Y%m%d)"'\2/
+s/\(^set(CMake_VERSION_PATCH\) [0-9]'"$n"'\(.*\)/\1 '"$(date +%Y%m%d)"'\2/
' "${BASH_SOURCE%/*}/CMakeVersion.cmake"
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index fd315ce6c..683da4376 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,6 +1,5 @@
# CMake version number components.
-set(CMake_VERSION_MAJOR 2)
-set(CMake_VERSION_MINOR 8)
-set(CMake_VERSION_PATCH 12)
-set(CMake_VERSION_TWEAK 2)
+set(CMake_VERSION_MAJOR 3)
+set(CMake_VERSION_MINOR 5)
+set(CMake_VERSION_PATCH 1)
#set(CMake_VERSION_RC 0)
diff --git a/Source/CMakeVersionCompute.cmake b/Source/CMakeVersionCompute.cmake
new file mode 100644
index 000000000..496d6cf1a
--- /dev/null
+++ b/Source/CMakeVersionCompute.cmake
@@ -0,0 +1,20 @@
+# Load version number components.
+include(${CMake_SOURCE_DIR}/Source/CMakeVersion.cmake)
+
+# Releases define a small patch level.
+if("${CMake_VERSION_PATCH}" VERSION_LESS 20000000)
+ set(CMake_VERSION_IS_RELEASE 1)
+ set(CMake_VERSION_SOURCE "")
+else()
+ set(CMake_VERSION_IS_RELEASE 0)
+ include(${CMake_SOURCE_DIR}/Source/CMakeVersionSource.cmake)
+endif()
+
+# Compute the full version string.
+set(CMake_VERSION ${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}.${CMake_VERSION_PATCH})
+if(CMake_VERSION_RC)
+ set(CMake_VERSION ${CMake_VERSION}-rc${CMake_VERSION_RC})
+endif()
+if(CMake_VERSION_SOURCE)
+ set(CMake_VERSION ${CMake_VERSION}-${CMake_VERSION_SOURCE})
+endif()
diff --git a/Source/CMakeVersionSource.cmake b/Source/CMakeVersionSource.cmake
index 05e265c03..888f557fb 100644
--- a/Source/CMakeVersionSource.cmake
+++ b/Source/CMakeVersionSource.cmake
@@ -30,8 +30,8 @@ if(EXISTS ${CMake_SOURCE_DIR}/.git/HEAD)
elseif(EXISTS ${CMake_SOURCE_DIR}/CVS/Repository)
file(READ ${CMake_SOURCE_DIR}/CVS/Repository repo)
set(branch "")
- if("${repo}" MATCHES "\\.git/")
- string(REGEX REPLACE ".*\\.git/([^\r\n]*).*" "-\\1" branch "${repo}")
+ if("${repo}" MATCHES "\\.git/([^\r\n]*)")
+ set(branch "${CMAKE_MATCH_1}")
endif()
set(CMake_VERSION_SOURCE "cvs${branch}")
endif()
diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.cxx b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
new file mode 100644
index 000000000..4eb23c182
--- /dev/null
+++ b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
@@ -0,0 +1,628 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmCPackIFWGenerator.h"
+
+#include "cmCPackIFWPackage.h"
+#include "cmCPackIFWInstaller.h"
+
+#include <CPack/cmCPackLog.h>
+#include <CPack/cmCPackComponentGroup.h>
+
+#include <cmsys/SystemTools.hxx>
+#include <cmsys/Glob.hxx>
+#include <cmsys/Directory.hxx>
+#include <cmsys/RegularExpression.hxx>
+
+#include <cmGlobalGenerator.h>
+#include <cmSystemTools.h>
+#include <cmMakefile.h>
+#include <cmGeneratedFileStream.h>
+#include <cmXMLSafe.h>
+#include <cmVersionConfig.h>
+#include <cmTimestamp.h>
+
+//----------------------------------------------------------------------------
+cmCPackIFWGenerator::cmCPackIFWGenerator()
+{
+}
+
+//----------------------------------------------------------------------------
+cmCPackIFWGenerator::~cmCPackIFWGenerator()
+{
+}
+
+//----------------------------------------------------------------------------
+bool cmCPackIFWGenerator::IsVersionLess(const char *version)
+{
+ return cmSystemTools::VersionCompare(cmSystemTools::OP_LESS,
+ FrameworkVersion.data(), version);
+}
+
+//----------------------------------------------------------------------------
+bool cmCPackIFWGenerator::IsVersionGreater(const char *version)
+{
+ return cmSystemTools::VersionCompare(cmSystemTools::OP_GREATER,
+ FrameworkVersion.data(), version);
+}
+
+//----------------------------------------------------------------------------
+bool cmCPackIFWGenerator::IsVersionEqual(const char *version)
+{
+ return cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL,
+ FrameworkVersion.data(), version);
+}
+
+//----------------------------------------------------------------------------
+int cmCPackIFWGenerator::PackageFiles()
+{
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- Configuration" << std::endl);
+
+ // Installer configuragion
+ Installer.GenerateInstallerFile();
+
+ // Packages configuration
+ Installer.GeneratePackageFiles();
+
+ std::string ifwTLD = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
+ std::string ifwTmpFile = ifwTLD;
+ ifwTmpFile += "/IFWOutput.log";
+
+ // Run repogen
+ if (!Installer.Repositories.empty())
+ {
+ std::string ifwCmd = RepoGen;
+
+ if(IsVersionLess("2.0.0"))
+ {
+ ifwCmd += " -c " + this->toplevel + "/config/config.xml";
+ }
+
+ ifwCmd += " -p " + this->toplevel + "/packages";
+
+ if(!PkgsDirsVector.empty())
+ {
+ for(std::vector<std::string>::iterator it = PkgsDirsVector.begin();
+ it != PkgsDirsVector.end(); ++it)
+ {
+ ifwCmd += " -p " + *it;
+ }
+ }
+
+ if (!OnlineOnly && !DownloadedPackages.empty())
+ {
+ ifwCmd += " -i ";
+ std::set<cmCPackIFWPackage*>::iterator it
+ = DownloadedPackages.begin();
+ ifwCmd += (*it)->Name;
+ ++it;
+ while(it != DownloadedPackages.end())
+ {
+ ifwCmd += "," + (*it)->Name;
+ ++it;
+ }
+ }
+ ifwCmd += " " + this->toplevel + "/repository";
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << ifwCmd
+ << std::endl);
+ std::string output;
+ int retVal = 1;
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+ "- Generate repository" << std::endl);
+ bool res = cmSystemTools::RunSingleCommand(
+ ifwCmd.c_str(), &output, &output,
+ &retVal, 0, this->GeneratorVerbose, 0);
+ if ( !res || retVal )
+ {
+ cmGeneratedFileStream ofs(ifwTmpFile.c_str());
+ ofs << "# Run command: " << ifwCmd << std::endl
+ << "# Output:" << std::endl
+ << output << std::endl;
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running IFW command: "
+ << ifwCmd << std::endl
+ << "Please check " << ifwTmpFile << " for errors"
+ << std::endl);
+ return 0;
+ }
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- repository: " << this->toplevel
+ << "/repository generated" << std::endl);
+ }
+
+ // Run binary creator
+ {
+ std::string ifwCmd = BinCreator;
+ ifwCmd += " -c " + this->toplevel + "/config/config.xml";
+ ifwCmd += " -p " + this->toplevel + "/packages";
+
+ if(!PkgsDirsVector.empty())
+ {
+ for(std::vector<std::string>::iterator it = PkgsDirsVector.begin();
+ it != PkgsDirsVector.end(); ++it)
+ {
+ ifwCmd += " -p " + *it;
+ }
+ }
+
+ if (OnlineOnly)
+ {
+ ifwCmd += " --online-only";
+ }
+ else if (!DownloadedPackages.empty() && !Installer.Repositories.empty())
+ {
+ ifwCmd += " -e ";
+ std::set<cmCPackIFWPackage*>::iterator it
+ = DownloadedPackages.begin();
+ ifwCmd += (*it)->Name;
+ ++it;
+ while(it != DownloadedPackages.end())
+ {
+ ifwCmd += "," + (*it)->Name;
+ ++it;
+ }
+ }
+ else if (!DependentPackages.empty())
+ {
+ ifwCmd += " -i ";
+ // Binary
+ std::set<cmCPackIFWPackage*>::iterator bit = BinaryPackages.begin();
+ while(bit != BinaryPackages.end())
+ {
+ ifwCmd += (*bit)->Name + ",";
+ ++bit;
+ }
+ // Depend
+ DependenceMap::iterator it = DependentPackages.begin();
+ ifwCmd += it->second.Name;
+ ++it;
+ while(it != DependentPackages.end())
+ {
+ ifwCmd += "," + it->second.Name;
+ ++it;
+ }
+ }
+ // TODO: set correct name for multipackages
+ if (!this->packageFileNames.empty())
+ {
+ ifwCmd += " " + packageFileNames[0];
+ }
+ else
+ {
+ ifwCmd += " installer";
+ }
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << ifwCmd
+ << std::endl);
+ std::string output;
+ int retVal = 1;
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- Generate package" << std::endl);
+ bool res = cmSystemTools::RunSingleCommand(
+ ifwCmd.c_str(), &output, &output,
+ &retVal, 0, this->GeneratorVerbose, 0);
+ if ( !res || retVal )
+ {
+ cmGeneratedFileStream ofs(ifwTmpFile.c_str());
+ ofs << "# Run command: " << ifwCmd << std::endl
+ << "# Output:" << std::endl
+ << output << std::endl;
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running IFW command: "
+ << ifwCmd << std::endl
+ << "Please check " << ifwTmpFile << " for errors"
+ << std::endl);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+//----------------------------------------------------------------------------
+const char *cmCPackIFWGenerator::GetPackagingInstallPrefix()
+{
+ const char *defPrefix = cmCPackGenerator::GetPackagingInstallPrefix();
+
+ std::string tmpPref = defPrefix ? defPrefix : "";
+
+ if(this->Components.empty())
+ {
+ tmpPref += "packages/" + GetRootPackageName() + "/data";
+ }
+
+ this->SetOption("CPACK_IFW_PACKAGING_INSTALL_PREFIX", tmpPref.c_str());
+
+ return this->GetOption("CPACK_IFW_PACKAGING_INSTALL_PREFIX");
+}
+
+//----------------------------------------------------------------------------
+const char *cmCPackIFWGenerator::GetOutputExtension()
+{
+ return ExecutableSuffix.c_str();
+}
+
+//----------------------------------------------------------------------------
+int cmCPackIFWGenerator::InitializeInternal()
+{
+ // Search Qt Installer Framework tools
+
+ const std::string BinCreatorOpt = "CPACK_IFW_BINARYCREATOR_EXECUTABLE";
+ const std::string RepoGenOpt = "CPACK_IFW_REPOGEN_EXECUTABLE";
+ const std::string FrameworkVersionOpt = "CPACK_IFW_FRAMEWORK_VERSION";
+
+ if(!this->IsSet(BinCreatorOpt) ||
+ !this->IsSet(RepoGenOpt) ||
+ !this->IsSet(FrameworkVersionOpt))
+ {
+ this->ReadListFile("CPackIFW.cmake");
+ }
+
+ // Look 'binarycreator' executable (needs)
+
+ const char *BinCreatorStr = this->GetOption(BinCreatorOpt);
+ if(!BinCreatorStr || cmSystemTools::IsNOTFOUND(BinCreatorStr))
+ {
+ BinCreator = "";
+ }
+ else
+ {
+ BinCreator = BinCreatorStr;
+ }
+
+ if (BinCreator.empty())
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Cannot find QtIFW compiler \"binarycreator\": "
+ "likely it is not installed, or not in your PATH"
+ << std::endl);
+ return 0;
+ }
+
+ // Look 'repogen' executable (optional)
+
+ const char *RepoGenStr = this->GetOption(RepoGenOpt);
+ if(!RepoGenStr || cmSystemTools::IsNOTFOUND(RepoGenStr))
+ {
+ RepoGen = "";
+ }
+ else
+ {
+ RepoGen = RepoGenStr;
+ }
+
+ // Framework version
+ if(const char* FrameworkVersionSrt =
+ this->GetOption(FrameworkVersionOpt))
+ {
+ FrameworkVersion = FrameworkVersionSrt;
+ }
+ else
+ {
+ FrameworkVersion = "1.9.9";
+ }
+
+ // Variables that Change Behavior
+
+ // Resolve duplicate names
+ ResolveDuplicateNames = this->IsOn("CPACK_IFW_RESOLVE_DUPLICATE_NAMES");
+
+ // Additional packages dirs
+ PkgsDirsVector.clear();
+ if(const char* dirs = this->GetOption("CPACK_IFW_PACKAGES_DIRECTORIES"))
+ {
+ cmSystemTools::ExpandListArgument(dirs,
+ PkgsDirsVector);
+ }
+
+ // Installer
+ Installer.Generator = this;
+ Installer.ConfigureFromOptions();
+
+ if (const char* ifwDownloadAll =
+ this->GetOption("CPACK_IFW_DOWNLOAD_ALL"))
+ {
+ OnlineOnly = cmSystemTools::IsOn(ifwDownloadAll);
+ }
+ else if (const char* cpackDownloadAll =
+ this->GetOption("CPACK_DOWNLOAD_ALL"))
+ {
+ OnlineOnly = cmSystemTools::IsOn(cpackDownloadAll);
+ }
+ else
+ {
+ OnlineOnly = false;
+ }
+
+ if (!Installer.Repositories.empty() && RepoGen.empty()) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Cannot find QtIFW repository generator \"repogen\": "
+ "likely it is not installed, or not in your PATH"
+ << std::endl);
+ return 0;
+ }
+
+ // Executable suffix
+ if(const char *optExeSuffix = this->GetOption("CMAKE_EXECUTABLE_SUFFIX"))
+ {
+ ExecutableSuffix = optExeSuffix;
+ if(ExecutableSuffix.empty())
+ {
+ std::string sysName(this->GetOption("CMAKE_SYSTEM_NAME"));
+ if(sysName == "Linux")
+ {
+ ExecutableSuffix = ".run";
+ }
+ }
+ }
+ else
+ {
+ ExecutableSuffix = cmCPackGenerator::GetOutputExtension();
+ }
+
+ return this->Superclass::InitializeInternal();
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmCPackIFWGenerator::GetComponentInstallDirNameSuffix(
+ const std::string& componentName)
+{
+ const std::string prefix = "packages/";
+ const std::string suffix = "/data";
+
+ if (componentPackageMethod == ONE_PACKAGE) {
+ return std::string(prefix + GetRootPackageName() + suffix);
+ }
+
+ return prefix
+ + GetComponentPackageName(&Components[componentName])
+ + suffix;
+}
+
+//----------------------------------------------------------------------------
+cmCPackComponent*
+cmCPackIFWGenerator::GetComponent(const std::string &projectName,
+ const std::string &componentName)
+{
+ ComponentsMap::iterator cit = Components.find(componentName);
+ if ( cit != Components.end() ) return &(cit->second);
+
+ cmCPackComponent* component
+ = cmCPackGenerator::GetComponent(projectName, componentName);
+ if(!component) return component;
+
+ std::string name = GetComponentPackageName(component);
+ PackagesMap::iterator pit = Packages.find(name);
+ if(pit != Packages.end()) return component;
+
+ cmCPackIFWPackage *package = &Packages[name];
+ package->Name = name;
+ package->Generator = this;
+ if(package->ConfigureFromComponent(component))
+ {
+ package->Installer = &Installer;
+ Installer.Packages.insert(
+ std::pair<std::string, cmCPackIFWPackage*>(
+ name, package));
+ ComponentPackages.insert(
+ std::pair<cmCPackComponent*, cmCPackIFWPackage*>(
+ component, package));
+ if(component->IsDownloaded)
+ {
+ DownloadedPackages.insert(package);
+ }
+ else
+ {
+ BinaryPackages.insert(package);
+ }
+ }
+ else
+ {
+ Packages.erase(name);
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Cannot configure package \"" << name <<
+ "\" for component \"" << component->Name << "\""
+ << std::endl);
+ }
+
+ return component;
+}
+
+//----------------------------------------------------------------------------
+cmCPackComponentGroup*
+cmCPackIFWGenerator::GetComponentGroup(const std::string &projectName,
+ const std::string &groupName)
+{
+ cmCPackComponentGroup* group
+ = cmCPackGenerator::GetComponentGroup(projectName, groupName);
+ if(!group) return group;
+
+ std::string name = GetGroupPackageName(group);
+ PackagesMap::iterator pit = Packages.find(name);
+ if(pit != Packages.end()) return group;
+
+ cmCPackIFWPackage *package = &Packages[name];
+ package->Name = name;
+ package->Generator = this;
+ if(package->ConfigureFromGroup(group))
+ {
+ package->Installer = &Installer;
+ Installer.Packages.insert(
+ std::pair<std::string, cmCPackIFWPackage*>(
+ name, package));
+ GroupPackages.insert(
+ std::pair<cmCPackComponentGroup*, cmCPackIFWPackage*>(
+ group, package));
+ BinaryPackages.insert(package);
+ }
+ else
+ {
+ Packages.erase(name);
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Cannot configure package \"" << name <<
+ "\" for component group \"" << group->Name << "\""
+ << std::endl);
+ }
+ return group;
+}
+
+//----------------------------------------------------------------------------
+enum cmCPackGenerator::CPackSetDestdirSupport
+cmCPackIFWGenerator::SupportsSetDestdir() const
+{
+ return cmCPackGenerator::SETDESTDIR_SHOULD_NOT_BE_USED;
+}
+
+//----------------------------------------------------------------------------
+bool cmCPackIFWGenerator::SupportsAbsoluteDestination() const
+{
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmCPackIFWGenerator::SupportsComponentInstallation() const
+{
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmCPackIFWGenerator::IsOnePackage() const
+{
+ return componentPackageMethod == ONE_PACKAGE;
+}
+
+//----------------------------------------------------------------------------
+std::string cmCPackIFWGenerator::GetRootPackageName()
+{
+ // Default value
+ std::string name = "root";
+ if (const char* optIFW_PACKAGE_GROUP =
+ this->GetOption("CPACK_IFW_PACKAGE_GROUP"))
+ {
+ // Configure from root group
+ cmCPackIFWPackage package;
+ package.Generator = this;
+ package.ConfigureFromGroup(optIFW_PACKAGE_GROUP);
+ name = package.Name;
+ }
+ else if (const char* optIFW_PACKAGE_NAME =
+ this->GetOption("CPACK_IFW_PACKAGE_NAME"))
+ {
+ // Configure from root package name
+ name = optIFW_PACKAGE_NAME;
+ }
+ else if (const char* optPACKAGE_NAME =
+ this->GetOption("CPACK_PACKAGE_NAME"))
+ {
+ // Configure from package name
+ name = optPACKAGE_NAME;
+ }
+ return name;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmCPackIFWGenerator::GetGroupPackageName(cmCPackComponentGroup *group) const
+{
+ std::string name;
+ if (!group) return name;
+ if (cmCPackIFWPackage* package = GetGroupPackage(group))
+ {
+ return package->Name;
+ }
+ const char* option = GetOption(
+ "CPACK_IFW_COMPONENT_GROUP_"
+ + cmsys::SystemTools::UpperCase(group->Name)
+ + "_NAME");
+ name = option ? option : group->Name;
+ if(group->ParentGroup)
+ {
+ cmCPackIFWPackage* package = GetGroupPackage(group->ParentGroup);
+ bool dot = !ResolveDuplicateNames;
+ if(dot && name.substr(0, package->Name.size()) == package->Name)
+ {
+ dot = false;
+ }
+ if(dot)
+ {
+ name = package->Name + "." + name;
+ }
+ }
+ return name;
+}
+
+//----------------------------------------------------------------------------
+std::string cmCPackIFWGenerator::GetComponentPackageName(
+ cmCPackComponent *component) const
+{
+ std::string name;
+ if (!component) return name;
+ if (cmCPackIFWPackage* package = GetComponentPackage(component))
+ {
+ return package->Name;
+ }
+ std::string prefix = "CPACK_IFW_COMPONENT_"
+ + cmsys::SystemTools::UpperCase(component->Name)
+ + "_";
+ const char* option = GetOption(prefix + "NAME");
+ name = option ? option : component->Name;
+ if(component->Group)
+ {
+ cmCPackIFWPackage* package = GetGroupPackage(component->Group);
+ if((componentPackageMethod == ONE_PACKAGE_PER_GROUP)
+ || IsOn(prefix + "COMMON"))
+ {
+ return package->Name;
+ }
+ bool dot = !ResolveDuplicateNames;
+ if(dot && name.substr(0, package->Name.size()) == package->Name)
+ {
+ dot = false;
+ }
+ if(dot)
+ {
+ name = package->Name + "." + name;
+ }
+ }
+ return name;
+}
+
+//----------------------------------------------------------------------------
+cmCPackIFWPackage* cmCPackIFWGenerator::GetGroupPackage(
+ cmCPackComponentGroup *group) const
+{
+ std::map<cmCPackComponentGroup*, cmCPackIFWPackage*>::const_iterator pit
+ = GroupPackages.find(group);
+ return pit != GroupPackages.end() ? pit->second : 0;
+}
+
+//----------------------------------------------------------------------------
+cmCPackIFWPackage* cmCPackIFWGenerator::GetComponentPackage(
+ cmCPackComponent *component) const
+{
+ std::map<cmCPackComponent*, cmCPackIFWPackage*>::const_iterator pit
+ = ComponentPackages.find(component);
+ return pit != ComponentPackages.end() ? pit->second : 0;
+}
+
+//----------------------------------------------------------------------------
+void cmCPackIFWGenerator::WriteGeneratedByToStrim(cmGeneratedFileStream &xout)
+{
+ xout << "<!-- Generated by CPack " << CMake_VERSION << " IFW generator "
+ << "for QtIFW ";
+ if(IsVersionLess("2.0"))
+ {
+ xout << "less 2.0";
+ }
+ else
+ {
+ xout << FrameworkVersion;
+ }
+ xout << " tools at " << cmTimestamp().CurrentTime("", true) << " -->"
+ << std::endl;
+}
diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.h b/Source/CPack/IFW/cmCPackIFWGenerator.h
new file mode 100644
index 000000000..32468613d
--- /dev/null
+++ b/Source/CPack/IFW/cmCPackIFWGenerator.h
@@ -0,0 +1,155 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmCPackIFWGenerator_h
+#define cmCPackIFWGenerator_h
+
+#include <cmGeneratedFileStream.h>
+#include <CPack/cmCPackGenerator.h>
+
+#include "cmCPackIFWPackage.h"
+#include "cmCPackIFWInstaller.h"
+
+/** \class cmCPackIFWGenerator
+ * \brief A generator for Qt Installer Framework tools
+ *
+ * http://qt-project.org/doc/qtinstallerframework/index.html
+ */
+class cmCPackIFWGenerator : public cmCPackGenerator
+{
+public:
+ cmCPackTypeMacro(cmCPackIFWGenerator, cmCPackGenerator);
+
+ typedef std::map<std::string, cmCPackIFWPackage> PackagesMap;
+ typedef std::map<std::string, cmCPackComponent> ComponentsMap;
+ typedef std::map<std::string, cmCPackComponentGroup> ComponentGoupsMap;
+ typedef std::map<std::string, cmCPackIFWPackage::DependenceStruct>
+ DependenceMap;
+
+ /**
+ * Construct IFW generator
+ */
+ cmCPackIFWGenerator();
+
+ /**
+ * Destruct IFW generator
+ */
+ virtual ~cmCPackIFWGenerator();
+
+ /**
+ * Compare \a version with QtIFW framework version
+ */
+ bool IsVersionLess(const char *version);
+
+ /**
+ * Compare \a version with QtIFW framework version
+ */
+ bool IsVersionGreater(const char *version);
+
+ /**
+ * Compare \a version with QtIFW framework version
+ */
+ bool IsVersionEqual(const char *version);
+
+protected: // cmCPackGenerator reimplementation
+
+ /**
+ * @brief Initialize generator
+ * @return 0 on failure
+ */
+ virtual int InitializeInternal();
+ virtual int PackageFiles();
+ virtual const char* GetPackagingInstallPrefix();
+
+ /**
+ * @brief Extension of binary installer
+ * @return Executable suffix or value from default implementation
+ */
+ virtual const char* GetOutputExtension();
+
+ virtual std::string GetComponentInstallDirNameSuffix(
+ const std::string& componentName);
+
+ /**
+ * @brief Get Component
+ * @param projectName Project name
+ * @param componentName Component name
+ *
+ * This method calls the base implementation.
+ *
+ * @return Pointer to component
+ */
+ virtual cmCPackComponent* GetComponent(
+ const std::string& projectName,
+ const std::string& componentName);
+
+ /**
+ * @brief Get group of component
+ * @param projectName Project name
+ * @param groupName Component group name
+ *
+ * This method calls the base implementation.
+ *
+ * @return Pointer to component group
+ */
+ virtual cmCPackComponentGroup* GetComponentGroup(
+ const std::string& projectName,
+ const std::string& groupName);
+
+ enum cmCPackGenerator::CPackSetDestdirSupport SupportsSetDestdir() const;
+ virtual bool SupportsAbsoluteDestination() const;
+ virtual bool SupportsComponentInstallation() const;
+
+protected: // Methods
+
+ bool IsOnePackage() const;
+
+ std::string GetRootPackageName();
+
+ std::string GetGroupPackageName(cmCPackComponentGroup *group) const;
+ std::string GetComponentPackageName(cmCPackComponent *component) const;
+
+ cmCPackIFWPackage* GetGroupPackage(cmCPackComponentGroup *group) const;
+ cmCPackIFWPackage* GetComponentPackage(cmCPackComponent *component) const;
+
+ void WriteGeneratedByToStrim(cmGeneratedFileStream& xout);
+
+protected: // Data
+
+ friend class cmCPackIFWPackage;
+ friend class cmCPackIFWInstaller;
+
+ // Installer
+ cmCPackIFWInstaller Installer;
+ // Collection of packages
+ PackagesMap Packages;
+ // Collection of binary packages
+ std::set<cmCPackIFWPackage*> BinaryPackages;
+ // Collection of downloaded packages
+ std::set<cmCPackIFWPackage*> DownloadedPackages;
+ // Dependent packages
+ DependenceMap DependentPackages;
+ std::map<cmCPackComponent*, cmCPackIFWPackage*> ComponentPackages;
+ std::map<cmCPackComponentGroup*, cmCPackIFWPackage*> GroupPackages;
+
+private:
+ std::string RepoGen;
+ std::string BinCreator;
+ std::string FrameworkVersion;
+ std::string ExecutableSuffix;
+
+ bool OnlineOnly;
+ bool ResolveDuplicateNames;
+ std::vector<std::string> PkgsDirsVector;
+};
+
+#endif
diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.cxx b/Source/CPack/IFW/cmCPackIFWInstaller.cxx
new file mode 100644
index 000000000..8c77a2c24
--- /dev/null
+++ b/Source/CPack/IFW/cmCPackIFWInstaller.cxx
@@ -0,0 +1,541 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmCPackIFWInstaller.h"
+
+#include "cmCPackIFWGenerator.h"
+
+#include <CPack/cmCPackLog.h>
+
+#include <cmGeneratedFileStream.h>
+#include <cmXMLSafe.h>
+
+#ifdef cmCPackLogger
+# undef cmCPackLogger
+#endif
+#define cmCPackLogger(logType, msg) \
+ do { \
+ std::ostringstream cmCPackLog_msg; \
+ cmCPackLog_msg << msg; \
+ if(Generator) { \
+ Generator->Logger->Log(logType, __FILE__, __LINE__, \
+ cmCPackLog_msg.str().c_str()); \
+ } \
+ } while ( 0 )
+
+//----------------------------------------------------------------------------
+cmCPackIFWInstaller::cmCPackIFWInstaller() :
+ Generator(0)
+{
+}
+
+//----------------------------------------------------------------------------
+const char *cmCPackIFWInstaller::GetOption(const std::string &op) const
+{
+ return Generator ? Generator->GetOption(op) : 0;
+}
+
+//----------------------------------------------------------------------------
+bool cmCPackIFWInstaller::IsOn(const std::string &op) const
+{
+ return Generator ? Generator->IsOn(op) : false;
+}
+
+//----------------------------------------------------------------------------
+bool cmCPackIFWInstaller::IsVersionLess(const char *version)
+{
+ return Generator ? Generator->IsVersionLess(version) : false;
+}
+
+//----------------------------------------------------------------------------
+bool cmCPackIFWInstaller::IsVersionGreater(const char *version)
+{
+ return Generator ? Generator->IsVersionGreater(version) : false;
+}
+
+//----------------------------------------------------------------------------
+bool cmCPackIFWInstaller::IsVersionEqual(const char *version)
+{
+ return Generator ? Generator->IsVersionEqual(version) : false;
+}
+
+
+//----------------------------------------------------------------------------
+void cmCPackIFWInstaller::ConfigureFromOptions()
+{
+ // Name;
+ if (const char* optIFW_PACKAGE_NAME =
+ this->GetOption("CPACK_IFW_PACKAGE_NAME"))
+ {
+ Name = optIFW_PACKAGE_NAME;
+ }
+ else if (const char* optPACKAGE_NAME =
+ this->GetOption("CPACK_PACKAGE_NAME"))
+ {
+ Name = optPACKAGE_NAME;
+ }
+ else
+ {
+ Name = "Your package";
+ }
+
+ // Title;
+ if (const char* optIFW_PACKAGE_TITLE =
+ GetOption("CPACK_IFW_PACKAGE_TITLE"))
+ {
+ Title = optIFW_PACKAGE_TITLE;
+ }
+ else if (const char* optPACKAGE_DESCRIPTION_SUMMARY =
+ GetOption("CPACK_PACKAGE_DESCRIPTION_SUMMARY"))
+ {
+ Title = optPACKAGE_DESCRIPTION_SUMMARY;
+ }
+ else
+ {
+ Title = "Your package description";
+ }
+
+ // Version;
+ if (const char* option = GetOption("CPACK_PACKAGE_VERSION"))
+ {
+ Version = option;
+ }
+ else
+ {
+ Version = "1.0.0";
+ }
+
+ // Publisher
+ if(const char* optIFW_PACKAGE_PUBLISHER =
+ GetOption("CPACK_IFW_PACKAGE_PUBLISHER"))
+ {
+ Publisher = optIFW_PACKAGE_PUBLISHER;
+ }
+ else if(const char* optPACKAGE_VENDOR = GetOption("CPACK_PACKAGE_VENDOR"))
+ {
+ Publisher = optPACKAGE_VENDOR;
+ }
+
+ // ProductUrl
+ if(const char* option = GetOption("CPACK_IFW_PRODUCT_URL"))
+ {
+ ProductUrl = option;
+ }
+
+ // ApplicationIcon
+ if(const char* option = GetOption("CPACK_IFW_PACKAGE_ICON"))
+ {
+ if(cmSystemTools::FileExists(option))
+ {
+ InstallerApplicationIcon = option;
+ }
+ else
+ {
+ // TODO: implement warning
+ }
+ }
+
+ // WindowIcon
+ if(const char* option = GetOption("CPACK_IFW_PACKAGE_WINDOW_ICON"))
+ {
+ if(cmSystemTools::FileExists(option))
+ {
+ InstallerWindowIcon = option;
+ }
+ else
+ {
+ // TODO: implement warning
+ }
+ }
+
+ // Logo
+ if(const char* option = GetOption("CPACK_IFW_PACKAGE_LOGO"))
+ {
+ if(cmSystemTools::FileExists(option))
+ {
+ Logo = option;
+ }
+ else
+ {
+ // TODO: implement warning
+ }
+ }
+
+ // Start menu
+ if (const char* optIFW_START_MENU_DIR =
+ this->GetOption("CPACK_IFW_PACKAGE_START_MENU_DIRECTORY"))
+ {
+ StartMenuDir = optIFW_START_MENU_DIR;
+ }
+ else
+ {
+ StartMenuDir = Name;
+ }
+
+ // Default target directory for installation
+ if (const char* optIFW_TARGET_DIRECTORY =
+ GetOption("CPACK_IFW_TARGET_DIRECTORY"))
+ {
+ TargetDir = optIFW_TARGET_DIRECTORY;
+ }
+ else if (const char *optPACKAGE_INSTALL_DIRECTORY =
+ GetOption("CPACK_PACKAGE_INSTALL_DIRECTORY"))
+ {
+ TargetDir = "@ApplicationsDir@/";
+ TargetDir += optPACKAGE_INSTALL_DIRECTORY;
+ }
+ else
+ {
+ TargetDir = "@RootDir@/usr/local";
+ }
+
+ // Default target directory for installation with administrator rights
+ if (const char* option = GetOption("CPACK_IFW_ADMIN_TARGET_DIRECTORY"))
+ {
+ AdminTargetDir = option;
+ }
+
+ // Repositories
+ Repositories.clear();
+ RepositoryStruct Repo;
+ if(const char *site = this->GetOption("CPACK_DOWNLOAD_SITE"))
+ {
+ Repo.Url = site;
+ Repositories.push_back(Repo);
+ }
+ if(const char *RepoAllStr = this->GetOption("CPACK_IFW_REPOSITORIES_ALL"))
+ {
+ std::vector<std::string> RepoAllVector;
+ cmSystemTools::ExpandListArgument(RepoAllStr,
+ RepoAllVector);
+ for(std::vector<std::string>::iterator
+ rit = RepoAllVector.begin(); rit != RepoAllVector.end(); ++rit)
+ {
+ std::string prefix = "CPACK_IFW_REPOSITORY_"
+ + cmsys::SystemTools::UpperCase(*rit)
+ + "_";
+ // Url
+ if (const char* url = GetOption(prefix + "URL"))
+ {
+ Repo.Url = url;
+ }
+ else
+ {
+ Repo.Url = "";
+ }
+ // Enabled
+ if (IsOn(prefix + "DISABLED"))
+ {
+ Repo.Enabled = "0";
+ }
+ else
+ {
+ Repo.Enabled = "";
+ }
+ // Username
+ if (const char* username = GetOption(prefix + "USERNAME"))
+ {
+ Repo.Username = username;
+ }
+ else
+ {
+ Repo.Username = "";
+ }
+ // Password
+ if (const char* password = GetOption(prefix + "PASSWORD"))
+ {
+ Repo.Password = password;
+ }
+ else
+ {
+ Repo.Password = "";
+ }
+ // DisplayName
+ if (const char* displayName = GetOption(prefix + "DISPLAY_NAME"))
+ {
+ Repo.DisplayName = displayName;
+ }
+ else
+ {
+ Repo.DisplayName = "";
+ }
+
+ if(!Repo.Url.empty())
+ {
+ Repositories.push_back(Repo);
+ }
+ }
+ }
+
+ // Maintenance tool
+ if(const char* optIFW_MAINTENANCE_TOOL =
+ this->GetOption("CPACK_IFW_PACKAGE_MAINTENANCE_TOOL_NAME"))
+ {
+ MaintenanceToolName = optIFW_MAINTENANCE_TOOL;
+ }
+
+ // Maintenance tool ini file
+ if(const char* optIFW_MAINTENANCE_TOOL_INI =
+ this->GetOption("CPACK_IFW_PACKAGE_MAINTENANCE_TOOL_INI_FILE"))
+ {
+ MaintenanceToolIniFile = optIFW_MAINTENANCE_TOOL_INI;
+ }
+
+ // Allow non-ASCII characters
+ if(this->GetOption("CPACK_IFW_PACKAGE_ALLOW_NON_ASCII_CHARACTERS"))
+ {
+ if(IsOn("CPACK_IFW_PACKAGE_ALLOW_NON_ASCII_CHARACTERS"))
+ {
+ AllowNonAsciiCharacters = "true";
+ }
+ else
+ {
+ AllowNonAsciiCharacters = "false";
+ }
+ }
+
+ // Space in path
+ if(this->GetOption("CPACK_IFW_PACKAGE_ALLOW_SPACE_IN_PATH"))
+ {
+ if(IsOn("CPACK_IFW_PACKAGE_ALLOW_SPACE_IN_PATH"))
+ {
+ AllowSpaceInPath = "true";
+ }
+ else
+ {
+ AllowSpaceInPath = "false";
+ }
+ }
+
+ // Control script
+ if(const char* optIFW_CONTROL_SCRIPT =
+ this->GetOption("CPACK_IFW_PACKAGE_CONTROL_SCRIPT"))
+ {
+ ControlScript = optIFW_CONTROL_SCRIPT;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmCPackIFWInstaller::GenerateInstallerFile()
+{
+ // Lazy directory initialization
+ if(Directory.empty() && Generator)
+ {
+ Directory = Generator->toplevel;
+ }
+
+ // Output stream
+ cmGeneratedFileStream xout((Directory + "/config/config.xml").data());
+
+ xout << "<?xml version=\"1.0\"?>" << std::endl;
+
+ WriteGeneratedByToStrim(xout);
+
+ xout << "<Installer>" << std::endl;
+
+ xout << " <Name>" << cmXMLSafe(Name).str() << "</Name>" << std::endl;
+
+ xout << " <Version>" << Version << "</Version>" << std::endl;
+
+ xout << " <Title>" << cmXMLSafe(Title).str() << "</Title>"
+ << std::endl;
+
+ if(!Publisher.empty())
+ {
+ xout << " <Publisher>" << cmXMLSafe(Publisher).str()
+ << "</Publisher>" << std::endl;
+ }
+
+ if(!ProductUrl.empty())
+ {
+ xout << " <ProductUrl>" << ProductUrl << "</ProductUrl>" << std::endl;
+ }
+
+ // ApplicationIcon
+ if(!InstallerApplicationIcon.empty())
+ {
+ std::string name =
+ cmSystemTools::GetFilenameName(InstallerApplicationIcon);
+ std::string path = Directory + "/config/" + name;
+ name = cmSystemTools::GetFilenameWithoutExtension(name);
+ cmsys::SystemTools::CopyFileIfDifferent(
+ InstallerApplicationIcon.data(), path.data());
+ xout << " <InstallerApplicationIcon>" << name
+ << "</InstallerApplicationIcon>" << std::endl;
+ }
+
+ // WindowIcon
+ if(!InstallerWindowIcon.empty())
+ {
+ std::string name = cmSystemTools::GetFilenameName(InstallerWindowIcon);
+ std::string path = Directory + "/config/" + name;
+ cmsys::SystemTools::CopyFileIfDifferent(
+ InstallerWindowIcon.data(), path.data());
+ xout << " <InstallerWindowIcon>" << name
+ << "</InstallerWindowIcon>" << std::endl;
+ }
+
+ // Logo
+ if(!Logo.empty())
+ {
+ std::string name = cmSystemTools::GetFilenameName(Logo);
+ std::string path = Directory + "/config/" + name;
+ cmsys::SystemTools::CopyFileIfDifferent(Logo.data(), path.data());
+ xout << " <Logo>" << name << "</Logo>" << std::endl;
+ }
+
+ // Start menu
+ if(!IsVersionLess("2.0"))
+ {
+ xout << " <StartMenuDir>" << StartMenuDir
+ << "</StartMenuDir>" << std::endl;
+ }
+
+ // Target dir
+ if(!TargetDir.empty())
+ {
+ xout << " <TargetDir>" << TargetDir << "</TargetDir>" << std::endl;
+ }
+
+ // Admin target dir
+ if(!AdminTargetDir.empty())
+ {
+ xout << " <AdminTargetDir>" << AdminTargetDir
+ << "</AdminTargetDir>" << std::endl;
+ }
+
+ // Remote repositories
+ if (!Repositories.empty())
+ {
+ xout << " <RemoteRepositories>" << std::endl;
+ for(std::vector<RepositoryStruct>::iterator
+ rit = Repositories.begin(); rit != Repositories.end(); ++rit)
+ {
+ xout << " <Repository>" << std::endl;
+ // Url
+ xout << " <Url>" << rit->Url
+ << "</Url>" << std::endl;
+ // Enabled
+ if(!rit->Enabled.empty())
+ {
+ xout << " <Enabled>" << rit->Enabled
+ << "</Enabled>" << std::endl;
+ }
+ // Username
+ if(!rit->Username.empty())
+ {
+ xout << " <Username>" << rit->Username
+ << "</Username>" << std::endl;
+ }
+ // Password
+ if(!rit->Password.empty())
+ {
+ xout << " <Password>" << rit->Password
+ << "</Password>" << std::endl;
+ }
+ // DisplayName
+ if(!rit->DisplayName.empty())
+ {
+ xout << " <DisplayName>" << rit->DisplayName
+ << "</DisplayName>" << std::endl;
+ }
+ xout << " </Repository>" << std::endl;
+ }
+ xout << " </RemoteRepositories>" << std::endl;
+ }
+
+ // Maintenance tool
+ if(!IsVersionLess("2.0") && !MaintenanceToolName.empty())
+ {
+ xout << " <MaintenanceToolName>" << MaintenanceToolName
+ << "</MaintenanceToolName>" << std::endl;
+ }
+
+ // Maintenance tool ini file
+ if(!IsVersionLess("2.0") && !MaintenanceToolIniFile.empty())
+ {
+ xout << " <MaintenanceToolIniFile>" << MaintenanceToolIniFile
+ << "</MaintenanceToolIniFile>" << std::endl;
+ }
+
+ // Different allows
+ if(IsVersionLess("2.0"))
+ {
+ // CPack IFW default policy
+ xout << " <!-- CPack IFW default policy for QtIFW less 2.0 -->"
+ << std::endl;
+ xout << " <AllowNonAsciiCharacters>true</AllowNonAsciiCharacters>"
+ << std::endl;
+ xout << " <AllowSpaceInPath>true</AllowSpaceInPath>" << std::endl;
+ }
+ else
+ {
+ if(!AllowNonAsciiCharacters.empty())
+ {
+ xout << " <AllowNonAsciiCharacters>" << AllowNonAsciiCharacters
+ << "</AllowNonAsciiCharacters>" << std::endl;
+ }
+ if(!AllowSpaceInPath.empty())
+ {
+ xout << " <AllowAllowSpaceInPath>" << AllowSpaceInPath
+ << "</AllowSpaceInPath>" << std::endl;
+ }
+ }
+
+ // Control script (copy to config dir)
+ if(!IsVersionLess("2.0") && !ControlScript.empty())
+ {
+ std::string name = cmSystemTools::GetFilenameName(ControlScript);
+ std::string path = Directory + "/config/" + name;
+ cmsys::SystemTools::CopyFileIfDifferent(ControlScript.data(), path.data());
+ xout << " <ControlScript>" << name << "</ControlScript>" << std::endl;
+ }
+
+ xout << "</Installer>" << std::endl;
+}
+
+//----------------------------------------------------------------------------
+void cmCPackIFWInstaller::GeneratePackageFiles()
+{
+ if (Packages.empty() || Generator->IsOnePackage())
+ {
+ // Generate default package
+ cmCPackIFWPackage package;
+ package.Generator = Generator;
+ package.Installer = this;
+ // Check package group
+ if (const char* option = GetOption("CPACK_IFW_PACKAGE_GROUP"))
+ {
+ package.ConfigureFromGroup(option);
+ package.ForcedInstallation = "true";
+ }
+ else
+ {
+ package.ConfigureFromOptions();
+ }
+ package.GeneratePackageFile();
+ return;
+ }
+
+ // Generate packages meta information
+ for(PackagesMap::iterator pit = Packages.begin();
+ pit != Packages.end(); ++pit)
+ {
+ cmCPackIFWPackage* package = pit->second;
+ package->GeneratePackageFile();
+ }
+}
+
+void cmCPackIFWInstaller::WriteGeneratedByToStrim(cmGeneratedFileStream &xout)
+{
+ if(Generator) Generator->WriteGeneratedByToStrim(xout);
+}
diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.h b/Source/CPack/IFW/cmCPackIFWInstaller.h
new file mode 100644
index 000000000..4cba5b29e
--- /dev/null
+++ b/Source/CPack/IFW/cmCPackIFWInstaller.h
@@ -0,0 +1,121 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmCPackIFWInstaller_h
+#define cmCPackIFWInstaller_h
+
+#include <cmGeneratedFileStream.h>
+#include <cmStandardIncludes.h>
+
+class cmCPackIFWPackage;
+class cmCPackIFWGenerator;
+
+/** \class cmCPackIFWInstaller
+ * \brief A binary installer to be created CPack IFW generator
+ */
+class cmCPackIFWInstaller
+{
+public: // Types
+
+ typedef std::map<std::string, cmCPackIFWPackage*> PackagesMap;
+
+ struct RepositoryStruct
+ {
+ std::string Url;
+ std::string Enabled;
+ std::string Username;
+ std::string Password;
+ std::string DisplayName;
+ };
+
+public: // Constructor
+
+ /**
+ * Construct installer
+ */
+ cmCPackIFWInstaller();
+
+public: // Configuration
+
+ /// Name of the product being installed
+ std::string Name;
+
+ /// Version number of the product being installed
+ std::string Version;
+
+ /// Name of the installer as displayed on the title bar
+ std::string Title;
+
+ /// Publisher of the software (as shown in the Windows Control Panel)
+ std::string Publisher;
+
+ /// URL to a page that contains product information on your web site
+ std::string ProductUrl;
+
+ /// Filename for a custom installer icon
+ std::string InstallerApplicationIcon;
+
+ /// Filename for a custom window icon
+ std::string InstallerWindowIcon;
+
+ /// Filename for a logo
+ std::string Logo;
+
+ /// Name of the default program group in the Windows Start menu
+ std::string StartMenuDir;
+
+ /// Default target directory for installation
+ std::string TargetDir;
+
+ /// Default target directory for installation with administrator rights
+ std::string AdminTargetDir;
+
+ /// Filename of the generated maintenance tool
+ std::string MaintenanceToolName;
+
+ /// Filename for the configuration of the generated maintenance tool
+ std::string MaintenanceToolIniFile;
+
+ /// Set to true if the installation path can contain non-ASCII characters
+ std::string AllowNonAsciiCharacters;
+
+ /// Set to false if the installation path cannot contain space characters
+ std::string AllowSpaceInPath;
+
+ /// Filename for a custom installer control script
+ std::string ControlScript;
+
+public: // Internal implementation
+
+ const char* GetOption(const std::string& op) const;
+ bool IsOn(const std::string& op) const;
+
+ bool IsVersionLess(const char *version);
+ bool IsVersionGreater(const char *version);
+ bool IsVersionEqual(const char *version);
+
+ void ConfigureFromOptions();
+
+ void GenerateInstallerFile();
+
+ void GeneratePackageFiles();
+
+ cmCPackIFWGenerator* Generator;
+ PackagesMap Packages;
+ std::vector<RepositoryStruct> Repositories;
+ std::string Directory;
+
+protected:
+ void WriteGeneratedByToStrim(cmGeneratedFileStream& xout);
+};
+
+#endif // cmCPackIFWInstaller_h
diff --git a/Source/CPack/IFW/cmCPackIFWPackage.cxx b/Source/CPack/IFW/cmCPackIFWPackage.cxx
new file mode 100644
index 000000000..5474ad1b0
--- /dev/null
+++ b/Source/CPack/IFW/cmCPackIFWPackage.cxx
@@ -0,0 +1,566 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmCPackIFWPackage.h"
+
+#include "cmCPackIFWGenerator.h"
+
+#include <CPack/cmCPackLog.h>
+
+#include <cmGeneratedFileStream.h>
+#include <cmTimestamp.h>
+
+//----------------------------------------------------------------- Logger ---
+#ifdef cmCPackLogger
+# undef cmCPackLogger
+#endif
+#define cmCPackLogger(logType, msg) \
+ do { \
+ std::ostringstream cmCPackLog_msg; \
+ cmCPackLog_msg << msg; \
+ if(Generator) { \
+ Generator->Logger->Log(logType, __FILE__, __LINE__, \
+ cmCPackLog_msg.str().c_str()); \
+ } \
+ } while ( 0 )
+
+//---------------------------------------------------------- CompareStruct ---
+cmCPackIFWPackage::CompareStruct::CompareStruct() :
+ Type(CompareNone)
+{
+}
+
+//------------------------------------------------------- DependenceStruct ---
+cmCPackIFWPackage::DependenceStruct::DependenceStruct()
+{
+}
+
+//----------------------------------------------------------------------------
+cmCPackIFWPackage::DependenceStruct::DependenceStruct(
+ const std::string &dependence)
+{
+ // Search compare section
+ size_t pos = std::string::npos;
+ if((pos = dependence.find("<=")) != std::string::npos)
+ {
+ Compare.Type = CompareLessOrEqual;
+ Compare.Value = dependence.substr(pos + 2);
+ }
+ else if((pos = dependence.find(">=")) != std::string::npos)
+ {
+ Compare.Type = CompareGreaterOrEqual;
+ Compare.Value = dependence.substr(pos + 2);
+ }
+ else if((pos = dependence.find("<")) != std::string::npos)
+ {
+ Compare.Type = CompareLess;
+ Compare.Value = dependence.substr(pos + 1);
+ }
+ else if((pos = dependence.find("=")) != std::string::npos)
+ {
+ Compare.Type = CompareEqual;
+ Compare.Value = dependence.substr(pos + 1);
+ }
+ else if((pos = dependence.find(">")) != std::string::npos)
+ {
+ Compare.Type = CompareGreater;
+ Compare.Value = dependence.substr(pos + 1);
+ }
+ Name = pos == std::string::npos ? dependence : dependence.substr(0, pos);
+}
+
+//----------------------------------------------------------------------------
+std::string cmCPackIFWPackage::DependenceStruct::NameWithCompare() const
+{
+ if (Compare.Type == CompareNone) return Name;
+
+ std::string result = Name;
+
+ if (Compare.Type == CompareLessOrEqual)
+ {
+ result += "<=";
+ }
+ else if (Compare.Type == CompareGreaterOrEqual)
+ {
+ result += ">=";
+ }
+ else if (Compare.Type == CompareLess)
+ {
+ result += "<";
+ }
+ else if (Compare.Type == CompareEqual)
+ {
+ result += "=";
+ }
+ else if (Compare.Type == CompareGreater)
+ {
+ result += ">";
+ }
+
+ result += Compare.Value;
+
+ return result;
+}
+
+//------------------------------------------------------ cmCPackIFWPackage ---
+cmCPackIFWPackage::cmCPackIFWPackage() :
+ Generator(0),
+ Installer(0)
+{
+}
+
+//----------------------------------------------------------------------------
+const char *cmCPackIFWPackage::GetOption(const std::string &op) const
+{
+ const char *option = Generator ? Generator->GetOption(op) : 0;
+ return option && *option ? option : 0;
+}
+
+//----------------------------------------------------------------------------
+bool cmCPackIFWPackage::IsOn(const std::string &op) const
+{
+ return Generator ? Generator->IsOn(op) : false;
+}
+
+//----------------------------------------------------------------------------
+bool cmCPackIFWPackage::IsVersionLess(const char *version)
+{
+ return Generator ? Generator->IsVersionLess(version) : false;
+}
+
+//----------------------------------------------------------------------------
+bool cmCPackIFWPackage::IsVersionGreater(const char *version)
+{
+ return Generator ? Generator->IsVersionGreater(version) : false;
+}
+
+//----------------------------------------------------------------------------
+bool cmCPackIFWPackage::IsVersionEqual(const char *version)
+{
+ return Generator ? Generator->IsVersionEqual(version) : false;
+}
+
+//----------------------------------------------------------------------------
+std::string cmCPackIFWPackage::GetComponentName(cmCPackComponent *component)
+{
+ if (!component) return "";
+ const char* option = GetOption(
+ "CPACK_IFW_COMPONENT_"
+ + cmsys::SystemTools::UpperCase(component->Name)
+ + "_NAME");
+ return option ? option : component->Name;
+}
+
+//----------------------------------------------------------------------------
+void cmCPackIFWPackage::DefaultConfiguration()
+{
+ DisplayName = "";
+ Description = "";
+ Version = "";
+ ReleaseDate = "";
+ Script = "";
+ Licenses.clear();
+ SortingPriority = "";
+ Default = "";
+ Virtual = "";
+ ForcedInstallation = "";
+}
+
+//----------------------------------------------------------------------------
+// Defaul configuration (all in one package)
+int cmCPackIFWPackage::ConfigureFromOptions()
+{
+ // Restore defaul configuration
+ DefaultConfiguration();
+
+ // Name
+ Name = Generator->GetRootPackageName();
+
+ // Display name
+ if (const char *option = this->GetOption("CPACK_PACKAGE_NAME"))
+ {
+ DisplayName = option;
+ }
+ else
+ {
+ DisplayName = "Your package";
+ }
+
+ // Description
+ if (const char* option =
+ this->GetOption("CPACK_PACKAGE_DESCRIPTION_SUMMARY"))
+ {
+ Description = option;
+ }
+ else
+ {
+ Description = "Your package description";
+ }
+
+ // Version
+ if(const char* option = GetOption("CPACK_PACKAGE_VERSION"))
+ {
+ Version = option;
+ }
+ else
+ {
+ Version = "1.0.0";
+ }
+
+ ForcedInstallation = "true";
+
+ return 1;
+}
+
+//----------------------------------------------------------------------------
+int cmCPackIFWPackage::ConfigureFromComponent(cmCPackComponent *component)
+{
+ if(!component) return 0;
+
+ // Restore defaul configuration
+ DefaultConfiguration();
+
+ std::string prefix = "CPACK_IFW_COMPONENT_"
+ + cmsys::SystemTools::UpperCase(component->Name)
+ + "_";
+
+ // Display name
+ DisplayName = component->DisplayName;
+
+ // Description
+ Description = component->Description;
+
+ // Version
+ if(const char* optVERSION = GetOption(prefix + "VERSION"))
+ {
+ Version = optVERSION;
+ }
+ else if(const char* optPACKAGE_VERSION =
+ GetOption("CPACK_PACKAGE_VERSION"))
+ {
+ Version = optPACKAGE_VERSION;
+ }
+ else
+ {
+ Version = "1.0.0";
+ }
+
+ // Script
+ if (const char* option = GetOption(prefix + "SCRIPT"))
+ {
+ Script = option;
+ }
+
+ // CMake dependencies
+ if (!component->Dependencies.empty())
+ {
+ std::vector<cmCPackComponent*>::iterator dit;
+ for(dit = component->Dependencies.begin();
+ dit != component->Dependencies.end();
+ ++dit)
+ {
+ Dependencies.insert(Generator->ComponentPackages[*dit]);
+ }
+ }
+
+ // QtIFW dependencies
+ if(const char* option = this->GetOption(prefix + "DEPENDS"))
+ {
+ std::vector<std::string> deps;
+ cmSystemTools::ExpandListArgument(option,
+ deps);
+ for(std::vector<std::string>::iterator
+ dit = deps.begin(); dit != deps.end(); ++dit)
+ {
+ DependenceStruct dep(*dit);
+ if (!Generator->Packages.count(dep.Name))
+ {
+ bool hasDep = Generator->DependentPackages.count(dep.Name) > 0;
+ DependenceStruct &depRef =
+ Generator->DependentPackages[dep.Name];
+ if(!hasDep)
+ {
+ depRef = dep;
+ }
+ AlienDependencies.insert(&depRef);
+ }
+ }
+ }
+
+ // Licenses
+ if (const char* option = this->GetOption(prefix + "LICENSES"))
+ {
+ Licenses.clear();
+ cmSystemTools::ExpandListArgument( option, Licenses );
+ if ( Licenses.size() % 2 != 0 )
+ {
+ cmCPackLogger(cmCPackLog::LOG_WARNING, prefix << "LICENSES"
+ << " should contain pairs of <display_name> and <file_path>."
+ << std::endl);
+ Licenses.clear();
+ }
+ }
+
+ // Priority
+ if(const char* option = this->GetOption(prefix + "PRIORITY"))
+ {
+ SortingPriority = option;
+ }
+
+ // Default
+ Default = component->IsDisabledByDefault ? "false" : "true";
+
+ // Virtual
+ Virtual = component->IsHidden ? "true" : "";
+
+ // ForcedInstallation
+ ForcedInstallation = component->IsRequired ? "true" : "false";
+
+ return 1;
+}
+
+//----------------------------------------------------------------------------
+int
+cmCPackIFWPackage::ConfigureFromGroup(cmCPackComponentGroup *group)
+{
+ if(!group) return 0;
+
+ // Restore defaul configuration
+ DefaultConfiguration();
+
+ std::string prefix = "CPACK_IFW_COMPONENT_GROUP_"
+ + cmsys::SystemTools::UpperCase(group->Name)
+ + "_";
+
+ DisplayName = group->DisplayName;
+ Description = group->Description;
+
+ // Version
+ if(const char* optVERSION = GetOption(prefix + "VERSION"))
+ {
+ Version = optVERSION;
+ }
+ else if(const char* optPACKAGE_VERSION =
+ GetOption("CPACK_PACKAGE_VERSION"))
+ {
+ Version = optPACKAGE_VERSION;
+ }
+ else
+ {
+ Version = "1.0.0";
+ }
+
+ // Script
+ if (const char* option = GetOption(prefix + "SCRIPT"))
+ {
+ Script = option;
+ }
+
+ // Licenses
+ if (const char* option = this->GetOption(prefix + "LICENSES"))
+ {
+ Licenses.clear();
+ cmSystemTools::ExpandListArgument( option, Licenses );
+ if ( Licenses.size() % 2 != 0 )
+ {
+ cmCPackLogger(cmCPackLog::LOG_WARNING, prefix << "LICENSES"
+ << " should contain pairs of <display_name> and <file_path>."
+ << std::endl);
+ Licenses.clear();
+ }
+ }
+
+ // Priority
+ if(const char* option = this->GetOption(prefix + "PRIORITY"))
+ {
+ SortingPriority = option;
+ }
+
+ return 1;
+}
+
+//----------------------------------------------------------------------------
+int cmCPackIFWPackage::ConfigureFromGroup(const std::string &groupName)
+{
+ // Group configuration
+
+ cmCPackComponentGroup group;
+ std::string prefix = "CPACK_COMPONENT_GROUP_"
+ + cmsys::SystemTools::UpperCase(groupName)
+ + "_";
+
+ if (const char *option = GetOption(prefix + "DISPLAY_NAME"))
+ {
+ group.DisplayName = option;
+ }
+ else
+ {
+ group.DisplayName = group.Name;
+ }
+
+ if (const char* option = GetOption(prefix + "DESCRIPTION"))
+ {
+ group.Description = option;
+ }
+ group.IsBold = IsOn(prefix + "BOLD_TITLE");
+ group.IsExpandedByDefault = IsOn(prefix + "EXPANDED");
+
+ // Package configuration
+
+ group.Name = groupName;
+
+ if(Generator)
+ {
+ Name = Generator->GetGroupPackageName(&group);
+ }
+ else
+ {
+ Name = group.Name;
+ }
+
+ return ConfigureFromGroup(&group);
+}
+
+//----------------------------------------------------------------------------
+void cmCPackIFWPackage::GeneratePackageFile()
+{
+ // Lazy directory initialization
+ if (Directory.empty())
+ {
+ if(Installer)
+ {
+ Directory = Installer->Directory + "/packages/" + Name;
+ }
+ else if (Generator)
+ {
+ Directory = Generator->toplevel + "/packages/" + Name;
+ }
+ }
+
+ // Output stream
+ cmGeneratedFileStream xout((Directory + "/meta/package.xml").data());
+
+ xout << "<?xml version=\"1.0\"?>" << std::endl;
+
+ WriteGeneratedByToStrim(xout);
+
+ xout << "<Package>" << std::endl;
+
+ xout << " <DisplayName>" << DisplayName
+ << "</DisplayName>" << std::endl;
+
+ xout << " <Description>" << Description
+ << "</Description>" << std::endl;
+
+ xout << " <Name>" << Name << "</Name>" << std::endl;
+
+ xout << " <Version>" << Version
+ << "</Version>" << std::endl;
+
+ xout << " <ReleaseDate>";
+ if(ReleaseDate.empty())
+ {
+ xout << cmTimestamp().CurrentTime("%Y-%m-%d", true);
+ }
+ else
+ {
+ xout << ReleaseDate;
+ }
+ xout << "</ReleaseDate>" << std::endl;
+
+ // Script (copy to meta dir)
+ if(!Script.empty())
+ {
+ std::string name = cmSystemTools::GetFilenameName(Script);
+ std::string path = Directory + "/meta/" + name;
+ cmsys::SystemTools::CopyFileIfDifferent(Script.data(), path.data());
+ xout << " <Script>" << name << "</Script>" << std::endl;
+ }
+
+ // Dependencies
+ std::set<DependenceStruct> compDepSet;
+ for(std::set<DependenceStruct*>::iterator ait = AlienDependencies.begin();
+ ait != AlienDependencies.end(); ++ait)
+ {
+ compDepSet.insert(*(*ait));
+ }
+ for(std::set<cmCPackIFWPackage*>::iterator it = Dependencies.begin();
+ it != Dependencies.end(); ++it)
+ {
+ compDepSet.insert(DependenceStruct((*it)->Name));
+ }
+ // Write dependencies
+ if (!compDepSet.empty())
+ {
+ xout << " <Dependencies>";
+ std::set<DependenceStruct>::iterator it = compDepSet.begin();
+ xout << it->NameWithCompare();
+ ++it;
+ while(it != compDepSet.end())
+ {
+ xout << "," << it->NameWithCompare();
+ ++it;
+ }
+ xout << "</Dependencies>" << std::endl;
+ }
+
+ // Licenses (copy to meta dir)
+ std::vector<std::string> licenses = Licenses;
+ for(size_t i = 1; i < licenses.size(); i += 2)
+ {
+ std::string name = cmSystemTools::GetFilenameName(licenses[i]);
+ std::string path = Directory + "/meta/" + name;
+ cmsys::SystemTools::CopyFileIfDifferent(licenses[i].data(), path.data());
+ licenses[i] = name;
+ }
+ if(!licenses.empty())
+ {
+ xout << " <Licenses>" << std::endl;
+ for(size_t i = 0; i < licenses.size(); i += 2)
+ {
+ xout << " <License "
+ << "name=\"" << licenses[i] << "\" "
+ << "file=\"" << licenses[i + 1] << "\" "
+ << "/>" <<std::endl;
+ }
+ xout << " </Licenses>" << std::endl;
+ }
+
+ if (!ForcedInstallation.empty())
+ {
+ xout << " <ForcedInstallation>" << ForcedInstallation
+ << "</ForcedInstallation>" << std::endl;
+ }
+
+ if (!Virtual.empty())
+ {
+ xout << " <Virtual>" << Virtual << "</Virtual>" << std::endl;
+ }
+ else if (!Default.empty())
+ {
+ xout << " <Default>" << Default << "</Default>" << std::endl;
+ }
+
+ // Priority
+ if(!SortingPriority.empty())
+ {
+ xout << " <SortingPriority>" << SortingPriority
+ << "</SortingPriority>" << std::endl;
+ }
+
+ xout << "</Package>" << std::endl;
+}
+
+void cmCPackIFWPackage::WriteGeneratedByToStrim(cmGeneratedFileStream &xout)
+{
+ if(Generator) Generator->WriteGeneratedByToStrim(xout);
+}
diff --git a/Source/CPack/IFW/cmCPackIFWPackage.h b/Source/CPack/IFW/cmCPackIFWPackage.h
new file mode 100644
index 000000000..d2f792709
--- /dev/null
+++ b/Source/CPack/IFW/cmCPackIFWPackage.h
@@ -0,0 +1,141 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmCPackIFWPackage_h
+#define cmCPackIFWPackage_h
+
+#include <cmStandardIncludes.h>
+#include <cmGeneratedFileStream.h>
+
+class cmCPackComponent;
+class cmCPackComponentGroup;
+class cmCPackIFWInstaller;
+class cmCPackIFWGenerator;
+
+/** \class cmCPackIFWPackage
+ * \brief A single component to be installed by CPack IFW generator
+ */
+class cmCPackIFWPackage
+{
+public: // Types
+ enum CompareTypes
+ {
+ CompareNone = 0x0,
+ CompareEqual = 0x1,
+ CompareLess = 0x2,
+ CompareLessOrEqual = 0x3,
+ CompareGreater = 0x4,
+ CompareGreaterOrEqual = 0x5
+ };
+
+ struct CompareStruct
+ {
+ CompareStruct();
+
+ unsigned int Type;
+ std::string Value;
+ };
+
+ struct DependenceStruct
+ {
+ DependenceStruct();
+ DependenceStruct(const std::string &dependence);
+
+ std::string Name;
+ CompareStruct Compare;
+
+ std::string NameWithCompare() const;
+
+ bool operator < (const DependenceStruct &other) const
+ {
+ return Name < other.Name;
+ }
+ };
+
+public: // [Con|De]structor
+
+ /**
+ * Construct package
+ */
+ cmCPackIFWPackage();
+
+public: // Configuration
+
+ /// Human-readable name of the component
+ std::string DisplayName;
+
+ /// Human-readable description of the component
+ std::string Description;
+
+ /// Version number of the component
+ std::string Version;
+
+ /// Date when this component version was released
+ std::string ReleaseDate;
+
+ /// Domain-like identification for this component
+ std::string Name;
+
+ /// File name of a script being loaded
+ std::string Script;
+
+ /// List of license agreements to be accepted by the installing user
+ std::vector<std::string> Licenses;
+
+ /// Priority of the component in the tree
+ std::string SortingPriority;
+
+ /// Set to true to preselect the component in the installer
+ std::string Default;
+
+ /// Set to true to hide the component from the installer
+ std::string Virtual;
+
+ /// Determines that the package must always be installed
+ std::string ForcedInstallation;
+
+public: // Internal implementation
+
+ const char* GetOption(const std::string& op) const;
+ bool IsOn(const std::string& op) const;
+
+ bool IsVersionLess(const char *version);
+ bool IsVersionGreater(const char *version);
+ bool IsVersionEqual(const char *version);
+
+ std::string GetComponentName(cmCPackComponent *component);
+
+ void DefaultConfiguration();
+
+ int ConfigureFromOptions();
+ int ConfigureFromComponent(cmCPackComponent *component);
+ int ConfigureFromGroup(cmCPackComponentGroup *group);
+ int ConfigureFromGroup(const std::string &groupName);
+
+ void GeneratePackageFile();
+
+ // Pointer to generator
+ cmCPackIFWGenerator* Generator;
+ // Pointer to installer
+ cmCPackIFWInstaller* Installer;
+ // Collection of dependencies
+ std::set<cmCPackIFWPackage*> Dependencies;
+ // Collection of unresolved dependencies
+ std::set<DependenceStruct*> AlienDependencies;
+ // Patch to package directory
+ std::string Directory;
+
+protected:
+ void WriteGeneratedByToStrim(cmGeneratedFileStream& xout);
+};
+
+#endif // cmCPackIFWPackage_h
diff --git a/Source/CPack/OSXScriptLauncher.cxx b/Source/CPack/OSXScriptLauncher.cxx
index a9842c1df..c271517f1 100644
--- a/Source/CPack/OSXScriptLauncher.cxx
+++ b/Source/CPack/OSXScriptLauncher.cxx
@@ -11,8 +11,9 @@
============================================================================*/
#include <cmsys/SystemTools.hxx>
#include <cmsys/Process.h>
-#include <cmsys/ios/fstream>
-#include <cmsys/ios/iostream>
+#include <cmsys/FStream.hxx>
+
+#include <iostream>
#include <CoreFoundation/CoreFoundation.h>
@@ -20,14 +21,14 @@
#include <sys/syslimits.h>
#define DebugError(x) \
- ofs << x << cmsys_ios::endl; \
- cmsys_ios::cout << x << cmsys_ios::endl
+ ofs << x << std::endl; \
+ std::cout << x << std::endl
int main(int argc, char* argv[])
{
//if ( cmsys::SystemTools::FileExists(
- cmsys_stl::string cwd = cmsys::SystemTools::GetCurrentWorkingDirectory();
- cmsys_ios::ofstream ofs("/tmp/output.txt");
+ std::string cwd = cmsys::SystemTools::GetCurrentWorkingDirectory();
+ cmsys::ofstream ofs("/tmp/output.txt");
CFStringRef fileName;
CFBundleRef appBundle;
@@ -66,7 +67,7 @@ int main(int argc, char* argv[])
//dispose of the CF variable
CFRelease(scriptFileURL);
- cmsys_stl::string fullScriptPath = reinterpret_cast<char*>(path);
+ std::string fullScriptPath = reinterpret_cast<char*>(path);
delete [] path;
@@ -75,10 +76,10 @@ int main(int argc, char* argv[])
return 1;
}
- cmsys_stl::string scriptDirectory = cmsys::SystemTools::GetFilenamePath(
+ std::string scriptDirectory = cmsys::SystemTools::GetFilenamePath(
fullScriptPath);
- ofs << fullScriptPath.c_str() << cmsys_ios::endl;
- cmsys_stl::vector<const char*> args;
+ ofs << fullScriptPath.c_str() << std::endl;
+ std::vector<const char*> args;
args.push_back(fullScriptPath.c_str());
int cc;
for ( cc = 1; cc < argc; ++ cc )
@@ -109,7 +110,7 @@ int main(int argc, char* argv[])
data[i] = ' ';
}
}
- cmsys_ios::cout.write(data, length);
+ std::cout.write(data, length);
}
cmsysProcess_WaitForExit(cp, 0);
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
index cc9dec7b8..ece327a41 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -1,6 +1,6 @@
/*============================================================================
CMake - Cross Platform Makefile Generator
- Copyright 2000-2012 Kitware, Inc., Insight Software Consortium
+ Copyright 2012-2015 Kitware, Inc., Insight Software Consortium
Distributed under the OSI-approved BSD License (the "License");
see accompanying file Copyright.txt for details.
@@ -14,33 +14,49 @@
#include <cmSystemTools.h>
#include <cmGeneratedFileStream.h>
+#include <cmCryptoHash.h>
+#include <cmInstalledFile.h>
#include <CPack/cmCPackLog.h>
#include <CPack/cmCPackComponentGroup.h>
#include "cmWIXSourceWriter.h"
+#include "cmWIXDirectoriesSourceWriter.h"
+#include "cmWIXFeaturesSourceWriter.h"
+#include "cmWIXFilesSourceWriter.h"
#include "cmWIXRichTextFormatWriter.h"
#include <cmsys/SystemTools.hxx>
#include <cmsys/Directory.hxx>
+#include <cmsys/Encoding.hxx>
+#include <cmsys/FStream.hxx>
#include <rpc.h> // for GUID generation
-int cmCPackWIXGenerator::InitializeInternal()
+cmCPackWIXGenerator::cmCPackWIXGenerator():
+ Patch(0)
{
- componentPackageMethod = ONE_PACKAGE;
- return this->Superclass::InitializeInternal();
}
-bool cmCPackWIXGenerator::RunWiXCommand(const std::string& command)
+cmCPackWIXGenerator::~cmCPackWIXGenerator()
{
- std::string cpackTopLevel;
- if(!RequireOption("CPACK_TOPLEVEL_DIRECTORY", cpackTopLevel))
+ if(this->Patch)
{
- return false;
+ delete this->Patch;
}
+}
+
+int cmCPackWIXGenerator::InitializeInternal()
+{
+ componentPackageMethod = ONE_PACKAGE;
+ this->Patch = new cmWIXPatch(this->Logger);
+
+ return this->Superclass::InitializeInternal();
+}
- std::string logFileName = cpackTopLevel + "/wix.log";
+bool cmCPackWIXGenerator::RunWiXCommand(std::string const& command)
+{
+ std::string logFileName = this->CPackTopLevel + "/wix.log";
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"Running WiX command: " << command << std::endl);
@@ -48,10 +64,11 @@ bool cmCPackWIXGenerator::RunWiXCommand(const std::string& command)
std::string output;
int returnValue = 0;
- bool status = cmSystemTools::RunSingleCommand(command.c_str(), &output,
+ bool status = cmSystemTools::RunSingleCommand(
+ command.c_str(), &output, &output,
&returnValue, 0, cmSystemTools::OUTPUT_NONE);
- std::ofstream logFile(logFileName.c_str(), std::ios::app);
+ cmsys::ofstream logFile(logFileName.c_str(), std::ios::app);
logFile << command << std::endl;
logFile << output;
logFile.close();
@@ -69,7 +86,7 @@ bool cmCPackWIXGenerator::RunWiXCommand(const std::string& command)
}
bool cmCPackWIXGenerator::RunCandleCommand(
- const std::string& sourceFile, const std::string& objectFile)
+ std::string const& sourceFile, std::string const& objectFile)
{
std::string executable;
if(!RequireOption("CPACK_WIX_CANDLE_EXECUTABLE", executable))
@@ -82,12 +99,21 @@ bool cmCPackWIXGenerator::RunCandleCommand(
command << " -nologo";
command << " -arch " << GetArchitecture();
command << " -out " << QuotePath(objectFile);
+
+ for(extension_set_t::const_iterator i = CandleExtensions.begin();
+ i != CandleExtensions.end(); ++i)
+ {
+ command << " -ext " << QuotePath(*i);
+ }
+
+ AddCustomFlags("CPACK_WIX_CANDLE_EXTRA_FLAGS", command);
+
command << " " << QuotePath(sourceFile);
return RunWiXCommand(command.str());
}
-bool cmCPackWIXGenerator::RunLightCommand(const std::string& objectFiles)
+bool cmCPackWIXGenerator::RunLightCommand(std::string const& objectFiles)
{
std::string executable;
if(!RequireOption("CPACK_WIX_LIGHT_EXECUTABLE", executable))
@@ -99,12 +125,21 @@ bool cmCPackWIXGenerator::RunLightCommand(const std::string& objectFiles)
command << QuotePath(executable);
command << " -nologo";
command << " -out " << QuotePath(packageFileNames.at(0));
- command << " -ext WixUIExtension";
+
+ for(extension_set_t::const_iterator i = this->LightExtensions.begin();
+ i != this->LightExtensions.end(); ++i)
+ {
+ command << " -ext " << QuotePath(*i);
+ }
+
const char* const cultures = GetOption("CPACK_WIX_CULTURES");
if(cultures)
{
command << " -cultures:" << cultures;
}
+
+ AddCustomFlags("CPACK_WIX_LIGHT_EXTRA_FLAGS", command);
+
command << " " << objectFiles;
return RunWiXCommand(command.str());
@@ -152,15 +187,14 @@ bool cmCPackWIXGenerator::InitializeWiXConfiguration()
"you might want to set this explicitly." << std::endl);
}
- std::string cpackTopLevel;
- if(!RequireOption("CPACK_TOPLEVEL_DIRECTORY", cpackTopLevel))
+ if(!RequireOption("CPACK_TOPLEVEL_DIRECTORY", this->CPackTopLevel))
{
return false;
}
if(GetOption("CPACK_WIX_LICENSE_RTF") == 0)
{
- std::string licenseFilename = cpackTopLevel + "/License.rtf";
+ std::string licenseFilename = this->CPackTopLevel + "/License.rtf";
SetOption("CPACK_WIX_LICENSE_RTF", licenseFilename.c_str());
if(!CreateLicenseFile())
@@ -169,6 +203,57 @@ bool cmCPackWIXGenerator::InitializeWiXConfiguration()
}
}
+ if(GetOption("CPACK_PACKAGE_VENDOR") == 0)
+ {
+ std::string defaultVendor = "Humanity";
+ SetOption("CPACK_PACKAGE_VENDOR", defaultVendor.c_str());
+
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE,
+ "CPACK_PACKAGE_VENDOR implicitly set to " << defaultVendor << " . "
+ << std::endl);
+ }
+
+ if(GetOption("CPACK_WIX_UI_REF") == 0)
+ {
+ std::string defaultRef = "WixUI_InstallDir";
+
+ if(!this->Components.empty())
+ {
+ defaultRef = "WixUI_FeatureTree";
+ }
+
+ SetOption("CPACK_WIX_UI_REF", defaultRef.c_str());
+ }
+
+ const char* packageContact = GetOption("CPACK_PACKAGE_CONTACT");
+ if(packageContact != 0 &&
+ GetOption("CPACK_WIX_PROPERTY_ARPCONTACT") == 0)
+ {
+ SetOption("CPACK_WIX_PROPERTY_ARPCONTACT", packageContact);
+ }
+
+ CollectExtensions("CPACK_WIX_EXTENSIONS", this->CandleExtensions);
+ CollectExtensions("CPACK_WIX_CANDLE_EXTENSIONS", this->CandleExtensions);
+
+ this->LightExtensions.insert("WixUIExtension");
+ CollectExtensions("CPACK_WIX_EXTENSIONS", this->LightExtensions);
+ CollectExtensions("CPACK_WIX_LIGHT_EXTENSIONS", this->LightExtensions);
+
+ const char* patchFilePath = GetOption("CPACK_WIX_PATCH_FILE");
+ if(patchFilePath)
+ {
+ std::vector<std::string> patchFilePaths;
+ cmSystemTools::ExpandListArgument(patchFilePath, patchFilePaths);
+
+ for(size_t i = 0; i < patchFilePaths.size(); ++i)
+ {
+ if(!this->Patch->LoadFragments(patchFilePaths[i]))
+ {
+ return false;
+ }
+ }
+ }
+
return true;
}
@@ -179,23 +264,41 @@ bool cmCPackWIXGenerator::PackageFilesImpl()
return false;
}
- if(!CreateWiXVariablesIncludeFile())
- {
- return false;
- }
+ CreateWiXVariablesIncludeFile();
+ CreateWiXPropertiesIncludeFile();
+ CreateWiXProductFragmentIncludeFile();
if(!CreateWiXSourceFiles())
{
return false;
}
+ AppendUserSuppliedExtraSources();
+
+ std::set<std::string> usedBaseNames;
+
std::stringstream objectFiles;
- for(size_t i = 0; i < wixSources.size(); ++i)
+ for(size_t i = 0; i < this->WixSources.size(); ++i)
{
- const std::string& sourceFilename = wixSources[i];
+ std::string const& sourceFilename = this->WixSources[i];
+
+ std::string baseName =
+ cmSystemTools::GetFilenameWithoutLastExtension(sourceFilename);
+
+ unsigned int counter = 0;
+ std::string uniqueBaseName = baseName;
+
+ while(usedBaseNames.find(uniqueBaseName) != usedBaseNames.end())
+ {
+ std::stringstream tmp;
+ tmp << baseName << ++counter;
+ uniqueBaseName = tmp.str();
+ }
+
+ usedBaseNames.insert(uniqueBaseName);
std::string objectFilename =
- cmSystemTools::GetFilenameWithoutExtension(sourceFilename) + ".wixobj";
+ this->CPackTopLevel + "/" + uniqueBaseName + ".wixobj";
if(!RunCandleCommand(sourceFilename, objectFilename))
{
@@ -205,21 +308,43 @@ bool cmCPackWIXGenerator::PackageFilesImpl()
objectFiles << " " << QuotePath(objectFilename);
}
+ AppendUserSuppliedExtraObjects(objectFiles);
+
return RunLightCommand(objectFiles.str());
}
-bool cmCPackWIXGenerator::CreateWiXVariablesIncludeFile()
+void cmCPackWIXGenerator::AppendUserSuppliedExtraSources()
+{
+ const char *cpackWixExtraSources = GetOption("CPACK_WIX_EXTRA_SOURCES");
+ if(!cpackWixExtraSources) return;
+
+ cmSystemTools::ExpandListArgument(cpackWixExtraSources, this->WixSources);
+}
+
+void cmCPackWIXGenerator::AppendUserSuppliedExtraObjects(std::ostream& stream)
{
- std::string cpackTopLevel;
- if(!RequireOption("CPACK_TOPLEVEL_DIRECTORY", cpackTopLevel))
+ const char *cpackWixExtraObjects = GetOption("CPACK_WIX_EXTRA_OBJECTS");
+ if(!cpackWixExtraObjects) return;
+
+ std::vector<std::string> expandedExtraObjects;
+
+ cmSystemTools::ExpandListArgument(
+ cpackWixExtraObjects, expandedExtraObjects);
+
+ for(size_t i = 0; i < expandedExtraObjects.size(); ++i)
{
- return false;
+ stream << " " << QuotePath(expandedExtraObjects[i]);
}
+}
+void cmCPackWIXGenerator::CreateWiXVariablesIncludeFile()
+{
std::string includeFilename =
- cpackTopLevel + "/cpack_variables.wxi";
+ this->CPackTopLevel + "/cpack_variables.wxi";
+
+ cmWIXSourceWriter includeFile(
+ this->Logger, includeFilename, true);
- cmWIXSourceWriter includeFile(Logger, includeFilename, true);
CopyDefinition(includeFile, "CPACK_WIX_PRODUCT_GUID");
CopyDefinition(includeFile, "CPACK_WIX_UPGRADE_GUID");
CopyDefinition(includeFile, "CPACK_PACKAGE_VENDOR");
@@ -232,12 +357,74 @@ bool cmCPackWIXGenerator::CreateWiXVariablesIncludeFile()
SetOptionIfNotSet("CPACK_WIX_PROGRAM_MENU_FOLDER",
GetOption("CPACK_PACKAGE_NAME"));
CopyDefinition(includeFile, "CPACK_WIX_PROGRAM_MENU_FOLDER");
+ CopyDefinition(includeFile, "CPACK_WIX_UI_REF");
+}
- return true;
+void cmCPackWIXGenerator::CreateWiXPropertiesIncludeFile()
+{
+ std::string includeFilename =
+ this->CPackTopLevel + "/properties.wxi";
+
+ cmWIXSourceWriter includeFile(
+ this->Logger, includeFilename, true);
+
+ std::string prefix = "CPACK_WIX_PROPERTY_";
+ std::vector<std::string> options = GetOptions();
+
+ for(size_t i = 0; i < options.size(); ++i)
+ {
+ std::string const& name = options[i];
+
+ if(name.length() > prefix.length() &&
+ name.substr(0, prefix.length()) == prefix)
+ {
+ std::string id = name.substr(prefix.length());
+ std::string value = GetOption(name.c_str());
+
+ includeFile.BeginElement("Property");
+ includeFile.AddAttribute("Id", id);
+ includeFile.AddAttribute("Value", value);
+ includeFile.EndElement("Property");
+ }
+ }
+
+ if(GetOption("CPACK_WIX_PROPERTY_ARPINSTALLLOCATION") == 0)
+ {
+ includeFile.BeginElement("Property");
+ includeFile.AddAttribute("Id", "INSTALL_ROOT");
+ includeFile.AddAttribute("Secure", "yes");
+
+ includeFile.BeginElement("RegistrySearch");
+ includeFile.AddAttribute("Id", "FindInstallLocation");
+ includeFile.AddAttribute("Root", "HKLM");
+ includeFile.AddAttribute("Key", "Software\\Microsoft\\Windows\\"
+ "CurrentVersion\\Uninstall\\[WIX_UPGRADE_DETECTED]");
+ includeFile.AddAttribute("Name", "InstallLocation");
+ includeFile.AddAttribute("Type", "raw");
+ includeFile.EndElement("RegistrySearch");
+ includeFile.EndElement("Property");
+
+ includeFile.BeginElement("SetProperty");
+ includeFile.AddAttribute("Id", "ARPINSTALLLOCATION");
+ includeFile.AddAttribute("Value", "[INSTALL_ROOT]");
+ includeFile.AddAttribute("After", "CostFinalize");
+ includeFile.EndElement("SetProperty");
+ }
+}
+
+void cmCPackWIXGenerator::CreateWiXProductFragmentIncludeFile()
+{
+ std::string includeFilename =
+ this->CPackTopLevel + "/product_fragment.wxi";
+
+ cmWIXSourceWriter includeFile(
+ this->Logger, includeFilename, true);
+
+ this->Patch->ApplyFragment("#PRODUCT", includeFile);
}
void cmCPackWIXGenerator::CopyDefinition(
- cmWIXSourceWriter &source, const std::string &name)
+ cmWIXSourceWriter &source, std::string const& name)
{
const char* value = GetOption(name.c_str());
if(value)
@@ -247,233 +434,422 @@ void cmCPackWIXGenerator::CopyDefinition(
}
void cmCPackWIXGenerator::AddDefinition(cmWIXSourceWriter& source,
- const std::string& name, const std::string& value)
+ std::string const& name, std::string const& value)
{
std::stringstream tmp;
tmp << name << "=\"" << value << '"';
source.AddProcessingInstruction("define",
- cmWIXSourceWriter::WindowsCodepageToUtf8(tmp.str()));
+ cmWIXSourceWriter::CMakeEncodingToUtf8(tmp.str()));
}
bool cmCPackWIXGenerator::CreateWiXSourceFiles()
{
- std::string cpackTopLevel;
- if(!RequireOption("CPACK_TOPLEVEL_DIRECTORY", cpackTopLevel))
- {
- return false;
- }
-
std::string directoryDefinitionsFilename =
- cpackTopLevel + "/directories.wxs";
+ this->CPackTopLevel + "/directories.wxs";
- wixSources.push_back(directoryDefinitionsFilename);
+ this->WixSources.push_back(directoryDefinitionsFilename);
- cmWIXSourceWriter directoryDefinitions(Logger, directoryDefinitionsFilename);
+ cmWIXDirectoriesSourceWriter directoryDefinitions(
+ this->Logger, directoryDefinitionsFilename);
directoryDefinitions.BeginElement("Fragment");
+ std::string installRoot;
+ if(!RequireOption("CPACK_PACKAGE_INSTALL_DIRECTORY", installRoot))
+ {
+ return false;
+ }
+
directoryDefinitions.BeginElement("Directory");
directoryDefinitions.AddAttribute("Id", "TARGETDIR");
directoryDefinitions.AddAttribute("Name", "SourceDir");
- directoryDefinitions.BeginElement("Directory");
- if(GetArchitecture() == "x86")
+ size_t installRootSize =
+ directoryDefinitions.BeginInstallationPrefixDirectory(
+ GetProgramFilesFolderId(), installRoot);
+
+ std::string fileDefinitionsFilename =
+ this->CPackTopLevel + "/files.wxs";
+
+ this->WixSources.push_back(fileDefinitionsFilename);
+
+ cmWIXFilesSourceWriter fileDefinitions(
+ this->Logger, fileDefinitionsFilename);
+
+ fileDefinitions.BeginElement("Fragment");
+
+ std::string featureDefinitionsFilename =
+ this->CPackTopLevel +"/features.wxs";
+
+ this->WixSources.push_back(featureDefinitionsFilename);
+
+ cmWIXFeaturesSourceWriter featureDefinitions(
+ this->Logger, featureDefinitionsFilename);
+
+ featureDefinitions.BeginElement("Fragment");
+
+ featureDefinitions.BeginElement("Feature");
+ featureDefinitions.AddAttribute("Id", "ProductFeature");
+ featureDefinitions.AddAttribute("Display", "expand");
+ featureDefinitions.AddAttribute("Absent", "disallow");
+ featureDefinitions.AddAttribute("ConfigurableDirectory", "INSTALL_ROOT");
+
+ std::string cpackPackageName;
+ if(!RequireOption("CPACK_PACKAGE_NAME", cpackPackageName))
+ {
+ return false;
+ }
+
+ featureDefinitions.AddAttribute("Title", cpackPackageName);
+ featureDefinitions.AddAttribute("Level", "1");
+ this->Patch->ApplyFragment("#PRODUCTFEATURE", featureDefinitions);
+
+ const char* package = GetOption("CPACK_WIX_CMAKE_PACKAGE_REGISTRY");
+ if(package)
+ {
+ featureDefinitions.CreateCMakePackageRegistryEntry(
+ package, GetOption("CPACK_WIX_UPGRADE_GUID"));
+ }
+
+ if(!CreateFeatureHierarchy(featureDefinitions))
{
- directoryDefinitions.AddAttribute("Id", "ProgramFilesFolder");
+ return false;
+ }
+
+ featureDefinitions.EndElement("Feature");
+
+ std::set<cmWIXShortcuts::Type> emittedShortcutTypes;
+
+ cmWIXShortcuts globalShortcuts;
+ if(Components.empty())
+ {
+ AddComponentsToFeature(toplevel, "ProductFeature",
+ directoryDefinitions, fileDefinitions, featureDefinitions,
+ globalShortcuts);
+
+ globalShortcuts.AddShortcutTypes(emittedShortcutTypes);
}
else
{
- directoryDefinitions.AddAttribute("Id", "ProgramFiles64Folder");
+ for(std::map<std::string, cmCPackComponent>::const_iterator
+ i = this->Components.begin(); i != this->Components.end(); ++i)
+ {
+ cmCPackComponent const& component = i->second;
+
+ std::string componentPath = toplevel;
+ componentPath += "/";
+ componentPath += component.Name;
+
+ std::string componentFeatureId = "CM_C_" + component.Name;
+
+ cmWIXShortcuts featureShortcuts;
+ AddComponentsToFeature(componentPath, componentFeatureId,
+ directoryDefinitions, fileDefinitions,
+ featureDefinitions, featureShortcuts);
+
+ featureShortcuts.AddShortcutTypes(emittedShortcutTypes);
+
+ if(!CreateShortcuts(component.Name, componentFeatureId,
+ featureShortcuts, false, fileDefinitions, featureDefinitions))
+ {
+ return false;
+ }
+ }
}
- std::vector<std::string> install_root;
+ bool emitUninstallShortcut = emittedShortcutTypes.find(
+ cmWIXShortcuts::START_MENU) != emittedShortcutTypes.end();
- std::string tmp;
- if(!RequireOption("CPACK_PACKAGE_INSTALL_DIRECTORY", tmp))
+ if(!CreateShortcuts(std::string(), "ProductFeature",
+ globalShortcuts, emitUninstallShortcut,
+ fileDefinitions, featureDefinitions))
{
return false;
}
- cmSystemTools::SplitPath(tmp.c_str(), install_root);
+ featureDefinitions.EndElement("Fragment");
+ fileDefinitions.EndElement("Fragment");
+
+ directoryDefinitions.EndInstallationPrefixDirectory(
+ installRootSize);
- if(!install_root.empty() && install_root.back().empty())
+ if(emittedShortcutTypes.find(cmWIXShortcuts::START_MENU) !=
+ emittedShortcutTypes.end())
{
- install_root.pop_back();
+ directoryDefinitions.EmitStartMenuFolder(
+ GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER"));
}
- for(size_t i = 1; i < install_root.size(); ++i)
+ if(emittedShortcutTypes.find(cmWIXShortcuts::DESKTOP) !=
+ emittedShortcutTypes.end())
{
- directoryDefinitions.BeginElement("Directory");
+ directoryDefinitions.EmitDesktopFolder();
+ }
- if(i == install_root.size() - 1)
- {
- directoryDefinitions.AddAttribute("Id", "INSTALL_ROOT");
- }
- else
- {
- std::stringstream ss;
- ss << "INSTALL_PREFIX_" << i;
- directoryDefinitions.AddAttribute("Id", ss.str());
- }
+ if(emittedShortcutTypes.find(cmWIXShortcuts::STARTUP) !=
+ emittedShortcutTypes.end())
+ {
+ directoryDefinitions.EmitStartupFolder();
+ }
- directoryDefinitions.AddAttribute("Name", install_root[i]);
- }
+ directoryDefinitions.EndElement("Directory");
+ directoryDefinitions.EndElement("Fragment");
- size_t directoryCounter = 0;
- size_t fileCounter = 0;
+ if(!GenerateMainSourceFileFromTemplate())
+ {
+ return false;
+ }
- std::string fileDefinitionsFilename =
- cpackTopLevel + "/files.wxs";
+ return this->Patch->CheckForUnappliedFragments();
+}
- wixSources.push_back(fileDefinitionsFilename);
+std::string cmCPackWIXGenerator::GetProgramFilesFolderId() const
+{
+ if(GetArchitecture() == "x86")
+ {
+ return "ProgramFilesFolder";
+ }
+ else
+ {
+ return "ProgramFiles64Folder";
+ }
+}
- cmWIXSourceWriter fileDefinitions(Logger, fileDefinitionsFilename);
- fileDefinitions.BeginElement("Fragment");
+bool cmCPackWIXGenerator::GenerateMainSourceFileFromTemplate()
+{
+ std::string wixTemplate = FindTemplate("WIX.template.in");
+ if(GetOption("CPACK_WIX_TEMPLATE") != 0)
+ {
+ wixTemplate = GetOption("CPACK_WIX_TEMPLATE");
+ }
- std::string featureDefinitionsFilename =
- cpackTopLevel +"/features.wxs";
+ if(wixTemplate.empty())
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Could not find CPack WiX template file WIX.template.in" << std::endl);
+ return false;
+ }
- wixSources.push_back(featureDefinitionsFilename);
+ std::string mainSourceFilePath = this->CPackTopLevel + "/main.wxs";
- cmWIXSourceWriter featureDefinitions(Logger, featureDefinitionsFilename);
- featureDefinitions.BeginElement("Fragment");
+ if(!ConfigureFile(wixTemplate.c_str(), mainSourceFilePath .c_str()))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Failed creating '" << mainSourceFilePath <<
+ "'' from template." << std::endl);
- featureDefinitions.BeginElement("Feature");
- featureDefinitions.AddAttribute("Id", "ProductFeature");
- featureDefinitions.AddAttribute("Title", Name);
- featureDefinitions.AddAttribute("Level", "1");
- featureDefinitions.EndElement();
+ return false;
+ }
- featureDefinitions.BeginElement("FeatureRef");
- featureDefinitions.AddAttribute("Id", "ProductFeature");
+ this->WixSources.push_back(mainSourceFilePath);
- const char *cpackPackageExecutables = GetOption("CPACK_PACKAGE_EXECUTABLES");
- std::vector<std::string> cpackPkgExecutables;
- std::string regKey;
- if ( cpackPackageExecutables )
+ return true;
+}
+
+bool cmCPackWIXGenerator::CreateFeatureHierarchy(
+ cmWIXFeaturesSourceWriter& featureDefinitions)
+{
+ for(std::map<std::string, cmCPackComponentGroup>::const_iterator
+ i = ComponentGroups.begin(); i != ComponentGroups.end(); ++i)
{
- cmSystemTools::ExpandListArgument(cpackPackageExecutables,
- cpackPkgExecutables);
- if ( cpackPkgExecutables.size() % 2 != 0 )
+ cmCPackComponentGroup const& group = i->second;
+ if(group.ParentGroup == 0)
{
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "CPACK_PACKAGE_EXECUTABLES should contain pairs of <executable> and "
- "<icon name>." << std::endl);
- cpackPkgExecutables.clear();
+ featureDefinitions.EmitFeatureForComponentGroup(group);
}
+ }
- const char *cpackVendor = GetOption("CPACK_PACKAGE_VENDOR");
- const char *cpackPkgName = GetOption("CPACK_PACKAGE_NAME");
- if (!cpackVendor || !cpackPkgName)
- {
- cmCPackLogger(cmCPackLog::LOG_WARNING, "CPACK_PACKAGE_VENDOR and "
- "CPACK_PACKAGE_NAME must be defined for shortcut creation" << std::endl);
- cpackPkgExecutables.clear();
- }
- else
+ for(std::map<std::string, cmCPackComponent>::const_iterator
+ i = this->Components.begin(); i != this->Components.end(); ++i)
+ {
+ cmCPackComponent const& component = i->second;
+
+ if(!component.Group)
{
- regKey = std::string("Software/") + cpackVendor + "/" + cpackPkgName;
+ featureDefinitions.EmitFeatureForComponent(component);
}
}
- std::vector<std::string> dirIdExecutables;
+ return true;
+}
+
+bool cmCPackWIXGenerator::AddComponentsToFeature(
+ std::string const& rootPath,
+ std::string const& featureId,
+ cmWIXDirectoriesSourceWriter& directoryDefinitions,
+ cmWIXFilesSourceWriter& fileDefinitions,
+ cmWIXFeaturesSourceWriter& featureDefinitions,
+ cmWIXShortcuts& shortcuts)
+{
+ featureDefinitions.BeginElement("FeatureRef");
+ featureDefinitions.AddAttribute("Id", featureId);
+
+ std::vector<std::string> cpackPackageExecutablesList;
+ const char *cpackPackageExecutables = GetOption("CPACK_PACKAGE_EXECUTABLES");
+ if(cpackPackageExecutables)
+ {
+ cmSystemTools::ExpandListArgument(cpackPackageExecutables,
+ cpackPackageExecutablesList);
+ if(cpackPackageExecutablesList.size() % 2 != 0 )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPACK_PACKAGE_EXECUTABLES should contain pairs of <executable> and "
+ "<text label>." << std::endl);
+ return false;
+ }
+ }
+
+ std::vector<std::string> cpackPackageDesktopLinksList;
+ const char *cpackPackageDesktopLinks =
+ GetOption("CPACK_CREATE_DESKTOP_LINKS");
+ if(cpackPackageDesktopLinks)
+ {
+ cmSystemTools::ExpandListArgument(cpackPackageDesktopLinks,
+ cpackPackageDesktopLinksList);
+ }
+
AddDirectoryAndFileDefinitons(
- toplevel, "INSTALL_ROOT",
+ rootPath, "INSTALL_ROOT",
directoryDefinitions, fileDefinitions, featureDefinitions,
- directoryCounter, fileCounter, cpackPkgExecutables, dirIdExecutables);
+ cpackPackageExecutablesList, cpackPackageDesktopLinksList,
+ shortcuts);
+
+ featureDefinitions.EndElement("FeatureRef");
- directoryDefinitions.EndElement();
- directoryDefinitions.EndElement();
+ return true;
+}
- if (dirIdExecutables.size() > 0 && dirIdExecutables.size() % 3 == 0)
+bool cmCPackWIXGenerator::CreateShortcuts(
+ std::string const& cpackComponentName,
+ std::string const& featureId,
+ cmWIXShortcuts const& shortcuts,
+ bool emitUninstallShortcut,
+ cmWIXFilesSourceWriter& fileDefinitions,
+ cmWIXFeaturesSourceWriter& featureDefinitions)
+{
+ if(!shortcuts.empty(cmWIXShortcuts::START_MENU))
{
- fileDefinitions.BeginElement("DirectoryRef");
- fileDefinitions.AddAttribute("Id", "PROGRAM_MENU_FOLDER");
- fileDefinitions.BeginElement("Component");
- fileDefinitions.AddAttribute("Id", "SHORTCUT");
- fileDefinitions.AddAttribute("Guid", "*");
+ if(!this->CreateShortcutsOfSpecificType(cmWIXShortcuts::START_MENU,
+ cpackComponentName, featureId, "",
+ shortcuts, emitUninstallShortcut,
+ fileDefinitions, featureDefinitions))
+ {
+ return false;
+ }
+ }
- std::vector<std::string>::iterator it;
- for ( it = dirIdExecutables.begin() ;
- it != dirIdExecutables.end();
- ++it)
+ if(!shortcuts.empty(cmWIXShortcuts::DESKTOP))
+ {
+ if(!this->CreateShortcutsOfSpecificType(cmWIXShortcuts::DESKTOP,
+ cpackComponentName, featureId, "DESKTOP",
+ shortcuts, false,
+ fileDefinitions, featureDefinitions))
{
- std::string fileName = *it++;
- std::string iconName = *it++;
- std::string directoryId = *it;
-
- fileDefinitions.BeginElement("Shortcut");
- std::string shortcutName = fileName; // the iconName is mor likely to contain blanks early on
- std::string::size_type const dotPos = shortcutName.find('.');
- if(std::string::npos == dotPos)
- { shortcutName = shortcutName.substr(0, dotPos); }
- fileDefinitions.AddAttribute("Id", "SHORTCUT_" + shortcutName);
- fileDefinitions.AddAttribute("Name", iconName);
- std::string target = "[" + directoryId + "]" + fileName;
- fileDefinitions.AddAttribute("Target", target);
- fileDefinitions.AddAttribute("WorkingDirectory", directoryId);
- fileDefinitions.EndElement();
+ return false;
}
- fileDefinitions.BeginElement("Shortcut");
- fileDefinitions.AddAttribute("Id", "UNINSTALL");
- std::string pkgName = GetOption("CPACK_PACKAGE_NAME");
- fileDefinitions.AddAttribute("Name", "Uninstall " + pkgName);
- fileDefinitions.AddAttribute("Description", "Uninstalls " + pkgName);
- fileDefinitions.AddAttribute("Target", "[SystemFolder]msiexec.exe");
- fileDefinitions.AddAttribute("Arguments", "/x [ProductCode]");
- fileDefinitions.EndElement();
- fileDefinitions.BeginElement("RemoveFolder");
- fileDefinitions.AddAttribute("Id", "PROGRAM_MENU_FOLDER");
- fileDefinitions.AddAttribute("On", "uninstall");
- fileDefinitions.EndElement();
- fileDefinitions.BeginElement("RegistryValue");
- fileDefinitions.AddAttribute("Root", "HKCU");
- fileDefinitions.AddAttribute("Key", regKey);
- fileDefinitions.AddAttribute("Name", "installed");
- fileDefinitions.AddAttribute("Type", "integer");
- fileDefinitions.AddAttribute("Value", "1");
- fileDefinitions.AddAttribute("KeyPath", "yes");
-
- featureDefinitions.BeginElement("ComponentRef");
- featureDefinitions.AddAttribute("Id", "SHORTCUT");
- featureDefinitions.EndElement();
- directoryDefinitions.BeginElement("Directory");
- directoryDefinitions.AddAttribute("Id", "ProgramMenuFolder");
- directoryDefinitions.BeginElement("Directory");
- directoryDefinitions.AddAttribute("Id", "PROGRAM_MENU_FOLDER");
- const char *startMenuFolder = GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER");
- directoryDefinitions.AddAttribute("Name", startMenuFolder);
- }
-
- featureDefinitions.EndElement();
- featureDefinitions.EndElement();
- fileDefinitions.EndElement();
- directoryDefinitions.EndElement();
+ }
- std::string wixTemplate = FindTemplate("WIX.template.in");
- if(GetOption("CPACK_WIX_TEMPLATE") != 0)
+ if(!shortcuts.empty(cmWIXShortcuts::STARTUP))
{
- wixTemplate = GetOption("CPACK_WIX_TEMPLATE");
+ if(!this->CreateShortcutsOfSpecificType(cmWIXShortcuts::STARTUP,
+ cpackComponentName, featureId, "STARTUP",
+ shortcuts, false,
+ fileDefinitions, featureDefinitions))
+ {
+ return false;
+ }
}
- if(wixTemplate.empty())
+
+ return true;
+}
+
+bool cmCPackWIXGenerator::CreateShortcutsOfSpecificType(
+ cmWIXShortcuts::Type type,
+ std::string const& cpackComponentName,
+ std::string const& featureId,
+ std::string const& idPrefix,
+ cmWIXShortcuts const& shortcuts,
+ bool emitUninstallShortcut,
+ cmWIXFilesSourceWriter& fileDefinitions,
+ cmWIXFeaturesSourceWriter& featureDefinitions)
+{
+ std::string directoryId;
+ switch(type)
{
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Could not find CPack WiX template file WIX.template.in" << std::endl);
- return false;
+ case cmWIXShortcuts::START_MENU:
+ directoryId = "PROGRAM_MENU_FOLDER";
+ break;
+ case cmWIXShortcuts::DESKTOP:
+ directoryId = "DesktopFolder";
+ break;
+ case cmWIXShortcuts::STARTUP:
+ directoryId = "StartupFolder";
+ break;
+ default:
+ return false;
}
- std::string mainSourceFilePath = cpackTopLevel + "/main.wxs";
+ featureDefinitions.BeginElement("FeatureRef");
+ featureDefinitions.AddAttribute("Id", featureId);
- if(!ConfigureFile(wixTemplate.c_str(), mainSourceFilePath .c_str()))
+ std::string cpackVendor;
+ if(!RequireOption("CPACK_PACKAGE_VENDOR", cpackVendor))
{
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Failed creating '" << mainSourceFilePath <<
- "'' from template." << std::endl);
+ return false;
+ }
+ std::string cpackPackageName;
+ if(!RequireOption("CPACK_PACKAGE_NAME", cpackPackageName))
+ {
return false;
}
- wixSources.push_back(mainSourceFilePath);
+ std::string idSuffix;
+ if(!cpackComponentName.empty())
+ {
+ idSuffix += "_";
+ idSuffix += cpackComponentName;
+ }
+
+ std::string componentId = "CM_SHORTCUT";
+ if(idPrefix.size())
+ {
+ componentId += "_" + idPrefix;
+ }
+
+ componentId += idSuffix;
+
+ fileDefinitions.BeginElement("DirectoryRef");
+ fileDefinitions.AddAttribute("Id", directoryId);
+
+ fileDefinitions.BeginElement("Component");
+ fileDefinitions.AddAttribute("Id", componentId);
+ fileDefinitions.AddAttribute("Guid", "*");
+
+ this->Patch->ApplyFragment(componentId, fileDefinitions);
+
+ std::string registryKey = std::string("Software\\") +
+ cpackVendor + "\\" + cpackPackageName;
+
+ shortcuts.EmitShortcuts(type, registryKey,
+ cpackComponentName, fileDefinitions);
+
+ if(type == cmWIXShortcuts::START_MENU)
+ {
+ fileDefinitions.EmitRemoveFolder(
+ "CM_REMOVE_PROGRAM_MENU_FOLDER" + idSuffix);
+ }
+
+ if(emitUninstallShortcut)
+ {
+ fileDefinitions.EmitUninstallShortcut(cpackPackageName);
+ }
+
+ fileDefinitions.EndElement("Component");
+ fileDefinitions.EndElement("DirectoryRef");
+
+ featureDefinitions.EmitComponentRef(componentId);
+ featureDefinitions.EndElement("FeatureRef");
return true;
}
@@ -504,7 +880,7 @@ bool cmCPackWIXGenerator::CreateLicenseFile()
{
cmWIXRichTextFormatWriter rtfWriter(licenseDestinationFilename);
- std::ifstream licenseSource(licenseSourceFilename.c_str());
+ cmsys::ifstream licenseSource(licenseSourceFilename.c_str());
std::string line;
while(std::getline(licenseSource, line))
@@ -526,19 +902,58 @@ bool cmCPackWIXGenerator::CreateLicenseFile()
}
void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons(
- const std::string& topdir,
- const std::string& directoryId,
- cmWIXSourceWriter& directoryDefinitions,
- cmWIXSourceWriter& fileDefinitions,
- cmWIXSourceWriter& featureDefinitions,
- size_t& directoryCounter,
- size_t& fileCounter,
- const std::vector<std::string>& pkgExecutables,
- std::vector<std::string>& dirIdExecutables)
+ std::string const& topdir,
+ std::string const& directoryId,
+ cmWIXDirectoriesSourceWriter& directoryDefinitions,
+ cmWIXFilesSourceWriter& fileDefinitions,
+ cmWIXFeaturesSourceWriter& featureDefinitions,
+ std::vector<std::string> const& packageExecutables,
+ std::vector<std::string> const& desktopExecutables,
+ cmWIXShortcuts& shortcuts)
{
cmsys::Directory dir;
dir.Load(topdir.c_str());
+ std::string relativeDirectoryPath =
+ cmSystemTools::RelativePath(toplevel.c_str(), topdir.c_str());
+
+ if(relativeDirectoryPath.empty())
+ {
+ relativeDirectoryPath = ".";
+ }
+
+ cmInstalledFile const* directoryInstalledFile = this->GetInstalledFile(
+ this->RelativePathWithoutComponentPrefix(relativeDirectoryPath)
+ );
+
+ bool emptyDirectory = dir.GetNumberOfFiles() == 2;
+ bool createDirectory = false;
+
+ if(emptyDirectory)
+ {
+ createDirectory = true;
+ }
+
+ if(directoryInstalledFile)
+ {
+ if(directoryInstalledFile->HasProperty("CPACK_WIX_ACL"))
+ {
+ createDirectory = true;
+ }
+ }
+
+ if(createDirectory)
+ {
+ std::string componentId = fileDefinitions.EmitComponentCreateFolder(
+ directoryId, GenerateGUID(), directoryInstalledFile);
+ featureDefinitions.EmitComponentRef(componentId);
+ }
+
+ if(emptyDirectory)
+ {
+ return;
+ }
+
for(size_t i = 0; i < dir.GetNumberOfFiles(); ++i)
{
std::string fileName = dir.GetFile(static_cast<unsigned long>(i));
@@ -550,11 +965,14 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons(
std::string fullPath = topdir + "/" + fileName;
+ std::string relativePath = cmSystemTools::RelativePath(
+ toplevel.c_str(), fullPath.c_str());
+
+ std::string id = PathToId(relativePath);
+
if(cmSystemTools::FileIsDirectory(fullPath.c_str()))
{
- std::stringstream tmp;
- tmp << "DIR_ID_" << ++directoryCounter;
- std::string subDirectoryId = tmp.str();
+ std::string subDirectoryId = std::string("CM_D") + id;
directoryDefinitions.BeginElement("Directory");
directoryDefinitions.AddAttribute("Id", subDirectoryId);
@@ -565,55 +983,50 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons(
directoryDefinitions,
fileDefinitions,
featureDefinitions,
- directoryCounter,
- fileCounter,
- pkgExecutables,
- dirIdExecutables);
- directoryDefinitions.EndElement();
+ packageExecutables,
+ desktopExecutables,
+ shortcuts);
+
+ this->Patch->ApplyFragment(subDirectoryId, directoryDefinitions);
+ directoryDefinitions.EndElement("Directory");
}
else
{
- std::stringstream tmp;
- tmp << "_ID_" << ++fileCounter;
- std::string idSuffix = tmp.str();
-
- std::string componentId = std::string("CMP") + idSuffix;
- std::string fileId = std::string("FILE") + idSuffix;
-
- fileDefinitions.BeginElement("DirectoryRef");
- fileDefinitions.AddAttribute("Id", directoryId);
+ cmInstalledFile const* installedFile = this->GetInstalledFile(
+ this->RelativePathWithoutComponentPrefix(relativePath)
+ );
- fileDefinitions.BeginElement("Component");
- fileDefinitions.AddAttribute("Id", componentId);
- fileDefinitions.AddAttribute("Guid", "*");
-
- fileDefinitions.BeginElement("File");
- fileDefinitions.AddAttribute("Id", fileId);
- fileDefinitions.AddAttribute("Source", fullPath);
- fileDefinitions.AddAttribute("KeyPath", "yes");
+ if(installedFile)
+ {
+ shortcuts.CreateFromProperties(id, directoryId, *installedFile);
+ }
- fileDefinitions.EndElement();
- fileDefinitions.EndElement();
- fileDefinitions.EndElement();
+ std::string componentId = fileDefinitions.EmitComponentFile(
+ directoryId, id, fullPath, *(this->Patch), installedFile);
- featureDefinitions.BeginElement("ComponentRef");
- featureDefinitions.AddAttribute("Id", componentId);
- featureDefinitions.EndElement();
+ featureDefinitions.EmitComponentRef(componentId);
- std::vector<std::string>::const_iterator it;
- for (it = pkgExecutables.begin() ;
- it != pkgExecutables.end() ;
- ++it)
+ for(size_t j = 0; j < packageExecutables.size(); ++j)
{
- std::string execName = *it++;
- std::string iconName = *it;
+ std::string const& executableName = packageExecutables[j++];
+ std::string const& textLabel = packageExecutables[j];
- if (cmSystemTools::LowerCase(fileName) ==
- cmSystemTools::LowerCase(execName) + ".exe")
+ if(cmSystemTools::LowerCase(fileName) ==
+ cmSystemTools::LowerCase(executableName) + ".exe")
{
- dirIdExecutables.push_back(fileName);
- dirIdExecutables.push_back(iconName);
- dirIdExecutables.push_back(directoryId);
+ cmWIXShortcut shortcut;
+ shortcut.label= textLabel;
+ shortcut.workingDirectoryId = directoryId;
+ shortcuts.insert(cmWIXShortcuts::START_MENU, id, shortcut);
+
+ if(!desktopExecutables.empty() &&
+ std::find(desktopExecutables.begin(),
+ desktopExecutables.end(),
+ executableName)
+ != desktopExecutables.end())
+ {
+ shortcuts.insert(cmWIXShortcuts::DESKTOP, id, shortcut);
+ }
}
}
}
@@ -621,7 +1034,7 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons(
}
bool cmCPackWIXGenerator::RequireOption(
- const std::string& name, std::string &value) const
+ std::string const& name, std::string &value) const
{
const char* tmp = GetOption(name.c_str());
if(tmp)
@@ -659,22 +1072,23 @@ std::string cmCPackWIXGenerator::GenerateGUID()
UUID guid;
UuidCreate(&guid);
- unsigned char *tmp = 0;
- UuidToString(&guid, &tmp);
+ unsigned short *tmp = 0;
+ UuidToStringW(&guid, &tmp);
- std::string result(reinterpret_cast<char*>(tmp));
- RpcStringFree(&tmp);
+ std::string result =
+ cmsys::Encoding::ToNarrow(reinterpret_cast<wchar_t*>(tmp));
+ RpcStringFreeW(&tmp);
return cmSystemTools::UpperCase(result);
}
-std::string cmCPackWIXGenerator::QuotePath(const std::string& path)
+std::string cmCPackWIXGenerator::QuotePath(std::string const& path)
{
return std::string("\"") + path + '"';
}
std::string cmCPackWIXGenerator::GetRightmostExtension(
- const std::string& filename)
+ std::string const& filename)
{
std::string extension;
@@ -686,3 +1100,159 @@ std::string cmCPackWIXGenerator::GetRightmostExtension(
return cmSystemTools::LowerCase(extension);
}
+
+std::string cmCPackWIXGenerator::PathToId(std::string const& path)
+{
+ id_map_t::const_iterator i = PathToIdMap.find(path);
+ if(i != PathToIdMap.end()) return i->second;
+
+ std::string id = CreateNewIdForPath(path);
+ return id;
+}
+
+std::string cmCPackWIXGenerator::CreateNewIdForPath(std::string const& path)
+{
+ std::vector<std::string> components;
+ cmSystemTools::SplitPath(path.c_str(), components, false);
+
+ size_t replacementCount = 0;
+
+ std::string identifier;
+ std::string currentComponent;
+
+ for(size_t i = 1; i < components.size(); ++i)
+ {
+ if(i != 1) identifier += '.';
+
+ currentComponent = NormalizeComponentForId(
+ components[i], replacementCount);
+
+ identifier += currentComponent;
+ }
+
+ std::string idPrefix = "P";
+ size_t replacementPercent = replacementCount * 100 / identifier.size();
+ if(replacementPercent > 33 || identifier.size() > 60)
+ {
+ identifier = CreateHashedId(path, currentComponent);
+ idPrefix = "H";
+ }
+
+ std::stringstream result;
+ result << idPrefix << "_" << identifier;
+
+ size_t ambiguityCount = ++IdAmbiguityCounter[identifier];
+
+ if(ambiguityCount > 999)
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error while trying to generate a unique Id for '" <<
+ path << "'" << std::endl);
+
+ return std::string();
+ }
+ else if(ambiguityCount > 1)
+ {
+ result << "_" << ambiguityCount;
+ }
+
+ std::string resultString = result.str();
+
+ PathToIdMap[path] = resultString;
+
+ return resultString;
+}
+
+std::string cmCPackWIXGenerator::CreateHashedId(
+ std::string const& path, std::string const& normalizedFilename)
+{
+ cmsys::auto_ptr<cmCryptoHash> sha1 = cmCryptoHash::New("SHA1");
+ std::string hash = sha1->HashString(path.c_str());
+
+ std::string identifier;
+ identifier += hash.substr(0, 7) + "_";
+
+ const size_t maxFileNameLength = 52;
+ if(normalizedFilename.length() > maxFileNameLength)
+ {
+ identifier += normalizedFilename.substr(0, maxFileNameLength - 3);
+ identifier += "...";
+ }
+ else
+ {
+ identifier += normalizedFilename;
+ }
+
+ return identifier;
+}
+
+std::string cmCPackWIXGenerator::NormalizeComponentForId(
+ std::string const& component, size_t& replacementCount)
+{
+ std::string result;
+ result.resize(component.size());
+
+ for(size_t i = 0; i < component.size(); ++i)
+ {
+ char c = component[i];
+ if(IsLegalIdCharacter(c))
+ {
+ result[i] = c;
+ }
+ else
+ {
+ result[i] = '_';
+ ++ replacementCount;
+ }
+ }
+
+ return result;
+}
+
+bool cmCPackWIXGenerator::IsLegalIdCharacter(char c)
+{
+ return (c >= '0' && c <= '9') ||
+ (c >= 'a' && c <= 'z') ||
+ (c >= 'A' && c <= 'Z') ||
+ c == '_' || c == '.';
+}
+
+void cmCPackWIXGenerator::CollectExtensions(
+ std::string const& variableName, extension_set_t& extensions)
+{
+ const char *variableContent = GetOption(variableName.c_str());
+ if(!variableContent) return;
+
+ std::vector<std::string> list;
+ cmSystemTools::ExpandListArgument(variableContent, list);
+ extensions.insert(list.begin(), list.end());
+}
+
+void cmCPackWIXGenerator::AddCustomFlags(
+ std::string const& variableName, std::ostream& stream)
+{
+ const char *variableContent = GetOption(variableName.c_str());
+ if(!variableContent) return;
+
+ std::vector<std::string> list;
+ cmSystemTools::ExpandListArgument(variableContent, list);
+
+ for(std::vector<std::string>::const_iterator i = list.begin();
+ i != list.end(); ++i)
+ {
+ stream << " " << QuotePath(*i);
+ }
+}
+
+std::string cmCPackWIXGenerator::RelativePathWithoutComponentPrefix(
+ std::string const& path)
+{
+ if(this->Components.empty())
+ {
+ return path;
+ }
+
+ std::string::size_type pos = path.find('/');
+
+ return path.substr(pos + 1);
+}
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.h b/Source/CPack/WiX/cmCPackWIXGenerator.h
index aaccf9d46..3f66b2c02 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.h
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.h
@@ -1,6 +1,6 @@
/*============================================================================
CMake - Cross Platform Makefile Generator
- Copyright 2000-2012 Kitware, Inc.
+ Copyright 2012-2015 Kitware, Inc.
Distributed under the OSI-approved BSD License (the "License");
see accompanying file Copyright.txt for details.
@@ -13,12 +13,18 @@
#ifndef cmCPackWIXGenerator_h
#define cmCPackWIXGenerator_h
+#include "cmWIXPatch.h"
+#include "cmWIXShortcut.h"
+
#include <CPack/cmCPackGenerator.h>
#include <string>
#include <map>
class cmWIXSourceWriter;
+class cmWIXDirectoriesSourceWriter;
+class cmWIXFilesSourceWriter;
+class cmWIXFeaturesSourceWriter;
/** \class cmCPackWIXGenerator
* \brief A generator for WIX files
@@ -28,6 +34,9 @@ class cmCPackWIXGenerator : public cmCPackGenerator
public:
cmCPackTypeMacro(cmCPackWIXGenerator, cmCPackGenerator);
+ cmCPackWIXGenerator();
+ ~cmCPackWIXGenerator();
+
protected:
virtual int InitializeInternal();
@@ -50,56 +59,128 @@ protected:
virtual bool SupportsComponentInstallation() const
{
- return false;
+ return true;
}
private:
+ typedef std::map<std::string, std::string> id_map_t;
+ typedef std::map<std::string, size_t> ambiguity_map_t;
+ typedef std::set<std::string> extension_set_t;
+
bool InitializeWiXConfiguration();
bool PackageFilesImpl();
- bool CreateWiXVariablesIncludeFile();
+ void CreateWiXVariablesIncludeFile();
+
+ void CreateWiXPropertiesIncludeFile();
+
+ void CreateWiXProductFragmentIncludeFile();
void CopyDefinition(
- cmWIXSourceWriter &source, const std::string &name);
+ cmWIXSourceWriter &source, std::string const& name);
void AddDefinition(cmWIXSourceWriter& source,
- const std::string& name, const std::string& value);
+ std::string const& name, std::string const& value);
bool CreateWiXSourceFiles();
+ std::string GetProgramFilesFolderId() const;
+
+ bool GenerateMainSourceFileFromTemplate();
+
+ bool CreateFeatureHierarchy(
+ cmWIXFeaturesSourceWriter& featureDefinitions);
+
+ bool AddComponentsToFeature(
+ std::string const& rootPath,
+ std::string const& featureId,
+ cmWIXDirectoriesSourceWriter& directoryDefinitions,
+ cmWIXFilesSourceWriter& fileDefinitions,
+ cmWIXFeaturesSourceWriter& featureDefinitions,
+ cmWIXShortcuts& shortcuts);
+
+ bool CreateShortcuts(
+ std::string const& cpackComponentName,
+ std::string const& featureId,
+ cmWIXShortcuts const& shortcuts,
+ bool emitUninstallShortcut,
+ cmWIXFilesSourceWriter& fileDefinitions,
+ cmWIXFeaturesSourceWriter& featureDefinitions);
+
+ bool CreateShortcutsOfSpecificType(
+ cmWIXShortcuts::Type type,
+ std::string const& cpackComponentName,
+ std::string const& featureId,
+ std::string const& idPrefix,
+ cmWIXShortcuts const& shortcuts,
+ bool emitUninstallShortcut,
+ cmWIXFilesSourceWriter& fileDefinitions,
+ cmWIXFeaturesSourceWriter& featureDefinitions);
+
+ void AppendUserSuppliedExtraSources();
+
+ void AppendUserSuppliedExtraObjects(std::ostream& stream);
+
bool CreateLicenseFile();
- bool RunWiXCommand(const std::string& command);
+ bool RunWiXCommand(std::string const& command);
bool RunCandleCommand(
- const std::string& sourceFile, const std::string& objectFile);
-
- bool RunLightCommand(const std::string& objectFiles);
+ std::string const& sourceFile, std::string const& objectFile);
- void AddDirectoryAndFileDefinitons(const std::string& topdir,
- const std::string& directoryId,
- cmWIXSourceWriter& directoryDefinitions,
- cmWIXSourceWriter& fileDefinitions,
- cmWIXSourceWriter& featureDefinitions,
- size_t& directoryCounter,
- size_t& fileCounter,
- const std::vector<std::string>& pkgExecutables,
- std::vector<std::string>& dirIdExecutables
- );
+ bool RunLightCommand(std::string const& objectFiles);
+ void AddDirectoryAndFileDefinitons(std::string const& topdir,
+ std::string const& directoryId,
+ cmWIXDirectoriesSourceWriter& directoryDefinitions,
+ cmWIXFilesSourceWriter& fileDefinitions,
+ cmWIXFeaturesSourceWriter& featureDefinitions,
+ std::vector<std::string> const& packageExecutables,
+ std::vector<std::string> const& desktopExecutables,
+ cmWIXShortcuts& shortcuts);
- bool RequireOption(const std::string& name, std::string& value) const;
+ bool RequireOption(std::string const& name, std::string& value) const;
std::string GetArchitecture() const;
static std::string GenerateGUID();
- static std::string QuotePath(const std::string& path);
+ static std::string QuotePath(std::string const& path);
+
+ static std::string GetRightmostExtension(std::string const& filename);
+
+ std::string PathToId(std::string const& path);
+
+ std::string CreateNewIdForPath(std::string const& path);
+
+ static std::string CreateHashedId(
+ std::string const& path, std::string const& normalizedFilename);
+
+ std::string NormalizeComponentForId(
+ std::string const& component, size_t& replacementCount);
+
+ static bool IsLegalIdCharacter(char c);
+
+ void CollectExtensions(
+ std::string const& variableName, extension_set_t& extensions);
+
+ void AddCustomFlags(
+ std::string const& variableName, std::ostream& stream);
+
+ std::string RelativePathWithoutComponentPrefix(
+ std::string const& path);
+
+ std::vector<std::string> WixSources;
+ id_map_t PathToIdMap;
+ ambiguity_map_t IdAmbiguityCounter;
+
+ extension_set_t CandleExtensions;
+ extension_set_t LightExtensions;
- static std::string GetRightmostExtension(const std::string& filename);
+ std::string CPackTopLevel;
- std::vector<std::string> wixSources;
+ cmWIXPatch* Patch;
};
#endif
diff --git a/Source/CPack/WiX/cmWIXAccessControlList.cxx b/Source/CPack/WiX/cmWIXAccessControlList.cxx
new file mode 100644
index 000000000..fc0d3d37a
--- /dev/null
+++ b/Source/CPack/WiX/cmWIXAccessControlList.cxx
@@ -0,0 +1,149 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmWIXAccessControlList.h"
+
+#include <CPack/cmCPackGenerator.h>
+
+#include <cmSystemTools.h>
+
+cmWIXAccessControlList::cmWIXAccessControlList(
+ cmCPackLog *logger,
+ cmInstalledFile const& installedFile,
+ cmWIXSourceWriter &sourceWriter):
+ Logger(logger),
+ InstalledFile(installedFile),
+ SourceWriter(sourceWriter)
+{
+
+}
+
+bool cmWIXAccessControlList::Apply()
+{
+ std::vector<std::string> entries;
+ this->InstalledFile.GetPropertyAsList("CPACK_WIX_ACL", entries);
+
+ for(size_t i = 0; i < entries.size(); ++i)
+ {
+ this->CreatePermissionElement(entries[i]);
+ }
+
+ return true;
+}
+
+void cmWIXAccessControlList::CreatePermissionElement(
+ std::string const& entry)
+{
+ std::string::size_type pos = entry.find('=');
+ if(pos == std::string::npos)
+ {
+ this->ReportError(entry, "Did not find mandatory '='");
+ return;
+ }
+
+ std::string user_and_domain = entry.substr(0, pos);
+ std::string permission_string = entry.substr(pos + 1);
+
+ pos = user_and_domain.find('@');
+ std::string user;
+ std::string domain;
+ if(pos != std::string::npos)
+ {
+ user = user_and_domain.substr(0, pos);
+ domain = user_and_domain.substr(pos + 1);
+ }
+ else
+ {
+ user = user_and_domain;
+ }
+
+ std::vector<std::string> permissions =
+ cmSystemTools::tokenize(permission_string, ",");
+
+ this->SourceWriter.BeginElement("Permission");
+ this->SourceWriter.AddAttribute("User", user);
+ if(!domain.empty())
+ {
+ this->SourceWriter.AddAttribute("Domain", domain);
+ }
+ for(size_t i = 0; i < permissions.size(); ++i)
+ {
+ this->EmitBooleanAttribute(entry,
+ cmSystemTools::TrimWhitespace(permissions[i]));
+ }
+ this->SourceWriter.EndElement("Permission");
+}
+
+void cmWIXAccessControlList::ReportError(
+ std::string const& entry,
+ std::string const& message)
+{
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Failed processing ACL entry '" << entry <<
+ "': " << message << std::endl);
+}
+
+bool cmWIXAccessControlList::IsBooleanAttribute(std::string const& name)
+{
+ static const char* validAttributes[] =
+ {
+ "Append",
+ "ChangePermission",
+ "CreateChild",
+ "CreateFile",
+ "CreateLink",
+ "CreateSubkeys",
+ "Delete",
+ "DeleteChild",
+ "EnumerateSubkeys",
+ "Execute",
+ "FileAllRights",
+ "GenericAll",
+ "GenericExecute",
+ "GenericRead",
+ "GenericWrite",
+ "Notify",
+ "Read",
+ "ReadAttributes",
+ "ReadExtendedAttributes",
+ "ReadPermission",
+ "SpecificRightsAll",
+ "Synchronize",
+ "TakeOwnership",
+ "Traverse",
+ "Write",
+ "WriteAttributes",
+ "WriteExtendedAttributes",
+ 0
+ };
+
+ size_t i = 0;
+ while(validAttributes[i])
+ {
+ if(name == validAttributes[i++]) return true;
+ }
+
+ return false;
+}
+
+void cmWIXAccessControlList::EmitBooleanAttribute(
+ std::string const& entry, std::string const& name)
+{
+ if(!this->IsBooleanAttribute(name))
+ {
+ std::stringstream message;
+ message << "Unknown boolean attribute '" << name << "'";
+ this->ReportError(entry, message.str());
+ }
+
+ this->SourceWriter.AddAttribute(name, "yes");
+}
diff --git a/Source/CPack/WiX/cmWIXAccessControlList.h b/Source/CPack/WiX/cmWIXAccessControlList.h
new file mode 100644
index 000000000..20902f768
--- /dev/null
+++ b/Source/CPack/WiX/cmWIXAccessControlList.h
@@ -0,0 +1,46 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmWIXAccessControlList_h
+#define cmWIXAccessControlList_h
+
+#include <cmInstalledFile.h>
+#include <CPack/cmCPackLog.h>
+
+#include "cmWIXSourceWriter.h"
+
+class cmWIXAccessControlList
+{
+public:
+ cmWIXAccessControlList(
+ cmCPackLog *logger,
+ cmInstalledFile const& installedFile,
+ cmWIXSourceWriter &sourceWriter);
+
+ bool Apply();
+
+private:
+ void CreatePermissionElement(std::string const& entry);
+
+ void ReportError(std::string const& entry, std::string const& message);
+
+ bool IsBooleanAttribute(std::string const& name);
+
+ void EmitBooleanAttribute(
+ std::string const& entry, std::string const& name);
+
+ cmCPackLog* Logger;
+ cmInstalledFile const& InstalledFile;
+ cmWIXSourceWriter &SourceWriter;
+};
+
+#endif
diff --git a/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx
new file mode 100644
index 000000000..7bd4315e5
--- /dev/null
+++ b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx
@@ -0,0 +1,95 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmWIXDirectoriesSourceWriter.h"
+
+cmWIXDirectoriesSourceWriter::cmWIXDirectoriesSourceWriter(cmCPackLog* logger,
+ std::string const& filename):
+ cmWIXSourceWriter(logger, filename)
+{
+
+}
+
+void cmWIXDirectoriesSourceWriter::EmitStartMenuFolder(
+ std::string const& startMenuFolder)
+{
+ BeginElement("Directory");
+ AddAttribute("Id", "ProgramMenuFolder");
+
+ BeginElement("Directory");
+ AddAttribute("Id", "PROGRAM_MENU_FOLDER");
+ AddAttribute("Name", startMenuFolder);
+ EndElement("Directory");
+
+ EndElement("Directory");
+}
+
+void cmWIXDirectoriesSourceWriter::EmitDesktopFolder()
+{
+ BeginElement("Directory");
+ AddAttribute("Id", "DesktopFolder");
+ AddAttribute("Name", "Desktop");
+ EndElement("Directory");
+}
+
+void cmWIXDirectoriesSourceWriter::EmitStartupFolder()
+{
+ BeginElement("Directory");
+ AddAttribute("Id", "StartupFolder");
+ AddAttribute("Name", "Startup");
+ EndElement("Directory");
+}
+
+size_t cmWIXDirectoriesSourceWriter::BeginInstallationPrefixDirectory(
+ std::string const& programFilesFolderId,
+ std::string const& installRootString)
+{
+ BeginElement("Directory");
+ AddAttribute("Id", programFilesFolderId);
+
+ std::vector<std::string> installRoot;
+
+ cmSystemTools::SplitPath(installRootString.c_str(), installRoot);
+
+ if(!installRoot.empty() && installRoot.back().empty())
+ {
+ installRoot.pop_back();
+ }
+
+ for(size_t i = 1; i < installRoot.size(); ++i)
+ {
+ BeginElement("Directory");
+
+ if(i == installRoot.size() - 1)
+ {
+ AddAttribute("Id", "INSTALL_ROOT");
+ }
+ else
+ {
+ std::stringstream tmp;
+ tmp << "INSTALL_PREFIX_" << i;
+ AddAttribute("Id", tmp.str());
+ }
+
+ AddAttribute("Name", installRoot[i]);
+ }
+
+ return installRoot.size();
+}
+
+void cmWIXDirectoriesSourceWriter::EndInstallationPrefixDirectory(size_t size)
+{
+ for(size_t i = 0; i < size; ++i)
+ {
+ EndElement("Directory");
+ }
+}
diff --git a/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.h b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.h
new file mode 100644
index 000000000..f8c816640
--- /dev/null
+++ b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.h
@@ -0,0 +1,44 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmWIXDirectoriesSourceWriter_h
+#define cmWIXDirectoriesSourceWriter_h
+
+#include "cmWIXSourceWriter.h"
+
+#include <CPack/cmCPackGenerator.h>
+
+#include <string>
+
+/** \class cmWIXDirectoriesSourceWriter
+ * \brief Helper class to generate directories.wxs
+ */
+class cmWIXDirectoriesSourceWriter : public cmWIXSourceWriter
+{
+public:
+ cmWIXDirectoriesSourceWriter(cmCPackLog* logger,
+ std::string const& filename);
+
+ void EmitStartMenuFolder(std::string const& startMenuFolder);
+
+ void EmitDesktopFolder();
+
+ void EmitStartupFolder();
+
+ size_t BeginInstallationPrefixDirectory(
+ std::string const& programFilesFolderId,
+ std::string const& installRootString);
+
+ void EndInstallationPrefixDirectory(size_t size);
+};
+
+#endif
diff --git a/Source/CPack/WiX/cmWIXFeaturesSourceWriter.cxx b/Source/CPack/WiX/cmWIXFeaturesSourceWriter.cxx
new file mode 100644
index 000000000..0bcfc389f
--- /dev/null
+++ b/Source/CPack/WiX/cmWIXFeaturesSourceWriter.cxx
@@ -0,0 +1,102 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmWIXFeaturesSourceWriter.h"
+
+cmWIXFeaturesSourceWriter::cmWIXFeaturesSourceWriter(cmCPackLog* logger,
+ std::string const& filename):
+ cmWIXSourceWriter(logger, filename)
+{
+
+}
+
+void cmWIXFeaturesSourceWriter::CreateCMakePackageRegistryEntry(
+ std::string const& package,
+ std::string const& upgradeGuid)
+{
+ BeginElement("Component");
+ AddAttribute("Id", "CM_PACKAGE_REGISTRY");
+ AddAttribute("Directory", "TARGETDIR");
+ AddAttribute("Guid", "*");
+
+ std::string registryKey =
+ std::string("Software\\Kitware\\CMake\\Packages\\") + package;
+
+ BeginElement("RegistryValue");
+ AddAttribute("Root", "HKLM");
+ AddAttribute("Key", registryKey);
+ AddAttribute("Name", upgradeGuid);
+ AddAttribute("Type", "string");
+ AddAttribute("Value", "[INSTALL_ROOT]");
+ AddAttribute("KeyPath", "yes");
+ EndElement("RegistryValue");
+
+ EndElement("Component");
+}
+
+void cmWIXFeaturesSourceWriter::EmitFeatureForComponentGroup(
+ cmCPackComponentGroup const& group)
+{
+ BeginElement("Feature");
+ AddAttribute("Id", "CM_G_" + group.Name);
+
+ if(group.IsExpandedByDefault)
+ {
+ AddAttribute("Display", "expand");
+ }
+
+ AddAttributeUnlessEmpty("Title", group.DisplayName);
+ AddAttributeUnlessEmpty("Description", group.Description);
+
+ for(std::vector<cmCPackComponentGroup*>::const_iterator
+ i = group.Subgroups.begin(); i != group.Subgroups.end(); ++i)
+ {
+ EmitFeatureForComponentGroup(**i);
+ }
+
+ for(std::vector<cmCPackComponent*>::const_iterator
+ i = group.Components.begin(); i != group.Components.end(); ++i)
+ {
+ EmitFeatureForComponent(**i);
+ }
+
+ EndElement("Feature");
+}
+
+void cmWIXFeaturesSourceWriter::EmitFeatureForComponent(
+ cmCPackComponent const& component)
+{
+ BeginElement("Feature");
+ AddAttribute("Id", "CM_C_" + component.Name);
+
+ AddAttributeUnlessEmpty("Title", component.DisplayName);
+ AddAttributeUnlessEmpty("Description", component.Description);
+
+ if(component.IsRequired)
+ {
+ AddAttribute("Absent", "disallow");
+ }
+
+ if(component.IsHidden)
+ {
+ AddAttribute("Display", "hidden");
+ }
+
+ EndElement("Feature");
+}
+
+void cmWIXFeaturesSourceWriter::EmitComponentRef(std::string const& id)
+{
+ BeginElement("ComponentRef");
+ AddAttribute("Id", id);
+ EndElement("ComponentRef");
+}
diff --git a/Source/CPack/WiX/cmWIXFeaturesSourceWriter.h b/Source/CPack/WiX/cmWIXFeaturesSourceWriter.h
new file mode 100644
index 000000000..767041755
--- /dev/null
+++ b/Source/CPack/WiX/cmWIXFeaturesSourceWriter.h
@@ -0,0 +1,39 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmWIXFeaturesSourceWriter_h
+#define cmWIXFeaturesSourceWriter_h
+
+#include "cmWIXSourceWriter.h"
+#include <CPack/cmCPackGenerator.h>
+
+/** \class cmWIXFeaturesSourceWriter
+ * \brief Helper class to generate features.wxs
+ */
+class cmWIXFeaturesSourceWriter : public cmWIXSourceWriter
+{
+public:
+ cmWIXFeaturesSourceWriter(cmCPackLog* logger,
+ std::string const& filename);
+
+ void CreateCMakePackageRegistryEntry(
+ std::string const& package,
+ std::string const& upgradeGuid);
+
+ void EmitFeatureForComponentGroup(const cmCPackComponentGroup& group);
+
+ void EmitFeatureForComponent(const cmCPackComponent& component);
+
+ void EmitComponentRef(std::string const& id);
+};
+
+#endif
diff --git a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
new file mode 100644
index 000000000..d4698a764
--- /dev/null
+++ b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
@@ -0,0 +1,183 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014-2015 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmWIXFilesSourceWriter.h"
+#include "cmWIXAccessControlList.h"
+
+#include <cmInstalledFile.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+cmWIXFilesSourceWriter::cmWIXFilesSourceWriter(cmCPackLog* logger,
+ std::string const& filename):
+ cmWIXSourceWriter(logger, filename)
+{
+
+}
+
+void cmWIXFilesSourceWriter::EmitShortcut(
+ std::string const& id,
+ cmWIXShortcut const& shortcut,
+ std::string const& shortcutPrefix,
+ size_t shortcutIndex)
+{
+ std::stringstream shortcutId;
+ shortcutId << shortcutPrefix << id;
+
+ if(shortcutIndex > 0)
+ {
+ shortcutId << "_" << shortcutIndex;
+ }
+
+ std::string fileId = std::string("CM_F") + id;
+
+ BeginElement("Shortcut");
+ AddAttribute("Id", shortcutId.str());
+ AddAttribute("Name", shortcut.label);
+ std::string target = "[#" + fileId + "]";
+ AddAttribute("Target", target);
+ AddAttribute("WorkingDirectory", shortcut.workingDirectoryId);
+ EndElement("Shortcut");
+}
+
+void cmWIXFilesSourceWriter::EmitRemoveFolder(std::string const& id)
+{
+ BeginElement("RemoveFolder");
+ AddAttribute("Id", id);
+ AddAttribute("On", "uninstall");
+ EndElement("RemoveFolder");
+}
+
+void cmWIXFilesSourceWriter::EmitInstallRegistryValue(
+ std::string const& registryKey,
+ std::string const& cpackComponentName,
+ std::string const& suffix)
+{
+ std::string valueName;
+ if(!cpackComponentName.empty())
+ {
+ valueName = cpackComponentName + "_";
+ }
+
+ valueName += "installed";
+ valueName += suffix;
+
+ BeginElement("RegistryValue");
+ AddAttribute("Root", "HKCU");
+ AddAttribute("Key", registryKey);
+ AddAttribute("Name", valueName);
+ AddAttribute("Type", "integer");
+ AddAttribute("Value", "1");
+ AddAttribute("KeyPath", "yes");
+ EndElement("RegistryValue");
+}
+
+void cmWIXFilesSourceWriter::EmitUninstallShortcut(
+ std::string const& packageName)
+{
+ BeginElement("Shortcut");
+ AddAttribute("Id", "UNINSTALL");
+ AddAttribute("Name", "Uninstall " + packageName);
+ AddAttribute("Description", "Uninstalls " + packageName);
+ AddAttribute("Target", "[SystemFolder]msiexec.exe");
+ AddAttribute("Arguments", "/x [ProductCode]");
+ EndElement("Shortcut");
+}
+
+std::string cmWIXFilesSourceWriter::EmitComponentCreateFolder(
+ std::string const& directoryId,
+ std::string const& guid,
+ cmInstalledFile const* installedFile)
+{
+ std::string componentId =
+ std::string("CM_C_EMPTY_") + directoryId;
+
+ BeginElement("DirectoryRef");
+ AddAttribute("Id", directoryId);
+
+ BeginElement("Component");
+ AddAttribute("Id", componentId);
+ AddAttribute("Guid", guid);
+
+ BeginElement("CreateFolder");
+
+ if(installedFile)
+ {
+ cmWIXAccessControlList acl(Logger, *installedFile, *this);
+ acl.Apply();
+ }
+
+ EndElement("CreateFolder");
+ EndElement("Component");
+ EndElement("DirectoryRef");
+
+ return componentId;
+}
+
+std::string cmWIXFilesSourceWriter::EmitComponentFile(
+ std::string const& directoryId,
+ std::string const& id,
+ std::string const& filePath,
+ cmWIXPatch &patch,
+ cmInstalledFile const* installedFile)
+{
+ std::string componentId = std::string("CM_C") + id;
+ std::string fileId = std::string("CM_F") + id;
+
+ BeginElement("DirectoryRef");
+ AddAttribute("Id", directoryId);
+
+ BeginElement("Component");
+ AddAttribute("Id", componentId);
+ AddAttribute("Guid", "*");
+
+ if(installedFile)
+ {
+ if(installedFile->GetPropertyAsBool("CPACK_NEVER_OVERWRITE"))
+ {
+ AddAttribute("NeverOverwrite", "yes");
+ }
+ if(installedFile->GetPropertyAsBool("CPACK_PERMANENT"))
+ {
+ AddAttribute("Permanent", "yes");
+ }
+ }
+
+ BeginElement("File");
+ AddAttribute("Id", fileId);
+ AddAttribute("Source", filePath);
+ AddAttribute("KeyPath", "yes");
+
+ mode_t fileMode = 0;
+ cmSystemTools::GetPermissions(filePath.c_str(), fileMode);
+
+ if(!(fileMode & S_IWRITE))
+ {
+ AddAttribute("ReadOnly", "yes");
+ }
+
+ if(installedFile)
+ {
+ cmWIXAccessControlList acl(Logger, *installedFile, *this);
+ acl.Apply();
+ }
+
+ patch.ApplyFragment(fileId, *this);
+ EndElement("File");
+
+ patch.ApplyFragment(componentId, *this);
+ EndElement("Component");
+ EndElement("DirectoryRef");
+
+ return componentId;
+}
diff --git a/Source/CPack/WiX/cmWIXFilesSourceWriter.h b/Source/CPack/WiX/cmWIXFilesSourceWriter.h
new file mode 100644
index 000000000..c48bc15ba
--- /dev/null
+++ b/Source/CPack/WiX/cmWIXFilesSourceWriter.h
@@ -0,0 +1,60 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014-2015 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmWIXFilesSourceWriter_h
+#define cmWIXFilesSourceWriter_h
+
+#include "cmWIXSourceWriter.h"
+#include "cmWIXShortcut.h"
+#include "cmWIXPatch.h"
+
+#include <CPack/cmCPackGenerator.h>
+
+/** \class cmWIXFilesSourceWriter
+ * \brief Helper class to generate files.wxs
+ */
+class cmWIXFilesSourceWriter : public cmWIXSourceWriter
+{
+public:
+ cmWIXFilesSourceWriter(cmCPackLog* logger,
+ std::string const& filename);
+
+ void EmitShortcut(
+ std::string const& id,
+ cmWIXShortcut const& shortcut,
+ std::string const& shortcutPrefix,
+ size_t shortcutIndex);
+
+ void EmitRemoveFolder(std::string const& id);
+
+ void EmitInstallRegistryValue(
+ std::string const& registryKey,
+ std::string const& cpackComponentName,
+ std::string const& suffix);
+
+ void EmitUninstallShortcut(std::string const& packageName);
+
+ std::string EmitComponentCreateFolder(
+ std::string const& directoryId,
+ std::string const& guid,
+ cmInstalledFile const* installedFile);
+
+ std::string EmitComponentFile(
+ std::string const& directoryId,
+ std::string const& id,
+ std::string const& filePath,
+ cmWIXPatch &patch,
+ cmInstalledFile const* installedFile);
+};
+
+
+#endif
diff --git a/Source/CPack/WiX/cmWIXPatch.cxx b/Source/CPack/WiX/cmWIXPatch.cxx
new file mode 100644
index 000000000..07375da10
--- /dev/null
+++ b/Source/CPack/WiX/cmWIXPatch.cxx
@@ -0,0 +1,111 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmWIXPatch.h"
+
+#include <CPack/cmCPackGenerator.h>
+
+cmWIXPatch::cmWIXPatch(cmCPackLog* logger):
+ Logger(logger)
+{
+
+}
+
+bool cmWIXPatch::LoadFragments(std::string const& patchFilePath)
+{
+ cmWIXPatchParser parser(Fragments, Logger);
+ if(!parser.ParseFile(patchFilePath.c_str()))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Failed parsing XML patch file: '" <<
+ patchFilePath << "'" << std::endl);
+ return false;
+ }
+
+ return true;
+}
+
+void cmWIXPatch::ApplyFragment(
+ std::string const& id, cmWIXSourceWriter& writer)
+{
+ cmWIXPatchParser::fragment_map_t::iterator i = Fragments.find(id);
+ if(i == Fragments.end()) return;
+
+ const cmWIXPatchElement& fragment = i->second;
+
+ this->ApplyElementChildren(fragment, writer);
+
+ Fragments.erase(i);
+}
+
+void cmWIXPatch::ApplyElementChildren(
+ const cmWIXPatchElement& element, cmWIXSourceWriter& writer)
+{
+ for(cmWIXPatchElement::child_list_t::const_iterator
+ j = element.children.begin(); j != element.children.end(); ++j)
+ {
+ cmWIXPatchNode *node = *j;
+
+ switch(node->type())
+ {
+ case cmWIXPatchNode::ELEMENT:
+ ApplyElement(dynamic_cast<const cmWIXPatchElement&>(*node), writer);
+ break;
+ case cmWIXPatchNode::TEXT:
+ writer.AddTextNode(dynamic_cast<const cmWIXPatchText&>(*node).text);
+ break;
+ }
+ }
+}
+
+void cmWIXPatch::ApplyElement(
+ const cmWIXPatchElement& element, cmWIXSourceWriter& writer)
+{
+ writer.BeginElement(element.name);
+
+ for(cmWIXPatchElement::attributes_t::const_iterator
+ i = element.attributes.begin(); i != element.attributes.end(); ++i)
+ {
+ writer.AddAttribute(i->first, i->second);
+ }
+
+ this->ApplyElementChildren(element, writer);
+
+ writer.EndElement(element.name);
+}
+
+bool cmWIXPatch::CheckForUnappliedFragments()
+{
+ std::string fragmentList;
+ for(cmWIXPatchParser::fragment_map_t::const_iterator
+ i = Fragments.begin(); i != Fragments.end(); ++i)
+ {
+ if(!fragmentList.empty())
+ {
+ fragmentList += ", ";
+ }
+
+ fragmentList += "'";
+ fragmentList += i->first;
+ fragmentList += "'";
+ }
+
+ if(!fragmentList.empty())
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Some XML patch fragments did not have matching IDs: " <<
+ fragmentList << std::endl);
+ return false;
+ }
+
+ return true;
+}
diff --git a/Source/CPack/WiX/cmWIXPatch.h b/Source/CPack/WiX/cmWIXPatch.h
new file mode 100644
index 000000000..2f31a013e
--- /dev/null
+++ b/Source/CPack/WiX/cmWIXPatch.h
@@ -0,0 +1,48 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmWIXPatch_h
+#define cmWIXPatch_h
+
+#include "cmWIXSourceWriter.h"
+#include "cmWIXPatchParser.h"
+
+#include <string>
+
+/** \class cmWIXPatch
+ * \brief Class that maintains and applies patch fragments
+ */
+class cmWIXPatch
+{
+public:
+ cmWIXPatch(cmCPackLog* logger);
+
+ bool LoadFragments(std::string const& patchFilePath);
+
+ void ApplyFragment(std::string const& id, cmWIXSourceWriter& writer);
+
+ bool CheckForUnappliedFragments();
+
+private:
+ void ApplyElementChildren(const cmWIXPatchElement& element,
+ cmWIXSourceWriter& writer);
+
+ void ApplyElement(const cmWIXPatchElement& element,
+ cmWIXSourceWriter& writer);
+
+ cmCPackLog* Logger;
+
+ cmWIXPatchParser::fragment_map_t Fragments;
+};
+
+
+#endif
diff --git a/Source/CPack/WiX/cmWIXPatchParser.cxx b/Source/CPack/WiX/cmWIXPatchParser.cxx
new file mode 100644
index 000000000..14c5413bc
--- /dev/null
+++ b/Source/CPack/WiX/cmWIXPatchParser.cxx
@@ -0,0 +1,181 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2013 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmWIXPatchParser.h"
+
+#include <CPack/cmCPackGenerator.h>
+
+#include <cm_expat.h>
+
+cmWIXPatchNode::Type cmWIXPatchText::type()
+{
+ return cmWIXPatchNode::TEXT;
+}
+
+cmWIXPatchNode::Type cmWIXPatchElement::type()
+{
+ return cmWIXPatchNode::ELEMENT;
+}
+
+cmWIXPatchNode::~cmWIXPatchNode()
+{
+
+}
+
+cmWIXPatchElement::~cmWIXPatchElement()
+{
+ for(child_list_t::iterator i = children.begin(); i != children.end(); ++i)
+ {
+ delete *i;
+ }
+}
+
+cmWIXPatchParser::cmWIXPatchParser(
+ fragment_map_t& fragments, cmCPackLog* logger):
+ Logger(logger),
+ State(BEGIN_DOCUMENT),
+ Valid(true),
+ Fragments(fragments)
+{
+
+}
+
+void cmWIXPatchParser::StartElement(const std::string& name, const char **atts)
+{
+ if(State == BEGIN_DOCUMENT)
+ {
+ if(name == "CPackWiXPatch")
+ {
+ State = BEGIN_FRAGMENTS;
+ }
+ else
+ {
+ ReportValidationError("Expected root element 'CPackWiXPatch'");
+ }
+ }
+ else if(State == BEGIN_FRAGMENTS)
+ {
+ if(name == "CPackWiXFragment")
+ {
+ State = INSIDE_FRAGMENT;
+ StartFragment(atts);
+ }
+ else
+ {
+ ReportValidationError("Expected 'CPackWixFragment' element");
+ }
+ }
+ else if(State == INSIDE_FRAGMENT)
+ {
+ cmWIXPatchElement &parent = *ElementStack.back();
+
+ cmWIXPatchElement *element = new cmWIXPatchElement;
+ parent.children.push_back(element);
+
+ element->name = name;
+
+ for(size_t i = 0; atts[i]; i += 2)
+ {
+ std::string key = atts[i];
+ std::string value = atts[i+1];
+
+ element->attributes[key] = value;
+ }
+
+ ElementStack.push_back(element);
+ }
+}
+
+void cmWIXPatchParser::StartFragment(const char **attributes)
+{
+ for(size_t i = 0; attributes[i]; i += 2)
+ {
+ std::string key = attributes[i];
+ std::string value = attributes[i+1];
+
+ if(key == "Id")
+ {
+ if(Fragments.find(value) != Fragments.end())
+ {
+ std::stringstream tmp;
+ tmp << "Invalid reuse of 'CPackWixFragment' 'Id': " << value;
+ ReportValidationError(tmp.str());
+ }
+
+ ElementStack.push_back(&Fragments[value]);
+ }
+ else
+ {
+ ReportValidationError(
+ "The only allowed 'CPackWixFragment' attribute is 'Id'");
+ }
+ }
+}
+
+void cmWIXPatchParser::EndElement(const std::string& name)
+{
+ if(State == INSIDE_FRAGMENT)
+ {
+ if(name == "CPackWiXFragment")
+ {
+ State = BEGIN_FRAGMENTS;
+ ElementStack.clear();
+ }
+ else
+ {
+ ElementStack.pop_back();
+ }
+ }
+}
+
+void cmWIXPatchParser::CharacterDataHandler(const char* data, int length)
+{
+ const char* whitespace = "\x20\x09\x0d\x0a";
+
+ if(State == INSIDE_FRAGMENT)
+ {
+ cmWIXPatchElement &parent = *ElementStack.back();
+
+ std::string text(data, length);
+
+ std::string::size_type first = text.find_first_not_of(whitespace);
+ std::string::size_type last = text.find_last_not_of(whitespace);
+
+ if(first != std::string::npos && last != std::string::npos)
+ {
+ cmWIXPatchText *text_node = new cmWIXPatchText;
+ text_node->text = text.substr(first, last - first + 1);
+
+ parent.children.push_back(text_node);
+ }
+ }
+}
+
+void cmWIXPatchParser::ReportError(int line, int column, const char* msg)
+{
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error while processing XML patch file at " << line << ":" << column <<
+ ": "<< msg << std::endl);
+ Valid = false;
+}
+
+void cmWIXPatchParser::ReportValidationError(std::string const& message)
+{
+ ReportError(XML_GetCurrentLineNumber(static_cast<XML_Parser>(this->Parser)),
+ XML_GetCurrentColumnNumber(static_cast<XML_Parser>(this->Parser)),
+ message.c_str());
+}
+
+bool cmWIXPatchParser::IsValid() const
+{
+ return Valid;
+}
diff --git a/Source/CPack/WiX/cmWIXPatchParser.h b/Source/CPack/WiX/cmWIXPatchParser.h
new file mode 100644
index 000000000..acaeae364
--- /dev/null
+++ b/Source/CPack/WiX/cmWIXPatchParser.h
@@ -0,0 +1,100 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2013 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmCPackWIXPatchParser_h
+#define cmCPackWIXPatchParser_h
+
+#include <cmXMLParser.h>
+
+#include <CPack/cmCPackLog.h>
+
+#include <map>
+#include <list>
+
+struct cmWIXPatchNode
+{
+ enum Type
+ {
+ TEXT,
+ ELEMENT
+ };
+
+ virtual ~cmWIXPatchNode();
+
+ virtual Type type() = 0;
+};
+
+struct cmWIXPatchText : public cmWIXPatchNode
+{
+ virtual Type type();
+
+ std::string text;
+};
+
+struct cmWIXPatchElement : cmWIXPatchNode
+{
+ virtual Type type();
+
+ ~cmWIXPatchElement();
+
+ typedef std::list<cmWIXPatchNode*> child_list_t;
+ typedef std::map<std::string, std::string> attributes_t;
+
+ std::string name;
+ child_list_t children;
+ attributes_t attributes;
+};
+
+/** \class cmWIXPatchParser
+ * \brief Helper class that parses XML patch files (CPACK_WIX_PATCH_FILE)
+ */
+class cmWIXPatchParser : public cmXMLParser
+{
+public:
+ typedef std::map<std::string, cmWIXPatchElement> fragment_map_t;
+
+ cmWIXPatchParser(fragment_map_t& Fragments, cmCPackLog* logger);
+
+private:
+ virtual void StartElement(const std::string& name, const char **atts);
+
+ void StartFragment(const char **attributes);
+
+ virtual void EndElement(const std::string& name);
+
+ virtual void CharacterDataHandler(const char* data, int length);
+
+ virtual void ReportError(int line, int column, const char* msg);
+
+ void ReportValidationError(std::string const& message);
+
+ bool IsValid() const;
+
+ cmCPackLog* Logger;
+
+ enum ParserState
+ {
+ BEGIN_DOCUMENT,
+ BEGIN_FRAGMENTS,
+ INSIDE_FRAGMENT
+ };
+
+ ParserState State;
+
+ bool Valid;
+
+ fragment_map_t& Fragments;
+
+ std::list<cmWIXPatchElement*> ElementStack;
+};
+
+#endif
diff --git a/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx b/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx
index 774c22c76..f27caa941 100644
--- a/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx
+++ b/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx
@@ -15,8 +15,8 @@
#include <cmVersion.h>
cmWIXRichTextFormatWriter::cmWIXRichTextFormatWriter(
- const std::string& filename):
- file(filename.c_str(), std::ios::binary)
+ std::string const& filename):
+ File(filename.c_str(), std::ios::binary)
{
StartGroup();
WriteHeader();
@@ -29,11 +29,11 @@ cmWIXRichTextFormatWriter::~cmWIXRichTextFormatWriter()
/* I haven't seen this in the RTF spec but
* wordpad terminates its RTF like this */
- file << "\r\n";
- file.put(0);
+ File << "\r\n";
+ File.put(0);
}
-void cmWIXRichTextFormatWriter::AddText(const std::string& text)
+void cmWIXRichTextFormatWriter::AddText(std::string const& text)
{
typedef unsigned char rtf_byte_t;
@@ -44,16 +44,16 @@ void cmWIXRichTextFormatWriter::AddText(const std::string& text)
switch(c)
{
case '\\':
- file << "\\\\";
+ File << "\\\\";
break;
case '{':
- file << "\\{";
+ File << "\\{";
break;
case '}':
- file << "\\}";
+ File << "\\}";
break;
case '\n':
- file << "\\par\r\n";
+ File << "\\par\r\n";
break;
case '\r':
continue;
@@ -61,11 +61,45 @@ void cmWIXRichTextFormatWriter::AddText(const std::string& text)
{
if(c <= 0x7F)
{
- file << c;
+ File << c;
}
else
{
- file << "[NON-ASCII-" << int(c) << "]";
+ if(c <= 0xC0)
+ {
+ EmitInvalidCodepoint(c);
+ }
+ else if(c < 0xE0 && i+1 < text.size())
+ {
+ EmitUnicodeCodepoint(
+ (text[i+1] & 0x3F) |
+ ((c & 0x1F) << 6)
+ );
+ i+= 1;
+ }
+ else if(c < 0xF0 && i+2 < text.size())
+ {
+ EmitUnicodeCodepoint(
+ (text[i+2] & 0x3F) |
+ ((text[i+1] & 0x3F) << 6) |
+ ((c & 0xF) << 12)
+ );
+ i += 2;
+ }
+ else if(c < 0xF8 && i+3 < text.size())
+ {
+ EmitUnicodeCodepoint(
+ (text[i+3] & 0x3F) |
+ ((text[i+2] & 0x3F) << 6) |
+ ((text[i+1] & 0x3F) << 12) |
+ ((c & 0x7) << 18)
+ );
+ i += 3;
+ }
+ else
+ {
+ EmitInvalidCodepoint(c);
+ }
}
}
break;
@@ -82,6 +116,7 @@ void cmWIXRichTextFormatWriter::WriteHeader()
ControlWord("deflang1031");
WriteFontTable();
+ WriteColorTable();
WriteGenerator();
}
@@ -99,11 +134,27 @@ void cmWIXRichTextFormatWriter::WriteFontTable()
EndGroup();
}
+void cmWIXRichTextFormatWriter::WriteColorTable()
+{
+ StartGroup();
+ ControlWord("colortbl ;");
+ ControlWord("red255");
+ ControlWord("green0");
+ ControlWord("blue0;");
+ ControlWord("red0");
+ ControlWord("green255");
+ ControlWord("blue0;");
+ ControlWord("red0");
+ ControlWord("green0");
+ ControlWord("blue255;");
+ EndGroup();
+}
+
void cmWIXRichTextFormatWriter::WriteGenerator()
{
StartGroup();
NewControlWord("generator");
- file << " CPack WiX Generator (" << cmVersion::GetCMakeVersion() << ");";
+ File << " CPack WiX Generator (" << cmVersion::GetCMakeVersion() << ");";
EndGroup();
}
@@ -116,22 +167,62 @@ void cmWIXRichTextFormatWriter::WriteDocumentPrefix()
ControlWord("fs20");
}
-void cmWIXRichTextFormatWriter::ControlWord(const std::string& keyword)
+void cmWIXRichTextFormatWriter::ControlWord(std::string const& keyword)
{
- file << "\\" << keyword;
+ File << "\\" << keyword;
}
-void cmWIXRichTextFormatWriter::NewControlWord(const std::string& keyword)
+void cmWIXRichTextFormatWriter::NewControlWord(std::string const& keyword)
{
- file << "\\*\\" << keyword;
+ File << "\\*\\" << keyword;
}
void cmWIXRichTextFormatWriter::StartGroup()
{
- file.put('{');
+ File.put('{');
}
void cmWIXRichTextFormatWriter::EndGroup()
{
- file.put('}');
+ File.put('}');
+}
+
+void cmWIXRichTextFormatWriter::EmitUnicodeCodepoint(int c)
+{
+ // Do not emit byte order mark (BOM)
+ if(c == 0xFEFF)
+ {
+ return;
+ }
+ else if(c <= 0xFFFF)
+ {
+ EmitUnicodeSurrogate(c);
+ }
+ else
+ {
+ c -= 0x10000;
+ EmitUnicodeSurrogate(((c >> 10) & 0x3FF) + 0xD800);
+ EmitUnicodeSurrogate((c & 0x3FF) + 0xDC00);
+ }
+}
+
+void cmWIXRichTextFormatWriter::EmitUnicodeSurrogate(int c)
+{
+ ControlWord("u");
+ if(c <= 32767)
+ {
+ File << c;
+ }
+ else
+ {
+ File << (c - 65536);
+ }
+ File << "?";
+}
+
+void cmWIXRichTextFormatWriter::EmitInvalidCodepoint(int c)
+{
+ ControlWord("cf1 ");
+ File << "[INVALID-BYTE-" << int(c) << "]";
+ ControlWord("cf0 ");
}
diff --git a/Source/CPack/WiX/cmWIXRichTextFormatWriter.h b/Source/CPack/WiX/cmWIXRichTextFormatWriter.h
index 10b67c39f..f6327fbd5 100644
--- a/Source/CPack/WiX/cmWIXRichTextFormatWriter.h
+++ b/Source/CPack/WiX/cmWIXRichTextFormatWriter.h
@@ -13,7 +13,7 @@
#ifndef cmWIXRichTextFormatWriter_h
#define cmWIXRichTextFormatWriter_h
-#include <fstream>
+#include <cmsys/FStream.hxx>
/** \class cmWIXRichtTextFormatWriter
* \brief Helper class to generate Rich Text Format (RTF) documents
@@ -22,25 +22,31 @@
class cmWIXRichTextFormatWriter
{
public:
- cmWIXRichTextFormatWriter(const std::string& filename);
+ cmWIXRichTextFormatWriter(std::string const& filename);
~cmWIXRichTextFormatWriter();
- void AddText(const std::string& text);
+ void AddText(std::string const& text);
private:
void WriteHeader();
void WriteFontTable();
+ void WriteColorTable();
void WriteGenerator();
void WriteDocumentPrefix();
- void ControlWord(const std::string& keyword);
- void NewControlWord(const std::string& keyword);
+ void ControlWord(std::string const& keyword);
+ void NewControlWord(std::string const& keyword);
void StartGroup();
void EndGroup();
- std::ofstream file;
+ void EmitUnicodeCodepoint(int c);
+ void EmitUnicodeSurrogate(int c);
+
+ void EmitInvalidCodepoint(int c);
+
+ cmsys::ofstream File;
};
#endif
diff --git a/Source/CPack/WiX/cmWIXShortcut.cxx b/Source/CPack/WiX/cmWIXShortcut.cxx
new file mode 100644
index 000000000..d72187284
--- /dev/null
+++ b/Source/CPack/WiX/cmWIXShortcut.cxx
@@ -0,0 +1,125 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmWIXShortcut.h"
+
+#include "cmWIXFilesSourceWriter.h"
+
+void cmWIXShortcuts::insert(
+ Type type, std::string const& id, cmWIXShortcut const& shortcut)
+{
+ this->Shortcuts[type][id].push_back(shortcut);
+}
+
+bool cmWIXShortcuts::empty(Type type) const
+{
+ return this->Shortcuts.find(type) == this->Shortcuts.end();
+}
+
+bool cmWIXShortcuts::EmitShortcuts(
+ Type type,
+ std::string const& registryKey,
+ std::string const& cpackComponentName,
+ cmWIXFilesSourceWriter& fileDefinitions) const
+{
+ shortcut_type_map_t::const_iterator i = this->Shortcuts.find(type);
+
+ if(i == this->Shortcuts.end())
+ {
+ return false;
+ }
+
+ shortcut_id_map_t const& id_map = i->second;
+
+ std::string shortcutPrefix;
+ std::string registrySuffix;
+
+ switch(type)
+ {
+ case START_MENU:
+ shortcutPrefix = "CM_S";
+ break;
+ case DESKTOP:
+ shortcutPrefix = "CM_DS";
+ registrySuffix = "_desktop";
+ break;
+ case STARTUP:
+ shortcutPrefix = "CM_SS";
+ registrySuffix = "_startup";
+ break;
+ default:
+ return false;
+ }
+
+ for(shortcut_id_map_t::const_iterator j = id_map.begin();
+ j != id_map.end(); ++j)
+ {
+ std::string const& id = j->first;
+ shortcut_list_t const& shortcutList = j->second;
+
+ for(size_t shortcutListIndex = 0;
+ shortcutListIndex < shortcutList.size(); ++shortcutListIndex)
+ {
+ cmWIXShortcut const& shortcut = shortcutList[shortcutListIndex];
+ fileDefinitions.EmitShortcut(id, shortcut,
+ shortcutPrefix, shortcutListIndex);
+ }
+ }
+
+ fileDefinitions.EmitInstallRegistryValue(
+ registryKey, cpackComponentName, registrySuffix);
+
+ return true;
+}
+
+void cmWIXShortcuts::AddShortcutTypes(std::set<Type>& types)
+{
+ for(shortcut_type_map_t::const_iterator i = this->Shortcuts.begin();
+ i != this->Shortcuts.end(); ++i)
+ {
+ types.insert(i->first);
+ }
+}
+
+void cmWIXShortcuts::CreateFromProperties(
+ std::string const& id,
+ std::string const& directoryId,
+ cmInstalledFile const& installedFile)
+{
+ CreateFromProperty("CPACK_START_MENU_SHORTCUTS",
+ START_MENU, id, directoryId, installedFile);
+
+ CreateFromProperty("CPACK_DESKTOP_SHORTCUTS",
+ DESKTOP, id, directoryId, installedFile);
+
+ CreateFromProperty("CPACK_STARTUP_SHORTCUTS",
+ STARTUP, id, directoryId, installedFile);
+}
+
+void cmWIXShortcuts::CreateFromProperty(
+ std::string const& propertyName,
+ Type type,
+ std::string const& id,
+ std::string const& directoryId,
+ cmInstalledFile const& installedFile)
+{
+ std::vector<std::string> list;
+ installedFile.GetPropertyAsList(propertyName, list);
+
+ for(size_t i = 0; i < list.size(); ++i)
+ {
+ cmWIXShortcut shortcut;
+ shortcut.label = list[i];
+ shortcut.workingDirectoryId = directoryId;
+ insert(type, id, shortcut);
+ }
+}
diff --git a/Source/CPack/WiX/cmWIXShortcut.h b/Source/CPack/WiX/cmWIXShortcut.h
new file mode 100644
index 000000000..5945e4367
--- /dev/null
+++ b/Source/CPack/WiX/cmWIXShortcut.h
@@ -0,0 +1,73 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014-2015 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmWIXShortcut_h
+#define cmWIXShortcut_h
+
+#include <string>
+#include <map>
+#include <set>
+#include <vector>
+
+#include <cmInstalledFile.h>
+
+class cmWIXFilesSourceWriter;
+
+struct cmWIXShortcut
+{
+ std::string label;
+ std::string workingDirectoryId;
+};
+
+class cmWIXShortcuts
+{
+public:
+ enum Type
+ {
+ START_MENU,
+ DESKTOP,
+ STARTUP
+ };
+
+ typedef std::vector<cmWIXShortcut> shortcut_list_t;
+ typedef std::map<std::string, shortcut_list_t> shortcut_id_map_t;
+
+ void insert(Type type, std::string const& id, cmWIXShortcut const& shortcut);
+
+ bool empty(Type type) const;
+
+ bool EmitShortcuts(
+ Type type,
+ std::string const& registryKey,
+ std::string const& cpackComponentName,
+ cmWIXFilesSourceWriter& fileDefinitions) const;
+
+ void AddShortcutTypes(std::set<Type>& types);
+
+ void CreateFromProperties(std::string const& id,
+ std::string const& directoryId, cmInstalledFile const& installedFile);
+
+private:
+ typedef std::map<Type, shortcut_id_map_t> shortcut_type_map_t;
+
+ void CreateFromProperty(
+ std::string const& propertyName,
+ Type type,
+ std::string const& id,
+ std::string const& directoryId,
+ cmInstalledFile const& installedFile);
+
+ shortcut_type_map_t Shortcuts;
+ shortcut_id_map_t EmptyIdMap;
+};
+
+#endif
diff --git a/Source/CPack/WiX/cmWIXSourceWriter.cxx b/Source/CPack/WiX/cmWIXSourceWriter.cxx
index af7ba807f..63acb278f 100644
--- a/Source/CPack/WiX/cmWIXSourceWriter.cxx
+++ b/Source/CPack/WiX/cmWIXSourceWriter.cxx
@@ -10,6 +10,8 @@
See the License for more information.
============================================================================*/
+#include "cmStandardIncludes.h"
+
#include "cmWIXSourceWriter.h"
#include <CPack/cmCPackGenerator.h>
@@ -17,11 +19,12 @@
#include <windows.h>
cmWIXSourceWriter::cmWIXSourceWriter(cmCPackLog* logger,
- const std::string& filename,
+ std::string const& filename,
bool isIncludeFile):
Logger(logger),
- file(filename.c_str()),
- state(DEFAULT)
+ File(filename.c_str()),
+ State(DEFAULT),
+ SourceFilename(filename)
{
WriteXMLDeclaration();
@@ -39,76 +42,122 @@ cmWIXSourceWriter::cmWIXSourceWriter(cmCPackLog* logger,
cmWIXSourceWriter::~cmWIXSourceWriter()
{
- while(elements.size())
+ if(Elements.size() > 1)
{
- EndElement();
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ Elements.size() - 1 << " WiX elements were still open when closing '" <<
+ SourceFilename << "'" << std::endl);
+ return;
}
+
+ EndElement(Elements.back());
}
-void cmWIXSourceWriter::BeginElement(const std::string& name)
+void cmWIXSourceWriter::BeginElement(std::string const& name)
{
- if(state == BEGIN)
+ if(State == BEGIN)
{
- file << ">";
+ File << ">";
}
- file << "\n";
- Indent(elements.size());
- file << "<" << name;
+ File << "\n";
+ Indent(Elements.size());
+ File << "<" << name;
- elements.push_back(name);
- state = BEGIN;
+ Elements.push_back(name);
+ State = BEGIN;
}
-void cmWIXSourceWriter::EndElement()
+void cmWIXSourceWriter::EndElement(std::string const& name)
{
- if(elements.empty())
+ if(Elements.empty())
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
- "can not end WiX element with no open elements" << std::endl);
+ "can not end WiX element with no open elements in '" <<
+ SourceFilename << "'" << std::endl);
return;
}
- if(state == DEFAULT)
+ if(Elements.back() != name)
{
- file << "\n";
- Indent(elements.size()-1);
- file << "</" << elements.back() << ">";
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "WiX element <" << Elements.back() <<
+ "> can not be closed by </" << name << "> in '" <<
+ SourceFilename << "'" << std::endl);
+ return;
+ }
+
+ if(State == DEFAULT)
+ {
+ File << "\n";
+ Indent(Elements.size()-1);
+ File << "</" << Elements.back() << ">";
}
else
{
- file << "/>";
+ File << "/>";
+ }
+
+ Elements.pop_back();
+ State = DEFAULT;
+}
+
+void cmWIXSourceWriter::AddTextNode(std::string const& text)
+{
+ if(State == BEGIN)
+ {
+ File << ">";
+ }
+
+ if(Elements.empty())
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "can not add text without open WiX element in '" <<
+ SourceFilename << "'" << std::endl);
+ return;
}
- elements.pop_back();
- state = DEFAULT;
+ File << this->EscapeAttributeValue(text);
+ State = DEFAULT;
}
void cmWIXSourceWriter::AddProcessingInstruction(
- const std::string& target, const std::string& content)
+ std::string const& target, std::string const& content)
{
- if(state == BEGIN)
+ if(State == BEGIN)
{
- file << ">";
+ File << ">";
}
- file << "\n";
- Indent(elements.size());
- file << "<?" << target << " " << content << "?>";
+ File << "\n";
+ Indent(Elements.size());
+ File << "<?" << target << " " << content << "?>";
- state = DEFAULT;
+ State = DEFAULT;
}
void cmWIXSourceWriter::AddAttribute(
- const std::string& key, const std::string& value)
+ std::string const& key, std::string const& value)
{
- std::string utf8 = WindowsCodepageToUtf8(value);
+ std::string utf8 = CMakeEncodingToUtf8(value);
- file << " " << key << "=\"" << EscapeAttributeValue(utf8) << '"';
+ File << " " << key << "=\"" << EscapeAttributeValue(utf8) << '"';
}
-std::string cmWIXSourceWriter::WindowsCodepageToUtf8(const std::string& value)
+void cmWIXSourceWriter::AddAttributeUnlessEmpty(
+ std::string const& key, std::string const& value)
{
+ if(!value.empty())
+ {
+ AddAttribute(key, value);
+ }
+}
+
+std::string cmWIXSourceWriter::CMakeEncodingToUtf8(std::string const& value)
+{
+#ifdef CMAKE_ENCODING_UTF8
+ return value;
+#else
if(value.empty())
{
return std::string();
@@ -142,24 +191,25 @@ std::string cmWIXSourceWriter::WindowsCodepageToUtf8(const std::string& value)
&utf8[0], static_cast<int>(utf8.size()), 0, 0);
return std::string(&utf8[0], utf8.size());
+#endif
}
void cmWIXSourceWriter::WriteXMLDeclaration()
{
- file << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
+ File << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
}
void cmWIXSourceWriter::Indent(size_t count)
{
for(size_t i = 0; i < count; ++i)
{
- file << " ";
+ File << " ";
}
}
std::string cmWIXSourceWriter::EscapeAttributeValue(
- const std::string& value)
+ std::string const& value)
{
std::string result;
result.reserve(value.size());
@@ -173,6 +223,9 @@ std::string cmWIXSourceWriter::EscapeAttributeValue(
case '<':
result += "&lt;";
break;
+ case '>':
+ result += "&gt;";
+ break;
case '&':
result +="&amp;";
break;
diff --git a/Source/CPack/WiX/cmWIXSourceWriter.h b/Source/CPack/WiX/cmWIXSourceWriter.h
index 1dafc1ff2..9e303f0d8 100644
--- a/Source/CPack/WiX/cmWIXSourceWriter.h
+++ b/Source/CPack/WiX/cmWIXSourceWriter.h
@@ -15,7 +15,7 @@
#include <vector>
#include <string>
-#include <fstream>
+#include <cmsys/FStream.hxx>
#include <CPack/cmCPackLog.h>
@@ -26,21 +26,29 @@ class cmWIXSourceWriter
{
public:
cmWIXSourceWriter(cmCPackLog* logger,
- const std::string& filename, bool isIncludeFile = false);
+ std::string const& filename, bool isIncludeFile = false);
~cmWIXSourceWriter();
- void BeginElement(const std::string& name);
+ void BeginElement(std::string const& name);
- void EndElement();
+ void EndElement(std::string const& name);
+
+ void AddTextNode(std::string const& text);
void AddProcessingInstruction(
- const std::string& target, const std::string& content);
+ std::string const& target, std::string const& content);
void AddAttribute(
- const std::string& key, const std::string& value);
+ std::string const& key, std::string const& value);
+
+ void AddAttributeUnlessEmpty(
+ std::string const& key, std::string const& value);
+
+ static std::string CMakeEncodingToUtf8(std::string const& value);
- static std::string WindowsCodepageToUtf8(const std::string& value);
+protected:
+ cmCPackLog* Logger;
private:
enum State
@@ -53,15 +61,15 @@ private:
void Indent(size_t count);
- static std::string EscapeAttributeValue(const std::string& value);
+ static std::string EscapeAttributeValue(std::string const& value);
- cmCPackLog* Logger;
+ cmsys::ofstream File;
- std::ofstream file;
+ State State;
- State state;
+ std::vector<std::string> Elements;
- std::vector<std::string> elements;
+ std::string SourceFilename;
};
#endif
diff --git a/Source/CPack/cmCPack7zGenerator.cxx b/Source/CPack/cmCPack7zGenerator.cxx
new file mode 100644
index 000000000..2809e568e
--- /dev/null
+++ b/Source/CPack/cmCPack7zGenerator.cxx
@@ -0,0 +1,25 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmCPack7zGenerator.h"
+
+//----------------------------------------------------------------------
+cmCPack7zGenerator::cmCPack7zGenerator()
+ :cmCPackArchiveGenerator(cmArchiveWrite::CompressNone,
+ "7zip")
+{
+}
+
+//----------------------------------------------------------------------
+cmCPack7zGenerator::~cmCPack7zGenerator()
+{
+}
diff --git a/Source/CPack/cmCPack7zGenerator.h b/Source/CPack/cmCPack7zGenerator.h
new file mode 100644
index 000000000..f5a323f1e
--- /dev/null
+++ b/Source/CPack/cmCPack7zGenerator.h
@@ -0,0 +1,36 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmCPack7zGenerator_h
+#define cmCPack7zGenerator_h
+
+#include "cmCPackArchiveGenerator.h"
+
+/** \class cmCPack7zGenerator
+ * \brief A generator for 7z files
+ */
+class cmCPack7zGenerator : public cmCPackArchiveGenerator
+{
+public:
+ cmCPackTypeMacro(cmCPack7zGenerator, cmCPackArchiveGenerator);
+
+ /**
+ * Construct generator
+ */
+ cmCPack7zGenerator();
+ virtual ~cmCPack7zGenerator();
+
+protected:
+ virtual const char* GetOutputExtension() { return ".7z"; }
+};
+
+#endif
diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx
index 6e7b8d7c8..db985db81 100644
--- a/Source/CPack/cmCPackArchiveGenerator.cxx
+++ b/Source/CPack/cmCPackArchiveGenerator.cxx
@@ -14,7 +14,6 @@
#include "cmake.h"
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
#include "cmSystemTools.h"
#include "cmMakefile.h"
#include "cmGeneratedFileStream.h"
@@ -27,10 +26,10 @@
//----------------------------------------------------------------------
cmCPackArchiveGenerator::cmCPackArchiveGenerator(cmArchiveWrite::Compress t,
- cmArchiveWrite::Type at)
+ std::string const& format)
{
this->Compress = t;
- this->Archive = at;
+ this->ArchiveFormat = format;
}
//----------------------------------------------------------------------
@@ -56,13 +55,21 @@ int cmCPackArchiveGenerator::addOneComponentToArchive(cmArchiveWrite& archive,
localToplevel += "/"+ component->Name;
std::string dir = cmSystemTools::GetCurrentWorkingDirectory();
// Change to local toplevel
- cmSystemTools::ChangeDirectory(localToplevel.c_str());
+ cmSystemTools::ChangeDirectory(localToplevel);
std::string filePrefix;
if (this->IsOn("CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY"))
{
filePrefix = this->GetOption("CPACK_PACKAGE_FILE_NAME");
filePrefix += "/";
}
+ const char* installPrefix =
+ this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX");
+ if(installPrefix && installPrefix[0] == '/' && installPrefix[1] != 0)
+ {
+ // add to file prefix and remove the leading '/'
+ filePrefix += installPrefix+1;
+ filePrefix += "/";
+ }
std::vector<std::string>::const_iterator fileIt;
for (fileIt = component->Files.begin(); fileIt != component->Files.end();
++fileIt )
@@ -70,7 +77,7 @@ int cmCPackArchiveGenerator::addOneComponentToArchive(cmArchiveWrite& archive,
std::string rp = filePrefix + *fileIt;
cmCPackLogger(cmCPackLog::LOG_DEBUG,"Adding file: "
<< rp << std::endl);
- archive.Add(rp);
+ archive.Add(rp, 0, 0, false);
if (!archive)
{
cmCPackLogger(cmCPackLog::LOG_ERROR, "ERROR while packaging files: "
@@ -80,7 +87,7 @@ int cmCPackArchiveGenerator::addOneComponentToArchive(cmArchiveWrite& archive,
}
}
// Go back to previous dir
- cmSystemTools::ChangeDirectory(dir.c_str());
+ cmSystemTools::ChangeDirectory(dir);
return 1;
}
@@ -100,7 +107,7 @@ if (!GenerateHeader(&gf)) \
<< ">." << std::endl); \
return 0; \
} \
-cmArchiveWrite archive(gf,this->Compress, this->Archive); \
+cmArchiveWrite archive(gf,this->Compress, this->ArchiveFormat); \
if (!archive) \
{ \
cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem to create archive < " \
@@ -270,13 +277,13 @@ int cmCPackArchiveGenerator::PackageFiles()
DECLARE_AND_OPEN_ARCHIVE(packageFileNames[0],archive);
std::vector<std::string>::const_iterator fileIt;
std::string dir = cmSystemTools::GetCurrentWorkingDirectory();
- cmSystemTools::ChangeDirectory(toplevel.c_str());
+ cmSystemTools::ChangeDirectory(toplevel);
for ( fileIt = files.begin(); fileIt != files.end(); ++ fileIt )
{
// Get the relative path to the file
std::string rp = cmSystemTools::RelativePath(toplevel.c_str(),
fileIt->c_str());
- archive.Add(rp);
+ archive.Add(rp, 0, 0, false);
if(!archive)
{
cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem while adding file< "
@@ -288,7 +295,7 @@ int cmCPackArchiveGenerator::PackageFiles()
return 0;
}
}
- cmSystemTools::ChangeDirectory(dir.c_str());
+ cmSystemTools::ChangeDirectory(dir);
// The destructor of cmArchiveWrite will close and finish the write
return 1;
}
diff --git a/Source/CPack/cmCPackArchiveGenerator.h b/Source/CPack/cmCPackArchiveGenerator.h
index 6411b1ebf..16e7632de 100644
--- a/Source/CPack/cmCPackArchiveGenerator.h
+++ b/Source/CPack/cmCPackArchiveGenerator.h
@@ -31,7 +31,7 @@ public:
/**
* Construct generator
*/
- cmCPackArchiveGenerator(cmArchiveWrite::Compress, cmArchiveWrite::Type);
+ cmCPackArchiveGenerator(cmArchiveWrite::Compress, std::string const& format);
virtual ~cmCPackArchiveGenerator();
// Used to add a header to the archive
virtual int GenerateHeader(std::ostream* os);
@@ -68,7 +68,7 @@ protected:
int PackageComponentsAllInOne();
virtual const char* GetOutputExtension() = 0;
cmArchiveWrite::Compress Compress;
- cmArchiveWrite::Type Archive;
+ std::string ArchiveFormat;
};
#endif
diff --git a/Source/CPack/cmCPackBundleGenerator.cxx b/Source/CPack/cmCPackBundleGenerator.cxx
index 6c994f13f..b2d701944 100644
--- a/Source/CPack/cmCPackBundleGenerator.cxx
+++ b/Source/CPack/cmCPackBundleGenerator.cxx
@@ -39,6 +39,21 @@ int cmCPackBundleGenerator::InitializeInternal()
return 0;
}
+ if(this->GetOption("CPACK_BUNDLE_APPLE_CERT_APP"))
+ {
+ const std::string codesign_path = cmSystemTools::FindProgram("codesign",
+ std::vector<std::string>(), false);
+
+ if(codesign_path.empty())
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Cannot locate codesign command"
+ << std::endl);
+ return 0;
+ }
+ this->SetOptionIfNotSet("CPACK_COMMAND_CODESIGN", codesign_path.c_str());
+ }
+
return this->Superclass::InitializeInternal();
}
@@ -53,7 +68,7 @@ const char* cmCPackBundleGenerator::GetPackagingInstallPrefix()
}
//----------------------------------------------------------------------
-int cmCPackBundleGenerator::PackageFiles()
+int cmCPackBundleGenerator::ConstructBundle()
{
// Get required arguments ...
@@ -97,24 +112,24 @@ int cmCPackBundleGenerator::PackageFiles()
// The staging directory contains everything that will end-up inside the
// final disk image ...
- cmOStringStream staging;
+ std::ostringstream staging;
staging << toplevel;
- cmOStringStream contents;
+ std::ostringstream contents;
contents << staging.str() << "/" << cpack_bundle_name
<< ".app/" << "Contents";
- cmOStringStream application;
+ std::ostringstream application;
application << contents.str() << "/" << "MacOS";
- cmOStringStream resources;
+ std::ostringstream resources;
resources << contents.str() << "/" << "Resources";
// Install a required, user-provided bundle metadata file ...
- cmOStringStream plist_source;
+ std::ostringstream plist_source;
plist_source << cpack_bundle_plist;
- cmOStringStream plist_target;
+ std::ostringstream plist_target;
plist_target << contents.str() << "/" << "Info.plist";
if(!this->CopyFile(plist_source, plist_target))
@@ -127,10 +142,10 @@ int cmCPackBundleGenerator::PackageFiles()
}
// Install a user-provided bundle icon ...
- cmOStringStream icon_source;
+ std::ostringstream icon_source;
icon_source << cpack_bundle_icon;
- cmOStringStream icon_target;
+ std::ostringstream icon_target;
icon_target << resources.str() << "/" << cpack_bundle_name << ".icns";
if(!this->CopyFile(icon_source, icon_target))
@@ -146,10 +161,10 @@ int cmCPackBundleGenerator::PackageFiles()
// executable or a script) ...
if(!cpack_bundle_startup_command.empty())
{
- cmOStringStream command_source;
+ std::ostringstream command_source;
command_source << cpack_bundle_startup_command;
- cmOStringStream command_target;
+ std::ostringstream command_target;
command_target << application.str() << "/" << cpack_bundle_name;
if(!this->CopyFile(command_source, command_target))
@@ -165,6 +180,22 @@ int cmCPackBundleGenerator::PackageFiles()
cmSystemTools::SetPermissions(command_target.str().c_str(), 0777);
}
+ return 1;
+}
+
+//----------------------------------------------------------------------
+int cmCPackBundleGenerator::PackageFiles()
+{
+ if(!this->ConstructBundle())
+ {
+ return 0;
+ }
+
+ if(!this->SignBundle(toplevel))
+ {
+ return 0;
+ }
+
return this->CreateDMG(toplevel, packageFileNames[0]);
}
@@ -172,3 +203,105 @@ bool cmCPackBundleGenerator::SupportsComponentInstallation() const
{
return false;
}
+
+
+int cmCPackBundleGenerator::SignBundle(const std::string& src_dir)
+{
+ const std::string cpack_apple_cert_app =
+ this->GetOption("CPACK_BUNDLE_APPLE_CERT_APP")
+ ? this->GetOption("CPACK_BUNDLE_APPLE_CERT_APP") : "";
+
+ // codesign the application.
+ if(!cpack_apple_cert_app.empty())
+ {
+ std::string output;
+ std::string bundle_path;
+ bundle_path = src_dir + "/";
+ bundle_path += this->GetOption("CPACK_BUNDLE_NAME");
+ bundle_path += ".app";
+
+ // A list of additional files to sign, ie. frameworks and plugins.
+ const std::string sign_parameter =
+ this->GetOption("CPACK_BUNDLE_APPLE_CODESIGN_PARAMETER")
+ ? this->GetOption("CPACK_BUNDLE_APPLE_CODESIGN_PARAMETER")
+ : "--deep -f";
+
+ const std::string sign_files =
+ this->GetOption("CPACK_BUNDLE_APPLE_CODESIGN_FILES")
+ ? this->GetOption("CPACK_BUNDLE_APPLE_CODESIGN_FILES") : "";
+
+ std::vector<std::string> relFiles;
+ cmSystemTools::ExpandListArgument(sign_files, relFiles);
+
+ // sign the files supplied by the user, ie. frameworks.
+ for(std::vector<std::string>::iterator it = relFiles.begin();
+ it != relFiles.end(); ++it)
+ {
+ std::ostringstream temp_sign_file_cmd;
+ temp_sign_file_cmd << this->GetOption("CPACK_COMMAND_CODESIGN");
+ temp_sign_file_cmd << " " << sign_parameter << " -s \""
+ << cpack_apple_cert_app;
+ temp_sign_file_cmd << "\" -i ";
+ temp_sign_file_cmd << this->GetOption("CPACK_APPLE_BUNDLE_ID");
+ temp_sign_file_cmd << " \"";
+ temp_sign_file_cmd << bundle_path;
+ temp_sign_file_cmd << it->c_str() << "\"";
+
+ if(!this->RunCommand(temp_sign_file_cmd, &output))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error signing file:"
+ << bundle_path << it->c_str() << std::endl << output << std::endl);
+
+ return 0;
+ }
+ }
+
+ // sign main binary
+ std::ostringstream temp_sign_binary_cmd;
+ temp_sign_binary_cmd << this->GetOption("CPACK_COMMAND_CODESIGN");
+ temp_sign_binary_cmd << " " << sign_parameter << " -s \""
+ << cpack_apple_cert_app;
+ temp_sign_binary_cmd << "\" \"" << bundle_path << "\"";
+
+ if(!this->RunCommand(temp_sign_binary_cmd, &output))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error signing the application binary."
+ << std::endl << output << std::endl);
+
+ return 0;
+ }
+
+ // sign app bundle
+ std::ostringstream temp_codesign_cmd;
+ temp_codesign_cmd << this->GetOption("CPACK_COMMAND_CODESIGN");
+ temp_codesign_cmd << " " << sign_parameter << " -s \""
+ << cpack_apple_cert_app << "\"";
+ if(this->GetOption("CPACK_BUNDLE_APPLE_ENTITLEMENTS"))
+ {
+ temp_codesign_cmd << " --entitlements ";
+ temp_codesign_cmd << this->GetOption("CPACK_BUNDLE_APPLE_ENTITLEMENTS");
+ }
+ temp_codesign_cmd << " \"" << bundle_path << "\"";
+
+ if(!this->RunCommand(temp_codesign_cmd, &output))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error signing the application package."
+ << std::endl << output << std::endl);
+
+ return 0;
+ }
+
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+ "- Application has been codesigned"
+ << std::endl);
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE,
+ (this->GetOption("CPACK_BUNDLE_APPLE_ENTITLEMENTS")
+ ? "with entitlement sandboxing" : "without entitlement sandboxing")
+ << std::endl);
+ }
+
+ return 1;
+}
diff --git a/Source/CPack/cmCPackBundleGenerator.h b/Source/CPack/cmCPackBundleGenerator.h
index ed0187dd4..9cb2f0ac7 100644
--- a/Source/CPack/cmCPackBundleGenerator.h
+++ b/Source/CPack/cmCPackBundleGenerator.h
@@ -31,6 +31,8 @@ public:
protected:
virtual int InitializeInternal();
virtual const char* GetPackagingInstallPrefix();
+ int ConstructBundle();
+ int SignBundle(const std::string& src_dir);
int PackageFiles();
bool SupportsComponentInstallation() const;
diff --git a/Source/CPack/cmCPackComponentGroup.cxx b/Source/CPack/cmCPackComponentGroup.cxx
index f93eca823..fd20e9b20 100644
--- a/Source/CPack/cmCPackComponentGroup.cxx
+++ b/Source/CPack/cmCPackComponentGroup.cxx
@@ -16,7 +16,8 @@
#include <string>
//----------------------------------------------------------------------
-unsigned long cmCPackComponent::GetInstalledSize(const char* installDir) const
+unsigned long cmCPackComponent::GetInstalledSize(
+ const std::string& installDir) const
{
if (this->TotalSize != 0)
{
@@ -29,7 +30,7 @@ unsigned long cmCPackComponent::GetInstalledSize(const char* installDir) const
std::string path = installDir;
path += '/';
path += *fileIt;
- this->TotalSize += cmSystemTools::FileLength(path.c_str());
+ this->TotalSize += cmSystemTools::FileLength(path);
}
return this->TotalSize;
@@ -37,7 +38,7 @@ unsigned long cmCPackComponent::GetInstalledSize(const char* installDir) const
//----------------------------------------------------------------------
unsigned long
-cmCPackComponent::GetInstalledSizeInKbytes(const char* installDir) const
+cmCPackComponent::GetInstalledSizeInKbytes(const std::string& installDir) const
{
unsigned long result = (GetInstalledSize(installDir) + 512) / 1024;
return result? result : 1;
diff --git a/Source/CPack/cmCPackComponentGroup.h b/Source/CPack/cmCPackComponentGroup.h
index abae3724e..0679638a6 100644
--- a/Source/CPack/cmCPackComponentGroup.h
+++ b/Source/CPack/cmCPackComponentGroup.h
@@ -94,11 +94,11 @@ public:
/// Get the total installed size of all of the files in this
/// component, in bytes. installDir is the directory into which the
/// component was installed.
- unsigned long GetInstalledSize(const char* installDir) const;
+ unsigned long GetInstalledSize(const std::string& installDir) const;
/// Identical to GetInstalledSize, but returns the result in
/// kilobytes.
- unsigned long GetInstalledSizeInKbytes(const char* installDir) const;
+ unsigned long GetInstalledSizeInKbytes(const std::string& installDir) const;
private:
mutable unsigned long TotalSize;
diff --git a/Source/CPack/cmCPackCygwinBinaryGenerator.cxx b/Source/CPack/cmCPackCygwinBinaryGenerator.cxx
index 6605f16e0..1f905c030 100644
--- a/Source/CPack/cmCPackCygwinBinaryGenerator.cxx
+++ b/Source/CPack/cmCPackCygwinBinaryGenerator.cxx
@@ -14,7 +14,6 @@
#include "cmake.h"
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
#include "cmSystemTools.h"
#include "cmMakefile.h"
#include "cmGeneratedFileStream.h"
diff --git a/Source/CPack/cmCPackCygwinSourceGenerator.cxx b/Source/CPack/cmCPackCygwinSourceGenerator.cxx
index f1e8539b9..f5cb53cc9 100644
--- a/Source/CPack/cmCPackCygwinSourceGenerator.cxx
+++ b/Source/CPack/cmCPackCygwinSourceGenerator.cxx
@@ -14,7 +14,6 @@
#include "cmake.h"
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
#include "cmSystemTools.h"
#include "cmMakefile.h"
#include "cmGeneratedFileStream.h"
diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx
index 4494e8a18..13c8d8f6c 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -15,11 +15,13 @@
#include "cmMakefile.h"
#include "cmGeneratedFileStream.h"
#include "cmCPackLog.h"
+#include "cmArchiveWrite.h"
#include <cmsys/SystemTools.hxx>
#include <cmsys/Glob.hxx>
#include <limits.h> // USHRT_MAX
+#include <sys/stat.h>
// NOTE:
// A debian package .deb is simply an 'ar' archive. The only subtle difference
@@ -58,7 +60,7 @@ int cmCPackDebGenerator::PackageOnePack(std::string initialTopLevel,
// Begin the archive for this pack
std::string localToplevel(initialTopLevel);
std::string packageFileName(
- cmSystemTools::GetParentDirectory(toplevel.c_str())
+ cmSystemTools::GetParentDirectory(toplevel)
);
std::string outputFileName(
std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME"))
@@ -90,9 +92,10 @@ int cmCPackDebGenerator::PackageOnePack(std::string initialTopLevel,
}
cmsys::Glob gl;
- std::string findExpr(this->GetOption("WDIR"));
+ std::string findExpr(this->GetOption("GEN_WDIR"));
findExpr += "/*";
gl.RecurseOn();
+ gl.SetRecurseListDirs(true);
if ( !gl.FindFiles(findExpr) )
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -186,7 +189,7 @@ int cmCPackDebGenerator::PackageComponentsAllInOne()
// The ALL GROUPS in ONE package case
std::string localToplevel(initialTopLevel);
std::string packageFileName(
- cmSystemTools::GetParentDirectory(toplevel.c_str())
+ cmSystemTools::GetParentDirectory(toplevel)
);
std::string outputFileName(
std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME"))
@@ -217,9 +220,10 @@ int cmCPackDebGenerator::PackageComponentsAllInOne()
}
cmsys::Glob gl;
- std::string findExpr(this->GetOption("WDIR"));
+ std::string findExpr(this->GetOption("GEN_WDIR"));
findExpr += "/*";
gl.RecurseOn();
+ gl.SetRecurseListDirs(true);
if ( !gl.FindFiles(findExpr) )
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -282,11 +286,9 @@ int cmCPackDebGenerator::PackageFiles()
int cmCPackDebGenerator::createDeb()
{
- const char* cmakeExecutable = this->GetOption("CMAKE_COMMAND");
-
// debian-binary file
std::string dbfilename;
- dbfilename += this->GetOption("WDIR");
+ dbfilename += this->GetOption("GEN_WDIR");
dbfilename += "/debian-binary";
{ // the scope is needed for cmGeneratedFileStream
cmGeneratedFileStream out(dbfilename.c_str());
@@ -296,44 +298,50 @@ int cmCPackDebGenerator::createDeb()
// control file
std::string ctlfilename;
- ctlfilename = this->GetOption("WDIR");
+ ctlfilename = this->GetOption("GEN_WDIR");
ctlfilename += "/control";
// debian policy enforce lower case for package name
// mandatory entries:
std::string debian_pkg_name = cmsys::SystemTools::LowerCase(
- this->GetOption("CPACK_DEBIAN_PACKAGE_NAME") );
+ this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_NAME") );
const char* debian_pkg_version =
- this->GetOption("CPACK_DEBIAN_PACKAGE_VERSION");
+ this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_VERSION");
const char* debian_pkg_section =
- this->GetOption("CPACK_DEBIAN_PACKAGE_SECTION");
+ this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SECTION");
const char* debian_pkg_priority =
- this->GetOption("CPACK_DEBIAN_PACKAGE_PRIORITY");
+ this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_PRIORITY");
const char* debian_pkg_arch =
- this->GetOption("CPACK_DEBIAN_PACKAGE_ARCHITECTURE");
- const char* maintainer = this->GetOption("CPACK_DEBIAN_PACKAGE_MAINTAINER");
- const char* desc = this->GetOption("CPACK_DEBIAN_PACKAGE_DESCRIPTION");
+ this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_ARCHITECTURE");
+ const char* maintainer =
+ this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_MAINTAINER");
+ const char* desc =
+ this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_DESCRIPTION");
// optional entries
- const char* debian_pkg_dep = this->GetOption("CPACK_DEBIAN_PACKAGE_DEPENDS");
+ const char* debian_pkg_dep =
+ this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_DEPENDS");
const char* debian_pkg_rec =
- this->GetOption("CPACK_DEBIAN_PACKAGE_RECOMMENDS");
+ this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_RECOMMENDS");
const char* debian_pkg_sug =
- this->GetOption("CPACK_DEBIAN_PACKAGE_SUGGESTS");
+ this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SUGGESTS");
const char* debian_pkg_url =
- this->GetOption("CPACK_DEBIAN_PACKAGE_HOMEPAGE");
+ this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_HOMEPAGE");
const char* debian_pkg_predep =
- this->GetOption("CPACK_DEBIAN_PACKAGE_PREDEPENDS");
+ this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_PREDEPENDS");
const char* debian_pkg_enhances =
- this->GetOption("CPACK_DEBIAN_PACKAGE_ENHANCES");
+ this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_ENHANCES");
const char* debian_pkg_breaks =
- this->GetOption("CPACK_DEBIAN_PACKAGE_BREAKS");
+ this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_BREAKS");
const char* debian_pkg_conflicts =
- this->GetOption("CPACK_DEBIAN_PACKAGE_CONFLICTS");
+ this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_CONFLICTS");
const char* debian_pkg_provides =
- this->GetOption("CPACK_DEBIAN_PACKAGE_PROVIDES");
+ this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_PROVIDES");
const char* debian_pkg_replaces =
- this->GetOption("CPACK_DEBIAN_PACKAGE_REPLACES");
+ this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_REPLACES");
+ const char* debian_pkg_source =
+ this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SOURCE");
+
{ // the scope is needed for cmGeneratedFileStream
cmGeneratedFileStream out(ctlfilename.c_str());
@@ -342,6 +350,10 @@ int cmCPackDebGenerator::createDeb()
out << "Section: " << debian_pkg_section << "\n";
out << "Priority: " << debian_pkg_priority << "\n";
out << "Architecture: " << debian_pkg_arch << "\n";
+ if(debian_pkg_source && *debian_pkg_source)
+ {
+ out << "Source: " << debian_pkg_source << "\n";
+ }
if(debian_pkg_dep && *debian_pkg_dep)
{
out << "Depends: " << debian_pkg_dep << "\n";
@@ -386,11 +398,11 @@ int cmCPackDebGenerator::createDeb()
{
std::string dirName = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
dirName += '/';
- for (std::vector<std::string>::const_iterator fileIt =
- packageFiles.begin();
- fileIt != packageFiles.end(); ++ fileIt )
+ for (std::vector<std::string>::const_iterator fileIt =
+ packageFiles.begin();
+ fileIt != packageFiles.end(); ++ fileIt )
{
- totalSize += cmSystemTools::FileLength(fileIt->c_str());
+ totalSize += cmSystemTools::FileLength(*fileIt);
}
}
out << "Installed-Size: " << (totalSize + 1023) / 1024 << "\n";
@@ -399,84 +411,146 @@ int cmCPackDebGenerator::createDeb()
out << std::endl;
}
- std::string cmd;
- if (NULL != this->GetOption("CPACK_DEBIAN_FAKEROOT_EXECUTABLE")) {
- cmd += this->GetOption("CPACK_DEBIAN_FAKEROOT_EXECUTABLE");
+ const std::string strGenWDIR(this->GetOption("GEN_WDIR"));
+
+ cmArchiveWrite::Compress tar_compression_type = cmArchiveWrite::CompressGZip;
+ const char* debian_compression_type =
+ this->GetOption("GEN_CPACK_DEBIAN_COMPRESSION_TYPE");
+ if(!debian_compression_type)
+ {
+ debian_compression_type = "gzip";
+ }
+
+ std::string compression_suffix;
+ if(!strcmp(debian_compression_type, "lzma")) {
+ compression_suffix = ".lzma";
+ tar_compression_type = cmArchiveWrite::CompressLZMA;
+ } else if(!strcmp(debian_compression_type, "xz")) {
+ compression_suffix = ".xz";
+ tar_compression_type = cmArchiveWrite::CompressXZ;
+ } else if(!strcmp(debian_compression_type, "bzip2")) {
+ compression_suffix = ".bz2";
+ tar_compression_type = cmArchiveWrite::CompressBZip2;
+ } else if(!strcmp(debian_compression_type, "gzip")) {
+ compression_suffix = ".gz";
+ tar_compression_type = cmArchiveWrite::CompressGZip;
+ } else if(!strcmp(debian_compression_type, "none")) {
+ compression_suffix = "";
+ tar_compression_type = cmArchiveWrite::CompressNone;
+ } else {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error unrecognized compression type: "
+ << debian_compression_type << std::endl);
}
- cmd += " \"";
- cmd += cmakeExecutable;
- cmd += "\" -E tar cfz data.tar.gz ";
-
- // now add all directories which have to be compressed
- // collect all top level install dirs for that
- // e.g. /opt/bin/foo, /usr/bin/bar and /usr/bin/baz would give /usr and /opt
- size_t topLevelLength = std::string(this->GetOption("WDIR")).length();
- cmCPackLogger(cmCPackLog::LOG_DEBUG, "WDIR: \"" << this->GetOption("WDIR")
- << "\", length = " << topLevelLength
+
+
+ std::string filename_data_tar = strGenWDIR
+ + "/data.tar" + compression_suffix;
+
+ // atomic file generation for data.tar
+ {
+ cmGeneratedFileStream fileStream_data_tar;
+ fileStream_data_tar.Open(filename_data_tar.c_str(), false, true);
+ if(!fileStream_data_tar)
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error opening the file \"" << filename_data_tar << "\" for writing"
<< std::endl);
- std::set<std::string> installDirs;
+ return 0;
+ }
+ cmArchiveWrite data_tar(fileStream_data_tar, tar_compression_type, "paxr");
+
+ // uid/gid should be the one of the root user, and this root user has
+ // always uid/gid equal to 0.
+ data_tar.SetUIDAndGID(0u, 0u);
+ data_tar.SetUNAMEAndGNAME("root", "root");
+
+ // now add all directories which have to be compressed
+ // collect all top level install dirs for that
+ // e.g. /opt/bin/foo, /usr/bin/bar and /usr/bin/baz would
+ // give /usr and /opt
+ size_t topLevelLength = strGenWDIR.length();
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "WDIR: \""
+ << strGenWDIR
+ << "\", length = " << topLevelLength
+ << std::endl);
+ std::set<std::string> orderedFiles;
+
+ // we have to reconstruct the parent folders as well
+
for (std::vector<std::string>::const_iterator fileIt =
- packageFiles.begin();
- fileIt != packageFiles.end(); ++ fileIt )
- {
- cmCPackLogger(cmCPackLog::LOG_DEBUG, "FILEIT: \"" << *fileIt << "\""
- << std::endl);
- std::string::size_type slashPos = fileIt->find('/', topLevelLength+1);
- std::string relativeDir = fileIt->substr(topLevelLength,
- slashPos - topLevelLength);
- cmCPackLogger(cmCPackLog::LOG_DEBUG, "RELATIVEDIR: \"" << relativeDir
- << "\"" << std::endl);
- if (installDirs.find(relativeDir) == installDirs.end())
+ packageFiles.begin();
+ fileIt != packageFiles.end(); ++ fileIt )
{
- installDirs.insert(relativeDir);
- cmd += " .";
- cmd += relativeDir;
+ std::string currentPath = *fileIt;
+ while(currentPath != strGenWDIR)
+ {
+ // the last one IS strGenWDIR, but we do not want this one:
+ // XXX/application/usr/bin/myprogram with GEN_WDIR=XXX/application
+ // should not add XXX/application
+ orderedFiles.insert(currentPath);
+ currentPath = cmSystemTools::CollapseCombinedPath(currentPath, "..");
+ }
}
- }
- std::string output;
- int retval = -1;
- int res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output,
- &retval, this->GetOption("WDIR"), this->GeneratorVerbose, 0);
- if ( !res || retval )
- {
- std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- tmpFile += "/Deb.log";
- cmGeneratedFileStream ofs(tmpFile.c_str());
- ofs << "# Run command: " << cmd.c_str() << std::endl
- << "# Working directory: " << toplevel << std::endl
- << "# Output:" << std::endl
- << output.c_str() << std::endl;
- cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running tar command: "
- << cmd.c_str() << std::endl
- << "Please check " << tmpFile.c_str() << " for errors" << std::endl);
- return 0;
- }
+ for (std::set<std::string>::const_iterator fileIt =
+ orderedFiles.begin();
+ fileIt != orderedFiles.end(); ++ fileIt )
+ {
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "FILEIT: \"" << *fileIt << "\""
+ << std::endl);
+ std::string::size_type slashPos = fileIt->find('/', topLevelLength+1);
+ std::string relativeDir = fileIt->substr(topLevelLength,
+ slashPos - topLevelLength);
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "RELATIVEDIR: \"" << relativeDir
+ << "\"" << std::endl);
+
+ // do not recurse because the loop will do it
+ if(!data_tar.Add(*fileIt, topLevelLength, ".", false))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Problem adding file to tar:" << std::endl
+ << "#top level directory: "
+ << strGenWDIR << std::endl
+ << "#file: " << *fileIt << std::endl
+ << "#error:" << data_tar.GetError() << std::endl);
+ return 0;
+ }
+ }
+ } // scope for file generation
- std::string md5filename;
- md5filename = this->GetOption("WDIR");
- md5filename += "/md5sums";
- { // the scope is needed for cmGeneratedFileStream
+ std::string md5filename = strGenWDIR + "/md5sums";
+ {
+ // the scope is needed for cmGeneratedFileStream
cmGeneratedFileStream out(md5filename.c_str());
- std::vector<std::string>::const_iterator fileIt;
-// std::string topLevelWithTrailingSlash = toplevel;
+
std::string topLevelWithTrailingSlash =
this->GetOption("CPACK_TEMPORARY_DIRECTORY");
topLevelWithTrailingSlash += '/';
- for ( fileIt = packageFiles.begin();
- fileIt != packageFiles.end(); ++ fileIt )
+ for (std::vector<std::string>::const_iterator fileIt =
+ packageFiles.begin();
+ fileIt != packageFiles.end(); ++ fileIt )
{
- cmd = "\"";
- cmd += cmakeExecutable;
- cmd += "\" -E md5sum \"";
- cmd += *fileIt;
- cmd += "\"";
- //std::string output;
- //int retVal = -1;
- res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output,
- &retval, toplevel.c_str(), this->GeneratorVerbose, 0);
+ // hash only regular files
+ if( cmSystemTools::FileIsDirectory(*fileIt)
+ || cmSystemTools::FileIsSymlink(*fileIt))
+ {
+ continue;
+ }
+
+ char md5sum[33];
+ if(!cmSystemTools::ComputeFileMD5(*fileIt, md5sum))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem computing the md5 of "
+ << *fileIt << std::endl);
+ }
+
+ md5sum[32] = 0;
+
+ std::string output(md5sum);
+ output += " " + *fileIt + "\n";
// debian md5sums entries are like this:
// 014f3604694729f3bf19263bac599765 usr/bin/ccmake
// thus strip the full path (with the trailing slash)
@@ -486,71 +560,116 @@ int cmCPackDebGenerator::createDeb()
}
// each line contains a eol.
// Do not end the md5sum file with yet another (invalid)
- }
+ }
- cmd = "";
- if (NULL != this->GetOption("CPACK_DEBIAN_FAKEROOT_EXECUTABLE"))
+
+
+ std::string filename_control_tar = strGenWDIR + "/control.tar.gz";
+ // atomic file generation for control.tar
+ {
+ cmGeneratedFileStream fileStream_control_tar;
+ fileStream_control_tar.Open(filename_control_tar.c_str(), false, true);
+ if(!fileStream_control_tar)
{
- cmd = this->GetOption("CPACK_DEBIAN_FAKEROOT_EXECUTABLE");
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error opening the file \"" << filename_control_tar
+ << "\" for writing" << std::endl);
+ return 0;
}
- cmd += " \"";
- cmd += cmakeExecutable;
- cmd += "\" -E tar cfz control.tar.gz ./control ./md5sums";
+ cmArchiveWrite control_tar(fileStream_control_tar,
+ cmArchiveWrite::CompressGZip,
+ "paxr");
+
+ // sets permissions and uid/gid for the files
+ control_tar.SetUIDAndGID(0u, 0u);
+ control_tar.SetUNAMEAndGNAME("root", "root");
+
+ /* permissions are set according to
+ https://www.debian.org/doc/debian-policy/ch-files.html#s-permissions-owners
+ and
+ https://lintian.debian.org/tags/control-file-has-bad-permissions.html
+ */
+ const mode_t permission644 = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+ const mode_t permissionExecute = S_IXUSR | S_IXGRP | S_IXOTH;
+ const mode_t permission755 = permission644 | permissionExecute;
+
+ // for md5sum and control (that we have generated here), we use 644
+ // (RW-R--R--)
+ // so that deb lintian doesn't warn about it
+ control_tar.SetPermissions(permission644);
+
+ // adds control and md5sums
+ if( !control_tar.Add(md5filename, strGenWDIR.length(), ".")
+ || !control_tar.Add(strGenWDIR + "/control", strGenWDIR.length(), "."))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error adding file to tar:" << std::endl
+ << "#top level directory: "
+ << strGenWDIR << std::endl
+ << "#file: \"control\" or \"md5sums\"" << std::endl
+ << "#error:" << control_tar.GetError() << std::endl);
+ return 0;
+ }
+
+ // for the other files, we use
+ // -either the original permission on the files
+ // -either a permission strictly defined by the Debian policies
const char* controlExtra =
- this->GetOption("CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA");
- if( controlExtra )
- {
- std::vector<std::string> controlExtraList;
- cmSystemTools::ExpandListArgument(controlExtra, controlExtraList);
- for(std::vector<std::string>::iterator i =
- controlExtraList.begin(); i != controlExtraList.end(); ++i)
+ this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA");
+ if( controlExtra )
{
- std::string filenamename =
- cmsys::SystemTools::GetFilenameName(i->c_str());
- std::string localcopy = this->GetOption("WDIR");
- localcopy += "/";
- localcopy += filenamename;
- // if we can copy the file, it means it does exist, let's add it:
- if( cmsys::SystemTools::CopyFileIfDifferent(
- i->c_str(), localcopy.c_str()) )
+ // permissions are now controlled by the original file permissions
+
+ const bool permissionStrictPolicy =
+ this->IsSet("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION");
+
+ static const char* strictFiles[] = {
+ "config", "postinst", "postrm", "preinst", "prerm"
+ };
+ std::set<std::string> setStrictFiles(
+ strictFiles,
+ strictFiles + sizeof(strictFiles)/sizeof(strictFiles[0]));
+
+ // default
+ control_tar.ClearPermissions();
+
+ std::vector<std::string> controlExtraList;
+ cmSystemTools::ExpandListArgument(controlExtra, controlExtraList);
+ for(std::vector<std::string>::iterator i = controlExtraList.begin();
+ i != controlExtraList.end(); ++i)
{
- // debian is picky and need relative to ./ path in the tar.gz
- cmd += " ./";
- cmd += filenamename;
+ std::string filenamename =
+ cmsys::SystemTools::GetFilenameName(*i);
+ std::string localcopy = strGenWDIR + "/" + filenamename;
+
+ if(permissionStrictPolicy)
+ {
+ control_tar.SetPermissions(setStrictFiles.count(filenamename) ?
+ permission755 : permission644);
+ }
+
+ // if we can copy the file, it means it does exist, let's add it:
+ if( cmsys::SystemTools::CopyFileIfDifferent(*i, localcopy) )
+ {
+ control_tar.Add(localcopy, strGenWDIR.length(), ".");
+ }
}
}
- }
- res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output,
- &retval, this->GetOption("WDIR"), this->GeneratorVerbose, 0);
+ }
- if ( !res || retval )
- {
- std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- tmpFile += "/Deb.log";
- cmGeneratedFileStream ofs(tmpFile.c_str());
- ofs << "# Run command: " << cmd.c_str() << std::endl
- << "# Working directory: " << toplevel << std::endl
- << "# Output:" << std::endl
- << output.c_str() << std::endl;
- cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running tar command: "
- << cmd.c_str() << std::endl
- << "Please check " << tmpFile.c_str() << " for errors" << std::endl);
- return 0;
- }
- // ar -r your-package-name.deb debian-binary control.tar.gz data.tar.gz
+ // ar -r your-package-name.deb debian-binary control.tar.* data.tar.*
// since debian packages require BSD ar (most Linux distros and even
// FreeBSD and NetBSD ship GNU ar) we use a copy of OpenBSD ar here.
std::vector<std::string> arFiles;
- std::string topLevelString = this->GetOption("WDIR");
- topLevelString += "/";
+ std::string topLevelString = strGenWDIR + "/";
arFiles.push_back(topLevelString + "debian-binary");
arFiles.push_back(topLevelString + "control.tar.gz");
- arFiles.push_back(topLevelString + "data.tar.gz");
- std::string outputFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- outputFileName += "/";
- outputFileName += this->GetOption("CPACK_OUTPUT_FILE_NAME");
- res = ar_append(outputFileName.c_str(), arFiles);
+ arFiles.push_back(topLevelString + "data.tar" + compression_suffix);
+ std::string outputFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
+ outputFileName += "/";
+ outputFileName += this->GetOption("CPACK_OUTPUT_FILE_NAME");
+ int res = ar_append(outputFileName.c_str(), arFiles);
if ( res!=0 )
{
std::string tmpFile = this->GetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME");
@@ -588,9 +707,9 @@ std::string cmCPackDebGenerator::GetComponentInstallDirNameSuffix(
// the current COMPONENT belongs to.
std::string groupVar = "CPACK_COMPONENT_" +
cmSystemTools::UpperCase(componentName) + "_GROUP";
- if (NULL != GetOption(groupVar.c_str()))
+ if (NULL != GetOption(groupVar))
{
- return std::string(GetOption(groupVar.c_str()));
+ return std::string(GetOption(groupVar));
}
else
{
@@ -772,12 +891,14 @@ static int put_arobj(CF *cfp, struct stat *sb)
if (lname > sizeof(hdr->ar_name) || strchr(name, ' '))
(void)sprintf(ar_hb, HDR1, AR_EFMT1, (int)lname,
(long int)sb->st_mtime, (unsigned)uid, (unsigned)gid,
- sb->st_mode, (long long)sb->st_size + lname, ARFMAG);
+ (unsigned)sb->st_mode, (long long)sb->st_size + lname,
+ ARFMAG);
else {
lname = 0;
(void)sprintf(ar_hb, HDR2, name,
(long int)sb->st_mtime, (unsigned)uid, (unsigned)gid,
- sb->st_mode, (long long)sb->st_size, ARFMAG);
+ (unsigned)sb->st_mode, (long long)sb->st_size,
+ ARFMAG);
}
off_t size = sb->st_size;
@@ -803,7 +924,7 @@ static int put_arobj(CF *cfp, struct stat *sb)
static int ar_append(const char* archive,const std::vector<std::string>& files)
{
int eval = 0;
- FILE* aFile = fopen(archive, "wb+");
+ FILE* aFile = cmSystemTools::Fopen(archive, "wb+");
if (aFile!=NULL) {
fwrite(ARMAG, SARMAG, 1, aFile);
if (fseek(aFile, 0, SEEK_END) != -1) {
@@ -814,7 +935,7 @@ static int ar_append(const char* archive,const std::vector<std::string>& files)
for(std::vector<std::string>::const_iterator fileIt = files.begin();
fileIt!=files.end(); ++fileIt) {
const char* filename = fileIt->c_str();
- FILE* file = fopen(filename, "rb");
+ FILE* file = cmSystemTools::Fopen(filename, "rb");
if (file == NULL) {
eval = -1;
continue;
diff --git a/Source/CPack/cmCPackDocumentMacros.cxx b/Source/CPack/cmCPackDocumentMacros.cxx
deleted file mode 100644
index ddc75a4b4..000000000
--- a/Source/CPack/cmCPackDocumentMacros.cxx
+++ /dev/null
@@ -1,16 +0,0 @@
-#include "cmCPackDocumentMacros.h"
-
-void cmCPackDocumentMacros::GetMacrosDocumentation(
- std::vector<cmDocumentationEntry>& )
-{
- // Commented-out example of use
- //
- // cmDocumentationEntry e("cpack_<macro>",
- // "Brief Description"
- // "which may be on several lines.",
- // "Long description in pre-formatted format"
- // " blah\n"
- // " blah\n"
- //);
- //v.push_back(e);
-}
diff --git a/Source/CPack/cmCPackDocumentMacros.h b/Source/CPack/cmCPackDocumentMacros.h
deleted file mode 100644
index 544f74f5f..000000000
--- a/Source/CPack/cmCPackDocumentMacros.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef cmCPackDocumentMacros_h
-#define cmCPackDocumentMacros_h
-#include "cmStandardIncludes.h"
-class cmCPackDocumentMacros
-{
-public:
- static void GetMacrosDocumentation(std::vector<cmDocumentationEntry>& v);
-};
-
-#endif
diff --git a/Source/CPack/cmCPackDocumentVariables.cxx b/Source/CPack/cmCPackDocumentVariables.cxx
deleted file mode 100644
index 8b16ae985..000000000
--- a/Source/CPack/cmCPackDocumentVariables.cxx
+++ /dev/null
@@ -1,122 +0,0 @@
-#include "cmCPackDocumentVariables.h"
-#include "cmake.h"
-
-void cmCPackDocumentVariables::DefineVariables(cmake* cm)
-{
- // Subsection: variables defined/used by cpack,
- // which are common to all CPack generators
-
- cm->DefineProperty
- ("CPACK_PACKAGING_INSTALL_PREFIX", cmProperty::VARIABLE,
- "The prefix used in the built package.",
- "Each CPack generator has a default value (like /usr)."
- " This default value may"
- " be overwritten from the CMakeLists.txt or the cpack command line"
- " by setting an alternative value.\n"
- "e.g. "
- " set(CPACK_PACKAGING_INSTALL_PREFIX \"/opt\")\n"
- "This is not the same purpose as CMAKE_INSTALL_PREFIX which"
- " is used when installing from the build tree without building"
- " a package."
- "", false,
- "Variables common to all CPack generators");
-
- cm->DefineProperty
- ("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", cmProperty::VARIABLE,
- "Boolean toggle to include/exclude top level directory.",
- "When preparing a package CPack installs the item under"
- " the so-called top level directory. The purpose of"
- " is to include (set to 1 or ON or TRUE) the top level directory"
- " in the package or not (set to 0 or OFF or FALSE).\n"
- "Each CPack generator has a built-in default value for this"
- " variable. E.g. Archive generators (ZIP, TGZ, ...) includes"
- " the top level whereas RPM or DEB don't. The user may override"
- " the default value by setting this variable.\n"
- "There is a similar variable "
- "CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY "
- "which may be used to override the behavior for the component"
- " packaging case which may have different default value for"
- " historical (now backward compatibility) reason.", false,
- "Variables common to all CPack generators");
-
- cm->DefineProperty
- ("CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY", cmProperty::VARIABLE,
- "Boolean toggle to include/exclude top level directory "
- "(component case).",
- "Similar usage as CPACK_INCLUDE_TOPLEVEL_DIRECTORY"
- " but for the component case. "
- "See CPACK_INCLUDE_TOPLEVEL_DIRECTORY documentation for"
- " the detail.", false,
- "Variables common to all CPack generators");
-
- cm->DefineProperty
- ("CPACK_SET_DESTDIR", cmProperty::VARIABLE,
- "Boolean toggle to make CPack use DESTDIR mechanism when"
- " packaging.", "DESTDIR means DESTination DIRectory."
- " It is commonly used by makefile "
- "users in order to install software at non-default location. It "
- "is a basic relocation mechanism that should not be used on"
- " Windows (see CMAKE_INSTALL_PREFIX documentation). "
- "It is usually invoked like this:\n"
- " make DESTDIR=/home/john install\n"
- "which will install the concerned software using the"
- " installation prefix, e.g. \"/usr/local\" prepended with "
- "the DESTDIR value which finally gives \"/home/john/usr/local\"."
- " When preparing a package, CPack first installs the items to be "
- "packaged in a local (to the build tree) directory by using the "
- "same DESTDIR mechanism. Nevertheless, if "
- "CPACK_SET_DESTDIR is set then CPack will set DESTDIR before"
- " doing the local install. The most noticeable difference is"
- " that without CPACK_SET_DESTDIR, CPack uses "
- "CPACK_PACKAGING_INSTALL_PREFIX as a prefix whereas with "
- "CPACK_SET_DESTDIR set, CPack will use CMAKE_INSTALL_PREFIX as"
- " a prefix.\n"
- "Manually setting CPACK_SET_DESTDIR may help (or simply be"
- " necessary) if some install rules uses absolute "
- "DESTINATION (see CMake INSTALL command)."
- " However, starting with"
- " CPack/CMake 2.8.3 RPM and DEB installers tries to handle DESTDIR"
- " automatically so that it is seldom necessary for the user to set"
- " it.", false,
- "Variables common to all CPack generators");
-
- cm->DefineProperty
- ("CPACK_INSTALL_SCRIPT", cmProperty::VARIABLE,
- "Extra CMake script provided by the user.",
- "If set this CMake script will be executed by CPack "
- "during its local [CPack-private] installation "
- "which is done right before packaging the files."
- " The script is not called by e.g.: make install.", false,
- "Variables common to all CPack generators");
-
- cm->DefineProperty
- ("CPACK_ABSOLUTE_DESTINATION_FILES", cmProperty::VARIABLE,
- "List of files which have been installed using "
- " an ABSOLUTE DESTINATION path.",
- "This variable is a Read-Only variable which is set internally"
- " by CPack during installation and before packaging using"
- " CMAKE_ABSOLUTE_DESTINATION_FILES defined in cmake_install.cmake "
- "scripts. The value can be used within CPack project configuration"
- " file and/or CPack<GEN>.cmake file of <GEN> generator.", false,
- "Variables common to all CPack generators");
-
- cm->DefineProperty
- ("CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION", cmProperty::VARIABLE,
- "Ask CPack to warn each time a file with absolute INSTALL"
- " DESTINATION is encountered.",
- "This variable triggers the definition of "
- "CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION when CPack runs"
- " cmake_install.cmake scripts.", false,
- "Variables common to all CPack generators");
-
- cm->DefineProperty
- ("CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION", cmProperty::VARIABLE,
- "Ask CPack to error out as soon as a file with absolute INSTALL"
- " DESTINATION is encountered.",
- "The fatal error is emitted before the installation of "
- "the offending file takes place. Some CPack generators, like NSIS,"
- "enforce this internally. "
- "This variable triggers the definition of"
- "CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION when CPack runs"
- "Variables common to all CPack generators");
-}
diff --git a/Source/CPack/cmCPackDocumentVariables.h b/Source/CPack/cmCPackDocumentVariables.h
deleted file mode 100644
index e7971be13..000000000
--- a/Source/CPack/cmCPackDocumentVariables.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef cmCPackDocumentVariables_h
-#define cmCPackDocumentVariables_h
-class cmake;
-class cmCPackDocumentVariables
-{
-public:
- static void DefineVariables(cmake* cm);
-};
-
-#endif
diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx
index d973c0134..d6de77df9 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.cxx
+++ b/Source/CPack/cmCPackDragNDropGenerator.cxx
@@ -16,6 +16,18 @@
#include "cmGeneratedFileStream.h"
#include <cmsys/RegularExpression.hxx>
+#include <cmsys/FStream.hxx>
+
+#include <iomanip>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#ifdef HAVE_CoreServices
+// For the old LocaleStringToLangAndRegionCodes() function, to convert
+// to the old Script Manager RegionCode values needed for the 'LPic' data
+// structure used for generating multi-lingual SLAs.
+#include <CoreServices/CoreServices.h>
+#endif
static const char* SLAHeader =
"data 'LPic' (5000) {\n"
@@ -50,6 +62,7 @@ static const char* SLASTREnglish =
//----------------------------------------------------------------------
cmCPackDragNDropGenerator::cmCPackDragNDropGenerator()
+ : singleLicense(false)
{
// default to one package file for components
this->componentPackageMethod = ONE_PACKAGE;
@@ -102,6 +115,70 @@ int cmCPackDragNDropGenerator::InitializeInternal()
}
this->SetOptionIfNotSet("CPACK_COMMAND_REZ", rez_path.c_str());
+ if(this->IsSet("CPACK_DMG_SLA_DIR"))
+ {
+ slaDirectory = this->GetOption("CPACK_DMG_SLA_DIR");
+ if(!slaDirectory.empty() && this->IsSet("CPACK_RESOURCE_FILE_LICENSE"))
+ {
+ std::string license_file =
+ this->GetOption("CPACK_RESOURCE_FILE_LICENSE");
+ if(!license_file.empty() &&
+ (license_file.find("CPack.GenericLicense.txt") == std::string::npos))
+ {
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+ "Both CPACK_DMG_SLA_DIR and CPACK_RESOURCE_FILE_LICENSE specified, "
+ "using CPACK_RESOURCE_FILE_LICENSE as a license for all languages."
+ << std::endl);
+ singleLicense = true;
+ }
+ }
+ if(!this->IsSet("CPACK_DMG_SLA_LANGUAGES"))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPACK_DMG_SLA_DIR set but no languages defined "
+ "(set CPACK_DMG_SLA_LANGUAGES)"
+ << std::endl);
+ return 0;
+ }
+ if(!cmSystemTools::FileExists(slaDirectory, false))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPACK_DMG_SLA_DIR does not exist"
+ << std::endl);
+ return 0;
+ }
+
+ std::vector<std::string> languages;
+ cmSystemTools::ExpandListArgument(
+ this->GetOption("CPACK_DMG_SLA_LANGUAGES"), languages);
+ if(languages.empty())
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPACK_DMG_SLA_LANGUAGES set but empty"
+ << std::endl);
+ return 0;
+ }
+ for(size_t i = 0; i < languages.size(); ++i)
+ {
+ std::string license = slaDirectory + "/" + languages[i] + ".license.txt";
+ if (!singleLicense && !cmSystemTools::FileExists(license))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Missing license file " << languages[i] << ".license.txt"
+ << std::endl);
+ return 0;
+ }
+ std::string menu = slaDirectory + "/" + languages[i] + ".menu.txt";
+ if (!cmSystemTools::FileExists(menu))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Missing menu file " << languages[i] << ".menu.txt"
+ << std::endl);
+ return 0;
+ }
+ }
+ }
+
return this->Superclass::InitializeInternal();
}
@@ -168,8 +245,8 @@ int cmCPackDragNDropGenerator::PackageFiles()
}
//----------------------------------------------------------------------
-bool cmCPackDragNDropGenerator::CopyFile(cmOStringStream& source,
- cmOStringStream& target)
+bool cmCPackDragNDropGenerator::CopyFile(std::ostringstream& source,
+ std::ostringstream& target)
{
if(!cmSystemTools::CopyFileIfDifferent(
source.str().c_str(),
@@ -189,14 +266,36 @@ bool cmCPackDragNDropGenerator::CopyFile(cmOStringStream& source,
}
//----------------------------------------------------------------------
-bool cmCPackDragNDropGenerator::RunCommand(cmOStringStream& command,
+bool cmCPackDragNDropGenerator::CreateEmptyFile(std::ostringstream& target,
+ size_t size)
+{
+ cmsys::ofstream fout(target.str().c_str(),
+ std::ios::out | std::ios::binary);
+ if(!fout)
+ {
+ return false;
+ }
+ else
+ {
+ // Seek to desired size - 1 byte
+ fout.seekp(size - 1, std::ios_base::beg);
+ char byte = 0;
+ // Write one byte to ensure file grows
+ fout.write(&byte, 1);
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------
+bool cmCPackDragNDropGenerator::RunCommand(std::ostringstream& command,
std::string* output)
{
int exit_code = 1;
bool result = cmSystemTools::RunSingleCommand(
command.str().c_str(),
- output,
+ output, output,
&exit_code,
0,
this->GeneratorVerbose,
@@ -245,21 +344,36 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
this->GetOption("CPACK_DMG_DS_STORE")
? this->GetOption("CPACK_DMG_DS_STORE") : "";
+ const std::string cpack_dmg_languages =
+ this->GetOption("CPACK_DMG_SLA_LANGUAGES")
+ ? this->GetOption("CPACK_DMG_SLA_LANGUAGES") : "";
+
+ const std::string cpack_dmg_ds_store_setup_script =
+ this->GetOption("CPACK_DMG_DS_STORE_SETUP_SCRIPT")
+ ? this->GetOption("CPACK_DMG_DS_STORE_SETUP_SCRIPT") : "";
+
// only put license on dmg if is user provided
if(!cpack_license_file.empty() &&
cpack_license_file.find("CPack.GenericLicense.txt") != std::string::npos)
- {
+ {
+ cpack_license_file = "";
+ }
+
+ // use sla_dir if both sla_dir and license_file are set
+ if(!cpack_license_file.empty() &&
+ !slaDirectory.empty() && !singleLicense)
+ {
cpack_license_file = "";
- }
+ }
// The staging directory contains everything that will end-up inside the
// final disk image ...
- cmOStringStream staging;
+ std::ostringstream staging;
staging << src_dir;
// Add a symlink to /Applications so users can drag-and-drop the bundle
// into it
- cmOStringStream application_link;
+ std::ostringstream application_link;
application_link << staging.str() << "/Applications";
cmSystemTools::CreateSymlink("/Applications",
application_link.str().c_str());
@@ -267,10 +381,10 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
// Optionally add a custom volume icon ...
if(!cpack_package_icon.empty())
{
- cmOStringStream package_icon_source;
+ std::ostringstream package_icon_source;
package_icon_source << cpack_package_icon;
- cmOStringStream package_icon_destination;
+ std::ostringstream package_icon_destination;
package_icon_destination << staging.str() << "/.VolumeIcon.icns";
if(!this->CopyFile(package_icon_source, package_icon_destination))
@@ -288,10 +402,10 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
// (e.g. for setting background/layout) ...
if(!cpack_dmg_ds_store.empty())
{
- cmOStringStream package_settings_source;
+ std::ostringstream package_settings_source;
package_settings_source << cpack_dmg_ds_store;
- cmOStringStream package_settings_destination;
+ std::ostringstream package_settings_destination;
package_settings_destination << staging.str() << "/.DS_Store";
if(!this->CopyFile(package_settings_source, package_settings_destination))
@@ -306,13 +420,18 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
}
// Optionally add a custom background image ...
+ // Make sure the background file type is the same as the custom image
+ // and that the file is hidden so it doesn't show up.
if(!cpack_dmg_background_image.empty())
{
- cmOStringStream package_background_source;
+ const std::string extension =
+ cmSystemTools::GetFilenameLastExtension(cpack_dmg_background_image);
+ std::ostringstream package_background_source;
package_background_source << cpack_dmg_background_image;
- cmOStringStream package_background_destination;
- package_background_destination << staging.str() << "/background.png";
+ std::ostringstream package_background_destination;
+ package_background_destination << staging.str()
+ << "/.background/background" << extension;
if(!this->CopyFile(package_background_source,
package_background_destination))
@@ -324,18 +443,22 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
return 0;
}
+ }
- cmOStringStream temp_background_hiding_command;
- temp_background_hiding_command << this->GetOption("CPACK_COMMAND_SETFILE");
- temp_background_hiding_command << " -a V \"";
- temp_background_hiding_command << package_background_destination.str();
- temp_background_hiding_command << "\"";
+ bool remount_image = !cpack_package_icon.empty() ||
+ !cpack_dmg_ds_store_setup_script.empty();
- if(!this->RunCommand(temp_background_hiding_command))
+ // Create 1 MB dummy padding file in staging area when we need to remount
+ // image, so we have enough space for storing changes ...
+ if(remount_image)
+ {
+ std::ostringstream dummy_padding;
+ dummy_padding << staging.str() << "/.dummy-padding-file";
+ if(!this->CreateEmptyFile(dummy_padding, 1048576))
{
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Error setting attributes on disk volume background image."
- << std::endl);
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error creating dummy padding file."
+ << std::endl);
return 0;
}
@@ -345,7 +468,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
std::string temp_image = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
temp_image += "/temp.dmg";
- cmOStringStream temp_image_command;
+ std::ostringstream temp_image_command;
temp_image_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
temp_image_command << " create";
temp_image_command << " -ov";
@@ -364,12 +487,13 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
return 0;
}
- // Optionally set the custom icon flag for the image ...
- if(!cpack_package_icon.empty())
+ if(remount_image)
{
- cmOStringStream temp_mount;
+ // Store that we have a failure so that we always unmount the image
+ // before we exit.
+ bool had_error = false;
- cmOStringStream attach_command;
+ std::ostringstream attach_command;
attach_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
attach_command << " attach";
attach_command << " \"" << temp_image << "\"";
@@ -386,23 +510,60 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
cmsys::RegularExpression mountpoint_regex(".*(/Volumes/[^\n]+)\n.*");
mountpoint_regex.find(attach_output.c_str());
+ std::ostringstream temp_mount;
temp_mount << mountpoint_regex.match(1);
- cmOStringStream setfile_command;
- setfile_command << this->GetOption("CPACK_COMMAND_SETFILE");
- setfile_command << " -a C";
- setfile_command << " \"" << temp_mount.str() << "\"";
-
- if(!this->RunCommand(setfile_command))
+ // Remove dummy padding file so we have enough space on RW image ...
+ std::ostringstream dummy_padding;
+ dummy_padding << temp_mount.str() << "/.dummy-padding-file";
+ if(!cmSystemTools::RemoveFile(dummy_padding.str()))
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Error assigning custom icon to temporary disk image."
+ "Error removing dummy padding file."
<< std::endl);
- return 0;
+ had_error = true;
}
- cmOStringStream detach_command;
+ // Optionally set the custom icon flag for the image ...
+ if(!had_error && !cpack_package_icon.empty())
+ {
+ std::ostringstream setfile_command;
+ setfile_command << this->GetOption("CPACK_COMMAND_SETFILE");
+ setfile_command << " -a C";
+ setfile_command << " \"" << temp_mount.str() << "\"";
+
+ if(!this->RunCommand(setfile_command))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error assigning custom icon to temporary disk image."
+ << std::endl);
+
+ had_error = true;
+ }
+ }
+
+ // Optionally we can execute a custom apple script to generate
+ // the .DS_Store for the volume folder ...
+ if(!had_error && !cpack_dmg_ds_store_setup_script.empty())
+ {
+ std::ostringstream setup_script_command;
+ setup_script_command << "osascript"
+ << " \"" << cpack_dmg_ds_store_setup_script << "\""
+ << " \"" << cpack_dmg_volume_name << "\"";
+ std::string error;
+ if(!this->RunCommand(setup_script_command, &error))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error executing custom script on disk image." << std::endl
+ << error
+ << std::endl);
+
+ had_error = true;
+ }
+ }
+
+ std::ostringstream detach_command;
detach_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
detach_command << " detach";
detach_command << " \"" << temp_mount.str() << "\"";
@@ -415,68 +576,173 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
return 0;
}
+
+ if(had_error)
+ {
+ return 0;
+ }
}
- if(!cpack_license_file.empty())
- {
+ if(!cpack_license_file.empty() || !slaDirectory.empty())
+ {
+ // Use old hardcoded style if sla_dir is not set
+ bool oldStyle = slaDirectory.empty();
std::string sla_r = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
sla_r += "/sla.r";
- std::ifstream ifs;
- ifs.open(cpack_license_file.c_str());
- if(ifs.is_open())
- {
- cmGeneratedFileStream osf(sla_r.c_str());
- osf << "#include <CoreServices/CoreServices.r>\n\n";
- osf << SLAHeader;
- osf << "\n";
- osf << "data 'TEXT' (5002, \"English\") {\n";
- while(ifs.good())
+ std::vector<std::string> languages;
+ if(!oldStyle)
{
- std::string line;
- std::getline(ifs, line);
- // escape quotes
- std::string::size_type pos = line.find('\"');
- while(pos != std::string::npos)
+ cmSystemTools::ExpandListArgument(cpack_dmg_languages, languages);
+ }
+
+ cmGeneratedFileStream ofs(sla_r.c_str());
+ ofs << "#include <CoreServices/CoreServices.r>\n\n";
+ if(oldStyle)
+ {
+ ofs << SLAHeader;
+ ofs << "\n";
+ }
+ else
+ {
+ /*
+ * LPic Layout
+ * (https://github.com/pypt/dmg-add-license/blob/master/main.c)
+ * as far as I can tell (no official documentation seems to exist):
+ * struct LPic {
+ * uint16_t default_language; // points to a resid, defaulting to 0,
+ * // which is the first set language
+ * uint16_t length;
+ * struct {
+ * uint16_t language_code;
+ * uint16_t resid;
+ * uint16_t encoding; // Encoding from TextCommon.h,
+ * // forcing MacRoman (0) for now. Might need to
+ * // allow overwrite per license by user later
+ * } item[1];
+ * }
+ */
+
+ // Create vector first for readability, then iterate to write to ofs
+ std::vector<uint16_t> header_data;
+ header_data.push_back(0);
+ header_data.push_back(languages.size());
+ for(size_t i = 0; i < languages.size(); ++i)
{
- line.replace(pos, 1, "\\\"");
- pos = line.find('\"', pos+2);
+ CFStringRef language_cfstring = CFStringCreateWithCString(
+ NULL, languages[i].c_str(), kCFStringEncodingUTF8);
+ CFStringRef iso_language =
+ CFLocaleCreateCanonicalLanguageIdentifierFromString(
+ NULL, language_cfstring);
+ if (!iso_language)
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ languages[i] << " is not a recognized language"
+ << std::endl);
+ }
+ char *iso_language_cstr = (char *) malloc(65);
+ CFStringGetCString(iso_language, iso_language_cstr, 64,
+ kCFStringEncodingMacRoman);
+ LangCode lang = 0;
+ RegionCode region = 0;
+#ifdef HAVE_CoreServices
+ OSStatus err = LocaleStringToLangAndRegionCodes(iso_language_cstr,
+ &lang, &region);
+ if (err != noErr)
+#endif
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "No language/region code available for " << iso_language_cstr
+ << std::endl);
+ free(iso_language_cstr);
+ return 0;
+ }
+#ifdef HAVE_CoreServices
+ free(iso_language_cstr);
+ header_data.push_back(region);
+ header_data.push_back(i);
+ header_data.push_back(0);
+#endif
}
- // break up long lines to avoid Rez errors
- std::vector<std::string> lines;
- const size_t max_line_length = 512;
- for(size_t i=0; i<line.size(); i+= max_line_length)
+ ofs << "data 'LPic' (5000) {\n";
+ ofs << std::hex << std::uppercase << std::setfill('0');
+
+ for(size_t i = 0; i < header_data.size(); ++i)
+ {
+ if(i % 8 == 0)
{
- int line_length = max_line_length;
- if(i+max_line_length > line.size())
- line_length = line.size()-i;
- lines.push_back(line.substr(i, line_length));
+ ofs << " $\"";
}
- for(size_t i=0; i<lines.size(); i++)
+ ofs << std::setw(4) << header_data[i];
+
+ if(i % 8 == 7 || i == header_data.size() - 1)
{
- osf << " \"" << lines[i] << "\"\n";
+ ofs << "\"\n";
}
- osf << " \"\\n\"\n";
+ else
+ {
+ ofs << " ";
+ }
+ }
+ ofs << "};\n\n";
+ // Reset ofs options
+ ofs << std::dec << std::nouppercase << std::setfill(' ');
+ }
+
+ bool have_write_license_error = false;
+ std::string error;
+
+ if(oldStyle)
+ {
+ if(!this->WriteLicense(ofs, 0, "", cpack_license_file, &error))
+ {
+ have_write_license_error = true;
+ }
+ }
+ else
+ {
+ for(size_t i = 0; i < languages.size() && !have_write_license_error; ++i)
+ {
+ if(singleLicense)
+ {
+ if(!this->WriteLicense(ofs, i + 5000, languages[i],
+ cpack_license_file, &error))
+ {
+ have_write_license_error = true;
+ }
+ }
+ else
+ {
+ if(!this->WriteLicense(ofs, i + 5000, languages[i], "", &error))
+ {
+ have_write_license_error = true;
+ }
+ }
+ }
+ }
+
+ ofs.Close();
+
+ if(have_write_license_error)
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error writing license file to SLA." << std::endl
+ << error
+ << std::endl);
+ return 0;
}
- osf << "};\n";
- osf << "\n";
- osf << SLASTREnglish;
- ifs.close();
- osf.close();
- }
// convert to UDCO
std::string temp_udco = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
temp_udco += "/temp-udco.dmg";
- cmOStringStream udco_image_command;
+ std::ostringstream udco_image_command;
udco_image_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
udco_image_command << " convert \"" << temp_image << "\"";
udco_image_command << " -format UDCO";
- udco_image_command << " -o \"" << temp_udco << "\"";
+ udco_image_command << " -ov -o \"" << temp_udco << "\"";
- std::string error;
if(!this->RunCommand(udco_image_command, &error))
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -487,7 +753,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
}
// unflatten dmg
- cmOStringStream unflatten_command;
+ std::ostringstream unflatten_command;
unflatten_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
unflatten_command << " unflatten ";
unflatten_command << "\"" << temp_udco << "\"";
@@ -502,8 +768,13 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
}
// Rez the SLA
- cmOStringStream embed_sla_command;
+ std::ostringstream embed_sla_command;
embed_sla_command << this->GetOption("CPACK_COMMAND_REZ");
+ const char* sysroot = this->GetOption("CPACK_OSX_SYSROOT");
+ if(sysroot && sysroot[0] != '\0')
+ {
+ embed_sla_command << " -isysroot \"" << sysroot << "\"";
+ }
embed_sla_command << " \"" << sla_r << "\"";
embed_sla_command << " -a -o ";
embed_sla_command << "\"" << temp_udco << "\"";
@@ -518,7 +789,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
}
// flatten dmg
- cmOStringStream flatten_command;
+ std::ostringstream flatten_command;
flatten_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
flatten_command << " flatten ";
flatten_command << "\"" << temp_udco << "\"";
@@ -533,11 +804,11 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
}
temp_image = temp_udco;
- }
+ }
// Create the final compressed read-only disk image ...
- cmOStringStream final_image_command;
+ std::ostringstream final_image_command;
final_image_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
final_image_command << " convert \"" << temp_image << "\"";
final_image_command << " -format ";
@@ -601,3 +872,155 @@ cmCPackDragNDropGenerator::GetComponentInstallDirNameSuffix(
return GetComponentPackageFileName(package_file_name, componentName, false);
}
+
+bool
+cmCPackDragNDropGenerator::WriteLicense(cmGeneratedFileStream& outputStream,
+ int licenseNumber, std::string licenseLanguage, std::string licenseFile,
+ std::string *error)
+{
+ if(!licenseFile.empty() && !singleLicense)
+ {
+ licenseNumber = 5002;
+ licenseLanguage = "English";
+ }
+
+ // License header
+ outputStream << "data 'TEXT' (" << licenseNumber << ", \""
+ << licenseLanguage << "\") {\n";
+ // License body
+ std::string actual_license = !licenseFile.empty() ? licenseFile :
+ (slaDirectory + "/" + licenseLanguage + ".license.txt");
+ cmsys::ifstream license_ifs;
+ license_ifs.open(actual_license.c_str());
+ if(license_ifs.is_open())
+ {
+ while(license_ifs.good())
+ {
+ std::string line;
+ std::getline(license_ifs, line);
+ if(!line.empty())
+ {
+ EscapeQuotesAndBackslashes(line);
+ std::vector<std::string> lines;
+ if(!this->BreakLongLine(line, lines, error))
+ {
+ return false;
+ }
+ for(size_t i = 0; i < lines.size(); ++i)
+ {
+ outputStream << " \"" << lines[i] << "\"\n";
+ }
+ }
+ outputStream << " \"\\n\"\n";
+ }
+ license_ifs.close();
+ }
+
+ // End of License
+ outputStream << "};\n\n";
+ if(!licenseFile.empty() && !singleLicense)
+ {
+ outputStream << SLASTREnglish;
+ }
+ else
+ {
+ // Menu header
+ outputStream << "resource 'STR#' (" << licenseNumber << ", \""
+ << licenseLanguage << "\") {\n";
+ outputStream << " {\n";
+
+ // Menu body
+ cmsys::ifstream menu_ifs;
+ menu_ifs.open((slaDirectory+"/"+licenseLanguage+".menu.txt").c_str());
+ if(menu_ifs.is_open())
+ {
+ size_t lines_written = 0;
+ while(menu_ifs.good())
+ {
+ // Lines written from original file, not from broken up lines
+ std::string line;
+ std::getline(menu_ifs, line);
+ if(!line.empty())
+ {
+ EscapeQuotesAndBackslashes(line);
+ std::vector<std::string> lines;
+ if(!this->BreakLongLine(line, lines, error))
+ {
+ return false;
+ }
+ for(size_t i = 0; i < lines.size(); ++i)
+ {
+ std::string comma;
+ // We need a comma after every complete string,
+ // but not on the very last line
+ if(lines_written != 8 && i == lines.size() - 1)
+ {
+ comma = ",";
+ }
+ else
+ {
+ comma = "";
+ }
+ outputStream << " \"" << lines[i] << "\"" << comma << "\n";
+ }
+ ++lines_written;
+ }
+ }
+ menu_ifs.close();
+ }
+
+ //End of menu
+ outputStream << " }\n";
+ outputStream << "};\n";
+ outputStream << "\n";
+ }
+
+ return true;
+}
+
+bool
+cmCPackDragNDropGenerator::BreakLongLine(const std::string& line,
+ std::vector<std::string>& lines, std::string *error)
+{
+ const size_t max_line_length = 512;
+ for(size_t i = 0; i < line.size(); i += max_line_length)
+ {
+ size_t line_length = max_line_length;
+ if(i + line_length > line.size())
+ {
+ line_length = line.size() - i;
+ }
+ else while(line_length > 0 && line[i + line_length - 1] != ' ')
+ {
+ line_length = line_length - 1;
+ }
+
+ if(line_length == 0)
+ {
+ *error = "Please make sure there are no words "
+ "(or character sequences not broken up by spaces or newlines) "
+ "in your license file which are more than 512 characters long.";
+ return false;
+ }
+ lines.push_back(line.substr(i, line_length));
+ }
+ return true;
+}
+
+void
+cmCPackDragNDropGenerator::EscapeQuotesAndBackslashes(std::string& line)
+{
+ std::string::size_type backslash_pos = line.find('\\');
+ while(backslash_pos != std::string::npos)
+ {
+ line.replace(backslash_pos, 1, "\\\\");
+ backslash_pos = line.find('\\', backslash_pos + 2);
+ }
+
+ std::string::size_type quote_pos = line.find('\"');
+ while(quote_pos != std::string::npos)
+ {
+ line.replace(quote_pos, 1, "\\\"");
+ quote_pos = line.find('\"', quote_pos + 2);
+ }
+}
diff --git a/Source/CPack/cmCPackDragNDropGenerator.h b/Source/CPack/cmCPackDragNDropGenerator.h
index 808c61886..604cdf586 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.h
+++ b/Source/CPack/cmCPackDragNDropGenerator.h
@@ -15,6 +15,8 @@
#include "cmCPackGenerator.h"
+class cmGeneratedFileStream;
+
/** \class cmCPackDragNDropGenerator
* \brief A generator for OSX drag-n-drop installs
*/
@@ -33,8 +35,9 @@ protected:
bool SupportsComponentInstallation() const;
- bool CopyFile(cmOStringStream& source, cmOStringStream& target);
- bool RunCommand(cmOStringStream& command, std::string* output = 0);
+ bool CopyFile(std::ostringstream& source, std::ostringstream& target);
+ bool CreateEmptyFile(std::ostringstream& target, size_t size);
+ bool RunCommand(std::ostringstream& command, std::string* output = 0);
std::string
GetComponentInstallDirNameSuffix(const std::string& componentName);
@@ -42,6 +45,18 @@ protected:
int CreateDMG(const std::string& src_dir, const std::string& output_file);
std::string InstallPrefix;
+
+private:
+ std::string slaDirectory;
+ bool singleLicense;
+
+ bool WriteLicense(cmGeneratedFileStream& outputStream, int licenseNumber,
+ std::string licenseLanguage, std::string licenseFile,
+ std::string *error);
+ bool BreakLongLine(const std::string& line,
+ std::vector<std::string>& lines,
+ std::string *error);
+ void EscapeQuotesAndBackslashes(std::string& line);
};
#endif
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index 3c685bd9d..22d4bf06d 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -16,17 +16,19 @@
#include "cmCPackLog.h"
#include "cmake.h"
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
#include "cmGeneratedFileStream.h"
#include "cmCPackComponentGroup.h"
#include "cmXMLSafe.h"
#include <cmsys/SystemTools.hxx>
#include <cmsys/Glob.hxx>
+#include <cmsys/FStream.hxx>
#include <algorithm>
+#include <list>
#if defined(__HAIKU__)
-#include <StorageKit.h>
+#include <FindDirectory.h>
+#include <StorageDefs.h>
#endif
//----------------------------------------------------------------------
@@ -151,14 +153,14 @@ int cmCPackGenerator::PrepareNames()
<< descFileName << "]" << std::endl);
return 0;
}
- std::ifstream ifs(descFileName);
+ cmsys::ifstream ifs(descFileName);
if ( !ifs )
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Cannot open description file name: " << descFileName << std::endl);
return 0;
}
- cmOStringStream ostr;
+ std::ostringstream ostr;
std::string line;
cmCPackLogger(cmCPackLog::LOG_VERBOSE,
@@ -215,7 +217,7 @@ int cmCPackGenerator::InstallProject()
{
std::string destDir = "DESTDIR=";
destDir += tempInstallDirectory;
- cmSystemTools::PutEnv(destDir.c_str());
+ cmSystemTools::PutEnv(destDir);
}
else
{
@@ -252,7 +254,7 @@ int cmCPackGenerator::InstallProject()
// If the project is a CMAKE project then run pre-install
// and then read the cmake_install script to run it
if ( !this->InstallProjectViaInstallCMakeProjects(
- setDestDir, bareTempInstallDirectory.c_str()) )
+ setDestDir, bareTempInstallDirectory) )
{
return 0;
}
@@ -267,7 +269,7 @@ int cmCPackGenerator::InstallProject()
//----------------------------------------------------------------------
int cmCPackGenerator::InstallProjectViaInstallCommands(
- bool setDestDir, const char* tempInstallDirectory)
+ bool setDestDir, const std::string& tempInstallDirectory)
{
(void) setDestDir;
const char* installCommands = this->GetOption("CPACK_INSTALL_COMMANDS");
@@ -275,7 +277,7 @@ int cmCPackGenerator::InstallProjectViaInstallCommands(
{
std::string tempInstallDirectoryEnv = "CMAKE_INSTALL_PREFIX=";
tempInstallDirectoryEnv += tempInstallDirectory;
- cmSystemTools::PutEnv(tempInstallDirectoryEnv.c_str());
+ cmSystemTools::PutEnv(tempInstallDirectoryEnv);
std::vector<std::string> installCommandsVector;
cmSystemTools::ExpandListArgument(installCommands,installCommandsVector);
std::vector<std::string>::iterator it;
@@ -283,23 +285,24 @@ int cmCPackGenerator::InstallProjectViaInstallCommands(
it != installCommandsVector.end();
++it )
{
- cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << it->c_str()
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << *it
<< std::endl);
std::string output;
int retVal = 1;
- bool resB = cmSystemTools::RunSingleCommand(it->c_str(), &output,
+ bool resB = cmSystemTools::RunSingleCommand(
+ it->c_str(), &output, &output,
&retVal, 0, this->GeneratorVerbose, 0);
if ( !resB || retVal )
{
std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
tmpFile += "/InstallOutput.log";
cmGeneratedFileStream ofs(tmpFile.c_str());
- ofs << "# Run command: " << it->c_str() << std::endl
+ ofs << "# Run command: " << *it << std::endl
<< "# Output:" << std::endl
- << output.c_str() << std::endl;
+ << output << std::endl;
cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Problem running install command: " << it->c_str() << std::endl
- << "Please check " << tmpFile.c_str() << " for errors"
+ "Problem running install command: " << *it << std::endl
+ << "Please check " << tmpFile << " for errors"
<< std::endl);
return 0;
}
@@ -310,7 +313,7 @@ int cmCPackGenerator::InstallProjectViaInstallCommands(
//----------------------------------------------------------------------
int cmCPackGenerator::InstallProjectViaInstalledDirectories(
- bool setDestDir, const char* tempInstallDirectory)
+ bool setDestDir, const std::string& tempInstallDirectory)
{
(void)setDestDir;
(void)tempInstallDirectory;
@@ -327,7 +330,7 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
++it )
{
cmCPackLogger(cmCPackLog::LOG_VERBOSE,
- "Create ignore files regex for: " << it->c_str() << std::endl);
+ "Create ignore files regex for: " << *it << std::endl);
ignoreFilesRegex.push_back(it->c_str());
}
}
@@ -347,7 +350,7 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
return 0;
}
std::vector<std::string>::iterator it;
- const char* tempDir = tempInstallDirectory;
+ const std::string& tempDir = tempInstallDirectory;
for ( it = installDirectoriesVector.begin();
it != installDirectoriesVector.end();
++it )
@@ -355,14 +358,15 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
std::list<std::pair<std::string,std::string> > symlinkedFiles;
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Find files" << std::endl);
cmsys::Glob gl;
- std::string top = it->c_str();
+ std::string top = *it;
it ++;
- std::string subdir = it->c_str();
+ std::string subdir = *it;
std::string findExpr = top;
findExpr += "/*";
cmCPackLogger(cmCPackLog::LOG_OUTPUT,
"- Install directory: " << top << std::endl);
gl.RecurseOn();
+ gl.SetRecurseListDirs(true);
if ( !gl.FindFiles(findExpr) )
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -375,7 +379,11 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
for ( gfit = files.begin(); gfit != files.end(); ++ gfit )
{
bool skip = false;
- std::string &inFile = *gfit;
+ std::string inFile = *gfit;
+ if(cmSystemTools::FileIsDirectory(*gfit))
+ {
+ inFile += '/';
+ }
for ( regIt= ignoreFilesRegex.begin();
regIt!= ignoreFilesRegex.end();
++ regIt)
@@ -383,7 +391,7 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
if ( regIt->find(inFile.c_str()) )
{
cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Ignore file: "
- << inFile.c_str() << std::endl);
+ << inFile << std::endl);
skip = true;
}
}
@@ -395,14 +403,14 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
filePath += "/" + subdir + "/"
+ cmSystemTools::RelativePath(top.c_str(), gfit->c_str());
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Copy file: "
- << inFile.c_str() << " -> " << filePath.c_str() << std::endl);
+ << inFile << " -> " << filePath << std::endl);
/* If the file is a symlink we will have to re-create it */
- if ( cmSystemTools::FileIsSymlink(inFile.c_str()))
+ if ( cmSystemTools::FileIsSymlink(inFile))
{
std::string targetFile;
std::string inFileRelative =
cmSystemTools::RelativePath(top.c_str(),inFile.c_str());
- cmSystemTools::ReadSymlink(inFile.c_str(),targetFile);
+ cmSystemTools::ReadSymlink(inFile,targetFile);
symlinkedFiles.push_back(std::pair<std::string,
std::string>(targetFile,inFileRelative));
}
@@ -414,12 +422,12 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
) )
{
cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem copying file: "
- << inFile.c_str() << " -> " << filePath.c_str() << std::endl);
+ << inFile << " -> " << filePath << std::endl);
return 0;
}
}
/* rebuild symlinks in the installed tree */
- if (symlinkedFiles.size()>0)
+ if (!symlinkedFiles.empty())
{
std::list< std::pair<std::string,std::string> >::iterator symlinkedIt;
std::string curDir = cmSystemTools::GetCurrentWorkingDirectory();
@@ -427,7 +435,7 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
goToDir += "/"+subdir;
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"Change dir to: " << goToDir <<std::endl);
- cmSystemTools::ChangeDirectory(goToDir.c_str());
+ cmSystemTools::ChangeDirectory(goToDir);
for (symlinkedIt=symlinkedFiles.begin();
symlinkedIt != symlinkedFiles.end();
++symlinkedIt)
@@ -435,8 +443,20 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Will create a symlink: "
<< symlinkedIt->second << "--> "
<< symlinkedIt->first << std::endl);
- if (!cmSystemTools::CreateSymlink((symlinkedIt->first).c_str(),
- (symlinkedIt->second).c_str()))
+ // make sure directory exists for symlink
+ std::string destDir =
+ cmSystemTools::GetFilenamePath(symlinkedIt->second);
+ if(!destDir.empty() && !cmSystemTools::MakeDirectory(destDir))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot create dir: "
+ << destDir
+ << "\nTrying to create symlink: "
+ << symlinkedIt->second << "--> "
+ << symlinkedIt->first
+ << std::endl);
+ }
+ if (!cmSystemTools::CreateSymlink(symlinkedIt->first,
+ symlinkedIt->second))
{
cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot create symlink: "
<< symlinkedIt->second << "--> "
@@ -446,7 +466,7 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
}
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Going back to: "
<< curDir <<std::endl);
- cmSystemTools::ChangeDirectory(curDir.c_str());
+ cmSystemTools::ChangeDirectory(curDir);
}
}
}
@@ -455,7 +475,7 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
//----------------------------------------------------------------------
int cmCPackGenerator::InstallProjectViaInstallScript(
- bool setDestDir, const char* tempInstallDirectory)
+ bool setDestDir, const std::string& tempInstallDirectory)
{
const char* cmakeScripts
= this->GetOption("CPACK_INSTALL_SCRIPT");
@@ -471,7 +491,7 @@ int cmCPackGenerator::InstallProjectViaInstallScript(
it != cmakeScriptsVector.end();
++it )
{
- std::string installScript = it->c_str();
+ std::string installScript = *it;
cmCPackLogger(cmCPackLog::LOG_OUTPUT,
"- Install script: " << installScript << std::endl);
@@ -497,7 +517,7 @@ int cmCPackGenerator::InstallProjectViaInstallScript(
}
else
{
- this->SetOption("CMAKE_INSTALL_PREFIX", tempInstallDirectory);
+ this->SetOption("CMAKE_INSTALL_PREFIX", tempInstallDirectory.c_str());
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"- Using non-DESTDIR install... (this->SetOption)" << std::endl);
@@ -507,10 +527,10 @@ int cmCPackGenerator::InstallProjectViaInstallScript(
}
this->SetOptionIfNotSet("CMAKE_CURRENT_BINARY_DIR",
- tempInstallDirectory);
+ tempInstallDirectory.c_str());
this->SetOptionIfNotSet("CMAKE_CURRENT_SOURCE_DIR",
- tempInstallDirectory);
- int res = this->MakefileMap->ReadListFile(0, installScript.c_str());
+ tempInstallDirectory.c_str());
+ int res = this->MakefileMap->ReadListFile(installScript.c_str());
if ( cmSystemTools::GetErrorOccuredFlag() || !res )
{
return 0;
@@ -522,7 +542,7 @@ int cmCPackGenerator::InstallProjectViaInstallScript(
//----------------------------------------------------------------------
int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
- bool setDestDir, const char* baseTempInstallDirectory)
+ bool setDestDir, const std::string& baseTempInstallDirectory)
{
const char* cmakeProjects
= this->GetOption("CPACK_INSTALL_CMAKE_PROJECTS");
@@ -560,13 +580,13 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
<< std::endl);
return 0;
}
- std::string installDirectory = it->c_str();
+ std::string installDirectory = *it;
++it;
- std::string installProjectName = it->c_str();
+ std::string installProjectName = *it;
++it;
- std::string installComponent = it->c_str();
+ std::string installComponent = *it;
++it;
- std::string installSubDirectory = it->c_str();
+ std::string installSubDirectory = *it;
std::string installFile = installDirectory + "/cmake_install.cmake";
std::vector<std::string> componentsVector;
@@ -579,12 +599,12 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
* (this works at CPack time too)
*/
if (this->SupportsComponentInstallation() &
- !(this->IsSet("CPACK_MONOLITHIC_INSTALL")))
+ !(this->IsOn("CPACK_MONOLITHIC_INSTALL")))
{
// Determine the installation types for this project (if provided).
std::string installTypesVar = "CPACK_"
+ cmSystemTools::UpperCase(installComponent) + "_INSTALL_TYPES";
- const char *installTypes = this->GetOption(installTypesVar.c_str());
+ const char *installTypes = this->GetOption(installTypesVar);
if (installTypes && *installTypes)
{
std::vector<std::string> installTypesVector;
@@ -594,15 +614,15 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
installTypeIt != installTypesVector.end();
++installTypeIt)
{
- this->GetInstallationType(installProjectName.c_str(),
- installTypeIt->c_str());
+ this->GetInstallationType(installProjectName,
+ *installTypeIt);
}
}
// Determine the set of components that will be used in this project
std::string componentsVar
= "CPACK_COMPONENTS_" + cmSystemTools::UpperCase(installComponent);
- const char *components = this->GetOption(componentsVar.c_str());
+ const char *components = this->GetOption(componentsVar);
if (components && *components)
{
cmSystemTools::ExpandListArgument(components, componentsVector);
@@ -611,7 +631,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
compIt != componentsVector.end();
++compIt)
{
- GetComponent(installProjectName.c_str(), compIt->c_str());
+ GetComponent(installProjectName, *compIt);
}
componentInstall = true;
}
@@ -621,26 +641,30 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
componentsVector.push_back(installComponent);
}
- const char* buildConfig = this->GetOption("CPACK_BUILD_CONFIG");
+ const char* buildConfigCstr = this->GetOption("CPACK_BUILD_CONFIG");
+ std::string buildConfig = buildConfigCstr ? buildConfigCstr : "";
cmGlobalGenerator* globalGenerator
= this->MakefileMap->GetCMakeInstance()->CreateGlobalGenerator(
cmakeGenerator);
+ if ( !globalGenerator )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Specified package generator not found. "
+ "CPACK_CMAKE_GENERATOR value is invalid."
+ << std::endl);
+ return 0;
+ }
// set the global flag for unix style paths on cmSystemTools as
// soon as the generator is set. This allows gmake to be used
// on windows.
cmSystemTools::SetForceUnixPaths(globalGenerator->GetForceUnixPaths());
// Does this generator require pre-install?
- if ( globalGenerator->GetPreinstallTargetName() )
+ if (const char* preinstall = globalGenerator->GetPreinstallTargetName())
{
- globalGenerator->FindMakeProgram(this->MakefileMap);
- const char* cmakeMakeProgram
- = this->MakefileMap->GetDefinition("CMAKE_MAKE_PROGRAM");
- std::string buildCommand
- = globalGenerator->GenerateBuildCommand(cmakeMakeProgram,
- installProjectName.c_str(), 0, 0,
- globalGenerator->GetPreinstallTargetName(),
- buildConfig, false, false);
+ std::string buildCommand =
+ globalGenerator->GenerateCMakeBuildCommand(
+ preinstall, buildConfig, "", false);
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"- Install command: " << buildCommand << std::endl);
cmCPackLogger(cmCPackLog::LOG_OUTPUT,
@@ -649,7 +673,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
int retVal = 1;
bool resB =
cmSystemTools::RunSingleCommand(buildCommand.c_str(),
- &output,
+ &output, &output,
&retVal,
installDirectory.c_str(),
this->GeneratorVerbose, 0);
@@ -658,14 +682,14 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
tmpFile += "/PreinstallOutput.log";
cmGeneratedFileStream ofs(tmpFile.c_str());
- ofs << "# Run command: " << buildCommand.c_str() << std::endl
- << "# Directory: " << installDirectory.c_str() << std::endl
+ ofs << "# Run command: " << buildCommand << std::endl
+ << "# Directory: " << installDirectory << std::endl
<< "# Output:" << std::endl
- << output.c_str() << std::endl;
+ << output << std::endl;
cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Problem running install command: " << buildCommand.c_str()
+ "Problem running install command: " << buildCommand
<< std::endl
- << "Please check " << tmpFile.c_str() << " for errors"
+ << "Please check " << tmpFile << " for errors"
<< std::endl);
return 0;
}
@@ -691,12 +715,14 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
}
cmake cm;
+ cm.SetHomeDirectory("");
+ cm.SetHomeOutputDirectory("");
+ cm.GetCurrentSnapshot().SetDefaultDefinitions();
cm.AddCMakePaths();
cm.SetProgressCallback(cmCPackGeneratorProgress, this);
- cmGlobalGenerator gg;
- gg.SetCMakeInstance(&cm);
- cmsys::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator());
- cmMakefile *mf = lg->GetMakefile();
+ cmGlobalGenerator gg(&cm);
+ cmsys::auto_ptr<cmMakefile> mf(
+ new cmMakefile(&gg, cm.GetCurrentSnapshot()));
std::string realInstallDirectory = tempInstallDirectory;
if ( !installSubDirectory.empty() && installSubDirectory != "/" )
{
@@ -782,7 +808,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
* in order to put things in subdirs...
*/
cmSystemTools::PutEnv(
- (std::string("DESTDIR=")+tempInstallDirectory).c_str()
+ std::string("DESTDIR=")+tempInstallDirectory
);
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"- Creating directory: '" << dir << "'" << std::endl);
@@ -818,9 +844,9 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
<< "'" << std::endl);
}
- if ( buildConfig && *buildConfig )
+ if (!buildConfig.empty())
{
- mf->AddDefinition("BUILD_TYPE", buildConfig);
+ mf->AddDefinition("BUILD_TYPE", buildConfig.c_str());
}
std::string installComponentLowerCase
= cmSystemTools::LowerCase(installComponent);
@@ -846,6 +872,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
cmsys::Glob glB;
findExpr += "/*";
glB.RecurseOn();
+ glB.SetRecurseListDirs(true);
glB.FindFiles(findExpr);
filesBefore = glB.GetFiles();
std::sort(filesBefore.begin(),filesBefore.end());
@@ -869,7 +896,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
"1");
}
// do installation
- int res = mf->ReadListFile(0, installFile.c_str());
+ int res = mf->ReadListFile(installFile.c_str());
// forward definition of CMAKE_ABSOLUTE_DESTINATION_FILES
// to CPack (may be used by generators like CPack RPM or DEB)
// in order to transparently handle ABSOLUTE PATH
@@ -885,6 +912,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
{
cmsys::Glob glA;
glA.RecurseOn();
+ glA.SetRecurseListDirs(true);
glA.FindFiles(findExpr);
std::vector<std::string> filesAfter = glA.GetFiles();
std::sort(filesAfter.begin(),filesAfter.end());
@@ -913,7 +941,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
}
if (NULL !=mf->GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES")) {
- if (absoluteDestFiles.length()>0) {
+ if (!absoluteDestFiles.empty()) {
absoluteDestFiles +=";";
}
absoluteDestFiles +=
@@ -927,19 +955,19 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
std::string absoluteDestFileComponent =
std::string("CPACK_ABSOLUTE_DESTINATION_FILES")
+ "_" + GetComponentInstallDirNameSuffix(installComponent);
- if (NULL != this->GetOption(absoluteDestFileComponent.c_str()))
+ if (NULL != this->GetOption(absoluteDestFileComponent))
{
std::string absoluteDestFilesListComponent =
- this->GetOption(absoluteDestFileComponent.c_str());
+ this->GetOption(absoluteDestFileComponent);
absoluteDestFilesListComponent +=";";
absoluteDestFilesListComponent +=
mf->GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES");
- this->SetOption(absoluteDestFileComponent.c_str(),
+ this->SetOption(absoluteDestFileComponent,
absoluteDestFilesListComponent.c_str());
}
else
{
- this->SetOption(absoluteDestFileComponent.c_str(),
+ this->SetOption(absoluteDestFileComponent,
mf->GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES"));
}
}
@@ -961,14 +989,14 @@ bool cmCPackGenerator::ReadListFile(const char* moduleName)
{
bool retval;
std::string fullPath = this->MakefileMap->GetModulesFile(moduleName);
- retval = this->MakefileMap->ReadListFile(0, fullPath.c_str());
+ retval = this->MakefileMap->ReadListFile(fullPath.c_str());
// include FATAL_ERROR and ERROR in the return status
retval = retval && (! cmSystemTools::GetErrorOccuredFlag());
return retval;
}
//----------------------------------------------------------------------
-void cmCPackGenerator::SetOptionIfNotSet(const char* op,
+void cmCPackGenerator::SetOptionIfNotSet(const std::string& op,
const char* value)
{
const char* def = this->MakefileMap->GetDefinition(op);
@@ -980,12 +1008,8 @@ void cmCPackGenerator::SetOptionIfNotSet(const char* op,
}
//----------------------------------------------------------------------
-void cmCPackGenerator::SetOption(const char* op, const char* value)
+void cmCPackGenerator::SetOption(const std::string& op, const char* value)
{
- if ( !op )
- {
- return;
- }
if ( !value )
{
this->MakefileMap->RemoveDefinition(op);
@@ -1000,7 +1024,7 @@ void cmCPackGenerator::SetOption(const char* op, const char* value)
int cmCPackGenerator::DoPackage()
{
cmCPackLogger(cmCPackLog::LOG_OUTPUT,
- "Create package using " << this->Name.c_str() << std::endl);
+ "Create package using " << this->Name << std::endl);
// Prepare CPack internal name and check
// values for many CPACK_xxx vars
@@ -1048,7 +1072,6 @@ int cmCPackGenerator::DoPackage()
const char* tempPackageFileName = this->GetOption(
"CPACK_TEMPORARY_PACKAGE_FILE_NAME");
- const char* packageFileName = this->GetOption("CPACK_OUTPUT_FILE_PATH");
const char* tempDirectory = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Find files" << std::endl);
@@ -1056,6 +1079,7 @@ int cmCPackGenerator::DoPackage()
std::string findExpr = tempDirectory;
findExpr += "/*";
gl.RecurseOn();
+ gl.SetRecurseListDirs(true);
gl.SetRecurseThroughSymlinks(false);
if ( !gl.FindFiles(findExpr) )
{
@@ -1088,7 +1112,7 @@ int cmCPackGenerator::DoPackage()
* may update this during PackageFiles.
* (either putting several names or updating the provided one)
*/
- packageFileNames.push_back(tempPackageFileName);
+ packageFileNames.push_back(tempPackageFileName ? tempPackageFileName : "");
toplevel = tempDirectory;
if ( !this->PackageFiles() || cmSystemTools::GetErrorOccuredFlag())
{
@@ -1113,7 +1137,7 @@ int cmCPackGenerator::DoPackage()
std::string tmpPF(this->GetOption("CPACK_OUTPUT_FILE_PREFIX"));
tempPackageFileName = it->c_str();
tmpPF += "/"+cmSystemTools::GetFilenameName(*it);
- packageFileName = tmpPF.c_str();
+ const char* packageFileName = tmpPF.c_str();
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Copy final package(s): "
<< (tempPackageFileName ? tempPackageFileName : "(NULL)" )
<< " to "
@@ -1138,16 +1162,10 @@ int cmCPackGenerator::DoPackage()
}
//----------------------------------------------------------------------
-int cmCPackGenerator::Initialize(const char* name, cmMakefile* mf)
+int cmCPackGenerator::Initialize(const std::string& name, cmMakefile* mf)
{
this->MakefileMap = mf;
this->Name = name;
- if ( !this->SetCMakeRoot() )
- {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Cannot initialize the generator" << std::endl);
- return 0;
- }
// set the running generator name
this->SetOption("CPACK_GENERATOR", this->Name.c_str());
// Load the project specific config file
@@ -1178,19 +1196,19 @@ int cmCPackGenerator::InitializeInternal()
}
//----------------------------------------------------------------------
-bool cmCPackGenerator::IsSet(const char* name) const
+bool cmCPackGenerator::IsSet(const std::string& name) const
{
return this->MakefileMap->IsSet(name);
}
//----------------------------------------------------------------------
-bool cmCPackGenerator::IsOn(const char* name) const
+bool cmCPackGenerator::IsOn(const std::string& name) const
{
return cmSystemTools::IsOn(GetOption(name));
}
//----------------------------------------------------------------------
-const char* cmCPackGenerator::GetOption(const char* op) const
+const char* cmCPackGenerator::GetOption(const std::string& op) const
{
const char* ret = this->MakefileMap->GetDefinition(op);
if(!ret)
@@ -1204,29 +1222,9 @@ const char* cmCPackGenerator::GetOption(const char* op) const
}
//----------------------------------------------------------------------
-int cmCPackGenerator::SetCMakeRoot()
+std::vector<std::string> cmCPackGenerator::GetOptions() const
{
- // use the CMAKE_ROOT from cmake which should have been
- // found by now
- const char* root=
- this->MakefileMap->GetDefinition("CMAKE_ROOT");
-
- if(root)
- {
- this->CMakeRoot = root;
- cmCPackLogger(cmCPackLog::LOG_DEBUG, "Looking for CMAKE_ROOT: "
- << this->CMakeRoot.c_str() << std::endl);
- this->SetOption("CMAKE_ROOT", this->CMakeRoot.c_str());
- return 1;
- }
- 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);
- return 0;
+ return this->MakefileMap->GetDefinitions();
}
//----------------------------------------------------------------------
@@ -1263,14 +1261,14 @@ const char* cmCPackGenerator::GetInstallPath()
this->InstallPath += "-";
this->InstallPath += this->GetOption("CPACK_PACKAGE_VERSION");
#elif defined(__HAIKU__)
- BPath dir;
- if (find_directory(B_COMMON_DIRECTORY, &dir) == B_OK)
+ char dir[B_PATH_NAME_LENGTH];
+ if (find_directory(B_SYSTEM_DIRECTORY, -1, false, dir, sizeof(dir)) == B_OK)
{
- this->InstallPath = dir.Path();
+ this->InstallPath = dir;
}
else
{
- this->InstallPath = "/boot/common";
+ this->InstallPath = "/boot/system";
}
#else
this->InstallPath = "/usr/local/";
@@ -1294,7 +1292,7 @@ std::string cmCPackGenerator::FindTemplate(const char* name)
<< (name ? name : "(NULL)") << std::endl);
std::string ffile = this->MakefileMap->GetModulesFile(name);
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Found template: "
- << ffile.c_str() << std::endl);
+ << ffile << std::endl);
return ffile;
}
@@ -1339,6 +1337,14 @@ int cmCPackGenerator::CleanTemporaryDirectory()
}
//----------------------------------------------------------------------
+cmInstalledFile const* cmCPackGenerator::GetInstalledFile(
+ std::string const& name) const
+{
+ cmake const* cm = this->MakefileMap->GetCMakeInstance();
+ return cm->GetInstalledFile(name);
+}
+
+//----------------------------------------------------------------------
int cmCPackGenerator::PrepareGroupingKind()
{
// find a component package method specified by the user
@@ -1366,7 +1372,7 @@ int cmCPackGenerator::PrepareGroupingKind()
groupingType = this->GetOption("CPACK_COMPONENTS_GROUPING");
}
- if (groupingType.length()>0)
+ if (!groupingType.empty())
{
cmCPackLogger(cmCPackLog::LOG_VERBOSE, "["
<< this->Name << "]"
@@ -1453,14 +1459,14 @@ std::string cmCPackGenerator::GetComponentPackageFileName(
std::string suffix="-"+groupOrComponentName;
/* check if we should use DISPLAY name */
std::string dispNameVar = "CPACK_"+Name+"_USE_DISPLAY_NAME_IN_FILENAME";
- if (IsOn(dispNameVar.c_str()))
+ if (IsOn(dispNameVar))
{
/* the component Group case */
if (isGroupName)
{
std::string groupDispVar = "CPACK_COMPONENT_GROUP_"
+ cmSystemTools::UpperCase(groupOrComponentName) + "_DISPLAY_NAME";
- const char* groupDispName = GetOption(groupDispVar.c_str());
+ const char* groupDispName = GetOption(groupDispVar);
if (groupDispName)
{
suffix = "-"+std::string(groupDispName);
@@ -1471,7 +1477,7 @@ std::string cmCPackGenerator::GetComponentPackageFileName(
{
std::string dispVar = "CPACK_COMPONENT_"
+ cmSystemTools::UpperCase(groupOrComponentName) + "_DISPLAY_NAME";
- const char* dispName = GetOption(dispVar.c_str());
+ const char* dispName = GetOption(dispVar);
if(dispName)
{
suffix = "-"+std::string(dispName);
@@ -1503,13 +1509,16 @@ bool cmCPackGenerator::SupportsComponentInstallation() const
//----------------------------------------------------------------------
bool cmCPackGenerator::WantsComponentInstallation() const
{
- return (!IsOn("CPACK_MONOLITHIC_INSTALL") & SupportsComponentInstallation());
+ return (!IsOn("CPACK_MONOLITHIC_INSTALL")
+ && SupportsComponentInstallation()
+ // check that we have at least one group or component
+ && (!this->ComponentGroups.empty() || !this->Components.empty()));
}
//----------------------------------------------------------------------
cmCPackInstallationType*
-cmCPackGenerator::GetInstallationType(const char *projectName,
- const char *name)
+cmCPackGenerator::GetInstallationType(const std::string& projectName,
+ const std::string& name)
{
(void) projectName;
bool hasInstallationType = this->InstallationTypes.count(name) != 0;
@@ -1522,7 +1531,7 @@ cmCPackGenerator::GetInstallationType(const char *projectName,
installType->Name = name;
const char* displayName
- = this->GetOption((macroPrefix + "_DISPLAY_NAME").c_str());
+ = this->GetOption(macroPrefix + "_DISPLAY_NAME");
if (displayName && *displayName)
{
installType->DisplayName = displayName;
@@ -1540,7 +1549,8 @@ cmCPackGenerator::GetInstallationType(const char *projectName,
//----------------------------------------------------------------------
cmCPackComponent*
-cmCPackGenerator::GetComponent(const char *projectName, const char *name)
+cmCPackGenerator::GetComponent(const std::string& projectName,
+ const std::string& name)
{
bool hasComponent = this->Components.count(name) != 0;
cmCPackComponent *component = &this->Components[name];
@@ -1551,7 +1561,7 @@ cmCPackGenerator::GetComponent(const char *projectName, const char *name)
+ cmsys::SystemTools::UpperCase(name);
component->Name = name;
const char* displayName
- = this->GetOption((macroPrefix + "_DISPLAY_NAME").c_str());
+ = this->GetOption(macroPrefix + "_DISPLAY_NAME");
if (displayName && *displayName)
{
component->DisplayName = displayName;
@@ -1561,23 +1571,23 @@ cmCPackGenerator::GetComponent(const char *projectName, const char *name)
component->DisplayName = component->Name;
}
component->IsHidden
- = this->IsSet((macroPrefix + "_HIDDEN").c_str());
+ = this->IsOn(macroPrefix + "_HIDDEN");
component->IsRequired
- = this->IsSet((macroPrefix + "_REQUIRED").c_str());
+ = this->IsOn(macroPrefix + "_REQUIRED");
component->IsDisabledByDefault
- = this->IsSet((macroPrefix + "_DISABLED").c_str());
+ = this->IsOn(macroPrefix + "_DISABLED");
component->IsDownloaded
- = this->IsSet((macroPrefix + "_DOWNLOADED").c_str())
+ = this->IsOn(macroPrefix + "_DOWNLOADED")
|| cmSystemTools::IsOn(this->GetOption("CPACK_DOWNLOAD_ALL"));
- const char* archiveFile = this->GetOption((macroPrefix +
- "_ARCHIVE_FILE").c_str());
+ const char* archiveFile = this->GetOption(macroPrefix +
+ "_ARCHIVE_FILE");
if (archiveFile && *archiveFile)
{
component->ArchiveFile = archiveFile;
}
- const char* groupName = this->GetOption((macroPrefix + "_GROUP").c_str());
+ const char* groupName = this->GetOption(macroPrefix + "_GROUP");
if (groupName && *groupName)
{
component->Group = GetComponentGroup(projectName, groupName);
@@ -1589,7 +1599,7 @@ cmCPackGenerator::GetComponent(const char *projectName, const char *name)
}
const char* description
- = this->GetOption((macroPrefix + "_DESCRIPTION").c_str());
+ = this->GetOption(macroPrefix + "_DESCRIPTION");
if (description && *description)
{
component->Description = description;
@@ -1597,7 +1607,7 @@ cmCPackGenerator::GetComponent(const char *projectName, const char *name)
// Determine the installation types.
const char *installTypes
- = this->GetOption((macroPrefix + "_INSTALL_TYPES").c_str());
+ = this->GetOption(macroPrefix + "_INSTALL_TYPES");
if (installTypes && *installTypes)
{
std::vector<std::string> installTypesVector;
@@ -1608,12 +1618,12 @@ cmCPackGenerator::GetComponent(const char *projectName, const char *name)
++installTypesIt)
{
component->InstallationTypes.push_back(
- this->GetInstallationType(projectName, installTypesIt->c_str()));
+ this->GetInstallationType(projectName, *installTypesIt));
}
}
// Determine the component dependencies.
- const char *depends = this->GetOption((macroPrefix + "_DEPENDS").c_str());
+ const char *depends = this->GetOption(macroPrefix + "_DEPENDS");
if (depends && *depends)
{
std::vector<std::string> dependsVector;
@@ -1624,7 +1634,7 @@ cmCPackGenerator::GetComponent(const char *projectName, const char *name)
++dependIt)
{
cmCPackComponent *child = GetComponent(projectName,
- dependIt->c_str());
+ *dependIt);
component->Dependencies.push_back(child);
child->ReverseDependencies.push_back(component);
}
@@ -1635,7 +1645,8 @@ cmCPackGenerator::GetComponent(const char *projectName, const char *name)
//----------------------------------------------------------------------
cmCPackComponentGroup*
-cmCPackGenerator::GetComponentGroup(const char *projectName, const char *name)
+cmCPackGenerator::GetComponentGroup(const std::string& projectName,
+ const std::string& name)
{
(void) projectName;
std::string macroPrefix = "CPACK_COMPONENT_GROUP_"
@@ -1647,7 +1658,7 @@ cmCPackGenerator::GetComponentGroup(const char *projectName, const char *name)
// Define the group
group->Name = name;
const char* displayName
- = this->GetOption((macroPrefix + "_DISPLAY_NAME").c_str());
+ = this->GetOption(macroPrefix + "_DISPLAY_NAME");
if (displayName && *displayName)
{
group->DisplayName = displayName;
@@ -1658,17 +1669,17 @@ cmCPackGenerator::GetComponentGroup(const char *projectName, const char *name)
}
const char* description
- = this->GetOption((macroPrefix + "_DESCRIPTION").c_str());
+ = this->GetOption(macroPrefix + "_DESCRIPTION");
if (description && *description)
{
group->Description = description;
}
group->IsBold
- = this->IsSet((macroPrefix + "_BOLD_TITLE").c_str());
+ = this->IsOn(macroPrefix + "_BOLD_TITLE");
group->IsExpandedByDefault
- = this->IsSet((macroPrefix + "_EXPANDED").c_str());
+ = this->IsOn(macroPrefix + "_EXPANDED");
const char* parentGroupName
- = this->GetOption((macroPrefix + "_PARENT_GROUP").c_str());
+ = this->GetOption(macroPrefix + "_PARENT_GROUP");
if (parentGroupName && *parentGroupName)
{
group->ParentGroup = GetComponentGroup(projectName, parentGroupName);
diff --git a/Source/CPack/cmCPackGenerator.h b/Source/CPack/cmCPackGenerator.h
index 8fafef93d..907bb1ee1 100644
--- a/Source/CPack/cmCPackGenerator.h
+++ b/Source/CPack/cmCPackGenerator.h
@@ -22,13 +22,14 @@
// Forward declarations are insufficient since we use them in
// std::map data members below...
-#define cmCPackTypeMacro(class, superclass) \
- cmTypeMacro(class, superclass); \
- static cmCPackGenerator* CreateGenerator() { return new class; }
+#define cmCPackTypeMacro(klass, superclass) \
+ cmTypeMacro(klass, superclass); \
+ static cmCPackGenerator* CreateGenerator() { return new klass; } \
+ class cmCPackTypeMacro_UseTrailingSemicolon
#define cmCPackLogger(logType, msg) \
do { \
- cmOStringStream cmCPackLog_msg; \
+ std::ostringstream cmCPackLog_msg; \
cmCPackLog_msg << msg; \
this->Logger->Log(logType, __FILE__, __LINE__,\
cmCPackLog_msg.str().c_str());\
@@ -46,6 +47,7 @@
class cmMakefile;
class cmCPackLog;
+class cmInstalledFile;
/** \class cmCPackGenerator
* \brief A superclass of all CPack Generators
@@ -90,7 +92,7 @@ public:
/**
* Initialize generator
*/
- int Initialize(const char* name, cmMakefile* mf);
+ int Initialize(const std::string& name, cmMakefile* mf);
/**
* Construct generator
@@ -99,14 +101,12 @@ public:
virtual ~cmCPackGenerator();
//! Set and get the options
- void SetOption(const char* op, const char* value);
- void SetOptionIfNotSet(const char* op, const char* value);
- const char* GetOption(const char* op) const;
- bool IsSet(const char* name) const;
- bool IsOn(const char* name) const;
-
- //! Set all the variables
- int SetCMakeRoot();
+ void SetOption(const std::string& op, const char* value);
+ void SetOptionIfNotSet(const std::string& op, const char* value);
+ const char* GetOption(const std::string& op) const;
+ std::vector<std::string> GetOptions() const;
+ bool IsSet(const std::string& name) const;
+ bool IsOn(const std::string& name) const;
//! Set the logger
void SetLogger(cmCPackLog* log) { this->Logger = log; }
@@ -130,6 +130,8 @@ protected:
int CleanTemporaryDirectory();
+ cmInstalledFile const* GetInstalledFile(std::string const& name) const;
+
virtual const char* GetOutputExtension() { return ".cpack"; }
virtual const char* GetOutputPostfix() { return 0; }
@@ -160,9 +162,10 @@ protected:
* CPack specific generator may mangle CPACK_PACKAGE_FILE_NAME
* with CPACK_COMPONENT_xxxx_<NAME>_DISPLAY_NAME if
* CPACK_<GEN>_USE_DISPLAY_NAME_IN_FILENAME is ON.
- * @param[in] initialPackageFileName
- * @param[in] groupOrComponentName
- * @param[in] isGroupName
+ * @param[in] initialPackageFileName the initial package name to be mangled
+ * @param[in] groupOrComponentName the name of the group/component
+ * @param[in] isGroupName true if previous name refers to a group,
+ * false otherwise
*/
virtual std::string GetComponentPackageFileName(
const std::string& initialPackageFileName,
@@ -172,7 +175,7 @@ protected:
/**
* Package the list of files and/or components which
* has been prepared by the beginning of DoPackage.
- * @pre @ref toplevel has been filled-in
+ * @pre the @ref toplevel has been filled-in
* @pre the list of file @ref files has been populated
* @pre packageFileNames contains at least 1 entry
* @post packageFileNames may have been updated and contains
@@ -191,13 +194,13 @@ protected:
//! Run install commands if specified
virtual int InstallProjectViaInstallCommands(
- bool setDestDir, const char* tempInstallDirectory);
+ bool setDestDir, const std::string& tempInstallDirectory);
virtual int InstallProjectViaInstallScript(
- bool setDestDir, const char* tempInstallDirectory);
+ bool setDestDir, const std::string& tempInstallDirectory);
virtual int InstallProjectViaInstalledDirectories(
- bool setDestDir, const char* tempInstallDirectory);
+ bool setDestDir, const std::string& tempInstallDirectory);
virtual int InstallProjectViaInstallCMakeProjects(
- bool setDestDir, const char* tempInstallDirectory);
+ bool setDestDir, const std::string& tempInstallDirectory);
/**
* The various level of support of
@@ -246,12 +249,14 @@ protected:
* @return true if component installation is supported and wanted.
*/
virtual bool WantsComponentInstallation() const;
- virtual cmCPackInstallationType* GetInstallationType(const char *projectName,
- const char* name);
- virtual cmCPackComponent* GetComponent(const char *projectName,
- const char* name);
- virtual cmCPackComponentGroup* GetComponentGroup(const char *projectName,
- const char* name);
+ virtual cmCPackInstallationType* GetInstallationType(
+ const std::string& projectName,
+ const std::string& name);
+ virtual cmCPackComponent* GetComponent(const std::string& projectName,
+ const std::string& name);
+ virtual cmCPackComponentGroup* GetComponentGroup(
+ const std::string& projectName,
+ const std::string& name);
cmSystemTools::OutputOption GeneratorVerbose;
std::string Name;
@@ -284,10 +289,6 @@ protected:
*/
std::vector<std::string> files;
- std::string CPackSelf;
- std::string CMakeSelf;
- std::string CMakeRoot;
-
std::map<std::string, cmCPackInstallationType> InstallationTypes;
/**
* The set of components.
diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx
index b36c2a2f8..46261427d 100644
--- a/Source/CPack/cmCPackGeneratorFactory.cxx
+++ b/Source/CPack/cmCPackGeneratorFactory.cxx
@@ -14,11 +14,14 @@
#include "cmCPackGenerator.h"
#include "cmCPackTGZGenerator.h"
+#include "cmCPackTXZGenerator.h"
#include "cmCPackTarBZip2Generator.h"
#include "cmCPackTarCompressGenerator.h"
#include "cmCPackZIPGenerator.h"
+#include "cmCPack7zGenerator.h"
#include "cmCPackSTGZGenerator.h"
#include "cmCPackNSISGenerator.h"
+#include "IFW/cmCPackIFWGenerator.h"
#ifdef __APPLE__
# include "cmCPackDragNDropGenerator.h"
@@ -43,10 +46,8 @@
#endif
#include "cmCPackLog.h"
+#include "cmAlgorithms.h"
-#if defined(__BORLANDC__)
-# pragma warn -8008 /* condition is always true */
-#endif
//----------------------------------------------------------------------
cmCPackGeneratorFactory::cmCPackGeneratorFactory()
@@ -56,6 +57,11 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
this->RegisterGenerator("TGZ", "Tar GZip compression",
cmCPackTGZGenerator::CreateGenerator);
}
+ if (cmCPackTXZGenerator::CanGenerate())
+ {
+ this->RegisterGenerator("TXZ", "Tar XZ compression",
+ cmCPackTXZGenerator::CreateGenerator);
+ }
if (cmCPackSTGZGenerator::CanGenerate())
{
this->RegisterGenerator("STGZ", "Self extracting Tar GZip compression",
@@ -68,6 +74,11 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
this->RegisterGenerator("NSIS64", "Null Soft Installer (64-bit)",
cmCPackNSISGenerator::CreateGenerator64);
}
+ if (cmCPackIFWGenerator::CanGenerate())
+ {
+ this->RegisterGenerator("IFW", "Qt Installer Framework",
+ cmCPackIFWGenerator::CreateGenerator);
+ }
#ifdef __CYGWIN__
if (cmCPackCygwinBinaryGenerator::CanGenerate())
{
@@ -86,6 +97,11 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
this->RegisterGenerator("ZIP", "ZIP file format",
cmCPackZIPGenerator::CreateGenerator);
}
+ if (cmCPack7zGenerator::CanGenerate())
+ {
+ this->RegisterGenerator("7Z", "7-Zip file format",
+ cmCPack7zGenerator::CreateGenerator);
+ }
#ifdef _WIN32
if (cmCPackWIXGenerator::CanGenerate())
{
@@ -143,15 +159,12 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
//----------------------------------------------------------------------
cmCPackGeneratorFactory::~cmCPackGeneratorFactory()
{
- std::vector<cmCPackGenerator*>::iterator it;
- for ( it = this->Generators.begin(); it != this->Generators.end(); ++ it )
- {
- delete *it;
- }
+ cmDeleteAll(this->Generators);
}
//----------------------------------------------------------------------
-cmCPackGenerator* cmCPackGeneratorFactory::NewGenerator(const char* name)
+cmCPackGenerator* cmCPackGeneratorFactory::NewGenerator(
+ const std::string& name)
{
cmCPackGenerator* gen = this->NewGeneratorInternal(name);
if ( !gen )
@@ -165,12 +178,8 @@ cmCPackGenerator* cmCPackGeneratorFactory::NewGenerator(const char* name)
//----------------------------------------------------------------------
cmCPackGenerator* cmCPackGeneratorFactory::NewGeneratorInternal(
- const char* name)
+ const std::string& name)
{
- if ( !name )
- {
- return 0;
- }
cmCPackGeneratorFactory::t_GeneratorCreatorsMap::iterator it
= this->GeneratorCreators.find(name);
if ( it == this->GeneratorCreators.end() )
@@ -181,11 +190,11 @@ cmCPackGenerator* cmCPackGeneratorFactory::NewGeneratorInternal(
}
//----------------------------------------------------------------------
-void cmCPackGeneratorFactory::RegisterGenerator(const char* name,
+void cmCPackGeneratorFactory::RegisterGenerator(const std::string& name,
const char* generatorDescription,
CreateGeneratorCall* createGenerator)
{
- if ( !name || !createGenerator )
+ if ( !createGenerator )
{
cmCPack_Log(this->Logger, cmCPackLog::LOG_ERROR,
"Cannot register generator" << std::endl);
diff --git a/Source/CPack/cmCPackGeneratorFactory.h b/Source/CPack/cmCPackGeneratorFactory.h
index dff2e49eb..010777f25 100644
--- a/Source/CPack/cmCPackGeneratorFactory.h
+++ b/Source/CPack/cmCPackGeneratorFactory.h
@@ -31,26 +31,26 @@ public:
~cmCPackGeneratorFactory();
//! Get the generator
- cmCPackGenerator* NewGenerator(const char* name);
+ cmCPackGenerator* NewGenerator(const std::string& name);
void DeleteGenerator(cmCPackGenerator* gen);
typedef cmCPackGenerator* CreateGeneratorCall();
- void RegisterGenerator(const char* name,
+ void RegisterGenerator(const std::string& name,
const char* generatorDescription,
CreateGeneratorCall* createGenerator);
void SetLogger(cmCPackLog* logger) { this->Logger = logger; }
- typedef std::map<cmStdString, cmStdString> DescriptionsMap;
+ typedef std::map<std::string, std::string> DescriptionsMap;
const DescriptionsMap& GetGeneratorsList() const
{ return this->GeneratorDescriptions; }
private:
- cmCPackGenerator* NewGeneratorInternal(const char* name);
+ cmCPackGenerator* NewGeneratorInternal(const std::string& name);
std::vector<cmCPackGenerator*> Generators;
- typedef std::map<cmStdString, CreateGeneratorCall*> t_GeneratorCreatorsMap;
+ typedef std::map<std::string, CreateGeneratorCall*> t_GeneratorCreatorsMap;
t_GeneratorCreatorsMap GeneratorCreators;
DescriptionsMap GeneratorDescriptions;
cmCPackLog* Logger;
diff --git a/Source/CPack/cmCPackLog.cxx b/Source/CPack/cmCPackLog.cxx
index 4e8bf0f4e..7633ac2e1 100644
--- a/Source/CPack/cmCPackLog.cxx
+++ b/Source/CPack/cmCPackLog.cxx
@@ -102,7 +102,7 @@ void cmCPackLog::Log(int tag, const char* file, int line,
display = true;
if ( needTagString )
{
- if ( tagString.size() > 0 ) { tagString += ","; }
+ if (!tagString.empty()) { tagString += ","; }
tagString = "VERBOSE";
}
}
@@ -112,7 +112,7 @@ void cmCPackLog::Log(int tag, const char* file, int line,
display = true;
if ( needTagString )
{
- if ( tagString.size() > 0 ) { tagString += ","; }
+ if (!tagString.empty()) { tagString += ","; }
tagString = "WARNING";
}
}
@@ -122,7 +122,7 @@ void cmCPackLog::Log(int tag, const char* file, int line,
display = true;
if ( needTagString )
{
- if ( tagString.size() > 0 ) { tagString += ","; }
+ if (!tagString.empty()) { tagString += ","; }
tagString = "ERROR";
}
}
@@ -132,7 +132,7 @@ void cmCPackLog::Log(int tag, const char* file, int line,
display = true;
if ( needTagString )
{
- if ( tagString.size() > 0 ) { tagString += ","; }
+ if (!tagString.empty()) { tagString += ","; }
tagString = "DEBUG";
}
useFileAndLine = true;
@@ -143,7 +143,7 @@ void cmCPackLog::Log(int tag, const char* file, int line,
display = true;
if ( needTagString )
{
- if ( tagString.size() > 0 ) { tagString += ","; }
+ if (!tagString.empty()) { tagString += ","; }
tagString = "VERBOSE";
}
}
@@ -169,27 +169,27 @@ void cmCPackLog::Log(int tag, const char* file, int line,
{
if ( error && !this->ErrorPrefix.empty() )
{
- *this->DefaultError << this->ErrorPrefix.c_str();
+ *this->DefaultError << this->ErrorPrefix;
}
else if ( warning && !this->WarningPrefix.empty() )
{
- *this->DefaultError << this->WarningPrefix.c_str();
+ *this->DefaultError << this->WarningPrefix;
}
else if ( output && !this->OutputPrefix.empty() )
{
- *this->DefaultOutput << this->OutputPrefix.c_str();
+ *this->DefaultOutput << this->OutputPrefix;
}
else if ( verbose && !this->VerbosePrefix.empty() )
{
- *this->DefaultOutput << this->VerbosePrefix.c_str();
+ *this->DefaultOutput << this->VerbosePrefix;
}
else if ( debug && !this->DebugPrefix.empty() )
{
- *this->DefaultOutput << this->DebugPrefix.c_str();
+ *this->DefaultOutput << this->DebugPrefix;
}
else if ( !this->Prefix.empty() )
{
- *this->DefaultOutput << this->Prefix.c_str();
+ *this->DefaultOutput << this->Prefix;
}
if ( useFileAndLine )
{
diff --git a/Source/CPack/cmCPackLog.h b/Source/CPack/cmCPackLog.h
index 812f1de27..7a7ff589a 100644
--- a/Source/CPack/cmCPackLog.h
+++ b/Source/CPack/cmCPackLog.h
@@ -17,7 +17,7 @@
#define cmCPack_Log(ctSelf, logType, msg) \
do { \
- cmOStringStream cmCPackLog_msg; \
+ std::ostringstream cmCPackLog_msg; \
cmCPackLog_msg << msg; \
(ctSelf)->Log(logType, __FILE__, __LINE__, cmCPackLog_msg.str().c_str());\
} while ( 0 )
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
index 62bfa91d4..5ba639fee 100644
--- a/Source/CPack/cmCPackNSISGenerator.cxx
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
@@ -13,7 +13,6 @@
#include "cmCPackNSISGenerator.h"
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
#include "cmSystemTools.h"
#include "cmMakefile.h"
#include "cmGeneratedFileStream.h"
@@ -49,7 +48,7 @@ int cmCPackNSISGenerator::PackageFiles()
// TODO: Fix nsis to force out file name
std::string nsisInFileName = this->FindTemplate("NSIS.template.in");
- if ( nsisInFileName.size() == 0 )
+ if (nsisInFileName.empty())
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
"CPack error: Could not find NSIS installer template file."
@@ -58,7 +57,7 @@ int cmCPackNSISGenerator::PackageFiles()
}
std::string nsisInInstallOptions
= this->FindTemplate("NSIS.InstallOptions.ini.in");
- if ( nsisInInstallOptions.size() == 0 )
+ if (nsisInInstallOptions.empty())
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
"CPack error: Could not find NSIS installer options file."
@@ -71,7 +70,7 @@ int cmCPackNSISGenerator::PackageFiles()
tmpFile += "/NSISOutput.log";
std::string nsisInstallOptions = nsisFileName + "/NSIS.InstallOptions.ini";
nsisFileName += "/project.nsi";
- cmOStringStream str;
+ std::ostringstream str;
std::vector<std::string>::const_iterator it;
for ( it = files.begin(); it != files.end(); ++ it )
{
@@ -83,15 +82,15 @@ int cmCPackNSISGenerator::PackageFiles()
fileN = fileN.substr(fileN.find('/')+1, std::string::npos);
}
cmSystemTools::ReplaceString(fileN, "/", "\\");
- str << " Delete \"$INSTDIR\\" << fileN.c_str() << "\"" << std::endl;
+ str << " Delete \"$INSTDIR\\" << fileN << "\"" << std::endl;
}
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Uninstall Files: "
- << str.str().c_str() << std::endl);
+ << str.str() << std::endl);
this->SetOptionIfNotSet("CPACK_NSIS_DELETE_FILES", str.str().c_str());
std::vector<std::string> dirs;
this->GetListOfSubdirectories(toplevel.c_str(), dirs);
std::vector<std::string>::const_iterator sit;
- cmOStringStream dstr;
+ std::ostringstream dstr;
for ( sit = dirs.begin(); sit != dirs.end(); ++ sit )
{
std::string componentName;
@@ -117,14 +116,14 @@ int cmCPackNSISGenerator::PackageFiles()
}
}
cmSystemTools::ReplaceString(fileN, "/", "\\");
- dstr << " RMDir \"$INSTDIR\\" << fileN.c_str() << "\"" << std::endl;
+ dstr << " RMDir \"$INSTDIR\\" << fileN << "\"" << std::endl;
if (!componentName.empty())
{
this->Components[componentName].Directories.push_back(fileN);
}
}
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Uninstall Dirs: "
- << dstr.str().c_str() << std::endl);
+ << dstr.str() << std::endl);
this->SetOptionIfNotSet("CPACK_NSIS_DELETE_DIRECTORIES",
dstr.str().c_str());
@@ -158,6 +157,28 @@ int cmCPackNSISGenerator::PackageFiles()
installerIconCode.c_str());
}
+ if (this->IsSet("CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP"))
+ {
+ std::string installerBitmapCode =
+ "!define MUI_WELCOMEFINISHPAGE_BITMAP \"";
+ installerBitmapCode +=
+ this->GetOption("CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP");
+ installerBitmapCode += "\"\n";
+ this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_WELCOMEFINISH_CODE",
+ installerBitmapCode.c_str());
+ }
+
+ if (this->IsSet("CPACK_NSIS_MUI_UNWELCOMEFINISHPAGE_BITMAP"))
+ {
+ std::string installerBitmapCode =
+ "!define MUI_UNWELCOMEFINISHPAGE_BITMAP \"";
+ installerBitmapCode +=
+ this->GetOption("CPACK_NSIS_MUI_UNWELCOMEFINISHPAGE_BITMAP");
+ installerBitmapCode += "\"\n";
+ this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_UNWELCOMEFINISH_CODE",
+ installerBitmapCode.c_str());
+ }
+
if(this->IsSet("CPACK_NSIS_MUI_FINISHPAGE_RUN"))
{
std::string installerRunCode = "!define MUI_FINISHPAGE_RUN \"$INSTDIR\\";
@@ -190,7 +211,7 @@ int cmCPackNSISGenerator::PackageFiles()
std::string groupDescriptions;
std::string installTypesCode;
std::string defines;
- cmOStringStream macrosOut;
+ std::ostringstream macrosOut;
bool anyDownloadedComponents = false;
// Create installation types. The order is significant, so we first fill
@@ -320,21 +341,21 @@ int cmCPackNSISGenerator::PackageFiles()
std::string nsisCmd = "\"";
nsisCmd += this->GetOption("CPACK_INSTALLER_PROGRAM");
nsisCmd += "\" \"" + nsisFileName + "\"";
- cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << nsisCmd.c_str()
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << nsisCmd
<< std::endl);
std::string output;
int retVal = 1;
- bool res = cmSystemTools::RunSingleCommand(nsisCmd.c_str(), &output,
+ bool res = cmSystemTools::RunSingleCommand(nsisCmd.c_str(), &output, &output,
&retVal, 0, this->GeneratorVerbose, 0);
if ( !res || retVal )
{
cmGeneratedFileStream ofs(tmpFile.c_str());
- ofs << "# Run command: " << nsisCmd.c_str() << std::endl
+ ofs << "# Run command: " << nsisCmd << std::endl
<< "# Output:" << std::endl
- << output.c_str() << std::endl;
+ << output << std::endl;
cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running NSIS command: "
- << nsisCmd.c_str() << std::endl
- << "Please check " << tmpFile.c_str() << " for errors" << std::endl);
+ << nsisCmd << std::endl
+ << "Please check " << tmpFile << " for errors" << std::endl);
return 0;
}
return 1;
@@ -427,11 +448,11 @@ int cmCPackNSISGenerator::InitializeInternal()
std::string nsisCmd = "\"" + nsisPath + "\" " NSIS_OPT "VERSION";
cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Test NSIS version: "
- << nsisCmd.c_str() << std::endl);
+ << nsisCmd << std::endl);
std::string output;
int retVal = 1;
- bool resS = cmSystemTools::RunSingleCommand(nsisCmd.c_str(),
- &output, &retVal, 0, this->GeneratorVerbose, 0);
+ bool resS = cmSystemTools::RunSingleCommand(
+ nsisCmd.c_str(), &output, &output, &retVal, 0, this->GeneratorVerbose, 0);
cmsys::RegularExpression versionRex("v([0-9]+.[0-9]+)");
cmsys::RegularExpression versionRexCVS("v(.*)\\.cvs");
if ( !resS || retVal ||
@@ -442,13 +463,13 @@ int cmCPackNSISGenerator::InitializeInternal()
std::string tmpFile = topDir ? topDir : ".";
tmpFile += "/NSISOutput.log";
cmGeneratedFileStream ofs(tmpFile.c_str());
- ofs << "# Run command: " << nsisCmd.c_str() << std::endl
+ ofs << "# Run command: " << nsisCmd << std::endl
<< "# Output:" << std::endl
- << output.c_str() << std::endl;
+ << output << std::endl;
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Problem checking NSIS version with command: "
- << nsisCmd.c_str() << std::endl
- << "Please check " << tmpFile.c_str() << " for errors" << std::endl);
+ << nsisCmd << std::endl
+ << "Please check " << tmpFile << " for errors" << std::endl);
return 0;
}
if ( versionRex.find(output))
@@ -470,7 +491,7 @@ int cmCPackNSISGenerator::InitializeInternal()
{
// No version check for NSIS cvs build
cmCPackLogger(cmCPackLog::LOG_DEBUG, "NSIS Version: CVS "
- << versionRexCVS.match(1).c_str() << std::endl);
+ << versionRexCVS.match(1) << std::endl);
}
this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM", nsisPath.c_str());
this->SetOptionIfNotSet("CPACK_NSIS_EXECUTABLES_DIRECTORY", "bin");
@@ -503,8 +524,8 @@ int cmCPackNSISGenerator::InitializeInternal()
<< "not set" << std::endl);
}
- cmOStringStream str;
- cmOStringStream deleteStr;
+ std::ostringstream str;
+ std::ostringstream deleteStr;
if ( cpackPackageExecutables )
{
@@ -536,7 +557,7 @@ int cmCPackNSISGenerator::InitializeInternal()
<< ".lnk\"" << std::endl;
// see if CPACK_CREATE_DESKTOP_LINK_ExeName is on
// if so add a desktop link
- if(cpackPackageDesktopLinksVector.size() &&
+ if(!cpackPackageDesktopLinksVector.empty() &&
std::find(cpackPackageDesktopLinksVector.begin(),
cpackPackageDesktopLinksVector.end(),
execName)
@@ -565,8 +586,8 @@ int cmCPackNSISGenerator::InitializeInternal()
}
//----------------------------------------------------------------------
-void cmCPackNSISGenerator::CreateMenuLinks( cmOStringStream& str,
- cmOStringStream& deleteStr)
+void cmCPackNSISGenerator::CreateMenuLinks( std::ostringstream& str,
+ std::ostringstream& deleteStr)
{
const char* cpackMenuLinks
= this->GetOption("CPACK_NSIS_MENU_LINKS");
@@ -588,8 +609,8 @@ void cmCPackNSISGenerator::CreateMenuLinks( cmOStringStream& str,
return;
}
- cmsys::RegularExpression urlRegex;
- urlRegex.compile("^(mailto:|(ftps?|https?|news)://).*$");
+ static cmsys::RegularExpression
+ urlRegex("^(mailto:|(ftps?|https?|news)://).*$");
std::vector<std::string>::iterator it;
for ( it = cpackMenuLinksVector.begin();
@@ -629,7 +650,7 @@ void cmCPackNSISGenerator::CreateMenuLinks( cmOStringStream& str,
// if so add a desktop link
std::string desktop = "CPACK_CREATE_DESKTOP_LINK_";
desktop += linkName;
- if(this->IsSet(desktop.c_str()))
+ if(this->IsSet(desktop))
{
str << " StrCmp \"$INSTALL_DESKTOP\" \"1\" 0 +2\n";
str << " CreateShortCut \"$DESKTOP\\"
@@ -654,11 +675,11 @@ bool cmCPackNSISGenerator::GetListOfSubdirectories(const char* topdir,
if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)),".") &&
strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)),".."))
{
- cmsys_stl::string fullPath = topdir;
+ std::string fullPath = topdir;
fullPath += "/";
fullPath += dir.GetFile(static_cast<unsigned long>(fileNum));
- if(cmsys::SystemTools::FileIsDirectory(fullPath.c_str()) &&
- !cmsys::SystemTools::FileIsSymlink(fullPath.c_str()))
+ if(cmsys::SystemTools::FileIsDirectory(fullPath) &&
+ !cmsys::SystemTools::FileIsSymlink(fullPath))
{
if (!this->GetListOfSubdirectories(fullPath.c_str(), dirs))
{
@@ -694,7 +715,7 @@ bool cmCPackNSISGenerator::SupportsComponentInstallation() const
std::string
cmCPackNSISGenerator::
CreateComponentDescription(cmCPackComponent *component,
- cmOStringStream& macrosOut)
+ std::ostringstream& macrosOut)
{
// Basic description of the component
std::string componentCode = "Section ";
@@ -714,7 +735,7 @@ CreateComponentDescription(cmCPackComponent *component,
}
else if (!component->InstallationTypes.empty())
{
- cmOStringStream out;
+ std::ostringstream out;
std::vector<cmCPackInstallationType *>::iterator installTypeIter;
for (installTypeIter = component->InstallationTypes.begin();
installTypeIter != component->InstallationTypes.end();
@@ -734,7 +755,7 @@ CreateComponentDescription(cmCPackComponent *component,
// Compute the name of the archive.
std::string packagesDir = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
packagesDir += ".dummy";
- cmOStringStream out;
+ std::ostringstream out;
out << cmSystemTools::GetFilenameWithoutLastExtension(packagesDir)
<< "-" << component->Name << ".zip";
component->ArchiveFile = out.str();
@@ -771,7 +792,7 @@ CreateComponentDescription(cmCPackComponent *component,
<< archiveFile << std::endl);
if (cmSystemTools::FileExists(archiveFile.c_str(), true))
{
- if (!cmSystemTools::RemoveFile(archiveFile.c_str()))
+ if (!cmSystemTools::RemoveFile(archiveFile))
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Unable to remove archive file " << archiveFile
@@ -825,7 +846,7 @@ CreateComponentDescription(cmCPackComponent *component,
}
out << std::endl;
- totalSize += cmSystemTools::FileLength((dirName + *fileIt).c_str());
+ totalSize += cmSystemTools::FileLength(dirName + *fileIt);
}
}
@@ -836,20 +857,20 @@ CreateComponentDescription(cmCPackComponent *component,
zipListFileName.c_str());
std::string output;
int retVal = -1;
- int res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output, &retVal,
- dirName.c_str(),
- cmSystemTools::OUTPUT_NONE, 0);
+ int res = cmSystemTools::RunSingleCommand(
+ cmd.c_str(), &output, &output,
+ &retVal, dirName.c_str(), cmSystemTools::OUTPUT_NONE, 0);
if ( !res || retVal )
{
std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
tmpFile += "/CompressZip.log";
cmGeneratedFileStream ofs(tmpFile.c_str());
- ofs << "# Run command: " << cmd.c_str() << std::endl
+ ofs << "# Run command: " << cmd << std::endl
<< "# Output:" << std::endl
- << output.c_str() << std::endl;
+ << output << std::endl;
cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running zip command: "
- << cmd.c_str() << std::endl
- << "Please check " << tmpFile.c_str() << " for errors" << std::endl);
+ << cmd << std::endl
+ << "Please check " << tmpFile << " for errors" << std::endl);
return "";
}
@@ -859,7 +880,7 @@ CreateComponentDescription(cmCPackComponent *component,
{
totalSizeInKbytes = 1;
}
- cmOStringStream out;
+ std::ostringstream out;
out << " AddSize " << totalSizeInKbytes << "\n"
<< " Push \"" << component->ArchiveFile << "\"\n"
<< " Call DownloadFile\n"
@@ -891,7 +912,7 @@ CreateComponentDescription(cmCPackComponent *component,
path = *pathIt;
cmSystemTools::ReplaceString(path, "/", "\\");
macrosOut << " Delete \"$INSTDIR\\"
- << path.c_str()
+ << path
<< "\"\n";
}
for (pathIt = component->Directories.begin();
@@ -901,7 +922,7 @@ CreateComponentDescription(cmCPackComponent *component,
path = *pathIt;
cmSystemTools::ReplaceString(path, "/", "\\");
macrosOut << " RMDir \"$INSTDIR\\"
- << path.c_str()
+ << path
<< "\"\n";
}
macrosOut << " noremove_" << component->Name << ":\n";
@@ -935,7 +956,7 @@ std::string cmCPackNSISGenerator::CreateSelectionDependenciesDescription
}
visited.insert(component);
- cmOStringStream out;
+ std::ostringstream out;
std::vector<cmCPackComponent *>::iterator dependIt;
for (dependIt = component->Dependencies.begin();
dependIt != component->Dependencies.end();
@@ -967,7 +988,7 @@ std::string cmCPackNSISGenerator::CreateDeselectionDependenciesDescription
}
visited.insert(component);
- cmOStringStream out;
+ std::ostringstream out;
std::vector<cmCPackComponent *>::iterator dependIt;
for (dependIt = component->ReverseDependencies.begin();
dependIt != component->ReverseDependencies.end();
@@ -992,7 +1013,7 @@ std::string cmCPackNSISGenerator::CreateDeselectionDependenciesDescription
std::string
cmCPackNSISGenerator::
CreateComponentGroupDescription(cmCPackComponentGroup *group,
- cmOStringStream& macrosOut)
+ std::ostringstream& macrosOut)
{
if (group->Components.empty() && group->Subgroups.empty())
{
diff --git a/Source/CPack/cmCPackNSISGenerator.h b/Source/CPack/cmCPackNSISGenerator.h
index e46fbdab7..c7b2ce108 100644
--- a/Source/CPack/cmCPackNSISGenerator.h
+++ b/Source/CPack/cmCPackNSISGenerator.h
@@ -38,8 +38,8 @@ public:
protected:
virtual int InitializeInternal();
- void CreateMenuLinks( cmOStringStream& str,
- cmOStringStream& deleteStr);
+ void CreateMenuLinks( std::ostringstream& str,
+ std::ostringstream& deleteStr);
int PackageFiles();
virtual const char* GetOutputExtension() { return ".exe"; }
virtual const char* GetOutputPostfix() { return "win32"; }
@@ -56,7 +56,7 @@ protected:
/// macrosOut.
std::string
CreateComponentDescription(cmCPackComponent *component,
- cmOStringStream& macrosOut);
+ std::ostringstream& macrosOut);
/// Produce NSIS code that selects all of the components that this component
/// depends on, recursively.
@@ -75,7 +75,7 @@ protected:
/// added macros will be emitted via macrosOut.
std::string
CreateComponentGroupDescription(cmCPackComponentGroup *group,
- cmOStringStream& macrosOut);
+ std::ostringstream& macrosOut);
/// Translations any newlines found in the string into \\r\\n, so that the
/// resulting string can be used within NSIS.
diff --git a/Source/CPack/cmCPackOSXX11Generator.cxx b/Source/CPack/cmCPackOSXX11Generator.cxx
index 76e15fb84..8940f5415 100644
--- a/Source/CPack/cmCPackOSXX11Generator.cxx
+++ b/Source/CPack/cmCPackOSXX11Generator.cxx
@@ -13,7 +13,6 @@
#include "cmake.h"
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
#include "cmSystemTools.h"
#include "cmMakefile.h"
#include "cmGeneratedFileStream.h"
@@ -45,8 +44,8 @@ int cmCPackOSXX11Generator::PackageFiles()
{
cmCPackLogger(cmCPackLog::LOG_DEBUG, "The cpackPackageExecutables: "
<< cpackPackageExecutables << "." << std::endl);
- cmOStringStream str;
- cmOStringStream deleteStr;
+ std::ostringstream str;
+ std::ostringstream deleteStr;
std::vector<std::string> cpackPackageExecutablesVector;
cmSystemTools::ExpandListArgument(cpackPackageExecutables,
cpackPackageExecutablesVector);
@@ -165,7 +164,7 @@ int cmCPackOSXX11Generator::PackageFiles()
std::string output;
std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
tmpFile += "/hdiutilOutput.log";
- cmOStringStream dmgCmd;
+ std::ostringstream dmgCmd;
dmgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM_DISK_IMAGE")
<< "\" create -ov -format UDZO -srcfolder \""
<< diskImageDirectory.c_str()
@@ -180,9 +179,9 @@ int cmCPackOSXX11Generator::PackageFiles()
bool res = false;
while(numTries > 0)
{
- res = cmSystemTools::RunSingleCommand(dmgCmd.str().c_str(), &output,
- &retVal, 0,
- this->GeneratorVerbose, 0);
+ res = cmSystemTools::RunSingleCommand(
+ dmgCmd.str().c_str(), &output, &output,
+ &retVal, 0, this->GeneratorVerbose, 0);
if ( res && !retVal )
{
numTries = -1;
@@ -227,7 +226,7 @@ int cmCPackOSXX11Generator::InitializeInternal()
//----------------------------------------------------------------------
/*
-bool cmCPackOSXX11Generator::CopyCreateResourceFile(const char* name)
+bool cmCPackOSXX11Generator::CopyCreateResourceFile(const std::string& name)
{
std::string uname = cmSystemTools::UpperCase(name);
std::string cpackVar = "CPACK_RESOURCE_FILE_" + uname;
@@ -271,8 +270,8 @@ bool cmCPackOSXX11Generator::CopyCreateResourceFile(const char* name)
*/
//----------------------------------------------------------------------
-bool cmCPackOSXX11Generator::CopyResourcePlistFile(const char* name,
- const char* dir, const char* outputFileName /* = 0 */,
+bool cmCPackOSXX11Generator::CopyResourcePlistFile(const std::string& name,
+ const std::string& dir, const char* outputFileName /* = 0 */,
bool copyOnly /* = false */)
{
std::string inFName = "CPack.";
@@ -288,7 +287,7 @@ bool cmCPackOSXX11Generator::CopyResourcePlistFile(const char* name,
if ( !outputFileName )
{
- outputFileName = name;
+ outputFileName = name.c_str();
}
std::string destFileName = dir;
diff --git a/Source/CPack/cmCPackOSXX11Generator.h b/Source/CPack/cmCPackOSXX11Generator.h
index b7bd24396..9d0a6d188 100644
--- a/Source/CPack/cmCPackOSXX11Generator.h
+++ b/Source/CPack/cmCPackOSXX11Generator.h
@@ -37,8 +37,9 @@ protected:
virtual const char* GetPackagingInstallPrefix();
virtual const char* GetOutputExtension() { return ".dmg"; }
- //bool CopyCreateResourceFile(const char* name, const char* dir);
- bool CopyResourcePlistFile(const char* name, const char* dir,
+ //bool CopyCreateResourceFile(const std::string& name,
+ // const std::string& dir);
+ bool CopyResourcePlistFile(const std::string& name, const std::string& dir,
const char* outputFileName = 0, bool copyOnly = false);
std::string InstallPrefix;
};
diff --git a/Source/CPack/cmCPackPackageMakerGenerator.cxx b/Source/CPack/cmCPackPackageMakerGenerator.cxx
index c617a3e32..8fdc03660 100644
--- a/Source/CPack/cmCPackPackageMakerGenerator.cxx
+++ b/Source/CPack/cmCPackPackageMakerGenerator.cxx
@@ -13,7 +13,6 @@
#include "cmake.h"
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
#include "cmSystemTools.h"
#include "cmMakefile.h"
#include "cmGeneratedFileStream.h"
@@ -22,12 +21,22 @@
#include <cmsys/SystemTools.hxx>
#include <cmsys/Glob.hxx>
+#include <cmsys/FStream.hxx>
+
+#include <assert.h>
+
+static inline
+unsigned int getVersion(unsigned int major, unsigned int minor)
+{
+ assert(major < 256 && minor < 256);
+ return ((major & 0xFF) << 16 | minor);
+}
//----------------------------------------------------------------------
cmCPackPackageMakerGenerator::cmCPackPackageMakerGenerator()
{
this->PackageMakerVersion = 0.0;
- this->PackageCompatibilityVersion = 10.4;
+ this->PackageCompatibilityVersion = getVersion(10, 4);
}
//----------------------------------------------------------------------
@@ -38,18 +47,18 @@ cmCPackPackageMakerGenerator::~cmCPackPackageMakerGenerator()
//----------------------------------------------------------------------
bool cmCPackPackageMakerGenerator::SupportsComponentInstallation() const
{
- return this->PackageCompatibilityVersion >= 10.4;
+ return this->PackageCompatibilityVersion >= getVersion(10, 4);
}
//----------------------------------------------------------------------
-int cmCPackPackageMakerGenerator::CopyInstallScript(const char* resdir,
- const char* script,
- const char* name)
+int cmCPackPackageMakerGenerator::CopyInstallScript(const std::string& resdir,
+ const std::string& script,
+ const std::string& name)
{
std::string dst = resdir;
dst += "/";
dst += name;
- cmSystemTools::CopyFileAlways(script, dst.c_str());
+ cmSystemTools::CopyFileAlways(script.c_str(), dst.c_str());
cmSystemTools::SetPermissions(dst.c_str(),0777);
cmCPackLogger(cmCPackLog::LOG_VERBOSE,
"copy script : " << script << "\ninto " << dst.c_str() <<
@@ -240,7 +249,7 @@ int cmCPackPackageMakerGenerator::PackageFiles()
std::string packageFile;
if (compIt->second.IsDownloaded)
{
- if (this->PackageCompatibilityVersion >= 10.5 &&
+ if (this->PackageCompatibilityVersion >= getVersion(10, 5) &&
this->PackageMakerVersion >= 3.0)
{
// Build this package within the upload directory.
@@ -259,7 +268,7 @@ int cmCPackPackageMakerGenerator::PackageFiles()
}
else if (!warnedAboutDownloadCompatibility)
{
- if (this->PackageCompatibilityVersion < 10.5)
+ if (this->PackageCompatibilityVersion < getVersion(10, 5))
{
cmCPackLogger(
cmCPackLog::LOG_WARNING,
@@ -324,7 +333,7 @@ int cmCPackPackageMakerGenerator::PackageFiles()
if (this->Components.empty())
{
// Use PackageMaker to build the package.
- cmOStringStream pkgCmd;
+ std::ostringstream pkgCmd;
pkgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM")
<< "\" -build -p \"" << packageDirFileName << "\"";
if (this->Components.empty())
@@ -358,7 +367,7 @@ int cmCPackPackageMakerGenerator::PackageFiles()
std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
tmpFile += "/hdiutilOutput.log";
- cmOStringStream dmgCmd;
+ std::ostringstream dmgCmd;
dmgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM_DISK_IMAGE")
<< "\" create -ov -format UDZO -srcfolder \"" << packageDirFileName
<< "\" \"" << packageFileNames[0] << "\"";
@@ -368,9 +377,9 @@ int cmCPackPackageMakerGenerator::PackageFiles()
bool res = false;
while(numTries > 0)
{
- res = cmSystemTools::RunSingleCommand(dmgCmd.str().c_str(), &output,
- &retVal, 0, this->GeneratorVerbose,
- 0);
+ res = cmSystemTools::RunSingleCommand(
+ dmgCmd.str().c_str(), &output, &output,
+ &retVal, 0, this->GeneratorVerbose, 0);
if ( res && !retVal )
{
numTries = -1;
@@ -467,7 +476,7 @@ int cmCPackPackageMakerGenerator::InitializeInternal()
return 0;
}
- std::ifstream ifs(versionFile.c_str());
+ cmsys::ifstream ifs(versionFile.c_str());
if ( !ifs )
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -519,22 +528,29 @@ int cmCPackPackageMakerGenerator::InitializeInternal()
const char *packageCompat = this->GetOption("CPACK_OSX_PACKAGE_VERSION");
if (packageCompat && *packageCompat)
{
- this->PackageCompatibilityVersion = atof(packageCompat);
+ unsigned int majorVersion = 10;
+ unsigned int minorVersion = 5;
+ int res = sscanf(packageCompat, "%u.%u", &majorVersion, &minorVersion);
+ if (res == 2)
+ {
+ this->PackageCompatibilityVersion =
+ getVersion(majorVersion, minorVersion);
+ }
}
else if (this->GetOption("CPACK_DOWNLOAD_SITE"))
{
this->SetOption("CPACK_OSX_PACKAGE_VERSION", "10.5");
- this->PackageCompatibilityVersion = 10.5;
+ this->PackageCompatibilityVersion = getVersion(10, 5);
}
else if (this->GetOption("CPACK_COMPONENTS_ALL"))
{
this->SetOption("CPACK_OSX_PACKAGE_VERSION", "10.4");
- this->PackageCompatibilityVersion = 10.4;
+ this->PackageCompatibilityVersion = getVersion(10, 4);
}
else
{
this->SetOption("CPACK_OSX_PACKAGE_VERSION", "10.3");
- this->PackageCompatibilityVersion = 10.3;
+ this->PackageCompatibilityVersion = getVersion(10, 3);
}
std::vector<std::string> no_paths;
@@ -552,8 +568,9 @@ int cmCPackPackageMakerGenerator::InitializeInternal()
}
//----------------------------------------------------------------------
-bool cmCPackPackageMakerGenerator::CopyCreateResourceFile(const char* name,
- const char* dirName)
+bool cmCPackPackageMakerGenerator::CopyCreateResourceFile(
+ const std::string& name,
+ const std::string& dirName)
{
std::string uname = cmSystemTools::UpperCase(name);
std::string cpackVar = "CPACK_RESOURCE_FILE_" + uname;
@@ -562,7 +579,7 @@ bool cmCPackPackageMakerGenerator::CopyCreateResourceFile(const char* name,
{
cmCPackLogger(cmCPackLog::LOG_ERROR, "CPack option: " << cpackVar.c_str()
<< " not specified. It should point to "
- << (name ? name : "(NULL)")
+ << (!name.empty() ? name : "<empty>")
<< ".rtf, " << name
<< ".html, or " << name << ".txt file" << std::endl);
return false;
@@ -570,7 +587,7 @@ bool cmCPackPackageMakerGenerator::CopyCreateResourceFile(const char* name,
if ( !cmSystemTools::FileExists(inFileName) )
{
cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find "
- << (name ? name : "(NULL)")
+ << (!name.empty() ? name : "<empty>")
<< " resource file: " << inFileName << std::endl);
return false;
}
@@ -599,12 +616,13 @@ bool cmCPackPackageMakerGenerator::CopyCreateResourceFile(const char* name,
return true;
}
-bool cmCPackPackageMakerGenerator::CopyResourcePlistFile(const char* name,
- const char* outName)
+bool cmCPackPackageMakerGenerator::CopyResourcePlistFile(
+ const std::string& name,
+ const char* outName)
{
if (!outName)
{
- outName = name;
+ outName = name.c_str();
}
std::string inFName = "CPack.";
@@ -638,8 +656,9 @@ bool cmCPackPackageMakerGenerator::RunPackageMaker(const char *command,
cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << command << std::endl);
std::string output;
int retVal = 1;
- bool res = cmSystemTools::RunSingleCommand(command, &output, &retVal, 0,
- this->GeneratorVerbose, 0);
+ bool res = cmSystemTools::RunSingleCommand(
+ command, &output, &output,
+ &retVal, 0, this->GeneratorVerbose, 0);
cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Done running package maker"
<< std::endl);
if ( !res || retVal )
@@ -684,7 +703,7 @@ cmCPackPackageMakerGenerator::GetPackageName(const cmCPackComponent& component)
{
std::string packagesDir = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
packagesDir += ".dummy";
- cmOStringStream out;
+ std::ostringstream out;
out << cmSystemTools::GetFilenameWithoutLastExtension(packagesDir)
<< "-" << component.Name << ".pkg";
return out.str();
@@ -707,16 +726,16 @@ GenerateComponentPackage(const char *packageFile,
packageFile << std::endl);
// The command that will be used to run PackageMaker
- cmOStringStream pkgCmd;
+ std::ostringstream pkgCmd;
- if (this->PackageCompatibilityVersion < 10.5 ||
+ if (this->PackageCompatibilityVersion < getVersion(10, 5) ||
this->PackageMakerVersion < 3.0)
{
// Create Description.plist and Info.plist files for normal Mac OS
// X packages, which work on Mac OS X 10.3 and newer.
std::string descriptionFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
descriptionFile += '/' + component.Name + "-Description.plist";
- std::ofstream out(descriptionFile.c_str());
+ cmsys::ofstream out(descriptionFile.c_str());
out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl
<< "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\""
<< "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">" << std::endl
@@ -797,7 +816,7 @@ WriteDistributionFile(const char* metapackageFile)
// Create the choice outline, which provides a tree-based view of
// the components in their groups.
- cmOStringStream choiceOut;
+ std::ostringstream choiceOut;
choiceOut << "<choices-outline>" << std::endl;
// Emit the outline for the groups
@@ -859,7 +878,8 @@ WriteDistributionFile(const char* metapackageFile)
//----------------------------------------------------------------------
void
cmCPackPackageMakerGenerator::
-CreateChoiceOutline(const cmCPackComponentGroup& group, cmOStringStream& out)
+CreateChoiceOutline(const cmCPackComponentGroup& group,
+ std::ostringstream& out)
{
out << "<line choice=\"" << group.Name << "Choice\">" << std::endl;
std::vector<cmCPackComponentGroup*>::const_iterator groupIt;
@@ -882,7 +902,7 @@ CreateChoiceOutline(const cmCPackComponentGroup& group, cmOStringStream& out)
//----------------------------------------------------------------------
void
cmCPackPackageMakerGenerator::CreateChoice(const cmCPackComponentGroup& group,
- cmOStringStream& out)
+ std::ostringstream& out)
{
out << "<choice id=\"" << group.Name << "Choice\" "
<< "title=\"" << group.DisplayName << "\" "
@@ -900,7 +920,7 @@ cmCPackPackageMakerGenerator::CreateChoice(const cmCPackComponentGroup& group,
//----------------------------------------------------------------------
void
cmCPackPackageMakerGenerator::CreateChoice(const cmCPackComponent& component,
- cmOStringStream& out)
+ std::ostringstream& out)
{
std::string packageId = "com.";
packageId += this->GetOption("CPACK_PACKAGE_VENDOR");
@@ -961,6 +981,7 @@ cmCPackPackageMakerGenerator::CreateChoice(const cmCPackComponent& component,
std::string dirName = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
dirName += '/';
dirName += component.Name;
+ dirName += this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX");
unsigned long installedSize
= component.GetInstalledSizeInKbytes(dirName.c_str());
@@ -985,7 +1006,7 @@ void
cmCPackPackageMakerGenerator::
AddDependencyAttributes(const cmCPackComponent& component,
std::set<const cmCPackComponent *>& visited,
- cmOStringStream& out)
+ std::ostringstream& out)
{
if (visited.find(&component) != visited.end())
{
@@ -1009,7 +1030,7 @@ void
cmCPackPackageMakerGenerator::
AddReverseDependencyAttributes(const cmCPackComponent& component,
std::set<const cmCPackComponent *>& visited,
- cmOStringStream& out)
+ std::ostringstream& out)
{
if (visited.find(&component) != visited.end())
{
diff --git a/Source/CPack/cmCPackPackageMakerGenerator.h b/Source/CPack/cmCPackPackageMakerGenerator.h
index ba3d968f6..7d349c662 100644
--- a/Source/CPack/cmCPackPackageMakerGenerator.h
+++ b/Source/CPack/cmCPackPackageMakerGenerator.h
@@ -38,9 +38,9 @@ public:
virtual bool SupportsComponentInstallation() const;
protected:
- int CopyInstallScript(const char* resdir,
- const char* script,
- const char* name);
+ int CopyInstallScript(const std::string& resdir,
+ const std::string& script,
+ const std::string& name);
virtual int InitializeInternal();
int PackageFiles();
virtual const char* GetOutputExtension() { return ".dmg"; }
@@ -51,8 +51,9 @@ protected:
// CPACK_RESOURCE_FILE_${NAME} (where ${NAME} is the uppercased
// version of name) specifies the input file to use for this file,
// which will be configured via ConfigureFile.
- bool CopyCreateResourceFile(const char* name, const char *dirName);
- bool CopyResourcePlistFile(const char* name, const char* outName = 0);
+ bool CopyCreateResourceFile(const std::string& name,
+ const std::string& dirName);
+ bool CopyResourcePlistFile(const std::string& name, const char* outName = 0);
// Run PackageMaker with the given command line, which will (if
// successful) produce the given package file. Returns true if
@@ -83,30 +84,30 @@ protected:
// dependency attributes for inter-component dependencies.
void AddDependencyAttributes(const cmCPackComponent& component,
std::set<const cmCPackComponent *>& visited,
- cmOStringStream& out);
+ std::ostringstream& out);
// Subroutine of WriteDistributionFile that writes out the
// reverse dependency attributes for inter-component dependencies.
void
AddReverseDependencyAttributes(const cmCPackComponent& component,
std::set<const cmCPackComponent *>& visited,
- cmOStringStream& out);
+ std::ostringstream& out);
// Generates XML that encodes the hierarchy of component groups and
// their components in a form that can be used by distribution
// metapackages.
void CreateChoiceOutline(const cmCPackComponentGroup& group,
- cmOStringStream& out);
+ std::ostringstream& out);
/// Create the "choice" XML element to describe a component group
/// for the installer GUI.
void CreateChoice(const cmCPackComponentGroup& group,
- cmOStringStream& out);
+ std::ostringstream& out);
/// Create the "choice" XML element to describe a component for the
/// installer GUI.
void CreateChoice(const cmCPackComponent& component,
- cmOStringStream& out);
+ std::ostringstream& out);
// Escape the given string to make it usable as an XML attribute
// value.
@@ -116,7 +117,7 @@ protected:
cmCPackComponent PostFlightComponent;
double PackageMakerVersion;
- double PackageCompatibilityVersion;
+ unsigned int PackageCompatibilityVersion;
};
#endif
diff --git a/Source/CPack/cmCPackRPMGenerator.cxx b/Source/CPack/cmCPackRPMGenerator.cxx
index 66a419405..71ab3a0d5 100644
--- a/Source/CPack/cmCPackRPMGenerator.cxx
+++ b/Source/CPack/cmCPackRPMGenerator.cxx
@@ -57,7 +57,7 @@ int cmCPackRPMGenerator::PackageOnePack(std::string initialToplevel,
// Begin the archive for this pack
std::string localToplevel(initialToplevel);
std::string packageFileName(
- cmSystemTools::GetParentDirectory(toplevel.c_str())
+ cmSystemTools::GetParentDirectory(toplevel)
);
std::string outputFileName(
GetComponentPackageFileName(this->GetOption("CPACK_PACKAGE_FILE_NAME"),
@@ -166,7 +166,7 @@ int cmCPackRPMGenerator::PackageComponentsAllInOne()
// The ALL GROUPS in ONE package case
std::string localToplevel(initialTopLevel);
std::string packageFileName(
- cmSystemTools::GetParentDirectory(toplevel.c_str())
+ cmSystemTools::GetParentDirectory(toplevel)
);
std::string outputFileName(
std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME"))
@@ -272,9 +272,9 @@ std::string cmCPackRPMGenerator::GetComponentInstallDirNameSuffix(
// the current COMPONENT belongs to.
std::string groupVar = "CPACK_COMPONENT_" +
cmSystemTools::UpperCase(componentName) + "_GROUP";
- if (NULL != GetOption(groupVar.c_str()))
+ if (NULL != GetOption(groupVar))
{
- return std::string(GetOption(groupVar.c_str()));
+ return std::string(GetOption(groupVar));
}
else
{
diff --git a/Source/CPack/cmCPackSTGZGenerator.cxx b/Source/CPack/cmCPackSTGZGenerator.cxx
index 9b6cf14df..68b893f6f 100644
--- a/Source/CPack/cmCPackSTGZGenerator.cxx
+++ b/Source/CPack/cmCPackSTGZGenerator.cxx
@@ -14,12 +14,11 @@
#include "cmake.h"
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
#include "cmSystemTools.h"
#include "cmMakefile.h"
#include "cmCPackLog.h"
-#include <cmsys/ios/sstream>
+#include <cmsys/FStream.hxx>
#include <sys/types.h>
#include <sys/stat.h>
@@ -42,7 +41,7 @@ int cmCPackSTGZGenerator::InitializeInternal()
if ( inFile.empty() )
{
cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find template file: "
- << inFile.c_str() << std::endl);
+ << inFile << std::endl);
return 0;
}
this->SetOptionIfNotSet("CPACK_STGZ_HEADER_FILE", inFile.c_str());
@@ -70,8 +69,6 @@ int cmCPackSTGZGenerator::PackageFiles()
retval &= cmSystemTools::SetPermissions((*it).c_str(),
#if defined( _MSC_VER ) || defined( __MINGW32__ )
S_IREAD | S_IWRITE | S_IEXEC
-#elif defined( __BORLANDC__ )
- S_IRUSR | S_IWUSR | S_IXUSR
#else
S_IRUSR | S_IWUSR | S_IXUSR |
S_IRGRP | S_IWGRP | S_IXGRP |
@@ -86,12 +83,12 @@ int cmCPackSTGZGenerator::PackageFiles()
int cmCPackSTGZGenerator::GenerateHeader(std::ostream* os)
{
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Writing header" << std::endl);
- cmsys_ios::ostringstream str;
+ std::ostringstream str;
int counter = 0;
std::string inLicFile = this->GetOption("CPACK_RESOURCE_FILE_LICENSE");
std::string line;
- std::ifstream ilfs(inLicFile.c_str());
+ cmsys::ifstream ilfs(inLicFile.c_str());
std::string licenseText;
while ( cmSystemTools::GetLineFromStream(ilfs, line) )
{
@@ -104,7 +101,7 @@ int cmCPackSTGZGenerator::GenerateHeader(std::ostream* os)
// Create the header
std::string inFile = this->GetOption("CPACK_STGZ_HEADER_FILE");
- std::ifstream ifs(inFile.c_str());
+ cmsys::ifstream ifs(inFile.c_str());
std::string packageHeaderText;
while ( cmSystemTools::GetLineFromStream(ifs, line) )
{
@@ -133,6 +130,6 @@ int cmCPackSTGZGenerator::GenerateHeader(std::ostream* os)
cmSystemTools::ReplaceString(res, headerLengthTag, buffer);
// Write in file
- *os << res.c_str();
+ *os << res;
return this->Superclass::GenerateHeader(os);
}
diff --git a/Source/CPack/cmCPackTGZGenerator.cxx b/Source/CPack/cmCPackTGZGenerator.cxx
index 509c7f80a..3fa2b6470 100644
--- a/Source/CPack/cmCPackTGZGenerator.cxx
+++ b/Source/CPack/cmCPackTGZGenerator.cxx
@@ -15,7 +15,7 @@
//----------------------------------------------------------------------
cmCPackTGZGenerator::cmCPackTGZGenerator()
:cmCPackArchiveGenerator(cmArchiveWrite::CompressGZip,
- cmArchiveWrite::TypeTAR)
+ "paxr")
{
}
diff --git a/Source/CPack/cmCPackTXZGenerator.cxx b/Source/CPack/cmCPackTXZGenerator.cxx
new file mode 100644
index 000000000..6d4ede1a8
--- /dev/null
+++ b/Source/CPack/cmCPackTXZGenerator.cxx
@@ -0,0 +1,25 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmCPackTXZGenerator.h"
+
+//----------------------------------------------------------------------
+cmCPackTXZGenerator::cmCPackTXZGenerator()
+ :cmCPackArchiveGenerator(cmArchiveWrite::CompressXZ,
+ "paxr")
+{
+}
+
+//----------------------------------------------------------------------
+cmCPackTXZGenerator::~cmCPackTXZGenerator()
+{
+}
diff --git a/Source/CPack/cmCPackTXZGenerator.h b/Source/CPack/cmCPackTXZGenerator.h
new file mode 100644
index 000000000..bf8152fcc
--- /dev/null
+++ b/Source/CPack/cmCPackTXZGenerator.h
@@ -0,0 +1,35 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmCPackTXZGenerator_h
+#define cmCPackTXZGenerator_h
+
+#include "cmCPackArchiveGenerator.h"
+
+/** \class cmCPackTXZGenerator
+ * \brief A generator for TXZ files
+ *
+ */
+class cmCPackTXZGenerator : public cmCPackArchiveGenerator
+{
+public:
+ cmCPackTypeMacro(cmCPackTXZGenerator, cmCPackArchiveGenerator);
+ /**
+ * Construct generator
+ */
+ cmCPackTXZGenerator();
+ virtual ~cmCPackTXZGenerator();
+protected:
+ virtual const char* GetOutputExtension() { return ".tar.xz"; }
+};
+
+#endif
diff --git a/Source/CPack/cmCPackTarBZip2Generator.cxx b/Source/CPack/cmCPackTarBZip2Generator.cxx
index ae73c3795..9ff588b3f 100644
--- a/Source/CPack/cmCPackTarBZip2Generator.cxx
+++ b/Source/CPack/cmCPackTarBZip2Generator.cxx
@@ -14,7 +14,7 @@
//----------------------------------------------------------------------
cmCPackTarBZip2Generator::cmCPackTarBZip2Generator()
:cmCPackArchiveGenerator(cmArchiveWrite::CompressBZip2,
- cmArchiveWrite::TypeTAR)
+ "paxr")
{
}
diff --git a/Source/CPack/cmCPackTarCompressGenerator.cxx b/Source/CPack/cmCPackTarCompressGenerator.cxx
index df294084c..1c8311b01 100644
--- a/Source/CPack/cmCPackTarCompressGenerator.cxx
+++ b/Source/CPack/cmCPackTarCompressGenerator.cxx
@@ -15,7 +15,7 @@
//----------------------------------------------------------------------
cmCPackTarCompressGenerator::cmCPackTarCompressGenerator()
:cmCPackArchiveGenerator(cmArchiveWrite::CompressCompress,
- cmArchiveWrite::TypeTAR)
+ "paxr")
{
}
diff --git a/Source/CPack/cmCPackZIPGenerator.cxx b/Source/CPack/cmCPackZIPGenerator.cxx
index e6e4e77d0..7ef7729e6 100644
--- a/Source/CPack/cmCPackZIPGenerator.cxx
+++ b/Source/CPack/cmCPackZIPGenerator.cxx
@@ -15,7 +15,7 @@
//----------------------------------------------------------------------
cmCPackZIPGenerator::cmCPackZIPGenerator()
:cmCPackArchiveGenerator(cmArchiveWrite::CompressNone,
- cmArchiveWrite::TypeZIP)
+ "zip")
{
}
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index b18891858..c08897fa4 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -14,127 +14,48 @@
// Need these for documentation support.
#include "cmake.h"
#include "cmDocumentation.h"
-#include "cmCPackDocumentVariables.h"
-#include "cmCPackDocumentMacros.h"
#include "cmCPackGeneratorFactory.h"
#include "cmCPackGenerator.h"
#include "cmake.h"
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmCPackLog.h"
#include <cmsys/CommandLineArguments.hxx>
#include <cmsys/SystemTools.hxx>
+#include <cmsys/Encoding.hxx>
//----------------------------------------------------------------------------
-static const char * cmDocumentationName[][3] =
+static const char * cmDocumentationName[][2] =
{
{0,
- " cpack - Packaging driver provided by CMake.", 0},
- {0,0,0}
+ " cpack - Packaging driver provided by CMake."},
+ {0,0}
};
//----------------------------------------------------------------------------
-static const char * cmDocumentationUsage[][3] =
+static const char * cmDocumentationUsage[][2] =
{
{0,
- " cpack -G <generator> [options]",
- 0},
- {0,0,0}
+ " cpack -G <generator> [options]"},
+ {0,0}
};
//----------------------------------------------------------------------------
-static const char * cmDocumentationDescription[][3] =
+static const char * cmDocumentationOptions[][2] =
{
- {0,
- "The \"cpack\" executable is the CMake packaging program. "
- "CMake-generated build trees created for projects that use "
- "the INSTALL_* commands have packaging support. "
- "This program will generate the package.", 0},
- CMAKE_STANDARD_INTRODUCTION,
- {0,0,0}
-};
-
-//----------------------------------------------------------------------------
-static const char * cmDocumentationOptions[][3] =
-{
- {"-G <generator>", "Use the specified generator to generate package.",
- "CPack may support multiple native packaging systems on certain "
- "platforms. A generator is responsible for generating input files for "
- "particular system and invoking that systems. Possible generator names "
- "are specified in the Generators section." },
- {"-C <Configuration>", "Specify the project configuration",
- "This option specifies the configuration that the project was build "
- "with, for example 'Debug', 'Release'." },
- {"-D <var>=<value>", "Set a CPack variable.", \
- "Set a variable that can be used by the generator."}, \
- {"--config <config file>", "Specify the config file.",
- "Specify the config file to use to create the package. By default "
- "CPackConfig.cmake in the current directory will be used." },
- {"--verbose,-V","enable verbose output","Run cpack with verbose output."},
- {"--debug","enable debug output (for CPack developers)",
- "Run cpack with debug output (for CPack developers)."},
- {"-P <package name>","override/define CPACK_PACKAGE_NAME",
- "If the package name is not specified on cpack commmand line then"
- "CPack.cmake defines it as CMAKE_PROJECT_NAME"},
- {"-R <package version>","override/define CPACK_PACKAGE_VERSION",
- "If version is not specified on cpack command line then"
- "CPack.cmake defines it from CPACK_PACKAGE_VERSION_[MAJOR|MINOR|PATCH]"
- "look into CPack.cmake for detail"},
- {"-B <package directory>","override/define CPACK_PACKAGE_DIRECTORY",
- "The directory where CPack will be doing its packaging work."
- "The resulting package will be found there. Inside this directory"
- "CPack creates '_CPack_Packages' sub-directory which is the"
- "CPack temporary directory."},
- {"--vendor <vendor name>","override/define CPACK_PACKAGE_VENDOR",
- "If vendor is not specified on cpack command line "
- "(or inside CMakeLists.txt) then"
- "CPack.cmake defines it with a default value"},
- {"--help-command cmd [file]", "Print help for a single command and exit.",
- "Full documentation specific to the given command is displayed. "
- "If a file is specified, the documentation is written into and the output "
- "format is determined depending on the filename suffix. Supported are man "
- "page, HTML, DocBook and plain text."},
- {"--help-command-list [file]", "List available commands and exit.",
- "The list contains all commands for which help may be obtained by using "
- "the --help-command argument followed by a command name. "
- "If a file is specified, the documentation is written into and the output "
- "format is determined depending on the filename suffix. Supported are man "
- "page, HTML, DocBook and plain text."},
- {"--help-commands [file]", "Print help for all commands and exit.",
- "Full documentation specific for all current command is displayed."
- "If a file is specified, the documentation is written into and the output "
- "format is determined depending on the filename suffix. Supported are man "
- "page, HTML, DocBook and plain text."},
- {"--help-variable var [file]",
- "Print help for a single variable and exit.",
- "Full documentation specific to the given variable is displayed."
- "If a file is specified, the documentation is written into and the output "
- "format is determined depending on the filename suffix. Supported are man "
- "page, HTML, DocBook and plain text."},
- {"--help-variable-list [file]", "List documented variables and exit.",
- "The list contains all variables for which help may be obtained by using "
- "the --help-variable argument followed by a variable name. If a file is "
- "specified, the help is written into it."
- "If a file is specified, the documentation is written into and the output "
- "format is determined depending on the filename suffix. Supported are man "
- "page, HTML, DocBook and plain text."},
- {"--help-variables [file]", "Print help for all variables and exit.",
- "Full documentation for all variables is displayed."
- "If a file is specified, the documentation is written into and the output "
- "format is determined depending on the filename suffix. Supported are man "
- "page, HTML, DocBook and plain text."},
- {0,0,0}
-};
-
-//----------------------------------------------------------------------------
-static const char * cmDocumentationSeeAlso[][3] =
-{
- {0, "cmake", 0},
- {0, "ccmake", 0},
- {0, 0, 0}
+ {"-G <generator>", "Use the specified generator to generate package."},
+ {"-C <Configuration>", "Specify the project configuration"},
+ {"-D <var>=<value>", "Set a CPack variable."},
+ {"--config <config file>", "Specify the config file."},
+ {"--verbose,-V","enable verbose output"},
+ {"--debug","enable debug output (for CPack developers)"},
+ {"-P <package name>","override/define CPACK_PACKAGE_NAME"},
+ {"-R <package version>","override/define CPACK_PACKAGE_VERSION"},
+ {"-B <package directory>","override/define CPACK_PACKAGE_DIRECTORY"},
+ {"--vendor <vendor name>","override/define CPACK_PACKAGE_VENDOR"},
+ {0,0}
};
//----------------------------------------------------------------------------
@@ -146,7 +67,7 @@ int cpackUnknownArgument(const char*, void*)
//----------------------------------------------------------------------------
struct cpackDefinitions
{
- typedef std::map<cmStdString, cmStdString> MapType;
+ typedef std::map<std::string, std::string> MapType;
MapType Map;
cmCPackLog *Log;
};
@@ -169,16 +90,21 @@ int cpackDefinitionArgument(const char* argument, const char* cValue,
value = value.c_str() + pos + 1;
def->Map[key] = value;
cmCPack_Log(def->Log, cmCPackLog::LOG_DEBUG, "Set CPack variable: "
- << key.c_str() << " to \"" << value.c_str() << "\"" << std::endl);
+ << key << " to \"" << value << "\"" << std::endl);
return 1;
}
//----------------------------------------------------------------------------
// this is CPack.
-int main (int argc, char *argv[])
+int main (int argc, char const* const* argv)
{
- cmSystemTools::FindExecutableDirectory(argv[0]);
+ cmsys::Encoding::CommandLineArguments args =
+ cmsys::Encoding::CommandLineArguments::Main(argc, argv);
+ argc = args.argc();
+ argv = args.argv();
+
+ cmSystemTools::FindCMakeResources(argv[0]);
cmCPackLog log;
log.SetErrorPrefix("CPack Error: ");
@@ -188,7 +114,7 @@ int main (int argc, char *argv[])
cmSystemTools::EnableMSVCDebugHook();
- if ( cmSystemTools::GetCurrentWorkingDirectory().size() == 0 )
+ if (cmSystemTools::GetCurrentWorkingDirectory().empty())
{
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"Current working directory cannot be established." << std::endl);
@@ -268,14 +194,19 @@ int main (int argc, char *argv[])
}
cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
- "Read CPack config file: " << cpackConfigFile.c_str() << std::endl);
+ "Read CPack config file: " << cpackConfigFile << std::endl);
cmake cminst;
- cminst.RemoveUnscriptableCommands();
- cmGlobalGenerator cmgg;
- cmgg.SetCMakeInstance(&cminst);
- cmsys::auto_ptr<cmLocalGenerator> cmlg(cmgg.CreateLocalGenerator());
- cmMakefile* globalMF = cmlg->GetMakefile();
+ cminst.SetHomeDirectory("");
+ cminst.SetHomeOutputDirectory("");
+ cminst.GetCurrentSnapshot().SetDefaultDefinitions();
+ cminst.GetState()->RemoveUnscriptableCommands();
+ cmGlobalGenerator cmgg(&cminst);
+ cmsys::auto_ptr<cmMakefile> globalMF(
+ new cmMakefile(&cmgg, cminst.GetCurrentSnapshot()));
+#if defined(__CYGWIN__)
+ globalMF->AddDefinition("CMAKE_LEGACY_CYGWIN_WIN32", "0");
+#endif
bool cpackConfigFileSpecified = true;
if ( cpackConfigFile.empty() )
@@ -314,7 +245,7 @@ int main (int argc, char *argv[])
// paths, so FIND_XXX() commands can be used in scripts
std::string systemFile =
globalMF->GetModulesFile("CMakeDetermineSystem.cmake");
- if (!globalMF->ReadListFile(0, systemFile.c_str()))
+ if (!globalMF->ReadListFile(systemFile.c_str()))
{
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"Error reading CMakeDetermineSystem.cmake" << std::endl);
@@ -323,33 +254,38 @@ int main (int argc, char *argv[])
systemFile =
globalMF->GetModulesFile("CMakeSystemSpecificInformation.cmake");
- if (!globalMF->ReadListFile(0, systemFile.c_str()))
+ if (!globalMF->ReadListFile(systemFile.c_str()))
{
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"Error reading CMakeSystemSpecificInformation.cmake" << std::endl);
return 1;
}
+ if ( !cpackBuildConfig.empty() )
+ {
+ globalMF->AddDefinition("CPACK_BUILD_CONFIG", cpackBuildConfig.c_str());
+ }
+
if ( cmSystemTools::FileExists(cpackConfigFile.c_str()) )
{
cpackConfigFile =
- cmSystemTools::CollapseFullPath(cpackConfigFile.c_str());
+ cmSystemTools::CollapseFullPath(cpackConfigFile);
cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
- "Read CPack configuration file: " << cpackConfigFile.c_str()
+ "Read CPack configuration file: " << cpackConfigFile
<< std::endl);
- if ( !globalMF->ReadListFile(0, cpackConfigFile.c_str()) )
+ if ( !globalMF->ReadListFile(cpackConfigFile.c_str()) )
{
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"Problem reading CPack config file: \""
- << cpackConfigFile.c_str() << "\"" << std::endl);
+ << cpackConfigFile << "\"" << std::endl);
return 1;
}
}
else if ( cpackConfigFileSpecified )
{
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
- "Cannot find CPack config file: \"" << cpackConfigFile.c_str()
- << "\"" << std::endl);
+ "Cannot find CPack config file: \"" <<
+ cpackConfigFile << "\"" << std::endl);
return 1;
}
@@ -390,16 +326,12 @@ int main (int argc, char *argv[])
cpackProjectDirectory.c_str());
}
}
- if ( !cpackBuildConfig.empty() )
- {
- globalMF->AddDefinition("CPACK_BUILD_CONFIG", cpackBuildConfig.c_str());
- }
cpackDefinitions::MapType::iterator cdit;
for ( cdit = definitions.Map.begin();
cdit != definitions.Map.end();
++cdit )
{
- globalMF->AddDefinition(cdit->first.c_str(), cdit->second.c_str());
+ globalMF->AddDefinition(cdit->first, cdit->second.c_str());
}
const char* cpackModulesPath =
@@ -413,7 +345,6 @@ int main (int argc, char *argv[])
{
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"CPack generator not specified" << std::endl);
- parsed = 0;
}
else
{
@@ -426,8 +357,8 @@ int main (int argc, char *argv[])
++it )
{
const char* gen = it->c_str();
- cmMakefile newMF(*globalMF);
- cmMakefile* mf = &newMF;
+ cmMakefile::ScopePushPop raii(globalMF.get());
+ cmMakefile* mf = globalMF.get();
cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
"Specified generator: " << gen << std::endl);
if ( parsed && !mf->GetDefinition("CPACK_PACKAGE_NAME") )
@@ -481,11 +412,6 @@ int main (int argc, char *argv[])
}
if ( parsed )
{
-#ifdef _WIN32
- std::string comspec = "cmw9xcom.exe";
- cmSystemTools::SetWindows9xComspecSubstitute(comspec.c_str());
-#endif
-
const char* projName = mf->GetDefinition("CPACK_PACKAGE_NAME");
cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE, "Use generator: "
<< cpackGenerator->GetNameOfClass() << std::endl);
@@ -502,7 +428,7 @@ int main (int argc, char *argv[])
= mf->GetDefinition("CPACK_PACKAGE_VERSION_MINOR");
const char* projVersionPatch
= mf->GetDefinition("CPACK_PACKAGE_VERSION_PATCH");
- cmOStringStream ostr;
+ std::ostringstream ostr;
ostr << projVersionMajor << "." << projVersionMinor << "."
<< projVersionPatch;
mf->AddDefinition("CPACK_PACKAGE_VERSION",
@@ -533,43 +459,8 @@ int main (int argc, char *argv[])
doc.SetName("cpack");
doc.SetSection("Name",cmDocumentationName);
doc.SetSection("Usage",cmDocumentationUsage);
- doc.SetSection("Description",cmDocumentationDescription);
doc.PrependSection("Options",cmDocumentationOptions);
- // statically (in C++ code) defined variables
- cmCPackDocumentVariables::DefineVariables(&cminst);
-
- std::vector<cmDocumentationEntry> commands;
-
- std::string docedFile;
- std::string docPath;
- cmDocumentation::documentedModulesList_t docedModList;
-
- docedFile = globalMF->GetModulesFile("CPack.cmake");
- if (docedFile.length()!=0)
- {
- docPath = cmSystemTools::GetFilenamePath(docedFile.c_str());
- doc.getDocumentedModulesListInDir(docPath,"CPack*.cmake",docedModList);
- }
-
- // parse the files for documentation.
- cmDocumentation::documentedModulesList_t::iterator docedIt;
- for (docedIt = docedModList.begin();
- docedIt!= docedModList.end(); ++docedIt)
- {
- doc.GetStructuredDocFromFile(
- (docedIt->first).c_str(),
- commands,&cminst);
- }
-
- std::map<std::string,cmDocumentationSection *> propDocs;
- cminst.GetPropertiesDocumentation(propDocs);
- doc.SetSections(propDocs);
- cminst.GetCommandDocumentation(commands,true,false);
- // statically (in C++ code) defined macros/commands
- cmCPackDocumentMacros::GetMacrosDocumentation(commands);
- doc.SetSection("Commands",commands);
-
std::vector<cmDocumentationEntry> v;
cmCPackGeneratorFactory::DescriptionsMap::const_iterator generatorIt;
for( generatorIt = generators.GetGeneratorsList().begin();
@@ -579,12 +470,10 @@ int main (int argc, char *argv[])
cmDocumentationEntry e;
e.Name = generatorIt->first.c_str();
e.Brief = generatorIt->second.c_str();
- e.Full = "";
v.push_back(e);
}
doc.SetSection("Generators",v);
- doc.SetSeeAlsoList(cmDocumentationSeeAlso);
#undef cout
return doc.PrintRequestedDocumentation(std::cout)? 0:1;
#define cout no_cout_use_cmCPack_Log
diff --git a/Source/CTest/cmCTestBZR.cxx b/Source/CTest/cmCTestBZR.cxx
index 381c70ce5..587b583ce 100644
--- a/Source/CTest/cmCTestBZR.cxx
+++ b/Source/CTest/cmCTestBZR.cxx
@@ -14,7 +14,6 @@
#include "cmCTest.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"
-#include "cmXMLSafe.h"
#include <cmsys/RegularExpression.hxx>
@@ -225,35 +224,35 @@ private:
return true;
}
- virtual void StartElement(const char* name, const char**)
+ virtual void StartElement(const std::string& name, const char**)
{
this->CData.clear();
- if(strcmp(name, "log") == 0)
+ if(name == "log")
{
this->Rev = Revision();
this->Changes.clear();
}
// affected-files can contain blocks of
// modified, unknown, renamed, kind-changed, removed, conflicts, added
- else if(strcmp(name, "modified") == 0
- || strcmp(name, "renamed") == 0
- || strcmp(name, "kind-changed") == 0)
+ else if(name == "modified"
+ || name == "renamed"
+ || name == "kind-changed")
{
this->CurChange = Change();
this->CurChange.Action = 'M';
}
- else if(strcmp(name, "added") == 0)
+ else if(name == "added")
{
this->CurChange = Change();
this->CurChange = 'A';
}
- else if(strcmp(name, "removed") == 0)
+ else if(name == "removed")
{
this->CurChange = Change();
this->CurChange = 'D';
}
- else if(strcmp(name, "unknown") == 0
- || strcmp(name, "conflicts") == 0)
+ else if(name == "unknown"
+ || name == "conflicts")
{
// Should not happen here
this->CurChange = Change();
@@ -265,27 +264,27 @@ private:
this->CData.insert(this->CData.end(), data, data+length);
}
- virtual void EndElement(const char* name)
+ virtual void EndElement(const std::string& name)
{
- if(strcmp(name, "log") == 0)
+ if(name == "log")
{
this->BZR->DoRevision(this->Rev, this->Changes);
}
- else if((strcmp(name, "file") == 0 || strcmp(name, "directory") == 0)
- && !this->CData.empty())
+ else if(!this->CData.empty() &&
+ (name == "file" || name == "directory"))
{
this->CurChange.Path.assign(&this->CData[0], this->CData.size());
cmSystemTools::ConvertToUnixSlashes(this->CurChange.Path);
this->Changes.push_back(this->CurChange);
}
- else if(strcmp(name, "symlink") == 0 && !this->CData.empty())
+ else if(!this->CData.empty() && name == "symlink")
{
// symlinks have an arobase at the end in the log
this->CurChange.Path.assign(&this->CData[0], this->CData.size()-1);
cmSystemTools::ConvertToUnixSlashes(this->CurChange.Path);
this->Changes.push_back(this->CurChange);
}
- else if(strcmp(name, "committer") == 0 && !this->CData.empty())
+ else if(!this->CData.empty() && name == "committer")
{
this->Rev.Author.assign(&this->CData[0], this->CData.size());
if(this->EmailRegex.find(this->Rev.Author))
@@ -294,15 +293,15 @@ private:
this->Rev.EMail = this->EmailRegex.match(2);
}
}
- else if(strcmp(name, "timestamp") == 0 && !this->CData.empty())
+ else if(!this->CData.empty() && name == "timestamp")
{
this->Rev.Date.assign(&this->CData[0], this->CData.size());
}
- else if(strcmp(name, "message") == 0 && !this->CData.empty())
+ else if(!this->CData.empty() && name == "message")
{
this->Rev.Log.assign(&this->CData[0], this->CData.size());
}
- else if(strcmp(name, "revno") == 0 && !this->CData.empty())
+ else if(!this->CData.empty() && name == "revno")
{
this->Rev.Rev.assign(&this->CData[0], this->CData.size());
}
@@ -409,7 +408,7 @@ bool cmCTestBZR::UpdateImpl()
{
opts = this->CTest->GetCTestConfiguration("BZRUpdateOptions");
}
- std::vector<cmStdString> args = cmSystemTools::ParseArguments(opts.c_str());
+ std::vector<std::string> args = cmSystemTools::ParseArguments(opts.c_str());
// TODO: if(this->CTest->GetTestModel() == cmCTest::NIGHTLY)
@@ -418,7 +417,7 @@ bool cmCTestBZR::UpdateImpl()
bzr_update.push_back(this->CommandLineTool.c_str());
bzr_update.push_back("pull");
- for(std::vector<cmStdString>::const_iterator ai = args.begin();
+ for(std::vector<std::string>::const_iterator ai = args.begin();
ai != args.end(); ++ai)
{
bzr_update.push_back(ai->c_str());
diff --git a/Source/CTest/cmCTestBatchTestHandler.cxx b/Source/CTest/cmCTestBatchTestHandler.cxx
index 934481b88..d62c260d6 100644
--- a/Source/CTest/cmCTestBatchTestHandler.cxx
+++ b/Source/CTest/cmCTestBatchTestHandler.cxx
@@ -33,8 +33,8 @@ void cmCTestBatchTestHandler::WriteBatchScript()
{
this->Script = this->CTest->GetBinaryDir()
+ "/Testing/CTestBatch.txt";
- std::fstream fout;
- fout.open(this->Script.c_str(), std::ios::out);
+ cmsys::ofstream fout;
+ fout.open(this->Script.c_str());
fout << "#!/bin/sh\n";
for(TestMap::iterator i = this->Tests.begin(); i != this->Tests.end(); ++i)
@@ -48,7 +48,7 @@ void cmCTestBatchTestHandler::WriteBatchScript()
}
//---------------------------------------------------------
-void cmCTestBatchTestHandler::WriteSrunArgs(int test, std::fstream& fout)
+void cmCTestBatchTestHandler::WriteSrunArgs(int test, cmsys::ofstream& fout)
{
cmCTestTestHandler::cmCTestTestProperties* properties =
this->Properties[test];
@@ -58,7 +58,7 @@ void cmCTestBatchTestHandler::WriteSrunArgs(int test, std::fstream& fout)
fout << "-J=" << properties->Name << " ";
//Write dependency information
- /*if(this->Tests[test].size() > 0)
+ /*if(!this->Tests[test].empty())
{
fout << "-P=afterany";
for(TestSet::iterator i = this->Tests[test].begin();
@@ -79,7 +79,7 @@ void cmCTestBatchTestHandler::WriteSrunArgs(int test, std::fstream& fout)
}
//---------------------------------------------------------
-void cmCTestBatchTestHandler::WriteTestCommand(int test, std::fstream& fout)
+void cmCTestBatchTestHandler::WriteTestCommand(int test, cmsys::ofstream& fout)
{
std::vector<std::string> args = this->Properties[test]->Args;
std::vector<std::string> processArgs;
diff --git a/Source/CTest/cmCTestBatchTestHandler.h b/Source/CTest/cmCTestBatchTestHandler.h
index ab0d081ae..e0c6e48d5 100644
--- a/Source/CTest/cmCTestBatchTestHandler.h
+++ b/Source/CTest/cmCTestBatchTestHandler.h
@@ -17,6 +17,7 @@
#include <cmCTestTestHandler.h>
#include <cmCTestMultiProcessHandler.h>
#include <cmCTestRunTest.h>
+#include <cmsys/FStream.hxx>
/** \class cmCTestBatchTestHandler
* \brief run parallel ctest
@@ -30,8 +31,8 @@ public:
virtual void RunTests();
protected:
void WriteBatchScript();
- void WriteSrunArgs(int test, std::fstream& fout);
- void WriteTestCommand(int test, std::fstream& fout);
+ void WriteSrunArgs(int test, cmsys::ofstream& fout);
+ void WriteTestCommand(int test, cmsys::ofstream& fout);
void SubmitBatchScript();
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx
index 4fa3c53b9..20d303d82 100644
--- a/Source/CTest/cmCTestBuildAndTestHandler.cxx
+++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx
@@ -31,8 +31,7 @@ cmCTestBuildAndTestHandler::cmCTestBuildAndTestHandler()
//----------------------------------------------------------------------
void cmCTestBuildAndTestHandler::Initialize()
{
- this->BuildTargets.erase(
- this->BuildTargets.begin(), this->BuildTargets.end());
+ this->BuildTargets.clear();
this->Superclass::Initialize();
}
@@ -54,20 +53,26 @@ int cmCTestBuildAndTestHandler::ProcessHandler()
//----------------------------------------------------------------------
int cmCTestBuildAndTestHandler::RunCMake(std::string* outstring,
- cmOStringStream &out, std::string &cmakeOutString, std::string &cwd,
+ std::ostringstream &out, std::string &cmakeOutString, std::string &cwd,
cmake *cm)
{
unsigned int k;
std::vector<std::string> args;
- args.push_back(this->CTest->GetCMakeExecutable());
+ args.push_back(cmSystemTools::GetCMakeCommand());
args.push_back(this->SourceDir);
- if(this->BuildGenerator.size())
+ if(!this->BuildGenerator.empty())
{
std::string generator = "-G";
generator += this->BuildGenerator;
args.push_back(generator);
}
- if(this->BuildGeneratorToolset.size())
+ if(!this->BuildGeneratorPlatform.empty())
+ {
+ std::string platform = "-A";
+ platform += this->BuildGeneratorPlatform;
+ args.push_back(platform);
+ }
+ if(!this->BuildGeneratorToolset.empty())
{
std::string toolset = "-T";
toolset += this->BuildGeneratorToolset;
@@ -75,7 +80,7 @@ int cmCTestBuildAndTestHandler::RunCMake(std::string* outstring,
}
const char* config = 0;
- if ( this->CTest->GetConfigType().size() > 0 )
+ if (!this->CTest->GetConfigType().empty())
{
config = this->CTest->GetConfigType().c_str();
}
@@ -102,7 +107,7 @@ int cmCTestBuildAndTestHandler::RunCMake(std::string* outstring,
out << "Error: cmake execution failed\n";
out << cmakeOutString << "\n";
// return to the original directory
- cmSystemTools::ChangeDirectory(cwd.c_str());
+ cmSystemTools::ChangeDirectory(cwd);
if(outstring)
{
*outstring = out.str();
@@ -121,7 +126,7 @@ int cmCTestBuildAndTestHandler::RunCMake(std::string* outstring,
out << "Error: cmake execution failed\n";
out << cmakeOutString << "\n";
// return to the original directory
- cmSystemTools::ChangeDirectory(cwd.c_str());
+ cmSystemTools::ChangeDirectory(cwd);
if(outstring)
{
*outstring = out.str();
@@ -155,49 +160,59 @@ void CMakeProgressCallback(const char*msg, float , void * s)
}
//----------------------------------------------------------------------
-void CMakeStdoutCallback(const char* m, int len, void* s)
+void CMakeOutputCallback(const char* m, size_t len, void* s)
{
std::string* out = (std::string*)s;
out->append(m, len);
}
-struct cmSetupOutputCaptureCleanup
+
+//----------------------------------------------------------------------
+class cmCTestBuildAndTestCaptureRAII
{
- ~cmSetupOutputCaptureCleanup()
- {
- cmSystemTools::SetErrorCallback(0, 0);
+ cmake& CM;
+public:
+ cmCTestBuildAndTestCaptureRAII(cmake& cm, std::string& s): CM(cm)
+ {
+ cmSystemTools::SetMessageCallback(CMakeMessageCallback, &s);
+ cmSystemTools::SetStdoutCallback(CMakeOutputCallback, &s);
+ cmSystemTools::SetStderrCallback(CMakeOutputCallback, &s);
+ this->CM.SetProgressCallback(CMakeProgressCallback, &s);
+ }
+ ~cmCTestBuildAndTestCaptureRAII()
+ {
+ this->CM.SetProgressCallback(0, 0);
+ cmSystemTools::SetStderrCallback(0, 0);
cmSystemTools::SetStdoutCallback(0, 0);
- }
+ cmSystemTools::SetMessageCallback(0, 0);
+ }
};
//----------------------------------------------------------------------
int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
{
- unsigned int k;
- std::string cmakeOutString;
- cmSystemTools::SetErrorCallback(CMakeMessageCallback, &cmakeOutString);
- cmSystemTools::SetStdoutCallback(CMakeStdoutCallback, &cmakeOutString);
- // make sure SetStdoutCallback and SetErrorCallback are set to null
- // after this function exits so that they do not point at a destroyed
- // string cmakeOutString
- cmSetupOutputCaptureCleanup cleanup;
- static_cast<void>(cleanup);
- cmOStringStream out;
-
// if the generator and make program are not specified then it is an error
- if (!this->BuildGenerator.size() || !this->BuildMakeProgram.size())
+ if (this->BuildGenerator.empty())
{
if(outstring)
{
*outstring =
- "--build-and-test requires that both the generator and makeprogram "
- "be provided using the --build-generator and --build-makeprogram "
- "command line options. ";
+ "--build-and-test requires that the generator "
+ "be provided using the --build-generator "
+ "command line option. ";
}
return 1;
}
- if ( this->CTest->GetConfigType().size() == 0 &&
- this->ConfigSample.size())
+ cmake cm;
+ cm.SetHomeDirectory("");
+ cm.SetHomeOutputDirectory("");
+ std::string cmakeOutString;
+ cmCTestBuildAndTestCaptureRAII captureRAII(cm, cmakeOutString);
+ static_cast<void>(captureRAII);
+ std::ostringstream out;
+
+ if ( this->CTest->GetConfigType().empty() &&
+ !this->ConfigSample.empty())
{
// use the config sample to set the ConfigType
std::string fullPath;
@@ -210,7 +225,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
resultingConfig,
extraPaths,
failed);
- if (fullPath.size() && resultingConfig.size())
+ if (!fullPath.empty() && !resultingConfig.empty())
{
this->CTest->SetConfigType(resultingConfig.c_str());
}
@@ -226,21 +241,22 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
out << "Internal cmake changing into directory: "
<< this->BinaryDir << std::endl;
- if (!cmSystemTools::FileIsDirectory(this->BinaryDir.c_str()))
+ if (!cmSystemTools::FileIsDirectory(this->BinaryDir))
{
cmSystemTools::MakeDirectory(this->BinaryDir.c_str());
}
- cmSystemTools::ChangeDirectory(this->BinaryDir.c_str());
-
- // should we cmake?
- cmake cm;
- cm.SetProgressCallback(CMakeProgressCallback, &cmakeOutString);
+ cmSystemTools::ChangeDirectory(this->BinaryDir);
if(this->BuildNoCMake)
{
+ // Make the generator available for the Build call below.
cm.SetGlobalGenerator(cm.CreateGlobalGenerator(
- this->BuildGenerator.c_str()));
+ this->BuildGenerator));
+ cm.SetGeneratorPlatform(this->BuildGeneratorPlatform);
cm.SetGeneratorToolset(this->BuildGeneratorToolset);
+
+ // Load the cache to make CMAKE_MAKE_PROGRAM available.
+ cm.LoadCache(this->BinaryDir);
}
else
{
@@ -253,7 +269,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
// do the build
std::vector<std::string>::iterator tarIt;
- if ( this->BuildTargets.size() == 0 )
+ if (this->BuildTargets.empty())
{
this->BuildTargets.push_back("");
}
@@ -275,7 +291,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
}
std::string output;
const char* config = 0;
- if ( this->CTest->GetConfigType().size() > 0 )
+ if (!this->CTest->GetConfigType().empty())
{
config = this->CTest->GetConfigType().c_str();
}
@@ -290,12 +306,12 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
config = "Debug";
}
int retVal = cm.GetGlobalGenerator()->Build(
- this->SourceDir.c_str(), this->BinaryDir.c_str(),
- this->BuildProject.c_str(), tarIt->c_str(),
- &output, this->BuildMakeProgram.c_str(),
+ this->SourceDir, this->BinaryDir,
+ this->BuildProject, *tarIt,
+ output, this->BuildMakeProgram,
config,
!this->BuildNoClean,
- false, remainingTime);
+ false, false, remainingTime);
out << output;
// if the build failed then return
if (retVal)
@@ -313,7 +329,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
}
// if no test was specified then we are done
- if (!this->TestCommand.size())
+ if (this->TestCommand.empty())
{
return 0;
}
@@ -324,7 +340,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
std::string resultingConfig;
std::vector<std::string> extraPaths;
// if this->ExecutableDirectory is set try that as well
- if (this->ExecutableDirectory.size())
+ if (!this->ExecutableDirectory.empty())
{
std::string tempPath = this->ExecutableDirectory;
tempPath += "/";
@@ -358,13 +374,13 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
cmCTestLog(this->CTest, ERROR_MESSAGE, out.str());
}
// return to the original directory
- cmSystemTools::ChangeDirectory(cwd.c_str());
+ cmSystemTools::ChangeDirectory(cwd);
return 1;
}
std::vector<const char*> testCommand;
testCommand.push_back(fullPath.c_str());
- for(k=0; k < this->TestCommandArgs.size(); ++k)
+ for(size_t k=0; k < this->TestCommandArgs.size(); ++k)
{
testCommand.push_back(this->TestCommandArgs[k].c_str());
}
@@ -372,13 +388,13 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
std::string outs;
int retval = 0;
// run the test from the this->BuildRunDir if set
- if(this->BuildRunDir.size())
+ if(!this->BuildRunDir.empty())
{
out << "Run test in directory: " << this->BuildRunDir << "\n";
- cmSystemTools::ChangeDirectory(this->BuildRunDir.c_str());
+ cmSystemTools::ChangeDirectory(this->BuildRunDir);
}
out << "Running test command: \"" << fullPath << "\"";
- for(k=0; k < this->TestCommandArgs.size(); ++k)
+ for(size_t k=0; k < this->TestCommandArgs.size(); ++k)
{
out << " \"" << this->TestCommandArgs[k] << "\"";
}
@@ -437,9 +453,9 @@ int cmCTestBuildAndTestHandler::ProcessCommandLineArguments(
// dir must exist before CollapseFullPath is called
cmSystemTools::MakeDirectory(this->BinaryDir.c_str());
this->BinaryDir
- = cmSystemTools::CollapseFullPath(this->BinaryDir.c_str());
+ = cmSystemTools::CollapseFullPath(this->BinaryDir);
this->SourceDir
- = cmSystemTools::CollapseFullPath(this->SourceDir.c_str());
+ = cmSystemTools::CollapseFullPath(this->SourceDir);
}
else
{
@@ -481,6 +497,12 @@ int cmCTestBuildAndTestHandler::ProcessCommandLineArguments(
idx++;
this->BuildGenerator = allArgs[idx];
}
+ if(currentArg == "--build-generator-platform" &&
+ idx < allArgs.size() - 1)
+ {
+ idx++;
+ this->BuildGeneratorPlatform = allArgs[idx];
+ }
if(currentArg == "--build-generator-toolset" &&
idx < allArgs.size() - 1)
{
@@ -508,23 +530,14 @@ int cmCTestBuildAndTestHandler::ProcessCommandLineArguments(
{
this->BuildNoClean = true;
}
- if(currentArg.find("--build-options",0) == 0 && idx < allArgs.size() - 1)
+ if(currentArg.find("--build-options",0) == 0)
{
- ++idx;
- bool done = false;
- while(idx < allArgs.size() && !done)
+ while(idx+1 < allArgs.size() &&
+ allArgs[idx+1] != "--build-target" &&
+ allArgs[idx+1] != "--test-command")
{
+ ++idx;
this->BuildOptions.push_back(allArgs[idx]);
- if(idx+1 < allArgs.size()
- && (allArgs[idx+1] == "--build-target" ||
- allArgs[idx+1] == "--test-command"))
- {
- done = true;
- }
- else
- {
- ++idx;
- }
}
}
if(currentArg.find("--test-command",0) == 0 && idx < allArgs.size() - 1)
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.h b/Source/CTest/cmCTestBuildAndTestHandler.h
index ca50c6452..a75c631a2 100644
--- a/Source/CTest/cmCTestBuildAndTestHandler.h
+++ b/Source/CTest/cmCTestBuildAndTestHandler.h
@@ -50,13 +50,14 @@ public:
protected:
///! Run CMake and build a test and then run it as a single test.
int RunCMakeAndTest(std::string* output);
- int RunCMake(std::string* outstring, cmOStringStream &out,
+ int RunCMake(std::string* outstring, std::ostringstream &out,
std::string &cmakeOutString,
std::string &cwd, cmake *cm);
- cmStdString Output;
+ std::string Output;
std::string BuildGenerator;
+ std::string BuildGeneratorPlatform;
std::string BuildGeneratorToolset;
std::vector<std::string> BuildOptions;
bool BuildTwoConfig;
diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx
index 1f63185c1..27e22c4c7 100644
--- a/Source/CTest/cmCTestBuildCommand.cxx
+++ b/Source/CTest/cmCTestBuildCommand.cxx
@@ -58,7 +58,8 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler()
= this->Makefile->GetDefinition("CTEST_BUILD_COMMAND");
if ( ctestBuildCommand && *ctestBuildCommand )
{
- this->CTest->SetCTestConfiguration("MakeCommand", ctestBuildCommand);
+ this->CTest->SetCTestConfiguration("MakeCommand", ctestBuildCommand,
+ this->Quiet);
}
else
{
@@ -101,8 +102,7 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler()
}
if ( this->GlobalGenerator )
{
- if ( strcmp(this->GlobalGenerator->GetName(),
- cmakeGeneratorName) != 0 )
+ if ( this->GlobalGenerator->GetName() != cmakeGeneratorName )
{
delete this->GlobalGenerator;
this->GlobalGenerator = 0;
@@ -113,10 +113,16 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler()
this->GlobalGenerator =
this->Makefile->GetCMakeInstance()->CreateGlobalGenerator(
cmakeGeneratorName);
+ if(!this->GlobalGenerator)
+ {
+ std::string e = "could not create generator named \"";
+ e += cmakeGeneratorName;
+ e += "\"";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e);
+ cmSystemTools::SetFatalErrorOccured();
+ return 0;
+ }
}
- this->GlobalGenerator->FindMakeProgram(this->Makefile);
- const char* cmakeMakeProgram
- = this->Makefile->GetDefinition("CMAKE_MAKE_PROGRAM");
if(strlen(cmakeBuildConfiguration) == 0)
{
const char* config = 0;
@@ -133,18 +139,18 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler()
std::string dir = this->CTest->GetCTestConfiguration("BuildDirectory");
std::string buildCommand
= this->GlobalGenerator->
- GenerateBuildCommand(cmakeMakeProgram,
- cmakeProjectName, dir.c_str(),
- cmakeBuildAdditionalFlags, cmakeBuildTarget,
- cmakeBuildConfiguration, true, false);
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "SetMakeCommand:"
- << buildCommand.c_str() << "\n");
- this->CTest->SetCTestConfiguration("MakeCommand", buildCommand.c_str());
+ GenerateCMakeBuildCommand(cmakeBuildTarget ? cmakeBuildTarget : "",
+ cmakeBuildConfiguration,
+ cmakeBuildAdditionalFlags ? cmakeBuildAdditionalFlags : "",
+ this->Makefile->IgnoreErrorsCMP0061());
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "SetMakeCommand:" << buildCommand << "\n", this->Quiet);
+ this->CTest->SetCTestConfiguration("MakeCommand", buildCommand.c_str(),
+ this->Quiet);
}
else
{
- cmOStringStream ostr;
+ std::ostringstream ostr;
ostr << "has no project to build. If this is a "
"\"built with CMake\" project, verify that CTEST_CMAKE_GENERATOR "
"and CTEST_PROJECT_NAME are set."
@@ -156,7 +162,7 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler()
"\n"
"Alternatively, set CTEST_BUILD_COMMAND to build the project "
"with a custom command line.";
- this->SetError(ostr.str().c_str());
+ this->SetError(ostr.str());
return 0;
}
}
@@ -164,9 +170,11 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler()
if(const char* useLaunchers =
this->Makefile->GetDefinition("CTEST_USE_LAUNCHERS"))
{
- this->CTest->SetCTestConfiguration("UseLaunchers", useLaunchers);
+ this->CTest->SetCTestConfiguration("UseLaunchers", useLaunchers,
+ this->Quiet);
}
+ handler->SetQuiet(this->Quiet);
return handler;
}
@@ -177,7 +185,7 @@ bool cmCTestBuildCommand::InitialPass(std::vector<std::string> const& args,
bool ret = cmCTestHandlerCommand::InitialPass(args, status);
if ( this->Values[ctb_NUMBER_ERRORS] && *this->Values[ctb_NUMBER_ERRORS])
{
- cmOStringStream str;
+ std::ostringstream str;
str << this->Handler->GetTotalErrors();
this->Makefile->AddDefinition(
this->Values[ctb_NUMBER_ERRORS], str.str().c_str());
@@ -185,7 +193,7 @@ bool cmCTestBuildCommand::InitialPass(std::vector<std::string> const& args,
if ( this->Values[ctb_NUMBER_WARNINGS]
&& *this->Values[ctb_NUMBER_WARNINGS])
{
- cmOStringStream str;
+ std::ostringstream str;
str << this->Handler->GetTotalWarnings();
this->Makefile->AddDefinition(
this->Values[ctb_NUMBER_WARNINGS], str.str().c_str());
diff --git a/Source/CTest/cmCTestBuildCommand.h b/Source/CTest/cmCTestBuildCommand.h
index cabc39b32..2632ebc47 100644
--- a/Source/CTest/cmCTestBuildCommand.h
+++ b/Source/CTest/cmCTestBuildCommand.h
@@ -43,36 +43,10 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "ctest_build";}
+ virtual std::string GetName() const { return "ctest_build";}
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Build the project.";
- }
virtual bool InitialPass(std::vector<std::string> const& args,
cmExecutionStatus &status);
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " ctest_build([BUILD build_dir] [TARGET target] [RETURN_VALUE res]\n"
- " [APPEND][NUMBER_ERRORS val] [NUMBER_WARNINGS val])\n"
- "Builds the given build directory and stores results in Build.xml. "
- "If no BUILD is given, the CTEST_BINARY_DIRECTORY variable is used.\n"
- "The TARGET variable can be used to specify a build target. If none "
- "is specified, the \"all\" target will be built.\n"
- "The RETURN_VALUE option specifies a variable in which to store the "
- "return value of the native build tool. "
- "The NUMBER_ERRORS and NUMBER_WARNINGS options specify variables in "
- "which to store the number of build errors and warnings detected."
- "\n"
- CTEST_COMMAND_APPEND_OPTION_DOCS;
- }
cmTypeMacro(cmCTestBuildCommand, cmCTestHandlerCommand);
diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx
index 39eeb70a3..0d74f48f2 100644
--- a/Source/CTest/cmCTestBuildHandler.cxx
+++ b/Source/CTest/cmCTestBuildHandler.cxx
@@ -15,15 +15,16 @@
#include "cmCTest.h"
#include "cmake.h"
#include "cmMakefile.h"
-#include "cmLocalGenerator.h"
#include "cmGlobalGenerator.h"
#include "cmGeneratedFileStream.h"
-#include "cmXMLSafe.h"
+#include "cmXMLWriter.h"
#include "cmFileTimeComparison.h"
+#include "cmAlgorithms.h"
//#include <cmsys/RegularExpression.hxx>
#include <cmsys/Process.h>
#include <cmsys/Directory.hxx>
+#include <cmsys/FStream.hxx>
// used for sleep
#ifdef _WIN32
@@ -35,9 +36,6 @@
#include <math.h>
#include <float.h>
-#if defined(__BORLANDC__)
-# pragma warn -8060 /* possibly incorrect assignment */
-#endif
static const char* cmCTestErrorMatches[] = {
"^[Bb]us [Ee]rror",
@@ -69,13 +67,13 @@ static const char* cmCTestErrorMatches[] = {
"^CMake Error.*:",
":[ \\t]cannot find",
":[ \\t]can't find",
- ": \\*\\*\\* No rule to make target \\`.*\\'. Stop",
+ ": \\*\\*\\* No rule to make target [`'].*\\'. Stop",
": \\*\\*\\* No targets specified and no makefile found",
": Invalid loader fixup for symbol",
": Invalid fixups exist",
": Can't find library for",
": internal link edit command failed",
- ": Unrecognized option \\`.*\\'",
+ ": Unrecognized option [`'].*\\'",
"\", line [0-9]+\\.[0-9]+: [0-9]+-[0-9]+ \\([^WI]\\)",
"ld: 0706-006 Cannot find or open library file: -l ",
"ild: \\(argument error\\) can't find library argument ::",
@@ -288,9 +286,9 @@ std::string cmCTestBuildHandler::GetMakeCommand()
{
std::string makeCommand
= this->CTest->GetCTestConfiguration("MakeCommand");
- cmCTestLog(this->CTest,
- HANDLER_VERBOSE_OUTPUT, "MakeCommand:" << makeCommand <<
- "\n");
+ cmCTestOptionalLog(this->CTest,
+ HANDLER_VERBOSE_OUTPUT, "MakeCommand:" << makeCommand << "\n",
+ this->Quiet);
std::string configType = this->CTest->GetConfigType();
if (configType == "")
@@ -314,7 +312,8 @@ std::string cmCTestBuildHandler::GetMakeCommand()
//functions and commented...
int cmCTestBuildHandler::ProcessHandler()
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT, "Build project" << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "Build project" << std::endl,
+ this->Quiet);
// do we have time for this
if (this->CTest->GetRemainingTimeAllowed() < 120)
@@ -346,7 +345,7 @@ int cmCTestBuildHandler::ProcessHandler()
// Determine build command and build directory
std::string makeCommand = this->GetMakeCommand();
- if ( makeCommand.size() == 0 )
+ if (makeCommand.empty())
{
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Cannot find MakeCommand key in the DartConfiguration.tcl"
@@ -356,7 +355,7 @@ int cmCTestBuildHandler::ProcessHandler()
const std::string &buildDirectory
= this->CTest->GetCTestConfiguration("BuildDirectory");
- if ( buildDirectory.size() == 0 )
+ if (buildDirectory.empty())
{
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Cannot find BuildDirectory key in the DartConfiguration.tcl"
@@ -379,7 +378,7 @@ int cmCTestBuildHandler::ProcessHandler()
// Create lists of regular expression strings for errors, error exceptions,
// warnings and warning exceptions.
- std::vector<cmStdString>::size_type cc;
+ std::vector<std::string>::size_type cc;
for ( cc = 0; cmCTestErrorMatches[cc]; cc ++ )
{
this->CustomErrorMatches.push_back(cmCTestErrorMatches[cc]);
@@ -399,16 +398,16 @@ int cmCTestBuildHandler::ProcessHandler()
}
// Pre-compile regular expressions objects for all regular expressions
- std::vector<cmStdString>::iterator it;
+ std::vector<std::string>::iterator it;
#define cmCTestBuildHandlerPopulateRegexVector(strings, regexes) \
regexes.clear(); \
- cmCTestLog(this->CTest, DEBUG, this << "Add " #regexes \
- << std::endl); \
+ cmCTestOptionalLog(this->CTest, DEBUG, this << "Add " #regexes \
+ << std::endl, this->Quiet); \
for ( it = strings.begin(); it != strings.end(); ++it ) \
{ \
- cmCTestLog(this->CTest, DEBUG, "Add " #strings ": " \
- << it->c_str() << std::endl); \
+ cmCTestOptionalLog(this->CTest, DEBUG, "Add " #strings ": " \
+ << *it << std::endl, this->Quiet); \
regexes.push_back(it->c_str()); \
}
cmCTestBuildHandlerPopulateRegexVector(
@@ -474,8 +473,8 @@ int cmCTestBuildHandler::ProcessHandler()
}
else
{
- cmCTestLog(this->CTest, DEBUG, "Build with command: " << makeCommand
- << std::endl);
+ cmCTestOptionalLog(this->CTest, DEBUG, "Build with command: " <<
+ makeCommand << std::endl, this->Quiet);
}
// Remember end build time and calculate elapsed time
@@ -523,16 +522,17 @@ int cmCTestBuildHandler::ProcessHandler()
<< std::endl);
return -1;
}
- this->GenerateXMLHeader(xofs);
+ cmXMLWriter xml(xofs);
+ this->GenerateXMLHeader(xml);
if(this->UseCTestLaunch)
{
- this->GenerateXMLLaunched(xofs);
+ this->GenerateXMLLaunched(xml);
}
else
{
- this->GenerateXMLLogScraped(xofs);
+ this->GenerateXMLLogScraped(xml);
}
- this->GenerateXMLFooter(xofs, elapsed_build_time);
+ this->GenerateXMLFooter(xml, elapsed_build_time);
if (res != cmsysProcess_State_Exited || retVal || this->TotalErrors > 0)
{
@@ -552,17 +552,14 @@ int cmCTestBuildHandler::ProcessHandler()
}
//----------------------------------------------------------------------------
-void cmCTestBuildHandler::GenerateXMLHeader(std::ostream& os)
+void cmCTestBuildHandler::GenerateXMLHeader(cmXMLWriter& xml)
{
- this->CTest->StartXML(os, this->AppendXML);
- os << "<Build>\n"
- << "\t<StartDateTime>" << this->StartBuild << "</StartDateTime>\n"
- << "\t<StartBuildTime>" <<
- static_cast<unsigned int>(this->StartBuildTime)
- << "</StartBuildTime>\n"
- << "<BuildCommand>"
- << cmXMLSafe(this->GetMakeCommand())
- << "</BuildCommand>" << std::endl;
+ this->CTest->StartXML(xml, this->AppendXML);
+ xml.StartElement("Build");
+ xml.Element("StartDateTime", this->StartBuild);
+ xml.Element("StartBuildTime",
+ static_cast<unsigned int>(this->StartBuildTime));
+ xml.Element("BuildCommand", this->GetMakeCommand());
}
//----------------------------------------------------------------------------
@@ -591,7 +588,7 @@ private:
};
//----------------------------------------------------------------------------
-void cmCTestBuildHandler::GenerateXMLLaunched(std::ostream& os)
+void cmCTestBuildHandler::GenerateXMLLaunched(cmXMLWriter& xml)
{
if(this->CTestLaunchDir.empty())
{
@@ -601,23 +598,28 @@ void cmCTestBuildHandler::GenerateXMLLaunched(std::ostream& os)
// Sort XML fragments in chronological order.
cmFileTimeComparison ftc;
FragmentCompare fragmentCompare(&ftc);
- typedef std::set<cmStdString, FragmentCompare> Fragments;
+ typedef std::set<std::string, FragmentCompare> Fragments;
Fragments fragments(fragmentCompare);
+ // only report the first 50 warnings and first 50 errors
+ int numErrorsAllowed = this->MaxErrors;
+ int numWarningsAllowed = this->MaxWarnings;
// Identify fragments on disk.
cmsys::Directory launchDir;
- launchDir.Load(this->CTestLaunchDir.c_str());
+ launchDir.Load(this->CTestLaunchDir);
unsigned long n = launchDir.GetNumberOfFiles();
for(unsigned long i=0; i < n; ++i)
{
const char* fname = launchDir.GetFile(i);
- if(this->IsLaunchedErrorFile(fname))
+ if(this->IsLaunchedErrorFile(fname) && numErrorsAllowed)
{
+ numErrorsAllowed--;
fragments.insert(this->CTestLaunchDir + "/" + fname);
++this->TotalErrors;
}
- else if(this->IsLaunchedWarningFile(fname))
+ else if(this->IsLaunchedWarningFile(fname) && numWarningsAllowed)
{
+ numWarningsAllowed--;
fragments.insert(this->CTestLaunchDir + "/" + fname);
++this->TotalWarnings;
}
@@ -627,12 +629,12 @@ void cmCTestBuildHandler::GenerateXMLLaunched(std::ostream& os)
for(Fragments::const_iterator fi = fragments.begin();
fi != fragments.end(); ++fi)
{
- this->GenerateXMLLaunchedFragment(os, fi->c_str());
+ xml.FragmentFile(fi->c_str());
}
}
//----------------------------------------------------------------------------
-void cmCTestBuildHandler::GenerateXMLLogScraped(std::ostream& os)
+void cmCTestBuildHandler::GenerateXMLLogScraped(cmXMLWriter& xml)
{
std::vector<cmCTestBuildErrorWarning>& ew = this->ErrorsAndWarnings;
std::vector<cmCTestBuildErrorWarning>::iterator it;
@@ -643,7 +645,7 @@ void cmCTestBuildHandler::GenerateXMLLogScraped(std::ostream& os)
std::string srcdir = this->CTest->GetCTestConfiguration("SourceDirectory");
// make sure the source dir is in the correct case on windows
// via a call to collapse full path.
- srcdir = cmSystemTools::CollapseFullPath(srcdir.c_str());
+ srcdir = cmSystemTools::CollapseFullPath(srcdir);
srcdir += "/";
for ( it = ew.begin();
it != ew.end() && (numErrorsAllowed || numWarningsAllowed); it++ )
@@ -660,10 +662,9 @@ void cmCTestBuildHandler::GenerateXMLLogScraped(std::ostream& os)
{
numWarningsAllowed--;
}
- os << "\t<" << (cm->Error ? "Error" : "Warning") << ">\n"
- << "\t\t<BuildLogLine>" << cm->LogLine << "</BuildLogLine>\n"
- << "\t\t<Text>" << cmXMLSafe(cm->Text).Quotes(false)
- << "\n</Text>" << std::endl;
+ xml.StartElement(cm->Error ? "Error" : "Warning");
+ xml.Element("BuildLogLine", cm->LogLine);
+ xml.Element("Text", cm->Text);
std::vector<cmCTestCompileErrorWarningRex>::iterator rit;
for ( rit = this->ErrorWarningFileLineRegex.begin();
rit != this->ErrorWarningFileLineRegex.end(); ++ rit )
@@ -689,7 +690,7 @@ void cmCTestBuildHandler::GenerateXMLLogScraped(std::ostream& os)
{
// make sure it is a full path with the correct case
cm->SourceFile = cmSystemTools::CollapseFullPath(
- cm->SourceFile.c_str());
+ cm->SourceFile);
cmSystemTools::ReplaceString(
cm->SourceFile, srcdir.c_str(), "");
}
@@ -699,71 +700,57 @@ void cmCTestBuildHandler::GenerateXMLLogScraped(std::ostream& os)
}
if ( !cm->SourceFile.empty() && cm->LineNumber >= 0 )
{
- if ( cm->SourceFile.size() > 0 )
+ if (!cm->SourceFile.empty())
{
- os << "\t\t<SourceFile>" << cm->SourceFile << "</SourceFile>"
- << std::endl;
+ xml.Element("SourceFile", cm->SourceFile);
}
- if ( cm->SourceFileTail.size() > 0 )
+ if (!cm->SourceFileTail.empty())
{
- os << "\t\t<SourceFileTail>" << cm->SourceFileTail
- << "</SourceFileTail>" << std::endl;
+ xml.Element("SourceFileTail", cm->SourceFileTail);
}
if ( cm->LineNumber >= 0 )
{
- os << "\t\t<SourceLineNumber>" << cm->LineNumber
- << "</SourceLineNumber>" << std::endl;
+ xml.Element("SourceLineNumber", cm->LineNumber);
}
}
- os << "\t\t<PreContext>" << cmXMLSafe(cm->PreContext).Quotes(false)
- << "</PreContext>\n"
- << "\t\t<PostContext>" << cmXMLSafe(cm->PostContext).Quotes(false);
+ xml.Element("PreContext", cm->PreContext);
+ xml.StartElement("PostContext");
+ xml.Content(cm->PostContext);
// is this the last warning or error, if so notify
if ((cm->Error && !numErrorsAllowed) ||
(!cm->Error && !numWarningsAllowed))
{
- os << "\nThe maximum number of reported warnings or errors has been "
- "reached!!!\n";
+ xml.Content("\nThe maximum number of reported warnings or errors "
+ "has been reached!!!\n");
}
- os << "</PostContext>\n"
- << "\t\t<RepeatCount>0</RepeatCount>\n"
- << "</" << (cm->Error ? "Error" : "Warning") << ">\n\n"
- << std::endl;
+ xml.EndElement(); // PostContext
+ xml.Element("RepeatCount", "0");
+ xml.EndElement(); // "Error" / "Warning"
}
}
}
//----------------------------------------------------------------------------
-void cmCTestBuildHandler::GenerateXMLFooter(std::ostream& os,
+void cmCTestBuildHandler::GenerateXMLFooter(cmXMLWriter& xml,
double elapsed_build_time)
{
- os << "\t<Log Encoding=\"base64\" Compression=\"/bin/gzip\">\n\t</Log>\n"
- << "\t<EndDateTime>" << this->EndBuild << "</EndDateTime>\n"
- << "\t<EndBuildTime>" << static_cast<unsigned int>(this->EndBuildTime)
- << "</EndBuildTime>\n"
- << "<ElapsedMinutes>" << static_cast<int>(elapsed_build_time/6)/10.0
- << "</ElapsedMinutes>"
- << "</Build>" << std::endl;
- this->CTest->EndXML(os);
-}
-
-//----------------------------------------------------------------------------
-void cmCTestBuildHandler::GenerateXMLLaunchedFragment(std::ostream& os,
- const char* fname)
-{
- std::ifstream fin(fname, std::ios::in | std::ios::binary);
- std::string line;
- while(cmSystemTools::GetLineFromStream(fin, line))
- {
- os << line << "\n";
- }
+ xml.StartElement("Log");
+ xml.Attribute("Encoding", "base64");
+ xml.Attribute("Compression", "bin/gzip");
+ xml.EndElement(); // Log
+
+ xml.Element("EndDateTime", this->EndBuild);
+ xml.Element("EndBuildTime", static_cast<unsigned int>(this->EndBuildTime));
+ xml.Element("ElapsedMinutes", static_cast<int>(elapsed_build_time/6)/10.0);
+ xml.EndElement(); // Build
+ this->CTest->EndXML(xml);
}
//----------------------------------------------------------------------------
bool cmCTestBuildHandler::IsLaunchedErrorFile(const char* fname)
{
// error-{hash}.xml
- return (strncmp(fname, "error-", 6) == 0 &&
+ return (cmHasLiteralPrefix(fname, "error-") &&
strcmp(fname+strlen(fname)-4, ".xml") == 0);
}
@@ -771,7 +758,7 @@ bool cmCTestBuildHandler::IsLaunchedErrorFile(const char* fname)
bool cmCTestBuildHandler::IsLaunchedWarningFile(const char* fname)
{
// warning-{hash}.xml
- return (strncmp(fname, "warning-", 8) == 0 &&
+ return (cmHasLiteralPrefix(fname, "warning-") &&
strcmp(fname+strlen(fname)-4, ".xml") == 0);
}
@@ -816,7 +803,7 @@ cmCTestBuildHandler::LaunchHelper::LaunchHelper(cmCTestBuildHandler* handler):
launchDir += "/Build";
// Clean out any existing launcher fragments.
- cmSystemTools::RemoveADirectory(launchDir.c_str());
+ cmSystemTools::RemoveADirectory(launchDir);
if(this->Handler->UseCTestLaunch)
{
@@ -825,7 +812,7 @@ cmCTestBuildHandler::LaunchHelper::LaunchHelper(cmCTestBuildHandler* handler):
this->WriteLauncherConfig();
std::string launchEnv = "CTEST_LAUNCH_LOGS=";
launchEnv += launchDir;
- cmSystemTools::PutEnv(launchEnv.c_str());
+ cmSystemTools::PutEnv(launchEnv);
}
}
@@ -885,10 +872,10 @@ cmCTestBuildHandler::LaunchHelper
//----------------------------------------------------------------------
int cmCTestBuildHandler::RunMakeCommand(const char* command,
- int* retVal, const char* dir, int timeout, std::ofstream& ofs)
+ int* retVal, const char* dir, int timeout, std::ostream& ofs)
{
// First generate the command and arguments
- std::vector<cmStdString> args = cmSystemTools::ParseArguments(command);
+ std::vector<std::string> args = cmSystemTools::ParseArguments(command);
if(args.size() < 1)
{
@@ -896,20 +883,23 @@ int cmCTestBuildHandler::RunMakeCommand(const char* command,
}
std::vector<const char*> argv;
- for(std::vector<cmStdString>::const_iterator a = args.begin();
+ for(std::vector<std::string>::const_iterator a = args.begin();
a != args.end(); ++a)
{
argv.push_back(a->c_str());
}
argv.push_back(0);
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Run command:");
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Run command:",
+ this->Quiet);
std::vector<const char*>::iterator ait;
for ( ait = argv.begin(); ait != argv.end() && *ait; ++ ait )
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " \"" << *ait << "\"");
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " \"" << *ait <<
+ "\"", this->Quiet);
}
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl,
+ this->Quiet);
// Optionally use make rule launchers to record errors and warnings.
LaunchHelper launchHelper(this);
@@ -929,12 +919,12 @@ int cmCTestBuildHandler::RunMakeCommand(const char* command,
char* data;
int length;
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ cmCTestOptionalLog(this->CTest, HANDLER_PROGRESS_OUTPUT,
" Each symbol represents " << tick_len << " bytes of output."
<< std::endl
<< (this->UseCTestLaunch? "" :
" '!' represents an error and '*' a warning.\n")
- << " " << std::flush);
+ << " " << std::flush, this->Quiet);
// Initialize building structures
this->BuildProcessingQueue.clear();
@@ -977,8 +967,9 @@ int cmCTestBuildHandler::RunMakeCommand(const char* command,
this->ProcessBuffer(0, 0, tick, tick_len, ofs, &this->BuildProcessingQueue);
this->ProcessBuffer(0, 0, tick, tick_len, ofs,
&this->BuildProcessingErrorQueue);
- cmCTestLog(this->CTest, OUTPUT, " Size of output: "
- << ((this->BuildOutputLogSize + 512) / 1024) << "K" << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_PROGRESS_OUTPUT, " Size of output: "
+ << ((this->BuildOutputLogSize + 512) / 1024) << "K" << std::endl,
+ this->Quiet);
// Properly handle output of the build command
cmsysProcess_WaitForExit(cp, 0);
@@ -989,8 +980,8 @@ int cmCTestBuildHandler::RunMakeCommand(const char* command,
if (retVal)
{
*retVal = cmsysProcess_GetExitValue(cp);
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "Command exited with the value: " << *retVal << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Command exited with the value: " << *retVal << std::endl, this->Quiet);
// if a non zero return value
if (*retVal)
{
@@ -1014,13 +1005,14 @@ int cmCTestBuildHandler::RunMakeCommand(const char* command,
if (retVal)
{
*retVal = cmsysProcess_GetExitException(cp);
- cmCTestLog(this->CTest, WARNING, "There was an exception: " << *retVal
- << std::endl);
+ cmCTestOptionalLog(this->CTest, WARNING, "There was an exception: " <<
+ *retVal << std::endl, this->Quiet);
}
}
else if(result == cmsysProcess_State_Expired)
{
- cmCTestLog(this->CTest, WARNING, "There was a timeout" << std::endl);
+ cmCTestOptionalLog(this->CTest, WARNING, "There was a timeout" <<
+ std::endl, this->Quiet);
}
else if(result == cmsysProcess_State_Error)
{
@@ -1049,7 +1041,7 @@ int cmCTestBuildHandler::RunMakeCommand(const char* command,
//----------------------------------------------------------------------
void cmCTestBuildHandler::ProcessBuffer(const char* data, int length,
- size_t& tick, size_t tick_len, std::ofstream& ofs,
+ size_t& tick, size_t tick_len, std::ostream& ofs,
t_BuildProcessingQueueType* queue)
{
const std::string::size_type tick_line_len = 50;
@@ -1091,11 +1083,8 @@ void cmCTestBuildHandler::ProcessBuffer(const char* data, int length,
{
// Create a contiguous array for the line
this->CurrentProcessingLine.clear();
- t_BuildProcessingQueueType::iterator cit;
- for ( cit = queue->begin(); cit != it; ++cit )
- {
- this->CurrentProcessingLine.push_back(*cit);
- }
+ this->CurrentProcessingLine.insert(this->CurrentProcessingLine.end(),
+ queue->begin(), it);
this->CurrentProcessingLine.push_back(0);
const char* line = &*this->CurrentProcessingLine.begin();
@@ -1132,7 +1121,7 @@ void cmCTestBuildHandler::ProcessBuffer(const char* data, int length,
errorwarning.PostContext = "";
// Copy pre-context to report
- std::deque<cmStdString>::iterator pcit;
+ std::deque<std::string>::iterator pcit;
for ( pcit = this->PreContext.begin();
pcit != this->PreContext.end();
++pcit )
@@ -1150,7 +1139,7 @@ void cmCTestBuildHandler::ProcessBuffer(const char* data, int length,
{
// This is not an error or warning.
// So, figure out if this is a post-context line
- if ( this->ErrorsAndWarnings.size() &&
+ if ( !this->ErrorsAndWarnings.empty() &&
this->LastErrorOrWarning != this->ErrorsAndWarnings.end() &&
this->PostContextCount < this->MaxPostContext )
{
@@ -1185,13 +1174,14 @@ void cmCTestBuildHandler::ProcessBuffer(const char* data, int length,
while ( this->BuildOutputLogSize > (tick * tick_len) )
{
tick ++;
- cmCTestLog(this->CTest, HANDLER_OUTPUT, this->LastTickChar);
+ cmCTestOptionalLog(this->CTest, HANDLER_PROGRESS_OUTPUT,
+ this->LastTickChar, this->Quiet);
tickDisplayed = true;
if ( tick % tick_line_len == 0 && tick > 0 )
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " Size: "
+ cmCTestOptionalLog(this->CTest, HANDLER_PROGRESS_OUTPUT, " Size: "
<< ((this->BuildOutputLogSize + 512) / 1024) << "K" << std::endl
- << " ");
+ << " ", this->Quiet);
}
}
if ( tickDisplayed )
@@ -1216,7 +1206,8 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data)
return b_REGULAR_LINE;
}
- cmCTestLog(this->CTest, DEBUG, "Line: [" << data << "]" << std::endl);
+ cmCTestOptionalLog(this->CTest, DEBUG, "Line: [" << data << "]" <<
+ std::endl, this->Quiet);
std::vector<cmsys::RegularExpression>::iterator it;
@@ -1236,9 +1227,9 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data)
if ( it->find(data) )
{
errorLine = 1;
- cmCTestLog(this->CTest, DEBUG, " Error Line: " << data
+ cmCTestOptionalLog(this->CTest, DEBUG, " Error Line: " << data
<< " (matches: " << this->CustomErrorMatches[wrxCnt] << ")"
- << std::endl);
+ << std::endl, this->Quiet);
break;
}
wrxCnt ++;
@@ -1252,9 +1243,9 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data)
if ( it->find(data) )
{
errorLine = 0;
- cmCTestLog(this->CTest, DEBUG, " Not an error Line: " << data
+ cmCTestOptionalLog(this->CTest, DEBUG, " Not an error Line: " << data
<< " (matches: " << this->CustomErrorExceptions[wrxCnt] << ")"
- << std::endl);
+ << std::endl, this->Quiet);
break;
}
wrxCnt ++;
@@ -1271,10 +1262,10 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data)
if ( it->find(data) )
{
warningLine = 1;
- cmCTestLog(this->CTest, DEBUG,
+ cmCTestOptionalLog(this->CTest, DEBUG,
" Warning Line: " << data
<< " (matches: " << this->CustomWarningMatches[wrxCnt] << ")"
- << std::endl);
+ << std::endl, this->Quiet);
break;
}
wrxCnt ++;
@@ -1289,9 +1280,9 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data)
if ( it->find(data) )
{
warningLine = 0;
- cmCTestLog(this->CTest, DEBUG, " Not a warning Line: " << data
+ cmCTestOptionalLog(this->CTest, DEBUG, " Not a warning Line: " << data
<< " (matches: " << this->CustomWarningExceptions[wrxCnt] << ")"
- << std::endl);
+ << std::endl, this->Quiet);
break;
}
wrxCnt ++;
diff --git a/Source/CTest/cmCTestBuildHandler.h b/Source/CTest/cmCTestBuildHandler.h
index 439efd604..2e9b92a70 100644
--- a/Source/CTest/cmCTestBuildHandler.h
+++ b/Source/CTest/cmCTestBuildHandler.h
@@ -19,7 +19,10 @@
#include <cmsys/RegularExpression.hxx>
+#include <deque>
+
class cmMakefile;
+class cmXMLWriter;
/** \class cmCTestBuildHandler
* \brief A class that handles ctest -S invocations
@@ -54,7 +57,7 @@ private:
// and retVal is return value or exception.
int RunMakeCommand(const char* command,
int* retVal, const char* dir, int timeout,
- std::ofstream& ofs);
+ std::ostream& ofs);
enum {
b_REGULAR_LINE,
@@ -84,11 +87,10 @@ private:
};
// generate the XML output
- void GenerateXMLHeader(std::ostream& os);
- void GenerateXMLLaunched(std::ostream& os);
- void GenerateXMLLogScraped(std::ostream& os);
- void GenerateXMLFooter(std::ostream& os, double elapsed_build_time);
- void GenerateXMLLaunchedFragment(std::ostream& os, const char* fname);
+ void GenerateXMLHeader(cmXMLWriter& xml);
+ void GenerateXMLLaunched(cmXMLWriter& xml);
+ void GenerateXMLLogScraped(cmXMLWriter& xml);
+ void GenerateXMLFooter(cmXMLWriter& xml, double elapsed_build_time);
bool IsLaunchedErrorFile(const char* fname);
bool IsLaunchedWarningFile(const char* fname);
@@ -97,10 +99,10 @@ private:
double StartBuildTime;
double EndBuildTime;
- std::vector<cmStdString> CustomErrorMatches;
- std::vector<cmStdString> CustomErrorExceptions;
- std::vector<cmStdString> CustomWarningMatches;
- std::vector<cmStdString> CustomWarningExceptions;
+ std::vector<std::string> CustomErrorMatches;
+ std::vector<std::string> CustomErrorExceptions;
+ std::vector<std::string> CustomWarningMatches;
+ std::vector<std::string> CustomWarningExceptions;
std::vector<std::string> ReallyCustomWarningMatches;
std::vector<std::string> ReallyCustomWarningExceptions;
std::vector<cmCTestCompileErrorWarningRex> ErrorWarningFileLineRegex;
@@ -113,7 +115,7 @@ private:
typedef std::deque<char> t_BuildProcessingQueueType;
void ProcessBuffer(const char* data, int length, size_t& tick,
- size_t tick_len, std::ofstream& ofs, t_BuildProcessingQueueType* queue);
+ size_t tick_len, std::ostream& ofs, t_BuildProcessingQueueType* queue);
int ProcessSingleLine(const char* data);
t_BuildProcessingQueueType BuildProcessingQueue;
@@ -121,8 +123,8 @@ private:
size_t BuildOutputLogSize;
std::vector<char> CurrentProcessingLine;
- cmStdString SimplifySourceDir;
- cmStdString SimplifyBuildDir;
+ std::string SimplifySourceDir;
+ std::string SimplifyBuildDir;
size_t OutputLineCounter;
typedef std::vector<cmCTestBuildErrorWarning> t_ErrorsAndWarningsVector;
t_ErrorsAndWarningsVector ErrorsAndWarnings;
@@ -130,7 +132,7 @@ private:
size_t PostContextCount;
size_t MaxPreContext;
size_t MaxPostContext;
- std::deque<cmStdString> PreContext;
+ std::deque<std::string> PreContext;
int TotalErrors;
int TotalWarnings;
diff --git a/Source/CTest/cmCTestCVS.cxx b/Source/CTest/cmCTestCVS.cxx
index 726950704..0fb3fec57 100644
--- a/Source/CTest/cmCTestCVS.cxx
+++ b/Source/CTest/cmCTestCVS.cxx
@@ -13,9 +13,10 @@
#include "cmCTest.h"
#include "cmSystemTools.h"
-#include "cmXMLSafe.h"
+#include "cmXMLWriter.h"
#include <cmsys/RegularExpression.hxx>
+#include <cmsys/FStream.hxx>
//----------------------------------------------------------------------------
cmCTestCVS::cmCTestCVS(cmCTest* ct, std::ostream& log): cmCTestVC(ct, log)
@@ -98,7 +99,7 @@ bool cmCTestCVS::UpdateImpl()
opts = "-dP";
}
}
- std::vector<cmStdString> args = cmSystemTools::ParseArguments(opts.c_str());
+ std::vector<std::string> args = cmSystemTools::ParseArguments(opts.c_str());
// Specify the start time for nightly testing.
if(this->CTest->GetTestModel() == cmCTest::NIGHTLY)
@@ -111,7 +112,7 @@ bool cmCTestCVS::UpdateImpl()
cvs_update.push_back(this->CommandLineTool.c_str());
cvs_update.push_back("-z3");
cvs_update.push_back("update");
- for(std::vector<cmStdString>::const_iterator ai = args.begin();
+ for(std::vector<std::string>::const_iterator ai = args.begin();
ai != args.end(); ++ai)
{
cvs_update.push_back(ai->c_str());
@@ -231,7 +232,7 @@ std::string cmCTestCVS::ComputeBranchFlag(std::string const& dir)
// Lookup the branch in the tag file, if any.
std::string tagLine;
- std::ifstream tagStream(tagFile.c_str());
+ cmsys::ifstream tagStream(tagFile.c_str());
if(tagStream && cmSystemTools::GetLineFromStream(tagStream, tagLine) &&
tagLine.size() > 1 && tagLine[0] == 'T')
{
@@ -265,13 +266,13 @@ void cmCTestCVS::LoadRevisions(std::string const& file,
}
//----------------------------------------------------------------------------
-void cmCTestCVS::WriteXMLDirectory(std::ostream& xml,
+void cmCTestCVS::WriteXMLDirectory(cmXMLWriter& xml,
std::string const& path,
Directory const& dir)
{
const char* slash = path.empty()? "":"/";
- xml << "\t<Directory>\n"
- << "\t\t<Name>" << cmXMLSafe(path) << "</Name>\n";
+ xml.StartElement("Directory");
+ xml.Element("Name", path);
// Lookup the branch checked out in the working tree.
std::string branchFlag = this->ComputeBranchFlag(path);
@@ -297,17 +298,17 @@ void cmCTestCVS::WriteXMLDirectory(std::ostream& xml,
File f(fi->second, &revisions[0], &revisions[1]);
this->WriteXMLEntry(xml, path, fi->first, full, f);
}
- xml << "\t</Directory>\n";
+ xml.EndElement(); // Directory
}
//----------------------------------------------------------------------------
-bool cmCTestCVS::WriteXMLUpdates(std::ostream& xml)
+bool cmCTestCVS::WriteXMLUpdates(cmXMLWriter& xml)
{
cmCTestLog(this->CTest, HANDLER_OUTPUT,
" Gathering version information (one . per updated file):\n"
" " << std::flush);
- for(std::map<cmStdString, Directory>::const_iterator
+ for(std::map<std::string, Directory>::const_iterator
di = this->Dirs.begin(); di != this->Dirs.end(); ++di)
{
this->WriteXMLDirectory(xml, di->first, di->second);
diff --git a/Source/CTest/cmCTestCVS.h b/Source/CTest/cmCTestCVS.h
index b7fe567d8..f2c0a73bd 100644
--- a/Source/CTest/cmCTestCVS.h
+++ b/Source/CTest/cmCTestCVS.h
@@ -29,16 +29,16 @@ public:
private:
// Implement cmCTestVC internal API.
virtual bool UpdateImpl();
- virtual bool WriteXMLUpdates(std::ostream& xml);
+ virtual bool WriteXMLUpdates(cmXMLWriter& xml);
// Update status for files in each directory.
- class Directory: public std::map<cmStdString, PathStatus> {};
- std::map<cmStdString, Directory> Dirs;
+ class Directory: public std::map<std::string, PathStatus> {};
+ std::map<std::string, Directory> Dirs;
std::string ComputeBranchFlag(std::string const& dir);
void LoadRevisions(std::string const& file, const char* branchFlag,
std::vector<Revision>& revisions);
- void WriteXMLDirectory(std::ostream& xml, std::string const& path,
+ void WriteXMLDirectory(cmXMLWriter& xml, std::string const& path,
Directory const& dir);
// Parsing helper classes.
diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx
index db33cb68e..ba4dab235 100644
--- a/Source/CTest/cmCTestConfigureCommand.cxx
+++ b/Source/CTest/cmCTestConfigureCommand.cxx
@@ -45,7 +45,7 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler()
if ( ctestConfigureCommand && *ctestConfigureCommand )
{
this->CTest->SetCTestConfiguration("ConfigureCommand",
- ctestConfigureCommand);
+ ctestConfigureCommand, this->Quiet);
}
else
{
@@ -66,10 +66,10 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler()
const std::string cmakelists_file = source_dir + "/CMakeLists.txt";
if ( !cmSystemTools::FileExists(cmakelists_file.c_str()) )
{
- cmOStringStream e;
+ std::ostringstream e;
e << "CMakeLists.txt file does not exist ["
<< cmakelists_file << "]";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return 0;
}
@@ -86,7 +86,7 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler()
}
std::string cmakeConfigureCommand = "\"";
- cmakeConfigureCommand += this->CTest->GetCMakeExecutable();
+ cmakeConfigureCommand += cmSystemTools::GetCMakeCommand();
cmakeConfigureCommand += "\"";
std::vector<std::string>::const_iterator it;
@@ -118,6 +118,15 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler()
cmakeConfigureCommand += cmakeGeneratorName;
cmakeConfigureCommand += "\"";
+ const char* cmakeGeneratorPlatform =
+ this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR_PLATFORM");
+ if(cmakeGeneratorPlatform && *cmakeGeneratorPlatform)
+ {
+ cmakeConfigureCommand += " \"-A";
+ cmakeConfigureCommand += cmakeGeneratorPlatform;
+ cmakeConfigureCommand += "\"";
+ }
+
const char* cmakeGeneratorToolset =
this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR_TOOLSET");
if(cmakeGeneratorToolset && *cmakeGeneratorToolset)
@@ -132,7 +141,7 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler()
cmakeConfigureCommand += "\"";
this->CTest->SetCTestConfiguration("ConfigureCommand",
- cmakeConfigureCommand.c_str());
+ cmakeConfigureCommand.c_str(), this->Quiet);
}
else
{
@@ -151,5 +160,6 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler()
"internal CTest error. Cannot instantiate configure handler");
return 0;
}
+ handler->SetQuiet(this->Quiet);
return handler;
}
diff --git a/Source/CTest/cmCTestConfigureCommand.h b/Source/CTest/cmCTestConfigureCommand.h
index b343fc1e9..7941d4e3c 100644
--- a/Source/CTest/cmCTestConfigureCommand.h
+++ b/Source/CTest/cmCTestConfigureCommand.h
@@ -38,35 +38,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "ctest_configure";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Configure the project build tree.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " ctest_configure([BUILD build_dir] [SOURCE source_dir] [APPEND]\n"
- " [OPTIONS options] [RETURN_VALUE res])\n"
- "Configures the given build directory and stores results in "
- "Configure.xml. "
- "If no BUILD is given, the CTEST_BINARY_DIRECTORY variable is used. "
- "If no SOURCE is given, the CTEST_SOURCE_DIRECTORY variable is used. "
- "The OPTIONS argument specifies command line arguments to pass to "
- "the configuration tool. "
- "The RETURN_VALUE option specifies a variable in which to store the "
- "return value of the native build tool."
- "\n"
- CTEST_COMMAND_APPEND_OPTION_DOCS;
- }
+ virtual std::string GetName() const { return "ctest_configure";}
cmTypeMacro(cmCTestConfigureCommand, cmCTestHandlerCommand);
diff --git a/Source/CTest/cmCTestConfigureHandler.cxx b/Source/CTest/cmCTestConfigureHandler.cxx
index 7c4129864..2e8aeb956 100644
--- a/Source/CTest/cmCTestConfigureHandler.cxx
+++ b/Source/CTest/cmCTestConfigureHandler.cxx
@@ -15,7 +15,7 @@
#include "cmCTest.h"
#include "cmGeneratedFileStream.h"
#include "cmake.h"
-#include "cmXMLSafe.h"
+#include "cmXMLWriter.h"
#include <cmsys/Process.h>
@@ -35,10 +35,11 @@ void cmCTestConfigureHandler::Initialize()
//functions and commented...
int cmCTestConfigureHandler::ProcessHandler()
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT, "Configure project" << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ "Configure project" << std::endl, this->Quiet);
std::string cCommand
= this->CTest->GetCTestConfiguration("ConfigureCommand");
- if ( cCommand.size() == 0 )
+ if (cCommand.empty())
{
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Cannot find ConfigureCommand key in the DartConfiguration.tcl"
@@ -48,7 +49,7 @@ int cmCTestConfigureHandler::ProcessHandler()
std::string buildDirectory
= this->CTest->GetCTestConfiguration("BuildDirectory");
- if ( buildDirectory.size() == 0 )
+ if (buildDirectory.empty())
{
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Cannot find BuildDirectory key in the DartConfiguration.tcl"
@@ -75,9 +76,9 @@ int cmCTestConfigureHandler::ProcessHandler()
cmGeneratedFileStream ofs;
this->StartLogFile("Configure", ofs);
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Configure with command: "
- << cCommand.c_str() << std::endl);
- res = this->CTest->RunMakeCommand(cCommand.c_str(), &output,
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Configure with command: " << cCommand << std::endl, this->Quiet);
+ res = this->CTest->RunMakeCommand(cCommand.c_str(), output,
&retVal, buildDirectory.c_str(),
0, ofs);
@@ -88,39 +89,28 @@ int cmCTestConfigureHandler::ProcessHandler()
if ( os )
{
- this->CTest->StartXML(os, this->AppendXML);
- os << "<Configure>\n"
- << "\t<StartDateTime>" << start_time << "</StartDateTime>"
- << std::endl
- << "\t<StartConfigureTime>" << start_time_time
- << "</StartConfigureTime>\n";
-
- if ( res == cmsysProcess_State_Exited && retVal )
- {
- os << retVal;
- }
- os << "<ConfigureCommand>" << cCommand.c_str() << "</ConfigureCommand>"
- << std::endl;
- cmCTestLog(this->CTest, DEBUG, "End" << std::endl);
- os << "<Log>" << cmXMLSafe(output) << "</Log>" << std::endl;
- std::string end_time = this->CTest->CurrentTime();
- os << "\t<ConfigureStatus>" << retVal << "</ConfigureStatus>\n"
- << "\t<EndDateTime>" << end_time << "</EndDateTime>\n"
- << "\t<EndConfigureTime>" <<
- static_cast<unsigned int>(cmSystemTools::GetTime())
- << "</EndConfigureTime>\n"
- << "<ElapsedMinutes>"
- << static_cast<int>(
- (cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0
- << "</ElapsedMinutes>"
- << "</Configure>" << std::endl;
- this->CTest->EndXML(os);
+ cmXMLWriter xml(os);
+ this->CTest->StartXML(xml, this->AppendXML);
+ xml.StartElement("Configure");
+ xml.Element("StartDateTime", start_time);
+ xml.Element("StartConfigureTime", start_time_time);
+ xml.Element("ConfigureCommand", cCommand);
+ cmCTestOptionalLog(this->CTest, DEBUG, "End" << std::endl, this->Quiet);
+ xml.Element("Log", output);
+ xml.Element("ConfigureStatus", retVal);
+ xml.Element("EndDateTime", this->CTest->CurrentTime());
+ xml.Element("EndConfigureTime",
+ static_cast<unsigned int>(cmSystemTools::GetTime()));
+ xml.Element("ElapsedMinutes", static_cast<int>(
+ (cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0);
+ xml.EndElement(); // Configure
+ this->CTest->EndXML(xml);
}
}
else
{
- cmCTestLog(this->CTest, DEBUG, "Configure with command: " << cCommand
- << std::endl);
+ cmCTestOptionalLog(this->CTest, DEBUG,
+ "Configure with command: " << cCommand << std::endl, this->Quiet);
}
if (! res || retVal )
{
diff --git a/Source/CTest/cmCTestCoverageCommand.cxx b/Source/CTest/cmCTestCoverageCommand.cxx
index 72ff720d3..f1f935bab 100644
--- a/Source/CTest/cmCTestCoverageCommand.cxx
+++ b/Source/CTest/cmCTestCoverageCommand.cxx
@@ -24,8 +24,9 @@ cmCTestCoverageCommand::cmCTestCoverageCommand()
cmCTestGenericHandler* cmCTestCoverageCommand::InitializeHandler()
{
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
- "CoverageCommand", "CTEST_COVERAGE_COMMAND");
-
+ "CoverageCommand", "CTEST_COVERAGE_COMMAND", this->Quiet);
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "CoverageExtraFlags", "CTEST_COVERAGE_EXTRA_FLAGS", this->Quiet);
cmCTestCoverageHandler* handler = static_cast<cmCTestCoverageHandler*>(
this->CTest->GetInitializedHandler("coverage"));
if ( !handler )
@@ -40,6 +41,7 @@ cmCTestGenericHandler* cmCTestCoverageCommand::InitializeHandler()
handler->SetLabelFilter(this->Labels);
}
+ handler->SetQuiet(this->Quiet);
return handler;
}
diff --git a/Source/CTest/cmCTestCoverageCommand.h b/Source/CTest/cmCTestCoverageCommand.h
index 2fe762c45..5762e0731 100644
--- a/Source/CTest/cmCTestCoverageCommand.h
+++ b/Source/CTest/cmCTestCoverageCommand.h
@@ -39,33 +39,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "ctest_coverage";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Collect coverage tool results.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " ctest_coverage([BUILD build_dir] [RETURN_VALUE res] [APPEND]\n"
- " [LABELS label1 [label2 [...]]])\n"
- "Perform the coverage of the given build directory and stores results "
- "in Coverage.xml. The second argument is a variable that will hold "
- "value."
- "\n"
- "The LABELS option filters the coverage report to include only "
- "source files labeled with at least one of the labels specified."
- "\n"
- CTEST_COMMAND_APPEND_OPTION_DOCS;
- }
+ virtual std::string GetName() const { return "ctest_coverage";}
cmTypeMacro(cmCTestCoverageCommand, cmCTestHandlerCommand);
@@ -82,7 +56,7 @@ protected:
};
bool LabelsMentioned;
- std::set<cmStdString> Labels;
+ std::set<std::string> Labels;
};
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index 20aded2b5..2c2cd48aa 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -11,20 +11,23 @@
============================================================================*/
#include "cmCTestCoverageHandler.h"
#include "cmParsePHPCoverage.h"
+#include "cmParseCoberturaCoverage.h"
#include "cmParseGTMCoverage.h"
#include "cmParseCacheCoverage.h"
+#include "cmParseJacocoCoverage.h"
+#include "cmParseDelphiCoverage.h"
+#include "cmParseBlanketJSCoverage.h"
#include "cmCTest.h"
#include "cmake.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
#include "cmGeneratedFileStream.h"
-#include "cmXMLSafe.h"
+#include "cmXMLWriter.h"
#include <cmsys/Process.h>
#include <cmsys/RegularExpression.hxx>
#include <cmsys/Glob.hxx>
-#include <cmsys/stl/iterator>
-#include <cmsys/stl/algorithm>
+#include <cmsys/FStream.hxx>
#include <stdlib.h>
#include <math.h>
@@ -82,7 +85,7 @@ public:
}
args.push_back(0); // null terminate
cmsysProcess_SetCommand(this->Process, &*args.begin());
- if(this->WorkingDirectory.size())
+ if(!this->WorkingDirectory.empty())
{
cmsysProcess_SetWorkingDirectory(this->Process,
this->WorkingDirectory.c_str());
@@ -141,6 +144,7 @@ void cmCTestCoverageHandler::Initialize()
this->Superclass::Initialize();
this->CustomCoverageExclude.clear();
this->SourceLabels.clear();
+ this->TargetDirs.clear();
this->LabelIdMap.clear();
this->Labels.clear();
this->LabelFilter.clear();
@@ -154,13 +158,13 @@ void cmCTestCoverageHandler::CleanCoverageLogFiles(std::ostream& log)
logGlob += this->CTest->GetCurrentTag();
logGlob += "/CoverageLog*";
cmsys::Glob gl;
- gl.FindFiles(logGlob.c_str());
+ gl.FindFiles(logGlob);
std::vector<std::string> const& files = gl.GetFiles();
for(std::vector<std::string>::const_iterator fi = files.begin();
fi != files.end(); ++fi)
{
log << "Removing old coverage log: " << *fi << "\n";
- cmSystemTools::RemoveFile(fi->c_str());
+ cmSystemTools::RemoveFile(*fi);
}
}
@@ -170,8 +174,8 @@ bool cmCTestCoverageHandler::StartCoverageLogFile(
{
char covLogFilename[1024];
sprintf(covLogFilename, "CoverageLog-%d", logFileCount);
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Open file: "
- << covLogFilename << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Open file: "
+ << covLogFilename << std::endl, this->Quiet);
if(!this->StartResultingXML(cmCTest::PartCoverage,
covLogFilename, covLogFile))
{
@@ -179,14 +183,6 @@ bool cmCTestCoverageHandler::StartCoverageLogFile(
<< covLogFilename << std::endl);
return false;
}
- std::string local_start_time = this->CTest->CurrentTime();
- this->CTest->StartXML(covLogFile, this->AppendXML);
- covLogFile << "<CoverageLog>" << std::endl
- << "\t<StartDateTime>" << local_start_time << "</StartDateTime>"
- << "\t<StartTime>"
- << static_cast<unsigned int>(cmSystemTools::GetTime())
- << "</StartTime>"
- << std::endl;
return true;
}
@@ -194,21 +190,33 @@ bool cmCTestCoverageHandler::StartCoverageLogFile(
void cmCTestCoverageHandler::EndCoverageLogFile(cmGeneratedFileStream& ostr,
int logFileCount)
{
- std::string local_end_time = this->CTest->CurrentTime();
- ostr << "\t<EndDateTime>" << local_end_time << "</EndDateTime>" << std::endl
- << "\t<EndTime>" <<
- static_cast<unsigned int>(cmSystemTools::GetTime())
- << "</EndTime>" << std::endl
- << "</CoverageLog>" << std::endl;
- this->CTest->EndXML(ostr);
char covLogFilename[1024];
sprintf(covLogFilename, "CoverageLog-%d.xml", logFileCount);
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Close file: "
- << covLogFilename << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Close file: "
+ << covLogFilename << std::endl, this->Quiet);
ostr.Close();
}
//----------------------------------------------------------------------
+void cmCTestCoverageHandler::StartCoverageLogXML(cmXMLWriter& xml)
+{
+ this->CTest->StartXML(xml, this->AppendXML);
+ xml.StartElement("CoverageLog");
+ xml.Element("StartDateTime", this->CTest->CurrentTime());
+ xml.Element("StartTime",
+ static_cast<unsigned int>(cmSystemTools::GetTime()));
+}
+
+//----------------------------------------------------------------------
+void cmCTestCoverageHandler::EndCoverageLogXML(cmXMLWriter& xml)
+{
+ xml.Element("EndDateTime", this->CTest->CurrentTime());
+ xml.Element("EndTime", static_cast<unsigned int>(cmSystemTools::GetTime()));
+ xml.EndElement(); // CoverageLog
+ this->CTest->EndXML(xml);
+}
+
+//----------------------------------------------------------------------
bool cmCTestCoverageHandler::ShouldIDoCoverage(const char* file,
const char* srcDir,
const char* binDir)
@@ -224,8 +232,8 @@ bool cmCTestCoverageHandler::ShouldIDoCoverage(const char* file,
{
if ( sit->find(file) )
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " File " << file
- << " is excluded in CTestCustom.ctest" << std::endl;);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " File " << file
+ << " is excluded in CTestCustom.ctest" << std::endl;, this->Quiet);
return false;
}
}
@@ -233,12 +241,12 @@ bool cmCTestCoverageHandler::ShouldIDoCoverage(const char* file,
std::string fSrcDir = cmSystemTools::CollapseFullPath(srcDir);
std::string fBinDir = cmSystemTools::CollapseFullPath(binDir);
std::string fFile = cmSystemTools::CollapseFullPath(file);
- bool sourceSubDir = cmSystemTools::IsSubDirectory(fFile.c_str(),
- fSrcDir.c_str());
- bool buildSubDir = cmSystemTools::IsSubDirectory(fFile.c_str(),
- fBinDir.c_str());
+ bool sourceSubDir = cmSystemTools::IsSubDirectory(fFile,
+ fSrcDir);
+ bool buildSubDir = cmSystemTools::IsSubDirectory(fFile,
+ fBinDir);
// Always check parent directory of the file.
- std::string fileDir = cmSystemTools::GetFilenamePath(fFile.c_str());
+ std::string fileDir = cmSystemTools::GetFilenamePath(fFile);
std::string checkDir;
// We also need to check the binary/source directory pair.
@@ -264,10 +272,10 @@ bool cmCTestCoverageHandler::ShouldIDoCoverage(const char* file,
std::string ndc
= cmSystemTools::FileExistsInParentDirectories(".NoDartCoverage",
fFile.c_str(), checkDir.c_str());
- if ( ndc.size() )
+ if (!ndc.empty())
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Found: " << ndc.c_str()
- << " so skip coverage of " << file << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Found: " << ndc
+ << " so skip coverage of " << file << std::endl, this->Quiet);
return false;
}
@@ -275,7 +283,7 @@ bool cmCTestCoverageHandler::ShouldIDoCoverage(const char* file,
// Get the relative path to the file an apply it to the opposite directory.
// If it is the same as fileDir, then ignore, otherwise check.
std::string relPath;
- if(checkDir.size() )
+ if(!checkDir.empty())
{
relPath = cmSystemTools::RelativePath(checkDir.c_str(),
fFile.c_str());
@@ -293,7 +301,7 @@ bool cmCTestCoverageHandler::ShouldIDoCoverage(const char* file,
checkDir = fSrcDir;
}
fFile = checkDir + "/" + relPath;
- fFile = cmSystemTools::GetFilenamePath(fFile.c_str());
+ fFile = cmSystemTools::GetFilenamePath(fFile);
if ( fileDir == fFile )
{
@@ -303,10 +311,10 @@ bool cmCTestCoverageHandler::ShouldIDoCoverage(const char* file,
ndc = cmSystemTools::FileExistsInParentDirectories(".NoDartCoverage",
fFile.c_str(), checkDir.c_str());
- if ( ndc.size() )
+ if (!ndc.empty())
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Found: " << ndc.c_str()
- << " so skip coverage of: " << file << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Found: " << ndc
+ << " so skip coverage of: " << file << std::endl, this->Quiet);
return false;
}
// Ok, nothing in source tree, nothing in binary tree
@@ -350,17 +358,19 @@ int cmCTestCoverageHandler::ProcessHandler()
cmSystemTools::ConvertToUnixSlashes(sourceDir);
cmSystemTools::ConvertToUnixSlashes(binaryDir);
- cmCTestLog(this->CTest, HANDLER_OUTPUT, "Performing coverage" << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ "Performing coverage" << std::endl, this->Quiet);
cmCTestCoverageHandlerContainer cont;
cont.Error = error;
cont.SourceDir = sourceDir;
cont.BinaryDir = binaryDir;
cont.OFS = &ofs;
+ cont.Quiet = this->Quiet;
// setup the regex exclude stuff
this->CustomCoverageExcludeRegex.clear();
- std::vector<cmStdString>::iterator rexIt;
+ std::vector<std::string>::iterator rexIt;
for ( rexIt = this->CustomCoverageExclude.begin();
rexIt != this->CustomCoverageExclude.end();
++ rexIt )
@@ -380,6 +390,12 @@ int cmCTestCoverageHandler::ProcessHandler()
{
return error;
}
+ file_count += this->HandleLCovCoverage(&cont);
+ error = cont.Error;
+ if ( file_count < 0 )
+ {
+ return error;
+ }
file_count += this->HandleTracePyCoverage(&cont);
error = cont.Error;
if ( file_count < 0 )
@@ -392,6 +408,13 @@ int cmCTestCoverageHandler::ProcessHandler()
{
return error;
}
+ file_count += this->HandleCoberturaCoverage(&cont);
+ error = cont.Error;
+ if ( file_count < 0 )
+ {
+ return error;
+ }
+
file_count += this->HandleMumpsCoverage(&cont);
error = cont.Error;
if ( file_count < 0 )
@@ -399,17 +422,39 @@ int cmCTestCoverageHandler::ProcessHandler()
return error;
}
+ file_count += this->HandleJacocoCoverage(&cont);
+ error = cont.Error;
+ if ( file_count < 0 )
+ {
+ return error;
+ }
+
+ file_count += this->HandleBlanketJSCoverage(&cont);
+ error = cont.Error;
+ if ( file_count < 0 )
+ {
+ return error;
+ }
+
+ file_count += this->HandleDelphiCoverage(&cont);
+ error = cont.Error;
+ if ( file_count < 0 )
+ {
+ return error;
+ }
std::set<std::string> uncovered = this->FindUncoveredFiles(&cont);
- if ( file_count == 0 )
+ if (file_count == 0 && this->ExtraCoverageGlobs.empty())
{
- cmCTestLog(this->CTest, WARNING,
+ cmCTestOptionalLog(this->CTest, WARNING,
" Cannot find any coverage files. Ignoring Coverage request."
- << std::endl);
+ << std::endl, this->Quiet);
return error;
}
cmGeneratedFileStream covSumFile;
cmGeneratedFileStream covLogFile;
+ cmXMLWriter covSumXML(covSumFile);
+ cmXMLWriter covLogXML(covLogFile);
if(!this->StartResultingXML(cmCTest::PartCoverage, "Coverage", covSumFile))
{
@@ -417,30 +462,32 @@ int cmCTestCoverageHandler::ProcessHandler()
"Cannot open coverage summary file." << std::endl);
return -1;
}
+ covSumFile.setf(std::ios::fixed, std::ios::floatfield);
+ covSumFile.precision(2);
- this->CTest->StartXML(covSumFile, this->AppendXML);
+ this->CTest->StartXML(covSumXML, this->AppendXML);
// Produce output xml files
- covSumFile << "<Coverage>" << std::endl
- << "\t<StartDateTime>" << coverage_start_time << "</StartDateTime>"
- << std::endl
- << "\t<StartTime>" << coverage_start_time_time << "</StartTime>"
- << std::endl;
+ covSumXML.StartElement("Coverage");
+ covSumXML.Element("StartDateTime", coverage_start_time);
+ covSumXML.Element("StartTime", coverage_start_time_time);
int logFileCount = 0;
if ( !this->StartCoverageLogFile(covLogFile, logFileCount) )
{
return -1;
}
+ this->StartCoverageLogXML(covLogXML);
cmCTestCoverageHandlerContainer::TotalCoverageMap::iterator fileIterator;
int cnt = 0;
long total_tested = 0;
long total_untested = 0;
//std::string fullSourceDir = sourceDir + "/";
//std::string fullBinaryDir = binaryDir + "/";
- cmCTestLog(this->CTest, HANDLER_OUTPUT, std::endl);
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
- " Accumulating results (each . represents one file):" << std::endl);
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " ");
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, std::endl, this->Quiet);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ " Accumulating results (each . represents one file):" << std::endl,
+ this->Quiet);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " ", this->Quiet);
std::vector<std::string> errorsWhileAccumulating;
@@ -449,14 +496,16 @@ int cmCTestCoverageHandler::ProcessHandler()
fileIterator != cont.TotalCoverage.end();
++fileIterator )
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT, "." << std::flush);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "." << std::flush,
+ this->Quiet);
file_count ++;
if ( file_count % 50 == 0 )
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " processed: " << file_count
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " processed: "
+ << file_count
<< " out of "
- << cont.TotalCoverage.size() << std::endl);
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " ");
+ << cont.TotalCoverage.size() << std::endl, this->Quiet);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " ", this->Quiet);
}
const std::string fullFileName = fileIterator->first;
@@ -465,48 +514,51 @@ int cmCTestCoverageHandler::ProcessHandler()
sourceDir.c_str(), binaryDir.c_str());
if ( !shouldIDoCoverage )
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
".NoDartCoverage found, so skip coverage check for: "
- << fullFileName.c_str()
- << std::endl);
+ << fullFileName
+ << std::endl, this->Quiet);
continue;
}
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "Process file: " << fullFileName << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Process file: " << fullFileName << std::endl, this->Quiet);
if ( !cmSystemTools::FileExists(fullFileName.c_str()) )
{
cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot find file: "
- << fullFileName.c_str() << std::endl);
+ << fullFileName << std::endl);
continue;
}
if ( ++cnt % 100 == 0 )
{
+ this->EndCoverageLogXML(covLogXML);
this->EndCoverageLogFile(covLogFile, logFileCount);
logFileCount ++;
if ( !this->StartCoverageLogFile(covLogFile, logFileCount) )
{
return -1;
}
+ this->StartCoverageLogXML(covLogXML);
}
const std::string fileName
- = cmSystemTools::GetFilenameName(fullFileName.c_str());
+ = cmSystemTools::GetFilenameName(fullFileName);
std::string shortFileName =
this->CTest->GetShortPathToFile(fullFileName.c_str());
const cmCTestCoverageHandlerContainer::SingleFileCoverageVector& fcov
= fileIterator->second;
- covLogFile << "\t<File Name=\"" << cmXMLSafe(fileName)
- << "\" FullPath=\"" << cmXMLSafe(shortFileName) << "\">\n"
- << "\t\t<Report>" << std::endl;
+ covLogXML.StartElement("File");
+ covLogXML.Attribute("Name", fileName);
+ covLogXML.Attribute("FullPath", shortFileName);
+ covLogXML.StartElement("Report");
- std::ifstream ifs(fullFileName.c_str());
+ cmsys::ifstream ifs(fullFileName.c_str());
if ( !ifs)
{
- cmOStringStream ostr;
- ostr << "Cannot open source file: " << fullFileName.c_str();
+ std::ostringstream ostr;
+ ostr << "Cannot open source file: " << fullFileName;
errorsWhileAccumulating.push_back(ostr.str());
error ++;
continue;
@@ -517,23 +569,26 @@ int cmCTestCoverageHandler::ProcessHandler()
cmCTestCoverageHandlerContainer::SingleFileCoverageVector::size_type cc;
std::string line;
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "Actually performing coverage for: " << fullFileName << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Actually performing coverage for: " << fullFileName << std::endl,
+ this->Quiet);
for ( cc= 0; cc < fcov.size(); cc ++ )
{
if ( !cmSystemTools::GetLineFromStream(ifs, line) &&
cc != fcov.size() -1 )
{
- cmOStringStream ostr;
- ostr << "Problem reading source file: " << fullFileName.c_str()
+ std::ostringstream ostr;
+ ostr << "Problem reading source file: " << fullFileName
<< " line:" << cc << " out total: " << fcov.size()-1;
errorsWhileAccumulating.push_back(ostr.str());
error ++;
break;
}
- covLogFile << "\t\t<Line Number=\"" << cc << "\" Count=\"" << fcov[cc]
- << "\">"
- << cmXMLSafe(line) << "</Line>" << std::endl;
+ covLogXML.StartElement("Line");
+ covLogXML.Attribute("Number", cc);
+ covLogXML.Attribute("Count", fcov[cc]);
+ covLogXML.Content(line);
+ covLogXML.EndElement(); // Line
if ( fcov[cc] == 0 )
{
untested ++;
@@ -545,8 +600,8 @@ int cmCTestCoverageHandler::ProcessHandler()
}
if ( cmSystemTools::GetLineFromStream(ifs, line) )
{
- cmOStringStream ostr;
- ostr << "Looks like there are more lines in the file: " << line;
+ std::ostringstream ostr;
+ ostr << "Looks like there are more lines in the file: " << fullFileName;
errorsWhileAccumulating.push_back(ostr.str());
}
float cper = 0;
@@ -560,24 +615,19 @@ int cmCTestCoverageHandler::ProcessHandler()
}
total_tested += tested;
total_untested += untested;
- covLogFile << "\t\t</Report>" << std::endl
- << "\t</File>" << std::endl;
- covSumFile << "\t<File Name=\"" << cmXMLSafe(fileName)
- << "\" FullPath=\"" << cmXMLSafe(
- this->CTest->GetShortPathToFile(fullFileName.c_str()))
- << "\" Covered=\"" << (tested+untested > 0 ? "true":"false") << "\">\n"
- << "\t\t<LOCTested>" << tested << "</LOCTested>\n"
- << "\t\t<LOCUnTested>" << untested << "</LOCUnTested>\n"
- << "\t\t<PercentCoverage>";
- covSumFile.setf(std::ios::fixed, std::ios::floatfield);
- covSumFile.precision(2);
- covSumFile << (cper) << "</PercentCoverage>\n"
- << "\t\t<CoverageMetric>";
- covSumFile.setf(std::ios::fixed, std::ios::floatfield);
- covSumFile.precision(2);
- covSumFile << (cmet) << "</CoverageMetric>\n";
- this->WriteXMLLabels(covSumFile, shortFileName);
- covSumFile << "\t</File>" << std::endl;
+ covLogXML.EndElement(); // Report
+ covLogXML.EndElement(); // File
+ covSumXML.StartElement("File");
+ covSumXML.Attribute("Name", fileName);
+ covSumXML.Attribute("FullPath",
+ this->CTest->GetShortPathToFile(fullFileName.c_str()));
+ covSumXML.Attribute("Covered", tested + untested > 0 ? "true" : "false");
+ covSumXML.Element("LOCTested", tested);
+ covSumXML.Element("LOCUnTested", untested);
+ covSumXML.Element("PercentCoverage", cper);
+ covSumXML.Element("CoverageMetric", cmet);
+ this->WriteXMLLabels(covSumXML, shortFileName);
+ covSumXML.EndElement(); // File
}
//Handle all the files in the extra coverage globs that have no cov data
@@ -587,46 +637,53 @@ int cmCTestCoverageHandler::ProcessHandler()
std::string fileName = cmSystemTools::GetFilenameName(*i);
std::string fullPath = cont.SourceDir + "/" + *i;
- covLogFile << "\t<File Name=\"" << cmXMLSafe(fileName)
- << "\" FullPath=\"" << cmXMLSafe(*i) << "\">\n"
- << "\t\t<Report>" << std::endl;
+ covLogXML.StartElement("File");
+ covLogXML.Attribute("Name", fileName);
+ covLogXML.Attribute("FullPath", *i);
+ covLogXML.StartElement("Report");
- std::ifstream ifs(fullPath.c_str());
+ cmsys::ifstream ifs(fullPath.c_str());
if (!ifs)
{
- cmOStringStream ostr;
- ostr << "Cannot open source file: " << fullPath.c_str();
+ std::ostringstream ostr;
+ ostr << "Cannot open source file: " << fullPath;
errorsWhileAccumulating.push_back(ostr.str());
error ++;
continue;
}
int untested = 0;
std::string line;
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "Actually performing coverage for: " << i->c_str() << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Actually performing coverage for: " << *i << std::endl, this->Quiet);
while (cmSystemTools::GetLineFromStream(ifs, line))
{
- covLogFile << "\t\t<Line Number=\"" << untested << "\" Count=\"0\">"
- << cmXMLSafe(line) << "</Line>" << std::endl;
+ covLogXML.StartElement("Line");
+ covLogXML.Attribute("Number", untested);
+ covLogXML.Attribute("Count", 0);
+ covLogXML.Content(line);
+ covLogXML.EndElement(); // Line
untested ++;
}
- covLogFile << "\t\t</Report>\n\t</File>" << std::endl;
+ covLogXML.EndElement(); // Report
+ covLogXML.EndElement(); // File
total_untested += untested;
- covSumFile << "\t<File Name=\"" << cmXMLSafe(fileName)
- << "\" FullPath=\"" << cmXMLSafe(i->c_str())
- << "\" Covered=\"true\">\n"
- << "\t\t<LOCTested>0</LOCTested>\n"
- << "\t\t<LOCUnTested>" << untested << "</LOCUnTested>\n"
- << "\t\t<PercentCoverage>0</PercentCoverage>\n"
- << "\t\t<CoverageMetric>0</CoverageMetric>\n";
- this->WriteXMLLabels(covSumFile, *i);
- covSumFile << "\t</File>" << std::endl;
- }
-
+ covSumXML.StartElement("File");
+ covSumXML.Attribute("Name", fileName);
+ covSumXML.Attribute("FullPath", *i);
+ covSumXML.Attribute("Covered", "true");
+ covSumXML.Element("LOCTested", 0);
+ covSumXML.Element("LOCUnTested", untested);
+ covSumXML.Element("PercentCoverage", 0);
+ covSumXML.Element("CoverageMetric", 0);
+ this->WriteXMLLabels(covSumXML, *i);
+ covSumXML.EndElement(); // File
+ }
+
+ this->EndCoverageLogXML(covLogXML);
this->EndCoverageLogFile(covLogFile, logFileCount);
- if ( errorsWhileAccumulating.size() > 0 )
+ if (!errorsWhileAccumulating.empty())
{
cmCTestLog(this->CTest, ERROR_MESSAGE, std::endl);
cmCTestLog(this->CTest, ERROR_MESSAGE,
@@ -637,7 +694,7 @@ int cmCTestCoverageHandler::ProcessHandler()
++ erIt )
{
cmCTestLog(this->CTest, ERROR_MESSAGE,
- " " << erIt->c_str() << std::endl);
+ " " << *erIt << std::endl);
}
}
@@ -651,22 +708,17 @@ int cmCTestCoverageHandler::ProcessHandler()
std::string end_time = this->CTest->CurrentTime();
- covSumFile << "\t<LOCTested>" << total_tested << "</LOCTested>\n"
- << "\t<LOCUntested>" << total_untested << "</LOCUntested>\n"
- << "\t<LOC>" << total_lines << "</LOC>\n"
- << "\t<PercentCoverage>";
- covSumFile.setf(std::ios::fixed, std::ios::floatfield);
- covSumFile.precision(2);
- covSumFile << (percent_coverage)<< "</PercentCoverage>\n"
- << "\t<EndDateTime>" << end_time << "</EndDateTime>\n"
- << "\t<EndTime>" <<
- static_cast<unsigned int>(cmSystemTools::GetTime())
- << "</EndTime>\n";
- covSumFile << "<ElapsedMinutes>" <<
- static_cast<int>((cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0
- << "</ElapsedMinutes>"
- << "</Coverage>" << std::endl;
- this->CTest->EndXML(covSumFile);
+ covSumXML.Element("LOCTested", total_tested);
+ covSumXML.Element("LOCUntested", total_untested);
+ covSumXML.Element("LOC", total_lines);
+ covSumXML.Element("PercentCoverage", percent_coverage);
+ covSumXML.Element("EndDateTime", end_time);
+ covSumXML.Element("EndTime",
+ static_cast<unsigned int>(cmSystemTools::GetTime()));
+ covSumXML.Element("ElapsedMinutes",
+ static_cast<int>((cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0);
+ covSumXML.EndElement(); // Coverage
+ this->CTest->EndXML(covSumXML);
cmCTestLog(this->CTest, HANDLER_OUTPUT, "" << std::endl
<< "\tCovered LOC: "
@@ -697,25 +749,25 @@ int cmCTestCoverageHandler::ProcessHandler()
//----------------------------------------------------------------------
void cmCTestCoverageHandler::PopulateCustomVectors(cmMakefile *mf)
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- " Add coverage exclude regular expressions." << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " Add coverage exclude regular expressions." << std::endl, this->Quiet);
this->CTest->PopulateCustomVector(mf, "CTEST_CUSTOM_COVERAGE_EXCLUDE",
this->CustomCoverageExclude);
this->CTest->PopulateCustomVector(mf, "CTEST_EXTRA_COVERAGE_GLOB",
this->ExtraCoverageGlobs);
- std::vector<cmStdString>::iterator it;
+ std::vector<std::string>::iterator it;
for ( it = this->CustomCoverageExclude.begin();
it != this->CustomCoverageExclude.end();
++ it )
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Add coverage exclude: "
- << it->c_str() << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " Add coverage exclude: " << *it << std::endl, this->Quiet);
}
for ( it = this->ExtraCoverageGlobs.begin();
it != this->ExtraCoverageGlobs.end(); ++it)
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Add coverage glob: "
- << it->c_str() << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " Add coverage glob: " << *it << std::endl, this->Quiet);
}
}
@@ -734,8 +786,8 @@ void cmCTestCoverageHandler::PopulateCustomVectors(cmMakefile *mf)
//----------------------------------------------------------------------
bool IsFileInDir(const std::string &infile, const std::string &indir)
{
- std::string file = cmSystemTools::CollapseFullPath(infile.c_str());
- std::string dir = cmSystemTools::CollapseFullPath(indir.c_str());
+ std::string file = cmSystemTools::CollapseFullPath(infile);
+ std::string dir = cmSystemTools::CollapseFullPath(indir);
if (
file.size() > dir.size() &&
@@ -755,12 +807,53 @@ int cmCTestCoverageHandler::HandlePHPCoverage(
{
cmParsePHPCoverage cov(*cont, this->CTest);
std::string coverageDir = this->CTest->GetBinaryDir() + "/xdebugCoverage";
- if(cmSystemTools::FileIsDirectory(coverageDir.c_str()))
+ if(cmSystemTools::FileIsDirectory(coverageDir))
{
cov.ReadPHPCoverageDirectory(coverageDir.c_str());
}
return static_cast<int>(cont->TotalCoverage.size());
}
+
+//----------------------------------------------------------------------
+int cmCTestCoverageHandler::HandleCoberturaCoverage(
+ cmCTestCoverageHandlerContainer* cont)
+{
+ cmParseCoberturaCoverage cov(*cont, this->CTest);
+
+ // Assume the coverage.xml is in the binary directory
+ // check for the COBERTURADIR environment variable,
+ // if it doesn't exist or is empty, assume the
+ // binary directory is used.
+ std::string coverageXMLFile;
+ const char* covDir = cmSystemTools::GetEnv("COBERTURADIR");
+ if(covDir && strlen(covDir) != 0)
+ {
+ coverageXMLFile = std::string(covDir);
+ }
+ else
+ {
+ coverageXMLFile = this->CTest->GetBinaryDir();
+ }
+ // build the find file string with the directory from above
+ coverageXMLFile += "/coverage.xml";
+
+ if(cmSystemTools::FileExists(coverageXMLFile.c_str()))
+ {
+ // If file exists, parse it
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Parsing Cobertura XML file: " << coverageXMLFile
+ << std::endl, this->Quiet);
+ cov.ReadCoverageXML(coverageXMLFile.c_str());
+ }
+ else
+ {
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " Cannot find Cobertura XML file: " << coverageXMLFile
+ << std::endl, this->Quiet);
+ }
+ return static_cast<int>(cont->TotalCoverage.size());
+}
+
//----------------------------------------------------------------------
int cmCTestCoverageHandler::HandleMumpsCoverage(
cmCTestCoverageHandlerContainer* cont)
@@ -771,33 +864,33 @@ int cmCTestCoverageHandler::HandleMumpsCoverage(
"/gtm_coverage.mcov";
if(cmSystemTools::FileExists(coverageFile.c_str()))
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Parsing Cache Coverage: " << coverageFile
- << std::endl);
+ << std::endl, this->Quiet);
cov.ReadCoverageFile(coverageFile.c_str());
return static_cast<int>(cont->TotalCoverage.size());
}
else
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- " Cannot find foobar GTM coverage file: " << coverageFile
- << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " Cannot find GTM coverage file: " << coverageFile
+ << std::endl, this->Quiet);
}
cmParseCacheCoverage ccov(*cont, this->CTest);
coverageFile = this->CTest->GetBinaryDir() +
"/cache_coverage.cmcov";
if(cmSystemTools::FileExists(coverageFile.c_str()))
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Parsing Cache Coverage: " << coverageFile
- << std::endl);
+ << std::endl, this->Quiet);
ccov.ReadCoverageFile(coverageFile.c_str());
}
else
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
" Cannot find Cache coverage file: " << coverageFile
- << std::endl);
+ << std::endl, this->Quiet);
}
return static_cast<int>(cont->TotalCoverage.size());
}
@@ -819,7 +912,7 @@ struct cmCTestCoverageHandlerLocale
{
if(!lc_all.empty())
{
- cmSystemTools::PutEnv(("LC_ALL=" + lc_all).c_str());
+ cmSystemTools::PutEnv("LC_ALL=" + lc_all);
}
else
{
@@ -830,14 +923,139 @@ struct cmCTestCoverageHandlerLocale
};
//----------------------------------------------------------------------
+int cmCTestCoverageHandler::HandleJacocoCoverage(
+ cmCTestCoverageHandlerContainer* cont)
+{
+ cmParseJacocoCoverage cov =
+ cmParseJacocoCoverage(*cont, this->CTest);
+
+ // Search in the source directory.
+ cmsys::Glob g1;
+ std::vector<std::string> files;
+ g1.SetRecurse(true);
+
+ std::string SourceDir
+ = this->CTest->GetCTestConfiguration("SourceDirectory");
+ std::string coverageFile = SourceDir+ "/*jacoco.xml";
+
+ g1.FindFiles(coverageFile);
+ files = g1.GetFiles();
+
+ // ...and in the binary directory.
+ cmsys::Glob g2;
+ std::vector<std::string> binFiles;
+ g2.SetRecurse(true);
+ std::string binaryDir
+ = this->CTest->GetCTestConfiguration("BuildDirectory");
+ std::string binCoverageFile = binaryDir+ "/*jacoco.xml";
+ g2.FindFiles(binCoverageFile);
+ binFiles = g2.GetFiles();
+ if (!binFiles.empty())
+ {
+ files.insert(files.end(), binFiles.begin(), binFiles.end());
+ }
+
+ if (!files.empty())
+ {
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Found Jacoco Files, Performing Coverage" << std::endl, this->Quiet);
+ cov.LoadCoverageData(files);
+ }
+ else
+ {
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " Cannot find Jacoco coverage files: " << coverageFile
+ << std::endl, this->Quiet);
+ }
+ return static_cast<int>(cont->TotalCoverage.size());
+}
+
+//----------------------------------------------------------------------
+int cmCTestCoverageHandler::HandleDelphiCoverage(
+ cmCTestCoverageHandlerContainer* cont)
+{
+ cmParseDelphiCoverage cov =
+ cmParseDelphiCoverage(*cont, this->CTest);
+ cmsys::Glob g;
+ std::vector<std::string> files;
+ g.SetRecurse(true);
+
+
+ std::string BinDir
+ = this->CTest->GetBinaryDir();
+ std::string coverageFile = BinDir+ "/*.html";
+
+
+ g.FindFiles(coverageFile);
+ files=g.GetFiles();
+ if (!files.empty())
+ {
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Found Delphi HTML Files, Performing Coverage" << std::endl,
+ this->Quiet);
+ cov.LoadCoverageData(files);
+ }
+ else
+ {
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " Cannot find Delphi coverage files: " << coverageFile
+ << std::endl, this->Quiet);
+ }
+ return static_cast<int>(cont->TotalCoverage.size());
+}
+
+//----------------------------------------------------------------------
+int cmCTestCoverageHandler::HandleBlanketJSCoverage(
+ cmCTestCoverageHandlerContainer* cont)
+ {
+ cmParseBlanketJSCoverage cov =
+ cmParseBlanketJSCoverage(*cont, this->CTest);
+ std::string SourceDir
+ = this->CTest->GetCTestConfiguration("SourceDirectory");
+
+ //Look for something other than output.json, still JSON extension.
+ std::string coverageFile = SourceDir+ "/*.json";
+ cmsys::Glob g;
+ std::vector<std::string> files;
+ g.FindFiles(coverageFile);
+ files=g.GetFiles();
+ if (!files.empty())
+ {
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Found BlanketJS output JSON, Performing Coverage" << std::endl,
+ this->Quiet);
+ cov.LoadCoverageData(files);
+ }
+ else
+ {
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " Cannot find BlanketJS coverage files: " << coverageFile
+ << std::endl, this->Quiet);
+ }
+ return static_cast<int>(cont->TotalCoverage.size());
+ }
+//----------------------------------------------------------------------
int cmCTestCoverageHandler::HandleGCovCoverage(
cmCTestCoverageHandlerContainer* cont)
{
std::string gcovCommand
= this->CTest->GetCTestConfiguration("CoverageCommand");
+ if (gcovCommand.empty())
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Could not find gcov." << std::endl);
+ return 0;
+ }
std::string gcovExtraFlags
= this->CTest->GetCTestConfiguration("CoverageExtraFlags");
+ // Immediately skip to next coverage option since codecov is only for Intel
+ // compiler
+ if ( gcovCommand == "codecov" )
+ {
+ return 0;
+ }
+
// Style 1
std::string st1gcovOutputRex1
= "[0-9]+\\.[0-9]+% of [0-9]+ (source |)lines executed in file (.*)$";
@@ -866,11 +1084,11 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
this->FindGCovFiles(files);
std::vector<std::string>::iterator it;
- if ( files.size() == 0 )
+ if (files.empty())
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
" Cannot find any GCov coverage files."
- << std::endl);
+ << std::endl, this->Quiet);
// No coverage files is a valid thing, so the exit code is 0
return 0;
}
@@ -879,16 +1097,17 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
std::string tempDir = testingDir + "/CoverageInfo";
std::string currentDirectory = cmSystemTools::GetCurrentWorkingDirectory();
cmSystemTools::MakeDirectory(tempDir.c_str());
- cmSystemTools::ChangeDirectory(tempDir.c_str());
+ cmSystemTools::ChangeDirectory(tempDir);
int gcovStyle = 0;
std::set<std::string> missingFiles;
std::string actualSourceFile = "";
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
- " Processing coverage (each . represents one file):" << std::endl);
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " ");
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ " Processing coverage (each . represents one file):" << std::endl,
+ this->Quiet);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " ", this->Quiet);
int file_count = 0;
// make sure output from gcov is in English!
@@ -901,33 +1120,34 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
//
for ( it = files.begin(); it != files.end(); ++ it )
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT, "." << std::flush);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "." << std::flush,
+ this->Quiet);
// Call gcov to get coverage data for this *.gcda file:
//
- std::string fileDir = cmSystemTools::GetFilenamePath(it->c_str());
+ std::string fileDir = cmSystemTools::GetFilenamePath(*it);
std::string command = "\"" + gcovCommand + "\" " +
gcovExtraFlags + " " +
"-o \"" + fileDir + "\" " +
"\"" + *it + "\"";
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, command.c_str()
- << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, command.c_str()
+ << std::endl, this->Quiet);
std::string output = "";
std::string errors = "";
int retVal = 0;
- *cont->OFS << "* Run coverage for: " << fileDir.c_str() << std::endl;
- *cont->OFS << " Command: " << command.c_str() << std::endl;
+ *cont->OFS << "* Run coverage for: " << fileDir << std::endl;
+ *cont->OFS << " Command: " << command << std::endl;
int res = this->CTest->RunCommand(command.c_str(), &output, &errors,
&retVal, tempDir.c_str(), 0 /*this->TimeOut*/);
- *cont->OFS << " Output: " << output.c_str() << std::endl;
- *cont->OFS << " Errors: " << errors.c_str() << std::endl;
+ *cont->OFS << " Output: " << output << std::endl;
+ *cont->OFS << " Errors: " << errors << std::endl;
if ( ! res )
{
cmCTestLog(this->CTest, ERROR_MESSAGE,
- "Problem running coverage on file: " << it->c_str() << std::endl);
+ "Problem running coverage on file: " << *it << std::endl);
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Command produced error: " << errors << std::endl);
cont->Error ++;
@@ -936,19 +1156,19 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
if ( retVal != 0 )
{
cmCTestLog(this->CTest, ERROR_MESSAGE, "Coverage command returned: "
- << retVal << " while processing: " << it->c_str() << std::endl);
+ << retVal << " while processing: " << *it << std::endl);
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Command produced error: " << cont->Error << std::endl);
}
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"--------------------------------------------------------------"
<< std::endl
<< output << std::endl
<< "--------------------------------------------------------------"
- << std::endl);
+ << std::endl, this->Quiet);
- std::vector<cmStdString> lines;
- std::vector<cmStdString>::iterator line;
+ std::vector<std::string> lines;
+ std::vector<std::string>::iterator line;
cmSystemTools::Split(output.c_str(), lines);
@@ -957,10 +1177,10 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
std::string sourceFile;
std::string gcovFile;
- cmCTestLog(this->CTest, DEBUG, "Line: [" << line->c_str() << "]"
- << std::endl);
+ cmCTestOptionalLog(this->CTest, DEBUG, "Line: [" << *line << "]"
+ << std::endl, this->Quiet);
- if ( line->size() == 0 )
+ if (line->empty())
{
// Ignore empty line; probably style 2
}
@@ -1058,8 +1278,8 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
break;
}
- cmCTestLog(this->CTest, WARNING, "Warning: " << st2re4.match(1)
- << " had unexpected EOF" << std::endl);
+ cmCTestOptionalLog(this->CTest, WARNING, "Warning: " << st2re4.match(1)
+ << " had unexpected EOF" << std::endl, this->Quiet);
}
else if ( st2re5.find(line->c_str() ) )
{
@@ -1075,8 +1295,8 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
break;
}
- cmCTestLog(this->CTest, WARNING, "Warning: Cannot open file: "
- << st2re5.match(1) << std::endl);
+ cmCTestOptionalLog(this->CTest, WARNING, "Warning: Cannot open file: "
+ << st2re5.match(1) << std::endl, this->Quiet);
}
else if ( st2re6.find(line->c_str() ) )
{
@@ -1092,8 +1312,9 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
break;
}
- cmCTestLog(this->CTest, WARNING, "Warning: File: " << st2re6.match(1)
- << " is newer than " << st2re6.match(2) << std::endl);
+ cmCTestOptionalLog(this->CTest, WARNING, "Warning: File: "
+ << st2re6.match(1)
+ << " is newer than " << st2re6.match(2) << std::endl, this->Quiet);
}
else
{
@@ -1103,7 +1324,7 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
!cmSystemTools::StringStartsWith(line->c_str(), "Removing "))
{
cmCTestLog(this->CTest, ERROR_MESSAGE,
- "Unknown gcov output line: [" << line->c_str() << "]"
+ "Unknown gcov output line: [" << *line << "]"
<< std::endl);
cont->Error ++;
//abort();
@@ -1120,10 +1341,10 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
cmCTestCoverageHandlerContainer::SingleFileCoverageVector& vec
= cont->TotalCoverage[actualSourceFile];
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " in gcovFile: "
- << gcovFile << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " in gcovFile: " << gcovFile << std::endl, this->Quiet);
- std::ifstream ifile(gcovFile.c_str());
+ cmsys::ifstream ifile(gcovFile.c_str());
if ( ! ifile )
{
cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot open file: "
@@ -1140,7 +1361,7 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
//TODO: Handle gcov 3.0 non-coverage lines
// Skip empty lines
- if ( !nl.size() )
+ if (nl.empty())
{
continue;
}
@@ -1195,44 +1416,44 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
//
if ( IsFileInDir(sourceFile, cont->SourceDir) )
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " produced s: "
- << sourceFile.c_str() << std::endl);
- *cont->OFS << " produced in source dir: " << sourceFile.c_str()
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " produced s: " << sourceFile << std::endl, this->Quiet);
+ *cont->OFS << " produced in source dir: " << sourceFile
<< std::endl;
actualSourceFile
- = cmSystemTools::CollapseFullPath(sourceFile.c_str());
+ = cmSystemTools::CollapseFullPath(sourceFile);
}
else if ( IsFileInDir(sourceFile, cont->BinaryDir) )
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " produced b: "
- << sourceFile.c_str() << std::endl);
- *cont->OFS << " produced in binary dir: " << sourceFile.c_str()
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " produced b: " << sourceFile << std::endl, this->Quiet);
+ *cont->OFS << " produced in binary dir: " << sourceFile
<< std::endl;
actualSourceFile
- = cmSystemTools::CollapseFullPath(sourceFile.c_str());
+ = cmSystemTools::CollapseFullPath(sourceFile);
}
if ( actualSourceFile.empty() )
{
if ( missingFiles.find(sourceFile) == missingFiles.end() )
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "Something went wrong" << std::endl);
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Something went wrong" << std::endl, this->Quiet);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Cannot find file: ["
- << sourceFile.c_str() << "]" << std::endl);
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ << sourceFile << "]" << std::endl, this->Quiet);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
" in source dir: ["
- << cont->SourceDir.c_str() << "]"
- << std::endl);
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ << cont->SourceDir << "]"
+ << std::endl, this->Quiet);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
" or binary dir: ["
<< cont->BinaryDir.size() << "]"
- << std::endl);
+ << std::endl, this->Quiet);
*cont->OFS << " Something went wrong. Cannot find file: "
- << sourceFile.c_str()
- << " in source dir: " << cont->SourceDir.c_str()
- << " or binary dir: " << cont->BinaryDir.c_str() << std::endl;
+ << sourceFile
+ << " in source dir: " << cont->SourceDir
+ << " or binary dir: " << cont->BinaryDir << std::endl;
missingFiles.insert(sourceFile);
}
@@ -1244,13 +1465,286 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
if ( file_count % 50 == 0 )
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " processed: " << file_count
- << " out of " << files.size() << std::endl);
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " ");
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " processed: "
+ << file_count
+ << " out of " << files.size() << std::endl, this->Quiet);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " ", this->Quiet);
+ }
+ }
+
+ cmSystemTools::ChangeDirectory(currentDirectory);
+ return file_count;
+}
+
+//----------------------------------------------------------------------
+int cmCTestCoverageHandler::HandleLCovCoverage(
+ cmCTestCoverageHandlerContainer* cont)
+{
+ std::string lcovCommand
+ = this->CTest->GetCTestConfiguration("CoverageCommand");
+ std::string lcovExtraFlags
+ = this->CTest->GetCTestConfiguration("CoverageExtraFlags");
+ if ( lcovCommand != "codecov" )
+ {
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " Not a valid Intel Coverage command."
+ << std::endl, this->Quiet);
+ return 0;
+ }
+ // There is only percentage completed output from LCOV
+ std::string st2lcovOutputRex3 = "[0-9]+%";
+ cmsys::RegularExpression st2re3(st2lcovOutputRex3.c_str());
+
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " This is coverage command: " << lcovCommand
+ << std::endl, this->Quiet);
+
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " These are coverage command flags: " << lcovExtraFlags
+ << std::endl, this->Quiet);
+
+ std::vector<std::string> files;
+ if (!this->FindLCovFiles(files))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Error while finding LCov files.\n");
+ return 0;
+ }
+ std::vector<std::string>::iterator it;
+
+ if (files.empty())
+ {
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " Cannot find any LCov coverage files."
+ << std::endl, this->Quiet);
+ // No coverage files is a valid thing, so the exit code is 0
+ return 0;
+ }
+ std::string testingDir = this->CTest->GetBinaryDir();
+ std::string tempDir = testingDir;
+ std::string currentDirectory = cmSystemTools::GetCurrentWorkingDirectory();
+
+ std::set<std::string> missingFiles;
+
+ std::string actualSourceFile = "";
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ " Processing coverage (each . represents one file):" << std::endl,
+ this->Quiet);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " ", this->Quiet);
+ int file_count = 0;
+
+ // make sure output from lcov is in English!
+ cmCTestCoverageHandlerLocale locale_C;
+ static_cast<void>(locale_C);
+
+ // In intel compiler we have to call codecov only once in each executable
+ // directory. It collects all *.dyn files to generate .dpi file.
+ for ( it = files.begin(); it != files.end(); ++ it )
+ {
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "." << std::flush,
+ this->Quiet);
+ std::string fileDir = cmSystemTools::GetFilenamePath(*it);
+ cmSystemTools::ChangeDirectory(fileDir);
+ std::string command = "\"" + lcovCommand + "\" " +
+ lcovExtraFlags + " ";
+
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Current coverage dir: " << fileDir << std::endl, this->Quiet);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, command.c_str()
+ << std::endl, this->Quiet);
+
+ std::string output = "";
+ std::string errors = "";
+ int retVal = 0;
+ *cont->OFS << "* Run coverage for: " << fileDir << std::endl;
+ *cont->OFS << " Command: " << command << std::endl;
+ int res = this->CTest->RunCommand(command.c_str(), &output, &errors,
+ &retVal, fileDir.c_str(), 0 /*this->TimeOut*/);
+
+ *cont->OFS << " Output: " << output << std::endl;
+ *cont->OFS << " Errors: " << errors << std::endl;
+ if ( ! res )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Problem running coverage on file: " << *it << std::endl);
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Command produced error: " << errors << std::endl);
+ cont->Error ++;
+ continue;
+ }
+ if ( retVal != 0 )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Coverage command returned: "
+ << retVal << " while processing: " << *it << std::endl);
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Command produced error: " << cont->Error << std::endl);
+ }
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "--------------------------------------------------------------"
+ << std::endl
+ << output << std::endl
+ << "--------------------------------------------------------------"
+ << std::endl, this->Quiet);
+
+ std::vector<std::string> lines;
+ std::vector<std::string>::iterator line;
+
+ cmSystemTools::Split(output.c_str(), lines);
+
+ for ( line = lines.begin(); line != lines.end(); ++line)
+ {
+ std::string sourceFile;
+ std::string lcovFile;
+
+ if (line->empty())
+ {
+ // Ignore empty line
+ }
+ // Look for LCOV files in binary directory
+ // Intel Compiler creates a CodeCoverage dir for each subfolder and
+ // each subfolder has LCOV files
+ cmsys::Glob gl;
+ gl.RecurseOn();
+ gl.RecurseThroughSymlinksOff();
+ std::string dir;
+ std::vector<std::string> lcovFiles;
+ dir = this->CTest->GetBinaryDir();
+ std::string daGlob;
+ daGlob = dir;
+ daGlob += "/*.LCOV";
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " looking for LCOV files in: " << daGlob << std::endl, this->Quiet);
+ gl.FindFiles(daGlob);
+ // Keep a list of all LCOV files
+ lcovFiles.insert(lcovFiles.end(), gl.GetFiles().begin(),
+ gl.GetFiles().end());
+
+ for(std::vector<std::string>::iterator a = lcovFiles.begin();
+ a != lcovFiles.end(); ++a)
+ {
+ lcovFile = *a;
+ cmsys::ifstream srcead(lcovFile.c_str());
+ if ( ! srcead )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot open file: "
+ << lcovFile << std::endl);
+ }
+ std::string srcname;
+
+ int success = cmSystemTools::GetLineFromStream(srcead, srcname);
+ if ( !success )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Error while parsing lcov file '" << lcovFile << "':"
+ << " No source file name found!" << std::endl);
+ return 0;
+ }
+ srcname = srcname.substr(18);
+ // We can directly read found LCOV files to determine the source
+ // files
+ sourceFile = srcname;
+ actualSourceFile = srcname;
+
+ for(std::vector<std::string>::iterator t = lcovFiles.begin();
+ t != lcovFiles.end(); ++t)
+ {
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Found LCOV File: " << *t << std::endl, this->Quiet);
+ }
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "SourceFile: "
+ << sourceFile << std::endl, this->Quiet);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "lCovFile: "
+ << lcovFile << std::endl, this->Quiet);
+
+ // If we have some LCOV files to process
+ if ( !lcovFile.empty() && !actualSourceFile.empty() )
+ {
+ cmCTestCoverageHandlerContainer::SingleFileCoverageVector& vec
+ = cont->TotalCoverage[actualSourceFile];
+
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " in lcovFile: " << lcovFile << std::endl, this->Quiet);
+
+ cmsys::ifstream ifile(lcovFile.c_str());
+ if ( ! ifile )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot open file: "
+ << lcovFile << std::endl);
+ }
+ else
+ {
+ long cnt = -1;
+ std::string nl;
+
+ // Skip the first line
+ cmSystemTools::GetLineFromStream(ifile, nl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "File is ready, start reading." << std::endl, this->Quiet);
+ while ( cmSystemTools::GetLineFromStream(ifile, nl) )
+ {
+ cnt ++;
+
+ // Skip empty lines
+ if (nl.empty())
+ {
+ continue;
+ }
+
+ // Skip unused lines
+ if ( nl.size() < 12 )
+ {
+ continue;
+ }
+
+ // Read the coverage count from the beginning of the lcov
+ // output line
+ std::string prefix = nl.substr(0, 17);
+ int cov = atoi(prefix.c_str());
+
+ // Read the line number starting at the 17th character of the
+ // lcov output line
+ std::string lineNumber = nl.substr(17, 7);
+
+ int lineIdx = atoi(lineNumber.c_str())-1;
+ if ( lineIdx >= 0 )
+ {
+ while ( vec.size() <= static_cast<size_t>(lineIdx) )
+ {
+ vec.push_back(-1);
+ }
+
+ // Initially all entries are -1 (not used). If we get coverage
+ // information, increment it to 0 first.
+ if ( vec[lineIdx] < 0 )
+ {
+ if ( cov > 0 || prefix.find("#") != prefix.npos )
+ {
+ vec[lineIdx] = 0;
+ }
+ }
+
+ vec[lineIdx] += cov;
+ }
+ }
+ }
+
+ actualSourceFile = "";
+ }
+ }
+ }
+
+ file_count++;
+
+ if ( file_count % 50 == 0 )
+ {
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ " processed: " << file_count << " out of " << files.size()
+ << std::endl, this->Quiet);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " ", this->Quiet);
}
}
- cmSystemTools::ChangeDirectory(currentDirectory.c_str());
+ cmSystemTools::ChangeDirectory(currentDirectory);
return file_count;
}
@@ -1272,8 +1766,8 @@ void cmCTestCoverageHandler::FindGCovFiles(std::vector<std::string>& files)
// Coverage files appear next to their object files in the target
// support directory.
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- " globbing for coverage in: " << lmi->first << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " globbing for coverage in: " << lmi->first << std::endl, this->Quiet);
std::string daGlob = lmi->first;
daGlob += "/*.da";
gl.FindFiles(daGlob);
@@ -1285,6 +1779,50 @@ void cmCTestCoverageHandler::FindGCovFiles(std::vector<std::string>& files)
}
}
+//----------------------------------------------------------------------------
+bool cmCTestCoverageHandler::FindLCovFiles(std::vector<std::string>& files)
+{
+ cmsys::Glob gl;
+ gl.RecurseOff(); // No need of recurse if -prof_dir${BUILD_DIR} flag is
+ // used while compiling.
+ gl.RecurseThroughSymlinksOff();
+ std::string prevBinaryDir;
+ std::string buildDir = this->CTest->GetCTestConfiguration("BuildDirectory");
+ if (cmSystemTools::ChangeDirectory(buildDir))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Error changing directory to " << buildDir << std::endl);
+ return false;
+ }
+
+ // Run profmerge to merge all *.dyn files into dpi files
+ if (!cmSystemTools::RunSingleCommand("profmerge"))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Error while running profmerge.\n");
+ return false;
+ }
+
+ prevBinaryDir = cmSystemTools::GetCurrentWorkingDirectory().c_str();
+
+ // DPI file should appear in build directory
+ std::string daGlob;
+ daGlob = prevBinaryDir;
+ daGlob += "/*.dpi";
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " looking for dpi files in: " << daGlob << std::endl, this->Quiet);
+ if (!gl.FindFiles(daGlob))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Error while finding files matching " << daGlob << std::endl);
+ return false;
+ }
+ files.insert(files.end(), gl.GetFiles().begin(), gl.GetFiles().end());
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Now searching in: " << daGlob << std::endl, this->Quiet);
+ return true;
+}
+
//----------------------------------------------------------------------
int cmCTestCoverageHandler::HandleTracePyCoverage(
cmCTestCoverageHandlerContainer* cont)
@@ -1296,11 +1834,11 @@ int cmCTestCoverageHandler::HandleTracePyCoverage(
gl.FindFiles(daGlob);
std::vector<std::string> files = gl.GetFiles();
- if ( files.size() == 0 )
+ if (files.empty())
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
" Cannot find any Python Trace.py coverage files."
- << std::endl);
+ << std::endl, this->Quiet);
// No coverage files is a valid thing, so the exit code is 0
return 0;
}
@@ -1309,9 +1847,9 @@ int cmCTestCoverageHandler::HandleTracePyCoverage(
std::string tempDir = testingDir + "/CoverageInfo";
std::string currentDirectory = cmSystemTools::GetCurrentWorkingDirectory();
cmSystemTools::MakeDirectory(tempDir.c_str());
- cmSystemTools::ChangeDirectory(tempDir.c_str());
+ cmSystemTools::ChangeDirectory(tempDir);
- cmSystemTools::ChangeDirectory(currentDirectory.c_str());
+ cmSystemTools::ChangeDirectory(currentDirectory);
std::vector<std::string>::iterator fileIt;
int file_count = 0;
@@ -1322,24 +1860,24 @@ int cmCTestCoverageHandler::HandleTracePyCoverage(
{
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Cannot find source Python file corresponding to: "
- << fileIt->c_str() << std::endl);
+ << *fileIt << std::endl);
continue;
}
std::string actualSourceFile
- = cmSystemTools::CollapseFullPath(fileName.c_str());
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- " Check coverage for file: " << actualSourceFile.c_str()
- << std::endl);
+ = cmSystemTools::CollapseFullPath(fileName);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " Check coverage for file: " << actualSourceFile
+ << std::endl, this->Quiet);
cmCTestCoverageHandlerContainer::SingleFileCoverageVector* vec
= &cont->TotalCoverage[actualSourceFile];
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- " in file: " << fileIt->c_str() << std::endl);
- std::ifstream ifile(fileIt->c_str());
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " in file: " << *fileIt << std::endl, this->Quiet);
+ cmsys::ifstream ifile(fileIt->c_str());
if ( ! ifile )
{
cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot open file: "
- << fileIt->c_str() << std::endl);
+ << *fileIt << std::endl);
}
else
{
@@ -1350,7 +1888,7 @@ int cmCTestCoverageHandler::HandleTracePyCoverage(
cnt ++;
// Skip empty lines
- if ( !nl.size() )
+ if (nl.empty())
{
continue;
}
@@ -1387,9 +1925,9 @@ int cmCTestCoverageHandler::HandleTracePyCoverage(
// So, this will be set to 0.
cov = 0;
}
- cmCTestLog(this->CTest, DEBUG, "Prefix: " << prefix.c_str()
+ cmCTestOptionalLog(this->CTest, DEBUG, "Prefix: " << prefix
<< " cov: " << cov
- << std::endl);
+ << std::endl, this->Quiet);
// Read the line number starting at the 10th character of the gcov
// output line
long lineIdx = cnt;
@@ -1415,7 +1953,7 @@ int cmCTestCoverageHandler::HandleTracePyCoverage(
}
++ file_count;
}
- cmSystemTools::ChangeDirectory(currentDirectory.c_str());
+ cmSystemTools::ChangeDirectory(currentDirectory);
return file_count;
}
@@ -1462,7 +2000,7 @@ namespace
//----------------------------------------------------------------------
int cmCTestCoverageHandler::RunBullseyeCoverageBranch(
cmCTestCoverageHandlerContainer* cont,
- std::set<cmStdString>& coveredFileNames,
+ std::set<std::string>& coveredFileNames,
std::vector<std::string>& files,
std::vector<std::string>& filesFullPath)
{
@@ -1474,36 +2012,36 @@ int cmCTestCoverageHandler::RunBullseyeCoverageBranch(
}
// create the output stream for the CoverageLog-N.xml file
cmGeneratedFileStream covLogFile;
+ cmXMLWriter covLogXML(covLogFile);
int logFileCount = 0;
if ( !this->StartCoverageLogFile(covLogFile, logFileCount) )
{
return -1;
}
+ this->StartCoverageLogXML(covLogXML);
// for each file run covbr on that file to get the coverage
// information for that file
std::string outputFile;
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "run covbr: "
- << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "run covbr: " << std::endl, this->Quiet);
if(!this->RunBullseyeCommand(cont, "covbr", 0, outputFile))
{
cmCTestLog(this->CTest, ERROR_MESSAGE, "error running covbr for." << "\n");
return -1;
}
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "covbr output in " << outputFile
- << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "covbr output in " << outputFile << std::endl, this->Quiet);
// open the output file
- std::ifstream fin(outputFile.c_str());
+ cmsys::ifstream fin(outputFile.c_str());
if(!fin)
{
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Cannot open coverage file: " <<
- outputFile.c_str() << std::endl);
+ outputFile << std::endl);
return 0;
}
- std::map<cmStdString, cmStdString> fileMap;
+ std::map<std::string, std::string> fileMap;
std::vector<std::string>::iterator fp = filesFullPath.begin();
for(std::vector<std::string>::iterator f = files.begin();
f != files.end(); ++f, ++fp)
@@ -1516,7 +2054,7 @@ int cmCTestCoverageHandler::RunBullseyeCoverageBranch(
std::string lineIn;
bool valid = false; // are we in a valid output file
int line = 0; // line of the current file
- cmStdString file;
+ std::string file;
while(cmSystemTools::GetLineFromStream(fin, lineIn))
{
bool startFile = false;
@@ -1533,49 +2071,49 @@ int cmCTestCoverageHandler::RunBullseyeCoverageBranch(
// if we are in a valid file close it because a new one started
if(valid)
{
- covLogFile << "\t\t</Report>" << std::endl
- << "\t</File>" << std::endl;
+ covLogXML.EndElement(); // Report
+ covLogXML.EndElement(); // File
}
// only allow 100 files in each log file
if ( count != 0 && count % 100 == 0 )
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "start a new log file: "
- << count
- << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "start a new log file: " << count << std::endl, this->Quiet);
+ this->EndCoverageLogXML(covLogXML);
this->EndCoverageLogFile(covLogFile, logFileCount);
logFileCount ++;
if ( !this->StartCoverageLogFile(covLogFile, logFileCount) )
{
return -1;
}
+ this->StartCoverageLogXML(covLogXML);
count++; // move on one
}
- std::map<cmStdString, cmStdString>::iterator
+ std::map<std::string, std::string>::iterator
i = fileMap.find(file);
// if the file should be covered write out the header for that file
if(i != fileMap.end())
{
// we have a new file so count it in the output
count++;
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "Produce coverage for file: "
- << file.c_str() << " " << count
- << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Produce coverage for file: " << file << " " << count
+ << std::endl, this->Quiet);
// start the file output
- covLogFile << "\t<File Name=\""
- << cmXMLSafe(i->first)
- << "\" FullPath=\"" << cmXMLSafe(
- this->CTest->GetShortPathToFile(
- i->second.c_str())) << "\">" << std::endl
- << "\t\t<Report>" << std::endl;
+ covLogXML.StartElement("File");
+ covLogXML.Attribute("Name", i->first);
+ covLogXML.Attribute("FullPath",
+ this->CTest->GetShortPathToFile(i->second.c_str()));
+ covLogXML.StartElement("Report");
// write the bullseye header
line =0;
for(int k =0; bullseyeHelp[k] != 0; ++k)
{
- covLogFile << "\t\t<Line Number=\"" << line << "\" Count=\"-1\">"
- << cmXMLSafe(bullseyeHelp[k])
- << "</Line>" << std::endl;
+ covLogXML.StartElement("Line");
+ covLogXML.Attribute("Number", line);
+ covLogXML.Attribute("Count", -1);
+ covLogXML.Content(bullseyeHelp[k]);
+ covLogXML.EndElement(); // Line
line++;
}
valid = true; // we are in a valid file section
@@ -1589,18 +2127,21 @@ int cmCTestCoverageHandler::RunBullseyeCoverageBranch(
// we are not at a start file, and we are in a valid file output the line
else if(valid)
{
- covLogFile << "\t\t<Line Number=\"" << line << "\" Count=\"-1\">"
- << cmXMLSafe(lineIn)
- << "</Line>" << std::endl;
+ covLogXML.StartElement("Line");
+ covLogXML.Attribute("Number", line);
+ covLogXML.Attribute("Count", -1);
+ covLogXML.Content(lineIn);
+ covLogXML.EndElement(); // Line
line++;
}
}
// if we ran out of lines a valid file then close that file
if(valid)
{
- covLogFile << "\t\t</Report>" << std::endl
- << "\t</File>" << std::endl;
+ covLogXML.EndElement(); // Report
+ covLogXML.EndElement(); // File
}
+ this->EndCoverageLogXML(covLogXML);
this->EndCoverageLogFile(covLogFile, logFileCount);
return 1;
}
@@ -1613,20 +2154,20 @@ int cmCTestCoverageHandler::RunBullseyeCommand(
std::string& outputFile)
{
std::string program = cmSystemTools::FindProgram(cmd);
- if(program.size() == 0)
+ if(program.empty())
{
cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot find :" << cmd << "\n");
return 0;
}
if(arg)
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "Run : " << program.c_str() << " " << arg << "\n");
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Run : " << program << " " << arg << "\n", this->Quiet);
}
else
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "Run : " << program.c_str() << "\n");
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Run : " << program << "\n", this->Quiet);
}
// create a process object and start it
cmCTestRunProcess runCoverageSrc;
@@ -1644,7 +2185,7 @@ int cmCTestCoverageHandler::RunBullseyeCommand(
if(!runCoverageSrc.StartProcess())
{
cmCTestLog(this->CTest, ERROR_MESSAGE, "Could not run : "
- << program.c_str() << " " << arg << "\n"
+ << program << " " << arg << "\n"
<< "kwsys process state : "
<< runCoverageSrc.GetProcessState());
return 0;
@@ -1670,23 +2211,20 @@ int cmCTestCoverageHandler::RunBullseyeSourceSummary(
std::ostream& tmpLog = *cont->OFS;
// copen the Coverage.xml file in the Testing directory
cmGeneratedFileStream covSumFile;
+ cmXMLWriter xml(covSumFile);
if(!this->StartResultingXML(cmCTest::PartCoverage, "Coverage", covSumFile))
{
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Cannot open coverage summary file." << std::endl);
return 0;
}
- this->CTest->StartXML(covSumFile, this->AppendXML);
+ this->CTest->StartXML(xml, this->AppendXML);
double elapsed_time_start = cmSystemTools::GetTime();
std::string coverage_start_time = this->CTest->CurrentTime();
- covSumFile << "<Coverage>" << std::endl
- << "\t<StartDateTime>"
- << coverage_start_time << "</StartDateTime>"
- << std::endl
- << "\t<StartTime>"
- << static_cast<unsigned int>(cmSystemTools::GetTime())
- << "</StartTime>"
- << std::endl;
+ xml.StartElement("Coverage");
+ xml.Element("StartDateTime", coverage_start_time);
+ xml.Element("StartTime",
+ static_cast<unsigned int>(cmSystemTools::GetTime()));
std::string stdline;
std::string errline;
// expected output:
@@ -1708,19 +2246,19 @@ int cmCTestCoverageHandler::RunBullseyeSourceSummary(
std::vector<std::string> coveredFiles;
std::vector<std::string> coveredFilesFullPath;
// Read and parse the summary output file
- std::ifstream fin(outputFile.c_str());
+ cmsys::ifstream fin(outputFile.c_str());
if(!fin)
{
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Cannot open coverage summary file: " <<
- outputFile.c_str() << std::endl);
+ outputFile << std::endl);
return 0;
}
- std::set<cmStdString> coveredFileNames;
+ std::set<std::string> coveredFileNames;
while(cmSystemTools::GetLineFromStream(fin, stdline))
{
// if we have a line of output from stdout
- if(stdline.size())
+ if(!stdline.empty())
{
// parse the comma separated output
this->ParseBullsEyeCovsrcLine(stdline,
@@ -1745,24 +2283,24 @@ int cmCTestCoverageHandler::RunBullseyeSourceSummary(
file += "/";
file += sourceFile;
}
- file = cmSystemTools::CollapseFullPath(file.c_str());
+ file = cmSystemTools::CollapseFullPath(file);
bool shouldIDoCoverage
= this->ShouldIDoCoverage(file.c_str(),
cont->SourceDir.c_str(),
cont->BinaryDir.c_str());
if ( !shouldIDoCoverage )
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- ".NoDartCoverage found, so skip coverage check for: "
- << file.c_str()
- << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ ".NoDartCoverage found, so skip coverage check for: "
+ << file
+ << std::endl, this->Quiet);
continue;
}
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "Doing coverage for: "
- << file.c_str()
- << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Doing coverage for: "
+ << file
+ << std::endl, this->Quiet);
coveredFiles.push_back(sourceFile);
coveredFilesFullPath.push_back(file);
@@ -1772,7 +2310,7 @@ int cmCTestCoverageHandler::RunBullseyeSourceSummary(
total_tested += functionsCalled;
total_untested += (totalFunctions - functionsCalled);
- std::string fileName = cmSystemTools::GetFilenameName(file.c_str());
+ std::string fileName = cmSystemTools::GetFilenameName(file);
std::string shortFileName =
this->CTest->GetShortPathToFile(file.c_str());
@@ -1781,14 +2319,14 @@ int cmCTestCoverageHandler::RunBullseyeSourceSummary(
{
cper /= 2.0f;
}
- percent_coverage += cper;
+ percent_coverage += static_cast<double>(cper);
float cmet = static_cast<float>(percentFunction + percentBranch);
if(totalBranches > 0)
{
cmet /= 2.0f;
}
cmet /= 100.0f;
- tmpLog << stdline.c_str() << "\n";
+ tmpLog << stdline << "\n";
tmpLog << fileName << "\n";
tmpLog << "functionsCalled: " << functionsCalled/100 << "\n";
tmpLog << "totalFunctions: " << totalFunctions/100 << "\n";
@@ -1798,58 +2336,35 @@ int cmCTestCoverageHandler::RunBullseyeSourceSummary(
tmpLog << "percentBranch: " << percentBranch << "\n";
tmpLog << "percentCoverage: " << percent_coverage << "\n";
tmpLog << "coverage metric: " << cmet << "\n";
- covSumFile << "\t<File Name=\"" << cmXMLSafe(sourceFile)
- << "\" FullPath=\"" << cmXMLSafe(shortFileName)
- << "\" Covered=\"" << (cmet>0?"true":"false") << "\">\n"
- << "\t\t<BranchesTested>"
- << branchCovered
- << "</BranchesTested>\n"
- << "\t\t<BranchesUnTested>"
- << totalBranches - branchCovered
- << "</BranchesUnTested>\n"
- << "\t\t<FunctionsTested>"
- << functionsCalled
- << "</FunctionsTested>\n"
- << "\t\t<FunctionsUnTested>"
- << totalFunctions - functionsCalled
- << "</FunctionsUnTested>\n"
- // Hack for conversion of function to loc assume a function
- // has 100 lines of code
- << "\t\t<LOCTested>" << functionsCalled *100
- << "</LOCTested>\n"
- << "\t\t<LOCUnTested>"
- << (totalFunctions - functionsCalled)*100
- << "</LOCUnTested>\n"
- << "\t\t<PercentCoverage>";
- covSumFile.setf(std::ios::fixed, std::ios::floatfield);
- covSumFile.precision(2);
- covSumFile << (cper) << "</PercentCoverage>\n"
- << "\t\t<CoverageMetric>";
- covSumFile.setf(std::ios::fixed, std::ios::floatfield);
- covSumFile.precision(2);
- covSumFile << (cmet) << "</CoverageMetric>\n";
- this->WriteXMLLabels(covSumFile, shortFileName);
- covSumFile << "\t</File>" << std::endl;
+ xml.StartElement("File");
+ xml.Attribute("Name", sourceFile);
+ xml.Attribute("FullPath", shortFileName);
+ xml.Attribute("Covered", cmet > 0 ? "true" : "false");
+ xml.Element("BranchesTested", branchCovered);
+ xml.Element("BranchesUnTested", totalBranches - branchCovered);
+ xml.Element("FunctionsTested", functionsCalled);
+ xml.Element("FunctionsUnTested", totalFunctions - functionsCalled);
+ // Hack for conversion of function to loc assume a function
+ // has 100 lines of code
+ xml.Element("LOCTested", functionsCalled * 100);
+ xml.Element("LOCUnTested", (totalFunctions - functionsCalled) * 100);
+ xml.Element("PercentCoverage", cper);
+ xml.Element("CoverageMetric", cmet);
+ this->WriteXMLLabels(xml, shortFileName);
+ xml.EndElement(); // File
}
}
std::string end_time = this->CTest->CurrentTime();
- covSumFile << "\t<LOCTested>" << total_tested << "</LOCTested>\n"
- << "\t<LOCUntested>" << total_untested << "</LOCUntested>\n"
- << "\t<LOC>" << total_functions << "</LOC>\n"
- << "\t<PercentCoverage>";
- covSumFile.setf(std::ios::fixed, std::ios::floatfield);
- covSumFile.precision(2);
- covSumFile
- << SAFEDIV(percent_coverage,number_files)<< "</PercentCoverage>\n"
- << "\t<EndDateTime>" << end_time << "</EndDateTime>\n"
- << "\t<EndTime>" << static_cast<unsigned int>(cmSystemTools::GetTime())
- << "</EndTime>\n";
- covSumFile
- << "<ElapsedMinutes>" <<
- static_cast<int>((cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0
- << "</ElapsedMinutes>"
- << "</Coverage>" << std::endl;
- this->CTest->EndXML(covSumFile);
+ xml.Element("LOCTested", total_tested);
+ xml.Element("LOCUntested", total_untested);
+ xml.Element("LOC", total_functions);
+ xml.Element("PercentCoverage", SAFEDIV(percent_coverage, number_files));
+ xml.Element("EndDateTime", end_time);
+ xml.Element("EndTime", static_cast<unsigned int>(cmSystemTools::GetTime()));
+ xml.Element("ElapsedMinutes",
+ static_cast<int>((cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0);
+ xml.EndElement(); // Coverage
+ this->CTest->EndXML(xml);
// Now create the coverage information for each file
return this->RunBullseyeCoverageBranch(cont,
@@ -1865,23 +2380,23 @@ int cmCTestCoverageHandler::HandleBullseyeCoverage(
const char* covfile = cmSystemTools::GetEnv("COVFILE");
if(!covfile || strlen(covfile) == 0)
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- " COVFILE environment variable not found, not running "
- " bullseye\n");
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " COVFILE environment variable not found, not running "
+ " bullseye\n", this->Quiet);
return 0;
}
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- " run covsrc with COVFILE=["
- << covfile
- << "]" << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " run covsrc with COVFILE=["
+ << covfile
+ << "]" << std::endl, this->Quiet);
if(!this->RunBullseyeSourceSummary(cont))
{
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Error running bullseye summary.\n");
return 0;
}
- cmCTestLog(this->CTest, DEBUG, "HandleBullseyeCoverage return 1 "
- << std::endl);
+ cmCTestOptionalLog(this->CTest, DEBUG, "HandleBullseyeCoverage return 1 "
+ << std::endl, this->Quiet);
return 1;
}
@@ -1915,7 +2430,7 @@ bool cmCTestCoverageHandler::ParseBullsEyeCovsrcLine(
if(pos == inputLine.npos)
{
cmCTestLog(this->CTest, ERROR_MESSAGE, "Error parsing string : "
- << inputLine.c_str() << "\n");
+ << inputLine << "\n");
return false;
}
// the source file has "" around it so extract out the file name
@@ -1949,7 +2464,7 @@ bool cmCTestCoverageHandler::ParseBullsEyeCovsrcLine(
if(pos != inputLine.npos)
{
cmCTestLog(this->CTest, ERROR_MESSAGE, "Error parsing input : "
- << inputLine.c_str() << " last pos not npos = " << pos <<
+ << inputLine << " last pos not npos = " << pos <<
"\n");
}
return true;
@@ -1975,9 +2490,9 @@ void cmCTestCoverageHandler::LoadLabels()
std::string fileList = this->CTest->GetBinaryDir();
fileList += cmake::GetCMakeFilesDirectory();
fileList += "/TargetDirectories.txt";
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- " target directory list [" << fileList << "]\n");
- std::ifstream finList(fileList.c_str());
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " target directory list [" << fileList << "]\n", this->Quiet);
+ cmsys::ifstream finList(fileList.c_str());
std::string line;
while(cmSystemTools::GetLineFromStream(finList, line))
{
@@ -1991,14 +2506,14 @@ void cmCTestCoverageHandler::LoadLabels(const char* dir)
LabelSet& dirLabels = this->TargetDirs[dir];
std::string fname = dir;
fname += "/Labels.txt";
- std::ifstream fin(fname.c_str());
+ cmsys::ifstream fin(fname.c_str());
if(!fin)
{
return;
}
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- " loading labels from [" << fname << "]\n");
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " loading labels from [" << fname << "]\n", this->Quiet);
bool inTarget = true;
std::string source;
std::string line;
@@ -2035,38 +2550,34 @@ void cmCTestCoverageHandler::LoadLabels(const char* dir)
// Label the source with the target labels.
LabelSet& labelSet = this->SourceLabels[source];
- for(std::vector<int>::const_iterator li = targetLabels.begin();
- li != targetLabels.end(); ++li)
- {
- labelSet.insert(*li);
- }
+ labelSet.insert(targetLabels.begin(), targetLabels.end());
}
}
}
//----------------------------------------------------------------------
-void cmCTestCoverageHandler::WriteXMLLabels(std::ofstream& os,
+void cmCTestCoverageHandler::WriteXMLLabels(cmXMLWriter& xml,
std::string const& source)
{
LabelMapType::const_iterator li = this->SourceLabels.find(source);
if(li != this->SourceLabels.end() && !li->second.empty())
{
- os << "\t\t<Labels>\n";
+ xml.StartElement("Labels");
for(LabelSet::const_iterator lsi = li->second.begin();
lsi != li->second.end(); ++lsi)
{
- os << "\t\t\t<Label>" << cmXMLSafe(this->Labels[*lsi]) << "</Label>\n";
+ xml.Element("Label", this->Labels[*lsi]);
}
- os << "\t\t</Labels>\n";
+ xml.EndElement(); // Labels
}
}
//----------------------------------------------------------------------------
void
-cmCTestCoverageHandler::SetLabelFilter(std::set<cmStdString> const& labels)
+cmCTestCoverageHandler::SetLabelFilter(std::set<std::string> const& labels)
{
this->LabelFilter.clear();
- for(std::set<cmStdString>::const_iterator li = labels.begin();
+ for(std::set<std::string>::const_iterator li = labels.begin();
li != labels.end(); ++li)
{
this->LabelFilter.insert(this->GetLabelId(*li));
@@ -2083,10 +2594,10 @@ bool cmCTestCoverageHandler::IntersectsFilter(LabelSet const& labels)
}
std::vector<int> ids;
- cmsys_stl::set_intersection
+ std::set_intersection
(labels.begin(), labels.end(),
this->LabelFilter.begin(), this->LabelFilter.end(),
- cmsys_stl::back_inserter(ids));
+ std::back_inserter(ids));
return !ids.empty();
}
@@ -2116,7 +2627,7 @@ std::set<std::string> cmCTestCoverageHandler::FindUncoveredFiles(
{
std::set<std::string> extraMatches;
- for(std::vector<cmStdString>::iterator i = this->ExtraCoverageGlobs.begin();
+ for(std::vector<std::string>::iterator i = this->ExtraCoverageGlobs.begin();
i != this->ExtraCoverageGlobs.end(); ++i)
{
cmsys::Glob gl;
@@ -2137,7 +2648,7 @@ std::set<std::string> cmCTestCoverageHandler::FindUncoveredFiles(
}
}
- if(extraMatches.size())
+ if(!extraMatches.empty())
{
for(cmCTestCoverageHandlerContainer::TotalCoverageMap::iterator i =
cont->TotalCoverage.begin(); i != cont->TotalCoverage.end(); ++i)
diff --git a/Source/CTest/cmCTestCoverageHandler.h b/Source/CTest/cmCTestCoverageHandler.h
index 92b0b2285..7102d1e67 100644
--- a/Source/CTest/cmCTestCoverageHandler.h
+++ b/Source/CTest/cmCTestCoverageHandler.h
@@ -20,6 +20,7 @@
#include <cmsys/RegularExpression.hxx>
class cmGeneratedFileStream;
+class cmXMLWriter;
class cmCTestCoverageHandlerContainer
{
public:
@@ -30,9 +31,10 @@ public:
typedef std::map<std::string, SingleFileCoverageVector> TotalCoverageMap;
TotalCoverageMap TotalCoverage;
std::ostream* OFS;
+ bool Quiet;
};
/** \class cmCTestCoverageHandler
- * \brief A class that handles coverage computaiton for ctest
+ * \brief A class that handles coverage computation for ctest
*
*/
class cmCTestCoverageHandler : public cmCTestGenericHandler
@@ -55,7 +57,7 @@ public:
void PopulateCustomVectors(cmMakefile *mf);
/** Report coverage only for sources with these labels. */
- void SetLabelFilter(std::set<cmStdString> const& labels);
+ void SetLabelFilter(std::set<std::string> const& labels);
private:
bool ShouldIDoCoverage(const char* file, const char* srcDir,
@@ -64,20 +66,40 @@ private:
bool StartCoverageLogFile(cmGeneratedFileStream& ostr, int logFileCount);
void EndCoverageLogFile(cmGeneratedFileStream& ostr, int logFileCount);
+ void StartCoverageLogXML(cmXMLWriter& xml);
+ void EndCoverageLogXML(cmXMLWriter& xml);
+
//! Handle coverage using GCC's GCov
int HandleGCovCoverage(cmCTestCoverageHandlerContainer* cont);
void FindGCovFiles(std::vector<std::string>& files);
+ //! Handle coverage using Intel's LCov
+ int HandleLCovCoverage(cmCTestCoverageHandlerContainer* cont);
+ bool FindLCovFiles(std::vector<std::string>& files);
+
//! Handle coverage using xdebug php coverage
int HandlePHPCoverage(cmCTestCoverageHandlerContainer* cont);
+
+ //! Handle coverage for Python with coverage.py
+ int HandleCoberturaCoverage(cmCTestCoverageHandlerContainer* cont);
+
//! Handle coverage for mumps
int HandleMumpsCoverage(cmCTestCoverageHandlerContainer* cont);
- //! Handle coverage using Bullseye
+ //! Handle coverage for Jacoco
+ int HandleJacocoCoverage(cmCTestCoverageHandlerContainer* cont);
+
+ //! Handle coverage for Delphi (Pascal)
+ int HandleDelphiCoverage(cmCTestCoverageHandlerContainer* cont);
+
+ //! Handle coverage for Jacoco
+ int HandleBlanketJSCoverage(cmCTestCoverageHandlerContainer* cont);
+
+//! Handle coverage using Bullseye
int HandleBullseyeCoverage(cmCTestCoverageHandlerContainer* cont);
int RunBullseyeSourceSummary(cmCTestCoverageHandlerContainer* cont);
int RunBullseyeCoverageBranch(cmCTestCoverageHandlerContainer* cont,
- std::set<cmStdString>& coveredFileNames,
+ std::set<std::string>& coveredFileNames,
std::vector<std::string>& files,
std::vector<std::string>& filesFullPath);
@@ -108,19 +130,19 @@ private:
std::set<std::string> FindUncoveredFiles(
cmCTestCoverageHandlerContainer* cont);
- std::vector<cmStdString> CustomCoverageExclude;
+ std::vector<std::string> CustomCoverageExclude;
std::vector<cmsys::RegularExpression> CustomCoverageExcludeRegex;
- std::vector<cmStdString> ExtraCoverageGlobs;
+ std::vector<std::string> ExtraCoverageGlobs;
// Map from source file to label ids.
class LabelSet: public std::set<int> {};
- typedef std::map<cmStdString, LabelSet> LabelMapType;
+ typedef std::map<std::string, LabelSet> LabelMapType;
LabelMapType SourceLabels;
LabelMapType TargetDirs;
// Map from label name to label id.
- typedef std::map<cmStdString, int> LabelIdMapType;
+ typedef std::map<std::string, int> LabelIdMapType;
LabelIdMapType LabelIdMap;
std::vector<std::string> Labels;
int GetLabelId(std::string const& label);
@@ -128,7 +150,7 @@ private:
// Label reading and writing methods.
void LoadLabels();
void LoadLabels(const char* dir);
- void WriteXMLLabels(std::ofstream& os, std::string const& source);
+ void WriteXMLLabels(cmXMLWriter& xml, std::string const& source);
// Label-based filtering.
std::set<int> LabelFilter;
diff --git a/Source/CTest/cmCTestCurl.cxx b/Source/CTest/cmCTestCurl.cxx
new file mode 100644
index 000000000..fb6cc007f
--- /dev/null
+++ b/Source/CTest/cmCTestCurl.cxx
@@ -0,0 +1,288 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmCTestCurl.h"
+
+#include "cmSystemTools.h"
+#include "cmCTest.h"
+
+cmCTestCurl::cmCTestCurl(cmCTest* ctest)
+{
+ this->CTest = ctest;
+ this->SetProxyType();
+ this->UseHttp10 = false;
+ // In windows, this will init the winsock stuff
+ ::curl_global_init(CURL_GLOBAL_ALL);
+ // default is to verify https
+ this->VerifyPeerOff = false;
+ this->VerifyHostOff = false;
+ this->TimeOutSeconds = 0;
+ this->Curl = curl_easy_init();
+}
+
+cmCTestCurl::~cmCTestCurl()
+{
+ ::curl_easy_cleanup(this->Curl);
+ ::curl_global_cleanup();
+}
+
+std::string cmCTestCurl::Escape(std::string const& source)
+{
+ char* data1 = curl_easy_escape(this->Curl, source.c_str(), 0);
+ std::string ret = data1;
+ curl_free(data1);
+ return ret;
+}
+
+namespace
+{
+static size_t
+curlWriteMemoryCallback(void *ptr, size_t size, size_t nmemb,
+ void *data)
+{
+ int realsize = (int)(size * nmemb);
+
+ std::vector<char> *vec
+ = static_cast<std::vector<char>* >(data);
+ const char* chPtr = static_cast<char*>(ptr);
+ vec->insert(vec->end(), chPtr, chPtr + realsize);
+ return realsize;
+}
+
+static size_t
+curlDebugCallback(CURL *, curl_infotype, char *chPtr,
+ size_t size, void *data)
+{
+ std::vector<char> *vec
+ = static_cast<std::vector<char>* >(data);
+ vec->insert(vec->end(), chPtr, chPtr + size);
+
+ return size;
+}
+
+}
+
+void cmCTestCurl::SetCurlOptions(std::vector<std::string> const& args)
+{
+ for( std::vector<std::string>::const_iterator i = args.begin();
+ i != args.end(); ++i)
+ {
+ if(*i == "CURLOPT_SSL_VERIFYPEER_OFF")
+ {
+ this->VerifyPeerOff = true;
+ }
+ if(*i == "CURLOPT_SSL_VERIFYHOST_OFF")
+ {
+ this->VerifyHostOff = true;
+ }
+ }
+}
+
+bool cmCTestCurl::InitCurl()
+{
+ if(!this->Curl)
+ {
+ return false;
+ }
+ if(this->VerifyPeerOff)
+ {
+ curl_easy_setopt(this->Curl, CURLOPT_SSL_VERIFYPEER, 0);
+ }
+ if(this->VerifyHostOff)
+ {
+ curl_easy_setopt(this->Curl, CURLOPT_SSL_VERIFYHOST, 0);
+ }
+ if(this->HTTPProxy.size())
+ {
+ curl_easy_setopt(this->Curl, CURLOPT_PROXY, this->HTTPProxy.c_str());
+ curl_easy_setopt(this->Curl, CURLOPT_PROXYTYPE, this->HTTPProxyType);
+ if (this->HTTPProxyAuth.size() > 0)
+ {
+ curl_easy_setopt(this->Curl, CURLOPT_PROXYUSERPWD,
+ this->HTTPProxyAuth.c_str());
+ }
+ }
+ if(this->UseHttp10)
+ {
+ curl_easy_setopt(this->Curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ }
+ // enable HTTP ERROR parsing
+ curl_easy_setopt(this->Curl, CURLOPT_FAILONERROR, 1);
+ return true;
+}
+
+
+bool cmCTestCurl::UploadFile(std::string const& local_file,
+ std::string const& url,
+ std::string const& fields,
+ std::string& response)
+{
+ response = "";
+ if(!this->InitCurl())
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Initialization of curl failed");
+ return false;
+ }
+ /* enable uploading */
+ curl_easy_setopt(this->Curl, CURLOPT_UPLOAD, 1);
+ // if there is little to no activity for too long stop submitting
+ if(this->TimeOutSeconds)
+ {
+ ::curl_easy_setopt(this->Curl, CURLOPT_LOW_SPEED_LIMIT, 1);
+ ::curl_easy_setopt(this->Curl, CURLOPT_LOW_SPEED_TIME,
+ this->TimeOutSeconds);
+ }
+ /* HTTP PUT please */
+ ::curl_easy_setopt(this->Curl, CURLOPT_PUT, 1);
+ ::curl_easy_setopt(this->Curl, CURLOPT_VERBOSE, 1);
+
+ FILE* ftpfile = cmsys::SystemTools::Fopen(local_file, "rb");
+ if(!ftpfile)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Could not open file for upload: " << local_file << "\n");
+ return false;
+ }
+ // set the url
+ std::string upload_url = url;
+ upload_url += "?";
+ upload_url += fields;
+ ::curl_easy_setopt(this->Curl, CURLOPT_URL, upload_url.c_str());
+ // now specify which file to upload
+ ::curl_easy_setopt(this->Curl, CURLOPT_INFILE, ftpfile);
+ unsigned long filelen = cmSystemTools::FileLength(local_file);
+ // and give the size of the upload (optional)
+ ::curl_easy_setopt(this->Curl, CURLOPT_INFILESIZE,
+ static_cast<long>(filelen));
+ ::curl_easy_setopt(this->Curl, CURLOPT_WRITEFUNCTION,
+ curlWriteMemoryCallback);
+ ::curl_easy_setopt(this->Curl, CURLOPT_DEBUGFUNCTION,
+ curlDebugCallback);
+ // Be sure to set Content-Type to satisfy fussy modsecurity rules
+ struct curl_slist *headers = ::curl_slist_append(NULL,
+ "Content-Type: text/xml");
+ ::curl_easy_setopt(this->Curl, CURLOPT_HTTPHEADER, headers);
+ std::vector<char> responseData;
+ std::vector<char> debugData;
+ ::curl_easy_setopt(this->Curl, CURLOPT_FILE, (void *)&responseData);
+ ::curl_easy_setopt(this->Curl, CURLOPT_DEBUGDATA, (void *)&debugData);
+ ::curl_easy_setopt(this->Curl, CURLOPT_FAILONERROR, 1);
+ // Now run off and do what you've been told!
+ ::curl_easy_perform(this->Curl);
+ ::fclose(ftpfile);
+ ::curl_easy_setopt(this->Curl, CURLOPT_HTTPHEADER, NULL);
+ ::curl_slist_free_all(headers);
+
+ if ( responseData.size() > 0 )
+ {
+ response = std::string(responseData.begin(), responseData.end());
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Curl response: [" << response << "]\n");
+ }
+ std::string curlDebug;
+ if ( debugData.size() > 0 )
+ {
+ curlDebug = std::string(debugData.begin(), debugData.end());
+ cmCTestLog(this->CTest, DEBUG, "Curl debug: [" << curlDebug << "]\n");
+ }
+ if(response.size() == 0)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "No response from server.\n" <<
+ curlDebug);
+ return false;
+ }
+ return true;
+}
+
+bool cmCTestCurl::HttpRequest(std::string const& url,
+ std::string const& fields,
+ std::string& response)
+{
+ response = "";
+ cmCTestLog(this->CTest, DEBUG, "HttpRequest\n"
+ << "url: " << url << "\n"
+ << "fields " << fields << "\n");
+ if(!this->InitCurl())
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Initialization of curl failed");
+ return false;
+ }
+ curl_easy_setopt(this->Curl, CURLOPT_POST, 1);
+ curl_easy_setopt(this->Curl, CURLOPT_POSTFIELDS, fields.c_str());
+ ::curl_easy_setopt(this->Curl, CURLOPT_URL, url.c_str());
+ ::curl_easy_setopt(this->Curl, CURLOPT_FOLLOWLOCATION, 1);
+ //set response options
+ ::curl_easy_setopt(this->Curl, CURLOPT_WRITEFUNCTION,
+ curlWriteMemoryCallback);
+ ::curl_easy_setopt(this->Curl, CURLOPT_DEBUGFUNCTION,
+ curlDebugCallback);
+ std::vector<char> responseData;
+ std::vector<char> debugData;
+ ::curl_easy_setopt(this->Curl, CURLOPT_FILE, (void *)&responseData);
+ ::curl_easy_setopt(this->Curl, CURLOPT_DEBUGDATA, (void *)&debugData);
+ ::curl_easy_setopt(this->Curl, CURLOPT_FAILONERROR, 1);
+
+ CURLcode res = ::curl_easy_perform(this->Curl);
+
+ if ( responseData.size() > 0 )
+ {
+ response = std::string(responseData.begin(), responseData.end());
+ cmCTestLog(this->CTest, DEBUG, "Curl response: [" << response << "]\n");
+ }
+ if ( debugData.size() > 0 )
+ {
+ std::string curlDebug = std::string(debugData.begin(), debugData.end());
+ cmCTestLog(this->CTest, DEBUG, "Curl debug: [" << curlDebug << "]\n");
+ }
+ cmCTestLog(this->CTest, DEBUG, "Curl res: " << res << "\n");
+ return (res == 0);
+}
+
+void cmCTestCurl::SetProxyType()
+{
+ if ( cmSystemTools::GetEnv("HTTP_PROXY") )
+ {
+ this->HTTPProxy = cmSystemTools::GetEnv("HTTP_PROXY");
+ if ( cmSystemTools::GetEnv("HTTP_PROXY_PORT") )
+ {
+ this->HTTPProxy += ":";
+ this->HTTPProxy += cmSystemTools::GetEnv("HTTP_PROXY_PORT");
+ }
+ if ( cmSystemTools::GetEnv("HTTP_PROXY_TYPE") )
+ {
+ // this is the default
+ this->HTTPProxyType = CURLPROXY_HTTP;
+ std::string type = cmSystemTools::GetEnv("HTTP_PROXY_TYPE");
+ // HTTP/SOCKS4/SOCKS5
+ if ( type == "HTTP" )
+ {
+ this->HTTPProxyType = CURLPROXY_HTTP;
+ }
+ else if ( type == "SOCKS4" )
+ {
+ this->HTTPProxyType = CURLPROXY_SOCKS4;
+ }
+ else if ( type == "SOCKS5" )
+ {
+ this->HTTPProxyType = CURLPROXY_SOCKS5;
+ }
+ }
+ if ( cmSystemTools::GetEnv("HTTP_PROXY_USER") )
+ {
+ this->HTTPProxyAuth = cmSystemTools::GetEnv("HTTP_PROXY_USER");
+ }
+ if ( cmSystemTools::GetEnv("HTTP_PROXY_PASSWD") )
+ {
+ this->HTTPProxyAuth += ":";
+ this->HTTPProxyAuth += cmSystemTools::GetEnv("HTTP_PROXY_PASSWD");
+ }
+ }
+}
diff --git a/Source/CTest/cmCTestCurl.h b/Source/CTest/cmCTestCurl.h
new file mode 100644
index 000000000..0737bb6df
--- /dev/null
+++ b/Source/CTest/cmCTestCurl.h
@@ -0,0 +1,54 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmCTestCurl_h
+#define cmCTestCurl_h
+
+#include "cmStandardIncludes.h"
+
+#include "cm_curl.h"
+
+class cmCTest;
+
+class cmCTestCurl
+{
+public:
+ cmCTestCurl(cmCTest*);
+ ~cmCTestCurl();
+ bool UploadFile(std::string const& url,
+ std::string const& file,
+ std::string const& fields,
+ std::string& response);
+ bool HttpRequest(std::string const& url,
+ std::string const& fields,
+ std::string& response);
+ // currently only supports CURLOPT_SSL_VERIFYPEER_OFF
+ // and CURLOPT_SSL_VERIFYHOST_OFF
+ void SetCurlOptions(std::vector<std::string> const& args);
+ void SetUseHttp10On() { this->UseHttp10 = true;}
+ void SetTimeOutSeconds(int s) { this->TimeOutSeconds = s;}
+ std::string Escape(std::string const& source);
+protected:
+ void SetProxyType();
+ bool InitCurl();
+private:
+ cmCTest* CTest;
+ CURL* Curl;
+ std::string HTTPProxyAuth;
+ std::string HTTPProxy;
+ curl_proxytype HTTPProxyType;
+ bool VerifyHostOff;
+ bool VerifyPeerOff;
+ bool UseHttp10;
+ int TimeOutSeconds;
+};
+
+#endif
diff --git a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx
index abc33de68..e175592e6 100644
--- a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx
+++ b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx
@@ -24,9 +24,9 @@ bool cmCTestEmptyBinaryDirectoryCommand
if ( !cmCTestScriptHandler::EmptyBinaryDirectory(args[0].c_str()) )
{
- cmOStringStream ostr;
- ostr << "problem removing the binary directory: " << args[0].c_str();
- this->SetError(ostr.str().c_str());
+ std::ostringstream ostr;
+ ostr << "problem removing the binary directory: " << args[0];
+ this->SetError(ostr.str());
return false;
}
diff --git a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h
index a763fe9e9..d182d1794 100644
--- a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h
+++ b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h
@@ -48,27 +48,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "ctest_empty_binary_directory";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "empties the binary directory";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " ctest_empty_binary_directory( directory )\n"
- "Removes a binary directory. This command will perform some checks "
- "prior to deleting the directory in an attempt to avoid malicious "
- "or accidental directory deletion.";
- }
+ virtual std::string GetName() const { return "ctest_empty_binary_directory";}
cmTypeMacro(cmCTestEmptyBinaryDirectoryCommand, cmCTestCommand);
diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx
index 5b3449181..bbb3b9d47 100644
--- a/Source/CTest/cmCTestGIT.cxx
+++ b/Source/CTest/cmCTestGIT.cxx
@@ -13,11 +13,11 @@
#include "cmCTest.h"
#include "cmSystemTools.h"
-#include "cmXMLSafe.h"
+#include "cmAlgorithms.h"
#include <cmsys/RegularExpression.hxx>
-#include <cmsys/ios/sstream>
#include <cmsys/Process.h>
+#include <cmsys/FStream.hxx>
#include <sys/types.h>
#include <time.h>
@@ -157,7 +157,7 @@ std::string cmCTestGIT::FindTopDir()
{
top_dir += "/";
top_dir += cdup;
- top_dir = cmSystemTools::CollapseFullPath(top_dir.c_str());
+ top_dir = cmSystemTools::CollapseFullPath(top_dir);
}
return top_dir;
}
@@ -178,8 +178,8 @@ bool cmCTestGIT::UpdateByFetchAndReset()
{
opts = this->CTest->GetCTestConfiguration("GITUpdateOptions");
}
- std::vector<cmStdString> args = cmSystemTools::ParseArguments(opts.c_str());
- for(std::vector<cmStdString>::const_iterator ai = args.begin();
+ std::vector<std::string> args = cmSystemTools::ParseArguments(opts.c_str());
+ for(std::vector<std::string>::const_iterator ai = args.begin();
ai != args.end(); ++ai)
{
git_fetch.push_back(ai->c_str());
@@ -200,7 +200,7 @@ bool cmCTestGIT::UpdateByFetchAndReset()
std::string sha1;
{
std::string fetch_head = this->FindGitDir() + "/FETCH_HEAD";
- std::ifstream fin(fetch_head.c_str(), std::ios::in | std::ios::binary);
+ cmsys::ifstream fin(fetch_head.c_str(), std::ios::in | std::ios::binary);
if(!fin)
{
this->Log << "Unable to open " << fetch_head << "\n";
@@ -536,11 +536,11 @@ private:
void DoHeaderLine()
{
// Look for header fields that we need.
- if(strncmp(this->Line.c_str(), "commit ", 7) == 0)
+ if(cmHasLiteralPrefix(this->Line.c_str(), "commit "))
{
this->Rev.Rev = this->Line.c_str()+7;
}
- else if(strncmp(this->Line.c_str(), "author ", 7) == 0)
+ else if(cmHasLiteralPrefix(this->Line.c_str(), "author "))
{
Person author;
this->ParsePerson(this->Line.c_str()+7, author);
@@ -548,7 +548,7 @@ private:
this->Rev.EMail = author.EMail;
this->Rev.Date = this->FormatDateTime(author);
}
- else if(strncmp(this->Line.c_str(), "committer ", 10) == 0)
+ else if(cmHasLiteralPrefix(this->Line.c_str(), "committer "))
{
Person committer;
this->ParsePerson(this->Line.c_str()+10, committer);
diff --git a/Source/CTest/cmCTestGenericHandler.cxx b/Source/CTest/cmCTestGenericHandler.cxx
index 5338f307b..ad79ba2b1 100644
--- a/Source/CTest/cmCTestGenericHandler.cxx
+++ b/Source/CTest/cmCTestGenericHandler.cxx
@@ -22,6 +22,8 @@ cmCTestGenericHandler::cmCTestGenericHandler()
this->CTest = 0;
this->SubmitIndex = 0;
this->AppendXML = false;
+ this->Quiet = false;
+ this->TestLoad = 0;
}
//----------------------------------------------------------------------
@@ -30,12 +32,8 @@ cmCTestGenericHandler::~cmCTestGenericHandler()
}
//----------------------------------------------------------------------
-void cmCTestGenericHandler::SetOption(const char* op, const char* value)
+void cmCTestGenericHandler::SetOption(const std::string& op, const char* value)
{
- if ( !op )
- {
- return;
- }
if ( !value )
{
cmCTestGenericHandler::t_StringToString::iterator remit
@@ -51,14 +49,10 @@ void cmCTestGenericHandler::SetOption(const char* op, const char* value)
}
//----------------------------------------------------------------------
-void cmCTestGenericHandler::SetPersistentOption(const char* op,
+void cmCTestGenericHandler::SetPersistentOption(const std::string& op,
const char* value)
{
this->SetOption(op, value);
- if ( !op )
- {
- return;
- }
if ( !value )
{
cmCTestGenericHandler::t_StringToString::iterator remit
@@ -77,18 +71,19 @@ void cmCTestGenericHandler::SetPersistentOption(const char* op,
void cmCTestGenericHandler::Initialize()
{
this->AppendXML = false;
+ this->TestLoad = 0;
this->Options.clear();
t_StringToString::iterator it;
for ( it = this->PersistentOptions.begin();
it != this->PersistentOptions.end();
++ it )
{
- this->Options[it->first.c_str()] = it->second.c_str();
+ this->Options[it->first] = it->second.c_str();
}
}
//----------------------------------------------------------------------
-const char* cmCTestGenericHandler::GetOption(const char* op)
+const char* cmCTestGenericHandler::GetOption(const std::string& op)
{
cmCTestGenericHandler::t_StringToString::iterator remit
= this->Options.find(op);
@@ -111,7 +106,7 @@ bool cmCTestGenericHandler::StartResultingXML(cmCTest::Part part,
<< std::endl;);
return false;
}
- cmOStringStream ostr;
+ std::ostringstream ostr;
ostr << name;
if ( this->SubmitIndex > 0 )
{
@@ -129,10 +124,10 @@ bool cmCTestGenericHandler::StartResultingXML(cmCTest::Part part,
return false;
}
if( !this->CTest->OpenOutputFile(this->CTest->GetCurrentTag(),
- ostr.str().c_str(), xofs, true) )
+ ostr.str(), xofs, true) )
{
cmCTestLog(this->CTest, ERROR_MESSAGE,
- "Cannot create resulting XML file: " << ostr.str().c_str()
+ "Cannot create resulting XML file: " << ostr.str()
<< std::endl);
return false;
}
@@ -150,7 +145,7 @@ bool cmCTestGenericHandler::StartLogFile(const char* name,
"Cannot create log file without providing the name" << std::endl;);
return false;
}
- cmOStringStream ostr;
+ std::ostringstream ostr;
ostr << "Last" << name;
if ( this->SubmitIndex > 0 )
{
@@ -161,10 +156,10 @@ bool cmCTestGenericHandler::StartLogFile(const char* name,
ostr << "_" << this->CTest->GetCurrentTag();
}
ostr << ".log";
- if( !this->CTest->OpenOutputFile("Temporary", ostr.str().c_str(), xofs) )
+ if( !this->CTest->OpenOutputFile("Temporary", ostr.str(), xofs) )
{
cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot create log file: "
- << ostr.str().c_str() << std::endl);
+ << ostr.str() << std::endl);
return false;
}
return true;
diff --git a/Source/CTest/cmCTestGenericHandler.h b/Source/CTest/cmCTestGenericHandler.h
index ba8febb61..4b7ae7901 100644
--- a/Source/CTest/cmCTestGenericHandler.h
+++ b/Source/CTest/cmCTestGenericHandler.h
@@ -71,12 +71,12 @@ public:
cmCTestGenericHandler();
virtual ~cmCTestGenericHandler();
- typedef std::map<cmStdString,cmStdString> t_StringToString;
+ typedef std::map<std::string,std::string> t_StringToString;
- void SetPersistentOption(const char* op, const char* value);
- void SetOption(const char* op, const char* value);
- const char* GetOption(const char* op);
+ void SetPersistentOption(const std::string& op, const char* value);
+ void SetOption(const std::string& op, const char* value);
+ const char* GetOption(const std::string& op);
void SetCommand(cmCTestCommand* command)
{
@@ -87,6 +87,10 @@ public:
int GetSubmitIndex() { return this->SubmitIndex; }
void SetAppendXML(bool b) { this->AppendXML = b; }
+ void SetQuiet(bool b) { this->Quiet = b; }
+ bool GetQuiet() { return this->Quiet; }
+ void SetTestLoad(unsigned long load) { this->TestLoad = load; }
+ unsigned long GetTestLoad() const { return this->TestLoad; }
protected:
bool StartResultingXML(cmCTest::Part part,
@@ -94,6 +98,8 @@ protected:
bool StartLogFile(const char* name, cmGeneratedFileStream& xofs);
bool AppendXML;
+ bool Quiet;
+ unsigned long TestLoad;
cmSystemTools::OutputOption HandlerVerbose;
cmCTest *CTest;
t_StringToString Options;
diff --git a/Source/CTest/cmCTestGlobalVC.cxx b/Source/CTest/cmCTestGlobalVC.cxx
index 8c51102e5..c091ec47e 100644
--- a/Source/CTest/cmCTestGlobalVC.cxx
+++ b/Source/CTest/cmCTestGlobalVC.cxx
@@ -13,7 +13,7 @@
#include "cmCTest.h"
#include "cmSystemTools.h"
-#include "cmXMLSafe.h"
+#include "cmXMLWriter.h"
#include <cmsys/RegularExpression.hxx>
@@ -91,36 +91,36 @@ void cmCTestGlobalVC::DoModification(PathStatus status,
}
//----------------------------------------------------------------------------
-void cmCTestGlobalVC::WriteXMLDirectory(std::ostream& xml,
+void cmCTestGlobalVC::WriteXMLDirectory(cmXMLWriter& xml,
std::string const& path,
Directory const& dir)
{
const char* slash = path.empty()? "":"/";
- xml << "\t<Directory>\n"
- << "\t\t<Name>" << cmXMLSafe(path) << "</Name>\n";
+ xml.StartElement("Directory");
+ xml.Element("Name", path);
for(Directory::const_iterator fi = dir.begin(); fi != dir.end(); ++fi)
{
std::string full = path + slash + fi->first;
this->WriteXMLEntry(xml, path, fi->first, full, fi->second);
}
- xml << "\t</Directory>\n";
+ xml.EndElement(); // Directory
}
//----------------------------------------------------------------------------
-void cmCTestGlobalVC::WriteXMLGlobal(std::ostream& xml)
+void cmCTestGlobalVC::WriteXMLGlobal(cmXMLWriter& xml)
{
if(!this->NewRevision.empty())
{
- xml << "\t<Revision>" << this->NewRevision << "</Revision>\n";
+ xml.Element("Revision", this->NewRevision);
}
if(!this->OldRevision.empty() && this->OldRevision != this->NewRevision)
{
- xml << "\t<PriorRevision>" << this->OldRevision << "</PriorRevision>\n";
+ xml.Element("PriorRevision", this->OldRevision);
}
}
//----------------------------------------------------------------------------
-bool cmCTestGlobalVC::WriteXMLUpdates(std::ostream& xml)
+bool cmCTestGlobalVC::WriteXMLUpdates(cmXMLWriter& xml)
{
cmCTestLog(this->CTest, HANDLER_OUTPUT,
" Gathering version information (one . per revision):\n"
@@ -132,7 +132,7 @@ bool cmCTestGlobalVC::WriteXMLUpdates(std::ostream& xml)
this->WriteXMLGlobal(xml);
- for(std::map<cmStdString, Directory>::const_iterator
+ for(std::map<std::string, Directory>::const_iterator
di = this->Dirs.begin(); di != this->Dirs.end(); ++di)
{
this->WriteXMLDirectory(xml, di->first, di->second);
diff --git a/Source/CTest/cmCTestGlobalVC.h b/Source/CTest/cmCTestGlobalVC.h
index a648a5982..d0e94109c 100644
--- a/Source/CTest/cmCTestGlobalVC.h
+++ b/Source/CTest/cmCTestGlobalVC.h
@@ -14,6 +14,8 @@
#include "cmCTestVC.h"
+#include <list>
+
/** \class cmCTestGlobalVC
* \brief Base class for handling globally-versioned trees
*
@@ -28,7 +30,7 @@ public:
protected:
// Implement cmCTestVC internal API.
- virtual bool WriteXMLUpdates(std::ostream& xml);
+ virtual bool WriteXMLUpdates(cmXMLWriter& xml);
/** Represent a vcs-reported action for one path in a revision. */
struct Change
@@ -39,8 +41,8 @@ protected:
};
// Update status for files in each directory.
- class Directory: public std::map<cmStdString, File> {};
- std::map<cmStdString, Directory> Dirs;
+ class Directory: public std::map<std::string, File> {};
+ std::map<std::string, Directory> Dirs;
// Old and new repository revisions.
std::string OldRevision;
@@ -60,8 +62,8 @@ protected:
virtual void LoadModifications() = 0;
virtual void LoadRevisions() = 0;
- virtual void WriteXMLGlobal(std::ostream& xml);
- void WriteXMLDirectory(std::ostream& xml, std::string const& path,
+ virtual void WriteXMLGlobal(cmXMLWriter& xml);
+ void WriteXMLDirectory(cmXMLWriter& xml, std::string const& path,
Directory const& dir);
};
diff --git a/Source/CTest/cmCTestHG.cxx b/Source/CTest/cmCTestHG.cxx
index 86a7617f1..0f79d68a0 100644
--- a/Source/CTest/cmCTestHG.cxx
+++ b/Source/CTest/cmCTestHG.cxx
@@ -149,8 +149,8 @@ bool cmCTestHG::UpdateImpl()
{
opts = this->CTest->GetCTestConfiguration("HGUpdateOptions");
}
- std::vector<cmStdString> args = cmSystemTools::ParseArguments(opts.c_str());
- for(std::vector<cmStdString>::const_iterator ai = args.begin();
+ std::vector<std::string> args = cmSystemTools::ParseArguments(opts.c_str());
+ for(std::vector<std::string>::const_iterator ai = args.begin();
ai != args.end(); ++ai)
{
hg_update.push_back(ai->c_str());
@@ -189,10 +189,10 @@ private:
return true;
}
- virtual void StartElement(const char* name, const char** atts)
+ virtual void StartElement(const std::string& name, const char** atts)
{
this->CData.clear();
- if(strcmp(name, "logentry") == 0)
+ if(name == "logentry")
{
this->Rev = Revision();
if(const char* rev = this->FindAttribute(atts, "revision"))
@@ -208,29 +208,29 @@ private:
this->CData.insert(this->CData.end(), data, data+length);
}
- virtual void EndElement(const char* name)
+ virtual void EndElement(const std::string& name)
{
- if(strcmp(name, "logentry") == 0)
+ if(name == "logentry")
{
this->HG->DoRevision(this->Rev, this->Changes);
}
- else if(strcmp(name, "author") == 0 && !this->CData.empty())
+ else if(!this->CData.empty() && name == "author")
{
this->Rev.Author.assign(&this->CData[0], this->CData.size());
}
- else if ( strcmp(name, "email") == 0 && !this->CData.empty())
+ else if(!this->CData.empty() && name == "email")
{
this->Rev.EMail.assign(&this->CData[0], this->CData.size());
}
- else if(strcmp(name, "date") == 0 && !this->CData.empty())
+ else if(!this->CData.empty() && name == "date")
{
this->Rev.Date.assign(&this->CData[0], this->CData.size());
}
- else if(strcmp(name, "msg") == 0 && !this->CData.empty())
+ else if(!this->CData.empty() && name == "msg")
{
this->Rev.Log.assign(&this->CData[0], this->CData.size());
}
- else if(strcmp(name, "files") == 0 && !this->CData.empty())
+ else if(!this->CData.empty() && name == "files")
{
std::vector<std::string> paths = this->SplitCData();
for(unsigned int i = 0; i < paths.size(); ++i)
@@ -242,7 +242,7 @@ private:
this->Changes.push_back(this->CurChange);
}
}
- else if(strcmp(name, "file_adds") == 0 && !this->CData.empty())
+ else if(!this->CData.empty() && name == "file_adds")
{
std::string added_paths(this->CData.begin(), this->CData.end());
for(unsigned int i = 0; i < this->Changes.size(); ++i)
@@ -253,7 +253,7 @@ private:
}
}
}
- else if(strcmp(name, "file_dels") == 0 && !this->CData.empty())
+ else if(!this->CData.empty() && name == "file_dels")
{
std::string added_paths(this->CData.begin(), this->CData.end());
for(unsigned int i = 0; i < this->Changes.size(); ++i)
diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx
index 2e2feb047..3579aee19 100644
--- a/Source/CTest/cmCTestHandlerCommand.cxx
+++ b/Source/CTest/cmCTestHandlerCommand.cxx
@@ -29,6 +29,7 @@ cmCTestHandlerCommand::cmCTestHandlerCommand()
this->Arguments[ct_SUBMIT_INDEX] = "SUBMIT_INDEX";
this->Last = ct_LAST;
this->AppendXML = false;
+ this->Quiet = false;
}
bool cmCTestHandlerCommand
@@ -46,9 +47,9 @@ bool cmCTestHandlerCommand
if(!this->CheckArgumentKeyword(args[i]) &&
!this->CheckArgumentValue(args[i]))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "called with unknown argument \"" << args[i] << "\".";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
@@ -74,7 +75,7 @@ bool cmCTestHandlerCommand
{
this->CTest->SetCTestConfiguration("BuildDirectory",
cmSystemTools::CollapseFullPath(
- this->Values[ct_BUILD]).c_str());
+ this->Values[ct_BUILD]).c_str(), this->Quiet);
}
else
{
@@ -84,7 +85,7 @@ bool cmCTestHandlerCommand
{
this->
CTest->SetCTestConfiguration("BuildDirectory",
- cmSystemTools::CollapseFullPath(bdir).c_str());
+ cmSystemTools::CollapseFullPath(bdir).c_str(), this->Quiet);
}
else
{
@@ -98,13 +99,20 @@ bool cmCTestHandlerCommand
"Set source directory to: " << this->Values[ct_SOURCE] << std::endl);
this->CTest->SetCTestConfiguration("SourceDirectory",
cmSystemTools::CollapseFullPath(
- this->Values[ct_SOURCE]).c_str());
+ this->Values[ct_SOURCE]).c_str(), this->Quiet);
}
else
{
this->CTest->SetCTestConfiguration("SourceDirectory",
cmSystemTools::CollapseFullPath(
- this->Makefile->GetSafeDefinition("CTEST_SOURCE_DIRECTORY")).c_str());
+ this->Makefile->GetSafeDefinition("CTEST_SOURCE_DIRECTORY")).c_str(),
+ this->Quiet);
+ }
+
+ if(const char* changeId =
+ this->Makefile->GetDefinition("CTEST_CHANGE_ID"))
+ {
+ this->CTest->SetCTestConfiguration("ChangeId", changeId, this->Quiet);
}
cmCTestLog(this->CTest, DEBUG, "Initialize handler" << std::endl;);
@@ -137,16 +145,16 @@ bool cmCTestHandlerCommand
}
std::string current_dir = cmSystemTools::GetCurrentWorkingDirectory();
cmSystemTools::ChangeDirectory(
- this->CTest->GetCTestConfiguration("BuildDirectory").c_str());
+ this->CTest->GetCTestConfiguration("BuildDirectory"));
int res = handler->ProcessHandler();
if ( this->Values[ct_RETURN_VALUE] && *this->Values[ct_RETURN_VALUE])
{
- cmOStringStream str;
+ std::ostringstream str;
str << res;
this->Makefile->AddDefinition(
this->Values[ct_RETURN_VALUE], str.str().c_str());
}
- cmSystemTools::ChangeDirectory(current_dir.c_str());
+ cmSystemTools::ChangeDirectory(current_dir);
return true;
}
@@ -160,6 +168,12 @@ bool cmCTestHandlerCommand::CheckArgumentKeyword(std::string const& arg)
this->AppendXML = true;
return true;
}
+ if(arg == "QUIET")
+ {
+ this->ArgumentDoing = ArgumentDoingNone;
+ this->Quiet = true;
+ return true;
+ }
// Check for a keyword in our argument/value table.
for(unsigned int k=0; k < this->Arguments.size(); ++k)
@@ -183,7 +197,7 @@ bool cmCTestHandlerCommand::CheckArgumentValue(std::string const& arg)
unsigned int k = this->ArgumentIndex;
if(this->Values[k])
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Called with more than one value for " << this->Arguments[k];
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
this->ArgumentDoing = ArgumentDoingError;
diff --git a/Source/CTest/cmCTestHandlerCommand.h b/Source/CTest/cmCTestHandlerCommand.h
index 8ef2b8028..87b2cd871 100644
--- a/Source/CTest/cmCTestHandlerCommand.h
+++ b/Source/CTest/cmCTestHandlerCommand.h
@@ -62,6 +62,7 @@ protected:
unsigned int ArgumentIndex;
bool AppendXML;
+ bool Quiet;
std::string ReturnVariable;
std::vector<const char*> Arguments;
diff --git a/Source/CTest/cmCTestLaunch.cxx b/Source/CTest/cmCTestLaunch.cxx
index 9831d0200..749a5beec 100644
--- a/Source/CTest/cmCTestLaunch.cxx
+++ b/Source/CTest/cmCTestLaunch.cxx
@@ -13,12 +13,19 @@
#include "cmGeneratedFileStream.h"
#include "cmSystemTools.h"
-#include "cmXMLSafe.h"
+#include "cmXMLWriter.h"
#include "cmake.h"
#include <cmsys/MD5.h>
#include <cmsys/Process.h>
#include <cmsys/RegularExpression.hxx>
+#include <cmsys/FStream.hxx>
+
+#ifdef _WIN32
+#include <io.h> // for _setmode
+#include <fcntl.h> // for _O_BINARY
+#include <stdio.h> // for std{out,err} and fileno
+#endif
//----------------------------------------------------------------------------
cmCTestLaunch::cmCTestLaunch(int argc, const char* const* argv)
@@ -47,8 +54,8 @@ cmCTestLaunch::~cmCTestLaunch()
cmsysProcess_Delete(this->Process);
if(!this->Passthru)
{
- cmSystemTools::RemoveFile(this->LogOut.c_str());
- cmSystemTools::RemoveFile(this->LogErr.c_str());
+ cmSystemTools::RemoveFile(this->LogOut);
+ cmSystemTools::RemoveFile(this->LogErr);
}
}
@@ -64,7 +71,8 @@ bool cmCTestLaunch::ParseArguments(int argc, const char* const* argv)
DoingTargetName,
DoingTargetType,
DoingBuildDir,
- DoingCount };
+ DoingCount,
+ DoingFilterPrefix };
Doing doing = DoingNone;
int arg0 = 0;
for(int i=1; !arg0 && i < argc; ++i)
@@ -98,6 +106,10 @@ bool cmCTestLaunch::ParseArguments(int argc, const char* const* argv)
{
doing = DoingBuildDir;
}
+ else if(strcmp(arg, "--filter-prefix") == 0)
+ {
+ doing = DoingFilterPrefix;
+ }
else if(doing == DoingOutput)
{
this->OptionOutput = arg;
@@ -132,6 +144,11 @@ bool cmCTestLaunch::ParseArguments(int argc, const char* const* argv)
this->OptionBuildDir = arg;
doing = DoingNone;
}
+ else if(doing == DoingFilterPrefix)
+ {
+ this->OptionFilterPrefix = arg;
+ doing = DoingNone;
+ }
}
// Extract the real command line.
@@ -161,7 +178,7 @@ void cmCTestLaunch::HandleRealArg(const char* arg)
// Expand response file arguments.
if(arg[0] == '@' && cmSystemTools::FileExists(arg+1))
{
- std::ifstream fin(arg+1);
+ cmsys::ifstream fin(arg+1);
std::string line;
while(cmSystemTools::GetLineFromStream(fin, line))
{
@@ -231,8 +248,8 @@ void cmCTestLaunch::RunChild()
cmsysProcess* cp = this->Process;
cmsysProcess_SetCommand(cp, this->RealArgV);
- std::ofstream fout;
- std::ofstream ferr;
+ cmsys::ofstream fout;
+ cmsys::ofstream ferr;
if(this->Passthru)
{
// In passthru mode we just share the output pipes.
@@ -248,6 +265,13 @@ void cmCTestLaunch::RunChild()
std::ios::out | std::ios::binary);
}
+#ifdef _WIN32
+ // Do this so that newline transformation is not done when writing to cout
+ // and cerr below.
+ _setmode(fileno(stdout), _O_BINARY);
+ _setmode(fileno(stderr), _O_BINARY);
+#endif
+
// Run the real command.
cmsysProcess_Execute(cp);
@@ -320,7 +344,7 @@ void cmCTestLaunch::LoadLabels()
cmSystemTools::ConvertToUnixSlashes(source);
// Load the labels file.
- std::ifstream fin(fname.c_str(), std::ios::in | std::ios::binary);
+ cmsys::ifstream fin(fname.c_str(), std::ios::in | std::ios::binary);
if(!fin) { return; }
bool inTarget = true;
bool inSource = false;
@@ -383,35 +407,32 @@ void cmCTestLaunch::WriteXML()
// Use cmGeneratedFileStream to atomically create the report file.
cmGeneratedFileStream fxml(logXML.c_str());
- fxml << "\t<Failure type=\""
- << (this->IsError()? "Error" : "Warning") << "\">\n";
- this->WriteXMLAction(fxml);
- this->WriteXMLCommand(fxml);
- this->WriteXMLResult(fxml);
- this->WriteXMLLabels(fxml);
- fxml << "\t</Failure>\n";
+ cmXMLWriter xml(fxml, 2);
+ xml.StartElement("Failure");
+ xml.Attribute("type", this->IsError() ? "Error" : "Warning");
+ this->WriteXMLAction(xml);
+ this->WriteXMLCommand(xml);
+ this->WriteXMLResult(xml);
+ this->WriteXMLLabels(xml);
+ xml.EndElement(); // Failure
}
//----------------------------------------------------------------------------
-void cmCTestLaunch::WriteXMLAction(std::ostream& fxml)
+void cmCTestLaunch::WriteXMLAction(cmXMLWriter& xml)
{
- fxml << "\t\t<!-- Meta-information about the build action -->\n";
- fxml << "\t\t<Action>\n";
+ xml.Comment("Meta-information about the build action");
+ xml.StartElement("Action");
// TargetName
if(!this->OptionTargetName.empty())
{
- fxml << "\t\t\t<TargetName>"
- << cmXMLSafe(this->OptionTargetName)
- << "</TargetName>\n";
+ xml.Element("TargetName", this->OptionTargetName);
}
// Language
if(!this->OptionLanguage.empty())
{
- fxml << "\t\t\t<Language>"
- << cmXMLSafe(this->OptionLanguage)
- << "</Language>\n";
+ xml.Element("Language", this->OptionLanguage);
}
// SourceFile
@@ -423,24 +444,20 @@ void cmCTestLaunch::WriteXMLAction(std::ostream& fxml)
// If file is in source tree use its relative location.
if(cmSystemTools::FileIsFullPath(this->SourceDir.c_str()) &&
cmSystemTools::FileIsFullPath(source.c_str()) &&
- cmSystemTools::IsSubDirectory(source.c_str(),
- this->SourceDir.c_str()))
+ cmSystemTools::IsSubDirectory(source,
+ this->SourceDir))
{
source = cmSystemTools::RelativePath(this->SourceDir.c_str(),
source.c_str());
}
- fxml << "\t\t\t<SourceFile>"
- << cmXMLSafe(source)
- << "</SourceFile>\n";
+ xml.Element("SourceFile", source);
}
// OutputFile
if(!this->OptionOutput.empty())
{
- fxml << "\t\t\t<OutputFile>"
- << cmXMLSafe(this->OptionOutput)
- << "</OutputFile>\n";
+ xml.Element("OutputFile", this->OptionOutput);
}
// OutputType
@@ -470,112 +487,110 @@ void cmCTestLaunch::WriteXMLAction(std::ostream& fxml)
}
if(outputType)
{
- fxml << "\t\t\t<OutputType>"
- << cmXMLSafe(outputType)
- << "</OutputType>\n";
+ xml.Element("OutputType", outputType);
}
- fxml << "\t\t</Action>\n";
+ xml.EndElement(); // Action
}
//----------------------------------------------------------------------------
-void cmCTestLaunch::WriteXMLCommand(std::ostream& fxml)
+void cmCTestLaunch::WriteXMLCommand(cmXMLWriter& xml)
{
- fxml << "\n";
- fxml << "\t\t<!-- Details of command -->\n";
- fxml << "\t\t<Command>\n";
+ xml.Comment("Details of command");
+ xml.StartElement("Command");
if(!this->CWD.empty())
{
- fxml << "\t\t\t<WorkingDirectory>"
- << cmXMLSafe(this->CWD)
- << "</WorkingDirectory>\n";
+ xml.Element("WorkingDirectory", this->CWD);
}
for(std::vector<std::string>::const_iterator ai = this->RealArgs.begin();
ai != this->RealArgs.end(); ++ai)
{
- fxml << "\t\t\t<Argument>"
- << cmXMLSafe(ai->c_str())
- << "</Argument>\n";
+ xml.Element("Argument", *ai);
}
- fxml << "\t\t</Command>\n";
+ xml.EndElement(); // Command
}
//----------------------------------------------------------------------------
-void cmCTestLaunch::WriteXMLResult(std::ostream& fxml)
+void cmCTestLaunch::WriteXMLResult(cmXMLWriter& xml)
{
- fxml << "\n";
- fxml << "\t\t<!-- Result of command -->\n";
- fxml << "\t\t<Result>\n";
+ xml.Comment("Result of command");
+ xml.StartElement("Result");
// StdOut
- fxml << "\t\t\t<StdOut>";
- this->DumpFileToXML(fxml, this->LogOut);
- fxml << "</StdOut>\n";
+ xml.StartElement("StdOut");
+ this->DumpFileToXML(xml, this->LogOut);
+ xml.EndElement(); // StdOut
// StdErr
- fxml << "\t\t\t<StdErr>";
- this->DumpFileToXML(fxml, this->LogErr);
- fxml << "</StdErr>\n";
+ xml.StartElement("StdErr");
+ this->DumpFileToXML(xml, this->LogErr);
+ xml.EndElement(); // StdErr
// ExitCondition
- fxml << "\t\t\t<ExitCondition>";
+ xml.StartElement("ExitCondition");
cmsysProcess* cp = this->Process;
switch (cmsysProcess_GetState(cp))
{
case cmsysProcess_State_Starting:
- fxml << "No process has been executed"; break;
+ xml.Content("No process has been executed"); break;
case cmsysProcess_State_Executing:
- fxml << "The process is still executing"; break;
+ xml.Content("The process is still executing"); break;
case cmsysProcess_State_Disowned:
- fxml << "Disowned"; break;
+ xml.Content("Disowned"); break;
case cmsysProcess_State_Killed:
- fxml << "Killed by parent"; break;
+ xml.Content("Killed by parent"); break;
case cmsysProcess_State_Expired:
- fxml << "Killed when timeout expired"; break;
+ xml.Content("Killed when timeout expired"); break;
case cmsysProcess_State_Exited:
- fxml << this->ExitCode; break;
+ xml.Content(this->ExitCode); break;
case cmsysProcess_State_Exception:
- fxml << "Terminated abnormally: "
- << cmXMLSafe(cmsysProcess_GetExceptionString(cp)); break;
+ xml.Content("Terminated abnormally: ");
+ xml.Content(cmsysProcess_GetExceptionString(cp)); break;
case cmsysProcess_State_Error:
- fxml << "Error administrating child process: "
- << cmXMLSafe(cmsysProcess_GetErrorString(cp)); break;
+ xml.Content("Error administrating child process: ");
+ xml.Content(cmsysProcess_GetErrorString(cp)); break;
};
- fxml << "</ExitCondition>\n";
+ xml.EndElement(); // ExitCondition
- fxml << "\t\t</Result>\n";
+ xml.EndElement(); // Result
}
//----------------------------------------------------------------------------
-void cmCTestLaunch::WriteXMLLabels(std::ostream& fxml)
+void cmCTestLaunch::WriteXMLLabels(cmXMLWriter& xml)
{
this->LoadLabels();
if(!this->Labels.empty())
{
- fxml << "\n";
- fxml << "\t\t<!-- Interested parties -->\n";
- fxml << "\t\t<Labels>\n";
- for(std::set<cmStdString>::const_iterator li = this->Labels.begin();
+ xml.Comment("Interested parties");
+ xml.StartElement("Labels");
+ for(std::set<std::string>::const_iterator li = this->Labels.begin();
li != this->Labels.end(); ++li)
{
- fxml << "\t\t\t<Label>" << cmXMLSafe(*li) << "</Label>\n";
+ xml.Element("Label", *li);
}
- fxml << "\t\t</Labels>\n";
+ xml.EndElement(); // Labels
}
}
//----------------------------------------------------------------------------
-void cmCTestLaunch::DumpFileToXML(std::ostream& fxml,
+void cmCTestLaunch::DumpFileToXML(cmXMLWriter& xml,
std::string const& fname)
{
- std::ifstream fin(fname.c_str(), std::ios::in | std::ios::binary);
+ cmsys::ifstream fin(fname.c_str(), std::ios::in | std::ios::binary);
std::string line;
const char* sep = "";
+
while(cmSystemTools::GetLineFromStream(fin, line))
{
- fxml << sep << cmXMLSafe(line).Quotes(false);
+ if(MatchesFilterPrefix(line))
+ {
+ continue;
+ }
+
+ xml.Content(sep);
+ xml.Content(line);
sep = "\n";
}
}
@@ -635,7 +650,7 @@ cmCTestLaunch
fname += "Custom";
fname += purpose;
fname += ".txt";
- std::ifstream fin(fname.c_str(), std::ios::in | std::ios::binary);
+ cmsys::ifstream fin(fname.c_str(), std::ios::in | std::ios::binary);
std::string line;
cmsys::RegularExpression rex;
while(cmSystemTools::GetLineFromStream(fin, line))
@@ -654,12 +669,17 @@ bool cmCTestLaunch::ScrapeLog(std::string const& fname)
// Look for log file lines matching warning expressions but not
// suppression expressions.
- std::ifstream fin(fname.c_str(), std::ios::in | std::ios::binary);
+ cmsys::ifstream fin(fname.c_str(), std::ios::in | std::ios::binary);
std::string line;
while(cmSystemTools::GetLineFromStream(fin, line))
{
- if(this->Match(line.c_str(), this->RegexWarning) &&
- !this->Match(line.c_str(), this->RegexWarningSuppress))
+ if(MatchesFilterPrefix(line))
+ {
+ continue;
+ }
+
+ if(this->Match(line, this->RegexWarning) &&
+ !this->Match(line, this->RegexWarningSuppress))
{
return true;
}
@@ -683,6 +703,17 @@ bool cmCTestLaunch::Match(std::string const& line,
}
//----------------------------------------------------------------------------
+bool cmCTestLaunch::MatchesFilterPrefix(std::string const& line) const
+{
+ if(!this->OptionFilterPrefix.empty() && cmSystemTools::StringStartsWith(
+ line.c_str(), this->OptionFilterPrefix.c_str()))
+ {
+ return true;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
int cmCTestLaunch::Main(int argc, const char* const argv[])
{
if(argc == 2)
@@ -697,21 +728,21 @@ int cmCTestLaunch::Main(int argc, const char* const argv[])
//----------------------------------------------------------------------------
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmake.h"
#include <cmsys/auto_ptr.hxx>
void cmCTestLaunch::LoadConfig()
{
cmake cm;
- cmGlobalGenerator gg;
- gg.SetCMakeInstance(&cm);
- cmsys::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator());
- cmMakefile* mf = lg->GetMakefile();
+ cm.SetHomeDirectory("");
+ cm.SetHomeOutputDirectory("");
+ cm.GetCurrentSnapshot().SetDefaultDefinitions();
+ cmGlobalGenerator gg(&cm);
+ cmsys::auto_ptr<cmMakefile> mf(new cmMakefile(&gg, cm.GetCurrentSnapshot()));
std::string fname = this->LogDir;
fname += "CTestLaunchConfig.cmake";
if(cmSystemTools::FileExists(fname.c_str()) &&
- mf->ReadListFile(0, fname.c_str()))
+ mf->ReadListFile(fname.c_str()))
{
this->SourceDir = mf->GetSafeDefinition("CTEST_SOURCE_DIRECTORY");
cmSystemTools::ConvertToUnixSlashes(this->SourceDir);
diff --git a/Source/CTest/cmCTestLaunch.h b/Source/CTest/cmCTestLaunch.h
index 7457e8357..b13e4847b 100644
--- a/Source/CTest/cmCTestLaunch.h
+++ b/Source/CTest/cmCTestLaunch.h
@@ -15,6 +15,8 @@
#include "cmStandardIncludes.h"
#include <cmsys/RegularExpression.hxx>
+class cmXMLWriter;
+
/** \class cmCTestLaunch
* \brief Launcher for make rules to report results for ctest
*
@@ -45,6 +47,7 @@ private:
std::string OptionTargetName;
std::string OptionTargetType;
std::string OptionBuildDir;
+ std::string OptionFilterPrefix;
bool ParseArguments(int argc, const char* const* argv);
// The real command line appearing after launcher arguments.
@@ -72,7 +75,7 @@ private:
bool HaveErr;
// Labels associated with the build rule.
- std::set<cmStdString> Labels;
+ std::set<std::string> Labels;
void LoadLabels();
bool SourceMatches(std::string const& lhs,
std::string const& rhs);
@@ -87,14 +90,15 @@ private:
bool ScrapeLog(std::string const& fname);
bool Match(std::string const& line,
std::vector<cmsys::RegularExpression>& regexps);
+ bool MatchesFilterPrefix(std::string const& line) const;
// Methods to generate the xml fragment.
void WriteXML();
- void WriteXMLAction(std::ostream& fxml);
- void WriteXMLCommand(std::ostream& fxml);
- void WriteXMLResult(std::ostream& fxml);
- void WriteXMLLabels(std::ostream& fxml);
- void DumpFileToXML(std::ostream& fxml, std::string const& fname);
+ void WriteXMLAction(cmXMLWriter& xml);
+ void WriteXMLCommand(cmXMLWriter& xml);
+ void WriteXMLResult(cmXMLWriter& xml);
+ void WriteXMLLabels(cmXMLWriter& xml);
+ void DumpFileToXML(cmXMLWriter& xml, std::string const& fname);
// Configuration
void LoadConfig();
diff --git a/Source/CTest/cmCTestMemCheckCommand.cxx b/Source/CTest/cmCTestMemCheckCommand.cxx
index 535c9934f..b379d32af 100644
--- a/Source/CTest/cmCTestMemCheckCommand.cxx
+++ b/Source/CTest/cmCTestMemCheckCommand.cxx
@@ -21,12 +21,20 @@ cmCTestGenericHandler* cmCTestMemCheckCommand::InitializeActualHandler()
= this->CTest->GetInitializedHandler("memcheck");
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
- "MemoryCheckCommand", "CTEST_MEMORYCHECK_COMMAND");
+ "MemoryCheckType", "CTEST_MEMORYCHECK_TYPE", this->Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
- "MemoryCheckCommandOptions", "CTEST_MEMORYCHECK_COMMAND_OPTIONS");
+ "MemoryCheckSanitizerOptions", "CTEST_MEMORYCHECK_SANITIZER_OPTIONS",
+ this->Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
- "MemoryCheckSuppressionFile", "CTEST_MEMORYCHECK_SUPPRESSIONS_FILE");
+ "MemoryCheckCommand", "CTEST_MEMORYCHECK_COMMAND", this->Quiet);
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "MemoryCheckCommandOptions", "CTEST_MEMORYCHECK_COMMAND_OPTIONS",
+ this->Quiet);
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "MemoryCheckSuppressionFile", "CTEST_MEMORYCHECK_SUPPRESSIONS_FILE",
+ this->Quiet);
+ handler->SetQuiet(this->Quiet);
return handler;
}
diff --git a/Source/CTest/cmCTestMemCheckCommand.h b/Source/CTest/cmCTestMemCheckCommand.h
index 6db47aec8..e239d4642 100644
--- a/Source/CTest/cmCTestMemCheckCommand.h
+++ b/Source/CTest/cmCTestMemCheckCommand.h
@@ -41,41 +41,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "ctest_memcheck";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Run tests with a dynamic analysis tool.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " ctest_memcheck([BUILD build_dir] [RETURN_VALUE res] [APPEND]\n"
- " [START start number] [END end number]\n"
- " [STRIDE stride number] [EXCLUDE exclude regex ]\n"
- " [INCLUDE include regex] \n"
- " [EXCLUDE_LABEL exclude regex] \n"
- " [INCLUDE_LABEL label regex] \n"
- " [PARALLEL_LEVEL level] )\n"
- "Tests the given build directory and stores results in MemCheck.xml. "
- "The second argument is a variable that will hold value. Optionally, "
- "you can specify the starting test number START, the ending test number "
- "END, the number of tests to skip between each test STRIDE, a regular "
- "expression for tests to run INCLUDE, or a regular expression for tests "
- "not to run EXCLUDE. EXCLUDE_LABEL and INCLUDE_LABEL are regular "
- "expressions for tests to be included or excluded by the test "
- "property LABEL. PARALLEL_LEVEL should be set to a positive number "
- "representing the number of tests to be run in parallel."
- "\n"
- CTEST_COMMAND_APPEND_OPTION_DOCS;
- }
+ virtual std::string GetName() const { return "ctest_memcheck";}
cmTypeMacro(cmCTestMemCheckCommand, cmCTestTestCommand);
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index 3ae2ac6a7..acf527acd 100644
--- a/Source/CTest/cmCTestMemCheckHandler.cxx
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -18,8 +18,10 @@
#include <cmsys/Process.h>
#include <cmsys/RegularExpression.hxx>
#include <cmsys/Base64.h>
+#include <cmsys/Glob.hxx>
+#include <cmsys/FStream.hxx>
#include "cmMakefile.h"
-#include "cmXMLSafe.h"
+#include "cmXMLWriter.h"
#include <stdlib.h>
#include <math.h>
@@ -43,42 +45,48 @@ static CatToErrorType cmCTestMemCheckBoundsChecker[] = {
{0,0}
};
+static void xmlReportError(int line, const char* msg, void* data)
+{
+ cmCTest* ctest = (cmCTest*)data;
+ cmCTestLog(ctest, ERROR_MESSAGE,
+ "Error parsing XML in stream at line "
+ << line << ": " << msg << std::endl);
+}
+
// parse the xml file containing the results of last BoundsChecker run
class cmBoundsCheckerParser : public cmXMLParser
{
public:
- cmBoundsCheckerParser(cmCTest* c) { this->CTest = c;}
- void StartElement(const char* name, const char** atts)
+ cmBoundsCheckerParser(cmCTest* c)
{
- if(strcmp(name, "MemoryLeak") == 0)
- {
- this->Errors.push_back(cmCTestMemCheckHandler::MLK);
- }
- if(strcmp(name, "ResourceLeak") == 0)
+ this->CTest = c;
+ this->SetErrorCallback(xmlReportError, (void*)c);
+ }
+ void StartElement(const std::string& name, const char** atts)
+ {
+ if(name == "MemoryLeak" ||
+ name == "ResourceLeak")
{
this->Errors.push_back(cmCTestMemCheckHandler::MLK);
}
- if(strcmp(name, "Error") == 0)
- {
- this->ParseError(atts);
- }
- if(strcmp(name, "Dangling Pointer") == 0)
+ else if(name == "Error" ||
+ name == "Dangling Pointer")
{
this->ParseError(atts);
}
// Create the log
- cmOStringStream ostr;
+ std::ostringstream ostr;
ostr << name << ":\n";
int i = 0;
for(; atts[i] != 0; i+=2)
{
- ostr << " " << cmXMLSafe(atts[i])
- << " - " << cmXMLSafe(atts[i+1]) << "\n";
+ ostr << " " << atts[i]
+ << " - " << atts[i+1] << "\n";
}
ostr << "\n";
this->Log += ostr.str();
}
- void EndElement(const char* )
+ void EndElement(const std::string& )
{
}
@@ -129,60 +137,7 @@ public:
#define BOUNDS_CHECKER_MARKER \
"******######*****Begin BOUNDS CHECKER XML******######******"
-//----------------------------------------------------------------------
-static const char* cmCTestMemCheckResultStrings[] = {
- "ABR",
- "ABW",
- "ABWL",
- "COR",
- "EXU",
- "FFM",
- "FIM",
- "FMM",
- "FMR",
- "FMW",
- "FUM",
- "IPR",
- "IPW",
- "MAF",
- "MLK",
- "MPK",
- "NPR",
- "ODS",
- "PAR",
- "PLK",
- "UMC",
- "UMR",
- 0
-};
-
-//----------------------------------------------------------------------
-static const char* cmCTestMemCheckResultLongStrings[] = {
- "Threading Problem",
- "ABW",
- "ABWL",
- "COR",
- "EXU",
- "FFM",
- "FIM",
- "Mismatched deallocation",
- "FMR",
- "FMW",
- "FUM",
- "IPR",
- "IPW",
- "MAF",
- "Memory Leak",
- "Potential Memory Leak",
- "NPR",
- "ODS",
- "Invalid syscall param",
- "PLK",
- "Uninitialized Memory Conditional",
- "Uninitialized Memory Read",
- 0
-};
//----------------------------------------------------------------------
@@ -191,12 +146,14 @@ cmCTestMemCheckHandler::cmCTestMemCheckHandler()
this->MemCheck = true;
this->CustomMaximumPassedTestOutputSize = 0;
this->CustomMaximumFailedTestOutputSize = 0;
+ this->LogWithPID = false;
}
//----------------------------------------------------------------------
void cmCTestMemCheckHandler::Initialize()
{
this->Superclass::Initialize();
+ this->LogWithPID = false;
this->CustomMaximumPassedTestOutputSize = 0;
this->CustomMaximumFailedTestOutputSize = 0;
this->MemoryTester = "";
@@ -204,12 +161,6 @@ void cmCTestMemCheckHandler::Initialize()
this->MemoryTesterOptions.clear();
this->MemoryTesterStyle = UNKNOWN;
this->MemoryTesterOutputFile = "";
- int cc;
- for ( cc = 0; cc < NO_MEMORY_FAULT; cc ++ )
- {
- this->MemoryTesterGlobalResults[cc] = 0;
- }
-
}
//----------------------------------------------------------------------
@@ -245,18 +196,18 @@ int cmCTestMemCheckHandler::PostProcessHandler()
void cmCTestMemCheckHandler::GenerateTestCommand(
std::vector<std::string>& args, int test)
{
- std::vector<cmStdString>::size_type pp;
- cmStdString index;
- cmOStringStream stream;
+ std::vector<std::string>::size_type pp;
+ std::string index;
+ std::ostringstream stream;
std::string memcheckcommand
= cmSystemTools::ConvertToOutputPath(this->MemoryTester.c_str());
stream << test;
index = stream.str();
for ( pp = 0; pp < this->MemoryTesterDynamicOptions.size(); pp ++ )
{
- cmStdString arg = this->MemoryTesterDynamicOptions[pp];
- cmStdString::size_type pos = arg.find("??");
- if (pos != cmStdString::npos)
+ std::string arg = this->MemoryTesterDynamicOptions[pp];
+ std::string::size_type pos = arg.find("??");
+ if (pos != std::string::npos)
{
arg.replace(pos, 2, index);
}
@@ -265,15 +216,122 @@ void cmCTestMemCheckHandler::GenerateTestCommand(
memcheckcommand += arg;
memcheckcommand += "\"";
}
+ // Create a copy of the memory tester environment variable.
+ // This is used for memory testing programs that pass options
+ // via environment varaibles.
+ std::string memTesterEnvironmentVariable =
+ this->MemoryTesterEnvironmentVariable;
for ( pp = 0; pp < this->MemoryTesterOptions.size(); pp ++ )
{
- args.push_back(this->MemoryTesterOptions[pp]);
- memcheckcommand += " \"";
- memcheckcommand += this->MemoryTesterOptions[pp];
- memcheckcommand += "\"";
+ if(!memTesterEnvironmentVariable.empty())
+ {
+ // If we are using env to pass options, append all the options to
+ // this string with space separation.
+ memTesterEnvironmentVariable += " " + this->MemoryTesterOptions[pp];
+ }
+ // for regular options just add them to args and memcheckcommand
+ // which is just used for display
+ else
+ {
+ args.push_back(this->MemoryTesterOptions[pp]);
+ memcheckcommand += " \"";
+ memcheckcommand += this->MemoryTesterOptions[pp];
+ memcheckcommand += "\"";
+ }
+ }
+ // if this is an env option type, then add the env string as a single
+ // argument.
+ if(!memTesterEnvironmentVariable.empty())
+ {
+ std::string::size_type pos = memTesterEnvironmentVariable.find("??");
+ if (pos != std::string::npos)
+ {
+ memTesterEnvironmentVariable.replace(pos, 2, index);
+ }
+ memcheckcommand += " " + memTesterEnvironmentVariable;
+ args.push_back(memTesterEnvironmentVariable);
+ }
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Memory check command: " << memcheckcommand << std::endl, this->Quiet);
+}
+
+//----------------------------------------------------------------------
+void cmCTestMemCheckHandler::InitializeResultsVectors()
+{
+ // fill these members
+// cmsys::vector<std::string> ResultStrings;
+// cmsys::vector<std::string> ResultStringsLong;
+// cmsys::vector<int> GlobalResults;
+ this->ResultStringsLong.clear();
+ this->ResultStrings.clear();
+ this->GlobalResults.clear();
+ // If we are working with style checkers that dynamically fill
+ // the results strings then return.
+ if(this->MemoryTesterStyle > cmCTestMemCheckHandler::BOUNDS_CHECKER)
+ {
+ return;
+ }
+
+ // define the standard set of errors
+ //----------------------------------------------------------------------
+ static const char* cmCTestMemCheckResultStrings[] = {
+ "ABR",
+ "ABW",
+ "ABWL",
+ "COR",
+ "EXU",
+ "FFM",
+ "FIM",
+ "FMM",
+ "FMR",
+ "FMW",
+ "FUM",
+ "IPR",
+ "IPW",
+ "MAF",
+ "MLK",
+ "MPK",
+ "NPR",
+ "ODS",
+ "PAR",
+ "PLK",
+ "UMC",
+ "UMR",
+ 0
+ };
+//----------------------------------------------------------------------
+ static const char* cmCTestMemCheckResultLongStrings[] = {
+ "Threading Problem",
+ "ABW",
+ "ABWL",
+ "COR",
+ "EXU",
+ "FFM",
+ "FIM",
+ "Mismatched deallocation",
+ "FMR",
+ "FMW",
+ "FUM",
+ "IPR",
+ "IPW",
+ "MAF",
+ "Memory Leak",
+ "Potential Memory Leak",
+ "NPR",
+ "ODS",
+ "Invalid syscall param",
+ "PLK",
+ "Uninitialized Memory Conditional",
+ "Uninitialized Memory Read",
+ 0
+ };
+ this->GlobalResults.clear();
+ for(int i =0; cmCTestMemCheckResultStrings[i] != 0; ++i)
+ {
+ this->ResultStrings.push_back(cmCTestMemCheckResultStrings[i]);
+ this->ResultStringsLong.push_back(cmCTestMemCheckResultLongStrings[i]);
+ this->GlobalResults.push_back(0);
}
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Memory check command: "
- << memcheckcommand << std::endl);
}
//----------------------------------------------------------------------
@@ -288,49 +346,60 @@ void cmCTestMemCheckHandler::PopulateCustomVectors(cmMakefile *mf)
this->CTest->PopulateCustomVector(mf,
"CTEST_CUSTOM_MEMCHECK_IGNORE",
this->CustomTestsIgnore);
+ std::string cmake = cmSystemTools::GetCMakeCommand();
+ this->CTest->SetCTestConfiguration("CMakeCommand", cmake.c_str(),
+ this->Quiet);
}
//----------------------------------------------------------------------
-void cmCTestMemCheckHandler::GenerateDartOutput(std::ostream& os)
+void cmCTestMemCheckHandler::GenerateDartOutput(cmXMLWriter& xml)
{
if ( !this->CTest->GetProduceXML() )
{
return;
}
-
- this->CTest->StartXML(os, this->AppendXML);
- os << "<DynamicAnalysis Checker=\"";
+ this->CTest->StartXML(xml, this->AppendXML);
+ xml.StartElement("DynamicAnalysis");
switch ( this->MemoryTesterStyle )
{
case cmCTestMemCheckHandler::VALGRIND:
- os << "Valgrind";
+ xml.Attribute("Checker", "Valgrind");
break;
case cmCTestMemCheckHandler::PURIFY:
- os << "Purify";
+ xml.Attribute("Checker", "Purify");
break;
case cmCTestMemCheckHandler::BOUNDS_CHECKER:
- os << "BoundsChecker";
+ xml.Attribute("Checker", "BoundsChecker");
+ break;
+ case cmCTestMemCheckHandler::ADDRESS_SANITIZER:
+ xml.Attribute("Checker", "AddressSanitizer");
+ break;
+ case cmCTestMemCheckHandler::THREAD_SANITIZER:
+ xml.Attribute("Checker", "ThreadSanitizer");
+ break;
+ case cmCTestMemCheckHandler::MEMORY_SANITIZER:
+ xml.Attribute("Checker", "MemorySanitizer");
+ break;
+ case cmCTestMemCheckHandler::UB_SANITIZER:
+ xml.Attribute("Checker", "UndefinedBehaviorSanitizer");
break;
default:
- os << "Unknown";
+ xml.Attribute("Checker", "Unknown");
}
- os << "\">" << std::endl;
- os << "\t<StartDateTime>" << this->StartTest << "</StartDateTime>\n"
- << "\t<StartTestTime>" << this->StartTestTime << "</StartTestTime>\n"
- << "\t<TestList>\n";
+ xml.Element("StartDateTime", this->StartTest);
+ xml.Element("StartTestTime", this->StartTestTime);
+ xml.StartElement("TestList");
cmCTestMemCheckHandler::TestResultsVector::size_type cc;
for ( cc = 0; cc < this->TestResults.size(); cc ++ )
{
cmCTestTestResult *result = &this->TestResults[cc];
std::string testPath = result->Path + "/" + result->Name;
- os << "\t\t<Test>" << cmXMLSafe(
- this->CTest->GetShortPathToFile(testPath.c_str()))
- << "</Test>" << std::endl;
+ xml.Element("Test", this->CTest->GetShortPathToFile(testPath.c_str()));
}
- os << "\t</TestList>\n";
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
- "-- Processing memory checking output: ");
+ xml.EndElement(); // TestList
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ "-- Processing memory checking output: ", this->Quiet);
size_t total = this->TestResults.size();
size_t step = total / 10;
size_t current = 0;
@@ -338,8 +407,7 @@ void cmCTestMemCheckHandler::GenerateDartOutput(std::ostream& os)
{
cmCTestTestResult *result = &this->TestResults[cc];
std::string memcheckstr;
- int memcheckresults[cmCTestMemCheckHandler::NO_MEMORY_FAULT];
- int kk;
+ std::vector<int> memcheckresults(this->ResultStrings.size(), 0);
bool res = this->ProcessMemCheckOutput(result->Output, memcheckstr,
memcheckresults);
if ( res && result->Status == cmCTestMemCheckHandler::COMPLETED )
@@ -348,97 +416,97 @@ void cmCTestMemCheckHandler::GenerateDartOutput(std::ostream& os)
}
this->CleanTestOutput(memcheckstr,
static_cast<size_t>(this->CustomMaximumFailedTestOutputSize));
- this->WriteTestResultHeader(os, result);
- os << "\t\t<Results>" << std::endl;
- for ( kk = 0; cmCTestMemCheckResultLongStrings[kk]; kk ++ )
+ this->WriteTestResultHeader(xml, result);
+ xml.StartElement("Results");
+ for(std::vector<int>::size_type kk = 0;
+ kk < memcheckresults.size(); ++kk)
{
if ( memcheckresults[kk] )
{
- os << "\t\t\t<Defect type=\"" << cmCTestMemCheckResultLongStrings[kk]
- << "\">"
- << memcheckresults[kk]
- << "</Defect>" << std::endl;
+ xml.StartElement("Defect");
+ xml.Attribute("type", this->ResultStringsLong[kk]);
+ xml.Content(memcheckresults[kk]);
+ xml.EndElement(); // Defect
}
- this->MemoryTesterGlobalResults[kk] += memcheckresults[kk];
+ this->GlobalResults[kk] += memcheckresults[kk];
}
+ xml.EndElement(); // Results
- std::string logTag;
+ xml.StartElement("Log");
if(this->CTest->ShouldCompressMemCheckOutput())
{
this->CTest->CompressString(memcheckstr);
- logTag = "\t<Log compression=\"gzip\" encoding=\"base64\">\n";
- }
- else
- {
- logTag = "\t<Log>\n";
+ xml.Attribute("compression", "gzip");
+ xml.Attribute("encoding", "base64");
}
+ xml.Content(memcheckstr);
+ xml.EndElement(); // Log
- os
- << "\t\t</Results>\n"
- << logTag << cmXMLSafe(memcheckstr) << std::endl
- << "\t</Log>\n";
- this->WriteTestResultFooter(os, result);
+ this->WriteTestResultFooter(xml, result);
if ( current < cc )
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT, "#" << std::flush);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "#" << std::flush,
+ this->Quiet);
current += step;
}
}
- cmCTestLog(this->CTest, HANDLER_OUTPUT, std::endl);
- cmCTestLog(this->CTest, HANDLER_OUTPUT, "Memory checking results:"
- << std::endl);
- os << "\t<DefectList>" << std::endl;
- for ( cc = 0; cmCTestMemCheckResultStrings[cc]; cc ++ )
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, std::endl, this->Quiet);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "Memory checking results:"
+ << std::endl, this->Quiet);
+ xml.StartElement("DefectList");
+ for ( cc = 0; cc < this->GlobalResults.size(); cc ++ )
{
- if ( this->MemoryTesterGlobalResults[cc] )
+ if ( this->GlobalResults[cc] )
{
#ifdef cerr
# undef cerr
#endif
std::cerr.width(35);
#define cerr no_cerr
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
- cmCTestMemCheckResultLongStrings[cc] << " - "
- << this->MemoryTesterGlobalResults[cc] << std::endl);
- os << "\t\t<Defect Type=\"" << cmCTestMemCheckResultLongStrings[cc]
- << "\"/>" << std::endl;
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ this->ResultStringsLong[cc] << " - "
+ << this->GlobalResults[cc] << std::endl, this->Quiet);
+ xml.StartElement("Defect");
+ xml.Attribute("Type", this->ResultStringsLong[cc]);
+ xml.EndElement();
}
}
- os << "\t</DefectList>" << std::endl;
-
- os << "\t<EndDateTime>" << this->EndTest << "</EndDateTime>" << std::endl;
- os << "\t<EndTestTime>" << this->EndTestTime
- << "</EndTestTime>" << std::endl;
- os << "<ElapsedMinutes>"
- << static_cast<int>(this->ElapsedTestingTime/6)/10.0
- << "</ElapsedMinutes>\n";
-
- os << "</DynamicAnalysis>" << std::endl;
- this->CTest->EndXML(os);
+ xml.EndElement(); // DefectList
+ xml.Element("EndDateTime", this->EndTest);
+ xml.Element("EndTestTime", this->EndTestTime);
+ xml.Element("ElapsedMinutes",
+ static_cast<int>(this->ElapsedTestingTime/6)/10.0);
+ xml.EndElement(); // DynamicAnalysis
+ this->CTest->EndXML(xml);
}
//----------------------------------------------------------------------
bool cmCTestMemCheckHandler::InitializeMemoryChecking()
{
+ this->MemoryTesterEnvironmentVariable = "";
+ this->MemoryTester = "";
// Setup the command
if ( cmSystemTools::FileExists(this->CTest->GetCTestConfiguration(
"MemoryCheckCommand").c_str()) )
{
this->MemoryTester
= this->CTest->GetCTestConfiguration("MemoryCheckCommand").c_str();
-
+ std::string testerName =
+ cmSystemTools::GetFilenameName(this->MemoryTester);
// determine the checker type
- if ( this->MemoryTester.find("valgrind") != std::string::npos )
+ if ( testerName.find("valgrind") != std::string::npos ||
+ this->CTest->GetCTestConfiguration("MemoryCheckType")
+ == "Valgrind")
{
this->MemoryTesterStyle = cmCTestMemCheckHandler::VALGRIND;
}
- else if ( this->MemoryTester.find("purify") != std::string::npos )
+ else if ( testerName.find("purify") != std::string::npos )
{
this->MemoryTesterStyle = cmCTestMemCheckHandler::PURIFY;
}
- else if ( this->MemoryTester.find("BC") != std::string::npos )
+ else if ( testerName.find("BC") != std::string::npos )
{
this->MemoryTesterStyle = cmCTestMemCheckHandler::BOUNDS_CHECKER;
}
@@ -468,12 +536,62 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
= this->CTest->GetCTestConfiguration("BoundsCheckerCommand").c_str();
this->MemoryTesterStyle = cmCTestMemCheckHandler::BOUNDS_CHECKER;
}
- else
+ if ( this->CTest->GetCTestConfiguration("MemoryCheckType")
+ == "AddressSanitizer")
+ {
+ this->MemoryTester
+ = this->CTest->GetCTestConfiguration("CMakeCommand").c_str();
+ this->MemoryTesterStyle = cmCTestMemCheckHandler::ADDRESS_SANITIZER;
+ this->LogWithPID = true; // even if we give the log file the pid is added
+ }
+ if ( this->CTest->GetCTestConfiguration("MemoryCheckType")
+ == "ThreadSanitizer")
{
- cmCTestLog(this->CTest, WARNING,
- "Memory checker (MemoryCheckCommand) "
- "not set, or cannot find the specified program."
- << std::endl);
+ this->MemoryTester
+ = this->CTest->GetCTestConfiguration("CMakeCommand").c_str();
+ this->MemoryTesterStyle = cmCTestMemCheckHandler::THREAD_SANITIZER;
+ this->LogWithPID = true; // even if we give the log file the pid is added
+ }
+ if ( this->CTest->GetCTestConfiguration("MemoryCheckType")
+ == "MemorySanitizer")
+ {
+ this->MemoryTester
+ = this->CTest->GetCTestConfiguration("CMakeCommand").c_str();
+ this->MemoryTesterStyle = cmCTestMemCheckHandler::MEMORY_SANITIZER;
+ this->LogWithPID = true; // even if we give the log file the pid is added
+ }
+ if ( this->CTest->GetCTestConfiguration("MemoryCheckType")
+ == "UndefinedBehaviorSanitizer")
+ {
+ this->MemoryTester
+ = this->CTest->GetCTestConfiguration("CMakeCommand").c_str();
+ this->MemoryTesterStyle = cmCTestMemCheckHandler::UB_SANITIZER;
+ this->LogWithPID = true; // even if we give the log file the pid is added
+ }
+ // Check the MemoryCheckType
+ if(this->MemoryTesterStyle == cmCTestMemCheckHandler::UNKNOWN)
+ {
+ std::string checkType =
+ this->CTest->GetCTestConfiguration("MemoryCheckType");
+ if(checkType == "Purify")
+ {
+ this->MemoryTesterStyle = cmCTestMemCheckHandler::PURIFY;
+ }
+ else if(checkType == "BoundsChecker")
+ {
+ this->MemoryTesterStyle = cmCTestMemCheckHandler::BOUNDS_CHECKER;
+ }
+ else if(checkType == "Valgrind")
+ {
+ this->MemoryTesterStyle = cmCTestMemCheckHandler::VALGRIND;
+ }
+ }
+ if(this->MemoryTester.empty())
+ {
+ cmCTestOptionalLog(this->CTest, WARNING,
+ "Memory checker (MemoryCheckCommand) "
+ "not set, or cannot find the specified program."
+ << std::endl, this->Quiet);
return false;
}
@@ -519,7 +637,7 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Cannot find memory checker suppression file: "
<< this->CTest->GetCTestConfiguration(
- "MemoryCheckSuppressionFile").c_str() << std::endl);
+ "MemoryCheckSuppressionFile") << std::endl);
return false;
}
std::string suppressions = "--suppressions="
@@ -572,31 +690,67 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
this->MemoryTesterOptions.push_back("/M");
break;
}
+ // these are almost the same but the env var used is different
+ case cmCTestMemCheckHandler::ADDRESS_SANITIZER:
+ case cmCTestMemCheckHandler::THREAD_SANITIZER:
+ case cmCTestMemCheckHandler::MEMORY_SANITIZER:
+ case cmCTestMemCheckHandler::UB_SANITIZER:
+ {
+ // To pass arguments to ThreadSanitizer the environment variable
+ // TSAN_OPTIONS is used. This is done with the cmake -E env command.
+ // The MemoryTesterDynamicOptions is setup with the -E env
+ // Then the MemoryTesterEnvironmentVariable gets the
+ // TSAN_OPTIONS string with the log_path in it.
+ this->MemoryTesterDynamicOptions.push_back("-E");
+ this->MemoryTesterDynamicOptions.push_back("env");
+ std::string envVar;
+ std::string extraOptions =
+ this->CTest->GetCTestConfiguration("MemoryCheckSanitizerOptions");
+ if(this->MemoryTesterStyle == cmCTestMemCheckHandler::ADDRESS_SANITIZER)
+ {
+ envVar = "ASAN_OPTIONS";
+ extraOptions += " detect_leaks=1";
+ }
+ else if(this->MemoryTesterStyle ==
+ cmCTestMemCheckHandler::THREAD_SANITIZER)
+ {
+ envVar = "TSAN_OPTIONS";
+ }
+ else if(this->MemoryTesterStyle ==
+ cmCTestMemCheckHandler::MEMORY_SANITIZER)
+ {
+ envVar = "MSAN_OPTIONS";
+ }
+ else if(this->MemoryTesterStyle == cmCTestMemCheckHandler::UB_SANITIZER)
+ {
+ envVar = "UBSAN_OPTIONS";
+ }
+ std::string outputFile = envVar + "=log_path=\""
+ + this->MemoryTesterOutputFile + "\" ";
+ this->MemoryTesterEnvironmentVariable = outputFile + extraOptions;
+ break;
+ }
default:
cmCTestLog(this->CTest, ERROR_MESSAGE,
- "Do not understand memory checker: " << this->MemoryTester.c_str()
+ "Do not understand memory checker: " << this->MemoryTester
<< std::endl);
return false;
}
- std::vector<cmStdString>::size_type cc;
- for ( cc = 0; cmCTestMemCheckResultStrings[cc]; cc ++ )
- {
- this->MemoryTesterGlobalResults[cc] = 0;
- }
+ this->InitializeResultsVectors();
+ // std::vector<std::string>::size_type cc;
+ // for ( cc = 0; cmCTestMemCheckResultStrings[cc]; cc ++ )
+ // {
+ // this->MemoryTesterGlobalResults[cc] = 0;
+ // }
return true;
}
//----------------------------------------------------------------------
-bool cmCTestMemCheckHandler::ProcessMemCheckOutput(const std::string& str,
- std::string& log, int* results)
+bool cmCTestMemCheckHandler::
+ProcessMemCheckOutput(const std::string& str,
+ std::string& log, std::vector<int>& results)
{
- std::string::size_type cc;
- for ( cc = 0; cc < cmCTestMemCheckHandler::NO_MEMORY_FAULT; cc ++ )
- {
- results[cc] = 0;
- }
-
if ( this->MemoryTesterStyle == cmCTestMemCheckHandler::VALGRIND )
{
return this->ProcessMemCheckValgrindOutput(str, log, results);
@@ -606,6 +760,17 @@ bool cmCTestMemCheckHandler::ProcessMemCheckOutput(const std::string& str,
return this->ProcessMemCheckPurifyOutput(str, log, results);
}
else if ( this->MemoryTesterStyle ==
+ cmCTestMemCheckHandler::ADDRESS_SANITIZER ||
+ this->MemoryTesterStyle ==
+ cmCTestMemCheckHandler::THREAD_SANITIZER ||
+ this->MemoryTesterStyle ==
+ cmCTestMemCheckHandler::MEMORY_SANITIZER ||
+ this->MemoryTesterStyle ==
+ cmCTestMemCheckHandler::UB_SANITIZER)
+ {
+ return this->ProcessMemCheckSanitizerOutput(str, log, results);
+ }
+ else if ( this->MemoryTesterStyle ==
cmCTestMemCheckHandler::BOUNDS_CHECKER )
{
return this->ProcessMemCheckBoundsCheckerOutput(str, log, results);
@@ -616,41 +781,120 @@ bool cmCTestMemCheckHandler::ProcessMemCheckOutput(const std::string& str,
log.append("None that I know");
log = str;
}
-
-
return true;
}
+std::vector<int>::size_type cmCTestMemCheckHandler::FindOrAddWarning(
+ const std::string& warning)
+{
+ for(std::vector<std::string>::size_type i =0;
+ i < this->ResultStrings.size(); ++i)
+ {
+ if(this->ResultStrings[i] == warning)
+ {
+ return i;
+ }
+ }
+ this->GlobalResults.push_back(0); // this must stay the same size
+ this->ResultStrings.push_back(warning);
+ this->ResultStringsLong.push_back(warning);
+ return this->ResultStrings.size()-1;
+}
+//----------------------------------------------------------------------
+bool cmCTestMemCheckHandler::ProcessMemCheckSanitizerOutput(
+ const std::string& str, std::string& log,
+ std::vector<int>& result)
+{
+ std::string regex;
+ switch ( this->MemoryTesterStyle )
+ {
+ case cmCTestMemCheckHandler::ADDRESS_SANITIZER:
+ regex = "ERROR: AddressSanitizer: (.*) on.*";
+ break;
+ case cmCTestMemCheckHandler::THREAD_SANITIZER:
+ regex = "WARNING: ThreadSanitizer: (.*) \\(pid=.*\\)";
+ break;
+ case cmCTestMemCheckHandler::MEMORY_SANITIZER:
+ regex = "WARNING: MemorySanitizer: (.*)";
+ break;
+ case cmCTestMemCheckHandler::UB_SANITIZER:
+ regex = "runtime error: (.*)";
+ break;
+ default:
+ break;
+ }
+ cmsys::RegularExpression sanitizerWarning(regex);
+ cmsys::RegularExpression leakWarning("(Direct|Indirect) leak of .*");
+ int defects = 0;
+ std::vector<std::string> lines;
+ cmSystemTools::Split(str.c_str(), lines);
+ std::ostringstream ostr;
+ log = "";
+ for( std::vector<std::string>::iterator i = lines.begin();
+ i != lines.end(); ++i)
+ {
+ std::string resultFound;
+ if(leakWarning.find(*i))
+ {
+ resultFound = leakWarning.match(1)+" leak";
+ }
+ else if (sanitizerWarning.find(*i))
+ {
+ resultFound = sanitizerWarning.match(1);
+ }
+ if(!resultFound.empty())
+ {
+ std::vector<int>::size_type idx = this->FindOrAddWarning(resultFound);
+ if(result.empty() || idx > result.size()-1)
+ {
+ result.push_back(1);
+ }
+ else
+ {
+ result[idx]++;
+ }
+ defects++;
+ ostr << "<b>" << this->ResultStrings[idx] << "</b> ";
+ }
+ ostr << *i << std::endl;
+ }
+ log = ostr.str();
+ if(defects)
+ {
+ return false;
+ }
+ return true;
+}
//----------------------------------------------------------------------
bool cmCTestMemCheckHandler::ProcessMemCheckPurifyOutput(
const std::string& str, std::string& log,
- int* results)
+ std::vector<int>& results)
{
- std::vector<cmStdString> lines;
+ std::vector<std::string> lines;
cmSystemTools::Split(str.c_str(), lines);
- cmOStringStream ostr;
+ std::ostringstream ostr;
log = "";
cmsys::RegularExpression pfW("^\\[[WEI]\\] ([A-Z][A-Z][A-Z][A-Z]*): ");
int defects = 0;
- for( std::vector<cmStdString>::iterator i = lines.begin();
+ for( std::vector<std::string>::iterator i = lines.begin();
i != lines.end(); ++i)
{
- int failure = cmCTestMemCheckHandler::NO_MEMORY_FAULT;
+ std::vector<int>::size_type failure = this->ResultStrings.size();
if ( pfW.find(*i) )
{
- int cc;
- for ( cc = 0; cc < cmCTestMemCheckHandler::NO_MEMORY_FAULT; cc ++ )
+ std::vector<int>::size_type cc;
+ for ( cc = 0; cc < this->ResultStrings.size(); cc ++ )
{
- if ( pfW.match(1) == cmCTestMemCheckResultStrings[cc] )
+ if ( pfW.match(1) == this->ResultStrings[cc] )
{
failure = cc;
break;
}
}
- if ( cc == cmCTestMemCheckHandler::NO_MEMORY_FAULT )
+ if ( cc == this->ResultStrings.size() )
{
cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown Purify memory fault: "
<< pfW.match(1) << std::endl);
@@ -658,13 +902,13 @@ bool cmCTestMemCheckHandler::ProcessMemCheckPurifyOutput(
<< std::endl;
}
}
- if ( failure != NO_MEMORY_FAULT )
+ if ( failure != this->ResultStrings.size() )
{
- ostr << "<b>" << cmCTestMemCheckResultStrings[failure] << "</b> ";
+ ostr << "<b>" << this->ResultStrings[failure] << "</b> ";
results[failure] ++;
defects ++;
}
- ostr << cmXMLSafe(*i) << std::endl;
+ ostr << *i << std::endl;
}
log = ostr.str();
@@ -678,9 +922,9 @@ bool cmCTestMemCheckHandler::ProcessMemCheckPurifyOutput(
//----------------------------------------------------------------------
bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput(
const std::string& str, std::string& log,
- int* results)
+ std::vector<int>& results)
{
- std::vector<cmStdString> lines;
+ std::vector<std::string> lines;
cmSystemTools::Split(str.c_str(), lines);
bool unlimitedOutput = false;
if(str.find("CTEST_FULL_OUTPUT") != str.npos ||
@@ -691,7 +935,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput(
std::string::size_type cc;
- cmOStringStream ostr;
+ std::ostringstream ostr;
log = "";
int defects = 0;
@@ -731,18 +975,18 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput(
"locked by a different thread");
std::vector<std::string::size_type> nonValGrindOutput;
double sttime = cmSystemTools::GetTime();
- cmCTestLog(this->CTest, DEBUG, "Start test: " << lines.size() << std::endl);
+ cmCTestOptionalLog(this->CTest, DEBUG,
+ "Start test: " << lines.size() << std::endl, this->Quiet);
std::string::size_type totalOutputSize = 0;
- bool outputFull = false;
for ( cc = 0; cc < lines.size(); cc ++ )
{
- cmCTestLog(this->CTest, DEBUG, "test line "
- << lines[cc] << std::endl);
+ cmCTestOptionalLog(this->CTest, DEBUG, "test line "
+ << lines[cc] << std::endl, this->Quiet);
if ( valgrindLine.find(lines[cc]) )
{
- cmCTestLog(this->CTest, DEBUG, "valgrind line "
- << lines[cc] << std::endl);
+ cmCTestOptionalLog(this->CTest, DEBUG, "valgrind line "
+ << lines[cc] << std::endl, this->Quiet);
int failure = cmCTestMemCheckHandler::NO_MEMORY_FAULT;
if ( vgFIM.find(lines[cc]) )
{
@@ -807,12 +1051,12 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput(
if ( failure != cmCTestMemCheckHandler::NO_MEMORY_FAULT )
{
- ostr << "<b>" << cmCTestMemCheckResultStrings[failure] << "</b> ";
+ ostr << "<b>" << this->ResultStrings[failure] << "</b> ";
results[failure] ++;
defects ++;
}
totalOutputSize += lines[cc].size();
- ostr << cmXMLSafe(lines[cc]) << std::endl;
+ ostr << lines[cc] << std::endl;
}
else
{
@@ -820,32 +1064,26 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput(
}
}
// Now put all all the non valgrind output into the test output
- if(!outputFull)
+ // This should be last in case it gets truncated by the output
+ // limiting code
+ for(std::vector<std::string::size_type>::iterator i =
+ nonValGrindOutput.begin(); i != nonValGrindOutput.end(); ++i)
{
- for(std::vector<std::string::size_type>::iterator i =
- nonValGrindOutput.begin(); i != nonValGrindOutput.end(); ++i)
+ totalOutputSize += lines[*i].size();
+ ostr << lines[*i] << std::endl;
+ if(!unlimitedOutput && totalOutputSize >
+ static_cast<size_t>(this->CustomMaximumFailedTestOutputSize))
{
- totalOutputSize += lines[*i].size();
- cmCTestLog(this->CTest, DEBUG, "before xml safe "
- << lines[*i] << std::endl);
- cmCTestLog(this->CTest, DEBUG, "after xml safe "
- << cmXMLSafe(lines[*i]) << std::endl);
-
- ostr << cmXMLSafe(lines[*i]) << std::endl;
- if(!unlimitedOutput && totalOutputSize >
- static_cast<size_t>(this->CustomMaximumFailedTestOutputSize))
- {
- outputFull = true;
- ostr << "....\n";
- ostr << "Test Output for this test has been truncated see testing"
- " machine logs for full output,\n";
- ostr << "or put CTEST_FULL_OUTPUT in the output of "
- "this test program.\n";
- }
+ ostr << "....\n";
+ ostr << "Test Output for this test has been truncated see testing"
+ " machine logs for full output,\n";
+ ostr << "or put CTEST_FULL_OUTPUT in the output of "
+ "this test program.\n";
+ break; // stop the copy of output if we are full
}
}
- cmCTestLog(this->CTest, DEBUG, "End test (elapsed: "
- << (cmSystemTools::GetTime() - sttime) << std::endl);
+ cmCTestOptionalLog(this->CTest, DEBUG, "End test (elapsed: "
+ << (cmSystemTools::GetTime() - sttime) << std::endl, this->Quiet);
log = ostr.str();
if ( defects )
{
@@ -859,14 +1097,15 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput(
//----------------------------------------------------------------------
bool cmCTestMemCheckHandler::ProcessMemCheckBoundsCheckerOutput(
const std::string& str, std::string& log,
- int* results)
+ std::vector<int>& results)
{
log = "";
double sttime = cmSystemTools::GetTime();
- std::vector<cmStdString> lines;
+ std::vector<std::string> lines;
cmSystemTools::Split(str.c_str(), lines);
- cmCTestLog(this->CTest, DEBUG, "Start test: " << lines.size() << std::endl);
- std::vector<cmStdString>::size_type cc;
+ cmCTestOptionalLog(this->CTest, DEBUG,
+ "Start test: " << lines.size() << std::endl, this->Quiet);
+ std::vector<std::string>::size_type cc;
for ( cc = 0; cc < lines.size(); cc ++ )
{
if(lines[cc] == BOUNDS_CHECKER_MARKER)
@@ -890,7 +1129,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckBoundsCheckerOutput(
else if(!parser.ParseChunk(theLine.c_str(), theLine.size()))
{
cmCTestLog(this->CTest, ERROR_MESSAGE,
- "Error in ParseChunk: " << theLine.c_str()
+ "Error in ParseChunk: " << theLine
<< std::endl);
}
}
@@ -901,8 +1140,8 @@ bool cmCTestMemCheckHandler::ProcessMemCheckBoundsCheckerOutput(
results[parser.Errors[cc]]++;
defects++;
}
- cmCTestLog(this->CTest, DEBUG, "End test (elapsed: "
- << (cmSystemTools::GetTime() - sttime) << std::endl);
+ cmCTestOptionalLog(this->CTest, DEBUG, "End test (elapsed: "
+ << (cmSystemTools::GetTime() - sttime) << std::endl, this->Quiet);
if(defects)
{
// only put the output of Bounds Checker if there were
@@ -913,23 +1152,55 @@ bool cmCTestMemCheckHandler::ProcessMemCheckBoundsCheckerOutput(
return true;
}
+// PostProcessTest memcheck results
+void
+cmCTestMemCheckHandler::PostProcessTest(cmCTestTestResult& res,
+ int test)
+{
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "PostProcessTest memcheck results for : "
+ << res.Name << std::endl, this->Quiet);
+ if(this->MemoryTesterStyle
+ == cmCTestMemCheckHandler::BOUNDS_CHECKER)
+ {
+ this->PostProcessBoundsCheckerTest(res, test);
+ }
+ else
+ {
+ std::vector<std::string> files;
+ this->TestOutputFileNames(test, files);
+ for(std::vector<std::string>::iterator i = files.begin();
+ i != files.end(); ++i)
+ {
+ this->AppendMemTesterOutput(res, *i);
+ }
+ }
+}
+
+
// This method puts the bounds checker output file into the output
// for the test
void
cmCTestMemCheckHandler::PostProcessBoundsCheckerTest(cmCTestTestResult& res,
int test)
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"PostProcessBoundsCheckerTest for : "
- << res.Name.c_str() << std::endl);
- cmStdString ofile = testOutputFileName(test);
+ << res.Name << std::endl, this->Quiet);
+ std::vector<std::string> files;
+ this->TestOutputFileNames(test, files);
+ if (files.empty())
+ {
+ return;
+ }
+ std::string ofile = files[0];
if ( ofile.empty() )
{
return;
}
// put a scope around this to close ifs so the file can be removed
{
- std::ifstream ifs(ofile.c_str());
+ cmsys::ifstream ifs(ofile.c_str());
if ( !ifs )
{
std::string log = "Cannot read memory tester output file: " + ofile;
@@ -946,45 +1217,25 @@ cmCTestMemCheckHandler::PostProcessBoundsCheckerTest(cmCTestTestResult& res,
}
}
cmSystemTools::Delay(1000);
- cmSystemTools::RemoveFile(this->BoundsCheckerDPBDFile.c_str());
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Remove: "
- << this->BoundsCheckerDPBDFile.c_str() << std::endl);
- cmSystemTools::RemoveFile(this->BoundsCheckerXMLFile.c_str());
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Remove: "
- << this->BoundsCheckerXMLFile.c_str() << std::endl);
+ cmSystemTools::RemoveFile(this->BoundsCheckerDPBDFile);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Remove: "
+ << this->BoundsCheckerDPBDFile << std::endl, this->Quiet);
+ cmSystemTools::RemoveFile(this->BoundsCheckerXMLFile);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Remove: "
+ << this->BoundsCheckerXMLFile << std::endl, this->Quiet);
}
void
-cmCTestMemCheckHandler::PostProcessPurifyTest(cmCTestTestResult& res,
- int test)
+cmCTestMemCheckHandler::AppendMemTesterOutput(cmCTestTestResult& res,
+ std::string const& ofile)
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "PostProcessPurifyTest for : "
- << res.Name.c_str() << std::endl);
- appendMemTesterOutput(res, test);
-}
-
-void
-cmCTestMemCheckHandler::PostProcessValgrindTest(cmCTestTestResult& res,
- int test)
-{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "PostProcessValgrindTest for : "
- << res.Name.c_str() << std::endl);
- appendMemTesterOutput(res, test);
-}
-
-void
-cmCTestMemCheckHandler::appendMemTesterOutput(cmCTestTestResult& res,
- int test)
-{
- cmStdString ofile = testOutputFileName(test);
-
if ( ofile.empty() )
{
return;
}
- std::ifstream ifs(ofile.c_str());
+ // put ifs in scope so file can be deleted if needed
+ {
+ cmsys::ifstream ifs(ofile.c_str());
if ( !ifs )
{
std::string log = "Cannot read memory tester output file: " + ofile;
@@ -997,26 +1248,50 @@ cmCTestMemCheckHandler::appendMemTesterOutput(cmCTestTestResult& res,
res.Output += line;
res.Output += "\n";
}
+ }
+ if(this->LogWithPID)
+ {
+ cmSystemTools::RemoveFile(ofile);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Remove: "<< ofile <<"\n", this->Quiet);
+ }
}
-cmStdString
-cmCTestMemCheckHandler::testOutputFileName(int test)
+void cmCTestMemCheckHandler::TestOutputFileNames(int test,
+ std::vector<std::string>&
+ files)
{
- cmStdString index;
- cmOStringStream stream;
+ std::string index;
+ std::ostringstream stream;
stream << test;
index = stream.str();
- cmStdString ofile = this->MemoryTesterOutputFile;
- cmStdString::size_type pos = ofile.find("??");
+ std::string ofile = this->MemoryTesterOutputFile;
+ std::string::size_type pos = ofile.find("??");
ofile.replace(pos, 2, index);
-
- if ( !cmSystemTools::FileExists(ofile.c_str()) )
+ if(this->LogWithPID)
+ {
+ ofile += ".*";
+ cmsys::Glob g;
+ g.FindFiles(ofile);
+ if(g.GetFiles().empty())
+ {
+ std::string log = "Cannot find memory tester output file: "
+ + ofile;
+ cmCTestLog(this->CTest, ERROR_MESSAGE, log.c_str() << std::endl);
+ ofile = "";
+ }
+ else
+ {
+ files = g.GetFiles();
+ return;
+ }
+ }
+ else if ( !cmSystemTools::FileExists(ofile.c_str()) )
{
std::string log = "Cannot find memory tester output file: "
+ ofile;
cmCTestLog(this->CTest, ERROR_MESSAGE, log.c_str() << std::endl);
ofile = "";
}
-
- return ofile;
+ files.push_back(ofile);
}
diff --git a/Source/CTest/cmCTestMemCheckHandler.h b/Source/CTest/cmCTestMemCheckHandler.h
index 040d2e092..f1ac794dc 100644
--- a/Source/CTest/cmCTestMemCheckHandler.h
+++ b/Source/CTest/cmCTestMemCheckHandler.h
@@ -15,9 +15,13 @@
#include "cmCTestTestHandler.h"
+#include "cmStandardIncludes.h"
#include "cmListFileCache.h"
+#include <vector>
+#include <string>
class cmMakefile;
+class cmXMLWriter;
/** \class cmCTestMemCheckHandler
* \brief A class that handles ctest -S invocations
@@ -45,7 +49,12 @@ private:
UNKNOWN = 0,
VALGRIND,
PURIFY,
- BOUNDS_CHECKER
+ BOUNDS_CHECKER,
+ // checkers after here do not use the standard error list
+ ADDRESS_SANITIZER,
+ THREAD_SANITIZER,
+ MEMORY_SANITIZER,
+ UB_SANITIZER
};
public:
enum { // Memory faults
@@ -89,11 +98,21 @@ private:
std::string BoundsCheckerDPBDFile;
std::string BoundsCheckerXMLFile;
std::string MemoryTester;
- std::vector<cmStdString> MemoryTesterDynamicOptions;
- std::vector<cmStdString> MemoryTesterOptions;
+ std::vector<std::string> MemoryTesterDynamicOptions;
+ std::vector<std::string> MemoryTesterOptions;
int MemoryTesterStyle;
std::string MemoryTesterOutputFile;
- int MemoryTesterGlobalResults[NO_MEMORY_FAULT];
+ std::string MemoryTesterEnvironmentVariable;
+ // these are used to store the types of errors that can show up
+ std::vector<std::string> ResultStrings;
+ std::vector<std::string> ResultStringsLong;
+ std::vector<int> GlobalResults;
+ bool LogWithPID; // does log file add pid
+
+ std::vector<int>::size_type FindOrAddWarning(const std::string& warning);
+ // initialize the ResultStrings and ResultStringsLong for
+ // this type of checker
+ void InitializeResultsVectors();
///! Initialize memory checking subsystem.
bool InitializeMemoryChecking();
@@ -101,33 +120,38 @@ private:
/**
* Generate the Dart compatible output
*/
- void GenerateDartOutput(std::ostream& os);
+ void GenerateDartOutput(cmXMLWriter& xml);
- std::vector<cmStdString> CustomPreMemCheck;
- std::vector<cmStdString> CustomPostMemCheck;
+ std::vector<std::string> CustomPreMemCheck;
+ std::vector<std::string> CustomPostMemCheck;
//! Parse Valgrind/Purify/Bounds Checker result out of the output
//string. After running, log holds the output and results hold the
//different memmory errors.
bool ProcessMemCheckOutput(const std::string& str,
- std::string& log, int* results);
+ std::string& log, std::vector<int>& results);
bool ProcessMemCheckValgrindOutput(const std::string& str,
- std::string& log, int* results);
+ std::string& log,
+ std::vector<int>& results);
bool ProcessMemCheckPurifyOutput(const std::string& str,
- std::string& log, int* results);
+ std::string& log,
+ std::vector<int>& results);
+ bool ProcessMemCheckSanitizerOutput(const std::string& str,
+ std::string& log,
+ std::vector<int>& results);
bool ProcessMemCheckBoundsCheckerOutput(const std::string& str,
- std::string& log, int* results);
+ std::string& log,
+ std::vector<int>& results);
- void PostProcessPurifyTest(cmCTestTestResult& res, int test);
+ void PostProcessTest(cmCTestTestResult& res, int test);
void PostProcessBoundsCheckerTest(cmCTestTestResult& res, int test);
- void PostProcessValgrindTest(cmCTestTestResult& res, int test);
///! append MemoryTesterOutputFile to the test log
- void appendMemTesterOutput(cmCTestTestHandler::cmCTestTestResult& res,
- int test);
+ void AppendMemTesterOutput(cmCTestTestHandler::cmCTestTestResult& res,
+ std::string const& filename);
///! generate the output filename for the given test index
- cmStdString testOutputFileName(int test);
+ void TestOutputFileNames(int test, std::vector<std::string>& files);
};
#endif
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index 76ddeea01..7c7f5dfe2 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -13,10 +13,15 @@
#include "cmProcess.h"
#include "cmStandardIncludes.h"
#include "cmCTest.h"
+#include "cmCTestScriptHandler.h"
#include "cmSystemTools.h"
#include <stdlib.h>
#include <stack>
+#include <list>
#include <float.h>
+#include <math.h>
+#include <cmsys/FStream.hxx>
+#include <cmsys/SystemInformation.hxx>
class TestComparator
{
@@ -38,9 +43,12 @@ private:
cmCTestMultiProcessHandler::cmCTestMultiProcessHandler()
{
this->ParallelLevel = 1;
+ this->TestLoad = 0;
this->Completed = 0;
this->RunningCount = 0;
this->StopTimePassed = false;
+ this->HasCycles = false;
+ this->SerialTestRunning = false;
}
cmCTestMultiProcessHandler::~cmCTestMultiProcessHandler()
@@ -65,6 +73,11 @@ cmCTestMultiProcessHandler::SetTests(TestMap& tests,
if(!this->CTest->GetShowOnly())
{
this->ReadCostData();
+ this->HasCycles = !this->CheckCycles();
+ if(this->HasCycles)
+ {
+ return;
+ }
this->CreateTestCostList();
}
}
@@ -75,17 +88,22 @@ void cmCTestMultiProcessHandler::SetParallelLevel(size_t level)
this->ParallelLevel = level < 1 ? 1 : level;
}
+void cmCTestMultiProcessHandler::SetTestLoad(unsigned long load)
+{
+ this->TestLoad = load;
+}
+
//---------------------------------------------------------
void cmCTestMultiProcessHandler::RunTests()
{
this->CheckResume();
- if(!this->CheckCycles())
+ if(this->HasCycles)
{
return;
}
this->TestHandler->SetMaxIndex(this->FindMaxIndex());
this->StartNextTests();
- while(this->Tests.size() != 0)
+ while(!this->Tests.empty())
{
if(this->StopTimePassed)
{
@@ -105,18 +123,24 @@ void cmCTestMultiProcessHandler::RunTests()
//---------------------------------------------------------
void cmCTestMultiProcessHandler::StartTestProcess(int test)
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "test " << test << "\n");
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "test " << test << "\n", this->Quiet);
this->TestRunningMap[test] = true; // mark the test as running
// now remove the test itself
this->EraseTest(test);
this->RunningCount += GetProcessorsUsed(test);
cmCTestRunTest* testRun = new cmCTestRunTest(this->TestHandler);
+ if(this->CTest->GetRepeatUntilFail())
+ {
+ testRun->SetRunUntilFailOn();
+ testRun->SetNumberOfRuns(this->CTest->GetTestRepeat());
+ }
testRun->SetIndex(test);
testRun->SetTestProperties(this->Properties[test]);
std::string current_dir = cmSystemTools::GetCurrentWorkingDirectory();
- cmSystemTools::ChangeDirectory(this->Properties[test]->Directory.c_str());
+ cmSystemTools::ChangeDirectory(this->Properties[test]->Directory);
// Lock the resources we'll be using
this->LockResources(test);
@@ -133,6 +157,13 @@ void cmCTestMultiProcessHandler::StartTestProcess(int test)
}
else
{
+
+ for(TestMap::iterator j = this->Tests.begin();
+ j != this->Tests.end(); ++j)
+ {
+ j->second.erase(test);
+ }
+
this->UnlockResources(test);
this->Completed++;
this->TestFinishMap[test] = true;
@@ -142,17 +173,19 @@ void cmCTestMultiProcessHandler::StartTestProcess(int test)
this->Failed->push_back(this->Properties[test]->Name);
delete testRun;
}
- cmSystemTools::ChangeDirectory(current_dir.c_str());
+ cmSystemTools::ChangeDirectory(current_dir);
}
//---------------------------------------------------------
void cmCTestMultiProcessHandler::LockResources(int index)
{
- for(std::set<std::string>::iterator i =
- this->Properties[index]->LockedResources.begin();
- i != this->Properties[index]->LockedResources.end(); ++i)
+ this->LockedResources.insert(
+ this->Properties[index]->LockedResources.begin(),
+ this->Properties[index]->LockedResources.end());
+
+ if (this->Properties[index]->RunSerial)
{
- this->LockedResources.insert(*i);
+ this->SerialTestRunning = true;
}
}
@@ -165,6 +198,10 @@ void cmCTestMultiProcessHandler::UnlockResources(int index)
{
this->LockedResources.erase(*i);
}
+ if (this->Properties[index]->RunSerial)
+ {
+ this->SerialTestRunning = false;
+ }
}
//---------------------------------------------------------
@@ -180,17 +217,20 @@ inline size_t cmCTestMultiProcessHandler::GetProcessorsUsed(int test)
{
size_t processors =
static_cast<int>(this->Properties[test]->Processors);
- //If this is set to run serially, it must run alone.
- //Also, if processors setting is set higher than the -j
+ //If processors setting is set higher than the -j
//setting, we default to using all of the process slots.
- if(this->Properties[test]->RunSerial
- || processors > this->ParallelLevel)
+ if (processors > this->ParallelLevel)
{
processors = this->ParallelLevel;
}
return processors;
}
+std::string cmCTestMultiProcessHandler::GetName(int test)
+{
+ return this->Properties[test]->Name;
+}
+
//---------------------------------------------------------
bool cmCTestMultiProcessHandler::StartTest(int test)
{
@@ -205,37 +245,8 @@ bool cmCTestMultiProcessHandler::StartTest(int test)
}
}
- // copy the depend tests locally because when
- // a test is finished it will be removed from the depend list
- // and we don't want to be iterating a list while removing from it
- TestSet depends = this->Tests[test];
- size_t totalDepends = depends.size();
- if(totalDepends)
- {
- for(TestSet::const_iterator i = depends.begin();
- i != depends.end(); ++i)
- {
- // if the test is not already running then start it
- if(!this->TestRunningMap[*i])
- {
- // this test might be finished, but since
- // this is a copy of the depend map we might
- // still have it
- if(!this->TestFinishMap[*i])
- {
- // only start one test in this function
- return this->StartTest(*i);
- }
- else
- {
- // the depend has been and finished
- totalDepends--;
- }
- }
- }
- }
// if there are no depends left then run this test
- if(totalDepends == 0)
+ if(this->Tests[test].empty())
{
this->StartTestProcess(test);
return true;
@@ -259,30 +270,136 @@ void cmCTestMultiProcessHandler::StartNextTests()
return;
}
+ // Don't start any new tests if one with the RUN_SERIAL property
+ // is already running.
+ if (this->SerialTestRunning)
+ {
+ return;
+ }
+
+ bool allTestsFailedTestLoadCheck = false;
+ bool usedFakeLoadForTesting = false;
+ size_t minProcessorsRequired = this->ParallelLevel;
+ std::string testWithMinProcessors = "";
+
+ cmsys::SystemInformation info;
+
+ unsigned long systemLoad = 0;
+ size_t spareLoad = 0;
+ if (this->TestLoad > 0)
+ {
+ // Activate possible wait.
+ allTestsFailedTestLoadCheck = true;
+
+ // Check for a fake load average value used in testing.
+ if (const char* fake_load_value =
+ cmSystemTools::GetEnv("__CTEST_FAKE_LOAD_AVERAGE_FOR_TESTING"))
+ {
+ usedFakeLoadForTesting = true;
+ if (!cmSystemTools::StringToULong(fake_load_value, &systemLoad))
+ {
+ cmSystemTools::Error("Failed to parse fake load value: ",
+ fake_load_value);
+ }
+ }
+ // If it's not set, look up the true load average.
+ else
+ {
+ systemLoad = static_cast<unsigned long>(ceil(info.GetLoadAverage()));
+ }
+ spareLoad = (this->TestLoad > systemLoad ?
+ this->TestLoad - systemLoad : 0);
+
+ // Don't start more tests than the spare load can support.
+ if (numToStart > spareLoad)
+ {
+ numToStart = spareLoad;
+ }
+ }
+
TestList copy = this->SortedTests;
for(TestList::iterator test = copy.begin(); test != copy.end(); ++test)
{
- //in case this test has already been started due to dependency
- if(this->TestRunningMap[*test] || this->TestFinishMap[*test])
+ // Take a nap if we're currently performing a RUN_SERIAL test.
+ if (this->SerialTestRunning)
+ {
+ break;
+ }
+ // We can only start a RUN_SERIAL test if no other tests are also running.
+ if (this->Properties[*test]->RunSerial && this->RunningCount > 0)
{
continue;
}
+
size_t processors = GetProcessorsUsed(*test);
- if(processors > numToStart)
+ bool testLoadOk = true;
+ if (this->TestLoad > 0)
{
- return;
+ if (processors <= spareLoad)
+ {
+ cmCTestLog(this->CTest, DEBUG,
+ "OK to run " << GetName(*test) <<
+ ", it requires " << processors <<
+ " procs & system load is: " <<
+ systemLoad << std::endl);
+ allTestsFailedTestLoadCheck = false;
+ }
+ else
+ {
+ testLoadOk = false;
+ }
}
- if(this->StartTest(*test))
+
+ if (processors <= minProcessorsRequired)
+ {
+ minProcessorsRequired = processors;
+ testWithMinProcessors = GetName(*test);
+ }
+
+ if(testLoadOk && processors <= numToStart && this->StartTest(*test))
{
if(this->StopTimePassed)
{
return;
}
+
numToStart -= processors;
}
- if(numToStart == 0)
+ else if(numToStart == 0)
{
- return;
+ break;
+ }
+ }
+
+ if (allTestsFailedTestLoadCheck)
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "***** WAITING, ");
+ if (this->SerialTestRunning)
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ "Waiting for RUN_SERIAL test to finish.");
+ }
+ else
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ "System Load: " << systemLoad << ", "
+ "Max Allowed Load: " << this->TestLoad << ", "
+ "Smallest test " << testWithMinProcessors <<
+ " requires " << minProcessorsRequired);
+ }
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "*****" << std::endl);
+
+ if (usedFakeLoadForTesting)
+ {
+ // Break out of the infinite loop of waiting for our fake load
+ // to come down.
+ this->StopTimePassed = true;
+ }
+ else
+ {
+ // Wait between 1 and 5 seconds before trying again.
+ cmCTestScriptHandler::SleepInSeconds(
+ cmSystemTools::RandomSeed() % 5 + 1);
}
}
}
@@ -291,7 +408,7 @@ void cmCTestMultiProcessHandler::StartNextTests()
bool cmCTestMultiProcessHandler::CheckOutput()
{
// no more output we are done
- if(this->RunningTests.size() == 0)
+ if(this->RunningTests.empty())
{
return false;
}
@@ -313,7 +430,13 @@ bool cmCTestMultiProcessHandler::CheckOutput()
cmCTestRunTest* p = *i;
int test = p->GetIndex();
- if(p->EndTest(this->Completed, this->Total, true))
+ bool testResult = p->EndTest(this->Completed, this->Total, true);
+ if(p->StartAgain())
+ {
+ this->Completed--; // remove the completed test because run again
+ continue;
+ }
+ if(testResult)
{
this->Passed->push_back(p->GetTestProperties()->Name);
}
@@ -342,14 +465,14 @@ void cmCTestMultiProcessHandler::UpdateCostData()
{
std::string fname = this->CTest->GetCostDataFile();
std::string tmpout = fname + ".tmp";
- std::fstream fout;
- fout.open(tmpout.c_str(), std::ios::out);
+ cmsys::ofstream fout;
+ fout.open(tmpout.c_str());
PropertiesMap temp = this->Properties;
if(cmSystemTools::FileExists(fname.c_str()))
{
- std::ifstream fin;
+ cmsys::ifstream fin;
fin.open(fname.c_str());
std::string line;
@@ -357,7 +480,7 @@ void cmCTestMultiProcessHandler::UpdateCostData()
{
if(line == "---") break;
std::vector<cmsys::String> parts =
- cmSystemTools::SplitString(line.c_str(), ' ');
+ cmSystemTools::SplitString(line, ' ');
//Format: <name> <previous_runs> <avg_cost>
if(parts.size() < 3) break;
@@ -380,7 +503,7 @@ void cmCTestMultiProcessHandler::UpdateCostData()
}
}
fin.close();
- cmSystemTools::RemoveFile(fname.c_str());
+ cmSystemTools::RemoveFile(fname);
}
// Add all tests not previously listed in the file
@@ -392,7 +515,7 @@ void cmCTestMultiProcessHandler::UpdateCostData()
// Write list of failed tests
fout << "---\n";
- for(std::vector<cmStdString>::iterator i = this->Failed->begin();
+ for(std::vector<std::string>::iterator i = this->Failed->begin();
i != this->Failed->end(); ++i)
{
fout << i->c_str() << "\n";
@@ -408,7 +531,7 @@ void cmCTestMultiProcessHandler::ReadCostData()
if(cmSystemTools::FileExists(fname.c_str(), true))
{
- std::ifstream fin;
+ cmsys::ifstream fin;
fin.open(fname.c_str());
std::string line;
while(std::getline(fin, line))
@@ -416,7 +539,7 @@ void cmCTestMultiProcessHandler::ReadCostData()
if(line == "---") break;
std::vector<cmsys::String> parts =
- cmSystemTools::SplitString(line.c_str(), ' ');
+ cmSystemTools::SplitString(line, ' ');
// Probably an older version of the file, will be fixed next run
if(parts.size() < 3)
@@ -472,24 +595,153 @@ int cmCTestMultiProcessHandler::SearchByName(std::string name)
//---------------------------------------------------------
void cmCTestMultiProcessHandler::CreateTestCostList()
{
- for(TestMap::iterator i = this->Tests.begin();
- i != this->Tests.end(); ++i)
+ if(this->ParallelLevel > 1)
+ {
+ CreateParallelTestCostList();
+ }
+ else
{
- SortedTests.push_back(i->first);
+ CreateSerialTestCostList();
+ }
+}
+
+//---------------------------------------------------------
+void cmCTestMultiProcessHandler::CreateParallelTestCostList()
+{
+ TestSet alreadySortedTests;
+
+ std::list<TestSet> priorityStack;
+ priorityStack.push_back(TestSet());
+ TestSet &topLevel = priorityStack.back();
- //If the test failed last time, it should be run first, so max the cost.
- //Only do this for parallel runs; in non-parallel runs, avoid clobbering
- //the test's explicitly set cost.
- if(this->ParallelLevel > 1 &&
- std::find(this->LastTestsFailed.begin(), this->LastTestsFailed.end(),
+ // In parallel test runs add previously failed tests to the front
+ // of the cost list and queue other tests for further sorting
+ for(TestMap::const_iterator i = this->Tests.begin();
+ i != this->Tests.end(); ++i)
+ {
+ if(std::find(this->LastTestsFailed.begin(), this->LastTestsFailed.end(),
this->Properties[i->first]->Name) != this->LastTestsFailed.end())
{
- this->Properties[i->first]->Cost = FLT_MAX;
+ //If the test failed last time, it should be run first.
+ this->SortedTests.push_back(i->first);
+ alreadySortedTests.insert(i->first);
+ }
+ else
+ {
+ topLevel.insert(i->first);
}
}
+ // In parallel test runs repeatedly move dependencies of the tests on
+ // the current dependency level to the next level until no
+ // further dependencies exist.
+ while(priorityStack.back().size())
+ {
+ TestSet &previousSet = priorityStack.back();
+ priorityStack.push_back(TestSet());
+ TestSet &currentSet = priorityStack.back();
+
+ for(TestSet::const_iterator i = previousSet.begin();
+ i != previousSet.end(); ++i)
+ {
+ TestSet const& dependencies = this->Tests[*i];
+ currentSet.insert(dependencies.begin(), dependencies.end());
+ }
+
+ for(TestSet::const_iterator i = currentSet.begin();
+ i != currentSet.end(); ++i)
+ {
+ previousSet.erase(*i);
+ }
+ }
+
+ // Remove the empty dependency level
+ priorityStack.pop_back();
+
+ // Reverse iterate over the different dependency levels (deepest first).
+ // Sort tests within each level by COST and append them to the cost list.
+ for(std::list<TestSet>::reverse_iterator i = priorityStack.rbegin();
+ i != priorityStack.rend(); ++i)
+ {
+ TestSet const& currentSet = *i;
+ TestComparator comp(this);
+
+ TestList sortedCopy;
+
+ sortedCopy.insert(sortedCopy.end(),
+ currentSet.begin(), currentSet.end());
+
+ std::stable_sort(sortedCopy.begin(), sortedCopy.end(), comp);
+
+ for(TestList::const_iterator j = sortedCopy.begin();
+ j != sortedCopy.end(); ++j)
+ {
+ if(alreadySortedTests.find(*j) == alreadySortedTests.end())
+ {
+ this->SortedTests.push_back(*j);
+ alreadySortedTests.insert(*j);
+ }
+ }
+ }
+}
+
+//---------------------------------------------------------
+void cmCTestMultiProcessHandler::GetAllTestDependencies(
+ int test, TestList& dependencies)
+{
+ TestSet const& dependencySet = this->Tests[test];
+ for(TestSet::const_iterator i = dependencySet.begin();
+ i != dependencySet.end(); ++i)
+ {
+ GetAllTestDependencies(*i, dependencies);
+ dependencies.push_back(*i);
+ }
+}
+
+//---------------------------------------------------------
+void cmCTestMultiProcessHandler::CreateSerialTestCostList()
+{
+ TestList presortedList;
+
+ for(TestMap::iterator i = this->Tests.begin();
+ i != this->Tests.end(); ++i)
+ {
+ presortedList.push_back(i->first);
+ }
+
TestComparator comp(this);
- std::stable_sort(SortedTests.begin(), SortedTests.end(), comp);
+ std::stable_sort(presortedList.begin(), presortedList.end(), comp);
+
+ TestSet alreadySortedTests;
+
+ for(TestList::const_iterator i = presortedList.begin();
+ i != presortedList.end(); ++i)
+ {
+ int test = *i;
+
+ if(alreadySortedTests.find(test) != alreadySortedTests.end())
+ {
+ continue;
+ }
+
+ TestList dependencies;
+ GetAllTestDependencies(test, dependencies);
+
+ for(TestList::const_iterator j = dependencies.begin();
+ j != dependencies.end(); ++j)
+ {
+ int testDependency = *j;
+
+ if(alreadySortedTests.find(testDependency) == alreadySortedTests.end())
+ {
+ alreadySortedTests.insert(testDependency);
+ this->SortedTests.push_back(testDependency);
+ }
+ }
+
+ alreadySortedTests.insert(test);
+ this->SortedTests.push_back(test);
+ }
}
//---------------------------------------------------------
@@ -497,8 +749,8 @@ void cmCTestMultiProcessHandler::WriteCheckpoint(int index)
{
std::string fname = this->CTest->GetBinaryDir()
+ "/Testing/Temporary/CTestCheckpoint.txt";
- std::fstream fout;
- fout.open(fname.c_str(), std::ios::app | std::ios::out);
+ cmsys::ofstream fout;
+ fout.open(fname.c_str(), std::ios::app);
fout << index << "\n";
fout.close();
}
@@ -508,7 +760,7 @@ void cmCTestMultiProcessHandler::MarkFinished()
{
std::string fname = this->CTest->GetBinaryDir()
+ "/Testing/Temporary/CTestCheckpoint.txt";
- cmSystemTools::RemoveFile(fname.c_str());
+ cmSystemTools::RemoveFile(fname);
}
//---------------------------------------------------------
@@ -526,48 +778,53 @@ void cmCTestMultiProcessHandler::PrintTestList()
//push working dir
std::string current_dir = cmSystemTools::GetCurrentWorkingDirectory();
- cmSystemTools::ChangeDirectory(p.Directory.c_str());
+ cmSystemTools::ChangeDirectory(p.Directory);
cmCTestRunTest testRun(this->TestHandler);
testRun.SetIndex(p.Index);
testRun.SetTestProperties(&p);
testRun.ComputeArguments(); //logs the command in verbose mode
- if(p.Labels.size()) //print the labels
+ if(!p.Labels.empty()) //print the labels
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Labels:");
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Labels:",
+ this->Quiet);
}
for(std::vector<std::string>::iterator label = p.Labels.begin();
label != p.Labels.end(); ++label)
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " " << *label);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " " << *label,
+ this->Quiet);
}
- if(p.Labels.size()) //print the labels
+ if(!p.Labels.empty()) //print the labels
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl,
+ this->Quiet);
}
if (this->TestHandler->MemCheck)
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " Memory Check");
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Memory Check",
+ this->Quiet);
}
else
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " Test");
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Test", this->Quiet);
}
- cmOStringStream indexStr;
+ std::ostringstream indexStr;
indexStr << " #" << p.Index << ":";
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
std::setw(3 + getNumWidth(this->TestHandler->GetMaxIndex()))
- << indexStr.str().c_str());
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " ");
- cmCTestLog(this->CTest, HANDLER_OUTPUT, p.Name.c_str() << std::endl);
+ << indexStr.str(), this->Quiet);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " ", this->Quiet);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ p.Name.c_str() << std::endl, this->Quiet);
//pop working dir
- cmSystemTools::ChangeDirectory(current_dir.c_str());
+ cmSystemTools::ChangeDirectory(current_dir);
}
- cmCTestLog(this->CTest, HANDLER_OUTPUT, std::endl << "Total Tests: "
- << this->Total << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, std::endl << "Total Tests: "
+ << this->Total << std::endl, this->Quiet);
}
void cmCTestMultiProcessHandler::PrintLabels()
@@ -580,18 +837,21 @@ void cmCTestMultiProcessHandler::PrintLabels()
allLabels.insert(p.Labels.begin(), p.Labels.end());
}
- if(allLabels.size())
+ if(!allLabels.empty())
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT, "All Labels:" << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ "All Labels:" << std::endl, this->Quiet);
}
else
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT, "No Labels Exist" << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ "No Labels Exist" << std::endl, this->Quiet);
}
for(std::set<std::string>::iterator label = allLabels.begin();
label != allLabels.end(); ++label)
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " " << *label << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ " " << *label << std::endl, this->Quiet);
}
}
@@ -609,7 +869,7 @@ void cmCTestMultiProcessHandler::CheckResume()
<< "----------------------------------------------------------"
<< std::endl;
- std::ifstream fin;
+ cmsys::ifstream fin;
fin.open(fname.c_str());
std::string line;
while(std::getline(fin, line))
@@ -622,7 +882,7 @@ void cmCTestMultiProcessHandler::CheckResume()
}
else if(cmSystemTools::FileExists(fname.c_str(), true))
{
- cmSystemTools::RemoveFile(fname.c_str());
+ cmSystemTools::RemoveFile(fname);
}
}
@@ -654,8 +914,8 @@ int cmCTestMultiProcessHandler::FindMaxIndex()
//Returns true if no cycles exist in the dependency graph
bool cmCTestMultiProcessHandler::CheckCycles()
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "Checking test dependency graph..." << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Checking test dependency graph..." << std::endl, this->Quiet);
for(TestMap::iterator it = this->Tests.begin();
it != this->Tests.end(); ++it)
{
@@ -690,7 +950,7 @@ bool cmCTestMultiProcessHandler::CheckCycles()
}
}
}
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "Checking test dependency graph end" << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Checking test dependency graph end" << std::endl, this->Quiet);
return true;
}
diff --git a/Source/CTest/cmCTestMultiProcessHandler.h b/Source/CTest/cmCTestMultiProcessHandler.h
index cd21d9187..ed3e155a0 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.h
+++ b/Source/CTest/cmCTestMultiProcessHandler.h
@@ -37,12 +37,13 @@ public:
void SetTests(TestMap& tests, PropertiesMap& properties);
// Set the max number of tests that can be run at the same time.
void SetParallelLevel(size_t);
+ void SetTestLoad(unsigned long load);
virtual void RunTests();
void PrintTestList();
void PrintLabels();
- void SetPassFailVectors(std::vector<cmStdString>* passed,
- std::vector<cmStdString>* failed)
+ void SetPassFailVectors(std::vector<std::string>* passed,
+ std::vector<std::string>* failed)
{
this->Passed = passed;
this->Failed = failed;
@@ -57,6 +58,8 @@ public:
cmCTestTestHandler * GetTestHandler()
{ return this->TestHandler; }
+
+ void SetQuiet(bool b) { this->Quiet = b; }
protected:
// Start the next test or tests as many as are allowed by
// ParallelLevel
@@ -72,6 +75,12 @@ protected:
int SearchByName(std::string name);
void CreateTestCostList();
+
+ void GetAllTestDependencies(int test, TestList& dependencies);
+ void CreateSerialTestCostList();
+
+ void CreateParallelTestCostList();
+
// Removes the checkpoint file
void MarkFinished();
void EraseTest(int index);
@@ -85,6 +94,7 @@ protected:
bool CheckCycles();
int FindMaxIndex();
inline size_t GetProcessorsUsed(int index);
+ std::string GetName(int index);
void LockResources(int index);
void UnlockResources(int index);
@@ -101,16 +111,20 @@ protected:
PropertiesMap Properties;
std::map<int, bool> TestRunningMap;
std::map<int, bool> TestFinishMap;
- std::map<int, cmStdString> TestOutput;
- std::vector<cmStdString>* Passed;
- std::vector<cmStdString>* Failed;
+ std::map<int, std::string> TestOutput;
+ std::vector<std::string>* Passed;
+ std::vector<std::string>* Failed;
std::vector<std::string> LastTestsFailed;
std::set<std::string> LockedResources;
std::vector<cmCTestTestHandler::cmCTestTestResult>* TestResults;
size_t ParallelLevel; // max number of process that can be run at once
+ unsigned long TestLoad;
std::set<cmCTestRunTest*> RunningTests; // current running tests
cmCTestTestHandler * TestHandler;
cmCTest* CTest;
+ bool HasCycles;
+ bool Quiet;
+ bool SerialTestRunning;
};
#endif
diff --git a/Source/CTest/cmCTestP4.cxx b/Source/CTest/cmCTestP4.cxx
new file mode 100644
index 000000000..5e0c54a3f
--- /dev/null
+++ b/Source/CTest/cmCTestP4.cxx
@@ -0,0 +1,562 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2013 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmCTestP4.h"
+
+#include "cmCTest.h"
+#include "cmSystemTools.h"
+
+#include <cmsys/RegularExpression.hxx>
+#include <cmsys/Process.h>
+
+#include <sys/types.h>
+#include <time.h>
+#include <ctype.h>
+
+//----------------------------------------------------------------------------
+cmCTestP4::cmCTestP4(cmCTest* ct, std::ostream& log):
+ cmCTestGlobalVC(ct, log)
+{
+ this->PriorRev = this->Unknown;
+}
+
+//----------------------------------------------------------------------------
+cmCTestP4::~cmCTestP4()
+{
+}
+
+//----------------------------------------------------------------------------
+class cmCTestP4::IdentifyParser: public cmCTestVC::LineParser
+{
+public:
+ IdentifyParser(cmCTestP4* p4, const char* prefix,
+ std::string& rev): Rev(rev)
+ {
+ this->SetLog(&p4->Log, prefix);
+ this->RegexIdentify.compile("^Change ([0-9]+) on");
+ }
+private:
+ std::string& Rev;
+ cmsys::RegularExpression RegexIdentify;
+
+ bool ProcessLine()
+ {
+ if(this->RegexIdentify.find(this->Line))
+ {
+ this->Rev = this->RegexIdentify.match(1);
+ return false;
+ }
+ return true;
+ }
+};
+
+//----------------------------------------------------------------------------
+class cmCTestP4::ChangesParser: public cmCTestVC::LineParser
+{
+public:
+ ChangesParser(cmCTestP4* p4, const char* prefix) : P4(p4)
+ {
+ this->SetLog(&P4->Log, prefix);
+ this->RegexIdentify.compile("^Change ([0-9]+) on");
+ }
+private:
+ cmsys::RegularExpression RegexIdentify;
+ cmCTestP4* P4;
+
+ bool ProcessLine()
+ {
+ if(this->RegexIdentify.find(this->Line))
+ {
+ P4->ChangeLists.push_back(this->RegexIdentify.match(1));
+ }
+ return true;
+ }
+};
+
+//----------------------------------------------------------------------------
+class cmCTestP4::UserParser: public cmCTestVC::LineParser
+{
+public:
+ UserParser(cmCTestP4* p4, const char* prefix) : P4(p4)
+ {
+ this->SetLog(&P4->Log, prefix);
+ this->RegexUser.compile("^(.+) <(.*)> \\((.*)\\) accessed (.*)$");
+ }
+private:
+ cmsys::RegularExpression RegexUser;
+ cmCTestP4* P4;
+
+ bool ProcessLine()
+ {
+ if(this->RegexUser.find(this->Line))
+ {
+ User NewUser;
+
+ NewUser.UserName = this->RegexUser.match(1);
+ NewUser.EMail = this->RegexUser.match(2);
+ NewUser.Name = this->RegexUser.match(3);
+ NewUser.AccessTime = this->RegexUser.match(4);
+ P4->Users[this->RegexUser.match(1)] = NewUser;
+
+ return false;
+ }
+ return true;
+ }
+};
+
+//----------------------------------------------------------------------------
+/* Diff format:
+==== //depot/file#rev - /absolute/path/to/file ====
+(diff data)
+==== //depot/file2#rev - /absolute/path/to/file2 ====
+(diff data)
+==== //depot/file3#rev - /absolute/path/to/file3 ====
+==== //depot/file4#rev - /absolute/path/to/file4 ====
+(diff data)
+*/
+class cmCTestP4::DiffParser: public cmCTestVC::LineParser
+{
+public:
+ DiffParser(cmCTestP4* p4, const char* prefix)
+ : P4(p4), AlreadyNotified(false)
+ {
+ this->SetLog(&P4->Log, prefix);
+ this->RegexDiff.compile("^==== (.*)#[0-9]+ - (.*)");
+ }
+private:
+ cmCTestP4* P4;
+ bool AlreadyNotified;
+ std::string CurrentPath;
+ cmsys::RegularExpression RegexDiff;
+
+ bool ProcessLine()
+ {
+ if(!this->Line.empty() && this->Line[0] == '='
+ && this->RegexDiff.find(this->Line))
+ {
+ CurrentPath = this->RegexDiff.match(1);
+ AlreadyNotified = false;
+ }
+ else
+ {
+ if(!AlreadyNotified)
+ {
+ P4->DoModification(PathModified, CurrentPath);
+ AlreadyNotified = true;
+ }
+ }
+ return true;
+ }
+};
+
+//----------------------------------------------------------------------------
+cmCTestP4::User cmCTestP4::GetUserData(const std::string& username)
+{
+ std::map<std::string, cmCTestP4::User>::const_iterator it =
+ Users.find(username);
+
+ if(it == Users.end())
+ {
+ std::vector<char const*> p4_users;
+ SetP4Options(p4_users);
+ p4_users.push_back("users");
+ p4_users.push_back("-m");
+ p4_users.push_back("1");
+ p4_users.push_back(username.c_str());
+ p4_users.push_back(0);
+
+ UserParser out(this, "users-out> ");
+ OutputLogger err(this->Log, "users-err> ");
+ RunChild(&p4_users[0], &out, &err);
+
+ // The user should now be added to the map. Search again.
+ it = Users.find(username);
+ if(it == Users.end())
+ {
+ return cmCTestP4::User();
+ }
+ }
+
+ return it->second;
+}
+
+//----------------------------------------------------------------------------
+/* Commit format:
+
+Change 1111111 by user@client on 2013/09/26 11:50:36
+
+ text
+ text
+
+Affected files ...
+
+... //path/to/file#rev edit
+... //path/to/file#rev add
+... //path/to/file#rev delete
+... //path/to/file#rev integrate
+*/
+class cmCTestP4::DescribeParser: public cmCTestVC::LineParser
+{
+public:
+ DescribeParser(cmCTestP4* p4, const char* prefix):
+ LineParser('\n', false), P4(p4), Section(SectionHeader)
+ {
+ this->SetLog(&P4->Log, prefix);
+ this->RegexHeader.compile("^Change ([0-9]+) by (.+)@(.+) on (.*)$");
+ this->RegexDiff.compile("^\\.\\.\\. (.*)#[0-9]+ ([^ ]+)$");
+ }
+private:
+ cmsys::RegularExpression RegexHeader;
+ cmsys::RegularExpression RegexDiff;
+ cmCTestP4* P4;
+
+ typedef cmCTestP4::Revision Revision;
+ typedef cmCTestP4::Change Change;
+ std::vector<Change> Changes;
+ enum SectionType { SectionHeader, SectionBody, SectionDiffHeader,
+ SectionDiff, SectionCount };
+ SectionType Section;
+ Revision Rev;
+
+ virtual bool ProcessLine()
+ {
+ if(this->Line.empty())
+ {
+ this->NextSection();
+ }
+ else
+ {
+ switch(this->Section)
+ {
+ case SectionHeader: this->DoHeaderLine(); break;
+ case SectionBody: this->DoBodyLine(); break;
+ case SectionDiffHeader: break; // nothing to do
+ case SectionDiff: this->DoDiffLine(); break;
+ case SectionCount: break; // never happens
+ }
+ }
+ return true;
+ }
+
+ void NextSection()
+ {
+ if(this->Section == SectionDiff)
+ {
+ this->P4->DoRevision(this->Rev, this->Changes);
+ this->Rev = Revision();
+ }
+
+ this->Section = SectionType((this->Section+1) % SectionCount);
+ }
+
+ void DoHeaderLine()
+ {
+ if(this->RegexHeader.find(this->Line))
+ {
+ this->Rev.Rev = this->RegexHeader.match(1);
+ this->Rev.Date = this->RegexHeader.match(4);
+
+ cmCTestP4::User user = P4->GetUserData(this->RegexHeader.match(2));
+ this->Rev.Author = user.Name;
+ this->Rev.EMail = user.EMail;
+
+ this->Rev.Committer = this->Rev.Author;
+ this->Rev.CommitterEMail = this->Rev.EMail;
+ this->Rev.CommitDate = this->Rev.Date;
+ }
+ }
+
+ void DoBodyLine()
+ {
+ if(this->Line[0] == '\t')
+ {
+ this->Rev.Log += this->Line.substr(1);
+ }
+ this->Rev.Log += "\n";
+ }
+
+ void DoDiffLine()
+ {
+ if(this->RegexDiff.find(this->Line))
+ {
+ Change change;
+ std::string Path = this->RegexDiff.match(1);
+ if(Path.length() > 2 && Path[0] == '/' && Path[1] == '/')
+ {
+ size_t found = Path.find('/', 2);
+ if(found != std::string::npos)
+ {
+ Path = Path.substr(found + 1);
+ }
+ }
+
+ change.Path = Path;
+ std::string action = this->RegexDiff.match(2);
+
+ if(action == "add")
+ {
+ change.Action = 'A';
+ }
+ else if(action == "delete")
+ {
+ change.Action = 'D';
+ }
+ else if(action == "edit" || action == "integrate")
+ {
+ change.Action = 'M';
+ }
+
+ Changes.push_back(change);
+ }
+ }
+};
+
+//----------------------------------------------------------------------------
+void cmCTestP4::SetP4Options(std::vector<char const*> &CommandOptions)
+{
+ if(P4Options.empty())
+ {
+ const char* p4 = this->CommandLineTool.c_str();
+ P4Options.push_back(p4);
+
+ //The CTEST_P4_CLIENT variable sets the P4 client used when issuing
+ //Perforce commands, if it's different from the default one.
+ std::string client = this->CTest->GetCTestConfiguration("P4Client");
+ if(!client.empty())
+ {
+ P4Options.push_back("-c");
+ P4Options.push_back(client);
+ }
+
+ //Set the message language to be English, in case the P4 admin
+ //has localized them
+ P4Options.push_back("-L");
+ P4Options.push_back("en");
+
+ //The CTEST_P4_OPTIONS variable adds additional Perforce command line
+ //options before the main command
+ std::string opts = this->CTest->GetCTestConfiguration("P4Options");
+ std::vector<std::string> args =
+ cmSystemTools::ParseArguments(opts.c_str());
+
+ P4Options.insert(P4Options.end(), args.begin(), args.end());
+ }
+
+ CommandOptions.clear();
+ for(std::vector<std::string>::iterator i = P4Options.begin();
+ i != P4Options.end(); ++i)
+ {
+ CommandOptions.push_back(i->c_str());
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmCTestP4::GetWorkingRevision()
+{
+ std::vector<char const*> p4_identify;
+ SetP4Options(p4_identify);
+
+ p4_identify.push_back("changes");
+ p4_identify.push_back("-m");
+ p4_identify.push_back("1");
+ p4_identify.push_back("-t");
+
+ std::string source = this->SourceDirectory + "/...#have";
+ p4_identify.push_back(source.c_str());
+ p4_identify.push_back(0);
+
+ std::string rev;
+ IdentifyParser out(this, "p4_changes-out> ", rev);
+ OutputLogger err(this->Log, "p4_changes-err> ");
+
+ bool result = RunChild(&p4_identify[0], &out, &err);
+
+ // If there was a problem contacting the server return "<unknown>"
+ if(!result)
+ {
+ return "<unknown>";
+ }
+
+ if(rev.empty())
+ {
+ return "0";
+ }
+ else
+ {
+ return rev;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmCTestP4::NoteOldRevision()
+{
+ this->OldRevision = this->GetWorkingRevision();
+
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Old revision of repository is: "
+ << this->OldRevision << "\n");
+ this->PriorRev.Rev = this->OldRevision;
+}
+
+//----------------------------------------------------------------------------
+void cmCTestP4::NoteNewRevision()
+{
+ this->NewRevision = this->GetWorkingRevision();
+
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " New revision of repository is: "
+ << this->NewRevision << "\n");
+}
+
+//----------------------------------------------------------------------------
+void cmCTestP4::LoadRevisions()
+{
+ std::vector<char const*> p4_changes;
+ SetP4Options(p4_changes);
+
+ // Use 'p4 changes ...@old,new' to get a list of changelists
+ std::string range = this->SourceDirectory + "/...";
+
+ // If any revision is unknown it means we couldn't contact the server.
+ // Do not process updates
+ if(this->OldRevision == "<unknown>" || this->NewRevision == "<unknown>")
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " At least one of the revisions "
+ << "is unknown. No repository changes will be reported.\n");
+ return;
+ }
+
+ range.append("@").append(this->OldRevision)
+ .append(",").append(this->NewRevision);
+
+ p4_changes.push_back("changes");
+ p4_changes.push_back(range.c_str());
+ p4_changes.push_back(0);
+
+ ChangesParser out(this, "p4_changes-out> ");
+ OutputLogger err(this->Log, "p4_changes-err> ");
+
+ ChangeLists.clear();
+ this->RunChild(&p4_changes[0], &out, &err);
+
+ if(ChangeLists.empty())
+ return;
+
+ //p4 describe -s ...@1111111,2222222
+ std::vector<char const*> p4_describe;
+ for(std::vector<std::string>::reverse_iterator i = ChangeLists.rbegin();
+ i != ChangeLists.rend(); ++i)
+ {
+ SetP4Options(p4_describe);
+ p4_describe.push_back("describe");
+ p4_describe.push_back("-s");
+ p4_describe.push_back(i->c_str());
+ p4_describe.push_back(0);
+
+ DescribeParser outDescribe(this, "p4_describe-out> ");
+ OutputLogger errDescribe(this->Log, "p4_describe-err> ");
+ this->RunChild(&p4_describe[0], &outDescribe, &errDescribe);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmCTestP4::LoadModifications()
+{
+ std::vector<char const*> p4_diff;
+ SetP4Options(p4_diff);
+
+ p4_diff.push_back("diff");
+
+ //Ideally we would use -Od but not all clients support it
+ p4_diff.push_back("-dn");
+ std::string source = this->SourceDirectory + "/...";
+ p4_diff.push_back(source.c_str());
+ p4_diff.push_back(0);
+
+ DiffParser out(this, "p4_diff-out> ");
+ OutputLogger err(this->Log, "p4_diff-err> ");
+ this->RunChild(&p4_diff[0], &out, &err);
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestP4::UpdateCustom(const std::string& custom)
+{
+ std::vector<std::string> p4_custom_command;
+ cmSystemTools::ExpandListArgument(custom, p4_custom_command, true);
+
+ std::vector<char const*> p4_custom;
+ for(std::vector<std::string>::const_iterator
+ i = p4_custom_command.begin(); i != p4_custom_command.end(); ++i)
+ {
+ p4_custom.push_back(i->c_str());
+ }
+ p4_custom.push_back(0);
+
+ OutputLogger custom_out(this->Log, "p4_customsync-out> ");
+ OutputLogger custom_err(this->Log, "p4_customsync-err> ");
+
+ return this->RunUpdateCommand(&p4_custom[0], &custom_out, &custom_err);
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestP4::UpdateImpl()
+{
+ std::string custom = this->CTest->GetCTestConfiguration("P4UpdateCustom");
+ if(!custom.empty())
+ {
+ return this->UpdateCustom(custom);
+ }
+
+ // If we couldn't get a revision number before updating, abort.
+ if(this->OldRevision == "<unknown>")
+ {
+ this->UpdateCommandLine = "Unknown current revision";
+ cmCTestLog(this->CTest, ERROR_MESSAGE, " Unknown current revision\n");
+ return false;
+ }
+
+ std::vector<char const*> p4_sync;
+ SetP4Options(p4_sync);
+
+ p4_sync.push_back("sync");
+
+ // Get user-specified update options.
+ std::string opts = this->CTest->GetCTestConfiguration("UpdateOptions");
+ if(opts.empty())
+ {
+ opts = this->CTest->GetCTestConfiguration("P4UpdateOptions");
+ }
+ std::vector<std::string> args = cmSystemTools::ParseArguments(opts.c_str());
+ for(std::vector<std::string>::const_iterator ai = args.begin();
+ ai != args.end(); ++ai)
+ {
+ p4_sync.push_back(ai->c_str());
+ }
+
+ std::string source = this->SourceDirectory + "/...";
+
+ // Specify the start time for nightly testing.
+ if(this->CTest->GetTestModel() == cmCTest::NIGHTLY)
+ {
+ std::string date = this->GetNightlyTime();
+ //CTest reports the date as YYYY-MM-DD, Perforce needs it as YYYY/MM/DD
+ std::replace(date.begin(), date.end(), '-', '/');
+
+ //Revision specification: /...@"YYYY/MM/DD HH:MM:SS"
+ source.append("@\"").append(date).append("\"");
+ }
+
+ p4_sync.push_back(source.c_str());
+ p4_sync.push_back(0);
+
+ OutputLogger out(this->Log, "p4_sync-out> ");
+ OutputLogger err(this->Log, "p4_sync-err> ");
+
+ return this->RunUpdateCommand(&p4_sync[0], &out, &err);
+}
diff --git a/Source/CTest/cmCTestP4.h b/Source/CTest/cmCTestP4.h
new file mode 100644
index 000000000..7a53475fd
--- /dev/null
+++ b/Source/CTest/cmCTestP4.h
@@ -0,0 +1,71 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2013 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmCTestP4_h
+#define cmCTestP4_h
+
+#include "cmCTestGlobalVC.h"
+#include <vector>
+#include <map>
+
+/** \class cmCTestP4
+ * \brief Interaction with the Perforce command-line tool
+ *
+ */
+class cmCTestP4: public cmCTestGlobalVC
+{
+public:
+ /** Construct with a CTest instance and update log stream. */
+ cmCTestP4(cmCTest* ctest, std::ostream& log);
+
+ virtual ~cmCTestP4();
+
+private:
+ std::vector<std::string> ChangeLists;
+
+ struct User
+ {
+ std::string UserName;
+ std::string Name;
+ std::string EMail;
+ std::string AccessTime;
+
+ User(): UserName(), Name(), EMail(), AccessTime() {}
+ };
+ std::map<std::string, User> Users;
+ std::vector<std::string> P4Options;
+
+ User GetUserData(const std::string& username);
+ void SetP4Options(std::vector<char const*> &options);
+
+ std::string GetWorkingRevision();
+ virtual void NoteOldRevision();
+ virtual void NoteNewRevision();
+ virtual bool UpdateImpl();
+ bool UpdateCustom(const std::string& custom);
+
+ void LoadRevisions();
+ void LoadModifications();
+
+ // Parsing helper classes.
+ class IdentifyParser;
+ class ChangesParser;
+ class UserParser;
+ class DescribeParser;
+ class DiffParser;
+ friend class IdentifyParser;
+ friend class ChangesParser;
+ friend class UserParser;
+ friend class DescribeParser;
+ friend class DiffParser;
+};
+
+#endif
diff --git a/Source/CTest/cmCTestReadCustomFilesCommand.cxx b/Source/CTest/cmCTestReadCustomFilesCommand.cxx
index 5db01f98d..3b9d5527a 100644
--- a/Source/CTest/cmCTestReadCustomFilesCommand.cxx
+++ b/Source/CTest/cmCTestReadCustomFilesCommand.cxx
@@ -10,7 +10,6 @@
See the License for more information.
============================================================================*/
#include "cmCTestReadCustomFilesCommand.h"
-
#include "cmCTest.h"
bool cmCTestReadCustomFilesCommand
diff --git a/Source/CTest/cmCTestReadCustomFilesCommand.h b/Source/CTest/cmCTestReadCustomFilesCommand.h
index b984c84e9..c95694ae5 100644
--- a/Source/CTest/cmCTestReadCustomFilesCommand.h
+++ b/Source/CTest/cmCTestReadCustomFilesCommand.h
@@ -46,26 +46,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "ctest_read_custom_files";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "read CTestCustom files.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " ctest_read_custom_files( directory ... )\n"
- "Read all the CTestCustom.ctest or CTestCustom.cmake files from "
- "the given directory.";
- }
+ virtual std::string GetName() const { return "ctest_read_custom_files";}
cmTypeMacro(cmCTestReadCustomFilesCommand, cmCTestCommand);
diff --git a/Source/CTest/cmCTestRunScriptCommand.cxx b/Source/CTest/cmCTestRunScriptCommand.cxx
index fe429bd9d..7afbe04ba 100644
--- a/Source/CTest/cmCTestRunScriptCommand.cxx
+++ b/Source/CTest/cmCTestRunScriptCommand.cxx
@@ -54,9 +54,9 @@ bool cmCTestRunScriptCommand
int ret;
cmCTestScriptHandler::RunScript(this->CTest, args[i].c_str(), !np,
&ret);
- cmOStringStream str;
+ std::ostringstream str;
str << ret;
- this->Makefile->AddDefinition(returnVariable.c_str(), str.str().c_str());
+ this->Makefile->AddDefinition(returnVariable, str.str().c_str());
}
}
return true;
diff --git a/Source/CTest/cmCTestRunScriptCommand.h b/Source/CTest/cmCTestRunScriptCommand.h
index 05e78991a..0998e5c62 100644
--- a/Source/CTest/cmCTestRunScriptCommand.h
+++ b/Source/CTest/cmCTestRunScriptCommand.h
@@ -47,31 +47,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "ctest_run_script";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "runs a ctest -S script";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " ctest_run_script([NEW_PROCESS] script_file_name script_file_name1 \n"
- " script_file_name2 ... [RETURN_VALUE var])\n"
- "Runs a script or scripts much like if it was run from ctest -S. "
- "If no argument is provided then the current script is run using "
- "the current settings of the variables. If NEW_PROCESS is specified "
- "then each script will be run in a separate process."
- "If RETURN_VALUE is specified the return value of the last script "
- "run will be put into var.";
- }
+ virtual std::string GetName() const { return "ctest_run_script";}
cmTypeMacro(cmCTestRunScriptCommand, cmCTestCommand);
};
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index 0e2fa41b9..d108592f6 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -33,6 +33,9 @@ cmCTestRunTest::cmCTestRunTest(cmCTestTestHandler* handler)
this->CompressedOutput = "";
this->CompressionRatio = 2;
this->StopTimePassed = false;
+ this->NumberOfRunsLeft = 1; // default to 1 run of the test
+ this->RunUntilFail = false; // default to run the test once
+ this->RunAgain = false; // default to not having to run again
}
cmCTestRunTest::~cmCTestRunTest()
@@ -54,8 +57,7 @@ bool cmCTestRunTest::CheckOutput()
// Process has terminated and all output read.
return false;
}
- else if(p == cmsysProcess_Pipe_STDOUT ||
- p == cmsysProcess_Pipe_STDERR)
+ else if(p == cmsysProcess_Pipe_STDOUT)
{
// Store this line of output.
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
@@ -116,10 +118,10 @@ void cmCTestRunTest::CompressOutput()
unsigned char *encoded_buffer
= new unsigned char[static_cast<int>(outSize * 1.5)];
- unsigned long rlen
+ size_t rlen
= cmsysBase64_Encode(out, strm.total_out, encoded_buffer, 1);
- for(unsigned long i = 0; i < rlen; i++)
+ for(size_t i = 0; i < rlen; i++)
{
this->CompressedOutput += encoded_buffer[i];
}
@@ -155,7 +157,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
std::string> >::iterator passIt;
bool forceFail = false;
bool outputTestErrorsToConsole = false;
- if ( this->TestProperties->RequiredRegularExpressions.size() > 0 )
+ if (!this->TestProperties->RequiredRegularExpressions.empty())
{
bool found = false;
for ( passIt = this->TestProperties->RequiredRegularExpressions.begin();
@@ -184,7 +186,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
}
reason += "]";
}
- if ( this->TestProperties->ErrorRegularExpressions.size() > 0 )
+ if (!this->TestProperties->ErrorRegularExpressions.empty())
{
for ( passIt = this->TestProperties->ErrorRegularExpressions.begin();
passIt != this->TestProperties->ErrorRegularExpressions.end();
@@ -206,7 +208,13 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
bool success =
!forceFail && (retVal == 0 ||
this->TestProperties->RequiredRegularExpressions.size());
- if((success && !this->TestProperties->WillFail)
+ if(this->TestProperties->SkipReturnCode >= 0
+ && this->TestProperties->SkipReturnCode == retVal)
+ {
+ this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "***Skipped ");
+ }
+ else if((success && !this->TestProperties->WillFail)
|| (!success && this->TestProperties->WillFail))
{
this->TestResult.Status = cmCTestTestHandler::COMPLETED;
@@ -274,12 +282,12 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
// Set the working directory to the tests directory
std::string oldpath = cmSystemTools::GetCurrentWorkingDirectory();
- cmSystemTools::ChangeDirectory(this->TestProperties->Directory.c_str());
+ cmSystemTools::ChangeDirectory(this->TestProperties->Directory);
this->DartProcessing();
// restore working directory
- cmSystemTools::ChangeDirectory(oldpath.c_str());
+ cmSystemTools::ChangeDirectory(oldpath);
// if this is doing MemCheck then all the output needs to be put into
@@ -312,7 +320,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
*this->TestHandler->LogFile
<< "----------------------------------------------------------"
<< std::endl;
- if(this->TestResult.Reason.size())
+ if(!this->TestResult.Reason.empty())
{
*this->TestHandler->LogFile << reasonType << ":\n"
<< this->TestResult.Reason << "\n";
@@ -328,9 +336,9 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
*this->TestHandler->LogFile << "Test Failed.\n";
}
}
- *this->TestHandler->LogFile << "\"" << this->TestProperties->Name.c_str()
+ *this->TestHandler->LogFile << "\"" << this->TestProperties->Name
<< "\" end time: " << this->CTest->CurrentTime() << std::endl
- << "\"" << this->TestProperties->Name.c_str() << "\" time elapsed: "
+ << "\"" << this->TestProperties->Name << "\" time elapsed: "
<< buffer << std::endl
<< "----------------------------------------------------------"
<< std::endl << std::endl;
@@ -351,13 +359,50 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
this->MemCheckPostProcess();
this->ComputeWeightedCost();
}
- // Always push the current TestResult onto the
+ // If the test does not need to rerun push the current TestResult onto the
// TestHandler vector
- this->TestHandler->TestResults.push_back(this->TestResult);
+ if(!this->NeedsToRerun())
+ {
+ this->TestHandler->TestResults.push_back(this->TestResult);
+ }
delete this->TestProcess;
return passed;
}
+bool cmCTestRunTest::StartAgain()
+{
+ if(!this->RunAgain)
+ {
+ return false;
+ }
+ this->RunAgain = false; // reset
+ // change to tests directory
+ std::string current_dir = cmSystemTools::GetCurrentWorkingDirectory();
+ cmSystemTools::ChangeDirectory(this->TestProperties->Directory);
+ this->StartTest(this->TotalNumberOfTests);
+ // change back
+ cmSystemTools::ChangeDirectory(current_dir);
+ return true;
+}
+
+bool cmCTestRunTest::NeedsToRerun()
+{
+ this->NumberOfRunsLeft--;
+ if(this->NumberOfRunsLeft == 0)
+ {
+ return false;
+ }
+ // if number of runs left is not 0, and we are running until
+ // we find a failed test, then return true so the test can be
+ // restarted
+ if(this->RunUntilFail
+ && this->TestResult.Status == cmCTestTestHandler::COMPLETED)
+ {
+ this->RunAgain = true;
+ return true;
+ }
+ return false;
+}
//----------------------------------------------------------------------
void cmCTestRunTest::ComputeWeightedCost()
{
@@ -380,32 +425,21 @@ void cmCTestRunTest::MemCheckPostProcess()
{
return;
}
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, this->Index
- << ": process test output now: "
- << this->TestProperties->Name.c_str() << " "
- << this->TestResult.Name.c_str() << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, this->Index
+ << ": process test output now: "
+ << this->TestProperties->Name << " "
+ << this->TestResult.Name << std::endl,
+ this->TestHandler->GetQuiet());
cmCTestMemCheckHandler * handler = static_cast<cmCTestMemCheckHandler*>
(this->TestHandler);
- switch ( handler->MemoryTesterStyle )
- {
- case cmCTestMemCheckHandler::VALGRIND:
- handler->PostProcessValgrindTest(this->TestResult, this->Index);
- break;
- case cmCTestMemCheckHandler::PURIFY:
- handler->PostProcessPurifyTest(this->TestResult, this->Index);
- break;
- case cmCTestMemCheckHandler::BOUNDS_CHECKER:
- handler->PostProcessBoundsCheckerTest(this->TestResult, this->Index);
- break;
- default:
- break;
- }
+ handler->PostProcessTest(this->TestResult, this->Index);
}
//----------------------------------------------------------------------
// Starts the execution of a test. Returns once it has started
bool cmCTestRunTest::StartTest(size_t total)
{
+ this->TotalNumberOfTests = total; // save for rerun case
cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(2*getNumWidth(total) + 8)
<< "Start "
<< std::setw(getNumWidth(this->TestHandler->GetMaxIndex()))
@@ -459,9 +493,9 @@ bool cmCTestRunTest::StartTest(size_t total)
//Required file was not found
this->TestProcess = new cmProcess;
*this->TestHandler->LogFile << "Unable to find required file: "
- << file.c_str() << std::endl;
+ << file << std::endl;
cmCTestLog(this->CTest, ERROR_MESSAGE, "Unable to find required file: "
- << file.c_str() << std::endl);
+ << file << std::endl);
this->TestResult.Output = "Unable to find required file: " + file;
this->TestResult.FullCommandLine = "";
this->TestResult.CompletionStatus = "Not Run";
@@ -476,9 +510,9 @@ bool cmCTestRunTest::StartTest(size_t total)
// that has that information
this->TestProcess = new cmProcess;
*this->TestHandler->LogFile << "Unable to find executable: "
- << args[1].c_str() << std::endl;
+ << args[1] << std::endl;
cmCTestLog(this->CTest, ERROR_MESSAGE, "Unable to find executable: "
- << args[1].c_str() << std::endl);
+ << args[1] << std::endl);
this->TestResult.Output = "Unable to find executable: " + args[1];
this->TestResult.FullCommandLine = "";
this->TestResult.CompletionStatus = "Not Run";
@@ -500,10 +534,10 @@ bool cmCTestRunTest::StartTest(size_t total)
//----------------------------------------------------------------------
void cmCTestRunTest::ComputeArguments()
{
+ this->Arguments.clear(); // reset becaue this might be a rerun
std::vector<std::string>::const_iterator j =
this->TestProperties->Args.begin();
++j; // skip test name
-
// find the test executable
if(this->TestHandler->MemCheck)
{
@@ -542,11 +576,26 @@ void cmCTestRunTest::ComputeArguments()
}
this->TestResult.FullCommandLine = testCommand;
+ // Print the test command in verbose mode
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl
<< this->Index << ": "
<< (this->TestHandler->MemCheck?"MemCheck":"Test")
<< " command: " << testCommand
<< std::endl);
+
+ // Print any test-specific env vars in verbose mode
+ if (this->TestProperties->Environment.size())
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, this->Index << ": "
+ << "Environment variables: " << std::endl);
+ }
+ for(std::vector<std::string>::const_iterator e =
+ this->TestProperties->Environment.begin();
+ e != this->TestProperties->Environment.end(); ++e)
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, this->Index << ": " << *e
+ << std::endl);
+ }
}
//----------------------------------------------------------------------
@@ -557,7 +606,7 @@ void cmCTestRunTest::DartProcessing()
{
if (this->TestHandler->DartStuff.find(this->ProcessOutput.c_str()))
{
- std::string dartString = this->TestHandler->DartStuff.match(1);
+ this->TestResult.DartString = this->TestHandler->DartStuff.match(1);
// keep searching and replacing until none are left
while (this->TestHandler->DartStuff1.find(this->ProcessOutput.c_str()))
{
@@ -565,8 +614,6 @@ void cmCTestRunTest::DartProcessing()
cmSystemTools::ReplaceString(this->ProcessOutput,
this->TestHandler->DartStuff1.match(1).c_str(), "");
}
- this->TestResult.RegressionImages
- = this->TestHandler->GenerateRegressionImages(dartString);
}
}
}
@@ -668,8 +715,9 @@ bool cmCTestRunTest::ForkProcess(double testTimeOut, bool explicitTimeout,
{
timeout = 0;
}
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, this->Index << ": "
- << "Test timeout computed to be: " << timeout << "\n");
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, this->Index << ": "
+ << "Test timeout computed to be: " << timeout << "\n",
+ this->TestHandler->GetQuiet());
this->TestProcess->SetTimeout(timeout);
@@ -677,7 +725,7 @@ bool cmCTestRunTest::ForkProcess(double testTimeOut, bool explicitTimeout,
cmSystemTools::SaveRestoreEnvironment sre;
#endif
- if (environment && environment->size()>0)
+ if (environment && !environment->empty())
{
cmSystemTools::AppendEnv(*environment);
}
@@ -687,10 +735,28 @@ bool cmCTestRunTest::ForkProcess(double testTimeOut, bool explicitTimeout,
void cmCTestRunTest::WriteLogOutputTop(size_t completed, size_t total)
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(getNumWidth(total))
- << completed << "/");
- cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(getNumWidth(total))
- << total << " ");
+ // if this is the last or only run of this test
+ // then print out completed / total
+ // Only issue is if a test fails and we are running until fail
+ // then it will never print out the completed / total, same would
+ // got for run until pass. Trick is when this is called we don't
+ // yet know if we are passing or failing.
+ if(this->NumberOfRunsLeft == 1)
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(getNumWidth(total))
+ << completed << "/");
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(getNumWidth(total))
+ << total << " ");
+ }
+ // if this is one of several runs of a test just print blank space
+ // to keep things neat
+ else
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(getNumWidth(total))
+ << " " << " ");
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(getNumWidth(total))
+ << " " << " ");
+ }
if ( this->TestHandler->MemCheck )
{
@@ -701,11 +767,11 @@ void cmCTestRunTest::WriteLogOutputTop(size_t completed, size_t total)
cmCTestLog(this->CTest, HANDLER_OUTPUT, "Test");
}
- cmOStringStream indexStr;
+ std::ostringstream indexStr;
indexStr << " #" << this->Index << ":";
cmCTestLog(this->CTest, HANDLER_OUTPUT,
std::setw(3 + getNumWidth(this->TestHandler->GetMaxIndex()))
- << indexStr.str().c_str());
+ << indexStr.str());
cmCTestLog(this->CTest, HANDLER_OUTPUT, " ");
const int maxTestNameWidth = this->CTest->GetMaxTestNameWidth();
std::string outname = this->TestProperties->Name + " ";
@@ -716,18 +782,18 @@ void cmCTestRunTest::WriteLogOutputTop(size_t completed, size_t total)
<< this->TestProperties->Name << std::endl;
*this->TestHandler->LogFile << this->TestProperties->Index << "/"
<< this->TestHandler->TotalNumberOfTests
- << " Test: " << this->TestProperties->Name.c_str() << std::endl;
+ << " Test: " << this->TestProperties->Name << std::endl;
*this->TestHandler->LogFile << "Command: \"" << this->ActualCommand << "\"";
for (std::vector<std::string>::iterator i = this->Arguments.begin();
i != this->Arguments.end(); ++i)
{
*this->TestHandler->LogFile
- << " \"" << i->c_str() << "\"";
+ << " \"" << *i << "\"";
}
*this->TestHandler->LogFile << std::endl
<< "Directory: " << this->TestProperties->Directory << std::endl
- << "\"" << this->TestProperties->Name.c_str() << "\" start time: "
+ << "\"" << this->TestProperties->Name << "\" start time: "
<< this->StartTime << std::endl;
*this->TestHandler->LogFile
@@ -735,9 +801,9 @@ void cmCTestRunTest::WriteLogOutputTop(size_t completed, size_t total)
<< "----------------------------------------------------------"
<< std::endl;
*this->TestHandler->LogFile
- << this->ProcessOutput.c_str() << "<end of output>" << std::endl;
+ << this->ProcessOutput << "<end of output>" << std::endl;
cmCTestLog(this->CTest, HANDLER_OUTPUT, outname.c_str());
cmCTestLog(this->CTest, DEBUG, "Testing "
- << this->TestProperties->Name.c_str() << " ... ");
+ << this->TestProperties->Name << " ... ");
}
diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h
index 476f3e126..3b5c83160 100644
--- a/Source/CTest/cmCTestRunTest.h
+++ b/Source/CTest/cmCTestRunTest.h
@@ -27,6 +27,8 @@ public:
cmCTestRunTest(cmCTestTestHandler* handler);
~cmCTestRunTest();
+ void SetNumberOfRuns(int n) {this->NumberOfRunsLeft = n;}
+ void SetRunUntilFailOn() { this->RunUntilFail = true;}
void SetTestProperties(cmCTestTestHandler::cmCTestTestProperties * prop)
{ this->TestProperties = prop; }
@@ -58,7 +60,10 @@ public:
void ComputeArguments();
void ComputeWeightedCost();
+
+ bool StartAgain();
private:
+ bool NeedsToRerun();
void DartProcessing();
void ExeNotFound(std::string exe);
// Figures out a final timeout which is min(STOP_TIME, NOW+TIMEOUT)
@@ -92,6 +97,10 @@ private:
std::string ActualCommand;
std::vector<std::string> Arguments;
bool StopTimePassed;
+ bool RunUntilFail;
+ int NumberOfRunsLeft;
+ bool RunAgain;
+ size_t TotalNumberOfTests;
};
inline int getNumWidth(size_t n)
diff --git a/Source/CTest/cmCTestSVN.cxx b/Source/CTest/cmCTestSVN.cxx
index 2668c8eef..f7bd1f941 100644
--- a/Source/CTest/cmCTestSVN.cxx
+++ b/Source/CTest/cmCTestSVN.cxx
@@ -14,7 +14,7 @@
#include "cmCTest.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"
-#include "cmXMLSafe.h"
+#include "cmXMLWriter.h"
#include <cmsys/RegularExpression.hxx>
@@ -277,7 +277,7 @@ bool cmCTestSVN::UpdateImpl()
{
opts = this->CTest->GetCTestConfiguration("SVNUpdateOptions");
}
- std::vector<cmStdString> args = cmSystemTools::ParseArguments(opts.c_str());
+ std::vector<std::string> args = cmSystemTools::ParseArguments(opts.c_str());
// Specify the start time for nightly testing.
if(this->CTest->GetTestModel() == cmCTest::NIGHTLY)
@@ -287,7 +287,7 @@ bool cmCTestSVN::UpdateImpl()
std::vector<char const*> svn_update;
svn_update.push_back("update");
- for(std::vector<cmStdString>::const_iterator ai = args.begin();
+ for(std::vector<std::string>::const_iterator ai = args.begin();
ai != args.end(); ++ai)
{
svn_update.push_back(ai->c_str());
@@ -314,9 +314,9 @@ bool cmCTestSVN::RunSVNCommand(std::vector<char const*> const& parameters,
std::string userOptions =
this->CTest->GetCTestConfiguration("SVNOptions");
- std::vector<cmStdString> parsedUserOptions =
+ std::vector<std::string> parsedUserOptions =
cmSystemTools::ParseArguments(userOptions.c_str());
- for(std::vector<cmStdString>::iterator i = parsedUserOptions.begin();
+ for(std::vector<std::string>::iterator i = parsedUserOptions.begin();
i != parsedUserOptions.end(); ++i)
{
args.push_back(i->c_str());
@@ -361,10 +361,10 @@ private:
return true;
}
- virtual void StartElement(const char* name, const char** atts)
+ virtual void StartElement(const std::string& name, const char** atts)
{
this->CData.clear();
- if(strcmp(name, "logentry") == 0)
+ if(name == "logentry")
{
this->Rev = Revision();
this->Rev.SVNInfo = &SVNRepo;
@@ -374,7 +374,7 @@ private:
}
this->Changes.clear();
}
- else if(strcmp(name, "path") == 0)
+ else if(name == "path")
{
this->CurChange = Change();
if(const char* action = this->FindAttribute(atts, "action"))
@@ -389,28 +389,28 @@ private:
this->CData.insert(this->CData.end(), data, data+length);
}
- virtual void EndElement(const char* name)
+ virtual void EndElement(const std::string& name)
{
- if(strcmp(name, "logentry") == 0)
+ if(name == "logentry")
{
this->SVN->DoRevisionSVN(this->Rev, this->Changes);
}
- else if(strcmp(name, "path") == 0 && !this->CData.empty())
+ else if(!this->CData.empty() && name == "path")
{
std::string orig_path(&this->CData[0], this->CData.size());
std::string new_path = SVNRepo.BuildLocalPath( orig_path );
this->CurChange.Path.assign(new_path);
this->Changes.push_back(this->CurChange);
}
- else if(strcmp(name, "author") == 0 && !this->CData.empty())
+ else if(!this->CData.empty() && name == "author")
{
this->Rev.Author.assign(&this->CData[0], this->CData.size());
}
- else if(strcmp(name, "date") == 0 && !this->CData.empty())
+ else if(!this->CData.empty() && name == "date")
{
this->Rev.Date.assign(&this->CData[0], this->CData.size());
}
- else if(strcmp(name, "msg") == 0 && !this->CData.empty())
+ else if(!this->CData.empty() && name == "msg")
{
this->Rev.Log.assign(&this->CData[0], this->CData.size());
}
@@ -535,11 +535,11 @@ void cmCTestSVN::LoadModifications()
}
//----------------------------------------------------------------------------
-void cmCTestSVN::WriteXMLGlobal(std::ostream& xml)
+void cmCTestSVN::WriteXMLGlobal(cmXMLWriter& xml)
{
this->cmCTestGlobalVC::WriteXMLGlobal(xml);
- xml << "\t<SVNPath>" << this->RootInfo->Base << "</SVNPath>\n";
+ xml.Element("SVNPath", this->RootInfo->Base);
}
//----------------------------------------------------------------------------
diff --git a/Source/CTest/cmCTestSVN.h b/Source/CTest/cmCTestSVN.h
index c6548e3fb..f9febc52b 100644
--- a/Source/CTest/cmCTestSVN.h
+++ b/Source/CTest/cmCTestSVN.h
@@ -14,6 +14,8 @@
#include "cmCTestGlobalVC.h"
+#include <list>
+
/** \class cmCTestSVN
* \brief Interaction with subversion command-line tool
*
@@ -82,7 +84,7 @@ private:
void DoRevisionSVN(Revision const& revision,
std::vector<Change> const& changes);
- void WriteXMLGlobal(std::ostream& xml);
+ void WriteXMLGlobal(cmXMLWriter& xml);
// Parsing helper classes.
class InfoParser;
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index 8643cb3f7..ee15271a0 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -16,12 +16,12 @@
#include "cmake.h"
#include "cmFunctionBlocker.h"
#include "cmMakefile.h"
-#include "cmLocalGenerator.h"
#include "cmGlobalGenerator.h"
#include "cmGeneratedFileStream.h"
//#include <cmsys/RegularExpression.hxx>
#include <cmsys/Process.h>
+#include <cmsys/Directory.hxx>
// used for sleep
#ifdef _WIN32
@@ -85,7 +85,6 @@ cmCTestScriptHandler::cmCTestScriptHandler()
this->EmptyBinDir = false;
this->EmptyBinDirOnce = false;
this->Makefile = 0;
- this->LocalGenerator = 0;
this->CMake = 0;
this->GlobalGenerator = 0;
@@ -124,42 +123,21 @@ void cmCTestScriptHandler::Initialize()
// what time in seconds did this script start running
this->ScriptStartTime = 0;
+ delete this->Makefile;
this->Makefile = 0;
- if (this->LocalGenerator)
- {
- delete this->LocalGenerator;
- }
- this->LocalGenerator = 0;
- if (this->GlobalGenerator)
- {
- delete this->GlobalGenerator;
- }
+
+ delete this->GlobalGenerator;
this->GlobalGenerator = 0;
- if (this->CMake)
- {
- delete this->CMake;
- }
+
+ delete this->CMake;
}
//----------------------------------------------------------------------
cmCTestScriptHandler::~cmCTestScriptHandler()
{
- // local generator owns the makefile
- this->Makefile = 0;
- if (this->LocalGenerator)
- {
- delete this->LocalGenerator;
- }
- this->LocalGenerator = 0;
- if (this->GlobalGenerator)
- {
- delete this->GlobalGenerator;
- }
- this->GlobalGenerator = 0;
- if (this->CMake)
- {
- delete this->CMake;
- }
+ delete this->Makefile;
+ delete this->GlobalGenerator;
+ delete this->CMake;
}
@@ -182,8 +160,8 @@ int cmCTestScriptHandler::ProcessHandler()
for (size_t i=0; i < this->ConfigurationScripts.size(); ++i)
{
// for each script run it
- res += this->RunConfigurationScript
- (cmSystemTools::CollapseFullPath(this->ConfigurationScripts[i].c_str()),
+ res |= this->RunConfigurationScript
+ (cmSystemTools::CollapseFullPath(this->ConfigurationScripts[i]),
this->ScriptProcessScope[i]);
}
if ( res )
@@ -195,15 +173,14 @@ int cmCTestScriptHandler::ProcessHandler()
void cmCTestScriptHandler::UpdateElapsedTime()
{
- if (this->LocalGenerator)
+ if (this->Makefile)
{
// set the current elapsed time
char timeString[20];
int itime = static_cast<unsigned int>(cmSystemTools::GetTime()
- this->ScriptStartTime);
sprintf(timeString,"%i",itime);
- this->LocalGenerator->GetMakefile()->AddDefinition("CTEST_ELAPSED_TIME",
- timeString);
+ this->Makefile->AddDefinition("CTEST_ELAPSED_TIME", timeString);
}
}
@@ -213,7 +190,7 @@ void cmCTestScriptHandler::AddCTestCommand(cmCTestCommand* command)
cmCTestCommand* newCom = command;
newCom->CTest = this->CTest;
newCom->CTestScriptHandler = this;
- this->CMake->AddCommand(newCom);
+ this->CMake->GetState()->AddCommand(newCom);
}
int cmCTestScriptHandler::ExecuteScript(const std::string& total_script_arg)
@@ -221,16 +198,16 @@ int cmCTestScriptHandler::ExecuteScript(const std::string& total_script_arg)
// execute the script passing in the arguments to the script as well as the
// arguments from this invocation of cmake
std::vector<const char*> argv;
- argv.push_back(this->CTest->GetCTestExecutable());
+ argv.push_back(cmSystemTools::GetCTestCommand().c_str());
argv.push_back("-SR");
argv.push_back(total_script_arg.c_str());
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Executable for CTest is: " <<
- this->CTest->GetCTestExecutable() << "\n");
+ cmSystemTools::GetCTestCommand() << "\n");
// now pass through all the other arguments
- std::vector<cmStdString> &initArgs =
+ std::vector<std::string> &initArgs =
this->CTest->GetInitialCommandLineArguments();
//*** need to make sure this does not have the current script ***
for(size_t i=1; i < initArgs.size(); ++i)
@@ -298,7 +275,7 @@ int cmCTestScriptHandler::ExecuteScript(const std::string& total_script_arg)
cmsysProcess_Delete(cp);
if(failed)
{
- cmOStringStream message;
+ std::ostringstream message;
message << "Error running command: [";
message << result << "] ";
for(std::vector<const char*>::iterator i = argv.begin();
@@ -316,6 +293,15 @@ int cmCTestScriptHandler::ExecuteScript(const std::string& total_script_arg)
return retVal;
}
+static void ctestScriptProgressCallback(const char *m, float, void* cd)
+{
+ cmCTest* ctest = static_cast<cmCTest*>(cd);
+ if(m && *m)
+ {
+ cmCTestLog(ctest, HANDLER_OUTPUT, "-- " << m << std::endl);
+ }
+}
+
void cmCTestScriptHandler::CreateCMake()
{
// create a cmake instance to read the configuration script
@@ -323,25 +309,26 @@ void cmCTestScriptHandler::CreateCMake()
{
delete this->CMake;
delete this->GlobalGenerator;
- delete this->LocalGenerator;
+ delete this->Makefile;
}
this->CMake = new cmake;
+ this->CMake->SetHomeDirectory("");
+ this->CMake->SetHomeOutputDirectory("");
+ this->CMake->GetCurrentSnapshot().SetDefaultDefinitions();
this->CMake->AddCMakePaths();
- this->GlobalGenerator = new cmGlobalGenerator;
- this->GlobalGenerator->SetCMakeInstance(this->CMake);
-
- this->LocalGenerator = this->GlobalGenerator->CreateLocalGenerator();
- this->Makefile = this->LocalGenerator->GetMakefile();
+ this->GlobalGenerator = new cmGlobalGenerator(this->CMake);
- // Set CMAKE_CURRENT_SOURCE_DIR and CMAKE_CURRENT_BINARY_DIR.
- // Also, some commands need Makefile->GetCurrentDirectory().
+ cmState::Snapshot snapshot = this->CMake->GetCurrentSnapshot();
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
- this->Makefile->SetStartDirectory(cwd.c_str());
- this->Makefile->SetStartOutputDirectory(cwd.c_str());
+ snapshot.GetDirectory().SetCurrentSource(cwd);
+ snapshot.GetDirectory().SetCurrentBinary(cwd);
+ this->Makefile = new cmMakefile(this->GlobalGenerator, snapshot);
+
+ this->CMake->SetProgressCallback(ctestScriptProgressCallback, this->CTest);
// remove all cmake commands which are not scriptable, since they can't be
// used in ctest scripts
- this->CMake->RemoveUnscriptableCommands();
+ this->CMake->GetState()->RemoveUnscriptableCommands();
// add any ctest specific commands, probably should have common superclass
// for ctest commands to clean this up. If a couple more commands are
@@ -361,12 +348,6 @@ void cmCTestScriptHandler::CreateCMake()
this->AddCTestCommand(new cmCTestUploadCommand);
}
-void cmCTestScriptHandler::GetCommandDocumentation(
- std::vector<cmDocumentationEntry>& v) const
-{
- this->CMake->GetCommandDocumentation(v);
-}
-
//----------------------------------------------------------------------
// this sets up some variables for the script to use, creates the required
// cmake instance and generators, and then reads in the script
@@ -402,18 +383,22 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg)
this->Makefile->AddDefinition("CTEST_SCRIPT_NAME",
cmSystemTools::GetFilenameName(script).c_str());
this->Makefile->AddDefinition("CTEST_EXECUTABLE_NAME",
- this->CTest->GetCTestExecutable());
+ cmSystemTools::GetCTestCommand().c_str());
this->Makefile->AddDefinition("CMAKE_EXECUTABLE_NAME",
- this->CTest->GetCMakeExecutable());
+ cmSystemTools::GetCMakeCommand().c_str());
this->Makefile->AddDefinition("CTEST_RUN_CURRENT_SCRIPT", true);
this->UpdateElapsedTime();
// add the script arg if defined
- if (script_arg.size())
+ if (!script_arg.empty())
{
this->Makefile->AddDefinition("CTEST_SCRIPT_ARG", script_arg.c_str());
}
+#if defined(__CYGWIN__)
+ this->Makefile->AddDefinition("CMAKE_LEGACY_CYGWIN_WIN32", "0");
+#endif
+
// always add a function blocker to update the elapsed time
cmCTestScriptFunctionBlocker *f = new cmCTestScriptFunctionBlocker();
f->CTestScriptHandler = this;
@@ -427,11 +412,11 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg)
ctest scripting easier. */
std::string systemFile =
this->Makefile->GetModulesFile("CTestScriptMode.cmake");
- if (!this->Makefile->ReadListFile(0, systemFile.c_str()) ||
+ if (!this->Makefile->ReadListFile(systemFile.c_str()) ||
cmSystemTools::GetErrorOccuredFlag())
{
cmCTestLog(this->CTest, ERROR_MESSAGE, "Error in read:"
- << systemFile.c_str() << "\n");
+ << systemFile << "\n");
return 2;
}
@@ -441,19 +426,15 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg)
for (std::map<std::string, std::string>::const_iterator it = defs.begin();
it != defs.end(); ++it)
{
- this->Makefile->AddDefinition(it->first.c_str(), it->second.c_str());
+ this->Makefile->AddDefinition(it->first, it->second.c_str());
}
// finally read in the script
- if (!this->Makefile->ReadListFile(0, script.c_str()) ||
+ if (!this->Makefile->ReadListFile(script.c_str()) ||
cmSystemTools::GetErrorOccuredFlag())
{
- cmCTestLog(this->CTest, ERROR_MESSAGE, "Error in read script: "
- << script.c_str()
- << std::endl);
// Reset the error flag so that it can run more than
- // one script with an error when you
- // use ctest_run_script
+ // one script with an error when you use ctest_run_script.
cmSystemTools::ResetErrorOccuredFlag();
return 2;
}
@@ -476,8 +457,8 @@ int cmCTestScriptHandler::ExtractVariables()
= this->Makefile->GetSafeDefinition("CTEST_BINARY_DIRECTORY");
// add in translations for src and bin
- cmSystemTools::AddKeepPath(this->SourceDir.c_str());
- cmSystemTools::AddKeepPath(this->BinaryDir.c_str());
+ cmSystemTools::AddKeepPath(this->SourceDir);
+ cmSystemTools::AddKeepPath(this->BinaryDir);
this->CTestCmd
= this->Makefile->GetSafeDefinition("CTEST_COMMAND");
@@ -651,7 +632,7 @@ int cmCTestScriptHandler::RunCurrentScript()
if (!this->CTestEnv.empty())
{
std::vector<std::string> envArgs;
- cmSystemTools::ExpandListArgument(this->CTestEnv.c_str(),envArgs);
+ cmSystemTools::ExpandListArgument(this->CTestEnv,envArgs);
cmSystemTools::AppendEnv(envArgs);
}
@@ -707,7 +688,8 @@ int cmCTestScriptHandler::CheckOutSourceDir()
output = "";
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Run cvs: " << this->CVSCheckOut << std::endl);
- res = cmSystemTools::RunSingleCommand(this->CVSCheckOut.c_str(), &output,
+ res = cmSystemTools::RunSingleCommand(
+ this->CVSCheckOut.c_str(), &output, &output,
&retVal, this->CTestRoot.c_str(), this->HandlerVerbose,
0 /*this->TimeOut*/);
if (!res || retVal != 0)
@@ -737,11 +719,11 @@ int cmCTestScriptHandler::BackupDirectories()
// if for some reason those directories exist then first delete them
if (cmSystemTools::FileExists(this->BackupSourceDir.c_str()))
{
- cmSystemTools::RemoveADirectory(this->BackupSourceDir.c_str());
+ cmSystemTools::RemoveADirectory(this->BackupSourceDir);
}
if (cmSystemTools::FileExists(this->BackupBinaryDir.c_str()))
{
- cmSystemTools::RemoveADirectory(this->BackupBinaryDir.c_str());
+ cmSystemTools::RemoveADirectory(this->BackupBinaryDir);
}
// first rename the src and binary directories
@@ -771,13 +753,13 @@ int cmCTestScriptHandler::PerformExtraUpdates()
// do an initial cvs update as required
command = this->UpdateCmd;
- std::vector<cmStdString>::iterator it;
+ std::vector<std::string>::iterator it;
for (it = this->ExtraUpdates.begin();
it != this->ExtraUpdates.end();
++ it )
{
std::vector<std::string> cvsArgs;
- cmSystemTools::ExpandListArgument(it->c_str(),cvsArgs);
+ cmSystemTools::ExpandListArgument(*it,cvsArgs);
if (cvsArgs.size() == 2)
{
std::string fullCommand = command;
@@ -786,8 +768,9 @@ int cmCTestScriptHandler::PerformExtraUpdates()
output = "";
retVal = 0;
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Run Update: "
- << fullCommand.c_str() << std::endl);
- res = cmSystemTools::RunSingleCommand(fullCommand.c_str(), &output,
+ << fullCommand << std::endl);
+ res = cmSystemTools::RunSingleCommand(
+ fullCommand.c_str(), &output, &output,
&retVal, cvsArgs[0].c_str(),
this->HandlerVerbose, 0 /*this->TimeOut*/);
if (!res || retVal != 0)
@@ -907,8 +890,9 @@ int cmCTestScriptHandler::RunConfigurationDashboard()
command += "\"";
retVal = 0;
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Run cmake command: "
- << command.c_str() << std::endl);
- res = cmSystemTools::RunSingleCommand(command.c_str(), &output,
+ << command << std::endl);
+ res = cmSystemTools::RunSingleCommand(
+ command.c_str(), &output, &output,
&retVal, this->BinaryDir.c_str(),
this->HandlerVerbose, 0 /*this->TimeOut*/);
@@ -921,7 +905,7 @@ int cmCTestScriptHandler::RunConfigurationDashboard()
}
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "Write CMake output to file: " << cmakeOutputFile.c_str()
+ "Write CMake output to file: " << cmakeOutputFile
<< std::endl);
cmGeneratedFileStream fout(cmakeOutputFile.c_str());
if ( fout )
@@ -932,7 +916,7 @@ int cmCTestScriptHandler::RunConfigurationDashboard()
{
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Cannot open CMake output file: "
- << cmakeOutputFile.c_str() << " for writing" << std::endl);
+ << cmakeOutputFile << " for writing" << std::endl);
}
}
if (!res || retVal != 0)
@@ -953,8 +937,9 @@ int cmCTestScriptHandler::RunConfigurationDashboard()
output = "";
retVal = 0;
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Run ctest command: "
- << command.c_str() << std::endl);
- res = cmSystemTools::RunSingleCommand(command.c_str(), &output,
+ << command << std::endl);
+ res = cmSystemTools::RunSingleCommand(
+ command.c_str(), &output, &output,
&retVal, this->BinaryDir.c_str(), this->HandlerVerbose,
0 /*this->TimeOut*/);
@@ -967,13 +952,13 @@ int cmCTestScriptHandler::RunConfigurationDashboard()
{
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Unable to run cmake:" << std::endl
- << cmakeFailedOuput.c_str() << std::endl);
+ << cmakeFailedOuput << std::endl);
return 10;
}
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Unable to run ctest:" << std::endl
- << "command: " << command.c_str() << std::endl
- << "output: " << output.c_str() << std::endl);
+ << "command: " << command << std::endl
+ << "output: " << output << std::endl);
if (!res)
{
return 11;
@@ -985,8 +970,8 @@ int cmCTestScriptHandler::RunConfigurationDashboard()
// if all was succesful, delete the backup dirs to free up disk space
if (this->Backup)
{
- cmSystemTools::RemoveADirectory(this->BackupSourceDir.c_str());
- cmSystemTools::RemoveADirectory(this->BackupBinaryDir.c_str());
+ cmSystemTools::RemoveADirectory(this->BackupSourceDir);
+ cmSystemTools::RemoveADirectory(this->BackupBinaryDir);
}
return 0;
@@ -1027,11 +1012,11 @@ void cmCTestScriptHandler::RestoreBackupDirectories()
// if for some reason those directories exist then first delete them
if (cmSystemTools::FileExists(this->SourceDir.c_str()))
{
- cmSystemTools::RemoveADirectory(this->SourceDir.c_str());
+ cmSystemTools::RemoveADirectory(this->SourceDir);
}
if (cmSystemTools::FileExists(this->BinaryDir.c_str()))
{
- cmSystemTools::RemoveADirectory(this->BinaryDir.c_str());
+ cmSystemTools::RemoveADirectory(this->BinaryDir);
}
// rename the src and binary directories
rename(this->BackupSourceDir.c_str(), this->SourceDir.c_str());
@@ -1062,15 +1047,71 @@ bool cmCTestScriptHandler::EmptyBinaryDirectory(const char *sname)
return false;
}
+ // consider non existing target directory a success
+ if(!cmSystemTools::FileExists(sname))
+ {
+ return true;
+ }
+
// try to avoid deleting directories that we shouldn't
std::string check = sname;
check += "/CMakeCache.txt";
- if(cmSystemTools::FileExists(check.c_str()) &&
- !cmSystemTools::RemoveADirectory(sname))
+
+ if(!cmSystemTools::FileExists(check.c_str()))
{
return false;
}
- return true;
+
+ for(int i = 0; i < 5; ++i)
+ {
+ if(TryToRemoveBinaryDirectoryOnce(sname))
+ {
+ return true;
+ }
+ cmSystemTools::Delay(100);
+ }
+
+ return false;
+}
+
+//-------------------------------------------------------------------------
+bool cmCTestScriptHandler::TryToRemoveBinaryDirectoryOnce(
+ const std::string& directoryPath)
+{
+ cmsys::Directory directory;
+ directory.Load(directoryPath);
+
+ for(unsigned long i = 0; i < directory.GetNumberOfFiles(); ++i)
+ {
+ std::string path = directory.GetFile(i);
+
+ if(path == "." || path == ".." || path == "CMakeCache.txt")
+ {
+ continue;
+ }
+
+ std::string fullPath = directoryPath + std::string("/") + path;
+
+ bool isDirectory = cmSystemTools::FileIsDirectory(fullPath) &&
+ !cmSystemTools::FileIsSymlink(fullPath);
+
+ if(isDirectory)
+ {
+ if(!cmSystemTools::RemoveADirectory(fullPath))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if(!cmSystemTools::RemoveFile(fullPath))
+ {
+ return false;
+ }
+ }
+ }
+
+ return cmSystemTools::RemoveADirectory(directoryPath);
}
//-------------------------------------------------------------------------
diff --git a/Source/CTest/cmCTestScriptHandler.h b/Source/CTest/cmCTestScriptHandler.h
index 9d852cab6..c9d0b6a3c 100644
--- a/Source/CTest/cmCTestScriptHandler.h
+++ b/Source/CTest/cmCTestScriptHandler.h
@@ -18,7 +18,6 @@
#include "cmListFileCache.h"
class cmMakefile;
-class cmLocalGenerator;
class cmGlobalGenerator;
class cmake;
class cmCTestCommand;
@@ -110,7 +109,6 @@ public:
void Initialize();
void CreateCMake();
- void GetCommandDocumentation(std::vector<cmDocumentationEntry>& v) const;
cmake* GetCMake() { return this->CMake;}
private:
// reads in a script
@@ -136,26 +134,29 @@ private:
// Add ctest command
void AddCTestCommand(cmCTestCommand* command);
- std::vector<cmStdString> ConfigurationScripts;
+ // Try to remove the binary directory once
+ static bool TryToRemoveBinaryDirectoryOnce(const std::string& directoryPath);
+
+ std::vector<std::string> ConfigurationScripts;
std::vector<bool> ScriptProcessScope;
bool Backup;
bool EmptyBinDir;
bool EmptyBinDirOnce;
- cmStdString SourceDir;
- cmStdString BinaryDir;
- cmStdString BackupSourceDir;
- cmStdString BackupBinaryDir;
- cmStdString CTestRoot;
- cmStdString CVSCheckOut;
- cmStdString CTestCmd;
- cmStdString UpdateCmd;
- cmStdString CTestEnv;
- cmStdString InitialCache;
- cmStdString CMakeCmd;
- cmStdString CMOutFile;
- std::vector<cmStdString> ExtraUpdates;
+ std::string SourceDir;
+ std::string BinaryDir;
+ std::string BackupSourceDir;
+ std::string BackupBinaryDir;
+ std::string CTestRoot;
+ std::string CVSCheckOut;
+ std::string CTestCmd;
+ std::string UpdateCmd;
+ std::string CTestEnv;
+ std::string InitialCache;
+ std::string CMakeCmd;
+ std::string CMOutFile;
+ std::vector<std::string> ExtraUpdates;
double MinimumInterval;
double ContinuousDuration;
@@ -164,7 +165,6 @@ private:
double ScriptStartTime;
cmMakefile *Makefile;
- cmLocalGenerator *LocalGenerator;
cmGlobalGenerator *GlobalGenerator;
cmake *CMake;
};
diff --git a/Source/CTest/cmCTestSleepCommand.h b/Source/CTest/cmCTestSleepCommand.h
index 0f51ddfeb..740a7e12a 100644
--- a/Source/CTest/cmCTestSleepCommand.h
+++ b/Source/CTest/cmCTestSleepCommand.h
@@ -47,27 +47,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "ctest_sleep";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "sleeps for some amount of time";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " ctest_sleep(<seconds>)\n"
- "Sleep for given number of seconds.\n"
- " ctest_sleep(<time1> <duration> <time2>)\n"
- "Sleep for t=(time1 + duration - time2) seconds if t > 0.";
- }
+ virtual std::string GetName() const { return "ctest_sleep";}
cmTypeMacro(cmCTestSleepCommand, cmCTestCommand);
diff --git a/Source/CTest/cmCTestStartCommand.cxx b/Source/CTest/cmCTestStartCommand.cxx
index 228a17300..36576c540 100644
--- a/Source/CTest/cmCTestStartCommand.cxx
+++ b/Source/CTest/cmCTestStartCommand.cxx
@@ -12,7 +12,6 @@
#include "cmCTestStartCommand.h"
#include "cmCTest.h"
-#include "cmLocalGenerator.h"
#include "cmGlobalGenerator.h"
#include "cmCTestVC.h"
#include "cmGeneratedFileStream.h"
@@ -20,6 +19,7 @@
cmCTestStartCommand::cmCTestStartCommand()
{
this->CreateNewTag = true;
+ this->Quiet = false;
}
bool cmCTestStartCommand
@@ -57,6 +57,14 @@ bool cmCTestStartCommand
this->CreateNewTag = false;
}
}
+ if (cnt < args.size())
+ {
+ if (args[cnt] == "QUIET")
+ {
+ cnt ++;
+ this->Quiet = true;
+ }
+ }
if ( cnt < args.size() )
{
@@ -95,18 +103,20 @@ bool cmCTestStartCommand
std::string sourceDir = cmSystemTools::CollapseFullPath(src_dir);
std::string binaryDir = cmSystemTools::CollapseFullPath(bld_dir);
- this->CTest->SetCTestConfiguration("SourceDirectory", sourceDir.c_str());
- this->CTest->SetCTestConfiguration("BuildDirectory", binaryDir.c_str());
+ this->CTest->SetCTestConfiguration("SourceDirectory", sourceDir.c_str(),
+ this->Quiet);
+ this->CTest->SetCTestConfiguration("BuildDirectory", binaryDir.c_str(),
+ this->Quiet);
- cmCTestLog(this->CTest, HANDLER_OUTPUT, "Run dashboard with model "
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "Run dashboard with model "
<< smodel << std::endl
<< " Source directory: " << src_dir << std::endl
- << " Build directory: " << bld_dir << std::endl);
+ << " Build directory: " << bld_dir << std::endl, this->Quiet);
const char* track = this->CTest->GetSpecificTrack();
if ( track )
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
- " Track: " << track << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ " Track: " << track << std::endl, this->Quiet);
}
// Log startup actions.
@@ -124,14 +134,14 @@ bool cmCTestStartCommand
{
return false;
}
- if(!cmSystemTools::FileIsDirectory(sourceDir.c_str()))
+ if(!cmSystemTools::FileIsDirectory(sourceDir))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "given source path\n"
<< " " << sourceDir << "\n"
<< "which is not an existing directory. "
<< "Set CTEST_CHECKOUT_COMMAND to a command line to create it.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
@@ -160,7 +170,7 @@ bool cmCTestStartCommand::InitialCheckout(
{
// Use a generic VC object to run and log the command.
cmCTestVC vc(this->CTest, ofs);
- vc.SetSourceDirectory(sourceDir.c_str());
+ vc.SetSourceDirectory(sourceDir);
if(!vc.InitialCheckout(initialCheckoutCommand))
{
return false;
diff --git a/Source/CTest/cmCTestStartCommand.h b/Source/CTest/cmCTestStartCommand.h
index 6be47703e..eed196288 100644
--- a/Source/CTest/cmCTestStartCommand.h
+++ b/Source/CTest/cmCTestStartCommand.h
@@ -34,6 +34,7 @@ public:
ni->CTest = this->CTest;
ni->CTestScriptHandler = this->CTestScriptHandler;
ni->CreateNewTag = this->CreateNewTag;
+ ni->Quiet = this->Quiet;
return ni;
}
@@ -53,39 +54,24 @@ public:
}
/**
- * The name of the command as specified in CMakeList.txt.
- */
- virtual const char* GetName() const { return "ctest_start";}
-
- /**
- * Succinct documentation.
+ * Should this invocation of ctest_start output non-error messages?
*/
- virtual const char* GetTerseDocumentation() const
+ bool ShouldBeQuiet()
{
- return "Starts the testing for a given model";
+ return this->Quiet;
}
/**
- * More documentation.
+ * The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetFullDocumentation() const
- {
- return
- " ctest_start(Model [TRACK <track>] [APPEND] [source [binary]])\n"
- "Starts the testing for a given model. The command should be called "
- "after the binary directory is initialized. If the 'source' and "
- "'binary' directory are not specified, it reads the "
- "CTEST_SOURCE_DIRECTORY and CTEST_BINARY_DIRECTORY. If the track is "
- "specified, the submissions will go to the specified track. "
- "If APPEND is used, the existing TAG is used rather than "
- "creating a new one based on the current time stamp.";
- }
+ virtual std::string GetName() const { return "ctest_start";}
cmTypeMacro(cmCTestStartCommand, cmCTestCommand);
private:
bool InitialCheckout(std::ostream& ofs, std::string const& sourceDir);
bool CreateNewTag;
+ bool Quiet;
};
diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx
index 24974e3bc..5a8090c7c 100644
--- a/Source/CTest/cmCTestSubmitCommand.cxx
+++ b/Source/CTest/cmCTestSubmitCommand.cxx
@@ -27,7 +27,8 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
= this->Makefile->GetDefinition("CTEST_TRIGGER_SITE");
bool ctestDropSiteCDash
= this->Makefile->IsOn("CTEST_DROP_SITE_CDASH");
-
+ const char* ctestProjectName
+ = this->Makefile->GetDefinition("CTEST_PROJECT_NAME");
if ( !ctestDropMethod )
{
ctestDropMethod = "http";
@@ -43,44 +44,43 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
// error: CDash requires CTEST_DROP_LOCATION definition
// in CTestConfig.cmake
}
-
- this->CTest->SetCTestConfiguration("DropMethod", ctestDropMethod);
- this->CTest->SetCTestConfiguration("DropSite", ctestDropSite);
- this->CTest->SetCTestConfiguration("DropLocation", ctestDropLocation);
+ this->CTest->SetCTestConfiguration("ProjectName", ctestProjectName,
+ this->Quiet);
+ this->CTest->SetCTestConfiguration("DropMethod", ctestDropMethod,
+ this->Quiet);
+ this->CTest->SetCTestConfiguration("DropSite", ctestDropSite, this->Quiet);
+ this->CTest->SetCTestConfiguration("DropLocation", ctestDropLocation,
+ this->Quiet);
this->CTest->SetCTestConfiguration("IsCDash",
- ctestDropSiteCDash ? "TRUE" : "FALSE");
+ ctestDropSiteCDash ? "TRUE" : "FALSE", this->Quiet);
// Only propagate TriggerSite for non-CDash projects:
//
if ( !ctestDropSiteCDash )
{
- this->CTest->SetCTestConfiguration("TriggerSite", ctestTriggerSite);
+ this->CTest->SetCTestConfiguration("TriggerSite", ctestTriggerSite,
+ this->Quiet);
}
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
- "CurlOptions", "CTEST_CURL_OPTIONS");
+ "CurlOptions", "CTEST_CURL_OPTIONS", this->Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
- "DropSiteUser", "CTEST_DROP_SITE_USER");
+ "DropSiteUser", "CTEST_DROP_SITE_USER", this->Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
- "DropSitePassword", "CTEST_DROP_SITE_PASSWORD");
+ "DropSitePassword", "CTEST_DROP_SITE_PASSWORD", this->Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
- "ScpCommand", "CTEST_SCP_COMMAND");
+ "ScpCommand", "CTEST_SCP_COMMAND", this->Quiet);
const char* notesFilesVariable
= this->Makefile->GetDefinition("CTEST_NOTES_FILES");
if (notesFilesVariable)
{
std::vector<std::string> notesFiles;
- std::vector<cmStdString> newNotesFiles;
+ cmCTest::VectorOfStrings newNotesFiles;
cmSystemTools::ExpandListArgument(notesFilesVariable,notesFiles);
- std::vector<std::string>::iterator it;
- for ( it = notesFiles.begin();
- it != notesFiles.end();
- ++ it )
- {
- newNotesFiles.push_back(*it);
- }
+ newNotesFiles.insert(newNotesFiles.end(),
+ notesFiles.begin(), notesFiles.end());
this->CTest->GenerateNotesFile(newNotesFiles);
}
@@ -89,15 +89,10 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
if (extraFilesVariable)
{
std::vector<std::string> extraFiles;
- std::vector<cmStdString> newExtraFiles;
+ cmCTest::VectorOfStrings newExtraFiles;
cmSystemTools::ExpandListArgument(extraFilesVariable,extraFiles);
- std::vector<std::string>::iterator it;
- for ( it = extraFiles.begin();
- it != extraFiles.end();
- ++ it )
- {
- newExtraFiles.push_back(*it);
- }
+ newExtraFiles.insert(newExtraFiles.end(),
+ extraFiles.begin(), extraFiles.end());
if ( !this->CTest->SubmitExtraFiles(newExtraFiles))
{
this->SetError("problem submitting extra files.");
@@ -154,44 +149,77 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
static_cast<cmCTestSubmitHandler*>(handler)->SetOption("InternalTest",
this->InternalTest ? "ON" : "OFF");
+ handler->SetQuiet(this->Quiet);
+
+ if (this->CDashUpload)
+ {
+ static_cast<cmCTestSubmitHandler*>(handler)->
+ SetOption("CDashUploadFile", this->CDashUploadFile.c_str());
+ static_cast<cmCTestSubmitHandler*>(handler)->
+ SetOption("CDashUploadType", this->CDashUploadType.c_str());
+ }
return handler;
}
+//----------------------------------------------------------------------------
+bool cmCTestSubmitCommand::InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ this->CDashUpload = !args.empty() && args[0] == "CDASH_UPLOAD";
+ return this->cmCTestHandlerCommand::InitialPass(args, status);
+}
//----------------------------------------------------------------------------
bool cmCTestSubmitCommand::CheckArgumentKeyword(std::string const& arg)
{
- // Look for arguments specific to this command.
- if(arg == "PARTS")
+ if (this->CDashUpload)
{
- this->ArgumentDoing = ArgumentDoingParts;
- this->PartsMentioned = true;
- return true;
- }
+ if(arg == "CDASH_UPLOAD")
+ {
+ this->ArgumentDoing = ArgumentDoingCDashUpload;
+ return true;
+ }
- if(arg == "FILES")
- {
- this->ArgumentDoing = ArgumentDoingFiles;
- this->FilesMentioned = true;
- return true;
+ if(arg == "CDASH_UPLOAD_TYPE")
+ {
+ this->ArgumentDoing = ArgumentDoingCDashUploadType;
+ return true;
+ }
}
-
- if(arg == "RETRY_COUNT")
+ else
{
- this->ArgumentDoing = ArgumentDoingRetryCount;
- return true;
- }
+ // Look for arguments specific to this command.
+ if(arg == "PARTS")
+ {
+ this->ArgumentDoing = ArgumentDoingParts;
+ this->PartsMentioned = true;
+ return true;
+ }
- if(arg == "RETRY_DELAY")
- {
- this->ArgumentDoing = ArgumentDoingRetryDelay;
- return true;
- }
+ if(arg == "FILES")
+ {
+ this->ArgumentDoing = ArgumentDoingFiles;
+ this->FilesMentioned = true;
+ return true;
+ }
- if(arg == "INTERNAL_TEST_CHECKSUM")
- {
- this->InternalTest = true;
- return true;
+ if(arg == "RETRY_COUNT")
+ {
+ this->ArgumentDoing = ArgumentDoingRetryCount;
+ return true;
+ }
+
+ if(arg == "RETRY_DELAY")
+ {
+ this->ArgumentDoing = ArgumentDoingRetryDelay;
+ return true;
+ }
+
+ if(arg == "INTERNAL_TEST_CHECKSUM")
+ {
+ this->InternalTest = true;
+ return true;
+ }
}
// Look for other arguments.
@@ -212,7 +240,7 @@ bool cmCTestSubmitCommand::CheckArgumentValue(std::string const& arg)
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Part name \"" << arg << "\" is invalid.";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
this->ArgumentDoing = ArgumentDoingError;
@@ -222,14 +250,14 @@ bool cmCTestSubmitCommand::CheckArgumentValue(std::string const& arg)
if(this->ArgumentDoing == ArgumentDoingFiles)
{
- cmStdString filename(arg);
+ std::string filename(arg);
if(cmSystemTools::FileExists(filename.c_str()))
{
this->Files.insert(filename);
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "File \"" << filename << "\" does not exist. Cannot submit "
<< "a non-existent file.";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
@@ -250,6 +278,20 @@ bool cmCTestSubmitCommand::CheckArgumentValue(std::string const& arg)
return true;
}
+ if(this->ArgumentDoing == ArgumentDoingCDashUpload)
+ {
+ this->ArgumentDoing = ArgumentDoingNone;
+ this->CDashUploadFile = arg;
+ return true;
+ }
+
+ if(this->ArgumentDoing == ArgumentDoingCDashUploadType)
+ {
+ this->ArgumentDoing = ArgumentDoingNone;
+ this->CDashUploadType = arg;
+ return true;
+ }
+
// Look for other arguments.
return this->Superclass::CheckArgumentValue(arg);
}
diff --git a/Source/CTest/cmCTestSubmitCommand.h b/Source/CTest/cmCTestSubmitCommand.h
index 53ee8754e..19e8eafb5 100644
--- a/Source/CTest/cmCTestSubmitCommand.h
+++ b/Source/CTest/cmCTestSubmitCommand.h
@@ -32,6 +32,7 @@ public:
this->InternalTest = false;
this->RetryCount = "";
this->RetryDelay = "";
+ this->CDashUpload = false;
}
/**
@@ -45,48 +46,13 @@ public:
return ni;
}
- /**
- * The name of the command as specified in CMakeList.txt.
- */
- virtual const char* GetName() const { return "ctest_submit";}
+ virtual bool InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus &status);
/**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Submit results to a dashboard server.";
- }
-
- /**
- * More documentation.
+ * The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetFullDocumentation() const
- {
- return
- " ctest_submit([PARTS ...] [FILES ...] [RETRY_COUNT count] "
- " [RETRY_DELAY delay][RETURN_VALUE res])\n"
- "By default all available parts are submitted if no PARTS or FILES "
- "are specified. "
- "The PARTS option lists a subset of parts to be submitted. "
- "Valid part names are:\n"
- " Start = nothing\n"
- " Update = ctest_update results, in Update.xml\n"
- " Configure = ctest_configure results, in Configure.xml\n"
- " Build = ctest_build results, in Build.xml\n"
- " Test = ctest_test results, in Test.xml\n"
- " Coverage = ctest_coverage results, in Coverage.xml\n"
- " MemCheck = ctest_memcheck results, in DynamicAnalysis.xml\n"
- " Notes = Files listed by CTEST_NOTES_FILES, in Notes.xml\n"
- " ExtraFiles = Files listed by CTEST_EXTRA_SUBMIT_FILES\n"
- " Submit = nothing\n"
- "The FILES option explicitly lists specific files to be submitted. "
- "Each individual file must exist at the time of the call.\n"
- "The RETRY_DELAY option specifies how long in seconds to wait after "
- "a timed-out submission before attempting to re-submit.\n"
- "The RETRY_COUNT option specifies how many times to retry a timed-out "
- "submission.\n";
- }
+ virtual std::string GetName() const { return "ctest_submit";}
cmTypeMacro(cmCTestSubmitCommand, cmCTestHandlerCommand);
@@ -102,6 +68,8 @@ protected:
ArgumentDoingFiles,
ArgumentDoingRetryDelay,
ArgumentDoingRetryCount,
+ ArgumentDoingCDashUpload,
+ ArgumentDoingCDashUploadType,
ArgumentDoingLast2
};
@@ -112,6 +80,9 @@ protected:
cmCTest::SetOfStrings Files;
std::string RetryCount;
std::string RetryDelay;
+ bool CDashUpload;
+ std::string CDashUploadFile;
+ std::string CDashUploadType;
};
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index 941d34877..833cad6f0 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -10,12 +10,14 @@
See the License for more information.
============================================================================*/
#include "cmCTestSubmitHandler.h"
-
+#include "cmCTestScriptHandler.h"
+#include "cmake.h"
#include "cmSystemTools.h"
#include "cmVersion.h"
#include "cmGeneratedFileStream.h"
#include "cmCTest.h"
#include "cmXMLParser.h"
+#include "cmState.h"
#include <cmsys/Process.h>
#include <cmsys/Base64.h>
@@ -23,8 +25,10 @@
// For XML-RPC submission
#include "cm_xmlrpc.h"
+#include <cm_jsoncpp_reader.h>
// For curl submission
-#include "cm_curl.h"
+#include "cmCurl.h"
+#include "cmCTestCurl.h"
#include <sys/stat.h>
@@ -61,17 +65,17 @@ private:
std::string GetCurrentValue()
{
std::string val;
- if(this->CurrentValue.size())
+ if(!this->CurrentValue.empty())
{
val.assign(&this->CurrentValue[0], this->CurrentValue.size());
}
return val;
}
- virtual void StartElement(const char* name, const char** atts)
+ virtual void StartElement(const std::string& name, const char** atts)
{
this->CurrentValue.clear();
- if(strcmp(name, "cdash") == 0)
+ if(name == "cdash")
{
this->CDashVersion = this->FindAttribute(atts, "version");
}
@@ -82,9 +86,9 @@ private:
this->CurrentValue.insert(this->CurrentValue.end(), data, data+length);
}
- virtual void EndElement(const char* name)
+ virtual void EndElement(const std::string& name)
{
- if(strcmp(name, "status") == 0)
+ if(name == "status")
{
std::string status = cmSystemTools::UpperCase(this->GetCurrentValue());
if(status == "OK" || status == "SUCCESS")
@@ -100,15 +104,15 @@ private:
this->Status = STATUS_ERROR;
}
}
- else if(strcmp(name, "filename") == 0)
+ else if(name == "filename")
{
this->Filename = this->GetCurrentValue();
}
- else if(strcmp(name, "md5") == 0)
+ else if(name == "md5")
{
this->MD5 = this->GetCurrentValue();
}
- else if(strcmp(name, "message") == 0)
+ else if(name == "message")
{
this->Message = this->GetCurrentValue();
}
@@ -170,10 +174,10 @@ void cmCTestSubmitHandler::Initialize()
}
//----------------------------------------------------------------------------
-bool cmCTestSubmitHandler::SubmitUsingFTP(const cmStdString& localprefix,
- const std::set<cmStdString>& files,
- const cmStdString& remoteprefix,
- const cmStdString& url)
+bool cmCTestSubmitHandler::SubmitUsingFTP(const std::string& localprefix,
+ const std::set<std::string>& files,
+ const std::string& remoteprefix,
+ const std::string& url)
{
CURL *curl;
CURLcode res;
@@ -217,30 +221,31 @@ bool cmCTestSubmitHandler::SubmitUsingFTP(const cmStdString& localprefix,
::curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
- cmStdString local_file = *file;
+ std::string local_file = *file;
if ( !cmSystemTools::FileExists(local_file.c_str()) )
{
local_file = localprefix + "/" + *file;
}
- cmStdString upload_as
+ std::string upload_as
= url + "/" + remoteprefix + cmSystemTools::GetFilenameName(*file);
- struct stat st;
- if ( ::stat(local_file.c_str(), &st) )
+
+ if ( !cmSystemTools::FileExists(local_file.c_str()) )
{
cmCTestLog(this->CTest, ERROR_MESSAGE, " Cannot find file: "
- << local_file.c_str() << std::endl);
+ << local_file << std::endl);
::curl_easy_cleanup(curl);
::curl_global_cleanup();
return false;
}
+ unsigned long filelen = cmSystemTools::FileLength(local_file);
- ftpfile = ::fopen(local_file.c_str(), "rb");
- *this->LogFile << "\tUpload file: " << local_file.c_str() << " to "
- << upload_as.c_str() << std::endl;
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Upload file: "
- << local_file.c_str() << " to "
- << upload_as.c_str() << std::endl);
+ ftpfile = cmsys::SystemTools::Fopen(local_file, "rb");
+ *this->LogFile << "\tUpload file: " << local_file << " to "
+ << upload_as << std::endl;
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " Upload file: " << local_file << " to " << upload_as << std::endl,
+ this->Quiet);
::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
@@ -252,7 +257,7 @@ bool cmCTestSubmitHandler::SubmitUsingFTP(const cmStdString& localprefix,
// and give the size of the upload (optional)
::curl_easy_setopt(curl, CURLOPT_INFILESIZE,
- static_cast<long>(st.st_size));
+ static_cast<long>(filelen));
// and give curl the buffer for errors
::curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &error_buffer);
@@ -272,17 +277,17 @@ bool cmCTestSubmitHandler::SubmitUsingFTP(const cmStdString& localprefix,
// Now run off and do what you've been told!
res = ::curl_easy_perform(curl);
- if ( chunk.size() > 0 )
+ if (!chunk.empty())
{
- cmCTestLog(this->CTest, DEBUG, "CURL output: ["
+ cmCTestOptionalLog(this->CTest, DEBUG, "CURL output: ["
<< cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "]"
- << std::endl);
+ << std::endl, this->Quiet);
}
- if ( chunkDebug.size() > 0 )
+ if (!chunkDebug.empty())
{
- cmCTestLog(this->CTest, DEBUG, "CURL debug output: ["
+ cmCTestOptionalLog(this->CTest, DEBUG, "CURL debug output: ["
<< cmCTestLogWrite(&*chunkDebug.begin(), chunkDebug.size()) << "]"
- << std::endl);
+ << std::endl, this->Quiet);
}
fclose(ftpfile);
@@ -290,17 +295,17 @@ bool cmCTestSubmitHandler::SubmitUsingFTP(const cmStdString& localprefix,
{
cmCTestLog(this->CTest, ERROR_MESSAGE,
" Error when uploading file: "
- << local_file.c_str() << std::endl);
+ << local_file << std::endl);
cmCTestLog(this->CTest, ERROR_MESSAGE, " Error message was: "
<< error_buffer << std::endl);
*this->LogFile << " Error when uploading file: "
- << local_file.c_str()
+ << local_file
<< std::endl
<< " Error message was: "
<< error_buffer << std::endl
<< " Curl output was: ";
// avoid dereference of empty vector
- if(chunk.size())
+ if(!chunk.empty())
{
*this->LogFile << cmCTestLogWrite(&*chunk.begin(), chunk.size());
cmCTestLog(this->CTest, ERROR_MESSAGE, "CURL output: ["
@@ -314,8 +319,8 @@ bool cmCTestSubmitHandler::SubmitUsingFTP(const cmStdString& localprefix,
}
// always cleanup
::curl_easy_cleanup(curl);
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " Uploaded: " + local_file
- << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ " Uploaded: " + local_file << std::endl, this->Quiet);
}
}
::curl_global_cleanup();
@@ -324,22 +329,24 @@ bool cmCTestSubmitHandler::SubmitUsingFTP(const cmStdString& localprefix,
//----------------------------------------------------------------------------
// Uploading files is simpler
-bool cmCTestSubmitHandler::SubmitUsingHTTP(const cmStdString& localprefix,
- const std::set<cmStdString>& files,
- const cmStdString& remoteprefix,
- const cmStdString& url)
+bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix,
+ const std::set<std::string>& files,
+ const std::string& remoteprefix,
+ const std::string& url)
{
CURL *curl;
CURLcode res;
FILE* ftpfile;
char error_buffer[1024];
+ struct curl_slist *headers = ::curl_slist_append(NULL,
+ "Content-Type: text/xml");
/* In windows, this will init the winsock stuff */
::curl_global_init(CURL_GLOBAL_ALL);
- cmStdString dropMethod(this->CTest->GetCTestConfiguration("DropMethod"));
- cmStdString curlopt(this->CTest->GetCTestConfiguration("CurlOptions"));
+ std::string dropMethod(this->CTest->GetCTestConfiguration("DropMethod"));
+ std::string curlopt(this->CTest->GetCTestConfiguration("CurlOptions"));
std::vector<std::string> args;
- cmSystemTools::ExpandListArgument(curlopt.c_str(), args);
+ cmSystemTools::ExpandListArgument(curlopt, args);
bool verifyPeerOff = false;
bool verifyHostOff = false;
for( std::vector<std::string>::iterator i = args.begin();
@@ -354,7 +361,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const cmStdString& localprefix,
verifyHostOff = true;
}
}
- cmStdString::size_type kk;
+ std::string::size_type kk;
cmCTest::SetOfStrings::const_iterator file;
for ( file = files.begin(); file != files.end(); ++file )
{
@@ -362,16 +369,17 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const cmStdString& localprefix,
curl = curl_easy_init();
if(curl)
{
+ cmCurlSetCAInfo(curl);
if(verifyPeerOff)
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- " Set CURLOPT_SSL_VERIFYPEER to off\n");
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " Set CURLOPT_SSL_VERIFYPEER to off\n", this->Quiet);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
}
if(verifyHostOff)
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- " Set CURLOPT_SSL_VERIFYHOST to off\n");
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " Set CURLOPT_SSL_VERIFYHOST to off\n", this->Quiet);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
}
@@ -389,7 +397,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const cmStdString& localprefix,
break;
default:
curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
- if (this->HTTPProxyAuth.size() > 0)
+ if (!this->HTTPProxyAuth.empty())
{
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD,
this->HTTPProxyAuth.c_str());
@@ -414,18 +422,21 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const cmStdString& localprefix,
::curl_easy_setopt(curl, CURLOPT_PUT, 1);
::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
- cmStdString local_file = *file;
+ // Be sure to set Content-Type to satisfy fussy modsecurity rules
+ ::curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
+
+ std::string local_file = *file;
if ( !cmSystemTools::FileExists(local_file.c_str()) )
{
local_file = localprefix + "/" + *file;
}
- cmStdString remote_file
+ std::string remote_file
= remoteprefix + cmSystemTools::GetFilenameName(*file);
- *this->LogFile << "\tUpload file: " << local_file.c_str() << " to "
- << remote_file.c_str() << std::endl;
+ *this->LogFile << "\tUpload file: " << local_file << " to "
+ << remote_file << std::endl;
- cmStdString ofile = "";
+ std::string ofile = "";
for ( kk = 0; kk < remote_file.size(); kk ++ )
{
char c = remote_file[kk];
@@ -448,8 +459,8 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const cmStdString& localprefix,
ofile.append(hexCh);
}
}
- cmStdString upload_as
- = url + ((url.find("?",0) == cmStdString::npos) ? "?" : "&")
+ std::string upload_as
+ = url + ((url.find("?",0) == std::string::npos) ? "?" : "&")
+ "FileName=" + ofile;
upload_as += "&MD5=";
@@ -461,25 +472,26 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const cmStdString& localprefix,
else
{
char md5[33];
- cmSystemTools::ComputeFileMD5(local_file.c_str(), md5);
+ cmSystemTools::ComputeFileMD5(local_file, md5);
md5[32] = 0;
upload_as += md5;
}
- struct stat st;
- if ( ::stat(local_file.c_str(), &st) )
+ if( !cmSystemTools::FileExists(local_file.c_str()) )
{
cmCTestLog(this->CTest, ERROR_MESSAGE, " Cannot find file: "
- << local_file.c_str() << std::endl);
+ << local_file << std::endl);
::curl_easy_cleanup(curl);
+ ::curl_slist_free_all(headers);
::curl_global_cleanup();
return false;
}
+ unsigned long filelen = cmSystemTools::FileLength(local_file);
- ftpfile = ::fopen(local_file.c_str(), "rb");
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Upload file: "
- << local_file.c_str() << " to "
- << upload_as.c_str() << " Size: " << st.st_size << std::endl);
+ ftpfile = cmsys::SystemTools::Fopen(local_file, "rb");
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " Upload file: " << local_file << " to "
+ << upload_as << " Size: " << filelen << std::endl, this->Quiet);
// specify target
::curl_easy_setopt(curl,CURLOPT_URL, upload_as.c_str());
@@ -489,7 +501,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const cmStdString& localprefix,
// and give the size of the upload (optional)
::curl_easy_setopt(curl, CURLOPT_INFILESIZE,
- static_cast<long>(st.st_size));
+ static_cast<long>(filelen));
// and give curl the buffer for errors
::curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &error_buffer);
@@ -522,18 +534,18 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const cmStdString& localprefix,
chunk.assign(mock_output.begin(), mock_output.end());
}
- if ( chunk.size() > 0 )
+ if (!chunk.empty())
{
- cmCTestLog(this->CTest, DEBUG, "CURL output: ["
+ cmCTestOptionalLog(this->CTest, DEBUG, "CURL output: ["
<< cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "]"
- << std::endl);
+ << std::endl, this->Quiet);
this->ParseResponse(chunk);
}
- if ( chunkDebug.size() > 0 )
+ if (!chunkDebug.empty())
{
- cmCTestLog(this->CTest, DEBUG, "CURL debug output: ["
+ cmCTestOptionalLog(this->CTest, DEBUG, "CURL debug output: ["
<< cmCTestLogWrite(&*chunkDebug.begin(), chunkDebug.size()) << "]"
- << std::endl);
+ << std::endl, this->Quiet);
}
// If curl failed for any reason, or checksum fails, wait and retry
@@ -552,8 +564,9 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const cmStdString& localprefix,
for(int i = 0; i < count; i++)
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
- " Submit failed, waiting " << delay << " seconds...\n");
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ " Submit failed, waiting " << delay << " seconds...\n",
+ this->Quiet);
double stop = cmSystemTools::GetTime() + delay;
while(cmSystemTools::GetTime() < stop)
@@ -561,12 +574,12 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const cmStdString& localprefix,
cmSystemTools::Delay(100);
}
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
" Retry submission: Attempt " << (i + 1) << " of "
- << count << std::endl);
+ << count << std::endl, this->Quiet);
::fclose(ftpfile);
- ftpfile = ::fopen(local_file.c_str(), "rb");
+ ftpfile = cmsys::SystemTools::Fopen(local_file, "rb");
::curl_easy_setopt(curl, CURLOPT_INFILE, ftpfile);
chunk.clear();
@@ -575,11 +588,11 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const cmStdString& localprefix,
res = ::curl_easy_perform(curl);
- if ( chunk.size() > 0 )
+ if (!chunk.empty())
{
- cmCTestLog(this->CTest, DEBUG, "CURL output: ["
+ cmCTestOptionalLog(this->CTest, DEBUG, "CURL output: ["
<< cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "]"
- << std::endl);
+ << std::endl, this->Quiet);
this->ParseResponse(chunk);
}
@@ -595,16 +608,16 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const cmStdString& localprefix,
{
cmCTestLog(this->CTest, ERROR_MESSAGE,
" Error when uploading file: "
- << local_file.c_str() << std::endl);
+ << local_file << std::endl);
cmCTestLog(this->CTest, ERROR_MESSAGE, " Error message was: "
<< error_buffer << std::endl);
*this->LogFile << " Error when uploading file: "
- << local_file.c_str()
+ << local_file
<< std::endl
<< " Error message was: " << error_buffer
<< std::endl;
// avoid deref of begin for zero size array
- if(chunk.size())
+ if(!chunk.empty())
{
*this->LogFile << " Curl output was: "
<< cmCTestLogWrite(&*chunk.begin(), chunk.size())
@@ -614,15 +627,17 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const cmStdString& localprefix,
<< std::endl);
}
::curl_easy_cleanup(curl);
+ ::curl_slist_free_all(headers);
::curl_global_cleanup();
return false;
}
// always cleanup
::curl_easy_cleanup(curl);
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " Uploaded: " + local_file
- << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ " Uploaded: " + local_file << std::endl, this->Quiet);
}
}
+ ::curl_slist_free_all(headers);
::curl_global_cleanup();
return true;
}
@@ -666,12 +681,13 @@ void cmCTestSubmitHandler
//----------------------------------------------------------------------------
bool cmCTestSubmitHandler::TriggerUsingHTTP(
- const std::set<cmStdString>& files,
- const cmStdString& remoteprefix,
- const cmStdString& url)
+ const std::set<std::string>& files,
+ const std::string& remoteprefix,
+ const std::string& url)
{
CURL *curl;
char error_buffer[1024];
+
/* In windows, this will init the winsock stuff */
::curl_global_init(CURL_GLOBAL_ALL);
@@ -696,7 +712,7 @@ bool cmCTestSubmitHandler::TriggerUsingHTTP(
break;
default:
curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
- if (this->HTTPProxyAuth.size() > 0)
+ if (!this->HTTPProxyAuth.empty())
{
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD,
this->HTTPProxyAuth.c_str());
@@ -721,10 +737,10 @@ bool cmCTestSubmitHandler::TriggerUsingHTTP(
::curl_easy_setopt(curl, CURLOPT_FILE, (void *)&chunk);
::curl_easy_setopt(curl, CURLOPT_DEBUGDATA, (void *)&chunkDebug);
- cmStdString rfile
+ std::string rfile
= remoteprefix + cmSystemTools::GetFilenameName(*file);
- cmStdString ofile = "";
- cmStdString::iterator kk;
+ std::string ofile = "";
+ std::string::iterator kk;
for ( kk = rfile.begin(); kk < rfile.end(); ++ kk)
{
char c = *kk;
@@ -747,25 +763,25 @@ bool cmCTestSubmitHandler::TriggerUsingHTTP(
ofile.append(hexCh);
}
}
- cmStdString turl
- = url + ((url.find("?",0) == cmStdString::npos) ? "?" : "&")
+ std::string turl
+ = url + ((url.find("?",0) == std::string::npos) ? "?" : "&")
+ "xmlfile=" + ofile;
- *this->LogFile << "Trigger url: " << turl.c_str() << std::endl;
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Trigger url: "
- << turl.c_str() << std::endl);
+ *this->LogFile << "Trigger url: " << turl << std::endl;
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " Trigger url: " << turl << std::endl, this->Quiet);
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_easy_setopt(curl, CURLOPT_URL, turl.c_str());
if ( curl_easy_perform(curl) )
{
cmCTestLog(this->CTest, ERROR_MESSAGE, " Error when triggering: "
- << turl.c_str() << std::endl);
+ << turl << std::endl);
cmCTestLog(this->CTest, ERROR_MESSAGE, " Error message was: "
<< error_buffer << std::endl);
*this->LogFile << "\tTriggering failed with error: " << error_buffer
<< std::endl
<< " Error message was: " << error_buffer
<< std::endl;
- if(chunk.size())
+ if(!chunk.empty())
{
*this->LogFile
<< " Curl output was: "
@@ -779,43 +795,45 @@ bool cmCTestSubmitHandler::TriggerUsingHTTP(
return false;
}
- if ( chunk.size() > 0 )
+ if (!chunk.empty())
{
- cmCTestLog(this->CTest, DEBUG, "CURL output: ["
+ cmCTestOptionalLog(this->CTest, DEBUG, "CURL output: ["
<< cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "]"
- << std::endl);
+ << std::endl, this->Quiet);
}
- if ( chunkDebug.size() > 0 )
+ if (!chunkDebug.empty())
{
- cmCTestLog(this->CTest, DEBUG, "CURL debug output: ["
+ cmCTestOptionalLog(this->CTest, DEBUG, "CURL debug output: ["
<< cmCTestLogWrite(&*chunkDebug.begin(), chunkDebug.size())
- << "]" << std::endl);
+ << "]" << std::endl, this->Quiet);
}
// always cleanup
::curl_easy_cleanup(curl);
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl,
+ this->Quiet);
}
}
::curl_global_cleanup();
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " Dart server triggered..."
- << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Dart server triggered..."
+ << std::endl, this->Quiet);
return true;
}
//----------------------------------------------------------------------------
bool cmCTestSubmitHandler::SubmitUsingSCP(
- const cmStdString& scp_command,
- const cmStdString& localprefix,
- const std::set<cmStdString>& files,
- const cmStdString& remoteprefix,
- const cmStdString& url)
+ const std::string& scp_command,
+ const std::string& localprefix,
+ const std::set<std::string>& files,
+ const std::string& remoteprefix,
+ const std::string& url)
{
- if ( !scp_command.size() || !localprefix.size() ||
- !files.size() || !remoteprefix.size() || !url.size() )
+ if ( scp_command.empty() || localprefix.empty() ||
+ files.empty() || remoteprefix.empty() || url.empty() )
{
return 0;
}
+
std::vector<const char*> argv;
argv.push_back(scp_command.c_str()); // Scp command
argv.push_back(scp_command.c_str()); // Dummy string for file
@@ -840,9 +858,9 @@ bool cmCTestSubmitHandler::SubmitUsingSCP(
argv[1] = lfname.c_str();
std::string rfname = url + "/" + remoteprefix + *file;
argv[2] = rfname.c_str();
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Execute \"" << argv[0]
- << "\" \"" << argv[1] << "\" \""
- << argv[2] << "\"" << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Execute \"" << argv[0] << "\" \"" << argv[1] << "\" \""
+ << argv[2] << "\"" << std::endl, this->Quiet);
*this->LogFile << "Execute \"" << argv[0] << "\" \"" << argv[1] << "\" \""
<< argv[2] << "\"" << std::endl;
@@ -853,8 +871,8 @@ bool cmCTestSubmitHandler::SubmitUsingSCP(
while(cmsysProcess_WaitForData(cp, &data, &length, 0))
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- cmCTestLogWrite(data, length));
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ cmCTestLogWrite(data, length), this->Quiet);
}
cmsysProcess_WaitForExit(cp, 0);
@@ -866,8 +884,8 @@ bool cmCTestSubmitHandler::SubmitUsingSCP(
retVal = cmsysProcess_GetExitValue(cp);
if ( retVal != 0 )
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "\tSCP returned: "
- << retVal << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "\tSCP returned: " << retVal << std::endl, this->Quiet);
*this->LogFile << "\tSCP returned: " << retVal << std::endl;
problems ++;
}
@@ -906,13 +924,13 @@ bool cmCTestSubmitHandler::SubmitUsingSCP(
//----------------------------------------------------------------------------
bool cmCTestSubmitHandler::SubmitUsingCP(
- const cmStdString& localprefix,
- const std::set<cmStdString>& files,
- const cmStdString& remoteprefix,
- const cmStdString& destination)
+ const std::string& localprefix,
+ const std::set<std::string>& files,
+ const std::string& remoteprefix,
+ const std::string& destination)
{
- if ( !localprefix.size() ||
- !files.size() || !remoteprefix.size() || !destination.size() )
+ if ( localprefix.empty() ||
+ files.empty() || remoteprefix.empty() || destination.empty() )
{
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Missing arguments for submit via cp:\n"
@@ -922,6 +940,7 @@ bool cmCTestSubmitHandler::SubmitUsingCP(
<< "\tdestination: " << destination << std::endl);
return 0;
}
+
cmCTest::SetOfStrings::const_iterator file;
bool problems = false;
for ( file = files.begin(); file != files.end(); ++file )
@@ -930,13 +949,13 @@ bool cmCTestSubmitHandler::SubmitUsingCP(
cmSystemTools::ConvertToUnixSlashes(lfname);
lfname += "/" + *file;
std::string rfname = destination + "/" + remoteprefix + *file;
- cmSystemTools::CopyFileAlways(lfname.c_str(), rfname.c_str());
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Copy file: "
- << lfname.c_str() << " to "
- << rfname.c_str() << std::endl);
+ cmSystemTools::CopyFileAlways(lfname, rfname);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Copy file: "
+ << lfname << " to "
+ << rfname << std::endl, this->Quiet);
}
std::string tagDoneFile = destination + "/" + remoteprefix + "DONE";
- cmSystemTools::Touch(tagDoneFile.c_str(), true);
+ cmSystemTools::Touch(tagDoneFile, true);
if ( problems )
{
return false;
@@ -947,17 +966,17 @@ bool cmCTestSubmitHandler::SubmitUsingCP(
//----------------------------------------------------------------------------
#if defined(CTEST_USE_XMLRPC)
-bool cmCTestSubmitHandler::SubmitUsingXMLRPC(const cmStdString& localprefix,
- const std::set<cmStdString>& files,
- const cmStdString& remoteprefix,
- const cmStdString& url)
+bool cmCTestSubmitHandler::SubmitUsingXMLRPC(const std::string& localprefix,
+ const std::set<std::string>& files,
+ const std::string& remoteprefix,
+ const std::string& url)
{
xmlrpc_env env;
char ctestString[] = "CTest";
std::string ctestVersionString = cmVersion::GetCMakeVersion();
char* ctestVersion = const_cast<char*>(ctestVersionString.c_str());
- cmStdString realURL = url + "/" + remoteprefix + "/Command/";
+ std::string realURL = url + "/" + remoteprefix + "/Command/";
/* Start up our XML-RPC client library. */
xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS, ctestString, ctestVersion);
@@ -966,20 +985,21 @@ bool cmCTestSubmitHandler::SubmitUsingXMLRPC(const cmStdString& localprefix,
xmlrpc_env_init(&env);
/* Call the famous server at UserLand. */
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " Submitting to: "
- << realURL.c_str() << " (" << remoteprefix.c_str() << ")" << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Submitting to: "
+ << realURL.c_str() << " (" << remoteprefix.c_str() << ")" << std::endl,
+ this->Quiet);
cmCTest::SetOfStrings::const_iterator file;
for ( file = files.begin(); file != files.end(); ++file )
{
xmlrpc_value *result;
- cmStdString local_file = *file;
+ std::string local_file = *file;
if ( !cmSystemTools::FileExists(local_file.c_str()) )
{
local_file = localprefix + "/" + *file;
}
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " Submit file: "
- << local_file.c_str() << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Submit file: "
+ << local_file.c_str() << std::endl, this->Quiet);
struct stat st;
if ( ::stat(local_file.c_str(), &st) )
{
@@ -998,7 +1018,7 @@ bool cmCTestSubmitHandler::SubmitUsingXMLRPC(const cmStdString& localprefix,
return false;
}
size_t fileSize = static_cast<size_t>(st.st_size);
- FILE* fp = fopen(local_file.c_str(), "rb");
+ FILE* fp = cmsys::SystemTools::Fopen(local_file.c_str(), "rb");
if ( !fp )
{
cmCTestLog(this->CTest, ERROR_MESSAGE, " Cannot open file: "
@@ -1045,28 +1065,195 @@ bool cmCTestSubmitHandler::SubmitUsingXMLRPC(const cmStdString& localprefix,
return true;
}
#else
-bool cmCTestSubmitHandler::SubmitUsingXMLRPC(cmStdString const&,
- std::set<cmStdString> const&,
- cmStdString const&,
- cmStdString const&)
+bool cmCTestSubmitHandler::SubmitUsingXMLRPC(std::string const&,
+ std::set<std::string> const&,
+ std::string const&,
+ std::string const&)
{
return false;
}
#endif
+void cmCTestSubmitHandler::ConstructCDashURL(std::string& dropMethod,
+ std::string& url)
+{
+ dropMethod = this->CTest->GetCTestConfiguration("DropMethod");
+ url = dropMethod;
+ url += "://";
+ if ( this->CTest->GetCTestConfiguration("DropSiteUser").size() > 0 )
+ {
+ url += this->CTest->GetCTestConfiguration("DropSiteUser");
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ this->CTest->GetCTestConfiguration("DropSiteUser").c_str(),
+ this->Quiet);
+ if ( this->CTest->GetCTestConfiguration("DropSitePassword").size() > 0 )
+ {
+ url += ":" + this->CTest->GetCTestConfiguration("DropSitePassword");
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, ":******",
+ this->Quiet);
+ }
+ url += "@";
+ }
+ url += this->CTest->GetCTestConfiguration("DropSite") +
+ this->CTest->GetCTestConfiguration("DropLocation");
+}
+
+
+int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
+ std::string const& typeString)
+{
+ if (file.empty())
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Upload file not specified\n");
+ return -1;
+ }
+ if (!cmSystemTools::FileExists(file))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Upload file not found: '" << file << "'\n");
+ return -1;
+ }
+ cmCTestCurl curl(this->CTest);
+ std::string curlopt(this->CTest->GetCTestConfiguration("CurlOptions"));
+ std::vector<std::string> args;
+ cmSystemTools::ExpandListArgument(curlopt, args);
+ curl.SetCurlOptions(args);
+ curl.SetTimeOutSeconds(SUBMIT_TIMEOUT_IN_SECONDS_DEFAULT);
+ std::string dropMethod;
+ std::string url;
+ this->ConstructCDashURL(dropMethod, url);
+ std::string::size_type pos = url.find("submit.php?");
+ url = url.substr(0, pos+10);
+ if ( ! (dropMethod == "http" || dropMethod == "https" ) )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Only http and https are supported for CDASH_UPLOAD\n");
+ return -1;
+ }
+ char md5sum[33];
+ md5sum[32] = 0;
+ cmSystemTools::ComputeFileMD5(file, md5sum);
+ // 1. request the buildid and check to see if the file
+ // has already been uploaded
+ // TODO I added support for subproject. You would need to add
+ // a "&subproject=subprojectname" to the first POST.
+ cmCTestScriptHandler* ch =
+ static_cast<cmCTestScriptHandler*>(this->CTest->GetHandler("script"));
+ cmake* cm = ch->GetCMake();
+ const char* subproject = cm->GetState()->GetGlobalProperty("SubProject");
+ // TODO: Encode values for a URL instead of trusting caller.
+ std::ostringstream str;
+ str << "project="
+ << curl.Escape(this->CTest->GetCTestConfiguration("ProjectName")) << "&";
+ if(subproject)
+ {
+ str << "subproject=" << curl.Escape(subproject) << "&";
+ }
+ str << "stamp=" << curl.Escape(this->CTest->GetCurrentTag()) << "-"
+ << curl.Escape(this->CTest->GetTestModelString()) << "&"
+ << "model=" << curl.Escape(this->CTest->GetTestModelString()) << "&"
+ << "build="
+ << curl.Escape(this->CTest->GetCTestConfiguration("BuildName")) << "&"
+ << "site="
+ << curl.Escape(this->CTest->GetCTestConfiguration("Site")) << "&"
+ << "track="
+ << curl.Escape(this->CTest->GetTestModelString()) << "&"
+ << "starttime=" << (int)cmSystemTools::GetTime() << "&"
+ << "endtime=" << (int)cmSystemTools::GetTime() << "&"
+ << "datafilesmd5[0]=" << md5sum << "&"
+ << "type=" << curl.Escape(typeString);
+ std::string fields = str.str();
+ cmCTestOptionalLog(this->CTest, DEBUG, "fields: " << fields << "\nurl:"
+ << url << "\nfile: " << file << "\n", this->Quiet);
+ std::string response;
+ if(!curl.HttpRequest(url, fields, response))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Error in HttpRequest\n" << response);
+ return -1;
+ }
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Request upload response: [" << response << "]\n", this->Quiet);
+ Json::Value json;
+ Json::Reader reader;
+ if(!reader.parse(response, json))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "error parsing json string [" << response << "]\n"
+ << reader.getFormattedErrorMessages() << "\n");
+ return -1;
+ }
+ if(json["status"].asInt() != 0)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Bad status returned from CDash: "
+ << json["status"].asInt());
+ return -1;
+ }
+ if(json["datafilesmd5"].isArray())
+ {
+ int datares = json["datafilesmd5"][0].asInt();
+ if(datares == 1)
+ {
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "File already exists on CDash, skip upload " << file << "\n",
+ this->Quiet);
+ return 0;
+ }
+ }
+ else
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "bad datafilesmd5 value in response "
+ << response << "\n");
+ return -1;
+ }
+
+ std::string upload_as = cmSystemTools::GetFilenameName(file);
+ std::ostringstream fstr;
+ fstr << "type=" << curl.Escape(typeString) << "&"
+ << "md5=" << md5sum << "&"
+ << "filename=" << curl.Escape(upload_as) << "&"
+ << "buildid=" << json["buildid"].asString();
+ if(!curl.UploadFile(file, url, fstr.str(), response))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "error uploading to CDash. "
+ << file << " " << url << " " << fstr.str());
+ return -1;
+ }
+ if(!reader.parse(response, json))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "error parsing json string [" << response << "]\n"
+ << reader.getFormattedErrorMessages() << "\n");
+ return -1;
+ }
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Upload file response: [" << response << "]\n", this->Quiet );
+ return 0;
+}
+
//----------------------------------------------------------------------------
int cmCTestSubmitHandler::ProcessHandler()
{
+ const char* cdashUploadFile = this->GetOption("CDashUploadFile");
+ const char* cdashUploadType = this->GetOption("CDashUploadType");
+ if(cdashUploadFile && cdashUploadType)
+ {
+ return this->HandleCDashUploadFile(cdashUploadFile, cdashUploadType);
+ }
std::string iscdash = this->CTest->GetCTestConfiguration("IsCDash");
// cdash does not need to trigger so just return true
- if(iscdash.size())
+ if(!iscdash.empty())
{
this->CDash = true;
}
const std::string &buildDirectory
= this->CTest->GetCTestConfiguration("BuildDirectory");
- if ( buildDirectory.size() == 0 )
+ if (buildDirectory.empty())
{
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Cannot find BuildDirectory key in the DartConfiguration.tcl"
@@ -1085,7 +1272,7 @@ int cmCTestSubmitHandler::ProcessHandler()
}
if ( getenv("HTTP_PROXY_TYPE") )
{
- cmStdString type = getenv("HTTP_PROXY_TYPE");
+ std::string type = getenv("HTTP_PROXY_TYPE");
// HTTP/SOCKS4/SOCKS5
if ( type == "HTTP" )
{
@@ -1122,7 +1309,7 @@ int cmCTestSubmitHandler::ProcessHandler()
}
if ( getenv("FTP_PROXY_TYPE") )
{
- cmStdString type = getenv("FTP_PROXY_TYPE");
+ std::string type = getenv("FTP_PROXY_TYPE");
// HTTP/SOCKS4/SOCKS5
if ( type == "HTTP" )
{
@@ -1139,15 +1326,15 @@ int cmCTestSubmitHandler::ProcessHandler()
}
}
- if ( this->HTTPProxy.size() > 0 )
+ if (!this->HTTPProxy.empty())
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " Use HTTP Proxy: "
- << this->HTTPProxy << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Use HTTP Proxy: "
+ << this->HTTPProxy << std::endl, this->Quiet);
}
- if ( this->FTPProxy.size() > 0 )
+ if (!this->FTPProxy.empty())
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " Use FTP Proxy: "
- << this->FTPProxy << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Use FTP Proxy: "
+ << this->FTPProxy << std::endl, this->Quiet);
}
cmGeneratedFileStream ofs;
this->StartLogFile("Submit", ofs);
@@ -1159,11 +1346,7 @@ int cmCTestSubmitHandler::ProcessHandler()
{
// Submit the explicitly selected files:
//
- cmCTest::SetOfStrings::const_iterator it;
- for (it = this->Files.begin(); it != this->Files.end(); ++it)
- {
- files.insert(*it);
- }
+ files.insert(this->Files.begin(), this->Files.end());
}
// Add to the list of files to submit from any selected, existing parts:
@@ -1178,21 +1361,21 @@ int cmCTestSubmitHandler::ProcessHandler()
this->CTest->AddIfExists(cmCTest::PartTest, "Test.xml");
if(this->CTest->AddIfExists(cmCTest::PartCoverage, "Coverage.xml"))
{
- cmCTest::VectorOfStrings gfiles;
+ std::vector<std::string> gfiles;
std::string gpath
= buildDirectory + "/Testing/" + this->CTest->GetCurrentTag();
std::string::size_type glen = gpath.size() + 1;
gpath = gpath + "/CoverageLog*";
- cmCTestLog(this->CTest, DEBUG, "Globbing for: " << gpath.c_str()
- << std::endl);
+ cmCTestOptionalLog(this->CTest, DEBUG, "Globbing for: " << gpath
+ << std::endl, this->Quiet);
if ( cmSystemTools::SimpleGlob(gpath, gfiles, 1) )
{
size_t cc;
for ( cc = 0; cc < gfiles.size(); cc ++ )
{
gfiles[cc] = gfiles[cc].substr(glen);
- cmCTestLog(this->CTest, DEBUG, "Glob file: " << gfiles[cc].c_str()
- << std::endl);
+ cmCTestOptionalLog(this->CTest, DEBUG, "Glob file: " << gfiles[cc]
+ << std::endl, this->Quiet);
this->CTest->AddSubmitFile(cmCTest::PartCoverage, gfiles[cc].c_str());
}
}
@@ -1218,11 +1401,7 @@ int cmCTestSubmitHandler::ProcessHandler()
// Submit files from this part.
std::vector<std::string> const& pfiles = this->CTest->GetSubmitFiles(p);
- for(std::vector<std::string>::const_iterator pi = pfiles.begin();
- pi != pfiles.end(); ++pi)
- {
- files.insert(*pi);
- }
+ files.insert(pfiles.begin(), pfiles.end());
}
if ( ofs )
@@ -1232,29 +1411,29 @@ int cmCTestSubmitHandler::ProcessHandler()
cmCTest::SetOfStrings::iterator it;
for ( it = files.begin(); it != files.end(); ++ it )
{
- ofs << cnt << "\t" << it->c_str() << std::endl;
+ ofs << cnt << "\t" << *it << std::endl;
cnt ++;
}
}
- cmCTestLog(this->CTest, HANDLER_OUTPUT, "Submit files (using "
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "Submit files (using "
<< this->CTest->GetCTestConfiguration("DropMethod") << ")"
- << std::endl);
+ << std::endl, this->Quiet);
const char* specificTrack = this->CTest->GetSpecificTrack();
if ( specificTrack )
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " Send to track: "
- << specificTrack << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Send to track: "
+ << specificTrack << std::endl, this->Quiet);
}
this->SetLogFile(&ofs);
- cmStdString dropMethod(this->CTest->GetCTestConfiguration("DropMethod"));
+ std::string dropMethod(this->CTest->GetCTestConfiguration("DropMethod"));
if ( dropMethod == "" || dropMethod == "ftp" )
{
ofs << "Using drop method: FTP" << std::endl;
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " Using FTP submit method"
- << std::endl
- << " Drop site: ftp://");
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ " Using FTP submit method" << std::endl << " Drop site: ftp://",
+ this->Quiet);
std::string url = "ftp://";
url += cmCTest::MakeURLSafe(
this->CTest->GetCTestConfiguration("DropSiteUser")) + ":" +
@@ -1263,20 +1442,22 @@ int cmCTestSubmitHandler::ProcessHandler()
this->CTest->GetCTestConfiguration("DropSite") +
cmCTest::MakeURLSafe(
this->CTest->GetCTestConfiguration("DropLocation"));
- if ( this->CTest->GetCTestConfiguration("DropSiteUser").size() > 0 )
+ if (!this->CTest->GetCTestConfiguration("DropSiteUser").empty())
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
this->CTest->GetCTestConfiguration(
- "DropSiteUser").c_str());
- if ( this->CTest->GetCTestConfiguration("DropSitePassword").size() > 0 )
+ "DropSiteUser").c_str(), this->Quiet);
+ if (!this->CTest->GetCTestConfiguration("DropSitePassword").empty())
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT, ":******");
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, ":******",
+ this->Quiet);
}
- cmCTestLog(this->CTest, HANDLER_OUTPUT, "@");
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "@", this->Quiet);
}
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
this->CTest->GetCTestConfiguration("DropSite")
- << this->CTest->GetCTestConfiguration("DropLocation") << std::endl);
+ << this->CTest->GetCTestConfiguration("DropLocation") << std::endl,
+ this->Quiet);
if ( !this->SubmitUsingFTP(buildDirectory + "/Testing/"
+ this->CTest->GetCurrentTag(),
files, prefix, url) )
@@ -1289,11 +1470,12 @@ int cmCTestSubmitHandler::ProcessHandler()
}
if(!this->CDash)
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " Using HTTP trigger method"
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ " Using HTTP trigger method"
<< std::endl
<< " Trigger site: "
<< this->CTest->GetCTestConfiguration("TriggerSite")
- << std::endl);
+ << std::endl, this->Quiet);
if ( !this->
TriggerUsingHTTP(files, prefix,
this->CTest->GetCTestConfiguration("TriggerSite")))
@@ -1303,8 +1485,8 @@ int cmCTestSubmitHandler::ProcessHandler()
ofs << " Problems when triggering via HTTP" << std::endl;
return -1;
}
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " Submission successful"
- << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ " Submission successful" << std::endl, this->Quiet);
ofs << " Submission successful" << std::endl;
return 0;
}
@@ -1314,27 +1496,30 @@ int cmCTestSubmitHandler::ProcessHandler()
std::string url = dropMethod;
url += "://";
ofs << "Using drop method: " << dropMethod << std::endl;
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " Using HTTP submit method"
- << std::endl
- << " Drop site:" << url);
- if ( this->CTest->GetCTestConfiguration("DropSiteUser").size() > 0 )
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ " Using HTTP submit method" << std::endl << " Drop site:" << url,
+ this->Quiet);
+ if (!this->CTest->GetCTestConfiguration("DropSiteUser").empty())
{
url += this->CTest->GetCTestConfiguration("DropSiteUser");
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
- this->CTest->GetCTestConfiguration("DropSiteUser").c_str());
- if ( this->CTest->GetCTestConfiguration("DropSitePassword").size() > 0 )
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ this->CTest->GetCTestConfiguration("DropSiteUser").c_str(),
+ this->Quiet);
+ if (!this->CTest->GetCTestConfiguration("DropSitePassword").empty())
{
url += ":" + this->CTest->GetCTestConfiguration("DropSitePassword");
- cmCTestLog(this->CTest, HANDLER_OUTPUT, ":******");
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, ":******",
+ this->Quiet);
}
url += "@";
- cmCTestLog(this->CTest, HANDLER_OUTPUT, "@");
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "@", this->Quiet);
}
url += this->CTest->GetCTestConfiguration("DropSite") +
this->CTest->GetCTestConfiguration("DropLocation");
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
this->CTest->GetCTestConfiguration("DropSite")
- << this->CTest->GetCTestConfiguration("DropLocation") << std::endl);
+ << this->CTest->GetCTestConfiguration("DropLocation") << std::endl,
+ this->Quiet);
if ( !this->SubmitUsingHTTP(buildDirectory + "/Testing/" +
this->CTest->GetCurrentTag(), files, prefix, url) )
{
@@ -1345,11 +1530,10 @@ int cmCTestSubmitHandler::ProcessHandler()
}
if(!this->CDash)
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " Using HTTP trigger method"
- << std::endl
- << " Trigger site: "
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ " Using HTTP trigger method" << std::endl << " Trigger site: "
<< this->CTest->GetCTestConfiguration("TriggerSite")
- << std::endl);
+ << std::endl, this->Quiet);
if ( !this->
TriggerUsingHTTP(files, prefix,
this->CTest->GetCTestConfiguration("TriggerSite")))
@@ -1368,8 +1552,10 @@ int cmCTestSubmitHandler::ProcessHandler()
}
else
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " Submission successful" <<
- (this->HasWarnings ? ", with warnings." : "") << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ " Submission successful" <<
+ (this->HasWarnings ? ", with warnings." : "") << std::endl,
+ this->Quiet);
ofs << " Submission successful" <<
(this->HasWarnings ? ", with warnings." : "") << std::endl;
}
@@ -1380,8 +1566,8 @@ int cmCTestSubmitHandler::ProcessHandler()
{
#if defined(CTEST_USE_XMLRPC)
ofs << "Using drop method: XML-RPC" << std::endl;
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " Using XML-RPC submit method"
- << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ " Using XML-RPC submit method" << std::endl, this->Quiet);
std::string url = this->CTest->GetCTestConfiguration("DropSite");
prefix = this->CTest->GetCTestConfiguration("DropLocation");
if ( !this->SubmitUsingXMLRPC(buildDirectory + "/Testing/" +
@@ -1392,8 +1578,8 @@ int cmCTestSubmitHandler::ProcessHandler()
ofs << " Problems when submitting via XML-RPC" << std::endl;
return -1;
}
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " Submission successful"
- << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Submission successful"
+ << std::endl, this->Quiet);
ofs << " Submission successful" << std::endl;
return 0;
#else
@@ -1407,7 +1593,7 @@ int cmCTestSubmitHandler::ProcessHandler()
{
std::string url;
std::string oldWorkingDirectory;
- if ( this->CTest->GetCTestConfiguration("DropSiteUser").size() > 0 )
+ if (!this->CTest->GetCTestConfiguration("DropSiteUser").empty())
{
url += this->CTest->GetCTestConfiguration("DropSiteUser") + "@";
}
@@ -1417,22 +1603,22 @@ int cmCTestSubmitHandler::ProcessHandler()
// change to the build directory so that we can uses a relative path
// on windows since scp dosn't support "c:" a drive in the path
oldWorkingDirectory = cmSystemTools::GetCurrentWorkingDirectory();
- cmSystemTools::ChangeDirectory(buildDirectory.c_str());
+ cmSystemTools::ChangeDirectory(buildDirectory);
if ( !this->SubmitUsingSCP(
this->CTest->GetCTestConfiguration("ScpCommand"),
"Testing/"+this->CTest->GetCurrentTag(), files, prefix, url) )
{
- cmSystemTools::ChangeDirectory(oldWorkingDirectory.c_str());
+ cmSystemTools::ChangeDirectory(oldWorkingDirectory);
cmCTestLog(this->CTest, ERROR_MESSAGE,
" Problems when submitting via SCP"
<< std::endl);
ofs << " Problems when submitting via SCP" << std::endl;
return -1;
}
- cmSystemTools::ChangeDirectory(oldWorkingDirectory.c_str());
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " Submission successful"
- << std::endl);
+ cmSystemTools::ChangeDirectory(oldWorkingDirectory);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Submission successful"
+ << std::endl, this->Quiet);
ofs << " Submission successful" << std::endl;
return 0;
}
@@ -1446,9 +1632,9 @@ int cmCTestSubmitHandler::ProcessHandler()
// on windows since scp dosn't support "c:" a drive in the path
std::string
oldWorkingDirectory = cmSystemTools::GetCurrentWorkingDirectory();
- cmSystemTools::ChangeDirectory(buildDirectory.c_str());
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Change directory: "
- << buildDirectory.c_str() << std::endl);
+ cmSystemTools::ChangeDirectory(buildDirectory);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " Change directory: " << buildDirectory << std::endl, this->Quiet);
if ( !this->SubmitUsingCP(
"Testing/"+this->CTest->GetCurrentTag(),
@@ -1456,16 +1642,16 @@ int cmCTestSubmitHandler::ProcessHandler()
prefix,
location) )
{
- cmSystemTools::ChangeDirectory(oldWorkingDirectory.c_str());
+ cmSystemTools::ChangeDirectory(oldWorkingDirectory);
cmCTestLog(this->CTest, ERROR_MESSAGE,
" Problems when submitting via CP"
<< std::endl);
ofs << " Problems when submitting via cp" << std::endl;
return -1;
}
- cmSystemTools::ChangeDirectory(oldWorkingDirectory.c_str());
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " Submission successful"
- << std::endl);
+ cmSystemTools::ChangeDirectory(oldWorkingDirectory);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Submission successful"
+ << std::endl, this->Quiet);
ofs << " Submission successful" << std::endl;
return 0;
}
@@ -1478,8 +1664,10 @@ int cmCTestSubmitHandler::ProcessHandler()
//----------------------------------------------------------------------------
std::string cmCTestSubmitHandler::GetSubmitResultsPrefix()
{
+ std::string buildname = cmCTest::SafeBuildIdField(
+ this->CTest->GetCTestConfiguration("BuildName"));
std::string name = this->CTest->GetCTestConfiguration("Site") +
- "___" + this->CTest->GetCTestConfiguration("BuildName") +
+ "___" + buildname +
"___" + this->CTest->GetCurrentTag() + "-" +
this->CTest->GetTestModelString() + "___XML___";
return name;
@@ -1500,9 +1688,5 @@ void cmCTestSubmitHandler::SelectParts(std::set<cmCTest::Part> const& parts)
//----------------------------------------------------------------------------
void cmCTestSubmitHandler::SelectFiles(cmCTest::SetOfStrings const& files)
{
- cmCTest::SetOfStrings::const_iterator it;
- for (it = files.begin(); it != files.end(); ++it)
- {
- this->Files.insert(*it);
- }
+ this->Files.insert(files.begin(), files.end());
}
diff --git a/Source/CTest/cmCTestSubmitHandler.h b/Source/CTest/cmCTestSubmitHandler.h
index 14eac80b5..f9cd8946e 100644
--- a/Source/CTest/cmCTestSubmitHandler.h
+++ b/Source/CTest/cmCTestSubmitHandler.h
@@ -41,39 +41,44 @@ public:
/** Specify a set of files to submit. */
void SelectFiles(cmCTest::SetOfStrings const& files);
+ // handle the cdash file upload protocol
+ int HandleCDashUploadFile(std::string const& file, std::string const& type);
+
+ void ConstructCDashURL(std::string& dropMethod, std::string& url);
+
private:
void SetLogFile(std::ostream* ost) { this->LogFile = ost; }
/**
* Submit file using various ways
*/
- bool SubmitUsingFTP(const cmStdString& localprefix,
- const std::set<cmStdString>& files,
- const cmStdString& remoteprefix,
- const cmStdString& url);
- bool SubmitUsingHTTP(const cmStdString& localprefix,
- const std::set<cmStdString>& files,
- const cmStdString& remoteprefix,
- const cmStdString& url);
- bool SubmitUsingSCP(const cmStdString& scp_command,
- const cmStdString& localprefix,
- const std::set<cmStdString>& files,
- const cmStdString& remoteprefix,
- const cmStdString& url);
-
- bool SubmitUsingCP( const cmStdString& localprefix,
- const std::set<cmStdString>& files,
- const cmStdString& remoteprefix,
- const cmStdString& url);
-
- bool TriggerUsingHTTP(const std::set<cmStdString>& files,
- const cmStdString& remoteprefix,
- const cmStdString& url);
-
- bool SubmitUsingXMLRPC(const cmStdString& localprefix,
- const std::set<cmStdString>& files,
- const cmStdString& remoteprefix,
- const cmStdString& url);
+ bool SubmitUsingFTP(const std::string& localprefix,
+ const std::set<std::string>& files,
+ const std::string& remoteprefix,
+ const std::string& url);
+ bool SubmitUsingHTTP(const std::string& localprefix,
+ const std::set<std::string>& files,
+ const std::string& remoteprefix,
+ const std::string& url);
+ bool SubmitUsingSCP(const std::string& scp_command,
+ const std::string& localprefix,
+ const std::set<std::string>& files,
+ const std::string& remoteprefix,
+ const std::string& url);
+
+ bool SubmitUsingCP( const std::string& localprefix,
+ const std::set<std::string>& files,
+ const std::string& remoteprefix,
+ const std::string& url);
+
+ bool TriggerUsingHTTP(const std::set<std::string>& files,
+ const std::string& remoteprefix,
+ const std::string& url);
+
+ bool SubmitUsingXMLRPC(const std::string& localprefix,
+ const std::set<std::string>& files,
+ const std::string& remoteprefix,
+ const std::string& url);
typedef std::vector<char> cmCTestSubmitHandlerVectorOfChar;
@@ -82,10 +87,10 @@ private:
std::string GetSubmitResultsPrefix();
class ResponseParser;
- cmStdString HTTPProxy;
+ std::string HTTPProxy;
int HTTPProxyType;
- cmStdString HTTPProxyAuth;
- cmStdString FTPProxy;
+ std::string HTTPProxyAuth;
+ std::string FTPProxy;
int FTPProxyType;
std::ostream* LogFile;
bool SubmitPart[cmCTest::PartCount];
diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx
index 231f035fb..b7d8318f4 100644
--- a/Source/CTest/cmCTestTestCommand.cxx
+++ b/Source/CTest/cmCTestTestCommand.cxx
@@ -26,6 +26,7 @@ cmCTestTestCommand::cmCTestTestCommand()
this->Arguments[ctt_PARALLEL_LEVEL] = "PARALLEL_LEVEL";
this->Arguments[ctt_SCHEDULE_RANDOM] = "SCHEDULE_RANDOM";
this->Arguments[ctt_STOP_TIME] = "STOP_TIME";
+ this->Arguments[ctt_TEST_LOAD] = "TEST_LOAD";
this->Arguments[ctt_LAST] = 0;
this->Last = ctt_LAST;
}
@@ -53,7 +54,7 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
if ( this->Values[ctt_START] || this->Values[ctt_END] ||
this->Values[ctt_STRIDE] )
{
- cmOStringStream testsToRunString;
+ std::ostringstream testsToRunString;
if ( this->Values[ctt_START] )
{
testsToRunString << this->Values[ctt_START];
@@ -103,6 +104,39 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
{
this->CTest->SetStopTime(this->Values[ctt_STOP_TIME]);
}
+
+ // Test load is determined by: TEST_LOAD argument,
+ // or CTEST_TEST_LOAD script variable, or ctest --test-load
+ // command line argument... in that order.
+ unsigned long testLoad;
+ const char* ctestTestLoad
+ = this->Makefile->GetDefinition("CTEST_TEST_LOAD");
+ if(this->Values[ctt_TEST_LOAD] && *this->Values[ctt_TEST_LOAD])
+ {
+ if (!cmSystemTools::StringToULong(this->Values[ctt_TEST_LOAD], &testLoad))
+ {
+ testLoad = 0;
+ cmCTestLog(this->CTest, WARNING, "Invalid value for 'TEST_LOAD' : "
+ << this->Values[ctt_TEST_LOAD] << std::endl);
+ }
+ }
+ else if(ctestTestLoad && *ctestTestLoad)
+ {
+ if (!cmSystemTools::StringToULong(ctestTestLoad, &testLoad))
+ {
+ testLoad = 0;
+ cmCTestLog(this->CTest, WARNING,
+ "Invalid value for 'CTEST_TEST_LOAD' : " <<
+ ctestTestLoad << std::endl);
+ }
+ }
+ else
+ {
+ testLoad = this->CTest->GetTestLoad();
+ }
+ handler->SetTestLoad(testLoad);
+
+ handler->SetQuiet(this->Quiet);
return handler;
}
diff --git a/Source/CTest/cmCTestTestCommand.h b/Source/CTest/cmCTestTestCommand.h
index 130cb6973..0dfca974d 100644
--- a/Source/CTest/cmCTestTestCommand.h
+++ b/Source/CTest/cmCTestTestCommand.h
@@ -39,46 +39,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "ctest_test";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Run tests in the project build tree.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " ctest_test([BUILD build_dir] [APPEND]\n"
- " [START start number] [END end number]\n"
- " [STRIDE stride number] [EXCLUDE exclude regex ]\n"
- " [INCLUDE include regex] [RETURN_VALUE res] \n"
- " [EXCLUDE_LABEL exclude regex] \n"
- " [INCLUDE_LABEL label regex] \n"
- " [PARALLEL_LEVEL level] \n"
- " [SCHEDULE_RANDOM on] \n"
- " [STOP_TIME time of day]) \n"
- "Tests the given build directory and stores results in Test.xml. The "
- "second argument is a variable that will hold value. Optionally, "
- "you can specify the starting test number START, the ending test number "
- "END, the number of tests to skip between each test STRIDE, a regular "
- "expression for tests to run INCLUDE, or a regular expression for tests "
- "to not run EXCLUDE. EXCLUDE_LABEL and INCLUDE_LABEL are regular "
- "expression for test to be included or excluded by the test "
- "property LABEL. PARALLEL_LEVEL should be set to a positive number "
- "representing the number of tests to be run in parallel. "
- "SCHEDULE_RANDOM will launch tests in a random order, and is "
- "typically used to detect implicit test dependencies. STOP_TIME is the "
- "time of day at which the tests should all stop running."
- "\n"
- CTEST_COMMAND_APPEND_OPTION_DOCS;
- }
+ virtual std::string GetName() const { return "ctest_test";}
cmTypeMacro(cmCTestTestCommand, cmCTestHandlerCommand);
@@ -99,6 +60,7 @@ protected:
ctt_PARALLEL_LEVEL,
ctt_SCHEDULE_RANDOM,
ctt_STOP_TIME,
+ ctt_TEST_LOAD,
ctt_LAST
};
};
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index 497774d1b..b6a4819a0 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -20,12 +20,13 @@
#include <cmsys/Process.h>
#include <cmsys/RegularExpression.hxx>
#include <cmsys/Base64.h>
+#include <cmsys/Directory.hxx>
+#include <cmsys/FStream.hxx>
#include "cmMakefile.h"
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
#include "cmCommand.h"
#include "cmSystemTools.h"
-#include "cmXMLSafe.h"
+#include "cmXMLWriter.h"
#include "cm_utf8.h"
#include <stdlib.h>
@@ -58,11 +59,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "subdirs";}
-
- // Unused methods
- virtual const char* GetTerseDocumentation() const { return ""; }
- virtual const char* GetFullDocumentation() const { return ""; }
+ virtual std::string GetName() const { return "subdirs";}
cmTypeMacro(cmCTestSubdirCommand, cmCommand);
@@ -95,12 +92,12 @@ bool cmCTestSubdirCommand
fname += *it;
}
- if ( !cmSystemTools::FileIsDirectory(fname.c_str()) )
+ if ( !cmSystemTools::FileIsDirectory(fname) )
{
// No subdirectory? So what...
continue;
}
- cmSystemTools::ChangeDirectory(fname.c_str());
+ cmSystemTools::ChangeDirectory(fname);
const char* testFilename;
if( cmSystemTools::FileExists("CTestTestfile.cmake") )
{
@@ -119,19 +116,17 @@ bool cmCTestSubdirCommand
}
fname += "/";
fname += testFilename;
- bool readit =
- this->Makefile->ReadListFile(this->Makefile->GetCurrentListFile(),
- fname.c_str());
- cmSystemTools::ChangeDirectory(cwd.c_str());
+ bool readit = this->Makefile->ReadDependentFile(fname.c_str());
+ cmSystemTools::ChangeDirectory(cwd);
if(!readit)
{
std::string m = "Could not find include file: ";
m += fname;
- this->SetError(m.c_str());
+ this->SetError(m);
return false;
}
}
- cmSystemTools::ChangeDirectory(cwd.c_str());
+ cmSystemTools::ChangeDirectory(cwd);
return true;
}
@@ -159,11 +154,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "add_subdirectory";}
-
- // Unused methods
- virtual const char* GetTerseDocumentation() const { return ""; }
- virtual const char* GetFullDocumentation() const { return ""; }
+ virtual std::string GetName() const { return "add_subdirectory";}
cmTypeMacro(cmCTestAddSubdirectoryCommand, cmCommand);
@@ -181,17 +172,17 @@ bool cmCTestAddSubdirectoryCommand
}
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
- cmSystemTools::ChangeDirectory(cwd.c_str());
+ cmSystemTools::ChangeDirectory(cwd);
std::string fname = cwd;
fname += "/";
- fname += args[1];
+ fname += args[0];
if ( !cmSystemTools::FileExists(fname.c_str()) )
{
// No subdirectory? So what...
return true;
}
- cmSystemTools::ChangeDirectory(fname.c_str());
+ cmSystemTools::ChangeDirectory(fname);
const char* testFilename;
if( cmSystemTools::FileExists("CTestTestfile.cmake") )
{
@@ -206,20 +197,18 @@ bool cmCTestAddSubdirectoryCommand
else
{
// No CTestTestfile? Who cares...
- cmSystemTools::ChangeDirectory(cwd.c_str());
+ cmSystemTools::ChangeDirectory(cwd);
return true;
}
fname += "/";
fname += testFilename;
- bool readit =
- this->Makefile->ReadListFile(this->Makefile->GetCurrentListFile(),
- fname.c_str());
- cmSystemTools::ChangeDirectory(cwd.c_str());
+ bool readit = this->Makefile->ReadDependentFile(fname.c_str());
+ cmSystemTools::ChangeDirectory(cwd);
if(!readit)
{
std::string m = "Could not find include file: ";
m += fname;
- this->SetError(m.c_str());
+ this->SetError(m);
return false;
}
return true;
@@ -249,11 +238,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "ADD_TEST";}
-
- // Unused methods
- virtual const char* GetTerseDocumentation() const { return ""; }
- virtual const char* GetFullDocumentation() const { return ""; }
+ virtual std::string GetName() const { return "add_test";}
cmTypeMacro(cmCTestAddTestCommand, cmCommand);
@@ -297,11 +282,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "SET_TESTS_PROPERTIES";}
-
- // Unused methods
- virtual const char* GetTerseDocumentation() const { return ""; }
- virtual const char* GetFullDocumentation() const { return ""; }
+ virtual std::string GetName() const { return "set_tests_properties";}
cmTypeMacro(cmCTestSetTestsPropertiesCommand, cmCommand);
@@ -523,7 +504,7 @@ int cmCTestTestHandler::ProcessHandler()
if ( val )
{
this->UseExcludeLabelRegExpFlag = true;
- this->ExcludeLabelRegularExpression = val;
+ this->ExcludeLabelRegExp = val;
}
val = this->GetOption("IncludeRegularExpression");
if ( val )
@@ -537,13 +518,14 @@ int cmCTestTestHandler::ProcessHandler()
this->UseExcludeRegExp();
this->SetExcludeRegExp(val);
}
+ this->SetRerunFailed(cmSystemTools::IsOn(this->GetOption("RerunFailed")));
this->TestResults.clear();
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
(this->MemCheck ? "Memory check" : "Test")
<< " project " << cmSystemTools::GetCurrentWorkingDirectory()
- << std::endl);
+ << std::endl, this->Quiet);
if ( ! this->PreProcessHandler() )
{
return -1;
@@ -553,8 +535,8 @@ int cmCTestTestHandler::ProcessHandler()
this->StartLogFile((this->MemCheck ? "DynamicAnalysis" : "Test"), mLogFile);
this->LogFile = &mLogFile;
- std::vector<cmStdString> passed;
- std::vector<cmStdString> failed;
+ std::vector<std::string> passed;
+ std::vector<std::string> failed;
int total;
//start the real time clock
@@ -577,27 +559,27 @@ int cmCTestTestHandler::ProcessHandler()
}
else
{
- if (this->HandlerVerbose && passed.size() &&
+ if (this->HandlerVerbose && !passed.empty() &&
(this->UseIncludeRegExpFlag || this->UseExcludeRegExpFlag))
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl
- << "The following tests passed:" << std::endl);
- for(std::vector<cmStdString>::iterator j = passed.begin();
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl
+ << "The following tests passed:" << std::endl, this->Quiet);
+ for(std::vector<std::string>::iterator j = passed.begin();
j != passed.end(); ++j)
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "\t" << *j
- << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "\t" << *j
+ << std::endl, this->Quiet);
}
}
float percent = float(passed.size()) * 100.0f / float(total);
- if ( failed.size() > 0 && percent > 99)
+ if (!failed.empty() && percent > 99)
{
percent = 99;
}
cmCTestLog(this->CTest, HANDLER_OUTPUT, std::endl
- << static_cast<int>(percent + .5) << "% tests passed, "
+ << static_cast<int>(percent + .5f) << "% tests passed, "
<< failed.size() << " tests failed out of "
<< total << std::endl);
if(this->CTest->GetLabelSummary())
@@ -606,10 +588,10 @@ int cmCTestTestHandler::ProcessHandler()
}
char realBuf[1024];
sprintf(realBuf, "%6.2f sec", (double)(clock_finish - clock_start));
- cmCTestLog(this->CTest, HANDLER_OUTPUT, "\nTotal Test time (real) = "
- << realBuf << "\n" );
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ "\nTotal Test time (real) = " << realBuf << "\n", this->Quiet );
- if (failed.size())
+ if (!failed.empty())
{
cmGeneratedFileStream ofs;
cmCTestLog(this->CTest, HANDLER_OUTPUT, std::endl
@@ -629,7 +611,7 @@ int cmCTestTestHandler::ProcessHandler()
ofs << ftit->TestCount << ":" << ftit->Name << std::endl;
cmCTestLog(this->CTest, HANDLER_OUTPUT, "\t" << std::setw(3)
<< ftit->TestCount << " - "
- << ftit->Name.c_str() << " ("
+ << ftit->Name << " ("
<< this->GetTestStatus(ftit->Status) << ")"
<< std::endl);
}
@@ -650,7 +632,8 @@ int cmCTestTestHandler::ProcessHandler()
this->LogFile = 0;
return 1;
}
- this->GenerateDartOutput(xmlfile);
+ cmXMLWriter xml(xmlfile);
+ this->GenerateDartOutput(xml);
}
if ( ! this->PostProcessHandler() )
@@ -672,16 +655,15 @@ int cmCTestTestHandler::ProcessHandler()
void cmCTestTestHandler::PrintLabelSummary()
{
cmCTestTestHandler::ListOfTests::iterator it = this->TestList.begin();
- cmCTestTestHandler::TestResultsVector::iterator ri =
- this->TestResults.begin();
- std::map<cmStdString, double> labelTimes;
- std::set<cmStdString> labels;
+ std::map<std::string, double> labelTimes;
+ std::map<std::string, int> labelCounts;
+ std::set<std::string> labels;
// initialize maps
std::string::size_type maxlen = 0;
for(; it != this->TestList.end(); ++it)
{
cmCTestTestProperties& p = *it;
- if(p.Labels.size() != 0)
+ if(!p.Labels.empty())
{
for(std::vector<std::string>::iterator l = p.Labels.begin();
l != p.Labels.end(); ++l)
@@ -692,51 +674,66 @@ void cmCTestTestHandler::PrintLabelSummary()
}
labels.insert(*l);
labelTimes[*l] = 0;
+ labelCounts[*l] = 0;
}
}
}
- ri = this->TestResults.begin();
+ cmCTestTestHandler::TestResultsVector::iterator ri =
+ this->TestResults.begin();
// fill maps
for(; ri != this->TestResults.end(); ++ri)
{
cmCTestTestResult &result = *ri;
cmCTestTestProperties& p = *result.Properties;
- if(p.Labels.size() != 0)
+ if(!p.Labels.empty())
{
for(std::vector<std::string>::iterator l = p.Labels.begin();
l != p.Labels.end(); ++l)
{
labelTimes[*l] += result.ExecutionTime;
+ ++labelCounts[*l];
}
}
}
// now print times
- if(labels.size())
+ if(!labels.empty())
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT, "\nLabel Time Summary:");
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "\nLabel Time Summary:",
+ this->Quiet);
}
- for(std::set<cmStdString>::const_iterator i = labels.begin();
+ for(std::set<std::string>::const_iterator i = labels.begin();
i != labels.end(); ++i)
{
std::string label = *i;
label.resize(maxlen +3, ' ');
+
char buf[1024];
sprintf(buf, "%6.2f sec", labelTimes[*i]);
- cmCTestLog(this->CTest, HANDLER_OUTPUT, "\n"
- << label << " = " << buf );
+
+ std::ostringstream labelCountStr;
+ labelCountStr << "(" << labelCounts[*i] << " test";
+ if (labelCounts[*i] > 1)
+ {
+ labelCountStr << "s";
+ }
+ labelCountStr << ")";
+
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "\n"
+ << label << " = " << buf << " " << labelCountStr.str(),
+ this->Quiet );
if ( this->LogFile )
{
*this->LogFile << "\n" << *i << " = "
<< buf << "\n";
}
}
- if(labels.size())
+ if(!labels.empty())
{
if(this->LogFile)
{
*this->LogFile << "\n";
}
- cmCTestLog(this->CTest, HANDLER_OUTPUT, "\n");
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "\n", this->Quiet);
}
}
@@ -751,7 +748,7 @@ void cmCTestTestHandler::CheckLabelFilterInclude(cmCTestTestProperties& it)
}
// if there are no labels and we are filtering by labels
// then exclude the test as it does not have the label
- if(it.Labels.size() == 0 )
+ if(it.Labels.empty())
{
it.IsInBasedOnREOptions = false;
return;
@@ -785,7 +782,7 @@ void cmCTestTestHandler::CheckLabelFilterExclude(cmCTestTestProperties& it)
}
// if there are no labels and we are excluding by labels
// then do nothing as a no label can not be a match
- if(it.Labels.size() == 0 )
+ if(it.Labels.empty())
{
return;
}
@@ -819,6 +816,13 @@ void cmCTestTestHandler::ComputeTestList()
{
this->TestList.clear(); // clear list of test
this->GetListOfTests();
+
+ if (this->RerunFailed)
+ {
+ this->ComputeTestListForRerunFailed();
+ return;
+ }
+
cmCTestTestHandler::ListOfTests::size_type tmsize = this->TestList.size();
// how many tests are in based on RegExp?
int inREcnt = 0;
@@ -856,7 +860,7 @@ void cmCTestTestHandler::ComputeTestList()
if (this->UseUnion)
{
// if it is not in the list and not in the regexp then skip
- if ((this->TestsToRun.size() &&
+ if ((!this->TestsToRun.empty() &&
std::find(this->TestsToRun.begin(), this->TestsToRun.end(), cnt)
== this->TestsToRun.end()) && !it->IsInBasedOnREOptions)
{
@@ -866,7 +870,7 @@ void cmCTestTestHandler::ComputeTestList()
else
{
// is this test in the list of tests to run? If not then skip it
- if ((this->TestsToRun.size() &&
+ if ((!this->TestsToRun.empty() &&
std::find(this->TestsToRun.begin(),
this->TestsToRun.end(), inREcnt)
== this->TestsToRun.end()) || !it->IsInBasedOnREOptions)
@@ -881,9 +885,47 @@ void cmCTestTestHandler::ComputeTestList()
this->TotalNumberOfTests = this->TestList.size();
// Set the TestList to the final list of all test
this->TestList = finalList;
+
+ this->UpdateMaxTestNameWidth();
+}
+
+void cmCTestTestHandler::ComputeTestListForRerunFailed()
+{
+ this->ExpandTestsToRunInformationForRerunFailed();
+
+ cmCTestTestHandler::ListOfTests::iterator it;
+ ListOfTests finalList;
+ int cnt = 0;
+ for ( it = this->TestList.begin(); it != this->TestList.end(); it ++ )
+ {
+ cnt ++;
+
+ // if this test is not in our list of tests to run, then skip it.
+ if ((!this->TestsToRun.empty() &&
+ std::find(this->TestsToRun.begin(), this->TestsToRun.end(), cnt)
+ == this->TestsToRun.end()))
+ {
+ continue;
+ }
+
+ it->Index = cnt;
+ finalList.push_back(*it);
+ }
+
+ // Save the total number of tests before exclusions
+ this->TotalNumberOfTests = this->TestList.size();
+
+ // Set the TestList to the list of failed tests to rerun
+ this->TestList = finalList;
+
+ this->UpdateMaxTestNameWidth();
+}
+
+void cmCTestTestHandler::UpdateMaxTestNameWidth()
+{
std::string::size_type max = this->CTest->GetMaxTestNameWidth();
- for (it = this->TestList.begin();
- it != this->TestList.end(); it ++ )
+ for ( cmCTestTestHandler::ListOfTests::iterator it = this->TestList.begin();
+ it != this->TestList.end(); it ++ )
{
cmCTestTestProperties& p = *it;
if(max < p.Name.size())
@@ -900,7 +942,7 @@ void cmCTestTestHandler::ComputeTestList()
bool cmCTestTestHandler::GetValue(const char* tag,
int& value,
- std::ifstream& fin)
+ std::istream& fin)
{
std::string line;
bool ret = true;
@@ -922,7 +964,7 @@ bool cmCTestTestHandler::GetValue(const char* tag,
bool cmCTestTestHandler::GetValue(const char* tag,
double& value,
- std::ifstream& fin)
+ std::istream& fin)
{
std::string line;
cmSystemTools::GetLineFromStream(fin, line);
@@ -944,7 +986,7 @@ bool cmCTestTestHandler::GetValue(const char* tag,
bool cmCTestTestHandler::GetValue(const char* tag,
bool& value,
- std::ifstream& fin)
+ std::istream& fin)
{
std::string line;
cmSystemTools::GetLineFromStream(fin, line);
@@ -976,7 +1018,7 @@ bool cmCTestTestHandler::GetValue(const char* tag,
bool cmCTestTestHandler::GetValue(const char* tag,
size_t& value,
- std::ifstream& fin)
+ std::istream& fin)
{
std::string line;
cmSystemTools::GetLineFromStream(fin, line);
@@ -990,7 +1032,7 @@ bool cmCTestTestHandler::GetValue(const char* tag,
{
cmCTestLog(this->CTest, ERROR_MESSAGE,
"parse error: missing tag: "
- << tag << " found [" << line.c_str() << "]" << std::endl);
+ << tag << " found [" << line << "]" << std::endl);
ret = false;
}
return ret;
@@ -998,7 +1040,7 @@ bool cmCTestTestHandler::GetValue(const char* tag,
bool cmCTestTestHandler::GetValue(const char* tag,
std::string& value,
- std::ifstream& fin)
+ std::istream& fin)
{
std::string line;
cmSystemTools::GetLineFromStream(fin, line);
@@ -1018,8 +1060,8 @@ bool cmCTestTestHandler::GetValue(const char* tag,
}
//---------------------------------------------------------------------
-void cmCTestTestHandler::ProcessDirectory(std::vector<cmStdString> &passed,
- std::vector<cmStdString> &failed)
+void cmCTestTestHandler::ProcessDirectory(std::vector<std::string> &passed,
+ std::vector<std::string> &failed)
{
this->ComputeTestList();
this->StartTest = this->CTest->CurrentTime();
@@ -1031,6 +1073,15 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<cmStdString> &passed,
parallel->SetCTest(this->CTest);
parallel->SetParallelLevel(this->CTest->GetParallelLevel());
parallel->SetTestHandler(this);
+ parallel->SetQuiet(this->Quiet);
+ if(this->TestLoad > 0)
+ {
+ parallel->SetTestLoad(this->TestLoad);
+ }
+ else
+ {
+ parallel->SetTestLoad(this->CTest->GetTestLoad());
+ }
*this->LogFile << "Start testing: "
<< this->CTest->CurrentTime() << std::endl
@@ -1062,7 +1113,7 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<cmStdString> &passed,
p.Timeout = this->CTest->GetGlobalTimeout();
}
- if(p.Depends.size())
+ if(!p.Depends.empty())
{
for(std::vector<std::string>::iterator i = p.Depends.begin();
i != p.Depends.end(); ++i)
@@ -1112,55 +1163,54 @@ void cmCTestTestHandler::GenerateTestCommand(std::vector<std::string>&, int)
}
//----------------------------------------------------------------------
-void cmCTestTestHandler::GenerateDartOutput(std::ostream& os)
+void cmCTestTestHandler::GenerateDartOutput(cmXMLWriter& xml)
{
if ( !this->CTest->GetProduceXML() )
{
return;
}
- this->CTest->StartXML(os, this->AppendXML);
- os << "<Testing>\n"
- << "\t<StartDateTime>" << this->StartTest << "</StartDateTime>\n"
- << "\t<StartTestTime>" << this->StartTestTime << "</StartTestTime>\n"
- << "\t<TestList>\n";
+ this->CTest->StartXML(xml, this->AppendXML);
+ xml.StartElement("Testing");
+ xml.Element("StartDateTime", this->StartTest);
+ xml.Element("StartTestTime", this->StartTestTime);
+ xml.StartElement("TestList");
cmCTestTestHandler::TestResultsVector::size_type cc;
for ( cc = 0; cc < this->TestResults.size(); cc ++ )
{
cmCTestTestResult *result = &this->TestResults[cc];
std::string testPath = result->Path + "/" + result->Name;
- os << "\t\t<Test>" << cmXMLSafe(
- this->CTest->GetShortPathToFile(testPath.c_str()))
- << "</Test>" << std::endl;
+ xml.Element("Test", this->CTest->GetShortPathToFile(testPath.c_str()));
}
- os << "\t</TestList>\n";
+ xml.EndElement(); // TestList
for ( cc = 0; cc < this->TestResults.size(); cc ++ )
{
cmCTestTestResult *result = &this->TestResults[cc];
- this->WriteTestResultHeader(os, result);
- os << "\t\t<Results>" << std::endl;
+ this->WriteTestResultHeader(xml, result);
+ xml.StartElement("Results");
if ( result->Status != cmCTestTestHandler::NOT_RUN )
{
if ( result->Status != cmCTestTestHandler::COMPLETED ||
result->ReturnValue )
{
- os << "\t\t\t<NamedMeasurement type=\"text/string\" "
- "name=\"Exit Code\"><Value>"
- << cmXMLSafe(this->GetTestStatus(result->Status))
- << "</Value>"
- "</NamedMeasurement>\n"
- << "\t\t\t<NamedMeasurement type=\"text/string\" "
- "name=\"Exit Value\"><Value>"
- << result->ReturnValue
- << "</Value></NamedMeasurement>"
- << std::endl;
+ xml.StartElement("NamedMeasurement");
+ xml.Attribute("type", "text/string");
+ xml.Attribute("name", "Exit Code");
+ xml.Element("Value", this->GetTestStatus(result->Status));
+ xml.EndElement(); // NamedMeasurement
+ xml.StartElement("NamedMeasurement");
+ xml.Attribute("type", "text/string");
+ xml.Attribute("name", "Exit Value");
+ xml.Element("Value", result->ReturnValue);
+ xml.EndElement(); // NamedMeasurement
}
- os << result->RegressionImages;
- os << "\t\t\t<NamedMeasurement type=\"numeric/double\" "
- << "name=\"Execution Time\"><Value>"
- << result->ExecutionTime
- << "</Value></NamedMeasurement>\n";
- if(result->Reason.size())
+ this->GenerateRegressionImages(xml, result->DartString);
+ xml.StartElement("NamedMeasurement");
+ xml.Attribute("type", "numeric/double");
+ xml.Attribute("name", "Execution Time");
+ xml.Element("Value", result->ExecutionTime);
+ xml.EndElement(); // NamedMeasurement
+ if(!result->Reason.empty())
{
const char* reasonType = "Pass Reason";
if(result->Status != cmCTestTestHandler::COMPLETED &&
@@ -1168,109 +1218,103 @@ void cmCTestTestHandler::GenerateDartOutput(std::ostream& os)
{
reasonType = "Fail Reason";
}
- os << "\t\t\t<NamedMeasurement type=\"text/string\" "
- << "name=\"" << reasonType << "\"><Value>"
- << cmXMLSafe(result->Reason)
- << "</Value></NamedMeasurement>\n";
+ xml.StartElement("NamedMeasurement");
+ xml.Attribute("type", "text/string");
+ xml.Attribute("name", reasonType);
+ xml.Element("Value", result->Reason);
+ xml.EndElement(); // NamedMeasurement
}
- os
- << "\t\t\t<NamedMeasurement type=\"text/string\" "
- << "name=\"Completion Status\"><Value>"
- << cmXMLSafe(result->CompletionStatus)
- << "</Value></NamedMeasurement>\n";
- }
- os
- << "\t\t\t<NamedMeasurement type=\"text/string\" "
- << "name=\"Command Line\"><Value>"
- << cmXMLSafe(result->FullCommandLine)
- << "</Value></NamedMeasurement>\n";
- std::map<cmStdString,cmStdString>::iterator measureIt;
+ xml.StartElement("NamedMeasurement");
+ xml.Attribute("type", "text/string");
+ xml.Attribute("name", "Completion Status");
+ xml.Element("Value", result->CompletionStatus);
+ xml.EndElement(); // NamedMeasurement
+ }
+ xml.StartElement("NamedMeasurement");
+ xml.Attribute("type", "text/string");
+ xml.Attribute("name", "Command Line");
+ xml.Element("Value", result->FullCommandLine);
+ xml.EndElement(); // NamedMeasurement
+ std::map<std::string,std::string>::iterator measureIt;
for ( measureIt = result->Properties->Measurements.begin();
measureIt != result->Properties->Measurements.end();
++ measureIt )
{
- os
- << "\t\t\t<NamedMeasurement type=\"text/string\" "
- << "name=\"" << measureIt->first.c_str() << "\"><Value>"
- << cmXMLSafe(measureIt->second)
- << "</Value></NamedMeasurement>\n";
- }
- os
- << "\t\t\t<Measurement>\n"
- << "\t\t\t\t<Value"
- << (result->CompressOutput ?
- " encoding=\"base64\" compression=\"gzip\">"
- : ">");
- os << cmXMLSafe(result->Output);
- os
- << "</Value>\n"
- << "\t\t\t</Measurement>\n"
- << "\t\t</Results>\n";
-
- this->AttachFiles(os, result);
- this->WriteTestResultFooter(os, result);
- }
-
- os << "\t<EndDateTime>" << this->EndTest << "</EndDateTime>\n"
- << "\t<EndTestTime>" << this->EndTestTime << "</EndTestTime>\n"
- << "<ElapsedMinutes>"
- << static_cast<int>(this->ElapsedTestingTime/6)/10.0
- << "</ElapsedMinutes>"
- << "</Testing>" << std::endl;
- this->CTest->EndXML(os);
+ xml.StartElement("NamedMeasurement");
+ xml.Attribute("type", "text/string");
+ xml.Attribute("name", measureIt->first);
+ xml.Element("Value", measureIt->second);
+ xml.EndElement(); // NamedMeasurement
+ }
+ xml.StartElement("Measurement");
+ xml.StartElement("Value");
+ if (result->CompressOutput)
+ {
+ xml.Attribute("encoding", "base64");
+ xml.Attribute("compression", "gzip");
+ }
+ xml.Content(result->Output);
+ xml.EndElement(); // Value
+ xml.EndElement(); // Measurement
+ xml.EndElement(); // Results
+
+ this->AttachFiles(xml, result);
+ this->WriteTestResultFooter(xml, result);
+ }
+
+ xml.Element("EndDateTime", this->EndTest);
+ xml.Element("EndTestTime", this->EndTestTime);
+ xml.Element("ElapsedMinutes",
+ static_cast<int>(this->ElapsedTestingTime/6)/10.0);
+ xml.EndElement(); // Testing
+ this->CTest->EndXML(xml);
}
//----------------------------------------------------------------------------
-void cmCTestTestHandler::WriteTestResultHeader(std::ostream& os,
+void cmCTestTestHandler::WriteTestResultHeader(cmXMLWriter& xml,
cmCTestTestResult* result)
{
- os << "\t<Test Status=\"";
+ xml.StartElement("Test");
if ( result->Status == cmCTestTestHandler::COMPLETED )
{
- os << "passed";
+ xml.Attribute("Status", "passed");
}
else if ( result->Status == cmCTestTestHandler::NOT_RUN )
{
- os << "notrun";
+ xml.Attribute("Status", "notrun");
}
else
{
- os << "failed";
+ xml.Attribute("Status", "failed");
}
std::string testPath = result->Path + "/" + result->Name;
- os << "\">\n"
- << "\t\t<Name>" << cmXMLSafe(result->Name) << "</Name>\n"
- << "\t\t<Path>" << cmXMLSafe(
- this->CTest->GetShortPathToFile(result->Path.c_str())) << "</Path>\n"
- << "\t\t<FullName>" << cmXMLSafe(
- this->CTest->GetShortPathToFile(testPath.c_str())) << "</FullName>\n"
- << "\t\t<FullCommandLine>"
- << cmXMLSafe(result->FullCommandLine)
- << "</FullCommandLine>\n";
+ xml.Element("Name", result->Name);
+ xml.Element("Path", this->CTest->GetShortPathToFile(result->Path.c_str()));
+ xml.Element("FullName", this->CTest->GetShortPathToFile(testPath.c_str()));
+ xml.Element("FullCommandLine", result->FullCommandLine);
}
//----------------------------------------------------------------------------
-void cmCTestTestHandler::WriteTestResultFooter(std::ostream& os,
+void cmCTestTestHandler::WriteTestResultFooter(cmXMLWriter& xml,
cmCTestTestResult* result)
{
if(!result->Properties->Labels.empty())
{
- os << "\t\t<Labels>\n";
+ xml.StartElement("Labels");
std::vector<std::string> const& labels = result->Properties->Labels;
for(std::vector<std::string>::const_iterator li = labels.begin();
li != labels.end(); ++li)
{
- os << "\t\t\t<Label>" << cmXMLSafe(*li) << "</Label>\n";
+ xml.Element("Label", *li);
}
- os << "\t\t</Labels>\n";
+ xml.EndElement(); // Labels
}
- os
- << "\t</Test>" << std::endl;
+ xml.EndElement(); // Test
}
//----------------------------------------------------------------------
-void cmCTestTestHandler::AttachFiles(std::ostream& os,
+void cmCTestTestHandler::AttachFiles(cmXMLWriter& xml,
cmCTestTestResult* result)
{
if(result->Status != cmCTestTestHandler::COMPLETED
@@ -1285,26 +1329,29 @@ void cmCTestTestHandler::AttachFiles(std::ostream& os,
result->Properties->AttachedFiles.begin();
file != result->Properties->AttachedFiles.end(); ++file)
{
- std::string base64 = this->CTest->Base64GzipEncodeFile(*file);
+ const std::string &base64 = this->CTest->Base64GzipEncodeFile(*file);
std::string fname = cmSystemTools::GetFilenameName(*file);
- os << "\t\t<NamedMeasurement name=\"Attached File\" encoding=\"base64\" "
- "compression=\"tar/gzip\" filename=\"" << fname << "\" type=\"file\">"
- "\n\t\t\t<Value>\n\t\t\t"
- << base64
- << "\n\t\t\t</Value>\n\t\t</NamedMeasurement>\n";
+ xml.StartElement("NamedMeasurement");
+ xml.Attribute("name", "Attached File");
+ xml.Attribute("encoding", "base64");
+ xml.Attribute("compression", "tar/gzip");
+ xml.Attribute("filename", fname);
+ xml.Attribute("type", "file");
+ xml.Element("Value", base64);
+ xml.EndElement(); // NamedMeasurement
}
}
//----------------------------------------------------------------------
-int cmCTestTestHandler::ExecuteCommands(std::vector<cmStdString>& vec)
+int cmCTestTestHandler::ExecuteCommands(std::vector<std::string>& vec)
{
- std::vector<cmStdString>::iterator it;
+ std::vector<std::string>::iterator it;
for ( it = vec.begin(); it != vec.end(); ++it )
{
int retVal = 0;
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Run command: " << *it
- << std::endl);
- if ( !cmSystemTools::RunSingleCommand(it->c_str(), 0, &retVal, 0,
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Run command: " <<
+ *it << std::endl, this->Quiet);
+ if ( !cmSystemTools::RunSingleCommand(it->c_str(), 0, 0, &retVal, 0,
cmSystemTools::OUTPUT_MERGE
/*this->Verbose*/) || retVal != 0 )
{
@@ -1344,7 +1391,7 @@ void cmCTestTestHandler
{
std::string tempPath;
- if (filepath.size() &&
+ if (!filepath.empty() &&
filepath[filepath.size()-1] != '/')
{
filepath += "/";
@@ -1353,7 +1400,7 @@ void cmCTestTestHandler
attempted.push_back(tempPath);
attemptedConfigs.push_back("");
- if(ctest->GetConfigType().size())
+ if(!ctest->GetConfigType().empty())
{
tempPath = filepath;
tempPath += ctest->GetConfigType();
@@ -1431,7 +1478,7 @@ std::string cmCTestTestHandler
// even if a fullpath was specified also try it relative to the current
// directory
- if (filepath.size() && filepath[0] == '/')
+ if (!filepath.empty() && filepath[0] == '/')
{
std::string localfilepath = filepath.substr(1,filepath.size()-1);
cmCTestTestHandler::AddConfigurations(ctest, attempted,
@@ -1442,7 +1489,7 @@ std::string cmCTestTestHandler
// if extraPaths are provided and we were not passed a full path, try them,
// try any extra paths
- if (filepath.size() == 0)
+ if (filepath.empty())
{
for (unsigned int i = 0; i < extraPaths.size(); ++i)
{
@@ -1462,37 +1509,37 @@ std::string cmCTestTestHandler
// now look in the paths we specified above
for(unsigned int ai=0;
- ai < attempted.size() && fullPath.size() == 0; ++ai)
+ ai < attempted.size() && fullPath.empty(); ++ai)
{
// first check without exe extension
if(cmSystemTools::FileExists(attempted[ai].c_str())
- && !cmSystemTools::FileIsDirectory(attempted[ai].c_str()))
+ && !cmSystemTools::FileIsDirectory(attempted[ai]))
{
- fullPath = cmSystemTools::CollapseFullPath(attempted[ai].c_str());
+ fullPath = cmSystemTools::CollapseFullPath(attempted[ai]);
resultingConfig = attemptedConfigs[ai];
}
// then try with the exe extension
else
{
- failed.push_back(attempted[ai].c_str());
+ failed.push_back(attempted[ai]);
tempPath = attempted[ai];
tempPath += cmSystemTools::GetExecutableExtension();
if(cmSystemTools::FileExists(tempPath.c_str())
- && !cmSystemTools::FileIsDirectory(tempPath.c_str()))
+ && !cmSystemTools::FileIsDirectory(tempPath))
{
- fullPath = cmSystemTools::CollapseFullPath(tempPath.c_str());
+ fullPath = cmSystemTools::CollapseFullPath(tempPath);
resultingConfig = attemptedConfigs[ai];
}
else
{
- failed.push_back(tempPath.c_str());
+ failed.push_back(tempPath);
}
}
}
// if everything else failed, check the users path, but only if a full path
// wasn't specified
- if (fullPath.size() == 0 && filepath.size() == 0)
+ if (fullPath.empty() && filepath.empty())
{
std::string path = cmSystemTools::FindProgram(filename.c_str());
if (path != "")
@@ -1501,7 +1548,7 @@ std::string cmCTestTestHandler
return path;
}
}
- if(fullPath.size() == 0)
+ if(fullPath.empty())
{
cmCTestLog(ctest, HANDLER_OUTPUT,
"Could not find executable " << testCommand << "\n"
@@ -1509,8 +1556,7 @@ std::string cmCTestTestHandler
for(std::vector<std::string>::iterator i = failed.begin();
i != failed.end(); ++i)
{
- cmCTestLog(ctest, HANDLER_OUTPUT,
- i->c_str() << "\n");
+ cmCTestLog(ctest, HANDLER_OUTPUT, i->c_str() << "\n");
}
}
@@ -1526,7 +1572,7 @@ void cmCTestTestHandler::GetListOfTests()
this->IncludeLabelRegularExpression.
compile(this->IncludeLabelRegExp.c_str());
}
- if ( !this->IncludeLabelRegExp.empty() )
+ if ( !this->ExcludeLabelRegExp.empty() )
{
this->ExcludeLabelRegularExpression.
compile(this->ExcludeLabelRegExp.c_str());
@@ -1539,38 +1585,39 @@ void cmCTestTestHandler::GetListOfTests()
{
this->ExcludeTestsRegularExpression.compile(this->ExcludeRegExp.c_str());
}
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "Constructing a list of tests" << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Constructing a list of tests" << std::endl, this->Quiet);
cmake cm;
- cmGlobalGenerator gg;
- gg.SetCMakeInstance(&cm);
- cmsys::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator());
- cmMakefile *mf = lg->GetMakefile();
+ cm.SetHomeDirectory("");
+ cm.SetHomeOutputDirectory("");
+ cm.GetCurrentSnapshot().SetDefaultDefinitions();
+ cmGlobalGenerator gg(&cm);
+ cmsys::auto_ptr<cmMakefile> mf(new cmMakefile(&gg, cm.GetCurrentSnapshot()));
mf->AddDefinition("CTEST_CONFIGURATION_TYPE",
this->CTest->GetConfigType().c_str());
// Add handler for ADD_TEST
cmCTestAddTestCommand* newCom1 = new cmCTestAddTestCommand;
newCom1->TestHandler = this;
- cm.AddCommand(newCom1);
+ cm.GetState()->AddCommand(newCom1);
// Add handler for SUBDIRS
cmCTestSubdirCommand* newCom2 =
new cmCTestSubdirCommand;
newCom2->TestHandler = this;
- cm.AddCommand(newCom2);
+ cm.GetState()->AddCommand(newCom2);
// Add handler for ADD_SUBDIRECTORY
cmCTestAddSubdirectoryCommand* newCom3 =
new cmCTestAddSubdirectoryCommand;
newCom3->TestHandler = this;
- cm.AddCommand(newCom3);
+ cm.GetState()->AddCommand(newCom3);
// Add handler for SET_SOURCE_FILES_PROPERTIES
cmCTestSetTestsPropertiesCommand* newCom4
= new cmCTestSetTestsPropertiesCommand;
newCom4->TestHandler = this;
- cm.AddCommand(newCom4);
+ cm.GetState()->AddCommand(newCom4);
const char* testFilename;
if( cmSystemTools::FileExists("CTestTestfile.cmake") )
@@ -1588,7 +1635,7 @@ void cmCTestTestHandler::GetListOfTests()
return;
}
- if ( !mf->ReadListFile(0, testFilename) )
+ if ( !mf->ReadListFile(testFilename) )
{
return;
}
@@ -1596,8 +1643,8 @@ void cmCTestTestHandler::GetListOfTests()
{
return;
}
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "Done constructing a list of tests" << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Done constructing a list of tests" << std::endl, this->Quiet);
}
//----------------------------------------------------------------------
@@ -1708,12 +1755,97 @@ void cmCTestTestHandler::ExpandTestsToRunInformation(size_t numTests)
this->TestsToRun.erase(new_end, this->TestsToRun.end());
}
+void cmCTestTestHandler::ExpandTestsToRunInformationForRerunFailed()
+{
+
+ std::string dirName = this->CTest->GetBinaryDir() + "/Testing/Temporary";
+
+ cmsys::Directory directory;
+ if (directory.Load(dirName) == 0)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Unable to read the contents of "
+ << dirName << std::endl);
+ return;
+ }
+
+ int numFiles = static_cast<int>
+ (cmsys::Directory::GetNumberOfFilesInDirectory(dirName));
+ std::string pattern = "LastTestsFailed";
+ std::string logName = "";
+
+ for (int i = 0; i < numFiles; ++i)
+ {
+ std::string fileName = directory.GetFile(i);
+ // bcc crashes if we attempt a normal substring comparison,
+ // hence the following workaround
+ std::string fileNameSubstring = fileName.substr(0, pattern.length());
+ if (fileNameSubstring.compare(pattern) != 0)
+ {
+ continue;
+ }
+ if (logName == "")
+ {
+ logName = fileName;
+ }
+ else
+ {
+ // if multiple matching logs were found we use the most recently
+ // modified one.
+ int res;
+ cmSystemTools::FileTimeCompare(logName, fileName, &res);
+ if (res == -1)
+ {
+ logName = fileName;
+ }
+ }
+ }
+
+ std::string lastTestsFailedLog = this->CTest->GetBinaryDir()
+ + "/Testing/Temporary/" + logName;
+
+ if ( !cmSystemTools::FileExists(lastTestsFailedLog.c_str()) )
+ {
+ if ( !this->CTest->GetShowOnly() && !this->CTest->ShouldPrintLabels() )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, lastTestsFailedLog
+ << " does not exist!" << std::endl);
+ }
+ return;
+ }
+
+ // parse the list of tests to rerun from LastTestsFailed.log
+ cmsys::ifstream ifs(lastTestsFailedLog.c_str());
+ if ( ifs )
+ {
+ std::string line;
+ std::string::size_type pos;
+ while ( cmSystemTools::GetLineFromStream(ifs, line) )
+ {
+ pos = line.find(':', 0);
+ if (pos == line.npos)
+ {
+ continue;
+ }
+
+ int val = atoi(line.substr(0, pos).c_str());
+ this->TestsToRun.push_back(val);
+ }
+ ifs.close();
+ }
+ else if ( !this->CTest->GetShowOnly() && !this->CTest->ShouldPrintLabels() )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Problem reading file: "
+ << lastTestsFailedLog <<
+ " while generating list of previously failed tests." << std::endl);
+ }
+}
+
//----------------------------------------------------------------------
// Just for convenience
#define SPACE_REGEX "[ \t\r\n]"
//----------------------------------------------------------------------
-std::string cmCTestTestHandler::GenerateRegressionImages(
- const std::string& xml)
+void cmCTestTestHandler::GenerateRegressionImages(
+ cmXMLWriter& xml, const std::string& dart)
{
cmsys::RegularExpression twoattributes(
"<DartMeasurement"
@@ -1748,71 +1880,62 @@ std::string cmCTestTestHandler::GenerateRegressionImages(
SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
SPACE_REGEX "*>([^<]*)</DartMeasurementFile>");
- cmOStringStream ostr;
bool done = false;
- std::string cxml = xml;
+ std::string cxml = dart;
while ( ! done )
{
if ( twoattributes.find(cxml) )
{
- ostr
- << "\t\t\t<NamedMeasurement"
- << " " << twoattributes.match(1) << "=\""
- << twoattributes.match(2) << "\""
- << " " << twoattributes.match(3) << "=\""
- << twoattributes.match(4) << "\""
- << "><Value>" << twoattributes.match(5)
- << "</Value></NamedMeasurement>"
- << std::endl;
+ xml.StartElement("NamedMeasurement");
+ xml.Attribute(twoattributes.match(1).c_str(),
+ twoattributes.match(2));
+ xml.Attribute(twoattributes.match(3).c_str(),
+ twoattributes.match(4));
+ xml.Element("Value", twoattributes.match(5));
+ xml.EndElement();
cxml.erase(twoattributes.start(),
twoattributes.end() - twoattributes.start());
}
else if ( threeattributes.find(cxml) )
{
- ostr
- << "\t\t\t<NamedMeasurement"
- << " " << threeattributes.match(1) << "=\""
- << threeattributes.match(2) << "\""
- << " " << threeattributes.match(3) << "=\""
- << threeattributes.match(4) << "\""
- << " " << threeattributes.match(5) << "=\""
- << threeattributes.match(6) << "\""
- << "><Value>" << threeattributes.match(7)
- << "</Value></NamedMeasurement>"
- << std::endl;
+ xml.StartElement("NamedMeasurement");
+ xml.Attribute(threeattributes.match(1).c_str(),
+ threeattributes.match(2));
+ xml.Attribute(threeattributes.match(3).c_str(),
+ threeattributes.match(4));
+ xml.Attribute(threeattributes.match(5).c_str(),
+ threeattributes.match(6));
+ xml.Element("Value", twoattributes.match(7));
+ xml.EndElement();
cxml.erase(threeattributes.start(),
threeattributes.end() - threeattributes.start());
}
else if ( fourattributes.find(cxml) )
{
- ostr
- << "\t\t\t<NamedMeasurement"
- << " " << fourattributes.match(1) << "=\""
- << fourattributes.match(2) << "\""
- << " " << fourattributes.match(3) << "=\""
- << fourattributes.match(4) << "\""
- << " " << fourattributes.match(5) << "=\""
- << fourattributes.match(6) << "\""
- << " " << fourattributes.match(7) << "=\""
- << fourattributes.match(8) << "\""
- << "><Value>" << fourattributes.match(9)
- << "</Value></NamedMeasurement>"
- << std::endl;
+ xml.StartElement("NamedMeasurement");
+ xml.Attribute(fourattributes.match(1).c_str(),
+ fourattributes.match(2));
+ xml.Attribute(fourattributes.match(3).c_str(),
+ fourattributes.match(4));
+ xml.Attribute(fourattributes.match(5).c_str(),
+ fourattributes.match(6));
+ xml.Attribute(fourattributes.match(7).c_str(),
+ fourattributes.match(8));
+ xml.Element("Value", twoattributes.match(9));
+ xml.EndElement();
cxml.erase(fourattributes.start(),
fourattributes.end() - fourattributes.start());
}
else if ( cdatastart.find(cxml) && cdataend.find(cxml) )
{
- ostr
- << "\t\t\t<NamedMeasurement"
- << " " << cdatastart.match(1) << "=\""
- << cdatastart.match(2) << "\""
- << " " << cdatastart.match(3) << "=\""
- << cdatastart.match(4) << "\""
- << "><Value><![CDATA["
- << cxml.substr(cdatastart.end(), cdataend.start() - cdatastart.end())
- << "]]></Value></NamedMeasurement>"
- << std::endl;
+ xml.StartElement("NamedMeasurement");
+ xml.Attribute(cdatastart.match(1).c_str(), cdatastart.match(2));
+ xml.Attribute(cdatastart.match(3).c_str(), cdatastart.match(4));
+ xml.StartElement("Value");
+ xml.CData(
+ cxml.substr(cdatastart.end(), cdataend.start() - cdatastart.end()));
+ xml.EndElement(); // Value
+ xml.EndElement(); // NamedMeasurement
cxml.erase(cdatastart.start(),
cdataend.end() - cdatastart.start());
}
@@ -1822,7 +1945,7 @@ std::string cmCTestTestHandler::GenerateRegressionImages(
cmCTest::CleanString(measurementfile.match(5));
if ( cmSystemTools::FileExists(filename.c_str()) )
{
- long len = cmSystemTools::FileLength(filename.c_str());
+ long len = cmSystemTools::FileLength(filename);
if ( len == 0 )
{
std::string k1 = measurementfile.match(1);
@@ -1838,17 +1961,16 @@ std::string cmCTestTestHandler::GenerateRegressionImages(
v2 = "text/string";
}
- ostr
- << "\t\t\t<NamedMeasurement"
- << " " << k1 << "=\"" << v1 << "\""
- << " " << k2 << "=\"" << v2 << "\""
- << " encoding=\"none\""
- << "><Value>Image " << filename.c_str()
- << " is empty</Value></NamedMeasurement>";
+ xml.StartElement("NamedMeasurement");
+ xml.Attribute(k1.c_str(), v1);
+ xml.Attribute(k2.c_str(), v2);
+ xml.Attribute("encoding", "none");
+ xml.Element("Value", "Image " + filename + " is empty");
+ xml.EndElement();
}
else
{
- std::ifstream ifs(filename.c_str(), std::ios::in
+ cmsys::ifstream ifs(filename.c_str(), std::ios::in
#ifdef _WIN32
| std::ios::binary
#endif
@@ -1859,19 +1981,17 @@ std::string cmCTestTestHandler::GenerateRegressionImages(
= new unsigned char [ static_cast<int>(
static_cast<double>(len) * 1.5 + 5.0) ];
- unsigned long rlen
+ size_t rlen
= cmsysBase64_Encode(file_buffer, len, encoded_buffer, 1);
- unsigned long cc;
-
- ostr
- << "\t\t\t<NamedMeasurement"
- << " " << measurementfile.match(1) << "=\""
- << measurementfile.match(2) << "\""
- << " " << measurementfile.match(3) << "=\""
- << measurementfile.match(4) << "\""
- << " encoding=\"base64\""
- << ">" << std::endl << "\t\t\t\t<Value>";
- for ( cc = 0; cc < rlen; cc ++ )
+
+ xml.StartElement("NamedMeasurement");
+ xml.Attribute(measurementfile.match(1).c_str(),
+ measurementfile.match(2));
+ xml.Attribute(measurementfile.match(3).c_str(),
+ measurementfile.match(4));
+ xml.Attribute("encoding", "base64");
+ std::stringstream ostr;
+ for (size_t cc = 0; cc < rlen; cc ++ )
{
ostr << encoded_buffer[cc];
if ( cc % 60 == 0 && cc )
@@ -1879,9 +1999,8 @@ std::string cmCTestTestHandler::GenerateRegressionImages(
ostr << std::endl;
}
}
- ostr
- << "</Value>" << std::endl << "\t\t\t</NamedMeasurement>"
- << std::endl;
+ xml.Element("Value", ostr.str());
+ xml.EndElement(); // NamedMeasurement
delete [] file_buffer;
delete [] encoded_buffer;
}
@@ -1893,15 +2012,13 @@ std::string cmCTestTestHandler::GenerateRegressionImages(
{
idx = 2;
}
- ostr
- << "\t\t\t<NamedMeasurement"
- << " name=\"" << measurementfile.match(idx) << "\""
- << " text=\"text/string\""
- << "><Value>File " << filename.c_str()
- << " not found</Value></NamedMeasurement>"
- << std::endl;
- cmCTestLog(this->CTest, HANDLER_OUTPUT, "File \"" << filename.c_str()
- << "\" not found." << std::endl);
+ xml.StartElement("NamedMeasurement");
+ xml.Attribute("name", measurementfile.match(idx));
+ xml.Attribute("text", "text/string");
+ xml.Element("Value", "File " + filename + " not found");
+ xml.EndElement();
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "File \"" << filename
+ << "\" not found." << std::endl, this->Quiet);
}
cxml.erase(measurementfile.start(),
measurementfile.end() - measurementfile.start());
@@ -1911,7 +2028,6 @@ std::string cmCTestTestHandler::GenerateRegressionImages(
done = true;
}
}
- return ostr.str();
}
//----------------------------------------------------------------------
@@ -1938,7 +2054,7 @@ void cmCTestTestHandler::SetTestsToRunInformation(const char* in)
// string
if(cmSystemTools::FileExists(in))
{
- std::ifstream fin(in);
+ cmsys::ifstream fin(in);
unsigned long filelen = cmSystemTools::FileLength(in);
char* buff = new char[filelen+1];
fin.getline(buff, filelen);
@@ -1974,7 +2090,7 @@ bool cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length)
}
current = next;
}
- else // Bad byte will be handled by cmXMLSafe.
+ else // Bad byte will be handled by cmXMLWriter.
{
++current;
}
@@ -1982,7 +2098,7 @@ bool cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length)
output = output.substr(0, current - begin);
// Append truncation message.
- cmOStringStream msg;
+ std::ostringstream msg;
msg << "...\n"
"The rest of the test output was removed since it exceeds the threshold "
"of " << length << " bytes.\n";
@@ -1995,7 +2111,7 @@ bool cmCTestTestHandler::SetTestsProperties(
const std::vector<std::string>& args)
{
std::vector<std::string>::const_iterator it;
- std::vector<cmStdString> tests;
+ std::vector<std::string> tests;
bool found = false;
for ( it = args.begin(); it != args.end(); ++ it )
{
@@ -2020,7 +2136,7 @@ bool cmCTestTestHandler::SetTestsProperties(
break;
}
std::string val = *it;
- std::vector<cmStdString>::const_iterator tit;
+ std::vector<std::string>::const_iterator tit;
for ( tit = tests.begin(); tit != tests.end(); ++ tit )
{
cmCTestTestHandler::ListOfTests::iterator rtit;
@@ -2036,36 +2152,18 @@ bool cmCTestTestHandler::SetTestsProperties(
}
if ( key == "ATTACHED_FILES" )
{
- std::vector<std::string> lval;
- cmSystemTools::ExpandListArgument(val.c_str(), lval);
-
- for(std::vector<std::string>::iterator f = lval.begin();
- f != lval.end(); ++f)
- {
- rtit->AttachedFiles.push_back(*f);
- }
+ cmSystemTools::ExpandListArgument(val, rtit->AttachedFiles);
}
if ( key == "ATTACHED_FILES_ON_FAIL" )
{
- std::vector<std::string> lval;
- cmSystemTools::ExpandListArgument(val.c_str(), lval);
-
- for(std::vector<std::string>::iterator f = lval.begin();
- f != lval.end(); ++f)
- {
- rtit->AttachOnFail.push_back(*f);
- }
+ cmSystemTools::ExpandListArgument(val, rtit->AttachOnFail);
}
if ( key == "RESOURCE_LOCK" )
{
std::vector<std::string> lval;
- cmSystemTools::ExpandListArgument(val.c_str(), lval);
+ cmSystemTools::ExpandListArgument(val, lval);
- for(std::vector<std::string>::iterator f = lval.begin();
- f != lval.end(); ++f)
- {
- rtit->LockedResources.insert(*f);
- }
+ rtit->LockedResources.insert(lval.begin(), lval.end());
}
if ( key == "TIMEOUT" )
{
@@ -2078,14 +2176,7 @@ bool cmCTestTestHandler::SetTestsProperties(
}
if ( key == "REQUIRED_FILES" )
{
- std::vector<std::string> lval;
- cmSystemTools::ExpandListArgument(val.c_str(), lval);
-
- for(std::vector<std::string>::iterator f = lval.begin();
- f != lval.end(); ++f)
- {
- rtit->RequiredFiles.push_back(*f);
- }
+ cmSystemTools::ExpandListArgument(val, rtit->RequiredFiles);
}
if ( key == "RUN_SERIAL" )
{
@@ -2094,14 +2185,14 @@ bool cmCTestTestHandler::SetTestsProperties(
if ( key == "FAIL_REGULAR_EXPRESSION" )
{
std::vector<std::string> lval;
- cmSystemTools::ExpandListArgument(val.c_str(), lval);
+ cmSystemTools::ExpandListArgument(val, lval);
std::vector<std::string>::iterator crit;
for ( crit = lval.begin(); crit != lval.end(); ++ crit )
{
rtit->ErrorRegularExpressions.push_back(
std::pair<cmsys::RegularExpression, std::string>(
cmsys::RegularExpression(crit->c_str()),
- std::string(crit->c_str())));
+ std::string(*crit)));
}
}
if ( key == "PROCESSORS" )
@@ -2112,35 +2203,25 @@ bool cmCTestTestHandler::SetTestsProperties(
rtit->Processors = 1;
}
}
- if ( key == "DEPENDS" )
+ if ( key == "SKIP_RETURN_CODE" )
{
- std::vector<std::string> lval;
- cmSystemTools::ExpandListArgument(val.c_str(), lval);
- std::vector<std::string>::iterator crit;
- for ( crit = lval.begin(); crit != lval.end(); ++ crit )
+ rtit->SkipReturnCode = atoi(val.c_str());
+ if(rtit->SkipReturnCode < 0 || rtit->SkipReturnCode > 255)
{
- rtit->Depends.push_back(*crit);
+ rtit->SkipReturnCode = -1;
}
}
+ if ( key == "DEPENDS" )
+ {
+ cmSystemTools::ExpandListArgument(val, rtit->Depends);
+ }
if ( key == "ENVIRONMENT" )
{
- std::vector<std::string> lval;
- cmSystemTools::ExpandListArgument(val.c_str(), lval);
- std::vector<std::string>::iterator crit;
- for ( crit = lval.begin(); crit != lval.end(); ++ crit )
- {
- rtit->Environment.push_back(*crit);
- }
+ cmSystemTools::ExpandListArgument(val, rtit->Environment);
}
if ( key == "LABELS" )
{
- std::vector<std::string> lval;
- cmSystemTools::ExpandListArgument(val.c_str(), lval);
- std::vector<std::string>::iterator crit;
- for ( crit = lval.begin(); crit != lval.end(); ++ crit )
- {
- rtit->Labels.push_back(*crit);
- }
+ cmSystemTools::ExpandListArgument(val, rtit->Labels);
}
if ( key == "MEASUREMENT" )
{
@@ -2159,14 +2240,14 @@ bool cmCTestTestHandler::SetTestsProperties(
if ( key == "PASS_REGULAR_EXPRESSION" )
{
std::vector<std::string> lval;
- cmSystemTools::ExpandListArgument(val.c_str(), lval);
+ cmSystemTools::ExpandListArgument(val, lval);
std::vector<std::string>::iterator crit;
for ( crit = lval.begin(); crit != lval.end(); ++ crit )
{
rtit->RequiredRegularExpressions.push_back(
std::pair<cmsys::RegularExpression, std::string>(
cmsys::RegularExpression(crit->c_str()),
- std::string(crit->c_str())));
+ std::string(*crit)));
}
}
if ( key == "WORKING_DIRECTORY" )
@@ -2184,7 +2265,8 @@ 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);
+ cmCTestOptionalLog(this->CTest, DEBUG, "Add test: " << args[0] << std::endl,
+ this->Quiet);
if (this->UseExcludeRegExpFlag &&
this->UseExcludeRegExpFirst &&
@@ -2194,7 +2276,7 @@ bool cmCTestTestHandler::AddTest(const std::vector<std::string>& args)
}
if ( this->MemCheck )
{
- std::vector<cmStdString>::iterator it;
+ std::vector<std::string>::iterator it;
bool found = false;
for ( it = this->CustomTestsIgnore.begin();
it != this->CustomTestsIgnore.end(); ++ it )
@@ -2207,14 +2289,14 @@ bool cmCTestTestHandler::AddTest(const std::vector<std::string>& args)
}
if ( found )
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Ignore memcheck: "
- << *it << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Ignore memcheck: " << *it << std::endl, this->Quiet);
return true;
}
}
else
{
- std::vector<cmStdString>::iterator it;
+ std::vector<std::string>::iterator it;
bool found = false;
for ( it = this->CustomTestsIgnore.begin();
it != this->CustomTestsIgnore.end(); ++ it )
@@ -2227,8 +2309,8 @@ bool cmCTestTestHandler::AddTest(const std::vector<std::string>& args)
}
if ( found )
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Ignore test: "
- << *it << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Ignore test: "
+ << *it << std::endl, this->Quiet);
return true;
}
}
@@ -2237,8 +2319,8 @@ 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);
+ cmCTestOptionalLog(this->CTest, DEBUG, "Set test directory: "
+ << test.Directory << std::endl, this->Quiet);
test.IsInBasedOnREOptions = true;
test.WillFail = false;
@@ -2247,6 +2329,7 @@ bool cmCTestTestHandler::AddTest(const std::vector<std::string>& args)
test.ExplicitTimeout = false;
test.Cost = 0;
test.Processors = 1;
+ test.SkipReturnCode = -1;
test.PreviousRuns = 0;
if (this->UseIncludeRegExpFlag &&
!this->IncludeTestsRegularExpression.find(testname.c_str()))
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h
index 93b793b20..c635430d9 100644
--- a/Source/CTest/cmCTestTestHandler.h
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -18,6 +18,7 @@
#include <cmsys/RegularExpression.hxx>
class cmMakefile;
+class cmXMLWriter;
/** \class cmCTestTestHandler
* \brief A class that handles ctest -S invocations
@@ -44,6 +45,12 @@ public:
void SetUseUnion(bool val) { this->UseUnion = val; }
/**
+ * Set whether or not CTest should only execute the tests that failed
+ * on the previous run. By default this is false.
+ */
+ void SetRerunFailed(bool val) { this->RerunFailed = val; }
+
+ /**
* This method is called when reading CTest custom file
*/
void PopulateCustomVectors(cmMakefile *mf);
@@ -58,6 +65,11 @@ public:
void SetMaxIndex(int n) {this->MaxIndex = n;}
int GetMaxIndex() {return this->MaxIndex;}
+ void SetTestOutputSizePassed(int n)
+ { this->CustomMaximumPassedTestOutputSize = n; }
+ void SetTestOutputSizeFailed(int n)
+ { this->CustomMaximumFailedTestOutputSize = n; }
+
///! pass the -I argument down
void SetTestsToRunInformation(const char*);
@@ -81,8 +93,8 @@ public:
// ctest -j N will break for that feature
struct cmCTestTestProperties
{
- cmStdString Name;
- cmStdString Directory;
+ std::string Name;
+ std::string Directory;
std::vector<std::string> Args;
std::vector<std::string> RequiredFiles;
std::vector<std::string> Depends;
@@ -92,7 +104,7 @@ public:
std::string> > ErrorRegularExpressions;
std::vector<std::pair<cmsys::RegularExpression,
std::string> > RequiredRegularExpressions;
- std::map<cmStdString, cmStdString> Measurements;
+ std::map<std::string, std::string> Measurements;
bool IsInBasedOnREOptions;
bool WillFail;
float Cost;
@@ -103,6 +115,8 @@ public:
int Index;
//Requested number of process slots
int Processors;
+ // return code of test which will mark test as "not run"
+ int SkipReturnCode;
std::vector<std::string> Environment;
std::vector<std::string> Labels;
std::set<std::string> LockedResources;
@@ -120,7 +134,7 @@ public:
bool CompressOutput;
std::string CompletionStatus;
std::string Output;
- std::string RegressionImages;
+ std::string DartString;
int TestCount;
cmCTestTestProperties* Properties;
};
@@ -154,12 +168,12 @@ protected:
virtual int PreProcessHandler();
virtual int PostProcessHandler();
virtual void GenerateTestCommand(std::vector<std::string>& args, int test);
- int ExecuteCommands(std::vector<cmStdString>& vec);
+ int ExecuteCommands(std::vector<std::string>& vec);
- void WriteTestResultHeader(std::ostream& os, cmCTestTestResult* result);
- void WriteTestResultFooter(std::ostream& os, cmCTestTestResult* result);
+ void WriteTestResultHeader(cmXMLWriter& xml, cmCTestTestResult* result);
+ void WriteTestResultFooter(cmXMLWriter& xml, cmCTestTestResult* result);
// Write attached test files into the xml
- void AttachFiles(std::ostream& os, cmCTestTestResult* result);
+ void AttachFiles(cmXMLWriter& xml, cmCTestTestResult* result);
//! Clean test output to specified length
bool CleanTestOutput(std::string& output, size_t length);
@@ -169,7 +183,7 @@ protected:
typedef std::vector<cmCTestTestResult> TestResultsVector;
TestResultsVector TestResults;
- std::vector<cmStdString> CustomTestsIgnore;
+ std::vector<std::string> CustomTestsIgnore;
std::string StartTest;
std::string EndTest;
unsigned int StartTestTime;
@@ -196,14 +210,14 @@ private:
/**
* Generate the Dart compatible output
*/
- virtual void GenerateDartOutput(std::ostream& os);
+ virtual void GenerateDartOutput(cmXMLWriter& xml);
void PrintLabelSummary();
/**
* Run the tests for a directory and any subdirectories
*/
- void ProcessDirectory(std::vector<cmStdString> &passed,
- std::vector<cmStdString> &failed);
+ void ProcessDirectory(std::vector<std::string> &passed,
+ std::vector<std::string> &failed);
/**
* Get the list of tests in directory and subdirectories.
@@ -213,21 +227,27 @@ private:
// based on union regex and -I stuff
void ComputeTestList();
+ // compute the lists of tests that will actually run
+ // based on LastTestFailed.log
+ void ComputeTestListForRerunFailed();
+
+ void UpdateMaxTestNameWidth();
+
bool GetValue(const char* tag,
std::string& value,
- std::ifstream& fin);
+ std::istream& fin);
bool GetValue(const char* tag,
int& value,
- std::ifstream& fin);
+ std::istream& fin);
bool GetValue(const char* tag,
size_t& value,
- std::ifstream& fin);
+ std::istream& fin);
bool GetValue(const char* tag,
bool& value,
- std::ifstream& fin);
+ std::istream& fin);
bool GetValue(const char* tag,
double& value,
- std::ifstream& fin);
+ std::istream& fin);
/**
* Find the executable for a test
*/
@@ -235,9 +255,10 @@ private:
const char* GetTestStatus(int status);
void ExpandTestsToRunInformation(size_t numPossibleTests);
+ void ExpandTestsToRunInformationForRerunFailed();
- std::vector<cmStdString> CustomPreTest;
- std::vector<cmStdString> CustomPostTest;
+ std::vector<std::string> CustomPreTest;
+ std::vector<std::string> CustomPostTest;
std::vector<int> TestsToRun;
@@ -255,7 +276,7 @@ private:
cmsys::RegularExpression IncludeTestsRegularExpression;
cmsys::RegularExpression ExcludeTestsRegularExpression;
- std::string GenerateRegressionImages(const std::string& xml);
+ void GenerateRegressionImages(cmXMLWriter& xml, const std::string& dart);
cmsys::RegularExpression DartStuff1;
void CheckLabelFilter(cmCTestTestProperties& it);
void CheckLabelFilterExclude(cmCTestTestProperties& it);
@@ -268,6 +289,8 @@ private:
cmsys::RegularExpression DartStuff;
std::ostream* LogFile;
+
+ bool RerunFailed;
};
#endif
diff --git a/Source/CTest/cmCTestUpdateCommand.cxx b/Source/CTest/cmCTestUpdateCommand.cxx
index 2ca9f6c86..dfda9f1e9 100644
--- a/Source/CTest/cmCTestUpdateCommand.cxx
+++ b/Source/CTest/cmCTestUpdateCommand.cxx
@@ -20,45 +20,56 @@ cmCTestGenericHandler* cmCTestUpdateCommand::InitializeHandler()
{
this->CTest->SetCTestConfiguration("SourceDirectory",
cmSystemTools::CollapseFullPath(
- this->Values[ct_SOURCE]).c_str());
+ this->Values[ct_SOURCE]).c_str(), this->Quiet);
}
else
{
this->CTest->SetCTestConfiguration("SourceDirectory",
cmSystemTools::CollapseFullPath(
- this->Makefile->GetDefinition("CTEST_SOURCE_DIRECTORY")).c_str());
+ this->Makefile->GetDefinition("CTEST_SOURCE_DIRECTORY")).c_str(),
+ this->Quiet);
}
std::string source_dir
= this->CTest->GetCTestConfiguration("SourceDirectory");
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
- "UpdateCommand", "CTEST_UPDATE_COMMAND");
+ "UpdateCommand", "CTEST_UPDATE_COMMAND", this->Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
- "UpdateOptions", "CTEST_UPDATE_OPTIONS");
+ "UpdateOptions", "CTEST_UPDATE_OPTIONS", this->Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
- "CVSCommand", "CTEST_CVS_COMMAND");
+ "CVSCommand", "CTEST_CVS_COMMAND", this->Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
- "CVSUpdateOptions", "CTEST_CVS_UPDATE_OPTIONS");
+ "CVSUpdateOptions", "CTEST_CVS_UPDATE_OPTIONS", this->Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
- "SVNCommand", "CTEST_SVN_COMMAND");
+ "SVNCommand", "CTEST_SVN_COMMAND", this->Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
- "SVNUpdateOptions", "CTEST_SVN_UPDATE_OPTIONS");
+ "SVNUpdateOptions", "CTEST_SVN_UPDATE_OPTIONS", this->Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
- "SVNOptions", "CTEST_SVN_OPTIONS");
+ "SVNOptions", "CTEST_SVN_OPTIONS", this->Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
- "BZRCommand", "CTEST_BZR_COMMAND");
+ "BZRCommand", "CTEST_BZR_COMMAND", this->Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
- "BZRUpdateOptions", "CTEST_BZR_UPDATE_OPTIONS");
+ "BZRUpdateOptions", "CTEST_BZR_UPDATE_OPTIONS", this->Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
- "GITCommand", "CTEST_GIT_COMMAND");
+ "GITCommand", "CTEST_GIT_COMMAND", this->Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
- "GITUpdateOptions", "CTEST_GIT_UPDATE_OPTIONS");
+ "GITUpdateOptions", "CTEST_GIT_UPDATE_OPTIONS", this->Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
- "GITUpdateCustom", "CTEST_GIT_UPDATE_CUSTOM");
+ "GITUpdateCustom", "CTEST_GIT_UPDATE_CUSTOM", this->Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
- "HGCommand", "CTEST_HG_COMMAND");
+ "UpdateVersionOnly", "CTEST_UPDATE_VERSION_ONLY", this->Quiet);
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
- "HGUpdateOptions", "CTEST_HG_UPDATE_OPTIONS");
+ "HGCommand", "CTEST_HG_COMMAND", this->Quiet);
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "HGUpdateOptions", "CTEST_HG_UPDATE_OPTIONS", this->Quiet);
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "P4Command", "CTEST_P4_COMMAND", this->Quiet);
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "P4UpdateOptions", "CTEST_P4_UPDATE_OPTIONS", this->Quiet);
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "P4Client", "CTEST_P4_CLIENT", this->Quiet);
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "P4Options", "CTEST_P4_OPTIONS", this->Quiet);
cmCTestGenericHandler* handler
= this->CTest->GetInitializedHandler("update");
@@ -74,6 +85,7 @@ cmCTestGenericHandler* cmCTestUpdateCommand::InitializeHandler()
return 0;
}
handler->SetOption("SourceDirectory", source_dir.c_str());
+ handler->SetQuiet(this->Quiet);
return handler;
}
diff --git a/Source/CTest/cmCTestUpdateCommand.h b/Source/CTest/cmCTestUpdateCommand.h
index c578fff6f..fb80333b7 100644
--- a/Source/CTest/cmCTestUpdateCommand.h
+++ b/Source/CTest/cmCTestUpdateCommand.h
@@ -39,29 +39,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "ctest_update";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Update the work tree from version control.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " ctest_update([SOURCE source] [RETURN_VALUE res])\n"
- "Updates the given source directory and stores results in Update.xml. "
- "If no SOURCE is given, the CTEST_SOURCE_DIRECTORY variable is used. "
- "The RETURN_VALUE option specifies a variable in which to store the "
- "result, which is the number of files updated or -1 on error."
- ;
- }
+ virtual std::string GetName() const { return "ctest_update";}
cmTypeMacro(cmCTestUpdateCommand, cmCTestHandlerCommand);
diff --git a/Source/CTest/cmCTestUpdateHandler.cxx b/Source/CTest/cmCTestUpdateHandler.cxx
index 9eae3f3ac..bf2f34ac7 100644
--- a/Source/CTest/cmCTestUpdateHandler.cxx
+++ b/Source/CTest/cmCTestUpdateHandler.cxx
@@ -15,12 +15,12 @@
#include "cmCTest.h"
#include "cmake.h"
#include "cmMakefile.h"
-#include "cmLocalGenerator.h"
#include "cmGlobalGenerator.h"
#include "cmVersion.h"
#include "cmGeneratedFileStream.h"
#include "cmXMLParser.h"
-#include "cmXMLSafe.h"
+#include "cmXMLWriter.h"
+#include "cmCLocaleEnvironmentScope.h"
#include "cmCTestVC.h"
#include "cmCTestCVS.h"
@@ -28,6 +28,7 @@
#include "cmCTestBZR.h"
#include "cmCTestGIT.h"
#include "cmCTestHG.h"
+#include "cmCTestP4.h"
#include <cmsys/auto_ptr.hxx>
@@ -51,7 +52,8 @@ static const char* cmCTestUpdateHandlerUpdateStrings[] =
"SVN",
"BZR",
"GIT",
- "HG"
+ "HG",
+ "P4"
};
static const char* cmCTestUpdateHandlerUpdateToString(int type)
@@ -64,46 +66,6 @@ static const char* cmCTestUpdateHandlerUpdateToString(int type)
return cmCTestUpdateHandlerUpdateStrings[type];
}
-class cmCTestUpdateHandlerLocale
-{
-public:
- cmCTestUpdateHandlerLocale();
- ~cmCTestUpdateHandlerLocale();
-private:
- std::string saveLCMessages;
-};
-
-cmCTestUpdateHandlerLocale::cmCTestUpdateHandlerLocale()
-{
- const char* lcmess = cmSystemTools::GetEnv("LC_MESSAGES");
- if(lcmess)
- {
- saveLCMessages = lcmess;
- }
- // if LC_MESSAGES is not set to C, then
- // set it, so that svn/cvs info will be in english ascii
- if(! (lcmess && strcmp(lcmess, "C") == 0))
- {
- cmSystemTools::PutEnv("LC_MESSAGES=C");
- }
-}
-
-cmCTestUpdateHandlerLocale::~cmCTestUpdateHandlerLocale()
-{
- // restore the value of LC_MESSAGES after running the version control
- // commands
- if(saveLCMessages.size())
- {
- std::string put = "LC_MESSAGES=";
- put += saveLCMessages;
- cmSystemTools::PutEnv(put.c_str());
- }
- else
- {
- cmSystemTools::UnsetEnv("LC_MESSAGES");
- }
-}
-
//----------------------------------------------------------------------
cmCTestUpdateHandler::cmCTestUpdateHandler()
{
@@ -120,11 +82,13 @@ void cmCTestUpdateHandler::Initialize()
//----------------------------------------------------------------------
int cmCTestUpdateHandler::DetermineType(const char* cmd, const char* type)
{
- cmCTestLog(this->CTest, DEBUG, "Determine update type from command: " << cmd
- << " and type: " << type << std::endl);
+ cmCTestOptionalLog(this->CTest, DEBUG,
+ "Determine update type from command: " << cmd << " and type: " << type <<
+ std::endl, this->Quiet);
if ( type && *type )
{
- cmCTestLog(this->CTest, DEBUG, "Type specified: " << type << std::endl);
+ cmCTestOptionalLog(this->CTest, DEBUG, "Type specified: " << type <<
+ std::endl, this->Quiet);
std::string stype = cmSystemTools::LowerCase(type);
if ( stype.find("cvs") != std::string::npos )
{
@@ -146,11 +110,15 @@ int cmCTestUpdateHandler::DetermineType(const char* cmd, const char* type)
{
return cmCTestUpdateHandler::e_HG;
}
+ if ( stype.find("p4") != std::string::npos )
+ {
+ return cmCTestUpdateHandler::e_P4;
+ }
}
else
{
- cmCTestLog(this->CTest, DEBUG, "Type not specified, check command: "
- << cmd << std::endl);
+ cmCTestOptionalLog(this->CTest, DEBUG,
+ "Type not specified, check command: " << cmd << std::endl, this->Quiet);
std::string stype = cmSystemTools::LowerCase(cmd);
if ( stype.find("cvs") != std::string::npos )
{
@@ -172,6 +140,10 @@ int cmCTestUpdateHandler::DetermineType(const char* cmd, const char* type)
{
return cmCTestUpdateHandler::e_HG;
}
+ if ( stype.find("p4") != std::string::npos )
+ {
+ return cmCTestUpdateHandler::e_P4;
+ }
}
return cmCTestUpdateHandler::e_UNKNOWN;
}
@@ -182,7 +154,7 @@ int cmCTestUpdateHandler::DetermineType(const char* cmd, const char* type)
int cmCTestUpdateHandler::ProcessHandler()
{
// Make sure VCS tool messages are in English so we can parse them.
- cmCTestUpdateHandlerLocale fixLocale;
+ cmCLocaleEnvironmentScope fixLocale;
static_cast<void>(fixLocale);
// Get source dir
@@ -201,18 +173,19 @@ int cmCTestUpdateHandler::ProcessHandler()
this->StartLogFile("Update", ofs);
}
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " Updating the repository: "
- << sourceDirectory << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ " Updating the repository: " << sourceDirectory << std::endl,
+ this->Quiet);
if(!this->SelectVCS())
{
return -1;
}
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " Use "
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Use "
<< cmCTestUpdateHandlerUpdateToString(this->UpdateType)
<< " repository type"
- << std::endl;);
+ << std::endl;, this->Quiet);
// Create an object to interact with the VCS tool.
cmsys::auto_ptr<cmCTestVC> vc;
@@ -223,6 +196,7 @@ int cmCTestUpdateHandler::ProcessHandler()
case e_BZR: vc.reset(new cmCTestBZR(this->CTest, ofs)); break;
case e_GIT: vc.reset(new cmCTestGIT(this->CTest, ofs)); break;
case e_HG: vc.reset(new cmCTestHG(this->CTest, ofs)); break;
+ case e_P4: vc.reset(new cmCTestP4(this->CTest, ofs)); break;
default: vc.reset(new cmCTestVC(this->CTest, ofs)); break;
}
vc->SetCommandLineTool(this->UpdateCommand);
@@ -247,80 +221,82 @@ int cmCTestUpdateHandler::ProcessHandler()
double elapsed_time_start = cmSystemTools::GetTime();
bool updated = vc->Update();
-
- os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- << "<Update mode=\"Client\" Generator=\"ctest-"
- << cmVersion::GetCMakeVersion() << "\">\n"
- << "\t<Site>" << this->CTest->GetCTestConfiguration("Site") << "</Site>\n"
- << "\t<BuildName>" << this->CTest->GetCTestConfiguration("BuildName")
- << "</BuildName>\n"
- << "\t<BuildStamp>" << this->CTest->GetCurrentTag() << "-"
- << this->CTest->GetTestModelString() << "</BuildStamp>" << std::endl;
- os << "\t<StartDateTime>" << start_time << "</StartDateTime>\n"
- << "\t<StartTime>" << start_time_time << "</StartTime>\n"
- << "\t<UpdateCommand>"
- << cmXMLSafe(vc->GetUpdateCommandLine()).Quotes(false)
- << "</UpdateCommand>\n"
- << "\t<UpdateType>" << cmXMLSafe(
- cmCTestUpdateHandlerUpdateToString(this->UpdateType))
- << "</UpdateType>\n";
-
- vc->WriteXML(os);
+ std::string buildname = cmCTest::SafeBuildIdField(
+ this->CTest->GetCTestConfiguration("BuildName"));
+
+ cmXMLWriter xml(os);
+ xml.StartDocument();
+ xml.StartElement("Update");
+ xml.Attribute("mode", "Client");
+ xml.Attribute("Generator",
+ std::string("ctest-") + cmVersion::GetCMakeVersion());
+ xml.Element("Site", this->CTest->GetCTestConfiguration("Site"));
+ xml.Element("BuildName", buildname);
+ xml.Element("BuildStamp", this->CTest->GetCurrentTag() + "-" +
+ this->CTest->GetTestModelString());
+ xml.Element("StartDateTime", start_time);
+ xml.Element("StartTime", start_time_time);
+ xml.Element("UpdateCommand", vc->GetUpdateCommandLine());
+ xml.Element("UpdateType",
+ cmCTestUpdateHandlerUpdateToString(this->UpdateType));
+
+ vc->WriteXML(xml);
int localModifications = 0;
int numUpdated = vc->GetPathCount(cmCTestVC::PathUpdated);
if(numUpdated)
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
- " Found " << numUpdated << " updated files\n");
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ " Found " << numUpdated << " updated files\n", this->Quiet);
}
if(int numModified = vc->GetPathCount(cmCTestVC::PathModified))
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
- " Found " << numModified << " locally modified files\n");
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ " Found " << numModified << " locally modified files\n", this->Quiet);
localModifications += numModified;
}
if(int numConflicting = vc->GetPathCount(cmCTestVC::PathConflicting))
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
- " Found " << numConflicting << " conflicting files\n");
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ " Found " << numConflicting << " conflicting files\n", this->Quiet);
localModifications += numConflicting;
}
- cmCTestLog(this->CTest, DEBUG, "End" << std::endl);
+ cmCTestOptionalLog(this->CTest, DEBUG, "End" << std::endl, this->Quiet);
std::string end_time = this->CTest->CurrentTime();
- os << "\t<EndDateTime>" << end_time << "</EndDateTime>\n"
- << "\t<EndTime>" << static_cast<unsigned int>(cmSystemTools::GetTime())
- << "</EndTime>\n"
- << "<ElapsedMinutes>" <<
- static_cast<int>((cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0
- << "</ElapsedMinutes>\n"
- << "\t<UpdateReturnStatus>";
+ xml.Element("EndDateTime", end_time);
+ xml.Element("EndTime", static_cast<unsigned int>(cmSystemTools::GetTime()));
+ xml.Element("ElapsedMinutes",
+ static_cast<int>((cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0);
+
+ xml.StartElement("UpdateReturnStatus");
if(localModifications)
{
- os << "Update error: There are modified or conflicting files in the "
- "repository";
+ xml.Content("Update error: "
+ "There are modified or conflicting files in the repository");
cmCTestLog(this->CTest, ERROR_MESSAGE,
" There are modified or conflicting files in the repository"
<< std::endl);
}
if(!updated)
{
- os << "Update command failed:\n" << vc->GetUpdateCommandLine();
- cmCTestLog(this->CTest, ERROR_MESSAGE, " Update command failed: "
+ xml.Content("Update command failed:\n");
+ xml.Content(vc->GetUpdateCommandLine());
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Update command failed: "
<< vc->GetUpdateCommandLine() << "\n");
}
- os << "</UpdateReturnStatus>" << std::endl;
- os << "</Update>" << std::endl;
- return numUpdated;
+ xml.EndElement(); // UpdateReturnStatus
+ xml.EndElement(); // Update
+ xml.EndDocument();
+ return updated? numUpdated : -1;
}
//----------------------------------------------------------------------
int cmCTestUpdateHandler::DetectVCS(const char* dir)
{
std::string sourceDirectory = dir;
- cmCTestLog(this->CTest, DEBUG, "Check directory: "
- << sourceDirectory.c_str() << std::endl);
+ cmCTestOptionalLog(this->CTest, DEBUG, "Check directory: "
+ << sourceDirectory << std::endl, this->Quiet);
sourceDirectory += "/.svn";
if ( cmSystemTools::FileExists(sourceDirectory.c_str()) )
{
@@ -350,6 +326,18 @@ int cmCTestUpdateHandler::DetectVCS(const char* dir)
{
return cmCTestUpdateHandler::e_HG;
}
+ sourceDirectory = dir;
+ sourceDirectory += "/.p4";
+ if ( cmSystemTools::FileExists(sourceDirectory.c_str()) )
+ {
+ return cmCTestUpdateHandler::e_P4;
+ }
+ sourceDirectory = dir;
+ sourceDirectory += "/.p4config";
+ if ( cmSystemTools::FileExists(sourceDirectory.c_str()) )
+ {
+ return cmCTestUpdateHandler::e_P4;
+ }
return cmCTestUpdateHandler::e_UNKNOWN;
}
@@ -380,6 +368,7 @@ bool cmCTestUpdateHandler::SelectVCS()
case e_BZR: key = "BZRCommand"; break;
case e_GIT: key = "GITCommand"; break;
case e_HG: key = "HGCommand"; break;
+ case e_P4: key = "P4Command"; break;
default: break;
}
if (key)
@@ -388,7 +377,7 @@ bool cmCTestUpdateHandler::SelectVCS()
}
if (this->UpdateCommand.empty())
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Cannot find UpdateCommand ";
if (key)
{
diff --git a/Source/CTest/cmCTestUpdateHandler.h b/Source/CTest/cmCTestUpdateHandler.h
index 55ec974dc..d2423c0d5 100644
--- a/Source/CTest/cmCTestUpdateHandler.h
+++ b/Source/CTest/cmCTestUpdateHandler.h
@@ -17,10 +17,6 @@
#include "cmCTestGenericHandler.h"
#include "cmListFileCache.h"
-#if defined(__sgi) && !defined(__GNUC__)
-# pragma set woff 1375 /* base class destructor not virtual */
-#endif
-
/** \class cmCTestUpdateHandler
* \brief A class that handles ctest -S invocations
*
@@ -44,6 +40,7 @@ public:
e_BZR,
e_GIT,
e_HG,
+ e_P4,
e_LAST
};
@@ -69,8 +66,4 @@ private:
bool SelectVCS();
};
-#if defined(__sgi) && !defined(__GNUC__)
-# pragma reset woff 1375 /* base class destructor not virtual */
-#endif
-
#endif
diff --git a/Source/CTest/cmCTestUploadCommand.cxx b/Source/CTest/cmCTestUploadCommand.cxx
index 731c1c7a3..f5000dd4c 100644
--- a/Source/CTest/cmCTestUploadCommand.cxx
+++ b/Source/CTest/cmCTestUploadCommand.cxx
@@ -26,6 +26,7 @@ cmCTestGenericHandler* cmCTestUploadCommand::InitializeHandler()
}
static_cast<cmCTestUploadHandler*>(handler)->SetFiles(this->Files);
+ handler->SetQuiet(this->Quiet);
return handler;
}
@@ -38,6 +39,12 @@ bool cmCTestUploadCommand::CheckArgumentKeyword(std::string const& arg)
this->ArgumentDoing = ArgumentDoingFiles;
return true;
}
+ if(arg == "QUIET")
+ {
+ this->ArgumentDoing = ArgumentDoingNone;
+ this->Quiet = true;
+ return true;
+ }
return false;
}
@@ -47,7 +54,7 @@ bool cmCTestUploadCommand::CheckArgumentValue(std::string const& arg)
{
if(this->ArgumentDoing == ArgumentDoingFiles)
{
- cmStdString filename(arg);
+ std::string filename(arg);
if(cmSystemTools::FileExists(filename.c_str()))
{
this->Files.insert(filename);
@@ -55,7 +62,7 @@ bool cmCTestUploadCommand::CheckArgumentValue(std::string const& arg)
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "File \"" << filename << "\" does not exist. Cannot submit "
<< "a non-existent file.";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
diff --git a/Source/CTest/cmCTestUploadCommand.h b/Source/CTest/cmCTestUploadCommand.h
index 62f379f6d..4a07608d2 100644
--- a/Source/CTest/cmCTestUploadCommand.h
+++ b/Source/CTest/cmCTestUploadCommand.h
@@ -43,26 +43,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "ctest_upload";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Upload files to a dashboard server.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " ctest_upload(FILES ...)\n"
- "Pass a list of files to be sent along with the build results to "
- "the dashboard server.\n";
- }
+ virtual std::string GetName() const { return "ctest_upload";}
cmTypeMacro(cmCTestUploadCommand, cmCTestHandlerCommand);
diff --git a/Source/CTest/cmCTestUploadHandler.cxx b/Source/CTest/cmCTestUploadHandler.cxx
index caf2e5370..5c6b2290f 100644
--- a/Source/CTest/cmCTestUploadHandler.cxx
+++ b/Source/CTest/cmCTestUploadHandler.cxx
@@ -13,7 +13,7 @@
#include "cmGeneratedFileStream.h"
#include "cmVersion.h"
-#include "cmXMLSafe.h"
+#include "cmXMLWriter.h"
//----------------------------------------------------------------------------
cmCTestUploadHandler::cmCTestUploadHandler()
@@ -44,34 +44,39 @@ int cmCTestUploadHandler::ProcessHandler()
"Cannot open Upload.xml file" << std::endl);
return -1;
}
-
+ std::string buildname = cmCTest::SafeBuildIdField(
+ this->CTest->GetCTestConfiguration("BuildName"));
cmCTest::SetOfStrings::const_iterator it;
- ofs << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- << "<?xml-stylesheet type=\"text/xsl\" "
+
+ cmXMLWriter xml(ofs);
+ xml.StartDocument();
+ xml.ProcessingInstruction("xml-stylesheet", "type=\"text/xsl\" "
"href=\"Dart/Source/Server/XSL/Build.xsl "
- "<file:///Dart/Source/Server/XSL/Build.xsl> \"?>\n"
- << "<Site BuildName=\""
- << this->CTest->GetCTestConfiguration("BuildName")
- << "\" BuildStamp=\""
- << this->CTest->GetCurrentTag() << "-"
- << this->CTest->GetTestModelString() << "\" Name=\""
- << this->CTest->GetCTestConfiguration("Site") << "\" Generator=\"ctest"
- << cmVersion::GetCMakeVersion()
- << "\">\n";
- this->CTest->AddSiteProperties(ofs);
- ofs << "<Upload>\n";
+ "<file:///Dart/Source/Server/XSL/Build.xsl> \"");
+ xml.StartElement("Site");
+ xml.Attribute("BuildName", buildname);
+ xml.Attribute("BuildStamp",
+ this->CTest->GetCurrentTag() + "-" + this->CTest->GetTestModelString());
+ xml.Attribute("Name", this->CTest->GetCTestConfiguration("Site"));
+ xml.Attribute("Generator",
+ std::string("ctest") + cmVersion::GetCMakeVersion());
+ this->CTest->AddSiteProperties(xml);
+ xml.StartElement("Upload");
for ( it = this->Files.begin(); it != this->Files.end(); it ++ )
{
- cmCTestLog(this->CTest, OUTPUT,
- "\tUpload file: " << it->c_str() << std::endl);
- ofs << "<File filename=\"" << cmXMLSafe(*it) << "\">\n"
- << "<Content encoding=\"base64\">\n";
- ofs << this->CTest->Base64EncodeFile(*it);
- ofs << "\n</Content>\n"
- << "</File>\n";
+ cmCTestOptionalLog(this->CTest, OUTPUT,
+ "\tUpload file: " << *it << std::endl, this->Quiet);
+ xml.StartElement("File");
+ xml.Attribute("filename", *it);
+ xml.StartElement("Content");
+ xml.Attribute("encoding", "base64");
+ xml.Content(this->CTest->Base64EncodeFile(*it));
+ xml.EndElement(); // Content
+ xml.EndElement(); // File
}
- ofs << "</Upload>\n"
- << "</Site>\n";
+ xml.EndElement(); // Upload
+ xml.EndElement(); // Site
+ xml.EndDocument();
return 0;
}
diff --git a/Source/CTest/cmCTestVC.cxx b/Source/CTest/cmCTestVC.cxx
index fbee2272e..8eff4d61b 100644
--- a/Source/CTest/cmCTestVC.cxx
+++ b/Source/CTest/cmCTestVC.cxx
@@ -13,7 +13,7 @@
#include "cmCTest.h"
#include "cmSystemTools.h"
-#include "cmXMLSafe.h"
+#include "cmXMLWriter.h"
#include <cmsys/Process.h>
@@ -63,9 +63,9 @@ bool cmCTestVC::InitialCheckout(const char* command)
}
// Construct the initial checkout command line.
- std::vector<cmStdString> args = cmSystemTools::ParseArguments(command);
+ std::vector<std::string> args = cmSystemTools::ParseArguments(command);
std::vector<char const*> vc_co;
- for(std::vector<cmStdString>::const_iterator ai = args.begin();
+ for(std::vector<std::string>::const_iterator ai = args.begin();
ai != args.end(); ++ai)
{
vc_co.push_back(ai->c_str());
@@ -105,7 +105,7 @@ bool cmCTestVC::RunChild(char const* const* cmd, OutputParser* out,
//----------------------------------------------------------------------------
std::string cmCTestVC::ComputeCommandLine(char const* const* cmd)
{
- cmOStringStream line;
+ std::ostringstream line;
const char* sep = "";
for(const char* const* arg = cmd; *arg; ++arg)
{
@@ -166,10 +166,17 @@ void cmCTestVC::CleanupImpl()
//----------------------------------------------------------------------------
bool cmCTestVC::Update()
{
- this->NoteOldRevision();
- this->Log << "--- Begin Update ---\n";
- bool result = this->UpdateImpl();
- this->Log << "--- End Update ---\n";
+ bool result = true;
+ // if update version only is on then do not actually update,
+ // just note the current version and finish
+ if(!cmSystemTools::IsOn(
+ this->CTest->GetCTestConfiguration("UpdateVersionOnly").c_str()))
+ {
+ this->NoteOldRevision();
+ this->Log << "--- Begin Update ---\n";
+ result = this->UpdateImpl();
+ this->Log << "--- End Update ---\n";
+ }
this->NoteNewRevision();
return result;
}
@@ -195,7 +202,7 @@ bool cmCTestVC::UpdateImpl()
}
//----------------------------------------------------------------------------
-bool cmCTestVC::WriteXML(std::ostream& xml)
+bool cmCTestVC::WriteXML(cmXMLWriter& xml)
{
this->Log << "--- Begin Revisions ---\n";
bool result = this->WriteXMLUpdates(xml);
@@ -204,7 +211,7 @@ bool cmCTestVC::WriteXML(std::ostream& xml)
}
//----------------------------------------------------------------------------
-bool cmCTestVC::WriteXMLUpdates(std::ostream&)
+bool cmCTestVC::WriteXMLUpdates(cmXMLWriter&)
{
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"* CTest cannot extract updates for this VCS tool.\n");
@@ -212,7 +219,7 @@ bool cmCTestVC::WriteXMLUpdates(std::ostream&)
}
//----------------------------------------------------------------------------
-void cmCTestVC::WriteXMLEntry(std::ostream& xml,
+void cmCTestVC::WriteXMLEntry(cmXMLWriter& xml,
std::string const& path,
std::string const& name,
std::string const& full,
@@ -221,21 +228,19 @@ void cmCTestVC::WriteXMLEntry(std::ostream& xml,
static const char* desc[3] = { "Updated", "Modified", "Conflicting"};
Revision const& rev = f.Rev? *f.Rev : this->Unknown;
std::string prior = f.PriorRev? f.PriorRev->Rev : std::string("Unknown");
- xml << "\t\t<" << desc[f.Status] << ">\n"
- << "\t\t\t<File>" << cmXMLSafe(name) << "</File>\n"
- << "\t\t\t<Directory>" << cmXMLSafe(path) << "</Directory>\n"
- << "\t\t\t<FullName>" << cmXMLSafe(full) << "</FullName>\n"
- << "\t\t\t<CheckinDate>" << cmXMLSafe(rev.Date) << "</CheckinDate>\n"
- << "\t\t\t<Author>" << cmXMLSafe(rev.Author) << "</Author>\n"
- << "\t\t\t<Email>" << cmXMLSafe(rev.EMail) << "</Email>\n"
- << "\t\t\t<Committer>" << cmXMLSafe(rev.Committer) << "</Committer>\n"
- << "\t\t\t<CommitterEmail>" << cmXMLSafe(rev.CommitterEMail)
- << "</CommitterEmail>\n"
- << "\t\t\t<CommitDate>" << cmXMLSafe(rev.CommitDate)
- << "</CommitDate>\n"
- << "\t\t\t<Log>" << cmXMLSafe(rev.Log) << "</Log>\n"
- << "\t\t\t<Revision>" << cmXMLSafe(rev.Rev) << "</Revision>\n"
- << "\t\t\t<PriorRevision>" << cmXMLSafe(prior) << "</PriorRevision>\n"
- << "\t\t</" << desc[f.Status] << ">\n";
+ xml.StartElement(desc[f.Status]);
+ xml.Element("File", name);
+ xml.Element("Directory", path);
+ xml.Element("FullName", full);
+ xml.Element("CheckinDate", rev.Date);
+ xml.Element("Author", rev.Author);
+ xml.Element("Email", rev.EMail);
+ xml.Element("Committer", rev.Committer);
+ xml.Element("CommitterEmail", rev.CommitterEMail);
+ xml.Element("CommitDate", rev.CommitDate);
+ xml.Element("Log", rev.Log);
+ xml.Element("Revision", rev.Rev);
+ xml.Element("PriorRevision", prior);
+ xml.EndElement();
++this->PathCount[f.Status];
}
diff --git a/Source/CTest/cmCTestVC.h b/Source/CTest/cmCTestVC.h
index 9dd06515d..bc8930287 100644
--- a/Source/CTest/cmCTestVC.h
+++ b/Source/CTest/cmCTestVC.h
@@ -15,6 +15,7 @@
#include "cmProcessTools.h"
class cmCTest;
+class cmXMLWriter;
/** \class cmCTestVC
* \brief Base class for version control system handlers
@@ -51,7 +52,7 @@ public:
{ return this->UpdateCommandLine; }
/** Write Update.xml entries for the updates found. */
- bool WriteXML(std::ostream& xml);
+ bool WriteXML(cmXMLWriter& xml);
/** Enumerate non-trivial working tree states during update. */
enum PathStatus { PathUpdated, PathModified, PathConflicting };
@@ -65,7 +66,7 @@ protected:
virtual void NoteOldRevision();
virtual bool UpdateImpl();
virtual void NoteNewRevision();
- virtual bool WriteXMLUpdates(std::ostream& xml);
+ virtual bool WriteXMLUpdates(cmXMLWriter& xml);
#if defined(__SUNPRO_CC) && __SUNPRO_CC <= 0x510
public: // Sun CC 5.1 needs help to allow cmCTestSVN::Revision to see this
@@ -110,7 +111,7 @@ protected:
OutputParser* out, OutputParser* err = 0);
/** Write xml element for one file. */
- void WriteXMLEntry(std::ostream& xml, std::string const& path,
+ void WriteXMLEntry(cmXMLWriter& xml, std::string const& path,
std::string const& name, std::string const& full,
File const& f);
diff --git a/Source/CTest/cmParseBlanketJSCoverage.cxx b/Source/CTest/cmParseBlanketJSCoverage.cxx
new file mode 100644
index 000000000..1edd01f48
--- /dev/null
+++ b/Source/CTest/cmParseBlanketJSCoverage.cxx
@@ -0,0 +1,164 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmStandardIncludes.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "cmSystemTools.h"
+#include "cmParseBlanketJSCoverage.h"
+#include <cmsys/Directory.hxx>
+#include <cmsys/Glob.hxx>
+#include <cmsys/FStream.hxx>
+
+
+class cmParseBlanketJSCoverage::JSONParser
+ {
+public:
+ typedef cmCTestCoverageHandlerContainer::
+ SingleFileCoverageVector FileLinesType;
+ JSONParser(cmCTestCoverageHandlerContainer& cont)
+ : Coverage(cont)
+ {
+ }
+
+ virtual ~JSONParser()
+ {
+ }
+
+ std::string getValue(std::string line, int type)
+ {
+ size_t begIndex;
+ size_t endIndex;
+ endIndex = line.rfind(',');
+ begIndex = line.find_first_of(':');
+ if(type == 0)
+ {
+ // A unique substring to remove the extra characters
+ // around the files name in the JSON (extra " and ,)
+ std::string foundFileName =
+ line.substr(begIndex+3,endIndex-(begIndex+4));
+ return foundFileName;
+ }
+ else
+ {
+ return line.substr(begIndex,line.npos);
+ }
+ }
+ bool ParseFile(std::string file)
+ {
+ FileLinesType localCoverageVector;
+ std::string filename;
+ bool foundFile = false;
+ bool inSource = false;
+ std::string covResult;
+ std::string line;
+
+ cmsys::ifstream in(file.c_str());
+ if(!in)
+ {
+ return false;
+ }
+ while( cmSystemTools::GetLineFromStream(in, line))
+ {
+ if(line.find("filename") != line.npos)
+ {
+ if(foundFile)
+ {
+ /*
+ * Upon finding a second file name, generate a
+ * vector within the total coverage to capture the
+ * information in the local vector
+ */
+ FileLinesType& CoverageVector =
+ this->Coverage.TotalCoverage[filename];
+ CoverageVector = localCoverageVector;
+ localCoverageVector.clear();
+ }
+ foundFile= true;
+ inSource = false;
+ filename = getValue(line,0).c_str();
+ }
+ else if((line.find("coverage") != line.npos) && foundFile && inSource )
+ {
+ /*
+ * two types of "coverage" in the JSON structure
+ *
+ * The coverage result over the file or set of files
+ * and the coverage for each individual line
+ *
+ * FoundFile and foundSource ensure that
+ * only the value of the line coverage is captured
+ */
+ std::string result = getValue(line,1);
+ result = result.substr(2,result.npos);
+ if(result == "\"\"")
+ {
+ // Empty quotation marks indicate that the
+ // line is not executable
+ localCoverageVector.push_back(-1);
+ }
+ else
+ {
+ // Else, it contains the number of time executed
+ localCoverageVector.push_back(atoi(result.c_str()));
+ }
+ }
+ else if(line.find("source") != line.npos)
+ {
+ inSource=true;
+ }
+ }
+
+ // On exit, capture end of last file covered.
+ FileLinesType& CoverageVector =
+ this->Coverage.TotalCoverage[filename];
+ CoverageVector = localCoverageVector;
+ localCoverageVector.clear();
+ return true;
+ }
+private:
+ cmCTestCoverageHandlerContainer& Coverage;
+};
+
+cmParseBlanketJSCoverage::cmParseBlanketJSCoverage(
+ cmCTestCoverageHandlerContainer& cont, cmCTest* ctest)
+ :Coverage(cont), CTest(ctest)
+ {
+ }
+
+bool cmParseBlanketJSCoverage::LoadCoverageData(std::vector<std::string> files)
+ {
+ size_t i=0;
+ std::string path;
+ cmCTestOptionalLog(this->CTest,HANDLER_VERBOSE_OUTPUT,
+ "Found " << files.size() <<" Files" << std::endl, this->Coverage.Quiet);
+ for(i=0;i<files.size();i++)
+ {
+ cmCTestOptionalLog(this->CTest,HANDLER_VERBOSE_OUTPUT,
+ "Reading JSON File " << files[i] << std::endl, this->Coverage.Quiet);
+
+ if(!this->ReadJSONFile(files[i]))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+bool cmParseBlanketJSCoverage::ReadJSONFile(std::string file)
+ {
+ cmParseBlanketJSCoverage::JSONParser parser
+ (this->Coverage);
+ cmCTestOptionalLog(this->CTest,HANDLER_VERBOSE_OUTPUT,
+ "Parsing " << file << std::endl, this->Coverage.Quiet);
+ parser.ParseFile(file);
+ return true;
+ }
diff --git a/Source/CTest/cmParseBlanketJSCoverage.h b/Source/CTest/cmParseBlanketJSCoverage.h
new file mode 100644
index 000000000..fc1d47747
--- /dev/null
+++ b/Source/CTest/cmParseBlanketJSCoverage.h
@@ -0,0 +1,48 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmParseBlanketJSCoverage_h
+#define cmParseBlanketJSCoverage_h
+
+#include "cmStandardIncludes.h"
+#include "cmCTestCoverageHandler.h"
+
+
+/** \class cmParseBlanketJSCoverage
+ * \brief Parse BlanketJS coverage information
+ *
+ * This class is used to parse BlanketJS(Pascal) coverage information
+ * generated by the Blanket.js library when used in conjunction with the
+ * test runner mocha.js, which is used to write out the JSON format.
+ *
+ * Blanket.js:
+ * http://blanketjs.org/
+ *
+ * Mocha.js
+ * http://visionmedia.github.io/mocha/
+ */
+class cmParseBlanketJSCoverage
+{
+public:
+ cmParseBlanketJSCoverage(cmCTestCoverageHandlerContainer& cont,
+ cmCTest* ctest);
+ bool LoadCoverageData(std::vector<std::string> files);
+ // Read the JSON output
+ bool ReadJSONFile(std::string file);
+
+protected:
+
+ class JSONParser;
+ cmCTestCoverageHandlerContainer& Coverage;
+ cmCTest* CTest;
+};
+#endif
diff --git a/Source/CTest/cmParseCacheCoverage.cxx b/Source/CTest/cmParseCacheCoverage.cxx
index 137f344df..92bf88eaf 100644
--- a/Source/CTest/cmParseCacheCoverage.cxx
+++ b/Source/CTest/cmParseCacheCoverage.cxx
@@ -5,6 +5,7 @@
#include "cmParseCacheCoverage.h"
#include <cmsys/Directory.hxx>
#include <cmsys/Glob.hxx>
+#include <cmsys/FStream.hxx>
cmParseCacheCoverage::cmParseCacheCoverage(
@@ -30,7 +31,7 @@ bool cmParseCacheCoverage::LoadCoverageData(const char* d)
{
std::string file = dir.GetFile(i);
if(file != "." && file != ".."
- && !cmSystemTools::FileIsDirectory(file.c_str()))
+ && !cmSystemTools::FileIsDirectory(file))
{
std::string path = d;
path += "/";
@@ -70,9 +71,9 @@ void cmParseCacheCoverage::RemoveUnCoveredFiles()
}
if(nothing)
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"No coverage found in: " << ci->first
- << std::endl);
+ << std::endl, this->Coverage.Quiet);
this->Coverage.TotalCoverage.erase(ci++);
}
else
@@ -106,7 +107,7 @@ bool cmParseCacheCoverage::SplitString(std::vector<std::string>& args,
bool cmParseCacheCoverage::ReadCMCovFile(const char* file)
{
- std::ifstream in(file);
+ cmsys::ifstream in(file);
if(!in)
{
cmCTestLog(this->CTest, ERROR_MESSAGE,
@@ -162,7 +163,7 @@ bool cmParseCacheCoverage::ReadCMCovFile(const char* file)
}
// if we do not have a routine yet, then it should be
// the first argument in the vector
- if(routine.size() == 0)
+ if(routine.empty())
{
routine = separateLine[0];
// Find the full path to the file
@@ -190,7 +191,7 @@ bool cmParseCacheCoverage::ReadCMCovFile(const char* file)
// move to next line. We should have already warned
// after the call to FindMumpsFile that we did not find
// it, so don't report again to cut down on output
- if(filepath.size() == 0)
+ if(filepath.empty())
{
continue;
}
@@ -214,7 +215,19 @@ bool cmParseCacheCoverage::ReadCMCovFile(const char* file)
{
coverageVector.push_back(-1);
}
- coverageVector[linenumber] += count;
+ // Accounts for lines that were previously marked
+ // as non-executable code (-1). if the parser comes back with
+ // a non-zero count, increase the count by 1 to push the line
+ // into the executable code set in addition to the count found.
+ if(coverageVector[linenumber] == -1 &&
+ count > 0)
+ {
+ coverageVector[linenumber] += count+1;
+ }
+ else
+ {
+ coverageVector[linenumber] += count;
+ }
}
return true;
}
diff --git a/Source/CTest/cmParseCoberturaCoverage.cxx b/Source/CTest/cmParseCoberturaCoverage.cxx
new file mode 100644
index 000000000..3ed5cb0f9
--- /dev/null
+++ b/Source/CTest/cmParseCoberturaCoverage.cxx
@@ -0,0 +1,200 @@
+#include "cmStandardIncludes.h"
+#include "cmSystemTools.h"
+#include "cmXMLParser.h"
+#include "cmParseCoberturaCoverage.h"
+#include <cmsys/Directory.hxx>
+#include <cmsys/FStream.hxx>
+
+//----------------------------------------------------------------------------
+class cmParseCoberturaCoverage::XMLParser: public cmXMLParser
+{
+public:
+ XMLParser(cmCTest* ctest, cmCTestCoverageHandlerContainer& cont)
+ : CTest(ctest), Coverage(cont)
+ {
+ this->InSources = false;
+ this->InSource = false;
+ this->SkipThisClass = false;
+ this->FilePaths.push_back(this->Coverage.SourceDir);
+ this->FilePaths.push_back(this->Coverage.BinaryDir);
+ this->CurFileName = "";
+ }
+
+ virtual ~XMLParser()
+ {
+ }
+
+protected:
+
+
+ virtual void EndElement(const std::string& name)
+ {
+ if(name == "source")
+ {
+ this->InSource=false;
+ }
+ else if (name == "sources")
+ {
+ this->InSources=false;
+ }
+ else if(name == "class")
+ {
+ this->SkipThisClass = false;
+ }
+ }
+
+ virtual void CharacterDataHandler(const char* data, int length)
+ {
+ std::string tmp;
+ tmp.insert(0,data,length);
+ if (this->InSources && this->InSource)
+ {
+ this->FilePaths.push_back(tmp);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Adding Source: " << tmp << std::endl, this->Coverage.Quiet);
+ }
+ }
+
+ virtual void StartElement(const std::string& name, const char** atts)
+ {
+ std::string FoundSource;
+ std::string finalpath = "";
+ if(name == "source")
+ {
+ this->InSource = true;
+ }
+ else if(name == "sources")
+ {
+ this->InSources = true;
+ }
+ else if(name == "class")
+ {
+ int tagCount = 0;
+ while(true)
+ {
+ if(strcmp(atts[tagCount], "filename") == 0)
+ {
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Reading file: " << atts[tagCount+1]<< std::endl,
+ this->Coverage.Quiet);
+ std::string filename = atts[tagCount+1];
+ this->CurFileName = "";
+
+ // Check if this is an absolute path that falls within our
+ // source or binary directories.
+ for(size_t i=0;i < FilePaths.size();i++)
+ {
+ if (filename.find(FilePaths[i]) == 0)
+ {
+ this->CurFileName = filename;
+ break;
+ }
+ }
+
+ if (this->CurFileName == "")
+ {
+ // Check if this is a path that is relative to our source or
+ // binary directories.
+ for(size_t i=0;i < FilePaths.size();i++)
+ {
+ finalpath = FilePaths[i] + "/" + filename;
+ if(cmSystemTools::FileExists(finalpath.c_str()))
+ {
+ this->CurFileName = finalpath;
+ break;
+ }
+ }
+ }
+
+ cmsys::ifstream fin(this->CurFileName.c_str());
+ if(this->CurFileName == "" || !fin )
+ {
+ this->CurFileName = this->Coverage.BinaryDir + "/" +
+ atts[tagCount+1];
+ fin.open(this->CurFileName.c_str());
+ if (!fin)
+ {
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Skipping system file " << filename << std::endl,
+ this->Coverage.Quiet);
+
+ this->SkipThisClass = true;
+ break;
+ }
+ }
+ std::string line;
+ FileLinesType& curFileLines =
+ this->Coverage.TotalCoverage[this->CurFileName];
+ curFileLines.push_back(-1);
+ while(cmSystemTools::GetLineFromStream(fin, line))
+ {
+ curFileLines.push_back(-1);
+ }
+
+ break;
+ }
+ ++tagCount;
+ }
+ }
+ else if(name == "line")
+ {
+ int tagCount = 0;
+ int curNumber = -1;
+ int curHits = -1;
+ while(true)
+ {
+ if(this->SkipThisClass)
+ {
+ break;
+ }
+ if(strcmp(atts[tagCount], "hits") == 0)
+ {
+ curHits = atoi(atts[tagCount+1]);
+ }
+ else if(strcmp(atts[tagCount], "number") == 0)
+ {
+ curNumber = atoi(atts[tagCount+1]);
+ }
+
+ if(curHits > -1 && curNumber > 0)
+ {
+ FileLinesType& curFileLines =
+ this->Coverage.TotalCoverage[this->CurFileName];
+ {
+ curFileLines[curNumber-1] = curHits;
+ }
+ break;
+ }
+ ++tagCount;
+ }
+ }
+ }
+
+private:
+
+ bool InSources;
+ bool InSource;
+ bool SkipThisClass;
+ std::vector<std::string> FilePaths;
+ typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector
+ FileLinesType;
+ cmCTest* CTest;
+ cmCTestCoverageHandlerContainer& Coverage;
+ std::string CurFileName;
+
+};
+
+
+cmParseCoberturaCoverage::cmParseCoberturaCoverage(
+ cmCTestCoverageHandlerContainer& cont,
+ cmCTest* ctest)
+ :Coverage(cont), CTest(ctest)
+{
+}
+
+bool cmParseCoberturaCoverage::ReadCoverageXML(const char* xmlFile)
+{
+ cmParseCoberturaCoverage::XMLParser parser(this->CTest, this->Coverage);
+ parser.ParseFile(xmlFile);
+ return true;
+}
diff --git a/Source/CTest/cmParseCoberturaCoverage.h b/Source/CTest/cmParseCoberturaCoverage.h
new file mode 100644
index 000000000..ff5954dd1
--- /dev/null
+++ b/Source/CTest/cmParseCoberturaCoverage.h
@@ -0,0 +1,51 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmParseCoberturaCoverage_h
+#define cmParseCoberturaCoverage_h
+
+#include "cmStandardIncludes.h"
+#include "cmCTestCoverageHandler.h"
+
+/** \class cmParsePythonCoverage
+ * \brief Parse coverage.py Python coverage information
+ *
+ * This class is used to parse the output of the coverage.py tool that
+ * is currently maintained by Ned Batchelder. That tool has a command
+ * that produces xml output in the format typically output by the common
+ * Java-based Cobertura coverage application. This helper class parses
+ * that XML file to fill the coverage-handler container.
+ */
+class cmParseCoberturaCoverage
+{
+public:
+
+ //! Create the coverage parser by passing in the coverage handler
+ //! container and the cmCTest object
+ cmParseCoberturaCoverage(cmCTestCoverageHandlerContainer& cont,
+ cmCTest* ctest);
+
+ bool inSources;
+ bool inSource;
+ std::vector<std::string> filepaths;
+ //! Read the XML produced by running `coverage xml`
+ bool ReadCoverageXML(const char* xmlFile);
+
+private:
+
+ class XMLParser;
+ cmCTestCoverageHandlerContainer& Coverage;
+ cmCTest* CTest;
+ std::string CurFileName;
+};
+
+#endif
diff --git a/Source/CTest/cmParseDelphiCoverage.cxx b/Source/CTest/cmParseDelphiCoverage.cxx
new file mode 100644
index 000000000..e453fe167
--- /dev/null
+++ b/Source/CTest/cmParseDelphiCoverage.cxx
@@ -0,0 +1,254 @@
+#include "cmStandardIncludes.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "cmSystemTools.h"
+#include "cmXMLParser.h"
+#include "cmParseDelphiCoverage.h"
+#include <cmsys/Directory.hxx>
+#include <cmsys/Glob.hxx>
+#include <cmsys/FStream.hxx>
+
+
+class cmParseDelphiCoverage::HTMLParser
+{
+public:
+ typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector
+ FileLinesType;
+ HTMLParser(cmCTest* ctest, cmCTestCoverageHandlerContainer& cont)
+ : CTest(ctest), Coverage(cont)
+ {
+ }
+
+ virtual ~HTMLParser()
+ {
+ }
+
+ bool initializeDelphiFile(const std::string filename,
+ cmParseDelphiCoverage::HTMLParser::FileLinesType &coverageVector)
+ {
+ std::string line;
+ size_t comPos;
+ size_t semiPos;
+ bool blockComFlag= false;
+ bool lineComFlag= false;
+ std::vector<std::string> beginSet;
+ cmsys::ifstream in(filename.c_str());
+ if(!in)
+ {
+ return false;
+ }
+ while(cmSystemTools::GetLineFromStream(in, line))
+ {
+ lineComFlag=false;
+ // Unique cases found in lines.
+ size_t beginPos = line.find("begin");
+
+ //Check that the begin is the first non-space string on the line
+ if( (beginPos == line.find_first_not_of(' ')) && beginPos != line.npos )
+ {
+ beginSet.push_back("begin");
+ coverageVector.push_back(-1);
+ continue;
+ }
+ else if(line.find('{') != line.npos)
+ {
+ blockComFlag=true;
+ }
+ else if(line.find('}') != line.npos)
+ {
+ blockComFlag=false;
+ coverageVector.push_back(-1);
+ continue;
+ }
+ else if((line.find("end;") != line.npos)
+ && !beginSet.empty())
+ {
+ beginSet.pop_back();
+ coverageVector.push_back(-1);
+ continue;
+ }
+
+ // This checks for comments after lines of code, finding the
+ // comment symbol after the ending semicolon.
+ comPos = line.find("//");
+ if(comPos != line.npos)
+ {
+ semiPos= line.find(';');
+ if(comPos < semiPos)
+ {
+ lineComFlag=true;
+ }
+ }
+ //Based up what was found, add a line to the coverageVector
+ if(!beginSet.empty() && line != "" && !blockComFlag
+ && !lineComFlag)
+ {
+ coverageVector.push_back(0);
+ }
+ else
+ {
+ coverageVector.push_back(-1);
+ }
+ }
+ return true;
+ }
+ bool ParseFile(const char* file)
+ {
+ std::string line=file;
+ std::string lineresult;
+ std::string lastroutine;
+ std::string filename;
+ std::string filelineoffset;
+ size_t afterLineNum = 0;
+ size_t lastoffset = 0;
+ size_t endcovpos = 0;
+ size_t endnamepos = 0;
+ size_t pos = 0;
+
+ /*
+ * This first 'while' section goes through the found HTML
+ * file name and attempts to capture the source file name
+ * which is set as part of the HTML file name: the name of
+ * the file is found in parenthesis '()'
+ *
+ * See test HTML file name: UTCovTest(UTCovTest.pas).html.
+ *
+ * Find the text inside each pair of parenthesis and check
+ * to see if it ends in '.pas'. If it can't be found,
+ * exit the function.
+ */
+ while(true)
+ {
+ lastoffset = line.find('(',pos);
+ if(lastoffset==line.npos)
+ {
+ cmCTestOptionalLog(this->CTest,HANDLER_VERBOSE_OUTPUT,
+ endnamepos << "File not found " << lastoffset << std::endl,
+ this->Coverage.Quiet);
+ return false;
+ }
+ endnamepos = line.find(')',lastoffset);
+ filename = line.substr(lastoffset+1,
+ (endnamepos-1)-lastoffset);
+ if(filename.find(".pas") != filename.npos)
+ {
+ cmCTestOptionalLog(this->CTest,HANDLER_VERBOSE_OUTPUT,
+ "Coverage found for file: " << filename << std::endl,
+ this->Coverage.Quiet);
+ break;
+ }
+ pos = lastoffset+1;
+ }
+ /*
+ * Glob through the source directory for the
+ * file found above
+ */
+ cmsys::Glob gl;
+ gl.RecurseOn();
+ gl.RecurseThroughSymlinksOff();
+ std::string glob = Coverage.SourceDir + "*/" + filename;
+ gl.FindFiles(glob);
+ std::vector<std::string> const& files = gl.GetFiles();
+ if(files.empty())
+ {
+ /*
+ * If that doesn't find any matching files
+ * return a failure.
+ */
+ cmCTestOptionalLog(this->CTest,HANDLER_VERBOSE_OUTPUT,
+ "Unable to find file matching" << glob << std::endl,
+ this->Coverage.Quiet);
+ return false;
+ }
+ FileLinesType& coverageVector =
+ this->Coverage.TotalCoverage[files[0]];
+
+ /*
+ * Initialize the file to have all code between 'begin' and
+ * 'end' tags marked as executable
+ */
+
+ this->initializeDelphiFile(files[0],coverageVector);
+
+ cmsys::ifstream in(file);
+ if(!in)
+ {
+ return false;
+ }
+
+ /*
+ * Now read the HTML file, looking for the lines that have an
+ * "inline" in it. Then parse out the "class" value of that
+ * line to determine if the line is executed or not.
+ *
+ * Sample HTML line:
+ *
+ * <tr class="covered"><td>47</td><td><pre style="display:inline;">
+ * &nbsp;CheckEquals(1,2-1);</pre></td></tr>
+ *
+ */
+
+ while( cmSystemTools::GetLineFromStream(in, line))
+ {
+ if(line.find("inline") == line.npos)
+ {
+ continue;
+ }
+
+ lastoffset = line.find("class=");
+ endcovpos = line.find(">",lastoffset);
+ lineresult = line.substr(lastoffset+7,(endcovpos-8)-lastoffset);
+
+ if(lineresult == "covered")
+ {
+ afterLineNum = line.find('<',endcovpos+5);
+ filelineoffset= line.substr(endcovpos+5,
+ afterLineNum-(endcovpos+5));
+ coverageVector[atoi(filelineoffset.c_str())-1] = 1;
+ }
+ }
+ return true;
+ }
+
+
+ private:
+ cmCTest* CTest;
+ cmCTestCoverageHandlerContainer& Coverage;
+};
+
+cmParseDelphiCoverage::cmParseDelphiCoverage(
+ cmCTestCoverageHandlerContainer& cont, cmCTest* ctest)
+ :Coverage(cont), CTest(ctest)
+ {
+ }
+
+bool cmParseDelphiCoverage::LoadCoverageData(
+ const std::vector<std::string> files)
+ {
+ size_t i;
+ std::string path;
+ size_t numf = files.size();
+ for (i = 0; i < numf; i++)
+ {
+ path = files[i];
+
+ cmCTestOptionalLog(this->CTest,HANDLER_VERBOSE_OUTPUT,
+ "Reading HTML File " << path << std::endl, this->Coverage.Quiet);
+ if(cmSystemTools::GetFilenameLastExtension(path) == ".html")
+ {
+ if(!this->ReadDelphiHTML(path.c_str()))
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+bool cmParseDelphiCoverage::ReadDelphiHTML(const char* file)
+ {
+ cmParseDelphiCoverage::HTMLParser
+ parser(this->CTest, this->Coverage);
+ parser.ParseFile(file);
+ return true;
+ }
diff --git a/Source/CTest/cmParseDelphiCoverage.h b/Source/CTest/cmParseDelphiCoverage.h
new file mode 100644
index 000000000..018340b2e
--- /dev/null
+++ b/Source/CTest/cmParseDelphiCoverage.h
@@ -0,0 +1,46 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmParseDelphiCoverage_h
+#define cmParseDelphiCoverage_h
+
+#include "cmStandardIncludes.h"
+#include "cmCTestCoverageHandler.h"
+
+
+/** \class cmParseDelphiCoverage
+ * \brief Parse Delphi coverage information
+ *
+ * This class is used to parse Delphi(Pascal) coverage information
+ * generated by the Delphi-Code-Coverage tool
+ *
+ * https://code.google.com/p/delphi-code-coverage/
+ */
+
+class cmParseDelphiCoverage
+ {
+ public:
+ cmParseDelphiCoverage(cmCTestCoverageHandlerContainer& cont,
+ cmCTest* ctest);
+ bool LoadCoverageData(const std::vector<std::string> files);
+ bool ReadDelphiHTML(const char* file);
+ // Read a single HTML file from output
+ bool ReadHTMLFile(const char* f);
+
+
+ protected:
+
+ class HTMLParser;
+ cmCTestCoverageHandlerContainer& Coverage;
+ cmCTest* CTest;
+ };
+#endif
diff --git a/Source/CTest/cmParseGTMCoverage.cxx b/Source/CTest/cmParseGTMCoverage.cxx
index 6b4adb4bd..f3f80084d 100644
--- a/Source/CTest/cmParseGTMCoverage.cxx
+++ b/Source/CTest/cmParseGTMCoverage.cxx
@@ -5,6 +5,7 @@
#include "cmParseGTMCoverage.h"
#include <cmsys/Directory.hxx>
#include <cmsys/Glob.hxx>
+#include <cmsys/FStream.hxx>
cmParseGTMCoverage::cmParseGTMCoverage(cmCTestCoverageHandlerContainer& cont,
@@ -29,7 +30,7 @@ bool cmParseGTMCoverage::LoadCoverageData(const char* d)
{
std::string file = dir.GetFile(i);
if(file != "." && file != ".."
- && !cmSystemTools::FileIsDirectory(file.c_str()))
+ && !cmSystemTools::FileIsDirectory(file))
{
std::string path = d;
path += "/";
@@ -48,7 +49,7 @@ bool cmParseGTMCoverage::LoadCoverageData(const char* d)
bool cmParseGTMCoverage::ReadMCovFile(const char* file)
{
- std::ifstream in(file);
+ cmsys::ifstream in(file);
if(!in)
{
return false;
@@ -79,7 +80,7 @@ bool cmParseGTMCoverage::ReadMCovFile(const char* file)
// no need to search the file if we just did it
if(function == lastfunction && lastroutine == routine)
{
- if(lastpath.size())
+ if(!lastpath.empty())
{
this->Coverage.TotalCoverage[lastpath][lastoffset + linenumber]
+= count;
@@ -105,7 +106,19 @@ bool cmParseGTMCoverage::ReadMCovFile(const char* file)
{
cmCTestCoverageHandlerContainer::SingleFileCoverageVector&
coverageVector = this->Coverage.TotalCoverage[filepath];
- coverageVector[lineoffset + linenumber] += count;
+ // This section accounts for lines that were previously marked
+ // as non-executable code (-1), if the parser comes back with
+ // a non-zero count, increase the count by 1 to push the line
+ // into the executable code set in addtion to the count found.
+ if(coverageVector[lineoffset + linenumber] == -1 &&
+ count > 0)
+ {
+ coverageVector[lineoffset + linenumber] += count+1;
+ }
+ else
+ {
+ coverageVector[lineoffset + linenumber] += count;
+ }
lastoffset = lineoffset;
}
}
@@ -127,7 +140,7 @@ bool cmParseGTMCoverage::FindFunctionInMumpsFile(std::string const& filepath,
std::string const& function,
int& lineoffset)
{
- std::ifstream in(filepath.c_str());
+ cmsys::ifstream in(filepath.c_str());
if(!in)
{
return false;
@@ -140,7 +153,7 @@ bool cmParseGTMCoverage::FindFunctionInMumpsFile(std::string const& filepath,
if(pos == 0)
{
char nextchar = line[function.size()];
- if(nextchar == ' ' || nextchar == '(')
+ if(nextchar == ' ' || nextchar == '('|| nextchar == '\t')
{
lineoffset = linenum;
return true;
@@ -181,7 +194,7 @@ bool cmParseGTMCoverage::ParseMCOVLine(std::string const& line,
// ( file , entry ) = "number_executed:timing_info"
// ^COVERAGE("%RSEL","init",8,"FOR_LOOP",1)=1
// ( file , entry, line, IGNORE ) =number_executed
- std::vector<cmStdString> args;
+ std::vector<std::string> args;
std::string::size_type pos = line.find('(', 0);
// if no ( is found, then return line has no coverage
if(pos == std::string::npos)
@@ -260,7 +273,11 @@ bool cmParseGTMCoverage::ParseMCOVLine(std::string const& line,
// ^COVERAGE("%RSEL","SRC"), the line offset is 0
if(args.size() == 2)
{
- linenumber = 0;
+ // To avoid double counting of line 0 of each entry point,
+ // Don't count the lines that do not give an explicit line
+ // number.
+ routine="";
+ function="";
}
else
{
diff --git a/Source/CTest/cmParseJacocoCoverage.cxx b/Source/CTest/cmParseJacocoCoverage.cxx
new file mode 100644
index 000000000..47e3b3267
--- /dev/null
+++ b/Source/CTest/cmParseJacocoCoverage.cxx
@@ -0,0 +1,209 @@
+#include "cmStandardIncludes.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "cmSystemTools.h"
+#include "cmXMLParser.h"
+#include "cmParseJacocoCoverage.h"
+#include <cmsys/Directory.hxx>
+#include <cmsys/Glob.hxx>
+#include <cmsys/FStream.hxx>
+
+
+class cmParseJacocoCoverage::XMLParser: public cmXMLParser
+{
+ public:
+ XMLParser(cmCTest* ctest, cmCTestCoverageHandlerContainer& cont)
+ : CTest(ctest), Coverage(cont)
+ {
+ this->FilePath = "";
+ this->PackagePath = "";
+ this->PackageName = "";
+ }
+
+ virtual ~XMLParser()
+ {
+ }
+
+ protected:
+
+ virtual void EndElement(const std::string&)
+ {
+ }
+
+ virtual void StartElement(const std::string& name,
+ const char** atts)
+ {
+ if(name == "package")
+ {
+ this->PackageName = atts[1];
+ this->PackagePath = "";
+ }
+ else if(name == "sourcefile")
+ {
+ std::string fileName = atts[1];
+
+ if (this->PackagePath == "")
+ {
+ if(!this->FindPackagePath(fileName))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot find file: "
+ << this->PackageName << "/" << fileName << std::endl);
+ this->Coverage.Error++;
+ return;
+ }
+ }
+
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Reading file: " << fileName << std::endl,
+ this->Coverage.Quiet);
+
+ this->FilePath = this->PackagePath + "/" + fileName;
+ cmsys::ifstream fin(this->FilePath.c_str());
+ if (!fin)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Jacoco Coverage: Error opening " << this->FilePath
+ << std::endl);
+ }
+ std::string line;
+ FileLinesType& curFileLines =
+ this->Coverage.TotalCoverage[this->FilePath];
+ if(fin)
+ {
+ curFileLines.push_back(-1);
+ }
+ while(cmSystemTools::GetLineFromStream(fin, line))
+ {
+ curFileLines.push_back(-1);
+ }
+ }
+ else if(name == "line")
+ {
+ int tagCount = 0;
+ int nr = -1;
+ int ci = -1;
+ while(true)
+ {
+ if(strcmp(atts[tagCount],"ci") == 0)
+ {
+ ci = atoi(atts[tagCount+1]);
+ }
+ else if (strcmp(atts[tagCount],"nr") == 0)
+ {
+ nr = atoi(atts[tagCount+1]);
+ }
+ if (ci > -1 && nr > 0)
+ {
+ FileLinesType& curFileLines=
+ this->Coverage.TotalCoverage[this->FilePath];
+ if(!curFileLines.empty())
+ {
+ curFileLines[nr-1] = ci;
+ }
+ break;
+ }
+ ++tagCount;
+ }
+ }
+ }
+
+ virtual bool FindPackagePath(const std::string fileName)
+ {
+ // Search for the source file in the source directory.
+ if (this->PackagePathFound(fileName, this->Coverage.SourceDir))
+ {
+ return true;
+ }
+
+ // If not found there, check the binary directory.
+ if (this->PackagePathFound(fileName, this->Coverage.BinaryDir))
+ {
+ return true;
+ }
+ return false;
+ }
+
+ virtual bool PackagePathFound(const std::string fileName,
+ const std::string baseDir)
+ {
+ // Search for the file in the baseDir and its subdirectories.
+ std::string packageGlob = baseDir;
+ packageGlob += "/";
+ packageGlob += fileName;
+ cmsys::Glob gl;
+ gl.RecurseOn();
+ gl.RecurseThroughSymlinksOn();
+ gl.FindFiles(packageGlob);
+ std::vector<std::string> const& files = gl.GetFiles();
+ if (files.size() == 0)
+ {
+ return false;
+ }
+
+ // Check if any of the locations found match our package.
+ for(std::vector<std::string>::const_iterator fi = files.begin();
+ fi != files.end(); ++fi)
+ {
+ std::string dir = cmsys::SystemTools::GetParentDirectory(*fi);
+ if (cmsys::SystemTools::StringEndsWith(dir, this->PackageName.c_str()))
+ {
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Found package directory for " << fileName <<
+ ": " << dir << std::endl,
+ this->Coverage.Quiet);
+ this->PackagePath = dir;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private:
+ std::string FilePath;
+ std::string PackagePath;
+ std::string PackageName;
+ typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector
+ FileLinesType;
+ cmCTest* CTest;
+ cmCTestCoverageHandlerContainer& Coverage;
+};
+
+cmParseJacocoCoverage::cmParseJacocoCoverage(
+ cmCTestCoverageHandlerContainer& cont,
+ cmCTest* ctest)
+ :Coverage(cont), CTest(ctest)
+ {
+ }
+
+bool cmParseJacocoCoverage::LoadCoverageData(
+ const std::vector<std::string> files)
+{
+ // load all the jacoco.xml files in the source directory
+ cmsys::Directory dir;
+ size_t i;
+ std::string path;
+ size_t numf = files.size();
+ for (i = 0; i < numf; i++)
+ {
+ path = files[i];
+
+ cmCTestOptionalLog(this->CTest,HANDLER_VERBOSE_OUTPUT,
+ "Reading XML File " << path << std::endl, this->Coverage.Quiet);
+ if(cmSystemTools::GetFilenameLastExtension(path) == ".xml")
+ {
+ if(!this->ReadJacocoXML(path.c_str()))
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+bool cmParseJacocoCoverage::ReadJacocoXML(const char* file)
+{
+ cmParseJacocoCoverage::XMLParser
+ parser(this->CTest, this->Coverage);
+ parser.ParseFile(file);
+ return true;
+}
diff --git a/Source/CTest/cmParseJacocoCoverage.h b/Source/CTest/cmParseJacocoCoverage.h
new file mode 100644
index 000000000..dad05a32e
--- /dev/null
+++ b/Source/CTest/cmParseJacocoCoverage.h
@@ -0,0 +1,59 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmParseJacocoCoverage_h
+#define cmParseJacocoCoverage_h
+
+#include "cmStandardIncludes.h"
+#include "cmCTestCoverageHandler.h"
+
+
+/** \class cmParseJacocoCoverage
+ * \brief Parse JaCoCO coverage information
+ *
+ * This class is used to parse coverage information for
+ * java using the JaCoCo tool:
+ *
+ * http://www.eclemma.org/jacoco/trunk/index.html
+ */
+class cmParseJacocoCoverage
+{
+public:
+ cmParseJacocoCoverage(cmCTestCoverageHandlerContainer& cont,
+ cmCTest* ctest);
+ bool LoadCoverageData(const std::vector<std::string> files);
+
+ std::string PackageName;
+ std::string FileName;
+ std::string ModuleName;
+ std::string CurFileName;
+private:
+ // implement virtual from parent
+ // remove files with no coverage
+ void RemoveUnCoveredFiles();
+ // Read a single mcov file
+ bool ReadJacocoXML(const char* f);
+ // split a string based on ,
+ bool SplitString(std::vector<std::string>& args,
+ std::string const& line);
+ bool FindJavaFile(std::string const& routine,
+ std::string& filepath);
+ void InitializeJavaFile(std::string& file);
+ bool LoadSource(std::string d);
+
+ class XMLParser;
+ std::map<std::string, std::string> RoutineToDirectory;
+ cmCTestCoverageHandlerContainer& Coverage;
+ cmCTest* CTest;
+};
+
+#endif
diff --git a/Source/CTest/cmParseMumpsCoverage.cxx b/Source/CTest/cmParseMumpsCoverage.cxx
index 37e8bd082..225e704d9 100644
--- a/Source/CTest/cmParseMumpsCoverage.cxx
+++ b/Source/CTest/cmParseMumpsCoverage.cxx
@@ -5,6 +5,7 @@
#include "cmParseGTMCoverage.h"
#include <cmsys/Directory.hxx>
#include <cmsys/Glob.hxx>
+#include <cmsys/FStream.hxx>
cmParseMumpsCoverage::cmParseMumpsCoverage(
@@ -23,7 +24,7 @@ bool cmParseMumpsCoverage::ReadCoverageFile(const char* file)
// Read the gtm_coverage.mcov file, that has two lines of data:
// packages:/full/path/to/Vista/Packages
// coverage_dir:/full/path/to/dir/with/*.mcov
- std::ifstream in(file);
+ cmsys::ifstream in(file);
if(!in)
{
return false;
@@ -61,7 +62,7 @@ bool cmParseMumpsCoverage::ReadCoverageFile(const char* file)
void cmParseMumpsCoverage::InitializeMumpsFile(std::string& file)
{
// initialize the coverage information for a given mumps file
- std::ifstream in(file.c_str());
+ cmsys::ifstream in(file.c_str());
if(!in)
{
return;
@@ -95,11 +96,13 @@ void cmParseMumpsCoverage::InitializeMumpsFile(std::string& file)
}
if(found)
{
- // (2) If the first character found above is whitespace then continue the
- // search for the first following non-whitespace character.
+ // (2) If the first character found above is whitespace or a period
+ // then continue the search for the first following non-whitespace
+ // character.
if(line[i] == ' ' || line[i] == '\t')
{
- while(i < line.size() && (line[i] == ' ' || line[i] == '\t'))
+ while(i < line.size() && (line[i] == ' ' || line[i] == '\t'
+ || line[i] == '.'))
{
i++;
}
@@ -121,7 +124,7 @@ bool cmParseMumpsCoverage::LoadPackages(const char* d)
glob.RecurseOn();
std::string pat = d;
pat += "/*.m";
- glob.FindFiles(pat.c_str());
+ glob.FindFiles(pat);
std::vector<std::string>& files = glob.GetFiles();
std::vector<std::string>::iterator fileIt;
for ( fileIt = files.begin(); fileIt != files.end();
@@ -139,7 +142,7 @@ bool cmParseMumpsCoverage::LoadPackages(const char* d)
bool cmParseMumpsCoverage::FindMumpsFile(std::string const& routine,
std::string& filepath)
{
- std::map<cmStdString, cmStdString>::iterator i =
+ std::map<std::string, std::string>::iterator i =
this->RoutineToDirectory.find(routine);
if(i != this->RoutineToDirectory.end())
{
diff --git a/Source/CTest/cmParseMumpsCoverage.h b/Source/CTest/cmParseMumpsCoverage.h
index c1effa79b..bc7189168 100644
--- a/Source/CTest/cmParseMumpsCoverage.h
+++ b/Source/CTest/cmParseMumpsCoverage.h
@@ -44,7 +44,7 @@ protected:
bool FindMumpsFile(std::string const& routine,
std::string& filepath);
protected:
- std::map<cmStdString, cmStdString> RoutineToDirectory;
+ std::map<std::string, std::string> RoutineToDirectory;
cmCTestCoverageHandlerContainer& Coverage;
cmCTest* CTest;
};
diff --git a/Source/CTest/cmParsePHPCoverage.cxx b/Source/CTest/cmParsePHPCoverage.cxx
index 593b2d1a8..c7f5a684d 100644
--- a/Source/CTest/cmParsePHPCoverage.cxx
+++ b/Source/CTest/cmParsePHPCoverage.cxx
@@ -2,6 +2,7 @@
#include "cmSystemTools.h"
#include "cmParsePHPCoverage.h"
#include <cmsys/Directory.hxx>
+#include <cmsys/FStream.hxx>
/*
To setup coverage for php.
@@ -20,7 +21,7 @@ cmParsePHPCoverage::cmParsePHPCoverage(cmCTestCoverageHandlerContainer& cont,
{
}
-bool cmParsePHPCoverage::ReadUntil(std::ifstream& in, char until)
+bool cmParsePHPCoverage::ReadUntil(std::istream& in, char until)
{
char c = 0;
while(in.get(c) && c != until)
@@ -32,8 +33,8 @@ bool cmParsePHPCoverage::ReadUntil(std::ifstream& in, char until)
}
return true;
}
-bool cmParsePHPCoverage::ReadCoverageArray(std::ifstream& in,
- cmStdString const& fileName)
+bool cmParsePHPCoverage::ReadCoverageArray(std::istream& in,
+ std::string const& fileName)
{
cmCTestCoverageHandlerContainer::SingleFileCoverageVector& coverageVector
= this->Coverage.TotalCoverage[fileName];
@@ -109,7 +110,7 @@ bool cmParsePHPCoverage::ReadCoverageArray(std::ifstream& in,
return true;
}
-bool cmParsePHPCoverage::ReadInt(std::ifstream& in, int& v)
+bool cmParsePHPCoverage::ReadInt(std::istream& in, int& v)
{
std::string s;
char c = 0;
@@ -121,7 +122,7 @@ bool cmParsePHPCoverage::ReadInt(std::ifstream& in, int& v)
return true;
}
-bool cmParsePHPCoverage::ReadArraySize(std::ifstream& in, int& size)
+bool cmParsePHPCoverage::ReadArraySize(std::istream& in, int& size)
{
char c = 0;
in.get(c);
@@ -139,7 +140,7 @@ bool cmParsePHPCoverage::ReadArraySize(std::ifstream& in, int& size)
return false;
}
-bool cmParsePHPCoverage::ReadFileInformation(std::ifstream& in)
+bool cmParsePHPCoverage::ReadFileInformation(std::istream& in)
{
char buf[4];
in.read(buf, 2);
@@ -165,7 +166,7 @@ bool cmParsePHPCoverage::ReadFileInformation(std::ifstream& in)
// read the string data
in.read(s, size-1);
s[size-1] = 0;
- cmStdString fileName = s;
+ std::string fileName = s;
delete [] s;
// read close quote
if(in.get(c) && c != '"')
@@ -190,7 +191,7 @@ bool cmParsePHPCoverage::ReadFileInformation(std::ifstream& in)
bool cmParsePHPCoverage::ReadPHPData(const char* file)
{
- std::ifstream in(file);
+ cmsys::ifstream in(file);
if(!in)
{
return false;
@@ -238,7 +239,7 @@ bool cmParsePHPCoverage::ReadPHPCoverageDirectory(const char* d)
{
std::string file = dir.GetFile(i);
if(file != "." && file != ".."
- && !cmSystemTools::FileIsDirectory(file.c_str()))
+ && !cmSystemTools::FileIsDirectory(file))
{
std::string path = d;
path += "/";
diff --git a/Source/CTest/cmParsePHPCoverage.h b/Source/CTest/cmParsePHPCoverage.h
index d50a83c58..92a76347f 100644
--- a/Source/CTest/cmParsePHPCoverage.h
+++ b/Source/CTest/cmParsePHPCoverage.h
@@ -32,11 +32,11 @@ public:
void PrintCoverage();
private:
bool ReadPHPData(const char* file);
- bool ReadArraySize(std::ifstream& in, int& size);
- bool ReadFileInformation(std::ifstream& in);
- bool ReadInt(std::ifstream& in, int& v);
- bool ReadCoverageArray(std::ifstream& in, cmStdString const&);
- bool ReadUntil(std::ifstream& in, char until);
+ bool ReadArraySize(std::istream& in, int& size);
+ bool ReadFileInformation(std::istream& in);
+ bool ReadInt(std::istream& in, int& v);
+ bool ReadCoverageArray(std::istream& in, std::string const&);
+ bool ReadUntil(std::istream& in, char until);
cmCTestCoverageHandlerContainer& Coverage;
cmCTest* CTest;
};
diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx
index 167b992c9..0c25f4050 100644
--- a/Source/CTest/cmProcess.cxx
+++ b/Source/CTest/cmProcess.cxx
@@ -39,7 +39,7 @@ void cmProcess::SetCommandArguments(std::vector<std::string> const& args)
bool cmProcess::StartProcess()
{
- if(this->Command.size() == 0)
+ if(this->Command.empty())
{
return false;
}
@@ -56,12 +56,13 @@ bool cmProcess::StartProcess()
this->ProcessArgs.push_back(0); // null terminate the list
this->Process = cmsysProcess_New();
cmsysProcess_SetCommand(this->Process, &*this->ProcessArgs.begin());
- if(this->WorkingDirectory.size())
+ if(!this->WorkingDirectory.empty())
{
cmsysProcess_SetWorkingDirectory(this->Process,
this->WorkingDirectory.c_str());
}
cmsysProcess_SetTimeout(this->Process, this->Timeout);
+ cmsysProcess_SetOption(this->Process, cmsysProcess_Option_MergeOutput, 1);
cmsysProcess_Execute(this->Process);
return (cmsysProcess_GetState(this->Process)
== cmsysProcess_State_Executing);
@@ -124,14 +125,10 @@ int cmProcess::GetNextOutputLine(std::string& line, double timeout)
for(;;)
{
// Look for lines already buffered.
- if(this->StdOut.GetLine(line))
+ if(this->Output.GetLine(line))
{
return cmsysProcess_Pipe_STDOUT;
}
- else if(this->StdErr.GetLine(line))
- {
- return cmsysProcess_Pipe_STDERR;
- }
// Check for more data from the process.
char* data;
@@ -143,11 +140,7 @@ int cmProcess::GetNextOutputLine(std::string& line, double timeout)
}
else if(p == cmsysProcess_Pipe_STDOUT)
{
- this->StdOut.insert(this->StdOut.end(), data, data+length);
- }
- else if(p == cmsysProcess_Pipe_STDERR)
- {
- this->StdErr.insert(this->StdErr.end(), data, data+length);
+ this->Output.insert(this->Output.end(), data, data+length);
}
else // p == cmsysProcess_Pipe_None
{
@@ -157,14 +150,10 @@ int cmProcess::GetNextOutputLine(std::string& line, double timeout)
}
// Look for partial last lines.
- if(this->StdOut.GetLast(line))
+ if(this->Output.GetLast(line))
{
return cmsysProcess_Pipe_STDOUT;
}
- else if(this->StdErr.GetLast(line))
- {
- return cmsysProcess_Pipe_STDERR;
- }
// No more data. Wait for process exit.
if(!cmsysProcess_WaitForExit(this->Process, &timeout))
diff --git a/Source/CTest/cmProcess.h b/Source/CTest/cmProcess.h
index 1479df05f..eddeeabe8 100644
--- a/Source/CTest/cmProcess.h
+++ b/Source/CTest/cmProcess.h
@@ -48,8 +48,7 @@ public:
* Read one line of output but block for no more than timeout.
* Returns:
* cmsysProcess_Pipe_None = Process terminated and all output read
- * cmsysProcess_Pipe_STDOUT = Line came from stdout
- * cmsysProcess_Pipe_STDOUT = Line came from stderr
+ * cmsysProcess_Pipe_STDOUT = Line came from stdout or stderr
* cmsysProcess_Pipe_Timeout = Timeout expired while waiting
*/
int GetNextOutputLine(std::string& line, double timeout);
@@ -68,13 +67,11 @@ private:
bool GetLine(std::string& line);
bool GetLast(std::string& line);
};
- Buffer StdErr;
- Buffer StdOut;
+ Buffer Output;
std::string Command;
std::string WorkingDirectory;
std::vector<std::string> Arguments;
std::vector<const char*> ProcessArgs;
- std::string Output;
int Id;
int ExitValue;
};
diff --git a/Source/Checks/cm_c11_thread_local.c b/Source/Checks/cm_c11_thread_local.c
new file mode 100644
index 000000000..ab780f284
--- /dev/null
+++ b/Source/Checks/cm_c11_thread_local.c
@@ -0,0 +1,2 @@
+_Thread_local int i = 42;
+int main(void) { return 0; }
diff --git a/Source/Checks/cm_c11_thread_local.cmake b/Source/Checks/cm_c11_thread_local.cmake
new file mode 100644
index 000000000..6b8d10b2b
--- /dev/null
+++ b/Source/Checks/cm_c11_thread_local.cmake
@@ -0,0 +1,33 @@
+set(CMake_C11_THREAD_LOCAL_BROKEN 0)
+if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_C11_STANDARD_COMPILE_OPTION)
+ if(NOT DEFINED CMake_C11_THREAD_LOCAL_WORKS)
+ message(STATUS "Checking if compiler supports C11 _Thread_local")
+ try_compile(CMake_C11_THREAD_LOCAL_WORKS
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_LIST_DIR}/cm_c11_thread_local.c
+ CMAKE_FLAGS -DCMAKE_C_STANDARD=11
+ OUTPUT_VARIABLE OUTPUT
+ )
+ if(CMake_C11_THREAD_LOCAL_WORKS AND "${OUTPUT}" MATCHES "error: expected '=', ',', ';', 'asm' or '__attribute__' before 'int'")
+ set_property(CACHE CMake_C11_THREAD_LOCAL_WORKS PROPERTY VALUE 0)
+ endif()
+ if(CMake_C11_THREAD_LOCAL_WORKS)
+ message(STATUS "Checking if compiler supports C11 _Thread_local - yes")
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Determining if compiler supports C11 _Thread_local passed with the following output:\n"
+ "${OUTPUT}\n"
+ "\n"
+ )
+ else()
+ message(STATUS "Checking if compiler supports C11 _Thread_local - no")
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Determining if compiler supports C11 _Thread_local failed with the following output:\n"
+ "${OUTPUT}\n"
+ "\n"
+ )
+ endif()
+ endif()
+ if(NOT CMake_C11_THREAD_LOCAL_WORKS)
+ set(CMake_C11_THREAD_LOCAL_BROKEN 1)
+ endif()
+endif()
diff --git a/Source/Checks/cm_cxx11_unordered_map.cmake b/Source/Checks/cm_cxx11_unordered_map.cmake
new file mode 100644
index 000000000..80fe391bc
--- /dev/null
+++ b/Source/Checks/cm_cxx11_unordered_map.cmake
@@ -0,0 +1,25 @@
+
+if(CMAKE_CXX_STANDARD AND NOT DEFINED CMake_HAVE_CXX11_UNORDERED_MAP)
+ message(STATUS "Checking if compiler supports C++11 unordered_map")
+ try_compile(CMake_HAVE_CXX11_UNORDERED_MAP
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_LIST_DIR}/cm_cxx11_unordered_map.cpp
+ CMAKE_FLAGS -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}
+ OUTPUT_VARIABLE OUTPUT
+ )
+ if(CMake_HAVE_CXX11_UNORDERED_MAP)
+ message(STATUS "Checking if compiler supports C++11 unordered_map - yes")
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Determining if compiler supports C++11 unordered_map passed with the following output:\n"
+ "${OUTPUT}\n"
+ "\n"
+ )
+ else()
+ message(STATUS "Checking if compiler supports C++11 unordered_map - no")
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Determining if compiler supports C++11 unordered_map failed with the following output:\n"
+ "${OUTPUT}\n"
+ "\n"
+ )
+ endif()
+endif()
diff --git a/Source/Checks/cm_cxx11_unordered_map.cpp b/Source/Checks/cm_cxx11_unordered_map.cpp
new file mode 100644
index 000000000..beeb31b23
--- /dev/null
+++ b/Source/Checks/cm_cxx11_unordered_map.cpp
@@ -0,0 +1,6 @@
+#include <unordered_map>
+int main() {
+ std::unordered_map<int, int> map;
+ map[0] = 0;
+ return 0;
+}
diff --git a/Source/Checks/cm_cxx14_cstdio.cmake b/Source/Checks/cm_cxx14_cstdio.cmake
new file mode 100644
index 000000000..73f7e2ed5
--- /dev/null
+++ b/Source/Checks/cm_cxx14_cstdio.cmake
@@ -0,0 +1,33 @@
+set(CMake_CXX14_CSTDIO_BROKEN 0)
+if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang" AND CMAKE_CXX14_STANDARD_COMPILE_OPTION)
+ if(NOT DEFINED CMake_CXX14_CSTDIO_WORKS)
+ message(STATUS "Checking if compiler supports C++14 cstdio")
+ try_compile(CMake_CXX14_CSTDIO_WORKS
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_LIST_DIR}/cm_cxx14_cstdio.cpp
+ CMAKE_FLAGS -DCMAKE_CXX_STANDARD=14
+ OUTPUT_VARIABLE OUTPUT
+ )
+ if(CMake_CXX14_CSTDIO_WORKS AND "${OUTPUT}" MATCHES "error: no member named.*gets.*in the global namespace")
+ set_property(CACHE CMake_CXX14_CSTDIO_WORKS PROPERTY VALUE 0)
+ endif()
+ if(CMake_CXX14_CSTDIO_WORKS)
+ message(STATUS "Checking if compiler supports C++14 cstdio - yes")
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Determining if compiler supports C++14 cstdio passed with the following output:\n"
+ "${OUTPUT}\n"
+ "\n"
+ )
+ else()
+ message(STATUS "Checking if compiler supports C++14 cstdio - no")
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Determining if compiler supports C++14 cstdio failed with the following output:\n"
+ "${OUTPUT}\n"
+ "\n"
+ )
+ endif()
+ endif()
+ if(NOT CMake_CXX14_CSTDIO_WORKS)
+ set(CMake_CXX14_CSTDIO_BROKEN 1)
+ endif()
+endif()
diff --git a/Source/Checks/cm_cxx14_cstdio.cpp b/Source/Checks/cm_cxx14_cstdio.cpp
new file mode 100644
index 000000000..3a6a699dc
--- /dev/null
+++ b/Source/Checks/cm_cxx14_cstdio.cpp
@@ -0,0 +1,2 @@
+#include <cstdio>
+int main() { return 0; }
diff --git a/Source/CursesDialog/CMakeLists.txt b/Source/CursesDialog/CMakeLists.txt
index 5efc2fb1a..93ff4256e 100644
--- a/Source/CursesDialog/CMakeLists.txt
+++ b/Source/CursesDialog/CMakeLists.txt
@@ -11,6 +11,7 @@
#=============================================================================
set( CURSES_SRCS
+ CursesDialog/cmCursesOptionsWidget
CursesDialog/cmCursesBoolWidget
CursesDialog/cmCursesCacheEntryComposite
CursesDialog/cmCursesDummyWidget
@@ -25,13 +26,26 @@ set( CURSES_SRCS
CursesDialog/ccmake
)
-include_directories(${CMake_SOURCE_DIR}/Source/CursesDialog/form
- ${CMake_BINARY_DIR}/Source/CursesDialog/form)
+if( NOT CMAKE_USE_SYSTEM_FORM )
+ include_directories(${CMake_SOURCE_DIR}/Source/CursesDialog/form
+ ${CMake_BINARY_DIR}/Source/CursesDialog/form)
+endif()
include_directories(${CURSES_INCLUDE_PATH})
add_executable(ccmake ${CURSES_SRCS} )
target_link_libraries(ccmake CMakeLib)
-target_link_libraries(ccmake cmForm)
+if(CMAKE_USE_SYSTEM_FORM)
+ target_link_libraries(ccmake
+ ${CURSES_FORM_LIBRARY}
+ ${CURSES_LIBRARY}
+ )
+ if(CURSES_EXTRA_LIBRARY)
+ target_link_libraries(ccmake ${CURSES_EXTRA_LIBRARY})
+ endif()
+else()
+ target_link_libraries(ccmake cmForm)
+endif()
-install(TARGETS ccmake DESTINATION bin)
+CMake_OPTIONAL_COMPONENT(ccmake)
+install(TARGETS ccmake DESTINATION bin ${COMPONENT})
diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx
index 623d7d3a5..5236e57d5 100644
--- a/Source/CursesDialog/ccmake.cxx
+++ b/Source/CursesDialog/ccmake.cxx
@@ -9,7 +9,6 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#include "../cmCacheManager.h"
#include "../cmSystemTools.h"
#include "../cmake.h"
#include "../cmDocumentation.h"
@@ -19,51 +18,44 @@
#include "cmCursesMainForm.h"
#include "cmCursesStandardIncludes.h"
+#include <cmsys/Encoding.hxx>
#include <form.h>
//----------------------------------------------------------------------------
-static const char * cmDocumentationName[][3] =
+static const char * cmDocumentationName[][2] =
{
{0,
- " ccmake - Curses Interface for CMake.", 0},
- {0,0,0}
+ " ccmake - Curses Interface for CMake."},
+ {0,0}
};
//----------------------------------------------------------------------------
-static const char * cmDocumentationUsage[][3] =
+static const char * cmDocumentationUsage[][2] =
{
{0,
" ccmake <path-to-source>\n"
- " ccmake <path-to-existing-build>", 0},
- {0,0,0}
+ " ccmake <path-to-existing-build>"},
+ {0,
+ "Specify a source directory to (re-)generate a build system for "
+ "it in the current working directory. Specify an existing build "
+ "directory to re-generate its build system."},
+ {0,0}
};
//----------------------------------------------------------------------------
-static const char * cmDocumentationDescription[][3] =
+static const char * cmDocumentationUsageNote[][2] =
{
{0,
- "The \"ccmake\" executable is the CMake curses interface. Project "
- "configuration settings may be specified interactively through "
- "this GUI. Brief instructions are provided at the bottom of the "
- "terminal when the program is running.", 0},
- CMAKE_STANDARD_INTRODUCTION,
- {0,0,0}
+ "Run 'ccmake --help' for more information."},
+ {0,0}
};
//----------------------------------------------------------------------------
-static const char * cmDocumentationOptions[][3] =
+static const char * cmDocumentationOptions[][2] =
{
CMAKE_STANDARD_OPTIONS_TABLE,
- {0,0,0}
-};
-
-//----------------------------------------------------------------------------
-static const char * cmDocumentationSeeAlso[][3] =
-{
- {0, "cmake", 0},
- {0, "ctest", 0},
- {0, 0, 0}
+ {0,0}
};
cmCursesForm* cmCursesForm::CurrentForm=0;
@@ -92,35 +84,40 @@ void onsig(int)
}
-void CMakeErrorHandler(const char* message, const char* title, bool&, void* clientData)
+void CMakeMessageHandler(const char* message, const char* title, bool&,
+ void* clientData)
{
cmCursesForm* self = static_cast<cmCursesForm*>( clientData );
self->AddError(message, title);
}
-int main(int argc, char** argv)
+int main(int argc, char const* const* argv)
{
- cmSystemTools::FindExecutableDirectory(argv[0]);
+ cmsys::Encoding::CommandLineArguments encoding_args =
+ cmsys::Encoding::CommandLineArguments::Main(argc, argv);
+ argc = encoding_args.argc();
+ argv = encoding_args.argv();
+
+ cmSystemTools::FindCMakeResources(argv[0]);
cmDocumentation doc;
doc.addCMakeStandardDocSections();
if(doc.CheckOptions(argc, argv))
{
cmake hcm;
- std::vector<cmDocumentationEntry> commands;
- std::vector<cmDocumentationEntry> compatCommands;
+ hcm.SetHomeDirectory("");
+ hcm.SetHomeOutputDirectory("");
+ hcm.AddCMakePaths();
std::vector<cmDocumentationEntry> generators;
- hcm.GetCommandDocumentation(commands, true, false);
- hcm.GetCommandDocumentation(compatCommands, false, true);
hcm.GetGeneratorDocumentation(generators);
doc.SetName("ccmake");
doc.SetSection("Name",cmDocumentationName);
doc.SetSection("Usage",cmDocumentationUsage);
- doc.SetSection("Description",cmDocumentationDescription);
+ if ( argc == 1 )
+ {
+ doc.AppendSection("Usage",cmDocumentationUsageNote);
+ }
doc.SetSection("Generators",generators);
doc.PrependSection("Options",cmDocumentationOptions);
- doc.SetSection("Command",commands);
- doc.SetSection("Compatibility Commands",compatCommands);
- doc.SetSeeAlsoList(cmDocumentationSeeAlso);
return doc.PrintRequestedDocumentation(std::cout)? 0:1;
}
@@ -192,7 +189,7 @@ int main(int argc, char** argv)
return 1;
}
- cmSystemTools::SetErrorCallback(CMakeErrorHandler, myform);
+ cmSystemTools::SetMessageCallback(CMakeMessageHandler, myform);
cmCursesForm::CurrentForm = myform;
diff --git a/Source/CursesDialog/cmCursesBoolWidget.cxx b/Source/CursesDialog/cmCursesBoolWidget.cxx
index fd15b9944..29d9cb23b 100644
--- a/Source/CursesDialog/cmCursesBoolWidget.cxx
+++ b/Source/CursesDialog/cmCursesBoolWidget.cxx
@@ -16,7 +16,7 @@ cmCursesBoolWidget::cmCursesBoolWidget(int width, int height,
int left, int top) :
cmCursesWidget(width, height, left, top)
{
- this->Type = cmCacheManager::BOOL;
+ this->Type = cmState::BOOL;
set_field_fore(this->Field, A_NORMAL);
set_field_back(this->Field, A_STANDOUT);
field_opts_off(this->Field, O_STATIC);
diff --git a/Source/CursesDialog/cmCursesBoolWidget.h b/Source/CursesDialog/cmCursesBoolWidget.h
index d2a25ca12..8a57c73da 100644
--- a/Source/CursesDialog/cmCursesBoolWidget.h
+++ b/Source/CursesDialog/cmCursesBoolWidget.h
@@ -9,8 +9,8 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#ifndef __cmCursesBoolWidget_h
-#define __cmCursesBoolWidget_h
+#ifndef cmCursesBoolWidget_h
+#define cmCursesBoolWidget_h
#include "cmCursesWidget.h"
class cmCursesMainForm;
@@ -37,4 +37,4 @@ protected:
};
-#endif // __cmCursesBoolWidget_h
+#endif // cmCursesBoolWidget_h
diff --git a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
index c58d037f0..7e0924212 100644
--- a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
+++ b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
@@ -10,6 +10,7 @@
See the License for more information.
============================================================================*/
#include "cmCursesCacheEntryComposite.h"
+#include "cmCursesOptionsWidget.h"
#include "cmCursesStringWidget.h"
#include "cmCursesLabelWidget.h"
#include "cmCursesBoolWidget.h"
@@ -17,10 +18,15 @@
#include "cmCursesFilePathWidget.h"
#include "cmCursesDummyWidget.h"
#include "../cmSystemTools.h"
+#include "../cmake.h"
+#include "../cmState.h"
-cmCursesCacheEntryComposite::cmCursesCacheEntryComposite(const char* key,
- int labelwidth,
- int entrywidth) :
+#include <assert.h>
+
+cmCursesCacheEntryComposite::cmCursesCacheEntryComposite(
+ const std::string& key,
+ int labelwidth,
+ int entrywidth) :
Key(key), LabelWidth(labelwidth), EntryWidth(entrywidth)
{
this->Label = new cmCursesLabelWidget(this->LabelWidth, 1, 1, 1, key);
@@ -30,7 +36,7 @@ cmCursesCacheEntryComposite::cmCursesCacheEntryComposite(const char* key,
}
cmCursesCacheEntryComposite::cmCursesCacheEntryComposite(
- const char* key, const cmCacheManager::CacheIterator& it, bool isNew,
+ const std::string& key, cmake *cm, bool isNew,
int labelwidth, int entrywidth)
: Key(key), LabelWidth(labelwidth), EntryWidth(entrywidth)
{
@@ -45,11 +51,13 @@ cmCursesCacheEntryComposite::cmCursesCacheEntryComposite(
}
this->Entry = 0;
- switch ( it.GetType() )
+ const char* value = cm->GetState()->GetCacheEntryValue(key);
+ assert(value);
+ switch (cm->GetState()->GetCacheEntryType(key))
{
- case cmCacheManager::BOOL:
+ case cmState::BOOL:
this->Entry = new cmCursesBoolWidget(this->EntryWidth, 1, 1, 1);
- if (cmSystemTools::IsOn(it.GetValue()))
+ if (cmSystemTools::IsOn(value))
{
static_cast<cmCursesBoolWidget*>(this->Entry)->SetValueAsBool(true);
}
@@ -58,23 +66,42 @@ cmCursesCacheEntryComposite::cmCursesCacheEntryComposite(
static_cast<cmCursesBoolWidget*>(this->Entry)->SetValueAsBool(false);
}
break;
- case cmCacheManager::PATH:
+ case cmState::PATH:
this->Entry = new cmCursesPathWidget(this->EntryWidth, 1, 1, 1);
- static_cast<cmCursesPathWidget*>(this->Entry)->SetString(
- it.GetValue());
+ static_cast<cmCursesPathWidget*>(this->Entry)->SetString(value);
break;
- case cmCacheManager::FILEPATH:
+ case cmState::FILEPATH:
this->Entry = new cmCursesFilePathWidget(this->EntryWidth, 1, 1, 1);
- static_cast<cmCursesFilePathWidget*>(this->Entry)->SetString(
- it.GetValue());
+ static_cast<cmCursesFilePathWidget*>(this->Entry)->SetString(value);
break;
- case cmCacheManager::STRING:
- this->Entry = new cmCursesStringWidget(this->EntryWidth, 1, 1, 1);
- static_cast<cmCursesStringWidget*>(this->Entry)->SetString(
- it.GetValue());
+ case cmState::STRING:
+ {
+ const char* stringsProp = cm->GetState()
+ ->GetCacheEntryProperty(key, "STRINGS");
+ if(stringsProp)
+ {
+ cmCursesOptionsWidget* ow =
+ new cmCursesOptionsWidget(this->EntryWidth, 1, 1, 1);
+ this->Entry = ow;
+ std::vector<std::string> options;
+ cmSystemTools::ExpandListArgument(stringsProp, options);
+ for(std::vector<std::string>::iterator
+ si = options.begin(); si != options.end(); ++si)
+ {
+ ow->AddOption(*si);
+ }
+ ow->SetOption(value);
+ }
+ else
+ {
+ this->Entry = new cmCursesStringWidget(this->EntryWidth, 1, 1, 1);
+ static_cast<cmCursesStringWidget*>(this->Entry)->SetString(value);
+ }
break;
- case cmCacheManager::UNINITIALIZED:
- cmSystemTools::Error("Found an undefined variable: ", it.GetName());
+ }
+ case cmState::UNINITIALIZED:
+ cmSystemTools::Error("Found an undefined variable: ",
+ key.c_str());
break;
default:
// TODO : put warning message here
diff --git a/Source/CursesDialog/cmCursesCacheEntryComposite.h b/Source/CursesDialog/cmCursesCacheEntryComposite.h
index 1357a02ec..f28089742 100644
--- a/Source/CursesDialog/cmCursesCacheEntryComposite.h
+++ b/Source/CursesDialog/cmCursesCacheEntryComposite.h
@@ -9,18 +9,18 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#ifndef __cmCursesCacheEntryComposite_h
-#define __cmCursesCacheEntryComposite_h
+#ifndef cmCursesCacheEntryComposite_h
+#define cmCursesCacheEntryComposite_h
-#include "../cmCacheManager.h"
#include "cmCursesLabelWidget.h"
class cmCursesCacheEntryComposite
{
public:
- cmCursesCacheEntryComposite(const char* key, int labelwidth, int entrywidth);
- cmCursesCacheEntryComposite(const char* key,
- const cmCacheManager::CacheIterator& it,
+ cmCursesCacheEntryComposite(const std::string& key, int labelwidth,
+ int entrywidth);
+ cmCursesCacheEntryComposite(const std::string& key,
+ cmake *cm,
bool isNew, int labelwidth, int entrywidth);
~cmCursesCacheEntryComposite();
const char* GetValue();
@@ -39,4 +39,4 @@ protected:
int EntryWidth;
};
-#endif // __cmCursesCacheEntryComposite_h
+#endif // cmCursesCacheEntryComposite_h
diff --git a/Source/CursesDialog/cmCursesDummyWidget.cxx b/Source/CursesDialog/cmCursesDummyWidget.cxx
index 60086a51b..9801e4d58 100644
--- a/Source/CursesDialog/cmCursesDummyWidget.cxx
+++ b/Source/CursesDialog/cmCursesDummyWidget.cxx
@@ -15,7 +15,7 @@ cmCursesDummyWidget::cmCursesDummyWidget(int width, int height,
int left, int top) :
cmCursesWidget(width, height, left, top)
{
- this->Type = cmCacheManager::INTERNAL;
+ this->Type = cmState::INTERNAL;
}
diff --git a/Source/CursesDialog/cmCursesDummyWidget.h b/Source/CursesDialog/cmCursesDummyWidget.h
index 9ac13652d..2b3b9b5f3 100644
--- a/Source/CursesDialog/cmCursesDummyWidget.h
+++ b/Source/CursesDialog/cmCursesDummyWidget.h
@@ -9,8 +9,8 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#ifndef __cmCursesDummyWidget_h
-#define __cmCursesDummyWidget_h
+#ifndef cmCursesDummyWidget_h
+#define cmCursesDummyWidget_h
#include "cmCursesWidget.h"
@@ -33,4 +33,4 @@ protected:
};
-#endif // __cmCursesDummyWidget_h
+#endif // cmCursesDummyWidget_h
diff --git a/Source/CursesDialog/cmCursesFilePathWidget.cxx b/Source/CursesDialog/cmCursesFilePathWidget.cxx
index 01db014bb..51ed67087 100644
--- a/Source/CursesDialog/cmCursesFilePathWidget.cxx
+++ b/Source/CursesDialog/cmCursesFilePathWidget.cxx
@@ -15,6 +15,6 @@ cmCursesFilePathWidget::cmCursesFilePathWidget(int width, int height,
int left, int top) :
cmCursesPathWidget(width, height, left, top)
{
- this->Type = cmCacheManager::FILEPATH;
+ this->Type = cmState::FILEPATH;
}
diff --git a/Source/CursesDialog/cmCursesFilePathWidget.h b/Source/CursesDialog/cmCursesFilePathWidget.h
index 9d2972ee7..6c50dd41a 100644
--- a/Source/CursesDialog/cmCursesFilePathWidget.h
+++ b/Source/CursesDialog/cmCursesFilePathWidget.h
@@ -9,8 +9,8 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#ifndef __cmCursesFilePathWidget_h
-#define __cmCursesFilePathWidget_h
+#ifndef cmCursesFilePathWidget_h
+#define cmCursesFilePathWidget_h
#include "cmCursesPathWidget.h"
@@ -25,4 +25,4 @@ protected:
};
-#endif // __cmCursesFilePathWidget_h
+#endif // cmCursesFilePathWidget_h
diff --git a/Source/CursesDialog/cmCursesForm.cxx b/Source/CursesDialog/cmCursesForm.cxx
index 72ae5eef7..d1b470c31 100644
--- a/Source/CursesDialog/cmCursesForm.cxx
+++ b/Source/CursesDialog/cmCursesForm.cxx
@@ -11,7 +11,7 @@
============================================================================*/
#include "cmCursesForm.h"
-std::ofstream cmCursesForm::DebugFile;
+cmsys::ofstream cmCursesForm::DebugFile;
bool cmCursesForm::Debug = false;
cmCursesForm::cmCursesForm()
diff --git a/Source/CursesDialog/cmCursesForm.h b/Source/CursesDialog/cmCursesForm.h
index 3cba856ab..9837f5aa3 100644
--- a/Source/CursesDialog/cmCursesForm.h
+++ b/Source/CursesDialog/cmCursesForm.h
@@ -9,11 +9,12 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#ifndef __cmCursesForm_h
-#define __cmCursesForm_h
+#ifndef cmCursesForm_h
+#define cmCursesForm_h
#include "../cmStandardIncludes.h"
#include "cmCursesStandardIncludes.h"
+#include <cmsys/FStream.hxx>
class cmCursesForm
{
@@ -63,7 +64,7 @@ public:
protected:
- static std::ofstream DebugFile;
+ static cmsys::ofstream DebugFile;
static bool Debug;
cmCursesForm(const cmCursesForm& form);
@@ -72,4 +73,4 @@ protected:
FORM* Form;
};
-#endif // __cmCursesForm_h
+#endif // cmCursesForm_h
diff --git a/Source/CursesDialog/cmCursesLabelWidget.cxx b/Source/CursesDialog/cmCursesLabelWidget.cxx
index b5ed3128c..b50eb644d 100644
--- a/Source/CursesDialog/cmCursesLabelWidget.cxx
+++ b/Source/CursesDialog/cmCursesLabelWidget.cxx
@@ -19,7 +19,7 @@ cmCursesLabelWidget::cmCursesLabelWidget(int width, int height,
field_opts_off(this->Field, O_EDIT);
field_opts_off(this->Field, O_ACTIVE);
field_opts_off(this->Field, O_STATIC);
- this->SetValue(name.c_str());
+ this->SetValue(name);
}
cmCursesLabelWidget::~cmCursesLabelWidget()
diff --git a/Source/CursesDialog/cmCursesLabelWidget.h b/Source/CursesDialog/cmCursesLabelWidget.h
index cc32d11ea..98170f581 100644
--- a/Source/CursesDialog/cmCursesLabelWidget.h
+++ b/Source/CursesDialog/cmCursesLabelWidget.h
@@ -9,8 +9,8 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#ifndef __cmCursesLabelWidget_h
-#define __cmCursesLabelWidget_h
+#ifndef cmCursesLabelWidget_h
+#define cmCursesLabelWidget_h
#include "cmCursesWidget.h"
#include "cmCursesStandardIncludes.h"
@@ -35,4 +35,4 @@ protected:
void operator=(const cmCursesLabelWidget&);
};
-#endif // __cmCursesLabelWidget_h
+#endif // cmCursesLabelWidget_h
diff --git a/Source/CursesDialog/cmCursesLongMessageForm.cxx b/Source/CursesDialog/cmCursesLongMessageForm.cxx
index 057f8f3d8..6144ddc2b 100644
--- a/Source/CursesDialog/cmCursesLongMessageForm.cxx
+++ b/Source/CursesDialog/cmCursesLongMessageForm.cxx
@@ -9,7 +9,6 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#include "../cmCacheManager.h"
#include "../cmSystemTools.h"
#include "../cmake.h"
#include "../cmVersion.h"
@@ -81,12 +80,13 @@ void cmCursesLongMessageForm::UpdateStatusBar()
sprintf(version+sideSpace, "%s", vertmp);
version[width] = '\0';
+ char fmt_s[] = "%s";
curses_move(y-4,0);
attron(A_STANDOUT);
- printw(bar);
+ printw(fmt_s, bar);
attroff(A_STANDOUT);
curses_move(y-3,0);
- printw(version);
+ printw(fmt_s, version);
pos_form_cursor(this->Form);
}
@@ -102,8 +102,9 @@ void cmCursesLongMessageForm::PrintKeys()
char firstLine[512];
sprintf(firstLine, "Press [e] to exit help");
+ char fmt_s[] = "%s";
curses_move(y-2,0);
- printw(firstLine);
+ printw(fmt_s, firstLine);
pos_form_cursor(this->Form);
}
diff --git a/Source/CursesDialog/cmCursesLongMessageForm.h b/Source/CursesDialog/cmCursesLongMessageForm.h
index 1e86974f2..6e37eeade 100644
--- a/Source/CursesDialog/cmCursesLongMessageForm.h
+++ b/Source/CursesDialog/cmCursesLongMessageForm.h
@@ -9,8 +9,8 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#ifndef __cmCursesLongMessageForm_h
-#define __cmCursesLongMessageForm_h
+#ifndef cmCursesLongMessageForm_h
+#define cmCursesLongMessageForm_h
#include "../cmStandardIncludes.h"
#include "cmCursesForm.h"
@@ -55,4 +55,4 @@ protected:
};
-#endif // __cmCursesLongMessageForm_h
+#endif // cmCursesLongMessageForm_h
diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx
index 4fee0bbd3..a2fc2c0ca 100644
--- a/Source/CursesDialog/cmCursesMainForm.cxx
+++ b/Source/CursesDialog/cmCursesMainForm.cxx
@@ -9,7 +9,6 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#include "../cmCacheManager.h"
#include "../cmSystemTools.h"
#include "../cmVersion.h"
#include "../cmake.h"
@@ -22,6 +21,8 @@
#include "cmCursesDummyWidget.h"
#include "cmCursesCacheEntryComposite.h"
#include "cmCursesLongMessageForm.h"
+#include "cmAlgorithms.h"
+#include "cmState.h"
inline int ctrl(int z)
@@ -43,14 +44,14 @@ cmCursesMainForm::cmCursesMainForm(std::vector<std::string> const& args,
this->HelpMessage.push_back("");
this->HelpMessage.push_back(s_ConstHelpMessage);
this->CMakeInstance = new cmake;
- this->CMakeInstance->SetCMakeEditCommand("ccmake");
+ this->CMakeInstance->SetCMakeEditCommand(
+ cmSystemTools::GetCMakeCursesCommand());
// create the arguments for the cmake object
- std::string whereCMake = cmSystemTools::GetProgramPath(this->Args[0].c_str());
+ std::string whereCMake = cmSystemTools::GetProgramPath(this->Args[0]);
whereCMake += "/cmake";
this->Args[0] = whereCMake;
this->CMakeInstance->SetArgs(this->Args);
- this->CMakeInstance->SetCMakeCommand(whereCMake.c_str());
this->SearchString = "";
this->OldSearchString = "";
this->SearchMode = false;
@@ -69,11 +70,7 @@ cmCursesMainForm::~cmCursesMainForm()
// Clean-up composites
if (this->Entries)
{
- std::vector<cmCursesCacheEntryComposite*>::iterator it;
- for (it = this->Entries->begin(); it != this->Entries->end(); ++it)
- {
- delete *it;
- }
+ cmDeleteAll(*this->Entries);
}
delete this->Entries;
if (this->CMakeInstance)
@@ -84,9 +81,9 @@ cmCursesMainForm::~cmCursesMainForm()
}
// See if a cache entry is in the list of entries in the ui.
-bool cmCursesMainForm::LookForCacheEntry(const char* key)
+bool cmCursesMainForm::LookForCacheEntry(const std::string& key)
{
- if (!key || !this->Entries)
+ if (!this->Entries)
{
return false;
}
@@ -94,7 +91,7 @@ bool cmCursesMainForm::LookForCacheEntry(const char* key)
std::vector<cmCursesCacheEntryComposite*>::iterator it;
for (it = this->Entries->begin(); it != this->Entries->end(); ++it)
{
- if (!strcmp(key, (*it)->Key.c_str()))
+ if (key == (*it)->Key)
{
return true;
}
@@ -110,17 +107,21 @@ void cmCursesMainForm::InitializeUI()
// which contain labels, entries and new entry markers
std::vector<cmCursesCacheEntryComposite*>* newEntries =
new std::vector<cmCursesCacheEntryComposite*>;
- newEntries->reserve(this->CMakeInstance->GetCacheManager()->GetSize());
+ std::vector<std::string> cacheKeys =
+ this->CMakeInstance->GetState()->GetCacheEntryKeys();
+ newEntries->reserve(cacheKeys.size());
// Count non-internal and non-static entries
int count=0;
- for(cmCacheManager::CacheIterator i =
- this->CMakeInstance->GetCacheManager()->NewIterator();
- !i.IsAtEnd(); i.Next())
+
+ for(std::vector<std::string>::const_iterator it = cacheKeys.begin();
+ it != cacheKeys.end(); ++it)
{
- if ( i.GetType() != cmCacheManager::INTERNAL &&
- i.GetType() != cmCacheManager::STATIC &&
- i.GetType() != cmCacheManager::UNINITIALIZED)
+ cmState::CacheEntryType t = this->CMakeInstance->GetState()
+ ->GetCacheEntryType(*it);
+ if (t != cmState::INTERNAL &&
+ t != cmState::STATIC &&
+ t != cmState::UNINITIALIZED)
{
++count;
}
@@ -142,45 +143,49 @@ void cmCursesMainForm::InitializeUI()
// Create the composites.
// First add entries which are new
- for(cmCacheManager::CacheIterator i =
- this->CMakeInstance->GetCacheManager()->NewIterator();
- !i.IsAtEnd(); i.Next())
+ for(std::vector<std::string>::const_iterator it = cacheKeys.begin();
+ it != cacheKeys.end(); ++it)
{
- const char* key = i.GetName();
- if ( i.GetType() == cmCacheManager::INTERNAL ||
- i.GetType() == cmCacheManager::STATIC ||
- i.GetType() == cmCacheManager::UNINITIALIZED )
+ std::string key = *it;
+ cmState::CacheEntryType t = this->CMakeInstance->GetState()
+ ->GetCacheEntryType(*it);
+ if (t == cmState::INTERNAL ||
+ t == cmState::STATIC ||
+ t == cmState::UNINITIALIZED )
{
continue;
}
if (!this->LookForCacheEntry(key))
{
- newEntries->push_back(new cmCursesCacheEntryComposite(key, i,
- true, 30,
- entrywidth));
+ newEntries->push_back(new cmCursesCacheEntryComposite(key,
+ this->CMakeInstance,
+ true, 30,
+ entrywidth));
this->OkToGenerate = false;
}
}
// then add entries which are old
- for(cmCacheManager::CacheIterator i =
- this->CMakeInstance->GetCacheManager()->NewIterator();
- !i.IsAtEnd(); i.Next())
+ for(std::vector<std::string>::const_iterator it = cacheKeys.begin();
+ it != cacheKeys.end(); ++it)
{
- const char* key = i.GetName();
- if ( i.GetType() == cmCacheManager::INTERNAL ||
- i.GetType() == cmCacheManager::STATIC ||
- i.GetType() == cmCacheManager::UNINITIALIZED )
+ std::string key = *it;
+ cmState::CacheEntryType t = this->CMakeInstance->GetState()
+ ->GetCacheEntryType(*it);
+ if (t == cmState::INTERNAL ||
+ t == cmState::STATIC ||
+ t == cmState::UNINITIALIZED )
{
continue;
}
if (this->LookForCacheEntry(key))
{
- newEntries->push_back(new cmCursesCacheEntryComposite(key, i,
- false, 30,
- entrywidth));
+ newEntries->push_back(new cmCursesCacheEntryComposite(key,
+ this->CMakeInstance,
+ false, 30,
+ entrywidth));
}
}
}
@@ -188,12 +193,7 @@ void cmCursesMainForm::InitializeUI()
// Clean old entries
if (this->Entries)
{
- // Have to call delete on each pointer
- std::vector<cmCursesCacheEntryComposite*>::iterator it;
- for (it = this->Entries->begin(); it != this->Entries->end(); ++it)
- {
- delete *it;
- }
+ cmDeleteAll(*this->Entries);
}
delete this->Entries;
this->Entries = newEntries;
@@ -224,10 +224,13 @@ void cmCursesMainForm::RePost()
std::vector<cmCursesCacheEntryComposite*>::iterator it;
for (it = this->Entries->begin(); it != this->Entries->end(); ++it)
{
- cmCacheManager::CacheIterator mit =
- this->CMakeInstance->GetCacheManager()->GetCacheIterator((*it)->GetValue());
- if (mit.IsAtEnd() ||
- (!this->AdvancedMode && mit.GetPropertyAsBool("ADVANCED")))
+ const char* existingValue =
+ this->CMakeInstance->GetState()
+ ->GetCacheEntryValue((*it)->GetValue());
+ bool advanced =
+ this->CMakeInstance->GetState()
+ ->GetCacheEntryPropertyAsBool((*it)->GetValue(), "ADVANCED");
+ if (!existingValue || (!this->AdvancedMode && advanced))
{
continue;
}
@@ -253,10 +256,13 @@ void cmCursesMainForm::RePost()
std::vector<cmCursesCacheEntryComposite*>::iterator it;
for (it = this->Entries->begin(); it != this->Entries->end(); ++it)
{
- cmCacheManager::CacheIterator mit =
- this->CMakeInstance->GetCacheManager()->GetCacheIterator((*it)->GetValue());
- if (mit.IsAtEnd() ||
- (!this->AdvancedMode && mit.GetPropertyAsBool("ADVANCED")))
+ const char* existingValue =
+ this->CMakeInstance->GetState()
+ ->GetCacheEntryValue((*it)->GetValue());
+ bool advanced =
+ this->CMakeInstance->GetState()
+ ->GetCacheEntryPropertyAsBool((*it)->GetValue(), "ADVANCED");
+ if (!existingValue || (!this->AdvancedMode && advanced))
{
continue;
}
@@ -287,9 +293,9 @@ void cmCursesMainForm::Render(int left, int top, int width, int height)
cmCursesWidget* cw = reinterpret_cast<cmCursesWidget*>
(field_userptr(currentField));
// If in edit mode, get out of it
- if ( cw->GetType() == cmCacheManager::STRING ||
- cw->GetType() == cmCacheManager::PATH ||
- cw->GetType() == cmCacheManager::FILEPATH )
+ if ( cw->GetType() == cmState::STRING ||
+ cw->GetType() == cmState::PATH ||
+ cw->GetType() == cmState::FILEPATH )
{
cmCursesStringWidget* sw = static_cast<cmCursesStringWidget*>(cw);
sw->SetInEdit(false);
@@ -322,10 +328,13 @@ void cmCursesMainForm::Render(int left, int top, int width, int height)
std::vector<cmCursesCacheEntryComposite*>::iterator it;
for (it = this->Entries->begin(); it != this->Entries->end(); ++it)
{
- cmCacheManager::CacheIterator mit =
- this->CMakeInstance->GetCacheManager()->GetCacheIterator((*it)->GetValue());
- if (mit.IsAtEnd() ||
- (!this->AdvancedMode && mit.GetPropertyAsBool("ADVANCED")))
+ const char* existingValue =
+ this->CMakeInstance->GetState()
+ ->GetCacheEntryValue((*it)->GetValue());
+ bool advanced =
+ this->CMakeInstance->GetState()
+ ->GetCacheEntryPropertyAsBool((*it)->GetValue(), "ADVANCED");
+ if (!existingValue || (!this->AdvancedMode && advanced))
{
continue;
}
@@ -342,10 +351,13 @@ void cmCursesMainForm::Render(int left, int top, int width, int height)
std::vector<cmCursesCacheEntryComposite*>::iterator it;
for (it = this->Entries->begin(); it != this->Entries->end(); ++it)
{
- cmCacheManager::CacheIterator mit =
- this->CMakeInstance->GetCacheManager()->GetCacheIterator((*it)->GetValue());
- if (mit.IsAtEnd() ||
- (!this->AdvancedMode && mit.GetPropertyAsBool("ADVANCED")))
+ const char* existingValue =
+ this->CMakeInstance->GetState()
+ ->GetCacheEntryValue((*it)->GetValue());
+ bool advanced =
+ this->CMakeInstance->GetState()
+ ->GetCacheEntryPropertyAsBool((*it)->GetValue(), "ADVANCED");
+ if (!existingValue || (!this->AdvancedMode && advanced))
{
continue;
}
@@ -439,24 +451,25 @@ void cmCursesMainForm::PrintKeys(int process /* = 0 */)
}
curses_move(y-4,0);
+ char fmt_s[] = "%s";
char fmt[512] = "Press [enter] to edit option";
if ( process )
{
strcpy(fmt, " ");
}
- printw(fmt);
+ printw(fmt_s, fmt);
curses_move(y-3,0);
- printw(firstLine);
+ printw(fmt_s, firstLine);
curses_move(y-2,0);
- printw(secondLine);
+ printw(fmt_s, secondLine);
curses_move(y-1,0);
- printw(thirdLine);
+ printw(fmt_s, thirdLine);
if (cw)
{
sprintf(firstLine, "Page %d of %d", cw->GetPage(), this->NumberOfPages);
curses_move(0,65-static_cast<unsigned int>(strlen(firstLine))-1);
- printw(firstLine);
+ printw(fmt_s, firstLine);
}
// }
@@ -503,11 +516,12 @@ void cmCursesMainForm::UpdateStatusBar(const char* message)
// Get the help string of the current entry
// and add it to the help string
- cmCacheManager::CacheIterator it =
- this->CMakeInstance->GetCacheManager()->GetCacheIterator(curField);
- if (!it.IsAtEnd())
+ const char* existingValue =
+ this->CMakeInstance->GetState()->GetCacheEntryValue(curField);
+ if (existingValue)
{
- const char* hs = it.GetProperty("HELPSTRING");
+ const char* hs = this->CMakeInstance->GetState()
+ ->GetCacheEntryProperty(curField, "HELPSTRING");
if ( hs )
{
strncpy(help, hs, 127);
@@ -599,13 +613,13 @@ void cmCursesMainForm::UpdateStatusBar(const char* message)
version[width] = '\0';
// Now print both lines
+ char fmt_s[] = "%s";
curses_move(y-5,0);
attron(A_STANDOUT);
- char format[] = "%s";
- printw(format, bar);
+ printw(fmt_s, bar);
attroff(A_STANDOUT);
curses_move(y-4,0);
- printw(version);
+ printw(fmt_s, version);
pos_form_cursor(this->Form);
}
@@ -647,7 +661,7 @@ int cmCursesMainForm::Configure(int noconfigure)
// always save the current gui values to disk
this->FillCacheManagerFromUI();
- this->CMakeInstance->GetCacheManager()->SaveCache(
+ this->CMakeInstance->SaveCache(
this->CMakeInstance->GetHomeOutputDirectory());
this->LoadCache(0);
@@ -800,37 +814,42 @@ void cmCursesMainForm::FillCacheManagerFromUI()
size_t size = this->Entries->size();
for(size_t i=0; i < size; i++)
{
- cmCacheManager::CacheIterator it =
- this->CMakeInstance->GetCacheManager()->GetCacheIterator(
- (*this->Entries)[i]->Key.c_str());
- if (!it.IsAtEnd())
+ std::string cacheKey = (*this->Entries)[i]->Key;
+ const char* existingValue = this->CMakeInstance->GetState()
+ ->GetCacheEntryValue(cacheKey);
+ if (existingValue)
{
- std::string oldValue = it.GetValue();
+ std::string oldValue = existingValue;
std::string newValue = (*this->Entries)[i]->Entry->GetValue();
std::string fixedOldValue;
std::string fixedNewValue;
- this->FixValue(it.GetType(), oldValue, fixedOldValue);
- this->FixValue(it.GetType(), newValue, fixedNewValue);
+ cmState::CacheEntryType t =
+ this->CMakeInstance->GetState()
+ ->GetCacheEntryType(cacheKey);
+ this->FixValue(t, oldValue, fixedOldValue);
+ this->FixValue(t, newValue, fixedNewValue);
if(!(fixedOldValue == fixedNewValue))
{
// The user has changed the value. Mark it as modified.
- it.SetProperty("MODIFIED", true);
- it.SetValue(fixedNewValue.c_str());
+ this->CMakeInstance->GetState()
+ ->SetCacheEntryBoolProperty(cacheKey, "MODIFIED", true);
+ this->CMakeInstance->GetState()
+ ->SetCacheEntryValue(cacheKey, fixedNewValue);
}
}
}
}
-void cmCursesMainForm::FixValue(cmCacheManager::CacheEntryType type,
+void cmCursesMainForm::FixValue(cmState::CacheEntryType type,
const std::string& in, std::string& out) const
{
out = in.substr(0,in.find_last_not_of(" ")+1);
- if(type == cmCacheManager::PATH || type == cmCacheManager::FILEPATH)
+ if(type == cmState::PATH || type == cmState::FILEPATH)
{
cmSystemTools::ConvertToUnixSlashes(out);
}
- if(type == cmCacheManager::BOOL)
+ if(type == cmState::BOOL)
{
if(cmSystemTools::IsOff(out.c_str()))
{
@@ -902,7 +921,7 @@ void cmCursesMainForm::HandleInput()
if ( key == 10 || key == KEY_ENTER )
{
this->SearchMode = false;
- if ( this->SearchString.size() > 0 )
+ if (!this->SearchString.empty())
{
this->JumpToCacheEntry(this->SearchString.c_str());
this->OldSearchString = this->SearchString;
@@ -927,7 +946,7 @@ void cmCursesMainForm::HandleInput()
}
else if ( key == ctrl('h') || key == KEY_BACKSPACE || key == KEY_DC )
{
- if ( this->SearchString.size() > 0 )
+ if (!this->SearchString.empty())
{
this->SearchString.resize(this->SearchString.size()-1);
}
@@ -1025,12 +1044,15 @@ void cmCursesMainForm::HandleInput()
cmCursesWidget* lbl = reinterpret_cast<cmCursesWidget*>(field_userptr(
this->Fields[findex-2]));
const char* curField = lbl->GetValue();
- const char* helpString=0;
- cmCacheManager::CacheIterator it =
- this->CMakeInstance->GetCacheManager()->GetCacheIterator(curField);
- if (!it.IsAtEnd())
+ const char* helpString = 0;
+
+ const char* existingValue =
+ this->CMakeInstance->GetState()
+ ->GetCacheEntryValue(curField);
+ if (existingValue)
{
- helpString = it.GetProperty("HELPSTRING");
+ helpString = this->CMakeInstance->GetState()
+ ->GetCacheEntryProperty(curField, "HELPSTRING");
}
if (helpString)
{
@@ -1076,7 +1098,7 @@ void cmCursesMainForm::HandleInput()
}
else if ( key == 'n' )
{
- if ( this->OldSearchString.size() > 0 )
+ if (!this->OldSearchString.empty())
{
this->JumpToCacheEntry(this->OldSearchString.c_str());
}
@@ -1140,7 +1162,7 @@ void cmCursesMainForm::HandleInput()
field_userptr(this->Fields[findex-2]));
if ( lbl )
{
- this->CMakeInstance->GetCacheManager()->RemoveCacheEntry(lbl->GetValue());
+ this->CMakeInstance->GetState()->RemoveCacheEntry(lbl->GetValue());
std::string nextVal;
if (nextCur)
@@ -1210,7 +1232,7 @@ void cmCursesMainForm::JumpToCacheEntry(const char* astr)
int findex = start_index;
for(;;)
{
- if ( str.size() > 0 )
+ if (!str.empty())
{
cmCursesWidget* lbl = 0;
if ( findex >= 0 )
diff --git a/Source/CursesDialog/cmCursesMainForm.h b/Source/CursesDialog/cmCursesMainForm.h
index 883a2b3d6..255c823be 100644
--- a/Source/CursesDialog/cmCursesMainForm.h
+++ b/Source/CursesDialog/cmCursesMainForm.h
@@ -9,8 +9,8 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#ifndef __cmCursesMainForm_h
-#define __cmCursesMainForm_h
+#ifndef cmCursesMainForm_h
+#define cmCursesMainForm_h
#include "../cmStandardIncludes.h"
#include "cmCursesForm.h"
@@ -51,7 +51,7 @@ public:
* Returns true if an entry with the given key is in the
* list of current composites.
*/
- bool LookForCacheEntry(const char* key);
+ bool LookForCacheEntry(const std::string& key);
enum {
MIN_WIDTH = 65,
@@ -113,7 +113,7 @@ protected:
// cache.
void FillCacheManagerFromUI();
// Fix formatting of values to a consistent form.
- void FixValue(cmCacheManager::CacheEntryType type,
+ void FixValue(cmState::CacheEntryType type,
const std::string& in, std::string& out) const;
// Re-post the existing fields. Used to toggle between
// normal and advanced modes. Render() should be called
@@ -161,4 +161,4 @@ protected:
bool SearchMode;
};
-#endif // __cmCursesMainForm_h
+#endif // cmCursesMainForm_h
diff --git a/Source/CursesDialog/cmCursesOptionsWidget.cxx b/Source/CursesDialog/cmCursesOptionsWidget.cxx
new file mode 100644
index 000000000..30110a496
--- /dev/null
+++ b/Source/CursesDialog/cmCursesOptionsWidget.cxx
@@ -0,0 +1,105 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmCursesOptionsWidget.h"
+#include "cmCursesMainForm.h"
+
+inline int ctrl(int z)
+{
+ return (z&037);
+}
+
+cmCursesOptionsWidget::cmCursesOptionsWidget(int width, int height,
+ int left, int top) :
+ cmCursesWidget(width, height, left, top)
+{
+ this->Type = cmState::BOOL; // this is a bit of a hack
+ // there is no option type, and string type causes ccmake to cast
+ // the widget into a string widget at some point. BOOL is safe for
+ // now.
+ set_field_fore(this->Field, A_NORMAL);
+ set_field_back(this->Field, A_STANDOUT);
+ field_opts_off(this->Field, O_STATIC);
+}
+
+bool cmCursesOptionsWidget::HandleInput(int& key, cmCursesMainForm*, WINDOW* w)
+{
+
+ // 10 == enter
+ if (key == 10 || key == KEY_ENTER)
+ {
+ this->NextOption();
+ touchwin(w);
+ wrefresh(w);
+ return true;
+ }
+ else if (key == KEY_LEFT || key == ctrl('b'))
+ {
+ touchwin(w);
+ wrefresh(w);
+ this->PreviousOption();
+ return true;
+ }
+ else if (key == KEY_RIGHT || key == ctrl('f'))
+ {
+ this->NextOption();
+ touchwin(w);
+ wrefresh(w);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void cmCursesOptionsWidget::AddOption(std::string const & option )
+{
+ this->Options.push_back(option);
+}
+
+void cmCursesOptionsWidget::NextOption()
+{
+ this->CurrentOption++;
+ if(this->CurrentOption > this->Options.size()-1)
+ {
+ this->CurrentOption = 0;
+ }
+ this->SetValue(this->Options[this->CurrentOption]);
+}
+void cmCursesOptionsWidget::PreviousOption()
+{
+ if(this->CurrentOption == 0)
+ {
+ this->CurrentOption = this->Options.size()-1;
+ }
+ else
+ {
+ this->CurrentOption--;
+ }
+ this->SetValue(this->Options[this->CurrentOption]);
+}
+
+void cmCursesOptionsWidget::SetOption(const std::string& value)
+{
+ this->CurrentOption = 0; // default to 0 index
+ this->SetValue(value);
+ int index = 0;
+ for(std::vector<std::string>::iterator i = this->Options.begin();
+ i != this->Options.end(); ++i)
+ {
+ if(*i == value)
+ {
+ this->CurrentOption = index;
+ }
+ index++;
+ }
+}
diff --git a/Source/CursesDialog/cmCursesOptionsWidget.h b/Source/CursesDialog/cmCursesOptionsWidget.h
new file mode 100644
index 000000000..324014eae
--- /dev/null
+++ b/Source/CursesDialog/cmCursesOptionsWidget.h
@@ -0,0 +1,39 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmCursesOptionsWidget_h
+#define cmCursesOptionsWidget_h
+
+#include "cmCursesWidget.h"
+class cmCursesMainForm;
+
+class cmCursesOptionsWidget : public cmCursesWidget
+{
+public:
+ cmCursesOptionsWidget(int width, int height, int left, int top);
+
+ // Description:
+ // Handle user input. Called by the container of this widget
+ // when this widget has focus. Returns true if the input was
+ // handled.
+ virtual bool HandleInput(int& key, cmCursesMainForm* fm, WINDOW* w);
+ void SetOption(const std::string&);
+ void AddOption(std::string const &);
+ void NextOption();
+ void PreviousOption();
+protected:
+ cmCursesOptionsWidget(const cmCursesOptionsWidget& from);
+ void operator=(const cmCursesOptionsWidget&);
+ std::vector<std::string> Options;
+ std::vector<std::string>::size_type CurrentOption;
+};
+
+#endif // cmCursesOptionsWidget_h
diff --git a/Source/CursesDialog/cmCursesPathWidget.cxx b/Source/CursesDialog/cmCursesPathWidget.cxx
index 14c325bcb..611682309 100644
--- a/Source/CursesDialog/cmCursesPathWidget.cxx
+++ b/Source/CursesDialog/cmCursesPathWidget.cxx
@@ -18,7 +18,7 @@ cmCursesPathWidget::cmCursesPathWidget(int width, int height,
int left, int top) :
cmCursesStringWidget(width, height, left, top)
{
- this->Type = cmCacheManager::PATH;
+ this->Type = cmState::PATH;
this->Cycle = false;
this->CurrentIndex = 0;
}
@@ -57,9 +57,9 @@ void cmCursesPathWidget::OnTab(cmCursesMainForm* fm, WINDOW* w)
{
glob = cstr + "*";
}
- std::vector<cmStdString> dirs;
+ std::vector<std::string> dirs;
- cmSystemTools::SimpleGlob(glob.c_str(), dirs, (this->Type == cmCacheManager::PATH?-1:0));
+ cmSystemTools::SimpleGlob(glob, dirs, (this->Type == cmState::PATH?-1:0));
if ( this->CurrentIndex < dirs.size() )
{
cstr = dirs[this->CurrentIndex];
@@ -69,12 +69,12 @@ void cmCursesPathWidget::OnTab(cmCursesMainForm* fm, WINDOW* w)
cstr = cstr.substr(0, cstr.size()-1);
}
- if ( cmSystemTools::FileIsDirectory(cstr.c_str()) )
+ if ( cmSystemTools::FileIsDirectory(cstr) )
{
cstr += "/";
}
- this->SetString(cstr.c_str());
+ this->SetString(cstr);
touchwin(w);
wrefresh(w);
form_driver(form, REQ_END_FIELD);
diff --git a/Source/CursesDialog/cmCursesPathWidget.h b/Source/CursesDialog/cmCursesPathWidget.h
index 45c22a392..18d298aa4 100644
--- a/Source/CursesDialog/cmCursesPathWidget.h
+++ b/Source/CursesDialog/cmCursesPathWidget.h
@@ -9,8 +9,8 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#ifndef __cmCursesPathWidget_h
-#define __cmCursesPathWidget_h
+#ifndef cmCursesPathWidget_h
+#define cmCursesPathWidget_h
#include "cmCursesStringWidget.h"
@@ -37,4 +37,4 @@ protected:
std::string::size_type CurrentIndex;
};
-#endif // __cmCursesPathWidget_h
+#endif // cmCursesPathWidget_h
diff --git a/Source/CursesDialog/cmCursesStandardIncludes.h b/Source/CursesDialog/cmCursesStandardIncludes.h
index b157a289b..6047ec579 100644
--- a/Source/CursesDialog/cmCursesStandardIncludes.h
+++ b/Source/CursesDialog/cmCursesStandardIncludes.h
@@ -15,52 +15,12 @@
#define _MSE_INT_H
#endif
-#include <cmFormConfigure.h>
-
#if defined(__hpux)
# define _BOOL_DEFINED
# include <sys/time.h>
-# define _XOPEN_SOURCE_EXTENDED
-# include <curses.h>
-# include <form.h>
-# undef _XOPEN_SOURCE_EXTENDED
-#else
-/* figure out which curses.h to include */
-# if defined(CURSES_HAVE_NCURSES_H)
-# include <ncurses.h>
-# elif defined(CURSES_HAVE_NCURSES_NCURSES_H)
-# include <ncurses/ncurses.h>
-# elif defined(CURSES_HAVE_NCURSES_CURSES_H)
-# include <ncurses/curses.h>
-# else
-# include <curses.h>
-# endif
-
-# include <form.h>
-#endif
-
-// This is a hack to prevent warnings about these functions being
-// declared but not referenced.
-#if defined(__sgi) && !defined(__GNUC__)
-class cmCursesStandardIncludesHack
-{
-public:
- enum
- {
- Ref1 = sizeof(cfgetospeed(0)),
- Ref2 = sizeof(cfgetispeed(0)),
- Ref3 = sizeof(tcgetattr(0, 0)),
- Ref4 = sizeof(tcsetattr(0, 0, 0)),
- Ref5 = sizeof(cfsetospeed(0,0)),
- Ref6 = sizeof(cfsetispeed(0,0))
- };
-};
-#endif
-
-#ifndef getmaxyx
- #define getmaxyx(w,y,x) ((y) = getmaxy(w), (x) = getmaxx(w))
#endif
+#include <form.h>
// on some machines move erase and clear conflict with stl
// so remove them from the namespace
diff --git a/Source/CursesDialog/cmCursesStringWidget.cxx b/Source/CursesDialog/cmCursesStringWidget.cxx
index bd1ff71c6..6eb15c17a 100644
--- a/Source/CursesDialog/cmCursesStringWidget.cxx
+++ b/Source/CursesDialog/cmCursesStringWidget.cxx
@@ -22,7 +22,7 @@ cmCursesStringWidget::cmCursesStringWidget(int width, int height,
cmCursesWidget(width, height, left, top)
{
this->InEdit = false;
- this->Type = cmCacheManager::STRING;
+ this->Type = cmState::STRING;
set_field_fore(this->Field, A_NORMAL);
set_field_back(this->Field, A_STANDOUT);
field_opts_off(this->Field, O_STATIC);
@@ -168,17 +168,16 @@ bool cmCursesStringWidget::HandleInput(int& key, cmCursesMainForm* fm,
else if ( key == 127 ||
key == KEY_BACKSPACE )
{
- if ( form->curcol > 0 )
- {
+ FIELD *cur = current_field(form);
form_driver(form, REQ_DEL_PREV);
- }
+ if (current_field(form) != cur)
+ {
+ set_current_field(form, cur);
+ }
}
else if ( key == ctrl('d') ||key == KEY_DC )
{
- if ( form->curcol >= 0 )
- {
- form_driver(form, REQ_DEL_CHAR);
- }
+ form_driver(form, REQ_DEL_CHAR);
}
else
{
@@ -195,7 +194,7 @@ bool cmCursesStringWidget::HandleInput(int& key, cmCursesMainForm* fm,
return true;
}
-void cmCursesStringWidget::SetString(const char* value)
+void cmCursesStringWidget::SetString(const std::string& value)
{
this->SetValue(value);
}
@@ -221,6 +220,7 @@ bool cmCursesStringWidget::PrintKeys()
}
if (this->InEdit)
{
+ char fmt_s[] = "%s";
char firstLine[512];
// Clean the toolbar
for(int i=0; i<512; i++)
@@ -229,17 +229,16 @@ bool cmCursesStringWidget::PrintKeys()
}
firstLine[511] = '\0';
curses_move(y-4,0);
- printw(firstLine);
+ printw(fmt_s, firstLine);
curses_move(y-3,0);
- printw(firstLine);
+ printw(fmt_s, firstLine);
curses_move(y-2,0);
- printw(firstLine);
+ printw(fmt_s, firstLine);
curses_move(y-1,0);
- printw(firstLine);
+ printw(fmt_s, firstLine);
- sprintf(firstLine, "Editing option, press [enter] to leave edit.");
curses_move(y-3,0);
- printw(firstLine);
+ printw(fmt_s, "Editing option, press [enter] to leave edit.");
return true;
}
else
diff --git a/Source/CursesDialog/cmCursesStringWidget.h b/Source/CursesDialog/cmCursesStringWidget.h
index e939049df..fc1b2ba4f 100644
--- a/Source/CursesDialog/cmCursesStringWidget.h
+++ b/Source/CursesDialog/cmCursesStringWidget.h
@@ -9,8 +9,8 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#ifndef __cmCursesStringWidget_h
-#define __cmCursesStringWidget_h
+#ifndef cmCursesStringWidget_h
+#define cmCursesStringWidget_h
#include "cmCursesWidget.h"
@@ -37,7 +37,7 @@ public:
/**
* Set/Get the string.
*/
- void SetString(const char* value);
+ void SetString(const std::string& value);
const char* GetString();
virtual const char* GetValue();
@@ -73,4 +73,4 @@ protected:
bool Done;
};
-#endif // __cmCursesStringWidget_h
+#endif // cmCursesStringWidget_h
diff --git a/Source/CursesDialog/cmCursesWidget.cxx b/Source/CursesDialog/cmCursesWidget.cxx
index 5dffcaa5c..a12e4c21d 100644
--- a/Source/CursesDialog/cmCursesWidget.cxx
+++ b/Source/CursesDialog/cmCursesWidget.cxx
@@ -46,10 +46,10 @@ void cmCursesWidget::Move(int x, int y, bool isNewPage)
}
}
-void cmCursesWidget::SetValue(const char* value)
+void cmCursesWidget::SetValue(const std::string& value)
{
this->Value = value;
- set_field_buffer(this->Field, 0, value);
+ set_field_buffer(this->Field, 0, const_cast<char *>(value.c_str()));
}
const char* cmCursesWidget::GetValue()
diff --git a/Source/CursesDialog/cmCursesWidget.h b/Source/CursesDialog/cmCursesWidget.h
index 952c67a86..7bbdff109 100644
--- a/Source/CursesDialog/cmCursesWidget.h
+++ b/Source/CursesDialog/cmCursesWidget.h
@@ -9,10 +9,10 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#ifndef __cmCursesWidget_h
-#define __cmCursesWidget_h
+#ifndef cmCursesWidget_h
+#define cmCursesWidget_h
-#include "../cmCacheManager.h"
+#include "../cmState.h"
#include "cmCursesStandardIncludes.h"
class cmCursesMainForm;
@@ -40,13 +40,13 @@ public:
* Set/Get the value (setting the value also changes the contents
* of the field buffer).
*/
- virtual void SetValue(const char* value);
+ virtual void SetValue(const std::string& value);
virtual const char* GetValue();
/**
* Get the type of the widget (STRING, PATH etc...)
*/
- cmCacheManager::CacheEntryType GetType()
+ cmState::CacheEntryType GetType()
{ return this->Type; }
/**
@@ -77,11 +77,11 @@ protected:
cmCursesWidget(const cmCursesWidget& from);
void operator=(const cmCursesWidget&);
- cmCacheManager::CacheEntryType Type;
+ cmState::CacheEntryType Type;
std::string Value;
FIELD* Field;
// The page in the main form this widget is in
int Page;
};
-#endif // __cmCursesWidget_h
+#endif // cmCursesWidget_h
diff --git a/Source/CursesDialog/form/fld_attr.c b/Source/CursesDialog/form/fld_attr.c
index 86195882b..35ea9033c 100644
--- a/Source/CursesDialog/form/fld_attr.c
+++ b/Source/CursesDialog/form/fld_attr.c
@@ -29,13 +29,7 @@
/****************************************************************************
* Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
****************************************************************************/
-#if defined(__hpux)
- #define _XOPEN_SOURCE_EXTENDED
-#endif
- #include "form.priv.h"
-#if defined(__hpux)
- #undef _XOPEN_SOURCE_EXTENDED
-#endif
+#include "form.priv.h"
MODULE_ID("$Id$")
/*----------------------------------------------------------------------------
diff --git a/Source/CursesDialog/form/form.h b/Source/CursesDialog/form/form.h
index 94f05af8a..1219cb5f2 100644
--- a/Source/CursesDialog/form/form.h
+++ b/Source/CursesDialog/form/form.h
@@ -47,7 +47,17 @@
# elif defined(CURSES_HAVE_NCURSES_CURSES_H)
# include <ncurses/curses.h>
# else
+# if defined(__hpux)
+# if defined(_XOPEN_SOURCE_EXTENDED)
+# define HAVE__XOPEN_SOURCE_EXTENDED
+# else
+# define _XOPEN_SOURCE_EXTENDED
+# endif
+# endif
# include <curses.h>
+# if defined(__hpux) && !defined(HAVE__XOPEN_SOURCE_EXTENDED)
+# undef _XOPEN_SOURCE_EXTENDED
+# endif
# endif
#include <eti.h>
diff --git a/Source/CursesDialog/form/form.priv.h b/Source/CursesDialog/form/form.priv.h
index 3691f2fd0..8516a6ffd 100644
--- a/Source/CursesDialog/form/form.priv.h
+++ b/Source/CursesDialog/form/form.priv.h
@@ -33,12 +33,6 @@
#include "mf_common.h"
#include "form.h"
-/* get around odd bug on aCC and itanium */
-#if defined(__hpux) && defined(__ia64)
-#define getmaxx __getmaxx
-#define getmaxy __getmaxy
-#endif
-
/* form status values */
#define _OVLMODE (0x04) /* Form is in overlay mode */
#define _WINDOW_MODIFIED (0x10) /* Current field window has been modified */
diff --git a/Source/CursesDialog/form/frm_driver.c b/Source/CursesDialog/form/frm_driver.c
index b9611bf10..26f580e45 100644
--- a/Source/CursesDialog/form/frm_driver.c
+++ b/Source/CursesDialog/form/frm_driver.c
@@ -29,13 +29,7 @@
/****************************************************************************
* Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
****************************************************************************/
-#if defined(__hpux)
- #define _XOPEN_SOURCE_EXTENDED
-#endif
#include "form.priv.h"
-#if defined(__hpux)
- #undef _XOPEN_SOURCE_EXTENDED
-#endif
/* AIX seems to define this */
#undef lines
@@ -357,12 +351,7 @@ static void Buffer_To_Window(const FIELD * field, WINDOW * win)
assert(win && field);
-#if defined(__LSB_VERSION__)
getmaxyx(win, height, width);
-#else
- width = getmaxx(win);
- height = getmaxy(win);
-#endif
for(row=0, pBuffer=field->buf;
row < height;
@@ -394,17 +383,13 @@ static void Window_To_Buffer(WINDOW * win, FIELD * field)
int pad;
int len = 0;
char *p;
- int row, height;
+ int row, height, width;
assert(win && field && field->buf );
pad = field->pad;
p = field->buf;
-#if defined(__LSB_VERSION__)
- { int width; getmaxyx(win, height, width); }
-#else
- height = getmaxy(win);
-#endif
+ getmaxyx(win, height, width);
for(row=0; (row < height) && (row < field->drows); row++ )
{
diff --git a/Source/CursesDialog/form/frm_post.c b/Source/CursesDialog/form/frm_post.c
index 3c63de70e..924fe6a9e 100644
--- a/Source/CursesDialog/form/frm_post.c
+++ b/Source/CursesDialog/form/frm_post.c
@@ -63,12 +63,7 @@ int post_form(FORM * form)
RETURN(E_NOT_CONNECTED);
formwin = Get_Form_Window(form);
-#if defined(__LSB_VERSION__)
getmaxyx(formwin, height, width);
-#else
- width = getmaxx(formwin);
- height = getmaxy(formwin);
-#endif
if ((form->cols > width) || (form->rows > height))
RETURN(E_NO_ROOM);
diff --git a/Source/CursesDialog/form/frm_req_name.c b/Source/CursesDialog/form/frm_req_name.c
index b108dabe4..6fb9183b3 100644
--- a/Source/CursesDialog/form/frm_req_name.c
+++ b/Source/CursesDialog/form/frm_req_name.c
@@ -35,13 +35,7 @@
* Routines to handle external names of menu requests *
***************************************************************************/
-#if defined(__hpux)
- #define _XOPEN_SOURCE_EXTENDED
-#endif
#include "form.priv.h"
-#if defined(__hpux)
- #undef _XOPEN_SOURCE_EXTENDED
-#endif
MODULE_ID("$Id$")
diff --git a/Source/Modules/FindJsonCpp.cmake b/Source/Modules/FindJsonCpp.cmake
new file mode 100644
index 000000000..014d3bd73
--- /dev/null
+++ b/Source/Modules/FindJsonCpp.cmake
@@ -0,0 +1,117 @@
+#[=======================================================================[.rst:
+FindJsonCpp
+-----------
+
+Find JsonCpp includes and library.
+
+Imported Targets
+^^^^^^^^^^^^^^^^
+
+An :ref:`imported target <Imported targets>` named
+``JsonCpp::JsonCpp`` is provided if JsonCpp has been found.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module defines the following variables:
+
+``JsonCpp_FOUND``
+ True if JsonCpp was found, false otherwise.
+``JsonCpp_INCLUDE_DIRS``
+ Include directories needed to include JsonCpp headers.
+``JsonCpp_LIBRARIES``
+ Libraries needed to link to JsonCpp.
+``JsonCpp_VERSION_STRING``
+ The version of JsonCpp found.
+ May not be set for JsonCpp versions prior to 1.0.
+``JsonCpp_VERSION_MAJOR``
+ The major version of JsonCpp.
+``JsonCpp_VERSION_MINOR``
+ The minor version of JsonCpp.
+``JsonCpp_VERSION_PATCH``
+ The patch version of JsonCpp.
+
+Cache Variables
+^^^^^^^^^^^^^^^
+
+This module uses the following cache variables:
+
+``JsonCpp_LIBRARY``
+ The location of the JsonCpp library file.
+``JsonCpp_INCLUDE_DIR``
+ The location of the JsonCpp include directory containing ``json/json.h``.
+
+The cache variables should not be used by project code.
+They may be set by end users to point at JsonCpp components.
+#]=======================================================================]
+
+#=============================================================================
+# Copyright 2014-2015 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+#-----------------------------------------------------------------------------
+find_library(JsonCpp_LIBRARY
+ NAMES jsoncpp
+ )
+mark_as_advanced(JsonCpp_LIBRARY)
+
+find_path(JsonCpp_INCLUDE_DIR
+ NAMES json/json.h
+ PATH_SUFFIXES jsoncpp
+ )
+mark_as_advanced(JsonCpp_INCLUDE_DIR)
+
+#-----------------------------------------------------------------------------
+# Extract version number if possible.
+set(_JsonCpp_H_REGEX "^#[ \t]*define[ \t]+JSONCPP_VERSION_STRING[ \t]+\"(([0-9]+)\\.([0-9]+)\\.([0-9]+)[^\"]*)\".*$")
+if(JsonCpp_INCLUDE_DIR AND EXISTS "${JsonCpp_INCLUDE_DIR}/json/version.h")
+ file(STRINGS "${JsonCpp_INCLUDE_DIR}/json/version.h" _JsonCpp_H REGEX "${_JsonCpp_H_REGEX}")
+else()
+ set(_JsonCpp_H "")
+endif()
+if(_JsonCpp_H MATCHES "${_JsonCpp_H_REGEX}")
+ set(JsonCpp_VERSION_STRING "${CMAKE_MATCH_1}")
+ set(JsonCpp_VERSION_MAJOR "${CMAKE_MATCH_2}")
+ set(JsonCpp_VERSION_MINOR "${CMAKE_MATCH_3}")
+ set(JsonCpp_VERSION_PATCH "${CMAKE_MATCH_4}")
+else()
+ set(JsonCpp_VERSION_STRING "")
+ set(JsonCpp_VERSION_MAJOR "")
+ set(JsonCpp_VERSION_MINOR "")
+ set(JsonCpp_VERSION_PATCH "")
+endif()
+unset(_JsonCpp_H_REGEX)
+unset(_JsonCpp_H)
+
+#-----------------------------------------------------------------------------
+include(${CMAKE_CURRENT_LIST_DIR}/../../Modules/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(JsonCpp
+ FOUND_VAR JsonCpp_FOUND
+ REQUIRED_VARS JsonCpp_LIBRARY JsonCpp_INCLUDE_DIR
+ VERSION_VAR JsonCpp_VERSION_STRING
+ )
+set(JSONCPP_FOUND ${JsonCpp_FOUND})
+
+#-----------------------------------------------------------------------------
+# Provide documented result variables and targets.
+if(JsonCpp_FOUND)
+ set(JsonCpp_INCLUDE_DIRS ${JsonCpp_INCLUDE_DIR})
+ set(JsonCpp_LIBRARIES ${JsonCpp_LIBRARY})
+ if(NOT TARGET JsonCpp::JsonCpp)
+ add_library(JsonCpp::JsonCpp UNKNOWN IMPORTED)
+ set_target_properties(JsonCpp::JsonCpp PROPERTIES
+ IMPORTED_LOCATION "${JsonCpp_LIBRARY}"
+ INTERFACE_INCLUDE_DIRECTORIES "${JsonCpp_INCLUDE_DIRS}"
+ IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
+ )
+ endif()
+endif()
diff --git a/Source/QtDialog/AddCacheEntry.cxx b/Source/QtDialog/AddCacheEntry.cxx
index e7fedc5c5..3881045bd 100644
--- a/Source/QtDialog/AddCacheEntry.cxx
+++ b/Source/QtDialog/AddCacheEntry.cxx
@@ -15,14 +15,16 @@
#include <QCompleter>
static const int NumTypes = 4;
+static const int DefaultTypeIndex = 0;
static const QByteArray TypeStrings[NumTypes] =
{ "BOOL", "PATH", "FILEPATH", "STRING" };
static const QCMakeProperty::PropertyType Types[NumTypes] =
{ QCMakeProperty::BOOL, QCMakeProperty::PATH,
QCMakeProperty::FILEPATH, QCMakeProperty::STRING};
-AddCacheEntry::AddCacheEntry(QWidget* p, const QStringList& completions)
- : QWidget(p)
+AddCacheEntry::AddCacheEntry(QWidget* p, const QStringList& varNames,
+ const QStringList& varTypes)
+ : QWidget(p), VarNames(varNames), VarTypes(varTypes)
{
this->setupUi(this);
for(int i=0; i<NumTypes; i++)
@@ -43,7 +45,10 @@ AddCacheEntry::AddCacheEntry(QWidget* p, const QStringList& completions)
this->setTabOrder(path, filepath);
this->setTabOrder(filepath, string);
this->setTabOrder(string, this->Description);
- this->Name->setCompleter(new QCompleter(completions, this));
+ QCompleter *completer = new QCompleter(this->VarNames, this);
+ this->Name->setCompleter(completer);
+ connect(completer, SIGNAL(activated(const QString&)),
+ this, SLOT(onCompletionActivated(const QString&)));
}
QString AddCacheEntry::name() const
@@ -77,7 +82,32 @@ QCMakeProperty::PropertyType AddCacheEntry::type() const
{
return Types[idx];
}
- return QCMakeProperty::BOOL;
+ return Types[DefaultTypeIndex];
}
+QString AddCacheEntry::typeString() const
+{
+ int idx = this->Type->currentIndex();
+ if(idx >= 0 && idx < NumTypes)
+ {
+ return TypeStrings[idx];
+ }
+ return TypeStrings[DefaultTypeIndex];
+}
+void AddCacheEntry::onCompletionActivated(const QString &text)
+{
+ int idx = this->VarNames.indexOf(text);
+ if (idx != -1)
+ {
+ QString vartype = this->VarTypes[idx];
+ for (int i = 0; i < NumTypes; i++)
+ {
+ if (TypeStrings[i] == vartype)
+ {
+ this->Type->setCurrentIndex(i);
+ break;
+ }
+ }
+ }
+}
diff --git a/Source/QtDialog/AddCacheEntry.h b/Source/QtDialog/AddCacheEntry.h
index e219d4ee7..38c3a7444 100644
--- a/Source/QtDialog/AddCacheEntry.h
+++ b/Source/QtDialog/AddCacheEntry.h
@@ -24,12 +24,21 @@ class AddCacheEntry : public QWidget, public Ui::AddCacheEntry
{
Q_OBJECT
public:
- AddCacheEntry(QWidget* p, const QStringList& completions);
+ AddCacheEntry(QWidget* p, const QStringList& varNames,
+ const QStringList& varTypes);
QString name() const;
QVariant value() const;
QString description() const;
QCMakeProperty::PropertyType type() const;
+ QString typeString() const;
+
+private slots:
+ void onCompletionActivated(const QString &text);
+
+private:
+ const QStringList& VarNames;
+ const QStringList& VarTypes;
};
#endif
diff --git a/Source/QtDialog/CMake.desktop b/Source/QtDialog/CMake.desktop
index 645eb76e9..842091f5b 100644
--- a/Source/QtDialog/CMake.desktop
+++ b/Source/QtDialog/CMake.desktop
@@ -3,7 +3,7 @@ Version=1.0
Name=CMake
Comment=Cross-platform buildsystem
Exec=cmake-gui %f
-Icon=CMakeSetup32.png
+Icon=CMakeSetup
Terminal=false
X-MultipleArgs=false
Type=Application
diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt
index ef252944e..a906f4a6f 100644
--- a/Source/QtDialog/CMakeLists.txt
+++ b/Source/QtDialog/CMakeLists.txt
@@ -14,6 +14,7 @@ project(QtDialog)
if(POLICY CMP0020)
cmake_policy(SET CMP0020 NEW) # Drop when CMake >= 2.8.11 required
endif()
+CMake_OPTIONAL_COMPONENT(cmake-gui)
find_package(Qt5Widgets QUIET)
if (Qt5Widgets_FOUND)
include_directories(${Qt5Widgets_INCLUDE_DIRS})
@@ -27,15 +28,62 @@ if (Qt5Widgets_FOUND)
macro(qt4_add_resources)
qt5_add_resources(${ARGN})
endmacro()
- set(QT_LIBRARIES ${Qt5Widgets_LIBRARIES})
+ set(CMake_QT_LIBRARIES ${Qt5Widgets_LIBRARIES})
+ set(QT_QTMAIN_LIBRARY ${Qt5Core_QTMAIN_LIBRARIES})
+
# Remove this when the minimum version of Qt is 4.6.
add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
- if(WIN32 AND TARGET Qt5::Core)
+ # We need to install platform plugin and add qt.conf for Qt5 on Mac and Windows.
+ # FIXME: This should be part of Qt5 CMake scripts, but unfortunatelly
+ # Qt5 support is missing there.
+ if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32))
+ macro(install_qt5_plugin _qt_plugin_name _qt_plugins_var)
+ get_target_property(_qt_plugin_path "${_qt_plugin_name}" LOCATION)
+ if(EXISTS "${_qt_plugin_path}")
+ get_filename_component(_qt_plugin_file "${_qt_plugin_path}" NAME)
+ get_filename_component(_qt_plugin_type "${_qt_plugin_path}" PATH)
+ get_filename_component(_qt_plugin_type "${_qt_plugin_type}" NAME)
+ if(APPLE)
+ set(_qt_plugin_dir "PlugIns")
+ elseif(WIN32)
+ set(_qt_plugin_dir "plugins")
+ endif()
+ set(_qt_plugin_dest "${_qt_plugin_dir}/${_qt_plugin_type}")
+ install(FILES "${_qt_plugin_path}"
+ DESTINATION "${_qt_plugin_dest}"
+ ${COMPONENT})
+ set(${_qt_plugins_var}
+ "${${_qt_plugins_var}};\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${_qt_plugin_dest}/${_qt_plugin_file}")
+ else()
+ message(FATAL_ERROR "QT plugin ${_qt_plugin_name} not found")
+ endif()
+ endmacro()
+ if(APPLE)
+ install_qt5_plugin("Qt5::QCocoaIntegrationPlugin" QT_PLUGINS)
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+ "[Paths]\nPlugins = ${_qt_plugin_dir}\n")
+ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+ DESTINATION "${CMAKE_INSTALL_PREFIX}/Resources"
+ ${COMPONENT})
+ elseif(WIN32)
+ install_qt5_plugin("Qt5::QWindowsIntegrationPlugin" QT_PLUGINS)
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+ "[Paths]\nPlugins = ../${_qt_plugin_dir}\n")
+ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+ DESTINATION bin
+ ${COMPONENT})
+ endif()
+ endif()
+
+ if(TARGET Qt5::Core)
get_property(_Qt5_Core_LOCATION TARGET Qt5::Core PROPERTY LOCATION)
get_filename_component(Qt_BIN_DIR "${_Qt5_Core_LOCATION}" PATH)
+ if(APPLE)
+ get_filename_component(Qt_BIN_DIR "${Qt_BIN_DIR}" PATH)
+ endif()
endif()
else()
set(QT_MIN_VERSION "4.4.0")
@@ -47,12 +95,8 @@ else()
include(${QT_USE_FILE})
- if(WIN32 AND EXISTS "${QT_QMAKE_EXECUTABLE}")
- get_filename_component(_Qt_BIN_DIR "${QT_QMAKE_EXECUTABLE}" PATH)
- if(EXISTS "${_Qt_BIN_DIR}/QtCore4.dll")
- set(Qt_BIN_DIR ${_Qt_BIN_DIR})
- endif()
- endif()
+ set(CMake_QT_LIBRARIES ${QT_LIBRARIES})
+
endif()
set(SRCS
@@ -69,15 +113,18 @@ set(SRCS
QCMakeCacheView.h
QCMakeWidgets.cxx
QCMakeWidgets.h
- QMacInstallDialog.cxx
- QMacInstallDialog.h
+ RegexExplorer.cxx
+ RegexExplorer.h
+ WarningMessagesDialog.cxx
+ WarningMessagesDialog.h
)
QT4_WRAP_UI(UI_SRCS
CMakeSetupDialog.ui
Compilers.ui
CrossCompiler.ui
AddCacheEntry.ui
- MacInstallDialog.ui
+ RegexExplorer.ui
+ WarningMessagesDialog.ui
)
QT4_WRAP_CPP(MOC_SRCS
AddCacheEntry.h
@@ -87,7 +134,8 @@ QT4_WRAP_CPP(MOC_SRCS
QCMake.h
QCMakeCacheView.h
QCMakeWidgets.h
- QMacInstallDialog.h
+ RegexExplorer.h
+ WarningMessagesDialog.h
)
QT4_ADD_RESOURCES(RC_SRCS CMakeSetup.qrc)
@@ -102,56 +150,84 @@ if(APPLE)
MACOSX_PACKAGE_LOCATION Resources)
endif()
+if(CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL)
+ install(FILES ${CMake_SOURCE_DIR}/Licenses/LGPLv2.1.txt
+ DESTINATION ${CMAKE_DATA_DIR}/Licenses
+ ${COMPONENT})
+ set_property(SOURCE CMakeSetupDialog.cxx
+ PROPERTY COMPILE_DEFINITIONS CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL)
+endif()
+
set(CMAKE_INCLUDE_CURRENT_DIR ON)
-add_executable(cmake-gui WIN32 MACOSX_BUNDLE ${SRCS})
-target_link_libraries(cmake-gui CMakeLib ${QT_QTMAIN_LIBRARY} ${QT_LIBRARIES})
-if(Qt_BIN_DIR)
- set_property(TARGET cmake-gui PROPERTY Qt_BIN_DIR ${Qt_BIN_DIR})
-endif()
+add_executable(cmake-gui WIN32 MACOSX_BUNDLE ${SRCS} ${MANIFEST_FILE})
+target_link_libraries(cmake-gui CMakeLib ${QT_QTMAIN_LIBRARY} ${CMake_QT_LIBRARIES})
if(APPLE)
+ file(STRINGS "${CMake_SOURCE_DIR}/Copyright.txt" copyright_line
+ LIMIT_COUNT 1 REGEX "^Copyright 2000-20[0-9][0-9] Kitware")
+
set_target_properties(cmake-gui PROPERTIES
- OUTPUT_NAME ${CMAKE_BUNDLE_NAME})
+ OUTPUT_NAME CMake
+ MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in"
+ MACOSX_BUNDLE_SHORT_VERSION_STRING "${CMAKE_BUNDLE_VERSION}"
+ # TBD: MACOSX_BUNDLE_BUNDLE_VERSION "${CMAKE_BUNDLE_VERSION}"
+ MACOSX_BUNDLE_COPYRIGHT "${copyright_line}"
+ MACOSX_BUNDLE_GUI_IDENTIFIER "org.cmake.cmake"
+ )
+
+ # Create a symlink in the build tree to provide a "cmake-gui" next
+ # to the "cmake" executable that refers to the application bundle.
+ add_custom_command(TARGET cmake-gui POST_BUILD
+ COMMAND ln -sf CMake.app/Contents/MacOS/CMake
+ $<TARGET_FILE_DIR:cmake>/cmake-gui
+ )
endif()
set(CMAKE_INSTALL_DESTINATION_ARGS
- BUNDLE DESTINATION "${CMAKE_BUNDLE_LOCATION}")
+ BUNDLE DESTINATION "${CMAKE_BUNDLE_LOCATION}" ${COMPONENT})
+
+install(TARGETS cmake-gui
+ RUNTIME DESTINATION bin ${COMPONENT}
+ ${CMAKE_INSTALL_DESTINATION_ARGS})
-install(TARGETS cmake-gui RUNTIME DESTINATION bin ${CMAKE_INSTALL_DESTINATION_ARGS})
+if(UNIX AND NOT APPLE)
+ foreach (size IN ITEMS 32 128)
+ install(
+ FILES "${CMAKE_CURRENT_SOURCE_DIR}/CMakeSetup${size}.png"
+ DESTINATION "${CMAKE_XDGDATA_DIR}/icons/hicolor/${size}x${size}/apps"
+ ${COMPONENT}
+ RENAME "CMakeSetup.png")
+ endforeach ()
-if(UNIX)
# install a desktop file so CMake appears in the application start menu
# with an icon
- install(FILES CMake.desktop DESTINATION share/applications )
- install(FILES CMakeSetup32.png DESTINATION share/pixmaps )
- install(FILES cmakecache.xml DESTINATION share/mime/packages )
+ install(FILES CMake.desktop
+ DESTINATION "${CMAKE_XDGDATA_DIR}/applications"
+ ${COMPONENT})
+ install(FILES cmakecache.xml
+ DESTINATION "${CMAKE_XDGDATA_DIR}/mime/packages"
+ ${COMPONENT})
endif()
if(APPLE)
- set(CMAKE_POSTFLIGHT_SCRIPT
- "${CMake_BINARY_DIR}/Source/QtDialog/postflight.sh")
- set(CMAKE_POSTUPGRADE_SCRIPT
- "${CMake_BINARY_DIR}/Source/QtDialog/postupgrade.sh")
- configure_file("${CMake_SOURCE_DIR}/Source/QtDialog/postflight.sh.in"
- "${CMake_BINARY_DIR}/Source/QtDialog/postflight.sh")
- configure_file("${CMake_SOURCE_DIR}/Source/QtDialog/postupgrade.sh.in"
- "${CMake_BINARY_DIR}/Source/QtDialog/postupgrade.sh")
- install(CODE "execute_process(COMMAND ln -s \"../MacOS/${CMAKE_BUNDLE_NAME}\" cmake-gui
- WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin)")
+ install(CODE "
+ execute_process(COMMAND ln -s \"../MacOS/CMake\" cmake-gui
+ WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin)
+ " ${COMPONENT})
endif()
-if(APPLE OR WIN32)
+if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32))
# install rules for including 3rd party libs such as Qt
# if a system Qt is used (e.g. installed in /usr/lib/), it will not be included in the installation
set(fixup_exe "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin/cmake-gui${CMAKE_EXECUTABLE_SUFFIX}")
if(APPLE)
- set(fixup_exe "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/MacOS/${CMAKE_BUNDLE_NAME}")
+ set(fixup_exe "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/MacOS/CMake")
endif()
install(CODE "
include(\"${CMake_SOURCE_DIR}/Modules/BundleUtilities.cmake\")
set(BU_CHMOD_BUNDLE_ITEMS ON)
- fixup_bundle(\"${fixup_exe}\" \"\" \"${QT_LIBRARY_DIR};${QT_BINARY_DIR}\")
- ")
+ fixup_bundle(\"${fixup_exe}\" \"${QT_PLUGINS}\" \"${Qt_BIN_DIR};${QT_LIBRARY_DIR};${QT_BINARY_DIR}\")
+ " ${COMPONENT})
endif()
set(CMAKE_PACKAGE_QTGUI TRUE)
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx
index 01893f589..4f93a7729 100644
--- a/Source/QtDialog/CMakeSetup.cxx
+++ b/Source/QtDialog/CMakeSetup.cxx
@@ -14,92 +14,93 @@
#include <QDir>
#include <QTranslator>
#include <QLocale>
-#include "QMacInstallDialog.h"
+#include <QTextCodec>
#include "CMakeSetupDialog.h"
#include "cmDocumentation.h"
#include "cmake.h"
#include "cmVersion.h"
+#include "cmAlgorithms.h"
#include <cmsys/CommandLineArguments.hxx>
#include <cmsys/SystemTools.hxx>
+#include <cmsys/Encoding.hxx>
//----------------------------------------------------------------------------
-static const char * cmDocumentationName[][3] =
+static const char * cmDocumentationName[][2] =
{
{0,
- " cmake-gui - CMake GUI.", 0},
- {0,0,0}
+ " cmake-gui - CMake GUI."},
+ {0,0}
};
//----------------------------------------------------------------------------
-static const char * cmDocumentationUsage[][3] =
+static const char * cmDocumentationUsage[][2] =
{
{0,
" cmake-gui [options]\n"
" cmake-gui [options] <path-to-source>\n"
- " cmake-gui [options] <path-to-existing-build>", 0},
- {0,0,0}
+ " cmake-gui [options] <path-to-existing-build>"},
+ {0,0}
};
//----------------------------------------------------------------------------
-static const char * cmDocumentationDescription[][3] =
+static const char * cmDocumentationOptions[][2] =
{
- {0,
- "The \"cmake-gui\" executable is the CMake GUI. Project "
- "configuration settings may be specified interactively. "
- "Brief instructions are provided at the bottom of the "
- "window when the program is running.", 0},
- CMAKE_STANDARD_INTRODUCTION,
- {0,0,0}
+ {0,0}
};
-//----------------------------------------------------------------------------
-static const char * cmDocumentationOptions[][3] =
-{
- {0,0,0}
-};
+#if defined(Q_OS_MAC)
+static int cmOSXInstall(std::string dir);
+#endif
int main(int argc, char** argv)
{
- cmSystemTools::FindExecutableDirectory(argv[0]);
+ cmsys::Encoding::CommandLineArguments encoding_args =
+ cmsys::Encoding::CommandLineArguments::Main(argc, argv);
+ int argc2 = encoding_args.argc();
+ char const* const* argv2 = encoding_args.argv();
+
+ cmSystemTools::FindCMakeResources(argv2[0]);
// check docs first so that X is not need to get docs
// do docs, if args were given
cmDocumentation doc;
doc.addCMakeStandardDocSections();
- if(argc >1 && doc.CheckOptions(argc, argv))
+ if(argc2 >1 && doc.CheckOptions(argc2, argv2))
{
// Construct and print requested documentation.
cmake hcm;
+ hcm.SetHomeDirectory("");
+ hcm.SetHomeOutputDirectory("");
hcm.AddCMakePaths();
- // just incase the install is bad avoid a seg fault
- const char* root = hcm.GetCacheDefinition("CMAKE_ROOT");
- if(root)
- {
- doc.SetCMakeRoot(root);
- }
- std::vector<cmDocumentationEntry> commands;
- std::vector<cmDocumentationEntry> compatCommands;
- std::map<std::string,cmDocumentationSection *> propDocs;
std::vector<cmDocumentationEntry> generators;
- hcm.GetCommandDocumentation(commands, true, false);
- hcm.GetCommandDocumentation(compatCommands, false, true);
hcm.GetGeneratorDocumentation(generators);
- hcm.GetPropertiesDocumentation(propDocs);
doc.SetName("cmake");
doc.SetSection("Name",cmDocumentationName);
doc.SetSection("Usage",cmDocumentationUsage);
- doc.SetSection("Description",cmDocumentationDescription);
doc.AppendSection("Generators",generators);
doc.PrependSection("Options",cmDocumentationOptions);
- doc.SetSection("Commands",commands);
- doc.SetSection("Compatilbility Commands", compatCommands);
- doc.SetSections(propDocs);
return (doc.PrintRequestedDocumentation(std::cout)? 0:1);
}
+#if defined(Q_OS_MAC)
+ if (argc2 == 2 && strcmp(argv2[1], "--install") == 0)
+ {
+ return cmOSXInstall("/usr/local/bin");
+ }
+ if (argc2 == 2 && cmHasLiteralPrefix(argv2[1], "--install="))
+ {
+ return cmOSXInstall(argv2[1]+10);
+ }
+#endif
+
QApplication app(argc, argv);
+#if defined(CMAKE_ENCODING_UTF8)
+ QTextCodec* utf8_codec = QTextCodec::codecForName("UTF-8");
+ QTextCodec::setCodecForLocale(utf8_codec);
+#endif
+
// clean out standard Qt paths for plugins, which we don't use anyway
// when creating Mac bundles, it potentially causes problems
foreach(QString p, QApplication::libraryPaths())
@@ -107,16 +108,6 @@ int main(int argc, char** argv)
QApplication::removeLibraryPath(p);
}
- // if arg for install
- for(int i =0; i < argc; i++)
- {
- if(strcmp(argv[i], "--mac-install") == 0)
- {
- QMacInstallDialog setupdialog(0);
- setupdialog.exec();
- return 0;
- }
- }
// tell the cmake library where cmake is
QDir cmExecDir(QApplication::applicationDirPath());
#if defined(Q_OS_MAC)
@@ -144,7 +135,7 @@ int main(int argc, char** argv)
dialog.show();
cmsys::CommandLineArguments arg;
- arg.Initialize(argc, argv);
+ arg.Initialize(argc2, argv2);
std::string binaryDirectory;
std::string sourceDirectory;
typedef cmsys::CommandLineArguments argT;
@@ -165,10 +156,10 @@ int main(int argc, char** argv)
QStringList args = app.arguments();
if(args.count() == 2)
{
- cmsys_stl::string filePath = cmSystemTools::CollapseFullPath(args[1].toLocal8Bit().data());
+ std::string filePath = cmSystemTools::CollapseFullPath(args[1].toLocal8Bit().data());
// check if argument is a directory containing CMakeCache.txt
- cmsys_stl::string buildFilePath =
+ std::string buildFilePath =
cmSystemTools::CollapseFullPath("CMakeCache.txt", filePath.c_str());
// check if argument is a CMakeCache.txt file
@@ -179,7 +170,7 @@ int main(int argc, char** argv)
}
// check if argument is a directory containing CMakeLists.txt
- cmsys_stl::string srcFilePath =
+ std::string srcFilePath =
cmSystemTools::CollapseFullPath("CMakeLists.txt", filePath.c_str());
if(cmSystemTools::FileExists(buildFilePath.c_str()))
@@ -203,3 +194,54 @@ int main(int argc, char** argv)
return app.exec();
}
+#if defined(Q_OS_MAC)
+# include <errno.h>
+# include <string.h>
+# include <sys/stat.h>
+# include <unistd.h>
+static bool cmOSXInstall(std::string const& dir, std::string const& tool)
+{
+ if (tool.empty())
+ {
+ return true;
+ }
+ std::string link = dir + cmSystemTools::GetFilenameName(tool);
+ struct stat st;
+ if (lstat(link.c_str(), &st) == 0 && S_ISLNK(st.st_mode))
+ {
+ char buf[4096];
+ ssize_t s = readlink(link.c_str(), buf, sizeof(buf)-1);
+ if (s >= 0 && std::string(buf, s) == tool)
+ {
+ std::cerr << "Exists: '" << link << "' -> '" << tool << "'\n";
+ return true;
+ }
+ }
+ if (symlink(tool.c_str(), link.c_str()) == 0)
+ {
+ std::cerr << "Linked: '" << link << "' -> '" << tool << "'\n";
+ return true;
+ }
+ else
+ {
+ int err = errno;
+ std::cerr << "Failed: '" << link << "' -> '" << tool << "': "
+ << strerror(err) << "\n";
+ return false;
+ }
+}
+static int cmOSXInstall(std::string dir)
+{
+ if (!cmHasLiteralSuffix(dir, "/"))
+ {
+ dir += "/";
+ }
+ return (
+ cmOSXInstall(dir, cmSystemTools::GetCMakeCommand()) &&
+ cmOSXInstall(dir, cmSystemTools::GetCTestCommand()) &&
+ cmOSXInstall(dir, cmSystemTools::GetCPackCommand()) &&
+ cmOSXInstall(dir, cmSystemTools::GetCMakeGUICommand()) &&
+ cmOSXInstall(dir, cmSystemTools::GetCMakeCursesCommand())
+ ) ? 0 : 1;
+}
+#endif
diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx
index 4d62f7263..2fc4fafdc 100644
--- a/Source/QtDialog/CMakeSetupDialog.cxx
+++ b/Source/QtDialog/CMakeSetupDialog.cxx
@@ -27,13 +27,15 @@
#include <QUrl>
#include <QShortcut>
#include <QKeySequence>
-#include <QMacInstallDialog.h>
#include <QInputDialog>
#include "QCMake.h"
#include "QCMakeCacheView.h"
#include "AddCacheEntry.h"
#include "FirstConfigure.h"
+#include "RegexExplorer.h"
+#include "WarningMessagesDialog.h"
+#include "cmSystemTools.h"
#include "cmVersion.h"
QCMakeThread::QCMakeThread(QObject* p)
@@ -66,12 +68,13 @@ CMakeSetupDialog::CMakeSetupDialog()
// create the GUI
QSettings settings;
settings.beginGroup("Settings/StartPath");
- int h = settings.value("Height", 500).toInt();
- int w = settings.value("Width", 700).toInt();
- this->resize(w, h);
+ restoreGeometry(settings.value("geometry").toByteArray());
+ restoreState(settings.value("windowState").toByteArray());
- this->AddVariableCompletions = settings.value("AddVariableCompletionEntries",
+ this->AddVariableNames = settings.value("AddVariableNames",
QStringList("CMAKE_INSTALL_PREFIX")).toStringList();
+ this->AddVariableTypes = settings.value("AddVariableTypes",
+ QStringList("PATH")).toStringList();
QWidget* cont = new QWidget(this);
this->setupUi(cont);
@@ -117,13 +120,16 @@ CMakeSetupDialog::CMakeSetupDialog()
QAction* showChangesAction = ToolsMenu->addAction(tr("&Show My Changes"));
QObject::connect(showChangesAction, SIGNAL(triggered(bool)),
this, SLOT(showUserChanges()));
-#if defined(Q_WS_MAC)
+#if defined(Q_WS_MAC) || defined(Q_OS_MAC)
this->InstallForCommandLineAction
- = ToolsMenu->addAction(tr("&Install For Command Line Use"));
+ = ToolsMenu->addAction(tr("&How to Install For Command Line Use"));
QObject::connect(this->InstallForCommandLineAction, SIGNAL(triggered(bool)),
this, SLOT(doInstallForCommandLine()));
#endif
ToolsMenu->addSeparator();
+ ToolsMenu->addAction(tr("Regular Expression Explorer..."),
+ this, SLOT(doRegexExplorerDialog()));
+ ToolsMenu->addSeparator();
ToolsMenu->addAction(tr("&Find in Output..."),
this, SLOT(doOutputFindDialog()),
QKeySequence::Find);
@@ -140,9 +146,8 @@ CMakeSetupDialog::CMakeSetupDialog()
this, SLOT(doOutputErrorNext())); // in Eclipse
QMenu* OptionsMenu = this->menuBar()->addMenu(tr("&Options"));
- this->SuppressDevWarningsAction =
- OptionsMenu->addAction(tr("&Suppress dev Warnings (-Wno-dev)"));
- this->SuppressDevWarningsAction->setCheckable(true);
+ OptionsMenu->addAction(tr("Warning Messages..."),
+ this, SLOT(doWarningMessagesDialog()));
this->WarnUninitializedAction =
OptionsMenu->addAction(tr("&Warn Uninitialized (--warn-uninitialized)"));
this->WarnUninitializedAction->setCheckable(true);
@@ -273,9 +278,6 @@ void CMakeSetupDialog::initialize()
QObject::connect(this->AddEntry, SIGNAL(clicked(bool)),
this, SLOT(addCacheEntry()));
- QObject::connect(this->SuppressDevWarningsAction, SIGNAL(triggered(bool)),
- this->CMakeThread->cmakeInstance(), SLOT(setSuppressDevWarnings(bool)));
-
QObject::connect(this->WarnUninitializedAction, SIGNAL(triggered(bool)),
this->CMakeThread->cmakeInstance(),
SLOT(setWarnUninitializedMode(bool)));
@@ -299,8 +301,8 @@ CMakeSetupDialog::~CMakeSetupDialog()
{
QSettings settings;
settings.beginGroup("Settings/StartPath");
- settings.setValue("Height", this->height());
- settings.setValue("Width", this->width());
+ settings.setValue("windowState", QVariant(saveState()));
+ settings.setValue("geometry", QVariant(saveGeometry()));
settings.setValue("SplitterSizes", this->Splitter->saveState());
// wait for thread to stop
@@ -418,8 +420,38 @@ bool CMakeSetupDialog::doConfigureInternal()
void CMakeSetupDialog::doInstallForCommandLine()
{
- QMacInstallDialog setupdialog(0);
- setupdialog.exec();
+ QString title = tr("How to Install For Command Line Use");
+ QString msg = tr(
+ "One may add CMake to the PATH:\n"
+ "\n"
+ " PATH=\"%1\":\"$PATH\"\n"
+ "\n"
+ "Or, to install symlinks to '/usr/local/bin', run:\n"
+ "\n"
+ " sudo \"%2\" --install\n"
+ "\n"
+ "Or, to install symlinks to another directory, run:\n"
+ "\n"
+ " sudo \"%3\" --install=/path/to/bin\n"
+ );
+ msg = msg.arg(cmSystemTools::GetFilenamePath(
+ cmSystemTools::GetCMakeCommand()).c_str());
+ msg = msg.arg(cmSystemTools::GetCMakeGUICommand().c_str());
+ msg = msg.arg(cmSystemTools::GetCMakeGUICommand().c_str());
+
+ QDialog dialog;
+ dialog.setWindowTitle(title);
+ QVBoxLayout* l = new QVBoxLayout(&dialog);
+ QLabel* lab = new QLabel(&dialog);
+ l->addWidget(lab);
+ lab->setText(msg);
+ lab->setWordWrap(false);
+ lab->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ QDialogButtonBox* btns = new QDialogButtonBox(QDialogButtonBox::Ok,
+ Qt::Horizontal, &dialog);
+ QObject::connect(btns, SIGNAL(accepted()), &dialog, SLOT(accept()));
+ l->addWidget(btns);
+ dialog.exec();
}
bool CMakeSetupDialog::doGenerateInternal()
@@ -576,7 +608,8 @@ void CMakeSetupDialog::doInterrupt()
void CMakeSetupDialog::doSourceBrowse()
{
QString dir = QFileDialog::getExistingDirectory(this,
- tr("Enter Path to Source"), this->SourceDirectory->text());
+ tr("Enter Path to Source"), this->SourceDirectory->text(),
+ QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
if(!dir.isEmpty())
{
this->setSourceDirectory(dir);
@@ -606,7 +639,8 @@ void CMakeSetupDialog::updateBinaryDirectory(const QString& dir)
void CMakeSetupDialog::doBinaryBrowse()
{
QString dir = QFileDialog::getExistingDirectory(this,
- tr("Enter Path to Build"), this->BinaryDirectory->currentText());
+ tr("Enter Path to Build"), this->BinaryDirectory->currentText(),
+ QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
if(!dir.isEmpty() && dir != this->BinaryDirectory->currentText())
{
this->setBinaryDirectory(dir);
@@ -701,6 +735,7 @@ bool CMakeSetupDialog::setupFirstConfigure()
{
dialog.saveToSettings();
this->CMakeThread->cmakeInstance()->setGenerator(dialog.getGenerator());
+ this->CMakeThread->cmakeInstance()->setToolset(dialog.getToolset());
QCMakeCacheModel* m = this->CacheValues->cacheModel();
@@ -752,6 +787,9 @@ bool CMakeSetupDialog::setupFirstConfigure()
QString systemName = dialog.getSystemName();
m->insertProperty(QCMakeProperty::STRING, "CMAKE_SYSTEM_NAME",
tr("CMake System Name"), systemName, false);
+ QString systemVersion = dialog.getSystemVersion();
+ m->insertProperty(QCMakeProperty::STRING, "CMAKE_SYSTEM_VERSION",
+ tr("CMake System Version"), systemVersion, false);
QString cxxCompiler = dialog.getCXXCompiler();
m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_CXX_COMPILER",
tr("CXX compiler."), cxxCompiler, false);
@@ -808,12 +846,26 @@ void CMakeSetupDialog::doDeleteCache()
void CMakeSetupDialog::doAbout()
{
- QString msg = tr("CMake %1\n"
- "Using Qt %2\n"
- "www.cmake.org");
-
+ QString msg = tr(
+ "CMake %1 (cmake.org).\n"
+ "CMake suite maintained and supported by Kitware (kitware.com/cmake).\n"
+ "Distributed under terms of the BSD 3-Clause License.\n"
+ "\n"
+ "CMake GUI maintained by csimsoft,\n"
+ "built using Qt %2 (qt-project.org).\n"
+#ifdef CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL
+ "\n"
+ "The Qt Toolkit is Copyright (C) Digia Plc and/or its subsidiary(-ies).\n"
+ "Qt is licensed under terms of the GNU LGPLv2.1, available at:\n"
+ " \"%3\""
+#endif
+ );
msg = msg.arg(cmVersion::GetCMakeVersion());
msg = msg.arg(qVersion());
+#ifdef CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL
+ std::string lgpl = cmSystemTools::GetCMakeRoot()+"/Licenses/LGPLv2.1.txt";
+ msg = msg.arg(lgpl.c_str());
+#endif
QDialog dialog;
dialog.setWindowTitle(tr("About"));
@@ -947,6 +999,7 @@ void CMakeSetupDialog::saveBuildPaths(const QStringList& paths)
void CMakeSetupDialog::setCacheModified()
{
this->CacheModified = true;
+ this->ConfigureNeeded = true;
this->enterState(ReadyConfigure);
}
@@ -1034,7 +1087,8 @@ void CMakeSetupDialog::addCacheEntry()
dialog.resize(400, 200);
dialog.setWindowTitle(tr("Add Cache Entry"));
QVBoxLayout* l = new QVBoxLayout(&dialog);
- AddCacheEntry* w = new AddCacheEntry(&dialog, this->AddVariableCompletions);
+ AddCacheEntry* w = new AddCacheEntry(&dialog, this->AddVariableNames,
+ this->AddVariableTypes);
QDialogButtonBox* btns = new QDialogButtonBox(
QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
Qt::Horizontal, &dialog);
@@ -1049,23 +1103,26 @@ void CMakeSetupDialog::addCacheEntry()
m->insertProperty(w->type(), w->name(), w->description(), w->value(), false);
// only add variable names to the completion which are new
- if (!this->AddVariableCompletions.contains(w->name()))
+ if (!this->AddVariableNames.contains(w->name()))
{
- this->AddVariableCompletions << w->name();
+ this->AddVariableNames << w->name();
+ this->AddVariableTypes << w->typeString();
// limit to at most 100 completion items
- if (this->AddVariableCompletions.size() > 100)
+ if (this->AddVariableNames.size() > 100)
{
- this->AddVariableCompletions.removeFirst();
+ this->AddVariableNames.removeFirst();
+ this->AddVariableTypes.removeFirst();
}
// make sure CMAKE_INSTALL_PREFIX is always there
- if (!this->AddVariableCompletions.contains("CMAKE_INSTALL_PREFIX"))
+ if (!this->AddVariableNames.contains("CMAKE_INSTALL_PREFIX"))
{
- this->AddVariableCompletions << QString("CMAKE_INSTALL_PREFIX");
+ this->AddVariableNames << "CMAKE_INSTALL_PREFIX";
+ this->AddVariableTypes << "PATH";
}
QSettings settings;
settings.beginGroup("Settings/StartPath");
- settings.setValue("AddVariableCompletionEntries",
- this->AddVariableCompletions);
+ settings.setValue("AddVariableNames", this->AddVariableNames);
+ settings.setValue("AddVariableTypes", this->AddVariableTypes);
}
}
}
@@ -1216,6 +1273,12 @@ void CMakeSetupDialog::doOutputFindDialog()
}
}
+void CMakeSetupDialog::doRegexExplorerDialog()
+{
+ RegexExplorer dialog(this);
+ dialog.exec();
+}
+
void CMakeSetupDialog::doOutputFindPrev()
{
doOutputFindNext(false);
@@ -1231,7 +1294,7 @@ void CMakeSetupDialog::doOutputFindNext(bool directionForward)
QString search = this->FindHistory.front();
- QTextCursor cursor = this->Output->textCursor();
+ QTextCursor textCursor = this->Output->textCursor();
QTextDocument* document = this->Output->document();
QTextDocument::FindFlags flags;
if (!directionForward)
@@ -1239,67 +1302,73 @@ void CMakeSetupDialog::doOutputFindNext(bool directionForward)
flags |= QTextDocument::FindBackward;
}
- cursor = document->find(search, cursor, flags);
+ textCursor = document->find(search, textCursor, flags);
- if (cursor.isNull())
+ if (textCursor.isNull())
{
// first search found nothing, wrap around and search again
- cursor = this->Output->textCursor();
- cursor.movePosition(directionForward ? QTextCursor::Start
- : QTextCursor::End);
- cursor = document->find(search, cursor, flags);
+ textCursor = this->Output->textCursor();
+ textCursor.movePosition(directionForward ? QTextCursor::Start
+ : QTextCursor::End);
+ textCursor = document->find(search, textCursor, flags);
}
- if (cursor.hasSelection())
+ if (textCursor.hasSelection())
{
- this->Output->setTextCursor(cursor);
+ this->Output->setTextCursor(textCursor);
}
}
void CMakeSetupDialog::doOutputErrorNext()
{
- QTextCursor cursor = this->Output->textCursor();
+ QTextCursor textCursor = this->Output->textCursor();
bool atEnd = false;
// move cursor out of current error-block
- if (cursor.blockCharFormat() == this->ErrorFormat)
+ if (textCursor.blockCharFormat() == this->ErrorFormat)
{
- atEnd = !cursor.movePosition(QTextCursor::NextBlock);
+ atEnd = !textCursor.movePosition(QTextCursor::NextBlock);
}
// move cursor to next error-block
- while (cursor.blockCharFormat() != this->ErrorFormat && !atEnd)
+ while (textCursor.blockCharFormat() != this->ErrorFormat && !atEnd)
{
- atEnd = !cursor.movePosition(QTextCursor::NextBlock);
+ atEnd = !textCursor.movePosition(QTextCursor::NextBlock);
}
if (atEnd)
{
// first search found nothing, wrap around and search again
- atEnd = !cursor.movePosition(QTextCursor::Start);
+ atEnd = !textCursor.movePosition(QTextCursor::Start);
// move cursor to next error-block
- while (cursor.blockCharFormat() != this->ErrorFormat && !atEnd)
+ while (textCursor.blockCharFormat() != this->ErrorFormat && !atEnd)
{
- atEnd = !cursor.movePosition(QTextCursor::NextBlock);
+ atEnd = !textCursor.movePosition(QTextCursor::NextBlock);
}
}
if (!atEnd)
{
- cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
+ textCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
QTextCharFormat selectionFormat;
selectionFormat.setBackground(Qt::yellow);
- QTextEdit::ExtraSelection extraSelection = {cursor, selectionFormat};
+ QTextEdit::ExtraSelection extraSelection = {textCursor, selectionFormat};
this->Output->setExtraSelections(QList<QTextEdit::ExtraSelection>()
<< extraSelection);
// make the whole error-block visible
- this->Output->setTextCursor(cursor);
+ this->Output->setTextCursor(textCursor);
// remove the selection to see the extraSelection
- cursor.setPosition(cursor.anchor());
- this->Output->setTextCursor(cursor);
+ textCursor.setPosition(textCursor.anchor());
+ this->Output->setTextCursor(textCursor);
}
}
+
+void CMakeSetupDialog::doWarningMessagesDialog()
+{
+ WarningMessagesDialog dialog(this, this->CMakeThread->cmakeInstance());
+ dialog.exec();
+}
diff --git a/Source/QtDialog/CMakeSetupDialog.h b/Source/QtDialog/CMakeSetupDialog.h
index 963c7d12e..4b53b1cbd 100644
--- a/Source/QtDialog/CMakeSetupDialog.h
+++ b/Source/QtDialog/CMakeSetupDialog.h
@@ -82,6 +82,9 @@ protected slots:
void doOutputFindNext(bool directionForward = true);
void doOutputFindPrev();
void doOutputErrorNext();
+ void doRegexExplorerDialog();
+ /// display the modal warning messages dialog window
+ void doWarningMessagesDialog();
protected:
@@ -101,7 +104,6 @@ protected:
QAction* ExitAction;
QAction* ConfigureAction;
QAction* GenerateAction;
- QAction* SuppressDevWarningsAction;
QAction* WarnUninitializedAction;
QAction* WarnUnusedAction;
QAction* InstallForCommandLineAction;
@@ -110,7 +112,8 @@ protected:
QTextCharFormat ErrorFormat;
QTextCharFormat MessageFormat;
- QStringList AddVariableCompletions;
+ QStringList AddVariableNames;
+ QStringList AddVariableTypes;
QStringList FindHistory;
QEventLoop LocalLoop;
diff --git a/Source/QtDialog/CMakeSetupDialog.ui b/Source/QtDialog/CMakeSetupDialog.ui
index 98da249d5..b04bd93ae 100644
--- a/Source/QtDialog/CMakeSetupDialog.ui
+++ b/Source/QtDialog/CMakeSetupDialog.ui
@@ -134,7 +134,7 @@
</property>
<property name="sizeHint" stdset="0">
<size>
- <width>40</width>
+ <width>12</width>
<height>23</height>
</size>
</property>
diff --git a/Source/QtDialog/FirstConfigure.cxx b/Source/QtDialog/FirstConfigure.cxx
index 6de9f00cc..61aad72e0 100644
--- a/Source/QtDialog/FirstConfigure.cxx
+++ b/Source/QtDialog/FirstConfigure.cxx
@@ -15,6 +15,11 @@ StartCompilerSetup::StartCompilerSetup(QWidget* p)
l->addWidget(new QLabel(tr("Specify the generator for this project")));
this->GeneratorOptions = new QComboBox(this);
l->addWidget(this->GeneratorOptions);
+
+ // Add the ability to specify toolset (-T parameter)
+ ToolsetFrame = CreateToolsetWidgets();
+ l->addWidget(ToolsetFrame);
+
l->addSpacing(6);
this->CompilerSetupOptions[0] = new QRadioButton(tr("Use default native compilers"), this);
@@ -36,17 +41,51 @@ StartCompilerSetup::StartCompilerSetup(QWidget* p)
this, SLOT(onSelectionChanged(bool)));
QObject::connect(this->CompilerSetupOptions[3], SIGNAL(toggled(bool)),
this, SLOT(onSelectionChanged(bool)));
+ QObject::connect(GeneratorOptions,
+ SIGNAL(currentIndexChanged(QString const&)),
+ this, SLOT(onGeneratorChanged(QString const&)));
+}
+
+QFrame* StartCompilerSetup::CreateToolsetWidgets()
+{
+ QFrame* frame = new QFrame(this);
+ QVBoxLayout* l = new QVBoxLayout(frame);
+ l->setContentsMargins(0, 0, 0, 0);
+
+ ToolsetLabel = new QLabel(tr("Optional toolset to use (-T parameter)"));
+ l->addWidget(ToolsetLabel);
+
+ Toolset = new QLineEdit(frame);
+ l->addWidget(Toolset);
+
+ return frame;
}
StartCompilerSetup::~StartCompilerSetup()
{
}
-void StartCompilerSetup::setGenerators(const QStringList& gens)
+void StartCompilerSetup::setGenerators(
+ std::vector<cmake::GeneratorInfo> const& gens)
{
this->GeneratorOptions->clear();
- this->GeneratorOptions->addItems(gens);
-};
+
+ QStringList generator_list;
+
+ std::vector<cmake::GeneratorInfo>::const_iterator it;
+ for (it = gens.begin(); it != gens.end(); ++it)
+ {
+ generator_list.append(QString::fromLocal8Bit(it->name.c_str()));
+
+ if (it->supportsToolset)
+ {
+ this->GeneratorsSupportingToolset.append(
+ QString::fromLocal8Bit(it->name.c_str()));
+ }
+ }
+
+ this->GeneratorOptions->addItems(generator_list);
+}
void StartCompilerSetup::setCurrentGenerator(const QString& gen)
{
@@ -62,6 +101,11 @@ QString StartCompilerSetup::getGenerator() const
return this->GeneratorOptions->currentText();
};
+QString StartCompilerSetup::getToolset() const
+{
+ return this->Toolset->text();
+};
+
bool StartCompilerSetup::defaultSetup() const
{
return this->CompilerSetupOptions[0]->isChecked();
@@ -88,6 +132,18 @@ void StartCompilerSetup::onSelectionChanged(bool on)
selectionChanged();
}
+void StartCompilerSetup::onGeneratorChanged(QString const& name)
+{
+ if (GeneratorsSupportingToolset.contains(name))
+ {
+ ToolsetFrame->show();
+ }
+ else
+ {
+ ToolsetFrame->hide();
+ }
+}
+
int StartCompilerSetup::nextId() const
{
if(compilerSetup())
@@ -325,7 +381,8 @@ FirstConfigure::~FirstConfigure()
{
}
-void FirstConfigure::setGenerators(const QStringList& gens)
+void FirstConfigure::setGenerators(
+ std::vector<cmake::GeneratorInfo> const& gens)
{
this->mStartCompilerSetupPage->setGenerators(gens);
}
@@ -335,6 +392,11 @@ QString FirstConfigure::getGenerator() const
return this->mStartCompilerSetupPage->getGenerator();
}
+QString FirstConfigure::getToolset() const
+{
+ return this->mStartCompilerSetupPage->getToolset();
+}
+
void FirstConfigure::loadFromSettings()
{
QSettings settings;
diff --git a/Source/QtDialog/FirstConfigure.h b/Source/QtDialog/FirstConfigure.h
index be390b0fd..09952b650 100644
--- a/Source/QtDialog/FirstConfigure.h
+++ b/Source/QtDialog/FirstConfigure.h
@@ -4,6 +4,7 @@
#include <QWizard>
#include <QWizardPage>
+#include "cmake.h"
#include "ui_Compilers.h"
#include "ui_CrossCompiler.h"
@@ -27,9 +28,10 @@ class StartCompilerSetup : public QWizardPage
public:
StartCompilerSetup(QWidget* p);
~StartCompilerSetup();
- void setGenerators(const QStringList& gens);
+ void setGenerators(std::vector<cmake::GeneratorInfo> const& gens);
void setCurrentGenerator(const QString& gen);
QString getGenerator() const;
+ QString getToolset() const;
bool defaultSetup() const;
bool compilerSetup() const;
@@ -43,10 +45,18 @@ class StartCompilerSetup : public QWizardPage
protected slots:
void onSelectionChanged(bool);
+ void onGeneratorChanged(QString const& name);
protected:
QComboBox* GeneratorOptions;
QRadioButton* CompilerSetupOptions[4];
+ QFrame* ToolsetFrame;
+ QLineEdit* Toolset;
+ QLabel* ToolsetLabel;
+ QStringList GeneratorsSupportingToolset;
+
+ private:
+ QFrame* CreateToolsetWidgets();
};
//! the page that gives basic options for native compilers
@@ -140,8 +150,9 @@ public:
FirstConfigure();
~FirstConfigure();
- void setGenerators(const QStringList& gens);
+ void setGenerators(std::vector<cmake::GeneratorInfo> const& gens);
QString getGenerator() const;
+ QString getToolset() const;
bool defaultSetup() const;
bool compilerSetup() const;
diff --git a/Source/QtDialog/Info.plist.in b/Source/QtDialog/Info.plist.in
new file mode 100644
index 000000000..00a27c39c
--- /dev/null
+++ b/Source/QtDialog/Info.plist.in
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
+ <key>CFBundleIconFile</key>
+ <string>${MACOSX_BUNDLE_ICON_FILE}</string>
+ <key>CFBundleIdentifier</key>
+ <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
+ <key>CSResourcesFileMapped</key>
+ <true/>
+ <key>LSApplicationCategoryType</key>
+ <string>public.app-category.developer-tools</string>
+ <key>NSHumanReadableCopyright</key>
+ <string>${MACOSX_BUNDLE_COPYRIGHT}</string>
+ <key>NSHighResolutionCapable</key>
+ <true/>
+</dict>
+</plist>
diff --git a/Source/QtDialog/MacInstallDialog.ui b/Source/QtDialog/MacInstallDialog.ui
deleted file mode 100644
index c7e31dbbe..000000000
--- a/Source/QtDialog/MacInstallDialog.ui
+++ /dev/null
@@ -1,103 +0,0 @@
-<ui version="4.0" >
- <class>Dialog</class>
- <widget class="QDialog" name="Dialog" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>470</width>
- <height>159</height>
- </rect>
- </property>
- <property name="windowTitle" >
- <string>Install Command Line Tools</string>
- </property>
- <layout class="QGridLayout" >
- <property name="margin" >
- <number>9</number>
- </property>
- <property name="spacing" >
- <number>6</number>
- </property>
- <item row="3" column="1" >
- <spacer>
- <property name="orientation" >
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" >
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="2" column="0" colspan="3" >
- <layout class="QHBoxLayout" >
- <property name="margin" >
- <number>0</number>
- </property>
- <property name="spacing" >
- <number>6</number>
- </property>
- <item>
- <spacer>
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" >
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="skipInstallButton" >
- <property name="text" >
- <string>Skip Install Command Line </string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="doInstallButton" >
- <property name="text" >
- <string>Install Command Line Links</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="0" column="2" >
- <widget class="QPushButton" name="choosePathButton" >
- <property name="text" >
- <string>Choose...</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0" >
- <widget class="QLabel" name="label" >
- <property name="text" >
- <string>Install Folder:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1" >
- <widget class="QLineEdit" name="InstallPrefix" />
- </item>
- <item row="1" column="0" colspan="3" >
- <widget class="QLabel" name="label_2" >
- <property name="text" >
- <string>This will create symbolic links to the command line tools of cmake into the specified install folder.</string>
- </property>
- <property name="wordWrap" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx
index 0d0118164..dd7c1387a 100644
--- a/Source/QtDialog/QCMake.cxx
+++ b/Source/QtDialog/QCMake.cxx
@@ -15,8 +15,7 @@
#include <QDir>
#include <QCoreApplication>
-#include "cmake.h"
-#include "cmCacheManager.h"
+#include "cmState.h"
#include "cmSystemTools.h"
#include "cmExternalMakefileProjectGenerator.h"
@@ -27,59 +26,41 @@
QCMake::QCMake(QObject* p)
: QObject(p)
{
- this->SuppressDevWarnings = false;
this->WarnUninitializedMode = false;
this->WarnUnusedMode = false;
qRegisterMetaType<QCMakeProperty>();
qRegisterMetaType<QCMakePropertyList>();
- QDir execDir(QCoreApplication::applicationDirPath());
-
-#if defined(Q_OS_MAC)
- if(execDir.exists("../bin/cmake"))
- {
- execDir.cd("../bin");
- }
- else
- {
- execDir.cd("../../../"); // path to cmake in build directory (need to fix for deployment)
- }
-#endif
-
- QString cmakeCommand = QString("cmake")+QString::fromLocal8Bit(cmSystemTools::GetExecutableExtension());
- cmakeCommand = execDir.filePath(cmakeCommand);
-
cmSystemTools::DisableRunCommandOutput();
cmSystemTools::SetRunCommandHideConsole(true);
- cmSystemTools::SetErrorCallback(QCMake::errorCallback, this);
- cmSystemTools::FindExecutableDirectory(cmakeCommand.toLocal8Bit().data());
+ cmSystemTools::SetMessageCallback(QCMake::messageCallback, this);
+ cmSystemTools::SetStdoutCallback(QCMake::stdoutCallback, this);
+ cmSystemTools::SetStderrCallback(QCMake::stderrCallback, this);
this->CMakeInstance = new cmake;
- this->CMakeInstance->SetCMakeCommand(cmakeCommand.toLocal8Bit().data());
-#if defined(Q_OS_MAC)
- this->CMakeInstance->SetCMakeEditCommand("cmake-gui.app/Contents/MacOS/cmake-gui");
-#else
- this->CMakeInstance->SetCMakeEditCommand("cmake-gui");
-#endif
+ this->CMakeInstance->SetCMakeEditCommand(
+ cmSystemTools::GetCMakeGUICommand());
this->CMakeInstance->SetProgressCallback(QCMake::progressCallback, this);
cmSystemTools::SetInterruptCallback(QCMake::interruptCallback, this);
- std::vector<std::string> generators;
+ std::vector<cmake::GeneratorInfo> generators;
this->CMakeInstance->GetRegisteredGenerators(generators);
- std::vector<std::string>::iterator iter;
- for(iter = generators.begin(); iter != generators.end(); ++iter)
+
+ std::vector<cmake::GeneratorInfo>::const_iterator it;
+ for(it = generators.begin(); it != generators.end(); ++it)
{
// Skip the generator "KDevelop3", since there is also
// "KDevelop3 - Unix Makefiles", which is the full and official name.
// The short name is actually only still there since this was the name
// in CMake 2.4, to keep "command line argument compatibility", but
// this is not necessary in the GUI.
- if (*iter == "KDevelop3")
+ if (it->name == "KDevelop3")
{
continue;
}
- this->AvailableGenerators.append(QString::fromLocal8Bit(iter->c_str()));
+
+ this->AvailableGenerators.push_back(*it);
}
}
@@ -113,9 +94,10 @@ void QCMake::setBinaryDirectory(const QString& _dir)
{
this->BinaryDirectory = QDir::fromNativeSeparators(dir);
emit this->binaryDirChanged(this->BinaryDirectory);
- cmCacheManager *cachem = this->CMakeInstance->GetCacheManager();
+ cmState* state = this->CMakeInstance->GetState();
this->setGenerator(QString());
- if(!this->CMakeInstance->GetCacheManager()->LoadCache(
+ this->setToolset(QString());
+ if(!this->CMakeInstance->LoadCache(
this->BinaryDirectory.toLocal8Bit().data()))
{
QDir testDir(this->BinaryDirectory);
@@ -129,18 +111,26 @@ void QCMake::setBinaryDirectory(const QString& _dir)
QCMakePropertyList props = this->properties();
emit this->propertiesChanged(props);
- cmCacheManager::CacheIterator itm = cachem->NewIterator();
- if ( itm.Find("CMAKE_HOME_DIRECTORY"))
+ const char* homeDir = state->GetCacheEntryValue("CMAKE_HOME_DIRECTORY");
+ if (homeDir)
{
- setSourceDirectory(QString::fromLocal8Bit(itm.GetValue()));
+ setSourceDirectory(QString::fromLocal8Bit(homeDir));
}
- if ( itm.Find("CMAKE_GENERATOR"))
+ const char* gen = state->GetCacheEntryValue("CMAKE_GENERATOR");
+ if (gen)
{
- const char* extraGen = cachem->GetCacheValue("CMAKE_EXTRA_GENERATOR");
+ const char* extraGen = state
+ ->GetInitializedCacheValue("CMAKE_EXTRA_GENERATOR");
std::string curGen = cmExternalMakefileProjectGenerator::
- CreateFullGeneratorName(itm.GetValue(), extraGen);
+ CreateFullGeneratorName(gen, extraGen? extraGen : "");
this->setGenerator(QString::fromLocal8Bit(curGen.c_str()));
}
+
+ const char* toolset = state->GetCacheEntryValue("CMAKE_GENERATOR_TOOLSET");
+ if (toolset)
+ {
+ this->setToolset(QString::fromLocal8Bit(toolset));
+ }
}
}
@@ -154,6 +144,15 @@ void QCMake::setGenerator(const QString& gen)
}
}
+void QCMake::setToolset(const QString& toolset)
+{
+ if(this->Toolset != toolset)
+ {
+ this->Toolset = toolset;
+ emit this->toolsetChanged(this->Toolset);
+ }
+}
+
void QCMake::configure()
{
#ifdef Q_OS_WIN
@@ -161,13 +160,12 @@ void QCMake::configure()
#endif
this->CMakeInstance->SetHomeDirectory(this->SourceDirectory.toLocal8Bit().data());
- this->CMakeInstance->SetStartDirectory(this->SourceDirectory.toLocal8Bit().data());
this->CMakeInstance->SetHomeOutputDirectory(this->BinaryDirectory.toLocal8Bit().data());
- this->CMakeInstance->SetStartOutputDirectory(this->BinaryDirectory.toLocal8Bit().data());
this->CMakeInstance->SetGlobalGenerator(
this->CMakeInstance->CreateGlobalGenerator(this->Generator.toLocal8Bit().data()));
+ this->CMakeInstance->SetGeneratorPlatform("");
+ this->CMakeInstance->SetGeneratorToolset(this->Toolset.toLocal8Bit().data());
this->CMakeInstance->LoadCache();
- this->CMakeInstance->SetSuppressDevWarnings(this->SuppressDevWarnings);
this->CMakeInstance->SetWarnUninitialized(this->WarnUninitializedMode);
this->CMakeInstance->SetWarnUnused(this->WarnUnusedMode);
this->CMakeInstance->PreLoadCMakeFiles();
@@ -210,34 +208,36 @@ void QCMake::setProperties(const QCMakePropertyList& newProps)
QStringList toremove;
// set the value of properties
- cmCacheManager *cachem = this->CMakeInstance->GetCacheManager();
- for(cmCacheManager::CacheIterator i = cachem->NewIterator();
- !i.IsAtEnd(); i.Next())
+ cmState* state = this->CMakeInstance->GetState();
+ std::vector<std::string> cacheKeys = state->GetCacheEntryKeys();
+ for(std::vector<std::string>::const_iterator it = cacheKeys.begin();
+ it != cacheKeys.end(); ++it)
{
-
- if(i.GetType() == cmCacheManager::INTERNAL ||
- i.GetType() == cmCacheManager::STATIC)
+ cmState::CacheEntryType t = state->GetCacheEntryType(*it);
+ if(t == cmState::INTERNAL ||
+ t == cmState::STATIC)
{
continue;
}
QCMakeProperty prop;
- prop.Key = QString::fromLocal8Bit(i.GetName());
+ prop.Key = QString::fromLocal8Bit(it->c_str());
int idx = props.indexOf(prop);
if(idx == -1)
{
- toremove.append(QString::fromLocal8Bit(i.GetName()));
+ toremove.append(QString::fromLocal8Bit(it->c_str()));
}
else
{
prop = props[idx];
if(prop.Value.type() == QVariant::Bool)
{
- i.SetValue(prop.Value.toBool() ? "ON" : "OFF");
+ state->SetCacheEntryValue(*it, prop.Value.toBool() ? "ON" : "OFF");
}
else
{
- i.SetValue(prop.Value.toString().toLocal8Bit().data());
+ state->SetCacheEntryValue(*it,
+ prop.Value.toString().toLocal8Bit().data());
}
props.removeAt(idx);
}
@@ -249,7 +249,7 @@ void QCMake::setProperties(const QCMakePropertyList& newProps)
{
this->CMakeInstance->UnwatchUnusedCli(s.toLocal8Bit().data());
- cachem->RemoveCacheEntry(s.toLocal8Bit().data());
+ state->RemoveCacheEntry(s.toLocal8Bit().data());
}
// add some new properites
@@ -262,75 +262,80 @@ void QCMake::setProperties(const QCMakePropertyList& newProps)
this->CMakeInstance->AddCacheEntry(s.Key.toLocal8Bit().data(),
s.Value.toBool() ? "ON" : "OFF",
s.Help.toLocal8Bit().data(),
- cmCacheManager::BOOL);
+ cmState::BOOL);
}
else if(s.Type == QCMakeProperty::STRING)
{
this->CMakeInstance->AddCacheEntry(s.Key.toLocal8Bit().data(),
s.Value.toString().toLocal8Bit().data(),
s.Help.toLocal8Bit().data(),
- cmCacheManager::STRING);
+ cmState::STRING);
}
else if(s.Type == QCMakeProperty::PATH)
{
this->CMakeInstance->AddCacheEntry(s.Key.toLocal8Bit().data(),
s.Value.toString().toLocal8Bit().data(),
s.Help.toLocal8Bit().data(),
- cmCacheManager::PATH);
+ cmState::PATH);
}
else if(s.Type == QCMakeProperty::FILEPATH)
{
this->CMakeInstance->AddCacheEntry(s.Key.toLocal8Bit().data(),
s.Value.toString().toLocal8Bit().data(),
s.Help.toLocal8Bit().data(),
- cmCacheManager::FILEPATH);
+ cmState::FILEPATH);
}
}
- cachem->SaveCache(this->BinaryDirectory.toLocal8Bit().data());
+ this->CMakeInstance->SaveCache(this->BinaryDirectory.toLocal8Bit().data());
}
QCMakePropertyList QCMake::properties() const
{
QCMakePropertyList ret;
- cmCacheManager *cachem = this->CMakeInstance->GetCacheManager();
- for(cmCacheManager::CacheIterator i = cachem->NewIterator();
- !i.IsAtEnd(); i.Next())
+ cmState* state = this->CMakeInstance->GetState();
+ std::vector<std::string> cacheKeys = state->GetCacheEntryKeys();
+ for (std::vector<std::string>::const_iterator i = cacheKeys.begin();
+ i != cacheKeys.end(); ++i)
{
-
- if(i.GetType() == cmCacheManager::INTERNAL ||
- i.GetType() == cmCacheManager::STATIC ||
- i.GetType() == cmCacheManager::UNINITIALIZED)
+ cmState::CacheEntryType t = state->GetCacheEntryType(*i);
+ if(t == cmState::INTERNAL ||
+ t == cmState::STATIC ||
+ t == cmState::UNINITIALIZED)
{
continue;
}
- QCMakeProperty prop;
- prop.Key = QString::fromLocal8Bit(i.GetName());
- prop.Help = QString::fromLocal8Bit(i.GetProperty("HELPSTRING"));
- prop.Value = QString::fromLocal8Bit(i.GetValue());
- prop.Advanced = i.GetPropertyAsBool("ADVANCED");
+ const char* cachedValue = state->GetCacheEntryValue(*i);
- if(i.GetType() == cmCacheManager::BOOL)
+ QCMakeProperty prop;
+ prop.Key = QString::fromLocal8Bit(i->c_str());
+ prop.Help = QString::fromLocal8Bit(
+ state->GetCacheEntryProperty(*i, "HELPSTRING"));
+ prop.Value = QString::fromLocal8Bit(cachedValue);
+ prop.Advanced = state->GetCacheEntryPropertyAsBool(*i, "ADVANCED");
+ if(t == cmState::BOOL)
{
prop.Type = QCMakeProperty::BOOL;
- prop.Value = cmSystemTools::IsOn(i.GetValue());
+ prop.Value = cmSystemTools::IsOn(cachedValue);
}
- else if(i.GetType() == cmCacheManager::PATH)
+ else if(t == cmState::PATH)
{
prop.Type = QCMakeProperty::PATH;
}
- else if(i.GetType() == cmCacheManager::FILEPATH)
+ else if(t == cmState::FILEPATH)
{
prop.Type = QCMakeProperty::FILEPATH;
}
- else if(i.GetType() == cmCacheManager::STRING)
+ else if(t == cmState::STRING)
{
prop.Type = QCMakeProperty::STRING;
- if (i.PropertyExists("STRINGS"))
+ const char* stringsProperty =
+ state->GetCacheEntryProperty(*i, "STRINGS");
+ if (stringsProperty)
{
- prop.Strings = QString::fromLocal8Bit(i.GetProperty("STRINGS")).split(";");
+ prop.Strings = QString::fromLocal8Bit(stringsProperty).split(";");
}
}
@@ -369,14 +374,28 @@ void QCMake::progressCallback(const char* msg, float percent, void* cd)
QCoreApplication::processEvents();
}
-void QCMake::errorCallback(const char* msg, const char* /*title*/,
- bool& /*stop*/, void* cd)
+void QCMake::messageCallback(const char* msg, const char* /*title*/,
+ bool& /*stop*/, void* cd)
{
QCMake* self = reinterpret_cast<QCMake*>(cd);
emit self->errorMessage(QString::fromLocal8Bit(msg));
QCoreApplication::processEvents();
}
+void QCMake::stdoutCallback(const char* msg, size_t len, void* cd)
+{
+ QCMake* self = reinterpret_cast<QCMake*>(cd);
+ emit self->outputMessage(QString::fromLocal8Bit(msg,int(len)));
+ QCoreApplication::processEvents();
+}
+
+void QCMake::stderrCallback(const char* msg, size_t len, void* cd)
+{
+ QCMake* self = reinterpret_cast<QCMake*>(cd);
+ emit self->outputMessage(QString::fromLocal8Bit(msg,int(len)));
+ QCoreApplication::processEvents();
+}
+
QString QCMake::binaryDirectory() const
{
return this->BinaryDirectory;
@@ -392,19 +411,20 @@ QString QCMake::generator() const
return this->Generator;
}
-QStringList QCMake::availableGenerators() const
+std::vector<cmake::GeneratorInfo> const& QCMake::availableGenerators() const
{
- return this->AvailableGenerators;
+ return AvailableGenerators;
}
void QCMake::deleteCache()
{
// delete cache
- this->CMakeInstance->GetCacheManager()->DeleteCache(this->BinaryDirectory.toLocal8Bit().data());
+ this->CMakeInstance->DeleteCache(this->BinaryDirectory.toLocal8Bit().data());
// reload to make our cache empty
- this->CMakeInstance->GetCacheManager()->LoadCache(this->BinaryDirectory.toLocal8Bit().data());
+ this->CMakeInstance->LoadCache(this->BinaryDirectory.toLocal8Bit().data());
// emit no generator and no properties
this->setGenerator(QString());
+ this->setToolset(QString());
QCMakePropertyList props = this->properties();
emit this->propertiesChanged(props);
}
@@ -415,7 +435,7 @@ void QCMake::reloadCache()
QCMakePropertyList props;
emit this->propertiesChanged(props);
// reload
- this->CMakeInstance->GetCacheManager()->LoadCache(this->BinaryDirectory.toLocal8Bit().data());
+ this->CMakeInstance->LoadCache(this->BinaryDirectory.toLocal8Bit().data());
// emit new cache properties
props = this->properties();
emit this->propertiesChanged(props);
@@ -435,10 +455,44 @@ bool QCMake::getDebugOutput() const
return this->CMakeInstance->GetDebugOutput();
}
+bool QCMake::getSuppressDevWarnings()
+{
+ return this->CMakeInstance->GetSuppressDevWarnings();
+}
void QCMake::setSuppressDevWarnings(bool value)
{
- this->SuppressDevWarnings = value;
+ this->CMakeInstance->SetSuppressDevWarnings(value);
+}
+
+bool QCMake::getSuppressDeprecatedWarnings()
+{
+ return this->CMakeInstance->GetSuppressDeprecatedWarnings();
+}
+
+void QCMake::setSuppressDeprecatedWarnings(bool value)
+{
+ this->CMakeInstance->SetSuppressDeprecatedWarnings(value);
+}
+
+bool QCMake::getDevWarningsAsErrors()
+{
+ return this->CMakeInstance->GetDevWarningsAsErrors();
+}
+
+void QCMake::setDevWarningsAsErrors(bool value)
+{
+ this->CMakeInstance->SetDevWarningsAsErrors(value);
+}
+
+bool QCMake::getDeprecatedWarningsAsErrors()
+{
+ return this->CMakeInstance->GetDeprecatedWarningsAsErrors();
+}
+
+void QCMake::setDeprecatedWarningsAsErrors(bool value)
+{
+ this->CMakeInstance->SetDeprecatedWarningsAsErrors(value);
}
void QCMake::setWarnUninitializedMode(bool value)
diff --git a/Source/QtDialog/QCMake.h b/Source/QtDialog/QCMake.h
index 93ac8ab00..8942e7c90 100644
--- a/Source/QtDialog/QCMake.h
+++ b/Source/QtDialog/QCMake.h
@@ -10,13 +10,15 @@
See the License for more information.
============================================================================*/
-#ifndef __QCMake_h
-#define __QCMake_h
+#ifndef QCMake_h
+#define QCMake_h
#ifdef _MSC_VER
#pragma warning ( disable : 4127 )
#pragma warning ( disable : 4512 )
#endif
+#include <vector>
+
#include <QObject>
#include <QString>
#include <QVariant>
@@ -25,7 +27,7 @@
#include <QMetaType>
#include <QAtomicInt>
-class cmake;
+#include "cmake.h"
/// struct to represent cmake properties in Qt
/// Value is of type String or Bool
@@ -73,6 +75,8 @@ public slots:
void setBinaryDirectory(const QString& dir);
/// set the desired generator to use
void setGenerator(const QString& generator);
+ /// set the desired generator to use
+ void setToolset(const QString& toolset);
/// do the configure step
void configure();
/// generate the files
@@ -87,8 +91,22 @@ public slots:
void reloadCache();
/// set whether to do debug output
void setDebugOutput(bool);
+ /// get whether to do suppress dev warnings
+ bool getSuppressDevWarnings();
/// set whether to do suppress dev warnings
void setSuppressDevWarnings(bool value);
+ /// get whether to do suppress deprecated warnings
+ bool getSuppressDeprecatedWarnings();
+ /// set whether to do suppress deprecated warnings
+ void setSuppressDeprecatedWarnings(bool value);
+ /// get whether to treat developer (author) warnings as errors
+ bool getDevWarningsAsErrors();
+ /// set whether to treat developer (author) warnings as errors
+ void setDevWarningsAsErrors(bool value);
+ /// get whether to treat deprecated warnings as errors
+ bool getDeprecatedWarningsAsErrors();
+ /// set whether to treat deprecated warnings as errors
+ void setDeprecatedWarningsAsErrors(bool value);
/// set whether to run cmake with warnings about uninitialized variables
void setWarnUninitializedMode(bool value);
/// set whether to run cmake with warnings about unused variables
@@ -104,7 +122,7 @@ public:
/// get the current generator
QString generator() const;
/// get the available generators
- QStringList availableGenerators() const;
+ std::vector<cmake::GeneratorInfo> const& availableGenerators() const;
/// get whether to do debug output
bool getDebugOutput() const;
@@ -130,25 +148,29 @@ signals:
void errorMessage(const QString& msg);
/// signal when debug output changes
void debugOutputChanged(bool);
+ /// signal when the toolset changes
+ void toolsetChanged(const QString& toolset);
protected:
cmake* CMakeInstance;
static bool interruptCallback(void*);
static void progressCallback(const char* msg, float percent, void* cd);
- static void errorCallback(const char* msg, const char* title,
- bool&, void* cd);
- bool SuppressDevWarnings;
+ static void messageCallback(const char* msg, const char* title,
+ bool&, void* cd);
+ static void stdoutCallback(const char* msg, size_t len, void* cd);
+ static void stderrCallback(const char* msg, size_t len, void* cd);
bool WarnUninitializedMode;
bool WarnUnusedMode;
bool WarnUnusedAllMode;
QString SourceDirectory;
QString BinaryDirectory;
QString Generator;
- QStringList AvailableGenerators;
+ QString Toolset;
+ std::vector<cmake::GeneratorInfo> AvailableGenerators;
QString CMakeExecutable;
QAtomicInt InterruptFlag;
};
-#endif // __QCMake_h
+#endif // QCMake_h
diff --git a/Source/QtDialog/QCMakeWidgets.cxx b/Source/QtDialog/QCMakeWidgets.cxx
index a0c5e17fe..41f98b5d2 100644
--- a/Source/QtDialog/QCMakeWidgets.cxx
+++ b/Source/QtDialog/QCMakeWidgets.cxx
@@ -67,7 +67,8 @@ void QCMakeFilePathEditor::chooseFile()
title = title.arg(this->Variable);
}
this->fileDialogExists(true);
- path = QFileDialog::getOpenFileName(this, title, info.absolutePath());
+ path = QFileDialog::getOpenFileName(this, title, info.absolutePath(),
+ QString(), NULL, QFileDialog::DontResolveSymlinks);
this->fileDialogExists(false);
if(!path.isEmpty())
@@ -91,7 +92,8 @@ void QCMakePathEditor::chooseFile()
title = title.arg(this->Variable);
}
this->fileDialogExists(true);
- path = QFileDialog::getExistingDirectory(this, title, this->text());
+ path = QFileDialog::getExistingDirectory(this, title, this->text(),
+ QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
this->fileDialogExists(false);
if(!path.isEmpty())
{
diff --git a/Source/QtDialog/QMacInstallDialog.cxx b/Source/QtDialog/QMacInstallDialog.cxx
deleted file mode 100644
index 8b8c5319f..000000000
--- a/Source/QtDialog/QMacInstallDialog.cxx
+++ /dev/null
@@ -1,121 +0,0 @@
-#include "QMacInstallDialog.h"
-#include <QMessageBox>
-#include "cmSystemTools.h"
-#include <iostream>
-#include <QFileDialog>
-#include "ui_MacInstallDialog.h"
-
-class QMacInstallDialog::QMacInstallDialogInternals : public Ui::Dialog
-{
-public:
-};
-
-QMacInstallDialog::QMacInstallDialog(QWidget*w)
- :QDialog(w)
-{
- this->Internals = new QMacInstallDialogInternals;
- this->Internals->setupUi(this);
- QObject::connect(this->Internals->choosePathButton, SIGNAL(pressed()),
- this, SLOT(ShowBrowser()));
- QObject::connect(this->Internals->skipInstallButton, SIGNAL(pressed()),
- this, SLOT(SkipInstall()));
- QObject::connect(this->Internals->doInstallButton, SIGNAL(pressed()),
- this, SLOT(DoInstall()));
- this->Internals->InstallPrefix->setText("/usr/bin/");
-
-}
-
-QMacInstallDialog::~QMacInstallDialog()
-{
- delete this->Internals;
-}
-
-void QMacInstallDialog::DoInstall()
-{
- QDir installDir(this->Internals->InstallPrefix->text());
- QString installTo = installDir.path();
- if(!cmSystemTools::FileExists(installTo.toLocal8Bit().data()))
- {
- QString message = tr("Build install does not exist, "
- "should I create it?\n\n"
- "Directory: ");
- message += installDir.path();
- QString title = tr("Create Directory");
- QMessageBox::StandardButton btn;
- btn = QMessageBox::information(this, title, message,
- QMessageBox::Yes | QMessageBox::No);
- if(btn == QMessageBox::Yes)
- {
- cmSystemTools::MakeDirectory(installTo.toLocal8Bit().data());
- }
- }
- QDir cmExecDir(QApplication::applicationDirPath());
- cmExecDir.cd("../bin");
- QFileInfoList list = cmExecDir.entryInfoList();
- for (int i = 0; i < list.size(); ++i)
- {
- QFileInfo fileInfo = list.at(i);
- QString filename = fileInfo.fileName();
- if(filename.size() && filename[0] == '.')
- {
- continue;
- }
- QString file = fileInfo.absoluteFilePath();
- QString newName = installTo;
- newName += "/";
- newName += filename;
- // Remove the old files
- if(cmSystemTools::FileExists(newName.toLocal8Bit().data()))
- {
- std::cout << "rm [" << newName.toLocal8Bit().data() << "]\n";
- if(!cmSystemTools::RemoveFile(newName.toLocal8Bit().data()))
- {
- QString message = tr("Failed to remove file "
- "installation may be incomplete: ");
- message += newName;
- QString title = tr("Error Removing file");
- QMessageBox::StandardButton btn =
- QMessageBox::critical(this, title, message,
- QMessageBox::Ok|QMessageBox::Abort);
- if(btn == QMessageBox::Abort)
- {
- return;
- }
- }
- }
- std::cout << "ln -s [" << file.toLocal8Bit().data() << "] [";
- std::cout << newName.toLocal8Bit().data() << "]\n";
- if(!cmSystemTools::CreateSymlink(file.toLocal8Bit().data(),
- newName.toLocal8Bit().data()))
- {
- QString message = tr("Failed create symlink "
- "installation may be incomplete: ");
- message += newName;
- QString title = tr("Error Creating Symlink");
- QMessageBox::StandardButton btn =
- QMessageBox::critical(this, title, message,
- QMessageBox::Ok|QMessageBox::Abort);
- if(btn == QMessageBox::Abort)
- {
- return;
- }
- }
- }
- this->done(0);
-}
-
-void QMacInstallDialog::SkipInstall()
-{
- this->done(0);
-}
-
-
-void QMacInstallDialog::ShowBrowser()
-{
- QString dir = QFileDialog::getExistingDirectory(this,
- tr("Enter Install Prefix"), this->Internals->InstallPrefix->text());
- if(!dir.isEmpty())
- {
- this->Internals->InstallPrefix->setText(dir);
- }
-}
diff --git a/Source/QtDialog/QMacInstallDialog.h b/Source/QtDialog/QMacInstallDialog.h
deleted file mode 100644
index efe67dfaf..000000000
--- a/Source/QtDialog/QMacInstallDialog.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef QMacInstallDialog_h
-#define QMacInstallDialog_h
-#include <QDialog>
-
-class QMacInstallDialog : public QDialog
-{
- Q_OBJECT;
-public:
- QMacInstallDialog(QWidget*w);
- ~QMacInstallDialog();
-private slots:
- void ShowBrowser();
- void SkipInstall();
- void DoInstall();
-private:
- class QMacInstallDialogInternals;
- QMacInstallDialogInternals* Internals;
-};
-
-#endif
diff --git a/Source/QtDialog/QtDialogCPack.cmake.in b/Source/QtDialog/QtDialogCPack.cmake.in
index 3196471d7..7ae860548 100644
--- a/Source/QtDialog/QtDialogCPack.cmake.in
+++ b/Source/QtDialog/QtDialogCPack.cmake.in
@@ -9,9 +9,6 @@ if(CMAKE_PACKAGE_QTGUI)
# / and then install
# cmake into the bundle for cmake-gui and must use DESTDIR
set(CPACK_SET_DESTDIR TRUE)
- # we also want to run post install stuff to setup command line
- set(CPACK_POSTFLIGHT_SCRIPT "@CMAKE_POSTFLIGHT_SCRIPT@")
- set(CPACK_POSTUPGRADE_SCRIPT "@CMAKE_POSTUPGRADE_SCRIPT@")
endif()
endif()
diff --git a/Source/QtDialog/RegexExplorer.cxx b/Source/QtDialog/RegexExplorer.cxx
new file mode 100644
index 000000000..dfcf048d1
--- /dev/null
+++ b/Source/QtDialog/RegexExplorer.cxx
@@ -0,0 +1,166 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Kitware, Inc., Gregor Jasny
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "RegexExplorer.h"
+
+RegexExplorer::RegexExplorer(QWidget* p) : QDialog(p), m_matched(false)
+{
+ this->setupUi(this);
+
+ for(int i = 1; i < cmsys::RegularExpression::NSUBEXP; ++i)
+ {
+ matchNumber->addItem(
+ QString("Match %1").arg(QString::number(i)),
+ QVariant(i));
+ }
+ matchNumber->setCurrentIndex(0);
+}
+
+void RegexExplorer::setStatusColor(QWidget* widget, bool successful)
+{
+ QColor color = successful ? QColor(0, 127, 0) : Qt::red;
+
+ QPalette palette = widget->palette();
+ palette.setColor(QPalette::Foreground, color);
+ widget->setPalette(palette);
+}
+
+void RegexExplorer::on_regularExpression_textChanged(const QString& text)
+{
+#ifdef QT_NO_STL
+ m_regex = text.toAscii().constData();
+#else
+ m_regex = text.toStdString();
+#endif
+
+ bool validExpression =
+ stripEscapes(m_regex) && m_regexParser.compile(m_regex);
+ if(!validExpression)
+ {
+ m_regexParser.set_invalid();
+ }
+
+ setStatusColor(labelRegexValid, validExpression);
+
+ on_inputText_textChanged();
+}
+
+void RegexExplorer::on_inputText_textChanged()
+{
+ if(m_regexParser.is_valid())
+ {
+ QString plainText = inputText->toPlainText();
+#ifdef QT_NO_STL
+ m_text = plainText.toAscii().constData();
+#else
+ m_text = plainText.toStdString();
+#endif
+ m_matched = m_regexParser.find(m_text);
+ }
+ else
+ {
+ m_matched = false;
+ }
+
+ setStatusColor(labelRegexMatch, m_matched);
+
+ if(!m_matched)
+ {
+ clearMatch();
+ return;
+ }
+
+#ifdef QT_NO_STL
+ QString matchText = m_regexParser.match(0).c_str();
+#else
+ QString matchText = QString::fromStdString(m_regexParser.match(0));
+#endif
+ match0->setPlainText(matchText);
+
+ on_matchNumber_currentIndexChanged(matchNumber->currentIndex());
+}
+
+void RegexExplorer::on_matchNumber_currentIndexChanged(int index)
+{
+ if(!m_matched)
+ {
+ return;
+ }
+
+ QVariant itemData = matchNumber->itemData(index);
+ int idx = itemData.toInt();
+
+ if(idx < 1 || idx >= cmsys::RegularExpression::NSUBEXP)
+ {
+ return;
+ }
+
+#ifdef QT_NO_STL
+ QString match = m_regexParser.match(idx).c_str();
+#else
+ QString match = QString::fromStdString(m_regexParser.match(idx));
+#endif
+ matchN->setPlainText(match);
+}
+
+void RegexExplorer::clearMatch()
+{
+ match0->clear();
+ matchN->clear();
+}
+
+bool RegexExplorer::stripEscapes(std::string& source)
+{
+ const char* in = source.c_str();
+
+ std::string result;
+ result.reserve(source.size());
+
+ for(char inc = *in; inc != '\0'; inc = *++in)
+ {
+ if(inc == '\\')
+ {
+ char nextc = in[1];
+ if(nextc == 't')
+ {
+ result.append(1, '\t');
+ in++;
+ }
+ else if(nextc == 'n')
+ {
+ result.append(1, '\n');
+ in++;
+ }
+ else if(nextc == 't')
+ {
+ result.append(1, '\t');
+ in++;
+ }
+ else if(isalnum(nextc) || nextc == '\0')
+ {
+ return false;
+ }
+ else
+ {
+ result.append(1, nextc);
+ in++;
+ }
+ }
+ else
+ {
+ result.append(1, inc);
+ }
+ }
+
+ source = result;
+ return true;
+}
diff --git a/Source/QtDialog/RegexExplorer.h b/Source/QtDialog/RegexExplorer.h
new file mode 100644
index 000000000..2ac9c3e2e
--- /dev/null
+++ b/Source/QtDialog/RegexExplorer.h
@@ -0,0 +1,48 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Kitware, Inc., Gregor Jasny
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef RegexExplorer_h
+#define RegexExplorer_h
+
+#include <string>
+#include <cmsys/RegularExpression.hxx>
+#include <QDialog>
+
+#include "ui_RegexExplorer.h"
+
+class QString;
+class QWidget;
+
+class RegexExplorer : public QDialog, public Ui::RegexExplorer
+{
+ Q_OBJECT
+public:
+ RegexExplorer(QWidget* p);
+
+private slots:
+ void on_regularExpression_textChanged(const QString& text);
+ void on_inputText_textChanged();
+ void on_matchNumber_currentIndexChanged(int index);
+
+private:
+ static void setStatusColor(QWidget* widget, bool successful);
+ static bool stripEscapes(std::string& regex);
+
+ void clearMatch();
+
+ cmsys::RegularExpression m_regexParser;
+ std::string m_text;
+ std::string m_regex;
+ bool m_matched;
+};
+
+#endif
diff --git a/Source/QtDialog/RegexExplorer.ui b/Source/QtDialog/RegexExplorer.ui
new file mode 100644
index 000000000..2c2d7616f
--- /dev/null
+++ b/Source/QtDialog/RegexExplorer.ui
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>RegexExplorer</class>
+ <widget class="QDialog" name="RegexExplorer">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>639</width>
+ <height>555</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Regular Expression Explorer</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Input Text</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPlainTextEdit" name="inputText"/>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Regular Expression</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelRegexValid">
+ <property name="text">
+ <string>Valid</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelRegexMatch">
+ <property name="text">
+ <string>Match</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="regularExpression"/>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Complete Match</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPlainTextEdit" name="match0">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QComboBox" name="matchNumber">
+ <property name="editable">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QPlainTextEdit" name="matchN">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Source/QtDialog/WarningMessagesDialog.cxx b/Source/QtDialog/WarningMessagesDialog.cxx
new file mode 100644
index 000000000..4bd541f3e
--- /dev/null
+++ b/Source/QtDialog/WarningMessagesDialog.cxx
@@ -0,0 +1,99 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Kitware, Inc., Gregor Jasny
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "WarningMessagesDialog.h"
+
+WarningMessagesDialog::WarningMessagesDialog(QWidget* prnt, QCMake* instance)
+ : QDialog(prnt), cmakeInstance(instance)
+{
+ this->setupUi(this);
+ this->setInitialValues();
+ this->setupSignals();
+}
+
+void WarningMessagesDialog::setInitialValues()
+{
+ this->suppressDeveloperWarnings->setChecked(
+ this->cmakeInstance->getSuppressDevWarnings());
+ this->suppressDeprecatedWarnings->setChecked(
+ this->cmakeInstance->getSuppressDeprecatedWarnings());
+
+ this->developerWarningsAsErrors->setChecked(
+ this->cmakeInstance->getDevWarningsAsErrors());
+ this->deprecatedWarningsAsErrors->setChecked(
+ this->cmakeInstance->getDeprecatedWarningsAsErrors());
+}
+
+void WarningMessagesDialog::setupSignals()
+{
+ QObject::connect(this->buttonBox, SIGNAL(accepted()),
+ this, SLOT(doAccept()));
+
+ QObject::connect(this->suppressDeveloperWarnings, SIGNAL(stateChanged(int)),
+ this, SLOT(doSuppressDeveloperWarningsChanged(int)));
+ QObject::connect(this->suppressDeprecatedWarnings, SIGNAL(stateChanged(int)),
+ this, SLOT(doSuppressDeprecatedWarningsChanged(int)));
+
+ QObject::connect(this->developerWarningsAsErrors, SIGNAL(stateChanged(int)),
+ this, SLOT(doDeveloperWarningsAsErrorsChanged(int)));
+ QObject::connect(this->deprecatedWarningsAsErrors, SIGNAL(stateChanged(int)),
+ this, SLOT(doDeprecatedWarningsAsErrorsChanged(int)));
+}
+
+void WarningMessagesDialog::doAccept()
+{
+ this->cmakeInstance->setSuppressDevWarnings(
+ this->suppressDeveloperWarnings->isChecked());
+ this->cmakeInstance->setSuppressDeprecatedWarnings(
+ this->suppressDeprecatedWarnings->isChecked());
+
+ this->cmakeInstance->setDevWarningsAsErrors(
+ this->developerWarningsAsErrors->isChecked());
+ this->cmakeInstance->setDeprecatedWarningsAsErrors(
+ this->deprecatedWarningsAsErrors->isChecked());
+}
+
+void WarningMessagesDialog::doSuppressDeveloperWarningsChanged(int state)
+{
+ // no warnings implies no errors either
+ if (state)
+ {
+ this->developerWarningsAsErrors->setChecked(false);
+ }
+}
+
+void WarningMessagesDialog::doSuppressDeprecatedWarningsChanged(int state)
+{
+ // no warnings implies no errors either
+ if (state)
+ {
+ this->deprecatedWarningsAsErrors->setChecked(false);
+ }
+}
+
+void WarningMessagesDialog::doDeveloperWarningsAsErrorsChanged(int state)
+{
+ // warnings as errors implies warnings are not suppressed
+ if (state)
+ {
+ this->suppressDeveloperWarnings->setChecked(false);
+ }
+}
+
+void WarningMessagesDialog::doDeprecatedWarningsAsErrorsChanged(int state)
+{
+ // warnings as errors implies warnings are not suppressed
+ if (state)
+ {
+ this->suppressDeprecatedWarnings->setChecked(false);
+ }
+}
diff --git a/Source/QtDialog/WarningMessagesDialog.h b/Source/QtDialog/WarningMessagesDialog.h
new file mode 100644
index 000000000..6c274a71d
--- /dev/null
+++ b/Source/QtDialog/WarningMessagesDialog.h
@@ -0,0 +1,75 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Kitware, Inc., Gregor Jasny
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef WarningMessagesDialog_h
+#define WarningMessagesDialog_h
+
+#include <QDialog>
+#include <QWidget>
+
+#include "ui_WarningMessagesDialog.h"
+#include "QCMake.h"
+
+/**
+ * Dialog window for setting the warning message related options.
+ */
+class WarningMessagesDialog : public QDialog, public Ui_MessagesDialog
+{
+ Q_OBJECT
+
+public:
+ WarningMessagesDialog(QWidget* prnt, QCMake* instance);
+
+private slots:
+ /**
+ * Handler for the accept event of the ok/cancel button box.
+ */
+ void doAccept();
+
+ /**
+ * Handler for checked state changed event of the suppress developer warnings
+ * checkbox.
+ */
+ void doSuppressDeveloperWarningsChanged(int state);
+ /**
+ * Handler for checked state changed event of the suppress deprecated
+ * warnings checkbox.
+ */
+ void doSuppressDeprecatedWarningsChanged(int state);
+
+ /**
+ * Handler for checked state changed event of the developer warnings as
+ * errors checkbox.
+ */
+ void doDeveloperWarningsAsErrorsChanged(int state);
+ /**
+ * Handler for checked state changed event of the deprecated warnings as
+ * errors checkbox.
+ */
+ void doDeprecatedWarningsAsErrorsChanged(int state);
+
+private:
+ QCMake* cmakeInstance;
+
+ /**
+ * Set the initial values of the widgets on this dialog window, using the
+ * current state of the cache.
+ */
+ void setInitialValues();
+
+ /**
+ * Setup the signals for the widgets on this dialog window.
+ */
+ void setupSignals();
+};
+
+#endif /* MessageDialog_h */
diff --git a/Source/QtDialog/WarningMessagesDialog.ui b/Source/QtDialog/WarningMessagesDialog.ui
new file mode 100644
index 000000000..3b35cbc67
--- /dev/null
+++ b/Source/QtDialog/WarningMessagesDialog.ui
@@ -0,0 +1,173 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MessagesDialog</class>
+ <widget class="QDialog" name="MessagesDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>300</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Warning Messages</string>
+ </property>
+ <property name="modal">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Suppress Warnings</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QCheckBox" name="suppressDeveloperWarnings">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Suppress developer (author) warnings.</string>
+ </property>
+ <property name="text">
+ <string>Developer Warnings</string>
+ </property>
+ <property name="tristate">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="suppressDeprecatedWarnings">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Suppress deprecated warnings.</string>
+ </property>
+ <property name="text">
+ <string>Deprecated Warnings</string>
+ </property>
+ <property name="tristate">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Warnings as Errors</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QCheckBox" name="developerWarningsAsErrors">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Treat developer (author) warnings as errors.</string>
+ </property>
+ <property name="text">
+ <string>Developer Warnings as Errors</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="deprecatedWarningsAsErrors">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Treat deprecated warnings as errors.</string>
+ </property>
+ <property name="text">
+ <string>Deprecated Warnings as Errors</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>MessagesDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>MessagesDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/Source/QtDialog/postflight.sh.in b/Source/QtDialog/postflight.sh.in
deleted file mode 100755
index 33be35206..000000000
--- a/Source/QtDialog/postflight.sh.in
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash
-"$2@CMAKE_INSTALL_SUBDIR@/@CMAKE_BUNDLE_NAME@.app/Contents/MacOS/@CMAKE_BUNDLE_NAME@" --mac-install
-exit 0
diff --git a/Source/QtDialog/postupgrade.sh.in b/Source/QtDialog/postupgrade.sh.in
deleted file mode 100755
index 06bd98656..000000000
--- a/Source/QtDialog/postupgrade.sh.in
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-exit 0
diff --git a/Source/QtIFW/CMake.Dialogs.QtGUI.qs b/Source/QtIFW/CMake.Dialogs.QtGUI.qs
new file mode 100644
index 000000000..219a0a90a
--- /dev/null
+++ b/Source/QtIFW/CMake.Dialogs.QtGUI.qs
@@ -0,0 +1,21 @@
+// Component: CMake.Dialogs.QtGUI
+
+function Component()
+{
+ // Default constructor
+}
+
+Component.prototype.createOperations = function()
+{
+ // Create shortcut
+ if (installer.value("os") === "win") {
+
+ component.addOperation("CreateShortcut",
+ installer.value("TargetDir") + "/bin/cmake-gui.exe",
+ installer.value("StartMenuDir") + "/CMake (cmake-gui).lnk");
+
+ }
+
+ // Call default implementation
+ component.createOperations();
+}
diff --git a/Source/QtIFW/CMake.Documentation.SphinxHTML.qs.in b/Source/QtIFW/CMake.Documentation.SphinxHTML.qs.in
new file mode 100644
index 000000000..5c929e86f
--- /dev/null
+++ b/Source/QtIFW/CMake.Documentation.SphinxHTML.qs.in
@@ -0,0 +1,21 @@
+// Component: CMake.Documentation.SphinxHTML
+
+function Component()
+{
+ // Default constructor
+}
+
+Component.prototype.createOperations = function()
+{
+ // Create shortcut
+ if (installer.value("os") === "win") {
+
+ component.addOperation("CreateShortcut",
+ installer.value("TargetDir") + "/@CMAKE_DOC_DIR@/html/index.html",
+ installer.value("StartMenuDir") + "/CMake Documentation.lnk");
+
+ }
+
+ // Call default implementation
+ component.createOperations();
+}
diff --git a/Source/QtIFW/CMake.qs.in b/Source/QtIFW/CMake.qs.in
new file mode 100644
index 000000000..828cc7cb2
--- /dev/null
+++ b/Source/QtIFW/CMake.qs.in
@@ -0,0 +1,22 @@
+function Component()
+{
+ // Default constructor
+}
+
+Component.prototype.createOperations = function()
+{
+ // Create shortcut
+ if (installer.value("os") === "win") {
+
+ component.addOperation("CreateShortcut",
+ installer.value("TargetDir") + "/@CMAKE_DOC_DIR@/cmake.org.html",
+ installer.value("StartMenuDir") + "/CMake Web Site.lnk");
+
+ component.addOperation("CreateShortcut",
+ installer.value("TargetDir") + "/cmake-maintenance.exe",
+ installer.value("StartMenuDir") + "/CMake Maintenance Tool.lnk");
+ }
+
+ // Call default implementation
+ component.createOperations();
+}
diff --git a/Source/QtIFW/cmake.org.html b/Source/QtIFW/cmake.org.html
new file mode 100644
index 000000000..cf5649db6
--- /dev/null
+++ b/Source/QtIFW/cmake.org.html
@@ -0,0 +1,7 @@
+<html>
+<head>
+<meta http-equiv="Refresh" content="0; url=http://cmake.org/" />
+</head>
+<body>
+</body>
+</html>
diff --git a/Source/QtIFW/controlscript.qs b/Source/QtIFW/controlscript.qs
new file mode 100644
index 000000000..d1a9b102a
--- /dev/null
+++ b/Source/QtIFW/controlscript.qs
@@ -0,0 +1,6 @@
+// controlscript.qs - CMake installation control script
+
+function Controller()
+{
+ // do nothing now
+}
diff --git a/Source/QtIFW/installscript.qs.in b/Source/QtIFW/installscript.qs.in
new file mode 100644
index 000000000..3411e34e4
--- /dev/null
+++ b/Source/QtIFW/installscript.qs.in
@@ -0,0 +1,24 @@
+function Component()
+{
+ // default constructor
+}
+
+Component.prototype.createOperations = function()
+{
+ // Create shortcut
+ if (installer.value("os") === "win") {
+
+@_CPACK_IFW_SHORTCUT_OPTIONAL@
+
+ component.addOperation("CreateShortcut",
+ installer.value("TargetDir") + "/@CMAKE_DOC_DIR@/cmake.org.html",
+ installer.value("StartMenuDir") + "/CMake Web Site.lnk");
+
+ component.addOperation("CreateShortcut",
+ installer.value("TargetDir") + "/cmake-maintenance.exe",
+ installer.value("StartMenuDir") + "/CMake Maintenance Tool.lnk");
+ }
+
+ // Call default implementation
+ component.createOperations();
+}
diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx
new file mode 100644
index 000000000..e7263aead
--- /dev/null
+++ b/Source/bindexplib.cxx
@@ -0,0 +1,460 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+/*-------------------------------------------------------------------------
+ Portions of this source have been derived from the 'bindexplib' tool
+ provided by the CERN ROOT Data Analysis Framework project (root.cern.ch).
+ Permission has been granted by Pere Mato <pere.mato@cern.ch> to distribute
+ this derived work under the CMake license.
+-------------------------------------------------------------------------*/
+
+/*
+*----------------------------------------------------------------------
+* Program: dumpexts.exe
+* Author: Gordon Chaffee
+*
+* History: The real functionality of this file was written by
+* Matt Pietrek in 1993 in his pedump utility. I've
+* modified it to dump the externals in a bunch of object
+* files to create a .def file.
+*
+* Notes: Visual C++ puts an underscore before each exported symbol.
+* This file removes them. I don't know if this is a problem
+* this other compilers. If _MSC_VER is defined,
+* the underscore is removed. If not, it isn't. To get a
+* full dump of an object file, use the -f option. This can
+* help determine the something that may be different with a
+* compiler other than Visual C++.
+* ======================================
+* Corrections (Axel 2006-04-04):
+* Conversion to C++. Mostly.
+*
+ * Extension (Axel 2006-03-15)
+ * As soon as an object file contains an /EXPORT directive (which
+ * is generated by the compiler when a symbol is declared as
+ * declspec(dllexport)) no to-be-exported symbols are printed,
+ * as the linker will see these directives, and if those directives
+ * are present we only export selectively (i.e. we trust the
+ * programmer).
+ *
+ * ======================================
+* ======================================
+* Corrections (Valery Fine 23/02/98):
+*
+* The "(vector) deleting destructor" MUST not be exported
+* To recognize it the following test are introduced:
+* "@@UAEPAXI@Z" scalar deleting dtor
+* "@@QAEPAXI@Z" vector deleting dtor
+* "AEPAXI@Z" vector deleting dtor with thunk adjustor
+* ======================================
+* Corrections (Valery Fine 12/02/97):
+*
+* It created a wrong EXPORTS for the global pointers and constants.
+* The Section Header has been involved to discover the missing information
+* Now the pointers are correctly supplied supplied with "DATA" descriptor
+* the constants with no extra descriptor.
+*
+* Corrections (Valery Fine 16/09/96):
+*
+* It didn't work for C++ code with global variables and class definitons
+* The DumpExternalObject function has been introduced to generate .DEF file
+*
+* Author: Valery Fine 16/09/96 (E-mail: fine@vxcern.cern.ch)
+*----------------------------------------------------------------------
+*/
+#include "bindexplib.h"
+#include <cmsys/Encoding.hxx>
+#include <windows.h>
+#include <stdio.h>
+#include <string>
+#include <fstream>
+#include <iostream>
+
+typedef struct cmANON_OBJECT_HEADER_BIGOBJ {
+ /* same as ANON_OBJECT_HEADER_V2 */
+ WORD Sig1; // Must be IMAGE_FILE_MACHINE_UNKNOWN
+ WORD Sig2; // Must be 0xffff
+ WORD Version; // >= 2 (implies the Flags field is present)
+ WORD Machine; // Actual machine - IMAGE_FILE_MACHINE_xxx
+ DWORD TimeDateStamp;
+ CLSID ClassID; // {D1BAA1C7-BAEE-4ba9-AF20-FAF66AA4DCB8}
+ DWORD SizeOfData; // Size of data that follows the header
+ DWORD Flags; // 0x1 -> contains metadata
+ DWORD MetaDataSize; // Size of CLR metadata
+ DWORD MetaDataOffset; // Offset of CLR metadata
+
+ /* bigobj specifics */
+ DWORD NumberOfSections; // extended from WORD
+ DWORD PointerToSymbolTable;
+ DWORD NumberOfSymbols;
+} cmANON_OBJECT_HEADER_BIGOBJ;
+
+typedef struct _cmIMAGE_SYMBOL_EX {
+ union {
+ BYTE ShortName[8];
+ struct {
+ DWORD Short; // if 0, use LongName
+ DWORD Long; // offset into string table
+ } Name;
+ DWORD LongName[2]; // PBYTE [2]
+ } N;
+ DWORD Value;
+ LONG SectionNumber;
+ WORD Type;
+ BYTE StorageClass;
+ BYTE NumberOfAuxSymbols;
+} cmIMAGE_SYMBOL_EX;
+typedef cmIMAGE_SYMBOL_EX UNALIGNED *cmPIMAGE_SYMBOL_EX;
+
+PIMAGE_SECTION_HEADER GetSectionHeaderOffset(PIMAGE_FILE_HEADER
+ pImageFileHeader)
+{
+ return (PIMAGE_SECTION_HEADER)
+ ((DWORD_PTR)pImageFileHeader +
+ IMAGE_SIZEOF_FILE_HEADER +
+ pImageFileHeader->SizeOfOptionalHeader);
+}
+
+PIMAGE_SECTION_HEADER GetSectionHeaderOffset(cmANON_OBJECT_HEADER_BIGOBJ*
+ pImageFileHeader)
+{
+ return (PIMAGE_SECTION_HEADER)
+ ((DWORD_PTR)pImageFileHeader +
+ sizeof(cmANON_OBJECT_HEADER_BIGOBJ));
+}
+
+/*
++ * Utility func, strstr with size
++ */
+const char* StrNStr(const char* start, const char* find, size_t &size) {
+ size_t len;
+ const char* hint;
+
+ if (!start || !find || !size) {
+ size = 0;
+ return 0;
+ }
+ len = strlen(find);
+
+ while ((hint = (const char*) memchr(start, find[0], size-len+1))) {
+ size -= (hint - start);
+ if (!strncmp(hint, find, len))
+ return hint;
+ start = hint + 1;
+ }
+
+ size = 0;
+ return 0;
+}
+
+template <
+ // cmANON_OBJECT_HEADER_BIGOBJ or IMAGE_FILE_HEADER
+ class ObjectHeaderType,
+ // cmPIMAGE_SYMBOL_EX or PIMAGE_SYMBOL
+ class SymbolTableType>
+class DumpSymbols
+{
+public:
+ /*
+ *----------------------------------------------------------------------
+ * Constructor --
+ *
+ * Initialize variables from pointer to object header.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ DumpSymbols(ObjectHeaderType* ih,
+ std::set<std::string>& symbols,
+ std::set<std::string>& dataSymbols,
+ bool is64)
+ :Symbols(symbols), DataSymbols(dataSymbols)
+ {
+ this->ObjectImageHeader = ih;
+ this->SymbolTable = (SymbolTableType*)
+ ((DWORD_PTR)this->ObjectImageHeader
+ + this->ObjectImageHeader->PointerToSymbolTable);
+ this->SectionHeaders =
+ GetSectionHeaderOffset(this->ObjectImageHeader);
+ this->SymbolCount = this->ObjectImageHeader->NumberOfSymbols;
+ this->Is64Bit = is64;
+ }
+
+ /*
+ *----------------------------------------------------------------------
+ * HaveExportedObjects --
+ *
+ * Returns true if export directives (declspec(dllexport)) exist.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ bool HaveExportedObjects() {
+ WORD i = 0;
+ size_t size = 0;
+ const char * rawdata = 0;
+ PIMAGE_SECTION_HEADER pDirectivesSectionHeader = 0;
+ PIMAGE_SECTION_HEADER pSectionHeaders = this->SectionHeaders;
+ for(i = 0; (i < this->ObjectImageHeader->NumberOfSections &&
+ !pDirectivesSectionHeader); i++)
+ if (!strncmp((const char*)&pSectionHeaders[i].Name[0], ".drectve",8))
+ pDirectivesSectionHeader = &pSectionHeaders[i];
+ if (!pDirectivesSectionHeader) return 0;
+
+ rawdata=(const char*)
+ this->ObjectImageHeader+pDirectivesSectionHeader->PointerToRawData;
+ if (!pDirectivesSectionHeader->PointerToRawData || !rawdata) return 0;
+
+ size = pDirectivesSectionHeader->SizeOfRawData;
+ const char* posImportFlag = rawdata;
+ while ((posImportFlag = StrNStr(posImportFlag, " /EXPORT:", size))) {
+ const char* lookingForDict = posImportFlag + 9;
+ if (!strncmp(lookingForDict, "_G__cpp_",8) ||
+ !strncmp(lookingForDict, "_G__set_cpp_",12)) {
+ posImportFlag = lookingForDict;
+ continue;
+ }
+
+ const char* lookingForDATA = posImportFlag + 9;
+ while (*(++lookingForDATA) && *lookingForDATA != ' ');
+ lookingForDATA -= 5;
+ // ignore DATA exports
+ if (strncmp(lookingForDATA, ",DATA", 5)) break;
+ posImportFlag = lookingForDATA + 5;
+ }
+ if(posImportFlag) {
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ *----------------------------------------------------------------------
+ * DumpObjFile --
+ *
+ * Dump an object file's exported symbols.
+ *----------------------------------------------------------------------
+ */
+ void DumpObjFile() {
+ if(!HaveExportedObjects()) {
+ this->DumpExternalsObjects();
+ }
+ }
+
+ /*
+ *----------------------------------------------------------------------
+ * DumpExternalsObjects --
+ *
+ * Dumps a COFF symbol table from an OBJ.
+ *----------------------------------------------------------------------
+ */
+ void DumpExternalsObjects() {
+ unsigned i;
+ PSTR stringTable;
+ std::string symbol;
+ DWORD SectChar;
+ /*
+ * The string table apparently starts right after the symbol table
+ */
+ stringTable = (PSTR)&this->SymbolTable[this->SymbolCount];
+ SymbolTableType* pSymbolTable = this->SymbolTable;
+ for ( i=0; i < this->SymbolCount; i++ ) {
+ if (pSymbolTable->SectionNumber > 0 &&
+ ( pSymbolTable->Type == 0x20 || pSymbolTable->Type == 0x0)) {
+ if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
+ /*
+ * The name of the Function entry points
+ */
+ if (pSymbolTable->N.Name.Short != 0) {
+ symbol = "";
+ symbol.insert(0, (const char *)pSymbolTable->N.ShortName, 8);
+ } else {
+ symbol = stringTable + pSymbolTable->N.Name.Long;
+ }
+
+ // clear out any leading spaces
+ while (isspace(symbol[0])) symbol.erase(0,1);
+ // if it starts with _ and has an @ then it is a __cdecl
+ // so remove the @ stuff for the export
+ if(symbol[0] == '_') {
+ std::string::size_type posAt = symbol.find('@');
+ if (posAt != std::string::npos) {
+ symbol.erase(posAt);
+ }
+ }
+ // For 64 bit builds we don't need to remove _
+ if(!this->Is64Bit)
+ {
+ if (symbol[0] == '_')
+ {
+ symbol.erase(0,1);
+ }
+ }
+ /*
+ Check whether it is "Scalar deleting destructor" and
+ "Vector deleting destructor"
+ */
+ const char *scalarPrefix = "??_G";
+ const char *vectorPrefix = "??_E";
+ // original code had a check for
+ // symbol.find("real@") == std::string::npos)
+ // but if this disallows memmber functions with the name real
+ // if scalarPrefix and vectorPrefix are not found then print
+ // the symbol
+ if (symbol.compare(0, 4, scalarPrefix) &&
+ symbol.compare(0, 4, vectorPrefix) )
+ {
+ SectChar =
+ this->
+ SectionHeaders[pSymbolTable->SectionNumber-1].Characteristics;
+ if (!pSymbolTable->Type && (SectChar & IMAGE_SCN_MEM_WRITE)) {
+ // Read only (i.e. constants) must be excluded
+ this->DataSymbols.insert(symbol);
+ } else {
+ if ( pSymbolTable->Type ||
+ !(SectChar & IMAGE_SCN_MEM_READ)) {
+ this->Symbols.insert(symbol);
+ } else {
+ // printf(" strange symbol: %s \n",symbol.c_str());
+ }
+ }
+ }
+ }
+ }
+ else if (pSymbolTable->SectionNumber == IMAGE_SYM_UNDEFINED &&
+ !pSymbolTable->Type && 0) {
+ /*
+ * The IMPORT global variable entry points
+ */
+ if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
+ symbol = stringTable + pSymbolTable->N.Name.Long;
+ while (isspace(symbol[0])) symbol.erase(0,1);
+ if (symbol[0] == '_') symbol.erase(0,1);
+ this->DataSymbols.insert(symbol);
+ }
+ }
+
+ /*
+ * Take into account any aux symbols
+ */
+ i += pSymbolTable->NumberOfAuxSymbols;
+ pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
+ pSymbolTable++;
+ }
+ }
+private:
+ std::set<std::string>& Symbols;
+ std::set<std::string>& DataSymbols;
+ DWORD_PTR SymbolCount;
+ PIMAGE_SECTION_HEADER SectionHeaders;
+ ObjectHeaderType* ObjectImageHeader;
+ SymbolTableType* SymbolTable;
+ bool Is64Bit;
+};
+
+bool
+DumpFile(const char* filename,
+ std::set<std::string>& symbols,
+ std::set<std::string>& dataSymbols)
+{
+ HANDLE hFile;
+ HANDLE hFileMapping;
+ LPVOID lpFileBase;
+ PIMAGE_DOS_HEADER dosHeader;
+
+ hFile = CreateFileW(cmsys::Encoding::ToWide(filename).c_str(),
+ GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+
+ if (hFile == INVALID_HANDLE_VALUE) {
+ fprintf(stderr, "Couldn't open file '%s' with CreateFile()\n", filename);
+ return false;
+ }
+
+ hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
+ if (hFileMapping == 0) {
+ CloseHandle(hFile);
+ fprintf(stderr, "Couldn't open file mapping with CreateFileMapping()\n");
+ return false;
+ }
+
+ lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
+ if (lpFileBase == 0) {
+ CloseHandle(hFileMapping);
+ CloseHandle(hFile);
+ fprintf(stderr, "Couldn't map view of file with MapViewOfFile()\n");
+ return false;
+ }
+
+ dosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
+ if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) {
+ fprintf(stderr, "File is an executable. I don't dump those.\n");
+ return false;
+ }
+ /* Does it look like a i386 COFF OBJ file??? */
+ else if (
+ ((dosHeader->e_magic == IMAGE_FILE_MACHINE_I386) ||
+ (dosHeader->e_magic == IMAGE_FILE_MACHINE_AMD64))
+ && (dosHeader->e_sp == 0)
+ ) {
+ /*
+ * The two tests above aren't what they look like. They're
+ * really checking for IMAGE_FILE_HEADER.Machine == i386 (0x14C)
+ * and IMAGE_FILE_HEADER.SizeOfOptionalHeader == 0;
+ */
+ DumpSymbols<IMAGE_FILE_HEADER, IMAGE_SYMBOL>
+ symbolDumper((PIMAGE_FILE_HEADER) lpFileBase, symbols, dataSymbols,
+ (dosHeader->e_magic == IMAGE_FILE_MACHINE_AMD64));
+ symbolDumper.DumpObjFile();
+ } else {
+ // check for /bigobj format
+ cmANON_OBJECT_HEADER_BIGOBJ* h =
+ (cmANON_OBJECT_HEADER_BIGOBJ*) lpFileBase;
+ if(h->Sig1 == 0x0 && h->Sig2 == 0xffff) {
+ DumpSymbols<cmANON_OBJECT_HEADER_BIGOBJ, cmIMAGE_SYMBOL_EX>
+ symbolDumper((cmANON_OBJECT_HEADER_BIGOBJ*) lpFileBase, symbols,
+ dataSymbols,
+ (h->Machine == IMAGE_FILE_MACHINE_AMD64));
+ symbolDumper.DumpObjFile();
+ } else {
+ printf("unrecognized file format in '%s'\n", filename);
+ return false;
+ }
+ }
+ UnmapViewOfFile(lpFileBase);
+ CloseHandle(hFileMapping);
+ CloseHandle(hFile);
+ return true;
+}
+
+bool bindexplib::AddObjectFile(const char* filename)
+{
+ if(!DumpFile(filename, this->Symbols, this->DataSymbols))
+ {
+ return false;
+ }
+ return true;
+}
+
+void bindexplib::WriteFile(FILE* file)
+{
+ fprintf(file,"EXPORTS \n");
+ for(std::set<std::string>::const_iterator i = this->DataSymbols.begin();
+ i!= this->DataSymbols.end(); ++i)
+ {
+ fprintf(file, "\t%s \t DATA\n", i->c_str());
+ }
+ for(std::set<std::string>::const_iterator i = this->Symbols.begin();
+ i!= this->Symbols.end(); ++i)
+ {
+ fprintf(file, "\t%s\n", i->c_str());
+ }
+}
diff --git a/Source/bindexplib.h b/Source/bindexplib.h
new file mode 100644
index 000000000..8661a4aab
--- /dev/null
+++ b/Source/bindexplib.h
@@ -0,0 +1,29 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef bindexplib_h
+#define bindexplib_h
+
+#include "cmStandardIncludes.h"
+
+
+class bindexplib
+{
+public:
+ bindexplib() {}
+ bool AddObjectFile(const char* filename);
+ void WriteFile(FILE* file);
+private:
+ std::set<std::string> Symbols;
+ std::set<std::string> DataSymbols;
+};
+#endif
diff --git a/Source/cmAddCompileOptionsCommand.h b/Source/cmAddCompileOptionsCommand.h
index e9bbf2816..f147ec04e 100644
--- a/Source/cmAddCompileOptionsCommand.h
+++ b/Source/cmAddCompileOptionsCommand.h
@@ -13,7 +13,6 @@
#define cmAddCompileOptionsCommand_h
#include "cmCommand.h"
-#include "cmDocumentGeneratorExpressions.h"
class cmAddCompileOptionsCommand : public cmCommand
{
@@ -36,34 +35,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const {return "add_compile_options";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Adds options to the compilation of source files.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " add_compile_options(<option> ...)\n"
- "Adds options to the compiler command line for sources in the "
- "current directory and below. This command can be used to add any "
- "options, but alternative commands exist to add preprocessor "
- "definitions or include directories. "
- "See documentation of the directory and target COMPILE_OPTIONS "
- "properties for details. "
- "Arguments to add_compile_options may use \"generator "
- "expressions\" with the syntax \"$<...>\". "
- CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS
- ;
- }
+ virtual std::string GetName() const {return "add_compile_options";}
cmTypeMacro(cmAddCompileOptionsCommand, cmCommand);
};
diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx
index 56348494d..fe516eac8 100644
--- a/Source/cmAddCustomCommandCommand.cxx
+++ b/Source/cmAddCustomCommandCommand.cxx
@@ -32,9 +32,10 @@ bool cmAddCustomCommandCommand
std::string source, target, main_dependency, working;
std::string comment_buffer;
const char* comment = 0;
- std::vector<std::string> depends, outputs, output;
+ std::vector<std::string> depends, outputs, output, byproducts;
bool verbatim = false;
bool append = false;
+ bool uses_terminal = false;
std::string implicit_depends_lang;
cmCustomCommand::ImplicitDependsList implicit_depends;
@@ -56,6 +57,7 @@ bool cmAddCustomCommandCommand
doing_main_dependency,
doing_output,
doing_outputs,
+ doing_byproducts,
doing_comment,
doing_working_directory,
doing_nothing
@@ -102,6 +104,10 @@ bool cmAddCustomCommandCommand
{
append = true;
}
+ else if(copy == "USES_TERMINAL")
+ {
+ uses_terminal = true;
+ }
else if(copy == "TARGET")
{
doing = doing_target;
@@ -122,6 +128,10 @@ bool cmAddCustomCommandCommand
{
doing = doing_output;
}
+ else if (copy == "BYPRODUCTS")
+ {
+ doing = doing_byproducts;
+ }
else if (copy == "WORKING_DIRECTORY")
{
doing = doing_working_directory;
@@ -145,6 +155,7 @@ bool cmAddCustomCommandCommand
{
case doing_output:
case doing_outputs:
+ case doing_byproducts:
if (!cmSystemTools::FileIsFullPath(copy.c_str()))
{
// This is an output to be generated, so it should be
@@ -157,7 +168,7 @@ bool cmAddCustomCommandCommand
// and later references "${CMAKE_CURRENT_SOURCE_DIR}/out.txt".
// This is fairly obscure so we can wait for someone to
// complain.
- filename = this->Makefile->GetCurrentOutputDirectory();
+ filename = this->Makefile->GetCurrentBinaryDirectory();
filename += "/";
}
filename += copy;
@@ -173,6 +184,10 @@ bool cmAddCustomCommandCommand
break;
}
+ if (cmSystemTools::FileIsFullPath(filename.c_str()))
+ {
+ filename = cmSystemTools::CollapseFullPath(filename);
+ }
switch (doing)
{
case doing_working_directory:
@@ -224,6 +239,9 @@ bool cmAddCustomCommandCommand
case doing_outputs:
outputs.push_back(filename);
break;
+ case doing_byproducts:
+ byproducts.push_back(filename);
+ break;
case doing_comment:
comment_buffer = copy;
comment = comment_buffer.c_str();
@@ -263,7 +281,9 @@ bool cmAddCustomCommandCommand
}
// Make sure the output names and locations are safe.
- if(!this->CheckOutputs(output) || !this->CheckOutputs(outputs))
+ if(!this->CheckOutputs(output) ||
+ !this->CheckOutputs(outputs) ||
+ !this->CheckOutputs(byproducts))
{
return false;
}
@@ -273,7 +293,7 @@ bool cmAddCustomCommandCommand
{
// Lookup an existing command.
if(cmSourceFile* sf =
- this->Makefile->GetSourceFileWithOutput(output[0].c_str()))
+ this->Makefile->GetSourceFileWithOutput(output[0]))
{
if(cmCustomCommand* cc = sf->GetCustomCommand())
{
@@ -285,18 +305,18 @@ bool cmAddCustomCommandCommand
}
// No command for this output exists.
- cmOStringStream e;
- e << "given APPEND option with output \"" << output[0].c_str()
+ std::ostringstream e;
+ e << "given APPEND option with output \"" << output[0]
<< "\" which is not already a custom command output.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
// Convert working directory to a full path.
if(!working.empty())
{
- const char* build_dir = this->Makefile->GetCurrentOutputDirectory();
- working = cmSystemTools::CollapseFullPath(working.c_str(), build_dir);
+ const char* build_dir = this->Makefile->GetCurrentBinaryDirectory();
+ working = cmSystemTools::CollapseFullPath(working, build_dir);
}
// Choose which mode of the command to use.
@@ -305,26 +325,26 @@ bool cmAddCustomCommandCommand
{
// Source is empty, use the target.
std::vector<std::string> no_depends;
- this->Makefile->AddCustomCommandToTarget(target.c_str(), no_depends,
+ this->Makefile->AddCustomCommandToTarget(target, byproducts, no_depends,
commandLines, cctype,
comment, working.c_str(),
- escapeOldStyle);
+ escapeOldStyle, uses_terminal);
}
else if(target.empty())
{
// Target is empty, use the output.
- this->Makefile->AddCustomCommandToOutput(output, depends,
- main_dependency.c_str(),
+ this->Makefile->AddCustomCommandToOutput(output, byproducts,
+ depends, main_dependency,
commandLines, comment,
working.c_str(), false,
- escapeOldStyle);
+ escapeOldStyle, uses_terminal);
// Add implicit dependency scanning requests if any were given.
if(!implicit_depends.empty())
{
bool okay = false;
if(cmSourceFile* sf =
- this->Makefile->GetSourceFileWithOutput(output[0].c_str()))
+ this->Makefile->GetSourceFileWithOutput(output[0]))
{
if(cmCustomCommand* cc = sf->GetCustomCommand())
{
@@ -334,19 +354,58 @@ bool cmAddCustomCommandCommand
}
if(!okay)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "could not locate source file with a custom command producing \""
<< output[0] << "\" even though this command tried to create it!";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
}
+ else if (!byproducts.empty())
+ {
+ this->SetError("BYPRODUCTS may not be specified with SOURCE signatures");
+ return false;
+ }
+ else if (uses_terminal)
+ {
+ this->SetError("USES_TERMINAL may not be used with SOURCE signatures");
+ return false;
+ }
else
{
+ bool issueMessage = true;
+ std::ostringstream e;
+ cmake::MessageType messageType = cmake::AUTHOR_WARNING;
+ switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0050))
+ {
+ case cmPolicies::WARN:
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0050) << "\n";
+ break;
+ case cmPolicies::OLD:
+ issueMessage = false;
+ break;
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::NEW:
+ messageType = cmake::FATAL_ERROR;
+ break;
+ }
+
+ if (issueMessage)
+ {
+ e << "The SOURCE signatures of add_custom_command are no longer "
+ "supported.";
+ this->Makefile->IssueMessage(messageType, e.str());
+ if (messageType == cmake::FATAL_ERROR)
+ {
+ return false;
+ }
+ }
+
// Use the old-style mode for backward compatibility.
- this->Makefile->AddCustomCommandOldStyle(target.c_str(), outputs, depends,
- source.c_str(), commandLines,
+ this->Makefile->AddCustomCommandOldStyle(target, outputs, depends,
+ source, commandLines,
comment);
}
@@ -367,7 +426,7 @@ cmAddCustomCommandCommand
{
std::string e = "attempted to have a file \"" + *o +
"\" in a source directory as an output of custom command.";
- this->SetError(e.c_str());
+ this->SetError(e);
cmSystemTools::SetFatalErrorOccured();
return false;
}
@@ -376,10 +435,10 @@ cmAddCustomCommandCommand
std::string::size_type pos = o->find_first_of("#<>");
if(pos != o->npos)
{
- cmOStringStream msg;
+ std::ostringstream msg;
msg << "called with OUTPUT containing a \"" << (*o)[pos]
<< "\". This character is not allowed.";
- this->SetError(msg.str().c_str());
+ this->SetError(msg.str());
return false;
}
}
diff --git a/Source/cmAddCustomCommandCommand.h b/Source/cmAddCustomCommandCommand.h
index 1cc1e3a75..1d6ddb288 100644
--- a/Source/cmAddCustomCommandCommand.h
+++ b/Source/cmAddCustomCommandCommand.h
@@ -13,12 +13,9 @@
#define cmAddCustomCommandCommand_h
#include "cmCommand.h"
-#include "cmDocumentGeneratorExpressions.h"
/** \class cmAddCustomCommandCommand
- * \brief
- *
- * cmAddCustomCommandCommand defines a new command (rule) that can
+ * \brief cmAddCustomCommandCommand defines a new command (rule) that can
* be executed within the build process
*
*/
@@ -44,142 +41,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const {return "add_custom_command";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Add a custom build rule to the generated build system.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- "There are two main signatures for add_custom_command "
- "The first signature is for adding a custom command "
- "to produce an output.\n"
- " add_custom_command(OUTPUT output1 [output2 ...]\n"
- " COMMAND command1 [ARGS] [args1...]\n"
- " [COMMAND command2 [ARGS] [args2...] ...]\n"
- " [MAIN_DEPENDENCY depend]\n"
- " [DEPENDS [depends...]]\n"
- " [IMPLICIT_DEPENDS <lang1> depend1\n"
- " [<lang2> depend2] ...]\n"
- " [WORKING_DIRECTORY dir]\n"
- " [COMMENT comment] [VERBATIM] [APPEND])\n"
- "This defines a command to generate specified OUTPUT file(s). "
- "A target created in the same directory (CMakeLists.txt file) that "
- "specifies any output of the custom command as a source file is given "
- "a rule to generate the file using the command at build time. "
- "Do not list the output in more than one independent target that may "
- "build in parallel or the two instances of the rule may conflict "
- "(instead use add_custom_target to drive the command and make the "
- "other targets depend on that one). "
- "If an output name is a relative path it will be interpreted "
- "relative to the build tree directory corresponding to the current "
- "source directory. "
- "Note that MAIN_DEPENDENCY is completely optional and is "
- "used as a suggestion to visual studio about where to hang the "
- "custom command. In makefile terms this creates a new target in the "
- "following form:\n"
- " OUTPUT: MAIN_DEPENDENCY DEPENDS\n"
- " COMMAND\n"
- "If more than one command is specified they will be executed in order. "
- "The optional ARGS argument is for backward compatibility and will be "
- "ignored.\n"
- "The second signature adds a custom command to a target "
- "such as a library or executable. This is useful for "
- "performing an operation before or after building the target. "
- "The command becomes part of the target and will only execute "
- "when the target itself is built. If the target is already built,"
- " the command will not execute.\n"
- " add_custom_command(TARGET target\n"
- " PRE_BUILD | PRE_LINK | POST_BUILD\n"
- " COMMAND command1 [ARGS] [args1...]\n"
- " [COMMAND command2 [ARGS] [args2...] ...]\n"
- " [WORKING_DIRECTORY dir]\n"
- " [COMMENT comment] [VERBATIM])\n"
- "This defines a new command that will be associated with "
- "building the specified target. When the command will "
- "happen is determined by which of the following is specified:\n"
- " PRE_BUILD - run before all other dependencies\n"
- " PRE_LINK - run after other dependencies\n"
- " POST_BUILD - run after the target has been built\n"
- "Note that the PRE_BUILD option is only supported on Visual "
- "Studio 7 or later. For all other generators PRE_BUILD "
- "will be treated as PRE_LINK.\n"
- "If WORKING_DIRECTORY is specified the command will be executed "
- "in the directory given. "
- "If it is a relative path it will be interpreted relative to the "
- "build tree directory corresponding to the current source directory. "
- "If COMMENT is set, the value will be displayed as a "
- "message before the commands are executed at build time. "
- "If APPEND is specified the COMMAND and DEPENDS option values "
- "are appended to the custom command for the first output specified. "
- "There must have already been a previous call to this command with "
- "the same output. The COMMENT, WORKING_DIRECTORY, and MAIN_DEPENDENCY "
- "options are currently ignored when APPEND is given, "
- "but may be used in the future."
- "\n"
- "If VERBATIM is given then all arguments to the commands will be "
- "escaped properly for the build tool so that the invoked command "
- "receives each argument unchanged. "
- "Note that one level of escapes is still used by the CMake language "
- "processor before add_custom_command even sees the arguments. "
- "Use of VERBATIM is recommended as it enables correct behavior. "
- "When VERBATIM is not given the behavior is platform specific because "
- "there is no protection of tool-specific special characters."
- "\n"
- "If the output of the custom command is not actually "
- "created as a file on disk it should be marked as SYMBOLIC with "
- "SET_SOURCE_FILES_PROPERTIES.\n"
-
- "The IMPLICIT_DEPENDS option requests scanning of implicit "
- "dependencies of an input file. The language given specifies the "
- "programming language whose corresponding dependency scanner should "
- "be used. Currently only C and CXX language scanners are supported. "
- "The language has to be specified for every file in the "
- "IMPLICIT_DEPENDS list. "
- "Dependencies discovered from the scanning are added to those of "
- "the custom command at build time. Note that the IMPLICIT_DEPENDS "
- "option is currently supported only for Makefile generators and "
- "will be ignored by other generators."
- "\n"
- "If COMMAND specifies an executable target (created by "
- "ADD_EXECUTABLE) it will automatically be replaced by the location "
- "of the executable created at build time. Additionally a "
- "target-level dependency will be added so that the executable target "
- "will be built before any target using this custom command. However "
- "this does NOT add a file-level dependency that would cause the "
- "custom command to re-run whenever the executable is recompiled."
- "\n"
- "Arguments to COMMAND may use \"generator expressions\" with the "
- "syntax \"$<...>\". "
- CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS
- "References to target names in generator expressions imply "
- "target-level dependencies, but NOT file-level dependencies. "
- "List target names with the DEPENDS option to add file dependencies."
- "\n"
- "The DEPENDS option specifies files on which the command depends. "
- "If any dependency is an OUTPUT of another custom command in the "
- "same directory (CMakeLists.txt file) CMake automatically brings the "
- "other custom command into the target in which this command is built. "
- "If DEPENDS is not specified the command will run whenever the OUTPUT "
- "is missing; if the command does not actually create the OUTPUT then "
- "the rule will always run. "
- "If DEPENDS specifies any target (created by an ADD_* command) "
- "a target-level dependency is created to make sure the target is "
- "built before any target using this custom command. Additionally, "
- "if the target is an executable or library a file-level dependency "
- "is created to cause the custom command to re-run whenever the target "
- "is recompiled.\n"
- ;
- }
+ virtual std::string GetName() const {return "add_custom_command";}
cmTypeMacro(cmAddCustomCommandCommand, cmCommand);
protected:
diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx
index 4eba88636..42bd71c4e 100644
--- a/Source/cmAddCustomTargetCommand.cxx
+++ b/Source/cmAddCustomTargetCommand.cxx
@@ -11,6 +11,9 @@
============================================================================*/
#include "cmAddCustomTargetCommand.h"
+#include "cmGeneratorExpression.h"
+#include "cmGlobalGenerator.h"
+
// cmAddCustomTargetCommand
bool cmAddCustomTargetCommand
::InitialPass(std::vector<std::string> const& args,
@@ -22,20 +25,17 @@ bool cmAddCustomTargetCommand
return false;
}
+ std::string targetName = args[0];
+
// Check the target name.
- if(args[0].find_first_of("/\\") != args[0].npos)
+ if(targetName.find_first_of("/\\") != targetName.npos)
{
- if(!this->Makefile->NeedBackwardsCompatibility(2,2))
- {
- cmOStringStream e;
- e << "called with invalid target name \"" << args[0]
- << "\". Target names may not contain a slash. "
- << "Use ADD_CUSTOM_COMMAND to generate files. "
- << "Set CMAKE_BACKWARDS_COMPATIBILITY to 2.2 "
- << "or lower to skip this check.";
- this->SetError(e.str().c_str());
- return false;
- }
+ std::ostringstream e;
+ e << "called with invalid target name \"" << targetName
+ << "\". Target names may not contain a slash. "
+ << "Use ADD_CUSTOM_COMMAND to generate files.";
+ this->SetError(e.str());
+ return false;
}
// Accumulate one command line at a time.
@@ -45,9 +45,10 @@ bool cmAddCustomTargetCommand
cmCustomCommandLines commandLines;
// Accumulate dependencies.
- std::vector<std::string> depends;
+ std::vector<std::string> depends, byproducts;
std::string working_directory;
bool verbatim = false;
+ bool uses_terminal = false;
std::string comment_buffer;
const char* comment = 0;
std::vector<std::string> sources;
@@ -56,10 +57,11 @@ bool cmAddCustomTargetCommand
enum tdoing {
doing_command,
doing_depends,
+ doing_byproducts,
doing_working_directory,
doing_comment,
doing_source,
- doing_verbatim
+ doing_nothing
};
tdoing doing = doing_command;
@@ -84,15 +86,24 @@ bool cmAddCustomTargetCommand
{
doing = doing_depends;
}
+ else if(copy == "BYPRODUCTS")
+ {
+ doing = doing_byproducts;
+ }
else if(copy == "WORKING_DIRECTORY")
{
doing = doing_working_directory;
}
else if(copy == "VERBATIM")
{
- doing = doing_verbatim;
+ doing = doing_nothing;
verbatim = true;
}
+ else if(copy == "USES_TERMINAL")
+ {
+ doing = doing_nothing;
+ uses_terminal = true;
+ }
else if (copy == "COMMENT")
{
doing = doing_comment;
@@ -122,6 +133,19 @@ bool cmAddCustomTargetCommand
case doing_command:
currentLine.push_back(copy);
break;
+ case doing_byproducts:
+ {
+ std::string filename;
+ if (!cmSystemTools::FileIsFullPath(copy.c_str()))
+ {
+ filename = this->Makefile->GetCurrentBinaryDirectory();
+ filename += "/";
+ }
+ filename += copy;
+ cmSystemTools::ConvertToUnixSlashes(filename);
+ byproducts.push_back(filename);
+ }
+ break;
case doing_depends:
{
std::string dep = copy;
@@ -143,16 +167,58 @@ bool cmAddCustomTargetCommand
}
}
- std::string::size_type pos = args[0].find_first_of("#<>");
- if(pos != args[0].npos)
+ std::string::size_type pos = targetName.find_first_of("#<>");
+ if(pos != targetName.npos)
{
- cmOStringStream msg;
- msg << "called with target name containing a \"" << args[0][pos]
+ std::ostringstream msg;
+ msg << "called with target name containing a \"" << targetName[pos]
<< "\". This character is not allowed.";
- this->SetError(msg.str().c_str());
+ this->SetError(msg.str());
return false;
}
+ // Some requirements on custom target names already exist
+ // and have been checked at this point.
+ // The following restrictions overlap but depend on policy CMP0037.
+ bool nameOk = cmGeneratorExpression::IsValidTargetName(targetName) &&
+ !cmGlobalGenerator::IsReservedTarget(targetName);
+ if (nameOk)
+ {
+ nameOk = targetName.find(":") == std::string::npos;
+ }
+ if (!nameOk)
+ {
+ cmake::MessageType messageType = cmake::AUTHOR_WARNING;
+ std::ostringstream e;
+ bool issueMessage = false;
+ switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0037))
+ {
+ case cmPolicies::WARN:
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0037) << "\n";
+ issueMessage = true;
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::NEW:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ issueMessage = true;
+ messageType = cmake::FATAL_ERROR;
+ }
+ if (issueMessage)
+ {
+ e << "The target name \"" << targetName <<
+ "\" is reserved or not valid for certain "
+ "CMake features, such as generator expressions, and may result "
+ "in undefined behavior.";
+ this->Makefile->IssueMessage(messageType, e.str());
+
+ if (messageType == cmake::FATAL_ERROR)
+ {
+ return false;
+ }
+ }
+ }
+
// Store the last command line finished.
if(!currentLine.empty())
{
@@ -163,9 +229,9 @@ bool cmAddCustomTargetCommand
// Enforce name uniqueness.
{
std::string msg;
- if(!this->Makefile->EnforceUniqueName(args[0], msg, true))
+ if(!this->Makefile->EnforceUniqueName(targetName, msg, true))
{
- this->SetError(msg.c_str());
+ this->SetError(msg);
return false;
}
}
@@ -173,17 +239,32 @@ bool cmAddCustomTargetCommand
// Convert working directory to a full path.
if(!working_directory.empty())
{
- const char* build_dir = this->Makefile->GetCurrentOutputDirectory();
+ const char* build_dir = this->Makefile->GetCurrentBinaryDirectory();
working_directory =
- cmSystemTools::CollapseFullPath(working_directory.c_str(), build_dir);
+ cmSystemTools::CollapseFullPath(working_directory, build_dir);
+ }
+
+ if (commandLines.empty() && !byproducts.empty())
+ {
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR,
+ "BYPRODUCTS may not be specified without any COMMAND");
+ return true;
+ }
+ if (commandLines.empty() && uses_terminal)
+ {
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR,
+ "USES_TERMINAL may not be specified without any COMMAND");
+ return true;
}
// Add the utility target to the makefile.
bool escapeOldStyle = !verbatim;
cmTarget* target =
- this->Makefile->AddUtilityCommand(args[0].c_str(), excludeFromAll,
- working_directory.c_str(), depends,
- commandLines, escapeOldStyle, comment);
+ this->Makefile->AddUtilityCommand(targetName, excludeFromAll,
+ working_directory.c_str(),
+ byproducts, depends,
+ commandLines, escapeOldStyle, comment,
+ uses_terminal);
// Add additional user-specified source files to the target.
target->AddSources(sources);
diff --git a/Source/cmAddCustomTargetCommand.h b/Source/cmAddCustomTargetCommand.h
index d4ed450f0..d2b00adf4 100644
--- a/Source/cmAddCustomTargetCommand.h
+++ b/Source/cmAddCustomTargetCommand.h
@@ -42,66 +42,9 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const
+ virtual std::string GetName() const
{return "add_custom_target";}
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Add a target with no output so it will always be built.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " add_custom_target(Name [ALL] [command1 [args1...]]\n"
- " [COMMAND command2 [args2...] ...]\n"
- " [DEPENDS depend depend depend ... ]\n"
- " [WORKING_DIRECTORY dir]\n"
- " [COMMENT comment] [VERBATIM]\n"
- " [SOURCES src1 [src2...]])\n"
- "Adds a target with the given name that executes the given commands. "
- "The target has no output file and is ALWAYS CONSIDERED OUT OF DATE "
- "even if the commands try to create a file with the name of the "
- "target. Use ADD_CUSTOM_COMMAND to generate a file with dependencies. "
- "By default nothing depends on the custom target. Use "
- "ADD_DEPENDENCIES to add dependencies to or from other targets. "
- "If the ALL option is specified "
- "it indicates that this target should be added to the default build "
- "target so that it will be run every time "
- "(the command cannot be called ALL). "
- "The command and arguments are optional and if not specified an "
- "empty target will be created. "
- "If WORKING_DIRECTORY is set, then the command will be run in that "
- "directory. "
- "If it is a relative path it will be interpreted relative to the "
- "build tree directory corresponding to the current source directory. "
- "If COMMENT is set, the value will be displayed as a "
- "message before the commands are executed at build time. "
- "Dependencies listed with the DEPENDS argument may reference files "
- "and outputs of custom commands created with add_custom_command() in "
- "the same directory (CMakeLists.txt file).\n"
- "If VERBATIM is given then all arguments to the commands will be "
- "escaped properly for the build tool so that the invoked command "
- "receives each argument unchanged. "
- "Note that one level of escapes is still used by the CMake language "
- "processor before add_custom_target even sees the arguments. "
- "Use of VERBATIM is recommended as it enables correct behavior. "
- "When VERBATIM is not given the behavior is platform specific because "
- "there is no protection of tool-specific special characters."
- "\n"
- "The SOURCES option specifies additional source files to be included "
- "in the custom target. "
- "Specified source files will be added to IDE project files for "
- "convenience in editing even if they have not build rules."
- ;
- }
-
cmTypeMacro(cmAddCustomTargetCommand, cmCommand);
};
diff --git a/Source/cmAddDefinitionsCommand.h b/Source/cmAddDefinitionsCommand.h
index ff2c4a038..9800fd291 100644
--- a/Source/cmAddDefinitionsCommand.h
+++ b/Source/cmAddDefinitionsCommand.h
@@ -41,36 +41,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const {return "add_definitions";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Adds -D define flags to the compilation of source files.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " add_definitions(-DFOO -DBAR ...)\n"
- "Adds flags to the compiler command line for sources in the current "
- "directory and below. This command can be used to add any flags, "
- "but it was originally intended to add preprocessor definitions. "
- "Flags beginning in -D or /D that look like preprocessor definitions "
- "are automatically added to the COMPILE_DEFINITIONS property for "
- "the current directory. Definitions with non-trivial values may be "
- "left in the set of flags instead of being converted for reasons of "
- "backwards compatibility. See documentation of the directory, "
- "target, and source file COMPILE_DEFINITIONS properties for details "
- "on adding preprocessor definitions to specific scopes and "
- "configurations."
- ;
- }
+ virtual std::string GetName() const {return "add_definitions";}
cmTypeMacro(cmAddDefinitionsCommand, cmCommand);
};
diff --git a/Source/cmAddDependenciesCommand.cxx b/Source/cmAddDependenciesCommand.cxx
index e4d7f7f1e..01e525311 100644
--- a/Source/cmAddDependenciesCommand.cxx
+++ b/Source/cmAddDependenciesCommand.cxx
@@ -10,7 +10,6 @@
See the License for more information.
============================================================================*/
#include "cmAddDependenciesCommand.h"
-#include "cmLocalGenerator.h"
#include "cmGlobalGenerator.h"
// cmDependenciesCommand
@@ -24,25 +23,25 @@ bool cmAddDependenciesCommand
}
std::string target_name = args[0];
- if(this->Makefile->IsAlias(target_name.c_str()))
+ if(this->Makefile->IsAlias(target_name))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Cannot add target-level dependencies to alias target \""
<< target_name << "\".\n";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
}
- if(cmTarget* target = this->Makefile->FindTargetToUse(target_name.c_str()))
+ if(cmTarget* target = this->Makefile->FindTargetToUse(target_name))
{
std::vector<std::string>::const_iterator s = args.begin();
++s; // skip over target_name
for (; s != args.end(); ++s)
{
- target->AddUtility(s->c_str());
+ target->AddUtility(*s, this->Makefile);
}
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Cannot add target-level dependencies to non-existent target \""
<< target_name << "\".\n"
<< "The add_dependencies works for top-level logical targets created "
diff --git a/Source/cmAddDependenciesCommand.h b/Source/cmAddDependenciesCommand.h
index ed8006765..db3712a24 100644
--- a/Source/cmAddDependenciesCommand.h
+++ b/Source/cmAddDependenciesCommand.h
@@ -40,36 +40,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "add_dependencies";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Add a dependency between top-level targets.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " add_dependencies(target-name depend-target1\n"
- " depend-target2 ...)\n"
- "Make a top-level target depend on other top-level targets. A "
- "top-level target is one created by ADD_EXECUTABLE, ADD_LIBRARY, "
- "or ADD_CUSTOM_TARGET. Adding dependencies with this command "
- "can be used to make sure one target is built before another target. "
- "Dependencies added to an IMPORTED target are followed transitively "
- "in its place since the target itself does not build. "
- "See the DEPENDS option of ADD_CUSTOM_TARGET "
- "and ADD_CUSTOM_COMMAND for adding file-level dependencies in custom "
- "rules. See the OBJECT_DEPENDS option in "
- "SET_SOURCE_FILES_PROPERTIES to add file-level dependencies to object "
- "files.";
- }
+ virtual std::string GetName() const { return "add_dependencies";}
cmTypeMacro(cmAddDependenciesCommand, cmCommand);
};
diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx
index 578525969..a84bb9dee 100644
--- a/Source/cmAddExecutableCommand.cxx
+++ b/Source/cmAddExecutableCommand.cxx
@@ -69,6 +69,46 @@ bool cmAddExecutableCommand
}
}
+ bool nameOk = cmGeneratorExpression::IsValidTargetName(exename) &&
+ !cmGlobalGenerator::IsReservedTarget(exename);
+
+ if (nameOk && !importTarget && !isAlias)
+ {
+ nameOk = exename.find(":") == std::string::npos;
+ }
+ if (!nameOk)
+ {
+ cmake::MessageType messageType = cmake::AUTHOR_WARNING;
+ std::ostringstream e;
+ bool issueMessage = false;
+ switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0037))
+ {
+ case cmPolicies::WARN:
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0037) << "\n";
+ issueMessage = true;
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::NEW:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ issueMessage = true;
+ messageType = cmake::FATAL_ERROR;
+ }
+ if (issueMessage)
+ {
+ e << "The target name \"" << exename <<
+ "\" is reserved or not valid for certain "
+ "CMake features, such as generator expressions, and may result "
+ "in undefined behavior.";
+ this->Makefile->IssueMessage(messageType, e.str());
+
+ if (messageType == cmake::FATAL_ERROR)
+ {
+ return false;
+ }
+ }
+ }
+
// Special modifiers are not allowed with IMPORTED signature.
if(importTarget
&& (use_win32 || use_macbundle || excludeFromAll))
@@ -91,9 +131,9 @@ bool cmAddExecutableCommand
}
if (isAlias)
{
- if(!cmGeneratorExpression::IsValidTargetName(exename.c_str()))
+ if(!cmGeneratorExpression::IsValidTargetName(exename))
{
- this->SetError(("Invalid name for ALIAS: " + exename).c_str());
+ this->SetError("Invalid name for ALIAS: " + exename);
return false;
}
if(excludeFromAll)
@@ -108,51 +148,51 @@ bool cmAddExecutableCommand
}
if(args.size() != 3)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "ALIAS requires exactly one target argument.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
const char *aliasedName = s->c_str();
if(this->Makefile->IsAlias(aliasedName))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "cannot create ALIAS target \"" << exename
<< "\" because target \"" << aliasedName << "\" is itself an ALIAS.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
cmTarget *aliasedTarget =
this->Makefile->FindTargetToUse(aliasedName, true);
if(!aliasedTarget)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "cannot create ALIAS target \"" << exename
<< "\" because target \"" << aliasedName << "\" does not already "
"exist.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
- cmTarget::TargetType type = aliasedTarget->GetType();
- if(type != cmTarget::EXECUTABLE)
+ cmState::TargetType type = aliasedTarget->GetType();
+ if(type != cmState::EXECUTABLE)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "cannot create ALIAS target \"" << exename
<< "\" because target \"" << aliasedName << "\" is not an "
"executable.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
if(aliasedTarget->IsImported())
{
- cmOStringStream e;
+ std::ostringstream e;
e << "cannot create ALIAS target \"" << exename
<< "\" because target \"" << aliasedName << "\" is IMPORTED.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
- this->Makefile->AddAlias(exename.c_str(), aliasedTarget);
+ this->Makefile->AddAlias(exename, aliasedName);
return true;
}
@@ -160,17 +200,17 @@ bool cmAddExecutableCommand
if(importTarget)
{
// Make sure the target does not already exist.
- if(this->Makefile->FindTargetToUse(exename.c_str()))
+ if(this->Makefile->FindTargetToUse(exename))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "cannot create imported target \"" << exename
<< "\" because another target with the same name already exists.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
// Create the imported target.
- this->Makefile->AddImportedTarget(exename.c_str(), cmTarget::EXECUTABLE,
+ this->Makefile->AddImportedTarget(exename, cmState::EXECUTABLE,
importGlobal);
return true;
}
@@ -180,7 +220,7 @@ bool cmAddExecutableCommand
std::string msg;
if(!this->Makefile->EnforceUniqueName(exename, msg))
{
- this->SetError(msg.c_str());
+ this->SetError(msg);
return false;
}
}
diff --git a/Source/cmAddExecutableCommand.h b/Source/cmAddExecutableCommand.h
index 2774ce841..e134077b5 100644
--- a/Source/cmAddExecutableCommand.h
+++ b/Source/cmAddExecutableCommand.h
@@ -41,87 +41,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "add_executable";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return
- "Add an executable to the project using the specified source files.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " add_executable(<name> [WIN32] [MACOSX_BUNDLE]\n"
- " [EXCLUDE_FROM_ALL]\n"
- " source1 source2 ... sourceN)\n"
- "Adds an executable target called <name> to be built from the "
- "source files listed in the command invocation. "
- "The <name> corresponds to the logical target name and must be "
- "globally unique within a project. "
- "The actual file name of the executable built is constructed based on "
- "conventions of the native platform "
- "(such as <name>.exe or just <name>). "
- "\n"
- "By default the executable file will be created in the build tree "
- "directory corresponding to the source tree directory in which "
- "the command was invoked. "
- "See documentation of the RUNTIME_OUTPUT_DIRECTORY "
- "target property to change this location. "
- "See documentation of the OUTPUT_NAME target property to change "
- "the <name> part of the final file name. "
- "\n"
- "If WIN32 is given the property WIN32_EXECUTABLE will be set on the "
- "target created. "
- "See documentation of that target property for details."
- "\n"
- "If MACOSX_BUNDLE is given the corresponding property will be "
- "set on the created target. "
- "See documentation of the MACOSX_BUNDLE target property for details."
- "\n"
- "If EXCLUDE_FROM_ALL is given the corresponding property will be "
- "set on the created target. "
- "See documentation of the EXCLUDE_FROM_ALL target property for "
- "details."
- "\n"
- "The add_executable command can also create IMPORTED executable "
- "targets using this signature:\n"
- " add_executable(<name> IMPORTED [GLOBAL])\n"
- "An IMPORTED executable target references an executable file located "
- "outside the project. "
- "No rules are generated to build it. "
- "The target name has scope in the directory in which it is created "
- "and below, but the GLOBAL option extends visibility. "
- "It may be referenced like any target built within the project. "
- "IMPORTED executables are useful for convenient reference from "
- "commands like add_custom_command. "
- "Details about the imported executable are specified by setting "
- "properties whose names begin in \"IMPORTED_\". "
- "The most important such property is IMPORTED_LOCATION "
- "(and its per-configuration version IMPORTED_LOCATION_<CONFIG>) "
- "which specifies the location of the main executable file on disk. "
- "See documentation of the IMPORTED_* properties for more information."
- "\n"
- "The signature\n"
- " add_executable(<name> ALIAS <target>)\n"
- "creates an alias, such that <name> can be used to refer to <target> "
- "in subsequent commands. The <name> does not appear in the generated "
- "buildsystem as a make target. The <target> may not be an IMPORTED "
- "target or an ALIAS. Alias targets can be used as linkable targets, "
- "targets to read properties from, executables for custom commands and "
- "custom targets. They can also be tested for existance with the "
- "regular if(TARGET) subcommand. The <name> may not be used to modify "
- "properties of <target>, that is, it may not be used as the operand of "
- "set_property, set_target_properties, target_link_libraries etc. An "
- "ALIAS target may not be installed of exported."
- ;
- }
+ virtual std::string GetName() const { return "add_executable";}
cmTypeMacro(cmAddExecutableCommand, cmCommand);
};
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index cbc6ed1e9..5296cbb36 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -12,6 +12,7 @@
#include "cmAddLibraryCommand.h"
#include "cmake.h"
+#include "cmState.h"
// cmLibraryCommand
bool cmAddLibraryCommand
@@ -24,10 +25,10 @@ bool cmAddLibraryCommand
}
// Library type defaults to value of BUILD_SHARED_LIBS, if it exists,
// otherwise it defaults to static library.
- cmTarget::TargetType type = cmTarget::SHARED_LIBRARY;
+ cmState::TargetType type = cmState::SHARED_LIBRARY;
if (cmSystemTools::IsOff(this->Makefile->GetDefinition("BUILD_SHARED_LIBS")))
{
- type = cmTarget::STATIC_LIBRARY;
+ type = cmState::STATIC_LIBRARY;
}
bool excludeFromAll = false;
bool importTarget = false;
@@ -49,41 +50,117 @@ bool cmAddLibraryCommand
std::string libType = *s;
if(libType == "STATIC")
{
+ if (type == cmState::INTERFACE_LIBRARY)
+ {
+ std::ostringstream e;
+ e << "INTERFACE library specified with conflicting STATIC type.";
+ this->SetError(e.str());
+ return false;
+ }
++s;
- type = cmTarget::STATIC_LIBRARY;
+ type = cmState::STATIC_LIBRARY;
haveSpecifiedType = true;
}
else if(libType == "SHARED")
{
+ if (type == cmState::INTERFACE_LIBRARY)
+ {
+ std::ostringstream e;
+ e << "INTERFACE library specified with conflicting SHARED type.";
+ this->SetError(e.str());
+ return false;
+ }
++s;
- type = cmTarget::SHARED_LIBRARY;
+ type = cmState::SHARED_LIBRARY;
haveSpecifiedType = true;
}
else if(libType == "MODULE")
{
+ if (type == cmState::INTERFACE_LIBRARY)
+ {
+ std::ostringstream e;
+ e << "INTERFACE library specified with conflicting MODULE type.";
+ this->SetError(e.str());
+ return false;
+ }
++s;
- type = cmTarget::MODULE_LIBRARY;
+ type = cmState::MODULE_LIBRARY;
haveSpecifiedType = true;
}
else if(libType == "OBJECT")
{
+ if (type == cmState::INTERFACE_LIBRARY)
+ {
+ std::ostringstream e;
+ e << "INTERFACE library specified with conflicting OBJECT type.";
+ this->SetError(e.str());
+ return false;
+ }
++s;
- type = cmTarget::OBJECT_LIBRARY;
+ type = cmState::OBJECT_LIBRARY;
haveSpecifiedType = true;
}
else if(libType == "UNKNOWN")
{
+ if (type == cmState::INTERFACE_LIBRARY)
+ {
+ std::ostringstream e;
+ e << "INTERFACE library specified with conflicting UNKNOWN type.";
+ this->SetError(e.str());
+ return false;
+ }
++s;
- type = cmTarget::UNKNOWN_LIBRARY;
+ type = cmState::UNKNOWN_LIBRARY;
haveSpecifiedType = true;
}
else if(libType == "ALIAS")
{
+ if (type == cmState::INTERFACE_LIBRARY)
+ {
+ std::ostringstream e;
+ e << "INTERFACE library specified with conflicting ALIAS type.";
+ this->SetError(e.str());
+ return false;
+ }
++s;
isAlias = true;
}
+ else if(libType == "INTERFACE")
+ {
+ if (haveSpecifiedType)
+ {
+ std::ostringstream e;
+ e << "INTERFACE library specified with conflicting/multiple types.";
+ this->SetError(e.str());
+ return false;
+ }
+ if (isAlias)
+ {
+ std::ostringstream e;
+ e << "INTERFACE library specified with conflicting ALIAS type.";
+ this->SetError(e.str());
+ return false;
+ }
+ if (excludeFromAll)
+ {
+ std::ostringstream e;
+ e << "INTERFACE library may not be used with EXCLUDE_FROM_ALL.";
+ this->SetError(e.str());
+ return false;
+ }
+ ++s;
+ type = cmState::INTERFACE_LIBRARY;
+ haveSpecifiedType = true;
+ }
else if(*s == "EXCLUDE_FROM_ALL")
{
+ if (type == cmState::INTERFACE_LIBRARY)
+ {
+ std::ostringstream e;
+ e << "INTERFACE library may not be used with EXCLUDE_FROM_ALL.";
+ this->SetError(e.str());
+ return false;
+ }
++s;
excludeFromAll = true;
}
@@ -97,16 +174,85 @@ bool cmAddLibraryCommand
++s;
importGlobal = true;
}
+ else if(type == cmState::INTERFACE_LIBRARY && *s == "GLOBAL")
+ {
+ std::ostringstream e;
+ e << "GLOBAL option may only be used with IMPORTED libraries.";
+ this->SetError(e.str());
+ return false;
+ }
else
{
break;
}
}
+
+ if (type == cmState::INTERFACE_LIBRARY)
+ {
+ if (s != args.end())
+ {
+ std::ostringstream e;
+ e << "INTERFACE library requires no source arguments.";
+ this->SetError(e.str());
+ return false;
+ }
+ if (importGlobal && !importTarget)
+ {
+ std::ostringstream e;
+ e << "INTERFACE library specified as GLOBAL, but not as IMPORTED.";
+ this->SetError(e.str());
+ return false;
+ }
+ }
+
+ bool nameOk = cmGeneratorExpression::IsValidTargetName(libName) &&
+ !cmGlobalGenerator::IsReservedTarget(libName);
+
+ if (nameOk && !importTarget && !isAlias)
+ {
+ nameOk = libName.find(":") == std::string::npos;
+ }
+ if (!nameOk)
+ {
+ cmake::MessageType messageType = cmake::AUTHOR_WARNING;
+ std::ostringstream e;
+ bool issueMessage = false;
+ switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0037))
+ {
+ case cmPolicies::WARN:
+ if(type != cmState::INTERFACE_LIBRARY)
+ {
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0037) << "\n";
+ issueMessage = true;
+ }
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::NEW:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ issueMessage = true;
+ messageType = cmake::FATAL_ERROR;
+ }
+ if (issueMessage)
+ {
+ e << "The target name \"" << libName <<
+ "\" is reserved or not valid for certain "
+ "CMake features, such as generator expressions, and may result "
+ "in undefined behavior.";
+ this->Makefile->IssueMessage(messageType, e.str());
+
+ if (messageType == cmake::FATAL_ERROR)
+ {
+ return false;
+ }
+ }
+ }
+
if (isAlias)
{
- if(!cmGeneratorExpression::IsValidTargetName(libName.c_str()))
+ if(!cmGeneratorExpression::IsValidTargetName(libName))
{
- this->SetError(("Invalid name for ALIAS: " + libName).c_str());
+ this->SetError("Invalid name for ALIAS: " + libName);
return false;
}
if(excludeFromAll)
@@ -121,53 +267,54 @@ bool cmAddLibraryCommand
}
if(args.size() != 3)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "ALIAS requires exactly one target argument.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
const char *aliasedName = s->c_str();
if(this->Makefile->IsAlias(aliasedName))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "cannot create ALIAS target \"" << libName
<< "\" because target \"" << aliasedName << "\" is itself an ALIAS.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
cmTarget *aliasedTarget =
this->Makefile->FindTargetToUse(aliasedName, true);
if(!aliasedTarget)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "cannot create ALIAS target \"" << libName
<< "\" because target \"" << aliasedName << "\" does not already "
"exist.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
- cmTarget::TargetType aliasedType = aliasedTarget->GetType();
- if(aliasedType != cmTarget::SHARED_LIBRARY
- && aliasedType != cmTarget::STATIC_LIBRARY
- && aliasedType != cmTarget::MODULE_LIBRARY
- && aliasedType != cmTarget::OBJECT_LIBRARY)
+ cmState::TargetType aliasedType = aliasedTarget->GetType();
+ if(aliasedType != cmState::SHARED_LIBRARY
+ && aliasedType != cmState::STATIC_LIBRARY
+ && aliasedType != cmState::MODULE_LIBRARY
+ && aliasedType != cmState::OBJECT_LIBRARY
+ && aliasedType != cmState::INTERFACE_LIBRARY)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "cannot create ALIAS target \"" << libName
<< "\" because target \"" << aliasedName << "\" is not a library.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
if(aliasedTarget->IsImported())
{
- cmOStringStream e;
+ std::ostringstream e;
e << "cannot create ALIAS target \"" << libName
<< "\" because target \"" << aliasedName << "\" is IMPORTED.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
- this->Makefile->AddAlias(libName.c_str(), aliasedTarget);
+ this->Makefile->AddAlias(libName, aliasedName);
return true;
}
@@ -181,19 +328,19 @@ bool cmAddLibraryCommand
CMAKE_${LANG}_CREATE_SHARED_LIBRARY is defined and if not default to
STATIC. But at this point we know only the name of the target, but not
yet its linker language. */
- if ((type != cmTarget::STATIC_LIBRARY) &&
- (type != cmTarget::OBJECT_LIBRARY) &&
- (this->Makefile->GetCMakeInstance()->GetPropertyAsBool(
+ if ((type == cmState::SHARED_LIBRARY ||
+ type == cmState::MODULE_LIBRARY) &&
+ (this->Makefile->GetState()->GetGlobalPropertyAsBool(
"TARGET_SUPPORTS_SHARED_LIBS") == false))
{
- cmOStringStream w;
+ std::ostringstream w;
w <<
"ADD_LIBRARY called with " <<
- (type==cmTarget::SHARED_LIBRARY ? "SHARED" : "MODULE") <<
+ (type==cmState::SHARED_LIBRARY ? "SHARED" : "MODULE") <<
" option but the target platform does not support dynamic linking. "
"Building a STATIC library instead. This may lead to problems.";
this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
- type = cmTarget::STATIC_LIBRARY;
+ type = cmState::STATIC_LIBRARY;
}
// Handle imported target creation.
@@ -205,7 +352,7 @@ bool cmAddLibraryCommand
this->SetError("called with IMPORTED argument but no library type.");
return false;
}
- if(type == cmTarget::OBJECT_LIBRARY)
+ if(type == cmState::OBJECT_LIBRARY)
{
this->Makefile->IssueMessage(
cmake::FATAL_ERROR,
@@ -213,24 +360,34 @@ bool cmAddLibraryCommand
);
return true;
}
+ if(type == cmState::INTERFACE_LIBRARY)
+ {
+ if (!cmGeneratorExpression::IsValidTargetName(libName))
+ {
+ std::ostringstream e;
+ e << "Invalid name for IMPORTED INTERFACE library target: " << libName;
+ this->SetError(e.str());
+ return false;
+ }
+ }
// Make sure the target does not already exist.
- if(this->Makefile->FindTargetToUse(libName.c_str()))
+ if(this->Makefile->FindTargetToUse(libName))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "cannot create imported target \"" << libName
<< "\" because another target with the same name already exists.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
// Create the imported target.
- this->Makefile->AddImportedTarget(libName.c_str(), type, importGlobal);
+ this->Makefile->AddImportedTarget(libName, type, importGlobal);
return true;
}
// A non-imported target may not have UNKNOWN type.
- if(type == cmTarget::UNKNOWN_LIBRARY)
+ if(type == cmState::UNKNOWN_LIBRARY)
{
this->Makefile->IssueMessage(
cmake::FATAL_ERROR,
@@ -244,11 +401,31 @@ bool cmAddLibraryCommand
std::string msg;
if(!this->Makefile->EnforceUniqueName(libName, msg))
{
- this->SetError(msg.c_str());
+ this->SetError(msg);
return false;
}
}
+ std::vector<std::string> srclists;
+
+ if(type == cmState::INTERFACE_LIBRARY)
+ {
+ if (!cmGeneratorExpression::IsValidTargetName(libName)
+ || libName.find("::") != std::string::npos)
+ {
+ std::ostringstream e;
+ e << "Invalid name for INTERFACE library target: " << libName;
+ this->SetError(e.str());
+ return false;
+ }
+
+ this->Makefile->AddLibrary(libName,
+ type,
+ srclists,
+ excludeFromAll);
+ return true;
+ }
+
if (s == args.end())
{
std::string msg = "You have called ADD_LIBRARY for library ";
@@ -258,14 +435,9 @@ bool cmAddLibraryCommand
cmSystemTools::Message(msg.c_str() ,"Warning");
}
- std::vector<std::string> srclists;
- while (s != args.end())
- {
- srclists.push_back(*s);
- ++s;
- }
+ srclists.insert(srclists.end(), s, args.end());
- this->Makefile->AddLibrary(libName.c_str(), type, srclists, excludeFromAll);
+ this->Makefile->AddLibrary(libName, type, srclists, excludeFromAll);
return true;
}
diff --git a/Source/cmAddLibraryCommand.h b/Source/cmAddLibraryCommand.h
index 59354b0f5..350708b23 100644
--- a/Source/cmAddLibraryCommand.h
+++ b/Source/cmAddLibraryCommand.h
@@ -41,118 +41,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "add_library";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Add a library to the project using the specified source files.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " add_library(<name> [STATIC | SHARED | MODULE]\n"
- " [EXCLUDE_FROM_ALL]\n"
- " source1 source2 ... sourceN)\n"
- "Adds a library target called <name> to be built from the "
- "source files listed in the command invocation. "
- "The <name> corresponds to the logical target name and must be "
- "globally unique within a project. "
- "The actual file name of the library built is constructed based on "
- "conventions of the native platform "
- "(such as lib<name>.a or <name>.lib)."
- "\n"
- "STATIC, SHARED, or MODULE may be given to specify the type of library "
- "to be created. "
- "STATIC libraries are archives of object files for use when linking "
- "other targets. "
- "SHARED libraries are linked dynamically and loaded at runtime. "
- "MODULE libraries are plugins that are not linked into other targets "
- "but may be loaded dynamically at runtime using dlopen-like "
- "functionality. "
- "If no type is given explicitly the type is STATIC or SHARED based "
- "on whether the current value of the variable BUILD_SHARED_LIBS is "
- "true. "
- "For SHARED and MODULE libraries the POSITION_INDEPENDENT_CODE "
- "target property is set to TRUE automatically."
- "\n"
- "By default the library file will be created in the build tree "
- "directory corresponding to the source tree directory in which "
- "the command was invoked. "
- "See documentation of the ARCHIVE_OUTPUT_DIRECTORY, "
- "LIBRARY_OUTPUT_DIRECTORY, and RUNTIME_OUTPUT_DIRECTORY "
- "target properties to change this location. "
- "See documentation of the OUTPUT_NAME target property to change "
- "the <name> part of the final file name. "
- "\n"
- "If EXCLUDE_FROM_ALL is given the corresponding property will be "
- "set on the created target. "
- "See documentation of the EXCLUDE_FROM_ALL target property for "
- "details."
- "\n"
- "The add_library command can also create IMPORTED library "
- "targets using this signature:\n"
- " add_library(<name> <SHARED|STATIC|MODULE|UNKNOWN> IMPORTED\n"
- " [GLOBAL])\n"
- "An IMPORTED library target references a library file located "
- "outside the project. "
- "No rules are generated to build it. "
- "The target name has scope in the directory in which it is created "
- "and below, but the GLOBAL option extends visibility. "
- "It may be referenced like any target built within the project. "
- "IMPORTED libraries are useful for convenient reference from "
- "commands like target_link_libraries. "
- "Details about the imported library are specified by setting "
- "properties whose names begin in \"IMPORTED_\". "
- "The most important such property is IMPORTED_LOCATION "
- "(and its per-configuration version IMPORTED_LOCATION_<CONFIG>) "
- "which specifies the location of the main library file on disk. "
- "See documentation of the IMPORTED_* properties for more information."
- "\n"
- "The signature\n"
- " add_library(<name> OBJECT <src>...)\n"
- "creates a special \"object library\" target. "
- "An object library compiles source files but does not archive or link "
- "their object files into a library. "
- "Instead other targets created by add_library or add_executable may "
- "reference the objects using an expression of the form "
- "$<TARGET_OBJECTS:objlib> as a source, where \"objlib\" is the "
- "object library name. "
- "For example:\n"
- " add_library(... $<TARGET_OBJECTS:objlib> ...)\n"
- " add_executable(... $<TARGET_OBJECTS:objlib> ...)\n"
- "will include objlib's object files in a library and an executable "
- "along with those compiled from their own sources. "
- "Object libraries may contain only sources (and headers) that compile "
- "to object files. "
- "They may contain custom commands generating such sources, but not "
- "PRE_BUILD, PRE_LINK, or POST_BUILD commands. "
- "Object libraries cannot be imported, exported, installed, or linked."
- " "
- "Some native build systems may not like targets that have only "
- "object files, so consider adding at least one real source file "
- "to any target that references $<TARGET_OBJECTS:objlib>."
- "\n"
- "The signature\n"
- " add_library(<name> ALIAS <target>)\n"
- "creates an alias, such that <name> can be used to refer to <target> "
- "in subsequent commands. The <name> does not appear in the generated "
- "buildsystem as a make target. The <target> may not be an IMPORTED "
- "target or an ALIAS. Alias targets can be used as linkable targets, "
- "targets to read properties from. They can also be tested for "
- "existance with the "
- "regular if(TARGET) subcommand. The <name> may not be used to modify "
- "properties of <target>, that is, it may not be used as the operand of "
- "set_property, set_target_properties, target_link_libraries etc. An "
- "ALIAS target may not be installed of exported."
- ;
- }
+ virtual std::string GetName() const { return "add_library";}
cmTypeMacro(cmAddLibraryCommand, cmCommand);
};
diff --git a/Source/cmAddSubDirectoryCommand.cxx b/Source/cmAddSubDirectoryCommand.cxx
index 5b1c9c668..69c6a14d4 100644
--- a/Source/cmAddSubDirectoryCommand.cxx
+++ b/Source/cmAddSubDirectoryCommand.cxx
@@ -37,7 +37,7 @@ bool cmAddSubDirectoryCommand::InitialPass
excludeFromAll = true;
continue;
}
- else if (!binArg.size())
+ else if (binArg.empty())
{
binArg = *i;
}
@@ -57,19 +57,19 @@ bool cmAddSubDirectoryCommand::InitialPass
}
else
{
- srcPath = this->Makefile->GetCurrentDirectory();
+ srcPath = this->Makefile->GetCurrentSourceDirectory();
srcPath += "/";
srcPath += srcArg;
}
- if(!cmSystemTools::FileIsDirectory(srcPath.c_str()))
+ if(!cmSystemTools::FileIsDirectory(srcPath))
{
std::string error = "given source \"";
error += srcArg;
error += "\" which is not an existing directory.";
- this->SetError(error.c_str());
+ this->SetError(error);
return false;
}
- srcPath = cmSystemTools::CollapseFullPath(srcPath.c_str());
+ srcPath = cmSystemTools::CollapseFullPath(srcPath);
// Compute the full path to the binary directory.
std::string binPath;
@@ -78,23 +78,23 @@ bool cmAddSubDirectoryCommand::InitialPass
// No binary directory was specified. If the source directory is
// not a subdirectory of the current directory then it is an
// error.
- if(!cmSystemTools::IsSubDirectory(srcPath.c_str(),
- this->Makefile->GetCurrentDirectory()))
+ if(!cmSystemTools::IsSubDirectory(srcPath,
+ this->Makefile->GetCurrentSourceDirectory()))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "not given a binary directory but the given source directory "
<< "\"" << srcPath << "\" is not a subdirectory of \""
- << this->Makefile->GetCurrentDirectory() << "\". "
+ << this->Makefile->GetCurrentSourceDirectory() << "\". "
<< "When specifying an out-of-tree source a binary directory "
<< "must be explicitly specified.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
// Remove the CurrentDirectory from the srcPath and replace it
// with the CurrentOutputDirectory.
- const char* src = this->Makefile->GetCurrentDirectory();
- const char* bin = this->Makefile->GetCurrentOutputDirectory();
+ const char* src = this->Makefile->GetCurrentSourceDirectory();
+ const char* bin = this->Makefile->GetCurrentBinaryDirectory();
size_t srcLen = strlen(src);
size_t binLen = strlen(bin);
if(srcLen > 0 && src[srcLen-1] == '/')
@@ -113,16 +113,16 @@ bool cmAddSubDirectoryCommand::InitialPass
}
else
{
- binPath = this->Makefile->GetCurrentOutputDirectory();
+ binPath = this->Makefile->GetCurrentBinaryDirectory();
binPath += "/";
binPath += binArg;
}
}
- binPath = cmSystemTools::CollapseFullPath(binPath.c_str());
+ binPath = cmSystemTools::CollapseFullPath(binPath);
// Add the subdirectory using the computed full paths.
- this->Makefile->AddSubDirectory(srcPath.c_str(), binPath.c_str(),
- excludeFromAll, false, true);
+ this->Makefile->AddSubDirectory(srcPath, binPath,
+ excludeFromAll, true);
return true;
}
diff --git a/Source/cmAddSubDirectoryCommand.h b/Source/cmAddSubDirectoryCommand.h
index e7f907c3f..abf3efcd9 100644
--- a/Source/cmAddSubDirectoryCommand.h
+++ b/Source/cmAddSubDirectoryCommand.h
@@ -42,54 +42,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "add_subdirectory";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Add a subdirectory to the build.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " add_subdirectory(source_dir [binary_dir] \n"
- " [EXCLUDE_FROM_ALL])\n"
- "Add a subdirectory to the build. The source_dir specifies the "
- "directory in which the source CMakeLists.txt and code files are "
- "located. If it is a relative "
- "path it will be evaluated with respect to the current "
- "directory (the typical usage), but it may also be an absolute path. "
- "The binary_dir specifies the directory in which to place the output "
- "files. If it is a relative path it will be evaluated with respect "
- "to the current output directory, but it may also be an absolute "
- "path. If binary_dir is not specified, the value of source_dir, "
- "before expanding any relative path, will be used (the typical usage). "
- "The CMakeLists.txt file in the specified source directory will "
- "be processed immediately by CMake before processing in the current "
- "input file continues beyond this command.\n"
-
- "If the EXCLUDE_FROM_ALL argument is provided then targets in the "
- "subdirectory will not be included in the ALL target of the parent "
- "directory by default, and will be excluded from IDE project files. "
- "Users must explicitly build targets in the subdirectory. "
- "This is meant for use when the subdirectory contains a separate part "
- "of the project that is useful but not necessary, such as a set of "
- "examples. "
- "Typically the subdirectory should contain its own project() command "
- "invocation so that a full build system will be generated in the "
- "subdirectory (such as a VS IDE solution file). "
- "Note that inter-target dependencies supercede this exclusion. "
- "If a target built by the parent project depends on a target in the "
- "subdirectory, the dependee target will be included in the parent "
- "project build system to satisfy the dependency."
- ;
- }
+ virtual std::string GetName() const { return "add_subdirectory";}
cmTypeMacro(cmAddSubDirectoryCommand, cmCommand);
};
diff --git a/Source/cmAddTestCommand.cxx b/Source/cmAddTestCommand.cxx
index a9165f5b1..3472b9870 100644
--- a/Source/cmAddTestCommand.cxx
+++ b/Source/cmAddTestCommand.cxx
@@ -36,31 +36,27 @@ bool cmAddTestCommand
// Collect the command with arguments.
std::vector<std::string> command;
- for(std::vector<std::string>::const_iterator it = args.begin() + 1;
- it != args.end(); ++it)
- {
- command.push_back(*it);
- }
+ command.insert(command.end(), args.begin() + 1, args.end());
// Create the test but add a generator only the first time it is
// seen. This preserves behavior from before test generators.
- cmTest* test = this->Makefile->GetTest(args[0].c_str());
+ cmTest* test = this->Makefile->GetTest(args[0]);
if(test)
{
// If the test was already added by a new-style signature do not
// allow it to be duplicated.
if(!test->GetOldStyle())
{
- cmOStringStream e;
+ std::ostringstream e;
e << " given test name \"" << args[0]
<< "\" which already exists in this directory.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
else
{
- test = this->Makefile->CreateTest(args[0].c_str());
+ test = this->Makefile->CreateTest(args[0]);
test->SetOldStyle(true);
this->Makefile->AddTestGenerator(new cmTestGenerator(test));
}
@@ -135,9 +131,9 @@ bool cmAddTestCommand::HandleNameMode(std::vector<std::string> const& args)
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << " given unknown argument:\n " << args[i] << "\n";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
@@ -157,17 +153,17 @@ bool cmAddTestCommand::HandleNameMode(std::vector<std::string> const& args)
}
// Require a unique test name within the directory.
- if(this->Makefile->GetTest(name.c_str()))
+ if(this->Makefile->GetTest(name))
{
- cmOStringStream e;
+ std::ostringstream e;
e << " given test NAME \"" << name
<< "\" which already exists in this directory.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
// Add the test.
- cmTest* test = this->Makefile->CreateTest(name.c_str());
+ cmTest* test = this->Makefile->CreateTest(name);
test->SetOldStyle(false);
test->SetCommand(command);
if(!working_directory.empty())
diff --git a/Source/cmAddTestCommand.h b/Source/cmAddTestCommand.h
index ec7fda3f3..624288f57 100644
--- a/Source/cmAddTestCommand.h
+++ b/Source/cmAddTestCommand.h
@@ -13,7 +13,6 @@
#define cmAddTestCommand_h
#include "cmCommand.h"
-#include "cmDocumentGeneratorExpressions.h"
/** \class cmAddTestCommand
* \brief Add a test to the lists of tests to run.
@@ -41,59 +40,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "add_test";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Add a test to the project with the specified arguments.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " add_test(testname Exename arg1 arg2 ... )\n"
- "If the ENABLE_TESTING command has been run, this command adds a "
- "test target to the current directory. If ENABLE_TESTING has not "
- "been run, this command does nothing. "
- "The tests are run by the testing subsystem by executing Exename "
- "with the specified arguments. Exename can be either an executable "
- "built by this project or an arbitrary executable on the "
- "system (like tclsh). The test will be run with the current working "
- "directory set to the CMakeList.txt files corresponding directory "
- "in the binary tree.\n"
- "\n"
- " add_test(NAME <name> [CONFIGURATIONS [Debug|Release|...]]\n"
- " [WORKING_DIRECTORY dir]\n"
- " COMMAND <command> [arg1 [arg2 ...]])\n"
- "Add a test called <name>. "
- "The test name may not contain spaces, quotes, or other characters "
- "special in CMake syntax. "
- "If COMMAND specifies an executable target (created by "
- "add_executable) it will automatically be replaced by the location "
- "of the executable created at build time. "
- "If a CONFIGURATIONS option is given then the test will be executed "
- "only when testing under one of the named configurations. "
- "If a WORKING_DIRECTORY option is given then the test will be executed "
- "in the given directory."
- "\n"
- "Arguments after COMMAND may use \"generator expressions\" with the "
- "syntax \"$<...>\". "
- CM_DOCUMENT_ADD_TEST_GENERATOR_EXPRESSIONS
- "Example usage:\n"
- " add_test(NAME mytest\n"
- " COMMAND testDriver --config $<CONFIGURATION>\n"
- " --exe $<TARGET_FILE:myexe>)\n"
- "This creates a test \"mytest\" whose command runs a testDriver "
- "tool passing the configuration name and the full path to the "
- "executable file produced by target \"myexe\"."
- ;
- }
+ virtual std::string GetName() const { return "add_test";}
cmTypeMacro(cmAddTestCommand, cmCommand);
private:
diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h
new file mode 100644
index 000000000..bb65ea556
--- /dev/null
+++ b/Source/cmAlgorithms.h
@@ -0,0 +1,372 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Stephen Kelly <steveire@gmail.com>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmAlgorithms_h
+#define cmAlgorithms_h
+
+#include "cmStandardIncludes.h"
+
+inline bool cmHasLiteralPrefixImpl(const std::string &str1,
+ const char *str2,
+ size_t N)
+{
+ return strncmp(str1.c_str(), str2, N) == 0;
+}
+
+inline bool cmHasLiteralPrefixImpl(const char* str1,
+ const char *str2,
+ size_t N)
+{
+ return strncmp(str1, str2, N) == 0;
+}
+
+inline bool cmHasLiteralSuffixImpl(const std::string &str1,
+ const char *str2,
+ size_t N)
+{
+ size_t len = str1.size();
+ return len >= N && strcmp(str1.c_str() + len - N, str2) == 0;
+}
+
+inline bool cmHasLiteralSuffixImpl(const char* str1,
+ const char* str2,
+ size_t N)
+{
+ size_t len = strlen(str1);
+ return len >= N && strcmp(str1 + len - N, str2) == 0;
+}
+
+template<typename T, size_t N>
+const T* cmArrayBegin(const T (&a)[N]) { return a; }
+template<typename T, size_t N>
+const T* cmArrayEnd(const T (&a)[N]) { return a + N; }
+template<typename T, size_t N>
+size_t cmArraySize(const T (&)[N]) { return N; }
+
+template<typename T, size_t N>
+bool cmHasLiteralPrefix(const T& str1, const char (&str2)[N])
+{
+ return cmHasLiteralPrefixImpl(str1, str2, N - 1);
+}
+
+template<typename T, size_t N>
+bool cmHasLiteralSuffix(const T& str1, const char (&str2)[N])
+{
+ return cmHasLiteralSuffixImpl(str1, str2, N - 1);
+}
+
+struct cmStrCmp {
+ cmStrCmp(const char *test) : m_test(test) {}
+ cmStrCmp(const std::string &test) : m_test(test) {}
+
+ bool operator()(const std::string& input) const
+ {
+ return m_test == input;
+ }
+
+ bool operator()(const char * input) const
+ {
+ return strcmp(input, m_test.c_str()) == 0;
+ }
+
+private:
+ const std::string m_test;
+};
+
+template<typename FwdIt>
+FwdIt cmRotate(FwdIt first, FwdIt middle, FwdIt last)
+{
+ const typename std::iterator_traits<FwdIt>::difference_type dist =
+ std::distance(middle, last);
+ std::rotate(first, middle, last);
+ std::advance(first, dist);
+ return first;
+}
+
+namespace ContainerAlgorithms {
+
+template<typename T>
+struct cmIsPair
+{
+ enum { value = false };
+};
+
+template<typename K, typename V>
+struct cmIsPair<std::pair<K, V> >
+{
+ enum { value = true };
+};
+
+template<typename Range,
+ bool valueTypeIsPair = cmIsPair<typename Range::value_type>::value>
+struct DefaultDeleter
+{
+ void operator()(typename Range::value_type value) const {
+ delete value;
+ }
+};
+
+template<typename Range>
+struct DefaultDeleter<Range, /* valueTypeIsPair = */ true>
+{
+ void operator()(typename Range::value_type value) const {
+ delete value.second;
+ }
+};
+
+template<typename FwdIt>
+FwdIt RemoveN(FwdIt i1, FwdIt i2, size_t n)
+{
+ FwdIt m = i1;
+ std::advance(m, n);
+ return cmRotate(i1, m, i2);
+}
+
+template<typename Range>
+struct BinarySearcher
+{
+ typedef typename Range::value_type argument_type;
+ BinarySearcher(Range const& r)
+ : m_range(r)
+ {
+ }
+
+ bool operator()(argument_type const& item) const
+ {
+ return std::binary_search(m_range.begin(), m_range.end(), item);
+ }
+private:
+ Range const& m_range;
+};
+
+}
+
+template<typename const_iterator_>
+struct cmRange
+{
+ typedef const_iterator_ const_iterator;
+ typedef typename std::iterator_traits<const_iterator>::value_type value_type;
+ typedef typename std::iterator_traits<const_iterator>::difference_type
+ difference_type;
+ cmRange(const_iterator begin_, const_iterator end_)
+ : Begin(begin_), End(end_) {}
+ const_iterator begin() const { return Begin; }
+ const_iterator end() const { return End; }
+ bool empty() const { return std::distance(Begin, End) == 0; }
+ difference_type size() const { return std::distance(Begin, End); }
+ cmRange& advance(KWIML_INT_intptr_t amount)
+ {
+ std::advance(Begin, amount);
+ return *this;
+ }
+
+ cmRange& retreat(KWIML_INT_intptr_t amount)
+ {
+ std::advance(End, -amount);
+ return *this;
+ }
+private:
+ const_iterator Begin;
+ const_iterator End;
+};
+
+typedef cmRange<std::vector<std::string>::const_iterator> cmStringRange;
+
+class cmListFileBacktrace;
+typedef
+cmRange<std::vector<cmListFileBacktrace>::const_iterator> cmBacktraceRange;
+
+template<typename Iter1, typename Iter2>
+cmRange<Iter1> cmMakeRange(Iter1 begin, Iter2 end)
+{
+ return cmRange<Iter1>(begin, end);
+}
+
+template<typename Range>
+cmRange<typename Range::const_iterator>
+cmMakeRange(Range const& range)
+{
+ return cmRange<typename Range::const_iterator>(
+ range.begin(), range.end());
+}
+
+template<typename Range>
+void cmDeleteAll(Range const& r)
+{
+ std::for_each(r.begin(), r.end(),
+ ContainerAlgorithms::DefaultDeleter<Range>());
+}
+
+template<typename Range>
+std::string cmJoin(Range const& r, const char* delimiter)
+{
+ if (r.empty())
+ {
+ return std::string();
+ }
+ std::ostringstream os;
+ typedef typename Range::value_type ValueType;
+ typedef typename Range::const_iterator InputIt;
+ const InputIt first = r.begin();
+ InputIt last = r.end();
+ --last;
+ std::copy(first, last,
+ std::ostream_iterator<ValueType>(os, delimiter));
+
+ os << *last;
+
+ return os.str();
+}
+
+template<typename Range>
+std::string cmJoin(Range const& r, std::string delimiter)
+{
+ return cmJoin(r, delimiter.c_str());
+}
+
+template<typename Range>
+typename Range::const_iterator cmRemoveN(Range& r, size_t n)
+{
+ return ContainerAlgorithms::RemoveN(r.begin(), r.end(), n);
+}
+
+template<typename Range, typename InputRange>
+typename Range::const_iterator cmRemoveIndices(Range& r, InputRange const& rem)
+{
+ typename InputRange::const_iterator remIt = rem.begin();
+ typename InputRange::const_iterator remEnd = rem.end();
+ const typename Range::iterator rangeEnd = r.end();
+ if (remIt == remEnd)
+ {
+ return rangeEnd;
+ }
+
+ typename Range::iterator writer = r.begin();
+ std::advance(writer, *remIt);
+ typename Range::iterator pivot = writer;
+ typename InputRange::value_type prevRem = *remIt;
+ ++remIt;
+ size_t count = 1;
+ for ( ; writer != rangeEnd && remIt != remEnd; ++count, ++remIt)
+ {
+ std::advance(pivot, *remIt - prevRem);
+ prevRem = *remIt;
+ writer = ContainerAlgorithms::RemoveN(writer, pivot, count);
+ }
+ return ContainerAlgorithms::RemoveN(writer, rangeEnd, count);
+}
+
+template<typename Range, typename MatchRange>
+typename Range::const_iterator cmRemoveMatching(Range &r, MatchRange const& m)
+{
+ return std::remove_if(r.begin(), r.end(),
+ ContainerAlgorithms::BinarySearcher<MatchRange>(m));
+}
+
+namespace ContainerAlgorithms {
+
+template<typename Range, typename T = typename Range::value_type>
+struct RemoveDuplicatesAPI
+{
+ typedef typename Range::const_iterator const_iterator;
+ typedef typename Range::const_iterator value_type;
+
+ static bool lessThan(value_type a, value_type b) { return *a < *b; }
+ static value_type uniqueValue(const_iterator a) { return a; }
+ template<typename It>
+ static bool valueCompare(It it, const_iterator it2) { return **it != *it2; }
+};
+
+template<typename Range, typename T>
+struct RemoveDuplicatesAPI<Range, T*>
+{
+ typedef typename Range::const_iterator const_iterator;
+ typedef T* value_type;
+
+ static bool lessThan(value_type a, value_type b) { return a < b; }
+ static value_type uniqueValue(const_iterator a) { return *a; }
+ template<typename It>
+ static bool valueCompare(It it, const_iterator it2) { return *it != *it2; }
+};
+
+}
+
+template<typename Range>
+typename Range::const_iterator cmRemoveDuplicates(Range& r)
+{
+ typedef typename ContainerAlgorithms::RemoveDuplicatesAPI<Range> API;
+ typedef typename API::value_type T;
+ std::vector<T> unique;
+ unique.reserve(r.size());
+ std::vector<size_t> indices;
+ size_t count = 0;
+ const typename Range::const_iterator end = r.end();
+ for(typename Range::const_iterator it = r.begin();
+ it != end; ++it, ++count)
+ {
+ const typename std::vector<T>::iterator low =
+ std::lower_bound(unique.begin(), unique.end(),
+ API::uniqueValue(it), API::lessThan);
+ if (low == unique.end() || API::valueCompare(low, it))
+ {
+ unique.insert(low, API::uniqueValue(it));
+ }
+ else
+ {
+ indices.push_back(count);
+ }
+ }
+ if (indices.empty())
+ {
+ return end;
+ }
+ return cmRemoveIndices(r, indices);
+}
+
+template<typename Range>
+std::string cmWrap(std::string prefix, Range const& r, std::string suffix,
+ std::string sep)
+{
+ if (r.empty())
+ {
+ return std::string();
+ }
+ return prefix + cmJoin(r, (suffix + sep + prefix).c_str()) + suffix;
+}
+
+template<typename Range>
+std::string cmWrap(char prefix, Range const& r, char suffix, std::string sep)
+{
+ return cmWrap(std::string(1, prefix), r, std::string(1, suffix), sep);
+}
+
+template<typename Range, typename T>
+typename Range::const_iterator cmFindNot(Range const& r, T const& t)
+{
+ return std::find_if(r.begin(), r.end(),
+ std::bind1st(std::not_equal_to<T>(), t));
+}
+
+template<typename Range>
+cmRange<typename Range::const_reverse_iterator>
+cmReverseRange(Range const& range)
+{
+ return cmRange<typename Range::const_reverse_iterator>(
+ range.rbegin(), range.rend());
+}
+
+template <class Iter>
+std::reverse_iterator<Iter> cmMakeReverseIterator(Iter it)
+{
+ return std::reverse_iterator<Iter>(it);
+}
+
+#endif
diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx
index b410e440e..e62a2ed11 100644
--- a/Source/cmArchiveWrite.cxx
+++ b/Source/cmArchiveWrite.cxx
@@ -12,9 +12,44 @@
#include "cmArchiveWrite.h"
#include "cmSystemTools.h"
-#include <cmsys/ios/iostream>
+#include "cmLocale.h"
#include <cmsys/Directory.hxx>
+#include <cmsys/FStream.hxx>
#include <cm_libarchive.h>
+#include "cm_get_date.h"
+
+#ifndef __LA_SSIZE_T
+# define __LA_SSIZE_T la_ssize_t
+#endif
+
+//----------------------------------------------------------------------------
+static std::string cm_archive_error_string(struct archive* a)
+{
+ const char* e = archive_error_string(a);
+ return e? e : "unknown error";
+}
+
+//----------------------------------------------------------------------------
+static void cm_archive_entry_copy_pathname(struct archive_entry* e,
+ const std::string& dest)
+{
+#if cmsys_STL_HAS_WSTRING
+ archive_entry_copy_pathname_w(e, cmsys::Encoding::ToWide(dest).c_str());
+#else
+ archive_entry_copy_pathname(e, dest.c_str());
+#endif
+}
+
+//----------------------------------------------------------------------------
+static void cm_archive_entry_copy_sourcepath(struct archive_entry* e,
+ const std::string& file)
+{
+#if cmsys_STL_HAS_WSTRING
+ archive_entry_copy_sourcepath_w(e, cmsys::Encoding::ToWide(file).c_str());
+#else
+ archive_entry_copy_sourcepath(e, file.c_str());
+#endif
+}
//----------------------------------------------------------------------------
class cmArchiveWrite::Entry
@@ -35,7 +70,7 @@ struct cmArchiveWrite::Callback
{
cmArchiveWrite* self = static_cast<cmArchiveWrite*>(cd);
if(self->Stream.write(static_cast<const char*>(b),
- static_cast<cmsys_ios::streamsize>(n)))
+ static_cast<std::streamsize>(n)))
{
return static_cast<__LA_SSIZE_T>(n);
}
@@ -47,59 +82,61 @@ struct cmArchiveWrite::Callback
};
//----------------------------------------------------------------------------
-cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c, Type t):
- Stream(os),
- Archive(archive_write_new()),
- Disk(archive_read_disk_new()),
- Verbose(false)
+cmArchiveWrite::cmArchiveWrite(
+ std::ostream& os, Compress c, std::string const& format):
+ Stream(os),
+ Archive(archive_write_new()),
+ Disk(archive_read_disk_new()),
+ Verbose(false),
+ Format(format)
{
switch (c)
{
case CompressNone:
- if(archive_write_set_compression_none(this->Archive) != ARCHIVE_OK)
+ if(archive_write_add_filter_none(this->Archive) != ARCHIVE_OK)
{
- this->Error = "archive_write_set_compression_none: ";
- this->Error += archive_error_string(this->Archive);
+ this->Error = "archive_write_add_filter_none: ";
+ this->Error += cm_archive_error_string(this->Archive);
return;
}
break;
case CompressCompress:
- if(archive_write_set_compression_compress(this->Archive) != ARCHIVE_OK)
+ if(archive_write_add_filter_compress(this->Archive) != ARCHIVE_OK)
{
- this->Error = "archive_write_set_compression_compress: ";
- this->Error += archive_error_string(this->Archive);
+ this->Error = "archive_write_add_filter_compress: ";
+ this->Error += cm_archive_error_string(this->Archive);
return;
}
break;
case CompressGZip:
- if(archive_write_set_compression_gzip(this->Archive) != ARCHIVE_OK)
+ if(archive_write_add_filter_gzip(this->Archive) != ARCHIVE_OK)
{
- this->Error = "archive_write_set_compression_gzip: ";
- this->Error += archive_error_string(this->Archive);
+ this->Error = "archive_write_add_filter_gzip: ";
+ this->Error += cm_archive_error_string(this->Archive);
return;
}
break;
case CompressBZip2:
- if(archive_write_set_compression_bzip2(this->Archive) != ARCHIVE_OK)
+ if(archive_write_add_filter_bzip2(this->Archive) != ARCHIVE_OK)
{
- this->Error = "archive_write_set_compression_bzip2: ";
- this->Error += archive_error_string(this->Archive);
+ this->Error = "archive_write_add_filter_bzip2: ";
+ this->Error += cm_archive_error_string(this->Archive);
return;
}
break;
case CompressLZMA:
- if(archive_write_set_compression_lzma(this->Archive) != ARCHIVE_OK)
+ if(archive_write_add_filter_lzma(this->Archive) != ARCHIVE_OK)
{
- this->Error = "archive_write_set_compression_lzma: ";
- this->Error += archive_error_string(this->Archive);
+ this->Error = "archive_write_add_filter_lzma: ";
+ this->Error += cm_archive_error_string(this->Archive);
return;
}
break;
case CompressXZ:
- if(archive_write_set_compression_xz(this->Archive) != ARCHIVE_OK)
+ if(archive_write_add_filter_xz(this->Archive) != ARCHIVE_OK)
{
- this->Error = "archive_write_set_compression_xz: ";
- this->Error += archive_error_string(this->Archive);
+ this->Error = "archive_write_add_filter_xz: ";
+ this->Error += cm_archive_error_string(this->Archive);
return;
}
break;
@@ -108,35 +145,24 @@ cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c, Type t):
if (archive_read_disk_set_standard_lookup(this->Disk) != ARCHIVE_OK)
{
this->Error = "archive_read_disk_set_standard_lookup: ";
- this->Error += archive_error_string(this->Archive);
- return;;
+ this->Error += cm_archive_error_string(this->Archive);
+ return;
}
#endif
- switch (t)
+
+ if(archive_write_set_format_by_name(this->Archive, format.c_str())
+ != ARCHIVE_OK)
{
- case TypeZIP:
- if(archive_write_set_format_zip(this->Archive) != ARCHIVE_OK)
- {
- this->Error = "archive_write_set_format_zip: ";
- this->Error += archive_error_string(this->Archive);
- return;
- }
- break;
- case TypeTAR:
- if(archive_write_set_format_pax_restricted(this->Archive) != ARCHIVE_OK)
- {
- this->Error = "archive_write_set_format_pax_restricted: ";
- this->Error += archive_error_string(this->Archive);
- return;
- }
- break;
+ this->Error = "archive_write_set_format_by_name: ";
+ this->Error += cm_archive_error_string(this->Archive);
+ return;
}
// do not pad the last block!!
if (archive_write_set_bytes_in_last_block(this->Archive, 1))
{
this->Error = "archive_write_set_bytes_in_last_block: ";
- this->Error += archive_error_string(this->Archive);
+ this->Error += cm_archive_error_string(this->Archive);
return;
}
@@ -146,7 +172,7 @@ cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c, Type t):
0) != ARCHIVE_OK)
{
this->Error = "archive_write_open: ";
- this->Error += archive_error_string(this->Archive);
+ this->Error += cm_archive_error_string(this->Archive);
return;
}
}
@@ -154,12 +180,15 @@ cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c, Type t):
//----------------------------------------------------------------------------
cmArchiveWrite::~cmArchiveWrite()
{
- archive_read_finish(this->Disk);
- archive_write_finish(this->Archive);
+ archive_read_free(this->Disk);
+ archive_write_free(this->Archive);
}
//----------------------------------------------------------------------------
-bool cmArchiveWrite::Add(std::string path, size_t skip, const char* prefix)
+bool cmArchiveWrite::Add(std::string path,
+ size_t skip,
+ const char* prefix,
+ bool recursive)
{
if(this->Okay())
{
@@ -167,20 +196,21 @@ bool cmArchiveWrite::Add(std::string path, size_t skip, const char* prefix)
{
path.erase(path.size()-1);
}
- this->AddPath(path.c_str(), skip, prefix);
+ this->AddPath(path.c_str(), skip, prefix, recursive);
}
return this->Okay();
}
//----------------------------------------------------------------------------
bool cmArchiveWrite::AddPath(const char* path,
- size_t skip, const char* prefix)
+ size_t skip, const char* prefix,
+ bool recursive)
{
if(!this->AddFile(path, skip, prefix))
{
return false;
}
- if(!cmSystemTools::FileIsDirectory(path) ||
+ if((!cmSystemTools::FileIsDirectory(path) || !recursive) ||
cmSystemTools::FileIsSymlink(path))
{
return true;
@@ -221,6 +251,9 @@ bool cmArchiveWrite::AddFile(const char* file,
}
const char* out = file + skip;
+ cmLocaleRAII localeRAII;
+ static_cast<void>(localeRAII);
+
// Meta-data.
std::string dest = prefix? prefix : "";
dest += out;
@@ -229,22 +262,73 @@ bool cmArchiveWrite::AddFile(const char* file,
std::cout << dest << "\n";
}
Entry e;
- archive_entry_copy_sourcepath(e, file);
- archive_entry_set_pathname(e, dest.c_str());
+ cm_archive_entry_copy_sourcepath(e, file);
+ cm_archive_entry_copy_pathname(e, dest);
if(archive_read_disk_entry_from_file(this->Disk, e, -1, 0) != ARCHIVE_OK)
{
- this->Error = "archive_read_disk_entry_from_file: ";
- this->Error += archive_error_string(this->Disk);
+ this->Error = "archive_read_disk_entry_from_file '";
+ this->Error += file;
+ this->Error += "': ";
+ this->Error += cm_archive_error_string(this->Disk);
return false;
}
+ if (!this->MTime.empty())
+ {
+ time_t now;
+ time(&now);
+ time_t t = cm_get_date(now, this->MTime.c_str());
+ if (t == -1)
+ {
+ this->Error = "unable to parse mtime '";
+ this->Error += this->MTime;
+ this->Error += "'";
+ return false;
+ }
+ archive_entry_set_mtime(e, t, 0);
+ }
+
+ // manages the uid/guid of the entry (if any)
+ if (this->Uid.IsSet() && this->Gid.IsSet())
+ {
+ archive_entry_set_uid(e, this->Uid.Get());
+ archive_entry_set_gid(e, this->Gid.Get());
+ }
+
+ if (this->Uname.size() && this->Gname.size())
+ {
+ archive_entry_set_uname(e, this->Uname.c_str());
+ archive_entry_set_gname(e, this->Gname.c_str());
+ }
+
+
+ // manages the permissions
+ if (this->Permissions.IsSet())
+ {
+ archive_entry_set_perm(e, this->Permissions.Get());
+ }
+
+ if (this->PermissionsMask.IsSet())
+ {
+ mode_t perm = archive_entry_perm(e);
+ archive_entry_set_perm(e, perm & this->PermissionsMask.Get());
+ }
+
// Clear acl and xattr fields not useful for distribution.
archive_entry_acl_clear(e);
archive_entry_xattr_clear(e);
archive_entry_set_fflags(e, 0, 0);
+
+ if (this->Format == "pax" || this->Format == "paxr")
+ {
+ // Sparse files are a GNU tar extension.
+ // Do not use them in standard tar files.
+ archive_entry_sparse_clear(e);
+ }
+
if(archive_write_header(this->Archive, e) != ARCHIVE_OK)
{
this->Error = "archive_write_header: ";
- this->Error += archive_error_string(this->Archive);
+ this->Error += cm_archive_error_string(this->Archive);
return false;
}
@@ -263,7 +347,7 @@ bool cmArchiveWrite::AddFile(const char* file,
//----------------------------------------------------------------------------
bool cmArchiveWrite::AddData(const char* file, size_t size)
{
- std::ifstream fin(file, std::ios::in | cmsys_ios_binary);
+ cmsys::ifstream fin(file, std::ios::in | std::ios::binary);
if(!fin)
{
this->Error = "Error opening \"";
@@ -277,7 +361,7 @@ bool cmArchiveWrite::AddData(const char* file, size_t size)
size_t nleft = size;
while(nleft > 0)
{
- typedef cmsys_ios::streamsize ssize_type;
+ typedef std::streamsize ssize_type;
size_t const nnext = nleft > sizeof(buffer)? sizeof(buffer) : nleft;
ssize_type const nnext_s = static_cast<ssize_type>(nnext);
fin.read(buffer, nnext_s);
@@ -291,7 +375,7 @@ bool cmArchiveWrite::AddData(const char* file, size_t size)
if(archive_write_data(this->Archive, buffer, nnext) != nnext_s)
{
this->Error = "archive_write_data: ";
- this->Error += archive_error_string(this->Archive);
+ this->Error += cm_archive_error_string(this->Archive);
return false;
}
nleft -= nnext;
diff --git a/Source/cmArchiveWrite.h b/Source/cmArchiveWrite.h
index 3e3b2f0ca..8dbbb8372 100644
--- a/Source/cmArchiveWrite.h
+++ b/Source/cmArchiveWrite.h
@@ -18,6 +18,22 @@
# error "cmArchiveWrite not allowed during bootstrap build!"
#endif
+template<typename T>
+class cmArchiveWriteOptional
+{
+public:
+ cmArchiveWriteOptional() {this->Clear();}
+ explicit cmArchiveWriteOptional(T val) {this->Set(val);}
+
+ void Set(T val) {this->IsValueSet = true; this->Value=val;}
+ void Clear() {this->IsValueSet = false;}
+ bool IsSet() const {return this->IsValueSet;}
+ T Get() const {return Value;}
+private:
+ T Value;
+ bool IsValueSet;
+};
+
/** \class cmArchiveWrite
* \brief Wrapper around libarchive for writing.
*
@@ -38,15 +54,10 @@ public:
CompressXZ
};
- /** Archive Type */
- enum Type
- {
- TypeTAR,
- TypeZIP
- };
-
/** Construct with output stream to which to write archive. */
- cmArchiveWrite(std::ostream& os, Compress c = CompressNone, Type = TypeTAR);
+ cmArchiveWrite(std::ostream& os, Compress c = CompressNone,
+ std::string const& format = "paxr");
+
~cmArchiveWrite();
/**
@@ -57,7 +68,10 @@ public:
* skip. The remaining part of the input path is appended to the
* "prefix" value to construct the final name in the archive.
*/
- bool Add(std::string path, size_t skip = 0, const char* prefix = 0);
+ bool Add(std::string path,
+ size_t skip = 0,
+ const char* prefix = 0,
+ bool recursive = true);
/** Returns true if there has been no error. */
operator safe_bool() const
@@ -73,9 +87,66 @@ public:
// std::cout.
void SetVerbose(bool v) { this->Verbose = v; }
+ void SetMTime(std::string const& t) { this->MTime = t; }
+
+ //! Sets the permissions of the added files/folders
+ void SetPermissions(mode_t permissions_)
+ {
+ this->Permissions.Set(permissions_);
+ }
+
+ //! Clears permissions - default is used instead
+ void ClearPermissions() { this->Permissions.Clear(); }
+
+ //! Sets the permissions mask of files/folders
+ //!
+ //! The permissions will be copied from the existing file
+ //! or folder. The mask will then be applied to unset
+ //! some of them
+ void SetPermissionsMask(mode_t permissionsMask_)
+ {
+ this->PermissionsMask.Set(permissionsMask_);
+ }
+
+ //! Clears permissions mask - default is used instead
+ void ClearPermissionsMask()
+ {
+ this->PermissionsMask.Clear();
+ }
+
+ //! Sets UID and GID to be used in the tar file
+ void SetUIDAndGID(int uid_, int gid_)
+ {
+ this->Uid.Set(uid_);
+ this->Gid.Set(gid_);
+ }
+
+ //! Clears UID and GID to be used in the tar file - default is used instead
+ void ClearUIDAndGID()
+ {
+ this->Uid.Clear();
+ this->Gid.Clear();
+ }
+
+ //! Sets UNAME and GNAME to be used in the tar file
+ void SetUNAMEAndGNAME(const std::string& uname_, const std::string& gname_)
+ {
+ this->Uname = uname_;
+ this->Gname = gname_;
+ }
+
+ //! Clears UNAME and GNAME to be used in the tar file
+ //! default is used instead
+ void ClearUNAMEAndGNAME()
+ {
+ this->Uname = "";
+ this->Gname = "";
+ }
+
private:
bool Okay() const { return this->Error.empty(); }
- bool AddPath(const char* path, size_t skip, const char* prefix);
+ bool AddPath(const char* path, size_t skip, const char* prefix,
+ bool recursive = true);
bool AddFile(const char* file, size_t skip, const char* prefix);
bool AddData(const char* file, size_t size);
@@ -88,7 +159,25 @@ private:
struct archive* Archive;
struct archive* Disk;
bool Verbose;
+ std::string Format;
std::string Error;
+ std::string MTime;
+
+ //! UID of the user in the tar file
+ cmArchiveWriteOptional<int> Uid;
+
+ //! GUID of the user in the tar file
+ cmArchiveWriteOptional<int> Gid;
+
+ //! UNAME/GNAME of the user (does not override UID/GID)
+ //!@{
+ std::string Uname;
+ std::string Gname;
+ //!@}
+
+ //! Permissions on files/folders
+ cmArchiveWriteOptional<mode_t> Permissions;
+ cmArchiveWriteOptional<mode_t> PermissionsMask;
};
#endif
diff --git a/Source/cmAuxSourceDirectoryCommand.cxx b/Source/cmAuxSourceDirectoryCommand.cxx
index 01f64b730..92ac07dfd 100644
--- a/Source/cmAuxSourceDirectoryCommand.cxx
+++ b/Source/cmAuxSourceDirectoryCommand.cxx
@@ -26,11 +26,10 @@ bool cmAuxSourceDirectoryCommand::InitialPass
std::string sourceListValue;
std::string templateDirectory = args[0];
- this->Makefile->AddExtraDirectory(templateDirectory.c_str());
std::string tdir;
if(!cmSystemTools::FileIsFullPath(templateDirectory.c_str()))
{
- tdir = this->Makefile->GetCurrentDirectory();
+ tdir = this->Makefile->GetCurrentSourceDirectory();
tdir += "/";
tdir += templateDirectory;
}
@@ -40,7 +39,7 @@ bool cmAuxSourceDirectoryCommand::InitialPass
}
// was the list already populated
- const char *def = this->Makefile->GetDefinition(args[1].c_str());
+ const char *def = this->Makefile->GetDefinition(args[1]);
if (def)
{
sourceListValue = def;
@@ -61,10 +60,10 @@ bool cmAuxSourceDirectoryCommand::InitialPass
std::string ext = file.substr(dotpos+1);
std::string base = file.substr(0, dotpos);
// Process only source files
- if( base.size() != 0
- && std::find( this->Makefile->GetSourceExtensions().begin(),
- this->Makefile->GetSourceExtensions().end(), ext )
- != this->Makefile->GetSourceExtensions().end() )
+ std::vector<std::string> srcExts =
+ this->Makefile->GetCMakeInstance()->GetSourceExtensions();
+ if(!base.empty() &&
+ std::find(srcExts.begin(), srcExts.end(), ext) != srcExts.end())
{
std::string fullname = templateDirectory;
fullname += "/";
@@ -72,7 +71,7 @@ bool cmAuxSourceDirectoryCommand::InitialPass
// add the file as a class file so
// depends can be done
cmSourceFile* sf =
- this->Makefile->GetOrCreateSource(fullname.c_str());
+ this->Makefile->GetOrCreateSource(fullname);
sf->SetProperty("ABSTRACT","0");
if(!sourceListValue.empty())
{
@@ -83,7 +82,7 @@ bool cmAuxSourceDirectoryCommand::InitialPass
}
}
}
- this->Makefile->AddDefinition(args[1].c_str(), sourceListValue.c_str());
+ this->Makefile->AddDefinition(args[1], sourceListValue.c_str());
return true;
}
diff --git a/Source/cmAuxSourceDirectoryCommand.h b/Source/cmAuxSourceDirectoryCommand.h
index 8a70f19cb..6615273bb 100644
--- a/Source/cmAuxSourceDirectoryCommand.h
+++ b/Source/cmAuxSourceDirectoryCommand.h
@@ -44,39 +44,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "aux_source_directory";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Find all source files in a directory.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " aux_source_directory(<dir> <variable>)\n"
- "Collects the names of all the source files in the specified "
- "directory and stores the list in the <variable> provided. This "
- "command is intended to be used by projects that use explicit "
- "template instantiation. Template instantiation files can be "
- "stored in a \"Templates\" subdirectory and collected automatically "
- "using this command to avoid manually listing all instantiations.\n"
- "It is tempting to use this command to avoid writing the list of "
- "source files for a library or executable target. While this seems "
- "to work, there is no way for CMake to generate a build system that "
- "knows when a new source file has been added. Normally the "
- "generated build system knows when it needs to rerun CMake because "
- "the CMakeLists.txt file is modified to add a new source. When the "
- "source is just added to the directory without modifying this file, "
- "one would have to manually rerun CMake to generate a build system "
- "incorporating the new file.";
- }
+ virtual std::string GetName() const { return "aux_source_directory";}
cmTypeMacro(cmAuxSourceDirectoryCommand, cmCommand);
};
diff --git a/Source/cmBootstrapCommands1.cxx b/Source/cmBootstrapCommands1.cxx
index 9093579dc..0782b3ba7 100644
--- a/Source/cmBootstrapCommands1.cxx
+++ b/Source/cmBootstrapCommands1.cxx
@@ -28,6 +28,7 @@
#include "cmCMakePolicyCommand.cxx"
#include "cmCommandArgumentsHelper.cxx"
#include "cmConfigureFileCommand.cxx"
+#include "cmContinueCommand.cxx"
#include "cmCoreTryCompile.cxx"
#include "cmCreateTestSourceList.cxx"
#include "cmDefinePropertyCommand.cxx"
@@ -41,7 +42,6 @@
#include "cmEndWhileCommand.cxx"
#include "cmExecProgramCommand.cxx"
#include "cmExecuteProcessCommand.cxx"
-#include "cmExternalMakefileProjectGenerator.cxx"
#include "cmFindBase.cxx"
#include "cmFindCommon.cxx"
#include "cmFileCommand.cxx"
@@ -52,8 +52,11 @@
#include "cmFindProgramCommand.cxx"
#include "cmForEachCommand.cxx"
#include "cmFunctionCommand.cxx"
+#include "cmPathLabel.cxx"
+#include "cmSearchPath.cxx"
+#include "cmParseArgumentsCommand.cxx"
-void GetBootstrapCommands1(std::list<cmCommand*>& commands)
+void GetBootstrapCommands1(std::vector<cmCommand*>& commands)
{
commands.push_back(new cmAddCustomCommandCommand);
commands.push_back(new cmAddCustomTargetCommand);
@@ -68,6 +71,7 @@ void GetBootstrapCommands1(std::list<cmCommand*>& commands)
commands.push_back(new cmCMakeMinimumRequired);
commands.push_back(new cmCMakePolicyCommand);
commands.push_back(new cmConfigureFileCommand);
+ commands.push_back(new cmContinueCommand);
commands.push_back(new cmCreateTestSourceList);
commands.push_back(new cmDefinePropertyCommand);
commands.push_back(new cmElseCommand);
@@ -88,4 +92,5 @@ void GetBootstrapCommands1(std::list<cmCommand*>& commands)
commands.push_back(new cmFindProgramCommand);
commands.push_back(new cmForEachCommand);
commands.push_back(new cmFunctionCommand);
+ commands.push_back(new cmParseArgumentsCommand);
}
diff --git a/Source/cmBootstrapCommands2.cxx b/Source/cmBootstrapCommands2.cxx
index be72526ba..e522d8c79 100644
--- a/Source/cmBootstrapCommands2.cxx
+++ b/Source/cmBootstrapCommands2.cxx
@@ -14,7 +14,8 @@
// This is sort of a boot strapping approach since you would
// like to have CMake to build CMake.
#include "cmCommands.h"
-#include "cmGeneratorExpressionEvaluationFile.cxx"
+#include "cmConditionEvaluator.cxx"
+#include "cmExpandedCommandArgument.cxx"
#include "cmGetCMakePropertyCommand.cxx"
#include "cmGetDirectoryPropertyCommand.cxx"
#include "cmGetFilenameComponentCommand.cxx"
@@ -58,7 +59,7 @@
#include "cmUnsetCommand.cxx"
#include "cmWhileCommand.cxx"
-void GetBootstrapCommands2(std::list<cmCommand*>& commands)
+void GetBootstrapCommands2(std::vector<cmCommand*>& commands)
{
commands.push_back(new cmGetCMakePropertyCommand);
commands.push_back(new cmGetDirectoryPropertyCommand);
diff --git a/Source/cmBreakCommand.cxx b/Source/cmBreakCommand.cxx
index b70e40088..fc0c3f58f 100644
--- a/Source/cmBreakCommand.cxx
+++ b/Source/cmBreakCommand.cxx
@@ -12,10 +12,74 @@
#include "cmBreakCommand.h"
// cmBreakCommand
-bool cmBreakCommand::InitialPass(std::vector<std::string> const&,
+bool cmBreakCommand::InitialPass(std::vector<std::string> const &args,
cmExecutionStatus &status)
{
+ if(!this->Makefile->IsLoopBlock())
+ {
+ bool issueMessage = true;
+ std::ostringstream e;
+ cmake::MessageType messageType = cmake::AUTHOR_WARNING;
+ switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0055))
+ {
+ case cmPolicies::WARN:
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0055) << "\n";
+ break;
+ case cmPolicies::OLD:
+ issueMessage = false;
+ break;
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::NEW:
+ messageType = cmake::FATAL_ERROR;
+ break;
+ }
+
+ if(issueMessage)
+ {
+ e << "A BREAK command was found outside of a proper "
+ "FOREACH or WHILE loop scope.";
+ this->Makefile->IssueMessage(messageType, e.str());
+ if(messageType == cmake::FATAL_ERROR)
+ {
+ return false;
+ }
+ }
+ }
+
status.SetBreakInvoked(true);
+
+ if(!args.empty())
+ {
+ bool issueMessage = true;
+ std::ostringstream e;
+ cmake::MessageType messageType = cmake::AUTHOR_WARNING;
+ switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0055))
+ {
+ case cmPolicies::WARN:
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0055) << "\n";
+ break;
+ case cmPolicies::OLD:
+ issueMessage = false;
+ break;
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::NEW:
+ messageType = cmake::FATAL_ERROR;
+ break;
+ }
+
+ if(issueMessage)
+ {
+ e << "The BREAK command does not accept any arguments.";
+ this->Makefile->IssueMessage(messageType, e.str());
+ if(messageType == cmake::FATAL_ERROR)
+ {
+ return false;
+ }
+ }
+ }
+
return true;
}
diff --git a/Source/cmBreakCommand.h b/Source/cmBreakCommand.h
index 17f57cfa1..1fcae505a 100644
--- a/Source/cmBreakCommand.h
+++ b/Source/cmBreakCommand.h
@@ -45,25 +45,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const {return "break";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Break from an enclosing foreach or while loop.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " break()\n"
- "Breaks from an enclosing foreach loop or while loop";
- }
+ virtual std::string GetName() const {return "break";}
cmTypeMacro(cmBreakCommand, cmCommand);
};
diff --git a/Source/cmBuildCommand.cxx b/Source/cmBuildCommand.cxx
index b6e2569a5..64d4fcaad 100644
--- a/Source/cmBuildCommand.cxx
+++ b/Source/cmBuildCommand.cxx
@@ -11,7 +11,6 @@
============================================================================*/
#include "cmBuildCommand.h"
-#include "cmLocalGenerator.h"
#include "cmGlobalGenerator.h"
//----------------------------------------------------------------------
@@ -44,7 +43,7 @@ bool cmBuildCommand
// Parse remaining arguments.
const char* configuration = 0;
const char* project_name = 0;
- const char* target = 0;
+ std::string target;
enum Doing { DoingNone, DoingConfiguration, DoingProjectName, DoingTarget };
Doing doing = DoingNone;
for(unsigned int i=1; i < args.size(); ++i)
@@ -74,29 +73,18 @@ bool cmBuildCommand
else if(doing == DoingTarget)
{
doing = DoingNone;
- target = args[i].c_str();
+ target = args[i];
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "unknown argument \"" << args[i] << "\"";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
- const char* makeprogram
- = this->Makefile->GetDefinition("CMAKE_MAKE_PROGRAM");
- if(!makeprogram)
- {
- this->Makefile->IssueMessage(
- cmake::FATAL_ERROR,
- "build_command() requires CMAKE_MAKE_PROGRAM to be defined. "
- "Call project() or enable_language() first.");
- return true;
- }
-
- // If null/empty CONFIGURATION argument, GenerateBuildCommand uses 'Debug'
+ // If null/empty CONFIGURATION argument, cmake --build uses 'Debug'
// in the currently implemented multi-configuration global generators...
// so we put this code here to end up with the same default configuration
// as the original 2-arg build_command signature:
@@ -110,19 +98,15 @@ bool cmBuildCommand
configuration = "Release";
}
- // If null/empty PROJECT_NAME argument, use the Makefile's project name:
- //
- if(!project_name || !*project_name)
+ if(project_name && *project_name)
{
- project_name = this->Makefile->GetProjectName();
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING,
+ "Ignoring PROJECT_NAME option because it has no effect.");
}
- // If null/empty TARGET argument, GenerateBuildCommand omits any mention
- // of a target name on the build command line...
- //
- std::string makecommand = this->Makefile->GetLocalGenerator()
- ->GetGlobalGenerator()->GenerateBuildCommand
- (makeprogram, project_name, 0, 0, target, configuration, true, false);
+ std::string makecommand = this->Makefile->GetGlobalGenerator()
+ ->GenerateCMakeBuildCommand(target, configuration, "",
+ this->Makefile->IgnoreErrorsCMP0061());
this->Makefile->AddDefinition(variable, makecommand.c_str());
@@ -142,19 +126,17 @@ bool cmBuildCommand
const char* define = args[0].c_str();
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 )
+ if ( cfg && *cfg )
{
configType = cfg;
}
- std::string makecommand = this->Makefile->GetLocalGenerator()
- ->GetGlobalGenerator()->GenerateBuildCommand
- (makeprogram.c_str(), this->Makefile->GetProjectName(), 0, 0,
- 0, configType.c_str(), true, false);
+ std::string makecommand = this->Makefile->GetGlobalGenerator()
+ ->GenerateCMakeBuildCommand("", configType, "",
+ this->Makefile->IgnoreErrorsCMP0061());
if(cacheValue)
{
@@ -164,6 +146,6 @@ bool cmBuildCommand
makecommand.c_str(),
"Command used to build entire project "
"from the command line.",
- cmCacheManager::STRING);
+ cmState::STRING);
return true;
}
diff --git a/Source/cmBuildCommand.h b/Source/cmBuildCommand.h
index 1bab4536e..979abc005 100644
--- a/Source/cmBuildCommand.h
+++ b/Source/cmBuildCommand.h
@@ -50,48 +50,11 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const {return "build_command";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Get the command line to build this project.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " build_command(<variable>\n"
- " [CONFIGURATION <config>]\n"
- " [PROJECT_NAME <projname>]\n"
- " [TARGET <target>])\n"
- "Sets the given <variable> to a string containing the command line "
- "for building one configuration of a target in a project using the "
- "build tool appropriate for the current CMAKE_GENERATOR.\n"
- "If CONFIGURATION is omitted, CMake chooses a reasonable default "
- "value for multi-configuration generators. CONFIGURATION is "
- "ignored for single-configuration generators.\n"
- "If PROJECT_NAME is omitted, the resulting command line will build "
- "the top level PROJECT in the current build tree.\n"
- "If TARGET is omitted, the resulting command line will build "
- "everything, effectively using build target 'all' or 'ALL_BUILD'.\n"
- " build_command(<cachevariable> <makecommand>)\n"
- "This second signature is deprecated, but still available for "
- "backwards compatibility. Use the first signature instead.\n"
- "Sets the given <cachevariable> to a string containing the command "
- "to build this project from the root of the build tree using "
- "the build tool given by <makecommand>. <makecommand> should be "
- "the full path to msdev, devenv, nmake, make or one of the end "
- "user build tools."
- ;
- }
+ virtual std::string GetName() const {return "build_command";}
cmTypeMacro(cmBuildCommand, cmCommand);
+private:
+ bool IgnoreErrors() const;
};
#endif
diff --git a/Source/cmBuildNameCommand.cxx b/Source/cmBuildNameCommand.cxx
index f95a79eda..2733d7677 100644
--- a/Source/cmBuildNameCommand.cxx
+++ b/Source/cmBuildNameCommand.cxx
@@ -17,12 +17,15 @@
bool cmBuildNameCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
+ if(this->Disallowed(cmPolicies::CMP0036,
+ "The build_name command should not be called; see CMP0036."))
+ { return true; }
if(args.size() < 1 )
{
this->SetError("called with incorrect number of arguments");
return false;
}
- const char* cacheValue = this->Makefile->GetDefinition(args[0].c_str());
+ const char* cacheValue = this->Makefile->GetDefinition(args[0]);
if(cacheValue)
{
// do we need to correct the value?
@@ -33,10 +36,10 @@ bool cmBuildNameCommand
cmSystemTools::ReplaceString(cv,"/", "_");
cmSystemTools::ReplaceString(cv,"(", "_");
cmSystemTools::ReplaceString(cv,")", "_");
- this->Makefile->AddCacheDefinition(args[0].c_str(),
+ this->Makefile->AddCacheDefinition(args[0],
cv.c_str(),
"Name of build.",
- cmCacheManager::STRING);
+ cmState::STRING);
}
return true;
}
@@ -46,8 +49,8 @@ bool cmBuildNameCommand
if(this->Makefile->GetDefinition("UNIX"))
{
buildname = "";
- cmSystemTools::RunSingleCommand("uname -a", &buildname);
- if(buildname.length())
+ cmSystemTools::RunSingleCommand("uname -a", &buildname, &buildname);
+ if(!buildname.empty())
{
std::string RegExp = "([^ ]*) [^ ]* ([^ ]*) ";
cmsys::RegularExpression reg( RegExp.c_str() );
@@ -68,10 +71,10 @@ bool cmBuildNameCommand
cmSystemTools::ReplaceString(buildname,
")", "_");
- this->Makefile->AddCacheDefinition(args[0].c_str(),
+ this->Makefile->AddCacheDefinition(args[0],
buildname.c_str(),
"Name of build.",
- cmCacheManager::STRING);
+ cmState::STRING);
return true;
}
diff --git a/Source/cmBuildNameCommand.h b/Source/cmBuildNameCommand.h
index 26505a260..47455f851 100644
--- a/Source/cmBuildNameCommand.h
+++ b/Source/cmBuildNameCommand.h
@@ -14,67 +14,15 @@
#include "cmCommand.h"
-/** \class cmBuildNameCommand
- * \brief build_name command
- *
- * cmBuildNameCommand implements the build_name CMake command
- */
class cmBuildNameCommand : public cmCommand
{
public:
- /**
- * This is a virtual constructor for the command.
- */
- virtual cmCommand* Clone()
- {
- return new cmBuildNameCommand;
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
+ cmTypeMacro(cmBuildNameCommand, cmCommand);
+ virtual cmCommand* Clone() { return new cmBuildNameCommand; }
virtual bool InitialPass(std::vector<std::string> const& args,
cmExecutionStatus &status);
-
- /**
- * This determines if the command is invoked when in script mode.
- */
+ virtual std::string GetName() const {return "build_name";}
virtual bool IsScriptable() const { return true; }
-
- /**
- * The name of the command as specified in CMakeList.txt.
- */
- virtual const char* GetName() const {return "build_name";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return
- "Deprecated. Use ${CMAKE_SYSTEM} and ${CMAKE_CXX_COMPILER} instead.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " build_name(variable)\n"
- "Sets the specified variable to a string representing the platform "
- "and compiler settings. These values are now available through the "
- "CMAKE_SYSTEM and CMAKE_CXX_COMPILER variables.";
- }
-
- /** This command is kept for compatibility with older CMake versions. */
- virtual bool IsDiscouraged() const
- {
- return true;
- }
-
- cmTypeMacro(cmBuildNameCommand, cmCommand);
};
diff --git a/Source/cmCLocaleEnvironmentScope.cxx b/Source/cmCLocaleEnvironmentScope.cxx
new file mode 100644
index 000000000..579230274
--- /dev/null
+++ b/Source/cmCLocaleEnvironmentScope.cxx
@@ -0,0 +1,67 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmCLocaleEnvironmentScope.h"
+
+#include "cmSystemTools.h"
+
+#include <sstream>
+
+cmCLocaleEnvironmentScope::cmCLocaleEnvironmentScope()
+{
+ this->SetEnv("LANGUAGE", "");
+ this->SetEnv("LC_MESSAGES", "C");
+
+ std::string lcAll = this->GetEnv("LC_ALL");
+
+ if(!lcAll.empty())
+ {
+ this->SetEnv("LC_ALL", "");
+ this->SetEnv("LC_CTYPE", lcAll);
+ }
+}
+
+std::string cmCLocaleEnvironmentScope::GetEnv(std::string const& key)
+{
+ const char* value = cmSystemTools::GetEnv(key);
+ return value ? value : std::string();
+}
+
+void cmCLocaleEnvironmentScope::SetEnv(
+ std::string const& key, std::string const& value)
+{
+ std::string oldValue = this->GetEnv(key);
+
+ this->EnvironmentBackup.insert(std::make_pair(key, oldValue));
+
+ if(value.empty())
+ {
+ cmSystemTools::UnsetEnv(key.c_str());
+ }
+ else
+ {
+ std::stringstream tmp;
+ tmp << key << "=" << value;
+ cmSystemTools::PutEnv(tmp.str());
+ }
+}
+
+cmCLocaleEnvironmentScope::~cmCLocaleEnvironmentScope()
+{
+ for(backup_map_t::const_iterator i = this->EnvironmentBackup.begin();
+ i != this->EnvironmentBackup.end(); ++i)
+ {
+ std::stringstream tmp;
+ tmp << i->first << "=" << i->second;
+ cmSystemTools::PutEnv(tmp.str());
+ }
+}
diff --git a/Source/cmCLocaleEnvironmentScope.h b/Source/cmCLocaleEnvironmentScope.h
new file mode 100644
index 000000000..b011741a3
--- /dev/null
+++ b/Source/cmCLocaleEnvironmentScope.h
@@ -0,0 +1,32 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmCLocaleEnvironmentScope_h
+#define cmCLocaleEnvironmentScope_h
+
+#include "cmStandardIncludes.h"
+
+class cmCLocaleEnvironmentScope
+{
+public:
+ cmCLocaleEnvironmentScope();
+ ~cmCLocaleEnvironmentScope();
+
+private:
+ std::string GetEnv(std::string const& key);
+ void SetEnv(std::string const& key, std::string const& value);
+
+ typedef std::map<std::string, std::string> backup_map_t;
+ backup_map_t EnvironmentBackup;
+};
+
+#endif
diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx
index 62f238369..6ff7c0d98 100644
--- a/Source/cmCMakeHostSystemInformationCommand.cxx
+++ b/Source/cmCMakeHostSystemInformationCommand.cxx
@@ -11,8 +11,6 @@
============================================================================*/
#include "cmCMakeHostSystemInformationCommand.h"
-#include <cmsys/ios/sstream>
-
// cmCMakeHostSystemInformation
bool cmCMakeHostSystemInformationCommand
::InitialPass(std::vector<std::string> const &args, cmExecutionStatus &)
@@ -53,7 +51,7 @@ bool cmCMakeHostSystemInformationCommand
result_list += value;
}
- this->Makefile->AddDefinition(variable.c_str(), result_list.c_str());
+ this->Makefile->AddDefinition(variable, result_list.c_str());
return true;
}
@@ -97,7 +95,7 @@ bool cmCMakeHostSystemInformationCommand
else
{
std::string e = "does not recognize <key> " + key;
- this->SetError(e.c_str());
+ this->SetError(e);
return false;
}
@@ -107,7 +105,7 @@ bool cmCMakeHostSystemInformationCommand
std::string cmCMakeHostSystemInformationCommand
::ValueToString(size_t value) const
{
- cmsys_ios::stringstream tmp;
+ std::stringstream tmp;
tmp << value;
return tmp.str();
}
diff --git a/Source/cmCMakeHostSystemInformationCommand.h b/Source/cmCMakeHostSystemInformationCommand.h
index d1b8700ff..463b180b3 100644
--- a/Source/cmCMakeHostSystemInformationCommand.h
+++ b/Source/cmCMakeHostSystemInformationCommand.h
@@ -48,46 +48,11 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const
+ virtual std::string GetName() const
{
return "cmake_host_system_information";
}
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Query host system specific information.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " cmake_host_system_information(RESULT <variable> QUERY <key> ...)\n"
- "Queries system information of the host system on which cmake runs. "
- "One or more <key> can be provided to "
- "select the information to be queried. "
- "The list of queried values is stored in <variable>.\n"
- "<key> can be one of the following values:\n"
- " NUMBER_OF_LOGICAL_CORES = Number of logical cores.\n"
- " NUMBER_OF_PHYSICAL_CORES = Number of physical cores.\n"
- " HOSTNAME = Hostname.\n"
- " FQDN = Fully qualified domain name.\n"
- " TOTAL_VIRTUAL_MEMORY = "
- "Total virtual memory in megabytes.\n"
- " AVAILABLE_VIRTUAL_MEMORY = "
- "Available virtual memory in megabytes.\n"
- " TOTAL_PHYSICAL_MEMORY = "
- "Total physical memory in megabytes.\n"
- " AVAILABLE_PHYSICAL_MEMORY = "
- "Available physical memory in megabytes.\n"
- ;
- }
-
cmTypeMacro(cmCMakeHostSystemInformationCommand, cmCommand);
private:
diff --git a/Source/cmCMakeMinimumRequired.cxx b/Source/cmCMakeMinimumRequired.cxx
index 49c585fba..8591ed6ce 100644
--- a/Source/cmCMakeMinimumRequired.cxx
+++ b/Source/cmCMakeMinimumRequired.cxx
@@ -63,24 +63,24 @@ bool cmCMakeMinimumRequired
// Get the current version number.
- int current_major = cmVersion::GetMajorVersion();
- int current_minor = cmVersion::GetMinorVersion();
- int current_patch = cmVersion::GetPatchVersion();
- int current_tweak = cmVersion::GetTweakVersion();
+ unsigned int current_major = cmVersion::GetMajorVersion();
+ unsigned int current_minor = cmVersion::GetMinorVersion();
+ unsigned int current_patch = cmVersion::GetPatchVersion();
+ unsigned int current_tweak = cmVersion::GetTweakVersion();
// Parse at least two components of the version number.
// Use zero for those not specified.
- int required_major = 0;
- int required_minor = 0;
- int required_patch = 0;
- int required_tweak = 0;
+ unsigned int required_major = 0;
+ unsigned int required_minor = 0;
+ unsigned int required_patch = 0;
+ unsigned int required_tweak = 0;
if(sscanf(version_string.c_str(), "%u.%u.%u.%u",
&required_major, &required_minor,
&required_patch, &required_tweak) < 2)
{
- cmOStringStream e;
- e << "could not parse VERSION \"" << version_string.c_str() << "\".";
- this->SetError(e.str().c_str());
+ std::ostringstream e;
+ e << "could not parse VERSION \"" << version_string << "\".";
+ this->SetError(e.str());
return false;
}
@@ -97,8 +97,8 @@ bool cmCMakeMinimumRequired
current_tweak < required_tweak))
{
// The current version is too low.
- cmOStringStream e;
- e << "CMake " << version_string.c_str()
+ std::ostringstream e;
+ e << "CMake " << version_string
<< " or higher is required. You are running version "
<< cmVersion::GetCMakeVersion();
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
@@ -114,6 +114,9 @@ bool cmCMakeMinimumRequired
if (required_major < 2 || (required_major == 2 && required_minor < 4))
{
+ this->Makefile->IssueMessage(
+ cmake::AUTHOR_WARNING,
+ "Compatibility with CMake < 2.4 is not supported by CMake >= 3.0.");
this->Makefile->SetPolicyVersion("2.4");
}
else
@@ -129,10 +132,10 @@ bool cmCMakeMinimumRequired::EnforceUnknownArguments()
{
if(!this->UnknownArguments.empty())
{
- cmOStringStream e;
+ std::ostringstream e;
e << "called with unknown argument \""
<< this->UnknownArguments[0] << "\".";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
return true;
diff --git a/Source/cmCMakeMinimumRequired.h b/Source/cmCMakeMinimumRequired.h
index acf28298b..31b727198 100644
--- a/Source/cmCMakeMinimumRequired.h
+++ b/Source/cmCMakeMinimumRequired.h
@@ -45,38 +45,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const {return "cmake_minimum_required";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Set the minimum required version of cmake for a project.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " cmake_minimum_required(VERSION major[.minor[.patch[.tweak]]]\n"
- " [FATAL_ERROR])\n"
- "If the current version of CMake is lower than that required "
- "it will stop processing the project and report an error. "
- "When a version higher than 2.4 is specified the command implicitly "
- "invokes\n"
- " cmake_policy(VERSION major[.minor[.patch[.tweak]]])\n"
- "which sets the cmake policy version level to the version specified. "
- "When version 2.4 or lower is given the command implicitly invokes\n"
- " cmake_policy(VERSION 2.4)\n"
- "which enables compatibility features for CMake 2.4 and lower.\n"
- "The FATAL_ERROR option is accepted but ignored by CMake 2.6 "
- "and higher. "
- "It should be specified so CMake versions 2.4 and lower fail with an "
- "error instead of just a warning.";
- }
+ virtual std::string GetName() const {return "cmake_minimum_required";}
cmTypeMacro(cmCMakeMinimumRequired, cmCommand);
diff --git a/Source/cmCMakePolicyCommand.cxx b/Source/cmCMakePolicyCommand.cxx
index f4be55930..3ef6d356b 100644
--- a/Source/cmCMakePolicyCommand.cxx
+++ b/Source/cmCMakePolicyCommand.cxx
@@ -56,9 +56,9 @@ bool cmCMakePolicyCommand
return this->HandleVersionMode(args);
}
- cmOStringStream e;
+ std::ostringstream e;
e << "given unknown first argument \"" << args[0] << "\"";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
@@ -82,9 +82,9 @@ bool cmCMakePolicyCommand::HandleSetMode(std::vector<std::string> const& args)
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "SET given unrecognized policy status \"" << args[2] << "\"";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
@@ -93,6 +93,22 @@ bool cmCMakePolicyCommand::HandleSetMode(std::vector<std::string> const& args)
this->SetError("SET failed to set policy.");
return false;
}
+ if(args[1] == "CMP0001" &&
+ (status == cmPolicies::WARN || status == cmPolicies::OLD))
+ {
+ if(!(this->Makefile->GetState()
+ ->GetInitializedCacheValue("CMAKE_BACKWARDS_COMPATIBILITY")))
+ {
+ // Set it to 2.4 because that is the last version where the
+ // variable had meaning.
+ this->Makefile->AddCacheDefinition
+ ("CMAKE_BACKWARDS_COMPATIBILITY", "2.4",
+ "For backwards compatibility, what version of CMake "
+ "commands and "
+ "syntax should this version of CMake try to support.",
+ cmState::STRING);
+ }
+ }
return true;
}
@@ -111,12 +127,12 @@ bool cmCMakePolicyCommand::HandleGetMode(std::vector<std::string> const& args)
// Lookup the policy number.
cmPolicies::PolicyID pid;
- if(!this->Makefile->GetPolicies()->GetPolicyID(id.c_str(), pid))
+ if(!cmPolicies::GetPolicyID(id.c_str(), pid))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "GET given policy \"" << id << "\" which is not known to this "
<< "version of CMake.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
@@ -126,22 +142,22 @@ bool cmCMakePolicyCommand::HandleGetMode(std::vector<std::string> const& args)
{
case cmPolicies::OLD:
// Report that the policy is set to OLD.
- this->Makefile->AddDefinition(var.c_str(), "OLD");
+ this->Makefile->AddDefinition(var, "OLD");
break;
case cmPolicies::WARN:
// Report that the policy is not set.
- this->Makefile->AddDefinition(var.c_str(), "");
+ this->Makefile->AddDefinition(var, "");
break;
case cmPolicies::NEW:
// Report that the policy is set to NEW.
- this->Makefile->AddDefinition(var.c_str(), "NEW");
+ this->Makefile->AddDefinition(var, "NEW");
break;
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
// The policy is required to be set before anything needs it.
{
- cmOStringStream e;
- e << this->Makefile->GetPolicies()->GetRequiredPolicyError(pid)
+ std::ostringstream e;
+ e << cmPolicies::GetRequiredPolicyError(pid)
<< "\n"
<< "The call to cmake_policy(GET " << id << " ...) at which this "
<< "error appears requests the policy, and this version of CMake "
diff --git a/Source/cmCMakePolicyCommand.h b/Source/cmCMakePolicyCommand.h
index 4f9faa168..8dc8fbeed 100644
--- a/Source/cmCMakePolicyCommand.h
+++ b/Source/cmCMakePolicyCommand.h
@@ -46,89 +46,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const {return "cmake_policy";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Manage CMake Policy settings.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- "As CMake evolves it is sometimes necessary to change existing "
- "behavior in order to fix bugs or improve implementations of "
- "existing features. "
- "The CMake Policy mechanism is designed to help keep existing projects "
- "building as new versions of CMake introduce changes in behavior. "
- "Each new policy (behavioral change) is given an identifier of "
- "the form \"CMP<NNNN>\" where \"<NNNN>\" is an integer index. "
- "Documentation associated with each policy describes the OLD and NEW "
- "behavior and the reason the policy was introduced. "
- "Projects may set each policy to select the desired behavior. "
- "When CMake needs to know which behavior to use it checks for "
- "a setting specified by the project. "
- "If no setting is available the OLD behavior is assumed and a warning "
- "is produced requesting that the policy be set.\n"
- "The cmake_policy command is used to set policies to OLD or NEW "
- "behavior. "
- "While setting policies individually is supported, we encourage "
- "projects to set policies based on CMake versions.\n"
- " cmake_policy(VERSION major.minor[.patch[.tweak]])\n"
- "Specify that the current CMake list file is written for the "
- "given version of CMake. "
- "All policies introduced in the specified version or earlier "
- "will be set to use NEW behavior. "
- "All policies introduced after the specified version will be unset "
- "(unless variable CMAKE_POLICY_DEFAULT_CMP<NNNN> sets a default). "
- "This effectively requests behavior preferred as of a given CMake "
- "version and tells newer CMake versions to warn about their new "
- "policies. "
- "The policy version specified must be at least 2.4 or the command "
- "will report an error. "
- "In order to get compatibility features supporting versions earlier "
- "than 2.4 see documentation of policy CMP0001."
- "\n"
- " cmake_policy(SET CMP<NNNN> NEW)\n"
- " cmake_policy(SET CMP<NNNN> OLD)\n"
- "Tell CMake to use the OLD or NEW behavior for a given policy. "
- "Projects depending on the old behavior of a given policy may "
- "silence a policy warning by setting the policy state to OLD. "
- "Alternatively one may fix the project to work with the new behavior "
- "and set the policy state to NEW."
- "\n"
- " cmake_policy(GET CMP<NNNN> <variable>)\n"
- "Check whether a given policy is set to OLD or NEW behavior. "
- "The output variable value will be \"OLD\" or \"NEW\" if the "
- "policy is set, and empty otherwise."
- "\n"
- "CMake keeps policy settings on a stack, so changes made by the "
- "cmake_policy command affect only the top of the stack. "
- "A new entry on the policy stack is managed automatically for each "
- "subdirectory to protect its parents and siblings. "
- "CMake also manages a new entry for scripts loaded by include() and "
- "find_package() commands except when invoked with the NO_POLICY_SCOPE "
- "option (see also policy CMP0011). "
- "The cmake_policy command provides an interface to manage custom "
- "entries on the policy stack:\n"
- " cmake_policy(PUSH)\n"
- " cmake_policy(POP)\n"
- "Each PUSH must have a matching POP to erase any changes. "
- "This is useful to make temporary changes to policy settings."
- "\n"
- "Functions and macros record policy settings when they are created "
- "and use the pre-record policies when they are invoked. "
- "If the function or macro implementation sets policies, the changes "
- "automatically propagate up through callers until they reach the "
- "closest nested policy stack entry."
- ;
- }
+ virtual std::string GetName() const {return "cmake_policy";}
cmTypeMacro(cmCMakePolicyCommand, cmCommand);
private:
diff --git a/Source/cmCPackPropertiesGenerator.cxx b/Source/cmCPackPropertiesGenerator.cxx
new file mode 100644
index 000000000..35b3d59dc
--- /dev/null
+++ b/Source/cmCPackPropertiesGenerator.cxx
@@ -0,0 +1,47 @@
+#include "cmCPackPropertiesGenerator.h"
+
+#include "cmOutputConverter.h"
+#include "cmLocalGenerator.h"
+
+cmCPackPropertiesGenerator::cmCPackPropertiesGenerator(
+ cmLocalGenerator* lg,
+ cmInstalledFile const& installedFile,
+ std::vector<std::string> const& configurations):
+ cmScriptGenerator("CPACK_BUILD_CONFIG", configurations),
+ LG(lg),
+ InstalledFile(installedFile)
+{
+ this->ActionsPerConfig = true;
+}
+
+void cmCPackPropertiesGenerator::GenerateScriptForConfig(std::ostream& os,
+ const std::string& config, Indent const& indent)
+{
+ std::string const& expandedFileName =
+ this->InstalledFile.GetNameExpression().Evaluate(this->LG,
+ config);
+
+ cmInstalledFile::PropertyMapType const& properties =
+ this->InstalledFile.GetProperties();
+
+ for(cmInstalledFile::PropertyMapType::const_iterator i = properties.begin();
+ i != properties.end(); ++i)
+ {
+ std::string const& name = i->first;
+ cmInstalledFile::Property const& property = i->second;
+
+ os << indent << "set_property(INSTALL " <<
+ cmOutputConverter::EscapeForCMake(expandedFileName) << " PROPERTY " <<
+ cmOutputConverter::EscapeForCMake(name);
+
+ for(cmInstalledFile::ExpressionVectorType::const_iterator
+ j = property.ValueExpressions.begin();
+ j != property.ValueExpressions.end(); ++j)
+ {
+ std::string value = (*j)->Evaluate(this->LG, config);
+ os << " " << cmOutputConverter::EscapeForCMake(value);
+ }
+
+ os << ")\n";
+ }
+}
diff --git a/Source/cmCPackPropertiesGenerator.h b/Source/cmCPackPropertiesGenerator.h
new file mode 100644
index 000000000..eec3df092
--- /dev/null
+++ b/Source/cmCPackPropertiesGenerator.h
@@ -0,0 +1,40 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmCPackPropertiesGenerator_h
+#define cmCPackPropertiesGenerator_h
+
+#include "cmScriptGenerator.h"
+#include "cmInstalledFile.h"
+
+class cmLocalGenerator;
+
+/** \class cmCPackPropertiesGenerator
+ * \brief Support class for generating CPackProperties.cmake.
+ *
+ */
+class cmCPackPropertiesGenerator: public cmScriptGenerator
+{
+public:
+ cmCPackPropertiesGenerator(
+ cmLocalGenerator* lg,
+ cmInstalledFile const& installedFile,
+ std::vector<std::string> const& configurations);
+
+protected:
+ virtual void GenerateScriptForConfig(std::ostream& os,
+ const std::string& config, Indent const& indent);
+
+ cmLocalGenerator* LG;
+ cmInstalledFile const& InstalledFile;
+};
+
+#endif
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx
index cb62f21e6..fb78446dc 100644
--- a/Source/cmCPluginAPI.cxx
+++ b/Source/cmCPluginAPI.cxx
@@ -51,12 +51,14 @@ void CCONV cmSetError(void *info, const char *err)
unsigned int CCONV cmGetCacheMajorVersion(void *arg)
{
cmMakefile *mf = static_cast<cmMakefile *>(arg);
- return mf->GetCacheMajorVersion();
+ cmState *state = mf->GetState();
+ return state->GetCacheMajorVersion();
}
unsigned int CCONV cmGetCacheMinorVersion(void *arg)
{
cmMakefile *mf = static_cast<cmMakefile *>(arg);
- return mf->GetCacheMinorVersion();
+ cmState *state = mf->GetState();
+ return state->GetCacheMinorVersion();
}
unsigned int CCONV cmGetMajorVersion(void *)
@@ -85,27 +87,27 @@ void CCONV cmAddCacheDefinition(void *arg, const char* name,
{
case CM_CACHE_BOOL:
mf->AddCacheDefinition(name,value,doc,
- cmCacheManager::BOOL);
+ cmState::BOOL);
break;
case CM_CACHE_PATH:
mf->AddCacheDefinition(name,value,doc,
- cmCacheManager::PATH);
+ cmState::PATH);
break;
case CM_CACHE_FILEPATH:
mf->AddCacheDefinition(name,value,doc,
- cmCacheManager::FILEPATH);
+ cmState::FILEPATH);
break;
case CM_CACHE_STRING:
mf->AddCacheDefinition(name,value,doc,
- cmCacheManager::STRING);
+ cmState::STRING);
break;
case CM_CACHE_INTERNAL:
mf->AddCacheDefinition(name,value,doc,
- cmCacheManager::INTERNAL);
+ cmState::INTERNAL);
break;
case CM_CACHE_STATIC:
mf->AddCacheDefinition(name,value,doc,
- cmCacheManager::STATIC);
+ cmState::STATIC);
break;
}
}
@@ -113,7 +115,9 @@ void CCONV cmAddCacheDefinition(void *arg, const char* name,
const char* CCONV cmGetProjectName(void *arg)
{
cmMakefile *mf = static_cast<cmMakefile *>(arg);
- return mf->GetProjectName();
+ static std::string name;
+ name = mf->GetStateSnapshot().GetProjectName();
+ return name.c_str();
}
const char* CCONV cmGetHomeDirectory(void *arg)
@@ -129,22 +133,22 @@ const char* CCONV cmGetHomeOutputDirectory(void *arg)
const char* CCONV cmGetStartDirectory(void *arg)
{
cmMakefile *mf = static_cast<cmMakefile *>(arg);
- return mf->GetStartDirectory();
+ return mf->GetCurrentSourceDirectory();
}
const char* CCONV cmGetStartOutputDirectory(void *arg)
{
cmMakefile *mf = static_cast<cmMakefile *>(arg);
- return mf->GetStartOutputDirectory();
+ return mf->GetCurrentBinaryDirectory();
}
const char* CCONV cmGetCurrentDirectory(void *arg)
{
cmMakefile *mf = static_cast<cmMakefile *>(arg);
- return mf->GetCurrentDirectory();
+ return mf->GetCurrentSourceDirectory();
}
const char* CCONV cmGetCurrentOutputDirectory(void *arg)
{
cmMakefile *mf = static_cast<cmMakefile *>(arg);
- return mf->GetCurrentOutputDirectory();
+ return mf->GetCurrentBinaryDirectory();
}
const char* CCONV cmGetDefinition(void *arg,const char*def)
{
@@ -162,7 +166,7 @@ int CCONV cmIsOn(void *arg, const char* name)
int CCONV cmCommandExists(void *arg, const char* name)
{
cmMakefile *mf = static_cast<cmMakefile *>(arg);
- return static_cast<int>(mf->CommandExists(name));
+ return static_cast<int>(mf->GetState()->GetCommand(name) ? 1 : 0);
}
void CCONV cmAddDefineFlag(void *arg, const char* definition)
@@ -353,10 +357,11 @@ void CCONV cmAddCustomCommandToTarget(void *arg, const char* target,
}
// Pass the call to the makefile instance.
+ std::vector<std::string> no_byproducts;
std::vector<std::string> no_depends;
const char* no_comment = 0;
const char* no_working_dir = 0;
- mf->AddCustomCommandToTarget(target, no_depends, commandLines,
+ mf->AddCustomCommandToTarget(target, no_byproducts, no_depends, commandLines,
cctype, no_comment, no_working_dir);
}
@@ -368,13 +373,13 @@ void CCONV cmAddLinkLibraryForTarget(void *arg, const char *tgt,
switch (libtype)
{
case CM_LIBRARY_GENERAL:
- mf->AddLinkLibraryForTarget(tgt,value, cmTarget::GENERAL);
+ mf->AddLinkLibraryForTarget(tgt,value, GENERAL_LibraryType);
break;
case CM_LIBRARY_DEBUG:
- mf->AddLinkLibraryForTarget(tgt,value, cmTarget::DEBUG);
+ mf->AddLinkLibraryForTarget(tgt,value, DEBUG_LibraryType);
break;
case CM_LIBRARY_OPTIMIZED:
- mf->AddLinkLibraryForTarget(tgt,value, cmTarget::OPTIMIZED);
+ mf->AddLinkLibraryForTarget(tgt,value, OPTIMIZED_LibraryType);
break;
}
}
@@ -390,7 +395,7 @@ void CCONV cmAddLibrary(void *arg, const char *libname, int shared,
srcs2.push_back(srcs[i]);
}
mf->AddLibrary(libname,
- (shared? cmTarget::SHARED_LIBRARY : cmTarget::STATIC_LIBRARY),
+ (shared? cmState::SHARED_LIBRARY : cmState::STATIC_LIBRARY),
srcs2);
}
@@ -423,8 +428,7 @@ int CCONV cmExecuteCommand(void *arg, const char *name,
{
// Assume all arguments are quoted.
lff.Arguments.push_back(
- cmListFileArgument(args[i], cmListFileArgument::Quoted,
- "[CMake-Plugin]", 0));
+ cmListFileArgument(args[i], cmListFileArgument::Quoted, 0));
}
cmExecutionStatus status;
return mf->ExecuteCommand(lff,status);
@@ -437,15 +441,14 @@ void CCONV cmExpandSourceListArguments(void *arg,
char ***resArgv,
unsigned int startArgumentIndex)
{
- cmMakefile *mf = static_cast<cmMakefile *>(arg);
+ (void)arg;
+ (void)startArgumentIndex;
std::vector<std::string> result;
- std::vector<std::string> args2;
int i;
for (i = 0; i < numArgs; ++i)
{
- args2.push_back(args[i]);
+ result.push_back(args[i]);
}
- mf->ExpandSourceListArguments(args2, result, startArgumentIndex);
int resargc = static_cast<int>(result.size());
char **resargv = 0;
if (resargc)
@@ -524,11 +527,9 @@ void * CCONV cmCreateSourceFile(void)
return (void*)new cmCPluginAPISourceFile;
}
-void * CCONV cmCreateNewSourceFile(void *arg)
+void * CCONV cmCreateNewSourceFile(void *)
{
- cmMakefile *mf = static_cast<cmMakefile *>(arg);
cmCPluginAPISourceFile *sf = new cmCPluginAPISourceFile;
- sf->Properties.SetCMakeInstance(mf->GetCMakeInstance());
return (void*)sf;
}
@@ -557,9 +558,9 @@ void CCONV *cmGetSource(void *arg, const char *name)
sf->RealSourceFile = rsf;
sf->FullPath = rsf->GetFullPath();
sf->SourceName =
- cmSystemTools::GetFilenameWithoutLastExtension(sf->FullPath.c_str());
+ cmSystemTools::GetFilenameWithoutLastExtension(sf->FullPath);
sf->SourceExtension =
- cmSystemTools::GetFilenameLastExtension(sf->FullPath.c_str());
+ cmSystemTools::GetFilenameLastExtension(sf->FullPath);
// Store the proxy in the map so it can be re-used and deleted later.
cmCPluginAPISourceFileMap::value_type entry(rsf, sf);
@@ -583,7 +584,7 @@ void * CCONV cmAddSource(void *arg, void *arg2)
}
// Create the real cmSourceFile instance and copy over saved information.
- cmSourceFile* rsf = mf->GetOrCreateSource(osf->FullPath.c_str());
+ cmSourceFile* rsf = mf->GetOrCreateSource(osf->FullPath);
rsf->GetProperties() = osf->Properties;
for(std::vector<std::string>::iterator i = osf->Depends.begin();
i != osf->Depends.end(); ++i)
@@ -628,11 +629,7 @@ const char * CCONV cmSourceFileGetProperty(void *arg,const char *prop)
{
return sf->FullPath.c_str();
}
- bool chain = false;
- // Ignore chain because old code will not expect it and it is a
- // pain to implement here anyway.
- return sf->Properties.GetPropertyValue(prop, cmProperty::SOURCE_FILE,
- chain);
+ return sf->Properties.GetPropertyValue(prop);
}
}
@@ -660,7 +657,7 @@ void CCONV cmSourceFileSetProperty(void *arg,const char *prop,
else if(prop)
{
if(!value) { value = "NOTFOUND"; }
- sf->Properties.SetProperty(prop, value, cmProperty::SOURCE_FILE);
+ sf->Properties.SetProperty(prop, value);
}
}
@@ -768,7 +765,7 @@ void CCONV cmSourceFileSetName(void *arg, const char* name, const char* dir,
}
}
- cmOStringStream e;
+ std::ostringstream e;
e << "Cannot find source file \"" << pathname << "\"";
e << "\n\nTried extensions";
for( std::vector<std::string>::const_iterator ext = sourceExts.begin();
@@ -799,8 +796,7 @@ void CCONV cmSourceFileSetName2(void *arg, const char* name, const char* dir,
// Implement the old SetName method code here.
if(headerFileOnly)
{
- sf->Properties.SetProperty("HEADER_FILE_ONLY", "1",
- cmProperty::SOURCE_FILE);
+ sf->Properties.SetProperty("HEADER_FILE_ONLY", "1");
}
sf->SourceName = name;
std::string fname = sf->SourceName;
@@ -865,7 +861,7 @@ void CCONV DefineSourceFileProperty (void *arg, const char *name,
int chained)
{
cmMakefile *mf = static_cast<cmMakefile *>(arg);
- mf->GetCMakeInstance()->DefineProperty(name,cmProperty::SOURCE_FILE,
+ mf->GetState()->DefineProperty(name,cmProperty::SOURCE_FILE,
briefDocs, longDocs,
chained != 0);
}
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 14e1f5014..f3e7121f7 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -9,22 +9,24 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#include "cm_curl.h"
+#include "cmCurl.h" // include before anything that includes windows.h
#include "cmCTest.h"
#include "cmake.h"
#include "cmMakefile.h"
-#include "cmLocalGenerator.h"
#include "cmGlobalGenerator.h"
#include <cmsys/Base64.h>
#include <cmsys/Directory.hxx>
#include <cmsys/SystemInformation.hxx>
+#include <cmsys/FStream.hxx>
#include "cmDynamicLoader.h"
#include "cmGeneratedFileStream.h"
-#include "cmXMLSafe.h"
#include "cmVersionMacros.h"
#include "cmCTestCommand.h"
#include "cmCTestStartCommand.h"
+#include "cmAlgorithms.h"
+#include "cmState.h"
+#include "cmXMLWriter.h"
#include "cmCTestBuildHandler.h"
#include "cmCTestBuildAndTestHandler.h"
@@ -53,14 +55,10 @@
#include <cm_zlib.h>
#include <cmsys/Base64.h>
-#if defined(__BEOS__)
+#if defined(__BEOS__) || defined(__HAIKU__)
#include <be/kernel/OS.h> /* disable_debugger() API. */
#endif
-#if defined(__HAIKU__)
-#include <os/kernel/OS.h> /* disable_debugger() API. */
-#endif
-
#define DEBUGOUT std::cout << __LINE__ << " "; std::cout
#define DEBUGERR std::cerr << __LINE__ << " "; std::cerr
@@ -81,7 +79,7 @@ struct tm* cmCTest::GetNightlyTime(std::string str,
lctime->tm_mday,
str.c_str());
cmCTestLog(this, OUTPUT, "Determine Nightly Start Time" << std::endl
- << " Specified time: " << str.c_str() << std::endl);
+ << " Specified time: " << str << std::endl);
//Convert the nightly start time to seconds. Since we are
//providing only a time and a timezone, the current date of
//the local machine is assumed. Consequently, nightlySeconds
@@ -156,7 +154,7 @@ std::string cmCTest::CurrentTime()
strftime(current_time, 1000, "%a %b %d %H:%M:%S %Z %Y", t);
}
cmCTestLog(this, DEBUG, " Current_Time: " << current_time << std::endl);
- return cmXMLSafe(cmCTest::CleanString(current_time)).str();
+ return cmCTest::CleanString(current_time);
}
//----------------------------------------------------------------------
@@ -195,6 +193,7 @@ int cmCTest::HTTPRequest(std::string url, HTTPMethod method,
FILE* file;
::curl_global_init(CURL_GLOBAL_ALL);
curl = ::curl_easy_init();
+ cmCurlSetCAInfo(curl);
//set request options based on method
switch(method)
@@ -211,17 +210,15 @@ int cmCTest::HTTPRequest(std::string url, HTTPMethod method,
return -1;
}
::curl_easy_setopt(curl, CURLOPT_PUT, 1);
- file = ::fopen(putFile.c_str(), "rb");
+ file = cmsys::SystemTools::Fopen(putFile, "rb");
::curl_easy_setopt(curl, CURLOPT_INFILE, file);
//fall through to append GET fields
case cmCTest::HTTP_GET:
- if(fields.size())
+ if(!fields.empty())
{
url += "?" + fields;
}
break;
- default:
- break;
}
::curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
@@ -245,7 +242,7 @@ int cmCTest::HTTPRequest(std::string url, HTTPMethod method,
//----------------------------------------------------------------------
std::string cmCTest::MakeURLSafe(const std::string& str)
{
- cmOStringStream ost;
+ std::ostringstream ost;
char buffer[10];
for ( std::string::size_type pos = 0; pos < str.size(); pos ++ )
{
@@ -295,6 +292,7 @@ cmCTest::cmCTest()
this->LabelSummary = true;
this->ParallelLevel = 1;
this->ParallelLevelSetInCli = false;
+ this->TestLoad = 0;
this->SubmitIndex = 0;
this->Failover = false;
this->BatchJobs = false;
@@ -332,9 +330,11 @@ cmCTest::cmCTest()
this->OutputTestOutputOnTestFailure = false;
this->ComputedCompressTestOutput = false;
this->ComputedCompressMemCheckOutput = false;
- if(cmSystemTools::GetEnv("CTEST_OUTPUT_ON_FAILURE"))
+ this->RepeatTests = 1; // default to run each test once
+ this->RepeatUntilFail = false;
+ if(const char* outOnFail = cmSystemTools::GetEnv("CTEST_OUTPUT_ON_FAILURE"))
{
- this->OutputTestOutputOnTestFailure = true;
+ this->OutputTestOutputOnTestFailure = !cmSystemTools::IsOff(outOnFail);
}
this->InitStreams();
@@ -383,13 +383,7 @@ cmCTest::cmCTest()
//----------------------------------------------------------------------
cmCTest::~cmCTest()
{
- cmCTest::t_TestingHandlers::iterator it;
- for ( it = this->TestingHandlers.begin();
- it != this->TestingHandlers.end(); ++ it )
- {
- delete it->second;
- it->second = 0;
- }
+ cmDeleteAll(this->TestingHandlers);
this->SetOutputLogFileName(0);
}
@@ -398,6 +392,11 @@ void cmCTest::SetParallelLevel(int level)
this->ParallelLevel = level < 1 ? 1 : level;
}
+void cmCTest::SetTestLoad(unsigned long load)
+{
+ this->TestLoad = load;
+}
+
//----------------------------------------------------------------------------
bool cmCTest::ShouldCompressTestOutput()
{
@@ -473,7 +472,13 @@ cmCTest::Part cmCTest::GetPartFromName(const char* name)
//----------------------------------------------------------------------
int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
{
- cmCTestLog(this, DEBUG, "Here: " << __LINE__ << std::endl);
+ bool quiet = false;
+ if (command && command->ShouldBeQuiet())
+ {
+ quiet = true;
+ }
+
+ cmCTestOptionalLog(this, DEBUG, "Here: " << __LINE__ << std::endl, quiet);
if(!this->InteractiveDebugMode)
{
this->BlockTestErrorDiagnostics();
@@ -488,35 +493,38 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
this->UpdateCTestConfiguration();
- cmCTestLog(this, DEBUG, "Here: " << __LINE__ << std::endl);
+ cmCTestOptionalLog(this, DEBUG, "Here: " << __LINE__ << std::endl, quiet);
if ( this->ProduceXML )
{
- cmCTestLog(this, DEBUG, "Here: " << __LINE__ << std::endl);
- cmCTestLog(this, OUTPUT,
- " Site: " << this->GetCTestConfiguration("Site") << std::endl
- << " Build name: " << this->GetCTestConfiguration("BuildName")
- << std::endl);
- cmCTestLog(this, DEBUG, "Produce XML is on" << std::endl);
+ cmCTestOptionalLog(this, DEBUG, "Here: " << __LINE__ << std::endl, quiet);
+ cmCTestOptionalLog(this, OUTPUT,
+ " Site: " << this->GetCTestConfiguration("Site") << std::endl <<
+ " Build name: " << cmCTest::SafeBuildIdField(
+ this->GetCTestConfiguration("BuildName")) << std::endl, quiet);
+ cmCTestOptionalLog(this, DEBUG, "Produce XML is on" << std::endl, quiet);
if ( this->TestModel == cmCTest::NIGHTLY &&
this->GetCTestConfiguration("NightlyStartTime").empty() )
{
- cmCTestLog(this, WARNING,
- "WARNING: No nightly start time found please set in"
- " CTestConfig.cmake or DartConfig.cmake" << std::endl);
- cmCTestLog(this, DEBUG, "Here: " << __LINE__ << std::endl);
+ cmCTestOptionalLog(this, WARNING,
+ "WARNING: No nightly start time found please set in CTestConfig.cmake"
+ " or DartConfig.cmake" << std::endl, quiet);
+ cmCTestOptionalLog(this, DEBUG, "Here: " << __LINE__ << std::endl,
+ quiet);
return 0;
}
}
cmake cm;
- cmGlobalGenerator gg;
- gg.SetCMakeInstance(&cm);
- cmsys::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator());
- cmMakefile *mf = lg->GetMakefile();
- if ( !this->ReadCustomConfigurationFileTree(this->BinaryDir.c_str(), mf) )
- {
- cmCTestLog(this, DEBUG, "Cannot find custom configuration file tree"
- << std::endl);
+ cm.SetHomeDirectory("");
+ cm.SetHomeOutputDirectory("");
+ cm.GetCurrentSnapshot().SetDefaultDefinitions();
+ cmGlobalGenerator gg(&cm);
+ cmsys::auto_ptr<cmMakefile> mf(new cmMakefile(&gg, cm.GetCurrentSnapshot()));
+ if ( !this->ReadCustomConfigurationFileTree(this->BinaryDir.c_str(),
+ mf.get()) )
+ {
+ cmCTestOptionalLog(this, DEBUG,
+ "Cannot find custom configuration file tree" << std::endl, quiet);
return 0;
}
@@ -527,7 +535,7 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
std::string testingDir = this->BinaryDir + "/Testing";
if ( cmSystemTools::FileExists(testingDir.c_str()) )
{
- if ( !cmSystemTools::FileIsDirectory(testingDir.c_str()) )
+ if ( !cmSystemTools::FileIsDirectory(testingDir) )
{
cmCTestLog(this, ERROR_MESSAGE, "File " << testingDir
<< " is in the place of the testing directory" << std::endl);
@@ -553,7 +561,7 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
}
std::string tagfile = testingDir + "/TAG";
- std::ifstream tfin(tagfile.c_str());
+ cmsys::ifstream tfin(tagfile.c_str());
std::string tag;
if (createNewTag)
@@ -589,11 +597,12 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
}
tfin.close();
}
- if (tag.size() == 0 || (0 != command) || this->Parts[PartStart])
+ if (tag.empty() || (0 != command) || this->Parts[PartStart])
{
- cmCTestLog(this, DEBUG, "TestModel: " << this->GetTestModelString()
- << std::endl);
- cmCTestLog(this, DEBUG, "TestModel: " << this->TestModel << std::endl);
+ cmCTestOptionalLog(this, DEBUG, "TestModel: " <<
+ this->GetTestModelString() << std::endl, quiet);
+ cmCTestOptionalLog(this, DEBUG, "TestModel: " <<
+ this->TestModel << std::endl, quiet);
if ( this->TestModel == cmCTest::NIGHTLY )
{
lctime = this->GetNightlyTime(
@@ -608,7 +617,7 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
lctime->tm_hour,
lctime->tm_min);
tag = datestring;
- std::ofstream ofs(tagfile.c_str());
+ cmsys::ofstream ofs(tagfile.c_str());
if ( ofs )
{
ofs << tag << std::endl;
@@ -617,8 +626,8 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
ofs.close();
if ( 0 == command )
{
- cmCTestLog(this, OUTPUT, "Create new tag: " << tag << " - "
- << this->GetTestModelString() << std::endl);
+ cmCTestOptionalLog(this, OUTPUT, "Create new tag: " << tag << " - "
+ << this->GetTestModelString() << std::endl, quiet);
}
}
}
@@ -638,8 +647,8 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
return 0;
}
- cmCTestLog(this, OUTPUT, " Use existing tag: " << tag << " - "
- << this->GetTestModelString() << std::endl);
+ cmCTestOptionalLog(this, OUTPUT, " Use existing tag: " << tag << " - "
+ << this->GetTestModelString() << std::endl, quiet);
}
this->CurrentTag = tag;
@@ -652,8 +661,8 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
bool cmCTest::InitializeFromCommand(cmCTestStartCommand* command)
{
std::string src_dir
- = this->GetCTestConfiguration("SourceDirectory").c_str();
- std::string bld_dir = this->GetCTestConfiguration("BuildDirectory").c_str();
+ = this->GetCTestConfiguration("SourceDirectory");
+ std::string bld_dir = this->GetCTestConfiguration("BuildDirectory");
this->DartVersion = 1;
this->DropSiteCDash = false;
for(Part p = PartStart; p != PartCount; p = Part(p+1))
@@ -683,33 +692,33 @@ bool cmCTest::InitializeFromCommand(cmCTestStartCommand* command)
if ( !fname.empty() )
{
- cmCTestLog(this, OUTPUT, " Reading ctest configuration file: "
- << fname.c_str() << std::endl);
- bool readit = mf->ReadListFile(mf->GetCurrentListFile(),
- fname.c_str() );
+ cmCTestOptionalLog(this, OUTPUT, " Reading ctest configuration file: "
+ << fname << std::endl, command->ShouldBeQuiet());
+ bool readit = mf->ReadDependentFile(fname.c_str());
if(!readit)
{
std::string m = "Could not find include file: ";
m += fname;
- command->SetError(m.c_str());
+ command->SetError(m);
return false;
}
}
else
{
- cmCTestLog(this, WARNING,
+ cmCTestOptionalLog(this, WARNING,
"Cannot locate CTest configuration: in BuildDirectory: "
- << bld_dir_fname.c_str() << std::endl);
- cmCTestLog(this, WARNING,
+ << bld_dir_fname << std::endl, command->ShouldBeQuiet());
+ cmCTestOptionalLog(this, WARNING,
"Cannot locate CTest configuration: in SourceDirectory: "
- << src_dir_fname.c_str() << std::endl);
+ << src_dir_fname << std::endl, command->ShouldBeQuiet());
}
this->SetCTestConfigurationFromCMakeVariable(mf, "NightlyStartTime",
- "CTEST_NIGHTLY_START_TIME");
- this->SetCTestConfigurationFromCMakeVariable(mf, "Site", "CTEST_SITE");
+ "CTEST_NIGHTLY_START_TIME", command->ShouldBeQuiet());
+ this->SetCTestConfigurationFromCMakeVariable(mf, "Site", "CTEST_SITE",
+ command->ShouldBeQuiet());
this->SetCTestConfigurationFromCMakeVariable(mf, "BuildName",
- "CTEST_BUILD_NAME");
+ "CTEST_BUILD_NAME", command->ShouldBeQuiet());
const char* dartVersion = mf->GetDefinition("CTEST_DART_SERVER_VERSION");
if ( dartVersion )
{
@@ -728,8 +737,9 @@ bool cmCTest::InitializeFromCommand(cmCTestStartCommand* command)
{
return false;
}
- cmCTestLog(this, OUTPUT, " Use " << this->GetTestModelString()
- << " tag: " << this->GetCurrentTag() << std::endl);
+ cmCTestOptionalLog(this, OUTPUT, " Use " << this->GetTestModelString()
+ << " tag: " << this->GetCurrentTag() << std::endl,
+ command->ShouldBeQuiet());
return true;
}
@@ -751,13 +761,13 @@ bool cmCTest::UpdateCTestConfiguration()
}
}
cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, "UpdateCTestConfiguration from :"
- << fileName.c_str() << "\n");
+ << fileName << "\n");
if ( !cmSystemTools::FileExists(fileName.c_str()) )
{
// No need to exit if we are not producing XML
if ( this->ProduceXML )
{
- cmCTestLog(this, ERROR_MESSAGE, "Cannot find file: " << fileName.c_str()
+ cmCTestLog(this, ERROR_MESSAGE, "Cannot find file: " << fileName
<< std::endl);
return false;
}
@@ -765,9 +775,9 @@ bool cmCTest::UpdateCTestConfiguration()
else
{
cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, "Parse Config file:"
- << fileName.c_str() << "\n");
+ << fileName << "\n");
// parse the dart test file
- std::ifstream fin(fileName.c_str());
+ cmsys::ifstream fin(fileName.c_str());
if(!fin)
{
@@ -781,7 +791,7 @@ bool cmCTest::UpdateCTestConfiguration()
fin.getline(buffer, 1023);
buffer[1023] = 0;
std::string line = cmCTest::CleanString(buffer);
- if(line.size() == 0)
+ if(line.empty())
{
continue;
}
@@ -812,9 +822,23 @@ bool cmCTest::UpdateCTestConfiguration()
if ( !this->GetCTestConfiguration("BuildDirectory").empty() )
{
this->BinaryDir = this->GetCTestConfiguration("BuildDirectory");
- cmSystemTools::ChangeDirectory(this->BinaryDir.c_str());
+ cmSystemTools::ChangeDirectory(this->BinaryDir);
}
this->TimeOut = atoi(this->GetCTestConfiguration("TimeOut").c_str());
+ std::string const& testLoad = this->GetCTestConfiguration("TestLoad");
+ if (!testLoad.empty())
+ {
+ unsigned long load;
+ if (cmSystemTools::StringToULong(testLoad.c_str(), &load))
+ {
+ this->SetTestLoad(load);
+ }
+ else
+ {
+ cmCTestLog(this, WARNING, "Invalid value for 'Test Load' : "
+ << testLoad << std::endl);
+ }
+ }
if ( this->ProduceXML )
{
this->CompressXMLFiles = cmSystemTools::IsOn(
@@ -881,13 +905,13 @@ bool cmCTest::OpenOutputFile(const std::string& path,
bool compress)
{
std::string testingDir = this->BinaryDir + "/Testing";
- if ( path.size() > 0 )
+ if (!path.empty())
{
testingDir += "/" + path;
}
if ( cmSystemTools::FileExists(testingDir.c_str()) )
{
- if ( !cmSystemTools::FileIsDirectory(testingDir.c_str()) )
+ if ( !cmSystemTools::FileIsDirectory(testingDir) )
{
cmCTestLog(this, ERROR_MESSAGE, "File " << testingDir
<< " is in the place of the testing directory"
@@ -933,7 +957,7 @@ bool cmCTest::AddIfExists(Part part, const char* file)
{
std::string name = file;
name += ".gz";
- if ( this->CTestFileExists(name.c_str()) )
+ if ( this->CTestFileExists(name) )
{
this->AddSubmitFile(part, file);
}
@@ -1064,19 +1088,19 @@ int cmCTest::ProcessTests()
if ( !notest )
{
std::string notes_dir = this->BinaryDir + "/Testing/Notes";
- if ( cmSystemTools::FileIsDirectory(notes_dir.c_str()) )
+ if ( cmSystemTools::FileIsDirectory(notes_dir) )
{
cmsys::Directory d;
- d.Load(notes_dir.c_str());
+ d.Load(notes_dir);
unsigned long kk;
for ( kk = 0; kk < d.GetNumberOfFiles(); kk ++ )
{
const char* file = d.GetFile(kk);
std::string fullname = notes_dir + "/" + file;
if ( cmSystemTools::FileExists(fullname.c_str()) &&
- !cmSystemTools::FileIsDirectory(fullname.c_str()) )
+ !cmSystemTools::FileIsDirectory(fullname) )
{
- if ( this->NotesFiles.size() > 0 )
+ if (!this->NotesFiles.empty())
{
this->NotesFiles += ";";
}
@@ -1089,7 +1113,7 @@ int cmCTest::ProcessTests()
if (this->Parts[PartNotes])
{
this->UpdateCTestConfiguration();
- if ( this->NotesFiles.size() )
+ if (!this->NotesFiles.empty())
{
this->GenerateNotesFile(this->NotesFiles.c_str());
}
@@ -1135,11 +1159,11 @@ int cmCTest::GetTestModelFromString(const char* str)
return cmCTest::EXPERIMENTAL;
}
std::string rstr = cmSystemTools::LowerCase(str);
- if ( strncmp(rstr.c_str(), "cont", 4) == 0 )
+ if ( cmHasLiteralPrefix(rstr.c_str(), "cont") )
{
return cmCTest::CONTINUOUS;
}
- if ( strncmp(rstr.c_str(), "nigh", 4) == 0 )
+ if ( cmHasLiteralPrefix(rstr.c_str(), "nigh") )
{
return cmCTest::NIGHTLY;
}
@@ -1152,11 +1176,11 @@ int cmCTest::GetTestModelFromString(const char* str)
//######################################################################
//----------------------------------------------------------------------
-int cmCTest::RunMakeCommand(const char* command, std::string* output,
- int* retVal, const char* dir, int timeout, std::ofstream& ofs)
+int cmCTest::RunMakeCommand(const char* command, std::string& output,
+ int* retVal, const char* dir, int timeout, std::ostream& ofs)
{
// First generate the command and arguments
- std::vector<cmStdString> args = cmSystemTools::ParseArguments(command);
+ std::vector<std::string> args = cmSystemTools::ParseArguments(command);
if(args.size() < 1)
{
@@ -1164,18 +1188,14 @@ int cmCTest::RunMakeCommand(const char* command, std::string* output,
}
std::vector<const char*> argv;
- for(std::vector<cmStdString>::const_iterator a = args.begin();
+ for(std::vector<std::string>::const_iterator a = args.begin();
a != args.end(); ++a)
{
argv.push_back(a->c_str());
}
argv.push_back(0);
- if ( output )
- {
- *output = "";
- }
-
+ output = "";
cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, "Run command:");
std::vector<const char*>::iterator ait;
for ( ait = argv.begin(); ait != argv.end() && *ait; ++ ait )
@@ -1199,32 +1219,30 @@ int cmCTest::RunMakeCommand(const char* command, std::string* output,
char* data;
int length;
- cmCTestLog(this, HANDLER_OUTPUT,
+ cmCTestLog(this, HANDLER_PROGRESS_OUTPUT,
" Each . represents " << tick_len << " bytes of output" << std::endl
<< " " << std::flush);
while(cmsysProcess_WaitForData(cp, &data, &length, 0))
{
- if ( output )
+ for(int cc =0; cc < length; ++cc)
{
- for(int cc =0; cc < length; ++cc)
+ if(data[cc] == 0)
{
- if(data[cc] == 0)
- {
- data[cc] = '\n';
- }
+ data[cc] = '\n';
}
-
- output->append(data, length);
- while ( output->size() > (tick * tick_len) )
+ }
+ output.append(data, length);
+ while ( output.size() > (tick * tick_len) )
+ {
+ tick ++;
+ cmCTestLog(this, HANDLER_PROGRESS_OUTPUT, "." << std::flush);
+ if ( tick % tick_line_len == 0 && tick > 0 )
{
- tick ++;
- cmCTestLog(this, HANDLER_OUTPUT, "." << std::flush);
- if ( tick % tick_line_len == 0 && tick > 0 )
- {
- cmCTestLog(this, HANDLER_OUTPUT, " Size: "
- << int((double(output->size()) / 1024.0) + 1) << "K" << std::endl
- << " " << std::flush);
- }
+ cmCTestLog(this, HANDLER_PROGRESS_OUTPUT,
+ " Size: "
+ << int((double(output.size()) / 1024.0) + 1)
+ << "K" << std::endl
+ << " " << std::flush);
}
}
cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, cmCTestLogWrite(data, length));
@@ -1233,8 +1251,8 @@ int cmCTest::RunMakeCommand(const char* command, std::string* output,
ofs << cmCTestLogWrite(data, length);
}
}
- cmCTestLog(this, OUTPUT, " Size of output: "
- << int(double(output->size()) / 1024.0) << "K" << std::endl);
+ cmCTestLog(this, HANDLER_PROGRESS_OUTPUT, " Size of output: "
+ << int(double(output.size()) / 1024.0) << "K" << std::endl);
cmsysProcess_WaitForExit(cp, 0);
@@ -1258,9 +1276,9 @@ int cmCTest::RunMakeCommand(const char* command, std::string* output,
}
else if(result == cmsysProcess_State_Error)
{
- *output += "\n*** ERROR executing: ";
- *output += cmsysProcess_GetErrorString(cp);
- *output += "\n***The build process failed.";
+ output += "\n*** ERROR executing: ";
+ output += cmsysProcess_GetErrorString(cp);
+ output += "\n***The build process failed.";
cmCTestLog(this, ERROR_MESSAGE, "There was an error: "
<< cmsysProcess_GetErrorString(cp) << std::endl);
}
@@ -1281,7 +1299,7 @@ int cmCTest::RunTest(std::vector<const char*> argv,
std::ostream* log, double testTimeOut,
std::vector<std::string>* environment)
{
- bool modifyEnv = (environment && environment->size()>0);
+ bool modifyEnv = (environment && !environment->empty());
// determine how much time we have
double timeout = this->GetRemainingTimeAllowed() - 120;
@@ -1302,7 +1320,8 @@ int cmCTest::RunTest(std::vector<const char*> argv,
}
cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
"Test timeout computed to be: " << timeout << "\n");
- if(cmSystemTools::SameFile(argv[0], this->CTestSelf.c_str()) &&
+ if(cmSystemTools::SameFile(
+ argv[0], cmSystemTools::GetCTestCommand()) &&
!this->ForceNewCTestProcess)
{
cmCTest inst;
@@ -1310,7 +1329,7 @@ int cmCTest::RunTest(std::vector<const char*> argv,
inst.TimeOut = timeout;
// Capture output of the child ctest.
- cmOStringStream oss;
+ std::ostringstream oss;
inst.SetStreams(&oss, &oss);
std::vector<std::string> args;
@@ -1324,7 +1343,7 @@ int cmCTest::RunTest(std::vector<const char*> argv,
if (strcmp(argv[i],"--build-generator") == 0 && timeout > 0)
{
args.push_back("--test-timeout");
- cmOStringStream msg;
+ std::ostringstream msg;
msg << timeout;
args.push_back(msg.str());
}
@@ -1345,16 +1364,21 @@ int cmCTest::RunTest(std::vector<const char*> argv,
}
*retVal = inst.Run(args, output);
- *output += oss.str();
- if ( log )
+ if(output)
{
- *log << output->c_str();
+ *output += oss.str();
+ }
+ if ( log && output)
+ {
+ *log << *output;
+ }
+ cmSystemTools::ChangeDirectory(oldpath);
+ if(output)
+ {
+ cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
+ "Internal cmCTest object used to run test." << std::endl
+ << *output << std::endl);
}
- cmSystemTools::ChangeDirectory(oldpath.c_str());
-
- cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
- "Internal cmCTest object used to run test." << std::endl
- << *output << std::endl);
return cmsysProcess_State_Exited;
}
@@ -1424,7 +1448,10 @@ int cmCTest::RunTest(std::vector<const char*> argv,
*retVal = cmsysProcess_GetExitException(cp);
std::string outerr = "\n*** Exception executing: ";
outerr += cmsysProcess_GetExceptionString(cp);
- *output += outerr;
+ if(output)
+ {
+ *output += outerr;
+ }
cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, outerr.c_str() << std::endl
<< std::flush);
}
@@ -1432,7 +1459,10 @@ int cmCTest::RunTest(std::vector<const char*> argv,
{
std::string outerr = "\n*** ERROR executing: ";
outerr += cmsysProcess_GetErrorString(cp);
- *output += outerr;
+ if(output)
+ {
+ *output += outerr;
+ }
cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, outerr.c_str() << std::endl
<< std::flush);
}
@@ -1451,7 +1481,7 @@ std::string cmCTest::SafeBuildIdField(const std::string& value)
// Disallow non-filename and non-space whitespace characters.
// If they occur, replace them with ""
//
- const char *disallowed = "\\/:*?\"<>|\n\r\t\f\v";
+ const char *disallowed = "\\:*?\"<>|\n\r\t\f\v";
if (safevalue.find_first_of(disallowed) != value.npos)
{
@@ -1466,8 +1496,6 @@ std::string cmCTest::SafeBuildIdField(const std::string& value)
cmSystemTools::ReplaceString(safevalue, replace, "");
}
}
-
- safevalue = cmXMLSafe(safevalue).str();
}
if (safevalue == "")
@@ -1479,7 +1507,7 @@ std::string cmCTest::SafeBuildIdField(const std::string& value)
}
//----------------------------------------------------------------------
-void cmCTest::StartXML(std::ostream& ostr, bool append)
+void cmCTest::StartXML(cmXMLWriter& xml, bool append)
{
if(this->CurrentTag.empty())
{
@@ -1502,42 +1530,51 @@ void cmCTest::StartXML(std::ostream& ostr, bool append)
std::string site = cmCTest::SafeBuildIdField(
this->GetCTestConfiguration("Site"));
- ostr << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- << "<Site BuildName=\"" << buildname << "\"\n"
- << "\tBuildStamp=\"" << stamp << "\"\n"
- << "\tName=\"" << site << "\"\n"
- << "\tGenerator=\"ctest-" << cmVersion::GetCMakeVersion() << "\"\n"
- << (append? "\tAppend=\"true\"\n":"")
- << "\tCompilerName=\"" << this->GetCTestConfiguration("Compiler")
- << "\"\n"
-#ifdef _COMPILER_VERSION
- << "\tCompilerVersion=\"_COMPILER_VERSION\"\n"
-#endif
- << "\tOSName=\"" << info.GetOSName() << "\"\n"
- << "\tHostname=\"" << info.GetHostname() << "\"\n"
- << "\tOSRelease=\"" << info.GetOSRelease() << "\"\n"
- << "\tOSVersion=\"" << info.GetOSVersion() << "\"\n"
- << "\tOSPlatform=\"" << info.GetOSPlatform() << "\"\n"
- << "\tIs64Bits=\"" << info.Is64Bits() << "\"\n"
- << "\tVendorString=\"" << info.GetVendorString() << "\"\n"
- << "\tVendorID=\"" << info.GetVendorID() << "\"\n"
- << "\tFamilyID=\"" << info.GetFamilyID() << "\"\n"
- << "\tModelID=\"" << info.GetModelID() << "\"\n"
- << "\tProcessorCacheSize=\"" << info.GetProcessorCacheSize() << "\"\n"
- << "\tNumberOfLogicalCPU=\"" << info.GetNumberOfLogicalCPU() << "\"\n"
- << "\tNumberOfPhysicalCPU=\""<< info.GetNumberOfPhysicalCPU() << "\"\n"
- << "\tTotalVirtualMemory=\"" << info.GetTotalVirtualMemory() << "\"\n"
- << "\tTotalPhysicalMemory=\""<< info.GetTotalPhysicalMemory() << "\"\n"
- << "\tLogicalProcessorsPerPhysical=\""
- << info.GetLogicalProcessorsPerPhysical() << "\"\n"
- << "\tProcessorClockFrequency=\""
- << info.GetProcessorClockFrequency() << "\"\n"
- << ">" << std::endl;
- this->AddSiteProperties(ostr);
-}
-
-//----------------------------------------------------------------------
-void cmCTest::AddSiteProperties(std::ostream& ostr)
+ xml.StartDocument();
+ xml.StartElement("Site");
+ xml.Attribute("BuildName", buildname);
+ xml.BreakAttributes();
+ xml.Attribute("BuildStamp", stamp);
+ xml.Attribute("Name", site);
+ xml.Attribute("Generator",
+ std::string("ctest-") + cmVersion::GetCMakeVersion());
+ if(append)
+ {
+ xml.Attribute("Append", "true");
+ }
+ xml.Attribute("CompilerName", this->GetCTestConfiguration("Compiler"));
+ xml.Attribute("CompilerVersion",
+ this->GetCTestConfiguration("CompilerVersion"));
+ xml.Attribute("OSName", info.GetOSName());
+ xml.Attribute("Hostname", info.GetHostname());
+ xml.Attribute("OSRelease", info.GetOSRelease());
+ xml.Attribute("OSVersion", info.GetOSVersion());
+ xml.Attribute("OSPlatform", info.GetOSPlatform());
+ xml.Attribute("Is64Bits", info.Is64Bits());
+ xml.Attribute("VendorString", info.GetVendorString());
+ xml.Attribute("VendorID", info.GetVendorID());
+ xml.Attribute("FamilyID", info.GetFamilyID());
+ xml.Attribute("ModelID", info.GetModelID());
+ xml.Attribute("ProcessorCacheSize", info.GetProcessorCacheSize());
+ xml.Attribute("NumberOfLogicalCPU", info.GetNumberOfLogicalCPU());
+ xml.Attribute("NumberOfPhysicalCPU", info.GetNumberOfPhysicalCPU());
+ xml.Attribute("TotalVirtualMemory", info.GetTotalVirtualMemory());
+ xml.Attribute("TotalPhysicalMemory", info.GetTotalPhysicalMemory());
+ xml.Attribute("LogicalProcessorsPerPhysical",
+ info.GetLogicalProcessorsPerPhysical());
+ xml.Attribute("ProcessorClockFrequency", info.GetProcessorClockFrequency());
+
+ std::string changeId = this->GetCTestConfiguration("ChangeId");
+ if(!changeId.empty())
+ {
+ xml.Attribute("ChangeId", changeId);
+ }
+
+ this->AddSiteProperties(xml);
+}
+
+//----------------------------------------------------------------------
+void cmCTest::AddSiteProperties(cmXMLWriter& xml)
{
cmCTestScriptHandler* ch =
static_cast<cmCTestScriptHandler*>(this->GetHandler("script"));
@@ -1549,97 +1586,104 @@ void cmCTest::AddSiteProperties(std::ostream& ostr)
return;
}
// This code should go when cdash is changed to use labels only
- const char* subproject = cm->GetProperty("SubProject", cmProperty::GLOBAL);
+ const char* subproject = cm->GetState()
+ ->GetGlobalProperty("SubProject");
if(subproject)
{
- ostr << "<Subproject name=\"" << subproject << "\">\n";
+ xml.StartElement("Subproject");
+ xml.Attribute("name", subproject);
const char* labels =
- ch->GetCMake()->GetProperty("SubProjectLabels", cmProperty::GLOBAL);
+ ch->GetCMake()->GetState()
+ ->GetGlobalProperty("SubProjectLabels");
if(labels)
{
- ostr << " <Labels>\n";
+ xml.StartElement("Labels");
std::string l = labels;
std::vector<std::string> args;
cmSystemTools::ExpandListArgument(l, args);
for(std::vector<std::string>::iterator i = args.begin();
i != args.end(); ++i)
{
- ostr << " <Label>" << i->c_str() << "</Label>\n";
+ xml.Element("Label", *i);
}
- ostr << " </Labels>\n";
+ xml.EndElement();
}
- ostr << "</Subproject>\n";
+ xml.EndElement();
}
// This code should stay when cdash only does label based sub-projects
- const char* label = cm->GetProperty("Label", cmProperty::GLOBAL);
+ const char* label = cm->GetState()->GetGlobalProperty("Label");
if(label)
{
- ostr << "<Labels>\n";
- ostr << " <Label>" << label << "</Label>\n";
- ostr << "</Labels>\n";
+ xml.StartElement("Labels");
+ xml.Element("Label", label);
+ xml.EndElement();
}
}
-
//----------------------------------------------------------------------
-void cmCTest::EndXML(std::ostream& ostr)
+void cmCTest::EndXML(cmXMLWriter& xml)
{
- ostr << "</Site>" << std::endl;
+ xml.EndElement(); // Site
+ xml.EndDocument();
}
//----------------------------------------------------------------------
-int cmCTest::GenerateCTestNotesOutput(std::ostream& os,
+int cmCTest::GenerateCTestNotesOutput(cmXMLWriter& xml,
const cmCTest::VectorOfStrings& files)
{
+ std::string buildname = cmCTest::SafeBuildIdField(
+ this->GetCTestConfiguration("BuildName"));
cmCTest::VectorOfStrings::const_iterator it;
- os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- << "<?xml-stylesheet type=\"text/xsl\" "
+ xml.StartDocument();
+ xml.ProcessingInstruction("xml-stylesheet", "type=\"text/xsl\" "
"href=\"Dart/Source/Server/XSL/Build.xsl "
- "<file:///Dart/Source/Server/XSL/Build.xsl> \"?>\n"
- << "<Site BuildName=\"" << this->GetCTestConfiguration("BuildName")
- << "\" BuildStamp=\""
- << this->CurrentTag << "-" << this->GetTestModelString() << "\" Name=\""
- << this->GetCTestConfiguration("Site") << "\" Generator=\"ctest"
- << cmVersion::GetCMakeVersion()
- << "\">\n";
- this->AddSiteProperties(os);
- os << "<Notes>" << std::endl;
+ "<file:///Dart/Source/Server/XSL/Build.xsl> \"");
+ xml.StartElement("Site");
+ xml.Attribute("BuildName", buildname);
+ xml.Attribute("BuildStamp", this->CurrentTag+"-"+this->GetTestModelString());
+ xml.Attribute("Name", this->GetCTestConfiguration("Site"));
+ xml.Attribute("Generator",std::string("ctest")+cmVersion::GetCMakeVersion());
+ this->AddSiteProperties(xml);
+ xml.StartElement("Notes");
for ( it = files.begin(); it != files.end(); it ++ )
{
- cmCTestLog(this, OUTPUT, "\tAdd file: " << it->c_str() << std::endl);
+ cmCTestLog(this, OUTPUT, "\tAdd file: " << *it << std::endl);
std::string note_time = this->CurrentTime();
- os << "<Note Name=\"" << cmXMLSafe(*it) << "\">\n"
- << "<Time>" << cmSystemTools::GetTime() << "</Time>\n"
- << "<DateTime>" << note_time << "</DateTime>\n"
- << "<Text>" << std::endl;
- std::ifstream ifs(it->c_str());
+ xml.StartElement("Note");
+ xml.Attribute("Name", *it);
+ xml.Element("Time", cmSystemTools::GetTime());
+ xml.Element("DateTime", note_time);
+ xml.StartElement("Text");
+ cmsys::ifstream ifs(it->c_str());
if ( ifs )
{
std::string line;
while ( cmSystemTools::GetLineFromStream(ifs, line) )
{
- os << cmXMLSafe(line) << std::endl;
+ xml.Content(line);
+ xml.Content("\n");
}
ifs.close();
}
else
{
- os << "Problem reading file: " << it->c_str() << std::endl;
- cmCTestLog(this, ERROR_MESSAGE, "Problem reading file: " << it->c_str()
+ xml.Content("Problem reading file: " + *it + "\n");
+ cmCTestLog(this, ERROR_MESSAGE, "Problem reading file: " << *it
<< " while creating notes" << std::endl);
}
- os << "</Text>\n"
- << "</Note>" << std::endl;
+ xml.EndElement(); // Text
+ xml.EndElement(); // Note
}
- os << "</Notes>\n"
- << "</Site>" << std::endl;
+ xml.EndElement(); // Notes
+ xml.EndElement(); // Site
+ xml.EndDocument();
return 1;
}
//----------------------------------------------------------------------
-int cmCTest::GenerateNotesFile(const std::vector<cmStdString> &files)
+int cmCTest::GenerateNotesFile(const VectorOfStrings &files)
{
cmGeneratedFileStream ofs;
if ( !this->OpenOutputFile(this->CurrentTag, "Notes.xml", ofs) )
@@ -1647,8 +1691,8 @@ int cmCTest::GenerateNotesFile(const std::vector<cmStdString> &files)
cmCTestLog(this, ERROR_MESSAGE, "Cannot open notes file" << std::endl);
return 1;
}
-
- this->GenerateCTestNotesOutput(ofs, files);
+ cmXMLWriter xml(ofs);
+ this->GenerateCTestNotesOutput(xml, files);
return 0;
}
@@ -1660,12 +1704,12 @@ int cmCTest::GenerateNotesFile(const char* cfiles)
return 1;
}
- std::vector<cmStdString> files;
+ VectorOfStrings files;
cmCTestLog(this, OUTPUT, "Create notes file" << std::endl);
files = cmSystemTools::SplitString(cfiles, ';');
- if ( files.size() == 0 )
+ if (files.empty())
{
return 1;
}
@@ -1677,25 +1721,26 @@ int cmCTest::GenerateNotesFile(const char* cfiles)
std::string cmCTest::Base64GzipEncodeFile(std::string file)
{
std::string tarFile = file + "_temp.tar.gz";
- std::vector<cmStdString> files;
+ std::vector<std::string> files;
files.push_back(file);
- if(!cmSystemTools::CreateTar(tarFile.c_str(), files, true, false, false))
+ if(!cmSystemTools::CreateTar(tarFile.c_str(), files,
+ cmSystemTools::TarCompressGZip, false))
{
cmCTestLog(this, ERROR_MESSAGE, "Error creating tar while "
"encoding file: " << file << std::endl);
return "";
}
std::string base64 = this->Base64EncodeFile(tarFile);
- cmSystemTools::RemoveFile(tarFile.c_str());
+ cmSystemTools::RemoveFile(tarFile);
return base64;
}
//----------------------------------------------------------------------
std::string cmCTest::Base64EncodeFile(std::string file)
{
- long len = cmSystemTools::FileLength(file.c_str());
- std::ifstream ifs(file.c_str(), std::ios::in
+ size_t const len = cmSystemTools::FileLength(file);
+ cmsys::ifstream ifs(file.c_str(), std::ios::in
#ifdef _WIN32
| std::ios::binary
#endif
@@ -1705,14 +1750,13 @@ std::string cmCTest::Base64EncodeFile(std::string file)
ifs.close();
unsigned char *encoded_buffer
- = new unsigned char [ static_cast<int>(
- static_cast<double>(len) * 1.5 + 5.0) ];
+ = new unsigned char [ (len * 3) / 2 + 5 ];
- unsigned long rlen
+ size_t const rlen
= cmsysBase64_Encode(file_buffer, len, encoded_buffer, 1);
std::string base64 = "";
- for(unsigned long i = 0; i < rlen; i++)
+ for(size_t i = 0; i < rlen; i++)
{
base64 += encoded_buffer[i];
}
@@ -1724,9 +1768,9 @@ std::string cmCTest::Base64EncodeFile(std::string file)
//----------------------------------------------------------------------
-bool cmCTest::SubmitExtraFiles(const std::vector<cmStdString> &files)
+bool cmCTest::SubmitExtraFiles(const VectorOfStrings &files)
{
- std::vector<cmStdString>::const_iterator it;
+ VectorOfStrings::const_iterator it;
for ( it = files.begin();
it != files.end();
++ it )
@@ -1734,7 +1778,7 @@ bool cmCTest::SubmitExtraFiles(const std::vector<cmStdString> &files)
if ( !cmSystemTools::FileExists(it->c_str()) )
{
cmCTestLog(this, ERROR_MESSAGE, "Cannot find extra file: "
- << it->c_str() << " to submit."
+ << *it << " to submit."
<< std::endl;);
return false;
}
@@ -1751,12 +1795,12 @@ bool cmCTest::SubmitExtraFiles(const char* cfiles)
return 1;
}
- std::vector<cmStdString> files;
+ VectorOfStrings files;
cmCTestLog(this, OUTPUT, "Submit extra files" << std::endl);
files = cmSystemTools::SplitString(cfiles, ';');
- if ( files.size() == 0 )
+ if (files.empty())
{
return 1;
}
@@ -1986,11 +2030,11 @@ bool cmCTest::CheckArgument(const std::string& arg, const char* varg1,
//----------------------------------------------------------------------
// Processes one command line argument (and its arguments if any)
// for many simple options and then returns
-void cmCTest::HandleCommandLineArguments(size_t &i,
- std::vector<std::string> &args)
+bool cmCTest::HandleCommandLineArguments(size_t &i,
+ std::vector<std::string> &args,
+ std::string& errormsg)
{
std::string arg = args[i];
-
if(this->CheckArgument(arg, "-F"))
{
this->Failover = true;
@@ -2008,6 +2052,42 @@ void cmCTest::HandleCommandLineArguments(size_t &i,
this->SetParallelLevel(plevel);
this->ParallelLevelSetInCli = true;
}
+ if(this->CheckArgument(arg, "--repeat-until-fail"))
+ {
+ if( i >= args.size() - 1)
+ {
+ errormsg = "'--repeat-until-fail' requires an argument";
+ return false;
+ }
+ i++;
+ long repeat = 1;
+ if(!cmSystemTools::StringToLong(args[i].c_str(), &repeat))
+ {
+ errormsg = "'--repeat-until-fail' given non-integer value '"
+ + args[i] + "'";
+ return false;
+ }
+ this->RepeatTests = static_cast<int>(repeat);
+ if(repeat > 1)
+ {
+ this->RepeatUntilFail = true;
+ }
+ }
+
+ if(this->CheckArgument(arg, "--test-load") && i < args.size() - 1)
+ {
+ i++;
+ unsigned long load;
+ if (cmSystemTools::StringToULong(args[i].c_str(), &load))
+ {
+ this->SetTestLoad(load);
+ }
+ else
+ {
+ cmCTestLog(this, WARNING,
+ "Invalid value for 'Test Load' : " << args[i] << std::endl);
+ }
+ }
if(this->CheckArgument(arg, "--no-compress-output"))
{
@@ -2084,7 +2164,46 @@ void cmCTest::HandleCommandLineArguments(size_t &i,
{
this->OutputTestOutputOnTestFailure = true;
}
-
+ if (this->CheckArgument(arg, "--test-output-size-passed") &&
+ i < args.size() - 1)
+ {
+ i++;
+ long outputSize;
+ if (cmSystemTools::StringToLong(args[i].c_str(), &outputSize))
+ {
+ if (cmCTestTestHandler *pCTestTestHandler =
+ static_cast<cmCTestTestHandler*>(this->TestingHandlers["test"]))
+ {
+ pCTestTestHandler->SetTestOutputSizePassed(int(outputSize));
+ }
+ }
+ else
+ {
+ cmCTestLog(this, WARNING,
+ "Invalid value for '--test-output-size-passed': " <<
+ args[i] << "\n");
+ }
+ }
+ if (this->CheckArgument(arg, "--test-output-size-failed") &&
+ i < args.size() - 1)
+ {
+ i++;
+ long outputSize;
+ if (cmSystemTools::StringToLong(args[i].c_str(), &outputSize))
+ {
+ if (cmCTestTestHandler *pCTestTestHandler =
+ static_cast<cmCTestTestHandler*>(this->TestingHandlers["test"]))
+ {
+ pCTestTestHandler->SetTestOutputSizeFailed(int(outputSize));
+ }
+ }
+ else
+ {
+ cmCTestLog(this, WARNING,
+ "Invalid value for '--test-output-size-failed': " <<
+ args[i] << "\n");
+ }
+ }
if(this->CheckArgument(arg, "-N", "--show-only"))
{
this->ShowOnly = true;
@@ -2128,7 +2247,7 @@ void cmCTest::HandleCommandLineArguments(size_t &i,
if(this->CheckArgument(arg, "--overwrite") && i < args.size() - 1)
{
i++;
- this->AddCTestConfigurationOverwrite(args[i].c_str());
+ this->AddCTestConfigurationOverwrite(args[i]);
}
if(this->CheckArgument(arg, "-A", "--add-notes") && i < args.size() - 1)
{
@@ -2187,6 +2306,13 @@ void cmCTest::HandleCommandLineArguments(size_t &i,
this->GetHandler("memcheck")->
SetPersistentOption("ExcludeRegularExpression", args[i].c_str());
}
+
+ if(this->CheckArgument(arg, "--rerun-failed"))
+ {
+ this->GetHandler("test")->SetPersistentOption("RerunFailed", "true");
+ this->GetHandler("memcheck")->SetPersistentOption("RerunFailed", "true");
+ }
+ return true;
}
//----------------------------------------------------------------------
@@ -2240,9 +2366,9 @@ bool cmCTest::AddVariableDefinition(const std::string &arg)
{
std::string name;
std::string value;
- cmCacheManager::CacheEntryType type = cmCacheManager::UNINITIALIZED;
+ cmState::CacheEntryType type = cmState::UNINITIALIZED;
- if (cmCacheManager::ParseEntry(arg.c_str(), name, value, type))
+ if (cmake::ParseCacheEntry(arg, name, value, type))
{
this->Definitions[name] = value;
return true;
@@ -2255,23 +2381,26 @@ bool cmCTest::AddVariableDefinition(const std::string &arg)
// the main entry point of ctest, called from main
int cmCTest::Run(std::vector<std::string> &args, std::string* output)
{
- this->FindRunningCMake();
const char* ctestExec = "ctest";
bool cmakeAndTest = false;
bool executeTests = true;
bool SRArgumentSpecified = false;
// copy the command line
- for(size_t i=0; i < args.size(); ++i)
- {
- this->InitialCommandLineArguments.push_back(args[i]);
- }
+ this->InitialCommandLineArguments.insert(
+ this->InitialCommandLineArguments.end(),
+ args.begin(), args.end());
// process the command line arguments
for(size_t i=1; i < args.size(); ++i)
{
// handle the simple commandline arguments
- this->HandleCommandLineArguments(i,args);
+ std::string errormsg;
+ if(!this->HandleCommandLineArguments(i,args, errormsg))
+ {
+ cmSystemTools::Error(errormsg.c_str());
+ return 1;
+ }
// handle the script arguments -S -SR -SP
this->HandleScriptArguments(i,args,SRArgumentSpecified);
@@ -2316,7 +2445,7 @@ int cmCTest::Run(std::vector<std::string> &args, std::string* output)
executeTests = false;
cmCTestLog(this, ERROR_MESSAGE,
"CTest -T called with incorrect option: "
- << args[i].c_str() << std::endl);
+ << args[i] << std::endl);
cmCTestLog(this, ERROR_MESSAGE, "Available options are:" << std::endl
<< " " << ctestExec << " -T all" << std::endl
<< " " << ctestExec << " -T start" << std::endl
@@ -2353,7 +2482,7 @@ int cmCTest::Run(std::vector<std::string> &args, std::string* output)
{
executeTests = false;
cmCTestLog(this, ERROR_MESSAGE,
- "CTest -M called with incorrect option: " << str.c_str()
+ "CTest -M called with incorrect option: " << str
<< std::endl);
cmCTestLog(this, ERROR_MESSAGE, "Available options are:" << std::endl
<< " " << ctestExec << " -M Continuous" << std::endl
@@ -2496,29 +2625,6 @@ int cmCTest::Run(std::vector<std::string> &args, std::string* output)
}
//----------------------------------------------------------------------
-void cmCTest::FindRunningCMake()
-{
- // Find our own executable.
- this->CTestSelf = cmSystemTools::GetExecutableDirectory();
- this->CTestSelf += "/ctest";
- this->CTestSelf += cmSystemTools::GetExecutableExtension();
- if(!cmSystemTools::FileExists(this->CTestSelf.c_str()))
- {
- cmSystemTools::Error("CTest executable cannot be found at ",
- this->CTestSelf.c_str());
- }
-
- this->CMakeSelf = cmSystemTools::GetExecutableDirectory();
- this->CMakeSelf += "/cmake";
- this->CMakeSelf += cmSystemTools::GetExecutableExtension();
- if(!cmSystemTools::FileExists(this->CMakeSelf.c_str()))
- {
- cmSystemTools::Error("CMake executable cannot be found at ",
- this->CMakeSelf.c_str());
- }
-}
-
-//----------------------------------------------------------------------
void cmCTest::SetNotesFiles(const char* notes)
{
if ( !notes )
@@ -2547,20 +2653,20 @@ int cmCTest::ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf)
std::string fname = dir;
fname += "/CTestCustom.cmake";
cmCTestLog(this, DEBUG, "* Check for file: "
- << fname.c_str() << std::endl);
+ << fname << std::endl);
if ( cmSystemTools::FileExists(fname.c_str()) )
{
cmCTestLog(this, DEBUG, "* Read custom CTest configuration file: "
- << fname.c_str() << std::endl);
+ << fname << std::endl);
bool erroroc = cmSystemTools::GetErrorOccuredFlag();
cmSystemTools::ResetErrorOccuredFlag();
- if ( !mf->ReadListFile(0, fname.c_str()) ||
+ if ( !mf->ReadListFile(fname.c_str()) ||
cmSystemTools::GetErrorOccuredFlag() )
{
cmCTestLog(this, ERROR_MESSAGE,
"Problem reading custom configuration: "
- << fname.c_str() << std::endl);
+ << fname << std::endl);
}
found = true;
if ( erroroc )
@@ -2572,7 +2678,7 @@ int cmCTest::ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf)
std::string rexpr = dir;
rexpr += "/CTestCustom.ctest";
cmCTestLog(this, DEBUG, "* Check for file: "
- << rexpr.c_str() << std::endl);
+ << rexpr << std::endl);
if ( !found && cmSystemTools::FileExists(rexpr.c_str()) )
{
cmsys::Glob gl;
@@ -2584,13 +2690,13 @@ int cmCTest::ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf)
++ fileIt )
{
cmCTestLog(this, DEBUG, "* Read custom CTest configuration file: "
- << fileIt->c_str() << std::endl);
- if ( !mf->ReadListFile(0, fileIt->c_str()) ||
+ << *fileIt << std::endl);
+ if ( !mf->ReadListFile(fileIt->c_str()) ||
cmSystemTools::GetErrorOccuredFlag() )
{
cmCTestLog(this, ERROR_MESSAGE,
"Problem reading custom configuration: "
- << fileIt->c_str() << std::endl);
+ << *fileIt << std::endl);
}
}
found = true;
@@ -2604,7 +2710,7 @@ int cmCTest::ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf)
{
cmCTestLog(this, DEBUG,
"* Read custom CTest configuration vectors for handler: "
- << it->first.c_str() << " (" << it->second << ")" << std::endl);
+ << it->first << " (" << it->second << ")" << std::endl);
it->second->PopulateCustomVectors(mf);
}
}
@@ -2613,39 +2719,30 @@ int cmCTest::ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf)
}
//----------------------------------------------------------------------
-void cmCTest::PopulateCustomVector(cmMakefile* mf, const char* def,
- VectorOfStrings& vec)
+void cmCTest::PopulateCustomVector(cmMakefile* mf, const std::string& def,
+ std::vector<std::string>& vec)
{
- if ( !def)
- {
- return;
- }
const char* dval = mf->GetDefinition(def);
if ( !dval )
{
return;
}
cmCTestLog(this, DEBUG, "PopulateCustomVector: " << def << std::endl);
- std::vector<std::string> slist;
- cmSystemTools::ExpandListArgument(dval, slist);
- std::vector<std::string>::iterator it;
vec.clear();
+ cmSystemTools::ExpandListArgument(dval, vec);
- for ( it = slist.begin(); it != slist.end(); ++it )
+ for (std::vector<std::string>::const_iterator it = vec.begin();
+ it != vec.end(); ++it )
{
- cmCTestLog(this, DEBUG, " -- " << it->c_str() << std::endl);
- vec.push_back(it->c_str());
+ cmCTestLog(this, DEBUG, " -- " << *it << std::endl);
}
}
//----------------------------------------------------------------------
-void cmCTest::PopulateCustomInteger(cmMakefile* mf, const char* def, int& val)
+void cmCTest::PopulateCustomInteger(cmMakefile* mf, const std::string& def,
+ int& val)
{
- if ( !def)
- {
- return;
- }
const char* dval = mf->GetDefinition(def);
if ( !dval )
{
@@ -2659,10 +2756,10 @@ std::string cmCTest::GetShortPathToFile(const char* cfname)
{
const std::string& sourceDir
= cmSystemTools::CollapseFullPath(
- this->GetCTestConfiguration("SourceDirectory").c_str());
+ this->GetCTestConfiguration("SourceDirectory"));
const std::string& buildDir
= cmSystemTools::CollapseFullPath(
- this->GetCTestConfiguration("BuildDirectory").c_str());
+ this->GetCTestConfiguration("BuildDirectory"));
std::string fname = cmSystemTools::CollapseFullPath(cfname);
// Find relative paths to both directories
@@ -2722,7 +2819,7 @@ std::string cmCTest::GetShortPathToFile(const char* cfname)
}
//----------------------------------------------------------------------
-std::string cmCTest::GetCTestConfiguration(const char *name)
+std::string cmCTest::GetCTestConfiguration(const std::string& name)
{
if ( this->CTestConfigurationOverwrites.find(name) !=
this->CTestConfigurationOverwrites.end() )
@@ -2779,10 +2876,11 @@ void cmCTest::DetermineNextDayStop()
}
//----------------------------------------------------------------------
-void cmCTest::SetCTestConfiguration(const char *name, const char* value)
+void cmCTest::SetCTestConfiguration(const char *name, const char* value,
+ bool suppress)
{
- cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, "SetCTestConfiguration:"
- << name << ":" << (value ? value : "(null)") << "\n");
+ cmCTestOptionalLog(this, HANDLER_VERBOSE_OUTPUT, "SetCTestConfiguration:"
+ << name << ":" << (value ? value : "(null)") << "\n", suppress);
if ( !name )
{
@@ -2867,9 +2965,8 @@ void cmCTest::AddSubmitFile(Part part, const char* name)
}
//----------------------------------------------------------------------
-void cmCTest::AddCTestConfigurationOverwrite(const char* encstr)
+void cmCTest::AddCTestConfigurationOverwrite(const std::string& overStr)
{
- std::string overStr = encstr;
size_t epos = overStr.find("=");
if ( epos == overStr.npos )
{
@@ -2877,7 +2974,7 @@ void cmCTest::AddCTestConfigurationOverwrite(const char* encstr)
"CTest configuration overwrite specified in the wrong format."
<< std::endl
<< "Valid format is: --overwrite key=value" << std::endl
- << "The specified was: --overwrite " << overStr.c_str() << std::endl);
+ << "The specified was: --overwrite " << overStr << std::endl);
return;
}
std::string key = overStr.substr(0, epos);
@@ -2892,12 +2989,12 @@ void cmCTest::SetConfigType(const char* ct)
cmSystemTools::ReplaceString(this->ConfigType, ".\\", "");
std::string confTypeEnv
= "CMAKE_CONFIG_TYPE=" + this->ConfigType;
- cmSystemTools::PutEnv(confTypeEnv.c_str());
+ cmSystemTools::PutEnv(confTypeEnv);
}
//----------------------------------------------------------------------
bool cmCTest::SetCTestConfigurationFromCMakeVariable(cmMakefile* mf,
- const char* dconfig, const char* cmake_var)
+ const char* dconfig, const std::string& cmake_var, bool suppress)
{
const char* ctvar;
ctvar = mf->GetDefinition(cmake_var);
@@ -2905,10 +3002,10 @@ bool cmCTest::SetCTestConfigurationFromCMakeVariable(cmMakefile* mf,
{
return false;
}
- cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
- "SetCTestConfigurationFromCMakeVariable:"
- << dconfig << ":" << cmake_var << std::endl);
- this->SetCTestConfiguration(dconfig, ctvar);
+ cmCTestOptionalLog(this, HANDLER_VERBOSE_OUTPUT,
+ "SetCTestConfigurationFromCMakeVariable:" << dconfig << ":" <<
+ cmake_var << std::endl, suppress);
+ this->SetCTestConfiguration(dconfig, ctvar, suppress);
return true;
}
@@ -2920,7 +3017,7 @@ bool cmCTest::RunCommand(
const char* dir,
double timeout)
{
- std::vector<cmStdString> args = cmSystemTools::ParseArguments(command);
+ std::vector<std::string> args = cmSystemTools::ParseArguments(command);
if(args.size() < 1)
{
@@ -2928,7 +3025,7 @@ bool cmCTest::RunCommand(
}
std::vector<const char*> argv;
- for(std::vector<cmStdString>::const_iterator a = args.begin();
+ for(std::vector<std::string>::const_iterator a = args.begin();
a != args.end(); ++a)
{
argv.push_back(a->c_str());
@@ -2976,11 +3073,11 @@ bool cmCTest::RunCommand(
}
cmsysProcess_WaitForExit(cp, 0);
- if ( tempOutput.size() > 0 )
+ if (!tempOutput.empty())
{
stdOut->append(&*tempOutput.begin(), tempOutput.size());
}
- if ( tempError.size() > 0 )
+ if (!tempError.empty())
{
stdErr->append(&*tempError.begin(), tempError.size());
}
@@ -3046,6 +3143,7 @@ static const char* cmCTestStringLogType[] =
"DEBUG",
"OUTPUT",
"HANDLER_OUTPUT",
+ "HANDLER_PROGRESS_OUTPUT",
"HANDLER_VERBOSE_OUTPUT",
"WARNING",
"ERROR_MESSAGE",
@@ -3073,12 +3171,22 @@ void cmCTest::InitStreams()
this->StreamErr = &std::cerr;
}
-void cmCTest::Log(int logType, const char* file, int line, const char* msg)
+void cmCTest::Log(int logType, const char* file, int line, const char* msg,
+ bool suppress)
{
if ( !msg || !*msg )
{
return;
}
+ if ( suppress && logType != cmCTest::ERROR_MESSAGE )
+ {
+ return;
+ }
+ if ( logType == cmCTest::HANDLER_PROGRESS_OUTPUT &&
+ ( this->Debug || this->ExtraVerbose ) )
+ {
+ return;
+ }
if ( this->OutputLogFile )
{
bool display = true;
@@ -3176,7 +3284,7 @@ double cmCTest::GetRemainingTimeAllowed()
void cmCTest::OutputTestErrors(std::vector<char> const &process_output)
{
std::string test_outputs("\n*** Test Failed:\n");
- if(process_output.size())
+ if(!process_output.empty())
{
test_outputs.append(&*process_output.begin(), process_output.size());
}
@@ -3224,9 +3332,9 @@ bool cmCTest::CompressString(std::string& str)
// Now base64 encode the resulting binary string
unsigned char* base64EncodedBuffer
- = new unsigned char[static_cast<int>(outSize * 1.5)];
+ = new unsigned char[(outSize * 3) / 2];
- unsigned long rlen
+ size_t rlen
= cmsysBase64_Encode(out, strm.total_out, base64EncodedBuffer, 1);
str = "";
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index 5dd35ce41..73c280752 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -24,15 +24,24 @@ class cmGeneratedFileStream;
class cmCTestCommand;
class cmCTestScriptHandler;
class cmCTestStartCommand;
+class cmXMLWriter;
#define cmCTestLog(ctSelf, logType, msg) \
do { \
- cmOStringStream cmCTestLog_msg; \
+ std::ostringstream cmCTestLog_msg; \
cmCTestLog_msg << msg; \
(ctSelf)->Log(cmCTest::logType, __FILE__, __LINE__,\
cmCTestLog_msg.str().c_str());\
} while ( 0 )
+#define cmCTestOptionalLog(ctSelf, logType, msg, suppress) \
+ do { \
+ std::ostringstream cmCTestLog_msg; \
+ cmCTestLog_msg << msg; \
+ (ctSelf)->Log(cmCTest::logType, __FILE__, __LINE__,\
+ cmCTestLog_msg.str().c_str(), suppress);\
+ } while ( 0 )
+
#ifdef cerr
# undef cerr
#endif
@@ -70,8 +79,8 @@ public:
{
PartInfo(): Enabled(false) {}
- void SetName(const char* name) { this->Name = name; }
- const char* GetName() const { return this->Name.c_str(); }
+ void SetName(const std::string& name) { this->Name = name; }
+ const std::string& GetName() const { return this->Name; }
void Enable() { this->Enabled = true; }
operator bool() const { return this->Enabled; }
@@ -101,8 +110,8 @@ public:
if the string does not name a valid part. */
Part GetPartFromName(const char* name);
- typedef std::vector<cmStdString> VectorOfStrings;
- typedef std::set<cmStdString> SetOfStrings;
+ typedef std::vector<cmsys::String> VectorOfStrings;
+ typedef std::set<std::string> SetOfStrings;
///! Process Command line arguments
int Run(std::vector<std::string> &, std::string* output = 0);
@@ -134,7 +143,7 @@ public:
/*
* Is the tomorrow tag set?
*/
- bool GetTomorrowTag() { return this->TomorrowTag; };
+ bool GetTomorrowTag() { return this->TomorrowTag; }
/**
* Try to run tests of the project
@@ -152,6 +161,9 @@ public:
int GetParallelLevel() { return this->ParallelLevel; }
void SetParallelLevel(int);
+ unsigned long GetTestLoad() { return this->TestLoad; }
+ void SetTestLoad(unsigned long);
+
/**
* Check if CTest file exists
*/
@@ -167,13 +179,14 @@ public:
* Set the cmake test mode (experimental, nightly, continuous).
*/
void SetTestModel(int mode);
- int GetTestModel() { return this->TestModel; };
+ int GetTestModel() { return this->TestModel; }
std::string GetTestModelString();
static int GetTestModelFromString(const char* str);
static std::string CleanString(const std::string& str);
- std::string GetCTestConfiguration(const char *name);
- void SetCTestConfiguration(const char *name, const char* value);
+ std::string GetCTestConfiguration(const std::string& name);
+ void SetCTestConfiguration(const char *name, const char* value,
+ bool suppress=false);
void EmptyCTestConfiguration();
/**
@@ -185,9 +198,9 @@ public:
//! Set the notes files to be created.
void SetNotesFiles(const char* notes);
- void PopulateCustomVector(cmMakefile* mf, const char* definition,
- VectorOfStrings& vec);
- void PopulateCustomInteger(cmMakefile* mf, const char* def,
+ void PopulateCustomVector(cmMakefile* mf, const std::string& definition,
+ std::vector<std::string>& vec);
+ void PopulateCustomInteger(cmMakefile* mf, const std::string& def,
int& val);
///! Get the current time as string
@@ -264,16 +277,16 @@ public:
static std::string SafeBuildIdField(const std::string& value);
//! Start CTest XML output file
- void StartXML(std::ostream& ostr, bool append);
+ void StartXML(cmXMLWriter& xml, bool append);
//! End CTest XML output file
- void EndXML(std::ostream& ostr);
+ void EndXML(cmXMLWriter& xml);
//! Run command specialized for make and configure. Returns process status
// and retVal is return value or exception.
- int RunMakeCommand(const char* command, std::string* output,
+ int RunMakeCommand(const char* command, std::string& output,
int* retVal, const char* dir, int timeout,
- std::ofstream& ofs);
+ std::ostream& ofs);
/*
* return the current tag
@@ -287,10 +300,6 @@ public:
//source directory, it will become /.../relative/path/to/file
std::string GetShortPathToFile(const char* fname);
- //! Get the path to CTest
- const char* GetCTestExecutable() { return this->CTestSelf.c_str(); }
- const char* GetCMakeExecutable() { return this->CMakeSelf.c_str(); }
-
enum {
EXPERIMENTAL,
NIGHTLY,
@@ -336,7 +345,7 @@ public:
* Set the CTest variable from CMake variable
*/
bool SetCTestConfigurationFromCMakeVariable(cmMakefile* mf,
- const char* dconfig, const char* cmake_var);
+ const char* dconfig, const std::string& cmake_var, bool suppress=false);
//! Make string safe to be send as an URL
static std::string MakeURLSafe(const std::string&);
@@ -353,14 +362,14 @@ public:
//! Add overwrite to ctest configuration.
// The format is key=value
- void AddCTestConfigurationOverwrite(const char* encstr);
+ void AddCTestConfigurationOverwrite(const std::string& encstr);
//! Create XML file that contains all the notes specified
- int GenerateNotesFile(const std::vector<cmStdString> &files);
+ int GenerateNotesFile(const VectorOfStrings &files);
//! Submit extra files to the server
bool SubmitExtraFiles(const char* files);
- bool SubmitExtraFiles(const std::vector<cmStdString> &files);
+ bool SubmitExtraFiles(const VectorOfStrings &files);
//! Set the output log file name
void SetOutputLogFileName(const char* name);
@@ -373,6 +382,7 @@ public:
DEBUG = 0,
OUTPUT,
HANDLER_OUTPUT,
+ HANDLER_PROGRESS_OUTPUT,
HANDLER_VERBOSE_OUTPUT,
WARNING,
ERROR_MESSAGE,
@@ -380,7 +390,8 @@ public:
};
//! Add log to the output
- void Log(int logType, const char* file, int line, const char* msg);
+ void Log(int logType, const char* file, int line, const char* msg,
+ bool suppress=false);
//! Get the version of dart server
int GetDartVersion() { return this->DartVersion; }
@@ -395,8 +406,8 @@ public:
//! Read the custom configuration files and apply them to the current ctest
int ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf);
- std::vector<cmStdString> &GetInitialCommandLineArguments()
- { return this->InitialCommandLineArguments; };
+ std::vector<std::string> &GetInitialCommandLineArguments()
+ { return this->InitialCommandLineArguments; }
//! Set the track to submit to
void SetSpecificTrack(const char* track);
@@ -414,7 +425,7 @@ public:
/** Direct process output to given streams. */
void SetStreams(std::ostream* out, std::ostream* err)
{ this->StreamOut = out; this->StreamErr = err; }
- void AddSiteProperties(std::ostream& );
+ void AddSiteProperties(cmXMLWriter& xml);
bool GetLabelSummary() { return this->LabelSummary;}
std::string GetCostDataFile();
@@ -423,8 +434,13 @@ public:
{
return this->Definitions;
}
-
+ // return the number of times a test should be run
+ int GetTestRepeat() { return this->RepeatTests;}
+ // return true if test should run until fail
+ bool GetRepeatUntilFail() { return this->RepeatUntilFail;}
private:
+ int RepeatTests;
+ bool RepeatUntilFail;
std::string ConfigType;
std::string ScheduleType;
std::string StopTime;
@@ -451,13 +467,13 @@ private:
void DetermineNextDayStop();
// these are helper classes
- typedef std::map<cmStdString,cmCTestGenericHandler*> t_TestingHandlers;
+ typedef std::map<std::string,cmCTestGenericHandler*> t_TestingHandlers;
t_TestingHandlers TestingHandlers;
bool ShowOnly;
//! Map of configuration properties
- typedef std::map<cmStdString, cmStdString> CTestConfigurationMap;
+ typedef std::map<std::string, std::string> CTestConfigurationMap;
std::string CTestConfigFile;
// TODO: The ctest configuration should be a hierarchy of
@@ -467,7 +483,7 @@ private:
CTestConfigurationMap CTestConfiguration;
CTestConfigurationMap CTestConfigurationOverwrites;
PartInfo Parts[PartCount];
- typedef std::map<cmStdString, Part> PartMapType;
+ typedef std::map<std::string, Part> PartMapType;
PartMapType PartMap;
std::string CurrentTag;
@@ -487,11 +503,11 @@ private:
int ParallelLevel;
bool ParallelLevelSetInCli;
+ unsigned long TestLoad;
+
int CompatibilityMode;
// information for the --build-and-test options
- std::string CMakeSelf;
- std::string CTestSelf;
std::string BinaryDir;
std::string NotesFiles;
@@ -531,8 +547,9 @@ private:
bool AddVariableDefinition(const std::string &arg);
//! parse and process most common command line arguments
- void HandleCommandLineArguments(size_t &i,
- std::vector<std::string> &args);
+ bool HandleCommandLineArguments(size_t &i,
+ std::vector<std::string> &args,
+ std::string& errormsg);
//! hande the -S -SP and -SR arguments
void HandleScriptArguments(size_t &i,
@@ -543,12 +560,9 @@ private:
bool UpdateCTestConfiguration();
//! Create note from files.
- int GenerateCTestNotesOutput(std::ostream& os,
+ int GenerateCTestNotesOutput(cmXMLWriter& xml,
const VectorOfStrings& files);
- ///! Find the running cmake
- void FindRunningCMake();
-
//! Check if the argument is the one specified
bool CheckArgument(const std::string& arg, const char* varg1,
const char* varg2 = 0);
@@ -565,7 +579,7 @@ private:
int DartVersion;
bool DropSiteCDash;
- std::vector<cmStdString> InitialCommandLineArguments;
+ std::vector<std::string> InitialCommandLineArguments;
int SubmitIndex;
diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx
index ed09545cb..7466c299a 100644
--- a/Source/cmCacheManager.cxx
+++ b/Source/cmCacheManager.cxx
@@ -12,173 +12,22 @@
#include "cmCacheManager.h"
#include "cmSystemTools.h"
-#include "cmCacheManager.h"
#include "cmGeneratedFileStream.h"
-#include "cmMakefile.h"
#include "cmake.h"
#include "cmVersion.h"
#include <cmsys/Directory.hxx>
#include <cmsys/Glob.hxx>
-
+#include <cmsys/FStream.hxx>
#include <cmsys/RegularExpression.hxx>
-const char* cmCacheManagerTypes[] =
-{ "BOOL",
- "PATH",
- "FILEPATH",
- "STRING",
- "INTERNAL",
- "STATIC",
- "UNINITIALIZED",
- 0
-};
-
-cmCacheManager::cmCacheManager(cmake* cm)
+cmCacheManager::cmCacheManager()
{
this->CacheMajorVersion = 0;
this->CacheMinorVersion = 0;
- this->CMakeInstance = cm;
-}
-
-const char* cmCacheManager::TypeToString(cmCacheManager::CacheEntryType type)
-{
- if ( type > 6 )
- {
- return cmCacheManagerTypes[6];
- }
- return cmCacheManagerTypes[type];
-}
-
-cmCacheManager::CacheEntryType cmCacheManager::StringToType(const char* s)
-{
- int i = 0;
- while(cmCacheManagerTypes[i])
- {
- if(strcmp(s, cmCacheManagerTypes[i]) == 0)
- {
- return static_cast<CacheEntryType>(i);
- }
- ++i;
- }
- return STRING;
-}
-
-bool cmCacheManager::IsType(const char* s)
-{
- for(int i=0; cmCacheManagerTypes[i]; ++i)
- {
- if(strcmp(s, cmCacheManagerTypes[i]) == 0)
- {
- return true;
- }
- }
- return false;
}
-bool cmCacheManager::LoadCache(cmMakefile* mf)
-{
- return this->LoadCache(mf->GetHomeOutputDirectory());
-}
-
-
-bool cmCacheManager::LoadCache(const char* path)
-{
- return this->LoadCache(path,true);
-}
-
-bool cmCacheManager::LoadCache(const char* path,
- bool internal)
-{
- std::set<cmStdString> emptySet;
- return this->LoadCache(path, internal, emptySet, emptySet);
-}
-
-static bool ParseEntryWithoutType(const char* entry,
- std::string& var,
- std::string& value)
-{
- // input line is: key=value
- static cmsys::RegularExpression reg(
- "^([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
- // input line is: "key"=value
- static cmsys::RegularExpression regQuoted(
- "^\"([^\"]*)\"=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
- bool flag = false;
- if(regQuoted.find(entry))
- {
- var = regQuoted.match(1);
- value = regQuoted.match(2);
- flag = true;
- }
- else if (reg.find(entry))
- {
- var = reg.match(1);
- value = reg.match(2);
- flag = true;
- }
-
- // if value is enclosed in single quotes ('foo') then remove them
- // it is used to enclose trailing space or tab
- if (flag &&
- value.size() >= 2 &&
- value[0] == '\'' &&
- value[value.size() - 1] == '\'')
- {
- value = value.substr(1,
- value.size() - 2);
- }
-
- return flag;
-}
-
-bool cmCacheManager::ParseEntry(const char* entry,
- std::string& var,
- std::string& value,
- CacheEntryType& type)
-{
- // input line is: key:type=value
- static cmsys::RegularExpression reg(
- "^([^:]*):([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
- // input line is: "key":type=value
- static cmsys::RegularExpression regQuoted(
- "^\"([^\"]*)\":([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
- bool flag = false;
- if(regQuoted.find(entry))
- {
- var = regQuoted.match(1);
- type = cmCacheManager::StringToType(regQuoted.match(2).c_str());
- value = regQuoted.match(3);
- flag = true;
- }
- else if (reg.find(entry))
- {
- var = reg.match(1);
- type = cmCacheManager::StringToType(reg.match(2).c_str());
- value = reg.match(3);
- flag = true;
- }
-
- // if value is enclosed in single quotes ('foo') then remove them
- // it is used to enclose trailing space or tab
- if (flag &&
- value.size() >= 2 &&
- value[0] == '\'' &&
- value[value.size() - 1] == '\'')
- {
- value = value.substr(1,
- value.size() - 2);
- }
-
- if (!flag)
- {
- return ParseEntryWithoutType(entry, var, value);
- }
-
- return flag;
-}
-
-void cmCacheManager::CleanCMakeFiles(const char* path)
+void cmCacheManager::CleanCMakeFiles(const std::string& path)
{
std::string glob = path;
glob += cmake::GetCMakeFilesDirectory();
@@ -186,17 +35,13 @@ void cmCacheManager::CleanCMakeFiles(const char* path)
cmsys::Glob globIt;
globIt.FindFiles(glob);
std::vector<std::string> files = globIt.GetFiles();
- for(std::vector<std::string>::iterator i = files.begin();
- i != files.end(); ++i)
- {
- cmSystemTools::RemoveFile(i->c_str());
- }
+ std::for_each(files.begin(), files.end(), cmSystemTools::RemoveFile);
}
-bool cmCacheManager::LoadCache(const char* path,
+bool cmCacheManager::LoadCache(const std::string& path,
bool internal,
- std::set<cmStdString>& excludes,
- std::set<cmStdString>& includes)
+ std::set<std::string>& excludes,
+ std::set<std::string>& includes)
{
std::string cacheFile = path;
cacheFile += "/CMakeCache.txt";
@@ -211,7 +56,7 @@ bool cmCacheManager::LoadCache(const char* path,
return false;
}
- std::ifstream fin(cacheFile.c_str());
+ cmsys::ifstream fin(cacheFile.c_str());
if(!fin)
{
return false;
@@ -219,13 +64,14 @@ bool cmCacheManager::LoadCache(const char* path,
const char *realbuffer;
std::string buffer;
std::string entryKey;
+ unsigned int lineno = 0;
while(fin)
{
// Format is key:type=value
std::string helpString;
CacheEntry e;
- e.Properties.SetCMakeInstance(this->CMakeInstance);
cmSystemTools::GetLineFromStream(fin, buffer);
+ lineno++;
realbuffer = buffer.c_str();
while(*realbuffer != '0' &&
(*realbuffer == ' ' ||
@@ -233,6 +79,7 @@ bool cmCacheManager::LoadCache(const char* path,
*realbuffer == '\r' ||
*realbuffer == '\n'))
{
+ if (*realbuffer == '\n') lineno++;
realbuffer++;
}
// skip blank lines and comment lines
@@ -252,6 +99,7 @@ bool cmCacheManager::LoadCache(const char* path,
helpString += &realbuffer[2];
}
cmSystemTools::GetLineFromStream(fin, buffer);
+ lineno++;
realbuffer = buffer.c_str();
if(!fin)
{
@@ -259,7 +107,7 @@ bool cmCacheManager::LoadCache(const char* path,
}
}
e.SetProperty("HELPSTRING", helpString.c_str());
- if(cmCacheManager::ParseEntry(realbuffer, entryKey, e.Value, e.Type))
+ if(cmState::ParseCacheEntry(realbuffer, entryKey, e.Value, e.Type))
{
if ( excludes.find(entryKey) == excludes.end() )
{
@@ -267,7 +115,7 @@ bool cmCacheManager::LoadCache(const char* path,
// If the entry is not internal to the cache being loaded
// or if it is in the list of internal entries to be
// imported, load it.
- if ( internal || (e.Type != INTERNAL) ||
+ if ( internal || (e.Type != cmState::INTERNAL) ||
(includes.find(entryKey) != includes.end()) )
{
// If we are loading the cache from another project,
@@ -275,7 +123,7 @@ bool cmCacheManager::LoadCache(const char* path,
// not visible in the gui
if (!internal)
{
- e.Type = INTERNAL;
+ e.Type = cmState::INTERNAL;
helpString = "DO NOT EDIT, ";
helpString += entryKey;
helpString += " loaded from external file. "
@@ -294,20 +142,24 @@ bool cmCacheManager::LoadCache(const char* path,
}
else
{
- cmSystemTools::Error("Parse error in cache file ", cacheFile.c_str(),
- ". Offending entry: ", realbuffer);
+ std::ostringstream error;
+ error << "Parse error in cache file " << cacheFile;
+ error << " on line " << lineno << ". Offending entry: " << realbuffer;
+ cmSystemTools::Error(error.str().c_str());
}
}
this->CacheMajorVersion = 0;
this->CacheMinorVersion = 0;
- if(const char* cmajor = this->GetCacheValue("CMAKE_CACHE_MAJOR_VERSION"))
+ if(const char* cmajor =
+ this->GetInitializedCacheValue("CMAKE_CACHE_MAJOR_VERSION"))
{
unsigned int v=0;
if(sscanf(cmajor, "%u", &v) == 1)
{
this->CacheMajorVersion = v;
}
- if(const char* cminor = this->GetCacheValue("CMAKE_CACHE_MINOR_VERSION"))
+ if(const char* cminor =
+ this->GetInitializedCacheValue("CMAKE_CACHE_MINOR_VERSION"))
{
if(sscanf(cminor, "%u", &v) == 1)
{
@@ -321,27 +173,28 @@ bool cmCacheManager::LoadCache(const char* path,
// Set as version 0.0
this->AddCacheEntry("CMAKE_CACHE_MINOR_VERSION", "0",
"Minor version of cmake used to create the "
- "current loaded cache", cmCacheManager::INTERNAL);
+ "current loaded cache", cmState::INTERNAL);
this->AddCacheEntry("CMAKE_CACHE_MAJOR_VERSION", "0",
"Major version of cmake used to create the "
- "current loaded cache", cmCacheManager::INTERNAL);
+ "current loaded cache", cmState::INTERNAL);
}
// check to make sure the cache directory has not
// been moved
- if ( internal && this->GetCacheValue("CMAKE_CACHEFILE_DIR") )
+ const char* oldDir = this->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR");
+ if (internal && oldDir)
{
std::string currentcwd = path;
- std::string oldcwd = this->GetCacheValue("CMAKE_CACHEFILE_DIR");
+ std::string oldcwd = oldDir;
cmSystemTools::ConvertToUnixSlashes(currentcwd);
currentcwd += "/CMakeCache.txt";
oldcwd += "/CMakeCache.txt";
- if(!cmSystemTools::SameFile(oldcwd.c_str(), currentcwd.c_str()))
+ if(!cmSystemTools::SameFile(oldcwd, currentcwd))
{
std::string message =
std::string("The current CMakeCache.txt directory ") +
currentcwd + std::string(" is different than the directory ") +
- std::string(this->GetCacheValue("CMAKE_CACHEFILE_DIR")) +
+ std::string(this->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR")) +
std::string(" where CMakeCache.txt was created. This may result "
"in binaries being created in the wrong place. If you "
"are not sure, reedit the CMakeCache.txt");
@@ -365,7 +218,7 @@ bool cmCacheManager::ReadPropertyEntry(std::string const& entryKey,
CacheEntry& e)
{
// All property entries are internal.
- if(e.Type != cmCacheManager::INTERNAL)
+ if(e.Type != cmState::INTERNAL)
{
return false;
}
@@ -383,8 +236,7 @@ bool cmCacheManager::ReadPropertyEntry(std::string const& entryKey,
{
// Create an entry and store the property.
CacheEntry& ne = this->Cache[key];
- ne.Properties.SetCMakeInstance(this->CMakeInstance);
- ne.Type = cmCacheManager::UNINITIALIZED;
+ ne.Type = cmState::UNINITIALIZED;
ne.SetProperty(*p, e.Value.c_str());
}
else
@@ -422,13 +274,7 @@ void cmCacheManager::WritePropertyEntries(std::ostream& os,
}
}
-bool cmCacheManager::SaveCache(cmMakefile* mf)
-{
- return this->SaveCache(mf->GetHomeOutputDirectory());
-}
-
-
-bool cmCacheManager::SaveCache(const char* path)
+bool cmCacheManager::SaveCache(const std::string& path)
{
std::string cacheFile = path;
cacheFile += "/CMakeCache.txt";
@@ -447,15 +293,15 @@ bool cmCacheManager::SaveCache(const char* path)
sprintf(temp, "%d", cmVersion::GetMinorVersion());
this->AddCacheEntry("CMAKE_CACHE_MINOR_VERSION", temp,
"Minor version of cmake used to create the "
- "current loaded cache", cmCacheManager::INTERNAL);
+ "current loaded cache", cmState::INTERNAL);
sprintf(temp, "%d", cmVersion::GetMajorVersion());
this->AddCacheEntry("CMAKE_CACHE_MAJOR_VERSION", temp,
"Major version of cmake used to create the "
- "current loaded cache", cmCacheManager::INTERNAL);
+ "current loaded cache", cmState::INTERNAL);
sprintf(temp, "%d", cmVersion::GetPatchVersion());
this->AddCacheEntry("CMAKE_CACHE_PATCH_VERSION", temp,
"Patch version of cmake used to create the "
- "current loaded cache", cmCacheManager::INTERNAL);
+ "current loaded cache", cmState::INTERNAL);
// Let us store the current working directory so that if somebody
// Copies it, he will not be surprised
@@ -470,17 +316,12 @@ bool cmCacheManager::SaveCache(const char* path)
cmSystemTools::ConvertToUnixSlashes(currentcwd);
this->AddCacheEntry("CMAKE_CACHEFILE_DIR", currentcwd.c_str(),
"This is the directory where this CMakeCache.txt"
- " was created", cmCacheManager::INTERNAL);
+ " was created", cmState::INTERNAL);
fout << "# This is the CMakeCache file.\n"
- << "# For build in directory: " << currentcwd << "\n";
- cmCacheManager::CacheEntry* cmakeCacheEntry
- = this->GetCacheEntry("CMAKE_COMMAND");
- if ( cmakeCacheEntry )
- {
- fout << "# It was generated by CMake: " <<
- cmakeCacheEntry->Value << std::endl;
- }
+ << "# For build in directory: " << currentcwd << "\n"
+ << "# It was generated by CMake: "
+ << cmSystemTools::GetCMakeCommand() << std::endl;
fout << "# You can edit this file to change values found and used by cmake."
<< std::endl
@@ -500,11 +341,11 @@ bool cmCacheManager::SaveCache(const char* path)
fout << "########################\n";
fout << "\n";
- for( std::map<cmStdString, CacheEntry>::const_iterator i =
+ for( std::map<std::string, CacheEntry>::const_iterator i =
this->Cache.begin(); i != this->Cache.end(); ++i)
{
const CacheEntry& ce = (*i).second;
- CacheEntryType t = ce.Type;
+ cmState::CacheEntryType t = ce.Type;
if(!ce.Initialized)
{
/*
@@ -513,7 +354,7 @@ bool cmCacheManager::SaveCache(const char* path)
"\" is uninitialized");
*/
}
- else if(t != INTERNAL)
+ else if(t != cmState::INTERNAL)
{
// Format is key:type=value
if(const char* help = ce.GetProperty("HELPSTRING"))
@@ -525,7 +366,7 @@ bool cmCacheManager::SaveCache(const char* path)
cmCacheManager::OutputHelpString(fout, "Missing description");
}
this->OutputKey(fout, i->first);
- fout << ":" << cmCacheManagerTypes[t] << "=";
+ fout << ":" << cmState::CacheEntryTypeToString(t) << "=";
this->OutputValue(fout, ce.Value);
fout << "\n\n";
}
@@ -545,9 +386,9 @@ bool cmCacheManager::SaveCache(const char* path)
continue;
}
- CacheEntryType t = i.GetType();
+ cmState::CacheEntryType t = i.GetType();
this->WritePropertyEntries(fout, i);
- if(t == cmCacheManager::INTERNAL)
+ if(t == cmState::INTERNAL)
{
// Format is key:type=value
if(const char* help = i.GetProperty("HELPSTRING"))
@@ -555,7 +396,7 @@ bool cmCacheManager::SaveCache(const char* path)
this->OutputHelpString(fout, help);
}
this->OutputKey(fout, i.GetName());
- fout << ":" << cmCacheManagerTypes[t] << "=";
+ fout << ":" << cmState::CacheEntryTypeToString(t) << "=";
this->OutputValue(fout, i.GetValue());
fout << "\n";
}
@@ -566,7 +407,7 @@ bool cmCacheManager::SaveCache(const char* path)
checkCacheFile += cmake::GetCMakeFilesDirectory();
cmSystemTools::MakeDirectory(checkCacheFile.c_str());
checkCacheFile += "/cmake.check_cache";
- std::ofstream checkCache(checkCacheFile.c_str());
+ cmsys::ofstream checkCache(checkCacheFile.c_str());
if(!checkCache)
{
cmSystemTools::Error("Unable to open check cache file for write. ",
@@ -578,7 +419,7 @@ bool cmCacheManager::SaveCache(const char* path)
return true;
}
-bool cmCacheManager::DeleteCache(const char* path)
+bool cmCacheManager::DeleteCache(const std::string& path)
{
std::string cacheFile = path;
cmSystemTools::ConvertToUnixSlashes(cacheFile);
@@ -586,13 +427,13 @@ bool cmCacheManager::DeleteCache(const char* path)
cacheFile += "/CMakeCache.txt";
if(cmSystemTools::FileExists(cacheFile.c_str()))
{
- cmSystemTools::RemoveFile(cacheFile.c_str());
+ cmSystemTools::RemoveFile(cacheFile);
// now remove the files in the CMakeFiles directory
// this cleans up language cache files
cmakeFiles += cmake::GetCMakeFilesDirectory();
- if(cmSystemTools::FileIsDirectory(cmakeFiles.c_str()))
+ if(cmSystemTools::FileIsDirectory(cmakeFiles))
{
- cmSystemTools::RemoveADirectory(cmakeFiles.c_str());
+ cmSystemTools::RemoveADirectory(cmakeFiles);
}
}
return true;
@@ -609,7 +450,7 @@ void cmCacheManager::OutputKey(std::ostream& fout, std::string const& key)
void cmCacheManager::OutputValue(std::ostream& fout, std::string const& value)
{
// if value has trailing space or tab, enclose it in single quotes
- if (value.size() &&
+ if (!value.empty() &&
(value[value.size() - 1] == ' ' ||
value[value.size() - 1] == '\t'))
{
@@ -644,13 +485,13 @@ void cmCacheManager::OutputHelpString(std::ostream& fout,
fout << "\\n";
}
oneLine = helpString.substr(pos, i - pos);
- fout << oneLine.c_str() << "\n";
+ fout << oneLine << "\n";
pos = i;
}
}
}
-void cmCacheManager::RemoveCacheEntry(const char* key)
+void cmCacheManager::RemoveCacheEntry(const std::string& key)
{
CacheEntryMap::iterator i = this->Cache.find(key);
if(i != this->Cache.end())
@@ -660,7 +501,8 @@ void cmCacheManager::RemoveCacheEntry(const char* key)
}
-cmCacheManager::CacheEntry *cmCacheManager::GetCacheEntry(const char* key)
+cmCacheManager::CacheEntry *cmCacheManager::GetCacheEntry(
+ const std::string& key)
{
CacheEntryMap::iterator i = this->Cache.find(key);
if(i != this->Cache.end())
@@ -676,7 +518,8 @@ cmCacheManager::CacheIterator cmCacheManager::GetCacheIterator(
return CacheIterator(*this, key);
}
-const char* cmCacheManager::GetCacheValue(const char* key) const
+const char*
+cmCacheManager::GetInitializedCacheValue(const std::string& key) const
{
CacheEntryMap::const_iterator i = this->Cache.find(key);
if(i != this->Cache.end() &&
@@ -692,12 +535,12 @@ void cmCacheManager::PrintCache(std::ostream& out) const
{
out << "=================================================" << std::endl;
out << "CMakeCache Contents:" << std::endl;
- for(std::map<cmStdString, CacheEntry>::const_iterator i =
+ for(std::map<std::string, CacheEntry>::const_iterator i =
this->Cache.begin(); i != this->Cache.end(); ++i)
{
- if((*i).second.Type != INTERNAL)
+ if((*i).second.Type != cmState::INTERNAL)
{
- out << (*i).first.c_str() << " = " << (*i).second.Value.c_str()
+ out << (*i).first << " = " << (*i).second.Value
<< std::endl;
}
}
@@ -708,13 +551,12 @@ void cmCacheManager::PrintCache(std::ostream& out) const
}
-void cmCacheManager::AddCacheEntry(const char* key,
+void cmCacheManager::AddCacheEntry(const std::string& key,
const char* value,
const char* helpString,
- CacheEntryType type)
+ cmState::CacheEntryType type)
{
CacheEntry& e = this->Cache[key];
- e.Properties.SetCMakeInstance(this->CMakeInstance);
if ( value )
{
e.Value = value;
@@ -726,7 +568,7 @@ void cmCacheManager::AddCacheEntry(const char* key,
}
e.Type = type;
// make sure we only use unix style paths
- if(type == FILEPATH || type == PATH)
+ if(type == cmState::FILEPATH || type == cmState::PATH)
{
if(e.Value.find(';') != e.Value.npos)
{
@@ -750,11 +592,6 @@ void cmCacheManager::AddCacheEntry(const char* key,
}
e.SetProperty("HELPSTRING", helpString? helpString :
"(This variable does not exist and should not be used)");
- if (this->Cache[key].Value == e.Value)
- {
- this->CMakeInstance->UnwatchUnusedCli(key);
- }
- this->Cache[key] = e;
}
bool cmCacheManager::CacheIterator::IsAtEnd() const
@@ -767,7 +604,7 @@ void cmCacheManager::CacheIterator::Begin()
this->Position = this->Container.Cache.begin();
}
-bool cmCacheManager::CacheIterator::Find(const char* key)
+bool cmCacheManager::CacheIterator::Find(const std::string& key)
{
this->Position = this->Container.Cache.find(key);
return !this->IsAtEnd();
@@ -807,49 +644,47 @@ bool cmCacheManager::CacheIterator::GetValueAsBool() const
//----------------------------------------------------------------------------
const char*
-cmCacheManager::CacheEntry::GetProperty(const char* prop) const
+cmCacheManager::CacheEntry::GetProperty(const std::string& prop) const
{
- if(strcmp(prop, "TYPE") == 0)
+ if(prop == "TYPE")
{
- return cmCacheManagerTypes[this->Type];
+ return cmState::CacheEntryTypeToString(this->Type);
}
- else if(strcmp(prop, "VALUE") == 0)
+ else if(prop == "VALUE")
{
return this->Value.c_str();
}
- bool c = false;
- return
- this->Properties.GetPropertyValue(prop, cmProperty::CACHE, c);
+ return this->Properties.GetPropertyValue(prop);
}
//----------------------------------------------------------------------------
-void cmCacheManager::CacheEntry::SetProperty(const char* prop,
+void cmCacheManager::CacheEntry::SetProperty(const std::string& prop,
const char* value)
{
- if(strcmp(prop, "TYPE") == 0)
+ if(prop == "TYPE")
{
- this->Type = cmCacheManager::StringToType(value? value : "STRING");
+ this->Type = cmState::StringToCacheEntryType(value? value : "STRING");
}
- else if(strcmp(prop, "VALUE") == 0)
+ else if(prop == "VALUE")
{
this->Value = value? value : "";
}
else
{
- this->Properties.SetProperty(prop, value, cmProperty::CACHE);
+ this->Properties.SetProperty(prop, value);
}
}
//----------------------------------------------------------------------------
-void cmCacheManager::CacheEntry::AppendProperty(const char* prop,
+void cmCacheManager::CacheEntry::AppendProperty(const std::string& prop,
const char* value,
bool asString)
{
- if(strcmp(prop, "TYPE") == 0)
+ if(prop == "TYPE")
{
- this->Type = cmCacheManager::StringToType(value? value : "STRING");
+ this->Type = cmState::StringToCacheEntryType(value? value : "STRING");
}
- else if(strcmp(prop, "VALUE") == 0)
+ else if(prop == "VALUE")
{
if(value)
{
@@ -862,12 +697,13 @@ void cmCacheManager::CacheEntry::AppendProperty(const char* prop,
}
else
{
- this->Properties.AppendProperty(prop, value, cmProperty::CACHE, asString);
+ this->Properties.AppendProperty(prop, value, asString);
}
}
//----------------------------------------------------------------------------
-const char* cmCacheManager::CacheIterator::GetProperty(const char* prop) const
+const char* cmCacheManager::CacheIterator::GetProperty(
+ const std::string& prop) const
{
if(!this->IsAtEnd())
{
@@ -877,7 +713,8 @@ const char* cmCacheManager::CacheIterator::GetProperty(const char* prop) const
}
//----------------------------------------------------------------------------
-void cmCacheManager::CacheIterator::SetProperty(const char* p, const char* v)
+void cmCacheManager::CacheIterator::SetProperty(const std::string& p,
+ const char* v)
{
if(!this->IsAtEnd())
{
@@ -886,7 +723,7 @@ void cmCacheManager::CacheIterator::SetProperty(const char* p, const char* v)
}
//----------------------------------------------------------------------------
-void cmCacheManager::CacheIterator::AppendProperty(const char* p,
+void cmCacheManager::CacheIterator::AppendProperty(const std::string& p,
const char* v,
bool asString)
{
@@ -897,7 +734,8 @@ void cmCacheManager::CacheIterator::AppendProperty(const char* p,
}
//----------------------------------------------------------------------------
-bool cmCacheManager::CacheIterator::GetPropertyAsBool(const char* prop) const
+bool cmCacheManager::CacheIterator::GetPropertyAsBool(
+ const std::string& prop) const
{
if(const char* value = this->GetProperty(prop))
{
@@ -907,93 +745,14 @@ bool cmCacheManager::CacheIterator::GetPropertyAsBool(const char* prop) const
}
//----------------------------------------------------------------------------
-void cmCacheManager::CacheIterator::SetProperty(const char* p, bool v)
+void cmCacheManager::CacheIterator::SetProperty(const std::string& p, bool v)
{
this->SetProperty(p, v ? "ON" : "OFF");
}
//----------------------------------------------------------------------------
-bool cmCacheManager::CacheIterator::PropertyExists(const char* prop) const
+bool cmCacheManager::CacheIterator::PropertyExists(
+ const std::string& prop) const
{
return this->GetProperty(prop)? true:false;
}
-
-//----------------------------------------------------------------------------
-bool cmCacheManager::NeedCacheCompatibility(int major, int minor)
-{
- // Compatibility is not needed if the cache version is zero because
- // the cache was created or modified by the user.
- if(this->CacheMajorVersion == 0)
- {
- return false;
- }
-
- // Compatibility is needed if the cache version is equal to or lower
- // than the given version.
- unsigned int actual_compat =
- CMake_VERSION_ENCODE(this->CacheMajorVersion, this->CacheMinorVersion, 0);
- return (actual_compat &&
- actual_compat <= CMake_VERSION_ENCODE(major, minor, 0));
-}
-
-//----------------------------------------------------------------------------
-void cmCacheManager::DefineProperties(cmake *cm)
-{
- cm->DefineProperty
- ("ADVANCED", cmProperty::CACHE,
- "True if entry should be hidden by default in GUIs.",
- "This is a boolean value indicating whether the entry is considered "
- "interesting only for advanced configuration. "
- "The mark_as_advanced() command modifies this property."
- );
-
- cm->DefineProperty
- ("HELPSTRING", cmProperty::CACHE,
- "Help associated with entry in GUIs.",
- "This string summarizes the purpose of an entry to help users set it "
- "through a CMake GUI."
- );
-
- cm->DefineProperty
- ("TYPE", cmProperty::CACHE,
- "Widget type for entry in GUIs.",
- "Cache entry values are always strings, but CMake GUIs present widgets "
- "to help users set values. "
- "The GUIs use this property as a hint to determine the widget type. "
- "Valid TYPE values are:\n"
- " BOOL = Boolean ON/OFF value.\n"
- " PATH = Path to a directory.\n"
- " FILEPATH = Path to a file.\n"
- " STRING = Generic string value.\n"
- " INTERNAL = Do not present in GUI at all.\n"
- " STATIC = Value managed by CMake, do not change.\n"
- " UNINITIALIZED = Type not yet specified.\n"
- "Generally the TYPE of a cache entry should be set by the command "
- "which creates it (set, option, find_library, etc.)."
- );
-
- cm->DefineProperty
- ("MODIFIED", cmProperty::CACHE,
- "Internal management property. Do not set or get.",
- "This is an internal cache entry property managed by CMake to "
- "track interactive user modification of entries. Ignore it."
- );
-
- cm->DefineProperty
- ("STRINGS", cmProperty::CACHE,
- "Enumerate possible STRING entry values for GUI selection.",
- "For cache entries with type STRING, this enumerates a set of values. "
- "CMake GUIs may use this to provide a selection widget instead of a "
- "generic string entry field. "
- "This is for convenience only. "
- "CMake does not enforce that the value matches one of those listed."
- );
-
- cm->DefineProperty
- ("VALUE", cmProperty::CACHE,
- "Value of a cache entry.",
- "This property maps to the actual value of a cache entry. "
- "Setting this property always sets the value without checking, so "
- "use with care."
- );
-}
diff --git a/Source/cmCacheManager.h b/Source/cmCacheManager.h
index a5e5eeeff..6f063ebbc 100644
--- a/Source/cmCacheManager.h
+++ b/Source/cmCacheManager.h
@@ -14,9 +14,9 @@
#include "cmStandardIncludes.h"
#include "cmPropertyMap.h"
-class cmMakefile;
+#include "cmState.h"
+
class cmMarkAsAdvancedCommand;
-class cmake;
/** \class cmCacheManager
* \brief Control class for cmake's cache
@@ -27,24 +27,25 @@ class cmake;
class cmCacheManager
{
public:
- cmCacheManager(cmake* cm);
+ cmCacheManager();
class CacheIterator;
friend class cmCacheManager::CacheIterator;
- enum CacheEntryType{ BOOL=0, PATH, FILEPATH, STRING, INTERNAL,STATIC,
- UNINITIALIZED };
private:
struct CacheEntry
{
std::string Value;
- CacheEntryType Type;
+ cmState::CacheEntryType Type;
cmPropertyMap Properties;
- const char* GetProperty(const char*) const;
- void SetProperty(const char* property, const char* value);
- void AppendProperty(const char* property, const char* value,
+ const char* GetProperty(const std::string&) const;
+ void SetProperty(const std::string& property, const char* value);
+ void AppendProperty(const std::string& property, const char* value,
bool asString=false);
bool Initialized;
- CacheEntry() : Value(""), Type(UNINITIALIZED), Initialized(false)
+ CacheEntry()
+ : Value(""),
+ Type(cmState::UNINITIALIZED),
+ Initialized(false)
{}
};
@@ -53,26 +54,28 @@ public:
{
public:
void Begin();
- bool Find(const char*);
+ bool Find(const std::string&);
bool IsAtEnd() const;
void Next();
- const char *GetName() const {
- return this->Position->first.c_str(); }
- const char* GetProperty(const char*) const ;
- bool GetPropertyAsBool(const char*) const ;
- bool PropertyExists(const char*) const;
- void SetProperty(const char* property, const char* value);
- void AppendProperty(const char* property, const char* value,
+ std::string GetName() const {
+ return this->Position->first; }
+ const char* GetProperty(const std::string&) const ;
+ bool GetPropertyAsBool(const std::string&) const ;
+ bool PropertyExists(const std::string&) const;
+ void SetProperty(const std::string& property, const char* value);
+ void AppendProperty(const std::string& property, const char* value,
bool asString=false);
- void SetProperty(const char* property, bool value);
+ void SetProperty(const std::string& property, bool value);
const char* GetValue() const { return this->GetEntry().Value.c_str(); }
bool GetValueAsBool() const;
void SetValue(const char*);
- CacheEntryType GetType() const { return this->GetEntry().Type; }
- void SetType(CacheEntryType ty) { this->GetEntry().Type = ty; }
+ cmState::CacheEntryType GetType() const
+ { return this->GetEntry().Type; }
+ void SetType(cmState::CacheEntryType ty)
+ { this->GetEntry().Type = ty; }
bool Initialized() { return this->GetEntry().Initialized; }
cmCacheManager &Container;
- std::map<cmStdString, CacheEntry>::iterator Position;
+ std::map<std::string, CacheEntry>::iterator Position;
CacheIterator(cmCacheManager &cm) : Container(cm) {
this->Begin();
}
@@ -94,33 +97,16 @@ public:
return CacheIterator(*this);
}
- /**
- * Types for the cache entries. These are useful as
- * hints for a cache editor program. Path should bring
- * up a file chooser, BOOL a check box, and STRING a
- * text entry box, FILEPATH is a full path to a file which
- * can be different than just a path input
- */
- static CacheEntryType StringToType(const char*);
- static const char* TypeToString(CacheEntryType);
- static bool IsType(const char*);
-
- ///! Load a cache for given makefile. Loads from ouput home.
- bool LoadCache(cmMakefile*);
///! Load a cache for given makefile. Loads from path/CMakeCache.txt.
- bool LoadCache(const char* path);
- bool LoadCache(const char* path, bool internal);
- bool LoadCache(const char* path, bool internal,
- std::set<cmStdString>& excludes,
- std::set<cmStdString>& includes);
-
- ///! Save cache for given makefile. Saves to ouput home CMakeCache.txt.
- bool SaveCache(cmMakefile*) ;
+ bool LoadCache(const std::string& path, bool internal,
+ std::set<std::string>& excludes,
+ std::set<std::string>& includes);
+
///! Save cache for given makefile. Saves to ouput path/CMakeCache.txt
- bool SaveCache(const char* path) ;
+ bool SaveCache(const std::string& path) ;
///! Delete the cache given
- bool DeleteCache(const char* path);
+ bool DeleteCache(const std::string& path);
///! Print the cache to a stream
void PrintCache(std::ostream&) const;
@@ -129,45 +115,113 @@ public:
cmCacheManager::CacheIterator GetCacheIterator(const char *key=0);
///! Remove an entry from the cache
- void RemoveCacheEntry(const char* key);
+ void RemoveCacheEntry(const std::string& key);
///! Get the number of entries in the cache
int GetSize() {
return static_cast<int>(this->Cache.size()); }
- ///! Break up a line like VAR:type="value" into var, type and value
- static bool ParseEntry(const char* entry,
- std::string& var,
- std::string& value,
- CacheEntryType& type);
-
///! Get a value from the cache given a key
- const char* GetCacheValue(const char* key) const;
+ const char* GetInitializedCacheValue(const std::string& key) const;
- /** Get the version of CMake that wrote the cache. */
- unsigned int GetCacheMajorVersion() { return this->CacheMajorVersion; }
- unsigned int GetCacheMinorVersion() { return this->CacheMinorVersion; }
- bool NeedCacheCompatibility(int major, int minor);
+ const char* GetCacheEntryValue(const std::string& key)
+ {
+ cmCacheManager::CacheIterator it = this->GetCacheIterator(key.c_str());
+ if (it.IsAtEnd())
+ {
+ return 0;
+ }
+ return it.GetValue();
+ }
+
+ const char* GetCacheEntryProperty(std::string const& key,
+ std::string const& propName)
+ {
+ return this->GetCacheIterator(key.c_str()).GetProperty(propName);
+ }
+
+ cmState::CacheEntryType GetCacheEntryType(std::string const& key)
+ {
+ return this->GetCacheIterator(key.c_str()).GetType();
+ }
+
+ bool GetCacheEntryPropertyAsBool(std::string const& key,
+ std::string const& propName)
+ {
+ return this->GetCacheIterator(key.c_str()).GetPropertyAsBool(propName);
+ }
+
+ void SetCacheEntryProperty(std::string const& key,
+ std::string const& propName,
+ std::string const& value)
+ {
+ this->GetCacheIterator(key.c_str()).SetProperty(propName, value.c_str());
+ }
+
+ void SetCacheEntryBoolProperty(std::string const& key,
+ std::string const& propName,
+ bool value)
+ {
+ this->GetCacheIterator(key.c_str()).SetProperty(propName, value);
+ }
+
+ void SetCacheEntryValue(std::string const& key,
+ std::string const& value)
+ {
+ this->GetCacheIterator(key.c_str()).SetValue(value.c_str());
+ }
+
+ void RemoveCacheEntryProperty(std::string const& key,
+ std::string const& propName)
+ {
+ this->GetCacheIterator(key.c_str()).SetProperty(propName, (void*)0);
+ }
- /** Define and document CACHE entry properties. */
- static void DefineProperties(cmake *cm);
+ void AppendCacheEntryProperty(std::string const& key,
+ std::string const& propName,
+ std::string const& value,
+ bool asString = false)
+ {
+ this->GetCacheIterator(key.c_str()).AppendProperty(propName,
+ value.c_str(),
+ asString);
+ }
+
+ std::vector<std::string> GetCacheEntryKeys()
+ {
+ std::vector<std::string> definitions;
+ definitions.reserve(this->GetSize());
+ cmCacheManager::CacheIterator cit = this->GetCacheIterator();
+ for ( cit.Begin(); !cit.IsAtEnd(); cit.Next() )
+ {
+ definitions.push_back(cit.GetName());
+ }
+ return definitions;
+ }
+
+ /** Get the version of CMake that wrote the cache. */
+ unsigned int GetCacheMajorVersion() const
+ { return this->CacheMajorVersion; }
+ unsigned int GetCacheMinorVersion() const
+ { return this->CacheMinorVersion; }
protected:
///! Add an entry into the cache
- void AddCacheEntry(const char* key, const char* value,
- const char* helpString, CacheEntryType type);
+ void AddCacheEntry(const std::string& key, const char* value,
+ const char* helpString,
+ cmState::CacheEntryType type);
///! Get a cache entry object for a key
- CacheEntry *GetCacheEntry(const char *key);
+ CacheEntry *GetCacheEntry(const std::string& key);
///! Clean out the CMakeFiles directory if no CMakeCache.txt
- void CleanCMakeFiles(const char* path);
+ void CleanCMakeFiles(const std::string& path);
// Cache version info
unsigned int CacheMajorVersion;
unsigned int CacheMinorVersion;
private:
cmake* CMakeInstance;
- typedef std::map<cmStdString, CacheEntry> CacheEntryMap;
+ typedef std::map<std::string, CacheEntry> CacheEntryMap;
static void OutputHelpString(std::ostream& fout,
const std::string& helpString);
static void OutputKey(std::ostream& fout, std::string const& key);
@@ -178,12 +232,10 @@ private:
void WritePropertyEntries(std::ostream& os, CacheIterator const& i);
CacheEntryMap Cache;
- // Only cmake and cmMakefile should be able to add cache values
+ // Only cmake and cmState should be able to add cache values
// the commands should never use the cmCacheManager directly
- friend class cmMakefile; // allow access to add cache values
+ friend class cmState; // allow access to add cache values
friend class cmake; // allow access to add cache values
- friend class cmakewizard; // allow access to add cache values
- friend class cmMarkAsAdvancedCommand; // allow access to add cache values
};
#endif
diff --git a/Source/cmCallVisualStudioMacro.cxx b/Source/cmCallVisualStudioMacro.cxx
index 0c154770d..0e0483892 100644
--- a/Source/cmCallVisualStudioMacro.cxx
+++ b/Source/cmCallVisualStudioMacro.cxx
@@ -34,8 +34,6 @@ static bool LogErrorsAsMessages;
// Copied from a correct comdef.h to avoid problems with deficient versions
// of comdef.h that exist in the wild... Fixes issue #7533.
//
-#if ( _MSC_VER >= 1300 )
-// VS7 and later:
#ifdef _NATIVE_WCHAR_T_DEFINED
# ifdef _DEBUG
# pragma comment(lib, "comsuppwd.lib")
@@ -49,10 +47,6 @@ static bool LogErrorsAsMessages;
# pragma comment(lib, "comsupp.lib")
# endif
#endif
-#else
-// VS6 only had comsupp.lib:
-# pragma comment(lib, "comsupp.lib")
-#endif
//----------------------------------------------------------------------------
@@ -63,12 +57,13 @@ static bool LogErrorsAsMessages;
{ \
if (LogErrorsAsMessages) \
{ \
- std::ostringstream oss; \
- oss.flags(std::ios::hex); \
- oss << context << " failed HRESULT, hr = 0x" << hr << std::endl; \
- oss.flags(std::ios::dec); \
- oss << __FILE__ << "(" << __LINE__ << ")"; \
- cmSystemTools::Message(oss.str().c_str()); \
+ std::ostringstream _hresult_oss; \
+ _hresult_oss.flags(std::ios::hex); \
+ _hresult_oss << context << " failed HRESULT, hr = 0x" \
+ << hr << std::endl; \
+ _hresult_oss.flags(std::ios::dec); \
+ _hresult_oss << __FILE__ << "(" << __LINE__ << ")"; \
+ cmSystemTools::Message(_hresult_oss.str().c_str()); \
} \
}
@@ -503,7 +498,7 @@ int cmCallVisualStudioMacro::CallMacro(
}
}
- if(0 == instances.size())
+ if(instances.empty())
{
// no instances to call
diff --git a/Source/cmCommand.h b/Source/cmCommand.h
index 49f451b58..59bc396f3 100644
--- a/Source/cmCommand.h
+++ b/Source/cmCommand.h
@@ -81,7 +81,7 @@ public:
* not implement this method. At this point, reading and
* writing to the cache can be done.
*/
- virtual void FinalPass() {};
+ virtual void FinalPass() {}
/**
* Does this command have a final pass? Query after InitialPass.
@@ -102,15 +102,6 @@ public:
}
/**
- * This determines if usage of the method is discouraged or not.
- * This is currently only used for generating the documentation.
- */
- virtual bool IsDiscouraged() const
- {
- return false;
- }
-
- /**
* This is used to avoid including this command
* in documentation. This is mainly used by
* cmMacroHelperCommand and cmFunctionHelperCommand
@@ -124,17 +115,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const = 0;
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const = 0;
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const = 0;
+ virtual std::string GetName() const = 0;
/**
* Enable the command.
@@ -165,7 +146,7 @@ public:
*/
const char* GetError()
{
- if(this->Error.length() == 0)
+ if(this->Error.empty())
{
this->Error = this->GetName();
this->Error += " unknown error.";
@@ -176,13 +157,32 @@ public:
/**
* Set the error message
*/
- void SetError(const char* e)
+ void SetError(const std::string& e)
{
this->Error = this->GetName();
this->Error += " ";
this->Error += e;
}
+ /** Check if the command is disallowed by a policy. */
+ bool Disallowed(cmPolicies::PolicyID pol, const char* e)
+ {
+ switch(this->Makefile->GetPolicyStatus(pol))
+ {
+ case cmPolicies::WARN:
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING,
+ cmPolicies::GetPolicyWarning(pol));
+ case cmPolicies::OLD:
+ return false;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e);
+ break;
+ }
+ return true;
+ }
+
protected:
cmMakefile* Makefile;
cmCommandArgumentsHelper Helper;
diff --git a/Source/cmCommandArgumentLexer.cxx b/Source/cmCommandArgumentLexer.cxx
index e68f6b5fd..e23ef8a8b 100644
--- a/Source/cmCommandArgumentLexer.cxx
+++ b/Source/cmCommandArgumentLexer.cxx
@@ -1069,7 +1069,7 @@ case YY_STATE_EOF(NOESCAPES):
"fatal flex scanner internal error--no action found" );
} /* end of action switch */
} /* end of scanning one token */
-return 0; /* this should not happend but it should silence a warning */
+return 0; /* this should not happen but it quiets some compilers */
} /* end of cmCommandArgument_yylex */
/* yy_get_next_buffer - try to read in a new buffer
@@ -1820,7 +1820,7 @@ void cmCommandArgument_yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yysca
}
/** Set the current line number.
- * @param line_number
+ * @param line_number The line number to set.
* @param yyscanner The scanner object.
*/
void cmCommandArgument_yyset_lineno (int line_number , yyscan_t yyscanner)
@@ -1835,7 +1835,7 @@ void cmCommandArgument_yyset_lineno (int line_number , yyscan_t yyscanner)
}
/** Set the current column.
- * @param column_no
+ * @param column_no The column number to set.
* @param yyscanner The scanner object.
*/
void cmCommandArgument_yyset_column (int column_no , yyscan_t yyscanner)
diff --git a/Source/cmCommandArgumentParser.cxx b/Source/cmCommandArgumentParser.cxx
index c5146c5d7..9f8a4de7f 100644
--- a/Source/cmCommandArgumentParser.cxx
+++ b/Source/cmCommandArgumentParser.cxx
@@ -183,12 +183,6 @@ static void cmCommandArgumentError(yyscan_t yyscanner, const char* message);
#define YYINITDEPTH 10000
/* Disable some warnings in the generated code. */
-#ifdef __BORLANDC__
-# pragma warn -8004 /* Variable assigned a value that is not used. */
-# pragma warn -8008 /* condition always returns true */
-# pragma warn -8060 /* possibly incorrect assignment */
-# pragma warn -8066 /* unreachable code */
-#endif
#ifdef _MSC_VER
# pragma warning (disable: 4102) /* Unused goto label. */
# pragma warning (disable: 4065) /* Switch statement contains default but no
diff --git a/Source/cmCommandArgumentParser.y b/Source/cmCommandArgumentParser.y
index 48f5c8ecd..b1d53f6ed 100644
--- a/Source/cmCommandArgumentParser.y
+++ b/Source/cmCommandArgumentParser.y
@@ -64,12 +64,6 @@ static void cmCommandArgumentError(yyscan_t yyscanner, const char* message);
#define YYINITDEPTH 10000
/* Disable some warnings in the generated code. */
-#ifdef __BORLANDC__
-# pragma warn -8004 /* Variable assigned a value that is not used. */
-# pragma warn -8008 /* condition always returns true */
-# pragma warn -8060 /* possibly incorrect assignment */
-# pragma warn -8066 /* unreachable code */
-#endif
#ifdef _MSC_VER
# pragma warning (disable: 4102) /* Unused goto label. */
# pragma warning (disable: 4065) /* Switch statement contains default but no
diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx
index dbeeb0793..14e9e5661 100644
--- a/Source/cmCommandArgumentParserHelper.cxx
+++ b/Source/cmCommandArgumentParserHelper.cxx
@@ -13,6 +13,8 @@
#include "cmSystemTools.h"
#include "cmMakefile.h"
+#include "cmState.h"
+#include "cmOutputConverter.h"
#include "cmCommandArgumentLexer.h"
@@ -49,14 +51,14 @@ void cmCommandArgumentParserHelper::SetLineFile(long line, const char* file)
this->FileName = file;
}
-char* cmCommandArgumentParserHelper::AddString(const char* str)
+char* cmCommandArgumentParserHelper::AddString(const std::string& str)
{
- if ( !str || !*str )
+ if ( str.empty() )
{
return this->EmptyVariable;
}
- char* stVal = new char[strlen(str)+1];
- strcpy(stVal, str);
+ char* stVal = new char[str.size()+1];
+ strcpy(stVal, str.c_str());
this->Variables.push_back(stVal);
return stVal;
}
@@ -79,7 +81,7 @@ char* cmCommandArgumentParserHelper::ExpandSpecialVariable(const char* key,
{
if (this->EscapeQuotes)
{
- return this->AddString(cmSystemTools::EscapeQuotes(ptr).c_str());
+ return this->AddString(cmSystemTools::EscapeQuotes(ptr));
}
else
{
@@ -90,11 +92,12 @@ char* cmCommandArgumentParserHelper::ExpandSpecialVariable(const char* key,
}
if ( strcmp(key, "CACHE") == 0 )
{
- if(const char* c = this->Makefile->GetCacheManager()->GetCacheValue(var))
+ if(const char* c = this->Makefile->GetState()
+ ->GetInitializedCacheValue(var))
{
if(this->EscapeQuotes)
{
- return this->AddString(cmSystemTools::EscapeQuotes(c).c_str());
+ return this->AddString(cmSystemTools::EscapeQuotes(c));
}
else
{
@@ -103,7 +106,7 @@ char* cmCommandArgumentParserHelper::ExpandSpecialVariable(const char* key,
}
return this->EmptyVariable;
}
- cmOStringStream e;
+ std::ostringstream e;
e << "Syntax $" << key << "{} is not supported. "
<< "Only ${}, $ENV{}, and $CACHE{} are allowed.";
this->SetError(e.str());
@@ -118,9 +121,9 @@ char* cmCommandArgumentParserHelper::ExpandVariable(const char* var)
}
if(this->FileLine >= 0 && strcmp(var, "CMAKE_CURRENT_LIST_LINE") == 0)
{
- cmOStringStream ostr;
+ std::ostringstream ostr;
ostr << this->FileLine;
- return this->AddString(ostr.str().c_str());
+ return this->AddString(ostr.str());
}
const char* value = this->Makefile->GetDefinition(var);
if(!value && !this->RemoveEmpty)
@@ -136,24 +139,25 @@ char* cmCommandArgumentParserHelper::ExpandVariable(const char* var)
cmSystemTools::IsSubDirectory(this->FileName,
this->Makefile->GetHomeOutputDirectory()))
{
- cmOStringStream msg;
- cmListFileBacktrace bt;
+ std::ostringstream msg;
cmListFileContext lfc;
- lfc.FilePath = this->FileName;
+ cmOutputConverter converter(this->Makefile->GetStateSnapshot());
+ lfc.FilePath = converter.Convert(this->FileName,
+ cmOutputConverter::HOME);
+
lfc.Line = this->FileLine;
- bt.push_back(lfc);
msg << "uninitialized variable \'" << var << "\'";
this->Makefile->GetCMakeInstance()->IssueMessage(cmake::AUTHOR_WARNING,
- msg.str().c_str(), bt);
+ msg.str(), lfc);
}
}
return 0;
}
if (this->EscapeQuotes && value)
{
- return this->AddString(cmSystemTools::EscapeQuotes(value).c_str());
+ return this->AddString(cmSystemTools::EscapeQuotes(value));
}
- return this->AddString(value);
+ return this->AddString(value ? value : "");
}
char* cmCommandArgumentParserHelper::ExpandVariableForAt(const char* var)
@@ -166,7 +170,7 @@ char* cmCommandArgumentParserHelper::ExpandVariableForAt(const char* var)
// then return an empty string
if(!ret && this->RemoveEmpty)
{
- return this->AddString(ret);
+ return this->AddString("");
}
// if the ret was not 0, then return it
if(ret)
@@ -181,7 +185,7 @@ char* cmCommandArgumentParserHelper::ExpandVariableForAt(const char* var)
std::string ref = "@";
ref += var;
ref += "@";
- return this->AddString(ref.c_str());
+ return this->AddString(ref);
}
char* cmCommandArgumentParserHelper::CombineUnions(char* in1, char* in2)
@@ -253,7 +257,7 @@ bool cmCommandArgumentParserHelper::HandleEscapeSymbol
break;
default:
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Invalid escape sequence \\" << symbol;
this->SetError(e.str());
}
@@ -293,7 +297,7 @@ int cmCommandArgumentParserHelper::ParseString(const char* str, int verb)
if ( Verbose )
{
std::cerr << "Expanding [" << str << "] produced: ["
- << this->Result.c_str() << "]" << std::endl;
+ << this->Result << "]" << std::endl;
}
return 1;
}
@@ -335,7 +339,7 @@ int cmCommandArgumentParserHelper::LexInput(char* buf, int maxlen)
void cmCommandArgumentParserHelper::Error(const char* str)
{
unsigned long pos = static_cast<unsigned long>(this->InputBufferPos);
- cmOStringStream ostr;
+ std::ostringstream ostr;
ostr << str << " (" << pos << ")";
this->SetError(ostr.str());
}
diff --git a/Source/cmCommandArgumentParserHelper.h b/Source/cmCommandArgumentParserHelper.h
index f8c672fef..387afc639 100644
--- a/Source/cmCommandArgumentParserHelper.h
+++ b/Source/cmCommandArgumentParserHelper.h
@@ -77,16 +77,14 @@ public:
char BSLASHVariable[3];
private:
- cmStdString::size_type InputBufferPos;
- cmStdString InputBuffer;
+ std::string::size_type InputBufferPos;
+ std::string InputBuffer;
std::vector<char> OutputBuffer;
- int CurrentLine;
- int Verbose;
void Print(const char* place, const char* str);
void SafePrintMissing(const char* str, int line, int cnt);
- char* AddString(const char* str);
+ char* AddString(const std::string& str);
void CleanupParser();
void SetError(std::string const& msg);
@@ -94,12 +92,14 @@ private:
std::vector<char*> Variables;
const cmMakefile* Makefile;
std::string Result;
+ std::string ErrorString;
const char* FileName;
+ long FileLine;
+ int CurrentLine;
+ int Verbose;
bool WarnUninitialized;
bool CheckSystemVars;
- long FileLine;
bool EscapeQuotes;
- std::string ErrorString;
bool NoEscapeMode;
bool ReplaceAtSyntax;
bool RemoveEmpty;
diff --git a/Source/cmCommandArgumentsHelper.cxx b/Source/cmCommandArgumentsHelper.cxx
index 1d5fc0790..1a2efc672 100644
--- a/Source/cmCommandArgumentsHelper.cxx
+++ b/Source/cmCommandArgumentsHelper.cxx
@@ -50,13 +50,8 @@ void cmCommandArgument::FollowsGroup(const cmCommandArgumentGroup* group)
if (group!=0)
{
this->ArgumentsBeforeEmpty = false;
- for(std::vector<cmCommandArgument*>::const_iterator
- argIt= group->ContainedArguments.begin();
- argIt != group->ContainedArguments.end();
- ++argIt)
- {
- this->ArgumentsBefore.insert(*argIt);
- }
+ this->ArgumentsBefore.insert(group->ContainedArguments.begin(),
+ group->ContainedArguments.end());
}
}
diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
deleted file mode 100644
index 1e2a85cfb..000000000
--- a/Source/cmCommands.cxx
+++ /dev/null
@@ -1,86 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#include "cmCommands.h"
-#if defined(CMAKE_BUILD_WITH_CMAKE)
-#include "cmAddCompileOptionsCommand.cxx"
-#include "cmAuxSourceDirectoryCommand.cxx"
-#include "cmBuildNameCommand.cxx"
-#include "cmCMakeHostSystemInformationCommand.cxx"
-#include "cmElseIfCommand.cxx"
-#include "cmExportCommand.cxx"
-#include "cmExportLibraryDependencies.cxx"
-#include "cmFLTKWrapUICommand.cxx"
-#include "cmIncludeExternalMSProjectCommand.cxx"
-#include "cmInstallProgramsCommand.cxx"
-#include "cmLinkLibrariesCommand.cxx"
-#include "cmLoadCacheCommand.cxx"
-#include "cmOutputRequiredFilesCommand.cxx"
-#include "cmQTWrapCPPCommand.cxx"
-#include "cmQTWrapUICommand.cxx"
-#include "cmRemoveCommand.cxx"
-#include "cmRemoveDefinitionsCommand.cxx"
-#include "cmSourceGroupCommand.cxx"
-#include "cmSubdirDependsCommand.cxx"
-#include "cmTargetCompileDefinitionsCommand.cxx"
-#include "cmTargetCompileOptionsCommand.cxx"
-#include "cmTargetIncludeDirectoriesCommand.cxx"
-#include "cmTargetPropCommandBase.cxx"
-#include "cmUseMangledMesaCommand.cxx"
-#include "cmUtilitySourceCommand.cxx"
-#include "cmVariableRequiresCommand.cxx"
-#include "cmVariableWatchCommand.cxx"
-
-#include "cmWriteFileCommand.cxx"
-
-// This one must be last because it includes windows.h and
-// windows.h #defines GetCurrentDirectory which is a member
-// of cmMakefile
-#include "cmLoadCommandCommand.cxx"
-#endif
-
-void GetPredefinedCommands(std::list<cmCommand*>&
-#if defined(CMAKE_BUILD_WITH_CMAKE)
- commands
-#endif
- )
-{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
- commands.push_back(new cmAddCompileOptionsCommand);
- commands.push_back(new cmAuxSourceDirectoryCommand);
- commands.push_back(new cmBuildNameCommand);
- commands.push_back(new cmCMakeHostSystemInformationCommand);
- commands.push_back(new cmElseIfCommand);
- commands.push_back(new cmExportCommand);
- commands.push_back(new cmExportLibraryDependenciesCommand);
- commands.push_back(new cmFLTKWrapUICommand);
- commands.push_back(new cmIncludeExternalMSProjectCommand);
- commands.push_back(new cmInstallProgramsCommand);
- commands.push_back(new cmLinkLibrariesCommand);
- commands.push_back(new cmLoadCacheCommand);
- commands.push_back(new cmLoadCommandCommand);
- commands.push_back(new cmOutputRequiredFilesCommand);
- commands.push_back(new cmQTWrapCPPCommand);
- commands.push_back(new cmQTWrapUICommand);
- commands.push_back(new cmRemoveCommand);
- commands.push_back(new cmRemoveDefinitionsCommand);
- commands.push_back(new cmSourceGroupCommand);
- commands.push_back(new cmSubdirDependsCommand);
- commands.push_back(new cmTargetIncludeDirectoriesCommand);
- commands.push_back(new cmTargetCompileDefinitionsCommand);
- commands.push_back(new cmTargetCompileOptionsCommand);
- commands.push_back(new cmUseMangledMesaCommand);
- commands.push_back(new cmUtilitySourceCommand);
- commands.push_back(new cmVariableRequiresCommand);
- commands.push_back(new cmVariableWatchCommand);
- commands.push_back(new cmWriteFileCommand);
-#endif
-}
diff --git a/Source/cmCommands.cxx.in b/Source/cmCommands.cxx.in
new file mode 100644
index 000000000..e23bbd1e3
--- /dev/null
+++ b/Source/cmCommands.cxx.in
@@ -0,0 +1,19 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmCommands.h"
+
+@COMMAND_INCLUDES@
+
+void GetPredefinedCommands(std::vector<cmCommand*>& commands)
+{
+@NEW_COMMANDS@
+}
diff --git a/Source/cmCommands.h b/Source/cmCommands.h
index c56673fed..7a94423a4 100644
--- a/Source/cmCommands.h
+++ b/Source/cmCommands.h
@@ -13,6 +13,8 @@
#define cmCommands_h
#include "cmStandardIncludes.h"
+#include <vector>
+
class cmCommand;
/**
* Global function to return all compiled in commands.
@@ -21,9 +23,9 @@ class cmCommand;
* It is up to the caller to delete the commands created by this
* call.
*/
-void GetBootstrapCommands1(std::list<cmCommand*>& commands);
-void GetBootstrapCommands2(std::list<cmCommand*>& commands);
-void GetPredefinedCommands(std::list<cmCommand*>& commands);
+void GetBootstrapCommands1(std::vector<cmCommand*>& commands);
+void GetBootstrapCommands2(std::vector<cmCommand*>& commands);
+void GetPredefinedCommands(std::vector<cmCommand*>& commands);
#endif
diff --git a/Source/cmCommandsForBootstrap.cxx b/Source/cmCommandsForBootstrap.cxx
new file mode 100644
index 000000000..5f397a1fb
--- /dev/null
+++ b/Source/cmCommandsForBootstrap.cxx
@@ -0,0 +1,16 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmCommands.h"
+
+void GetPredefinedCommands(std::vector<cmCommand*>&)
+{
+}
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
new file mode 100644
index 000000000..76ed0387c
--- /dev/null
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -0,0 +1,428 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmCommonTargetGenerator.h"
+
+#include "cmComputeLinkInformation.h"
+#include "cmGeneratorTarget.h"
+#include "cmGlobalCommonGenerator.h"
+#include "cmLocalCommonGenerator.h"
+#include "cmMakefile.h"
+#include "cmSourceFile.h"
+#include "cmSystemTools.h"
+
+cmCommonTargetGenerator::cmCommonTargetGenerator(
+ cmOutputConverter::RelativeRoot wd,
+ cmGeneratorTarget* gt
+ )
+ : WorkingDirectory(wd)
+ , GeneratorTarget(gt)
+ , Makefile(gt->Makefile)
+ , LocalGenerator(static_cast<cmLocalCommonGenerator*>(gt->LocalGenerator))
+ , GlobalGenerator(static_cast<cmGlobalCommonGenerator*>(
+ gt->LocalGenerator->GetGlobalGenerator()))
+ , ConfigName(LocalGenerator->GetConfigName())
+ , ModuleDefinitionFile(GeneratorTarget->GetModuleDefinitionFile(ConfigName))
+ , FortranModuleDirectoryComputed(false)
+{
+}
+
+cmCommonTargetGenerator::~cmCommonTargetGenerator()
+{
+}
+
+std::string const& cmCommonTargetGenerator::GetConfigName() const
+{
+ return this->ConfigName;
+}
+
+std::string cmCommonTargetGenerator::Convert(
+ std::string const& source,
+ cmLocalGenerator::RelativeRoot relative,
+ cmLocalGenerator::OutputFormat output)
+{
+ return this->LocalGenerator->Convert(source, relative, output);
+}
+
+//----------------------------------------------------------------------------
+const char* cmCommonTargetGenerator::GetFeature(const std::string& feature)
+{
+ return this->GeneratorTarget->GetFeature(feature, this->ConfigName);
+}
+
+//----------------------------------------------------------------------------
+bool cmCommonTargetGenerator::GetFeatureAsBool(const std::string& feature)
+{
+ return this->GeneratorTarget->GetFeatureAsBool(feature, this->ConfigName);
+}
+
+//----------------------------------------------------------------------------
+void cmCommonTargetGenerator::AddFeatureFlags(
+ std::string& flags, const std::string& lang
+ )
+{
+ // Add language-specific flags.
+ this->LocalGenerator->AddLanguageFlags(flags, lang, this->ConfigName);
+
+ if(this->GetFeatureAsBool("INTERPROCEDURAL_OPTIMIZATION"))
+ {
+ this->LocalGenerator->AppendFeatureOptions(flags, lang, "IPO");
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmCommonTargetGenerator::AddModuleDefinitionFlag(std::string& flags)
+{
+ if(!this->ModuleDefinitionFile)
+ {
+ return;
+ }
+
+ // TODO: Create a per-language flag variable.
+ const char* defFileFlag =
+ this->Makefile->GetDefinition("CMAKE_LINK_DEF_FILE_FLAG");
+ if(!defFileFlag)
+ {
+ return;
+ }
+
+ // Append the flag and value. Use ConvertToLinkReference to help
+ // vs6's "cl -link" pass it to the linker.
+ std::string flag = defFileFlag;
+ flag += (this->LocalGenerator->ConvertToLinkReference(
+ this->ModuleDefinitionFile->GetFullPath()));
+ this->LocalGenerator->AppendFlags(flags, flag);
+}
+
+//----------------------------------------------------------------------------
+std::string cmCommonTargetGenerator::ComputeFortranModuleDirectory() const
+{
+ std::string mod_dir;
+ const char* target_mod_dir =
+ this->GeneratorTarget->GetProperty("Fortran_MODULE_DIRECTORY");
+ const char* moddir_flag =
+ this->Makefile->GetDefinition("CMAKE_Fortran_MODDIR_FLAG");
+ if(target_mod_dir && moddir_flag)
+ {
+ // Compute the full path to the module directory.
+ if(cmSystemTools::FileIsFullPath(target_mod_dir))
+ {
+ // Already a full path.
+ mod_dir = target_mod_dir;
+ }
+ else
+ {
+ // Interpret relative to the current output directory.
+ mod_dir = this->LocalGenerator->GetCurrentBinaryDirectory();
+ mod_dir += "/";
+ mod_dir += target_mod_dir;
+ }
+
+ // Make sure the module output directory exists.
+ cmSystemTools::MakeDirectory(mod_dir);
+ }
+ return mod_dir;
+}
+
+//----------------------------------------------------------------------------
+std::string cmCommonTargetGenerator::GetFortranModuleDirectory()
+{
+ // Compute the module directory.
+ if(!this->FortranModuleDirectoryComputed)
+ {
+ this->FortranModuleDirectoryComputed = true;
+ this->FortranModuleDirectory = this->ComputeFortranModuleDirectory();
+ }
+
+ // Return the computed directory.
+ return this->FortranModuleDirectory;
+}
+
+//----------------------------------------------------------------------------
+void cmCommonTargetGenerator::AddFortranFlags(std::string& flags)
+{
+ // Enable module output if necessary.
+ if(const char* modout_flag =
+ this->Makefile->GetDefinition("CMAKE_Fortran_MODOUT_FLAG"))
+ {
+ this->LocalGenerator->AppendFlags(flags, modout_flag);
+ }
+
+ // Add a module output directory flag if necessary.
+ std::string mod_dir = this->GetFortranModuleDirectory();
+ if (!mod_dir.empty())
+ {
+ mod_dir = this->Convert(mod_dir,
+ this->WorkingDirectory,
+ cmLocalGenerator::SHELL);
+ }
+ else
+ {
+ mod_dir =
+ this->Makefile->GetSafeDefinition("CMAKE_Fortran_MODDIR_DEFAULT");
+ }
+ if (!mod_dir.empty())
+ {
+ const char* moddir_flag =
+ this->Makefile->GetRequiredDefinition("CMAKE_Fortran_MODDIR_FLAG");
+ std::string modflag = moddir_flag;
+ modflag += mod_dir;
+ this->LocalGenerator->AppendFlags(flags, modflag);
+ }
+
+ // If there is a separate module path flag then duplicate the
+ // include path with it. This compiler does not search the include
+ // path for modules.
+ if(const char* modpath_flag =
+ this->Makefile->GetDefinition("CMAKE_Fortran_MODPATH_FLAG"))
+ {
+ std::vector<std::string> includes;
+ const std::string& config =
+ this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ this->LocalGenerator->GetIncludeDirectories(includes,
+ this->GeneratorTarget,
+ "C", config);
+ for(std::vector<std::string>::const_iterator idi = includes.begin();
+ idi != includes.end(); ++idi)
+ {
+ std::string flg = modpath_flag;
+ flg += this->Convert(*idi,
+ cmLocalGenerator::NONE,
+ cmLocalGenerator::SHELL);
+ this->LocalGenerator->AppendFlags(flags, flg);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmCommonTargetGenerator
+::AppendFortranFormatFlags(std::string& flags, cmSourceFile const& source)
+{
+ const char* srcfmt = source.GetProperty("Fortran_FORMAT");
+ cmLocalGenerator::FortranFormat format =
+ this->LocalGenerator->GetFortranFormat(srcfmt);
+ if(format == cmLocalGenerator::FortranFormatNone)
+ {
+ const char* tgtfmt = this->GeneratorTarget->GetProperty("Fortran_FORMAT");
+ format = this->LocalGenerator->GetFortranFormat(tgtfmt);
+ }
+ const char* var = 0;
+ switch (format)
+ {
+ case cmLocalGenerator::FortranFormatFixed:
+ var = "CMAKE_Fortran_FORMAT_FIXED_FLAG"; break;
+ case cmLocalGenerator::FortranFormatFree:
+ var = "CMAKE_Fortran_FORMAT_FREE_FLAG"; break;
+ default: break;
+ }
+ if(var)
+ {
+ this->LocalGenerator->AppendFlags(
+ flags, this->Makefile->GetDefinition(var));
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmCommonTargetGenerator::GetFrameworkFlags(std::string const& l)
+{
+ if(!this->Makefile->IsOn("APPLE"))
+ {
+ return std::string();
+ }
+
+ std::string fwSearchFlagVar = "CMAKE_" + l + "_FRAMEWORK_SEARCH_FLAG";
+ const char* fwSearchFlag =
+ this->Makefile->GetDefinition(fwSearchFlagVar);
+ if(!(fwSearchFlag && *fwSearchFlag))
+ {
+ return std::string();
+ }
+
+ std::set<std::string> emitted;
+#ifdef __APPLE__ /* don't insert this when crosscompiling e.g. to iphone */
+ emitted.insert("/System/Library/Frameworks");
+#endif
+ std::vector<std::string> includes;
+
+ const std::string& config =
+ this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ this->LocalGenerator->GetIncludeDirectories(includes,
+ this->GeneratorTarget,
+ "C", config);
+ // check all include directories for frameworks as this
+ // will already have added a -F for the framework
+ for(std::vector<std::string>::iterator i = includes.begin();
+ i != includes.end(); ++i)
+ {
+ if(this->GlobalGenerator->NameResolvesToFramework(*i))
+ {
+ std::string frameworkDir = *i;
+ frameworkDir += "/../";
+ frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir);
+ emitted.insert(frameworkDir);
+ }
+ }
+
+ std::string flags;
+ const char* cfg = this->LocalGenerator->GetConfigName().c_str();
+ if(cmComputeLinkInformation* cli =
+ this->GeneratorTarget->GetLinkInformation(cfg))
+ {
+ std::vector<std::string> const& frameworks = cli->GetFrameworkPaths();
+ for(std::vector<std::string>::const_iterator i = frameworks.begin();
+ i != frameworks.end(); ++i)
+ {
+ if(emitted.insert(*i).second)
+ {
+ flags += fwSearchFlag;
+ flags += this->LocalGenerator
+ ->ConvertToOutputFormat(*i, cmLocalGenerator::SHELL);
+ flags += " ";
+ }
+ }
+ }
+ return flags;
+}
+
+//----------------------------------------------------------------------------
+std::string cmCommonTargetGenerator::GetFlags(const std::string &l)
+{
+ ByLanguageMap::iterator i = this->FlagsByLanguage.find(l);
+ if (i == this->FlagsByLanguage.end())
+ {
+ std::string flags;
+ const char *lang = l.c_str();
+
+ // Add language feature flags.
+ this->AddFeatureFlags(flags, lang);
+
+ this->LocalGenerator->AddArchitectureFlags(flags, this->GeneratorTarget,
+ lang, this->ConfigName);
+
+ // Fortran-specific flags computed for this target.
+ if(l == "Fortran")
+ {
+ this->AddFortranFlags(flags);
+ }
+
+ this->LocalGenerator->AddCMP0018Flags(flags, this->GeneratorTarget,
+ lang, this->ConfigName);
+
+ this->LocalGenerator->AddVisibilityPresetFlags(flags,
+ this->GeneratorTarget,
+ lang);
+
+ // Append old-style preprocessor definition flags.
+ this->LocalGenerator->
+ AppendFlags(flags, this->Makefile->GetDefineFlags());
+
+ // Add framework directory flags.
+ this->LocalGenerator->
+ AppendFlags(flags,this->GetFrameworkFlags(l));
+
+ // Add target-specific flags.
+ this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget,
+ lang, this->ConfigName);
+
+ ByLanguageMap::value_type entry(l, flags);
+ i = this->FlagsByLanguage.insert(entry).first;
+ }
+ return i->second;
+}
+
+std::string cmCommonTargetGenerator::GetDefines(const std::string &l)
+{
+ ByLanguageMap::iterator i = this->DefinesByLanguage.find(l);
+ if (i == this->DefinesByLanguage.end())
+ {
+ std::set<std::string> defines;
+ const char *lang = l.c_str();
+ // Add the export symbol definition for shared library objects.
+ if(const char* exportMacro =
+ this->GeneratorTarget->GetExportMacro())
+ {
+ this->LocalGenerator->AppendDefines(defines, exportMacro);
+ }
+
+ // Add preprocessor definitions for this target and configuration.
+ this->LocalGenerator->AddCompileDefinitions(defines, this->GeneratorTarget,
+ this->LocalGenerator->GetConfigName(), l);
+
+ std::string definesString;
+ this->LocalGenerator->JoinDefines(defines, definesString, lang);
+
+ ByLanguageMap::value_type entry(l, definesString);
+ i = this->DefinesByLanguage.insert(entry).first;
+ }
+ return i->second;
+}
+
+std::string cmCommonTargetGenerator::GetIncludes(std::string const& l)
+{
+ ByLanguageMap::iterator i = this->IncludesByLanguage.find(l);
+ if (i == this->IncludesByLanguage.end())
+ {
+ std::string includes;
+ this->AddIncludeFlags(includes, l);
+ ByLanguageMap::value_type entry(l, includes);
+ i = this->IncludesByLanguage.insert(entry).first;
+ }
+ return i->second;
+}
+
+std::vector<std::string>
+cmCommonTargetGenerator::GetLinkedTargetDirectories() const
+{
+ std::vector<std::string> dirs;
+ std::set<cmGeneratorTarget const*> emitted;
+ if (cmComputeLinkInformation* cli =
+ this->GeneratorTarget->GetLinkInformation(this->ConfigName))
+ {
+ cmComputeLinkInformation::ItemVector const& items = cli->GetItems();
+ for(cmComputeLinkInformation::ItemVector::const_iterator
+ i = items.begin(); i != items.end(); ++i)
+ {
+ cmGeneratorTarget const* linkee = i->Target;
+ if(linkee && !linkee->IsImported()
+ // We can ignore the INTERFACE_LIBRARY items because
+ // Target->GetLinkInformation already processed their
+ // link interface and they don't have any output themselves.
+ && linkee->GetType() != cmState::INTERFACE_LIBRARY
+ && emitted.insert(linkee).second)
+ {
+ cmLocalGenerator* lg = linkee->GetLocalGenerator();
+ std::string di = lg->GetCurrentBinaryDirectory();
+ di += "/";
+ di += lg->GetTargetDirectory(linkee);
+ dirs.push_back(di);
+ }
+ }
+ }
+ return dirs;
+}
+
+std::string cmCommonTargetGenerator::GetManifests()
+{
+ std::vector<cmSourceFile const*> manifest_srcs;
+ this->GeneratorTarget->GetManifests(manifest_srcs, this->ConfigName);
+
+ std::vector<std::string> manifests;
+ for (std::vector<cmSourceFile const*>::iterator mi = manifest_srcs.begin();
+ mi != manifest_srcs.end(); ++mi)
+ {
+ manifests.push_back(this->Convert((*mi)->GetFullPath(),
+ this->WorkingDirectory,
+ cmOutputConverter::SHELL));
+ }
+
+ return cmJoin(manifests, " ");
+}
diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h
new file mode 100644
index 000000000..0c1750012
--- /dev/null
+++ b/Source/cmCommonTargetGenerator.h
@@ -0,0 +1,94 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmCommonTargetGenerator_h
+#define cmCommonTargetGenerator_h
+
+#include "cmStandardIncludes.h"
+
+#include "cmLocalGenerator.h"
+
+class cmGeneratorTarget;
+class cmGlobalCommonGenerator;
+class cmLocalCommonGenerator;
+class cmMakefile;
+class cmSourceFile;
+
+/** \class cmCommonTargetGenerator
+ * \brief Common infrastructure for Makefile and Ninja per-target generators
+ */
+class cmCommonTargetGenerator
+{
+public:
+ cmCommonTargetGenerator(cmOutputConverter::RelativeRoot wd,
+ cmGeneratorTarget* gt);
+ virtual ~cmCommonTargetGenerator();
+
+ std::string const& GetConfigName() const;
+
+protected:
+
+ // Add language feature flags.
+ void AddFeatureFlags(std::string& flags, const std::string& lang);
+
+ // Feature query methods.
+ const char* GetFeature(const std::string& feature);
+ bool GetFeatureAsBool(const std::string& feature);
+
+ // Helper to add flag for windows .def file.
+ void AddModuleDefinitionFlag(std::string& flags);
+
+ cmOutputConverter::RelativeRoot WorkingDirectory;
+ cmGeneratorTarget* GeneratorTarget;
+ cmMakefile* Makefile;
+ cmLocalCommonGenerator* LocalGenerator;
+ cmGlobalCommonGenerator* GlobalGenerator;
+ std::string ConfigName;
+
+ // The windows module definition source file (.def), if any.
+ cmSourceFile const* ModuleDefinitionFile;
+
+ // Target-wide Fortran module output directory.
+ bool FortranModuleDirectoryComputed;
+ std::string FortranModuleDirectory;
+ std::string GetFortranModuleDirectory();
+ virtual std::string ComputeFortranModuleDirectory() const;
+
+ // Compute target-specific Fortran language flags.
+ void AddFortranFlags(std::string& flags);
+
+ std::string Convert(std::string const& source,
+ cmLocalGenerator::RelativeRoot relative,
+ cmLocalGenerator::OutputFormat output =
+ cmLocalGenerator::UNCHANGED);
+
+ void AppendFortranFormatFlags(std::string& flags,
+ cmSourceFile const& source);
+
+ // Return the a string with -F flags on apple
+ std::string GetFrameworkFlags(std::string const& l);
+
+ virtual void AddIncludeFlags(std::string& flags,
+ std::string const& lang) = 0;
+
+ typedef std::map<std::string, std::string> ByLanguageMap;
+ std::string GetFlags(const std::string &l);
+ ByLanguageMap FlagsByLanguage;
+ std::string GetDefines(const std::string &l);
+ ByLanguageMap DefinesByLanguage;
+ std::string GetIncludes(std::string const& l);
+ ByLanguageMap IncludesByLanguage;
+ std::string GetManifests();
+
+ std::vector<std::string> GetLinkedTargetDirectories() const;
+};
+
+#endif
diff --git a/Source/cmComputeComponentGraph.h b/Source/cmComputeComponentGraph.h
index a2ce946c1..4dbac4a2e 100644
--- a/Source/cmComputeComponentGraph.h
+++ b/Source/cmComputeComponentGraph.h
@@ -67,17 +67,17 @@ private:
int Root;
int VisitIndex;
};
- int TarjanWalkId;
std::vector<int> TarjanVisited;
std::vector<int> TarjanComponents;
std::vector<TarjanEntry> TarjanEntries;
+ std::vector<NodeList> Components;
std::stack<int> TarjanStack;
+ int TarjanWalkId;
int TarjanIndex;
void Tarjan();
void TarjanVisit(int i);
// Connected components.
- std::vector<NodeList> Components;
};
#endif
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index dec2b54d1..13098ad5b 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -12,13 +12,12 @@
#include "cmComputeLinkDepends.h"
#include "cmComputeComponentGraph.h"
-#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
+#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmTarget.h"
#include "cmake.h"
-
-#include <cmsys/stl/algorithm>
+#include "cmAlgorithms.h"
#include <assert.h>
@@ -166,25 +165,29 @@ guaranteed to be acyclic.
The final list of items produced by this procedure consists of the
original user link line followed by minimal additional items needed to
-satisfy dependencies.
+satisfy dependencies. The final list is then filtered to de-duplicate
+items that we know the linker will re-use automatically (shared libs).
*/
//----------------------------------------------------------------------------
cmComputeLinkDepends
-::cmComputeLinkDepends(cmTarget* target, const char* config, cmTarget* head)
+::cmComputeLinkDepends(const cmGeneratorTarget* target,
+ const std::string& config)
{
// Store context information.
this->Target = target;
- this->HeadTarget = head;
- this->Makefile = this->Target->GetMakefile();
- this->LocalGenerator = this->Makefile->GetLocalGenerator();
- this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
+ this->Makefile = this->Target->Target->GetMakefile();
+ this->GlobalGenerator =
+ this->Target->GetLocalGenerator()->GetGlobalGenerator();
this->CMakeInstance = this->GlobalGenerator->GetCMakeInstance();
// The configuration being linked.
- this->Config = (config && *config)? config : 0;
- this->LinkType = this->Target->ComputeLinkType(this->Config);
+ this->HasConfig = !config.empty();
+ this->Config = (this->HasConfig)? config : std::string();
+ std::vector<std::string> debugConfigs =
+ this->Makefile->GetCMakeInstance()->GetDebugConfigs();
+ this->LinkType = CMP0003_ComputeLinkType(this->Config, debugConfigs);
// Enable debug mode if requested.
this->DebugMode = this->Makefile->IsOn("CMAKE_LINK_DEPENDS_DEBUG_MODE");
@@ -199,12 +202,7 @@ cmComputeLinkDepends
//----------------------------------------------------------------------------
cmComputeLinkDepends::~cmComputeLinkDepends()
{
- for(std::vector<DependSetList*>::iterator
- i = this->InferredDependSets.begin();
- i != this->InferredDependSets.end(); ++i)
- {
- delete *i;
- }
+ cmDeleteAll(this->InferredDependSets);
delete this->CCG;
}
@@ -253,7 +251,8 @@ cmComputeLinkDepends::Compute()
"---------------------------------------"
"---------------------------------------\n");
fprintf(stderr, "Link dependency analysis for target %s, config %s\n",
- this->Target->GetName(), this->Config?this->Config:"noconfig");
+ this->Target->GetName().c_str(),
+ this->HasConfig?this->Config.c_str():"noconfig");
this->DisplayConstraintGraph();
}
@@ -261,11 +260,26 @@ cmComputeLinkDepends::Compute()
this->OrderLinkEntires();
// Compute the final set of link entries.
- for(std::vector<int>::const_iterator li = this->FinalLinkOrder.begin();
- li != this->FinalLinkOrder.end(); ++li)
- {
- this->FinalLinkEntries.push_back(this->EntryList[*li]);
+ // Iterate in reverse order so we can keep only the last occurrence
+ // of a shared library.
+ std::set<int> emmitted;
+ for(std::vector<int>::const_reverse_iterator
+ li = this->FinalLinkOrder.rbegin(),
+ le = this->FinalLinkOrder.rend();
+ li != le; ++li)
+ {
+ int i = *li;
+ LinkEntry const& e = this->EntryList[i];
+ cmGeneratorTarget const* t = e.Target;
+ // Entries that we know the linker will re-use do not need to be repeated.
+ bool uniquify = t && t->GetType() == cmState::SHARED_LIBRARY;
+ if(!uniquify || emmitted.insert(i).second)
+ {
+ this->FinalLinkEntries.push_back(e);
+ }
}
+ // Reverse the resulting order since we iterated in reverse.
+ std::reverse(this->FinalLinkEntries.begin(), this->FinalLinkEntries.end());
// Display the final set.
if(this->DebugMode)
@@ -277,12 +291,12 @@ cmComputeLinkDepends::Compute()
}
//----------------------------------------------------------------------------
-std::map<cmStdString, int>::iterator
+std::map<std::string, int>::iterator
cmComputeLinkDepends::AllocateLinkEntry(std::string const& item)
{
- std::map<cmStdString, int>::value_type
+ std::map<std::string, int>::value_type
index_entry(item, static_cast<int>(this->EntryList.size()));
- std::map<cmStdString, int>::iterator
+ std::map<std::string, int>::iterator
lei = this->LinkEntryIndex.insert(index_entry).first;
this->EntryList.push_back(LinkEntry());
this->InferredDependSets.push_back(0);
@@ -291,11 +305,10 @@ cmComputeLinkDepends::AllocateLinkEntry(std::string const& item)
}
//----------------------------------------------------------------------------
-int cmComputeLinkDepends::AddLinkEntry(int depender_index,
- std::string const& item)
+int cmComputeLinkDepends::AddLinkEntry(cmLinkItem const& item)
{
// Check if the item entry has already been added.
- std::map<cmStdString, int>::iterator lei = this->LinkEntryIndex.find(item);
+ std::map<std::string, int>::iterator lei = this->LinkEntryIndex.find(item);
if(lei != this->LinkEntryIndex.end())
{
// Yes. We do not need to follow the item's dependencies again.
@@ -309,7 +322,7 @@ int cmComputeLinkDepends::AddLinkEntry(int depender_index,
int index = lei->second;
LinkEntry& entry = this->EntryList[index];
entry.Item = item;
- entry.Target = this->FindTargetToLink(depender_index, entry.Item.c_str());
+ entry.Target = item.Target;
entry.IsFlag = (!entry.Target && item[0] == '-' && item[1] != 'l' &&
item.substr(0, 10) != "-framework");
@@ -325,7 +338,7 @@ int cmComputeLinkDepends::AddLinkEntry(int depender_index,
// Look for an old-style <item>_LIB_DEPENDS variable.
std::string var = entry.Item;
var += "_LIB_DEPENDS";
- if(const char* val = this->Makefile->GetDefinition(var.c_str()))
+ if(const char* val = this->Makefile->GetDefinition(var))
{
// The item dependencies are known. Follow them.
BFSEntry qe = {index, val};
@@ -352,21 +365,28 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
if(entry.Target)
{
// Follow the target dependencies.
- if(cmTarget::LinkInterface const* iface =
- entry.Target->GetLinkInterface(this->Config, this->HeadTarget))
+ if(cmLinkInterface const* iface =
+ entry.Target->GetLinkInterface(this->Config, this->Target))
{
+ const bool isIface =
+ entry.Target->GetType() == cmState::INTERFACE_LIBRARY;
// This target provides its own link interface information.
this->AddLinkEntries(depender_index, iface->Libraries);
+ if (isIface)
+ {
+ return;
+ }
+
// Handle dependent shared libraries.
this->FollowSharedDeps(depender_index, iface);
// Support for CMP0003.
- for(std::vector<std::string>::const_iterator
+ for(std::vector<cmLinkItem>::const_iterator
oi = iface->WrongConfigLibraries.begin();
oi != iface->WrongConfigLibraries.end(); ++oi)
{
- this->CheckWrongConfigItem(depender_index, *oi);
+ this->CheckWrongConfigItem(*oi);
}
}
}
@@ -380,7 +400,7 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
//----------------------------------------------------------------------------
void
cmComputeLinkDepends
-::FollowSharedDeps(int depender_index, cmTarget::LinkInterface const* iface,
+::FollowSharedDeps(int depender_index, cmLinkInterface const* iface,
bool follow_interface)
{
// Follow dependencies if we have not followed them already.
@@ -398,9 +418,9 @@ cmComputeLinkDepends
void
cmComputeLinkDepends
::QueueSharedDependencies(int depender_index,
- std::vector<std::string> const& deps)
+ std::vector<cmLinkItem> const& deps)
{
- for(std::vector<std::string>::const_iterator li = deps.begin();
+ for(std::vector<cmLinkItem>::const_iterator li = deps.begin();
li != deps.end(); ++li)
{
SharedDepEntry qe;
@@ -414,7 +434,7 @@ cmComputeLinkDepends
void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
{
// Check if the target already has an entry.
- std::map<cmStdString, int>::iterator lei =
+ std::map<std::string, int>::iterator lei =
this->LinkEntryIndex.find(dep.Item);
if(lei == this->LinkEntryIndex.end())
{
@@ -424,8 +444,7 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
// Initialize the item entry.
LinkEntry& entry = this->EntryList[lei->second];
entry.Item = dep.Item;
- entry.Target = this->FindTargetToLink(dep.DependerIndex,
- dep.Item.c_str());
+ entry.Target = dep.Item.Target;
// This item was added specifically because it is a dependent
// shared library. It may get special treatment
@@ -444,8 +463,8 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
// Target items may have their own dependencies.
if(entry.Target)
{
- if(cmTarget::LinkInterface const* iface =
- entry.Target->GetLinkInterface(this->Config, this->HeadTarget))
+ if(cmLinkInterface const* iface =
+ entry.Target->GetLinkInterface(this->Config, this->Target))
{
// Follow public and private dependencies transitively.
this->FollowSharedDeps(index, iface, true);
@@ -464,25 +483,25 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index,
cmSystemTools::ExpandListArgument(value, deplist);
// Look for entries meant for this configuration.
- std::vector<std::string> actual_libs;
- cmTarget::LinkLibraryType llt = cmTarget::GENERAL;
+ std::vector<cmLinkItem> actual_libs;
+ cmTargetLinkLibraryType llt = GENERAL_LibraryType;
bool haveLLT = false;
for(std::vector<std::string>::const_iterator di = deplist.begin();
di != deplist.end(); ++di)
{
if(*di == "debug")
{
- llt = cmTarget::DEBUG;
+ llt = DEBUG_LibraryType;
haveLLT = true;
}
else if(*di == "optimized")
{
- llt = cmTarget::OPTIMIZED;
+ llt = OPTIMIZED_LibraryType;
haveLLT = true;
}
else if(*di == "general")
{
- llt = cmTarget::GENERAL;
+ llt = GENERAL_LibraryType;
haveLLT = true;
}
else if(!di->empty())
@@ -496,31 +515,33 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index,
{
std::string var = *di;
var += "_LINK_TYPE";
- if(const char* val = this->Makefile->GetDefinition(var.c_str()))
+ if(const char* val = this->Makefile->GetDefinition(var))
{
if(strcmp(val, "debug") == 0)
{
- llt = cmTarget::DEBUG;
+ llt = DEBUG_LibraryType;
}
else if(strcmp(val, "optimized") == 0)
{
- llt = cmTarget::OPTIMIZED;
+ llt = OPTIMIZED_LibraryType;
}
}
}
// If the library is meant for this link type then use it.
- if(llt == cmTarget::GENERAL || llt == this->LinkType)
+ if(llt == GENERAL_LibraryType || llt == this->LinkType)
{
- actual_libs.push_back(*di);
+ cmLinkItem item(*di, this->FindTargetToLink(depender_index, *di));
+ actual_libs.push_back(item);
}
else if(this->OldLinkDirMode)
{
- this->CheckWrongConfigItem(depender_index, *di);
+ cmLinkItem item(*di, this->FindTargetToLink(depender_index, *di));
+ this->CheckWrongConfigItem(item);
}
// Reset the link type until another explicit type is given.
- llt = cmTarget::GENERAL;
+ llt = GENERAL_LibraryType;
haveLLT = false;
}
}
@@ -533,39 +554,40 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index,
void cmComputeLinkDepends::AddDirectLinkEntries()
{
// Add direct link dependencies in this configuration.
- cmTarget::LinkImplementation const* impl =
- this->Target->GetLinkImplementation(this->Config, this->HeadTarget);
+ cmLinkImplementation const* impl =
+ this->Target->GetLinkImplementation(this->Config);
this->AddLinkEntries(-1, impl->Libraries);
- for(std::vector<std::string>::const_iterator
+ for(std::vector<cmLinkItem>::const_iterator
wi = impl->WrongConfigLibraries.begin();
wi != impl->WrongConfigLibraries.end(); ++wi)
{
- this->CheckWrongConfigItem(-1, *wi);
+ this->CheckWrongConfigItem(*wi);
}
}
//----------------------------------------------------------------------------
+template <typename T>
void
-cmComputeLinkDepends::AddLinkEntries(int depender_index,
- std::vector<std::string> const& libs)
+cmComputeLinkDepends::AddLinkEntries(
+ int depender_index, std::vector<T> const& libs)
{
// Track inferred dependency sets implied by this list.
std::map<int, DependSet> dependSets;
// Loop over the libraries linked directly by the depender.
- for(std::vector<std::string>::const_iterator li = libs.begin();
+ for(typename std::vector<T>::const_iterator li = libs.begin();
li != libs.end(); ++li)
{
// Skip entries that will resolve to the target getting linked or
// are empty.
- std::string item = this->Target->CheckCMP0004(*li);
+ cmLinkItem const& item = *li;
if(item == this->Target->GetName() || item.empty())
{
continue;
}
// Add a link entry for this item.
- int dependee_index = this->AddLinkEntry(depender_index, item);
+ int dependee_index = this->AddLinkEntry(*li);
// The dependee must come after the depender.
if(depender_index >= 0)
@@ -611,44 +633,21 @@ cmComputeLinkDepends::AddLinkEntries(int depender_index,
}
//----------------------------------------------------------------------------
-cmTarget* cmComputeLinkDepends::FindTargetToLink(int depender_index,
- const char* name)
+cmGeneratorTarget const*
+cmComputeLinkDepends::FindTargetToLink(int depender_index,
+ const std::string& name)
{
// Look for a target in the scope of the depender.
- cmMakefile* mf = this->Makefile;
+ cmGeneratorTarget const* from = this->Target;
if(depender_index >= 0)
{
- if(cmTarget* depender = this->EntryList[depender_index].Target)
+ if(cmGeneratorTarget const* depender =
+ this->EntryList[depender_index].Target)
{
- mf = depender->GetMakefile();
+ from = depender;
}
}
- cmTarget* tgt = mf->FindTargetToUse(name);
-
- // Skip targets that will not really be linked. This is probably a
- // name conflict between an external library and an executable
- // within the project.
- if(tgt && tgt->GetType() == cmTarget::EXECUTABLE &&
- !tgt->IsExecutableWithExports())
- {
- tgt = 0;
- }
-
- if(tgt && tgt->GetType() == cmTarget::OBJECT_LIBRARY)
- {
- cmOStringStream e;
- e << "Target \"" << this->Target->GetName() << "\" links to "
- "OBJECT library \"" << tgt->GetName() << "\" but this is not "
- "allowed. "
- "One may link only to STATIC or SHARED libraries, or to executables "
- "with the ENABLE_EXPORTS property set.";
- this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
- this->Target->GetBacktrace());
- tgt = 0;
- }
-
- // Return the target found, if any.
- return tgt;
+ return from->FindTargetToLink(name);
}
//----------------------------------------------------------------------------
@@ -674,18 +673,15 @@ void cmComputeLinkDepends::InferDependencies()
for(++i; i != sets->end(); ++i)
{
DependSet intersection;
- cmsys_stl::set_intersection
+ std::set_intersection
(common.begin(), common.end(), i->begin(), i->end(),
std::inserter(intersection, intersection.begin()));
common = intersection;
}
// Add the inferred dependencies to the graph.
- for(DependSet::const_iterator j = common.begin(); j != common.end(); ++j)
- {
- int dependee_index = *j;
- this->EntryConstraintGraph[depender_index].push_back(dependee_index);
- }
+ cmGraphEdgeList& edges = this->EntryConstraintGraph[depender_index];
+ edges.insert(edges.end(), common.begin(), common.end());
}
}
@@ -697,11 +693,10 @@ void cmComputeLinkDepends::CleanConstraintGraph()
{
// Sort the outgoing edges for each graph node so that the
// original order will be preserved as much as possible.
- cmsys_stl::sort(i->begin(), i->end());
+ std::sort(i->begin(), i->end());
// Make the edge list unique.
- EdgeList::iterator last = cmsys_stl::unique(i->begin(), i->end());
- i->erase(last, i->end());
+ i->erase(std::unique(i->begin(), i->end()), i->end());
}
}
@@ -709,15 +704,12 @@ void cmComputeLinkDepends::CleanConstraintGraph()
void cmComputeLinkDepends::DisplayConstraintGraph()
{
// Display the graph nodes and their edges.
- cmOStringStream e;
+ std::ostringstream e;
for(unsigned int i=0; i < this->EntryConstraintGraph.size(); ++i)
{
EdgeList const& nl = this->EntryConstraintGraph[i];
e << "item " << i << " is [" << this->EntryList[i].Item << "]\n";
- for(EdgeList::const_iterator j = nl.begin(); j != nl.end(); ++j)
- {
- e << " item " << *j << " must follow it\n";
- }
+ e << cmWrap(" item ", nl, " must follow it", "\n") << "\n";
}
fprintf(stderr, "%s\n", e.str().c_str());
}
@@ -942,10 +934,10 @@ int cmComputeLinkDepends::ComputeComponentCount(NodeList const& nl)
int count = 2;
for(NodeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni)
{
- if(cmTarget* target = this->EntryList[*ni].Target)
+ if(cmGeneratorTarget const* target = this->EntryList[*ni].Target)
{
- if(cmTarget::LinkInterface const* iface =
- target->GetLinkInterface(this->Config, this->HeadTarget))
+ if(cmLinkInterface const* iface =
+ target->GetLinkInterface(this->Config, this->Target))
{
if(iface->Multiplicity > count)
{
@@ -960,14 +952,14 @@ int cmComputeLinkDepends::ComputeComponentCount(NodeList const& nl)
//----------------------------------------------------------------------------
void cmComputeLinkDepends::DisplayFinalEntries()
{
- fprintf(stderr, "target [%s] links to:\n", this->Target->GetName());
+ fprintf(stderr, "target [%s] links to:\n", this->Target->GetName().c_str());
for(std::vector<LinkEntry>::const_iterator lei =
this->FinalLinkEntries.begin();
lei != this->FinalLinkEntries.end(); ++lei)
{
if(lei->Target)
{
- fprintf(stderr, " target [%s]\n", lei->Target->GetName());
+ fprintf(stderr, " target [%s]\n", lei->Target->GetName().c_str());
}
else
{
@@ -978,8 +970,7 @@ void cmComputeLinkDepends::DisplayFinalEntries()
}
//----------------------------------------------------------------------------
-void cmComputeLinkDepends::CheckWrongConfigItem(int depender_index,
- std::string const& item)
+void cmComputeLinkDepends::CheckWrongConfigItem(cmLinkItem const& item)
{
if(!this->OldLinkDirMode)
{
@@ -989,11 +980,8 @@ void cmComputeLinkDepends::CheckWrongConfigItem(int depender_index,
// For CMake 2.4 bug-compatibility we need to consider the output
// directories of targets linked in another configuration as link
// directories.
- if(cmTarget* tgt = this->FindTargetToLink(depender_index, item.c_str()))
+ if(item.Target && !item.Target->IsImported())
{
- if(!tgt->IsImported())
- {
- this->OldWrongConfigItems.insert(tgt);
- }
+ this->OldWrongConfigItems.insert(item.Target);
}
}
diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h
index 1d5d1b920..f10e4e435 100644
--- a/Source/cmComputeLinkDepends.h
+++ b/Source/cmComputeLinkDepends.h
@@ -13,7 +13,7 @@
#define cmComputeLinkDepends_h
#include "cmStandardIncludes.h"
-#include "cmTarget.h"
+#include "cmLinkItem.h"
#include "cmGraphAdjacencyList.h"
@@ -21,9 +21,8 @@
class cmComputeComponentGraph;
class cmGlobalGenerator;
-class cmLocalGenerator;
class cmMakefile;
-class cmTarget;
+class cmGeneratorTarget;
class cmake;
/** \class cmComputeLinkDepends
@@ -32,14 +31,15 @@ class cmake;
class cmComputeLinkDepends
{
public:
- cmComputeLinkDepends(cmTarget* target, const char* config, cmTarget *head);
+ cmComputeLinkDepends(cmGeneratorTarget const* target,
+ const std::string& config);
~cmComputeLinkDepends();
// Basic information about each link item.
struct LinkEntry
{
std::string Item;
- cmTarget* Target;
+ cmGeneratorTarget const* Target;
bool IsSharedDep;
bool IsFlag;
LinkEntry(): Item(), Target(0), IsSharedDep(false), IsFlag(false) {}
@@ -52,41 +52,32 @@ public:
EntryVector const& Compute();
void SetOldLinkDirMode(bool b);
- std::set<cmTarget*> const& GetOldWrongConfigItems() const
+ std::set<cmGeneratorTarget const*> const& GetOldWrongConfigItems() const
{ return this->OldWrongConfigItems; }
private:
// Context information.
- cmTarget* Target;
- cmTarget* HeadTarget;
+ cmGeneratorTarget const* Target;
cmMakefile* Makefile;
- cmLocalGenerator* LocalGenerator;
- cmGlobalGenerator* GlobalGenerator;
+ cmGlobalGenerator const* GlobalGenerator;
cmake* CMakeInstance;
- bool DebugMode;
-
- // Configuration information.
- const char* Config;
- cmTarget::LinkLibraryType LinkType;
-
- // Output information.
+ std::string Config;
EntryVector FinalLinkEntries;
- typedef cmTarget::LinkLibraryVectorType LinkLibraryVectorType;
-
- std::map<cmStdString, int>::iterator
+ std::map<std::string, int>::iterator
AllocateLinkEntry(std::string const& item);
- int AddLinkEntry(int depender_index, std::string const& item);
+ int AddLinkEntry(cmLinkItem const& item);
void AddVarLinkEntries(int depender_index, const char* value);
void AddDirectLinkEntries();
- void AddLinkEntries(int depender_index,
- std::vector<std::string> const& libs);
- cmTarget* FindTargetToLink(int depender_index, const char* name);
+ template <typename T>
+ void AddLinkEntries(int depender_index, std::vector<T> const& libs);
+ cmGeneratorTarget const* FindTargetToLink(int depender_index,
+ const std::string& name);
// One entry for each unique item.
std::vector<LinkEntry> EntryList;
- std::map<cmStdString, int> LinkEntryIndex;
+ std::map<std::string, int> LinkEntryIndex;
// BFS of initial dependencies.
struct BFSEntry
@@ -102,16 +93,16 @@ private:
// of the interface.
struct SharedDepEntry
{
- std::string Item;
+ cmLinkItem Item;
int DependerIndex;
};
std::queue<SharedDepEntry> SharedDepQueue;
std::set<int> SharedDepFollowed;
void FollowSharedDeps(int depender_index,
- cmTarget::LinkInterface const* iface,
+ cmLinkInterface const* iface,
bool follow_interface = false);
void QueueSharedDependencies(int depender_index,
- std::vector<std::string> const& deps);
+ std::vector<cmLinkItem> const& deps);
void HandleSharedDependency(SharedDepEntry const& dep);
// Dependency inferral for each link item.
@@ -132,7 +123,7 @@ private:
void OrderLinkEntires();
std::vector<char> ComponentVisited;
std::vector<int> ComponentOrder;
- int ComponentOrderId;
+
struct PendingComponent
{
// The real component id. Needed because the map is indexed by
@@ -159,11 +150,14 @@ private:
// Record of the original link line.
std::vector<int> OriginalEntries;
+ std::set<cmGeneratorTarget const*> OldWrongConfigItems;
+ void CheckWrongConfigItem(cmLinkItem const& item);
- // Compatibility help.
+ int ComponentOrderId;
+ cmTargetLinkLibraryType LinkType;
+ bool HasConfig;
+ bool DebugMode;
bool OldLinkDirMode;
- void CheckWrongConfigItem(int depender_index, std::string const& item);
- std::set<cmTarget*> OldWrongConfigItems;
};
#endif
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index fb7b5b67d..50d832438 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -14,11 +14,14 @@
#include "cmComputeLinkDepends.h"
#include "cmOrderDirectories.h"
-#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
+#include "cmGlobalGenerator.h"
+#include "cmState.h"
+#include "cmOutputConverter.h"
#include "cmMakefile.h"
-#include "cmTarget.h"
+#include "cmGeneratorTarget.h"
#include "cmake.h"
+#include "cmAlgorithms.h"
#include <ctype.h>
@@ -239,20 +242,19 @@ because this need be done only for shared libraries without soname-s.
//----------------------------------------------------------------------------
cmComputeLinkInformation
-::cmComputeLinkInformation(cmTarget* target, const char* config,
- cmTarget *headTarget)
+::cmComputeLinkInformation(const cmGeneratorTarget* target,
+ const std::string& config)
{
// Store context information.
this->Target = target;
- this->HeadTarget = headTarget;
- this->Makefile = this->Target->GetMakefile();
- this->LocalGenerator = this->Makefile->GetLocalGenerator();
- this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
+ this->Makefile = this->Target->Target->GetMakefile();
+ this->GlobalGenerator =
+ this->Target->GetLocalGenerator()->GetGlobalGenerator();
this->CMakeInstance = this->GlobalGenerator->GetCMakeInstance();
// Check whether to recognize OpenBSD-style library versioned names.
- this->OpenBSD = this->Makefile->GetCMakeInstance()
- ->GetPropertyAsBool("FIND_LIBRARY_USE_OPENBSD_VERSIONING");
+ this->OpenBSD = this->Makefile->GetState()
+ ->GetGlobalPropertyAsBool("FIND_LIBRARY_USE_OPENBSD_VERSIONING");
// The configuration being linked.
this->Config = config;
@@ -267,8 +269,8 @@ cmComputeLinkInformation
this->OrderDependentRPath = 0;
// Get the language used for linking this target.
- this->LinkLanguage = this->Target->GetLinkerLanguage(config, headTarget);
- if(!this->LinkLanguage)
+ this->LinkLanguage = this->Target->GetLinkerLanguage(config);
+ if(this->LinkLanguage.empty())
{
// The Compute method will do nothing, so skip the rest of the
// initialization.
@@ -288,12 +290,12 @@ cmComputeLinkInformation
// the program that will load it.
this->LoaderFlag = 0;
if(!this->UseImportLibrary &&
- this->Target->GetType() == cmTarget::MODULE_LIBRARY)
+ this->Target->GetType() == cmState::MODULE_LIBRARY)
{
std::string loader_flag_var = "CMAKE_SHARED_MODULE_LOADER_";
loader_flag_var += this->LinkLanguage;
loader_flag_var += "_FLAG";
- this->LoaderFlag = this->Makefile->GetDefinition(loader_flag_var.c_str());
+ this->LoaderFlag = this->Makefile->GetDefinition(loader_flag_var);
}
// Get options needed to link libraries.
@@ -306,10 +308,10 @@ cmComputeLinkInformation
// Get options needed to specify RPATHs.
this->RuntimeUseChrpath = false;
- if(this->Target->GetType() != cmTarget::STATIC_LIBRARY)
+ if(this->Target->GetType() != cmState::STATIC_LIBRARY)
{
const char* tType =
- ((this->Target->GetType() == cmTarget::EXECUTABLE)?
+ ((this->Target->GetType() == cmState::EXECUTABLE)?
"EXECUTABLE" : "SHARED_LIBRARY");
std::string rtVar = "CMAKE_";
rtVar += tType;
@@ -317,11 +319,12 @@ cmComputeLinkInformation
rtVar += this->LinkLanguage;
rtVar += "_FLAG";
std::string rtSepVar = rtVar + "_SEP";
- this->RuntimeFlag = this->Makefile->GetSafeDefinition(rtVar.c_str());
- this->RuntimeSep = this->Makefile->GetSafeDefinition(rtSepVar.c_str());
+ this->RuntimeFlag = this->Makefile->GetSafeDefinition(rtVar);
+ this->RuntimeSep = this->Makefile->GetSafeDefinition(rtSepVar);
this->RuntimeAlways =
(this->Makefile->
GetSafeDefinition("CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH"));
+
this->RuntimeUseChrpath = this->Target->IsChrpathUsed(config);
// Get options needed to help find dependent libraries.
@@ -330,7 +333,7 @@ cmComputeLinkInformation
rlVar += "_RPATH_LINK_";
rlVar += this->LinkLanguage;
rlVar += "_FLAG";
- this->RPathLinkFlag = this->Makefile->GetSafeDefinition(rlVar.c_str());
+ this->RPathLinkFlag = this->Makefile->GetSafeDefinition(rlVar);
}
// Check if we need to include the runtime search path at link time.
@@ -338,7 +341,7 @@ cmComputeLinkInformation
std::string var = "CMAKE_SHARED_LIBRARY_LINK_";
var += this->LinkLanguage;
var += "_WITH_RUNTIME_PATH";
- this->LinkWithRuntimePath = this->Makefile->IsOn(var.c_str());
+ this->LinkWithRuntimePath = this->Makefile->IsOn(var);
}
// Check the platform policy for missing soname case.
@@ -409,13 +412,14 @@ cmComputeLinkInformation
{
// Construct a mask to not bother with this behavior for link
// directories already specified by the user.
- std::vector<std::string> const& dirs = this->Target->GetLinkDirectories();
- for(std::vector<std::string>::const_iterator di = dirs.begin();
- di != dirs.end(); ++di)
- {
- this->OldLinkDirMask.insert(*di);
- }
+ std::vector<std::string> const& dirs =
+ this->Target->GetLinkDirectories();
+ this->OldLinkDirMask.insert(dirs.begin(), dirs.end());
}
+
+ this->CMP0060Warn =
+ this->Makefile->PolicyOptionalWarningEnabled(
+ "CMAKE_POLICY_WARNING_CMP0060");
}
//----------------------------------------------------------------------------
@@ -450,18 +454,7 @@ std::string cmComputeLinkInformation::GetRPathLinkString()
}
// Construct the linker runtime search path.
- std::string rpath_link;
- const char* sep = "";
- std::vector<std::string> const& dirs =
- this->OrderDependentRPath->GetOrderedDirectories();
- for(std::vector<std::string>::const_iterator di = dirs.begin();
- di != dirs.end(); ++di)
- {
- rpath_link += sep;
- sep = ":";
- rpath_link += *di;
- }
- return rpath_link;
+ return cmJoin(this->OrderDependentRPath->GetOrderedDirectories(), ":");
}
//----------------------------------------------------------------------------
@@ -477,7 +470,7 @@ std::vector<std::string> const& cmComputeLinkInformation::GetFrameworkPaths()
}
//----------------------------------------------------------------------------
-std::set<cmTarget*> const&
+const std::set<const cmGeneratorTarget*>&
cmComputeLinkInformation::GetSharedLibrariesLinked()
{
return this->SharedLibrariesLinked;
@@ -487,25 +480,25 @@ cmComputeLinkInformation::GetSharedLibrariesLinked()
bool cmComputeLinkInformation::Compute()
{
// Skip targets that do not link.
- if(!(this->Target->GetType() == cmTarget::EXECUTABLE ||
- this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
- this->Target->GetType() == cmTarget::MODULE_LIBRARY ||
- this->Target->GetType() == cmTarget::STATIC_LIBRARY))
+ if(!(this->Target->GetType() == cmState::EXECUTABLE ||
+ this->Target->GetType() == cmState::SHARED_LIBRARY ||
+ this->Target->GetType() == cmState::MODULE_LIBRARY ||
+ this->Target->GetType() == cmState::STATIC_LIBRARY))
{
return false;
}
// We require a link language for the target.
- if(!this->LinkLanguage)
+ if(this->LinkLanguage.empty())
{
cmSystemTools::
Error("CMake can not determine linker language for target: ",
- this->Target->GetName());
+ this->Target->GetName().c_str());
return false;
}
// Compute the ordered link line items.
- cmComputeLinkDepends cld(this->Target, this->Config, this->HeadTarget);
+ cmComputeLinkDepends cld(this->Target, this->Config);
cld.SetOldLinkDirMode(this->OldLinkDirMode);
cmComputeLinkDepends::EntryVector const& linkEntries = cld.Compute();
@@ -526,7 +519,8 @@ bool cmComputeLinkInformation::Compute()
// Restore the target link type so the correct system runtime
// libraries are found.
- const char* lss = this->Target->GetProperty("LINK_SEARCH_END_STATIC");
+ const char* lss =
+ this->Target->GetProperty("LINK_SEARCH_END_STATIC");
if(cmSystemTools::IsOn(lss))
{
this->SetCurrentLinkType(LinkStatic);
@@ -542,14 +536,15 @@ bool cmComputeLinkInformation::Compute()
// For CMake 2.4 bug-compatibility we need to consider the output
// directories of targets linked in another configuration as link
// directories.
- std::set<cmTarget*> const& wrongItems = cld.GetOldWrongConfigItems();
- for(std::set<cmTarget*>::const_iterator i = wrongItems.begin();
- i != wrongItems.end(); ++i)
+ std::set<cmGeneratorTarget const*> const& wrongItems =
+ cld.GetOldWrongConfigItems();
+ for(std::set<cmGeneratorTarget const*>::const_iterator i =
+ wrongItems.begin(); i != wrongItems.end(); ++i)
{
- cmTarget* tgt = *i;
+ cmGeneratorTarget const* tgt = *i;
bool implib =
(this->UseImportLibrary &&
- (tgt->GetType() == cmTarget::SHARED_LIBRARY));
+ (tgt->GetType() == cmState::SHARED_LIBRARY));
std::string lib = tgt->GetFullPath(this->Config , implib, true);
this->OldLinkDirItems.push_back(lib);
}
@@ -564,6 +559,21 @@ bool cmComputeLinkInformation::Compute()
// Add implicit language runtime libraries and directories.
this->AddImplicitLinkInfo();
+ if (!this->CMP0060WarnItems.empty())
+ {
+ std::ostringstream w;
+ w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0060) << "\n"
+ "Some library files are in directories implicitly searched by "
+ "the linker when invoked for " << this->LinkLanguage << ":\n"
+ " " << cmJoin(this->CMP0060WarnItems, "\n ") << "\n"
+ "For compatibility with older versions of CMake, the generated "
+ "link line will ask the linker to search for these by library "
+ "name."
+ ;
+ this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
+ this->Target->GetBacktrace());
+ }
+
return true;
}
@@ -571,8 +581,8 @@ bool cmComputeLinkInformation::Compute()
void cmComputeLinkInformation::AddImplicitLinkInfo()
{
// The link closure lists all languages whose implicit info is needed.
- cmTarget::LinkClosure const* lc=this->Target->GetLinkClosure(this->Config,
- this->HeadTarget);
+ cmGeneratorTarget::LinkClosure const* lc =
+ this->Target->GetLinkClosure(this->Config);
for(std::vector<std::string>::const_iterator li = lc->Languages.begin();
li != lc->Languages.end(); ++li)
{
@@ -592,7 +602,7 @@ void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang)
std::string libVar = "CMAKE_";
libVar += lang;
libVar += "_IMPLICIT_LINK_LIBRARIES";
- if(const char* libs = this->Makefile->GetDefinition(libVar.c_str()))
+ if(const char* libs = this->Makefile->GetDefinition(libVar))
{
std::vector<std::string> libsVec;
cmSystemTools::ExpandListArgument(libs, libsVec);
@@ -601,7 +611,7 @@ void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang)
{
if(this->ImplicitLinkLibs.find(*i) == this->ImplicitLinkLibs.end())
{
- this->AddItem(i->c_str(), 0);
+ this->AddItem(*i, 0);
}
}
}
@@ -611,7 +621,7 @@ void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang)
std::string dirVar = "CMAKE_";
dirVar += lang;
dirVar += "_IMPLICIT_LINK_DIRECTORIES";
- if(const char* dirs = this->Makefile->GetDefinition(dirVar.c_str()))
+ if(const char* dirs = this->Makefile->GetDefinition(dirVar))
{
std::vector<std::string> dirsVec;
cmSystemTools::ExpandListArgument(dirs, dirsVec);
@@ -620,10 +630,11 @@ void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang)
}
//----------------------------------------------------------------------------
-void cmComputeLinkInformation::AddItem(std::string const& item, cmTarget* tgt)
+void cmComputeLinkInformation::AddItem(std::string const& item,
+ cmGeneratorTarget const* tgt)
{
// Compute the proper name to use to link this library.
- const char* config = this->Config;
+ const std::string& config = this->Config;
bool impexe = (tgt && tgt->IsExecutableWithExports());
if(impexe && !this->UseImportLibrary && !this->LoaderFlag)
{
@@ -642,23 +653,31 @@ void cmComputeLinkInformation::AddItem(std::string const& item, cmTarget* tgt)
// platform. Add it now.
std::string linkItem;
linkItem = this->LoaderFlag;
+
std::string exe = tgt->GetFullPath(config, this->UseImportLibrary,
true);
linkItem += exe;
this->Items.push_back(Item(linkItem, true, tgt));
this->Depends.push_back(exe);
}
+ else if(tgt->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ // Add the interface library as an item so it can be considered as part
+ // of COMPATIBLE_INTERFACE_ enforcement. The generators will ignore
+ // this for the actual link line.
+ this->Items.push_back(Item(std::string(), true, tgt));
+ }
else
{
// Decide whether to use an import library.
bool implib =
(this->UseImportLibrary &&
- (impexe || tgt->GetType() == cmTarget::SHARED_LIBRARY));
+ (impexe || tgt->GetType() == cmState::SHARED_LIBRARY));
// Pass the full path to the target file.
std::string lib = tgt->GetFullPath(config, implib, true);
if(!this->LinkDependsNoShared ||
- tgt->GetType() != cmTarget::SHARED_LIBRARY)
+ tgt->GetType() != cmState::SHARED_LIBRARY)
{
this->Depends.push_back(lib);
}
@@ -672,7 +691,7 @@ void cmComputeLinkInformation::AddItem(std::string const& item, cmTarget* tgt)
// This is not a CMake target. Use the name given.
if(cmSystemTools::FileIsFullPath(item.c_str()))
{
- if(cmSystemTools::FileIsDirectory(item.c_str()))
+ if(cmSystemTools::FileIsDirectory(item))
{
// This is a directory.
this->AddDirectoryItem(item);
@@ -695,7 +714,7 @@ void cmComputeLinkInformation::AddItem(std::string const& item, cmTarget* tgt)
//----------------------------------------------------------------------------
void cmComputeLinkInformation::AddSharedDepItem(std::string const& item,
- cmTarget* tgt)
+ const cmGeneratorTarget* tgt)
{
// If dropping shared library dependencies, ignore them.
if(this->SharedDependencyMode == SharedDepModeNone)
@@ -709,7 +728,7 @@ void cmComputeLinkInformation::AddSharedDepItem(std::string const& item,
{
// The target will provide a full path. Make sure it is a shared
// library.
- if(tgt->GetType() != cmTarget::SHARED_LIBRARY)
+ if(tgt->GetType() != cmState::SHARED_LIBRARY)
{
return;
}
@@ -787,9 +806,8 @@ void cmComputeLinkInformation::AddSharedDepItem(std::string const& item,
void cmComputeLinkInformation::ComputeLinkTypeInfo()
{
// Check whether archives may actually be shared libraries.
- this->ArchivesMayBeShared =
- this->CMakeInstance->GetPropertyAsBool(
- "TARGET_ARCHIVES_MAY_BE_SHARED_LIBS");
+ this->ArchivesMayBeShared = this->CMakeInstance->GetState()
+ ->GetGlobalPropertyAsBool("TARGET_ARCHIVES_MAY_BE_SHARED_LIBS");
// First assume we cannot do link type stuff.
this->LinkTypeEnabled = false;
@@ -800,9 +818,9 @@ void cmComputeLinkInformation::ComputeLinkTypeInfo()
const char* target_type_str = 0;
switch(this->Target->GetType())
{
- case cmTarget::EXECUTABLE: target_type_str = "EXE"; break;
- case cmTarget::SHARED_LIBRARY: target_type_str = "SHARED_LIBRARY"; break;
- case cmTarget::MODULE_LIBRARY: target_type_str = "SHARED_MODULE"; break;
+ case cmState::EXECUTABLE: target_type_str = "EXE"; break;
+ case cmState::SHARED_LIBRARY: target_type_str = "SHARED_LIBRARY"; break;
+ case cmState::MODULE_LIBRARY: target_type_str = "SHARED_MODULE"; break;
default: break;
}
if(target_type_str)
@@ -813,7 +831,7 @@ void cmComputeLinkInformation::ComputeLinkTypeInfo()
static_link_type_flag_var += this->LinkLanguage;
static_link_type_flag_var += "_FLAGS";
static_link_type_flag =
- this->Makefile->GetDefinition(static_link_type_flag_var.c_str());
+ this->Makefile->GetDefinition(static_link_type_flag_var);
std::string shared_link_type_flag_var = "CMAKE_";
shared_link_type_flag_var += target_type_str;
@@ -821,7 +839,7 @@ void cmComputeLinkInformation::ComputeLinkTypeInfo()
shared_link_type_flag_var += this->LinkLanguage;
shared_link_type_flag_var += "_FLAGS";
shared_link_type_flag =
- this->Makefile->GetDefinition(shared_link_type_flag_var.c_str());
+ this->Makefile->GetDefinition(shared_link_type_flag_var);
}
// We can support link type switching only if all needed flags are
@@ -835,7 +853,8 @@ void cmComputeLinkInformation::ComputeLinkTypeInfo()
}
// Lookup the starting link type from the target (linked statically?).
- const char* lss = this->Target->GetProperty("LINK_SEARCH_START_STATIC");
+ const char* lss =
+ this->Target->GetProperty("LINK_SEARCH_START_STATIC");
this->StartLinkType = cmSystemTools::IsOn(lss)? LinkStatic : LinkShared;
this->CurrentLinkType = this->StartLinkType;
}
@@ -896,7 +915,7 @@ void cmComputeLinkInformation::ComputeItemParserInfo()
// be the library name. Match index 3 will be the library
// extension.
reg = "^(";
- for(std::set<cmStdString>::iterator p = this->LinkPrefixes.begin();
+ for(std::set<std::string>::iterator p = this->LinkPrefixes.begin();
p != this->LinkPrefixes.end(); ++p)
{
reg += *p;
@@ -1057,7 +1076,7 @@ void cmComputeLinkInformation::SetCurrentLinkType(LinkType lt)
//----------------------------------------------------------------------------
void cmComputeLinkInformation::AddTargetItem(std::string const& item,
- cmTarget* target)
+ cmGeneratorTarget const* target)
{
// This is called to handle a link item that is a full path to a target.
// If the target is not a static library make sure the link type is
@@ -1065,13 +1084,13 @@ void cmComputeLinkInformation::AddTargetItem(std::string const& item,
// shared and static libraries but static-mode can handle only
// static libraries. If a previous user item changed the link type
// to static we need to make sure it is back to shared.
- if(target->GetType() != cmTarget::STATIC_LIBRARY)
+ if(target->GetType() != cmState::STATIC_LIBRARY)
{
this->SetCurrentLinkType(LinkShared);
}
// Keep track of shared library targets linked.
- if(target->GetType() == cmTarget::SHARED_LIBRARY)
+ if(target->GetType() == cmState::SHARED_LIBRARY)
{
this->SharedLibrariesLinked.insert(target);
}
@@ -1120,9 +1139,10 @@ void cmComputeLinkInformation::AddFullItem(std::string const& item)
// Full path libraries should specify a valid library file name.
// See documentation of CMP0008.
+ std::string generator = this->GlobalGenerator->GetName();
if(this->Target->GetPolicyStatusCMP0008() != cmPolicies::NEW &&
- (strstr(this->GlobalGenerator->GetName(), "Visual Studio") ||
- strstr(this->GlobalGenerator->GetName(), "Xcode")))
+ (generator.find("Visual Studio") != generator.npos ||
+ generator.find("Xcode") != generator.npos))
{
std::string file = cmSystemTools::GetFilenameName(item);
if(!this->ExtractAnyLibraryName.find(file.c_str()))
@@ -1200,6 +1220,28 @@ bool cmComputeLinkInformation::CheckImplicitDirItem(std::string const& item)
return false;
}
+ // Check the policy for whether we should use the approach below.
+ switch (this->Target->GetPolicyStatusCMP0060())
+ {
+ case cmPolicies::WARN:
+ if (this->CMP0060Warn)
+ {
+ // Print the warning at most once for this item.
+ std::string const& wid = "CMP0060-WARNING-GIVEN-" + item;
+ if (!this->CMakeInstance->GetPropertyAsBool(wid))
+ {
+ this->CMakeInstance->SetProperty(wid, "1");
+ this->CMP0060WarnItems.insert(item);
+ }
+ }
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::NEW:
+ return false;
+ }
+
// Many system linkers support multiple architectures by
// automatically selecting the implicit linker search path for the
// current architecture. If the library appears in an implicit link
@@ -1338,7 +1380,7 @@ void cmComputeLinkInformation::AddFrameworkItem(std::string const& item)
// Try to separate the framework name and path.
if(!this->SplitFramework.find(item.c_str()))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Could not parse framework path \"" << item << "\" "
<< "linked by target " << this->Target->GetName() << ".";
cmSystemTools::Error(e.str().c_str());
@@ -1362,7 +1404,8 @@ void cmComputeLinkInformation::AddFrameworkItem(std::string const& item)
// Add the item using the -framework option.
this->Items.push_back(Item("-framework", false));
- fw = this->LocalGenerator->EscapeForShell(fw.c_str());
+ cmOutputConverter converter(this->Makefile->GetStateSnapshot());
+ fw = converter.EscapeForShell(fw);
this->Items.push_back(Item(fw, false));
}
@@ -1385,7 +1428,7 @@ void cmComputeLinkInformation::DropDirectoryItem(std::string const& item)
{
// A full path to a directory was found as a link item. Warn the
// user.
- cmOStringStream e;
+ std::ostringstream e;
e << "WARNING: Target \"" << this->Target->GetName()
<< "\" requests linking to directory \"" << item << "\". "
<< "Targets may link only to libraries. "
@@ -1411,16 +1454,13 @@ void cmComputeLinkInformation::ComputeFrameworkInfo()
implicitDirVar += this->LinkLanguage;
implicitDirVar += "_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES";
if(const char* implicitDirs =
- this->Makefile->GetDefinition(implicitDirVar.c_str()))
+ this->Makefile->GetDefinition(implicitDirVar))
{
cmSystemTools::ExpandListArgument(implicitDirs, implicitDirVec);
}
- for(std::vector<std::string>::const_iterator i = implicitDirVec.begin();
- i != implicitDirVec.end(); ++i)
- {
- this->FrameworkPathsEmmitted.insert(*i);
- }
+ this->FrameworkPathsEmmitted.insert(implicitDirVec.begin(),
+ implicitDirVec.end());
// Regular expression to extract a framework path and name.
this->SplitFramework.compile("(.*)/(.*)\\.framework$");
@@ -1498,17 +1538,17 @@ void cmComputeLinkInformation::HandleBadFullItem(std::string const& item,
// Print the warning at most once for this item.
std::string wid = "CMP0008-WARNING-GIVEN-";
wid += item;
- if(!this->CMakeInstance->GetPropertyAsBool(wid.c_str()))
+ if(!this->CMakeInstance->GetState()
+ ->GetGlobalPropertyAsBool(wid))
{
- this->CMakeInstance->SetProperty(wid.c_str(), "1");
- cmOStringStream w;
- w << (this->Makefile->GetPolicies()
- ->GetPolicyWarning(cmPolicies::CMP0008)) << "\n"
+ this->CMakeInstance->GetState()->SetGlobalProperty(wid, "1");
+ std::ostringstream w;
+ w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0008) << "\n"
<< "Target \"" << this->Target->GetName() << "\" links to item\n"
<< " " << item << "\n"
<< "which is a full-path but not a valid library file name.";
this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
- this->Target->GetBacktrace());
+ this->Target->GetBacktrace());
}
}
case cmPolicies::OLD:
@@ -1520,9 +1560,8 @@ void cmComputeLinkInformation::HandleBadFullItem(std::string const& item,
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
{
- cmOStringStream e;
- e << (this->Makefile->GetPolicies()->
- GetRequiredPolicyError(cmPolicies::CMP0008)) << "\n"
+ std::ostringstream e;
+ e << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0008) << "\n"
<< "Target \"" << this->Target->GetName() << "\" links to item\n"
<< " " << item << "\n"
<< "which is a full-path but not a valid library file name.";
@@ -1547,13 +1586,15 @@ bool cmComputeLinkInformation::FinishLinkerSearchDirectories()
switch(this->Target->GetPolicyStatusCMP0003())
{
case cmPolicies::WARN:
- if(!this->CMakeInstance->GetPropertyAsBool("CMP0003-WARNING-GIVEN"))
+ if(!this->CMakeInstance->GetState()
+ ->GetGlobalPropertyAsBool("CMP0003-WARNING-GIVEN"))
{
- this->CMakeInstance->SetProperty("CMP0003-WARNING-GIVEN", "1");
- cmOStringStream w;
+ this->CMakeInstance->GetState()
+ ->SetGlobalProperty("CMP0003-WARNING-GIVEN", "1");
+ std::ostringstream w;
this->PrintLinkPolicyDiagnosis(w);
this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
- this->Target->GetBacktrace());
+ this->Target->GetBacktrace());
}
case cmPolicies::OLD:
// OLD behavior is to add the paths containing libraries with
@@ -1565,9 +1606,8 @@ bool cmComputeLinkInformation::FinishLinkerSearchDirectories()
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
{
- cmOStringStream e;
- e << (this->Makefile->GetPolicies()->
- GetRequiredPolicyError(cmPolicies::CMP0003)) << "\n";
+ std::ostringstream e;
+ e << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0003) << "\n";
this->PrintLinkPolicyDiagnosis(e);
this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
this->Target->GetBacktrace());
@@ -1634,7 +1674,7 @@ void cmComputeLinkInformation::PrintLinkPolicyDiagnosis(std::ostream& os)
// List the paths old behavior is adding.
os << "and other libraries with known full path:\n";
- std::set<cmStdString> emitted;
+ std::set<std::string> emitted;
for(std::vector<std::string>::const_iterator
i = this->OldLinkDirItems.begin();
i != this->OldLinkDirItems.end(); ++i)
@@ -1684,17 +1724,13 @@ void cmComputeLinkInformation::LoadImplicitLinkInfo()
implicitDirVar += this->LinkLanguage;
implicitDirVar += "_IMPLICIT_LINK_DIRECTORIES";
if(const char* implicitDirs =
- this->Makefile->GetDefinition(implicitDirVar.c_str()))
+ this->Makefile->GetDefinition(implicitDirVar))
{
cmSystemTools::ExpandListArgument(implicitDirs, implicitDirVec);
}
// Store implicit link directories.
- for(std::vector<std::string>::const_iterator i = implicitDirVec.begin();
- i != implicitDirVec.end(); ++i)
- {
- this->ImplicitLinkDirs.insert(*i);
- }
+ this->ImplicitLinkDirs.insert(implicitDirVec.begin(), implicitDirVec.end());
// Get language-specific implicit libraries.
std::vector<std::string> implicitLibVec;
@@ -1702,7 +1738,7 @@ void cmComputeLinkInformation::LoadImplicitLinkInfo()
implicitLibVar += this->LinkLanguage;
implicitLibVar += "_IMPLICIT_LINK_LIBRARIES";
if(const char* implicitLibs =
- this->Makefile->GetDefinition(implicitLibVar.c_str()))
+ this->Makefile->GetDefinition(implicitLibVar))
{
cmSystemTools::ExpandListArgument(implicitLibs, implicitLibVec);
}
@@ -1739,14 +1775,14 @@ cmComputeLinkInformation::GetRuntimeSearchPath()
//----------------------------------------------------------------------------
void
cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath,
- cmTarget* target)
+ cmGeneratorTarget const* target)
{
// Ignore targets on Apple where install_name is not @rpath.
// The dependenty library can be found with other means such as
// @loader_path or full paths.
if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
{
- if(!target->HasMacOSXRpath(this->Config))
+ if(!target->HasMacOSXRpathInstallNameDir(this->Config))
{
return;
}
@@ -1754,14 +1790,14 @@ cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath,
// Libraries with unknown type must be handled using just the file
// on disk.
- if(target->GetType() == cmTarget::UNKNOWN_LIBRARY)
+ if(target->GetType() == cmState::UNKNOWN_LIBRARY)
{
this->AddLibraryRuntimeInfo(fullPath);
return;
}
// Skip targets that are not shared libraries (modules cannot be linked).
- if(target->GetType() != cmTarget::SHARED_LIBRARY)
+ if(target->GetType() != cmState::SHARED_LIBRARY)
{
return;
}
@@ -1803,7 +1839,7 @@ cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath)
}
}
- is_shared_library = this->ExtractSharedLibraryName.find(file.c_str());
+ is_shared_library = this->ExtractSharedLibraryName.find(file);
if(!is_shared_library)
{
@@ -1823,8 +1859,8 @@ cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath)
{
if(fullPath.find(".framework") != std::string::npos)
{
- cmsys::RegularExpression splitFramework;
- splitFramework.compile("^(.*)/(.*).framework/(.*)$");
+ static cmsys::RegularExpression
+ splitFramework("^(.*)/(.*).framework/(.*)$");
if(splitFramework.find(fullPath) &&
(std::string::npos !=
splitFramework.match(3).find(splitFramework.match(2))))
@@ -1850,7 +1886,7 @@ cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath)
//----------------------------------------------------------------------------
static void cmCLI_ExpandListUnique(const char* str,
std::vector<std::string>& out,
- std::set<cmStdString>& emitted)
+ std::set<std::string>& emitted)
{
std::vector<std::string> tmp;
cmSystemTools::ExpandListArgument(str, tmp);
@@ -1888,14 +1924,21 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
this->Target->GetPropertyAsBool("INSTALL_RPATH_USE_LINK_PATH");
// Construct the RPATH.
- std::set<cmStdString> emitted;
+ std::set<std::string> emitted;
if(use_install_rpath)
{
- const char* install_rpath = this->Target->GetProperty("INSTALL_RPATH");
+ const char* install_rpath =
+ this->Target->GetProperty("INSTALL_RPATH");
cmCLI_ExpandListUnique(install_rpath, runtimeDirs, emitted);
}
if(use_build_rpath || use_link_rpath)
{
+ std::string rootPath = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT");
+ const char *stagePath
+ = this->Makefile->GetDefinition("CMAKE_STAGING_PREFIX");
+ const char *installPrefix
+ = this->Makefile->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
+ cmSystemTools::ConvertToUnixSlashes(rootPath);
std::vector<std::string> const& rdirs = this->GetRuntimeSearchPath();
for(std::vector<std::string>::const_iterator ri = rdirs.begin();
ri != rdirs.end(); ++ri)
@@ -1904,24 +1947,51 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
// support or if using the link path as an rpath.
if(use_build_rpath)
{
- if(emitted.insert(*ri).second)
+ std::string d = *ri;
+ if (!rootPath.empty() && d.find(rootPath) == 0)
{
- runtimeDirs.push_back(*ri);
+ d = d.substr(rootPath.size());
+ }
+ else if (stagePath && *stagePath && d.find(stagePath) == 0)
+ {
+ std::string suffix = d.substr(strlen(stagePath));
+ d = installPrefix;
+ d += "/";
+ d += suffix;
+ cmSystemTools::ConvertToUnixSlashes(d);
+ }
+ if(emitted.insert(d).second)
+ {
+ runtimeDirs.push_back(d);
}
}
else if(use_link_rpath)
{
// Do not add any path inside the source or build tree.
- const char* topSourceDir = this->Makefile->GetHomeDirectory();
- const char* topBinaryDir = this->Makefile->GetHomeOutputDirectory();
- if(!cmSystemTools::ComparePath(ri->c_str(), topSourceDir) &&
- !cmSystemTools::ComparePath(ri->c_str(), topBinaryDir) &&
- !cmSystemTools::IsSubDirectory(ri->c_str(), topSourceDir) &&
- !cmSystemTools::IsSubDirectory(ri->c_str(), topBinaryDir))
+ const char* topSourceDir = this->CMakeInstance->GetHomeDirectory();
+ const char* topBinaryDir =
+ this->CMakeInstance->GetHomeOutputDirectory();
+ if(!cmSystemTools::ComparePath(*ri, topSourceDir) &&
+ !cmSystemTools::ComparePath(*ri, topBinaryDir) &&
+ !cmSystemTools::IsSubDirectory(*ri, topSourceDir) &&
+ !cmSystemTools::IsSubDirectory(*ri, topBinaryDir))
{
- if(emitted.insert(*ri).second)
+ std::string d = *ri;
+ if (!rootPath.empty() && d.find(rootPath) == 0)
{
- runtimeDirs.push_back(*ri);
+ d = d.substr(rootPath.size());
+ }
+ else if (stagePath && *stagePath && d.find(stagePath) == 0)
+ {
+ std::string suffix = d.substr(strlen(stagePath));
+ d = installPrefix;
+ d += "/";
+ d += suffix;
+ cmSystemTools::ConvertToUnixSlashes(d);
+ }
+ if(emitted.insert(d).second)
+ {
+ runtimeDirs.push_back(d);
}
}
}
@@ -1931,18 +2001,18 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
// Add runtime paths required by the languages to always be
// present. This is done even when skipping rpath support.
{
- cmTarget::LinkClosure const* lc =
- this->Target->GetLinkClosure(this->Config, this->HeadTarget);
+ cmGeneratorTarget::LinkClosure const* lc =
+ this->Target->GetLinkClosure(this->Config);
for(std::vector<std::string>::const_iterator li = lc->Languages.begin();
li != lc->Languages.end(); ++li)
{
std::string useVar = "CMAKE_" + *li +
"_USE_IMPLICIT_LINK_DIRECTORIES_IN_RUNTIME_PATH";
- if(this->Makefile->IsOn(useVar.c_str()))
+ if(this->Makefile->IsOn(useVar))
{
std::string dirVar = "CMAKE_" + *li +
"_IMPLICIT_LINK_DIRECTORIES";
- if(const char* dirs = this->Makefile->GetDefinition(dirVar.c_str()))
+ if(const char* dirs = this->Makefile->GetDefinition(dirVar))
{
cmCLI_ExpandListUnique(dirs, runtimeDirs, emitted);
}
@@ -1963,18 +2033,7 @@ std::string cmComputeLinkInformation::GetRPathString(bool for_install)
this->GetRPath(runtimeDirs, for_install);
// Concatenate the paths.
- std::string rpath;
- const char* sep = "";
- for(std::vector<std::string>::const_iterator ri = runtimeDirs.begin();
- ri != runtimeDirs.end(); ++ri)
- {
- // Separate from previous path.
- rpath += sep;
- sep = this->GetRuntimeSep().c_str();
-
- // Add this path.
- rpath += *ri;
- }
+ std::string rpath = cmJoin(runtimeDirs, this->GetRuntimeSep());
// If the rpath will be replaced at install time, prepare space.
if(!for_install && this->RuntimeUseChrpath)
diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h
index e6ee87185..5eecf7dcb 100644
--- a/Source/cmComputeLinkInformation.h
+++ b/Source/cmComputeLinkInformation.h
@@ -18,9 +18,8 @@
class cmake;
class cmGlobalGenerator;
-class cmLocalGenerator;
class cmMakefile;
-class cmTarget;
+class cmGeneratorTarget;
class cmOrderDirectories;
/** \class cmComputeLinkInformation
@@ -29,8 +28,8 @@ class cmOrderDirectories;
class cmComputeLinkInformation
{
public:
- cmComputeLinkInformation(cmTarget* target, const char* config,
- cmTarget* headTarget);
+ cmComputeLinkInformation(cmGeneratorTarget const* target,
+ const std::string& config);
~cmComputeLinkInformation();
bool Compute();
@@ -39,31 +38,31 @@ public:
Item(): Value(), IsPath(true), Target(0) {}
Item(Item const& item):
Value(item.Value), IsPath(item.IsPath), Target(item.Target) {}
- Item(std::string const& v, bool p, cmTarget* target = 0):
+ Item(std::string const& v, bool p, cmGeneratorTarget const* target = 0):
Value(v), IsPath(p), Target(target) {}
std::string Value;
bool IsPath;
- cmTarget* Target;
+ cmGeneratorTarget const* Target;
};
typedef std::vector<Item> ItemVector;
ItemVector const& GetItems();
std::vector<std::string> const& GetDirectories();
std::vector<std::string> const& GetDepends();
std::vector<std::string> const& GetFrameworkPaths();
- const char* GetLinkLanguage() const { return this->LinkLanguage; }
+ std::string GetLinkLanguage() const { return this->LinkLanguage; }
std::vector<std::string> const& GetRuntimeSearchPath();
std::string const& GetRuntimeFlag() const { return this->RuntimeFlag; }
std::string const& GetRuntimeSep() const { return this->RuntimeSep; }
void GetRPath(std::vector<std::string>& runtimeDirs, bool for_install);
std::string GetRPathString(bool for_install);
std::string GetChrpathString();
- std::set<cmTarget*> const& GetSharedLibrariesLinked();
+ std::set<cmGeneratorTarget const*> const& GetSharedLibrariesLinked();
std::string const& GetRPathLinkFlag() const { return this->RPathLinkFlag; }
std::string GetRPathLinkString();
private:
- void AddItem(std::string const& item, cmTarget* tgt);
- void AddSharedDepItem(std::string const& item, cmTarget* tgt);
+ void AddItem(std::string const& item, const cmGeneratorTarget* tgt);
+ void AddSharedDepItem(std::string const& item, cmGeneratorTarget const* tgt);
// Output information.
ItemVector Items;
@@ -71,20 +70,17 @@ private:
std::vector<std::string> Depends;
std::vector<std::string> FrameworkPaths;
std::vector<std::string> RuntimeSearchPath;
- std::set<cmTarget*> SharedLibrariesLinked;
+ std::set<cmGeneratorTarget const*> SharedLibrariesLinked;
// Context information.
- cmTarget* Target;
- cmTarget* HeadTarget;
+ cmGeneratorTarget const* Target;
cmMakefile* Makefile;
- cmLocalGenerator* LocalGenerator;
cmGlobalGenerator* GlobalGenerator;
cmake* CMakeInstance;
// Configuration information.
- const char* Config;
- const char* LinkLanguage;
- bool LinkDependsNoShared;
+ std::string Config;
+ std::string LinkLanguage;
// Modes for dealing with dependent shared libraries.
enum SharedDepMode
@@ -95,8 +91,6 @@ private:
SharedDepModeLink // List file on link line
};
- // System info.
- bool UseImportLibrary;
const char* LoaderFlag;
std::string LibLinkFlag;
std::string LibLinkFileFlag;
@@ -104,34 +98,29 @@ private:
std::string RuntimeFlag;
std::string RuntimeSep;
std::string RuntimeAlways;
- bool RuntimeUseChrpath;
- bool NoSONameUsesPath;
- bool LinkWithRuntimePath;
std::string RPathLinkFlag;
SharedDepMode SharedDependencyMode;
+ enum LinkType { LinkUnknown, LinkStatic, LinkShared };
+ void SetCurrentLinkType(LinkType lt);
+
// Link type adjustment.
void ComputeLinkTypeInfo();
- enum LinkType { LinkUnknown, LinkStatic, LinkShared };
LinkType StartLinkType;
LinkType CurrentLinkType;
std::string StaticLinkTypeFlag;
std::string SharedLinkTypeFlag;
- bool LinkTypeEnabled;
- void SetCurrentLinkType(LinkType lt);
- bool ArchivesMayBeShared;
// Link item parsing.
void ComputeItemParserInfo();
std::vector<std::string> StaticLinkExtensions;
std::vector<std::string> SharedLinkExtensions;
std::vector<std::string> LinkExtensions;
- std::set<cmStdString> LinkPrefixes;
+ std::set<std::string> LinkPrefixes;
cmsys::RegularExpression ExtractStaticLibraryName;
cmsys::RegularExpression ExtractSharedLibraryName;
cmsys::RegularExpression ExtractAnyLibraryName;
std::string SharedRegexString;
- bool OpenBSD;
void AddLinkPrefix(const char* p);
void AddLinkExtension(const char* e, LinkType type);
std::string CreateExtensionRegex(std::vector<std::string> const& exts,
@@ -139,7 +128,7 @@ private:
std::string NoCaseExpression(const char* str);
// Handling of link items.
- void AddTargetItem(std::string const& item, cmTarget* target);
+ void AddTargetItem(std::string const& item, const cmGeneratorTarget* target);
void AddFullItem(std::string const& item);
bool CheckImplicitDirItem(std::string const& item);
void AddUserItem(std::string const& item, bool pathNotKnown);
@@ -153,7 +142,7 @@ private:
// Framework info.
void ComputeFrameworkInfo();
void AddFrameworkPath(std::string const& p);
- std::set<cmStdString> FrameworkPathsEmmitted;
+ std::set<std::string> FrameworkPathsEmmitted;
cmsys::RegularExpression SplitFramework;
// Linker search path computation.
@@ -165,25 +154,37 @@ private:
void LoadImplicitLinkInfo();
void AddImplicitLinkInfo();
void AddImplicitLinkInfo(std::string const& lang);
- std::set<cmStdString> ImplicitLinkDirs;
- std::set<cmStdString> ImplicitLinkLibs;
+ std::set<std::string> ImplicitLinkDirs;
+ std::set<std::string> ImplicitLinkLibs;
// Additional paths configured by the runtime linker
std::vector<std::string> RuntimeLinkDirs;
// Linker search path compatibility mode.
- std::set<cmStdString> OldLinkDirMask;
+ std::set<std::string> OldLinkDirMask;
std::vector<std::string> OldLinkDirItems;
std::vector<std::string> OldUserFlagItems;
- bool OldLinkDirMode;
-
+ std::set<std::string> CMP0060WarnItems;
+ // Dependent library path computation.
+ cmOrderDirectories* OrderDependentRPath;
// Runtime path computation.
cmOrderDirectories* OrderRuntimeSearchPath;
- void AddLibraryRuntimeInfo(std::string const& fullPath, cmTarget* target);
+
+ bool OldLinkDirMode;
+ bool OpenBSD;
+ bool LinkDependsNoShared;
+ bool UseImportLibrary;
+ bool RuntimeUseChrpath;
+ bool NoSONameUsesPath;
+ bool LinkWithRuntimePath;
+ bool LinkTypeEnabled;
+ bool ArchivesMayBeShared;
+ bool CMP0060Warn;
+
+ void AddLibraryRuntimeInfo(std::string const& fullPath,
+ const cmGeneratorTarget* target);
void AddLibraryRuntimeInfo(std::string const& fullPath);
- // Dependent library path computation.
- cmOrderDirectories* OrderDependentRPath;
};
#endif
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index 0829add20..586b5bfb1 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -15,7 +15,9 @@
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#include "cmState.h"
#include "cmSystemTools.h"
+#include "cmSourceFile.h"
#include "cmTarget.h"
#include "cmake.h"
@@ -97,8 +99,10 @@ cmComputeTargetDepends::cmComputeTargetDepends(cmGlobalGenerator* gg)
{
this->GlobalGenerator = gg;
cmake* cm = this->GlobalGenerator->GetCMakeInstance();
- this->DebugMode = cm->GetPropertyAsBool("GLOBAL_DEPENDS_DEBUG_MODE");
- this->NoCycles = cm->GetPropertyAsBool("GLOBAL_DEPENDS_NO_CYCLES");
+ this->DebugMode = cm->GetState()
+ ->GetGlobalPropertyAsBool("GLOBAL_DEPENDS_DEBUG_MODE");
+ this->NoCycles = cm->GetState()
+ ->GetGlobalPropertyAsBool("GLOBAL_DEPENDS_NO_CYCLES");
}
//----------------------------------------------------------------------------
@@ -143,12 +147,13 @@ bool cmComputeTargetDepends::Compute()
//----------------------------------------------------------------------------
void
-cmComputeTargetDepends::GetTargetDirectDepends(cmTarget* t,
+cmComputeTargetDepends::GetTargetDirectDepends(cmGeneratorTarget const* t,
cmTargetDependSet& deps)
{
// Lookup the index for this target. All targets should be known by
// this point.
- std::map<cmTarget*, int>::const_iterator tii = this->TargetIndex.find(t);
+ std::map<cmGeneratorTarget const*, int>::const_iterator tii
+ = this->TargetIndex.find(t);
assert(tii != this->TargetIndex.end());
int i = tii->second;
@@ -156,7 +161,7 @@ cmComputeTargetDepends::GetTargetDirectDepends(cmTarget* t,
EdgeList const& nl = this->FinalGraph[i];
for(EdgeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni)
{
- cmTarget* dep = this->Targets[*ni];
+ cmGeneratorTarget const* dep = this->Targets[*ni];
cmTargetDependSet::iterator di = deps.insert(dep).first;
di->SetType(ni->IsStrong());
}
@@ -170,13 +175,15 @@ void cmComputeTargetDepends::CollectTargets()
this->GlobalGenerator->GetLocalGenerators();
for(unsigned int i = 0; i < lgens.size(); ++i)
{
- cmTargets& targets = lgens[i]->GetMakefile()->GetTargets();
- for(cmTargets::iterator ti = targets.begin(); ti != targets.end(); ++ti)
+ const std::vector<cmGeneratorTarget*> targets =
+ lgens[i]->GetGeneratorTargets();
+ for(std::vector<cmGeneratorTarget*>::const_iterator ti = targets.begin();
+ ti != targets.end(); ++ti)
{
- cmTarget* target = &ti->second;
+ cmGeneratorTarget* gt = *ti;
int index = static_cast<int>(this->Targets.size());
- this->TargetIndex[target] = index;
- this->Targets.push_back(target);
+ this->TargetIndex[gt] = index;
+ this->Targets.push_back(gt);
}
}
}
@@ -198,49 +205,65 @@ void cmComputeTargetDepends::CollectDepends()
void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
{
// Get the depender.
- cmTarget* depender = this->Targets[depender_index];
+ cmGeneratorTarget const* depender = this->Targets[depender_index];
+ if (depender->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ return;
+ }
// Loop over all targets linked directly in all configs.
// We need to make targets depend on the union of all config-specific
// dependencies in all targets, because the generated build-systems can't
// deal with config-specific dependencies.
{
- std::set<cmStdString> emitted;
- {
- std::vector<std::string> tlibs;
- depender->GetDirectLinkLibraries(0, tlibs, depender);
- // A target should not depend on itself.
- emitted.insert(depender->GetName());
- for(std::vector<std::string>::const_iterator lib = tlibs.begin();
- lib != tlibs.end(); ++lib)
+ std::set<std::string> emitted;
+
+ std::vector<std::string> configs;
+ depender->Makefile->GetConfigurations(configs);
+ if (configs.empty())
{
- // Don't emit the same library twice for this target.
- if(emitted.insert(*lib).second)
- {
- this->AddTargetDepend(depender_index, lib->c_str(), true);
- this->AddInterfaceDepends(depender_index, lib->c_str(),
- true, emitted);
- }
+ configs.push_back("");
}
- }
- std::vector<std::string> configs;
- depender->GetMakefile()->GetConfigurations(configs);
for (std::vector<std::string>::const_iterator it = configs.begin();
it != configs.end(); ++it)
{
- std::vector<std::string> tlibs;
- depender->GetDirectLinkLibraries(it->c_str(), tlibs, depender);
+ std::vector<cmSourceFile const*> objectFiles;
+ depender->GetExternalObjects(objectFiles, *it);
+ for(std::vector<cmSourceFile const*>::const_iterator
+ oi = objectFiles.begin(); oi != objectFiles.end(); ++oi)
+ {
+ std::string objLib = (*oi)->GetObjectLibrary();
+ if (!objLib.empty() && emitted.insert(objLib).second)
+ {
+ if(depender->GetType() != cmState::EXECUTABLE &&
+ depender->GetType() != cmState::STATIC_LIBRARY &&
+ depender->GetType() != cmState::SHARED_LIBRARY &&
+ depender->GetType() != cmState::MODULE_LIBRARY)
+ {
+ this->GlobalGenerator->GetCMakeInstance()
+ ->IssueMessage(cmake::FATAL_ERROR,
+ "Only executables and non-OBJECT libraries may "
+ "reference target objects.",
+ depender->GetBacktrace());
+ return;
+ }
+ const_cast<cmGeneratorTarget*>(depender)->Target->AddUtility(objLib);
+ }
+ }
+
+ cmLinkImplementation const* impl = depender->GetLinkImplementation(*it);
+
// A target should not depend on itself.
emitted.insert(depender->GetName());
- for(std::vector<std::string>::const_iterator lib = tlibs.begin();
- lib != tlibs.end(); ++lib)
+ for(std::vector<cmLinkImplItem>::const_iterator
+ lib = impl->Libraries.begin();
+ lib != impl->Libraries.end(); ++lib)
{
// Don't emit the same library twice for this target.
if(emitted.insert(*lib).second)
{
- this->AddTargetDepend(depender_index, lib->c_str(), true);
- this->AddInterfaceDepends(depender_index, lib->c_str(),
- true, emitted);
+ this->AddTargetDepend(depender_index, *lib, true);
+ this->AddInterfaceDepends(depender_index, *lib, emitted);
}
}
}
@@ -248,17 +271,17 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
// Loop over all utility dependencies.
{
- std::set<cmStdString> const& tutils = depender->GetUtilities();
- std::set<cmStdString> emitted;
+ std::set<cmLinkItem> const& tutils = depender->GetUtilityItems();
+ std::set<std::string> emitted;
// A target should not depend on itself.
emitted.insert(depender->GetName());
- for(std::set<cmStdString>::const_iterator util = tutils.begin();
+ for(std::set<cmLinkItem>::const_iterator util = tutils.begin();
util != tutils.end(); ++util)
{
// Don't emit the same utility twice for this target.
if(emitted.insert(*util).second)
{
- this->AddTargetDepend(depender_index, util->c_str(), false);
+ this->AddTargetDepend(depender_index, *util, false);
}
}
}
@@ -266,24 +289,24 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
//----------------------------------------------------------------------------
void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
- cmTarget* dependee,
- const char *config,
- std::set<cmStdString> &emitted)
+ const cmGeneratorTarget* dependee,
+ const std::string& config,
+ std::set<std::string> &emitted)
{
- cmTarget* depender = this->Targets[depender_index];
- if(cmTarget::LinkInterface const* iface =
- dependee->GetLinkInterface(config, depender))
+ cmGeneratorTarget const* depender = this->Targets[depender_index];
+ if(cmLinkInterface const* iface =
+ dependee->GetLinkInterface(config,
+ depender))
{
- for(std::vector<std::string>::const_iterator
+ for(std::vector<cmLinkItem>::const_iterator
lib = iface->Libraries.begin();
lib != iface->Libraries.end(); ++lib)
{
// Don't emit the same library twice for this target.
if(emitted.insert(*lib).second)
{
- this->AddTargetDepend(depender_index, lib->c_str(), true);
- this->AddInterfaceDepends(depender_index, lib->c_str(),
- true, emitted);
+ this->AddTargetDepend(depender_index, *lib, true);
+ this->AddInterfaceDepends(depender_index, *lib, emitted);
}
}
}
@@ -291,18 +314,16 @@ void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
//----------------------------------------------------------------------------
void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
- const char* dependee_name,
- bool linking,
- std::set<cmStdString> &emitted)
+ cmLinkItem const& dependee_name,
+ std::set<std::string> &emitted)
{
- cmTarget* depender = this->Targets[depender_index];
- cmTarget* dependee =
- depender->GetMakefile()->FindTargetToUse(dependee_name);
+ cmGeneratorTarget const* depender = this->Targets[depender_index];
+ cmGeneratorTarget const* dependee = dependee_name.Target;
// Skip targets that will not really be linked. This is probably a
// name conflict between an external library and an executable
// within the project.
- if(linking && dependee &&
- dependee->GetType() == cmTarget::EXECUTABLE &&
+ if(dependee &&
+ dependee->GetType() == cmState::EXECUTABLE &&
!dependee->IsExecutableWithExports())
{
dependee = 0;
@@ -310,37 +331,75 @@ void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
if(dependee)
{
- this->AddInterfaceDepends(depender_index, dependee, 0, emitted);
+ this->AddInterfaceDepends(depender_index, dependee, "", emitted);
std::vector<std::string> configs;
- depender->GetMakefile()->GetConfigurations(configs);
+ depender->Makefile->GetConfigurations(configs);
for (std::vector<std::string>::const_iterator it = configs.begin();
it != configs.end(); ++it)
{
// A target should not depend on itself.
emitted.insert(depender->GetName());
- this->AddInterfaceDepends(depender_index, dependee,
- it->c_str(), emitted);
+ this->AddInterfaceDepends(depender_index, dependee, *it, emitted);
}
}
}
//----------------------------------------------------------------------------
-void cmComputeTargetDepends::AddTargetDepend(int depender_index,
- const char* dependee_name,
- bool linking)
+void cmComputeTargetDepends::AddTargetDepend(
+ int depender_index, cmLinkItem const& dependee_name,
+ bool linking)
{
// Get the depender.
- cmTarget* depender = this->Targets[depender_index];
+ cmGeneratorTarget const* depender = this->Targets[depender_index];
// Check the target's makefile first.
- cmTarget* dependee =
- depender->GetMakefile()->FindTargetToUse(dependee_name);
+ cmGeneratorTarget const* dependee = dependee_name.Target;
+
+ if(!dependee && !linking &&
+ (depender->GetType() != cmState::GLOBAL_TARGET))
+ {
+ cmake::MessageType messageType = cmake::AUTHOR_WARNING;
+ bool issueMessage = false;
+ std::ostringstream e;
+ switch(depender->GetPolicyStatusCMP0046())
+ {
+ case cmPolicies::WARN:
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0046) << "\n";
+ issueMessage = true;
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::NEW:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ issueMessage = true;
+ messageType = cmake::FATAL_ERROR;
+ }
+ if(issueMessage)
+ {
+ cmake* cm = this->GlobalGenerator->GetCMakeInstance();
+
+ e << "The dependency target \"" << dependee_name
+ << "\" of target \"" << depender->GetName() << "\" does not exist.";
+
+ cmListFileBacktrace const* backtrace =
+ depender->GetUtilityBacktrace(dependee_name);
+ if(backtrace)
+ {
+ cm->IssueMessage(messageType, e.str(), *backtrace);
+ }
+ else
+ {
+ cm->IssueMessage(messageType, e.str());
+ }
+
+ }
+ }
// Skip targets that will not really be linked. This is probably a
// name conflict between an external library and an executable
// within the project.
if(linking && dependee &&
- dependee->GetType() == cmTarget::EXECUTABLE &&
+ dependee->GetType() == cmState::EXECUTABLE &&
!dependee->IsExecutableWithExports())
{
dependee = 0;
@@ -354,18 +413,19 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index,
//----------------------------------------------------------------------------
void cmComputeTargetDepends::AddTargetDepend(int depender_index,
- cmTarget* dependee,
+ const cmGeneratorTarget* dependee,
bool linking)
{
- if(dependee->IsImported())
+ if(dependee->IsImported() ||
+ dependee->GetType() == cmState::INTERFACE_LIBRARY)
{
- // Skip imported targets but follow their utility dependencies.
- std::set<cmStdString> const& utils = dependee->GetUtilities();
- for(std::set<cmStdString>::const_iterator i = utils.begin();
+ // Skip IMPORTED and INTERFACE targets but follow their utility
+ // dependencies.
+ std::set<cmLinkItem> const& utils = dependee->GetUtilityItems();
+ for(std::set<cmLinkItem>::const_iterator i = utils.begin();
i != utils.end(); ++i)
{
- if(cmTarget* transitive_dependee =
- dependee->GetMakefile()->FindTargetToUse(i->c_str()))
+ if(cmGeneratorTarget const* transitive_dependee = i->Target)
{
this->AddTargetDepend(depender_index, transitive_dependee, false);
}
@@ -375,7 +435,7 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index,
{
// Lookup the index for this target. All targets should be known by
// this point.
- std::map<cmTarget*, int>::const_iterator tii =
+ std::map<cmGeneratorTarget const*, int>::const_iterator tii =
this->TargetIndex.find(dependee);
assert(tii != this->TargetIndex.end());
int dependee_index = tii->second;
@@ -388,22 +448,23 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index,
//----------------------------------------------------------------------------
void
-cmComputeTargetDepends::DisplayGraph(Graph const& graph, const char* name)
+cmComputeTargetDepends::DisplayGraph(Graph const& graph,
+ const std::string& name)
{
- fprintf(stderr, "The %s target dependency graph is:\n", name);
+ fprintf(stderr, "The %s target dependency graph is:\n", name.c_str());
int n = static_cast<int>(graph.size());
for(int depender_index = 0; depender_index < n; ++depender_index)
{
EdgeList const& nl = graph[depender_index];
- cmTarget* depender = this->Targets[depender_index];
+ cmGeneratorTarget const* depender = this->Targets[depender_index];
fprintf(stderr, "target %d is [%s]\n",
- depender_index, depender->GetName());
+ depender_index, depender->GetName().c_str());
for(EdgeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni)
{
int dependee_index = *ni;
- cmTarget* dependee = this->Targets[dependee_index];
+ cmGeneratorTarget const* dependee = this->Targets[dependee_index];
fprintf(stderr, " depends on target %d [%s] (%s)\n", dependee_index,
- dependee->GetName(), ni->IsStrong()? "strong" : "weak");
+ dependee->GetName().c_str(), ni->IsStrong()? "strong" : "weak");
}
}
fprintf(stderr, "\n");
@@ -425,7 +486,7 @@ cmComputeTargetDepends
{
int i = *ni;
fprintf(stderr, " contains target %d [%s]\n",
- i, this->Targets[i]->GetName());
+ i, this->Targets[i]->GetName().c_str());
}
}
fprintf(stderr, "\n");
@@ -461,7 +522,7 @@ cmComputeTargetDepends
// Make sure the component is all STATIC_LIBRARY targets.
for(NodeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni)
{
- if(this->Targets[*ni]->GetType() != cmTarget::STATIC_LIBRARY)
+ if(this->Targets[*ni]->GetType() != cmState::STATIC_LIBRARY)
{
this->ComplainAboutBadComponent(ccg, c);
return false;
@@ -478,7 +539,7 @@ cmComputeTargetDepends
bool strong)
{
// Construct the error message.
- cmOStringStream e;
+ std::ostringstream e;
e << "The inter-target dependency graph contains the following "
<< "strongly connected component (cycle):\n";
std::vector<NodeList> const& components = ccg.GetComponents();
@@ -488,11 +549,11 @@ cmComputeTargetDepends
{
// Get the depender.
int i = *ci;
- cmTarget* depender = this->Targets[i];
+ cmGeneratorTarget const* depender = this->Targets[i];
// Describe the depender.
e << " \"" << depender->GetName() << "\" of type "
- << cmTarget::GetTargetTypeName(depender->GetType()) << "\n";
+ << cmState::GetTargetTypeName(depender->GetType()) << "\n";
// List its dependencies that are inside the component.
EdgeList const& nl = this->InitialGraph[i];
@@ -501,7 +562,7 @@ cmComputeTargetDepends
int j = *ni;
if(cmap[j] == c)
{
- cmTarget* dependee = this->Targets[j];
+ cmGeneratorTarget const* dependee = this->Targets[j];
e << " depends on \"" << dependee->GetName() << "\""
<< " (" << (ni->IsStrong()? "strong" : "weak") << ")\n";
}
diff --git a/Source/cmComputeTargetDepends.h b/Source/cmComputeTargetDepends.h
index d6131cf1c..6100d970a 100644
--- a/Source/cmComputeTargetDepends.h
+++ b/Source/cmComputeTargetDepends.h
@@ -20,7 +20,8 @@
class cmComputeComponentGraph;
class cmGlobalGenerator;
-class cmTarget;
+class cmLinkItem;
+class cmGeneratorTarget;
class cmTargetDependSet;
/** \class cmComputeTargetDepends
@@ -38,28 +39,34 @@ public:
bool Compute();
- std::vector<cmTarget*> const& GetTargets() const { return this->Targets; }
- void GetTargetDirectDepends(cmTarget* t, cmTargetDependSet& deps);
+ std::vector<cmGeneratorTarget const*> const&
+ GetTargets() const { return this->Targets; }
+ void GetTargetDirectDepends(cmGeneratorTarget const* t,
+ cmTargetDependSet& deps);
private:
void CollectTargets();
void CollectDepends();
void CollectTargetDepends(int depender_index);
- void AddTargetDepend(int depender_index, const char* dependee_name,
+ void AddTargetDepend(int depender_index,
+ cmLinkItem const& dependee_name,
+ bool linking);
+ void AddTargetDepend(int depender_index, cmGeneratorTarget const* dependee,
bool linking);
- void AddTargetDepend(int depender_index, cmTarget* dependee, bool linking);
bool ComputeFinalDepends(cmComputeComponentGraph const& ccg);
- void AddInterfaceDepends(int depender_index, const char* dependee_name,
- bool linking, std::set<cmStdString> &emitted);
- void AddInterfaceDepends(int depender_index, cmTarget* dependee,
- const char *config,
- std::set<cmStdString> &emitted);
+ void AddInterfaceDepends(int depender_index,
+ cmLinkItem const& dependee_name,
+ std::set<std::string> &emitted);
+ void AddInterfaceDepends(int depender_index,
+ cmGeneratorTarget const* dependee,
+ const std::string& config,
+ std::set<std::string> &emitted);
cmGlobalGenerator* GlobalGenerator;
bool DebugMode;
bool NoCycles;
// Collect all targets.
- std::vector<cmTarget*> Targets;
- std::map<cmTarget*, int> TargetIndex;
+ std::vector<cmGeneratorTarget const*> Targets;
+ std::map<cmGeneratorTarget const*, int> TargetIndex;
// Represent the target dependency graph. The entry at each
// top-level index corresponds to a depender whose dependencies are
@@ -69,7 +76,7 @@ private:
typedef cmGraphAdjacencyList Graph;
Graph InitialGraph;
Graph FinalGraph;
- void DisplayGraph(Graph const& graph, const char* name);
+ void DisplayGraph(Graph const& graph, const std::string& name);
// Deal with connected components.
void DisplayComponents(cmComputeComponentGraph const& ccg);
diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx
new file mode 100644
index 000000000..6a0ebec2d
--- /dev/null
+++ b/Source/cmConditionEvaluator.cxx
@@ -0,0 +1,854 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmConditionEvaluator.h"
+#include "cmOutputConverter.h"
+#include "cmAlgorithms.h"
+
+cmConditionEvaluator::cmConditionEvaluator(cmMakefile& makefile,
+ const cmListFileContext &context,
+ const cmListFileBacktrace& bt):
+ Makefile(makefile),
+ ExecutionContext(context),
+ Backtrace(bt),
+ Policy12Status(makefile.GetPolicyStatus(cmPolicies::CMP0012)),
+ Policy54Status(makefile.GetPolicyStatus(cmPolicies::CMP0054)),
+ Policy57Status(makefile.GetPolicyStatus(cmPolicies::CMP0057)),
+ Policy64Status(makefile.GetPolicyStatus(cmPolicies::CMP0064))
+{
+
+}
+
+//=========================================================================
+// order of operations,
+// 1. ( ) -- parenthetical groups
+// 2. IS_DIRECTORY EXISTS COMMAND DEFINED etc predicates
+// 3. MATCHES LESS GREATER EQUAL STRLESS STRGREATER STREQUAL etc binary ops
+// 4. NOT
+// 5. AND OR
+//
+// There is an issue on whether the arguments should be values of references,
+// for example IF (FOO AND BAR) should that compare the strings FOO and BAR
+// or should it really do IF (${FOO} AND ${BAR}) Currently IS_DIRECTORY
+// EXISTS COMMAND and DEFINED all take values. EQUAL, LESS and GREATER can
+// take numeric values or variable names. STRLESS and STRGREATER take
+// variable names but if the variable name is not found it will use the name
+// directly. AND OR take variables or the values 0 or 1.
+
+bool cmConditionEvaluator::IsTrue(
+ const std::vector<cmExpandedCommandArgument> &args,
+ std::string &errorString,
+ cmake::MessageType &status)
+{
+ errorString = "";
+
+ // handle empty invocation
+ if (args.size() < 1)
+ {
+ return false;
+ }
+
+ // store the reduced args in this vector
+ cmArgumentList newArgs;
+
+ // copy to the list structure
+ newArgs.insert(newArgs.end(), args.begin(), args.end());
+
+ // now loop through the arguments and see if we can reduce any of them
+ // we do this multiple times. Once for each level of precedence
+ // parens
+ if (!this->HandleLevel0(newArgs, errorString, status))
+ {
+ return false;
+ }
+ //predicates
+ if (!this->HandleLevel1(newArgs, errorString, status))
+ {
+ return false;
+ }
+ // binary ops
+ if (!this->HandleLevel2(newArgs, errorString, status))
+ {
+ return false;
+ }
+
+ // NOT
+ if (!this->HandleLevel3(newArgs, errorString, status))
+ {
+ return false;
+ }
+ // AND OR
+ if (!this->HandleLevel4(newArgs, errorString, status))
+ {
+ return false;
+ }
+
+ // now at the end there should only be one argument left
+ if (newArgs.size() != 1)
+ {
+ errorString = "Unknown arguments specified";
+ status = cmake::FATAL_ERROR;
+ return false;
+ }
+
+ return this->GetBooleanValueWithAutoDereference(*(newArgs.begin()),
+ errorString, status, true);
+}
+
+cmListFileContext cmConditionEvaluator::GetConditionContext(
+ cmMakefile* mf,
+ const cmCommandContext& command,
+ const std::string& filePath)
+{
+ cmListFileContext context =
+ cmListFileContext::FromCommandContext(
+ command,
+ filePath);
+
+ if(!mf->GetCMakeInstance()->GetIsInTryCompile())
+ {
+ cmOutputConverter converter(mf->GetStateSnapshot());
+ context.FilePath = converter.Convert(context.FilePath,
+ cmOutputConverter::HOME);
+ }
+ return context;
+}
+
+//=========================================================================
+const char* cmConditionEvaluator::GetDefinitionIfUnquoted(
+ cmExpandedCommandArgument const& argument) const
+{
+ if((this->Policy54Status != cmPolicies::WARN &&
+ this->Policy54Status != cmPolicies::OLD) &&
+ argument.WasQuoted())
+ {
+ return 0;
+ }
+
+ const char* def = this->Makefile.GetDefinition(argument.GetValue());
+
+ if(def && argument.WasQuoted() && this->Policy54Status == cmPolicies::WARN)
+ {
+ if(!this->Makefile.HasCMP0054AlreadyBeenReported(
+ this->ExecutionContext))
+ {
+ std::ostringstream e;
+ e << (cmPolicies::GetPolicyWarning(cmPolicies::CMP0054)) << "\n";
+ e << "Quoted variables like \"" << argument.GetValue() <<
+ "\" will no longer be dereferenced "
+ "when the policy is set to NEW. "
+ "Since the policy is not set the OLD behavior will be used.";
+
+ this->Makefile.GetCMakeInstance()
+ ->IssueMessage(cmake::AUTHOR_WARNING, e.str(),
+ this->Backtrace);
+ }
+ }
+
+ return def;
+}
+
+//=========================================================================
+const char* cmConditionEvaluator::GetVariableOrString(
+ const cmExpandedCommandArgument& argument) const
+{
+ const char* def = this->GetDefinitionIfUnquoted(argument);
+
+ if(!def)
+ {
+ def = argument.c_str();
+ }
+
+ return def;
+}
+
+//=========================================================================
+bool cmConditionEvaluator::IsKeyword(std::string const& keyword,
+ cmExpandedCommandArgument& argument) const
+{
+ if((this->Policy54Status != cmPolicies::WARN &&
+ this->Policy54Status != cmPolicies::OLD) &&
+ argument.WasQuoted())
+ {
+ return false;
+ }
+
+ bool isKeyword = argument.GetValue() == keyword;
+
+ if(isKeyword && argument.WasQuoted() &&
+ this->Policy54Status == cmPolicies::WARN)
+ {
+ if(!this->Makefile.HasCMP0054AlreadyBeenReported(
+ this->ExecutionContext))
+ {
+ std::ostringstream e;
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0054) << "\n";
+ e << "Quoted keywords like \"" << argument.GetValue() <<
+ "\" will no longer be interpreted as keywords "
+ "when the policy is set to NEW. "
+ "Since the policy is not set the OLD behavior will be used.";
+
+ this->Makefile.GetCMakeInstance()
+ ->IssueMessage(cmake::AUTHOR_WARNING, e.str(),
+ this->Backtrace);
+ }
+ }
+
+ return isKeyword;
+}
+
+//=========================================================================
+bool cmConditionEvaluator::GetBooleanValue(
+ cmExpandedCommandArgument& arg) const
+{
+ // Check basic constants.
+ if (arg == "0")
+ {
+ return false;
+ }
+ if (arg == "1")
+ {
+ return true;
+ }
+
+ // Check named constants.
+ if (cmSystemTools::IsOn(arg.c_str()))
+ {
+ return true;
+ }
+ if (cmSystemTools::IsOff(arg.c_str()))
+ {
+ return false;
+ }
+
+ // Check for numbers.
+ if(!arg.empty())
+ {
+ char* end;
+ double d = strtod(arg.c_str(), &end);
+ if(*end == '\0')
+ {
+ // The whole string is a number. Use C conversion to bool.
+ return d? true:false;
+ }
+ }
+
+ // Check definition.
+ const char* def = this->GetDefinitionIfUnquoted(arg);
+ return !cmSystemTools::IsOff(def);
+}
+
+//=========================================================================
+// Boolean value behavior from CMake 2.6.4 and below.
+bool cmConditionEvaluator::GetBooleanValueOld(
+ cmExpandedCommandArgument const& arg, bool one) const
+{
+ if(one)
+ {
+ // Old IsTrue behavior for single argument.
+ if(arg == "0")
+ { return false; }
+ else if(arg == "1")
+ { return true; }
+ else
+ {
+ const char* def = this->GetDefinitionIfUnquoted(arg);
+ return !cmSystemTools::IsOff(def);
+ }
+ }
+ else
+ {
+ // Old GetVariableOrNumber behavior.
+ const char* def = this->GetDefinitionIfUnquoted(arg);
+ if(!def && atoi(arg.c_str()))
+ {
+ def = arg.c_str();
+ }
+ return !cmSystemTools::IsOff(def);
+ }
+}
+
+//=========================================================================
+// returns the resulting boolean value
+bool cmConditionEvaluator::GetBooleanValueWithAutoDereference(
+ cmExpandedCommandArgument &newArg,
+ std::string &errorString,
+ cmake::MessageType &status,
+ bool oneArg) const
+{
+ // Use the policy if it is set.
+ if (this->Policy12Status == cmPolicies::NEW)
+ {
+ return GetBooleanValue(newArg);
+ }
+ else if (this->Policy12Status == cmPolicies::OLD)
+ {
+ return GetBooleanValueOld(newArg, oneArg);
+ }
+
+ // Check policy only if old and new results differ.
+ bool newResult = this->GetBooleanValue(newArg);
+ bool oldResult = this->GetBooleanValueOld(newArg, oneArg);
+ if(newResult != oldResult)
+ {
+ switch(this->Policy12Status)
+ {
+ case cmPolicies::WARN:
+ {
+ errorString = "An argument named \"" + newArg.GetValue()
+ + "\" appears in a conditional statement. "
+ + cmPolicies::GetPolicyWarning(cmPolicies::CMP0012);
+ status = cmake::AUTHOR_WARNING;
+ }
+ case cmPolicies::OLD:
+ return oldResult;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ {
+ errorString = "An argument named \"" + newArg.GetValue()
+ + "\" appears in a conditional statement. "
+ + cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0012);
+ status = cmake::FATAL_ERROR;
+ }
+ case cmPolicies::NEW:
+ break;
+ }
+ }
+ return newResult;
+}
+
+//=========================================================================
+void cmConditionEvaluator::IncrementArguments(cmArgumentList &newArgs,
+ cmArgumentList::iterator &argP1,
+ cmArgumentList::iterator &argP2) const
+{
+ if (argP1 != newArgs.end())
+ {
+ argP1++;
+ argP2 = argP1;
+ if (argP1 != newArgs.end())
+ {
+ argP2++;
+ }
+ }
+}
+
+//=========================================================================
+// helper function to reduce code duplication
+void cmConditionEvaluator::HandlePredicate(bool value, int &reducible,
+ cmArgumentList::iterator &arg,
+ cmArgumentList &newArgs,
+ cmArgumentList::iterator &argP1,
+ cmArgumentList::iterator &argP2) const
+{
+ if(value)
+ {
+ *arg = cmExpandedCommandArgument("1", true);
+ }
+ else
+ {
+ *arg = cmExpandedCommandArgument("0", true);
+ }
+ newArgs.erase(argP1);
+ argP1 = arg;
+ this->IncrementArguments(newArgs,argP1,argP2);
+ reducible = 1;
+}
+
+//=========================================================================
+// helper function to reduce code duplication
+void cmConditionEvaluator::HandleBinaryOp(bool value, int &reducible,
+ cmArgumentList::iterator &arg,
+ cmArgumentList &newArgs,
+ cmArgumentList::iterator &argP1,
+ cmArgumentList::iterator &argP2)
+{
+ if(value)
+ {
+ *arg = cmExpandedCommandArgument("1", true);
+ }
+ else
+ {
+ *arg = cmExpandedCommandArgument("0", true);
+ }
+ newArgs.erase(argP2);
+ newArgs.erase(argP1);
+ argP1 = arg;
+ this->IncrementArguments(newArgs,argP1,argP2);
+ reducible = 1;
+}
+
+//=========================================================================
+// level 0 processes parenthetical expressions
+bool cmConditionEvaluator::HandleLevel0(cmArgumentList &newArgs,
+ std::string &errorString,
+ cmake::MessageType &status)
+{
+ int reducible;
+ do
+ {
+ reducible = 0;
+ cmArgumentList::iterator arg = newArgs.begin();
+ while (arg != newArgs.end())
+ {
+ if (IsKeyword("(", *arg))
+ {
+ // search for the closing paren for this opening one
+ cmArgumentList::iterator argClose;
+ argClose = arg;
+ argClose++;
+ unsigned int depth = 1;
+ while (argClose != newArgs.end() && depth)
+ {
+ if (this->IsKeyword("(", *argClose))
+ {
+ depth++;
+ }
+ if (this->IsKeyword(")", *argClose))
+ {
+ depth--;
+ }
+ argClose++;
+ }
+ if (depth)
+ {
+ errorString = "mismatched parenthesis in condition";
+ status = cmake::FATAL_ERROR;
+ return false;
+ }
+ // store the reduced args in this vector
+ std::vector<cmExpandedCommandArgument> newArgs2;
+
+ // copy to the list structure
+ cmArgumentList::iterator argP1 = arg;
+ argP1++;
+ newArgs2.insert(newArgs2.end(), argP1, argClose);
+ newArgs2.pop_back();
+ // now recursively invoke IsTrue to handle the values inside the
+ // parenthetical expression
+ bool value =
+ this->IsTrue(newArgs2, errorString, status);
+ if(value)
+ {
+ *arg = cmExpandedCommandArgument("1", true);
+ }
+ else
+ {
+ *arg = cmExpandedCommandArgument("0", true);
+ }
+ argP1 = arg;
+ argP1++;
+ // remove the now evaluated parenthetical expression
+ newArgs.erase(argP1,argClose);
+ }
+ ++arg;
+ }
+ }
+ while (reducible);
+ return true;
+}
+
+//=========================================================================
+// level one handles most predicates except for NOT
+bool cmConditionEvaluator::HandleLevel1(cmArgumentList &newArgs,
+ std::string &, cmake::MessageType &)
+{
+ int reducible;
+ do
+ {
+ reducible = 0;
+ cmArgumentList::iterator arg = newArgs.begin();
+ cmArgumentList::iterator argP1;
+ cmArgumentList::iterator argP2;
+ while (arg != newArgs.end())
+ {
+ argP1 = arg;
+ this->IncrementArguments(newArgs,argP1,argP2);
+ // does a file exist
+ if (this->IsKeyword("EXISTS", *arg) && argP1 != newArgs.end())
+ {
+ this->HandlePredicate(
+ cmSystemTools::FileExists(argP1->c_str()),
+ reducible, arg, newArgs, argP1, argP2);
+ }
+ // does a directory with this name exist
+ if (this->IsKeyword("IS_DIRECTORY", *arg) && argP1 != newArgs.end())
+ {
+ this->HandlePredicate(
+ cmSystemTools::FileIsDirectory(argP1->c_str()),
+ reducible, arg, newArgs, argP1, argP2);
+ }
+ // does a symlink with this name exist
+ if (this->IsKeyword("IS_SYMLINK", *arg) && argP1 != newArgs.end())
+ {
+ this->HandlePredicate(
+ cmSystemTools::FileIsSymlink(argP1->c_str()),
+ reducible, arg, newArgs, argP1, argP2);
+ }
+ // is the given path an absolute path ?
+ if (this->IsKeyword("IS_ABSOLUTE", *arg) && argP1 != newArgs.end())
+ {
+ this->HandlePredicate(
+ cmSystemTools::FileIsFullPath(argP1->c_str()),
+ reducible, arg, newArgs, argP1, argP2);
+ }
+ // does a command exist
+ if (this->IsKeyword("COMMAND", *arg) && argP1 != newArgs.end())
+ {
+ cmCommand* command =
+ this->Makefile.GetState()->GetCommand(argP1->c_str());
+ this->HandlePredicate(
+ command ? true : false,
+ reducible, arg, newArgs, argP1, argP2);
+ }
+ // does a policy exist
+ if (this->IsKeyword("POLICY", *arg) && argP1 != newArgs.end())
+ {
+ cmPolicies::PolicyID pid;
+ this->HandlePredicate(
+ cmPolicies::GetPolicyID(argP1->c_str(), pid),
+ reducible, arg, newArgs, argP1, argP2);
+ }
+ // does a target exist
+ if (this->IsKeyword("TARGET", *arg) && argP1 != newArgs.end())
+ {
+ this->HandlePredicate(
+ this->Makefile.FindTargetToUse(argP1->GetValue())?true:false,
+ reducible, arg, newArgs, argP1, argP2);
+ }
+ // does a test exist
+ if(this->Policy64Status != cmPolicies::OLD &&
+ this->Policy64Status != cmPolicies::WARN)
+ {
+ if (this->IsKeyword("TEST", *arg) && argP1 != newArgs.end())
+ {
+ const cmTest* haveTest = this->Makefile.GetTest(argP1->c_str());
+ this->HandlePredicate(
+ haveTest?true:false,
+ reducible, arg, newArgs, argP1, argP2);
+ }
+ }
+ else if(this->Policy64Status == cmPolicies::WARN &&
+ this->IsKeyword("TEST", *arg))
+ {
+ std::ostringstream e;
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0064) << "\n";
+ e << "TEST will be interpreted as an operator "
+ "when the policy is set to NEW. "
+ "Since the policy is not set the OLD behavior will be used.";
+
+ this->Makefile.IssueMessage(cmake::AUTHOR_WARNING, e.str());
+ }
+ // is a variable defined
+ if (this->IsKeyword("DEFINED", *arg) && argP1 != newArgs.end())
+ {
+ size_t argP1len = argP1->GetValue().size();
+ bool bdef = false;
+ if(argP1len > 4 && argP1->GetValue().substr(0, 4) == "ENV{" &&
+ argP1->GetValue().operator[](argP1len-1) == '}')
+ {
+ std::string env = argP1->GetValue().substr(4, argP1len-5);
+ bdef = cmSystemTools::GetEnv(env.c_str())?true:false;
+ }
+ else
+ {
+ bdef = this->Makefile.IsDefinitionSet(argP1->GetValue());
+ }
+ this->HandlePredicate(bdef, reducible, arg, newArgs, argP1, argP2);
+ }
+ ++arg;
+ }
+ }
+ while (reducible);
+ return true;
+}
+
+//=========================================================================
+// level two handles most binary operations except for AND OR
+bool cmConditionEvaluator::HandleLevel2(cmArgumentList &newArgs,
+ std::string &errorString,
+ cmake::MessageType &status)
+{
+ int reducible;
+ std::string def_buf;
+ const char *def;
+ const char *def2;
+ do
+ {
+ reducible = 0;
+ cmArgumentList::iterator arg = newArgs.begin();
+ cmArgumentList::iterator argP1;
+ cmArgumentList::iterator argP2;
+ while (arg != newArgs.end())
+ {
+ argP1 = arg;
+ this->IncrementArguments(newArgs,argP1,argP2);
+ if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
+ IsKeyword("MATCHES", *argP1))
+ {
+ def = this->GetVariableOrString(*arg);
+ if (def != arg->c_str() // yes, we compare the pointer value
+ && cmHasLiteralPrefix(arg->GetValue(), "CMAKE_MATCH_"))
+ {
+ // The string to match is owned by our match result variables.
+ // Move it to our own buffer before clearing them.
+ def_buf = def;
+ def = def_buf.c_str();
+ }
+ const char* rex = argP2->c_str();
+ this->Makefile.ClearMatches();
+ cmsys::RegularExpression regEntry;
+ if ( !regEntry.compile(rex) )
+ {
+ std::ostringstream error;
+ error << "Regular expression \"" << rex << "\" cannot compile";
+ errorString = error.str();
+ status = cmake::FATAL_ERROR;
+ return false;
+ }
+ if (regEntry.find(def))
+ {
+ this->Makefile.StoreMatches(regEntry);
+ *arg = cmExpandedCommandArgument("1", true);
+ }
+ else
+ {
+ *arg = cmExpandedCommandArgument("0", true);
+ }
+ newArgs.erase(argP2);
+ newArgs.erase(argP1);
+ argP1 = arg;
+ this->IncrementArguments(newArgs,argP1,argP2);
+ reducible = 1;
+ }
+
+ if (argP1 != newArgs.end() && this->IsKeyword("MATCHES", *arg))
+ {
+ *arg = cmExpandedCommandArgument("0", true);
+ newArgs.erase(argP1);
+ argP1 = arg;
+ this->IncrementArguments(newArgs,argP1,argP2);
+ reducible = 1;
+ }
+
+ if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
+ (this->IsKeyword("LESS", *argP1) ||
+ this->IsKeyword("GREATER", *argP1) ||
+ this->IsKeyword("EQUAL", *argP1)))
+ {
+ def = this->GetVariableOrString(*arg);
+ def2 = this->GetVariableOrString(*argP2);
+ double lhs;
+ double rhs;
+ bool result;
+ if(sscanf(def, "%lg", &lhs) != 1 ||
+ sscanf(def2, "%lg", &rhs) != 1)
+ {
+ result = false;
+ }
+ else if (*(argP1) == "LESS")
+ {
+ result = (lhs < rhs);
+ }
+ else if (*(argP1) == "GREATER")
+ {
+ result = (lhs > rhs);
+ }
+ else
+ {
+ result = (lhs == rhs);
+ }
+ this->HandleBinaryOp(result,
+ reducible, arg, newArgs, argP1, argP2);
+ }
+
+ if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
+ (this->IsKeyword("STRLESS", *argP1) ||
+ this->IsKeyword("STREQUAL", *argP1) ||
+ this->IsKeyword("STRGREATER", *argP1)))
+ {
+ def = this->GetVariableOrString(*arg);
+ def2 = this->GetVariableOrString(*argP2);
+ int val = strcmp(def,def2);
+ bool result;
+ if (*(argP1) == "STRLESS")
+ {
+ result = (val < 0);
+ }
+ else if (*(argP1) == "STRGREATER")
+ {
+ result = (val > 0);
+ }
+ else // strequal
+ {
+ result = (val == 0);
+ }
+ this->HandleBinaryOp(result,
+ reducible, arg, newArgs, argP1, argP2);
+ }
+
+ if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
+ (this->IsKeyword("VERSION_LESS", *argP1) ||
+ this->IsKeyword("VERSION_GREATER", *argP1) ||
+ this->IsKeyword("VERSION_EQUAL", *argP1)))
+ {
+ def = this->GetVariableOrString(*arg);
+ def2 = this->GetVariableOrString(*argP2);
+ cmSystemTools::CompareOp op = cmSystemTools::OP_EQUAL;
+ if(*argP1 == "VERSION_LESS")
+ {
+ op = cmSystemTools::OP_LESS;
+ }
+ else if(*argP1 == "VERSION_GREATER")
+ {
+ op = cmSystemTools::OP_GREATER;
+ }
+ bool result = cmSystemTools::VersionCompare(op, def, def2);
+ this->HandleBinaryOp(result,
+ reducible, arg, newArgs, argP1, argP2);
+ }
+
+ // is file A newer than file B
+ if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
+ this->IsKeyword("IS_NEWER_THAN", *argP1))
+ {
+ int fileIsNewer=0;
+ bool success=cmSystemTools::FileTimeCompare(arg->GetValue(),
+ (argP2)->GetValue(),
+ &fileIsNewer);
+ this->HandleBinaryOp(
+ (success==false || fileIsNewer==1 || fileIsNewer==0),
+ reducible, arg, newArgs, argP1, argP2);
+ }
+
+ if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
+ this->IsKeyword("IN_LIST", *argP1))
+ {
+ if(this->Policy57Status != cmPolicies::OLD &&
+ this->Policy57Status != cmPolicies::WARN)
+ {
+ bool result = false;
+
+ def = this->GetVariableOrString(*arg);
+ def2 = this->Makefile.GetDefinition(argP2->GetValue());
+
+ if(def2)
+ {
+ std::vector<std::string> list;
+ cmSystemTools::ExpandListArgument(def2, list, true);
+
+ result = std::find(list.begin(), list.end(), def) != list.end();
+ }
+
+ this->HandleBinaryOp(result,
+ reducible, arg, newArgs, argP1, argP2);
+ }
+ else if(this->Policy57Status == cmPolicies::WARN)
+ {
+ std::ostringstream e;
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0057) << "\n";
+ e << "IN_LIST will be interpreted as an operator "
+ "when the policy is set to NEW. "
+ "Since the policy is not set the OLD behavior will be used.";
+
+ this->Makefile.IssueMessage(cmake::AUTHOR_WARNING, e.str());
+ }
+ }
+
+ ++arg;
+ }
+ }
+ while (reducible);
+ return true;
+}
+
+//=========================================================================
+// level 3 handles NOT
+bool cmConditionEvaluator::HandleLevel3(cmArgumentList &newArgs,
+ std::string &errorString,
+ cmake::MessageType &status)
+{
+ int reducible;
+ do
+ {
+ reducible = 0;
+ cmArgumentList::iterator arg = newArgs.begin();
+ cmArgumentList::iterator argP1;
+ cmArgumentList::iterator argP2;
+ while (arg != newArgs.end())
+ {
+ argP1 = arg;
+ IncrementArguments(newArgs,argP1,argP2);
+ if (argP1 != newArgs.end() && IsKeyword("NOT", *arg))
+ {
+ bool rhs = this->GetBooleanValueWithAutoDereference(*argP1,
+ errorString,
+ status);
+ this->HandlePredicate(!rhs, reducible, arg, newArgs, argP1, argP2);
+ }
+ ++arg;
+ }
+ }
+ while (reducible);
+ return true;
+}
+
+//=========================================================================
+// level 4 handles AND OR
+bool cmConditionEvaluator::HandleLevel4(cmArgumentList &newArgs,
+ std::string &errorString,
+ cmake::MessageType &status)
+{
+ int reducible;
+ bool lhs;
+ bool rhs;
+ do
+ {
+ reducible = 0;
+ cmArgumentList::iterator arg = newArgs.begin();
+ cmArgumentList::iterator argP1;
+ cmArgumentList::iterator argP2;
+ while (arg != newArgs.end())
+ {
+ argP1 = arg;
+ IncrementArguments(newArgs,argP1,argP2);
+ if (argP1 != newArgs.end() && IsKeyword("AND", *argP1) &&
+ argP2 != newArgs.end())
+ {
+ lhs = this->GetBooleanValueWithAutoDereference(*arg,
+ errorString,
+ status);
+ rhs = this->GetBooleanValueWithAutoDereference(*argP2,
+ errorString,
+ status);
+ this->HandleBinaryOp((lhs && rhs),
+ reducible, arg, newArgs, argP1, argP2);
+ }
+
+ if (argP1 != newArgs.end() && this->IsKeyword("OR", *argP1) &&
+ argP2 != newArgs.end())
+ {
+ lhs = this->GetBooleanValueWithAutoDereference(*arg,
+ errorString,
+ status);
+ rhs = this->GetBooleanValueWithAutoDereference(*argP2,
+ errorString,
+ status);
+ this->HandleBinaryOp((lhs || rhs),
+ reducible, arg, newArgs, argP1, argP2);
+ }
+ ++arg;
+ }
+ }
+ while (reducible);
+ return true;
+}
diff --git a/Source/cmConditionEvaluator.h b/Source/cmConditionEvaluator.h
new file mode 100644
index 000000000..8600825d0
--- /dev/null
+++ b/Source/cmConditionEvaluator.h
@@ -0,0 +1,107 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmConditionEvaluator_h
+#define cmConditionEvaluator_h
+
+#include "cmCommand.h"
+#include "cmExpandedCommandArgument.h"
+
+#include <list>
+
+class cmConditionEvaluator
+{
+public:
+ typedef std::list<cmExpandedCommandArgument> cmArgumentList;
+
+ cmConditionEvaluator(cmMakefile& makefile,
+ cmListFileContext const& context,
+ cmListFileBacktrace const& bt);
+
+ // this is a shared function for both If and Else to determine if the
+ // arguments were valid, and if so, was the response true. If there is
+ // an error, the errorString will be set.
+ bool IsTrue(const std::vector<cmExpandedCommandArgument> &args,
+ std::string &errorString,
+ cmake::MessageType &status);
+
+ static cmListFileContext GetConditionContext(cmMakefile* mf,
+ const cmCommandContext& command, std::string const& filePath);
+
+private:
+ // Filter the given variable definition based on policy CMP0054.
+ const char* GetDefinitionIfUnquoted(
+ const cmExpandedCommandArgument& argument) const;
+
+ const char* GetVariableOrString(
+ const cmExpandedCommandArgument& argument) const;
+
+ bool IsKeyword(std::string const& keyword,
+ cmExpandedCommandArgument& argument) const;
+
+ bool GetBooleanValue(
+ cmExpandedCommandArgument& arg) const;
+
+ bool GetBooleanValueOld(
+ cmExpandedCommandArgument const& arg, bool one) const;
+
+ bool GetBooleanValueWithAutoDereference(
+ cmExpandedCommandArgument &newArg,
+ std::string &errorString,
+ cmake::MessageType &status,
+ bool oneArg = false) const;
+
+ void IncrementArguments(
+ cmArgumentList &newArgs,
+ cmArgumentList::iterator &argP1,
+ cmArgumentList::iterator &argP2) const;
+
+ void HandlePredicate(bool value, int &reducible,
+ cmArgumentList::iterator &arg,
+ cmArgumentList &newArgs,
+ cmArgumentList::iterator &argP1,
+ cmArgumentList::iterator &argP2) const;
+
+ void HandleBinaryOp(bool value, int &reducible,
+ cmArgumentList::iterator &arg,
+ cmArgumentList &newArgs,
+ cmArgumentList::iterator &argP1,
+ cmArgumentList::iterator &argP2);
+
+ bool HandleLevel0(cmArgumentList &newArgs,
+ std::string &errorString,
+ cmake::MessageType &status);
+
+ bool HandleLevel1(cmArgumentList &newArgs,
+ std::string &, cmake::MessageType &);
+
+ bool HandleLevel2(cmArgumentList &newArgs,
+ std::string &errorString,
+ cmake::MessageType &status);
+
+ bool HandleLevel3(cmArgumentList &newArgs,
+ std::string &errorString,
+ cmake::MessageType &status);
+
+ bool HandleLevel4(cmArgumentList &newArgs,
+ std::string &errorString,
+ cmake::MessageType &status);
+
+ cmMakefile& Makefile;
+ cmListFileContext ExecutionContext;
+ cmListFileBacktrace Backtrace;
+ cmPolicies::PolicyStatus Policy12Status;
+ cmPolicies::PolicyStatus Policy54Status;
+ cmPolicies::PolicyStatus Policy57Status;
+ cmPolicies::PolicyStatus Policy64Status;
+};
+
+#endif
diff --git a/Source/cmConfigure.cmake.h.in b/Source/cmConfigure.cmake.h.in
index ab53b1d27..62128a793 100644
--- a/Source/cmConfigure.cmake.h.in
+++ b/Source/cmConfigure.cmake.h.in
@@ -9,14 +9,10 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#cmakedefine CMAKE_NO_STD_NAMESPACE
-#cmakedefine CMAKE_NO_ANSI_STREAM_HEADERS
-#cmakedefine CMAKE_NO_ANSI_STRING_STREAM
-#cmakedefine CMAKE_NO_ANSI_FOR_SCOPE
#cmakedefine HAVE_ENVIRON_NOT_REQUIRE_PROTOTYPE
#cmakedefine HAVE_UNSETENV
#cmakedefine CMAKE_USE_ELF_PARSER
-#cmakedefine CMAKE_STRICT
-#define CMAKE_ROOT_DIR "${CMake_SOURCE_DIR}"
-#define CMAKE_BUILD_DIR "${CMake_BINARY_DIR}"
+#cmakedefine CMAKE_USE_MACH_PARSER
+#cmakedefine CMAKE_ENCODING_UTF8
+#cmakedefine CMake_HAVE_CXX11_UNORDERED_MAP
#define CMAKE_DATA_DIR "/@CMAKE_DATA_DIR@"
diff --git a/Source/cmConfigureFileCommand.cxx b/Source/cmConfigureFileCommand.cxx
index e52ddef35..46b71c59b 100644
--- a/Source/cmConfigureFileCommand.cxx
+++ b/Source/cmConfigureFileCommand.cxx
@@ -26,32 +26,32 @@ bool cmConfigureFileCommand
const char* inFile = args[0].c_str();
if(!cmSystemTools::FileIsFullPath(inFile))
{
- this->InputFile = this->Makefile->GetCurrentDirectory();
+ this->InputFile = this->Makefile->GetCurrentSourceDirectory();
this->InputFile += "/";
}
this->InputFile += inFile;
// If the input location is a directory, error out.
- if(cmSystemTools::FileIsDirectory(this->InputFile.c_str()))
+ if(cmSystemTools::FileIsDirectory(this->InputFile))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "input location\n"
<< " " << this->InputFile << "\n"
<< "is a directory but a file was expected.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
const char* outFile = args[1].c_str();
if(!cmSystemTools::FileIsFullPath(outFile))
{
- this->OutputFile = this->Makefile->GetCurrentOutputDirectory();
+ this->OutputFile = this->Makefile->GetCurrentBinaryDirectory();
this->OutputFile += "/";
}
this->OutputFile += outFile;
// If the output location is already a directory put the file in it.
- if(cmSystemTools::FileIsDirectory(this->OutputFile.c_str()))
+ if(cmSystemTools::FileIsDirectory(this->OutputFile))
{
this->OutputFile += "/";
this->OutputFile += cmSystemTools::GetFilenameName(inFile);
@@ -61,23 +61,20 @@ bool cmConfigureFileCommand
{
std::string e = "attempted to configure a file: " + this->OutputFile
+ " into a source directory.";
- this->SetError(e.c_str());
+ this->SetError(e);
cmSystemTools::SetFatalErrorOccured();
return false;
}
std::string errorMessage;
if (!this->NewLineStyle.ReadFromArguments(args, errorMessage))
{
- this->SetError(errorMessage.c_str());
+ this->SetError(errorMessage);
return false;
}
this->CopyOnly = false;
this->EscapeQuotes = false;
- // for CMake 2.0 and earlier CONFIGURE_FILE defaults to the FinalPass,
- // after 2.0 it only does InitialPass
- this->Immediate = !this->Makefile->NeedBackwardsCompatibility(2,0);
-
+ std::string unknown_args;
this->AtOnly = false;
for(unsigned int i=2;i < args.size();++i)
{
@@ -101,30 +98,36 @@ bool cmConfigureFileCommand
}
else if(args[i] == "IMMEDIATE")
{
- this->Immediate = true;
+ /* Ignore legacy option. */
}
- }
-
- // If we were told to copy the file immediately, then do it on the
- // first pass (now).
- if(this->Immediate)
- {
- if ( !this->ConfigureFile() )
+ else if(args[i] == "NEWLINE_STYLE" ||
+ args[i] == "LF" || args[i] == "UNIX" ||
+ args[i] == "CRLF" || args[i] == "WIN32" ||
+ args[i] == "DOS")
{
- this->SetError("Problem configuring file");
- return false;
+ /* Options handled by NewLineStyle member above. */
+ }
+ else
+ {
+ unknown_args += " ";
+ unknown_args += args[i];
+ unknown_args += "\n";
}
}
+ if (!unknown_args.empty())
+ {
+ std::string msg = "configure_file called with unknown argument(s):\n";
+ msg += unknown_args;
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, msg);
+ }
- return true;
-}
-
-void cmConfigureFileCommand::FinalPass()
-{
- if(!this->Immediate)
+ if ( !this->ConfigureFile() )
{
- this->ConfigureFile();
+ this->SetError("Problem configuring file");
+ return false;
}
+
+ return true;
}
int cmConfigureFileCommand::ConfigureFile()
diff --git a/Source/cmConfigureFileCommand.h b/Source/cmConfigureFileCommand.h
index 0393ecfa9..8155ef736 100644
--- a/Source/cmConfigureFileCommand.h
+++ b/Source/cmConfigureFileCommand.h
@@ -34,71 +34,13 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "configure_file";}
+ virtual std::string GetName() const { return "configure_file";}
/**
* This determines if the command is invoked when in script mode.
*/
virtual bool IsScriptable() const { return true; }
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Copy a file to another location and modify its contents.";
- }
-
- /**
- * Longer documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " configure_file(<input> <output>\n"
- " [COPYONLY] [ESCAPE_QUOTES] [@ONLY] \n"
- " [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])\n"
- "Copies a file <input> to file <output> and substitutes variable "
- "values referenced in the file content. "
- "If <input> is a relative path it is evaluated with respect to "
- "the current source directory. "
- "The <input> must be a file, not a directory. "
- "If <output> is a relative path it is evaluated with respect to "
- "the current binary directory. "
- "If <output> names an existing directory the input file is placed "
- "in that directory with its original name. "
- "\n"
- "If the <input> file is modified the build system will re-run CMake "
- "to re-configure the file and generate the build system again."
- "\n"
- "This command replaces any variables in the input file referenced as "
- "${VAR} or @VAR@ with their values as determined by CMake. If a "
- "variable is not defined, it will be replaced with nothing. "
- "If COPYONLY is specified, then no variable expansion will take "
- "place. If ESCAPE_QUOTES is specified then any substituted quotes "
- "will be C-style escaped. "
- "The file will be configured with the current values of CMake "
- "variables. If @ONLY is specified, only variables "
- "of the form @VAR@ will be replaced and ${VAR} will be ignored. "
- "This is useful for configuring scripts that use ${VAR}."
- "\n"
- "Input file lines of the form \"#cmakedefine VAR ...\" "
- "will be replaced with either \"#define VAR ...\" or "
- "\"/* #undef VAR */\" depending on whether VAR is set in CMake to "
- "any value not considered a false constant by the if() command. "
- "(Content of \"...\", if any, is processed as above.) "
- "Input file lines of the form \"#cmakedefine01 VAR\" "
- "will be replaced with either \"#define VAR 1\" or "
- "\"#define VAR 0\" similarly."
- "\n"
- "With NEWLINE_STYLE the line ending could be adjusted: \n"
- " 'UNIX' or 'LF' for \\n, 'DOS', 'WIN32' or 'CRLF' for \\r\\n.\n"
- "COPYONLY must not be used with NEWLINE_STYLE.\n";
- }
-
- virtual void FinalPass();
- virtual bool HasFinalPass() const { return !this->Immediate; }
-
private:
int ConfigureFile();
@@ -108,7 +50,6 @@ private:
std::string OutputFile;
bool CopyOnly;
bool EscapeQuotes;
- bool Immediate;
bool AtOnly;
};
diff --git a/Source/cmContinueCommand.cxx b/Source/cmContinueCommand.cxx
new file mode 100644
index 000000000..4a03caade
--- /dev/null
+++ b/Source/cmContinueCommand.cxx
@@ -0,0 +1,39 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2014 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmContinueCommand.h"
+
+// cmContinueCommand
+bool cmContinueCommand::InitialPass(std::vector<std::string> const &args,
+ cmExecutionStatus &status)
+{
+ if(!this->Makefile->IsLoopBlock())
+ {
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR,
+ "A CONTINUE command was found outside of a "
+ "proper FOREACH or WHILE loop scope.");
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
+ }
+
+ status.SetContinueInvoked(true);
+
+ if(!args.empty())
+ {
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR,
+ "The CONTINUE command does not accept any "
+ "arguments.");
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
+ }
+
+ return true;
+}
diff --git a/Source/cmContinueCommand.h b/Source/cmContinueCommand.h
new file mode 100644
index 000000000..093b14f91
--- /dev/null
+++ b/Source/cmContinueCommand.h
@@ -0,0 +1,55 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2014 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmContinueCommand_h
+#define cmContinueCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmContinueCommand
+ * \brief Continue from an enclosing foreach or while loop
+ *
+ * cmContinueCommand returns from an enclosing foreach or while loop
+ */
+class cmContinueCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmContinueCommand;
+ }
+
+ /**
+ * This is called when the command is first encountered in
+ * the CMakeLists.txt file.
+ */
+ virtual bool InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus &status);
+
+ /**
+ * This determines if the command is invoked when in script mode.
+ */
+ virtual bool IsScriptable() const { return true; }
+
+ /**
+ * The name of the command as specified in CMakeList.txt.
+ */
+ virtual std::string GetName() const { return "continue"; }
+
+ cmTypeMacro(cmContinueCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index 086f27a58..4a1f770ba 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -11,9 +11,9 @@
============================================================================*/
#include "cmCoreTryCompile.h"
#include "cmake.h"
-#include "cmCacheManager.h"
-#include "cmLocalGenerator.h"
+#include "cmOutputConverter.h"
#include "cmGlobalGenerator.h"
+#include "cmAlgorithms.h"
#include "cmExportTryCompileFileGenerator.h"
#include <cmsys/Directory.hxx>
@@ -28,13 +28,13 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
const char* sourceDirectory = argv[2].c_str();
const char* projectName = 0;
- const char* targetName = 0;
- std::vector<std::string> cmakeFlags;
+ std::string targetName;
+ std::vector<std::string> cmakeFlags(1, "CMAKE_FLAGS"); // fake argv[0]
std::vector<std::string> compileDefs;
std::string outputVariable;
std::string copyFile;
std::string copyFileError;
- std::vector<cmTarget*> targets;
+ std::vector<std::string> targets;
std::string libsToLink = " ";
bool useOldLinkLibs = true;
char targetNameBuf[64];
@@ -53,10 +53,6 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
if(argv[i] == "CMAKE_FLAGS")
{
doing = DoingCMakeFlags;
- // CMAKE_FLAGS is the first argument because we need an argv[0] that
- // is not used, so it matches regular command line parsing which has
- // the program name as arg 0
- cmakeFlags.push_back(argv[i]);
}
else if(argv[i] == "COMPILE_DEFINITIONS")
{
@@ -93,29 +89,30 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
else if(doing == DoingLinkLibraries)
{
libsToLink += "\"" + cmSystemTools::TrimWhitespace(argv[i]) + "\" ";
- if(cmTarget *tgt = this->Makefile->FindTargetToUse(argv[i].c_str()))
+ if(cmTarget *tgt = this->Makefile->FindTargetToUse(argv[i]))
{
switch(tgt->GetType())
{
- case cmTarget::SHARED_LIBRARY:
- case cmTarget::STATIC_LIBRARY:
- case cmTarget::UNKNOWN_LIBRARY:
+ case cmState::SHARED_LIBRARY:
+ case cmState::STATIC_LIBRARY:
+ case cmState::INTERFACE_LIBRARY:
+ case cmState::UNKNOWN_LIBRARY:
break;
- case cmTarget::EXECUTABLE:
+ case cmState::EXECUTABLE:
if (tgt->IsExecutableWithExports())
{
break;
}
default:
this->Makefile->IssueMessage(cmake::FATAL_ERROR,
- "Only libraries may be used as try_compile IMPORTED "
+ "Only libraries may be used as try_compile or try_run IMPORTED "
"LINK_LIBRARIES. Got " + std::string(tgt->GetName()) + " of "
- "type " + tgt->GetTargetTypeName(tgt->GetType()) + ".");
+ "type " + cmState::GetTargetTypeName(tgt->GetType()) + ".");
return -1;
}
if (tgt->IsImported())
{
- targets.push_back(tgt);
+ targets.push_back(argv[i]);
}
}
}
@@ -149,7 +146,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
}
else
{
- cmOStringStream m;
+ std::ostringstream m;
m << "try_compile given unknown argument \"" << argv[i] << "\".";
this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, m.str());
}
@@ -200,13 +197,13 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
else
{
// only valid for srcfile signatures
- if (compileDefs.size())
+ if (!compileDefs.empty())
{
this->Makefile->IssueMessage(cmake::FATAL_ERROR,
"COMPILE_DEFINITIONS specified on a srcdir type TRY_COMPILE");
return -1;
}
- if (copyFile.size())
+ if (!copyFile.empty())
{
this->Makefile->IssueMessage(cmake::FATAL_ERROR,
"COPY_FILE specified on a srcdir type TRY_COMPILE");
@@ -219,7 +216,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
// do not allow recursive try Compiles
if (this->BinaryDirectory == this->Makefile->GetHomeOutputDirectory())
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Attempt at a recursive or nested TRY_COMPILE in directory\n"
<< " " << this->BinaryDirectory << "\n";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
@@ -232,7 +229,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
{
// remove any CMakeCache.txt files so we will have a clean test
std::string ccFile = this->BinaryDirectory + "/CMakeCache.txt";
- cmSystemTools::RemoveFile(ccFile.c_str());
+ cmSystemTools::RemoveFile(ccFile);
// Choose sources.
if(!useSources)
@@ -241,31 +238,27 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
}
// Detect languages to enable.
- cmLocalGenerator* lg = this->Makefile->GetLocalGenerator();
- cmGlobalGenerator* gg = lg->GetGlobalGenerator();
+ cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
std::set<std::string> testLangs;
for(std::vector<std::string>::iterator si = sources.begin();
si != sources.end(); ++si)
{
std::string ext = cmSystemTools::GetFilenameLastExtension(*si);
- if(const char* lang = gg->GetLanguageFromExtension(ext.c_str()))
+ std::string lang = gg->GetLanguageFromExtension(ext.c_str());
+ if(!lang.empty())
{
testLangs.insert(lang);
}
else
{
- cmOStringStream err;
+ std::ostringstream err;
err << "Unknown extension \"" << ext << "\" for file\n"
<< " " << *si << "\n"
<< "try_compile() works only for enabled languages. "
- << "Currently these are:\n ";
+ << "Currently these are:\n ";
std::vector<std::string> langs;
gg->GetEnabledLanguages(langs);
- for(std::vector<std::string>::iterator l = langs.begin();
- l != langs.end(); ++l)
- {
- err << " " << *l;
- }
+ err << cmJoin(langs, " ");
err << "\nSee project() command to enable other languages.";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, err.str());
return -1;
@@ -277,12 +270,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
sourceDirectory = this->BinaryDirectory.c_str();
// now create a CMakeLists.txt file in that directory
- FILE *fout = fopen(outFileName.c_str(),"w");
+ FILE *fout = cmsys::SystemTools::Fopen(outFileName,"w");
if (!fout)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Failed to open\n"
- << " " << outFileName.c_str() << "\n"
+ << " " << outFileName << "\n"
<< cmSystemTools::GetLastSystemError();
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
return -1;
@@ -294,7 +287,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
cmVersion::GetPatchVersion(), cmVersion::GetTweakVersion());
if(def)
{
- fprintf(fout, "SET(CMAKE_MODULE_PATH %s)\n", def);
+ fprintf(fout, "set(CMAKE_MODULE_PATH \"%s\")\n", def);
}
std::string projectLangs;
@@ -305,57 +298,86 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
std::string rulesOverrideBase = "CMAKE_USER_MAKE_RULES_OVERRIDE";
std::string rulesOverrideLang = rulesOverrideBase + "_" + *li;
if(const char* rulesOverridePath =
- this->Makefile->GetDefinition(rulesOverrideLang.c_str()))
+ this->Makefile->GetDefinition(rulesOverrideLang))
{
- fprintf(fout, "SET(%s \"%s\")\n",
+ fprintf(fout, "set(%s \"%s\")\n",
rulesOverrideLang.c_str(), rulesOverridePath);
}
else if(const char* rulesOverridePath2 =
- this->Makefile->GetDefinition(rulesOverrideBase.c_str()))
+ this->Makefile->GetDefinition(rulesOverrideBase))
{
- fprintf(fout, "SET(%s \"%s\")\n",
+ fprintf(fout, "set(%s \"%s\")\n",
rulesOverrideBase.c_str(), rulesOverridePath2);
}
}
- fprintf(fout, "PROJECT(CMAKE_TRY_COMPILE%s)\n", projectLangs.c_str());
- fprintf(fout, "SET(CMAKE_VERBOSE_MAKEFILE 1)\n");
+ fprintf(fout, "project(CMAKE_TRY_COMPILE%s)\n", projectLangs.c_str());
+ fprintf(fout, "set(CMAKE_VERBOSE_MAKEFILE 1)\n");
for(std::set<std::string>::iterator li = testLangs.begin();
li != testLangs.end(); ++li)
{
std::string langFlags = "CMAKE_" + *li + "_FLAGS";
- const char* flags = this->Makefile->GetDefinition(langFlags.c_str());
- fprintf(fout, "SET(CMAKE_%s_FLAGS %s)\n", li->c_str(),
- lg->EscapeForCMake(flags?flags:"").c_str());
- fprintf(fout, "SET(CMAKE_%s_FLAGS \"${CMAKE_%s_FLAGS}"
+ const char* flags = this->Makefile->GetDefinition(langFlags);
+ fprintf(fout, "set(CMAKE_%s_FLAGS %s)\n", li->c_str(),
+ cmOutputConverter::EscapeForCMake(flags?flags:"").c_str());
+ fprintf(fout, "set(CMAKE_%s_FLAGS \"${CMAKE_%s_FLAGS}"
" ${COMPILE_DEFINITIONS}\")\n", li->c_str(), li->c_str());
}
- fprintf(fout, "INCLUDE_DIRECTORIES(${INCLUDE_DIRECTORIES})\n");
- fprintf(fout, "SET(CMAKE_SUPPRESS_REGENERATION 1)\n");
- fprintf(fout, "LINK_DIRECTORIES(${LINK_DIRECTORIES})\n");
- // handle any compile flags we need to pass on
- if (compileDefs.size())
+ switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0056))
{
- fprintf(fout, "ADD_DEFINITIONS( ");
- for (size_t i = 0; i < compileDefs.size(); ++i)
+ case cmPolicies::WARN:
+ if(this->Makefile->PolicyOptionalWarningEnabled(
+ "CMAKE_POLICY_WARNING_CMP0056"))
+ {
+ std::ostringstream w;
+ w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0056) << "\n"
+ "For compatibility with older versions of CMake, try_compile "
+ "is not honoring caller link flags (e.g. CMAKE_EXE_LINKER_FLAGS) "
+ "in the test project."
+ ;
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ }
+ case cmPolicies::OLD:
+ // OLD behavior is to do nothing.
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0056)
+ );
+ case cmPolicies::NEW:
+ // NEW behavior is to pass linker flags.
{
- fprintf(fout,"%s ",compileDefs[i].c_str());
- }
- fprintf(fout, ")\n");
+ const char* exeLinkFlags =
+ this->Makefile->GetDefinition("CMAKE_EXE_LINKER_FLAGS");
+ fprintf(fout, "set(CMAKE_EXE_LINKER_FLAGS %s)\n",
+ cmOutputConverter::EscapeForCMake(
+ exeLinkFlags ? exeLinkFlags : "").c_str());
+ } break;
+ }
+ fprintf(fout, "set(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS}"
+ " ${EXE_LINKER_FLAGS}\")\n");
+ fprintf(fout, "include_directories(${INCLUDE_DIRECTORIES})\n");
+ fprintf(fout, "set(CMAKE_SUPPRESS_REGENERATION 1)\n");
+ fprintf(fout, "link_directories(${LINK_DIRECTORIES})\n");
+ // handle any compile flags we need to pass on
+ if (!compileDefs.empty())
+ {
+ fprintf(fout, "add_definitions(%s)\n", cmJoin(compileDefs, " ").c_str());
}
/* Use a random file name to avoid rapid creation and deletion
of the same executable name (some filesystems fail on that). */
- sprintf(targetNameBuf, "cmTryCompileExec%u",
- cmSystemTools::RandomSeed());
+ sprintf(targetNameBuf, "cmTC_%05x",
+ cmSystemTools::RandomSeed() & 0xFFFFF);
targetName = targetNameBuf;
if (!targets.empty())
{
std::string fname = "/" + std::string(targetName) + "Targets.cmake";
- cmExportTryCompileFileGenerator tcfg;
+ cmExportTryCompileFileGenerator tcfg(gg, targets, this->Makefile);
tcfg.SetExportFile((this->BinaryDirectory + fname).c_str());
- tcfg.SetExports(targets);
- tcfg.SetConfig(this->Makefile->GetDefinition(
+ tcfg.SetConfig(this->Makefile->GetSafeDefinition(
"CMAKE_TRY_COMPILE_CONFIGURATION"));
if(!tcfg.GenerateImportFile())
@@ -371,8 +393,8 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
}
/* for the TRY_COMPILEs we want to be able to specify the architecture.
- So the user can set CMAKE_OSX_ARCHITECTURE to i386;ppc and then set
- CMAKE_TRY_COMPILE_OSX_ARCHITECTURE first to i386 and then to ppc to
+ So the user can set CMAKE_OSX_ARCHITECTURES to i386;ppc and then set
+ CMAKE_TRY_COMPILE_OSX_ARCHITECTURES first to i386 and then to ppc to
have the tests run for each specific architecture. Since
cmLocalGenerator doesn't allow building for "the other"
architecture only via CMAKE_OSX_ARCHITECTURES.
@@ -404,16 +426,71 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
flag += this->Makefile->GetSafeDefinition("CMAKE_OSX_DEPLOYMENT_TARGET");
cmakeFlags.push_back(flag);
}
+ if (const char *cxxDef
+ = this->Makefile->GetDefinition("CMAKE_CXX_COMPILER_TARGET"))
+ {
+ std::string flag="-DCMAKE_CXX_COMPILER_TARGET=";
+ flag += cxxDef;
+ cmakeFlags.push_back(flag);
+ }
+ if (const char *cDef
+ = this->Makefile->GetDefinition("CMAKE_C_COMPILER_TARGET"))
+ {
+ std::string flag="-DCMAKE_C_COMPILER_TARGET=";
+ flag += cDef;
+ cmakeFlags.push_back(flag);
+ }
+ if (const char *tcxxDef = this->Makefile->GetDefinition(
+ "CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN"))
+ {
+ std::string flag="-DCMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN=";
+ flag += tcxxDef;
+ cmakeFlags.push_back(flag);
+ }
+ if (const char *tcDef = this->Makefile->GetDefinition(
+ "CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN"))
+ {
+ std::string flag="-DCMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN=";
+ flag += tcDef;
+ cmakeFlags.push_back(flag);
+ }
+ if (const char *rootDef
+ = this->Makefile->GetDefinition("CMAKE_SYSROOT"))
+ {
+ std::string flag="-DCMAKE_SYSROOT=";
+ flag += rootDef;
+ cmakeFlags.push_back(flag);
+ }
if(this->Makefile->GetDefinition("CMAKE_POSITION_INDEPENDENT_CODE")!=0)
{
- fprintf(fout, "SET(CMAKE_POSITION_INDEPENDENT_CODE \"ON\")\n");
+ fprintf(fout, "set(CMAKE_POSITION_INDEPENDENT_CODE \"ON\")\n");
+ }
+ if (const char *lssDef = this->Makefile->GetDefinition(
+ "CMAKE_LINK_SEARCH_START_STATIC"))
+ {
+ fprintf(fout, "set(CMAKE_LINK_SEARCH_START_STATIC \"%s\")\n", lssDef);
+ }
+ if (const char *lssDef = this->Makefile->GetDefinition(
+ "CMAKE_LINK_SEARCH_END_STATIC"))
+ {
+ fprintf(fout, "set(CMAKE_LINK_SEARCH_END_STATIC \"%s\")\n", lssDef);
+ }
+
+ /* Set the appropriate policy information for ENABLE_EXPORTS */
+ fprintf(fout, "cmake_policy(SET CMP0065 %s)\n",
+ this->Makefile->GetPolicyStatus(cmPolicies::CMP0065) ==
+ cmPolicies::NEW ? "NEW" : "OLD");
+ if(const char *ee = this->Makefile->GetDefinition(
+ "CMAKE_ENABLE_EXPORTS"))
+ {
+ fprintf(fout, "set(CMAKE_ENABLE_EXPORTS %s)\n", ee);
}
/* Put the executable at a known location (for COPY_FILE). */
- fprintf(fout, "SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY \"%s\")\n",
+ fprintf(fout, "set(CMAKE_RUNTIME_OUTPUT_DIRECTORY \"%s\")\n",
this->BinaryDirectory.c_str());
/* Create the actual executable. */
- fprintf(fout, "ADD_EXECUTABLE(%s", targetName);
+ fprintf(fout, "add_executable(%s", targetName.c_str());
for(std::vector<std::string>::iterator si = sources.begin();
si != sources.end(); ++si)
{
@@ -429,12 +506,13 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
if (useOldLinkLibs)
{
fprintf(fout,
- "TARGET_LINK_LIBRARIES(%s ${LINK_LIBRARIES})\n",targetName);
+ "target_link_libraries(%s ${LINK_LIBRARIES})\n",
+ targetName.c_str());
}
else
{
- fprintf(fout, "TARGET_LINK_LIBRARIES(%s %s)\n",
- targetName,
+ fprintf(fout, "target_link_libraries(%s %s)\n",
+ targetName.c_str(),
libsToLink.c_str());
}
fclose(fout);
@@ -446,26 +524,26 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
std::string output;
// actually do the try compile now that everything is setup
int res = this->Makefile->TryCompile(sourceDirectory,
- this->BinaryDirectory.c_str(),
+ this->BinaryDirectory,
projectName,
targetName,
this->SrcFileSignature,
&cmakeFlags,
- &output);
+ output);
if ( erroroc )
{
cmSystemTools::SetErrorOccured();
}
// set the result var to the return value to indicate success or failure
- this->Makefile->AddCacheDefinition(argv[0].c_str(),
+ this->Makefile->AddCacheDefinition(argv[0],
(res == 0 ? "TRUE" : "FALSE"),
"Result of TRY_COMPILE",
- cmCacheManager::INTERNAL);
+ cmState::INTERNAL);
- if ( outputVariable.size() > 0 )
+ if (!outputVariable.empty())
{
- this->Makefile->AddDefinition(outputVariable.c_str(), output.c_str());
+ this->Makefile->AddDefinition(outputVariable, output.c_str());
}
if (this->SrcFileSignature)
@@ -473,17 +551,17 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
std::string copyFileErrorMessage;
this->FindOutputFile(targetName);
- if ((res==0) && (copyFile.size()))
+ if ((res==0) && !copyFile.empty())
{
if(this->OutputFile.empty() ||
- !cmSystemTools::CopyFileAlways(this->OutputFile.c_str(),
- copyFile.c_str()))
+ !cmSystemTools::CopyFileAlways(this->OutputFile,
+ copyFile))
{
- cmOStringStream emsg;
+ std::ostringstream emsg;
emsg << "Cannot copy output executable\n"
- << " '" << this->OutputFile.c_str() << "'\n"
+ << " '" << this->OutputFile << "'\n"
<< "to destination specified by COPY_FILE:\n"
- << " '" << copyFile.c_str() << "'\n";
+ << " '" << copyFile << "'\n";
if(!this->FindErrorMessage.empty())
{
emsg << this->FindErrorMessage.c_str();
@@ -502,7 +580,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
if(!copyFileError.empty())
{
- this->Makefile->AddDefinition(copyFileError.c_str(),
+ this->Makefile->AddDefinition(copyFileError,
copyFileErrorMessage.c_str());
}
}
@@ -528,7 +606,7 @@ void cmCoreTryCompile::CleanupFiles(const char* binDir)
cmsys::Directory dir;
dir.Load(binDir);
size_t fileNum;
- std::set<cmStdString> deletedFiles;
+ std::set<std::string> deletedFiles;
for (fileNum = 0; fileNum < dir.GetNumberOfFiles(); ++fileNum)
{
if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)),".") &&
@@ -542,22 +620,27 @@ void cmCoreTryCompile::CleanupFiles(const char* binDir)
std::string fullPath = binDir;
fullPath += "/";
fullPath += dir.GetFile(static_cast<unsigned long>(fileNum));
- if(cmSystemTools::FileIsDirectory(fullPath.c_str()))
+ if(cmSystemTools::FileIsDirectory(fullPath))
{
this->CleanupFiles(fullPath.c_str());
- cmSystemTools::RemoveADirectory(fullPath.c_str());
+ cmSystemTools::RemoveADirectory(fullPath);
}
else
{
+#ifdef _WIN32
// Sometimes anti-virus software hangs on to new files so we
// cannot delete them immediately. Try a few times.
- int tries = 5;
+ cmSystemTools::WindowsFileRetry retry =
+ cmSystemTools::GetWindowsFileRetry();
while(!cmSystemTools::RemoveFile(fullPath.c_str()) &&
- --tries && cmSystemTools::FileExists(fullPath.c_str()))
+ --retry.Count && cmSystemTools::FileExists(fullPath.c_str()))
{
- cmSystemTools::Delay(500);
+ cmSystemTools::Delay(retry.Delay);
}
- if(tries == 0)
+ if(retry.Count == 0)
+#else
+ if(!cmSystemTools::RemoveFile(fullPath))
+#endif
{
std::string m = "Remove failed on file: " + fullPath;
cmSystemTools::ReportLastSystemError(m.c_str());
@@ -568,7 +651,7 @@ void cmCoreTryCompile::CleanupFiles(const char* binDir)
}
}
-void cmCoreTryCompile::FindOutputFile(const char* targetName)
+void cmCoreTryCompile::FindOutputFile(const std::string& targetName)
{
this->FindErrorMessage = "";
this->OutputFile = "";
@@ -591,6 +674,10 @@ void cmCoreTryCompile::FindOutputFile(const char* targetName)
searchDirs.push_back(tmp);
}
searchDirs.push_back("/Debug");
+#if defined(__APPLE__)
+ std::string app = "/Debug/" + targetName + ".app";
+ searchDirs.push_back(app);
+#endif
searchDirs.push_back("/Development");
for(std::vector<std::string>::const_iterator it = searchDirs.begin();
@@ -602,19 +689,16 @@ void cmCoreTryCompile::FindOutputFile(const char* targetName)
command += tmpOutputFile;
if(cmSystemTools::FileExists(command.c_str()))
{
- tmpOutputFile = cmSystemTools::CollapseFullPath(command.c_str());
- this->OutputFile = tmpOutputFile;
+ this->OutputFile = cmSystemTools::CollapseFullPath(command);
return;
}
}
- cmOStringStream emsg;
+ std::ostringstream emsg;
emsg << "Unable to find the executable at any of:\n";
- for (unsigned int i = 0; i < searchDirs.size(); ++i)
- {
- emsg << " " << this->BinaryDirectory << searchDirs[i]
- << tmpOutputFile << "\n";
- }
+ emsg << cmWrap(" " + this->BinaryDirectory,
+ searchDirs,
+ tmpOutputFile, "\n") << "\n";
this->FindErrorMessage = emsg.str();
return;
}
diff --git a/Source/cmCoreTryCompile.h b/Source/cmCoreTryCompile.h
index 5c67f1355..3272462d9 100644
--- a/Source/cmCoreTryCompile.h
+++ b/Source/cmCoreTryCompile.h
@@ -44,7 +44,7 @@ public:
TryCompileCode. The result is stored in OutputFile. If nothing is found,
the error message is stored in FindErrorMessage.
*/
- void FindOutputFile(const char* targetName);
+ void FindOutputFile(const std::string& targetName);
cmTypeMacro(cmCoreTryCompile, cmCommand);
diff --git a/Source/cmCreateTestSourceList.cxx b/Source/cmCreateTestSourceList.cxx
index de20cb7ef..54c27d6ce 100644
--- a/Source/cmCreateTestSourceList.cxx
+++ b/Source/cmCreateTestSourceList.cxx
@@ -73,7 +73,7 @@ bool cmCreateTestSourceList
"You must specify a file extension for the test driver file.");
return false;
}
- std::string driver = this->Makefile->GetCurrentOutputDirectory();
+ std::string driver = this->Makefile->GetCurrentBinaryDirectory();
driver += "/";
driver += *i;
++i;
@@ -101,7 +101,7 @@ bool cmCreateTestSourceList
break;
}
std::string func_name;
- if (cmSystemTools::GetFilenamePath(*i).size() > 0)
+ if (!cmSystemTools::GetFilenamePath(*i).empty())
{
func_name = cmSystemTools::GetFilenamePath(*i) + "/" +
cmSystemTools::GetFilenameWithoutLastExtension(*i);
@@ -126,7 +126,7 @@ bool cmCreateTestSourceList
for(i = testsBegin, j = tests_func_name.begin(); i != tests.end(); ++i, ++j)
{
std::string func_name;
- if (cmSystemTools::GetFilenamePath(*i).size() > 0)
+ if (!cmSystemTools::GetFilenamePath(*i).empty())
{
func_name = cmSystemTools::GetFilenamePath(*i) + "/" +
cmSystemTools::GetFilenameWithoutLastExtension(*i);
@@ -145,12 +145,12 @@ bool cmCreateTestSourceList
" },\n";
numTests++;
}
- if(extraInclude.size())
+ if(!extraInclude.empty())
{
this->Makefile->AddDefinition("CMAKE_TESTDRIVER_EXTRA_INCLUDES",
extraInclude.c_str());
}
- if(function.size())
+ if(!function.empty())
{
this->Makefile->AddDefinition("CMAKE_TESTDRIVER_ARGVC_FUNCTION",
function.c_str());
@@ -169,13 +169,13 @@ bool cmCreateTestSourceList
// Construct the source list.
std::string sourceListValue;
{
- cmSourceFile* sf = this->Makefile->GetOrCreateSource(driver.c_str());
+ cmSourceFile* sf = this->Makefile->GetOrCreateSource(driver);
sf->SetProperty("ABSTRACT","0");
sourceListValue = args[1];
}
for(i = testsBegin; i != tests.end(); ++i)
{
- cmSourceFile* sf = this->Makefile->GetOrCreateSource(i->c_str());
+ cmSourceFile* sf = this->Makefile->GetOrCreateSource(*i);
sf->SetProperty("ABSTRACT","0");
sourceListValue += ";";
sourceListValue += *i;
diff --git a/Source/cmCreateTestSourceList.h b/Source/cmCreateTestSourceList.h
index 3aa0a79cf..2f6b541f8 100644
--- a/Source/cmCreateTestSourceList.h
+++ b/Source/cmCreateTestSourceList.h
@@ -15,7 +15,7 @@
#include "cmCommand.h"
/** \class cmCreateTestSourceList
- * \brief
+ * \brief Test driver generation command
*
*/
@@ -40,47 +40,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const {return "create_test_sourcelist";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Create a test driver and source list for building test programs.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " create_test_sourcelist(sourceListName driverName\n"
- " test1 test2 test3\n"
- " EXTRA_INCLUDE include.h\n"
- " FUNCTION function)\n"
- "A test driver is a program that links together many small tests into "
- "a single executable. This is useful when building static executables "
- "with large libraries to shrink the total required size. "
- "The list of source files "
- "needed to build the test driver will be in sourceListName. "
- "DriverName is the name of the test driver program. The rest of "
- "the arguments consist of a list of test source files, can be "
- "semicolon separated. Each test source file should have a function in "
- "it that is the same name as the file with no extension (foo.cxx "
- "should have int foo(int, char*[]);) DriverName will be able to "
- "call each of the "
- "tests by name on the command line. If EXTRA_INCLUDE is specified, "
- "then the next argument is included into the generated file. If "
- "FUNCTION is specified, then the next argument is taken as a function "
- "name that is passed a pointer to ac and av. This can be used to add "
- "extra command line processing to each test. The cmake variable "
- "CMAKE_TESTDRIVER_BEFORE_TESTMAIN can be set to have code that will be "
- "placed directly before calling the test main function. "
- "CMAKE_TESTDRIVER_AFTER_TESTMAIN can be set to have code that will be "
- "placed directly after the call to the test main function.";
- }
+ virtual std::string GetName() const {return "create_test_sourcelist";}
cmTypeMacro(cmCreateTestSourceList, cmCommand);
};
diff --git a/Source/cmCryptoHash.cxx b/Source/cmCryptoHash.cxx
index a4f6ac4b4..66162181e 100644
--- a/Source/cmCryptoHash.cxx
+++ b/Source/cmCryptoHash.cxx
@@ -12,6 +12,7 @@
#include "cmCryptoHash.h"
#include <cmsys/MD5.h>
+#include <cmsys/FStream.hxx>
#include "cm_sha2.h"
//----------------------------------------------------------------------------
@@ -34,18 +35,18 @@ cmsys::auto_ptr<cmCryptoHash> cmCryptoHash::New(const char* algo)
}
//----------------------------------------------------------------------------
-std::string cmCryptoHash::HashString(const char* input)
+std::string cmCryptoHash::HashString(const std::string& input)
{
this->Initialize();
- this->Append(reinterpret_cast<unsigned char const*>(input),
- static_cast<int>(strlen(input)));
+ this->Append(reinterpret_cast<unsigned char const*>(input.c_str()),
+ static_cast<int>(input.size()));
return this->Finalize();
}
//----------------------------------------------------------------------------
-std::string cmCryptoHash::HashFile(const char* file)
+std::string cmCryptoHash::HashFile(const std::string& file)
{
- std::ifstream fin(file, std::ios::in | cmsys_ios_binary);
+ cmsys::ifstream fin(file.c_str(), std::ios::in | std::ios::binary);
if(!fin)
{
return "";
diff --git a/Source/cmCryptoHash.h b/Source/cmCryptoHash.h
index 1bea9abcb..88cd240c0 100644
--- a/Source/cmCryptoHash.h
+++ b/Source/cmCryptoHash.h
@@ -21,8 +21,8 @@ class cmCryptoHash
public:
virtual ~cmCryptoHash() {}
static cmsys::auto_ptr<cmCryptoHash> New(const char* algo);
- std::string HashString(const char* input);
- std::string HashFile(const char* file);
+ std::string HashString(const std::string& input);
+ std::string HashFile(const std::string& file);
protected:
virtual void Initialize()=0;
virtual void Append(unsigned char const*, int)=0;
diff --git a/Source/cmCurl.cxx b/Source/cmCurl.cxx
new file mode 100644
index 000000000..4f3d89083
--- /dev/null
+++ b/Source/cmCurl.cxx
@@ -0,0 +1,69 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmCurl.h"
+#include "cmSystemTools.h"
+
+// curl versions before 7.21.5 did not provide this error code
+#if defined(LIBCURL_VERSION_NUM) && LIBCURL_VERSION_NUM < 0x071505
+# define CURLE_NOT_BUILT_IN 4
+#endif
+
+#define check_curl_result(result, errstr) \
+ if (result != CURLE_OK && result != CURLE_NOT_BUILT_IN) \
+ { \
+ e += e.empty()? "" : "\n"; \
+ e += errstr; \
+ e += ::curl_easy_strerror(result); \
+ }
+
+//----------------------------------------------------------------------------
+std::string cmCurlSetCAInfo(::CURL *curl, const char* cafile)
+{
+ std::string e;
+ if(cafile && *cafile)
+ {
+ ::CURLcode res = ::curl_easy_setopt(curl, CURLOPT_CAINFO, cafile);
+ check_curl_result(res, "Unable to set TLS/SSL Verify CAINFO: ");
+ }
+#if !defined(CMAKE_USE_SYSTEM_CURL) && \
+ !defined(_WIN32) && !defined(__APPLE__) && \
+ !defined(CURL_CA_BUNDLE) && !defined(CURL_CA_PATH)
+# define CMAKE_CAFILE_FEDORA "/etc/pki/tls/certs/ca-bundle.crt"
+ else if(cmSystemTools::FileExists(CMAKE_CAFILE_FEDORA, true))
+ {
+ ::CURLcode res =
+ ::curl_easy_setopt(curl, CURLOPT_CAINFO, CMAKE_CAFILE_FEDORA);
+ check_curl_result(res, "Unable to set TLS/SSL Verify CAINFO: ");
+ }
+# undef CMAKE_CAFILE_FEDORA
+ else
+ {
+# define CMAKE_CAFILE_COMMON "/etc/ssl/certs/ca-certificates.crt"
+ if(cmSystemTools::FileExists(CMAKE_CAFILE_COMMON, true))
+ {
+ ::CURLcode res =
+ ::curl_easy_setopt(curl, CURLOPT_CAINFO, CMAKE_CAFILE_COMMON);
+ check_curl_result(res, "Unable to set TLS/SSL Verify CAINFO: ");
+ }
+# undef CMAKE_CAFILE_COMMON
+# define CMAKE_CAPATH_COMMON "/etc/ssl/certs"
+ if(cmSystemTools::FileIsDirectory(CMAKE_CAPATH_COMMON))
+ {
+ ::CURLcode res =
+ ::curl_easy_setopt(curl, CURLOPT_CAPATH, CMAKE_CAPATH_COMMON);
+ check_curl_result(res, "Unable to set TLS/SSL Verify CAPATH: ");
+ }
+# undef CMAKE_CAPATH_COMMON
+ }
+#endif
+ return e;
+}
diff --git a/Source/cmCurl.h b/Source/cmCurl.h
new file mode 100644
index 000000000..0c5609ca7
--- /dev/null
+++ b/Source/cmCurl.h
@@ -0,0 +1,21 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmCurl_h
+#define cmCurl_h
+
+#include <cmsys/Configure.h>
+#include "cm_curl.h"
+#include "cmStandardIncludes.h"
+
+std::string cmCurlSetCAInfo(::CURL *curl, const char* cafile = 0);
+
+#endif
diff --git a/Source/cmCustomCommand.cxx b/Source/cmCustomCommand.cxx
index 3620a3895..7c37e3b96 100644
--- a/Source/cmCustomCommand.cxx
+++ b/Source/cmCustomCommand.cxx
@@ -17,97 +17,49 @@
//----------------------------------------------------------------------------
cmCustomCommand::cmCustomCommand()
+ : Backtrace()
{
this->HaveComment = false;
this->EscapeOldStyle = true;
this->EscapeAllowMakeVars = false;
+ this->UsesTerminal = false;
}
//----------------------------------------------------------------------------
-cmCustomCommand::cmCustomCommand(const cmCustomCommand& r):
- Outputs(r.Outputs),
- Depends(r.Depends),
- CommandLines(r.CommandLines),
- HaveComment(r.HaveComment),
- Comment(r.Comment),
- WorkingDirectory(r.WorkingDirectory),
- EscapeAllowMakeVars(r.EscapeAllowMakeVars),
- EscapeOldStyle(r.EscapeOldStyle),
- Backtrace(new cmListFileBacktrace(*r.Backtrace))
-{
-}
-
-//----------------------------------------------------------------------------
-cmCustomCommand& cmCustomCommand::operator=(cmCustomCommand const& r)
-{
- if(this == &r)
- {
- return *this;
- }
-
- this->Outputs = r.Outputs;
- this->Depends = r.Depends;
- this->CommandLines = r.CommandLines;
- this->HaveComment = r.HaveComment;
- this->Comment = r.Comment;
- this->WorkingDirectory = r.WorkingDirectory;
- this->EscapeAllowMakeVars = r.EscapeAllowMakeVars;
- this->EscapeOldStyle = r.EscapeOldStyle;
- this->ImplicitDepends = r.ImplicitDepends;
-
- cmsys::auto_ptr<cmListFileBacktrace>
- newBacktrace(new cmListFileBacktrace(*r.Backtrace));
- delete this->Backtrace;
- this->Backtrace = newBacktrace.release();
-
- return *this;
-}
-
-//----------------------------------------------------------------------------
-cmCustomCommand::cmCustomCommand(cmMakefile* mf,
+cmCustomCommand::cmCustomCommand(cmMakefile const* mf,
const std::vector<std::string>& outputs,
+ const std::vector<std::string>& byproducts,
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines,
const char* comment,
const char* workingDirectory):
Outputs(outputs),
+ Byproducts(byproducts),
Depends(depends),
CommandLines(commandLines),
- HaveComment(comment?true:false),
+ Backtrace(),
Comment(comment?comment:""),
WorkingDirectory(workingDirectory?workingDirectory:""),
+ HaveComment(comment?true:false),
EscapeAllowMakeVars(false),
- EscapeOldStyle(true),
- Backtrace(new cmListFileBacktrace)
+ EscapeOldStyle(true)
{
- this->EscapeOldStyle = true;
- this->EscapeAllowMakeVars = false;
if(mf)
{
- mf->GetBacktrace(*this->Backtrace);
+ this->Backtrace = mf->GetBacktrace();
}
}
//----------------------------------------------------------------------------
-cmCustomCommand::~cmCustomCommand()
-{
- delete this->Backtrace;
-}
-
-//----------------------------------------------------------------------------
const std::vector<std::string>& cmCustomCommand::GetOutputs() const
{
return this->Outputs;
}
//----------------------------------------------------------------------------
-const char* cmCustomCommand::GetWorkingDirectory() const
+const std::vector<std::string>& cmCustomCommand::GetByproducts() const
{
- if(this->WorkingDirectory.size() == 0)
- {
- return 0;
- }
- return this->WorkingDirectory.c_str();
+ return this->Byproducts;
}
//----------------------------------------------------------------------------
@@ -132,21 +84,14 @@ const char* cmCustomCommand::GetComment() const
//----------------------------------------------------------------------------
void cmCustomCommand::AppendCommands(const cmCustomCommandLines& commandLines)
{
- for(cmCustomCommandLines::const_iterator i=commandLines.begin();
- i != commandLines.end(); ++i)
- {
- this->CommandLines.push_back(*i);
- }
+ this->CommandLines.insert(this->CommandLines.end(),
+ commandLines.begin(), commandLines.end());
}
//----------------------------------------------------------------------------
void cmCustomCommand::AppendDepends(const std::vector<std::string>& depends)
{
- for(std::vector<std::string>::const_iterator i=depends.begin();
- i != depends.end(); ++i)
- {
- this->Depends.push_back(*i);
- }
+ this->Depends.insert(this->Depends.end(), depends.begin(), depends.end());
}
//----------------------------------------------------------------------------
@@ -176,7 +121,7 @@ void cmCustomCommand::SetEscapeAllowMakeVars(bool b)
//----------------------------------------------------------------------------
cmListFileBacktrace const& cmCustomCommand::GetBacktrace() const
{
- return *this->Backtrace;
+ return this->Backtrace;
}
//----------------------------------------------------------------------------
@@ -198,3 +143,15 @@ void cmCustomCommand::AppendImplicitDepends(ImplicitDependsList const& l)
this->ImplicitDepends.insert(this->ImplicitDepends.end(),
l.begin(), l.end());
}
+
+//----------------------------------------------------------------------------
+bool cmCustomCommand::GetUsesTerminal() const
+{
+ return this->UsesTerminal;
+}
+
+//----------------------------------------------------------------------------
+void cmCustomCommand::SetUsesTerminal(bool b)
+{
+ this->UsesTerminal = b;
+}
diff --git a/Source/cmCustomCommand.h b/Source/cmCustomCommand.h
index e20d2bf40..f9b38c3c4 100644
--- a/Source/cmCustomCommand.h
+++ b/Source/cmCustomCommand.h
@@ -13,8 +13,8 @@
#define cmCustomCommand_h
#include "cmStandardIncludes.h"
+#include "cmListFileCache.h"
class cmMakefile;
-class cmListFileBacktrace;
/** \class cmCustomCommand
* \brief A class to encapsulate a custom command
@@ -26,28 +26,29 @@ class cmCustomCommand
public:
/** Default and copy constructors for STL containers. */
cmCustomCommand();
- cmCustomCommand(const cmCustomCommand& r);
- cmCustomCommand& operator=(cmCustomCommand const& r);
/** Main constructor specifies all information for the command. */
- cmCustomCommand(cmMakefile* mf,
+ cmCustomCommand(cmMakefile const* mf,
const std::vector<std::string>& outputs,
+ const std::vector<std::string>& byproducts,
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines,
const char* comment,
const char* workingDirectory);
- ~cmCustomCommand();
-
/** Get the output file produced by the command. */
const std::vector<std::string>& GetOutputs() const;
- /** Get the working directory. */
- const char* GetWorkingDirectory() const;
+ /** Get the extra files produced by the command. */
+ const std::vector<std::string>& GetByproducts() const;
/** Get the vector that holds the list of dependencies. */
const std::vector<std::string>& GetDepends() const;
+ /** Get the working directory. */
+ std::string const& GetWorkingDirectory() const
+ { return this->WorkingDirectory; }
+
/** Get the list of command lines. */
const cmCustomCommandLines& GetCommandLines() const;
@@ -72,23 +73,30 @@ public:
/** Backtrace of the command that created this custom command. */
cmListFileBacktrace const& GetBacktrace() const;
- typedef std::pair<cmStdString, cmStdString> ImplicitDependsPair;
+ typedef std::pair<std::string, std::string> ImplicitDependsPair;
class ImplicitDependsList: public std::vector<ImplicitDependsPair> {};
void SetImplicitDepends(ImplicitDependsList const&);
void AppendImplicitDepends(ImplicitDependsList const&);
ImplicitDependsList const& GetImplicitDepends() const;
+ /** Set/Get whether this custom command should be given access to the
+ real console (if possible). */
+ bool GetUsesTerminal() const;
+ void SetUsesTerminal(bool b);
+
private:
std::vector<std::string> Outputs;
+ std::vector<std::string> Byproducts;
std::vector<std::string> Depends;
cmCustomCommandLines CommandLines;
- bool HaveComment;
+ cmListFileBacktrace Backtrace;
+ ImplicitDependsList ImplicitDepends;
std::string Comment;
std::string WorkingDirectory;
+ bool HaveComment;
bool EscapeAllowMakeVars;
bool EscapeOldStyle;
- cmListFileBacktrace* Backtrace;
- ImplicitDependsList ImplicitDepends;
+ bool UsesTerminal;
};
#endif
diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx
index f2f77eea0..dc06678cf 100644
--- a/Source/cmCustomCommandGenerator.cxx
+++ b/Source/cmCustomCommandGenerator.cxx
@@ -12,16 +12,17 @@
#include "cmCustomCommandGenerator.h"
#include "cmMakefile.h"
-#include "cmCustomCommand.h"
#include "cmLocalGenerator.h"
+#include "cmCustomCommand.h"
+#include "cmOutputConverter.h"
#include "cmGeneratorExpression.h"
//----------------------------------------------------------------------------
cmCustomCommandGenerator::cmCustomCommandGenerator(
- cmCustomCommand const& cc, const char* config, cmMakefile* mf):
- CC(cc), Config(config), Makefile(mf), LG(mf->GetLocalGenerator()),
+ cmCustomCommand const& cc, const std::string& config, cmLocalGenerator* lg):
+ CC(cc), Config(config), LG(lg),
OldStyle(cc.GetEscapeOldStyle()), MakeVars(cc.GetEscapeAllowMakeVars()),
- GE(new cmGeneratorExpression(cc.GetBacktrace()))
+ GE(new cmGeneratorExpression(cc.GetBacktrace())), DependsDone(false)
{
}
@@ -41,13 +42,44 @@ unsigned int cmCustomCommandGenerator::GetNumberOfCommands() const
std::string cmCustomCommandGenerator::GetCommand(unsigned int c) const
{
std::string const& argv0 = this->CC.GetCommandLines()[c][0];
- cmTarget* target = this->Makefile->FindTargetToUse(argv0.c_str());
- if(target && target->GetType() == cmTarget::EXECUTABLE &&
- (target->IsImported() || !this->Makefile->IsOn("CMAKE_CROSSCOMPILING")))
+ cmGeneratorTarget* target =
+ this->LG->FindGeneratorTargetToUse(argv0);
+ if(target && target->GetType() == cmState::EXECUTABLE &&
+ (target->IsImported()
+ || !this->LG->GetMakefile()->IsOn("CMAKE_CROSSCOMPILING")))
{
return target->GetLocation(this->Config);
}
- return this->GE->Parse(argv0)->Evaluate(this->Makefile, this->Config);
+ return this->GE->Parse(argv0)->Evaluate(this->LG, this->Config);
+}
+
+//----------------------------------------------------------------------------
+std::string escapeForShellOldStyle(const std::string& str)
+{
+ std::string result;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ // if there are spaces
+ std::string temp = str;
+ if (temp.find(" ") != std::string::npos &&
+ temp.find("\"")==std::string::npos)
+ {
+ result = "\"";
+ result += str;
+ result += "\"";
+ return result;
+ }
+ return str;
+#else
+ for(const char* ch = str.c_str(); *ch != '\0'; ++ch)
+ {
+ if(*ch == ' ')
+ {
+ result += '\\';
+ }
+ result += *ch;
+ }
+ return result;
+#endif
}
//----------------------------------------------------------------------------
@@ -58,16 +90,72 @@ cmCustomCommandGenerator
cmCustomCommandLine const& commandLine = this->CC.GetCommandLines()[c];
for(unsigned int j=1;j < commandLine.size(); ++j)
{
- std::string arg = this->GE->Parse(commandLine[j])->Evaluate(this->Makefile,
- this->Config);
+ std::string arg =
+ this->GE->Parse(commandLine[j])->Evaluate(this->LG,
+ this->Config);
cmd += " ";
if(this->OldStyle)
{
- cmd += this->LG->EscapeForShellOldStyle(arg.c_str());
+ cmd += escapeForShellOldStyle(arg);
}
else
{
- cmd += this->LG->EscapeForShell(arg.c_str(), this->MakeVars);
+ cmOutputConverter converter(this->LG->GetStateSnapshot());
+ cmd += converter.EscapeForShell(arg, this->MakeVars);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+const char* cmCustomCommandGenerator::GetComment() const
+{
+ return this->CC.GetComment();
+}
+
+//----------------------------------------------------------------------------
+std::string cmCustomCommandGenerator::GetWorkingDirectory() const
+{
+ return this->CC.GetWorkingDirectory();
+}
+
+//----------------------------------------------------------------------------
+std::vector<std::string> const& cmCustomCommandGenerator::GetOutputs() const
+{
+ return this->CC.GetOutputs();
+}
+
+//----------------------------------------------------------------------------
+std::vector<std::string> const& cmCustomCommandGenerator::GetByproducts() const
+{
+ return this->CC.GetByproducts();
+}
+
+//----------------------------------------------------------------------------
+std::vector<std::string> const& cmCustomCommandGenerator::GetDepends() const
+{
+ if (!this->DependsDone)
+ {
+ this->DependsDone = true;
+ std::vector<std::string> depends = this->CC.GetDepends();
+ for(std::vector<std::string>::const_iterator
+ i = depends.begin();
+ i != depends.end(); ++i)
+ {
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge
+ = this->GE->Parse(*i);
+ std::vector<std::string> result;
+ cmSystemTools::ExpandListArgument(
+ cge->Evaluate(this->LG, this->Config), result);
+ for (std::vector<std::string>::iterator it = result.begin();
+ it != result.end(); ++it)
+ {
+ if (cmSystemTools::FileIsFullPath(it->c_str()))
+ {
+ *it = cmSystemTools::CollapseFullPath(*it);
+ }
+ }
+ this->Depends.insert(this->Depends.end(), result.begin(), result.end());
}
}
+ return this->Depends;
}
diff --git a/Source/cmCustomCommandGenerator.h b/Source/cmCustomCommandGenerator.h
index 4e89f2731..a637fed7c 100644
--- a/Source/cmCustomCommandGenerator.h
+++ b/Source/cmCustomCommandGenerator.h
@@ -15,26 +15,33 @@
#include "cmStandardIncludes.h"
class cmCustomCommand;
-class cmMakefile;
class cmLocalGenerator;
class cmGeneratorExpression;
class cmCustomCommandGenerator
{
cmCustomCommand const& CC;
- const char* Config;
- cmMakefile* Makefile;
+ std::string Config;
cmLocalGenerator* LG;
bool OldStyle;
bool MakeVars;
cmGeneratorExpression* GE;
+ mutable bool DependsDone;
+ mutable std::vector<std::string> Depends;
public:
- cmCustomCommandGenerator(cmCustomCommand const& cc, const char* config,
- cmMakefile* mf);
+ cmCustomCommandGenerator(cmCustomCommand const& cc,
+ const std::string& config,
+ cmLocalGenerator* lg);
~cmCustomCommandGenerator();
+ cmCustomCommand const& GetCC() const { return this->CC; }
unsigned int GetNumberOfCommands() const;
std::string GetCommand(unsigned int c) const;
void AppendArguments(unsigned int c, std::string& cmd) const;
+ const char* GetComment() const;
+ std::string GetWorkingDirectory() const;
+ std::vector<std::string> const& GetOutputs() const;
+ std::vector<std::string> const& GetByproducts() const;
+ std::vector<std::string> const& GetDepends() const;
};
#endif
diff --git a/Source/cmDefinePropertyCommand.cxx b/Source/cmDefinePropertyCommand.cxx
index 5816829e0..0efc7fcf5 100644
--- a/Source/cmDefinePropertyCommand.cxx
+++ b/Source/cmDefinePropertyCommand.cxx
@@ -11,8 +11,8 @@
============================================================================*/
#include "cmDefinePropertyCommand.h"
#include "cmake.h"
+#include "cmState.h"
-// cmDefinePropertiesCommand
bool cmDefinePropertyCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
@@ -54,12 +54,12 @@ bool cmDefinePropertyCommand
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "given invalid scope " << args[0] << ". "
<< "Valid scopes are "
<< "GLOBAL, DIRECTORY, TARGET, SOURCE, "
<< "TEST, VARIABLE, CACHED_VARIABLE.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
@@ -101,9 +101,9 @@ bool cmDefinePropertyCommand
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "given invalid argument \"" << args[i] << "\".";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
@@ -128,8 +128,8 @@ bool cmDefinePropertyCommand
}
// Actually define the property.
- this->Makefile->GetCMakeInstance()->DefineProperty
- (this->PropertyName.c_str(), scope,
+ this->Makefile->GetState()->DefineProperty
+ (this->PropertyName, scope,
this->BriefDocs.c_str(), this->FullDocs.c_str(), inherited);
return true;
diff --git a/Source/cmDefinePropertyCommand.h b/Source/cmDefinePropertyCommand.h
index b5175d50b..bc5c8a4f8 100644
--- a/Source/cmDefinePropertyCommand.h
+++ b/Source/cmDefinePropertyCommand.h
@@ -32,54 +32,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "define_property";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Define and document custom properties.";
- }
-
- /**
- * Longer documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " define_property(<GLOBAL | DIRECTORY | TARGET | SOURCE |\n"
- " TEST | VARIABLE | CACHED_VARIABLE>\n"
- " PROPERTY <name> [INHERITED]\n"
- " BRIEF_DOCS <brief-doc> [docs...]\n"
- " FULL_DOCS <full-doc> [docs...])\n"
- "Define one property in a scope for use with the "
- "set_property and get_property commands. "
- "This is primarily useful to associate documentation with property "
- "names that may be retrieved with the get_property command. "
- "The first argument determines the kind of scope in which the "
- "property should be used. It must be one of the following:\n"
- " GLOBAL = associated with the global namespace\n"
- " DIRECTORY = associated with one directory\n"
- " TARGET = associated with one target\n"
- " SOURCE = associated with one source file\n"
- " TEST = associated with a test named with add_test\n"
- " VARIABLE = documents a CMake language variable\n"
- " CACHED_VARIABLE = documents a CMake cache variable\n"
- "Note that unlike set_property and get_property no actual scope "
- "needs to be given; only the kind of scope is important.\n"
- "The required PROPERTY option is immediately followed by the name "
- "of the property being defined.\n"
- "If the INHERITED option then the get_property command will chain "
- "up to the next higher scope when the requested property is not "
- "set in the scope given to the command. "
- "DIRECTORY scope chains to GLOBAL. "
- "TARGET, SOURCE, and TEST chain to DIRECTORY.\n"
- "The BRIEF_DOCS and FULL_DOCS options are followed by strings to be "
- "associated with the property as its brief and full documentation. "
- "Corresponding options to the get_property command will retrieve the "
- "documentation.";
- }
+ virtual std::string GetName() const { return "define_property";}
cmTypeMacro(cmDefinePropertyCommand, cmCommand);
private:
diff --git a/Source/cmDefinitions.cxx b/Source/cmDefinitions.cxx
index 9d2870058..b06fb5c0b 100644
--- a/Source/cmDefinitions.cxx
+++ b/Source/cmDefinitions.cxx
@@ -11,168 +11,138 @@
============================================================================*/
#include "cmDefinitions.h"
-//----------------------------------------------------------------------------
-cmDefinitions::Def cmDefinitions::NoDef;
+#include <assert.h>
//----------------------------------------------------------------------------
-cmDefinitions::cmDefinitions(cmDefinitions* parent): Up(parent)
-{
-}
-
-//----------------------------------------------------------------------------
-void cmDefinitions::Reset(cmDefinitions* parent)
-{
- this->Up = parent;
- this->Map.clear();
-}
+cmDefinitions::Def cmDefinitions::NoDef;
//----------------------------------------------------------------------------
-cmDefinitions::Def const&
-cmDefinitions::GetInternal(const char* key)
+cmDefinitions::Def const& cmDefinitions::GetInternal(
+ const std::string& key, StackIter begin, StackIter end, bool raise)
{
- MapType::const_iterator i = this->Map.find(key);
- if(i != this->Map.end())
+ assert(begin != end);
+ MapType::iterator i = begin->Map.find(key);
+ if (i != begin->Map.end())
{
+ i->second.Used = true;
return i->second;
}
- else if(cmDefinitions* up = this->Up)
+ StackIter it = begin;
+ ++it;
+ if (it == end)
{
- // Query the parent scope and store the result locally.
- Def def = up->GetInternal(key);
- return this->Map.insert(MapType::value_type(key, def)).first->second;
+ return cmDefinitions::NoDef;
}
- return this->NoDef;
-}
-
-//----------------------------------------------------------------------------
-cmDefinitions::Def const&
-cmDefinitions::SetInternal(const char* key, Def const& def)
-{
- if(this->Up || def.Exists)
+ Def const& def = cmDefinitions::GetInternal(key, it, end, raise);
+ if (!raise)
{
- // In lower scopes we store keys, defined or not.
- MapType::iterator i = this->Map.find(key);
- if(i == this->Map.end())
- {
- i = this->Map.insert(MapType::value_type(key, def)).first;
- }
- else
- {
- i->second = def;
- }
- return i->second;
- }
- else
- {
- // In the top-most scope we need not store undefined keys.
- this->Map.erase(key);
- return this->NoDef;
+ return def;
}
+ return begin->Map.insert(MapType::value_type(key, def)).first->second;
}
//----------------------------------------------------------------------------
-const char* cmDefinitions::Get(const char* key)
+const char* cmDefinitions::Get(const std::string& key,
+ StackIter begin, StackIter end)
{
- Def const& def = this->GetInternal(key);
+ Def const& def = cmDefinitions::GetInternal(key, begin, end, false);
return def.Exists? def.c_str() : 0;
}
-//----------------------------------------------------------------------------
-const char* cmDefinitions::Set(const char* key, const char* value)
+void cmDefinitions::Raise(const std::string& key,
+ StackIter begin, StackIter end)
{
- Def const& def = this->SetInternal(key, Def(value));
- return def.Exists? def.c_str() : 0;
+ cmDefinitions::GetInternal(key, begin, end, true);
}
-//----------------------------------------------------------------------------
-std::set<cmStdString> cmDefinitions::LocalKeys() const
+bool cmDefinitions::HasKey(const std::string& key,
+ StackIter begin, StackIter end)
{
- std::set<cmStdString> keys;
- // Consider local definitions.
- for(MapType::const_iterator mi = this->Map.begin();
- mi != this->Map.end(); ++mi)
+ for (StackIter it = begin; it != end; ++it)
{
- if (mi->second.Exists)
+ MapType::const_iterator i = it->Map.find(key);
+ if (i != it->Map.end())
{
- keys.insert(mi->first);
+ return true;
}
}
- return keys;
+ return false;
}
//----------------------------------------------------------------------------
-cmDefinitions cmDefinitions::Closure() const
+void cmDefinitions::Set(const std::string& key, const char* value)
{
- return cmDefinitions(ClosureTag(), this);
+ Def def(value);
+ this->Map[key] = def;
}
//----------------------------------------------------------------------------
-cmDefinitions::cmDefinitions(ClosureTag const&, cmDefinitions const* root):
- Up(0)
+std::vector<std::string> cmDefinitions::UnusedKeys() const
{
- std::set<cmStdString> undefined;
- this->ClosureImpl(undefined, root);
+ std::vector<std::string> keys;
+ keys.reserve(this->Map.size());
+ // Consider local definitions.
+ for(MapType::const_iterator mi = this->Map.begin();
+ mi != this->Map.end(); ++mi)
+ {
+ if (!mi->second.Used)
+ {
+ keys.push_back(mi->first);
+ }
+ }
+ return keys;
}
//----------------------------------------------------------------------------
-void cmDefinitions::ClosureImpl(std::set<cmStdString>& undefined,
- cmDefinitions const* defs)
+cmDefinitions cmDefinitions::MakeClosure(StackIter begin,
+ StackIter end)
{
- // Consider local definitions.
- for(MapType::const_iterator mi = defs->Map.begin();
- mi != defs->Map.end(); ++mi)
+ cmDefinitions closure;
+ std::set<std::string> undefined;
+ for (StackIter it = begin; it != end; ++it)
{
- // Use this key if it is not already set or unset.
- if(this->Map.find(mi->first) == this->Map.end() &&
- undefined.find(mi->first) == undefined.end())
+ // Consider local definitions.
+ for(MapType::const_iterator mi = it->Map.begin();
+ mi != it->Map.end(); ++mi)
{
- if(mi->second.Exists)
- {
- this->Map.insert(*mi);
- }
- else
+ // Use this key if it is not already set or unset.
+ if(closure.Map.find(mi->first) == closure.Map.end() &&
+ undefined.find(mi->first) == undefined.end())
{
- undefined.insert(mi->first);
+ if(mi->second.Exists)
+ {
+ closure.Map.insert(*mi);
+ }
+ else
+ {
+ undefined.insert(mi->first);
+ }
}
}
}
-
- // Traverse parents.
- if(cmDefinitions const* up = defs->Up)
- {
- this->ClosureImpl(undefined, up);
- }
+ return closure;
}
//----------------------------------------------------------------------------
-std::set<cmStdString> cmDefinitions::ClosureKeys() const
+std::vector<std::string>
+cmDefinitions::ClosureKeys(StackIter begin, StackIter end)
{
- std::set<cmStdString> defined;
- std::set<cmStdString> undefined;
- this->ClosureKeys(defined, undefined);
- return defined;
-}
+ std::set<std::string> bound;
+ std::vector<std::string> defined;
-//----------------------------------------------------------------------------
-void cmDefinitions::ClosureKeys(std::set<cmStdString>& defined,
- std::set<cmStdString>& undefined) const
-{
- // Consider local definitions.
- for(MapType::const_iterator mi = this->Map.begin();
- mi != this->Map.end(); ++mi)
+ for (StackIter it = begin; it != end; ++it)
{
- // Use this key if it is not already set or unset.
- if(defined.find(mi->first) == defined.end() &&
- undefined.find(mi->first) == undefined.end())
+ defined.reserve(defined.size() + it->Map.size());
+ for(MapType::const_iterator mi = it->Map.begin();
+ mi != it->Map.end(); ++mi)
{
- std::set<cmStdString>& m = mi->second.Exists? defined : undefined;
- m.insert(mi->first);
+ // Use this key if it is not already set or unset.
+ if(bound.insert(mi->first).second && mi->second.Exists)
+ {
+ defined.push_back(mi->first);
+ }
}
}
- // Traverse parents.
- if(cmDefinitions const* up = this->Up)
- {
- up->ClosureKeys(defined, undefined);
- }
+ return defined;
}
diff --git a/Source/cmDefinitions.h b/Source/cmDefinitions.h
index 4834d8443..411867c52 100644
--- a/Source/cmDefinitions.h
+++ b/Source/cmDefinitions.h
@@ -14,6 +14,18 @@
#include "cmStandardIncludes.h"
+#include "cmLinkedTree.h"
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+#ifdef CMake_HAVE_CXX11_UNORDERED_MAP
+#include <unordered_map>
+#else
+#include "cmsys/hash_map.hxx"
+#endif
+#endif
+
+#include <list>
+
/** \class cmDefinitions
* \brief Store a scope of variable definitions for CMake language.
*
@@ -23,64 +35,60 @@
*/
class cmDefinitions
{
+ typedef cmLinkedTree<cmDefinitions>::iterator StackIter;
public:
- /** Construct with the given parent scope. */
- cmDefinitions(cmDefinitions* parent = 0);
-
- /** Reset object as if newly constructed. */
- void Reset(cmDefinitions* parent = 0);
+ static const char* Get(const std::string& key,
+ StackIter begin, StackIter end);
- /** Returns the parent scope, if any. */
- cmDefinitions* GetParent() const { return this->Up; }
+ static void Raise(const std::string& key,
+ StackIter begin, StackIter end);
- /** Get the value associated with a key; null if none.
- Store the result locally if it came from a parent. */
- const char* Get(const char* key);
+ static bool HasKey(const std::string& key,
+ StackIter begin, StackIter end);
/** Set (or unset if null) a value associated with a key. */
- const char* Set(const char* key, const char* value);
+ void Set(const std::string& key, const char* value);
- /** Get the set of all local keys. */
- std::set<cmStdString> LocalKeys() const;
+ std::vector<std::string> UnusedKeys() const;
- /** Compute the closure of all defined keys with values.
- This flattens the scope. The result has no parent. */
- cmDefinitions Closure() const;
+ static std::vector<std::string> ClosureKeys(StackIter begin,
+ StackIter end);
- /** Compute the set of all defined keys. */
- std::set<cmStdString> ClosureKeys() const;
+ static cmDefinitions MakeClosure(StackIter begin, StackIter end);
private:
// String with existence boolean.
- struct Def: public cmStdString
+ struct Def: public std::string
{
- Def(): cmStdString(), Exists(false) {}
- Def(const char* v): cmStdString(v?v:""), Exists(v?true:false) {}
- Def(Def const& d): cmStdString(d), Exists(d.Exists) {}
+ private:
+ typedef std::string std_string;
+ public:
+ Def(): std_string(), Exists(false), Used(false) {}
+ Def(const char* v)
+ : std_string(v ? v : ""),
+ Exists(v ? true : false),
+ Used(false)
+ {}
+ Def(const std_string& v): std_string(v), Exists(true), Used(false) {}
+ Def(Def const& d): std_string(d), Exists(d.Exists), Used(d.Used) {}
bool Exists;
+ bool Used;
};
static Def NoDef;
- // Parent scope, if any.
- cmDefinitions* Up;
-
- // Local definitions, set or unset.
- typedef std::map<cmStdString, Def> MapType;
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+#ifdef CMake_HAVE_CXX11_UNORDERED_MAP
+ typedef std::unordered_map<std::string, Def> MapType;
+#else
+ typedef cmsys::hash_map<std::string, Def> MapType;
+#endif
+#else
+ typedef std::map<std::string, Def> MapType;
+#endif
MapType Map;
- // Internal query and update methods.
- Def const& GetInternal(const char* key);
- Def const& SetInternal(const char* key, Def const& def);
-
- // Implementation of Closure() method.
- struct ClosureTag {};
- cmDefinitions(ClosureTag const&, cmDefinitions const* root);
- void ClosureImpl(std::set<cmStdString>& undefined,
- cmDefinitions const* defs);
-
- // Implementation of ClosureKeys() method.
- void ClosureKeys(std::set<cmStdString>& defined,
- std::set<cmStdString>& undefined) const;
+ static Def const& GetInternal(const std::string& key,
+ StackIter begin, StackIter end, bool raise);
};
#endif
diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx
index 74a0ccb21..d4190112d 100644
--- a/Source/cmDepends.cxx
+++ b/Source/cmDepends.cxx
@@ -17,6 +17,7 @@
#include "cmSystemTools.h"
#include "cmFileTimeComparison.h"
#include <string.h>
+#include <cmsys/FStream.hxx>
//----------------------------------------------------------------------------
cmDepends::cmDepends(cmLocalGenerator* lg, const char* targetDir):
@@ -46,7 +47,7 @@ bool cmDepends::Write(std::ostream &makeDepends,
std::string srcLang = "CMAKE_DEPENDS_CHECK_";
srcLang += this->Language;
cmMakefile* mf = this->LocalGenerator->GetMakefile();
- const char* srcStr = mf->GetSafeDefinition(srcLang.c_str());
+ const char* srcStr = mf->GetSafeDefinition(srcLang);
std::vector<std::string> pairs;
cmSystemTools::ExpandListArgument(srcStr, pairs);
@@ -57,12 +58,7 @@ bool cmDepends::Write(std::ostream &makeDepends,
// Get the source and object file.
std::string const& src = *si++;
if(si == pairs.end()) { break; }
- std::string obj = *si++;
-
- // Make sure the object file is relative to the top of the build tree.
- obj = this->LocalGenerator->Convert(obj.c_str(),
- cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE);
+ std::string const& obj = *si++;
dependencies[obj].insert(src);
}
for(std::map<std::string, std::set<std::string> >::const_iterator
@@ -98,12 +94,12 @@ bool cmDepends::Check(const char *makeFile, const char *internalFile,
// Get the CWD but do not call CollapseFullPath because
// we only need it to cd back, and the form does not matter
oldcwd = cmSystemTools::GetCurrentWorkingDirectory(false);
- cmSystemTools::ChangeDirectory(this->CompileDirectory.c_str());
+ cmSystemTools::ChangeDirectory(this->CompileDirectory);
}
// Check whether dependencies must be regenerated.
bool okay = true;
- std::ifstream fin(internalFile);
+ cmsys::ifstream fin(internalFile);
if(!(fin && this->CheckDependencies(fin, internalFile, validDeps)))
{
// Clear all dependencies so they will be regenerated.
@@ -115,7 +111,7 @@ bool cmDepends::Check(const char *makeFile, const char *internalFile,
// Restore working directory.
if(oldcwd != ".")
{
- cmSystemTools::ChangeDirectory(oldcwd.c_str());
+ cmSystemTools::ChangeDirectory(oldcwd);
}
return okay;
@@ -127,7 +123,7 @@ void cmDepends::Clear(const char *file)
// Print verbose output.
if(this->Verbose)
{
- cmOStringStream msg;
+ std::ostringstream msg;
msg << "Clearing dependencies in \"" << file << "\"." << std::endl;
cmSystemTools::Stdout(msg.str().c_str());
}
@@ -217,7 +213,7 @@ bool cmDepends::CheckDependencies(std::istream& internalDepends,
// Print verbose output.
if(this->Verbose)
{
- cmOStringStream msg;
+ std::ostringstream msg;
msg << "Dependee \"" << dependee
<< "\" does not exist for depender \""
<< depender << "\"." << std::endl;
@@ -239,7 +235,7 @@ bool cmDepends::CheckDependencies(std::istream& internalDepends,
// Print verbose output.
if(this->Verbose)
{
- cmOStringStream msg;
+ std::ostringstream msg;
msg << "Dependee \"" << dependee
<< "\" is newer than depender \""
<< depender << "\"." << std::endl;
@@ -261,7 +257,7 @@ bool cmDepends::CheckDependencies(std::istream& internalDepends,
// Print verbose output.
if(this->Verbose)
{
- cmOStringStream msg;
+ std::ostringstream msg;
msg << "Dependee \"" << dependee
<< "\" is newer than depends file \""
<< internalDependsFileName << "\"." << std::endl;
@@ -296,7 +292,7 @@ bool cmDepends::CheckDependencies(std::istream& internalDepends,
}
//----------------------------------------------------------------------------
-void cmDepends::SetIncludePathFromLanguage(const char* lang)
+void cmDepends::SetIncludePathFromLanguage(const std::string& lang)
{
// Look for the new per "TARGET_" variant first:
const char * includePath = 0;
@@ -304,7 +300,7 @@ void cmDepends::SetIncludePathFromLanguage(const char* lang)
includePathVar += lang;
includePathVar += "_TARGET_INCLUDE_PATH";
cmMakefile* mf = this->LocalGenerator->GetMakefile();
- includePath = mf->GetDefinition(includePathVar.c_str());
+ includePath = mf->GetDefinition(includePathVar);
if(includePath)
{
cmSystemTools::ExpandListArgument(includePath, this->IncludePath);
@@ -315,7 +311,7 @@ void cmDepends::SetIncludePathFromLanguage(const char* lang)
includePathVar = "CMAKE_";
includePathVar += lang;
includePathVar += "_INCLUDE_PATH";
- includePath = mf->GetDefinition(includePathVar.c_str());
+ includePath = mf->GetDefinition(includePathVar);
if(includePath)
{
cmSystemTools::ExpandListArgument(includePath, this->IncludePath);
diff --git a/Source/cmDepends.h b/Source/cmDepends.h
index d787eddc6..4f6517ed4 100644
--- a/Source/cmDepends.h
+++ b/Source/cmDepends.h
@@ -32,7 +32,7 @@ public:
cmDepends(cmLocalGenerator* lg=0, const char* targetDir="");
/** at what level will the compile be done from */
- void SetCompileDirectory(const char *dir) {this->CompileDirectory = dir;};
+ void SetCompileDirectory(const char *dir) {this->CompileDirectory = dir;}
/** Set the local generator for the directory in which we are
scanning dependencies. This is not a full local generator; it
@@ -41,7 +41,7 @@ public:
void SetLocalGenerator(cmLocalGenerator* lg) { this->LocalGenerator = lg; }
/** Set the specific language to be scanned. */
- void SetLanguage(const char* lang) { this->Language = lang; }
+ void SetLanguage(const std::string& lang) { this->Language = lang; }
/** Set the target build directory. */
void SetTargetDirectory(const char* dir) { this->TargetDirectory = dir; }
@@ -114,7 +114,7 @@ protected:
// The include file search path.
std::vector<std::string> IncludePath;
- void SetIncludePathFromLanguage(const char* lang);
+ void SetIncludePathFromLanguage(const std::string& lang);
private:
cmDepends(cmDepends const&); // Purposely not implemented.
diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx
index a252a1ab7..6cdd4c13d 100644
--- a/Source/cmDependsC.cxx
+++ b/Source/cmDependsC.cxx
@@ -15,6 +15,8 @@
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
+#include "cmAlgorithms.h"
+#include <cmsys/FStream.hxx>
#include <ctype.h> // isspace
@@ -36,7 +38,7 @@ cmDependsC::cmDependsC()
//----------------------------------------------------------------------------
cmDependsC::cmDependsC(cmLocalGenerator* lg,
const char* targetDir,
- const char* lang,
+ const std::string& lang,
const std::map<std::string, DependencyVector>* validDeps)
: cmDepends(lg, targetDir)
, ValidDeps(validDeps)
@@ -53,14 +55,14 @@ cmDependsC::cmDependsC(cmLocalGenerator* lg,
std::string scanRegexVar = "CMAKE_";
scanRegexVar += lang;
scanRegexVar += "_INCLUDE_REGEX_SCAN";
- if(const char* sr = mf->GetDefinition(scanRegexVar.c_str()))
+ if(const char* sr = mf->GetDefinition(scanRegexVar))
{
scanRegex = sr;
}
std::string complainRegexVar = "CMAKE_";
complainRegexVar += lang;
complainRegexVar += "_INCLUDE_REGEX_COMPLAIN";
- if(const char* cr = mf->GetDefinition(complainRegexVar.c_str()))
+ if(const char* cr = mf->GetDefinition(complainRegexVar))
{
complainRegex = cr;
}
@@ -89,12 +91,7 @@ cmDependsC::cmDependsC(cmLocalGenerator* lg,
cmDependsC::~cmDependsC()
{
this->WriteCacheFile();
-
- for (std::map<cmStdString, cmIncludeLines*>::iterator it=
- this->FileCache.begin(); it!=this->FileCache.end(); ++it)
- {
- delete it->second;
- }
+ cmDeleteAll(this->FileCache);
}
//----------------------------------------------------------------------------
@@ -115,7 +112,7 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
return false;
}
- std::set<cmStdString> dependencies;
+ std::set<std::string> dependencies;
bool haveDeps = false;
if (this->ValidDeps != 0)
@@ -124,11 +121,7 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
this->ValidDeps->find(obj);
if (tmpIt!= this->ValidDeps->end())
{
- for(DependencyVector::const_iterator i=tmpIt->second.begin();
- i != tmpIt->second.end(); ++i)
- {
- dependencies.insert(*i);
- }
+ dependencies.insert(tmpIt->second.begin(), tmpIt->second.end());
haveDeps = true;
}
}
@@ -148,7 +141,7 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
this->Encountered.insert(*srcIt);
}
- std::set<cmStdString> scanned;
+ std::set<std::string> scanned;
// Use reserve to allocate enough memory for tempPathStr
// so that during the loops no memory is allocated or freed
@@ -181,7 +174,7 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
}
else
{
- std::map<cmStdString, cmStdString>::iterator
+ std::map<std::string, std::string>::iterator
headerLocationIt=this->HeaderLocationCache.find(current.FileName);
if (headerLocationIt!=this->HeaderLocationCache.end())
{
@@ -223,7 +216,7 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
scanned.insert(fullName);
// Check whether this file is already in the cache
- std::map<cmStdString, cmIncludeLines*>::iterator fileIt=
+ std::map<std::string, cmIncludeLines*>::iterator fileIt=
this->FileCache.find(fullName);
if (fileIt!=this->FileCache.end())
{
@@ -246,16 +239,25 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
// Try to scan the file. Just leave it out if we cannot find
// it.
- std::ifstream fin(fullName.c_str());
+ cmsys::ifstream fin(fullName.c_str());
if(fin)
{
- // Add this file as a dependency.
- dependencies.insert(fullName);
+ cmsys::FStream::BOM bom = cmsys::FStream::ReadBOM(fin);
+ if(bom == cmsys::FStream::BOM_None ||
+ bom == cmsys::FStream::BOM_UTF8)
+ {
+ // Add this file as a dependency.
+ dependencies.insert(fullName);
- // Scan this file for new dependencies. Pass the directory
- // containing the file to handle double-quote includes.
- std::string dir = cmSystemTools::GetFilenamePath(fullName);
- this->Scan(fin, dir.c_str(), fullName);
+ // Scan this file for new dependencies. Pass the directory
+ // containing the file to handle double-quote includes.
+ std::string dir = cmSystemTools::GetFilenamePath(fullName);
+ this->Scan(fin, dir.c_str(), fullName);
+ }
+ else
+ {
+ // Skip file with encoding we do not implement.
+ }
}
}
}
@@ -268,16 +270,22 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
// written by the original local generator for this directory
// convert the dependencies to paths relative to the home output
// directory. We must do the same here.
- internalDepends << obj << std::endl;
- for(std::set<cmStdString>::const_iterator i=dependencies.begin();
+ std::string obj_i =
+ this->LocalGenerator->Convert(obj, cmLocalGenerator::HOME_OUTPUT);
+ std::string obj_m =
+ this->LocalGenerator->ConvertToOutputFormat(obj_i,
+ cmLocalGenerator::MAKERULE);
+ internalDepends << obj_i << std::endl;
+
+ for(std::set<std::string>::const_iterator i=dependencies.begin();
i != dependencies.end(); ++i)
{
- makeDepends << obj << ": " <<
- this->LocalGenerator->Convert(i->c_str(),
+ makeDepends << obj_m << ": " <<
+ this->LocalGenerator->Convert(*i,
cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE)
+ cmLocalGenerator::MAKERULE)
<< std::endl;
- internalDepends << " " << i->c_str() << std::endl;
+ internalDepends << " " << *i << std::endl;
}
makeDepends << std::endl;
@@ -287,11 +295,11 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
//----------------------------------------------------------------------------
void cmDependsC::ReadCacheFile()
{
- if(this->CacheFileName.size() == 0)
+ if(this->CacheFileName.empty())
{
return;
}
- std::ifstream fin(this->CacheFileName.c_str());
+ cmsys::ifstream fin(this->CacheFileName.c_str());
if(!fin)
{
return;
@@ -376,11 +384,11 @@ void cmDependsC::ReadCacheFile()
//----------------------------------------------------------------------------
void cmDependsC::WriteCacheFile() const
{
- if(this->CacheFileName.size() == 0)
+ if(this->CacheFileName.empty())
{
return;
}
- std::ofstream cacheOut(this->CacheFileName.c_str());
+ cmsys::ofstream cacheOut(this->CacheFileName.c_str());
if(!cacheOut)
{
return;
@@ -391,7 +399,7 @@ void cmDependsC::WriteCacheFile() const
cacheOut << this->IncludeRegexComplainString << "\n\n";
cacheOut << this->IncludeRegexTransformString << "\n\n";
- for (std::map<cmStdString, cmIncludeLines*>::const_iterator fileIt=
+ for (std::map<std::string, cmIncludeLines*>::const_iterator fileIt=
this->FileCache.begin();
fileIt!=this->FileCache.end(); ++fileIt)
{
@@ -420,7 +428,7 @@ void cmDependsC::WriteCacheFile() const
//----------------------------------------------------------------------------
void cmDependsC::Scan(std::istream& is, const char* directory,
- const cmStdString& fullName)
+ const std::string& fullName)
{
cmIncludeLines* newCacheEntry=new cmIncludeLines;
newCacheEntry->Used=true;
diff --git a/Source/cmDependsC.h b/Source/cmDependsC.h
index 16dfad7bc..07d3c21f3 100644
--- a/Source/cmDependsC.h
+++ b/Source/cmDependsC.h
@@ -25,7 +25,8 @@ public:
/** Checking instances need to know the build directory name and the
relative path from the build directory to the target file. */
cmDependsC();
- cmDependsC(cmLocalGenerator* lg, const char* targetDir, const char* lang,
+ cmDependsC(cmLocalGenerator* lg, const char* targetDir,
+ const std::string& lang,
const std::map<std::string, DependencyVector>* validDeps);
/** Virtual destructor to cleanup subclasses properly. */
@@ -40,7 +41,7 @@ protected:
// Method to scan a single file.
void Scan(std::istream& is, const char* directory,
- const cmStdString& fullName);
+ const std::string& fullName);
// Regular expression to identify C preprocessor include directives.
cmsys::RegularExpression IncludeRegexLine;
@@ -56,7 +57,7 @@ protected:
// Regex to transform #include lines.
std::string IncludeRegexTransformString;
cmsys::RegularExpression IncludeRegexTransform;
- typedef std::map<cmStdString, cmStdString> TransformRulesType;
+ typedef std::map<std::string, std::string> TransformRulesType;
TransformRulesType TransformRules;
void SetupTransforms();
void ParseTransform(std::string const& xform);
@@ -66,8 +67,8 @@ public:
// Data structures for dependency graph walk.
struct UnscannedEntry
{
- cmStdString FileName;
- cmStdString QuotedLocation;
+ std::string FileName;
+ std::string QuotedLocation;
};
struct cmIncludeLines
@@ -78,13 +79,13 @@ public:
};
protected:
const std::map<std::string, DependencyVector>* ValidDeps;
- std::set<cmStdString> Encountered;
+ std::set<std::string> Encountered;
std::queue<UnscannedEntry> Unscanned;
- std::map<cmStdString, cmIncludeLines *> FileCache;
- std::map<cmStdString, cmStdString> HeaderLocationCache;
+ std::map<std::string, cmIncludeLines *> FileCache;
+ std::map<std::string, std::string> HeaderLocationCache;
- cmStdString CacheFileName;
+ std::string CacheFileName;
void WriteCacheFile() const;
void ReadCacheFile();
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index e41e5ea86..80f560f31 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -16,107 +16,38 @@
#include "cmMakefile.h"
#include "cmGeneratedFileStream.h"
-#include "cmDependsFortranParser.h" /* Interface to parser object. */
-
+#include "cmFortranParser.h" /* Interface to parser object. */
+#include <cmsys/FStream.hxx>
#include <assert.h>
-#include <stack>
// TODO: Test compiler for the case of the mod file. Some always
// use lower case and some always use upper case. I do not know if any
// use the case from the source code.
//----------------------------------------------------------------------------
-// Information about a single source file.
-class cmDependsFortranSourceInfo
-{
-public:
- // The name of the source file.
- std::string Source;
-
- // Set of provided and required modules.
- std::set<cmStdString> Provides;
- std::set<cmStdString> Requires;
-
- // Set of files included in the translation unit.
- std::set<cmStdString> Includes;
-};
-
-//----------------------------------------------------------------------------
-// Parser methods not included in generated interface.
-
-// Get the current buffer processed by the lexer.
-YY_BUFFER_STATE cmDependsFortranLexer_GetCurrentBuffer(yyscan_t yyscanner);
-
-// The parser entry point.
-int cmDependsFortran_yyparse(yyscan_t);
-
-//----------------------------------------------------------------------------
-// Define parser object internal structure.
-struct cmDependsFortranFile
-{
- cmDependsFortranFile(FILE* file, YY_BUFFER_STATE buffer,
- const std::string& dir):
- File(file), Buffer(buffer), Directory(dir) {}
- FILE* File;
- YY_BUFFER_STATE Buffer;
- std::string Directory;
-};
-
-struct cmDependsFortranParser_s
-{
- cmDependsFortranParser_s(cmDependsFortran* self,
- std::set<std::string>& ppDefines,
- cmDependsFortranSourceInfo& info);
- ~cmDependsFortranParser_s();
-
- // Pointer back to the main class.
- cmDependsFortran* Self;
-
- // Lexical scanner instance.
- yyscan_t Scanner;
-
- // Stack of open files in the translation unit.
- std::stack<cmDependsFortranFile> FileStack;
-
- // Buffer for string literals.
- std::string TokenString;
-
- // Flag for whether lexer is reading from inside an interface.
- bool InInterface;
-
- int OldStartcond;
- std::set<std::string> PPDefinitions;
- size_t InPPFalseBranch;
- std::stack<bool> SkipToEnd;
-
- // Information about the parsed source.
- cmDependsFortranSourceInfo& Info;
-};
-
-//----------------------------------------------------------------------------
class cmDependsFortranInternals
{
public:
// The set of modules provided by this target.
- std::set<cmStdString> TargetProvides;
+ std::set<std::string> TargetProvides;
// Map modules required by this target to locations.
- typedef std::map<cmStdString, cmStdString> TargetRequiresMap;
+ typedef std::map<std::string, std::string> TargetRequiresMap;
TargetRequiresMap TargetRequires;
// Information about each object file.
- typedef std::map<cmStdString, cmDependsFortranSourceInfo> ObjectInfoMap;
+ typedef std::map<std::string, cmFortranSourceInfo> ObjectInfoMap;
ObjectInfoMap ObjectInfo;
- cmDependsFortranSourceInfo& CreateObjectInfo(const char* obj,
+ cmFortranSourceInfo& CreateObjectInfo(const char* obj,
const char* src)
{
- std::map<cmStdString, cmDependsFortranSourceInfo>::iterator i =
+ std::map<std::string, cmFortranSourceInfo>::iterator i =
this->ObjectInfo.find(obj);
if(i == this->ObjectInfo.end())
{
- std::map<cmStdString, cmDependsFortranSourceInfo>::value_type
- entry(obj, cmDependsFortranSourceInfo());
+ std::map<std::string, cmFortranSourceInfo>::value_type
+ entry(obj, cmFortranSourceInfo());
i = this->ObjectInfo.insert(entry).first;
i->second.Source = src;
}
@@ -126,7 +57,7 @@ public:
//----------------------------------------------------------------------------
cmDependsFortran::cmDependsFortran():
- PPDefinitions(0), Internal(0)
+ Internal(0)
{
}
@@ -143,7 +74,7 @@ cmDependsFortran
std::vector<std::string> definitions;
cmMakefile* mf = this->LocalGenerator->GetMakefile();
if(const char* c_defines =
- mf->GetDefinition("CMAKE_TARGET_DEFINITIONS"))
+ mf->GetDefinition("CMAKE_TARGET_DEFINITIONS_Fortran"))
{
cmSystemTools::ExpandListArgument(c_defines, definitions);
}
@@ -159,7 +90,7 @@ cmDependsFortran
{
def = it->substr(0, assignment);
}
- this->PPDefinitions.push_back(def);
+ this->PPDefinitions.insert(def);
}
}
@@ -192,22 +123,18 @@ bool cmDependsFortran::WriteDependencies(
{
const std::string& src = *it;
// Get the information object for this source.
- cmDependsFortranSourceInfo& info =
+ cmFortranSourceInfo& info =
this->Internal->CreateObjectInfo(obj.c_str(), src.c_str());
- // Make a copy of the macros defined via ADD_DEFINITIONS
- std::set<std::string> ppDefines(this->PPDefinitions.begin(),
- this->PPDefinitions.end());
-
- // Create the parser object. The constructor takes ppMacro and info per
- // reference, so we may look into the resulting objects later.
- cmDependsFortranParser parser(this, ppDefines, info);
+ // Create the parser object. The constructor takes info by reference,
+ // so we may look into the resulting objects later.
+ cmFortranParser parser(this->IncludePath, this->PPDefinitions, info);
// Push on the starting file.
- cmDependsFortranParser_FilePush(&parser, src.c_str());
+ cmFortranParser_FilePush(&parser, src.c_str());
// Parse the translation unit.
- if(cmDependsFortran_yyparse(parser.Scanner) != 0)
+ if(cmFortran_yyparse(parser.Scanner) != 0)
{
// Failed to parse the file. Report failure to write dependencies.
okay = false;
@@ -227,17 +154,13 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends,
const char* stamp_dir = this->TargetDirectory.c_str();
// Get the directory in which module files will be created.
- const char* mod_dir;
cmMakefile* mf = this->LocalGenerator->GetMakefile();
- if(const char* target_mod_dir =
- mf->GetDefinition("CMAKE_Fortran_TARGET_MODULE_DIR"))
- {
- mod_dir = target_mod_dir;
- }
- else
+ std::string mod_dir =
+ mf->GetSafeDefinition("CMAKE_Fortran_TARGET_MODULE_DIR");
+ if (mod_dir.empty())
{
mod_dir =
- this->LocalGenerator->GetMakefile()->GetCurrentOutputDirectory();
+ this->LocalGenerator->GetCurrentBinaryDirectory();
}
// Actually write dependencies to the streams.
@@ -260,8 +183,8 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends,
cmGeneratedFileStream fiStream(fiName.c_str());
fiStream << "# The fortran modules provided by this target.\n";
fiStream << "provides\n";
- std::set<cmStdString> const& provides = this->Internal->TargetProvides;
- for(std::set<cmStdString>::const_iterator i = provides.begin();
+ std::set<std::string> const& provides = this->Internal->TargetProvides;
+ for(std::set<std::string>::const_iterator i = provides.begin();
i != provides.end(); ++i)
{
fiStream << " " << *i << "\n";
@@ -275,7 +198,7 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends,
cmGeneratedFileStream fcStream(fcName.c_str());
fcStream << "# Remove fortran modules provided by this target.\n";
fcStream << "FILE(REMOVE";
- for(std::set<cmStdString>::const_iterator i = provides.begin();
+ for(std::set<std::string>::const_iterator i = provides.begin();
i != provides.end(); ++i)
{
std::string mod_upper = mod_dir;
@@ -292,15 +215,15 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends,
stamp += ".mod.stamp";
fcStream << "\n";
fcStream << " \"" <<
- this->LocalGenerator->Convert(mod_lower.c_str(),
+ this->LocalGenerator->Convert(mod_lower,
cmLocalGenerator::START_OUTPUT)
<< "\"\n";
fcStream << " \"" <<
- this->LocalGenerator->Convert(mod_upper.c_str(),
+ this->LocalGenerator->Convert(mod_upper,
cmLocalGenerator::START_OUTPUT)
<< "\"\n";
fcStream << " \"" <<
- this->LocalGenerator->Convert(stamp.c_str(),
+ this->LocalGenerator->Convert(stamp,
cmLocalGenerator::START_OUTPUT)
<< "\"\n";
}
@@ -318,18 +241,14 @@ void cmDependsFortran::LocateModules()
for(ObjectInfoMap::const_iterator infoI = objInfo.begin();
infoI != objInfo.end(); ++infoI)
{
- cmDependsFortranSourceInfo const& info = infoI->second;
- for(std::set<cmStdString>::const_iterator i = info.Provides.begin();
- i != info.Provides.end(); ++i)
- {
- // Include this module in the set provided by this target.
- this->Internal->TargetProvides.insert(*i);
- }
+ cmFortranSourceInfo const& info = infoI->second;
+ // Include this module in the set provided by this target.
+ this->Internal->TargetProvides.insert(info.Provides.begin(),
+ info.Provides.end());
- for(std::set<cmStdString>::const_iterator i = info.Requires.begin();
+ for(std::set<std::string>::const_iterator i = info.Requires.begin();
i != info.Requires.end(); ++i)
{
- // Include this module in the set required by this target.
this->Internal->TargetRequires[*i] = "";
}
}
@@ -356,7 +275,7 @@ void cmDependsFortran::LocateModules()
{
std::string targetDir = cmSystemTools::GetFilenamePath(*i);
std::string fname = targetDir + "/fortran.internal";
- std::ifstream fin(fname.c_str());
+ cmsys::ifstream fin(fname.c_str());
if(fin)
{
this->MatchRemoteModules(fin, targetDir.c_str());
@@ -368,8 +287,8 @@ void cmDependsFortran::LocateModules()
void cmDependsFortran::MatchLocalModules()
{
const char* stampDir = this->TargetDirectory.c_str();
- std::set<cmStdString> const& provides = this->Internal->TargetProvides;
- for(std::set<cmStdString>::const_iterator i = provides.begin();
+ std::set<std::string> const& provides = this->Internal->TargetProvides;
+ for(std::set<std::string>::const_iterator i = provides.begin();
i != provides.end(); ++i)
{
this->ConsiderModule(i->c_str(), stampDir);
@@ -432,8 +351,9 @@ void cmDependsFortran::ConsiderModule(const char* name,
bool
cmDependsFortran
::WriteDependenciesReal(const char *obj,
- cmDependsFortranSourceInfo const& info,
- const char* mod_dir, const char* stamp_dir,
+ cmFortranSourceInfo const& info,
+ std::string const& mod_dir,
+ const char* stamp_dir,
std::ostream& makeDepends,
std::ostream& internalDepends)
{
@@ -443,26 +363,31 @@ cmDependsFortran
const char* src = info.Source.c_str();
// Write the include dependencies to the output stream.
- internalDepends << obj << std::endl;
+ std::string obj_i =
+ this->LocalGenerator->Convert(obj, cmLocalGenerator::HOME_OUTPUT);
+ std::string obj_m =
+ this->LocalGenerator->ConvertToOutputFormat(obj_i,
+ cmLocalGenerator::MAKERULE);
+ internalDepends << obj_i << std::endl;
internalDepends << " " << src << std::endl;
- for(std::set<cmStdString>::const_iterator i = info.Includes.begin();
+ for(std::set<std::string>::const_iterator i = info.Includes.begin();
i != info.Includes.end(); ++i)
{
- makeDepends << obj << ": " <<
- this->LocalGenerator->Convert(i->c_str(),
+ makeDepends << obj_m << ": " <<
+ this->LocalGenerator->Convert(*i,
cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE)
+ cmLocalGenerator::MAKERULE)
<< std::endl;
- internalDepends << " " << i->c_str() << std::endl;
+ internalDepends << " " << *i << std::endl;
}
makeDepends << std::endl;
// Write module requirements to the output stream.
- for(std::set<cmStdString>::const_iterator i = info.Requires.begin();
+ for(std::set<std::string>::const_iterator i = info.Requires.begin();
i != info.Requires.end(); ++i)
{
// Require only modules not provided in the same source.
- if(std::set<cmStdString>::const_iterator(info.Provides.find(*i)) !=
+ if(std::set<std::string>::const_iterator(info.Provides.find(*i)) !=
info.Provides.end())
{
continue;
@@ -480,12 +405,12 @@ cmDependsFortran
proxy += "/";
proxy += *i;
proxy += ".mod.proxy";
- proxy = this->LocalGenerator->Convert(proxy.c_str(),
+ proxy = this->LocalGenerator->Convert(proxy,
cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE);
+ cmLocalGenerator::MAKERULE);
// since we require some things add them to our list of requirements
- makeDepends << obj << ".requires: " << proxy << std::endl;
+ makeDepends << obj_m << ".requires: " << proxy << std::endl;
}
// The object file should depend on timestamped files for the
@@ -497,10 +422,10 @@ cmDependsFortran
{
// This module is known. Depend on its timestamp file.
std::string stampFile =
- this->LocalGenerator->Convert(required->second.c_str(),
+ this->LocalGenerator->Convert(required->second,
cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE);
- makeDepends << obj << ": " << stampFile << "\n";
+ cmLocalGenerator::MAKERULE);
+ makeDepends << obj_m << ": " << stampFile << "\n";
}
else
{
@@ -510,26 +435,26 @@ cmDependsFortran
if(this->FindModule(*i, module))
{
module =
- this->LocalGenerator->Convert(module.c_str(),
+ this->LocalGenerator->Convert(module,
cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE);
- makeDepends << obj << ": " << module << "\n";
+ cmLocalGenerator::MAKERULE);
+ makeDepends << obj_m << ": " << module << "\n";
}
}
}
// Write provided modules to the output stream.
- for(std::set<cmStdString>::const_iterator i = info.Provides.begin();
+ for(std::set<std::string>::const_iterator i = info.Provides.begin();
i != info.Provides.end(); ++i)
{
std::string proxy = stamp_dir;
proxy += "/";
proxy += *i;
proxy += ".mod.proxy";
- proxy = this->LocalGenerator->Convert(proxy.c_str(),
+ proxy = this->LocalGenerator->Convert(proxy,
cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE);
- makeDepends << proxy << ": " << obj << ".provides" << std::endl;
+ cmLocalGenerator::MAKERULE);
+ makeDepends << proxy << ": " << obj_m << ".provides" << std::endl;
}
// If any modules are provided then they must be converted to stamp files.
@@ -537,8 +462,8 @@ cmDependsFortran
{
// Create a target to copy the module after the object file
// changes.
- makeDepends << obj << ".provides.build:\n";
- for(std::set<cmStdString>::const_iterator i = info.Provides.begin();
+ makeDepends << obj_m << ".provides.build:\n";
+ for(std::set<std::string>::const_iterator i = info.Provides.begin();
i != info.Provides.end(); ++i)
{
// Include this module in the set provided by this target.
@@ -552,7 +477,7 @@ cmDependsFortran
modFile += "/";
modFile += *i;
modFile =
- this->LocalGenerator->Convert(modFile.c_str(),
+ this->LocalGenerator->Convert(modFile,
cmLocalGenerator::HOME_OUTPUT,
cmLocalGenerator::SHELL);
std::string stampFile = stamp_dir;
@@ -560,7 +485,7 @@ cmDependsFortran
stampFile += m;
stampFile += ".mod.stamp";
stampFile =
- this->LocalGenerator->Convert(stampFile.c_str(),
+ this->LocalGenerator->Convert(stampFile,
cmLocalGenerator::HOME_OUTPUT,
cmLocalGenerator::SHELL);
makeDepends << "\t$(CMAKE_COMMAND) -E cmake_copy_f90_mod "
@@ -575,17 +500,17 @@ cmDependsFortran
}
// After copying the modules update the timestamp file so that
// copying will not be done again until the source rebuilds.
- makeDepends << "\t$(CMAKE_COMMAND) -E touch " << obj
+ makeDepends << "\t$(CMAKE_COMMAND) -E touch " << obj_m
<< ".provides.build\n";
// Make sure the module timestamp rule is evaluated by the time
// the target finishes building.
std::string driver = this->TargetDirectory;
driver += "/build";
- driver = this->LocalGenerator->Convert(driver.c_str(),
+ driver = this->LocalGenerator->Convert(driver,
cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE);
- makeDepends << driver << ": " << obj << ".provides.build\n";
+ cmLocalGenerator::MAKERULE);
+ makeDepends << driver << ": " << obj_m << ".provides.build\n";
}
return true;
@@ -663,10 +588,10 @@ bool cmDependsFortran::CopyModule(const std::vector<std::string>& args)
if(cmDependsFortran::ModulesDiffer(mod_upper.c_str(), stamp.c_str(),
compilerId.c_str()))
{
- if(!cmSystemTools::CopyFileAlways(mod_upper.c_str(), stamp.c_str()))
+ if(!cmSystemTools::CopyFileAlways(mod_upper, stamp))
{
std::cerr << "Error copying Fortran module from \""
- << mod_upper.c_str() << "\" to \"" << stamp.c_str()
+ << mod_upper << "\" to \"" << stamp
<< "\".\n";
return false;
}
@@ -678,10 +603,10 @@ bool cmDependsFortran::CopyModule(const std::vector<std::string>& args)
if(cmDependsFortran::ModulesDiffer(mod_lower.c_str(), stamp.c_str(),
compilerId.c_str()))
{
- if(!cmSystemTools::CopyFileAlways(mod_lower.c_str(), stamp.c_str()))
+ if(!cmSystemTools::CopyFileAlways(mod_lower, stamp))
{
std::cerr << "Error copying Fortran module from \""
- << mod_lower.c_str() << "\" to \"" << stamp.c_str()
+ << mod_lower << "\" to \"" << stamp
<< "\".\n";
return false;
}
@@ -689,9 +614,9 @@ bool cmDependsFortran::CopyModule(const std::vector<std::string>& args)
return true;
}
- std::cerr << "Error copying Fortran module \"" << args[2].c_str()
- << "\". Tried \"" << mod_upper.c_str()
- << "\" and \"" << mod_lower.c_str() << "\".\n";
+ std::cerr << "Error copying Fortran module \"" << args[2]
+ << "\". Tried \"" << mod_upper
+ << "\" and \"" << mod_lower << "\".\n";
return false;
}
@@ -700,7 +625,7 @@ bool cmDependsFortran::CopyModule(const std::vector<std::string>& args)
// is later used for longer sequences it should be re-written using an
// efficient string search algorithm such as Boyer-Moore.
static
-bool cmDependsFortranStreamContainsSequence(std::ifstream& ifs,
+bool cmFortranStreamContainsSequence(std::istream& ifs,
const char* seq, int len)
{
assert(len > 0);
@@ -733,8 +658,8 @@ bool cmDependsFortranStreamContainsSequence(std::ifstream& ifs,
//----------------------------------------------------------------------------
// Helper function to compare the remaining content in two streams.
-static bool cmDependsFortranStreamsDiffer(std::ifstream& ifs1,
- std::ifstream& ifs2)
+static bool cmFortranStreamsDiffer(std::istream& ifs1,
+ std::istream& ifs2)
{
// Compare the remaining content.
for(;;)
@@ -765,7 +690,11 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
const char* compilerId)
{
/*
- gnu:
+ gnu >= 4.9:
+ A mod file is an ascii file compressed with gzip.
+ Compiling twice produces identical modules.
+
+ gnu < 4.9:
A mod file is an ascii file.
<bar.mod>
FORTRAN module created from /path/to/foo.f90 on Sun Dec 30 22:47:58 2007
@@ -799,11 +728,11 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
}
#if defined(_WIN32) || defined(__CYGWIN__)
- std::ifstream finModFile(modFile, std::ios::in | std::ios::binary);
- std::ifstream finStampFile(stampFile, std::ios::in | std::ios::binary);
+ cmsys::ifstream finModFile(modFile, std::ios::in | std::ios::binary);
+ cmsys::ifstream finStampFile(stampFile, std::ios::in | std::ios::binary);
#else
- std::ifstream finModFile(modFile, std::ios::in);
- std::ifstream finStampFile(stampFile, std::ios::in);
+ cmsys::ifstream finModFile(modFile, std::ios::in);
+ cmsys::ifstream finStampFile(stampFile, std::ios::in);
#endif
if(!finModFile || !finStampFile)
{
@@ -821,21 +750,30 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
*/
if (strcmp(compilerId, "GNU") == 0 )
{
- const char seq[1] = {'\n'};
- const int seqlen = 1;
-
- if(!cmDependsFortranStreamContainsSequence(finModFile, seq, seqlen))
+ // GNU Fortran 4.9 and later compress .mod files with gzip
+ // but also do not include a date so we can fall through to
+ // compare them without skipping any prefix.
+ unsigned char hdr[2];
+ bool okay = finModFile.read(reinterpret_cast<char*>(hdr), 2)? true:false;
+ finModFile.seekg(0);
+ if(!(okay && hdr[0] == 0x1f && hdr[1] == 0x8b))
{
- // The module is of unexpected format. Assume it is different.
- std::cerr << compilerId << " fortran module " << modFile
- << " has unexpected format." << std::endl;
- return true;
- }
+ const char seq[1] = {'\n'};
+ const int seqlen = 1;
- if(!cmDependsFortranStreamContainsSequence(finStampFile, seq, seqlen))
- {
- // The stamp must differ if the sequence is not contained.
- return true;
+ if(!cmFortranStreamContainsSequence(finModFile, seq, seqlen))
+ {
+ // The module is of unexpected format. Assume it is different.
+ std::cerr << compilerId << " fortran module " << modFile
+ << " has unexpected format." << std::endl;
+ return true;
+ }
+
+ if(!cmFortranStreamContainsSequence(finStampFile, seq, seqlen))
+ {
+ // The stamp must differ if the sequence is not contained.
+ return true;
+ }
}
}
else if(strcmp(compilerId, "Intel") == 0)
@@ -843,7 +781,7 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
const char seq[2] = {'\n', '\0'};
const int seqlen = 2;
- if(!cmDependsFortranStreamContainsSequence(finModFile, seq, seqlen))
+ if(!cmFortranStreamContainsSequence(finModFile, seq, seqlen))
{
// The module is of unexpected format. Assume it is different.
std::cerr << compilerId << " fortran module " << modFile
@@ -851,7 +789,7 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
return true;
}
- if(!cmDependsFortranStreamContainsSequence(finStampFile, seq, seqlen))
+ if(!cmFortranStreamContainsSequence(finStampFile, seq, seqlen))
{
// The stamp must differ if the sequence is not contained.
return true;
@@ -861,7 +799,7 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
// Compare the remaining content. If no compiler id matched above,
// including the case none was given, this will compare the whole
// content.
- if(!cmDependsFortranStreamsDiffer(finModFile, finStampFile))
+ if(!cmFortranStreamsDiffer(finModFile, finStampFile))
{
return false;
}
@@ -869,396 +807,3 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
// The modules are different.
return true;
}
-
-//----------------------------------------------------------------------------
-bool cmDependsFortran::FindIncludeFile(const char* dir,
- const char* includeName,
- std::string& fileName)
-{
- // If the file is a full path, include it directly.
- if(cmSystemTools::FileIsFullPath(includeName))
- {
- fileName = includeName;
- return cmSystemTools::FileExists(fileName.c_str(), true);
- }
- else
- {
- // Check for the file in the directory containing the including
- // file.
- std::string fullName = dir;
- fullName += "/";
- fullName += includeName;
- if(cmSystemTools::FileExists(fullName.c_str(), true))
- {
- fileName = fullName;
- return true;
- }
-
- // Search the include path for the file.
- for(std::vector<std::string>::const_iterator i =
- this->IncludePath.begin(); i != this->IncludePath.end(); ++i)
- {
- fullName = *i;
- fullName += "/";
- fullName += includeName;
- if(cmSystemTools::FileExists(fullName.c_str(), true))
- {
- fileName = fullName;
- return true;
- }
- }
- }
- return false;
-}
-
-//----------------------------------------------------------------------------
-cmDependsFortranParser_s
-::cmDependsFortranParser_s(cmDependsFortran* self,
- std::set<std::string>& ppDefines,
- cmDependsFortranSourceInfo& info):
- Self(self), PPDefinitions(ppDefines), Info(info)
-{
- this->InInterface = 0;
- this->InPPFalseBranch = 0;
-
- // Initialize the lexical scanner.
- cmDependsFortran_yylex_init(&this->Scanner);
- cmDependsFortran_yyset_extra(this, this->Scanner);
-
- // Create a dummy buffer that is never read but is the fallback
- // buffer when the last file is popped off the stack.
- YY_BUFFER_STATE buffer =
- cmDependsFortran_yy_create_buffer(0, 4, this->Scanner);
- cmDependsFortran_yy_switch_to_buffer(buffer, this->Scanner);
-}
-
-//----------------------------------------------------------------------------
-cmDependsFortranParser_s::~cmDependsFortranParser_s()
-{
- cmDependsFortran_yylex_destroy(this->Scanner);
-}
-
-//----------------------------------------------------------------------------
-bool cmDependsFortranParser_FilePush(cmDependsFortranParser* parser,
- const char* fname)
-{
- // Open the new file and push it onto the stack. Save the old
- // buffer with it on the stack.
- if(FILE* file = fopen(fname, "rb"))
- {
- YY_BUFFER_STATE current =
- cmDependsFortranLexer_GetCurrentBuffer(parser->Scanner);
- std::string dir = cmSystemTools::GetParentDirectory(fname);
- cmDependsFortranFile f(file, current, dir);
- YY_BUFFER_STATE buffer =
- cmDependsFortran_yy_create_buffer(0, 16384, parser->Scanner);
- cmDependsFortran_yy_switch_to_buffer(buffer, parser->Scanner);
- parser->FileStack.push(f);
- return 1;
- }
- else
- {
- return 0;
- }
-}
-
-//----------------------------------------------------------------------------
-bool cmDependsFortranParser_FilePop(cmDependsFortranParser* parser)
-{
- // Pop one file off the stack and close it. Switch the lexer back
- // to the next one on the stack.
- if(parser->FileStack.empty())
- {
- return 0;
- }
- else
- {
- cmDependsFortranFile f = parser->FileStack.top(); parser->FileStack.pop();
- fclose(f.File);
- YY_BUFFER_STATE current =
- cmDependsFortranLexer_GetCurrentBuffer(parser->Scanner);
- cmDependsFortran_yy_delete_buffer(current, parser->Scanner);
- cmDependsFortran_yy_switch_to_buffer(f.Buffer, parser->Scanner);
- return 1;
- }
-}
-
-//----------------------------------------------------------------------------
-int cmDependsFortranParser_Input(cmDependsFortranParser* parser,
- char* buffer, size_t bufferSize)
-{
- // Read from the file on top of the stack. If the stack is empty,
- // the end of the translation unit has been reached.
- if(!parser->FileStack.empty())
- {
- FILE* file = parser->FileStack.top().File;
- return (int)fread(buffer, 1, bufferSize, file);
- }
- return 0;
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_StringStart(cmDependsFortranParser* parser)
-{
- parser->TokenString = "";
-}
-
-//----------------------------------------------------------------------------
-const char* cmDependsFortranParser_StringEnd(cmDependsFortranParser* parser)
-{
- return parser->TokenString.c_str();
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_StringAppend(cmDependsFortranParser* parser,
- char c)
-{
- parser->TokenString += c;
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_SetInInterface(cmDependsFortranParser* parser,
- bool in)
-{
- if(parser->InPPFalseBranch)
- {
- return;
- }
-
- parser->InInterface = in;
-}
-
-//----------------------------------------------------------------------------
-bool cmDependsFortranParser_GetInInterface(cmDependsFortranParser* parser)
-{
- return parser->InInterface;
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_SetOldStartcond(cmDependsFortranParser* parser,
- int arg)
-{
- parser->OldStartcond = arg;
-}
-
-//----------------------------------------------------------------------------
-int cmDependsFortranParser_GetOldStartcond(cmDependsFortranParser* parser)
-{
- return parser->OldStartcond;
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_Error(cmDependsFortranParser*, const char*)
-{
- // If there is a parser error just ignore it. The source will not
- // compile and the user will edit it. Then dependencies will have
- // to be regenerated anyway.
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleUse(cmDependsFortranParser* parser,
- const char* name)
-{
- if(!parser->InPPFalseBranch)
- {
- parser->Info.Requires.insert(cmSystemTools::LowerCase(name) );
- }
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleInclude(cmDependsFortranParser* parser,
- const char* name)
-{
- if(parser->InPPFalseBranch)
- {
- return;
- }
-
- // If processing an include statement there must be an open file.
- assert(!parser->FileStack.empty());
-
- // Get the directory containing the source in which the include
- // statement appears. This is always the first search location for
- // Fortran include files.
- std::string dir = parser->FileStack.top().Directory;
-
- // Find the included file. If it cannot be found just ignore the
- // problem because either the source will not compile or the user
- // does not care about depending on this included source.
- std::string fullName;
- if(parser->Self->FindIncludeFile(dir.c_str(), name, fullName))
- {
- // Found the included file. Save it in the set of included files.
- parser->Info.Includes.insert(fullName);
-
- // Parse it immediately to translate the source inline.
- cmDependsFortranParser_FilePush(parser, fullName.c_str());
- }
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleModule(cmDependsFortranParser* parser,
- const char* name)
-{
- if(!parser->InPPFalseBranch && !parser->InInterface)
- {
- parser->Info.Provides.insert(cmSystemTools::LowerCase(name));
- }
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleDefine(cmDependsFortranParser* parser,
- const char* macro)
-{
- if(!parser->InPPFalseBranch)
- {
- parser->PPDefinitions.insert(macro);
- }
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleUndef(cmDependsFortranParser* parser,
- const char* macro)
-{
- if(!parser->InPPFalseBranch)
- {
- std::set<std::string>::iterator match;
- match = parser->PPDefinitions.find(macro);
- if(match != parser->PPDefinitions.end())
- {
- parser->PPDefinitions.erase(match);
- }
- }
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleIfdef(cmDependsFortranParser* parser,
- const char* macro)
-{
- // A new PP branch has been opened
- parser->SkipToEnd.push(false);
-
- if (parser->InPPFalseBranch)
- {
- parser->InPPFalseBranch++;
- }
- else if(parser->PPDefinitions.find(macro) == parser->PPDefinitions.end())
- {
- parser->InPPFalseBranch=1;
- }
- else
- {
- parser->SkipToEnd.top() = true;
- }
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleIfndef(cmDependsFortranParser* parser,
- const char* macro)
-{
- // A new PP branch has been opened
- parser->SkipToEnd.push(false);
-
- if (parser->InPPFalseBranch)
- {
- parser->InPPFalseBranch++;
- }
- else if(parser->PPDefinitions.find(macro) != parser->PPDefinitions.end())
- {
- parser->InPPFalseBranch = 1;
- }
- else
- {
- // ignore other branches
- parser->SkipToEnd.top() = true;
- }
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleIf(cmDependsFortranParser* parser)
-{
- /* Note: The current parser is _not_ able to get statements like
- * #if 0
- * #if 1
- * #if MYSMBOL
- * #if defined(MYSYMBOL)
- * #if defined(MYSYMBOL) && ...
- * right. The same for #elif. Thus in
- * #if SYMBOL_1
- * ..
- * #elif SYMBOL_2
- * ...
- * ...
- * #elif SYMBOL_N
- * ..
- * #else
- * ..
- * #endif
- * _all_ N+1 branches are considered. If you got something like this
- * #if defined(MYSYMBOL)
- * #if !defined(MYSYMBOL)
- * use
- * #ifdef MYSYMBOL
- * #ifndef MYSYMBOL
- * instead.
- */
-
- // A new PP branch has been opened
- // Never skip! See note above.
- parser->SkipToEnd.push(false);
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleElif(cmDependsFortranParser* parser)
-{
- /* Note: There are parser limitations. See the note at
- * cmDependsFortranParser_RuleIf(..)
- */
-
- // Always taken unless an #ifdef or #ifndef-branch has been taken
- // already. If the second condition isn't meet already
- // (parser->InPPFalseBranch == 0) correct it.
- if(!parser->SkipToEnd.empty() &&
- parser->SkipToEnd.top() && !parser->InPPFalseBranch)
- {
- parser->InPPFalseBranch = 1;
- }
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleElse(cmDependsFortranParser* parser)
-{
- // if the parent branch is false do nothing!
- if(parser->InPPFalseBranch > 1)
- {
- return;
- }
-
- // parser->InPPFalseBranch is either 0 or 1. We change it depending on
- // parser->SkipToEnd.top()
- if(!parser->SkipToEnd.empty() &&
- parser->SkipToEnd.top())
- {
- parser->InPPFalseBranch = 1;
- }
- else
- {
- parser->InPPFalseBranch = 0;
- }
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleEndif(cmDependsFortranParser* parser)
-{
- if(!parser->SkipToEnd.empty())
- {
- parser->SkipToEnd.pop();
- }
-
- // #endif doesn't know if there was a "#else" in before, so it
- // always decreases InPPFalseBranch
- if(parser->InPPFalseBranch)
- {
- parser->InPPFalseBranch--;
- }
-}
diff --git a/Source/cmDependsFortran.h b/Source/cmDependsFortran.h
index cb40796c8..a8a401330 100644
--- a/Source/cmDependsFortran.h
+++ b/Source/cmDependsFortran.h
@@ -9,13 +9,13 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#ifndef cmDependsFortran_h
-#define cmDependsFortran_h
+#ifndef cmFortran_h
+#define cmFortran_h
#include "cmDepends.h"
class cmDependsFortranInternals;
-class cmDependsFortranSourceInfo;
+class cmFortranSourceInfo;
/** \class cmDependsFortran
* \brief Dependency scanner for Fortran object files.
@@ -46,12 +46,6 @@ public:
static bool ModulesDiffer(const char* modFile, const char* stampFile,
const char* compilerId);
- /** Method to find an included file in the include path. Fortran
- always searches the directory containing the including source
- first. */
- bool FindIncludeFile(const char* dir, const char* includeName,
- std::string& fileName);
-
protected:
// Finalize the dependency information for the target.
virtual bool Finalize(std::ostream& makeDepends,
@@ -71,15 +65,16 @@ protected:
// Actually write the depenencies to the streams.
bool WriteDependenciesReal(const char *obj,
- cmDependsFortranSourceInfo const& info,
- const char* mod_dir, const char* stamp_dir,
+ cmFortranSourceInfo const& info,
+ std::string const& mod_dir,
+ const char* stamp_dir,
std::ostream& makeDepends,
std::ostream& internalDepends);
// The source file from which to start scanning.
std::string SourceFile;
- std::vector<std::string> PPDefinitions;
+ std::set<std::string> PPDefinitions;
// Internal implementation details.
cmDependsFortranInternals* Internal;
diff --git a/Source/cmDependsFortranLexer.cxx b/Source/cmDependsFortranLexer.cxx
deleted file mode 100644
index 924d9d2a9..000000000
--- a/Source/cmDependsFortranLexer.cxx
+++ /dev/null
@@ -1,2414 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#line 2 "cmDependsFortranLexer.cxx"
-
-#line 4 "cmDependsFortranLexer.cxx"
-
-#define YY_INT_ALIGNED short int
-
-/* A lexical scanner generated by flex */
-
-#define FLEX_SCANNER
-#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 35
-#if YY_FLEX_SUBMINOR_VERSION > 0
-#define FLEX_BETA
-#endif
-
-/* First, we deal with platform-specific or compiler-specific issues. */
-
-/* begin standard C headers. */
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* end standard C headers. */
-
-/* flex integer type definitions */
-
-#ifndef FLEXINT_H
-#define FLEXINT_H
-
-/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
-
-#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-
-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
- * if you want the limit (max/min) macros for int types.
- */
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS 1
-#endif
-
-#include <inttypes.h>
-typedef int8_t flex_int8_t;
-typedef uint8_t flex_uint8_t;
-typedef int16_t flex_int16_t;
-typedef uint16_t flex_uint16_t;
-typedef int32_t flex_int32_t;
-typedef uint32_t flex_uint32_t;
-#else
-typedef signed char flex_int8_t;
-typedef short int flex_int16_t;
-typedef int flex_int32_t;
-typedef unsigned char flex_uint8_t;
-typedef unsigned short int flex_uint16_t;
-typedef unsigned int flex_uint32_t;
-
-/* Limits of integral types. */
-#ifndef INT8_MIN
-#define INT8_MIN (-128)
-#endif
-#ifndef INT16_MIN
-#define INT16_MIN (-32767-1)
-#endif
-#ifndef INT32_MIN
-#define INT32_MIN (-2147483647-1)
-#endif
-#ifndef INT8_MAX
-#define INT8_MAX (127)
-#endif
-#ifndef INT16_MAX
-#define INT16_MAX (32767)
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX (2147483647)
-#endif
-#ifndef UINT8_MAX
-#define UINT8_MAX (255U)
-#endif
-#ifndef UINT16_MAX
-#define UINT16_MAX (65535U)
-#endif
-#ifndef UINT32_MAX
-#define UINT32_MAX (4294967295U)
-#endif
-
-#endif /* ! C99 */
-
-#endif /* ! FLEXINT_H */
-
-#ifdef __cplusplus
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else /* ! __cplusplus */
-
-/* C99 requires __STDC__ to be defined as 1. */
-#if defined (__STDC__)
-
-#define YY_USE_CONST
-
-#endif /* defined (__STDC__) */
-#endif /* ! __cplusplus */
-
-#ifdef YY_USE_CONST
-#define yyconst const
-#else
-#define yyconst
-#endif
-
-/* Returned upon end-of-file. */
-#define YY_NULL 0
-
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index. If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
- */
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
-
-/* An opaque pointer. */
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
-typedef void* yyscan_t;
-#endif
-
-/* For convenience, these vars (plus the bison vars far below)
- are macros in the reentrant scanner. */
-#define yyin yyg->yyin_r
-#define yyout yyg->yyout_r
-#define yyextra yyg->yyextra_r
-#define yyleng yyg->yyleng_r
-#define yytext yyg->yytext_r
-#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
-#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
-#define yy_flex_debug yyg->yy_flex_debug_r
-
-/* Enter a start condition. This macro really ought to take a parameter,
- * but we do it the disgusting crufty way forced on us by the ()-less
- * definition of BEGIN.
- */
-#define BEGIN yyg->yy_start = 1 + 2 *
-
-/* Translate the current start state into a value that can be later handed
- * to BEGIN to return to the state. The YYSTATE alias is for lex
- * compatibility.
- */
-#define YY_START ((yyg->yy_start - 1) / 2)
-#define YYSTATE YY_START
-
-/* Action number for EOF rule of a given start state. */
-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
-/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE cmDependsFortran_yyrestart(yyin ,yyscanner )
-
-#define YY_END_OF_BUFFER_CHAR 0
-
-/* Size of default input buffer. */
-#ifndef YY_BUF_SIZE
-#ifdef __ia64__
-/* On IA-64, the buffer size is 16k, not 8k.
- * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
- * Ditto for the __ia64__ case accordingly.
- */
-#define YY_BUF_SIZE 32768
-#else
-#define YY_BUF_SIZE 16384
-#endif /* __ia64__ */
-#endif
-
-/* The state buf must be large enough to hold one state per character in the main buffer.
- */
-#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
-
-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
-#define YY_TYPEDEF_YY_BUFFER_STATE
-typedef struct yy_buffer_state *YY_BUFFER_STATE;
-#endif
-
-#define EOB_ACT_CONTINUE_SCAN 0
-#define EOB_ACT_END_OF_FILE 1
-#define EOB_ACT_LAST_MATCH 2
-
- #define YY_LESS_LINENO(n)
-
-/* Return all but the first "n" matched characters back to the input stream. */
-#define yyless(n) \
- do \
- { \
- /* Undo effects of setting up yytext. */ \
- int yyless_macro_arg = (n); \
- YY_LESS_LINENO(yyless_macro_arg);\
- *yy_cp = yyg->yy_hold_char; \
- YY_RESTORE_YY_MORE_OFFSET \
- yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
- YY_DO_BEFORE_ACTION; /* set up yytext again */ \
- } \
- while ( 0 )
-
-#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
-
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
-#ifndef YY_STRUCT_YY_BUFFER_STATE
-#define YY_STRUCT_YY_BUFFER_STATE
-struct yy_buffer_state
- {
- FILE *yy_input_file;
-
- char *yy_ch_buf; /* input buffer */
- char *yy_buf_pos; /* current position in input buffer */
-
- /* Size of input buffer in bytes, not including room for EOB
- * characters.
- */
- yy_size_t yy_buf_size;
-
- /* Number of characters read into yy_ch_buf, not including EOB
- * characters.
- */
- int yy_n_chars;
-
- /* Whether we "own" the buffer - i.e., we know we created it,
- * and can realloc() it to grow it, and should free() it to
- * delete it.
- */
- int yy_is_our_buffer;
-
- /* Whether this is an "interactive" input source; if so, and
- * if we're using stdio for input, then we want to use getc()
- * instead of fread(), to make sure we stop fetching input after
- * each newline.
- */
- int yy_is_interactive;
-
- /* Whether we're considered to be at the beginning of a line.
- * If so, '^' rules will be active on the next match, otherwise
- * not.
- */
- int yy_at_bol;
-
- int yy_bs_lineno; /**< The line count. */
- int yy_bs_column; /**< The column count. */
-
- /* Whether to try to fill the input buffer when we reach the
- * end of it.
- */
- int yy_fill_buffer;
-
- int yy_buffer_status;
-
-#define YY_BUFFER_NEW 0
-#define YY_BUFFER_NORMAL 1
- /* When an EOF's been seen but there's still some text to process
- * then we mark the buffer as YY_EOF_PENDING, to indicate that we
- * shouldn't try reading from the input source any more. We might
- * still have a bunch of tokens to match, though, because of
- * possible backing-up.
- *
- * When we actually see the EOF, we change the status to "new"
- * (via cmDependsFortran_yyrestart()), so that the user can continue scanning by
- * just pointing yyin at a new input file.
- */
-#define YY_BUFFER_EOF_PENDING 2
-
- };
-#endif /* !YY_STRUCT_YY_BUFFER_STATE */
-
-/* We provide macros for accessing buffer states in case in the
- * future we want to put the buffer states in a more general
- * "scanner state".
- *
- * Returns the top of the stack, or NULL.
- */
-#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
- ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
- : NULL)
-
-/* Same as previous macro, but useful when we know that the buffer stack is not
- * NULL or when we need an lvalue. For internal use only.
- */
-#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
-
-void cmDependsFortran_yyrestart (FILE *input_file ,yyscan_t yyscanner );
-void cmDependsFortran_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-YY_BUFFER_STATE cmDependsFortran_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
-void cmDependsFortran_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void cmDependsFortran_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void cmDependsFortran_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-void cmDependsFortran_yypop_buffer_state (yyscan_t yyscanner );
-
-static void cmDependsFortran_yyensure_buffer_stack (yyscan_t yyscanner );
-static void cmDependsFortran_yy_load_buffer_state (yyscan_t yyscanner );
-static void cmDependsFortran_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
-
-#define YY_FLUSH_BUFFER cmDependsFortran_yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
-
-YY_BUFFER_STATE cmDependsFortran_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
-YY_BUFFER_STATE cmDependsFortran_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
-YY_BUFFER_STATE cmDependsFortran_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
-
-void *cmDependsFortran_yyalloc (yy_size_t ,yyscan_t yyscanner );
-void *cmDependsFortran_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
-void cmDependsFortran_yyfree (void * ,yyscan_t yyscanner );
-
-#define yy_new_buffer cmDependsFortran_yy_create_buffer
-
-#define yy_set_interactive(is_interactive) \
- { \
- if ( ! YY_CURRENT_BUFFER ){ \
- cmDependsFortran_yyensure_buffer_stack (yyscanner); \
- YY_CURRENT_BUFFER_LVALUE = \
- cmDependsFortran_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
- } \
- YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
- }
-
-#define yy_set_bol(at_bol) \
- { \
- if ( ! YY_CURRENT_BUFFER ){\
- cmDependsFortran_yyensure_buffer_stack (yyscanner); \
- YY_CURRENT_BUFFER_LVALUE = \
- cmDependsFortran_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
- } \
- YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
- }
-
-#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
-
-/* Begin user sect3 */
-
-#define cmDependsFortran_yywrap(n) 1
-#define YY_SKIP_YYWRAP
-
-typedef unsigned char YY_CHAR;
-
-typedef int yy_state_type;
-
-#define yytext_ptr yytext_r
-
-static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner);
-static int yy_get_next_buffer (yyscan_t yyscanner );
-static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
-
-/* Done after the current pattern has been matched and before the
- * corresponding action - sets up yytext.
- */
-#define YY_DO_BEFORE_ACTION \
- yyg->yytext_ptr = yy_bp; \
- yyleng = (size_t) (yy_cp - yy_bp); \
- yyg->yy_hold_char = *yy_cp; \
- *yy_cp = '\0'; \
- yyg->yy_c_buf_p = yy_cp;
-
-#define YY_NUM_RULES 44
-#define YY_END_OF_BUFFER 45
-/* This struct is not used in this scanner,
- but its presence is necessary. */
-struct yy_trans_info
- {
- flex_int32_t yy_verify;
- flex_int32_t yy_nxt;
- };
-static yyconst flex_int16_t yy_accept[165] =
- { 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 45, 39, 41, 40, 43, 1, 39, 32, 2, 34,
- 39, 40, 37, 39, 38, 39, 38, 41, 39, 40,
- 39, 38, 9, 8, 9, 4, 3, 39, 0, 10,
- 0, 0, 0, 0, 0, 32, 32, 33, 35, 37,
- 39, 38, 0, 42, 38, 0, 0, 0, 0, 0,
- 0, 0, 0, 39, 0, 11, 38, 0, 0, 5,
- 0, 0, 0, 28, 0, 0, 32, 32, 32, 32,
- 0, 0, 0, 0, 0, 22, 0, 0, 0, 0,
- 0, 6, 0, 0, 0, 0, 0, 0, 0, 0,
-
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 29, 30, 0, 0, 0, 0, 0, 0,
- 0, 23, 24, 0, 0, 0, 0, 0, 0, 0,
- 0, 31, 26, 0, 0, 19, 0, 0, 25, 20,
- 0, 0, 18, 0, 0, 17, 27, 0, 0, 16,
- 21, 0, 7, 36, 7, 14, 0, 13, 15, 0,
- 0, 0, 12, 0
- } ;
-
-static yyconst flex_int32_t yy_ec[256] =
- { 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
- 1, 1, 4, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 5, 6, 7, 8, 9, 1, 10, 11, 1,
- 1, 12, 1, 13, 1, 1, 1, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 15, 16, 17,
- 18, 19, 20, 1, 21, 21, 22, 23, 24, 25,
- 21, 21, 26, 21, 21, 27, 21, 28, 21, 21,
- 21, 21, 29, 21, 30, 21, 21, 21, 21, 21,
- 1, 31, 1, 1, 32, 1, 21, 21, 33, 34,
-
- 35, 36, 21, 21, 37, 21, 21, 38, 21, 39,
- 21, 21, 21, 21, 40, 21, 41, 21, 21, 21,
- 21, 21, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1
- } ;
-
-static yyconst flex_int32_t yy_meta[42] =
- { 0,
- 1, 2, 2, 3, 4, 3, 3, 1, 1, 3,
- 3, 1, 3, 5, 1, 3, 1, 3, 6, 1,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 1, 5, 7, 7, 7, 7, 7, 7, 7, 7,
- 7
- } ;
-
-static yyconst flex_int16_t yy_base[174] =
- { 0,
- 0, 40, 0, 41, 188, 48, 44, 54, 56, 65,
- 186, 0, 505, 505, 171, 505, 81, 74, 505, 505,
- 158, 505, 151, 137, 0, 85, 122, 87, 153, 145,
- 194, 226, 505, 143, 91, 505, 505, 0, 142, 505,
- 266, 34, 70, 74, 34, 122, 141, 505, 0, 505,
- 112, 0, 98, 505, 0, 154, 306, 0, 43, 133,
- 139, 46, 130, 347, 130, 505, 0, 121, 163, 179,
- 104, 156, 129, 176, 147, 178, 214, 267, 273, 292,
- 279, 179, 249, 280, 257, 265, 288, 289, 116, 107,
- 317, 505, 287, 289, 291, 302, 307, 310, 307, 311,
-
- 316, 326, 329, 333, 332, 336, 347, 345, 349, 101,
- 86, 346, 505, 505, 350, 351, 353, 350, 357, 362,
- 362, 505, 505, 367, 369, 371, 366, 372, 56, 47,
- 374, 505, 505, 374, 379, 505, 374, 387, 505, 505,
- 387, 391, 505, 117, 0, 505, 505, 392, 394, 505,
- 505, 394, 505, 505, 505, 505, 395, 419, 505, 429,
- 0, 25, 505, 505, 446, 453, 459, 462, 469, 476,
- 483, 490, 497
- } ;
-
-static yyconst flex_int16_t yy_def[174] =
- { 0,
- 164, 1, 1, 1, 1, 1, 165, 165, 165, 165,
- 164, 166, 164, 164, 167, 164, 166, 164, 164, 164,
- 166, 164, 164, 166, 168, 166, 168, 164, 166, 164,
- 169, 164, 164, 164, 164, 164, 164, 166, 167, 164,
- 164, 164, 164, 164, 164, 164, 170, 164, 166, 164,
- 166, 168, 164, 164, 27, 164, 164, 57, 164, 164,
- 164, 164, 164, 169, 169, 164, 32, 164, 164, 164,
- 164, 164, 164, 164, 164, 164, 170, 170, 170, 170,
- 164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
- 164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
-
- 164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
- 164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
- 164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
- 164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
- 164, 164, 164, 171, 172, 164, 164, 164, 164, 164,
- 164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
- 173, 173, 164, 0, 164, 164, 164, 164, 164, 164,
- 164, 164, 164
- } ;
-
-static yyconst flex_int16_t yy_nxt[547] =
- { 0,
- 12, 13, 14, 13, 13, 15, 16, 12, 17, 18,
- 19, 12, 20, 12, 21, 22, 12, 23, 12, 24,
- 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
- 26, 27, 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 28, 28, 163, 28, 28, 34, 29, 29, 28,
- 30, 145, 28, 35, 36, 29, 34, 71, 34, 31,
- 144, 76, 37, 35, 36, 35, 83, 34, 71, 32,
- 32, 37, 76, 88, 35, 46, 46, 83, 46, 47,
- 32, 32, 41, 48, 88, 41, 53, 54, 56, 53,
- 130, 56, 69, 70, 57, 69, 72, 73, 74, 53,
-
- 54, 75, 53, 42, 43, 129, 44, 72, 73, 74,
- 45, 111, 75, 81, 42, 43, 81, 44, 154, 154,
- 110, 45, 38, 46, 46, 90, 46, 47, 93, 38,
- 38, 48, 66, 38, 89, 55, 38, 82, 38, 93,
- 38, 38, 78, 46, 40, 78, 79, 68, 82, 63,
- 80, 96, 38, 55, 58, 56, 51, 58, 56, 84,
- 85, 57, 96, 86, 69, 70, 87, 69, 99, 50,
- 84, 85, 49, 40, 86, 59, 60, 87, 61, 99,
- 91, 94, 62, 91, 95, 164, 59, 60, 92, 61,
- 30, 164, 94, 62, 64, 95, 66, 164, 97, 164,
-
- 100, 64, 64, 98, 164, 64, 101, 64, 64, 97,
- 64, 100, 64, 64, 98, 78, 46, 101, 78, 79,
- 164, 164, 164, 80, 64, 64, 65, 65, 66, 65,
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 67,
- 65, 65, 65, 65, 65, 65, 67, 67, 67, 67,
- 67, 67, 67, 67, 67, 67, 65, 67, 67, 67,
- 67, 67, 67, 67, 67, 67, 67, 41, 78, 46,
- 41, 78, 79, 102, 78, 46, 80, 78, 79, 105,
- 81, 164, 80, 81, 102, 164, 164, 106, 42, 43,
- 105, 44, 107, 78, 46, 45, 78, 79, 106, 42,
-
- 43, 80, 44, 107, 82, 103, 45, 58, 104, 108,
- 58, 109, 112, 113, 114, 82, 103, 164, 91, 104,
- 108, 91, 109, 112, 113, 114, 92, 115, 59, 60,
- 116, 61, 117, 118, 119, 62, 164, 120, 115, 59,
- 60, 116, 61, 117, 118, 119, 62, 64, 120, 66,
- 164, 121, 164, 122, 64, 64, 123, 124, 64, 125,
- 64, 64, 121, 64, 122, 64, 64, 123, 124, 126,
- 125, 127, 128, 131, 132, 133, 134, 64, 64, 135,
- 126, 136, 127, 128, 131, 132, 133, 134, 137, 138,
- 135, 139, 136, 140, 141, 142, 143, 146, 147, 137,
-
- 138, 148, 139, 149, 140, 141, 142, 143, 146, 147,
- 150, 151, 148, 152, 149, 156, 157, 158, 159, 164,
- 160, 150, 151, 160, 152, 164, 156, 157, 158, 159,
- 160, 164, 164, 160, 164, 161, 164, 164, 164, 164,
- 164, 164, 164, 164, 164, 161, 33, 33, 33, 33,
- 33, 33, 33, 38, 164, 164, 164, 38, 38, 39,
- 39, 39, 39, 39, 39, 39, 52, 164, 52, 65,
- 65, 65, 65, 65, 65, 65, 77, 77, 77, 77,
- 77, 77, 77, 153, 153, 153, 164, 153, 153, 153,
- 155, 164, 155, 164, 155, 155, 155, 162, 162, 162,
-
- 162, 162, 164, 162, 11, 164, 164, 164, 164, 164,
- 164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
- 164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
- 164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
- 164, 164, 164, 164, 164, 164
- } ;
-
-static yyconst flex_int16_t yy_chk[547] =
- { 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 2, 4, 162, 2, 4, 7, 2, 4, 6,
- 6, 130, 6, 7, 7, 6, 8, 42, 9, 6,
- 129, 45, 9, 8, 8, 9, 59, 10, 42, 6,
- 6, 10, 45, 62, 10, 18, 18, 59, 18, 18,
- 6, 6, 17, 18, 62, 17, 26, 26, 28, 26,
- 111, 28, 35, 35, 28, 35, 43, 43, 44, 53,
-
- 53, 44, 53, 17, 17, 110, 17, 43, 43, 44,
- 17, 90, 44, 51, 17, 17, 51, 17, 144, 144,
- 89, 17, 27, 46, 46, 68, 46, 46, 71, 27,
- 27, 46, 65, 27, 63, 27, 27, 51, 27, 71,
- 27, 27, 47, 47, 39, 47, 47, 34, 51, 30,
- 47, 73, 27, 27, 29, 56, 24, 29, 56, 60,
- 60, 56, 73, 61, 69, 69, 61, 69, 75, 23,
- 60, 60, 21, 15, 61, 29, 29, 61, 29, 75,
- 70, 72, 29, 70, 72, 11, 29, 29, 70, 29,
- 5, 0, 72, 29, 31, 72, 31, 0, 74, 0,
-
- 76, 31, 31, 74, 0, 31, 82, 31, 31, 74,
- 31, 76, 31, 31, 74, 77, 77, 82, 77, 77,
- 0, 0, 0, 77, 31, 31, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 41, 78, 78,
- 41, 78, 78, 83, 79, 79, 78, 79, 79, 85,
- 81, 0, 79, 81, 83, 0, 0, 86, 41, 41,
- 85, 41, 86, 80, 80, 41, 80, 80, 86, 41,
-
- 41, 80, 41, 86, 81, 84, 41, 57, 84, 87,
- 57, 88, 93, 94, 95, 81, 84, 0, 91, 84,
- 87, 91, 88, 93, 94, 95, 91, 96, 57, 57,
- 97, 57, 98, 99, 100, 57, 0, 101, 96, 57,
- 57, 97, 57, 98, 99, 100, 57, 64, 101, 64,
- 0, 102, 0, 103, 64, 64, 104, 105, 64, 106,
- 64, 64, 102, 64, 103, 64, 64, 104, 105, 107,
- 106, 108, 109, 112, 115, 116, 117, 64, 64, 118,
- 107, 119, 108, 109, 112, 115, 116, 117, 120, 121,
- 118, 124, 119, 125, 126, 127, 128, 131, 134, 120,
-
- 121, 135, 124, 137, 125, 126, 127, 128, 131, 134,
- 138, 141, 135, 142, 137, 148, 149, 152, 157, 0,
- 158, 138, 141, 158, 142, 0, 148, 149, 152, 157,
- 160, 0, 0, 160, 0, 158, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 160, 165, 165, 165, 165,
- 165, 165, 165, 166, 0, 0, 0, 166, 166, 167,
- 167, 167, 167, 167, 167, 167, 168, 0, 168, 169,
- 169, 169, 169, 169, 169, 169, 170, 170, 170, 170,
- 170, 170, 170, 171, 171, 171, 0, 171, 171, 171,
- 172, 0, 172, 0, 172, 172, 172, 173, 173, 173,
-
- 173, 173, 0, 173, 164, 164, 164, 164, 164, 164,
- 164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
- 164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
- 164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
- 164, 164, 164, 164, 164, 164
- } ;
-
-/* The intent behind this definition is that it'll catch
- * any uses of REJECT which flex missed.
- */
-#define REJECT reject_used_but_not_detected
-#define yymore() yymore_used_but_not_detected
-#define YY_MORE_ADJ 0
-#define YY_RESTORE_YY_MORE_OFFSET
-#line 1 "cmDependsFortranLexer.in.l"
-#line 2 "cmDependsFortranLexer.in.l"
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-/*-------------------------------------------------------------------------
- Portions of this source have been derived from makedepf90 version 2.8.8,
-
- Copyright (C) 2000--2006 Erik Edelmann <erik.edelmann@iki.fi>
-
- The code was originally distributed under the GPL but permission
- from the copyright holder has been obtained to distribute this
- derived work under the CMake license.
--------------------------------------------------------------------------*/
-
-/*
-
-This file must be translated to C and modified to build everywhere.
-
-Run flex like this:
-
- flex -i --prefix=cmDependsFortran_yy --header-file=cmDependsFortranLexer.h -ocmDependsFortranLexer.cxx cmDependsFortranLexer.in.l
-
-Modify cmDependsFortranLexer.cxx:
- - remove TABs
- - remove "yyscanner" argument from these methods:
- yy_fatal_error, cmDependsFortran_yyalloc, cmDependsFortran_yyrealloc, cmDependsFortran_yyfree
- - remove "yyscanner = NULL" from end of cmDependsFortran_yylex_destroy
- - remove all YY_BREAK lines occurring right after return statements
- - change while ( 1 ) to for(;;)
-
-Modify cmDependsFortranLexer.h:
- - remove TABs
- - remove the yy_init_globals function
- - remove the block that includes unistd.h
- - remove #line directives (avoids bogus warning on old Sun)
-
-*/
-
-#include "cmStandardLexer.h"
-
-#define cmDependsFortranLexer_cxx
-#include "cmDependsFortranParser.h" /* Interface to parser object. */
-
-/* Replace the lexer input function. */
-#undef YY_INPUT
-#define YY_INPUT(buf, result, max_size) \
- { result = cmDependsFortranParser_Input(yyextra, buf, max_size); }
-
-/* Include the set of tokens from the parser. */
-#include "cmDependsFortranParserTokens.h"
-
-/*--------------------------------------------------------------------------*/
-
-
-#line 678 "cmDependsFortranLexer.cxx"
-
-#define INITIAL 0
-#define free_fmt 1
-#define fixed_fmt 2
-#define str_sq 3
-#define str_dq 4
-
-#ifndef YY_NO_UNISTD_H
-/* Special case for "unistd.h", since it is non-ANSI. We include it way
- * down here because we want the user's section 1 to have been scanned first.
- * The user has a chance to override it with an option.
- */
-#include <unistd.h>
-#endif
-
-#ifndef YY_EXTRA_TYPE
-#define YY_EXTRA_TYPE void *
-#endif
-
-/* Holds the entire state of the reentrant scanner. */
-struct yyguts_t
- {
-
- /* User-defined. Not touched by flex. */
- YY_EXTRA_TYPE yyextra_r;
-
- /* The rest are the same as the globals declared in the non-reentrant scanner. */
- FILE *yyin_r, *yyout_r;
- size_t yy_buffer_stack_top; /**< index of top of stack. */
- size_t yy_buffer_stack_max; /**< capacity of stack. */
- YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
- char yy_hold_char;
- int yy_n_chars;
- int yyleng_r;
- char *yy_c_buf_p;
- int yy_init;
- int yy_start;
- int yy_did_buffer_switch_on_eof;
- int yy_start_stack_ptr;
- int yy_start_stack_depth;
- int *yy_start_stack;
- yy_state_type yy_last_accepting_state;
- char* yy_last_accepting_cpos;
-
- int yylineno_r;
- int yy_flex_debug_r;
-
- char *yytext_r;
- int yy_more_flag;
- int yy_more_len;
-
- }; /* end struct yyguts_t */
-
-static int yy_init_globals (yyscan_t yyscanner );
-
-int cmDependsFortran_yylex_init (yyscan_t* scanner);
-
-int cmDependsFortran_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
-
-/* Accessor methods to globals.
- These are made visible to non-reentrant scanners for convenience. */
-
-int cmDependsFortran_yylex_destroy (yyscan_t yyscanner );
-
-int cmDependsFortran_yyget_debug (yyscan_t yyscanner );
-
-void cmDependsFortran_yyset_debug (int debug_flag ,yyscan_t yyscanner );
-
-YY_EXTRA_TYPE cmDependsFortran_yyget_extra (yyscan_t yyscanner );
-
-void cmDependsFortran_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
-
-FILE *cmDependsFortran_yyget_in (yyscan_t yyscanner );
-
-void cmDependsFortran_yyset_in (FILE * in_str ,yyscan_t yyscanner );
-
-FILE *cmDependsFortran_yyget_out (yyscan_t yyscanner );
-
-void cmDependsFortran_yyset_out (FILE * out_str ,yyscan_t yyscanner );
-
-int cmDependsFortran_yyget_leng (yyscan_t yyscanner );
-
-char *cmDependsFortran_yyget_text (yyscan_t yyscanner );
-
-int cmDependsFortran_yyget_lineno (yyscan_t yyscanner );
-
-void cmDependsFortran_yyset_lineno (int line_number ,yyscan_t yyscanner );
-
-/* Macros after this point can all be overridden by user definitions in
- * section 1.
- */
-
-#ifndef YY_SKIP_YYWRAP
-#ifdef __cplusplus
-extern "C" int cmDependsFortran_yywrap (yyscan_t yyscanner );
-#else
-extern int cmDependsFortran_yywrap (yyscan_t yyscanner );
-#endif
-#endif
-
- static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner);
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
-#endif
-
-#ifndef YY_NO_INPUT
-
-#ifdef __cplusplus
-static int yyinput (yyscan_t yyscanner );
-#else
-static int input (yyscan_t yyscanner );
-#endif
-
-#endif
-
-/* Amount of stuff to slurp up with each read. */
-#ifndef YY_READ_BUF_SIZE
-#ifdef __ia64__
-/* On IA-64, the buffer size is 16k, not 8k */
-#define YY_READ_BUF_SIZE 16384
-#else
-#define YY_READ_BUF_SIZE 8192
-#endif /* __ia64__ */
-#endif
-
-/* Copy whatever the last rule matched to the standard output. */
-#ifndef ECHO
-/* This used to be an fputs(), but since the string might contain NUL's,
- * we now use fwrite().
- */
-#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
-#endif
-
-/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
- * is returned in "result".
- */
-#ifndef YY_INPUT
-#define YY_INPUT(buf,result,max_size) \
- if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
- { \
- int c = '*'; \
- size_t n; \
- for ( n = 0; n < max_size && \
- (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
- buf[n] = (char) c; \
- if ( c == '\n' ) \
- buf[n++] = (char) c; \
- if ( c == EOF && ferror( yyin ) ) \
- YY_FATAL_ERROR( "input in flex scanner failed" ); \
- result = n; \
- } \
- else \
- { \
- errno=0; \
- while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
- { \
- if( errno != EINTR) \
- { \
- YY_FATAL_ERROR( "input in flex scanner failed" ); \
- break; \
- } \
- errno=0; \
- clearerr(yyin); \
- } \
- }\
-\
-
-#endif
-
-/* No semi-colon after return; correct usage is to write "yyterminate();" -
- * we don't want an extra ';' after the "return" because that will cause
- * some compilers to complain about unreachable statements.
- */
-#ifndef yyterminate
-#define yyterminate() return YY_NULL
-#endif
-
-/* Number of entries by which start-condition stack grows. */
-#ifndef YY_START_STACK_INCR
-#define YY_START_STACK_INCR 25
-#endif
-
-/* Report a fatal error. */
-#ifndef YY_FATAL_ERROR
-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)
-#endif
-
-/* end tables serialization structures and prototypes */
-
-/* Default declaration of generated scanner - a define so the user can
- * easily add parameters.
- */
-#ifndef YY_DECL
-#define YY_DECL_IS_OURS 1
-
-extern int cmDependsFortran_yylex (yyscan_t yyscanner);
-
-#define YY_DECL int cmDependsFortran_yylex (yyscan_t yyscanner)
-#endif /* !YY_DECL */
-
-/* Code executed at the beginning of each rule, after yytext and yyleng
- * have been set up.
- */
-#ifndef YY_USER_ACTION
-#define YY_USER_ACTION
-#endif
-
-/* Code executed at the end of each rule. */
-#ifndef YY_BREAK
-#define YY_BREAK break;
-#endif
-
-#define YY_RULE_SETUP \
- if ( yyleng > 0 ) \
- YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \
- (yytext[yyleng - 1] == '\n'); \
- YY_USER_ACTION
-
-/** The main scanner function which does all the work.
- */
-YY_DECL
-{
- yy_state_type yy_current_state;
- char *yy_cp, *yy_bp;
- int yy_act;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-#line 71 "cmDependsFortranLexer.in.l"
-
-
-#line 914 "cmDependsFortranLexer.cxx"
-
- if ( !yyg->yy_init )
- {
- yyg->yy_init = 1;
-
-#ifdef YY_USER_INIT
- YY_USER_INIT;
-#endif
-
- if ( ! yyg->yy_start )
- yyg->yy_start = 1; /* first start state */
-
- if ( ! yyin )
- yyin = stdin;
-
- if ( ! yyout )
- yyout = stdout;
-
- if ( ! YY_CURRENT_BUFFER ) {
- cmDependsFortran_yyensure_buffer_stack (yyscanner);
- YY_CURRENT_BUFFER_LVALUE =
- cmDependsFortran_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
- }
-
- cmDependsFortran_yy_load_buffer_state(yyscanner );
- }
-
- for(;;) /* loops until end-of-file is reached */
- {
- yy_cp = yyg->yy_c_buf_p;
-
- /* Support of yytext. */
- *yy_cp = yyg->yy_hold_char;
-
- /* yy_bp points to the position in yy_ch_buf of the start of
- * the current run.
- */
- yy_bp = yy_cp;
-
- yy_current_state = yyg->yy_start;
- yy_current_state += YY_AT_BOL();
-yy_match:
- do
- {
- YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
- if ( yy_accept[yy_current_state] )
- {
- yyg->yy_last_accepting_state = yy_current_state;
- yyg->yy_last_accepting_cpos = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 165 )
- yy_c = yy_meta[(unsigned int) yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- ++yy_cp;
- }
- while ( yy_base[yy_current_state] != 505 );
-
-yy_find_action:
- yy_act = yy_accept[yy_current_state];
- if ( yy_act == 0 )
- { /* have to back up */
- yy_cp = yyg->yy_last_accepting_cpos;
- yy_current_state = yyg->yy_last_accepting_state;
- yy_act = yy_accept[yy_current_state];
- }
-
- YY_DO_BEFORE_ACTION;
-
-do_action: /* This label is used only to access EOF actions. */
-
- switch ( yy_act )
- { /* beginning of action switch */
- case 0: /* must back up */
- /* undo the effects of YY_DO_BEFORE_ACTION */
- *yy_cp = yyg->yy_hold_char;
- yy_cp = yyg->yy_last_accepting_cpos;
- yy_current_state = yyg->yy_last_accepting_state;
- goto yy_find_action;
-
-case 1:
-YY_RULE_SETUP
-#line 73 "cmDependsFortranLexer.in.l"
-{
- cmDependsFortranParser_StringStart(yyextra);
- cmDependsFortranParser_SetOldStartcond(yyextra, YY_START);
- BEGIN(str_dq);
-}
- YY_BREAK
-case 2:
-YY_RULE_SETUP
-#line 79 "cmDependsFortranLexer.in.l"
-{
- cmDependsFortranParser_StringStart(yyextra);
- cmDependsFortranParser_SetOldStartcond(yyextra, YY_START);
- BEGIN(str_sq);
-}
- YY_BREAK
-case 3:
-#line 86 "cmDependsFortranLexer.in.l"
-case 4:
-YY_RULE_SETUP
-#line 86 "cmDependsFortranLexer.in.l"
-{
- BEGIN(cmDependsFortranParser_GetOldStartcond(yyextra) );
- yylvalp->string = strdup(cmDependsFortranParser_StringEnd(yyextra));
- return STRING;
-}
-case 5:
-/* rule 5 can match eol */
-#line 93 "cmDependsFortranLexer.in.l"
-case 6:
-/* rule 6 can match eol */
-YY_RULE_SETUP
-#line 93 "cmDependsFortranLexer.in.l"
-/* Ignore (continued strings, free fmt) */
- YY_BREAK
-case 7:
-/* rule 7 can match eol */
-YY_RULE_SETUP
-#line 95 "cmDependsFortranLexer.in.l"
-{
- if (cmDependsFortranParser_GetOldStartcond(yyextra) == fixed_fmt)
- ; /* Ignore (cont. strings, fixed fmt) */
- else
- {
- unput(yytext[strlen(yytext)-1]);
- }
-}
- YY_BREAK
-case 8:
-/* rule 8 can match eol */
-YY_RULE_SETUP
-#line 105 "cmDependsFortranLexer.in.l"
-{
- unput ('\n');
- BEGIN(INITIAL);
- return UNTERMINATED_STRING;
-}
-case 9:
-YY_RULE_SETUP
-#line 111 "cmDependsFortranLexer.in.l"
-{
- cmDependsFortranParser_StringAppend(yyextra, yytext[0]);
-}
- YY_BREAK
-case 10:
-/* rule 10 can match eol */
-YY_RULE_SETUP
-#line 115 "cmDependsFortranLexer.in.l"
-{ return EOSTMT; } /* Treat comments like */
-case 11:
-/* rule 11 can match eol */
-YY_RULE_SETUP
-#line 116 "cmDependsFortranLexer.in.l"
-{ return EOSTMT; } /* empty lines */
-case 12:
-/* rule 12 can match eol */
-YY_RULE_SETUP
-#line 118 "cmDependsFortranLexer.in.l"
-{
- yytext[yyleng-1] = 0;
- yylvalp->string = strdup(strchr(yytext, '<')+1);
- return CPP_INCLUDE_ANGLE;
-}
-case 13:
-YY_RULE_SETUP
-#line 123 "cmDependsFortranLexer.in.l"
-{ return CPP_INCLUDE; }
-case 14:
-YY_RULE_SETUP
-#line 124 "cmDependsFortranLexer.in.l"
-{ return F90PPR_INCLUDE; }
-case 15:
-YY_RULE_SETUP
-#line 125 "cmDependsFortranLexer.in.l"
-{ return COCO_INCLUDE; }
-case 16:
-YY_RULE_SETUP
-#line 127 "cmDependsFortranLexer.in.l"
-{ return CPP_DEFINE; }
-case 17:
-YY_RULE_SETUP
-#line 128 "cmDependsFortranLexer.in.l"
-{ return F90PPR_DEFINE; }
-case 18:
-YY_RULE_SETUP
-#line 130 "cmDependsFortranLexer.in.l"
-{ return CPP_UNDEF; }
-case 19:
-YY_RULE_SETUP
-#line 131 "cmDependsFortranLexer.in.l"
-{ return F90PPR_UNDEF; }
-case 20:
-YY_RULE_SETUP
-#line 133 "cmDependsFortranLexer.in.l"
-{ return CPP_IFDEF; }
-case 21:
-YY_RULE_SETUP
-#line 134 "cmDependsFortranLexer.in.l"
-{ return CPP_IFNDEF; }
-case 22:
-YY_RULE_SETUP
-#line 135 "cmDependsFortranLexer.in.l"
-{ return CPP_IF; }
-case 23:
-YY_RULE_SETUP
-#line 136 "cmDependsFortranLexer.in.l"
-{ return CPP_ELIF; }
-case 24:
-YY_RULE_SETUP
-#line 137 "cmDependsFortranLexer.in.l"
-{ return CPP_ELSE; }
-case 25:
-YY_RULE_SETUP
-#line 138 "cmDependsFortranLexer.in.l"
-{ return CPP_ENDIF; }
-case 26:
-YY_RULE_SETUP
-#line 140 "cmDependsFortranLexer.in.l"
-{ return F90PPR_IFDEF; }
-case 27:
-YY_RULE_SETUP
-#line 141 "cmDependsFortranLexer.in.l"
-{ return F90PPR_IFNDEF; }
-case 28:
-YY_RULE_SETUP
-#line 142 "cmDependsFortranLexer.in.l"
-{ return F90PPR_IF; }
-case 29:
-YY_RULE_SETUP
-#line 143 "cmDependsFortranLexer.in.l"
-{ return F90PPR_ELIF; }
-case 30:
-YY_RULE_SETUP
-#line 144 "cmDependsFortranLexer.in.l"
-{ return F90PPR_ELSE; }
-case 31:
-YY_RULE_SETUP
-#line 145 "cmDependsFortranLexer.in.l"
-{ return F90PPR_ENDIF; }
-/* Line continuations, possible involving comments. */
-case 32:
-/* rule 32 can match eol */
-YY_RULE_SETUP
-#line 148 "cmDependsFortranLexer.in.l"
-
- YY_BREAK
-case 33:
-/* rule 33 can match eol */
-YY_RULE_SETUP
-#line 149 "cmDependsFortranLexer.in.l"
-
- YY_BREAK
-case 34:
-YY_RULE_SETUP
-#line 151 "cmDependsFortranLexer.in.l"
-{ return COMMA; }
-case 35:
-YY_RULE_SETUP
-#line 153 "cmDependsFortranLexer.in.l"
-{ return DCOLON; }
-case 36:
-/* rule 36 can match eol */
-YY_RULE_SETUP
-#line 155 "cmDependsFortranLexer.in.l"
-{ return GARBAGE; }
-case 37:
-YY_RULE_SETUP
-#line 157 "cmDependsFortranLexer.in.l"
-{ return ASSIGNMENT_OP; }
-case 38:
-YY_RULE_SETUP
-#line 159 "cmDependsFortranLexer.in.l"
-{
- yylvalp->string = strdup(yytext);
- return WORD;
-}
-case 39:
-YY_RULE_SETUP
-#line 164 "cmDependsFortranLexer.in.l"
-{ return GARBAGE; }
-case 40:
-/* rule 40 can match eol */
-YY_RULE_SETUP
-#line 166 "cmDependsFortranLexer.in.l"
-{ return EOSTMT; }
-case 41:
-YY_RULE_SETUP
-#line 169 "cmDependsFortranLexer.in.l"
-/* Ignore */
- YY_BREAK
-case 42:
-/* rule 42 can match eol */
-YY_RULE_SETUP
-#line 170 "cmDependsFortranLexer.in.l"
-/* Ignore line-endings preceeded by \ */
- YY_BREAK
-case 43:
-YY_RULE_SETUP
-#line 172 "cmDependsFortranLexer.in.l"
-{ return *yytext; }
-case YY_STATE_EOF(INITIAL):
-case YY_STATE_EOF(free_fmt):
-case YY_STATE_EOF(fixed_fmt):
-case YY_STATE_EOF(str_sq):
-case YY_STATE_EOF(str_dq):
-#line 174 "cmDependsFortranLexer.in.l"
-{
- if(!cmDependsFortranParser_FilePop(yyextra) )
- {
- return YY_NULL;
- }
-}
- YY_BREAK
-case 44:
-YY_RULE_SETUP
-#line 181 "cmDependsFortranLexer.in.l"
-ECHO;
- YY_BREAK
-#line 1270 "cmDependsFortranLexer.cxx"
-
- case YY_END_OF_BUFFER:
- {
- /* Amount of text matched not including the EOB char. */
- int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1;
-
- /* Undo the effects of YY_DO_BEFORE_ACTION. */
- *yy_cp = yyg->yy_hold_char;
- YY_RESTORE_YY_MORE_OFFSET
-
- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
- {
- /* We're scanning a new file or input source. It's
- * possible that this happened because the user
- * just pointed yyin at a new source and called
- * cmDependsFortran_yylex(). If so, then we have to assure
- * consistency between YY_CURRENT_BUFFER and our
- * globals. Here is the right place to do so, because
- * this is the first action (other than possibly a
- * back-up) that will match for the new input source.
- */
- yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
- YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
- }
-
- /* Note that here we test for yy_c_buf_p "<=" to the position
- * of the first EOB in the buffer, since yy_c_buf_p will
- * already have been incremented past the NUL character
- * (since all states make transitions on EOB to the
- * end-of-buffer state). Contrast this with the test
- * in input().
- */
- if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
- { /* This was really a NUL. */
- yy_state_type yy_next_state;
-
- yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
-
- yy_current_state = yy_get_previous_state( yyscanner );
-
- /* Okay, we're now positioned to make the NUL
- * transition. We couldn't have
- * yy_get_previous_state() go ahead and do it
- * for us because it doesn't know how to deal
- * with the possibility of jamming (and we don't
- * want to build jamming into it because then it
- * will run more slowly).
- */
-
- yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner);
-
- yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
-
- if ( yy_next_state )
- {
- /* Consume the NUL. */
- yy_cp = ++yyg->yy_c_buf_p;
- yy_current_state = yy_next_state;
- goto yy_match;
- }
-
- else
- {
- yy_cp = yyg->yy_c_buf_p;
- goto yy_find_action;
- }
- }
-
- else switch ( yy_get_next_buffer( yyscanner ) )
- {
- case EOB_ACT_END_OF_FILE:
- {
- yyg->yy_did_buffer_switch_on_eof = 0;
-
- if ( cmDependsFortran_yywrap(yyscanner ) )
- {
- /* Note: because we've taken care in
- * yy_get_next_buffer() to have set up
- * yytext, we can now set up
- * yy_c_buf_p so that if some total
- * hoser (like flex itself) wants to
- * call the scanner after we return the
- * YY_NULL, it'll still work - another
- * YY_NULL will get returned.
- */
- yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;
-
- yy_act = YY_STATE_EOF(YY_START);
- goto do_action;
- }
-
- else
- {
- if ( ! yyg->yy_did_buffer_switch_on_eof )
- YY_NEW_FILE;
- }
- break;
- }
-
- case EOB_ACT_CONTINUE_SCAN:
- yyg->yy_c_buf_p =
- yyg->yytext_ptr + yy_amount_of_matched_text;
-
- yy_current_state = yy_get_previous_state( yyscanner );
-
- yy_cp = yyg->yy_c_buf_p;
- yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
- goto yy_match;
-
- case EOB_ACT_LAST_MATCH:
- yyg->yy_c_buf_p =
- &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];
-
- yy_current_state = yy_get_previous_state( yyscanner );
-
- yy_cp = yyg->yy_c_buf_p;
- yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
- goto yy_find_action;
- }
- break;
- }
-
- default:
- YY_FATAL_ERROR(
- "fatal flex scanner internal error--no action found" );
- } /* end of action switch */
- } /* end of scanning one token */
-} /* end of cmDependsFortran_yylex */
-
-/* yy_get_next_buffer - try to read in a new buffer
- *
- * Returns a code representing an action:
- * EOB_ACT_LAST_MATCH -
- * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
- * EOB_ACT_END_OF_FILE - end of file
- */
-static int yy_get_next_buffer (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
- char *source = yyg->yytext_ptr;
- int number_to_move, i;
- int ret_val;
-
- if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
- YY_FATAL_ERROR(
- "fatal flex scanner internal error--end of buffer missed" );
-
- if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
- { /* Don't try to fill the buffer, so this is an EOF. */
- if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 )
- {
- /* We matched a single character, the EOB, so
- * treat this as a final EOF.
- */
- return EOB_ACT_END_OF_FILE;
- }
-
- else
- {
- /* We matched some text prior to the EOB, first
- * process it.
- */
- return EOB_ACT_LAST_MATCH;
- }
- }
-
- /* Try to read more data. */
-
- /* First move last chars to start of buffer. */
- number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
-
- for ( i = 0; i < number_to_move; ++i )
- *(dest++) = *(source++);
-
- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
- /* don't do the read, it's not guaranteed to return an EOF,
- * just force an EOF
- */
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;
-
- else
- {
- int num_to_read =
- YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
-
- while ( num_to_read <= 0 )
- { /* Not enough room in the buffer - grow it. */
-
- /* just a shorter name for the current buffer */
- YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
-
- int yy_c_buf_p_offset =
- (int) (yyg->yy_c_buf_p - b->yy_ch_buf);
-
- if ( b->yy_is_our_buffer )
- {
- int new_size = b->yy_buf_size * 2;
-
- if ( new_size <= 0 )
- b->yy_buf_size += b->yy_buf_size / 8;
- else
- b->yy_buf_size *= 2;
-
- b->yy_ch_buf = (char *)
- /* Include room in for 2 EOB chars. */
- cmDependsFortran_yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
- }
- else
- /* Can't grow it, we don't own it. */
- b->yy_ch_buf = 0;
-
- if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR(
- "fatal error - scanner input buffer overflow" );
-
- yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
-
- num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
- number_to_move - 1;
-
- }
-
- if ( num_to_read > YY_READ_BUF_SIZE )
- num_to_read = YY_READ_BUF_SIZE;
-
- /* Read in more data. */
- YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
- yyg->yy_n_chars, (size_t) num_to_read );
-
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
- }
-
- if ( yyg->yy_n_chars == 0 )
- {
- if ( number_to_move == YY_MORE_ADJ )
- {
- ret_val = EOB_ACT_END_OF_FILE;
- cmDependsFortran_yyrestart(yyin ,yyscanner);
- }
-
- else
- {
- ret_val = EOB_ACT_LAST_MATCH;
- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
- YY_BUFFER_EOF_PENDING;
- }
- }
-
- else
- ret_val = EOB_ACT_CONTINUE_SCAN;
-
- if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
- /* Extend the array by 50%, plus the number we really need. */
- yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) cmDependsFortran_yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
- if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
- YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
- }
-
- yyg->yy_n_chars += number_to_move;
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
-
- yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
-
- return ret_val;
-}
-
-/* yy_get_previous_state - get the state just before the EOB char was reached */
-
- static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
-{
- yy_state_type yy_current_state;
- char *yy_cp;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- yy_current_state = yyg->yy_start;
- yy_current_state += YY_AT_BOL();
-
- for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
- {
- YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
- if ( yy_accept[yy_current_state] )
- {
- yyg->yy_last_accepting_state = yy_current_state;
- yyg->yy_last_accepting_cpos = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 165 )
- yy_c = yy_meta[(unsigned int) yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- }
-
- return yy_current_state;
-}
-
-/* yy_try_NUL_trans - try to make a transition on the NUL character
- *
- * synopsis
- * next_state = yy_try_NUL_trans( current_state );
- */
- static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner)
-{
- int yy_is_jam;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
- char *yy_cp = yyg->yy_c_buf_p;
-
- YY_CHAR yy_c = 1;
- if ( yy_accept[yy_current_state] )
- {
- yyg->yy_last_accepting_state = yy_current_state;
- yyg->yy_last_accepting_cpos = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 165 )
- yy_c = yy_meta[(unsigned int) yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- yy_is_jam = (yy_current_state == 164);
-
- return yy_is_jam ? 0 : yy_current_state;
-}
-
- static void yyunput (int c, char * yy_bp , yyscan_t yyscanner)
-{
- char *yy_cp;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- yy_cp = yyg->yy_c_buf_p;
-
- /* undo effects of setting up yytext */
- *yy_cp = yyg->yy_hold_char;
-
- if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
- { /* need to shift things up to make room */
- /* +2 for EOB chars. */
- int number_to_move = yyg->yy_n_chars + 2;
- char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
- YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
- char *source =
- &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
-
- while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
- *--dest = *--source;
-
- yy_cp += (int) (dest - source);
- yy_bp += (int) (dest - source);
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
- yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
-
- if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
- YY_FATAL_ERROR( "flex scanner push-back overflow" );
- }
-
- *--yy_cp = (char) c;
-
- yyg->yytext_ptr = yy_bp;
- yyg->yy_hold_char = *yy_cp;
- yyg->yy_c_buf_p = yy_cp;
-}
-
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
- static int yyinput (yyscan_t yyscanner)
-#else
- static int input (yyscan_t yyscanner)
-#endif
-
-{
- int c;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- *yyg->yy_c_buf_p = yyg->yy_hold_char;
-
- if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
- {
- /* yy_c_buf_p now points to the character we want to return.
- * If this occurs *before* the EOB characters, then it's a
- * valid NUL; if not, then we've hit the end of the buffer.
- */
- if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
- /* This was really a NUL. */
- *yyg->yy_c_buf_p = '\0';
-
- else
- { /* need more input */
- int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
- ++yyg->yy_c_buf_p;
-
- switch ( yy_get_next_buffer( yyscanner ) )
- {
- case EOB_ACT_LAST_MATCH:
- /* This happens because yy_g_n_b()
- * sees that we've accumulated a
- * token and flags that we need to
- * try matching the token before
- * proceeding. But for input(),
- * there's no matching to consider.
- * So convert the EOB_ACT_LAST_MATCH
- * to EOB_ACT_END_OF_FILE.
- */
-
- /* Reset buffer status. */
- cmDependsFortran_yyrestart(yyin ,yyscanner);
-
- /*FALLTHROUGH*/
-
- case EOB_ACT_END_OF_FILE:
- {
- if ( cmDependsFortran_yywrap(yyscanner ) )
- return EOF;
-
- if ( ! yyg->yy_did_buffer_switch_on_eof )
- YY_NEW_FILE;
-#ifdef __cplusplus
- return yyinput(yyscanner);
-#else
- return input(yyscanner);
-#endif
- }
-
- case EOB_ACT_CONTINUE_SCAN:
- yyg->yy_c_buf_p = yyg->yytext_ptr + offset;
- break;
- }
- }
- }
-
- c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */
- *yyg->yy_c_buf_p = '\0'; /* preserve yytext */
- yyg->yy_hold_char = *++yyg->yy_c_buf_p;
-
- YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n');
-
- return c;
-}
-#endif /* ifndef YY_NO_INPUT */
-
-/** Immediately switch to a different input stream.
- * @param input_file A readable stream.
- * @param yyscanner The scanner object.
- * @note This function does not reset the start condition to @c INITIAL .
- */
- void cmDependsFortran_yyrestart (FILE * input_file , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- if ( ! YY_CURRENT_BUFFER ){
- cmDependsFortran_yyensure_buffer_stack (yyscanner);
- YY_CURRENT_BUFFER_LVALUE =
- cmDependsFortran_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
- }
-
- cmDependsFortran_yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
- cmDependsFortran_yy_load_buffer_state(yyscanner );
-}
-
-/** Switch to a different input buffer.
- * @param new_buffer The new input buffer.
- * @param yyscanner The scanner object.
- */
- void cmDependsFortran_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- /* TODO. We should be able to replace this entire function body
- * with
- * cmDependsFortran_yypop_buffer_state();
- * cmDependsFortran_yypush_buffer_state(new_buffer);
- */
- cmDependsFortran_yyensure_buffer_stack (yyscanner);
- if ( YY_CURRENT_BUFFER == new_buffer )
- return;
-
- if ( YY_CURRENT_BUFFER )
- {
- /* Flush out information for old buffer. */
- *yyg->yy_c_buf_p = yyg->yy_hold_char;
- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
- }
-
- YY_CURRENT_BUFFER_LVALUE = new_buffer;
- cmDependsFortran_yy_load_buffer_state(yyscanner );
-
- /* We don't actually know whether we did this switch during
- * EOF (cmDependsFortran_yywrap()) processing, but the only time this flag
- * is looked at is after cmDependsFortran_yywrap() is called, so it's safe
- * to go ahead and always set it.
- */
- yyg->yy_did_buffer_switch_on_eof = 1;
-}
-
-static void cmDependsFortran_yy_load_buffer_state (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
- yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
- yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
- yyg->yy_hold_char = *yyg->yy_c_buf_p;
-}
-
-/** Allocate and initialize an input buffer state.
- * @param file A readable stream.
- * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
- * @param yyscanner The scanner object.
- * @return the allocated buffer state.
- */
- YY_BUFFER_STATE cmDependsFortran_yy_create_buffer (FILE * file, int size , yyscan_t yyscanner)
-{
- YY_BUFFER_STATE b;
-
- b = (YY_BUFFER_STATE) cmDependsFortran_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
- if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in cmDependsFortran_yy_create_buffer()" );
-
- b->yy_buf_size = size;
-
- /* yy_ch_buf has to be 2 characters longer than the size given because
- * we need to put in 2 end-of-buffer characters.
- */
- b->yy_ch_buf = (char *) cmDependsFortran_yyalloc(b->yy_buf_size + 2 ,yyscanner );
- if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR( "out of dynamic memory in cmDependsFortran_yy_create_buffer()" );
-
- b->yy_is_our_buffer = 1;
-
- cmDependsFortran_yy_init_buffer(b,file ,yyscanner);
-
- return b;
-}
-
-/** Destroy the buffer.
- * @param b a buffer created with cmDependsFortran_yy_create_buffer()
- * @param yyscanner The scanner object.
- */
- void cmDependsFortran_yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- if ( ! b )
- return;
-
- if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
- YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
-
- if ( b->yy_is_our_buffer )
- cmDependsFortran_yyfree((void *) b->yy_ch_buf ,yyscanner );
-
- cmDependsFortran_yyfree((void *) b ,yyscanner );
-}
-
-#ifndef __cplusplus
-extern int isatty (int );
-#endif /* __cplusplus */
-
-/* Initializes or reinitializes a buffer.
- * This function is sometimes called more than once on the same buffer,
- * such as during a cmDependsFortran_yyrestart() or at EOF.
- */
- static void cmDependsFortran_yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
-
-{
- int oerrno = errno;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- cmDependsFortran_yy_flush_buffer(b ,yyscanner);
-
- b->yy_input_file = file;
- b->yy_fill_buffer = 1;
-
- /* If b is the current buffer, then cmDependsFortran_yy_init_buffer was _probably_
- * called from cmDependsFortran_yyrestart() or through yy_get_next_buffer.
- * In that case, we don't want to reset the lineno or column.
- */
- if (b != YY_CURRENT_BUFFER){
- b->yy_bs_lineno = 1;
- b->yy_bs_column = 0;
- }
-
- b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
-
- errno = oerrno;
-}
-
-/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
- * @param yyscanner The scanner object.
- */
- void cmDependsFortran_yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- if ( ! b )
- return;
-
- b->yy_n_chars = 0;
-
- /* We always need two end-of-buffer characters. The first causes
- * a transition to the end-of-buffer state. The second causes
- * a jam in that state.
- */
- b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
- b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
-
- b->yy_buf_pos = &b->yy_ch_buf[0];
-
- b->yy_at_bol = 1;
- b->yy_buffer_status = YY_BUFFER_NEW;
-
- if ( b == YY_CURRENT_BUFFER )
- cmDependsFortran_yy_load_buffer_state(yyscanner );
-}
-
-/** Pushes the new state onto the stack. The new state becomes
- * the current state. This function will allocate the stack
- * if necessary.
- * @param new_buffer The new state.
- * @param yyscanner The scanner object.
- */
-void cmDependsFortran_yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- if (new_buffer == NULL)
- return;
-
- cmDependsFortran_yyensure_buffer_stack(yyscanner);
-
- /* This block is copied from cmDependsFortran_yy_switch_to_buffer. */
- if ( YY_CURRENT_BUFFER )
- {
- /* Flush out information for old buffer. */
- *yyg->yy_c_buf_p = yyg->yy_hold_char;
- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
- }
-
- /* Only push if top exists. Otherwise, replace top. */
- if (YY_CURRENT_BUFFER)
- yyg->yy_buffer_stack_top++;
- YY_CURRENT_BUFFER_LVALUE = new_buffer;
-
- /* copied from cmDependsFortran_yy_switch_to_buffer. */
- cmDependsFortran_yy_load_buffer_state(yyscanner );
- yyg->yy_did_buffer_switch_on_eof = 1;
-}
-
-/** Removes and deletes the top of the stack, if present.
- * The next element becomes the new top.
- * @param yyscanner The scanner object.
- */
-void cmDependsFortran_yypop_buffer_state (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- if (!YY_CURRENT_BUFFER)
- return;
-
- cmDependsFortran_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
- YY_CURRENT_BUFFER_LVALUE = NULL;
- if (yyg->yy_buffer_stack_top > 0)
- --yyg->yy_buffer_stack_top;
-
- if (YY_CURRENT_BUFFER) {
- cmDependsFortran_yy_load_buffer_state(yyscanner );
- yyg->yy_did_buffer_switch_on_eof = 1;
- }
-}
-
-/* Allocates the stack if it does not exist.
- * Guarantees space for at least one push.
- */
-static void cmDependsFortran_yyensure_buffer_stack (yyscan_t yyscanner)
-{
- int num_to_alloc;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- if (!yyg->yy_buffer_stack) {
-
- /* First allocation is just for 2 elements, since we don't know if this
- * scanner will even need a stack. We use 2 instead of 1 to avoid an
- * immediate realloc on the next call.
- */
- num_to_alloc = 1;
- yyg->yy_buffer_stack = (struct yy_buffer_state**)cmDependsFortran_yyalloc
- (num_to_alloc * sizeof(struct yy_buffer_state*)
- , yyscanner);
- if ( ! yyg->yy_buffer_stack )
- YY_FATAL_ERROR( "out of dynamic memory in cmDependsFortran_yyensure_buffer_stack()" );
-
- memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-
- yyg->yy_buffer_stack_max = num_to_alloc;
- yyg->yy_buffer_stack_top = 0;
- return;
- }
-
- if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){
-
- /* Increase the buffer to prepare for a possible push. */
- int grow_size = 8 /* arbitrary grow size */;
-
- num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
- yyg->yy_buffer_stack = (struct yy_buffer_state**)cmDependsFortran_yyrealloc
- (yyg->yy_buffer_stack,
- num_to_alloc * sizeof(struct yy_buffer_state*)
- , yyscanner);
- if ( ! yyg->yy_buffer_stack )
- YY_FATAL_ERROR( "out of dynamic memory in cmDependsFortran_yyensure_buffer_stack()" );
-
- /* zero only the new slots.*/
- memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
- yyg->yy_buffer_stack_max = num_to_alloc;
- }
-}
-
-/** Setup the input buffer state to scan directly from a user-specified character buffer.
- * @param base the character buffer
- * @param size the size in bytes of the character buffer
- * @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE cmDependsFortran_yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
-{
- YY_BUFFER_STATE b;
-
- if ( size < 2 ||
- base[size-2] != YY_END_OF_BUFFER_CHAR ||
- base[size-1] != YY_END_OF_BUFFER_CHAR )
- /* They forgot to leave room for the EOB's. */
- return 0;
-
- b = (YY_BUFFER_STATE) cmDependsFortran_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
- if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in cmDependsFortran_yy_scan_buffer()" );
-
- b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
- b->yy_buf_pos = b->yy_ch_buf = base;
- b->yy_is_our_buffer = 0;
- b->yy_input_file = 0;
- b->yy_n_chars = b->yy_buf_size;
- b->yy_is_interactive = 0;
- b->yy_at_bol = 1;
- b->yy_fill_buffer = 0;
- b->yy_buffer_status = YY_BUFFER_NEW;
-
- cmDependsFortran_yy_switch_to_buffer(b ,yyscanner );
-
- return b;
-}
-
-/** Setup the input buffer state to scan a string. The next call to cmDependsFortran_yylex() will
- * scan from a @e copy of @a str.
- * @param yystr a NUL-terminated string to scan
- * @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
- * @note If you want to scan bytes that may contain NUL values, then use
- * cmDependsFortran_yy_scan_bytes() instead.
- */
-YY_BUFFER_STATE cmDependsFortran_yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
-{
-
- return cmDependsFortran_yy_scan_bytes(yystr,strlen(yystr) ,yyscanner);
-}
-
-/** Setup the input buffer state to scan the given bytes. The next call to cmDependsFortran_yylex() will
- * scan from a @e copy of @a bytes.
- * @param yybytes the byte buffer to scan
- * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
- * @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE cmDependsFortran_yy_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner)
-{
- YY_BUFFER_STATE b;
- char *buf;
- yy_size_t n;
- int i;
-
- /* Get memory for full buffer, including space for trailing EOB's. */
- n = _yybytes_len + 2;
- buf = (char *) cmDependsFortran_yyalloc(n ,yyscanner );
- if ( ! buf )
- YY_FATAL_ERROR( "out of dynamic memory in cmDependsFortran_yy_scan_bytes()" );
-
- for ( i = 0; i < _yybytes_len; ++i )
- buf[i] = yybytes[i];
-
- buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
-
- b = cmDependsFortran_yy_scan_buffer(buf,n ,yyscanner);
- if ( ! b )
- YY_FATAL_ERROR( "bad buffer in cmDependsFortran_yy_scan_bytes()" );
-
- /* It's okay to grow etc. this buffer, and we should throw it
- * away when we're done.
- */
- b->yy_is_our_buffer = 1;
-
- return b;
-}
-
-#ifndef YY_EXIT_FAILURE
-#define YY_EXIT_FAILURE 2
-#endif
-
-static void yy_fatal_error (yyconst char* msg , yyscan_t)
-{
- (void) fprintf( stderr, "%s\n", msg );
- exit( YY_EXIT_FAILURE );
-}
-
-/* Redefine yyless() so it works in section 3 code. */
-
-#undef yyless
-#define yyless(n) \
- do \
- { \
- /* Undo effects of setting up yytext. */ \
- int yyless_macro_arg = (n); \
- YY_LESS_LINENO(yyless_macro_arg);\
- yytext[yyleng] = yyg->yy_hold_char; \
- yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
- yyg->yy_hold_char = *yyg->yy_c_buf_p; \
- *yyg->yy_c_buf_p = '\0'; \
- yyleng = yyless_macro_arg; \
- } \
- while ( 0 )
-
-/* Accessor methods (get/set functions) to struct members. */
-
-/** Get the user-defined data for this scanner.
- * @param yyscanner The scanner object.
- */
-YY_EXTRA_TYPE cmDependsFortran_yyget_extra (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yyextra;
-}
-
-/** Get the current line number.
- * @param yyscanner The scanner object.
- */
-int cmDependsFortran_yyget_lineno (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- if (! YY_CURRENT_BUFFER)
- return 0;
-
- return yylineno;
-}
-
-/** Get the current column number.
- * @param yyscanner The scanner object.
- */
-int cmDependsFortran_yyget_column (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- if (! YY_CURRENT_BUFFER)
- return 0;
-
- return yycolumn;
-}
-
-/** Get the input stream.
- * @param yyscanner The scanner object.
- */
-FILE *cmDependsFortran_yyget_in (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yyin;
-}
-
-/** Get the output stream.
- * @param yyscanner The scanner object.
- */
-FILE *cmDependsFortran_yyget_out (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yyout;
-}
-
-/** Get the length of the current token.
- * @param yyscanner The scanner object.
- */
-int cmDependsFortran_yyget_leng (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yyleng;
-}
-
-/** Get the current token.
- * @param yyscanner The scanner object.
- */
-
-char *cmDependsFortran_yyget_text (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yytext;
-}
-
-/** Set the user-defined data. This data is never touched by the scanner.
- * @param user_defined The data to be associated with this scanner.
- * @param yyscanner The scanner object.
- */
-void cmDependsFortran_yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yyextra = user_defined ;
-}
-
-/** Set the current line number.
- * @param line_number
- * @param yyscanner The scanner object.
- */
-void cmDependsFortran_yyset_lineno (int line_number , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- /* lineno is only valid if an input buffer exists. */
- if (! YY_CURRENT_BUFFER )
- yy_fatal_error( "cmDependsFortran_yyset_lineno called with no buffer" , yyscanner);
-
- yylineno = line_number;
-}
-
-/** Set the current column.
- * @param line_number
- * @param yyscanner The scanner object.
- */
-void cmDependsFortran_yyset_column (int column_no , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- /* column is only valid if an input buffer exists. */
- if (! YY_CURRENT_BUFFER )
- yy_fatal_error( "cmDependsFortran_yyset_column called with no buffer" , yyscanner);
-
- yycolumn = column_no;
-}
-
-/** Set the input stream. This does not discard the current
- * input buffer.
- * @param in_str A readable stream.
- * @param yyscanner The scanner object.
- * @see cmDependsFortran_yy_switch_to_buffer
- */
-void cmDependsFortran_yyset_in (FILE * in_str , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yyin = in_str ;
-}
-
-void cmDependsFortran_yyset_out (FILE * out_str , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yyout = out_str ;
-}
-
-int cmDependsFortran_yyget_debug (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yy_flex_debug;
-}
-
-void cmDependsFortran_yyset_debug (int bdebug , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yy_flex_debug = bdebug ;
-}
-
-/* Accessor methods for yylval and yylloc */
-
-/* User-visible API */
-
-/* cmDependsFortran_yylex_init is special because it creates the scanner itself, so it is
- * the ONLY reentrant function that doesn't take the scanner as the last argument.
- * That's why we explicitly handle the declaration, instead of using our macros.
- */
-
-int cmDependsFortran_yylex_init(yyscan_t* ptr_yy_globals)
-
-{
- if (ptr_yy_globals == NULL){
- errno = EINVAL;
- return 1;
- }
-
- *ptr_yy_globals = (yyscan_t) cmDependsFortran_yyalloc ( sizeof( struct yyguts_t ), NULL );
-
- if (*ptr_yy_globals == NULL){
- errno = ENOMEM;
- return 1;
- }
-
- /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
- memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
-
- return yy_init_globals ( *ptr_yy_globals );
-}
-
-/* cmDependsFortran_yylex_init_extra has the same functionality as cmDependsFortran_yylex_init, but follows the
- * convention of taking the scanner as the last argument. Note however, that
- * this is a *pointer* to a scanner, as it will be allocated by this call (and
- * is the reason, too, why this function also must handle its own declaration).
- * The user defined value in the first argument will be available to cmDependsFortran_yyalloc in
- * the yyextra field.
- */
-
-int cmDependsFortran_yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
-
-{
- struct yyguts_t dummy_yyguts;
-
- cmDependsFortran_yyset_extra (yy_user_defined, &dummy_yyguts);
-
- if (ptr_yy_globals == NULL){
- errno = EINVAL;
- return 1;
- }
-
- *ptr_yy_globals = (yyscan_t) cmDependsFortran_yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
-
- if (*ptr_yy_globals == NULL){
- errno = ENOMEM;
- return 1;
- }
-
- /* By setting to 0xAA, we expose bugs in
- yy_init_globals. Leave at 0x00 for releases. */
- memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
-
- cmDependsFortran_yyset_extra (yy_user_defined, *ptr_yy_globals);
-
- return yy_init_globals ( *ptr_yy_globals );
-}
-
-static int yy_init_globals (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- /* Initialization is the same as for the non-reentrant scanner.
- * This function is called from cmDependsFortran_yylex_destroy(), so don't allocate here.
- */
-
- yyg->yy_buffer_stack = 0;
- yyg->yy_buffer_stack_top = 0;
- yyg->yy_buffer_stack_max = 0;
- yyg->yy_c_buf_p = (char *) 0;
- yyg->yy_init = 0;
- yyg->yy_start = 0;
-
- yyg->yy_start_stack_ptr = 0;
- yyg->yy_start_stack_depth = 0;
- yyg->yy_start_stack = NULL;
-
-/* Defined in main.c */
-#ifdef YY_STDINIT
- yyin = stdin;
- yyout = stdout;
-#else
- yyin = (FILE *) 0;
- yyout = (FILE *) 0;
-#endif
-
- /* For future reference: Set errno on error, since we are called by
- * cmDependsFortran_yylex_init()
- */
- return 0;
-}
-
-/* cmDependsFortran_yylex_destroy is for both reentrant and non-reentrant scanners. */
-int cmDependsFortran_yylex_destroy (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- /* Pop the buffer stack, destroying each element. */
- while(YY_CURRENT_BUFFER){
- cmDependsFortran_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
- YY_CURRENT_BUFFER_LVALUE = NULL;
- cmDependsFortran_yypop_buffer_state(yyscanner);
- }
-
- /* Destroy the stack itself. */
- cmDependsFortran_yyfree(yyg->yy_buffer_stack ,yyscanner);
- yyg->yy_buffer_stack = NULL;
-
- /* Destroy the start condition stack. */
- cmDependsFortran_yyfree(yyg->yy_start_stack ,yyscanner );
- yyg->yy_start_stack = NULL;
-
- /* Reset the globals. This is important in a non-reentrant scanner so the next time
- * cmDependsFortran_yylex() is called, initialization will occur. */
- yy_init_globals( yyscanner);
-
- /* Destroy the main struct (reentrant only). */
- cmDependsFortran_yyfree ( yyscanner , yyscanner );
- return 0;
-}
-
-/*
- * Internal utility routines.
- */
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
-{
- int i;
- for ( i = 0; i < n; ++i )
- s1[i] = s2[i];
-}
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
-{
- int n;
- for ( n = 0; s[n]; ++n )
- ;
-
- return n;
-}
-#endif
-
-void *cmDependsFortran_yyalloc (yy_size_t size , yyscan_t)
-{
- return (void *) malloc( size );
-}
-
-void *cmDependsFortran_yyrealloc (void * ptr, yy_size_t size , yyscan_t)
-{
- /* The cast to (char *) in the following accommodates both
- * implementations that use char* generic pointers, and those
- * that use void* generic pointers. It works with the latter
- * because both ANSI C and C++ allow castless assignment from
- * any pointer type to void*, and deal with argument conversions
- * as though doing an assignment.
- */
- return (void *) realloc( (char *) ptr, size );
-}
-
-void cmDependsFortran_yyfree (void * ptr , yyscan_t)
-{
- free( (char *) ptr ); /* see cmDependsFortran_yyrealloc() for (char *) cast */
-}
-
-#define YYTABLES_NAME "yytables"
-
-#line 181 "cmDependsFortranLexer.in.l"
-
-
-
-/*--------------------------------------------------------------------------*/
-YY_BUFFER_STATE cmDependsFortranLexer_GetCurrentBuffer(yyscan_t yyscanner)
-{
- /* Hack into the internal flex-generated scanner to get the buffer. */
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return YY_CURRENT_BUFFER;
-}
-
diff --git a/Source/cmDependsFortranLexer.h b/Source/cmDependsFortranLexer.h
deleted file mode 100644
index 8e24cfd80..000000000
--- a/Source/cmDependsFortranLexer.h
+++ /dev/null
@@ -1,348 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef cmDependsFortran_yyHEADER_H
-#define cmDependsFortran_yyHEADER_H 1
-#define cmDependsFortran_yyIN_HEADER 1
-
-#define YY_INT_ALIGNED short int
-
-/* A lexical scanner generated by flex */
-
-#define FLEX_SCANNER
-#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 35
-#if YY_FLEX_SUBMINOR_VERSION > 0
-#define FLEX_BETA
-#endif
-
-/* First, we deal with platform-specific or compiler-specific issues. */
-
-/* begin standard C headers. */
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* end standard C headers. */
-
-/* flex integer type definitions */
-
-#ifndef FLEXINT_H
-#define FLEXINT_H
-
-/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
-
-#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-
-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
- * if you want the limit (max/min) macros for int types.
- */
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS 1
-#endif
-
-#include <inttypes.h>
-typedef int8_t flex_int8_t;
-typedef uint8_t flex_uint8_t;
-typedef int16_t flex_int16_t;
-typedef uint16_t flex_uint16_t;
-typedef int32_t flex_int32_t;
-typedef uint32_t flex_uint32_t;
-#else
-typedef signed char flex_int8_t;
-typedef short int flex_int16_t;
-typedef int flex_int32_t;
-typedef unsigned char flex_uint8_t;
-typedef unsigned short int flex_uint16_t;
-typedef unsigned int flex_uint32_t;
-
-/* Limits of integral types. */
-#ifndef INT8_MIN
-#define INT8_MIN (-128)
-#endif
-#ifndef INT16_MIN
-#define INT16_MIN (-32767-1)
-#endif
-#ifndef INT32_MIN
-#define INT32_MIN (-2147483647-1)
-#endif
-#ifndef INT8_MAX
-#define INT8_MAX (127)
-#endif
-#ifndef INT16_MAX
-#define INT16_MAX (32767)
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX (2147483647)
-#endif
-#ifndef UINT8_MAX
-#define UINT8_MAX (255U)
-#endif
-#ifndef UINT16_MAX
-#define UINT16_MAX (65535U)
-#endif
-#ifndef UINT32_MAX
-#define UINT32_MAX (4294967295U)
-#endif
-
-#endif /* ! C99 */
-
-#endif /* ! FLEXINT_H */
-
-#ifdef __cplusplus
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else /* ! __cplusplus */
-
-/* C99 requires __STDC__ to be defined as 1. */
-#if defined (__STDC__)
-
-#define YY_USE_CONST
-
-#endif /* defined (__STDC__) */
-#endif /* ! __cplusplus */
-
-#ifdef YY_USE_CONST
-#define yyconst const
-#else
-#define yyconst
-#endif
-
-/* An opaque pointer. */
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
-typedef void* yyscan_t;
-#endif
-
-/* For convenience, these vars (plus the bison vars far below)
- are macros in the reentrant scanner. */
-#define yyin yyg->yyin_r
-#define yyout yyg->yyout_r
-#define yyextra yyg->yyextra_r
-#define yyleng yyg->yyleng_r
-#define yytext yyg->yytext_r
-#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
-#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
-#define yy_flex_debug yyg->yy_flex_debug_r
-
-/* Size of default input buffer. */
-#ifndef YY_BUF_SIZE
-#ifdef __ia64__
-/* On IA-64, the buffer size is 16k, not 8k.
- * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
- * Ditto for the __ia64__ case accordingly.
- */
-#define YY_BUF_SIZE 32768
-#else
-#define YY_BUF_SIZE 16384
-#endif /* __ia64__ */
-#endif
-
-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
-#define YY_TYPEDEF_YY_BUFFER_STATE
-typedef struct yy_buffer_state *YY_BUFFER_STATE;
-#endif
-
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
-#ifndef YY_STRUCT_YY_BUFFER_STATE
-#define YY_STRUCT_YY_BUFFER_STATE
-struct yy_buffer_state
- {
- FILE *yy_input_file;
-
- char *yy_ch_buf; /* input buffer */
- char *yy_buf_pos; /* current position in input buffer */
-
- /* Size of input buffer in bytes, not including room for EOB
- * characters.
- */
- yy_size_t yy_buf_size;
-
- /* Number of characters read into yy_ch_buf, not including EOB
- * characters.
- */
- int yy_n_chars;
-
- /* Whether we "own" the buffer - i.e., we know we created it,
- * and can realloc() it to grow it, and should free() it to
- * delete it.
- */
- int yy_is_our_buffer;
-
- /* Whether this is an "interactive" input source; if so, and
- * if we're using stdio for input, then we want to use getc()
- * instead of fread(), to make sure we stop fetching input after
- * each newline.
- */
- int yy_is_interactive;
-
- /* Whether we're considered to be at the beginning of a line.
- * If so, '^' rules will be active on the next match, otherwise
- * not.
- */
- int yy_at_bol;
-
- int yy_bs_lineno; /**< The line count. */
- int yy_bs_column; /**< The column count. */
-
- /* Whether to try to fill the input buffer when we reach the
- * end of it.
- */
- int yy_fill_buffer;
-
- int yy_buffer_status;
-
- };
-#endif /* !YY_STRUCT_YY_BUFFER_STATE */
-
-void cmDependsFortran_yyrestart (FILE *input_file ,yyscan_t yyscanner );
-void cmDependsFortran_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-YY_BUFFER_STATE cmDependsFortran_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
-void cmDependsFortran_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void cmDependsFortran_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void cmDependsFortran_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-void cmDependsFortran_yypop_buffer_state (yyscan_t yyscanner );
-
-YY_BUFFER_STATE cmDependsFortran_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
-YY_BUFFER_STATE cmDependsFortran_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
-YY_BUFFER_STATE cmDependsFortran_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
-
-void *cmDependsFortran_yyalloc (yy_size_t ,yyscan_t yyscanner );
-void *cmDependsFortran_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
-void cmDependsFortran_yyfree (void * ,yyscan_t yyscanner );
-
-/* Begin user sect3 */
-
-#define cmDependsFortran_yywrap(n) 1
-#define YY_SKIP_YYWRAP
-
-#define yytext_ptr yytext_r
-
-#ifdef YY_HEADER_EXPORT_START_CONDITIONS
-#define INITIAL 0
-#define free_fmt 1
-#define fixed_fmt 2
-#define str_sq 3
-#define str_dq 4
-
-#endif
-
-#ifndef YY_EXTRA_TYPE
-#define YY_EXTRA_TYPE void *
-#endif
-
-int cmDependsFortran_yylex_init (yyscan_t* scanner);
-
-int cmDependsFortran_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
-
-/* Accessor methods to globals.
- These are made visible to non-reentrant scanners for convenience. */
-
-int cmDependsFortran_yylex_destroy (yyscan_t yyscanner );
-
-int cmDependsFortran_yyget_debug (yyscan_t yyscanner );
-
-void cmDependsFortran_yyset_debug (int debug_flag ,yyscan_t yyscanner );
-
-YY_EXTRA_TYPE cmDependsFortran_yyget_extra (yyscan_t yyscanner );
-
-void cmDependsFortran_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
-
-FILE *cmDependsFortran_yyget_in (yyscan_t yyscanner );
-
-void cmDependsFortran_yyset_in (FILE * in_str ,yyscan_t yyscanner );
-
-FILE *cmDependsFortran_yyget_out (yyscan_t yyscanner );
-
-void cmDependsFortran_yyset_out (FILE * out_str ,yyscan_t yyscanner );
-
-int cmDependsFortran_yyget_leng (yyscan_t yyscanner );
-
-char *cmDependsFortran_yyget_text (yyscan_t yyscanner );
-
-int cmDependsFortran_yyget_lineno (yyscan_t yyscanner );
-
-void cmDependsFortran_yyset_lineno (int line_number ,yyscan_t yyscanner );
-
-/* Macros after this point can all be overridden by user definitions in
- * section 1.
- */
-
-#ifndef YY_SKIP_YYWRAP
-#ifdef __cplusplus
-extern "C" int cmDependsFortran_yywrap (yyscan_t yyscanner );
-#else
-extern int cmDependsFortran_yywrap (yyscan_t yyscanner );
-#endif
-#endif
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
-#endif
-
-#ifndef YY_NO_INPUT
-
-#endif
-
-/* Amount of stuff to slurp up with each read. */
-#ifndef YY_READ_BUF_SIZE
-#ifdef __ia64__
-/* On IA-64, the buffer size is 16k, not 8k */
-#define YY_READ_BUF_SIZE 16384
-#else
-#define YY_READ_BUF_SIZE 8192
-#endif /* __ia64__ */
-#endif
-
-/* Number of entries by which start-condition stack grows. */
-#ifndef YY_START_STACK_INCR
-#define YY_START_STACK_INCR 25
-#endif
-
-/* Default declaration of generated scanner - a define so the user can
- * easily add parameters.
- */
-#ifndef YY_DECL
-#define YY_DECL_IS_OURS 1
-
-extern int cmDependsFortran_yylex (yyscan_t yyscanner);
-
-#define YY_DECL int cmDependsFortran_yylex (yyscan_t yyscanner)
-#endif /* !YY_DECL */
-
-/* yy_get_previous_state - get the state just before the EOB char was reached */
-
-#undef YY_NEW_FILE
-#undef YY_FLUSH_BUFFER
-#undef yy_set_bol
-#undef yy_new_buffer
-#undef yy_set_interactive
-#undef YY_DO_BEFORE_ACTION
-
-#ifdef YY_DECL_IS_OURS
-#undef YY_DECL_IS_OURS
-#undef YY_DECL
-#endif
-
-#undef cmDependsFortran_yyIN_HEADER
-#endif /* cmDependsFortran_yyHEADER_H */
diff --git a/Source/cmDependsFortranLexer.in.l b/Source/cmDependsFortranLexer.in.l
deleted file mode 100644
index 01488024e..000000000
--- a/Source/cmDependsFortranLexer.in.l
+++ /dev/null
@@ -1,190 +0,0 @@
-%{
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-/*-------------------------------------------------------------------------
- Portions of this source have been derived from makedepf90 version 2.8.8,
-
- Copyright (C) 2000--2006 Erik Edelmann <erik.edelmann@iki.fi>
-
- The code was originally distributed under the GPL but permission
- from the copyright holder has been obtained to distribute this
- derived work under the CMake license.
--------------------------------------------------------------------------*/
-
-/*
-
-This file must be translated to C and modified to build everywhere.
-
-Run flex like this:
-
- flex -i --prefix=cmDependsFortran_yy --header-file=cmDependsFortranLexer.h -ocmDependsFortranLexer.cxx cmDependsFortranLexer.in.l
-
-Modify cmDependsFortranLexer.cxx:
- - remove TABs
- - remove use of the 'register' storage class specifier
- - remove "yyscanner" argument from these methods:
- yy_fatal_error, cmDependsFortran_yyalloc, cmDependsFortran_yyrealloc, cmDependsFortran_yyfree
- - remove "yyscanner = NULL" from end of cmDependsFortran_yylex_destroy
- - remove all YY_BREAK lines occurring right after return statements
- - change while ( 1 ) to for(;;)
-
-Modify cmDependsFortranLexer.h:
- - remove TABs
- - remove the yy_init_globals function
- - remove the block that includes unistd.h
- - remove #line directives (avoids bogus warning on old Sun)
-
-*/
-
-#include "cmStandardLexer.h"
-
-#define cmDependsFortranLexer_cxx
-#include "cmDependsFortranParser.h" /* Interface to parser object. */
-
-/* Replace the lexer input function. */
-#undef YY_INPUT
-#define YY_INPUT(buf, result, max_size) \
- { result = cmDependsFortranParser_Input(yyextra, buf, max_size); }
-
-/* Include the set of tokens from the parser. */
-#include "cmDependsFortranParserTokens.h"
-
-/*--------------------------------------------------------------------------*/
-%}
-
-
-%option reentrant
-%option noyywrap
-%pointer
-
-%s free_fmt fixed_fmt
-%x str_sq str_dq
-
-%%
-
-\" {
- cmDependsFortranParser_StringStart(yyextra);
- cmDependsFortranParser_SetOldStartcond(yyextra, YY_START);
- BEGIN(str_dq);
-}
-
-' {
- cmDependsFortranParser_StringStart(yyextra);
- cmDependsFortranParser_SetOldStartcond(yyextra, YY_START);
- BEGIN(str_sq);
-}
-
-<str_dq>\" |
-<str_sq>' {
- BEGIN(cmDependsFortranParser_GetOldStartcond(yyextra) );
- yylvalp->string = strdup(cmDependsFortranParser_StringEnd(yyextra));
- return STRING;
-}
-
-<str_dq,str_sq>&[ \t]*\n |
-<str_dq,str_sq>&[ \t]*\n[ \t]*& /* Ignore (continued strings, free fmt) */
-
-<fixed_fmt,str_dq,str_sq>\n[ ]{5}[^ \t\n] {
- if (cmDependsFortranParser_GetOldStartcond(yyextra) == fixed_fmt)
- ; /* Ignore (cont. strings, fixed fmt) */
- else
- {
- unput(yytext[strlen(yytext)-1]);
- }
-}
-
-
-<str_dq,str_sq>\n {
- unput ('\n');
- BEGIN(INITIAL);
- return UNTERMINATED_STRING;
-}
-
-<str_sq,str_dq>. {
- cmDependsFortranParser_StringAppend(yyextra, yytext[0]);
-}
-
-!.*\n { return EOSTMT; } /* Treat comments like */
-<fixed_fmt>^[cC*dD].*\n { return EOSTMT; } /* empty lines */
-
-^[ \t]*#[ \t]*include[ \t]*<[^>]+> {
- yytext[yyleng-1] = 0;
- yylvalp->string = strdup(strchr(yytext, '<')+1);
- return CPP_INCLUDE_ANGLE;
-}
-^[ \t]*#[ \t]*include { return CPP_INCLUDE; }
-\$[ \t]*include { return F90PPR_INCLUDE; }
-\?\?[ \t]*include { return COCO_INCLUDE; }
-
-^[ \t]*#[ \t]*define { return CPP_DEFINE; }
-\$[ \t]*DEFINE { return F90PPR_DEFINE; }
-
-^[ \t]*#[ \t]*undef { return CPP_UNDEF; }
-\$[ \t]*UNDEF { return F90PPR_UNDEF; }
-
-^[ \t]*#[ \t]*ifdef { return CPP_IFDEF; }
-^[ \t]*#[ \t]*ifndef { return CPP_IFNDEF; }
-^[ \t]*#[ \t]*if { return CPP_IF; }
-^[ \t]*#[ \t]*elif { return CPP_ELIF; }
-^[ \t]*#[ \t]*else { return CPP_ELSE; }
-^[ \t]*#[ \t]*endif { return CPP_ENDIF; }
-
-$[ \t]*ifdef { return F90PPR_IFDEF; }
-$[ \t]*ifndef { return F90PPR_IFNDEF; }
-$[ \t]*if { return F90PPR_IF; }
-$[ \t]*elif { return F90PPR_ELIF; }
-$[ \t]*else { return F90PPR_ELSE; }
-$[ \t]*endif { return F90PPR_ENDIF; }
-
- /* Line continuations, possible involving comments. */
-&([ \t\n]*|!.*)*
-&([ \t\n]*|!.*)*&
-
-, { return COMMA; }
-
-:: { return DCOLON; }
-
-<fixed_fmt>\n[ ]{5}[^ ] { return GARBAGE; }
-
-=|=> { return ASSIGNMENT_OP; }
-
-[a-zA-Z_][a-zA-Z_0-9]* {
- yylvalp->string = strdup(yytext);
- return WORD;
-}
-
-[^ \t\n\r;,!'"a-zA-Z=&]+ { return GARBAGE; }
-
-;|\n { return EOSTMT; }
-
-
-[ \t\r,] /* Ignore */
-\\[ \t]*\n /* Ignore line-endings preceeded by \ */
-
-. { return *yytext; }
-
-<<EOF>> {
- if(!cmDependsFortranParser_FilePop(yyextra) )
- {
- return YY_NULL;
- }
-}
-
-%%
-
-/*--------------------------------------------------------------------------*/
-YY_BUFFER_STATE cmDependsFortranLexer_GetCurrentBuffer(yyscan_t yyscanner)
-{
- /* Hack into the internal flex-generated scanner to get the buffer. */
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return YY_CURRENT_BUFFER;
-}
diff --git a/Source/cmDependsFortranParser.cxx b/Source/cmDependsFortranParser.cxx
deleted file mode 100644
index 7b49a9c5c..000000000
--- a/Source/cmDependsFortranParser.cxx
+++ /dev/null
@@ -1,2094 +0,0 @@
-/* A Bison parser, made by GNU Bison 2.5. */
-
-/* Bison implementation for Yacc-like parsers in C
-
- Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-/* As a special exception, you may create a larger work that contains
- part or all of the Bison parser skeleton and distribute that work
- under terms of your choice, so long as that work isn't itself a
- parser generator using the skeleton or a modified version thereof
- as a parser skeleton. Alternatively, if you modify or redistribute
- the parser skeleton itself, you may (at your option) remove this
- special exception, which will cause the skeleton and the resulting
- Bison output files to be licensed under the GNU General Public
- License without this special exception.
-
- This special exception was added by the Free Software Foundation in
- version 2.2 of Bison. */
-
-/* C LALR(1) parser skeleton written by Richard Stallman, by
- simplifying the original so-called "semantic" parser. */
-
-/* All symbols defined below should begin with yy or YY, to avoid
- infringing on user name space. This should be done even for local
- variables, as they might otherwise be expanded by user macros.
- There are some unavoidable exceptions within include files to
- define necessary library symbols; they are noted "INFRINGES ON
- USER NAME SPACE" below. */
-
-/* Identify Bison output. */
-#define YYBISON 1
-
-/* Bison version. */
-#define YYBISON_VERSION "2.5"
-
-/* Skeleton name. */
-#define YYSKELETON_NAME "yacc.c"
-
-/* Pure parsers. */
-#define YYPURE 1
-
-/* Push parsers. */
-#define YYPUSH 0
-
-/* Pull parsers. */
-#define YYPULL 1
-
-/* Using locations. */
-#define YYLSP_NEEDED 0
-
-/* Substitute the variable and function names. */
-#define yyparse cmDependsFortran_yyparse
-#define yylex cmDependsFortran_yylex
-#define yyerror cmDependsFortran_yyerror
-#define yylval cmDependsFortran_yylval
-#define yychar cmDependsFortran_yychar
-#define yydebug cmDependsFortran_yydebug
-#define yynerrs cmDependsFortran_yynerrs
-
-
-/* Copy the first part of user declarations. */
-
-/* Line 268 of yacc.c */
-#line 1 "cmDependsFortranParser.y"
-
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-/*-------------------------------------------------------------------------
- Portions of this source have been derived from makedepf90 version 2.8.8,
-
- Copyright (C) 2000--2006 Erik Edelmann <erik.edelmann@iki.fi>
-
- The code was originally distributed under the GPL but permission
- from the copyright holder has been obtained to distribute this
- derived work under the CMake license.
--------------------------------------------------------------------------*/
-
-/*
-
-This file must be translated to C and modified to build everywhere.
-
-Run bison like this:
-
- bison --yacc --name-prefix=cmDependsFortran_yy
- --defines=cmDependsFortranParserTokens.h
- -ocmDependsFortranParser.cxx
- cmDependsFortranParser.y
-
-Modify cmDependsFortranParser.cxx:
- - remove TABs
- - Remove the yyerrorlab block in range ["goto yyerrlab1", "yyerrlab1:"]
-*/
-
-/*-------------------------------------------------------------------------*/
-#define cmDependsFortranParser_cxx
-#include "cmDependsFortranParser.h" /* Interface to parser object. */
-#include "cmDependsFortranParserTokens.h" /* Need YYSTYPE for YY_DECL. */
-
-#include <cmsys/String.h>
-
-/* Configure the parser to use a lexer object. */
-#define YYPARSE_PARAM yyscanner
-#define YYLEX_PARAM yyscanner
-#define YYERROR_VERBOSE 1
-#define cmDependsFortran_yyerror(x) \
- cmDependsFortranError(yyscanner, x)
-
-/* Forward declare the lexer entry point. */
-YY_DECL;
-
-/* Helper function to forward error callback. */
-static void cmDependsFortranError(yyscan_t yyscanner, const char* message)
-{
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_Error(parser, message);
-}
-
-static bool cmDependsFortranParserIsKeyword(const char* word,
- const char* keyword)
-{
- return cmsysString_strcasecmp(word, keyword) == 0;
-}
-
-/* Disable some warnings in the generated code. */
-#ifdef __BORLANDC__
-# pragma warn -8004 /* Variable assigned a value that is not used. */
-# pragma warn -8008 /* condition always returns true */
-# pragma warn -8060 /* possibly incorrect assignment */
-# pragma warn -8066 /* unreachable code */
-#endif
-#ifdef _MSC_VER
-# pragma warning (disable: 4102) /* Unused goto label. */
-# pragma warning (disable: 4065) /* Switch contains default but no case. */
-# pragma warning (disable: 4701) /* Local variable may not be initialized. */
-# pragma warning (disable: 4702) /* Unreachable code. */
-# pragma warning (disable: 4127) /* Conditional expression is constant. */
-# pragma warning (disable: 4244) /* Conversion to smaller type, data loss. */
-#endif
-
-
-/* Line 268 of yacc.c */
-#line 165 "cmDependsFortranParser.cxx"
-
-/* Enabling traces. */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-
-/* Enabling verbose error messages. */
-#ifdef YYERROR_VERBOSE
-# undef YYERROR_VERBOSE
-# define YYERROR_VERBOSE 1
-#else
-# define YYERROR_VERBOSE 0
-#endif
-
-/* Enabling the token table. */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
-#endif
-
-
-/* Tokens. */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
- /* Put the tokens into the symbol table, so that GDB and other debuggers
- know about them. */
- enum yytokentype {
- EOSTMT = 258,
- ASSIGNMENT_OP = 259,
- GARBAGE = 260,
- CPP_INCLUDE = 261,
- F90PPR_INCLUDE = 262,
- COCO_INCLUDE = 263,
- F90PPR_DEFINE = 264,
- CPP_DEFINE = 265,
- F90PPR_UNDEF = 266,
- CPP_UNDEF = 267,
- CPP_IFDEF = 268,
- CPP_IFNDEF = 269,
- CPP_IF = 270,
- CPP_ELSE = 271,
- CPP_ELIF = 272,
- CPP_ENDIF = 273,
- F90PPR_IFDEF = 274,
- F90PPR_IFNDEF = 275,
- F90PPR_IF = 276,
- F90PPR_ELSE = 277,
- F90PPR_ELIF = 278,
- F90PPR_ENDIF = 279,
- COMMA = 280,
- DCOLON = 281,
- CPP_TOENDL = 282,
- UNTERMINATED_STRING = 283,
- STRING = 284,
- WORD = 285,
- CPP_INCLUDE_ANGLE = 286
- };
-#endif
-/* Tokens. */
-#define EOSTMT 258
-#define ASSIGNMENT_OP 259
-#define GARBAGE 260
-#define CPP_INCLUDE 261
-#define F90PPR_INCLUDE 262
-#define COCO_INCLUDE 263
-#define F90PPR_DEFINE 264
-#define CPP_DEFINE 265
-#define F90PPR_UNDEF 266
-#define CPP_UNDEF 267
-#define CPP_IFDEF 268
-#define CPP_IFNDEF 269
-#define CPP_IF 270
-#define CPP_ELSE 271
-#define CPP_ELIF 272
-#define CPP_ENDIF 273
-#define F90PPR_IFDEF 274
-#define F90PPR_IFNDEF 275
-#define F90PPR_IF 276
-#define F90PPR_ELSE 277
-#define F90PPR_ELIF 278
-#define F90PPR_ENDIF 279
-#define COMMA 280
-#define DCOLON 281
-#define CPP_TOENDL 282
-#define UNTERMINATED_STRING 283
-#define STRING 284
-#define WORD 285
-#define CPP_INCLUDE_ANGLE 286
-
-
-
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-{
-
-/* Line 293 of yacc.c */
-#line 89 "cmDependsFortranParser.y"
-
- char* string;
-
-
-
-/* Line 293 of yacc.c */
-#line 269 "cmDependsFortranParser.cxx"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-#endif
-
-
-/* Copy the second part of user declarations. */
-
-
-/* Line 343 of yacc.c */
-#line 281 "cmDependsFortranParser.cxx"
-
-#ifdef short
-# undef short
-#endif
-
-#ifdef YYTYPE_UINT8
-typedef YYTYPE_UINT8 yytype_uint8;
-#else
-typedef unsigned char yytype_uint8;
-#endif
-
-#ifdef YYTYPE_INT8
-typedef YYTYPE_INT8 yytype_int8;
-#elif (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-typedef signed char yytype_int8;
-#else
-typedef short int yytype_int8;
-#endif
-
-#ifdef YYTYPE_UINT16
-typedef YYTYPE_UINT16 yytype_uint16;
-#else
-typedef unsigned short int yytype_uint16;
-#endif
-
-#ifdef YYTYPE_INT16
-typedef YYTYPE_INT16 yytype_int16;
-#else
-typedef short int yytype_int16;
-#endif
-
-#ifndef YYSIZE_T
-# ifdef __SIZE_TYPE__
-# define YYSIZE_T __SIZE_TYPE__
-# elif defined size_t
-# define YYSIZE_T size_t
-# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-# define YYSIZE_T size_t
-# else
-# define YYSIZE_T unsigned int
-# endif
-#endif
-
-#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
-
-#ifndef YY_
-# if defined YYENABLE_NLS && YYENABLE_NLS
-# if ENABLE_NLS
-# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-# define YY_(msgid) dgettext ("bison-runtime", msgid)
-# endif
-# endif
-# ifndef YY_
-# define YY_(msgid) msgid
-# endif
-#endif
-
-/* Suppress unused-variable warnings by "using" E. */
-#if ! defined lint || defined __GNUC__
-# define YYUSE(e) ((void) (e))
-#else
-# define YYUSE(e) /* empty */
-#endif
-
-/* Identity function, used to suppress warnings about constant conditions. */
-#ifndef lint
-# define YYID(n) (n)
-#else
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static int
-YYID (int yyi)
-#else
-static int
-YYID (yyi)
- int yyi;
-#endif
-{
- return yyi;
-}
-#endif
-
-#if ! defined yyoverflow || YYERROR_VERBOSE
-
-/* The parser invokes alloca or malloc; define the necessary symbols. */
-
-# ifdef YYSTACK_USE_ALLOCA
-# if YYSTACK_USE_ALLOCA
-# ifdef __GNUC__
-# define YYSTACK_ALLOC __builtin_alloca
-# elif defined __BUILTIN_VA_ARG_INCR
-# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
-# elif defined _AIX
-# define YYSTACK_ALLOC __alloca
-# elif defined _MSC_VER
-# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
-# define alloca _alloca
-# else
-# define YYSTACK_ALLOC alloca
-# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# ifndef EXIT_SUCCESS
-# define EXIT_SUCCESS 0
-# endif
-# endif
-# endif
-# endif
-# endif
-
-# ifdef YYSTACK_ALLOC
- /* Pacify GCC's `empty if-body' warning. */
-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
-# ifndef YYSTACK_ALLOC_MAXIMUM
- /* The OS might guarantee only one guard page at the bottom of the stack,
- and a page size can be as small as 4096 bytes. So we cannot safely
- invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
- to allow for a few compiler-allocated temporary stack slots. */
-# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
-# endif
-# else
-# define YYSTACK_ALLOC YYMALLOC
-# define YYSTACK_FREE YYFREE
-# ifndef YYSTACK_ALLOC_MAXIMUM
-# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
-# endif
-# if (defined __cplusplus && ! defined EXIT_SUCCESS \
- && ! ((defined YYMALLOC || defined malloc) \
- && (defined YYFREE || defined free)))
-# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# ifndef EXIT_SUCCESS
-# define EXIT_SUCCESS 0
-# endif
-# endif
-# ifndef YYMALLOC
-# define YYMALLOC malloc
-# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
-# endif
-# endif
-# ifndef YYFREE
-# define YYFREE free
-# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-void free (void *); /* INFRINGES ON USER NAME SPACE */
-# endif
-# endif
-# endif
-#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
-
-
-#if (! defined yyoverflow \
- && (! defined __cplusplus \
- || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
-
-/* A type that is properly aligned for any stack member. */
-union yyalloc
-{
- yytype_int16 yyss_alloc;
- YYSTYPE yyvs_alloc;
-};
-
-/* The size of the maximum gap between one aligned stack and the next. */
-# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
-
-/* The size of an array large to enough to hold all stacks, each with
- N elements. */
-# define YYSTACK_BYTES(N) \
- ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
- + YYSTACK_GAP_MAXIMUM)
-
-# define YYCOPY_NEEDED 1
-
-/* Relocate STACK from its old location to the new one. The
- local variables YYSIZE and YYSTACKSIZE give the old and new number of
- elements in the stack, and YYPTR gives the new location of the
- stack. Advance YYPTR to a properly aligned location for the next
- stack. */
-# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
- do \
- { \
- YYSIZE_T yynewbytes; \
- YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
- Stack = &yyptr->Stack_alloc; \
- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
- yyptr += yynewbytes / sizeof (*yyptr); \
- } \
- while (YYID (0))
-
-#endif
-
-#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
-/* Copy COUNT objects from FROM to TO. The source and destination do
- not overlap. */
-# ifndef YYCOPY
-# if defined __GNUC__ && 1 < __GNUC__
-# define YYCOPY(To, From, Count) \
- __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
-# else
-# define YYCOPY(To, From, Count) \
- do \
- { \
- YYSIZE_T yyi; \
- for (yyi = 0; yyi < (Count); yyi++) \
- (To)[yyi] = (From)[yyi]; \
- } \
- while (YYID (0))
-# endif
-# endif
-#endif /* !YYCOPY_NEEDED */
-
-/* YYFINAL -- State number of the termination state. */
-#define YYFINAL 2
-/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 276
-
-/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 32
-/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 16
-/* YYNRULES -- Number of rules. */
-#define YYNRULES 53
-/* YYNRULES -- Number of states. */
-#define YYNSTATES 97
-
-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
-#define YYUNDEFTOK 2
-#define YYMAXUTOK 286
-
-#define YYTRANSLATE(YYX) \
- ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
-
-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
-static const yytype_uint8 yytranslate[] =
-{
- 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
- 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 31
-};
-
-#if YYDEBUG
-/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
- YYRHS. */
-static const yytype_uint8 yyprhs[] =
-{
- 0, 0, 3, 4, 7, 9, 11, 16, 19, 24,
- 30, 38, 43, 47, 52, 57, 62, 67, 72, 76,
- 80, 84, 88, 93, 97, 99, 101, 103, 105, 107,
- 109, 111, 113, 115, 117, 119, 121, 123, 125, 127,
- 129, 131, 133, 135, 137, 139, 140, 143, 145, 147,
- 149, 151, 153, 155
-};
-
-/* YYRHS -- A `-1'-separated list of the rules' RHS. */
-static const yytype_int8 yyrhs[] =
-{
- 33, 0, -1, -1, 33, 34, -1, 36, -1, 35,
- -1, 30, 4, 46, 3, -1, 30, 3, -1, 30,
- 30, 46, 3, -1, 30, 26, 30, 46, 3, -1,
- 30, 25, 30, 26, 30, 46, 3, -1, 30, 29,
- 46, 3, -1, 31, 46, 3, -1, 37, 29, 46,
- 3, -1, 38, 30, 46, 3, -1, 39, 30, 46,
- 3, -1, 40, 30, 46, 3, -1, 41, 30, 46,
- 3, -1, 42, 46, 3, -1, 43, 46, 3, -1,
- 44, 46, 3, -1, 45, 46, 3, -1, 30, 5,
- 46, 3, -1, 5, 46, 3, -1, 3, -1, 1,
- -1, 6, -1, 7, -1, 8, -1, 10, -1, 9,
- -1, 12, -1, 11, -1, 13, -1, 19, -1, 14,
- -1, 20, -1, 15, -1, 21, -1, 17, -1, 23,
- -1, 16, -1, 22, -1, 18, -1, 24, -1, -1,
- 46, 47, -1, 30, -1, 29, -1, 5, -1, 4,
- -1, 26, -1, 25, -1, 28, -1
-};
-
-/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
-static const yytype_uint16 yyrline[] =
-{
- 0, 111, 111, 111, 113, 113, 115, 121, 131, 161,
- 172, 185, 196, 203, 210, 216, 222, 228, 234, 239,
- 244, 249, 254, 258, 259, 260, 265, 265, 265, 266,
- 266, 267, 267, 268, 268, 269, 269, 270, 270, 271,
- 271, 272, 272, 273, 273, 274, 274, 277, 278, 279,
- 280, 281, 282, 283
-};
-#endif
-
-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
-/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
- First, the terminals, then, starting at YYNTOKENS, nonterminals. */
-static const char *const yytname[] =
-{
- "$end", "error", "$undefined", "EOSTMT", "ASSIGNMENT_OP", "GARBAGE",
- "CPP_INCLUDE", "F90PPR_INCLUDE", "COCO_INCLUDE", "F90PPR_DEFINE",
- "CPP_DEFINE", "F90PPR_UNDEF", "CPP_UNDEF", "CPP_IFDEF", "CPP_IFNDEF",
- "CPP_IF", "CPP_ELSE", "CPP_ELIF", "CPP_ENDIF", "F90PPR_IFDEF",
- "F90PPR_IFNDEF", "F90PPR_IF", "F90PPR_ELSE", "F90PPR_ELIF",
- "F90PPR_ENDIF", "COMMA", "DCOLON", "CPP_TOENDL", "UNTERMINATED_STRING",
- "STRING", "WORD", "CPP_INCLUDE_ANGLE", "$accept", "code", "stmt",
- "assignment_stmt", "keyword_stmt", "include", "define", "undef", "ifdef",
- "ifndef", "if", "elif", "else", "endif", "other", "misc_code", 0
-};
-#endif
-
-# ifdef YYPRINT
-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
- token YYLEX-NUM. */
-static const yytype_uint16 yytoknum[] =
-{
- 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
- 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
- 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
- 285, 286
-};
-# endif
-
-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
-static const yytype_uint8 yyr1[] =
-{
- 0, 32, 33, 33, 34, 34, 35, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 37, 37, 37, 38,
- 38, 39, 39, 40, 40, 41, 41, 42, 42, 43,
- 43, 44, 44, 45, 45, 46, 46, 47, 47, 47,
- 47, 47, 47, 47
-};
-
-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
-static const yytype_uint8 yyr2[] =
-{
- 0, 2, 0, 2, 1, 1, 4, 2, 4, 5,
- 7, 4, 3, 4, 4, 4, 4, 4, 3, 3,
- 3, 3, 4, 3, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 0, 2, 1, 1, 1,
- 1, 1, 1, 1
-};
-
-/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
- Performed when YYTABLE doesn't specify something else to do. Zero
- means the default is an error. */
-static const yytype_uint8 yydefact[] =
-{
- 2, 0, 1, 25, 24, 45, 26, 27, 28, 30,
- 29, 32, 31, 33, 35, 37, 41, 39, 43, 34,
- 36, 38, 42, 40, 44, 0, 45, 3, 5, 4,
- 0, 0, 0, 0, 0, 45, 45, 45, 45, 0,
- 7, 45, 45, 0, 0, 45, 45, 0, 45, 45,
- 45, 45, 45, 0, 0, 0, 0, 23, 50, 49,
- 52, 51, 53, 48, 47, 46, 0, 0, 0, 45,
- 0, 0, 12, 0, 0, 0, 0, 0, 18, 19,
- 20, 21, 6, 22, 0, 0, 11, 8, 13, 14,
- 15, 16, 17, 45, 9, 0, 10
-};
-
-/* YYDEFGOTO[NTERM-NUM]. */
-static const yytype_int8 yydefgoto[] =
-{
- -1, 1, 27, 28, 29, 30, 31, 32, 33, 34,
- 35, 36, 37, 38, 39, 65
-};
-
-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
- STATE-NUM. */
-#define YYPACT_NINF -29
-static const yytype_int16 yypact[] =
-{
- -29, 39, -29, -29, -29, -29, -29, -29, -29, -29,
- -29, -29, -29, -29, -29, -29, -29, -29, -29, -29,
- -29, -29, -29, -29, -29, 246, -29, -29, -29, -29,
- -28, -27, -22, -17, -16, -29, -29, -29, -29, 2,
- -29, -29, -29, -13, -12, -29, -29, 61, -29, -29,
- -29, -29, -29, 68, 74, 80, 108, -29, -29, -29,
- -29, -29, -29, -29, -29, -29, 114, 120, -24, -29,
- 126, 154, -29, 160, 166, 172, 200, 206, -29, -29,
- -29, -29, -29, -29, -9, 212, -29, -29, -29, -29,
- -29, -29, -29, -29, -29, 218, -29
-};
-
-/* YYPGOTO[NTERM-NUM]. */
-static const yytype_int8 yypgoto[] =
-{
- -29, -29, -29, -29, -29, -29, -29, -29, -29, -29,
- -29, -29, -29, -29, -26, -29
-};
-
-/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
- positive, shift that token. If negative, reduce the rule which
- number is the opposite. If YYTABLE_NINF, syntax error. */
-#define YYTABLE_NINF -1
-static const yytype_uint8 yytable[] =
-{
- 47, 48, 84, 49, 0, 57, 58, 59, 50, 53,
- 54, 55, 56, 51, 52, 66, 67, 68, 69, 70,
- 71, 93, 73, 74, 75, 76, 77, 60, 61, 0,
- 62, 63, 64, 0, 0, 0, 0, 0, 0, 2,
- 3, 0, 4, 85, 5, 6, 7, 8, 9, 10,
- 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 72, 58, 59, 95, 0, 25,
- 26, 78, 58, 59, 0, 0, 0, 79, 58, 59,
- 0, 0, 0, 80, 58, 59, 60, 61, 0, 62,
- 63, 64, 0, 60, 61, 0, 62, 63, 64, 60,
- 61, 0, 62, 63, 64, 60, 61, 0, 62, 63,
- 64, 81, 58, 59, 0, 0, 0, 82, 58, 59,
- 0, 0, 0, 83, 58, 59, 0, 0, 0, 86,
- 58, 59, 0, 60, 61, 0, 62, 63, 64, 60,
- 61, 0, 62, 63, 64, 60, 61, 0, 62, 63,
- 64, 60, 61, 0, 62, 63, 64, 87, 58, 59,
- 0, 0, 0, 88, 58, 59, 0, 0, 0, 89,
- 58, 59, 0, 0, 0, 90, 58, 59, 0, 60,
- 61, 0, 62, 63, 64, 60, 61, 0, 62, 63,
- 64, 60, 61, 0, 62, 63, 64, 60, 61, 0,
- 62, 63, 64, 91, 58, 59, 0, 0, 0, 92,
- 58, 59, 0, 0, 0, 94, 58, 59, 0, 0,
- 0, 96, 58, 59, 0, 60, 61, 0, 62, 63,
- 64, 60, 61, 0, 62, 63, 64, 60, 61, 0,
- 62, 63, 64, 60, 61, 0, 62, 63, 64, 40,
- 41, 42, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 43, 44, 0, 0, 45, 46
-};
-
-#define yypact_value_is_default(yystate) \
- ((yystate) == (-29))
-
-#define yytable_value_is_error(yytable_value) \
- YYID (0)
-
-static const yytype_int8 yycheck[] =
-{
- 26, 29, 26, 30, -1, 3, 4, 5, 30, 35,
- 36, 37, 38, 30, 30, 41, 42, 30, 30, 45,
- 46, 30, 48, 49, 50, 51, 52, 25, 26, -1,
- 28, 29, 30, -1, -1, -1, -1, -1, -1, 0,
- 1, -1, 3, 69, 5, 6, 7, 8, 9, 10,
- 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 3, 4, 5, 93, -1, 30,
- 31, 3, 4, 5, -1, -1, -1, 3, 4, 5,
- -1, -1, -1, 3, 4, 5, 25, 26, -1, 28,
- 29, 30, -1, 25, 26, -1, 28, 29, 30, 25,
- 26, -1, 28, 29, 30, 25, 26, -1, 28, 29,
- 30, 3, 4, 5, -1, -1, -1, 3, 4, 5,
- -1, -1, -1, 3, 4, 5, -1, -1, -1, 3,
- 4, 5, -1, 25, 26, -1, 28, 29, 30, 25,
- 26, -1, 28, 29, 30, 25, 26, -1, 28, 29,
- 30, 25, 26, -1, 28, 29, 30, 3, 4, 5,
- -1, -1, -1, 3, 4, 5, -1, -1, -1, 3,
- 4, 5, -1, -1, -1, 3, 4, 5, -1, 25,
- 26, -1, 28, 29, 30, 25, 26, -1, 28, 29,
- 30, 25, 26, -1, 28, 29, 30, 25, 26, -1,
- 28, 29, 30, 3, 4, 5, -1, -1, -1, 3,
- 4, 5, -1, -1, -1, 3, 4, 5, -1, -1,
- -1, 3, 4, 5, -1, 25, 26, -1, 28, 29,
- 30, 25, 26, -1, 28, 29, 30, 25, 26, -1,
- 28, 29, 30, 25, 26, -1, 28, 29, 30, 3,
- 4, 5, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 25, 26, -1, -1, 29, 30
-};
-
-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
- symbol of state STATE-NUM. */
-static const yytype_uint8 yystos[] =
-{
- 0, 33, 0, 1, 3, 5, 6, 7, 8, 9,
- 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
- 20, 21, 22, 23, 24, 30, 31, 34, 35, 36,
- 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
- 3, 4, 5, 25, 26, 29, 30, 46, 29, 30,
- 30, 30, 30, 46, 46, 46, 46, 3, 4, 5,
- 25, 26, 28, 29, 30, 47, 46, 46, 30, 30,
- 46, 46, 3, 46, 46, 46, 46, 46, 3, 3,
- 3, 3, 3, 3, 26, 46, 3, 3, 3, 3,
- 3, 3, 3, 30, 3, 46, 3
-};
-
-#define yyerrok (yyerrstatus = 0)
-#define yyclearin (yychar = YYEMPTY)
-#define YYEMPTY (-2)
-#define YYEOF 0
-
-#define YYACCEPT goto yyacceptlab
-#define YYABORT goto yyabortlab
-#define YYERROR goto yyerrorlab
-
-
-/* Like YYERROR except do call yyerror. This remains here temporarily
- to ease the transition to the new meaning of YYERROR, for GCC.
- Once GCC version 2 has supplanted version 1, this can go. However,
- YYFAIL appears to be in use. Nevertheless, it is formally deprecated
- in Bison 2.4.2's NEWS entry, where a plan to phase it out is
- discussed. */
-
-#define YYFAIL goto yyerrlab
-#if defined YYFAIL
- /* This is here to suppress warnings from the GCC cpp's
- -Wunused-macros. Normally we don't worry about that warning, but
- some users do, and we want to make it easy for users to remove
- YYFAIL uses, which will produce warnings from Bison 2.5. */
-#endif
-
-#define YYRECOVERING() (!!yyerrstatus)
-
-#define YYBACKUP(Token, Value) \
-do \
- if (yychar == YYEMPTY && yylen == 1) \
- { \
- yychar = (Token); \
- yylval = (Value); \
- YYPOPSTACK (1); \
- goto yybackup; \
- } \
- else \
- { \
- yyerror (YY_("syntax error: cannot back up")); \
- YYERROR; \
- } \
-while (YYID (0))
-
-
-#define YYTERROR 1
-#define YYERRCODE 256
-
-
-/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
- If N is 0, then set CURRENT to the empty location which ends
- the previous symbol: RHS[0] (always defined). */
-
-#define YYRHSLOC(Rhs, K) ((Rhs)[K])
-#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N) \
- do \
- if (YYID (N)) \
- { \
- (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
- (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
- (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
- (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
- } \
- else \
- { \
- (Current).first_line = (Current).last_line = \
- YYRHSLOC (Rhs, 0).last_line; \
- (Current).first_column = (Current).last_column = \
- YYRHSLOC (Rhs, 0).last_column; \
- } \
- while (YYID (0))
-#endif
-
-
-/* This macro is provided for backward compatibility. */
-
-#ifndef YY_LOCATION_PRINT
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-#endif
-
-
-/* YYLEX -- calling `yylex' with the right arguments. */
-
-#ifdef YYLEX_PARAM
-# define YYLEX yylex (&yylval, YYLEX_PARAM)
-#else
-# define YYLEX yylex (&yylval)
-#endif
-
-/* Enable debugging if requested. */
-#if YYDEBUG
-
-# ifndef YYFPRINTF
-# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
-# define YYFPRINTF fprintf
-# endif
-
-# define YYDPRINTF(Args) \
-do { \
- if (yydebug) \
- YYFPRINTF Args; \
-} while (YYID (0))
-
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
-do { \
- if (yydebug) \
- { \
- YYFPRINTF (stderr, "%s ", Title); \
- yy_symbol_print (stderr, \
- Type, Value); \
- YYFPRINTF (stderr, "\n"); \
- } \
-} while (YYID (0))
-
-
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
-
-/*ARGSUSED*/
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
-#else
-static void
-yy_symbol_value_print (yyoutput, yytype, yyvaluep)
- FILE *yyoutput;
- int yytype;
- YYSTYPE const * const yyvaluep;
-#endif
-{
- if (!yyvaluep)
- return;
-# ifdef YYPRINT
- if (yytype < YYNTOKENS)
- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# else
- YYUSE (yyoutput);
-# endif
- switch (yytype)
- {
- default:
- break;
- }
-}
-
-
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
-
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
-#else
-static void
-yy_symbol_print (yyoutput, yytype, yyvaluep)
- FILE *yyoutput;
- int yytype;
- YYSTYPE const * const yyvaluep;
-#endif
-{
- if (yytype < YYNTOKENS)
- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
- else
- YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
-
- yy_symbol_value_print (yyoutput, yytype, yyvaluep);
- YYFPRINTF (yyoutput, ")");
-}
-
-/*------------------------------------------------------------------.
-| yy_stack_print -- Print the state stack from its BOTTOM up to its |
-| TOP (included). |
-`------------------------------------------------------------------*/
-
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
-#else
-static void
-yy_stack_print (yybottom, yytop)
- yytype_int16 *yybottom;
- yytype_int16 *yytop;
-#endif
-{
- YYFPRINTF (stderr, "Stack now");
- for (; yybottom <= yytop; yybottom++)
- {
- int yybot = *yybottom;
- YYFPRINTF (stderr, " %d", yybot);
- }
- YYFPRINTF (stderr, "\n");
-}
-
-# define YY_STACK_PRINT(Bottom, Top) \
-do { \
- if (yydebug) \
- yy_stack_print ((Bottom), (Top)); \
-} while (YYID (0))
-
-
-/*------------------------------------------------.
-| Report that the YYRULE is going to be reduced. |
-`------------------------------------------------*/
-
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
-#else
-static void
-yy_reduce_print (yyvsp, yyrule)
- YYSTYPE *yyvsp;
- int yyrule;
-#endif
-{
- int yynrhs = yyr2[yyrule];
- int yyi;
- unsigned long int yylno = yyrline[yyrule];
- YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
- yyrule - 1, yylno);
- /* The symbols being reduced. */
- for (yyi = 0; yyi < yynrhs; yyi++)
- {
- YYFPRINTF (stderr, " $%d = ", yyi + 1);
- yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
- &(yyvsp[(yyi + 1) - (yynrhs)])
- );
- YYFPRINTF (stderr, "\n");
- }
-}
-
-# define YY_REDUCE_PRINT(Rule) \
-do { \
- if (yydebug) \
- yy_reduce_print (yyvsp, Rule); \
-} while (YYID (0))
-
-/* Nonzero means print parse trace. It is left uninitialized so that
- multiple parsers can coexist. */
-int yydebug;
-#else /* !YYDEBUG */
-# define YYDPRINTF(Args)
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
-# define YY_STACK_PRINT(Bottom, Top)
-# define YY_REDUCE_PRINT(Rule)
-#endif /* !YYDEBUG */
-
-
-/* YYINITDEPTH -- initial size of the parser's stacks. */
-#ifndef YYINITDEPTH
-# define YYINITDEPTH 200
-#endif
-
-/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
- if the built-in stack extension method is used).
-
- Do not make this value too large; the results are undefined if
- YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
- evaluated with infinite-precision integer arithmetic. */
-
-#ifndef YYMAXDEPTH
-# define YYMAXDEPTH 10000
-#endif
-
-
-#if YYERROR_VERBOSE
-
-# ifndef yystrlen
-# if defined __GLIBC__ && defined _STRING_H
-# define yystrlen strlen
-# else
-/* Return the length of YYSTR. */
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static YYSIZE_T
-yystrlen (const char *yystr)
-#else
-static YYSIZE_T
-yystrlen (yystr)
- const char *yystr;
-#endif
-{
- YYSIZE_T yylen;
- for (yylen = 0; yystr[yylen]; yylen++)
- continue;
- return yylen;
-}
-# endif
-# endif
-
-# ifndef yystpcpy
-# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
-# define yystpcpy stpcpy
-# else
-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
- YYDEST. */
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static char *
-yystpcpy (char *yydest, const char *yysrc)
-#else
-static char *
-yystpcpy (yydest, yysrc)
- char *yydest;
- const char *yysrc;
-#endif
-{
- char *yyd = yydest;
- const char *yys = yysrc;
-
- while ((*yyd++ = *yys++) != '\0')
- continue;
-
- return yyd - 1;
-}
-# endif
-# endif
-
-# ifndef yytnamerr
-/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
- quotes and backslashes, so that it's suitable for yyerror. The
- heuristic is that double-quoting is unnecessary unless the string
- contains an apostrophe, a comma, or backslash (other than
- backslash-backslash). YYSTR is taken from yytname. If YYRES is
- null, do not copy; instead, return the length of what the result
- would have been. */
-static YYSIZE_T
-yytnamerr (char *yyres, const char *yystr)
-{
- if (*yystr == '"')
- {
- YYSIZE_T yyn = 0;
- char const *yyp = yystr;
-
- for (;;)
- switch (*++yyp)
- {
- case '\'':
- case ',':
- goto do_not_strip_quotes;
-
- case '\\':
- if (*++yyp != '\\')
- goto do_not_strip_quotes;
- /* Fall through. */
- default:
- if (yyres)
- yyres[yyn] = *yyp;
- yyn++;
- break;
-
- case '"':
- if (yyres)
- yyres[yyn] = '\0';
- return yyn;
- }
- do_not_strip_quotes: ;
- }
-
- if (! yyres)
- return yystrlen (yystr);
-
- return yystpcpy (yyres, yystr) - yyres;
-}
-# endif
-
-/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
- about the unexpected token YYTOKEN for the state stack whose top is
- YYSSP.
-
- Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
- not large enough to hold the message. In that case, also set
- *YYMSG_ALLOC to the required number of bytes. Return 2 if the
- required number of bytes is too large to store. */
-static int
-yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
- yytype_int16 *yyssp, int yytoken)
-{
- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
- YYSIZE_T yysize = yysize0;
- YYSIZE_T yysize1;
- enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
- /* Internationalized format string. */
- const char *yyformat = 0;
- /* Arguments of yyformat. */
- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
- /* Number of reported tokens (one for the "unexpected", one per
- "expected"). */
- int yycount = 0;
-
- /* There are many possibilities here to consider:
- - Assume YYFAIL is not used. It's too flawed to consider. See
- <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
- for details. YYERROR is fine as it does not invoke this
- function.
- - If this state is a consistent state with a default action, then
- the only way this function was invoked is if the default action
- is an error action. In that case, don't check for expected
- tokens because there are none.
- - The only way there can be no lookahead present (in yychar) is if
- this state is a consistent state with a default action. Thus,
- detecting the absence of a lookahead is sufficient to determine
- that there is no unexpected or expected token to report. In that
- case, just report a simple "syntax error".
- - Don't assume there isn't a lookahead just because this state is a
- consistent state with a default action. There might have been a
- previous inconsistent state, consistent state with a non-default
- action, or user semantic action that manipulated yychar.
- - Of course, the expected token list depends on states to have
- correct lookahead information, and it depends on the parser not
- to perform extra reductions after fetching a lookahead from the
- scanner and before detecting a syntax error. Thus, state merging
- (from LALR or IELR) and default reductions corrupt the expected
- token list. However, the list is correct for canonical LR with
- one exception: it will still contain any token that will not be
- accepted due to an error action in a later state.
- */
- if (yytoken != YYEMPTY)
- {
- int yyn = yypact[*yyssp];
- yyarg[yycount++] = yytname[yytoken];
- if (!yypact_value_is_default (yyn))
- {
- /* Start YYX at -YYN if negative to avoid negative indexes in
- YYCHECK. In other words, skip the first -YYN actions for
- this state because they are default actions. */
- int yyxbegin = yyn < 0 ? -yyn : 0;
- /* Stay within bounds of both yycheck and yytname. */
- int yychecklim = YYLAST - yyn + 1;
- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
- int yyx;
-
- for (yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
- && !yytable_value_is_error (yytable[yyx + yyn]))
- {
- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
- {
- yycount = 1;
- yysize = yysize0;
- break;
- }
- yyarg[yycount++] = yytname[yyx];
- yysize1 = yysize + yytnamerr (0, yytname[yyx]);
- if (! (yysize <= yysize1
- && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
- return 2;
- yysize = yysize1;
- }
- }
- }
-
- switch (yycount)
- {
-# define YYCASE_(N, S) \
- case N: \
- yyformat = S; \
- break
- YYCASE_(0, YY_("syntax error"));
- YYCASE_(1, YY_("syntax error, unexpected %s"));
- YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
- YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
- YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
- YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
-# undef YYCASE_
- }
-
- yysize1 = yysize + yystrlen (yyformat);
- if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
- return 2;
- yysize = yysize1;
-
- if (*yymsg_alloc < yysize)
- {
- *yymsg_alloc = 2 * yysize;
- if (! (yysize <= *yymsg_alloc
- && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
- *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
- return 1;
- }
-
- /* Avoid sprintf, as that infringes on the user's name space.
- Don't have undefined behavior even if the translation
- produced a string with the wrong number of "%s"s. */
- {
- char *yyp = *yymsg;
- int yyi = 0;
- while ((*yyp = *yyformat) != '\0')
- if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
- {
- yyp += yytnamerr (yyp, yyarg[yyi++]);
- yyformat += 2;
- }
- else
- {
- yyp++;
- yyformat++;
- }
- }
- return 0;
-}
-#endif /* YYERROR_VERBOSE */
-
-/*-----------------------------------------------.
-| Release the memory associated to this symbol. |
-`-----------------------------------------------*/
-
-/*ARGSUSED*/
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
-#else
-static void
-yydestruct (yymsg, yytype, yyvaluep)
- const char *yymsg;
- int yytype;
- YYSTYPE *yyvaluep;
-#endif
-{
- YYUSE (yyvaluep);
-
- if (!yymsg)
- yymsg = "Deleting";
- YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
-
- switch (yytype)
- {
-
- default:
- break;
- }
-}
-
-
-/* Prevent warnings from -Wmissing-prototypes. */
-#ifdef YYPARSE_PARAM
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void *YYPARSE_PARAM);
-#else
-int yyparse ();
-#endif
-#else /* ! YYPARSE_PARAM */
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
-
-
-/*----------.
-| yyparse. |
-`----------*/
-
-#ifdef YYPARSE_PARAM
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-int
-yyparse (void *YYPARSE_PARAM)
-#else
-int
-yyparse (YYPARSE_PARAM)
- void *YYPARSE_PARAM;
-#endif
-#else /* ! YYPARSE_PARAM */
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-int
-yyparse (void)
-#else
-int
-yyparse ()
-
-#endif
-#endif
-{
-/* The lookahead symbol. */
-int yychar;
-
-/* The semantic value of the lookahead symbol. */
-YYSTYPE yylval;
-
- /* Number of syntax errors so far. */
- int yynerrs;
-
- int yystate;
- /* Number of tokens to shift before error messages enabled. */
- int yyerrstatus;
-
- /* The stacks and their tools:
- `yyss': related to states.
- `yyvs': related to semantic values.
-
- Refer to the stacks thru separate pointers, to allow yyoverflow
- to reallocate them elsewhere. */
-
- /* The state stack. */
- yytype_int16 yyssa[YYINITDEPTH];
- yytype_int16 *yyss;
- yytype_int16 *yyssp;
-
- /* The semantic value stack. */
- YYSTYPE yyvsa[YYINITDEPTH];
- YYSTYPE *yyvs;
- YYSTYPE *yyvsp;
-
- YYSIZE_T yystacksize;
-
- int yyn;
- int yyresult;
- /* Lookahead token as an internal (translated) token number. */
- int yytoken;
- /* The variables used to return semantic value and location from the
- action routines. */
- YYSTYPE yyval;
-
-#if YYERROR_VERBOSE
- /* Buffer for error messages, and its allocated size. */
- char yymsgbuf[128];
- char *yymsg = yymsgbuf;
- YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
-#endif
-
-#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
-
- /* The number of symbols on the RHS of the reduced rule.
- Keep to zero when no symbol should be popped. */
- int yylen = 0;
-
- yytoken = 0;
- yyss = yyssa;
- yyvs = yyvsa;
- yystacksize = YYINITDEPTH;
-
- YYDPRINTF ((stderr, "Starting parse\n"));
-
- yystate = 0;
- yyerrstatus = 0;
- yynerrs = 0;
- yychar = YYEMPTY; /* Cause a token to be read. */
-
- /* Initialize stack pointers.
- Waste one element of value and location stack
- so that they stay on the same level as the state stack.
- The wasted elements are never initialized. */
- yyssp = yyss;
- yyvsp = yyvs;
-
- goto yysetstate;
-
-/*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate. |
-`------------------------------------------------------------*/
- yynewstate:
- /* In all cases, when you get here, the value and location stacks
- have just been pushed. So pushing a state here evens the stacks. */
- yyssp++;
-
- yysetstate:
- *yyssp = yystate;
-
- if (yyss + yystacksize - 1 <= yyssp)
- {
- /* Get the current used size of the three stacks, in elements. */
- YYSIZE_T yysize = yyssp - yyss + 1;
-
-#ifdef yyoverflow
- {
- /* Give user a chance to reallocate the stack. Use copies of
- these so that the &'s don't force the real ones into
- memory. */
- YYSTYPE *yyvs1 = yyvs;
- yytype_int16 *yyss1 = yyss;
-
- /* Each stack pointer address is followed by the size of the
- data in use in that stack, in bytes. This used to be a
- conditional around just the two extra args, but that might
- be undefined if yyoverflow is a macro. */
- yyoverflow (YY_("memory exhausted"),
- &yyss1, yysize * sizeof (*yyssp),
- &yyvs1, yysize * sizeof (*yyvsp),
- &yystacksize);
-
- yyss = yyss1;
- yyvs = yyvs1;
- }
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
- goto yyexhaustedlab;
-# else
- /* Extend the stack our own way. */
- if (YYMAXDEPTH <= yystacksize)
- goto yyexhaustedlab;
- yystacksize *= 2;
- if (YYMAXDEPTH < yystacksize)
- yystacksize = YYMAXDEPTH;
-
- {
- yytype_int16 *yyss1 = yyss;
- union yyalloc *yyptr =
- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
- if (! yyptr)
- goto yyexhaustedlab;
- YYSTACK_RELOCATE (yyss_alloc, yyss);
- YYSTACK_RELOCATE (yyvs_alloc, yyvs);
-# undef YYSTACK_RELOCATE
- if (yyss1 != yyssa)
- YYSTACK_FREE (yyss1);
- }
-# endif
-#endif /* no yyoverflow */
-
- yyssp = yyss + yysize - 1;
- yyvsp = yyvs + yysize - 1;
-
- YYDPRINTF ((stderr, "Stack size increased to %lu\n",
- (unsigned long int) yystacksize));
-
- if (yyss + yystacksize - 1 <= yyssp)
- YYABORT;
- }
-
- YYDPRINTF ((stderr, "Entering state %d\n", yystate));
-
- if (yystate == YYFINAL)
- YYACCEPT;
-
- goto yybackup;
-
-/*-----------.
-| yybackup. |
-`-----------*/
-yybackup:
-
- /* Do appropriate processing given the current state. Read a
- lookahead token if we need one and don't already have one. */
-
- /* First try to decide what to do without reference to lookahead token. */
- yyn = yypact[yystate];
- if (yypact_value_is_default (yyn))
- goto yydefault;
-
- /* Not known => get a lookahead token if don't already have one. */
-
- /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
- if (yychar == YYEMPTY)
- {
- YYDPRINTF ((stderr, "Reading a token: "));
- yychar = YYLEX;
- }
-
- if (yychar <= YYEOF)
- {
- yychar = yytoken = YYEOF;
- YYDPRINTF ((stderr, "Now at end of input.\n"));
- }
- else
- {
- yytoken = YYTRANSLATE (yychar);
- YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
- }
-
- /* If the proper action on seeing token YYTOKEN is to reduce or to
- detect an error, take that action. */
- yyn += yytoken;
- if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
- goto yydefault;
- yyn = yytable[yyn];
- if (yyn <= 0)
- {
- if (yytable_value_is_error (yyn))
- goto yyerrlab;
- yyn = -yyn;
- goto yyreduce;
- }
-
- /* Count tokens shifted since error; after three, turn off error
- status. */
- if (yyerrstatus)
- yyerrstatus--;
-
- /* Shift the lookahead token. */
- YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
-
- /* Discard the shifted token. */
- yychar = YYEMPTY;
-
- yystate = yyn;
- *++yyvsp = yylval;
-
- goto yynewstate;
-
-
-/*-----------------------------------------------------------.
-| yydefault -- do the default action for the current state. |
-`-----------------------------------------------------------*/
-yydefault:
- yyn = yydefact[yystate];
- if (yyn == 0)
- goto yyerrlab;
- goto yyreduce;
-
-
-/*-----------------------------.
-| yyreduce -- Do a reduction. |
-`-----------------------------*/
-yyreduce:
- /* yyn is the number of a rule to reduce with. */
- yylen = yyr2[yyn];
-
- /* If YYLEN is nonzero, implement the default value of the action:
- `$$ = $1'.
-
- Otherwise, the following line sets YYVAL to garbage.
- This behavior is undocumented and Bison
- users should not rely upon it. Assigning to YYVAL
- unconditionally makes the parser a bit smaller, and it avoids a
- GCC warning that YYVAL may be used uninitialized. */
- yyval = yyvsp[1-yylen];
-
-
- YY_REDUCE_PRINT (yyn);
- switch (yyn)
- {
- case 6:
-
-/* Line 1806 of yacc.c */
-#line 116 "cmDependsFortranParser.y"
- {
- free((yyvsp[(1) - (4)].string));
- }
- break;
-
- case 7:
-
-/* Line 1806 of yacc.c */
-#line 122 "cmDependsFortranParser.y"
- {
- if (cmDependsFortranParserIsKeyword((yyvsp[(1) - (2)].string), "interface"))
- {
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_SetInInterface(parser, true);
- }
- free((yyvsp[(1) - (2)].string));
- }
- break;
-
- case 8:
-
-/* Line 1806 of yacc.c */
-#line 132 "cmDependsFortranParser.y"
- {
- if (cmDependsFortranParserIsKeyword((yyvsp[(1) - (4)].string), "use"))
- {
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleUse(parser, (yyvsp[(2) - (4)].string));
- }
- else if (cmDependsFortranParserIsKeyword((yyvsp[(1) - (4)].string), "module"))
- {
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleModule(parser, (yyvsp[(2) - (4)].string));
- }
- else if (cmDependsFortranParserIsKeyword((yyvsp[(1) - (4)].string), "interface"))
- {
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_SetInInterface(parser, true);
- }
- else if (cmDependsFortranParserIsKeyword((yyvsp[(2) - (4)].string), "interface") &&
- cmDependsFortranParserIsKeyword((yyvsp[(1) - (4)].string), "end"))
- {
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_SetInInterface(parser, false);
- }
- free((yyvsp[(1) - (4)].string));
- free((yyvsp[(2) - (4)].string));
- }
- break;
-
- case 9:
-
-/* Line 1806 of yacc.c */
-#line 162 "cmDependsFortranParser.y"
- {
- if (cmDependsFortranParserIsKeyword((yyvsp[(1) - (5)].string), "use"))
- {
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleUse(parser, (yyvsp[(3) - (5)].string));
- }
- free((yyvsp[(1) - (5)].string));
- free((yyvsp[(3) - (5)].string));
- }
- break;
-
- case 10:
-
-/* Line 1806 of yacc.c */
-#line 173 "cmDependsFortranParser.y"
- {
- if (cmDependsFortranParserIsKeyword((yyvsp[(1) - (7)].string), "use") &&
- cmDependsFortranParserIsKeyword((yyvsp[(3) - (7)].string), "non_intrinsic") )
- {
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleUse(parser, (yyvsp[(5) - (7)].string));
- }
- free((yyvsp[(1) - (7)].string));
- free((yyvsp[(3) - (7)].string));
- free((yyvsp[(5) - (7)].string));
- }
- break;
-
- case 11:
-
-/* Line 1806 of yacc.c */
-#line 186 "cmDependsFortranParser.y"
- {
- if (cmDependsFortranParserIsKeyword((yyvsp[(1) - (4)].string), "include"))
- {
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleInclude(parser, (yyvsp[(2) - (4)].string));
- }
- free((yyvsp[(1) - (4)].string));
- free((yyvsp[(2) - (4)].string));
- }
- break;
-
- case 12:
-
-/* Line 1806 of yacc.c */
-#line 197 "cmDependsFortranParser.y"
- {
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleInclude(parser, (yyvsp[(1) - (3)].string));
- free((yyvsp[(1) - (3)].string));
- }
- break;
-
- case 13:
-
-/* Line 1806 of yacc.c */
-#line 204 "cmDependsFortranParser.y"
- {
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleInclude(parser, (yyvsp[(2) - (4)].string));
- free((yyvsp[(2) - (4)].string));
- }
- break;
-
- case 14:
-
-/* Line 1806 of yacc.c */
-#line 211 "cmDependsFortranParser.y"
- {
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleDefine(parser, (yyvsp[(2) - (4)].string));
- free((yyvsp[(2) - (4)].string));
- }
- break;
-
- case 15:
-
-/* Line 1806 of yacc.c */
-#line 217 "cmDependsFortranParser.y"
- {
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleUndef(parser, (yyvsp[(2) - (4)].string));
- free((yyvsp[(2) - (4)].string));
- }
- break;
-
- case 16:
-
-/* Line 1806 of yacc.c */
-#line 223 "cmDependsFortranParser.y"
- {
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleIfdef(parser, (yyvsp[(2) - (4)].string));
- free((yyvsp[(2) - (4)].string));
- }
- break;
-
- case 17:
-
-/* Line 1806 of yacc.c */
-#line 229 "cmDependsFortranParser.y"
- {
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleIfndef(parser, (yyvsp[(2) - (4)].string));
- free((yyvsp[(2) - (4)].string));
- }
- break;
-
- case 18:
-
-/* Line 1806 of yacc.c */
-#line 235 "cmDependsFortranParser.y"
- {
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleIf(parser);
- }
- break;
-
- case 19:
-
-/* Line 1806 of yacc.c */
-#line 240 "cmDependsFortranParser.y"
- {
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleElif(parser);
- }
- break;
-
- case 20:
-
-/* Line 1806 of yacc.c */
-#line 245 "cmDependsFortranParser.y"
- {
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleElse(parser);
- }
- break;
-
- case 21:
-
-/* Line 1806 of yacc.c */
-#line 250 "cmDependsFortranParser.y"
- {
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleEndif(parser);
- }
- break;
-
- case 22:
-
-/* Line 1806 of yacc.c */
-#line 255 "cmDependsFortranParser.y"
- {
- free((yyvsp[(1) - (4)].string));
- }
- break;
-
- case 47:
-
-/* Line 1806 of yacc.c */
-#line 277 "cmDependsFortranParser.y"
- { free ((yyvsp[(1) - (1)].string)); }
- break;
-
- case 48:
-
-/* Line 1806 of yacc.c */
-#line 278 "cmDependsFortranParser.y"
- { free ((yyvsp[(1) - (1)].string)); }
- break;
-
-
-
-/* Line 1806 of yacc.c */
-#line 1860 "cmDependsFortranParser.cxx"
- default: break;
- }
- /* User semantic actions sometimes alter yychar, and that requires
- that yytoken be updated with the new translation. We take the
- approach of translating immediately before every use of yytoken.
- One alternative is translating here after every semantic action,
- but that translation would be missed if the semantic action invokes
- YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
- if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
- incorrect destructor might then be invoked immediately. In the
- case of YYERROR or YYBACKUP, subsequent parser actions might lead
- to an incorrect destructor call or verbose syntax error message
- before the lookahead is translated. */
- YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
-
- YYPOPSTACK (yylen);
- yylen = 0;
- YY_STACK_PRINT (yyss, yyssp);
-
- *++yyvsp = yyval;
-
- /* Now `shift' the result of the reduction. Determine what state
- that goes to, based on the state we popped back to and the rule
- number reduced by. */
-
- yyn = yyr1[yyn];
-
- yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
- if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
- yystate = yytable[yystate];
- else
- yystate = yydefgoto[yyn - YYNTOKENS];
-
- goto yynewstate;
-
-
-/*------------------------------------.
-| yyerrlab -- here on detecting error |
-`------------------------------------*/
-yyerrlab:
- /* Make sure we have latest lookahead translation. See comments at
- user semantic actions for why this is necessary. */
- yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
-
- /* If not already recovering from an error, report this error. */
- if (!yyerrstatus)
- {
- ++yynerrs;
-#if ! YYERROR_VERBOSE
- yyerror (YY_("syntax error"));
-#else
-# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
- yyssp, yytoken)
- {
- char const *yymsgp = YY_("syntax error");
- int yysyntax_error_status;
- yysyntax_error_status = YYSYNTAX_ERROR;
- if (yysyntax_error_status == 0)
- yymsgp = yymsg;
- else if (yysyntax_error_status == 1)
- {
- if (yymsg != yymsgbuf)
- YYSTACK_FREE (yymsg);
- yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
- if (!yymsg)
- {
- yymsg = yymsgbuf;
- yymsg_alloc = sizeof yymsgbuf;
- yysyntax_error_status = 2;
- }
- else
- {
- yysyntax_error_status = YYSYNTAX_ERROR;
- yymsgp = yymsg;
- }
- }
- yyerror (yymsgp);
- if (yysyntax_error_status == 2)
- goto yyexhaustedlab;
- }
-# undef YYSYNTAX_ERROR
-#endif
- }
-
-
-
- if (yyerrstatus == 3)
- {
- /* If just tried and failed to reuse lookahead token after an
- error, discard it. */
-
- if (yychar <= YYEOF)
- {
- /* Return failure if at end of input. */
- if (yychar == YYEOF)
- YYABORT;
- }
- else
- {
- yydestruct ("Error: discarding",
- yytoken, &yylval);
- yychar = YYEMPTY;
- }
- }
-
-#if 0
- /* Else will try to reuse lookahead token after shifting the error
- token. */
- goto yyerrlab1;
-
-
-/*---------------------------------------------------.
-| yyerrorlab -- error raised explicitly by YYERROR. |
-`---------------------------------------------------*/
-yyerrorlab:
-
- /* Pacify compilers like GCC when the user code never invokes
- YYERROR and the label yyerrorlab therefore never appears in user
- code. */
- if (/*CONSTCOND*/ 0)
- goto yyerrorlab;
-
- /* Do not reclaim the symbols of the rule which action triggered
- this YYERROR. */
- YYPOPSTACK (yylen);
- yylen = 0;
- YY_STACK_PRINT (yyss, yyssp);
- yystate = *yyssp;
- goto yyerrlab1;
-
-
-/*-------------------------------------------------------------.
-| yyerrlab1 -- common code for both syntax error and YYERROR. |
-`-------------------------------------------------------------*/
-yyerrlab1:
-#endif
- yyerrstatus = 3; /* Each real token shifted decrements this. */
-
- for (;;)
- {
- yyn = yypact[yystate];
- if (!yypact_value_is_default (yyn))
- {
- yyn += YYTERROR;
- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
- {
- yyn = yytable[yyn];
- if (0 < yyn)
- break;
- }
- }
-
- /* Pop the current state because it cannot handle the error token. */
- if (yyssp == yyss)
- YYABORT;
-
-
- yydestruct ("Error: popping",
- yystos[yystate], yyvsp);
- YYPOPSTACK (1);
- yystate = *yyssp;
- YY_STACK_PRINT (yyss, yyssp);
- }
-
- *++yyvsp = yylval;
-
-
- /* Shift the error token. */
- YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
-
- yystate = yyn;
- goto yynewstate;
-
-
-/*-------------------------------------.
-| yyacceptlab -- YYACCEPT comes here. |
-`-------------------------------------*/
-yyacceptlab:
- yyresult = 0;
- goto yyreturn;
-
-/*-----------------------------------.
-| yyabortlab -- YYABORT comes here. |
-`-----------------------------------*/
-yyabortlab:
- yyresult = 1;
- goto yyreturn;
-
-#if !defined(yyoverflow) || YYERROR_VERBOSE
-/*-------------------------------------------------.
-| yyexhaustedlab -- memory exhaustion comes here. |
-`-------------------------------------------------*/
-yyexhaustedlab:
- yyerror (YY_("memory exhausted"));
- yyresult = 2;
- /* Fall through. */
-#endif
-
-yyreturn:
- if (yychar != YYEMPTY)
- {
- /* Make sure we have latest lookahead translation. See comments at
- user semantic actions for why this is necessary. */
- yytoken = YYTRANSLATE (yychar);
- yydestruct ("Cleanup: discarding lookahead",
- yytoken, &yylval);
- }
- /* Do not reclaim the symbols of the rule which action triggered
- this YYABORT or YYACCEPT. */
- YYPOPSTACK (yylen);
- YY_STACK_PRINT (yyss, yyssp);
- while (yyssp != yyss)
- {
- yydestruct ("Cleanup: popping",
- yystos[*yyssp], yyvsp);
- YYPOPSTACK (1);
- }
-#ifndef yyoverflow
- if (yyss != yyssa)
- YYSTACK_FREE (yyss);
-#endif
-#if YYERROR_VERBOSE
- if (yymsg != yymsgbuf)
- YYSTACK_FREE (yymsg);
-#endif
- /* Make sure YYID is used. */
- return YYID (yyresult);
-}
-
-
-
-/* Line 2067 of yacc.c */
-#line 286 "cmDependsFortranParser.y"
-
-/* End of grammar */
diff --git a/Source/cmDependsFortranParser.h b/Source/cmDependsFortranParser.h
deleted file mode 100644
index 399c3c8d9..000000000
--- a/Source/cmDependsFortranParser.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef cmDependsFortranParser_h
-#define cmDependsFortranParser_h
-
-#include <stddef.h> /* size_t */
-
-/* Forward declare parser object type. */
-typedef struct cmDependsFortranParser_s cmDependsFortranParser;
-
-/* Functions to enter/exit #include'd files in order. */
-bool cmDependsFortranParser_FilePush(cmDependsFortranParser* parser,
- const char* fname);
-bool cmDependsFortranParser_FilePop(cmDependsFortranParser* parser);
-
-/* Callbacks for lexer. */
-int cmDependsFortranParser_Input(cmDependsFortranParser* parser,
- char* buffer, size_t bufferSize);
-
-
-void cmDependsFortranParser_StringStart(cmDependsFortranParser* parser);
-const char* cmDependsFortranParser_StringEnd(cmDependsFortranParser* parser);
-void cmDependsFortranParser_StringAppend(cmDependsFortranParser* parser,
- char c);
-
-void cmDependsFortranParser_SetInInterface(cmDependsFortranParser* parser,
- bool is_in);
-bool cmDependsFortranParser_GetInInterface(cmDependsFortranParser* parser);
-
-
-void cmDependsFortranParser_SetInPPFalseBranch(cmDependsFortranParser* parser,
- bool is_in);
-bool cmDependsFortranParser_GetInPPFalseBranch(cmDependsFortranParser* parser);
-
-
-void cmDependsFortranParser_SetOldStartcond(cmDependsFortranParser* parser,
- int arg);
-int cmDependsFortranParser_GetOldStartcond(cmDependsFortranParser* parser);
-
-/* Callbacks for parser. */
-void cmDependsFortranParser_Error(cmDependsFortranParser* parser,
- const char* message);
-void cmDependsFortranParser_RuleUse(cmDependsFortranParser* parser,
- const char* name);
-void cmDependsFortranParser_RuleInclude(cmDependsFortranParser* parser,
- const char* name);
-void cmDependsFortranParser_RuleModule(cmDependsFortranParser* parser,
- const char* name);
-void cmDependsFortranParser_RuleDefine(cmDependsFortranParser* parser,
- const char* name);
-void cmDependsFortranParser_RuleUndef(cmDependsFortranParser* parser,
- const char* name);
-void cmDependsFortranParser_RuleIfdef(cmDependsFortranParser* parser,
- const char* name);
-void cmDependsFortranParser_RuleIfndef(cmDependsFortranParser* parser,
- const char* name);
-void cmDependsFortranParser_RuleIf(cmDependsFortranParser* parser);
-void cmDependsFortranParser_RuleElif(cmDependsFortranParser* parser);
-void cmDependsFortranParser_RuleElse(cmDependsFortranParser* parser);
-void cmDependsFortranParser_RuleEndif(cmDependsFortranParser* parser);
-
-/* Define the parser stack element type. */
-typedef union cmDependsFortran_yystype_u cmDependsFortran_yystype;
-union cmDependsFortran_yystype_u
-{
- char* string;
-};
-
-/* Setup the proper yylex interface. */
-#define YY_EXTRA_TYPE cmDependsFortranParser*
-#define YY_DECL \
-int cmDependsFortran_yylex(YYSTYPE* yylvalp, yyscan_t yyscanner)
-#define YYSTYPE cmDependsFortran_yystype
-#define YYSTYPE_IS_DECLARED 1
-#if !defined(cmDependsFortranLexer_cxx)
-# include "cmDependsFortranLexer.h"
-#endif
-#if !defined(cmDependsFortranLexer_cxx)
-#if !defined(cmDependsFortranParser_cxx)
-# undef YY_EXTRA_TYPE
-# undef YY_DECL
-# undef YYSTYPE
-# undef YYSTYPE_IS_DECLARED
-#endif
-#endif
-
-#endif
diff --git a/Source/cmDependsFortranParser.y b/Source/cmDependsFortranParser.y
deleted file mode 100644
index d814f3075..000000000
--- a/Source/cmDependsFortranParser.y
+++ /dev/null
@@ -1,288 +0,0 @@
-%{
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-/*-------------------------------------------------------------------------
- Portions of this source have been derived from makedepf90 version 2.8.8,
-
- Copyright (C) 2000--2006 Erik Edelmann <erik.edelmann@iki.fi>
-
- The code was originally distributed under the GPL but permission
- from the copyright holder has been obtained to distribute this
- derived work under the CMake license.
--------------------------------------------------------------------------*/
-
-/*
-
-This file must be translated to C and modified to build everywhere.
-
-Run bison like this:
-
- bison --yacc --name-prefix=cmDependsFortran_yy
- --defines=cmDependsFortranParserTokens.h
- -ocmDependsFortranParser.cxx
- cmDependsFortranParser.y
-
-Modify cmDependsFortranParser.cxx:
- - remove TABs
- - remove use of the 'register' storage class specifier
- - Remove the yyerrorlab block in range ["goto yyerrlab1", "yyerrlab1:"]
-*/
-
-/*-------------------------------------------------------------------------*/
-#define cmDependsFortranParser_cxx
-#include "cmDependsFortranParser.h" /* Interface to parser object. */
-#include "cmDependsFortranParserTokens.h" /* Need YYSTYPE for YY_DECL. */
-
-#include <cmsys/String.h>
-
-/* Configure the parser to use a lexer object. */
-#define YYPARSE_PARAM yyscanner
-#define YYLEX_PARAM yyscanner
-#define YYERROR_VERBOSE 1
-#define cmDependsFortran_yyerror(x) \
- cmDependsFortranError(yyscanner, x)
-
-/* Forward declare the lexer entry point. */
-YY_DECL;
-
-/* Helper function to forward error callback. */
-static void cmDependsFortranError(yyscan_t yyscanner, const char* message)
-{
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_Error(parser, message);
-}
-
-static bool cmDependsFortranParserIsKeyword(const char* word,
- const char* keyword)
-{
- return cmsysString_strcasecmp(word, keyword) == 0;
-}
-
-/* Disable some warnings in the generated code. */
-#ifdef __BORLANDC__
-# pragma warn -8004 /* Variable assigned a value that is not used. */
-# pragma warn -8008 /* condition always returns true */
-# pragma warn -8060 /* possibly incorrect assignment */
-# pragma warn -8066 /* unreachable code */
-#endif
-#ifdef _MSC_VER
-# pragma warning (disable: 4102) /* Unused goto label. */
-# pragma warning (disable: 4065) /* Switch contains default but no case. */
-# pragma warning (disable: 4701) /* Local variable may not be initialized. */
-# pragma warning (disable: 4702) /* Unreachable code. */
-# pragma warning (disable: 4127) /* Conditional expression is constant. */
-# pragma warning (disable: 4244) /* Conversion to smaller type, data loss. */
-#endif
-%}
-
-/* Generate a reentrant parser object. */
-%pure-parser
-
-%union {
- char* string;
-}
-
-/*-------------------------------------------------------------------------*/
-/* Tokens */
-%token EOSTMT ASSIGNMENT_OP GARBAGE
-%token CPP_INCLUDE F90PPR_INCLUDE COCO_INCLUDE
-%token F90PPR_DEFINE CPP_DEFINE F90PPR_UNDEF CPP_UNDEF
-%token CPP_IFDEF CPP_IFNDEF CPP_IF CPP_ELSE CPP_ELIF CPP_ENDIF
-%token F90PPR_IFDEF F90PPR_IFNDEF F90PPR_IF
-%token F90PPR_ELSE F90PPR_ELIF F90PPR_ENDIF
-%token COMMA DCOLON
-%token <string> CPP_TOENDL
-%token <number> UNTERMINATED_STRING
-%token <string> STRING WORD
-%token <string> CPP_INCLUDE_ANGLE
-
-/*-------------------------------------------------------------------------*/
-/* grammar */
-%%
-
-code: /* empty */ | code stmt;
-
-stmt: keyword_stmt | assignment_stmt;
-
-assignment_stmt: WORD ASSIGNMENT_OP other EOSTMT /* Ignore */
- {
- free($1);
- }
-
-keyword_stmt:
- WORD EOSTMT
- {
- if (cmDependsFortranParserIsKeyword($1, "interface"))
- {
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_SetInInterface(parser, true);
- }
- free($1);
- }
-| WORD WORD other EOSTMT
- {
- if (cmDependsFortranParserIsKeyword($1, "use"))
- {
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleUse(parser, $2);
- }
- else if (cmDependsFortranParserIsKeyword($1, "module"))
- {
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleModule(parser, $2);
- }
- else if (cmDependsFortranParserIsKeyword($1, "interface"))
- {
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_SetInInterface(parser, true);
- }
- else if (cmDependsFortranParserIsKeyword($2, "interface") &&
- cmDependsFortranParserIsKeyword($1, "end"))
- {
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_SetInInterface(parser, false);
- }
- free($1);
- free($2);
- }
-| WORD DCOLON WORD other EOSTMT
- {
- if (cmDependsFortranParserIsKeyword($1, "use"))
- {
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleUse(parser, $3);
- }
- free($1);
- free($3);
- }
-| WORD COMMA WORD DCOLON WORD other EOSTMT
- {
- if (cmDependsFortranParserIsKeyword($1, "use") &&
- cmDependsFortranParserIsKeyword($3, "non_intrinsic") )
- {
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleUse(parser, $5);
- }
- free($1);
- free($3);
- free($5);
- }
-| WORD STRING other EOSTMT /* Ignore */
- {
- if (cmDependsFortranParserIsKeyword($1, "include"))
- {
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleInclude(parser, $2);
- }
- free($1);
- free($2);
- }
-| CPP_INCLUDE_ANGLE other EOSTMT
- {
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleInclude(parser, $1);
- free($1);
- }
-| include STRING other EOSTMT
- {
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleInclude(parser, $2);
- free($2);
- }
-| define WORD other EOSTMT
- {
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleDefine(parser, $2);
- free($2);
- }
-| undef WORD other EOSTMT
- {
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleUndef(parser, $2);
- free($2);
- }
-| ifdef WORD other EOSTMT
- {
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleIfdef(parser, $2);
- free($2);
- }
-| ifndef WORD other EOSTMT
- {
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleIfndef(parser, $2);
- free($2);
- }
-| if other EOSTMT
- {
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleIf(parser);
- }
-| elif other EOSTMT
- {
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleElif(parser);
- }
-| else other EOSTMT
- {
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleElse(parser);
- }
-| endif other EOSTMT
- {
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleEndif(parser);
- }
-| WORD GARBAGE other EOSTMT /* Ignore */
- {
- free($1);
- }
-| GARBAGE other EOSTMT
-| EOSTMT
-| error
-;
-
-
-
-include: CPP_INCLUDE | F90PPR_INCLUDE | COCO_INCLUDE ;
-define: CPP_DEFINE | F90PPR_DEFINE;
-undef: CPP_UNDEF | F90PPR_UNDEF ;
-ifdef: CPP_IFDEF | F90PPR_IFDEF ;
-ifndef: CPP_IFNDEF | F90PPR_IFNDEF ;
-if: CPP_IF | F90PPR_IF ;
-elif: CPP_ELIF | F90PPR_ELIF ;
-else: CPP_ELSE | F90PPR_ELSE ;
-endif: CPP_ENDIF | F90PPR_ENDIF ;
-other: /* empty */ | other misc_code ;
-
-misc_code:
- WORD { free ($1); }
-| STRING { free ($1); }
-| GARBAGE
-| ASSIGNMENT_OP
-| DCOLON
-| COMMA
-| UNTERMINATED_STRING
-;
-
-%%
-/* End of grammar */
diff --git a/Source/cmDependsFortranParserTokens.h b/Source/cmDependsFortranParserTokens.h
deleted file mode 100644
index 941eda09c..000000000
--- a/Source/cmDependsFortranParserTokens.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* A Bison parser, made by GNU Bison 2.5. */
-
-/* Bison interface for Yacc-like parsers in C
-
- Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-/* As a special exception, you may create a larger work that contains
- part or all of the Bison parser skeleton and distribute that work
- under terms of your choice, so long as that work isn't itself a
- parser generator using the skeleton or a modified version thereof
- as a parser skeleton. Alternatively, if you modify or redistribute
- the parser skeleton itself, you may (at your option) remove this
- special exception, which will cause the skeleton and the resulting
- Bison output files to be licensed under the GNU General Public
- License without this special exception.
-
- This special exception was added by the Free Software Foundation in
- version 2.2 of Bison. */
-
-
-/* Tokens. */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
- /* Put the tokens into the symbol table, so that GDB and other debuggers
- know about them. */
- enum yytokentype {
- EOSTMT = 258,
- ASSIGNMENT_OP = 259,
- GARBAGE = 260,
- CPP_INCLUDE = 261,
- F90PPR_INCLUDE = 262,
- COCO_INCLUDE = 263,
- F90PPR_DEFINE = 264,
- CPP_DEFINE = 265,
- F90PPR_UNDEF = 266,
- CPP_UNDEF = 267,
- CPP_IFDEF = 268,
- CPP_IFNDEF = 269,
- CPP_IF = 270,
- CPP_ELSE = 271,
- CPP_ELIF = 272,
- CPP_ENDIF = 273,
- F90PPR_IFDEF = 274,
- F90PPR_IFNDEF = 275,
- F90PPR_IF = 276,
- F90PPR_ELSE = 277,
- F90PPR_ELIF = 278,
- F90PPR_ENDIF = 279,
- COMMA = 280,
- DCOLON = 281,
- CPP_TOENDL = 282,
- UNTERMINATED_STRING = 283,
- STRING = 284,
- WORD = 285,
- CPP_INCLUDE_ANGLE = 286
- };
-#endif
-/* Tokens. */
-#define EOSTMT 258
-#define ASSIGNMENT_OP 259
-#define GARBAGE 260
-#define CPP_INCLUDE 261
-#define F90PPR_INCLUDE 262
-#define COCO_INCLUDE 263
-#define F90PPR_DEFINE 264
-#define CPP_DEFINE 265
-#define F90PPR_UNDEF 266
-#define CPP_UNDEF 267
-#define CPP_IFDEF 268
-#define CPP_IFNDEF 269
-#define CPP_IF 270
-#define CPP_ELSE 271
-#define CPP_ELIF 272
-#define CPP_ENDIF 273
-#define F90PPR_IFDEF 274
-#define F90PPR_IFNDEF 275
-#define F90PPR_IF 276
-#define F90PPR_ELSE 277
-#define F90PPR_ELIF 278
-#define F90PPR_ENDIF 279
-#define COMMA 280
-#define DCOLON 281
-#define CPP_TOENDL 282
-#define UNTERMINATED_STRING 283
-#define STRING 284
-#define WORD 285
-#define CPP_INCLUDE_ANGLE 286
-
-
-
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-{
-
-/* Line 2068 of yacc.c */
-#line 89 "cmDependsFortranParser.y"
-
- char* string;
-
-
-
-/* Line 2068 of yacc.c */
-#line 118 "cmDependsFortranParserTokens.h"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-#endif
diff --git a/Source/cmDependsJavaLexer.cxx b/Source/cmDependsJavaLexer.cxx
index 0af44b02e..f7676d9c2 100644
--- a/Source/cmDependsJavaLexer.cxx
+++ b/Source/cmDependsJavaLexer.cxx
@@ -1591,7 +1591,7 @@ case YY_STATE_EOF(string):
"fatal flex scanner internal error--no action found" );
} /* end of action switch */
} /* end of scanning one token */
-return 0; /* this should not happen but it silences a warning*/
+return 0; /* this should not happen but it quiets some compilers */
} /* end of cmDependsJava_yylex */
/* yy_get_next_buffer - try to read in a new buffer
@@ -2330,7 +2330,7 @@ void cmDependsJava_yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner
}
/** Set the current line number.
- * @param line_number
+ * @param line_number The line number to set.
* @param yyscanner The scanner object.
*/
void cmDependsJava_yyset_lineno (int line_number , yyscan_t yyscanner)
@@ -2345,7 +2345,7 @@ void cmDependsJava_yyset_lineno (int line_number , yyscan_t yyscanner)
}
/** Set the current column.
- * @param column_no
+ * @param column_no The column number to set.
* @param yyscanner The scanner object.
*/
void cmDependsJava_yyset_column (int column_no , yyscan_t yyscanner)
diff --git a/Source/cmDependsJavaParser.cxx b/Source/cmDependsJavaParser.cxx
index 586c0debe..899f4d2c5 100644
--- a/Source/cmDependsJavaParser.cxx
+++ b/Source/cmDependsJavaParser.cxx
@@ -336,12 +336,6 @@ static void cmDependsJavaError(yyscan_t yyscanner, const char* message);
#define jpStoreClass(str) \
yyGetParser->AddClassFound(str); yyGetParser->DeallocateParserType(&(str))
/* Disable some warnings in the generated code. */
-#ifdef __BORLANDC__
-# pragma warn -8004 /* Variable assigned a value that is not used. */
-# pragma warn -8008 /* condition always returns true */
-# pragma warn -8060 /* possibly incorrect assignment */
-# pragma warn -8066 /* unreachable code */
-#endif
#ifdef _MSC_VER
# pragma warning (disable: 4102) /* Unused goto label. */
# pragma warning (disable: 4065) /* Switch statement contains default but
diff --git a/Source/cmDependsJavaParser.y b/Source/cmDependsJavaParser.y
index 944d4b5ce..b66dc6d7e 100644
--- a/Source/cmDependsJavaParser.y
+++ b/Source/cmDependsJavaParser.y
@@ -52,12 +52,6 @@ static void cmDependsJavaError(yyscan_t yyscanner, const char* message);
#define jpElementStart(cnt) yyGetParser->PrepareElement(&yyval)
#define jpStoreClass(str) yyGetParser->AddClassFound(str); yyGetParser->DeallocateParserType(&(str))
/* Disable some warnings in the generated code. */
-#ifdef __BORLANDC__
-# pragma warn -8004 /* Variable assigned a value that is not used. */
-# pragma warn -8008 /* condition always returns true */
-# pragma warn -8060 /* possibly incorrect assignment */
-# pragma warn -8066 /* unreachable code */
-#endif
#ifdef _MSC_VER
# pragma warning (disable: 4102) /* Unused goto label. */
# pragma warning (disable: 4065) /* Switch statement contains default but no case. */
diff --git a/Source/cmDependsJavaParserHelper.cxx b/Source/cmDependsJavaParserHelper.cxx
index 6136baa84..3c0232574 100644
--- a/Source/cmDependsJavaParserHelper.cxx
+++ b/Source/cmDependsJavaParserHelper.cxx
@@ -13,6 +13,7 @@
#include "cmSystemTools.h"
#include "cmDependsJavaLexer.h"
+#include <cmsys/FStream.hxx>
int cmDependsJava_yyparse( yyscan_t yyscanner );
@@ -35,10 +36,10 @@ cmDependsJavaParserHelper::~cmDependsJavaParserHelper()
}
void cmDependsJavaParserHelper::CurrentClass
-::AddFileNamesForPrinting(std::vector<cmStdString> *files,
+::AddFileNamesForPrinting(std::vector<std::string> *files,
const char* prefix, const char* sep)
{
- cmStdString rname = "";
+ std::string rname = "";
if ( prefix )
{
rname += prefix;
@@ -75,7 +76,7 @@ void cmDependsJavaParserHelper::AddClassFound(const char* sclass)
{
return;
}
- std::vector<cmStdString>::iterator it;
+ std::vector<std::string>::iterator it;
for ( it = this->ClassesFound.begin();
it != this->ClassesFound.end();
it ++ )
@@ -90,7 +91,7 @@ void cmDependsJavaParserHelper::AddClassFound(const char* sclass)
void cmDependsJavaParserHelper::AddPackagesImport(const char* sclass)
{
- std::vector<cmStdString>::iterator it;
+ std::vector<std::string>::iterator it;
for ( it = this->PackagesImport.begin();
it != this->PackagesImport.end();
it ++ )
@@ -225,7 +226,7 @@ void cmDependsJavaParserHelper::EndClass()
{
CurrentClass* parent = 0;
CurrentClass* current = 0;
- if ( this->ClassStack.size() > 0 )
+ if (!this->ClassStack.empty())
{
current = &(*(this->ClassStack.end() - 1));
if ( this->ClassStack.size() > 1 )
@@ -250,24 +251,24 @@ void cmDependsJavaParserHelper::EndClass()
void cmDependsJavaParserHelper::PrintClasses()
{
- if ( this->ClassStack.size() == 0 )
+ if (this->ClassStack.empty())
{
std::cerr << "Error when parsing. No classes on class stack" << std::endl;
abort();
}
- std::vector<cmStdString> files = this->GetFilesProduced();
- std::vector<cmStdString>::iterator sit;
+ std::vector<std::string> files = this->GetFilesProduced();
+ std::vector<std::string>::iterator sit;
for ( sit = files.begin();
sit != files.end();
++ sit )
{
- std::cout << " " << sit->c_str() << ".class" << std::endl;
+ std::cout << " " << *sit << ".class" << std::endl;
}
}
-std::vector<cmStdString> cmDependsJavaParserHelper::GetFilesProduced()
+std::vector<std::string> cmDependsJavaParserHelper::GetFilesProduced()
{
- std::vector<cmStdString> files;
+ std::vector<std::string> files;
CurrentClass* toplevel = &(*(this->ClassStack.begin()));
std::vector<CurrentClass>::iterator it;
for ( it = toplevel->NestedClasses->begin();
@@ -304,32 +305,32 @@ int cmDependsJavaParserHelper::ParseString(const char* str, int verb)
if ( verb )
{
- if ( this->CurrentPackage.size() > 0 )
+ if (!this->CurrentPackage.empty())
{
std::cout << "Current package is: " <<
- this->CurrentPackage.c_str() << std::endl;
+ this->CurrentPackage << std::endl;
}
std::cout << "Imports packages:";
- if ( this->PackagesImport.size() > 0 )
+ if (!this->PackagesImport.empty())
{
- std::vector<cmStdString>::iterator it;
+ std::vector<std::string>::iterator it;
for ( it = this->PackagesImport.begin();
it != this->PackagesImport.end();
++ it )
{
- std::cout << " " << it->c_str();
+ std::cout << " " << *it;
}
}
std::cout << std::endl;
std::cout << "Depends on:";
- if ( this->ClassesFound.size() > 0 )
+ if (!this->ClassesFound.empty())
{
- std::vector<cmStdString>::iterator it;
+ std::vector<std::string>::iterator it;
for ( it = this->ClassesFound.begin();
it != this->ClassesFound.end();
++ it )
{
- std::cout << " " << it->c_str();
+ std::cout << " " << *it;
}
}
std::cout << std::endl;
@@ -412,14 +413,14 @@ int cmDependsJavaParserHelper::ParseFile(const char* file)
{
return 0;
}
- std::ifstream ifs(file);
+ cmsys::ifstream ifs(file);
if ( !ifs )
{
return 0;
}
- cmStdString fullfile = "";
- cmStdString line;
+ std::string fullfile = "";
+ std::string line;
while ( cmSystemTools::GetLineFromStream(ifs, line) )
{
fullfile += line + "\n";
diff --git a/Source/cmDependsJavaParserHelper.h b/Source/cmDependsJavaParserHelper.h
index 9807a048c..554201894 100644
--- a/Source/cmDependsJavaParserHelper.h
+++ b/Source/cmDependsJavaParserHelper.h
@@ -59,15 +59,15 @@ public:
const char* GetCurrentCombine() { return this->CurrentCombine.c_str(); }
void UpdateCombine(const char* str1, const char* str2);
- std::vector<cmStdString>& GetClassesFound() { return this->ClassesFound; }
+ std::vector<std::string>& GetClassesFound() { return this->ClassesFound; }
- std::vector<cmStdString> GetFilesProduced();
+ std::vector<std::string> GetFilesProduced();
private:
class CurrentClass
{
public:
- cmStdString Name;
+ std::string Name;
std::vector<CurrentClass>* NestedClasses;
CurrentClass()
{
@@ -93,16 +93,16 @@ private:
{
(*this) = c;
}
- void AddFileNamesForPrinting(std::vector<cmStdString> *files,
+ void AddFileNamesForPrinting(std::vector<std::string> *files,
const char* prefix, const char* sep);
};
- cmStdString CurrentPackage;
- cmStdString::size_type InputBufferPos;
- cmStdString InputBuffer;
+ std::string CurrentPackage;
+ std::string::size_type InputBufferPos;
+ std::string InputBuffer;
std::vector<char> OutputBuffer;
- std::vector<cmStdString> ClassesFound;
- std::vector<cmStdString> PackagesImport;
- cmStdString CurrentCombine;
+ std::vector<std::string> ClassesFound;
+ std::vector<std::string> PackagesImport;
+ std::string CurrentCombine;
std::vector<CurrentClass> ClassStack;
diff --git a/Source/cmDocumentCompileDefinitions.h b/Source/cmDocumentCompileDefinitions.h
deleted file mode 100644
index d15bd6dca..000000000
--- a/Source/cmDocumentCompileDefinitions.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2011 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef cmDocumentCompileDefinitions_h
-#define cmDocumentCompileDefinitions_h
-
-#define CM_DOCUMENT_COMPILE_DEFINITIONS_DISCLAIMER \
- "Disclaimer: Most native build tools have poor support for escaping " \
- "certain values. CMake has work-arounds for many cases but some " \
- "values may just not be possible to pass correctly. If a value " \
- "does not seem to be escaped correctly, do not attempt to " \
- "work-around the problem by adding escape sequences to the value. " \
- "Your work-around may break in a future version of CMake that " \
- "has improved escape support. Instead consider defining the macro " \
- "in a (configured) header file. Then report the limitation. " \
- "Known limitations include:\n" \
- " # - broken almost everywhere\n" \
- " ; - broken in VS IDE 7.0 and Borland Makefiles\n" \
- " , - broken in VS IDE\n" \
- " % - broken in some cases in NMake\n" \
- " & | - broken in some cases on MinGW\n" \
- " ^ < > \\\" - broken in most Make tools on Windows\n" \
- "CMake does not reject these values outright because they do work " \
- "in some cases. Use with caution. "
-
-#endif
diff --git a/Source/cmDocumentGeneratorExpressions.h b/Source/cmDocumentGeneratorExpressions.h
deleted file mode 100644
index 46cd77eae..000000000
--- a/Source/cmDocumentGeneratorExpressions.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2010 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef cmDocumentGeneratorExpressions_h
-#define cmDocumentGeneratorExpressions_h
-
-#define CM_DOCUMENT_ADD_TEST_GENERATOR_EXPRESSIONS \
- "Generator expressions are evaluated during build system generation " \
- "to produce information specific to each build configuration. " \
- "Valid expressions are:\n" \
- " $<0:...> = empty string (ignores \"...\")\n" \
- " $<1:...> = content of \"...\"\n" \
- " $<CONFIG:cfg> = '1' if config is \"cfg\", else '0'\n" \
- " $<CONFIGURATION> = configuration name\n" \
- " $<BOOL:...> = '1' if the '...' is true, else '0'\n" \
- " $<STREQUAL:a,b> = '1' if a is STREQUAL b, else '0'\n" \
- " $<ANGLE-R> = A literal '>'. Used to compare " \
- "strings which contain a '>' for example.\n" \
- " $<COMMA> = A literal ','. Used to compare " \
- "strings which contain a ',' for example.\n" \
- " $<SEMICOLON> = A literal ';'. Used to prevent " \
- "list expansion on an argument with ';'.\n" \
- " $<JOIN:list,...> = joins the list with the content of " \
- "\"...\"\n" \
- " $<TARGET_NAME:...> = Marks ... as being the name of a " \
- "target. This is required if exporting targets to multiple " \
- "dependent export sets. The '...' must be a literal name of a " \
- "target- it may not contain generator expressions.\n" \
- " $<INSTALL_INTERFACE:...> = content of \"...\" when the property " \
- "is exported using install(EXPORT), and empty otherwise.\n" \
- " $<BUILD_INTERFACE:...> = content of \"...\" when the property " \
- "is exported using export(), or when the target is used by another " \
- "target in the same buildsystem. Expands to the empty string " \
- "otherwise.\n" \
- " $<C_COMPILER_ID> = The CMake-id of the C compiler " \
- "used.\n" \
- " $<C_COMPILER_ID:comp> = '1' if the CMake-id of the C " \
- "compiler matches comp, otherwise '0'.\n" \
- " $<CXX_COMPILER_ID> = The CMake-id of the CXX compiler " \
- "used.\n" \
- " $<CXX_COMPILER_ID:comp> = '1' if the CMake-id of the CXX " \
- "compiler matches comp, otherwise '0'.\n" \
- " $<VERSION_GREATER:v1,v2> = '1' if v1 is a version greater than " \
- "v2, else '0'.\n" \
- " $<VERSION_LESS:v1,v2> = '1' if v1 is a version less than v2, " \
- "else '0'.\n" \
- " $<VERSION_EQUAL:v1,v2> = '1' if v1 is the same version as v2, " \
- "else '0'.\n" \
- " $<C_COMPILER_VERSION> = The version of the C compiler used.\n" \
- " $<C_COMPILER_VERSION:ver> = '1' if the version of the C " \
- "compiler matches ver, otherwise '0'.\n" \
- " $<CXX_COMPILER_VERSION> = The version of the CXX compiler " \
- "used.\n" \
- " $<CXX_COMPILER_VERSION:ver> = '1' if the version of the CXX " \
- "compiler matches ver, otherwise '0'.\n" \
- " $<TARGET_FILE:tgt> = main file (.exe, .so.1.2, .a)\n" \
- " $<TARGET_LINKER_FILE:tgt> = file used to link (.a, .lib, .so)\n" \
- " $<TARGET_SONAME_FILE:tgt> = file with soname (.so.3)\n" \
- "where \"tgt\" is the name of a target. " \
- "Target file expressions produce a full path, but _DIR and _NAME " \
- "versions can produce the directory and file name components:\n" \
- " $<TARGET_FILE_DIR:tgt>/$<TARGET_FILE_NAME:tgt>\n" \
- " $<TARGET_LINKER_FILE_DIR:tgt>/$<TARGET_LINKER_FILE_NAME:tgt>\n" \
- " $<TARGET_SONAME_FILE_DIR:tgt>/$<TARGET_SONAME_FILE_NAME:tgt>\n" \
- "\n" \
- " $<TARGET_PROPERTY:tgt,prop> = The value of the property prop " \
- "on the target tgt.\n" \
- "Note that tgt is not added as a dependency of the target this " \
- "expression is evaluated on.\n" \
- " $<TARGET_POLICY:pol> = '1' if the policy was NEW when " \
- "the 'head' target was created, else '0'. If the policy was not " \
- "set, the warning message for the policy will be emitted. This " \
- "generator expression only works for a subset of policies.\n" \
- " $<INSTALL_PREFIX> = Content of the install prefix when " \
- "the target is exported via INSTALL(EXPORT) and empty otherwise.\n" \
- "Boolean expressions:\n" \
- " $<AND:?[,?]...> = '1' if all '?' are '1', else '0'\n" \
- " $<OR:?[,?]...> = '0' if all '?' are '0', else '1'\n" \
- " $<NOT:?> = '0' if '?' is '1', else '1'\n" \
- "where '?' is always either '0' or '1'.\n" \
- ""
-
-#define CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS \
- CM_DOCUMENT_ADD_TEST_GENERATOR_EXPRESSIONS \
- "Expressions with an implicit 'this' target:\n" \
- " $<TARGET_PROPERTY:prop> = The value of the property prop on " \
- "the target on which the generator expression is evaluated.\n" \
- ""
-
-#endif
diff --git a/Source/cmDocumentLocationUndefined.h b/Source/cmDocumentLocationUndefined.h
deleted file mode 100644
index 9aecf2163..000000000
--- a/Source/cmDocumentLocationUndefined.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2011 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef cmDocumentLocationUndefined_h
-#define cmDocumentLocationUndefined_h
-
-#define CM_LOCATION_UNDEFINED_BEHAVIOR(action) \
- "\n" \
- "Do not set properties that affect the location of a target after " \
- action ". These include properties whose names match " \
- "\"(RUNTIME|LIBRARY|ARCHIVE)_OUTPUT_(NAME|DIRECTORY)(_<CONFIG>)?\", " \
- "\"(IMPLIB_)?(PREFIX|SUFFIX)\", or \"LINKER_LANGUAGE\". " \
- "Failure to follow this rule is not diagnosed and leaves the location " \
- "of the target undefined."
-
-#endif
diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx
deleted file mode 100644
index c4f6216b6..000000000
--- a/Source/cmDocumentVariables.cxx
+++ /dev/null
@@ -1,2030 +0,0 @@
-#include "cmDocumentVariables.h"
-#include "cmake.h"
-
-#include <cmsys/ios/sstream>
-
-void cmDocumentVariables::DefineVariables(cmake* cm)
-{
- // Subsection: variables defined by cmake, that give
- // information about the project, and cmake
- cm->DefineProperty
- ("CMAKE_AR", cmProperty::VARIABLE,
- "Name of archiving tool for static libraries.",
- "This specifies the name of the program that creates archive "
- "or static libraries.",false,
- "Variables that Provide Information");
-
- cm->DefineProperty
- ("CMAKE_COMMAND", cmProperty::VARIABLE,
- "The full path to the cmake executable.",
- "This is the full path to the CMake executable cmake which is "
- "useful from custom commands that want to use the cmake -E "
- "option for portable system commands. "
- "(e.g. /usr/local/bin/cmake", false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_BINARY_DIR", cmProperty::VARIABLE,
- "The path to the top level of the build tree.",
- "This is the full path to the top level of the current CMake "
- "build tree. For an in-source build, this would be the same "
- "as CMAKE_SOURCE_DIR.", false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_SOURCE_DIR", cmProperty::VARIABLE,
- "The path to the top level of the source tree.",
- "This is the full path to the top level of the current CMake "
- "source tree. For an in-source build, this would be the same "
- "as CMAKE_BINARY_DIR.", false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_CURRENT_BINARY_DIR", cmProperty::VARIABLE,
- "The path to the binary directory currently being processed.",
- "This the full path to the build directory that is currently "
- "being processed by cmake. Each directory added by "
- "add_subdirectory will create a binary directory in the build "
- "tree, and as it is being processed this variable will be set. "
- "For in-source builds this is the current source directory "
- "being processed.", false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_CURRENT_SOURCE_DIR", cmProperty::VARIABLE,
- "The path to the source directory currently being processed.",
- "This the full path to the source directory that is currently "
- "being processed by cmake. ", false,
- "Variables that Provide Information");
-
- cm->DefineProperty
- ("CMAKE_CURRENT_LIST_FILE", cmProperty::VARIABLE,
- "Full path to the listfile currently being processed.",
- "As CMake processes the listfiles in your project this "
- "variable will always be set to the one currently being "
- "processed. "
- "The value has dynamic scope. "
- "When CMake starts processing commands in a source file "
- "it sets this variable to the location of the file. "
- "When CMake finishes processing commands from the file it "
- "restores the previous value. "
- "Therefore the value of the variable inside a macro or "
- "function is the file invoking the bottom-most entry on "
- "the call stack, not the file containing the macro or "
- "function definition."
- "\n"
- "See also CMAKE_PARENT_LIST_FILE.",false,
- "Variables that Provide Information");
-
- cm->DefineProperty
- ("CMAKE_CURRENT_LIST_LINE", cmProperty::VARIABLE,
- "The line number of the current file being processed.",
- "This is the line number of the file currently being"
- " processed by cmake.", false,
- "Variables that Provide Information");
-
- cm->DefineProperty
- ("CMAKE_CURRENT_LIST_DIR", cmProperty::VARIABLE,
- "Full directory of the listfile currently being processed.",
- "As CMake processes the listfiles in your project this "
- "variable will always be set to the directory where the listfile which "
- "is currently being processed (CMAKE_CURRENT_LIST_FILE) is located. "
- "The value has dynamic scope. "
- "When CMake starts processing commands in a source file "
- "it sets this variable to the directory where this file is located. "
- "When CMake finishes processing commands from the file it "
- "restores the previous value. "
- "Therefore the value of the variable inside a macro or "
- "function is the directory of the file invoking the bottom-most entry on "
- "the call stack, not the directory of the file containing the macro or "
- "function definition."
- "\n"
- "See also CMAKE_CURRENT_LIST_FILE.",false,
- "Variables that Provide Information");
-
- cm->DefineProperty
- ("CMAKE_SCRIPT_MODE_FILE", cmProperty::VARIABLE,
- "Full path to the -P script file currently being processed.",
- "When run in -P script mode, CMake sets this variable to the full "
- "path of the script file. When run to configure a CMakeLists.txt "
- "file, this variable is not set.", false,
- "Variables that Provide Information");
-
- cm->DefineProperty
- ("CMAKE_ARGC", cmProperty::VARIABLE,
- "Number of command line arguments passed to CMake in script mode.",
- "When run in -P script mode, CMake sets this variable to the number "
- "of command line arguments. See also CMAKE_ARGV0, 1, 2 ...", false,
- "Variables that Provide Information");
-
- cm->DefineProperty
- ("CMAKE_ARGV0", cmProperty::VARIABLE,
- "Command line argument passed to CMake in script mode.",
- "When run in -P script mode, CMake sets this variable to "
- "the first command line argument. It then also sets CMAKE_ARGV1, "
- "CMAKE_ARGV2, ... and so on, up to the number of command line arguments "
- "given. See also CMAKE_ARGC.", false,
- "Variables that Provide Information");
-
- cm->DefineProperty
- ("CMAKE_BUILD_TOOL", cmProperty::VARIABLE,
- "Tool used for the actual build process.",
- "This variable is set to the program that will be"
- " needed to build the output of CMake. If the "
- "generator selected was Visual Studio 6, the "
- "CMAKE_BUILD_TOOL will be set to msdev, for "
- "Unix Makefiles it will be set to make or gmake, "
- "and for Visual Studio 7 it set to devenv. For "
- "NMake Makefiles the value is nmake. This can be "
- "useful for adding special flags and commands based"
- " on the final build environment.", false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_CROSSCOMPILING", cmProperty::VARIABLE,
- "Is CMake currently cross compiling.",
- "This variable will be set to true by CMake if CMake is cross "
- "compiling. Specifically if the build platform is different "
- "from the target platform.", false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_CACHEFILE_DIR", cmProperty::VARIABLE,
- "The directory with the CMakeCache.txt file.",
- "This is the full path to the directory that has the "
- "CMakeCache.txt file in it. This is the same as "
- "CMAKE_BINARY_DIR.", false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_CACHE_MAJOR_VERSION", cmProperty::VARIABLE,
- "Major version of CMake used to create the CMakeCache.txt file",
- "This stores the major version of CMake used to "
- "write a CMake cache file. It is only different when "
- "a different version of CMake is run on a previously "
- "created cache file.", false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_CACHE_MINOR_VERSION", cmProperty::VARIABLE,
- "Minor version of CMake used to create the CMakeCache.txt file",
- "This stores the minor version of CMake used to "
- "write a CMake cache file. It is only different when "
- "a different version of CMake is run on a previously "
- "created cache file.", false,
- "Variables that Provide Information");
-
- cm->DefineProperty
- ("CMAKE_CACHE_PATCH_VERSION", cmProperty::VARIABLE,
- "Patch version of CMake used to create the CMakeCache.txt file",
- "This stores the patch version of CMake used to "
- "write a CMake cache file. It is only different when "
- "a different version of CMake is run on a previously "
- "created cache file.", false,
- "Variables that Provide Information");
-
- cm->DefineProperty
- ("CMAKE_CFG_INTDIR", cmProperty::VARIABLE,
- "Build-time reference to per-configuration output subdirectory.",
- "For native build systems supporting multiple configurations "
- "in the build tree (such as Visual Studio and Xcode), "
- "the value is a reference to a build-time variable specifying "
- "the name of the per-configuration output subdirectory. "
- "On Makefile generators this evaluates to \".\" because there "
- "is only one configuration in a build tree. "
- "Example values:\n"
- " $(IntDir) = Visual Studio 6\n"
- " $(OutDir) = Visual Studio 7, 8, 9\n"
- " $(Configuration) = Visual Studio 10\n"
- " $(CONFIGURATION) = Xcode\n"
- " . = Make-based tools\n"
- "Since these values are evaluated by the native build system, this "
- "variable is suitable only for use in command lines that will be "
- "evaluated at build time. "
- "Example of intended usage:\n"
- " add_executable(mytool mytool.c)\n"
- " add_custom_command(\n"
- " OUTPUT out.txt\n"
- " COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/mytool\n"
- " ${CMAKE_CURRENT_SOURCE_DIR}/in.txt out.txt\n"
- " DEPENDS mytool in.txt\n"
- " )\n"
- " add_custom_target(drive ALL DEPENDS out.txt)\n"
- "Note that CMAKE_CFG_INTDIR is no longer necessary for this purpose "
- "but has been left for compatibility with existing projects. "
- "Instead add_custom_command() recognizes executable target names in "
- "its COMMAND option, so "
- "\"${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/mytool\" can be "
- "replaced by just \"mytool\"."
- "\n"
- "This variable is read-only. Setting it is undefined behavior. "
- "In multi-configuration build systems the value of this variable "
- "is passed as the value of preprocessor symbol \"CMAKE_INTDIR\" to "
- "the compilation of all source files.",false,
- "Variables that Provide Information");
-
- cm->DefineProperty
- ("CMAKE_CTEST_COMMAND", cmProperty::VARIABLE,
- "Full path to ctest command installed with cmake.",
- "This is the full path to the CTest executable ctest "
- "which is useful from custom commands that want "
- "to use the cmake -E option for portable system "
- "commands.",false,
- "Variables that Provide Information");
-
- cm->DefineProperty
- ("CMAKE_DL_LIBS", cmProperty::VARIABLE,
- "Name of library containing dlopen and dlcose.",
- "The name of the library that has dlopen and "
- "dlclose in it, usually -ldl on most UNIX machines.",false,
- "Variables that Provide Information");
-
- cm->DefineProperty
- ("CMAKE_EDIT_COMMAND", cmProperty::VARIABLE,
- "Full path to cmake-gui or ccmake.",
- "This is the full path to the CMake executable "
- "that can graphically edit the cache. For example,"
- " cmake-gui, ccmake, or cmake -i.",false,
- "Variables that Provide Information");
-
- cm->DefineProperty
- ("CMAKE_GENERATOR", cmProperty::VARIABLE,
- "The generator used to build the project.",
- "The name of the generator that is being used to generate the "
- "build files. (e.g. \"Unix Makefiles\", "
- "\"Visual Studio 6\", etc.)",false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_EXTRA_GENERATOR", cmProperty::VARIABLE,
- "The extra generator used to build the project.",
- "When using the Eclipse, CodeBlocks or KDevelop generators, CMake "
- "generates Makefiles (CMAKE_GENERATOR) and additionally project files "
- "for the respective IDE. This IDE project file generator is stored in "
- "CMAKE_EXTRA_GENERATOR (e.g. \"Eclipse CDT4\").",false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_GENERATOR_TOOLSET", cmProperty::VARIABLE,
- "Native build system toolset name specified by user.",
- "Some CMake generators support a toolset name to be given to the "
- "native build system to choose a compiler. "
- "If the user specifies a toolset name (e.g. via the cmake -T option) "
- "the value will be available in this variable.",false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_HOME_DIRECTORY", cmProperty::VARIABLE,
- "Path to top of source tree.",
- "This is the path to the top level of the source tree.",false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_LINK_LIBRARY_SUFFIX", cmProperty::VARIABLE,
- "The suffix for libraries that you link to.",
- "The suffix to use for the end of a library filename, .lib on Windows."
- ,false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_EXECUTABLE_SUFFIX", cmProperty::VARIABLE,
- "The suffix for executables on this platform.",
- "The suffix to use for the end of an executable filename if any, "
- ".exe on Windows."
- "\n"
- "CMAKE_EXECUTABLE_SUFFIX_<LANG> overrides this for language <LANG>."
- ,false, "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_MAJOR_VERSION", cmProperty::VARIABLE,
- "The Major version of cmake (i.e. the 2 in 2.X.X)",
- "This specifies the major version of the CMake executable"
- " being run.",false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_MAKE_PROGRAM", cmProperty::VARIABLE,
- "See CMAKE_BUILD_TOOL.",
- "This variable is around for backwards compatibility, "
- "see CMAKE_BUILD_TOOL.",false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_VS_PLATFORM_TOOLSET", cmProperty::VARIABLE,
- "Visual Studio Platform Toolset name.",
- "VS 10 and above use MSBuild under the hood and support multiple "
- "compiler toolchains. "
- "CMake may specify a toolset explicitly, such as \"v110\" for "
- "VS 11 or \"Windows7.1SDK\" for 64-bit support in VS 10 Express. "
- "CMake provides the name of the chosen toolset in this variable."
- ,false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_XCODE_PLATFORM_TOOLSET", cmProperty::VARIABLE,
- "Xcode compiler selection.",
- "Xcode supports selection of a compiler from one of the installed "
- "toolsets. "
- "CMake provides the name of the chosen toolset in this variable, "
- "if any is explicitly selected (e.g. via the cmake -T option)."
- ,false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_MINOR_VERSION", cmProperty::VARIABLE,
- "The Minor version of cmake (i.e. the 4 in X.4.X).",
- "This specifies the minor version of the CMake"
- " executable being run.",false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_PATCH_VERSION", cmProperty::VARIABLE,
- "The patch version of cmake (i.e. the 3 in X.X.3).",
- "This specifies the patch version of the CMake"
- " executable being run.",false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_TWEAK_VERSION", cmProperty::VARIABLE,
- "The tweak version of cmake (i.e. the 1 in X.X.X.1).",
- "This specifies the tweak version of the CMake executable being run. "
- "Releases use tweak < 20000000 and development versions use the date "
- "format CCYYMMDD for the tweak level."
- ,false, "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_VERSION", cmProperty::VARIABLE,
- "The full version of cmake in major.minor.patch[.tweak[-id]] format.",
- "This specifies the full version of the CMake executable being run. "
- "This variable is defined by versions 2.6.3 and higher. "
- "See variables CMAKE_MAJOR_VERSION, CMAKE_MINOR_VERSION, "
- "CMAKE_PATCH_VERSION, and CMAKE_TWEAK_VERSION "
- "for individual version components. "
- "The [-id] component appears in non-release versions "
- "and may be arbitrary text.", false,
- "Variables that Provide Information");
-
- cm->DefineProperty
- ("CMAKE_PARENT_LIST_FILE", cmProperty::VARIABLE,
- "Full path to the CMake file that included the current one.",
- "While processing a CMake file loaded by include() or find_package() "
- "this variable contains the full path to the file including it. "
- "The top of the include stack is always the CMakeLists.txt for the "
- "current directory. "
- "See also CMAKE_CURRENT_LIST_FILE.",false,
- "Variables that Provide Information");
-
- cm->DefineProperty
- ("CMAKE_PROJECT_NAME", cmProperty::VARIABLE,
- "The name of the current project.",
- "This specifies name of the current project from"
- " the closest inherited PROJECT command.",false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_RANLIB", cmProperty::VARIABLE,
- "Name of randomizing tool for static libraries.",
- "This specifies name of the program that randomizes "
- "libraries on UNIX, not used on Windows, but may be present.",false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_ROOT", cmProperty::VARIABLE,
- "Install directory for running cmake.",
- "This is the install root for the running CMake and"
- " the Modules directory can be found here. This is"
- " commonly used in this format: ${CMAKE_ROOT}/Modules",false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_SIZEOF_VOID_P", cmProperty::VARIABLE,
- "Size of a void pointer.",
- "This is set to the size of a pointer on the machine, "
- "and is determined by a try compile. If a 64 bit size "
- "is found, then the library search path is modified to "
- "look for 64 bit libraries first.",false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_SKIP_RPATH", cmProperty::VARIABLE,
- "If true, do not add run time path information.",
- "If this is set to TRUE, then the rpath information "
- "is not added to compiled executables. The default "
- "is to add rpath information if the platform supports it. "
- "This allows for easy running from the build tree. To omit RPATH "
- "in the install step, but not the build step, use "
- "CMAKE_SKIP_INSTALL_RPATH instead.",false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_SOURCE_DIR", cmProperty::VARIABLE,
- "Source directory for project.",
- "This is the top level source directory for the project. "
- "It corresponds to the source directory given to "
- "cmake-gui or ccmake.",false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_STANDARD_LIBRARIES", cmProperty::VARIABLE,
- "Libraries linked into every executable and shared library.",
- "This is the list of libraries that are linked "
- "into all executables and libraries.",false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_VERBOSE_MAKEFILE", cmProperty::VARIABLE,
- "Create verbose makefiles if on.",
- "This variable defaults to false. You can set "
- "this variable to true to make CMake produce verbose "
- "makefiles that show each command line as it is used.",false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("PROJECT_BINARY_DIR", cmProperty::VARIABLE,
- "Full path to build directory for project.",
- "This is the binary directory of the most recent "
- "PROJECT command.",false,"Variables that Provide Information");
- cm->DefineProperty
- ("PROJECT_NAME", cmProperty::VARIABLE,
- "Name of the project given to the project command.",
- "This is the name given to the most "
- "recent PROJECT command.",false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("PROJECT_SOURCE_DIR", cmProperty::VARIABLE,
- "Top level source directory for the current project.",
- "This is the source directory of the most recent "
- "PROJECT command.",false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("[Project name]_BINARY_DIR", cmProperty::VARIABLE,
- "Top level binary directory for the named project.",
- "A variable is created with the name used in the PROJECT "
- "command, and is the binary directory for the project. "
- " This can be useful when SUBDIR is used to connect "
- "several projects.",false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("[Project name]_SOURCE_DIR", cmProperty::VARIABLE,
- "Top level source directory for the named project.",
- "A variable is created with the name used in the PROJECT "
- "command, and is the source directory for the project."
- " This can be useful when add_subdirectory "
- "is used to connect several projects.",false,
- "Variables that Provide Information");
-
- cm->DefineProperty
- ("CMAKE_IMPORT_LIBRARY_PREFIX", cmProperty::VARIABLE,
- "The prefix for import libraries that you link to.",
- "The prefix to use for the name of an import library if used "
- "on this platform."
- "\n"
- "CMAKE_IMPORT_LIBRARY_PREFIX_<LANG> overrides this for language <LANG>."
- ,false, "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_IMPORT_LIBRARY_SUFFIX", cmProperty::VARIABLE,
- "The suffix for import libraries that you link to.",
- "The suffix to use for the end of an import library filename if used "
- "on this platform."
- "\n"
- "CMAKE_IMPORT_LIBRARY_SUFFIX_<LANG> overrides this for language <LANG>."
- ,false, "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_SHARED_LIBRARY_PREFIX", cmProperty::VARIABLE,
- "The prefix for shared libraries that you link to.",
- "The prefix to use for the name of a shared library, lib on UNIX."
- "\n"
- "CMAKE_SHARED_LIBRARY_PREFIX_<LANG> overrides this for language <LANG>."
- ,false, "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_SHARED_LIBRARY_SUFFIX", cmProperty::VARIABLE,
- "The suffix for shared libraries that you link to.",
- "The suffix to use for the end of a shared library filename, "
- ".dll on Windows."
- "\n"
- "CMAKE_SHARED_LIBRARY_SUFFIX_<LANG> overrides this for language <LANG>."
- ,false, "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_SHARED_MODULE_PREFIX", cmProperty::VARIABLE,
- "The prefix for loadable modules that you link to.",
- "The prefix to use for the name of a loadable module on this platform."
- "\n"
- "CMAKE_SHARED_MODULE_PREFIX_<LANG> overrides this for language <LANG>."
- ,false, "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_SHARED_MODULE_SUFFIX", cmProperty::VARIABLE,
- "The suffix for shared libraries that you link to.",
- "The suffix to use for the end of a loadable module filename "
- "on this platform"
- "\n"
- "CMAKE_SHARED_MODULE_SUFFIX_<LANG> overrides this for language <LANG>."
- ,false, "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_STATIC_LIBRARY_PREFIX", cmProperty::VARIABLE,
- "The prefix for static libraries that you link to.",
- "The prefix to use for the name of a static library, lib on UNIX."
- "\n"
- "CMAKE_STATIC_LIBRARY_PREFIX_<LANG> overrides this for language <LANG>."
- ,false, "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_STATIC_LIBRARY_SUFFIX", cmProperty::VARIABLE,
- "The suffix for static libraries that you link to.",
- "The suffix to use for the end of a static library filename, "
- ".lib on Windows."
- "\n"
- "CMAKE_STATIC_LIBRARY_SUFFIX_<LANG> overrides this for language <LANG>."
- ,false, "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES", cmProperty::VARIABLE,
- "Additional suffixes for shared libraries.",
- "Extensions for shared libraries other than that specified by "
- "CMAKE_SHARED_LIBRARY_SUFFIX, if any. "
- "CMake uses this to recognize external shared library files during "
- "analysis of libraries linked by a target.",
- false,
- "Variables that Provide Information");
- cm->DefineProperty
- ("CMAKE_MINIMUM_REQUIRED_VERSION", cmProperty::VARIABLE,
- "Version specified to cmake_minimum_required command",
- "Variable containing the VERSION component specified in the "
- "cmake_minimum_required command.",
- false,
- "Variables that Provide Information");
-
-
- // Variables defined by cmake, that change the behavior
- // of cmake
-
- cm->DefineProperty
- ("CMAKE_POLICY_DEFAULT_CMP<NNNN>", cmProperty::VARIABLE,
- "Default for CMake Policy CMP<NNNN> when it is otherwise left unset.",
- "Commands cmake_minimum_required(VERSION) and cmake_policy(VERSION) "
- "by default leave policies introduced after the given version unset. "
- "Set CMAKE_POLICY_DEFAULT_CMP<NNNN> to OLD or NEW to specify the "
- "default for policy CMP<NNNN>, where <NNNN> is the policy number."
- "\n"
- "This variable should not be set by a project in CMake code; "
- "use cmake_policy(SET) instead. "
- "Users running CMake may set this variable in the cache "
- "(e.g. -DCMAKE_POLICY_DEFAULT_CMP<NNNN>=<OLD|NEW>) "
- "to set a policy not otherwise set by the project. "
- "Set to OLD to quiet a policy warning while using old behavior "
- "or to NEW to try building the project with new behavior.",
- false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_AUTOMOC_RELAXED_MODE", cmProperty::VARIABLE,
- "Switch between strict and relaxed automoc mode.",
- "By default, automoc behaves exactly as described in the documentation "
- "of the AUTOMOC target property. "
- "When set to TRUE, it accepts more input and tries to find the correct "
- "input file for moc even if it differs from the documented behaviour. "
- "In this mode it e.g. also checks whether a header file is intended to "
- "be processed by moc when a \"foo.moc\" file has been included.\n"
- "Relaxed mode has to be enabled for KDE4 compatibility.",
- false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME", cmProperty::VARIABLE,
- "Default component used in install() commands.",
- "If an install() command is used without the COMPONENT argument, "
- "these files will be grouped into a default component. The name of this "
- "default install component will be taken from this variable. "
- "It defaults to \"Unspecified\".",
- false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_FIND_LIBRARY_PREFIXES", cmProperty::VARIABLE,
- "Prefixes to prepend when looking for libraries.",
- "This specifies what prefixes to add to library names when "
- "the find_library command looks for libraries. On UNIX "
- "systems this is typically lib, meaning that when trying "
- "to find the foo library it will look for libfoo.",
- false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_FIND_LIBRARY_SUFFIXES", cmProperty::VARIABLE,
- "Suffixes to append when looking for libraries.",
- "This specifies what suffixes to add to library names when "
- "the find_library command looks for libraries. On Windows "
- "systems this is typically .lib and .dll, meaning that when trying "
- "to find the foo library it will look for foo.dll etc.",
- false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_CONFIGURATION_TYPES", cmProperty::VARIABLE,
- "Specifies the available build types on multi-config generators.",
- "This specifies what build types (configurations) will be available "
- "such as Debug, Release, RelWithDebInfo etc. "
- "This has reasonable defaults on most platforms, "
- "but can be extended to provide other build types. "
- "See also CMAKE_BUILD_TYPE for details of managing configuration data, "
- "and CMAKE_CFG_INTDIR."
- ,false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_BUILD_TYPE", cmProperty::VARIABLE,
- "Specifies the build type on single-configuration generators.",
- "This statically specifies what build type (configuration) "
- "will be built in this build tree. Possible values are "
- "empty, Debug, Release, RelWithDebInfo and MinSizeRel. "
- "This variable is only meaningful to single-configuration generators "
- "(such as make and Ninja) i.e. "
- "those which choose a single configuration "
- "when CMake runs to generate a build tree as opposed to "
- "multi-configuration generators which offer selection of the build "
- "configuration within the generated build environment. "
- "There are many per-config properties and variables "
- "(usually following clean SOME_VAR_<CONFIG> order conventions), "
- "such as CMAKE_C_FLAGS_<CONFIG>, specified as uppercase: "
- "CMAKE_C_FLAGS_[DEBUG|RELEASE|RELWITHDEBINFO|MINSIZEREL]. "
- "For example, in a build tree configured "
- "to build type Debug, CMake will see to having "
- "CMAKE_C_FLAGS_DEBUG settings get added to the CMAKE_C_FLAGS settings. "
- "See also CMAKE_CONFIGURATION_TYPES."
- ,false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_BACKWARDS_COMPATIBILITY", cmProperty::VARIABLE,
- "Version of cmake required to build project",
- "From the point of view of backwards compatibility, this "
- "specifies what version of CMake should be supported. By "
- "default this value is the version number of CMake that "
- "you are running. You can set this to an older version of"
- " CMake to support deprecated commands of CMake in projects"
- " that were written to use older versions of CMake. This "
- "can be set by the user or set at the beginning of a "
- "CMakeLists file.",false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_INSTALL_PREFIX", cmProperty::VARIABLE,
- "Install directory used by install.",
- "If \"make install\" is invoked or INSTALL is built"
- ", this directory is prepended onto all install "
- "directories. This variable defaults to /usr/local"
- " on UNIX and c:/Program Files on Windows.\n"
- "On UNIX one can use the DESTDIR mechanism in order"
- " to relocate the whole installation. "
- "DESTDIR means DESTination DIRectory. It is "
- "commonly used by makefile users "
- "in order to install software at non-default location. "
- "It is usually invoked like this:\n"
- " make DESTDIR=/home/john install\n"
- "which will install the concerned software using the"
- " installation prefix, e.g. \"/usr/local\" prepended with "
- "the DESTDIR value which finally gives \"/home/john/usr/local\".\n"
- "WARNING: DESTDIR may not be used on Windows because installation"
- " prefix usually contains a drive letter like in \"C:/Program Files\""
- " which cannot be prepended with some other prefix."
- "\n"
- "The installation prefix is also added to CMAKE_SYSTEM_PREFIX_PATH "
- "so that find_package, find_program, find_library, find_path, and "
- "find_file will search the prefix for other software."
- ,false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_SKIP_INSTALL_ALL_DEPENDENCY", cmProperty::VARIABLE,
- "Don't make the install target depend on the all target.",
- "By default, the \"install\" target depends on the \"all\" target. "
- "This has the effect, that when \"make install\" is invoked or INSTALL "
- "is built, first the \"all\" target is built, then the installation "
- "starts. "
- "If CMAKE_SKIP_INSTALL_ALL_DEPENDENCY is set to TRUE, this dependency "
- "is not created, so the installation process will start immediately, "
- "independent from whether the project has been completely built or not."
- ,false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_MODULE_PATH", cmProperty::VARIABLE,
- "List of directories to search for CMake modules.",
- "Commands like include() and find_package() search for files in "
- "directories listed by this variable before checking the default "
- "modules that come with CMake.",
- false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_WARN_DEPRECATED", cmProperty::VARIABLE,
- "Whether to issue deprecation warnings for macros and functions.",
- "If TRUE, this can be used by macros and functions to issue "
- "deprecation warnings. This variable is FALSE by default.",
- false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_ERROR_DEPRECATED", cmProperty::VARIABLE,
- "Whether to issue deprecation errors for macros and functions.",
- "If TRUE, this can be used by macros and functions to issue "
- "fatal errors when deprecated macros or functions are used. This "
- "variable is FALSE by default.",
- false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_PREFIX_PATH", cmProperty::VARIABLE,
- "Path used for searching by FIND_XXX(), with appropriate suffixes added.",
- "Specifies a path which will be used by the FIND_XXX() commands. It "
- "contains the \"base\" directories, the FIND_XXX() commands append "
- "appropriate subdirectories to the base directories. So FIND_PROGRAM() "
- "adds /bin to each of the directories in the path, FIND_LIBRARY() "
- "appends /lib to each of the directories, and FIND_PATH() and "
- "FIND_FILE() append /include . By default it is empty, it is intended "
- "to be set by the project. See also CMAKE_SYSTEM_PREFIX_PATH, "
- "CMAKE_INCLUDE_PATH, CMAKE_LIBRARY_PATH, CMAKE_PROGRAM_PATH.", false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_INCLUDE_PATH", cmProperty::VARIABLE,
- "Path used for searching by FIND_FILE() and FIND_PATH().",
- "Specifies a path which will be used both by FIND_FILE() and "
- "FIND_PATH(). Both commands will check each of the contained directories "
- "for the existence of the file which is currently searched. By default "
- "it is empty, it is intended to be set by the project. See also "
- "CMAKE_SYSTEM_INCLUDE_PATH, CMAKE_PREFIX_PATH.", false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_LIBRARY_PATH", cmProperty::VARIABLE,
- "Path used for searching by FIND_LIBRARY().",
- "Specifies a path which will be used by FIND_LIBRARY(). FIND_LIBRARY() "
- "will check each of the contained directories for the existence of the "
- "library which is currently searched. By default it is empty, it is "
- "intended to be set by the project. See also CMAKE_SYSTEM_LIBRARY_PATH, "
- "CMAKE_PREFIX_PATH.", false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_PROGRAM_PATH", cmProperty::VARIABLE,
- "Path used for searching by FIND_PROGRAM().",
- "Specifies a path which will be used by FIND_PROGRAM(). FIND_PROGRAM() "
- "will check each of the contained directories for the existence of the "
- "program which is currently searched. By default it is empty, it is "
- "intended to be set by the project. See also CMAKE_SYSTEM_PROGRAM_PATH, "
- " CMAKE_PREFIX_PATH.", false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_SYSTEM_PREFIX_PATH", cmProperty::VARIABLE,
- "Path used for searching by FIND_XXX(), with appropriate suffixes added.",
- "Specifies a path which will be used by the FIND_XXX() commands. It "
- "contains the \"base\" directories, the FIND_XXX() commands append "
- "appropriate subdirectories to the base directories. So FIND_PROGRAM() "
- "adds /bin to each of the directories in the path, FIND_LIBRARY() "
- "appends /lib to each of the directories, and FIND_PATH() and "
- "FIND_FILE() append /include . By default this contains the standard "
- "directories for the current system and the CMAKE_INSTALL_PREFIX. "
- "It is NOT intended "
- "to be modified by the project, use CMAKE_PREFIX_PATH for this. See also "
- "CMAKE_SYSTEM_INCLUDE_PATH, CMAKE_SYSTEM_LIBRARY_PATH, "
- "CMAKE_SYSTEM_PROGRAM_PATH, and CMAKE_SYSTEM_IGNORE_PATH.", false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_SYSTEM_IGNORE_PATH", cmProperty::VARIABLE,
- "Path to be ignored by FIND_XXX() commands.",
- "Specifies directories to be ignored by searches in FIND_XXX() "
- "commands. "
- "This is useful in cross-compiled environments where some system "
- "directories contain incompatible but possibly linkable libraries. For "
- "example, on cross-compiled cluster environments, this allows a user to "
- "ignore directories containing libraries meant for the front-end "
- "machine that modules like FindX11 (and others) would normally search. "
- "By default this contains a list of directories containing incompatible "
- "binaries for the host system. "
- "See also CMAKE_SYSTEM_PREFIX_PATH, CMAKE_SYSTEM_LIBRARY_PATH, "
- "CMAKE_SYSTEM_INCLUDE_PATH, and CMAKE_SYSTEM_PROGRAM_PATH.", false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_IGNORE_PATH", cmProperty::VARIABLE,
- "Path to be ignored by FIND_XXX() commands.",
- "Specifies directories to be ignored by searches in FIND_XXX() "
- "commands. "
- "This is useful in cross-compiled environments where some system "
- "directories contain incompatible but possibly linkable libraries. For "
- "example, on cross-compiled cluster environments, this allows a user to "
- "ignore directories containing libraries meant for the front-end "
- "machine that modules like FindX11 (and others) would normally search. "
- "By default this is empty; it is intended to be set by the project. "
- "Note that CMAKE_IGNORE_PATH takes a list of directory names, NOT a "
- "list of prefixes. If you want to ignore paths under prefixes (bin, "
- "include, lib, etc.), you'll need to specify them explicitly. "
- "See also CMAKE_PREFIX_PATH, CMAKE_LIBRARY_PATH, CMAKE_INCLUDE_PATH, "
- "CMAKE_PROGRAM_PATH.", false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_SYSTEM_INCLUDE_PATH", cmProperty::VARIABLE,
- "Path used for searching by FIND_FILE() and FIND_PATH().",
- "Specifies a path which will be used both by FIND_FILE() and "
- "FIND_PATH(). Both commands will check each of the contained directories "
- "for the existence of the file which is currently searched. By default "
- "it contains the standard directories for the current system. It is "
- "NOT intended to be modified by the project, use CMAKE_INCLUDE_PATH "
- "for this. See also CMAKE_SYSTEM_PREFIX_PATH.", false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_SYSTEM_LIBRARY_PATH", cmProperty::VARIABLE,
- "Path used for searching by FIND_LIBRARY().",
- "Specifies a path which will be used by FIND_LIBRARY(). FIND_LIBRARY() "
- "will check each of the contained directories for the existence of the "
- "library which is currently searched. By default it contains the "
- "standard directories for the current system. It is NOT intended to be "
- "modified by the project, use CMAKE_LIBRARY_PATH for this. See "
- "also CMAKE_SYSTEM_PREFIX_PATH.", false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_SYSTEM_PROGRAM_PATH", cmProperty::VARIABLE,
- "Path used for searching by FIND_PROGRAM().",
- "Specifies a path which will be used by FIND_PROGRAM(). FIND_PROGRAM() "
- "will check each of the contained directories for the existence of the "
- "program which is currently searched. By default it contains the "
- "standard directories for the current system. It is NOT intended to be "
- "modified by the project, use CMAKE_PROGRAM_PATH for this. See also "
- "CMAKE_SYSTEM_PREFIX_PATH.", false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_DISABLE_FIND_PACKAGE_<PackageName>", cmProperty::VARIABLE,
- "Variable for disabling find_package() calls.",
- "Every non-REQUIRED find_package() call in a project can be disabled "
- "by setting the variable CMAKE_DISABLE_FIND_PACKAGE_<PackageName> to "
- "TRUE. This can be used to build a project without an optional package, "
- "although that package is installed.\n"
- "This switch should be used during the initial CMake run. Otherwise if "
- "the package has already been found in a previous CMake run, the "
- "variables which have been stored in the cache will still be there. "
- "In that case it is recommended to remove the cache variables for "
- "this package from the cache using the cache editor or cmake -U", false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_FIND_PACKAGE_WARN_NO_MODULE", cmProperty::VARIABLE,
- "Tell find_package to warn if called without an explicit mode.",
- "If find_package is called without an explicit mode option "
- "(MODULE, CONFIG or NO_MODULE) and no Find<pkg>.cmake module is "
- "in CMAKE_MODULE_PATH then CMake implicitly assumes that the "
- "caller intends to search for a package configuration file. "
- "If no package configuration file is found then the wording "
- "of the failure message must account for both the case that the "
- "package is really missing and the case that the project has a "
- "bug and failed to provide the intended Find module. "
- "If instead the caller specifies an explicit mode option then "
- "the failure message can be more specific."
- "\n"
- "Set CMAKE_FIND_PACKAGE_WARN_NO_MODULE to TRUE to tell find_package "
- "to warn when it implicitly assumes Config mode. "
- "This helps developers enforce use of an explicit mode in all calls "
- "to find_package within a project.", false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_USER_MAKE_RULES_OVERRIDE", cmProperty::VARIABLE,
- "Specify a CMake file that overrides platform information.",
- "CMake loads the specified file while enabling support for each "
- "language from either the project() or enable_language() commands. "
- "It is loaded after CMake's builtin compiler and platform information "
- "modules have been loaded but before the information is used. "
- "The file may set platform information variables to override CMake's "
- "defaults."
- "\n"
- "This feature is intended for use only in overriding information "
- "variables that must be set before CMake builds its first test "
- "project to check that the compiler for a language works. "
- "It should not be used to load a file in cases that a normal include() "
- "will work. "
- "Use it only as a last resort for behavior that cannot be achieved "
- "any other way. "
- "For example, one may set CMAKE_C_FLAGS_INIT to change the default "
- "value used to initialize CMAKE_C_FLAGS before it is cached. "
- "The override file should NOT be used to set anything that could "
- "be set after languages are enabled, such as variables like "
- "CMAKE_RUNTIME_OUTPUT_DIRECTORY that affect the placement of binaries. "
- "Information set in the file will be used for try_compile and try_run "
- "builds too."
- ,false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("BUILD_SHARED_LIBS", cmProperty::VARIABLE,
- "Global flag to cause add_library to create shared libraries if on.",
- "If present and true, this will cause all libraries to be "
- "built shared unless the library was explicitly added as a "
- "static library. This variable is often added to projects "
- "as an OPTION so that each user of a project can decide if "
- "they want to build the project using shared or static "
- "libraries.",false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_NOT_USING_CONFIG_FLAGS", cmProperty::VARIABLE,
- "Skip _BUILD_TYPE flags if true.",
- "This is an internal flag used by the generators in "
- "CMake to tell CMake to skip the _BUILD_TYPE flags.",false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_MFC_FLAG", cmProperty::VARIABLE,
- "Tell cmake to use MFC for an executable or dll.",
- "This can be set in a CMakeLists.txt file and will "
- "enable MFC in the application. It should be set "
- "to 1 for the static MFC library, and 2 for "
- "the shared MFC library. This is used in Visual "
- "Studio 6 and 7 project files. The CMakeSetup "
- "dialog used MFC and the CMakeLists.txt looks like this:\n"
- " add_definitions(-D_AFXDLL)\n"
- " set(CMAKE_MFC_FLAG 2)\n"
- " add_executable(CMakeSetup WIN32 ${SRCS})\n",false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_COLOR_MAKEFILE", cmProperty::VARIABLE,
- "Enables color output when using the Makefile generator.",
- "When enabled, the generated Makefiles will produce colored output. "
- "Default is ON.",false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_ABSOLUTE_DESTINATION_FILES", cmProperty::VARIABLE,
- "List of files which have been installed using "
- " an ABSOLUTE DESTINATION path.",
- "This variable is defined by CMake-generated cmake_install.cmake "
- "scripts."
- " It can be used (read-only) by programs or scripts that source those"
- " install scripts. This is used by some CPack generators (e.g. RPM).",
- false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION", cmProperty::VARIABLE,
- "Ask cmake_install.cmake script to warn each time a file with "
- "absolute INSTALL DESTINATION is encountered.",
- "This variable is used by CMake-generated cmake_install.cmake"
- " scripts. If one sets this variable to ON while running the"
- " script, it may get warning messages from the script.", false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION", cmProperty::VARIABLE,
- "Ask cmake_install.cmake script to error out as soon as "
- "a file with absolute INSTALL DESTINATION is encountered.",
- "The fatal error is emitted before the installation of "
- "the offending file takes place."
- " This variable is used by CMake-generated cmake_install.cmake"
- " scripts. If one sets this variable to ON while running the"
- " script, it may get fatal error messages from the script.",false,
- "Variables That Change Behavior");
-
- cm->DefineProperty
- ("CMAKE_DEBUG_TARGET_PROPERTIES", cmProperty::VARIABLE,
- "Enables tracing output for target properties.",
- "This variable can be populated with a list of properties to generate "
- "debug output for when evaluating target properties. Currently it can "
- "only be used when evaluating the INCLUDE_DIRECTORIES, "
- "COMPILE_DEFINITIONS and COMPILE_OPTIONS target properties. "
- "In that case, it outputs a backtrace for each entry in the target "
- "property. Default is unset.", false, "Variables That Change Behavior");
-
- // Variables defined by CMake that describe the system
-
- cm->DefineProperty
- ("CMAKE_SYSTEM", cmProperty::VARIABLE,
- "Name of system cmake is compiling for.",
- "This variable is the composite of CMAKE_SYSTEM_NAME "
- "and CMAKE_SYSTEM_VERSION, like this "
- "${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_VERSION}. "
- "If CMAKE_SYSTEM_VERSION is not set, then "
- "CMAKE_SYSTEM is the same as CMAKE_SYSTEM_NAME.",false,
- "Variables That Describe the System");
- cm->DefineProperty
- ("CMAKE_SYSTEM_NAME", cmProperty::VARIABLE,
- "Name of the OS CMake is building for.",
- "This is the name of the operating system on "
- "which CMake is targeting. On systems that "
- "have the uname command, this variable is set "
- "to the output of uname -s. Linux, Windows, "
- " and Darwin for Mac OS X are the values found "
- " on the big three operating systems." ,false,
- "Variables That Describe the System");
- cm->DefineProperty
- ("CMAKE_SYSTEM_PROCESSOR", cmProperty::VARIABLE,
- "The name of the CPU CMake is building for.",
- "On systems that support uname, this variable is "
- "set to the output of uname -p, on windows it is "
- "set to the value of the environment variable "
- "PROCESSOR_ARCHITECTURE",false,
- "Variables That Describe the System");
- cm->DefineProperty
- ("CMAKE_SYSTEM_VERSION", cmProperty::VARIABLE,
- "OS version CMake is building for.",
- "A numeric version string for the system, on "
- "systems that support uname, this variable is "
- "set to the output of uname -r. On other "
- "systems this is set to major-minor version numbers.",false,
- "Variables That Describe the System");
- cm->DefineProperty
- ("CMAKE_LIBRARY_ARCHITECTURE", cmProperty::VARIABLE,
- "Target architecture library directory name, if detected.",
- "This is the value of CMAKE_<lang>_LIBRARY_ARCHITECTURE as "
- "detected for one of the enabled languages.",false,
- "Variables That Describe the System");
- cm->DefineProperty
- ("CMAKE_LIBRARY_ARCHITECTURE_REGEX", cmProperty::VARIABLE,
- "Regex matching possible target architecture library directory names.",
- "This is used to detect CMAKE_<lang>_LIBRARY_ARCHITECTURE from the "
- "implicit linker search path by matching the <arch> name.",false,
- "Variables That Describe the System");
-
- cm->DefineProperty
- ("CMAKE_HOST_SYSTEM", cmProperty::VARIABLE,
- "Name of system cmake is being run on.",
- "The same as CMAKE_SYSTEM but for the host system instead "
- "of the target system when cross compiling.",false,
- "Variables That Describe the System");
- cm->DefineProperty
- ("CMAKE_HOST_SYSTEM_NAME", cmProperty::VARIABLE,
- "Name of the OS CMake is running on.",
- "The same as CMAKE_SYSTEM_NAME but for the host system instead "
- "of the target system when cross compiling.",false,
- "Variables That Describe the System");
- cm->DefineProperty
- ("CMAKE_HOST_SYSTEM_PROCESSOR", cmProperty::VARIABLE,
- "The name of the CPU CMake is running on.",
- "The same as CMAKE_SYSTEM_PROCESSOR but for the host system instead "
- "of the target system when cross compiling.",false,
- "Variables That Describe the System");
- cm->DefineProperty
- ("CMAKE_HOST_SYSTEM_VERSION", cmProperty::VARIABLE,
- "OS version CMake is running on.",
- "The same as CMAKE_SYSTEM_VERSION but for the host system instead "
- "of the target system when cross compiling.",false,
- "Variables That Describe the System");
-
- cm->DefineProperty
- ("APPLE", cmProperty::VARIABLE,
- "True if running on Mac OS X.",
- "Set to true on Mac OS X."
- ,false,
- "Variables That Describe the System");
-
- cm->DefineProperty
- ("BORLAND", cmProperty::VARIABLE,
- "True if the Borland compiler is being used.",
- "This is set to true if the Borland compiler is being used.",false,
- "Variables That Describe the System");
-
- cm->DefineProperty
- ("CYGWIN", cmProperty::VARIABLE,
- "True for Cygwin.",
- "Set to true when using Cygwin."
- ,false,
- "Variables That Describe the System");
-
- cm->DefineProperty
- ("MSVC", cmProperty::VARIABLE,
- "True when using Microsoft Visual C",
- "Set to true when the compiler is some version of Microsoft Visual C.",
- false,
- "Variables That Describe the System");
-
- int msvc_versions[] = { 60, 70, 71, 80, 90, 100, 110, 120, 0 };
- for (int i = 0; msvc_versions[i] != 0; i ++)
- {
- const char minor = (char)('0' + (msvc_versions[i] % 10));
- cmStdString varName = "MSVC";
- cmsys_ios::ostringstream majorStr;
-
- majorStr << (msvc_versions[i] / 10);
- varName += majorStr.str();
- if (msvc_versions[i] < 100)
- {
- varName += minor;
- }
-
- cmStdString verString = majorStr.str() + "." + minor;
-
- cmStdString shortStr = "True when using Microsoft Visual C " + verString;
- cmStdString fullStr = "Set to true when the compiler is version " +
- verString +
- " of Microsoft Visual C.";
- cm->DefineProperty
- (varName.c_str(), cmProperty::VARIABLE,
- shortStr.c_str(),
- fullStr.c_str(),
- false,
- "Variables That Describe the System");
- }
-
- cm->DefineProperty
- ("MSVC_IDE", cmProperty::VARIABLE,
- "True when using the Microsoft Visual C IDE",
- "Set to true when the target platform is the Microsoft Visual C IDE, "
- "as opposed to the command line compiler.",
- false,
- "Variables That Describe the System");
-
- cm->DefineProperty
- ("MSVC_VERSION", cmProperty::VARIABLE,
- "The version of Microsoft Visual C/C++ being used if any.",
- "Known version numbers are:\n"
- " 1200 = VS 6.0\n"
- " 1300 = VS 7.0\n"
- " 1310 = VS 7.1\n"
- " 1400 = VS 8.0\n"
- " 1500 = VS 9.0\n"
- " 1600 = VS 10.0\n"
- " 1700 = VS 11.0\n"
- " 1800 = VS 12.0\n"
- "",
- false,
- "Variables That Describe the System");
-
- cm->DefineProperty
- ("CMAKE_CL_64", cmProperty::VARIABLE,
- "Using the 64 bit compiler from Microsoft",
- "Set to true when using the 64 bit cl compiler from Microsoft.",
- false,
- "Variables That Describe the System");
-
- cm->DefineProperty
- ("CMAKE_COMPILER_2005", cmProperty::VARIABLE,
- "Using the Visual Studio 2005 compiler from Microsoft",
- "Set to true when using the Visual Studio 2005 compiler "
- "from Microsoft.",
- false,
- "Variables That Describe the System");
-
- cm->DefineProperty
- ("UNIX", cmProperty::VARIABLE,
- "True for UNIX and UNIX like operating systems.",
- "Set to true when the target system is UNIX or UNIX like "
- "(i.e. APPLE and CYGWIN).",false,
- "Variables That Describe the System");
-
- cm->DefineProperty
- ("WIN32", cmProperty::VARIABLE,
- "True on windows systems, including win64.",
- "Set to true when the target system is Windows.",false,
- "Variables That Describe the System");
-
- cm->DefineProperty
- ("XCODE_VERSION", cmProperty::VARIABLE,
- "Version of Xcode (Xcode generator only).",
- "Under the Xcode generator, this is the version of Xcode as specified in "
- "\"Xcode.app/Contents/version.plist\" (such as \"3.1.2\").",false,
- "Variables That Describe the System");
-
- cm->DefineProperty
- ("CMAKE_HOST_APPLE", cmProperty::VARIABLE,
- "True for Apple OS X operating systems.",
- "Set to true when the host system is Apple OS X.",
- false,
- "Variables That Describe the System");
-
- cm->DefineProperty
- ("CMAKE_HOST_UNIX", cmProperty::VARIABLE,
- "True for UNIX and UNIX like operating systems.",
- "Set to true when the host system is UNIX or UNIX like "
- "(i.e. APPLE and CYGWIN).",false,
- "Variables That Describe the System");
-
- cm->DefineProperty
- ("CMAKE_HOST_WIN32", cmProperty::VARIABLE,
- "True on windows systems, including win64.",
- "Set to true when the host system is Windows and on Cygwin."
- ,false,
- "Variables That Describe the System");
-
- cm->DefineProperty
- ("CMAKE_OBJECT_PATH_MAX", cmProperty::VARIABLE,
- "Maximum object file full-path length allowed by native build tools.",
- "CMake computes for every source file an object file name that is "
- "unique to the source file and deterministic with respect to the "
- "full path to the source file. "
- "This allows multiple source files in a target to share the same name "
- "if they lie in different directories without rebuilding when one is "
- "added or removed. "
- "However, it can produce long full paths in a few cases, so CMake "
- "shortens the path using a hashing scheme when the full path to an "
- "object file exceeds a limit. "
- "CMake has a built-in limit for each platform that is sufficient for "
- "common tools, but some native tools may have a lower limit. "
- "This variable may be set to specify the limit explicitly. "
- "The value must be an integer no less than 128.",false,
- "Variables That Describe the System");
-
- cm->DefineProperty
- ("ENV", cmProperty::VARIABLE,
- "Access environment variables.",
- "Use the syntax $ENV{VAR} to read environment variable VAR. "
- "See also the set() command to set ENV{VAR}."
- ,false,
- "Variables That Describe the System");
-
- // Variables that affect the building of object files and
- // targets.
- //
- cm->DefineProperty
- ("CMAKE_INCLUDE_CURRENT_DIR", cmProperty::VARIABLE,
- "Automatically add the current source- and build directories "
- "to the include path.",
- "If this variable is enabled, CMake automatically adds in each "
- "directory ${CMAKE_CURRENT_SOURCE_DIR} and ${CMAKE_CURRENT_BINARY_DIR} "
- "to the include path for this directory. These additional include "
- "directories do not propagate down to subdirectories. This is useful "
- "mainly for out-of-source builds, where files generated into the "
- "build tree are included by files located in the source tree.\n"
- "By default CMAKE_INCLUDE_CURRENT_DIR is OFF.",
- false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE", cmProperty::VARIABLE,
- "Automatically add the current source- and build directories "
- "to the INTERFACE_INCLUDE_DIRECTORIES.",
- "If this variable is enabled, CMake automatically adds for each shared "
- "library target, static library target, module target and executable "
- "target, ${CMAKE_CURRENT_SOURCE_DIR} and ${CMAKE_CURRENT_BINARY_DIR} to "
- "the INTERFACE_INCLUDE_DIRECTORIES."
- "By default CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE is OFF.",
- false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_INSTALL_RPATH", cmProperty::VARIABLE,
- "The rpath to use for installed targets.",
- "A semicolon-separated list specifying the rpath "
- "to use in installed targets (for platforms that support it). "
- "This is used to initialize the target property "
- "INSTALL_RPATH for all targets.",
- false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_INSTALL_RPATH_USE_LINK_PATH", cmProperty::VARIABLE,
- "Add paths to linker search and installed rpath.",
- "CMAKE_INSTALL_RPATH_USE_LINK_PATH is a boolean that if set to true "
- "will append directories in the linker search path and outside the "
- "project to the INSTALL_RPATH. "
- "This is used to initialize the target property "
- "INSTALL_RPATH_USE_LINK_PATH for all targets.",
- false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_INSTALL_NAME_DIR", cmProperty::VARIABLE,
- "Mac OS X directory name for installed targets.",
- "CMAKE_INSTALL_NAME_DIR is used to initialize the "
- "INSTALL_NAME_DIR property on all targets. See that target "
- "property for more information.",
- false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_Fortran_FORMAT", cmProperty::VARIABLE,
- "Set to FIXED or FREE to indicate the Fortran source layout.",
- "This variable is used to initialize the Fortran_FORMAT "
- "property on all the targets. "
- "See that target property for additional information.",
- false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_Fortran_MODULE_DIRECTORY", cmProperty::VARIABLE,
- "Fortran module output directory.",
- "This variable is used to initialize the "
- "Fortran_MODULE_DIRECTORY property on all the targets. "
- "See that target property for additional information.",
- false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_LIBRARY_OUTPUT_DIRECTORY", cmProperty::VARIABLE,
- "Where to put all the LIBRARY targets when built.",
- "This variable is used to initialize the "
- "LIBRARY_OUTPUT_DIRECTORY property on all the targets. "
- "See that target property for additional information.",
- false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_ARCHIVE_OUTPUT_DIRECTORY", cmProperty::VARIABLE,
- "Where to put all the ARCHIVE targets when built.",
- "This variable is used to initialize the "
- "ARCHIVE_OUTPUT_DIRECTORY property on all the targets. "
- "See that target property for additional information.",
- false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_RUNTIME_OUTPUT_DIRECTORY", cmProperty::VARIABLE,
- "Where to put all the RUNTIME targets when built.",
- "This variable is used to initialize the "
- "RUNTIME_OUTPUT_DIRECTORY property on all the targets. "
- "See that target property for additional information.",
- false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_PDB_OUTPUT_DIRECTORY", cmProperty::VARIABLE,
- "Where to put all the MS debug symbol files from linker.",
- "This variable is used to initialize the "
- "PDB_OUTPUT_DIRECTORY property on all the targets. "
- "See that target property for additional information.",
- false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_LINK_DEPENDS_NO_SHARED", cmProperty::VARIABLE,
- "Whether to skip link dependencies on shared library files.",
- "This variable initializes the LINK_DEPENDS_NO_SHARED "
- "property on targets when they are created. "
- "See that target property for additional information.",
- false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_AUTOMOC", cmProperty::VARIABLE,
- "Whether to handle moc automatically for Qt targets.",
- "This variable is used to initialize the "
- "AUTOMOC property on all the targets. "
- "See that target property for additional information.",
- false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_AUTOMOC_MOC_OPTIONS", cmProperty::VARIABLE,
- "Additional options for moc when using automoc (see CMAKE_AUTOMOC).",
- "This variable is used to initialize the "
- "AUTOMOC_MOC_OPTIONS property on all the targets. "
- "See that target property for additional information.",
- false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_GNUtoMS", cmProperty::VARIABLE,
- "Convert GNU import libraries (.dll.a) to MS format (.lib).",
- "This variable is used to initialize the GNUtoMS property on targets "
- "when they are created. "
- "See that target property for additional information.",
- false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_DEBUG_POSTFIX", cmProperty::VARIABLE,
- "See variable CMAKE_<CONFIG>_POSTFIX.",
- "This variable is a special case of the more-general "
- "CMAKE_<CONFIG>_POSTFIX variable for the DEBUG configuration.",
- false,
- "Variables that Control the Build");
- cm->DefineProperty
- ("CMAKE_<CONFIG>_POSTFIX", cmProperty::VARIABLE,
- "Default filename postfix for libraries under configuration <CONFIG>.",
- "When a non-executable target is created its <CONFIG>_POSTFIX "
- "target property is initialized with the value of this variable "
- "if it is set.",
- false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_BUILD_WITH_INSTALL_RPATH", cmProperty::VARIABLE,
- "Use the install path for the RPATH",
- "Normally CMake uses the build tree for the RPATH when building "
- "executables etc on systems that use RPATH. When the software "
- "is installed the executables etc are relinked by CMake to have "
- "the install RPATH. If this variable is set to true then the software "
- "is always built with the install path for the RPATH and does not "
- "need to be relinked when installed.",false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_NO_BUILTIN_CHRPATH", cmProperty::VARIABLE,
- "Do not use the builtin ELF editor to fix RPATHs on installation.",
- "When an ELF binary needs to have a different RPATH after installation "
- "than it does in the build tree, CMake uses a builtin editor to change "
- "the RPATH in the installed copy. "
- "If this variable is set to true then CMake will relink the binary "
- "before installation instead of using its builtin editor.",false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_SKIP_BUILD_RPATH", cmProperty::VARIABLE,
- "Do not include RPATHs in the build tree.",
- "Normally CMake uses the build tree for the RPATH when building "
- "executables etc on systems that use RPATH. When the software "
- "is installed the executables etc are relinked by CMake to have "
- "the install RPATH. If this variable is set to true then the software "
- "is always built with no RPATH.",false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_SKIP_INSTALL_RPATH", cmProperty::VARIABLE,
- "Do not include RPATHs in the install tree.",
- "Normally CMake uses the build tree for the RPATH when building "
- "executables etc on systems that use RPATH. When the software "
- "is installed the executables etc are relinked by CMake to have "
- "the install RPATH. If this variable is set to true then the software "
- "is always installed without RPATH, even if RPATH is enabled when "
- "building. This can be useful for example to allow running tests from "
- "the build directory with RPATH enabled before the installation step. "
- "To omit RPATH in both the build and install steps, use "
- "CMAKE_SKIP_RPATH instead.",false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_EXE_LINKER_FLAGS", cmProperty::VARIABLE,
- "Linker flags to be used to create executables.",
- "These flags will be used by the linker when creating an executable."
- ,false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_EXE_LINKER_FLAGS_<CONFIG>", cmProperty::VARIABLE,
- "Flags to be used when linking an executable.",
- "Same as CMAKE_C_FLAGS_* but used by the linker "
- "when creating executables.",false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_MODULE_LINKER_FLAGS", cmProperty::VARIABLE,
- "Linker flags to be used to create modules.",
- "These flags will be used by the linker when creating a module."
- ,false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_MODULE_LINKER_FLAGS_<CONFIG>", cmProperty::VARIABLE,
- "Flags to be used when linking a module.",
- "Same as CMAKE_C_FLAGS_* but used by the linker "
- "when creating modules.",false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_SHARED_LINKER_FLAGS", cmProperty::VARIABLE,
- "Linker flags to be used to create shared libraries.",
- "These flags will be used by the linker when creating a shared library."
- ,false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_SHARED_LINKER_FLAGS_<CONFIG>", cmProperty::VARIABLE,
- "Flags to be used when linking a shared library.",
- "Same as CMAKE_C_FLAGS_* but used by the linker "
- "when creating shared libraries.",false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_STATIC_LINKER_FLAGS", cmProperty::VARIABLE,
- "Linker flags to be used to create static libraries.",
- "These flags will be used by the linker when creating a static library."
- ,false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_STATIC_LINKER_FLAGS_<CONFIG>", cmProperty::VARIABLE,
- "Flags to be used when linking a static library.",
- "Same as CMAKE_C_FLAGS_* but used by the linker "
- "when creating static libraries.",false,
- "Variables that Control the Build");
-
- cm->DefineProperty
- ("CMAKE_LIBRARY_PATH_FLAG", cmProperty::VARIABLE,
- "The flag to be used to add a library search path to a compiler.",
- "The flag will be used to specify a library directory to the compiler. "
- "On most compilers this is \"-L\".",false,
- "Variables that Control the Build");
- cm->DefineProperty
- ("CMAKE_LINK_DEF_FILE_FLAG ", cmProperty::VARIABLE,
- "Linker flag to be used to specify a .def file for dll creation.",
- "The flag will be used to add a .def file when creating "
- "a dll on Windows; this is only defined on Windows."
- ,false,
- "Variables that Control the Build");
- cm->DefineProperty
- ("CMAKE_LINK_LIBRARY_FLAG", cmProperty::VARIABLE,
- "Flag to be used to link a library into an executable.",
- "The flag will be used to specify a library to link to an executable. "
- "On most compilers this is \"-l\".",false,
- "Variables that Control the Build");
- cm->DefineProperty
- ("CMAKE_LINK_LIBRARY_FILE_FLAG", cmProperty::VARIABLE,
- "Flag to be used to link a library specified by a path to its file.",
- "The flag will be used before a library file path is given to the "
- "linker. "
- "This is needed only on very few platforms.", false,
- "Variables that Control the Build");
- cm->DefineProperty
- ("CMAKE_USE_RELATIVE_PATHS", cmProperty::VARIABLE,
- "Use relative paths (May not work!).",
- "If this is set to TRUE, then CMake will use "
- "relative paths between the source and binary tree. "
- "This option does not work for more complicated "
- "projects, and relative paths are used when possible. "
- "In general, it is not possible to move CMake generated"
- " makefiles to a different location regardless "
- "of the value of this variable.",false,
- "Variables that Control the Build");
- cm->DefineProperty
- ("EXECUTABLE_OUTPUT_PATH", cmProperty::VARIABLE,
- "Old executable location variable.",
- "The target property RUNTIME_OUTPUT_DIRECTORY supercedes "
- "this variable for a target if it is set. "
- "Executable targets are otherwise placed in this directory.",false,
- "Variables that Control the Build");
- cm->DefineProperty
- ("LIBRARY_OUTPUT_PATH", cmProperty::VARIABLE,
- "Old library location variable.",
- "The target properties ARCHIVE_OUTPUT_DIRECTORY, "
- "LIBRARY_OUTPUT_DIRECTORY, and RUNTIME_OUTPUT_DIRECTORY supercede "
- "this variable for a target if they are set. "
- "Library targets are otherwise placed in this directory.",false,
- "Variables that Control the Build");
- cm->DefineProperty
- ("CMAKE_TRY_COMPILE_CONFIGURATION", cmProperty::VARIABLE,
- "Build configuration used for try_compile and try_run projects.",
- "Projects built by try_compile and try_run are built "
- "synchronously during the CMake configuration step. "
- "Therefore a specific build configuration must be chosen even "
- "if the generated build system supports multiple configurations.",false,
- "Variables that Control the Build");
- cm->DefineProperty
- ("CMAKE_LINK_INTERFACE_LIBRARIES", cmProperty::VARIABLE,
- "Default value for LINK_INTERFACE_LIBRARIES of targets.",
- "This variable is used to initialize the "
- "LINK_INTERFACE_LIBRARIES property on all the targets. "
- "See that target property for additional information.",
- false,
- "Variables that Control the Build");
- cm->DefineProperty
- ("CMAKE_WIN32_EXECUTABLE", cmProperty::VARIABLE,
- "Default value for WIN32_EXECUTABLE of targets.",
- "This variable is used to initialize the "
- "WIN32_EXECUTABLE property on all the targets. "
- "See that target property for additional information.",
- false,
- "Variables that Control the Build");
- cm->DefineProperty
- ("CMAKE_MACOSX_BUNDLE", cmProperty::VARIABLE,
- "Default value for MACOSX_BUNDLE of targets.",
- "This variable is used to initialize the "
- "MACOSX_BUNDLE property on all the targets. "
- "See that target property for additional information.",
- false,
- "Variables that Control the Build");
- cm->DefineProperty
- ("CMAKE_POSITION_INDEPENDENT_CODE", cmProperty::VARIABLE,
- "Default value for POSITION_INDEPENDENT_CODE of targets.",
- "This variable is used to initialize the "
- "POSITION_INDEPENDENT_CODE property on all the targets. "
- "See that target property for additional information.",
- false,
- "Variables that Control the Build");
- cm->DefineProperty
- ("CMAKE_<LANG>_VISIBILITY_PRESET", cmProperty::VARIABLE,
- "Default value for <LANG>_VISIBILITY_PRESET of targets.",
- "This variable is used to initialize the "
- "<LANG>_VISIBILITY_PRESET property on all the targets. "
- "See that target property for additional information.",
- false,
- "Variables that Control the Build");
- cm->DefineProperty
- ("CMAKE_VISIBILITY_INLINES_HIDDEN", cmProperty::VARIABLE,
- "Default value for VISIBILITY_INLINES_HIDDEN of targets.",
- "This variable is used to initialize the "
- "VISIBILITY_INLINES_HIDDEN property on all the targets. "
- "See that target property for additional information.",
- false,
- "Variables that Control the Build");
-
-// Variables defined when the a language is enabled These variables will
-// also be defined whenever CMake has loaded its support for compiling (LANG)
-// programs. This support will be loaded whenever CMake is used to compile
-// (LANG) files. C and CXX are examples of the most common values for (LANG).
-
- cm->DefineProperty
- ("CMAKE_USER_MAKE_RULES_OVERRIDE_<LANG>", cmProperty::VARIABLE,
- "Specify a CMake file that overrides platform information for <LANG>.",
- "This is a language-specific version of "
- "CMAKE_USER_MAKE_RULES_OVERRIDE loaded only when enabling "
- "language <LANG>.",false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_COMPILER", cmProperty::VARIABLE,
- "The full path to the compiler for LANG.",
- "This is the command that will be used as the <LANG> compiler. "
- "Once set, you can not change this variable.",false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_COMPILER_ID", cmProperty::VARIABLE,
- "Compiler identification string.",
- "A short string unique to the compiler vendor. "
- "Possible values include:\n"
- " Absoft = Absoft Fortran (absoft.com)\n"
- " ADSP = Analog VisualDSP++ (analog.com)\n"
- " Clang = LLVM Clang (clang.llvm.org)\n"
- " Cray = Cray Compiler (cray.com)\n"
- " Embarcadero, Borland = Embarcadero (embarcadero.com)\n"
- " G95 = G95 Fortran (g95.org)\n"
- " GNU = GNU Compiler Collection (gcc.gnu.org)\n"
- " HP = Hewlett-Packard Compiler (hp.com)\n"
- " Intel = Intel Compiler (intel.com)\n"
- " MIPSpro = SGI MIPSpro (sgi.com)\n"
- " MSVC = Microsoft Visual Studio (microsoft.com)\n"
- " PGI = The Portland Group (pgroup.com)\n"
- " PathScale = PathScale (pathscale.com)\n"
- " SDCC = Small Device C Compiler (sdcc.sourceforge.net)\n"
- " SunPro = Oracle Solaris Studio (oracle.com)\n"
- " TI = Texas Instruments (ti.com)\n"
- " TinyCC = Tiny C Compiler (tinycc.org)\n"
- " Watcom = Open Watcom (openwatcom.org)\n"
- " XL, VisualAge, zOS = IBM XL (ibm.com)\n"
- "This variable is not guaranteed to be defined for all "
- "compilers or languages.",
- false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_PLATFORM_ID", cmProperty::VARIABLE,
- "An internal variable subject to change.",
- "This is used in determining the platform and is subject to change.",
- false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_COMPILER_ABI", cmProperty::VARIABLE,
- "An internal variable subject to change.",
- "This is used in determining the compiler ABI and is subject to change.",
- false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_COMPILER_VERSION", cmProperty::VARIABLE,
- "Compiler version string.",
- "Compiler version in major[.minor[.patch[.tweak]]] format. "
- "This variable is not guaranteed to be defined for all "
- "compilers or languages.",
- false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_INTERNAL_PLATFORM_ABI", cmProperty::VARIABLE,
- "An internal variable subject to change.",
- "This is used in determining the compiler ABI and is subject to change.",
- false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_SIZEOF_DATA_PTR", cmProperty::VARIABLE,
- "Size of pointer-to-data types for language <LANG>.",
- "This holds the size (in bytes) of pointer-to-data types in the target "
- "platform ABI. "
- "It is defined for languages C and CXX (C++).",
- false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_COMPILER_IS_GNU<LANG>", cmProperty::VARIABLE,
- "True if the compiler is GNU.",
- "If the selected <LANG> compiler is the GNU "
- "compiler then this is TRUE, if not it is FALSE. "
- "Unlike the other per-language variables, this uses the GNU syntax for "
- "identifying languages instead of the CMake syntax. Recognized values of "
- "the <LANG> suffix are:\n"
- " CC = C compiler\n"
- " CXX = C++ compiler\n"
- " G77 = Fortran compiler",
- false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_FLAGS", cmProperty::VARIABLE,
- "Flags for all build types.",
- "<LANG> flags used regardless of the value of CMAKE_BUILD_TYPE.",false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_FLAGS_DEBUG", cmProperty::VARIABLE,
- "Flags for Debug build type or configuration.",
- "<LANG> flags used when CMAKE_BUILD_TYPE is Debug.",false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_FLAGS_MINSIZEREL", cmProperty::VARIABLE,
- "Flags for MinSizeRel build type or configuration.",
- "<LANG> flags used when CMAKE_BUILD_TYPE is MinSizeRel."
- "Short for minimum size release.",false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_FLAGS_RELEASE", cmProperty::VARIABLE,
- "Flags for Release build type or configuration.",
- "<LANG> flags used when CMAKE_BUILD_TYPE is Release",false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_FLAGS_RELWITHDEBINFO", cmProperty::VARIABLE,
- "Flags for RelWithDebInfo type or configuration.",
- "<LANG> flags used when CMAKE_BUILD_TYPE is RelWithDebInfo. "
- "Short for Release With Debug Information.",false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_COMPILE_OBJECT", cmProperty::VARIABLE,
- "Rule variable to compile a single object file.",
- "This is a rule variable that tells CMake how to "
- "compile a single object file for the language <LANG>."
- ,false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_CREATE_SHARED_LIBRARY", cmProperty::VARIABLE,
- "Rule variable to create a shared library.",
- "This is a rule variable that tells CMake how to "
- "create a shared library for the language <LANG>.",false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_CREATE_SHARED_MODULE", cmProperty::VARIABLE,
- "Rule variable to create a shared module.",
- "This is a rule variable that tells CMake how to "
- "create a shared library for the language <LANG>.",false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_CREATE_STATIC_LIBRARY", cmProperty::VARIABLE,
- "Rule variable to create a static library.",
- "This is a rule variable that tells CMake how "
- "to create a static library for the language <LANG>.",false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_ARCHIVE_CREATE", cmProperty::VARIABLE,
- "Rule variable to create a new static archive.",
- "This is a rule variable that tells CMake how to create a static "
- "archive. It is used in place of CMAKE_<LANG>_CREATE_STATIC_LIBRARY "
- "on some platforms in order to support large object counts. "
- "See also CMAKE_<LANG>_ARCHIVE_APPEND and CMAKE_<LANG>_ARCHIVE_FINISH.",
- false, "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_ARCHIVE_APPEND", cmProperty::VARIABLE,
- "Rule variable to append to a static archive.",
- "This is a rule variable that tells CMake how to append to a static "
- "archive. It is used in place of CMAKE_<LANG>_CREATE_STATIC_LIBRARY "
- "on some platforms in order to support large object counts. "
- "See also CMAKE_<LANG>_ARCHIVE_CREATE and CMAKE_<LANG>_ARCHIVE_FINISH.",
- false, "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_ARCHIVE_FINISH", cmProperty::VARIABLE,
- "Rule variable to finish an existing static archive.",
- "This is a rule variable that tells CMake how to finish a static "
- "archive. It is used in place of CMAKE_<LANG>_CREATE_STATIC_LIBRARY "
- "on some platforms in order to support large object counts. "
- "See also CMAKE_<LANG>_ARCHIVE_CREATE and CMAKE_<LANG>_ARCHIVE_APPEND.",
- false, "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_IGNORE_EXTENSIONS", cmProperty::VARIABLE,
- "File extensions that should be ignored by the build.",
- "This is a list of file extensions that may be "
- "part of a project for a given language but are not compiled.",false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_IMPLICIT_INCLUDE_DIRECTORIES", cmProperty::VARIABLE,
- "Directories implicitly searched by the compiler for header files.",
- "CMake does not explicitly specify these directories on compiler "
- "command lines for language <LANG>. "
- "This prevents system include directories from being treated as user "
- "include directories on some compilers.", false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_IMPLICIT_LINK_DIRECTORIES", cmProperty::VARIABLE,
- "Implicit linker search path detected for language <LANG>.",
- "Compilers typically pass directories containing language runtime "
- "libraries and default library search paths when they invoke a linker. "
- "These paths are implicit linker search directories for the compiler's "
- "language. "
- "CMake automatically detects these directories for each language and "
- "reports the results in this variable."
- "\n"
- "When a library in one of these directories is given by full path to "
- "target_link_libraries() CMake will generate the -l<name> form on "
- "link lines to ensure the linker searches its implicit directories "
- "for the library. "
- "Note that some toolchains read implicit directories from an "
- "environment variable such as LIBRARY_PATH so keep its value "
- "consistent when operating in a given build tree.",false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES", cmProperty::VARIABLE,
- "Implicit linker framework search path detected for language <LANG>.",
- "These paths are implicit linker framework search directories for "
- "the compiler's language. "
- "CMake automatically detects these directories for each language and "
- "reports the results in this variable.", false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_IMPLICIT_LINK_LIBRARIES", cmProperty::VARIABLE,
- "Implicit link libraries and flags detected for language <LANG>.",
- "Compilers typically pass language runtime library names and "
- "other flags when they invoke a linker. "
- "These flags are implicit link options for the compiler's language. "
- "CMake automatically detects these libraries and flags for each "
- "language and reports the results in this variable.", false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_LIBRARY_ARCHITECTURE", cmProperty::VARIABLE,
- "Target architecture library directory name detected for <lang>.",
- "If the <lang> compiler passes to the linker an architecture-specific "
- "system library search directory such as <prefix>/lib/<arch> this "
- "variable contains the <arch> name if/as detected by CMake.",false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_LINKER_PREFERENCE_PROPAGATES", cmProperty::VARIABLE,
- "True if CMAKE_<LANG>_LINKER_PREFERENCE propagates across targets.",
- "This is used when CMake selects a linker language for a target. "
- "Languages compiled directly into the target are always considered. "
- "A language compiled into static libraries linked by the target is "
- "considered if this variable is true.", false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_LINKER_PREFERENCE", cmProperty::VARIABLE,
- "Preference value for linker language selection.",
- "The \"linker language\" for executable, shared library, and module "
- "targets is the language whose compiler will invoke the linker. "
- "The LINKER_LANGUAGE target property sets the language explicitly. "
- "Otherwise, the linker language is that whose linker preference value "
- "is highest among languages compiled and linked into the target. "
- "See also the CMAKE_<LANG>_LINKER_PREFERENCE_PROPAGATES variable.",
- false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_LINK_EXECUTABLE ", cmProperty::VARIABLE,
- "Rule variable to link an executable.",
- "Rule variable to link an executable for the given language."
- ,false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_OUTPUT_EXTENSION", cmProperty::VARIABLE,
- "Extension for the output of a compile for a single file.",
- "This is the extension for an object file for "
- "the given <LANG>. For example .obj for C on Windows.",false,
- "Variables for Languages");
-
- cm->DefineProperty
- ("CMAKE_<LANG>_SOURCE_FILE_EXTENSIONS", cmProperty::VARIABLE,
- "Extensions of source files for the given language.",
- "This is the list of extensions for a "
- "given language's source files."
- ,false,
- "Variables for Languages");
-
- cm->DefineProperty(
- "CMAKE_<LANG>_COMPILER_LOADED", cmProperty::VARIABLE,
- "Defined to true if the language is enabled.",
- "When language <LANG> is enabled by project() or enable_language() "
- "this variable is defined to 1.",
- false,"Variables for Languages");
-
- cm->DefineProperty(
- "CMAKE_Fortran_MODDIR_FLAG", cmProperty::VARIABLE,
- "Fortran flag for module output directory.",
- "This stores the flag needed to pass the value of the "
- "Fortran_MODULE_DIRECTORY target property to the compiler.",
- false,"Variables for Languages");
-
- cm->DefineProperty(
- "CMAKE_Fortran_MODDIR_DEFAULT", cmProperty::VARIABLE,
- "Fortran default module output directory.",
- "Most Fortran compilers write .mod files to the current working "
- "directory. "
- "For those that do not, this is set to \".\" and used when the "
- "Fortran_MODULE_DIRECTORY target property is not set.",
- false,"Variables for Languages");
-
- cm->DefineProperty(
- "CMAKE_Fortran_MODOUT_FLAG", cmProperty::VARIABLE,
- "Fortran flag to enable module output.",
- "Most Fortran compilers write .mod files out by default. "
- "For others, this stores the flag needed to enable module output.",
- false,"Variables for Languages");
-
- // variables that are used by cmake but not to be documented
- cm->DefineProperty("CMAKE_MATCH_0", cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_MATCH_1", cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_MATCH_2", cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_MATCH_3", cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_MATCH_4", cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_MATCH_5", cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_MATCH_6", cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_MATCH_7", cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_MATCH_8", cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_MATCH_9", cmProperty::VARIABLE,0,0);
-
- cm->DefineProperty("CMAKE_<LANG>_COMPILER_ARG1",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_<LANG>_COMPILER_ENV_VAR",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_<LANG>_COMPILER_ID_RUN",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_<LANG>_ABI_FILES",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_<LANG>_CREATE_ASSEMBLY_SOURCE",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_<LANG>_CREATE_PREPROCESSED_SOURCE",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_<LANG>_FLAGS_DEBUG_INIT",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_<LANG>_FLAGS_INIT",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_<LANG>_FLAGS_MINSIZEREL_INIT",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_<LANG>_FLAGS_RELEASE_INIT",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_<LANG>_FLAGS_RELWITHDEBINFO_INIT",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_<LANG>_INFORMATION_LOADED",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_<LANG>_LINK_EXECUTABLE",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_<LANG>_LINK_FLAGS",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_<LANG>_RESPONSE_FILE_LINK_FLAG",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_<LANG>_STANDARD_LIBRARIES",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_<LANG>_STANDARD_LIBRARIES_INIT",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_<LANG>_USE_RESPONSE_FILE_FOR_INCLUDES",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_<LANG>_USE_RESPONSE_FILE_FOR_OBJECTS",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_EXECUTABLE_SUFFIX_<LANG>",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_EXE_LINK_DYNAMIC_<LANG>_FLAGS",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_EXE_LINK_STATIC_<LANG>_FLAGS",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_GENERATOR_<LANG>",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_IMPORT_LIBRARY_PREFIX_<LANG>",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_IMPORT_LIBRARY_SUFFIX_<LANG>",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_INCLUDE_FLAG_<LANG>",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_INCLUDE_FLAG_SEP_<LANG>",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_INCLUDE_SYSTEM_FLAG_<LANG>",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_NEEDS_REQUIRES_STEP_<LANG>_FLAG",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_SHARED_LIBRARY_CREATE_<LANG>_FLAGS",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_SHARED_LIBRARY_<LANG>_FLAGS",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_SHARED_LIBRARY_LINK_<LANG>_FLAGS",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_SHARED_LIBRARY_LINK_DYNAMIC_<LANG>_FLAGS",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_SHARED_LIBRARY_LINK_STATIC_<LANG>_FLAGS",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_SHARED_LIBRARY_PREFIX_<LANG>",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_SHARED_LIBRARY_SUFFIX_<LANG>",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_SHARED_LIBRARY_RUNTIME_<LANG>_FLAG",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_SHARED_LIBRARY_RUNTIME_<LANG>_FLAG_SEP",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_SHARED_LIBRARY_RPATH_LINK_<LANG>_FLAG",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_EXECUTABLE_RUNTIME_<LANG>_FLAG",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_EXECUTABLE_RUNTIME_<LANG>_FLAG_SEP",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_EXECUTABLE_RPATH_LINK_<LANG>_FLAG",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty(
- "CMAKE_<LANG>_USE_IMPLICIT_LINK_DIRECTORIES_IN_RUNTIME_PATH",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_SHARED_MODULE_CREATE_<LANG>_FLAGS",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_SHARED_MODULE_<LANG>_FLAGS",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_SHARED_MODULE_LINK_DYNAMIC_<LANG>_FLAGS",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_SHARED_MODULE_LINK_STATIC_<LANG>_FLAGS",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_SHARED_MODULE_PREFIX_<LANG>",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_SHARED_MODULE_SUFFIX_<LANG>",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_STATIC_LIBRARY_PREFIX_<LANG>",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_STATIC_LIBRARY_SUFFIX_<LANG>",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_LINK_DEPENDENT_LIBRARY_FILES",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_LINK_DEPENDENT_LIBRARY_DIRS",
- cmProperty::VARIABLE,0,0);
- cm->DefineProperty("CMAKE_MAKE_INCLUDE_FROM_ROOT",
- cmProperty::VARIABLE,0,0);
-}
diff --git a/Source/cmDocumentVariables.h b/Source/cmDocumentVariables.h
deleted file mode 100644
index 1d59b2450..000000000
--- a/Source/cmDocumentVariables.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef cmDocumentVariables_h
-#define cmDocumentVariables_h
-class cmake;
-class cmDocumentVariables
-{
-public:
- static void DefineVariables(cmake* cm);
-};
-
-#endif
diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx
index 4edacbb1a..4f3475536 100644
--- a/Source/cmDocumentation.cxx
+++ b/Source/cmDocumentation.cxx
@@ -13,208 +13,74 @@
#include "cmSystemTools.h"
#include "cmVersion.h"
+#include "cmRST.h"
+#include "cmAlgorithms.h"
+
#include <cmsys/Directory.hxx>
#include <cmsys/Glob.hxx>
+#include <cmsys/FStream.hxx>
-#include <algorithm>
-
-//----------------------------------------------------------------------------
-static const char *cmDocumentationStandardOptions[][3] =
-{
- {"--copyright [file]", "Print the CMake copyright and exit.",
- "If a file is specified, the copyright is written into it."},
- {"--help,-help,-usage,-h,-H,/?", "Print usage information and exit.",
- "Usage describes the basic command line interface and its options."},
- {"--help-full [file]", "Print full help and exit.",
- "Full help displays most of the documentation provided by the UNIX "
- "man page. It is provided for use on non-UNIX platforms, but is "
- "also convenient if the man page is not installed. If a file is "
- "specified, the help is written into it."},
- {"--help-html [file]", "Print full help in HTML format.",
- "This option is used by CMake authors to help produce web pages. "
- "If a file is specified, the help is written into it."},
- {"--help-man [file]", "Print full help as a UNIX man page and exit.",
- "This option is used by the cmake build to generate the UNIX man page. "
- "If a file is specified, the help is written into it."},
- {"--version,-version,/V [file]",
- "Show program name/version banner and exit.",
- "If a file is specified, the version is written into it."},
- {0,0,0}
-};
-
-//----------------------------------------------------------------------------
-static const char *cmModulesDocumentationDescription[][3] =
-{
- {0,
- " CMake Modules - Modules coming with CMake, the Cross-Platform Makefile "
- "Generator.", 0},
-// CMAKE_DOCUMENTATION_OVERVIEW,
- {0,
- "This is the documentation for the modules and scripts coming with CMake. "
- "Using these modules you can check the computer system for "
- "installed software packages, features of the compiler and the "
- "existence of headers to name just a few.", 0},
- {0,0,0}
-};
-
-//----------------------------------------------------------------------------
-static const char *cmCustomModulesDocumentationDescription[][3] =
-{
- {0,
- " Custom CMake Modules - Additional Modules for CMake.", 0},
-// CMAKE_DOCUMENTATION_OVERVIEW,
- {0,
- "This is the documentation for additional modules and scripts for CMake. "
- "Using these modules you can check the computer system for "
- "installed software packages, features of the compiler and the "
- "existence of headers to name just a few.", 0},
- {0,0,0}
-};
-
-//----------------------------------------------------------------------------
-static const char *cmPropertiesDocumentationDescription[][3] =
-{
- {0,
- " CMake Properties - Properties supported by CMake, "
- "the Cross-Platform Makefile Generator.", 0},
-// CMAKE_DOCUMENTATION_OVERVIEW,
- {0,
- "This is the documentation for the properties supported by CMake. "
- "Properties can have different scopes. They can either be assigned to a "
- "source file, a directory, a target or globally to CMake. By modifying the "
- "values of properties the behaviour of the build system can be customized.",
- 0},
- {0,0,0}
-};
-
-//----------------------------------------------------------------------------
-static const char *cmCompatCommandsDocumentationDescription[][3] =
-{
- {0,
- " CMake Compatibility Listfile Commands - "
- "Obsolete commands supported by CMake for compatibility.", 0},
-// CMAKE_DOCUMENTATION_OVERVIEW,
- {0,
- "This is the documentation for now obsolete listfile commands from previous "
- "CMake versions, which are still supported for compatibility reasons. You "
- "should instead use the newer, faster and shinier new commands. ;-)", 0},
- {0,0,0}
-};
-
-//----------------------------------------------------------------------------
-static const char *cmDocumentationModulesHeader[][3] =
-{
- {0,
- "The following modules are provided with CMake. "
- "They can be used with INCLUDE(ModuleName).", 0},
- {0,0,0}
-};
-
-//----------------------------------------------------------------------------
-static const char *cmDocumentationCustomModulesHeader[][3] =
-{
- {0,
- "The following modules are also available for CMake. "
- "They can be used with INCLUDE(ModuleName).", 0},
- {0,0,0}
-};
+#include <ctype.h>
-//----------------------------------------------------------------------------
-static const char *cmDocumentationGeneratorsHeader[][3] =
-{
- {0,
- "The following generators are available on this platform:", 0},
- {0,0,0}
-};
+#include <algorithm>
//----------------------------------------------------------------------------
-static const char *cmDocumentationStandardSeeAlso[][3] =
-{
- {0,
- "The following resources are available to get help using CMake:", 0},
- {"Home Page",
- "http://www.cmake.org",
- "The primary starting point for learning about CMake."},
- {"Frequently Asked Questions",
- "http://www.cmake.org/Wiki/CMake_FAQ",
- "A Wiki is provided containing answers to frequently asked questions. "},
- {"Online Documentation",
- "http://www.cmake.org/HTML/Documentation.html",
- "Links to available documentation may be found on this web page."},
- {"Mailing List",
- "http://www.cmake.org/HTML/MailingLists.html",
- "For help and discussion about using cmake, a mailing list is provided at "
- "cmake@cmake.org. "
- "The list is member-post-only but one may sign up on the CMake web page. "
- "Please first read the full documentation at "
- "http://www.cmake.org before posting questions to the list."},
- {0,0,0}
+static const char *cmDocumentationStandardOptions[][2] =
+{
+ {"--help,-help,-usage,-h,-H,/?",
+ "Print usage information and exit."},
+ {"--version,-version,/V [<f>]",
+ "Print version number and exit."},
+ {"--help-full [<f>]",
+ "Print all help manuals and exit."},
+ {"--help-manual <man> [<f>]",
+ "Print one help manual and exit."},
+ {"--help-manual-list [<f>]",
+ "List help manuals available and exit."},
+ {"--help-command <cmd> [<f>]",
+ "Print help for one command and exit."},
+ {"--help-command-list [<f>]",
+ "List commands with help available and exit."},
+ {"--help-commands [<f>]",
+ "Print cmake-commands manual and exit."},
+ {"--help-module <mod> [<f>]",
+ "Print help for one module and exit."},
+ {"--help-module-list [<f>]",
+ "List modules with help available and exit."},
+ {"--help-modules [<f>]",
+ "Print cmake-modules manual and exit."},
+ {"--help-policy <cmp> [<f>]",
+ "Print help for one policy and exit."},
+ {"--help-policy-list [<f>]",
+ "List policies with help available and exit."},
+ {"--help-policies [<f>]",
+ "Print cmake-policies manual and exit."},
+ {"--help-property <prop> [<f>]",
+ "Print help for one property and exit."},
+ {"--help-property-list [<f>]",
+ "List properties with help available and exit."},
+ {"--help-properties [<f>]",
+ "Print cmake-properties manual and exit."},
+ {"--help-variable var [<f>]",
+ "Print help for one variable and exit."},
+ {"--help-variable-list [<f>]",
+ "List variables with help available and exit."},
+ {"--help-variables [<f>]",
+ "Print cmake-variables manual and exit."},
+ {0,0}
};
//----------------------------------------------------------------------------
-static const char *cmDocumentationCopyright[][3] =
+static const char *cmDocumentationGeneratorsHeader[][2] =
{
{0,
- "Copyright 2000-2012 Kitware, Inc., Insight Software Consortium. "
- "All rights reserved.", 0},
- {0,
- "Redistribution and use in source and binary forms, with or without "
- "modification, are permitted provided that the following conditions are "
- "met:", 0},
- {"",
- "Redistributions of source code must retain the above copyright notice, "
- "this list of conditions and the following disclaimer.", 0},
- {"",
- "Redistributions in binary form must reproduce the above copyright "
- "notice, this list of conditions and the following disclaimer in the "
- "documentation and/or other materials provided with the distribution.",
- 0},
- {"",
- "Neither the names of Kitware, Inc., the Insight Software Consortium, "
- "nor the names of their contributors may be used to endorse or promote "
- "products derived from this software without specific prior written "
- "permission.", 0},
- {0,
- "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "
- "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "
- "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR "
- "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT "
- "HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, "
- "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT "
- "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, "
- "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY "
- "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT "
- "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE "
- "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
- 0},
- {0, 0, 0}
+ "The following generators are available on this platform:"},
+ {0,0}
};
//----------------------------------------------------------------------------
-#define DOCUMENT_INTRO(type, default_name, desc) \
- static char const *cmDocumentation##type##Intro[2] = { default_name, desc };
-#define GET_DOCUMENT_INTRO(type) cmDocumentation##type##Intro
-
-DOCUMENT_INTRO(Modules, "cmakemodules",
- "Reference of available CMake modules.");
-DOCUMENT_INTRO(CustomModules, "cmakecustommodules",
- "Reference of available CMake custom modules.");
-DOCUMENT_INTRO(Policies, "cmakepolicies",
- "Reference of CMake policies.");
-DOCUMENT_INTRO(Properties, "cmakeprops",
- "Reference of CMake properties.");
-DOCUMENT_INTRO(Variables, "cmakevars",
- "Reference of CMake variables.");
-DOCUMENT_INTRO(Commands, "cmakecommands",
- "Reference of available CMake commands.");
-DOCUMENT_INTRO(CompatCommands, "cmakecompat",
- "Reference of CMake compatibility commands.");
-
-//----------------------------------------------------------------------------
cmDocumentation::cmDocumentation()
-:CurrentFormatter(0)
{
- this->SetForm(TextForm, 0);
this->addCommonStandardDocSections();
this->ShowGenerators = true;
}
@@ -222,363 +88,70 @@ cmDocumentation::cmDocumentation()
//----------------------------------------------------------------------------
cmDocumentation::~cmDocumentation()
{
- for(std::vector< char* >::iterator i = this->ModuleStrings.begin();
- i != this->ModuleStrings.end(); ++i)
- {
- delete [] *i;
- }
- for(std::map<std::string,cmDocumentationSection *>::iterator i =
- this->AllSections.begin();
- i != this->AllSections.end(); ++i)
- {
- delete i->second;
- }
-}
-
-//----------------------------------------------------------------------------
-bool cmDocumentation::PrintCopyright(std::ostream& os)
-{
- cmDocumentationSection *sec = this->AllSections["Copyright"];
- const std::vector<cmDocumentationEntry> &entries = sec->GetEntries();
- for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin();
- op != entries.end(); ++op)
- {
- if(op->Name.size())
- {
- os << " * ";
- this->TextFormatter.SetIndent(" ");
- this->TextFormatter.PrintColumn(os, op->Brief.c_str());
- }
- else
- {
- this->TextFormatter.SetIndent("");
- this->TextFormatter.PrintColumn(os, op->Brief.c_str());
- }
- os << "\n";
- }
- return true;
+ cmDeleteAll(this->AllSections);
}
//----------------------------------------------------------------------------
bool cmDocumentation::PrintVersion(std::ostream& os)
{
- os << this->GetNameString() << " version "
- << cmVersion::GetCMakeVersion() << "\n";
+ os <<
+ this->GetNameString() <<
+ " version " << cmVersion::GetCMakeVersion() << "\n"
+ "\n"
+ "CMake suite maintained and supported by Kitware (kitware.com/cmake).\n"
+ ;
return true;
}
//----------------------------------------------------------------------------
-void cmDocumentation::AddSectionToPrint(const char *section)
-{
- if (this->AllSections.find(section) != this->AllSections.end())
- {
- this->PrintSections.push_back(this->AllSections[section]);
- }
-}
-
-//----------------------------------------------------------------------------
-void cmDocumentation::ClearSections()
+bool cmDocumentation::PrintDocumentation(Type ht, std::ostream& os)
{
- this->PrintSections.erase(this->PrintSections.begin(),
- this->PrintSections.end());
- this->ModulesFound.clear();
-}
-
-//----------------------------------------------------------------------------
-void cmDocumentation::AddDocumentIntroToPrint(const char* intro[2])
-{
- const char* docname = this->GetDocName(false);
- if(intro && docname)
- {
- cmDocumentationSection* section;
- std::string desc("");
-
- desc += docname;
- desc += " - ";
- desc += intro[1];
-
- section = new cmDocumentationSection("Introduction", "NAME");
- section->Append(0, desc.c_str(), 0);
- this->PrintSections.push_back(section);
- }
-}
-
-//----------------------------------------------------------------------------
-bool cmDocumentation::PrintDocumentation(Type ht, std::ostream& os,
- const char* docname)
-{
- if ((this->CurrentFormatter->GetForm() != HTMLForm)
- && (this->CurrentFormatter->GetForm() != DocbookForm)
- && (this->CurrentFormatter->GetForm() != ManForm))
- {
- this->PrintVersion(os);
- }
-
- // Handle Document Name. docname==0 disables intro.
- this->SetDocName("");
- if (docname)
- {
- if (*docname)
- this->SetDocName(docname);
- else // empty string was given. select default if possible
- this->SetDocName(this->GetDefaultDocName(ht));
- }
-
switch (ht)
{
case cmDocumentation::Usage:
- return this->PrintDocumentationUsage(os);
- case cmDocumentation::Single:
- return this->PrintDocumentationSingle(os);
- case cmDocumentation::SingleModule:
- return this->PrintDocumentationSingleModule(os);
- case cmDocumentation::SinglePolicy:
- return this->PrintDocumentationSinglePolicy(os);
- case cmDocumentation::SingleProperty:
- return this->PrintDocumentationSingleProperty(os);
- case cmDocumentation::SingleVariable:
- return this->PrintDocumentationSingleVariable(os);
- case cmDocumentation::List:
- this->PrintDocumentationList(os,"Commands");
- this->PrintDocumentationList(os,"Compatibility Commands");
- return true;
- case cmDocumentation::ModuleList:
- // find the modules first, print the custom module docs only if
- // any custom modules have been found actually, Alex
- this->CreateCustomModulesSection();
- this->CreateModulesSection();
- if (this->AllSections.find("Custom CMake Modules")
- != this->AllSections.end())
- {
- this->PrintDocumentationList(os,"Custom CMake Modules");
- }
- this->PrintDocumentationList(os,"Modules");
- return true;
- case cmDocumentation::PropertyList:
- this->PrintDocumentationList(os,"Properties Description");
- for (std::vector<std::string>::iterator i =
- this->PropertySections.begin();
- i != this->PropertySections.end(); ++i)
- {
- this->PrintDocumentationList(os,i->c_str());
- }
- return true;
- case cmDocumentation::VariableList:
- for (std::vector<std::string>::iterator i =
- this->VariableSections.begin();
- i != this->VariableSections.end(); ++i)
- {
- this->PrintDocumentationList(os,i->c_str());
- }
- return true;
+ return this->PrintUsage(os);
+ case cmDocumentation::Help:
+ return this->PrintHelp(os);
case cmDocumentation::Full:
- return this->PrintDocumentationFull(os);
- case cmDocumentation::Modules:
- return this->PrintDocumentationModules(os);
- case cmDocumentation::CustomModules:
- return this->PrintDocumentationCustomModules(os);
- case cmDocumentation::Policies:
- return this->PrintDocumentationPolicies(os);
- case cmDocumentation::Properties:
- return this->PrintDocumentationProperties(os);
- case cmDocumentation::Variables:
- return this->PrintDocumentationVariables(os);
- case cmDocumentation::Commands:
- return this->PrintDocumentationCurrentCommands(os);
- case cmDocumentation::CompatCommands:
- return this->PrintDocumentationCompatCommands(os);
-
- case cmDocumentation::Copyright:
- return this->PrintCopyright(os);
+ return this->PrintHelpFull(os);
+ case cmDocumentation::OneManual:
+ return this->PrintHelpOneManual(os);
+ case cmDocumentation::OneCommand:
+ return this->PrintHelpOneCommand(os);
+ case cmDocumentation::OneModule:
+ return this->PrintHelpOneModule(os);
+ case cmDocumentation::OnePolicy:
+ return this->PrintHelpOnePolicy(os);
+ case cmDocumentation::OneProperty:
+ return this->PrintHelpOneProperty(os);
+ case cmDocumentation::OneVariable:
+ return this->PrintHelpOneVariable(os);
+ case cmDocumentation::ListManuals:
+ return this->PrintHelpListManuals(os);
+ case cmDocumentation::ListCommands:
+ return this->PrintHelpListCommands(os);
+ case cmDocumentation::ListModules:
+ return this->PrintHelpListModules(os);
+ case cmDocumentation::ListProperties:
+ return this->PrintHelpListProperties(os);
+ case cmDocumentation::ListVariables:
+ return this->PrintHelpListVariables(os);
+ case cmDocumentation::ListPolicies:
+ return this->PrintHelpListPolicies(os);
+ case cmDocumentation::ListGenerators:
+ return this->PrintHelpListGenerators(os);
case cmDocumentation::Version:
- return true;
+ return this->PrintVersion(os);
+ case cmDocumentation::OldCustomModules:
+ return this->PrintOldCustomModules(os);
default: return false;
}
}
//----------------------------------------------------------------------------
-bool cmDocumentation::CreateModulesSection()
-{
- cmDocumentationSection *sec =
- new cmDocumentationSection("Standard CMake Modules", "MODULES");
- this->AllSections["Modules"] = sec;
- std::string cmakeModules = this->CMakeRoot;
- cmakeModules += "/Modules";
- cmsys::Directory dir;
- dir.Load(cmakeModules.c_str());
- if (dir.GetNumberOfFiles() > 0)
- {
- sec->Append(cmDocumentationModulesHeader[0]);
- sec->Append(cmModulesDocumentationDescription);
- this->CreateModuleDocsForDir(dir, *this->AllSections["Modules"]);
- }
- return true;
-}
-
-//----------------------------------------------------------------------------
-bool cmDocumentation::CreateCustomModulesSection()
-{
- bool sectionHasHeader = false;
-
- std::vector<std::string> dirs;
- cmSystemTools::ExpandListArgument(this->CMakeModulePath, dirs);
-
- for(std::vector<std::string>::const_iterator dirIt = dirs.begin();
- dirIt != dirs.end();
- ++dirIt)
- {
- cmsys::Directory dir;
- dir.Load(dirIt->c_str());
- if (dir.GetNumberOfFiles() > 0)
- {
- if (!sectionHasHeader)
- {
- cmDocumentationSection *sec =
- new cmDocumentationSection("Custom CMake Modules","CUSTOM MODULES");
- this->AllSections["Custom CMake Modules"] = sec;
- sec->Append(cmDocumentationCustomModulesHeader[0]);
- sec->Append(cmCustomModulesDocumentationDescription);
- sectionHasHeader = true;
- }
- this->CreateModuleDocsForDir
- (dir, *this->AllSections["Custom CMake Modules"]);
- }
- }
-
- return true;
-}
-
-//----------------------------------------------------------------------------
-void cmDocumentation
-::CreateModuleDocsForDir(cmsys::Directory& dir,
- cmDocumentationSection &moduleSection)
-{
- // sort the files alphabetically, so the docs for one module are easier
- // to find than if they are in random order
- std::vector<std::string> sortedFiles;
- for(unsigned int i = 0; i < dir.GetNumberOfFiles(); ++i)
- {
- sortedFiles.push_back(dir.GetFile(i));
- }
- std::sort(sortedFiles.begin(), sortedFiles.end());
-
- for(std::vector<std::string>::const_iterator fname = sortedFiles.begin();
- fname!=sortedFiles.end(); ++fname)
- {
- if(fname->length() > 6)
- {
- if(fname->substr(fname->length()-6, 6) == ".cmake")
- {
- std::string moduleName = fname->substr(0, fname->length()-6);
- // this check is to avoid creating documentation for the modules with
- // the same name in multiple directories of CMAKE_MODULE_PATH
- if (this->ModulesFound.find(moduleName) == this->ModulesFound.end())
- {
- this->ModulesFound.insert(moduleName);
- std::string path = dir.GetPath();
- path += "/";
- path += (*fname);
- this->CreateSingleModule(path.c_str(), moduleName.c_str(),
- moduleSection);
- }
- }
- }
- }
-}
-
-//----------------------------------------------------------------------------
-bool cmDocumentation::CreateSingleModule(const char* fname,
- const char* moduleName,
- cmDocumentationSection &moduleSection)
-{
- std::ifstream fin(fname);
- if(!fin)
- {
- std::cerr << "Internal error: can not open module." << fname << std::endl;
- return false;
- }
- std::string line;
- std::string text;
- std::string brief;
- brief = " ";
- bool newParagraph = true;
- while ( fin && cmSystemTools::GetLineFromStream(fin, line) )
- {
- if(line.size() && line[0] == '#')
- {
- /* line beginnings with ## are mark-up ignore them */
- if (line.size()>=2 && line[1] == '#') continue;
- // blank line
- if(line.size() <= 2)
- {
- text += "\n";
- newParagraph = true;
- }
- else if(line[2] == '-')
- {
- brief = line.c_str()+4;
- }
- else
- {
- // two spaces
- if(line[1] == ' ' && line[2] == ' ')
- {
- if(!newParagraph)
- {
- text += "\n";
- newParagraph = true;
- }
- // Skip #, and leave space for preformatted
- text += line.c_str()+1;
- text += "\n";
- }
- else if(line[1] == ' ')
- {
- if(!newParagraph)
- {
- text += " ";
- }
- newParagraph = false;
- // skip # and space
- text += line.c_str()+2;
- }
- else
- {
- if(!newParagraph)
- {
- text += " ";
- }
- newParagraph = false;
- // skip #
- text += line.c_str()+1;
- }
- }
- }
- else
- {
- break;
- }
- }
-
- if(text.length() < 2 && brief.length() == 1)
- {
- return false;
- }
-
- char* pname = strcpy(new char[strlen(moduleName)+1], moduleName);
- char* ptext = strcpy(new char[text.length()+1], text.c_str());
- this->ModuleStrings.push_back(pname);
- this->ModuleStrings.push_back(ptext);
- char* pbrief = strcpy(new char[brief.length()+1], brief.c_str());
- this->ModuleStrings.push_back(pbrief);
- moduleSection.Append(pname, pbrief, ptext);
- return true;
-}
-
-
-//----------------------------------------------------------------------------
bool cmDocumentation::PrintRequestedDocumentation(std::ostream& os)
{
+ int count = 0;
bool result = true;
// Loop over requested documentation types.
@@ -587,16 +160,14 @@ bool cmDocumentation::PrintRequestedDocumentation(std::ostream& os)
i != this->RequestedHelpItems.end();
++i)
{
- this->SetForm(i->HelpForm, i->ManSection);
this->CurrentArgument = i->Argument;
// If a file name was given, use it. Otherwise, default to the
// given stream.
- std::ofstream* fout = 0;
+ cmsys::ofstream* fout = 0;
std::ostream* s = &os;
- std::string docname("");
- if(i->Filename.length() > 0)
+ if(!i->Filename.empty())
{
- fout = new std::ofstream(i->Filename.c_str(), std::ios::out);
+ fout = new cmsys::ofstream(i->Filename.c_str(), std::ios::out);
if(fout)
{
s = fout;
@@ -605,14 +176,14 @@ bool cmDocumentation::PrintRequestedDocumentation(std::ostream& os)
{
result = false;
}
- if(i->Filename != "-")
- {
- docname = cmSystemTools::GetFilenameWithoutLastExtension(i->Filename);
- }
+ }
+ else if(++count > 1)
+ {
+ os << "\n\n";
}
// Print this documentation type to the stream.
- if(!this->PrintDocumentation(i->HelpType, *s, docname.c_str()) || !*s)
+ if(!this->PrintDocumentation(i->HelpType, *s) || !*s)
{
result = false;
}
@@ -634,33 +205,30 @@ bool cmDocumentation::PrintRequestedDocumentation(std::ostream& os)
};
-cmDocumentation::Form cmDocumentation::GetFormFromFilename(
- const std::string& filename,
- int* manSection)
+void cmDocumentation::WarnFormFromFilename(
+ cmDocumentation::RequestedHelpItem& request, bool& result)
{
- std::string ext = cmSystemTools::GetFilenameLastExtension(filename);
+ std::string ext = cmSystemTools::GetFilenameLastExtension(request.Filename);
ext = cmSystemTools::UpperCase(ext);
if ((ext == ".HTM") || (ext == ".HTML"))
{
- return cmDocumentation::HTMLForm;
+ request.HelpType = cmDocumentation::None;
+ result = true;
+ cmSystemTools::Message("Warning: HTML help format no longer supported");
}
-
- if (ext == ".DOCBOOK")
+ else if (ext == ".DOCBOOK")
{
- return cmDocumentation::DocbookForm;
+ request.HelpType = cmDocumentation::None;
+ result = true;
+ cmSystemTools::Message("Warning: Docbook help format no longer supported");
}
-
// ".1" to ".9" should be manpages
- if ((ext.length()==2) && (ext[1] >='1') && (ext[1]<='9'))
+ else if ((ext.length()==2) && (ext[1] >='1') && (ext[1]<='9'))
{
- if (manSection)
- {
- *manSection = ext[1] - '0';
- }
- return cmDocumentation::ManForm;
+ request.HelpType = cmDocumentation::None;
+ result = true;
+ cmSystemTools::Message("Warning: Man help format no longer supported");
}
-
- return cmDocumentation::TextForm;
}
//----------------------------------------------------------------------------
@@ -668,29 +236,9 @@ void cmDocumentation::addCommonStandardDocSections()
{
cmDocumentationSection *sec;
- sec = new cmDocumentationSection("Author","AUTHOR");
- sec->Append(cmDocumentationEntry
- (0,
- "This manual page was generated by the \"--help-man\" option.",
- 0));
- this->AllSections["Author"] = sec;
-
- sec = new cmDocumentationSection("Copyright","COPYRIGHT");
- sec->Append(cmDocumentationCopyright);
- this->AllSections["Copyright"] = sec;
-
- sec = new cmDocumentationSection("See Also","SEE ALSO");
- sec->Append(cmDocumentationStandardSeeAlso);
- this->AllSections["Standard See Also"] = sec;
-
sec = new cmDocumentationSection("Options","OPTIONS");
sec->Append(cmDocumentationStandardOptions);
this->AllSections["Options"] = sec;
-
- sec = new cmDocumentationSection("Compatibility Commands",
- "COMPATIBILITY COMMANDS");
- sec->Append(cmCompatCommandsDocumentationDescription);
- this->AllSections["Compatibility Commands"] = sec;
}
//----------------------------------------------------------------------------
@@ -698,27 +246,9 @@ void cmDocumentation::addCMakeStandardDocSections()
{
cmDocumentationSection *sec;
- sec = new cmDocumentationSection("Properties","PROPERTIES");
- sec->Append(cmPropertiesDocumentationDescription);
- this->AllSections["Properties Description"] = sec;
-
sec = new cmDocumentationSection("Generators","GENERATORS");
sec->Append(cmDocumentationGeneratorsHeader);
this->AllSections["Generators"] = sec;
-
- this->PropertySections.push_back("Properties of Global Scope");
- this->PropertySections.push_back("Properties on Directories");
- this->PropertySections.push_back("Properties on Targets");
- this->PropertySections.push_back("Properties on Tests");
- this->PropertySections.push_back("Properties on Source Files");
- this->PropertySections.push_back("Properties on Cache Entries");
-
- this->VariableSections.push_back("Variables that Provide Information");
- this->VariableSections.push_back("Variables That Change Behavior");
- this->VariableSections.push_back("Variables That Describe the System");
- this->VariableSections.push_back("Variables that Control the Build");
- this->VariableSections.push_back("Variables for Languages");
-
}
//----------------------------------------------------------------------------
@@ -737,347 +267,6 @@ void cmDocumentation::addCPackStandardDocSections()
sec = new cmDocumentationSection("Generators","GENERATORS");
sec->Append(cmDocumentationGeneratorsHeader);
this->AllSections["Generators"] = sec;
-
- this->VariableSections.push_back(
- "Variables common to all CPack generators");
-}
-
-void cmDocumentation::addAutomaticVariableSections(const std::string& section)
-{
- std::vector<std::string>::iterator it;
- it = std::find(this->VariableSections.begin(),
- this->VariableSections.end(),
- section);
- /* if the section does not exist then add it */
- if (it==this->VariableSections.end())
- {
- this->VariableSections.push_back(section);
- }
-}
-//----------------------------------------------------------------------------
-int cmDocumentation::getDocumentedModulesListInDir(
- std::string path,
- std::string globExpr,
- documentedModulesList_t& docedModuleList)
-{
- cmsys::Glob gl;
- std::string findExpr;
- std::vector<std::string> files;
- std::string line;
- documentedModuleSectionPair_t docPair;
- int nbDocumentedModules = 0;
-
- findExpr = path + "/" + globExpr;
- if (gl.FindFiles(findExpr))
- {
- files = gl.GetFiles();
- for (std::vector<std::string>::iterator itf=files.begin();
- itf!=files.end();++itf)
- {
- std::ifstream fin((*itf).c_str());
- // file access trouble ignore it (ignore this kind of error)
- if (!fin) continue;
- /* read first line in order to get doc section */
- if (cmSystemTools::GetLineFromStream(fin, line))
- {
- /* Doc section indicates that
- * this file has structured doc in it.
- */
- if (line.find("##section")!=std::string::npos)
- {
- // ok found one more documented module
- ++nbDocumentedModules;
- docPair.first = *itf;
- // 10 is the size of '##section' + 1
- docPair.second = line.substr(10,std::string::npos);
- docedModuleList.push_back(docPair);
- }
- // No else if no section is found (undocumented module)
- }
- // No else cannot read first line (ignore this kind of error)
- line = "";
- }
- }
- if (nbDocumentedModules>0)
- {
- return 0;
- }
- else
- {
- return 1;
- }
-}
-
-//----------------------------------------------------------------------------
-static void trim(std::string& s)
-{
- std::string::size_type pos = s.find_last_not_of(' ');
- if(pos != std::string::npos)
- {
- s.erase(pos + 1);
- pos = s.find_first_not_of(' ');
- if(pos != std::string::npos) s.erase(0, pos);
- }
- else
- {
- s.erase(s.begin(), s.end());
- }
-}
-
-int cmDocumentation::GetStructuredDocFromFile(
- const char* fname,
- std::vector<cmDocumentationEntry>& commands,
- cmake* cm)
-{
- typedef enum sdoce {
- SDOC_NONE, SDOC_MODULE, SDOC_MACRO, SDOC_FUNCTION, SDOC_VARIABLE,
- SDOC_SECTION,
- SDOC_UNKNOWN} sdoc_t;
- int nbDocItemFound = 0;
- int docCtxIdx = 0;
- std::vector<int> docContextStack(60);
- docContextStack[docCtxIdx]=SDOC_NONE;
- cmDocumentationEntry e;
- std::ifstream fin(fname);
- if(!fin)
- {
- return nbDocItemFound;
- }
- std::string section;
- std::string name;
- std::string full;
- std::string brief;
- std::string line;
- bool newCtx = false; /* we've just entered ##<beginkey> context */
- bool inBrief = false; /* we are currently parsing brief desc. */
- bool inFullFirstParagraph = false; /* we are currently parsing full
- desc. first paragraph */
- brief = "";
- full = "";
- bool newParagraph = true;
- while ( fin && cmSystemTools::GetLineFromStream(fin, line) )
- {
- if(line.size() && line[0] == '#')
- {
- /* handle structured doc context */
- if ((line.size()>=2) && line[1]=='#')
- {
- /* markup word is following '##' stopping at first space
- * Some markup word like 'section' may have more characters
- * following but we don't handle those here.
- */
- std::string mkword = line.substr(2,line.find(' ',2)-2);
- if (mkword=="macro")
- {
- docCtxIdx++;
- docContextStack[docCtxIdx]=SDOC_MACRO;
- newCtx = true;
- }
- else if (mkword=="variable")
- {
- docCtxIdx++;
- docContextStack[docCtxIdx]=SDOC_VARIABLE;
- newCtx = true;
- }
- else if (mkword=="function")
- {
- docCtxIdx++;
- docContextStack[docCtxIdx]=SDOC_FUNCTION;
- newCtx = true;
- }
- else if (mkword=="module")
- {
- docCtxIdx++;
- docContextStack[docCtxIdx]=SDOC_MODULE;
- newCtx = true;
- }
- else if (mkword=="section")
- {
- docCtxIdx++;
- docContextStack[docCtxIdx]=SDOC_SECTION;
- // 10 is the size of '##section' + 1
- section = line.substr(10,std::string::npos);
- /* drop the rest of the line */
- line = "";
- newCtx = true;
- }
- else if (mkword.substr(0,3)=="end")
- {
- switch (docContextStack[docCtxIdx]) {
- case SDOC_MACRO:
- /* for now MACRO and FUNCTION are handled in the same way */
- case SDOC_FUNCTION:
- commands.push_back(cmDocumentationEntry(name.c_str(),
- brief.c_str(),full.c_str()));
- break;
- case SDOC_VARIABLE:
- this->addAutomaticVariableSections(section);
- cm->DefineProperty
- (name.c_str(), cmProperty::VARIABLE,
- brief.c_str(),
- full.c_str(),false,
- section.c_str());
- break;
- case SDOC_MODULE:
- /* not implemented */
- break;
- case SDOC_SECTION:
- /* not implemented */
- break;
- default:
- /* ignore other cases */
- break;
- }
- docCtxIdx--;
- newCtx = false;
- ++nbDocItemFound;
- }
- else
- {
- // error out unhandled context
- return nbDocItemFound;
- }
- /* context is set go to next doc line */
- continue;
- }
-
- // Now parse the text attached to the context
-
- // The first line after the context mark-up contains::
- // name - brief until. (brief is dot terminated or
- // followed by a blank line)
- if (newCtx)
- {
- // no brief (for easy variable definition)
- if (line.find("-")==std::string::npos)
- {
- name = line.substr(1,std::string::npos);
- trim(name);
- brief = "";
- inBrief = false;
- full = "";
- }
- // here we have a name and brief beginning
- else
- {
- name = line.substr(1,line.find("-")-1);
- trim(name);
- // we are parsing the brief context
- brief = line.substr(line.find("-")+1,std::string::npos);
- trim(brief);
- // Brief may already be terminated on the first line
- if (brief.find('.')!=std::string::npos)
- {
- inBrief = false;
- full = brief.substr(brief.find('.')+1,std::string::npos);
- trim(full);
- inFullFirstParagraph = true;
- brief = brief.substr(0,brief.find('.'));
- }
- // brief is continued on following lines
- else
- {
- inBrief = true;
- full = "";
- }
- }
- newCtx = false;
- continue;
- }
- // blank line
- if(line.size() <= 2)
- {
- if (inBrief) {
- inBrief = false;
- full = "";
- } else {
- if (full.length()>0)
- {
- full += "\n";
- }
- // the first paragraph of full has ended
- inFullFirstParagraph = false;
- }
- newParagraph = true;
- }
- // brief is terminated by '.'
- else if (inBrief && (line.find('.')!=std::string::npos))
- {
- /* the brief just ended */
- inBrief = false;
- std::string endBrief = line.substr(1,line.find('.'));
- trim(endBrief);
- trim(brief);
- brief += " " + endBrief;
- full += line.substr(line.find('.')+1,std::string::npos);
- trim(full);
- inFullFirstParagraph = true;
- }
- // we handle full text or multi-line brief.
- else
- {
- std::string* text;
- if (inBrief)
- {
- text = &brief;
- }
- else
- {
- text = &full;
- }
- // two spaces
- if(line[1] == ' ' && line[2] == ' ')
- {
- // there is no "full first paragraph at all."
- if (line[3] == ' ')
- {
- inFullFirstParagraph = false;
- }
-
- if(!newParagraph && !inFullFirstParagraph)
- {
- *text += "\n";
- newParagraph = true;
- }
- // Skip #, and leave space for pre-formatted
- if (inFullFirstParagraph)
- {
- std::string temp = line.c_str()+1;
- trim(temp);
- *text += " " + temp;
- }
- else
- {
- *text += line.c_str()+1;
- *text += "\n";
- }
- }
- else if(line[1] == ' ')
- {
- if(!newParagraph)
- {
- *text += " ";
- }
- newParagraph = false;
- // skip # and space
- *text += line.c_str()+2;
- }
- else
- {
- if(!newParagraph)
- {
- *text += " ";
- }
- newParagraph = false;
- // skip #
- *text += line.c_str()+1;
- }
- }
- }
- /* next line is not the first context line */
- newCtx = false;
- }
- return nbDocItemFound;
}
//----------------------------------------------------------------------------
@@ -1089,7 +278,6 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv,
{
RequestedHelpItem help;
help.HelpType = cmDocumentation::Usage;
- help.HelpForm = cmDocumentation::UsageForm;
this->RequestedHelpItems.push_back(help);
return true;
}
@@ -1112,155 +300,168 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv,
(strcmp(argv[i], "-h") == 0) ||
(strcmp(argv[i], "-H") == 0))
{
- help.HelpType = cmDocumentation::Usage;
- help.HelpForm = cmDocumentation::UsageForm;
+ help.HelpType = cmDocumentation::Help;
GET_OPT_ARGUMENT(help.Argument);
help.Argument = cmSystemTools::LowerCase(help.Argument);
// special case for single command
if (!help.Argument.empty())
{
- help.HelpType = cmDocumentation::Single;
+ help.HelpType = cmDocumentation::OneCommand;
}
}
else if(strcmp(argv[i], "--help-properties") == 0)
{
- help.HelpType = cmDocumentation::Properties;
+ help.HelpType = cmDocumentation::OneManual;
+ help.Argument = "cmake-properties.7";
GET_OPT_ARGUMENT(help.Filename);
- help.HelpForm = this->GetFormFromFilename(help.Filename,
- &help.ManSection);
+ this->WarnFormFromFilename(help, result);
}
else if(strcmp(argv[i], "--help-policies") == 0)
{
- help.HelpType = cmDocumentation::Policies;
+ help.HelpType = cmDocumentation::OneManual;
+ help.Argument = "cmake-policies.7";
GET_OPT_ARGUMENT(help.Filename);
- help.HelpForm = this->GetFormFromFilename(help.Filename,
- &help.ManSection);
+ this->WarnFormFromFilename(help, result);
}
else if(strcmp(argv[i], "--help-variables") == 0)
{
- help.HelpType = cmDocumentation::Variables;
+ help.HelpType = cmDocumentation::OneManual;
+ help.Argument = "cmake-variables.7";
GET_OPT_ARGUMENT(help.Filename);
- help.HelpForm = this->GetFormFromFilename(help.Filename,
- &help.ManSection);
+ this->WarnFormFromFilename(help, result);
}
else if(strcmp(argv[i], "--help-modules") == 0)
{
- help.HelpType = cmDocumentation::Modules;
+ help.HelpType = cmDocumentation::OneManual;
+ help.Argument = "cmake-modules.7";
GET_OPT_ARGUMENT(help.Filename);
- help.HelpForm = this->GetFormFromFilename(help.Filename,
- &help.ManSection);
+ this->WarnFormFromFilename(help, result);
}
else if(strcmp(argv[i], "--help-custom-modules") == 0)
{
- help.HelpType = cmDocumentation::CustomModules;
GET_OPT_ARGUMENT(help.Filename);
- help.HelpForm = this->GetFormFromFilename(help.Filename,
- &help.ManSection);
+ cmSystemTools::Message(
+ "Warning: --help-custom-modules no longer supported");
+ if(help.Filename.empty())
+ {
+ return true;
+ }
+ // Avoid breaking old project builds completely by at least generating
+ // the output file. Abuse help.Argument to give the file name to
+ // PrintOldCustomModules without disrupting our internal API.
+ help.HelpType = cmDocumentation::OldCustomModules;
+ help.Argument = cmSystemTools::GetFilenameName(help.Filename);
}
else if(strcmp(argv[i], "--help-commands") == 0)
{
- help.HelpType = cmDocumentation::Commands;
+ help.HelpType = cmDocumentation::OneManual;
+ help.Argument = "cmake-commands.7";
GET_OPT_ARGUMENT(help.Filename);
- help.HelpForm = this->GetFormFromFilename(help.Filename,
- &help.ManSection);
+ this->WarnFormFromFilename(help, result);
}
else if(strcmp(argv[i], "--help-compatcommands") == 0)
{
- help.HelpType = cmDocumentation::CompatCommands;
GET_OPT_ARGUMENT(help.Filename);
- help.HelpForm = this->GetFormFromFilename(help.Filename,
- &help.ManSection);
+ cmSystemTools::Message(
+ "Warning: --help-compatcommands no longer supported");
+ return true;
}
else if(strcmp(argv[i], "--help-full") == 0)
{
help.HelpType = cmDocumentation::Full;
GET_OPT_ARGUMENT(help.Filename);
- help.HelpForm = this->GetFormFromFilename(help.Filename,
- &help.ManSection);
+ this->WarnFormFromFilename(help, result);
}
else if(strcmp(argv[i], "--help-html") == 0)
{
- help.HelpType = cmDocumentation::Full;
GET_OPT_ARGUMENT(help.Filename);
- help.HelpForm = cmDocumentation::HTMLForm;
+ cmSystemTools::Message("Warning: --help-html no longer supported");
+ return true;
}
else if(strcmp(argv[i], "--help-man") == 0)
{
- help.HelpType = cmDocumentation::Full;
GET_OPT_ARGUMENT(help.Filename);
- help.HelpForm = cmDocumentation::ManForm;
- help.ManSection = 1;
+ cmSystemTools::Message("Warning: --help-man no longer supported");
+ return true;
}
else if(strcmp(argv[i], "--help-command") == 0)
{
- help.HelpType = cmDocumentation::Single;
+ help.HelpType = cmDocumentation::OneCommand;
GET_OPT_ARGUMENT(help.Argument);
GET_OPT_ARGUMENT(help.Filename);
help.Argument = cmSystemTools::LowerCase(help.Argument);
- help.HelpForm = this->GetFormFromFilename(help.Filename,
- &help.ManSection);
+ this->WarnFormFromFilename(help, result);
}
else if(strcmp(argv[i], "--help-module") == 0)
{
- help.HelpType = cmDocumentation::SingleModule;
+ help.HelpType = cmDocumentation::OneModule;
GET_OPT_ARGUMENT(help.Argument);
GET_OPT_ARGUMENT(help.Filename);
- help.HelpForm = this->GetFormFromFilename(help.Filename,
- &help.ManSection);
+ this->WarnFormFromFilename(help, result);
}
else if(strcmp(argv[i], "--help-property") == 0)
{
- help.HelpType = cmDocumentation::SingleProperty;
+ help.HelpType = cmDocumentation::OneProperty;
GET_OPT_ARGUMENT(help.Argument);
GET_OPT_ARGUMENT(help.Filename);
- help.HelpForm = this->GetFormFromFilename(help.Filename,
- &help.ManSection);
+ this->WarnFormFromFilename(help, result);
}
else if(strcmp(argv[i], "--help-policy") == 0)
{
- help.HelpType = cmDocumentation::SinglePolicy;
+ help.HelpType = cmDocumentation::OnePolicy;
GET_OPT_ARGUMENT(help.Argument);
GET_OPT_ARGUMENT(help.Filename);
- help.HelpForm = this->GetFormFromFilename(help.Filename,
- &help.ManSection);
+ this->WarnFormFromFilename(help, result);
}
else if(strcmp(argv[i], "--help-variable") == 0)
{
- help.HelpType = cmDocumentation::SingleVariable;
+ help.HelpType = cmDocumentation::OneVariable;
GET_OPT_ARGUMENT(help.Argument);
GET_OPT_ARGUMENT(help.Filename);
- help.HelpForm = this->GetFormFromFilename(help.Filename,
- &help.ManSection);
+ this->WarnFormFromFilename(help, result);
+ }
+ else if(strcmp(argv[i], "--help-manual") == 0)
+ {
+ help.HelpType = cmDocumentation::OneManual;
+ GET_OPT_ARGUMENT(help.Argument);
+ GET_OPT_ARGUMENT(help.Filename);
+ this->WarnFormFromFilename(help, result);
}
else if(strcmp(argv[i], "--help-command-list") == 0)
{
- help.HelpType = cmDocumentation::List;
+ help.HelpType = cmDocumentation::ListCommands;
GET_OPT_ARGUMENT(help.Filename);
- help.HelpForm = cmDocumentation::TextForm;
}
else if(strcmp(argv[i], "--help-module-list") == 0)
{
- help.HelpType = cmDocumentation::ModuleList;
+ help.HelpType = cmDocumentation::ListModules;
GET_OPT_ARGUMENT(help.Filename);
- help.HelpForm = cmDocumentation::TextForm;
}
else if(strcmp(argv[i], "--help-property-list") == 0)
{
- help.HelpType = cmDocumentation::PropertyList;
+ help.HelpType = cmDocumentation::ListProperties;
GET_OPT_ARGUMENT(help.Filename);
- help.HelpForm = cmDocumentation::TextForm;
}
else if(strcmp(argv[i], "--help-variable-list") == 0)
{
- help.HelpType = cmDocumentation::VariableList;
+ help.HelpType = cmDocumentation::ListVariables;
+ GET_OPT_ARGUMENT(help.Filename);
+ }
+ else if(strcmp(argv[i], "--help-policy-list") == 0)
+ {
+ help.HelpType = cmDocumentation::ListPolicies;
+ GET_OPT_ARGUMENT(help.Filename);
+ }
+ else if(strcmp(argv[i], "--help-manual-list") == 0)
+ {
+ help.HelpType = cmDocumentation::ListManuals;
GET_OPT_ARGUMENT(help.Filename);
- help.HelpForm = cmDocumentation::TextForm;
}
else if(strcmp(argv[i], "--copyright") == 0)
{
- help.HelpType = cmDocumentation::Copyright;
GET_OPT_ARGUMENT(help.Filename);
- help.HelpForm = cmDocumentation::UsageForm;
+ cmSystemTools::Message("Warning: --copyright no longer supported");
+ return true;
}
else if((strcmp(argv[i], "--version") == 0) ||
(strcmp(argv[i], "-version") == 0) ||
@@ -1268,7 +469,6 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv,
{
help.HelpType = cmDocumentation::Version;
GET_OPT_ARGUMENT(help.Filename);
- help.HelpForm = cmDocumentation::UsageForm;
}
if(help.HelpType != None)
{
@@ -1281,37 +481,9 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv,
}
//----------------------------------------------------------------------------
-void cmDocumentation::Print(Form f, int manSection, std::ostream& os)
-{
- this->SetForm(f, manSection);
- this->Print(os);
-}
-
-//----------------------------------------------------------------------------
-void cmDocumentation::Print(std::ostream& os)
-{
- // if the formatter supports it, print a master index for
- // all sections
- this->CurrentFormatter->PrintIndex(os, this->PrintSections);
- for(unsigned int i=0; i < this->PrintSections.size(); ++i)
- {
- std::string name = this->PrintSections[i]->
- GetName((this->CurrentFormatter->GetForm()));
- this->CurrentFormatter->PrintSection(os,*this->PrintSections[i],
- name.c_str());
- }
-}
-
-//----------------------------------------------------------------------------
-void cmDocumentation::SetName(const char* name)
+void cmDocumentation::SetName(const std::string& name)
{
- this->NameString = name?name:"";
-}
-
-//----------------------------------------------------------------------------
-void cmDocumentation::SetDocName(const char *docname)
-{
- this->DocName = docname?docname:"";
+ this->NameString = name;
}
//----------------------------------------------------------------------------
@@ -1338,7 +510,7 @@ void cmDocumentation::SetSection(const char *name,
//----------------------------------------------------------------------------
void cmDocumentation::SetSection(const char *name,
- const char *docs[][3])
+ const char *docs[][2])
{
cmDocumentationSection *sec =
new cmDocumentationSection(name,
@@ -1360,7 +532,7 @@ void cmDocumentation
//----------------------------------------------------------------------------
void cmDocumentation::PrependSection(const char *name,
- const char *docs[][3])
+ const char *docs[][2])
{
cmDocumentationSection *sec = 0;
if (this->AllSections.find(name) == this->AllSections.end())
@@ -1396,7 +568,7 @@ void cmDocumentation::PrependSection(const char *name,
//----------------------------------------------------------------------------
void cmDocumentation::AppendSection(const char *name,
- const char *docs[][3])
+ const char *docs[][2])
{
cmDocumentationSection *sec = 0;
if (this->AllSections.find(name) == this->AllSections.end())
@@ -1451,474 +623,277 @@ void cmDocumentation::PrependSection(const char *name,
}
//----------------------------------------------------------------------------
-void cmDocumentation::SetSeeAlsoList(const char *data[][3])
+void cmDocumentation::GlobHelp(std::vector<std::string>& files,
+ std::string const& pattern)
{
- cmDocumentationSection *sec =
- new cmDocumentationSection("See Also", "SEE ALSO");
- this->AllSections["See Also"] = sec;
- this->SeeAlsoString = ".B ";
- int i = 0;
- while(data[i][1])
+ cmsys::Glob gl;
+ std::string findExpr =
+ cmSystemTools::GetCMakeRoot() + "/Help/" + pattern + ".rst";
+ if(gl.FindFiles(findExpr))
{
- this->SeeAlsoString += data[i][1];
- this->SeeAlsoString += data[i+1][1]? "(1), ":"(1)";
- ++i;
+ files = gl.GetFiles();
}
- sec->Append(0,this->SeeAlsoString.c_str(),0);
- sec->Append(cmDocumentationStandardSeeAlso);
}
//----------------------------------------------------------------------------
-bool cmDocumentation::PrintDocumentationGeneric(std::ostream& os,
- const char *section)
+void cmDocumentation::PrintNames(std::ostream& os,
+ std::string const& pattern)
{
- if(this->AllSections.find(section) == this->AllSections.end())
- {
- os << "Internal error: " << section << " list is empty." << std::endl;
- return false;
- }
- if(this->CurrentArgument.length() == 0)
- {
- os << "Required argument missing.\n";
- return false;
- }
- const std::vector<cmDocumentationEntry> &entries =
- this->AllSections[section]->GetEntries();
- for(std::vector<cmDocumentationEntry>::const_iterator ei =
- entries.begin();
- ei != entries.end(); ++ei)
+ std::vector<std::string> files;
+ this->GlobHelp(files, pattern);
+ std::vector<std::string> names;
+ for (std::vector<std::string>::const_iterator i = files.begin();
+ i != files.end(); ++i)
{
- if(this->CurrentArgument == ei->Name)
+ std::string line;
+ cmsys::ifstream fin(i->c_str());
+ while(fin && cmSystemTools::GetLineFromStream(fin, line))
{
- this->PrintDocumentationCommand(os, *ei);
- return true;
+ if(!line.empty() && (isalnum(line[0]) || line[0] == '<'))
+ {
+ names.push_back(line);
+ break;
+ }
}
}
- return false;
+ std::sort(names.begin(), names.end());
+ for (std::vector<std::string>::iterator i = names.begin();
+ i != names.end(); ++i)
+ {
+ os << *i << "\n";
+ }
}
//----------------------------------------------------------------------------
-bool cmDocumentation::PrintDocumentationSingle(std::ostream& os)
+bool cmDocumentation::PrintFiles(std::ostream& os,
+ std::string const& pattern)
{
- if (this->PrintDocumentationGeneric(os,"Commands"))
- {
- return true;
- }
- if (this->PrintDocumentationGeneric(os,"Compatibility Commands"))
+ bool found = false;
+ std::vector<std::string> files;
+ this->GlobHelp(files, pattern);
+ std::sort(files.begin(), files.end());
+ cmRST r(os, cmSystemTools::GetCMakeRoot() + "/Help");
+ for (std::vector<std::string>::const_iterator i = files.begin();
+ i != files.end(); ++i)
{
- return true;
+ found = r.ProcessFile(*i) || found;
}
-
- // Argument was not a command. Complain.
- os << "Argument \"" << this->CurrentArgument.c_str()
- << "\" to --help-command is not a CMake command. "
- << "Use --help-command-list to see all commands.\n";
- return false;
+ return found;
}
//----------------------------------------------------------------------------
-bool cmDocumentation::PrintDocumentationSingleModule(std::ostream& os)
+bool cmDocumentation::PrintHelpFull(std::ostream& os)
{
- if(this->CurrentArgument.length() == 0)
- {
- os << "Argument --help-module needs a module name.\n";
- return false;
- }
-
- std::string moduleName;
- // find the module
- std::vector<std::string> dirs;
- cmSystemTools::ExpandListArgument(this->CMakeModulePath, dirs);
- for(std::vector<std::string>::const_iterator dirIt = dirs.begin();
- dirIt != dirs.end();
- ++dirIt)
- {
- moduleName = *dirIt;
- moduleName += "/";
- moduleName += this->CurrentArgument;
- moduleName += ".cmake";
- if(cmSystemTools::FileExists(moduleName.c_str()))
- {
- break;
- }
- moduleName = "";
- }
-
- if (moduleName.empty())
- {
- moduleName = this->CMakeRoot;
- moduleName += "/Modules/";
- moduleName += this->CurrentArgument;
- moduleName += ".cmake";
- if(!cmSystemTools::FileExists(moduleName.c_str()))
- {
- moduleName = "";
- }
- }
-
- if(!moduleName.empty())
- {
- cmDocumentationSection *sec =
- new cmDocumentationSection("Standard CMake Modules", "MODULES");
- this->AllSections["Modules"] = sec;
- if (this->CreateSingleModule(moduleName.c_str(),
- this->CurrentArgument.c_str(),
- *this->AllSections["Modules"]))
- {
- if(this->AllSections["Modules"]->GetEntries().size())
- {
- this->PrintDocumentationCommand
- (os, this->AllSections["Modules"]->GetEntries()[0]);
- os << "\n Defined in: ";
- os << moduleName << "\n";
- return true;
- }
- else
- {
- return false;
- }
- }
- }
-
- // Argument was not a module. Complain.
- os << "Argument \"" << this->CurrentArgument.c_str()
- << "\" to --help-module is not a CMake module.\n";
- return false;
+ return this->PrintFiles(os, "index");
}
//----------------------------------------------------------------------------
-bool cmDocumentation::PrintDocumentationSingleProperty(std::ostream& os)
+bool cmDocumentation::PrintHelpOneManual(std::ostream& os)
{
- bool done = false;
- for (std::vector<std::string>::iterator i =
- this->PropertySections.begin();
- !done && i != this->PropertySections.end(); ++i)
+ std::string mname = this->CurrentArgument;
+ std::string::size_type mlen = mname.length();
+ if(mlen > 3 && mname[mlen-3] == '(' &&
+ mname[mlen-1] == ')')
{
- done = this->PrintDocumentationGeneric(os,i->c_str());
+ mname = mname.substr(0, mlen-3) + "." + mname[mlen-2];
}
-
- if (done)
+ if(this->PrintFiles(os, "manual/" + mname) ||
+ this->PrintFiles(os, "manual/" + mname + ".[0-9]"))
{
return true;
}
-
- // Argument was not a command. Complain.
- os << "Argument \"" << this->CurrentArgument.c_str()
- << "\" to --help-property is not a CMake property. "
- << "Use --help-property-list to see all properties.\n";
+ // Argument was not a manual. Complain.
+ os << "Argument \"" << this->CurrentArgument
+ << "\" to --help-manual is not an available manual. "
+ << "Use --help-manual-list to see all available manuals.\n";
return false;
}
//----------------------------------------------------------------------------
-bool cmDocumentation::PrintDocumentationSinglePolicy(std::ostream& os)
+bool cmDocumentation::PrintHelpListManuals(std::ostream& os)
+{
+ this->PrintNames(os, "manual/*");
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintHelpOneCommand(std::ostream& os)
{
- if (this->PrintDocumentationGeneric(os,"Policies"))
+ std::string cname = cmSystemTools::LowerCase(this->CurrentArgument);
+ if(this->PrintFiles(os, "command/" + cname))
{
return true;
}
-
// Argument was not a command. Complain.
- os << "Argument \"" << this->CurrentArgument.c_str()
- << "\" to --help-policy is not a CMake policy.\n";
+ os << "Argument \"" << this->CurrentArgument
+ << "\" to --help-command is not a CMake command. "
+ << "Use --help-command-list to see all commands.\n";
return false;
}
//----------------------------------------------------------------------------
-bool cmDocumentation::PrintDocumentationSingleVariable(std::ostream& os)
+bool cmDocumentation::PrintHelpListCommands(std::ostream& os)
{
- bool done = false;
- for (std::vector<std::string>::iterator i =
- this->VariableSections.begin();
- !done && i != this->VariableSections.end(); ++i)
- {
- done = this->PrintDocumentationGeneric(os,i->c_str());
- }
+ this->PrintNames(os, "command/*");
+ return true;
+}
- if (done)
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintHelpOneModule(std::ostream& os)
+{
+ std::string mname = this->CurrentArgument;
+ if(this->PrintFiles(os, "module/" + mname))
{
return true;
}
-
- // Argument was not a command. Complain.
- os << "Argument \"" << this->CurrentArgument.c_str()
- << "\" to --help-variable is not a defined variable. "
- << "Use --help-variable-list to see all defined variables.\n";
+ // Argument was not a module. Complain.
+ os << "Argument \"" << this->CurrentArgument
+ << "\" to --help-module is not a CMake module.\n";
return false;
}
//----------------------------------------------------------------------------
-bool cmDocumentation::PrintDocumentationList(std::ostream& os,
- const char *section)
+bool cmDocumentation::PrintHelpListModules(std::ostream& os)
{
- if(this->AllSections.find(section) == this->AllSections.end())
+ std::vector<std::string> files;
+ this->GlobHelp(files, "module/*");
+ std::vector<std::string> modules;
+ for (std::vector<std::string>::iterator fi = files.begin();
+ fi != files.end(); ++fi)
{
- os << "Internal error: " << section << " list is empty." << std::endl;
- return false;
+ std::string module = cmSystemTools::GetFilenameName(*fi);
+ modules.push_back(module.substr(0, module.size()-4));
}
-
- const std::vector<cmDocumentationEntry> &entries =
- this->AllSections[section]->GetEntries();
- for(std::vector<cmDocumentationEntry>::const_iterator ei =
- entries.begin();
- ei != entries.end(); ++ei)
+ std::sort(modules.begin(), modules.end());
+ for (std::vector<std::string>::iterator i = modules.begin();
+ i != modules.end(); ++i)
{
- if(ei->Name.size())
- {
- os << ei->Name << std::endl;
- }
+ os << *i << "\n";
}
return true;
}
//----------------------------------------------------------------------------
-bool cmDocumentation::PrintDocumentationUsage(std::ostream& os)
+bool cmDocumentation::PrintHelpOneProperty(std::ostream& os)
{
- this->ClearSections();
- this->AddSectionToPrint("Usage");
- this->AddSectionToPrint("Options");
- if(this->ShowGenerators)
+ std::string pname = cmSystemTools::HelpFileName(this->CurrentArgument);
+ if(this->PrintFiles(os, "prop_*/" + pname))
{
- this->AddSectionToPrint("Generators");
+ return true;
}
- this->Print(os);
- return true;
+ // Argument was not a property. Complain.
+ os << "Argument \"" << this->CurrentArgument
+ << "\" to --help-property is not a CMake property. "
+ << "Use --help-property-list to see all properties.\n";
+ return false;
}
//----------------------------------------------------------------------------
-bool cmDocumentation::PrintDocumentationFull(std::ostream& os)
+bool cmDocumentation::PrintHelpListProperties(std::ostream& os)
{
- this->CreateFullDocumentation();
- this->CurrentFormatter->PrintHeader(GetNameString(), GetNameString(), os);
- this->Print(os);
- this->CurrentFormatter->PrintFooter(os);
+ this->PrintNames(os, "prop_*/*");
return true;
}
//----------------------------------------------------------------------------
-bool cmDocumentation::PrintDocumentationModules(std::ostream& os)
+bool cmDocumentation::PrintHelpOnePolicy(std::ostream& os)
{
- this->ClearSections();
- this->CreateModulesSection();
- this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(Modules));
- this->AddSectionToPrint("Description");
- this->AddSectionToPrint("Modules");
- this->AddSectionToPrint("Copyright");
- this->AddSectionToPrint("See Also");
- this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
- this->Print(os);
- this->CurrentFormatter->PrintFooter(os);
- return true;
-}
+ std::string pname = this->CurrentArgument;
+ std::vector<std::string> files;
+ if(this->PrintFiles(os, "policy/" + pname))
+ {
+ return true;
+ }
-//----------------------------------------------------------------------------
-bool cmDocumentation::PrintDocumentationCustomModules(std::ostream& os)
-{
- this->ClearSections();
- this->CreateCustomModulesSection();
- this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(CustomModules));
- this->AddSectionToPrint("Description");
- this->AddSectionToPrint("Custom CMake Modules");
-// the custom modules are most probably not under Kitware's copyright, Alex
-// this->AddSectionToPrint("Copyright");
- this->AddSectionToPrint("See Also");
-
- this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
- this->Print(os);
- this->CurrentFormatter->PrintFooter(os);
- return true;
+ // Argument was not a policy. Complain.
+ os << "Argument \"" << this->CurrentArgument
+ << "\" to --help-policy is not a CMake policy.\n";
+ return false;
}
//----------------------------------------------------------------------------
-bool cmDocumentation::PrintDocumentationPolicies(std::ostream& os)
+bool cmDocumentation::PrintHelpListPolicies(std::ostream& os)
{
- this->ClearSections();
- this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(Policies));
- this->AddSectionToPrint("Description");
- this->AddSectionToPrint("Policies");
- this->AddSectionToPrint("Copyright");
- this->AddSectionToPrint("See Also");
-
- this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
- this->Print(os);
- this->CurrentFormatter->PrintFooter(os);
+ this->PrintNames(os, "policy/*");
return true;
}
//----------------------------------------------------------------------------
-bool cmDocumentation::PrintDocumentationProperties(std::ostream& os)
+bool cmDocumentation::PrintHelpListGenerators(std::ostream& os)
{
- this->ClearSections();
- this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(Properties));
- this->AddSectionToPrint("Properties Description");
- for (std::vector<std::string>::iterator i =
- this->PropertySections.begin();
- i != this->PropertySections.end(); ++i)
+ std::map<std::string,cmDocumentationSection*>::iterator si;
+ si = this->AllSections.find("Generators");
+ if(si != this->AllSections.end())
{
- this->AddSectionToPrint(i->c_str());
+ this->Formatter.SetIndent(" ");
+ this->Formatter.PrintSection(os, *si->second);
}
- this->AddSectionToPrint("Copyright");
- this->AddSectionToPrint("Standard See Also");
- this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
- this->Print(os);
- this->CurrentFormatter->PrintFooter(os);
return true;
}
//----------------------------------------------------------------------------
-bool cmDocumentation::PrintDocumentationVariables(std::ostream& os)
+bool cmDocumentation::PrintHelpOneVariable(std::ostream& os)
{
- this->ClearSections();
- this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(Variables));
- for (std::vector<std::string>::iterator i =
- this->VariableSections.begin();
- i != this->VariableSections.end(); ++i)
+ std::string vname = cmSystemTools::HelpFileName(this->CurrentArgument);
+ if(this->PrintFiles(os, "variable/" + vname))
{
- this->AddSectionToPrint(i->c_str());
+ return true;
}
- this->AddSectionToPrint("Copyright");
- this->AddSectionToPrint("Standard See Also");
- this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
- this->Print(os);
- this->CurrentFormatter->PrintFooter(os);
- return true;
+ // Argument was not a variable. Complain.
+ os << "Argument \"" << this->CurrentArgument
+ << "\" to --help-variable is not a defined variable. "
+ << "Use --help-variable-list to see all defined variables.\n";
+ return false;
}
//----------------------------------------------------------------------------
-bool cmDocumentation::PrintDocumentationCurrentCommands(std::ostream& os)
+bool cmDocumentation::PrintHelpListVariables(std::ostream& os)
{
- this->ClearSections();
- this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(Commands));
- this->AddSectionToPrint("Commands");
- this->AddSectionToPrint("Copyright");
- this->AddSectionToPrint("Standard See Also");
- this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
- this->Print(os);
- this->CurrentFormatter->PrintFooter(os);
+ this->PrintNames(os, "variable/*");
return true;
}
//----------------------------------------------------------------------------
-bool cmDocumentation::PrintDocumentationCompatCommands(std::ostream& os)
+bool cmDocumentation::PrintUsage(std::ostream& os)
{
- this->ClearSections();
- this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(CompatCommands));
- this->AddSectionToPrint("Compatibility Commands Description");
- this->AddSectionToPrint("Compatibility Commands");
- this->AddSectionToPrint("Copyright");
- this->AddSectionToPrint("Standard See Also");
- this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
- this->Print(os);
- this->CurrentFormatter->PrintFooter(os);
+ std::map<std::string,cmDocumentationSection*>::iterator si;
+ si = this->AllSections.find("Usage");
+ if(si != this->AllSections.end())
+ {
+ this->Formatter.PrintSection(os, *si->second);
+ }
return true;
}
//----------------------------------------------------------------------------
-void cmDocumentation
-::PrintDocumentationCommand(std::ostream& os,
- const cmDocumentationEntry &entry)
-{
- // the string "SingleItem" will be used in a few places to detect the case
- // that only the documentation for a single item is printed
- cmDocumentationSection *sec = new cmDocumentationSection("SingleItem","");
- sec->Append(entry);
- this->AllSections["temp"] = sec;
- this->ClearSections();
- this->AddSectionToPrint("temp");
- this->Print(os);
- this->AllSections.erase("temp");
- delete sec;
-}
-
-//----------------------------------------------------------------------------
-void cmDocumentation::CreateFullDocumentation()
+bool cmDocumentation::PrintHelp(std::ostream& os)
{
- this->ClearSections();
- this->CreateCustomModulesSection();
- this->CreateModulesSection();
-
- std::set<std::string> emitted;
- this->AddSectionToPrint("Name");
- emitted.insert("Name");
- this->AddSectionToPrint("Usage");
- emitted.insert("Usage");
- this->AddSectionToPrint("Description");
- emitted.insert("Description");
- this->AddSectionToPrint("Options");
- emitted.insert("Options");
- this->AddSectionToPrint("Generators");
- emitted.insert("Generators");
- this->AddSectionToPrint("Commands");
- emitted.insert("Commands");
-
-
- this->AddSectionToPrint("Properties Description");
- emitted.insert("Properties Description");
- for (std::vector<std::string>::iterator i =
- this->PropertySections.begin();
- i != this->PropertySections.end(); ++i)
+ std::map<std::string,cmDocumentationSection*>::iterator si;
+ si = this->AllSections.find("Usage");
+ if(si != this->AllSections.end())
{
- this->AddSectionToPrint(i->c_str());
- emitted.insert(i->c_str());
+ this->Formatter.PrintSection(os, *si->second);
}
-
- emitted.insert("Copyright");
- emitted.insert("See Also");
- emitted.insert("Standard See Also");
- emitted.insert("Author");
-
- // add any sections not yet written out, or to be written out
- for (std::map<std::string, cmDocumentationSection*>::iterator i =
- this->AllSections.begin();
- i != this->AllSections.end(); ++i)
+ si = this->AllSections.find("Options");
+ if(si != this->AllSections.end())
{
- if (emitted.find(i->first) == emitted.end())
- {
- this->AddSectionToPrint(i->first.c_str());
- }
+ this->Formatter.PrintSection(os, *si->second);
}
-
- this->AddSectionToPrint("Copyright");
-
- if(this->CurrentFormatter->GetForm() == ManForm)
- {
- this->AddSectionToPrint("See Also");
- this->AddSectionToPrint("Author");
- }
- else
+ if(this->ShowGenerators)
{
- this->AddSectionToPrint("Standard See Also");
+ si = this->AllSections.find("Generators");
+ if(si != this->AllSections.end())
+ {
+ this->Formatter.PrintSection(os, *si->second);
+ }
}
+ return true;
}
//----------------------------------------------------------------------------
-void cmDocumentation::SetForm(Form f, int manSection)
-{
- switch(f)
- {
- case HTMLForm:
- this->CurrentFormatter = &this->HTMLFormatter;
- break;
- case DocbookForm:
- this->CurrentFormatter = &this->DocbookFormatter;
- break;
- case ManForm:
- this->ManFormatter.SetManSection(manSection);
- this->CurrentFormatter = &this->ManFormatter;
- break;
- case TextForm:
- this->CurrentFormatter = &this->TextFormatter;
- break;
- case UsageForm:
- this->CurrentFormatter = & this->UsageFormatter;
- break;
- }
-}
-
-
-//----------------------------------------------------------------------------
const char* cmDocumentation::GetNameString() const
{
- if(this->NameString.length() > 0)
+ if(!this->NameString.empty())
{
return this->NameString.c_str();
}
@@ -1929,43 +904,53 @@ const char* cmDocumentation::GetNameString() const
}
//----------------------------------------------------------------------------
-const char* cmDocumentation::GetDocName(bool fallbackToNameString) const
+bool cmDocumentation::IsOption(const char* arg) const
{
- if (this->DocName.length() > 0)
- {
- return this->DocName.c_str();
- }
- else if (fallbackToNameString)
- {
- return this->GetNameString();
- }
- else
- return 0;
+ return ((arg[0] == '-') || (strcmp(arg, "/V") == 0) ||
+ (strcmp(arg, "/?") == 0));
}
//----------------------------------------------------------------------------
-#define CASE_DEFAULT_DOCNAME(doctype) \
- case cmDocumentation::doctype : \
- return GET_DOCUMENT_INTRO(doctype)[0];
-const char* cmDocumentation::GetDefaultDocName(Type ht) const
-{
- switch (ht)
+bool cmDocumentation::PrintOldCustomModules(std::ostream& os)
+{
+ // CheckOptions abuses the Argument field to give us the file name.
+ std::string filename = this->CurrentArgument;
+ std::string ext = cmSystemTools::UpperCase(
+ cmSystemTools::GetFilenameLastExtension(filename));
+ std::string name = cmSystemTools::GetFilenameWithoutLastExtension(filename);
+
+ const char* summary = "cmake --help-custom-modules no longer supported\n";
+ const char* detail =
+ "CMake versions prior to 3.0 exposed their internal module help page\n"
+ "generation functionality through the --help-custom-modules option.\n"
+ "CMake versions 3.0 and above use other means to generate their module\n"
+ "help pages so this functionality is no longer available to be exposed.\n"
+ "\n"
+ "This file was generated as a placeholder to provide this information.\n"
+ ;
+ if((ext == ".HTM") || (ext == ".HTML"))
+ {
+ os << "<html><title>" << name << "</title><body>\n"
+ << summary << "<p/>\n" << detail << "</body></html>\n";
+ }
+ else if((ext.length()==2) && (ext[1] >='1') && (ext[1]<='9'))
+ {
+ os <<
+ ".TH " << name << " " << ext[1] << " \"" <<
+ cmSystemTools::GetCurrentDateTime("%B %d, %Y") <<
+ "\" \"cmake " << cmVersion::GetCMakeVersion() << "\"\n"
+ ".SH NAME\n"
+ ".PP\n" <<
+ name << " \\- " << summary <<
+ "\n"
+ ".SH DESCRIPTION\n"
+ ".PP\n" <<
+ detail
+ ;
+ }
+ else
{
- CASE_DEFAULT_DOCNAME(Modules)
- CASE_DEFAULT_DOCNAME(CustomModules)
- CASE_DEFAULT_DOCNAME(Policies)
- CASE_DEFAULT_DOCNAME(Properties)
- CASE_DEFAULT_DOCNAME(Variables)
- CASE_DEFAULT_DOCNAME(Commands)
- CASE_DEFAULT_DOCNAME(CompatCommands)
- default: break;
+ os << name << "\n\n" << summary << "\n" << detail;
}
- return 0;
-}
-
-//----------------------------------------------------------------------------
-bool cmDocumentation::IsOption(const char* arg) const
-{
- return ((arg[0] == '-') || (strcmp(arg, "/V") == 0) ||
- (strcmp(arg, "/?") == 0));
+ return true;
}
diff --git a/Source/cmDocumentation.h b/Source/cmDocumentation.h
index e180f60f5..b6c5fde7e 100644
--- a/Source/cmDocumentation.h
+++ b/Source/cmDocumentation.h
@@ -13,13 +13,7 @@
#define _cmDocumentation_h
#include "cmStandardIncludes.h"
-#include "cmProperty.h"
#include "cmDocumentationFormatter.h"
-#include "cmDocumentationFormatterHTML.h"
-#include "cmDocumentationFormatterDocbook.h"
-#include "cmDocumentationFormatterMan.h"
-#include "cmDocumentationFormatterText.h"
-#include "cmDocumentationFormatterUsage.h"
#include "cmDocumentationSection.h"
#include "cmake.h"
@@ -37,22 +31,6 @@ public:
~cmDocumentation();
/**
- * An helper type pair for [structured] documented modules.
- * The comment of those module contains structure markup
- * which makes it possible to retrieve the documentation
- * of variables, macros and functions defined in the module.
- * - first is the filename of the module
- * - second is the section of the doc the module belongs too
- */
- typedef std::pair<std::string,std::string> documentedModuleSectionPair_t;
- /**
- * A list of documented module(s).
- */
- typedef std::list<documentedModuleSectionPair_t> documentedModulesList_t;
-
- // High-level interface for standard documents:
-
- /**
* Check command line arguments for documentation options. Returns
* true if documentation options are found, and false otherwise.
* When true is returned, PrintRequestedDocumentation should be
@@ -72,70 +50,38 @@ public:
bool PrintRequestedDocumentation(std::ostream& os);
/** Print help of the given type. */
- bool PrintDocumentation(Type ht, std::ostream& os, const char* docname=0);
+ bool PrintDocumentation(Type ht, std::ostream& os);
void SetShowGenerators(bool showGen) { this->ShowGenerators = showGen; }
/** Set the program name for standard document generation. */
- void SetName(const char* name);
+ void SetName(const std::string& name);
/** Set a section of the documentation. Typical sections include Name,
- Usage, Description, Options, SeeAlso */
+ Usage, Description, Options */
void SetSection(const char *sectionName,
cmDocumentationSection *section);
void SetSection(const char *sectionName,
std::vector<cmDocumentationEntry> &docs);
void SetSection(const char *sectionName,
- const char *docs[][3]);
+ const char *docs[][2]);
void SetSections(std::map<std::string,cmDocumentationSection *>
&sections);
/** Add the documentation to the beginning/end of the section */
void PrependSection(const char *sectionName,
- const char *docs[][3]);
+ const char *docs[][2]);
void PrependSection(const char *sectionName,
std::vector<cmDocumentationEntry> &docs);
void PrependSection(const char *sectionName,
cmDocumentationEntry &docs);
void AppendSection(const char *sectionName,
- const char *docs[][3]);
+ const char *docs[][2]);
void AppendSection(const char *sectionName,
std::vector<cmDocumentationEntry> &docs);
void AppendSection(const char *sectionName,
cmDocumentationEntry &docs);
- /**
- * Print documentation in the given form. All previously added
- * sections will be generated.
- */
- void Print(Form f, int manSection, std::ostream& os);
-
- /**
- * Print documentation in the current form. All previously added
- * sections will be generated.
- */
- void Print(std::ostream& os);
-
- /**
- * Add a section of documentation. This can be used to generate custom help
- * documents.
- */
- void AddSectionToPrint(const char *section);
-
- void SetSeeAlsoList(const char *data[][3]);
-
- /** Clear all previously added sections of help. */
- void ClearSections();
-
- /** Set cmake root so we can find installed files */
- void SetCMakeRoot(const char* root) { this->CMakeRoot = root;}
-
- /** Set CMAKE_MODULE_PATH so we can find additional cmake modules */
- void SetCMakeModulePath(const char* path) { this->CMakeModulePath = path;}
-
- static Form GetFormFromFilename(const std::string& filename,
- int* ManSection);
-
/** Add common (to all tools) documentation section(s) */
void addCommonStandardDocSections();
@@ -148,124 +94,53 @@ public:
/** Add the CPack standard documentation section(s) */
void addCPackStandardDocSections();
- /** Add automatic variables sections */
- void addAutomaticVariableSections(const std::string& section);
-
- /**
- * Retrieve the list of documented module located in
- * path which match the globing expression globExpr.
- * @param[in] path, directory where to start the search
- * we will recurse into it.
- * @param[in] globExpr, the globing expression used to
- * match the file in path.
- * @param[out] the list of obtained pairs (may be empty)
- * @return 0 on success 1 on error or empty list
- */
- int getDocumentedModulesListInDir(
- std::string path,
- std::string globExpr,
- documentedModulesList_t& docModuleList);
-
- /**
- * Get the documentation of macros, functions and variable documented
- * with CMake structured documentation in a CMake script.
- * (in fact it may be in any file which follow the structured doc format)
- * Structured documentation begin with
- * ## (double sharp) in column 1 & 2 immediately followed
- * by a markup. Those ## are ignored by the legacy module
- * documentation parser @see CreateSingleModule.
- * Current markup are ##section, ##module,
- * ##macro, ##function, ##variable and ##end.
- * ##end is closing either of the previous ones.
- * @param[in] fname the script file name to be parsed for documentation
- * @param[in,out] commands the vector of command/macros documentation
- * entry found in the script file.
- * @param[in,out] the cmake object instance to which variable documentation
- * will be attached (using @see cmake::DefineProperty)
- * @param[in] the documentation section in which the property will be
- * inserted.
- * @return the number of documented items (command and variable)
- * found in the file.
- */
- int GetStructuredDocFromFile(const char* fname,
- std::vector<cmDocumentationEntry>& commands,
- cmake* cm);
private:
- void SetForm(Form f, int manSection);
- void SetDocName(const char* docname);
-
- bool CreateSingleModule(const char* fname,
- const char* moduleName,
- cmDocumentationSection &sec);
- void CreateModuleDocsForDir(cmsys::Directory& dir,
- cmDocumentationSection &moduleSection);
- bool CreateModulesSection();
- bool CreateCustomModulesSection();
- void CreateFullDocumentation();
- void AddDocumentIntroToPrint(const char* intro[2]);
+ void GlobHelp(std::vector<std::string>& files, std::string const& pattern);
+ void PrintNames(std::ostream& os, std::string const& pattern);
+ bool PrintFiles(std::ostream& os, std::string const& pattern);
- bool PrintCopyright(std::ostream& os);
bool PrintVersion(std::ostream& os);
- bool PrintDocumentationGeneric(std::ostream& os, const char *section);
- bool PrintDocumentationList(std::ostream& os, const char *section);
- bool PrintDocumentationSingle(std::ostream& os);
- bool PrintDocumentationSingleModule(std::ostream& os);
- bool PrintDocumentationSingleProperty(std::ostream& os);
- bool PrintDocumentationSinglePolicy(std::ostream& os);
- bool PrintDocumentationSingleVariable(std::ostream& os);
- bool PrintDocumentationUsage(std::ostream& os);
- bool PrintDocumentationFull(std::ostream& os);
- bool PrintDocumentationModules(std::ostream& os);
- bool PrintDocumentationCustomModules(std::ostream& os);
- bool PrintDocumentationPolicies(std::ostream& os);
- bool PrintDocumentationProperties(std::ostream& os);
- bool PrintDocumentationVariables(std::ostream& os);
- bool PrintDocumentationCurrentCommands(std::ostream& os);
- bool PrintDocumentationCompatCommands(std::ostream& os);
- void PrintDocumentationCommand(std::ostream& os,
- const cmDocumentationEntry &entry);
-
+ bool PrintUsage(std::ostream& os);
+ bool PrintHelp(std::ostream& os);
+ bool PrintHelpFull(std::ostream& os);
+ bool PrintHelpOneManual(std::ostream& os);
+ bool PrintHelpOneCommand(std::ostream& os);
+ bool PrintHelpOneModule(std::ostream& os);
+ bool PrintHelpOnePolicy(std::ostream& os);
+ bool PrintHelpOneProperty(std::ostream& os);
+ bool PrintHelpOneVariable(std::ostream& os);
+ bool PrintHelpListManuals(std::ostream& os);
+ bool PrintHelpListCommands(std::ostream& os);
+ bool PrintHelpListModules(std::ostream& os);
+ bool PrintHelpListProperties(std::ostream& os);
+ bool PrintHelpListVariables(std::ostream& os);
+ bool PrintHelpListPolicies(std::ostream& os);
+ bool PrintHelpListGenerators(std::ostream& os);
+ bool PrintOldCustomModules(std::ostream& os);
const char* GetNameString() const;
- const char* GetDocName(bool fallbackToNameString = true) const;
- const char* GetDefaultDocName(Type ht) const;
bool IsOption(const char* arg) const;
bool ShowGenerators;
std::string NameString;
- std::string DocName;
std::map<std::string,cmDocumentationSection*> AllSections;
- std::string SeeAlsoString;
- std::string CMakeRoot;
- std::string CMakeModulePath;
- std::set<std::string> ModulesFound;
- std::vector< char* > ModuleStrings;
- std::vector<const cmDocumentationSection *> PrintSections;
std::string CurrentArgument;
struct RequestedHelpItem
{
- RequestedHelpItem():HelpForm(TextForm), HelpType(None), ManSection(1) {}
- cmDocumentationEnums::Form HelpForm;
+ RequestedHelpItem(): HelpType(None) {}
cmDocumentationEnums::Type HelpType;
std::string Filename;
std::string Argument;
- int ManSection;
};
std::vector<RequestedHelpItem> RequestedHelpItems;
- cmDocumentationFormatter* CurrentFormatter;
- cmDocumentationFormatterHTML HTMLFormatter;
- cmDocumentationFormatterDocbook DocbookFormatter;
- cmDocumentationFormatterMan ManFormatter;
- cmDocumentationFormatterText TextFormatter;
- cmDocumentationFormatterUsage UsageFormatter;
+ cmDocumentationFormatter Formatter;
- std::vector<std::string> PropertySections;
- std::vector<std::string> VariableSections;
+ static void WarnFormFromFilename(RequestedHelpItem& request, bool& result);
};
#endif
diff --git a/Source/cmDocumentationFormatter.cxx b/Source/cmDocumentationFormatter.cxx
index 9f01949b9..6869e2fb5 100644
--- a/Source/cmDocumentationFormatter.cxx
+++ b/Source/cmDocumentationFormatter.cxx
@@ -11,7 +11,10 @@
============================================================================*/
#include "cmDocumentationFormatter.h"
-cmDocumentationFormatter::cmDocumentationFormatter()
+#include "cmDocumentationSection.h"
+
+cmDocumentationFormatter::cmDocumentationFormatter():
+ TextWidth(77), TextIndent("")
{
}
@@ -43,7 +46,7 @@ void cmDocumentationFormatter::PrintFormatted(std::ostream& os,
preformatted.append(1, '\n');
}
}
- if(preformatted.length())
+ if(!preformatted.empty())
{
this->PrintPreformatted(os, preformatted.c_str());
}
@@ -59,98 +62,169 @@ void cmDocumentationFormatter::PrintFormatted(std::ostream& os,
++ptr;
paragraph.append(1, '\n');
}
- if(paragraph.length())
+ if(!paragraph.empty())
{
this->PrintParagraph(os, paragraph.c_str());
}
}
}
-//----------------------------------------------------------------------------
-std::string
-cmDocumentationFormatter::ComputeSectionLinkPrefix(std::string const& name)
+void cmDocumentationFormatter::PrintPreformatted(std::ostream& os,
+ const char* text)
{
- // Map from section name to a prefix for links pointing within the
- // section. For example, the commands section should have HTML
- // links to each command with names like #command:ADD_EXECUTABLE.
- if(name.find("Command") != name.npos)
- {
- return "command";
- }
- else if(name.find("Propert") != name.npos)
+ bool newline = true;
+ for(const char* ptr = text; *ptr; ++ptr)
{
- if(name.find("Global") != name.npos)
- {
- return "prop_global";
- }
- else if(name.find("Direct") != name.npos)
+ if(newline && *ptr != '\n')
{
- return "prop_dir";
+ os << this->TextIndent;
+ newline = false;
}
- else if(name.find("Target") != name.npos)
+ os << *ptr;
+ if(*ptr == '\n')
{
- return "prop_tgt";
+ newline = true;
}
- else if(name.find("Test") != name.npos)
+ }
+ os << "\n";
+}
+
+void cmDocumentationFormatter::PrintParagraph(std::ostream& os,
+ const char* text)
+{
+ os << this->TextIndent;
+ this->PrintColumn(os, text);
+ os << "\n";
+}
+
+void cmDocumentationFormatter::SetIndent(const char* indent)
+{
+ this->TextIndent = indent;
+}
+
+void cmDocumentationFormatter::PrintColumn(std::ostream& os,
+ const char* text)
+{
+ // Print text arranged in an indented column of fixed witdh.
+ const char* l = text;
+ long column = 0;
+ bool newSentence = false;
+ bool firstLine = true;
+ int width = this->TextWidth - static_cast<int>(strlen(this->TextIndent));
+
+ // Loop until the end of the text.
+ while(*l)
+ {
+ // Parse the next word.
+ const char* r = l;
+ while(*r && (*r != '\n') && (*r != ' ')) { ++r; }
+
+ // Does it fit on this line?
+ if(r-l < (width-column-(newSentence?1:0)))
{
- return "prop_test";
+ // Word fits on this line.
+ if(r > l)
+ {
+ if(column)
+ {
+ // Not first word on line. Separate from the previous word
+ // by a space, or two if this is a new sentence.
+ if(newSentence)
+ {
+ os << " ";
+ column += 2;
+ }
+ else
+ {
+ os << " ";
+ column += 1;
+ }
+ }
+ else
+ {
+ // First word on line. Print indentation unless this is the
+ // first line.
+ os << (firstLine?"":this->TextIndent);
+ }
+
+ // Print the word.
+ os.write(l, static_cast<long>(r-l));
+ newSentence = (*(r-1) == '.');
+ }
+
+ if(*r == '\n')
+ {
+ // Text provided a newline. Start a new line.
+ os << "\n";
+ ++r;
+ column = 0;
+ firstLine = false;
+ }
+ else
+ {
+ // No provided newline. Continue this line.
+ column += static_cast<long>(r-l);
+ }
}
- else if(name.find("Source") != name.npos)
+ else
{
- return "prop_sf";
+ // Word does not fit on this line. Start a new line.
+ os << "\n";
+ firstLine = false;
+ if(r > l)
+ {
+ os << this->TextIndent;
+ os.write(l, static_cast<long>(r-l));
+ column = static_cast<long>(r-l);
+ newSentence = (*(r-1) == '.');
+ }
+ else
+ {
+ column = 0;
+ }
}
- return "property";
- }
- else if(name.find("Variable") != name.npos)
- {
- return "variable";
- }
- else if(name.find("Polic") != name.npos)
- {
- return "policy";
- }
- else if(name.find("Module") != name.npos)
- {
- return "module";
- }
- else if(name.find("Name") != name.npos ||
- name.find("Introduction") != name.npos)
- {
- return "name";
- }
- else if(name.find("Usage") != name.npos)
- {
- return "usage";
- }
- else if(name.find("Description") != name.npos)
- {
- return "desc";
- }
- else if(name.find("Generators") != name.npos)
- {
- return "gen";
- }
- else if(name.find("Options") != name.npos)
- {
- return "opt";
- }
- else if(name.find("Copyright") != name.npos)
- {
- return "copy";
- }
- else if(name.find("See Also") != name.npos)
- {
- return "see";
- }
- else if(name.find("SingleItem") != name.npos)
- {
- return "single_item";
+
+ // Move to beginning of next word. Skip over whitespace.
+ l = r;
+ while(*l && (*l == ' ')) { ++l; }
}
- else
+}
+
+void cmDocumentationFormatter
+::PrintSection(std::ostream& os,
+ cmDocumentationSection const& section)
+{
+ os << section.GetName() << "\n";
+
+ const std::vector<cmDocumentationEntry> &entries =
+ section.GetEntries();
+ for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin();
+ op != entries.end(); ++op)
{
- std::cerr
- << "WARNING: ComputeSectionLinkPrefix failed for \"" << name << "\""
- << std::endl;
- return "other";
+ if(!op->Name.empty())
+ {
+ os << " " << op->Name;
+ this->TextIndent = " ";
+ int align = static_cast<int>(strlen(this->TextIndent))-4;
+ for(int i = static_cast<int>(op->Name.size()); i < align; ++i)
+ {
+ os << " ";
+ }
+ if (op->Name.size() > strlen(this->TextIndent)-4 )
+ {
+ os << "\n";
+ os.write(this->TextIndent, strlen(this->TextIndent)-2);
+ }
+ os << "= ";
+ this->PrintColumn(os, op->Brief.c_str());
+ os << "\n";
+ }
+ else
+ {
+ os << "\n";
+ this->TextIndent = "";
+ this->PrintFormatted(os, op->Brief.c_str());
+ }
}
+ os << "\n";
}
diff --git a/Source/cmDocumentationFormatter.h b/Source/cmDocumentationFormatter.h
index 665b9b61a..6e19b7d72 100644
--- a/Source/cmDocumentationFormatter.h
+++ b/Source/cmDocumentationFormatter.h
@@ -25,19 +25,17 @@ class cmDocumentationEnums
public:
/** Types of help provided. */
enum Type
- { None, Usage, Single, SingleModule, SingleProperty, SingleVariable,
- List, ModuleList, PropertyList, VariableList,
- Full, Properties, Variables, Modules, CustomModules, Commands,
- CompatCommands, Copyright, Version, Policies, SinglePolicy };
-
- /** Forms of documentation output. */
- enum Form { TextForm, HTMLForm, ManForm, UsageForm, DocbookForm };
+ {
+ None, Version, Usage, Help, Full, ListManuals, ListCommands,
+ ListModules, ListProperties, ListVariables, ListPolicies, ListGenerators,
+ OneManual, OneCommand, OneModule, OneProperty, OneVariable, OnePolicy,
+ OldCustomModules
+ };
};
class cmDocumentationSection;
-/** Base class for printing the documentation in the various supported
- formats. */
+/** Print documentation in a simple text format. */
class cmDocumentationFormatter
{
public:
@@ -45,23 +43,15 @@ public:
virtual ~cmDocumentationFormatter();
void PrintFormatted(std::ostream& os, const char* text);
- virtual cmDocumentationEnums::Form GetForm() const = 0;
-
- virtual void PrintHeader(const char* /*docname*/,
- const char* /*appname*/,
- std::ostream& /*os*/) {}
- virtual void PrintFooter(std::ostream& /*os*/) {}
virtual void PrintSection(std::ostream& os,
- const cmDocumentationSection& section,
- const char* name) = 0;
- virtual void PrintPreformatted(std::ostream& os, const char* text) = 0;
- virtual void PrintParagraph(std::ostream& os, const char* text) = 0;
- virtual void PrintIndex(std::ostream& ,
- std::vector<const cmDocumentationSection *>&)
- {}
-
- /** Compute a prefix for links into a section (#\<prefix\>_SOMETHING). */
- std::string ComputeSectionLinkPrefix(std::string const& name);
+ cmDocumentationSection const& section);
+ virtual void PrintPreformatted(std::ostream& os, const char* text);
+ virtual void PrintParagraph(std::ostream& os, const char* text);
+ void PrintColumn(std::ostream& os, const char* text);
+ void SetIndent(const char* indent);
+private:
+ int TextWidth;
+ const char* TextIndent;
};
#endif
diff --git a/Source/cmDocumentationFormatterDocbook.cxx b/Source/cmDocumentationFormatterDocbook.cxx
deleted file mode 100644
index 706ce0a02..000000000
--- a/Source/cmDocumentationFormatterDocbook.cxx
+++ /dev/null
@@ -1,254 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#include "cmDocumentationFormatterDocbook.h"
-#include "cmDocumentationSection.h"
-#include <algorithm>
-#include <ctype.h> // for isalnum
-
-static int cmIsAlnum(int c)
-{
- return isalnum(c);
-}
-
-//----------------------------------------------------------------------------
-
-// this function is a copy of the one in the HTML formatter
-// the three functions below are slightly modified copies
-static bool cmDocumentationIsHyperlinkCharDocbook(char c)
-{
- // This is not a complete list but works for CMake documentation.
- return ((c >= 'A' && c <= 'Z') ||
- (c >= 'a' && c <= 'z') ||
- (c >= '0' && c <= '9') ||
- c == '-' || c == '.' || c == '/' || c == '~' || c == '@' ||
- c == ':' || c == '_' || c == '&' || c == '?' || c == '=');
-}
-
-//----------------------------------------------------------------------------
-static void cmDocumentationPrintDocbookChar(std::ostream& os, char c)
-{
- // Use an escape sequence if necessary.
- switch(c)
- {
- case '<':
- os << "&lt;";
- break;
- case '>':
- os << "&gt;";
- break;
- case '&':
- os << "&amp;";
- break;
- default:
- os << c;
- }
-}
-
-//----------------------------------------------------------------------------
-const char* cmDocumentationPrintDocbookLink(std::ostream& os,const char* begin)
-{
- // Look for the end of the link.
- const char* end = begin;
- while(cmDocumentationIsHyperlinkCharDocbook(*end))
- {
- ++end;
- }
-
- // Print the hyperlink itself.
- os << "<ulink url=\"";
- for(const char* c = begin; c != end; ++c)
- {
- cmDocumentationPrintDocbookChar(os, *c);
- }
- os << "\" />";
-
- return end;
-}
-
-//----------------------------------------------------------------------------
-void cmDocumentationPrintDocbookEscapes(std::ostream& os, const char* text)
-{
- // Hyperlink prefixes.
- static const char* hyperlinks[] = {"http://", "ftp://", "mailto:", 0};
-
- // Print each character.
- for(const char* p = text; *p;)
- {
- // Handle hyperlinks specially to make them active.
- bool found_hyperlink = false;
- for(const char** h = hyperlinks; !found_hyperlink && *h; ++h)
- {
- if(strncmp(p, *h, strlen(*h)) == 0)
- {
- p = cmDocumentationPrintDocbookLink(os, p);
- found_hyperlink = true;
- }
- }
-
- // Print other characters normally.
- if(!found_hyperlink)
- {
- cmDocumentationPrintDocbookChar(os, *p++);
- }
- }
-}
-
-//----------------------------------------------------------------------------
-cmDocumentationFormatterDocbook::cmDocumentationFormatterDocbook()
-:cmDocumentationFormatter()
-{
-}
-
-//----------------------------------------------------------------------------
-void cmDocumentationFormatterDocbook
-::PrintSection(std::ostream& os,
- const cmDocumentationSection &section,
- const char* name)
-{
- os << "<sect1 id=\"";
- this->PrintId(os, 0, name);
- os << "\">\n<title>" << name << "</title>\n";
-
- std::string prefix = this->ComputeSectionLinkPrefix(name);
- const std::vector<cmDocumentationEntry> &entries = section.GetEntries();
-
- bool hasSubSections = false;
- for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin();
- op != entries.end(); ++op)
- {
- if(op->Name.size())
- {
- hasSubSections = true;
- break;
- }
- }
-
- bool inAbstract = false;
- for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin();
- op != entries.end(); ++op)
- {
- if(op->Name.size())
- {
- if(inAbstract)
- {
- os << "</abstract>\n";
- inAbstract = false;
- }
- os << "<sect2 id=\"";
- this->PrintId(os, prefix.c_str(), op->Name);
- os << "\">\n<title>";
- cmDocumentationPrintDocbookEscapes(os, op->Name.c_str());
- os << "</title>\n";
- if(op->Full.size())
- {
- os << "<abstract>\n<para>";
- cmDocumentationPrintDocbookEscapes(os, op->Brief.c_str());
- os << "</para>\n</abstract>\n";
- this->PrintFormatted(os, op->Full.c_str());
- }
- else
- {
- this->PrintFormatted(os, op->Brief.c_str());
- }
- os << "</sect2>\n";
- }
- else
- {
- if(hasSubSections && op == entries.begin())
- {
- os << "<abstract>\n";
- inAbstract = true;
- }
- this->PrintFormatted(os, op->Brief.c_str());
- }
- }
-
- // empty sections are not allowed in docbook.
- if(entries.empty())
- {
- os << "<para/>\n";
- }
-
- os << "</sect1>\n";
-}
-
-//----------------------------------------------------------------------------
-void cmDocumentationFormatterDocbook
-::PrintPreformatted(std::ostream& os, const char* text)
-{
- os << "<para>\n<programlisting>";
- cmDocumentationPrintDocbookEscapes(os, text);
- os << "</programlisting>\n</para>\n";
-}
-
-void cmDocumentationFormatterDocbook
-::PrintParagraph(std::ostream& os, const char* text)
-{
- os << "<para>";
- cmDocumentationPrintDocbookEscapes(os, text);
- os << "</para>\n";
-}
-
-//----------------------------------------------------------------------------
-void cmDocumentationFormatterDocbook
-::PrintHeader(const char* docname, const char* appname, std::ostream& os)
-{
- this->Docname = docname;
-
- // this one is used to ensure that we don't create multiple link targets
- // with the same name. We can clear it here since we are at the
- // start of a document here.
- this->EmittedLinkIds.clear();
-
- os << "<?xml version=\"1.0\" ?>\n"
- "<!DOCTYPE article PUBLIC \"-//OASIS//DTD DocBook V4.5//EN\" "
- "\"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd\" [\n"
- "<!ENTITY % addindex \"IGNORE\">\n"
- "<!ENTITY % English \"INCLUDE\"> ]>\n"
- "<article>\n"
- "<articleinfo>\n"
- "<title>" << docname << " - " << appname << "</title>\n"
- "</articleinfo>\n";
-}
-
-//----------------------------------------------------------------------------
-void cmDocumentationFormatterDocbook::PrintFooter(std::ostream& os)
-{
- os << "</article>\n";
-}
-
-//----------------------------------------------------------------------------
-void cmDocumentationFormatterDocbook
-::PrintId(std::ostream& os, const char* prefix, std::string id)
-{
- std::replace_if(id.begin(), id.end(),
- std::not1(std::ptr_fun(cmIsAlnum)), '_');
- if(prefix)
- {
- id = std::string(prefix) + "." + id;
- }
- os << this->Docname << '.' << id;
-
- // make sure that each id exists only once. Since it seems
- // not easily possible to determine which link refers to which id,
- // we have at least to make sure that the duplicated id's get a
- // different name (by appending an increasing number), Alex
- if (this->EmittedLinkIds.find(id) == this->EmittedLinkIds.end())
- {
- this->EmittedLinkIds.insert(id);
- }
- else
- {
- static unsigned int i=0;
- os << i++;
- }
-}
diff --git a/Source/cmDocumentationFormatterDocbook.h b/Source/cmDocumentationFormatterDocbook.h
deleted file mode 100644
index 0352d342a..000000000
--- a/Source/cmDocumentationFormatterDocbook.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef _cmDocumentationFormatterDocbook_h
-#define _cmDocumentationFormatterDocbook_h
-
-#include "cmStandardIncludes.h"
-
-#include "cmDocumentationFormatter.h"
-
-/** Class to print the documentation as Docbook.
- http://www.oasis-open.org/docbook/xml/4.2/ */
-class cmDocumentationFormatterDocbook : public cmDocumentationFormatter
-{
-public:
- cmDocumentationFormatterDocbook();
-
- virtual cmDocumentationEnums::Form GetForm() const
- { return cmDocumentationEnums::DocbookForm;}
-
- virtual void PrintHeader(const char* docname, const char* appname,
- std::ostream& os);
- virtual void PrintFooter(std::ostream& os);
- virtual void PrintSection(std::ostream& os,
- const cmDocumentationSection& section,
- const char* name);
- virtual void PrintPreformatted(std::ostream& os, const char* text);
- virtual void PrintParagraph(std::ostream& os, const char* text);
-private:
- void PrintId(std::ostream& os, const char* prefix, std::string id);
- std::set<std::string> EmittedLinkIds;
- std::string Docname;
-};
-
-#endif
diff --git a/Source/cmDocumentationFormatterHTML.cxx b/Source/cmDocumentationFormatterHTML.cxx
deleted file mode 100644
index 7213b43de..000000000
--- a/Source/cmDocumentationFormatterHTML.cxx
+++ /dev/null
@@ -1,288 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#include "cmDocumentationFormatterHTML.h"
-#include "cmDocumentationSection.h"
-#include "cmVersion.h"
-//----------------------------------------------------------------------------
-static bool cmDocumentationIsHyperlinkChar(char c)
-{
- // This is not a complete list but works for CMake documentation.
- return ((c >= 'A' && c <= 'Z') ||
- (c >= 'a' && c <= 'z') ||
- (c >= '0' && c <= '9') ||
- c == '-' || c == '.' || c == '/' || c == '~' || c == '@' ||
- c == ':' || c == '_' || c == '&' || c == '?' || c == '=');
-}
-
-//----------------------------------------------------------------------------
-static void cmDocumentationPrintHTMLChar(std::ostream& os, char c)
-{
- // Use an escape sequence if necessary.
- switch (c)
- {
- case '<':
- os << "&lt;";
- break;
- case '>':
- os << "&gt;";
- break;
- case '&':
- os << "&amp;";
- break;
- case '\n':
- os << "<br />";
- break;
- default:
- os << c;
- }
-}
-
-//----------------------------------------------------------------------------
-bool cmDocumentationHTMLIsIdChar(char c)
-{
- // From the HTML specification:
- // ID and NAME tokens must begin with a letter ([A-Za-z]) and may
- // be followed by any number of letters, digits ([0-9]), hyphens
- // ("-"), underscores ("_"), colons (":"), and periods (".").
- return ((c >= 'A' && c <= 'Z') ||
- (c >= 'a' && c <= 'z') ||
- (c >= '0' && c <= '9') ||
- c == '-' || c == '_' || c == ':' || c == '.');
-}
-
-//----------------------------------------------------------------------------
-void cmDocumentationPrintHTMLId(std::ostream& os, const char* begin)
-{
- for(const char* c = begin; *c; ++c)
- {
- if(cmDocumentationHTMLIsIdChar(*c))
- {
- os << *c;
- }
- }
-}
-
-//----------------------------------------------------------------------------
-const char* cmDocumentationPrintHTMLLink(std::ostream& os, const char* begin)
-{
- // Look for the end of the link.
- const char* end = begin;
- while(cmDocumentationIsHyperlinkChar(*end))
- {
- ++end;
- }
-
- // Print the hyperlink itself.
- os << "<a href=\"";
- for(const char* c = begin; c != end; ++c)
- {
- cmDocumentationPrintHTMLChar(os, *c);
- }
- os << "\">";
-
- // The name of the hyperlink is the text itself.
- for(const char* c = begin; c != end; ++c)
- {
- cmDocumentationPrintHTMLChar(os, *c);
- }
- os << "</a>";
-
- // Return the position at which to continue scanning the input
- // string.
- return end;
-}
-
-
-cmDocumentationFormatterHTML::cmDocumentationFormatterHTML()
-:cmDocumentationFormatter()
-{
-}
-
-void cmDocumentationFormatterHTML
-::PrintSection(std::ostream& os,
- const cmDocumentationSection &section,
- const char* name)
-{
- std::string prefix = this->ComputeSectionLinkPrefix(name);
-
- const std::vector<cmDocumentationEntry> &entries =
- section.GetEntries();
-
- // skip the index if the help for only a single item (--help-command,
- // --help-policy, --help-property, --help-module) is printed
- bool isSingleItemHelp = ((name!=0) && (strcmp(name, "SingleItem")==0));
-
- if (!isSingleItemHelp)
- {
- if (name)
- {
- os << "<h2><a name=\"section_";
- cmDocumentationPrintHTMLId(os, name);
- os << "\"></a>" << name << "</h2>\n";
- }
-
- // Is a list needed?
- for(std::vector<cmDocumentationEntry>::const_iterator op
- = entries.begin(); op != entries.end(); ++ op )
- {
- if (op->Name.size())
- {
- os << "<ul>\n";
- for(;op != entries.end() && op->Name.size(); ++op)
- {
- if(op->Name.size())
- {
- os << " <li><a href=\"#" << prefix << ":";
- cmDocumentationPrintHTMLId(os, op->Name.c_str());
- os << "\"><b><code>";
- this->PrintHTMLEscapes(os, op->Name.c_str());
- os << "</code></b></a></li>\n";
- }
- }
- os << "</ul>\n" ;
- break; // Skip outer loop termination test
- }
- }
- }
-
- for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin();
- op != entries.end();)
- {
- if(op->Name.size())
- {
- os << "<ul>\n";
- for(;op != entries.end() && op->Name.size(); ++op)
- {
- os << " <li>\n";
- if(op->Name.size())
- {
- os << " <a name=\"" << prefix << ":";
- cmDocumentationPrintHTMLId(os, op->Name.c_str());
- os << "\"></a><b><code>";
- this->PrintHTMLEscapes(os, op->Name.c_str());
- os << "</code></b>: ";
- }
- this->PrintHTMLEscapes(os, op->Brief.c_str());
- if(op->Full.size())
- {
- os << "<br />\n ";
- this->PrintFormatted(os, op->Full.c_str());
- }
- os << "\n";
- os << " </li>\n";
- }
- os << "</ul>\n";
- }
- else
- {
- this->PrintFormatted(os, op->Brief.c_str());
- os << "\n";
- ++op;
- }
- }
-}
-
-void cmDocumentationFormatterHTML::PrintPreformatted(std::ostream& os,
- const char* text)
-{
- os << "<pre>";
- this->PrintHTMLEscapes(os, text);
- os << "</pre>\n ";
-}
-
-void cmDocumentationFormatterHTML::PrintParagraph(std::ostream& os,
- const char* text)
-{
- os << "<p>";
- this->PrintHTMLEscapes(os, text);
- os << "</p>\n";
-}
-
-//----------------------------------------------------------------------------
-void cmDocumentationFormatterHTML::PrintHeader(const char* docname,
- const char* appname,
- std::ostream& os)
-{
- os << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\""
- << " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n";
- os << "<html xmlns=\"http://www.w3.org/1999/xhtml\""
- << " xml:lang=\"en\" lang=\"en\">\n";
- os << "<head><meta http-equiv=\"Content-Type\" "
- << "content=\"text/html;charset=utf-8\" /><title>";
- os << docname << " - " << appname;
- os << "</title></head><body>\n";
-}
-
-//----------------------------------------------------------------------------
-void cmDocumentationFormatterHTML::PrintFooter(std::ostream& os)
-{
- os << "</body></html>\n";
-}
-
-//----------------------------------------------------------------------------
-void cmDocumentationFormatterHTML::PrintHTMLEscapes(std::ostream& os,
- const char* text)
-{
- // Hyperlink prefixes.
- static const char* hyperlinks[] = {"http://", "ftp://", "mailto:", 0};
-
- // Print each character.
- for(const char* p = text; *p;)
- {
- // Handle hyperlinks specially to make them active.
- bool found_hyperlink = false;
- for(const char** h = hyperlinks; !found_hyperlink && *h; ++h)
- {
- if(strncmp(p, *h, strlen(*h)) == 0)
- {
- p = cmDocumentationPrintHTMLLink(os, p);
- found_hyperlink = true;
- }
- }
-
- // Print other characters normally.
- if(!found_hyperlink)
- {
- cmDocumentationPrintHTMLChar(os, *p++);
- }
- }
-}
-
-void cmDocumentationFormatterHTML
-::PrintIndex(std::ostream& os,
- std::vector<const cmDocumentationSection *>& sections)
-{
- // skip the index if only the help for a single item is printed
- if ((sections.size() == 1)
- && (sections[0]->GetName(this->GetForm()) != 0 )
- && (std::string(sections[0]->GetName(this->GetForm())) == "SingleItem"))
- {
- return;
- }
-
- os << "<h2><a name=\"section_Index\"></a>Master Index "
- << "CMake " << cmVersion::GetCMakeVersion()
- << "</h2>\n";
-
- if (!sections.empty())
- {
- os << "<ul>\n";
- for(unsigned int i=0; i < sections.size(); ++i)
- {
- std::string name = sections[i]->GetName((this->GetForm()));
- os << " <li><a href=\"#section_";
- cmDocumentationPrintHTMLId(os, name.c_str());
- os << "\"><b>" << name << "</b></a></li>\n";
- }
- os << "</ul>\n";
- }
-}
diff --git a/Source/cmDocumentationFormatterHTML.h b/Source/cmDocumentationFormatterHTML.h
deleted file mode 100644
index 44bf24026..000000000
--- a/Source/cmDocumentationFormatterHTML.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef _cmDocumentationFormatterHTML_h
-#define _cmDocumentationFormatterHTML_h
-
-#include "cmStandardIncludes.h"
-
-#include "cmDocumentationFormatter.h"
-
-/** Class to print the documentation as HTML. */
-class cmDocumentationFormatterHTML : public cmDocumentationFormatter
-{
-public:
- cmDocumentationFormatterHTML();
-
- virtual cmDocumentationEnums::Form GetForm() const
- { return cmDocumentationEnums::HTMLForm;}
-
- virtual void PrintHeader(const char* docname, const char* appname,
- std::ostream& os);
- virtual void PrintFooter(std::ostream& os);
- virtual void PrintSection(std::ostream& os,
- const cmDocumentationSection& section,
- const char* name);
- virtual void PrintPreformatted(std::ostream& os, const char* text);
- virtual void PrintParagraph(std::ostream& os, const char* text);
- virtual void PrintIndex(std::ostream& ,
- std::vector<const cmDocumentationSection *>&);
-private:
- void PrintHTMLEscapes(std::ostream& os, const char* text);
-};
-
-#endif
diff --git a/Source/cmDocumentationFormatterMan.cxx b/Source/cmDocumentationFormatterMan.cxx
deleted file mode 100644
index 4123c85cb..000000000
--- a/Source/cmDocumentationFormatterMan.cxx
+++ /dev/null
@@ -1,102 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-
-#include "cmDocumentationFormatterMan.h"
-#include "cmDocumentationSection.h"
-
-#include "cmSystemTools.h"
-#include "cmVersion.h"
-
-
-cmDocumentationFormatterMan::cmDocumentationFormatterMan()
-:cmDocumentationFormatter()
-,ManSection(1)
-{
-}
-
-void cmDocumentationFormatterMan::SetManSection(int manSection)
-{
- this->ManSection = manSection;
-}
-
-void cmDocumentationFormatterMan
-::PrintSection(std::ostream& os,
- const cmDocumentationSection &section,
- const char* name)
-{
- if(name)
- {
- os << ".SH " << name << "\n";
- }
-
- const std::vector<cmDocumentationEntry> &entries =
- section.GetEntries();
- for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin();
- op != entries.end(); ++op)
- {
- if(op->Name.size())
- {
- os << ".TP\n"
- << ".B " << (op->Name.size()?op->Name.c_str():"*") << "\n";
- this->PrintFormatted(os, op->Brief.c_str());
- this->PrintFormatted(os, op->Full.c_str());
- }
- else
- {
- os << ".PP\n";
- this->PrintFormatted(os, op->Brief.c_str());
- }
- }
-}
-
-void cmDocumentationFormatterMan::EscapeText(std::string& man_text)
-{
- cmSystemTools::ReplaceString(man_text, "\\", "\\\\");
- cmSystemTools::ReplaceString(man_text, "-", "\\-");
-}
-
-void cmDocumentationFormatterMan::PrintPreformatted(std::ostream& os,
- const char* text)
-{
- std::string man_text = text;
- this->EscapeText(man_text);
- os << ".nf\n" << man_text;
- if (*text && man_text.at(man_text.length()-1) != '\n')
- os << "\n";
- os << ".fi\n\n";
-}
-
-void cmDocumentationFormatterMan::PrintParagraph(std::ostream& os,
- const char* text)
-{
- std::string man_text = text;
- this->EscapeText(man_text);
- os << man_text << "\n\n";
-}
-
-
-//----------------------------------------------------------------------------
-void cmDocumentationFormatterMan::PrintHeader(const char* docname,
- const char* appname,
- std::ostream& os)
-{
- std::string s_docname(docname), s_appname(appname);
-
- this->EscapeText(s_docname);
- this->EscapeText(s_appname);
- os << ".TH " << s_docname << " " << this->ManSection << " \""
- << cmSystemTools::GetCurrentDateTime("%B %d, %Y").c_str()
- << "\" \"" << s_appname
- << " " << cmVersion::GetCMakeVersion()
- << "\"\n";
-}
-
diff --git a/Source/cmDocumentationFormatterMan.h b/Source/cmDocumentationFormatterMan.h
deleted file mode 100644
index b3d069c36..000000000
--- a/Source/cmDocumentationFormatterMan.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef _cmDocumentationFormatterMan_h
-#define _cmDocumentationFormatterMan_h
-
-#include "cmStandardIncludes.h"
-
-#include "cmDocumentationFormatter.h"
-
-/** Class to print the documentation as man page. */
-class cmDocumentationFormatterMan : public cmDocumentationFormatter
-{
-public:
- cmDocumentationFormatterMan();
-
- void SetManSection(int manSection);
-
- virtual cmDocumentationEnums::Form GetForm() const
- { return cmDocumentationEnums::ManForm;}
-
- virtual void PrintHeader(const char* docname, const char* appname,
- std::ostream& os);
- virtual void PrintSection(std::ostream& os,
- const cmDocumentationSection& section,
- const char* name);
- virtual void PrintPreformatted(std::ostream& os, const char* text);
- virtual void PrintParagraph(std::ostream& os, const char* text);
-
-private:
- void EscapeText(std::string& man_text);
- int ManSection;
-};
-
-#endif
diff --git a/Source/cmDocumentationFormatterText.cxx b/Source/cmDocumentationFormatterText.cxx
deleted file mode 100644
index 5def1947a..000000000
--- a/Source/cmDocumentationFormatterText.cxx
+++ /dev/null
@@ -1,180 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-
-#include "cmDocumentationFormatterText.h"
-#include "cmDocumentationSection.h"
-
-cmDocumentationFormatterText::cmDocumentationFormatterText()
-:cmDocumentationFormatter()
-,TextWidth(77)
-,TextIndent("")
-{
-}
-
-void cmDocumentationFormatterText
-::PrintSection(std::ostream& os,
- const cmDocumentationSection &section,
- const char* name)
-{
- if(name && (strcmp(name, "SingleItem")!=0))
- {
- os <<
- "---------------------------------------"
- "---------------------------------------\n";
- os << name << "\n\n";
- }
-
- const std::vector<cmDocumentationEntry> &entries =
- section.GetEntries();
- for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin();
- op != entries.end(); ++op)
- {
- if(op->Name.size())
- {
- os << " " << op->Name << "\n";
- this->TextIndent = " ";
- this->PrintFormatted(os, op->Brief.c_str());
- if(op->Full.size())
- {
- os << "\n";
- this->PrintFormatted(os, op->Full.c_str());
- }
- }
- else
- {
- this->TextIndent = "";
- this->PrintFormatted(os, op->Brief.c_str());
- }
- os << "\n";
- }
-}
-
-void cmDocumentationFormatterText::PrintPreformatted(std::ostream& os,
- const char* text)
-{
- bool newline = true;
- for(const char* ptr = text; *ptr; ++ptr)
- {
- if(newline && *ptr != '\n')
- {
- os << this->TextIndent;
- newline = false;
- }
- os << *ptr;
- if(*ptr == '\n')
- {
- newline = true;
- }
- }
- os << "\n";
-}
-
-void cmDocumentationFormatterText::PrintParagraph(std::ostream& os,
- const char* text)
-{
- os << this->TextIndent;
- this->PrintColumn(os, text);
- os << "\n";
-}
-
-void cmDocumentationFormatterText::SetIndent(const char* indent)
-{
- this->TextIndent = indent;
-}
-
-void cmDocumentationFormatterText::PrintColumn(std::ostream& os,
- const char* text)
-{
- // Print text arranged in an indented column of fixed witdh.
- const char* l = text;
- long column = 0;
- bool newSentence = false;
- bool firstLine = true;
- int width = this->TextWidth - static_cast<int>(strlen(this->TextIndent));
-
- // Loop until the end of the text.
- while(*l)
- {
- // Parse the next word.
- const char* r = l;
- while(*r && (*r != '\n') && (*r != ' ')) { ++r; }
-
- // Does it fit on this line?
- if(r-l < (width-column-(newSentence?1:0)))
- {
- // Word fits on this line.
- if(r > l)
- {
- if(column)
- {
- // Not first word on line. Separate from the previous word
- // by a space, or two if this is a new sentence.
- if(newSentence)
- {
- os << " ";
- column += 2;
- }
- else
- {
- os << " ";
- column += 1;
- }
- }
- else
- {
- // First word on line. Print indentation unless this is the
- // first line.
- os << (firstLine?"":this->TextIndent);
- }
-
- // Print the word.
- os.write(l, static_cast<long>(r-l));
- newSentence = (*(r-1) == '.');
- }
-
- if(*r == '\n')
- {
- // Text provided a newline. Start a new line.
- os << "\n";
- ++r;
- column = 0;
- firstLine = false;
- }
- else
- {
- // No provided newline. Continue this line.
- column += static_cast<long>(r-l);
- }
- }
- else
- {
- // Word does not fit on this line. Start a new line.
- os << "\n";
- firstLine = false;
- if(r > l)
- {
- os << this->TextIndent;
- os.write(l, static_cast<long>(r-l));
- column = static_cast<long>(r-l);
- newSentence = (*(r-1) == '.');
- }
- else
- {
- column = 0;
- }
- }
-
- // Move to beginning of next word. Skip over whitespace.
- l = r;
- while(*l && (*l == ' ')) { ++l; }
- }
-}
diff --git a/Source/cmDocumentationFormatterText.h b/Source/cmDocumentationFormatterText.h
deleted file mode 100644
index d9c2af297..000000000
--- a/Source/cmDocumentationFormatterText.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef _cmDocumentationFormatterText_h
-#define _cmDocumentationFormatterText_h
-
-#include "cmStandardIncludes.h"
-
-#include "cmDocumentationFormatter.h"
-
-/** Class to print the documentation as plain text. */
-class cmDocumentationFormatterText : public cmDocumentationFormatter
-{
-public:
- cmDocumentationFormatterText();
-
- virtual cmDocumentationEnums::Form GetForm() const
- { return cmDocumentationEnums::TextForm;}
-
- virtual void PrintSection(std::ostream& os,
- const cmDocumentationSection& section,
- const char* name);
- virtual void PrintPreformatted(std::ostream& os, const char* text);
- virtual void PrintParagraph(std::ostream& os, const char* text);
- void PrintColumn(std::ostream& os, const char* text);
- void SetIndent(const char* indent);
-protected:
- int TextWidth;
- const char* TextIndent;
-};
-
-#endif
diff --git a/Source/cmDocumentationFormatterUsage.cxx b/Source/cmDocumentationFormatterUsage.cxx
deleted file mode 100644
index a068e5682..000000000
--- a/Source/cmDocumentationFormatterUsage.cxx
+++ /dev/null
@@ -1,63 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-
-#include "cmDocumentationFormatterUsage.h"
-#include "cmDocumentationSection.h"
-
-cmDocumentationFormatterUsage::cmDocumentationFormatterUsage()
-:cmDocumentationFormatterText()
-{
-}
-
-void cmDocumentationFormatterUsage
-::PrintSection(std::ostream& os,
- const cmDocumentationSection &section,
- const char* name)
-{
- if(name)
- {
- os << name << "\n";
- }
-
- const std::vector<cmDocumentationEntry> &entries =
- section.GetEntries();
- for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin();
- op != entries.end(); ++op)
- {
- if(op->Name.size())
- {
- os << " " << op->Name;
- this->TextIndent = " ";
- int align = static_cast<int>(strlen(this->TextIndent))-4;
- for(int i = static_cast<int>(op->Name.size()); i < align; ++i)
- {
- os << " ";
- }
- if (op->Name.size() > strlen(this->TextIndent)-4 )
- {
- os << "\n";
- os.write(this->TextIndent, strlen(this->TextIndent)-2);
- }
- os << "= ";
- this->PrintColumn(os, op->Brief.c_str());
- os << "\n";
- }
- else
- {
- os << "\n";
- this->TextIndent = "";
- this->PrintFormatted(os, op->Brief.c_str());
- }
- }
- os << "\n";
-}
-
diff --git a/Source/cmDocumentationFormatterUsage.h b/Source/cmDocumentationFormatterUsage.h
deleted file mode 100644
index 3ed3442cb..000000000
--- a/Source/cmDocumentationFormatterUsage.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef _cmDocumentationFormatterUsage_h
-#define _cmDocumentationFormatterUsage_h
-
-#include "cmDocumentationFormatterText.h"
-
-/** Class to print the documentation as usage on the command line. */
-class cmDocumentationFormatterUsage : public cmDocumentationFormatterText
-{
-public:
- cmDocumentationFormatterUsage();
-
- virtual cmDocumentationEnums::Form GetForm() const
- { return cmDocumentationEnums::UsageForm;}
-
- virtual void PrintSection(std::ostream& os,
- const cmDocumentationSection& section,
- const char* name);
-};
-
-#endif
diff --git a/Source/cmDocumentationSection.cxx b/Source/cmDocumentationSection.cxx
index a2dfe70d0..b0dd8ef64 100644
--- a/Source/cmDocumentationSection.cxx
+++ b/Source/cmDocumentationSection.cxx
@@ -13,69 +13,33 @@
//----------------------------------------------------------------------------
-void cmDocumentationSection::Append(const char *data[][3])
+void cmDocumentationSection::Append(const char *data[][2])
{
int i = 0;
while(data[i][1])
{
this->Entries.push_back(cmDocumentationEntry(data[i][0],
- data[i][1],
- data[i][2]));
+ data[i][1]));
data += 1;
}
}
//----------------------------------------------------------------------------
-void cmDocumentationSection::Prepend(const char *data[][3])
+void cmDocumentationSection::Prepend(const char *data[][2])
{
std::vector<cmDocumentationEntry> tmp;
int i = 0;
while(data[i][1])
{
tmp.push_back(cmDocumentationEntry(data[i][0],
- data[i][1],
- data[i][2]));
+ data[i][1]));
data += 1;
}
this->Entries.insert(this->Entries.begin(),tmp.begin(),tmp.end());
}
//----------------------------------------------------------------------------
-void cmDocumentationSection::Append(const char *n, const char *b,
- const char *f)
+void cmDocumentationSection::Append(const char *n, const char *b)
{
- this->Entries.push_back(cmDocumentationEntry(n,b,f));
+ this->Entries.push_back(cmDocumentationEntry(n,b));
}
-
-#if 0
-//----------------------------------------------------------------------------
-void cmDocumentationSection::Set(const cmDocumentationEntry* header,
- const cmDocumentationEntry* section,
- const cmDocumentationEntry* footer)
-{
- this->Entries.erase(this->Entries.begin(), this->Entries.end());
- if(header)
- {
- for(const cmDocumentationEntry* op = header; op->brief; ++op)
- {
- this->Entries.push_back(*op);
- }
- }
- if(section)
- {
- for(const cmDocumentationEntry* op = section; op->brief; ++op)
- {
- this->Entries.push_back(*op);
- }
- }
- if(footer)
- {
- for(const cmDocumentationEntry* op = footer; op->brief; ++op)
- {
- this->Entries.push_back(*op);
- }
- }
- cmDocumentationEntry empty = {0,0,0};
- this->Entries.push_back(empty);
-}
-#endif
diff --git a/Source/cmDocumentationSection.h b/Source/cmDocumentationSection.h
index 4f8c10d3e..d796da84b 100644
--- a/Source/cmDocumentationSection.h
+++ b/Source/cmDocumentationSection.h
@@ -24,8 +24,8 @@ class cmDocumentationSection
{
public:
/** Create a cmSection, with a special name for man-output mode. */
- cmDocumentationSection(const char* name, const char* manName)
- :Name(name), ManName(manName) {}
+ cmDocumentationSection(const char* name, const char*)
+ :Name(name) {}
/** Has any content been added to this section or is it empty ? */
bool IsEmpty() const { return this->Entries.empty(); }
@@ -33,10 +33,9 @@ public:
/** Clear contents. */
void Clear() { this->Entries.clear(); }
- /** Return the name of this section for the given output form. */
- const char* GetName(cmDocumentationEnums::Form form) const
- { return (form==cmDocumentationEnums::ManForm ?
- this->ManName.c_str() : this->Name.c_str()); }
+ /** Return the name of this section. */
+ std::string GetName() const
+ { return this->Name; }
/** Return a pointer to the first entry of this section. */
const std::vector<cmDocumentationEntry> &GetEntries() const
@@ -49,11 +48,11 @@ public:
{ this->Entries.insert(this->Entries.end(),entries.begin(),entries.end()); }
/** Append an entry to this section using NULL terminated chars */
- void Append(const char *[][3]);
- void Append(const char *n, const char *b, const char *f);
+ void Append(const char *[][2]);
+ void Append(const char *n, const char *b);
/** prepend some documentation to this section */
- void Prepend(const char *[][3]);
+ void Prepend(const char *[][2]);
void Prepend(const std::vector<cmDocumentationEntry> &entries)
{ this->Entries.insert(this->Entries.begin(),
entries.begin(),entries.end()); }
@@ -61,7 +60,6 @@ public:
private:
std::string Name;
- std::string ManName;
std::vector<cmDocumentationEntry> Entries;
};
diff --git a/Source/cmDynamicLoader.cxx b/Source/cmDynamicLoader.cxx
index 6a0ab7b1b..944a00072 100644
--- a/Source/cmDynamicLoader.cxx
+++ b/Source/cmDynamicLoader.cxx
@@ -23,7 +23,7 @@ public:
static cmDynamicLoaderCache* GetInstance();
private:
- std::map<cmStdString, cmsys::DynamicLoader::LibraryHandle> CacheMap;
+ std::map<std::string, cmsys::DynamicLoader::LibraryHandle> CacheMap;
static cmDynamicLoaderCache* Instance;
};
@@ -47,7 +47,7 @@ void cmDynamicLoaderCache::CacheFile(const char* path,
bool cmDynamicLoaderCache::GetCacheFile(const char* path,
cmsys::DynamicLoader::LibraryHandle& p)
{
- std::map<cmStdString, cmsys::DynamicLoader::LibraryHandle>::iterator it
+ std::map<std::string, cmsys::DynamicLoader::LibraryHandle>::iterator it
= this->CacheMap.find(path);
if ( it != this->CacheMap.end() )
{
@@ -59,7 +59,7 @@ bool cmDynamicLoaderCache::GetCacheFile(const char* path,
bool cmDynamicLoaderCache::FlushCache(const char* path)
{
- std::map<cmStdString, cmsys::DynamicLoader::LibraryHandle>::iterator it
+ std::map<std::string, cmsys::DynamicLoader::LibraryHandle>::iterator it
= this->CacheMap.find(path);
bool ret = false;
if ( it != this->CacheMap.end() )
@@ -73,7 +73,7 @@ bool cmDynamicLoaderCache::FlushCache(const char* path)
void cmDynamicLoaderCache::FlushCache()
{
- for ( std::map<cmStdString,
+ for ( std::map<std::string,
cmsys::DynamicLoader::LibraryHandle>::iterator it
= this->CacheMap.begin();
it != this->CacheMap.end(); it++ )
diff --git a/Source/cmDynamicLoader.h b/Source/cmDynamicLoader.h
index acf8011f2..84bc9bcba 100644
--- a/Source/cmDynamicLoader.h
+++ b/Source/cmDynamicLoader.h
@@ -15,8 +15,8 @@
// libraries into a process.
-#ifndef __cmDynamicLoader_h
-#define __cmDynamicLoader_h
+#ifndef cmDynamicLoader_h
+#define cmDynamicLoader_h
#include "cmStandardIncludes.h"
@@ -36,8 +36,8 @@ public:
static void FlushCache();
protected:
- cmDynamicLoader() {};
- ~cmDynamicLoader() {};
+ cmDynamicLoader() {}
+ ~cmDynamicLoader() {}
private:
cmDynamicLoader(const cmDynamicLoader&); // Not implemented.
diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx
index 30de9a8a6..b480cd53b 100644
--- a/Source/cmELF.cxx
+++ b/Source/cmELF.cxx
@@ -13,15 +13,32 @@
#include "cmELF.h"
#include <cmsys/auto_ptr.hxx>
-
-// Need the native byte order of the running CPU.
-#define cmsys_CPU_UNKNOWN_OKAY // We can decide at runtime if not known.
-#include <cmsys/CPU.h>
+#include <cmsys/FStream.hxx>
// Include the ELF format information system header.
#if defined(__OpenBSD__)
# include <stdint.h>
# include <elf_abi.h>
+#elif defined(__HAIKU__)
+# include <elf32.h>
+# include <elf64.h>
+ typedef struct Elf32_Ehdr Elf32_Ehdr;
+ typedef struct Elf32_Shdr Elf32_Shdr;
+ typedef struct Elf32_Sym Elf32_Sym;
+ typedef struct Elf32_Rel Elf32_Rel;
+ typedef struct Elf32_Rela Elf32_Rela;
+# define ELFMAG0 0x7F
+# define ELFMAG1 'E'
+# define ELFMAG2 'L'
+# define ELFMAG3 'F'
+# define ET_NONE 0
+# define ET_REL 1
+# define ET_EXEC 2
+# define ET_DYN 3
+# define ET_CORE 4
+# define EM_386 3
+# define EM_SPARC 2
+# define EM_PPC 20
#else
# include <elf.h>
#endif
@@ -71,7 +88,7 @@ public:
// Construct and take ownership of the file stream object.
cmELFInternal(cmELF* external,
- cmsys::auto_ptr<std::ifstream>& fin,
+ cmsys::auto_ptr<cmsys::ifstream>& fin,
ByteOrderType order):
External(external),
Stream(*fin.release()),
@@ -81,9 +98,9 @@ public:
// In most cases the processor-specific byte order will match that
// of the target execution environment. If we choose wrong here
// it is fixed when the header is read.
-#if cmsys_CPU_ENDIAN_ID == cmsys_CPU_ENDIAN_ID_LITTLE
+#if KWIML_ABI_ENDIAN_ID == KWIML_ABI_ENDIAN_ID_LITTLE
this->NeedSwap = (this->ByteOrder == ByteOrderMSB);
-#elif cmsys_CPU_ENDIAN_ID == cmsys_CPU_ENDIAN_ID_BIG
+#elif KWIML_ABI_ENDIAN_ID == KWIML_ABI_ENDIAN_ID_BIG
this->NeedSwap = (this->ByteOrder == ByteOrderLSB);
#else
this->NeedSwap = false; // Final decision is at runtime anyway.
@@ -103,7 +120,7 @@ public:
virtual unsigned int GetNumberOfSections() const = 0;
virtual unsigned int GetDynamicEntryCount() = 0;
virtual unsigned long GetDynamicEntryPosition(int j) = 0;
- virtual StringEntry const* GetDynamicSectionString(int tag) = 0;
+ virtual StringEntry const* GetDynamicSectionString(unsigned int tag) = 0;
virtual void PrintInfo(std::ostream& os) const = 0;
bool ReadBytes(unsigned long pos, unsigned long size, char* buf)
@@ -166,7 +183,7 @@ protected:
}
// Store string table entry states.
- std::map<int, StringEntry> DynamicSectionStrings;
+ std::map<unsigned int, StringEntry> DynamicSectionStrings;
};
//----------------------------------------------------------------------------
@@ -177,16 +194,18 @@ struct cmELFTypes32
typedef Elf32_Shdr ELF_Shdr;
typedef Elf32_Dyn ELF_Dyn;
typedef Elf32_Half ELF_Half;
+ typedef KWIML_INT_uint32_t tagtype;
static const char* GetName() { return "32-bit"; }
};
-// Configure the implementation template for 32-bit ELF files.
+// Configure the implementation template for 64-bit ELF files.
struct cmELFTypes64
{
typedef Elf64_Ehdr ELF_Ehdr;
typedef Elf64_Shdr ELF_Shdr;
typedef Elf64_Dyn ELF_Dyn;
typedef Elf64_Half ELF_Half;
+ typedef KWIML_INT_uint64_t tagtype;
static const char* GetName() { return "64-bit"; }
};
@@ -201,10 +220,11 @@ public:
typedef typename Types::ELF_Shdr ELF_Shdr;
typedef typename Types::ELF_Dyn ELF_Dyn;
typedef typename Types::ELF_Half ELF_Half;
+ typedef typename Types::tagtype tagtype;
// Construct with a stream and byte swap indicator.
cmELFInternalImpl(cmELF* external,
- cmsys::auto_ptr<std::ifstream>& fin,
+ cmsys::auto_ptr<cmsys::ifstream>& fin,
ByteOrderType order);
// Return the number of sections as specified by the ELF header.
@@ -218,7 +238,7 @@ public:
virtual unsigned long GetDynamicEntryPosition(int j);
// Lookup a string from the dynamic section with the given tag.
- virtual StringEntry const* GetDynamicSectionString(int tag);
+ virtual StringEntry const* GetDynamicSectionString(unsigned int tag);
// Print information about the ELF file.
virtual void PrintInfo(std::ostream& os) const
@@ -462,7 +482,7 @@ private:
template <class Types>
cmELFInternalImpl<Types>
::cmELFInternalImpl(cmELF* external,
- cmsys::auto_ptr<std::ifstream>& fin,
+ cmsys::auto_ptr<cmsys::ifstream>& fin,
ByteOrderType order):
cmELFInternal(external, fin, order)
{
@@ -508,7 +528,7 @@ cmELFInternalImpl<Types>
break;
}
#endif
- cmOStringStream e;
+ std::ostringstream e;
e << "Unknown ELF file type " << eti;
this->SetErrorMessage(e.str().c_str());
return;
@@ -543,8 +563,14 @@ bool cmELFInternalImpl<Types>::LoadDynamicSection()
return true;
}
- // Allocate the dynamic section entries.
+ // If there are no entries we are done.
ELF_Shdr const& sec = this->SectionHeaders[this->DynamicSectionIndex];
+ if(sec.sh_entsize == 0)
+ {
+ return false;
+ }
+
+ // Allocate the dynamic section entries.
int n = static_cast<int>(sec.sh_size / sec.sh_entsize);
this->DynamicSectionEntries.resize(n);
@@ -603,10 +629,10 @@ unsigned long cmELFInternalImpl<Types>::GetDynamicEntryPosition(int j)
//----------------------------------------------------------------------------
template <class Types>
cmELF::StringEntry const*
-cmELFInternalImpl<Types>::GetDynamicSectionString(int tag)
+cmELFInternalImpl<Types>::GetDynamicSectionString(unsigned int tag)
{
// Short-circuit if already checked.
- std::map<int, StringEntry>::iterator dssi =
+ std::map<unsigned int, StringEntry>::iterator dssi =
this->DynamicSectionStrings.find(tag);
if(dssi != this->DynamicSectionStrings.end())
{
@@ -644,7 +670,7 @@ cmELFInternalImpl<Types>::GetDynamicSectionString(int tag)
di != this->DynamicSectionEntries.end(); ++di)
{
ELF_Dyn& dyn = *di;
- if(dyn.d_tag == tag)
+ if(static_cast<tagtype>(dyn.d_tag) == static_cast<tagtype>(tag))
{
// We found the tag requested.
// Make sure the position given is within the string section.
@@ -707,7 +733,7 @@ cmELFInternalImpl<Types>::GetDynamicSectionString(int tag)
cmELF::cmELF(const char* fname): Internal(0)
{
// Try to open the file.
- cmsys::auto_ptr<std::ifstream> fin(new std::ifstream(fname));
+ cmsys::auto_ptr<cmsys::ifstream> fin(new cmsys::ifstream(fname));
// Quit now if the file could not be opened.
if(!fin.get() || !*fin)
diff --git a/Source/cmElseCommand.h b/Source/cmElseCommand.h
index f25991943..dde5fcc61 100644
--- a/Source/cmElseCommand.h
+++ b/Source/cmElseCommand.h
@@ -45,25 +45,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "else";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Starts the else portion of an if block.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " else(expression)\n"
- "See the if command.";
- }
+ virtual std::string GetName() const { return "else";}
cmTypeMacro(cmElseCommand, cmCommand);
};
diff --git a/Source/cmElseIfCommand.h b/Source/cmElseIfCommand.h
index 46e2bd9f9..c627cbe5e 100644
--- a/Source/cmElseIfCommand.h
+++ b/Source/cmElseIfCommand.h
@@ -45,25 +45,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "elseif";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Starts the elseif portion of an if block.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " elseif(expression)\n"
- "See the if command.";
- }
+ virtual std::string GetName() const { return "elseif";}
cmTypeMacro(cmElseIfCommand, cmCommand);
};
diff --git a/Source/cmEnableLanguageCommand.h b/Source/cmEnableLanguageCommand.h
index 747448b3e..2b09e1186 100644
--- a/Source/cmEnableLanguageCommand.h
+++ b/Source/cmEnableLanguageCommand.h
@@ -43,38 +43,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const {return "enable_language";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Enable a language (CXX/C/Fortran/etc)";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " enable_language(<lang> [OPTIONAL] )\n"
- "This command enables support for the named language in CMake. "
- "This is the same as the project command but does not create "
- "any of the extra variables that are created by the project command. "
- "Example languages are CXX, C, Fortran. "
- "\n"
- "This command must be called in file scope, not in a function call. "
- "Furthermore, it must be called in the highest directory common to "
- "all targets using the named language directly for compiling sources "
- "or indirectly through link dependencies. "
- "It is simplest to enable all needed languages in the top-level "
- "directory of a project."
- "\n"
- "The OPTIONAL keyword is a placeholder for future implementation "
- "and does not currently work.";
- }
+ virtual std::string GetName() const {return "enable_language";}
cmTypeMacro(cmEnableLanguageCommand, cmCommand);
};
diff --git a/Source/cmEnableTestingCommand.cxx b/Source/cmEnableTestingCommand.cxx
index aa41ef73b..6a7fd4692 100644
--- a/Source/cmEnableTestingCommand.cxx
+++ b/Source/cmEnableTestingCommand.cxx
@@ -10,7 +10,6 @@
See the License for more information.
============================================================================*/
#include "cmEnableTestingCommand.h"
-#include "cmLocalGenerator.h"
// we do this in the final pass so that we now the subdirs have all
// been defined
diff --git a/Source/cmEnableTestingCommand.h b/Source/cmEnableTestingCommand.h
index 9b9e9851b..d028c59b4 100644
--- a/Source/cmEnableTestingCommand.h
+++ b/Source/cmEnableTestingCommand.h
@@ -48,28 +48,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "enable_testing";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Enable testing for current directory and below.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " enable_testing()\n"
- "Enables testing for this directory and below. "
- "See also the add_test command. Note that ctest expects to find "
- "a test file in the build directory root. Therefore, this command "
- "should be in the source directory root.";
- }
+ virtual std::string GetName() const { return "enable_testing";}
cmTypeMacro(cmEnableTestingCommand, cmCommand);
diff --git a/Source/cmEndForEachCommand.h b/Source/cmEndForEachCommand.h
index d5ee8a6ae..c3be3879b 100644
--- a/Source/cmEndForEachCommand.h
+++ b/Source/cmEndForEachCommand.h
@@ -52,25 +52,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "endforeach";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Ends a list of commands in a FOREACH block.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " endforeach(expression)\n"
- "See the FOREACH command.";
- }
+ virtual std::string GetName() const { return "endforeach";}
cmTypeMacro(cmEndForEachCommand, cmCommand);
};
diff --git a/Source/cmEndFunctionCommand.h b/Source/cmEndFunctionCommand.h
index d7b74e98b..3a42c1743 100644
--- a/Source/cmEndFunctionCommand.h
+++ b/Source/cmEndFunctionCommand.h
@@ -52,25 +52,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "endfunction";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Ends a list of commands in a function block.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " endfunction(expression)\n"
- "See the function command.";
- }
+ virtual std::string GetName() const { return "endfunction";}
cmTypeMacro(cmEndFunctionCommand, cmCommand);
};
diff --git a/Source/cmEndIfCommand.h b/Source/cmEndIfCommand.h
index 5c4b9e36a..a8248c81a 100644
--- a/Source/cmEndIfCommand.h
+++ b/Source/cmEndIfCommand.h
@@ -45,25 +45,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "endif";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Ends a list of commands in an if block.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " endif(expression)\n"
- "See the if command.";
- }
+ virtual std::string GetName() const { return "endif";}
cmTypeMacro(cmEndIfCommand, cmCommand);
};
diff --git a/Source/cmEndMacroCommand.h b/Source/cmEndMacroCommand.h
index 9d0e70fdc..fdc04eebb 100644
--- a/Source/cmEndMacroCommand.h
+++ b/Source/cmEndMacroCommand.h
@@ -52,25 +52,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "endmacro";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Ends a list of commands in a macro block.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " endmacro(expression)\n"
- "See the macro command.";
- }
+ virtual std::string GetName() const { return "endmacro";}
cmTypeMacro(cmEndMacroCommand, cmCommand);
};
diff --git a/Source/cmEndWhileCommand.h b/Source/cmEndWhileCommand.h
index 18ba5ea31..ec1cb652f 100644
--- a/Source/cmEndWhileCommand.h
+++ b/Source/cmEndWhileCommand.h
@@ -52,25 +52,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "endwhile";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Ends a list of commands in a while block.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " endwhile(expression)\n"
- "See the while command.";
- }
+ virtual std::string GetName() const { return "endwhile";}
cmTypeMacro(cmEndWhileCommand, cmCommand);
};
diff --git a/Source/cmExecProgramCommand.cxx b/Source/cmExecProgramCommand.cxx
index 9fdb1e896..41785c2b0 100644
--- a/Source/cmExecProgramCommand.cxx
+++ b/Source/cmExecProgramCommand.cxx
@@ -12,6 +12,8 @@
#include "cmExecProgramCommand.h"
#include "cmSystemTools.h"
+#include <cmsys/Process.h>
+
// cmExecProgramCommand
bool cmExecProgramCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
@@ -39,7 +41,7 @@ bool cmExecProgramCommand
}
else if ( haveoutput_variable )
{
- if ( output_variable.size() > 0 )
+ if (!output_variable.empty())
{
this->SetError("called with incorrect number of arguments");
return false;
@@ -57,7 +59,7 @@ bool cmExecProgramCommand
}
else if ( havereturn_variable )
{
- if ( return_variable.size() > 0 )
+ if (!return_variable.empty())
{
this->SetError("called with incorrect number of arguments");
return false;
@@ -82,7 +84,7 @@ bool cmExecProgramCommand
}
std::string command;
- if(arguments.size())
+ if(!arguments.empty())
{
command = cmSystemTools::ConvertToRunCommandPath(args[0].c_str());
command += " ";
@@ -93,7 +95,7 @@ bool cmExecProgramCommand
command = args[0];
}
bool verbose = true;
- if(output_variable.size() > 0)
+ if(!output_variable.empty())
{
verbose = false;
}
@@ -103,20 +105,20 @@ bool cmExecProgramCommand
if(args.size() - count == 2)
{
cmSystemTools::MakeDirectory(args[1].c_str());
- result = cmSystemTools::RunCommand(command.c_str(), output, retVal,
- args[1].c_str(), verbose);
+ result = cmExecProgramCommand::RunCommand(command.c_str(), output, retVal,
+ args[1].c_str(), verbose);
}
else
{
- result = cmSystemTools::RunCommand(command.c_str(), output,
- retVal, 0, verbose);
+ result = cmExecProgramCommand::RunCommand(command.c_str(), output,
+ retVal, 0, verbose);
}
if(!result)
{
retVal = -1;
}
- if ( output_variable.size() > 0 )
+ if (!output_variable.empty())
{
std::string::size_type first = output.find_first_not_of(" \n\t\r");
std::string::size_type last = output.find_last_not_of(" \n\t\r");
@@ -130,16 +132,202 @@ bool cmExecProgramCommand
}
std::string coutput = std::string(output, first, last-first+1);
- this->Makefile->AddDefinition(output_variable.c_str(), coutput.c_str());
+ this->Makefile->AddDefinition(output_variable, coutput.c_str());
}
- if ( return_variable.size() > 0 )
+ if (!return_variable.empty())
{
char buffer[100];
sprintf(buffer, "%d", retVal);
- this->Makefile->AddDefinition(return_variable.c_str(), buffer);
+ this->Makefile->AddDefinition(return_variable, buffer);
}
return true;
}
+bool cmExecProgramCommand::RunCommand(const char* command,
+ std::string& output,
+ int &retVal,
+ const char* dir,
+ bool verbose)
+{
+ if(cmSystemTools::GetRunCommandOutput())
+ {
+ verbose = false;
+ }
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ // if the command does not start with a quote, then
+ // try to find the program, and if the program can not be
+ // found use system to run the command as it must be a built in
+ // shell command like echo or dir
+ int count = 0;
+ std::string shortCmd;
+ if(command[0] == '\"')
+ {
+ // count the number of quotes
+ for(const char* s = command; *s != 0; ++s)
+ {
+ if(*s == '\"')
+ {
+ count++;
+ if(count > 2)
+ {
+ break;
+ }
+ }
+ }
+ // if there are more than two double quotes use
+ // GetShortPathName, the cmd.exe program in windows which
+ // is used by system fails to execute if there are more than
+ // one set of quotes in the arguments
+ if(count > 2)
+ {
+ cmsys::RegularExpression quoted("^\"([^\"]*)\"[ \t](.*)");
+ if(quoted.find(command))
+ {
+ std::string cmd = quoted.match(1);
+ std::string args = quoted.match(2);
+ if(! cmSystemTools::FileExists(cmd.c_str()) )
+ {
+ shortCmd = cmd;
+ }
+ else if(!cmSystemTools::GetShortPath(cmd.c_str(), shortCmd))
+ {
+ cmSystemTools::Error("GetShortPath failed for " , cmd.c_str());
+ return false;
+ }
+ shortCmd += " ";
+ shortCmd += args;
+
+ command = shortCmd.c_str();
+ }
+ else
+ {
+ cmSystemTools::Error("Could not parse command line with quotes ",
+ command);
+ }
+ }
+ }
+#endif
+
+ // Allocate a process instance.
+ cmsysProcess* cp = cmsysProcess_New();
+ if(!cp)
+ {
+ cmSystemTools::Error("Error allocating process instance.");
+ return false;
+ }
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if(dir)
+ {
+ cmsysProcess_SetWorkingDirectory(cp, dir);
+ }
+ if(cmSystemTools::GetRunCommandHideConsole())
+ {
+ cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
+ }
+ cmsysProcess_SetOption(cp, cmsysProcess_Option_Verbatim, 1);
+ const char* cmd[] = {command, 0};
+ cmsysProcess_SetCommand(cp, cmd);
+#else
+ std::string commandInDir;
+ if(dir)
+ {
+ commandInDir = "cd \"";
+ commandInDir += dir;
+ commandInDir += "\" && ";
+ commandInDir += command;
+ }
+ else
+ {
+ commandInDir = command;
+ }
+#ifndef __VMS
+ commandInDir += " 2>&1";
+#endif
+ command = commandInDir.c_str();
+ if(verbose)
+ {
+ cmSystemTools::Stdout("running ");
+ cmSystemTools::Stdout(command);
+ cmSystemTools::Stdout("\n");
+ }
+ fflush(stdout);
+ fflush(stderr);
+ const char* cmd[] = {"/bin/sh", "-c", command, 0};
+ cmsysProcess_SetCommand(cp, cmd);
+#endif
+
+ cmsysProcess_Execute(cp);
+
+ // Read the process output.
+ int length;
+ char* data;
+ int p;
+ while((p = cmsysProcess_WaitForData(cp, &data, &length, 0), p))
+ {
+ if(p == cmsysProcess_Pipe_STDOUT || p == cmsysProcess_Pipe_STDERR)
+ {
+ if(verbose)
+ {
+ cmSystemTools::Stdout(data, length);
+ }
+ output.append(data, length);
+ }
+ }
+
+ // All output has been read. Wait for the process to exit.
+ cmsysProcess_WaitForExit(cp, 0);
+
+ // Check the result of running the process.
+ std::string msg;
+ switch(cmsysProcess_GetState(cp))
+ {
+ case cmsysProcess_State_Exited:
+ retVal = cmsysProcess_GetExitValue(cp);
+ break;
+ case cmsysProcess_State_Exception:
+ retVal = -1;
+ msg += "\nProcess terminated due to: ";
+ msg += cmsysProcess_GetExceptionString(cp);
+ break;
+ case cmsysProcess_State_Error:
+ retVal = -1;
+ msg += "\nProcess failed because: ";
+ msg += cmsysProcess_GetErrorString(cp);
+ break;
+ case cmsysProcess_State_Expired:
+ retVal = -1;
+ msg += "\nProcess terminated due to timeout.";
+ break;
+ }
+ if(!msg.empty())
+ {
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ // Old Windows process execution printed this info.
+ msg += "\n\nfor command: ";
+ msg += command;
+ if(dir)
+ {
+ msg += "\nin dir: ";
+ msg += dir;
+ }
+ msg += "\n";
+ if(verbose)
+ {
+ cmSystemTools::Stdout(msg.c_str());
+ }
+ output += msg;
+#else
+ // Old UNIX process execution only put message in output.
+ output += msg;
+#endif
+ }
+
+ // Delete the process instance.
+ cmsysProcess_Delete(cp);
+
+ return true;
+}
diff --git a/Source/cmExecProgramCommand.h b/Source/cmExecProgramCommand.h
index f752501fa..adefdf923 100644
--- a/Source/cmExecProgramCommand.h
+++ b/Source/cmExecProgramCommand.h
@@ -42,7 +42,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const
+ virtual std::string GetName() const
{return "exec_program";}
/**
@@ -50,46 +50,11 @@ public:
*/
virtual bool IsScriptable() const { return true; }
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return
- "Deprecated. Use the execute_process() command instead.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- "Run an executable program during the processing of the CMakeList.txt"
- " file.\n"
- " exec_program(Executable [directory in which to run]\n"
- " [ARGS <arguments to executable>]\n"
- " [OUTPUT_VARIABLE <var>]\n"
- " [RETURN_VALUE <var>])\n"
- "The executable is run in the optionally specified directory. The "
- "executable can include arguments if it is double quoted, but it is "
- "better to use the optional ARGS argument to specify arguments to the "
- "program. This is because cmake will then be able to escape spaces "
- "in the executable path. An optional argument OUTPUT_VARIABLE "
- "specifies a variable in which to store the output. "
- "To capture the return value of the execution, provide a RETURN_VALUE. "
- "If OUTPUT_VARIABLE is specified, then no output will go to the "
- "stdout/stderr of the console running cmake.\n"
- ;
- }
-
- /** This command is kept for compatibility with older CMake versions. */
- virtual bool IsDiscouraged() const
- {
- return true;
- }
-
cmTypeMacro(cmExecProgramCommand, cmCommand);
+private:
+ static bool RunCommand(const char* command, std::string& output,
+ int &retVal, const char* directory = 0,
+ bool verbose = true);
};
#endif
diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx
index 994c1707b..a37139051 100644
--- a/Source/cmExecuteProcessCommand.cxx
+++ b/Source/cmExecuteProcessCommand.cxx
@@ -189,9 +189,9 @@ bool cmExecuteProcessCommand
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << " given unknown argument \"" << args[i] << "\".";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
@@ -200,7 +200,7 @@ bool cmExecuteProcessCommand
{
std::string e = "attempted to output into a file: " + output_file
+ " into a source directory.";
- this->SetError(e.c_str());
+ this->SetError(e);
cmSystemTools::SetFatalErrorOccured();
return false;
}
@@ -255,11 +255,7 @@ bool cmExecuteProcessCommand
cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
// Check the output variables.
- bool merge_output = (output_variable == error_variable);
- if(error_variable.empty() && !error_quiet)
- {
- cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDERR, 1);
- }
+ bool merge_output = false;
if(!input_file.empty())
{
cmsysProcess_SetPipeFile(cp, cmsysProcess_Pipe_STDIN, input_file.c_str());
@@ -271,8 +267,23 @@ bool cmExecuteProcessCommand
}
if(!error_file.empty())
{
- cmsysProcess_SetPipeFile(cp, cmsysProcess_Pipe_STDERR,
- error_file.c_str());
+ if (error_file == output_file)
+ {
+ merge_output = true;
+ }
+ else
+ {
+ cmsysProcess_SetPipeFile(cp, cmsysProcess_Pipe_STDERR,
+ error_file.c_str());
+ }
+ }
+ if (!output_variable.empty() && output_variable == error_variable)
+ {
+ merge_output = true;
+ }
+ if (merge_output)
+ {
+ cmsysProcess_SetOption(cp, cmsysProcess_Option_MergeOutput, 1);
}
// Set the timeout if any.
@@ -293,8 +304,7 @@ bool cmExecuteProcessCommand
while((p = cmsysProcess_WaitForData(cp, &data, &length, 0), p))
{
// Put the output in the right place.
- if((p == cmsysProcess_Pipe_STDOUT && !output_quiet) ||
- (p == cmsysProcess_Pipe_STDERR && !error_quiet && merge_output))
+ if (p == cmsysProcess_Pipe_STDOUT && !output_quiet)
{
if(output_variable.empty())
{
@@ -307,7 +317,11 @@ bool cmExecuteProcessCommand
}
else if(p == cmsysProcess_Pipe_STDERR && !error_quiet)
{
- if(!error_variable.empty())
+ if(error_variable.empty())
+ {
+ cmSystemTools::Stderr(data, length);
+ }
+ else
{
cmExecuteProcessCommandAppend(tempError, data, length);
}
@@ -324,14 +338,14 @@ bool cmExecuteProcessCommand
error_strip_trailing_whitespace);
// Store the output obtained.
- if(!output_variable.empty() && tempOutput.size())
+ if(!output_variable.empty() && !tempOutput.empty())
{
- this->Makefile->AddDefinition(output_variable.c_str(),
+ this->Makefile->AddDefinition(output_variable,
&*tempOutput.begin());
}
- if(!merge_output && !error_variable.empty() && tempError.size())
+ if(!merge_output && !error_variable.empty() && !tempError.empty())
{
- this->Makefile->AddDefinition(error_variable.c_str(),
+ this->Makefile->AddDefinition(error_variable,
&*tempError.begin());
}
@@ -345,19 +359,19 @@ bool cmExecuteProcessCommand
int v = cmsysProcess_GetExitValue(cp);
char buf[100];
sprintf(buf, "%d", v);
- this->Makefile->AddDefinition(result_variable.c_str(), buf);
+ this->Makefile->AddDefinition(result_variable, buf);
}
break;
case cmsysProcess_State_Exception:
- this->Makefile->AddDefinition(result_variable.c_str(),
+ this->Makefile->AddDefinition(result_variable,
cmsysProcess_GetExceptionString(cp));
break;
case cmsysProcess_State_Error:
- this->Makefile->AddDefinition(result_variable.c_str(),
+ this->Makefile->AddDefinition(result_variable,
cmsysProcess_GetErrorString(cp));
break;
case cmsysProcess_State_Expired:
- this->Makefile->AddDefinition(result_variable.c_str(),
+ this->Makefile->AddDefinition(result_variable,
"Process terminated due to timeout");
break;
}
diff --git a/Source/cmExecuteProcessCommand.h b/Source/cmExecuteProcessCommand.h
index 0e20a4b19..6906a08a8 100644
--- a/Source/cmExecuteProcessCommand.h
+++ b/Source/cmExecuteProcessCommand.h
@@ -41,7 +41,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const
+ virtual std::string GetName() const
{return "execute_process";}
/**
@@ -49,64 +49,6 @@ public:
*/
virtual bool IsScriptable() const { return true; }
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Execute one or more child processes.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " execute_process(COMMAND <cmd1> [args1...]]\n"
- " [COMMAND <cmd2> [args2...] [...]]\n"
- " [WORKING_DIRECTORY <directory>]\n"
- " [TIMEOUT <seconds>]\n"
- " [RESULT_VARIABLE <variable>]\n"
- " [OUTPUT_VARIABLE <variable>]\n"
- " [ERROR_VARIABLE <variable>]\n"
- " [INPUT_FILE <file>]\n"
- " [OUTPUT_FILE <file>]\n"
- " [ERROR_FILE <file>]\n"
- " [OUTPUT_QUIET]\n"
- " [ERROR_QUIET]\n"
- " [OUTPUT_STRIP_TRAILING_WHITESPACE]\n"
- " [ERROR_STRIP_TRAILING_WHITESPACE])\n"
- "Runs the given sequence of one or more commands with the standard "
- "output of each process piped to the standard input of the next. "
- "A single standard error pipe is used for all processes. "
- "If WORKING_DIRECTORY is given the named directory will be set as "
- "the current working directory of the child processes. "
- "If TIMEOUT is given the child processes will be terminated if they "
- "do not finish in the specified number of seconds "
- "(fractions are allowed). "
- "If RESULT_VARIABLE is given the variable will be set to contain "
- "the result of running the processes. This will be an integer return "
- "code from the last child or a string describing an error condition. "
- "If OUTPUT_VARIABLE or ERROR_VARIABLE are given the variable named "
- "will be set with the contents of the standard output and standard "
- "error pipes respectively. If the same variable is named for both "
- "pipes their output will be merged in the order produced. "
- "If INPUT_FILE, OUTPUT_FILE, or ERROR_FILE is given the file named "
- "will be attached to the standard input of the first process, "
- "standard output of the last process, or standard error of all "
- "processes respectively. "
- "If OUTPUT_QUIET or ERROR_QUIET is given then the standard output "
- "or standard error results will be quietly ignored. "
- "If more than one OUTPUT_* or ERROR_* option is given for the same "
- "pipe the precedence is not specified. "
- "If no OUTPUT_* or ERROR_* options are given the output will be shared "
- "with the corresponding pipes of the CMake process itself.\n"
- "The execute_process command is a newer more powerful version of "
- "exec_program, but the old command has been kept for compatibility."
- ;
- }
-
cmTypeMacro(cmExecuteProcessCommand, cmCommand);
};
diff --git a/Source/cmExecutionStatus.h b/Source/cmExecutionStatus.h
index 1488924c7..201465d1d 100644
--- a/Source/cmExecutionStatus.h
+++ b/Source/cmExecutionStatus.h
@@ -12,43 +12,47 @@
#ifndef cmExecutionStatus_h
#define cmExecutionStatus_h
-#include "cmObject.h"
+#include "cmStandardIncludes.h"
/** \class cmExecutionStatus
* \brief Superclass for all command status classes
*
* when a command is involked it may set values on a command status instance
*/
-class cmExecutionStatus : public cmObject
+class cmExecutionStatus
{
public:
- cmTypeMacro(cmExecutionStatus, cmObject);
+ cmExecutionStatus() { this->Clear(); }
- cmExecutionStatus() { this->Clear();};
-
- virtual void SetReturnInvoked(bool val)
+ void SetReturnInvoked(bool val)
{ this->ReturnInvoked = val; }
- virtual bool GetReturnInvoked()
+ bool GetReturnInvoked()
{ return this->ReturnInvoked; }
- virtual void SetBreakInvoked(bool val)
+ void SetBreakInvoked(bool val)
{ this->BreakInvoked = val; }
- virtual bool GetBreakInvoked()
+ bool GetBreakInvoked()
{ return this->BreakInvoked; }
- virtual void Clear()
+ void SetContinueInvoked(bool val)
+ { this->ContinueInvoked = val; }
+ bool GetContinueInvoked()
+ { return this->ContinueInvoked; }
+
+ void Clear()
{
this->ReturnInvoked = false;
this->BreakInvoked = false;
+ this->ContinueInvoked = false;
this->NestedError = false;
}
- virtual void SetNestedError(bool val) { this->NestedError = val; }
- virtual bool GetNestedError() { return this->NestedError; }
-
+ void SetNestedError(bool val) { this->NestedError = val; }
+ bool GetNestedError() { return this->NestedError; }
-protected:
+private:
bool ReturnInvoked;
bool BreakInvoked;
+ bool ContinueInvoked;
bool NestedError;
};
diff --git a/Source/cmExpandedCommandArgument.cxx b/Source/cmExpandedCommandArgument.cxx
new file mode 100644
index 000000000..4477cf5a0
--- /dev/null
+++ b/Source/cmExpandedCommandArgument.cxx
@@ -0,0 +1,51 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmExpandedCommandArgument.h"
+
+cmExpandedCommandArgument::cmExpandedCommandArgument():
+ Quoted(false)
+{
+
+}
+
+cmExpandedCommandArgument::cmExpandedCommandArgument(
+ std::string const& value, bool quoted):
+ Value(value), Quoted(quoted)
+{
+
+}
+
+std::string const& cmExpandedCommandArgument::GetValue() const
+{
+ return this->Value;
+}
+
+bool cmExpandedCommandArgument::WasQuoted() const
+{
+ return this->Quoted;
+}
+
+bool cmExpandedCommandArgument::operator== (std::string const& value) const
+{
+ return this->Value == value;
+}
+
+bool cmExpandedCommandArgument::empty() const
+{
+ return this->Value.empty();
+}
+
+const char* cmExpandedCommandArgument::c_str() const
+{
+ return this->Value.c_str();
+}
diff --git a/Source/cmExpandedCommandArgument.h b/Source/cmExpandedCommandArgument.h
new file mode 100644
index 000000000..f4e151704
--- /dev/null
+++ b/Source/cmExpandedCommandArgument.h
@@ -0,0 +1,45 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmExpandedCommandArgument_h
+#define cmExpandedCommandArgument_h
+
+#include "cmStandardIncludes.h"
+
+/** \class cmExpandedCommandArgument
+ * \brief Represents an expanded command argument
+ *
+ * cmCommandArgument stores a string representing an expanded
+ * command argument and context information.
+ */
+
+class cmExpandedCommandArgument
+{
+public:
+ cmExpandedCommandArgument();
+ cmExpandedCommandArgument(std::string const& value, bool quoted);
+
+ std::string const& GetValue() const;
+
+ bool WasQuoted() const;
+
+ bool operator== (std::string const& value) const;
+
+ bool empty() const;
+
+ const char* c_str() const;
+
+private:
+ std::string Value;
+ bool Quoted;
+};
+
+#endif
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index cdc3316c4..dcb21876c 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -11,42 +11,61 @@
============================================================================*/
#include "cmExportBuildFileGenerator.h"
-#include "cmExportCommand.h"
+#include "cmLocalGenerator.h"
+#include "cmGlobalGenerator.h"
+#include "cmExportSet.h"
+#include "cmTargetExport.h"
//----------------------------------------------------------------------------
cmExportBuildFileGenerator::cmExportBuildFileGenerator()
{
- this->ExportCommand = 0;
+ this->LG = 0;
+ this->ExportSet = 0;
+}
+
+//----------------------------------------------------------------------------
+void cmExportBuildFileGenerator::Compute(cmLocalGenerator* lg)
+{
+ this->LG = lg;
+ if (this->ExportSet)
+ {
+ this->ExportSet->Compute(lg);
+ }
}
//----------------------------------------------------------------------------
bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
{
- std::vector<cmTarget*> allTargets;
{
std::string expectedTargets;
std::string sep;
- for(std::vector<cmTarget*>::const_iterator
- tei = this->Exports->begin();
- tei != this->Exports->end(); ++tei)
+ std::vector<std::string> targets;
+ this->GetTargets(targets);
+ for(std::vector<std::string>::const_iterator
+ tei = targets.begin();
+ tei != targets.end(); ++tei)
{
- expectedTargets += sep + this->Namespace + (*tei)->GetExportName();
+ cmGeneratorTarget *te = this->LG
+ ->FindGeneratorTargetToUse(*tei);
+ expectedTargets += sep + this->Namespace + te->GetExportName();
sep = " ";
- cmTarget* te = *tei;
if(this->ExportedTargets.insert(te).second)
{
- allTargets.push_back(te);
+ this->Exports.push_back(te);
}
else
{
- if(this->ExportCommand && this->ExportCommand->ErrorMessage.empty())
- {
- cmOStringStream e;
- e << "given target \"" << te->GetName() << "\" more than once.";
- this->ExportCommand->ErrorMessage = e.str();
- }
+ std::ostringstream e;
+ e << "given target \"" << te->GetName() << "\" more than once.";
+ this->LG->GetGlobalGenerator()->GetCMakeInstance()
+ ->IssueMessage(cmake::FATAL_ERROR, e.str(),
+ this->LG->GetMakefile()->GetBacktrace());
return false;
}
+ if (te->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ this->GenerateRequiredCMakeVersion(os, "3.0.0");
+ }
}
this->GenerateExpectedTargetsCode(os, expectedTargets);
@@ -55,40 +74,49 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
std::vector<std::string> missingTargets;
// Create all the imported targets.
- for(std::vector<cmTarget*>::const_iterator
- tei = allTargets.begin();
- tei != allTargets.end(); ++tei)
+ for(std::vector<cmGeneratorTarget*>::const_iterator
+ tei = this->Exports.begin();
+ tei != this->Exports.end(); ++tei)
{
- cmTarget* te = *tei;
- this->GenerateImportTargetCode(os, te);
+ cmGeneratorTarget* gte = *tei;
+ this->GenerateImportTargetCode(os, gte);
- te->AppendBuildInterfaceIncludes();
+ gte->Target->AppendBuildInterfaceIncludes();
ImportPropertyMap properties;
- this->PopulateInterfaceProperty("INTERFACE_INCLUDE_DIRECTORIES", te,
+ this->PopulateInterfaceProperty("INTERFACE_INCLUDE_DIRECTORIES", gte,
+ cmGeneratorExpression::BuildInterface,
+ properties, missingTargets);
+ this->PopulateInterfaceProperty("INTERFACE_SOURCES", gte,
+ cmGeneratorExpression::BuildInterface,
+ properties, missingTargets);
+ this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS", gte,
cmGeneratorExpression::BuildInterface,
properties, missingTargets);
- this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS", te,
+ this->PopulateInterfaceProperty("INTERFACE_COMPILE_OPTIONS", gte,
cmGeneratorExpression::BuildInterface,
properties, missingTargets);
- this->PopulateInterfaceProperty("INTERFACE_COMPILE_OPTIONS", te,
+ this->PopulateInterfaceProperty("INTERFACE_AUTOUIC_OPTIONS", gte,
+ cmGeneratorExpression::BuildInterface,
+ properties, missingTargets);
+ this->PopulateInterfaceProperty("INTERFACE_COMPILE_FEATURES", gte,
cmGeneratorExpression::BuildInterface,
properties, missingTargets);
this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE",
- te, properties);
+ gte, properties);
const bool newCMP0022Behavior =
- te->GetPolicyStatusCMP0022() != cmPolicies::WARN
- && te->GetPolicyStatusCMP0022() != cmPolicies::OLD;
+ gte->GetPolicyStatusCMP0022() != cmPolicies::WARN
+ && gte->GetPolicyStatusCMP0022() != cmPolicies::OLD;
if (newCMP0022Behavior)
{
- this->PopulateInterfaceLinkLibrariesProperty(te,
+ this->PopulateInterfaceLinkLibrariesProperty(gte,
cmGeneratorExpression::BuildInterface,
properties, missingTargets);
}
- this->PopulateCompatibleInterfaceProperties(te, properties);
+ this->PopulateCompatibleInterfaceProperties(gte, properties);
- this->GenerateInterfaceProperties(te, os, properties);
+ this->GenerateInterfaceProperties(gte, os, properties);
}
// Generate import file content for each configuration.
@@ -96,7 +124,7 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
ci = this->Configurations.begin();
ci != this->Configurations.end(); ++ci)
{
- this->GenerateImportConfig(os, ci->c_str(), missingTargets);
+ this->GenerateImportConfig(os, *ci, missingTargets);
}
this->GenerateMissingTargetsCheckCode(os, missingTargets);
@@ -108,26 +136,35 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
void
cmExportBuildFileGenerator
::GenerateImportTargetsConfig(std::ostream& os,
- const char* config, std::string const& suffix,
- std::vector<std::string> &missingTargets)
+ const std::string& config,
+ std::string const& suffix,
+ std::vector<std::string> &missingTargets)
{
- for(std::vector<cmTarget*>::const_iterator
- tei = this->Exports->begin();
- tei != this->Exports->end(); ++tei)
+ for(std::vector<cmGeneratorTarget*>::const_iterator
+ tei = this->Exports.begin();
+ tei != this->Exports.end(); ++tei)
{
// Collect import properties for this target.
- cmTarget* target = *tei;
+ cmGeneratorTarget* target = *tei;
ImportPropertyMap properties;
- this->SetImportLocationProperty(config, suffix, target, properties);
+
+ if (target->GetType() != cmState::INTERFACE_LIBRARY)
+ {
+ this->SetImportLocationProperty(config, suffix, target, properties);
+ }
if(!properties.empty())
{
// Get the rest of the target details.
- this->SetImportDetailProperties(config, suffix,
- target, properties, missingTargets);
- this->SetImportLinkInterface(config, suffix,
- cmGeneratorExpression::BuildInterface,
- target, properties, missingTargets);
-
+ if (target->GetType() != cmState::INTERFACE_LIBRARY)
+ {
+ this->SetImportDetailProperties(config, suffix,
+ target,
+ properties, missingTargets);
+ this->SetImportLinkInterface(config, suffix,
+ cmGeneratorExpression::BuildInterface,
+ target,
+ properties, missingTargets);
+ }
// TOOD: PUBLIC_HEADER_LOCATION
// This should wait until the build feature propagation stuff
@@ -136,19 +173,28 @@ cmExportBuildFileGenerator
// properties);
// Generate code in the export file.
- this->GenerateImportPropertyCode(os, config, target, properties);
+ this->GenerateImportPropertyCode(os, config, target,
+ properties);
}
}
}
//----------------------------------------------------------------------------
+void cmExportBuildFileGenerator::SetExportSet(cmExportSet *exportSet)
+{
+ this->ExportSet = exportSet;
+}
+
+//----------------------------------------------------------------------------
void
cmExportBuildFileGenerator
-::SetImportLocationProperty(const char* config, std::string const& suffix,
- cmTarget* target, ImportPropertyMap& properties)
+::SetImportLocationProperty(const std::string& config,
+ std::string const& suffix,
+ cmGeneratorTarget* target,
+ ImportPropertyMap& properties)
{
// Get the makefile in which to lookup target information.
- cmMakefile* mf = target->GetMakefile();
+ cmMakefile* mf = target->Makefile;
// Add the main target file.
{
@@ -166,13 +212,9 @@ cmExportBuildFileGenerator
properties[prop] = value;
}
- // Check whether this is a DLL platform.
- bool dll_platform =
- (mf->IsOn("WIN32") || mf->IsOn("CYGWIN") || mf->IsOn("MINGW"));
-
// Add the import library for windows DLLs.
- if(dll_platform &&
- (target->GetType() == cmTarget::SHARED_LIBRARY ||
+ if(target->IsDLLPlatform() &&
+ (target->GetType() == cmState::SHARED_LIBRARY ||
target->IsExecutableWithExports()) &&
mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"))
{
@@ -188,15 +230,35 @@ cmExportBuildFileGenerator
//----------------------------------------------------------------------------
void
cmExportBuildFileGenerator::HandleMissingTarget(
- std::string& link_libs, std::vector<std::string>&,
- cmMakefile*, cmTarget* depender, cmTarget* dependee)
+ std::string& link_libs,
+ std::vector<std::string>& missingTargets,
+ cmGeneratorTarget* depender,
+ cmGeneratorTarget* dependee)
{
// The target is not in the export.
if(!this->AppendMode)
{
- // We are not appending, so all exported targets should be
- // known here. This is probably user-error.
- this->ComplainAboutMissingTarget(depender, dependee);
+ const std::string name = dependee->GetName();
+ cmGlobalGenerator* gg =
+ dependee->GetLocalGenerator()->GetGlobalGenerator();
+ std::vector<std::string> namespaces = this->FindNamespaces(gg, name);
+
+ int targetOccurrences = (int)namespaces.size();
+ if (targetOccurrences == 1)
+ {
+ std::string missingTarget = namespaces[0];
+
+ missingTarget += dependee->GetExportName();
+ link_libs += missingTarget;
+ missingTargets.push_back(missingTarget);
+ return;
+ }
+ else
+ {
+ // We are not appending, so all exported targets should be
+ // known here. This is probably user-error.
+ this->ComplainAboutMissingTarget(depender, dependee, targetOccurrences);
+ }
}
// Assume the target will be exported by another command.
// Append it with the export namespace.
@@ -205,36 +267,90 @@ cmExportBuildFileGenerator::HandleMissingTarget(
}
//----------------------------------------------------------------------------
+void cmExportBuildFileGenerator
+::GetTargets(std::vector<std::string> &targets) const
+{
+ if (this->ExportSet)
+ {
+ for(std::vector<cmTargetExport*>::const_iterator
+ tei = this->ExportSet->GetTargetExports()->begin();
+ tei != this->ExportSet->GetTargetExports()->end(); ++tei)
+ {
+ targets.push_back((*tei)->TargetName);
+ }
+ return;
+ }
+ targets = this->Targets;
+}
+
+//----------------------------------------------------------------------------
+std::vector<std::string>
+cmExportBuildFileGenerator
+::FindNamespaces(cmGlobalGenerator* gg, const std::string& name)
+{
+ std::vector<std::string> namespaces;
+
+ std::map<std::string, cmExportBuildFileGenerator*>& exportSets
+ = gg->GetBuildExportSets();
+
+ for(std::map<std::string, cmExportBuildFileGenerator*>::const_iterator
+ expIt = exportSets.begin(); expIt != exportSets.end(); ++expIt)
+ {
+ const cmExportBuildFileGenerator* exportSet = expIt->second;
+ std::vector<std::string> targets;
+ exportSet->GetTargets(targets);
+ if (std::find(targets.begin(), targets.end(), name) != targets.end())
+ {
+ namespaces.push_back(exportSet->GetNamespace());
+ }
+ }
+
+ return namespaces;
+}
+
+//----------------------------------------------------------------------------
void
cmExportBuildFileGenerator
-::ComplainAboutMissingTarget(cmTarget* depender,
- cmTarget* dependee)
+::ComplainAboutMissingTarget(cmGeneratorTarget* depender,
+ cmGeneratorTarget* dependee,
+ int occurrences)
{
- if(!this->ExportCommand || !this->ExportCommand->ErrorMessage.empty())
+ if(cmSystemTools::GetErrorOccuredFlag())
{
return;
}
- cmOStringStream e;
- e << "called with target \"" << depender->GetName()
- << "\" which requires target \"" << dependee->GetName()
- << "\" that is not in the export list.\n"
- << "If the required target is not easy to reference in this call, "
+ std::ostringstream e;
+ e << "export called with target \"" << depender->GetName()
+ << "\" which requires target \"" << dependee->GetName() << "\" ";
+ if (occurrences == 0)
+ {
+ e << "that is not in the export set.\n";
+ }
+ else
+ {
+ e << "that is not in this export set, but " << occurrences
+ << " times in others.\n";
+ }
+ e << "If the required target is not easy to reference in this call, "
<< "consider using the APPEND option with multiple separate calls.";
- this->ExportCommand->ErrorMessage = e.str();
+
+ this->LG->GetGlobalGenerator()->GetCMakeInstance()
+ ->IssueMessage(cmake::FATAL_ERROR, e.str(),
+ this->LG->GetMakefile()->GetBacktrace());
}
std::string
-cmExportBuildFileGenerator::InstallNameDir(cmTarget* target,
+cmExportBuildFileGenerator::InstallNameDir(cmGeneratorTarget* target,
const std::string& config)
{
std::string install_name_dir;
- cmMakefile* mf = target->GetMakefile();
+ cmMakefile* mf = target->Target->GetMakefile();
if(mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
{
install_name_dir =
- target->GetInstallNameDirForBuildTree(config.c_str());
+ target->GetInstallNameDirForBuildTree(config);
}
return install_name_dir;
diff --git a/Source/cmExportBuildFileGenerator.h b/Source/cmExportBuildFileGenerator.h
index 3ffdf8b13..85aae2fa4 100644
--- a/Source/cmExportBuildFileGenerator.h
+++ b/Source/cmExportBuildFileGenerator.h
@@ -13,8 +13,9 @@
#define cmExportBuildFileGenerator_h
#include "cmExportFileGenerator.h"
+#include "cmListFileCache.h"
-class cmExportCommand;
+class cmExportSet;
/** \class cmExportBuildFileGenerator
* \brief Generate a file exporting targets from a build tree.
@@ -31,40 +32,51 @@ public:
cmExportBuildFileGenerator();
/** Set the list of targets to export. */
- void SetExports(std::vector<cmTarget*> const* exports)
- { this->Exports = exports; }
+ void SetTargets(std::vector<std::string> const& targets)
+ { this->Targets = targets; }
+ void GetTargets(std::vector<std::string> &targets) const;
+ void AppendTargets(std::vector<std::string> const& targets)
+ { this->Targets.insert(this->Targets.end(),
+ targets.begin(), targets.end()); }
+ void SetExportSet(cmExportSet*);
/** Set whether to append generated code to the output file. */
void SetAppendMode(bool append) { this->AppendMode = append; }
- /** Set the command instance through which errors should be reported. */
- void SetCommand(cmExportCommand* cmd) { this->ExportCommand = cmd; }
+ void Compute(cmLocalGenerator* lg);
+
protected:
// Implement virtual methods from the superclass.
virtual bool GenerateMainFile(std::ostream& os);
virtual void GenerateImportTargetsConfig(std::ostream& os,
- const char* config,
+ const std::string& config,
std::string const& suffix,
std::vector<std::string> &missingTargets);
virtual void HandleMissingTarget(std::string& link_libs,
std::vector<std::string>& missingTargets,
- cmMakefile* mf,
- cmTarget* depender,
- cmTarget* dependee);
+ cmGeneratorTarget* depender,
+ cmGeneratorTarget* dependee);
- void ComplainAboutMissingTarget(cmTarget* depender,
- cmTarget* dependee);
+ void ComplainAboutMissingTarget(cmGeneratorTarget* depender,
+ cmGeneratorTarget* dependee,
+ int occurrences);
/** Fill in properties indicating built file locations. */
- void SetImportLocationProperty(const char* config,
+ void SetImportLocationProperty(const std::string& config,
std::string const& suffix,
- cmTarget* target,
+ cmGeneratorTarget* target,
ImportPropertyMap& properties);
- std::string InstallNameDir(cmTarget* target, const std::string& config);
+ std::string InstallNameDir(cmGeneratorTarget* target,
+ const std::string& config);
+
+ std::vector<std::string>
+ FindNamespaces(cmGlobalGenerator* gg, const std::string& name);
- std::vector<cmTarget*> const* Exports;
- cmExportCommand* ExportCommand;
+ std::vector<std::string> Targets;
+ cmExportSet *ExportSet;
+ std::vector<cmGeneratorTarget*> Exports;
+ cmLocalGenerator* LG;
};
#endif
diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx
index f059ceba6..4eec66a33 100644
--- a/Source/cmExportCommand.cxx
+++ b/Source/cmExportCommand.cxx
@@ -11,16 +11,17 @@
============================================================================*/
#include "cmExportCommand.h"
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
#include "cmGeneratedFileStream.h"
#include "cmake.h"
#include <cmsys/RegularExpression.hxx>
+#include <cmsys/Encoding.hxx>
#include "cmExportBuildFileGenerator.h"
#if defined(__HAIKU__)
-#include <StorageKit.h>
+#include <FindDirectory.h>
+#include <StorageDefs.h>
#endif
cmExportCommand::cmExportCommand()
@@ -28,14 +29,12 @@ cmExportCommand::cmExportCommand()
,ArgumentGroup()
,Targets(&Helper, "TARGETS")
,Append(&Helper, "APPEND", &ArgumentGroup)
+,ExportSetName(&Helper, "EXPORT", &ArgumentGroup)
,Namespace(&Helper, "NAMESPACE", &ArgumentGroup)
,Filename(&Helper, "FILE", &ArgumentGroup)
,ExportOld(&Helper, "EXPORT_LINK_INTERFACE_LIBRARIES", &ArgumentGroup)
{
- // at first TARGETS
- this->Targets.Follows(0);
- // and after that the other options in any order
- this->ArgumentGroup.Follows(&this->Targets);
+ this->ExportSet = 0;
}
@@ -53,6 +52,16 @@ bool cmExportCommand
{
return this->HandlePackage(args);
}
+ else if (args[0] == "EXPORT")
+ {
+ this->ExportSetName.Follows(0);
+ this->ArgumentGroup.Follows(&this->ExportSetName);
+ }
+ else
+ {
+ this->Targets.Follows(0);
+ this->ArgumentGroup.Follows(&this->Targets);
+ }
std::vector<std::string> unknownArgs;
this->Helper.Parse(&args, &unknownArgs);
@@ -63,142 +72,178 @@ bool cmExportCommand
return false;
}
- if (this->Targets.WasFound() == false)
- {
- this->SetError("TARGETS option missing.");
- return false;
- }
-
+ std::string fname;
if(!this->Filename.WasFound())
{
- this->SetError("FILE <filename> option missing.");
- return false;
+ if (args[0] != "EXPORT")
+ {
+ this->SetError("FILE <filename> option missing.");
+ return false;
+ }
+ fname = this->ExportSetName.GetString() + ".cmake";
}
-
- // Make sure the file has a .cmake extension.
- if(cmSystemTools::GetFilenameLastExtension(this->Filename.GetCString())
- != ".cmake")
+ else
{
- cmOStringStream e;
- e << "FILE option given filename \"" << this->Filename.GetString()
- << "\" which does not have an extension of \".cmake\".\n";
- this->SetError(e.str().c_str());
- return false;
+ // Make sure the file has a .cmake extension.
+ if(cmSystemTools::GetFilenameLastExtension(this->Filename.GetCString())
+ != ".cmake")
+ {
+ std::ostringstream e;
+ e << "FILE option given filename \"" << this->Filename.GetString()
+ << "\" which does not have an extension of \".cmake\".\n";
+ this->SetError(e.str());
+ return false;
+ }
+ fname = this->Filename.GetString();
}
// Get the file to write.
- std::string fname = this->Filename.GetString();
if(cmSystemTools::FileIsFullPath(fname.c_str()))
{
if(!this->Makefile->CanIWriteThisFile(fname.c_str()))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "FILE option given filename \"" << fname
<< "\" which is in the source tree.\n";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
else
{
// Interpret relative paths with respect to the current build dir.
- fname = this->Makefile->GetCurrentOutputDirectory();
- fname += "/";
- fname += this->Filename.GetString();
+ std::string dir = this->Makefile->GetCurrentBinaryDirectory();
+ fname = dir + "/" + fname;
}
- // Collect the targets to be exported.
- std::vector<cmTarget*> targets;
- for(std::vector<std::string>::const_iterator
- currentTarget = this->Targets.GetVector().begin();
- currentTarget != this->Targets.GetVector().end();
- ++currentTarget)
+ std::vector<std::string> targets;
+
+ cmGlobalGenerator *gg = this->Makefile->GetGlobalGenerator();
+
+ if(args[0] == "EXPORT")
{
- if (this->Makefile->IsAlias(currentTarget->c_str()))
+ if (this->Append.IsEnabled())
{
- cmOStringStream e;
- e << "given ALIAS target \"" << *currentTarget
- << "\" which may not be exported.";
- this->SetError(e.str().c_str());
+ std::ostringstream e;
+ e << "EXPORT signature does not recognise the APPEND option.";
+ this->SetError(e.str());
return false;
}
- if(cmTarget* target =
- this->Makefile->GetLocalGenerator()->
- GetGlobalGenerator()->FindTarget(0, currentTarget->c_str()))
+ if (this->ExportOld.IsEnabled())
{
- if((target->GetType() == cmTarget::EXECUTABLE) ||
- (target->GetType() == cmTarget::STATIC_LIBRARY) ||
- (target->GetType() == cmTarget::SHARED_LIBRARY) ||
- (target->GetType() == cmTarget::MODULE_LIBRARY))
- {
- targets.push_back(target);
- }
- else if(target->GetType() == cmTarget::OBJECT_LIBRARY)
+ std::ostringstream e;
+ e << "EXPORT signature does not recognise the "
+ "EXPORT_LINK_INTERFACE_LIBRARIES option.";
+ this->SetError(e.str());
+ return false;
+ }
+
+ cmExportSetMap &setMap = gg->GetExportSets();
+ std::string setName = this->ExportSetName.GetString();
+ if (setMap.find(setName) == setMap.end())
+ {
+ std::ostringstream e;
+ e << "Export set \"" << setName << "\" not found.";
+ this->SetError(e.str());
+ return false;
+ }
+ this->ExportSet = setMap[setName];
+ }
+ else if (this->Targets.WasFound())
+ {
+ for(std::vector<std::string>::const_iterator
+ currentTarget = this->Targets.GetVector().begin();
+ currentTarget != this->Targets.GetVector().end();
+ ++currentTarget)
+ {
+ if (this->Makefile->IsAlias(*currentTarget))
{
- cmOStringStream e;
- e << "given OBJECT library \"" << *currentTarget
+ std::ostringstream e;
+ e << "given ALIAS target \"" << *currentTarget
<< "\" which may not be exported.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
+
+ if(cmTarget* target = gg->FindTarget(*currentTarget))
+ {
+ if(target->GetType() == cmState::OBJECT_LIBRARY)
+ {
+ std::ostringstream e;
+ e << "given OBJECT library \"" << *currentTarget
+ << "\" which may not be exported.";
+ this->SetError(e.str());
+ return false;
+ }
+ if (target->GetType() == cmState::UTILITY)
+ {
+ this->SetError("given custom target \"" + *currentTarget
+ + "\" which may not be exported.");
+ return false;
+ }
+ }
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "given target \"" << *currentTarget
- << "\" which is not an executable or library.";
- this->SetError(e.str().c_str());
+ << "\" which is not built by this project.";
+ this->SetError(e.str());
return false;
}
+ targets.push_back(*currentTarget);
}
- else
+ if (this->Append.IsEnabled())
{
- cmOStringStream e;
- e << "given target \"" << *currentTarget
- << "\" which is not built by this project.";
- this->SetError(e.str().c_str());
- return false;
+ if (cmExportBuildFileGenerator *ebfg = gg->GetExportedTargetsFile(fname))
+ {
+ ebfg->AppendTargets(targets);
+ return true;
+ }
}
}
+ else
+ {
+ this->SetError("EXPORT or TARGETS specifier missing.");
+ return false;
+ }
// Setup export file generation.
- cmExportBuildFileGenerator ebfg;
- ebfg.SetExportFile(fname.c_str());
- ebfg.SetNamespace(this->Namespace.GetCString());
- ebfg.SetAppendMode(this->Append.IsEnabled());
- ebfg.SetExports(&targets);
- ebfg.SetCommand(this);
- ebfg.SetExportOld(this->ExportOld.IsEnabled());
+ cmExportBuildFileGenerator *ebfg = new cmExportBuildFileGenerator;
+ ebfg->SetExportFile(fname.c_str());
+ ebfg->SetNamespace(this->Namespace.GetCString());
+ ebfg->SetAppendMode(this->Append.IsEnabled());
+ if (this->ExportSet)
+ {
+ ebfg->SetExportSet(this->ExportSet);
+ }
+ else
+ {
+ ebfg->SetTargets(targets);
+ }
+ this->Makefile->AddExportBuildFileGenerator(ebfg);
+ ebfg->SetExportOld(this->ExportOld.IsEnabled());
// Compute the set of configurations exported.
std::vector<std::string> configurationTypes;
this->Makefile->GetConfigurations(configurationTypes);
- if(!configurationTypes.empty())
+ if(configurationTypes.empty())
{
- for(std::vector<std::string>::const_iterator
- ci = configurationTypes.begin();
- ci != configurationTypes.end(); ++ci)
- {
- ebfg.AddConfiguration(ci->c_str());
- }
+ configurationTypes.push_back("");
}
- else
+ for(std::vector<std::string>::const_iterator
+ ci = configurationTypes.begin();
+ ci != configurationTypes.end(); ++ci)
{
- ebfg.AddConfiguration("");
+ ebfg->AddConfiguration(*ci);
}
-
- // Generate the import file.
- if(!ebfg.GenerateImportFile() && this->ErrorMessage.empty())
+ if (this->ExportSet)
{
- this->SetError("could not write export file.");
- return false;
+ gg->AddBuildExportExportSet(ebfg);
}
-
- // Report generated error message if any.
- if(!this->ErrorMessage.empty())
+ else
{
- this->SetError(this->ErrorMessage.c_str());
- return false;
+ gg->AddBuildExportSet(ebfg);
}
return true;
@@ -220,9 +265,9 @@ bool cmExportCommand::HandlePackage(std::vector<std::string> const& args)
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "PACKAGE given unknown argument: " << args[i];
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
@@ -237,17 +282,24 @@ bool cmExportCommand::HandlePackage(std::vector<std::string> const& args)
cmsys::RegularExpression packageRegex(packageExpr);
if(!packageRegex.find(package.c_str()))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "PACKAGE given invalid package name \"" << package << "\". "
<< "Package names must match \"" << packageExpr << "\".";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
+ // If the CMAKE_EXPORT_NO_PACKAGE_REGISTRY variable is set the command
+ // export(PACKAGE) does nothing.
+ if(this->Makefile->IsOn("CMAKE_EXPORT_NO_PACKAGE_REGISTRY"))
+ {
+ return true;
+ }
+
// We store the current build directory in the registry as a value
// named by a hash of its own content. This is deterministic and is
// unique with high probability.
- const char* outDir = this->Makefile->GetCurrentOutputDirectory();
+ const char* outDir = this->Makefile->GetCurrentBinaryDirectory();
std::string hash = cmSystemTools::ComputeStringMD5(outDir);
#if defined(_WIN32) && !defined(__CYGWIN__)
this->StorePackageRegistryWin(package, outDir, hash.c_str());
@@ -266,17 +318,17 @@ void cmExportCommand::ReportRegistryError(std::string const& msg,
std::string const& key,
long err)
{
- cmOStringStream e;
+ std::ostringstream e;
e << msg << "\n"
<< " HKEY_CURRENT_USER\\" << key << "\n";
- char winmsg[1024];
- if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
+ wchar_t winmsg[1024];
+ if(FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, 0, err,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
winmsg, 1024, 0) > 0)
{
e << "Windows reported:\n"
- << " " << winmsg;
+ << " " << cmsys::Encoding::ToNarrow(winmsg);
}
this->Makefile->IssueMessage(cmake::WARNING, e.str());
}
@@ -289,8 +341,9 @@ void cmExportCommand::StorePackageRegistryWin(std::string const& package,
std::string key = "Software\\Kitware\\CMake\\Packages\\";
key += package;
HKEY hKey;
- LONG err = RegCreateKeyEx(HKEY_CURRENT_USER,
- key.c_str(), 0, 0, REG_OPTION_NON_VOLATILE,
+ LONG err = RegCreateKeyExW(HKEY_CURRENT_USER,
+ cmsys::Encoding::ToWide(key).c_str(),
+ 0, 0, REG_OPTION_NON_VOLATILE,
KEY_SET_VALUE, 0, &hKey, 0);
if(err != ERROR_SUCCESS)
{
@@ -298,12 +351,15 @@ void cmExportCommand::StorePackageRegistryWin(std::string const& package,
"Cannot create/open registry key", key, err);
return;
}
- err = RegSetValueEx(hKey, hash, 0, REG_SZ, (BYTE const*)content,
- static_cast<DWORD>(strlen(content)+1));
+
+ std::wstring wcontent = cmsys::Encoding::ToWide(content);
+ err = RegSetValueExW(hKey, cmsys::Encoding::ToWide(hash).c_str(),
+ 0, REG_SZ, (BYTE const*)wcontent.c_str(),
+ static_cast<DWORD>(wcontent.size()+1)*sizeof(wchar_t));
RegCloseKey(hKey);
if(err != ERROR_SUCCESS)
{
- cmOStringStream msg;
+ std::ostringstream msg;
msg << "Cannot set registry value \"" << hash << "\" under key";
this->ReportRegistryError(msg.str(), key, err);
return;
@@ -316,14 +372,15 @@ void cmExportCommand::StorePackageRegistryDir(std::string const& package,
const char* hash)
{
#if defined(__HAIKU__)
- BPath dir;
- if (find_directory(B_USER_SETTINGS_DIRECTORY, &dir) != B_OK)
+ char dir[B_PATH_NAME_LENGTH];
+ if (find_directory(B_USER_SETTINGS_DIRECTORY, -1, false, dir, sizeof(dir)) !=
+ B_OK)
{
return;
}
- dir.Append("cmake/packages");
- dir.Append(package.c_str());
- std::string fname = dir.Path();
+ std::string fname = dir;
+ fname += "/cmake/packages/";
+ fname += package;
#else
const char* home = cmSystemTools::GetEnv("HOME");
if(!home)
@@ -347,7 +404,7 @@ void cmExportCommand::StorePackageRegistryDir(std::string const& package,
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Cannot create package registry file:\n"
<< " " << fname << "\n"
<< cmSystemTools::GetLastSystemError() << "\n";
diff --git a/Source/cmExportCommand.h b/Source/cmExportCommand.h
index 87c345284..f9506bbdd 100644
--- a/Source/cmExportCommand.h
+++ b/Source/cmExportCommand.h
@@ -13,9 +13,9 @@
#define cmExportCommand_h
#include "cmCommand.h"
-#include "cmDocumentLocationUndefined.h"
class cmExportBuildFileGenerator;
+class cmExportSet;
/** \class cmExportLibraryDependenciesCommand
* \brief Add a test to the lists of tests to run.
@@ -45,60 +45,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "export";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return
- "Export targets from the build tree for use by outside projects.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " export(TARGETS [target1 [target2 [...]]] [NAMESPACE <namespace>]\n"
- " [APPEND] FILE <filename> [EXPORT_LINK_INTERFACE_LIBRARIES])\n"
- "Create a file <filename> that may be included by outside projects to "
- "import targets from the current project's build tree. "
- "This is useful during cross-compiling to build utility executables "
- "that can run on the host platform in one project and then import "
- "them into another project being compiled for the target platform. "
- "If the NAMESPACE option is given the <namespace> string will be "
- "prepended to all target names written to the file. "
- "If the APPEND option is given the generated code will be appended "
- "to the file instead of overwriting it. "
- "The EXPORT_LINK_INTERFACE_LIBRARIES keyword, if present, causes the "
- "contents of the properties matching "
- "(IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)? to be exported, when "
- "policy CMP0022 is NEW. "
- "If a library target is included in the export but "
- "a target to which it links is not included the behavior is "
- "unspecified."
- "\n"
- "The file created by this command is specific to the build tree and "
- "should never be installed. "
- "See the install(EXPORT) command to export targets from an "
- "installation tree."
- CM_LOCATION_UNDEFINED_BEHAVIOR("passing it to this command")
- "\n"
- " export(PACKAGE <name>)\n"
- "Store the current build directory in the CMake user package registry "
- "for package <name>. "
- "The find_package command may consider the directory while searching "
- "for package <name>. "
- "This helps dependent projects find and use a package from the "
- "current project's build tree without help from the user. "
- "Note that the entry in the package registry that this command "
- "creates works only in conjunction with a package configuration "
- "file (<name>Config.cmake) that works with the build tree."
- ;
- }
+ virtual std::string GetName() const { return "export";}
cmTypeMacro(cmExportCommand, cmCommand);
@@ -106,10 +53,13 @@ private:
cmCommandArgumentGroup ArgumentGroup;
cmCAStringVector Targets;
cmCAEnabler Append;
+ cmCAString ExportSetName;
cmCAString Namespace;
cmCAString Filename;
cmCAEnabler ExportOld;
+ cmExportSet *ExportSet;
+
friend class cmExportBuildFileGenerator;
std::string ErrorMessage;
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 14be5cd47..c005995f7 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -18,15 +18,32 @@
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
-#include "cmTarget.h"
#include "cmTargetExport.h"
#include "cmVersion.h"
#include "cmComputeLinkInformation.h"
+#include "cmAlgorithms.h"
+#include "cmOutputConverter.h"
#include <cmsys/auto_ptr.hxx>
+#include <cmsys/FStream.hxx>
#include <assert.h>
//----------------------------------------------------------------------------
+static std::string cmExportFileGeneratorEscape(std::string const& str)
+{
+ // Escape a property value for writing into a .cmake file.
+ std::string result = cmOutputConverter::EscapeForCMake(str);
+ // Un-escape variable references generated by our own export code.
+ cmSystemTools::ReplaceString(result,
+ "\\${_IMPORT_PREFIX}",
+ "${_IMPORT_PREFIX}");
+ cmSystemTools::ReplaceString(result,
+ "\\${CMAKE_IMPORT_LIBRARY_SUFFIX}",
+ "${CMAKE_IMPORT_LIBRARY_SUFFIX}");
+ return result;
+}
+
+//----------------------------------------------------------------------------
cmExportFileGenerator::cmExportFileGenerator()
{
this->AppendMode = false;
@@ -34,7 +51,7 @@ cmExportFileGenerator::cmExportFileGenerator()
}
//----------------------------------------------------------------------------
-void cmExportFileGenerator::AddConfiguration(const char* config)
+void cmExportFileGenerator::AddConfiguration(const std::string& config)
{
this->Configurations.push_back(config);
}
@@ -52,15 +69,21 @@ void cmExportFileGenerator::SetExportFile(const char* mainFile)
}
//----------------------------------------------------------------------------
+const char* cmExportFileGenerator::GetMainExportFileName() const
+{
+ return this->MainImportFile.c_str();
+}
+
+//----------------------------------------------------------------------------
bool cmExportFileGenerator::GenerateImportFile()
{
// Open the output file to generate it.
- cmsys::auto_ptr<std::ofstream> foutPtr;
+ cmsys::auto_ptr<cmsys::ofstream> foutPtr;
if(this->AppendMode)
{
// Open for append.
- cmsys::auto_ptr<std::ofstream>
- ap(new std::ofstream(this->MainImportFile.c_str(), std::ios::app));
+ cmsys::auto_ptr<cmsys::ofstream>
+ ap(new cmsys::ofstream(this->MainImportFile.c_str(), std::ios::app));
foutPtr = ap;
}
else
@@ -74,7 +97,7 @@ bool cmExportFileGenerator::GenerateImportFile()
if(!foutPtr.get() || !*foutPtr)
{
std::string se = cmSystemTools::GetLastSystemError();
- cmOStringStream e;
+ std::ostringstream e;
e << "cannot write to file \"" << this->MainImportFile
<< "\": " << se;
cmSystemTools::Error(e.str().c_str());
@@ -110,12 +133,12 @@ bool cmExportFileGenerator::GenerateImportFile()
//----------------------------------------------------------------------------
void cmExportFileGenerator::GenerateImportConfig(std::ostream& os,
- const char* config,
+ const std::string& config,
std::vector<std::string> &missingTargets)
{
// Construct the property configuration suffix.
std::string suffix = "_";
- if(config && *config)
+ if(!config.empty())
{
suffix += cmSystemTools::UpperCase(config);
}
@@ -129,8 +152,9 @@ void cmExportFileGenerator::GenerateImportConfig(std::ostream& os,
}
//----------------------------------------------------------------------------
-void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName,
- cmTarget *target,
+void cmExportFileGenerator::PopulateInterfaceProperty(
+ const std::string& propName,
+ cmGeneratorTarget *target,
ImportPropertyMap &properties)
{
const char *input = target->GetProperty(propName);
@@ -141,9 +165,10 @@ void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName,
}
//----------------------------------------------------------------------------
-void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName,
- const char *outputName,
- cmTarget *target,
+void cmExportFileGenerator::PopulateInterfaceProperty(
+ const std::string& propName,
+ const std::string& outputName,
+ cmGeneratorTarget *target,
cmGeneratorExpression::PreprocessContext preprocessRule,
ImportPropertyMap &properties,
std::vector<std::string> &missingTargets)
@@ -180,7 +205,7 @@ void cmExportFileGenerator::GenerateRequiredCMakeVersion(std::ostream& os,
//----------------------------------------------------------------------------
bool cmExportFileGenerator::PopulateInterfaceLinkLibrariesProperty(
- cmTarget *target,
+ cmGeneratorTarget *target,
cmGeneratorExpression::PreprocessContext preprocessRule,
ImportPropertyMap &properties,
std::vector<std::string> &missingTargets)
@@ -215,68 +240,194 @@ static bool isSubDirectory(const char* a, const char* b)
//----------------------------------------------------------------------------
static bool checkInterfaceDirs(const std::string &prepro,
- cmTarget *target)
+ cmGeneratorTarget *target, const std::string& prop)
{
const char* installDir =
- target->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
- const char* topSourceDir = target->GetMakefile()->GetHomeDirectory();
- const char* topBinaryDir = target->GetMakefile()->GetHomeOutputDirectory();
+ target->Makefile->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
+ const char* topSourceDir =
+ target->GetLocalGenerator()->GetSourceDirectory();
+ const char* topBinaryDir =
+ target->GetLocalGenerator()->GetBinaryDirectory();
std::vector<std::string> parts;
cmGeneratorExpression::Split(prepro, parts);
const bool inSourceBuild = strcmp(topSourceDir, topBinaryDir) == 0;
+ bool hadFatalError = false;
+
for(std::vector<std::string>::iterator li = parts.begin();
li != parts.end(); ++li)
{
- if (cmGeneratorExpression::Find(*li) != std::string::npos)
+ size_t genexPos = cmGeneratorExpression::Find(*li);
+ if (genexPos == 0)
{
continue;
}
- if (strncmp(li->c_str(), "${_IMPORT_PREFIX}", 17) == 0)
+ cmake::MessageType messageType = cmake::FATAL_ERROR;
+ std::ostringstream e;
+ if (genexPos != std::string::npos)
+ {
+ if (prop == "INTERFACE_INCLUDE_DIRECTORIES")
+ {
+ switch (target->GetPolicyStatusCMP0041())
+ {
+ case cmPolicies::WARN:
+ messageType = cmake::WARNING;
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0041) << "\n";
+ break;
+ case cmPolicies::OLD:
+ continue;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ hadFatalError = true;
+ break; // Issue fatal message.
+ }
+ }
+ else
+ {
+ hadFatalError = true;
+ }
+ }
+ if (cmHasLiteralPrefix(li->c_str(), "${_IMPORT_PREFIX}"))
{
continue;
}
if (!cmSystemTools::FileIsFullPath(li->c_str()))
{
- cmOStringStream e;
- e << "Target \"" << target->GetName() << "\" "
- "INTERFACE_INCLUDE_DIRECTORIES property contains relative path:\n"
+ e << "Target \"" << target->GetName() << "\" " << prop <<
+ " property contains relative path:\n"
" \"" << *li << "\"";
- target->GetMakefile()->IssueMessage(cmake::FATAL_ERROR,
- e.str().c_str());
- return false;
+ target->GetLocalGenerator()->IssueMessage(messageType, e.str());
}
+ bool inBinary = isSubDirectory(li->c_str(), topBinaryDir);
+ bool inSource = isSubDirectory(li->c_str(), topSourceDir);
if (isSubDirectory(li->c_str(), installDir))
{
- continue;
+ // The include directory is inside the install tree. If the
+ // install tree is not inside the source tree or build tree then
+ // fall through to the checks below that the include directory is not
+ // also inside the source tree or build tree.
+ bool shouldContinue =
+ (!inBinary || isSubDirectory(installDir, topBinaryDir)) &&
+ (!inSource || isSubDirectory(installDir, topSourceDir));
+
+ if (prop == "INTERFACE_INCLUDE_DIRECTORIES")
+ {
+ if (!shouldContinue)
+ {
+ switch(target->GetPolicyStatusCMP0052())
+ {
+ case cmPolicies::WARN:
+ {
+ std::ostringstream s;
+ s << cmPolicies::GetPolicyWarning(cmPolicies::CMP0052) << "\n";
+ s << "Directory:\n \"" << *li << "\"\nin "
+ "INTERFACE_INCLUDE_DIRECTORIES of target \""
+ << target->GetName() << "\" is a subdirectory of the install "
+ "directory:\n \"" << installDir << "\"\nhowever it is also "
+ "a subdirectory of the " << (inBinary ? "build" : "source")
+ << " tree:\n \"" << (inBinary ? topBinaryDir : topSourceDir)
+ << "\"" << std::endl;
+ target->GetLocalGenerator()->IssueMessage(cmake::AUTHOR_WARNING,
+ s.str());
+ }
+ case cmPolicies::OLD:
+ shouldContinue = true;
+ break;
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::NEW:
+ break;
+ }
+ }
+ }
+ if (shouldContinue)
+ {
+ continue;
+ }
}
- if (isSubDirectory(li->c_str(), topBinaryDir))
+ if (inBinary)
{
- cmOStringStream e;
- e << "Target \"" << target->GetName() << "\" "
- "INTERFACE_INCLUDE_DIRECTORIES property contains path:\n"
+ e << "Target \"" << target->GetName() << "\" " << prop <<
+ " property contains path:\n"
" \"" << *li << "\"\nwhich is prefixed in the build directory.";
- target->GetMakefile()->IssueMessage(cmake::FATAL_ERROR,
- e.str().c_str());
- return false;
+ target->GetLocalGenerator()->IssueMessage(messageType, e.str());
}
if (!inSourceBuild)
{
- if (isSubDirectory(li->c_str(), topSourceDir))
+ if (inSource)
{
- cmOStringStream e;
- e << "Target \"" << target->GetName() << "\" "
- "INTERFACE_INCLUDE_DIRECTORIES property contains path:\n"
+ e << "Target \"" << target->GetName() << "\" " << prop <<
+ " property contains path:\n"
" \"" << *li << "\"\nwhich is prefixed in the source directory.";
- target->GetMakefile()->IssueMessage(cmake::FATAL_ERROR,
- e.str().c_str());
- return false;
+ target->GetLocalGenerator()->IssueMessage(messageType, e.str());
}
}
}
- return true;
+ return !hadFatalError;
+}
+
+//----------------------------------------------------------------------------
+static void prefixItems(std::string &exportDirs)
+{
+ std::vector<std::string> entries;
+ cmGeneratorExpression::Split(exportDirs, entries);
+ exportDirs = "";
+ const char *sep = "";
+ for(std::vector<std::string>::const_iterator ei = entries.begin();
+ ei != entries.end(); ++ei)
+ {
+ exportDirs += sep;
+ sep = ";";
+ if (!cmSystemTools::FileIsFullPath(ei->c_str())
+ && ei->find("${_IMPORT_PREFIX}") == std::string::npos)
+ {
+ exportDirs += "${_IMPORT_PREFIX}/";
+ }
+ exportDirs += *ei;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmExportFileGenerator::PopulateSourcesInterface(
+ cmTargetExport *tei,
+ cmGeneratorExpression::PreprocessContext preprocessRule,
+ ImportPropertyMap &properties,
+ std::vector<std::string> &missingTargets)
+{
+ cmGeneratorTarget* gt = tei->Target;
+ assert(preprocessRule == cmGeneratorExpression::InstallInterface);
+
+ const char *propName = "INTERFACE_SOURCES";
+ const char *input = gt->GetProperty(propName);
+
+ if (!input)
+ {
+ return;
+ }
+
+ if (!*input)
+ {
+ properties[propName] = "";
+ return;
+ }
+
+ std::string prepro = cmGeneratorExpression::Preprocess(input,
+ preprocessRule,
+ true);
+ if (!prepro.empty())
+ {
+ this->ResolveTargetsInGeneratorExpressions(prepro, gt,
+ missingTargets);
+
+ if (!checkInterfaceDirs(prepro, gt, propName))
+ {
+ return;
+ }
+ properties[propName] = prepro;
+ }
}
//----------------------------------------------------------------------------
@@ -286,30 +437,32 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
ImportPropertyMap &properties,
std::vector<std::string> &missingTargets)
{
- cmTarget *target = tei->Target;
+ cmGeneratorTarget *target = tei->Target;
assert(preprocessRule == cmGeneratorExpression::InstallInterface);
const char *propName = "INTERFACE_INCLUDE_DIRECTORIES";
const char *input = target->GetProperty(propName);
- cmListFileBacktrace lfbt;
- cmGeneratorExpression ge(lfbt);
+ cmGeneratorExpression ge;
- std::string dirs = tei->InterfaceIncludeDirectories;
+ std::string dirs = cmGeneratorExpression::Preprocess(
+ tei->InterfaceIncludeDirectories,
+ preprocessRule,
+ true);
this->ReplaceInstallPrefix(dirs);
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(dirs);
- std::string exportDirs = cge->Evaluate(target->GetMakefile(), 0,
+ std::string exportDirs = cge->Evaluate(target->GetLocalGenerator(), "",
false, target);
if (cge->GetHadContextSensitiveCondition())
{
- cmMakefile* mf = target->GetMakefile();
- cmOStringStream e;
+ cmLocalGenerator* lg = target->GetLocalGenerator();
+ std::ostringstream e;
e << "Target \"" << target->GetName() << "\" is installed with "
"INCLUDES DESTINATION set to a context sensitive path. Paths which "
"depend on the configuration, policy values or the link interface are "
"not supported. Consider using target_include_directories instead.";
- mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ lg->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
@@ -324,6 +477,8 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
return;
}
+ prefixItems(exportDirs);
+
std::string includes = (input?input:"");
const char* sep = input ? ";" : "";
includes += sep + exportDirs;
@@ -335,7 +490,7 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
this->ResolveTargetsInGeneratorExpressions(prepro, target,
missingTargets);
- if (!checkInterfaceDirs(prepro, target))
+ if (!checkInterfaceDirs(prepro, target, propName))
{
return;
}
@@ -344,8 +499,9 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
}
//----------------------------------------------------------------------------
-void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName,
- cmTarget *target,
+void cmExportFileGenerator::PopulateInterfaceProperty(
+ const std::string& propName,
+ cmGeneratorTarget* target,
cmGeneratorExpression::PreprocessContext preprocessRule,
ImportPropertyMap &properties,
std::vector<std::string> &missingTargets)
@@ -356,8 +512,9 @@ void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName,
//----------------------------------------------------------------------------
-void getPropertyContents(cmTarget *tgt, const char *prop,
- std::set<std::string> &ifaceProperties)
+void getPropertyContents(cmGeneratorTarget const* tgt,
+ const std::string& prop,
+ std::set<std::string> &ifaceProperties)
{
const char *p = tgt->GetProperty(prop);
if (!p)
@@ -366,27 +523,23 @@ void getPropertyContents(cmTarget *tgt, const char *prop,
}
std::vector<std::string> content;
cmSystemTools::ExpandListArgument(p, content);
- for (std::vector<std::string>::const_iterator ci = content.begin();
- ci != content.end(); ++ci)
- {
- ifaceProperties.insert(*ci);
- }
+ ifaceProperties.insert(content.begin(), content.end());
}
//----------------------------------------------------------------------------
-void getCompatibleInterfaceProperties(cmTarget *target,
+void getCompatibleInterfaceProperties(cmGeneratorTarget *target,
std::set<std::string> &ifaceProperties,
- const char *config)
+ const std::string& config)
{
cmComputeLinkInformation *info = target->GetLinkInformation(config);
if (!info)
{
- cmMakefile* mf = target->GetMakefile();
- cmOStringStream e;
+ cmLocalGenerator* lg = target->GetLocalGenerator();
+ std::ostringstream e;
e << "Exporting the target \"" << target->GetName() << "\" is not "
- "allowed since its linker language cannot be determined";
- mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ "allowed since its linker language cannot be determined";
+ lg->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
@@ -406,45 +559,63 @@ void getCompatibleInterfaceProperties(cmTarget *target,
getPropertyContents(li->Target,
"COMPATIBLE_INTERFACE_STRING",
ifaceProperties);
+ getPropertyContents(li->Target,
+ "COMPATIBLE_INTERFACE_NUMBER_MIN",
+ ifaceProperties);
+ getPropertyContents(li->Target,
+ "COMPATIBLE_INTERFACE_NUMBER_MAX",
+ ifaceProperties);
}
}
//----------------------------------------------------------------------------
void cmExportFileGenerator::PopulateCompatibleInterfaceProperties(
- cmTarget *target,
+ cmGeneratorTarget *gtarget,
ImportPropertyMap &properties)
{
this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_BOOL",
- target, properties);
+ gtarget, properties);
this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_STRING",
- target, properties);
+ gtarget, properties);
+ this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_NUMBER_MIN",
+ gtarget, properties);
+ this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_NUMBER_MAX",
+ gtarget, properties);
std::set<std::string> ifaceProperties;
- getPropertyContents(target, "COMPATIBLE_INTERFACE_BOOL", ifaceProperties);
- getPropertyContents(target, "COMPATIBLE_INTERFACE_STRING", ifaceProperties);
+ getPropertyContents(gtarget, "COMPATIBLE_INTERFACE_BOOL", ifaceProperties);
+ getPropertyContents(gtarget, "COMPATIBLE_INTERFACE_STRING", ifaceProperties);
+ getPropertyContents(gtarget, "COMPATIBLE_INTERFACE_NUMBER_MIN",
+ ifaceProperties);
+ getPropertyContents(gtarget, "COMPATIBLE_INTERFACE_NUMBER_MAX",
+ ifaceProperties);
- getCompatibleInterfaceProperties(target, ifaceProperties, 0);
+ if (gtarget->GetType() != cmState::INTERFACE_LIBRARY)
+ {
+ getCompatibleInterfaceProperties(gtarget, ifaceProperties, "");
- std::vector<std::string> configNames;
- target->GetMakefile()->GetConfigurations(configNames);
+ std::vector<std::string> configNames;
+ gtarget->Target->GetMakefile()->GetConfigurations(configNames);
- for (std::vector<std::string>::const_iterator ci = configNames.begin();
- ci != configNames.end(); ++ci)
- {
- getCompatibleInterfaceProperties(target, ifaceProperties, ci->c_str());
+ for (std::vector<std::string>::const_iterator ci = configNames.begin();
+ ci != configNames.end(); ++ci)
+ {
+ getCompatibleInterfaceProperties(gtarget, ifaceProperties, *ci);
+ }
}
for (std::set<std::string>::const_iterator it = ifaceProperties.begin();
it != ifaceProperties.end(); ++it)
{
- this->PopulateInterfaceProperty(("INTERFACE_" + *it).c_str(),
- target, properties);
+ this->PopulateInterfaceProperty("INTERFACE_" + *it,
+ gtarget, properties);
}
}
//----------------------------------------------------------------------------
-void cmExportFileGenerator::GenerateInterfaceProperties(cmTarget *target,
+void cmExportFileGenerator::GenerateInterfaceProperties(
+ const cmGeneratorTarget* target,
std::ostream& os,
const ImportPropertyMap &properties)
{
@@ -456,7 +627,8 @@ void cmExportFileGenerator::GenerateInterfaceProperties(cmTarget *target,
for(ImportPropertyMap::const_iterator pi = properties.begin();
pi != properties.end(); ++pi)
{
- os << " " << pi->first << " \"" << pi->second << "\"\n";
+ os << " " << pi->first << " "
+ << cmExportFileGeneratorEscape(pi->second) << "\n";
}
os << ")\n\n";
}
@@ -465,12 +637,12 @@ void cmExportFileGenerator::GenerateInterfaceProperties(cmTarget *target,
//----------------------------------------------------------------------------
bool
cmExportFileGenerator::AddTargetNamespace(std::string &input,
- cmTarget* target,
+ cmGeneratorTarget* target,
std::vector<std::string> &missingTargets)
{
- cmMakefile *mf = target->GetMakefile();
+ cmLocalGenerator *lg = target->GetLocalGenerator();
- cmTarget *tgt = mf->FindTargetToUse(input.c_str());
+ cmGeneratorTarget *tgt = lg->FindGeneratorTargetToUse(input);
if (!tgt)
{
return false;
@@ -488,7 +660,7 @@ cmExportFileGenerator::AddTargetNamespace(std::string &input,
{
std::string namespacedTarget;
this->HandleMissingTarget(namespacedTarget, missingTargets,
- mf, target, tgt);
+ target, tgt);
if (!namespacedTarget.empty())
{
input = namespacedTarget;
@@ -501,7 +673,7 @@ cmExportFileGenerator::AddTargetNamespace(std::string &input,
void
cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
std::string &input,
- cmTarget* target,
+ cmGeneratorTarget* target,
std::vector<std::string> &missingTargets,
FreeTargetsReplace replace)
{
@@ -538,14 +710,12 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
void
cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
std::string &input,
- cmTarget* target,
+ cmGeneratorTarget* target,
std::vector<std::string> &missingTargets)
{
std::string::size_type pos = 0;
std::string::size_type lastPos = pos;
- cmMakefile *mf = target->GetMakefile();
-
while((pos = input.find("$<TARGET_PROPERTY:", lastPos)) != input.npos)
{
std::string::size_type nameStartPos = pos +
@@ -602,11 +772,32 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
lastPos = endPos;
}
+ pos = 0;
+ lastPos = pos;
+ while (errorString.empty() &&
+ (pos = input.find("$<LINK_ONLY:", lastPos)) != input.npos)
+ {
+ std::string::size_type nameStartPos = pos + sizeof("$<LINK_ONLY:") - 1;
+ std::string::size_type endPos = input.find(">", nameStartPos);
+ if (endPos == input.npos)
+ {
+ errorString = "$<LINK_ONLY:...> expression incomplete";
+ break;
+ }
+ std::string libName = input.substr(nameStartPos, endPos - nameStartPos);
+ if (cmGeneratorExpression::IsValidTargetName(libName) &&
+ this->AddTargetNamespace(libName, target, missingTargets))
+ {
+ input.replace(nameStartPos, endPos - nameStartPos, libName);
+ }
+ lastPos = nameStartPos + libName.size() + 1;
+ }
+
this->ReplaceInstallPrefix(input);
if (!errorString.empty())
{
- mf->IssueMessage(cmake::FATAL_ERROR, errorString);
+ target->GetLocalGenerator()->IssueMessage(cmake::FATAL_ERROR, errorString);
}
}
@@ -620,14 +811,14 @@ cmExportFileGenerator::ReplaceInstallPrefix(std::string &)
//----------------------------------------------------------------------------
void
cmExportFileGenerator
-::SetImportLinkInterface(const char* config, std::string const& suffix,
+::SetImportLinkInterface(const std::string& config, std::string const& suffix,
cmGeneratorExpression::PreprocessContext preprocessRule,
- cmTarget* target, ImportPropertyMap& properties,
+ cmGeneratorTarget* target, ImportPropertyMap& properties,
std::vector<std::string>& missingTargets)
{
// Add the transitive link dependencies for this configuration.
- cmTarget::LinkInterface const* iface = target->GetLinkInterface(config,
- target);
+ cmLinkInterface const* iface = target->GetLinkInterface(config,
+ target);
if (!iface)
{
return;
@@ -645,7 +836,7 @@ cmExportFileGenerator
const char *propContent;
if (const char *prop_suffixed = target->GetProperty(
- ("LINK_INTERFACE_LIBRARIES" + suffix).c_str()))
+ "LINK_INTERFACE_LIBRARIES" + suffix))
{
propContent = prop_suffixed;
}
@@ -665,13 +856,13 @@ cmExportFileGenerator
if(newCMP0022Behavior && !this->ExportOld)
{
- cmMakefile *mf = target->GetMakefile();
- cmOStringStream e;
+ cmLocalGenerator *lg = target->GetLocalGenerator();
+ std::ostringstream e;
e << "Target \"" << target->GetName() << "\" has policy CMP0022 enabled, "
"but also has old-style LINK_INTERFACE_LIBRARIES properties "
"populated, but it was exported without the "
"EXPORT_LINK_INTERFACE_LIBRARIES to export the old-style properties";
- mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ lg->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
@@ -695,22 +886,21 @@ cmExportFileGenerator
//----------------------------------------------------------------------------
void
cmExportFileGenerator
-::SetImportDetailProperties(const char* config, std::string const& suffix,
- cmTarget* target, ImportPropertyMap& properties,
+::SetImportDetailProperties(const std::string& config,
+ std::string const& suffix,
+ cmGeneratorTarget* target,
+ ImportPropertyMap& properties,
std::vector<std::string>& missingTargets
)
{
// Get the makefile in which to lookup target information.
- cmMakefile* mf = target->GetMakefile();
+ cmMakefile* mf = target->Makefile;
// Add the soname for unix shared libraries.
- if(target->GetType() == cmTarget::SHARED_LIBRARY ||
- target->GetType() == cmTarget::MODULE_LIBRARY)
+ if(target->GetType() == cmState::SHARED_LIBRARY ||
+ target->GetType() == cmState::MODULE_LIBRARY)
{
- // Check whether this is a DLL platform.
- bool dll_platform =
- (mf->IsOn("WIN32") || mf->IsOn("CYGWIN") || mf->IsOn("MINGW"));
- if(!dll_platform)
+ if(!target->IsDLLPlatform())
{
std::string prop;
std::string value;
@@ -734,21 +924,22 @@ cmExportFileGenerator
}
// Add the transitive link dependencies for this configuration.
- if(cmTarget::LinkInterface const* iface = target->GetLinkInterface(config,
- target))
+ if(cmLinkInterface const* iface =
+ target->GetLinkInterface(config, target))
{
this->SetImportLinkProperty(suffix, target,
"IMPORTED_LINK_INTERFACE_LANGUAGES",
iface->Languages, properties, missingTargets);
+ std::vector<std::string> dummy;
this->SetImportLinkProperty(suffix, target,
"IMPORTED_LINK_DEPENDENT_LIBRARIES",
- iface->SharedDeps, properties, missingTargets);
+ iface->SharedDeps, properties, dummy);
if(iface->Multiplicity > 0)
{
std::string prop = "IMPORTED_LINK_INTERFACE_MULTIPLICITY";
prop += suffix;
- cmOStringStream m;
+ std::ostringstream m;
m << iface->Multiplicity;
properties[prop] = m.str();
}
@@ -756,51 +947,51 @@ cmExportFileGenerator
}
//----------------------------------------------------------------------------
+template <typename T>
void
cmExportFileGenerator
::SetImportLinkProperty(std::string const& suffix,
- cmTarget* target,
- const char* propName,
- std::vector<std::string> const& libs,
+ cmGeneratorTarget* target,
+ const std::string& propName,
+ std::vector<T> const& entries,
ImportPropertyMap& properties,
std::vector<std::string>& missingTargets
- )
+ )
{
- // Skip the property if there are no libraries.
- if(libs.empty())
+ // Skip the property if there are no entries.
+ if(entries.empty())
{
return;
}
// Construct the property value.
- std::string link_libs;
+ std::string link_entries;
const char* sep = "";
- for(std::vector<std::string>::const_iterator li = libs.begin();
- li != libs.end(); ++li)
+ for(typename std::vector<T>::const_iterator li = entries.begin();
+ li != entries.end(); ++li)
{
// Separate this from the previous entry.
- link_libs += sep;
+ link_entries += sep;
sep = ";";
std::string temp = *li;
this->AddTargetNamespace(temp, target, missingTargets);
- link_libs += temp;
+ link_entries += temp;
}
// Store the property.
std::string prop = propName;
prop += suffix;
- properties[prop] = link_libs;
+ properties[prop] = link_entries;
}
-
//----------------------------------------------------------------------------
void cmExportFileGenerator::GenerateImportHeaderCode(std::ostream& os,
- const char* config)
+ const std::string& config)
{
os << "#----------------------------------------------------------------\n"
<< "# Generated CMake target import file";
- if(config)
+ if(!config.empty())
{
os << " for configuration \"" << config << "\".\n";
}
@@ -866,7 +1057,7 @@ void cmExportFileGenerator::GenerateExpectedTargetsCode(std::ostream& os,
//----------------------------------------------------------------------------
void
cmExportFileGenerator
-::GenerateImportTargetCode(std::ostream& os, cmTarget* target)
+::GenerateImportTargetCode(std::ostream& os, const cmGeneratorTarget* target)
{
// Construct the imported target name.
std::string targetName = this->Namespace;
@@ -877,21 +1068,24 @@ cmExportFileGenerator
os << "# Create imported target " << targetName << "\n";
switch(target->GetType())
{
- case cmTarget::EXECUTABLE:
+ case cmState::EXECUTABLE:
os << "add_executable(" << targetName << " IMPORTED)\n";
break;
- case cmTarget::STATIC_LIBRARY:
+ case cmState::STATIC_LIBRARY:
os << "add_library(" << targetName << " STATIC IMPORTED)\n";
break;
- case cmTarget::SHARED_LIBRARY:
+ case cmState::SHARED_LIBRARY:
os << "add_library(" << targetName << " SHARED IMPORTED)\n";
break;
- case cmTarget::MODULE_LIBRARY:
+ case cmState::MODULE_LIBRARY:
os << "add_library(" << targetName << " MODULE IMPORTED)\n";
break;
- case cmTarget::UNKNOWN_LIBRARY:
+ case cmState::UNKNOWN_LIBRARY:
os << "add_library(" << targetName << " UNKNOWN IMPORTED)\n";
break;
+ case cmState::INTERFACE_LIBRARY:
+ os << "add_library(" << targetName << " INTERFACE IMPORTED)\n";
+ break;
default: // should never happen
break;
}
@@ -928,8 +1122,8 @@ cmExportFileGenerator
//----------------------------------------------------------------------------
void
cmExportFileGenerator
-::GenerateImportPropertyCode(std::ostream& os, const char* config,
- cmTarget* target,
+::GenerateImportPropertyCode(std::ostream& os, const std::string& config,
+ cmGeneratorTarget const* target,
ImportPropertyMap const& properties)
{
// Construct the imported target name.
@@ -942,7 +1136,7 @@ cmExportFileGenerator
<< config << "\"\n";
os << "set_property(TARGET " << targetName
<< " APPEND PROPERTY IMPORTED_CONFIGURATIONS ";
- if(config && *config)
+ if(!config.empty())
{
os << cmSystemTools::UpperCase(config);
}
@@ -955,7 +1149,8 @@ cmExportFileGenerator
for(ImportPropertyMap::const_iterator pi = properties.begin();
pi != properties.end(); ++pi)
{
- os << " " << pi->first << " \"" << pi->second << "\"\n";
+ os << " " << pi->first << " "
+ << cmExportFileGeneratorEscape(pi->second) << "\n";
}
os << " )\n"
<< "\n";
@@ -1048,7 +1243,7 @@ cmExportFileGenerator::GenerateImportedFileCheckLoop(std::ostream& os)
//----------------------------------------------------------------------------
void
cmExportFileGenerator
-::GenerateImportedFileChecksCode(std::ostream& os, cmTarget* target,
+::GenerateImportedFileChecksCode(std::ostream& os, cmGeneratorTarget* target,
ImportPropertyMap const& properties,
const std::set<std::string>& importedLocations)
{
@@ -1066,7 +1261,7 @@ cmExportFileGenerator
ImportPropertyMap::const_iterator pi = properties.find(*li);
if (pi != properties.end())
{
- os << "\"" << pi->second << "\" ";
+ os << cmExportFileGeneratorEscape(pi->second) << " ";
}
}
diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h
index 9628b9681..18f0b009a 100644
--- a/Source/cmExportFileGenerator.h
+++ b/Source/cmExportFileGenerator.h
@@ -15,6 +15,20 @@
#include "cmCommand.h"
#include "cmGeneratorExpression.h"
+#include "cmVersionMacros.h"
+#include "cmVersion.h"
+
+#define STRINGIFY_HELPER(X) #X
+#define STRINGIFY(X) STRINGIFY_HELPER(X)
+
+#define DEVEL_CMAKE_VERSION(major, minor) ( \
+ CMake_VERSION_ENCODE(major, minor, 0) > \
+ CMake_VERSION_ENCODE(CMake_VERSION_MAJOR, CMake_VERSION_MINOR, 0) ? \
+ STRINGIFY(CMake_VERSION_MAJOR) "." STRINGIFY(CMake_VERSION_MINOR) "." \
+ STRINGIFY(CMake_VERSION_PATCH) \
+ : #major "." #minor ".0" \
+ )
+
class cmTargetExport;
/** \class cmExportFileGenerator
@@ -33,36 +47,41 @@ public:
/** Set the full path to the export file to generate. */
void SetExportFile(const char* mainFile);
+ const char *GetMainExportFileName() const;
/** Set the namespace in which to place exported target names. */
- void SetNamespace(const char* ns) { this->Namespace = ns; }
+ void SetNamespace(const std::string& ns) { this->Namespace = ns; }
+ std::string GetNamespace() const { return this->Namespace; }
void SetExportOld(bool exportOld) { this->ExportOld = exportOld; }
/** Add a configuration to be exported. */
- void AddConfiguration(const char* config);
+ void AddConfiguration(const std::string& config);
/** Actually generate the export file. Returns whether there was an
error. */
bool GenerateImportFile();
protected:
- typedef std::map<cmStdString, cmStdString> ImportPropertyMap;
+ typedef std::map<std::string, std::string> ImportPropertyMap;
// Generate per-configuration target information to the given output
// stream.
- void GenerateImportConfig(std::ostream& os, const char* config,
+ void GenerateImportConfig(std::ostream& os, const std::string& config,
std::vector<std::string> &missingTargets);
// Methods to implement export file code generation.
- void GenerateImportHeaderCode(std::ostream& os, const char* config = 0);
+ void GenerateImportHeaderCode(std::ostream& os,
+ const std::string& config = "");
void GenerateImportFooterCode(std::ostream& os);
void GenerateImportVersionCode(std::ostream& os);
- void GenerateImportTargetCode(std::ostream& os, cmTarget* target);
- void GenerateImportPropertyCode(std::ostream& os, const char* config,
- cmTarget* target,
+ void GenerateImportTargetCode(std::ostream& os,
+ cmGeneratorTarget const* target);
+ void GenerateImportPropertyCode(std::ostream& os, const std::string& config,
+ cmGeneratorTarget const* target,
ImportPropertyMap const& properties);
- void GenerateImportedFileChecksCode(std::ostream& os, cmTarget* target,
+ void GenerateImportedFileChecksCode(std::ostream& os,
+ cmGeneratorTarget* target,
ImportPropertyMap const& properties,
const std::set<std::string>& importedLocations);
void GenerateImportedFileCheckLoop(std::ostream& os);
@@ -74,13 +93,17 @@ protected:
// Collect properties with detailed information about targets beyond
// their location on disk.
- void SetImportDetailProperties(const char* config,
- std::string const& suffix, cmTarget* target,
+ void SetImportDetailProperties(const std::string& config,
+ std::string const& suffix,
+ cmGeneratorTarget* target,
ImportPropertyMap& properties,
std::vector<std::string>& missingTargets);
+
+ template <typename T>
void SetImportLinkProperty(std::string const& suffix,
- cmTarget* target, const char* propName,
- std::vector<std::string> const& libs,
+ cmGeneratorTarget* target,
+ const std::string& propName,
+ std::vector<T> const& entries,
ImportPropertyMap& properties,
std::vector<std::string>& missingTargets);
@@ -89,7 +112,7 @@ protected:
/** Each subclass knows where the target files are located. */
virtual void GenerateImportTargetsConfig(std::ostream& os,
- const char* config,
+ const std::string& config,
std::string const& suffix,
std::vector<std::string> &missingTargets) = 0;
@@ -97,33 +120,40 @@ protected:
* export set. */
virtual void HandleMissingTarget(std::string& link_libs,
std::vector<std::string>& missingTargets,
- cmMakefile* mf,
- cmTarget* depender,
- cmTarget* dependee) = 0;
- void PopulateInterfaceProperty(const char *,
- cmTarget *target,
+ cmGeneratorTarget* depender,
+ cmGeneratorTarget* dependee) = 0;
+ void PopulateInterfaceProperty(const std::string&,
+ cmGeneratorTarget *target,
cmGeneratorExpression::PreprocessContext,
ImportPropertyMap &properties,
std::vector<std::string> &missingTargets);
- bool PopulateInterfaceLinkLibrariesProperty(cmTarget *target,
+ bool PopulateInterfaceLinkLibrariesProperty(cmGeneratorTarget* target,
cmGeneratorExpression::PreprocessContext,
ImportPropertyMap &properties,
std::vector<std::string> &missingTargets);
- void PopulateInterfaceProperty(const char *propName, cmTarget *target,
+ void PopulateInterfaceProperty(const std::string& propName,
+ cmGeneratorTarget* target,
ImportPropertyMap &properties);
- void PopulateCompatibleInterfaceProperties(cmTarget *target,
+ void PopulateCompatibleInterfaceProperties(cmGeneratorTarget *target,
ImportPropertyMap &properties);
- void GenerateInterfaceProperties(cmTarget *target, std::ostream& os,
+ void GenerateInterfaceProperties(cmGeneratorTarget const* target,
+ std::ostream& os,
const ImportPropertyMap &properties);
void PopulateIncludeDirectoriesInterface(
cmTargetExport *target,
cmGeneratorExpression::PreprocessContext preprocessRule,
ImportPropertyMap &properties,
std::vector<std::string> &missingTargets);
+ void PopulateSourcesInterface(
+ cmTargetExport *target,
+ cmGeneratorExpression::PreprocessContext preprocessRule,
+ ImportPropertyMap &properties,
+ std::vector<std::string> &missingTargets);
- void SetImportLinkInterface(const char* config, std::string const& suffix,
+ void SetImportLinkInterface(const std::string& config,
+ std::string const& suffix,
cmGeneratorExpression::PreprocessContext preprocessRule,
- cmTarget* target, ImportPropertyMap& properties,
+ cmGeneratorTarget* target, ImportPropertyMap& properties,
std::vector<std::string>& missingTargets);
enum FreeTargetsReplace {
@@ -132,7 +162,7 @@ protected:
};
void ResolveTargetsInGeneratorExpressions(std::string &input,
- cmTarget* target,
+ cmGeneratorTarget* target,
std::vector<std::string> &missingTargets,
FreeTargetsReplace replace = NoReplaceFreeTargets);
@@ -155,25 +185,25 @@ protected:
bool AppendMode;
// The set of targets included in the export.
- std::set<cmTarget*> ExportedTargets;
+ std::set<cmGeneratorTarget*> ExportedTargets;
private:
- void PopulateInterfaceProperty(const char *, const char *,
- cmTarget *target,
+ void PopulateInterfaceProperty(const std::string&, const std::string&,
+ cmGeneratorTarget* target,
cmGeneratorExpression::PreprocessContext,
ImportPropertyMap &properties,
std::vector<std::string> &missingTargets);
- bool AddTargetNamespace(std::string &input, cmTarget* target,
+ bool AddTargetNamespace(std::string &input, cmGeneratorTarget* target,
std::vector<std::string> &missingTargets);
void ResolveTargetsInGeneratorExpression(std::string &input,
- cmTarget* target,
+ cmGeneratorTarget* target,
std::vector<std::string> &missingTargets);
virtual void ReplaceInstallPrefix(std::string &input);
- virtual std::string InstallNameDir(cmTarget* target,
+ virtual std::string InstallNameDir(cmGeneratorTarget* target,
const std::string& config) = 0;
};
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index c8b4a7985..71418e825 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -19,6 +19,7 @@
#include "cmInstallExportGenerator.h"
#include "cmInstallTargetGenerator.h"
#include "cmTargetExport.h"
+#include "cmAlgorithms.h"
//----------------------------------------------------------------------------
cmExportInstallFileGenerator
@@ -47,7 +48,8 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
tei = this->IEGen->GetExportSet()->GetTargetExports()->begin();
tei != this->IEGen->GetExportSet()->GetTargetExports()->end(); ++tei)
{
- expectedTargets += sep + this->Namespace + (*tei)->Target->GetExportName();
+ expectedTargets +=
+ sep + this->Namespace + (*tei)->Target->GetExportName();
sep = " ";
cmTargetExport * te = *tei;
if(this->ExportedTargets.insert(te->Target).second)
@@ -56,7 +58,7 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "install(EXPORT \""
<< this->IEGen->GetExportSet()->GetName()
<< "\" ...) " << "includes target \"" << te->Target->GetName()
@@ -69,22 +71,33 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
this->GenerateExpectedTargetsCode(os, expectedTargets);
}
- // Add code to compute the installation prefix relative to the
- // import file location.
- const char* installDest = this->IEGen->GetDestination();
- if(!cmSystemTools::FileIsFullPath(installDest))
+ // Set an _IMPORT_PREFIX variable for import location properties
+ // to reference if they are relative to the install prefix.
+ std::string installPrefix = this->IEGen->GetLocalGenerator()
+ ->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
+ std::string const& expDest = this->IEGen->GetDestination();
+ if(cmSystemTools::FileIsFullPath(expDest))
{
- std::string installPrefix =
- this->IEGen->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
- std::string absDest = installPrefix + "/" + installDest;
+ // The export file is being installed to an absolute path so the
+ // package is not relocatable. Use the configured install prefix.
+ os <<
+ "# The installation prefix configured by this project.\n"
+ "set(_IMPORT_PREFIX \"" << installPrefix << "\")\n"
+ "\n";
+ }
+ else
+ {
+ // Add code to compute the installation prefix relative to the
+ // import file location.
+ std::string absDest = installPrefix + "/" + expDest;
std::string absDestS = absDest + "/";
os << "# Compute the installation prefix relative to this file.\n"
<< "get_filename_component(_IMPORT_PREFIX"
<< " \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n";
- if(strncmp(absDestS.c_str(), "/lib/", 5) == 0 ||
- strncmp(absDestS.c_str(), "/lib64/", 7) == 0 ||
- strncmp(absDestS.c_str(), "/usr/lib/", 9) == 0 ||
- strncmp(absDestS.c_str(), "/usr/lib64/", 11) == 0)
+ if(cmHasLiteralPrefix(absDestS.c_str(), "/lib/") ||
+ cmHasLiteralPrefix(absDestS.c_str(), "/lib64/") ||
+ cmHasLiteralPrefix(absDestS.c_str(), "/usr/lib/") ||
+ cmHasLiteralPrefix(absDestS.c_str(), "/usr/lib64/"))
{
// Handle "/usr move" symlinks created by some Linux distros.
os <<
@@ -98,7 +111,7 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
"unset(_realOrig)\n"
"unset(_realCurr)\n";
}
- std::string dest = installDest;
+ std::string dest = expDest;
while(!dest.empty())
{
os <<
@@ -106,46 +119,61 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
dest = cmSystemTools::GetFilenamePath(dest);
}
os << "\n";
-
- // Import location properties may reference this variable.
- this->ImportPrefix = "${_IMPORT_PREFIX}/";
}
std::vector<std::string> missingTargets;
bool require2_8_12 = false;
+ bool require3_0_0 = false;
+ bool require3_1_0 = false;
+ bool requiresConfigFiles = false;
// Create all the imported targets.
for(std::vector<cmTargetExport*>::const_iterator
tei = allTargets.begin();
tei != allTargets.end(); ++tei)
{
- cmTarget* te = (*tei)->Target;
- this->GenerateImportTargetCode(os, te);
+ cmGeneratorTarget* gt = (*tei)->Target;
+
+ requiresConfigFiles = requiresConfigFiles
+ || gt->GetType() != cmState::INTERFACE_LIBRARY;
+
+ this->GenerateImportTargetCode(os, gt);
ImportPropertyMap properties;
this->PopulateIncludeDirectoriesInterface(*tei,
cmGeneratorExpression::InstallInterface,
properties, missingTargets);
+ this->PopulateSourcesInterface(*tei,
+ cmGeneratorExpression::InstallInterface,
+ properties, missingTargets);
this->PopulateInterfaceProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES",
- te,
+ gt,
cmGeneratorExpression::InstallInterface,
properties, missingTargets);
this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS",
- te,
+ gt,
cmGeneratorExpression::InstallInterface,
properties, missingTargets);
this->PopulateInterfaceProperty("INTERFACE_COMPILE_OPTIONS",
- te,
+ gt,
+ cmGeneratorExpression::InstallInterface,
+ properties, missingTargets);
+ this->PopulateInterfaceProperty("INTERFACE_AUTOUIC_OPTIONS",
+ gt,
+ cmGeneratorExpression::InstallInterface,
+ properties, missingTargets);
+ this->PopulateInterfaceProperty("INTERFACE_COMPILE_FEATURES",
+ gt,
cmGeneratorExpression::InstallInterface,
properties, missingTargets);
const bool newCMP0022Behavior =
- te->GetPolicyStatusCMP0022() != cmPolicies::WARN
- && te->GetPolicyStatusCMP0022() != cmPolicies::OLD;
+ gt->GetPolicyStatusCMP0022() != cmPolicies::WARN
+ && gt->GetPolicyStatusCMP0022() != cmPolicies::OLD;
if (newCMP0022Behavior)
{
- if (this->PopulateInterfaceLinkLibrariesProperty(te,
+ if (this->PopulateInterfaceLinkLibrariesProperty(gt,
cmGeneratorExpression::InstallInterface,
properties, missingTargets)
&& !this->ExportOld)
@@ -153,14 +181,34 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
require2_8_12 = true;
}
}
+ if (gt->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ require3_0_0 = true;
+ }
+ if(gt->GetProperty("INTERFACE_SOURCES"))
+ {
+ // We can only generate INTERFACE_SOURCES in CMake 3.3, but CMake 3.1
+ // can consume them.
+ require3_1_0 = true;
+ }
+
this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE",
- te, properties);
- this->PopulateCompatibleInterfaceProperties(te, properties);
+ gt, properties);
+
+ this->PopulateCompatibleInterfaceProperties(gt, properties);
- this->GenerateInterfaceProperties(te, os, properties);
+ this->GenerateInterfaceProperties(gt, os, properties);
}
- if (require2_8_12)
+ if (require3_1_0)
+ {
+ this->GenerateRequiredCMakeVersion(os, "3.1.0");
+ }
+ else if (require3_0_0)
+ {
+ this->GenerateRequiredCMakeVersion(os, "3.0.0");
+ }
+ else if (require2_8_12)
{
this->GenerateRequiredCMakeVersion(os, "2.8.12");
}
@@ -176,23 +224,24 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
<< "\n";
// Cleanup the import prefix variable.
- if(!this->ImportPrefix.empty())
- {
- os << "# Cleanup temporary variables.\n"
- << "set(_IMPORT_PREFIX)\n"
- << "\n";
- }
+ os << "# Cleanup temporary variables.\n"
+ << "set(_IMPORT_PREFIX)\n"
+ << "\n";
this->GenerateImportedFileCheckLoop(os);
- // Generate an import file for each configuration.
bool result = true;
- for(std::vector<std::string>::const_iterator
- ci = this->Configurations.begin();
- ci != this->Configurations.end(); ++ci)
+ // Generate an import file for each configuration.
+ // Don't do this if we only export INTERFACE_LIBRARY targets.
+ if (requiresConfigFiles)
{
- if(!this->GenerateImportFileConfig(ci->c_str(), missingTargets))
+ for(std::vector<std::string>::const_iterator
+ ci = this->Configurations.begin();
+ ci != this->Configurations.end(); ++ci)
{
- result = false;
+ if(!this->GenerateImportFileConfig(*ci, missingTargets))
+ {
+ result = false;
+ }
}
}
@@ -218,7 +267,8 @@ cmExportInstallFileGenerator::ReplaceInstallPrefix(std::string &input)
//----------------------------------------------------------------------------
bool
-cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config,
+cmExportInstallFileGenerator::GenerateImportFileConfig(
+ const std::string& config,
std::vector<std::string> &missingTargets)
{
// Skip configurations not enabled for this export.
@@ -232,7 +282,7 @@ cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config,
fileName += "/";
fileName += this->FileBase;
fileName += "-";
- if(config && *config)
+ if(!config.empty())
{
fileName += cmSystemTools::LowerCase(config);
}
@@ -247,8 +297,8 @@ cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config,
if(!exportFileStream)
{
std::string se = cmSystemTools::GetLastSystemError();
- cmOStringStream e;
- e << "cannot write to file \"" << fileName.c_str()
+ std::ostringstream e;
+ e << "cannot write to file \"" << fileName
<< "\": " << se;
cmSystemTools::Error(e.str().c_str());
return false;
@@ -274,7 +324,8 @@ cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config,
void
cmExportInstallFileGenerator
::GenerateImportTargetsConfig(std::ostream& os,
- const char* config, std::string const& suffix,
+ const std::string& config,
+ std::string const& suffix,
std::vector<std::string> &missingTargets)
{
// Add each target in the set to the export.
@@ -284,8 +335,14 @@ cmExportInstallFileGenerator
{
// Collect import properties for this target.
cmTargetExport const* te = *tei;
+ if (te->Target->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ continue;
+ }
+
ImportPropertyMap properties;
std::set<std::string> importedLocations;
+
this->SetImportLocationProperty(config, suffix, te->ArchiveGenerator,
properties, importedLocations);
this->SetImportLocationProperty(config, suffix, te->LibraryGenerator,
@@ -303,12 +360,13 @@ cmExportInstallFileGenerator
if(!properties.empty())
{
// Get the rest of the target details.
+ cmGeneratorTarget *gtgt = te->Target;
this->SetImportDetailProperties(config, suffix,
- te->Target, properties, missingTargets);
+ gtgt, properties, missingTargets);
this->SetImportLinkInterface(config, suffix,
cmGeneratorExpression::InstallInterface,
- te->Target, properties, missingTargets);
+ gtgt, properties, missingTargets);
// TOOD: PUBLIC_HEADER_LOCATION
// This should wait until the build feature propagation stuff
@@ -317,8 +375,8 @@ cmExportInstallFileGenerator
// properties);
// Generate code in the export file.
- this->GenerateImportPropertyCode(os, config, te->Target, properties);
- this->GenerateImportedFileChecksCode(os, te->Target, properties,
+ this->GenerateImportPropertyCode(os, config, gtgt, properties);
+ this->GenerateImportedFileChecksCode(os, gtgt, properties,
importedLocations);
}
}
@@ -327,7 +385,8 @@ cmExportInstallFileGenerator
//----------------------------------------------------------------------------
void
cmExportInstallFileGenerator
-::SetImportLocationProperty(const char* config, std::string const& suffix,
+::SetImportLocationProperty(const std::string& config,
+ std::string const& suffix,
cmInstallTargetGenerator* itgen,
ImportPropertyMap& properties,
std::set<std::string>& importedLocations
@@ -340,19 +399,15 @@ cmExportInstallFileGenerator
}
// Get the target to be installed.
- cmTarget* target = itgen->GetTarget();
+ cmGeneratorTarget* target = itgen->GetTarget();
// Construct the installed location of the target.
- std::string dest = itgen->GetDestination();
+ std::string dest = itgen->GetDestination(config);
std::string value;
if(!cmSystemTools::FileIsFullPath(dest.c_str()))
{
// The target is installed relative to the installation prefix.
- if(this->ImportPrefix.empty())
- {
- this->ComplainAboutImportPrefix(itgen);
- }
- value = this->ImportPrefix;
+ value = "${_IMPORT_PREFIX}/";
}
value += dest;
value += "/";
@@ -398,12 +453,13 @@ cmExportInstallFileGenerator
//----------------------------------------------------------------------------
void
-cmExportInstallFileGenerator::HandleMissingTarget(
- std::string& link_libs, std::vector<std::string>& missingTargets,
- cmMakefile* mf, cmTarget* depender, cmTarget* dependee)
+cmExportInstallFileGenerator::HandleMissingTarget(std::string& link_libs,
+ std::vector<std::string>& missingTargets,
+ cmGeneratorTarget* depender, cmGeneratorTarget* dependee)
{
const std::string name = dependee->GetName();
- std::vector<std::string> namespaces = this->FindNamespaces(mf, name);
+ cmGlobalGenerator* gg = dependee->GetLocalGenerator()->GetGlobalGenerator();
+ std::vector<std::string> namespaces = this->FindNamespaces(gg, name);
int targetOccurrences = (int)namespaces.size();
if (targetOccurrences == 1)
{
@@ -415,8 +471,8 @@ cmExportInstallFileGenerator::HandleMissingTarget(
}
else
{
- // We are not appending, so all exported targets should be
- // known here. This is probably user-error.
+ // All exported targets should be known here and should be unique.
+ // This is probably user-error.
this->ComplainAboutMissingTarget(depender, dependee, targetOccurrences);
}
}
@@ -424,10 +480,9 @@ cmExportInstallFileGenerator::HandleMissingTarget(
//----------------------------------------------------------------------------
std::vector<std::string>
cmExportInstallFileGenerator
-::FindNamespaces(cmMakefile* mf, const std::string& name)
+::FindNamespaces(cmGlobalGenerator* gg, const std::string& name)
{
std::vector<std::string> namespaces;
- cmGlobalGenerator* gg = mf->GetLocalGenerator()->GetGlobalGenerator();
const cmExportSetMap& exportSets = gg->GetExportSets();
for(cmExportSetMap::const_iterator expIt = exportSets.begin();
@@ -441,7 +496,7 @@ cmExportInstallFileGenerator
bool containsTarget = false;
for(unsigned int i=0; i<targets->size(); i++)
{
- if (name == (*targets)[i]->Target->GetName())
+ if (name == (*targets)[i]->TargetName)
{
containsTarget = true;
break;
@@ -462,32 +517,14 @@ cmExportInstallFileGenerator
return namespaces;
}
-
-//----------------------------------------------------------------------------
-void
-cmExportInstallFileGenerator
-::ComplainAboutImportPrefix(cmInstallTargetGenerator* itgen)
-{
- const char* installDest = this->IEGen->GetDestination();
- cmOStringStream e;
- e << "install(EXPORT \""
- << this->IEGen->GetExportSet()->GetName()
- << "\") given absolute "
- << "DESTINATION \"" << installDest << "\" but the export "
- << "references an installation of target \""
- << itgen->GetTarget()->GetName() << "\" which has relative "
- << "DESTINATION \"" << itgen->GetDestination() << "\".";
- cmSystemTools::Error(e.str().c_str());
-}
-
//----------------------------------------------------------------------------
void
cmExportInstallFileGenerator
-::ComplainAboutMissingTarget(cmTarget* depender,
- cmTarget* dependee,
+::ComplainAboutMissingTarget(cmGeneratorTarget* depender,
+ cmGeneratorTarget* dependee,
int occurrences)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "install(EXPORT \""
<< this->IEGen->GetExportSet()->GetName()
<< "\" ...) "
@@ -506,12 +543,12 @@ cmExportInstallFileGenerator
}
std::string
-cmExportInstallFileGenerator::InstallNameDir(cmTarget* target,
+cmExportInstallFileGenerator::InstallNameDir(cmGeneratorTarget* target,
const std::string&)
{
std::string install_name_dir;
- cmMakefile* mf = target->GetMakefile();
+ cmMakefile* mf = target->Target->GetMakefile();
if(mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
{
install_name_dir =
diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h
index 7c634a4d8..13dae8996 100644
--- a/Source/cmExportInstallFileGenerator.h
+++ b/Source/cmExportInstallFileGenerator.h
@@ -41,7 +41,7 @@ public:
/** Get the per-config file generated for each configuraiton. This
maps from the configuration name to the file temporary location
for installation. */
- std::map<cmStdString, cmStdString> const& GetConfigImportFiles()
+ std::map<std::string, std::string> const& GetConfigImportFiles()
{ return this->ConfigImportFiles; }
/** Compute the globbing expression used to load per-config import
@@ -52,47 +52,43 @@ protected:
// Implement virtual methods from the superclass.
virtual bool GenerateMainFile(std::ostream& os);
virtual void GenerateImportTargetsConfig(std::ostream& os,
- const char* config,
+ const std::string& config,
std::string const& suffix,
std::vector<std::string> &missingTargets);
virtual void HandleMissingTarget(std::string& link_libs,
std::vector<std::string>& missingTargets,
- cmMakefile* mf,
- cmTarget* depender,
- cmTarget* dependee);
+ cmGeneratorTarget* depender,
+ cmGeneratorTarget* dependee);
virtual void ReplaceInstallPrefix(std::string &input);
- void ComplainAboutMissingTarget(cmTarget* depender,
- cmTarget* dependee,
+ void ComplainAboutMissingTarget(cmGeneratorTarget* depender,
+ cmGeneratorTarget* dependee,
int occurrences);
- std::vector<std::string> FindNamespaces(cmMakefile* mf,
+ std::vector<std::string> FindNamespaces(cmGlobalGenerator* gg,
const std::string& name);
/** Generate a per-configuration file for the targets. */
- bool GenerateImportFileConfig(const char* config,
+ bool GenerateImportFileConfig(const std::string& config,
std::vector<std::string> &missingTargets);
/** Fill in properties indicating installed file locations. */
- void SetImportLocationProperty(const char* config,
+ void SetImportLocationProperty(const std::string& config,
std::string const& suffix,
cmInstallTargetGenerator* itgen,
ImportPropertyMap& properties,
std::set<std::string>& importedLocations
);
- void ComplainAboutImportPrefix(cmInstallTargetGenerator* itgen);
-
- std::string InstallNameDir(cmTarget* target, const std::string& config);
+ std::string InstallNameDir(cmGeneratorTarget* target,
+ const std::string& config);
cmInstallExportGenerator* IEGen;
- std::string ImportPrefix;
-
// The import file generated for each configuration.
- std::map<cmStdString, cmStdString> ConfigImportFiles;
+ std::map<std::string, std::string> ConfigImportFiles;
};
#endif
diff --git a/Source/cmExportLibraryDependencies.cxx b/Source/cmExportLibraryDependencies.cxx
deleted file mode 100644
index f07b783d6..000000000
--- a/Source/cmExportLibraryDependencies.cxx
+++ /dev/null
@@ -1,204 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#include "cmExportLibraryDependencies.h"
-#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
-#include "cmGeneratedFileStream.h"
-#include "cmake.h"
-#include "cmVersion.h"
-
-#include <cmsys/auto_ptr.hxx>
-
-bool cmExportLibraryDependenciesCommand
-::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
-{
- if(args.size() < 1 )
- {
- this->SetError("called with incorrect number of arguments");
- return false;
- }
-
- // store the arguments for the final pass
- this->Filename = args[0];
- this->Append = false;
- if(args.size() > 1)
- {
- if(args[1] == "APPEND")
- {
- this->Append = true;
- }
- }
- return true;
-}
-
-
-void cmExportLibraryDependenciesCommand::FinalPass()
-{
- // export_library_dependencies() shouldn't modify anything
- // ensure this by calling a const method
- this->ConstFinalPass();
-}
-
-void cmExportLibraryDependenciesCommand::ConstFinalPass() const
-{
- // Use copy-if-different if not appending.
- cmsys::auto_ptr<std::ofstream> foutPtr;
- if(this->Append)
- {
- cmsys::auto_ptr<std::ofstream> ap(
- new std::ofstream(this->Filename.c_str(), std::ios::app));
- foutPtr = ap;
- }
- else
- {
- cmsys::auto_ptr<cmGeneratedFileStream> ap(
- new cmGeneratedFileStream(this->Filename.c_str(), true));
- ap->SetCopyIfDifferent(true);
- foutPtr = ap;
- }
- std::ostream& fout = *foutPtr.get();
-
- if (!fout)
- {
- cmSystemTools::Error("Error Writing ", this->Filename.c_str());
- cmSystemTools::ReportLastSystemError("");
- return;
- }
-
- // Collect dependency information about all library targets built in
- // the project.
- cmake* cm = this->Makefile->GetCMakeInstance();
- cmGlobalGenerator* global = cm->GetGlobalGenerator();
- const std::vector<cmLocalGenerator *>& locals = global->GetLocalGenerators();
- std::map<cmStdString, cmStdString> libDepsOld;
- std::map<cmStdString, cmStdString> libDepsNew;
- std::map<cmStdString, cmStdString> libTypes;
- for(std::vector<cmLocalGenerator *>::const_iterator i = locals.begin();
- i != locals.end(); ++i)
- {
- const cmLocalGenerator* gen = *i;
- const cmTargets &tgts = gen->GetMakefile()->GetTargets();
- for(cmTargets::const_iterator l = tgts.begin();
- l != tgts.end(); ++l)
- {
- // Get the current target.
- cmTarget const& target = l->second;
-
- // Skip non-library targets.
- if(target.GetType() < cmTarget::STATIC_LIBRARY
- || target.GetType() > cmTarget::MODULE_LIBRARY)
- {
- continue;
- }
-
- // Construct the dependency variable name.
- std::string targetEntry = target.GetName();
- targetEntry += "_LIB_DEPENDS";
-
- // Construct the dependency variable value. It is safe to use
- // the target GetLinkLibraries method here because this code is
- // called at the end of configure but before generate so library
- // dependencies have yet to be analyzed. Therefore the value
- // will be the direct link dependencies.
- std::string valueOld;
- std::string valueNew;
- cmTarget::LinkLibraryVectorType const& libs = target.GetLinkLibraries();
- for(cmTarget::LinkLibraryVectorType::const_iterator li = libs.begin();
- li != libs.end(); ++li)
- {
- std::string ltVar = li->first;
- ltVar += "_LINK_TYPE";
- std::string ltValue;
- switch(li->second)
- {
- case cmTarget::GENERAL:
- valueNew += "general;";
- ltValue = "general";
- break;
- case cmTarget::DEBUG:
- valueNew += "debug;";
- ltValue = "debug";
- break;
- case cmTarget::OPTIMIZED:
- valueNew += "optimized;";
- ltValue = "optimized";
- break;
- }
- std::string lib = li->first;
- if(cmTarget* libtgt = global->FindTarget(0, lib.c_str()))
- {
- // Handle simple output name changes. This command is
- // deprecated so we do not support full target name
- // translation (which requires per-configuration info).
- if(const char* outname = libtgt->GetProperty("OUTPUT_NAME"))
- {
- lib = outname;
- }
- }
- valueOld += lib;
- valueOld += ";";
- valueNew += lib;
- valueNew += ";";
-
- std::string& ltEntry = libTypes[ltVar];
- if(ltEntry.empty())
- {
- ltEntry = ltValue;
- }
- else if(ltEntry != ltValue)
- {
- ltEntry = "general";
- }
- }
- libDepsNew[targetEntry] = valueNew;
- libDepsOld[targetEntry] = valueOld;
- }
- }
-
- // Generate dependency information for both old and new style CMake
- // versions.
- const char* vertest =
- "\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" GREATER 2.4";
- fout << "# Generated by CMake " << cmVersion::GetCMakeVersion() << "\n\n";
- fout << "IF(" << vertest << ")\n";
- fout << " # Information for CMake 2.6 and above.\n";
- for(std::map<cmStdString, cmStdString>::const_iterator
- i = libDepsNew.begin();
- i != libDepsNew.end(); ++i)
- {
- if(!i->second.empty())
- {
- fout << " SET(\"" << i->first << "\" \"" << i->second << "\")\n";
- }
- }
- fout << "ELSE(" << vertest << ")\n";
- fout << " # Information for CMake 2.4 and lower.\n";
- for(std::map<cmStdString, cmStdString>::const_iterator
- i = libDepsOld.begin();
- i != libDepsOld.end(); ++i)
- {
- if(!i->second.empty())
- {
- fout << " SET(\"" << i->first << "\" \"" << i->second << "\")\n";
- }
- }
- for(std::map<cmStdString, cmStdString>::const_iterator i = libTypes.begin();
- i != libTypes.end(); ++i)
- {
- if(i->second != "general")
- {
- fout << " SET(\"" << i->first << "\" \"" << i->second << "\")\n";
- }
- }
- fout << "ENDIF(" << vertest << ")\n";
- return;
-}
diff --git a/Source/cmExportLibraryDependencies.h b/Source/cmExportLibraryDependencies.h
deleted file mode 100644
index d8b65ccf1..000000000
--- a/Source/cmExportLibraryDependencies.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef cmExportLibraryDependenciesCommand_h
-#define cmExportLibraryDependenciesCommand_h
-
-#include "cmCommand.h"
-
-/** \class cmExportLibraryDependenciesCommand
- * \brief Add a test to the lists of tests to run.
- *
- * cmExportLibraryDependenciesCommand adds a test to the list of tests to run
- *
- */
-class cmExportLibraryDependenciesCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- virtual cmCommand* Clone()
- {
- return new cmExportLibraryDependenciesCommand;
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- virtual bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus &status);
-
- /**
- * This is called at the end after all the information
- * specified by the command is accumulated.
- */
- virtual void FinalPass();
- virtual bool HasFinalPass() const { return true; }
-
- /**
- * The name of the command as specified in CMakeList.txt.
- */
- virtual const char* GetName() const { return "export_library_dependencies";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Deprecated. Use INSTALL(EXPORT) or EXPORT command.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- "This command generates an old-style library dependencies file. "
- "Projects requiring CMake 2.6 or later should not use the command. "
- "Use instead the install(EXPORT) command to help export targets "
- "from an installation tree and the export() command to export targets "
- "from a build tree.\n"
- "The old-style library dependencies file does not take into account "
- "per-configuration names of libraries or the LINK_INTERFACE_LIBRARIES "
- "target property.\n"
- " export_library_dependencies(<file> [APPEND])\n"
- "Create a file named <file> that can be included into a CMake listfile "
- "with the INCLUDE command. The file will contain a number of SET "
- "commands that will set all the variables needed for library dependency "
- "information. This should be the last command in the top level "
- "CMakeLists.txt file of the project. If the APPEND option is "
- "specified, the SET commands will be appended to the given file "
- "instead of replacing it.";
- }
-
- /** This command is kept for compatibility with older CMake versions. */
- virtual bool IsDiscouraged() const
- {
- return true;
- }
-
- cmTypeMacro(cmExportLibraryDependenciesCommand, cmCommand);
-
-private:
- std::string Filename;
- bool Append;
- void ConstFinalPass() const;
-};
-
-
-#endif
diff --git a/Source/cmExportLibraryDependenciesCommand.cxx b/Source/cmExportLibraryDependenciesCommand.cxx
new file mode 100644
index 000000000..21d961fbc
--- /dev/null
+++ b/Source/cmExportLibraryDependenciesCommand.cxx
@@ -0,0 +1,204 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmExportLibraryDependenciesCommand.h"
+#include "cmGlobalGenerator.h"
+#include "cmGeneratedFileStream.h"
+#include "cmake.h"
+#include "cmVersion.h"
+
+#include <cmsys/auto_ptr.hxx>
+
+bool cmExportLibraryDependenciesCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(this->Disallowed(cmPolicies::CMP0033,
+ "The export_library_dependencies command should not be called; "
+ "see CMP0033."))
+ { return true; }
+ if(args.size() < 1 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // store the arguments for the final pass
+ this->Filename = args[0];
+ this->Append = false;
+ if(args.size() > 1)
+ {
+ if(args[1] == "APPEND")
+ {
+ this->Append = true;
+ }
+ }
+ return true;
+}
+
+
+void cmExportLibraryDependenciesCommand::FinalPass()
+{
+ // export_library_dependencies() shouldn't modify anything
+ // ensure this by calling a const method
+ this->ConstFinalPass();
+}
+
+void cmExportLibraryDependenciesCommand::ConstFinalPass() const
+{
+ // Use copy-if-different if not appending.
+ cmsys::auto_ptr<cmsys::ofstream> foutPtr;
+ if(this->Append)
+ {
+ cmsys::auto_ptr<cmsys::ofstream> ap(
+ new cmsys::ofstream(this->Filename.c_str(), std::ios::app));
+ foutPtr = ap;
+ }
+ else
+ {
+ cmsys::auto_ptr<cmGeneratedFileStream> ap(
+ new cmGeneratedFileStream(this->Filename.c_str(), true));
+ ap->SetCopyIfDifferent(true);
+ foutPtr = ap;
+ }
+ std::ostream& fout = *foutPtr.get();
+
+ if (!fout)
+ {
+ cmSystemTools::Error("Error Writing ", this->Filename.c_str());
+ cmSystemTools::ReportLastSystemError("");
+ return;
+ }
+
+ // Collect dependency information about all library targets built in
+ // the project.
+ cmake* cm = this->Makefile->GetCMakeInstance();
+ cmGlobalGenerator* global = cm->GetGlobalGenerator();
+ const std::vector<cmMakefile*>& locals = global->GetMakefiles();
+ std::map<std::string, std::string> libDepsOld;
+ std::map<std::string, std::string> libDepsNew;
+ std::map<std::string, std::string> libTypes;
+ for(std::vector<cmMakefile*>::const_iterator i = locals.begin();
+ i != locals.end(); ++i)
+ {
+ const cmTargets &tgts = (*i)->GetTargets();
+ for(cmTargets::const_iterator l = tgts.begin();
+ l != tgts.end(); ++l)
+ {
+ // Get the current target.
+ cmTarget const& target = l->second;
+
+ // Skip non-library targets.
+ if(target.GetType() < cmState::STATIC_LIBRARY
+ || target.GetType() > cmState::MODULE_LIBRARY)
+ {
+ continue;
+ }
+
+ // Construct the dependency variable name.
+ std::string targetEntry = target.GetName();
+ targetEntry += "_LIB_DEPENDS";
+
+ // Construct the dependency variable value with the direct link
+ // dependencies.
+ std::string valueOld;
+ std::string valueNew;
+ cmTarget::LinkLibraryVectorType const& libs =
+ target.GetOriginalLinkLibraries();
+ for(cmTarget::LinkLibraryVectorType::const_iterator li = libs.begin();
+ li != libs.end(); ++li)
+ {
+ std::string ltVar = li->first;
+ ltVar += "_LINK_TYPE";
+ std::string ltValue;
+ switch(li->second)
+ {
+ case GENERAL_LibraryType:
+ valueNew += "general;";
+ ltValue = "general";
+ break;
+ case DEBUG_LibraryType:
+ valueNew += "debug;";
+ ltValue = "debug";
+ break;
+ case OPTIMIZED_LibraryType:
+ valueNew += "optimized;";
+ ltValue = "optimized";
+ break;
+ }
+ std::string lib = li->first;
+ if(cmTarget* libtgt = global->FindTarget(lib))
+ {
+ // Handle simple output name changes. This command is
+ // deprecated so we do not support full target name
+ // translation (which requires per-configuration info).
+ if(const char* outname = libtgt->GetProperty("OUTPUT_NAME"))
+ {
+ lib = outname;
+ }
+ }
+ valueOld += lib;
+ valueOld += ";";
+ valueNew += lib;
+ valueNew += ";";
+
+ std::string& ltEntry = libTypes[ltVar];
+ if(ltEntry.empty())
+ {
+ ltEntry = ltValue;
+ }
+ else if(ltEntry != ltValue)
+ {
+ ltEntry = "general";
+ }
+ }
+ libDepsNew[targetEntry] = valueNew;
+ libDepsOld[targetEntry] = valueOld;
+ }
+ }
+
+ // Generate dependency information for both old and new style CMake
+ // versions.
+ const char* vertest =
+ "\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" GREATER 2.4";
+ fout << "# Generated by CMake " << cmVersion::GetCMakeVersion() << "\n\n";
+ fout << "if(" << vertest << ")\n";
+ fout << " # Information for CMake 2.6 and above.\n";
+ for(std::map<std::string, std::string>::const_iterator
+ i = libDepsNew.begin();
+ i != libDepsNew.end(); ++i)
+ {
+ if(!i->second.empty())
+ {
+ fout << " set(\"" << i->first << "\" \"" << i->second << "\")\n";
+ }
+ }
+ fout << "else()\n";
+ fout << " # Information for CMake 2.4 and lower.\n";
+ for(std::map<std::string, std::string>::const_iterator
+ i = libDepsOld.begin();
+ i != libDepsOld.end(); ++i)
+ {
+ if(!i->second.empty())
+ {
+ fout << " set(\"" << i->first << "\" \"" << i->second << "\")\n";
+ }
+ }
+ for(std::map<std::string, std::string>::const_iterator i = libTypes.begin();
+ i != libTypes.end(); ++i)
+ {
+ if(i->second != "general")
+ {
+ fout << " set(\"" << i->first << "\" \"" << i->second << "\")\n";
+ }
+ }
+ fout << "endif()\n";
+ return;
+}
diff --git a/Source/cmExportLibraryDependenciesCommand.h b/Source/cmExportLibraryDependenciesCommand.h
new file mode 100644
index 000000000..81aa21a5b
--- /dev/null
+++ b/Source/cmExportLibraryDependenciesCommand.h
@@ -0,0 +1,36 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmExportLibraryDependenciesCommand_h
+#define cmExportLibraryDependenciesCommand_h
+
+#include "cmCommand.h"
+
+class cmExportLibraryDependenciesCommand : public cmCommand
+{
+public:
+ cmTypeMacro(cmExportLibraryDependenciesCommand, cmCommand);
+ virtual cmCommand* Clone() { return new cmExportLibraryDependenciesCommand; }
+ virtual bool InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus &status);
+ virtual std::string GetName() const { return "export_library_dependencies";}
+
+ virtual void FinalPass();
+ virtual bool HasFinalPass() const { return true; }
+
+private:
+ std::string Filename;
+ bool Append;
+ void ConstFinalPass() const;
+};
+
+
+#endif
diff --git a/Source/cmExportSet.cxx b/Source/cmExportSet.cxx
index 33b063037..0059b6400 100644
--- a/Source/cmExportSet.cxx
+++ b/Source/cmExportSet.cxx
@@ -12,12 +12,20 @@
#include "cmExportSet.h"
#include "cmTargetExport.h"
+#include "cmAlgorithms.h"
+#include "cmLocalGenerator.h"
cmExportSet::~cmExportSet()
{
- for(unsigned int i = 0; i < this->TargetExports.size(); ++ i)
+ cmDeleteAll(this->TargetExports);
+}
+
+void cmExportSet::Compute(cmLocalGenerator* lg)
+{
+ for (std::vector<cmTargetExport*>::iterator it = this->TargetExports.begin();
+ it != this->TargetExports.end(); ++it)
{
- delete this->TargetExports[i];
+ (*it)->Target = lg->FindGeneratorTargetToUse((*it)->TargetName);
}
}
diff --git a/Source/cmExportSet.h b/Source/cmExportSet.h
index a57aa1204..d780a228c 100644
--- a/Source/cmExportSet.h
+++ b/Source/cmExportSet.h
@@ -15,6 +15,7 @@
#include "cmSystemTools.h"
class cmTargetExport;
class cmInstallExportGenerator;
+class cmLocalGenerator;
/// A set of targets that were installed with the same EXPORT parameter.
class cmExportSet
@@ -25,6 +26,8 @@ public:
/// Destructor
~cmExportSet();
+ void Compute(cmLocalGenerator* lg);
+
void AddTargetExport(cmTargetExport* tgt);
void AddInstallation(cmInstallExportGenerator const* installation);
diff --git a/Source/cmExportSetMap.cxx b/Source/cmExportSetMap.cxx
index 96fdb3e4f..cf431c60c 100644
--- a/Source/cmExportSetMap.cxx
+++ b/Source/cmExportSetMap.cxx
@@ -12,6 +12,7 @@
#include "cmExportSetMap.h"
#include "cmExportSet.h"
+#include "cmAlgorithms.h"
cmExportSet* cmExportSetMap::operator[](const std::string &name)
{
@@ -23,12 +24,13 @@ cmExportSet* cmExportSetMap::operator[](const std::string &name)
return it->second;
}
+void cmExportSetMap::clear()
+{
+ cmDeleteAll(*this);
+ this->derived::clear();
+}
+
cmExportSetMap::~cmExportSetMap()
{
- for(std::map<std::string, cmExportSet*>::iterator it = this->begin();
- it != this->end();
- ++ it)
- {
- delete it->second;
- }
+ this->clear();
}
diff --git a/Source/cmExportSetMap.h b/Source/cmExportSetMap.h
index 4663c5538..965046cef 100644
--- a/Source/cmExportSetMap.h
+++ b/Source/cmExportSetMap.h
@@ -18,6 +18,7 @@ class cmExportSet;
/// A name -> cmExportSet map with overloaded operator[].
class cmExportSetMap : public std::map<std::string, cmExportSet*>
{
+ typedef std::map<std::string, cmExportSet*> derived;
public:
/** \brief Overloaded operator[].
*
@@ -26,6 +27,8 @@ public:
*/
cmExportSet* operator[](const std::string &name);
+ void clear();
+
/// Overloaded destructor deletes all member export sets.
~cmExportSetMap();
};
diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx
index 819ac371e..83127e7ed 100644
--- a/Source/cmExportTryCompileFileGenerator.cxx
+++ b/Source/cmExportTryCompileFileGenerator.cxx
@@ -13,16 +13,26 @@
#include "cmExportTryCompileFileGenerator.h"
#include "cmGeneratedFileStream.h"
+#include "cmGlobalGenerator.h"
+#include "cmLocalGenerator.h"
#include "cmGeneratorExpressionDAGChecker.h"
//----------------------------------------------------------------------------
+cmExportTryCompileFileGenerator::cmExportTryCompileFileGenerator(
+ cmGlobalGenerator* gg,
+ const std::vector<std::string>& targets,
+ cmMakefile* mf)
+{
+ gg->CreateImportedGenerationObjects(mf, targets, this->Exports);
+}
+
bool cmExportTryCompileFileGenerator::GenerateMainFile(std::ostream& os)
{
- std::set<cmTarget*> emitted;
- std::set<cmTarget*> emittedDeps;
+ std::set<cmGeneratorTarget const*> emitted;
+ std::set<cmGeneratorTarget const*> emittedDeps;
while(!this->Exports.empty())
{
- cmTarget* te = this->Exports.back();
+ cmGeneratorTarget const* te = this->Exports.back();
this->Exports.pop_back();
if (emitted.insert(te).second)
{
@@ -32,10 +42,12 @@ bool cmExportTryCompileFileGenerator::GenerateMainFile(std::ostream& os)
ImportPropertyMap properties;
#define FIND_TARGETS(PROPERTY) \
- this->FindTargets(#PROPERTY, te, emittedDeps);
+ this->FindTargets("INTERFACE_" #PROPERTY, te, emittedDeps);
CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(FIND_TARGETS)
+#undef FIND_TARGETS
+
this->PopulateProperties(te, properties, emittedDeps);
this->GenerateInterfaceProperties(te, os, properties);
@@ -44,9 +56,10 @@ bool cmExportTryCompileFileGenerator::GenerateMainFile(std::ostream& os)
return true;
}
-std::string cmExportTryCompileFileGenerator::FindTargets(const char *propName,
- cmTarget *tgt,
- std::set<cmTarget*> &emitted)
+std::string cmExportTryCompileFileGenerator::FindTargets(
+ const std::string& propName,
+ cmGeneratorTarget const* tgt,
+ std::set<cmGeneratorTarget const*> &emitted)
{
const char *prop = tgt->GetProperty(propName);
if(!prop)
@@ -54,25 +67,28 @@ std::string cmExportTryCompileFileGenerator::FindTargets(const char *propName,
return std::string();
}
- cmListFileBacktrace lfbt;
- cmGeneratorExpression ge(lfbt);
+ cmGeneratorExpression ge;
- cmGeneratorExpressionDAGChecker dagChecker(lfbt,
+ cmGeneratorExpressionDAGChecker dagChecker(
tgt->GetName(),
propName, 0, 0);
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
cmTarget dummyHead;
- dummyHead.SetType(cmTarget::EXECUTABLE, "try_compile_dummy_exe");
- dummyHead.SetMakefile(tgt->GetMakefile());
+ dummyHead.SetType(cmState::EXECUTABLE, "try_compile_dummy_exe");
+ dummyHead.SetMakefile(tgt->Target->GetMakefile());
- std::string result = cge->Evaluate(tgt->GetMakefile(), this->Config,
- false, &dummyHead, tgt, &dagChecker);
+ cmGeneratorTarget gDummyHead(&dummyHead, tgt->GetLocalGenerator());
- const std::set<cmTarget*> &allTargets = cge->GetAllTargetsSeen();
- for(std::set<cmTarget*>::const_iterator li = allTargets.begin();
- li != allTargets.end(); ++li)
+ std::string result = cge->Evaluate(tgt->GetLocalGenerator(), this->Config,
+ false, &gDummyHead,
+ tgt, &dagChecker);
+
+ const std::set<cmGeneratorTarget const*> &allTargets =
+ cge->GetAllTargetsSeen();
+ for(std::set<cmGeneratorTarget const*>::const_iterator li =
+ allTargets.begin(); li != allTargets.end(); ++li)
{
if(emitted.insert(*li).second)
{
@@ -84,22 +100,23 @@ std::string cmExportTryCompileFileGenerator::FindTargets(const char *propName,
//----------------------------------------------------------------------------
void
-cmExportTryCompileFileGenerator::PopulateProperties(cmTarget* target,
- ImportPropertyMap& properties,
- std::set<cmTarget*> &emitted)
+cmExportTryCompileFileGenerator::PopulateProperties(
+ const cmGeneratorTarget* target,
+ ImportPropertyMap& properties,
+ std::set<cmGeneratorTarget const*> &emitted)
{
- cmPropertyMap props = target->GetProperties();
- for(cmPropertyMap::const_iterator i = props.begin(); i != props.end(); ++i)
+ std::vector<std::string> props = target->GetPropertyKeys();
+ for(std::vector<std::string>::const_iterator i = props.begin();
+ i != props.end(); ++i)
{
- properties[i->first] = i->second.GetValue();
- if(i->first.find("IMPORTED_LINK_INTERFACE_LIBRARIES") == 0
- || i->first.find("IMPORTED_LINK_DEPENDENT_LIBRARIES") == 0
- || i->first.find("INTERFACE_LINK_LIBRARIES") == 0)
- {
- const std::string libs = i->second.GetValue();
+ properties[*i] = target->GetProperty(*i);
- std::string evalResult = this->FindTargets(i->first.c_str(),
+ if(i->find("IMPORTED_LINK_INTERFACE_LIBRARIES") == 0
+ || i->find("IMPORTED_LINK_DEPENDENT_LIBRARIES") == 0
+ || i->find("INTERFACE_LINK_LIBRARIES") == 0)
+ {
+ std::string evalResult = this->FindTargets(*i,
target, emitted);
std::vector<std::string> depends;
@@ -107,7 +124,8 @@ cmExportTryCompileFileGenerator::PopulateProperties(cmTarget* target,
for(std::vector<std::string>::const_iterator li = depends.begin();
li != depends.end(); ++li)
{
- cmTarget *tgt = target->GetMakefile()->FindTargetToUse(li->c_str());
+ cmGeneratorTarget *tgt =
+ target->GetLocalGenerator()->FindGeneratorTargetToUse(*li);
if(tgt && emitted.insert(tgt).second)
{
this->Exports.push_back(tgt);
@@ -116,17 +134,18 @@ cmExportTryCompileFileGenerator::PopulateProperties(cmTarget* target,
}
}
}
+
std::string
-cmExportTryCompileFileGenerator::InstallNameDir(cmTarget* target,
+cmExportTryCompileFileGenerator::InstallNameDir(cmGeneratorTarget* target,
const std::string& config)
{
std::string install_name_dir;
- cmMakefile* mf = target->GetMakefile();
+ cmMakefile* mf = target->Target->GetMakefile();
if(mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
{
install_name_dir =
- target->GetInstallNameDirForBuildTree(config.c_str());
+ target->GetInstallNameDirForBuildTree(config);
}
return install_name_dir;
diff --git a/Source/cmExportTryCompileFileGenerator.h b/Source/cmExportTryCompileFileGenerator.h
index 91b4a6153..fc135a455 100644
--- a/Source/cmExportTryCompileFileGenerator.h
+++ b/Source/cmExportTryCompileFileGenerator.h
@@ -9,8 +9,8 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#ifndef cmExportInstallFileGenerator_h
-#define cmExportInstallFileGenerator_h
+#ifndef cmExportTryCompileFileGenerator_h
+#define cmExportTryCompileFileGenerator_h
#include "cmExportFileGenerator.h"
@@ -20,38 +20,40 @@ class cmInstallTargetGenerator;
class cmExportTryCompileFileGenerator: public cmExportFileGenerator
{
public:
+ cmExportTryCompileFileGenerator(cmGlobalGenerator* gg,
+ std::vector<std::string> const& targets,
+ cmMakefile* mf);
+
/** Set the list of targets to export. */
- void SetExports(const std::vector<cmTarget*> &exports)
- { this->Exports = exports; }
- void SetConfig(const char *config) { this->Config = config; }
+ void SetConfig(const std::string& config) { this->Config = config; }
protected:
// Implement virtual methods from the superclass.
virtual bool GenerateMainFile(std::ostream& os);
virtual void GenerateImportTargetsConfig(std::ostream&,
- const char*,
+ const std::string&,
std::string const&,
std::vector<std::string>&) {}
virtual void HandleMissingTarget(std::string&,
std::vector<std::string>&,
- cmMakefile*,
- cmTarget*,
- cmTarget*) {}
+ cmGeneratorTarget*,
+ cmGeneratorTarget*) {}
- void PopulateProperties(cmTarget* target,
+ void PopulateProperties(cmGeneratorTarget const* target,
ImportPropertyMap& properties,
- std::set<cmTarget*> &emitted);
+ std::set<const cmGeneratorTarget*>& emitted);
- std::string InstallNameDir(cmTarget* target,
+ std::string InstallNameDir(cmGeneratorTarget* target,
const std::string& config);
private:
- std::string FindTargets(const char *prop, cmTarget *tgt,
- std::set<cmTarget*> &emitted);
+ std::string FindTargets(const std::string& prop,
+ const cmGeneratorTarget* tgt,
+ std::set<const cmGeneratorTarget*>& emitted);
- std::vector<cmTarget*> Exports;
- const char *Config;
+ std::vector<cmGeneratorTarget const*> Exports;
+ std::string Config;
};
#endif
diff --git a/Source/cmExprLexer.cxx b/Source/cmExprLexer.cxx
index 9947c77f1..4704f0368 100644
--- a/Source/cmExprLexer.cxx
+++ b/Source/cmExprLexer.cxx
@@ -976,7 +976,7 @@ case YY_STATE_EOF(INITIAL):
"fatal flex scanner internal error--no action found" );
} /* end of action switch */
} /* end of scanning one token */
-return 0; /* this should not happen but it silences a warning*/
+return 0; /* this should not happen but it quiets some compilers */
} /* end of cmExpr_yylex */
/* yy_get_next_buffer - try to read in a new buffer
@@ -1716,7 +1716,7 @@ void cmExpr_yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
}
/** Set the current line number.
- * @param line_number
+ * @param line_number The line number to set.
* @param yyscanner The scanner object.
*/
void cmExpr_yyset_lineno (int line_number , yyscan_t yyscanner)
@@ -1731,7 +1731,7 @@ void cmExpr_yyset_lineno (int line_number , yyscan_t yyscanner)
}
/** Set the current column.
- * @param column_no
+ * @param column_no The column number to set.
* @param yyscanner The scanner object.
*/
void cmExpr_yyset_column (int column_no , yyscan_t yyscanner)
diff --git a/Source/cmExprParser.cxx b/Source/cmExprParser.cxx
index 77880c0a3..c12b42e70 100644
--- a/Source/cmExprParser.cxx
+++ b/Source/cmExprParser.cxx
@@ -157,12 +157,6 @@ static void cmExprError(yyscan_t yyscanner, const char* message);
/* Disable some warnings in the generated code. */
-#ifdef __BORLANDC__
-# pragma warn -8004 /* Variable assigned a value that is not used. */
-# pragma warn -8008 /* condition always returns true */
-# pragma warn -8060 /* possibly incorrect assignment */
-# pragma warn -8066 /* unreachable code */
-#endif
#ifdef _MSC_VER
# pragma warning (disable: 4102) /* Unused goto label. */
# pragma warning (disable: 4065) /* Switch statement contains default but
diff --git a/Source/cmExprParser.y b/Source/cmExprParser.y
index 12c2e4806..f2c85d097 100644
--- a/Source/cmExprParser.y
+++ b/Source/cmExprParser.y
@@ -52,12 +52,6 @@ static void cmExprError(yyscan_t yyscanner, const char* message);
/* Disable some warnings in the generated code. */
-#ifdef __BORLANDC__
-# pragma warn -8004 /* Variable assigned a value that is not used. */
-# pragma warn -8008 /* condition always returns true */
-# pragma warn -8060 /* possibly incorrect assignment */
-# pragma warn -8066 /* unreachable code */
-#endif
#ifdef _MSC_VER
# pragma warning (disable: 4102) /* Unused goto label. */
# pragma warning (disable: 4065) /* Switch statement contains default but no case. */
diff --git a/Source/cmExprParserHelper.cxx b/Source/cmExprParserHelper.cxx
index cc35f84cd..6016c4cce 100644
--- a/Source/cmExprParserHelper.cxx
+++ b/Source/cmExprParserHelper.cxx
@@ -99,7 +99,7 @@ int cmExprParserHelper::LexInput(char* buf, int maxlen)
void cmExprParserHelper::Error(const char* str)
{
unsigned long pos = static_cast<unsigned long>(this->InputBufferPos);
- cmOStringStream ostr;
+ std::ostringstream ostr;
ostr << str << " (" << pos << ")";
this->ErrorString = ostr.str();
}
diff --git a/Source/cmExprParserHelper.h b/Source/cmExprParserHelper.h
index 4b76b3322..8d6b2cd47 100644
--- a/Source/cmExprParserHelper.h
+++ b/Source/cmExprParserHelper.h
@@ -49,8 +49,8 @@ public:
const char* GetError() { return this->ErrorString.c_str(); }
private:
- cmStdString::size_type InputBufferPos;
- cmStdString InputBuffer;
+ std::string::size_type InputBufferPos;
+ std::string InputBuffer;
std::vector<char> OutputBuffer;
int CurrentLine;
int Verbose;
diff --git a/Source/cmExternalMakefileProjectGenerator.cxx b/Source/cmExternalMakefileProjectGenerator.cxx
index 9c965cc24..9264671a3 100644
--- a/Source/cmExternalMakefileProjectGenerator.cxx
+++ b/Source/cmExternalMakefileProjectGenerator.cxx
@@ -13,14 +13,20 @@
#include "cmExternalMakefileProjectGenerator.h"
+void cmExternalMakefileProjectGenerator
+::EnableLanguage(std::vector<std::string> const&,
+ cmMakefile *, bool)
+{
+}
+
std::string cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
- const char* globalGenerator,
- const char* extraGenerator)
+ const std::string& globalGenerator,
+ const std::string& extraGenerator)
{
std::string fullName;
- if (globalGenerator)
+ if (!globalGenerator.empty())
{
- if (extraGenerator && *extraGenerator)
+ if (!extraGenerator.empty())
{
fullName = extraGenerator;
fullName += " - ";
@@ -30,22 +36,22 @@ std::string cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
return fullName;
}
-const char* cmExternalMakefileProjectGenerator::GetGlobalGeneratorName(
- const char* fullName)
+std::string cmExternalMakefileProjectGenerator::GetGlobalGeneratorName(
+ const std::string& fullName)
{
// at least one global generator must be supported
assert(!this->SupportedGlobalGenerators.empty());
- if (fullName==0)
+ if (fullName.empty())
{
- return 0;
+ return "";
}
std::string currentName = fullName;
// if we get only the short name, take the first global generator as default
if (currentName == this->GetName())
{
- return this->SupportedGlobalGenerators[0].c_str();
+ return this->SupportedGlobalGenerators[0];
}
// otherwise search for the matching global generator
@@ -54,11 +60,11 @@ const char* cmExternalMakefileProjectGenerator::GetGlobalGeneratorName(
it != this->SupportedGlobalGenerators.end();
++it)
{
- if (this->CreateFullGeneratorName(it->c_str(), this->GetName())
+ if (this->CreateFullGeneratorName(*it, this->GetName())
== currentName)
{
- return it->c_str();
+ return *it;
}
}
- return 0;
+ return "";
}
diff --git a/Source/cmExternalMakefileProjectGenerator.h b/Source/cmExternalMakefileProjectGenerator.h
index 182c1a8f6..cba1c76dd 100644
--- a/Source/cmExternalMakefileProjectGenerator.h
+++ b/Source/cmExternalMakefileProjectGenerator.h
@@ -37,10 +37,12 @@ public:
virtual ~cmExternalMakefileProjectGenerator() {}
///! Get the name for this generator.
- virtual const char* GetName() const = 0;
+ virtual std::string GetName() const = 0;
/** Get the documentation entry for this generator. */
virtual void GetDocumentation(cmDocumentationEntry& entry,
- const char* fullName) const = 0;
+ const std::string& fullName) const = 0;
+ virtual void EnableLanguage(std::vector<std::string> const& languages,
+ cmMakefile *, bool optional);
///! set the global generator which will generate the makefiles
virtual void SetGlobalGenerator(cmGlobalGenerator* generator)
@@ -51,12 +53,13 @@ public:
{return this->SupportedGlobalGenerators;}
///! Get the name of the global generator for the given full name
- const char* GetGlobalGeneratorName(const char* fullName);
+ std::string GetGlobalGeneratorName(const std::string& fullName);
/** Create a full name from the given global generator name and the
* extra generator name
*/
- static std::string CreateFullGeneratorName(const char* globalGenerator,
- const char* extraGenerator);
+ static std::string CreateFullGeneratorName(
+ const std::string& globalGenerator,
+ const std::string& extraGenerator);
///! Generate the project files, the Makefiles have already been generated
virtual void Generate() = 0;
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index dfbb1c0ad..9348ef2b3 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -17,7 +17,6 @@
#include "cmake.h"
#include "cmSourceFile.h"
#include "cmGeneratedFileStream.h"
-#include "cmTarget.h"
#include "cmSystemTools.h"
#include "cmXMLSafe.h"
@@ -38,17 +37,10 @@ http://forums.codeblocks.org/index.php/topic,6789.0.html
//----------------------------------------------------------------------------
void cmExtraCodeBlocksGenerator
-::GetDocumentation(cmDocumentationEntry& entry, const char*) const
+::GetDocumentation(cmDocumentationEntry& entry, const std::string&) const
{
entry.Name = this->GetName();
entry.Brief = "Generates CodeBlocks project files.";
- entry.Full =
- "Project files for CodeBlocks will be created in the top directory "
- "and in every subdirectory which features a CMakeLists.txt file "
- "containing a PROJECT() call. "
- "Additionally a hierarchy of makefiles is generated into the "
- "build tree. The appropriate make program can build the project through "
- "the default make target. A \"make install\" target is also provided.";
}
cmExtraCodeBlocksGenerator::cmExtraCodeBlocksGenerator()
@@ -68,7 +60,7 @@ cmExtraCodeBlocksGenerator::cmExtraCodeBlocksGenerator()
void cmExtraCodeBlocksGenerator::Generate()
{
// for each sub project in the project create a codeblocks project
- for (std::map<cmStdString, std::vector<cmLocalGenerator*> >::const_iterator
+ for (std::map<std::string, std::vector<cmLocalGenerator*> >::const_iterator
it = this->GlobalGenerator->GetProjectMap().begin();
it!= this->GlobalGenerator->GetProjectMap().end();
++it)
@@ -83,9 +75,8 @@ void cmExtraCodeBlocksGenerator::Generate()
void cmExtraCodeBlocksGenerator::CreateProjectFile(
const std::vector<cmLocalGenerator*>& lgs)
{
- const cmMakefile* mf=lgs[0]->GetMakefile();
- std::string outputDir=mf->GetStartOutputDirectory();
- std::string projectName=mf->GetProjectName();
+ std::string outputDir=lgs[0]->GetCurrentBinaryDirectory();
+ std::string projectName=lgs[0]->GetProjectName();
std::string filename=outputDir+"/";
filename+=projectName+".cbp";
@@ -250,7 +241,7 @@ void cmExtraCodeBlocksGenerator
Tree tree;
// build tree of virtual folders
- for (std::map<cmStdString, std::vector<cmLocalGenerator*> >::const_iterator
+ for (std::map<std::string, std::vector<cmLocalGenerator*> >::const_iterator
it = this->GlobalGenerator->GetProjectMap().begin();
it != this->GlobalGenerator->GetProjectMap().end();
++it)
@@ -280,10 +271,10 @@ void cmExtraCodeBlocksGenerator
}
const std::string &relative = cmSystemTools::RelativePath(
- it->second[0]->GetMakefile()->GetHomeDirectory(),
+ it->second[0]->GetSourceDirectory(),
jt->c_str());
std::vector<std::string> splitted;
- cmSystemTools::SplitPath(relative.c_str(), splitted, false);
+ cmSystemTools::SplitPath(relative, splitted, false);
// Split filename from path
std::string fileName = *(splitted.end()-1);
splitted.erase(splitted.end() - 1, splitted.end());
@@ -304,7 +295,7 @@ void cmExtraCodeBlocksGenerator
tree.BuildVirtualFolder(virtualFolders);
// And one for <Unit>
std::string unitFiles;
- tree.BuildUnit(unitFiles, std::string(mf->GetHomeDirectory()) + "/");
+ tree.BuildUnit(unitFiles, std::string(lgs[0]->GetSourceDirectory()) + "/");
// figure out the compiler
std::string compiler = this->GetCBCompilerId(mf);
@@ -314,84 +305,66 @@ void cmExtraCodeBlocksGenerator
"<CodeBlocks_project_file>\n"
" <FileVersion major=\"1\" minor=\"6\" />\n"
" <Project>\n"
- " <Option title=\"" << mf->GetProjectName()<<"\" />\n"
+ " <Option title=\"" << lgs[0]->GetProjectName()<<"\" />\n"
" <Option makefile_is_custom=\"1\" />\n"
" <Option compiler=\"" << compiler << "\" />\n"
" "<<virtualFolders<<"\n"
" <Build>\n";
- this->AppendTarget(fout, "all", 0, make.c_str(), mf, compiler.c_str());
+ this->AppendTarget(fout, "all", 0, make.c_str(), lgs[0], compiler.c_str());
// add all executable and library targets and some of the GLOBAL
// and UTILITY targets
for (std::vector<cmLocalGenerator*>::const_iterator lg=lgs.begin();
lg!=lgs.end(); lg++)
{
- cmMakefile* makefile=(*lg)->GetMakefile();
- cmTargets& targets=makefile->GetTargets();
- for (cmTargets::iterator ti = targets.begin();
+ std::vector<cmGeneratorTarget*> targets=(*lg)->GetGeneratorTargets();
+ for (std::vector<cmGeneratorTarget*>::iterator ti = targets.begin();
ti != targets.end(); ti++)
{
- switch(ti->second.GetType())
+ std::string targetName = (*ti)->GetName();
+ switch((*ti)->GetType())
{
- case cmTarget::GLOBAL_TARGET:
+ case cmState::GLOBAL_TARGET:
{
- bool insertTarget = false;
// Only add the global targets from CMAKE_BINARY_DIR,
// not from the subdirs
- if (strcmp(makefile->GetStartOutputDirectory(),
- makefile->GetHomeOutputDirectory())==0)
- {
- insertTarget = true;
- // only add the "edit_cache" target if it's not ccmake, because
- // this will not work within the IDE
- if (ti->first == "edit_cache")
- {
- const char* editCommand = makefile->GetDefinition
- ("CMAKE_EDIT_COMMAND");
- if (editCommand == 0)
- {
- insertTarget = false;
- }
- else if (strstr(editCommand, "ccmake")!=NULL)
- {
- insertTarget = false;
- }
- }
- }
- if (insertTarget)
+ if (strcmp((*lg)->GetCurrentBinaryDirectory(),
+ (*lg)->GetBinaryDirectory())==0)
{
- this->AppendTarget(fout, ti->first.c_str(), 0,
- make.c_str(), makefile, compiler.c_str());
+ this->AppendTarget(fout, targetName, 0,
+ make.c_str(), *lg, compiler.c_str());
}
}
break;
- case cmTarget::UTILITY:
+ case cmState::UTILITY:
// Add all utility targets, except the Nightly/Continuous/
// Experimental-"sub"targets as e.g. NightlyStart
- if (((ti->first.find("Nightly")==0) &&(ti->first!="Nightly"))
- || ((ti->first.find("Continuous")==0)&&(ti->first!="Continuous"))
- || ((ti->first.find("Experimental")==0)
- && (ti->first!="Experimental")))
+ if (((targetName.find("Nightly")==0) &&(targetName!="Nightly"))
+ || ((targetName.find("Continuous")==0)
+ &&(targetName!="Continuous"))
+ || ((targetName.find("Experimental")==0)
+ && (targetName!="Experimental")))
{
break;
}
- this->AppendTarget(fout, ti->first.c_str(), 0,
- make.c_str(), makefile, compiler.c_str());
+ this->AppendTarget(fout, targetName, 0,
+ make.c_str(), *lg, compiler.c_str());
break;
- case cmTarget::EXECUTABLE:
- case cmTarget::STATIC_LIBRARY:
- case cmTarget::SHARED_LIBRARY:
- case cmTarget::MODULE_LIBRARY:
- case cmTarget::OBJECT_LIBRARY:
+ case cmState::EXECUTABLE:
+ case cmState::STATIC_LIBRARY:
+ case cmState::SHARED_LIBRARY:
+ case cmState::MODULE_LIBRARY:
+ case cmState::OBJECT_LIBRARY:
{
- this->AppendTarget(fout, ti->first.c_str(), &ti->second,
- make.c_str(), makefile, compiler.c_str());
- std::string fastTarget = ti->first;
+ cmGeneratorTarget* gt = *ti;
+ this->AppendTarget(fout, targetName, gt,
+ make.c_str(), *lg, compiler.c_str());
+ std::string fastTarget = targetName;
fastTarget += "/fast";
- this->AppendTarget(fout, fastTarget.c_str(), &ti->second,
- make.c_str(), makefile, compiler.c_str());
+ this->AppendTarget(fout, fastTarget, gt,
+ make.c_str(), *lg, compiler.c_str());
}
break;
default:
@@ -403,29 +376,37 @@ void cmExtraCodeBlocksGenerator
fout<<" </Build>\n";
- // Collect all used source files in the project
- // Sort them into two containers, one for C/C++ implementation files
- // which may have an acompanying header, one for all other files
- std::map<std::string, cmSourceFile*> cFiles;
- std::set<std::string> otherFiles;
+ // Collect all used source files in the project.
+ // Keep a list of C/C++ source files which might have an acompanying header
+ // that should be looked for.
+ typedef std::map<std::string, CbpUnit> all_files_map_t;
+ all_files_map_t allFiles;
+ std::vector<std::string> cFiles;
+
+ std::vector<std::string> srcExts =
+ this->GlobalGenerator->GetCMakeInstance()->GetSourceExtensions();
+
for (std::vector<cmLocalGenerator*>::const_iterator lg=lgs.begin();
lg!=lgs.end(); lg++)
{
cmMakefile* makefile=(*lg)->GetMakefile();
- cmTargets& targets=makefile->GetTargets();
- for (cmTargets::iterator ti = targets.begin();
+ std::vector<cmGeneratorTarget*> targets=(*lg)->GetGeneratorTargets();
+ for (std::vector<cmGeneratorTarget*>::iterator ti = targets.begin();
ti != targets.end(); ti++)
{
- switch(ti->second.GetType())
+ switch((*ti)->GetType())
{
- case cmTarget::EXECUTABLE:
- case cmTarget::STATIC_LIBRARY:
- case cmTarget::SHARED_LIBRARY:
- case cmTarget::MODULE_LIBRARY:
- case cmTarget::OBJECT_LIBRARY:
- case cmTarget::UTILITY: // can have sources since 2.6.3
+ case cmState::EXECUTABLE:
+ case cmState::STATIC_LIBRARY:
+ case cmState::SHARED_LIBRARY:
+ case cmState::MODULE_LIBRARY:
+ case cmState::OBJECT_LIBRARY:
+ case cmState::UTILITY: // can have sources since 2.6.3
{
- const std::vector<cmSourceFile*>&sources=ti->second.GetSourceFiles();
+ std::vector<cmSourceFile*> sources;
+ cmGeneratorTarget* gt = *ti;
+ gt->GetSourceFiles(sources,
+ makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
for (std::vector<cmSourceFile*>::const_iterator si=sources.begin();
si!=sources.end(); si++)
{
@@ -437,14 +418,14 @@ void cmExtraCodeBlocksGenerator
// check whether it is a C/C++ implementation file
bool isCFile = false;
- if ((*si)->GetLanguage() && (*(*si)->GetLanguage() == 'C'))
+ std::string lang = (*si)->GetLanguage();
+ if (lang == "C" || lang == "CXX")
{
+ std::string srcext = (*si)->GetExtension();
for(std::vector<std::string>::const_iterator
- ext = mf->GetSourceExtensions().begin();
- ext != mf->GetSourceExtensions().end();
- ++ext)
+ ext = srcExts.begin(); ext != srcExts.end(); ++ext)
{
- if ((*si)->GetExtension() == *ext)
+ if (srcext == *ext)
{
isCFile = true;
break;
@@ -452,15 +433,15 @@ void cmExtraCodeBlocksGenerator
}
}
- // then put it accordingly into one of the two containers
- if (isCFile)
- {
- cFiles[(*si)->GetFullPath()] = *si ;
- }
- else
+ std::string fullPath = (*si)->GetFullPath();
+
+ if(isCFile)
{
- otherFiles.insert((*si)->GetFullPath());
+ cFiles.push_back(fullPath);
}
+
+ CbpUnit &cbpUnit = allFiles[fullPath];
+ cbpUnit.Targets.push_back(*ti);
}
}
default: // intended fallthrough
@@ -469,62 +450,69 @@ void cmExtraCodeBlocksGenerator
}
}
+ std::vector<std::string> headerExts =
+ this->GlobalGenerator->GetCMakeInstance()->GetHeaderExtensions();
+
// The following loop tries to add header files matching to implementation
- // files to the project. It does that by iterating over all source files,
+ // files to the project. It does that by iterating over all
+ // C/C++ source files,
// replacing the file name extension with ".h" and checks whether such a
// file exists. If it does, it is inserted into the map of files.
// A very similar version of that code exists also in the kdevelop
// project generator.
- for (std::map<std::string, cmSourceFile*>::const_iterator
+ for (std::vector<std::string>::const_iterator
sit=cFiles.begin();
sit!=cFiles.end();
++sit)
{
- std::string headerBasename=cmSystemTools::GetFilenamePath(sit->first);
+ std::string const& fileName = *sit;
+ std::string headerBasename=cmSystemTools::GetFilenamePath(fileName);
headerBasename+="/";
- headerBasename+=cmSystemTools::GetFilenameWithoutExtension(sit->first);
+ headerBasename+=cmSystemTools::GetFilenameWithoutExtension(fileName);
// check if there's a matching header around
for(std::vector<std::string>::const_iterator
- ext = mf->GetHeaderExtensions().begin();
- ext != mf->GetHeaderExtensions().end();
+ ext = headerExts.begin();
+ ext != headerExts.end();
++ext)
{
std::string hname=headerBasename;
hname += ".";
hname += *ext;
// if it's already in the set, don't check if it exists on disk
- std::set<std::string>::const_iterator headerIt=otherFiles.find(hname);
- if (headerIt != otherFiles.end())
+ if (allFiles.find(hname) != allFiles.end())
{
break;
}
if(cmSystemTools::FileExists(hname.c_str()))
{
- otherFiles.insert(hname);
+ allFiles[hname].Targets = allFiles[fileName].Targets;
break;
}
}
}
// insert all source files in the CodeBlocks project
- // first the C/C++ implementation files, then all others
- for (std::map<std::string, cmSourceFile*>::const_iterator
- sit=cFiles.begin();
- sit!=cFiles.end();
+ for (all_files_map_t::const_iterator
+ sit=allFiles.begin();
+ sit!=allFiles.end();
++sit)
{
- fout<<" <Unit filename=\""<< sit->first <<"\">\n"
- " </Unit>\n";
- }
- for (std::set<std::string>::const_iterator
- sit=otherFiles.begin();
- sit!=otherFiles.end();
- ++sit)
- {
- fout<<" <Unit filename=\""<< sit->c_str() <<"\">\n"
- " </Unit>\n";
+ std::string const& unitFilename = sit->first;
+ CbpUnit const& unit = sit->second;
+
+ fout<<" <Unit filename=\""<< cmXMLSafe(unitFilename) <<"\">\n";
+
+ for(std::vector<const cmGeneratorTarget*>::const_iterator ti =
+ unit.Targets.begin();
+ ti != unit.Targets.end(); ++ti)
+ {
+ std::string const& targetName = (*ti)->GetName();
+ fout<<" <Option target=\""<< cmXMLSafe(targetName) <<"\"/>\n";
+ }
+
+ fout<<" </Unit>\n";
}
// Add CMakeLists.txt
@@ -537,14 +525,15 @@ void cmExtraCodeBlocksGenerator
// Write a dummy file for OBJECT libraries, so C::B can reference some file
std::string cmExtraCodeBlocksGenerator::CreateDummyTargetFile(
- cmMakefile* mf, cmTarget* target) const
+ cmLocalGenerator* lg,
+ cmGeneratorTarget* target) const
{
// this file doesn't seem to be used by C::B in custom makefile mode,
// but we generate a unique file for each OBJECT library so in case
// C::B uses it in some way, the targets don't interfere with each other.
- std::string filename = mf->GetCurrentOutputDirectory();
+ std::string filename = lg->GetCurrentBinaryDirectory();
filename += "/";
- filename += mf->GetLocalGenerator()->GetTargetDirectory(*target);
+ filename += lg->GetTargetDirectory(target);
filename += "/";
filename += target->GetName();
filename += ".objlib";
@@ -562,21 +551,22 @@ std::string cmExtraCodeBlocksGenerator::CreateDummyTargetFile(
// Generate the xml code for one target.
void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
- const char* targetName,
- cmTarget* target,
+ const std::string& targetName,
+ cmGeneratorTarget* target,
const char* make,
- const cmMakefile* makefile,
+ const cmLocalGenerator* lg,
const char* compiler)
{
- std::string makefileName = makefile->GetStartOutputDirectory();
+ cmMakefile const* makefile = lg->GetMakefile();
+ std::string makefileName = lg->GetCurrentBinaryDirectory();
makefileName += "/Makefile";
fout<<" <Target title=\"" << targetName << "\">\n";
if (target!=0)
{
int cbTargetType = this->GetCBTargetType(target);
- std::string workingDir = makefile->GetStartOutputDirectory();
- if ( target->GetType()==cmTarget::EXECUTABLE)
+ std::string workingDir = lg->GetCurrentBinaryDirectory();
+ if ( target->GetType()==cmState::EXECUTABLE)
{
// Determine the directory where the executable target is created, and
// set the working directory to this dir.
@@ -597,11 +587,11 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
}
}
- const char* buildType = makefile->GetDefinition("CMAKE_BUILD_TYPE");
+ std::string buildType = makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
std::string location;
- if ( target->GetType()==cmTarget::OBJECT_LIBRARY)
+ if ( target->GetType()==cmState::OBJECT_LIBRARY)
{
- location = this->CreateDummyTargetFile(const_cast<cmMakefile*>(makefile),
+ location = this->CreateDummyTargetFile(const_cast<cmLocalGenerator*>(lg),
target);
}
else
@@ -617,12 +607,9 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
" <Option compiler=\"" << compiler << "\" />\n"
" <Compiler>\n";
- cmGeneratorTarget *gtgt = this->GlobalGenerator
- ->GetGeneratorTarget(target);
-
// the compilerdefines for this target
std::vector<std::string> cdefs;
- target->GetCompileDefinitions(cdefs, buildType);
+ target->GetCompileDefinitions(cdefs, buildType, "C");
// Expand the list.
for(std::vector<std::string>::const_iterator di = cdefs.begin();
@@ -636,27 +623,17 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
std::set<std::string> uniqIncludeDirs;
std::vector<std::string> includes;
- target->GetMakefile()->GetLocalGenerator()->
- GetIncludeDirectories(includes, gtgt, "C", buildType);
- for(std::vector<std::string>::const_iterator dirIt=includes.begin();
- dirIt != includes.end();
- ++dirIt)
- {
- uniqIncludeDirs.insert(*dirIt);
- }
+ lg->GetIncludeDirectories(includes, target, "C", buildType);
+
+ uniqIncludeDirs.insert(includes.begin(), includes.end());
std::string systemIncludeDirs = makefile->GetSafeDefinition(
"CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS");
if (!systemIncludeDirs.empty())
{
std::vector<std::string> dirs;
- cmSystemTools::ExpandListArgument(systemIncludeDirs.c_str(), dirs);
- for(std::vector<std::string>::const_iterator dirIt=dirs.begin();
- dirIt != dirs.end();
- ++dirIt)
- {
- uniqIncludeDirs.insert(*dirIt);
- }
+ cmSystemTools::ExpandListArgument(systemIncludeDirs, dirs);
+ uniqIncludeDirs.insert(dirs.begin(), dirs.end());
}
systemIncludeDirs = makefile->GetSafeDefinition(
@@ -664,20 +641,15 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
if (!systemIncludeDirs.empty())
{
std::vector<std::string> dirs;
- cmSystemTools::ExpandListArgument(systemIncludeDirs.c_str(), dirs);
- for(std::vector<std::string>::const_iterator dirIt=dirs.begin();
- dirIt != dirs.end();
- ++dirIt)
- {
- uniqIncludeDirs.insert(*dirIt);
- }
+ cmSystemTools::ExpandListArgument(systemIncludeDirs, dirs);
+ uniqIncludeDirs.insert(dirs.begin(), dirs.end());
}
for(std::set<std::string>::const_iterator dirIt=uniqIncludeDirs.begin();
dirIt != uniqIncludeDirs.end();
++dirIt)
{
- fout <<" <Add directory=\"" << dirIt->c_str() << "\" />\n";
+ fout <<" <Add directory=\"" << *dirIt << "\" />\n";
}
fout<<" </Compiler>\n";
@@ -685,7 +657,7 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
else // e.g. all and the GLOBAL and UTILITY targets
{
fout<<" <Option working_dir=\""
- << makefile->GetStartOutputDirectory() << "\" />\n"
+ << lg->GetCurrentBinaryDirectory() << "\" />\n"
<<" <Option type=\"" << 4 << "\" />\n";
}
@@ -719,9 +691,7 @@ std::string cmExtraCodeBlocksGenerator::GetCBCompilerId(const cmMakefile* mf)
compilerIdVar = "CMAKE_C_COMPILER_ID";
}
- std::string hostSystemName = mf->GetSafeDefinition("CMAKE_HOST_SYSTEM_NAME");
- std::string systemName = mf->GetSafeDefinition("CMAKE_SYSTEM_NAME");
- std::string compilerId = mf->GetSafeDefinition(compilerIdVar.c_str());
+ std::string compilerId = mf->GetSafeDefinition(compilerIdVar);
std::string compiler = "gcc"; // default to gcc
if (compilerId == "MSVC")
{
@@ -739,7 +709,7 @@ std::string cmExtraCodeBlocksGenerator::GetCBCompilerId(const cmMakefile* mf)
{
compiler = "icc";
}
- else if (compilerId == "Watcom")
+ else if (compilerId == "Watcom" || compilerId == "OpenWatcom")
{
compiler = "ow";
}
@@ -752,9 +722,9 @@ std::string cmExtraCodeBlocksGenerator::GetCBCompilerId(const cmMakefile* mf)
// Translate the cmake target type into the CodeBlocks target type id
-int cmExtraCodeBlocksGenerator::GetCBTargetType(cmTarget* target)
+int cmExtraCodeBlocksGenerator::GetCBTargetType(cmGeneratorTarget* target)
{
- if ( target->GetType()==cmTarget::EXECUTABLE)
+ if ( target->GetType()==cmState::EXECUTABLE)
{
if ((target->GetPropertyAsBool("WIN32_EXECUTABLE"))
|| (target->GetPropertyAsBool("MACOSX_BUNDLE")))
@@ -766,13 +736,13 @@ int cmExtraCodeBlocksGenerator::GetCBTargetType(cmTarget* target)
return 1;
}
}
- else if (( target->GetType()==cmTarget::STATIC_LIBRARY)
- || (target->GetType()==cmTarget::OBJECT_LIBRARY))
+ else if (( target->GetType()==cmState::STATIC_LIBRARY)
+ || (target->GetType()==cmState::OBJECT_LIBRARY))
{
return 2;
}
- else if ((target->GetType()==cmTarget::SHARED_LIBRARY)
- || (target->GetType()==cmTarget::MODULE_LIBRARY))
+ else if ((target->GetType()==cmState::SHARED_LIBRARY)
+ || (target->GetType()==cmState::MODULE_LIBRARY))
{
return 3;
}
@@ -782,19 +752,23 @@ int cmExtraCodeBlocksGenerator::GetCBTargetType(cmTarget* target)
// Create the command line for building the given target using the selected
// make
std::string cmExtraCodeBlocksGenerator::BuildMakeCommand(
- const std::string& make, const char* makefile, const char* target)
+ const std::string& make, const char* makefile,
+ const std::string& target)
{
std::string command = make;
- if (strcmp(this->GlobalGenerator->GetName(), "NMake Makefiles")==0)
+ std::string generator = this->GlobalGenerator->GetName();
+ if (generator == "NMake Makefiles")
{
+ // For Windows ConvertToOutputPath already adds quotes when required.
+ // These need to be escaped, see
+ // http://public.kitware.com/Bug/view.php?id=13952
std::string makefileName = cmSystemTools::ConvertToOutputPath(makefile);
- command += " /NOLOGO /f &quot;";
- command += makefileName;
- command += "&quot; ";
+ command += " /NOLOGO /f ";
+ command += cmXMLSafe(makefileName).str();
command += " VERBOSE=1 ";
command += target;
}
- else if (strcmp(this->GlobalGenerator->GetName(), "MinGW Makefiles")==0)
+ else if (generator == "MinGW Makefiles")
{
// no escaping of spaces in this case, see
// http://public.kitware.com/Bug/view.php?id=10014
@@ -805,7 +779,7 @@ std::string cmExtraCodeBlocksGenerator::BuildMakeCommand(
command += " VERBOSE=1 ";
command += target;
}
- else if (strcmp(this->GlobalGenerator->GetName(), "Ninja")==0)
+ else if (generator == "Ninja")
{
command += " -v ";
command += target;
diff --git a/Source/cmExtraCodeBlocksGenerator.h b/Source/cmExtraCodeBlocksGenerator.h
index e0a64ca01..0c3846d35 100644
--- a/Source/cmExtraCodeBlocksGenerator.h
+++ b/Source/cmExtraCodeBlocksGenerator.h
@@ -17,7 +17,7 @@
class cmLocalGenerator;
class cmMakefile;
-class cmTarget;
+class cmGeneratorTarget;
class cmGeneratedFileStream;
/** \class cmExtraCodeBlocksGenerator
@@ -28,33 +28,38 @@ class cmExtraCodeBlocksGenerator : public cmExternalMakefileProjectGenerator
public:
cmExtraCodeBlocksGenerator();
- virtual const char* GetName() const
+ virtual std::string GetName() const
{ return cmExtraCodeBlocksGenerator::GetActualName();}
- static const char* GetActualName() { return "CodeBlocks";}
+ static std::string GetActualName() { return "CodeBlocks";}
static cmExternalMakefileProjectGenerator* New()
{ return new cmExtraCodeBlocksGenerator; }
/** Get the documentation entry for this generator. */
virtual void GetDocumentation(cmDocumentationEntry& entry,
- const char* fullName) const;
+ const std::string& fullName) const;
virtual void Generate();
private:
+ struct CbpUnit
+ {
+ std::vector<const cmGeneratorTarget*> Targets;
+ };
void CreateProjectFile(const std::vector<cmLocalGenerator*>& lgs);
void CreateNewProjectFile(const std::vector<cmLocalGenerator*>& lgs,
const std::string& filename);
- std::string CreateDummyTargetFile(cmMakefile* mf, cmTarget* target) const;
+ std::string CreateDummyTargetFile(cmLocalGenerator* lg,
+ cmGeneratorTarget* target) const;
std::string GetCBCompilerId(const cmMakefile* mf);
- int GetCBTargetType(cmTarget* target);
+ int GetCBTargetType(cmGeneratorTarget* target);
std::string BuildMakeCommand(const std::string& make, const char* makefile,
- const char* target);
+ const std::string& target);
void AppendTarget(cmGeneratedFileStream& fout,
- const char* targetName,
- cmTarget* target,
+ const std::string& targetName,
+ cmGeneratorTarget* target,
const char* make,
- const cmMakefile* makefile,
+ const cmLocalGenerator* lg,
const char* compiler);
};
diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx
new file mode 100644
index 000000000..67aa157a1
--- /dev/null
+++ b/Source/cmExtraCodeLiteGenerator.cxx
@@ -0,0 +1,474 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2004-2009 Kitware, Inc.
+ Copyright 2004 Alexander Neundorf (neundorf@kde.org)
+ Copyright 2013 Eran Ifrah (eran.ifrah@gmail.com)
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmExtraCodeLiteGenerator.h"
+#include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmLocalUnixMakefileGenerator3.h"
+#include "cmMakefile.h"
+#include "cmake.h"
+#include "cmSourceFile.h"
+#include "cmGeneratedFileStream.h"
+#include "cmSystemTools.h"
+
+#include <cmsys/SystemTools.hxx>
+#include <cmsys/SystemInformation.hxx>
+#include <cmsys/Directory.hxx>
+#include "cmStandardIncludes.h"
+#include "cmXMLSafe.h"
+
+//----------------------------------------------------------------------------
+void cmExtraCodeLiteGenerator::GetDocumentation(cmDocumentationEntry& entry,
+ const std::string&) const
+{
+ entry.Name = this->GetName();
+ entry.Brief = "Generates CodeLite project files.";
+}
+
+cmExtraCodeLiteGenerator::cmExtraCodeLiteGenerator()
+ : cmExternalMakefileProjectGenerator()
+ , ConfigName("NoConfig")
+ , CpuCount(2)
+{
+#if defined(_WIN32)
+ this->SupportedGlobalGenerators.push_back("MinGW Makefiles");
+ this->SupportedGlobalGenerators.push_back("NMake Makefiles");
+#endif
+ this->SupportedGlobalGenerators.push_back("Ninja");
+ this->SupportedGlobalGenerators.push_back("Unix Makefiles");
+}
+
+void cmExtraCodeLiteGenerator::Generate()
+{
+ // Hold root tree information for creating the workspace
+ std::string workspaceProjectName;
+ std::string workspaceOutputDir;
+ std::string workspaceFileName;
+ std::string workspaceSourcePath;
+ std::string lprjdebug;
+
+ cmGeneratedFileStream fout;
+
+ // loop projects and locate the root project.
+ // and extract the information for creating the worspace
+ for (std::map<std::string, std::vector<cmLocalGenerator*> >::const_iterator
+ it = this->GlobalGenerator->GetProjectMap().begin();
+ it!= this->GlobalGenerator->GetProjectMap().end();
+ ++it)
+ {
+ const cmMakefile* mf =it->second[0]->GetMakefile();
+ this->ConfigName = GetConfigurationName( mf );
+
+ if (strcmp(it->second[0]->GetCurrentBinaryDirectory(),
+ it->second[0]->GetBinaryDirectory()) == 0)
+ {
+ workspaceOutputDir = it->second[0]->GetCurrentBinaryDirectory();
+ workspaceProjectName = it->second[0]->GetProjectName();
+ workspaceSourcePath = it->second[0]->GetSourceDirectory();
+ workspaceFileName = workspaceOutputDir+"/";
+ workspaceFileName += workspaceProjectName + ".workspace";
+ this->WorkspacePath = it->second[0]->GetCurrentBinaryDirectory();;
+
+ fout.Open(workspaceFileName.c_str(), false, false);
+ fout << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<CodeLite_Workspace Name=\"" << workspaceProjectName << "\" >\n";
+ }
+ }
+
+ // for each sub project in the workspace create a codelite project
+ for (std::map<std::string, std::vector<cmLocalGenerator*> >::const_iterator
+ it = this->GlobalGenerator->GetProjectMap().begin();
+ it!= this->GlobalGenerator->GetProjectMap().end();
+ ++it)
+ {
+ // retrive project information
+ std::string outputDir = it->second[0]->GetCurrentBinaryDirectory();
+ std::string projectName = it->second[0]->GetProjectName();
+ std::string filename = outputDir + "/" + projectName + ".project";
+
+ // Make the project file relative to the workspace
+ filename = cmSystemTools::RelativePath(this->WorkspacePath.c_str(),
+ filename.c_str());
+
+ // create a project file
+ this->CreateProjectFile(it->second);
+ fout << " <Project Name=\"" << projectName << "\" Path=\""
+ << filename << "\" Active=\"No\"/>\n";
+ lprjdebug += "<Project Name=\"" + projectName
+ + "\" ConfigName=\"" + this->ConfigName + "\"/>\n";
+ }
+
+ fout << " <BuildMatrix>\n"
+ " <WorkspaceConfiguration Name=\""
+ << this->ConfigName << "\" Selected=\"yes\">\n"
+ " " << lprjdebug << ""
+ " </WorkspaceConfiguration>\n"
+ " </BuildMatrix>\n"
+ "</CodeLite_Workspace>\n";
+}
+
+/* create the project file */
+void cmExtraCodeLiteGenerator::CreateProjectFile(
+ const std::vector<cmLocalGenerator*>& lgs)
+{
+ std::string outputDir = lgs[0]->GetCurrentBinaryDirectory();
+ std::string projectName = lgs[0]->GetProjectName();
+ std::string filename = outputDir + "/";
+
+ filename += projectName + ".project";
+ this->CreateNewProjectFile(lgs, filename);
+}
+
+void cmExtraCodeLiteGenerator
+::CreateNewProjectFile(const std::vector<cmLocalGenerator*>& lgs,
+ const std::string& filename)
+{
+ const cmMakefile* mf=lgs[0]->GetMakefile();
+ cmGeneratedFileStream fout(filename.c_str());
+ if(!fout)
+ {
+ return;
+ }
+
+ ////////////////////////////////////
+ fout << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<CodeLite_Project Name=\"" << lgs[0]->GetProjectName()
+ << "\" InternalType=\"\">\n";
+
+ // Collect all used source files in the project
+ // Sort them into two containers, one for C/C++ implementation files
+ // which may have an acompanying header, one for all other files
+ std::string projectType;
+
+ std::vector<std::string> srcExts =
+ this->GlobalGenerator->GetCMakeInstance()->GetSourceExtensions();
+ std::vector<std::string> headerExts =
+ this->GlobalGenerator->GetCMakeInstance()->GetHeaderExtensions();
+
+ std::map<std::string, cmSourceFile*> cFiles;
+ std::set<std::string> otherFiles;
+ for (std::vector<cmLocalGenerator*>::const_iterator lg=lgs.begin();
+ lg!=lgs.end(); lg++)
+ {
+ cmMakefile* makefile=(*lg)->GetMakefile();
+ std::vector<cmGeneratorTarget*> targets=(*lg)->GetGeneratorTargets();
+ for (std::vector<cmGeneratorTarget*>::iterator ti = targets.begin();
+ ti != targets.end(); ti++)
+ {
+
+ switch((*ti)->GetType())
+ {
+ case cmState::EXECUTABLE:
+ {
+ projectType = "Executable";
+ }
+ break;
+ case cmState::STATIC_LIBRARY:
+ {
+ projectType = "Static Library";
+ }
+ break;
+ case cmState::SHARED_LIBRARY:
+ {
+ projectType = "Dynamic Library";
+ }
+ break;
+ case cmState::MODULE_LIBRARY:
+ {
+ projectType = "Dynamic Library";
+ }
+ break;
+ default: // intended fallthrough
+ break;
+ }
+
+ switch((*ti)->GetType())
+ {
+ case cmState::EXECUTABLE:
+ case cmState::STATIC_LIBRARY:
+ case cmState::SHARED_LIBRARY:
+ case cmState::MODULE_LIBRARY:
+ {
+ std::vector<cmSourceFile*> sources;
+ cmGeneratorTarget* gt = *ti;
+ gt->GetSourceFiles(sources,
+ makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
+ for (std::vector<cmSourceFile*>::const_iterator si=sources.begin();
+ si!=sources.end(); si++)
+ {
+ // check whether it is a C/C++ implementation file
+ bool isCFile = false;
+ std::string lang = (*si)->GetLanguage();
+ if (lang == "C" || lang == "CXX")
+ {
+ std::string srcext = (*si)->GetExtension();
+ for(std::vector<std::string>::const_iterator
+ ext = srcExts.begin(); ext != srcExts.end(); ++ext)
+ {
+ if (srcext == *ext)
+ {
+ isCFile = true;
+ break;
+ }
+ }
+ }
+
+ // then put it accordingly into one of the two containers
+ if (isCFile)
+ {
+ cFiles[(*si)->GetFullPath()] = *si ;
+ }
+ else
+ {
+ otherFiles.insert((*si)->GetFullPath());
+ }
+ }
+ }
+ default: // intended fallthrough
+ break;
+ }
+ }
+ }
+
+ // The following loop tries to add header files matching to implementation
+ // files to the project. It does that by iterating over all source files,
+ // replacing the file name extension with ".h" and checks whether such a
+ // file exists. If it does, it is inserted into the map of files.
+ // A very similar version of that code exists also in the kdevelop
+ // project generator.
+ for (std::map<std::string, cmSourceFile*>::const_iterator
+ sit=cFiles.begin();
+ sit!=cFiles.end();
+ ++sit)
+ {
+ std::string headerBasename=cmSystemTools::GetFilenamePath(sit->first);
+ headerBasename+="/";
+ headerBasename+=cmSystemTools::GetFilenameWithoutExtension(sit->first);
+
+ // check if there's a matching header around
+ for(std::vector<std::string>::const_iterator
+ ext = headerExts.begin();
+ ext != headerExts.end();
+ ++ext)
+ {
+ std::string hname=headerBasename;
+ hname += ".";
+ hname += *ext;
+ // if it's already in the set, don't check if it exists on disk
+ std::set<std::string>::const_iterator headerIt=otherFiles.find(hname);
+ if (headerIt != otherFiles.end())
+ {
+ break;
+ }
+
+ if(cmSystemTools::FileExists(hname.c_str()))
+ {
+ otherFiles.insert(hname);
+ break;
+ }
+ }
+ }
+
+ // Get the project path ( we need it later to convert files to
+ // their relative path)
+ std::string projectPath = cmSystemTools::GetFilenamePath(filename);
+
+ // Create 2 virtual folders: src and include
+ // and place all the implementation files into the src
+ // folder, the rest goes to the include folder
+ fout<< " <VirtualDirectory Name=\"src\">\n";
+
+ // insert all source files in the codelite project
+ // first the C/C++ implementation files, then all others
+ for (std::map<std::string, cmSourceFile*>::const_iterator
+ sit=cFiles.begin();
+ sit!=cFiles.end();
+ ++sit)
+ {
+ std::string relativePath =
+ cmSystemTools::RelativePath(projectPath.c_str(), sit->first.c_str());
+ fout<< " <File Name=\"" << relativePath << "\"/>\n";
+ }
+ fout<< " </VirtualDirectory>\n";
+ fout<< " <VirtualDirectory Name=\"include\">\n";
+ for (std::set<std::string>::const_iterator
+ sit=otherFiles.begin();
+ sit!=otherFiles.end();
+ ++sit)
+ {
+ std::string relativePath =
+ cmSystemTools::RelativePath(projectPath.c_str(), sit->c_str());
+ fout << " <File Name=\"" << relativePath << "\"/>\n";
+ }
+ fout << " </VirtualDirectory>\n";
+
+ // Get the number of CPUs. We use this information for the make -jN
+ // command
+ cmsys::SystemInformation info;
+ info.RunCPUCheck();
+
+ this->CpuCount = info.GetNumberOfLogicalCPU() *
+ info.GetNumberOfPhysicalCPU();
+
+ std::string cleanCommand = GetCleanCommand(mf);
+ std::string buildCommand = GetBuildCommand(mf);
+ std::string rebuildCommand = GetRebuildCommand(mf);
+ std::string singleFileCommand = GetSingleFileBuildCommand(mf);
+
+ std::string codeliteCompilerName = this->GetCodeLiteCompilerName(mf);
+
+ fout << "\n"
+ " <Settings Type=\"" << projectType << "\">\n"
+ " <Configuration Name=\"" << this->ConfigName << "\" CompilerType=\""
+ << codeliteCompilerName << "\" DebuggerType=\"GNU gdb debugger\" "
+ "Type=\""
+ << projectType << "\" BuildCmpWithGlobalSettings=\"append\" "
+ "BuildLnkWithGlobalSettings=\"append\" "
+ "BuildResWithGlobalSettings=\"append\">\n"
+ " <Compiler Options=\"-g\" "
+ "Required=\"yes\" PreCompiledHeader=\"\">\n"
+ " <IncludePath Value=\".\"/>\n"
+ " </Compiler>\n"
+ " <Linker Options=\"\" Required=\"yes\"/>\n"
+ " <ResourceCompiler Options=\"\" Required=\"no\"/>\n"
+ " <General OutputFile=\"$(IntermediateDirectory)/$(ProjectName)\" "
+ "IntermediateDirectory=\"./\" Command=\"./$(ProjectName)\" "
+ "CommandArguments=\"\" WorkingDirectory=\"$(IntermediateDirectory)\" "
+ "PauseExecWhenProcTerminates=\"yes\"/>\n"
+ " <Debugger IsRemote=\"no\" RemoteHostName=\"\" "
+ "RemoteHostPort=\"\" DebuggerPath=\"\">\n"
+ " <PostConnectCommands/>\n"
+ " <StartupCommands/>\n"
+ " </Debugger>\n"
+ " <PreBuild/>\n"
+ " <PostBuild/>\n"
+ " <CustomBuild Enabled=\"yes\">\n"
+ " <RebuildCommand>" << rebuildCommand << "</RebuildCommand>\n"
+ " <CleanCommand>" << cleanCommand << "</CleanCommand>\n"
+ " <BuildCommand>" << buildCommand << "</BuildCommand>\n"
+ " <SingleFileCommand>" << singleFileCommand
+ << "</SingleFileCommand>\n"
+ " <PreprocessFileCommand/>\n"
+ " <WorkingDirectory>$(WorkspacePath)</WorkingDirectory>\n"
+ " </CustomBuild>\n"
+ " <AdditionalRules>\n"
+ " <CustomPostBuild/>\n"
+ " <CustomPreBuild/>\n"
+ " </AdditionalRules>\n"
+ " </Configuration>\n"
+ " <GlobalSettings>\n"
+ " <Compiler Options=\"\">\n"
+ " <IncludePath Value=\".\"/>\n"
+ " </Compiler>\n"
+ " <Linker Options=\"\">\n"
+ " <LibraryPath Value=\".\"/>\n"
+ " </Linker>\n"
+ " <ResourceCompiler Options=\"\"/>\n"
+ " </GlobalSettings>\n"
+ " </Settings>\n"
+ "</CodeLite_Project>\n";
+}
+
+std::string
+cmExtraCodeLiteGenerator::GetCodeLiteCompilerName(const cmMakefile* mf) const
+{
+ // figure out which language to use
+ // for now care only for C and C++
+ std::string compilerIdVar = "CMAKE_CXX_COMPILER_ID";
+ if (this->GlobalGenerator->GetLanguageEnabled("CXX") == false)
+ {
+ compilerIdVar = "CMAKE_C_COMPILER_ID";
+ }
+
+ std::string compilerId = mf->GetSafeDefinition(compilerIdVar);
+ std::string compiler = "gnu g++"; // default to g++
+
+ // Since we need the compiler for parsing purposes only
+ // it does not matter if we use clang or clang++, same as
+ // "gnu gcc" vs "gnu g++"
+ if (compilerId == "MSVC")
+ {
+ compiler = "VC++";
+ }
+ else if (compilerId == "Clang")
+ {
+ compiler = "clang++";
+ }
+ else if (compilerId == "GNU")
+ {
+ compiler = "gnu g++";
+ }
+ return compiler;
+}
+
+std::string
+cmExtraCodeLiteGenerator::GetConfigurationName(const cmMakefile* mf) const
+{
+ std::string confName = mf->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ // Trim the configuration name from whitespaces (left and right)
+ confName.erase(0, confName.find_first_not_of(" \t\r\v\n"));
+ confName.erase(confName.find_last_not_of(" \t\r\v\n")+1);
+ if ( confName.empty() )
+ {
+ confName = "NoConfig";
+ }
+ return confName;
+}
+
+std::string
+cmExtraCodeLiteGenerator::GetBuildCommand(const cmMakefile* mf) const
+{
+ std::string generator = mf->GetSafeDefinition("CMAKE_GENERATOR");
+ std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
+ std::string buildCommand = make; // Default
+ if ( generator == "NMake Makefiles" ||
+ generator == "Ninja" )
+ {
+ buildCommand = make;
+ }
+ else if ( generator == "MinGW Makefiles" ||
+ generator == "Unix Makefiles" )
+ {
+ std::ostringstream ss;
+ ss << make << " -j " << this->CpuCount;
+ buildCommand = ss.str();
+ }
+ return buildCommand;
+}
+
+std::string
+cmExtraCodeLiteGenerator::GetCleanCommand(const cmMakefile* mf) const
+{
+ return GetBuildCommand(mf) + " clean";
+}
+
+std::string
+cmExtraCodeLiteGenerator::GetRebuildCommand(const cmMakefile* mf) const
+{
+ return GetCleanCommand(mf) + cmXMLSafe(" && ").str() + GetBuildCommand(mf);
+}
+
+std::string
+cmExtraCodeLiteGenerator::GetSingleFileBuildCommand
+(const cmMakefile* mf) const
+{
+ std::string buildCommand;
+ std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
+ std::string generator = mf->GetSafeDefinition("CMAKE_GENERATOR");
+ if ( generator == "Unix Makefiles" || generator == "MinGW Makefiles" )
+ {
+ std::ostringstream ss;
+ ss << make << " -f$(ProjectPath)/Makefile $(CurrentFileName).cpp.o";
+ buildCommand = ss.str();
+ }
+ return buildCommand;
+}
diff --git a/Source/cmExtraCodeLiteGenerator.h b/Source/cmExtraCodeLiteGenerator.h
new file mode 100644
index 000000000..6b4965d5a
--- /dev/null
+++ b/Source/cmExtraCodeLiteGenerator.h
@@ -0,0 +1,54 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2004-2009 Kitware, Inc.
+ Copyright 2004 Alexander Neundorf (neundorf@kde.org)
+ Copyright 2013 Eran Ifrah (eran.ifrah@gmail.com)
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmGlobalCodeLiteGenerator_h
+#define cmGlobalCodeLiteGenerator_h
+
+#include "cmExternalMakefileProjectGenerator.h"
+
+class cmLocalGenerator;
+
+class cmExtraCodeLiteGenerator : public cmExternalMakefileProjectGenerator
+{
+protected:
+ std::string ConfigName;
+ std::string WorkspacePath;
+ unsigned int CpuCount;
+
+protected:
+ std::string GetCodeLiteCompilerName(const cmMakefile* mf) const;
+ std::string GetConfigurationName( const cmMakefile* mf ) const;
+ std::string GetBuildCommand(const cmMakefile* mf) const;
+ std::string GetCleanCommand(const cmMakefile* mf) const;
+ std::string GetRebuildCommand(const cmMakefile* mf) const;
+ std::string GetSingleFileBuildCommand(const cmMakefile* mf) const;
+public:
+ cmExtraCodeLiteGenerator();
+
+ virtual std::string GetName() const
+ { return cmExtraCodeLiteGenerator::GetActualName();}
+ static std::string GetActualName() { return "CodeLite";}
+ static cmExternalMakefileProjectGenerator* New()
+ { return new cmExtraCodeLiteGenerator; }
+ /** Get the documentation entry for this generator. */
+ virtual void GetDocumentation(cmDocumentationEntry& entry,
+ const std::string& fullName) const;
+
+ virtual void Generate();
+ void CreateProjectFile(const std::vector<cmLocalGenerator*>& lgs);
+
+ void CreateNewProjectFile(const std::vector<cmLocalGenerator*>& lgs,
+ const std::string& filename);
+};
+
+#endif
diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx
index d80e775bf..aedf6f41b 100644
--- a/Source/cmExtraEclipseCDT4Generator.cxx
+++ b/Source/cmExtraEclipseCDT4Generator.cxx
@@ -16,6 +16,7 @@
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmGeneratedFileStream.h"
+#include "cmState.h"
#include "cmTarget.h"
#include "cmSourceFile.h"
@@ -40,28 +41,46 @@ cmExtraEclipseCDT4Generator
this->SupportsVirtualFolders = true;
this->GenerateLinkedResources = true;
this->SupportsGmakeErrorParser = true;
+ this->SupportsMachO64Parser = true;
}
//----------------------------------------------------------------------------
void cmExtraEclipseCDT4Generator
-::GetDocumentation(cmDocumentationEntry& entry, const char*) const
+::GetDocumentation(cmDocumentationEntry& entry, const std::string&) const
{
entry.Name = this->GetName();
entry.Brief = "Generates Eclipse CDT 4.0 project files.";
- entry.Full =
- "Project files for Eclipse will be created in the top directory. "
- "In out of source builds, a linked resource to the top level source "
- "directory will be created. "
- "Additionally a hierarchy of makefiles is generated into the "
- "build tree. The appropriate make program can build the project through "
- "the default make target. A \"make install\" target is also provided.";
+}
+
+//----------------------------------------------------------------------------
+void cmExtraEclipseCDT4Generator
+::EnableLanguage(std::vector<std::string> const& languages,
+ cmMakefile *, bool)
+{
+ for (std::vector<std::string>::const_iterator lit = languages.begin();
+ lit != languages.end(); ++lit)
+ {
+ if (*lit == "CXX")
+ {
+ this->Natures.insert("org.eclipse.cdt.core.ccnature");
+ this->Natures.insert("org.eclipse.cdt.core.cnature");
+ }
+ else if (*lit == "C")
+ {
+ this->Natures.insert("org.eclipse.cdt.core.cnature");
+ }
+ else if (*lit == "Java")
+ {
+ this->Natures.insert("org.eclipse.jdt.core.javanature");
+ }
+ }
}
//----------------------------------------------------------------------------
void cmExtraEclipseCDT4Generator::Generate()
{
- const cmMakefile* mf
- = this->GlobalGenerator->GetLocalGenerators()[0]->GetMakefile();
+ cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
+ const cmMakefile* mf = lg->GetMakefile();
std::string eclipseVersion = mf->GetSafeDefinition("CMAKE_ECLIPSE_VERSION");
cmsys::RegularExpression regex(".*([0-9]+\\.[0-9]+).*");
@@ -77,6 +96,7 @@ void cmExtraEclipseCDT4Generator::Generate()
if (version < 3006) // 3.6 is Helios
{
this->SupportsVirtualFolders = false;
+ this->SupportsMachO64Parser = false;
}
if (version < 3007) // 3.7 is Indigo
{
@@ -86,8 +106,8 @@ void cmExtraEclipseCDT4Generator::Generate()
}
// TODO: Decide if these are local or member variables
- this->HomeDirectory = mf->GetHomeDirectory();
- this->HomeOutputDirectory = mf->GetHomeOutputDirectory();
+ this->HomeDirectory = lg->GetSourceDirectory();
+ this->HomeOutputDirectory = lg->GetBinaryDirectory();
this->GenerateLinkedResources = mf->IsOn(
"CMAKE_ECLIPSE_GENERATE_LINKED_RESOURCES");
@@ -106,8 +126,8 @@ void cmExtraEclipseCDT4Generator::Generate()
"Enable CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT instead.");
}
- if (cmSystemTools::IsSubDirectory(this->HomeOutputDirectory.c_str(),
- this->HomeDirectory.c_str()))
+ if (cmSystemTools::IsSubDirectory(this->HomeOutputDirectory,
+ this->HomeDirectory))
{
mf->IssueMessage(cmake::WARNING, "The build directory is a subdirectory "
"of the source directory.\n"
@@ -137,9 +157,8 @@ void cmExtraEclipseCDT4Generator::CreateSourceProjectFile()
assert(this->HomeDirectory != this->HomeOutputDirectory);
// set up the project name: <project>-Source@<baseSourcePathName>
- const cmMakefile* mf
- = this->GlobalGenerator->GetLocalGenerators()[0]->GetMakefile();
- std::string name = this->GenerateProjectName(mf->GetProjectName(), "Source",
+ cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
+ std::string name = this->GenerateProjectName(lg->GetProjectName(), "Source",
this->GetPathBasename(this->HomeDirectory));
const std::string filename = this->HomeDirectory + "/.project";
@@ -177,8 +196,11 @@ void cmExtraEclipseCDT4Generator::CreateSourceProjectFile()
//----------------------------------------------------------------------------
void cmExtraEclipseCDT4Generator::AddEnvVar(cmGeneratedFileStream& fout,
- const char* envVar, cmMakefile* mf)
+ const char* envVar,
+ cmLocalGenerator* lg)
{
+ cmMakefile* mf = lg->GetMakefile();
+
// get the variables from the environment and from the cache and then
// figure out which one to use:
@@ -186,8 +208,8 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(cmGeneratedFileStream& fout,
std::string cacheEntryName = "CMAKE_ECLIPSE_ENVVAR_";
cacheEntryName += envVar;
- const char* cacheValue = mf->GetCacheManager()->GetCacheValue(
- cacheEntryName.c_str());
+ const char* cacheValue = lg->GetState()->GetInitializedCacheValue(
+ cacheEntryName);
// now we have both, decide which one to use
std::string valueToUse;
@@ -201,10 +223,10 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(cmGeneratedFileStream& fout,
// The variable is in the env, but not in the cache. Use it and put it
// in the cache
valueToUse = envVarValue;
- mf->AddCacheDefinition(cacheEntryName.c_str(), valueToUse.c_str(),
- cacheEntryName.c_str(), cmCacheManager::STRING,
+ mf->AddCacheDefinition(cacheEntryName, valueToUse.c_str(),
+ cacheEntryName.c_str(), cmState::STRING,
true);
- mf->GetCacheManager()->SaveCache(mf->GetHomeOutputDirectory());
+ mf->GetCMakeInstance()->SaveCache(lg->GetBinaryDirectory());
}
else if (envVarValue==0 && cacheValue!=0)
{
@@ -222,10 +244,10 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(cmGeneratedFileStream& fout,
if (valueToUse.find(envVarValue) == std::string::npos)
{
valueToUse = envVarValue;
- mf->AddCacheDefinition(cacheEntryName.c_str(), valueToUse.c_str(),
- cacheEntryName.c_str(), cmCacheManager::STRING,
+ mf->AddCacheDefinition(cacheEntryName, valueToUse.c_str(),
+ cacheEntryName.c_str(), cmState::STRING,
true);
- mf->GetCacheManager()->SaveCache(mf->GetHomeOutputDirectory());
+ mf->GetCMakeInstance()->SaveCache(lg->GetBinaryDirectory());
}
}
@@ -239,8 +261,8 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(cmGeneratedFileStream& fout,
//----------------------------------------------------------------------------
void cmExtraEclipseCDT4Generator::CreateProjectFile()
{
- cmMakefile* mf
- = this->GlobalGenerator->GetLocalGenerators()[0]->GetMakefile();
+ cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
+ cmMakefile* mf = lg->GetMakefile();
const std::string filename = this->HomeOutputDirectory + "/.project";
@@ -260,7 +282,7 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile()
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<projectDescription>\n"
"\t<name>" <<
- this->GenerateProjectName(mf->GetProjectName(),
+ this->GenerateProjectName(lg->GetProjectName(),
mf->GetSafeDefinition("CMAKE_BUILD_TYPE"),
this->GetPathBasename(this->HomeOutputDirectory))
<< "</name>\n"
@@ -341,17 +363,17 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile()
// but not necessarily when eclipse is open
if (compilerId == "MSVC")
{
- AddEnvVar(fout, "PATH", mf);
- AddEnvVar(fout, "INCLUDE", mf);
- AddEnvVar(fout, "LIB", mf);
- AddEnvVar(fout, "LIBPATH", mf);
+ AddEnvVar(fout, "PATH", lg);
+ AddEnvVar(fout, "INCLUDE", lg);
+ AddEnvVar(fout, "LIB", lg);
+ AddEnvVar(fout, "LIBPATH", lg);
}
else if (compilerId == "Intel")
{
// if the env.var is set, use this one and put it in the cache
// if the env.var is not set, but the value is in the cache,
// use it from the cache:
- AddEnvVar(fout, "INTEL_LICENSE_FILE", mf);
+ AddEnvVar(fout, "INTEL_LICENSE_FILE", lg);
}
fout <<
"</value>\n"
@@ -440,13 +462,28 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile()
// set natures for c/c++ projects
fout <<
"\t<natures>\n"
- // TODO: ccnature only if it is c++ ???
- "\t\t<nature>org.eclipse.cdt.core.ccnature</nature>\n"
"\t\t<nature>org.eclipse.cdt.make.core.makeNature</nature>\n"
- "\t\t<nature>org.eclipse.cdt.make.core.ScannerConfigNature</nature>\n"
- "\t\t<nature>org.eclipse.cdt.core.cnature</nature>\n"
- "\t</natures>\n"
- ;
+ "\t\t<nature>org.eclipse.cdt.make.core.ScannerConfigNature</nature>\n";
+
+ for (std::set<std::string>::const_iterator nit=this->Natures.begin();
+ nit != this->Natures.end(); ++nit)
+ {
+ fout << "\t\t<nature>" << *nit << "</nature>\n";
+ }
+
+ if (const char *extraNaturesProp = mf->GetState()
+ ->GetGlobalProperty("ECLIPSE_EXTRA_NATURES"))
+ {
+ std::vector<std::string> extraNatures;
+ cmSystemTools::ExpandListArgument(extraNaturesProp, extraNatures);
+ for (std::vector<std::string>::const_iterator nit = extraNatures.begin();
+ nit != extraNatures.end(); ++nit)
+ {
+ fout << "\t\t<nature>" << *nit << "</nature>\n";
+ }
+ }
+
+ fout << "\t</natures>\n";
fout << "\t<linkedResources>\n";
// create linked resources
@@ -460,10 +497,10 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile()
std::string sourceLinkedResourceName = "[Source directory]";
std::string linkSourceDirectory = this->GetEclipsePath(
- mf->GetStartDirectory());
+ lg->GetCurrentSourceDirectory());
// .project dir can't be subdir of a linked resource dir
- if (!cmSystemTools::IsSubDirectory(this->HomeOutputDirectory.c_str(),
- linkSourceDirectory.c_str()))
+ if (!cmSystemTools::IsSubDirectory(this->HomeOutputDirectory,
+ linkSourceDirectory))
{
this->AppendLinkedResource(fout, sourceLinkedResourceName,
this->GetEclipsePath(linkSourceDirectory),
@@ -499,24 +536,26 @@ void cmExtraEclipseCDT4Generator::CreateLinksForTargets(
++lgIt)
{
cmMakefile* makefile = (*lgIt)->GetMakefile();
- const cmTargets& targets = makefile->GetTargets();
+ const std::vector<cmGeneratorTarget*> targets =
+ (*lgIt)->GetGeneratorTargets();
- for(cmTargets::const_iterator ti=targets.begin(); ti!=targets.end();++ti)
+ for(std::vector<cmGeneratorTarget*>::const_iterator ti=targets.begin();
+ ti!=targets.end();++ti)
{
std::string linkName2 = linkName;
linkName2 += "/";
- switch(ti->second.GetType())
+ switch((*ti)->GetType())
{
- case cmTarget::EXECUTABLE:
- case cmTarget::STATIC_LIBRARY:
- case cmTarget::SHARED_LIBRARY:
- case cmTarget::MODULE_LIBRARY:
- case cmTarget::OBJECT_LIBRARY:
+ case cmState::EXECUTABLE:
+ case cmState::STATIC_LIBRARY:
+ case cmState::SHARED_LIBRARY:
+ case cmState::MODULE_LIBRARY:
+ case cmState::OBJECT_LIBRARY:
{
- const char* prefix = (ti->second.GetType()==cmTarget::EXECUTABLE ?
+ const char* prefix = ((*ti)->GetType()==cmState::EXECUTABLE ?
"[exe] " : "[lib] ");
linkName2 += prefix;
- linkName2 += ti->first;
+ linkName2 += (*ti)->GetName();
this->AppendLinkedResource(fout, linkName2, "virtual:/virtual",
VirtualFolder);
if (!this->GenerateLinkedResources)
@@ -525,17 +564,19 @@ void cmExtraEclipseCDT4Generator::CreateLinksForTargets(
}
std::vector<cmSourceGroup> sourceGroups=makefile->GetSourceGroups();
// get the files from the source lists then add them to the groups
- cmTarget* tgt = const_cast<cmTarget*>(&ti->second);
- std::vector<cmSourceFile*>const & files = tgt->GetSourceFiles();
+ cmGeneratorTarget* gt = const_cast<cmGeneratorTarget*>(*ti);
+ std::vector<cmSourceFile*> files;
+ gt->GetSourceFiles(files,
+ makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
for(std::vector<cmSourceFile*>::const_iterator sfIt = files.begin();
sfIt != files.end();
sfIt++)
{
// Add the file to the list of sources.
std::string source = (*sfIt)->GetFullPath();
- cmSourceGroup& sourceGroup =
+ cmSourceGroup* sourceGroup =
makefile->FindSourceGroup(source.c_str(), sourceGroups);
- sourceGroup.AssignSource(*sfIt);
+ sourceGroup->AssignSource(*sfIt);
}
for(std::vector<cmSourceGroup>::iterator sgIt = sourceGroups.begin();
@@ -555,13 +596,14 @@ void cmExtraEclipseCDT4Generator::CreateLinksForTargets(
++fileIt)
{
std::string fullPath = (*fileIt)->GetFullPath();
- if (!cmSystemTools::FileIsDirectory(fullPath.c_str()))
+ if (!cmSystemTools::FileIsDirectory(fullPath))
{
std::string linkName4 = linkName3;
linkName4 += "/";
linkName4 += cmSystemTools::GetFilenameName(fullPath);
this->AppendLinkedResource(fout, linkName4,
- fullPath, LinkToFile);
+ this->GetEclipsePath(fullPath),
+ LinkToFile);
}
}
}
@@ -590,18 +632,18 @@ void cmExtraEclipseCDT4Generator::CreateLinksToSubprojects(
this->AppendLinkedResource(fout, "[Subprojects]",
"virtual:/virtual", VirtualFolder);
- for (std::map<cmStdString, std::vector<cmLocalGenerator*> >::const_iterator
+ for (std::map<std::string, std::vector<cmLocalGenerator*> >::const_iterator
it = this->GlobalGenerator->GetProjectMap().begin();
it != this->GlobalGenerator->GetProjectMap().end();
++it)
{
std::string linkSourceDirectory = this->GetEclipsePath(
- it->second[0]->GetMakefile()->GetStartDirectory());
+ it->second[0]->GetCurrentSourceDirectory());
// a linked resource must not point to a parent directory of .project or
// .project itself
if ((baseDir != linkSourceDirectory) &&
- !cmSystemTools::IsSubDirectory(baseDir.c_str(),
- linkSourceDirectory.c_str()))
+ !cmSystemTools::IsSubDirectory(baseDir,
+ linkSourceDirectory))
{
std::string linkName = "[Subprojects]/";
linkName += it->first;
@@ -628,7 +670,7 @@ void cmExtraEclipseCDT4Generator::AppendIncludeDirectories(
{
if (!inc->empty())
{
- std::string dir = cmSystemTools::CollapseFullPath(inc->c_str());
+ std::string dir = cmSystemTools::CollapseFullPath(*inc);
// handle framework include dirs on OSX, the remainder after the
// Frameworks/ part has to be stripped
@@ -656,8 +698,8 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
{
std::set<std::string> emmited;
- const cmMakefile* mf
- = this->GlobalGenerator->GetLocalGenerators()[0]->GetMakefile();
+ cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
+ const cmMakefile* mf = lg->GetMakefile();
const std::string filename = this->HomeOutputDirectory + "/.cproject";
@@ -723,7 +765,9 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
}
else if (systemName == "Darwin")
{
- fout << "<extension id=\"org.eclipse.cdt.core.MachO\""
+ fout << "<extension id=\"" <<
+ (this->SupportsMachO64Parser ? "org.eclipse.cdt.core.MachO64"
+ : "org.eclipse.cdt.core.MachO") << "\""
" point=\"org.eclipse.cdt.core.BinaryParser\">\n"
"<attribute key=\"c++filt\" value=\"c++filt\"/>\n"
"</extension>\n"
@@ -782,7 +826,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
// exlude source directory from output search path
// - only if not named the same as an output directory
if (!cmSystemTools::FileIsDirectory(
- std::string(this->HomeOutputDirectory + "/" + *it).c_str()))
+ std::string(this->HomeOutputDirectory + "/" + *it)))
{
excludeFromOut += this->EscapeForXML(*it) + "/|";
}
@@ -805,11 +849,16 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
{
// Expand the list.
std::vector<std::string> defs;
- cmSystemTools::ExpandListArgument(cdefs, defs);
+ cmGeneratorExpression::Split(cdefs, defs);
for(std::vector<std::string>::const_iterator di = defs.begin();
di != defs.end(); ++di)
{
+ if (cmGeneratorExpression::Find(*di) != std::string::npos)
+ {
+ continue;
+ }
+
std::string::size_type equals = di->find('=', 0);
std::string::size_type enddef = di->length();
@@ -916,18 +965,13 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
it != this->GlobalGenerator->GetLocalGenerators().end();
++it)
{
- cmGeneratorTargetsType targets = (*it)->GetMakefile()
- ->GetGeneratorTargets();
- for (cmGeneratorTargetsType::iterator l = targets.begin();
+ std::vector<cmGeneratorTarget*> targets = (*it)->GetGeneratorTargets();
+ for (std::vector<cmGeneratorTarget*>::iterator l = targets.begin();
l != targets.end(); ++l)
{
- if (l->first->IsImported())
- {
- continue;
- }
std::vector<std::string> includeDirs;
- const char *config = mf->GetDefinition("CMAKE_BUILD_TYPE");
- (*it)->GetIncludeDirectories(includeDirs, l->second, "C", config);
+ std::string config = mf->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ (*it)->GetIncludeDirectories(includeDirs, *l, "C", config);
this->AppendIncludeDirectories(fout, includeDirs, emmited);
}
}
@@ -940,7 +984,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
std::string systemIncludeDirs = mf->GetSafeDefinition(
"CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS");
std::vector<std::string> dirs;
- cmSystemTools::ExpandListArgument(systemIncludeDirs.c_str(), dirs);
+ cmSystemTools::ExpandListArgument(systemIncludeDirs, dirs);
this->AppendIncludeDirectories(fout, dirs, emmited);
}
compiler = mf->GetSafeDefinition("CMAKE_CXX_COMPILER");
@@ -949,7 +993,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
std::string systemIncludeDirs = mf->GetSafeDefinition(
"CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS");
std::vector<std::string> dirs;
- cmSystemTools::ExpandListArgument(systemIncludeDirs.c_str(), dirs);
+ cmSystemTools::ExpandListArgument(systemIncludeDirs, dirs);
this->AppendIncludeDirectories(fout, dirs, emmited);
}
@@ -964,7 +1008,6 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
const std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
const std::string makeArgs = mf->GetSafeDefinition(
"CMAKE_ECLIPSE_MAKE_ARGUMENTS");
- const std::string cmake = mf->GetRequiredDefinition("CMAKE_COMMAND");
cmGlobalGenerator* generator
= const_cast<cmGlobalGenerator*>(this->GlobalGenerator);
@@ -987,72 +1030,54 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
it != this->GlobalGenerator->GetLocalGenerators().end();
++it)
{
- const cmTargets& targets = (*it)->GetMakefile()->GetTargets();
- cmMakefile* makefile=(*it)->GetMakefile();
- std::string subdir = (*it)->Convert(makefile->GetCurrentOutputDirectory(),
+ const std::vector<cmGeneratorTarget*> targets =
+ (*it)->GetGeneratorTargets();
+ std::string subdir = (*it)->Convert((*it)->GetCurrentBinaryDirectory(),
cmLocalGenerator::HOME_OUTPUT);
if (subdir == ".")
{
subdir = "";
}
- for(cmTargets::const_iterator ti=targets.begin(); ti!=targets.end(); ++ti)
+ for(std::vector<cmGeneratorTarget*>::const_iterator ti =
+ targets.begin(); ti!=targets.end(); ++ti)
{
- switch(ti->second.GetType())
+ std::string targetName = (*ti)->GetName();
+ switch((*ti)->GetType())
{
- case cmTarget::GLOBAL_TARGET:
+ case cmState::GLOBAL_TARGET:
{
- bool insertTarget = false;
// Only add the global targets from CMAKE_BINARY_DIR,
// not from the subdirs
if (subdir.empty())
{
- insertTarget = true;
- // only add the "edit_cache" target if it's not ccmake, because
- // this will not work within the IDE
- if (ti->first == "edit_cache")
- {
- const char* editCommand = makefile->GetDefinition
- ("CMAKE_EDIT_COMMAND");
- if (editCommand == 0)
- {
- insertTarget = false;
- }
- else if (strstr(editCommand, "ccmake")!=NULL)
- {
- insertTarget = false;
- }
- }
- }
- if (insertTarget)
- {
- this->AppendTarget(fout, ti->first, make, makeArgs, subdir, ": ");
+ this->AppendTarget(fout, targetName, make, makeArgs, subdir, ": ");
}
}
break;
- case cmTarget::UTILITY:
+ case cmState::UTILITY:
// Add all utility targets, except the Nightly/Continuous/
// Experimental-"sub"targets as e.g. NightlyStart
- if (((ti->first.find("Nightly")==0) &&(ti->first!="Nightly"))
- || ((ti->first.find("Continuous")==0)&&(ti->first!="Continuous"))
- || ((ti->first.find("Experimental")==0)
- && (ti->first!="Experimental")))
+ if (((targetName.find("Nightly")==0) &&(targetName!="Nightly"))
+ || ((targetName.find("Continuous")==0)&&(targetName!="Continuous"))
+ || ((targetName.find("Experimental")==0)
+ && (targetName!="Experimental")))
{
break;
}
- this->AppendTarget(fout, ti->first, make, makeArgs, subdir, ": ");
+ this->AppendTarget(fout, targetName, make, makeArgs, subdir, ": ");
break;
- case cmTarget::EXECUTABLE:
- case cmTarget::STATIC_LIBRARY:
- case cmTarget::SHARED_LIBRARY:
- case cmTarget::MODULE_LIBRARY:
- case cmTarget::OBJECT_LIBRARY:
+ case cmState::EXECUTABLE:
+ case cmState::STATIC_LIBRARY:
+ case cmState::SHARED_LIBRARY:
+ case cmState::MODULE_LIBRARY:
+ case cmState::OBJECT_LIBRARY:
{
- const char* prefix = (ti->second.GetType()==cmTarget::EXECUTABLE ?
+ const char* prefix = ((*ti)->GetType()==cmState::EXECUTABLE ?
"[exe] " : "[lib] ");
- this->AppendTarget(fout, ti->first, make, makeArgs, subdir, prefix);
- std::string fastTarget = ti->first;
+ this->AppendTarget(fout, targetName, make, makeArgs, subdir, prefix);
+ std::string fastTarget = targetName;
fastTarget += "/fast";
this->AppendTarget(fout, fastTarget, make, makeArgs, subdir, prefix);
@@ -1061,22 +1086,24 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
{
std::string virtDir = "[Targets]/";
virtDir += prefix;
- virtDir += ti->first;
+ virtDir += targetName;
std::string buildArgs = "-C \"";
- buildArgs += makefile->GetHomeOutputDirectory();
+ buildArgs += (*it)->GetBinaryDirectory();
buildArgs += "\" ";
buildArgs += makeArgs;
this->AppendTarget(fout, "Build", make, buildArgs, virtDir, "",
- ti->first.c_str());
+ targetName.c_str());
std::string cleanArgs = "-E chdir \"";
- cleanArgs += makefile->GetCurrentOutputDirectory();
+ cleanArgs += (*it)->GetCurrentBinaryDirectory();
cleanArgs += "\" \"";
- cleanArgs += cmake;
+ cleanArgs += cmSystemTools::GetCMakeCommand();
cleanArgs += "\" -P \"";
- cleanArgs += (*it)->GetTargetDirectory(ti->second);
+ cmGeneratorTarget* gt = *ti;
+ cleanArgs += (*it)->GetTargetDirectory(gt);
cleanArgs += "/cmake_clean.cmake\"";
- this->AppendTarget(fout, "Clean", cmake, cleanArgs, virtDir, "", "");
+ this->AppendTarget(fout, "Clean", cmSystemTools::GetCMakeCommand(),
+ cleanArgs, virtDir, "", "");
}
}
break;
@@ -1124,8 +1151,8 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
fout << "</cconfiguration>\n"
"</storageModule>\n"
"<storageModule moduleId=\"cdtBuildSystem\" version=\"4.0.0\">\n"
- "<project id=\"" << this->EscapeForXML(mf->GetProjectName())
- << ".null.1\" name=\"" << this->EscapeForXML(mf->GetProjectName())
+ "<project id=\"" << this->EscapeForXML(lg->GetProjectName())
+ << ".null.1\" name=\"" << this->EscapeForXML(lg->GetProjectName())
<< "\"/>\n"
"</storageModule>\n"
"</cproject>\n"
@@ -1139,7 +1166,7 @@ cmExtraEclipseCDT4Generator::GetEclipsePath(const std::string& path)
#if defined(__CYGWIN__)
std::string cmd = "cygpath -m " + path;
std::string out;
- if (!cmSystemTools::RunCommand(cmd.c_str(), out, 0, false))
+ if (!cmSystemTools::RunSingleCommand(cmd.c_str(), &out, &out))
{
return path;
}
@@ -1157,7 +1184,7 @@ std::string
cmExtraEclipseCDT4Generator::GetPathBasename(const std::string& path)
{
std::string outputBasename = path;
- while (outputBasename.size() > 0 &&
+ while (!outputBasename.empty() &&
(outputBasename[outputBasename.size() - 1] == '/' ||
outputBasename[outputBasename.size() - 1] == '\\'))
{
@@ -1271,7 +1298,7 @@ void cmExtraEclipseCDT4Generator::AppendTarget(cmGeneratedFileStream& fout,
std::string pathXml = cmExtraEclipseCDT4Generator::EscapeForXML(path);
fout <<
"<target name=\"" << prefix << targetXml << "\""
- " path=\"" << pathXml.c_str() << "\""
+ " path=\"" << pathXml << "\""
" targetID=\"org.eclipse.cdt.make.MakeTargetBuilder\">\n"
"<buildCommand>"
<< cmExtraEclipseCDT4Generator::GetEclipsePath(make)
diff --git a/Source/cmExtraEclipseCDT4Generator.h b/Source/cmExtraEclipseCDT4Generator.h
index b31cce74c..16675f2a3 100644
--- a/Source/cmExtraEclipseCDT4Generator.h
+++ b/Source/cmExtraEclipseCDT4Generator.h
@@ -33,14 +33,16 @@ public:
return new cmExtraEclipseCDT4Generator;
}
- virtual const char* GetName() const {
+ virtual std::string GetName() const {
return cmExtraEclipseCDT4Generator::GetActualName();
}
- static const char* GetActualName() { return "Eclipse CDT4"; }
+ static std::string GetActualName() { return "Eclipse CDT4"; }
virtual void GetDocumentation(cmDocumentationEntry& entry,
- const char* fullName) const;
+ const std::string& fullName) const;
+ virtual void EnableLanguage(std::vector<std::string> const& languages,
+ cmMakefile *, bool optional);
virtual void Generate();
@@ -98,13 +100,14 @@ private:
std::set<std::string>& emittedDirs);
static void AddEnvVar(cmGeneratedFileStream& fout, const char* envVar,
- cmMakefile* mf);
+ cmLocalGenerator* lg);
void CreateLinksToSubprojects(cmGeneratedFileStream& fout,
const std::string& baseDir);
void CreateLinksForTargets(cmGeneratedFileStream& fout);
std::vector<std::string> SrcLinkedResources;
+ std::set<std::string> Natures;
std::string HomeDirectory;
std::string HomeOutputDirectory;
bool IsOutOfSourceBuild;
@@ -112,6 +115,7 @@ private:
bool GenerateLinkedResources;
bool SupportsVirtualFolders;
bool SupportsGmakeErrorParser;
+ bool SupportsMachO64Parser;
};
diff --git a/Source/cmExtraKateGenerator.cxx b/Source/cmExtraKateGenerator.cxx
new file mode 100644
index 000000000..ff5d3ab5f
--- /dev/null
+++ b/Source/cmExtraKateGenerator.cxx
@@ -0,0 +1,351 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2004-2009 Kitware, Inc.
+ Copyright 2004 Alexander Neundorf (neundorf@kde.org)
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmExtraKateGenerator.h"
+#include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmLocalUnixMakefileGenerator3.h"
+#include "cmMakefile.h"
+#include "cmake.h"
+#include "cmSourceFile.h"
+#include "cmGeneratedFileStream.h"
+#include "cmSystemTools.h"
+
+#include <cmsys/SystemTools.hxx>
+
+//----------------------------------------------------------------------------
+void cmExtraKateGenerator
+::GetDocumentation(cmDocumentationEntry& entry, const std::string&) const
+{
+ entry.Name = this->GetName();
+ entry.Brief = "Generates Kate project files.";
+}
+
+cmExtraKateGenerator::cmExtraKateGenerator()
+:cmExternalMakefileProjectGenerator()
+{
+#if defined(_WIN32)
+ this->SupportedGlobalGenerators.push_back("MinGW Makefiles");
+ this->SupportedGlobalGenerators.push_back("NMake Makefiles");
+// disable until somebody actually tests it:
+// this->SupportedGlobalGenerators.push_back("MSYS Makefiles");
+#endif
+ this->SupportedGlobalGenerators.push_back("Ninja");
+ this->SupportedGlobalGenerators.push_back("Unix Makefiles");
+}
+
+
+void cmExtraKateGenerator::Generate()
+{
+ cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
+ const cmMakefile* mf = lg->GetMakefile();
+ this->ProjectName = this->GenerateProjectName(lg->GetProjectName(),
+ mf->GetSafeDefinition("CMAKE_BUILD_TYPE"),
+ this->GetPathBasename(lg->GetBinaryDirectory()));
+ this->UseNinja = (this->GlobalGenerator->GetName() == "Ninja");
+
+ this->CreateKateProjectFile(lg);
+ this->CreateDummyKateProjectFile(lg);
+}
+
+
+void cmExtraKateGenerator::CreateKateProjectFile(
+ const cmLocalGenerator* lg) const
+{
+ std::string filename = lg->GetBinaryDirectory();
+ filename += "/.kateproject";
+ cmGeneratedFileStream fout(filename.c_str());
+ if (!fout)
+ {
+ return;
+ }
+
+ fout <<
+ "{\n"
+ "\t\"name\": \"" << this->ProjectName << "\",\n"
+ "\t\"directory\": \"" << lg->GetSourceDirectory() << "\",\n"
+ "\t\"files\": [ { " << this->GenerateFilesString(lg) << "} ],\n";
+ this->WriteTargets(lg, fout);
+ fout << "}\n";
+}
+
+
+void
+cmExtraKateGenerator::WriteTargets(const cmLocalGenerator* lg,
+ cmGeneratedFileStream& fout) const
+{
+ cmMakefile const* mf = lg->GetMakefile();
+ const std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
+ const std::string makeArgs = mf->GetSafeDefinition(
+ "CMAKE_KATE_MAKE_ARGUMENTS");
+ const char* homeOutputDir = lg->GetBinaryDirectory();
+
+ fout <<
+ "\t\"build\": {\n"
+ "\t\t\"directory\": \"" << lg->GetBinaryDirectory() << "\",\n"
+ "\t\t\"default_target\": \"all\",\n"
+ "\t\t\"clean_target\": \"clean\",\n";
+
+ // build, clean and quick are for the build plugin kate <= 4.12:
+ fout << "\t\t\"build\": \"" << make << " -C \\\"" << homeOutputDir
+ << "\\\" " << makeArgs << " " << "all\",\n";
+ fout << "\t\t\"clean\": \"" << make << " -C \\\"" << homeOutputDir
+ << "\\\" " << makeArgs << " " << "clean\",\n";
+ fout << "\t\t\"quick\": \"" << make << " -C \\\"" << homeOutputDir
+ << "\\\" " << makeArgs << " " << "install\",\n";
+
+ // this is for kate >= 4.13:
+ fout <<
+ "\t\t\"targets\":[\n";
+
+ this->AppendTarget(fout, "all", make, makeArgs,
+ homeOutputDir, homeOutputDir);
+ this->AppendTarget(fout, "clean", make, makeArgs,
+ homeOutputDir, homeOutputDir);
+
+ // add all executable and library targets and some of the GLOBAL
+ // and UTILITY targets
+ for (std::vector<cmLocalGenerator*>::const_iterator
+ it = this->GlobalGenerator->GetLocalGenerators().begin();
+ it != this->GlobalGenerator->GetLocalGenerators().end();
+ ++it)
+ {
+ const std::vector<cmGeneratorTarget*> targets =
+ (*it)->GetGeneratorTargets();
+ std::string currentDir = (*it)->GetCurrentBinaryDirectory();
+ bool topLevel = (currentDir == (*it)->GetBinaryDirectory());
+
+ for(std::vector<cmGeneratorTarget*>::const_iterator ti =
+ targets.begin(); ti!=targets.end(); ++ti)
+ {
+ std::string targetName = (*ti)->GetName();
+ switch((*ti)->GetType())
+ {
+ case cmState::GLOBAL_TARGET:
+ {
+ bool insertTarget = false;
+ // Only add the global targets from CMAKE_BINARY_DIR,
+ // not from the subdirs
+ if (topLevel)
+ {
+ insertTarget = true;
+ // only add the "edit_cache" target if it's not ccmake, because
+ // this will not work within the IDE
+ if (targetName == "edit_cache")
+ {
+ const char* editCommand = (*it)->GetMakefile()->GetDefinition
+ ("CMAKE_EDIT_COMMAND");
+ if (editCommand == 0)
+ {
+ insertTarget = false;
+ }
+ else if (strstr(editCommand, "ccmake")!=NULL)
+ {
+ insertTarget = false;
+ }
+ }
+ }
+ if (insertTarget)
+ {
+ this->AppendTarget(fout, targetName, make, makeArgs,
+ currentDir, homeOutputDir);
+ }
+ }
+ break;
+ case cmState::UTILITY:
+ // Add all utility targets, except the Nightly/Continuous/
+ // Experimental-"sub"targets as e.g. NightlyStart
+ if (((targetName.find("Nightly")==0) &&(targetName!="Nightly"))
+ || ((targetName.find("Continuous")==0)
+ &&(targetName!="Continuous"))
+ || ((targetName.find("Experimental")==0)
+ && (targetName!="Experimental")))
+ {
+ break;
+ }
+
+ this->AppendTarget(fout, targetName, make, makeArgs,
+ currentDir, homeOutputDir);
+ break;
+ case cmState::EXECUTABLE:
+ case cmState::STATIC_LIBRARY:
+ case cmState::SHARED_LIBRARY:
+ case cmState::MODULE_LIBRARY:
+ case cmState::OBJECT_LIBRARY:
+ {
+ this->AppendTarget(fout, targetName, make, makeArgs,
+ currentDir, homeOutputDir);
+ std::string fastTarget = targetName;
+ fastTarget += "/fast";
+ this->AppendTarget(fout, fastTarget, make, makeArgs,
+ currentDir, homeOutputDir);
+
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ //insert rules for compiling, preprocessing and assembling individual files
+ std::vector<std::string> objectFileTargets;
+ (*it)->GetIndividualFileTargets(objectFileTargets);
+ for(std::vector<std::string>::const_iterator fit=objectFileTargets.begin();
+ fit != objectFileTargets.end();
+ ++fit)
+ {
+ this->AppendTarget(fout, *fit, make, makeArgs, currentDir,homeOutputDir);
+ }
+ }
+
+ fout <<
+ "\t] }\n";
+}
+
+
+void
+cmExtraKateGenerator::AppendTarget(cmGeneratedFileStream& fout,
+ const std::string& target,
+ const std::string& make,
+ const std::string& makeArgs,
+ const std::string& path,
+ const char* homeOutputDir
+ ) const
+{
+ static char JsonSep = ' ';
+
+ fout <<
+ "\t\t\t" << JsonSep << "{\"name\":\"" << target << "\", "
+ "\"build_cmd\":\"" << make
+ << " -C \\\"" << (this->UseNinja ? homeOutputDir : path.c_str())
+ << "\\\" " << makeArgs << " "
+ << target << "\"}\n";
+
+ JsonSep = ',';
+}
+
+
+
+void
+cmExtraKateGenerator::CreateDummyKateProjectFile(
+ const cmLocalGenerator* lg) const
+{
+ std::string filename = lg->GetBinaryDirectory();
+ filename += "/";
+ filename += this->ProjectName;
+ filename += ".kateproject";
+ cmGeneratedFileStream fout(filename.c_str());
+ if (!fout)
+ {
+ return;
+ }
+
+ fout << "#Generated by " << cmSystemTools::GetCMakeCommand()
+ << ", do not edit.\n";
+}
+
+
+std::string
+cmExtraKateGenerator::GenerateFilesString(const cmLocalGenerator* lg) const
+{
+ std::string s = lg->GetSourceDirectory();
+ s += "/.git";
+ if(cmSystemTools::FileExists(s.c_str()))
+ {
+ return std::string("\"git\": 1 ");
+ }
+
+ s = lg->GetSourceDirectory();
+ s += "/.svn";
+ if(cmSystemTools::FileExists(s.c_str()))
+ {
+ return std::string("\"svn\": 1 ");
+ }
+
+ s = lg->GetSourceDirectory();
+ s += "/";
+
+ std::set<std::string> files;
+ std::string tmp;
+ const std::vector<cmLocalGenerator *>& lgs =
+ this->GlobalGenerator->GetLocalGenerators();
+
+ for (std::vector<cmLocalGenerator*>::const_iterator it=lgs.begin();
+ it!=lgs.end(); it++)
+ {
+ cmMakefile* makefile=(*it)->GetMakefile();
+ const std::vector<std::string>& listFiles=makefile->GetListFiles();
+ for (std::vector<std::string>::const_iterator lt=listFiles.begin();
+ lt!=listFiles.end(); lt++)
+ {
+ tmp=*lt;
+ {
+ files.insert(tmp);
+ }
+ }
+
+ const std::vector<cmSourceFile*>& sources = makefile->GetSourceFiles();
+ for (std::vector<cmSourceFile*>::const_iterator sfIt = sources.begin();
+ sfIt != sources.end(); sfIt++)
+ {
+ cmSourceFile* sf = *sfIt;
+ if (sf->GetPropertyAsBool("GENERATED"))
+ {
+ continue;
+ }
+
+ tmp = sf->GetFullPath();
+ files.insert(tmp);
+ }
+ }
+
+ const char* sep = "";
+ tmp = "\"list\": [";
+ for(std::set<std::string>::const_iterator it = files.begin();
+ it != files.end(); ++it)
+ {
+ tmp += sep;
+ tmp += " \"";
+ tmp += *it;
+ tmp += "\"";
+ sep = ",";
+ }
+ tmp += "] ";
+
+ return tmp;
+}
+
+
+std::string cmExtraKateGenerator::GenerateProjectName(const std::string& name,
+ const std::string& type,
+ const std::string& path) const
+{
+ return name + (type.empty() ? "" : "-") + type + "@" + path;
+}
+
+
+std::string cmExtraKateGenerator::GetPathBasename(const std::string& path)const
+{
+ std::string outputBasename = path;
+ while (!outputBasename.empty() &&
+ (outputBasename[outputBasename.size() - 1] == '/' ||
+ outputBasename[outputBasename.size() - 1] == '\\'))
+ {
+ outputBasename.resize(outputBasename.size() - 1);
+ }
+ std::string::size_type loc = outputBasename.find_last_of("/\\");
+ if (loc != std::string::npos)
+ {
+ outputBasename = outputBasename.substr(loc + 1);
+ }
+
+ return outputBasename;
+}
diff --git a/Source/cmExtraKateGenerator.h b/Source/cmExtraKateGenerator.h
new file mode 100644
index 000000000..281c1efe3
--- /dev/null
+++ b/Source/cmExtraKateGenerator.h
@@ -0,0 +1,61 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2004-2009 Kitware, Inc.
+ Copyright 2013 Alexander Neundorf (neundorf@kde.org)
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmExtraKateGenerator_h
+#define cmExtraKateGenerator_h
+
+#include "cmExternalMakefileProjectGenerator.h"
+
+class cmLocalGenerator;
+class cmGeneratedFileStream;
+
+/** \class cmExtraKateGenerator
+ * \brief Write Kate project files for Makefile or ninja based projects
+ */
+class cmExtraKateGenerator : public cmExternalMakefileProjectGenerator
+{
+public:
+ cmExtraKateGenerator();
+
+ virtual std::string GetName() const
+ { return cmExtraKateGenerator::GetActualName();}
+ static std::string GetActualName() { return "Kate";}
+ static cmExternalMakefileProjectGenerator* New()
+ { return new cmExtraKateGenerator; }
+ /** Get the documentation entry for this generator. */
+ virtual void GetDocumentation(cmDocumentationEntry& entry,
+ const std::string& fullName) const;
+
+ virtual void Generate();
+private:
+ void CreateKateProjectFile(const cmLocalGenerator* lg) const;
+ void CreateDummyKateProjectFile(const cmLocalGenerator* lg) const;
+ void WriteTargets(const cmLocalGenerator* lg,
+ cmGeneratedFileStream& fout) const;
+ void AppendTarget(cmGeneratedFileStream& fout,
+ const std::string& target,
+ const std::string& make,
+ const std::string& makeArgs,
+ const std::string& path,
+ const char* homeOutputDir) const;
+
+ std::string GenerateFilesString(const cmLocalGenerator* lg) const;
+ std::string GetPathBasename(const std::string& path) const;
+ std::string GenerateProjectName(const std::string& name,
+ const std::string& type,
+ const std::string& path) const;
+
+ std::string ProjectName;
+ bool UseNinja;
+};
+
+#endif
diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx
index 523fca9aa..92d38b95c 100644
--- a/Source/cmExtraSublimeTextGenerator.cxx
+++ b/Source/cmExtraSublimeTextGenerator.cxx
@@ -20,8 +20,6 @@
#include "cmMakefile.h"
#include "cmSourceFile.h"
#include "cmSystemTools.h"
-#include "cmTarget.h"
-#include "cmXMLSafe.h"
#include <cmsys/SystemTools.hxx>
@@ -41,17 +39,10 @@ http://sublimetext.info/docs/en/reference/build_systems.html
//----------------------------------------------------------------------------
void cmExtraSublimeTextGenerator
-::GetDocumentation(cmDocumentationEntry& entry, const char*) const
+::GetDocumentation(cmDocumentationEntry& entry, const std::string&) const
{
entry.Name = this->GetName();
entry.Brief = "Generates Sublime Text 2 project files.";
- entry.Full =
- "Project files for Sublime Text 2 will be created in the top directory "
- "and in every subdirectory which features a CMakeLists.txt file "
- "containing a PROJECT() call. "
- "Additionally Makefiles (or build.ninja files) are generated into the "
- "build tree. The appropriate make program can build the project through "
- "the default make target. A \"make install\" target is also provided.";
}
cmExtraSublimeTextGenerator::cmExtraSublimeTextGenerator()
@@ -71,7 +62,7 @@ cmExtraSublimeTextGenerator::cmExtraSublimeTextGenerator()
void cmExtraSublimeTextGenerator::Generate()
{
// for each sub project in the project create a sublime text 2 project
- for (std::map<cmStdString, std::vector<cmLocalGenerator*> >::const_iterator
+ for (std::map<std::string, std::vector<cmLocalGenerator*> >::const_iterator
it = this->GlobalGenerator->GetProjectMap().begin();
it!= this->GlobalGenerator->GetProjectMap().end();
++it)
@@ -85,9 +76,8 @@ void cmExtraSublimeTextGenerator::Generate()
void cmExtraSublimeTextGenerator::CreateProjectFile(
const std::vector<cmLocalGenerator*>& lgs)
{
- const cmMakefile* mf=lgs[0]->GetMakefile();
- std::string outputDir=mf->GetStartOutputDirectory();
- std::string projectName=mf->GetProjectName();
+ std::string outputDir=lgs[0]->GetCurrentBinaryDirectory();
+ std::string projectName=lgs[0]->GetProjectName();
const std::string filename =
outputDir + "/" + projectName + ".sublime-project";
@@ -107,8 +97,8 @@ void cmExtraSublimeTextGenerator
}
const std::string &sourceRootRelativeToOutput = cmSystemTools::RelativePath(
- mf->GetHomeOutputDirectory(),
- mf->GetHomeDirectory());
+ lgs[0]->GetBinaryDirectory(),
+ lgs[0]->GetSourceDirectory());
// Write the folder entries to the project file
fout << "{\n";
fout << "\t\"folders\":\n\t[\n\t";
@@ -116,8 +106,8 @@ void cmExtraSublimeTextGenerator
{
fout << "\t{\n\t\t\t\"path\": \"" << sourceRootRelativeToOutput << "\"";
const std::string &outputRelativeToSourceRoot =
- cmSystemTools::RelativePath(mf->GetHomeDirectory(),
- mf->GetHomeOutputDirectory());
+ cmSystemTools::RelativePath(lgs[0]->GetSourceDirectory(),
+ lgs[0]->GetBinaryDirectory());
if ((!outputRelativeToSourceRoot.empty()) &&
((outputRelativeToSourceRoot.length() < 3) ||
(outputRelativeToSourceRoot.substr(0, 3) != "../")))
@@ -171,72 +161,54 @@ void cmExtraSublimeTextGenerator::
lg!=lgs.end(); lg++)
{
cmMakefile* makefile=(*lg)->GetMakefile();
- cmTargets& targets=makefile->GetTargets();
- for (cmTargets::iterator ti = targets.begin();
+ std::vector<cmGeneratorTarget*> targets=(*lg)->GetGeneratorTargets();
+ for (std::vector<cmGeneratorTarget*>::iterator ti = targets.begin();
ti != targets.end(); ti++)
{
- switch(ti->second.GetType())
+ std::string targetName = (*ti)->GetName();
+ switch((*ti)->GetType())
{
- case cmTarget::GLOBAL_TARGET:
+ case cmState::GLOBAL_TARGET:
{
- bool insertTarget = false;
// Only add the global targets from CMAKE_BINARY_DIR,
// not from the subdirs
- if (strcmp(makefile->GetStartOutputDirectory(),
- makefile->GetHomeOutputDirectory())==0)
+ if (strcmp((*lg)->GetCurrentBinaryDirectory(),
+ (*lg)->GetBinaryDirectory())==0)
{
- insertTarget = true;
- // only add the "edit_cache" target if it's not ccmake, because
- // this will not work within the IDE
- if (ti->first == "edit_cache")
- {
- const char* editCommand = makefile->GetDefinition
- ("CMAKE_EDIT_COMMAND");
- if (editCommand == 0)
- {
- insertTarget = false;
- }
- else if (strstr(editCommand, "ccmake")!=NULL)
- {
- insertTarget = false;
- }
- }
- }
- if (insertTarget)
- {
- this->AppendTarget(fout, ti->first.c_str(), *lg, 0,
+ this->AppendTarget(fout, targetName, *lg, 0,
make.c_str(), makefile, compiler.c_str(),
sourceFileFlags, false);
}
}
break;
- case cmTarget::UTILITY:
+ case cmState::UTILITY:
// Add all utility targets, except the Nightly/Continuous/
// Experimental-"sub"targets as e.g. NightlyStart
- if (((ti->first.find("Nightly")==0) &&(ti->first!="Nightly"))
- || ((ti->first.find("Continuous")==0)&&(ti->first!="Continuous"))
- || ((ti->first.find("Experimental")==0)
- && (ti->first!="Experimental")))
+ if (((targetName.find("Nightly")==0) &&(targetName!="Nightly"))
+ || ((targetName.find("Continuous")==0)
+ &&(targetName!="Continuous"))
+ || ((targetName.find("Experimental")==0)
+ && (targetName!="Experimental")))
{
break;
}
- this->AppendTarget(fout, ti->first.c_str(), *lg, 0,
+ this->AppendTarget(fout, targetName, *lg, 0,
make.c_str(), makefile, compiler.c_str(),
sourceFileFlags, false);
break;
- case cmTarget::EXECUTABLE:
- case cmTarget::STATIC_LIBRARY:
- case cmTarget::SHARED_LIBRARY:
- case cmTarget::MODULE_LIBRARY:
- case cmTarget::OBJECT_LIBRARY:
+ case cmState::EXECUTABLE:
+ case cmState::STATIC_LIBRARY:
+ case cmState::SHARED_LIBRARY:
+ case cmState::MODULE_LIBRARY:
+ case cmState::OBJECT_LIBRARY:
{
- this->AppendTarget(fout, ti->first.c_str(), *lg, &ti->second,
+ this->AppendTarget(fout, targetName, *lg, *ti,
make.c_str(), makefile, compiler.c_str(),
sourceFileFlags, false);
- std::string fastTarget = ti->first;
+ std::string fastTarget = targetName;
fastTarget += "/fast";
- this->AppendTarget(fout, fastTarget.c_str(), *lg, &ti->second,
+ this->AppendTarget(fout, fastTarget, *lg, *ti,
make.c_str(), makefile, compiler.c_str(),
sourceFileFlags, false);
}
@@ -250,9 +222,9 @@ void cmExtraSublimeTextGenerator::
void cmExtraSublimeTextGenerator::
AppendTarget(cmGeneratedFileStream& fout,
- const char* targetName,
+ const std::string& targetName,
cmLocalGenerator* lg,
- cmTarget* target,
+ cmGeneratorTarget* target,
const char* make,
const cmMakefile* makefile,
const char*, //compiler
@@ -262,9 +234,9 @@ void cmExtraSublimeTextGenerator::
if (target != 0)
{
- cmGeneratorTarget *gtgt = this->GlobalGenerator
- ->GetGeneratorTarget(target);
- std::vector<cmSourceFile*> const& sourceFiles = target->GetSourceFiles();
+ std::vector<cmSourceFile*> sourceFiles;
+ target->GetSourceFiles(sourceFiles,
+ makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
std::vector<cmSourceFile*>::const_iterator sourceFilesEnd =
sourceFiles.end();
for (std::vector<cmSourceFile*>::const_iterator iter =
@@ -281,9 +253,9 @@ void cmExtraSublimeTextGenerator::
}
std::vector<std::string>& flags = sourceFileFlagsIter->second;
std::string flagsString =
- this->ComputeFlagsForObject(*iter, lg, target, gtgt);
+ this->ComputeFlagsForObject(*iter, lg, target);
std::string definesString =
- this->ComputeDefines(*iter, lg, target, gtgt);
+ this->ComputeDefines(*iter, lg, target);
flags.clear();
cmsys::RegularExpression flagRegex;
// Regular expression to extract compiler flags from a string
@@ -316,7 +288,7 @@ void cmExtraSublimeTextGenerator::
// Ninja uses ninja.build files (look for a way to get the output file name
// from cmMakefile or something)
std::string makefileName;
- if (strcmp(this->GlobalGenerator->GetName(), "Ninja")==0)
+ if (this->GlobalGenerator->GetName() == "Ninja")
{
makefileName = "build.ninja";
}
@@ -328,7 +300,7 @@ void cmExtraSublimeTextGenerator::
{
fout << ",\n\t";
}
- fout << "\t{\n\t\t\t\"name\": \"" << makefile->GetProjectName() << " - " <<
+ fout << "\t{\n\t\t\t\"name\": \"" << lg->GetProjectName() << " - " <<
targetName << "\",\n";
fout << "\t\t\t\"cmd\": [" <<
this->BuildMakeCommand(make, makefileName.c_str(), targetName) <<
@@ -341,11 +313,13 @@ void cmExtraSublimeTextGenerator::
// Create the command line for building the given target using the selected
// make
std::string cmExtraSublimeTextGenerator::BuildMakeCommand(
- const std::string& make, const char* makefile, const char* target)
+ const std::string& make, const char* makefile,
+ const std::string& target)
{
std::string command = "\"";
command += make + "\"";
- if (strcmp(this->GlobalGenerator->GetName(), "NMake Makefiles")==0)
+ std::string generator = this->GlobalGenerator->GetName();
+ if (generator == "NMake Makefiles")
{
std::string makefileName = cmSystemTools::ConvertToOutputPath(makefile);
command += ", \"/NOLOGO\", \"/f\", \"";
@@ -354,7 +328,7 @@ std::string cmExtraSublimeTextGenerator::BuildMakeCommand(
command += target;
command += "\"";
}
- else if (strcmp(this->GlobalGenerator->GetName(), "Ninja")==0)
+ else if (generator == "Ninja")
{
std::string makefileName = cmSystemTools::ConvertToOutputPath(makefile);
command += ", \"-f\", \"";
@@ -366,7 +340,7 @@ std::string cmExtraSublimeTextGenerator::BuildMakeCommand(
else
{
std::string makefileName;
- if (strcmp(this->GlobalGenerator->GetName(), "MinGW Makefiles")==0)
+ if (generator == "MinGW Makefiles")
{
// no escaping of spaces in this case, see
// http://public.kitware.com/Bug/view.php?id=10014
@@ -389,18 +363,17 @@ std::string cmExtraSublimeTextGenerator::BuildMakeCommand(
std::string
cmExtraSublimeTextGenerator::ComputeFlagsForObject(cmSourceFile* source,
cmLocalGenerator* lg,
- cmTarget *target,
cmGeneratorTarget* gtgt)
{
std::string flags;
cmMakefile *makefile = lg->GetMakefile();
- const char* language = source->GetLanguage();
- if (language == NULL)
+ std::string language = source->GetLanguage();
+ if (language.empty())
{
language = "C";
}
- const char* config = makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ const std::string& config = makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
// Add language-specific flags.
lg->AddLanguageFlags(flags, language, config);
@@ -414,7 +387,7 @@ cmExtraSublimeTextGenerator::ComputeFlagsForObject(cmSourceFile* source,
// }
// Add shared-library flags if needed.
- lg->AddCMP0018Flags(flags, target, language, config);
+ lg->AddCMP0018Flags(flags, gtgt, language, config);
// Add include directory flags.
{
@@ -422,14 +395,14 @@ cmExtraSublimeTextGenerator::ComputeFlagsForObject(cmSourceFile* source,
lg->GetIncludeDirectories(includes, gtgt, language, config);
std::string includeFlags =
lg->GetIncludeFlags(includes, gtgt, language, true); // full include paths
- lg->AppendFlags(flags, includeFlags.c_str());
+ lg->AppendFlags(flags, includeFlags);
}
// Append old-style preprocessor definition flags.
lg->AppendFlags(flags, makefile->GetDefineFlags());
// Add target-specific flags.
- lg->AddCompileOptions(flags, target, config, language);
+ lg->AddCompileOptions(flags, gtgt, language, config);
// Add source file specific flags.
lg->AppendFlags(flags, source->GetProperty("COMPILE_FLAGS"));
@@ -443,18 +416,14 @@ cmExtraSublimeTextGenerator::ComputeFlagsForObject(cmSourceFile* source,
// void cmMakefileTargetGenerator::WriteTargetLanguageFlags().
std::string
cmExtraSublimeTextGenerator::
-ComputeDefines(cmSourceFile *source, cmLocalGenerator* lg, cmTarget *target,
- cmGeneratorTarget*)
+ComputeDefines(cmSourceFile *source, cmLocalGenerator* lg,
+ cmGeneratorTarget* target)
{
std::set<std::string> defines;
cmMakefile *makefile = lg->GetMakefile();
- const char* language = source->GetLanguage();
- if (language == NULL)
- {
- language = "";
- }
- const char* config = makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ const std::string& language = source->GetLanguage();
+ const std::string& config = makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
// Add the export symbol definition for shared library objects.
if(const char* exportMacro = target->GetExportMacro())
@@ -463,12 +432,12 @@ ComputeDefines(cmSourceFile *source, cmLocalGenerator* lg, cmTarget *target,
}
// Add preprocessor definitions for this target and configuration.
- lg->AddCompileDefinitions(defines, target, config);
+ lg->AddCompileDefinitions(defines, target, config, language);
lg->AppendDefines(defines, source->GetProperty("COMPILE_DEFINITIONS"));
{
std::string defPropName = "COMPILE_DEFINITIONS_";
defPropName += cmSystemTools::UpperCase(config);
- lg->AppendDefines(defines, source->GetProperty(defPropName.c_str()));
+ lg->AppendDefines(defines, source->GetProperty(defPropName));
}
std::string definesString;
diff --git a/Source/cmExtraSublimeTextGenerator.h b/Source/cmExtraSublimeTextGenerator.h
index 790259372..cf31ee058 100644
--- a/Source/cmExtraSublimeTextGenerator.h
+++ b/Source/cmExtraSublimeTextGenerator.h
@@ -18,7 +18,6 @@
class cmLocalGenerator;
class cmMakefile;
-class cmTarget;
class cmGeneratedFileStream;
class cmGeneratorTarget;
@@ -31,15 +30,15 @@ public:
typedef std::map<std::string, std::vector<std::string> > MapSourceFileFlags;
cmExtraSublimeTextGenerator();
- virtual const char* GetName() const
+ virtual std::string GetName() const
{ return cmExtraSublimeTextGenerator::GetActualName();}
- static const char* GetActualName()
+ static std::string GetActualName()
{ return "Sublime Text 2";}
static cmExternalMakefileProjectGenerator* New()
{ return new cmExtraSublimeTextGenerator; }
/** Get the documentation entry for this generator. */
virtual void GetDocumentation(cmDocumentationEntry& entry,
- const char* fullName) const;
+ const std::string& fullName) const;
virtual void Generate();
private:
@@ -60,14 +59,14 @@ private:
* specified target.
*/
std::string BuildMakeCommand(const std::string& make, const char* makefile,
- const char* target);
+ const std::string& target);
/** Appends the specified target to the generated project file as a Sublime
* Text build system.
*/
void AppendTarget(cmGeneratedFileStream& fout,
- const char* targetName,
+ const std::string& targetName,
cmLocalGenerator* lg,
- cmTarget* target,
+ cmGeneratorTarget* target,
const char* make,
const cmMakefile* makefile,
const char* compiler,
@@ -79,11 +78,10 @@ private:
*/
std::string ComputeFlagsForObject(cmSourceFile *source,
cmLocalGenerator* lg,
- cmTarget *target,
cmGeneratorTarget* gtgt);
std::string ComputeDefines(cmSourceFile *source, cmLocalGenerator* lg,
- cmTarget *target, cmGeneratorTarget* gtgt);
+ cmGeneratorTarget* gtgt);
};
#endif
diff --git a/Source/cmFLTKWrapUICommand.cxx b/Source/cmFLTKWrapUICommand.cxx
index b08c335ac..d17d6646f 100644
--- a/Source/cmFLTKWrapUICommand.cxx
+++ b/Source/cmFLTKWrapUICommand.cxx
@@ -24,18 +24,15 @@ bool cmFLTKWrapUICommand
}
// what is the current source dir
- std::string cdir = this->Makefile->GetCurrentDirectory();
+ std::string cdir = this->Makefile->GetCurrentSourceDirectory();
const char* fluid_exe =
this->Makefile->GetRequiredDefinition("FLTK_FLUID_EXECUTABLE");
// get parameter for the command
this->Target = args[0]; // Target that will use the generated files
- std::vector<std::string> newArgs;
- this->Makefile->ExpandSourceListArguments(args,newArgs, 1);
-
// get the list of GUI files from which .cxx and .h will be generated
- std::string outputDirectory = this->Makefile->GetCurrentOutputDirectory();
+ std::string outputDirectory = this->Makefile->GetCurrentBinaryDirectory();
{
// Some of the generated files are *.h so the directory "GUI"
@@ -45,10 +42,10 @@ bool cmFLTKWrapUICommand
this->Makefile->AddIncludeDirectories( outputDirectories );
}
- for(std::vector<std::string>::iterator i = (newArgs.begin() + 1);
- i != newArgs.end(); i++)
+ for(std::vector<std::string>::const_iterator i = (args.begin() + 1);
+ i != args.end(); i++)
{
- cmSourceFile *curr = this->Makefile->GetSource(i->c_str());
+ cmSourceFile *curr = this->Makefile->GetSource(*i);
// if we should use the source GUI
// to generate .cxx and .h files
if (!curr || !curr->GetPropertyAsBool("WRAP_EXCLUDE"))
@@ -78,19 +75,19 @@ bool cmFLTKWrapUICommand
commandLines.push_back(commandLine);
// Add command for generating the .h and .cxx files
- const char* no_main_dependency = 0;
+ std::string no_main_dependency = "";
const char* no_comment = 0;
const char* no_working_dir = 0;
- this->Makefile->AddCustomCommandToOutput(cxxres.c_str(),
+ this->Makefile->AddCustomCommandToOutput(cxxres,
depends, no_main_dependency,
commandLines, no_comment,
no_working_dir);
- this->Makefile->AddCustomCommandToOutput(hname.c_str(),
+ this->Makefile->AddCustomCommandToOutput(hname,
depends, no_main_dependency,
commandLines, no_comment,
no_working_dir);
- cmSourceFile *sf = this->Makefile->GetSource(cxxres.c_str());
+ cmSourceFile *sf = this->Makefile->GetSource(cxxres);
sf->AddDepend(hname.c_str());
sf->AddDepend(origname.c_str());
this->GeneratedSourcesClasses.push_back(sf);
@@ -110,7 +107,7 @@ bool cmFLTKWrapUICommand
}
std::string varName = this->Target;
varName += "_FLTK_UI_SRCS";
- this->Makefile->AddDefinition(varName.c_str(), sourceListValue.c_str());
+ this->Makefile->AddDefinition(varName, sourceListValue.c_str());
return true;
}
@@ -120,57 +117,18 @@ void cmFLTKWrapUICommand::FinalPass()
// people should add the srcs to the target themselves, but the old command
// didn't support that, so check and see if they added the files in and if
// they didn;t then print a warning and add then anyhow
- cmTarget* target = this->Makefile->FindTarget(this->Target.c_str());
+ cmTarget* target = this->Makefile->FindTarget(this->Target);
if(!target)
{
std::string msg =
"FLTK_WRAP_UI was called with a target that was never created: ";
msg += this->Target;
msg +=". The problem was found while processing the source directory: ";
- msg += this->Makefile->GetStartDirectory();
+ msg += this->Makefile->GetCurrentSourceDirectory();
msg += ". This FLTK_WRAP_UI call will be ignored.";
cmSystemTools::Message(msg.c_str(),"Warning");
return;
}
- std::vector<cmSourceFile*> const& srcs =
- target->GetSourceFiles();
- bool found = false;
- for (unsigned int i = 0; i < srcs.size(); ++i)
- {
- if (srcs[i]->GetFullPath() ==
- this->GeneratedSourcesClasses[0]->GetFullPath())
- {
- found = true;
- break;
- }
- }
- if (!found)
- {
- std::string msg =
- "In CMake 2.2 the FLTK_WRAP_UI command sets a variable to the list of "
- "source files that should be added to your executable or library. It "
- "appears that you have not added these source files to your target. "
- "You should change your CMakeLists.txt file to "
- "directly add the generated files to the target. "
- "For example FTLK_WRAP_UI(foo src1 src2 src3) "
- "will create a variable named foo_FLTK_UI_SRCS that contains the list "
- "of sources to add to your target when you call ADD_LIBRARY or "
- "ADD_EXECUTABLE. For now CMake will add the sources to your target "
- "for you as was done in CMake 2.0 and earlier. In the future this may "
- "become an error.";
- msg +="The problem was found while processing the source directory: ";
- msg += this->Makefile->GetStartDirectory();
- cmSystemTools::Message(msg.c_str(),"Warning");
- // first we add the rules for all the .fl to .h and .cxx files
- size_t lastHeadersClass = this->GeneratedSourcesClasses.size();
-
- // Generate code for all the .fl files
- for(size_t classNum = 0; classNum < lastHeadersClass; classNum++)
- {
- this->Makefile->GetTargets()[this->Target]
- .AddSourceFile(this->GeneratedSourcesClasses[classNum]);
- }
- }
}
diff --git a/Source/cmFLTKWrapUICommand.h b/Source/cmFLTKWrapUICommand.h
index 530de2c96..617fcd955 100644
--- a/Source/cmFLTKWrapUICommand.h
+++ b/Source/cmFLTKWrapUICommand.h
@@ -52,29 +52,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "fltk_wrap_ui";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Create FLTK user interfaces Wrappers.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " fltk_wrap_ui(resultingLibraryName source1\n"
- " source2 ... sourceN )\n"
- "Produce .h and .cxx files for all the .fl and .fld files listed. "
- "The resulting .h and .cxx files will be added to a variable named "
- "resultingLibraryName_FLTK_UI_SRCS which should be added to your "
- "library.";
- }
+ virtual std::string GetName() const { return "fltk_wrap_ui";}
private:
/**
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 4446f7216..b3557f9a2 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -15,12 +15,15 @@
#include "cmHexFileConverter.h"
#include "cmInstallType.h"
#include "cmFileTimeComparison.h"
+#include "cmGlobalGenerator.h"
#include "cmCryptoHash.h"
+#include "cmAlgorithms.h"
#include "cmTimestamp.h"
#if defined(CMAKE_BUILD_WITH_CMAKE)
-#include "cm_curl.h"
+#include "cmCurl.h"
+#include "cmFileLockResult.h"
#endif
#undef GetCurrentDirectory
@@ -32,6 +35,8 @@
#include <cmsys/Directory.hxx>
#include <cmsys/Glob.hxx>
#include <cmsys/RegularExpression.hxx>
+#include <cmsys/FStream.hxx>
+#include <cmsys/Encoding.hxx>
// Table of permissions flags.
#if defined(_WIN32) && !defined(__CYGWIN__)
@@ -60,6 +65,35 @@ static mode_t mode_setuid = S_ISUID;
static mode_t mode_setgid = S_ISGID;
#endif
+#if defined(_WIN32) && defined(CMAKE_ENCODING_UTF8)
+// libcurl doesn't support file:// urls for unicode filenames on Windows.
+// Convert string from UTF-8 to ACP if this is a file:// URL.
+static std::string fix_file_url_windows(const std::string& url)
+{
+ std::string ret = url;
+ if(strncmp(url.c_str(), "file://", 7) == 0)
+ {
+ std::wstring wurl = cmsys::Encoding::ToWide(url);
+ if(!wurl.empty())
+ {
+ int mblen = WideCharToMultiByte(CP_ACP, 0, wurl.c_str(), -1,
+ NULL, 0, NULL, NULL);
+ if(mblen > 0)
+ {
+ std::vector<char> chars(mblen);
+ mblen = WideCharToMultiByte(CP_ACP, 0, wurl.c_str(), -1,
+ &chars[0], mblen, NULL, NULL);
+ if(mblen > 0)
+ {
+ ret = &chars[0];
+ }
+ }
+ }
+ }
+ return ret;
+}
+#endif
+
// cmLibraryCommand
bool cmFileCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
@@ -171,9 +205,13 @@ bool cmFileCommand
{
return this->HandleGenerateCommand(args);
}
+ else if ( subCommand == "LOCK" )
+ {
+ return this->HandleLockCommand(args);
+ }
std::string e = "does not recognize sub-command "+subCommand;
- this->SetError(e.c_str());
+ this->SetError(e);
return false;
}
@@ -181,7 +219,6 @@ bool cmFileCommand
bool cmFileCommand::HandleWriteCommand(std::vector<std::string> const& args,
bool append)
{
- std::string message;
std::vector<std::string>::const_iterator i = args.begin();
i++; // Get rid of subcommand
@@ -189,22 +226,18 @@ bool cmFileCommand::HandleWriteCommand(std::vector<std::string> const& args,
std::string fileName = *i;
if ( !cmsys::SystemTools::FileIsFullPath(i->c_str()) )
{
- fileName = this->Makefile->GetCurrentDirectory();
+ fileName = this->Makefile->GetCurrentSourceDirectory();
fileName += "/" + *i;
}
i++;
- for(;i != args.end(); ++i)
- {
- message += *i;
- }
if ( !this->Makefile->CanIWriteThisFile(fileName.c_str()) )
{
std::string e
= "attempted to write a file: " + fileName +
" into a source directory.";
- this->SetError(e.c_str());
+ this->SetError(e);
cmSystemTools::SetFatalErrorOccured();
return false;
}
@@ -219,8 +252,6 @@ bool cmFileCommand::HandleWriteCommand(std::vector<std::string> const& args,
cmSystemTools::SetPermissions(fileName.c_str(),
#if defined( _MSC_VER ) || defined( __MINGW32__ )
mode | S_IWRITE
-#elif defined( __BORLANDC__ )
- mode | S_IWUSR
#else
mode | S_IWUSR | S_IWGRP
#endif
@@ -228,15 +259,17 @@ bool cmFileCommand::HandleWriteCommand(std::vector<std::string> const& args,
}
// If GetPermissions fails, pretend like it is ok. File open will fail if
// the file is not writable
- std::ofstream file(fileName.c_str(), append?std::ios::app: std::ios::out);
+ cmsys::ofstream file(fileName.c_str(), append?std::ios::app: std::ios::out);
if ( !file )
{
- std::string error = "Internal CMake error when trying to open file: ";
- error += fileName.c_str();
- error += " for writing.";
- this->SetError(error.c_str());
+ std::string error = "failed to open for writing (";
+ error += cmSystemTools::GetLastSystemError();
+ error += "):\n ";
+ error += fileName;
+ this->SetError(error);
return false;
}
+ std::string message = cmJoin(cmMakeRange(i, args.end()), std::string());
file << message;
file.close();
if(mode)
@@ -275,7 +308,7 @@ bool cmFileCommand::HandleReadCommand(std::vector<std::string> const& args)
std::string fileName = fileNameArg.GetString();
if ( !cmsys::SystemTools::FileIsFullPath(fileName.c_str()) )
{
- fileName = this->Makefile->GetCurrentDirectory();
+ fileName = this->Makefile->GetCurrentSourceDirectory();
fileName += "/" + fileNameArg.GetString();
}
@@ -283,31 +316,32 @@ bool cmFileCommand::HandleReadCommand(std::vector<std::string> const& args)
// Open the specified file.
#if defined(_WIN32) || defined(__CYGWIN__)
- std::ifstream file(fileName.c_str(), std::ios::in |
+ cmsys::ifstream file(fileName.c_str(), std::ios::in |
(hexOutputArg.IsEnabled() ? std::ios::binary : std::ios::in));
#else
- std::ifstream file(fileName.c_str(), std::ios::in);
+ cmsys::ifstream file(fileName.c_str(), std::ios::in);
#endif
if ( !file )
{
- std::string error = "Internal CMake error when trying to open file: ";
- error += fileName.c_str();
- error += " for reading.";
- this->SetError(error.c_str());
+ std::string error = "failed to open for reading (";
+ error += cmSystemTools::GetLastSystemError();
+ error += "):\n ";
+ error += fileName;
+ this->SetError(error);
return false;
}
// is there a limit?
long sizeLimit = -1;
- if (limitArg.GetString().size() > 0)
+ if (!limitArg.GetString().empty())
{
sizeLimit = atoi(limitArg.GetCString());
}
// is there an offset?
long offset = 0;
- if (offsetArg.GetString().size() > 0)
+ if (!offsetArg.GetString().empty())
{
offset = atoi(offsetArg.GetCString());
}
@@ -358,7 +392,7 @@ bool cmFileCommand::HandleReadCommand(std::vector<std::string> const& args)
}
}
}
- this->Makefile->AddDefinition(variable.c_str(), output.c_str());
+ this->Makefile->AddDefinition(variable, output.c_str());
return true;
}
@@ -368,29 +402,29 @@ bool cmFileCommand::HandleHashCommand(std::vector<std::string> const& args)
#if defined(CMAKE_BUILD_WITH_CMAKE)
if(args.size() != 3)
{
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " requires a file name and output variable";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
cmsys::auto_ptr<cmCryptoHash> hash(cmCryptoHash::New(args[0].c_str()));
if(hash.get())
{
- std::string out = hash->HashFile(args[1].c_str());
+ std::string out = hash->HashFile(args[1]);
if(!out.empty())
{
- this->Makefile->AddDefinition(args[2].c_str(), out.c_str());
+ this->Makefile->AddDefinition(args[2], out.c_str());
return true;
}
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " failed to read file \"" << args[1] << "\": "
<< cmSystemTools::GetLastSystemError();
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
}
return false;
#else
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " not available during bootstrap";
this->SetError(e.str().c_str());
return false;
@@ -410,7 +444,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
std::string fileName = args[1];
if(!cmsys::SystemTools::FileIsFullPath(fileName.c_str()))
{
- fileName = this->Makefile->GetCurrentDirectory();
+ fileName = this->Makefile->GetCurrentSourceDirectory();
fileName += "/" + args[1];
}
@@ -425,7 +459,8 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
arg_length_minimum,
arg_length_maximum,
arg__maximum,
- arg_regex };
+ arg_regex,
+ arg_encoding };
unsigned int minlen = 0;
unsigned int maxlen = 0;
int limit_input = -1;
@@ -435,6 +470,13 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
bool have_regex = false;
bool newline_consume = false;
bool hex_conversion_enabled = true;
+ enum { encoding_none = cmsys::FStream::BOM_None,
+ encoding_utf8 = cmsys::FStream::BOM_UTF8,
+ encoding_utf16le = cmsys::FStream::BOM_UTF16LE,
+ encoding_utf16be = cmsys::FStream::BOM_UTF16BE,
+ encoding_utf32le = cmsys::FStream::BOM_UTF32LE,
+ encoding_utf32be = cmsys::FStream::BOM_UTF32BE};
+ int encoding = encoding_none;
int arg_mode = arg_none;
for(unsigned int i=3; i < args.size(); ++i)
{
@@ -472,15 +514,19 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
hex_conversion_enabled = false;
arg_mode = arg_none;
}
+ else if(args[i] == "ENCODING")
+ {
+ arg_mode = arg_encoding;
+ }
else if(arg_mode == arg_limit_input)
{
if(sscanf(args[i].c_str(), "%d", &limit_input) != 1 ||
limit_input < 0)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "STRINGS option LIMIT_INPUT value \""
<< args[i] << "\" is not an unsigned integer.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
arg_mode = arg_none;
@@ -490,10 +536,10 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
if(sscanf(args[i].c_str(), "%d", &limit_output) != 1 ||
limit_output < 0)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "STRINGS option LIMIT_OUTPUT value \""
<< args[i] << "\" is not an unsigned integer.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
arg_mode = arg_none;
@@ -503,10 +549,10 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
int count;
if(sscanf(args[i].c_str(), "%d", &count) != 1 || count < 0)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "STRINGS option LIMIT_COUNT value \""
<< args[i] << "\" is not an unsigned integer.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
limit_count = count;
@@ -517,10 +563,10 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
int len;
if(sscanf(args[i].c_str(), "%d", &len) != 1 || len < 0)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "STRINGS option LENGTH_MINIMUM value \""
<< args[i] << "\" is not an unsigned integer.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
minlen = len;
@@ -531,10 +577,10 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
int len;
if(sscanf(args[i].c_str(), "%d", &len) != 1 || len < 0)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "STRINGS option LENGTH_MAXIMUM value \""
<< args[i] << "\" is not an unsigned integer.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
maxlen = len;
@@ -544,21 +590,53 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
{
if(!regex.compile(args[i].c_str()))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "STRINGS option REGEX value \""
<< args[i] << "\" could not be compiled.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
have_regex = true;
arg_mode = arg_none;
}
+ else if(arg_mode == arg_encoding)
+ {
+ if(args[i] == "UTF-8")
+ {
+ encoding = encoding_utf8;
+ }
+ else if(args[i] == "UTF-16LE")
+ {
+ encoding = encoding_utf16le;
+ }
+ else if(args[i] == "UTF-16BE")
+ {
+ encoding = encoding_utf16be;
+ }
+ else if(args[i] == "UTF-32LE")
+ {
+ encoding = encoding_utf32le;
+ }
+ else if(args[i] == "UTF-32BE")
+ {
+ encoding = encoding_utf32be;
+ }
+ else
+ {
+ std::ostringstream e;
+ e << "STRINGS option ENCODING \""
+ << args[i] << "\" not recognized.";
+ this->SetError(e.str());
+ return false;
+ }
+ arg_mode = arg_none;
+ }
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "STRINGS given unknown argument \""
<< args[i] << "\"";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
@@ -566,7 +644,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
if (hex_conversion_enabled)
{
// TODO: should work without temp file, but just on a memory buffer
- std::string binaryFileName = this->Makefile->GetCurrentOutputDirectory();
+ std::string binaryFileName = this->Makefile->GetCurrentBinaryDirectory();
binaryFileName += cmake::GetCMakeFilesDirectory();
binaryFileName += "/FileCommandStringsBinaryFile";
if(cmHexFileConverter::TryConvert(fileName.c_str(),binaryFileName.c_str()))
@@ -577,27 +655,127 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
// Open the specified file.
#if defined(_WIN32) || defined(__CYGWIN__)
- std::ifstream fin(fileName.c_str(), std::ios::in | std::ios::binary);
+ cmsys::ifstream fin(fileName.c_str(), std::ios::in | std::ios::binary);
#else
- std::ifstream fin(fileName.c_str(), std::ios::in);
+ cmsys::ifstream fin(fileName.c_str(), std::ios::in);
#endif
if(!fin)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "STRINGS file \"" << fileName << "\" cannot be read.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
+ //If BOM is found and encoding was not specified, use the BOM
+ int bom_found = cmsys::FStream::ReadBOM(fin);
+ if(encoding == encoding_none && bom_found != cmsys::FStream::BOM_None)
+ {
+ encoding = bom_found;
+ }
+
+ unsigned int bytes_rem = 0;
+ if(encoding == encoding_utf16le || encoding == encoding_utf16be)
+ {
+ bytes_rem = 1;
+ }
+ if(encoding == encoding_utf32le || encoding == encoding_utf32be)
+ {
+ bytes_rem = 3;
+ }
+
// Parse strings out of the file.
int output_size = 0;
std::vector<std::string> strings;
std::string s;
- int c;
while((!limit_count || strings.size() < limit_count) &&
(limit_input < 0 || static_cast<int>(fin.tellg()) < limit_input) &&
- (c = fin.get(), fin))
+ fin)
{
+ std::string current_str;
+
+ int c = fin.get();
+ for(unsigned int i=0; i<bytes_rem; ++i)
+ {
+ int c1 = fin.get();
+ if(!fin)
+ {
+ fin.putback(static_cast<char>(c1));
+ break;
+ }
+ c = (c << 8) | c1;
+ }
+ if(encoding == encoding_utf16le)
+ {
+ c = ((c & 0xFF) << 8) | ((c & 0xFF00) >> 8);
+ }
+ else if(encoding == encoding_utf32le)
+ {
+ c = (((c & 0xFF) << 24) | ((c & 0xFF00) << 8) |
+ ((c & 0xFF0000) >> 8) | ((c & 0xFF000000) >> 24));
+ }
+
+ if(c == '\r')
+ {
+ // Ignore CR character to make output always have UNIX newlines.
+ continue;
+ }
+
+ else if((c >= 0x20 && c < 0x7F) || c == '\t' ||
+ (c == '\n' && newline_consume))
+ {
+ // This is an ASCII character that may be part of a string.
+ // Cast added to avoid compiler warning. Cast is ok because
+ // c is guaranteed to fit in char by the above if...
+ current_str += static_cast<char>(c);
+ }
+ else if(encoding == encoding_utf8)
+ {
+ // Check for UTF-8 encoded string (up to 4 octets)
+ static const unsigned char utf8_check_table[3][2] =
+ {
+ {0xE0, 0xC0},
+ {0xF0, 0xE0},
+ {0xF8, 0xF0},
+ };
+
+ // how many octets are there?
+ unsigned int num_utf8_bytes = 0;
+ for(unsigned int j=0; num_utf8_bytes == 0 && j<3; j++)
+ {
+ if((c & utf8_check_table[j][0]) == utf8_check_table[j][1])
+ num_utf8_bytes = j+2;
+ }
+
+ // get subsequent octets and check that they are valid
+ for(unsigned int j=0; j<num_utf8_bytes; j++)
+ {
+ if(j != 0)
+ {
+ c = fin.get();
+ if(!fin || (c & 0xC0) != 0x80)
+ {
+ fin.putback(static_cast<char>(c));
+ break;
+ }
+ }
+ current_str += static_cast<char>(c);
+ }
+
+ // if this was an invalid utf8 sequence, discard the data, and put
+ // back subsequent characters
+ if((current_str.length() != num_utf8_bytes))
+ {
+ for(unsigned int j=0; j<current_str.size()-1; j++)
+ {
+ c = current_str[current_str.size() - 1 - j];
+ fin.putback(static_cast<char>(c));
+ }
+ current_str = "";
+ }
+ }
+
+
if(c == '\n' && !newline_consume)
{
// The current line has been terminated. Check if the current
@@ -618,26 +796,13 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
// Reset the string to empty.
s = "";
}
- else if(c == '\r')
- {
- // Ignore CR character to make output always have UNIX newlines.
- }
- else if((c >= 0x20 && c < 0x7F) || c == '\t' ||
- (c == '\n' && newline_consume))
- {
- // This is an ASCII character that may be part of a string.
- // Cast added to avoid compiler warning. Cast is ok because
- // c is guaranteed to fit in char by the above if...
- s += static_cast<char>(c);
- }
- else
+ else if(current_str.empty())
{
- // TODO: Support ENCODING option. See issue #10519.
// A non-string character has been found. Check if the current
// string matches the requirements. We require that the length
// be at least one no matter what the user specified.
- if(s.length() >= minlen && s.length() >= 1 &&
- (!have_regex || regex.find(s.c_str())))
+ if(s.length() >= minlen && !s.empty() &&
+ (!have_regex || regex.find(s.c_str())))
{
output_size += static_cast<int>(s.size()) + 1;
if(limit_output >= 0 && output_size >= limit_output)
@@ -651,10 +816,15 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
// Reset the string to empty.
s = "";
}
+ else
+ {
+ s += current_str;
+ }
+
- // Terminate a string if the maximum length is reached.
if(maxlen > 0 && s.size() == maxlen)
{
+ // Terminate a string if the maximum length is reached.
if(s.length() >= minlen &&
(!have_regex || regex.find(s.c_str())))
{
@@ -708,7 +878,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
}
// Save the output in a makefile variable.
- this->Makefile->AddDefinition(outVar.c_str(), output.c_str());
+ this->Makefile->AddDefinition(outVar, output.c_str());
return true;
}
@@ -735,13 +905,13 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
{
switch(status)
{
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
g.RecurseThroughSymlinksOff();
break;
case cmPolicies::OLD:
case cmPolicies::WARN:
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
g.RecurseThroughSymlinksOn();
break;
}
@@ -751,6 +921,35 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
bool first = true;
for ( ; i != args.end(); ++i )
{
+ if( *i == "LIST_DIRECTORIES" )
+ {
+ ++i;
+ if(i != args.end())
+ {
+ if(cmSystemTools::IsOn(i->c_str()))
+ {
+ g.SetListDirs(true);
+ g.SetRecurseListDirs(true);
+ }
+ else if(cmSystemTools::IsOff(i->c_str()))
+ {
+ g.SetListDirs(false);
+ g.SetRecurseListDirs(false);
+ }
+ else
+ {
+ this->SetError("LIST_DIRECTORIES missing bool value.");
+ return false;
+ }
+ }
+ else
+ {
+ this->SetError("LIST_DIRECTORIES missing bool value.");
+ return false;
+ }
+ ++i;
+ }
+
if ( recurse && (*i == "FOLLOW_SYMLINKS") )
{
explicitFollowSymlinks = true;
@@ -781,23 +980,50 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
}
}
+ cmsys::Glob::GlobMessages globMessages;
if ( !cmsys::SystemTools::FileIsFullPath(i->c_str()) )
{
- std::string expr = this->Makefile->GetCurrentDirectory();
+ std::string expr = this->Makefile->GetCurrentSourceDirectory();
// Handle script mode
- if ( expr.size() > 0 )
+ if (!expr.empty())
{
expr += "/" + *i;
- g.FindFiles(expr);
+ g.FindFiles(expr, &globMessages);
}
else
{
- g.FindFiles(*i);
+ g.FindFiles(*i, &globMessages);
}
}
else
{
- g.FindFiles(*i);
+ g.FindFiles(*i, &globMessages);
+ }
+
+ if(!globMessages.empty())
+ {
+ bool shouldExit = false;
+ for(cmsys::Glob::GlobMessagesIterator it=globMessages.begin();
+ it != globMessages.end(); ++it)
+ {
+ if(it->type == cmsys::Glob::cyclicRecursion)
+ {
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING,
+ "Cyclic recursion detected while globbing for '"
+ + *i + "':\n" + it->content);
+ }
+ else
+ {
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR,
+ "Error has occured while globbing for '"
+ + *i + "' - " + it->content);
+ shouldExit = true;
+ }
+ }
+ if(shouldExit)
+ {
+ return false;
+ }
}
std::vector<std::string>::size_type cc;
@@ -817,6 +1043,8 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
{
switch (status)
{
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
// Correct behavior, yay!
break;
@@ -829,21 +1057,13 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
if(g.GetFollowedSymlinkCount() != 0)
{
this->Makefile->IssueMessage(cmake::AUTHOR_WARNING,
- this->Makefile->GetPolicies()->
- GetPolicyWarning(cmPolicies::CMP0009));
+ cmPolicies::GetPolicyWarning(cmPolicies::CMP0009));
}
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- this->SetError("policy CMP0009 error");
- this->Makefile->IssueMessage(cmake::FATAL_ERROR,
- this->Makefile->GetPolicies()->
- GetRequiredPolicyError(cmPolicies::CMP0009));
- return false;
}
}
- this->Makefile->AddDefinition(variable.c_str(), output.c_str());
+ this->Makefile->AddDefinition(variable, output.c_str());
return true;
}
@@ -864,7 +1084,7 @@ bool cmFileCommand::HandleMakeDirectoryCommand(
const std::string* cdir = &(*i);
if ( !cmsys::SystemTools::FileIsFullPath(i->c_str()) )
{
- expr = this->Makefile->GetCurrentDirectory();
+ expr = this->Makefile->GetCurrentSourceDirectory();
expr += "/" + *i;
cdir = &expr;
}
@@ -872,14 +1092,14 @@ bool cmFileCommand::HandleMakeDirectoryCommand(
{
std::string e = "attempted to create a directory: " + *cdir
+ " into a source directory.";
- this->SetError(e.c_str());
+ this->SetError(e);
cmSystemTools::SetFatalErrorOccured();
return false;
}
if ( !cmSystemTools::MakeDirectory(cdir->c_str()) )
{
std::string error = "problem creating directory: " + *cdir;
- this->SetError(error.c_str());
+ this->SetError(error);
return false;
}
}
@@ -923,9 +1143,9 @@ cmFileCommand::HandleDifferentCommand(std::vector<std::string> const& args)
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "DIFFERENT given unknown argument " << args[i];
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
@@ -1038,9 +1258,9 @@ protected:
{
if(permissions && !cmSystemTools::SetPermissions(toFile, permissions))
{
- cmOStringStream e;
+ std::ostringstream e;
e << this->Name << " cannot set permissions on \"" << toFile << "\"";
- this->FileCommand->SetError(e.str().c_str());
+ this->FileCommand->SetError(e.str());
return false;
}
return true;
@@ -1062,9 +1282,9 @@ protected:
else if(arg == "SETGID") { permissions |= mode_setgid; }
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << this->Name << " given invalid permission \"" << arg << "\".";
- this->FileCommand->SetError(e.str().c_str());
+ this->FileCommand->SetError(e.str());
return false;
}
return true;
@@ -1089,9 +1309,9 @@ protected:
virtual bool ReportMissing(const char* fromFile)
{
// The input file does not exist and installation is not optional.
- cmOStringStream e;
+ std::ostringstream e;
e << this->Name << " cannot find \"" << fromFile << "\".";
- this->FileCommand->SetError(e.str().c_str());
+ this->FileCommand->SetError(e.str());
return false;
}
@@ -1122,16 +1342,16 @@ protected:
void NotBeforeMatch(std::string const& arg)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "option " << arg << " may not appear before PATTERN or REGEX.";
- this->FileCommand->SetError(e.str().c_str());
+ this->FileCommand->SetError(e.str());
this->Doing = DoingError;
}
void NotAfterMatch(std::string const& arg)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "option " << arg << " may not appear after PATTERN or REGEX.";
- this->FileCommand->SetError(e.str().c_str());
+ this->FileCommand->SetError(e.str());
this->Doing = DoingError;
}
virtual void DefaultFilePermissions()
@@ -1167,9 +1387,9 @@ bool cmFileCopier::Parse(std::vector<std::string> const& args)
if(!this->CheckKeyword(args[i]) &&
!this->CheckValue(args[i]))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "called with unknown argument \"" << args[i] << "\".";
- this->FileCommand->SetError(e.str().c_str());
+ this->FileCommand->SetError(e.str());
return false;
}
@@ -1183,9 +1403,9 @@ bool cmFileCopier::Parse(std::vector<std::string> const& args)
// Require a destination.
if(this->Destination.empty())
{
- cmOStringStream e;
+ std::ostringstream e;
e << this->Name << " given no DESTINATION";
- this->FileCommand->SetError(e.str().c_str());
+ this->FileCommand->SetError(e.str());
return false;
}
@@ -1329,7 +1549,7 @@ bool cmFileCopier::CheckValue(std::string const& arg)
}
else
{
- std::string file = this->Makefile->GetCurrentDirectory();
+ std::string file = this->Makefile->GetCurrentSourceDirectory();
file += "/" + arg;
this->Files.push_back(file);
}
@@ -1341,7 +1561,7 @@ bool cmFileCopier::CheckValue(std::string const& arg)
}
else
{
- this->Destination = this->Makefile->GetCurrentOutputDirectory();
+ this->Destination = this->Makefile->GetCurrentBinaryDirectory();
this->Destination += "/" + arg;
}
this->Doing = DoingNone;
@@ -1363,9 +1583,9 @@ bool cmFileCopier::CheckValue(std::string const& arg)
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "could not compile PATTERN \"" << arg << "\".";
- this->FileCommand->SetError(e.str().c_str());
+ this->FileCommand->SetError(e.str());
this->Doing = DoingError;
}
}
@@ -1379,9 +1599,9 @@ bool cmFileCopier::CheckValue(std::string const& arg)
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "could not compile REGEX \"" << arg << "\".";
- this->FileCommand->SetError(e.str().c_str());
+ this->FileCommand->SetError(e.str());
this->Doing = DoingError;
}
break;
@@ -1423,7 +1643,7 @@ bool cmFileCopier::Run(std::vector<std::string> const& args)
{
// Split the input file into its directory and name components.
std::vector<std::string> fromPathComponents;
- cmSystemTools::SplitPath(files[i].c_str(), fromPathComponents);
+ cmSystemTools::SplitPath(files[i], fromPathComponents);
std::string fromName = *(fromPathComponents.end()-1);
std::string fromDir = cmSystemTools::JoinPath(fromPathComponents.begin(),
fromPathComponents.end()-1);
@@ -1459,9 +1679,9 @@ bool cmFileCopier::Install(const char* fromFile, const char* toFile)
{
if(!*fromFile)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "INSTALL encountered an empty string input file name.";
- this->FileCommand->SetError(e.str().c_str());
+ this->FileCommand->SetError(e.str());
return false;
}
@@ -1500,10 +1720,10 @@ bool cmFileCopier::InstallSymlink(const char* fromFile, const char* toFile)
std::string symlinkTarget;
if(!cmSystemTools::ReadSymlink(fromFile, symlinkTarget))
{
- cmOStringStream e;
+ std::ostringstream e;
e << this->Name << " cannot read symlink \"" << fromFile
<< "\" to duplicate at \"" << toFile << "\".";
- this->FileCommand->SetError(e.str().c_str());
+ this->FileCommand->SetError(e.str());
return false;
}
@@ -1531,12 +1751,12 @@ bool cmFileCopier::InstallSymlink(const char* fromFile, const char* toFile)
cmSystemTools::RemoveFile(toFile);
// Create the symlink.
- if(!cmSystemTools::CreateSymlink(symlinkTarget.c_str(), toFile))
+ if(!cmSystemTools::CreateSymlink(symlinkTarget, toFile))
{
- cmOStringStream e;
+ std::ostringstream e;
e << this->Name << " cannot duplicate symlink \"" << fromFile
<< "\" at \"" << toFile << "\".";
- this->FileCommand->SetError(e.str().c_str());
+ this->FileCommand->SetError(e.str());
return false;
}
}
@@ -1565,10 +1785,10 @@ bool cmFileCopier::InstallFile(const char* fromFile, const char* toFile,
// Copy the file.
if(copy && !cmSystemTools::CopyAFile(fromFile, toFile, true))
{
- cmOStringStream e;
+ std::ostringstream e;
e << this->Name << " cannot copy file \"" << fromFile
<< "\" to \"" << toFile << "\".";
- this->FileCommand->SetError(e.str().c_str());
+ this->FileCommand->SetError(e.str());
return false;
}
@@ -1584,10 +1804,10 @@ bool cmFileCopier::InstallFile(const char* fromFile, const char* toFile,
}
if (!cmSystemTools::CopyFileTime(fromFile, toFile))
{
- cmOStringStream e;
+ std::ostringstream e;
e << this->Name << " cannot set modification time on \""
<< toFile << "\"";
- this->FileCommand->SetError(e.str().c_str());
+ this->FileCommand->SetError(e.str());
return false;
}
}
@@ -1610,15 +1830,16 @@ bool cmFileCopier::InstallDirectory(const char* source,
MatchProperties const& match_properties)
{
// Inform the user about this directory installation.
- this->ReportCopy(destination, TypeDir, true);
+ this->ReportCopy(destination, TypeDir,
+ !cmSystemTools::FileIsDirectory(destination));
// Make sure the destination directory exists.
if(!cmSystemTools::MakeDirectory(destination))
{
- cmOStringStream e;
+ std::ostringstream e;
e << this->Name << " cannot make directory \"" << destination << "\": "
<< cmSystemTools::GetLastSystemError();
- this->FileCommand->SetError(e.str().c_str());
+ this->FileCommand->SetError(e.str());
return false;
}
@@ -1670,7 +1891,7 @@ bool cmFileCopier::InstallDirectory(const char* source,
if(!(strcmp(dir.GetFile(fileNum), ".") == 0 ||
strcmp(dir.GetFile(fileNum), "..") == 0))
{
- cmsys_stl::string fromPath = source;
+ std::string fromPath = source;
fromPath += "/";
fromPath += dir.GetFile(fileNum);
std::string toPath = destination;
@@ -1701,6 +1922,9 @@ struct cmFileInstaller: public cmFileCopier
cmFileCopier(command, "INSTALL"),
InstallType(cmInstallType_FILES),
Optional(false),
+ MessageAlways(false),
+ MessageLazy(false),
+ MessageNever(false),
DestDirLength(0)
{
// Installation does not use source permissions by default.
@@ -1722,13 +1946,19 @@ struct cmFileInstaller: public cmFileCopier
protected:
cmInstallType InstallType;
bool Optional;
+ bool MessageAlways;
+ bool MessageLazy;
+ bool MessageNever;
int DestDirLength;
std::string Rename;
std::string Manifest;
void ManifestAppend(std::string const& file)
{
- this->Manifest += ";";
+ if (!this->Manifest.empty())
+ {
+ this->Manifest += ";";
+ }
this->Manifest += file.substr(this->DestDirLength);
}
@@ -1737,9 +1967,12 @@ protected:
virtual void ReportCopy(const char* toFile, Type type, bool copy)
{
- std::string message = (copy? "Installing: " : "Up-to-date: ");
- message += toFile;
- this->Makefile->DisplayStatus(message.c_str(), -1);
+ if(!this->MessageNever && (copy || !this->MessageLazy))
+ {
+ std::string message = (copy? "Installing: " : "Up-to-date: ");
+ message += toFile;
+ this->Makefile->DisplayStatus(message.c_str(), -1);
+ }
if(type != TypeDir)
{
// Add the file to the manifest.
@@ -1825,6 +2058,16 @@ bool cmFileInstaller::Parse(std::vector<std::string> const& args)
return false;
}
+ if(((this->MessageAlways?1:0) +
+ (this->MessageLazy?1:0) +
+ (this->MessageNever?1:0)) > 1)
+ {
+ this->FileCommand->SetError("INSTALL options MESSAGE_ALWAYS, "
+ "MESSAGE_LAZY, and MESSAGE_NEVER "
+ "are mutually exclusive.");
+ return false;
+ }
+
return true;
}
@@ -1876,6 +2119,42 @@ bool cmFileInstaller::CheckKeyword(std::string const& arg)
this->Optional = true;
}
}
+ else if(arg == "MESSAGE_ALWAYS")
+ {
+ if(this->CurrentMatchRule)
+ {
+ this->NotAfterMatch(arg);
+ }
+ else
+ {
+ this->Doing = DoingNone;
+ this->MessageAlways = true;
+ }
+ }
+ else if(arg == "MESSAGE_LAZY")
+ {
+ if(this->CurrentMatchRule)
+ {
+ this->NotAfterMatch(arg);
+ }
+ else
+ {
+ this->Doing = DoingNone;
+ this->MessageLazy = true;
+ }
+ }
+ else if(arg == "MESSAGE_NEVER")
+ {
+ if(this->CurrentMatchRule)
+ {
+ this->NotAfterMatch(arg);
+ }
+ else
+ {
+ this->Doing = DoingNone;
+ this->MessageNever = true;
+ }
+ }
else if(arg == "PERMISSIONS")
{
if(this->CurrentMatchRule)
@@ -1905,11 +2184,11 @@ bool cmFileInstaller::CheckKeyword(std::string const& arg)
else if(arg == "COMPONENTS" || arg == "CONFIGURATIONS" ||
arg == "PROPERTIES")
{
- cmOStringStream e;
+ std::ostringstream e;
e << "INSTALL called with old-style " << arg << " argument. "
<< "This script was generated with an older version of CMake. "
<< "Re-run this cmake version on your build tree.";
- this->FileCommand->SetError(e.str().c_str());
+ this->FileCommand->SetError(e.str());
this->Doing = DoingError;
}
else
@@ -1973,9 +2252,9 @@ bool cmFileInstaller
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Option TYPE given unknown value \"" << stype << "\".";
- this->FileCommand->SetError(e.str().c_str());
+ this->FileCommand->SetError(e.str());
return false;
}
return true;
@@ -2046,7 +2325,7 @@ bool cmFileInstaller::HandleInstallDestination()
"absolute path or remove DESTDIR environment variable."
"\nDESTINATION=\n";
message += destination;
- this->FileCommand->SetError(message.c_str());
+ this->FileCommand->SetError(message);
return false;
}
}
@@ -2054,22 +2333,25 @@ bool cmFileInstaller::HandleInstallDestination()
this->DestDirLength = int(sdestdir.size());
}
- if ( !cmSystemTools::FileExists(destination.c_str()) )
+ if(this->InstallType != cmInstallType_DIRECTORY)
{
- if ( !cmSystemTools::MakeDirectory(destination.c_str()) )
+ if ( !cmSystemTools::FileExists(destination.c_str()) )
{
- std::string errstring = "cannot create directory: " + destination +
+ if ( !cmSystemTools::MakeDirectory(destination.c_str()) )
+ {
+ std::string errstring = "cannot create directory: " + destination +
". Maybe need administrative privileges.";
- this->FileCommand->SetError(errstring.c_str());
- return false;
+ this->FileCommand->SetError(errstring);
+ return false;
+ }
}
- }
- if ( !cmSystemTools::FileIsDirectory(destination.c_str()) )
- {
- std::string errstring = "INSTALL destination: " + destination +
+ if ( !cmSystemTools::FileIsDirectory(destination) )
+ {
+ std::string errstring = "INSTALL destination: " + destination +
" is not a directory.";
- this->FileCommand->SetError(errstring.c_str());
- return false;
+ this->FileCommand->SetError(errstring);
+ return false;
+ }
}
return true;
}
@@ -2115,9 +2397,9 @@ cmFileCommand::HandleRPathChangeCommand(std::vector<std::string> const& args)
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "RPATH_CHANGE given unknown argument " << args[i];
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
@@ -2138,9 +2420,9 @@ cmFileCommand::HandleRPathChangeCommand(std::vector<std::string> const& args)
}
if(!cmSystemTools::FileExists(file, true))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "RPATH_CHANGE given FILE \"" << file << "\" that does not exist.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
bool success = true;
@@ -2150,13 +2432,13 @@ cmFileCommand::HandleRPathChangeCommand(std::vector<std::string> const& args)
bool changed;
if(!cmSystemTools::ChangeRPath(file, oldRPath, newRPath, &emsg, &changed))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "RPATH_CHANGE could not write new RPATH:\n"
<< " " << newRPath << "\n"
<< "to the file:\n"
<< " " << file << "\n"
<< emsg;
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
success = false;
}
if(success)
@@ -2200,9 +2482,9 @@ cmFileCommand::HandleRPathRemoveCommand(std::vector<std::string> const& args)
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "RPATH_REMOVE given unknown argument " << args[i];
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
@@ -2213,9 +2495,9 @@ cmFileCommand::HandleRPathRemoveCommand(std::vector<std::string> const& args)
}
if(!cmSystemTools::FileExists(file, true))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "RPATH_REMOVE given FILE \"" << file << "\" that does not exist.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
bool success = true;
@@ -2225,11 +2507,11 @@ cmFileCommand::HandleRPathRemoveCommand(std::vector<std::string> const& args)
bool removed;
if(!cmSystemTools::RemoveRPath(file, &emsg, &removed))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "RPATH_REMOVE could not remove RPATH from file:\n"
<< " " << file << "\n"
<< emsg;
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
success = false;
}
if(success)
@@ -2281,9 +2563,9 @@ cmFileCommand::HandleRPathCheckCommand(std::vector<std::string> const& args)
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "RPATH_CHECK given unknown argument " << args[i];
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
@@ -2336,7 +2618,7 @@ bool cmFileCommand::HandleRelativePathCommand(
std::string errstring =
"RELATIVE_PATH must be passed a full path to the directory: "
+ directoryName;
- this->SetError(errstring.c_str());
+ this->SetError(errstring);
return false;
}
if(!cmSystemTools::FileIsFullPath(fileName.c_str()))
@@ -2344,13 +2626,13 @@ bool cmFileCommand::HandleRelativePathCommand(
std::string errstring =
"RELATIVE_PATH must be passed a full path to the file: "
+ fileName;
- this->SetError(errstring.c_str());
+ this->SetError(errstring);
return false;
}
std::string res = cmSystemTools::RelativePath(directoryName.c_str(),
fileName.c_str());
- this->Makefile->AddDefinition(outVar.c_str(),
+ this->Makefile->AddDefinition(outVar,
res.c_str());
return true;
}
@@ -2369,26 +2651,26 @@ bool cmFileCommand::HandleRename(std::vector<std::string> const& args)
std::string oldname = args[1];
if(!cmsys::SystemTools::FileIsFullPath(oldname.c_str()))
{
- oldname = this->Makefile->GetCurrentDirectory();
+ oldname = this->Makefile->GetCurrentSourceDirectory();
oldname += "/" + args[1];
}
std::string newname = args[2];
if(!cmsys::SystemTools::FileIsFullPath(newname.c_str()))
{
- newname = this->Makefile->GetCurrentDirectory();
+ newname = this->Makefile->GetCurrentSourceDirectory();
newname += "/" + args[2];
}
if(!cmSystemTools::RenameFile(oldname.c_str(), newname.c_str()))
{
std::string err = cmSystemTools::GetLastSystemError();
- cmOStringStream e;
+ std::ostringstream e;
e << "RENAME failed to rename\n"
<< " " << oldname << "\n"
<< "to\n"
<< " " << newname << "\n"
<< "because: " << err << "\n";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
return true;
@@ -2409,18 +2691,18 @@ bool cmFileCommand::HandleRemove(std::vector<std::string> const& args,
std::string fileName = *i;
if(!cmsys::SystemTools::FileIsFullPath(fileName.c_str()))
{
- fileName = this->Makefile->GetCurrentDirectory();
+ fileName = this->Makefile->GetCurrentSourceDirectory();
fileName += "/" + *i;
}
- if(cmSystemTools::FileIsDirectory(fileName.c_str()) &&
- !cmSystemTools::FileIsSymlink(fileName.c_str()) && recurse)
+ if(cmSystemTools::FileIsDirectory(fileName) &&
+ !cmSystemTools::FileIsSymlink(fileName) && recurse)
{
- cmSystemTools::RemoveADirectory(fileName.c_str());
+ cmSystemTools::RemoveADirectory(fileName);
}
else
{
- cmSystemTools::RemoveFile(fileName.c_str());
+ cmSystemTools::RemoveFile(fileName);
}
}
return true;
@@ -2444,7 +2726,7 @@ bool cmFileCommand::HandleCMakePathCommand(std::vector<std::string>
#else
char pathSep = ':';
#endif
- std::vector<cmsys::String> path = cmSystemTools::SplitString(i->c_str(),
+ std::vector<cmsys::String> path = cmSystemTools::SplitString(*i,
pathSep);
i++;
const char* var = i->c_str();
@@ -2490,7 +2772,7 @@ namespace {
void *data)
{
int realsize = (int)(size * nmemb);
- std::ofstream* fout = static_cast<std::ofstream*>(data);
+ cmsys::ofstream* fout = static_cast<cmsys::ofstream*>(data);
const char* chPtr = static_cast<char*>(ptr);
fout->write(chPtr, realsize);
return realsize;
@@ -2511,13 +2793,36 @@ namespace {
static size_t
- cmFileCommandCurlDebugCallback(CURL *, curl_infotype, char *chPtr,
+ cmFileCommandCurlDebugCallback(CURL *, curl_infotype type, char *chPtr,
size_t size, void *data)
{
cmFileCommandVectorOfChar *vec
= static_cast<cmFileCommandVectorOfChar*>(data);
- vec->insert(vec->end(), chPtr, chPtr + size);
- return size;
+ switch(type)
+ {
+ case CURLINFO_TEXT:
+ case CURLINFO_HEADER_IN:
+ case CURLINFO_HEADER_OUT:
+ vec->insert(vec->end(), chPtr, chPtr + size);
+ break;
+ case CURLINFO_DATA_IN:
+ case CURLINFO_DATA_OUT:
+ case CURLINFO_SSL_DATA_IN:
+ case CURLINFO_SSL_DATA_OUT:
+ {
+ char buf[128];
+ int n = sprintf(buf, "[%" KWIML_INT_PRIu64 " bytes data]\n",
+ static_cast<KWIML_INT_uint64_t>(size));
+ if (n > 0)
+ {
+ vec->insert(vec->end(), buf, buf + n);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return 0;
}
@@ -2538,13 +2843,18 @@ namespace {
if (total > 0.0)
{
this->CurrentPercentage = static_cast<int>(value/total*100.0 + 0.5);
+ if(this->CurrentPercentage > 100)
+ {
+ // Avoid extra progress reports for unexpected data beyond total.
+ this->CurrentPercentage = 100;
+ }
}
bool updated = (OldPercentage != this->CurrentPercentage);
if (updated)
{
- cmOStringStream oss;
+ std::ostringstream oss;
oss << "[" << this->Text << " " << this->CurrentPercentage
<< "% complete]";
status = oss.str();
@@ -2648,7 +2958,7 @@ namespace {
{ \
std::string e(errstr); \
e += ::curl_easy_strerror(result); \
- this->SetError(e.c_str()); \
+ this->SetError(e); \
return false; \
}
@@ -2671,7 +2981,7 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
long timeout = 0;
long inactivity_timeout = 0;
- std::string verboseLog;
+ std::string logVar;
std::string statusVar;
bool tls_verify = this->Makefile->IsOn("CMAKE_TLS_VERIFY");
const char* cainfo = this->Makefile->GetDefinition("CMAKE_TLS_CAINFO");
@@ -2716,7 +3026,7 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
this->SetError("DOWNLOAD missing VAR for LOG.");
return false;
}
- verboseLog = *i;
+ logVar = *i;
}
else if(*i == "STATUS")
{
@@ -2784,7 +3094,7 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
std::string err =
"DOWNLOAD EXPECTED_HASH expects ALGO=value but got: ";
err += *i;
- this->SetError(err.c_str());
+ this->SetError(err);
return false;
}
std::string algo = i->substr(0, pos);
@@ -2794,7 +3104,7 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
{
std::string err = "DOWNLOAD EXPECTED_HASH given unknown ALGO: ";
err += algo;
- this->SetError(err.c_str());
+ this->SetError(err);
return false;
}
hashMatchMSG = algo + " hash";
@@ -2808,17 +3118,17 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
if(cmSystemTools::FileExists(file.c_str()) && hash.get())
{
std::string msg;
- std::string actualHash = hash->HashFile(file.c_str());
+ std::string actualHash = hash->HashFile(file);
if(actualHash == expectedHash)
{
msg = "returning early; file already exists with expected ";
msg += hashMatchMSG;
msg += "\"";
- if(statusVar.size())
+ if(!statusVar.empty())
{
- cmOStringStream result;
+ std::ostringstream result;
result << (int)0 << ";\"" << msg;
- this->Makefile->AddDefinition(statusVar.c_str(),
+ this->Makefile->AddDefinition(statusVar,
result.str().c_str());
}
return true;
@@ -2827,24 +3137,28 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
// Make sure parent directory exists so we can write to the file
// as we receive downloaded bits from curl...
//
- std::string dir = cmSystemTools::GetFilenamePath(file.c_str());
+ std::string dir = cmSystemTools::GetFilenamePath(file);
if(!cmSystemTools::FileExists(dir.c_str()) &&
!cmSystemTools::MakeDirectory(dir.c_str()))
{
std::string errstring = "DOWNLOAD error: cannot create directory '"
+ dir + "' - Specify file by full path name and verify that you "
"have directory creation and file write privileges.";
- this->SetError(errstring.c_str());
+ this->SetError(errstring);
return false;
}
- std::ofstream fout(file.c_str(), std::ios::binary);
+ cmsys::ofstream fout(file.c_str(), std::ios::binary);
if(!fout)
{
this->SetError("DOWNLOAD cannot open file for write.");
return false;
}
+#if defined(_WIN32) && defined(CMAKE_ENCODING_UTF8)
+ url = fix_file_url_windows(url);
+#endif
+
::CURL *curl;
::curl_global_init(CURL_GLOBAL_DEFAULT);
curl = ::curl_easy_init();
@@ -2886,10 +3200,11 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
}
// check to see if a CAINFO file has been specified
// command arg comes first
- if(cainfo && *cainfo)
+ std::string const& cainfo_err = cmCurlSetCAInfo(curl, cainfo);
+ if (!cainfo_err.empty())
{
- res = ::curl_easy_setopt(curl, CURLOPT_CAINFO, cainfo);
- check_curl_result(res, "Unable to set TLS/SSL Verify CAINFO: ");
+ this->SetError(cainfo_err);
+ return false;
}
cmFileCommandVectorOfChar chunkDebug;
@@ -2903,7 +3218,7 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
res = ::curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
check_curl_result(res, "DOWNLOAD cannot set follow-redirect option: ");
- if(verboseLog.size())
+ if(!logVar.empty())
{
res = ::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
check_curl_result(res, "DOWNLOAD cannot set verbose: ");
@@ -2949,11 +3264,11 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
g_curl.release();
::curl_easy_cleanup(curl);
- if(statusVar.size())
+ if(!statusVar.empty())
{
- cmOStringStream result;
+ std::ostringstream result;
result << (int)res << ";\"" << ::curl_easy_strerror(res) << "\"";
- this->Makefile->AddDefinition(statusVar.c_str(),
+ this->Makefile->AddDefinition(statusVar,
result.str().c_str());
}
@@ -2968,8 +3283,8 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
//
if (hash.get())
{
- std::string actualHash = hash->HashFile(file.c_str());
- if (actualHash.size() == 0)
+ std::string actualHash = hash->HashFile(file);
+ if (actualHash.empty())
{
this->SetError("DOWNLOAD cannot compute hash on downloaded file");
return false;
@@ -2977,33 +3292,23 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
if (expectedHash != actualHash)
{
- cmOStringStream oss;
+ std::ostringstream oss;
oss << "DOWNLOAD HASH mismatch" << std::endl
<< " for file: [" << file << "]" << std::endl
<< " expected hash: [" << expectedHash << "]" << std::endl
<< " actual hash: [" << actualHash << "]" << std::endl
+ << " status: [" << (int)res << ";\""
+ << ::curl_easy_strerror(res) << "\"]" << std::endl
;
- this->SetError(oss.str().c_str());
+ this->SetError(oss.str());
return false;
}
}
- if(chunkDebug.size())
+ if (!logVar.empty())
{
chunkDebug.push_back(0);
- if(CURLE_OPERATION_TIMEOUTED == res)
- {
- std::string output = &*chunkDebug.begin();
-
- if(verboseLog.size())
- {
- this->Makefile->AddDefinition(verboseLog.c_str(),
- &*chunkDebug.begin());
- }
- }
-
- this->Makefile->AddDefinition(verboseLog.c_str(),
- &*chunkDebug.begin());
+ this->Makefile->AddDefinition(logVar, &*chunkDebug.begin());
}
return true;
@@ -3094,24 +3399,20 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
// Open file for reading:
//
- FILE *fin = fopen(filename.c_str(), "rb");
+ FILE *fin = cmsys::SystemTools::Fopen(filename, "rb");
if(!fin)
{
std::string errStr = "UPLOAD cannot open file '";
errStr += filename + "' for reading.";
- this->SetError(errStr.c_str());
+ this->SetError(errStr);
return false;
}
- struct stat st;
- if(::stat(filename.c_str(), &st))
- {
- std::string errStr = "UPLOAD cannot stat file '";
- errStr += filename + "'.";
- this->SetError(errStr.c_str());
- fclose(fin);
- return false;
- }
+ unsigned long file_size = cmsys::SystemTools::FileLength(filename);
+
+#if defined(_WIN32) && defined(CMAKE_ENCODING_UTF8)
+ url = fix_file_url_windows(url);
+#endif
::CURL *curl;
::curl_global_init(CURL_GLOBAL_DEFAULT);
@@ -3127,6 +3428,7 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
// enable HTTP ERROR parsing
::CURLcode res = ::curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
+ check_curl_result(res, "UPLOAD cannot set fail on error flag: ");
// enable uploading
res = ::curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
@@ -3155,7 +3457,7 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
res = ::curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
check_curl_result(res, "UPLOAD cannot set follow-redirect option: ");
- if(logVar.size())
+ if(!logVar.empty())
{
res = ::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
check_curl_result(res, "UPLOAD cannot set verbose: ");
@@ -3201,7 +3503,7 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
// and give the size of the upload (optional)
res = ::curl_easy_setopt(curl,
- CURLOPT_INFILESIZE, static_cast<long>(st.st_size));
+ CURLOPT_INFILESIZE, static_cast<long>(file_size));
check_curl_result(res, "UPLOAD cannot set input file size: ");
res = ::curl_easy_perform(curl);
@@ -3210,11 +3512,11 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
g_curl.release();
::curl_easy_cleanup(curl);
- if(statusVar.size())
+ if(!statusVar.empty())
{
- cmOStringStream result;
+ std::ostringstream result;
result << (int)res << ";\"" << ::curl_easy_strerror(res) << "\"";
- this->Makefile->AddDefinition(statusVar.c_str(),
+ this->Makefile->AddDefinition(statusVar,
result.str().c_str());
}
@@ -3223,11 +3525,11 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
fclose(fin);
fin = NULL;
- if(logVar.size())
+ if(!logVar.empty())
{
std::string log;
- if(chunkResponse.size())
+ if(!chunkResponse.empty())
{
chunkResponse.push_back(0);
log += "Response:\n";
@@ -3235,7 +3537,7 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
log += "\n";
}
- if(chunkDebug.size())
+ if(!chunkDebug.empty())
{
chunkDebug.push_back(0);
log += "Debug:\n";
@@ -3243,7 +3545,7 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
log += "\n";
}
- this->Makefile->AddDefinition(logVar.c_str(), log.c_str());
+ this->Makefile->AddDefinition(logVar, log.c_str());
}
return true;
@@ -3260,8 +3562,7 @@ void cmFileCommand::AddEvaluationFile(const std::string &inputName,
bool inputIsContent
)
{
- cmListFileBacktrace lfbt;
- this->Makefile->GetBacktrace(lfbt);
+ cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
cmGeneratorExpression outputGe(lfbt);
cmsys::auto_ptr<cmCompiledGeneratorExpression> outputCge
@@ -3271,12 +3572,8 @@ void cmFileCommand::AddEvaluationFile(const std::string &inputName,
cmsys::auto_ptr<cmCompiledGeneratorExpression> conditionCge
= conditionGe.Parse(condition);
- this->Makefile->GetLocalGenerator()
- ->GetGlobalGenerator()->AddEvaluationFile(inputName,
- outputCge,
- this->Makefile,
- conditionCge,
- inputIsContent);
+ this->Makefile->AddEvaluationFile(inputName, outputCge,
+ conditionCge, inputIsContent);
}
//----------------------------------------------------------------------------
@@ -3328,6 +3625,205 @@ bool cmFileCommand::HandleGenerateCommand(
}
//----------------------------------------------------------------------------
+bool cmFileCommand::HandleLockCommand(
+ std::vector<std::string> const& args)
+{
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ // Default values
+ bool directory = false;
+ bool release = false;
+ enum Guard {
+ GUARD_FUNCTION,
+ GUARD_FILE,
+ GUARD_PROCESS
+ };
+ Guard guard = GUARD_PROCESS;
+ std::string resultVariable;
+ unsigned long timeout = static_cast<unsigned long>(-1);
+
+ // Parse arguments
+ if(args.size() < 2)
+ {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ "sub-command LOCK requires at least two arguments.");
+ return false;
+ }
+
+ std::string path = args[1];
+ for (unsigned i = 2; i < args.size(); ++i)
+ {
+ if (args[i] == "DIRECTORY")
+ {
+ directory = true;
+ }
+ else if (args[i] == "RELEASE")
+ {
+ release = true;
+ }
+ else if (args[i] == "GUARD")
+ {
+ ++i;
+ const char* merr = "expected FUNCTION, FILE or PROCESS after GUARD";
+ if (i >= args.size())
+ {
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, merr);
+ return false;
+ }
+ else
+ {
+ if (args[i] == "FUNCTION")
+ {
+ guard = GUARD_FUNCTION;
+ }
+ else if (args[i] == "FILE")
+ {
+ guard = GUARD_FILE;
+ }
+ else if (args[i] == "PROCESS")
+ {
+ guard = GUARD_PROCESS;
+ }
+ else
+ {
+ std::ostringstream e;
+ e << merr << ", but got:\n \"" << args[i] << "\".";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+ }
+ }
+ else if (args[i] == "RESULT_VARIABLE")
+ {
+ ++i;
+ if (i >= args.size())
+ {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ "expected variable name after RESULT_VARIABLE");
+ return false;
+ }
+ resultVariable = args[i];
+ }
+ else if (args[i] == "TIMEOUT")
+ {
+ ++i;
+ if (i >= args.size())
+ {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ "expected timeout value after TIMEOUT");
+ return false;
+ }
+ long scanned;
+ if(!cmSystemTools::StringToLong(args[i].c_str(), &scanned)
+ || scanned < 0)
+ {
+ std::ostringstream e;
+ e << "TIMEOUT value \"" << args[i] << "\" is not an unsigned integer.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+ timeout = static_cast<unsigned long>(scanned);
+ }
+ else
+ {
+ std::ostringstream e;
+ e << "expected DIRECTORY, RELEASE, GUARD, RESULT_VARIABLE or TIMEOUT\n";
+ e << "but got: \"" << args[i] << "\".";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+ }
+
+ if (directory)
+ {
+ path += "/cmake.lock";
+ }
+
+ if (!cmsys::SystemTools::FileIsFullPath(path))
+ {
+ path = this->Makefile->GetCurrentSourceDirectory() + ("/" + path);
+ }
+
+ // Unify path (remove '//', '/../', ...)
+ path = cmSystemTools::CollapseFullPath(path);
+
+ // Create file and directories if needed
+ std::string parentDir = cmSystemTools::GetParentDirectory(path);
+ if (!cmSystemTools::MakeDirectory(parentDir))
+ {
+ std::ostringstream e;
+ e << "directory\n \"" << parentDir << "\"\ncreation failed ";
+ e << "(check permissions).";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+ FILE *file = cmsys::SystemTools::Fopen(path, "w");
+ if (!file)
+ {
+ std::ostringstream e;
+ e << "file\n \"" << path << "\"\ncreation failed (check permissions).";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+ fclose(file);
+
+ // Actual lock/unlock
+ cmFileLockPool& lockPool = this->Makefile->GetGlobalGenerator()
+ ->GetFileLockPool();
+
+ cmFileLockResult fileLockResult(cmFileLockResult::MakeOk());
+ if (release)
+ {
+ fileLockResult = lockPool.Release(path);
+ }
+ else
+ {
+ switch (guard)
+ {
+ case GUARD_FUNCTION:
+ fileLockResult = lockPool.LockFunctionScope(path, timeout);
+ break;
+ case GUARD_FILE:
+ fileLockResult = lockPool.LockFileScope(path, timeout);
+ break;
+ case GUARD_PROCESS:
+ fileLockResult = lockPool.LockProcessScope(path, timeout);
+ break;
+ default:
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+ }
+
+ const std::string result = fileLockResult.GetOutputMessage();
+
+ if (resultVariable.empty() && !fileLockResult.IsOk())
+ {
+ std::ostringstream e;
+ e << "error locking file\n \"" << path << "\"\n" << result << ".";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ if (!resultVariable.empty())
+ {
+ this->Makefile->AddDefinition(resultVariable, result.c_str());
+ }
+
+ return true;
+#else
+ static_cast<void>(args);
+ this->SetError("sub-command LOCK not implemented in bootstrap cmake");
+ return false;
+#endif
+}
+
+//----------------------------------------------------------------------------
bool cmFileCommand::HandleTimestampCommand(
std::vector<std::string> const& args)
{
@@ -3365,7 +3861,7 @@ bool cmFileCommand::HandleTimestampCommand(
{
std::string e = " TIMESTAMP sub-command does not recognize option " +
args[argsIndex] + ".";
- this->SetError(e.c_str());
+ this->SetError(e);
return false;
}
}
@@ -3373,7 +3869,7 @@ bool cmFileCommand::HandleTimestampCommand(
cmTimestamp timestamp;
std::string result = timestamp.FileModificationTime(
filename.c_str(), formatString, utcFlag);
- this->Makefile->AddDefinition(outputVariable.c_str(), result.c_str());
+ this->Makefile->AddDefinition(outputVariable, result.c_str());
return true;
}
diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h
index aa755d1f5..a4d341fa6 100644
--- a/Source/cmFileCommand.h
+++ b/Source/cmFileCommand.h
@@ -46,214 +46,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "file";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "File manipulation command.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " file(WRITE filename \"message to write\"... )\n"
- " file(APPEND filename \"message to write\"... )\n"
- " file(READ filename variable [LIMIT numBytes] [OFFSET offset] [HEX])\n"
- " file(<MD5|SHA1|SHA224|SHA256|SHA384|SHA512> filename variable)\n"
- " file(STRINGS filename variable [LIMIT_COUNT num]\n"
- " [LIMIT_INPUT numBytes] [LIMIT_OUTPUT numBytes]\n"
- " [LENGTH_MINIMUM numBytes] [LENGTH_MAXIMUM numBytes]\n"
- " [NEWLINE_CONSUME] [REGEX regex]\n"
- " [NO_HEX_CONVERSION])\n"
- " file(GLOB variable [RELATIVE path] [globbing expressions]...)\n"
- " file(GLOB_RECURSE variable [RELATIVE path] \n"
- " [FOLLOW_SYMLINKS] [globbing expressions]...)\n"
- " file(RENAME <oldname> <newname>)\n"
- " file(REMOVE [file1 ...])\n"
- " file(REMOVE_RECURSE [file1 ...])\n"
- " file(MAKE_DIRECTORY [directory1 directory2 ...])\n"
- " file(RELATIVE_PATH variable directory file)\n"
- " file(TO_CMAKE_PATH path result)\n"
- " file(TO_NATIVE_PATH path result)\n"
- " file(DOWNLOAD url file [INACTIVITY_TIMEOUT timeout]\n"
- " [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS]\n"
- " [EXPECTED_HASH ALGO=value] [EXPECTED_MD5 sum]\n"
- " [TLS_VERIFY on|off] [TLS_CAINFO file])\n"
- " file(UPLOAD filename url [INACTIVITY_TIMEOUT timeout]\n"
- " [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS])\n"
- " file(TIMESTAMP filename variable [<format string>] [UTC])\n"
- " file(GENERATE OUTPUT output_file\n"
- " <INPUT input_file|CONTENT input_content>\n"
- " [CONDITION expression])\n"
- "WRITE will write a message into a file called 'filename'. It "
- "overwrites the file if it already exists, and creates the file "
- "if it does not exist. (If the file is a build input, use "
- "configure_file to update the file only when its content changes.)\n"
- "APPEND will write a message into a file same as WRITE, except "
- "it will append it to the end of the file\n"
- "READ will read the content of a file and store it into the "
- "variable. It will start at the given offset and read up to numBytes. "
- "If the argument HEX is given, the binary data will be converted to "
- "hexadecimal representation and this will be stored in the variable.\n"
- "MD5, SHA1, SHA224, SHA256, SHA384, and SHA512 "
- "will compute a cryptographic hash of the content of a file.\n"
- "STRINGS will parse a list of ASCII strings from a file and "
- "store it in a variable. Binary data in the file are ignored. Carriage "
- "return (CR) characters are ignored. It works also for Intel Hex and "
- "Motorola S-record files, which are automatically converted to binary "
- "format when reading them. Disable this using NO_HEX_CONVERSION.\n"
- "LIMIT_COUNT sets the maximum number of strings to return. "
- "LIMIT_INPUT sets the maximum number of bytes to read from "
- "the input file. "
- "LIMIT_OUTPUT sets the maximum number of bytes to store in the "
- "output variable. "
- "LENGTH_MINIMUM sets the minimum length of a string to return. "
- "Shorter strings are ignored. "
- "LENGTH_MAXIMUM sets the maximum length of a string to return. Longer "
- "strings are split into strings no longer than the maximum length. "
- "NEWLINE_CONSUME allows newlines to be included in strings instead "
- "of terminating them.\n"
- "REGEX specifies a regular expression that a string must match to be "
- "returned. Typical usage \n"
- " file(STRINGS myfile.txt myfile)\n"
- "stores a list in the variable \"myfile\" in which each item is "
- "a line from the input file.\n"
- "GLOB will generate a list of all files that match the globbing "
- "expressions and store it into the variable. Globbing expressions "
- "are similar to regular expressions, but much simpler. If RELATIVE "
- "flag is specified for an expression, the results will be returned "
- "as a relative path to the given path. "
- "(We do not recommend using GLOB to collect a list of source files "
- "from your source tree. If no CMakeLists.txt file changes when a "
- "source is added or removed then the generated build system cannot "
- "know when to ask CMake to regenerate.)"
- "\n"
- "Examples of globbing expressions include:\n"
- " *.cxx - match all files with extension cxx\n"
- " *.vt? - match all files with extension vta,...,vtz\n"
- " f[3-5].txt - match files f3.txt, f4.txt, f5.txt\n"
- "GLOB_RECURSE will generate a list similar to the regular GLOB, except "
- "it will traverse all the subdirectories of the matched directory and "
- "match the files. Subdirectories that are symlinks are only traversed "
- "if FOLLOW_SYMLINKS is given or cmake policy CMP0009 is not set to NEW. "
- "See cmake --help-policy CMP0009 for more information.\n"
- "Examples of recursive globbing include:\n"
- " /dir/*.py - match all python files in /dir and subdirectories\n"
- "MAKE_DIRECTORY will create the given directories, also if their parent "
- "directories don't exist yet\n"
- "RENAME moves a file or directory within a filesystem, "
- "replacing the destination atomically."
- "\n"
- "REMOVE will remove the given files, also in subdirectories\n"
- "REMOVE_RECURSE will remove the given files and directories, also "
- "non-empty directories\n"
- "RELATIVE_PATH will determine relative path from directory to the given"
- " file.\n"
- "TO_CMAKE_PATH will convert path into a cmake style path with unix /. "
- " The input can be a single path or a system path like \"$ENV{PATH}\". "
- " Note the double quotes around the ENV call TO_CMAKE_PATH only takes "
- " one argument. This command will also convert the native list"
- " delimiters for a list of paths like the PATH environment variable.\n"
- "TO_NATIVE_PATH works just like TO_CMAKE_PATH, but will convert from "
- " a cmake style path into the native path style \\ for windows and / "
- "for UNIX.\n"
- "DOWNLOAD will download the given URL to the given file. "
- "If LOG var is specified a log of the download will be put in var. "
- "If STATUS var is specified the status of the operation will"
- " be put in var. The status is returned in a list of length 2. "
- "The first element is the numeric return value for the operation, "
- "and the second element is a string value for the error. A 0 "
- "numeric error means no error in the operation. "
- "If TIMEOUT time is specified, the operation will "
- "timeout after time seconds, time should be specified as an integer. "
- "The INACTIVITY_TIMEOUT specifies an integer number of seconds of "
- "inactivity after which the operation should terminate. "
- "If EXPECTED_HASH ALGO=value is specified, the operation will verify "
- "that the downloaded file's actual hash matches the expected value, "
- "where ALGO is one of MD5, SHA1, SHA224, SHA256, SHA384, or SHA512. "
- "If it does not match, the operation fails with an error. "
- "(\"EXPECTED_MD5 sum\" is short-hand for \"EXPECTED_HASH MD5=sum\".) "
- "If SHOW_PROGRESS is specified, progress information will be printed "
- "as status messages until the operation is complete. "
- "For https URLs CMake must be built with OpenSSL. "
- "TLS/SSL certificates are not checked by default. "
- "Set TLS_VERIFY to ON to check certificates and/or use "
- "EXPECTED_HASH to verify downloaded content. "
- "Set TLS_CAINFO to specify a custom Certificate Authority file. "
- "If either TLS option is not given CMake will check variables "
- "CMAKE_TLS_VERIFY and CMAKE_TLS_CAINFO, "
- "respectively."
- "\n"
- "UPLOAD will upload the given file to the given URL. "
- "If LOG var is specified a log of the upload will be put in var. "
- "If STATUS var is specified the status of the operation will"
- " be put in var. The status is returned in a list of length 2. "
- "The first element is the numeric return value for the operation, "
- "and the second element is a string value for the error. A 0 "
- "numeric error means no error in the operation. "
- "If TIMEOUT time is specified, the operation will "
- "timeout after time seconds, time should be specified as an integer. "
- "The INACTIVITY_TIMEOUT specifies an integer number of seconds of "
- "inactivity after which the operation should terminate. "
- "If SHOW_PROGRESS is specified, progress information will be printed "
- "as status messages until the operation is complete."
- "\n"
- "TIMESTAMP will write a string representation of "
- "the modification time of filename to variable.\n"
- "Should the command be unable to obtain a timestamp "
- "variable will be set to the empty string \"\".\n"
- "See documentation of the string TIMESTAMP sub-command for more details."
- "\n"
- "The file() command also provides COPY and INSTALL signatures:\n"
- " file(<COPY|INSTALL> files... DESTINATION <dir>\n"
- " [FILE_PERMISSIONS permissions...]\n"
- " [DIRECTORY_PERMISSIONS permissions...]\n"
- " [NO_SOURCE_PERMISSIONS] [USE_SOURCE_PERMISSIONS]\n"
- " [FILES_MATCHING]\n"
- " [[PATTERN <pattern> | REGEX <regex>]\n"
- " [EXCLUDE] [PERMISSIONS permissions...]] [...])\n"
- "The COPY signature copies files, directories, and symlinks to a "
- "destination folder. "
- "Relative input paths are evaluated with respect to the current "
- "source directory, and a relative destination is evaluated with "
- "respect to the current build directory. "
- "Copying preserves input file timestamps, and optimizes out a file "
- "if it exists at the destination with the same timestamp. "
- "Copying preserves input permissions unless explicit permissions or "
- "NO_SOURCE_PERMISSIONS are given (default is USE_SOURCE_PERMISSIONS). "
- "See the install(DIRECTORY) command for documentation of permissions, "
- "PATTERN, REGEX, and EXCLUDE options. "
- "\n"
- "The INSTALL signature differs slightly from COPY: "
- "it prints status messages, and NO_SOURCE_PERMISSIONS is default. "
- "Installation scripts generated by the install() command use this "
- "signature (with some undocumented options for internal use)."
- "\n"
- "GENERATE will write an <output_file> with content from an "
- "<input_file>, or from <input_content>. The output is generated "
- "conditionally based on the content of the <condition>. The file is "
- "written at CMake generate-time and the input may contain generator "
- "expressions. The <condition>, <output_file> and <input_file> may "
- "also contain generator expressions. The <condition> must evaluate to "
- "either '0' or '1'. The <output_file> must evaluate to a unique name "
- "among all configurations and among all invocations of file(GENERATE)."
- // Undocumented INSTALL options:
- // - RENAME <name>
- // - OPTIONAL
- // - FILES keyword to re-enter files... list
- // - PERMISSIONS before REGEX is alias for FILE_PERMISSIONS
- // - DIR_PERMISSIONS is alias for DIRECTORY_PERMISSIONS
- // - TYPE <FILE|DIRECTORY|EXECUTABLE|PROGRAM|
- // STATIC_LIBRARY|SHARED_LIBRARY|MODULE>
- // - COMPONENTS, CONFIGURATIONS, PROPERTIES (ignored for compat)
- ;
- }
+ virtual std::string GetName() const { return "file";}
cmTypeMacro(cmFileCommand, cmCommand);
@@ -282,6 +75,7 @@ protected:
bool HandleTimestampCommand(std::vector<std::string> const& args);
bool HandleGenerateCommand(std::vector<std::string> const& args);
+ bool HandleLockCommand(std::vector<std::string> const& args);
private:
void AddEvaluationFile(const std::string &inputName,
diff --git a/Source/cmFileLock.cxx b/Source/cmFileLock.cxx
new file mode 100644
index 000000000..e6aa5f49d
--- /dev/null
+++ b/Source/cmFileLock.cxx
@@ -0,0 +1,78 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Ruslan Baratov
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmFileLock.h"
+
+#include <assert.h>
+#include "cmFileLockResult.h"
+
+// Common implementation
+
+cmFileLock::~cmFileLock()
+{
+ if (!this->Filename.empty())
+ {
+ const cmFileLockResult result = this->Release();
+ static_cast<void>(result);
+ assert(result.IsOk());
+ }
+}
+
+cmFileLockResult cmFileLock::Lock(
+ const std::string& filename, unsigned long timeout)
+{
+ if (filename.empty())
+ {
+ // Error is internal since all the directories and file must be created
+ // before actual lock called.
+ return cmFileLockResult::MakeInternal();
+ }
+
+ if (!this->Filename.empty())
+ {
+ // Error is internal since double-lock must be checked in class
+ // cmFileLockPool by the cmFileLock::IsLocked method.
+ return cmFileLockResult::MakeInternal();
+ }
+
+ this->Filename = filename;
+ cmFileLockResult result = this->OpenFile();
+ if (result.IsOk())
+ {
+ if (timeout == static_cast<unsigned long>(-1))
+ {
+ result = this->LockWithoutTimeout();
+ }
+ else
+ {
+ result = this->LockWithTimeout(timeout);
+ }
+ }
+
+ if (!result.IsOk())
+ {
+ this->Filename = "";
+ }
+
+ return result;
+}
+
+bool cmFileLock::IsLocked(const std::string& filename) const
+{
+ return filename == this->Filename;
+}
+
+#if defined(_WIN32)
+# include "cmFileLockWin32.cxx"
+#else
+# include "cmFileLockUnix.cxx"
+#endif
diff --git a/Source/cmFileLock.h b/Source/cmFileLock.h
new file mode 100644
index 000000000..dd959a7cd
--- /dev/null
+++ b/Source/cmFileLock.h
@@ -0,0 +1,74 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Ruslan Baratov
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmFileLock_h
+#define cmFileLock_h
+
+#include "cmStandardIncludes.h"
+
+#if defined(_WIN32)
+# include <windows.h> // HANDLE
+#endif
+
+class cmFileLockResult;
+
+/**
+ * @brief Cross-platform file locking.
+ * @details Under the hood this class use 'fcntl' for Unix-like platforms and
+ * 'LockFileEx'/'UnlockFileEx' for Win32 platform. Locks are exclusive and
+ * advisory.
+ */
+class cmFileLock
+{
+ public:
+ cmFileLock();
+ ~cmFileLock();
+
+ /**
+ * @brief Lock the file.
+ * @param timeoutSec Lock timeout. If -1 try until success or fatal error.
+ */
+ cmFileLockResult Lock(const std::string& filename, unsigned long timeoutSec);
+
+ /**
+ * @brief Unlock the file.
+ */
+ cmFileLockResult Release();
+
+ /**
+ * @brief Check file is locked by this class.
+ * @details This function helps to find double locks (deadlocks) and to do
+ * explicit unlocks.
+ */
+ bool IsLocked(const std::string& filename) const;
+
+ private:
+ cmFileLock(const cmFileLock&);
+ cmFileLock& operator=(const cmFileLock&);
+
+ cmFileLockResult OpenFile();
+ cmFileLockResult LockWithoutTimeout();
+ cmFileLockResult LockWithTimeout(unsigned long timeoutSec);
+
+#if defined(_WIN32)
+ typedef HANDLE FileId;
+ BOOL LockFile(DWORD flags);
+#else
+ typedef int FileId;
+ int LockFile(int cmd, int type);
+#endif
+
+ FileId File;
+ std::string Filename;
+};
+
+#endif // cmFileLock_h
diff --git a/Source/cmFileLockPool.cxx b/Source/cmFileLockPool.cxx
new file mode 100644
index 000000000..3710eb030
--- /dev/null
+++ b/Source/cmFileLockPool.cxx
@@ -0,0 +1,188 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Ruslan Baratov
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmFileLockPool.h"
+
+#include <assert.h>
+
+#include "cmFileLock.h"
+#include "cmFileLockResult.h"
+#include "cmAlgorithms.h"
+
+cmFileLockPool::cmFileLockPool()
+{
+}
+
+cmFileLockPool::~cmFileLockPool()
+{
+ cmDeleteAll(this->FunctionScopes);
+ cmDeleteAll(this->FileScopes);
+}
+
+void cmFileLockPool::PushFunctionScope()
+{
+ this->FunctionScopes.push_back(new ScopePool());
+}
+
+void cmFileLockPool::PopFunctionScope()
+{
+ assert(!this->FunctionScopes.empty());
+ delete this->FunctionScopes.back();
+ this->FunctionScopes.pop_back();
+}
+
+void cmFileLockPool::PushFileScope()
+{
+ this->FileScopes.push_back(new ScopePool());
+}
+
+void cmFileLockPool::PopFileScope()
+{
+ assert(!this->FileScopes.empty());
+ delete this->FileScopes.back();
+ this->FileScopes.pop_back();
+}
+
+cmFileLockResult cmFileLockPool::LockFunctionScope(
+ const std::string& filename, unsigned long timeoutSec)
+{
+ if (this->IsAlreadyLocked(filename))
+ {
+ return cmFileLockResult::MakeAlreadyLocked();
+ }
+ if (this->FunctionScopes.empty())
+ {
+ return cmFileLockResult::MakeNoFunction();
+ }
+ return this->FunctionScopes.back()->Lock(filename, timeoutSec);
+}
+
+cmFileLockResult cmFileLockPool::LockFileScope(
+ const std::string& filename, unsigned long timeoutSec)
+{
+ if (this->IsAlreadyLocked(filename))
+ {
+ return cmFileLockResult::MakeAlreadyLocked();
+ }
+ assert(!this->FileScopes.empty());
+ return this->FileScopes.back()->Lock(filename, timeoutSec);
+}
+
+cmFileLockResult cmFileLockPool::LockProcessScope(
+ const std::string& filename, unsigned long timeoutSec)
+{
+ if (this->IsAlreadyLocked(filename))
+ {
+ return cmFileLockResult::MakeAlreadyLocked();
+ }
+ return this->ProcessScope.Lock(filename, timeoutSec);
+}
+
+cmFileLockResult cmFileLockPool::Release(const std::string& filename)
+{
+ for (It i = this->FunctionScopes.begin();
+ i != this->FunctionScopes.end(); ++i)
+ {
+ const cmFileLockResult result = (*i)->Release(filename);
+ if (!result.IsOk())
+ {
+ return result;
+ }
+ }
+
+ for (It i = this->FileScopes.begin(); i != this->FileScopes.end(); ++i)
+ {
+ const cmFileLockResult result = (*i)->Release(filename);
+ if (!result.IsOk())
+ {
+ return result;
+ }
+ }
+
+ return this->ProcessScope.Release(filename);
+}
+
+bool cmFileLockPool::IsAlreadyLocked(const std::string& filename) const
+{
+ for (CIt i = this->FunctionScopes.begin();
+ i != this->FunctionScopes.end(); ++i)
+ {
+ const bool result = (*i)->IsAlreadyLocked(filename);
+ if (result)
+ {
+ return true;
+ }
+ }
+
+ for (CIt i = this->FileScopes.begin(); i != this->FileScopes.end(); ++i)
+ {
+ const bool result = (*i)->IsAlreadyLocked(filename);
+ if (result)
+ {
+ return true;
+ }
+ }
+
+ return this->ProcessScope.IsAlreadyLocked(filename);
+}
+
+cmFileLockPool::ScopePool::ScopePool()
+{
+}
+
+cmFileLockPool::ScopePool::~ScopePool()
+{
+ cmDeleteAll(this->Locks);
+}
+
+cmFileLockResult cmFileLockPool::ScopePool::Lock(
+ const std::string& filename, unsigned long timeoutSec)
+{
+ cmFileLock *lock = new cmFileLock();
+ const cmFileLockResult result = lock->Lock(filename, timeoutSec);
+ if (result.IsOk())
+ {
+ this->Locks.push_back(lock);
+ return cmFileLockResult::MakeOk();
+ }
+ else
+ {
+ delete lock;
+ return result;
+ }
+}
+
+cmFileLockResult cmFileLockPool::ScopePool::Release(
+ const std::string& filename)
+{
+ for (It i = this->Locks.begin(); i != this->Locks.end(); ++i)
+ {
+ if ((*i)->IsLocked(filename))
+ {
+ return (*i)->Release();
+ }
+ }
+ return cmFileLockResult::MakeOk();
+}
+
+bool cmFileLockPool::ScopePool::IsAlreadyLocked(
+ const std::string& filename) const
+{
+ for (CIt i = this->Locks.begin(); i != this->Locks.end(); ++i)
+ {
+ if ((*i)->IsLocked(filename))
+ {
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/Source/cmFileLockPool.h b/Source/cmFileLockPool.h
new file mode 100644
index 000000000..f0614a37a
--- /dev/null
+++ b/Source/cmFileLockPool.h
@@ -0,0 +1,104 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Ruslan Baratov
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmFileLockPool_h
+#define cmFileLockPool_h
+
+#include "cmStandardIncludes.h"
+
+#include <list>
+
+class cmFileLockResult;
+class cmFileLock;
+
+class cmFileLockPool
+{
+ public:
+ cmFileLockPool();
+ ~cmFileLockPool();
+
+ //@{
+ /**
+ * @brief Function scope control.
+ */
+ void PushFunctionScope();
+ void PopFunctionScope();
+ //@}
+
+ //@{
+ /**
+ * @brief File scope control.
+ */
+ void PushFileScope();
+ void PopFileScope();
+ //@}
+
+ //@{
+ /**
+ * @brief Lock the file in given scope.
+ * @param timeoutSec Lock timeout. If -1 try until success or fatal error.
+ */
+ cmFileLockResult LockFunctionScope(
+ const std::string& filename, unsigned long timeoutSec
+ );
+ cmFileLockResult LockFileScope(
+ const std::string& filename, unsigned long timeoutSec
+ );
+ cmFileLockResult LockProcessScope(
+ const std::string& filename, unsigned long timeoutSec
+ );
+ //@}
+
+ /**
+ * @brief Unlock the file explicitly.
+ */
+ cmFileLockResult Release(const std::string& filename);
+
+ private:
+ cmFileLockPool(const cmFileLockPool&);
+ cmFileLockPool& operator=(const cmFileLockPool&);
+
+ bool IsAlreadyLocked(const std::string& filename) const;
+
+ class ScopePool
+ {
+ public:
+ ScopePool();
+ ~ScopePool();
+
+ cmFileLockResult Lock(
+ const std::string& filename, unsigned long timeoutSec
+ );
+ cmFileLockResult Release(const std::string& filename);
+ bool IsAlreadyLocked(const std::string& filename) const;
+
+ private:
+ ScopePool(const ScopePool&);
+ ScopePool& operator=(const ScopePool&);
+
+ typedef std::list<cmFileLock*> List;
+ typedef List::iterator It;
+ typedef List::const_iterator CIt;
+
+ List Locks;
+ };
+
+ typedef std::list<ScopePool*> List;
+
+ typedef List::iterator It;
+ typedef List::const_iterator CIt;
+
+ List FunctionScopes;
+ List FileScopes;
+ ScopePool ProcessScope;
+};
+
+#endif // cmFileLockPool_h
diff --git a/Source/cmFileLockResult.cxx b/Source/cmFileLockResult.cxx
new file mode 100644
index 000000000..045e7ee3c
--- /dev/null
+++ b/Source/cmFileLockResult.cxx
@@ -0,0 +1,111 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Ruslan Baratov
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmFileLockResult.h"
+
+#include <errno.h>
+
+cmFileLockResult cmFileLockResult::MakeOk()
+{
+ return cmFileLockResult(OK, 0);
+}
+
+cmFileLockResult cmFileLockResult::MakeSystem()
+{
+#if defined(_WIN32)
+ const Error lastError = GetLastError();
+#else
+ const Error lastError = errno;
+#endif
+ return cmFileLockResult(SYSTEM, lastError);
+}
+
+cmFileLockResult cmFileLockResult::MakeTimeout()
+{
+ return cmFileLockResult(TIMEOUT, 0);
+}
+
+cmFileLockResult cmFileLockResult::MakeAlreadyLocked()
+{
+ return cmFileLockResult(ALREADY_LOCKED, 0);
+}
+
+cmFileLockResult cmFileLockResult::MakeInternal()
+{
+ return cmFileLockResult(INTERNAL, 0);
+}
+
+cmFileLockResult cmFileLockResult::MakeNoFunction()
+{
+ return cmFileLockResult(NO_FUNCTION, 0);
+}
+
+bool cmFileLockResult::IsOk() const
+{
+ return this->Type == OK;
+}
+
+std::string cmFileLockResult::GetOutputMessage() const
+{
+ switch (this->Type)
+ {
+ case OK:
+ return "0";
+ case SYSTEM:
+#if defined(_WIN32)
+ {
+ char* errorText = NULL;
+
+ // http://stackoverflow.com/a/455533/2288008
+ DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_IGNORE_INSERTS;
+ ::FormatMessageA(
+ flags,
+ NULL,
+ this->ErrorValue,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPSTR)&errorText,
+ 0,
+ NULL
+ );
+
+ if (errorText != NULL)
+ {
+ const std::string message = errorText;
+ ::LocalFree(errorText);
+ return message;
+ }
+ else
+ {
+ return "Internal error (FormatMessageA failed)";
+ }
+ }
+#else
+ return strerror(this->ErrorValue);
+#endif
+ case TIMEOUT:
+ return "Timeout reached";
+ case ALREADY_LOCKED:
+ return "File already locked";
+ case NO_FUNCTION:
+ return "'GUARD FUNCTION' not used in function definition";
+ case INTERNAL:
+ default:
+ return "Internal error";
+ }
+}
+
+cmFileLockResult::cmFileLockResult(ErrorType typeValue, Error errorValue):
+ Type(typeValue), ErrorValue(errorValue)
+{
+}
diff --git a/Source/cmFileLockResult.h b/Source/cmFileLockResult.h
new file mode 100644
index 000000000..531fb49a2
--- /dev/null
+++ b/Source/cmFileLockResult.h
@@ -0,0 +1,85 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Ruslan Baratov
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmFileLockResult_h
+#define cmFileLockResult_h
+
+#include "cmStandardIncludes.h"
+
+#if defined(_WIN32)
+# include <windows.h> // DWORD
+#endif
+
+/**
+ * @brief Result of the locking/unlocking file.
+ * @note See @c cmFileLock
+ */
+class cmFileLockResult
+{
+ public:
+#if defined(_WIN32)
+ typedef DWORD Error;
+#else
+ typedef int Error;
+#endif
+
+ /**
+ * @brief Successful lock/unlock.
+ */
+ static cmFileLockResult MakeOk();
+
+ /**
+ * @brief Lock/Unlock failed. Read error/GetLastError.
+ */
+ static cmFileLockResult MakeSystem();
+
+ /**
+ * @brief Lock/Unlock failed. Timeout reached.
+ */
+ static cmFileLockResult MakeTimeout();
+
+ /**
+ * @brief File already locked.
+ */
+ static cmFileLockResult MakeAlreadyLocked();
+
+ /**
+ * @brief Internal error.
+ */
+ static cmFileLockResult MakeInternal();
+
+ /**
+ * @brief Try to lock with function guard outside of the function
+ */
+ static cmFileLockResult MakeNoFunction();
+
+ bool IsOk() const;
+ std::string GetOutputMessage() const;
+
+ private:
+ enum ErrorType
+ {
+ OK,
+ SYSTEM,
+ TIMEOUT,
+ ALREADY_LOCKED,
+ INTERNAL,
+ NO_FUNCTION
+ };
+
+ cmFileLockResult(ErrorType type, Error errorValue);
+
+ ErrorType Type;
+ Error ErrorValue;
+};
+
+#endif // cmFileLockResult_h
diff --git a/Source/cmFileLockUnix.cxx b/Source/cmFileLockUnix.cxx
new file mode 100644
index 000000000..36a2d7288
--- /dev/null
+++ b/Source/cmFileLockUnix.cxx
@@ -0,0 +1,106 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Ruslan Baratov
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmFileLock.h"
+
+#include <errno.h> // errno
+#include <stdio.h> // SEEK_SET
+#include <fcntl.h>
+#include <unistd.h>
+#include "cmSystemTools.h"
+
+cmFileLock::cmFileLock(): File(-1)
+{
+}
+
+cmFileLockResult cmFileLock::Release()
+{
+ if (this->Filename.empty())
+ {
+ return cmFileLockResult::MakeOk();
+ }
+ const int lockResult = this->LockFile(F_SETLK, F_UNLCK);
+
+ this->Filename = "";
+
+ ::close(this->File);
+ this->File = -1;
+
+ if (lockResult == 0)
+ {
+ return cmFileLockResult::MakeOk();
+ }
+ else
+ {
+ return cmFileLockResult::MakeSystem();
+ }
+}
+
+cmFileLockResult cmFileLock::OpenFile()
+{
+ this->File = ::open(this->Filename.c_str(), O_RDWR);
+ if (this->File == -1)
+ {
+ return cmFileLockResult::MakeSystem();
+ }
+ else
+ {
+ return cmFileLockResult::MakeOk();
+ }
+}
+
+cmFileLockResult cmFileLock::LockWithoutTimeout()
+{
+ if (this->LockFile(F_SETLKW, F_WRLCK) == -1)
+ {
+ return cmFileLockResult::MakeSystem();
+ }
+ else
+ {
+ return cmFileLockResult::MakeOk();
+ }
+}
+
+cmFileLockResult cmFileLock::LockWithTimeout(unsigned long seconds)
+{
+ while (true)
+ {
+ if (this->LockFile(F_SETLK, F_WRLCK) == -1)
+ {
+ if (errno != EACCES && errno != EAGAIN)
+ {
+ return cmFileLockResult::MakeSystem();
+ }
+ }
+ else
+ {
+ return cmFileLockResult::MakeOk();
+ }
+ if (seconds == 0)
+ {
+ return cmFileLockResult::MakeTimeout();
+ }
+ --seconds;
+ cmSystemTools::Delay(1000);
+ }
+}
+
+int cmFileLock::LockFile(int cmd, int type)
+{
+ struct ::flock lock;
+ lock.l_start = 0;
+ lock.l_len = 0; // lock all bytes
+ lock.l_pid = 0; // unused (for F_GETLK only)
+ lock.l_type = static_cast<short>(type); // exclusive lock
+ lock.l_whence = SEEK_SET;
+ return ::fcntl(this->File, cmd, &lock);
+}
diff --git a/Source/cmFileLockWin32.cxx b/Source/cmFileLockWin32.cxx
new file mode 100644
index 000000000..dc65948bd
--- /dev/null
+++ b/Source/cmFileLockWin32.cxx
@@ -0,0 +1,129 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Ruslan Baratov
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmFileLock.h"
+
+#include <windows.h> // CreateFileW
+#include "cmSystemTools.h"
+
+cmFileLock::cmFileLock(): File(INVALID_HANDLE_VALUE)
+{
+}
+
+cmFileLockResult cmFileLock::Release()
+{
+ if (this->Filename.empty())
+ {
+ return cmFileLockResult::MakeOk();
+ }
+ const unsigned long len = static_cast<unsigned long>(-1);
+ static OVERLAPPED overlapped;
+ const DWORD reserved = 0;
+ const BOOL unlockResult = UnlockFileEx(
+ File,
+ reserved,
+ len,
+ len,
+ &overlapped
+ );
+
+ this->Filename = "";
+
+ CloseHandle(this->File);
+ this->File = INVALID_HANDLE_VALUE;
+
+ if (unlockResult)
+ {
+ return cmFileLockResult::MakeOk();
+ }
+ else
+ {
+ return cmFileLockResult::MakeSystem();
+ }
+}
+
+cmFileLockResult cmFileLock::OpenFile()
+{
+ const DWORD access = GENERIC_READ | GENERIC_WRITE;
+ const DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
+ const PSECURITY_ATTRIBUTES security = NULL;
+ const DWORD attr = 0;
+ const HANDLE templ = NULL;
+ this->File = CreateFileW(
+ cmSystemTools::ConvertToWindowsExtendedPath(this->Filename).c_str(),
+ access,
+ shareMode,
+ security,
+ OPEN_EXISTING,
+ attr,
+ templ
+ );
+ if (this->File == INVALID_HANDLE_VALUE)
+ {
+ return cmFileLockResult::MakeSystem();
+ }
+ else
+ {
+ return cmFileLockResult::MakeOk();
+ }
+}
+
+cmFileLockResult cmFileLock::LockWithoutTimeout()
+{
+ if (!this->LockFile(LOCKFILE_EXCLUSIVE_LOCK))
+ {
+ return cmFileLockResult::MakeSystem();
+ }
+ else
+ {
+ return cmFileLockResult::MakeOk();
+ }
+}
+
+cmFileLockResult cmFileLock::LockWithTimeout(unsigned long seconds)
+{
+ const DWORD flags = LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY;
+ while (true)
+ {
+ const BOOL result = this->LockFile(flags);
+ if (result)
+ {
+ return cmFileLockResult::MakeOk();
+ }
+ const DWORD error = GetLastError();
+ if (error != ERROR_LOCK_VIOLATION)
+ {
+ return cmFileLockResult::MakeSystem();
+ }
+ if (seconds == 0)
+ {
+ return cmFileLockResult::MakeTimeout();
+ }
+ --seconds;
+ cmSystemTools::Delay(1000);
+ }
+}
+
+BOOL cmFileLock::LockFile(DWORD flags)
+{
+ const DWORD reserved = 0;
+ const unsigned long len = static_cast<unsigned long>(-1);
+ static OVERLAPPED overlapped;
+ return LockFileEx(
+ this->File,
+ flags,
+ reserved,
+ len,
+ len,
+ &overlapped
+ );
+}
diff --git a/Source/cmFileTimeComparison.cxx b/Source/cmFileTimeComparison.cxx
index 3167be496..279b61da9 100644
--- a/Source/cmFileTimeComparison.cxx
+++ b/Source/cmFileTimeComparison.cxx
@@ -13,8 +13,14 @@
// Use a hash table to avoid duplicate file time checks from disk.
#if defined(CMAKE_BUILD_WITH_CMAKE)
+#ifdef CMake_HAVE_CXX11_UNORDERED_MAP
+#include <unordered_map>
+#else
# include <cmsys/hash_map.hxx>
#endif
+#endif
+
+#include <cmsys/Encoding.hxx>
// Use a platform-specific API to get file times efficiently.
#if !defined(_WIN32) || defined(__CYGWIN__)
@@ -41,13 +47,21 @@ private:
class HashString
{
public:
- size_t operator()(const cmStdString& s) const
+ size_t operator()(const std::string& s) const
{
return h(s.c_str());
}
+#ifdef CMake_HAVE_CXX11_UNORDERED_MAP
+ std::hash<const char*> h;
+#else
cmsys::hash<const char*> h;
+#endif
};
- typedef cmsys::hash_map<cmStdString,
+#ifdef CMake_HAVE_CXX11_UNORDERED_MAP
+ typedef std::unordered_map<std::string,
+#else
+ typedef cmsys::hash_map<std::string,
+#endif
cmFileTimeComparison_Type, HashString> FileStatsMap;
FileStatsMap Files;
#endif
@@ -86,7 +100,8 @@ bool cmFileTimeComparisonInternal::Stat(const char* fname,
// Windows version. Get the modification time from extended file
// attributes.
WIN32_FILE_ATTRIBUTE_DATA fdata;
- if(!GetFileAttributesEx(fname, GetFileExInfoStandard, &fdata))
+ if(!GetFileAttributesExW(cmsys::Encoding::ToWide(fname).c_str(),
+ GetFileExInfoStandard, &fdata))
{
return false;
}
@@ -133,7 +148,7 @@ int cmFileTimeComparisonInternal::Compare(cmFileTimeComparison_Type* s1,
cmFileTimeComparison_Type* s2)
{
#if !defined(_WIN32) || defined(__CYGWIN__)
-# if cmsys_STAT_HAS_ST_MTIM
+# if CMake_STAT_HAS_ST_MTIM
// Compare using nanosecond resolution.
if(s1->st_mtim.tv_sec < s2->st_mtim.tv_sec)
{
@@ -151,6 +166,24 @@ int cmFileTimeComparisonInternal::Compare(cmFileTimeComparison_Type* s1,
{
return 1;
}
+# elif CMake_STAT_HAS_ST_MTIMESPEC
+ // Compare using nanosecond resolution.
+ if(s1->st_mtimespec.tv_sec < s2->st_mtimespec.tv_sec)
+ {
+ return -1;
+ }
+ else if(s1->st_mtimespec.tv_sec > s2->st_mtimespec.tv_sec)
+ {
+ return 1;
+ }
+ else if(s1->st_mtimespec.tv_nsec < s2->st_mtimespec.tv_nsec)
+ {
+ return -1;
+ }
+ else if(s1->st_mtimespec.tv_nsec > s2->st_mtimespec.tv_nsec)
+ {
+ return 1;
+ }
# else
// Compare using 1 second resolution.
if(s1->st_mtime < s2->st_mtime)
@@ -175,7 +208,7 @@ bool cmFileTimeComparisonInternal::TimesDiffer(cmFileTimeComparison_Type* s1,
cmFileTimeComparison_Type* s2)
{
#if !defined(_WIN32) || defined(__CYGWIN__)
-# if cmsys_STAT_HAS_ST_MTIM
+# if CMake_STAT_HAS_ST_MTIM
// Times are integers in units of 1ns.
long long bil = 1000000000;
long long t1 = s1->st_mtim.tv_sec * bil + s1->st_mtim.tv_nsec;
@@ -192,6 +225,23 @@ bool cmFileTimeComparisonInternal::TimesDiffer(cmFileTimeComparison_Type* s1,
{
return false;
}
+# elif CMake_STAT_HAS_ST_MTIMESPEC
+ // Times are integers in units of 1ns.
+ long long bil = 1000000000;
+ long long t1 = s1->st_mtimespec.tv_sec * bil + s1->st_mtimespec.tv_nsec;
+ long long t2 = s2->st_mtimespec.tv_sec * bil + s2->st_mtimespec.tv_nsec;
+ if(t1 < t2)
+ {
+ return (t2 - t1) >= bil;
+ }
+ else if(t2 < t1)
+ {
+ return (t1 - t2) >= bil;
+ }
+ else
+ {
+ return false;
+ }
# else
// Times are integers in units of 1s.
if(s1->st_mtime < s2->st_mtime)
diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx
index 7ce003216..fa9b38154 100644
--- a/Source/cmFindBase.cxx
+++ b/Source/cmFindBase.cxx
@@ -11,6 +11,9 @@
============================================================================*/
#include "cmFindBase.h"
+#include "cmAlgorithms.h"
+#include "cmState.h"
+
cmFindBase::cmFindBase()
{
this->AlreadyInCache = false;
@@ -20,106 +23,6 @@ cmFindBase::cmFindBase()
}
//----------------------------------------------------------------------------
-void cmFindBase::GenerateDocumentation()
-{
- this->cmFindCommon::GenerateDocumentation();
- cmSystemTools::ReplaceString(this->GenericDocumentationPathsOrder,
- "FIND_ARGS_XXX", "<VAR> NAMES name");
- this->GenericDocumentation =
- " FIND_XXX(<VAR> name1 [path1 path2 ...])\n"
- "This is the short-hand signature for the command that "
- "is sufficient in many cases. It is the same "
- "as FIND_XXX(<VAR> name1 [PATHS path1 path2 ...])\n"
- " FIND_XXX(\n"
- " <VAR>\n"
- " name | NAMES name1 [name2 ...]\n"
- " [HINTS path1 [path2 ... ENV var]]\n"
- " [PATHS path1 [path2 ... ENV var]]\n"
- " [PATH_SUFFIXES suffix1 [suffix2 ...]]\n"
- " [DOC \"cache documentation string\"]\n"
- " [NO_DEFAULT_PATH]\n"
- " [NO_CMAKE_ENVIRONMENT_PATH]\n"
- " [NO_CMAKE_PATH]\n"
- " [NO_SYSTEM_ENVIRONMENT_PATH]\n"
- " [NO_CMAKE_SYSTEM_PATH]\n"
- " [CMAKE_FIND_ROOT_PATH_BOTH |\n"
- " ONLY_CMAKE_FIND_ROOT_PATH |\n"
- " NO_CMAKE_FIND_ROOT_PATH]\n"
- " )\n"
- ""
- "This command is used to find a SEARCH_XXX_DESC. "
- "A cache entry named by <VAR> is created to store the result "
- "of this command. "
- "If the SEARCH_XXX is found the result is stored in the variable "
- "and the search will not be repeated unless the variable is cleared. "
- "If nothing is found, the result will be "
- "<VAR>-NOTFOUND, and the search will be attempted again the "
- "next time FIND_XXX is invoked with the same variable. "
- "The name of the SEARCH_XXX that "
- "is searched for is specified by the names listed "
- "after the NAMES argument. Additional search locations "
- "can be specified after the PATHS argument. If ENV var is "
- "found in the HINTS or PATHS section the environment variable var "
- "will be read and converted from a system environment variable to "
- "a cmake style list of paths. For example ENV PATH would be a way "
- "to list the system path variable. The argument "
- "after DOC will be used for the documentation string in "
- "the cache. "
- "PATH_SUFFIXES specifies additional subdirectories to check below "
- "each search path."
- "\n"
- "If NO_DEFAULT_PATH is specified, then no additional paths are "
- "added to the search. "
- "If NO_DEFAULT_PATH is not specified, the search process is as follows:\n"
- "1. Search paths specified in cmake-specific cache variables. "
- "These are intended to be used on the command line with a -DVAR=value. "
- "This can be skipped if NO_CMAKE_PATH is passed.\n"
- "XXX_EXTRA_PREFIX_ENTRY"
- " <prefix>/XXX_SUBDIR for each <prefix> in CMAKE_PREFIX_PATH\n"
- " CMAKE_XXX_PATH\n"
- " CMAKE_XXX_MAC_PATH\n"
- "2. Search paths specified in cmake-specific environment variables. "
- "These are intended to be set in the user's shell configuration. "
- "This can be skipped if NO_CMAKE_ENVIRONMENT_PATH is passed.\n"
- "XXX_EXTRA_PREFIX_ENTRY"
- " <prefix>/XXX_SUBDIR for each <prefix> in CMAKE_PREFIX_PATH\n"
- " CMAKE_XXX_PATH\n"
- " CMAKE_XXX_MAC_PATH\n"
- "3. Search the paths specified by the HINTS option. "
- "These should be paths computed by system introspection, such as a "
- "hint provided by the location of another item already found. "
- "Hard-coded guesses should be specified with the PATHS option.\n"
- "4. Search the standard system environment variables. "
- "This can be skipped if NO_SYSTEM_ENVIRONMENT_PATH is an argument.\n"
- " PATH\n"
- " XXX_SYSTEM\n" // replace with "", LIB, or INCLUDE
- "5. Search cmake variables defined in the Platform files "
- "for the current system. This can be skipped if NO_CMAKE_SYSTEM_PATH "
- "is passed.\n"
- "XXX_EXTRA_PREFIX_ENTRY"
- " <prefix>/XXX_SUBDIR for each <prefix> in CMAKE_SYSTEM_PREFIX_PATH\n"
- " CMAKE_SYSTEM_XXX_PATH\n"
- " CMAKE_SYSTEM_XXX_MAC_PATH\n"
- "6. Search the paths specified by the PATHS option "
- "or in the short-hand version of the command. "
- "These are typically hard-coded guesses.\n"
- ;
- this->GenericDocumentation += this->GenericDocumentationMacPolicy;
- this->GenericDocumentation += this->GenericDocumentationRootPath;
- this->GenericDocumentation += this->GenericDocumentationPathsOrder;
-}
-
-//----------------------------------------------------------------------------
-const char* cmFindBase::GetFullDocumentation() const
-{
- if(this->GenericDocumentation.empty())
- {
- const_cast<cmFindBase *>(this)->GenerateDocumentation();
- }
- return this->GenericDocumentation.c_str();
-}
-
-//----------------------------------------------------------------------------
bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
{
if(argsIn.size() < 2 )
@@ -128,11 +31,6 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
return false;
}
- // CMake versions below 2.3 did not search all these extra
- // locations. Preserve compatibility unless a modern argument is
- // passed.
- bool compatibility = this->Makefile->NeedBackwardsCompatibility(2,3);
-
// copy argsIn into args so it can be modified,
// in the process extract the DOC "documentation"
size_t size = argsIn.size();
@@ -212,7 +110,6 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
else if (args[j] == "PATH_SUFFIXES")
{
doing = DoingPathSuffixes;
- compatibility = false;
newStyle = true;
}
else if (args[j] == "NAMES_PER_DIR")
@@ -236,7 +133,6 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
else if (this->CheckCommonArgument(args[j]))
{
doing = DoingNone;
- compatibility = false;
// Some common arguments were accidentally supported by CMake
// 2.4 and 2.6.0 in the short-hand form of the command, so we
// must support it even though it is not documented.
@@ -247,11 +143,11 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
}
else if(doing == DoingPaths)
{
- this->AddUserPath(args[j], this->UserPaths);
+ this->UserGuessArgs.push_back(args[j]);
}
else if(doing == DoingHints)
{
- this->AddUserPath(args[j], this->UserHints);
+ this->UserHintsArgs.push_back(args[j]);
}
else if(doing == DoingPathSuffixes)
{
@@ -259,21 +155,10 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
}
}
- // Now that arguments have been parsed check the compatibility
- // setting. If we need to be compatible with CMake 2.2 and earlier
- // do not add the CMake system paths. It is safe to add the CMake
- // environment paths and system environment paths because that
- // existed in 2.2. It is safe to add the CMake user variable paths
- // because the user or project has explicitly set them.
- if(compatibility)
- {
- this->NoCMakeSystemPath = true;
- }
-
- if(this->VariableDocumentation.size() == 0)
+ if(this->VariableDocumentation.empty())
{
this->VariableDocumentation = "Where can ";
- if(this->Names.size() == 0)
+ if(this->Names.empty())
{
this->VariableDocumentation += "the (unknown) library be found";
}
@@ -284,11 +169,9 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
}
else
{
- this->VariableDocumentation += "one of the " + this->Names[0];
- for (unsigned int j = 1; j < this->Names.size() - 1; ++j)
- {
- this->VariableDocumentation += ", " + this->Names[j];
- }
+ this->VariableDocumentation += "one of the ";
+ this->VariableDocumentation +=
+ cmJoin(cmMakeRange(this->Names).retreat(1), ", ");
this->VariableDocumentation += " or "
+ this->Names[this->Names.size() - 1] + " libraries be found";
}
@@ -302,18 +185,11 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
std::vector<std::string> shortArgs = this->Names;
this->Names.clear(); // clear out any values in Names
this->Names.push_back(shortArgs[0]);
- for(unsigned int j = 1; j < shortArgs.size(); ++j)
- {
- this->AddUserPath(shortArgs[j], this->UserPaths);
- }
+ this->UserGuessArgs.insert(this->UserGuessArgs.end(),
+ shortArgs.begin() + 1, shortArgs.end());
}
this->ExpandPaths();
- // Filter out ignored paths from the prefix list
- std::set<std::string> ignored;
- this->GetIgnoredPaths(ignored);
- this->FilterPaths(this->SearchPaths, ignored);
-
this->ComputeFinalPaths();
return true;
@@ -321,226 +197,145 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
void cmFindBase::ExpandPaths()
{
- this->AddCMakeVariablePath();
- this->AddCMakeEnvironmentPath();
- this->AddUserHintsPath();
- this->AddSystemEnvironmentPath();
- this->AddCMakeSystemVariablePath();
- this->AddUserGuessPath();
-
- // Add suffixes and clean up paths.
- this->AddPathSuffixes();
-}
-
-//----------------------------------------------------------------------------
-void cmFindBase::AddPrefixPaths(std::vector<std::string> const& in_paths,
- PathType pathType)
-{
- // default for programs
- std::string subdir = "bin";
-
- if (this->CMakePathName == "INCLUDE")
- {
- subdir = "include";
- }
- else if (this->CMakePathName == "LIBRARY")
- {
- subdir = "lib";
- }
- else if (this->CMakePathName == "FRAMEWORK")
+ if(!this->NoDefaultPath)
{
- subdir = ""; // ? what to do for frameworks ?
- }
-
- for(std::vector<std::string>::const_iterator it = in_paths.begin();
- it != in_paths.end(); ++it)
- {
- std::string dir = it->c_str();
- if(!subdir.empty() && !dir.empty() && dir[dir.size()-1] != '/')
+ if(!this->NoCMakePath)
{
- dir += "/";
- }
- if(subdir == "include" || subdir == "lib")
- {
- const char* arch =
- this->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE");
- if(arch && *arch)
- {
- this->AddPathInternal(dir+subdir+"/"+arch, pathType);
- }
+ this->FillCMakeVariablePath();
}
- std::string add = dir + subdir;
- if(add != "/")
+ if(!this->NoCMakeEnvironmentPath)
{
- this->AddPathInternal(add, pathType);
+ this->FillCMakeEnvironmentPath();
}
- if (subdir == "bin")
+ }
+ this->FillUserHintsPath();
+ if(!this->NoDefaultPath)
+ {
+ if(!this->NoSystemEnvironmentPath)
{
- this->AddPathInternal(dir+"sbin", pathType);
+ this->FillSystemEnvironmentPath();
}
- if(!subdir.empty() && *it != "/")
+ if(!this->NoCMakeSystemPath)
{
- this->AddPathInternal(*it, pathType);
+ this->FillCMakeSystemVariablePath();
}
}
+ this->FillUserGuessPath();
}
//----------------------------------------------------------------------------
-void cmFindBase::AddCMakePrefixPath(const char* variable)
+void cmFindBase::FillCMakeEnvironmentPath()
{
- // Get a path from a CMake variable.
- if(const char* varPath = this->Makefile->GetDefinition(variable))
- {
- std::vector<std::string> tmp;
- cmSystemTools::ExpandListArgument(varPath, tmp);
- this->AddPrefixPaths(tmp, CMakePath);
- }
-}
+ cmSearchPath &paths = this->LabeledPaths[PathLabel::CMakeEnvironment];
-//----------------------------------------------------------------------------
-void cmFindBase::AddEnvPrefixPath(const char* variable)
-{
- // Get a path from the environment.
- std::vector<std::string> tmp;
- cmSystemTools::GetPath(tmp, variable);
- this->AddPrefixPaths(tmp, EnvPath);
-}
+ // Add CMAKE_*_PATH environment variables
+ std::string var = "CMAKE_";
+ var += this->CMakePathName;
+ var += "_PATH";
+ paths.AddEnvPrefixPath("CMAKE_PREFIX_PATH");
+ paths.AddEnvPath(var);
-//----------------------------------------------------------------------------
-void cmFindBase::AddCMakeEnvironmentPath()
-{
- if(!this->NoCMakeEnvironmentPath && !this->NoDefaultPath)
+ if(this->CMakePathName == "PROGRAM")
{
- // Add CMAKE_*_PATH environment variables
- std::string var = "CMAKE_";
- var += this->CMakePathName;
- var += "_PATH";
- this->AddEnvPrefixPath("CMAKE_PREFIX_PATH");
- this->AddEnvPath(var.c_str());
-
- if(this->CMakePathName == "PROGRAM")
- {
- this->AddEnvPath("CMAKE_APPBUNDLE_PATH");
- }
- else
- {
- this->AddEnvPath("CMAKE_FRAMEWORK_PATH");
- }
+ paths.AddEnvPath("CMAKE_APPBUNDLE_PATH");
+ }
+ else
+ {
+ paths.AddEnvPath("CMAKE_FRAMEWORK_PATH");
}
+ paths.AddSuffixes(this->SearchPathSuffixes);
}
//----------------------------------------------------------------------------
-void cmFindBase::AddCMakeVariablePath()
+void cmFindBase::FillCMakeVariablePath()
{
- if(!this->NoCMakePath && !this->NoDefaultPath)
+ cmSearchPath &paths = this->LabeledPaths[PathLabel::CMake];
+
+ // Add CMake varibles of the same name as the previous environment
+ // varibles CMAKE_*_PATH to be used most of the time with -D
+ // command line options
+ std::string var = "CMAKE_";
+ var += this->CMakePathName;
+ var += "_PATH";
+ paths.AddCMakePrefixPath("CMAKE_PREFIX_PATH");
+ paths.AddCMakePath(var);
+
+ if(this->CMakePathName == "PROGRAM")
{
- // Add CMake varibles of the same name as the previous environment
- // varibles CMAKE_*_PATH to be used most of the time with -D
- // command line options
- std::string var = "CMAKE_";
- var += this->CMakePathName;
- var += "_PATH";
- this->AddCMakePrefixPath("CMAKE_PREFIX_PATH");
- this->AddCMakePath(var.c_str());
-
- if(this->CMakePathName == "PROGRAM")
- {
- this->AddCMakePath("CMAKE_APPBUNDLE_PATH");
- }
- else
- {
- this->AddCMakePath("CMAKE_FRAMEWORK_PATH");
- }
+ paths.AddCMakePath("CMAKE_APPBUNDLE_PATH");
+ }
+ else
+ {
+ paths.AddCMakePath("CMAKE_FRAMEWORK_PATH");
}
+ paths.AddSuffixes(this->SearchPathSuffixes);
}
//----------------------------------------------------------------------------
-void cmFindBase::AddSystemEnvironmentPath()
+void cmFindBase::FillSystemEnvironmentPath()
{
- if(!this->NoSystemEnvironmentPath && !this->NoDefaultPath)
+ cmSearchPath &paths = this->LabeledPaths[PathLabel::SystemEnvironment];
+
+ // Add LIB or INCLUDE
+ if(!this->EnvironmentPath.empty())
{
- // Add LIB or INCLUDE
- if(!this->EnvironmentPath.empty())
- {
- this->AddEnvPath(this->EnvironmentPath.c_str());
- }
- // Add PATH
- this->AddEnvPath(0);
+ paths.AddEnvPath(this->EnvironmentPath);
+ paths.AddEnvPrefixPath("PATH", true);
}
+ // Add PATH
+ paths.AddEnvPath("PATH");
+ paths.AddSuffixes(this->SearchPathSuffixes);
}
//----------------------------------------------------------------------------
-void cmFindBase::AddCMakeSystemVariablePath()
+void cmFindBase::FillCMakeSystemVariablePath()
{
- if(!this->NoCMakeSystemPath && !this->NoDefaultPath)
- {
- std::string var = "CMAKE_SYSTEM_";
- var += this->CMakePathName;
- var += "_PATH";
- this->AddCMakePrefixPath("CMAKE_SYSTEM_PREFIX_PATH");
- this->AddCMakePath(var.c_str());
+ cmSearchPath &paths = this->LabeledPaths[PathLabel::CMakeSystem];
- if(this->CMakePathName == "PROGRAM")
- {
- this->AddCMakePath("CMAKE_SYSTEM_APPBUNDLE_PATH");
- }
- else
- {
- this->AddCMakePath("CMAKE_SYSTEM_FRAMEWORK_PATH");
- }
+ std::string var = "CMAKE_SYSTEM_";
+ var += this->CMakePathName;
+ var += "_PATH";
+ paths.AddCMakePrefixPath("CMAKE_SYSTEM_PREFIX_PATH");
+ paths.AddCMakePath(var);
+
+ if(this->CMakePathName == "PROGRAM")
+ {
+ paths.AddCMakePath("CMAKE_SYSTEM_APPBUNDLE_PATH");
+ }
+ else
+ {
+ paths.AddCMakePath("CMAKE_SYSTEM_FRAMEWORK_PATH");
}
+ paths.AddSuffixes(this->SearchPathSuffixes);
}
//----------------------------------------------------------------------------
-void cmFindBase::AddUserHintsPath()
+void cmFindBase::FillUserHintsPath()
{
- this->AddPathsInternal(this->UserHints, CMakePath);
-}
+ cmSearchPath &paths = this->LabeledPaths[PathLabel::Hints];
-//----------------------------------------------------------------------------
-void cmFindBase::AddUserGuessPath()
-{
- this->AddPathsInternal(this->UserPaths, CMakePath);
+ for(std::vector<std::string>::const_iterator p = this->UserHintsArgs.begin();
+ p != this->UserHintsArgs.end(); ++p)
+ {
+ paths.AddUserPath(*p);
+ }
+ paths.AddSuffixes(this->SearchPathSuffixes);
}
//----------------------------------------------------------------------------
-void cmFindBase::AddPathSuffixes()
+void cmFindBase::FillUserGuessPath()
{
- std::vector<std::string>& paths = this->SearchPaths;
- std::vector<std::string> finalPath = paths;
- std::vector<std::string>::iterator i;
- // clear the path
- paths.clear();
- // convert all paths to unix slashes and add search path suffixes
- // if there are any
- for(i = finalPath.begin();
- i != finalPath.end(); ++i)
+ cmSearchPath &paths = this->LabeledPaths[PathLabel::Guess];
+
+ for(std::vector<std::string>::const_iterator p = this->UserGuessArgs.begin();
+ p != this->UserGuessArgs.end(); ++p)
{
- cmSystemTools::ConvertToUnixSlashes(*i);
- // copy each finalPath combined with SearchPathSuffixes
- // to the SearchPaths ivar
- for(std::vector<std::string>::iterator j =
- this->SearchPathSuffixes.begin();
- j != this->SearchPathSuffixes.end(); ++j)
- {
- // if *i is only / then do not add a //
- // this will get incorrectly considered a network
- // path on windows and cause huge delays.
- std::string p = *i;
- if(p.size() && p[p.size()-1] != '/')
- {
- p += std::string("/");
- }
- p += *j;
- // add to all paths because the search path may be modified
- // later with lib being replaced for lib64 which may exist
- paths.push_back(p);
- }
- // now put the path without the path suffixes in the SearchPaths
- paths.push_back(*i);
+ paths.AddUserPath(*p);
}
+ paths.AddSuffixes(this->SearchPathSuffixes);
}
+//----------------------------------------------------------------------------
void cmFindBase::PrintFindStuff()
{
std::cerr << "SearchFrameworkLast: " << this->SearchFrameworkLast << "\n";
@@ -561,43 +356,31 @@ void cmFindBase::PrintFindStuff()
std::cerr << "NoCMakeSystemPath " << this->NoCMakeSystemPath << "\n";
std::cerr << "EnvironmentPath " << this->EnvironmentPath << "\n";
std::cerr << "CMakePathName " << this->CMakePathName << "\n";
- std::cerr << "Names ";
- for(unsigned int i =0; i < this->Names.size(); ++i)
- {
- std::cerr << this->Names[i] << " ";
- }
- std::cerr << "\n";
+ std::cerr << "Names " << cmJoin(this->Names, " ") << "\n";
std::cerr << "\n";
std::cerr << "SearchPathSuffixes ";
- for(unsigned int i =0; i < this->SearchPathSuffixes.size(); ++i)
- {
- std::cerr << this->SearchPathSuffixes[i] << "\n";
- }
- std::cerr << "\n";
+ std::cerr << cmJoin(this->SearchPathSuffixes, "\n") << "\n";
std::cerr << "SearchPaths\n";
- for(unsigned int i =0; i < this->SearchPaths.size(); ++i)
- {
- std::cerr << "[" << this->SearchPaths[i] << "]\n";
- }
+ std::cerr << cmWrap("[", this->SearchPaths, "]", "\n") << "\n";
}
bool cmFindBase::CheckForVariableInCache()
{
if(const char* cacheValue =
- this->Makefile->GetDefinition(this->VariableName.c_str()))
+ this->Makefile->GetDefinition(this->VariableName))
{
- cmCacheManager::CacheIterator it =
- this->Makefile->GetCacheManager()->
- GetCacheIterator(this->VariableName.c_str());
+ cmState* state = this->Makefile->GetState();
+ const char* cacheEntry = state->GetCacheEntryValue(this->VariableName);
bool found = !cmSystemTools::IsNOTFOUND(cacheValue);
- bool cached = !it.IsAtEnd();
+ bool cached = cacheEntry ? true : false;
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)
+ if(cached && state->GetCacheEntryType(this->VariableName)
+ == cmState::UNINITIALIZED)
{
this->AlreadyInCacheWithoutMetaInfo = true;
}
@@ -605,7 +388,8 @@ bool cmFindBase::CheckForVariableInCache()
}
else if(cached)
{
- const char* hs = it.GetProperty("HELPSTRING");
+ const char* hs = state->GetCacheEntryProperty(this->VariableName,
+ "HELPSTRING");
this->VariableDocumentation = hs?hs:"(none)";
}
}
diff --git a/Source/cmFindBase.h b/Source/cmFindBase.h
index 84b03300c..8ca311dd2 100644
--- a/Source/cmFindBase.h
+++ b/Source/cmFindBase.h
@@ -31,46 +31,35 @@ public:
virtual bool ParseArguments(std::vector<std::string> const& args);
cmTypeMacro(cmFindBase, cmFindCommon);
- virtual const char* GetFullDocumentation() const;
-
protected:
- virtual void GenerateDocumentation();
void PrintFindStuff();
void ExpandPaths();
- void AddPathSuffixes();
// see if the VariableName is already set in the cache,
// also copy the documentation from the cache to VariableDocumentation
// if it has documentation in the cache
bool CheckForVariableInCache();
- cmStdString GenericDocumentation;
// use by command during find
- cmStdString VariableDocumentation;
- cmStdString VariableName;
+ std::string VariableDocumentation;
+ std::string VariableName;
std::vector<std::string> Names;
bool NamesPerDir;
bool NamesPerDirAllowed;
// CMAKE_*_PATH CMAKE_SYSTEM_*_PATH FRAMEWORK|LIBRARY|INCLUDE|PROGRAM
- cmStdString EnvironmentPath; // LIB,INCLUDE
+ std::string EnvironmentPath; // LIB,INCLUDE
bool AlreadyInCache;
bool AlreadyInCacheWithoutMetaInfo;
private:
// Add pieces of the search.
- void AddCMakeEnvironmentPath();
- void AddCMakeVariablePath();
- void AddSystemEnvironmentPath();
- void AddCMakeSystemVariablePath();
- void AddUserHintsPath();
- void AddUserGuessPath();
-
- // Helpers.
- void AddCMakePrefixPath(const char* variable);
- void AddEnvPrefixPath(const char* variable);
- void AddPrefixPaths(std::vector<std::string> const& in_paths,
- PathType pathType);
+ void FillCMakeVariablePath();
+ void FillCMakeEnvironmentPath();
+ void FillUserHintsPath();
+ void FillSystemEnvironmentPath();
+ void FillCMakeSystemVariablePath();
+ void FillUserGuessPath();
};
diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx
index b44864e13..913985fdb 100644
--- a/Source/cmFindCommon.cxx
+++ b/Source/cmFindCommon.cxx
@@ -10,6 +10,19 @@
See the License for more information.
============================================================================*/
#include "cmFindCommon.h"
+#include <functional>
+#include <algorithm>
+
+//----------------------------------------------------------------------------
+cmFindCommon::PathGroup cmFindCommon::PathGroup::All("ALL");
+cmFindCommon::PathLabel cmFindCommon::PathLabel::CMake("CMAKE");
+cmFindCommon::PathLabel
+ cmFindCommon::PathLabel::CMakeEnvironment("CMAKE_ENVIRONMENT");
+cmFindCommon::PathLabel cmFindCommon::PathLabel::Hints("HINTS");
+cmFindCommon::PathLabel
+ cmFindCommon::PathLabel::SystemEnvironment("SYSTM_ENVIRONMENT");
+cmFindCommon::PathLabel cmFindCommon::PathLabel::CMakeSystem("CMAKE_SYSTEM");
+cmFindCommon::PathLabel cmFindCommon::PathLabel::Guess("GUESS");
//----------------------------------------------------------------------------
cmFindCommon::cmFindCommon()
@@ -34,80 +47,64 @@ cmFindCommon::cmFindCommon()
this->SearchFrameworkLast = false;
this->SearchAppBundleOnly = false;
this->SearchAppBundleLast = false;
+
+ this->InitializeSearchPathGroups();
}
//----------------------------------------------------------------------------
-void cmFindCommon::GenerateDocumentation()
+cmFindCommon::~cmFindCommon()
{
- // Documentation components.
- this->GenericDocumentationMacPolicy =
- "On Darwin or systems supporting OS X Frameworks, the cmake variable"
- " CMAKE_FIND_FRAMEWORK can be set to empty or one of the following:\n"
- " \"FIRST\" - Try to find frameworks before standard\n"
- " libraries or headers. This is the default on Darwin.\n"
- " \"LAST\" - Try to find frameworks after standard\n"
- " libraries or headers.\n"
- " \"ONLY\" - Only try to find frameworks.\n"
- " \"NEVER\" - Never try to find frameworks.\n"
- "On Darwin or systems supporting OS X Application Bundles, the cmake "
- "variable CMAKE_FIND_APPBUNDLE can be set to empty or one of the "
- "following:\n"
- " \"FIRST\" - Try to find application bundles before standard\n"
- " programs. This is the default on Darwin.\n"
- " \"LAST\" - Try to find application bundles after standard\n"
- " programs.\n"
- " \"ONLY\" - Only try to find application bundles.\n"
- " \"NEVER\" - Never try to find application bundles.\n";
- this->GenericDocumentationRootPath =
- "The CMake variable CMAKE_FIND_ROOT_PATH specifies one or more "
- "directories to be prepended to all other search directories. "
- "This effectively \"re-roots\" the entire search under given locations. "
- "By default it is empty. It is especially useful when "
- "cross-compiling to point to the root directory of the "
- "target environment and CMake will search there too. By default at first "
- "the directories listed in CMAKE_FIND_ROOT_PATH and then the non-rooted "
- "directories will be searched. "
- "The default behavior can be adjusted by setting "
- "CMAKE_FIND_ROOT_PATH_MODE_XXX. This behavior can be manually "
- "overridden on a per-call basis. "
- "By using CMAKE_FIND_ROOT_PATH_BOTH the search order will "
- "be as described above. If NO_CMAKE_FIND_ROOT_PATH is used "
- "then CMAKE_FIND_ROOT_PATH will not be used. If ONLY_CMAKE_FIND_ROOT_PATH "
- "is used then only the re-rooted directories will be searched.\n";
- this->GenericDocumentationPathsOrder =
- "The default search order is designed to be most-specific to "
- "least-specific for common use cases. "
- "Projects may override the order by simply calling the command "
- "multiple times and using the NO_* options:\n"
- " FIND_XXX(FIND_ARGS_XXX PATHS paths... NO_DEFAULT_PATH)\n"
- " FIND_XXX(FIND_ARGS_XXX)\n"
- "Once one of the calls succeeds the result variable will be set "
- "and stored in the cache so that no call will search again.";
}
//----------------------------------------------------------------------------
-cmFindCommon::~cmFindCommon()
+void cmFindCommon::InitializeSearchPathGroups()
{
+ std::vector<PathLabel>* labels;
+
+ // Define the varoius different groups of path types
+
+ // All search paths
+ labels = &this->PathGroupLabelMap[PathGroup::All];
+ labels->push_back(PathLabel::CMake);
+ labels->push_back(PathLabel::CMakeEnvironment);
+ labels->push_back(PathLabel::Hints);
+ labels->push_back(PathLabel::SystemEnvironment);
+ labels->push_back(PathLabel::CMakeSystem);
+ labels->push_back(PathLabel::Guess);
+
+ // Define the search group order
+ this->PathGroupOrder.push_back(PathGroup::All);
+
+ // Create the idividual labeld search paths
+ this->LabeledPaths.insert(std::make_pair(PathLabel::CMake,
+ cmSearchPath(this)));
+ this->LabeledPaths.insert(std::make_pair(PathLabel::CMakeEnvironment,
+ cmSearchPath(this)));
+ this->LabeledPaths.insert(std::make_pair(PathLabel::Hints,
+ cmSearchPath(this)));
+ this->LabeledPaths.insert(std::make_pair(PathLabel::SystemEnvironment,
+ cmSearchPath(this)));
+ this->LabeledPaths.insert(std::make_pair(PathLabel::CMakeSystem,
+ cmSearchPath(this)));
+ this->LabeledPaths.insert(std::make_pair(PathLabel::Guess,
+ cmSearchPath(this)));
}
//----------------------------------------------------------------------------
void cmFindCommon::SelectDefaultRootPathMode()
{
- // Use both by default.
- this->FindRootPathMode = RootPathModeBoth;
-
// Check the policy variable for this find command type.
std::string findRootPathVar = "CMAKE_FIND_ROOT_PATH_MODE_";
findRootPathVar += this->CMakePathName;
std::string rootPathMode =
- this->Makefile->GetSafeDefinition(findRootPathVar.c_str());
+ this->Makefile->GetSafeDefinition(findRootPathVar);
if (rootPathMode=="NEVER")
{
- this->FindRootPathMode = RootPathModeNoRootPath;
+ this->FindRootPathMode = RootPathModeNever;
}
else if (rootPathMode=="ONLY")
{
- this->FindRootPathMode = RootPathModeOnlyRootPath;
+ this->FindRootPathMode = RootPathModeOnly;
}
else if (rootPathMode=="BOTH")
{
@@ -181,28 +178,42 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths)
fprintf(stderr, "[%s]\n", i->c_str());
}
#endif
-
// Short-circuit if there is nothing to do.
- if(this->FindRootPathMode == RootPathModeNoRootPath)
+ if(this->FindRootPathMode == RootPathModeNever)
{
return;
}
+
+ const char* sysroot =
+ this->Makefile->GetDefinition("CMAKE_SYSROOT");
const char* rootPath =
this->Makefile->GetDefinition("CMAKE_FIND_ROOT_PATH");
- if((rootPath == 0) || (strlen(rootPath) == 0))
+ const bool noSysroot = !sysroot || !*sysroot;
+ const bool noRootPath = !rootPath || !*rootPath;
+ if(noSysroot && noRootPath)
{
return;
}
// Construct the list of path roots with no trailing slashes.
std::vector<std::string> roots;
- cmSystemTools::ExpandListArgument(rootPath, roots);
+ if (rootPath)
+ {
+ cmSystemTools::ExpandListArgument(rootPath, roots);
+ }
+ if (sysroot)
+ {
+ roots.push_back(sysroot);
+ }
for(std::vector<std::string>::iterator ri = roots.begin();
ri != roots.end(); ++ri)
{
cmSystemTools::ConvertToUnixSlashes(*ri);
}
+ const char* stagePrefix =
+ this->Makefile->GetDefinition("CMAKE_STAGING_PREFIX");
+
// Copy the original set of unrooted paths.
std::vector<std::string> unrootedPaths = paths;
paths.clear();
@@ -217,7 +228,9 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths)
// already inside. Skip the unrooted path if it is relative to
// a user home directory or is empty.
std::string rootedDir;
- if(cmSystemTools::IsSubDirectory(ui->c_str(), ri->c_str()))
+ if(cmSystemTools::IsSubDirectory(*ui, *ri)
+ || (stagePrefix
+ && cmSystemTools::IsSubDirectory(*ui, stagePrefix)))
{
rootedDir = *ui;
}
@@ -228,7 +241,7 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths)
rootedDir += "/";
// Append the original path with its old root removed.
- rootedDir += cmSystemTools::SplitPathRootComponent(ui->c_str());
+ rootedDir += cmSystemTools::SplitPathRootComponent(*ui);
}
// Store the new path.
@@ -245,24 +258,20 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths)
}
//----------------------------------------------------------------------------
-void cmFindCommon::FilterPaths(std::vector<std::string>& paths,
- const std::set<std::string>& ignore)
+void cmFindCommon::FilterPaths(const std::vector<std::string>& inPaths,
+ const std::set<std::string>& ignore,
+ std::vector<std::string>& outPaths)
{
- // Now filter out anything that's in the ignore set.
- std::vector<std::string> unfiltered;
- unfiltered.swap(paths);
-
- for(std::vector<std::string>::iterator pi = unfiltered.begin();
- pi != unfiltered.end(); ++pi)
+ for(std::vector<std::string>::const_iterator i = inPaths.begin();
+ i != inPaths.end(); ++i)
{
- if (ignore.count(*pi) == 0)
+ if(ignore.count(*i) == 0)
{
- paths.push_back(*pi);
+ outPaths.push_back(*i);
}
}
}
-
//----------------------------------------------------------------------------
void cmFindCommon::GetIgnoredPaths(std::vector<std::string>& ignore)
{
@@ -299,8 +308,6 @@ void cmFindCommon::GetIgnoredPaths(std::set<std::string>& ignore)
ignore.insert(ignoreVec.begin(), ignoreVec.end());
}
-
-
//----------------------------------------------------------------------------
bool cmFindCommon::CheckCommonArgument(std::string const& arg)
{
@@ -324,13 +331,13 @@ bool cmFindCommon::CheckCommonArgument(std::string const& arg)
{
this->NoCMakeSystemPath = true;
}
- else if(arg == "NO_CMAKE_FIND_ROOT_PATH")
+ else if(arg == "NO_CMAKE_FIND_ROOT_PATH")
{
- this->FindRootPathMode = RootPathModeNoRootPath;
+ this->FindRootPathMode = RootPathModeNever;
}
else if(arg == "ONLY_CMAKE_FIND_ROOT_PATH")
{
- this->FindRootPathMode = RootPathModeOnlyRootPath;
+ this->FindRootPathMode = RootPathModeOnly;
}
else if(arg == "CMAKE_FIND_ROOT_PATH_BOTH")
{
@@ -378,116 +385,34 @@ void cmFindCommon::AddPathSuffix(std::string const& arg)
}
//----------------------------------------------------------------------------
-void cmFindCommon::AddUserPath(std::string const& p,
- std::vector<std::string>& paths)
+void AddTrailingSlash(std::string& s)
{
- // We should view the registry as the target application would view
- // it.
- cmSystemTools::KeyWOW64 view = cmSystemTools::KeyWOW64_32;
- cmSystemTools::KeyWOW64 other_view = cmSystemTools::KeyWOW64_64;
- if(this->Makefile->PlatformIs64Bit())
- {
- view = cmSystemTools::KeyWOW64_64;
- other_view = cmSystemTools::KeyWOW64_32;
- }
-
- // Expand using the view of the target application.
- std::string expanded = p;
- cmSystemTools::ExpandRegistryValues(expanded, view);
- cmSystemTools::GlobDirs(expanded.c_str(), paths);
-
- // Executables can be either 32-bit or 64-bit, so expand using the
- // alternative view.
- if(expanded != p && this->CMakePathName == "PROGRAM")
+ if(!s.empty() && *s.rbegin() != '/')
{
- expanded = p;
- cmSystemTools::ExpandRegistryValues(expanded, other_view);
- cmSystemTools::GlobDirs(expanded.c_str(), paths);
+ s += '/';
}
}
-
-//----------------------------------------------------------------------------
-void cmFindCommon::AddCMakePath(const char* variable)
-{
- // Get a path from a CMake variable.
- if(const char* varPath = this->Makefile->GetDefinition(variable))
- {
- std::vector<std::string> tmp;
- cmSystemTools::ExpandListArgument(varPath, tmp);
-
- // Relative paths are interpreted with respect to the current
- // source directory.
- this->AddPathsInternal(tmp, CMakePath);
- }
-}
-
-//----------------------------------------------------------------------------
-void cmFindCommon::AddEnvPath(const char* variable)
-{
- // Get a path from the environment.
- std::vector<std::string> tmp;
- cmSystemTools::GetPath(tmp, variable);
- // Relative paths are interpreted with respect to the current
- // working directory.
- this->AddPathsInternal(tmp, EnvPath);
-}
-
-//----------------------------------------------------------------------------
-void cmFindCommon::AddPathsInternal(std::vector<std::string> const& in_paths,
- PathType pathType)
-{
- for(std::vector<std::string>::const_iterator i = in_paths.begin();
- i != in_paths.end(); ++i)
- {
- this->AddPathInternal(*i, pathType);
- }
-}
-
-//----------------------------------------------------------------------------
-void cmFindCommon::AddPathInternal(std::string const& in_path,
- PathType pathType)
+void cmFindCommon::ComputeFinalPaths()
{
- if(in_path.empty())
- {
- return;
- }
+ // Filter out ignored paths from the prefix list
+ std::set<std::string> ignored;
+ this->GetIgnoredPaths(ignored);
- // Select the base path with which to interpret relative paths.
- const char* relbase = 0;
- if(pathType == CMakePath)
+ // Combine the seperate path types, filtering out ignores
+ this->SearchPaths.clear();
+ std::vector<PathLabel>& allLabels = this->PathGroupLabelMap[PathGroup::All];
+ for(std::vector<PathLabel>::const_iterator l = allLabels.begin();
+ l != allLabels.end(); ++l)
{
- relbase = this->Makefile->GetCurrentDirectory();
+ this->LabeledPaths[*l].ExtractWithout(ignored, this->SearchPaths);
}
- // Convert to clean full path.
- std::string fullPath =
- cmSystemTools::CollapseFullPath(in_path.c_str(), relbase);
-
- // Insert the path if has not already been emitted.
- if(this->SearchPathsEmitted.insert(fullPath).second)
- {
- this->SearchPaths.push_back(fullPath.c_str());
- }
-}
-
-//----------------------------------------------------------------------------
-void cmFindCommon::ComputeFinalPaths()
-{
- std::vector<std::string>& paths = this->SearchPaths;
-
// Expand list of paths inside all search roots.
- this->RerootPaths(paths);
+ this->RerootPaths(this->SearchPaths);
// Add a trailing slash to all paths to aid the search process.
- for(std::vector<std::string>::iterator i = paths.begin();
- i != paths.end(); ++i)
- {
- std::string& p = *i;
- if(!p.empty() && p[p.size()-1] != '/')
- {
- p += "/";
- }
- }
+ std::for_each(this->SearchPaths.begin(), this->SearchPaths.end(),
+ &AddTrailingSlash);
}
//----------------------------------------------------------------------------
diff --git a/Source/cmFindCommon.h b/Source/cmFindCommon.h
index 542805faf..3fefc8da5 100644
--- a/Source/cmFindCommon.h
+++ b/Source/cmFindCommon.h
@@ -13,6 +13,8 @@
#define cmFindCommon_h
#include "cmCommand.h"
+#include "cmSearchPath.h"
+#include "cmPathLabel.h"
/** \class cmFindCommon
* \brief Base class for FIND_XXX implementations.
@@ -29,12 +31,39 @@ public:
cmTypeMacro(cmFindCommon, cmCommand);
protected:
-
- enum RootPathMode { RootPathModeBoth,
- RootPathModeOnlyRootPath,
- RootPathModeNoRootPath };
-
- enum PathType { FullPath, CMakePath, EnvPath };
+ friend class cmSearchPath;
+
+ /** Used to define groups of path labels */
+ class PathGroup : public cmPathLabel
+ {
+ protected:
+ PathGroup();
+ public:
+ PathGroup(const std::string& label) : cmPathLabel(label) { }
+ static PathGroup All;
+ };
+
+ /* Individual path types */
+ class PathLabel : public cmPathLabel
+ {
+ protected:
+ PathLabel();
+ public:
+ PathLabel(const std::string& label) : cmPathLabel(label) { }
+ static PathLabel CMake;
+ static PathLabel CMakeEnvironment;
+ static PathLabel Hints;
+ static PathLabel SystemEnvironment;
+ static PathLabel CMakeSystem;
+ static PathLabel Guess;
+ };
+
+ enum RootPathMode { RootPathModeNever,
+ RootPathModeOnly,
+ RootPathModeBoth };
+
+ /** Construct the various path groups and labels */
+ void InitializeSearchPathGroups();
/** Place a set of search paths under the search roots. */
void RerootPaths(std::vector<std::string>& paths);
@@ -44,8 +73,9 @@ protected:
void GetIgnoredPaths(std::set<std::string>& ignore);
/** Remove paths in the ignore set from the supplied vector. */
- void FilterPaths(std::vector<std::string>& paths,
- const std::set<std::string>& ignore);
+ void FilterPaths(const std::vector<std::string>& inPaths,
+ const std::set<std::string>& ignore,
+ std::vector<std::string>& outPaths);
/** Compute final search path list (reroot + trailing slash). */
void ComputeFinalPaths();
@@ -56,21 +86,15 @@ protected:
/** Compute the current default bundle/framework search policy. */
void SelectDefaultMacMode();
- virtual void GenerateDocumentation();
+ // Path arguments prior to path manipulation routines
+ std::vector<std::string> UserHintsArgs;
+ std::vector<std::string> UserGuessArgs;
- cmStdString CMakePathName;
+ std::string CMakePathName;
RootPathMode FindRootPathMode;
bool CheckCommonArgument(std::string const& arg);
void AddPathSuffix(std::string const& arg);
- void AddUserPath(std::string const& p,
- std::vector<std::string>& paths);
- void AddCMakePath(const char* variable);
- void AddEnvPath(const char* variable);
- void AddPathsInternal(std::vector<std::string> const& in_paths,
- PathType pathType);
- void AddPathInternal(std::string const& in_path, PathType pathType);
-
void SetMakefile(cmMakefile* makefile);
bool NoDefaultPath;
@@ -80,14 +104,14 @@ protected:
bool NoCMakeSystemPath;
std::vector<std::string> SearchPathSuffixes;
- std::vector<std::string> UserPaths;
- std::vector<std::string> UserHints;
- std::vector<std::string> SearchPaths;
- std::set<cmStdString> SearchPathsEmitted;
- std::string GenericDocumentationMacPolicy;
- std::string GenericDocumentationRootPath;
- std::string GenericDocumentationPathsOrder;
+ std::map<PathGroup, std::vector<PathLabel> > PathGroupLabelMap;
+ std::vector<PathGroup> PathGroupOrder;
+ std::map<std::string, PathLabel> PathLabelStringMap;
+ std::map<PathLabel, cmSearchPath> LabeledPaths;
+
+ std::vector<std::string> SearchPaths;
+ std::set<std::string> SearchPathsEmitted;
bool SearchFrameworkFirst;
bool SearchFrameworkOnly;
diff --git a/Source/cmFindFileCommand.cxx b/Source/cmFindFileCommand.cxx
index fa66fa11d..615e7c1d2 100644
--- a/Source/cmFindFileCommand.cxx
+++ b/Source/cmFindFileCommand.cxx
@@ -16,15 +16,3 @@ cmFindFileCommand::cmFindFileCommand()
{
this->IncludeFileInPath = true;
}
-
-void cmFindFileCommand::GenerateDocumentation()
-{
- this->cmFindPathCommand::GenerateDocumentation();
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "find_path", "find_file");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "directory containing the named file",
- "full path to named file");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "file in a directory", "full path to a file");
-}
diff --git a/Source/cmFindFileCommand.h b/Source/cmFindFileCommand.h
index 1bfdcbd16..daf1d6582 100644
--- a/Source/cmFindFileCommand.h
+++ b/Source/cmFindFileCommand.h
@@ -33,19 +33,9 @@ public:
{
return new cmFindFileCommand;
}
- virtual const char* GetName() const { return "find_file";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Find the full path to a file.";
- }
+ virtual std::string GetName() const { return "find_file";}
cmTypeMacro(cmFindFileCommand, cmFindPathCommand);
-protected:
- virtual void GenerateDocumentation();
};
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx
index 4af7e11bf..e7696af40 100644
--- a/Source/cmFindLibraryCommand.cxx
+++ b/Source/cmFindLibraryCommand.cxx
@@ -10,9 +10,7 @@
See the License for more information.
============================================================================*/
#include "cmFindLibraryCommand.h"
-#include "cmCacheManager.h"
#include <cmsys/Directory.hxx>
-#include <cmsys/stl/algorithm>
cmFindLibraryCommand::cmFindLibraryCommand()
{
@@ -20,62 +18,6 @@ cmFindLibraryCommand::cmFindLibraryCommand()
this->NamesPerDirAllowed = true;
}
-//----------------------------------------------------------------------------
-void cmFindLibraryCommand::GenerateDocumentation()
-{
- this->cmFindBase::GenerateDocumentation();
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "FIND_XXX", "find_library");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "CMAKE_XXX_PATH", "CMAKE_LIBRARY_PATH");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "CMAKE_XXX_MAC_PATH",
- "CMAKE_FRAMEWORK_PATH");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "CMAKE_SYSTEM_XXX_MAC_PATH",
- "CMAKE_SYSTEM_FRAMEWORK_PATH");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "XXX_SYSTEM", "LIB");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "CMAKE_SYSTEM_XXX_PATH",
- "CMAKE_SYSTEM_LIBRARY_PATH");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "SEARCH_XXX_DESC", "library");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "SEARCH_XXX", "library");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "XXX_SUBDIR", "lib");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "NAMES name1 [name2 ...]",
- "NAMES name1 [name2 ...] [NAMES_PER_DIR]");
- cmSystemTools::ReplaceString(
- this->GenericDocumentation,
- "XXX_EXTRA_PREFIX_ENTRY",
- " <prefix>/lib/<arch> if CMAKE_LIBRARY_ARCHITECTURE is set, and\n");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "CMAKE_FIND_ROOT_PATH_MODE_XXX",
- "CMAKE_FIND_ROOT_PATH_MODE_LIBRARY");
- this->GenericDocumentation +=
- "\n"
- "When more than one value is given to the NAMES option this command "
- "by default will consider one name at a time and search every directory "
- "for it. "
- "The NAMES_PER_DIR option tells this command to consider one directory "
- "at a time and search for all names in it."
- "\n"
- "If the library found is a framework, then VAR will be set to "
- "the full path to the framework <fullPath>/A.framework. "
- "When a full path to a framework is used as a library, "
- "CMake will use a -framework A, and a -F<fullPath> to "
- "link the framework to the target."
- "\n"
- "If the global property FIND_LIBRARY_USE_LIB64_PATHS is set all search "
- "paths will be tested as normal, with \"64/\" appended, and with all "
- "matches of \"lib/\" replaced with \"lib64/\". This property is "
- "automatically set for the platforms that are known to need it if at "
- "least one of the languages supported by the PROJECT command is enabled.";
-}
-
// cmFindLibraryCommand
bool cmFindLibraryCommand
::InitialPass(std::vector<std::string> const& argsIn, cmExecutionStatus &)
@@ -93,9 +35,9 @@ bool cmFindLibraryCommand
// value.
if(this->AlreadyInCacheWithoutMetaInfo)
{
- this->Makefile->AddCacheDefinition(this->VariableName.c_str(), "",
+ this->Makefile->AddCacheDefinition(this->VariableName, "",
this->VariableDocumentation.c_str(),
- cmCacheManager::FILEPATH);
+ cmState::FILEPATH);
}
return true;
}
@@ -111,8 +53,8 @@ bool cmFindLibraryCommand
}
}
- if(this->Makefile->GetCMakeInstance()
- ->GetPropertyAsBool("FIND_LIBRARY_USE_LIB64_PATHS"))
+ if(this->Makefile->GetState()
+ ->GetGlobalPropertyAsBool("FIND_LIBRARY_USE_LIB64_PATHS"))
{
// add special 64 bit paths if this is a 64 bit compile.
if(this->Makefile->PlatformIs64Bit())
@@ -125,17 +67,17 @@ bool cmFindLibraryCommand
if(library != "")
{
// Save the value in the cache
- this->Makefile->AddCacheDefinition(this->VariableName.c_str(),
+ this->Makefile->AddCacheDefinition(this->VariableName,
library.c_str(),
this->VariableDocumentation.c_str(),
- cmCacheManager::FILEPATH);
+ cmState::FILEPATH);
return true;
}
std::string notfound = this->VariableName + "-NOTFOUND";
- this->Makefile->AddCacheDefinition(this->VariableName.c_str(),
+ this->Makefile->AddCacheDefinition(this->VariableName,
notfound.c_str(),
this->VariableDocumentation.c_str(),
- cmCacheManager::FILEPATH);
+ cmState::FILEPATH);
return true;
}
@@ -144,7 +86,7 @@ void cmFindLibraryCommand::AddArchitecturePaths(const char* suffix)
{
std::vector<std::string> original;
original.swap(this->SearchPaths);
- for(std::vector<std::string>::iterator i = original.begin();
+ for(std::vector<std::string>::const_iterator i = original.begin();
i != original.end(); ++i)
{
this->AddArchitecturePath(*i, 0, suffix);
@@ -163,7 +105,7 @@ void cmFindLibraryCommand::AddArchitecturePath(
// Follow "lib<suffix>".
std::string next_dir = cur_dir + suffix;
- if(cmSystemTools::FileIsDirectory(next_dir.c_str()))
+ if(cmSystemTools::FileIsDirectory(next_dir))
{
next_dir += dir.substr(pos+3);
std::string::size_type next_pos = pos+3+strlen(suffix)+1;
@@ -171,7 +113,7 @@ void cmFindLibraryCommand::AddArchitecturePath(
}
// Follow "lib".
- if(cmSystemTools::FileIsDirectory(cur_dir.c_str()))
+ if(cmSystemTools::FileIsDirectory(cur_dir))
{
this->AddArchitecturePath(dir, pos+3+1, suffix, false);
}
@@ -180,13 +122,13 @@ void cmFindLibraryCommand::AddArchitecturePath(
{
// Check for <dir><suffix>/.
std::string cur_dir = dir + suffix + "/";
- if(cmSystemTools::FileIsDirectory(cur_dir.c_str()))
+ if(cmSystemTools::FileIsDirectory(cur_dir))
{
this->SearchPaths.push_back(cur_dir);
}
// Now add the original unchanged path
- if(cmSystemTools::FileIsDirectory(dir.c_str()))
+ if(cmSystemTools::FileIsDirectory(dir))
{
this->SearchPaths.push_back(dir);
}
@@ -251,16 +193,17 @@ struct cmFindLibraryHelper
void RegexFromList(std::string& out, std::vector<std::string> const& in);
size_type GetPrefixIndex(std::string const& prefix)
{
- return cmsys_stl::find(this->Prefixes.begin(), this->Prefixes.end(),
+ return std::find(this->Prefixes.begin(), this->Prefixes.end(),
prefix) - this->Prefixes.begin();
}
size_type GetSuffixIndex(std::string const& suffix)
{
- return cmsys_stl::find(this->Suffixes.begin(), this->Suffixes.end(),
+ return std::find(this->Suffixes.begin(), this->Suffixes.end(),
suffix) - this->Suffixes.begin();
}
bool HasValidSuffix(std::string const& name);
void AddName(std::string const& name);
+ void SetName(std::string const& name);
bool CheckDirectory(std::string const& path);
bool CheckDirectoryForName(std::string const& path, Name& name);
};
@@ -269,7 +212,7 @@ struct cmFindLibraryHelper
cmFindLibraryHelper::cmFindLibraryHelper(cmMakefile* mf):
Makefile(mf)
{
- this->GG = this->Makefile->GetLocalGenerator()->GetGlobalGenerator();
+ this->GG = this->Makefile->GetGlobalGenerator();
// Collect the list of library name prefixes/suffixes to try.
const char* prefixes_list =
@@ -283,8 +226,8 @@ cmFindLibraryHelper::cmFindLibraryHelper(cmMakefile* mf):
// Check whether to use OpenBSD-style library version comparisons.
this->OpenBSD =
- this->Makefile->GetCMakeInstance()
- ->GetPropertyAsBool("FIND_LIBRARY_USE_OPENBSD_VERSIONING");
+ this->Makefile->GetState()
+ ->GetGlobalPropertyAsBool("FIND_LIBRARY_USE_OPENBSD_VERSIONING");
}
//----------------------------------------------------------------------------
@@ -380,6 +323,13 @@ void cmFindLibraryHelper::AddName(std::string const& name)
}
//----------------------------------------------------------------------------
+void cmFindLibraryHelper::SetName(std::string const& name)
+{
+ this->Names.clear();
+ this->AddName(name);
+}
+
+//----------------------------------------------------------------------------
bool cmFindLibraryHelper::CheckDirectory(std::string const& path)
{
for(std::vector<Name>::iterator i = this->Names.begin();
@@ -409,7 +359,7 @@ bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path,
if(cmSystemTools::FileExists(this->TestPath.c_str(), true))
{
this->BestPath =
- cmSystemTools::CollapseFullPath(this->TestPath.c_str());
+ cmSystemTools::CollapseFullPath(this->TestPath);
cmSystemTools::ConvertToUnixSlashes(this->BestPath);
return true;
}
@@ -424,8 +374,8 @@ bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path,
// Search for a file matching the library name regex.
std::string dir = path;
cmSystemTools::ConvertToUnixSlashes(dir);
- std::set<cmStdString> const& files = this->GG->GetDirectoryContent(dir);
- for(std::set<cmStdString>::const_iterator fi = files.begin();
+ std::set<std::string> const& files = this->GG->GetDirectoryContent(dir);
+ for(std::set<std::string>::const_iterator fi = files.begin();
fi != files.end(); ++fi)
{
std::string const& origName = *fi;
@@ -438,7 +388,7 @@ bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path,
{
this->TestPath = path;
this->TestPath += origName;
- if(!cmSystemTools::FileIsDirectory(this->TestPath.c_str()))
+ if(!cmSystemTools::FileIsDirectory(this->TestPath))
{
// This is a matching file. Check if it is better than the
// best name found so far. Earlier prefixes are preferred,
@@ -517,8 +467,7 @@ std::string cmFindLibraryCommand::FindNormalLibraryDirsPerName()
ni != this->Names.end() ; ++ni)
{
// Switch to searching for this name.
- std::string const& name = *ni;
- helper.AddName(name);
+ helper.SetName(*ni);
// Search every directory.
for(std::vector<std::string>::const_iterator
@@ -562,9 +511,9 @@ std::string cmFindLibraryCommand::FindFrameworkLibraryNamesPerDir()
fwPath = *di;
fwPath += *ni;
fwPath += ".framework";
- if(cmSystemTools::FileIsDirectory(fwPath.c_str()))
+ if(cmSystemTools::FileIsDirectory(fwPath))
{
- return cmSystemTools::CollapseFullPath(fwPath.c_str());
+ return cmSystemTools::CollapseFullPath(fwPath);
}
}
}
@@ -588,9 +537,9 @@ std::string cmFindLibraryCommand::FindFrameworkLibraryDirsPerName()
fwPath = *di;
fwPath += *ni;
fwPath += ".framework";
- if(cmSystemTools::FileIsDirectory(fwPath.c_str()))
+ if(cmSystemTools::FileIsDirectory(fwPath))
{
- return cmSystemTools::CollapseFullPath(fwPath.c_str());
+ return cmSystemTools::CollapseFullPath(fwPath);
}
}
}
diff --git a/Source/cmFindLibraryCommand.h b/Source/cmFindLibraryCommand.h
index cd0fce8ad..e25717446 100644
--- a/Source/cmFindLibraryCommand.h
+++ b/Source/cmFindLibraryCommand.h
@@ -49,15 +49,8 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const {return "find_library";}
+ virtual std::string GetName() const {return "find_library";}
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Find a library.";
- }
cmTypeMacro(cmFindLibraryCommand, cmFindBase);
protected:
@@ -67,7 +60,6 @@ protected:
const char* suffix,
bool fresh = true);
std::string FindLibrary();
- virtual void GenerateDocumentation();
private:
std::string FindNormalLibrary();
std::string FindNormalLibraryNamesPerDir();
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index aa3a73d26..64176e7fb 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -13,40 +13,26 @@
#include <cmsys/Directory.hxx>
#include <cmsys/RegularExpression.hxx>
+#include <cmsys/Encoding.hxx>
+#include "cmAlgorithms.h"
#ifdef CMAKE_BUILD_WITH_CMAKE
#include "cmVariableWatch.h"
#endif
#if defined(__HAIKU__)
-#include <StorageKit.h>
+#include <string.h>
+#include <FindDirectory.h>
+#include <StorageDefs.h>
#endif
-void cmFindPackageNeedBackwardsCompatibility(const std::string& variable,
- int access_type, void*, const char* newValue,
- const cmMakefile*)
-{
- (void)newValue;
-#ifdef CMAKE_BUILD_WITH_CMAKE
- if(access_type == cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS)
- {
- std::string message = "An attempt was made to access a variable: ";
- message += variable;
- message +=
- " that has not been defined. This variable is created by the "
- "FIND_PACKAGE command. CMake version 1.6 always converted the "
- "variable name to upper-case, but this behavior is no longer the "
- "case. To fix this you might need to set the cache value of "
- "CMAKE_BACKWARDS_COMPATIBILITY to 1.6 or less. If you are writing a "
- "CMake listfile, you should change the variable reference to use "
- "the case of the argument to FIND_PACKAGE.";
- cmSystemTools::Error(message.c_str());
- }
-#else
- (void)variable;
- (void)access_type;
-#endif
-}
+//----------------------------------------------------------------------------
+cmFindPackageCommand::PathLabel
+ cmFindPackageCommand::PathLabel::UserRegistry("PACKAGE_REGISTRY");
+cmFindPackageCommand::PathLabel
+ cmFindPackageCommand::PathLabel::Builds("BUILDS");
+cmFindPackageCommand::PathLabel
+ cmFindPackageCommand::PathLabel::SystemRegistry("SYSTEM_PACKAGE_REGISTRY");
//----------------------------------------------------------------------------
cmFindPackageCommand::cmFindPackageCommand()
@@ -56,7 +42,6 @@ cmFindPackageCommand::cmFindPackageCommand()
this->Required = false;
this->NoUserRegistry = false;
this->NoSystemRegistry = false;
- this->NoBuilds = false;
this->UseConfigFiles = true;
this->UseFindModules = true;
this->DebugMode = false;
@@ -74,322 +59,33 @@ cmFindPackageCommand::cmFindPackageCommand()
this->VersionFoundTweak = 0;
this->VersionFoundCount = 0;
this->RequiredCMakeVersion = 0;
-}
-//----------------------------------------------------------------------------
-void cmFindPackageCommand::GenerateDocumentation()
-{
- this->cmFindCommon::GenerateDocumentation();
- cmSystemTools::ReplaceString(this->GenericDocumentationRootPath,
- "CMAKE_FIND_ROOT_PATH_MODE_XXX",
- "CMAKE_FIND_ROOT_PATH_MODE_PACKAGE");
- cmSystemTools::ReplaceString(this->GenericDocumentationPathsOrder,
- "FIND_ARGS_XXX", "<package>");
- cmSystemTools::ReplaceString(this->GenericDocumentationPathsOrder,
- "FIND_XXX", "find_package");
- this->CommandDocumentation =
- " find_package(<package> [version] [EXACT] [QUIET] [MODULE]\n"
- " [REQUIRED] [[COMPONENTS] [components...]]\n"
- " [OPTIONAL_COMPONENTS components...]\n"
- " [NO_POLICY_SCOPE])\n"
- "Finds and loads settings from an external project. "
- "<package>_FOUND will be set to indicate whether the package was found. "
- "When the package is found package-specific information is provided "
- "through variables and imported targets documented by the package "
- "itself. "
- "The QUIET option disables messages if the package cannot be found. "
- "The MODULE option disables the second signature documented below. "
- "The REQUIRED option stops processing with an error message if the "
- "package cannot be found."
- "\n"
- "A package-specific list of required components may be listed after the "
- "COMPONENTS option (or after the REQUIRED option if present). "
- "Additional optional components may be listed after OPTIONAL_COMPONENTS. "
- "Available components and their influence on whether a package is "
- "considered to be found are defined by the target package."
- "\n"
- "The [version] argument requests a version with which the package found "
- "should be compatible (format is major[.minor[.patch[.tweak]]]). "
- "The EXACT option requests that the version be matched exactly. "
- "If no [version] and/or component list is given to a recursive "
- "invocation inside a find-module, the corresponding arguments "
- "are forwarded automatically from the outer call (including the "
- "EXACT flag for [version]). "
- "Version support is currently provided only on a package-by-package "
- "basis (details below).\n"
- "User code should generally look for packages using the above simple "
- "signature. The remainder of this command documentation specifies the "
- "full command signature and details of the search process. Project "
- "maintainers wishing to provide a package to be found by this command "
- "are encouraged to read on.\n"
- "The command has two modes by which it searches for packages: "
- "\"Module\" mode and \"Config\" mode. "
- "Module mode is available when the command is invoked with the above "
- "reduced signature. "
- "CMake searches for a file called \"Find<package>.cmake\" in "
- "the CMAKE_MODULE_PATH followed by the CMake installation. "
- "If the file is found, it is read and processed by CMake. "
- "It is responsible for finding the package, checking the version, "
- "and producing any needed messages. "
- "Many find-modules provide limited or no support for versioning; "
- "check the module documentation. "
- "If no module is found and the MODULE option is not given the command "
- "proceeds to Config mode.\n"
- "The complete Config mode command signature is:\n"
- " find_package(<package> [version] [EXACT] [QUIET]\n"
- " [REQUIRED] [[COMPONENTS] [components...]]\n"
- " [CONFIG|NO_MODULE]\n"
- " [NO_POLICY_SCOPE]\n"
- " [NAMES name1 [name2 ...]]\n"
- " [CONFIGS config1 [config2 ...]]\n"
- " [HINTS path1 [path2 ... ]]\n"
- " [PATHS path1 [path2 ... ]]\n"
- " [PATH_SUFFIXES suffix1 [suffix2 ...]]\n"
- " [NO_DEFAULT_PATH]\n"
- " [NO_CMAKE_ENVIRONMENT_PATH]\n"
- " [NO_CMAKE_PATH]\n"
- " [NO_SYSTEM_ENVIRONMENT_PATH]\n"
- " [NO_CMAKE_PACKAGE_REGISTRY]\n"
- " [NO_CMAKE_BUILDS_PATH]\n"
- " [NO_CMAKE_SYSTEM_PATH]\n"
- " [NO_CMAKE_SYSTEM_PACKAGE_REGISTRY]\n"
- " [CMAKE_FIND_ROOT_PATH_BOTH |\n"
- " ONLY_CMAKE_FIND_ROOT_PATH |\n"
- " NO_CMAKE_FIND_ROOT_PATH])\n"
- "The CONFIG option may be used to skip Module mode explicitly and "
- "switch to Config mode. It is synonymous to using NO_MODULE. "
- "Config mode is also implied by use of options not specified in the "
- "reduced signature. "
- "\n"
- "Config mode attempts to locate a configuration file provided by the "
- "package to be found. A cache entry called <package>_DIR is created to "
- "hold the directory containing the file. "
- "By default the command searches for a package with the name <package>. "
- "If the NAMES option is given the names following it are used instead "
- "of <package>. "
- "The command searches for a file called \"<name>Config.cmake\" or "
- "\"<lower-case-name>-config.cmake\" for each name specified. "
- "A replacement set of possible configuration file names may be given "
- "using the CONFIGS option. "
- "The search procedure is specified below. Once found, the configuration "
- "file is read and processed by CMake. Since the file is provided by the "
- "package it already knows the location of package contents. "
- "The full path to the configuration file is stored in the cmake "
- "variable <package>_CONFIG."
- "\n"
- "All configuration files which have been considered by CMake while "
- "searching for an installation of the package with an appropriate "
- "version are stored in the cmake variable <package>_CONSIDERED_CONFIGS, "
- "the associated versions in <package>_CONSIDERED_VERSIONS. "
- "\n"
- "If the package configuration file cannot be found CMake "
- "will generate an error describing the problem unless the QUIET "
- "argument is specified. If REQUIRED is specified and the package "
- "is not found a fatal error is generated and the configure step stops "
- "executing. If <package>_DIR has been set to a directory not containing "
- "a configuration file CMake will ignore it and search from scratch."
- "\n"
- "When the [version] argument is given Config mode will only find a "
- "version of the package that claims compatibility with the requested "
- "version (format is major[.minor[.patch[.tweak]]]). "
- "If the EXACT option is given only a version of the package claiming "
- "an exact match of the requested version may be found. "
- "CMake does not establish any convention for the meaning of version "
- "numbers. "
- "Package version numbers are checked by \"version\" files provided by "
- "the packages themselves. "
- "For a candidate package configuration file \"<config-file>.cmake\" the "
- "corresponding version file is located next to it and named either "
- "\"<config-file>-version.cmake\" or \"<config-file>Version.cmake\". "
- "If no such version file is available then the configuration file "
- "is assumed to not be compatible with any requested version. "
- "A basic version file containing generic version matching code can be "
- "created using the macro write_basic_package_version_file(), see its "
- "documentation for more details. "
- "When a version file is found it is loaded to check the requested "
- "version number. "
- "The version file is loaded in a nested scope in which the following "
- "variables have been defined:\n"
- " PACKAGE_FIND_NAME = the <package> name\n"
- " PACKAGE_FIND_VERSION = full requested version string\n"
- " PACKAGE_FIND_VERSION_MAJOR = major version if requested, else 0\n"
- " PACKAGE_FIND_VERSION_MINOR = minor version if requested, else 0\n"
- " PACKAGE_FIND_VERSION_PATCH = patch version if requested, else 0\n"
- " PACKAGE_FIND_VERSION_TWEAK = tweak version if requested, else 0\n"
- " PACKAGE_FIND_VERSION_COUNT = number of version components, 0 to 4\n"
- "The version file checks whether it satisfies the requested version "
- "and sets these variables:\n"
- " PACKAGE_VERSION = full provided version string\n"
- " PACKAGE_VERSION_EXACT = true if version is exact match\n"
- " PACKAGE_VERSION_COMPATIBLE = true if version is compatible\n"
- " PACKAGE_VERSION_UNSUITABLE = true if unsuitable as any version\n"
- "These variables are checked by the find_package command to determine "
- "whether the configuration file provides an acceptable version. "
- "They are not available after the find_package call returns. "
- "If the version is acceptable the following variables are set:\n"
- " <package>_VERSION = full provided version string\n"
- " <package>_VERSION_MAJOR = major version if provided, else 0\n"
- " <package>_VERSION_MINOR = minor version if provided, else 0\n"
- " <package>_VERSION_PATCH = patch version if provided, else 0\n"
- " <package>_VERSION_TWEAK = tweak version if provided, else 0\n"
- " <package>_VERSION_COUNT = number of version components, 0 to 4\n"
- "and the corresponding package configuration file is loaded. "
- "When multiple package configuration files are available whose version "
- "files claim compatibility with the version requested it is unspecified "
- "which one is chosen. "
- "No attempt is made to choose a highest or closest version number."
- "\n"
- "Config mode provides an elaborate interface and search procedure. "
- "Much of the interface is provided for completeness and for use "
- "internally by find-modules loaded by Module mode. "
- "Most user code should simply call\n"
- " find_package(<package> [major[.minor]] [EXACT] [REQUIRED|QUIET])\n"
- "in order to find a package. Package maintainers providing CMake "
- "package configuration files are encouraged to name and install "
- "them such that the procedure outlined below will find them "
- "without requiring use of additional options."
- "\n"
- "CMake constructs a set of possible installation prefixes for the "
- "package. Under each prefix several directories are searched for a "
- "configuration file. The tables below show the directories searched. "
- "Each entry is meant for installation trees following Windows (W), "
- "UNIX (U), or Apple (A) conventions.\n"
- " <prefix>/ (W)\n"
- " <prefix>/(cmake|CMake)/ (W)\n"
- " <prefix>/<name>*/ (W)\n"
- " <prefix>/<name>*/(cmake|CMake)/ (W)\n"
- " <prefix>/(lib/<arch>|lib|share)/cmake/<name>*/ (U)\n"
- " <prefix>/(lib/<arch>|lib|share)/<name>*/ (U)\n"
- " <prefix>/(lib/<arch>|lib|share)/<name>*/(cmake|CMake)/ (U)\n"
- "On systems supporting OS X Frameworks and Application Bundles "
- "the following directories are searched for frameworks or bundles "
- "containing a configuration file:\n"
- " <prefix>/<name>.framework/Resources/ (A)\n"
- " <prefix>/<name>.framework/Resources/CMake/ (A)\n"
- " <prefix>/<name>.framework/Versions/*/Resources/ (A)\n"
- " <prefix>/<name>.framework/Versions/*/Resources/CMake/ (A)\n"
- " <prefix>/<name>.app/Contents/Resources/ (A)\n"
- " <prefix>/<name>.app/Contents/Resources/CMake/ (A)\n"
- "In all cases the <name> is treated as case-insensitive and corresponds "
- "to any of the names specified (<package> or names given by NAMES). "
- "Paths with lib/<arch> are enabled if CMAKE_LIBRARY_ARCHITECTURE is set. "
- "If PATH_SUFFIXES is specified the suffixes are appended to each "
- "(W) or (U) directory entry one-by-one.\n"
- "This set of directories is intended to work in cooperation with "
- "projects that provide configuration files in their installation trees. "
- "Directories above marked with (W) are intended for installations on "
- "Windows where the prefix may point at the top of an application's "
- "installation directory. Those marked with (U) are intended for "
- "installations on UNIX platforms where the prefix is shared by "
- "multiple packages. This is merely a convention, so all (W) and (U) "
- "directories are still searched on all platforms. "
- "Directories marked with (A) are intended for installations on "
- "Apple platforms. The cmake variables CMAKE_FIND_FRAMEWORK and "
- "CMAKE_FIND_APPBUNDLE determine the order of preference "
- "as specified below.\n"
- "The set of installation prefixes is constructed using the following "
- "steps. If NO_DEFAULT_PATH is specified all NO_* options are enabled.\n"
- "1. Search paths specified in cmake-specific cache variables. "
- "These are intended to be used on the command line with a -DVAR=value. "
- "This can be skipped if NO_CMAKE_PATH is passed.\n"
- " CMAKE_PREFIX_PATH\n"
- " CMAKE_FRAMEWORK_PATH\n"
- " CMAKE_APPBUNDLE_PATH\n"
- "2. Search paths specified in cmake-specific environment variables. "
- "These are intended to be set in the user's shell configuration. "
- "This can be skipped if NO_CMAKE_ENVIRONMENT_PATH is passed.\n"
- " <package>_DIR\n"
- " CMAKE_PREFIX_PATH\n"
- " CMAKE_FRAMEWORK_PATH\n"
- " CMAKE_APPBUNDLE_PATH\n"
- "3. Search paths specified by the HINTS option. "
- "These should be paths computed by system introspection, such as a "
- "hint provided by the location of another item already found. "
- "Hard-coded guesses should be specified with the PATHS option.\n"
- "4. Search the standard system environment variables. "
- "This can be skipped if NO_SYSTEM_ENVIRONMENT_PATH is passed. "
- "Path entries ending in \"/bin\" or \"/sbin\" are automatically "
- "converted to their parent directories.\n"
- " PATH\n"
- "5. Search project build trees recently configured in a CMake GUI. "
- "This can be skipped if NO_CMAKE_BUILDS_PATH is passed. "
- "It is intended for the case when a user is building multiple "
- "dependent projects one after another.\n"
- "6. Search paths stored in the CMake user package registry. "
- "This can be skipped if NO_CMAKE_PACKAGE_REGISTRY is passed. "
- "On Windows a <package> may appear under registry key\n"
- " HKEY_CURRENT_USER\\Software\\Kitware\\CMake\\Packages\\<package>\n"
- "as a REG_SZ value, with arbitrary name, that specifies the directory "
- "containing the package configuration file. "
- "On UNIX platforms a <package> may appear under the directory\n"
- " ~/.cmake/packages/<package>\n"
- "as a file, with arbitrary name, whose content specifies the directory "
- "containing the package configuration file. "
- "See the export(PACKAGE) command to create user package registry entries "
- "for project build trees."
- "\n"
- "7. Search cmake variables defined in the Platform files "
- "for the current system. This can be skipped if NO_CMAKE_SYSTEM_PATH "
- "is passed.\n"
- " CMAKE_SYSTEM_PREFIX_PATH\n"
- " CMAKE_SYSTEM_FRAMEWORK_PATH\n"
- " CMAKE_SYSTEM_APPBUNDLE_PATH\n"
- "8. Search paths stored in the CMake system package registry. "
- "This can be skipped if NO_CMAKE_SYSTEM_PACKAGE_REGISTRY is passed. "
- "On Windows a <package> may appear under registry key\n"
- " HKEY_LOCAL_MACHINE\\Software\\Kitware\\CMake\\Packages\\<package>\n"
- "as a REG_SZ value, with arbitrary name, that specifies the directory "
- "containing the package configuration file. "
- "There is no system package registry on non-Windows platforms."
- "\n"
- "9. Search paths specified by the PATHS option. "
- "These are typically hard-coded guesses.\n"
- ;
- this->CommandDocumentation += this->GenericDocumentationMacPolicy;
- this->CommandDocumentation += this->GenericDocumentationRootPath;
- this->CommandDocumentation += this->GenericDocumentationPathsOrder;
- this->CommandDocumentation +=
- "\n"
- "Every non-REQUIRED find_package() call can be disabled by setting the "
- "variable CMAKE_DISABLE_FIND_PACKAGE_<package> to TRUE. See the "
- "documentation for the CMAKE_DISABLE_FIND_PACKAGE_<package> variable for "
- "more information.\n"
- "When loading a find module or package configuration file find_package "
- "defines variables to provide information about the call arguments "
- "(and restores their original state before returning):\n"
- " <package>_FIND_REQUIRED = true if REQUIRED option was given\n"
- " <package>_FIND_QUIETLY = true if QUIET option was given\n"
- " <package>_FIND_VERSION = full requested version string\n"
- " <package>_FIND_VERSION_MAJOR = major version if requested, else 0\n"
- " <package>_FIND_VERSION_MINOR = minor version if requested, else 0\n"
- " <package>_FIND_VERSION_PATCH = patch version if requested, else 0\n"
- " <package>_FIND_VERSION_TWEAK = tweak version if requested, else 0\n"
- " <package>_FIND_VERSION_COUNT = number of version components, 0 to 4\n"
- " <package>_FIND_VERSION_EXACT = true if EXACT option was given\n"
- " <package>_FIND_COMPONENTS = list of requested components\n"
- " <package>_FIND_REQUIRED_<c> = true if component <c> is required\n"
- " false if component <c> is optional\n"
- "In Module mode the loaded find module is responsible to honor the "
- "request detailed by these variables; see the find module for details. "
- "In Config mode find_package handles REQUIRED, QUIET, and version "
- "options automatically but leaves it to the package configuration file "
- "to handle components in a way that makes sense for the package. "
- "The package configuration file may set <package>_FOUND to false "
- "to tell find_package that component requirements are not satisfied."
- "\n"
- "See the cmake_policy() command documentation for discussion of the "
- "NO_POLICY_SCOPE option."
- ;
+ this->AppendSearchPathGroups();
}
//----------------------------------------------------------------------------
-const char* cmFindPackageCommand::GetFullDocumentation() const
+void cmFindPackageCommand::AppendSearchPathGroups()
{
- if(this->CommandDocumentation.empty())
- {
- const_cast<cmFindPackageCommand *>(this)->GenerateDocumentation();
- }
- return this->CommandDocumentation.c_str();
+ std::vector<cmFindCommon::PathLabel>* labels;
+
+ // Update the All group with new paths
+ labels = &this->PathGroupLabelMap[PathGroup::All];
+ labels->insert(std::find(labels->begin(), labels->end(),
+ PathLabel::CMakeSystem),
+ PathLabel::UserRegistry);
+ labels->insert(std::find(labels->begin(), labels->end(),
+ PathLabel::CMakeSystem),
+ PathLabel::Builds);
+ labels->insert(std::find(labels->begin(), labels->end(), PathLabel::Guess),
+ PathLabel::SystemRegistry);
+
+ // Create the new path objects
+ this->LabeledPaths.insert(std::make_pair(PathLabel::UserRegistry,
+ cmSearchPath(this)));
+ this->LabeledPaths.insert(std::make_pair(PathLabel::Builds,
+ cmSearchPath(this)));
+ this->LabeledPaths.insert(std::make_pair(PathLabel::SystemRegistry,
+ cmSearchPath(this)));
}
//----------------------------------------------------------------------------
@@ -423,12 +119,24 @@ bool cmFindPackageCommand
// Lookup whether lib64 paths should be used.
if(this->Makefile->PlatformIs64Bit() &&
- this->Makefile->GetCMakeInstance()
- ->GetPropertyAsBool("FIND_LIBRARY_USE_LIB64_PATHS"))
+ this->Makefile->GetState()
+ ->GetGlobalPropertyAsBool("FIND_LIBRARY_USE_LIB64_PATHS"))
{
this->UseLib64Paths = true;
}
+ // Check if User Package Registry should be disabled
+ if(this->Makefile->IsOn("CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY"))
+ {
+ this->NoUserRegistry = true;
+ }
+
+ // Check if System Package Registry should be disabled
+ if(this->Makefile->IsOn("CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY"))
+ {
+ this->NoSystemRegistry = true;
+ }
+
// Find the current root path mode.
this->SelectDefaultRootPathMode();
@@ -442,11 +150,6 @@ bool cmFindPackageCommand
std::set<std::string> requiredComponents;
std::set<std::string> optionalComponents;
- // Check ancient compatibility.
- this->Compatibility_1_6 =
- this->Makefile->GetLocalGenerator()
- ->NeedBackwardsCompatibility(1, 6);
-
// Always search directly in a generated path.
this->SearchPathSuffixes.push_back("");
@@ -468,7 +171,6 @@ bool cmFindPackageCommand
else if(args[i] == "EXACT")
{
this->VersionExact = true;
- this->Compatibility_1_6 = false;
doing = DoingNone;
}
else if(args[i] == "MODULE")
@@ -493,75 +195,63 @@ bool cmFindPackageCommand
}
else if(args[i] == "COMPONENTS")
{
- this->Compatibility_1_6 = false;
doing = DoingComponents;
}
else if(args[i] == "OPTIONAL_COMPONENTS")
{
- this->Compatibility_1_6 = false;
doing = DoingOptionalComponents;
}
else if(args[i] == "NAMES")
{
configArgs.insert(i);
- this->Compatibility_1_6 = false;
doing = DoingNames;
}
else if(args[i] == "PATHS")
{
configArgs.insert(i);
- this->Compatibility_1_6 = false;
doing = DoingPaths;
}
else if(args[i] == "HINTS")
{
configArgs.insert(i);
- this->Compatibility_1_6 = false;
doing = DoingHints;
}
else if(args[i] == "PATH_SUFFIXES")
{
configArgs.insert(i);
- this->Compatibility_1_6 = false;
doing = DoingPathSuffixes;
}
else if(args[i] == "CONFIGS")
{
configArgs.insert(i);
- this->Compatibility_1_6 = false;
doing = DoingConfigs;
}
else if(args[i] == "NO_POLICY_SCOPE")
{
this->PolicyScope = false;
- this->Compatibility_1_6 = false;
doing = DoingNone;
}
else if(args[i] == "NO_CMAKE_PACKAGE_REGISTRY")
{
this->NoUserRegistry = true;
configArgs.insert(i);
- this->Compatibility_1_6 = false;
doing = DoingNone;
}
else if(args[i] == "NO_CMAKE_SYSTEM_PACKAGE_REGISTRY")
{
this->NoSystemRegistry = true;
configArgs.insert(i);
- this->Compatibility_1_6 = false;
doing = DoingNone;
}
else if(args[i] == "NO_CMAKE_BUILDS_PATH")
{
- this->NoBuilds = true;
+ // Ignore legacy option.
configArgs.insert(i);
- this->Compatibility_1_6 = false;
doing = DoingNone;
}
else if(this->CheckCommonArgument(args[i]))
{
configArgs.insert(i);
- this->Compatibility_1_6 = false;
doing = DoingNone;
}
else if((doing == DoingComponents) || (doing == DoingOptionalComponents))
@@ -580,7 +270,7 @@ bool cmFindPackageCommand
}
std::string req_var = this->Name + "_FIND_REQUIRED_" + args[i];
- this->AddFindDefinition(req_var.c_str(), isRequired);
+ this->AddFindDefinition(req_var, isRequired);
// Append to the list of required components.
components += components_sep;
@@ -593,11 +283,11 @@ bool cmFindPackageCommand
}
else if(doing == DoingPaths)
{
- this->AddUserPath(args[i], this->UserPaths);
+ this->UserGuessArgs.push_back(args[i]);
}
else if(doing == DoingHints)
{
- this->AddUserPath(args[i], this->UserHints);
+ this->UserHintsArgs.push_back(args[i]);
}
else if(doing == DoingPathSuffixes)
{
@@ -608,11 +298,11 @@ bool cmFindPackageCommand
if(args[i].find_first_of(":/\\") != args[i].npos ||
cmSystemTools::GetFilenameLastExtension(args[i]) != ".cmake")
{
- cmOStringStream e;
+ std::ostringstream e;
e << "given CONFIGS option followed by invalid file name \""
<< args[i] << "\". The names given must be file names without "
<< "a path and with a \".cmake\" extension.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
this->Configs.push_back(args[i]);
@@ -624,9 +314,9 @@ bool cmFindPackageCommand
}
else
{
- cmOStringStream e;
- e << "called with invalid argument \"" << args[i].c_str() << "\"";
- this->SetError(e.str().c_str());
+ std::ostringstream e;
+ e << "called with invalid argument \"" << args[i] << "\"";
+ this->SetError(e.str());
return false;
}
}
@@ -637,13 +327,10 @@ bool cmFindPackageCommand
std::back_inserter(doubledComponents));
if(!doubledComponents.empty())
{
- cmOStringStream e;
+ std::ostringstream e;
e << "called with components that are both required and optional:\n";
- for(unsigned int i=0; i<doubledComponents.size(); ++i)
- {
- e << " " << doubledComponents[i] << "\n";
- }
- this->SetError(e.str().c_str());
+ e << cmWrap(" ", doubledComponents, "", "\n") << "\n";
+ this->SetError(e.str());
return false;
}
@@ -652,7 +339,7 @@ bool cmFindPackageCommand
this->UseConfigFiles = moduleArgs.empty();
if(!this->UseFindModules && !this->UseConfigFiles)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "given options exclusive to Module mode:\n";
for(std::set<unsigned int>::const_iterator si = moduleArgs.begin();
si != moduleArgs.end(); ++si)
@@ -666,7 +353,7 @@ bool cmFindPackageCommand
e << " " << args[*si] << "\n";
}
e << "The options are incompatible.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
@@ -684,7 +371,7 @@ bool cmFindPackageCommand
// another find_package(<name>) call.
std::string mod = this->Name;
mod += "_FIND_MODULE";
- if(this->Makefile->IsOn(mod.c_str()))
+ if(this->Makefile->IsOn(mod))
{
if(this->Version.empty())
{
@@ -692,17 +379,17 @@ bool cmFindPackageCommand
// Requested version string.
std::string ver = this->Name;
ver += "_FIND_VERSION";
- this->Version = this->Makefile->GetSafeDefinition(ver.c_str());
+ this->Version = this->Makefile->GetSafeDefinition(ver);
// Whether an exact version is required.
std::string exact = this->Name;
exact += "_FIND_VERSION_EXACT";
- this->VersionExact = this->Makefile->IsOn(exact.c_str());
+ this->VersionExact = this->Makefile->IsOn(exact);
}
if(components.empty())
{
std::string components_var = this->Name + "_FIND_COMPONENTS";
- components = this->Makefile->GetSafeDefinition(components_var.c_str());
+ components = this->Makefile->GetSafeDefinition(components_var);
}
}
}
@@ -730,15 +417,15 @@ bool cmFindPackageCommand
std::string disableFindPackageVar = "CMAKE_DISABLE_FIND_PACKAGE_";
disableFindPackageVar += this->Name;
- if(this->Makefile->IsOn(disableFindPackageVar.c_str()))
+ if(this->Makefile->IsOn(disableFindPackageVar))
{
if (this->Required)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "for module " << this->Name << " called with REQUIRED, but "
<< disableFindPackageVar
<< " is enabled. A REQUIRED package cannot be disabled.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
@@ -767,7 +454,7 @@ bool cmFindPackageCommand
if(this->UseFindModules && this->UseConfigFiles &&
this->Makefile->IsOn("CMAKE_FIND_PACKAGE_WARN_NO_MODULE"))
{
- cmOStringStream aw;
+ std::ostringstream aw;
if(this->RequiredCMakeVersion >= CMake_VERSION_ENCODE(2,8,8))
{
aw << "find_package called without either MODULE or CONFIG option and "
@@ -845,7 +532,7 @@ void cmFindPackageCommand::SetModuleVariables(const std::string& components)
// Store the list of components.
std::string components_var = this->Name + "_FIND_COMPONENTS";
- this->AddFindDefinition(components_var.c_str(), components.c_str());
+ this->AddFindDefinition(components_var, components.c_str());
if(this->Quiet)
{
@@ -853,7 +540,7 @@ void cmFindPackageCommand::SetModuleVariables(const std::string& components)
// quietly.
std::string quietly = this->Name;
quietly += "_FIND_QUIETLY";
- this->AddFindDefinition(quietly.c_str(), "1");
+ this->AddFindDefinition(quietly, "1");
}
if(this->Required)
@@ -862,7 +549,7 @@ void cmFindPackageCommand::SetModuleVariables(const std::string& components)
// a fatal error if the package is not found.
std::string req = this->Name;
req += "_FIND_REQUIRED";
- this->AddFindDefinition(req.c_str(), "1");
+ this->AddFindDefinition(req, "1");
}
if(!this->Version.empty())
@@ -871,28 +558,29 @@ void cmFindPackageCommand::SetModuleVariables(const std::string& components)
// package has been requested.
std::string ver = this->Name;
ver += "_FIND_VERSION";
- this->AddFindDefinition(ver.c_str(), this->Version.c_str());
+ this->AddFindDefinition(ver, this->Version.c_str());
char buf[64];
sprintf(buf, "%u", this->VersionMajor);
- this->AddFindDefinition((ver+"_MAJOR").c_str(), buf);
+ this->AddFindDefinition(ver+"_MAJOR", buf);
sprintf(buf, "%u", this->VersionMinor);
- this->AddFindDefinition((ver+"_MINOR").c_str(), buf);
+ this->AddFindDefinition(ver+"_MINOR", buf);
sprintf(buf, "%u", this->VersionPatch);
- this->AddFindDefinition((ver+"_PATCH").c_str(), buf);
+ this->AddFindDefinition(ver+"_PATCH", buf);
sprintf(buf, "%u", this->VersionTweak);
- this->AddFindDefinition((ver+"_TWEAK").c_str(), buf);
+ this->AddFindDefinition(ver+"_TWEAK", buf);
sprintf(buf, "%u", this->VersionCount);
- this->AddFindDefinition((ver+"_COUNT").c_str(), buf);
+ this->AddFindDefinition(ver+"_COUNT", buf);
// Tell the module whether an exact version has been requested.
std::string exact = this->Name;
exact += "_FIND_VERSION_EXACT";
- this->AddFindDefinition(exact.c_str(), this->VersionExact? "1":"0");
+ this->AddFindDefinition(exact, this->VersionExact? "1":"0");
}
}
//----------------------------------------------------------------------------
-void cmFindPackageCommand::AddFindDefinition(const char* var, const char* val)
+void cmFindPackageCommand::AddFindDefinition(const std::string& var,
+ const char* val)
{
if(const char* old = this->Makefile->GetDefinition(var))
{
@@ -909,17 +597,17 @@ void cmFindPackageCommand::AddFindDefinition(const char* var, const char* val)
//----------------------------------------------------------------------------
void cmFindPackageCommand::RestoreFindDefinitions()
{
- for(std::map<cmStdString, OriginalDef>::iterator
+ for(std::map<std::string, OriginalDef>::iterator
i = this->OriginalDefs.begin(); i != this->OriginalDefs.end(); ++i)
{
OriginalDef const& od = i->second;
if(od.exists)
{
- this->Makefile->AddDefinition(i->first.c_str(), od.value.c_str());
+ this->Makefile->AddDefinition(i->first, od.value.c_str());
}
else
{
- this->Makefile->RemoveDefinition(i->first.c_str());
+ this->Makefile->RemoveDefinition(i->first);
}
}
}
@@ -931,16 +619,16 @@ bool cmFindPackageCommand::FindModule(bool& found)
module += this->Name;
module += ".cmake";
std::string mfile = this->Makefile->GetModulesFile(module.c_str());
- if ( mfile.size() )
+ if (!mfile.empty())
{
// Load the module we found, and set "<name>_FIND_MODULE" to true
// while inside it.
found = true;
std::string var = this->Name;
var += "_FIND_MODULE";
- this->Makefile->AddDefinition(var.c_str(), "1");
+ this->Makefile->AddDefinition(var, "1");
bool result = this->ReadListFile(mfile.c_str(), DoPolicyScope);
- this->Makefile->RemoveDefinition(var.c_str());
+ this->Makefile->RemoveDefinition(var);
return result;
}
return true;
@@ -956,24 +644,9 @@ bool cmFindPackageCommand::HandlePackageMode()
std::string upperFound = cmSystemTools::UpperCase(this->Name);
upperDir += "_DIR";
upperFound += "_FOUND";
- if(upperDir == this->Variable)
- {
- this->Compatibility_1_6 = false;
- }
// Try to find the config file.
- const char* def = this->Makefile->GetDefinition(this->Variable.c_str());
- if(this->Compatibility_1_6 && cmSystemTools::IsOff(def))
- {
- // Use the setting of the old name of the variable to provide the
- // value of the new.
- const char* oldDef = this->Makefile->GetDefinition(upperDir.c_str());
- if(!cmSystemTools::IsOff(oldDef))
- {
- this->Makefile->AddDefinition(this->Variable.c_str(), oldDef);
- def = this->Makefile->GetDefinition(this->Variable.c_str());
- }
- }
+ const char* def = this->Makefile->GetDefinition(this->Variable);
// Try to load the config file if the directory is known
bool fileFound = false;
@@ -989,7 +662,7 @@ bool cmFindPackageCommand::HandlePackageMode()
if(!cmSystemTools::FileIsFullPath(dir.c_str()))
{
dir = "/" + dir;
- dir = this->Makefile->GetCurrentDirectory() + dir;
+ dir = this->Makefile->GetCurrentSourceDirectory() + dir;
}
// The file location was cached. Look for the correct file.
std::string file;
@@ -998,14 +671,13 @@ bool cmFindPackageCommand::HandlePackageMode()
this->FileFound = file;
fileFound = true;
}
- def = this->Makefile->GetDefinition(this->Variable.c_str());
+ def = this->Makefile->GetDefinition(this->Variable);
}
// Search for the config file if it is not already found.
if(cmSystemTools::IsOff(def) || !fileFound)
{
fileFound = this->FindConfig();
- def = this->Makefile->GetDefinition(this->Variable.c_str());
}
// Sanity check.
@@ -1030,16 +702,16 @@ bool cmFindPackageCommand::HandlePackageMode()
if(fileFound)
{
- if ((this->Makefile->IsDefinitionSet(foundVar.c_str()))
- && (this->Makefile->IsOn(foundVar.c_str()) == false))
+ if ((this->Makefile->IsDefinitionSet(foundVar))
+ && (this->Makefile->IsOn(foundVar) == false))
{
// by removing Foo_FOUND here if it is FALSE, we don't really change
// the situation for the Config file which is about to be included,
// but we make it possible to detect later on whether the Config file
// has set Foo_FOUND to FALSE itself:
- this->Makefile->RemoveDefinition(foundVar.c_str());
+ this->Makefile->RemoveDefinition(foundVar);
}
- this->Makefile->RemoveDefinition(notFoundMessageVar.c_str());
+ this->Makefile->RemoveDefinition(notFoundMessageVar);
// Set the version variables before loading the config file.
// It may override them.
@@ -1052,14 +724,14 @@ bool cmFindPackageCommand::HandlePackageMode()
found = true;
// Check whether the Config file has set Foo_FOUND to FALSE:
- if ((this->Makefile->IsDefinitionSet(foundVar.c_str()))
- && (this->Makefile->IsOn(foundVar.c_str()) == false))
+ if ((this->Makefile->IsDefinitionSet(foundVar))
+ && (this->Makefile->IsOn(foundVar) == false))
{
// we get here if the Config file has set Foo_FOUND actively to FALSE
found = false;
configFileSetFOUNDFalse = true;
notFoundMessage = this->Makefile->GetSafeDefinition(
- notFoundMessageVar.c_str());
+ notFoundMessageVar);
}
}
else
@@ -1072,8 +744,8 @@ bool cmFindPackageCommand::HandlePackageMode()
if (result && !found && (!this->Quiet || this->Required))
{
// The variable is not set.
- cmOStringStream e;
- cmOStringStream aw;
+ std::ostringstream e;
+ std::ostringstream aw;
if (configFileSetFOUNDFalse)
{
e << "Found package configuration file:\n"
@@ -1087,7 +759,7 @@ bool cmFindPackageCommand::HandlePackageMode()
}
// If there are files in ConsideredConfigs, it means that FooConfig.cmake
// have been found, but they didn't have appropriate versions.
- else if (this->ConsideredConfigs.size() > 0)
+ else if (!this->ConsideredConfigs.empty())
{
e << "Could not find a configuration file for package \""
<< this->Name << "\" that "
@@ -1132,13 +804,8 @@ bool cmFindPackageCommand::HandlePackageMode()
{
e << "Could not find a package configuration file provided by \""
<< this->Name << "\"" << requestedVersionString
- << " with any of the following names:\n";
- for(std::vector<std::string>::const_iterator ci =
- this->Configs.begin();
- ci != this->Configs.end(); ++ci)
- {
- e << " " << *ci << "\n";
- }
+ << " with any of the following names:\n"
+ << cmWrap(" ", this->Configs, "", "\n") << "\n";
}
e << "Add the installation prefix of \"" << this->Name << "\" to "
@@ -1181,57 +848,20 @@ bool cmFindPackageCommand::HandlePackageMode()
}
// Set a variable marking whether the package was found.
- this->Makefile->AddDefinition(foundVar.c_str(), found? "1":"0");
+ this->Makefile->AddDefinition(foundVar, found? "1":"0");
// Set a variable naming the configuration file that was found.
std::string fileVar = this->Name;
fileVar += "_CONFIG";
if(found)
{
- this->Makefile->AddDefinition(fileVar.c_str(), this->FileFound.c_str());
+ this->Makefile->AddDefinition(fileVar, this->FileFound.c_str());
}
else
{
- this->Makefile->RemoveDefinition(fileVar.c_str());
+ this->Makefile->RemoveDefinition(fileVar);
}
- // Handle some ancient compatibility stuff.
- if(this->Compatibility_1_6)
- {
- // Listfiles will be looking for the capitalized version of the
- // name. Provide it.
- this->Makefile->AddDefinition
- (upperDir.c_str(),
- this->Makefile->GetDefinition(this->Variable.c_str()));
- this->Makefile->AddDefinition
- (upperFound.c_str(),
- this->Makefile->GetDefinition(foundVar.c_str()));
- }
-
-#ifdef CMAKE_BUILD_WITH_CMAKE
- if(!(upperDir == this->Variable))
- {
- if(this->Compatibility_1_6)
- {
- // Listfiles may use the capitalized version of the name.
- // Remove any previously added watch.
- this->Makefile->GetVariableWatch()->RemoveWatch(
- upperDir.c_str(),
- cmFindPackageNeedBackwardsCompatibility
- );
- }
- else
- {
- // Listfiles should not be using the capitalized version of the
- // name. Add a watch to warn the user.
- this->Makefile->GetVariableWatch()->AddWatch(
- upperDir.c_str(),
- cmFindPackageNeedBackwardsCompatibility
- );
- }
- }
-#endif
-
std::string consideredConfigsVar = this->Name;
consideredConfigsVar += "_CONSIDERED_CONFIGS";
std::string consideredVersionsVar = this->Name;
@@ -1251,10 +881,10 @@ bool cmFindPackageCommand::HandlePackageMode()
sep = ";";
}
- this->Makefile->AddDefinition(consideredConfigsVar.c_str(),
+ this->Makefile->AddDefinition(consideredConfigsVar,
consideredConfigFiles.c_str());
- this->Makefile->AddDefinition(consideredVersionsVar.c_str(),
+ this->Makefile->AddDefinition(consideredVersionsVar,
consideredVersions.c_str());
return result;
@@ -1314,9 +944,9 @@ bool cmFindPackageCommand::FindConfig()
help += this->Name;
help += ".";
// We force the value since we do not get here if it was already set.
- this->Makefile->AddCacheDefinition(this->Variable.c_str(),
+ this->Makefile->AddCacheDefinition(this->Variable,
init.c_str(), help.c_str(),
- cmCacheManager::PATH, true);
+ cmState::PATH, true);
return found;
}
@@ -1368,15 +998,15 @@ bool cmFindPackageCommand::FindAppBundleConfig()
//----------------------------------------------------------------------------
bool cmFindPackageCommand::ReadListFile(const char* f, PolicyScopeRule psr)
{
- if(this->Makefile->ReadListFile(this->Makefile->GetCurrentListFile(), f, 0,
- !this->PolicyScope || psr == NoPolicyScope))
+ const bool noPolicyScope = !this->PolicyScope || psr == NoPolicyScope;
+ if(this->Makefile->ReadDependentFile(f, noPolicyScope))
{
return true;
}
std::string e = "Error reading CMake code from \"";
e += f;
e += "\".";
- this->SetError(e.c_str());
+ this->SetError(e);
return false;
}
@@ -1384,8 +1014,8 @@ bool cmFindPackageCommand::ReadListFile(const char* f, PolicyScopeRule psr)
void cmFindPackageCommand::AppendToFoundProperty(bool found)
{
std::vector<std::string> foundContents;
- const char *foundProp =
- this->Makefile->GetCMakeInstance()->GetProperty("PACKAGES_FOUND");
+ const char *foundProp = this->Makefile->GetState()
+ ->GetGlobalProperty("PACKAGES_FOUND");
if (foundProp && *foundProp)
{
std::string tmp = foundProp;
@@ -1401,7 +1031,8 @@ void cmFindPackageCommand::AppendToFoundProperty(bool found)
std::vector<std::string> notFoundContents;
const char *notFoundProp =
- this->Makefile->GetCMakeInstance()->GetProperty("PACKAGES_NOT_FOUND");
+ this->Makefile->GetState()
+ ->GetGlobalProperty("PACKAGES_NOT_FOUND");
if (notFoundProp && *notFoundProp)
{
std::string tmp = notFoundProp;
@@ -1425,39 +1056,30 @@ void cmFindPackageCommand::AppendToFoundProperty(bool found)
}
- std::string tmp;
- const char* sep ="";
- for(size_t i=0; i<foundContents.size(); i++)
- {
- tmp += sep;
- tmp += foundContents[i];
- sep = ";";
- }
+ std::string tmp = cmJoin(foundContents, ";");
+ this->Makefile->GetState()
+ ->SetGlobalProperty("PACKAGES_FOUND", tmp.c_str());
- this->Makefile->GetCMakeInstance()->SetProperty("PACKAGES_FOUND",
- tmp.c_str());
-
- tmp = "";
- sep = "";
- for(size_t i=0; i<notFoundContents.size(); i++)
- {
- tmp += sep;
- tmp += notFoundContents[i];
- sep = ";";
- }
- this->Makefile->GetCMakeInstance()->SetProperty("PACKAGES_NOT_FOUND",
- tmp.c_str());
+ tmp = cmJoin(notFoundContents, ";");
+ this->Makefile->GetState()
+ ->SetGlobalProperty("PACKAGES_NOT_FOUND", tmp.c_str());
}
//----------------------------------------------------------------------------
void cmFindPackageCommand::AppendSuccessInformation()
{
+ {
+ std::string transitivePropName = "_CMAKE_";
+ transitivePropName += this->Name + "_TRANSITIVE_DEPENDENCY";
+ this->Makefile->GetState()
+ ->SetGlobalProperty(transitivePropName, "False");
+ }
std::string found = this->Name;
found += "_FOUND";
std::string upperFound = cmSystemTools::UpperCase(found);
- const char* upperResult = this->Makefile->GetDefinition(upperFound.c_str());
- const char* result = this->Makefile->GetDefinition(found.c_str());
+ const char* upperResult = this->Makefile->GetDefinition(upperFound);
+ const char* result = this->Makefile->GetDefinition(found);
bool packageFound = ((cmSystemTools::IsOn(result))
|| (cmSystemTools::IsOn(upperResult)));
@@ -1468,8 +1090,8 @@ void cmFindPackageCommand::AppendSuccessInformation()
std::string quietInfoPropName = "_CMAKE_";
quietInfoPropName += this->Name;
quietInfoPropName += "_QUIET";
- this->Makefile->GetCMakeInstance()->SetProperty(quietInfoPropName.c_str(),
- this->Quiet ? "TRUE" : "FALSE");
+ this->Makefile->GetState()
+ ->SetGlobalProperty(quietInfoPropName, this->Quiet ? "TRUE" : "FALSE");
// set a global property to record the required version of this package
std::string versionInfoPropName = "_CMAKE_";
@@ -1482,15 +1104,15 @@ void cmFindPackageCommand::AppendSuccessInformation()
versionInfo += " ";
versionInfo += this->Version;
}
- this->Makefile->GetCMakeInstance()->SetProperty(versionInfoPropName.c_str(),
- versionInfo.c_str());
+ this->Makefile->GetState()
+ ->SetGlobalProperty(versionInfoPropName, versionInfo.c_str());
if (this->Required)
{
std::string requiredInfoPropName = "_CMAKE_";
requiredInfoPropName += this->Name;
requiredInfoPropName += "_TYPE";
- this->Makefile->GetCMakeInstance()->SetProperty(
- requiredInfoPropName.c_str(), "REQUIRED");
+ this->Makefile->GetState()
+ ->SetGlobalProperty(requiredInfoPropName, "REQUIRED");
}
@@ -1501,95 +1123,108 @@ void cmFindPackageCommand::AppendSuccessInformation()
//----------------------------------------------------------------------------
void cmFindPackageCommand::ComputePrefixes()
{
- this->AddPrefixesCMakeVariable();
- this->AddPrefixesCMakeEnvironment();
- this->AddPrefixesUserHints();
- this->AddPrefixesSystemEnvironment();
- this->AddPrefixesUserRegistry();
- this->AddPrefixesBuilds();
- this->AddPrefixesCMakeSystemVariable();
- this->AddPrefixesSystemRegistry();
- this->AddPrefixesUserGuess();
+ if(!this->NoDefaultPath)
+ {
+ if(!this->NoCMakePath)
+ {
+ this->FillPrefixesCMakeVariable();
+ }
+ if(!this->NoCMakeEnvironmentPath)
+ {
+ this->FillPrefixesCMakeEnvironment();
+ }
+ }
+ this->FillPrefixesUserHints();
+ if(!this->NoDefaultPath)
+ {
+ if(!this->NoSystemEnvironmentPath)
+ {
+ this->FillPrefixesSystemEnvironment();
+ }
+ if(!this->NoUserRegistry)
+ {
+ this->FillPrefixesUserRegistry();
+ }
+ if(!this->NoCMakeSystemPath)
+ {
+ this->FillPrefixesCMakeSystemVariable();
+ }
+ if(!this->NoSystemRegistry)
+ {
+ this->FillPrefixesSystemRegistry();
+ }
+ }
+ this->FillPrefixesUserGuess();
+
this->ComputeFinalPaths();
}
//----------------------------------------------------------------------------
-void cmFindPackageCommand::AddPrefixesCMakeEnvironment()
+void cmFindPackageCommand::FillPrefixesCMakeEnvironment()
{
- if(!this->NoCMakeEnvironmentPath && !this->NoDefaultPath)
- {
- // Check the environment variable with the same name as the cache
- // entry.
- std::string env;
- if(cmSystemTools::GetEnv(this->Variable.c_str(), env) && env.length() > 0)
- {
- cmSystemTools::ConvertToUnixSlashes(env);
- this->AddPathInternal(env, EnvPath);
- }
+ cmSearchPath &paths = this->LabeledPaths[PathLabel::CMakeEnvironment];
- this->AddEnvPath("CMAKE_PREFIX_PATH");
- this->AddEnvPath("CMAKE_FRAMEWORK_PATH");
- this->AddEnvPath("CMAKE_APPBUNDLE_PATH");
- }
+ // Check the environment variable with the same name as the cache
+ // entry.
+ paths.AddEnvPath(this->Variable);
+
+ // And now the general CMake environment variables
+ paths.AddEnvPath("CMAKE_PREFIX_PATH");
+ paths.AddEnvPath("CMAKE_FRAMEWORK_PATH");
+ paths.AddEnvPath("CMAKE_APPBUNDLE_PATH");
}
//----------------------------------------------------------------------------
-void cmFindPackageCommand::AddPrefixesCMakeVariable()
+void cmFindPackageCommand::FillPrefixesCMakeVariable()
{
- if(!this->NoCMakePath && !this->NoDefaultPath)
- {
- this->AddCMakePath("CMAKE_PREFIX_PATH");
- this->AddCMakePath("CMAKE_FRAMEWORK_PATH");
- this->AddCMakePath("CMAKE_APPBUNDLE_PATH");
- }
+ cmSearchPath &paths = this->LabeledPaths[PathLabel::CMake];
+
+ paths.AddCMakePath("CMAKE_PREFIX_PATH");
+ paths.AddCMakePath("CMAKE_FRAMEWORK_PATH");
+ paths.AddCMakePath("CMAKE_APPBUNDLE_PATH");
}
//----------------------------------------------------------------------------
-void cmFindPackageCommand::AddPrefixesSystemEnvironment()
+void cmFindPackageCommand::FillPrefixesSystemEnvironment()
{
- if(!this->NoSystemEnvironmentPath && !this->NoDefaultPath)
+ cmSearchPath &paths = this->LabeledPaths[PathLabel::SystemEnvironment];
+
+ // Use the system search path to generate prefixes.
+ // Relative paths are interpreted with respect to the current
+ // working directory.
+ std::vector<std::string> tmp;
+ cmSystemTools::GetPath(tmp);
+ for(std::vector<std::string>::iterator i = tmp.begin();
+ i != tmp.end(); ++i)
{
- // Use the system search path to generate prefixes.
- // Relative paths are interpreted with respect to the current
- // working directory.
- std::vector<std::string> tmp;
- cmSystemTools::GetPath(tmp);
- for(std::vector<std::string>::iterator i = tmp.begin();
- i != tmp.end(); ++i)
+ // If the path is a PREFIX/bin case then add its parent instead.
+ if((cmHasLiteralSuffix(*i, "/bin")) ||
+ (cmHasLiteralSuffix(*i, "/sbin")))
{
- std::string const& d = *i;
-
- // If the path is a PREFIX/bin case then add its parent instead.
- if((d.size() >= 4 && strcmp(d.c_str()+d.size()-4, "/bin") == 0) ||
- (d.size() >= 5 && strcmp(d.c_str()+d.size()-5, "/sbin") == 0))
- {
- this->AddPathInternal(cmSystemTools::GetFilenamePath(d), EnvPath);
- }
- else
- {
- this->AddPathInternal(d, EnvPath);
- }
+ paths.AddPath(cmSystemTools::GetFilenamePath(*i));
+ }
+ else
+ {
+ paths.AddPath(*i);
}
}
}
//----------------------------------------------------------------------------
-void cmFindPackageCommand::AddPrefixesUserRegistry()
+void cmFindPackageCommand::FillPrefixesUserRegistry()
{
- if(this->NoUserRegistry || this->NoDefaultPath)
- {
- return;
- }
-
#if defined(_WIN32) && !defined(__CYGWIN__)
this->LoadPackageRegistryWinUser();
#elif defined(__HAIKU__)
- BPath dir;
- if (find_directory(B_USER_SETTINGS_DIRECTORY, &dir) == B_OK)
+ char dir[B_PATH_NAME_LENGTH];
+ if (find_directory(B_USER_SETTINGS_DIRECTORY, -1, false, dir, sizeof(dir)) ==
+ B_OK)
{
- dir.Append("cmake/packages");
- dir.Append(this->Name.c_str());
- this->LoadPackageRegistryDir(dir.Path());
+ std::string fname = dir;
+ fname += "/cmake/packages/";
+ fname += Name;
+ this->LoadPackageRegistryDir(fname,
+ this->LabeledPaths[PathLabel::UserRegistry]);
}
#else
if(const char* home = cmSystemTools::GetEnv("HOME"))
@@ -1597,13 +1232,14 @@ void cmFindPackageCommand::AddPrefixesUserRegistry()
std::string dir = home;
dir += "/.cmake/packages/";
dir += this->Name;
- this->LoadPackageRegistryDir(dir);
+ this->LoadPackageRegistryDir(dir,
+ this->LabeledPaths[PathLabel::UserRegistry]);
}
#endif
}
//----------------------------------------------------------------------------
-void cmFindPackageCommand::AddPrefixesSystemRegistry()
+void cmFindPackageCommand::FillPrefixesSystemRegistry()
{
if(this->NoSystemRegistry || this->NoDefaultPath)
{
@@ -1629,47 +1265,50 @@ void cmFindPackageCommand::AddPrefixesSystemRegistry()
void cmFindPackageCommand::LoadPackageRegistryWinUser()
{
// HKEY_CURRENT_USER\\Software shares 32-bit and 64-bit views.
- this->LoadPackageRegistryWin(true, 0);
+ this->LoadPackageRegistryWin(true, 0,
+ this->LabeledPaths[PathLabel::UserRegistry]);
}
//----------------------------------------------------------------------------
void cmFindPackageCommand::LoadPackageRegistryWinSystem()
{
+ cmSearchPath &paths = this->LabeledPaths[PathLabel::SystemRegistry];
+
// HKEY_LOCAL_MACHINE\\SOFTWARE has separate 32-bit and 64-bit views.
// Prefer the target platform view first.
if(this->Makefile->PlatformIs64Bit())
{
- this->LoadPackageRegistryWin(false, KEY_WOW64_64KEY);
- this->LoadPackageRegistryWin(false, KEY_WOW64_32KEY);
+ this->LoadPackageRegistryWin(false, KEY_WOW64_64KEY, paths);
+ this->LoadPackageRegistryWin(false, KEY_WOW64_32KEY, paths);
}
else
{
- this->LoadPackageRegistryWin(false, KEY_WOW64_32KEY);
- this->LoadPackageRegistryWin(false, KEY_WOW64_64KEY);
+ this->LoadPackageRegistryWin(false, KEY_WOW64_32KEY, paths);
+ this->LoadPackageRegistryWin(false, KEY_WOW64_64KEY, paths);
}
}
//----------------------------------------------------------------------------
-void cmFindPackageCommand::LoadPackageRegistryWin(bool user,
- unsigned int view)
+void cmFindPackageCommand::LoadPackageRegistryWin(bool user, unsigned int view,
+ cmSearchPath& outPaths)
{
- std::string key = "Software\\Kitware\\CMake\\Packages\\";
- key += this->Name;
- std::set<cmStdString> bad;
+ std::wstring key = L"Software\\Kitware\\CMake\\Packages\\";
+ key += cmsys::Encoding::ToWide(this->Name);
+ std::set<std::wstring> bad;
HKEY hKey;
- if(RegOpenKeyEx(user? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, key.c_str(),
- 0, KEY_QUERY_VALUE|view, &hKey) == ERROR_SUCCESS)
+ if(RegOpenKeyExW(user? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, key.c_str(),
+ 0, KEY_QUERY_VALUE|view, &hKey) == ERROR_SUCCESS)
{
DWORD valueType = REG_NONE;
- char name[16384];
- std::vector<char> data(512);
+ wchar_t name[16383]; // RegEnumValue docs limit name to 32767 _bytes_
+ std::vector<wchar_t> data(512);
bool done = false;
DWORD index = 0;
while(!done)
{
DWORD nameSize = static_cast<DWORD>(sizeof(name));
- DWORD dataSize = static_cast<DWORD>(data.size()-1);
- switch(RegEnumValue(hKey, index, name, &nameSize,
+ DWORD dataSize = static_cast<DWORD>(data.size()*sizeof(data[0]));
+ switch(RegEnumValueW(hKey, index, name, &nameSize,
0, &valueType, (BYTE*)&data[0], &dataSize))
{
case ERROR_SUCCESS:
@@ -1677,8 +1316,8 @@ void cmFindPackageCommand::LoadPackageRegistryWin(bool user,
if(valueType == REG_SZ)
{
data[dataSize] = 0;
- cmsys_ios::stringstream ss(&data[0]);
- if(!this->CheckPackageRegistryEntry(ss))
+ if(!this->CheckPackageRegistryEntry(
+ cmsys::Encoding::ToNarrow(&data[0]), outPaths))
{
// The entry is invalid.
bad.insert(name);
@@ -1686,7 +1325,7 @@ void cmFindPackageCommand::LoadPackageRegistryWin(bool user,
}
break;
case ERROR_MORE_DATA:
- data.resize(dataSize+1);
+ data.resize((dataSize+sizeof(data[0])-1)/sizeof(data[0]));
break;
case ERROR_NO_MORE_ITEMS: default: done = true; break;
}
@@ -1696,13 +1335,13 @@ void cmFindPackageCommand::LoadPackageRegistryWin(bool user,
// Remove bad values if possible.
if(user && !bad.empty() &&
- RegOpenKeyEx(HKEY_CURRENT_USER, key.c_str(),
+ RegOpenKeyExW(HKEY_CURRENT_USER, key.c_str(),
0, KEY_SET_VALUE|view, &hKey) == ERROR_SUCCESS)
{
- for(std::set<cmStdString>::const_iterator vi = bad.begin();
+ for(std::set<std::wstring>::const_iterator vi = bad.begin();
vi != bad.end(); ++vi)
{
- RegDeleteValue(hKey, vi->c_str());
+ RegDeleteValueW(hKey, vi->c_str());
}
RegCloseKey(hKey);
}
@@ -1720,10 +1359,11 @@ public:
};
//----------------------------------------------------------------------------
-void cmFindPackageCommand::LoadPackageRegistryDir(std::string const& dir)
+void cmFindPackageCommand::LoadPackageRegistryDir(std::string const& dir,
+ cmSearchPath& outPaths)
{
cmsys::Directory files;
- if(!files.Load(dir.c_str()))
+ if(!files.Load(dir))
{
return;
}
@@ -1735,14 +1375,16 @@ void cmFindPackageCommand::LoadPackageRegistryDir(std::string const& dir)
fname += "/";
fname += files.GetFile(i);
- if(!cmSystemTools::FileIsDirectory(fname.c_str()))
+ if(!cmSystemTools::FileIsDirectory(fname))
{
// Hold this file hostage until it behaves.
cmFindPackageCommandHoldFile holdFile(fname.c_str());
// Load the file.
- std::ifstream fin(fname.c_str(), std::ios::in | cmsys_ios_binary);
- if(fin && this->CheckPackageRegistryEntry(fin))
+ cmsys::ifstream fin(fname.c_str(), std::ios::in | std::ios::binary);
+ std::string fentry;
+ if(fin && cmSystemTools::GetLineFromStream(fin, fentry) &&
+ this->CheckPackageRegistryEntry(fentry, outPaths))
{
// The file references an existing package, so release it.
holdFile.Release();
@@ -1755,23 +1397,25 @@ void cmFindPackageCommand::LoadPackageRegistryDir(std::string const& dir)
#endif
//----------------------------------------------------------------------------
-bool cmFindPackageCommand::CheckPackageRegistryEntry(std::istream& is)
+bool cmFindPackageCommand::CheckPackageRegistryEntry(const std::string& fname,
+ cmSearchPath& outPaths)
{
// Parse the content of one package registry entry.
- std::string fname;
- if(cmSystemTools::GetLineFromStream(is, fname) &&
- cmSystemTools::FileIsFullPath(fname.c_str()))
+ if(cmSystemTools::FileIsFullPath(fname.c_str()))
{
// The first line in the stream is the full path to a file or
// directory containing the package.
if(cmSystemTools::FileExists(fname.c_str()))
{
// The path exists. Look for the package here.
- if(!cmSystemTools::FileIsDirectory(fname.c_str()))
+ if(!cmSystemTools::FileIsDirectory(fname))
+ {
+ outPaths.AddPath(cmSystemTools::GetFilenamePath(fname));
+ }
+ else
{
- fname = cmSystemTools::GetFilenamePath(fname);
+ outPaths.AddPath(fname);
}
- this->AddPathInternal(fname, FullPath);
return true;
}
else
@@ -1792,52 +1436,37 @@ bool cmFindPackageCommand::CheckPackageRegistryEntry(std::istream& is)
}
//----------------------------------------------------------------------------
-void cmFindPackageCommand::AddPrefixesBuilds()
+void cmFindPackageCommand::FillPrefixesCMakeSystemVariable()
{
- if(!this->NoBuilds && !this->NoDefaultPath)
- {
- // It is likely that CMake will have recently built the project.
- for(int i=0; i <= 10; ++i)
- {
- cmOStringStream r;
- r <<
- "[HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\"
- "Settings\\StartPath;WhereBuild" << i << "]";
- std::string f = r.str();
- cmSystemTools::ExpandRegistryValues(f);
- cmSystemTools::ConvertToUnixSlashes(f);
- if(cmSystemTools::FileIsFullPath(f.c_str()) &&
- cmSystemTools::FileIsDirectory(f.c_str()))
- {
- this->AddPathInternal(f, FullPath);
- }
- }
- }
+ cmSearchPath &paths = this->LabeledPaths[PathLabel::CMakeSystem];
+
+ paths.AddCMakePath("CMAKE_SYSTEM_PREFIX_PATH");
+ paths.AddCMakePath("CMAKE_SYSTEM_FRAMEWORK_PATH");
+ paths.AddCMakePath("CMAKE_SYSTEM_APPBUNDLE_PATH");
}
//----------------------------------------------------------------------------
-void cmFindPackageCommand::AddPrefixesCMakeSystemVariable()
+void cmFindPackageCommand::FillPrefixesUserGuess()
{
- if(!this->NoCMakeSystemPath && !this->NoDefaultPath)
+ cmSearchPath &paths = this->LabeledPaths[PathLabel::Guess];
+
+ for(std::vector<std::string>::const_iterator p = this->UserGuessArgs.begin();
+ p != this->UserGuessArgs.end(); ++p)
{
- this->AddCMakePath("CMAKE_SYSTEM_PREFIX_PATH");
- this->AddCMakePath("CMAKE_SYSTEM_FRAMEWORK_PATH");
- this->AddCMakePath("CMAKE_SYSTEM_APPBUNDLE_PATH");
+ paths.AddUserPath(*p);
}
}
//----------------------------------------------------------------------------
-void cmFindPackageCommand::AddPrefixesUserGuess()
+void cmFindPackageCommand::FillPrefixesUserHints()
{
- // Add guesses specified by the caller.
- this->AddPathsInternal(this->UserPaths, CMakePath);
-}
+ cmSearchPath &paths = this->LabeledPaths[PathLabel::Hints];
-//----------------------------------------------------------------------------
-void cmFindPackageCommand::AddPrefixesUserHints()
-{
- // Add hints specified by the caller.
- this->AddPathsInternal(this->UserHints, CMakePath);
+ for(std::vector<std::string>::const_iterator p = this->UserHintsArgs.begin();
+ p != this->UserHintsArgs.end(); ++p)
+ {
+ paths.AddUserPath(*p);
+ }
}
//----------------------------------------------------------------------------
@@ -1944,7 +1573,6 @@ bool cmFindPackageCommand::CheckVersion(std::string const& config_file)
if ((haveResult == false) && (this->Version.empty()))
{
result = true;
- haveResult = true;
}
ConfigFileInfo configFileInfo;
@@ -2048,25 +1676,25 @@ void cmFindPackageCommand::StoreVersionFound()
ver += "_VERSION";
if(this->VersionFound.empty())
{
- this->Makefile->RemoveDefinition(ver.c_str());
+ this->Makefile->RemoveDefinition(ver);
}
else
{
- this->Makefile->AddDefinition(ver.c_str(), this->VersionFound.c_str());
+ this->Makefile->AddDefinition(ver, this->VersionFound.c_str());
}
// Store the version components.
char buf[64];
sprintf(buf, "%u", this->VersionFoundMajor);
- this->Makefile->AddDefinition((ver+"_MAJOR").c_str(), buf);
+ this->Makefile->AddDefinition(ver+"_MAJOR", buf);
sprintf(buf, "%u", this->VersionFoundMinor);
- this->Makefile->AddDefinition((ver+"_MINOR").c_str(), buf);
+ this->Makefile->AddDefinition(ver+"_MINOR", buf);
sprintf(buf, "%u", this->VersionFoundPatch);
- this->Makefile->AddDefinition((ver+"_PATCH").c_str(), buf);
+ this->Makefile->AddDefinition(ver+"_PATCH", buf);
sprintf(buf, "%u", this->VersionFoundTweak);
- this->Makefile->AddDefinition((ver+"_TWEAK").c_str(), buf);
+ this->Makefile->AddDefinition(ver+"_TWEAK", buf);
sprintf(buf, "%u", this->VersionFoundCount);
- this->Makefile->AddDefinition((ver+"_COUNT").c_str(), buf);
+ this->Makefile->AddDefinition(ver+"_COUNT", buf);
}
//----------------------------------------------------------------------------
@@ -2235,7 +1863,7 @@ private:
// Construct a list of matches.
std::vector<std::string> matches;
cmsys::Directory d;
- d.Load(parent.c_str());
+ d.Load(parent);
for(unsigned long i=0; i < d.GetNumberOfFiles(); ++i)
{
const char* fname = d.GetFile(i);
@@ -2289,7 +1917,7 @@ private:
// Construct a list of matches.
std::vector<std::string> matches;
cmsys::Directory d;
- d.Load(parent.c_str());
+ d.Load(parent);
for(unsigned long i=0; i < d.GetNumberOfFiles(); ++i)
{
const char* fname = d.GetFile(i);
@@ -2343,7 +1971,7 @@ private:
// Look for matching files.
std::vector<std::string> matches;
cmsys::Directory d;
- d.Load(parent.c_str());
+ d.Load(parent);
for(unsigned long i=0; i < d.GetNumberOfFiles(); ++i)
{
const char* fname = d.GetFile(i);
@@ -2395,7 +2023,7 @@ private:
for(std::vector<std::string>::const_iterator fi = files.begin();
fi != files.end(); ++fi)
{
- if(cmSystemTools::FileIsDirectory(fi->c_str()))
+ if(cmSystemTools::FileIsDirectory(*fi))
{
if(this->Consider(*fi, lister))
{
@@ -2423,7 +2051,7 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
}
// Skip this if the prefix does not exist.
- if(!cmSystemTools::FileIsDirectory(prefix_in.c_str()))
+ if(!cmSystemTools::FileIsDirectory(prefix_in))
{
return false;
}
diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h
index c3801220d..8bfd4051e 100644
--- a/Source/cmFindPackageCommand.h
+++ b/Source/cmFindPackageCommand.h
@@ -49,30 +49,30 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "find_package";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Load settings for an external project.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const;
+ virtual std::string GetName() const { return "find_package";}
cmTypeMacro(cmFindPackageCommand, cmFindCommon);
-protected:
- virtual void GenerateDocumentation();
private:
+ class PathLabel : public cmFindCommon::PathLabel
+ {
+ protected:
+ PathLabel();
+ public:
+ PathLabel(const std::string& label) : cmFindCommon::PathLabel(label) { }
+ static PathLabel UserRegistry;
+ static PathLabel Builds;
+ static PathLabel SystemRegistry;
+ };
+
+ // Add additional search path labels and groups not present in the
+ // parent class
+ void AppendSearchPathGroups();
+
void AppendSuccessInformation();
void AppendToFoundProperty(bool found);
void SetModuleVariables(const std::string& components);
bool FindModule(bool& found);
- void AddFindDefinition(const char* var, const char* val);
+ void AddFindDefinition(const std::string& var, const char* val);
void RestoreFindDefinitions();
bool HandlePackageMode();
bool FindConfig();
@@ -84,20 +84,21 @@ private:
void StoreVersionFound();
void ComputePrefixes();
- void AddPrefixesCMakeEnvironment();
- void AddPrefixesCMakeVariable();
- void AddPrefixesSystemEnvironment();
- void AddPrefixesUserRegistry();
- void AddPrefixesSystemRegistry();
- void AddPrefixesBuilds();
- void AddPrefixesCMakeSystemVariable();
- void AddPrefixesUserGuess();
- void AddPrefixesUserHints();
- void LoadPackageRegistryDir(std::string const& dir);
+ void FillPrefixesCMakeEnvironment();
+ void FillPrefixesCMakeVariable();
+ void FillPrefixesSystemEnvironment();
+ void FillPrefixesUserRegistry();
+ void FillPrefixesSystemRegistry();
+ void FillPrefixesCMakeSystemVariable();
+ void FillPrefixesUserGuess();
+ void FillPrefixesUserHints();
+ void LoadPackageRegistryDir(std::string const& dir, cmSearchPath& outPaths);
void LoadPackageRegistryWinUser();
void LoadPackageRegistryWinSystem();
- void LoadPackageRegistryWin(bool user, unsigned int view);
- bool CheckPackageRegistryEntry(std::istream& is);
+ void LoadPackageRegistryWin(bool user, unsigned int view,
+ cmSearchPath& outPaths);
+ bool CheckPackageRegistryEntry(const std::string& fname,
+ cmSearchPath& outPaths);
bool SearchDirectory(std::string const& dir);
bool CheckDirectory(std::string const& dir);
bool FindConfigFile(std::string const& dir, std::string& file);
@@ -111,34 +112,31 @@ private:
friend class cmFindPackageFileList;
struct OriginalDef { bool exists; std::string value; };
- std::map<cmStdString, OriginalDef> OriginalDefs;
+ std::map<std::string, OriginalDef> OriginalDefs;
- std::string CommandDocumentation;
- cmStdString Name;
- cmStdString Variable;
- cmStdString Version;
+ std::string Name;
+ std::string Variable;
+ std::string Version;
unsigned int VersionMajor;
unsigned int VersionMinor;
unsigned int VersionPatch;
unsigned int VersionTweak;
unsigned int VersionCount;
bool VersionExact;
- cmStdString FileFound;
- cmStdString VersionFound;
+ std::string FileFound;
+ std::string VersionFound;
unsigned int VersionFoundMajor;
unsigned int VersionFoundMinor;
unsigned int VersionFoundPatch;
unsigned int VersionFoundTweak;
unsigned int VersionFoundCount;
- unsigned int RequiredCMakeVersion;
+ KWIML_INT_uint64_t RequiredCMakeVersion;
bool Quiet;
bool Required;
- bool Compatibility_1_6;
bool UseConfigFiles;
bool UseFindModules;
bool NoUserRegistry;
bool NoSystemRegistry;
- bool NoBuilds;
bool DebugMode;
bool UseLib64Paths;
bool PolicyScope;
diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx
index 6a432984d..1f3d1a455 100644
--- a/Source/cmFindPathCommand.cxx
+++ b/Source/cmFindPathCommand.cxx
@@ -10,7 +10,6 @@
See the License for more information.
============================================================================*/
#include "cmFindPathCommand.h"
-#include "cmCacheManager.h"
#include <cmsys/Glob.hxx>
@@ -20,51 +19,6 @@ cmFindPathCommand::cmFindPathCommand()
this->IncludeFileInPath = false;
}
-void cmFindPathCommand::GenerateDocumentation()
-{
- this->cmFindBase::GenerateDocumentation();
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "FIND_XXX", "find_path");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "CMAKE_XXX_PATH", "CMAKE_INCLUDE_PATH");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "CMAKE_XXX_MAC_PATH",
- "CMAKE_FRAMEWORK_PATH");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "CMAKE_SYSTEM_XXX_MAC_PATH",
- "CMAKE_SYSTEM_FRAMEWORK_PATH");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "XXX_SYSTEM", "INCLUDE");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "CMAKE_SYSTEM_XXX_PATH",
- "CMAKE_SYSTEM_INCLUDE_PATH");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "SEARCH_XXX_DESC",
- "directory containing the named file");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "SEARCH_XXX", "file in a directory");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "XXX_SUBDIR", "include");
- cmSystemTools::ReplaceString(
- this->GenericDocumentation,
- "XXX_EXTRA_PREFIX_ENTRY",
- " <prefix>/include/<arch> if CMAKE_LIBRARY_ARCHITECTURE is set, and\n");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "CMAKE_FIND_ROOT_PATH_MODE_XXX",
- "CMAKE_FIND_ROOT_PATH_MODE_INCLUDE");
- if(!this->IncludeFileInPath)
- {
- this->GenericDocumentation +=
- "\n"
- "When searching for frameworks, if the file is specified as "
- "A/b.h, then the framework search will look for "
- "A.framework/Headers/b.h. "
- "If that is found the path will be set to the path to the framework. "
- "CMake will convert this to the correct -F option to include the "
- "file. ";
- }
-}
-
// cmFindPathCommand
bool cmFindPathCommand
::InitialPass(std::vector<std::string> const& argsIn, cmExecutionStatus &)
@@ -83,31 +37,31 @@ bool cmFindPathCommand
if(this->AlreadyInCacheWithoutMetaInfo)
{
this->Makefile->AddCacheDefinition(
- this->VariableName.c_str(), "",
+ this->VariableName, "",
this->VariableDocumentation.c_str(),
(this->IncludeFileInPath ?
- cmCacheManager::FILEPATH :cmCacheManager::PATH)
+ cmState::FILEPATH :cmState::PATH)
);
}
return true;
}
std::string result = this->FindHeader();
- if(result.size() != 0)
+ if(!result.empty())
{
this->Makefile->AddCacheDefinition
- (this->VariableName.c_str(), result.c_str(),
+ (this->VariableName, result.c_str(),
this->VariableDocumentation.c_str(),
(this->IncludeFileInPath) ?
- cmCacheManager::FILEPATH :cmCacheManager::PATH);
+ cmState::FILEPATH :cmState::PATH);
return true;
}
this->Makefile->AddCacheDefinition
- (this->VariableName.c_str(),
+ (this->VariableName,
(this->VariableName + "-NOTFOUND").c_str(),
this->VariableDocumentation.c_str(),
(this->IncludeFileInPath) ?
- cmCacheManager::FILEPATH :cmCacheManager::PATH);
+ cmState::FILEPATH :cmState::PATH);
return true;
}
@@ -134,9 +88,9 @@ std::string
cmFindPathCommand::FindHeaderInFramework(std::string const& file,
std::string const& dir)
{
- cmStdString fileName = file;
- cmStdString frameWorkName;
- cmStdString::size_type pos = fileName.find("/");
+ std::string fileName = file;
+ std::string frameWorkName;
+ std::string::size_type pos = fileName.find("/");
// if there is a / in the name try to find the header as a framework
// For example bar/foo.h would look for:
// bar.framework/Headers/foo.h
@@ -153,7 +107,7 @@ cmFindPathCommand::FindHeaderInFramework(std::string const& file,
fileName = file;
frameWorkName = "";
}
- if(frameWorkName.size())
+ if(!frameWorkName.empty())
{
std::string fpath = dir;
fpath += frameWorkName;
@@ -173,15 +127,15 @@ cmFindPathCommand::FindHeaderInFramework(std::string const& file,
}
// if it is not found yet or not a framework header, then do a glob search
// for all frameworks in the directory: dir/*.framework/Headers/<file>
- cmStdString glob = dir;
+ std::string glob = dir;
glob += "*.framework/Headers/";
glob += file;
cmsys::Glob globIt;
globIt.FindFiles(glob);
std::vector<std::string> files = globIt.GetFiles();
- if(files.size())
+ if(!files.empty())
{
- cmStdString fheader = cmSystemTools::CollapseFullPath(files[0].c_str());
+ std::string fheader = cmSystemTools::CollapseFullPath(files[0]);
if(this->IncludeFileInPath)
{
return fheader;
diff --git a/Source/cmFindPathCommand.h b/Source/cmFindPathCommand.h
index 759567dc1..a51da7920 100644
--- a/Source/cmFindPathCommand.h
+++ b/Source/cmFindPathCommand.h
@@ -49,20 +49,10 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const {return "find_path";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Find the directory containing a file.";
- }
+ virtual std::string GetName() const {return "find_path";}
cmTypeMacro(cmFindPathCommand, cmFindBase);
bool IncludeFileInPath;
-protected:
- virtual void GenerateDocumentation();
private:
std::string FindHeaderInFramework(std::string const& file,
std::string const& dir);
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx
index 909b333ff..219ad48b5 100644
--- a/Source/cmFindProgramCommand.cxx
+++ b/Source/cmFindProgramCommand.cxx
@@ -10,42 +10,84 @@
See the License for more information.
============================================================================*/
#include "cmFindProgramCommand.h"
-#include "cmCacheManager.h"
#include <stdlib.h>
#if defined(__APPLE__)
#include <CoreFoundation/CoreFoundation.h>
#endif
-void cmFindProgramCommand::GenerateDocumentation()
+//----------------------------------------------------------------------------
+struct cmFindProgramHelper
{
- this->cmFindBase::GenerateDocumentation();
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "FIND_XXX", "find_program");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "CMAKE_XXX_PATH", "CMAKE_PROGRAM_PATH");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "CMAKE_XXX_MAC_PATH",
- "CMAKE_APPBUNDLE_PATH");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "CMAKE_SYSTEM_XXX_MAC_PATH",
- "CMAKE_SYSTEM_APPBUNDLE_PATH");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "XXX_SYSTEM", "");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "CMAKE_SYSTEM_XXX_PATH",
- "CMAKE_SYSTEM_PROGRAM_PATH");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "SEARCH_XXX_DESC", "program");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "SEARCH_XXX", "program");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "XXX_SUBDIR", "[s]bin");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "XXX_EXTRA_PREFIX_ENTRY", "");
- cmSystemTools::ReplaceString(this->GenericDocumentation,
- "CMAKE_FIND_ROOT_PATH_MODE_XXX",
- "CMAKE_FIND_ROOT_PATH_MODE_PROGRAM");
+ cmFindProgramHelper()
+ {
+#if defined (_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
+ // Consider platform-specific extensions.
+ this->Extensions.push_back(".com");
+ this->Extensions.push_back(".exe");
+#endif
+ // Consider original name with no extensions.
+ this->Extensions.push_back("");
+ }
+
+ // List of valid extensions.
+ std::vector<std::string> Extensions;
+
+ // Keep track of the best program file found so far.
+ std::string BestPath;
+
+ // Current names under consideration.
+ std::vector<std::string> Names;
+
+ // Current full path under consideration.
+ std::string TestPath;
+
+ void AddName(std::string const& name)
+ {
+ this->Names.push_back(name);
+ }
+ void SetName(std::string const& name)
+ {
+ this->Names.clear();
+ this->AddName(name);
+ }
+ bool CheckDirectory(std::string const& path)
+ {
+ for (std::vector<std::string>::iterator i = this->Names.begin();
+ i != this->Names.end(); ++i)
+ {
+ if (this->CheckDirectoryForName(path, *i))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ bool CheckDirectoryForName(std::string const& path, std::string const& name)
+ {
+ for (std::vector<std::string>::iterator ext = this->Extensions.begin();
+ ext != this->Extensions.end(); ++ext)
+ {
+ this->TestPath = path;
+ this->TestPath += name;
+ if (!ext->empty() && cmSystemTools::StringEndsWith(name, ext->c_str()))
+ {
+ continue;
+ }
+ this->TestPath += *ext;
+ if (cmSystemTools::FileExists(this->TestPath, true))
+ {
+ this->BestPath = cmSystemTools::CollapseFullPath(this->TestPath);
+ return true;
+ }
+ }
+ return false;
+ }
+};
+
+cmFindProgramCommand::cmFindProgramCommand()
+{
+ this->NamesPerDirAllowed = true;
}
// cmFindProgramCommand
@@ -66,60 +108,134 @@ bool cmFindProgramCommand
// value.
if(this->AlreadyInCacheWithoutMetaInfo)
{
- this->Makefile->AddCacheDefinition(this->VariableName.c_str(), "",
+ this->Makefile->AddCacheDefinition(this->VariableName, "",
this->VariableDocumentation.c_str(),
- cmCacheManager::FILEPATH);
+ cmState::FILEPATH);
}
return true;
}
- std::string result = FindProgram(this->Names);
+ std::string result = FindProgram();
if(result != "")
{
// Save the value in the cache
- this->Makefile->AddCacheDefinition(this->VariableName.c_str(),
+ this->Makefile->AddCacheDefinition(this->VariableName,
result.c_str(),
this->VariableDocumentation.c_str(),
- cmCacheManager::FILEPATH);
+ cmState::FILEPATH);
return true;
}
- this->Makefile->AddCacheDefinition(this->VariableName.c_str(),
+ this->Makefile->AddCacheDefinition(this->VariableName,
(this->VariableName + "-NOTFOUND").c_str(),
this->VariableDocumentation.c_str(),
- cmCacheManager::FILEPATH);
+ cmState::FILEPATH);
return true;
}
-std::string cmFindProgramCommand::FindProgram(std::vector<std::string> names)
+std::string cmFindProgramCommand::FindProgram()
{
std::string program = "";
if(this->SearchAppBundleFirst || this->SearchAppBundleOnly)
{
- program = FindAppBundle(names);
+ program = FindAppBundle();
}
if(program.empty() && !this->SearchAppBundleOnly)
{
- program = cmSystemTools::FindProgram(names, this->SearchPaths, true);
+ program = this->FindNormalProgram();
}
if(program.empty() && this->SearchAppBundleLast)
{
- program = this->FindAppBundle(names);
+ program = this->FindAppBundle();
}
return program;
}
-std::string cmFindProgramCommand
-::FindAppBundle(std::vector<std::string> names)
+//----------------------------------------------------------------------------
+std::string cmFindProgramCommand::FindNormalProgram()
+{
+ if(this->NamesPerDir)
+ {
+ return this->FindNormalProgramNamesPerDir();
+ }
+ else
+ {
+ return this->FindNormalProgramDirsPerName();
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmFindProgramCommand::FindNormalProgramNamesPerDir()
+{
+ // Search for all names in each directory.
+ cmFindProgramHelper helper;
+ for (std::vector<std::string>::const_iterator ni = this->Names.begin();
+ ni != this->Names.end() ; ++ni)
+ {
+ helper.AddName(*ni);
+ }
+
+ // Check for the names themselves (e.g. absolute paths).
+ if (helper.CheckDirectory(std::string()))
+ {
+ return helper.BestPath;
+ }
+
+ // Search every directory.
+ for (std::vector<std::string>::const_iterator
+ p = this->SearchPaths.begin(); p != this->SearchPaths.end(); ++p)
+ {
+ if(helper.CheckDirectory(*p))
+ {
+ return helper.BestPath;
+ }
+ }
+ // Couldn't find the program.
+ return "";
+}
+
+//----------------------------------------------------------------------------
+std::string cmFindProgramCommand::FindNormalProgramDirsPerName()
+{
+ // Search the entire path for each name.
+ cmFindProgramHelper helper;
+ for (std::vector<std::string>::const_iterator ni = this->Names.begin();
+ ni != this->Names.end() ; ++ni)
+ {
+ // Switch to searching for this name.
+ helper.SetName(*ni);
+
+ // Check for the name by itself (e.g. an absolute path).
+ if (helper.CheckDirectory(std::string()))
+ {
+ return helper.BestPath;
+ }
+
+ // Search every directory.
+ for (std::vector<std::string>::const_iterator
+ p = this->SearchPaths.begin();
+ p != this->SearchPaths.end(); ++p)
+ {
+ if (helper.CheckDirectory(*p))
+ {
+ return helper.BestPath;
+ }
+ }
+ }
+ // Couldn't find the program.
+ return "";
+}
+
+std::string cmFindProgramCommand::FindAppBundle()
{
- for(std::vector<std::string>::const_iterator name = names.begin();
- name != names.end() ; ++name)
+ for(std::vector<std::string>::const_iterator name = this->Names.begin();
+ name != this->Names.end() ; ++name)
{
std::string appName = *name + std::string(".app");
- std::string appPath = cmSystemTools::FindDirectory(appName.c_str(),
+ std::string appPath = cmSystemTools::FindDirectory(appName,
this->SearchPaths,
true);
@@ -128,7 +244,7 @@ std::string cmFindProgramCommand
std::string executable = GetBundleExecutable(appPath);
if (!executable.empty())
{
- return cmSystemTools::CollapseFullPath(executable.c_str());
+ return cmSystemTools::CollapseFullPath(executable);
}
}
}
diff --git a/Source/cmFindProgramCommand.h b/Source/cmFindProgramCommand.h
index 8350c9b42..f88186b92 100644
--- a/Source/cmFindProgramCommand.h
+++ b/Source/cmFindProgramCommand.h
@@ -25,6 +25,7 @@
class cmFindProgramCommand : public cmFindBase
{
public:
+ cmFindProgramCommand();
/**
* This is a virtual constructor for the command.
*/
@@ -48,24 +49,16 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "find_program";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Find an executable program.";
- }
+ virtual std::string GetName() const { return "find_program";}
cmTypeMacro(cmFindProgramCommand, cmFindBase);
-protected:
- std::string FindProgram(std::vector<std::string> names);
- virtual void GenerateDocumentation();
-
private:
- std::string FindAppBundle(std::vector<std::string> names);
+ std::string FindProgram();
+ std::string FindNormalProgram();
+ std::string FindNormalProgramDirsPerName();
+ std::string FindNormalProgramNamesPerDir();
+ std::string FindAppBundle();
std::string GetBundleExecutable(std::string bundlePath);
};
diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx
index d69706730..e983bfb98 100644
--- a/Source/cmForEachCommand.cxx
+++ b/Source/cmForEachCommand.cxx
@@ -13,6 +13,17 @@
#include <cmsys/auto_ptr.hxx>
+cmForEachFunctionBlocker::cmForEachFunctionBlocker(cmMakefile* mf):
+ Makefile(mf), Depth(0)
+{
+ this->Makefile->PushLoopBlock();
+}
+
+cmForEachFunctionBlocker::~cmForEachFunctionBlocker()
+{
+ this->Makefile->PopLoopBlock();
+}
+
bool cmForEachFunctionBlocker::
IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
cmExecutionStatus &inStatus)
@@ -35,19 +46,17 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
// at end of for each execute recorded commands
// store the old value
std::string oldDef;
- if (mf.GetDefinition(this->Args[0].c_str()))
+ if (mf.GetDefinition(this->Args[0]))
{
- oldDef = mf.GetDefinition(this->Args[0].c_str());
+ oldDef = mf.GetDefinition(this->Args[0]);
}
std::vector<std::string>::const_iterator j = this->Args.begin();
++j;
- std::string tmps;
- cmListFileArgument arg;
for( ; j != this->Args.end(); ++j)
{
// set the variable to the loop value
- mf.AddDefinition(this->Args[0].c_str(),j->c_str());
+ mf.AddDefinition(this->Args[0],j->c_str());
// Invoke all the functions that were collected in the block.
cmExecutionStatus status;
for(unsigned int c = 0; c < this->Functions.size(); ++c)
@@ -58,23 +67,28 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
{
inStatus.SetReturnInvoked(true);
// restore the variable to its prior value
- mf.AddDefinition(this->Args[0].c_str(),oldDef.c_str());
+ mf.AddDefinition(this->Args[0],oldDef.c_str());
return true;
}
if (status.GetBreakInvoked())
{
// restore the variable to its prior value
- mf.AddDefinition(this->Args[0].c_str(),oldDef.c_str());
+ mf.AddDefinition(this->Args[0],oldDef.c_str());
return true;
}
+ if (status.GetContinueInvoked())
+ {
+ break;
+ }
if(cmSystemTools::GetFatalErrorOccured() )
{
return true;
}
}
}
+
// restore the variable to its prior value
- mf.AddDefinition(this->Args[0].c_str(),oldDef.c_str());
+ mf.AddDefinition(this->Args[0],oldDef.c_str());
return true;
}
else
@@ -123,7 +137,7 @@ bool cmForEachCommand
}
// create a function blocker
- cmForEachFunctionBlocker *f = new cmForEachFunctionBlocker();
+ cmForEachFunctionBlocker *f = new cmForEachFunctionBlocker(this->Makefile);
if ( args.size() > 1 )
{
if ( args[1] == "RANGE" )
@@ -163,10 +177,10 @@ bool cmForEachCommand
step == 0
)
{
- cmOStringStream str;
+ std::ostringstream str;
str << "called with incorrect range specification: start ";
str << start << ", stop " << stop << ", step " << step;
- this->SetError(str.str().c_str());
+ this->SetError(str.str());
return false;
}
std::vector<std::string> range;
@@ -205,7 +219,8 @@ bool cmForEachCommand
//----------------------------------------------------------------------------
bool cmForEachCommand::HandleInMode(std::vector<std::string> const& args)
{
- cmsys::auto_ptr<cmForEachFunctionBlocker> f(new cmForEachFunctionBlocker());
+ cmsys::auto_ptr<cmForEachFunctionBlocker>
+ f(new cmForEachFunctionBlocker(this->Makefile));
f->Args.push_back(args[0]);
enum Doing { DoingNone, DoingLists, DoingItems };
@@ -226,7 +241,7 @@ bool cmForEachCommand::HandleInMode(std::vector<std::string> const& args)
}
else if(doing == DoingLists)
{
- const char* value = this->Makefile->GetDefinition(args[i].c_str());
+ const char* value = this->Makefile->GetDefinition(args[i]);
if(value && *value)
{
cmSystemTools::ExpandListArgument(value, f->Args, true);
@@ -234,7 +249,7 @@ bool cmForEachCommand::HandleInMode(std::vector<std::string> const& args)
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Unknown argument:\n" << " " << args[i] << "\n";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
return true;
@@ -242,5 +257,6 @@ bool cmForEachCommand::HandleInMode(std::vector<std::string> const& args)
}
this->Makefile->AddFunctionBlocker(f.release()); // TODO: pass auto_ptr
+
return true;
}
diff --git a/Source/cmForEachCommand.h b/Source/cmForEachCommand.h
index dc4761306..36e88088f 100644
--- a/Source/cmForEachCommand.h
+++ b/Source/cmForEachCommand.h
@@ -19,8 +19,8 @@
class cmForEachFunctionBlocker : public cmFunctionBlocker
{
public:
- cmForEachFunctionBlocker() {this->Depth = 0;}
- virtual ~cmForEachFunctionBlocker() {}
+ cmForEachFunctionBlocker(cmMakefile* mf);
+ ~cmForEachFunctionBlocker();
virtual bool IsFunctionBlocked(const cmListFileFunction& lff,
cmMakefile &mf,
cmExecutionStatus &);
@@ -29,6 +29,7 @@ public:
std::vector<std::string> Args;
std::vector<cmListFileFunction> Functions;
private:
+ cmMakefile* Makefile;
int Depth;
};
@@ -59,53 +60,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "foreach";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Evaluate a group of commands for each value in a list.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " foreach(loop_var arg1 arg2 ...)\n"
- " COMMAND1(ARGS ...)\n"
- " COMMAND2(ARGS ...)\n"
- " ...\n"
- " endforeach(loop_var)\n"
- "All commands between foreach and the matching endforeach are recorded "
- "without being invoked. Once the endforeach is evaluated, the "
- "recorded list of commands is invoked once for each argument listed "
- "in the original foreach command. Before each iteration of the loop "
- "\"${loop_var}\" will be set as a variable with "
- "the current value in the list.\n"
- " foreach(loop_var RANGE total)\n"
- " foreach(loop_var RANGE start stop [step])\n"
- "Foreach can also iterate over a generated range of numbers. "
- "There are three types of this iteration:\n"
- "* When specifying single number, the range will have elements "
- "0 to \"total\".\n"
- "* When specifying two numbers, the range will have elements from "
- "the first number to the second number.\n"
- "* The third optional number is the increment used to iterate from "
- "the first number to the second number."
- "\n"
- " foreach(loop_var IN [LISTS [list1 [...]]]\n"
- " [ITEMS [item1 [...]]])\n"
- "Iterates over a precise list of items. "
- "The LISTS option names list-valued variables to be traversed, "
- "including empty elements (an empty string is a zero-length list). "
- "The ITEMS option ends argument parsing and includes all arguments "
- "following it in the iteration."
- ;
- }
+ virtual std::string GetName() const { return "foreach";}
cmTypeMacro(cmForEachCommand, cmCommand);
private:
diff --git a/Source/cmFortranLexer.cxx b/Source/cmFortranLexer.cxx
new file mode 100644
index 000000000..6779c1ae8
--- /dev/null
+++ b/Source/cmFortranLexer.cxx
@@ -0,0 +1,2431 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#line 2 "cmFortranLexer.cxx"
+
+#line 4 "cmFortranLexer.cxx"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 39
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* An opaque pointer. */
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void* yyscan_t;
+#endif
+
+/* For convenience, these vars (plus the bison vars far below)
+ are macros in the reentrant scanner. */
+#define yyin yyg->yyin_r
+#define yyout yyg->yyout_r
+#define yyextra yyg->yyextra_r
+#define yyleng yyg->yyleng_r
+#define yytext yyg->yytext_r
+#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
+#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
+#define yy_flex_debug yyg->yy_flex_debug_r
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yyg->yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yyg->yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE cmFortran_yyrestart(yyin ,yyscanner )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
+#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+ #define YY_LINENO_REWIND_TO(ptr)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = yyg->yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ yy_size_t yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via cmFortran_yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
+ ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
+ : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
+
+void cmFortran_yyrestart (FILE *input_file ,yyscan_t yyscanner );
+void cmFortran_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmFortran_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
+void cmFortran_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void cmFortran_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void cmFortran_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+void cmFortran_yypop_buffer_state (yyscan_t yyscanner );
+
+static void cmFortran_yyensure_buffer_stack (yyscan_t yyscanner );
+static void cmFortran_yy_load_buffer_state (yyscan_t yyscanner );
+static void cmFortran_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
+
+#define YY_FLUSH_BUFFER cmFortran_yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
+
+YY_BUFFER_STATE cmFortran_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmFortran_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmFortran_yy_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner );
+
+void *cmFortran_yyalloc (yy_size_t ,yyscan_t yyscanner );
+void *cmFortran_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
+void cmFortran_yyfree (void * ,yyscan_t yyscanner );
+
+#define yy_new_buffer cmFortran_yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ cmFortran_yyensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ cmFortran_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ cmFortran_yyensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ cmFortran_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define cmFortran_yywrap(yyscanner) 1
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+typedef int yy_state_type;
+
+#define yytext_ptr yytext_r
+
+static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner);
+static int yy_get_next_buffer (yyscan_t yyscanner );
+static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yyg->yytext_ptr = yy_bp; \
+ yyleng = (size_t) (yy_cp - yy_bp); \
+ yyg->yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yyg->yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 45
+#define YY_END_OF_BUFFER 46
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_accept[173] =
+ { 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 46, 40, 42, 41, 44, 1, 40, 33, 2, 35,
+ 40, 41, 38, 40, 39, 40, 39, 42, 40, 41,
+ 40, 39, 9, 8, 9, 4, 3, 40, 0, 10,
+ 0, 0, 0, 0, 0, 33, 33, 34, 36, 38,
+ 40, 39, 0, 43, 39, 0, 0, 0, 12, 0,
+ 0, 0, 0, 0, 0, 40, 0, 11, 39, 0,
+ 0, 5, 0, 0, 0, 29, 0, 0, 33, 33,
+ 33, 33, 0, 0, 12, 12, 0, 0, 0, 23,
+ 0, 0, 0, 0, 0, 0, 6, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 30, 31,
+ 0, 0, 0, 0, 0, 0, 0, 24, 25, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 32, 27,
+ 0, 0, 20, 0, 0, 26, 21, 0, 0, 0,
+ 19, 0, 0, 18, 28, 0, 0, 17, 22, 0,
+ 7, 37, 7, 15, 0, 14, 16, 0, 0, 0,
+ 13, 0
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 4, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 5, 6, 7, 8, 9, 1, 10, 11, 1,
+ 1, 12, 1, 13, 1, 1, 1, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 15, 16, 17,
+ 18, 19, 20, 1, 21, 21, 22, 23, 24, 25,
+ 21, 21, 26, 21, 21, 27, 21, 28, 21, 21,
+ 21, 21, 29, 21, 30, 21, 21, 21, 21, 21,
+ 1, 31, 1, 1, 32, 1, 21, 21, 33, 34,
+
+ 35, 36, 21, 21, 37, 21, 21, 38, 21, 39,
+ 21, 21, 21, 21, 40, 21, 41, 21, 21, 21,
+ 21, 21, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int32_t yy_meta[42] =
+ { 0,
+ 1, 2, 2, 3, 4, 3, 3, 1, 1, 3,
+ 3, 1, 3, 5, 1, 3, 1, 3, 6, 1,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 1, 5, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7
+ } ;
+
+static yyconst flex_int16_t yy_base[182] =
+ { 0,
+ 0, 40, 0, 41, 220, 48, 44, 54, 56, 65,
+ 220, 0, 535, 535, 216, 535, 81, 74, 535, 535,
+ 186, 535, 153, 145, 0, 85, 122, 87, 154, 155,
+ 195, 227, 535, 147, 91, 535, 535, 0, 147, 535,
+ 267, 34, 70, 74, 34, 122, 141, 535, 0, 535,
+ 112, 0, 98, 535, 0, 156, 307, 0, 143, 43,
+ 155, 151, 48, 101, 130, 348, 130, 535, 0, 121,
+ 197, 165, 172, 244, 182, 183, 191, 248, 273, 293,
+ 308, 314, 321, 246, 275, 216, 269, 299, 304, 327,
+ 307, 304, 312, 116, 107, 367, 535, 327, 334, 347,
+
+ 347, 350, 352, 349, 354, 359, 357, 363, 366, 365,
+ 369, 372, 369, 373, 374, 101, 86, 372, 535, 535,
+ 378, 380, 386, 382, 388, 388, 389, 535, 535, 393,
+ 394, 396, 392, 430, 400, 56, 47, 403, 535, 535,
+ 409, 414, 535, 409, 416, 535, 535, 416, 419, 441,
+ 535, 117, 0, 535, 535, 423, 426, 535, 535, 430,
+ 535, 535, 535, 535, 432, 457, 535, 459, 0, 25,
+ 535, 535, 476, 483, 489, 492, 499, 506, 513, 520,
+ 527
+ } ;
+
+static yyconst flex_int16_t yy_def[182] =
+ { 0,
+ 172, 1, 1, 1, 1, 1, 173, 173, 173, 173,
+ 172, 174, 172, 172, 175, 172, 174, 172, 172, 172,
+ 174, 172, 172, 174, 176, 174, 176, 172, 172, 172,
+ 177, 172, 172, 172, 172, 172, 172, 174, 175, 172,
+ 172, 172, 172, 172, 172, 172, 178, 172, 174, 172,
+ 174, 176, 172, 172, 27, 172, 172, 57, 174, 172,
+ 172, 172, 172, 172, 172, 177, 177, 172, 32, 172,
+ 172, 172, 172, 172, 172, 172, 172, 172, 178, 178,
+ 178, 178, 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+
+ 172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 179, 180, 172, 172, 172, 172, 172, 172, 172,
+ 172, 172, 172, 172, 172, 172, 172, 172, 181, 181,
+ 172, 0, 172, 172, 172, 172, 172, 172, 172, 172,
+ 172
+ } ;
+
+static yyconst flex_int16_t yy_nxt[577] =
+ { 0,
+ 12, 13, 14, 13, 13, 15, 16, 12, 17, 18,
+ 19, 12, 20, 12, 21, 22, 12, 23, 12, 24,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 26, 27, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 28, 28, 171, 28, 28, 34, 29, 29, 28,
+ 30, 153, 28, 35, 36, 29, 34, 73, 34, 31,
+ 152, 78, 37, 35, 36, 35, 87, 34, 73, 32,
+ 32, 37, 78, 92, 35, 46, 46, 87, 46, 47,
+ 32, 32, 41, 48, 92, 41, 53, 54, 56, 53,
+ 137, 56, 71, 72, 57, 71, 74, 75, 76, 53,
+
+ 54, 77, 53, 42, 43, 136, 44, 74, 75, 76,
+ 45, 117, 77, 83, 42, 43, 83, 44, 162, 162,
+ 116, 45, 38, 46, 46, 95, 46, 47, 93, 38,
+ 38, 48, 68, 38, 94, 55, 38, 84, 38, 93,
+ 38, 38, 80, 46, 86, 80, 81, 86, 84, 40,
+ 82, 70, 38, 55, 38, 58, 59, 56, 58, 65,
+ 56, 38, 38, 57, 51, 38, 96, 59, 38, 96,
+ 38, 50, 38, 38, 97, 90, 60, 61, 91, 62,
+ 63, 88, 89, 64, 38, 38, 90, 60, 61, 91,
+ 62, 63, 88, 89, 64, 66, 98, 68, 71, 72,
+
+ 49, 71, 66, 66, 101, 102, 66, 98, 66, 66,
+ 103, 66, 104, 66, 66, 101, 102, 86, 40, 172,
+ 86, 103, 30, 104, 172, 66, 66, 67, 67, 68,
+ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
+ 69, 67, 67, 67, 67, 67, 67, 69, 69, 69,
+ 69, 69, 69, 69, 69, 69, 69, 67, 69, 69,
+ 69, 69, 69, 69, 69, 69, 69, 69, 41, 99,
+ 105, 41, 100, 106, 80, 46, 86, 80, 81, 86,
+ 99, 105, 82, 100, 106, 172, 172, 172, 85, 42,
+ 43, 172, 44, 107, 80, 46, 45, 80, 81, 172,
+
+ 42, 43, 82, 44, 107, 172, 172, 45, 58, 80,
+ 46, 58, 80, 81, 172, 80, 46, 82, 80, 81,
+ 85, 172, 83, 82, 108, 83, 110, 109, 113, 60,
+ 61, 114, 62, 63, 115, 108, 64, 110, 109, 113,
+ 60, 61, 114, 62, 63, 115, 84, 64, 66, 111,
+ 68, 172, 118, 172, 112, 66, 66, 84, 119, 66,
+ 111, 66, 66, 118, 66, 112, 66, 66, 96, 119,
+ 120, 96, 121, 122, 123, 124, 97, 125, 66, 66,
+ 126, 120, 127, 121, 122, 123, 124, 128, 125, 129,
+ 130, 126, 131, 127, 132, 133, 134, 135, 128, 138,
+
+ 129, 130, 139, 131, 140, 132, 133, 134, 135, 141,
+ 138, 142, 143, 139, 144, 140, 145, 146, 147, 148,
+ 141, 149, 142, 143, 151, 144, 154, 145, 146, 147,
+ 148, 150, 149, 155, 150, 151, 156, 154, 157, 158,
+ 159, 160, 150, 85, 155, 150, 164, 156, 165, 157,
+ 158, 159, 160, 166, 85, 167, 172, 164, 168, 165,
+ 168, 168, 172, 168, 166, 172, 167, 172, 172, 172,
+ 172, 172, 172, 169, 172, 169, 33, 33, 33, 33,
+ 33, 33, 33, 38, 172, 172, 172, 38, 38, 39,
+ 39, 39, 39, 39, 39, 39, 52, 172, 52, 67,
+
+ 67, 67, 67, 67, 67, 67, 79, 79, 79, 79,
+ 79, 79, 79, 161, 161, 161, 172, 161, 161, 161,
+ 163, 172, 163, 172, 163, 163, 163, 170, 170, 170,
+ 170, 170, 172, 170, 11, 172, 172, 172, 172, 172,
+ 172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 172, 172, 172, 172, 172
+ } ;
+
+static yyconst flex_int16_t yy_chk[577] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 4, 170, 2, 4, 7, 2, 4, 6,
+ 6, 137, 6, 7, 7, 6, 8, 42, 9, 6,
+ 136, 45, 9, 8, 8, 9, 60, 10, 42, 6,
+ 6, 10, 45, 63, 10, 18, 18, 60, 18, 18,
+ 6, 6, 17, 18, 63, 17, 26, 26, 28, 26,
+ 117, 28, 35, 35, 28, 35, 43, 43, 44, 53,
+
+ 53, 44, 53, 17, 17, 116, 17, 43, 43, 44,
+ 17, 95, 44, 51, 17, 17, 51, 17, 152, 152,
+ 94, 17, 27, 46, 46, 70, 46, 46, 64, 27,
+ 27, 46, 67, 27, 65, 27, 27, 51, 27, 64,
+ 27, 27, 47, 47, 59, 47, 47, 59, 51, 39,
+ 47, 34, 27, 27, 29, 29, 59, 56, 29, 30,
+ 56, 29, 29, 56, 24, 29, 72, 29, 29, 72,
+ 29, 23, 29, 29, 72, 62, 29, 29, 62, 29,
+ 29, 61, 61, 29, 29, 29, 62, 29, 29, 62,
+ 29, 29, 61, 61, 29, 31, 73, 31, 71, 71,
+
+ 21, 71, 31, 31, 75, 76, 31, 73, 31, 31,
+ 76, 31, 77, 31, 31, 75, 76, 86, 15, 11,
+ 86, 76, 5, 77, 0, 31, 31, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 41, 74,
+ 78, 41, 74, 84, 79, 79, 85, 79, 79, 85,
+ 74, 78, 79, 74, 84, 0, 0, 0, 85, 41,
+ 41, 0, 41, 87, 80, 80, 41, 80, 80, 0,
+
+ 41, 41, 80, 41, 87, 0, 0, 41, 57, 81,
+ 81, 57, 81, 81, 0, 82, 82, 81, 82, 82,
+ 57, 0, 83, 82, 88, 83, 89, 88, 91, 57,
+ 57, 92, 57, 57, 93, 88, 57, 89, 88, 91,
+ 57, 57, 92, 57, 57, 93, 83, 57, 66, 90,
+ 66, 0, 98, 0, 90, 66, 66, 83, 99, 66,
+ 90, 66, 66, 98, 66, 90, 66, 66, 96, 99,
+ 100, 96, 101, 102, 103, 104, 96, 105, 66, 66,
+ 106, 100, 107, 101, 102, 103, 104, 108, 105, 109,
+ 110, 106, 111, 107, 112, 113, 114, 115, 108, 118,
+
+ 109, 110, 121, 111, 122, 112, 113, 114, 115, 123,
+ 118, 124, 125, 121, 126, 122, 127, 130, 131, 132,
+ 123, 133, 124, 125, 135, 126, 138, 127, 130, 131,
+ 132, 134, 133, 141, 134, 135, 142, 138, 144, 145,
+ 148, 149, 150, 134, 141, 150, 156, 142, 157, 144,
+ 145, 148, 149, 160, 150, 165, 0, 156, 166, 157,
+ 168, 166, 0, 168, 160, 0, 165, 0, 0, 0,
+ 0, 0, 0, 166, 0, 168, 173, 173, 173, 173,
+ 173, 173, 173, 174, 0, 0, 0, 174, 174, 175,
+ 175, 175, 175, 175, 175, 175, 176, 0, 176, 177,
+
+ 177, 177, 177, 177, 177, 177, 178, 178, 178, 178,
+ 178, 178, 178, 179, 179, 179, 0, 179, 179, 179,
+ 180, 0, 180, 0, 180, 180, 180, 181, 181, 181,
+ 181, 181, 0, 181, 172, 172, 172, 172, 172, 172,
+ 172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 172, 172, 172, 172, 172
+ } ;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+#line 1 "cmFortranLexer.in.l"
+#line 2 "cmFortranLexer.in.l"
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+/*-------------------------------------------------------------------------
+ Portions of this source have been derived from makedepf90 version 2.8.8,
+
+ Copyright (C) 2000--2006 Erik Edelmann <erik.edelmann@iki.fi>
+
+ The code was originally distributed under the GPL but permission
+ from the copyright holder has been obtained to distribute this
+ derived work under the CMake license.
+-------------------------------------------------------------------------*/
+
+/*
+
+This file must be translated to C and modified to build everywhere.
+
+Run flex like this:
+
+ flex -i --prefix=cmFortran_yy --header-file=cmFortranLexer.h -ocmFortranLexer.cxx cmFortranLexer.in.l
+
+Modify cmFortranLexer.cxx:
+ - remove TABs
+ - remove use of the 'register' storage class specifier
+ - remove "yyscanner" argument from these methods:
+ yy_fatal_error, cmFortran_yyalloc, cmFortran_yyrealloc, cmFortran_yyfree
+ - remove "yyscanner = NULL" from end of cmFortran_yylex_destroy
+ - remove all YY_BREAK lines occurring right after return statements
+ - change while ( 1 ) to for(;;)
+
+Modify cmFortranLexer.h:
+ - remove TABs
+ - remove the yy_init_globals function
+ - remove the block that includes unistd.h
+ - remove #line directives (avoids bogus warning on old Sun)
+
+*/
+
+#include "cmStandardLexer.h"
+
+#define cmFortranLexer_cxx
+#include "cmFortranParser.h" /* Interface to parser object. */
+
+/* Replace the lexer input function. */
+#undef YY_INPUT
+#define YY_INPUT(buf, result, max_size) \
+ { result = cmFortranParser_Input(yyextra, buf, max_size); }
+
+/* Include the set of tokens from the parser. */
+#include "cmFortranParserTokens.h"
+
+/*--------------------------------------------------------------------------*/
+
+
+#line 689 "cmFortranLexer.cxx"
+
+#define INITIAL 0
+#define free_fmt 1
+#define fixed_fmt 2
+#define str_sq 3
+#define str_dq 4
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+/* Holds the entire state of the reentrant scanner. */
+struct yyguts_t
+ {
+
+ /* User-defined. Not touched by flex. */
+ YY_EXTRA_TYPE yyextra_r;
+
+ /* The rest are the same as the globals declared in the non-reentrant scanner. */
+ FILE *yyin_r, *yyout_r;
+ size_t yy_buffer_stack_top; /**< index of top of stack. */
+ size_t yy_buffer_stack_max; /**< capacity of stack. */
+ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
+ char yy_hold_char;
+ yy_size_t yy_n_chars;
+ yy_size_t yyleng_r;
+ char *yy_c_buf_p;
+ int yy_init;
+ int yy_start;
+ int yy_did_buffer_switch_on_eof;
+ int yy_start_stack_ptr;
+ int yy_start_stack_depth;
+ int *yy_start_stack;
+ yy_state_type yy_last_accepting_state;
+ char* yy_last_accepting_cpos;
+
+ int yylineno_r;
+ int yy_flex_debug_r;
+
+ char *yytext_r;
+ int yy_more_flag;
+ int yy_more_len;
+
+ }; /* end struct yyguts_t */
+
+static int yy_init_globals (yyscan_t yyscanner );
+
+int cmFortran_yylex_init (yyscan_t* scanner);
+
+int cmFortran_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int cmFortran_yylex_destroy (yyscan_t yyscanner );
+
+int cmFortran_yyget_debug (yyscan_t yyscanner );
+
+void cmFortran_yyset_debug (int debug_flag ,yyscan_t yyscanner );
+
+YY_EXTRA_TYPE cmFortran_yyget_extra (yyscan_t yyscanner );
+
+void cmFortran_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+
+FILE *cmFortran_yyget_in (yyscan_t yyscanner );
+
+void cmFortran_yyset_in (FILE * in_str ,yyscan_t yyscanner );
+
+FILE *cmFortran_yyget_out (yyscan_t yyscanner );
+
+void cmFortran_yyset_out (FILE * out_str ,yyscan_t yyscanner );
+
+yy_size_t cmFortran_yyget_leng (yyscan_t yyscanner );
+
+char *cmFortran_yyget_text (yyscan_t yyscanner );
+
+int cmFortran_yyget_lineno (yyscan_t yyscanner );
+
+void cmFortran_yyset_lineno (int line_number ,yyscan_t yyscanner );
+
+int cmFortran_yyget_column (yyscan_t yyscanner );
+
+void cmFortran_yyset_column (int column_no ,yyscan_t yyscanner );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int cmFortran_yywrap (yyscan_t yyscanner );
+#else
+extern int cmFortran_yywrap (yyscan_t yyscanner );
+#endif
+#endif
+
+ static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner);
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (yyscan_t yyscanner );
+#else
+static int input (yyscan_t yyscanner );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
+#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ size_t n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(yyin); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int cmFortran_yylex (yyscan_t yyscanner);
+
+#define YY_DECL int cmFortran_yylex (yyscan_t yyscanner)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ if ( yyleng > 0 ) \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \
+ (yytext[yyleng - 1] == '\n'); \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ yy_state_type yy_current_state;
+ char *yy_cp, *yy_bp;
+ int yy_act;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if ( !yyg->yy_init )
+ {
+ yyg->yy_init = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! yyg->yy_start )
+ yyg->yy_start = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ cmFortran_yyensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ cmFortran_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ }
+
+ cmFortran_yy_load_buffer_state(yyscanner );
+ }
+
+ {
+#line 72 "cmFortranLexer.in.l"
+
+
+#line 956 "cmFortranLexer.cxx"
+
+ for(;;) /* loops until end-of-file is reached */
+ {
+ yy_cp = yyg->yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yyg->yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yyg->yy_start;
+ yy_current_state += YY_AT_BOL();
+yy_match:
+ do
+ {
+ YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
+ if ( yy_accept[yy_current_state] )
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 173 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 535 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = yyg->yy_hold_char;
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 74 "cmFortranLexer.in.l"
+{
+ cmFortranParser_StringStart(yyextra);
+ cmFortranParser_SetOldStartcond(yyextra, YY_START);
+ BEGIN(str_dq);
+}
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 80 "cmFortranLexer.in.l"
+{
+ cmFortranParser_StringStart(yyextra);
+ cmFortranParser_SetOldStartcond(yyextra, YY_START);
+ BEGIN(str_sq);
+}
+ YY_BREAK
+case 3:
+#line 87 "cmFortranLexer.in.l"
+case 4:
+YY_RULE_SETUP
+#line 87 "cmFortranLexer.in.l"
+{
+ BEGIN(cmFortranParser_GetOldStartcond(yyextra) );
+ yylvalp->string = strdup(cmFortranParser_StringEnd(yyextra));
+ return STRING;
+}
+case 5:
+/* rule 5 can match eol */
+#line 94 "cmFortranLexer.in.l"
+case 6:
+/* rule 6 can match eol */
+YY_RULE_SETUP
+#line 94 "cmFortranLexer.in.l"
+/* Ignore (continued strings, free fmt) */
+ YY_BREAK
+case 7:
+/* rule 7 can match eol */
+YY_RULE_SETUP
+#line 96 "cmFortranLexer.in.l"
+{
+ if (cmFortranParser_GetOldStartcond(yyextra) == fixed_fmt)
+ ; /* Ignore (cont. strings, fixed fmt) */
+ else
+ {
+ unput(yytext[strlen(yytext)-1]);
+ }
+}
+ YY_BREAK
+case 8:
+/* rule 8 can match eol */
+YY_RULE_SETUP
+#line 106 "cmFortranLexer.in.l"
+{
+ unput ('\n');
+ BEGIN(INITIAL);
+ return UNTERMINATED_STRING;
+}
+case 9:
+YY_RULE_SETUP
+#line 112 "cmFortranLexer.in.l"
+{
+ cmFortranParser_StringAppend(yyextra, yytext[0]);
+}
+ YY_BREAK
+case 10:
+/* rule 10 can match eol */
+YY_RULE_SETUP
+#line 116 "cmFortranLexer.in.l"
+{ return EOSTMT; } /* Treat comments like */
+case 11:
+/* rule 11 can match eol */
+YY_RULE_SETUP
+#line 117 "cmFortranLexer.in.l"
+{ return EOSTMT; } /* empty lines */
+case 12:
+YY_RULE_SETUP
+#line 119 "cmFortranLexer.in.l"
+{ return CPP_LINE_DIRECTIVE; }
+case 13:
+/* rule 13 can match eol */
+YY_RULE_SETUP
+#line 120 "cmFortranLexer.in.l"
+{
+ yytext[yyleng-1] = 0;
+ yylvalp->string = strdup(strchr(yytext, '<')+1);
+ return CPP_INCLUDE_ANGLE;
+}
+case 14:
+YY_RULE_SETUP
+#line 125 "cmFortranLexer.in.l"
+{ return CPP_INCLUDE; }
+case 15:
+YY_RULE_SETUP
+#line 126 "cmFortranLexer.in.l"
+{ return F90PPR_INCLUDE; }
+case 16:
+YY_RULE_SETUP
+#line 127 "cmFortranLexer.in.l"
+{ return COCO_INCLUDE; }
+case 17:
+YY_RULE_SETUP
+#line 129 "cmFortranLexer.in.l"
+{ return CPP_DEFINE; }
+case 18:
+YY_RULE_SETUP
+#line 130 "cmFortranLexer.in.l"
+{ return F90PPR_DEFINE; }
+case 19:
+YY_RULE_SETUP
+#line 132 "cmFortranLexer.in.l"
+{ return CPP_UNDEF; }
+case 20:
+YY_RULE_SETUP
+#line 133 "cmFortranLexer.in.l"
+{ return F90PPR_UNDEF; }
+case 21:
+YY_RULE_SETUP
+#line 135 "cmFortranLexer.in.l"
+{ return CPP_IFDEF; }
+case 22:
+YY_RULE_SETUP
+#line 136 "cmFortranLexer.in.l"
+{ return CPP_IFNDEF; }
+case 23:
+YY_RULE_SETUP
+#line 137 "cmFortranLexer.in.l"
+{ return CPP_IF; }
+case 24:
+YY_RULE_SETUP
+#line 138 "cmFortranLexer.in.l"
+{ return CPP_ELIF; }
+case 25:
+YY_RULE_SETUP
+#line 139 "cmFortranLexer.in.l"
+{ return CPP_ELSE; }
+case 26:
+YY_RULE_SETUP
+#line 140 "cmFortranLexer.in.l"
+{ return CPP_ENDIF; }
+case 27:
+YY_RULE_SETUP
+#line 142 "cmFortranLexer.in.l"
+{ return F90PPR_IFDEF; }
+case 28:
+YY_RULE_SETUP
+#line 143 "cmFortranLexer.in.l"
+{ return F90PPR_IFNDEF; }
+case 29:
+YY_RULE_SETUP
+#line 144 "cmFortranLexer.in.l"
+{ return F90PPR_IF; }
+case 30:
+YY_RULE_SETUP
+#line 145 "cmFortranLexer.in.l"
+{ return F90PPR_ELIF; }
+case 31:
+YY_RULE_SETUP
+#line 146 "cmFortranLexer.in.l"
+{ return F90PPR_ELSE; }
+case 32:
+YY_RULE_SETUP
+#line 147 "cmFortranLexer.in.l"
+{ return F90PPR_ENDIF; }
+/* Line continuations, possible involving comments. */
+case 33:
+/* rule 33 can match eol */
+YY_RULE_SETUP
+#line 150 "cmFortranLexer.in.l"
+
+ YY_BREAK
+case 34:
+/* rule 34 can match eol */
+YY_RULE_SETUP
+#line 151 "cmFortranLexer.in.l"
+
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 153 "cmFortranLexer.in.l"
+{ return COMMA; }
+case 36:
+YY_RULE_SETUP
+#line 155 "cmFortranLexer.in.l"
+{ return DCOLON; }
+case 37:
+/* rule 37 can match eol */
+YY_RULE_SETUP
+#line 157 "cmFortranLexer.in.l"
+{ return GARBAGE; }
+case 38:
+YY_RULE_SETUP
+#line 159 "cmFortranLexer.in.l"
+{ return ASSIGNMENT_OP; }
+case 39:
+YY_RULE_SETUP
+#line 161 "cmFortranLexer.in.l"
+{
+ yylvalp->string = strdup(yytext);
+ return WORD;
+}
+case 40:
+YY_RULE_SETUP
+#line 166 "cmFortranLexer.in.l"
+{ return GARBAGE; }
+case 41:
+/* rule 41 can match eol */
+YY_RULE_SETUP
+#line 168 "cmFortranLexer.in.l"
+{ return EOSTMT; }
+case 42:
+YY_RULE_SETUP
+#line 171 "cmFortranLexer.in.l"
+/* Ignore */
+ YY_BREAK
+case 43:
+/* rule 43 can match eol */
+YY_RULE_SETUP
+#line 172 "cmFortranLexer.in.l"
+/* Ignore line-endings preceeded by \ */
+ YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 174 "cmFortranLexer.in.l"
+{ return *yytext; }
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(free_fmt):
+case YY_STATE_EOF(fixed_fmt):
+case YY_STATE_EOF(str_sq):
+case YY_STATE_EOF(str_dq):
+#line 176 "cmFortranLexer.in.l"
+{
+ if(!cmFortranParser_FilePop(yyextra) )
+ {
+ return YY_NULL;
+ }
+}
+ YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 183 "cmFortranLexer.in.l"
+ECHO;
+ YY_BREAK
+#line 1291 "cmFortranLexer.cxx"
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yyg->yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * cmFortran_yylex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner);
+
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++yyg->yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yyg->yy_c_buf_p;
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( yyscanner ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yyg->yy_did_buffer_switch_on_eof = 0;
+
+ if ( cmFortran_yywrap(yyscanner ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! yyg->yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yyg->yy_c_buf_p =
+ yyg->yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ yy_cp = yyg->yy_c_buf_p;
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yyg->yy_c_buf_p =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ yy_cp = yyg->yy_c_buf_p;
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of user's declarations */
+} /* end of cmFortran_yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ char *source = yyg->yytext_ptr;
+ int number_to_move, i;
+ int ret_val;
+
+ if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;
+
+ else
+ {
+ yy_size_t num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
+
+ int yy_c_buf_p_offset =
+ (int) (yyg->yy_c_buf_p - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ yy_size_t new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ cmFortran_yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ yyg->yy_n_chars, num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ if ( yyg->yy_n_chars == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ cmFortran_yyrestart(yyin ,yyscanner);
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) cmFortran_yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ }
+
+ yyg->yy_n_chars += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
+{
+ yy_state_type yy_current_state;
+ char *yy_cp;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ yy_current_state = yyg->yy_start;
+ yy_current_state += YY_AT_BOL();
+
+ for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
+ {
+ YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 173 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner)
+{
+ int yy_is_jam;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
+ char *yy_cp = yyg->yy_c_buf_p;
+
+ YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 173 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 172);
+
+ (void)yyg;
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+ static void yyunput (int c, char * yy_bp , yyscan_t yyscanner)
+{
+ char *yy_cp;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ yy_cp = yyg->yy_c_buf_p;
+
+ /* undo effects of setting up yytext */
+ *yy_cp = yyg->yy_hold_char;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ yy_size_t number_to_move = yyg->yy_n_chars + 2;
+ char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+ char *source =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+ while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+ yyg->yytext_ptr = yy_bp;
+ yyg->yy_hold_char = *yy_cp;
+ yyg->yy_c_buf_p = yy_cp;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (yyscan_t yyscanner)
+#else
+ static int input (yyscan_t yyscanner)
+#endif
+
+{
+ int c;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+
+ if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+ /* This was really a NUL. */
+ *yyg->yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ yy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
+ ++yyg->yy_c_buf_p;
+
+ switch ( yy_get_next_buffer( yyscanner ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ cmFortran_yyrestart(yyin ,yyscanner);
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( cmFortran_yywrap(yyscanner ) )
+ return EOF;
+
+ if ( ! yyg->yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput(yyscanner);
+#else
+ return input(yyscanner);
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yyg->yy_c_buf_p = yyg->yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */
+ *yyg->yy_c_buf_p = '\0'; /* preserve yytext */
+ yyg->yy_hold_char = *++yyg->yy_c_buf_p;
+
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n');
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * @param yyscanner The scanner object.
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void cmFortran_yyrestart (FILE * input_file , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if ( ! YY_CURRENT_BUFFER ){
+ cmFortran_yyensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ cmFortran_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ }
+
+ cmFortran_yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
+ cmFortran_yy_load_buffer_state(yyscanner );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * @param yyscanner The scanner object.
+ */
+ void cmFortran_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * cmFortran_yypop_buffer_state();
+ * cmFortran_yypush_buffer_state(new_buffer);
+ */
+ cmFortran_yyensure_buffer_stack (yyscanner);
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ cmFortran_yy_load_buffer_state(yyscanner );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (cmFortran_yywrap()) processing, but the only time this flag
+ * is looked at is after cmFortran_yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+static void cmFortran_yy_load_buffer_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ yyg->yy_hold_char = *yyg->yy_c_buf_p;
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * @param yyscanner The scanner object.
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE cmFortran_yy_create_buffer (FILE * file, int size , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) cmFortran_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in cmFortran_yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) cmFortran_yyalloc(b->yy_buf_size + 2 ,yyscanner );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in cmFortran_yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ cmFortran_yy_init_buffer(b,file ,yyscanner);
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with cmFortran_yy_create_buffer()
+ * @param yyscanner The scanner object.
+ */
+ void cmFortran_yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ cmFortran_yyfree((void *) b->yy_ch_buf ,yyscanner );
+
+ cmFortran_yyfree((void *) b ,yyscanner );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a cmFortran_yyrestart() or at EOF.
+ */
+ static void cmFortran_yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
+
+{
+ int oerrno = errno;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ cmFortran_yy_flush_buffer(b ,yyscanner);
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then cmFortran_yy_init_buffer was _probably_
+ * called from cmFortran_yyrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * @param yyscanner The scanner object.
+ */
+ void cmFortran_yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ cmFortran_yy_load_buffer_state(yyscanner );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ * @param yyscanner The scanner object.
+ */
+void cmFortran_yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (new_buffer == NULL)
+ return;
+
+ cmFortran_yyensure_buffer_stack(yyscanner);
+
+ /* This block is copied from cmFortran_yy_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ yyg->yy_buffer_stack_top++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from cmFortran_yy_switch_to_buffer. */
+ cmFortran_yy_load_buffer_state(yyscanner );
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ * @param yyscanner The scanner object.
+ */
+void cmFortran_yypop_buffer_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ cmFortran_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if (yyg->yy_buffer_stack_top > 0)
+ --yyg->yy_buffer_stack_top;
+
+ if (YY_CURRENT_BUFFER) {
+ cmFortran_yy_load_buffer_state(yyscanner );
+ yyg->yy_did_buffer_switch_on_eof = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void cmFortran_yyensure_buffer_stack (yyscan_t yyscanner)
+{
+ yy_size_t num_to_alloc;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (!yyg->yy_buffer_stack) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)cmFortran_yyalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ , yyscanner);
+ if ( ! yyg->yy_buffer_stack )
+ YY_FATAL_ERROR( "out of dynamic memory in cmFortran_yyensure_buffer_stack()" );
+
+ memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ yyg->yy_buffer_stack_max = num_to_alloc;
+ yyg->yy_buffer_stack_top = 0;
+ return;
+ }
+
+ if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)cmFortran_yyrealloc
+ (yyg->yy_buffer_stack,
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ , yyscanner);
+ if ( ! yyg->yy_buffer_stack )
+ YY_FATAL_ERROR( "out of dynamic memory in cmFortran_yyensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
+ yyg->yy_buffer_stack_max = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE cmFortran_yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) cmFortran_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in cmFortran_yy_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ cmFortran_yy_switch_to_buffer(b ,yyscanner );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to cmFortran_yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * cmFortran_yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE cmFortran_yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
+{
+
+ return cmFortran_yy_scan_bytes(yystr,strlen(yystr) ,yyscanner);
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to cmFortran_yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE cmFortran_yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ yy_size_t i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = _yybytes_len + 2;
+ buf = (char *) cmFortran_yyalloc(n ,yyscanner );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in cmFortran_yy_scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = cmFortran_yy_scan_buffer(buf,n ,yyscanner);
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in cmFortran_yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg , yyscan_t)
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ yytext[yyleng] = yyg->yy_hold_char; \
+ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
+ yyg->yy_hold_char = *yyg->yy_c_buf_p; \
+ *yyg->yy_c_buf_p = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the user-defined data for this scanner.
+ * @param yyscanner The scanner object.
+ */
+YY_EXTRA_TYPE cmFortran_yyget_extra (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyextra;
+}
+
+/** Get the current line number.
+ * @param yyscanner The scanner object.
+ */
+int cmFortran_yyget_lineno (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (! YY_CURRENT_BUFFER)
+ return 0;
+
+ return yylineno;
+}
+
+/** Get the current column number.
+ * @param yyscanner The scanner object.
+ */
+int cmFortran_yyget_column (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (! YY_CURRENT_BUFFER)
+ return 0;
+
+ return yycolumn;
+}
+
+/** Get the input stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *cmFortran_yyget_in (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyin;
+}
+
+/** Get the output stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *cmFortran_yyget_out (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyout;
+}
+
+/** Get the length of the current token.
+ * @param yyscanner The scanner object.
+ */
+yy_size_t cmFortran_yyget_leng (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyleng;
+}
+
+/** Get the current token.
+ * @param yyscanner The scanner object.
+ */
+
+char *cmFortran_yyget_text (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yytext;
+}
+
+/** Set the user-defined data. This data is never touched by the scanner.
+ * @param user_defined The data to be associated with this scanner.
+ * @param yyscanner The scanner object.
+ */
+void cmFortran_yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyextra = user_defined ;
+}
+
+/** Set the current line number.
+ * @param line_number The line number to set.
+ * @param yyscanner The scanner object.
+ */
+void cmFortran_yyset_lineno (int line_number , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* lineno is only valid if an input buffer exists. */
+ if (! YY_CURRENT_BUFFER )
+ YY_FATAL_ERROR( "cmFortran_yyset_lineno called with no buffer" );
+
+ yylineno = line_number;
+}
+
+/** Set the current column.
+ * @param column_no The column number to set.
+ * @param yyscanner The scanner object.
+ */
+void cmFortran_yyset_column (int column_no , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* column is only valid if an input buffer exists. */
+ if (! YY_CURRENT_BUFFER )
+ YY_FATAL_ERROR( "cmFortran_yyset_column called with no buffer" );
+
+ yycolumn = column_no;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ * @param yyscanner The scanner object.
+ * @see cmFortran_yy_switch_to_buffer
+ */
+void cmFortran_yyset_in (FILE * in_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyin = in_str ;
+}
+
+void cmFortran_yyset_out (FILE * out_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyout = out_str ;
+}
+
+int cmFortran_yyget_debug (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yy_flex_debug;
+}
+
+void cmFortran_yyset_debug (int bdebug , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yy_flex_debug = bdebug ;
+}
+
+/* Accessor methods for yylval and yylloc */
+
+/* User-visible API */
+
+/* cmFortran_yylex_init is special because it creates the scanner itself, so it is
+ * the ONLY reentrant function that doesn't take the scanner as the last argument.
+ * That's why we explicitly handle the declaration, instead of using our macros.
+ */
+
+int cmFortran_yylex_init(yyscan_t* ptr_yy_globals)
+
+{
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) cmFortran_yyalloc ( sizeof( struct yyguts_t ), NULL );
+
+ if (*ptr_yy_globals == NULL){
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+ return yy_init_globals ( *ptr_yy_globals );
+}
+
+/* cmFortran_yylex_init_extra has the same functionality as cmFortran_yylex_init, but follows the
+ * convention of taking the scanner as the last argument. Note however, that
+ * this is a *pointer* to a scanner, as it will be allocated by this call (and
+ * is the reason, too, why this function also must handle its own declaration).
+ * The user defined value in the first argument will be available to cmFortran_yyalloc in
+ * the yyextra field.
+ */
+
+int cmFortran_yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
+
+{
+ struct yyguts_t dummy_yyguts;
+
+ cmFortran_yyset_extra (yy_user_defined, &dummy_yyguts);
+
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) cmFortran_yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
+
+ if (*ptr_yy_globals == NULL){
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in
+ yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+ cmFortran_yyset_extra (yy_user_defined, *ptr_yy_globals);
+
+ return yy_init_globals ( *ptr_yy_globals );
+}
+
+static int yy_init_globals (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from cmFortran_yylex_destroy(), so don't allocate here.
+ */
+
+ yyg->yy_buffer_stack = 0;
+ yyg->yy_buffer_stack_top = 0;
+ yyg->yy_buffer_stack_max = 0;
+ yyg->yy_c_buf_p = (char *) 0;
+ yyg->yy_init = 0;
+ yyg->yy_start = 0;
+
+ yyg->yy_start_stack_ptr = 0;
+ yyg->yy_start_stack_depth = 0;
+ yyg->yy_start_stack = NULL;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ yyin = stdin;
+ yyout = stdout;
+#else
+ yyin = (FILE *) 0;
+ yyout = (FILE *) 0;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * cmFortran_yylex_init()
+ */
+ return 0;
+}
+
+/* cmFortran_yylex_destroy is for both reentrant and non-reentrant scanners. */
+int cmFortran_yylex_destroy (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ cmFortran_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ cmFortran_yypop_buffer_state(yyscanner);
+ }
+
+ /* Destroy the stack itself. */
+ cmFortran_yyfree(yyg->yy_buffer_stack ,yyscanner);
+ yyg->yy_buffer_stack = NULL;
+
+ /* Destroy the start condition stack. */
+ cmFortran_yyfree(yyg->yy_start_stack ,yyscanner );
+ yyg->yy_start_stack = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * cmFortran_yylex() is called, initialization will occur. */
+ yy_init_globals( yyscanner);
+
+ /* Destroy the main struct (reentrant only). */
+ cmFortran_yyfree ( yyscanner , yyscanner );
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
+{
+ int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
+{
+ int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *cmFortran_yyalloc (yy_size_t size , yyscan_t)
+{
+ return (void *) malloc( size );
+}
+
+void *cmFortran_yyrealloc (void * ptr, yy_size_t size , yyscan_t)
+{
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+}
+
+void cmFortran_yyfree (void * ptr , yyscan_t)
+{
+ free( (char *) ptr ); /* see cmFortran_yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 182 "cmFortranLexer.in.l"
+
+
+
+/*--------------------------------------------------------------------------*/
+YY_BUFFER_STATE cmFortranLexer_GetCurrentBuffer(yyscan_t yyscanner)
+{
+ /* Hack into the internal flex-generated scanner to get the buffer. */
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return YY_CURRENT_BUFFER;
+}
diff --git a/Source/cmFortranLexer.h b/Source/cmFortranLexer.h
new file mode 100644
index 000000000..b9ff0dc3c
--- /dev/null
+++ b/Source/cmFortranLexer.h
@@ -0,0 +1,352 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmFortran_yyHEADER_H
+#define cmFortran_yyHEADER_H 1
+#define cmFortran_yyIN_HEADER 1
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 39
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* An opaque pointer. */
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void* yyscan_t;
+#endif
+
+/* For convenience, these vars (plus the bison vars far below)
+ are macros in the reentrant scanner. */
+#define yyin yyg->yyin_r
+#define yyout yyg->yyout_r
+#define yyextra yyg->yyextra_r
+#define yyleng yyg->yyleng_r
+#define yytext yyg->yytext_r
+#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
+#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
+#define yy_flex_debug yyg->yy_flex_debug_r
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
+#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
+#endif
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ yy_size_t yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+void cmFortran_yyrestart (FILE *input_file ,yyscan_t yyscanner );
+void cmFortran_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmFortran_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
+void cmFortran_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void cmFortran_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void cmFortran_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+void cmFortran_yypop_buffer_state (yyscan_t yyscanner );
+
+YY_BUFFER_STATE cmFortran_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmFortran_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmFortran_yy_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner );
+
+void *cmFortran_yyalloc (yy_size_t ,yyscan_t yyscanner );
+void *cmFortran_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
+void cmFortran_yyfree (void * ,yyscan_t yyscanner );
+
+/* Begin user sect3 */
+
+#define cmFortran_yywrap(yyscanner) 1
+#define YY_SKIP_YYWRAP
+
+#define yytext_ptr yytext_r
+
+#ifdef YY_HEADER_EXPORT_START_CONDITIONS
+#define INITIAL 0
+#define free_fmt 1
+#define fixed_fmt 2
+#define str_sq 3
+#define str_dq 4
+
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+int cmFortran_yylex_init (yyscan_t* scanner);
+
+int cmFortran_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int cmFortran_yylex_destroy (yyscan_t yyscanner );
+
+int cmFortran_yyget_debug (yyscan_t yyscanner );
+
+void cmFortran_yyset_debug (int debug_flag ,yyscan_t yyscanner );
+
+YY_EXTRA_TYPE cmFortran_yyget_extra (yyscan_t yyscanner );
+
+void cmFortran_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+
+FILE *cmFortran_yyget_in (yyscan_t yyscanner );
+
+void cmFortran_yyset_in (FILE * in_str ,yyscan_t yyscanner );
+
+FILE *cmFortran_yyget_out (yyscan_t yyscanner );
+
+void cmFortran_yyset_out (FILE * out_str ,yyscan_t yyscanner );
+
+yy_size_t cmFortran_yyget_leng (yyscan_t yyscanner );
+
+char *cmFortran_yyget_text (yyscan_t yyscanner );
+
+int cmFortran_yyget_lineno (yyscan_t yyscanner );
+
+void cmFortran_yyset_lineno (int line_number ,yyscan_t yyscanner );
+
+int cmFortran_yyget_column (yyscan_t yyscanner );
+
+void cmFortran_yyset_column (int column_no ,yyscan_t yyscanner );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int cmFortran_yywrap (yyscan_t yyscanner );
+#else
+extern int cmFortran_yywrap (yyscan_t yyscanner );
+#endif
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
+#endif
+
+#ifndef YY_NO_INPUT
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
+#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int cmFortran_yylex (yyscan_t yyscanner);
+
+#define YY_DECL int cmFortran_yylex (yyscan_t yyscanner)
+#endif /* !YY_DECL */
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+#undef YY_NEW_FILE
+#undef YY_FLUSH_BUFFER
+#undef yy_set_bol
+#undef yy_new_buffer
+#undef yy_set_interactive
+#undef YY_DO_BEFORE_ACTION
+
+#ifdef YY_DECL_IS_OURS
+#undef YY_DECL_IS_OURS
+#undef YY_DECL
+#endif
+
+#undef cmFortran_yyIN_HEADER
+#endif /* cmFortran_yyHEADER_H */
diff --git a/Source/cmFortranLexer.in.l b/Source/cmFortranLexer.in.l
new file mode 100644
index 000000000..53984bb16
--- /dev/null
+++ b/Source/cmFortranLexer.in.l
@@ -0,0 +1,191 @@
+%{
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+/*-------------------------------------------------------------------------
+ Portions of this source have been derived from makedepf90 version 2.8.8,
+
+ Copyright (C) 2000--2006 Erik Edelmann <erik.edelmann@iki.fi>
+
+ The code was originally distributed under the GPL but permission
+ from the copyright holder has been obtained to distribute this
+ derived work under the CMake license.
+-------------------------------------------------------------------------*/
+
+/*
+
+This file must be translated to C and modified to build everywhere.
+
+Run flex like this:
+
+ flex -i --prefix=cmFortran_yy --header-file=cmFortranLexer.h -ocmFortranLexer.cxx cmFortranLexer.in.l
+
+Modify cmFortranLexer.cxx:
+ - remove TABs
+ - remove use of the 'register' storage class specifier
+ - remove "yyscanner" argument from these methods:
+ yy_fatal_error, cmFortran_yyalloc, cmFortran_yyrealloc, cmFortran_yyfree
+ - remove "yyscanner = NULL" from end of cmFortran_yylex_destroy
+ - remove all YY_BREAK lines occurring right after return statements
+ - change while ( 1 ) to for(;;)
+
+Modify cmFortranLexer.h:
+ - remove TABs
+ - remove the yy_init_globals function
+ - remove the block that includes unistd.h
+ - remove #line directives (avoids bogus warning on old Sun)
+
+*/
+
+#include "cmStandardLexer.h"
+
+#define cmFortranLexer_cxx
+#include "cmFortranParser.h" /* Interface to parser object. */
+
+/* Replace the lexer input function. */
+#undef YY_INPUT
+#define YY_INPUT(buf, result, max_size) \
+ { result = cmFortranParser_Input(yyextra, buf, max_size); }
+
+/* Include the set of tokens from the parser. */
+#include "cmFortranParserTokens.h"
+
+/*--------------------------------------------------------------------------*/
+%}
+
+
+%option reentrant
+%option noyywrap
+%pointer
+
+%s free_fmt fixed_fmt
+%x str_sq str_dq
+
+%%
+
+\" {
+ cmFortranParser_StringStart(yyextra);
+ cmFortranParser_SetOldStartcond(yyextra, YY_START);
+ BEGIN(str_dq);
+}
+
+' {
+ cmFortranParser_StringStart(yyextra);
+ cmFortranParser_SetOldStartcond(yyextra, YY_START);
+ BEGIN(str_sq);
+}
+
+<str_dq>\" |
+<str_sq>' {
+ BEGIN(cmFortranParser_GetOldStartcond(yyextra) );
+ yylvalp->string = strdup(cmFortranParser_StringEnd(yyextra));
+ return STRING;
+}
+
+<str_dq,str_sq>&[ \t]*\n |
+<str_dq,str_sq>&[ \t]*\n[ \t]*& /* Ignore (continued strings, free fmt) */
+
+<fixed_fmt,str_dq,str_sq>\n[ ]{5}[^ \t\n] {
+ if (cmFortranParser_GetOldStartcond(yyextra) == fixed_fmt)
+ ; /* Ignore (cont. strings, fixed fmt) */
+ else
+ {
+ unput(yytext[strlen(yytext)-1]);
+ }
+}
+
+
+<str_dq,str_sq>\n {
+ unput ('\n');
+ BEGIN(INITIAL);
+ return UNTERMINATED_STRING;
+}
+
+<str_sq,str_dq>. {
+ cmFortranParser_StringAppend(yyextra, yytext[0]);
+}
+
+!.*\n { return EOSTMT; } /* Treat comments like */
+<fixed_fmt>^[cC*dD].*\n { return EOSTMT; } /* empty lines */
+
+^[ \t]*#([ \t]*line)?[ \t]*[0-9]+[ \t]* { return CPP_LINE_DIRECTIVE; }
+^[ \t]*#[ \t]*include[ \t]*<[^>]+> {
+ yytext[yyleng-1] = 0;
+ yylvalp->string = strdup(strchr(yytext, '<')+1);
+ return CPP_INCLUDE_ANGLE;
+}
+^[ \t]*#[ \t]*include { return CPP_INCLUDE; }
+\$[ \t]*include { return F90PPR_INCLUDE; }
+\?\?[ \t]*include { return COCO_INCLUDE; }
+
+^[ \t]*#[ \t]*define { return CPP_DEFINE; }
+\$[ \t]*DEFINE { return F90PPR_DEFINE; }
+
+^[ \t]*#[ \t]*undef { return CPP_UNDEF; }
+\$[ \t]*UNDEF { return F90PPR_UNDEF; }
+
+^[ \t]*#[ \t]*ifdef { return CPP_IFDEF; }
+^[ \t]*#[ \t]*ifndef { return CPP_IFNDEF; }
+^[ \t]*#[ \t]*if { return CPP_IF; }
+^[ \t]*#[ \t]*elif { return CPP_ELIF; }
+^[ \t]*#[ \t]*else { return CPP_ELSE; }
+^[ \t]*#[ \t]*endif { return CPP_ENDIF; }
+
+$[ \t]*ifdef { return F90PPR_IFDEF; }
+$[ \t]*ifndef { return F90PPR_IFNDEF; }
+$[ \t]*if { return F90PPR_IF; }
+$[ \t]*elif { return F90PPR_ELIF; }
+$[ \t]*else { return F90PPR_ELSE; }
+$[ \t]*endif { return F90PPR_ENDIF; }
+
+ /* Line continuations, possible involving comments. */
+&([ \t\n]*|!.*)*
+&([ \t\n]*|!.*)*&
+
+, { return COMMA; }
+
+:: { return DCOLON; }
+
+<fixed_fmt>\n[ ]{5}[^ ] { return GARBAGE; }
+
+=|=> { return ASSIGNMENT_OP; }
+
+[a-zA-Z_][a-zA-Z_0-9]* {
+ yylvalp->string = strdup(yytext);
+ return WORD;
+}
+
+[^ \t\n\r;,!'"a-zA-Z=&]+ { return GARBAGE; }
+
+;|\n { return EOSTMT; }
+
+
+[ \t\r,] /* Ignore */
+\\[ \t]*\n /* Ignore line-endings preceeded by \ */
+
+. { return *yytext; }
+
+<<EOF>> {
+ if(!cmFortranParser_FilePop(yyextra) )
+ {
+ return YY_NULL;
+ }
+}
+
+%%
+
+/*--------------------------------------------------------------------------*/
+YY_BUFFER_STATE cmFortranLexer_GetCurrentBuffer(yyscan_t yyscanner)
+{
+ /* Hack into the internal flex-generated scanner to get the buffer. */
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return YY_CURRENT_BUFFER;
+}
diff --git a/Source/cmFortranParser.cxx b/Source/cmFortranParser.cxx
new file mode 100644
index 000000000..21a64434c
--- /dev/null
+++ b/Source/cmFortranParser.cxx
@@ -0,0 +1,1916 @@
+/* A Bison parser, made by GNU Bison 3.0.2. */
+
+/* Bison implementation for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Bison version. */
+#define YYBISON_VERSION "3.0.2"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 1
+
+/* Push parsers. */
+#define YYPUSH 0
+
+/* Pull parsers. */
+#define YYPULL 1
+
+
+/* Substitute the variable and function names. */
+#define yyparse cmFortran_yyparse
+#define yylex cmFortran_yylex
+#define yyerror cmFortran_yyerror
+#define yydebug cmFortran_yydebug
+#define yynerrs cmFortran_yynerrs
+
+
+/* Copy the first part of user declarations. */
+#line 1 "cmFortranParser.y" /* yacc.c:339 */
+
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+/*-------------------------------------------------------------------------
+ Portions of this source have been derived from makedepf90 version 2.8.8,
+
+ Copyright (C) 2000--2006 Erik Edelmann <erik.edelmann@iki.fi>
+
+ The code was originally distributed under the GPL but permission
+ from the copyright holder has been obtained to distribute this
+ derived work under the CMake license.
+-------------------------------------------------------------------------*/
+
+/*
+
+This file must be translated to C and modified to build everywhere.
+
+Run bison like this:
+
+ bison --yacc --name-prefix=cmFortran_yy
+ --defines=cmFortranParserTokens.h
+ -ocmFortranParser.cxx
+ cmFortranParser.y
+
+Modify cmFortranParser.cxx:
+ - "#if 0" out yyerrorlab block in range ["goto yyerrlab1", "yyerrlab1:"]
+*/
+
+/*-------------------------------------------------------------------------*/
+#define cmFortranParser_cxx
+#include "cmFortranParser.h" /* Interface to parser object. */
+#include "cmFortranParserTokens.h" /* Need YYSTYPE for YY_DECL. */
+
+#include <cmsys/String.h>
+
+/* Forward declare the lexer entry point. */
+YY_DECL;
+
+/* Helper function to forward error callback from parser. */
+static void cmFortran_yyerror(yyscan_t yyscanner, const char* message)
+{
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_Error(parser, message);
+}
+
+static bool cmFortranParserIsKeyword(const char* word,
+ const char* keyword)
+{
+ return cmsysString_strcasecmp(word, keyword) == 0;
+}
+
+/* Disable some warnings in the generated code. */
+#ifdef _MSC_VER
+# pragma warning (disable: 4102) /* Unused goto label. */
+# pragma warning (disable: 4065) /* Switch contains default but no case. */
+# pragma warning (disable: 4701) /* Local variable may not be initialized. */
+# pragma warning (disable: 4702) /* Unreachable code. */
+# pragma warning (disable: 4127) /* Conditional expression is constant. */
+# pragma warning (disable: 4244) /* Conversion to smaller type, data loss. */
+#endif
+
+#line 143 "cmFortranParser.cxx" /* yacc.c:339 */
+
+# ifndef YY_NULLPTR
+# if defined __cplusplus && 201103L <= __cplusplus
+# define YY_NULLPTR nullptr
+# else
+# define YY_NULLPTR 0
+# endif
+# endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 1
+#endif
+
+/* In a future release of Bison, this section will be replaced
+ by #include "cmFortranParserTokens.h". */
+#ifndef YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED
+# define YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED
+/* Debug traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int cmFortran_yydebug;
+#endif
+
+/* Token type. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ enum yytokentype
+ {
+ EOSTMT = 258,
+ ASSIGNMENT_OP = 259,
+ GARBAGE = 260,
+ CPP_LINE_DIRECTIVE = 261,
+ CPP_INCLUDE = 262,
+ F90PPR_INCLUDE = 263,
+ COCO_INCLUDE = 264,
+ F90PPR_DEFINE = 265,
+ CPP_DEFINE = 266,
+ F90PPR_UNDEF = 267,
+ CPP_UNDEF = 268,
+ CPP_IFDEF = 269,
+ CPP_IFNDEF = 270,
+ CPP_IF = 271,
+ CPP_ELSE = 272,
+ CPP_ELIF = 273,
+ CPP_ENDIF = 274,
+ F90PPR_IFDEF = 275,
+ F90PPR_IFNDEF = 276,
+ F90PPR_IF = 277,
+ F90PPR_ELSE = 278,
+ F90PPR_ELIF = 279,
+ F90PPR_ENDIF = 280,
+ COMMA = 281,
+ DCOLON = 282,
+ CPP_TOENDL = 283,
+ UNTERMINATED_STRING = 284,
+ STRING = 285,
+ WORD = 286,
+ CPP_INCLUDE_ANGLE = 287
+ };
+#endif
+/* Tokens. */
+#define EOSTMT 258
+#define ASSIGNMENT_OP 259
+#define GARBAGE 260
+#define CPP_LINE_DIRECTIVE 261
+#define CPP_INCLUDE 262
+#define F90PPR_INCLUDE 263
+#define COCO_INCLUDE 264
+#define F90PPR_DEFINE 265
+#define CPP_DEFINE 266
+#define F90PPR_UNDEF 267
+#define CPP_UNDEF 268
+#define CPP_IFDEF 269
+#define CPP_IFNDEF 270
+#define CPP_IF 271
+#define CPP_ELSE 272
+#define CPP_ELIF 273
+#define CPP_ENDIF 274
+#define F90PPR_IFDEF 275
+#define F90PPR_IFNDEF 276
+#define F90PPR_IF 277
+#define F90PPR_ELSE 278
+#define F90PPR_ELIF 279
+#define F90PPR_ENDIF 280
+#define COMMA 281
+#define DCOLON 282
+#define CPP_TOENDL 283
+#define UNTERMINATED_STRING 284
+#define STRING 285
+#define WORD 286
+#define CPP_INCLUDE_ANGLE 287
+
+/* Value type. */
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE YYSTYPE;
+union YYSTYPE
+{
+#line 81 "cmFortranParser.y" /* yacc.c:355 */
+
+ char* string;
+
+#line 251 "cmFortranParser.cxx" /* yacc.c:355 */
+};
+# define YYSTYPE_IS_TRIVIAL 1
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+
+int cmFortran_yyparse (yyscan_t yyscanner);
+
+#endif /* !YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED */
+
+/* Copy the second part of user declarations. */
+
+#line 265 "cmFortranParser.cxx" /* yacc.c:358 */
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#else
+typedef signed char yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif ! defined YYSIZE_T
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(Msgid) dgettext ("bison-runtime", Msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(Msgid) Msgid
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE
+# if (defined __GNUC__ \
+ && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \
+ || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
+# define YY_ATTRIBUTE(Spec) __attribute__(Spec)
+# else
+# define YY_ATTRIBUTE(Spec) /* empty */
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_PURE
+# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__))
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
+#endif
+
+#if !defined _Noreturn \
+ && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
+# if defined _MSC_VER && 1200 <= _MSC_VER
+# define _Noreturn __declspec (noreturn)
+# else
+# define _Noreturn YY_ATTRIBUTE ((__noreturn__))
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(E) ((void) (E))
+#else
+# define YYUSE(E) /* empty */
+#endif
+
+#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized. */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
+ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+ _Pragma ("GCC diagnostic pop")
+#else
+# define YY_INITIAL_VALUE(Value) Value
+#endif
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+ /* Use EXIT_SUCCESS as a witness for stdlib.h. */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's 'empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && ! defined EXIT_SUCCESS \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined EXIT_SUCCESS
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if ! defined free && ! defined EXIT_SUCCESS
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yytype_int16 yyss_alloc;
+ YYSTYPE yyvs_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAXIMUM)
+
+# define YYCOPY_NEEDED 1
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
+ Stack = &yyptr->Stack_alloc; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (0)
+
+#endif
+
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from SRC to DST. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(Dst, Src, Count) \
+ __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
+# else
+# define YYCOPY(Dst, Src, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (Dst)[yyi] = (Src)[yyi]; \
+ } \
+ while (0)
+# endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 2
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 290
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 33
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 16
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 54
+/* YYNSTATES -- Number of states. */
+#define YYNSTATES 101
+
+/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
+ by yylex, with out-of-bounds checking. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 287
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex, without out-of-bounds checking. */
+static const yytype_uint8 yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32
+};
+
+#if YYDEBUG
+ /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
+static const yytype_uint16 yyrline[] =
+{
+ 0, 104, 104, 104, 106, 106, 108, 114, 124, 154,
+ 165, 178, 189, 196, 203, 210, 216, 222, 228, 234,
+ 239, 244, 249, 254, 258, 259, 260, 265, 265, 265,
+ 266, 266, 267, 267, 268, 268, 269, 269, 270, 270,
+ 271, 271, 272, 272, 273, 273, 274, 274, 277, 278,
+ 279, 280, 281, 282, 283
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || 1
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "EOSTMT", "ASSIGNMENT_OP", "GARBAGE",
+ "CPP_LINE_DIRECTIVE", "CPP_INCLUDE", "F90PPR_INCLUDE", "COCO_INCLUDE",
+ "F90PPR_DEFINE", "CPP_DEFINE", "F90PPR_UNDEF", "CPP_UNDEF", "CPP_IFDEF",
+ "CPP_IFNDEF", "CPP_IF", "CPP_ELSE", "CPP_ELIF", "CPP_ENDIF",
+ "F90PPR_IFDEF", "F90PPR_IFNDEF", "F90PPR_IF", "F90PPR_ELSE",
+ "F90PPR_ELIF", "F90PPR_ENDIF", "COMMA", "DCOLON", "CPP_TOENDL",
+ "UNTERMINATED_STRING", "STRING", "WORD", "CPP_INCLUDE_ANGLE", "$accept",
+ "code", "stmt", "assignment_stmt", "keyword_stmt", "include", "define",
+ "undef", "ifdef", "ifndef", "if", "elif", "else", "endif", "other",
+ "misc_code", YY_NULLPTR
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[NUM] -- (External) token number corresponding to the
+ (internal) symbol number NUM (which must be that of a token). */
+static const yytype_uint16 yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287
+};
+# endif
+
+#define YYPACT_NINF -30
+
+#define yypact_value_is_default(Yystate) \
+ (!!((Yystate) == (-30)))
+
+#define YYTABLE_NINF -1
+
+#define yytable_value_is_error(Yytable_value) \
+ 0
+
+ /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+static const yytype_int16 yypact[] =
+{
+ -30, 41, -30, -30, -30, -30, -29, -30, -30, -30,
+ -30, -30, -30, -30, -30, -30, -30, -30, -30, -30,
+ -30, -30, -30, -30, -30, -30, 259, -30, -30, -30,
+ -30, -28, -23, -18, -16, -13, -30, -30, -30, -30,
+ 2, -30, -30, -30, -30, -12, -9, -30, -30, 64,
+ -30, -30, -30, -30, -30, 71, 77, 83, 112, -30,
+ -30, -30, -30, -30, -30, -30, -30, -30, 118, 124,
+ 130, -24, -30, 159, 165, -30, 171, 177, 206, 212,
+ 218, -30, -30, -30, -30, -30, -30, -30, -1, 224,
+ -30, -30, -30, -30, -30, -30, -30, -30, -30, 253,
+ -30
+};
+
+ /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+ Performed when YYTABLE does not specify something else to do. Zero
+ means the default is an error. */
+static const yytype_uint8 yydefact[] =
+{
+ 2, 0, 1, 26, 25, 46, 0, 27, 28, 29,
+ 31, 30, 33, 32, 34, 36, 38, 42, 40, 44,
+ 35, 37, 39, 43, 41, 45, 0, 46, 3, 5,
+ 4, 0, 0, 0, 0, 0, 46, 46, 46, 46,
+ 0, 46, 7, 46, 46, 0, 0, 46, 46, 0,
+ 46, 46, 46, 46, 46, 0, 0, 0, 0, 24,
+ 51, 50, 53, 52, 54, 49, 48, 47, 0, 0,
+ 0, 0, 46, 0, 0, 13, 0, 0, 0, 0,
+ 0, 19, 20, 21, 22, 12, 6, 23, 0, 0,
+ 11, 8, 14, 15, 16, 17, 18, 46, 9, 0,
+ 10
+};
+
+ /* YYPGOTO[NTERM-NUM]. */
+static const yytype_int8 yypgoto[] =
+{
+ -30, -30, -30, -30, -30, -30, -30, -30, -30, -30,
+ -30, -30, -30, -30, -27, -30
+};
+
+ /* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int8 yydefgoto[] =
+{
+ -1, 1, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, 67
+};
+
+ /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule whose
+ number is the opposite. If YYTABLE_NINF, syntax error. */
+static const yytype_uint8 yytable[] =
+{
+ 49, 41, 50, 88, 0, 59, 60, 61, 51, 55,
+ 56, 57, 58, 52, 68, 53, 69, 70, 54, 71,
+ 73, 74, 72, 76, 77, 78, 79, 80, 62, 63,
+ 97, 64, 65, 66, 0, 0, 0, 0, 0, 0,
+ 0, 2, 3, 0, 4, 89, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 75, 60, 61,
+ 99, 0, 26, 27, 81, 60, 61, 0, 0, 0,
+ 82, 60, 61, 0, 0, 0, 83, 60, 61, 0,
+ 62, 63, 0, 64, 65, 66, 0, 62, 63, 0,
+ 64, 65, 66, 62, 63, 0, 64, 65, 66, 62,
+ 63, 0, 64, 65, 66, 84, 60, 61, 0, 0,
+ 0, 85, 60, 61, 0, 0, 0, 86, 60, 61,
+ 0, 0, 0, 87, 60, 61, 0, 0, 62, 63,
+ 0, 64, 65, 66, 62, 63, 0, 64, 65, 66,
+ 62, 63, 0, 64, 65, 66, 62, 63, 0, 64,
+ 65, 66, 90, 60, 61, 0, 0, 0, 91, 60,
+ 61, 0, 0, 0, 92, 60, 61, 0, 0, 0,
+ 93, 60, 61, 0, 0, 62, 63, 0, 64, 65,
+ 66, 62, 63, 0, 64, 65, 66, 62, 63, 0,
+ 64, 65, 66, 62, 63, 0, 64, 65, 66, 94,
+ 60, 61, 0, 0, 0, 95, 60, 61, 0, 0,
+ 0, 96, 60, 61, 0, 0, 0, 98, 60, 61,
+ 0, 0, 62, 63, 0, 64, 65, 66, 62, 63,
+ 0, 64, 65, 66, 62, 63, 0, 64, 65, 66,
+ 62, 63, 0, 64, 65, 66, 100, 60, 61, 0,
+ 0, 0, 42, 43, 44, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 62,
+ 63, 0, 64, 65, 66, 45, 46, 0, 0, 47,
+ 48
+};
+
+static const yytype_int8 yycheck[] =
+{
+ 27, 30, 30, 27, -1, 3, 4, 5, 31, 36,
+ 37, 38, 39, 31, 41, 31, 43, 44, 31, 31,
+ 47, 48, 31, 50, 51, 52, 53, 54, 26, 27,
+ 31, 29, 30, 31, -1, -1, -1, -1, -1, -1,
+ -1, 0, 1, -1, 3, 72, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 3, 4, 5,
+ 97, -1, 31, 32, 3, 4, 5, -1, -1, -1,
+ 3, 4, 5, -1, -1, -1, 3, 4, 5, -1,
+ 26, 27, -1, 29, 30, 31, -1, 26, 27, -1,
+ 29, 30, 31, 26, 27, -1, 29, 30, 31, 26,
+ 27, -1, 29, 30, 31, 3, 4, 5, -1, -1,
+ -1, 3, 4, 5, -1, -1, -1, 3, 4, 5,
+ -1, -1, -1, 3, 4, 5, -1, -1, 26, 27,
+ -1, 29, 30, 31, 26, 27, -1, 29, 30, 31,
+ 26, 27, -1, 29, 30, 31, 26, 27, -1, 29,
+ 30, 31, 3, 4, 5, -1, -1, -1, 3, 4,
+ 5, -1, -1, -1, 3, 4, 5, -1, -1, -1,
+ 3, 4, 5, -1, -1, 26, 27, -1, 29, 30,
+ 31, 26, 27, -1, 29, 30, 31, 26, 27, -1,
+ 29, 30, 31, 26, 27, -1, 29, 30, 31, 3,
+ 4, 5, -1, -1, -1, 3, 4, 5, -1, -1,
+ -1, 3, 4, 5, -1, -1, -1, 3, 4, 5,
+ -1, -1, 26, 27, -1, 29, 30, 31, 26, 27,
+ -1, 29, 30, 31, 26, 27, -1, 29, 30, 31,
+ 26, 27, -1, 29, 30, 31, 3, 4, 5, -1,
+ -1, -1, 3, 4, 5, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 26,
+ 27, -1, 29, 30, 31, 26, 27, -1, -1, 30,
+ 31
+};
+
+ /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const yytype_uint8 yystos[] =
+{
+ 0, 34, 0, 1, 3, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 31, 32, 35, 36,
+ 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
+ 47, 30, 3, 4, 5, 26, 27, 30, 31, 47,
+ 30, 31, 31, 31, 31, 47, 47, 47, 47, 3,
+ 4, 5, 26, 27, 29, 30, 31, 48, 47, 47,
+ 47, 31, 31, 47, 47, 3, 47, 47, 47, 47,
+ 47, 3, 3, 3, 3, 3, 3, 3, 27, 47,
+ 3, 3, 3, 3, 3, 3, 3, 31, 3, 47,
+ 3
+};
+
+ /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const yytype_uint8 yyr1[] =
+{
+ 0, 33, 34, 34, 35, 35, 36, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 38, 38, 38,
+ 39, 39, 40, 40, 41, 41, 42, 42, 43, 43,
+ 44, 44, 45, 45, 46, 46, 47, 47, 48, 48,
+ 48, 48, 48, 48, 48
+};
+
+ /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 0, 2, 1, 1, 4, 2, 4, 5,
+ 7, 4, 4, 3, 4, 4, 4, 4, 4, 3,
+ 3, 3, 3, 4, 3, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 0, 2, 1, 1,
+ 1, 1, 1, 1, 1
+};
+
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ YYPOPSTACK (yylen); \
+ yystate = *yyssp; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (yyscanner, YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+while (0)
+
+/* Error token number */
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (0)
+
+/* This macro is provided for backward compatibility. */
+#ifndef YY_LOCATION_PRINT
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+#endif
+
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value, yyscanner); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (0)
+
+
+/*----------------------------------------.
+| Print this symbol's value on YYOUTPUT. |
+`----------------------------------------*/
+
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
+{
+ FILE *yyo = yyoutput;
+ YYUSE (yyo);
+ YYUSE (yyscanner);
+ if (!yyvaluep)
+ return;
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+ YYUSE (yytype);
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
+{
+ YYFPRINTF (yyoutput, "%s %s (",
+ yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
+
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yyscanner);
+ YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+static void
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (; yybottom <= yytop; yybottom++)
+ {
+ int yybot = *yybottom;
+ YYFPRINTF (stderr, " %d", yybot);
+ }
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+static void
+yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, yyscan_t yyscanner)
+{
+ unsigned long int yylno = yyrline[yyrule];
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ YYFPRINTF (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr,
+ yystos[yyssp[yyi + 1 - yynrhs]],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ , yyscanner);
+ YYFPRINTF (stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyssp, yyvsp, Rule, yyscanner); \
+} while (0)
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined __GLIBC__ && defined _STRING_H
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+static YYSIZE_T
+yystrlen (const char *yystr)
+{
+ YYSIZE_T yylen;
+ for (yylen = 0; yystr[yylen]; yylen++)
+ continue;
+ return yylen;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+{
+ char *yyd = yydest;
+ const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ YYSIZE_T yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return yystrlen (yystr);
+
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+ about the unexpected token YYTOKEN for the state stack whose top is
+ YYSSP.
+
+ Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
+ not large enough to hold the message. In that case, also set
+ *YYMSG_ALLOC to the required number of bytes. Return 2 if the
+ required number of bytes is too large to store. */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+ yytype_int16 *yyssp, int yytoken)
+{
+ YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
+ YYSIZE_T yysize = yysize0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ /* Internationalized format string. */
+ const char *yyformat = YY_NULLPTR;
+ /* Arguments of yyformat. */
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ /* Number of reported tokens (one for the "unexpected", one per
+ "expected"). */
+ int yycount = 0;
+
+ /* There are many possibilities here to consider:
+ - If this state is a consistent state with a default action, then
+ the only way this function was invoked is if the default action
+ is an error action. In that case, don't check for expected
+ tokens because there are none.
+ - The only way there can be no lookahead present (in yychar) is if
+ this state is a consistent state with a default action. Thus,
+ detecting the absence of a lookahead is sufficient to determine
+ that there is no unexpected or expected token to report. In that
+ case, just report a simple "syntax error".
+ - Don't assume there isn't a lookahead just because this state is a
+ consistent state with a default action. There might have been a
+ previous inconsistent state, consistent state with a non-default
+ action, or user semantic action that manipulated yychar.
+ - Of course, the expected token list depends on states to have
+ correct lookahead information, and it depends on the parser not
+ to perform extra reductions after fetching a lookahead from the
+ scanner and before detecting a syntax error. Thus, state merging
+ (from LALR or IELR) and default reductions corrupt the expected
+ token list. However, the list is correct for canonical LR with
+ one exception: it will still contain any token that will not be
+ accepted due to an error action in a later state.
+ */
+ if (yytoken != YYEMPTY)
+ {
+ int yyn = yypact[*yyssp];
+ yyarg[yycount++] = yytname[yytoken];
+ if (!yypact_value_is_default (yyn))
+ {
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. In other words, skip the first -YYN actions for
+ this state because they are default actions. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yyx;
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
+ && !yytable_value_is_error (yytable[yyx + yyn]))
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ {
+ YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
+ if (! (yysize <= yysize1
+ && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
+ }
+ }
+ }
+
+ switch (yycount)
+ {
+# define YYCASE_(N, S) \
+ case N: \
+ yyformat = S; \
+ break
+ YYCASE_(0, YY_("syntax error"));
+ YYCASE_(1, YY_("syntax error, unexpected %s"));
+ YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+ YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+ YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+ YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+# undef YYCASE_
+ }
+
+ {
+ YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
+ if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
+
+ if (*yymsg_alloc < yysize)
+ {
+ *yymsg_alloc = 2 * yysize;
+ if (! (yysize <= *yymsg_alloc
+ && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+ *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+ return 1;
+ }
+
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ {
+ char *yyp = *yymsg;
+ int yyi = 0;
+ while ((*yyp = *yyformat) != '\0')
+ if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyformat += 2;
+ }
+ else
+ {
+ yyp++;
+ yyformat++;
+ }
+ }
+ return 0;
+}
+#endif /* YYERROR_VERBOSE */
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, yyscan_t yyscanner)
+{
+ YYUSE (yyvaluep);
+ YYUSE (yyscanner);
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ YYUSE (yytype);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+}
+
+
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+int
+yyparse (yyscan_t yyscanner)
+{
+/* The lookahead symbol. */
+int yychar;
+
+
+/* The semantic value of the lookahead symbol. */
+/* Default value used for initialization, for pacifying older GCCs
+ or non-GCC compilers. */
+YY_INITIAL_VALUE (static YYSTYPE yyval_default;)
+YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
+
+ /* Number of syntax errors so far. */
+ int yynerrs;
+
+ int yystate;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+
+ /* The stacks and their tools:
+ 'yyss': related to states.
+ 'yyvs': related to semantic values.
+
+ Refer to the stacks through separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs;
+ YYSTYPE *yyvsp;
+
+ YYSIZE_T yystacksize;
+
+ int yyn;
+ int yyresult;
+ /* Lookahead token as an internal (translated) token number. */
+ int yytoken = 0;
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ yyssp = yyss = yyssa;
+ yyvsp = yyvs = yyvsa;
+ yystacksize = YYINITDEPTH;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ yytype_int16 *yyss1 = yyss;
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow (YY_("memory exhausted"),
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+ &yystacksize);
+
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyexhaustedlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yytype_int16 *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyexhaustedlab;
+ YYSTACK_RELOCATE (yyss_alloc, yyss);
+ YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ if (yystate == YYFINAL)
+ YYACCEPT;
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+ /* Do appropriate processing given the current state. Read a
+ lookahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to lookahead token. */
+ yyn = yypact[yystate];
+ if (yypact_value_is_default (yyn))
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = yylex (&yylval, yyscanner);
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yytable_value_is_error (yyn))
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the lookahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+ /* Discard the shifted token. */
+ yychar = YYEMPTY;
+
+ yystate = yyn;
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ '$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 6:
+#line 109 "cmFortranParser.y" /* yacc.c:1646 */
+ {
+ free((yyvsp[-3].string));
+ }
+#line 1457 "cmFortranParser.cxx" /* yacc.c:1646 */
+ break;
+
+ case 7:
+#line 115 "cmFortranParser.y" /* yacc.c:1646 */
+ {
+ if (cmFortranParserIsKeyword((yyvsp[-1].string), "interface"))
+ {
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_SetInInterface(parser, true);
+ }
+ free((yyvsp[-1].string));
+ }
+#line 1471 "cmFortranParser.cxx" /* yacc.c:1646 */
+ break;
+
+ case 8:
+#line 125 "cmFortranParser.y" /* yacc.c:1646 */
+ {
+ if (cmFortranParserIsKeyword((yyvsp[-3].string), "use"))
+ {
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
+ }
+ else if (cmFortranParserIsKeyword((yyvsp[-3].string), "module"))
+ {
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleModule(parser, (yyvsp[-2].string));
+ }
+ else if (cmFortranParserIsKeyword((yyvsp[-3].string), "interface"))
+ {
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_SetInInterface(parser, true);
+ }
+ else if (cmFortranParserIsKeyword((yyvsp[-2].string), "interface") &&
+ cmFortranParserIsKeyword((yyvsp[-3].string), "end"))
+ {
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_SetInInterface(parser, false);
+ }
+ free((yyvsp[-3].string));
+ free((yyvsp[-2].string));
+ }
+#line 1505 "cmFortranParser.cxx" /* yacc.c:1646 */
+ break;
+
+ case 9:
+#line 155 "cmFortranParser.y" /* yacc.c:1646 */
+ {
+ if (cmFortranParserIsKeyword((yyvsp[-4].string), "use"))
+ {
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
+ }
+ free((yyvsp[-4].string));
+ free((yyvsp[-2].string));
+ }
+#line 1520 "cmFortranParser.cxx" /* yacc.c:1646 */
+ break;
+
+ case 10:
+#line 166 "cmFortranParser.y" /* yacc.c:1646 */
+ {
+ if (cmFortranParserIsKeyword((yyvsp[-6].string), "use") &&
+ cmFortranParserIsKeyword((yyvsp[-4].string), "non_intrinsic") )
+ {
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
+ }
+ free((yyvsp[-6].string));
+ free((yyvsp[-4].string));
+ free((yyvsp[-2].string));
+ }
+#line 1537 "cmFortranParser.cxx" /* yacc.c:1646 */
+ break;
+
+ case 11:
+#line 179 "cmFortranParser.y" /* yacc.c:1646 */
+ {
+ if (cmFortranParserIsKeyword((yyvsp[-3].string), "include"))
+ {
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
+ }
+ free((yyvsp[-3].string));
+ free((yyvsp[-2].string));
+ }
+#line 1552 "cmFortranParser.cxx" /* yacc.c:1646 */
+ break;
+
+ case 12:
+#line 190 "cmFortranParser.y" /* yacc.c:1646 */
+ {
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleLineDirective(parser, (yyvsp[-2].string));
+ free((yyvsp[-2].string));
+ }
+#line 1563 "cmFortranParser.cxx" /* yacc.c:1646 */
+ break;
+
+ case 13:
+#line 197 "cmFortranParser.y" /* yacc.c:1646 */
+ {
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
+ free((yyvsp[-2].string));
+ }
+#line 1574 "cmFortranParser.cxx" /* yacc.c:1646 */
+ break;
+
+ case 14:
+#line 204 "cmFortranParser.y" /* yacc.c:1646 */
+ {
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
+ free((yyvsp[-2].string));
+ }
+#line 1585 "cmFortranParser.cxx" /* yacc.c:1646 */
+ break;
+
+ case 15:
+#line 211 "cmFortranParser.y" /* yacc.c:1646 */
+ {
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleDefine(parser, (yyvsp[-2].string));
+ free((yyvsp[-2].string));
+ }
+#line 1595 "cmFortranParser.cxx" /* yacc.c:1646 */
+ break;
+
+ case 16:
+#line 217 "cmFortranParser.y" /* yacc.c:1646 */
+ {
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleUndef(parser, (yyvsp[-2].string));
+ free((yyvsp[-2].string));
+ }
+#line 1605 "cmFortranParser.cxx" /* yacc.c:1646 */
+ break;
+
+ case 17:
+#line 223 "cmFortranParser.y" /* yacc.c:1646 */
+ {
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleIfdef(parser, (yyvsp[-2].string));
+ free((yyvsp[-2].string));
+ }
+#line 1615 "cmFortranParser.cxx" /* yacc.c:1646 */
+ break;
+
+ case 18:
+#line 229 "cmFortranParser.y" /* yacc.c:1646 */
+ {
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleIfndef(parser, (yyvsp[-2].string));
+ free((yyvsp[-2].string));
+ }
+#line 1625 "cmFortranParser.cxx" /* yacc.c:1646 */
+ break;
+
+ case 19:
+#line 235 "cmFortranParser.y" /* yacc.c:1646 */
+ {
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleIf(parser);
+ }
+#line 1634 "cmFortranParser.cxx" /* yacc.c:1646 */
+ break;
+
+ case 20:
+#line 240 "cmFortranParser.y" /* yacc.c:1646 */
+ {
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleElif(parser);
+ }
+#line 1643 "cmFortranParser.cxx" /* yacc.c:1646 */
+ break;
+
+ case 21:
+#line 245 "cmFortranParser.y" /* yacc.c:1646 */
+ {
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleElse(parser);
+ }
+#line 1652 "cmFortranParser.cxx" /* yacc.c:1646 */
+ break;
+
+ case 22:
+#line 250 "cmFortranParser.y" /* yacc.c:1646 */
+ {
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleEndif(parser);
+ }
+#line 1661 "cmFortranParser.cxx" /* yacc.c:1646 */
+ break;
+
+ case 23:
+#line 255 "cmFortranParser.y" /* yacc.c:1646 */
+ {
+ free((yyvsp[-3].string));
+ }
+#line 1669 "cmFortranParser.cxx" /* yacc.c:1646 */
+ break;
+
+ case 48:
+#line 277 "cmFortranParser.y" /* yacc.c:1646 */
+ { free ((yyvsp[0].string)); }
+#line 1675 "cmFortranParser.cxx" /* yacc.c:1646 */
+ break;
+
+ case 49:
+#line 278 "cmFortranParser.y" /* yacc.c:1646 */
+ { free ((yyvsp[0].string)); }
+#line 1681 "cmFortranParser.cxx" /* yacc.c:1646 */
+ break;
+
+
+#line 1685 "cmFortranParser.cxx" /* yacc.c:1646 */
+ default: break;
+ }
+ /* User semantic actions sometimes alter yychar, and that requires
+ that yytoken be updated with the new translation. We take the
+ approach of translating immediately before every use of yytoken.
+ One alternative is translating here after every semantic action,
+ but that translation would be missed if the semantic action invokes
+ YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+ if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
+ incorrect destructor might then be invoked immediately. In the
+ case of YYERROR or YYBACKUP, subsequent parser actions might lead
+ to an incorrect destructor call or verbose syntax error message
+ before the lookahead is translated. */
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+
+ /* Now 'shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*--------------------------------------.
+| yyerrlab -- here on detecting error. |
+`--------------------------------------*/
+yyerrlab:
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
+
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if ! YYERROR_VERBOSE
+ yyerror (yyscanner, YY_("syntax error"));
+#else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+ yyssp, yytoken)
+ {
+ char const *yymsgp = YY_("syntax error");
+ int yysyntax_error_status;
+ yysyntax_error_status = YYSYNTAX_ERROR;
+ if (yysyntax_error_status == 0)
+ yymsgp = yymsg;
+ else if (yysyntax_error_status == 1)
+ {
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+ if (!yymsg)
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ yysyntax_error_status = 2;
+ }
+ else
+ {
+ yysyntax_error_status = YYSYNTAX_ERROR;
+ yymsgp = yymsg;
+ }
+ }
+ yyerror (yyscanner, yymsgp);
+ if (yysyntax_error_status == 2)
+ goto yyexhaustedlab;
+ }
+# undef YYSYNTAX_ERROR
+#endif
+ }
+
+
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval, yyscanner);
+ yychar = YYEMPTY;
+ }
+ }
+
+#if 0
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+ /* Pacify compilers like GCC when the user code never invokes
+ YYERROR and the label yyerrorlab therefore never appears in user
+ code. */
+ if (/*CONSTCOND*/ 0)
+ goto yyerrorlab;
+
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+#endif
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (!yypact_value_is_default (yyn))
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp, yyscanner);
+ YYPOPSTACK (1);
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#if !defined yyoverflow || YYERROR_VERBOSE
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (yyscanner, YY_("memory exhausted"));
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+ if (yychar != YYEMPTY)
+ {
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = YYTRANSLATE (yychar);
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval, yyscanner);
+ }
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp, yyscanner);
+ YYPOPSTACK (1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
+ return yyresult;
+}
+#line 286 "cmFortranParser.y" /* yacc.c:1906 */
+
+/* End of grammar */
diff --git a/Source/cmFortranParser.h b/Source/cmFortranParser.h
new file mode 100644
index 000000000..cdaf46b27
--- /dev/null
+++ b/Source/cmFortranParser.h
@@ -0,0 +1,177 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmFortranParser_h
+#define cmFortranParser_h
+
+#if !defined(cmFortranLexer_cxx) && !defined(cmFortranParser_cxx)
+# include "cmStandardIncludes.h"
+#endif
+
+#include <stddef.h> /* size_t */
+
+/* Forward declare parser object type. */
+typedef struct cmFortranParser_s cmFortranParser;
+
+/* Functions to enter/exit #include'd files in order. */
+bool cmFortranParser_FilePush(cmFortranParser* parser,
+ const char* fname);
+bool cmFortranParser_FilePop(cmFortranParser* parser);
+
+/* Callbacks for lexer. */
+int cmFortranParser_Input(cmFortranParser* parser,
+ char* buffer, size_t bufferSize);
+
+
+void cmFortranParser_StringStart(cmFortranParser* parser);
+const char* cmFortranParser_StringEnd(cmFortranParser* parser);
+void cmFortranParser_StringAppend(cmFortranParser* parser,
+ char c);
+
+void cmFortranParser_SetInInterface(cmFortranParser* parser,
+ bool is_in);
+bool cmFortranParser_GetInInterface(cmFortranParser* parser);
+
+
+void cmFortranParser_SetInPPFalseBranch(cmFortranParser* parser,
+ bool is_in);
+bool cmFortranParser_GetInPPFalseBranch(cmFortranParser* parser);
+
+
+void cmFortranParser_SetOldStartcond(cmFortranParser* parser,
+ int arg);
+int cmFortranParser_GetOldStartcond(cmFortranParser* parser);
+
+/* Callbacks for parser. */
+void cmFortranParser_Error(cmFortranParser* parser,
+ const char* message);
+void cmFortranParser_RuleUse(cmFortranParser* parser,
+ const char* name);
+void cmFortranParser_RuleLineDirective(cmFortranParser* parser,
+ const char* filename);
+void cmFortranParser_RuleInclude(cmFortranParser* parser,
+ const char* name);
+void cmFortranParser_RuleModule(cmFortranParser* parser,
+ const char* name);
+void cmFortranParser_RuleDefine(cmFortranParser* parser,
+ const char* name);
+void cmFortranParser_RuleUndef(cmFortranParser* parser,
+ const char* name);
+void cmFortranParser_RuleIfdef(cmFortranParser* parser,
+ const char* name);
+void cmFortranParser_RuleIfndef(cmFortranParser* parser,
+ const char* name);
+void cmFortranParser_RuleIf(cmFortranParser* parser);
+void cmFortranParser_RuleElif(cmFortranParser* parser);
+void cmFortranParser_RuleElse(cmFortranParser* parser);
+void cmFortranParser_RuleEndif(cmFortranParser* parser);
+
+/* Define the parser stack element type. */
+typedef union cmFortran_yystype_u cmFortran_yystype;
+union cmFortran_yystype_u
+{
+ char* string;
+};
+
+/* Setup the proper yylex interface. */
+#define YY_EXTRA_TYPE cmFortranParser*
+#define YY_DECL \
+int cmFortran_yylex(YYSTYPE* yylvalp, yyscan_t yyscanner)
+#define YYSTYPE cmFortran_yystype
+#define YYSTYPE_IS_DECLARED 1
+#if !defined(cmFortranLexer_cxx)
+# include "cmFortranLexer.h"
+#endif
+#if !defined(cmFortranLexer_cxx)
+#if !defined(cmFortranParser_cxx)
+# undef YY_EXTRA_TYPE
+# undef YY_DECL
+# undef YYSTYPE
+# undef YYSTYPE_IS_DECLARED
+#endif
+#endif
+
+#if !defined(cmFortranLexer_cxx) && !defined(cmFortranParser_cxx)
+#include <stack>
+
+//----------------------------------------------------------------------------
+// Information about a single source file.
+class cmFortranSourceInfo
+{
+public:
+ // The name of the source file.
+ std::string Source;
+
+ // Set of provided and required modules.
+ std::set<std::string> Provides;
+ std::set<std::string> Requires;
+
+ // Set of files included in the translation unit.
+ std::set<std::string> Includes;
+};
+
+//----------------------------------------------------------------------------
+// Parser methods not included in generated interface.
+
+// Get the current buffer processed by the lexer.
+YY_BUFFER_STATE cmFortranLexer_GetCurrentBuffer(yyscan_t yyscanner);
+
+// The parser entry point.
+int cmFortran_yyparse(yyscan_t);
+
+//----------------------------------------------------------------------------
+// Define parser object internal structure.
+struct cmFortranFile
+{
+ cmFortranFile(FILE* file, YY_BUFFER_STATE buffer,
+ const std::string& dir):
+ File(file), Buffer(buffer), Directory(dir) {}
+ FILE* File;
+ YY_BUFFER_STATE Buffer;
+ std::string Directory;
+};
+
+struct cmFortranParser_s
+{
+ cmFortranParser_s(std::vector<std::string> const& includes,
+ std::set<std::string> const& defines,
+ cmFortranSourceInfo& info);
+ ~cmFortranParser_s();
+
+ bool FindIncludeFile(const char* dir, const char* includeName,
+ std::string& fileName);
+
+ // The include file search path.
+ std::vector<std::string> IncludePath;
+
+ // Lexical scanner instance.
+ yyscan_t Scanner;
+
+ // Stack of open files in the translation unit.
+ std::stack<cmFortranFile> FileStack;
+
+ // Buffer for string literals.
+ std::string TokenString;
+
+ // Flag for whether lexer is reading from inside an interface.
+ bool InInterface;
+
+ int OldStartcond;
+ std::set<std::string> PPDefinitions;
+ size_t InPPFalseBranch;
+ std::stack<bool> SkipToEnd;
+
+ // Information about the parsed source.
+ cmFortranSourceInfo& Info;
+};
+#endif
+
+#endif
diff --git a/Source/cmFortranParser.y b/Source/cmFortranParser.y
new file mode 100644
index 000000000..83f441aac
--- /dev/null
+++ b/Source/cmFortranParser.y
@@ -0,0 +1,287 @@
+%{
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+/*-------------------------------------------------------------------------
+ Portions of this source have been derived from makedepf90 version 2.8.8,
+
+ Copyright (C) 2000--2006 Erik Edelmann <erik.edelmann@iki.fi>
+
+ The code was originally distributed under the GPL but permission
+ from the copyright holder has been obtained to distribute this
+ derived work under the CMake license.
+-------------------------------------------------------------------------*/
+
+/*
+
+This file must be translated to C and modified to build everywhere.
+
+Run bison like this:
+
+ bison --yacc --name-prefix=cmFortran_yy
+ --defines=cmFortranParserTokens.h
+ -ocmFortranParser.cxx
+ cmFortranParser.y
+
+Modify cmFortranParser.cxx:
+ - "#if 0" out yyerrorlab block in range ["goto yyerrlab1", "yyerrlab1:"]
+*/
+
+/*-------------------------------------------------------------------------*/
+#define cmFortranParser_cxx
+#include "cmFortranParser.h" /* Interface to parser object. */
+#include "cmFortranParserTokens.h" /* Need YYSTYPE for YY_DECL. */
+
+#include <cmsys/String.h>
+
+/* Forward declare the lexer entry point. */
+YY_DECL;
+
+/* Helper function to forward error callback from parser. */
+static void cmFortran_yyerror(yyscan_t yyscanner, const char* message)
+{
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_Error(parser, message);
+}
+
+static bool cmFortranParserIsKeyword(const char* word,
+ const char* keyword)
+{
+ return cmsysString_strcasecmp(word, keyword) == 0;
+}
+
+/* Disable some warnings in the generated code. */
+#ifdef _MSC_VER
+# pragma warning (disable: 4102) /* Unused goto label. */
+# pragma warning (disable: 4065) /* Switch contains default but no case. */
+# pragma warning (disable: 4701) /* Local variable may not be initialized. */
+# pragma warning (disable: 4702) /* Unreachable code. */
+# pragma warning (disable: 4127) /* Conditional expression is constant. */
+# pragma warning (disable: 4244) /* Conversion to smaller type, data loss. */
+#endif
+%}
+
+/* Generate a reentrant parser object. */
+%define api.pure
+
+/* Configure the parser to use a lexer object. */
+%lex-param {yyscan_t yyscanner}
+%parse-param {yyscan_t yyscanner}
+
+%define parse.error verbose
+
+%union {
+ char* string;
+}
+
+/*-------------------------------------------------------------------------*/
+/* Tokens */
+%token EOSTMT ASSIGNMENT_OP GARBAGE
+%token CPP_LINE_DIRECTIVE
+%token CPP_INCLUDE F90PPR_INCLUDE COCO_INCLUDE
+%token F90PPR_DEFINE CPP_DEFINE F90PPR_UNDEF CPP_UNDEF
+%token CPP_IFDEF CPP_IFNDEF CPP_IF CPP_ELSE CPP_ELIF CPP_ENDIF
+%token F90PPR_IFDEF F90PPR_IFNDEF F90PPR_IF
+%token F90PPR_ELSE F90PPR_ELIF F90PPR_ENDIF
+%token COMMA DCOLON
+%token <string> CPP_TOENDL
+%token <number> UNTERMINATED_STRING
+%token <string> STRING WORD
+%token <string> CPP_INCLUDE_ANGLE
+
+/*-------------------------------------------------------------------------*/
+/* grammar */
+%%
+
+code: /* empty */ | code stmt;
+
+stmt: keyword_stmt | assignment_stmt;
+
+assignment_stmt: WORD ASSIGNMENT_OP other EOSTMT /* Ignore */
+ {
+ free($1);
+ }
+
+keyword_stmt:
+ WORD EOSTMT
+ {
+ if (cmFortranParserIsKeyword($1, "interface"))
+ {
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_SetInInterface(parser, true);
+ }
+ free($1);
+ }
+| WORD WORD other EOSTMT
+ {
+ if (cmFortranParserIsKeyword($1, "use"))
+ {
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleUse(parser, $2);
+ }
+ else if (cmFortranParserIsKeyword($1, "module"))
+ {
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleModule(parser, $2);
+ }
+ else if (cmFortranParserIsKeyword($1, "interface"))
+ {
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_SetInInterface(parser, true);
+ }
+ else if (cmFortranParserIsKeyword($2, "interface") &&
+ cmFortranParserIsKeyword($1, "end"))
+ {
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_SetInInterface(parser, false);
+ }
+ free($1);
+ free($2);
+ }
+| WORD DCOLON WORD other EOSTMT
+ {
+ if (cmFortranParserIsKeyword($1, "use"))
+ {
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleUse(parser, $3);
+ }
+ free($1);
+ free($3);
+ }
+| WORD COMMA WORD DCOLON WORD other EOSTMT
+ {
+ if (cmFortranParserIsKeyword($1, "use") &&
+ cmFortranParserIsKeyword($3, "non_intrinsic") )
+ {
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleUse(parser, $5);
+ }
+ free($1);
+ free($3);
+ free($5);
+ }
+| WORD STRING other EOSTMT /* Ignore */
+ {
+ if (cmFortranParserIsKeyword($1, "include"))
+ {
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleInclude(parser, $2);
+ }
+ free($1);
+ free($2);
+ }
+| CPP_LINE_DIRECTIVE STRING other EOSTMT
+ {
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleLineDirective(parser, $2);
+ free($2);
+ }
+| CPP_INCLUDE_ANGLE other EOSTMT
+ {
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleInclude(parser, $1);
+ free($1);
+ }
+| include STRING other EOSTMT
+ {
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleInclude(parser, $2);
+ free($2);
+ }
+| define WORD other EOSTMT
+ {
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleDefine(parser, $2);
+ free($2);
+ }
+| undef WORD other EOSTMT
+ {
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleUndef(parser, $2);
+ free($2);
+ }
+| ifdef WORD other EOSTMT
+ {
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleIfdef(parser, $2);
+ free($2);
+ }
+| ifndef WORD other EOSTMT
+ {
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleIfndef(parser, $2);
+ free($2);
+ }
+| if other EOSTMT
+ {
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleIf(parser);
+ }
+| elif other EOSTMT
+ {
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleElif(parser);
+ }
+| else other EOSTMT
+ {
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleElse(parser);
+ }
+| endif other EOSTMT
+ {
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleEndif(parser);
+ }
+| WORD GARBAGE other EOSTMT /* Ignore */
+ {
+ free($1);
+ }
+| GARBAGE other EOSTMT
+| EOSTMT
+| error
+;
+
+
+
+include: CPP_INCLUDE | F90PPR_INCLUDE | COCO_INCLUDE ;
+define: CPP_DEFINE | F90PPR_DEFINE;
+undef: CPP_UNDEF | F90PPR_UNDEF ;
+ifdef: CPP_IFDEF | F90PPR_IFDEF ;
+ifndef: CPP_IFNDEF | F90PPR_IFNDEF ;
+if: CPP_IF | F90PPR_IF ;
+elif: CPP_ELIF | F90PPR_ELIF ;
+else: CPP_ELSE | F90PPR_ELSE ;
+endif: CPP_ENDIF | F90PPR_ENDIF ;
+other: /* empty */ | other misc_code ;
+
+misc_code:
+ WORD { free ($1); }
+| STRING { free ($1); }
+| GARBAGE
+| ASSIGNMENT_OP
+| DCOLON
+| COMMA
+| UNTERMINATED_STRING
+;
+
+%%
+/* End of grammar */
diff --git a/Source/cmFortranParserImpl.cxx b/Source/cmFortranParserImpl.cxx
new file mode 100644
index 000000000..c175e6208
--- /dev/null
+++ b/Source/cmFortranParserImpl.cxx
@@ -0,0 +1,434 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmFortranParser.h"
+
+#include "cmSystemTools.h"
+#include <assert.h>
+
+//----------------------------------------------------------------------------
+bool cmFortranParser_s::FindIncludeFile(const char* dir,
+ const char* includeName,
+ std::string& fileName)
+{
+ // If the file is a full path, include it directly.
+ if(cmSystemTools::FileIsFullPath(includeName))
+ {
+ fileName = includeName;
+ return cmSystemTools::FileExists(fileName.c_str(), true);
+ }
+ else
+ {
+ // Check for the file in the directory containing the including
+ // file.
+ std::string fullName = dir;
+ fullName += "/";
+ fullName += includeName;
+ if(cmSystemTools::FileExists(fullName.c_str(), true))
+ {
+ fileName = fullName;
+ return true;
+ }
+
+ // Search the include path for the file.
+ for(std::vector<std::string>::const_iterator i =
+ this->IncludePath.begin(); i != this->IncludePath.end(); ++i)
+ {
+ fullName = *i;
+ fullName += "/";
+ fullName += includeName;
+ if(cmSystemTools::FileExists(fullName.c_str(), true))
+ {
+ fileName = fullName;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+cmFortranParser_s
+::cmFortranParser_s(std::vector<std::string> const& includes,
+ std::set<std::string> const& defines,
+ cmFortranSourceInfo& info):
+ IncludePath(includes), PPDefinitions(defines), Info(info)
+{
+ this->InInterface = 0;
+ this->InPPFalseBranch = 0;
+
+ // Initialize the lexical scanner.
+ cmFortran_yylex_init(&this->Scanner);
+ cmFortran_yyset_extra(this, this->Scanner);
+
+ // Create a dummy buffer that is never read but is the fallback
+ // buffer when the last file is popped off the stack.
+ YY_BUFFER_STATE buffer =
+ cmFortran_yy_create_buffer(0, 4, this->Scanner);
+ cmFortran_yy_switch_to_buffer(buffer, this->Scanner);
+}
+
+//----------------------------------------------------------------------------
+cmFortranParser_s::~cmFortranParser_s()
+{
+ cmFortran_yylex_destroy(this->Scanner);
+}
+
+//----------------------------------------------------------------------------
+bool cmFortranParser_FilePush(cmFortranParser* parser,
+ const char* fname)
+{
+ // Open the new file and push it onto the stack. Save the old
+ // buffer with it on the stack.
+ if(FILE* file = cmsys::SystemTools::Fopen(fname, "rb"))
+ {
+ YY_BUFFER_STATE current =
+ cmFortranLexer_GetCurrentBuffer(parser->Scanner);
+ std::string dir = cmSystemTools::GetParentDirectory(fname);
+ cmFortranFile f(file, current, dir);
+ YY_BUFFER_STATE buffer =
+ cmFortran_yy_create_buffer(0, 16384, parser->Scanner);
+ cmFortran_yy_switch_to_buffer(buffer, parser->Scanner);
+ parser->FileStack.push(f);
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmFortranParser_FilePop(cmFortranParser* parser)
+{
+ // Pop one file off the stack and close it. Switch the lexer back
+ // to the next one on the stack.
+ if(parser->FileStack.empty())
+ {
+ return 0;
+ }
+ else
+ {
+ cmFortranFile f = parser->FileStack.top(); parser->FileStack.pop();
+ fclose(f.File);
+ YY_BUFFER_STATE current =
+ cmFortranLexer_GetCurrentBuffer(parser->Scanner);
+ cmFortran_yy_delete_buffer(current, parser->Scanner);
+ cmFortran_yy_switch_to_buffer(f.Buffer, parser->Scanner);
+ return 1;
+ }
+}
+
+//----------------------------------------------------------------------------
+int cmFortranParser_Input(cmFortranParser* parser,
+ char* buffer, size_t bufferSize)
+{
+ // Read from the file on top of the stack. If the stack is empty,
+ // the end of the translation unit has been reached.
+ if(!parser->FileStack.empty())
+ {
+ FILE* file = parser->FileStack.top().File;
+ return (int)fread(buffer, 1, bufferSize, file);
+ }
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_StringStart(cmFortranParser* parser)
+{
+ parser->TokenString = "";
+}
+
+//----------------------------------------------------------------------------
+const char* cmFortranParser_StringEnd(cmFortranParser* parser)
+{
+ return parser->TokenString.c_str();
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_StringAppend(cmFortranParser* parser,
+ char c)
+{
+ parser->TokenString += c;
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_SetInInterface(cmFortranParser* parser,
+ bool in)
+{
+ if(parser->InPPFalseBranch)
+ {
+ return;
+ }
+
+ parser->InInterface = in;
+}
+
+//----------------------------------------------------------------------------
+bool cmFortranParser_GetInInterface(cmFortranParser* parser)
+{
+ return parser->InInterface;
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_SetOldStartcond(cmFortranParser* parser,
+ int arg)
+{
+ parser->OldStartcond = arg;
+}
+
+//----------------------------------------------------------------------------
+int cmFortranParser_GetOldStartcond(cmFortranParser* parser)
+{
+ return parser->OldStartcond;
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_Error(cmFortranParser*, const char*)
+{
+ // If there is a parser error just ignore it. The source will not
+ // compile and the user will edit it. Then dependencies will have
+ // to be regenerated anyway.
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleUse(cmFortranParser* parser,
+ const char* name)
+{
+ if(!parser->InPPFalseBranch)
+ {
+ parser->Info.Requires.insert(cmSystemTools::LowerCase(name) );
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleLineDirective(cmFortranParser* parser,
+ const char* filename)
+{
+ // This is a #line directive naming a file encountered during preprocessing.
+ std::string included = filename;
+
+ // Skip #line directives referencing non-files like
+ // "<built-in>" or "<command-line>".
+ if (included.empty() || included[0] == '<')
+ {
+ return;
+ }
+
+ // Fix windows file path separators since our lexer does not
+ // process escape sequences in string literals.
+ cmSystemTools::ReplaceString(included, "\\\\", "\\");
+ cmSystemTools::ConvertToUnixSlashes(included);
+
+ // Save the named file as included in the source.
+ if (cmSystemTools::FileExists(included))
+ {
+ parser->Info.Includes.insert(included);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleInclude(cmFortranParser* parser,
+ const char* name)
+{
+ if(parser->InPPFalseBranch)
+ {
+ return;
+ }
+
+ // If processing an include statement there must be an open file.
+ assert(!parser->FileStack.empty());
+
+ // Get the directory containing the source in which the include
+ // statement appears. This is always the first search location for
+ // Fortran include files.
+ std::string dir = parser->FileStack.top().Directory;
+
+ // Find the included file. If it cannot be found just ignore the
+ // problem because either the source will not compile or the user
+ // does not care about depending on this included source.
+ std::string fullName;
+ if(parser->FindIncludeFile(dir.c_str(), name, fullName))
+ {
+ // Found the included file. Save it in the set of included files.
+ parser->Info.Includes.insert(fullName);
+
+ // Parse it immediately to translate the source inline.
+ cmFortranParser_FilePush(parser, fullName.c_str());
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleModule(cmFortranParser* parser,
+ const char* name)
+{
+ if(!parser->InPPFalseBranch && !parser->InInterface)
+ {
+ parser->Info.Provides.insert(cmSystemTools::LowerCase(name));
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleDefine(cmFortranParser* parser,
+ const char* macro)
+{
+ if(!parser->InPPFalseBranch)
+ {
+ parser->PPDefinitions.insert(macro);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleUndef(cmFortranParser* parser,
+ const char* macro)
+{
+ if(!parser->InPPFalseBranch)
+ {
+ std::set<std::string>::iterator match;
+ match = parser->PPDefinitions.find(macro);
+ if(match != parser->PPDefinitions.end())
+ {
+ parser->PPDefinitions.erase(match);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleIfdef(cmFortranParser* parser,
+ const char* macro)
+{
+ // A new PP branch has been opened
+ parser->SkipToEnd.push(false);
+
+ if (parser->InPPFalseBranch)
+ {
+ parser->InPPFalseBranch++;
+ }
+ else if(parser->PPDefinitions.find(macro) == parser->PPDefinitions.end())
+ {
+ parser->InPPFalseBranch=1;
+ }
+ else
+ {
+ parser->SkipToEnd.top() = true;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleIfndef(cmFortranParser* parser,
+ const char* macro)
+{
+ // A new PP branch has been opened
+ parser->SkipToEnd.push(false);
+
+ if (parser->InPPFalseBranch)
+ {
+ parser->InPPFalseBranch++;
+ }
+ else if(parser->PPDefinitions.find(macro) != parser->PPDefinitions.end())
+ {
+ parser->InPPFalseBranch = 1;
+ }
+ else
+ {
+ // ignore other branches
+ parser->SkipToEnd.top() = true;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleIf(cmFortranParser* parser)
+{
+ /* Note: The current parser is _not_ able to get statements like
+ * #if 0
+ * #if 1
+ * #if MYSMBOL
+ * #if defined(MYSYMBOL)
+ * #if defined(MYSYMBOL) && ...
+ * right. The same for #elif. Thus in
+ * #if SYMBOL_1
+ * ..
+ * #elif SYMBOL_2
+ * ...
+ * ...
+ * #elif SYMBOL_N
+ * ..
+ * #else
+ * ..
+ * #endif
+ * _all_ N+1 branches are considered. If you got something like this
+ * #if defined(MYSYMBOL)
+ * #if !defined(MYSYMBOL)
+ * use
+ * #ifdef MYSYMBOL
+ * #ifndef MYSYMBOL
+ * instead.
+ */
+
+ // A new PP branch has been opened
+ // Never skip! See note above.
+ parser->SkipToEnd.push(false);
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleElif(cmFortranParser* parser)
+{
+ /* Note: There are parser limitations. See the note at
+ * cmFortranParser_RuleIf(..)
+ */
+
+ // Always taken unless an #ifdef or #ifndef-branch has been taken
+ // already. If the second condition isn't meet already
+ // (parser->InPPFalseBranch == 0) correct it.
+ if(!parser->SkipToEnd.empty() &&
+ parser->SkipToEnd.top() && !parser->InPPFalseBranch)
+ {
+ parser->InPPFalseBranch = 1;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleElse(cmFortranParser* parser)
+{
+ // if the parent branch is false do nothing!
+ if(parser->InPPFalseBranch > 1)
+ {
+ return;
+ }
+
+ // parser->InPPFalseBranch is either 0 or 1. We change it depending on
+ // parser->SkipToEnd.top()
+ if(!parser->SkipToEnd.empty() &&
+ parser->SkipToEnd.top())
+ {
+ parser->InPPFalseBranch = 1;
+ }
+ else
+ {
+ parser->InPPFalseBranch = 0;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleEndif(cmFortranParser* parser)
+{
+ if(!parser->SkipToEnd.empty())
+ {
+ parser->SkipToEnd.pop();
+ }
+
+ // #endif doesn't know if there was a "#else" in before, so it
+ // always decreases InPPFalseBranch
+ if(parser->InPPFalseBranch)
+ {
+ parser->InPPFalseBranch--;
+ }
+}
diff --git a/Source/cmFortranParserTokens.h b/Source/cmFortranParserTokens.h
new file mode 100644
index 000000000..ac4984066
--- /dev/null
+++ b/Source/cmFortranParserTokens.h
@@ -0,0 +1,131 @@
+/* A Bison parser, made by GNU Bison 3.0.2. */
+
+/* Bison interface for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+#ifndef YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED
+# define YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED
+/* Debug traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int cmFortran_yydebug;
+#endif
+
+/* Token type. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ enum yytokentype
+ {
+ EOSTMT = 258,
+ ASSIGNMENT_OP = 259,
+ GARBAGE = 260,
+ CPP_LINE_DIRECTIVE = 261,
+ CPP_INCLUDE = 262,
+ F90PPR_INCLUDE = 263,
+ COCO_INCLUDE = 264,
+ F90PPR_DEFINE = 265,
+ CPP_DEFINE = 266,
+ F90PPR_UNDEF = 267,
+ CPP_UNDEF = 268,
+ CPP_IFDEF = 269,
+ CPP_IFNDEF = 270,
+ CPP_IF = 271,
+ CPP_ELSE = 272,
+ CPP_ELIF = 273,
+ CPP_ENDIF = 274,
+ F90PPR_IFDEF = 275,
+ F90PPR_IFNDEF = 276,
+ F90PPR_IF = 277,
+ F90PPR_ELSE = 278,
+ F90PPR_ELIF = 279,
+ F90PPR_ENDIF = 280,
+ COMMA = 281,
+ DCOLON = 282,
+ CPP_TOENDL = 283,
+ UNTERMINATED_STRING = 284,
+ STRING = 285,
+ WORD = 286,
+ CPP_INCLUDE_ANGLE = 287
+ };
+#endif
+/* Tokens. */
+#define EOSTMT 258
+#define ASSIGNMENT_OP 259
+#define GARBAGE 260
+#define CPP_LINE_DIRECTIVE 261
+#define CPP_INCLUDE 262
+#define F90PPR_INCLUDE 263
+#define COCO_INCLUDE 264
+#define F90PPR_DEFINE 265
+#define CPP_DEFINE 266
+#define F90PPR_UNDEF 267
+#define CPP_UNDEF 268
+#define CPP_IFDEF 269
+#define CPP_IFNDEF 270
+#define CPP_IF 271
+#define CPP_ELSE 272
+#define CPP_ELIF 273
+#define CPP_ENDIF 274
+#define F90PPR_IFDEF 275
+#define F90PPR_IFNDEF 276
+#define F90PPR_IF 277
+#define F90PPR_ELSE 278
+#define F90PPR_ELIF 279
+#define F90PPR_ENDIF 280
+#define COMMA 281
+#define DCOLON 282
+#define CPP_TOENDL 283
+#define UNTERMINATED_STRING 284
+#define STRING 285
+#define WORD 286
+#define CPP_INCLUDE_ANGLE 287
+
+/* Value type. */
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE YYSTYPE;
+union YYSTYPE
+{
+#line 81 "cmFortranParser.y" /* yacc.c:1909 */
+
+ char* string;
+
+#line 122 "cmFortranParserTokens.h" /* yacc.c:1909 */
+};
+# define YYSTYPE_IS_TRIVIAL 1
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+
+int cmFortran_yyparse (yyscan_t yyscanner);
+
+#endif /* !YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED */
diff --git a/Source/cmFunctionBlocker.h b/Source/cmFunctionBlocker.h
index 68bf76286..a3b80781d 100644
--- a/Source/cmFunctionBlocker.h
+++ b/Source/cmFunctionBlocker.h
@@ -39,7 +39,7 @@ public:
/** Set/Get the context in which this blocker is created. */
void SetStartingContext(cmListFileContext const& lfc)
{ this->StartingContext = lfc; }
- cmListFileContext const& GetStartingContext()
+ cmListFileContext const& GetStartingContext() const
{ return this->StartingContext; }
private:
cmListFileContext StartingContext;
diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx
index a126cd110..c883ad743 100644
--- a/Source/cmFunctionCommand.cxx
+++ b/Source/cmFunctionCommand.cxx
@@ -20,7 +20,7 @@ public:
cmFunctionHelperCommand() {}
///! clean up any memory allocated by the function
- ~cmFunctionHelperCommand() {};
+ ~cmFunctionHelperCommand() {}
/**
* This is used to avoid including this command
@@ -43,6 +43,7 @@ public:
newC->Args = this->Args;
newC->Functions = this->Functions;
newC->Policies = this->Policies;
+ newC->FilePath = this->FilePath;
return newC;
}
@@ -59,39 +60,21 @@ public:
cmExecutionStatus &);
virtual bool InitialPass(std::vector<std::string> const&,
- cmExecutionStatus &) { return false; };
+ cmExecutionStatus &) { return false; }
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return this->Args[0].c_str(); }
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- std::string docs = "Function named: ";
- docs += this->GetName();
- return docs.c_str();
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return this->GetTerseDocumentation();
- }
+ virtual std::string GetName() const { return this->Args[0]; }
cmTypeMacro(cmFunctionHelperCommand, cmCommand);
std::vector<std::string> Args;
std::vector<cmListFileFunction> Functions;
cmPolicies::PolicyMap Policies;
+ std::string FilePath;
};
-
bool cmFunctionHelperCommand::InvokeInitialPass
(const std::vector<cmListFileArgument>& args,
cmExecutionStatus & inStatus)
@@ -107,21 +90,16 @@ bool cmFunctionHelperCommand::InvokeInitialPass
std::string errorMsg =
"Function invoked with incorrect arguments for function named: ";
errorMsg += this->Args[0];
- this->SetError(errorMsg.c_str());
+ this->SetError(errorMsg);
return false;
}
- // we push a scope on the makefile
- cmMakefile::LexicalPushPop lexScope(this->Makefile);
- cmMakefile::ScopePushPop varScope(this->Makefile);
- static_cast<void>(varScope);
-
- // Push a weak policy scope which restores the policies recorded at
- // function creation.
- cmMakefile::PolicyPushPop polScope(this->Makefile, true, this->Policies);
+ cmMakefile::FunctionPushPop functionScope(this->Makefile,
+ this->FilePath,
+ this->Policies);
// set the value of argc
- cmOStringStream strStream;
+ std::ostringstream strStream;
strStream << expandedArgs.size();
this->Makefile->AddDefinition("ARGC",strStream.str().c_str());
this->Makefile->MarkVariableAsUsed("ARGC");
@@ -129,42 +107,25 @@ bool cmFunctionHelperCommand::InvokeInitialPass
// set the values for ARGV0 ARGV1 ...
for (unsigned int t = 0; t < expandedArgs.size(); ++t)
{
- cmOStringStream tmpStream;
+ std::ostringstream tmpStream;
tmpStream << "ARGV" << t;
- this->Makefile->AddDefinition(tmpStream.str().c_str(),
+ this->Makefile->AddDefinition(tmpStream.str(),
expandedArgs[t].c_str());
- this->Makefile->MarkVariableAsUsed(tmpStream.str().c_str());
+ this->Makefile->MarkVariableAsUsed(tmpStream.str());
}
// define the formal arguments
for (unsigned int j = 1; j < this->Args.size(); ++j)
{
- this->Makefile->AddDefinition(this->Args[j].c_str(),
+ this->Makefile->AddDefinition(this->Args[j],
expandedArgs[j-1].c_str());
}
// define ARGV and ARGN
- std::vector<std::string>::const_iterator eit;
- std::string argvDef;
- std::string argnDef;
- unsigned int cnt = 0;
- for ( eit = expandedArgs.begin(); eit != expandedArgs.end(); ++eit )
- {
- if ( argvDef.size() > 0 )
- {
- argvDef += ";";
- }
- argvDef += *eit;
- if ( cnt >= this->Args.size()-1 )
- {
- if ( argnDef.size() > 0 )
- {
- argnDef += ";";
- }
- argnDef += *eit;
- }
- cnt ++;
- }
+ std::string argvDef = cmJoin(expandedArgs, ";");
+ std::vector<std::string>::const_iterator eit
+ = expandedArgs.begin() + (this->Args.size()-1);
+ std::string argnDef = cmJoin(cmMakeRange(eit, expandedArgs.end()), ";");
this->Makefile->AddDefinition("ARGV", argvDef.c_str());
this->Makefile->MarkVariableAsUsed("ARGV");
this->Makefile->AddDefinition("ARGN", argnDef.c_str());
@@ -180,8 +141,7 @@ bool cmFunctionHelperCommand::InvokeInitialPass
{
// The error message should have already included the call stack
// so we do not need to report an error here.
- lexScope.Quiet();
- polScope.Quiet();
+ functionScope.Quiet();
inStatus.SetNestedError(true);
return false;
}
@@ -210,36 +170,16 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
// if this is the endfunction for this function then execute
if (!this->Depth)
{
- std::string name = this->Args[0];
- std::vector<std::string>::size_type cc;
- name += "(";
- for ( cc = 0; cc < this->Args.size(); cc ++ )
- {
- name += " " + this->Args[cc];
- }
- name += " )";
-
// create a new command and add it to cmake
cmFunctionHelperCommand *f = new cmFunctionHelperCommand();
f->Args = this->Args;
f->Functions = this->Functions;
+ f->FilePath = this->GetStartingContext().FilePath;
mf.RecordPolicies(f->Policies);
- // Set the FilePath on the arguments to match the function since it is
- // not stored and the original values may be freed
- for (unsigned int i = 0; i < f->Functions.size(); ++i)
- {
- for (unsigned int j = 0; j < f->Functions[i].Arguments.size(); ++j)
- {
- f->Functions[i].Arguments[j].FilePath =
- f->Functions[i].FilePath.c_str();
- }
- }
-
std::string newName = "_" + this->Args[0];
- mf.GetCMakeInstance()->RenameCommand(this->Args[0].c_str(),
- newName.c_str());
- mf.AddCommand(f);
+ mf.GetState()->RenameCommand(this->Args[0], newName);
+ mf.GetState()->AddCommand(f);
// remove the function blocker now that the function is defined
mf.RemoveFunctionBlocker(this, lff);
@@ -265,7 +205,8 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf)
if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endfunction"))
{
std::vector<std::string> expandedArguments;
- mf.ExpandArguments(lff.Arguments, expandedArguments);
+ mf.ExpandArguments(lff.Arguments, expandedArguments,
+ this->GetStartingContext().FilePath.c_str());
// if the endfunction has arguments then make sure
// they match the ones in the opening function command
if ((expandedArguments.empty() ||
@@ -289,11 +230,7 @@ bool cmFunctionCommand
// create a function blocker
cmFunctionFunctionBlocker *f = new cmFunctionFunctionBlocker();
- for(std::vector<std::string>::const_iterator j = args.begin();
- j != args.end(); ++j)
- {
- f->Args.push_back(*j);
- }
+ f->Args.insert(f->Args.end(), args.begin(), args.end());
this->Makefile->AddFunctionBlocker(f);
return true;
}
diff --git a/Source/cmFunctionCommand.h b/Source/cmFunctionCommand.h
index 0a029dc5f..2df435e71 100644
--- a/Source/cmFunctionCommand.h
+++ b/Source/cmFunctionCommand.h
@@ -57,47 +57,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "function";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Start recording a function for later invocation as a command.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " function(<name> [arg1 [arg2 [arg3 ...]]])\n"
- " COMMAND1(ARGS ...)\n"
- " COMMAND2(ARGS ...)\n"
- " ...\n"
- " endfunction(<name>)\n"
- "Define a function named <name> that takes arguments named "
- "arg1 arg2 arg3 (...). Commands listed after function, but before "
- "the matching endfunction, are not invoked until the function "
- "is invoked. When it is invoked, the commands recorded in the "
- "function are first modified by replacing formal parameters (${arg1}) "
- "with the arguments passed, and then invoked as normal commands. In "
- "addition to referencing the formal parameters you can reference "
- "the variable ARGC which will be set to the number of arguments "
- "passed into the function as well as ARGV0 ARGV1 ARGV2 ... which "
- "will have the actual values of the arguments passed in. This "
- "facilitates creating functions with optional arguments. Additionally "
- "ARGV holds the list of all arguments given to the function and ARGN "
- "holds the list of arguments past the last expected argument."
- "\n"
- "A function opens a new scope: see set(var PARENT_SCOPE) for details."
- "\n"
- "See the cmake_policy() command documentation for the behavior of "
- "policies inside functions."
- ;
- }
+ virtual std::string GetName() const { return "function";}
cmTypeMacro(cmFunctionCommand, cmCommand);
};
diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx
index 0af07532a..600b793e3 100644
--- a/Source/cmGeneratedFileStream.cxx
+++ b/Source/cmGeneratedFileStream.cxx
@@ -152,7 +152,7 @@ void cmGeneratedFileStreamBase::Open(const char* name)
#endif
// Make sure the temporary file that will be used is not present.
- cmSystemTools::RemoveFile(this->TempName.c_str());
+ cmSystemTools::RemoveFile(this->TempName);
std::string dir = cmSystemTools::GetFilenamePath(this->TempName);
cmSystemTools::MakeDirectory(dir.c_str());
@@ -174,7 +174,7 @@ bool cmGeneratedFileStreamBase::Close()
if(!this->Name.empty() &&
this->Okay &&
(!this->CopyIfDifferent ||
- cmSystemTools::FilesDiffer(this->TempName.c_str(), resname.c_str())))
+ cmSystemTools::FilesDiffer(this->TempName, resname)))
{
// The destination is to be replaced. Rename the temporary to the
// destination atomically.
@@ -185,7 +185,7 @@ bool cmGeneratedFileStreamBase::Close()
{
this->RenameFile(gzname.c_str(), resname.c_str());
}
- cmSystemTools::RemoveFile(gzname.c_str());
+ cmSystemTools::RemoveFile(gzname);
}
else
{
@@ -198,7 +198,7 @@ bool cmGeneratedFileStreamBase::Close()
// Else, the destination was not replaced.
//
// Always delete the temporary file. We never want it to stay around.
- cmSystemTools::RemoveFile(this->TempName.c_str());
+ cmSystemTools::RemoveFile(this->TempName);
return replaced;
}
@@ -213,7 +213,7 @@ int cmGeneratedFileStreamBase::CompressFile(const char* oldname,
{
return 0;
}
- FILE* ifs = fopen(oldname, "r");
+ FILE* ifs = cmsys::SystemTools::Fopen(oldname, "r");
if ( !ifs )
{
return 0;
@@ -249,12 +249,7 @@ int cmGeneratedFileStreamBase::RenameFile(const char* oldname,
}
//----------------------------------------------------------------------------
-void cmGeneratedFileStream::SetName(const char* fname)
+void cmGeneratedFileStream::SetName(const std::string& fname)
{
- if ( !fname )
- {
- this->Name = "";
- return;
- }
this->Name = fname;
}
diff --git a/Source/cmGeneratedFileStream.h b/Source/cmGeneratedFileStream.h
index dac9c7b40..8df3e1a98 100644
--- a/Source/cmGeneratedFileStream.h
+++ b/Source/cmGeneratedFileStream.h
@@ -13,10 +13,7 @@
#define cmGeneratedFileStream_h
#include "cmStandardIncludes.h"
-
-#if defined(__sgi) && !defined(__GNUC__)
-# pragma set woff 1375 /* base class destructor not virtual */
-#endif
+#include <cmsys/FStream.hxx>
// This is the first base class of cmGeneratedFileStream. It will be
// created before and destroyed after the ofstream portion and can
@@ -59,10 +56,10 @@ protected:
// Whether the real file stream was valid when it was closed.
bool Okay;
- // Whether the destionation file is compressed
+ // Whether the destination file is compressed
bool Compress;
- // Whether the destionation file is compressed
+ // Whether the destination file is compressed
bool CompressExtraExtension;
};
@@ -77,10 +74,10 @@ protected:
* being updated.
*/
class cmGeneratedFileStream: private cmGeneratedFileStreamBase,
- public std::ofstream
+ public cmsys::ofstream
{
public:
- typedef std::ofstream Stream;
+ typedef cmsys::ofstream Stream;
/**
* This constructor prepares a default stream. The open method must
@@ -139,14 +136,10 @@ public:
* Set name of the file that will hold the actual output. This method allows
* the output file to be changed during the use of cmGeneratedFileStream.
*/
- void SetName(const char* fname);
+ void SetName(const std::string& fname);
private:
cmGeneratedFileStream(cmGeneratedFileStream const&); // not implemented
};
-#if defined(__sgi) && !defined(__GNUC__)
-# pragma reset woff 1375 /* base class destructor not virtual */
-#endif
-
#endif
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index d73c72c10..6796a011f 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -11,11 +11,9 @@
============================================================================*/
#include "cmGeneratorExpression.h"
-#include "cmMakefile.h"
-#include "cmTarget.h"
#include "assert.h"
-
-#include <cmsys/String.h>
+#include "cmAlgorithms.h"
+#include "cmSystemTools.h"
#include "cmGeneratorExpressionEvaluator.h"
#include "cmGeneratorExpressionLexer.h"
@@ -24,7 +22,7 @@
//----------------------------------------------------------------------------
cmGeneratorExpression::cmGeneratorExpression(
- cmListFileBacktrace const& backtrace):
+ const cmListFileBacktrace& backtrace):
Backtrace(backtrace)
{
}
@@ -33,17 +31,15 @@ cmGeneratorExpression::cmGeneratorExpression(
cmsys::auto_ptr<cmCompiledGeneratorExpression>
cmGeneratorExpression::Parse(std::string const& input)
{
- return this->Parse(input.c_str());
+ return cmsys::auto_ptr<cmCompiledGeneratorExpression>(
+ new cmCompiledGeneratorExpression(this->Backtrace, input));
}
//----------------------------------------------------------------------------
cmsys::auto_ptr<cmCompiledGeneratorExpression>
cmGeneratorExpression::Parse(const char* input)
{
- return cmsys::auto_ptr<cmCompiledGeneratorExpression>(
- new cmCompiledGeneratorExpression(
- this->Backtrace,
- input));
+ return this->Parse(std::string(input ? input : ""));
}
cmGeneratorExpression::~cmGeneratorExpression()
@@ -51,27 +47,43 @@ cmGeneratorExpression::~cmGeneratorExpression()
}
//----------------------------------------------------------------------------
-const char *cmCompiledGeneratorExpression::Evaluate(
- cmMakefile* mf, const char* config, bool quiet,
- cmTarget *headTarget,
- cmGeneratorExpressionDAGChecker *dagChecker) const
+const char *cmCompiledGeneratorExpression::Evaluate(cmLocalGenerator* lg,
+ const std::string& config, bool quiet,
+ const cmGeneratorTarget* headTarget,
+ cmGeneratorExpressionDAGChecker *dagChecker,
+ std::string const& language) const
{
- return this->Evaluate(mf,
+ return this->Evaluate(lg,
config,
quiet,
headTarget,
headTarget,
- dagChecker);
+ dagChecker,
+ language);
}
//----------------------------------------------------------------------------
const char *cmCompiledGeneratorExpression::Evaluate(
- cmMakefile* mf, const char* config, bool quiet,
- cmTarget *headTarget,
- cmTarget *currentTarget,
- cmGeneratorExpressionDAGChecker *dagChecker) const
+ cmLocalGenerator* lg, const std::string& config, bool quiet,
+ const cmGeneratorTarget* headTarget,
+ const cmGeneratorTarget* currentTarget,
+ cmGeneratorExpressionDAGChecker *dagChecker,
+ std::string const& language) const
+{
+ cmGeneratorExpressionContext context(lg, config, quiet, headTarget,
+ currentTarget ? currentTarget : headTarget,
+ this->EvaluateForBuildsystem,
+ this->Backtrace, language);
+
+ return this->EvaluateWithContext(context, dagChecker);
+}
+
+//----------------------------------------------------------------------------
+const char* cmCompiledGeneratorExpression::EvaluateWithContext(
+ cmGeneratorExpressionContext& context,
+ cmGeneratorExpressionDAGChecker *dagChecker) const
{
- if (!this->NeedsParsing)
+ if (!this->NeedsEvaluation)
{
return this->Input.c_str();
}
@@ -83,35 +95,26 @@ const char *cmCompiledGeneratorExpression::Evaluate(
const std::vector<cmGeneratorExpressionEvaluator*>::const_iterator end
= this->Evaluators.end();
- cmGeneratorExpressionContext context;
- context.Makefile = mf;
- context.Config = config;
- context.Quiet = quiet;
- context.HadError = false;
- context.HadContextSensitiveCondition = false;
- context.HeadTarget = headTarget;
- context.CurrentTarget = currentTarget ? currentTarget : headTarget;
- context.Backtrace = this->Backtrace;
-
for ( ; it != end; ++it)
{
this->Output += (*it)->Evaluate(&context, dagChecker);
- for(std::set<cmStdString>::const_iterator
- p = context.SeenTargetProperties.begin();
- p != context.SeenTargetProperties.end(); ++p)
- {
- this->SeenTargetProperties.insert(*p);
- }
+ this->SeenTargetProperties.insert(context.SeenTargetProperties.begin(),
+ context.SeenTargetProperties.end());
if (context.HadError)
{
this->Output = "";
break;
}
}
+
+ this->MaxLanguageStandard = context.MaxLanguageStandard;
+
if (!context.HadError)
{
this->HadContextSensitiveCondition = context.HadContextSensitiveCondition;
+ this->HadHeadSensitiveCondition = context.HadHeadSensitiveCondition;
+ this->SourceSensitiveTargets = context.SourceSensitiveTargets;
}
this->DependTargets = context.DependTargets;
@@ -122,16 +125,18 @@ const char *cmCompiledGeneratorExpression::Evaluate(
cmCompiledGeneratorExpression::cmCompiledGeneratorExpression(
cmListFileBacktrace const& backtrace,
- const char *input)
- : Backtrace(backtrace), Input(input ? input : ""),
- HadContextSensitiveCondition(false)
+ const std::string& input)
+ : Backtrace(backtrace), Input(input),
+ HadContextSensitiveCondition(false),
+ HadHeadSensitiveCondition(false),
+ EvaluateForBuildsystem(false)
{
cmGeneratorExpressionLexer l;
std::vector<cmGeneratorExpressionToken> tokens =
- l.Tokenize(this->Input.c_str());
- this->NeedsParsing = l.GetSawGeneratorExpression();
+ l.Tokenize(this->Input);
+ this->NeedsEvaluation = l.GetSawGeneratorExpression();
- if (this->NeedsParsing)
+ if (this->NeedsEvaluation)
{
cmGeneratorExpressionParser p(tokens);
p.Parse(this->Evaluators);
@@ -142,32 +147,31 @@ cmCompiledGeneratorExpression::cmCompiledGeneratorExpression(
//----------------------------------------------------------------------------
cmCompiledGeneratorExpression::~cmCompiledGeneratorExpression()
{
- std::vector<cmGeneratorExpressionEvaluator*>::const_iterator it
- = this->Evaluators.begin();
- const std::vector<cmGeneratorExpressionEvaluator*>::const_iterator end
- = this->Evaluators.end();
-
- for ( ; it != end; ++it)
- {
- delete *it;
- }
+ cmDeleteAll(this->Evaluators);
}
//----------------------------------------------------------------------------
std::string cmGeneratorExpression::StripEmptyListElements(
const std::string &input)
{
+ if (input.find(';') == input.npos)
+ {
+ return input;
+ }
std::string result;
+ result.reserve(input.size());
const char *c = input.c_str();
+ const char *last = c;
bool skipSemiColons = true;
for ( ; *c; ++c)
{
- if(c[0] == ';')
+ if(*c == ';')
{
if(skipSemiColons)
{
- continue;
+ result.append(last, c - last);
+ last = c + 1;
}
skipSemiColons = true;
}
@@ -175,8 +179,8 @@ std::string cmGeneratorExpression::StripEmptyListElements(
{
skipSemiColons = false;
}
- result += *c;
}
+ result.append(last);
if (!result.empty() && *(result.end() - 1) == ';')
{
@@ -245,7 +249,7 @@ static void prefixItems(const std::string &content, std::string &result,
result += sep;
sep = ";";
if (!cmSystemTools::FileIsFullPath(ei->c_str())
- && cmGeneratorExpression::Find(*ei) == std::string::npos)
+ && cmGeneratorExpression::Find(*ei) != 0)
{
result += prefix;
}
@@ -372,7 +376,7 @@ void cmGeneratorExpression::Split(const std::string &input,
}
if(!part.empty())
{
- cmSystemTools::ExpandListArgument(part.c_str(), output);
+ cmSystemTools::ExpandListArgument(part, output);
}
}
pos += 2;
@@ -430,7 +434,7 @@ std::string cmGeneratorExpression::Preprocess(const std::string &input,
return stripExportInterface(input, context, resolveRelative);
}
- assert(!"cmGeneratorExpression::Preprocess called with invalid args");
+ assert(0 && "cmGeneratorExpression::Preprocess called with invalid args");
return std::string();
}
@@ -449,10 +453,24 @@ std::string::size_type cmGeneratorExpression::Find(const std::string &input)
//----------------------------------------------------------------------------
bool cmGeneratorExpression::IsValidTargetName(const std::string &input)
{
- cmsys::RegularExpression targetNameValidator;
// The ':' is supported to allow use with IMPORTED targets. At least
// Qt 4 and 5 IMPORTED targets use ':' as the namespace delimiter.
- targetNameValidator.compile("^[A-Za-z0-9_.:+-]+$");
+ static cmsys::RegularExpression targetNameValidator("^[A-Za-z0-9_.:+-]+$");
+
+ return targetNameValidator.find(input);
+}
- return targetNameValidator.find(input.c_str());
+//----------------------------------------------------------------------------
+void
+cmCompiledGeneratorExpression::GetMaxLanguageStandard(
+ const cmGeneratorTarget* tgt,
+ std::map<std::string, std::string>& mapping)
+{
+ typedef std::map<cmGeneratorTarget const*,
+ std::map<std::string, std::string> > MapType;
+ MapType::const_iterator it = this->MaxLanguageStandard.find(tgt);
+ if (it != this->MaxLanguageStandard.end())
+ {
+ mapping = it->second;
+ }
}
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index c20f130c9..efd381b53 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -16,16 +16,15 @@
#include "cmStandardIncludes.h"
#include "cmListFileCache.h"
-#include <stack>
-
#include <cmsys/RegularExpression.hxx>
#include <cmsys/auto_ptr.hxx>
-class cmTarget;
-class cmMakefile;
+class cmGeneratorTarget;
+class cmLocalGenerator;
class cmListFileBacktrace;
struct cmGeneratorExpressionEvaluator;
+struct cmGeneratorExpressionContext;
struct cmGeneratorExpressionDAGChecker;
class cmCompiledGeneratorExpression;
@@ -43,7 +42,8 @@ class cmGeneratorExpression
{
public:
/** Construct. */
- cmGeneratorExpression(cmListFileBacktrace const& backtrace);
+ cmGeneratorExpression(
+ cmListFileBacktrace const& backtrace = cmListFileBacktrace());
~cmGeneratorExpression();
cmsys::auto_ptr<cmCompiledGeneratorExpression> Parse(
@@ -72,35 +72,37 @@ private:
cmGeneratorExpression(const cmGeneratorExpression &);
void operator=(const cmGeneratorExpression &);
- cmListFileBacktrace const& Backtrace;
+ cmListFileBacktrace Backtrace;
};
class cmCompiledGeneratorExpression
{
public:
- const char* Evaluate(cmMakefile* mf, const char* config,
+ const char* Evaluate(cmLocalGenerator* lg, const std::string& config,
bool quiet = false,
- cmTarget *headTarget = 0,
- cmTarget *currentTarget = 0,
- cmGeneratorExpressionDAGChecker *dagChecker = 0) const;
- const char* Evaluate(cmMakefile* mf, const char* config,
+ cmGeneratorTarget const* headTarget = 0,
+ cmGeneratorTarget const* currentTarget = 0,
+ cmGeneratorExpressionDAGChecker *dagChecker = 0,
+ std::string const& language = std::string()) const;
+ const char* Evaluate(cmLocalGenerator* lg, const std::string& config,
bool quiet,
- cmTarget *headTarget,
- cmGeneratorExpressionDAGChecker *dagChecker) const;
+ cmGeneratorTarget const* headTarget,
+ cmGeneratorExpressionDAGChecker *dagChecker,
+ std::string const& language = std::string()) const;
/** Get set of targets found during evaluations. */
- std::set<cmTarget*> const& GetTargets() const
+ std::set<cmGeneratorTarget*> const& GetTargets() const
{ return this->DependTargets; }
- std::set<cmStdString> const& GetSeenTargetProperties() const
+ std::set<std::string> const& GetSeenTargetProperties() const
{ return this->SeenTargetProperties; }
- std::set<cmTarget*> const& GetAllTargetsSeen() const
+ std::set<cmGeneratorTarget const*> const& GetAllTargetsSeen() const
{ return this->AllTargetsSeen; }
~cmCompiledGeneratorExpression();
- std::string GetInput() const
+ std::string const& GetInput() const
{
return this->Input;
}
@@ -113,10 +115,29 @@ public:
{
return this->HadContextSensitiveCondition;
}
+ bool GetHadHeadSensitiveCondition() const
+ {
+ return this->HadHeadSensitiveCondition;
+ }
+ std::set<cmGeneratorTarget const*> GetSourceSensitiveTargets() const
+ {
+ return this->SourceSensitiveTargets;
+ }
+
+ void SetEvaluateForBuildsystem(bool eval)
+ {
+ this->EvaluateForBuildsystem = eval;
+ }
+
+ void GetMaxLanguageStandard(cmGeneratorTarget const* tgt,
+ std::map<std::string, std::string>& mapping);
private:
+ const char* EvaluateWithContext(cmGeneratorExpressionContext& context,
+ cmGeneratorExpressionDAGChecker *dagChecker) const;
+
cmCompiledGeneratorExpression(cmListFileBacktrace const& backtrace,
- const char *input);
+ const std::string& input);
friend class cmGeneratorExpression;
@@ -126,13 +147,18 @@ private:
cmListFileBacktrace Backtrace;
std::vector<cmGeneratorExpressionEvaluator*> Evaluators;
const std::string Input;
- bool NeedsParsing;
+ bool NeedsEvaluation;
- mutable std::set<cmTarget*> DependTargets;
- mutable std::set<cmTarget*> AllTargetsSeen;
- mutable std::set<cmStdString> SeenTargetProperties;
+ mutable std::set<cmGeneratorTarget*> DependTargets;
+ mutable std::set<cmGeneratorTarget const*> AllTargetsSeen;
+ mutable std::set<std::string> SeenTargetProperties;
+ mutable std::map<cmGeneratorTarget const*,
+ std::map<std::string, std::string> > MaxLanguageStandard;
mutable std::string Output;
mutable bool HadContextSensitiveCondition;
+ mutable bool HadHeadSensitiveCondition;
+ mutable std::set<cmGeneratorTarget const*> SourceSensitiveTargets;
+ bool EvaluateForBuildsystem;
};
#endif
diff --git a/Source/cmGeneratorExpressionContext.cxx b/Source/cmGeneratorExpressionContext.cxx
new file mode 100644
index 000000000..5c9462f0c
--- /dev/null
+++ b/Source/cmGeneratorExpressionContext.cxx
@@ -0,0 +1,35 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2012 Stephen Kelly <steveire@gmail.com>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmGeneratorExpressionContext.h"
+#include "cmGeneratorTarget.h"
+
+cmGeneratorExpressionContext::cmGeneratorExpressionContext(
+ cmLocalGenerator* lg, std::string const& config,
+ bool quiet, cmGeneratorTarget const* headTarget,
+ const cmGeneratorTarget* currentTarget,
+ bool evaluateForBuildsystem,
+ cmListFileBacktrace const& backtrace,
+ std::string const& language)
+ : Backtrace(backtrace),
+ LG(lg),
+ Config(config),
+ Language(language),
+ HeadTarget(headTarget),
+ CurrentTarget(currentTarget),
+ Quiet(quiet),
+ HadError(false),
+ HadContextSensitiveCondition(false),
+ HadHeadSensitiveCondition(false),
+ EvaluateForBuildsystem(evaluateForBuildsystem)
+{
+}
diff --git a/Source/cmGeneratorExpressionContext.h b/Source/cmGeneratorExpressionContext.h
new file mode 100644
index 000000000..e802138bc
--- /dev/null
+++ b/Source/cmGeneratorExpressionContext.h
@@ -0,0 +1,57 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2012 Stephen Kelly <steveire@gmail.com>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmGeneratorExpressionContext_h
+#define cmGeneratorExpressionContext_h
+
+#include "cmListFileCache.h"
+
+#include <set>
+#include <map>
+#include <string>
+
+class cmGeneratorTarget;
+class cmLocalGenerator;
+
+//----------------------------------------------------------------------------
+struct cmGeneratorExpressionContext
+{
+ cmGeneratorExpressionContext(cmLocalGenerator* lg, std::string const& config,
+ bool quiet, const cmGeneratorTarget* headTarget,
+ cmGeneratorTarget const* currentTarget,
+ bool evaluateForBuildsystem,
+ cmListFileBacktrace const& backtrace,
+ std::string const& language);
+
+
+ cmListFileBacktrace Backtrace;
+ std::set<cmGeneratorTarget*> DependTargets;
+ std::set<cmGeneratorTarget const*> AllTargets;
+ std::set<std::string> SeenTargetProperties;
+ std::set<cmGeneratorTarget const*> SourceSensitiveTargets;
+ std::map<cmGeneratorTarget const*, std::map<std::string, std::string> >
+ MaxLanguageStandard;
+ cmLocalGenerator *LG;
+ std::string Config;
+ std::string Language;
+ // The target whose property is being evaluated.
+ cmGeneratorTarget const* HeadTarget;
+ // The dependent of HeadTarget which appears
+ // directly or indirectly in the property.
+ cmGeneratorTarget const* CurrentTarget;
+ bool Quiet;
+ bool HadError;
+ bool HadContextSensitiveCondition;
+ bool HadHeadSensitiveCondition;
+ bool EvaluateForBuildsystem;
+};
+
+#endif
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index 92dc054c9..c3b0272ed 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -12,7 +12,8 @@
#include "cmGeneratorExpressionDAGChecker.h"
-#include "cmMakefile.h"
+#include "cmLocalGenerator.h"
+#include "cmAlgorithms.h"
//----------------------------------------------------------------------------
cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
@@ -24,6 +25,25 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
: Parent(parent), Target(target), Property(property),
Content(content), Backtrace(backtrace), TransitivePropertiesOnly(false)
{
+ Initialize();
+}
+
+//----------------------------------------------------------------------------
+cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
+ const std::string &target,
+ const std::string &property,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *parent)
+ : Parent(parent), Target(target), Property(property),
+ Content(content), Backtrace(), TransitivePropertiesOnly(false)
+{
+ Initialize();
+}
+
+//----------------------------------------------------------------------------
+void
+cmGeneratorExpressionDAGChecker::Initialize()
+{
const cmGeneratorExpressionDAGChecker *top = this;
const cmGeneratorExpressionDAGChecker *p = this->Parent;
while (p)
@@ -31,7 +51,7 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
top = p;
p = p->Parent;
}
- this->CheckResult = this->checkGraph();
+ this->CheckResult = this->CheckGraph();
#define TEST_TRANSITIVE_PROPERTY_METHOD(METHOD) \
top->METHOD () ||
@@ -40,33 +60,33 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(TEST_TRANSITIVE_PROPERTY_METHOD)
false)
)
+#undef TEST_TRANSITIVE_PROPERTY_METHOD
{
- std::map<cmStdString, std::set<cmStdString> >::const_iterator it
- = top->Seen.find(target);
+ std::map<std::string, std::set<std::string> >::const_iterator it
+ = top->Seen.find(this->Target);
if (it != top->Seen.end())
{
- const std::set<cmStdString> &propSet = it->second;
- const std::set<cmStdString>::const_iterator i = propSet.find(property);
- if (i != propSet.end())
+ const std::set<std::string> &propSet = it->second;
+ if (propSet.find(this->Property) != propSet.end())
{
this->CheckResult = ALREADY_SEEN;
return;
}
}
const_cast<cmGeneratorExpressionDAGChecker *>(top)
- ->Seen[target].insert(property);
+ ->Seen[this->Target].insert(this->Property);
}
}
//----------------------------------------------------------------------------
cmGeneratorExpressionDAGChecker::Result
-cmGeneratorExpressionDAGChecker::check() const
+cmGeneratorExpressionDAGChecker::Check() const
{
return this->CheckResult;
}
//----------------------------------------------------------------------------
-void cmGeneratorExpressionDAGChecker::reportError(
+void cmGeneratorExpressionDAGChecker::ReportError(
cmGeneratorExpressionContext *context,
const std::string &expr)
{
@@ -85,37 +105,37 @@ void cmGeneratorExpressionDAGChecker::reportError(
if (parent && !parent->Parent)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Error evaluating generator expression:\n"
<< " " << expr << "\n"
<< "Self reference on target \""
<< context->HeadTarget->GetName() << "\".\n";
- context->Makefile->GetCMakeInstance()
- ->IssueMessage(cmake::FATAL_ERROR, e.str().c_str(),
+ context->LG->GetCMakeInstance()
+ ->IssueMessage(cmake::FATAL_ERROR, e.str(),
parent->Backtrace);
return;
}
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Error evaluating generator expression:\n"
<< " " << expr << "\n"
<< "Dependency loop found.";
- context->Makefile->GetCMakeInstance()
- ->IssueMessage(cmake::FATAL_ERROR, e.str().c_str(),
+ context->LG->GetCMakeInstance()
+ ->IssueMessage(cmake::FATAL_ERROR, e.str(),
context->Backtrace);
}
int loopStep = 1;
while (parent)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Loop step " << loopStep << "\n"
<< " "
<< (parent->Content ? parent->Content->GetOriginalExpression() : expr)
<< "\n";
- context->Makefile->GetCMakeInstance()
- ->IssueMessage(cmake::FATAL_ERROR, e.str().c_str(),
+ context->LG->GetCMakeInstance()
+ ->IssueMessage(cmake::FATAL_ERROR, e.str(),
parent->Backtrace);
parent = parent->Parent;
++loopStep;
@@ -124,7 +144,7 @@ void cmGeneratorExpressionDAGChecker::reportError(
//----------------------------------------------------------------------------
cmGeneratorExpressionDAGChecker::Result
-cmGeneratorExpressionDAGChecker::checkGraph() const
+cmGeneratorExpressionDAGChecker::CheckGraph() const
{
const cmGeneratorExpressionDAGChecker *parent = this->Parent;
while (parent)
@@ -173,40 +193,54 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(const char *tgt)
return (strcmp(prop, "LINK_LIBRARIES") == 0
|| strcmp(prop, "LINK_INTERFACE_LIBRARIES") == 0
|| strcmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES") == 0
- || strncmp(prop, "LINK_INTERFACE_LIBRARIES_", 25) == 0
- || strncmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_", 34) == 0)
+ || cmHasLiteralPrefix(prop, "LINK_INTERFACE_LIBRARIES_")
+ || cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_"))
|| strcmp(prop, "INTERFACE_LINK_LIBRARIES") == 0;
}
-//----------------------------------------------------------------------------
-bool cmGeneratorExpressionDAGChecker::EvaluatingIncludeDirectories() const
+std::string cmGeneratorExpressionDAGChecker::TopTarget() const
{
- const char *prop = this->Property.c_str();
- return (strcmp(prop, "INCLUDE_DIRECTORIES") == 0
- || strcmp(prop, "INTERFACE_INCLUDE_DIRECTORIES") == 0 );
+ const cmGeneratorExpressionDAGChecker *top = this;
+ const cmGeneratorExpressionDAGChecker *parent = this->Parent;
+ while (parent)
+ {
+ top = parent;
+ parent = parent->Parent;
+ }
+ return top->Target;
}
-//----------------------------------------------------------------------------
-bool
-cmGeneratorExpressionDAGChecker::EvaluatingSystemIncludeDirectories() const
+enum TransitiveProperty {
+#define DEFINE_ENUM_ENTRY(NAME) NAME,
+ CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(DEFINE_ENUM_ENTRY)
+#undef DEFINE_ENUM_ENTRY
+ TransitivePropertyTerminal
+};
+
+template<TransitiveProperty>
+bool additionalTest(const char* const)
{
- const char *prop = this->Property.c_str();
- return strcmp(prop, "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES") == 0;
+ return false;
}
-//----------------------------------------------------------------------------
-bool cmGeneratorExpressionDAGChecker::EvaluatingCompileDefinitions() const
+template<>
+bool additionalTest<COMPILE_DEFINITIONS>(const char* const prop)
{
- const char *prop = this->Property.c_str();
- return (strcmp(prop, "COMPILE_DEFINITIONS") == 0
- || strcmp(prop, "INTERFACE_COMPILE_DEFINITIONS") == 0
- || strncmp(prop, "COMPILE_DEFINITIONS_", 20) == 0);
+ return cmHasLiteralPrefix(prop, "COMPILE_DEFINITIONS_");
}
-//----------------------------------------------------------------------------
-bool cmGeneratorExpressionDAGChecker::EvaluatingCompileOptions() const
-{
- const char *prop = this->Property.c_str();
- return (strcmp(prop, "COMPILE_OPTIONS") == 0
- || strcmp(prop, "INTERFACE_COMPILE_OPTIONS") == 0 );
+#define DEFINE_TRANSITIVE_PROPERTY_METHOD(METHOD, PROPERTY) \
+bool cmGeneratorExpressionDAGChecker::METHOD() const \
+{ \
+ const char* const prop = this->Property.c_str(); \
+ if (strcmp(prop, #PROPERTY) == 0 \
+ || strcmp(prop, "INTERFACE_" #PROPERTY) == 0) \
+ { \
+ return true; \
+ } \
+ return additionalTest<PROPERTY>(prop); \
}
+
+CM_FOR_EACH_TRANSITIVE_PROPERTY(DEFINE_TRANSITIVE_PROPERTY_METHOD)
+
+#undef DEFINE_TRANSITIVE_PROPERTY_METHOD
diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h
index 0b7ef025c..10f9fa746 100644
--- a/Source/cmGeneratorExpressionDAGChecker.h
+++ b/Source/cmGeneratorExpressionDAGChecker.h
@@ -16,17 +16,27 @@
#include "cmGeneratorExpressionEvaluator.h"
+#define CM_SELECT_BOTH(F, A1, A2) F(A1, A2)
+#define CM_SELECT_FIRST(F, A1, A2) F(A1)
+#define CM_SELECT_SECOND(F, A1, A2) F(A2)
+
+#define CM_FOR_EACH_TRANSITIVE_PROPERTY_IMPL(F, SELECT) \
+ SELECT(F, EvaluatingIncludeDirectories, INCLUDE_DIRECTORIES) \
+ SELECT(F, EvaluatingSystemIncludeDirectories, SYSTEM_INCLUDE_DIRECTORIES) \
+ SELECT(F, EvaluatingCompileDefinitions, COMPILE_DEFINITIONS) \
+ SELECT(F, EvaluatingCompileOptions, COMPILE_OPTIONS) \
+ SELECT(F, EvaluatingAutoUicOptions, AUTOUIC_OPTIONS) \
+ SELECT(F, EvaluatingSources, SOURCES) \
+ SELECT(F, EvaluatingCompileFeatures, COMPILE_FEATURES)
+
+#define CM_FOR_EACH_TRANSITIVE_PROPERTY(F) \
+ CM_FOR_EACH_TRANSITIVE_PROPERTY_IMPL(F, CM_SELECT_BOTH)
+
#define CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(F) \
- F(EvaluatingIncludeDirectories) \
- F(EvaluatingSystemIncludeDirectories) \
- F(EvaluatingCompileDefinitions) \
- F(EvaluatingCompileOptions)
+ CM_FOR_EACH_TRANSITIVE_PROPERTY_IMPL(F, CM_SELECT_FIRST)
#define CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(F) \
- F(INTERFACE_INCLUDE_DIRECTORIES) \
- F(INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) \
- F(INTERFACE_COMPILE_DEFINITIONS) \
- F(INTERFACE_COMPILE_OPTIONS)
+ CM_FOR_EACH_TRANSITIVE_PROPERTY_IMPL(F, CM_SELECT_SECOND)
//----------------------------------------------------------------------------
struct cmGeneratorExpressionDAGChecker
@@ -36,6 +46,10 @@ struct cmGeneratorExpressionDAGChecker
const std::string &property,
const GeneratorExpressionContent *content,
cmGeneratorExpressionDAGChecker *parent);
+ cmGeneratorExpressionDAGChecker(const std::string &target,
+ const std::string &property,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *parent);
enum Result {
DAG,
@@ -44,9 +58,9 @@ struct cmGeneratorExpressionDAGChecker
ALREADY_SEEN
};
- Result check() const;
+ Result Check() const;
- void reportError(cmGeneratorExpressionContext *context,
+ void ReportError(cmGeneratorExpressionContext *context,
const std::string &expr);
bool EvaluatingLinkLibraries(const char *tgt = 0);
@@ -54,20 +68,25 @@ struct cmGeneratorExpressionDAGChecker
#define DECLARE_TRANSITIVE_PROPERTY_METHOD(METHOD) \
bool METHOD () const;
-CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(DECLARE_TRANSITIVE_PROPERTY_METHOD)
+ CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(DECLARE_TRANSITIVE_PROPERTY_METHOD)
+
+#undef DECLARE_TRANSITIVE_PROPERTY_METHOD
bool GetTransitivePropertiesOnly();
void SetTransitivePropertiesOnly()
{ this->TransitivePropertiesOnly = true; }
+ std::string TopTarget() const;
+
private:
- Result checkGraph() const;
+ Result CheckGraph() const;
+ void Initialize();
private:
const cmGeneratorExpressionDAGChecker * const Parent;
const std::string Target;
const std::string Property;
- std::map<cmStdString, std::set<cmStdString> > Seen;
+ std::map<std::string, std::set<std::string> > Seen;
const GeneratorExpressionContent * const Content;
const cmListFileBacktrace Backtrace;
Result CheckResult;
diff --git a/Source/cmGeneratorExpressionEvaluationFile.cxx b/Source/cmGeneratorExpressionEvaluationFile.cxx
index cab99ed04..4ac2a0d0e 100644
--- a/Source/cmGeneratorExpressionEvaluationFile.cxx
+++ b/Source/cmGeneratorExpressionEvaluationFile.cxx
@@ -13,6 +13,11 @@
#include "cmGeneratorExpressionEvaluationFile.h"
#include "cmMakefile.h"
+#include "cmLocalGenerator.h"
+#include "cmGlobalGenerator.h"
+#include "cmSourceFile.h"
+#include "cmGeneratedFileStream.h"
+#include <cmsys/FStream.hxx>
#include <assert.h>
@@ -20,44 +25,49 @@
cmGeneratorExpressionEvaluationFile::cmGeneratorExpressionEvaluationFile(
const std::string &input,
cmsys::auto_ptr<cmCompiledGeneratorExpression> outputFileExpr,
- cmMakefile *makefile,
cmsys::auto_ptr<cmCompiledGeneratorExpression> condition,
bool inputIsContent)
: Input(input),
OutputFileExpr(outputFileExpr),
- Makefile(makefile),
Condition(condition),
InputIsContent(inputIsContent)
{
}
//----------------------------------------------------------------------------
-void cmGeneratorExpressionEvaluationFile::Generate(const char *config,
+void cmGeneratorExpressionEvaluationFile::Generate(cmLocalGenerator* lg,
+ const std::string& config,
+ const std::string& lang,
cmCompiledGeneratorExpression* inputExpression,
- std::map<std::string, std::string> &outputFiles)
+ std::map<std::string, std::string> &outputFiles, mode_t perm)
{
std::string rawCondition = this->Condition->GetInput();
if (!rawCondition.empty())
{
- std::string condResult = this->Condition->Evaluate(this->Makefile, config);
+ std::string condResult = this->Condition->Evaluate(lg,
+ config,
+ false, 0, 0, 0, lang);
if (condResult == "0")
{
return;
}
if (condResult != "1")
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Evaluation file condition \"" << rawCondition << "\" did "
"not evaluate to valid content. Got \"" << condResult << "\".";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
+ lg->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
}
const std::string outputFileName
- = this->OutputFileExpr->Evaluate(this->Makefile, config);
+ = this->OutputFileExpr->Evaluate(lg, config,
+ false, 0, 0, 0, lang);
const std::string outputContent
- = inputExpression->Evaluate(this->Makefile, config);
+ = inputExpression->Evaluate(lg,
+ config,
+ false, 0, 0, 0, lang);
std::map<std::string, std::string>::iterator it
= outputFiles.find(outputFileName);
@@ -68,34 +78,53 @@ void cmGeneratorExpressionEvaluationFile::Generate(const char *config,
{
return;
}
- cmOStringStream e;
+ std::ostringstream e;
e << "Evaluation file to be written multiple times for different "
- "configurations with different content:\n " << outputFileName;
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
+ "configurations or languages with different content:\n "
+ << outputFileName;
+ lg->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
+ lg->GetMakefile()->AddCMakeOutputFile(outputFileName.c_str());
this->Files.push_back(outputFileName);
outputFiles[outputFileName] = outputContent;
- std::ofstream fout(outputFileName.c_str());
-
- if(!fout)
+ cmGeneratedFileStream fout(outputFileName.c_str());
+ fout.SetCopyIfDifferent(true);
+ fout << outputContent;
+ if (fout.Close() && perm)
{
- cmOStringStream e;
- e << "Evaluation file \"" << outputFileName << "\" cannot be written.";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
- return;
+ cmSystemTools::SetPermissions(outputFileName.c_str(), perm);
}
+}
- fout << outputContent;
+//----------------------------------------------------------------------------
+void cmGeneratorExpressionEvaluationFile::CreateOutputFile(
+ cmLocalGenerator *lg, std::string const& config)
+{
+ std::vector<std::string> enabledLanguages;
+ cmGlobalGenerator *gg = lg->GetGlobalGenerator();
+ gg->GetEnabledLanguages(enabledLanguages);
- fout.close();
+ for(std::vector<std::string>::const_iterator le = enabledLanguages.begin();
+ le != enabledLanguages.end(); ++le)
+ {
+ std::string name = this->OutputFileExpr->Evaluate(lg,
+ config,
+ false, 0, 0, 0, *le);
+ cmSourceFile* sf = lg->GetMakefile()->GetOrCreateSource(name);
+ sf->SetProperty("GENERATED", "1");
+
+ gg->SetFilenameTargetDepends(sf,
+ this->OutputFileExpr->GetSourceSensitiveTargets());
+ }
}
//----------------------------------------------------------------------------
-void cmGeneratorExpressionEvaluationFile::Generate()
+void cmGeneratorExpressionEvaluationFile::Generate(cmLocalGenerator *lg)
{
+ mode_t perm = 0;
std::string inputContent;
if (this->InputIsContent)
{
@@ -103,12 +132,14 @@ void cmGeneratorExpressionEvaluationFile::Generate()
}
else
{
- std::ifstream fin(this->Input.c_str());
+ lg->GetMakefile()->AddCMakeDependFile(this->Input.c_str());
+ cmSystemTools::GetPermissions(this->Input.c_str(), perm);
+ cmsys::ifstream fin(this->Input.c_str());
if(!fin)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Evaluation file \"" << this->Input << "\" cannot be read.";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
+ lg->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
@@ -130,18 +161,24 @@ void cmGeneratorExpressionEvaluationFile::Generate()
std::map<std::string, std::string> outputFiles;
std::vector<std::string> allConfigs;
- this->Makefile->GetConfigurations(allConfigs);
+ lg->GetMakefile()->GetConfigurations(allConfigs);
if (allConfigs.empty())
{
- this->Generate(0, inputExpression.get(), outputFiles);
+ allConfigs.push_back("");
}
- else
+
+ std::vector<std::string> enabledLanguages;
+ cmGlobalGenerator *gg = lg->GetGlobalGenerator();
+ gg->GetEnabledLanguages(enabledLanguages);
+
+ for(std::vector<std::string>::const_iterator le = enabledLanguages.begin();
+ le != enabledLanguages.end(); ++le)
{
for(std::vector<std::string>::const_iterator li = allConfigs.begin();
li != allConfigs.end(); ++li)
{
- this->Generate(li->c_str(), inputExpression.get(), outputFiles);
+ this->Generate(lg, *li, *le, inputExpression.get(), outputFiles, perm);
if(cmSystemTools::GetFatalErrorOccured())
{
return;
diff --git a/Source/cmGeneratorExpressionEvaluationFile.h b/Source/cmGeneratorExpressionEvaluationFile.h
index 20ee5cb2d..ad41274ca 100644
--- a/Source/cmGeneratorExpressionEvaluationFile.h
+++ b/Source/cmGeneratorExpressionEvaluationFile.h
@@ -13,33 +13,37 @@
#define cmGeneratorExpressionEvaluationFile_h
#include "cmStandardIncludes.h"
+#include <sys/types.h>
#include <cmsys/auto_ptr.hxx>
#include "cmGeneratorExpression.h"
+class cmLocalGenerator;
+
//----------------------------------------------------------------------------
class cmGeneratorExpressionEvaluationFile
{
public:
cmGeneratorExpressionEvaluationFile(const std::string &input,
cmsys::auto_ptr<cmCompiledGeneratorExpression> outputFileExpr,
- cmMakefile *makefile,
cmsys::auto_ptr<cmCompiledGeneratorExpression> condition,
bool inputIsContent);
- void Generate();
+ void Generate(cmLocalGenerator* lg);
std::vector<std::string> GetFiles() const { return this->Files; }
+ void CreateOutputFile(cmLocalGenerator* lg, std::string const& config);
+
private:
- void Generate(const char *config,
- cmCompiledGeneratorExpression* inputExpression,
- std::map<std::string, std::string> &outputFiles);
+ void Generate(cmLocalGenerator* lg, const std::string& config,
+ const std::string& lang,
+ cmCompiledGeneratorExpression* inputExpression,
+ std::map<std::string, std::string> &outputFiles, mode_t perm);
private:
const std::string Input;
const cmsys::auto_ptr<cmCompiledGeneratorExpression> OutputFileExpr;
- cmMakefile *Makefile;
const cmsys::auto_ptr<cmCompiledGeneratorExpression> Condition;
std::vector<std::string> Files;
const bool InputIsContent;
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index 8b3135412..af94bcc69 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -15,1403 +15,22 @@
#include "cmGeneratorExpressionParser.h"
#include "cmGeneratorExpressionDAGChecker.h"
#include "cmGeneratorExpression.h"
+#include "cmLocalGenerator.h"
+#include "cmGlobalGenerator.h"
+#include "cmSourceFile.h"
+#include "cmAlgorithms.h"
#include <cmsys/String.h>
#include <assert.h>
+#include <errno.h>
-//----------------------------------------------------------------------------
-#if !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x510
-static
-#endif
-void reportError(cmGeneratorExpressionContext *context,
- const std::string &expr, const std::string &result)
-{
- context->HadError = true;
- if (context->Quiet)
- {
- return;
- }
-
- cmOStringStream e;
- e << "Error evaluating generator expression:\n"
- << " " << expr << "\n"
- << result;
- context->Makefile->GetCMakeInstance()
- ->IssueMessage(cmake::FATAL_ERROR, e.str().c_str(),
- context->Backtrace);
-}
-
-//----------------------------------------------------------------------------
-struct cmGeneratorExpressionNode
-{
- enum {
- DynamicParameters = 0,
- OneOrMoreParameters = -1,
- ZeroOrMoreParameters = -2
- };
- virtual ~cmGeneratorExpressionNode() {}
-
- virtual bool GeneratesContent() const { return true; }
-
- virtual bool RequiresLiteralInput() const { return false; }
-
- virtual bool AcceptsArbitraryContentParameter() const
- { return false; }
-
- virtual int NumExpectedParameters() const { return 1; }
-
- virtual std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *dagChecker
- ) const = 0;
-};
-
-//----------------------------------------------------------------------------
-static const struct ZeroNode : public cmGeneratorExpressionNode
-{
- ZeroNode() {}
-
- virtual bool GeneratesContent() const { return false; }
-
- virtual bool AcceptsArbitraryContentParameter() const { return true; }
-
- std::string Evaluate(const std::vector<std::string> &,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- // Unreachable
- return std::string();
- }
-} zeroNode;
-
-//----------------------------------------------------------------------------
-static const struct OneNode : public cmGeneratorExpressionNode
-{
- OneNode() {}
-
- virtual bool AcceptsArbitraryContentParameter() const { return true; }
-
- std::string Evaluate(const std::vector<std::string> &,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- // Unreachable
- return std::string();
- }
-} oneNode;
-
-//----------------------------------------------------------------------------
-static const struct OneNode buildInterfaceNode;
-
-//----------------------------------------------------------------------------
-static const struct ZeroNode installInterfaceNode;
-
-//----------------------------------------------------------------------------
-#define BOOLEAN_OP_NODE(OPNAME, OP, SUCCESS_VALUE, FAILURE_VALUE) \
-static const struct OP ## Node : public cmGeneratorExpressionNode \
-{ \
- OP ## Node () {} \
- virtual int NumExpectedParameters() const { return OneOrMoreParameters; } \
- \
- std::string Evaluate(const std::vector<std::string> &parameters, \
- cmGeneratorExpressionContext *context, \
- const GeneratorExpressionContent *content, \
- cmGeneratorExpressionDAGChecker *) const \
- { \
- std::vector<std::string>::const_iterator it = parameters.begin(); \
- const std::vector<std::string>::const_iterator end = parameters.end(); \
- for ( ; it != end; ++it) \
- { \
- if (*it == #FAILURE_VALUE) \
- { \
- return #FAILURE_VALUE; \
- } \
- else if (*it != #SUCCESS_VALUE) \
- { \
- reportError(context, content->GetOriginalExpression(), \
- "Parameters to $<" #OP "> must resolve to either '0' or '1'."); \
- return std::string(); \
- } \
- } \
- return #SUCCESS_VALUE; \
- } \
-} OPNAME;
-
-BOOLEAN_OP_NODE(andNode, AND, 1, 0)
-BOOLEAN_OP_NODE(orNode, OR, 0, 1)
-
-#undef BOOLEAN_OP_NODE
-
-//----------------------------------------------------------------------------
-static const struct NotNode : public cmGeneratorExpressionNode
-{
- NotNode() {}
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *) const
- {
- if (*parameters.begin() != "0" && *parameters.begin() != "1")
- {
- reportError(context, content->GetOriginalExpression(),
- "$<NOT> parameter must resolve to exactly one '0' or '1' value.");
- return std::string();
- }
- return *parameters.begin() == "0" ? "1" : "0";
- }
-} notNode;
-
-//----------------------------------------------------------------------------
-static const struct BoolNode : public cmGeneratorExpressionNode
-{
- BoolNode() {}
-
- virtual int NumExpectedParameters() const { return 1; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- return !cmSystemTools::IsOff(parameters.begin()->c_str()) ? "1" : "0";
- }
-} boolNode;
-
-//----------------------------------------------------------------------------
-static const struct StrEqualNode : public cmGeneratorExpressionNode
-{
- StrEqualNode() {}
-
- virtual int NumExpectedParameters() const { return 2; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- return *parameters.begin() == parameters[1] ? "1" : "0";
- }
-} strEqualNode;
-
-//----------------------------------------------------------------------------
-static const struct Angle_RNode : public cmGeneratorExpressionNode
-{
- Angle_RNode() {}
-
- virtual int NumExpectedParameters() const { return 0; }
-
- std::string Evaluate(const std::vector<std::string> &,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- return ">";
- }
-} angle_rNode;
-
-//----------------------------------------------------------------------------
-static const struct CommaNode : public cmGeneratorExpressionNode
-{
- CommaNode() {}
-
- virtual int NumExpectedParameters() const { return 0; }
-
- std::string Evaluate(const std::vector<std::string> &,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- return ",";
- }
-} commaNode;
-
-//----------------------------------------------------------------------------
-static const struct SemicolonNode : public cmGeneratorExpressionNode
-{
- SemicolonNode() {}
-
- virtual int NumExpectedParameters() const { return 0; }
-
- std::string Evaluate(const std::vector<std::string> &,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- return ";";
- }
-} semicolonNode;
-
-//----------------------------------------------------------------------------
-struct CompilerIdNode : public cmGeneratorExpressionNode
-{
- CompilerIdNode() {}
-
- virtual int NumExpectedParameters() const { return ZeroOrMoreParameters; }
-
- std::string EvaluateWithLanguage(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *,
- const std::string &lang) const
- {
- const char *compilerId = context->Makefile ?
- context->Makefile->GetSafeDefinition((
- "CMAKE_" + lang + "_COMPILER_ID").c_str()) : "";
- if (parameters.size() == 0)
- {
- return compilerId ? compilerId : "";
- }
- cmsys::RegularExpression compilerIdValidator;
- compilerIdValidator.compile("^[A-Za-z0-9_]*$");
- if (!compilerIdValidator.find(parameters.begin()->c_str()))
- {
- reportError(context, content->GetOriginalExpression(),
- "Expression syntax not recognized.");
- return std::string();
- }
- if (!compilerId)
- {
- return parameters.front().empty() ? "1" : "0";
- }
-
- if (cmsysString_strcasecmp(parameters.begin()->c_str(), compilerId) == 0)
- {
- return "1";
- }
- return "0";
- }
-};
-
-//----------------------------------------------------------------------------
-static const struct CCompilerIdNode : public CompilerIdNode
-{
- CCompilerIdNode() {}
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *dagChecker) const
- {
- if (parameters.size() != 0 && parameters.size() != 1)
- {
- reportError(context, content->GetOriginalExpression(),
- "$<C_COMPILER_ID> expression requires one or two parameters");
- return std::string();
- }
- if (!context->HeadTarget)
- {
- reportError(context, content->GetOriginalExpression(),
- "$<C_COMPILER_ID> may only be used with targets. It may not "
- "be used with add_custom_command.");
- }
- return this->EvaluateWithLanguage(parameters, context, content,
- dagChecker, "C");
- }
-} cCompilerIdNode;
-
-//----------------------------------------------------------------------------
-static const struct CXXCompilerIdNode : public CompilerIdNode
-{
- CXXCompilerIdNode() {}
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *dagChecker) const
- {
- if (parameters.size() != 0 && parameters.size() != 1)
- {
- reportError(context, content->GetOriginalExpression(),
- "$<CXX_COMPILER_ID> expression requires one or two parameters");
- return std::string();
- }
- if (!context->HeadTarget)
- {
- reportError(context, content->GetOriginalExpression(),
- "$<CXX_COMPILER_ID> may only be used with targets. It may not "
- "be used with add_custom_command.");
- }
- return this->EvaluateWithLanguage(parameters, context, content,
- dagChecker, "CXX");
- }
-} cxxCompilerIdNode;
-
-//----------------------------------------------------------------------------
-struct CompilerVersionNode : public cmGeneratorExpressionNode
-{
- CompilerVersionNode() {}
-
- virtual int NumExpectedParameters() const { return ZeroOrMoreParameters; }
-
- std::string EvaluateWithLanguage(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *,
- const std::string &lang) const
- {
- const char *compilerVersion = context->Makefile ?
- context->Makefile->GetSafeDefinition((
- "CMAKE_" + lang + "_COMPILER_VERSION").c_str()) : "";
- if (parameters.size() == 0)
- {
- return compilerVersion ? compilerVersion : "";
- }
-
- cmsys::RegularExpression compilerIdValidator;
- compilerIdValidator.compile("^[0-9\\.]*$");
- if (!compilerIdValidator.find(parameters.begin()->c_str()))
- {
- reportError(context, content->GetOriginalExpression(),
- "Expression syntax not recognized.");
- return std::string();
- }
- if (!compilerVersion)
- {
- return parameters.front().empty() ? "1" : "0";
- }
-
- return cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL,
- parameters.begin()->c_str(),
- compilerVersion) ? "1" : "0";
- }
-};
-
-//----------------------------------------------------------------------------
-static const struct CCompilerVersionNode : public CompilerVersionNode
-{
- CCompilerVersionNode() {}
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *dagChecker) const
- {
- if (parameters.size() != 0 && parameters.size() != 1)
- {
- reportError(context, content->GetOriginalExpression(),
- "$<C_COMPILER_VERSION> expression requires one or two parameters");
- return std::string();
- }
- if (!context->HeadTarget)
- {
- reportError(context, content->GetOriginalExpression(),
- "$<C_COMPILER_VERSION> may only be used with targets. It may not "
- "be used with add_custom_command.");
- }
- return this->EvaluateWithLanguage(parameters, context, content,
- dagChecker, "C");
- }
-} cCompilerVersionNode;
-
-//----------------------------------------------------------------------------
-static const struct CxxCompilerVersionNode : public CompilerVersionNode
-{
- CxxCompilerVersionNode() {}
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *dagChecker) const
- {
- if (parameters.size() != 0 && parameters.size() != 1)
- {
- reportError(context, content->GetOriginalExpression(),
- "$<CXX_COMPILER_VERSION> expression requires one or two "
- "parameters");
- return std::string();
- }
- if (!context->HeadTarget)
- {
- reportError(context, content->GetOriginalExpression(),
- "$<CXX_COMPILER_VERSION> may only be used with targets. It may "
- "not be used with add_custom_command.");
- }
- return this->EvaluateWithLanguage(parameters, context, content,
- dagChecker, "CXX");
- }
-} cxxCompilerVersionNode;
-
-
-//----------------------------------------------------------------------------
-static const struct VersionGreaterNode : public cmGeneratorExpressionNode
-{
- VersionGreaterNode() {}
-
- virtual int NumExpectedParameters() const { return 2; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- return cmSystemTools::VersionCompare(cmSystemTools::OP_GREATER,
- parameters.front().c_str(),
- parameters[1].c_str()) ? "1" : "0";
- }
-} versionGreaterNode;
-
-//----------------------------------------------------------------------------
-static const struct VersionLessNode : public cmGeneratorExpressionNode
-{
- VersionLessNode() {}
-
- virtual int NumExpectedParameters() const { return 2; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- return cmSystemTools::VersionCompare(cmSystemTools::OP_LESS,
- parameters.front().c_str(),
- parameters[1].c_str()) ? "1" : "0";
- }
-} versionLessNode;
-
-//----------------------------------------------------------------------------
-static const struct VersionEqualNode : public cmGeneratorExpressionNode
-{
- VersionEqualNode() {}
-
- virtual int NumExpectedParameters() const { return 2; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- return cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL,
- parameters.front().c_str(),
- parameters[1].c_str()) ? "1" : "0";
- }
-} versionEqualNode;
-
-//----------------------------------------------------------------------------
-static const struct LinkOnlyNode : public cmGeneratorExpressionNode
-{
- LinkOnlyNode() {}
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *dagChecker) const
- {
- if(!dagChecker->GetTransitivePropertiesOnly())
- {
- return parameters.front();
- }
- return "";
- }
-} linkOnlyNode;
-
-//----------------------------------------------------------------------------
-static const struct ConfigurationNode : public cmGeneratorExpressionNode
-{
- ConfigurationNode() {}
-
- virtual int NumExpectedParameters() const { return 0; }
-
- std::string Evaluate(const std::vector<std::string> &,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- context->HadContextSensitiveCondition = true;
- return context->Config ? context->Config : "";
- }
-} configurationNode;
-
-//----------------------------------------------------------------------------
-static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
-{
- ConfigurationTestNode() {}
-
- virtual int NumExpectedParameters() const { return 1; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *) const
- {
- cmsys::RegularExpression configValidator;
- configValidator.compile("^[A-Za-z0-9_]*$");
- if (!configValidator.find(parameters.begin()->c_str()))
- {
- reportError(context, content->GetOriginalExpression(),
- "Expression syntax not recognized.");
- return std::string();
- }
- context->HadContextSensitiveCondition = true;
- if (!context->Config)
- {
- return parameters.front().empty() ? "1" : "0";
- }
-
- if (cmsysString_strcasecmp(parameters.begin()->c_str(),
- context->Config) == 0)
- {
- return "1";
- }
-
- if (context->CurrentTarget
- && context->CurrentTarget->IsImported())
- {
- const char* loc = 0;
- const char* imp = 0;
- std::string suffix;
- if (context->CurrentTarget->GetMappedConfig(context->Config,
- &loc,
- &imp,
- suffix))
- {
- // This imported target has an appropriate location
- // for this (possibly mapped) config.
- // Check if there is a proper config mapping for the tested config.
- std::vector<std::string> mappedConfigs;
- std::string mapProp = "MAP_IMPORTED_CONFIG_";
- mapProp += cmSystemTools::UpperCase(context->Config);
- if(const char* mapValue =
- context->CurrentTarget->GetProperty(mapProp.c_str()))
- {
- cmSystemTools::ExpandListArgument(cmSystemTools::UpperCase(mapValue),
- mappedConfigs);
- return std::find(mappedConfigs.begin(), mappedConfigs.end(),
- cmSystemTools::UpperCase(parameters.front()))
- != mappedConfigs.end() ? "1" : "0";
- }
- }
- }
- return "0";
- }
-} configurationTestNode;
-
-static const struct JoinNode : public cmGeneratorExpressionNode
-{
- JoinNode() {}
-
- virtual int NumExpectedParameters() const { return 2; }
-
- virtual bool AcceptsArbitraryContentParameter() const { return true; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- std::string result;
-
- std::vector<std::string> list;
- cmSystemTools::ExpandListArgument(parameters.front(), list);
- std::string sep;
- for(std::vector<std::string>::const_iterator li = list.begin();
- li != list.end(); ++li)
- {
- result += sep + *li;
- sep = parameters[1];
- }
- return result;
- }
-} joinNode;
-
-#define TRANSITIVE_PROPERTY_NAME(PROPERTY) \
- , #PROPERTY
-
-//----------------------------------------------------------------------------
-static const char* targetPropertyTransitiveWhitelist[] = {
- 0
- CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(TRANSITIVE_PROPERTY_NAME)
-};
-
-std::string getLinkedTargetsContent(const std::vector<std::string> &libraries,
- cmTarget *target,
- cmTarget *headTarget,
- cmGeneratorExpressionContext *context,
- cmGeneratorExpressionDAGChecker *dagChecker,
- const std::string &interfacePropertyName)
-{
- cmGeneratorExpression ge(context->Backtrace);
-
- std::string sep;
- std::string depString;
- for (std::vector<std::string>::const_iterator
- it = libraries.begin();
- it != libraries.end(); ++it)
- {
- if (*it == target->GetName())
- {
- // Broken code can have a target in its own link interface.
- // Don't follow such link interface entries so as not to create a
- // self-referencing loop.
- continue;
- }
- if (context->Makefile->FindTargetToUse(it->c_str()))
- {
- depString +=
- sep + "$<TARGET_PROPERTY:" + *it + "," + interfacePropertyName + ">";
- sep = ";";
- }
- }
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(depString);
- std::string linkedTargetsContent = cge->Evaluate(context->Makefile,
- context->Config,
- context->Quiet,
- headTarget,
- target,
- dagChecker);
- if (cge->GetHadContextSensitiveCondition())
- {
- context->HadContextSensitiveCondition = true;
- }
- return linkedTargetsContent;
-}
-
-//----------------------------------------------------------------------------
-struct TransitiveWhitelistCompare
-{
- explicit TransitiveWhitelistCompare(const std::string &needle)
- : Needle(needle) {}
- bool operator() (const char *item)
- { return strcmp(item, this->Needle.c_str()) == 0; }
-private:
- std::string Needle;
-};
-
-//----------------------------------------------------------------------------
-static const struct TargetPropertyNode : public cmGeneratorExpressionNode
-{
- TargetPropertyNode() {}
-
- // This node handles errors on parameter count itself.
- virtual int NumExpectedParameters() const { return OneOrMoreParameters; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *dagCheckerParent
- ) const
- {
- if (parameters.size() != 1 && parameters.size() != 2)
- {
- reportError(context, content->GetOriginalExpression(),
- "$<TARGET_PROPERTY:...> expression requires one or two parameters");
- return std::string();
- }
- cmsys::RegularExpression propertyNameValidator;
- propertyNameValidator.compile("^[A-Za-z0-9_]+$");
-
- cmTarget* target = context->HeadTarget;
- std::string propertyName = *parameters.begin();
-
- if (!target && parameters.size() == 1)
- {
- reportError(context, content->GetOriginalExpression(),
- "$<TARGET_PROPERTY:prop> may only be used with targets. It may not "
- "be used with add_custom_command. Specify the target to read a "
- "property from using the $<TARGET_PROPERTY:tgt,prop> signature "
- "instead.");
- return std::string();
- }
-
- if (parameters.size() == 2)
- {
- if (parameters.begin()->empty() && parameters[1].empty())
- {
- reportError(context, content->GetOriginalExpression(),
- "$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty "
- "target name and property name.");
- return std::string();
- }
- if (parameters.begin()->empty())
- {
- reportError(context, content->GetOriginalExpression(),
- "$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty "
- "target name.");
- return std::string();
- }
-
- std::string targetName = parameters.front();
- propertyName = parameters[1];
- if (!cmGeneratorExpression::IsValidTargetName(targetName))
- {
- if (!propertyNameValidator.find(propertyName.c_str()))
- {
- ::reportError(context, content->GetOriginalExpression(),
- "Target name and property name not supported.");
- return std::string();
- }
- ::reportError(context, content->GetOriginalExpression(),
- "Target name not supported.");
- return std::string();
- }
- if(propertyName == "ALIASED_TARGET")
- {
- if(context->Makefile->IsAlias(targetName.c_str()))
- {
- if(cmTarget* tgt =
- context->Makefile->FindTargetToUse(targetName.c_str()))
- {
- return tgt->GetName();
- }
- }
- return "";
- }
- target = context->Makefile->FindTargetToUse(
- targetName.c_str());
-
- if (!target)
- {
- cmOStringStream e;
- e << "Target \""
- << targetName
- << "\" not found.";
- reportError(context, content->GetOriginalExpression(), e.str());
- return std::string();
- }
- context->AllTargets.insert(target);
- }
-
- if (target == context->HeadTarget)
- {
- // Keep track of the properties seen while processing.
- // The evaluation of the LINK_LIBRARIES generator expressions
- // will check this to ensure that properties have one consistent
- // value for all evaluations.
- context->SeenTargetProperties.insert(propertyName);
- }
-
- if (propertyName.empty())
- {
- reportError(context, content->GetOriginalExpression(),
- "$<TARGET_PROPERTY:...> expression requires a non-empty property "
- "name.");
- return std::string();
- }
-
- if (!propertyNameValidator.find(propertyName.c_str()))
- {
- ::reportError(context, content->GetOriginalExpression(),
- "Property name not supported.");
- return std::string();
- }
-
- assert(target);
-
- if (propertyName == "LINKER_LANGUAGE")
- {
- if (target->LinkLanguagePropagatesToDependents() &&
- dagCheckerParent && dagCheckerParent->EvaluatingLinkLibraries())
- {
- reportError(context, content->GetOriginalExpression(),
- "LINKER_LANGUAGE target property can not be used while evaluating "
- "link libraries for a static library");
- return std::string();
- }
- const char *lang = target->GetLinkerLanguage(context->Config);
- return lang ? lang : "";
- }
-
- cmGeneratorExpressionDAGChecker dagChecker(context->Backtrace,
- target->GetName(),
- propertyName,
- content,
- dagCheckerParent);
-
- switch (dagChecker.check())
- {
- case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
- dagChecker.reportError(context, content->GetOriginalExpression());
- return std::string();
- case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
- // No error. We just skip cyclic references.
- return std::string();
- case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
- for (size_t i = 1;
- i < (sizeof(targetPropertyTransitiveWhitelist) /
- sizeof(*targetPropertyTransitiveWhitelist));
- ++i)
- {
- if (targetPropertyTransitiveWhitelist[i] == propertyName)
- {
- // No error. We're not going to find anything new here.
- return std::string();
- }
- }
- case cmGeneratorExpressionDAGChecker::DAG:
- break;
- }
-
- const char *prop = target->GetProperty(propertyName.c_str());
-
- if (dagCheckerParent)
- {
- if (dagCheckerParent->EvaluatingLinkLibraries())
- {
- if(!prop)
- {
- return std::string();
- }
- }
- else
- {
-#define ASSERT_TRANSITIVE_PROPERTY_METHOD(METHOD) \
- dagCheckerParent->METHOD () ||
-
- assert(
- CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(
- ASSERT_TRANSITIVE_PROPERTY_METHOD)
- false);
- }
- }
-
- std::string linkedTargetsContent;
-
- std::string interfacePropertyName;
-
- if (propertyName == "INTERFACE_INCLUDE_DIRECTORIES"
- || propertyName == "INCLUDE_DIRECTORIES")
- {
- interfacePropertyName = "INTERFACE_INCLUDE_DIRECTORIES";
- }
- else if (propertyName == "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES")
- {
- interfacePropertyName = "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES";
- }
- else if (propertyName == "INTERFACE_COMPILE_DEFINITIONS"
- || propertyName == "COMPILE_DEFINITIONS"
- || strncmp(propertyName.c_str(), "COMPILE_DEFINITIONS_", 20) == 0)
- {
- interfacePropertyName = "INTERFACE_COMPILE_DEFINITIONS";
- }
- else if (propertyName == "INTERFACE_COMPILE_OPTIONS"
- || propertyName == "COMPILE_OPTIONS")
- {
- interfacePropertyName = "INTERFACE_COMPILE_OPTIONS";
- }
-
- cmTarget *headTarget = context->HeadTarget ? context->HeadTarget : target;
-
- const char **transBegin = targetPropertyTransitiveWhitelist + 1;
- const char **transEnd = targetPropertyTransitiveWhitelist
- + (sizeof(targetPropertyTransitiveWhitelist) /
- sizeof(*targetPropertyTransitiveWhitelist));
- if (std::find_if(transBegin, transEnd,
- TransitiveWhitelistCompare(propertyName)) != transEnd)
- {
-
- std::vector<std::string> libs;
- target->GetTransitivePropertyLinkLibraries(context->Config,
- headTarget, libs);
- if (!libs.empty())
- {
- linkedTargetsContent =
- getLinkedTargetsContent(libs, target,
- headTarget,
- context, &dagChecker,
- interfacePropertyName);
- }
- }
- else if (std::find_if(transBegin, transEnd,
- TransitiveWhitelistCompare(interfacePropertyName)) != transEnd)
- {
- const cmTarget::LinkImplementation *impl = target->GetLinkImplementation(
- context->Config,
- headTarget);
- if(impl)
- {
- linkedTargetsContent =
- getLinkedTargetsContent(impl->Libraries, target,
- headTarget,
- context, &dagChecker,
- interfacePropertyName);
- }
- }
-
- linkedTargetsContent =
- cmGeneratorExpression::StripEmptyListElements(linkedTargetsContent);
-
- if (!prop)
- {
- if (target->IsImported())
- {
- return linkedTargetsContent;
- }
- if (target->IsLinkInterfaceDependentBoolProperty(propertyName,
- context->Config))
- {
- context->HadContextSensitiveCondition = true;
- return target->GetLinkInterfaceDependentBoolProperty(
- propertyName,
- context->Config) ? "1" : "0";
- }
- if (target->IsLinkInterfaceDependentStringProperty(propertyName,
- context->Config))
- {
- context->HadContextSensitiveCondition = true;
- const char *propContent =
- target->GetLinkInterfaceDependentStringProperty(
- propertyName,
- context->Config);
- return propContent ? propContent : "";
- }
-
- return linkedTargetsContent;
- }
-
- for (size_t i = 1;
- i < (sizeof(targetPropertyTransitiveWhitelist) /
- sizeof(*targetPropertyTransitiveWhitelist));
- ++i)
- {
- if (targetPropertyTransitiveWhitelist[i] == interfacePropertyName)
- {
- cmGeneratorExpression ge(context->Backtrace);
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
- std::string result = cge->Evaluate(context->Makefile,
- context->Config,
- context->Quiet,
- headTarget,
- target,
- &dagChecker);
-
- if (cge->GetHadContextSensitiveCondition())
- {
- context->HadContextSensitiveCondition = true;
- }
- if (!linkedTargetsContent.empty())
- {
- result += (result.empty() ? "" : ";") + linkedTargetsContent;
- }
- return result;
- }
- }
- return prop;
- }
-} targetPropertyNode;
-
-//----------------------------------------------------------------------------
-static const struct TargetNameNode : public cmGeneratorExpressionNode
-{
- TargetNameNode() {}
-
- virtual bool GeneratesContent() const { return true; }
-
- virtual bool AcceptsArbitraryContentParameter() const { return true; }
- virtual bool RequiresLiteralInput() const { return true; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- return parameters.front();
- }
-
- virtual int NumExpectedParameters() const { return 1; }
-
-} targetNameNode;
-
-//----------------------------------------------------------------------------
-static const char* targetPolicyWhitelist[] = {
- 0
-#define TARGET_POLICY_STRING(POLICY) \
- , #POLICY
-
- CM_FOR_EACH_TARGET_POLICY(TARGET_POLICY_STRING)
-
-#undef TARGET_POLICY_STRING
-};
-
-cmPolicies::PolicyStatus statusForTarget(cmTarget *tgt, const char *policy)
-{
-#define RETURN_POLICY(POLICY) \
- if (strcmp(policy, #POLICY) == 0) \
- { \
- return tgt->GetPolicyStatus ## POLICY (); \
- } \
-
- CM_FOR_EACH_TARGET_POLICY(RETURN_POLICY)
-
-#undef RETURN_POLICY
-
- assert("!Unreachable code. Not a valid policy");
- return cmPolicies::WARN;
-}
-
-cmPolicies::PolicyID policyForString(const char *policy_id)
-{
-#define RETURN_POLICY_ID(POLICY_ID) \
- if (strcmp(policy_id, #POLICY_ID) == 0) \
- { \
- return cmPolicies:: POLICY_ID; \
- } \
-
- CM_FOR_EACH_TARGET_POLICY(RETURN_POLICY_ID)
-
-#undef RETURN_POLICY_ID
-
- assert("!Unreachable code. Not a valid policy");
- return cmPolicies::CMP0002;
-}
-
-//----------------------------------------------------------------------------
-static const struct TargetPolicyNode : public cmGeneratorExpressionNode
-{
- TargetPolicyNode() {}
-
- virtual int NumExpectedParameters() const { return 1; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context ,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *) const
- {
- if (!context->HeadTarget)
- {
- reportError(context, content->GetOriginalExpression(),
- "$<TARGET_POLICY:prop> may only be used with targets. It may not "
- "be used with add_custom_command.");
- return std::string();
- }
-
- context->HadContextSensitiveCondition = true;
-
- for (size_t i = 1;
- i < (sizeof(targetPolicyWhitelist) /
- sizeof(*targetPolicyWhitelist));
- ++i)
- {
- const char *policy = targetPolicyWhitelist[i];
- if (parameters.front() == policy)
- {
- cmMakefile *mf = context->HeadTarget->GetMakefile();
- switch(statusForTarget(context->HeadTarget, policy))
- {
- case cmPolicies::WARN:
- mf->IssueMessage(cmake::AUTHOR_WARNING,
- mf->GetPolicies()->
- GetPolicyWarning(policyForString(policy)));
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::OLD:
- return "0";
- case cmPolicies::NEW:
- return "1";
- }
- }
- }
- reportError(context, content->GetOriginalExpression(),
- "$<TARGET_POLICY:prop> may only be used with a limited number of "
- "policies. Currently it may be used with the following policies:\n"
-
-#define STRINGIFY_HELPER(X) #X
-#define STRINGIFY(X) STRINGIFY_HELPER(X)
-
-#define TARGET_POLICY_LIST_ITEM(POLICY) \
- " * " STRINGIFY(POLICY) "\n"
-
- CM_FOR_EACH_TARGET_POLICY(TARGET_POLICY_LIST_ITEM)
-
-#undef TARGET_POLICY_LIST_ITEM
- );
- return std::string();
- }
-
-} targetPolicyNode;
-
-//----------------------------------------------------------------------------
-static const struct InstallPrefixNode : public cmGeneratorExpressionNode
-{
- InstallPrefixNode() {}
-
- virtual bool GeneratesContent() const { return true; }
- virtual int NumExpectedParameters() const { return 0; }
-
- std::string Evaluate(const std::vector<std::string> &,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *) const
- {
- reportError(context, content->GetOriginalExpression(),
- "INSTALL_PREFIX is a marker for install(EXPORT) only. It "
- "should never be evaluated.");
- return std::string();
- }
-
-} installPrefixNode;
-
-//----------------------------------------------------------------------------
-template<bool linker, bool soname>
-struct TargetFilesystemArtifactResultCreator
-{
- static std::string Create(cmTarget* target,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content);
-};
-
-//----------------------------------------------------------------------------
-template<>
-struct TargetFilesystemArtifactResultCreator<false, true>
-{
- static std::string Create(cmTarget* target,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content)
- {
- // The target soname file (.so.1).
- if(target->IsDLLPlatform())
- {
- ::reportError(context, content->GetOriginalExpression(),
- "TARGET_SONAME_FILE is not allowed "
- "for DLL target platforms.");
- return std::string();
- }
- if(target->GetType() != cmTarget::SHARED_LIBRARY)
- {
- ::reportError(context, content->GetOriginalExpression(),
- "TARGET_SONAME_FILE is allowed only for "
- "SHARED libraries.");
- return std::string();
- }
- std::string result = target->GetDirectory(context->Config);
- result += "/";
- result += target->GetSOName(context->Config);
- return result;
- }
-};
-
-//----------------------------------------------------------------------------
-template<>
-struct TargetFilesystemArtifactResultCreator<true, false>
-{
- static std::string Create(cmTarget* target,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content)
- {
- // The file used to link to the target (.so, .lib, .a).
- if(!target->IsLinkable())
- {
- ::reportError(context, content->GetOriginalExpression(),
- "TARGET_LINKER_FILE is allowed only for libraries and "
- "executables with ENABLE_EXPORTS.");
- return std::string();
- }
- return target->GetFullPath(context->Config,
- target->HasImportLibrary());
- }
-};
-
-//----------------------------------------------------------------------------
-template<>
-struct TargetFilesystemArtifactResultCreator<false, false>
-{
- static std::string Create(cmTarget* target,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *)
- {
- return target->GetFullPath(context->Config, false, true);
- }
-};
-
-
-//----------------------------------------------------------------------------
-template<bool dirQual, bool nameQual>
-struct TargetFilesystemArtifactResultGetter
-{
- static std::string Get(const std::string &result);
-};
-
-//----------------------------------------------------------------------------
-template<>
-struct TargetFilesystemArtifactResultGetter<false, true>
-{
- static std::string Get(const std::string &result)
- { return cmSystemTools::GetFilenameName(result); }
-};
-
-//----------------------------------------------------------------------------
-template<>
-struct TargetFilesystemArtifactResultGetter<true, false>
-{
- static std::string Get(const std::string &result)
- { return cmSystemTools::GetFilenamePath(result); }
-};
-
-//----------------------------------------------------------------------------
-template<>
-struct TargetFilesystemArtifactResultGetter<false, false>
-{
- static std::string Get(const std::string &result)
- { return result; }
-};
-
-//----------------------------------------------------------------------------
-template<bool linker, bool soname, bool dirQual, bool nameQual>
-struct TargetFilesystemArtifact : public cmGeneratorExpressionNode
-{
- TargetFilesystemArtifact() {}
-
- virtual int NumExpectedParameters() const { return 1; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *dagChecker) const
- {
- // Lookup the referenced target.
- std::string name = *parameters.begin();
-
- if (!cmGeneratorExpression::IsValidTargetName(name))
- {
- ::reportError(context, content->GetOriginalExpression(),
- "Expression syntax not recognized.");
- return std::string();
- }
- cmTarget* target = context->Makefile->FindTargetToUse(name.c_str());
- if(!target)
- {
- ::reportError(context, content->GetOriginalExpression(),
- "No target \"" + name + "\"");
- return std::string();
- }
- if(target->GetType() >= cmTarget::OBJECT_LIBRARY &&
- target->GetType() != cmTarget::UNKNOWN_LIBRARY)
- {
- ::reportError(context, content->GetOriginalExpression(),
- "Target \"" + name + "\" is not an executable or library.");
- return std::string();
- }
- if (dagChecker && dagChecker->EvaluatingLinkLibraries(name.c_str()))
- {
- ::reportError(context, content->GetOriginalExpression(),
- "Expressions which require the linker language may not "
- "be used while evaluating link libraries");
- return std::string();
- }
- context->DependTargets.insert(target);
- context->AllTargets.insert(target);
-
- std::string result =
- TargetFilesystemArtifactResultCreator<linker, soname>::Create(
- target,
- context,
- content);
- if (context->HadError)
- {
- return std::string();
- }
- return
- TargetFilesystemArtifactResultGetter<dirQual, nameQual>::Get(result);
- }
-};
-
-//----------------------------------------------------------------------------
-static const
-TargetFilesystemArtifact<false, false, false, false> targetFileNode;
-static const
-TargetFilesystemArtifact<true, false, false, false> targetLinkerFileNode;
-static const
-TargetFilesystemArtifact<false, true, false, false> targetSoNameFileNode;
-static const
-TargetFilesystemArtifact<false, false, false, true> targetFileNameNode;
-static const
-TargetFilesystemArtifact<true, false, false, true> targetLinkerFileNameNode;
-static const
-TargetFilesystemArtifact<false, true, false, true> targetSoNameFileNameNode;
-static const
-TargetFilesystemArtifact<false, false, true, false> targetFileDirNode;
-static const
-TargetFilesystemArtifact<true, false, true, false> targetLinkerFileDirNode;
-static const
-TargetFilesystemArtifact<false, true, true, false> targetSoNameFileDirNode;
-
-//----------------------------------------------------------------------------
-static const
-cmGeneratorExpressionNode* GetNode(const std::string &identifier)
-{
- if (identifier == "0")
- return &zeroNode;
- else if (identifier == "1")
- return &oneNode;
- else if (identifier == "AND")
- return &andNode;
- else if (identifier == "OR")
- return &orNode;
- else if (identifier == "NOT")
- return &notNode;
- else if (identifier == "C_COMPILER_ID")
- return &cCompilerIdNode;
- else if (identifier == "CXX_COMPILER_ID")
- return &cxxCompilerIdNode;
- else if (identifier == "VERSION_GREATER")
- return &versionGreaterNode;
- else if (identifier == "VERSION_LESS")
- return &versionLessNode;
- else if (identifier == "VERSION_EQUAL")
- return &versionEqualNode;
- else if (identifier == "C_COMPILER_VERSION")
- return &cCompilerVersionNode;
- else if (identifier == "CXX_COMPILER_VERSION")
- return &cxxCompilerVersionNode;
- else if (identifier == "CONFIGURATION")
- return &configurationNode;
- else if (identifier == "CONFIG")
- return &configurationTestNode;
- else if (identifier == "TARGET_FILE")
- return &targetFileNode;
- else if (identifier == "TARGET_LINKER_FILE")
- return &targetLinkerFileNode;
- else if (identifier == "TARGET_SONAME_FILE")
- return &targetSoNameFileNode;
- else if (identifier == "TARGET_FILE_NAME")
- return &targetFileNameNode;
- else if (identifier == "TARGET_LINKER_FILE_NAME")
- return &targetLinkerFileNameNode;
- else if (identifier == "TARGET_SONAME_FILE_NAME")
- return &targetSoNameFileNameNode;
- else if (identifier == "TARGET_FILE_DIR")
- return &targetFileDirNode;
- else if (identifier == "TARGET_LINKER_FILE_DIR")
- return &targetLinkerFileDirNode;
- else if (identifier == "TARGET_SONAME_FILE_DIR")
- return &targetSoNameFileDirNode;
- else if (identifier == "STREQUAL")
- return &strEqualNode;
- else if (identifier == "BOOL")
- return &boolNode;
- else if (identifier == "ANGLE-R")
- return &angle_rNode;
- else if (identifier == "COMMA")
- return &commaNode;
- else if (identifier == "SEMICOLON")
- return &semicolonNode;
- else if (identifier == "TARGET_PROPERTY")
- return &targetPropertyNode;
- else if (identifier == "TARGET_NAME")
- return &targetNameNode;
- else if (identifier == "TARGET_POLICY")
- return &targetPolicyNode;
- else if (identifier == "BUILD_INTERFACE")
- return &buildInterfaceNode;
- else if (identifier == "INSTALL_INTERFACE")
- return &installInterfaceNode;
- else if (identifier == "INSTALL_PREFIX")
- return &installPrefixNode;
- else if (identifier == "JOIN")
- return &joinNode;
- else if (identifier == "LINK_ONLY")
- return &linkOnlyNode;
- return 0;
-
-}
+#include "cmGeneratorExpressionNode.h"
//----------------------------------------------------------------------------
GeneratorExpressionContent::GeneratorExpressionContent(
const char *startContent,
- unsigned int length)
+ size_t length)
: StartContent(startContent), ContentLength(length)
{
@@ -1495,7 +114,8 @@ std::string GeneratorExpressionContent::Evaluate(
}
}
- const cmGeneratorExpressionNode *node = GetNode(identifier);
+ const cmGeneratorExpressionNode *node =
+ cmGeneratorExpressionNode::GetNode(identifier);
if (!node)
{
@@ -1524,14 +144,6 @@ std::string GeneratorExpressionContent::Evaluate(
return std::string();
}
- if (node->NumExpectedParameters() == 1
- && node->AcceptsArbitraryContentParameter())
- {
- return this->ProcessArbitraryContent(node, identifier, context,
- dagChecker,
- this->ParamChildren.begin());
- }
-
std::vector<std::string> parameters;
this->EvaluateParameters(node, identifier, context, dagChecker, parameters);
if (context->HadError)
@@ -1559,33 +171,35 @@ std::string GeneratorExpressionContent::EvaluateParameters(
pend = this->ParamChildren.end();
const bool acceptsArbitraryContent
= node->AcceptsArbitraryContentParameter();
- for ( ; pit != pend; ++pit)
+ int counter = 1;
+ for ( ; pit != pend; ++pit, ++counter)
{
- std::string parameter;
- std::vector<cmGeneratorExpressionEvaluator*>::const_iterator it =
- pit->begin();
- const std::vector<cmGeneratorExpressionEvaluator*>::const_iterator end =
- pit->end();
- for ( ; it != end; ++it)
+ if (acceptsArbitraryContent && counter == numExpected)
{
- parameter += (*it)->Evaluate(context, dagChecker);
- if (context->HadError)
- {
- return std::string();
- }
- }
- parameters.push_back(parameter);
- if (acceptsArbitraryContent
- && parameters.size() == (unsigned int)numExpected - 1)
- {
- assert(pit != pend);
std::string lastParam = this->ProcessArbitraryContent(node, identifier,
context,
dagChecker,
- pit + 1);
+ pit);
parameters.push_back(lastParam);
return std::string();
}
+ else
+ {
+ std::string parameter;
+ std::vector<cmGeneratorExpressionEvaluator*>::const_iterator it =
+ pit->begin();
+ const std::vector<cmGeneratorExpressionEvaluator*>::const_iterator end =
+ pit->end();
+ for ( ; it != end; ++it)
+ {
+ parameter += (*it)->Evaluate(context, dagChecker);
+ if (context->HadError)
+ {
+ return std::string();
+ }
+ }
+ parameters.push_back(parameter);
+ }
}
}
@@ -1605,7 +219,7 @@ std::string GeneratorExpressionContent::EvaluateParameters(
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "$<" + identifier + "> expression requires "
<< numExpected
<< " comma separated parameters, but got "
@@ -1621,34 +235,19 @@ std::string GeneratorExpressionContent::EvaluateParameters(
reportError(context, this->GetOriginalExpression(), "$<" + identifier
+ "> expression requires at least one parameter.");
}
- return std::string();
-}
-
-//----------------------------------------------------------------------------
-static void deleteAll(const std::vector<cmGeneratorExpressionEvaluator*> &c)
-{
- std::vector<cmGeneratorExpressionEvaluator*>::const_iterator it
- = c.begin();
- const std::vector<cmGeneratorExpressionEvaluator*>::const_iterator end
- = c.end();
- for ( ; it != end; ++it)
+ if (numExpected == cmGeneratorExpressionNode::OneOrZeroParameters
+ && parameters.size() > 1)
{
- delete *it;
+ reportError(context, this->GetOriginalExpression(), "$<" + identifier
+ + "> expression requires one or zero parameters.");
}
+ return std::string();
}
//----------------------------------------------------------------------------
GeneratorExpressionContent::~GeneratorExpressionContent()
{
- deleteAll(this->IdentifierChildren);
-
- typedef std::vector<cmGeneratorExpressionEvaluator*> EvaluatorVector;
- std::vector<EvaluatorVector>::const_iterator pit =
- this->ParamChildren.begin();
- const std::vector<EvaluatorVector>::const_iterator pend =
- this->ParamChildren.end();
- for ( ; pit != pend; ++pit)
- {
- deleteAll(*pit);
- }
+ cmDeleteAll(this->IdentifierChildren);
+ std::for_each(this->ParamChildren.begin(), this->ParamChildren.end(),
+ cmDeleteAll<std::vector<cmGeneratorExpressionEvaluator*> >);
}
diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h
index 218abf160..407f83f19 100644
--- a/Source/cmGeneratorExpressionEvaluator.h
+++ b/Source/cmGeneratorExpressionEvaluator.h
@@ -12,29 +12,11 @@
#ifndef cmGeneratorExpressionEvaluator_h
#define cmGeneratorExpressionEvaluator_h
-#include <vector>
-#include <string>
-
#include "cmListFileCache.h"
+#include "cmGeneratorExpressionContext.h"
-class cmTarget;
-
-//----------------------------------------------------------------------------
-struct cmGeneratorExpressionContext
-{
- cmListFileBacktrace Backtrace;
- std::set<cmTarget*> DependTargets;
- std::set<cmTarget*> AllTargets;
- std::set<cmStdString> SeenTargetProperties;
- cmMakefile *Makefile;
- const char *Config;
- cmTarget *HeadTarget; // The target whose property is being evaluated.
- cmTarget *CurrentTarget; // The dependent of HeadTarget which appears
- // directly or indirectly in the property.
- bool Quiet;
- bool HadError;
- bool HadContextSensitiveCondition;
-};
+#include <vector>
+#include <string>
struct cmGeneratorExpressionDAGChecker;
struct cmGeneratorExpressionNode;
@@ -63,7 +45,7 @@ private:
struct TextContent : public cmGeneratorExpressionEvaluator
{
- TextContent(const char *start, unsigned int length)
+ TextContent(const char *start, size_t length)
: Content(start), Length(length)
{
@@ -80,25 +62,25 @@ struct TextContent : public cmGeneratorExpressionEvaluator
return cmGeneratorExpressionEvaluator::Text;
}
- void Extend(unsigned int length)
+ void Extend(size_t length)
{
this->Length += length;
}
- unsigned int GetLength()
+ size_t GetLength()
{
return this->Length;
}
private:
const char *Content;
- unsigned int Length;
+ size_t Length;
};
//----------------------------------------------------------------------------
struct GeneratorExpressionContent : public cmGeneratorExpressionEvaluator
{
- GeneratorExpressionContent(const char *startContent, unsigned int length);
+ GeneratorExpressionContent(const char *startContent, size_t length);
void SetIdentifier(std::vector<cmGeneratorExpressionEvaluator*> identifier)
{
this->IdentifierChildren = identifier;
@@ -141,7 +123,7 @@ private:
std::vector<cmGeneratorExpressionEvaluator*> IdentifierChildren;
std::vector<std::vector<cmGeneratorExpressionEvaluator*> > ParamChildren;
const char *StartContent;
- unsigned int ContentLength;
+ size_t ContentLength;
};
#endif
diff --git a/Source/cmGeneratorExpressionLexer.cxx b/Source/cmGeneratorExpressionLexer.cxx
index cd71ec033..1c83466ce 100644
--- a/Source/cmGeneratorExpressionLexer.cxx
+++ b/Source/cmGeneratorExpressionLexer.cxx
@@ -32,52 +32,50 @@ static void InsertText(const char *upto, const char *c,
//----------------------------------------------------------------------------
std::vector<cmGeneratorExpressionToken>
-cmGeneratorExpressionLexer::Tokenize(const char *input)
+cmGeneratorExpressionLexer::Tokenize(const std::string& input)
{
std::vector<cmGeneratorExpressionToken> result;
- if (!input)
- return result;
- const char *c = input;
+ const char *c = input.c_str();
const char *upto = c;
for ( ; *c; ++c)
- {
- if(c[0] == '$' && c[1] == '<')
{
- InsertText(upto, c, result);
- upto = c;
- result.push_back(cmGeneratorExpressionToken(
- cmGeneratorExpressionToken::BeginExpression, upto, 2));
- upto = c + 2;
- ++c;
- SawBeginExpression = true;
- }
- else if(c[0] == '>')
- {
- InsertText(upto, c, result);
- upto = c;
- result.push_back(cmGeneratorExpressionToken(
- cmGeneratorExpressionToken::EndExpression, upto, 1));
- upto = c + 1;
- SawGeneratorExpression = SawBeginExpression;
- }
- else if(c[0] == ':')
- {
- InsertText(upto, c, result);
- upto = c;
- result.push_back(cmGeneratorExpressionToken(
- cmGeneratorExpressionToken::ColonSeparator, upto, 1));
- upto = c + 1;
- }
- else if(c[0] == ',')
- {
- InsertText(upto, c, result);
- upto = c;
- result.push_back(cmGeneratorExpressionToken(
- cmGeneratorExpressionToken::CommaSeparator, upto, 1));
- upto = c + 1;
- }
+ switch(*c)
+ {
+ case '$':
+ if(c[1] == '<')
+ {
+ InsertText(upto, c, result);
+ result.push_back(cmGeneratorExpressionToken(
+ cmGeneratorExpressionToken::BeginExpression, c, 2));
+ upto = c + 2;
+ ++c;
+ SawBeginExpression = true;
+ }
+ break;
+ case '>':
+ InsertText(upto, c, result);
+ result.push_back(cmGeneratorExpressionToken(
+ cmGeneratorExpressionToken::EndExpression, c, 1));
+ upto = c + 1;
+ SawGeneratorExpression = SawBeginExpression;
+ break;
+ case ':':
+ InsertText(upto, c, result);
+ result.push_back(cmGeneratorExpressionToken(
+ cmGeneratorExpressionToken::ColonSeparator, c, 1));
+ upto = c + 1;
+ break;
+ case ',':
+ InsertText(upto, c, result);
+ result.push_back(cmGeneratorExpressionToken(
+ cmGeneratorExpressionToken::CommaSeparator, c, 1));
+ upto = c + 1;
+ break;
+ default:
+ break;
+ }
}
InsertText(upto, c, result);
diff --git a/Source/cmGeneratorExpressionLexer.h b/Source/cmGeneratorExpressionLexer.h
index 5f16712fb..1e2e8c25e 100644
--- a/Source/cmGeneratorExpressionLexer.h
+++ b/Source/cmGeneratorExpressionLexer.h
@@ -19,7 +19,7 @@
//----------------------------------------------------------------------------
struct cmGeneratorExpressionToken
{
- cmGeneratorExpressionToken(unsigned type, const char *c, unsigned l)
+ cmGeneratorExpressionToken(unsigned type, const char *c, size_t l)
: TokenType(type), Content(c), Length(l)
{
}
@@ -32,7 +32,7 @@ struct cmGeneratorExpressionToken
};
unsigned TokenType;
const char *Content;
- unsigned Length;
+ size_t Length;
};
/** \class cmGeneratorExpressionLexer
@@ -43,7 +43,7 @@ class cmGeneratorExpressionLexer
public:
cmGeneratorExpressionLexer();
- std::vector<cmGeneratorExpressionToken> Tokenize(const char *input);
+ std::vector<cmGeneratorExpressionToken> Tokenize(const std::string& input);
bool GetSawGeneratorExpression() const
{
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
new file mode 100644
index 000000000..32b2f8251
--- /dev/null
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -0,0 +1,1906 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2012 Stephen Kelly <steveire@gmail.com>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmGeneratorExpressionNode.h"
+#include "cmGlobalGenerator.h"
+#include "cmAlgorithms.h"
+#include "cmOutputConverter.h"
+#include "cmMakefile.h"
+
+//----------------------------------------------------------------------------
+std::string cmGeneratorExpressionNode::EvaluateDependentExpression(
+ std::string const& prop, cmLocalGenerator *lg,
+ cmGeneratorExpressionContext *context,
+ cmGeneratorTarget const* headTarget,
+ cmGeneratorTarget const* currentTarget,
+ cmGeneratorExpressionDAGChecker *dagChecker)
+{
+ cmGeneratorExpression ge(context->Backtrace);
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
+ cge->SetEvaluateForBuildsystem(context->EvaluateForBuildsystem);
+ std::string result = cge->Evaluate(lg,
+ context->Config,
+ context->Quiet,
+ headTarget,
+ currentTarget,
+ dagChecker,
+ context->Language);
+ if (cge->GetHadContextSensitiveCondition())
+ {
+ context->HadContextSensitiveCondition = true;
+ }
+ if (cge->GetHadHeadSensitiveCondition())
+ {
+ context->HadHeadSensitiveCondition = true;
+ }
+ return result;
+}
+
+//----------------------------------------------------------------------------
+static const struct ZeroNode : public cmGeneratorExpressionNode
+{
+ ZeroNode() {}
+
+ virtual bool GeneratesContent() const { return false; }
+
+ virtual bool AcceptsArbitraryContentParameter() const { return true; }
+
+ std::string Evaluate(const std::vector<std::string> &,
+ cmGeneratorExpressionContext *,
+ const GeneratorExpressionContent *,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ return std::string();
+ }
+} zeroNode;
+
+//----------------------------------------------------------------------------
+static const struct OneNode : public cmGeneratorExpressionNode
+{
+ OneNode() {}
+
+ virtual bool AcceptsArbitraryContentParameter() const { return true; }
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *,
+ const GeneratorExpressionContent *,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ return parameters.front();
+ }
+} oneNode;
+
+//----------------------------------------------------------------------------
+static const struct OneNode buildInterfaceNode;
+
+//----------------------------------------------------------------------------
+static const struct ZeroNode installInterfaceNode;
+
+//----------------------------------------------------------------------------
+#define BOOLEAN_OP_NODE(OPNAME, OP, SUCCESS_VALUE, FAILURE_VALUE) \
+static const struct OP ## Node : public cmGeneratorExpressionNode \
+{ \
+ OP ## Node () {} \
+ virtual int NumExpectedParameters() const { return OneOrMoreParameters; } \
+ \
+ std::string Evaluate(const std::vector<std::string> &parameters, \
+ cmGeneratorExpressionContext *context, \
+ const GeneratorExpressionContent *content, \
+ cmGeneratorExpressionDAGChecker *) const \
+ { \
+ std::vector<std::string>::const_iterator it = parameters.begin(); \
+ const std::vector<std::string>::const_iterator end = parameters.end(); \
+ for ( ; it != end; ++it) \
+ { \
+ if (*it == #FAILURE_VALUE) \
+ { \
+ return #FAILURE_VALUE; \
+ } \
+ else if (*it != #SUCCESS_VALUE) \
+ { \
+ reportError(context, content->GetOriginalExpression(), \
+ "Parameters to $<" #OP "> must resolve to either '0' or '1'."); \
+ return std::string(); \
+ } \
+ } \
+ return #SUCCESS_VALUE; \
+ } \
+} OPNAME;
+
+BOOLEAN_OP_NODE(andNode, AND, 1, 0)
+BOOLEAN_OP_NODE(orNode, OR, 0, 1)
+
+#undef BOOLEAN_OP_NODE
+
+//----------------------------------------------------------------------------
+static const struct NotNode : public cmGeneratorExpressionNode
+{
+ NotNode() {}
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ if (*parameters.begin() != "0" && *parameters.begin() != "1")
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<NOT> parameter must resolve to exactly one '0' or '1' value.");
+ return std::string();
+ }
+ return *parameters.begin() == "0" ? "1" : "0";
+ }
+} notNode;
+
+//----------------------------------------------------------------------------
+static const struct BoolNode : public cmGeneratorExpressionNode
+{
+ BoolNode() {}
+
+ virtual int NumExpectedParameters() const { return 1; }
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *,
+ const GeneratorExpressionContent *,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ return !cmSystemTools::IsOff(parameters.begin()->c_str()) ? "1" : "0";
+ }
+} boolNode;
+
+//----------------------------------------------------------------------------
+static const struct StrEqualNode : public cmGeneratorExpressionNode
+{
+ StrEqualNode() {}
+
+ virtual int NumExpectedParameters() const { return 2; }
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *,
+ const GeneratorExpressionContent *,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ return *parameters.begin() == parameters[1] ? "1" : "0";
+ }
+} strEqualNode;
+
+//----------------------------------------------------------------------------
+static const struct EqualNode : public cmGeneratorExpressionNode
+{
+ EqualNode() {}
+
+ virtual int NumExpectedParameters() const { return 2; }
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ char *pEnd;
+
+ int base = 0;
+ bool flipSign = false;
+
+ const char *lhs = parameters[0].c_str();
+ if (cmHasLiteralPrefix(lhs, "0b") || cmHasLiteralPrefix(lhs, "0B"))
+ {
+ base = 2;
+ lhs += 2;
+ }
+ if (cmHasLiteralPrefix(lhs, "-0b") || cmHasLiteralPrefix(lhs, "-0B"))
+ {
+ base = 2;
+ lhs += 3;
+ flipSign = true;
+ }
+ if (cmHasLiteralPrefix(lhs, "+0b") || cmHasLiteralPrefix(lhs, "+0B"))
+ {
+ base = 2;
+ lhs += 3;
+ }
+
+ long lnum = strtol(lhs, &pEnd, base);
+ if (pEnd == lhs || *pEnd != '\0' || errno == ERANGE)
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<EQUAL> parameter " + parameters[0] + " is not a valid integer.");
+ return std::string();
+ }
+
+ if (flipSign)
+ {
+ lnum = -lnum;
+ }
+
+ base = 0;
+ flipSign = false;
+
+ const char *rhs = parameters[1].c_str();
+ if (cmHasLiteralPrefix(rhs, "0b") || cmHasLiteralPrefix(rhs, "0B"))
+ {
+ base = 2;
+ rhs += 2;
+ }
+ if (cmHasLiteralPrefix(rhs, "-0b") || cmHasLiteralPrefix(rhs, "-0B"))
+ {
+ base = 2;
+ rhs += 3;
+ flipSign = true;
+ }
+ if (cmHasLiteralPrefix(rhs, "+0b") || cmHasLiteralPrefix(rhs, "+0B"))
+ {
+ base = 2;
+ rhs += 3;
+ }
+
+ long rnum = strtol(rhs, &pEnd, base);
+ if (pEnd == rhs || *pEnd != '\0' || errno == ERANGE)
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<EQUAL> parameter " + parameters[1] + " is not a valid integer.");
+ return std::string();
+ }
+
+ if (flipSign)
+ {
+ rnum = -rnum;
+ }
+
+ return lnum == rnum ? "1" : "0";
+ }
+} equalNode;
+
+//----------------------------------------------------------------------------
+static const struct LowerCaseNode : public cmGeneratorExpressionNode
+{
+ LowerCaseNode() {}
+
+ bool AcceptsArbitraryContentParameter() const { return true; }
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *,
+ const GeneratorExpressionContent *,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ return cmSystemTools::LowerCase(parameters.front());
+ }
+} lowerCaseNode;
+
+//----------------------------------------------------------------------------
+static const struct UpperCaseNode : public cmGeneratorExpressionNode
+{
+ UpperCaseNode() {}
+
+ bool AcceptsArbitraryContentParameter() const { return true; }
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *,
+ const GeneratorExpressionContent *,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ return cmSystemTools::UpperCase(parameters.front());
+ }
+} upperCaseNode;
+
+//----------------------------------------------------------------------------
+static const struct MakeCIdentifierNode : public cmGeneratorExpressionNode
+{
+ MakeCIdentifierNode() {}
+
+ bool AcceptsArbitraryContentParameter() const { return true; }
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *,
+ const GeneratorExpressionContent *,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ return cmSystemTools::MakeCidentifier(parameters.front());
+ }
+} makeCIdentifierNode;
+
+//----------------------------------------------------------------------------
+static const struct Angle_RNode : public cmGeneratorExpressionNode
+{
+ Angle_RNode() {}
+
+ virtual int NumExpectedParameters() const { return 0; }
+
+ std::string Evaluate(const std::vector<std::string> &,
+ cmGeneratorExpressionContext *,
+ const GeneratorExpressionContent *,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ return ">";
+ }
+} angle_rNode;
+
+//----------------------------------------------------------------------------
+static const struct CommaNode : public cmGeneratorExpressionNode
+{
+ CommaNode() {}
+
+ virtual int NumExpectedParameters() const { return 0; }
+
+ std::string Evaluate(const std::vector<std::string> &,
+ cmGeneratorExpressionContext *,
+ const GeneratorExpressionContent *,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ return ",";
+ }
+} commaNode;
+
+//----------------------------------------------------------------------------
+static const struct SemicolonNode : public cmGeneratorExpressionNode
+{
+ SemicolonNode() {}
+
+ virtual int NumExpectedParameters() const { return 0; }
+
+ std::string Evaluate(const std::vector<std::string> &,
+ cmGeneratorExpressionContext *,
+ const GeneratorExpressionContent *,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ return ";";
+ }
+} semicolonNode;
+
+//----------------------------------------------------------------------------
+struct CompilerIdNode : public cmGeneratorExpressionNode
+{
+ CompilerIdNode() {}
+
+ virtual int NumExpectedParameters() const { return OneOrZeroParameters; }
+
+ std::string EvaluateWithLanguage(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *,
+ const std::string &lang) const
+ {
+ const char *compilerId =
+ context->LG->GetMakefile()
+ ->GetSafeDefinition("CMAKE_" + lang + "_COMPILER_ID");
+ if (parameters.empty())
+ {
+ return compilerId ? compilerId : "";
+ }
+ static cmsys::RegularExpression compilerIdValidator("^[A-Za-z0-9_]*$");
+ if (!compilerIdValidator.find(*parameters.begin()))
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "Expression syntax not recognized.");
+ return std::string();
+ }
+ if (!compilerId)
+ {
+ return parameters.front().empty() ? "1" : "0";
+ }
+
+ if (strcmp(parameters.begin()->c_str(), compilerId) == 0)
+ {
+ return "1";
+ }
+
+ if (cmsysString_strcasecmp(parameters.begin()->c_str(), compilerId) == 0)
+ {
+ switch(context->LG->GetPolicyStatus(cmPolicies::CMP0044))
+ {
+ case cmPolicies::WARN:
+ {
+ std::ostringstream e;
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0044);
+ context->LG->GetCMakeInstance()
+ ->IssueMessage(cmake::AUTHOR_WARNING,
+ e.str(), context->Backtrace);
+ }
+ case cmPolicies::OLD:
+ return "1";
+ case cmPolicies::NEW:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ break;
+ }
+ }
+ return "0";
+ }
+};
+
+//----------------------------------------------------------------------------
+static const struct CCompilerIdNode : public CompilerIdNode
+{
+ CCompilerIdNode() {}
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *dagChecker) const
+ {
+ if (!context->HeadTarget)
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<C_COMPILER_ID> may only be used with binary targets. It may "
+ "not be used with add_custom_command or add_custom_target.");
+ return std::string();
+ }
+ return this->EvaluateWithLanguage(parameters, context, content,
+ dagChecker, "C");
+ }
+} cCompilerIdNode;
+
+//----------------------------------------------------------------------------
+static const struct CXXCompilerIdNode : public CompilerIdNode
+{
+ CXXCompilerIdNode() {}
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *dagChecker) const
+ {
+ if (!context->HeadTarget)
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<CXX_COMPILER_ID> may only be used with binary targets. It may "
+ "not be used with add_custom_command or add_custom_target.");
+ return std::string();
+ }
+ return this->EvaluateWithLanguage(parameters, context, content,
+ dagChecker, "CXX");
+ }
+} cxxCompilerIdNode;
+
+//----------------------------------------------------------------------------
+struct CompilerVersionNode : public cmGeneratorExpressionNode
+{
+ CompilerVersionNode() {}
+
+ virtual int NumExpectedParameters() const { return OneOrZeroParameters; }
+
+ std::string EvaluateWithLanguage(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *,
+ const std::string &lang) const
+ {
+ const char *compilerVersion =
+ context->LG->GetMakefile()->GetSafeDefinition(
+ "CMAKE_" + lang + "_COMPILER_VERSION");
+ if (parameters.empty())
+ {
+ return compilerVersion ? compilerVersion : "";
+ }
+
+ static cmsys::RegularExpression compilerIdValidator("^[0-9\\.]*$");
+ if (!compilerIdValidator.find(*parameters.begin()))
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "Expression syntax not recognized.");
+ return std::string();
+ }
+ if (!compilerVersion)
+ {
+ return parameters.front().empty() ? "1" : "0";
+ }
+
+ return cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL,
+ parameters.begin()->c_str(),
+ compilerVersion) ? "1" : "0";
+ }
+};
+
+//----------------------------------------------------------------------------
+static const struct CCompilerVersionNode : public CompilerVersionNode
+{
+ CCompilerVersionNode() {}
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *dagChecker) const
+ {
+ if (!context->HeadTarget)
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<C_COMPILER_VERSION> may only be used with binary targets. It "
+ "may not be used with add_custom_command or add_custom_target.");
+ return std::string();
+ }
+ return this->EvaluateWithLanguage(parameters, context, content,
+ dagChecker, "C");
+ }
+} cCompilerVersionNode;
+
+//----------------------------------------------------------------------------
+static const struct CxxCompilerVersionNode : public CompilerVersionNode
+{
+ CxxCompilerVersionNode() {}
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *dagChecker) const
+ {
+ if (!context->HeadTarget)
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<CXX_COMPILER_VERSION> may only be used with binary targets. It "
+ "may not be used with add_custom_command or add_custom_target.");
+ return std::string();
+ }
+ return this->EvaluateWithLanguage(parameters, context, content,
+ dagChecker, "CXX");
+ }
+} cxxCompilerVersionNode;
+
+
+//----------------------------------------------------------------------------
+struct PlatformIdNode : public cmGeneratorExpressionNode
+{
+ PlatformIdNode() {}
+
+ virtual int NumExpectedParameters() const { return OneOrZeroParameters; }
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ const char *platformId =
+ context->LG->GetMakefile()->GetSafeDefinition("CMAKE_SYSTEM_NAME");
+ if (parameters.empty())
+ {
+ return platformId ? platformId : "";
+ }
+
+ if (!platformId)
+ {
+ return parameters.front().empty() ? "1" : "0";
+ }
+
+ if (strcmp(parameters.begin()->c_str(), platformId) == 0)
+ {
+ return "1";
+ }
+ return "0";
+ }
+} platformIdNode;
+
+//----------------------------------------------------------------------------
+static const struct VersionGreaterNode : public cmGeneratorExpressionNode
+{
+ VersionGreaterNode() {}
+
+ virtual int NumExpectedParameters() const { return 2; }
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *,
+ const GeneratorExpressionContent *,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ return cmSystemTools::VersionCompare(cmSystemTools::OP_GREATER,
+ parameters.front().c_str(),
+ parameters[1].c_str()) ? "1" : "0";
+ }
+} versionGreaterNode;
+
+//----------------------------------------------------------------------------
+static const struct VersionLessNode : public cmGeneratorExpressionNode
+{
+ VersionLessNode() {}
+
+ virtual int NumExpectedParameters() const { return 2; }
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *,
+ const GeneratorExpressionContent *,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ return cmSystemTools::VersionCompare(cmSystemTools::OP_LESS,
+ parameters.front().c_str(),
+ parameters[1].c_str()) ? "1" : "0";
+ }
+} versionLessNode;
+
+//----------------------------------------------------------------------------
+static const struct VersionEqualNode : public cmGeneratorExpressionNode
+{
+ VersionEqualNode() {}
+
+ virtual int NumExpectedParameters() const { return 2; }
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *,
+ const GeneratorExpressionContent *,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ return cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL,
+ parameters.front().c_str(),
+ parameters[1].c_str()) ? "1" : "0";
+ }
+} versionEqualNode;
+
+//----------------------------------------------------------------------------
+static const struct LinkOnlyNode : public cmGeneratorExpressionNode
+{
+ LinkOnlyNode() {}
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *,
+ const GeneratorExpressionContent *,
+ cmGeneratorExpressionDAGChecker *dagChecker) const
+ {
+ if(!dagChecker->GetTransitivePropertiesOnly())
+ {
+ return parameters.front();
+ }
+ return "";
+ }
+} linkOnlyNode;
+
+//----------------------------------------------------------------------------
+static const struct ConfigurationNode : public cmGeneratorExpressionNode
+{
+ ConfigurationNode() {}
+
+ virtual int NumExpectedParameters() const { return 0; }
+
+ std::string Evaluate(const std::vector<std::string> &,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ context->HadContextSensitiveCondition = true;
+ return context->Config;
+ }
+} configurationNode;
+
+//----------------------------------------------------------------------------
+static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
+{
+ ConfigurationTestNode() {}
+
+ virtual int NumExpectedParameters() const { return OneOrZeroParameters; }
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ if (parameters.empty())
+ {
+ return configurationNode.Evaluate(parameters, context, content, 0);
+ }
+ static cmsys::RegularExpression configValidator("^[A-Za-z0-9_]*$");
+ if (!configValidator.find(*parameters.begin()))
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "Expression syntax not recognized.");
+ return std::string();
+ }
+ context->HadContextSensitiveCondition = true;
+ if (context->Config.empty())
+ {
+ return parameters.front().empty() ? "1" : "0";
+ }
+
+ if (cmsysString_strcasecmp(parameters.begin()->c_str(),
+ context->Config.c_str()) == 0)
+ {
+ return "1";
+ }
+
+ if (context->CurrentTarget
+ && context->CurrentTarget->IsImported())
+ {
+ const char* loc = 0;
+ const char* imp = 0;
+ std::string suffix;
+ if (context->CurrentTarget->Target->GetMappedConfig(context->Config,
+ &loc,
+ &imp,
+ suffix))
+ {
+ // This imported target has an appropriate location
+ // for this (possibly mapped) config.
+ // Check if there is a proper config mapping for the tested config.
+ std::vector<std::string> mappedConfigs;
+ std::string mapProp = "MAP_IMPORTED_CONFIG_";
+ mapProp += cmSystemTools::UpperCase(context->Config);
+ if(const char* mapValue =
+ context->CurrentTarget->GetProperty(mapProp))
+ {
+ cmSystemTools::ExpandListArgument(cmSystemTools::UpperCase(mapValue),
+ mappedConfigs);
+ return std::find(mappedConfigs.begin(), mappedConfigs.end(),
+ cmSystemTools::UpperCase(parameters.front()))
+ != mappedConfigs.end() ? "1" : "0";
+ }
+ }
+ }
+ return "0";
+ }
+} configurationTestNode;
+
+static const struct JoinNode : public cmGeneratorExpressionNode
+{
+ JoinNode() {}
+
+ virtual int NumExpectedParameters() const { return 2; }
+
+ virtual bool AcceptsArbitraryContentParameter() const { return true; }
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *,
+ const GeneratorExpressionContent *,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ std::vector<std::string> list;
+ cmSystemTools::ExpandListArgument(parameters.front(), list);
+ return cmJoin(list, parameters[1]);
+ }
+} joinNode;
+
+static const struct CompileLanguageNode : public cmGeneratorExpressionNode
+{
+ CompileLanguageNode() {}
+
+ virtual int NumExpectedParameters() const { return OneOrZeroParameters; }
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *dagChecker) const
+ {
+ if(context->Language.empty())
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<COMPILE_LANGUAGE:...> may only be used to specify include "
+ "directories compile definitions, compile options and to evaluate "
+ "components of the file(GENERATE) command.");
+ return std::string();
+ }
+
+ std::vector<std::string> enabledLanguages;
+ cmGlobalGenerator* gg = context->LG->GetGlobalGenerator();
+ gg->GetEnabledLanguages(enabledLanguages);
+ if (!parameters.empty() &&
+ std::find(enabledLanguages.begin(), enabledLanguages.end(),
+ parameters.front()) == enabledLanguages.end())
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<COMPILE_LANGUAGE:...> Unknown language.");
+ return std::string();
+ }
+ std::string genName = gg->GetName();
+ if (genName.find("Visual Studio") != std::string::npos)
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<COMPILE_LANGUAGE:...> may not be used with Visual Studio "
+ "generators.");
+ return std::string();
+ }
+ else if (genName.find("Xcode") != std::string::npos)
+ {
+ if (dagChecker && (dagChecker->EvaluatingCompileDefinitions()
+ || dagChecker->EvaluatingIncludeDirectories()))
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<COMPILE_LANGUAGE:...> may only be used with COMPILE_OPTIONS "
+ "with the Xcode generator.");
+ return std::string();
+ }
+ }
+ else
+ {
+ if(genName.find("Makefiles") == std::string::npos &&
+ genName.find("Ninja") == std::string::npos &&
+ genName.find("Watcom WMake") == std::string::npos)
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<COMPILE_LANGUAGE:...> not supported for this generator.");
+ return std::string();
+ }
+ }
+ if (parameters.empty())
+ {
+ return context->Language;
+ }
+ return context->Language == parameters.front() ? "1" : "0";
+ }
+} languageNode;
+
+#define TRANSITIVE_PROPERTY_NAME(PROPERTY) \
+ , "INTERFACE_" #PROPERTY
+
+//----------------------------------------------------------------------------
+static const char* targetPropertyTransitiveWhitelist[] = {
+ 0
+ CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(TRANSITIVE_PROPERTY_NAME)
+};
+
+#undef TRANSITIVE_PROPERTY_NAME
+
+template <typename T>
+std::string
+getLinkedTargetsContent(
+ std::vector<T> const &libraries,
+ cmGeneratorTarget const* target,
+ cmGeneratorTarget const* headTarget,
+ cmGeneratorExpressionContext *context,
+ cmGeneratorExpressionDAGChecker *dagChecker,
+ const std::string &interfacePropertyName)
+{
+ std::string linkedTargetsContent;
+ std::string sep;
+ std::string depString;
+ for (typename std::vector<T>::const_iterator it = libraries.begin();
+ it != libraries.end(); ++it)
+ {
+ // Broken code can have a target in its own link interface.
+ // Don't follow such link interface entries so as not to create a
+ // self-referencing loop.
+ if (it->Target && it->Target != target)
+ {
+ depString +=
+ sep + "$<TARGET_PROPERTY:" +
+ it->Target->GetName() + "," + interfacePropertyName + ">";
+ sep = ";";
+ }
+ }
+ if(!depString.empty())
+ {
+ linkedTargetsContent =
+ cmGeneratorExpressionNode::EvaluateDependentExpression(depString,
+ target->GetLocalGenerator(),
+ context,
+ headTarget,
+ target, dagChecker);
+ }
+ linkedTargetsContent =
+ cmGeneratorExpression::StripEmptyListElements(linkedTargetsContent);
+ return linkedTargetsContent;
+}
+
+//----------------------------------------------------------------------------
+static const struct TargetPropertyNode : public cmGeneratorExpressionNode
+{
+ TargetPropertyNode() {}
+
+ // This node handles errors on parameter count itself.
+ virtual int NumExpectedParameters() const { return OneOrMoreParameters; }
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *dagCheckerParent
+ ) const
+ {
+ if (parameters.size() != 1 && parameters.size() != 2)
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<TARGET_PROPERTY:...> expression requires one or two parameters");
+ return std::string();
+ }
+ static cmsys::RegularExpression propertyNameValidator("^[A-Za-z0-9_]+$");
+
+ cmGeneratorTarget const* target = context->HeadTarget;
+ std::string propertyName = *parameters.begin();
+
+ if (parameters.size() == 1)
+ {
+ context->HadHeadSensitiveCondition = true;
+ }
+ if (!target && parameters.size() == 1)
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<TARGET_PROPERTY:prop> may only be used with binary targets. "
+ "It may not be used with add_custom_command or add_custom_target. "
+ "Specify the target to read a property from using the "
+ "$<TARGET_PROPERTY:tgt,prop> signature instead.");
+ return std::string();
+ }
+
+ if (parameters.size() == 2)
+ {
+ if (parameters.begin()->empty() && parameters[1].empty())
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty "
+ "target name and property name.");
+ return std::string();
+ }
+ if (parameters.begin()->empty())
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty "
+ "target name.");
+ return std::string();
+ }
+
+ std::string targetName = parameters.front();
+ propertyName = parameters[1];
+ if (!cmGeneratorExpression::IsValidTargetName(targetName))
+ {
+ if (!propertyNameValidator.find(propertyName.c_str()))
+ {
+ ::reportError(context, content->GetOriginalExpression(),
+ "Target name and property name not supported.");
+ return std::string();
+ }
+ ::reportError(context, content->GetOriginalExpression(),
+ "Target name not supported.");
+ return std::string();
+ }
+ if(propertyName == "ALIASED_TARGET")
+ {
+ if(context->LG->GetMakefile()->IsAlias(targetName))
+ {
+ if(cmGeneratorTarget* tgt =
+ context->LG->FindGeneratorTargetToUse(targetName))
+ {
+ return tgt->GetName();
+ }
+ }
+ return "";
+ }
+ target = context->LG->FindGeneratorTargetToUse(targetName);
+
+ if (!target)
+ {
+ std::ostringstream e;
+ e << "Target \""
+ << targetName
+ << "\" not found.";
+ reportError(context, content->GetOriginalExpression(), e.str());
+ return std::string();
+ }
+ context->AllTargets.insert(target);
+ }
+
+ if (target == context->HeadTarget)
+ {
+ // Keep track of the properties seen while processing.
+ // The evaluation of the LINK_LIBRARIES generator expressions
+ // will check this to ensure that properties have one consistent
+ // value for all evaluations.
+ context->SeenTargetProperties.insert(propertyName);
+ }
+ if (propertyName == "SOURCES")
+ {
+ context->SourceSensitiveTargets.insert(target);
+ }
+
+ if (propertyName.empty())
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<TARGET_PROPERTY:...> expression requires a non-empty property "
+ "name.");
+ return std::string();
+ }
+
+ if (!propertyNameValidator.find(propertyName))
+ {
+ ::reportError(context, content->GetOriginalExpression(),
+ "Property name not supported.");
+ return std::string();
+ }
+
+ assert(target);
+
+ if (propertyName == "LINKER_LANGUAGE")
+ {
+ if (target->LinkLanguagePropagatesToDependents() &&
+ dagCheckerParent && (dagCheckerParent->EvaluatingLinkLibraries()
+ || dagCheckerParent->EvaluatingSources()))
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "LINKER_LANGUAGE target property can not be used while evaluating "
+ "link libraries for a static library");
+ return std::string();
+ }
+ return target->GetLinkerLanguage(context->Config);
+ }
+
+ cmGeneratorExpressionDAGChecker dagChecker(context->Backtrace,
+ target->GetName(),
+ propertyName,
+ content,
+ dagCheckerParent);
+
+ switch (dagChecker.Check())
+ {
+ case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
+ dagChecker.ReportError(context, content->GetOriginalExpression());
+ return std::string();
+ case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
+ // No error. We just skip cyclic references.
+ return std::string();
+ case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
+ for (size_t i = 1;
+ i < cmArraySize(targetPropertyTransitiveWhitelist);
+ ++i)
+ {
+ if (targetPropertyTransitiveWhitelist[i] == propertyName)
+ {
+ // No error. We're not going to find anything new here.
+ return std::string();
+ }
+ }
+ case cmGeneratorExpressionDAGChecker::DAG:
+ break;
+ }
+
+ const char *prop = target->GetProperty(propertyName);
+
+ if (dagCheckerParent)
+ {
+ if (dagCheckerParent->EvaluatingLinkLibraries())
+ {
+#define TRANSITIVE_PROPERTY_COMPARE(PROPERTY) \
+ (#PROPERTY == propertyName || "INTERFACE_" #PROPERTY == propertyName) ||
+ if (CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(TRANSITIVE_PROPERTY_COMPARE)
+ false)
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<TARGET_PROPERTY:...> expression in link libraries "
+ "evaluation depends on target property which is transitive "
+ "over the link libraries, creating a recursion.");
+ return std::string();
+ }
+#undef TRANSITIVE_PROPERTY_COMPARE
+
+ if(!prop)
+ {
+ return std::string();
+ }
+ }
+ else
+ {
+#define ASSERT_TRANSITIVE_PROPERTY_METHOD(METHOD) \
+ dagCheckerParent->METHOD () ||
+
+ assert(
+ CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(
+ ASSERT_TRANSITIVE_PROPERTY_METHOD)
+ false);
+#undef ASSERT_TRANSITIVE_PROPERTY_METHOD
+ }
+ }
+
+ std::string linkedTargetsContent;
+
+ std::string interfacePropertyName;
+ bool isInterfaceProperty = false;
+
+#define POPULATE_INTERFACE_PROPERTY_NAME(prop) \
+ if (propertyName == #prop) \
+ { \
+ interfacePropertyName = "INTERFACE_" #prop; \
+ } \
+ else if (propertyName == "INTERFACE_" #prop) \
+ { \
+ interfacePropertyName = "INTERFACE_" #prop; \
+ isInterfaceProperty = true; \
+ } \
+ else
+
+ CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(POPULATE_INTERFACE_PROPERTY_NAME)
+ // Note that the above macro terminates with an else
+ /* else */ if (cmHasLiteralPrefix(propertyName.c_str(),
+ "COMPILE_DEFINITIONS_"))
+ {
+ cmPolicies::PolicyStatus polSt =
+ context->LG->GetPolicyStatus(cmPolicies::CMP0043);
+ if (polSt == cmPolicies::WARN || polSt == cmPolicies::OLD)
+ {
+ interfacePropertyName = "INTERFACE_COMPILE_DEFINITIONS";
+ }
+ }
+#undef POPULATE_INTERFACE_PROPERTY_NAME
+ cmGeneratorTarget const* headTarget =
+ context->HeadTarget && isInterfaceProperty
+ ? context->HeadTarget : target;
+
+ if(isInterfaceProperty)
+ {
+ if(cmLinkInterfaceLibraries const* iface =
+ target->GetLinkInterfaceLibraries(context->Config, headTarget, true))
+ {
+ linkedTargetsContent =
+ getLinkedTargetsContent(iface->Libraries, target,
+ headTarget,
+ context, &dagChecker,
+ interfacePropertyName);
+ }
+ }
+ else if(!interfacePropertyName.empty())
+ {
+ if(cmLinkImplementationLibraries const* impl =
+ target->GetLinkImplementationLibraries(context->Config))
+ {
+ linkedTargetsContent =
+ getLinkedTargetsContent(impl->Libraries, target,
+ target,
+ context, &dagChecker,
+ interfacePropertyName);
+ }
+ }
+
+ if (!prop)
+ {
+ if (target->IsImported()
+ || target->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ return linkedTargetsContent;
+ }
+ if (target->IsLinkInterfaceDependentBoolProperty(propertyName,
+ context->Config))
+ {
+ context->HadContextSensitiveCondition = true;
+ return target->GetLinkInterfaceDependentBoolProperty(
+ propertyName,
+ context->Config) ? "1" : "0";
+ }
+ if (target->IsLinkInterfaceDependentStringProperty(propertyName,
+ context->Config))
+ {
+ context->HadContextSensitiveCondition = true;
+ const char *propContent =
+ target->GetLinkInterfaceDependentStringProperty(
+ propertyName,
+ context->Config);
+ return propContent ? propContent : "";
+ }
+ if (target->IsLinkInterfaceDependentNumberMinProperty(propertyName,
+ context->Config))
+ {
+ context->HadContextSensitiveCondition = true;
+ const char *propContent =
+ target->GetLinkInterfaceDependentNumberMinProperty(
+ propertyName,
+ context->Config);
+ return propContent ? propContent : "";
+ }
+ if (target->IsLinkInterfaceDependentNumberMaxProperty(propertyName,
+ context->Config))
+ {
+ context->HadContextSensitiveCondition = true;
+ const char *propContent =
+ target->GetLinkInterfaceDependentNumberMaxProperty(
+ propertyName,
+ context->Config);
+ return propContent ? propContent : "";
+ }
+
+ return linkedTargetsContent;
+ }
+
+ if (!target->IsImported()
+ && dagCheckerParent && !dagCheckerParent->EvaluatingLinkLibraries())
+ {
+ if (target->IsLinkInterfaceDependentNumberMinProperty(propertyName,
+ context->Config))
+ {
+ context->HadContextSensitiveCondition = true;
+ const char *propContent =
+ target->GetLinkInterfaceDependentNumberMinProperty(
+ propertyName,
+ context->Config);
+ return propContent ? propContent : "";
+ }
+ if (target->IsLinkInterfaceDependentNumberMaxProperty(propertyName,
+ context->Config))
+ {
+ context->HadContextSensitiveCondition = true;
+ const char *propContent =
+ target->GetLinkInterfaceDependentNumberMaxProperty(
+ propertyName,
+ context->Config);
+ return propContent ? propContent : "";
+ }
+ }
+ if(!interfacePropertyName.empty())
+ {
+ std::string result = this->EvaluateDependentExpression(prop,
+ context->LG, context,
+ headTarget, target, &dagChecker);
+ if (!linkedTargetsContent.empty())
+ {
+ result += (result.empty() ? "" : ";") + linkedTargetsContent;
+ }
+ return result;
+ }
+ return prop;
+ }
+} targetPropertyNode;
+
+//----------------------------------------------------------------------------
+static const struct TargetNameNode : public cmGeneratorExpressionNode
+{
+ TargetNameNode() {}
+
+ virtual bool GeneratesContent() const { return true; }
+
+ virtual bool AcceptsArbitraryContentParameter() const { return true; }
+ virtual bool RequiresLiteralInput() const { return true; }
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *,
+ const GeneratorExpressionContent *,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ return parameters.front();
+ }
+
+ virtual int NumExpectedParameters() const { return 1; }
+
+} targetNameNode;
+
+//----------------------------------------------------------------------------
+static const struct TargetObjectsNode : public cmGeneratorExpressionNode
+{
+ TargetObjectsNode() {}
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ if (!context->EvaluateForBuildsystem)
+ {
+ std::ostringstream e;
+ e << "The evaluation of the TARGET_OBJECTS generator expression "
+ "is only suitable for consumption by CMake. It is not suitable "
+ "for writing out elsewhere.";
+ reportError(context, content->GetOriginalExpression(), e.str());
+ return std::string();
+ }
+
+ std::string tgtName = parameters.front();
+ cmGeneratorTarget* gt =
+ context->LG->FindGeneratorTargetToUse(tgtName);
+ if (!gt)
+ {
+ std::ostringstream e;
+ e << "Objects of target \"" << tgtName
+ << "\" referenced but no such target exists.";
+ reportError(context, content->GetOriginalExpression(), e.str());
+ return std::string();
+ }
+ if (gt->GetType() != cmState::OBJECT_LIBRARY)
+ {
+ std::ostringstream e;
+ e << "Objects of target \"" << tgtName
+ << "\" referenced but is not an OBJECT library.";
+ reportError(context, content->GetOriginalExpression(), e.str());
+ return std::string();
+ }
+
+ std::vector<cmSourceFile const*> objectSources;
+ gt->GetObjectSources(objectSources, context->Config);
+ std::map<cmSourceFile const*, std::string> mapping;
+
+ for(std::vector<cmSourceFile const*>::const_iterator it
+ = objectSources.begin(); it != objectSources.end(); ++it)
+ {
+ mapping[*it];
+ }
+
+ gt->LocalGenerator->ComputeObjectFilenames(mapping, gt);
+
+ std::string obj_dir = gt->ObjectDirectory;
+ std::string result;
+ const char* sep = "";
+ for(std::vector<cmSourceFile const*>::const_iterator it
+ = objectSources.begin(); it != objectSources.end(); ++it)
+ {
+ // Find the object file name corresponding to this source file.
+ std::map<cmSourceFile const*, std::string>::const_iterator
+ map_it = mapping.find(*it);
+ // It must exist because we populated the mapping just above.
+ assert(!map_it->second.empty());
+ result += sep;
+ std::string objFile = obj_dir + map_it->second;
+ cmSourceFile* sf =
+ context->LG->GetMakefile()->GetOrCreateSource(objFile, true);
+ sf->SetObjectLibrary(tgtName);
+ sf->SetProperty("EXTERNAL_OBJECT", "1");
+ result += objFile;
+ sep = ";";
+ }
+ return result;
+ }
+} targetObjectsNode;
+
+//----------------------------------------------------------------------------
+static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
+{
+ CompileFeaturesNode() {}
+
+ virtual int NumExpectedParameters() const { return OneOrMoreParameters; }
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *dagChecker) const
+ {
+ cmGeneratorTarget const* target = context->HeadTarget;
+ if (!target)
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<COMPILE_FEATURE> may only be used with binary targets. It may "
+ "not be used with add_custom_command or add_custom_target.");
+ return std::string();
+ }
+ context->HadHeadSensitiveCondition = true;
+
+ typedef std::map<std::string, std::vector<std::string> > LangMap;
+ static LangMap availableFeatures;
+
+ LangMap testedFeatures;
+
+ for (std::vector<std::string>::const_iterator it = parameters.begin();
+ it != parameters.end(); ++it)
+ {
+ std::string error;
+ std::string lang;
+ if (!context->LG->GetMakefile()->CompileFeatureKnown(
+ context->HeadTarget->Target,
+ *it, lang, &error))
+ {
+ reportError(context, content->GetOriginalExpression(), error);
+ return std::string();
+ }
+ testedFeatures[lang].push_back(*it);
+
+ if (availableFeatures.find(lang) == availableFeatures.end())
+ {
+ const char* featuresKnown
+ = context->LG->GetMakefile()->CompileFeaturesAvailable(lang,
+ &error);
+ if (!featuresKnown)
+ {
+ reportError(context, content->GetOriginalExpression(), error);
+ return std::string();
+ }
+ cmSystemTools::ExpandListArgument(featuresKnown,
+ availableFeatures[lang]);
+ }
+ }
+
+ bool evalLL = dagChecker && dagChecker->EvaluatingLinkLibraries();
+
+ for (LangMap::const_iterator lit = testedFeatures.begin();
+ lit != testedFeatures.end(); ++lit)
+ {
+ std::vector<std::string> const& langAvailable
+ = availableFeatures[lit->first];
+ const char* standardDefault = context->LG->GetMakefile()
+ ->GetDefinition("CMAKE_" + lit->first + "_STANDARD_DEFAULT");
+ for (std::vector<std::string>::const_iterator it = lit->second.begin();
+ it != lit->second.end(); ++it)
+ {
+ if (std::find(langAvailable.begin(), langAvailable.end(), *it)
+ == langAvailable.end())
+ {
+ return "0";
+ }
+ if (standardDefault && !*standardDefault)
+ {
+ // This compiler has no notion of language standard levels.
+ // All features known for the language are always available.
+ continue;
+ }
+ if (!context->LG->GetMakefile()->HaveStandardAvailable(target->Target,
+ lit->first, *it))
+ {
+ if (evalLL)
+ {
+ const char* l = target->GetProperty(lit->first + "_STANDARD");
+ if (!l)
+ {
+ l = standardDefault;
+ }
+ assert(l);
+ context->MaxLanguageStandard[target][lit->first] = l;
+ }
+ else
+ {
+ return "0";
+ }
+ }
+ }
+ }
+ return "1";
+ }
+} compileFeaturesNode;
+
+//----------------------------------------------------------------------------
+static const char* targetPolicyWhitelist[] = {
+ 0
+#define TARGET_POLICY_STRING(POLICY) \
+ , #POLICY
+
+ CM_FOR_EACH_TARGET_POLICY(TARGET_POLICY_STRING)
+
+#undef TARGET_POLICY_STRING
+};
+
+cmPolicies::PolicyStatus statusForTarget(cmGeneratorTarget const* tgt,
+ const char *policy)
+{
+#define RETURN_POLICY(POLICY) \
+ if (strcmp(policy, #POLICY) == 0) \
+ { \
+ return tgt->GetPolicyStatus ## POLICY (); \
+ } \
+
+ CM_FOR_EACH_TARGET_POLICY(RETURN_POLICY)
+
+#undef RETURN_POLICY
+
+ assert(0 && "Unreachable code. Not a valid policy");
+ return cmPolicies::WARN;
+}
+
+cmPolicies::PolicyID policyForString(const char *policy_id)
+{
+#define RETURN_POLICY_ID(POLICY_ID) \
+ if (strcmp(policy_id, #POLICY_ID) == 0) \
+ { \
+ return cmPolicies:: POLICY_ID; \
+ } \
+
+ CM_FOR_EACH_TARGET_POLICY(RETURN_POLICY_ID)
+
+#undef RETURN_POLICY_ID
+
+ assert(0 && "Unreachable code. Not a valid policy");
+ return cmPolicies::CMP0002;
+}
+
+//----------------------------------------------------------------------------
+static const struct TargetPolicyNode : public cmGeneratorExpressionNode
+{
+ TargetPolicyNode() {}
+
+ virtual int NumExpectedParameters() const { return 1; }
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *context ,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ if (!context->HeadTarget)
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<TARGET_POLICY:prop> may only be used with binary targets. It "
+ "may not be used with add_custom_command or add_custom_target.");
+ return std::string();
+ }
+
+ context->HadContextSensitiveCondition = true;
+ context->HadHeadSensitiveCondition = true;
+
+ for (size_t i = 1; i < cmArraySize(targetPolicyWhitelist); ++i)
+ {
+ const char *policy = targetPolicyWhitelist[i];
+ if (parameters.front() == policy)
+ {
+ cmLocalGenerator* lg = context->HeadTarget->GetLocalGenerator();
+ switch(statusForTarget(context->HeadTarget, policy))
+ {
+ case cmPolicies::WARN:
+ lg->IssueMessage(cmake::AUTHOR_WARNING,
+ cmPolicies::GetPolicyWarning(policyForString(policy)));
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::OLD:
+ return "0";
+ case cmPolicies::NEW:
+ return "1";
+ }
+ }
+ }
+ reportError(context, content->GetOriginalExpression(),
+ "$<TARGET_POLICY:prop> may only be used with a limited number of "
+ "policies. Currently it may be used with the following policies:\n"
+
+#define STRINGIFY_HELPER(X) #X
+#define STRINGIFY(X) STRINGIFY_HELPER(X)
+
+#define TARGET_POLICY_LIST_ITEM(POLICY) \
+ " * " STRINGIFY(POLICY) "\n"
+
+ CM_FOR_EACH_TARGET_POLICY(TARGET_POLICY_LIST_ITEM)
+
+#undef TARGET_POLICY_LIST_ITEM
+ );
+ return std::string();
+ }
+
+} targetPolicyNode;
+
+//----------------------------------------------------------------------------
+static const struct InstallPrefixNode : public cmGeneratorExpressionNode
+{
+ InstallPrefixNode() {}
+
+ virtual bool GeneratesContent() const { return true; }
+ virtual int NumExpectedParameters() const { return 0; }
+
+ std::string Evaluate(const std::vector<std::string> &,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "INSTALL_PREFIX is a marker for install(EXPORT) only. It "
+ "should never be evaluated.");
+ return std::string();
+ }
+
+} installPrefixNode;
+
+//----------------------------------------------------------------------------
+class ArtifactNameTag;
+class ArtifactLinkerTag;
+class ArtifactSonameTag;
+class ArtifactPdbTag;
+
+class ArtifactPathTag;
+class ArtifactDirTag;
+
+//----------------------------------------------------------------------------
+template<typename ArtifactT>
+struct TargetFilesystemArtifactResultCreator
+{
+ static std::string Create(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content);
+};
+
+//----------------------------------------------------------------------------
+template<>
+struct TargetFilesystemArtifactResultCreator<ArtifactSonameTag>
+{
+ static std::string Create(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content)
+ {
+ // The target soname file (.so.1).
+ if(target->IsDLLPlatform())
+ {
+ ::reportError(context, content->GetOriginalExpression(),
+ "TARGET_SONAME_FILE is not allowed "
+ "for DLL target platforms.");
+ return std::string();
+ }
+ if(target->GetType() != cmState::SHARED_LIBRARY)
+ {
+ ::reportError(context, content->GetOriginalExpression(),
+ "TARGET_SONAME_FILE is allowed only for "
+ "SHARED libraries.");
+ return std::string();
+ }
+ std::string result = target->GetDirectory(context->Config);
+ result += "/";
+ result += target->GetSOName(context->Config);
+ return result;
+ }
+};
+
+//----------------------------------------------------------------------------
+template<>
+struct TargetFilesystemArtifactResultCreator<ArtifactPdbTag>
+{
+ static std::string Create(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content)
+ {
+ if (target->IsImported())
+ {
+ ::reportError(context, content->GetOriginalExpression(),
+ "TARGET_PDB_FILE not allowed for IMPORTED targets.");
+ return std::string();
+ }
+
+ std::string language = target->GetLinkerLanguage(context->Config);
+
+ std::string pdbSupportVar = "CMAKE_" + language + "_LINKER_SUPPORTS_PDB";
+
+ if(!context->LG->GetMakefile()->IsOn(pdbSupportVar))
+ {
+ ::reportError(context, content->GetOriginalExpression(),
+ "TARGET_PDB_FILE is not supported by the target linker.");
+ return std::string();
+ }
+
+ cmState::TargetType targetType = target->GetType();
+
+ if(targetType != cmState::SHARED_LIBRARY &&
+ targetType != cmState::MODULE_LIBRARY &&
+ targetType != cmState::EXECUTABLE)
+ {
+ ::reportError(context, content->GetOriginalExpression(),
+ "TARGET_PDB_FILE is allowed only for "
+ "targets with linker created artifacts.");
+ return std::string();
+ }
+
+ std::string result = target->GetPDBDirectory(context->Config);
+ result += "/";
+ result += target->GetPDBName(context->Config);
+ return result;
+ }
+};
+
+//----------------------------------------------------------------------------
+template<>
+struct TargetFilesystemArtifactResultCreator<ArtifactLinkerTag>
+{
+ static std::string Create(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content)
+ {
+ // The file used to link to the target (.so, .lib, .a).
+ if(!target->IsLinkable())
+ {
+ ::reportError(context, content->GetOriginalExpression(),
+ "TARGET_LINKER_FILE is allowed only for libraries and "
+ "executables with ENABLE_EXPORTS.");
+ return std::string();
+ }
+ return target->GetFullPath(context->Config,
+ target->HasImportLibrary());
+ }
+};
+
+//----------------------------------------------------------------------------
+template<>
+struct TargetFilesystemArtifactResultCreator<ArtifactNameTag>
+{
+ static std::string Create(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *)
+ {
+ return target->GetFullPath(context->Config, false, true);
+ }
+};
+
+
+//----------------------------------------------------------------------------
+template<typename ArtifactT>
+struct TargetFilesystemArtifactResultGetter
+{
+ static std::string Get(const std::string &result);
+};
+
+//----------------------------------------------------------------------------
+template<>
+struct TargetFilesystemArtifactResultGetter<ArtifactNameTag>
+{
+ static std::string Get(const std::string &result)
+ { return cmSystemTools::GetFilenameName(result); }
+};
+
+//----------------------------------------------------------------------------
+template<>
+struct TargetFilesystemArtifactResultGetter<ArtifactDirTag>
+{
+ static std::string Get(const std::string &result)
+ { return cmSystemTools::GetFilenamePath(result); }
+};
+
+//----------------------------------------------------------------------------
+template<>
+struct TargetFilesystemArtifactResultGetter<ArtifactPathTag>
+{
+ static std::string Get(const std::string &result)
+ { return result; }
+};
+
+//----------------------------------------------------------------------------
+template<typename ArtifactT, typename ComponentT>
+struct TargetFilesystemArtifact : public cmGeneratorExpressionNode
+{
+ TargetFilesystemArtifact() {}
+
+ virtual int NumExpectedParameters() const { return 1; }
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *dagChecker) const
+ {
+ // Lookup the referenced target.
+ std::string name = *parameters.begin();
+
+ if (!cmGeneratorExpression::IsValidTargetName(name))
+ {
+ ::reportError(context, content->GetOriginalExpression(),
+ "Expression syntax not recognized.");
+ return std::string();
+ }
+ cmGeneratorTarget* target =
+ context->LG->FindGeneratorTargetToUse(name);
+ if(!target)
+ {
+ ::reportError(context, content->GetOriginalExpression(),
+ "No target \"" + name + "\"");
+ return std::string();
+ }
+ if(target->GetType() >= cmState::OBJECT_LIBRARY &&
+ target->GetType() != cmState::UNKNOWN_LIBRARY)
+ {
+ ::reportError(context, content->GetOriginalExpression(),
+ "Target \"" + name + "\" is not an executable or library.");
+ return std::string();
+ }
+ if (dagChecker && (dagChecker->EvaluatingLinkLibraries(name.c_str())
+ || (dagChecker->EvaluatingSources()
+ && name == dagChecker->TopTarget())))
+ {
+ ::reportError(context, content->GetOriginalExpression(),
+ "Expressions which require the linker language may not "
+ "be used while evaluating link libraries");
+ return std::string();
+ }
+ context->DependTargets.insert(target);
+ context->AllTargets.insert(target);
+
+ std::string result =
+ TargetFilesystemArtifactResultCreator<ArtifactT>::Create(
+ target,
+ context,
+ content);
+ if (context->HadError)
+ {
+ return std::string();
+ }
+ return
+ TargetFilesystemArtifactResultGetter<ComponentT>::Get(result);
+ }
+};
+
+//----------------------------------------------------------------------------
+template<typename ArtifactT>
+struct TargetFilesystemArtifactNodeGroup
+{
+ TargetFilesystemArtifactNodeGroup()
+ {
+ }
+
+ TargetFilesystemArtifact<ArtifactT, ArtifactPathTag> File;
+ TargetFilesystemArtifact<ArtifactT, ArtifactNameTag> FileName;
+ TargetFilesystemArtifact<ArtifactT, ArtifactDirTag> FileDir;
+};
+
+//----------------------------------------------------------------------------
+static const
+TargetFilesystemArtifactNodeGroup<ArtifactNameTag> targetNodeGroup;
+
+static const
+TargetFilesystemArtifactNodeGroup<ArtifactLinkerTag> targetLinkerNodeGroup;
+
+static const
+TargetFilesystemArtifactNodeGroup<ArtifactSonameTag> targetSoNameNodeGroup;
+
+static const
+TargetFilesystemArtifactNodeGroup<ArtifactPdbTag> targetPdbNodeGroup;
+
+//----------------------------------------------------------------------------
+static const struct ShellPathNode : public cmGeneratorExpressionNode
+{
+ ShellPathNode() {}
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ if (!cmSystemTools::FileIsFullPath(parameters.front()))
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "\"" + parameters.front() + "\" is not an absolute path.");
+ return std::string();
+ }
+ cmOutputConverter converter(context->LG->GetStateSnapshot());
+ return converter.ConvertDirectorySeparatorsForShell(parameters.front());
+ }
+} shellPathNode;
+
+//----------------------------------------------------------------------------
+const cmGeneratorExpressionNode*
+cmGeneratorExpressionNode::GetNode(const std::string &identifier)
+{
+ typedef std::map<std::string, const cmGeneratorExpressionNode*> NodeMap;
+ static NodeMap nodeMap;
+ if (nodeMap.empty())
+ {
+ nodeMap["0"] = &zeroNode;
+ nodeMap["1"] = &oneNode;
+ nodeMap["AND"] = &andNode;
+ nodeMap["OR"] = &orNode;
+ nodeMap["NOT"] = &notNode;
+ nodeMap["C_COMPILER_ID"] = &cCompilerIdNode;
+ nodeMap["CXX_COMPILER_ID"] = &cxxCompilerIdNode;
+ nodeMap["VERSION_GREATER"] = &versionGreaterNode;
+ nodeMap["VERSION_LESS"] = &versionLessNode;
+ nodeMap["VERSION_EQUAL"] = &versionEqualNode;
+ nodeMap["C_COMPILER_VERSION"] = &cCompilerVersionNode;
+ nodeMap["CXX_COMPILER_VERSION"] = &cxxCompilerVersionNode;
+ nodeMap["PLATFORM_ID"] = &platformIdNode;
+ nodeMap["COMPILE_FEATURES"] = &compileFeaturesNode;
+ nodeMap["CONFIGURATION"] = &configurationNode;
+ nodeMap["CONFIG"] = &configurationTestNode;
+ nodeMap["TARGET_FILE"] = &targetNodeGroup.File;
+ nodeMap["TARGET_LINKER_FILE"] = &targetLinkerNodeGroup.File;
+ nodeMap["TARGET_SONAME_FILE"] = &targetSoNameNodeGroup.File;
+ nodeMap["TARGET_PDB_FILE"] = &targetPdbNodeGroup.File;
+ nodeMap["TARGET_FILE_NAME"] = &targetNodeGroup.FileName;
+ nodeMap["TARGET_LINKER_FILE_NAME"] = &targetLinkerNodeGroup.FileName;
+ nodeMap["TARGET_SONAME_FILE_NAME"] = &targetSoNameNodeGroup.FileName;
+ nodeMap["TARGET_PDB_FILE_NAME"] = &targetPdbNodeGroup.FileName;
+ nodeMap["TARGET_FILE_DIR"] = &targetNodeGroup.FileDir;
+ nodeMap["TARGET_LINKER_FILE_DIR"] = &targetLinkerNodeGroup.FileDir;
+ nodeMap["TARGET_SONAME_FILE_DIR"] = &targetSoNameNodeGroup.FileDir;
+ nodeMap["TARGET_PDB_FILE_DIR"] = &targetPdbNodeGroup.FileDir;
+ nodeMap["STREQUAL"] = &strEqualNode;
+ nodeMap["EQUAL"] = &equalNode;
+ nodeMap["LOWER_CASE"] = &lowerCaseNode;
+ nodeMap["UPPER_CASE"] = &upperCaseNode;
+ nodeMap["MAKE_C_IDENTIFIER"] = &makeCIdentifierNode;
+ nodeMap["BOOL"] = &boolNode;
+ nodeMap["ANGLE-R"] = &angle_rNode;
+ nodeMap["COMMA"] = &commaNode;
+ nodeMap["SEMICOLON"] = &semicolonNode;
+ nodeMap["TARGET_PROPERTY"] = &targetPropertyNode;
+ nodeMap["TARGET_NAME"] = &targetNameNode;
+ nodeMap["TARGET_OBJECTS"] = &targetObjectsNode;
+ nodeMap["TARGET_POLICY"] = &targetPolicyNode;
+ nodeMap["BUILD_INTERFACE"] = &buildInterfaceNode;
+ nodeMap["INSTALL_INTERFACE"] = &installInterfaceNode;
+ nodeMap["INSTALL_PREFIX"] = &installPrefixNode;
+ nodeMap["JOIN"] = &joinNode;
+ nodeMap["LINK_ONLY"] = &linkOnlyNode;
+ nodeMap["COMPILE_LANGUAGE"] = &languageNode;
+ nodeMap["SHELL_PATH"] = &shellPathNode;
+ }
+ NodeMap::const_iterator i = nodeMap.find(identifier);
+ if (i == nodeMap.end())
+ {
+ return 0;
+ }
+ return i->second;
+}
+
+//----------------------------------------------------------------------------
+void reportError(cmGeneratorExpressionContext *context,
+ const std::string &expr, const std::string &result)
+{
+ context->HadError = true;
+ if (context->Quiet)
+ {
+ return;
+ }
+
+ std::ostringstream e;
+ e << "Error evaluating generator expression:\n"
+ << " " << expr << "\n"
+ << result;
+ context->LG->GetCMakeInstance()
+ ->IssueMessage(cmake::FATAL_ERROR, e.str(),
+ context->Backtrace);
+}
diff --git a/Source/cmGeneratorExpressionNode.h b/Source/cmGeneratorExpressionNode.h
new file mode 100644
index 000000000..854811b99
--- /dev/null
+++ b/Source/cmGeneratorExpressionNode.h
@@ -0,0 +1,69 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2012 Stephen Kelly <steveire@gmail.com>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmGeneratorExpressionNode_h
+#define cmGeneratorExpressionNode_h
+
+#include "cmGeneratorExpressionEvaluator.h"
+#include "cmGeneratorExpressionParser.h"
+#include "cmGeneratorExpressionDAGChecker.h"
+#include "cmGeneratorExpression.h"
+#include "cmLocalGenerator.h"
+#include "cmSourceFile.h"
+
+#include <cmsys/String.h>
+
+#include <assert.h>
+#include <errno.h>
+
+#include "cmListFileCache.h"
+
+//----------------------------------------------------------------------------
+struct cmGeneratorExpressionNode
+{
+ enum {
+ DynamicParameters = 0,
+ OneOrMoreParameters = -1,
+ OneOrZeroParameters = -2
+ };
+ virtual ~cmGeneratorExpressionNode() {}
+
+ virtual bool GeneratesContent() const { return true; }
+
+ virtual bool RequiresLiteralInput() const { return false; }
+
+ virtual bool AcceptsArbitraryContentParameter() const
+ { return false; }
+
+ virtual int NumExpectedParameters() const { return 1; }
+
+ virtual std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *dagChecker
+ ) const = 0;
+
+ static std::string EvaluateDependentExpression(
+ std::string const& prop, cmLocalGenerator *lg,
+ cmGeneratorExpressionContext *context,
+ const cmGeneratorTarget* headTarget,
+ const cmGeneratorTarget* currentTarget,
+ cmGeneratorExpressionDAGChecker *dagChecker);
+
+ static const cmGeneratorExpressionNode* GetNode(
+ const std::string &identifier);
+};
+
+//----------------------------------------------------------------------------
+void reportError(cmGeneratorExpressionContext *context,
+ const std::string &expr, const std::string &result);
+
+#endif
diff --git a/Source/cmGeneratorExpressionParser.cxx b/Source/cmGeneratorExpressionParser.cxx
index e1fb8f1de..a17da8cb5 100644
--- a/Source/cmGeneratorExpressionParser.cxx
+++ b/Source/cmGeneratorExpressionParser.cxx
@@ -39,7 +39,7 @@ void cmGeneratorExpressionParser::Parse(
static void extendText(std::vector<cmGeneratorExpressionEvaluator*> &result,
std::vector<cmGeneratorExpressionToken>::const_iterator it)
{
- if (result.size() > 0
+ if (!result.empty()
&& (*(result.end() - 1))->GetType()
== cmGeneratorExpressionEvaluator::Text)
{
@@ -57,7 +57,7 @@ static void extendText(std::vector<cmGeneratorExpressionEvaluator*> &result,
static void extendResult(std::vector<cmGeneratorExpressionEvaluator*> &result,
const std::vector<cmGeneratorExpressionEvaluator*> &contents)
{
- if (result.size() > 0
+ if (!result.empty()
&& (*(result.end() - 1))->GetType()
== cmGeneratorExpressionEvaluator::Text
&& (*contents.begin())->GetType()
@@ -235,7 +235,7 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression(
return;
}
- int contentLength = ((this->it - 1)->Content
+ size_t contentLength = ((this->it - 1)->Content
- startToken->Content)
+ (this->it - 1)->Length;
GeneratorExpressionContent *content = new GeneratorExpressionContent(
@@ -256,7 +256,7 @@ void cmGeneratorExpressionParser::ParseContent(
{
if (this->NestingLevel == 0)
{
- if (result.size() > 0
+ if (!result.empty()
&& (*(result.end() - 1))->GetType()
== cmGeneratorExpressionEvaluator::Text)
{
@@ -292,11 +292,11 @@ void cmGeneratorExpressionParser::ParseContent(
}
else
{
- assert(!"Got unexpected syntax token.");
+ assert(0 && "Got unexpected syntax token.");
}
assert(this->it != this->Tokens.end());
++this->it;
return;
}
- assert(!"Unhandled token in generator expression.");
+ assert(0 && "Unhandled token in generator expression.");
}
diff --git a/Source/cmGeneratorExpressionParser.h b/Source/cmGeneratorExpressionParser.h
index 28f14410f..5bd67774d 100644
--- a/Source/cmGeneratorExpressionParser.h
+++ b/Source/cmGeneratorExpressionParser.h
@@ -19,8 +19,6 @@
#include "cmListFileCache.h"
-class cmMakefile;
-class cmTarget;
struct cmGeneratorExpressionEvaluator;
//----------------------------------------------------------------------------
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 62ac2638d..ff12320bf 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -18,273 +18,2593 @@
#include "cmSourceFile.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionDAGChecker.h"
+#include "cmComputeLinkInformation.h"
+#include "cmCustomCommandGenerator.h"
+#include "cmAlgorithms.h"
+
+#include <queue>
+
+#include <errno.h>
+#include "assert.h"
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+#include <cmsys/hash_set.hxx>
+#define UNORDERED_SET cmsys::hash_set
+#else
+#define UNORDERED_SET std::set
+#endif
+
+class cmGeneratorTarget::TargetPropertyEntry {
+ static cmLinkImplItem NoLinkImplItem;
+public:
+ TargetPropertyEntry(cmsys::auto_ptr<cmCompiledGeneratorExpression> cge,
+ cmLinkImplItem const& item = NoLinkImplItem)
+ : ge(cge), LinkImplItem(item)
+ {}
+ const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge;
+ cmLinkImplItem const& LinkImplItem;
+};
+cmLinkImplItem cmGeneratorTarget::TargetPropertyEntry::NoLinkImplItem;
+
+//----------------------------------------------------------------------------
+void reportBadObjLib(std::vector<cmSourceFile*> const& badObjLib,
+ cmGeneratorTarget const* target, cmake *cm)
+{
+ if(!badObjLib.empty())
+ {
+ std::ostringstream e;
+ e << "OBJECT library \"" << target->GetName() << "\" contains:\n";
+ for(std::vector<cmSourceFile*>::const_iterator i = badObjLib.begin();
+ i != badObjLib.end(); ++i)
+ {
+ e << " " << (*i)->GetLocation().GetName() << "\n";
+ }
+ e << "but may contain only sources that compile, header files, and "
+ "other files that would not affect linking of a normal library.";
+ cm->IssueMessage(cmake::FATAL_ERROR, e.str(),
+ target->GetBacktrace());
+ }
+}
+
+struct ObjectSourcesTag {};
+struct CustomCommandsTag {};
+struct ExtraSourcesTag {};
+struct HeaderSourcesTag {};
+struct ExternalObjectsTag {};
+struct IDLSourcesTag {};
+struct ResxTag {};
+struct ModuleDefinitionFileTag {};
+struct AppManifestTag{};
+struct ManifestsTag{};
+struct CertificatesTag{};
+struct XamlTag{};
+
+template<typename Tag, typename OtherTag>
+struct IsSameTag
+{
+ enum {
+ Result = false
+ };
+};
+
+template<typename Tag>
+struct IsSameTag<Tag, Tag>
+{
+ enum {
+ Result = true
+ };
+};
+
+template<bool>
+struct DoAccept
+{
+ template <typename T> static void Do(T&, cmSourceFile*) {}
+};
+
+template<>
+struct DoAccept<true>
+{
+ static void Do(std::vector<cmSourceFile const*>& files, cmSourceFile* f)
+ {
+ files.push_back(f);
+ }
+ static void Do(cmGeneratorTarget::ResxData& data, cmSourceFile* f)
+ {
+ // Build and save the name of the corresponding .h file
+ // This relationship will be used later when building the project files.
+ // Both names would have been auto generated from Visual Studio
+ // where the user supplied the file name and Visual Studio
+ // appended the suffix.
+ std::string resx = f->GetFullPath();
+ std::string hFileName = resx.substr(0, resx.find_last_of(".")) + ".h";
+ data.ExpectedResxHeaders.insert(hFileName);
+ data.ResxSources.push_back(f);
+ }
+ static void Do(cmGeneratorTarget::XamlData& data, cmSourceFile* f)
+ {
+ // Build and save the name of the corresponding .h and .cpp file
+ // This relationship will be used later when building the project files.
+ // Both names would have been auto generated from Visual Studio
+ // where the user supplied the file name and Visual Studio
+ // appended the suffix.
+ std::string xaml = f->GetFullPath();
+ std::string hFileName = xaml + ".h";
+ std::string cppFileName = xaml + ".cpp";
+ data.ExpectedXamlHeaders.insert(hFileName);
+ data.ExpectedXamlSources.insert(cppFileName);
+ data.XamlSources.push_back(f);
+ }
+ static void Do(std::string& data, cmSourceFile* f)
+ {
+ data = f->GetFullPath();
+ }
+};
+
+//----------------------------------------------------------------------------
+template<typename Tag, typename DataType = std::vector<cmSourceFile const*> >
+struct TagVisitor
+{
+ DataType& Data;
+ std::vector<cmSourceFile*> BadObjLibFiles;
+ cmGeneratorTarget const* Target;
+ cmGlobalGenerator *GlobalGenerator;
+ cmsys::RegularExpression Header;
+ bool IsObjLib;
+
+ TagVisitor(cmGeneratorTarget const* target, DataType& data)
+ : Data(data), Target(target),
+ GlobalGenerator(target->GetLocalGenerator()->GetGlobalGenerator()),
+ Header(CM_HEADER_REGEX),
+ IsObjLib(target->GetType() == cmState::OBJECT_LIBRARY)
+ {
+ }
+
+ ~TagVisitor()
+ {
+ reportBadObjLib(this->BadObjLibFiles, this->Target,
+ this->GlobalGenerator->GetCMakeInstance());
+ }
+
+ void Accept(cmSourceFile *sf)
+ {
+ std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
+ if(sf->GetCustomCommand())
+ {
+ DoAccept<IsSameTag<Tag, CustomCommandsTag>::Result>::Do(this->Data, sf);
+ }
+ else if(this->Target->GetType() == cmState::UTILITY)
+ {
+ DoAccept<IsSameTag<Tag, ExtraSourcesTag>::Result>::Do(this->Data, sf);
+ }
+ else if(sf->GetPropertyAsBool("HEADER_FILE_ONLY"))
+ {
+ DoAccept<IsSameTag<Tag, HeaderSourcesTag>::Result>::Do(this->Data, sf);
+ }
+ else if(sf->GetPropertyAsBool("EXTERNAL_OBJECT"))
+ {
+ DoAccept<IsSameTag<Tag, ExternalObjectsTag>::Result>::Do(this->Data, sf);
+ if(this->IsObjLib)
+ {
+ this->BadObjLibFiles.push_back(sf);
+ }
+ }
+ else if(!sf->GetLanguage().empty())
+ {
+ DoAccept<IsSameTag<Tag, ObjectSourcesTag>::Result>::Do(this->Data, sf);
+ }
+ else if(ext == "def")
+ {
+ DoAccept<IsSameTag<Tag, ModuleDefinitionFileTag>::Result>::Do(this->Data,
+ sf);
+ if(this->IsObjLib)
+ {
+ this->BadObjLibFiles.push_back(sf);
+ }
+ }
+ else if(ext == "idl")
+ {
+ DoAccept<IsSameTag<Tag, IDLSourcesTag>::Result>::Do(this->Data, sf);
+ if(this->IsObjLib)
+ {
+ this->BadObjLibFiles.push_back(sf);
+ }
+ }
+ else if(ext == "resx")
+ {
+ DoAccept<IsSameTag<Tag, ResxTag>::Result>::Do(this->Data, sf);
+ }
+ else if (ext == "appxmanifest")
+ {
+ DoAccept<IsSameTag<Tag, AppManifestTag>::Result>::Do(this->Data, sf);
+ }
+ else if (ext == "manifest")
+ {
+ DoAccept<IsSameTag<Tag, ManifestsTag>::Result>::Do(this->Data, sf);
+ }
+ else if (ext == "pfx")
+ {
+ DoAccept<IsSameTag<Tag, CertificatesTag>::Result>::Do(this->Data, sf);
+ }
+ else if (ext == "xaml")
+ {
+ DoAccept<IsSameTag<Tag, XamlTag>::Result>::Do(this->Data, sf);
+ }
+ else if(this->Header.find(sf->GetFullPath().c_str()))
+ {
+ DoAccept<IsSameTag<Tag, HeaderSourcesTag>::Result>::Do(this->Data, sf);
+ }
+ else if(this->GlobalGenerator->IgnoreFile(sf->GetExtension().c_str()))
+ {
+ DoAccept<IsSameTag<Tag, ExtraSourcesTag>::Result>::Do(this->Data, sf);
+ }
+ else
+ {
+ DoAccept<IsSameTag<Tag, ExtraSourcesTag>::Result>::Do(this->Data, sf);
+ }
+ }
+};
+
+void CreatePropertyGeneratorExpressions(
+ cmStringRange const& entries,
+ cmBacktraceRange const& backtraces,
+ std::vector<cmGeneratorTarget::TargetPropertyEntry*>& items,
+ bool evaluateForBuildsystem = false)
+{
+ std::vector<cmListFileBacktrace>::const_iterator btIt = backtraces.begin();
+ for (std::vector<std::string>::const_iterator it = entries.begin();
+ it != entries.end(); ++it, ++btIt)
+ {
+ cmGeneratorExpression ge(*btIt);
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*it);
+ cge->SetEvaluateForBuildsystem(evaluateForBuildsystem);
+ items.push_back(new cmGeneratorTarget::TargetPropertyEntry(cge));
+ }
+}
//----------------------------------------------------------------------------
-cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t)
+cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
+ : Target(t),
+ SourceFileFlagsConstructed(false),
+ PolicyWarnedCMP0022(false),
+ DebugIncludesDone(false),
+ DebugCompileOptionsDone(false),
+ DebugCompileFeaturesDone(false),
+ DebugCompileDefinitionsDone(false),
+ DebugSourcesDone(false),
+ LinkImplementationLanguageIsContextDependent(true),
+ UtilityItemsDone(false)
{
this->Makefile = this->Target->GetMakefile();
- this->LocalGenerator = this->Makefile->GetLocalGenerator();
+ this->LocalGenerator = lg;
this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
- this->ClassifySources();
- this->LookupObjectLibraries();
+
+ this->GlobalGenerator->ComputeTargetObjectDirectory(this);
+
+ CreatePropertyGeneratorExpressions(
+ t->GetIncludeDirectoriesEntries(),
+ t->GetIncludeDirectoriesBacktraces(),
+ this->IncludeDirectoriesEntries);
+
+ CreatePropertyGeneratorExpressions(
+ t->GetCompileOptionsEntries(),
+ t->GetCompileOptionsBacktraces(),
+ this->CompileOptionsEntries);
+
+ CreatePropertyGeneratorExpressions(
+ t->GetCompileFeaturesEntries(),
+ t->GetCompileFeaturesBacktraces(),
+ this->CompileFeaturesEntries);
+
+ CreatePropertyGeneratorExpressions(
+ t->GetCompileDefinitionsEntries(),
+ t->GetCompileDefinitionsBacktraces(),
+ this->CompileDefinitionsEntries);
+
+ CreatePropertyGeneratorExpressions(
+ t->GetSourceEntries(),
+ t->GetSourceBacktraces(),
+ this->SourceEntries, true);
+
+ this->DLLPlatform = (this->Makefile->IsOn("WIN32") ||
+ this->Makefile->IsOn("CYGWIN") ||
+ this->Makefile->IsOn("MINGW"));
+
+ this->PolicyMap = t->PolicyMap;
+}
+
+cmGeneratorTarget::~cmGeneratorTarget()
+{
+ cmDeleteAll(this->IncludeDirectoriesEntries);
+ cmDeleteAll(this->CompileOptionsEntries);
+ cmDeleteAll(this->CompileFeaturesEntries);
+ cmDeleteAll(this->CompileDefinitionsEntries);
+ cmDeleteAll(this->SourceEntries);
+ cmDeleteAll(this->LinkInformation);
+ this->LinkInformation.clear();
+}
+
+cmLocalGenerator* cmGeneratorTarget::GetLocalGenerator() const
+{
+ return this->LocalGenerator;
}
//----------------------------------------------------------------------------
-int cmGeneratorTarget::GetType() const
+cmState::TargetType cmGeneratorTarget::GetType() const
{
return this->Target->GetType();
}
//----------------------------------------------------------------------------
-const char *cmGeneratorTarget::GetName() const
+const std::string& cmGeneratorTarget::GetName() const
{
return this->Target->GetName();
}
//----------------------------------------------------------------------------
-const char *cmGeneratorTarget::GetProperty(const char *prop)
+std::string cmGeneratorTarget::GetExportName() const
+{
+ const char *exportName = this->GetProperty("EXPORT_NAME");
+
+ if (exportName && *exportName)
+ {
+ if (!cmGeneratorExpression::IsValidTargetName(exportName))
+ {
+ std::ostringstream e;
+ e << "EXPORT_NAME property \"" << exportName << "\" for \""
+ << this->GetName() << "\": is not valid.";
+ cmSystemTools::Error(e.str().c_str());
+ return "";
+ }
+ return exportName;
+ }
+ return this->GetName();
+}
+
+//----------------------------------------------------------------------------
+const char *cmGeneratorTarget::GetProperty(const std::string& prop) const
{
return this->Target->GetProperty(prop);
}
//----------------------------------------------------------------------------
-bool cmGeneratorTarget::IsSystemIncludeDirectory(const char *dir,
- const char *config)
+const char* cmGeneratorTarget::GetOutputTargetType(bool implib) const
+{
+ switch(this->GetType())
+ {
+ case cmState::SHARED_LIBRARY:
+ if(this->IsDLLPlatform())
+ {
+ if(implib)
+ {
+ // A DLL import library is treated as an archive target.
+ return "ARCHIVE";
+ }
+ else
+ {
+ // A DLL shared library is treated as a runtime target.
+ return "RUNTIME";
+ }
+ }
+ else
+ {
+ // For non-DLL platforms shared libraries are treated as
+ // library targets.
+ return "LIBRARY";
+ }
+ case cmState::STATIC_LIBRARY:
+ // Static libraries are always treated as archive targets.
+ return "ARCHIVE";
+ case cmState::MODULE_LIBRARY:
+ if(implib)
+ {
+ // Module libraries are always treated as library targets.
+ return "ARCHIVE";
+ }
+ else
+ {
+ // Module import libraries are treated as archive targets.
+ return "LIBRARY";
+ }
+ case cmState::EXECUTABLE:
+ if(implib)
+ {
+ // Executable import libraries are treated as archive targets.
+ return "ARCHIVE";
+ }
+ else
+ {
+ // Executables are always treated as runtime targets.
+ return "RUNTIME";
+ }
+ default:
+ break;
+ }
+ return "";
+}
+
+//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetOutputName(const std::string& config,
+ bool implib) const
+{
+ // Lookup/compute/cache the output name for this configuration.
+ OutputNameKey key(config, implib);
+ cmGeneratorTarget::OutputNameMapType::iterator i =
+ this->OutputNameMap.find(key);
+ if(i == this->OutputNameMap.end())
+ {
+ // Add empty name in map to detect potential recursion.
+ OutputNameMapType::value_type entry(key, "");
+ i = this->OutputNameMap.insert(entry).first;
+
+ // Compute output name.
+ std::vector<std::string> props;
+ std::string type = this->GetOutputTargetType(implib);
+ std::string configUpper = cmSystemTools::UpperCase(config);
+ if(!type.empty() && !configUpper.empty())
+ {
+ // <ARCHIVE|LIBRARY|RUNTIME>_OUTPUT_NAME_<CONFIG>
+ props.push_back(type + "_OUTPUT_NAME_" + configUpper);
+ }
+ if(!type.empty())
+ {
+ // <ARCHIVE|LIBRARY|RUNTIME>_OUTPUT_NAME
+ props.push_back(type + "_OUTPUT_NAME");
+ }
+ if(!configUpper.empty())
+ {
+ // OUTPUT_NAME_<CONFIG>
+ props.push_back("OUTPUT_NAME_" + configUpper);
+ // <CONFIG>_OUTPUT_NAME
+ props.push_back(configUpper + "_OUTPUT_NAME");
+ }
+ // OUTPUT_NAME
+ props.push_back("OUTPUT_NAME");
+
+ std::string outName;
+ for(std::vector<std::string>::const_iterator it = props.begin();
+ it != props.end(); ++it)
+ {
+ if (const char* outNameProp = this->GetProperty(*it))
+ {
+ outName = outNameProp;
+ break;
+ }
+ }
+
+ if(outName.empty())
+ {
+ outName = this->GetName();
+ }
+
+ // Now evaluate genex and update the previously-prepared map entry.
+ cmGeneratorExpression ge;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(outName);
+ i->second = cge->Evaluate(this->LocalGenerator, config);
+ }
+ else if(i->second.empty())
+ {
+ // An empty map entry indicates we have been called recursively
+ // from the above block.
+ this->LocalGenerator->GetCMakeInstance()
+ ->IssueMessage(
+ cmake::FATAL_ERROR,
+ "Target '" + this->GetName() + "' OUTPUT_NAME depends on itself.",
+ this->GetBacktrace());
+ }
+ return i->second;
+}
+
+void cmGeneratorTarget::AddSource(const std::string& src)
+{
+ this->Target->AddSource(src);
+ cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+ cmGeneratorExpression ge(lfbt);
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(src);
+ cge->SetEvaluateForBuildsystem(true);
+ this->SourceEntries.push_back(
+ new TargetPropertyEntry(cge));
+ this->SourceFilesMap.clear();
+ this->LinkImplementationLanguageIsContextDependent = true;
+}
+
+void cmGeneratorTarget::AddTracedSources(std::vector<std::string> const& srcs)
+{
+ this->Target->AddTracedSources(srcs);
+ if (!srcs.empty())
+ {
+ std::string srcFiles = cmJoin(srcs, ";");
+ this->SourceFilesMap.clear();
+ this->LinkImplementationLanguageIsContextDependent = true;
+ cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+ cmGeneratorExpression ge(lfbt);
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(srcFiles);
+ cge->SetEvaluateForBuildsystem(true);
+ this->SourceEntries.push_back(
+ new cmGeneratorTarget::TargetPropertyEntry(cge));
+ }
+}
+
+//----------------------------------------------------------------------------
+std::vector<cmSourceFile*> const*
+cmGeneratorTarget::GetSourceDepends(cmSourceFile const* sf) const
+{
+ SourceEntriesType::const_iterator i = this->SourceDepends.find(sf);
+ if(i != this->SourceDepends.end())
+ {
+ return &i->second.Depends;
+ }
+ return 0;
+}
+
+static void handleSystemIncludesDep(cmLocalGenerator *lg,
+ cmGeneratorTarget const* depTgt,
+ const std::string& config,
+ cmGeneratorTarget const* headTarget,
+ cmGeneratorExpressionDAGChecker *dagChecker,
+ std::vector<std::string>& result,
+ bool excludeImported)
+{
+ if (const char* dirs =
+ depTgt->GetProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES"))
+ {
+ cmGeneratorExpression ge;
+ cmSystemTools::ExpandListArgument(ge.Parse(dirs)
+ ->Evaluate(lg,
+ config, false, headTarget,
+ depTgt, dagChecker), result);
+ }
+ if (!depTgt->IsImported() || excludeImported)
+ {
+ return;
+ }
+
+ if (const char* dirs =
+ depTgt->GetProperty("INTERFACE_INCLUDE_DIRECTORIES"))
+ {
+ cmGeneratorExpression ge;
+ cmSystemTools::ExpandListArgument(ge.Parse(dirs)
+ ->Evaluate(lg,
+ config, false, headTarget,
+ depTgt, dagChecker), result);
+ }
+}
+
+#define IMPLEMENT_VISIT_IMPL(DATA, DATATYPE) \
+ { \
+ std::vector<cmSourceFile*> sourceFiles; \
+ this->GetSourceFiles(sourceFiles, config); \
+ TagVisitor< DATA##Tag DATATYPE > visitor(this, data); \
+ for(std::vector<cmSourceFile*>::const_iterator si = sourceFiles.begin(); \
+ si != sourceFiles.end(); ++si) \
+ { \
+ visitor.Accept(*si); \
+ } \
+ } \
+
+
+#define IMPLEMENT_VISIT(DATA) \
+ IMPLEMENT_VISIT_IMPL(DATA, EMPTY) \
+
+#define EMPTY
+#define COMMA ,
+
+//----------------------------------------------------------------------------
+void
+cmGeneratorTarget
+::GetObjectSources(std::vector<cmSourceFile const*> &data,
+ const std::string& config) const
+{
+ IMPLEMENT_VISIT(ObjectSources);
+
+ if (!this->Objects.empty())
+ {
+ return;
+ }
+
+ for(std::vector<cmSourceFile const*>::const_iterator it = data.begin();
+ it != data.end(); ++it)
+ {
+ this->Objects[*it];
+ }
+
+ this->LocalGenerator->ComputeObjectFilenames(this->Objects, this);
+}
+
+void cmGeneratorTarget::ComputeObjectMapping()
+{
+ if(!this->Objects.empty())
+ {
+ return;
+ }
+
+ std::vector<std::string> configs;
+ this->Makefile->GetConfigurations(configs);
+ if (configs.empty())
+ {
+ configs.push_back("");
+ }
+ for(std::vector<std::string>::const_iterator ci = configs.begin();
+ ci != configs.end(); ++ci)
+ {
+ std::vector<cmSourceFile const*> sourceFiles;
+ this->GetObjectSources(sourceFiles, *ci);
+ }
+}
+
+//----------------------------------------------------------------------------
+const char* cmGeneratorTarget::GetFeature(const std::string& feature,
+ const std::string& config) const
+{
+ if(!config.empty())
+ {
+ std::string featureConfig = feature;
+ featureConfig += "_";
+ featureConfig += cmSystemTools::UpperCase(config);
+ if(const char* value = this->GetProperty(featureConfig))
+ {
+ return value;
+ }
+ }
+ if(const char* value = this->GetProperty(feature))
+ {
+ return value;
+ }
+ return this->LocalGenerator->GetFeature(feature, config);
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::GetFeatureAsBool(const std::string& feature,
+ const std::string& config) const
+{
+ return cmSystemTools::IsOn(this->GetFeature(feature, config));
+}
+
+//----------------------------------------------------------------------------
+const std::string& cmGeneratorTarget::GetObjectName(cmSourceFile const* file)
+{
+ this->ComputeObjectMapping();
+ return this->Objects[file];
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::AddExplicitObjectName(cmSourceFile const* sf)
+{
+ this->ExplicitObjectName.insert(sf);
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::HasExplicitObjectName(cmSourceFile const* file) const
+{
+ const_cast<cmGeneratorTarget*>(this)->ComputeObjectMapping();
+ std::set<cmSourceFile const*>::const_iterator it
+ = this->ExplicitObjectName.find(file);
+ return it != this->ExplicitObjectName.end();
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget
+::GetIDLSources(std::vector<cmSourceFile const*>& data,
+ const std::string& config) const
+{
+ IMPLEMENT_VISIT(IDLSources);
+}
+
+//----------------------------------------------------------------------------
+void
+cmGeneratorTarget
+::GetHeaderSources(std::vector<cmSourceFile const*>& data,
+ const std::string& config) const
+{
+ IMPLEMENT_VISIT(HeaderSources);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget
+::GetExtraSources(std::vector<cmSourceFile const*>& data,
+ const std::string& config) const
+{
+ IMPLEMENT_VISIT(ExtraSources);
+}
+
+//----------------------------------------------------------------------------
+void
+cmGeneratorTarget
+::GetCustomCommands(std::vector<cmSourceFile const*>& data,
+ const std::string& config) const
+{
+ IMPLEMENT_VISIT(CustomCommands);
+}
+
+//----------------------------------------------------------------------------
+void
+cmGeneratorTarget
+::GetExternalObjects(std::vector<cmSourceFile const*>& data,
+ const std::string& config) const
+{
+ IMPLEMENT_VISIT(ExternalObjects);
+}
+
+//----------------------------------------------------------------------------
+void
+cmGeneratorTarget::GetExpectedResxHeaders(std::set<std::string>& srcs,
+ const std::string& config) const
+{
+ ResxData data;
+ IMPLEMENT_VISIT_IMPL(Resx, COMMA cmGeneratorTarget::ResxData)
+ srcs = data.ExpectedResxHeaders;
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget
+::GetResxSources(std::vector<cmSourceFile const*>& srcs,
+ const std::string& config) const
+{
+ ResxData data;
+ IMPLEMENT_VISIT_IMPL(Resx, COMMA cmGeneratorTarget::ResxData)
+ srcs = data.ResxSources;
+}
+
+//----------------------------------------------------------------------------
+void
+cmGeneratorTarget
+::GetAppManifest(std::vector<cmSourceFile const*>& data,
+ const std::string& config) const
+{
+ IMPLEMENT_VISIT(AppManifest);
+}
+
+//----------------------------------------------------------------------------
+void
+cmGeneratorTarget
+::GetManifests(std::vector<cmSourceFile const*>& data,
+ const std::string& config) const
+{
+ IMPLEMENT_VISIT(Manifests);
+}
+
+//----------------------------------------------------------------------------
+void
+cmGeneratorTarget
+::GetCertificates(std::vector<cmSourceFile const*>& data,
+ const std::string& config) const
{
+ IMPLEMENT_VISIT(Certificates);
+}
+
+//----------------------------------------------------------------------------
+void
+cmGeneratorTarget::GetExpectedXamlHeaders(std::set<std::string>& headers,
+ const std::string& config) const
+{
+ XamlData data;
+ IMPLEMENT_VISIT_IMPL(Xaml, COMMA cmGeneratorTarget::XamlData)
+ headers = data.ExpectedXamlHeaders;
+}
+
+//----------------------------------------------------------------------------
+void
+cmGeneratorTarget::GetExpectedXamlSources(std::set<std::string>& srcs,
+ const std::string& config) const
+{
+ XamlData data;
+ IMPLEMENT_VISIT_IMPL(Xaml, COMMA cmGeneratorTarget::XamlData)
+ srcs = data.ExpectedXamlSources;
+}
+
+std::set<cmLinkItem> const& cmGeneratorTarget::GetUtilityItems() const
+{
+ if(!this->UtilityItemsDone)
+ {
+ this->UtilityItemsDone = true;
+ std::set<std::string> const& utilities = this->GetUtilities();
+ for(std::set<std::string>::const_iterator i = utilities.begin();
+ i != utilities.end(); ++i)
+ {
+ cmGeneratorTarget* gt =
+ this->LocalGenerator->FindGeneratorTargetToUse(*i);
+ this->UtilityItems.insert(cmLinkItem(*i, gt));
+ }
+ }
+ return this->UtilityItems;
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget
+::GetXamlSources(std::vector<cmSourceFile const*>& srcs,
+ const std::string& config) const
+{
+ XamlData data;
+ IMPLEMENT_VISIT_IMPL(Xaml, COMMA cmGeneratorTarget::XamlData)
+ srcs = data.XamlSources;
+}
+
+//----------------------------------------------------------------------------
+const char* cmGeneratorTarget::GetLocation(const std::string& config) const
+{
+ static std::string location;
+ if (this->IsImported())
+ {
+ location = this->Target->ImportedGetFullPath(config, false);
+ }
+ else
+ {
+ location = this->GetFullPath(config, false);
+ }
+ return location.c_str();
+}
+
+std::vector<cmCustomCommand> const&
+cmGeneratorTarget::GetPreBuildCommands() const
+{
+ return this->Target->GetPreBuildCommands();
+}
+
+std::vector<cmCustomCommand> const&
+cmGeneratorTarget::GetPreLinkCommands() const
+{
+ return this->Target->GetPreLinkCommands();
+}
+
+std::vector<cmCustomCommand> const&
+cmGeneratorTarget::GetPostBuildCommands() const
+{
+ return this->Target->GetPostBuildCommands();
+}
+
+bool cmGeneratorTarget::IsImported() const
+{
+ return this->Target->IsImported();
+}
+
+bool cmGeneratorTarget::IsImportedGloballyVisible() const
+{
+ return this->Target->IsImportedGloballyVisible();
+}
+
+//----------------------------------------------------------------------------
+const char* cmGeneratorTarget::GetLocationForBuild() const
+{
+ static std::string location;
+ if(this->IsImported())
+ {
+ location = this->Target->ImportedGetFullPath("", false);
+ return location.c_str();
+ }
+
+ // Now handle the deprecated build-time configuration location.
+ location = this->GetDirectory();
+ const char* cfgid = this->Makefile->GetDefinition("CMAKE_CFG_INTDIR");
+ if(cfgid && strcmp(cfgid, ".") != 0)
+ {
+ location += "/";
+ location += cfgid;
+ }
+
+ if(this->IsAppBundleOnApple())
+ {
+ std::string macdir = this->BuildMacContentDirectory("", "",
+ false);
+ if(!macdir.empty())
+ {
+ location += "/";
+ location += macdir;
+ }
+ }
+ location += "/";
+ location += this->GetFullName("", false);
+ return location.c_str();
+}
+
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir,
+ const std::string& config) const
+{
+ assert(this->GetType() != cmState::INTERFACE_LIBRARY);
std::string config_upper;
- if(config && *config)
+ if(!config.empty())
{
config_upper = cmSystemTools::UpperCase(config);
}
typedef std::map<std::string, std::vector<std::string> > IncludeCacheType;
- IncludeCacheType::iterator iter =
+ IncludeCacheType::const_iterator iter =
this->SystemIncludesCache.find(config_upper);
if (iter == this->SystemIncludesCache.end())
{
+ cmGeneratorExpressionDAGChecker dagChecker(
+ this->GetName(),
+ "SYSTEM_INCLUDE_DIRECTORIES", 0, 0);
+
+ bool excludeImported
+ = this->GetPropertyAsBool("NO_SYSTEM_FROM_IMPORTED");
+
std::vector<std::string> result;
- for (std::set<cmStdString>::const_iterator
+ for (std::set<std::string>::const_iterator
it = this->Target->GetSystemIncludeDirectories().begin();
it != this->Target->GetSystemIncludeDirectories().end(); ++it)
{
- cmListFileBacktrace lfbt;
- cmGeneratorExpression ge(lfbt);
-
- cmGeneratorExpressionDAGChecker dagChecker(lfbt,
- this->GetName(),
- "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", 0, 0);
-
+ cmGeneratorExpression ge;
cmSystemTools::ExpandListArgument(ge.Parse(*it)
- ->Evaluate(this->Makefile,
- config, false, this->Target,
- &dagChecker), result);
+ ->Evaluate(this->LocalGenerator,
+ config, false, this,
+ &dagChecker), result);
}
+
+ std::vector<cmGeneratorTarget const*> const& deps =
+ this->GetLinkImplementationClosure(config);
+ for(std::vector<cmGeneratorTarget const*>::const_iterator
+ li = deps.begin(), le = deps.end(); li != le; ++li)
+ {
+ handleSystemIncludesDep(this->LocalGenerator, *li, config, this,
+ &dagChecker, result, excludeImported);
+ }
+
+ std::set<std::string> unique;
for(std::vector<std::string>::iterator li = result.begin();
li != result.end(); ++li)
{
cmSystemTools::ConvertToUnixSlashes(*li);
+ unique.insert(*li);
}
+ result.clear();
+ result.insert(result.end(), unique.begin(), unique.end());
IncludeCacheType::value_type entry(config_upper, result);
iter = this->SystemIncludesCache.insert(entry).first;
}
- if (std::find(iter->second.begin(),
- iter->second.end(), dir) != iter->second.end())
+ return std::binary_search(iter->second.begin(), iter->second.end(), dir);
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::GetPropertyAsBool(const std::string& prop) const
+{
+ return this->Target->GetPropertyAsBool(prop);
+}
+
+//----------------------------------------------------------------------------
+static void AddInterfaceEntries(
+ cmGeneratorTarget const* thisTarget, std::string const& config,
+ std::string const& prop,
+ std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries)
+{
+ if(cmLinkImplementationLibraries const* impl =
+ thisTarget->GetLinkImplementationLibraries(config))
+ {
+ for (std::vector<cmLinkImplItem>::const_iterator
+ it = impl->Libraries.begin(), end = impl->Libraries.end();
+ it != end; ++it)
+ {
+ if(it->Target)
+ {
+ std::string genex =
+ "$<TARGET_PROPERTY:" + *it + "," + prop + ">";
+ cmGeneratorExpression ge(it->Backtrace);
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex);
+ cge->SetEvaluateForBuildsystem(true);
+ entries.push_back(
+ new cmGeneratorTarget::TargetPropertyEntry(cge, *it));
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+static bool processSources(cmGeneratorTarget const* tgt,
+ const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries,
+ std::vector<std::string> &srcs,
+ UNORDERED_SET<std::string> &uniqueSrcs,
+ cmGeneratorExpressionDAGChecker *dagChecker,
+ std::string const& config, bool debugSources)
+{
+ cmMakefile *mf = tgt->Target->GetMakefile();
+
+ bool contextDependent = false;
+
+ for (std::vector<cmGeneratorTarget::TargetPropertyEntry*>::const_iterator
+ it = entries.begin(), end = entries.end(); it != end; ++it)
+ {
+ cmLinkImplItem const& item = (*it)->LinkImplItem;
+ std::string const& targetName = item;
+ std::vector<std::string> entrySources;
+ cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(
+ tgt->GetLocalGenerator(),
+ config,
+ false,
+ tgt,
+ tgt,
+ dagChecker),
+ entrySources);
+
+ if ((*it)->ge->GetHadContextSensitiveCondition())
+ {
+ contextDependent = true;
+ }
+
+ for(std::vector<std::string>::iterator i = entrySources.begin();
+ i != entrySources.end(); ++i)
+ {
+ std::string& src = *i;
+ cmSourceFile* sf = mf->GetOrCreateSource(src);
+ std::string e;
+ std::string fullPath = sf->GetFullPath(&e);
+ if(fullPath.empty())
+ {
+ if(!e.empty())
+ {
+ cmake* cm = tgt->GetLocalGenerator()->GetCMakeInstance();
+ cm->IssueMessage(cmake::FATAL_ERROR, e,
+ tgt->GetBacktrace());
+ }
+ return contextDependent;
+ }
+
+ if (!targetName.empty() && !cmSystemTools::FileIsFullPath(src.c_str()))
+ {
+ std::ostringstream err;
+ if (!targetName.empty())
+ {
+ err << "Target \"" << targetName << "\" contains relative "
+ "path in its INTERFACE_SOURCES:\n"
+ " \"" << src << "\"";
+ }
+ else
+ {
+ err << "Found relative path while evaluating sources of "
+ "\"" << tgt->GetName() << "\":\n \"" << src << "\"\n";
+ }
+ tgt->GetLocalGenerator()->IssueMessage(cmake::FATAL_ERROR, err.str());
+ return contextDependent;
+ }
+ src = fullPath;
+ }
+ std::string usedSources;
+ for(std::vector<std::string>::iterator
+ li = entrySources.begin(); li != entrySources.end(); ++li)
+ {
+ std::string src = *li;
+
+ if(uniqueSrcs.insert(src).second)
+ {
+ srcs.push_back(src);
+ if (debugSources)
+ {
+ usedSources += " * " + src + "\n";
+ }
+ }
+ }
+ if (!usedSources.empty())
+ {
+ tgt->GetLocalGenerator()->GetCMakeInstance()->IssueMessage(cmake::LOG,
+ std::string("Used sources for target ")
+ + tgt->GetName() + ":\n"
+ + usedSources, (*it)->ge->GetBacktrace());
+ }
+ }
+ return contextDependent;
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetSourceFiles(std::vector<std::string> &files,
+ const std::string& config) const
+{
+ assert(this->GetType() != cmState::INTERFACE_LIBRARY);
+
+ if (!this->LocalGenerator->GetGlobalGenerator()->GetConfigureDoneCMP0026())
+ {
+ // At configure-time, this method can be called as part of getting the
+ // LOCATION property or to export() a file to be include()d. However
+ // there is no cmGeneratorTarget at configure-time, so search the SOURCES
+ // for TARGET_OBJECTS instead for backwards compatibility with OLD
+ // behavior of CMP0024 and CMP0026 only.
+
+ cmStringRange sourceEntries = this->Target->GetSourceEntries();
+ for(cmStringRange::const_iterator
+ i = sourceEntries.begin();
+ i != sourceEntries.end(); ++i)
+ {
+ std::string const& entry = *i;
+
+ std::vector<std::string> items;
+ cmSystemTools::ExpandListArgument(entry, items);
+ for (std::vector<std::string>::const_iterator
+ li = items.begin(); li != items.end(); ++li)
+ {
+ if(cmHasLiteralPrefix(*li, "$<TARGET_OBJECTS:") &&
+ (*li)[li->size() - 1] == '>')
+ {
+ continue;
+ }
+ files.push_back(*li);
+ }
+ }
+ return;
+ }
+
+ std::vector<std::string> debugProperties;
+ const char *debugProp =
+ this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+ if (debugProp)
+ {
+ cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+ }
+
+ bool debugSources = !this->DebugSourcesDone
+ && std::find(debugProperties.begin(),
+ debugProperties.end(),
+ "SOURCES")
+ != debugProperties.end();
+
+ if (this->LocalGenerator->GetGlobalGenerator()->GetConfigureDoneCMP0026())
+ {
+ this->DebugSourcesDone = true;
+ }
+
+ cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
+ "SOURCES", 0, 0);
+
+ UNORDERED_SET<std::string> uniqueSrcs;
+ bool contextDependentDirectSources = processSources(this,
+ this->SourceEntries,
+ files,
+ uniqueSrcs,
+ &dagChecker,
+ config,
+ debugSources);
+
+ std::vector<cmGeneratorTarget::TargetPropertyEntry*>
+ linkInterfaceSourcesEntries;
+
+ AddInterfaceEntries(
+ this, config, "INTERFACE_SOURCES",
+ linkInterfaceSourcesEntries);
+
+ std::vector<std::string>::size_type numFilesBefore = files.size();
+ bool contextDependentInterfaceSources = processSources(this,
+ linkInterfaceSourcesEntries,
+ files,
+ uniqueSrcs,
+ &dagChecker,
+ config,
+ debugSources);
+
+ if (!contextDependentDirectSources
+ && !(contextDependentInterfaceSources && numFilesBefore < files.size()))
+ {
+ this->LinkImplementationLanguageIsContextDependent = false;
+ }
+
+ cmDeleteAll(linkInterfaceSourcesEntries);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetSourceFiles(std::vector<cmSourceFile*> &files,
+ const std::string& config) const
+{
+
+ // Lookup any existing link implementation for this configuration.
+ std::string key = cmSystemTools::UpperCase(config);
+
+ if(!this->LinkImplementationLanguageIsContextDependent)
+ {
+ files = this->SourceFilesMap.begin()->second;
+ return;
+ }
+
+ SourceFilesMapType::iterator
+ it = this->SourceFilesMap.find(key);
+ if(it != this->SourceFilesMap.end())
+ {
+ files = it->second;
+ }
+ else
+ {
+ std::vector<std::string> srcs;
+ this->GetSourceFiles(srcs, config);
+
+ std::set<cmSourceFile*> emitted;
+
+ for(std::vector<std::string>::const_iterator i = srcs.begin();
+ i != srcs.end(); ++i)
+ {
+ cmSourceFile* sf = this->Makefile->GetOrCreateSource(*i);
+ if (emitted.insert(sf).second)
+ {
+ files.push_back(sf);
+ }
+ }
+ this->SourceFilesMap[key] = files;
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::GetCompilePDBName(const std::string& config) const
+{
+ std::string prefix;
+ std::string base;
+ std::string suffix;
+ this->GetFullNameInternal(config, false, prefix, base, suffix);
+
+ // Check for a per-configuration output directory target property.
+ std::string configUpper = cmSystemTools::UpperCase(config);
+ std::string configProp = "COMPILE_PDB_NAME_";
+ configProp += configUpper;
+ const char* config_name = this->GetProperty(configProp);
+ if(config_name && *config_name)
+ {
+ return prefix + config_name + ".pdb";
+ }
+
+ const char* name = this->GetProperty("COMPILE_PDB_NAME");
+ if(name && *name)
+ {
+ return prefix + name + ".pdb";
+ }
+
+ return "";
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::GetCompilePDBPath(const std::string& config) const
+{
+ std::string dir = this->GetCompilePDBDirectory(config);
+ std::string name = this->GetCompilePDBName(config);
+ if(dir.empty() && !name.empty())
+ {
+ dir = this->GetPDBDirectory(config);
+ }
+ if(!dir.empty())
+ {
+ dir += "/";
+ }
+ return dir + name;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::HasSOName(const std::string& config) const
+{
+ // soname is supported only for shared libraries and modules,
+ // and then only when the platform supports an soname flag.
+ return ((this->GetType() == cmState::SHARED_LIBRARY) &&
+ !this->GetPropertyAsBool("NO_SONAME") &&
+ this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config)));
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGeneratorTarget::NeedRelinkBeforeInstall(const std::string& config) const
+{
+ // Only executables and shared libraries can have an rpath and may
+ // need relinking.
+ if(this->GetType() != cmState::EXECUTABLE &&
+ this->GetType() != cmState::SHARED_LIBRARY &&
+ this->GetType() != cmState::MODULE_LIBRARY)
+ {
+ return false;
+ }
+
+ // If there is no install location this target will not be installed
+ // and therefore does not need relinking.
+ if(!this->Target->GetHaveInstallRule())
+ {
+ return false;
+ }
+
+ // If skipping all rpaths completely then no relinking is needed.
+ if(this->Makefile->IsOn("CMAKE_SKIP_RPATH"))
+ {
+ return false;
+ }
+
+ // If building with the install-tree rpath no relinking is needed.
+ if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
+ {
+ return false;
+ }
+
+ // If chrpath is going to be used no relinking is needed.
+ if(this->IsChrpathUsed(config))
+ {
+ return false;
+ }
+
+ // Check for rpath support on this platform.
+ std::string ll = this->GetLinkerLanguage(config);
+ if(!ll.empty())
+ {
+ std::string flagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
+ flagVar += ll;
+ flagVar += "_FLAG";
+ if(!this->Makefile->IsSet(flagVar))
+ {
+ // There is no rpath support on this platform so nothing needs
+ // relinking.
+ return false;
+ }
+ }
+ else
+ {
+ // No linker language is known. This error will be reported by
+ // other code.
+ return false;
+ }
+
+ // If either a build or install tree rpath is set then the rpath
+ // will likely change between the build tree and install tree and
+ // this target must be relinked.
+ return this->HaveBuildTreeRPATH(config)
+ || this->HaveInstallTreeRPATH();
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsChrpathUsed(const std::string& config) const
+{
+ // Only certain target types have an rpath.
+ if(!(this->GetType() == cmState::SHARED_LIBRARY ||
+ this->GetType() == cmState::MODULE_LIBRARY ||
+ this->GetType() == cmState::EXECUTABLE))
+ {
+ return false;
+ }
+
+ // If the target will not be installed we do not need to change its
+ // rpath.
+ if(!this->Target->GetHaveInstallRule())
+ {
+ return false;
+ }
+
+ // Skip chrpath if skipping rpath altogether.
+ if(this->Makefile->IsOn("CMAKE_SKIP_RPATH"))
+ {
+ return false;
+ }
+
+ // Skip chrpath if it does not need to be changed at install time.
+ if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
+ {
+ return false;
+ }
+
+ // Allow the user to disable builtin chrpath explicitly.
+ if(this->Makefile->IsOn("CMAKE_NO_BUILTIN_CHRPATH"))
+ {
+ return false;
+ }
+
+ if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
{
return true;
}
+
+#if defined(CMAKE_USE_ELF_PARSER)
+ // Enable if the rpath flag uses a separator and the target uses ELF
+ // binaries.
+ std::string ll = this->GetLinkerLanguage(config);
+ if(!ll.empty())
+ {
+ std::string sepVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
+ sepVar += ll;
+ sepVar += "_FLAG_SEP";
+ const char* sep = this->Makefile->GetDefinition(sepVar);
+ if(sep && *sep)
+ {
+ // TODO: Add ELF check to ABI detection and get rid of
+ // CMAKE_EXECUTABLE_FORMAT.
+ if(const char* fmt =
+ this->Makefile->GetDefinition("CMAKE_EXECUTABLE_FORMAT"))
+ {
+ return strcmp(fmt, "ELF") == 0;
+ }
+ }
+ }
+#endif
+ static_cast<void>(config);
return false;
}
//----------------------------------------------------------------------------
-bool cmGeneratorTarget::GetPropertyAsBool(const char *prop)
+bool cmGeneratorTarget::IsImportedSharedLibWithoutSOName(
+ const std::string& config) const
{
- return this->Target->GetPropertyAsBool(prop);
+ if(this->IsImported() && this->GetType() == cmState::SHARED_LIBRARY)
+ {
+ if(cmGeneratorTarget::ImportInfo const* info =
+ this->GetImportInfo(config))
+ {
+ return info->NoSOName;
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::HasMacOSXRpathInstallNameDir(
+ const std::string& config) const
+{
+ bool install_name_is_rpath = false;
+ bool macosx_rpath = false;
+
+ if(!this->IsImported())
+ {
+ if(this->GetType() != cmState::SHARED_LIBRARY)
+ {
+ return false;
+ }
+ const char* install_name = this->GetProperty("INSTALL_NAME_DIR");
+ bool use_install_name =
+ this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH");
+ if(install_name && use_install_name &&
+ std::string(install_name) == "@rpath")
+ {
+ install_name_is_rpath = true;
+ }
+ else if(install_name && use_install_name)
+ {
+ return false;
+ }
+ if(!install_name_is_rpath)
+ {
+ macosx_rpath = this->MacOSXRpathInstallNameDirDefault();
+ }
+ }
+ else
+ {
+ // Lookup the imported soname.
+ if(cmGeneratorTarget::ImportInfo const* info =
+ this->GetImportInfo(config))
+ {
+ if(!info->NoSOName && !info->SOName.empty())
+ {
+ if(info->SOName.find("@rpath/") == 0)
+ {
+ install_name_is_rpath = true;
+ }
+ }
+ else
+ {
+ std::string install_name;
+ cmSystemTools::GuessLibraryInstallName(info->Location, install_name);
+ if(install_name.find("@rpath") != std::string::npos)
+ {
+ install_name_is_rpath = true;
+ }
+ }
+ }
+ }
+
+ if(!install_name_is_rpath && !macosx_rpath)
+ {
+ return false;
+ }
+
+ if(!this->Makefile->IsSet("CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG"))
+ {
+ std::ostringstream w;
+ w << "Attempting to use";
+ if(macosx_rpath)
+ {
+ w << " MACOSX_RPATH";
+ }
+ else
+ {
+ w << " @rpath";
+ }
+ w << " without CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG being set.";
+ w << " This could be because you are using a Mac OS X version";
+ w << " less than 10.5 or because CMake's platform configuration is";
+ w << " corrupt.";
+ cmake* cm = this->LocalGenerator->GetCMakeInstance();
+ cm->IssueMessage(cmake::FATAL_ERROR, w.str(),
+ this->GetBacktrace());
+ }
+
+ return true;
}
//----------------------------------------------------------------------------
-std::vector<cmSourceFile*> const& cmGeneratorTarget::GetSourceFiles()
+bool cmGeneratorTarget::MacOSXRpathInstallNameDirDefault() const
{
- return this->Target->GetSourceFiles();
+ // we can't do rpaths when unsupported
+ if(!this->Makefile->IsSet("CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG"))
+ {
+ return false;
+ }
+
+ const char* macosx_rpath_str = this->GetProperty("MACOSX_RPATH");
+ if(macosx_rpath_str)
+ {
+ return this->GetPropertyAsBool("MACOSX_RPATH");
+ }
+
+ cmPolicies::PolicyStatus cmp0042 = this->GetPolicyStatusCMP0042();
+
+ if(cmp0042 == cmPolicies::WARN)
+ {
+ this->LocalGenerator->GetGlobalGenerator()->
+ AddCMP0042WarnTarget(this->GetName());
+ }
+
+ if(cmp0042 == cmPolicies::NEW)
+ {
+ return true;
+ }
+
+ return false;
}
//----------------------------------------------------------------------------
-void cmGeneratorTarget::ClassifySources()
+std::string cmGeneratorTarget::GetSOName(const std::string& config) const
{
- cmsys::RegularExpression header(CM_HEADER_REGEX);
- bool isObjLib = this->Target->GetType() == cmTarget::OBJECT_LIBRARY;
- std::vector<cmSourceFile*> badObjLib;
- std::vector<cmSourceFile*> const& sources = this->Target->GetSourceFiles();
- for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
- si != sources.end(); ++si)
+ if(this->IsImported())
{
- cmSourceFile* sf = *si;
- std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
- if(sf->GetCustomCommand())
+ // Lookup the imported soname.
+ if(cmGeneratorTarget::ImportInfo const* info =
+ this->GetImportInfo(config))
{
- this->CustomCommands.push_back(sf);
+ if(info->NoSOName)
+ {
+ // The imported library has no builtin soname so the name
+ // searched at runtime will be just the filename.
+ return cmSystemTools::GetFilenameName(info->Location);
+ }
+ else
+ {
+ // Use the soname given if any.
+ if(info->SOName.find("@rpath/") == 0)
+ {
+ return info->SOName.substr(6);
+ }
+ return info->SOName;
+ }
}
- else if(sf->GetPropertyAsBool("HEADER_FILE_ONLY"))
+ else
{
- this->HeaderSources.push_back(sf);
+ return "";
}
- else if(sf->GetPropertyAsBool("EXTERNAL_OBJECT"))
+ }
+ else
+ {
+ // Compute the soname that will be built.
+ std::string name;
+ std::string soName;
+ std::string realName;
+ std::string impName;
+ std::string pdbName;
+ this->GetLibraryNames(name, soName, realName,
+ impName, pdbName, config);
+ return soName;
+ }
+}
+
+
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::GetAppBundleDirectory(const std::string& config,
+ bool contentOnly) const
+{
+ std::string fpath = this->GetFullName(config, false);
+ fpath += ".app";
+ if(!this->Makefile->PlatformIsAppleIos())
+ {
+ fpath += "/Contents";
+ if(!contentOnly)
+ fpath += "/MacOS";
+ }
+ return fpath;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsBundleOnApple() const
+{
+ return this->IsFrameworkOnApple()
+ || this->IsAppBundleOnApple()
+ || this->IsCFBundleOnApple();
+}
+
+//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetCFBundleDirectory(const std::string& config,
+ bool contentOnly) const
+{
+ std::string fpath;
+ fpath += this->GetOutputName(config, false);
+ fpath += ".";
+ const char *ext = this->GetProperty("BUNDLE_EXTENSION");
+ if (!ext)
+ {
+ if (this->IsXCTestOnApple())
{
- this->ExternalObjects.push_back(sf);
- if(isObjLib) { badObjLib.push_back(sf); }
+ ext = "xctest";
}
- else if(sf->GetLanguage())
+ else
{
- this->ObjectSources.push_back(sf);
+ ext = "bundle";
}
- else if(ext == "def")
+ }
+ fpath += ext;
+ if(!this->Makefile->PlatformIsAppleIos())
+ {
+ fpath += "/Contents";
+ if(!contentOnly)
+ fpath += "/MacOS";
+ }
+ return fpath;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::GetFrameworkDirectory(const std::string& config,
+ bool rootDir) const
+{
+ std::string fpath;
+ fpath += this->GetOutputName(config, false);
+ fpath += ".framework";
+ if(!rootDir && !this->Makefile->PlatformIsAppleIos())
+ {
+ fpath += "/Versions/";
+ fpath += this->GetFrameworkVersion();
+ }
+ return fpath;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::GetFullName(const std::string& config, bool implib) const
+{
+ if(this->IsImported())
+ {
+ return this->GetFullNameImported(config, implib);
+ }
+ else
+ {
+ return this->GetFullNameInternal(config, implib);
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::GetInstallNameDirForBuildTree(
+ const std::string& config) const
+{
+ // If building directly for installation then the build tree install_name
+ // is the same as the install tree.
+ if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
+ {
+ return this->GetInstallNameDirForInstallTree();
+ }
+
+ // Use the build tree directory for the target.
+ if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME") &&
+ !this->Makefile->IsOn("CMAKE_SKIP_RPATH") &&
+ !this->GetPropertyAsBool("SKIP_BUILD_RPATH"))
+ {
+ std::string dir;
+ if(this->MacOSXRpathInstallNameDirDefault())
{
- this->ModuleDefinitionFile = sf->GetFullPath();
- if(isObjLib) { badObjLib.push_back(sf); }
+ dir = "@rpath";
}
- else if(ext == "idl")
+ else
{
- this->IDLSources.push_back(sf);
- if(isObjLib) { badObjLib.push_back(sf); }
+ dir = this->GetDirectory(config);
}
- else if(ext == "resx")
+ dir += "/";
+ return dir;
+ }
+ else
+ {
+ return "";
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetInstallNameDirForInstallTree() const
+{
+ if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
+ {
+ std::string dir;
+ const char* install_name_dir = this->GetProperty("INSTALL_NAME_DIR");
+
+ if(!this->Makefile->IsOn("CMAKE_SKIP_RPATH") &&
+ !this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH"))
{
- // Build and save the name of the corresponding .h file
- // This relationship will be used later when building the project files.
- // Both names would have been auto generated from Visual Studio
- // where the user supplied the file name and Visual Studio
- // appended the suffix.
- std::string resx = sf->GetFullPath();
- std::string hFileName = resx.substr(0, resx.find_last_of(".")) + ".h";
- this->ExpectedResxHeaders.insert(hFileName);
- this->ResxSources.push_back(sf);
+ if(install_name_dir && *install_name_dir)
+ {
+ dir = install_name_dir;
+ dir += "/";
+ }
}
- else if(header.find(sf->GetFullPath().c_str()))
+ if(!install_name_dir)
{
- this->HeaderSources.push_back(sf);
+ if(this->MacOSXRpathInstallNameDirDefault())
+ {
+ dir = "@rpath/";
+ }
}
- else if(this->GlobalGenerator->IgnoreFile(sf->GetExtension().c_str()))
+ return dir;
+ }
+ else
+ {
+ return "";
+ }
+}
+
+cmListFileBacktrace cmGeneratorTarget::GetBacktrace() const
+{
+ return this->Target->GetBacktrace();
+}
+
+const std::vector<std::string>&cmGeneratorTarget::GetLinkDirectories() const
+{
+ return this->Target->GetLinkDirectories();
+}
+
+const std::set<std::string>& cmGeneratorTarget::GetUtilities() const
+{
+ return this->Target->GetUtilities();
+}
+
+const cmListFileBacktrace*
+cmGeneratorTarget::GetUtilityBacktrace(const std::string& u) const
+{
+ return this->Target->GetUtilityBacktrace(u);
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::HaveWellDefinedOutputFiles() const
+{
+ return
+ this->GetType() == cmState::STATIC_LIBRARY ||
+ this->GetType() == cmState::SHARED_LIBRARY ||
+ this->GetType() == cmState::MODULE_LIBRARY ||
+ this->GetType() == cmState::EXECUTABLE;
+}
+
+//----------------------------------------------------------------------------
+const char* cmGeneratorTarget::GetExportMacro() const
+{
+ // Define the symbol for targets that export symbols.
+ if(this->GetType() == cmState::SHARED_LIBRARY ||
+ this->GetType() == cmState::MODULE_LIBRARY ||
+ this->IsExecutableWithExports())
+ {
+ if(const char* custom_export_name = this->GetProperty("DEFINE_SYMBOL"))
{
- // We only get here if a source file is not an external object
- // and has an extension that is listed as an ignored file type.
- // No message or diagnosis should be given.
- this->ExtraSources.push_back(sf);
+ this->ExportMacro = custom_export_name;
}
else
{
- this->ExtraSources.push_back(sf);
- if(isObjLib && ext != "txt")
+ std::string in = this->GetName();
+ in += "_EXPORTS";
+ this->ExportMacro = cmSystemTools::MakeCidentifier(in);
+ }
+ return this->ExportMacro.c_str();
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+//----------------------------------------------------------------------------
+class cmTargetCollectLinkLanguages
+{
+public:
+ cmTargetCollectLinkLanguages(cmGeneratorTarget const* target,
+ const std::string& config,
+ UNORDERED_SET<std::string>& languages,
+ cmGeneratorTarget const* head):
+ Config(config), Languages(languages), HeadTarget(head),
+ Target(target)
+ { this->Visited.insert(target); }
+
+ void Visit(cmLinkItem const& item)
+ {
+ if(!item.Target)
+ {
+ if(item.find("::") != std::string::npos)
{
- badObjLib.push_back(sf);
+ bool noMessage = false;
+ cmake::MessageType messageType = cmake::FATAL_ERROR;
+ std::stringstream e;
+ switch(this->Target->GetLocalGenerator()
+ ->GetPolicyStatus(cmPolicies::CMP0028))
+ {
+ case cmPolicies::WARN:
+ {
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0028) << "\n";
+ messageType = cmake::AUTHOR_WARNING;
+ }
+ break;
+ case cmPolicies::OLD:
+ noMessage = true;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ // Issue the fatal message.
+ break;
+ }
+
+ if(!noMessage)
+ {
+ e << "Target \"" << this->Target->GetName()
+ << "\" links to target \"" << item
+ << "\" but the target was not found. Perhaps a find_package() "
+ "call is missing for an IMPORTED target, or an ALIAS target is "
+ "missing?";
+ this->Target->GetLocalGenerator()->GetCMakeInstance()->IssueMessage(
+ messageType, e.str(), this->Target->GetBacktrace());
+ }
}
+ return;
+ }
+ if(!this->Visited.insert(item.Target).second)
+ {
+ return;
+ }
+ cmLinkInterface const* iface =
+ item.Target->GetLinkInterface(this->Config, this->HeadTarget);
+ if(!iface) { return; }
+
+ for(std::vector<std::string>::const_iterator
+ li = iface->Languages.begin(); li != iface->Languages.end(); ++li)
+ {
+ this->Languages.insert(*li);
+ }
+
+ for(std::vector<cmLinkItem>::const_iterator
+ li = iface->Libraries.begin(); li != iface->Libraries.end(); ++li)
+ {
+ this->Visit(*li);
}
}
+private:
+ std::string Config;
+ UNORDERED_SET<std::string>& Languages;
+ cmGeneratorTarget const* HeadTarget;
+ const cmGeneratorTarget* Target;
+ std::set<cmGeneratorTarget const*> Visited;
+};
- if(!badObjLib.empty())
+//----------------------------------------------------------------------------
+cmGeneratorTarget::LinkClosure const*
+cmGeneratorTarget::GetLinkClosure(const std::string& config) const
+{
+ std::string key(cmSystemTools::UpperCase(config));
+ LinkClosureMapType::iterator
+ i = this->LinkClosureMap.find(key);
+ if(i == this->LinkClosureMap.end())
{
- cmOStringStream e;
- e << "OBJECT library \"" << this->Target->GetName() << "\" contains:\n";
- for(std::vector<cmSourceFile*>::iterator i = badObjLib.begin();
- i != badObjLib.end(); ++i)
+ LinkClosure lc;
+ this->ComputeLinkClosure(config, lc);
+ LinkClosureMapType::value_type entry(key, lc);
+ i = this->LinkClosureMap.insert(entry).first;
+ }
+ return &i->second;
+}
+
+//----------------------------------------------------------------------------
+class cmTargetSelectLinker
+{
+ int Preference;
+ cmGeneratorTarget const* Target;
+ cmGlobalGenerator* GG;
+ std::set<std::string> Preferred;
+public:
+ cmTargetSelectLinker(cmGeneratorTarget const* target)
+ : Preference(0), Target(target)
+ {
+ this->GG = this->Target->GetLocalGenerator()->GetGlobalGenerator();
+ }
+ void Consider(const char* lang)
+ {
+ int preference = this->GG->GetLinkerPreference(lang);
+ if(preference > this->Preference)
{
- e << " " << (*i)->GetLocation().GetName() << "\n";
+ this->Preference = preference;
+ this->Preferred.clear();
+ }
+ if(preference == this->Preference)
+ {
+ this->Preferred.insert(lang);
}
- e << "but may contain only headers and sources that compile.";
- this->GlobalGenerator->GetCMakeInstance()
- ->IssueMessage(cmake::FATAL_ERROR, e.str(),
- this->Target->GetBacktrace());
+ }
+ std::string Choose()
+ {
+ if(this->Preferred.empty())
+ {
+ return "";
+ }
+ else if(this->Preferred.size() > 1)
+ {
+ std::stringstream e;
+ e << "Target " << this->Target->GetName()
+ << " contains multiple languages with the highest linker preference"
+ << " (" << this->Preference << "):\n";
+ for(std::set<std::string>::const_iterator
+ li = this->Preferred.begin(); li != this->Preferred.end(); ++li)
+ {
+ e << " " << *li << "\n";
+ }
+ e << "Set the LINKER_LANGUAGE property for this target.";
+ cmake* cm = this->Target->GetLocalGenerator()->GetCMakeInstance();
+ cm->IssueMessage(cmake::FATAL_ERROR, e.str(),
+ this->Target->GetBacktrace());
+ }
+ return *this->Preferred.begin();
+ }
+};
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::ComputeLinkClosure(const std::string& config,
+ LinkClosure& lc) const
+{
+ // Get languages built in this target.
+ UNORDERED_SET<std::string> languages;
+ cmLinkImplementation const* impl =
+ this->GetLinkImplementation(config);
+ assert(impl);
+ for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
+ li != impl->Languages.end(); ++li)
+ {
+ languages.insert(*li);
+ }
+
+ // Add interface languages from linked targets.
+ cmTargetCollectLinkLanguages cll(this, config, languages, this);
+ for(std::vector<cmLinkImplItem>::const_iterator li = impl->Libraries.begin();
+ li != impl->Libraries.end(); ++li)
+ {
+ cll.Visit(*li);
+ }
+
+ // Store the transitive closure of languages.
+ for(UNORDERED_SET<std::string>::const_iterator li = languages.begin();
+ li != languages.end(); ++li)
+ {
+ lc.Languages.push_back(*li);
+ }
+
+ // Choose the language whose linker should be used.
+ if(this->GetProperty("HAS_CXX"))
+ {
+ lc.LinkerLanguage = "CXX";
+ }
+ else if(const char* linkerLang = this->GetProperty("LINKER_LANGUAGE"))
+ {
+ lc.LinkerLanguage = linkerLang;
+ }
+ else
+ {
+ // Find the language with the highest preference value.
+ cmTargetSelectLinker tsl(this);
+
+ // First select from the languages compiled directly in this target.
+ for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
+ li != impl->Languages.end(); ++li)
+ {
+ tsl.Consider(li->c_str());
+ }
+
+ // Now consider languages that propagate from linked targets.
+ for(UNORDERED_SET<std::string>::const_iterator sit = languages.begin();
+ sit != languages.end(); ++sit)
+ {
+ std::string propagates = "CMAKE_"+*sit+"_LINKER_PREFERENCE_PROPAGATES";
+ if(this->Makefile->IsOn(propagates))
+ {
+ tsl.Consider(sit->c_str());
+ }
+ }
+
+ lc.LinkerLanguage = tsl.Choose();
}
}
//----------------------------------------------------------------------------
-void cmGeneratorTarget::LookupObjectLibraries()
+void cmGeneratorTarget::GetFullNameComponents(std::string& prefix,
+ std::string& base,
+ std::string& suffix,
+ const std::string& config,
+ bool implib) const
{
- std::vector<std::string> const& objLibs =
- this->Target->GetObjectLibraries();
- for(std::vector<std::string>::const_iterator oli = objLibs.begin();
- oli != objLibs.end(); ++oli)
+ this->GetFullNameInternal(config, implib, prefix, base, suffix);
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::BuildMacContentDirectory(const std::string& base,
+ const std::string& config,
+ bool contentOnly) const
+{
+ std::string fpath = base;
+ if(this->IsAppBundleOnApple())
+ {
+ fpath += this->GetAppBundleDirectory(config, contentOnly);
+ }
+ if(this->IsFrameworkOnApple())
+ {
+ fpath += this->GetFrameworkDirectory(config, contentOnly);
+ }
+ if(this->IsCFBundleOnApple())
+ {
+ fpath += this->GetCFBundleDirectory(config, contentOnly);
+ }
+ return fpath;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::GetMacContentDirectory(const std::string& config,
+ bool implib) const
+{
+ // Start with the output directory for the target.
+ std::string fpath = this->GetDirectory(config, implib);
+ fpath += "/";
+ bool contentOnly = true;
+ if(this->IsFrameworkOnApple())
+ {
+ // additional files with a framework go into the version specific
+ // directory
+ contentOnly = false;
+ }
+ fpath = this->BuildMacContentDirectory(fpath, config, contentOnly);
+ return fpath;
+}
+
+
+//----------------------------------------------------------------------------
+cmGeneratorTarget::CompileInfo const* cmGeneratorTarget::GetCompileInfo(
+ const std::string& config) const
+{
+ // There is no compile information for imported targets.
+ if(this->IsImported())
+ {
+ return 0;
+ }
+
+ if(this->GetType() > cmState::OBJECT_LIBRARY)
+ {
+ std::string msg = "cmTarget::GetCompileInfo called for ";
+ msg += this->GetName();
+ msg += " which has type ";
+ msg += cmState::GetTargetTypeName(this->GetType());
+ this->LocalGenerator->IssueMessage(cmake::INTERNAL_ERROR, msg);
+ return 0;
+ }
+
+ // Lookup/compute/cache the compile information for this configuration.
+ std::string config_upper;
+ if(!config.empty())
+ {
+ config_upper = cmSystemTools::UpperCase(config);
+ }
+ CompileInfoMapType::const_iterator i =
+ this->CompileInfoMap.find(config_upper);
+ if(i == this->CompileInfoMap.end())
+ {
+ CompileInfo info;
+ this->ComputePDBOutputDir("COMPILE_PDB", config, info.CompilePdbDir);
+ CompileInfoMapType::value_type entry(config_upper, info);
+ i = this->CompileInfoMap.insert(entry).first;
+ }
+ return &i->second;
+}
+
+//----------------------------------------------------------------------------
+cmSourceFile const*
+cmGeneratorTarget::GetModuleDefinitionFile(const std::string& config) const
+{
+ std::vector<cmSourceFile const*> data;
+ IMPLEMENT_VISIT_IMPL(ModuleDefinitionFile,
+ COMMA std::vector<cmSourceFile const*>)
+ if(!data.empty())
+ {
+ return data.front();
+ }
+
+ return 0;
+}
+
+bool cmGeneratorTarget::IsDLLPlatform() const
+{
+ return this->DLLPlatform;
+}
+
+//----------------------------------------------------------------------------
+void
+cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs,
+ const std::string &config) const
+{
+ std::vector<cmSourceFile const*> objectFiles;
+ this->GetExternalObjects(objectFiles, config);
+ std::vector<cmGeneratorTarget*> objectLibraries;
+ for(std::vector<cmSourceFile const*>::const_iterator
+ it = objectFiles.begin(); it != objectFiles.end(); ++it)
+ {
+ std::string objLib = (*it)->GetObjectLibrary();
+ if (cmGeneratorTarget* tgt =
+ this->LocalGenerator->FindGeneratorTargetToUse(objLib))
+ {
+ objectLibraries.push_back(tgt);
+ }
+ }
+
+ std::vector<cmGeneratorTarget*>::const_iterator end
+ = cmRemoveDuplicates(objectLibraries);
+
+ for(std::vector<cmGeneratorTarget*>::const_iterator
+ ti = objectLibraries.begin();
+ ti != end; ++ti)
{
- std::string const& objLibName = *oli;
- if(cmTarget* objLib = this->Makefile->FindTargetToUse(objLibName.c_str()))
+ cmGeneratorTarget* ogt = *ti;
+ std::vector<cmSourceFile const*> objectSources;
+ ogt->GetObjectSources(objectSources, config);
+ for(std::vector<cmSourceFile const*>::const_iterator
+ si = objectSources.begin();
+ si != objectSources.end(); ++si)
{
- if(objLib->GetType() == cmTarget::OBJECT_LIBRARY)
+ std::string obj = ogt->ObjectDirectory;
+ obj += ogt->Objects[*si];
+ objs.push_back(obj);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetAutoUicOptions(std::vector<std::string> &result,
+ const std::string& config) const
+{
+ const char *prop
+ = this->GetLinkInterfaceDependentStringProperty("AUTOUIC_OPTIONS",
+ config);
+ if (!prop)
+ {
+ return;
+ }
+ cmGeneratorExpression ge;
+
+ cmGeneratorExpressionDAGChecker dagChecker(
+ this->GetName(),
+ "AUTOUIC_OPTIONS", 0, 0);
+ cmSystemTools::ExpandListArgument(ge.Parse(prop)
+ ->Evaluate(this->LocalGenerator,
+ config,
+ false,
+ this,
+ &dagChecker),
+ result);
+}
+
+//----------------------------------------------------------------------------
+void processILibs(const std::string& config,
+ cmGeneratorTarget const* headTarget,
+ cmLinkItem const& item,
+ cmGlobalGenerator* gg,
+ std::vector<cmGeneratorTarget const*>& tgts,
+ std::set<cmGeneratorTarget const*>& emitted)
+{
+ if (item.Target && emitted.insert(item.Target).second)
+ {
+ tgts.push_back(item.Target);
+ if(cmLinkInterfaceLibraries const* iface =
+ item.Target->GetLinkInterfaceLibraries(config, headTarget, true))
+ {
+ for(std::vector<cmLinkItem>::const_iterator
+ it = iface->Libraries.begin();
+ it != iface->Libraries.end(); ++it)
{
- if(this->Target->GetType() != cmTarget::EXECUTABLE &&
- this->Target->GetType() != cmTarget::STATIC_LIBRARY &&
- this->Target->GetType() != cmTarget::SHARED_LIBRARY &&
- this->Target->GetType() != cmTarget::MODULE_LIBRARY)
+ processILibs(config, headTarget, *it, gg, tgts, emitted);
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+const std::vector<const cmGeneratorTarget*>&
+cmGeneratorTarget::GetLinkImplementationClosure(
+ const std::string& config) const
+{
+ LinkImplClosure& tgts =
+ this->LinkImplClosureMap[config];
+ if(!tgts.Done)
+ {
+ tgts.Done = true;
+ std::set<cmGeneratorTarget const*> emitted;
+
+ cmLinkImplementationLibraries const* impl
+ = this->GetLinkImplementationLibraries(config);
+
+ for(std::vector<cmLinkImplItem>::const_iterator
+ it = impl->Libraries.begin();
+ it != impl->Libraries.end(); ++it)
+ {
+ processILibs(config, this, *it,
+ this->LocalGenerator->GetGlobalGenerator(),
+ tgts , emitted);
+ }
+ }
+ return tgts;
+}
+
+//----------------------------------------------------------------------------
+class cmTargetTraceDependencies
+{
+public:
+ cmTargetTraceDependencies(cmGeneratorTarget* target);
+ void Trace();
+private:
+ cmGeneratorTarget* GeneratorTarget;
+ cmMakefile* Makefile;
+ cmLocalGenerator* LocalGenerator;
+ cmGlobalGenerator const* GlobalGenerator;
+ typedef cmGeneratorTarget::SourceEntry SourceEntry;
+ SourceEntry* CurrentEntry;
+ std::queue<cmSourceFile*> SourceQueue;
+ std::set<cmSourceFile*> SourcesQueued;
+ typedef std::map<std::string, cmSourceFile*> NameMapType;
+ NameMapType NameMap;
+ std::vector<std::string> NewSources;
+
+ void QueueSource(cmSourceFile* sf);
+ void FollowName(std::string const& name);
+ void FollowNames(std::vector<std::string> const& names);
+ bool IsUtility(std::string const& dep);
+ void CheckCustomCommand(cmCustomCommand const& cc);
+ void CheckCustomCommands(const std::vector<cmCustomCommand>& commands);
+ void FollowCommandDepends(cmCustomCommand const& cc,
+ const std::string& config,
+ std::set<std::string>& emitted);
+};
+
+//----------------------------------------------------------------------------
+cmTargetTraceDependencies
+::cmTargetTraceDependencies(cmGeneratorTarget* target):
+ GeneratorTarget(target)
+{
+ // Convenience.
+ this->Makefile = target->Target->GetMakefile();
+ this->LocalGenerator = target->GetLocalGenerator();
+ this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
+ this->CurrentEntry = 0;
+
+ // Queue all the source files already specified for the target.
+ if (target->GetType() != cmState::INTERFACE_LIBRARY)
+ {
+ std::vector<std::string> configs;
+ this->Makefile->GetConfigurations(configs);
+ if (configs.empty())
+ {
+ configs.push_back("");
+ }
+ std::set<cmSourceFile*> emitted;
+ for(std::vector<std::string>::const_iterator ci = configs.begin();
+ ci != configs.end(); ++ci)
+ {
+ std::vector<cmSourceFile*> sources;
+ this->GeneratorTarget->GetSourceFiles(sources, *ci);
+ for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
+ si != sources.end(); ++si)
+ {
+ cmSourceFile* sf = *si;
+ const std::set<cmGeneratorTarget const*> tgts =
+ this->GlobalGenerator->GetFilenameTargetDepends(sf);
+ if (tgts.find(this->GeneratorTarget) != tgts.end())
{
- this->GlobalGenerator->GetCMakeInstance()
- ->IssueMessage(cmake::FATAL_ERROR,
- "Only executables and non-OBJECT libraries may "
- "reference target objects.",
- this->Target->GetBacktrace());
+ std::ostringstream e;
+ e << "Evaluation output file\n \"" << sf->GetFullPath()
+ << "\"\ndepends on the sources of a target it is used in. This "
+ "is a dependency loop and is not allowed.";
+ this->GeneratorTarget
+ ->LocalGenerator->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
- this->Target->AddUtility(objLib->GetName());
- this->ObjectLibraries.push_back(objLib);
+ if(emitted.insert(sf).second && this->SourcesQueued.insert(sf).second)
+ {
+ this->SourceQueue.push(sf);
+ }
}
- else
+ }
+ }
+
+ // Queue pre-build, pre-link, and post-build rule dependencies.
+ this->CheckCustomCommands(
+ this->GeneratorTarget->GetPreBuildCommands());
+ this->CheckCustomCommands(
+ this->GeneratorTarget->GetPreLinkCommands());
+ this->CheckCustomCommands(
+ this->GeneratorTarget->GetPostBuildCommands());
+}
+
+//----------------------------------------------------------------------------
+void cmTargetTraceDependencies::Trace()
+{
+ // Process one dependency at a time until the queue is empty.
+ while(!this->SourceQueue.empty())
+ {
+ // Get the next source from the queue.
+ cmSourceFile* sf = this->SourceQueue.front();
+ this->SourceQueue.pop();
+ this->CurrentEntry = &this->GeneratorTarget->SourceDepends[sf];
+
+ // Queue dependencies added explicitly by the user.
+ if(const char* additionalDeps = sf->GetProperty("OBJECT_DEPENDS"))
+ {
+ std::vector<std::string> objDeps;
+ cmSystemTools::ExpandListArgument(additionalDeps, objDeps);
+ for(std::vector<std::string>::iterator odi = objDeps.begin();
+ odi != objDeps.end(); ++odi)
{
- cmOStringStream e;
- e << "Objects of target \"" << objLibName
- << "\" referenced but is not an OBJECT library.";
- this->GlobalGenerator->GetCMakeInstance()
- ->IssueMessage(cmake::FATAL_ERROR, e.str(),
- this->Target->GetBacktrace());
- return;
+ if (cmSystemTools::FileIsFullPath(*odi))
+ {
+ *odi = cmSystemTools::CollapseFullPath(*odi);
+ }
+ }
+ this->FollowNames(objDeps);
+ }
+
+ // Queue the source needed to generate this file, if any.
+ this->FollowName(sf->GetFullPath());
+
+ // Queue dependencies added programatically by commands.
+ this->FollowNames(sf->GetDepends());
+
+ // Queue custom command dependencies.
+ if(cmCustomCommand const* cc = sf->GetCustomCommand())
+ {
+ this->CheckCustomCommand(*cc);
+ }
+ }
+ this->CurrentEntry = 0;
+
+ this->GeneratorTarget->AddTracedSources(this->NewSources);
+}
+
+//----------------------------------------------------------------------------
+void cmTargetTraceDependencies::QueueSource(cmSourceFile* sf)
+{
+ if(this->SourcesQueued.insert(sf).second)
+ {
+ this->SourceQueue.push(sf);
+
+ // Make sure this file is in the target at the end.
+ this->NewSources.push_back(sf->GetFullPath());
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmTargetTraceDependencies::FollowName(std::string const& name)
+{
+ NameMapType::iterator i = this->NameMap.find(name);
+ if(i == this->NameMap.end())
+ {
+ // Check if we know how to generate this file.
+ cmSourceFile* sf = this->Makefile->GetSourceFileWithOutput(name);
+ NameMapType::value_type entry(name, sf);
+ i = this->NameMap.insert(entry).first;
+ }
+ if(cmSourceFile* sf = i->second)
+ {
+ // Record the dependency we just followed.
+ if(this->CurrentEntry)
+ {
+ this->CurrentEntry->Depends.push_back(sf);
+ }
+ this->QueueSource(sf);
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmTargetTraceDependencies::FollowNames(std::vector<std::string> const& names)
+{
+ for(std::vector<std::string>::const_iterator i = names.begin();
+ i != names.end(); ++i)
+ {
+ this->FollowName(*i);
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmTargetTraceDependencies::IsUtility(std::string const& dep)
+{
+ // Dependencies on targets (utilities) are supposed to be named by
+ // just the target name. However for compatibility we support
+ // naming the output file generated by the target (assuming there is
+ // no output-name property which old code would not have set). In
+ // that case the target name will be the file basename of the
+ // dependency.
+ std::string util = cmSystemTools::GetFilenameName(dep);
+ if(cmSystemTools::GetFilenameLastExtension(util) == ".exe")
+ {
+ util = cmSystemTools::GetFilenameWithoutLastExtension(util);
+ }
+
+ // Check for a target with this name.
+ if(cmGeneratorTarget* t
+ = this->GeneratorTarget->
+ GetLocalGenerator()->FindGeneratorTargetToUse(util))
+ {
+ // If we find the target and the dep was given as a full path,
+ // then make sure it was not a full path to something else, and
+ // the fact that the name matched a target was just a coincidence.
+ if(cmSystemTools::FileIsFullPath(dep.c_str()))
+ {
+ if(t->GetType() >= cmState::EXECUTABLE &&
+ t->GetType() <= cmState::MODULE_LIBRARY)
+ {
+ // This is really only for compatibility so we do not need to
+ // worry about configuration names and output names.
+ std::string tLocation = t->GetLocationForBuild();
+ tLocation = cmSystemTools::GetFilenamePath(tLocation);
+ std::string depLocation = cmSystemTools::GetFilenamePath(dep);
+ depLocation = cmSystemTools::CollapseFullPath(depLocation);
+ tLocation = cmSystemTools::CollapseFullPath(tLocation);
+ if(depLocation == tLocation)
+ {
+ this->GeneratorTarget->Target->AddUtility(util);
+ return true;
+ }
}
}
else
{
- cmOStringStream e;
- e << "Objects of target \"" << objLibName
- << "\" referenced but no such target exists.";
- this->GlobalGenerator->GetCMakeInstance()
- ->IssueMessage(cmake::FATAL_ERROR, e.str(),
- this->Target->GetBacktrace());
- return;
+ // The original name of the dependency was not a full path. It
+ // must name a target, so add the target-level dependency.
+ this->GeneratorTarget->Target->AddUtility(util);
+ return true;
}
}
+
+ // The dependency does not name a target built in this project.
+ return false;
}
//----------------------------------------------------------------------------
-void cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs)
+void
+cmTargetTraceDependencies
+::CheckCustomCommand(cmCustomCommand const& cc)
{
- for(std::vector<cmTarget*>::const_iterator
- ti = this->ObjectLibraries.begin();
- ti != this->ObjectLibraries.end(); ++ti)
+ // Transform command names that reference targets built in this
+ // project to corresponding target-level dependencies.
+ cmGeneratorExpression ge(cc.GetBacktrace());
+
+ // Add target-level dependencies referenced by generator expressions.
+ std::set<cmGeneratorTarget*> targets;
+
+ for(cmCustomCommandLines::const_iterator cit = cc.GetCommandLines().begin();
+ cit != cc.GetCommandLines().end(); ++cit)
{
- cmTarget* objLib = *ti;
- cmGeneratorTarget* ogt =
- this->GlobalGenerator->GetGeneratorTarget(objLib);
- for(std::vector<cmSourceFile*>::const_iterator
- si = ogt->ObjectSources.begin();
- si != ogt->ObjectSources.end(); ++si)
+ std::string const& command = *cit->begin();
+ // Check for a target with this name.
+ if(cmGeneratorTarget* t =
+ this->LocalGenerator->FindGeneratorTargetToUse(command))
{
- std::string obj = ogt->ObjectDirectory;
- obj += ogt->Objects[*si];
- objs.push_back(obj);
+ if(t->GetType() == cmState::EXECUTABLE)
+ {
+ // The command refers to an executable target built in
+ // this project. Add the target-level dependency to make
+ // sure the executable is up to date before this custom
+ // command possibly runs.
+ this->GeneratorTarget->Target->AddUtility(command);
+ }
+ }
+
+ // Check for target references in generator expressions.
+ for(cmCustomCommandLine::const_iterator cli = cit->begin();
+ cli != cit->end(); ++cli)
+ {
+ const cmsys::auto_ptr<cmCompiledGeneratorExpression> cge
+ = ge.Parse(*cli);
+ cge->Evaluate(this->GeneratorTarget->GetLocalGenerator(), "", true);
+ std::set<cmGeneratorTarget*> geTargets = cge->GetTargets();
+ targets.insert(geTargets.begin(), geTargets.end());
}
}
+
+ for(std::set<cmGeneratorTarget*>::iterator ti = targets.begin();
+ ti != targets.end(); ++ti)
+ {
+ this->GeneratorTarget->Target->AddUtility((*ti)->GetName());
+ }
+
+ // Queue the custom command dependencies.
+ std::vector<std::string> configs;
+ std::set<std::string> emitted;
+ this->Makefile->GetConfigurations(configs);
+ if (configs.empty())
+ {
+ configs.push_back("");
+ }
+ for(std::vector<std::string>::const_iterator ci = configs.begin();
+ ci != configs.end(); ++ci)
+ {
+ this->FollowCommandDepends(cc, *ci, emitted);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmTargetTraceDependencies::FollowCommandDepends(cmCustomCommand const& cc,
+ const std::string& config,
+ std::set<std::string>& emitted)
+{
+ cmCustomCommandGenerator ccg(cc, config,
+ this->GeneratorTarget->LocalGenerator);
+
+ const std::vector<std::string>& depends = ccg.GetDepends();
+
+ for(std::vector<std::string>::const_iterator di = depends.begin();
+ di != depends.end(); ++di)
+ {
+ std::string const& dep = *di;
+ if(emitted.insert(dep).second)
+ {
+ if(!this->IsUtility(dep))
+ {
+ // The dependency does not name a target and may be a file we
+ // know how to generate. Queue it.
+ this->FollowName(dep);
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmTargetTraceDependencies
+::CheckCustomCommands(const std::vector<cmCustomCommand>& commands)
+{
+ for(std::vector<cmCustomCommand>::const_iterator cli = commands.begin();
+ cli != commands.end(); ++cli)
+ {
+ this->CheckCustomCommand(*cli);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::TraceDependencies()
+{
+ // CMake-generated targets have no dependencies to trace. Normally tracing
+ // would find nothing anyway, but when building CMake itself the "install"
+ // target command ends up referencing the "cmake" target but we do not
+ // really want the dependency because "install" depend on "all" anyway.
+ if(this->GetType() == cmState::GLOBAL_TARGET)
+ {
+ return;
+ }
+
+ // Use a helper object to trace the dependencies.
+ cmTargetTraceDependencies tracer(this);
+ tracer.Trace();
+}
+
+std::string
+cmGeneratorTarget::GetCompilePDBDirectory(const std::string& config) const
+{
+ if(CompileInfo const* info = this->GetCompileInfo(config))
+ {
+ return info->CompilePdbDir;
+ }
+ return "";
}
//----------------------------------------------------------------------------
-void cmGeneratorTarget::GetAppleArchs(const char* config,
- std::vector<std::string>& archVec)
+void cmGeneratorTarget::GetAppleArchs(const std::string& config,
+ std::vector<std::string>& archVec) const
{
const char* archs = 0;
- if(config && *config)
+ if(!config.empty())
{
std::string defVarName = "OSX_ARCHITECTURES_";
defVarName += cmSystemTools::UpperCase(config);
- archs = this->Target->GetProperty(defVarName.c_str());
+ archs = this->GetProperty(defVarName);
}
if(!archs)
{
- archs = this->Target->GetProperty("OSX_ARCHITECTURES");
+ archs = this->GetProperty("OSX_ARCHITECTURES");
}
if(archs)
{
@@ -293,27 +2613,3517 @@ void cmGeneratorTarget::GetAppleArchs(const char* config,
}
//----------------------------------------------------------------------------
-const char* cmGeneratorTarget::GetCreateRuleVariable()
+std::string
+cmGeneratorTarget::GetCreateRuleVariable(std::string const& lang,
+ std::string const& config) const
{
switch(this->GetType())
{
- case cmTarget::STATIC_LIBRARY:
- return "_CREATE_STATIC_LIBRARY";
- case cmTarget::SHARED_LIBRARY:
- return "_CREATE_SHARED_LIBRARY";
- case cmTarget::MODULE_LIBRARY:
- return "_CREATE_SHARED_MODULE";
- case cmTarget::EXECUTABLE:
- return "_LINK_EXECUTABLE";
+ case cmState::STATIC_LIBRARY:
+ {
+ std::string var = "CMAKE_" + lang + "_CREATE_STATIC_LIBRARY";
+ if(this->GetFeatureAsBool(
+ "INTERPROCEDURAL_OPTIMIZATION", config))
+ {
+ std::string varIPO = var + "_IPO";
+ if(this->Makefile->GetDefinition(varIPO))
+ {
+ return varIPO;
+ }
+ }
+ return var;
+ }
+ case cmState::SHARED_LIBRARY:
+ return "CMAKE_" + lang + "_CREATE_SHARED_LIBRARY";
+ case cmState::MODULE_LIBRARY:
+ return "CMAKE_" + lang + "_CREATE_SHARED_MODULE";
+ case cmState::EXECUTABLE:
+ return "CMAKE_" + lang + "_LINK_EXECUTABLE";
default:
break;
}
return "";
}
+//----------------------------------------------------------------------------
+static void processIncludeDirectories(cmGeneratorTarget const* tgt,
+ const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries,
+ std::vector<std::string> &includes,
+ UNORDERED_SET<std::string> &uniqueIncludes,
+ cmGeneratorExpressionDAGChecker *dagChecker,
+ const std::string& config, bool debugIncludes,
+ const std::string& language)
+{
+ for (std::vector<cmGeneratorTarget::TargetPropertyEntry*>::const_iterator
+ it = entries.begin(), end = entries.end(); it != end; ++it)
+ {
+ cmLinkImplItem const& item = (*it)->LinkImplItem;
+ std::string const& targetName = item;
+ bool const fromImported = item.Target && item.Target->IsImported();
+ bool const checkCMP0027 = item.FromGenex;
+ std::vector<std::string> entryIncludes;
+ cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(
+ tgt->GetLocalGenerator(),
+ config,
+ false,
+ tgt,
+ dagChecker, language),
+ entryIncludes);
+
+ std::string usedIncludes;
+ for(std::vector<std::string>::iterator
+ li = entryIncludes.begin(); li != entryIncludes.end(); ++li)
+ {
+ if (fromImported
+ && !cmSystemTools::FileExists(li->c_str()))
+ {
+ std::ostringstream e;
+ cmake::MessageType messageType = cmake::FATAL_ERROR;
+ if (checkCMP0027)
+ {
+ switch(tgt->GetPolicyStatusCMP0027())
+ {
+ case cmPolicies::WARN:
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0027) << "\n";
+ case cmPolicies::OLD:
+ messageType = cmake::AUTHOR_WARNING;
+ break;
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::NEW:
+ break;
+ }
+ }
+ e << "Imported target \"" << targetName << "\" includes "
+ "non-existent path\n \"" << *li << "\"\nin its "
+ "INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:\n"
+ "* The path was deleted, renamed, or moved to another "
+ "location.\n"
+ "* An install or uninstall procedure did not complete "
+ "successfully.\n"
+ "* The installation package was faulty and references files it "
+ "does not provide.\n";
+ tgt->GetLocalGenerator()->IssueMessage(messageType, e.str());
+ return;
+ }
+
+ if (!cmSystemTools::FileIsFullPath(li->c_str()))
+ {
+ std::ostringstream e;
+ bool noMessage = false;
+ cmake::MessageType messageType = cmake::FATAL_ERROR;
+ if (!targetName.empty())
+ {
+ e << "Target \"" << targetName << "\" contains relative "
+ "path in its INTERFACE_INCLUDE_DIRECTORIES:\n"
+ " \"" << *li << "\"";
+ }
+ else
+ {
+ switch(tgt->GetPolicyStatusCMP0021())
+ {
+ case cmPolicies::WARN:
+ {
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0021) << "\n";
+ messageType = cmake::AUTHOR_WARNING;
+ }
+ break;
+ case cmPolicies::OLD:
+ noMessage = true;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ // Issue the fatal message.
+ break;
+ }
+ e << "Found relative path while evaluating include directories of "
+ "\"" << tgt->GetName() << "\":\n \"" << *li << "\"\n";
+ }
+ if (!noMessage)
+ {
+ tgt->GetLocalGenerator()->IssueMessage(messageType, e.str());
+ if (messageType == cmake::FATAL_ERROR)
+ {
+ return;
+ }
+ }
+ }
+
+ if (!cmSystemTools::IsOff(li->c_str()))
+ {
+ cmSystemTools::ConvertToUnixSlashes(*li);
+ }
+ std::string inc = *li;
+
+ if(uniqueIncludes.insert(inc).second)
+ {
+ includes.push_back(inc);
+ if (debugIncludes)
+ {
+ usedIncludes += " * " + inc + "\n";
+ }
+ }
+ }
+ if (!usedIncludes.empty())
+ {
+ tgt->GetLocalGenerator()->GetCMakeInstance()->IssueMessage(cmake::LOG,
+ std::string("Used includes for target ")
+ + tgt->GetName() + ":\n"
+ + usedIncludes, (*it)->ge->GetBacktrace());
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+std::vector<std::string>
+cmGeneratorTarget::GetIncludeDirectories(const std::string& config,
+ const std::string& lang) const
+{
+ std::vector<std::string> includes;
+ UNORDERED_SET<std::string> uniqueIncludes;
+
+ cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
+ "INCLUDE_DIRECTORIES", 0, 0);
+
+ std::vector<std::string> debugProperties;
+ const char *debugProp =
+ this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+ if (debugProp)
+ {
+ cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+ }
+
+ bool debugIncludes = !this->DebugIncludesDone
+ && std::find(debugProperties.begin(),
+ debugProperties.end(),
+ "INCLUDE_DIRECTORIES")
+ != debugProperties.end();
+
+ if (this->GlobalGenerator->GetConfigureDoneCMP0026())
+ {
+ this->DebugIncludesDone = true;
+ }
+
+ processIncludeDirectories(this,
+ this->IncludeDirectoriesEntries,
+ includes,
+ uniqueIncludes,
+ &dagChecker,
+ config,
+ debugIncludes,
+ lang);
+
+ std::vector<cmGeneratorTarget::TargetPropertyEntry*>
+ linkInterfaceIncludeDirectoriesEntries;
+ AddInterfaceEntries(
+ this, config, "INTERFACE_INCLUDE_DIRECTORIES",
+ linkInterfaceIncludeDirectoriesEntries);
+
+ if(this->Makefile->IsOn("APPLE"))
+ {
+ cmLinkImplementationLibraries const* impl =
+ this->GetLinkImplementationLibraries(config);
+ for(std::vector<cmLinkImplItem>::const_iterator
+ it = impl->Libraries.begin();
+ it != impl->Libraries.end(); ++it)
+ {
+ std::string libDir = cmSystemTools::CollapseFullPath(*it);
+
+ static cmsys::RegularExpression
+ frameworkCheck("(.*\\.framework)(/Versions/[^/]+)?/[^/]+$");
+ if(!frameworkCheck.find(libDir))
+ {
+ continue;
+ }
+
+ libDir = frameworkCheck.match(1);
+
+ cmGeneratorExpression ge;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(libDir.c_str());
+ linkInterfaceIncludeDirectoriesEntries
+ .push_back(new cmGeneratorTarget::TargetPropertyEntry(cge));
+ }
+ }
+
+ processIncludeDirectories(this,
+ linkInterfaceIncludeDirectoriesEntries,
+ includes,
+ uniqueIncludes,
+ &dagChecker,
+ config,
+ debugIncludes,
+ lang);
+
+ cmDeleteAll(linkInterfaceIncludeDirectoriesEntries);
+
+ return includes;
+}
+
+//----------------------------------------------------------------------------
+static void processCompileOptionsInternal(cmGeneratorTarget const* tgt,
+ const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries,
+ std::vector<std::string> &options,
+ UNORDERED_SET<std::string> &uniqueOptions,
+ cmGeneratorExpressionDAGChecker *dagChecker,
+ const std::string& config, bool debugOptions, const char *logName,
+ std::string const& language)
+{
+ for (std::vector<cmGeneratorTarget::TargetPropertyEntry*>::const_iterator
+ it = entries.begin(), end = entries.end(); it != end; ++it)
+ {
+ std::vector<std::string> entryOptions;
+ cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(
+ tgt->GetLocalGenerator(),
+ config,
+ false,
+ tgt,
+ dagChecker,
+ language),
+ entryOptions);
+ std::string usedOptions;
+ for(std::vector<std::string>::iterator
+ li = entryOptions.begin(); li != entryOptions.end(); ++li)
+ {
+ std::string const& opt = *li;
+
+ if(uniqueOptions.insert(opt).second)
+ {
+ options.push_back(opt);
+ if (debugOptions)
+ {
+ usedOptions += " * " + opt + "\n";
+ }
+ }
+ }
+ if (!usedOptions.empty())
+ {
+ tgt->GetLocalGenerator()->GetCMakeInstance()->IssueMessage(cmake::LOG,
+ std::string("Used compile ") + logName
+ + std::string(" for target ")
+ + tgt->GetName() + ":\n"
+ + usedOptions, (*it)->ge->GetBacktrace());
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+static void processCompileOptions(cmGeneratorTarget const* tgt,
+ const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries,
+ std::vector<std::string> &options,
+ UNORDERED_SET<std::string> &uniqueOptions,
+ cmGeneratorExpressionDAGChecker *dagChecker,
+ const std::string& config, bool debugOptions,
+ std::string const& language)
+{
+ processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
+ dagChecker, config, debugOptions, "options",
+ language);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetCompileOptions(std::vector<std::string> &result,
+ const std::string& config,
+ const std::string& language) const
+{
+ UNORDERED_SET<std::string> uniqueOptions;
+
+ cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
+ "COMPILE_OPTIONS", 0, 0);
+
+ std::vector<std::string> debugProperties;
+ const char *debugProp =
+ this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+ if (debugProp)
+ {
+ cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+ }
+
+ bool debugOptions = !this->DebugCompileOptionsDone
+ && std::find(debugProperties.begin(),
+ debugProperties.end(),
+ "COMPILE_OPTIONS")
+ != debugProperties.end();
+
+ if (this->GlobalGenerator->GetConfigureDoneCMP0026())
+ {
+ this->DebugCompileOptionsDone = true;
+ }
+
+ processCompileOptions(this,
+ this->CompileOptionsEntries,
+ result,
+ uniqueOptions,
+ &dagChecker,
+ config,
+ debugOptions,
+ language);
+
+ std::vector<cmGeneratorTarget::TargetPropertyEntry*>
+ linkInterfaceCompileOptionsEntries;
+
+ AddInterfaceEntries(
+ this, config, "INTERFACE_COMPILE_OPTIONS",
+ linkInterfaceCompileOptionsEntries);
+
+ processCompileOptions(this,
+ linkInterfaceCompileOptionsEntries,
+ result,
+ uniqueOptions,
+ &dagChecker,
+ config,
+ debugOptions,
+ language);
+
+ cmDeleteAll(linkInterfaceCompileOptionsEntries);
+}
+
+//----------------------------------------------------------------------------
+static void processCompileFeatures(cmGeneratorTarget const* tgt,
+ const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries,
+ std::vector<std::string> &options,
+ UNORDERED_SET<std::string> &uniqueOptions,
+ cmGeneratorExpressionDAGChecker *dagChecker,
+ const std::string& config, bool debugOptions)
+{
+ processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
+ dagChecker, config, debugOptions, "features",
+ std::string());
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetCompileFeatures(std::vector<std::string> &result,
+ const std::string& config) const
+{
+ UNORDERED_SET<std::string> uniqueFeatures;
+
+ cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
+ "COMPILE_FEATURES",
+ 0, 0);
+
+ std::vector<std::string> debugProperties;
+ const char *debugProp =
+ this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+ if (debugProp)
+ {
+ cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+ }
+
+ bool debugFeatures = !this->DebugCompileFeaturesDone
+ && std::find(debugProperties.begin(),
+ debugProperties.end(),
+ "COMPILE_FEATURES")
+ != debugProperties.end();
+
+ if (this->GlobalGenerator->GetConfigureDoneCMP0026())
+ {
+ this->DebugCompileFeaturesDone = true;
+ }
+
+ processCompileFeatures(this,
+ this->CompileFeaturesEntries,
+ result,
+ uniqueFeatures,
+ &dagChecker,
+ config,
+ debugFeatures);
+
+ std::vector<cmGeneratorTarget::TargetPropertyEntry*>
+ linkInterfaceCompileFeaturesEntries;
+ AddInterfaceEntries(
+ this, config, "INTERFACE_COMPILE_FEATURES",
+ linkInterfaceCompileFeaturesEntries);
+
+ processCompileFeatures(this,
+ linkInterfaceCompileFeaturesEntries,
+ result,
+ uniqueFeatures,
+ &dagChecker,
+ config,
+ debugFeatures);
+
+ cmDeleteAll(linkInterfaceCompileFeaturesEntries);
+}
+
+//----------------------------------------------------------------------------
+static void processCompileDefinitions(cmGeneratorTarget const* tgt,
+ const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries,
+ std::vector<std::string> &options,
+ UNORDERED_SET<std::string> &uniqueOptions,
+ cmGeneratorExpressionDAGChecker *dagChecker,
+ const std::string& config, bool debugOptions,
+ std::string const& language)
+{
+ processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
+ dagChecker, config, debugOptions,
+ "definitions", language);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetCompileDefinitions(std::vector<std::string> &list,
+ const std::string& config,
+ const std::string& language) const
+{
+ UNORDERED_SET<std::string> uniqueOptions;
+
+ cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
+ "COMPILE_DEFINITIONS", 0, 0);
+
+ std::vector<std::string> debugProperties;
+ const char *debugProp =
+ this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+ if (debugProp)
+ {
+ cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+ }
+
+ bool debugDefines = !this->DebugCompileDefinitionsDone
+ && std::find(debugProperties.begin(),
+ debugProperties.end(),
+ "COMPILE_DEFINITIONS")
+ != debugProperties.end();
+
+ if (this->GlobalGenerator->GetConfigureDoneCMP0026())
+ {
+ this->DebugCompileDefinitionsDone = true;
+ }
+
+ processCompileDefinitions(this,
+ this->CompileDefinitionsEntries,
+ list,
+ uniqueOptions,
+ &dagChecker,
+ config,
+ debugDefines,
+ language);
+
+ std::vector<cmGeneratorTarget::TargetPropertyEntry*>
+ linkInterfaceCompileDefinitionsEntries;
+ AddInterfaceEntries(
+ this, config, "INTERFACE_COMPILE_DEFINITIONS",
+ linkInterfaceCompileDefinitionsEntries);
+ if (!config.empty())
+ {
+ std::string configPropName = "COMPILE_DEFINITIONS_"
+ + cmSystemTools::UpperCase(config);
+ const char *configProp = this->GetProperty(configPropName);
+ if (configProp)
+ {
+ switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0043))
+ {
+ case cmPolicies::WARN:
+ {
+ std::ostringstream e;
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0043);
+ this->LocalGenerator->IssueMessage(cmake::AUTHOR_WARNING,
+ e.str());
+ }
+ case cmPolicies::OLD:
+ {
+ cmGeneratorExpression ge;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(configProp);
+ linkInterfaceCompileDefinitionsEntries
+ .push_back(new cmGeneratorTarget::TargetPropertyEntry(cge));
+ }
+ break;
+ case cmPolicies::NEW:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ break;
+ }
+ }
+ }
+
+ processCompileDefinitions(this,
+ linkInterfaceCompileDefinitionsEntries,
+ list,
+ uniqueOptions,
+ &dagChecker,
+ config,
+ debugDefines,
+ language);
+
+ cmDeleteAll(linkInterfaceCompileDefinitionsEntries);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::ComputeTargetManifest(
+ const std::string& config) const
+{
+ if (this->IsImported())
+ {
+ return;
+ }
+ cmGlobalGenerator* gg = this->LocalGenerator->GetGlobalGenerator();
+
+ // Get the names.
+ std::string name;
+ std::string soName;
+ std::string realName;
+ std::string impName;
+ std::string pdbName;
+ if(this->GetType() == cmState::EXECUTABLE)
+ {
+ this->GetExecutableNames(name, realName, impName, pdbName, config);
+ }
+ else if(this->GetType() == cmState::STATIC_LIBRARY ||
+ this->GetType() == cmState::SHARED_LIBRARY ||
+ this->GetType() == cmState::MODULE_LIBRARY)
+ {
+ this->GetLibraryNames(name, soName, realName, impName, pdbName,
+ config);
+ }
+ else
+ {
+ return;
+ }
+
+ // Get the directory.
+ std::string dir = this->GetDirectory(config, false);
+
+ // Add each name.
+ std::string f;
+ if(!name.empty())
+ {
+ f = dir;
+ f += "/";
+ f += name;
+ gg->AddToManifest(f);
+ }
+ if(!soName.empty())
+ {
+ f = dir;
+ f += "/";
+ f += soName;
+ gg->AddToManifest(f);
+ }
+ if(!realName.empty())
+ {
+ f = dir;
+ f += "/";
+ f += realName;
+ gg->AddToManifest(f);
+ }
+ if(!pdbName.empty())
+ {
+ f = dir;
+ f += "/";
+ f += pdbName;
+ gg->AddToManifest(f);
+ }
+ if(!impName.empty())
+ {
+ f = this->GetDirectory(config, true);
+ f += "/";
+ f += impName;
+ gg->AddToManifest(f);
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetFullPath(const std::string& config,
+ bool implib, bool realname) const
+{
+ if(this->IsImported())
+ {
+ return this->Target->ImportedGetFullPath(config, implib);
+ }
+ else
+ {
+ return this->NormalGetFullPath(config, implib, realname);
+ }
+}
+
+std::string cmGeneratorTarget::NormalGetFullPath(const std::string& config,
+ bool implib,
+ bool realname) const
+{
+ std::string fpath = this->GetDirectory(config, implib);
+ fpath += "/";
+ if(this->IsAppBundleOnApple())
+ {
+ fpath = this->BuildMacContentDirectory(fpath, config, false);
+ fpath += "/";
+ }
+
+ // Add the full name of the target.
+ if(implib)
+ {
+ fpath += this->GetFullName(config, true);
+ }
+ else if(realname)
+ {
+ fpath += this->NormalGetRealName(config);
+ }
+ else
+ {
+ fpath += this->GetFullName(config, false);
+ }
+ return fpath;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::NormalGetRealName(const std::string& config) const
+{
+ // This should not be called for imported targets.
+ // TODO: Split cmTarget into a class hierarchy to get compile-time
+ // enforcement of the limited imported target API.
+ if(this->IsImported())
+ {
+ std::string msg = "NormalGetRealName called on imported target: ";
+ msg += this->GetName();
+ this->LocalGenerator->IssueMessage(cmake::INTERNAL_ERROR, msg);
+ }
+
+ if(this->GetType() == cmState::EXECUTABLE)
+ {
+ // Compute the real name that will be built.
+ std::string name;
+ std::string realName;
+ std::string impName;
+ std::string pdbName;
+ this->GetExecutableNames(name, realName, impName, pdbName, config);
+ return realName;
+ }
+ else
+ {
+ // Compute the real name that will be built.
+ std::string name;
+ std::string soName;
+ std::string realName;
+ std::string impName;
+ std::string pdbName;
+ this->GetLibraryNames(name, soName, realName,
+ impName, pdbName, config);
+ return realName;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetLibraryNames(std::string& name,
+ std::string& soName,
+ std::string& realName,
+ std::string& impName,
+ std::string& pdbName,
+ const std::string& config) const
+{
+ // This should not be called for imported targets.
+ // TODO: Split cmTarget into a class hierarchy to get compile-time
+ // enforcement of the limited imported target API.
+ if(this->IsImported())
+ {
+ std::string msg = "GetLibraryNames called on imported target: ";
+ msg += this->GetName();
+ this->LocalGenerator->IssueMessage(cmake::INTERNAL_ERROR,
+ msg);
+ return;
+ }
+
+ // Check for library version properties.
+ const char* version = this->GetProperty("VERSION");
+ const char* soversion = this->GetProperty("SOVERSION");
+ if(!this->HasSOName(config) ||
+ this->Makefile->IsOn("CMAKE_PLATFORM_NO_VERSIONED_SONAME") ||
+ this->IsFrameworkOnApple())
+ {
+ // Versioning is supported only for shared libraries and modules,
+ // and then only when the platform supports an soname flag.
+ version = 0;
+ soversion = 0;
+ }
+ if(version && !soversion)
+ {
+ // The soversion must be set if the library version is set. Use
+ // the library version as the soversion.
+ soversion = version;
+ }
+ if(!version && soversion)
+ {
+ // Use the soversion as the library version.
+ version = soversion;
+ }
+
+ // Get the components of the library name.
+ std::string prefix;
+ std::string base;
+ std::string suffix;
+ this->GetFullNameInternal(config, false, prefix, base, suffix);
+
+ // The library name.
+ name = prefix+base+suffix;
+
+ if(this->IsFrameworkOnApple())
+ {
+ realName = prefix;
+ if(!this->Makefile->PlatformIsAppleIos())
+ {
+ realName += "Versions/";
+ realName += this->GetFrameworkVersion();
+ realName += "/";
+ }
+ realName += base;
+ soName = realName;
+ }
+ else
+ {
+ // The library's soname.
+ this->ComputeVersionedName(soName, prefix, base, suffix,
+ name, soversion);
+
+ // The library's real name on disk.
+ this->ComputeVersionedName(realName, prefix, base, suffix,
+ name, version);
+ }
+
+ // The import library name.
+ if(this->GetType() == cmState::SHARED_LIBRARY ||
+ this->GetType() == cmState::MODULE_LIBRARY)
+ {
+ impName = this->GetFullNameInternal(config, true);
+ }
+ else
+ {
+ impName = "";
+ }
+
+ // The program database file name.
+ pdbName = this->GetPDBName(config);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetExecutableNames(std::string& name,
+ std::string& realName,
+ std::string& impName,
+ std::string& pdbName,
+ const std::string& config) const
+{
+ // This should not be called for imported targets.
+ // TODO: Split cmTarget into a class hierarchy to get compile-time
+ // enforcement of the limited imported target API.
+ if(this->IsImported())
+ {
+ std::string msg =
+ "GetExecutableNames called on imported target: ";
+ msg += this->GetName();
+ this->LocalGenerator->IssueMessage(cmake::INTERNAL_ERROR, msg);
+ }
+
+ // This versioning is supported only for executables and then only
+ // when the platform supports symbolic links.
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ const char* version = 0;
+#else
+ // Check for executable version properties.
+ const char* version = this->GetProperty("VERSION");
+ if(this->GetType() != cmState::EXECUTABLE || this->Makefile->IsOn("XCODE"))
+ {
+ version = 0;
+ }
+#endif
+
+ // Get the components of the executable name.
+ std::string prefix;
+ std::string base;
+ std::string suffix;
+ this->GetFullNameInternal(config, false, prefix, base, suffix);
+
+ // The executable name.
+ name = prefix+base+suffix;
+
+ // The executable's real name on disk.
+#if defined(__CYGWIN__)
+ realName = prefix+base;
+#else
+ realName = name;
+#endif
+ if(version)
+ {
+ realName += "-";
+ realName += version;
+ }
+#if defined(__CYGWIN__)
+ realName += suffix;
+#endif
+
+ // The import library name.
+ impName = this->GetFullNameInternal(config, true);
+
+ // The program database file name.
+ pdbName = this->GetPDBName(config);
+}
+
+//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetFullNameInternal(const std::string& config,
+ bool implib) const
+{
+ std::string prefix;
+ std::string base;
+ std::string suffix;
+ this->GetFullNameInternal(config, implib, prefix, base, suffix);
+ return prefix+base+suffix;
+}
+
+//----------------------------------------------------------------------------
+const char*
+cmGeneratorTarget::ImportedGetLocation(const std::string& config) const
+{
+ static std::string location;
+ assert(this->IsImported());
+ location = this->Target->ImportedGetFullPath(config, false);
+ return location.c_str();
+}
+
+//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetFullNameImported(const std::string& config,
+ bool implib) const
+{
+ return cmSystemTools::GetFilenameName(
+ this->Target->ImportedGetFullPath(config, implib));
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetFullNameInternal(const std::string& config,
+ bool implib,
+ std::string& outPrefix,
+ std::string& outBase,
+ std::string& outSuffix) const
+{
+ // Use just the target name for non-main target types.
+ if(this->GetType() != cmState::STATIC_LIBRARY &&
+ this->GetType() != cmState::SHARED_LIBRARY &&
+ this->GetType() != cmState::MODULE_LIBRARY &&
+ this->GetType() != cmState::EXECUTABLE)
+ {
+ outPrefix = "";
+ outBase = this->GetName();
+ outSuffix = "";
+ return;
+ }
+
+ // Return an empty name for the import library if this platform
+ // does not support import libraries.
+ if(implib &&
+ !this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"))
+ {
+ outPrefix = "";
+ outBase = "";
+ outSuffix = "";
+ return;
+ }
+
+ // The implib option is only allowed for shared libraries, module
+ // libraries, and executables.
+ if(this->GetType() != cmState::SHARED_LIBRARY &&
+ this->GetType() != cmState::MODULE_LIBRARY &&
+ this->GetType() != cmState::EXECUTABLE)
+ {
+ implib = false;
+ }
+
+ // Compute the full name for main target types.
+ const char* targetPrefix = (implib
+ ? this->GetProperty("IMPORT_PREFIX")
+ : this->GetProperty("PREFIX"));
+ const char* targetSuffix = (implib
+ ? this->GetProperty("IMPORT_SUFFIX")
+ : this->GetProperty("SUFFIX"));
+ const char* configPostfix = 0;
+ if(!config.empty())
+ {
+ std::string configProp = cmSystemTools::UpperCase(config);
+ configProp += "_POSTFIX";
+ configPostfix = this->GetProperty(configProp);
+ // Mac application bundles and frameworks have no postfix.
+ if(configPostfix &&
+ (this->IsAppBundleOnApple() || this->IsFrameworkOnApple()))
+ {
+ configPostfix = 0;
+ }
+ }
+ const char* prefixVar = this->Target->GetPrefixVariableInternal(implib);
+ const char* suffixVar = this->Target->GetSuffixVariableInternal(implib);
+
+ // Check for language-specific default prefix and suffix.
+ std::string ll = this->GetLinkerLanguage(config);
+ if(!ll.empty())
+ {
+ if(!targetSuffix && suffixVar && *suffixVar)
+ {
+ std::string langSuff = suffixVar + std::string("_") + ll;
+ targetSuffix = this->Makefile->GetDefinition(langSuff);
+ }
+ if(!targetPrefix && prefixVar && *prefixVar)
+ {
+ std::string langPrefix = prefixVar + std::string("_") + ll;
+ targetPrefix = this->Makefile->GetDefinition(langPrefix);
+ }
+ }
+
+ // if there is no prefix on the target use the cmake definition
+ if(!targetPrefix && prefixVar)
+ {
+ targetPrefix = this->Makefile->GetSafeDefinition(prefixVar);
+ }
+ // if there is no suffix on the target use the cmake definition
+ if(!targetSuffix && suffixVar)
+ {
+ targetSuffix = this->Makefile->GetSafeDefinition(suffixVar);
+ }
+
+ // frameworks have directory prefix but no suffix
+ std::string fw_prefix;
+ if(this->IsFrameworkOnApple())
+ {
+ fw_prefix = this->GetOutputName(config, false);
+ fw_prefix += ".framework/";
+ targetPrefix = fw_prefix.c_str();
+ targetSuffix = 0;
+ }
+
+ if(this->IsCFBundleOnApple())
+ {
+ fw_prefix = this->GetCFBundleDirectory(config, false);
+ fw_prefix += "/";
+ targetPrefix = fw_prefix.c_str();
+ targetSuffix = 0;
+ }
+
+ // Begin the final name with the prefix.
+ outPrefix = targetPrefix?targetPrefix:"";
+
+ // Append the target name or property-specified name.
+ outBase += this->GetOutputName(config, implib);
+
+ // Append the per-configuration postfix.
+ outBase += configPostfix?configPostfix:"";
+
+ // Name shared libraries with their version number on some platforms.
+ if(const char* soversion = this->GetProperty("SOVERSION"))
+ {
+ if(this->GetType() == cmState::SHARED_LIBRARY && !implib &&
+ this->Makefile->IsOn("CMAKE_SHARED_LIBRARY_NAME_WITH_VERSION"))
+ {
+ outBase += "-";
+ outBase += soversion;
+ }
+ }
+
+ // Append the suffix.
+ outSuffix = targetSuffix?targetSuffix:"";
+}
+
+
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::GetLinkerLanguage(const std::string& config) const
+{
+ return this->GetLinkClosure(config)->LinkerLanguage;
+}
+
+//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetPDBName(const std::string& config) const
+{
+ std::string prefix;
+ std::string base;
+ std::string suffix;
+ this->GetFullNameInternal(config, false, prefix, base, suffix);
+
+ std::vector<std::string> props;
+ std::string configUpper =
+ cmSystemTools::UpperCase(config);
+ if(!configUpper.empty())
+ {
+ // PDB_NAME_<CONFIG>
+ props.push_back("PDB_NAME_" + configUpper);
+ }
+
+ // PDB_NAME
+ props.push_back("PDB_NAME");
+
+ for(std::vector<std::string>::const_iterator i = props.begin();
+ i != props.end(); ++i)
+ {
+ if(const char* outName = this->GetProperty(*i))
+ {
+ base = outName;
+ break;
+ }
+ }
+ return prefix+base+".pdb";
+}
+
+bool cmGeneratorTarget::StrictTargetComparison::operator()(
+ cmGeneratorTarget const* t1, cmGeneratorTarget const* t2) const
+{
+ int nameResult = strcmp(t1->GetName().c_str(), t2->GetName().c_str());
+ if (nameResult == 0)
+ {
+ return strcmp(t1->GetLocalGenerator()->GetCurrentBinaryDirectory(),
+ t2->GetLocalGenerator()->GetCurrentBinaryDirectory()) < 0;
+ }
+ return nameResult < 0;
+}
+
+//----------------------------------------------------------------------------
+struct cmGeneratorTarget::SourceFileFlags
+cmGeneratorTarget::GetTargetSourceFileFlags(const cmSourceFile* sf) const
+{
+ struct SourceFileFlags flags;
+ this->ConstructSourceFileFlags();
+ std::map<cmSourceFile const*, SourceFileFlags>::iterator si =
+ this->SourceFlagsMap.find(sf);
+ if(si != this->SourceFlagsMap.end())
+ {
+ flags = si->second;
+ }
+ else
+ {
+ // Handle the MACOSX_PACKAGE_LOCATION property on source files that
+ // were not listed in one of the other lists.
+ if(const char* location = sf->GetProperty("MACOSX_PACKAGE_LOCATION"))
+ {
+ flags.MacFolder = location;
+ if(strcmp(location, "Resources") == 0)
+ {
+ flags.Type = cmGeneratorTarget::SourceFileTypeResource;
+ }
+ else
+ {
+ flags.Type = cmGeneratorTarget::SourceFileTypeMacContent;
+ }
+ }
+ }
+ return flags;
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::ConstructSourceFileFlags() const
+{
+ if(this->SourceFileFlagsConstructed)
+ {
+ return;
+ }
+ this->SourceFileFlagsConstructed = true;
+
+ // Process public headers to mark the source files.
+ if(const char* files = this->GetProperty("PUBLIC_HEADER"))
+ {
+ std::vector<std::string> relFiles;
+ cmSystemTools::ExpandListArgument(files, relFiles);
+ for(std::vector<std::string>::iterator it = relFiles.begin();
+ it != relFiles.end(); ++it)
+ {
+ if(cmSourceFile* sf = this->Makefile->GetSource(*it))
+ {
+ SourceFileFlags& flags = this->SourceFlagsMap[sf];
+ flags.MacFolder = "Headers";
+ flags.Type = cmGeneratorTarget::SourceFileTypePublicHeader;
+ }
+ }
+ }
+
+ // Process private headers after public headers so that they take
+ // precedence if a file is listed in both.
+ if(const char* files = this->GetProperty("PRIVATE_HEADER"))
+ {
+ std::vector<std::string> relFiles;
+ cmSystemTools::ExpandListArgument(files, relFiles);
+ for(std::vector<std::string>::iterator it = relFiles.begin();
+ it != relFiles.end(); ++it)
+ {
+ if(cmSourceFile* sf = this->Makefile->GetSource(*it))
+ {
+ SourceFileFlags& flags = this->SourceFlagsMap[sf];
+ flags.MacFolder = "PrivateHeaders";
+ flags.Type = cmGeneratorTarget::SourceFileTypePrivateHeader;
+ }
+ }
+ }
+
+ // Mark sources listed as resources.
+ if(const char* files = this->GetProperty("RESOURCE"))
+ {
+ std::vector<std::string> relFiles;
+ cmSystemTools::ExpandListArgument(files, relFiles);
+ for(std::vector<std::string>::iterator it = relFiles.begin();
+ it != relFiles.end(); ++it)
+ {
+ if(cmSourceFile* sf = this->Makefile->GetSource(*it))
+ {
+ SourceFileFlags& flags = this->SourceFlagsMap[sf];
+ flags.MacFolder = "";
+ if(!this->Makefile->PlatformIsAppleIos())
+ {
+ flags.MacFolder = "Resources";
+ }
+ flags.Type = cmGeneratorTarget::SourceFileTypeResource;
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+const cmGeneratorTarget::CompatibleInterfacesBase&
+cmGeneratorTarget::GetCompatibleInterfaces(std::string const& config) const
+{
+ cmGeneratorTarget::CompatibleInterfaces& compat =
+ this->CompatibleInterfacesMap[config];
+ if(!compat.Done)
+ {
+ compat.Done = true;
+ compat.PropsBool.insert("POSITION_INDEPENDENT_CODE");
+ compat.PropsString.insert("AUTOUIC_OPTIONS");
+ std::vector<cmGeneratorTarget const*> const& deps =
+ this->GetLinkImplementationClosure(config);
+ for(std::vector<cmGeneratorTarget const*>::const_iterator li =
+ deps.begin(); li != deps.end(); ++li)
+ {
+#define CM_READ_COMPATIBLE_INTERFACE(X, x) \
+ if(const char* prop = (*li)->GetProperty("COMPATIBLE_INTERFACE_" #X)) \
+ { \
+ std::vector<std::string> props; \
+ cmSystemTools::ExpandListArgument(prop, props); \
+ compat.Props##x.insert(props.begin(), props.end()); \
+ }
+ CM_READ_COMPATIBLE_INTERFACE(BOOL, Bool)
+ CM_READ_COMPATIBLE_INTERFACE(STRING, String)
+ CM_READ_COMPATIBLE_INTERFACE(NUMBER_MIN, NumberMin)
+ CM_READ_COMPATIBLE_INTERFACE(NUMBER_MAX, NumberMax)
+#undef CM_READ_COMPATIBLE_INTERFACE
+ }
+ }
+ return compat;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsLinkInterfaceDependentBoolProperty(
+ const std::string &p, const std::string& config) const
+{
+ if (this->GetType() == cmState::OBJECT_LIBRARY
+ || this->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ return false;
+ }
+ return this->GetCompatibleInterfaces(config).PropsBool.count(p) > 0;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsLinkInterfaceDependentStringProperty(
+ const std::string &p, const std::string& config) const
+{
+ if (this->GetType() == cmState::OBJECT_LIBRARY
+ || this->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ return false;
+ }
+ return this->GetCompatibleInterfaces(config).PropsString.count(p) > 0;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsLinkInterfaceDependentNumberMinProperty(
+ const std::string &p, const std::string& config) const
+{
+ if (this->GetType() == cmState::OBJECT_LIBRARY
+ || this->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ return false;
+ }
+ return this->GetCompatibleInterfaces(config).PropsNumberMin.count(p) > 0;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsLinkInterfaceDependentNumberMaxProperty(
+ const std::string &p, const std::string& config) const
+{
+ if (this->GetType() == cmState::OBJECT_LIBRARY
+ || this->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ return false;
+ }
+ return this->GetCompatibleInterfaces(config).PropsNumberMax.count(p) > 0;
+}
+
+enum CompatibleType
+{
+ BoolType,
+ StringType,
+ NumberMinType,
+ NumberMaxType
+};
+
+template<typename PropertyType>
+PropertyType getLinkInterfaceDependentProperty(cmGeneratorTarget const* tgt,
+ const std::string& prop,
+ const std::string& config,
+ CompatibleType,
+ PropertyType *);
+
+template<>
+bool getLinkInterfaceDependentProperty(cmGeneratorTarget const* tgt,
+ const std::string& prop,
+ const std::string& config,
+ CompatibleType, bool *)
+{
+ return tgt->GetLinkInterfaceDependentBoolProperty(prop, config);
+}
+
+template<>
+const char * getLinkInterfaceDependentProperty(cmGeneratorTarget const* tgt,
+ const std::string& prop,
+ const std::string& config,
+ CompatibleType t,
+ const char **)
+{
+ switch(t)
+ {
+ case BoolType:
+ assert(0 && "String compatibility check function called for boolean");
+ return 0;
+ case StringType:
+ return tgt->GetLinkInterfaceDependentStringProperty(prop, config);
+ case NumberMinType:
+ return tgt->GetLinkInterfaceDependentNumberMinProperty(prop, config);
+ case NumberMaxType:
+ return tgt->GetLinkInterfaceDependentNumberMaxProperty(prop, config);
+ }
+ assert(0 && "Unreachable!");
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+template<typename PropertyType>
+void checkPropertyConsistency(cmGeneratorTarget const* depender,
+ cmGeneratorTarget const* dependee,
+ const std::string& propName,
+ std::set<std::string> &emitted,
+ const std::string& config,
+ CompatibleType t,
+ PropertyType *)
+{
+ const char *prop = dependee->GetProperty(propName);
+ if (!prop)
+ {
+ return;
+ }
+
+ std::vector<std::string> props;
+ cmSystemTools::ExpandListArgument(prop, props);
+ std::string pdir =
+ dependee->Target->GetMakefile()->GetRequiredDefinition("CMAKE_ROOT");
+ pdir += "/Help/prop_tgt/";
+
+ for(std::vector<std::string>::iterator pi = props.begin();
+ pi != props.end(); ++pi)
+ {
+ std::string pname = cmSystemTools::HelpFileName(*pi);
+ std::string pfile = pdir + pname + ".rst";
+ if(cmSystemTools::FileExists(pfile.c_str(), true))
+ {
+ std::ostringstream e;
+ e << "Target \"" << dependee->GetName() << "\" has property \""
+ << *pi << "\" listed in its " << propName << " property. "
+ "This is not allowed. Only user-defined properties may appear "
+ "listed in the " << propName << " property.";
+ depender->GetLocalGenerator()->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return;
+ }
+ if(emitted.insert(*pi).second)
+ {
+ getLinkInterfaceDependentProperty<PropertyType>(depender, *pi, config,
+ t, 0);
+ if (cmSystemTools::GetErrorOccuredFlag())
+ {
+ return;
+ }
+ }
+ }
+}
+
+static std::string intersect(const std::set<std::string> &s1,
+ const std::set<std::string> &s2)
+{
+ std::set<std::string> intersect;
+ std::set_intersection(s1.begin(),s1.end(),
+ s2.begin(),s2.end(),
+ std::inserter(intersect,intersect.begin()));
+ if (!intersect.empty())
+ {
+ return *intersect.begin();
+ }
+ return "";
+}
+
+static std::string intersect(const std::set<std::string> &s1,
+ const std::set<std::string> &s2,
+ const std::set<std::string> &s3)
+{
+ std::string result;
+ result = intersect(s1, s2);
+ if (!result.empty())
+ return result;
+ result = intersect(s1, s3);
+ if (!result.empty())
+ return result;
+ return intersect(s2, s3);
+}
+
+static std::string intersect(const std::set<std::string> &s1,
+ const std::set<std::string> &s2,
+ const std::set<std::string> &s3,
+ const std::set<std::string> &s4)
+{
+ std::string result;
+ result = intersect(s1, s2);
+ if (!result.empty())
+ return result;
+ result = intersect(s1, s3);
+ if (!result.empty())
+ return result;
+ result = intersect(s1, s4);
+ if (!result.empty())
+ return result;
+ return intersect(s2, s3, s4);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::CheckPropertyCompatibility(
+ cmComputeLinkInformation *info, const std::string& config) const
+{
+ const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
+
+ std::set<std::string> emittedBools;
+ static std::string strBool = "COMPATIBLE_INTERFACE_BOOL";
+ std::set<std::string> emittedStrings;
+ static std::string strString = "COMPATIBLE_INTERFACE_STRING";
+ std::set<std::string> emittedMinNumbers;
+ static std::string strNumMin = "COMPATIBLE_INTERFACE_NUMBER_MIN";
+ std::set<std::string> emittedMaxNumbers;
+ static std::string strNumMax = "COMPATIBLE_INTERFACE_NUMBER_MAX";
+
+ for(cmComputeLinkInformation::ItemVector::const_iterator li =
+ deps.begin(); li != deps.end(); ++li)
+ {
+ if (!li->Target)
+ {
+ continue;
+ }
+
+ checkPropertyConsistency<bool>(this, li->Target,
+ strBool,
+ emittedBools, config, BoolType, 0);
+ if (cmSystemTools::GetErrorOccuredFlag())
+ {
+ return;
+ }
+ checkPropertyConsistency<const char *>(this, li->Target,
+ strString,
+ emittedStrings, config,
+ StringType, 0);
+ if (cmSystemTools::GetErrorOccuredFlag())
+ {
+ return;
+ }
+ checkPropertyConsistency<const char *>(this, li->Target,
+ strNumMin,
+ emittedMinNumbers, config,
+ NumberMinType, 0);
+ if (cmSystemTools::GetErrorOccuredFlag())
+ {
+ return;
+ }
+ checkPropertyConsistency<const char *>(this, li->Target,
+ strNumMax,
+ emittedMaxNumbers, config,
+ NumberMaxType, 0);
+ if (cmSystemTools::GetErrorOccuredFlag())
+ {
+ return;
+ }
+ }
+
+ std::string prop = intersect(emittedBools,
+ emittedStrings,
+ emittedMinNumbers,
+ emittedMaxNumbers);
+
+ if (!prop.empty())
+ {
+ // Use a sorted std::vector to keep the error message sorted.
+ std::vector<std::string> props;
+ std::set<std::string>::const_iterator i = emittedBools.find(prop);
+ if (i != emittedBools.end())
+ {
+ props.push_back(strBool);
+ }
+ i = emittedStrings.find(prop);
+ if (i != emittedStrings.end())
+ {
+ props.push_back(strString);
+ }
+ i = emittedMinNumbers.find(prop);
+ if (i != emittedMinNumbers.end())
+ {
+ props.push_back(strNumMin);
+ }
+ i = emittedMaxNumbers.find(prop);
+ if (i != emittedMaxNumbers.end())
+ {
+ props.push_back(strNumMax);
+ }
+ std::sort(props.begin(), props.end());
+
+ std::string propsString = cmJoin(cmMakeRange(props).retreat(1), ", ");
+ propsString += " and the " + props.back();
+
+ std::ostringstream e;
+ e << "Property \"" << prop << "\" appears in both the "
+ << propsString <<
+ " property in the dependencies of target \"" << this->GetName() <<
+ "\". This is not allowed. A property may only require compatibility "
+ "in a boolean interpretation, a numeric minimum, a numeric maximum or a "
+ "string interpretation, but not a mixture.";
+ this->LocalGenerator->IssueMessage(cmake::FATAL_ERROR, e.str());
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string compatibilityType(CompatibleType t)
+{
+ switch(t)
+ {
+ case BoolType:
+ return "Boolean compatibility";
+ case StringType:
+ return "String compatibility";
+ case NumberMaxType:
+ return "Numeric maximum compatibility";
+ case NumberMinType:
+ return "Numeric minimum compatibility";
+ }
+ assert(0 && "Unreachable!");
+ return "";
+}
+
+//----------------------------------------------------------------------------
+std::string compatibilityAgree(CompatibleType t, bool dominant)
+{
+ switch(t)
+ {
+ case BoolType:
+ case StringType:
+ return dominant ? "(Disagree)\n" : "(Agree)\n";
+ case NumberMaxType:
+ case NumberMinType:
+ return dominant ? "(Dominant)\n" : "(Ignored)\n";
+ }
+ assert(0 && "Unreachable!");
+ return "";
+}
+
+//----------------------------------------------------------------------------
+template<typename PropertyType>
+PropertyType getTypedProperty(cmGeneratorTarget const* tgt,
+ const std::string& prop);
+
+//----------------------------------------------------------------------------
+template<>
+bool getTypedProperty<bool>(cmGeneratorTarget const* tgt,
+ const std::string& prop)
+{
+ return tgt->GetPropertyAsBool(prop);
+}
+
+//----------------------------------------------------------------------------
+template<>
+const char *getTypedProperty<const char *>(cmGeneratorTarget const* tgt,
+ const std::string& prop)
+{
+ return tgt->GetProperty(prop);
+}
+
+template<typename PropertyType>
+std::string valueAsString(PropertyType);
+template<>
+std::string valueAsString<bool>(bool value)
+{
+ return value ? "TRUE" : "FALSE";
+}
+template<>
+std::string valueAsString<const char*>(const char* value)
+{
+ return value ? value : "(unset)";
+}
+
+template<typename PropertyType>
+PropertyType impliedValue(PropertyType);
+template<>
+bool impliedValue<bool>(bool)
+{
+ return false;
+}
+template<>
+const char* impliedValue<const char*>(const char*)
+{
+ return "";
+}
+
+//----------------------------------------------------------------------------
+template<typename PropertyType>
+std::pair<bool, PropertyType> consistentProperty(PropertyType lhs,
+ PropertyType rhs,
+ CompatibleType t);
+
+//----------------------------------------------------------------------------
+template<>
+std::pair<bool, bool> consistentProperty(bool lhs, bool rhs,
+ CompatibleType)
+{
+ return std::make_pair(lhs == rhs, lhs);
+}
+
+//----------------------------------------------------------------------------
+std::pair<bool, const char*> consistentStringProperty(const char *lhs,
+ const char *rhs)
+{
+ const bool b = strcmp(lhs, rhs) == 0;
+ return std::make_pair(b, b ? lhs : 0);
+}
+
+//----------------------------------------------------------------------------
+std::pair<bool, const char*> consistentNumberProperty(const char *lhs,
+ const char *rhs,
+ CompatibleType t)
+{
+ char *pEnd;
+
+ const char* const null_ptr = 0;
+
+ long lnum = strtol(lhs, &pEnd, 0);
+ if (pEnd == lhs || *pEnd != '\0' || errno == ERANGE)
+ {
+ return std::pair<bool, const char*>(false, null_ptr);
+ }
+
+ long rnum = strtol(rhs, &pEnd, 0);
+ if (pEnd == rhs || *pEnd != '\0' || errno == ERANGE)
+ {
+ return std::pair<bool, const char*>(false, null_ptr);
+ }
+
+ if (t == NumberMaxType)
+ {
+ return std::make_pair(true, std::max(lnum, rnum) == lnum ? lhs : rhs);
+ }
+ else
+ {
+ return std::make_pair(true, std::min(lnum, rnum) == lnum ? lhs : rhs);
+ }
+}
+
+//----------------------------------------------------------------------------
+template<>
+std::pair<bool, const char*> consistentProperty(const char *lhs,
+ const char *rhs,
+ CompatibleType t)
+{
+ if (!lhs && !rhs)
+ {
+ return std::make_pair(true, lhs);
+ }
+ if (!lhs)
+ {
+ return std::make_pair(true, rhs);
+ }
+ if (!rhs)
+ {
+ return std::make_pair(true, lhs);
+ }
+
+ const char* const null_ptr = 0;
+
+ switch(t)
+ {
+ case BoolType:
+ assert(0 && "consistentProperty for strings called with BoolType");
+ return std::pair<bool, const char*>(false, null_ptr);
+ case StringType:
+ return consistentStringProperty(lhs, rhs);
+ case NumberMinType:
+ case NumberMaxType:
+ return consistentNumberProperty(lhs, rhs, t);
+ }
+ assert(0 && "Unreachable!");
+ return std::pair<bool, const char*>(false, null_ptr);
+}
+
+//----------------------------------------------------------------------------
+template<typename PropertyType>
+PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt,
+ const std::string &p,
+ const std::string& config,
+ const char *defaultValue,
+ CompatibleType t,
+ PropertyType *)
+{
+ PropertyType propContent = getTypedProperty<PropertyType>(tgt, p);
+ std::vector<std::string> headPropKeys = tgt->GetPropertyKeys();
+ const bool explicitlySet =
+ std::find(headPropKeys.begin(), headPropKeys.end(),
+ p) != headPropKeys.end();
+
+ const bool impliedByUse =
+ tgt->IsNullImpliedByLinkLibraries(p);
+ assert((impliedByUse ^ explicitlySet)
+ || (!impliedByUse && !explicitlySet));
+
+ std::vector<cmGeneratorTarget const*> const& deps =
+ tgt->GetLinkImplementationClosure(config);
+
+ if(deps.empty())
+ {
+ return propContent;
+ }
+ bool propInitialized = explicitlySet;
+
+ std::string report = " * Target \"";
+ report += tgt->GetName();
+ if (explicitlySet)
+ {
+ report += "\" has property content \"";
+ report += valueAsString<PropertyType>(propContent);
+ report += "\"\n";
+ }
+ else if (impliedByUse)
+ {
+ report += "\" property is implied by use.\n";
+ }
+ else
+ {
+ report += "\" property not set.\n";
+ }
+
+ std::string interfaceProperty = "INTERFACE_" + p;
+ for(std::vector<cmGeneratorTarget const*>::const_iterator li =
+ deps.begin();
+ li != deps.end(); ++li)
+ {
+ // An error should be reported if one dependency
+ // has INTERFACE_POSITION_INDEPENDENT_CODE ON and the other
+ // has INTERFACE_POSITION_INDEPENDENT_CODE OFF, or if the
+ // target itself has a POSITION_INDEPENDENT_CODE which disagrees
+ // with a dependency.
+
+ cmGeneratorTarget const* theTarget = *li;
+
+ std::vector<std::string> propKeys = theTarget->GetPropertyKeys();
+
+ const bool ifaceIsSet =
+ std::find(propKeys.begin(), propKeys.end(),
+ interfaceProperty) != propKeys.end();
+ PropertyType ifacePropContent =
+ getTypedProperty<PropertyType>(theTarget,
+ interfaceProperty);
+
+ std::string reportEntry;
+ if (ifaceIsSet)
+ {
+ reportEntry += " * Target \"";
+ reportEntry += theTarget->GetName();
+ reportEntry += "\" property value \"";
+ reportEntry += valueAsString<PropertyType>(ifacePropContent);
+ reportEntry += "\" ";
+ }
+
+ if (explicitlySet)
+ {
+ if (ifaceIsSet)
+ {
+ std::pair<bool, PropertyType> consistent =
+ consistentProperty(propContent,
+ ifacePropContent, t);
+ report += reportEntry;
+ report += compatibilityAgree(t, propContent != consistent.second);
+ if (!consistent.first)
+ {
+ std::ostringstream e;
+ e << "Property " << p << " on target \""
+ << tgt->GetName() << "\" does\nnot match the "
+ "INTERFACE_" << p << " property requirement\nof "
+ "dependency \"" << theTarget->GetName() << "\".\n";
+ cmSystemTools::Error(e.str().c_str());
+ break;
+ }
+ else
+ {
+ propContent = consistent.second;
+ continue;
+ }
+ }
+ else
+ {
+ // Explicitly set on target and not set in iface. Can't disagree.
+ continue;
+ }
+ }
+ else if (impliedByUse)
+ {
+ propContent = impliedValue<PropertyType>(propContent);
+
+ if (ifaceIsSet)
+ {
+ std::pair<bool, PropertyType> consistent =
+ consistentProperty(propContent,
+ ifacePropContent, t);
+ report += reportEntry;
+ report += compatibilityAgree(t, propContent != consistent.second);
+ if (!consistent.first)
+ {
+ std::ostringstream e;
+ e << "Property " << p << " on target \""
+ << tgt->GetName() << "\" is\nimplied to be " << defaultValue
+ << " because it was used to determine the link libraries\n"
+ "already. The INTERFACE_" << p << " property on\ndependency \""
+ << theTarget->GetName() << "\" is in conflict.\n";
+ cmSystemTools::Error(e.str().c_str());
+ break;
+ }
+ else
+ {
+ propContent = consistent.second;
+ continue;
+ }
+ }
+ else
+ {
+ // Implicitly set on target and not set in iface. Can't disagree.
+ continue;
+ }
+ }
+ else
+ {
+ if (ifaceIsSet)
+ {
+ if (propInitialized)
+ {
+ std::pair<bool, PropertyType> consistent =
+ consistentProperty(propContent,
+ ifacePropContent, t);
+ report += reportEntry;
+ report += compatibilityAgree(t, propContent != consistent.second);
+ if (!consistent.first)
+ {
+ std::ostringstream e;
+ e << "The INTERFACE_" << p << " property of \""
+ << theTarget->GetName() << "\" does\nnot agree with the value "
+ "of " << p << " already determined\nfor \""
+ << tgt->GetName() << "\".\n";
+ cmSystemTools::Error(e.str().c_str());
+ break;
+ }
+ else
+ {
+ propContent = consistent.second;
+ continue;
+ }
+ }
+ else
+ {
+ report += reportEntry + "(Interface set)\n";
+ propContent = ifacePropContent;
+ propInitialized = true;
+ }
+ }
+ else
+ {
+ // Not set. Nothing to agree on.
+ continue;
+ }
+ }
+ }
+
+ tgt->ReportPropertyOrigin(p, valueAsString<PropertyType>(propContent),
+ report, compatibilityType(t));
+ return propContent;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::GetLinkInterfaceDependentBoolProperty(
+ const std::string &p, const std::string& config) const
+{
+ return checkInterfacePropertyCompatibility<bool>(this, p, config,
+ "FALSE",
+ BoolType, 0);
+}
+
+//----------------------------------------------------------------------------
+const char* cmGeneratorTarget::GetLinkInterfaceDependentStringProperty(
+ const std::string &p,
+ const std::string& config) const
+{
+ return checkInterfacePropertyCompatibility<const char *>(this,
+ p,
+ config,
+ "empty",
+ StringType, 0);
+}
+
+//----------------------------------------------------------------------------
+const char * cmGeneratorTarget::GetLinkInterfaceDependentNumberMinProperty(
+ const std::string &p,
+ const std::string& config) const
+{
+ return checkInterfacePropertyCompatibility<const char *>(this,
+ p,
+ config,
+ "empty",
+ NumberMinType, 0);
+}
+
+//----------------------------------------------------------------------------
+const char * cmGeneratorTarget::GetLinkInterfaceDependentNumberMaxProperty(
+ const std::string &p,
+ const std::string& config) const
+{
+ return checkInterfacePropertyCompatibility<const char *>(this,
+ p,
+ config,
+ "empty",
+ NumberMaxType, 0);
+}
+
+//----------------------------------------------------------------------------
+cmComputeLinkInformation*
+cmGeneratorTarget::GetLinkInformation(const std::string& config) const
+{
+ // Lookup any existing information for this configuration.
+ std::string key(cmSystemTools::UpperCase(config));
+ cmTargetLinkInformationMap::iterator
+ i = this->LinkInformation.find(key);
+ if(i == this->LinkInformation.end())
+ {
+ // Compute information for this configuration.
+ cmComputeLinkInformation* info =
+ new cmComputeLinkInformation(this, config);
+ if(!info || !info->Compute())
+ {
+ delete info;
+ info = 0;
+ }
+
+ // Store the information for this configuration.
+ cmTargetLinkInformationMap::value_type entry(key, info);
+ i = this->LinkInformation.insert(entry).first;
+
+ if (info)
+ {
+ this->CheckPropertyCompatibility(info, config);
+ }
+ }
+ return i->second;
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetTargetVersion(int& major, int& minor) const
+{
+ int patch;
+ this->GetTargetVersion(false, major, minor, patch);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetTargetVersion(bool soversion,
+ int& major, int& minor, int& patch) const
+{
+ // Set the default values.
+ major = 0;
+ minor = 0;
+ patch = 0;
+
+ assert(this->GetType() != cmState::INTERFACE_LIBRARY);
+
+ // Look for a VERSION or SOVERSION property.
+ const char* prop = soversion? "SOVERSION" : "VERSION";
+ if(const char* version = this->GetProperty(prop))
+ {
+ // Try to parse the version number and store the results that were
+ // successfully parsed.
+ int parsed_major;
+ int parsed_minor;
+ int parsed_patch;
+ switch(sscanf(version, "%d.%d.%d",
+ &parsed_major, &parsed_minor, &parsed_patch))
+ {
+ case 3: patch = parsed_patch; // no break!
+ case 2: minor = parsed_minor; // no break!
+ case 1: major = parsed_major; // no break!
+ default: break;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetFrameworkVersion() const
+{
+ assert(this->GetType() != cmState::INTERFACE_LIBRARY);
+
+ if(const char* fversion = this->GetProperty("FRAMEWORK_VERSION"))
+ {
+ return fversion;
+ }
+ else if(const char* tversion = this->GetProperty("VERSION"))
+ {
+ return tversion;
+ }
+ else
+ {
+ return "A";
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::ComputeVersionedName(std::string& vName,
+ std::string const& prefix,
+ std::string const& base,
+ std::string const& suffix,
+ std::string const& name,
+ const char* version) const
+{
+ vName = this->Makefile->IsOn("APPLE") ? (prefix+base) : name;
+ if(version)
+ {
+ vName += ".";
+ vName += version;
+ }
+ vName += this->Makefile->IsOn("APPLE") ? suffix : std::string();
+}
+
+std::vector<std::string> cmGeneratorTarget::GetPropertyKeys() const
+{
+ cmPropertyMap propsObject = this->Target->GetProperties();
+ std::vector<std::string> props;
+ props.reserve(propsObject.size());
+ for (cmPropertyMap::const_iterator it = propsObject.begin();
+ it != propsObject.end(); ++it)
+ {
+ props.push_back(it->first);
+ }
+ return props;
+}
+
+//----------------------------------------------------------------------------
+void
+cmGeneratorTarget::ReportPropertyOrigin(const std::string &p,
+ const std::string &result,
+ const std::string &report,
+ const std::string &compatibilityType) const
+{
+ std::vector<std::string> debugProperties;
+ const char *debugProp = this->Target->GetMakefile()
+ ->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+ if (debugProp)
+ {
+ cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+ }
+
+ bool debugOrigin = !this->DebugCompatiblePropertiesDone[p]
+ && std::find(debugProperties.begin(),
+ debugProperties.end(),
+ p)
+ != debugProperties.end();
+
+ if (this->GlobalGenerator->GetConfigureDoneCMP0026())
+ {
+ this->DebugCompatiblePropertiesDone[p] = true;
+ }
+ if (!debugOrigin)
+ {
+ return;
+ }
+
+ std::string areport = compatibilityType;
+ areport += std::string(" of property \"") + p + "\" for target \"";
+ areport += std::string(this->GetName());
+ areport += "\" (result: \"";
+ areport += result;
+ areport += "\"):\n" + report;
+
+ this->LocalGenerator->GetCMakeInstance()->IssueMessage(cmake::LOG, areport);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::LookupLinkItems(std::vector<std::string> const& names,
+ std::vector<cmLinkItem>& items) const
+{
+ for(std::vector<std::string>::const_iterator i = names.begin();
+ i != names.end(); ++i)
+ {
+ std::string name = this->CheckCMP0004(*i);
+ if(name == this->GetName() || name.empty())
+ {
+ continue;
+ }
+ items.push_back(cmLinkItem(name, this->FindTargetToLink(name)));
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::ExpandLinkItems(std::string const& prop,
+ std::string const& value,
+ std::string const& config,
+ cmGeneratorTarget const* headTarget,
+ bool usage_requirements_only,
+ std::vector<cmLinkItem>& items,
+ bool& hadHeadSensitiveCondition) const
+{
+ cmGeneratorExpression ge;
+ cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), prop, 0, 0);
+ // The $<LINK_ONLY> expression may be in a link interface to specify private
+ // link dependencies that are otherwise excluded from usage requirements.
+ if(usage_requirements_only)
+ {
+ dagChecker.SetTransitivePropertiesOnly();
+ }
+ std::vector<std::string> libs;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
+ cmSystemTools::ExpandListArgument(cge->Evaluate(
+ this->LocalGenerator,
+ config,
+ false,
+ headTarget,
+ this, &dagChecker), libs);
+ this->LookupLinkItems(libs, items);
+ hadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition();
+}
+
+//----------------------------------------------------------------------------
+cmLinkInterface const*
+cmGeneratorTarget::GetLinkInterface(const std::string& config,
+ cmGeneratorTarget const* head) const
+{
+ // Imported targets have their own link interface.
+ if(this->IsImported())
+ {
+ return this->GetImportLinkInterface(config, head, false);
+ }
+
+ // Link interfaces are not supported for executables that do not
+ // export symbols.
+ if(this->GetType() == cmState::EXECUTABLE &&
+ !this->IsExecutableWithExports())
+ {
+ return 0;
+ }
+
+ // Lookup any existing link interface for this configuration.
+ cmHeadToLinkInterfaceMap& hm =
+ this->GetHeadToLinkInterfaceMap(config);
+
+ // If the link interface does not depend on the head target
+ // then return the one we computed first.
+ if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
+ {
+ return &hm.begin()->second;
+ }
+
+ cmOptionalLinkInterface& iface = hm[head];
+ if(!iface.LibrariesDone)
+ {
+ iface.LibrariesDone = true;
+ this->ComputeLinkInterfaceLibraries(
+ config, iface, head, false);
+ }
+ if(!iface.AllDone)
+ {
+ iface.AllDone = true;
+ if(iface.Exists)
+ {
+ this->ComputeLinkInterface(config, iface, head);
+ }
+ }
+
+ return iface.Exists? &iface : 0;
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::ComputeLinkInterface(const std::string& config,
+ cmOptionalLinkInterface &iface,
+ cmGeneratorTarget const* headTarget) const
+{
+ if(iface.ExplicitLibraries)
+ {
+ if(this->GetType() == cmState::SHARED_LIBRARY
+ || this->GetType() == cmState::STATIC_LIBRARY
+ || this->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ // Shared libraries may have runtime implementation dependencies
+ // on other shared libraries that are not in the interface.
+ UNORDERED_SET<std::string> emitted;
+ for(std::vector<cmLinkItem>::const_iterator
+ li = iface.Libraries.begin(); li != iface.Libraries.end(); ++li)
+ {
+ emitted.insert(*li);
+ }
+ if (this->GetType() != cmState::INTERFACE_LIBRARY)
+ {
+ cmLinkImplementation const* impl =
+ this->GetLinkImplementation(config);
+ for(std::vector<cmLinkImplItem>::const_iterator
+ li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
+ {
+ if(emitted.insert(*li).second)
+ {
+ if(li->Target)
+ {
+ // This is a runtime dependency on another shared library.
+ if(li->Target->GetType() == cmState::SHARED_LIBRARY)
+ {
+ iface.SharedDeps.push_back(*li);
+ }
+ }
+ else
+ {
+ // TODO: Recognize shared library file names. Perhaps this
+ // should be moved to cmComputeLinkInformation, but that creates
+ // a chicken-and-egg problem since this list is needed for its
+ // construction.
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (this->GetPolicyStatusCMP0022() == cmPolicies::WARN
+ || this->GetPolicyStatusCMP0022() == cmPolicies::OLD)
+ {
+ // The link implementation is the default link interface.
+ cmLinkImplementationLibraries const*
+ impl = this->GetLinkImplementationLibrariesInternal(config,
+ headTarget);
+ iface.ImplementationIsInterface = true;
+ iface.WrongConfigLibraries = impl->WrongConfigLibraries;
+ }
+
+ if(this->LinkLanguagePropagatesToDependents())
+ {
+ // Targets using this archive need its language runtime libraries.
+ if(cmLinkImplementation const* impl =
+ this->GetLinkImplementation(config))
+ {
+ iface.Languages = impl->Languages;
+ }
+ }
+
+ if(this->GetType() == cmState::STATIC_LIBRARY)
+ {
+ // Construct the property name suffix for this configuration.
+ std::string suffix = "_";
+ if(!config.empty())
+ {
+ suffix += cmSystemTools::UpperCase(config);
+ }
+ else
+ {
+ suffix += "NOCONFIG";
+ }
+
+ // How many repetitions are needed if this library has cyclic
+ // dependencies?
+ std::string propName = "LINK_INTERFACE_MULTIPLICITY";
+ propName += suffix;
+ if(const char* config_reps = this->GetProperty(propName))
+ {
+ sscanf(config_reps, "%u", &iface.Multiplicity);
+ }
+ else if(const char* reps =
+ this->GetProperty("LINK_INTERFACE_MULTIPLICITY"))
+ {
+ sscanf(reps, "%u", &iface.Multiplicity);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+const cmLinkInterfaceLibraries *
+cmGeneratorTarget::GetLinkInterfaceLibraries(const std::string& config,
+ cmGeneratorTarget const* head,
+ bool usage_requirements_only) const
+{
+ // Imported targets have their own link interface.
+ if(this->IsImported())
+ {
+ return this->GetImportLinkInterface(config, head,
+ usage_requirements_only);
+ }
+
+ // Link interfaces are not supported for executables that do not
+ // export symbols.
+ if(this->GetType() == cmState::EXECUTABLE &&
+ !this->IsExecutableWithExports())
+ {
+ return 0;
+ }
+
+ // Lookup any existing link interface for this configuration.
+ std::string CONFIG = cmSystemTools::UpperCase(config);
+ cmHeadToLinkInterfaceMap& hm =
+ (usage_requirements_only ?
+ this->GetHeadToLinkInterfaceUsageRequirementsMap(config) :
+ this->GetHeadToLinkInterfaceMap(config));
+
+ // If the link interface does not depend on the head target
+ // then return the one we computed first.
+ if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
+ {
+ return &hm.begin()->second;
+ }
+
+ cmOptionalLinkInterface& iface = hm[head];
+ if(!iface.LibrariesDone)
+ {
+ iface.LibrariesDone = true;
+ this->ComputeLinkInterfaceLibraries(
+ config, iface, head, usage_requirements_only);
+ }
+
+ return iface.Exists? &iface : 0;
+}
+
+//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetDirectory(const std::string& config,
+ bool implib) const
+{
+ if (this->IsImported())
+ {
+ // Return the directory from which the target is imported.
+ return
+ cmSystemTools::GetFilenamePath(
+ this->Target->ImportedGetFullPath(config, implib));
+ }
+ else if(OutputInfo const* info = this->GetOutputInfo(config))
+ {
+ // Return the directory in which the target will be built.
+ return implib? info->ImpDir : info->OutDir;
+ }
+ return "";
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::UsesDefaultOutputDir(const std::string& config,
+ bool implib) const
+{
+ std::string dir;
+ return this->ComputeOutputDir(config, implib, dir);
+}
+
+//----------------------------------------------------------------------------
+cmGeneratorTarget::OutputInfo const* cmGeneratorTarget::GetOutputInfo(
+ const std::string& config) const
+{
+ // There is no output information for imported targets.
+ if(this->IsImported())
+ {
+ return 0;
+ }
+
+ // Only libraries and executables have well-defined output files.
+ if(!this->HaveWellDefinedOutputFiles())
+ {
+ std::string msg = "cmGeneratorTarget::GetOutputInfo called for ";
+ msg += this->GetName();
+ msg += " which has type ";
+ msg += cmState::GetTargetTypeName(this->GetType());
+ this->LocalGenerator->IssueMessage(cmake::INTERNAL_ERROR, msg);
+ return 0;
+ }
+
+ // Lookup/compute/cache the output information for this configuration.
+ std::string config_upper;
+ if(!config.empty())
+ {
+ config_upper = cmSystemTools::UpperCase(config);
+ }
+ OutputInfoMapType::iterator i =
+ this->OutputInfoMap.find(config_upper);
+ if(i == this->OutputInfoMap.end())
+ {
+ // Add empty info in map to detect potential recursion.
+ OutputInfo info;
+ OutputInfoMapType::value_type entry(config_upper, info);
+ i = this->OutputInfoMap.insert(entry).first;
+
+ // Compute output directories.
+ this->ComputeOutputDir(config, false, info.OutDir);
+ this->ComputeOutputDir(config, true, info.ImpDir);
+ if(!this->ComputePDBOutputDir("PDB", config, info.PdbDir))
+ {
+ info.PdbDir = info.OutDir;
+ }
+
+ // Now update the previously-prepared map entry.
+ i->second = info;
+ }
+ else if(i->second.empty())
+ {
+ // An empty map entry indicates we have been called recursively
+ // from the above block.
+ this->LocalGenerator->GetCMakeInstance()->IssueMessage(
+ cmake::FATAL_ERROR,
+ "Target '" + this->GetName() + "' OUTPUT_DIRECTORY depends on itself.",
+ this->GetBacktrace());
+ return 0;
+ }
+ return &i->second;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::ComputeOutputDir(const std::string& config,
+ bool implib, std::string& out) const
+{
+ bool usesDefaultOutputDir = false;
+ std::string conf = config;
+
+ // Look for a target property defining the target output directory
+ // based on the target type.
+ std::string targetTypeName = this->GetOutputTargetType(implib);
+ const char* propertyName = 0;
+ std::string propertyNameStr = targetTypeName;
+ if(!propertyNameStr.empty())
+ {
+ propertyNameStr += "_OUTPUT_DIRECTORY";
+ propertyName = propertyNameStr.c_str();
+ }
+
+ // Check for a per-configuration output directory target property.
+ std::string configUpper = cmSystemTools::UpperCase(conf);
+ const char* configProp = 0;
+ std::string configPropStr = targetTypeName;
+ if(!configPropStr.empty())
+ {
+ configPropStr += "_OUTPUT_DIRECTORY_";
+ configPropStr += configUpper;
+ configProp = configPropStr.c_str();
+ }
+
+ // Select an output directory.
+ if(const char* config_outdir = this->GetProperty(configProp))
+ {
+ // Use the user-specified per-configuration output directory.
+ cmGeneratorExpression ge;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(config_outdir);
+ out = cge->Evaluate(this->LocalGenerator, config);
+
+ // Skip per-configuration subdirectory.
+ conf = "";
+ }
+ else if(const char* outdir = this->GetProperty(propertyName))
+ {
+ // Use the user-specified output directory.
+ cmGeneratorExpression ge;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(outdir);
+ out = cge->Evaluate(this->LocalGenerator, config);
+
+ // Skip per-configuration subdirectory if the value contained a
+ // generator expression.
+ if (out != outdir)
+ {
+ conf = "";
+ }
+ }
+ else if(this->GetType() == cmState::EXECUTABLE)
+ {
+ // Lookup the output path for executables.
+ out = this->Makefile->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH");
+ }
+ else if(this->GetType() == cmState::STATIC_LIBRARY ||
+ this->GetType() == cmState::SHARED_LIBRARY ||
+ this->GetType() == cmState::MODULE_LIBRARY)
+ {
+ // Lookup the output path for libraries.
+ out = this->Makefile->GetSafeDefinition("LIBRARY_OUTPUT_PATH");
+ }
+ if(out.empty())
+ {
+ // Default to the current output directory.
+ usesDefaultOutputDir = true;
+ out = ".";
+ }
+
+ // Convert the output path to a full path in case it is
+ // specified as a relative path. Treat a relative path as
+ // relative to the current output directory for this makefile.
+ out = (cmSystemTools::CollapseFullPath
+ (out, this->LocalGenerator->GetCurrentBinaryDirectory()));
+
+ // The generator may add the configuration's subdirectory.
+ if(!conf.empty())
+ {
+ bool iosPlatform = this->Makefile->PlatformIsAppleIos();
+ std::string suffix =
+ usesDefaultOutputDir && iosPlatform ? "${EFFECTIVE_PLATFORM_NAME}" : "";
+ this->LocalGenerator->GetGlobalGenerator()->
+ AppendDirectoryForConfig("/", conf, suffix, out);
+ }
+
+ return usesDefaultOutputDir;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::ComputePDBOutputDir(const std::string& kind,
+ const std::string& config,
+ std::string& out) const
+{
+ // Look for a target property defining the target output directory
+ // based on the target type.
+ const char* propertyName = 0;
+ std::string propertyNameStr = kind;
+ if(!propertyNameStr.empty())
+ {
+ propertyNameStr += "_OUTPUT_DIRECTORY";
+ propertyName = propertyNameStr.c_str();
+ }
+ std::string conf = config;
+
+ // Check for a per-configuration output directory target property.
+ std::string configUpper = cmSystemTools::UpperCase(conf);
+ const char* configProp = 0;
+ std::string configPropStr = kind;
+ if(!configPropStr.empty())
+ {
+ configPropStr += "_OUTPUT_DIRECTORY_";
+ configPropStr += configUpper;
+ configProp = configPropStr.c_str();
+ }
+
+ // Select an output directory.
+ if(const char* config_outdir = this->GetProperty(configProp))
+ {
+ // Use the user-specified per-configuration output directory.
+ out = config_outdir;
+
+ // Skip per-configuration subdirectory.
+ conf = "";
+ }
+ else if(const char* outdir = this->GetProperty(propertyName))
+ {
+ // Use the user-specified output directory.
+ out = outdir;
+ }
+ if(out.empty())
+ {
+ return false;
+ }
+
+ // Convert the output path to a full path in case it is
+ // specified as a relative path. Treat a relative path as
+ // relative to the current output directory for this makefile.
+ out = (cmSystemTools::CollapseFullPath
+ (out, this->LocalGenerator->GetCurrentBinaryDirectory()));
+
+ // The generator may add the configuration's subdirectory.
+ if(!conf.empty())
+ {
+ this->LocalGenerator->GetGlobalGenerator()->
+ AppendDirectoryForConfig("/", conf, "", out);
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::HaveInstallTreeRPATH() const
+{
+ const char* install_rpath = this->GetProperty("INSTALL_RPATH");
+ return (install_rpath && *install_rpath) &&
+ !this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH");
+}
+
+//----------------------------------------------------------------------------
+void
+cmGeneratorTarget::ComputeLinkInterfaceLibraries(
+ const std::string& config,
+ cmOptionalLinkInterface& iface,
+ cmGeneratorTarget const* headTarget,
+ bool usage_requirements_only) const
+{
+ // Construct the property name suffix for this configuration.
+ std::string suffix = "_";
+ if(!config.empty())
+ {
+ suffix += cmSystemTools::UpperCase(config);
+ }
+ else
+ {
+ suffix += "NOCONFIG";
+ }
+
+ // An explicit list of interface libraries may be set for shared
+ // libraries and executables that export symbols.
+ const char* explicitLibraries = 0;
+ std::string linkIfaceProp;
+ if(this->GetPolicyStatusCMP0022() != cmPolicies::OLD &&
+ this->GetPolicyStatusCMP0022() != cmPolicies::WARN)
+ {
+ // CMP0022 NEW behavior is to use INTERFACE_LINK_LIBRARIES.
+ linkIfaceProp = "INTERFACE_LINK_LIBRARIES";
+ explicitLibraries = this->GetProperty(linkIfaceProp);
+ }
+ else if(this->GetType() == cmState::SHARED_LIBRARY ||
+ this->IsExecutableWithExports())
+ {
+ // CMP0022 OLD behavior is to use LINK_INTERFACE_LIBRARIES if set on a
+ // shared lib or executable.
+
+ // Lookup the per-configuration property.
+ linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
+ linkIfaceProp += suffix;
+ explicitLibraries = this->GetProperty(linkIfaceProp);
+
+ // If not set, try the generic property.
+ if(!explicitLibraries)
+ {
+ linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
+ explicitLibraries = this->GetProperty(linkIfaceProp);
+ }
+ }
+
+ if(explicitLibraries &&
+ this->GetPolicyStatusCMP0022() == cmPolicies::WARN &&
+ !this->PolicyWarnedCMP0022)
+ {
+ // Compare the explicitly set old link interface properties to the
+ // preferred new link interface property one and warn if different.
+ const char* newExplicitLibraries =
+ this->GetProperty("INTERFACE_LINK_LIBRARIES");
+ if (newExplicitLibraries
+ && strcmp(newExplicitLibraries, explicitLibraries) != 0)
+ {
+ std::ostringstream w;
+ w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n"
+ "Target \"" << this->GetName() << "\" has an "
+ "INTERFACE_LINK_LIBRARIES property which differs from its " <<
+ linkIfaceProp << " properties."
+ "\n"
+ "INTERFACE_LINK_LIBRARIES:\n"
+ " " << newExplicitLibraries << "\n" <<
+ linkIfaceProp << ":\n"
+ " " << (explicitLibraries ? explicitLibraries : "(empty)") << "\n";
+ this->LocalGenerator->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ this->PolicyWarnedCMP0022 = true;
+ }
+ }
+
+ // There is no implicit link interface for executables or modules
+ // so if none was explicitly set then there is no link interface.
+ if(!explicitLibraries &&
+ (this->GetType() == cmState::EXECUTABLE ||
+ (this->GetType() == cmState::MODULE_LIBRARY)))
+ {
+ return;
+ }
+ iface.Exists = true;
+ iface.ExplicitLibraries = explicitLibraries;
+
+ if(explicitLibraries)
+ {
+ // The interface libraries have been explicitly set.
+ this->ExpandLinkItems(linkIfaceProp, explicitLibraries,
+ config,
+ headTarget, usage_requirements_only,
+ iface.Libraries,
+ iface.HadHeadSensitiveCondition);
+ }
+ else if (this->GetPolicyStatusCMP0022() == cmPolicies::WARN
+ || this->GetPolicyStatusCMP0022() == cmPolicies::OLD)
+ // If CMP0022 is NEW then the plain tll signature sets the
+ // INTERFACE_LINK_LIBRARIES, so if we get here then the project
+ // cleared the property explicitly and we should not fall back
+ // to the link implementation.
+ {
+ // The link implementation is the default link interface.
+ cmLinkImplementationLibraries const* impl =
+ this->GetLinkImplementationLibrariesInternal(config, headTarget);
+ iface.Libraries.insert(iface.Libraries.end(),
+ impl->Libraries.begin(), impl->Libraries.end());
+ if(this->GetPolicyStatusCMP0022() == cmPolicies::WARN &&
+ !this->PolicyWarnedCMP0022 && !usage_requirements_only)
+ {
+ // Compare the link implementation fallback link interface to the
+ // preferred new link interface property and warn if different.
+ std::vector<cmLinkItem> ifaceLibs;
+ static const std::string newProp = "INTERFACE_LINK_LIBRARIES";
+ if(const char* newExplicitLibraries = this->GetProperty(newProp))
+ {
+ bool hadHeadSensitiveConditionDummy = false;
+ this->ExpandLinkItems(newProp, newExplicitLibraries, config,
+ headTarget,
+ usage_requirements_only,
+ ifaceLibs, hadHeadSensitiveConditionDummy);
+ }
+ if (ifaceLibs != iface.Libraries)
+ {
+ std::string oldLibraries = cmJoin(impl->Libraries, ";");
+ std::string newLibraries = cmJoin(ifaceLibs, ";");
+ if(oldLibraries.empty())
+ { oldLibraries = "(empty)"; }
+ if(newLibraries.empty())
+ { newLibraries = "(empty)"; }
+
+ std::ostringstream w;
+ w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n"
+ "Target \"" << this->GetName() << "\" has an "
+ "INTERFACE_LINK_LIBRARIES property. "
+ "This should be preferred as the source of the link interface "
+ "for this library but because CMP0022 is not set CMake is "
+ "ignoring the property and using the link implementation "
+ "as the link interface instead."
+ "\n"
+ "INTERFACE_LINK_LIBRARIES:\n"
+ " " << newLibraries << "\n"
+ "Link implementation:\n"
+ " " << oldLibraries << "\n";
+ this->LocalGenerator->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ this->PolicyWarnedCMP0022 = true;
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+const cmLinkInterface *
+cmGeneratorTarget::GetImportLinkInterface(const std::string& config,
+ cmGeneratorTarget const* headTarget,
+ bool usage_requirements_only) const
+{
+ cmGeneratorTarget::ImportInfo const* info = this->GetImportInfo(config);
+ if(!info)
+ {
+ return 0;
+ }
+
+ std::string CONFIG = cmSystemTools::UpperCase(config);
+ cmHeadToLinkInterfaceMap& hm =
+ (usage_requirements_only ?
+ this->GetHeadToLinkInterfaceUsageRequirementsMap(config) :
+ this->GetHeadToLinkInterfaceMap(config));
+
+ // If the link interface does not depend on the head target
+ // then return the one we computed first.
+ if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
+ {
+ return &hm.begin()->second;
+ }
+
+ cmOptionalLinkInterface& iface = hm[headTarget];
+ if(!iface.AllDone)
+ {
+ iface.AllDone = true;
+ iface.Multiplicity = info->Multiplicity;
+ cmSystemTools::ExpandListArgument(info->Languages, iface.Languages);
+ this->ExpandLinkItems(info->LibrariesProp, info->Libraries,
+ config,
+ headTarget, usage_requirements_only,
+ iface.Libraries,
+ iface.HadHeadSensitiveCondition);
+ std::vector<std::string> deps;
+ cmSystemTools::ExpandListArgument(info->SharedDeps, deps);
+ this->LookupLinkItems(deps, iface.SharedDeps);
+ }
+
+ return &iface;
+}
+
+//----------------------------------------------------------------------------
+cmGeneratorTarget::ImportInfo const*
+cmGeneratorTarget::GetImportInfo(const std::string& config) const
+{
+ // There is no imported information for non-imported targets.
+ if(!this->IsImported())
+ {
+ return 0;
+ }
+
+ // Lookup/compute/cache the import information for this
+ // configuration.
+ std::string config_upper;
+ if(!config.empty())
+ {
+ config_upper = cmSystemTools::UpperCase(config);
+ }
+ else
+ {
+ config_upper = "NOCONFIG";
+ }
+
+ ImportInfoMapType::const_iterator i =
+ this->ImportInfoMap.find(config_upper);
+ if(i == this->ImportInfoMap.end())
+ {
+ ImportInfo info;
+ this->ComputeImportInfo(config_upper, info);
+ ImportInfoMapType::value_type entry(config_upper, info);
+ i = this->ImportInfoMap.insert(entry).first;
+ }
+
+ if(this->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ return &i->second;
+ }
+ // If the location is empty then the target is not available for
+ // this configuration.
+ if(i->second.Location.empty() && i->second.ImportLibrary.empty())
+ {
+ return 0;
+ }
+
+ // Return the import information.
+ return &i->second;
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
+ ImportInfo& info) const
+{
+ // This method finds information about an imported target from its
+ // properties. The "IMPORTED_" namespace is reserved for properties
+ // defined by the project exporting the target.
+
+ // Initialize members.
+ info.NoSOName = false;
+
+ const char* loc = 0;
+ const char* imp = 0;
+ std::string suffix;
+ if (!this->Target->GetMappedConfig(desired_config, &loc, &imp, suffix))
+ {
+ return;
+ }
+
+ // Get the link interface.
+ {
+ std::string linkProp = "INTERFACE_LINK_LIBRARIES";
+ const char *propertyLibs = this->GetProperty(linkProp);
+
+ if (this->GetType() != cmState::INTERFACE_LIBRARY)
+ {
+ if(!propertyLibs)
+ {
+ linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES";
+ linkProp += suffix;
+ propertyLibs = this->GetProperty(linkProp);
+ }
+
+ if(!propertyLibs)
+ {
+ linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES";
+ propertyLibs = this->GetProperty(linkProp);
+ }
+ }
+ if(propertyLibs)
+ {
+ info.LibrariesProp = linkProp;
+ info.Libraries = propertyLibs;
+ }
+ }
+ if(this->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ return;
+ }
+
+ // A provided configuration has been chosen. Load the
+ // configuration's properties.
+
+ // Get the location.
+ if(loc)
+ {
+ info.Location = loc;
+ }
+ else
+ {
+ std::string impProp = "IMPORTED_LOCATION";
+ impProp += suffix;
+ if(const char* config_location = this->GetProperty(impProp))
+ {
+ info.Location = config_location;
+ }
+ else if(const char* location = this->GetProperty("IMPORTED_LOCATION"))
+ {
+ info.Location = location;
+ }
+ }
+
+ // Get the soname.
+ if(this->GetType() == cmState::SHARED_LIBRARY)
+ {
+ std::string soProp = "IMPORTED_SONAME";
+ soProp += suffix;
+ if(const char* config_soname = this->GetProperty(soProp))
+ {
+ info.SOName = config_soname;
+ }
+ else if(const char* soname = this->GetProperty("IMPORTED_SONAME"))
+ {
+ info.SOName = soname;
+ }
+ }
+
+ // Get the "no-soname" mark.
+ if(this->GetType() == cmState::SHARED_LIBRARY)
+ {
+ std::string soProp = "IMPORTED_NO_SONAME";
+ soProp += suffix;
+ if(const char* config_no_soname = this->GetProperty(soProp))
+ {
+ info.NoSOName = cmSystemTools::IsOn(config_no_soname);
+ }
+ else if(const char* no_soname = this->GetProperty("IMPORTED_NO_SONAME"))
+ {
+ info.NoSOName = cmSystemTools::IsOn(no_soname);
+ }
+ }
+
+ // Get the import library.
+ if(imp)
+ {
+ info.ImportLibrary = imp;
+ }
+ else if(this->GetType() == cmState::SHARED_LIBRARY ||
+ this->IsExecutableWithExports())
+ {
+ std::string impProp = "IMPORTED_IMPLIB";
+ impProp += suffix;
+ if(const char* config_implib = this->GetProperty(impProp))
+ {
+ info.ImportLibrary = config_implib;
+ }
+ else if(const char* implib = this->GetProperty("IMPORTED_IMPLIB"))
+ {
+ info.ImportLibrary = implib;
+ }
+ }
+
+ // Get the link dependencies.
+ {
+ std::string linkProp = "IMPORTED_LINK_DEPENDENT_LIBRARIES";
+ linkProp += suffix;
+ if(const char* config_libs = this->GetProperty(linkProp))
+ {
+ info.SharedDeps = config_libs;
+ }
+ else if(const char* libs =
+ this->GetProperty("IMPORTED_LINK_DEPENDENT_LIBRARIES"))
+ {
+ info.SharedDeps = libs;
+ }
+ }
+
+ // Get the link languages.
+ if(this->LinkLanguagePropagatesToDependents())
+ {
+ std::string linkProp = "IMPORTED_LINK_INTERFACE_LANGUAGES";
+ linkProp += suffix;
+ if(const char* config_libs = this->GetProperty(linkProp))
+ {
+ info.Languages = config_libs;
+ }
+ else if(const char* libs =
+ this->GetProperty("IMPORTED_LINK_INTERFACE_LANGUAGES"))
+ {
+ info.Languages = libs;
+ }
+ }
+
+ // Get the cyclic repetition count.
+ if(this->GetType() == cmState::STATIC_LIBRARY)
+ {
+ std::string linkProp = "IMPORTED_LINK_INTERFACE_MULTIPLICITY";
+ linkProp += suffix;
+ if(const char* config_reps = this->GetProperty(linkProp))
+ {
+ sscanf(config_reps, "%u", &info.Multiplicity);
+ }
+ else if(const char* reps =
+ this->GetProperty("IMPORTED_LINK_INTERFACE_MULTIPLICITY"))
+ {
+ sscanf(reps, "%u", &info.Multiplicity);
+ }
+ }
+}
+
+cmHeadToLinkInterfaceMap&
+cmGeneratorTarget::GetHeadToLinkInterfaceMap(const std::string &config) const
+{
+ std::string CONFIG = cmSystemTools::UpperCase(config);
+ return this->LinkInterfaceMap[CONFIG];
+}
+
+cmHeadToLinkInterfaceMap&
+cmGeneratorTarget::GetHeadToLinkInterfaceUsageRequirementsMap(
+ const std::string &config) const
+{
+ std::string CONFIG = cmSystemTools::UpperCase(config);
+ return this->LinkInterfaceUsageRequirementsOnlyMap[CONFIG];
+}
+
+//----------------------------------------------------------------------------
+const cmLinkImplementation *
+cmGeneratorTarget::GetLinkImplementation(const std::string& config) const
+{
+ // There is no link implementation for imported targets.
+ if(this->IsImported())
+ {
+ return 0;
+ }
+
+ std::string CONFIG = cmSystemTools::UpperCase(config);
+ cmOptionalLinkImplementation& impl = this->LinkImplMap[CONFIG][this];
+ if(!impl.LibrariesDone)
+ {
+ impl.LibrariesDone = true;
+ this->ComputeLinkImplementationLibraries(config, impl, this);
+ }
+ if(!impl.LanguagesDone)
+ {
+ impl.LanguagesDone = true;
+ this->ComputeLinkImplementationLanguages(config, impl);
+ }
+ return &impl;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::GetConfigCommonSourceFiles(
+ std::vector<cmSourceFile*>& files) const
+{
+ std::vector<std::string> configs;
+ this->Makefile->GetConfigurations(configs);
+ if (configs.empty())
+ {
+ configs.push_back("");
+ }
+
+ std::vector<std::string>::const_iterator it = configs.begin();
+ const std::string& firstConfig = *it;
+ this->GetSourceFiles(files, firstConfig);
+
+ for ( ; it != configs.end(); ++it)
+ {
+ std::vector<cmSourceFile*> configFiles;
+ this->GetSourceFiles(configFiles, *it);
+ if (configFiles != files)
+ {
+ std::string firstConfigFiles;
+ const char* sep = "";
+ for (std::vector<cmSourceFile*>::const_iterator fi = files.begin();
+ fi != files.end(); ++fi)
+ {
+ firstConfigFiles += sep;
+ firstConfigFiles += (*fi)->GetFullPath();
+ sep = "\n ";
+ }
+
+ std::string thisConfigFiles;
+ sep = "";
+ for (std::vector<cmSourceFile*>::const_iterator fi = configFiles.begin();
+ fi != configFiles.end(); ++fi)
+ {
+ thisConfigFiles += sep;
+ thisConfigFiles += (*fi)->GetFullPath();
+ sep = "\n ";
+ }
+ std::ostringstream e;
+ e << "Target \"" << this->GetName()
+ << "\" has source files which vary by "
+ "configuration. This is not supported by the \""
+ << this->GlobalGenerator->GetName()
+ << "\" generator.\n"
+ "Config \"" << firstConfig << "\":\n"
+ " " << firstConfigFiles << "\n"
+ "Config \"" << *it << "\":\n"
+ " " << thisConfigFiles << "\n";
+ this->LocalGenerator->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetObjectLibrariesCMP0026(
+ std::vector<cmGeneratorTarget*>& objlibs) const
+{
+ // At configure-time, this method can be called as part of getting the
+ // LOCATION property or to export() a file to be include()d. However
+ // there is no cmGeneratorTarget at configure-time, so search the SOURCES
+ // for TARGET_OBJECTS instead for backwards compatibility with OLD
+ // behavior of CMP0024 and CMP0026 only.
+ cmStringRange rng = this->Target->GetSourceEntries();
+ for(std::vector<std::string>::const_iterator
+ i = rng.begin(); i != rng.end(); ++i)
+ {
+ std::string const& entry = *i;
+
+ std::vector<std::string> files;
+ cmSystemTools::ExpandListArgument(entry, files);
+ for (std::vector<std::string>::const_iterator
+ li = files.begin(); li != files.end(); ++li)
+ {
+ if(cmHasLiteralPrefix(*li, "$<TARGET_OBJECTS:") &&
+ (*li)[li->size() - 1] == '>')
+ {
+ std::string objLibName = li->substr(17, li->size()-18);
+
+ if (cmGeneratorExpression::Find(objLibName) != std::string::npos)
+ {
+ continue;
+ }
+ cmGeneratorTarget *objLib =
+ this->LocalGenerator->FindGeneratorTargetToUse(objLibName);
+ if(objLib)
+ {
+ objlibs.push_back(objLib);
+ }
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::CheckCMP0004(std::string const& item) const
+{
+ // Strip whitespace off the library names because we used to do this
+ // in case variables were expanded at generate time. We no longer
+ // do the expansion but users link to libraries like " ${VAR} ".
+ std::string lib = item;
+ std::string::size_type pos = lib.find_first_not_of(" \t\r\n");
+ if(pos != lib.npos)
+ {
+ lib = lib.substr(pos, lib.npos);
+ }
+ pos = lib.find_last_not_of(" \t\r\n");
+ if(pos != lib.npos)
+ {
+ lib = lib.substr(0, pos+1);
+ }
+ if(lib != item)
+ {
+ cmake* cm = this->LocalGenerator->GetCMakeInstance();
+ switch(this->GetPolicyStatusCMP0004())
+ {
+ case cmPolicies::WARN:
+ {
+ std::ostringstream w;
+ w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0004) << "\n"
+ << "Target \"" << this->GetName() << "\" links to item \""
+ << item << "\" which has leading or trailing whitespace.";
+ cm->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
+ this->GetBacktrace());
+ }
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::NEW:
+ {
+ std::ostringstream e;
+ e << "Target \"" << this->GetName() << "\" links to item \""
+ << item << "\" which has leading or trailing whitespace. "
+ << "This is now an error according to policy CMP0004.";
+ cm->IssueMessage(cmake::FATAL_ERROR, e.str(),
+ this->GetBacktrace());
+ }
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ {
+ std::ostringstream e;
+ e << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0004) << "\n"
+ << "Target \"" << this->GetName() << "\" links to item \""
+ << item << "\" which has leading or trailing whitespace.";
+ cm->IssueMessage(cmake::FATAL_ERROR, e.str(),
+ this->GetBacktrace());
+ }
+ break;
+ }
+ }
+ return lib;
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetLanguages(std::set<std::string>& languages,
+ const std::string& config) const
+{
+ std::vector<cmSourceFile*> sourceFiles;
+ this->GetSourceFiles(sourceFiles, config);
+ for(std::vector<cmSourceFile*>::const_iterator
+ i = sourceFiles.begin(); i != sourceFiles.end(); ++i)
+ {
+ const std::string& lang = (*i)->GetLanguage();
+ if(!lang.empty())
+ {
+ languages.insert(lang);
+ }
+ }
+
+ std::vector<cmGeneratorTarget*> objectLibraries;
+ std::vector<cmSourceFile const*> externalObjects;
+ if (!this->GlobalGenerator->GetConfigureDoneCMP0026())
+ {
+ std::vector<cmGeneratorTarget*> objectTargets;
+ this->GetObjectLibrariesCMP0026(objectTargets);
+ objectLibraries.reserve(objectTargets.size());
+ for (std::vector<cmGeneratorTarget*>::const_iterator it =
+ objectTargets.begin(); it != objectTargets.end(); ++it)
+ {
+ objectLibraries.push_back(*it);
+ }
+ }
+ else
+ {
+ this->GetExternalObjects(externalObjects, config);
+ for(std::vector<cmSourceFile const*>::const_iterator
+ i = externalObjects.begin(); i != externalObjects.end(); ++i)
+ {
+ std::string objLib = (*i)->GetObjectLibrary();
+ if (cmGeneratorTarget* tgt =
+ this->LocalGenerator->FindGeneratorTargetToUse(objLib))
+ {
+ objectLibraries.push_back(tgt);
+ }
+ }
+ }
+ for(std::vector<cmGeneratorTarget*>::const_iterator
+ i = objectLibraries.begin(); i != objectLibraries.end(); ++i)
+ {
+ (*i)->GetLanguages(languages, config);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::ComputeLinkImplementationLanguages(
+ const std::string& config,
+ cmOptionalLinkImplementation& impl) const
+{
+ // This target needs runtime libraries for its source languages.
+ std::set<std::string> languages;
+ // Get languages used in our source files.
+ this->GetLanguages(languages, config);
+ // Copy the set of langauges to the link implementation.
+ impl.Languages.insert(impl.Languages.begin(),
+ languages.begin(), languages.end());
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::HaveBuildTreeRPATH(const std::string& config) const
+{
+ if (this->GetPropertyAsBool("SKIP_BUILD_RPATH"))
+ {
+ return false;
+ }
+ if(cmLinkImplementationLibraries const* impl =
+ this->GetLinkImplementationLibraries(config))
+ {
+ return !impl->Libraries.empty();
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+cmLinkImplementationLibraries const*
+cmGeneratorTarget::GetLinkImplementationLibraries(
+ const std::string& config) const
+{
+ return this->GetLinkImplementationLibrariesInternal(config, this);
+}
+
+//----------------------------------------------------------------------------
+cmLinkImplementationLibraries const*
+cmGeneratorTarget::GetLinkImplementationLibrariesInternal(
+ const std::string& config, cmGeneratorTarget const* head) const
+{
+ // There is no link implementation for imported targets.
+ if(this->IsImported())
+ {
+ return 0;
+ }
+
+ // Populate the link implementation libraries for this configuration.
+ std::string CONFIG = cmSystemTools::UpperCase(config);
+ HeadToLinkImplementationMap& hm =
+ this->LinkImplMap[CONFIG];
+
+ // If the link implementation does not depend on the head target
+ // then return the one we computed first.
+ if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
+ {
+ return &hm.begin()->second;
+ }
+
+ cmOptionalLinkImplementation& impl = hm[head];
+ if(!impl.LibrariesDone)
+ {
+ impl.LibrariesDone = true;
+ this->ComputeLinkImplementationLibraries(config, impl, head);
+ }
+ return &impl;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGeneratorTarget::IsNullImpliedByLinkLibraries(const std::string &p) const
+{
+ return this->LinkImplicitNullProperties.find(p)
+ != this->LinkImplicitNullProperties.end();
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::ComputeLinkImplementationLibraries(
+ const std::string& config,
+ cmOptionalLinkImplementation& impl,
+ cmGeneratorTarget const* head) const
+{
+ cmStringRange entryRange =
+ this->Target->GetLinkImplementationEntries();
+ cmBacktraceRange btRange =
+ this->Target->GetLinkImplementationBacktraces();
+ cmBacktraceRange::const_iterator btIt = btRange.begin();
+ // Collect libraries directly linked in this configuration.
+ for (cmStringRange::const_iterator le = entryRange.begin(),
+ end = entryRange.end(); le != end; ++le, ++btIt)
+ {
+ std::vector<std::string> llibs;
+ cmGeneratorExpressionDAGChecker dagChecker(
+ this->GetName(),
+ "LINK_LIBRARIES", 0, 0);
+ cmGeneratorExpression ge(*btIt);
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> const cge =
+ ge.Parse(*le);
+ std::string const evaluated =
+ cge->Evaluate(this->LocalGenerator, config, false, head, &dagChecker);
+ cmSystemTools::ExpandListArgument(evaluated, llibs);
+ if(cge->GetHadHeadSensitiveCondition())
+ {
+ impl.HadHeadSensitiveCondition = true;
+ }
+
+ for(std::vector<std::string>::const_iterator li = llibs.begin();
+ li != llibs.end(); ++li)
+ {
+ // Skip entries that resolve to the target itself or are empty.
+ std::string name = this->CheckCMP0004(*li);
+ if(name == this->GetName() || name.empty())
+ {
+ if(name == this->GetName())
+ {
+ bool noMessage = false;
+ cmake::MessageType messageType = cmake::FATAL_ERROR;
+ std::ostringstream e;
+ switch(this->GetPolicyStatusCMP0038())
+ {
+ case cmPolicies::WARN:
+ {
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0038) << "\n";
+ messageType = cmake::AUTHOR_WARNING;
+ }
+ break;
+ case cmPolicies::OLD:
+ noMessage = true;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ // Issue the fatal message.
+ break;
+ }
+
+ if(!noMessage)
+ {
+ e << "Target \"" << this->GetName() << "\" links to itself.";
+ this->LocalGenerator->GetCMakeInstance()->IssueMessage(
+ messageType, e.str(), this->GetBacktrace());
+ if (messageType == cmake::FATAL_ERROR)
+ {
+ return;
+ }
+ }
+ }
+ continue;
+ }
+
+ // The entry is meant for this configuration.
+ impl.Libraries.push_back(
+ cmLinkImplItem(name, this->FindTargetToLink(name),
+ *btIt, evaluated != *le));
+ }
+
+ std::set<std::string> const& seenProps = cge->GetSeenTargetProperties();
+ for (std::set<std::string>::const_iterator it = seenProps.begin();
+ it != seenProps.end(); ++it)
+ {
+ if (!this->GetProperty(*it))
+ {
+ this->LinkImplicitNullProperties.insert(*it);
+ }
+ }
+ cge->GetMaxLanguageStandard(this,
+ this->MaxLanguageStandards);
+ }
+
+ // Get the list of configurations considered to be DEBUG.
+ std::vector<std::string> debugConfigs =
+ this->Makefile->GetCMakeInstance()->GetDebugConfigs();
+
+ cmTargetLinkLibraryType linkType =
+ CMP0003_ComputeLinkType(config, debugConfigs);
+ cmTarget::LinkLibraryVectorType const& oldllibs =
+ this->Target->GetOriginalLinkLibraries();
+ for(cmTarget::LinkLibraryVectorType::const_iterator li = oldllibs.begin();
+ li != oldllibs.end(); ++li)
+ {
+ if(li->second != GENERAL_LibraryType && li->second != linkType)
+ {
+ std::string name = this->CheckCMP0004(li->first);
+ if(name == this->GetName() || name.empty())
+ {
+ continue;
+ }
+ // Support OLD behavior for CMP0003.
+ impl.WrongConfigLibraries.push_back(
+ cmLinkItem(name, this->FindTargetToLink(name)));
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+cmGeneratorTarget*
+cmGeneratorTarget::FindTargetToLink(std::string const& name) const
+{
+ cmGeneratorTarget* tgt =
+ this->LocalGenerator->FindGeneratorTargetToUse(name);
+
+ // Skip targets that will not really be linked. This is probably a
+ // name conflict between an external library and an executable
+ // within the project.
+ if(tgt && tgt->GetType() == cmState::EXECUTABLE &&
+ !tgt->IsExecutableWithExports())
+ {
+ tgt = 0;
+ }
+
+ if(tgt && tgt->GetType() == cmState::OBJECT_LIBRARY)
+ {
+ std::ostringstream e;
+ e << "Target \"" << this->GetName() << "\" links to "
+ "OBJECT library \"" << tgt->GetName() << "\" but this is not "
+ "allowed. "
+ "One may link only to STATIC or SHARED libraries, or to executables "
+ "with the ENABLE_EXPORTS property set.";
+ cmake* cm = this->LocalGenerator->GetCMakeInstance();
+ cm->IssueMessage(cmake::FATAL_ERROR, e.str(),
+ this->GetBacktrace());
+ tgt = 0;
+ }
+
+ return tgt;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::GetPDBDirectory(const std::string& config) const
+{
+ if(OutputInfo const* info = this->GetOutputInfo(config))
+ {
+ // Return the directory in which the target will be built.
+ return info->PdbDir;
+ }
+ return "";
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::HasImplibGNUtoMS() const
+{
+ return this->HasImportLibrary()
+ && this->GetPropertyAsBool("GNUtoMS");
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::GetImplibGNUtoMS(std::string const& gnuName,
+ std::string& out, const char* newExt) const
+{
+ if(this->HasImplibGNUtoMS() &&
+ gnuName.size() > 6 && gnuName.substr(gnuName.size()-6) == ".dll.a")
+ {
+ out = gnuName.substr(0, gnuName.size()-6);
+ out += newExt? newExt : ".lib";
+ return true;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsExecutableWithExports() const
+{
+ return (this->GetType() == cmState::EXECUTABLE &&
+ this->GetPropertyAsBool("ENABLE_EXPORTS"));
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::HasImportLibrary() const
+{
+ return (this->IsDLLPlatform() &&
+ (this->GetType() == cmState::SHARED_LIBRARY ||
+ this->IsExecutableWithExports()));
+}
+
+//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetSupportDirectory() const
+{
+ std::string dir = this->LocalGenerator->GetCurrentBinaryDirectory();
+ dir += cmake::GetCMakeFilesDirectory();
+ dir += "/";
+ dir += this->GetName();
+#if defined(__VMS)
+ dir += "_dir";
+#else
+ dir += ".dir";
+#endif
+ return dir;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsLinkable() const
+{
+ return (this->GetType() == cmState::STATIC_LIBRARY ||
+ this->GetType() == cmState::SHARED_LIBRARY ||
+ this->GetType() == cmState::MODULE_LIBRARY ||
+ this->GetType() == cmState::UNKNOWN_LIBRARY ||
+ this->GetType() == cmState::INTERFACE_LIBRARY ||
+ this->IsExecutableWithExports());
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsFrameworkOnApple() const
+{
+ return (this->GetType() == cmState::SHARED_LIBRARY &&
+ this->Makefile->IsOn("APPLE") &&
+ this->GetPropertyAsBool("FRAMEWORK"));
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsAppBundleOnApple() const
+{
+ return (this->GetType() == cmState::EXECUTABLE &&
+ this->Makefile->IsOn("APPLE") &&
+ this->GetPropertyAsBool("MACOSX_BUNDLE"));
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsXCTestOnApple() const
+{
+ return (this->IsCFBundleOnApple() &&
+ this->GetPropertyAsBool("XCTEST"));
+}
//----------------------------------------------------------------------------
-std::vector<std::string> cmGeneratorTarget::GetIncludeDirectories(
- const char *config)
+bool cmGeneratorTarget::IsCFBundleOnApple() const
{
- return this->Target->GetIncludeDirectories(config);
+ return (this->GetType() == cmState::MODULE_LIBRARY &&
+ this->Makefile->IsOn("APPLE") &&
+ this->GetPropertyAsBool("BUNDLE"));
}
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index dedfa60aa..d96a32c55 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -12,7 +12,7 @@
#ifndef cmGeneratorTarget_h
#define cmGeneratorTarget_h
-#include "cmStandardIncludes.h"
+#include "cmLinkItem.h"
class cmCustomCommand;
class cmGlobalGenerator;
@@ -20,70 +20,682 @@ class cmLocalGenerator;
class cmMakefile;
class cmSourceFile;
class cmTarget;
+class cmComputeLinkInformation;
class cmGeneratorTarget
{
public:
- cmGeneratorTarget(cmTarget*);
+ cmGeneratorTarget(cmTarget*, cmLocalGenerator* lg);
+ ~cmGeneratorTarget();
- int GetType() const;
- const char *GetName() const;
- const char *GetProperty(const char *prop);
- bool GetPropertyAsBool(const char *prop);
- std::vector<cmSourceFile*> const& GetSourceFiles();
+ cmLocalGenerator* GetLocalGenerator() const;
+
+ bool IsImported() const;
+ bool IsImportedGloballyVisible() const;
+ const char *GetLocation(const std::string& config) const;
+
+ std::vector<cmCustomCommand> const &GetPreBuildCommands() const;
+ std::vector<cmCustomCommand> const &GetPreLinkCommands() const;
+ std::vector<cmCustomCommand> const &GetPostBuildCommands() const;
+
+#define DECLARE_TARGET_POLICY(POLICY) \
+ cmPolicies::PolicyStatus GetPolicyStatus ## POLICY () const \
+ { return this->PolicyMap.Get(cmPolicies::POLICY); }
+
+ CM_FOR_EACH_TARGET_POLICY(DECLARE_TARGET_POLICY)
+
+#undef DECLARE_TARGET_POLICY
+
+ /** Get the location of the target in the build tree with a placeholder
+ referencing the configuration in the native build system. This
+ location is suitable for use as the LOCATION target property. */
+ const char* GetLocationForBuild() const;
+
+ cmComputeLinkInformation*
+ GetLinkInformation(const std::string& config) const;
+
+ cmState::TargetType GetType() const;
+ const std::string& GetName() const;
+ std::string GetExportName() const;
+
+ std::vector<std::string> GetPropertyKeys() const;
+ const char *GetProperty(const std::string& prop) const;
+ bool GetPropertyAsBool(const std::string& prop) const;
+ void GetSourceFiles(std::vector<cmSourceFile*>& files,
+ const std::string& config) const;
+
+ void GetObjectSources(std::vector<cmSourceFile const*> &,
+ const std::string& config) const;
+ const std::string& GetObjectName(cmSourceFile const* file);
+
+ bool HasExplicitObjectName(cmSourceFile const* file) const;
+ void AddExplicitObjectName(cmSourceFile const* sf);
+
+ void GetResxSources(std::vector<cmSourceFile const*>&,
+ const std::string& config) const;
+ void GetIDLSources(std::vector<cmSourceFile const*>&,
+ const std::string& config) const;
+ void GetExternalObjects(std::vector<cmSourceFile const*>&,
+ const std::string& config) const;
+ void GetHeaderSources(std::vector<cmSourceFile const*>&,
+ const std::string& config) const;
+ void GetExtraSources(std::vector<cmSourceFile const*>&,
+ const std::string& config) const;
+ void GetCustomCommands(std::vector<cmSourceFile const*>&,
+ const std::string& config) const;
+ void GetExpectedResxHeaders(std::set<std::string>&,
+ const std::string& config) const;
+ void GetAppManifest(std::vector<cmSourceFile const*>&,
+ const std::string& config) const;
+ void GetManifests(std::vector<cmSourceFile const*>&,
+ const std::string& config) const;
+ void GetCertificates(std::vector<cmSourceFile const*>&,
+ const std::string& config) const;
+ void GetXamlSources(std::vector<cmSourceFile const*>&,
+ const std::string& config) const;
+ void GetExpectedXamlHeaders(std::set<std::string>&,
+ const std::string& config) const;
+ void GetExpectedXamlSources(std::set<std::string>&,
+ const std::string& config) const;
+
+ std::set<cmLinkItem>const& GetUtilityItems() const;
+
+ void ComputeObjectMapping();
+
+ const char* GetFeature(const std::string& feature,
+ const std::string& config) const;
+ bool GetFeatureAsBool(const std::string& feature,
+ const std::string& config) const;
+
+ bool IsLinkInterfaceDependentBoolProperty(const std::string &p,
+ const std::string& config) const;
+ bool IsLinkInterfaceDependentStringProperty(const std::string &p,
+ const std::string& config) const;
+ bool IsLinkInterfaceDependentNumberMinProperty(const std::string &p,
+ const std::string& config) const;
+ bool IsLinkInterfaceDependentNumberMaxProperty(const std::string &p,
+ const std::string& config) const;
+
+ bool GetLinkInterfaceDependentBoolProperty(const std::string &p,
+ const std::string& config) const;
+
+ const char *GetLinkInterfaceDependentStringProperty(const std::string &p,
+ const std::string& config) const;
+ const char *GetLinkInterfaceDependentNumberMinProperty(const std::string &p,
+ const std::string& config) const;
+ const char *GetLinkInterfaceDependentNumberMaxProperty(const std::string &p,
+ const std::string& config) const;
+
+ cmLinkInterface const* GetLinkInterface(const std::string& config,
+ const cmGeneratorTarget* headTarget) const;
+ void ComputeLinkInterface(const std::string& config,
+ cmOptionalLinkInterface& iface,
+ const cmGeneratorTarget* head) const;
+
+ cmLinkInterfaceLibraries const*
+ GetLinkInterfaceLibraries(const std::string& config,
+ const cmGeneratorTarget* headTarget,
+ bool usage_requirements_only) const;
+
+ void ComputeLinkInterfaceLibraries(const std::string& config,
+ cmOptionalLinkInterface &iface,
+ const cmGeneratorTarget* head,
+ bool usage_requirements_only) const;
+
+ /** Get the full path to the target according to the settings in its
+ makefile and the configuration type. */
+ std::string GetFullPath(const std::string& config="", bool implib = false,
+ bool realname = false) const;
+ std::string NormalGetFullPath(const std::string& config, bool implib,
+ bool realname) const;
+ std::string NormalGetRealName(const std::string& config) const;
+
+ /** @return the Mac App directory without the base */
+ std::string GetAppBundleDirectory(const std::string& config,
+ bool contentOnly) const;
+
+ /** Return whether this target is an executable Bundle, a framework
+ or CFBundle on Apple. */
+ bool IsBundleOnApple() const;
+
+ /** Get the full name of the target according to the settings in its
+ makefile. */
+ std::string GetFullName(const std::string& config="",
+ bool implib = false) const;
+
+ /** @return the Mac framework directory without the base. */
+ std::string GetFrameworkDirectory(const std::string& config,
+ bool rootDir) const;
+
+ /** Return the framework version string. Undefined if
+ IsFrameworkOnApple returns false. */
+ std::string GetFrameworkVersion() const;
+
+ /** @return the Mac CFBundle directory without the base */
+ std::string GetCFBundleDirectory(const std::string& config,
+ bool contentOnly) const;
+
+ /** Return the install name directory for the target in the
+ * build tree. For example: "\@rpath/", "\@loader_path/",
+ * or "/full/path/to/library". */
+ std::string GetInstallNameDirForBuildTree(const std::string& config) const;
+
+ /** Return the install name directory for the target in the
+ * install tree. For example: "\@rpath/" or "\@loader_path/". */
+ std::string GetInstallNameDirForInstallTree() const;
+
+ cmListFileBacktrace GetBacktrace() const;
+
+ const std::vector<std::string>& GetLinkDirectories() const;
+
+ std::set<std::string>const& GetUtilities() const;
+ cmListFileBacktrace const* GetUtilityBacktrace(const std::string& u) const;
+
+ bool LinkLanguagePropagatesToDependents() const
+ { return this->GetType() == cmState::STATIC_LIBRARY; }
+
+ /** Get the macro to define when building sources in this target.
+ If no macro should be defined null is returned. */
+ const char* GetExportMacro() const;
+
+ /** Get the soname of the target. Allowed only for a shared library. */
+ std::string GetSOName(const std::string& config) const;
+
+ void GetFullNameComponents(std::string& prefix,
+ std::string& base, std::string& suffix,
+ const std::string& config="",
+ bool implib = false) const;
+
+ /** Append to @a base the mac content directory and return it. */
+ std::string BuildMacContentDirectory(const std::string& base,
+ const std::string& config = "",
+ bool contentOnly = true) const;
+
+ /** @return the mac content directory for this target. */
+ std::string GetMacContentDirectory(const std::string& config = 0,
+ bool implib = false) const;
cmTarget* Target;
cmMakefile* Makefile;
cmLocalGenerator* LocalGenerator;
- cmGlobalGenerator* GlobalGenerator;
+ cmGlobalGenerator const* GlobalGenerator;
- /** Sources classified by purpose. */
- std::vector<cmSourceFile*> CustomCommands;
- std::vector<cmSourceFile*> ExtraSources;
- std::vector<cmSourceFile*> HeaderSources;
- std::vector<cmSourceFile*> ObjectSources;
- std::vector<cmSourceFile*> ExternalObjects;
- std::vector<cmSourceFile*> IDLSources;
- std::vector<cmSourceFile*> ResxSources;
+ cmSourceFile const* GetModuleDefinitionFile(const std::string& config) const;
- std::string ModuleDefinitionFile;
+ /** Return whether or not the target is for a DLL platform. */
+ bool IsDLLPlatform() const;
- std::map<cmSourceFile const*, std::string> Objects;
- std::set<cmSourceFile const*> ExplicitObjectName;
+ /** @return whether this target have a well defined output file name. */
+ bool HaveWellDefinedOutputFiles() const;
+
+ /** Link information from the transitive closure of the link
+ implementation and the interfaces of its dependencies. */
+ struct LinkClosure
+ {
+ // The preferred linker language.
+ std::string LinkerLanguage;
+
+ // Languages whose runtime libraries must be linked.
+ std::vector<std::string> Languages;
+ };
+
+ LinkClosure const* GetLinkClosure(const std::string& config) const;
+ void ComputeLinkClosure(const std::string& config, LinkClosure& lc) const;
+
+ cmLinkImplementation const*
+ GetLinkImplementation(const std::string& config) const;
+
+ void ComputeLinkImplementationLanguages(const std::string& config,
+ cmOptionalLinkImplementation& impl
+ ) const;
+
+ cmLinkImplementationLibraries const*
+ GetLinkImplementationLibraries(const std::string& config) const;
+
+ void ComputeLinkImplementationLibraries(const std::string& config,
+ cmOptionalLinkImplementation& impl,
+ const cmGeneratorTarget* head) const;
+
+ cmGeneratorTarget* FindTargetToLink(std::string const& name) const;
+
+ // Compute the set of languages compiled by the target. This is
+ // computed every time it is called because the languages can change
+ // when source file properties are changed and we do not have enough
+ // information to forward these property changes to the targets
+ // until we have per-target object file properties.
+ void GetLanguages(std::set<std::string>& languages,
+ std::string const& config) const;
+
+ void
+ GetObjectLibrariesCMP0026(std::vector<cmGeneratorTarget*>& objlibs) const;
+
+ std::string GetFullNameImported(const std::string& config,
+ bool implib) const;
- std::set<std::string> ExpectedResxHeaders;
+ bool GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const;
+
+ bool HaveBuildTreeRPATH(const std::string& config) const;
/** Full path with trailing slash to the top-level directory
holding object files for this target. Includes the build
time config name placeholder if needed for the generator. */
std::string ObjectDirectory;
- std::vector<cmTarget*> ObjectLibraries;
-
- void UseObjectLibraries(std::vector<std::string>& objs);
+ void UseObjectLibraries(std::vector<std::string>& objs,
+ const std::string& config) const;
- void GetAppleArchs(const char* config,
- std::vector<std::string>& archVec);
+ void GetAppleArchs(const std::string& config,
+ std::vector<std::string>& archVec) const;
- ///! Return the rule variable used to create this type of target,
- // need to add CMAKE_(LANG) for full name.
- const char* GetCreateRuleVariable();
+ /** Return the rule variable used to create this type of target. */
+ std::string GetCreateRuleVariable(std::string const& lang,
+ std::string const& config) const;
/** Get the include directories for this target. */
- std::vector<std::string> GetIncludeDirectories(const char *config);
+ std::vector<std::string> GetIncludeDirectories(
+ const std::string& config, const std::string& lang) const;
+
+ void GetCompileOptions(std::vector<std::string> &result,
+ const std::string& config,
+ const std::string& language) const;
+
+ void GetCompileFeatures(std::vector<std::string> &features,
+ const std::string& config) const;
+
+ void GetCompileDefinitions(std::vector<std::string> &result,
+ const std::string& config,
+ const std::string& language) const;
+
+ bool IsSystemIncludeDirectory(const std::string& dir,
+ const std::string& config) const;
+
+ /** Add the target output files to the global generator manifest. */
+ void ComputeTargetManifest(const std::string& config) const;
+
+ /**
+ * Trace through the source files in this target and add al source files
+ * that they depend on, used by all generators
+ */
+ void TraceDependencies();
+
+ /** Get the directory in which this target will be built. If the
+ configuration name is given then the generator will add its
+ subdirectory for that configuration. Otherwise just the canonical
+ output directory is given. */
+ std::string GetDirectory(const std::string& config = "",
+ bool implib = false) const;
+
+ /** Get the directory in which to place the target compiler .pdb file.
+ If the configuration name is given then the generator will add its
+ subdirectory for that configuration. Otherwise just the canonical
+ compiler pdb output directory is given. */
+ std::string GetCompilePDBDirectory(const std::string& config = "") const;
+
+ /** Get sources that must be built before the given source. */
+ std::vector<cmSourceFile*> const*
+ GetSourceDepends(cmSourceFile const* sf) const;
+
+ /** Return whether this target uses the default value for its output
+ directory. */
+ bool UsesDefaultOutputDir(const std::string& config, bool implib) const;
+
+ // Cache target output paths for each configuration.
+ struct OutputInfo
+ {
+ std::string OutDir;
+ std::string ImpDir;
+ std::string PdbDir;
+ bool empty() const
+ { return OutDir.empty() && ImpDir.empty() && PdbDir.empty(); }
+ };
+
+ OutputInfo const* GetOutputInfo(const std::string& config) const;
+
+ /** Get the name of the pdb file for the target. */
+ std::string GetPDBName(const std::string& config="") const;
+
+ /** Whether this library has soname enabled and platform supports it. */
+ bool HasSOName(const std::string& config) const;
+
+ struct CompileInfo
+ {
+ std::string CompilePdbDir;
+ };
- bool IsSystemIncludeDirectory(const char *dir, const char *config);
+ CompileInfo const* GetCompileInfo(const std::string& config) const;
+
+ typedef std::map<std::string, CompileInfo> CompileInfoMapType;
+ mutable CompileInfoMapType CompileInfoMap;
+
+ bool IsNullImpliedByLinkLibraries(const std::string &p) const;
+
+ /** Get the name of the compiler pdb file for the target. */
+ std::string GetCompilePDBName(const std::string& config="") const;
+
+ /** Get the path for the MSVC /Fd option for this target. */
+ std::string GetCompilePDBPath(const std::string& config="") const;
+
+ // Get the target base name.
+ std::string GetOutputName(const std::string& config, bool implib) const;
+
+ void AddSource(const std::string& src);
+ void AddTracedSources(std::vector<std::string> const& srcs);
+
+ /**
+ * Flags for a given source file as used in this target. Typically assigned
+ * via SET_TARGET_PROPERTIES when the property is a list of source files.
+ */
+ enum SourceFileType
+ {
+ SourceFileTypeNormal,
+ SourceFileTypePrivateHeader, // is in "PRIVATE_HEADER" target property
+ SourceFileTypePublicHeader, // is in "PUBLIC_HEADER" target property
+ SourceFileTypeResource, // is in "RESOURCE" target property *or*
+ // has MACOSX_PACKAGE_LOCATION=="Resources"
+ SourceFileTypeMacContent // has MACOSX_PACKAGE_LOCATION!="Resources"
+ };
+ struct SourceFileFlags
+ {
+ SourceFileFlags(): Type(SourceFileTypeNormal), MacFolder(0) {}
+ SourceFileFlags(SourceFileFlags const& r):
+ Type(r.Type), MacFolder(r.MacFolder) {}
+ SourceFileType Type;
+ const char* MacFolder; // location inside Mac content folders
+ };
+ void GetAutoUicOptions(std::vector<std::string> &result,
+ const std::string& config) const;
+
+ /** Get the names of the executable needed to generate a build rule
+ that takes into account executable version numbers. This should
+ be called only on an executable target. */
+ void GetExecutableNames(std::string& name, std::string& realName,
+ std::string& impName, std::string& pdbName,
+ const std::string& config) const;
+
+ /** Get the names of the library needed to generate a build rule
+ that takes into account shared library version numbers. This
+ should be called only on a library target. */
+ void GetLibraryNames(std::string& name, std::string& soName,
+ std::string& realName, std::string& impName,
+ std::string& pdbName, const std::string& config) const;
+
+ /**
+ * Compute whether this target must be relinked before installing.
+ */
+ bool NeedRelinkBeforeInstall(const std::string& config) const;
+
+ /** Return true if builtin chrpath will work for this target */
+ bool IsChrpathUsed(const std::string& config) const;
+
+ /** Get the directory in which this targets .pdb files will be placed.
+ If the configuration name is given then the generator will add its
+ subdirectory for that configuration. Otherwise just the canonical
+ pdb output directory is given. */
+ std::string GetPDBDirectory(const std::string& config) const;
+
+ ///! Return the preferred linker language for this target
+ std::string GetLinkerLanguage(const std::string& config = "") const;
+
+ /** Does this target have a GNU implib to convert to MS format? */
+ bool HasImplibGNUtoMS() const;
+
+ /** Convert the given GNU import library name (.dll.a) to a name with a new
+ extension (.lib or ${CMAKE_IMPORT_LIBRARY_SUFFIX}). */
+ bool GetImplibGNUtoMS(std::string const& gnuName, std::string& out,
+ const char* newExt = 0) const;
+
+ bool IsExecutableWithExports() const;
+
+ /** Return whether or not the target has a DLL import library. */
+ bool HasImportLibrary() const;
+
+ /** Get a build-tree directory in which to place target support files. */
+ std::string GetSupportDirectory() const;
+
+ /** Return whether this target may be used to link another target. */
+ bool IsLinkable() const;
+
+ /** Return whether this target is a shared library Framework on
+ Apple. */
+ bool IsFrameworkOnApple() const;
+
+ /** Return whether this target is an executable Bundle on Apple. */
+ bool IsAppBundleOnApple() const;
+
+ /** Return whether this target is a XCTest on Apple. */
+ bool IsXCTestOnApple() const;
+
+ /** Return whether this target is a CFBundle (plugin) on Apple. */
+ bool IsCFBundleOnApple() const;
+
+ struct SourceFileFlags
+ GetTargetSourceFileFlags(const cmSourceFile* sf) const;
+
+ struct ResxData {
+ mutable std::set<std::string> ExpectedResxHeaders;
+ mutable std::vector<cmSourceFile const*> ResxSources;
+ };
+
+ struct XamlData {
+ std::set<std::string> ExpectedXamlHeaders;
+ std::set<std::string> ExpectedXamlSources;
+ std::vector<cmSourceFile const*> XamlSources;
+ };
+
+ void ReportPropertyOrigin(const std::string &p,
+ const std::string &result,
+ const std::string &report,
+ const std::string &compatibilityType) const;
+
+ class TargetPropertyEntry;
+
+ bool HaveInstallTreeRPATH() const;
+
+ /** Whether this library has \@rpath and platform supports it. */
+ bool HasMacOSXRpathInstallNameDir(const std::string& config) const;
+
+ /** Whether this library defaults to \@rpath. */
+ bool MacOSXRpathInstallNameDirDefault() const;
+
+ /** Test for special case of a third-party shared library that has
+ no soname at all. */
+ bool IsImportedSharedLibWithoutSOName(const std::string& config) const;
+
+ const char* ImportedGetLocation(const std::string& config) const;
+
+ /** Get the target major and minor version numbers interpreted from
+ the VERSION property. Version 0 is returned if the property is
+ not set or cannot be parsed. */
+ void GetTargetVersion(int& major, int& minor) const;
+
+ /** Get the target major, minor, and patch version numbers
+ interpreted from the VERSION or SOVERSION property. Version 0
+ is returned if the property is not set or cannot be parsed. */
+ void
+ GetTargetVersion(bool soversion, int& major, int& minor, int& patch) const;
private:
- void ClassifySources();
- void LookupObjectLibraries();
+ friend class cmTargetTraceDependencies;
+ struct SourceEntry { std::vector<cmSourceFile*> Depends; };
+ typedef std::map<cmSourceFile const*, SourceEntry> SourceEntriesType;
+ SourceEntriesType SourceDepends;
+ mutable std::map<cmSourceFile const*, std::string> Objects;
+ std::set<cmSourceFile const*> ExplicitObjectName;
+ mutable std::map<std::string, std::vector<std::string> > SystemIncludesCache;
+
+ mutable std::string ExportMacro;
+
+ void ConstructSourceFileFlags() const;
+ mutable bool SourceFileFlagsConstructed;
+ mutable std::map<cmSourceFile const*, SourceFileFlags> SourceFlagsMap;
+
+ mutable std::map<std::string, bool> DebugCompatiblePropertiesDone;
+
+ std::string GetFullNameInternal(const std::string& config,
+ bool implib) const;
+ void GetFullNameInternal(const std::string& config, bool implib,
+ std::string& outPrefix, std::string& outBase,
+ std::string& outSuffix) const;
+
+ typedef std::map<std::string, LinkClosure> LinkClosureMapType;
+ mutable LinkClosureMapType LinkClosureMap;
+
+ // Returns ARCHIVE, LIBRARY, or RUNTIME based on platform and type.
+ const char* GetOutputTargetType(bool implib) const;
+
+ void ComputeVersionedName(std::string& vName,
+ std::string const& prefix,
+ std::string const& base,
+ std::string const& suffix,
+ std::string const& name,
+ const char* version) const;
- std::map<std::string, std::vector<std::string> > SystemIncludesCache;
+ struct CompatibleInterfacesBase
+ {
+ std::set<std::string> PropsBool;
+ std::set<std::string> PropsString;
+ std::set<std::string> PropsNumberMax;
+ std::set<std::string> PropsNumberMin;
+ };
+ CompatibleInterfacesBase const&
+ GetCompatibleInterfaces(std::string const& config) const;
+
+ struct CompatibleInterfaces: public CompatibleInterfacesBase
+ {
+ CompatibleInterfaces(): Done(false) {}
+ bool Done;
+ };
+ mutable std::map<std::string, CompatibleInterfaces> CompatibleInterfacesMap;
+
+ typedef std::map<std::string, cmComputeLinkInformation*>
+ cmTargetLinkInformationMap;
+ mutable cmTargetLinkInformationMap LinkInformation;
+
+ void CheckPropertyCompatibility(cmComputeLinkInformation *info,
+ const std::string& config) const;
cmGeneratorTarget(cmGeneratorTarget const&);
void operator=(cmGeneratorTarget const&);
-};
-typedef std::map<cmTarget*, cmGeneratorTarget*> cmGeneratorTargetsType;
+ struct LinkImplClosure: public std::vector<cmGeneratorTarget const*>
+ {
+ LinkImplClosure(): Done(false) {}
+ bool Done;
+ };
+ mutable std::map<std::string, LinkImplClosure> LinkImplClosureMap;
+
+ typedef std::map<std::string, cmHeadToLinkInterfaceMap>
+ LinkInterfaceMapType;
+ mutable LinkInterfaceMapType LinkInterfaceMap;
+ mutable LinkInterfaceMapType LinkInterfaceUsageRequirementsOnlyMap;
+
+ cmHeadToLinkInterfaceMap&
+ GetHeadToLinkInterfaceMap(std::string const& config) const;
+ cmHeadToLinkInterfaceMap& GetHeadToLinkInterfaceUsageRequirementsMap(
+ std::string const& config) const;
+
+ // Cache import information from properties for each configuration.
+ struct ImportInfo
+ {
+ ImportInfo(): NoSOName(false), Multiplicity(0) {}
+ bool NoSOName;
+ int Multiplicity;
+ std::string Location;
+ std::string SOName;
+ std::string ImportLibrary;
+ std::string Languages;
+ std::string Libraries;
+ std::string LibrariesProp;
+ std::string SharedDeps;
+ };
+
+ typedef std::map<std::string, ImportInfo> ImportInfoMapType;
+ mutable ImportInfoMapType ImportInfoMap;
+ void ComputeImportInfo(std::string const& desired_config,
+ ImportInfo& info) const;
+ ImportInfo const* GetImportInfo(const std::string& config) const;
+
+ /** Strip off leading and trailing whitespace from an item named in
+ the link dependencies of this target. */
+ std::string CheckCMP0004(std::string const& item) const;
+
+ cmLinkInterface const*
+ GetImportLinkInterface(const std::string& config,
+ const cmGeneratorTarget* head,
+ bool usage_requirements_only) const;
+
+ typedef std::map<std::string, std::vector<cmSourceFile*> >
+ SourceFilesMapType;
+ mutable SourceFilesMapType SourceFilesMap;
+
+ std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
+ std::vector<TargetPropertyEntry*> CompileOptionsEntries;
+ std::vector<TargetPropertyEntry*> CompileFeaturesEntries;
+ std::vector<TargetPropertyEntry*> CompileDefinitionsEntries;
+ std::vector<TargetPropertyEntry*> SourceEntries;
+ mutable std::set<std::string> LinkImplicitNullProperties;
+
+ void ExpandLinkItems(std::string const& prop, std::string const& value,
+ std::string const& config,
+ const cmGeneratorTarget* headTarget,
+ bool usage_requirements_only,
+ std::vector<cmLinkItem>& items,
+ bool& hadHeadSensitiveCondition) const;
+ void LookupLinkItems(std::vector<std::string> const& names,
+ std::vector<cmLinkItem>& items) const;
+
+ void GetSourceFiles(std::vector<std::string>& files,
+ const std::string& config) const;
+
+ struct HeadToLinkImplementationMap:
+ public std::map<cmGeneratorTarget const*, cmOptionalLinkImplementation> {};
+ typedef std::map<std::string,
+ HeadToLinkImplementationMap> LinkImplMapType;
+ mutable LinkImplMapType LinkImplMap;
+
+ cmLinkImplementationLibraries const*
+ GetLinkImplementationLibrariesInternal(const std::string& config,
+ const cmGeneratorTarget* head) const;
+ bool
+ ComputeOutputDir(const std::string& config,
+ bool implib, std::string& out) const;
+
+ typedef std::map<std::string, OutputInfo> OutputInfoMapType;
+ mutable OutputInfoMapType OutputInfoMap;
+
+ typedef std::pair<std::string, bool> OutputNameKey;
+ typedef std::map<OutputNameKey, std::string> OutputNameMapType;
+ mutable OutputNameMapType OutputNameMap;
+ mutable std::set<cmLinkItem> UtilityItems;
+ cmPolicies::PolicyMap PolicyMap;
+ mutable bool PolicyWarnedCMP0022;
+ mutable bool DebugIncludesDone;
+ mutable bool DebugCompileOptionsDone;
+ mutable bool DebugCompileFeaturesDone;
+ mutable bool DebugCompileDefinitionsDone;
+ mutable bool DebugSourcesDone;
+ mutable bool LinkImplementationLanguageIsContextDependent;
+ mutable bool UtilityItemsDone;
+ bool DLLPlatform;
+
+ bool ComputePDBOutputDir(const std::string& kind, const std::string& config,
+ std::string& out) const;
+
+public:
+ const std::vector<const cmGeneratorTarget*>&
+ GetLinkImplementationClosure(const std::string& config) const;
+
+ mutable std::map<std::string, std::string> MaxLanguageStandards;
+ std::map<std::string, std::string> const&
+ GetMaxLanguageStandards() const
+ {
+ return this->MaxLanguageStandards;
+ }
+
+ struct StrictTargetComparison {
+ bool operator()(cmGeneratorTarget const* t1,
+ cmGeneratorTarget const* t2) const;
+ };
+};
#endif
diff --git a/Source/cmGetCMakePropertyCommand.cxx b/Source/cmGetCMakePropertyCommand.cxx
index e7ad91a36..1a91183d4 100644
--- a/Source/cmGetCMakePropertyCommand.cxx
+++ b/Source/cmGetCMakePropertyCommand.cxx
@@ -12,8 +12,9 @@
#include "cmGetCMakePropertyCommand.h"
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
#include "cmake.h"
+#include "cmState.h"
+#include "cmAlgorithms.h"
// cmGetCMakePropertyCommand
bool cmGetCMakePropertyCommand
@@ -25,55 +26,44 @@ bool cmGetCMakePropertyCommand
return false;
}
- std::vector<std::string>::size_type cc;
std::string variable = args[0];
std::string output = "NOTFOUND";
if ( args[1] == "VARIABLES" )
{
- int cacheonly = 0;
- std::vector<std::string> vars = this->Makefile->GetDefinitions(cacheonly);
- if (vars.size()>0)
+ if (const char* varsProp = this->Makefile->GetProperty("VARIABLES"))
{
- output = vars[0];
- }
- for ( cc = 1; cc < vars.size(); ++cc )
- {
- output += ";";
- output += vars[cc];
+ output = varsProp;
}
}
else if ( args[1] == "MACROS" )
{
- this->Makefile->GetListOfMacros(output);
+ output.clear();
+ if (const char* macrosProp = this->Makefile->GetProperty("MACROS"))
+ {
+ output = macrosProp;
+ }
}
else if ( args[1] == "COMPONENTS" )
{
- const std::set<cmStdString>* components
- = this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
- ->GetInstallComponents();
- std::set<cmStdString>::const_iterator compIt;
- output = "";
- for (compIt = components->begin(); compIt != components->end(); ++compIt)
- {
- if (compIt != components->begin())
- {
- output += ";";
- }
- output += *compIt;
- }
+ const std::set<std::string>* components
+ = this->Makefile->GetGlobalGenerator()->GetInstallComponents();
+ output = cmJoin(*components, ";");
}
else
{
- const char *prop =
- this->Makefile->GetCMakeInstance()->GetProperty(args[1].c_str());
+ const char *prop = 0;
+ if (!args[1].empty())
+ {
+ prop = this->Makefile->GetState()->GetGlobalProperty(args[1]);
+ }
if (prop)
{
output = prop;
}
}
- this->Makefile->AddDefinition(variable.c_str(), output.c_str());
+ this->Makefile->AddDefinition(variable, output.c_str());
return true;
}
diff --git a/Source/cmGetCMakePropertyCommand.h b/Source/cmGetCMakePropertyCommand.h
index b77eaae04..15114064e 100644
--- a/Source/cmGetCMakePropertyCommand.h
+++ b/Source/cmGetCMakePropertyCommand.h
@@ -37,32 +37,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "get_cmake_property";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Get a property of the CMake instance.";
- }
-
- /**
- * Longer documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " get_cmake_property(VAR property)\n"
- "Get a property from the CMake instance. "
- "The value of the property is stored in the variable VAR. "
- "If the property is not found, VAR will be set to \"NOTFOUND\". "
- "Some supported properties "
- "include: VARIABLES, CACHE_VARIABLES, COMMANDS, MACROS, and "
- "COMPONENTS."
- "\n"
- "See also the more general get_property() command.";
- }
+ virtual std::string GetName() const { return "get_cmake_property";}
cmTypeMacro(cmGetCMakePropertyCommand, cmCommand);
};
diff --git a/Source/cmGetDirectoryPropertyCommand.cxx b/Source/cmGetDirectoryPropertyCommand.cxx
index 9e76e1bc3..255887689 100644
--- a/Source/cmGetDirectoryPropertyCommand.cxx
+++ b/Source/cmGetDirectoryPropertyCommand.cxx
@@ -26,7 +26,6 @@ bool cmGetDirectoryPropertyCommand
std::vector<std::string>::const_iterator i = args.begin();
std::string variable = *i;
++i;
- std::string output = "";
// get the directory argument if there is one
cmMakefile *dir = this->Makefile;
@@ -43,19 +42,17 @@ bool cmGetDirectoryPropertyCommand
// make sure the start dir is a full path
if (!cmSystemTools::FileIsFullPath(sd.c_str()))
{
- sd = this->Makefile->GetStartDirectory();
+ sd = this->Makefile->GetCurrentSourceDirectory();
sd += "/";
sd += *i;
}
// The local generators are associated with collapsed paths.
- sd = cmSystemTools::CollapseFullPath(sd.c_str());
+ sd = cmSystemTools::CollapseFullPath(sd);
// lookup the makefile from the directory name
- cmLocalGenerator *lg =
- this->Makefile->GetLocalGenerator()->GetGlobalGenerator()->
- FindLocalGenerator(sd.c_str());
- if (!lg)
+ dir = this->Makefile->GetGlobalGenerator()->FindMakefile(sd);
+ if (!dir)
{
this->SetError
("DIRECTORY argument provided but requested directory not found. "
@@ -63,7 +60,6 @@ bool cmGetDirectoryPropertyCommand
"it is valid but has not been processed yet.");
return false;
}
- dir = lg->GetMakefile();
++i;
}
@@ -79,18 +75,45 @@ bool cmGetDirectoryPropertyCommand
"providing the name of the variable to get.");
return false;
}
- output = dir->GetSafeDefinition(i->c_str());
- this->Makefile->AddDefinition(variable.c_str(), output.c_str());
+ std::string output = dir->GetSafeDefinition(*i);
+ this->Makefile->AddDefinition(variable, output.c_str());
return true;
}
- const char *prop = dir->GetProperty(i->c_str());
- if (prop)
+ const char *prop = 0;
+ if (!i->empty())
{
- this->Makefile->AddDefinition(variable.c_str(), prop);
- return true;
+ if (*i == "DEFINITIONS")
+ {
+ switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0059))
+ {
+ case cmPolicies::WARN:
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING,
+ cmPolicies::GetPolicyWarning(cmPolicies::CMP0059));
+ case cmPolicies::OLD:
+ this->StoreResult(variable,
+ this->Makefile->GetDefineFlagsCMP0059());
+ return true;
+ case cmPolicies::NEW:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ break;
+ }
+ }
+ prop = dir->GetProperty(*i);
}
- this->Makefile->AddDefinition(variable.c_str(), "");
+ this->StoreResult(variable, prop);
return true;
}
+void cmGetDirectoryPropertyCommand::StoreResult(std::string const& variable,
+ const char* prop)
+{
+ if (prop)
+ {
+ this->Makefile->AddDefinition(variable, prop);
+ return;
+ }
+ this->Makefile->AddDefinition(variable, "");
+}
+
diff --git a/Source/cmGetDirectoryPropertyCommand.h b/Source/cmGetDirectoryPropertyCommand.h
index d0d582028..f4188861f 100644
--- a/Source/cmGetDirectoryPropertyCommand.h
+++ b/Source/cmGetDirectoryPropertyCommand.h
@@ -37,42 +37,12 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "get_directory_property";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Get a property of DIRECTORY scope.";
- }
-
- /**
- * Longer documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " get_directory_property(<variable> [DIRECTORY <dir>] <prop-name>)\n"
- "Store a property of directory scope in the named variable. "
- "If the property is not defined the empty-string is returned. "
- "The DIRECTORY argument specifies another directory from which "
- "to retrieve the property value. "
- "The specified directory must have already been traversed by "
- "CMake."
- "\n"
- " get_directory_property(<variable> [DIRECTORY <dir>]\n"
- " DEFINITION <var-name>)\n"
- "Get a variable definition from a directory. "
- "This form is useful to get a variable definition from another "
- "directory."
- "\n"
- "See also the more general get_property() command.";
- }
+ virtual std::string GetName() const { return "get_directory_property";}
cmTypeMacro(cmGetDirectoryPropertyCommand, cmCommand);
-};
-
+private:
+ void StoreResult(const std::string& variable, const char* prop);
+};
#endif
diff --git a/Source/cmGetFilenameComponentCommand.cxx b/Source/cmGetFilenameComponentCommand.cxx
index 1d7fefcee..0f56c8e8f 100644
--- a/Source/cmGetFilenameComponentCommand.cxx
+++ b/Source/cmGetFilenameComponentCommand.cxx
@@ -24,9 +24,9 @@ bool cmGetFilenameComponentCommand
// Check and see if the value has been stored in the cache
// already, if so use that value
- if(args.size() == 4 && args[3] == "CACHE")
+ if(args.size() >= 4 && args[args.size() - 1] == "CACHE")
{
- const char* cacheValue = this->Makefile->GetDefinition(args[0].c_str());
+ const char* cacheValue = this->Makefile->GetDefinition(args[0]);
if(cacheValue && !cmSystemTools::IsNOTFOUND(cacheValue))
{
return true;
@@ -79,7 +79,7 @@ bool cmGetFilenameComponentCommand
}
}
}
- cmSystemTools::SplitProgramFromArgs(filename.c_str(),
+ cmSystemTools::SplitProgramFromArgs(filename,
result, programArgs);
}
else if (args[2] == "EXT")
@@ -93,45 +93,57 @@ bool cmGetFilenameComponentCommand
else if (args[2] == "ABSOLUTE" ||
args[2] == "REALPATH")
{
+ // If the path given is relative, evaluate it relative to the
+ // current source directory unless the user passes a different
+ // base directory.
+ std::string baseDir = this->Makefile->GetCurrentSourceDirectory();
+ for(unsigned int i=3; i < args.size(); ++i)
+ {
+ if(args[i] == "BASE_DIR")
+ {
+ ++i;
+ if(i < args.size())
+ {
+ baseDir = args[i];
+ }
+ }
+ }
// Collapse the path to its simplest form.
- // If the path given is relative evaluate it relative to the
- // current source directory.
- result = cmSystemTools::CollapseFullPath(
- filename.c_str(), this->Makefile->GetCurrentDirectory());
+ result = cmSystemTools::CollapseFullPath(filename, baseDir);
if(args[2] == "REALPATH")
{
// Resolve symlinks if possible
- result = cmSystemTools::GetRealPath(result.c_str());
+ result = cmSystemTools::GetRealPath(result);
}
}
else
{
std::string err = "unknown component " + args[2];
- this->SetError(err.c_str());
+ this->SetError(err);
return false;
}
- if(args.size() == 4 && args[3] == "CACHE")
+ if(args.size() >= 4 && args[args.size() - 1] == "CACHE")
{
- if(programArgs.size() && storeArgs.size())
+ if(!programArgs.empty() && !storeArgs.empty())
{
this->Makefile->AddCacheDefinition
- (storeArgs.c_str(), programArgs.c_str(),
- "", args[2] == "PATH" ? cmCacheManager::FILEPATH
- : cmCacheManager::STRING);
+ (storeArgs, programArgs.c_str(),
+ "", args[2] == "PATH" ? cmState::FILEPATH
+ : cmState::STRING);
}
this->Makefile->AddCacheDefinition
- (args[0].c_str(), result.c_str(), "",
- args[2] == "PATH" ? cmCacheManager::FILEPATH
- : cmCacheManager::STRING);
+ (args[0], result.c_str(), "",
+ args[2] == "PATH" ? cmState::FILEPATH
+ : cmState::STRING);
}
else
{
- if(programArgs.size() && storeArgs.size())
+ if(!programArgs.empty() && !storeArgs.empty())
{
- this->Makefile->AddDefinition(storeArgs.c_str(), programArgs.c_str());
+ this->Makefile->AddDefinition(storeArgs, programArgs.c_str());
}
- this->Makefile->AddDefinition(args[0].c_str(), result.c_str());
+ this->Makefile->AddDefinition(args[0], result.c_str());
}
return true;
diff --git a/Source/cmGetFilenameComponentCommand.h b/Source/cmGetFilenameComponentCommand.h
index 09af3325a..534de53d1 100644
--- a/Source/cmGetFilenameComponentCommand.h
+++ b/Source/cmGetFilenameComponentCommand.h
@@ -46,44 +46,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "get_filename_component";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Get a specific component of a full filename.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " get_filename_component(<VAR> <FileName> <COMP> [CACHE])\n"
- "Set <VAR> to a component of <FileName>, where <COMP> is one of:\n"
- " DIRECTORY = Directory without file name\n"
- " NAME = File name without directory\n"
- " EXT = File name longest extension (.b.c from d/a.b.c)\n"
- " NAME_WE = File name without directory or longest extension\n"
- " ABSOLUTE = Full path to file\n"
- " REALPATH = Full path to existing file with symlinks resolved\n"
- " PATH = Legacy alias for DIRECTORY (use for CMake <= 2.8.11)\n"
- "Paths are returned with forward slashes and have no trailing slahes. "
- "The longest file extension is always considered. "
- "If the optional CACHE argument is specified, the result variable is "
- "added to the cache.\n"
- " get_filename_component(<VAR> FileName\n"
- " PROGRAM [PROGRAM_ARGS <ARG_VAR>]\n"
- " [CACHE])\n"
- "The program in FileName will be found in the system search path or "
- "left as a full path. If PROGRAM_ARGS is present with PROGRAM, then "
- "any command-line arguments present in the FileName string are split "
- "from the program name and stored in <ARG_VAR>. This is used to "
- "separate a program name from its arguments in a command line string.";
- }
+ virtual std::string GetName() const { return "get_filename_component";}
cmTypeMacro(cmGetFilenameComponentCommand, cmCommand);
};
diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx
index faba7cd35..617a8116e 100644
--- a/Source/cmGetPropertyCommand.cxx
+++ b/Source/cmGetPropertyCommand.cxx
@@ -12,9 +12,9 @@
#include "cmGetPropertyCommand.h"
#include "cmake.h"
+#include "cmState.h"
#include "cmTest.h"
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
#include "cmSourceFile.h"
#include "cmPropertyDefinition.h"
@@ -67,13 +67,17 @@ bool cmGetPropertyCommand
{
scope = cmProperty::CACHE;
}
+ else if(args[1] == "INSTALL")
+ {
+ scope = cmProperty::INSTALL;
+ }
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "given invalid scope " << args[1] << ". "
<< "Valid scopes are "
- << "GLOBAL, DIRECTORY, TARGET, SOURCE, TEST, VARIABLE, CACHE.";
- this->SetError(e.str().c_str());
+ << "GLOBAL, DIRECTORY, TARGET, SOURCE, TEST, VARIABLE, CACHE, INSTALL.";
+ this->SetError(e.str());
return false;
}
@@ -118,9 +122,9 @@ bool cmGetPropertyCommand
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "given invalid argument \"" << args[i] << "\".";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
@@ -137,9 +141,8 @@ bool cmGetPropertyCommand
{
// Lookup brief documentation.
std::string output;
- if(cmPropertyDefinition* def =
- this->Makefile->GetCMakeInstance()->
- GetPropertyDefinition(this->PropertyName.c_str(), scope))
+ if(cmPropertyDefinition const* def = this->Makefile->GetState()->
+ GetPropertyDefinition(this->PropertyName, scope))
{
output = def->GetShortDescription();
}
@@ -147,15 +150,14 @@ bool cmGetPropertyCommand
{
output = "NOTFOUND";
}
- this->Makefile->AddDefinition(this->Variable.c_str(), output.c_str());
+ this->Makefile->AddDefinition(this->Variable, output.c_str());
}
else if(this->InfoType == OutFullDoc)
{
// Lookup full documentation.
std::string output;
- if(cmPropertyDefinition* def =
- this->Makefile->GetCMakeInstance()->
- GetPropertyDefinition(this->PropertyName.c_str(), scope))
+ if(cmPropertyDefinition const* def = this->Makefile->GetState()->
+ GetPropertyDefinition(this->PropertyName, scope))
{
output = def->GetFullDescription();
}
@@ -163,19 +165,19 @@ bool cmGetPropertyCommand
{
output = "NOTFOUND";
}
- this->Makefile->AddDefinition(this->Variable.c_str(), output.c_str());
+ this->Makefile->AddDefinition(this->Variable, output.c_str());
}
else if(this->InfoType == OutDefined)
{
// Lookup if the property is defined
- if(this->Makefile->GetCMakeInstance()->
- GetPropertyDefinition(this->PropertyName.c_str(), scope))
+ if(this->Makefile->GetState()->
+ GetPropertyDefinition(this->PropertyName, scope))
{
- this->Makefile->AddDefinition(this->Variable.c_str(), "1");
+ this->Makefile->AddDefinition(this->Variable, "1");
}
else
{
- this->Makefile->AddDefinition(this->Variable.c_str(), "0");
+ this->Makefile->AddDefinition(this->Variable, "0");
}
}
else
@@ -190,6 +192,7 @@ bool cmGetPropertyCommand
case cmProperty::TEST: return this->HandleTestMode();
case cmProperty::VARIABLE: return this->HandleVariableMode();
case cmProperty::CACHE: return this->HandleCacheMode();
+ case cmProperty::INSTALL: return this->HandleInstallMode();
case cmProperty::CACHED_VARIABLE:
break; // should never happen
@@ -204,17 +207,17 @@ bool cmGetPropertyCommand::StoreResult(const char* value)
{
if(this->InfoType == OutSet)
{
- this->Makefile->AddDefinition(this->Variable.c_str(), value? "1":"0");
+ this->Makefile->AddDefinition(this->Variable, value? "1":"0");
}
else // if(this->InfoType == OutValue)
{
if(value)
{
- this->Makefile->AddDefinition(this->Variable.c_str(), value);
+ this->Makefile->AddDefinition(this->Variable, value);
}
else
{
- this->Makefile->RemoveDefinition(this->Variable.c_str());
+ this->Makefile->RemoveDefinition(this->Variable);
}
}
return true;
@@ -231,7 +234,8 @@ bool cmGetPropertyCommand::HandleGlobalMode()
// Get the property.
cmake* cm = this->Makefile->GetCMakeInstance();
- return this->StoreResult(cm->GetProperty(this->PropertyName.c_str()));
+ return this->StoreResult(cm->GetState()
+ ->GetGlobalProperty(this->PropertyName));
}
//----------------------------------------------------------------------------
@@ -248,23 +252,17 @@ bool cmGetPropertyCommand::HandleDirectoryMode()
std::string dir = this->Name;
if(!cmSystemTools::FileIsFullPath(dir.c_str()))
{
- dir = this->Makefile->GetCurrentDirectory();
+ dir = this->Makefile->GetCurrentSourceDirectory();
dir += "/";
dir += this->Name;
}
// The local generators are associated with collapsed paths.
- dir = cmSystemTools::CollapseFullPath(dir.c_str());
+ dir = cmSystemTools::CollapseFullPath(dir);
// Lookup the generator.
- if(cmLocalGenerator* lg =
- (this->Makefile->GetLocalGenerator()
- ->GetGlobalGenerator()->FindLocalGenerator(dir.c_str())))
- {
- // Use the makefile for the directory found.
- mf = lg->GetMakefile();
- }
- else
+ mf = this->Makefile->GetGlobalGenerator()->FindMakefile(dir);
+ if (!mf)
{
// Could not find the directory.
this->SetError
@@ -275,8 +273,24 @@ bool cmGetPropertyCommand::HandleDirectoryMode()
}
}
+ if (this->PropertyName == "DEFINITIONS")
+ {
+ switch(mf->GetPolicyStatus(cmPolicies::CMP0059))
+ {
+ case cmPolicies::WARN:
+ mf->IssueMessage(cmake::AUTHOR_WARNING,
+ cmPolicies::GetPolicyWarning(cmPolicies::CMP0059));
+ case cmPolicies::OLD:
+ return this->StoreResult(mf->GetDefineFlagsCMP0059());
+ case cmPolicies::NEW:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ break;
+ }
+ }
+
// Get the property.
- return this->StoreResult(mf->GetProperty(this->PropertyName.c_str()));
+ return this->StoreResult(mf->GetProperty(this->PropertyName));
}
//----------------------------------------------------------------------------
@@ -290,26 +304,27 @@ bool cmGetPropertyCommand::HandleTargetMode()
if(this->PropertyName == "ALIASED_TARGET")
{
- if(this->Makefile->IsAlias(this->Name.c_str()))
+ if(this->Makefile->IsAlias(this->Name))
{
if(cmTarget* target =
- this->Makefile->FindTargetToUse(this->Name.c_str()))
+ this->Makefile->FindTargetToUse(this->Name))
{
- return this->StoreResult(target->GetName());
+ return this->StoreResult(target->GetName().c_str());
}
}
- return false;
+ return this->StoreResult((this->Variable + "-NOTFOUND").c_str());
}
- if(cmTarget* target = this->Makefile->FindTargetToUse(this->Name.c_str()))
+ if(cmTarget* target = this->Makefile->FindTargetToUse(this->Name))
{
- return this->StoreResult(target->GetProperty(this->PropertyName.c_str()));
+ return this->StoreResult(target->GetProperty(this->PropertyName,
+ this->Makefile));
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "could not find TARGET " << this->Name
<< ". Perhaps it has not yet been created.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
@@ -325,17 +340,17 @@ bool cmGetPropertyCommand::HandleSourceMode()
// Get the source file.
if(cmSourceFile* sf =
- this->Makefile->GetOrCreateSource(this->Name.c_str()))
+ this->Makefile->GetOrCreateSource(this->Name))
{
return
- this->StoreResult(sf->GetPropertyForUser(this->PropertyName.c_str()));
+ this->StoreResult(sf->GetPropertyForUser(this->PropertyName));
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "given SOURCE name that could not be found or created: "
<< this->Name;
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
@@ -350,15 +365,15 @@ bool cmGetPropertyCommand::HandleTestMode()
}
// Loop over all tests looking for matching names.
- if(cmTest* test = this->Makefile->GetTest(this->Name.c_str()))
+ if(cmTest* test = this->Makefile->GetTest(this->Name))
{
- return this->StoreResult(test->GetProperty(this->PropertyName.c_str()));
+ return this->StoreResult(test->GetProperty(this->PropertyName));
}
// If not found it is an error.
- cmOStringStream e;
+ std::ostringstream e;
e << "given TEST name that does not exist: " << this->Name;
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
@@ -372,7 +387,7 @@ bool cmGetPropertyCommand::HandleVariableMode()
}
return this->StoreResult
- (this->Makefile->GetDefinition(this->PropertyName.c_str()));
+ (this->Makefile->GetDefinition(this->PropertyName));
}
//----------------------------------------------------------------------------
@@ -385,12 +400,41 @@ bool cmGetPropertyCommand::HandleCacheMode()
}
const char* value = 0;
- cmCacheManager::CacheIterator it =
- this->Makefile->GetCacheManager()->GetCacheIterator(this->Name.c_str());
- if(!it.IsAtEnd())
+ if(this->Makefile->GetState()->GetCacheEntryValue(this->Name))
{
- value = it.GetProperty(this->PropertyName.c_str());
+ value = this->Makefile->GetState()
+ ->GetCacheEntryProperty(this->Name, this->PropertyName);
}
this->StoreResult(value);
return true;
}
+
+//----------------------------------------------------------------------------
+bool cmGetPropertyCommand::HandleInstallMode()
+{
+ if(this->Name.empty())
+ {
+ this->SetError("not given name for INSTALL scope.");
+ return false;
+ }
+
+ // Get the installed file.
+ cmake* cm = this->Makefile->GetCMakeInstance();
+
+ if(cmInstalledFile* file = cm->GetOrCreateInstalledFile(
+ this->Makefile, this->Name))
+ {
+ std::string value;
+ bool isSet = file->GetProperty(this->PropertyName, value);
+
+ return this->StoreResult(isSet ? value.c_str() : 0);
+ }
+ else
+ {
+ std::ostringstream e;
+ e << "given INSTALL name that could not be found or created: "
+ << this->Name;
+ this->SetError(e.str());
+ return false;
+ }
+}
diff --git a/Source/cmGetPropertyCommand.h b/Source/cmGetPropertyCommand.h
index 3c597fdcf..40b7dbc00 100644
--- a/Source/cmGetPropertyCommand.h
+++ b/Source/cmGetPropertyCommand.h
@@ -39,59 +39,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "get_property";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Get a property.";
- }
-
- /**
- * Longer documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " get_property(<variable>\n"
- " <GLOBAL |\n"
- " DIRECTORY [dir] |\n"
- " TARGET <target> |\n"
- " SOURCE <source> |\n"
- " TEST <test> |\n"
- " CACHE <entry> |\n"
- " VARIABLE>\n"
- " PROPERTY <name>\n"
- " [SET | DEFINED | BRIEF_DOCS | FULL_DOCS])\n"
- "Get one property from one object in a scope. "
- "The first argument specifies the variable in which to store the "
- "result. "
- "The second argument determines the scope from which to get the "
- "property. It must be one of the following:\n"
- "GLOBAL scope is unique and does not accept a name.\n"
- "DIRECTORY scope defaults to the current directory but another "
- "directory (already processed by CMake) may be named by full or "
- "relative path.\n"
- "TARGET scope must name one existing target.\n"
- "SOURCE scope must name one source file.\n"
- "TEST scope must name one existing test.\n"
- "CACHE scope must name one cache entry.\n"
- "VARIABLE scope is unique and does not accept a name.\n"
- "The required PROPERTY option is immediately followed by the name "
- "of the property to get. "
- "If the property is not set an empty value is returned. "
- "If the SET option is given the variable is set to a boolean "
- "value indicating whether the property has been set. "
- "If the DEFINED option is given the variable is set to a boolean "
- "value indicating whether the property has been defined "
- "such as with define_property. "
- "If BRIEF_DOCS or FULL_DOCS is given then the variable is set to "
- "a string containing documentation for the requested property. "
- "If documentation is requested for a property that has not been "
- "defined NOTFOUND is returned.";
- }
+ virtual std::string GetName() const { return "get_property";}
cmTypeMacro(cmGetPropertyCommand, cmCommand);
private:
@@ -112,6 +60,7 @@ private:
bool HandleTestMode();
bool HandleVariableMode();
bool HandleCacheMode();
+ bool HandleInstallMode();
};
#endif
diff --git a/Source/cmGetSourceFilePropertyCommand.cxx b/Source/cmGetSourceFilePropertyCommand.cxx
index 3d85e6d7d..46daa349a 100644
--- a/Source/cmGetSourceFilePropertyCommand.cxx
+++ b/Source/cmGetSourceFilePropertyCommand.cxx
@@ -29,16 +29,20 @@ bool cmGetSourceFilePropertyCommand
// for the location we must create a source file first
if (!sf && args[2] == "LOCATION")
{
- sf = this->Makefile->GetOrCreateSource(file);
+ sf = this->Makefile->CreateSource(file);
}
if(sf)
{
if(args[2] == "LANGUAGE")
{
- this->Makefile->AddDefinition(var, sf->GetLanguage());
+ this->Makefile->AddDefinition(var, sf->GetLanguage().c_str());
return true;
}
- const char *prop = sf->GetPropertyForUser(args[2].c_str());
+ const char *prop = 0;
+ if (!args[2].empty())
+ {
+ prop = sf->GetPropertyForUser(args[2]);
+ }
if (prop)
{
this->Makefile->AddDefinition(var, prop);
diff --git a/Source/cmGetSourceFilePropertyCommand.h b/Source/cmGetSourceFilePropertyCommand.h
index 2ba81037f..ab8ce365b 100644
--- a/Source/cmGetSourceFilePropertyCommand.h
+++ b/Source/cmGetSourceFilePropertyCommand.h
@@ -32,31 +32,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "get_source_file_property";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Get a property for a source file.";
- }
-
- /**
- * Longer documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " get_source_file_property(VAR file property)\n"
- "Get a property from a source file. The value of the property is "
- "stored in the variable VAR. If the property is not found, VAR "
- "will be set to \"NOTFOUND\". Use set_source_files_properties to set "
- "property values. Source file properties usually control how the "
- "file is built. One property that is always there is LOCATION"
- "\n"
- "See also the more general get_property() command.";
- }
+ virtual std::string GetName() const { return "get_source_file_property";}
cmTypeMacro(cmGetSourceFilePropertyCommand, cmCommand);
};
diff --git a/Source/cmGetTargetPropertyCommand.cxx b/Source/cmGetTargetPropertyCommand.cxx
index 02f00a508..ca40bd077 100644
--- a/Source/cmGetTargetPropertyCommand.cxx
+++ b/Source/cmGetTargetPropertyCommand.cxx
@@ -20,9 +20,10 @@ bool cmGetTargetPropertyCommand
this->SetError("called with incorrect number of arguments");
return false;
}
- std::string var = args[0].c_str();
- const char* targetName = args[1].c_str();
- const char *prop = 0;
+ std::string var = args[0];
+ const std::string& targetName = args[1];
+ std::string prop;
+ bool prop_exists = false;
if(args[2] == "ALIASED_TARGET")
{
@@ -32,21 +33,59 @@ bool cmGetTargetPropertyCommand
this->Makefile->FindTargetToUse(targetName))
{
prop = target->GetName();
+ prop_exists = true;
}
}
}
else if(cmTarget* tgt = this->Makefile->FindTargetToUse(targetName))
{
cmTarget& target = *tgt;
- prop = target.GetProperty(args[2].c_str());
+ const char* prop_cstr = 0;
+ if (!args[2].empty())
+ {
+ prop_cstr = target.GetProperty(args[2], this->Makefile);
+ }
+ if(prop_cstr)
+ {
+ prop = prop_cstr;
+ prop_exists = true;
+ }
}
-
- if (prop)
+ else
+ {
+ bool issueMessage = false;
+ std::ostringstream e;
+ cmake::MessageType messageType = cmake::AUTHOR_WARNING;
+ switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0045))
+ {
+ case cmPolicies::WARN:
+ issueMessage = true;
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0045) << "\n";
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ issueMessage = true;
+ messageType = cmake::FATAL_ERROR;
+ }
+ if (issueMessage)
+ {
+ e << "get_target_property() called with non-existent target \""
+ << targetName << "\".";
+ this->Makefile->IssueMessage(messageType, e.str());
+ if (messageType == cmake::FATAL_ERROR)
+ {
+ return false;
+ }
+ }
+ }
+ if (prop_exists)
{
- this->Makefile->AddDefinition(var.c_str(), prop);
+ this->Makefile->AddDefinition(var, prop.c_str());
return true;
}
- this->Makefile->AddDefinition(var.c_str(), (var+"-NOTFOUND").c_str());
+ this->Makefile->AddDefinition(var, (var+"-NOTFOUND").c_str());
return true;
}
diff --git a/Source/cmGetTargetPropertyCommand.h b/Source/cmGetTargetPropertyCommand.h
index f5e1aa729..a35c6fe9d 100644
--- a/Source/cmGetTargetPropertyCommand.h
+++ b/Source/cmGetTargetPropertyCommand.h
@@ -32,33 +32,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "get_target_property";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Get a property from a target.";
- }
-
- /**
- * Longer documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " get_target_property(VAR target property)\n"
- "Get a property from a target. The value of the property is "
- "stored in the variable VAR. If the property is not found, VAR "
- "will be set to \"NOTFOUND\". Use set_target_properties to set "
- "property values. Properties are usually used to control how "
- "a target is built, but some query the target instead. "
- "This command can get properties for any target so far created. "
- "The targets do not need to be in the current CMakeLists.txt file."
- "\n"
- "See also the more general get_property() command.";
- }
+ virtual std::string GetName() const { return "get_target_property";}
cmTypeMacro(cmGetTargetPropertyCommand, cmCommand);
};
diff --git a/Source/cmGetTestPropertyCommand.cxx b/Source/cmGetTestPropertyCommand.cxx
index 0e0e2c09b..bf34589f4 100644
--- a/Source/cmGetTestPropertyCommand.cxx
+++ b/Source/cmGetTestPropertyCommand.cxx
@@ -26,17 +26,21 @@ bool cmGetTestPropertyCommand
std::string testName = args[0];
std::string var = args[2];
- cmTest *test = this->Makefile->GetTest(testName.c_str());
+ cmTest *test = this->Makefile->GetTest(testName);
if (test)
{
- const char *prop = test->GetProperty(args[1].c_str());
+ const char *prop = 0;
+ if (!args[1].empty())
+ {
+ prop = test->GetProperty(args[1]);
+ }
if (prop)
{
- this->Makefile->AddDefinition(var.c_str(), prop);
+ this->Makefile->AddDefinition(var, prop);
return true;
}
}
- this->Makefile->AddDefinition(var.c_str(), "NOTFOUND");
+ this->Makefile->AddDefinition(var, "NOTFOUND");
return true;
}
diff --git a/Source/cmGetTestPropertyCommand.h b/Source/cmGetTestPropertyCommand.h
index 01f54d951..2819492ee 100644
--- a/Source/cmGetTestPropertyCommand.h
+++ b/Source/cmGetTestPropertyCommand.h
@@ -32,30 +32,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "get_test_property";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Get a property of the test.";
- }
-
- /**
- * Longer documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " get_test_property(test property VAR)\n"
- "Get a property from the Test. The value of the property is "
- "stored in the variable VAR. If the property is not found, VAR "
- "will be set to \"NOTFOUND\". For a list of standard properties "
- "you can type cmake --help-property-list"
- "\n"
- "See also the more general get_property() command.";
- }
+ virtual std::string GetName() const { return "get_test_property";}
cmTypeMacro(cmGetTestPropertyCommand, cmCommand);
};
diff --git a/Source/cmGhsMultiGpj.cxx b/Source/cmGhsMultiGpj.cxx
new file mode 100644
index 000000000..e1dce52bd
--- /dev/null
+++ b/Source/cmGhsMultiGpj.cxx
@@ -0,0 +1,44 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Geoffrey Viola <geoffrey.viola@asirobots.com>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmGhsMultiGpj.h"
+
+#include "cmGeneratedFileStream.h"
+
+void GhsMultiGpj::WriteGpjTag(Types const gpjType,
+ cmGeneratedFileStream *const filestream)
+{
+ char const *tag;
+ switch (gpjType)
+ {
+ case INTERGRITY_APPLICATION:
+ tag = "INTEGRITY Application";
+ break;
+ case LIBRARY:
+ tag = "Library";
+ break;
+ case PROJECT:
+ tag = "Project";
+ break;
+ case PROGRAM:
+ tag = "Program";
+ break;
+ case REFERENCE:
+ tag = "Reference";
+ break;
+ case SUBPROJECT:
+ tag = "Subproject";
+ break;
+ default:
+ tag = "";
+ }
+ *filestream << "[" << tag << "]" << std::endl;
+}
diff --git a/Source/cmGhsMultiGpj.h b/Source/cmGhsMultiGpj.h
new file mode 100644
index 000000000..91ff0f4a5
--- /dev/null
+++ b/Source/cmGhsMultiGpj.h
@@ -0,0 +1,34 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Geoffrey Viola <geoffrey.viola@asirobots.com>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmGhsMultiGpj_h
+#define cmGhsMultiGpj_h
+
+class cmGeneratedFileStream;
+
+class GhsMultiGpj
+{
+public:
+ enum Types
+ {
+ INTERGRITY_APPLICATION,
+ LIBRARY,
+ PROJECT,
+ PROGRAM,
+ REFERENCE,
+ SUBPROJECT
+ };
+
+ static void WriteGpjTag(Types const gpjType,
+ cmGeneratedFileStream *filestream);
+};
+
+#endif // ! cmGhsMultiGpjType_h
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
new file mode 100644
index 000000000..18e140e40
--- /dev/null
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -0,0 +1,616 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Geoffrey Viola <geoffrey.viola@asirobots.com>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmGhsMultiTargetGenerator.h"
+#include "cmGlobalGhsMultiGenerator.h"
+#include "cmLocalGhsMultiGenerator.h"
+#include "cmMakefile.h"
+#include "cmTarget.h"
+#include "cmGeneratedFileStream.h"
+#include "cmSourceFile.h"
+#include <assert.h>
+#include <cmAlgorithms.h>
+
+std::string const cmGhsMultiTargetGenerator::DDOption("-dynamic");
+
+cmGhsMultiTargetGenerator::cmGhsMultiTargetGenerator(cmGeneratorTarget *target)
+ : GeneratorTarget(target)
+ , LocalGenerator(static_cast<cmLocalGhsMultiGenerator *>(
+ target->GetLocalGenerator()))
+ , Makefile(target->Target->GetMakefile())
+ , TargetGroup(DetermineIfTargetGroup(target))
+ , DynamicDownload(false)
+{
+ this->RelBuildFilePath = this->GetRelBuildFilePath(target);
+
+ this->RelOutputFileName =
+ this->RelBuildFilePath + target->GetName() + ".a";
+
+ this->RelBuildFileName = this->RelBuildFilePath;
+ this->RelBuildFileName += this->GetBuildFileName(target);
+
+ std::string absPathToRoot = this->GetAbsPathToRoot(target);
+ absPathToRoot = this->AddSlashIfNeededToPath(absPathToRoot);
+ this->AbsBuildFilePath = absPathToRoot + this->RelBuildFilePath;
+ this->AbsBuildFileName = absPathToRoot + this->RelBuildFileName;
+ this->AbsOutputFileName = absPathToRoot + this->RelOutputFileName;
+}
+
+cmGhsMultiTargetGenerator::~cmGhsMultiTargetGenerator()
+{
+ cmDeleteAll(this->FolderBuildStreams);
+}
+
+std::string
+cmGhsMultiTargetGenerator::GetRelBuildFilePath(
+ const cmGeneratorTarget *target)
+{
+ std::string output;
+ char const *folderProp = target->GetProperty("FOLDER");
+ output = NULL == folderProp ? "" : folderProp;
+ cmSystemTools::ConvertToUnixSlashes(output);
+ if (!output.empty())
+ {
+ output += "/";
+ }
+ output += target->GetName() + "/";
+ return output;
+}
+
+std::string
+cmGhsMultiTargetGenerator::GetAbsPathToRoot(const cmGeneratorTarget *target)
+{
+ return target->GetLocalGenerator()->GetBinaryDirectory();
+}
+
+std::string
+cmGhsMultiTargetGenerator::GetAbsBuildFilePath(const cmGeneratorTarget *target)
+{
+ std::string output;
+ output = cmGhsMultiTargetGenerator::GetAbsPathToRoot(target);
+ output = cmGhsMultiTargetGenerator::AddSlashIfNeededToPath(output);
+ output += cmGhsMultiTargetGenerator::GetRelBuildFilePath(target);
+ return output;
+}
+
+std::string
+cmGhsMultiTargetGenerator::GetRelBuildFileName(const cmGeneratorTarget *target)
+{
+ std::string output;
+ output = cmGhsMultiTargetGenerator::GetRelBuildFilePath(target);
+ output = cmGhsMultiTargetGenerator::AddSlashIfNeededToPath(output);
+ output += cmGhsMultiTargetGenerator::GetBuildFileName(target);
+ return output;
+}
+
+std::string
+cmGhsMultiTargetGenerator::GetBuildFileName(const cmGeneratorTarget *target)
+{
+ std::string output;
+ output = target->GetName();
+ output += cmGlobalGhsMultiGenerator::FILE_EXTENSION;
+ return output;
+}
+
+std::string
+cmGhsMultiTargetGenerator::AddSlashIfNeededToPath(std::string const &input)
+{
+ std::string output(input);
+ if (!cmHasLiteralSuffix(output, "/"))
+ {
+ output += "/";
+ }
+ return output;
+}
+
+void cmGhsMultiTargetGenerator::Generate()
+{
+ const std::vector<cmSourceFile *> objectSources = this->GetSources();
+ if (!objectSources.empty() && this->IncludeThisTarget())
+ {
+ if (!cmSystemTools::FileExists(this->AbsBuildFilePath.c_str()))
+ {
+ cmSystemTools::MakeDirectory(this->AbsBuildFilePath.c_str());
+ }
+ cmGlobalGhsMultiGenerator::Open(std::string(""), this->AbsBuildFileName,
+ &this->FolderBuildStreams);
+ cmGlobalGhsMultiGenerator::OpenBuildFileStream(
+ this->GetFolderBuildStreams());
+ std::string config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ if (0 == config.length())
+ {
+ config = "RELEASE";
+ }
+ const std::string language(
+ this->GeneratorTarget->GetLinkerLanguage(config));
+ config = cmSystemTools::UpperCase(config);
+ this->DynamicDownload = this->DetermineIfDynamicDownload(config, language);
+ if (this->DynamicDownload)
+ {
+ *this->GetFolderBuildStreams() << "#component integrity_dynamic_download"
+ << std::endl;
+ }
+ GhsMultiGpj::WriteGpjTag(this->GetGpjTag(), this->GetFolderBuildStreams());
+ cmGlobalGhsMultiGenerator::WriteDisclaimer(this->GetFolderBuildStreams());
+
+ bool const notKernel = this->IsNotKernel(config, language);
+ this->WriteTypeSpecifics(config, notKernel);
+ this->SetCompilerFlags(config, language, notKernel);
+ this->WriteCompilerFlags(config, language);
+ this->WriteCompilerDefinitions(config, language);
+ this->WriteIncludes(config, language);
+ if (this->GeneratorTarget->GetType() == cmState::EXECUTABLE)
+ {
+ this->WriteTargetLinkLibraries();
+ }
+ this->WriteCustomCommands();
+
+ this->WriteSources(objectSources);
+ }
+}
+
+bool cmGhsMultiTargetGenerator::IncludeThisTarget()
+{
+ bool output = true;
+ char const *excludeFromAll =
+ this->GeneratorTarget->GetProperty("EXCLUDE_FROM_ALL");
+ if (NULL != excludeFromAll && '1' == excludeFromAll[0] &&
+ '\0' == excludeFromAll[1])
+ {
+ output = false;
+ }
+ return output;
+}
+
+std::vector<cmSourceFile *> cmGhsMultiTargetGenerator::GetSources() const
+{
+ std::vector<cmSourceFile *> output;
+ std::string config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ this->GeneratorTarget->GetSourceFiles(output, config);
+ return output;
+}
+
+GhsMultiGpj::Types cmGhsMultiTargetGenerator::GetGpjTag() const
+{
+ return cmGhsMultiTargetGenerator::GetGpjTag(this->GeneratorTarget);
+}
+
+GhsMultiGpj::Types cmGhsMultiTargetGenerator::GetGpjTag(
+ const cmGeneratorTarget *target)
+{
+ GhsMultiGpj::Types output;
+ if (cmGhsMultiTargetGenerator::DetermineIfTargetGroup(target))
+ {
+ output = GhsMultiGpj::INTERGRITY_APPLICATION;
+ }
+ else if (target->GetType() == cmState::STATIC_LIBRARY)
+ {
+ output = GhsMultiGpj::LIBRARY;
+ }
+ else
+ {
+ output = GhsMultiGpj::PROGRAM;
+ }
+ return output;
+}
+
+cmGlobalGhsMultiGenerator*
+cmGhsMultiTargetGenerator::GetGlobalGenerator() const
+{
+ return static_cast<cmGlobalGhsMultiGenerator *>(
+ this->LocalGenerator->GetGlobalGenerator());
+}
+
+void cmGhsMultiTargetGenerator::WriteTypeSpecifics(const std::string &config,
+ bool const notKernel)
+{
+ std::string outputDir(this->GetOutputDirectory(config));
+ std::string outputFilename(this->GetOutputFilename(config));
+
+ if (this->GeneratorTarget->GetType() == cmState::STATIC_LIBRARY)
+ {
+ *this->GetFolderBuildStreams() << " -o \""
+ << outputDir << outputFilename << ".a\""
+ << std::endl;
+ }
+ else if (this->GeneratorTarget->GetType() == cmState::EXECUTABLE)
+ {
+ if (notKernel && !this->IsTargetGroup())
+ {
+ *this->GetFolderBuildStreams() << " -relprog" << std::endl;
+ }
+ if (this->IsTargetGroup())
+ {
+ *this->GetFolderBuildStreams()
+ << " -o \"" << outputDir
+ << outputFilename << ".elf\"" << std::endl;
+ *this->GetFolderBuildStreams() << " :extraOutputFile=\"" << outputDir
+ << outputFilename << ".elf.ael\""
+ << std::endl;
+ }
+ else
+ {
+ *this->GetFolderBuildStreams() << " -o \""
+ << outputDir << outputFilename << ".as\""
+ << std::endl;
+ }
+ }
+}
+
+void cmGhsMultiTargetGenerator::SetCompilerFlags(std::string const &config,
+ const std::string &language,
+ bool const notKernel)
+{
+ std::map<std::string, std::string>::iterator i =
+ this->FlagsByLanguage.find(language);
+ if (i == this->FlagsByLanguage.end())
+ {
+ std::string flags;
+ const char *lang = language.c_str();
+
+ if (notKernel)
+ {
+ this->LocalGenerator->AddLanguageFlags(flags, lang, config);
+ }
+ else
+ {
+ this->LocalGenerator->AddLanguageFlags(
+ flags, lang + std::string("_GHS_KERNEL"), config);
+ }
+ this->LocalGenerator->AddCMP0018Flags(flags, this->GeneratorTarget,
+ lang, config);
+ this->LocalGenerator->AddVisibilityPresetFlags(flags,
+ this->GeneratorTarget,
+ lang);
+
+ // Append old-style preprocessor definition flags.
+ if (std::string(" ") != std::string(this->Makefile->GetDefineFlags()))
+ {
+ this->LocalGenerator->AppendFlags(flags,
+ this->Makefile->GetDefineFlags());
+ }
+
+ // Add target-specific flags.
+ this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget,
+ lang, config);
+
+ std::map<std::string, std::string>::value_type entry(language, flags);
+ i = this->FlagsByLanguage.insert(entry).first;
+ }
+}
+
+std::string cmGhsMultiTargetGenerator::GetDefines(const std::string &language,
+ std::string const &config)
+{
+ std::map<std::string, std::string>::iterator i =
+ this->DefinesByLanguage.find(language);
+ if (i == this->DefinesByLanguage.end())
+ {
+ std::set<std::string> defines;
+ const char *lang = language.c_str();
+ // Add the export symbol definition for shared library objects.
+ if (const char *exportMacro = this->GeneratorTarget->GetExportMacro())
+ {
+ this->LocalGenerator->AppendDefines(defines, exportMacro);
+ }
+
+ // Add preprocessor definitions for this target and configuration.
+ this->LocalGenerator->AddCompileDefinitions(defines,
+ this->GeneratorTarget, config,
+ language);
+
+ std::string definesString;
+ this->LocalGenerator->JoinDefines(defines, definesString, lang);
+
+ std::map<std::string, std::string>::value_type entry(language,
+ definesString);
+ i = this->DefinesByLanguage.insert(entry).first;
+ }
+ return i->second;
+}
+
+void cmGhsMultiTargetGenerator::WriteCompilerFlags(std::string const &,
+ const std::string &language)
+{
+ std::map<std::string, std::string>::iterator flagsByLangI =
+ this->FlagsByLanguage.find(language);
+ if (flagsByLangI != this->FlagsByLanguage.end())
+ {
+ if (!flagsByLangI->second.empty())
+ {
+ *this->GetFolderBuildStreams() << " " << flagsByLangI->second
+ << std::endl;
+ }
+ }
+}
+
+void cmGhsMultiTargetGenerator::WriteCompilerDefinitions(
+ const std::string &config, const std::string &language)
+{
+ std::vector<std::string> compileDefinitions;
+ this->GeneratorTarget->GetCompileDefinitions(compileDefinitions,
+ config, language);
+ for (std::vector<std::string>::const_iterator cdI =
+ compileDefinitions.begin();
+ cdI != compileDefinitions.end(); ++cdI)
+ {
+ *this->GetFolderBuildStreams() << " -D" << (*cdI) << std::endl;
+ }
+}
+
+void cmGhsMultiTargetGenerator::WriteIncludes(const std::string &config,
+ const std::string &language)
+{
+ std::vector<std::string> includes =
+ this->GeneratorTarget->GetIncludeDirectories(config, language);
+ for (std::vector<std::string>::const_iterator includes_i = includes.begin();
+ includes_i != includes.end(); ++includes_i)
+ {
+ *this->GetFolderBuildStreams() << " -I\"" << *includes_i << "\""
+ << std::endl;
+ }
+}
+
+void cmGhsMultiTargetGenerator::WriteTargetLinkLibraries()
+{
+ // library directories
+ cmTargetDependSet tds =
+ this->GetGlobalGenerator()->GetTargetDirectDepends(this->GeneratorTarget);
+ for (cmTargetDependSet::iterator tdsI = tds.begin(); tdsI != tds.end();
+ ++tdsI)
+ {
+ const cmGeneratorTarget *tg = *tdsI;
+ *this->GetFolderBuildStreams() << " -L\"" << GetAbsBuildFilePath(tg)
+ << "\"" << std::endl;
+ }
+ // library targets
+ cmTarget::LinkLibraryVectorType llv =
+ this->GeneratorTarget->Target->GetOriginalLinkLibraries();
+ for (cmTarget::LinkLibraryVectorType::const_iterator llvI = llv.begin();
+ llvI != llv.end(); ++llvI)
+ {
+ std::string libName = llvI->first;
+ // if it is a user defined target get the full path to the lib
+ cmTarget *tg(GetGlobalGenerator()->FindTarget(libName));
+ if (NULL != tg)
+ {
+ libName = tg->GetName() + ".a";
+ }
+ *this->GetFolderBuildStreams() << " -l\"" << libName << "\""
+ << std::endl;
+ }
+}
+
+void cmGhsMultiTargetGenerator::WriteCustomCommands()
+{
+ WriteCustomCommandsHelper(
+ this->GeneratorTarget->GetPreBuildCommands(),
+ cmTarget::PRE_BUILD);
+ WriteCustomCommandsHelper(
+ this->GeneratorTarget->GetPostBuildCommands(),
+ cmTarget::POST_BUILD);
+}
+
+void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper(
+ std::vector<cmCustomCommand> const &commandsSet,
+ cmTarget::CustomCommandType const commandType)
+{
+ for (std::vector<cmCustomCommand>::const_iterator commandsSetI =
+ commandsSet.begin();
+ commandsSetI != commandsSet.end(); ++commandsSetI)
+ {
+ cmCustomCommandLines const &commands = commandsSetI->GetCommandLines();
+ for (cmCustomCommandLines::const_iterator commandI = commands.begin();
+ commandI != commands.end(); ++commandI)
+ {
+ switch (commandType)
+ {
+ case cmTarget::PRE_BUILD:
+ *this->GetFolderBuildStreams() << " :preexecShellSafe=";
+ break;
+ case cmTarget::POST_BUILD:
+ *this->GetFolderBuildStreams() << " :postexecShellSafe=";
+ break;
+ default:
+ assert("Only pre and post are supported");
+ }
+ cmCustomCommandLine const &command = *commandI;
+ for (cmCustomCommandLine::const_iterator commandLineI = command.begin();
+ commandLineI != command.end(); ++commandLineI)
+ {
+ std::string subCommandE =
+ this->LocalGenerator->EscapeForShell(*commandLineI, true);
+ if (!command.empty())
+ {
+ *this->GetFolderBuildStreams()
+ << (command.begin() == commandLineI ? "'" : " ");
+ //Need to double escape backslashes
+ cmSystemTools::ReplaceString(subCommandE, "\\", "\\\\");
+ }
+ *this->GetFolderBuildStreams() << subCommandE;
+ }
+ if (!command.empty())
+ {
+ *this->GetFolderBuildStreams() << "'" << std::endl;
+ }
+ }
+ }
+}
+
+void cmGhsMultiTargetGenerator::WriteSources(
+ std::vector<cmSourceFile *> const &objectSources)
+{
+ for (std::vector<cmSourceFile *>::const_iterator si = objectSources.begin();
+ si != objectSources.end(); ++si)
+ {
+ std::vector<cmSourceGroup> sourceGroups(this->Makefile->GetSourceGroups());
+ char const *sourceFullPath = (*si)->GetFullPath().c_str();
+ cmSourceGroup *sourceGroup =
+ this->Makefile->FindSourceGroup(sourceFullPath, sourceGroups);
+ std::string sgPath(sourceGroup->GetFullName());
+ cmSystemTools::ConvertToUnixSlashes(sgPath);
+ cmGlobalGhsMultiGenerator::AddFilesUpToPath(
+ this->GetFolderBuildStreams(), &this->FolderBuildStreams,
+ this->LocalGenerator->GetBinaryDirectory(), sgPath,
+ GhsMultiGpj::SUBPROJECT, this->RelBuildFilePath);
+
+ std::string fullSourcePath((*si)->GetFullPath());
+ if ((*si)->GetExtension() == "int" || (*si)->GetExtension() == "bsp")
+ {
+ *this->FolderBuildStreams[sgPath] << fullSourcePath << std::endl;
+ }
+ else
+ {
+ //WORKAROUND: GHS MULTI needs the path to use backslashes without quotes
+ // to open files in search as of version 6.1.6
+ cmsys::SystemTools::ReplaceString(fullSourcePath, "/", "\\");
+ *this->FolderBuildStreams[sgPath] << fullSourcePath << std::endl;
+ }
+
+ if ("ld" != (*si)->GetExtension() && "int" != (*si)->GetExtension() &&
+ "bsp" != (*si)->GetExtension())
+ {
+ this->WriteObjectLangOverride(this->FolderBuildStreams[sgPath], (*si));
+
+ this->WriteObjectDir(this->FolderBuildStreams[sgPath],
+ this->AbsBuildFilePath + sgPath);
+ }
+ }
+}
+
+void cmGhsMultiTargetGenerator::WriteObjectLangOverride(
+ cmGeneratedFileStream *fileStream, cmSourceFile *sourceFile)
+{
+ const char *rawLangProp = sourceFile->GetProperty("LANGUAGE");
+ if (NULL != rawLangProp)
+ {
+ std::string sourceLangProp(rawLangProp);
+ std::string extension(sourceFile->GetExtension());
+ if ("CXX" == sourceLangProp && ("c" == extension || "C" == extension))
+ {
+ *fileStream << " -dotciscxx" << std::endl;
+ }
+ }
+}
+
+void cmGhsMultiTargetGenerator::WriteObjectDir(
+ cmGeneratedFileStream *fileStream, std::string const &dir)
+{
+ std::string workingDir(dir);
+ cmSystemTools::ConvertToUnixSlashes(workingDir);
+ if (!workingDir.empty())
+ {
+ workingDir += "/";
+ }
+ workingDir += "Objs";
+ *fileStream << " -object_dir=\"" << workingDir << "\"" << std::endl;
+}
+
+std::string
+cmGhsMultiTargetGenerator::GetOutputDirectory(const std::string &config) const
+{
+ std::string outputDir(AbsBuildFilePath);
+
+ const char *runtimeOutputProp =
+ this->GeneratorTarget->GetProperty("RUNTIME_OUTPUT_DIRECTORY");
+ if (NULL != runtimeOutputProp)
+ {
+ outputDir = runtimeOutputProp;
+ }
+
+ std::string configCapped(cmSystemTools::UpperCase(config));
+ const char *runtimeOutputSProp =
+ this->GeneratorTarget
+ ->GetProperty("RUNTIME_OUTPUT_DIRECTORY_" + configCapped);
+ if (NULL != runtimeOutputSProp)
+ {
+ outputDir = runtimeOutputSProp;
+ }
+ cmSystemTools::ConvertToUnixSlashes(outputDir);
+
+ if (!outputDir.empty())
+ {
+ outputDir += "/";
+ }
+
+ return outputDir;
+}
+
+std::string
+cmGhsMultiTargetGenerator::GetOutputFilename(const std::string &config) const
+{
+ std::string outputFilename(this->GeneratorTarget->GetName());
+
+ const char *outputNameProp =
+ this->GeneratorTarget->GetProperty("OUTPUT_NAME");
+ if (NULL != outputNameProp)
+ {
+ outputFilename = outputNameProp;
+ }
+
+ std::string configCapped(cmSystemTools::UpperCase(config));
+ const char *outputNameSProp =
+ this->GeneratorTarget->GetProperty(configCapped + "_OUTPUT_NAME");
+ if (NULL != outputNameSProp)
+ {
+ outputFilename = outputNameSProp;
+ }
+
+ return outputFilename;
+}
+
+bool cmGhsMultiTargetGenerator::IsNotKernel(std::string const &config,
+ const std::string &language)
+{
+ bool output;
+ std::vector<std::string> options;
+ this->GeneratorTarget->GetCompileOptions(options, config, language);
+ output =
+ options.end() == std::find(options.begin(), options.end(), "-kernel");
+ return output;
+}
+
+bool cmGhsMultiTargetGenerator::DetermineIfTargetGroup(
+ const cmGeneratorTarget *target)
+{
+ bool output = false;
+ std::vector<cmSourceFile *> sources;
+ std::string config =
+ target->Target->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ target->GetSourceFiles(sources, config);
+ for (std::vector<cmSourceFile *>::const_iterator sources_i = sources.begin();
+ sources.end() != sources_i; ++sources_i)
+ {
+ if ("int" == (*sources_i)->GetExtension())
+ {
+ output = true;
+ }
+ }
+ return output;
+}
+
+bool cmGhsMultiTargetGenerator::DetermineIfDynamicDownload(
+ std::string const &config, const std::string &language)
+{
+ std::vector<std::string> options;
+ bool output = false;
+ this->GeneratorTarget->GetCompileOptions(options, config, language);
+ for (std::vector<std::string>::const_iterator options_i = options.begin();
+ options_i != options.end(); ++options_i)
+ {
+ std::string option = *options_i;
+ if (this->DDOption == option)
+ {
+ output = true;
+ }
+ }
+ return output;
+}
diff --git a/Source/cmGhsMultiTargetGenerator.h b/Source/cmGhsMultiTargetGenerator.h
new file mode 100644
index 000000000..327fdefc9
--- /dev/null
+++ b/Source/cmGhsMultiTargetGenerator.h
@@ -0,0 +1,119 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Geoffrey Viola <geoffrey.viola@asirobots.com>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmGhsMultiTargetGenerator_h
+#define cmGhsMultiTargetGenerator_h
+
+#include "cmStandardIncludes.h"
+#include "cmTarget.h"
+#include "cmGhsMultiGpj.h"
+
+class cmGeneratedFileStream;
+class cmGlobalGhsMultiGenerator;
+class cmLocalGhsMultiGenerator;
+class cmMakefile;
+class cmSourceFile;
+class cmGeneratedFileStream;
+class cmCustomCommand;
+
+class cmGhsMultiTargetGenerator
+{
+public:
+ cmGhsMultiTargetGenerator(cmGeneratorTarget* target);
+
+ virtual ~cmGhsMultiTargetGenerator();
+
+ virtual void Generate();
+
+ bool IncludeThisTarget();
+ std::vector<cmSourceFile *> GetSources() const;
+ GhsMultiGpj::Types GetGpjTag() const;
+ static GhsMultiGpj::Types GetGpjTag(const cmGeneratorTarget* target);
+ const char *GetAbsBuildFilePath() const
+ {
+ return this->AbsBuildFilePath.c_str();
+ }
+ const char *GetRelBuildFileName() const
+ {
+ return this->RelBuildFileName.c_str();
+ }
+ const char *GetAbsBuildFileName() const
+ {
+ return this->AbsBuildFileName.c_str();
+ }
+ const char *GetAbsOutputFileName() const
+ {
+ return this->AbsOutputFileName.c_str();
+ }
+
+ static std::string GetRelBuildFilePath(const cmGeneratorTarget *target);
+ static std::string GetAbsPathToRoot(const cmGeneratorTarget *target);
+ static std::string GetAbsBuildFilePath(const cmGeneratorTarget *target);
+ static std::string GetRelBuildFileName(const cmGeneratorTarget *target);
+ static std::string GetBuildFileName(const cmGeneratorTarget *target);
+ static std::string AddSlashIfNeededToPath(std::string const &input);
+
+private:
+ cmGlobalGhsMultiGenerator *GetGlobalGenerator() const;
+ cmGeneratedFileStream *GetFolderBuildStreams()
+ {
+ return this->FolderBuildStreams[""];
+ };
+ bool IsTargetGroup() const { return this->TargetGroup; }
+
+ void WriteTypeSpecifics(const std::string &config, bool notKernel);
+ void WriteCompilerFlags(const std::string &config,
+ const std::string &language);
+ void WriteCompilerDefinitions(const std::string &config,
+ const std::string &language);
+
+ void SetCompilerFlags(std::string const &config, const std::string &language,
+ bool const notKernel);
+ std::string GetDefines(const std::string &langugae,
+ std::string const &config);
+
+ void WriteIncludes(const std::string &config, const std::string &language);
+ void WriteTargetLinkLibraries();
+ void WriteCustomCommands();
+ void
+ WriteCustomCommandsHelper(std::vector<cmCustomCommand> const &commandsSet,
+ cmTarget::CustomCommandType commandType);
+ void WriteSources(std::vector<cmSourceFile *> const &objectSources);
+ static void WriteObjectLangOverride(cmGeneratedFileStream *fileStream,
+ cmSourceFile *sourceFile);
+ static void WriteObjectDir(cmGeneratedFileStream *fileStream,
+ std::string const &dir);
+ std::string GetOutputDirectory(const std::string &config) const;
+ std::string GetOutputFilename(const std::string &config) const;
+
+ bool IsNotKernel(std::string const &config, const std::string &language);
+ static bool DetermineIfTargetGroup(const cmGeneratorTarget* target);
+ bool DetermineIfDynamicDownload(std::string const &config,
+ const std::string &language);
+
+ cmGeneratorTarget* GeneratorTarget;
+ cmLocalGhsMultiGenerator *LocalGenerator;
+ cmMakefile *Makefile;
+ std::string AbsBuildFilePath;
+ std::string RelBuildFilePath;
+ std::string AbsBuildFileName;
+ std::string RelBuildFileName;
+ std::string RelOutputFileName;
+ std::string AbsOutputFileName;
+ std::map<std::string, cmGeneratedFileStream *> FolderBuildStreams;
+ bool TargetGroup;
+ bool DynamicDownload;
+ static std::string const DDOption;
+ std::map<std::string, std::string> FlagsByLanguage;
+ std::map<std::string, std::string> DefinesByLanguage;
+};
+
+#endif // ! cmGhsMultiTargetGenerator_h
diff --git a/Source/cmGlobalBorlandMakefileGenerator.cxx b/Source/cmGlobalBorlandMakefileGenerator.cxx
index 2a7d61d6a..40e8d2901 100644
--- a/Source/cmGlobalBorlandMakefileGenerator.cxx
+++ b/Source/cmGlobalBorlandMakefileGenerator.cxx
@@ -14,13 +14,19 @@
#include "cmMakefile.h"
#include "cmake.h"
-cmGlobalBorlandMakefileGenerator::cmGlobalBorlandMakefileGenerator()
+cmGlobalBorlandMakefileGenerator::cmGlobalBorlandMakefileGenerator(cmake* cm)
+ : cmGlobalUnixMakefileGenerator3(cm)
{
this->EmptyRuleHackDepends = "NUL";
this->FindMakeProgramFile = "CMakeBorlandFindMake.cmake";
this->ForceUnixPaths = false;
this->ToolSupportsColor = true;
this->UseLinkScript = false;
+ cm->GetState()->SetWindowsShell(true);
+ this->IncludeDirective = "!include";
+ this->DefineWindowsNULL = true;
+ this->PassMakeflags = true;
+ this->UnixCD = false;
}
@@ -29,7 +35,7 @@ void cmGlobalBorlandMakefileGenerator
cmMakefile *mf,
bool optional)
{
- std::string outdir = this->CMakeInstance->GetStartOutputDirectory();
+ std::string outdir = this->CMakeInstance->GetHomeOutputDirectory();
mf->AddDefinition("BORLAND", "1");
mf->AddDefinition("CMAKE_GENERATOR_CC", "bcc32");
mf->AddDefinition("CMAKE_GENERATOR_CXX", "bcc32");
@@ -37,16 +43,12 @@ void cmGlobalBorlandMakefileGenerator
}
///! Create a local generator appropriate to this Global Generator
-cmLocalGenerator *cmGlobalBorlandMakefileGenerator::CreateLocalGenerator()
+cmLocalGenerator *cmGlobalBorlandMakefileGenerator::CreateLocalGenerator(
+ cmMakefile *mf)
{
- cmLocalUnixMakefileGenerator3* lg = new cmLocalUnixMakefileGenerator3;
- lg->SetIncludeDirective("!include");
- lg->SetWindowsShell(true);
- lg->SetDefineWindowsNULL(true);
+ cmLocalUnixMakefileGenerator3* lg =
+ new cmLocalUnixMakefileGenerator3(this, mf);
lg->SetMakefileVariableSize(32);
- lg->SetPassMakeflags(true);
- lg->SetGlobalGenerator(this);
- lg->SetUnixCD(false);
lg->SetMakeCommandEscapeTargetTwice(true);
lg->SetBorlandMakeCurlyHack(true);
return lg;
@@ -59,5 +61,4 @@ void cmGlobalBorlandMakefileGenerator
{
entry.Name = cmGlobalBorlandMakefileGenerator::GetActualName();
entry.Brief = "Generates Borland makefiles.";
- entry.Full = "";
}
diff --git a/Source/cmGlobalBorlandMakefileGenerator.h b/Source/cmGlobalBorlandMakefileGenerator.h
index bd3db3eae..b59c86d56 100644
--- a/Source/cmGlobalBorlandMakefileGenerator.h
+++ b/Source/cmGlobalBorlandMakefileGenerator.h
@@ -19,31 +19,34 @@
*
* cmGlobalBorlandMakefileGenerator manages nmake build process for a tree
*/
-class cmGlobalBorlandMakefileGenerator : public cmGlobalNMakeMakefileGenerator
+class cmGlobalBorlandMakefileGenerator : public cmGlobalUnixMakefileGenerator3
{
public:
- cmGlobalBorlandMakefileGenerator();
+ cmGlobalBorlandMakefileGenerator(cmake* cm);
static cmGlobalGeneratorFactory* NewFactory() {
return new cmGlobalGeneratorSimpleFactory
<cmGlobalBorlandMakefileGenerator>(); }
///! Get the name for the generator.
- virtual const char* GetName() const {
+ virtual std::string GetName() const {
return cmGlobalBorlandMakefileGenerator::GetActualName();}
- static const char* GetActualName() {return "Borland Makefiles";}
+ static std::string GetActualName() {return "Borland Makefiles";}
/** Get the documentation entry for this generator. */
static void GetDocumentation(cmDocumentationEntry& entry);
///! Create a local generator appropriate to this Global Generator
- virtual cmLocalGenerator *CreateLocalGenerator();
+ virtual cmLocalGenerator *CreateLocalGenerator(cmMakefile* mf);
/**
- * Try to determine system infomation such as shared library
+ * Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
cmMakefile *, bool optional);
+
+ virtual bool AllowNotParallel() const { return false; }
+ virtual bool AllowDeleteOnError() const { return false; }
};
#endif
diff --git a/Source/cmGlobalCommonGenerator.cxx b/Source/cmGlobalCommonGenerator.cxx
new file mode 100644
index 000000000..dc8e5a7ff
--- /dev/null
+++ b/Source/cmGlobalCommonGenerator.cxx
@@ -0,0 +1,21 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmGlobalCommonGenerator.h"
+
+cmGlobalCommonGenerator::cmGlobalCommonGenerator(cmake* cm):
+ cmGlobalGenerator(cm)
+{
+}
+
+cmGlobalCommonGenerator::~cmGlobalCommonGenerator()
+{
+}
diff --git a/Source/cmGlobalCommonGenerator.h b/Source/cmGlobalCommonGenerator.h
new file mode 100644
index 000000000..7bb0e55a0
--- /dev/null
+++ b/Source/cmGlobalCommonGenerator.h
@@ -0,0 +1,27 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmGlobalCommonGenerator_h
+#define cmGlobalCommonGenerator_h
+
+#include "cmGlobalGenerator.h"
+
+/** \class cmGlobalCommonGenerator
+ * \brief Common infrastructure for Makefile and Ninja global generators.
+ */
+class cmGlobalCommonGenerator : public cmGlobalGenerator
+{
+public:
+ cmGlobalCommonGenerator(cmake* cm);
+ ~cmGlobalCommonGenerator();
+};
+
+#endif
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index f297c4abb..848028ff3 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -11,14 +11,18 @@
============================================================================*/
#if defined(_WIN32) && !defined(__CYGWIN__)
#include "windows.h" // this must be first to define GetCurrentDirectory
+#if defined(_MSC_VER) && _MSC_VER >= 1800
+# define KWSYS_WINDOWS_DEPRECATED_GetVersionEx
+#endif
#endif
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmExternalMakefileProjectGenerator.h"
#include "cmake.h"
+#include "cmState.h"
#include "cmMakefile.h"
-#include "cmQtAutomoc.h"
+#include "cmQtAutoGeneratorInitializer.h"
#include "cmSourceFile.h"
#include "cmVersion.h"
#include "cmTargetExport.h"
@@ -26,19 +30,38 @@
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGeneratorExpression.h"
-#include "cmGeneratorExpressionEvaluationFile.h"
+#include "cmExportBuildFileGenerator.h"
+#include "cmCPackPropertiesGenerator.h"
+#include "cmAlgorithms.h"
+#include "cmInstallGenerator.h"
#include <cmsys/Directory.hxx>
+#include <cmsys/FStream.hxx>
#if defined(CMAKE_BUILD_WITH_CMAKE)
# include <cmsys/MD5.h>
+# include "cm_jsoncpp_value.h"
+# include "cm_jsoncpp_writer.h"
#endif
#include <stdlib.h> // required for atof
#include <assert.h>
-cmGlobalGenerator::cmGlobalGenerator()
+bool cmTarget::StrictTargetComparison::operator()(cmTarget const* t1,
+ cmTarget const* t2) const
+{
+ int nameResult = strcmp(t1->GetName().c_str(), t2->GetName().c_str());
+ if (nameResult == 0)
+ {
+ return strcmp(t1->GetMakefile()->GetCurrentBinaryDirectory(),
+ t2->GetMakefile()->GetCurrentBinaryDirectory()) < 0;
+ }
+ return nameResult < 0;
+}
+
+cmGlobalGenerator::cmGlobalGenerator(cmake* cm)
+ : CMakeInstance(cm)
{
// By default the .SYMBOLIC dependency is not needed on symbolic rules.
this->NeedSymbolicMark = false;
@@ -59,57 +82,97 @@ cmGlobalGenerator::cmGlobalGenerator()
this->TryCompileTimeout = 0;
this->ExtraGenerator = 0;
- this->CurrentLocalGenerator = 0;
+ this->CurrentMakefile = 0;
this->TryCompileOuterMakefile = 0;
+
+ this->ConfigureDoneCMP0026AndCMP0024 = false;
+
+ cm->GetState()->SetMinGWMake(false);
+ cm->GetState()->SetMSYSShell(false);
+ cm->GetState()->SetNMake(false);
+ cm->GetState()->SetWatcomWMake(false);
+ cm->GetState()->SetWindowsShell(false);
+ cm->GetState()->SetWindowsVSIDE(false);
}
cmGlobalGenerator::~cmGlobalGenerator()
{
- // Delete any existing cmLocalGenerators
- for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i)
- {
- delete this->LocalGenerators[i];
- }
- for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator
- li = this->EvaluationFiles.begin();
- li != this->EvaluationFiles.end();
- ++li)
- {
- delete *li;
- }
- this->LocalGenerators.clear();
+ this->ClearGeneratorMembers();
+ delete this->ExtraGenerator;
+}
- if (this->ExtraGenerator)
+bool cmGlobalGenerator::SetGeneratorPlatform(std::string const& p,
+ cmMakefile* mf)
+{
+ if(p.empty())
{
- delete this->ExtraGenerator;
+ return true;
}
- this->ClearGeneratorTargets();
+ std::ostringstream e;
+ e <<
+ "Generator\n"
+ " " << this->GetName() << "\n"
+ "does not support platform specification, but platform\n"
+ " " << p << "\n"
+ "was specified.";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
}
-bool cmGlobalGenerator::SetGeneratorToolset(std::string const& ts)
+bool cmGlobalGenerator::SetGeneratorToolset(std::string const& ts,
+ cmMakefile* mf)
{
- cmOStringStream e;
+ if(ts.empty())
+ {
+ return true;
+ }
+ std::ostringstream e;
e <<
"Generator\n"
" " << this->GetName() << "\n"
"does not support toolset specification, but toolset\n"
" " << ts << "\n"
"was specified.";
- this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
- cmListFileBacktrace());
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
return false;
}
+std::string cmGlobalGenerator::SelectMakeProgram(
+ const std::string& inMakeProgram,
+ const std::string& makeDefault) const
+{
+ std::string makeProgram = inMakeProgram;
+ if(cmSystemTools::IsOff(makeProgram.c_str()))
+ {
+ const char* makeProgramCSTR =
+ this->CMakeInstance->GetCacheDefinition("CMAKE_MAKE_PROGRAM");
+ if(cmSystemTools::IsOff(makeProgramCSTR))
+ {
+ makeProgram = makeDefault;
+ }
+ else
+ {
+ makeProgram = makeProgramCSTR;
+ }
+ if(cmSystemTools::IsOff(makeProgram.c_str()) &&
+ !makeProgram.empty())
+ {
+ makeProgram = "CMAKE_MAKE_PROGRAM-NOTFOUND";
+ }
+ }
+ return makeProgram;
+}
+
void cmGlobalGenerator::ResolveLanguageCompiler(const std::string &lang,
cmMakefile *mf,
- bool optional)
+ bool optional) const
{
std::string langComp = "CMAKE_";
langComp += lang;
langComp += "_COMPILER";
- if(!mf->GetDefinition(langComp.c_str()))
+ if(!mf->GetDefinition(langComp))
{
if(!optional)
{
@@ -118,7 +181,7 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string &lang,
}
return;
}
- const char* name = mf->GetRequiredDefinition(langComp.c_str());
+ const char* name = mf->GetRequiredDefinition(langComp);
std::string path;
if(!cmSystemTools::FileIsFullPath(name))
{
@@ -128,27 +191,25 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string &lang,
{
path = name;
}
- if((path.size() == 0 || !cmSystemTools::FileExists(path.c_str()))
+ if((path.empty() || !cmSystemTools::FileExists(path.c_str()))
&& (optional==false))
{
- std::string message = "your ";
- message += lang;
- message += " compiler: \"";
- message += name;
- message += "\" was not found. Please set ";
- message += langComp;
- message += " to a valid compiler path or name.";
- cmSystemTools::Error(message.c_str());
- path = name;
+ return;
}
- std::string doc = lang;
- doc += " compiler.";
const char* cname = this->GetCMakeInstance()->
- GetCacheManager()->GetCacheValue(langComp.c_str());
+ GetState()->GetInitializedCacheValue(langComp);
std::string changeVars;
- if(cname && (path != cname) && (optional==false))
+ if(cname && !optional)
{
- std::string cnameString = cname;
+ std::string cnameString;
+ if(!cmSystemTools::FileIsFullPath(cname))
+ {
+ cnameString = cmSystemTools::FindProgram(cname);
+ }
+ else
+ {
+ cnameString = cname;
+ }
std::string pathString = path;
// get rid of potentially multiple slashes:
cmSystemTools::ConvertToUnixSlashes(cnameString);
@@ -156,7 +217,7 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string &lang,
if (cnameString != pathString)
{
const char* cvars =
- this->GetCMakeInstance()->GetProperty(
+ this->GetCMakeInstance()->GetState()->GetGlobalProperty(
"__CMAKE_DELETE_CACHE_CHANGE_VARS_");
if(cvars)
{
@@ -166,19 +227,72 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string &lang,
changeVars += langComp;
changeVars += ";";
changeVars += cname;
- this->GetCMakeInstance()->SetProperty(
+ this->GetCMakeInstance()->GetState()->SetGlobalProperty(
"__CMAKE_DELETE_CACHE_CHANGE_VARS_",
changeVars.c_str());
}
}
- mf->AddCacheDefinition(langComp.c_str(), path.c_str(),
- doc.c_str(), cmCacheManager::FILEPATH);
+}
+
+void cmGlobalGenerator::AddBuildExportSet(cmExportBuildFileGenerator* gen)
+{
+ this->BuildExportSets[gen->GetMainExportFileName()] = gen;
+}
+
+void
+cmGlobalGenerator::AddBuildExportExportSet(cmExportBuildFileGenerator* gen)
+{
+ this->BuildExportSets[gen->GetMainExportFileName()] = gen;
+ this->BuildExportExportSets[gen->GetMainExportFileName()] = gen;
+}
+
+bool cmGlobalGenerator::GenerateImportFile(const std::string &file)
+{
+ std::map<std::string, cmExportBuildFileGenerator*>::iterator it
+ = this->BuildExportSets.find(file);
+ if (it != this->BuildExportSets.end())
+ {
+ bool result = it->second->GenerateImportFile();
+
+ if (!this->ConfigureDoneCMP0026AndCMP0024)
+ {
+ for (std::vector<cmMakefile*>::const_iterator mit =
+ this->Makefiles.begin(); mit != this->Makefiles.end(); ++mit)
+ {
+ (*mit)->RemoveExportBuildFileGeneratorCMP0024(it->second);
+ }
+ }
+
+ delete it->second;
+ it->second = 0;
+ this->BuildExportSets.erase(it);
+ return result;
+ }
+ return false;
+}
+
+void cmGlobalGenerator::ForceLinkerLanguages()
+{
+
+}
+
+bool
+cmGlobalGenerator::IsExportedTargetsFile(const std::string &filename) const
+{
+ const std::map<std::string, cmExportBuildFileGenerator*>::const_iterator it
+ = this->BuildExportSets.find(filename);
+ if (it == this->BuildExportSets.end())
+ {
+ return false;
+ }
+ return this->BuildExportExportSets.find(filename)
+ == this->BuildExportExportSets.end();
}
// Find the make program for the generator, required for try compiles
void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf)
{
- if(this->FindMakeProgramFile.size() == 0)
+ if(this->FindMakeProgramFile.empty())
{
cmSystemTools::Error(
"Generator implementation error, "
@@ -189,15 +303,15 @@ void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf)
{
std::string setMakeProgram =
mf->GetModulesFile(this->FindMakeProgramFile.c_str());
- if(setMakeProgram.size())
+ if(!setMakeProgram.empty())
{
- mf->ReadListFile(0, setMakeProgram.c_str());
+ mf->ReadListFile(setMakeProgram.c_str());
}
}
if(!mf->GetDefinition("CMAKE_MAKE_PROGRAM")
|| cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM")))
{
- cmOStringStream err;
+ std::ostringstream err;
err << "CMake was unable to find a build program corresponding to \""
<< this->GetName() << "\". CMAKE_MAKE_PROGRAM is not set. You "
<< "probably need to select a different build tool.";
@@ -213,37 +327,18 @@ void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf)
{
std::string dir;
std::string file;
- cmSystemTools::SplitProgramPath(makeProgram.c_str(),
+ cmSystemTools::SplitProgramPath(makeProgram,
dir, file);
std::string saveFile = file;
- cmSystemTools::GetShortPath(makeProgram.c_str(), makeProgram);
- cmSystemTools::SplitProgramPath(makeProgram.c_str(),
+ cmSystemTools::GetShortPath(makeProgram, makeProgram);
+ cmSystemTools::SplitProgramPath(makeProgram,
dir, file);
makeProgram = dir;
makeProgram += "/";
makeProgram += saveFile;
mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", makeProgram.c_str(),
"make program",
- cmCacheManager::FILEPATH);
- }
-
- if(makeProgram.find("xcodebuild") != makeProgram.npos)
- {
- // due to the text file busy /bin/sh problem with xcodebuild
- // use the cmakexbuild wrapper instead. This program
- // will run xcodebuild and if it sees the error text file busy
- // it will stop forwarding output, and let the build finish.
- // Then it will retry the build. It will continue this
- // untill no text file busy errors occur.
- std::string cmakexbuild =
- this->CMakeInstance->GetCacheManager()->GetCacheValue("CMAKE_COMMAND");
- cmakexbuild = cmakexbuild.substr(0, cmakexbuild.length()-5);
- cmakexbuild += "cmakexbuild";
-
- mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM",
- cmakexbuild.c_str(),
- "make program",
- cmCacheManager::FILEPATH);
+ cmState::FILEPATH);
}
}
@@ -260,6 +355,9 @@ void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf)
// CMakeSystem.cmake - configured file created by
// CMakeDetermineSystem.cmake IF CMAKE_SYSTEM_LOADED
+// CMakeSystemSpecificInitialize.cmake
+// - includes Platform/${CMAKE_SYSTEM_NAME}-Initialize.cmake
+
// Next try and enable all languages found in the languages vector
//
// FOREACH LANG in languages
@@ -291,9 +389,9 @@ void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf)
void
cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
- cmMakefile *mf, bool)
+ cmMakefile *mf, bool optional)
{
- if(languages.size() == 0)
+ if(languages.empty())
{
cmSystemTools::Error("EnableLanguage must have a lang specified!");
cmSystemTools::SetFatalErrorOccured();
@@ -315,7 +413,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
const char* lang = li->c_str();
if(this->LanguagesReady.find(lang) == this->LanguagesReady.end())
{
- cmOStringStream e;
+ std::ostringstream e;
e << "The test project needs language "
<< lang << " which is not enabled.";
this->TryCompileOuterMakefile
@@ -327,14 +425,16 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
}
}
+ bool fatalError = false;
+
mf->AddDefinition("RUN_CONFIGURE", true);
- std::string rootBin = mf->GetHomeOutputDirectory();
+ std::string rootBin = this->CMakeInstance->GetHomeOutputDirectory();
rootBin += cmake::GetCMakeFilesDirectory();
// If the configuration files path has been set,
// then we are in a try compile and need to copy the enable language
// files from the parent cmake bin dir, into the try compile bin dir
- if(this->ConfiguredFilesPath.size())
+ if(!this->ConfiguredFilesPath.empty())
{
rootBin = this->ConfiguredFilesPath;
}
@@ -349,12 +449,13 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
// try and load the CMakeSystem.cmake if it is there
std::string fpath = rootBin;
- if(!mf->GetDefinition("CMAKE_SYSTEM_LOADED"))
+ bool const readCMakeSystem = !mf->GetDefinition("CMAKE_SYSTEM_LOADED");
+ if(readCMakeSystem)
{
fpath += "/CMakeSystem.cmake";
if(cmSystemTools::FileExists(fpath.c_str()))
{
- mf->ReadListFile(0,fpath.c_str());
+ mf->ReadListFile(fpath.c_str());
}
}
// Load the CMakeDetermineSystem.cmake file and find out
@@ -363,27 +464,76 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
{
#if defined(_WIN32) && !defined(__CYGWIN__)
/* Windows version number data. */
- OSVERSIONINFO osvi;
- ZeroMemory(&osvi, sizeof(osvi));
- osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- GetVersionEx (&osvi);
- cmOStringStream windowsVersionString;
- windowsVersionString << osvi.dwMajorVersion << "." << osvi.dwMinorVersion;
+ OSVERSIONINFOEXW osviex;
+ ZeroMemory(&osviex, sizeof(osviex));
+ osviex.dwOSVersionInfoSize = sizeof(osviex);
+
+#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
+# pragma warning (push)
+# pragma warning (disable:4996)
+#endif
+ GetVersionExW((OSVERSIONINFOW*)&osviex);
+#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
+# pragma warning (pop)
+#endif
+ std::ostringstream windowsVersionString;
+ windowsVersionString << osviex.dwMajorVersion << "."
+ << osviex.dwMinorVersion << "."
+ << osviex.dwBuildNumber;
windowsVersionString.str();
mf->AddDefinition("CMAKE_HOST_SYSTEM_VERSION",
windowsVersionString.str().c_str());
#endif
// Read the DetermineSystem file
std::string systemFile = mf->GetModulesFile("CMakeDetermineSystem.cmake");
- mf->ReadListFile(0, systemFile.c_str());
+ mf->ReadListFile(systemFile.c_str());
// load the CMakeSystem.cmake from the binary directory
// this file is configured by the CMakeDetermineSystem.cmake file
fpath = rootBin;
fpath += "/CMakeSystem.cmake";
- mf->ReadListFile(0,fpath.c_str());
+ mf->ReadListFile(fpath.c_str());
+ }
+
+ if(readCMakeSystem)
+ {
+ // Tell the generator about the target system.
+ std::string system = mf->GetSafeDefinition("CMAKE_SYSTEM_NAME");
+ if(!this->SetSystemName(system, mf))
+ {
+ cmSystemTools::SetFatalErrorOccured();
+ return;
+ }
+
+ // Tell the generator about the platform, if any.
+ std::string platform = mf->GetSafeDefinition("CMAKE_GENERATOR_PLATFORM");
+ if(!this->SetGeneratorPlatform(platform, mf))
+ {
+ cmSystemTools::SetFatalErrorOccured();
+ return;
+ }
+
+ // Tell the generator about the toolset, if any.
+ std::string toolset = mf->GetSafeDefinition("CMAKE_GENERATOR_TOOLSET");
+ if(!this->SetGeneratorToolset(toolset, mf))
+ {
+ cmSystemTools::SetFatalErrorOccured();
+ return;
+ }
}
- std::map<cmStdString, bool> needTestLanguage;
- std::map<cmStdString, bool> needSetLanguageEnabledMaps;
+
+ // **** Load the system specific initialization if not yet loaded
+ if (!mf->GetDefinition("CMAKE_SYSTEM_SPECIFIC_INITIALIZE_LOADED"))
+ {
+ fpath = mf->GetModulesFile("CMakeSystemSpecificInitialize.cmake");
+ if(!mf->ReadListFile(fpath.c_str()))
+ {
+ cmSystemTools::Error("Could not find cmake module file: "
+ "CMakeSystemSpecificInitialize.cmake");
+ }
+ }
+
+ std::map<std::string, bool> needTestLanguage;
+ std::map<std::string, bool> needSetLanguageEnabledMaps;
// foreach language
// load the CMakeDetermine(LANG)Compiler.cmake file to find
// the compiler
@@ -401,7 +551,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
std::string loadedLang = "CMAKE_";
loadedLang += lang;
loadedLang += "_COMPILER_LOADED";
- if(!mf->GetDefinition(loadedLang.c_str()))
+ if(!mf->GetDefinition(loadedLang))
{
fpath = rootBin;
fpath += "/CMake";
@@ -413,7 +563,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
// to avoid duplicate compiler tests.
if(cmSystemTools::FileExists(fpath.c_str()))
{
- if(!mf->ReadListFile(0,fpath.c_str()))
+ if(!mf->ReadListFile(fpath.c_str()))
{
cmSystemTools::Error("Could not find cmake module file: ",
fpath.c_str());
@@ -443,10 +593,14 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
determineCompiler += "Compiler.cmake";
std::string determineFile =
mf->GetModulesFile(determineCompiler.c_str());
- if(!mf->ReadListFile(0,determineFile.c_str()))
+ if(!mf->ReadListFile(determineFile.c_str()))
{
cmSystemTools::Error("Could not find cmake module file: ",
- determineFile.c_str());
+ determineCompiler.c_str());
+ }
+ if (cmSystemTools::GetFatalErrorOccured())
+ {
+ return;
}
needTestLanguage[lang] = true;
// Some generators like visual studio should not use the env variables
@@ -462,13 +616,13 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
std::string compilerEnv = "CMAKE_";
compilerEnv += lang;
compilerEnv += "_COMPILER_ENV_VAR";
- std::string envVar = mf->GetRequiredDefinition(compilerEnv.c_str());
+ std::string envVar = mf->GetRequiredDefinition(compilerEnv);
std::string envVarValue =
- mf->GetRequiredDefinition(compilerName.c_str());
+ mf->GetRequiredDefinition(compilerName);
std::string env = envVar;
env += "=";
env += envVarValue;
- cmSystemTools::PutEnv(env.c_str());
+ cmSystemTools::PutEnv(env);
}
// if determineLanguage was called then load the file it
@@ -477,7 +631,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
fpath += "/CMake";
fpath += lang;
fpath += "Compiler.cmake";
- if(!mf->ReadListFile(0,fpath.c_str()))
+ if(!mf->ReadListFile(fpath.c_str()))
{
cmSystemTools::Error("Could not find cmake module file: ",
fpath.c_str());
@@ -496,10 +650,10 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
if (!mf->GetDefinition("CMAKE_SYSTEM_SPECIFIC_INFORMATION_LOADED"))
{
fpath = mf->GetModulesFile("CMakeSystemSpecificInformation.cmake");
- if(!mf->ReadListFile(0,fpath.c_str()))
+ if(!mf->ReadListFile(fpath.c_str()))
{
- cmSystemTools::Error("Could not find cmake module file: ",
- fpath.c_str());
+ cmSystemTools::Error("Could not find cmake module file: "
+ "CMakeSystemSpecificInformation.cmake");
}
}
// loop over languages again loading CMake(LANG)Information.cmake
@@ -513,10 +667,70 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
this->SetLanguageEnabled("NONE", mf);
continue;
}
+
+ // Check that the compiler was found.
+ std::string compilerName = "CMAKE_";
+ compilerName += lang;
+ compilerName += "_COMPILER";
+ std::string compilerEnv = "CMAKE_";
+ compilerEnv += lang;
+ compilerEnv += "_COMPILER_ENV_VAR";
+ std::ostringstream noCompiler;
+ const char* compilerFile = mf->GetDefinition(compilerName);
+ if(!compilerFile || !*compilerFile ||
+ cmSystemTools::IsNOTFOUND(compilerFile))
+ {
+ noCompiler <<
+ "No " << compilerName << " could be found.\n"
+ ;
+ }
+ else if(strcmp(lang, "RC") != 0 &&
+ strcmp(lang, "ASM_MASM") != 0)
+ {
+ if(!cmSystemTools::FileIsFullPath(compilerFile))
+ {
+ noCompiler <<
+ "The " << compilerName << ":\n"
+ " " << compilerFile << "\n"
+ "is not a full path and was not found in the PATH.\n"
+ ;
+ }
+ else if(!cmSystemTools::FileExists(compilerFile))
+ {
+ noCompiler <<
+ "The " << compilerName << ":\n"
+ " " << compilerFile << "\n"
+ "is not a full path to an existing compiler tool.\n"
+ ;
+ }
+ }
+ if(!noCompiler.str().empty())
+ {
+ // Skip testing this language since the compiler is not found.
+ needTestLanguage[lang] = false;
+ if(!optional)
+ {
+ // The compiler was not found and it is not optional. Remove
+ // CMake(LANG)Compiler.cmake so we try again next time CMake runs.
+ std::string compilerLangFile = rootBin;
+ compilerLangFile += "/CMake";
+ compilerLangFile += lang;
+ compilerLangFile += "Compiler.cmake";
+ cmSystemTools::RemoveFile(compilerLangFile);
+ if(!this->CMakeInstance->GetIsInTryCompile())
+ {
+ this->PrintCompilerAdvice(noCompiler, lang,
+ mf->GetDefinition(compilerEnv));
+ mf->IssueMessage(cmake::FATAL_ERROR, noCompiler.str());
+ fatalError = true;
+ }
+ }
+ }
+
std::string langLoadedVar = "CMAKE_";
langLoadedVar += lang;
langLoadedVar += "_INFORMATION_LOADED";
- if (!mf->GetDefinition(langLoadedVar.c_str()))
+ if (!mf->GetDefinition(langLoadedVar))
{
fpath = "CMake";
fpath += lang;
@@ -527,7 +741,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
cmSystemTools::Error("Could not find cmake module file: ",
fpath.c_str());
}
- else if(!mf->ReadListFile(0, informationFile.c_str()))
+ else if(!mf->ReadListFile(informationFile.c_str()))
{
cmSystemTools::Error("Could not process cmake module file: ",
informationFile.c_str());
@@ -539,26 +753,12 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
}
this->LanguagesReady.insert(lang);
- std::string compilerName = "CMAKE_";
- compilerName += lang;
- compilerName += "_COMPILER";
- std::string compilerLangFile = rootBin;
- compilerLangFile += "/CMake";
- compilerLangFile += lang;
- compilerLangFile += "Compiler.cmake";
// Test the compiler for the language just setup
// (but only if a compiler has been actually found)
// At this point we should have enough info for a try compile
// which is used in the backward stuff
// If the language is untested then test it now with a try compile.
- if (!mf->IsSet(compilerName.c_str()))
- {
- // if the compiler did not work, then remove the
- // CMake(LANG)Compiler.cmake file so that it will get tested the
- // next time cmake is run
- cmSystemTools::RemoveFile(compilerLangFile.c_str());
- }
- else if(needTestLanguage[lang])
+ if(needTestLanguage[lang])
{
if (!this->CMakeInstance->GetIsInTryCompile())
{
@@ -566,10 +766,10 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
testLang += lang;
testLang += "Compiler.cmake";
std::string ifpath = mf->GetModulesFile(testLang.c_str());
- if(!mf->ReadListFile(0,ifpath.c_str()))
+ if(!mf->ReadListFile(ifpath.c_str()))
{
cmSystemTools::Error("Could not find cmake module file: ",
- ifpath.c_str());
+ testLang.c_str());
}
std::string compilerWorks = "CMAKE_";
compilerWorks += lang;
@@ -577,32 +777,13 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
// if the compiler did not work, then remove the
// CMake(LANG)Compiler.cmake file so that it will get tested the
// next time cmake is run
- if(!mf->IsOn(compilerWorks.c_str()))
- {
- cmSystemTools::RemoveFile(compilerLangFile.c_str());
- }
- else
+ if(!mf->IsOn(compilerWorks))
{
- // load backwards compatibility stuff for C and CXX
- // for old versions of CMake ListFiles C and CXX had some
- // backwards compatibility files they have to load
- // These files have a bunch of try compiles in them so
- // should only be done
- if (mf->NeedBackwardsCompatibility(1,4))
- {
- if(strcmp(lang, "C") == 0)
- {
- ifpath =
- mf->GetModulesFile("CMakeBackwardCompatibilityC.cmake");
- mf->ReadListFile(0,ifpath.c_str());
- }
- if(strcmp(lang, "CXX") == 0)
- {
- ifpath =
- mf->GetModulesFile("CMakeBackwardCompatibilityCXX.cmake");
- mf->ReadListFile(0,ifpath.c_str());
- }
- }
+ std::string compilerLangFile = rootBin;
+ compilerLangFile += "/CMake";
+ compilerLangFile += lang;
+ compilerLangFile += "Compiler.cmake";
+ cmSystemTools::RemoveFile(compilerLangFile);
}
} // end if in try compile
} // end need test language
@@ -611,11 +792,14 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
sharedLibFlagsVar += lang;
sharedLibFlagsVar += "_FLAGS";
const char* sharedLibFlags =
- mf->GetSafeDefinition(sharedLibFlagsVar.c_str());
+ mf->GetSafeDefinition(sharedLibFlagsVar);
if (sharedLibFlags)
{
this->LanguageToOriginalSharedLibFlags[lang] = sharedLibFlags;
}
+
+ // Translate compiler ids for compatibility.
+ this->CheckCompilerIdCompatibility(mf, lang);
} // end for each language
// Now load files that can override any settings on the platform or for
@@ -627,19 +811,137 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
projectCompatibility += "Compatibility.cmake";
if(cmSystemTools::FileExists(projectCompatibility.c_str()))
{
- mf->ReadListFile(0,projectCompatibility.c_str());
+ mf->ReadListFile(projectCompatibility.c_str());
+ }
+ // Inform any extra generator of the new language.
+ if (this->ExtraGenerator)
+ {
+ this->ExtraGenerator->EnableLanguage(languages, mf, false);
+ }
+
+ if(fatalError)
+ {
+ cmSystemTools::SetFatalErrorOccured();
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::PrintCompilerAdvice(std::ostream& os,
+ std::string const& lang,
+ const char* envVar) const
+{
+ // Subclasses override this method if they do not support this advice.
+ os <<
+ "Tell CMake where to find the compiler by setting "
+ ;
+ if(envVar)
+ {
+ os <<
+ "either the environment variable \"" << envVar << "\" or "
+ ;
+ }
+ os <<
+ "the CMake cache entry CMAKE_" << lang << "_COMPILER "
+ "to the full path to the compiler, or to the compiler name "
+ "if it is in the PATH."
+ ;
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::CheckCompilerIdCompatibility(cmMakefile* mf,
+ std::string const& lang) const
+{
+ std::string compilerIdVar = "CMAKE_" + lang + "_COMPILER_ID";
+ const char* compilerId = mf->GetDefinition(compilerIdVar);
+ if(!compilerId)
+ {
+ return;
+ }
+
+ if(strcmp(compilerId, "AppleClang") == 0)
+ {
+ switch(mf->GetPolicyStatus(cmPolicies::CMP0025))
+ {
+ case cmPolicies::WARN:
+ if(!this->CMakeInstance->GetIsInTryCompile() &&
+ mf->PolicyOptionalWarningEnabled("CMAKE_POLICY_WARNING_CMP0025"))
+ {
+ std::ostringstream w;
+ w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0025) << "\n"
+ "Converting " << lang <<
+ " compiler id \"AppleClang\" to \"Clang\" for compatibility."
+ ;
+ mf->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ }
+ case cmPolicies::OLD:
+ // OLD behavior is to convert AppleClang to Clang.
+ mf->AddDefinition(compilerIdVar, "Clang");
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ mf->IssueMessage(
+ cmake::FATAL_ERROR,
+ cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0025)
+ );
+ case cmPolicies::NEW:
+ // NEW behavior is to keep AppleClang.
+ break;
+ }
+ }
+
+ if(strcmp(compilerId, "QCC") == 0)
+ {
+ switch(mf->GetPolicyStatus(cmPolicies::CMP0047))
+ {
+ case cmPolicies::WARN:
+ if(!this->CMakeInstance->GetIsInTryCompile() &&
+ mf->PolicyOptionalWarningEnabled("CMAKE_POLICY_WARNING_CMP0047"))
+ {
+ std::ostringstream w;
+ w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0047) << "\n"
+ "Converting " << lang <<
+ " compiler id \"QCC\" to \"GNU\" for compatibility."
+ ;
+ mf->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ }
+ case cmPolicies::OLD:
+ // OLD behavior is to convert QCC to GNU.
+ mf->AddDefinition(compilerIdVar, "GNU");
+ if(lang == "C")
+ {
+ mf->AddDefinition("CMAKE_COMPILER_IS_GNUCC", "1");
+ }
+ else if(lang == "CXX")
+ {
+ mf->AddDefinition("CMAKE_COMPILER_IS_GNUCXX", "1");
+ }
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ mf->IssueMessage(
+ cmake::FATAL_ERROR,
+ cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0047)
+ );
+ case cmPolicies::NEW:
+ // NEW behavior is to keep QCC.
+ break;
+ }
}
}
//----------------------------------------------------------------------------
-const char*
-cmGlobalGenerator::GetLanguageOutputExtension(cmSourceFile const& source)
+std::string
+cmGlobalGenerator::GetLanguageOutputExtension(cmSourceFile const& source) const
{
- if(const char* lang = source.GetLanguage())
+ const std::string& lang = source.GetLanguage();
+ if(!lang.empty())
{
- if(this->LanguageToOutputExtension.count(lang) > 0)
+ std::map<std::string, std::string>::const_iterator it =
+ this->LanguageToOutputExtension.find(lang);
+
+ if(it != this->LanguageToOutputExtension.end())
{
- return this->LanguageToOutputExtension[lang].c_str();
+ return it->second;
}
}
else
@@ -652,7 +954,7 @@ cmGlobalGenerator::GetLanguageOutputExtension(cmSourceFile const& source)
{
if(this->OutputExtensions.count(ext))
{
- return ext.c_str();
+ return ext;
}
}
}
@@ -660,7 +962,7 @@ cmGlobalGenerator::GetLanguageOutputExtension(cmSourceFile const& source)
}
-const char* cmGlobalGenerator::GetLanguageFromExtension(const char* ext)
+std::string cmGlobalGenerator::GetLanguageFromExtension(const char* ext) const
{
// if there is an extension and it starts with . then move past the
// . because the extensions are not stored with a . in the map
@@ -668,11 +970,13 @@ const char* cmGlobalGenerator::GetLanguageFromExtension(const char* ext)
{
++ext;
}
- if(this->ExtensionToLanguage.count(ext) > 0)
+ std::map<std::string, std::string>::const_iterator it
+ = this->ExtensionToLanguage.find(ext);
+ if(it != this->ExtensionToLanguage.end())
{
- return this->ExtensionToLanguage[ext].c_str();
+ return it->second;
}
- return 0;
+ return "";
}
/* SetLanguageEnabled() is now split in two parts:
@@ -687,15 +991,17 @@ files could change the object file extension
(CMAKE_<LANG>_OUTPUT_EXTENSION) before the CMake variables were copied
to the C++ maps.
*/
-void cmGlobalGenerator::SetLanguageEnabled(const char* l, cmMakefile* mf)
+void cmGlobalGenerator::SetLanguageEnabled(const std::string& l,
+ cmMakefile* mf)
{
this->SetLanguageEnabledFlag(l, mf);
this->SetLanguageEnabledMaps(l, mf);
}
-void cmGlobalGenerator::SetLanguageEnabledFlag(const char* l, cmMakefile* mf)
+void cmGlobalGenerator::SetLanguageEnabledFlag(const std::string& l,
+ cmMakefile* mf)
{
- this->LanguageEnabled[l] = true;
+ this->CMakeInstance->GetState()->SetLanguageEnabled(l);
// Fill the language-to-extension map with the current variable
// settings to make sure it is available for the try_compile()
@@ -705,7 +1011,8 @@ void cmGlobalGenerator::SetLanguageEnabledFlag(const char* l, cmMakefile* mf)
this->FillExtensionToLanguageMap(l, mf);
}
-void cmGlobalGenerator::SetLanguageEnabledMaps(const char* l, cmMakefile* mf)
+void cmGlobalGenerator::SetLanguageEnabledMaps(const std::string& l,
+ cmMakefile* mf)
{
// use LanguageToLinkerPreference to detect whether this functions has
// run before
@@ -717,16 +1024,16 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const char* l, cmMakefile* mf)
std::string linkerPrefVar = std::string("CMAKE_") +
std::string(l) + std::string("_LINKER_PREFERENCE");
- const char* linkerPref = mf->GetDefinition(linkerPrefVar.c_str());
+ const char* linkerPref = mf->GetDefinition(linkerPrefVar);
int preference = 0;
if(linkerPref)
{
if (sscanf(linkerPref, "%d", &preference)!=1)
{
// backward compatibility: before 2.6 LINKER_PREFERENCE
- // was either "None" or "Prefered", and only the first character was
+ // was either "None" or "Preferred", and only the first character was
// tested. So if there is a custom language out there and it is
- // "Prefered", set its preference high
+ // "Preferred", set its preference high
if (linkerPref[0]=='P')
{
preference = 100;
@@ -750,7 +1057,7 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const char* l, cmMakefile* mf)
std::string outputExtensionVar = std::string("CMAKE_") +
std::string(l) + std::string("_OUTPUT_EXTENSION");
- const char* outputExtension = mf->GetDefinition(outputExtensionVar.c_str());
+ const char* outputExtension = mf->GetDefinition(outputExtensionVar);
if(outputExtension)
{
this->LanguageToOutputExtension[l] = outputExtension;
@@ -768,7 +1075,7 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const char* l, cmMakefile* mf)
std::string ignoreExtensionsVar = std::string("CMAKE_") +
std::string(l) + std::string("_IGNORE_EXTENSIONS");
- std::string ignoreExts = mf->GetSafeDefinition(ignoreExtensionsVar.c_str());
+ std::string ignoreExts = mf->GetSafeDefinition(ignoreExtensionsVar);
std::vector<std::string> extensionList;
cmSystemTools::ExpandListArgument(ignoreExts, extensionList);
for(std::vector<std::string>::iterator i = extensionList.begin();
@@ -779,12 +1086,12 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const char* l, cmMakefile* mf)
}
-void cmGlobalGenerator::FillExtensionToLanguageMap(const char* l,
+void cmGlobalGenerator::FillExtensionToLanguageMap(const std::string& l,
cmMakefile* mf)
{
std::string extensionsVar = std::string("CMAKE_") +
std::string(l) + std::string("_SOURCE_FILE_EXTENSIONS");
- std::string exts = mf->GetSafeDefinition(extensionsVar.c_str());
+ std::string exts = mf->GetSafeDefinition(extensionsVar);
std::vector<std::string> extensionList;
cmSystemTools::ExpandListArgument(exts, extensionList);
for(std::vector<std::string>::iterator i = extensionList.begin();
@@ -794,113 +1101,93 @@ void cmGlobalGenerator::FillExtensionToLanguageMap(const char* l,
}
}
-bool cmGlobalGenerator::IgnoreFile(const char* l)
+bool cmGlobalGenerator::IgnoreFile(const char* ext) const
{
- if(this->GetLanguageFromExtension(l))
+ if(!this->GetLanguageFromExtension(ext).empty())
{
return false;
}
- return (this->IgnoreExtensions.count(l) > 0);
+ return (this->IgnoreExtensions.count(ext) > 0);
}
-bool cmGlobalGenerator::GetLanguageEnabled(const char* l) const
+bool cmGlobalGenerator::GetLanguageEnabled(const std::string& l) const
{
- return (this->LanguageEnabled.find(l)!= this->LanguageEnabled.end());
+ return this->CMakeInstance->GetState()->GetLanguageEnabled(l);
}
void cmGlobalGenerator::ClearEnabledLanguages()
{
- this->LanguageEnabled.clear();
+ return this->CMakeInstance->GetState()->ClearEnabledLanguages();
}
-bool cmGlobalGenerator::IsDependedOn(const char* project,
- cmTarget* targetIn)
+void cmGlobalGenerator::CreateLocalGenerators()
{
- // Get all local gens for this project
- std::vector<cmLocalGenerator*>* gens = &this->ProjectMap[project];
- // loop over local gens and get the targets for each one
- for(unsigned int i = 0; i < gens->size(); ++i)
+ cmDeleteAll(this->LocalGenerators);
+ this->LocalGenerators.clear();
+ this->LocalGenerators.reserve(this->Makefiles.size());
+ for (std::vector<cmMakefile*>::const_iterator it = this->Makefiles.begin();
+ it != this->Makefiles.end(); ++it)
{
- cmTargets& targets = (*gens)[i]->GetMakefile()->GetTargets();
- for (cmTargets::iterator l = targets.begin();
- l != targets.end(); l++)
- {
- cmTarget& target = l->second;
- TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(target);
- if(tgtdeps.count(targetIn))
- {
- return true;
- }
- }
+ this->LocalGenerators.push_back(this->CreateLocalGenerator(*it));
}
- return false;
}
void cmGlobalGenerator::Configure()
{
this->FirstTimeProgress = 0.0f;
- this->ClearGeneratorTargets();
- this->ExportSets.clear();
- // Delete any existing cmLocalGenerators
- unsigned int i;
- for (i = 0; i < this->LocalGenerators.size(); ++i)
- {
- delete this->LocalGenerators[i];
- }
- this->LocalGenerators.clear();
- for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator
- li = this->EvaluationFiles.begin();
- li != this->EvaluationFiles.end();
- ++li)
- {
- delete *li;
- }
- this->EvaluationFiles.clear();
- this->TargetDependencies.clear();
- this->TotalTargets.clear();
- this->ImportedTargets.clear();
- this->LocalGeneratorToTargetMap.clear();
- this->ProjectMap.clear();
- this->RuleHashes.clear();
- this->DirectoryContentMap.clear();
- this->BinaryDirectories.clear();
+ this->ClearGeneratorMembers();
- // start with this directory
- cmLocalGenerator *lg = this->CreateLocalGenerator();
- this->LocalGenerators.push_back(lg);
+ cmState::Snapshot snapshot = this->CMakeInstance->GetCurrentSnapshot();
- // set the Start directories
- cmMakefile* mf = lg->GetMakefile();
- lg->GetMakefile()->SetStartDirectory
- (this->CMakeInstance->GetStartDirectory());
- lg->GetMakefile()->SetStartOutputDirectory
- (this->CMakeInstance->GetStartOutputDirectory());
- lg->GetMakefile()->MakeStartDirectoriesCurrent();
+ snapshot.GetDirectory().SetCurrentSource
+ (this->CMakeInstance->GetHomeDirectory());
+ snapshot.GetDirectory().SetCurrentBinary
+ (this->CMakeInstance->GetHomeOutputDirectory());
- this->BinaryDirectories.insert(mf->GetStartOutputDirectory());
+ cmMakefile* dirMf = new cmMakefile(this, snapshot);
+ this->Makefiles.push_back(dirMf);
+
+ this->BinaryDirectories.insert(
+ this->CMakeInstance->GetHomeOutputDirectory());
// now do it
- lg->Configure();
+ this->ConfigureDoneCMP0026AndCMP0024 = false;
+ dirMf->Configure();
+ dirMf->EnforceDirectoryLevelRules();
+
+ this->ConfigureDoneCMP0026AndCMP0024 = true;
+
+ // Put a copy of each global target in every directory.
+ cmTargets globalTargets;
+ this->CreateDefaultGlobalTargets(&globalTargets);
+
+ for (unsigned int i = 0; i < this->Makefiles.size(); ++i)
+ {
+ cmMakefile* mf = this->Makefiles[i];
+ cmTargets* targets = &(mf->GetTargets());
+ cmTargets::iterator tit;
+ for ( tit = globalTargets.begin(); tit != globalTargets.end(); ++ tit )
+ {
+ (*targets)[tit->first] = tit->second;
+ (*targets)[tit->first].SetMakefile(mf);
+ }
+ }
// update the cache entry for the number of local generators, this is used
// for progress
char num[100];
- sprintf(num,"%d",static_cast<int>(this->LocalGenerators.size()));
+ sprintf(num,"%d",static_cast<int>(this->Makefiles.size()));
this->GetCMakeInstance()->AddCacheEntry
- ("CMAKE_NUMBER_OF_LOCAL_GENERATORS", num,
- "number of local generators", cmCacheManager::INTERNAL);
+ ("CMAKE_NUMBER_OF_MAKEFILES", num,
+ "number of local generators", cmState::INTERNAL);
// check for link libraries and include directories containing "NOTFOUND"
// and for infinite loops
- this->CheckLocalGenerators();
-
- // at this point this->LocalGenerators has been filled,
- // so create the map from project name to vector of local generators
- this->FillProjectMap();
+ this->CheckTargetProperties();
if ( this->CMakeInstance->GetWorkingMode() == cmake::NORMAL_MODE)
{
- cmOStringStream msg;
+ std::ostringstream msg;
if(cmSystemTools::GetErrorOccuredFlag())
{
msg << "Configuring incomplete, errors occurred!";
@@ -925,17 +1212,58 @@ void cmGlobalGenerator::Configure()
}
}
-bool cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS()
+void cmGlobalGenerator::CreateGenerationObjects(TargetTypes targetTypes)
+{
+ this->CreateLocalGenerators();
+ this->CreateGeneratorTargets(targetTypes);
+ this->ComputeBuildFileGenerators();
+}
+
+void cmGlobalGenerator::CreateImportedGenerationObjects(cmMakefile* mf,
+ const std::vector<std::string>& targets,
+ std::vector<const cmGeneratorTarget*>& exports)
+{
+ this->CreateGenerationObjects(ImportedOnly);
+ std::vector<cmMakefile*>::iterator mfit =
+ std::find(this->Makefiles.begin(), this->Makefiles.end(), mf);
+ cmLocalGenerator* lg =
+ this->LocalGenerators[std::distance(this->Makefiles.begin(), mfit)];
+ for (std::vector<std::string>::const_iterator it = targets.begin();
+ it != targets.end(); ++it)
+ {
+ cmGeneratorTarget* gt = lg->FindGeneratorTargetToUse(*it);
+ if (gt)
+ {
+ exports.push_back(gt);
+ }
+ }
+}
+
+cmExportBuildFileGenerator*
+cmGlobalGenerator::GetExportedTargetsFile(const std::string &filename) const
+{
+ std::map<std::string, cmExportBuildFileGenerator*>::const_iterator it
+ = this->BuildExportSets.find(filename);
+ return it == this->BuildExportSets.end() ? 0 : it->second;
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::AddCMP0042WarnTarget(const std::string& target)
+{
+ this->CMP0042WarnTargets.insert(target);
+}
+
+bool cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const
{
// If the property is not enabled then okay.
- if(!this->CMakeInstance
- ->GetPropertyAsBool("ALLOW_DUPLICATE_CUSTOM_TARGETS"))
+ if(!this->CMakeInstance->GetState()
+ ->GetGlobalPropertyAsBool("ALLOW_DUPLICATE_CUSTOM_TARGETS"))
{
return true;
}
// This generator does not support duplicate custom targets.
- cmOStringStream e;
+ std::ostringstream e;
e << "This project has enabled the ALLOW_DUPLICATE_CUSTOM_TARGETS "
<< "global property. "
<< "The \"" << this->GetName() << "\" generator does not support "
@@ -946,59 +1274,78 @@ bool cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS()
return false;
}
-void cmGlobalGenerator::Generate()
+void cmGlobalGenerator::ComputeBuildFileGenerators()
+{
+ for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i)
+ {
+ std::vector<cmExportBuildFileGenerator*> gens =
+ this->Makefiles[i]->GetExportBuildFileGenerators();
+ for (std::vector<cmExportBuildFileGenerator*>::const_iterator it =
+ gens.begin(); it != gens.end(); ++it)
+ {
+ (*it)->Compute(this->LocalGenerators[i]);
+ }
+ }
+}
+
+bool cmGlobalGenerator::Compute()
{
// Some generators track files replaced during the Generate.
// Start with an empty vector:
this->FilesReplacedDuringGenerate.clear();
+ // clear targets to issue warning CMP0042 for
+ this->CMP0042WarnTargets.clear();
+
// Check whether this generator is allowed to run.
if(!this->CheckALLOW_DUPLICATE_CUSTOM_TARGETS())
{
- return;
+ return false;
}
+ this->FinalizeTargetCompileInfo();
- // Check that all targets are valid.
- if(!this->CheckTargets())
- {
- return;
- }
+ this->CreateGenerationObjects();
- this->FinalizeTargetCompileDefinitions();
+ // at this point this->LocalGenerators has been filled,
+ // so create the map from project name to vector of local generators
+ this->FillProjectMap();
+#ifdef CMAKE_BUILD_WITH_CMAKE
// Iterate through all targets and set up automoc for those which have
- // the AUTOMOC property set
- this->CreateAutomocTargets();
+ // the AUTOMOC, AUTOUIC or AUTORCC property set
+ std::vector<cmGeneratorTarget const*> autogenTargets =
+ this->CreateQtAutoGeneratorsTargets();
+#endif
- // For each existing cmLocalGenerator
unsigned int i;
- // Put a copy of each global target in every directory.
- cmTargets globalTargets;
- this->CreateDefaultGlobalTargets(&globalTargets);
+ // Add generator specific helper commands
for (i = 0; i < this->LocalGenerators.size(); ++i)
{
- cmMakefile* mf = this->LocalGenerators[i]->GetMakefile();
- cmTargets* targets = &(mf->GetTargets());
- cmTargets::iterator tit;
- for ( tit = globalTargets.begin(); tit != globalTargets.end(); ++ tit )
- {
- (*targets)[tit->first] = tit->second;
- (*targets)[tit->first].SetMakefile(mf);
- }
+ this->LocalGenerators[i]->AddHelperCommands();
+ }
- for ( tit = targets->begin(); tit != targets->end(); ++ tit )
- {
- tit->second.AppendBuildInterfaceIncludes();
- }
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ for (std::vector<cmGeneratorTarget const*>::iterator it =
+ autogenTargets.begin(); it != autogenTargets.end(); ++it)
+ {
+ cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget(*it);
}
+#endif
- // Add generator specific helper commands
for (i = 0; i < this->LocalGenerators.size(); ++i)
{
- this->LocalGenerators[i]->AddHelperCommands();
+ cmMakefile* mf = this->LocalGenerators[i]->GetMakefile();
+ std::vector<cmInstallGenerator*>& gens = mf->GetInstallGenerators();
+ for (std::vector<cmInstallGenerator*>::const_iterator git = gens.begin();
+ git != gens.end(); ++git)
+ {
+ (*git)->Compute(this->LocalGenerators[i]);
+ }
}
+ this->AddExtraIDETargets();
+
// Trace the dependencies, after that no custom commands should be added
// because their dependencies might not be handled correctly
for (i = 0; i < this->LocalGenerators.size(); ++i)
@@ -1006,52 +1353,71 @@ void cmGlobalGenerator::Generate()
this->LocalGenerators[i]->TraceDependencies();
}
+ this->ForceLinkerLanguages();
+
// Compute the manifest of main targets generated.
for (i = 0; i < this->LocalGenerators.size(); ++i)
{
- this->LocalGenerators[i]->GenerateTargetManifest();
+ this->LocalGenerators[i]->ComputeTargetManifest();
}
- // Create per-target generator information.
- this->CreateGeneratorTargets();
-
- this->ProcessEvaluationFiles();
-
// Compute the inter-target dependencies.
if(!this->ComputeTargetDepends())
{
- return;
+ return false;
}
- // Create a map from local generator to the complete set of targets
- // it builds by default.
- this->FillLocalGeneratorToTargetMap();
-
for (i = 0; i < this->LocalGenerators.size(); ++i)
{
- cmMakefile* mf = this->LocalGenerators[i]->GetMakefile();
- cmTargets* targets = &(mf->GetTargets());
- for ( cmTargets::iterator it = targets->begin();
- it != targets->end(); ++ it )
- {
- it->second.FinalizeSystemIncludeDirectories();
- }
+ this->LocalGenerators[i]->ComputeHomeRelativeOutputPath();
}
+ return true;
+}
+
+void cmGlobalGenerator::Generate()
+{
+ // Create a map from local generator to the complete set of targets
+ // it builds by default.
+ this->InitializeProgressMarks();
+
+ this->ProcessEvaluationFiles();
+
// Generate project files
- for (i = 0; i < this->LocalGenerators.size(); ++i)
+ for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i)
{
- this->LocalGenerators[i]->GetMakefile()->SetGeneratingBuildSystem();
- this->SetCurrentLocalGenerator(this->LocalGenerators[i]);
+ this->SetCurrentMakefile(this->LocalGenerators[i]->GetMakefile());
this->LocalGenerators[i]->Generate();
- this->LocalGenerators[i]->GenerateInstallRules();
+ if(!this->LocalGenerators[i]->GetMakefile()->IsOn(
+ "CMAKE_SKIP_INSTALL_RULES"))
+ {
+ this->LocalGenerators[i]->GenerateInstallRules();
+ }
this->LocalGenerators[i]->GenerateTestFiles();
this->CMakeInstance->UpdateProgress("Generating",
(static_cast<float>(i)+1.0f)/
static_cast<float>(this->LocalGenerators.size()));
}
- this->SetCurrentLocalGenerator(0);
+ this->SetCurrentMakefile(0);
+ if(!this->GenerateCPackPropertiesFile())
+ {
+ this->GetCMakeInstance()->IssueMessage(
+ cmake::FATAL_ERROR, "Could not write CPack properties file.");
+ }
+
+ for (std::map<std::string, cmExportBuildFileGenerator*>::iterator
+ it = this->BuildExportSets.begin(); it != this->BuildExportSets.end();
+ ++it)
+ {
+ if (!it->second->GenerateImportFile()
+ && !cmSystemTools::GetErrorOccuredFlag())
+ {
+ this->GetCMakeInstance()
+ ->IssueMessage(cmake::FATAL_ERROR, "Could not write export file.");
+ return;
+ }
+ }
// Update rule hashes.
this->CheckRuleHashes();
@@ -1062,6 +1428,22 @@ void cmGlobalGenerator::Generate()
this->ExtraGenerator->Generate();
}
+ if(!this->CMP0042WarnTargets.empty())
+ {
+ std::ostringstream w;
+ w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0042) << "\n";
+ w << "MACOSX_RPATH is not specified for"
+ " the following targets:\n";
+ for(std::set<std::string>::iterator
+ iter = this->CMP0042WarnTargets.begin();
+ iter != this->CMP0042WarnTargets.end();
+ ++iter)
+ {
+ w << " " << *iter << "\n";
+ }
+ this->GetCMakeInstance()->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ }
+
this->CMakeInstance->UpdateProgress("Generating done", -1);
}
@@ -1073,9 +1455,9 @@ bool cmGlobalGenerator::ComputeTargetDepends()
{
return false;
}
- std::vector<cmTarget*> const& targets = ctd.GetTargets();
- for(std::vector<cmTarget*>::const_iterator ti = targets.begin();
- ti != targets.end(); ++ti)
+ std::vector<cmGeneratorTarget const*> const& targets = ctd.GetTargets();
+ for(std::vector<cmGeneratorTarget const*>::const_iterator ti
+ = targets.begin(); ti != targets.end(); ++ti)
{
ctd.GetTargetDirectDepends(*ti, this->TargetDependencies[*ti]);
}
@@ -1083,192 +1465,228 @@ bool cmGlobalGenerator::ComputeTargetDepends()
}
//----------------------------------------------------------------------------
-bool cmGlobalGenerator::CheckTargets()
+std::vector<const cmGeneratorTarget*>
+cmGlobalGenerator::CreateQtAutoGeneratorsTargets()
{
- // Make sure all targets can find their source files.
- for(unsigned int i=0; i < this->LocalGenerators.size(); ++i)
- {
- cmTargets& targets =
- this->LocalGenerators[i]->GetMakefile()->GetTargets();
- for(cmTargets::iterator ti = targets.begin();
- ti != targets.end(); ++ti)
- {
- cmTarget& target = ti->second;
- if(target.GetType() == cmTarget::EXECUTABLE ||
- target.GetType() == cmTarget::STATIC_LIBRARY ||
- target.GetType() == cmTarget::SHARED_LIBRARY ||
- target.GetType() == cmTarget::MODULE_LIBRARY ||
- target.GetType() == cmTarget::OBJECT_LIBRARY ||
- target.GetType() == cmTarget::UTILITY)
- {
- if(!target.FindSourceFiles())
- {
- return false;
- }
- }
- }
- }
- return true;
-}
+ std::vector<const cmGeneratorTarget*> autogenTargets;
-//----------------------------------------------------------------------------
-void cmGlobalGenerator::CreateAutomocTargets()
-{
#ifdef CMAKE_BUILD_WITH_CMAKE
- typedef std::vector<std::pair<cmQtAutomoc, cmTarget*> > Automocs;
- Automocs automocs;
for(unsigned int i=0; i < this->LocalGenerators.size(); ++i)
{
- cmTargets& targets =
- this->LocalGenerators[i]->GetMakefile()->GetTargets();
- for(cmTargets::iterator ti = targets.begin();
+ std::vector<cmGeneratorTarget*> targets =
+ this->LocalGenerators[i]->GetGeneratorTargets();
+ std::vector<cmGeneratorTarget*> filteredTargets;
+ filteredTargets.reserve(targets.size());
+ for(std::vector<cmGeneratorTarget*>::iterator ti = targets.begin();
ti != targets.end(); ++ti)
{
- cmTarget& target = ti->second;
- if(target.GetType() == cmTarget::EXECUTABLE ||
- target.GetType() == cmTarget::STATIC_LIBRARY ||
- target.GetType() == cmTarget::SHARED_LIBRARY ||
- target.GetType() == cmTarget::MODULE_LIBRARY ||
- target.GetType() == cmTarget::OBJECT_LIBRARY)
+ if ((*ti)->GetType() == cmState::GLOBAL_TARGET)
{
- if(target.GetPropertyAsBool("AUTOMOC") && !target.IsImported())
- {
- cmQtAutomoc automoc;
- if(automoc.InitializeMocSourceFile(&target))
- {
- automocs.push_back(std::make_pair(automoc, &target));
- }
- }
+ continue;
+ }
+ if((*ti)->GetType() != cmState::EXECUTABLE &&
+ (*ti)->GetType() != cmState::STATIC_LIBRARY &&
+ (*ti)->GetType() != cmState::SHARED_LIBRARY &&
+ (*ti)->GetType() != cmState::MODULE_LIBRARY &&
+ (*ti)->GetType() != cmState::OBJECT_LIBRARY)
+ {
+ continue;
+ }
+ if((!(*ti)->GetPropertyAsBool("AUTOMOC")
+ && !(*ti)->GetPropertyAsBool("AUTOUIC")
+ && !(*ti)->GetPropertyAsBool("AUTORCC"))
+ || (*ti)->IsImported())
+ {
+ continue;
+ }
+ // don't do anything if there is no Qt4 or Qt5Core (which contains moc):
+ cmMakefile* mf = (*ti)->Target->GetMakefile();
+ std::string qtMajorVersion = mf->GetSafeDefinition("QT_VERSION_MAJOR");
+ if (qtMajorVersion == "")
+ {
+ qtMajorVersion = mf->GetSafeDefinition("Qt5Core_VERSION_MAJOR");
+ }
+ if (qtMajorVersion != "4" && qtMajorVersion != "5")
+ {
+ continue;
}
+
+ cmGeneratorTarget* gt = *ti;
+
+ cmQtAutoGeneratorInitializer::InitializeAutogenSources(gt);
+ filteredTargets.push_back(gt);
+ }
+ for(std::vector<cmGeneratorTarget*>::iterator ti = filteredTargets.begin();
+ ti != filteredTargets.end(); ++ti)
+ {
+ cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
+ this->LocalGenerators[i], *ti);
+ autogenTargets.push_back(*ti);
}
- }
- for (Automocs::iterator it = automocs.begin(); it != automocs.end();
- ++it)
- {
- it->first.SetupAutomocTarget(it->second);
}
#endif
+ return autogenTargets;
}
//----------------------------------------------------------------------------
-void cmGlobalGenerator::FinalizeTargetCompileDefinitions()
+void cmGlobalGenerator::FinalizeTargetCompileInfo()
{
// Construct per-target generator information.
- for(unsigned int i=0; i < this->LocalGenerators.size(); ++i)
+ for(unsigned int i=0; i < this->Makefiles.size(); ++i)
{
- cmMakefile *mf = this->LocalGenerators[i]->GetMakefile();
+ cmMakefile *mf = this->Makefiles[i];
- const std::vector<cmValueWithOrigin> noconfig_compile_definitions =
+ const cmStringRange noconfig_compile_definitions =
mf->GetCompileDefinitionsEntries();
-
- std::vector<std::string> configs;
- mf->GetConfigurations(configs);
+ const cmBacktraceRange noconfig_compile_definitions_bts =
+ mf->GetCompileDefinitionsBacktraces();
cmTargets& targets = mf->GetTargets();
for(cmTargets::iterator ti = targets.begin();
ti != targets.end(); ++ti)
{
cmTarget* t = &ti->second;
+ if (t->GetType() == cmState::GLOBAL_TARGET)
+ {
+ continue;
+ }
+
+ t->AppendBuildInterfaceIncludes();
+
+ if (t->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ continue;
+ }
- for (std::vector<cmValueWithOrigin>::const_iterator it
+ cmBacktraceRange::const_iterator btIt
+ = noconfig_compile_definitions_bts.begin();
+ for (cmStringRange::const_iterator it
= noconfig_compile_definitions.begin();
- it != noconfig_compile_definitions.end(); ++it)
+ it != noconfig_compile_definitions.end(); ++it, ++btIt)
{
- t->InsertCompileDefinition(*it);
+ t->InsertCompileDefinition(*it, *btIt);
}
- for(std::vector<std::string>::const_iterator ci = configs.begin();
- ci != configs.end(); ++ci)
+ cmPolicies::PolicyStatus polSt
+ = mf->GetPolicyStatus(cmPolicies::CMP0043);
+ if (polSt == cmPolicies::WARN || polSt == cmPolicies::OLD)
{
- std::string defPropName = "COMPILE_DEFINITIONS_";
- defPropName += cmSystemTools::UpperCase(*ci);
- t->AppendProperty(defPropName.c_str(),
- mf->GetProperty(defPropName.c_str()));
+ std::vector<std::string> configs;
+ mf->GetConfigurations(configs);
+
+ for(std::vector<std::string>::const_iterator ci = configs.begin();
+ ci != configs.end(); ++ci)
+ {
+ std::string defPropName = "COMPILE_DEFINITIONS_";
+ defPropName += cmSystemTools::UpperCase(*ci);
+ t->AppendProperty(defPropName,
+ mf->GetProperty(defPropName));
+ }
}
}
}
}
//----------------------------------------------------------------------------
-void cmGlobalGenerator::CreateGeneratorTargets()
+void cmGlobalGenerator::CreateGeneratorTargets(
+ TargetTypes targetTypes,
+ cmMakefile *mf,
+ cmLocalGenerator *lg,
+ std::map<cmTarget*, cmGeneratorTarget*> const& importedMap)
{
- // Construct per-target generator information.
- for(unsigned int i=0; i < this->LocalGenerators.size(); ++i)
+ if (targetTypes == AllTargets)
{
- cmGeneratorTargetsType generatorTargets;
-
- cmMakefile *mf = this->LocalGenerators[i]->GetMakefile();
-
cmTargets& targets = mf->GetTargets();
for(cmTargets::iterator ti = targets.begin();
ti != targets.end(); ++ti)
{
cmTarget* t = &ti->second;
- cmGeneratorTarget* gt = new cmGeneratorTarget(t);
- this->GeneratorTargets[t] = gt;
- this->ComputeTargetObjects(gt);
- generatorTargets[t] = gt;
+ cmGeneratorTarget* gt = new cmGeneratorTarget(t, lg);
+ lg->AddGeneratorTarget(gt);
}
+ }
+
+ std::vector<cmTarget*> itgts = mf->GetImportedTargets();
+ for(std::vector<cmTarget*>::const_iterator
+ j = itgts.begin(); j != itgts.end(); ++j)
+ {
+ lg->AddImportedGeneratorTarget(importedMap.find(*j)->second);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::CreateGeneratorTargets(TargetTypes targetTypes)
+{
+ std::map<cmTarget*, cmGeneratorTarget*> importedMap;
+ for(unsigned int i=0; i < this->Makefiles.size(); ++i)
+ {
+ cmMakefile* mf = this->Makefiles[i];
for(std::vector<cmTarget*>::const_iterator
j = mf->GetOwnedImportedTargets().begin();
j != mf->GetOwnedImportedTargets().end(); ++j)
{
- cmGeneratorTarget* gt = new cmGeneratorTarget(*j);
- this->GeneratorTargets[*j] = gt;
- generatorTargets[*j] = gt;
+ cmLocalGenerator* lg = this->LocalGenerators[i];
+ cmGeneratorTarget* gt = new cmGeneratorTarget(*j, lg);
+ lg->AddOwnedImportedGeneratorTarget(gt);
+ importedMap[*j] = gt;
}
-
- mf->SetGeneratorTargets(generatorTargets);
}
-}
-//----------------------------------------------------------------------------
-void cmGlobalGenerator::ClearGeneratorTargets()
-{
- for(cmGeneratorTargetsType::iterator i = this->GeneratorTargets.begin();
- i != this->GeneratorTargets.end(); ++i)
+ // Construct per-target generator information.
+ for(unsigned int i=0; i < this->LocalGenerators.size(); ++i)
{
- delete i->second;
+ this->CreateGeneratorTargets(targetTypes, this->Makefiles[i],
+ this->LocalGenerators[i], importedMap);
}
- this->GeneratorTargets.clear();
}
+
//----------------------------------------------------------------------------
-cmGeneratorTarget* cmGlobalGenerator::GetGeneratorTarget(cmTarget* t) const
+void cmGlobalGenerator::ClearGeneratorMembers()
{
- cmGeneratorTargetsType::const_iterator ti = this->GeneratorTargets.find(t);
- if(ti == this->GeneratorTargets.end())
- {
- this->CMakeInstance->IssueMessage(
- cmake::INTERNAL_ERROR, "Missing cmGeneratorTarget instance!",
- cmListFileBacktrace());
- return 0;
- }
- return ti->second;
+ cmDeleteAll(this->BuildExportSets);
+ this->BuildExportSets.clear();
+
+ cmDeleteAll(this->Makefiles);
+ this->Makefiles.clear();
+
+ cmDeleteAll(this->LocalGenerators);
+ this->LocalGenerators.clear();
+
+ this->ExportSets.clear();
+ this->TargetDependencies.clear();
+ this->TargetSearchIndex.clear();
+ this->GeneratorTargetSearchIndex.clear();
+ this->ProjectMap.clear();
+ this->RuleHashes.clear();
+ this->DirectoryContentMap.clear();
+ this->BinaryDirectories.clear();
}
//----------------------------------------------------------------------------
-void cmGlobalGenerator::ComputeTargetObjects(cmGeneratorTarget*) const
+void cmGlobalGenerator::ComputeTargetObjectDirectory(cmGeneratorTarget*) const
{
- // Implemented in generator subclasses that need this.
}
-void cmGlobalGenerator::CheckLocalGenerators()
+void cmGlobalGenerator::CheckTargetProperties()
{
- std::map<cmStdString, cmStdString> notFoundMap;
-// std::set<cmStdString> notFoundMap;
+ std::map<std::string, std::string> notFoundMap;
+// std::set<std::string> notFoundMap;
// after it is all done do a ConfigureFinalPass
- cmCacheManager* manager = 0;
- for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i)
+ cmState* state = this->GetCMakeInstance()->GetState();
+ for (unsigned int i = 0; i < this->Makefiles.size(); ++i)
{
- manager = this->LocalGenerators[i]->GetMakefile()->GetCacheManager();
- this->LocalGenerators[i]->ConfigureFinalPass();
+ this->Makefiles[i]->ConfigureFinalPass();
cmTargets &targets =
- this->LocalGenerators[i]->GetMakefile()->GetTargets();
+ this->Makefiles[i]->GetTargets();
for (cmTargets::iterator l = targets.begin();
l != targets.end(); l++)
{
+ if (l->second.GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ continue;
+ }
const cmTarget::LinkLibraryVectorType& libs =
l->second.GetOriginalLinkLibraries();
for(cmTarget::LinkLibraryVectorType::const_iterator lib = libs.begin();
@@ -1278,9 +1696,7 @@ void cmGlobalGenerator::CheckLocalGenerators()
cmSystemTools::IsNOTFOUND(lib->first.c_str()))
{
std::string varName = lib->first.substr(0, lib->first.size()-9);
- cmCacheManager::CacheIterator it =
- manager->GetCacheIterator(varName.c_str());
- if(it.GetPropertyAsBool("ADVANCED"))
+ if(state->GetCacheEntryPropertyAsBool(varName, "ADVANCED"))
{
varName += " (ADVANCED)";
}
@@ -1288,7 +1704,7 @@ void cmGlobalGenerator::CheckLocalGenerators()
text += "\n linked by target \"";
text += l->second.GetName();
text += "\" in directory ";
- text+=this->LocalGenerators[i]->GetMakefile()->GetCurrentDirectory();
+ text+=this->Makefiles[i]->GetCurrentSourceDirectory();
notFoundMap[varName] = text;
}
}
@@ -1302,7 +1718,7 @@ void cmGlobalGenerator::CheckLocalGenerators()
std::string incDirs = cmGeneratorExpression::Preprocess(incDirProp,
cmGeneratorExpression::StripAllGeneratorExpressions);
- cmSystemTools::ExpandListArgument(incDirs.c_str(), incs);
+ cmSystemTools::ExpandListArgument(incDirs, incs);
for( std::vector<std::string>::const_iterator incDir = incs.begin();
incDir != incs.end(); ++incDir)
@@ -1311,29 +1727,26 @@ void cmGlobalGenerator::CheckLocalGenerators()
cmSystemTools::IsNOTFOUND(incDir->c_str()))
{
std::string varName = incDir->substr(0, incDir->size()-9);
- cmCacheManager::CacheIterator it =
- manager->GetCacheIterator(varName.c_str());
- if(it.GetPropertyAsBool("ADVANCED"))
+ if(state->GetCacheEntryPropertyAsBool(varName, "ADVANCED"))
{
varName += " (ADVANCED)";
}
std::string text = notFoundMap[varName];
text += "\n used as include directory in directory ";
- text += this->LocalGenerators[i]
- ->GetMakefile()->GetCurrentDirectory();
+ text += this->Makefiles[i]->GetCurrentSourceDirectory();
notFoundMap[varName] = text;
}
}
}
this->CMakeInstance->UpdateProgress
("Configuring", 0.9f+0.1f*(static_cast<float>(i)+1.0f)/
- static_cast<float>(this->LocalGenerators.size()));
+ static_cast<float>(this->Makefiles.size()));
}
- if(notFoundMap.size())
+ if(!notFoundMap.empty())
{
std::string notFoundVars;
- for(std::map<cmStdString, cmStdString>::const_iterator
+ for(std::map<std::string, std::string>::const_iterator
ii = notFoundMap.begin();
ii != notFoundMap.end();
++ii)
@@ -1350,19 +1763,20 @@ void cmGlobalGenerator::CheckLocalGenerators()
}
}
-int cmGlobalGenerator::TryCompile(const char *srcdir, const char *bindir,
- const char *projectName,
- const char *target, bool fast,
- std::string *output, cmMakefile *mf)
+int cmGlobalGenerator::TryCompile(const std::string& srcdir,
+ const std::string& bindir,
+ const std::string& projectName,
+ const std::string& target, bool fast,
+ std::string& output, cmMakefile *mf)
{
// if this is not set, then this is a first time configure
// and there is a good chance that the try compile stuff will
// take the bulk of the time, so try and guess some progress
// by getting closer and closer to 100 without actually getting there.
- if (!this->CMakeInstance->GetCacheManager()->GetCacheValue
- ("CMAKE_NUMBER_OF_LOCAL_GENERATORS"))
+ if (!this->CMakeInstance->GetState()->GetInitializedCacheValue
+ ("CMAKE_NUMBER_OF_MAKEFILES"))
{
- // If CMAKE_NUMBER_OF_LOCAL_GENERATORS is not set
+ // If CMAKE_NUMBER_OF_MAKEFILES is not set
// we are in the first time progress and we have no
// idea how long it will be. So, just move 1/10th of the way
// there each time, and don't go over 95%
@@ -1375,17 +1789,8 @@ int cmGlobalGenerator::TryCompile(const char *srcdir, const char *bindir,
this->FirstTimeProgress);
}
- std::string makeCommand = this->CMakeInstance->
- GetCacheManager()->GetCacheValue("CMAKE_MAKE_PROGRAM");
- if(makeCommand.size() == 0)
- {
- cmSystemTools::Error(
- "Generator cannot find the appropriate make command.");
- return 1;
- }
-
std::string newTarget;
- if (target && strlen(target))
+ if (!target.empty())
{
newTarget += target;
#if 0
@@ -1400,60 +1805,33 @@ int cmGlobalGenerator::TryCompile(const char *srcdir, const char *bindir,
#endif // WIN32
#endif
}
- const char* config = mf->GetDefinition("CMAKE_TRY_COMPILE_CONFIGURATION");
+ std::string config =
+ mf->GetSafeDefinition("CMAKE_TRY_COMPILE_CONFIGURATION");
return this->Build(srcdir,bindir,projectName,
- newTarget.c_str(),
- output,makeCommand.c_str(),config,false,fast,
+ newTarget,
+ output,"",config,false,fast,false,
this->TryCompileTimeout);
}
-std::string cmGlobalGenerator
-::GenerateBuildCommand(const char* makeProgram, const char *projectName,
- const char *projectDir, const char* additionalOptions,
- const char *targetName, const char* config,
- bool ignoreErrors, bool)
+void cmGlobalGenerator::GenerateBuildCommand(
+ std::vector<std::string>& makeCommand, const std::string&,
+ const std::string&, const std::string&, const std::string&,
+ const std::string&, bool, bool,
+ std::vector<std::string> const&)
{
- // Project name & dir and config are not used yet.
- (void)projectName;
- (void)projectDir;
- (void)config;
-
- std::string makeCommand =
- cmSystemTools::ConvertToUnixOutputPath(makeProgram);
-
- // Since we have full control over the invocation of nmake, let us
- // make it quiet.
- if ( strcmp(this->GetName(), "NMake Makefiles") == 0 )
- {
- makeCommand += " /NOLOGO ";
- }
- if ( ignoreErrors )
- {
- makeCommand += " -i";
- }
- if ( additionalOptions )
- {
- makeCommand += " ";
- makeCommand += additionalOptions;
- }
- if ( targetName )
- {
- makeCommand += " ";
- makeCommand += targetName;
- }
- return makeCommand;
+ makeCommand.push_back(
+ "cmGlobalGenerator::GenerateBuildCommand not implemented");
}
int cmGlobalGenerator::Build(
- const char *, const char *bindir,
- const char *projectName, const char *target,
- std::string *output,
- const char *makeCommandCSTR,
- const char *config,
- bool clean, bool fast,
+ const std::string&, const std::string& bindir,
+ const std::string& projectName, const std::string& target,
+ std::string& output,
+ const std::string& makeCommandCSTR,
+ const std::string& config,
+ bool clean, bool fast, bool verbose,
double timeout,
cmSystemTools::OutputOption outputflag,
- const char* extraOptions,
std::vector<std::string> const& nativeOptions)
{
/**
@@ -1461,126 +1839,144 @@ int cmGlobalGenerator::Build(
*/
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
cmSystemTools::ChangeDirectory(bindir);
- if(output)
- {
- *output += "Change Dir: ";
- *output += bindir;
- *output += "\n";
- }
+ output += "Change Dir: ";
+ output += bindir;
+ output += "\n";
int retVal;
bool hideconsole = cmSystemTools::GetRunCommandHideConsole();
cmSystemTools::SetRunCommandHideConsole(true);
std::string outputBuffer;
- std::string* outputPtr = 0;
- if(output)
+ std::string* outputPtr = &outputBuffer;
+
+ std::vector<std::string> makeCommand;
+ this->GenerateBuildCommand(makeCommand, makeCommandCSTR, projectName,
+ bindir, target, config, fast, verbose,
+ nativeOptions);
+
+ // Workaround to convince VCExpress.exe to produce output.
+ if (outputflag == cmSystemTools::OUTPUT_PASSTHROUGH &&
+ !makeCommand.empty() && cmSystemTools::LowerCase(
+ cmSystemTools::GetFilenameName(makeCommand[0])) == "vcexpress.exe")
{
- outputPtr = &outputBuffer;
+ outputflag = cmSystemTools::OUTPUT_FORWARD;
}
// should we do a clean first?
if (clean)
{
- std::string cleanCommand =
- this->GenerateBuildCommand(makeCommandCSTR, projectName, bindir,
- 0, "clean", config, false, fast);
- if(output)
- {
- *output += "\nRun Clean Command:";
- *output += cleanCommand;
- *output += "\n";
- }
+ std::vector<std::string> cleanCommand;
+ this->GenerateBuildCommand(cleanCommand, makeCommandCSTR, projectName,
+ bindir, "clean", config, fast, verbose);
+ output += "\nRun Clean Command:";
+ output += cmSystemTools::PrintSingleCommand(cleanCommand);
+ output += "\n";
- if (!cmSystemTools::RunSingleCommand(cleanCommand.c_str(), outputPtr,
+ if (!cmSystemTools::RunSingleCommand(cleanCommand, outputPtr, outputPtr,
&retVal, 0, outputflag, timeout))
{
cmSystemTools::SetRunCommandHideConsole(hideconsole);
cmSystemTools::Error("Generator: execution of make clean failed.");
- if (output)
- {
- *output += *outputPtr;
- *output += "\nGenerator: execution of make clean failed.\n";
- }
+ output += *outputPtr;
+ output += "\nGenerator: execution of make clean failed.\n";
// return to the original directory
- cmSystemTools::ChangeDirectory(cwd.c_str());
+ cmSystemTools::ChangeDirectory(cwd);
return 1;
}
- if (output)
- {
- *output += *outputPtr;
- }
+ output += *outputPtr;
}
// now build
- std::string makeCommand =
- this->GenerateBuildCommand(makeCommandCSTR, projectName, bindir,
- extraOptions, target,
- config, false, fast);
- if(output)
- {
- *output += "\nRun Build Command:";
- *output += makeCommand;
- *output += "\n";
- }
-
- std::vector<cmStdString> command =
- cmSystemTools::ParseArguments(makeCommand.c_str());
- for(std::vector<std::string>::const_iterator ni = nativeOptions.begin();
- ni != nativeOptions.end(); ++ni)
- {
- command.push_back(*ni);
- }
+ std::string makeCommandStr = cmSystemTools::PrintSingleCommand(makeCommand);
+ output += "\nRun Build Command:";
+ output += makeCommandStr;
+ output += "\n";
- if (!cmSystemTools::RunSingleCommand(command, outputPtr,
+ if (!cmSystemTools::RunSingleCommand(makeCommand, outputPtr, outputPtr,
&retVal, 0, outputflag, timeout))
{
cmSystemTools::SetRunCommandHideConsole(hideconsole);
cmSystemTools::Error
("Generator: execution of make failed. Make command was: ",
- makeCommand.c_str());
- if (output)
- {
- *output += *outputPtr;
- *output += "\nGenerator: execution of make failed. Make command was: "
- + makeCommand + "\n";
- }
+ makeCommandStr.c_str());
+ output += *outputPtr;
+ output += "\nGenerator: execution of make failed. Make command was: "
+ + makeCommandStr + "\n";
// return to the original directory
- cmSystemTools::ChangeDirectory(cwd.c_str());
+ cmSystemTools::ChangeDirectory(cwd);
return 1;
}
- if (output)
- {
- *output += *outputPtr;
- }
+ output += *outputPtr;
cmSystemTools::SetRunCommandHideConsole(hideconsole);
// The SGI MipsPro 7.3 compiler does not return an error code when
// the source has a #error in it! This is a work-around for such
// compilers.
- if((retVal == 0) && (output->find("#error") != std::string::npos))
+ if((retVal == 0) && (output.find("#error") != std::string::npos))
{
retVal = 1;
}
- cmSystemTools::ChangeDirectory(cwd.c_str());
+ cmSystemTools::ChangeDirectory(cwd);
return retVal;
}
-void cmGlobalGenerator::AddLocalGenerator(cmLocalGenerator *lg)
+//----------------------------------------------------------------------------
+std::string cmGlobalGenerator::GenerateCMakeBuildCommand(
+ const std::string& target, const std::string& config,
+ const std::string& native,
+ bool ignoreErrors)
{
- this->LocalGenerators.push_back(lg);
+ std::string makeCommand = cmSystemTools::GetCMakeCommand();
+ makeCommand = cmSystemTools::ConvertToOutputPath(makeCommand.c_str());
+ makeCommand += " --build .";
+ if(!config.empty())
+ {
+ makeCommand += " --config \"";
+ makeCommand += config;
+ makeCommand += "\"";
+ }
+ if(!target.empty())
+ {
+ makeCommand += " --target \"";
+ makeCommand += target;
+ makeCommand += "\"";
+ }
+ const char* sep = " -- ";
+ if(ignoreErrors)
+ {
+ const char* iflag = this->GetBuildIgnoreErrorsFlag();
+ if(iflag && *iflag)
+ {
+ makeCommand += sep;
+ makeCommand += iflag;
+ sep = " ";
+ }
+ }
+ if(!native.empty())
+ {
+ makeCommand += sep;
+ makeCommand += native;
+ }
+ return makeCommand;
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::AddMakefile(cmMakefile *mf)
+{
+ this->Makefiles.push_back(mf);
// update progress
// estimate how many lg there will be
const char *numGenC =
- this->CMakeInstance->GetCacheManager()->GetCacheValue
- ("CMAKE_NUMBER_OF_LOCAL_GENERATORS");
+ this->CMakeInstance->GetState()->GetInitializedCacheValue
+ ("CMAKE_NUMBER_OF_MAKEFILES");
if (!numGenC)
{
- // If CMAKE_NUMBER_OF_LOCAL_GENERATORS is not set
+ // If CMAKE_NUMBER_OF_MAKEFILES is not set
// we are in the first time progress and we have no
// idea how long it will be. So, just move half way
// there each time, and don't go over 95%
@@ -1595,7 +1991,7 @@ void cmGlobalGenerator::AddLocalGenerator(cmLocalGenerator *lg)
}
int numGen = atoi(numGenC);
- float prog = 0.9f*static_cast<float>(this->LocalGenerators.size())/
+ float prog = 0.9f*static_cast<float>(this->Makefiles.size())/
static_cast<float>(numGen);
if (prog > 0.9f)
{
@@ -1617,11 +2013,10 @@ void cmGlobalGenerator::EnableInstallTarget()
this->InstallTargetEnabled = true;
}
-cmLocalGenerator *cmGlobalGenerator::CreateLocalGenerator()
+cmLocalGenerator*
+cmGlobalGenerator::CreateLocalGenerator(cmMakefile* mf)
{
- cmLocalGenerator *lg = new cmLocalGenerator;
- lg->SetGlobalGenerator(this);
- return lg;
+ return new cmLocalGenerator(this, mf);
}
void cmGlobalGenerator::EnableLanguagesFromGenerator(cmGlobalGenerator *gen,
@@ -1633,9 +2028,11 @@ void cmGlobalGenerator::EnableLanguagesFromGenerator(cmGlobalGenerator *gen,
gen->GetCMakeInstance()->GetCacheDefinition("CMAKE_MAKE_PROGRAM");
this->GetCMakeInstance()->AddCacheEntry("CMAKE_MAKE_PROGRAM", make,
"make program",
- cmCacheManager::FILEPATH);
+ cmState::FILEPATH);
// copy the enabled languages
- this->LanguageEnabled = gen->LanguageEnabled;
+ this->GetCMakeInstance()->GetState()->SetEnabledLanguages(
+ gen->GetCMakeInstance()->GetState()->GetEnabledLanguages()
+ );
this->LanguagesReady = gen->LanguagesReady;
this->ExtensionToLanguage = gen->ExtensionToLanguage;
this->IgnoreExtensions = gen->IgnoreExtensions;
@@ -1658,54 +2055,62 @@ void cmGlobalGenerator::SetConfiguredFilesPath(cmGlobalGenerator* gen)
}
}
-bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
- cmLocalGenerator* gen)
+bool cmGlobalGenerator::IsExcluded(cmState::Snapshot const& rootSnp,
+ cmState::Snapshot const& snp_) const
{
- if(!gen || gen == root)
+ cmState::Snapshot snp = snp_;
+ while (snp.IsValid())
{
- // No directory excludes itself.
- return false;
- }
+ if(snp == rootSnp)
+ {
+ // No directory excludes itself.
+ return false;
+ }
- if(gen->GetMakefile()->GetPropertyAsBool("EXCLUDE_FROM_ALL"))
- {
- // This directory is excluded from its parent.
- return true;
+ if(snp.GetDirectory().GetPropertyAsBool("EXCLUDE_FROM_ALL"))
+ {
+ // This directory is excluded from its parent.
+ return true;
+ }
+ snp = snp.GetBuildsystemDirectoryParent();
}
+ return false;
+}
+
+bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
+ cmLocalGenerator* gen) const
+{
+ assert(gen);
- // This directory is included in its parent. Check whether the
- // parent is excluded.
- return this->IsExcluded(root, gen->GetParent());
+ cmState::Snapshot rootSnp = root->GetStateSnapshot();
+ cmState::Snapshot snp = gen->GetStateSnapshot();
+
+ return this->IsExcluded(rootSnp, snp);
}
bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
- cmTarget& target)
+ cmGeneratorTarget* target) const
{
- if(target.GetPropertyAsBool("EXCLUDE_FROM_ALL"))
+ if(target->GetType() == cmState::INTERFACE_LIBRARY
+ || target->GetPropertyAsBool("EXCLUDE_FROM_ALL"))
{
// This target is excluded from its directory.
return true;
}
- else
- {
- // This target is included in its directory. Check whether the
- // directory is excluded.
- return this->IsExcluded(root, target.GetMakefile()->GetLocalGenerator());
- }
+ // This target is included in its directory. Check whether the
+ // directory is excluded.
+ return this->IsExcluded(root, target->GetLocalGenerator());
}
-void cmGlobalGenerator::GetEnabledLanguages(std::vector<std::string>& lang)
+void
+cmGlobalGenerator::GetEnabledLanguages(std::vector<std::string>& lang) const
{
- for(std::map<cmStdString, bool>::iterator i =
- this->LanguageEnabled.begin(); i != this->LanguageEnabled.end(); ++i)
- {
- lang.push_back(i->first);
- }
+ lang = this->CMakeInstance->GetState()->GetEnabledLanguages();
}
-int cmGlobalGenerator::GetLinkerPreference(const char* lang)
+int cmGlobalGenerator::GetLinkerPreference(const std::string& lang) const
{
- std::map<cmStdString, int>::const_iterator it =
+ std::map<std::string, int>::const_iterator it =
this->LanguageToLinkerPreference.find(lang);
if (it != this->LanguageToLinkerPreference.end())
{
@@ -1721,146 +2126,143 @@ void cmGlobalGenerator::FillProjectMap()
for(i = 0; i < this->LocalGenerators.size(); ++i)
{
// for each local generator add all projects
- cmLocalGenerator *lg = this->LocalGenerators[i];
+ cmState::Snapshot snp = this->LocalGenerators[i]->GetStateSnapshot();
std::string name;
do
{
- if (name != lg->GetMakefile()->GetProjectName())
+ std::string snpProjName = snp.GetProjectName();
+ if (name != snpProjName)
{
- name = lg->GetMakefile()->GetProjectName();
+ name = snpProjName;
this->ProjectMap[name].push_back(this->LocalGenerators[i]);
}
- lg = lg->GetParent();
+ snp = snp.GetBuildsystemDirectoryParent();
}
- while (lg);
+ while (snp.IsValid());
}
}
-
-// Build a map that contains a the set of targets used by each local
-// generator directory level.
-void cmGlobalGenerator::FillLocalGeneratorToTargetMap()
+cmMakefile*
+cmGlobalGenerator::FindMakefile(const std::string& start_dir) const
{
- this->LocalGeneratorToTargetMap.clear();
- // Loop over all targets in all local generators.
- for(std::vector<cmLocalGenerator*>::const_iterator
- lgi = this->LocalGenerators.begin();
- lgi != this->LocalGenerators.end(); ++lgi)
+ for(std::vector<cmMakefile*>::const_iterator it =
+ this->Makefiles.begin(); it != this->Makefiles.end(); ++it)
{
- cmLocalGenerator* lg = *lgi;
- cmMakefile* mf = lg->GetMakefile();
- cmTargets& targets = mf->GetTargets();
- for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
+ std::string sd = (*it)->GetCurrentSourceDirectory();
+ if (sd == start_dir)
{
- cmTarget& target = t->second;
-
- // Consider the directory containing the target and all its
- // parents until something excludes the target.
- for(cmLocalGenerator* clg = lg; clg && !this->IsExcluded(clg, target);
- clg = clg->GetParent())
- {
- // This local generator includes the target.
- std::set<cmTarget*>& targetSet =
- this->LocalGeneratorToTargetMap[clg];
- targetSet.insert(&target);
-
- // Add dependencies of the included target. An excluded
- // target may still be included if it is a dependency of a
- // non-excluded target.
- TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(target);
- for(TargetDependSet::const_iterator ti = tgtdeps.begin();
- ti != tgtdeps.end(); ++ti)
- {
- targetSet.insert(*ti);
- }
- }
+ return *it;
}
}
+ return 0;
}
-
///! Find a local generator by its startdirectory
-cmLocalGenerator* cmGlobalGenerator::FindLocalGenerator(const char* start_dir)
+cmLocalGenerator*
+cmGlobalGenerator::FindLocalGenerator(const std::string& start_dir) const
{
- std::vector<cmLocalGenerator*>* gens = &this->LocalGenerators;
- for(unsigned int i = 0; i < gens->size(); ++i)
+ for(std::vector<cmLocalGenerator*>::const_iterator it =
+ this->LocalGenerators.begin(); it != this->LocalGenerators.end(); ++it)
{
- std::string sd = (*gens)[i]->GetMakefile()->GetStartDirectory();
+ std::string sd = (*it)->GetCurrentSourceDirectory();
if (sd == start_dir)
{
- return (*gens)[i];
+ return *it;
}
}
return 0;
}
//----------------------------------------------------------------------------
-void cmGlobalGenerator::AddAlias(const char *name, cmTarget *tgt)
+void cmGlobalGenerator::AddAlias(const std::string& name,
+ std::string const& tgtName)
{
- this->AliasTargets[name] = tgt;
+ this->AliasTargets[name] = tgtName;
}
//----------------------------------------------------------------------------
-bool cmGlobalGenerator::IsAlias(const char *name)
+bool cmGlobalGenerator::IsAlias(const std::string& name) const
{
return this->AliasTargets.find(name) != this->AliasTargets.end();
}
+void cmGlobalGenerator::IndexTarget(cmTarget* t)
+{
+ if (!t->IsImported() || t->IsImportedGloballyVisible())
+ {
+ this->TargetSearchIndex[t->GetName()] = t;
+ }
+}
+
+void cmGlobalGenerator::IndexGeneratorTarget(cmGeneratorTarget* gt)
+{
+ if (!gt->IsImported() || gt->IsImportedGloballyVisible())
+ {
+ this->GeneratorTargetSearchIndex[gt->GetName()] = gt;
+ }
+}
+
+cmTarget* cmGlobalGenerator::FindTargetImpl(std::string const& name) const
+{
+ TargetMap::const_iterator i = this->TargetSearchIndex.find(name);
+ if (i != this->TargetSearchIndex.end())
+ {
+ return i->second;
+ }
+ return 0;
+}
+
+cmGeneratorTarget*
+cmGlobalGenerator::FindGeneratorTargetImpl(std::string const& name) const
+{
+ GeneratorTargetMap::const_iterator i =
+ this->GeneratorTargetSearchIndex.find(name);
+ if (i != this->GeneratorTargetSearchIndex.end())
+ {
+ return i->second;
+ }
+ return 0;
+}
+
//----------------------------------------------------------------------------
cmTarget*
-cmGlobalGenerator::FindTarget(const char* project, const char* name,
- bool excludeAliases)
+cmGlobalGenerator::FindTarget(const std::string& name,
+ bool excludeAliases) const
{
- // if project specific
- if(project)
+ if (!excludeAliases)
{
- std::vector<cmLocalGenerator*>* gens = &this->ProjectMap[project];
- for(unsigned int i = 0; i < gens->size(); ++i)
+ std::map<std::string, std::string>::const_iterator ai =
+ this->AliasTargets.find(name);
+ if (ai != this->AliasTargets.end())
{
- cmTarget* ret = (*gens)[i]->GetMakefile()->FindTarget(name,
- excludeAliases);
- if(ret)
- {
- return ret;
- }
+ return this->FindTargetImpl(ai->second);
}
}
- // if all projects/directories
- else
+ return this->FindTargetImpl(name);
+}
+
+cmGeneratorTarget*
+cmGlobalGenerator::FindGeneratorTarget(const std::string& name) const
+{
+ std::map<std::string, std::string>::const_iterator ai =
+ this->AliasTargets.find(name);
+ if (ai != this->AliasTargets.end())
{
- if (!excludeAliases)
- {
- std::map<cmStdString, cmTarget*>::iterator ai
- = this->AliasTargets.find(name);
- if (ai != this->AliasTargets.end())
- {
- return ai->second;
- }
- }
- std::map<cmStdString,cmTarget *>::iterator i =
- this->TotalTargets.find ( name );
- if ( i != this->TotalTargets.end() )
- {
- return i->second;
- }
- i = this->ImportedTargets.find(name);
- if ( i != this->ImportedTargets.end() )
- {
- return i->second;
- }
+ return this->FindGeneratorTargetImpl(ai->second);
}
- return 0;
+ return this->FindGeneratorTargetImpl(name);
}
//----------------------------------------------------------------------------
-bool cmGlobalGenerator::NameResolvesToFramework(const std::string& libname)
+bool
+cmGlobalGenerator::NameResolvesToFramework(const std::string& libname) const
{
if(cmSystemTools::IsPathToFramework(libname.c_str()))
{
return true;
}
- if(cmTarget* tgt = this->FindTarget(0, libname.c_str()))
+ if(cmTarget* tgt = this->FindTarget(libname))
{
if(tgt->IsFrameworkOnApple())
{
@@ -1881,31 +2283,24 @@ inline std::string removeQuotes(const std::string& s)
return s;
}
-void cmGlobalGenerator::SetCMakeInstance(cmake* cm)
-{
- // Store a pointer to the cmake object instance.
- this->CMakeInstance = cm;
-}
-
void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
{
- cmMakefile* mf = this->LocalGenerators[0]->GetMakefile();
+ cmMakefile* mf = this->Makefiles[0];
const char* cmakeCfgIntDir = this->GetCMakeCFGIntDir();
- const char* cmakeCommand = mf->GetRequiredDefinition("CMAKE_COMMAND");
// CPack
- std::string workingDir = mf->GetStartOutputDirectory();
+ std::string workingDir = mf->GetCurrentBinaryDirectory();
cmCustomCommandLines cpackCommandLines;
std::vector<std::string> depends;
cmCustomCommandLine singleLine;
- singleLine.push_back(this->GetCMakeInstance()->GetCPackCommand());
+ singleLine.push_back(cmSystemTools::GetCPackCommand());
if ( cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.' )
{
singleLine.push_back("-C");
singleLine.push_back(cmakeCfgIntDir);
}
singleLine.push_back("--config");
- std::string configFile = mf->GetStartOutputDirectory();;
+ std::string configFile = mf->GetCurrentBinaryDirectory();;
configFile += "/CPackConfig.cmake";
std::string relConfigFile = "./CPackConfig.cmake";
singleLine.push_back(relConfigFile);
@@ -1929,7 +2324,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
= this->CreateGlobalTarget(this->GetPackageTargetName(),
"Run CPack packaging tool...",
&cpackCommandLines, depends,
- workingDir.c_str());
+ workingDir.c_str(), /*uses_terminal*/true);
}
// CPack source
const char* packageSourceTargetName = this->GetPackageSourceTargetName();
@@ -1939,9 +2334,9 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
cpackCommandLines.end());
singleLine.erase(singleLine.begin(), singleLine.end());
depends.erase(depends.begin(), depends.end());
- singleLine.push_back(this->GetCMakeInstance()->GetCPackCommand());
+ singleLine.push_back(cmSystemTools::GetCPackCommand());
singleLine.push_back("--config");
- configFile = mf->GetStartOutputDirectory();;
+ configFile = mf->GetCurrentBinaryDirectory();;
configFile += "/CPackSourceConfig.cmake";
relConfigFile = "./CPackSourceConfig.cmake";
singleLine.push_back(relConfigFile);
@@ -1953,8 +2348,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
= this->CreateGlobalTarget(packageSourceTargetName,
"Run CPack packaging tool for source...",
&cpackCommandLines, depends,
- workingDir.c_str()
- );
+ workingDir.c_str(), /*uses_terminal*/true);
}
}
@@ -1965,7 +2359,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
cpackCommandLines.end());
singleLine.erase(singleLine.begin(), singleLine.end());
depends.erase(depends.begin(), depends.end());
- singleLine.push_back(this->GetCMakeInstance()->GetCTestCommand());
+ singleLine.push_back(cmSystemTools::GetCTestCommand());
singleLine.push_back("--force-new-ctest-process");
if(cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.')
{
@@ -1979,7 +2373,8 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
cpackCommandLines.push_back(singleLine);
(*targets)[this->GetTestTargetName()]
= this->CreateGlobalTarget(this->GetTestTargetName(),
- "Running tests...", &cpackCommandLines, depends, 0);
+ "Running tests...", &cpackCommandLines, depends, 0,
+ /*uses_terminal*/true);
}
//Edit Cache
@@ -1991,30 +2386,31 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
singleLine.erase(singleLine.begin(), singleLine.end());
depends.erase(depends.begin(), depends.end());
- // Use CMAKE_EDIT_COMMAND for the edit_cache rule if it is defined.
- // Otherwise default to the interactive command-line interface.
- if(mf->GetDefinition("CMAKE_EDIT_COMMAND"))
+ // Use generator preference for the edit_cache rule if it is defined.
+ std::string edit_cmd = this->GetEditCacheCommand();
+ if (!edit_cmd.empty())
{
- singleLine.push_back(mf->GetDefinition("CMAKE_EDIT_COMMAND"));
+ singleLine.push_back(edit_cmd);
singleLine.push_back("-H$(CMAKE_SOURCE_DIR)");
singleLine.push_back("-B$(CMAKE_BINARY_DIR)");
cpackCommandLines.push_back(singleLine);
(*targets)[editCacheTargetName] =
this->CreateGlobalTarget(
editCacheTargetName, "Running CMake cache editor...",
- &cpackCommandLines, depends, 0);
+ &cpackCommandLines, depends, 0, /*uses_terminal*/true);
}
else
{
- singleLine.push_back(cmakeCommand);
- singleLine.push_back("-i");
- singleLine.push_back(".");
+ singleLine.push_back(cmSystemTools::GetCMakeCommand());
+ singleLine.push_back("-E");
+ singleLine.push_back("echo");
+ singleLine.push_back("No interactive CMake dialog available.");
cpackCommandLines.push_back(singleLine);
(*targets)[editCacheTargetName] =
this->CreateGlobalTarget(
editCacheTargetName,
- "Running interactive CMake command-line interface...",
- &cpackCommandLines, depends, 0);
+ "No interactive CMake dialog available...",
+ &cpackCommandLines, depends, 0, /*uses_terminal*/false);
}
}
@@ -2026,49 +2422,49 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
cpackCommandLines.end());
singleLine.erase(singleLine.begin(), singleLine.end());
depends.erase(depends.begin(), depends.end());
- singleLine.push_back(cmakeCommand);
+ singleLine.push_back(cmSystemTools::GetCMakeCommand());
singleLine.push_back("-H$(CMAKE_SOURCE_DIR)");
singleLine.push_back("-B$(CMAKE_BINARY_DIR)");
cpackCommandLines.push_back(singleLine);
(*targets)[rebuildCacheTargetName] =
this->CreateGlobalTarget(
rebuildCacheTargetName, "Running CMake to regenerate build system...",
- &cpackCommandLines, depends, 0);
+ &cpackCommandLines, depends, 0, /*uses_terminal*/true);
}
//Install
- if(this->InstallTargetEnabled)
+ bool skipInstallRules = mf->IsOn("CMAKE_SKIP_INSTALL_RULES");
+ if(this->InstallTargetEnabled && skipInstallRules)
+ {
+ mf->IssueMessage(cmake::WARNING,
+ "CMAKE_SKIP_INSTALL_RULES was enabled even though "
+ "installation rules have been specified");
+ }
+ else if(this->InstallTargetEnabled && !skipInstallRules)
{
if(!cmakeCfgIntDir || !*cmakeCfgIntDir || cmakeCfgIntDir[0] == '.')
{
- std::set<cmStdString>* componentsSet = &this->InstallComponents;
+ std::set<std::string>* componentsSet = &this->InstallComponents;
cpackCommandLines.erase(cpackCommandLines.begin(),
cpackCommandLines.end());
depends.erase(depends.begin(), depends.end());
- cmOStringStream ostr;
- if ( componentsSet->size() > 0 )
+ std::ostringstream ostr;
+ if (!componentsSet->empty())
{
- ostr << "Available install components are:";
- std::set<cmStdString>::iterator it;
- for (
- it = componentsSet->begin();
- it != componentsSet->end();
- ++ it )
- {
- ostr << " \"" << it->c_str() << "\"";
- }
+ ostr << "Available install components are: ";
+ ostr << cmWrap('"', *componentsSet, '"', " ");
}
else
{
ostr << "Only default component available";
}
- singleLine.push_back(ostr.str().c_str());
+ singleLine.push_back(ostr.str());
(*targets)["list_install_components"]
= this->CreateGlobalTarget("list_install_components",
ostr.str().c_str(),
- &cpackCommandLines, depends, 0);
+ &cpackCommandLines, depends, 0, /*uses_terminal*/false);
}
- std::string cmd = cmakeCommand;
+ std::string cmd = cmSystemTools::GetCMakeCommand();
cpackCommandLines.erase(cpackCommandLines.begin(),
cpackCommandLines.end());
singleLine.erase(singleLine.begin(), singleLine.end());
@@ -2086,18 +2482,29 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
depends.push_back(this->GetAllTargetName());
}
}
- if(mf->GetDefinition("CMake_BINARY_DIR"))
+ if(mf->GetDefinition("CMake_BINARY_DIR") &&
+ !mf->IsOn("CMAKE_CROSSCOMPILING"))
{
// We are building CMake itself. We cannot use the original
// executable to install over itself. The generator will
// automatically convert this name to the build-time location.
cmd = "cmake";
}
- singleLine.push_back(cmd.c_str());
+ singleLine.push_back(cmd);
if ( cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.' )
{
std::string cfgArg = "-DBUILD_TYPE=";
- cfgArg += mf->GetDefinition("CMAKE_CFG_INTDIR");
+ bool iosPlatform = mf->PlatformIsAppleIos();
+ if(iosPlatform)
+ {
+ cfgArg += "$(CONFIGURATION)";
+ singleLine.push_back(cfgArg);
+ cfgArg = "-DEFFECTIVE_PLATFORM_NAME=$(EFFECTIVE_PLATFORM_NAME)";
+ }
+ else
+ {
+ cfgArg += mf->GetDefinition("CMAKE_CFG_INTDIR");
+ }
singleLine.push_back(cfgArg);
}
singleLine.push_back("-P");
@@ -2106,7 +2513,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
(*targets)[this->GetInstallTargetName()] =
this->CreateGlobalTarget(
this->GetInstallTargetName(), "Install the project...",
- &cpackCommandLines, depends, 0);
+ &cpackCommandLines, depends, 0, /*uses_terminal*/true);
// install_local
if(const char* install_local = this->GetInstallLocalTargetName())
@@ -2122,7 +2529,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
(*targets)[install_local] =
this->CreateGlobalTarget(
install_local, "Installing only the local directory...",
- &cpackCommandLines, depends, 0);
+ &cpackCommandLines, depends, 0, /*uses_terminal*/true);
}
// install_strip
@@ -2139,7 +2546,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
(*targets)[install_strip] =
this->CreateGlobalTarget(
install_strip, "Installing the project stripped...",
- &cpackCommandLines, depends, 0);
+ &cpackCommandLines, depends, 0, /*uses_terminal*/true);
}
}
}
@@ -2147,8 +2554,8 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
//----------------------------------------------------------------------------
const char* cmGlobalGenerator::GetPredefinedTargetsFolder()
{
- const char* prop =
- this->GetCMakeInstance()->GetProperty("PREDEFINED_TARGETS_FOLDER");
+ const char* prop = this->GetCMakeInstance()->GetState()
+ ->GetGlobalProperty("PREDEFINED_TARGETS_FOLDER");
if (prop)
{
@@ -2161,7 +2568,8 @@ const char* cmGlobalGenerator::GetPredefinedTargetsFolder()
//----------------------------------------------------------------------------
bool cmGlobalGenerator::UseFolderProperty()
{
- const char* prop = this->GetCMakeInstance()->GetProperty("USE_FOLDERS");
+ const char* prop = this->GetCMakeInstance()->GetState()
+ ->GetGlobalProperty("USE_FOLDERS");
// If this property is defined, let the setter turn this on or off...
//
@@ -2177,61 +2585,31 @@ bool cmGlobalGenerator::UseFolderProperty()
}
//----------------------------------------------------------------------------
-void cmGlobalGenerator::EnableMinGWLanguage(cmMakefile *mf)
-{
- this->FindMakeProgram(mf);
- std::string makeProgram = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
- std::vector<std::string> locations;
- locations.push_back(cmSystemTools::GetProgramPath(makeProgram.c_str()));
- locations.push_back("/mingw/bin");
- locations.push_back("c:/mingw/bin");
- std::string tgcc = cmSystemTools::FindProgram("gcc", locations);
- std::string gcc = "gcc.exe";
- if(tgcc.size())
- {
- gcc = tgcc;
- }
- std::string tgxx = cmSystemTools::FindProgram("g++", locations);
- std::string gxx = "g++.exe";
- if(tgxx.size())
- {
- gxx = tgxx;
- }
- std::string trc = cmSystemTools::FindProgram("windres", locations);
- std::string rc = "windres.exe";
- if(trc.size())
- {
- rc = trc;
- }
- mf->AddDefinition("CMAKE_GENERATOR_CC", gcc.c_str());
- mf->AddDefinition("CMAKE_GENERATOR_CXX", gxx.c_str());
- mf->AddDefinition("CMAKE_GENERATOR_RC", rc.c_str());
-}
-
-//----------------------------------------------------------------------------
cmTarget cmGlobalGenerator::CreateGlobalTarget(
- const char* name, const char* message,
+ const std::string& name, const char* message,
const cmCustomCommandLines* commandLines,
std::vector<std::string> depends,
- const char* workingDirectory)
+ const char* workingDirectory,
+ bool uses_terminal)
{
// Package
cmTarget target;
- target.GetProperties().SetCMakeInstance(this->CMakeInstance);
- target.SetType(cmTarget::GLOBAL_TARGET, name);
+ target.SetType(cmState::GLOBAL_TARGET, name);
target.SetProperty("EXCLUDE_FROM_ALL","TRUE");
std::vector<std::string> no_outputs;
+ std::vector<std::string> no_byproducts;
std::vector<std::string> no_depends;
// Store the custom command in the target.
- cmCustomCommand cc(0, no_outputs, no_depends, *commandLines, 0,
- workingDirectory);
- target.GetPostBuildCommands().push_back(cc);
+ cmCustomCommand cc(0, no_outputs, no_byproducts, no_depends,
+ *commandLines, 0, workingDirectory);
+ cc.SetUsesTerminal(uses_terminal);
+ target.AddPostBuildCommand(cc);
target.SetProperty("EchoString", message);
std::vector<std::string>::iterator dit;
for ( dit = depends.begin(); dit != depends.end(); ++ dit )
{
- target.AddUtility(dit->c_str());
+ target.AddUtility(*dit);
}
// Organize in the "predefined targets" folder:
@@ -2261,18 +2639,22 @@ cmGlobalGenerator::GenerateRuleFile(std::string const& output) const
//----------------------------------------------------------------------------
std::string cmGlobalGenerator::GetSharedLibFlagsForLanguage(
- std::string const& l)
+ std::string const& l) const
{
- if(this->LanguageToOriginalSharedLibFlags.count(l) > 0)
+ std::map<std::string, std::string>::const_iterator it =
+ this->LanguageToOriginalSharedLibFlags.find(l);
+ if(it != this->LanguageToOriginalSharedLibFlags.end())
{
- return this->LanguageToOriginalSharedLibFlags[l];
+ return it->second;
}
return "";
}
//----------------------------------------------------------------------------
-void cmGlobalGenerator::AppendDirectoryForConfig(const char*, const char*,
- const char*, std::string&)
+void cmGlobalGenerator::AppendDirectoryForConfig(const std::string&,
+ const std::string&,
+ const std::string&,
+ std::string&)
{
// Subclasses that support multiple configurations should implement
// this method to append the subdirectory for the given build
@@ -2281,21 +2663,35 @@ void cmGlobalGenerator::AppendDirectoryForConfig(const char*, const char*,
//----------------------------------------------------------------------------
cmGlobalGenerator::TargetDependSet const&
-cmGlobalGenerator::GetTargetDirectDepends(cmTarget & target)
+cmGlobalGenerator::GetTargetDirectDepends(cmGeneratorTarget const* target)
{
- return this->TargetDependencies[&target];
+ return this->TargetDependencies[target];
}
-void cmGlobalGenerator::AddTarget(cmTarget* t)
+bool cmGlobalGenerator::IsReservedTarget(std::string const& name)
{
- if(t->IsImported())
- {
- this->ImportedTargets[t->GetName()] = t;
- }
- else
- {
- this->TotalTargets[t->GetName()] = t;
- }
+ // The following is a list of targets reserved
+ // by one or more of the cmake generators.
+
+ // Adding additional targets to this list will require a policy!
+ const char* reservedTargets[] =
+ {
+ "all", "ALL_BUILD",
+ "help",
+ "install", "INSTALL",
+ "preinstall",
+ "clean",
+ "edit_cache",
+ "rebuild_cache",
+ "test", "RUN_TESTS",
+ "package", "PACKAGE",
+ "package_source",
+ "ZERO_CHECK"
+ };
+
+ return std::find(cmArrayBegin(reservedTargets),
+ cmArrayEnd(reservedTargets), name)
+ != cmArrayEnd(reservedTargets);
}
void cmGlobalGenerator::SetExternalMakefileProjectGenerator(
@@ -2308,9 +2704,9 @@ void cmGlobalGenerator::SetExternalMakefileProjectGenerator(
}
}
-const char* cmGlobalGenerator::GetExtraGeneratorName() const
+std::string cmGlobalGenerator::GetExtraGeneratorName() const
{
- return this->ExtraGenerator==0 ? 0 : this->ExtraGenerator->GetName();
+ return this->ExtraGenerator? this->ExtraGenerator->GetName() : std::string();
}
void cmGlobalGenerator::FileReplacedDuringGenerate(const std::string& filename)
@@ -2344,15 +2740,15 @@ void cmGlobalGenerator::GetTargetSets(TargetDependSet& projectTargets,
{
continue;
}
- cmMakefile* mf = (*i)->GetMakefile();
// Get the targets in the makefile
- cmTargets &tgts = mf->GetTargets();
+ std::vector<cmGeneratorTarget*> tgts = (*i)->GetGeneratorTargets();
// loop over all the targets
- for (cmTargets::iterator l = tgts.begin(); l != tgts.end(); ++l)
+ for (std::vector<cmGeneratorTarget*>::iterator l = tgts.begin();
+ l != tgts.end(); ++l)
{
- cmTarget* target = &l->second;
+ cmGeneratorTarget* target = *l;
if(this->IsRootOnlyTarget(target) &&
- target->GetMakefile() != root->GetMakefile())
+ target->GetLocalGenerator() != root)
{
continue;
}
@@ -2365,14 +2761,14 @@ void cmGlobalGenerator::GetTargetSets(TargetDependSet& projectTargets,
}
//----------------------------------------------------------------------------
-bool cmGlobalGenerator::IsRootOnlyTarget(cmTarget* target)
+bool cmGlobalGenerator::IsRootOnlyTarget(cmGeneratorTarget* target) const
{
- return (target->GetType() == cmTarget::GLOBAL_TARGET ||
- strcmp(target->GetName(), this->GetAllTargetName()) == 0);
+ return (target->GetType() == cmState::GLOBAL_TARGET ||
+ target->GetName() == this->GetAllTargetName());
}
//----------------------------------------------------------------------------
-void cmGlobalGenerator::AddTargetDepends(cmTarget* target,
+void cmGlobalGenerator::AddTargetDepends(cmGeneratorTarget const* target,
TargetDependSet& projectTargets)
{
// add the target itself
@@ -2380,53 +2776,57 @@ void cmGlobalGenerator::AddTargetDepends(cmTarget* target,
{
// This is the first time we have encountered the target.
// Recursively follow its dependencies.
- TargetDependSet const& ts = this->GetTargetDirectDepends(*target);
+ TargetDependSet const& ts = this->GetTargetDirectDepends(target);
for(TargetDependSet::const_iterator i = ts.begin(); i != ts.end(); ++i)
{
- cmTarget* dtarget = *i;
- this->AddTargetDepends(dtarget, projectTargets);
+ this->AddTargetDepends(*i, projectTargets);
}
}
}
//----------------------------------------------------------------------------
-void cmGlobalGenerator::AddToManifest(const char* config,
- std::string const& f)
+void cmGlobalGenerator::AddToManifest(std::string const& f)
{
- // Add to the main manifest for this configuration.
- this->TargetManifest[config].insert(f);
-
// Add to the content listing for the file's directory.
std::string dir = cmSystemTools::GetFilenamePath(f);
std::string file = cmSystemTools::GetFilenameName(f);
- this->DirectoryContentMap[dir].insert(file);
+ DirectoryContent& dc = this->DirectoryContentMap[dir];
+ dc.Generated.insert(file);
+ dc.All.insert(file);
}
//----------------------------------------------------------------------------
-std::set<cmStdString> const&
+std::set<std::string> const&
cmGlobalGenerator::GetDirectoryContent(std::string const& dir, bool needDisk)
{
DirectoryContent& dc = this->DirectoryContentMap[dir];
- if(needDisk && !dc.LoadedFromDisk)
+ if(needDisk)
{
- // Load the directory content from disk.
- cmsys::Directory d;
- if(d.Load(dir.c_str()))
+ long mt = cmSystemTools::ModifiedTime(dir);
+ if (mt != dc.LastDiskTime)
{
- unsigned long n = d.GetNumberOfFiles();
- for(unsigned long i = 0; i < n; ++i)
+ // Reset to non-loaded directory content.
+ dc.All = dc.Generated;
+
+ // Load the directory content from disk.
+ cmsys::Directory d;
+ if(d.Load(dir))
{
- const char* f = d.GetFile(i);
- if(strcmp(f, ".") != 0 && strcmp(f, "..") != 0)
+ unsigned long n = d.GetNumberOfFiles();
+ for(unsigned long i = 0; i < n; ++i)
{
- dc.insert(f);
+ const char* f = d.GetFile(i);
+ if(strcmp(f, ".") != 0 && strcmp(f, "..") != 0)
+ {
+ dc.All.insert(f);
+ }
}
}
+ dc.LastDiskTime = mt;
}
- dc.LoadedFromDisk = true;
}
- return dc;
+ return dc.All;
}
//----------------------------------------------------------------------------
@@ -2455,9 +2855,9 @@ cmGlobalGenerator::AddRuleHash(const std::vector<std::string>& outputs,
}
// Shorten the output name (in expected use case).
- cmLocalGenerator* lg = this->GetLocalGenerators()[0];
- std::string fname = lg->Convert(outputs[0].c_str(),
- cmLocalGenerator::HOME_OUTPUT);
+ cmOutputConverter converter(this->GetMakefiles()[0]->GetStateSnapshot());
+ std::string fname = converter.Convert(
+ outputs[0], cmLocalGenerator::HOME_OUTPUT);
// Associate the hash with this output.
this->RuleHashes[fname] = hash;
@@ -2485,9 +2885,9 @@ void cmGlobalGenerator::CheckRuleHashes(std::string const& pfile,
std::string const& home)
{
#if defined(_WIN32) || defined(__CYGWIN__)
- std::ifstream fin(pfile.c_str(), std::ios::in | std::ios::binary);
+ cmsys::ifstream fin(pfile.c_str(), std::ios::in | std::ios::binary);
#else
- std::ifstream fin(pfile.c_str(), std::ios::in);
+ cmsys::ifstream fin(pfile.c_str(), std::ios::in);
#endif
if(!fin)
{
@@ -2510,7 +2910,7 @@ void cmGlobalGenerator::CheckRuleHashes(std::string const& pfile,
fname = line.substr(33, line.npos);
// Look for a hash for this file's rule.
- std::map<cmStdString, RuleHash>::const_iterator rhi =
+ std::map<std::string, RuleHash>::const_iterator rhi =
this->RuleHashes.find(fname);
if(rhi != this->RuleHashes.end())
{
@@ -2519,8 +2919,8 @@ void cmGlobalGenerator::CheckRuleHashes(std::string const& pfile,
{
// The rule has changed. Delete the output so it will be
// built again.
- fname = cmSystemTools::CollapseFullPath(fname.c_str(), home.c_str());
- cmSystemTools::RemoveFile(fname.c_str());
+ fname = cmSystemTools::CollapseFullPath(fname, home.c_str());
+ cmSystemTools::RemoveFile(fname);
}
}
else
@@ -2532,7 +2932,7 @@ void cmGlobalGenerator::CheckRuleHashes(std::string const& pfile,
// that if the feature is turned back on and the rule has
// changed the file is still rebuilt.
std::string fpath =
- cmSystemTools::CollapseFullPath(fname.c_str(), home.c_str());
+ cmSystemTools::CollapseFullPath(fname, home.c_str());
if(cmSystemTools::FileExists(fpath.c_str()))
{
RuleHash hash;
@@ -2549,13 +2949,13 @@ void cmGlobalGenerator::WriteRuleHashes(std::string const& pfile)
// Now generate a new persistence file with the current hashes.
if(this->RuleHashes.empty())
{
- cmSystemTools::RemoveFile(pfile.c_str());
+ cmSystemTools::RemoveFile(pfile);
}
else
{
cmGeneratedFileStream fout(pfile.c_str());
fout << "# Hashes of file build rules.\n";
- for(std::map<cmStdString, RuleHash>::const_iterator
+ for(std::map<std::string, RuleHash>::const_iterator
rhi = this->RuleHashes.begin(); rhi != this->RuleHashes.end(); ++rhi)
{
fout.write(rhi->second.Data, 32);
@@ -2567,35 +2967,51 @@ void cmGlobalGenerator::WriteRuleHashes(std::string const& pfile)
//----------------------------------------------------------------------------
void cmGlobalGenerator::WriteSummary()
{
- cmMakefile* mf = this->LocalGenerators[0]->GetMakefile();
-
// Record all target directories in a central location.
- std::string fname = mf->GetHomeOutputDirectory();
+ std::string fname = this->CMakeInstance->GetHomeOutputDirectory();
fname += cmake::GetCMakeFilesDirectory();
fname += "/TargetDirectories.txt";
cmGeneratedFileStream fout(fname.c_str());
- // Generate summary information files for each target.
- std::string dir;
- for(std::map<cmStdString,cmTarget *>::const_iterator ti =
- this->TotalTargets.begin(); ti != this->TotalTargets.end(); ++ti)
+ for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i)
{
- this->WriteSummary(ti->second);
- fout << ti->second->GetSupportDirectory() << "\n";
+ std::vector<cmGeneratorTarget*> tgts =
+ this->LocalGenerators[i]->GetGeneratorTargets();
+ for (std::vector<cmGeneratorTarget*>::iterator it = tgts.begin();
+ it != tgts.end(); ++it)
+ {
+ if ((*it)->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ continue;
+ }
+ this->WriteSummary(*it);
+ fout << (*it)->GetSupportDirectory() << "\n";
+ }
}
}
//----------------------------------------------------------------------------
-void cmGlobalGenerator::WriteSummary(cmTarget* target)
+void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target)
{
// Place the labels file in a per-target support directory.
std::string dir = target->GetSupportDirectory();
std::string file = dir;
file += "/Labels.txt";
+ std::string json_file = dir + "/Labels.json";
+#ifdef CMAKE_BUILD_WITH_CMAKE
// Check whether labels are enabled for this target.
if(const char* value = target->GetProperty("LABELS"))
{
+ Json::Value lj_root(Json::objectValue);
+ Json::Value& lj_target =
+ lj_root["target"] = Json::objectValue;
+ lj_target["name"] = target->GetName();
+ Json::Value& lj_target_labels =
+ lj_target["labels"] = Json::arrayValue;
+ Json::Value& lj_sources =
+ lj_root["sources"] = Json::arrayValue;
+
cmSystemTools::MakeDirectory(dir.c_str());
cmGeneratedFileStream fout(file.c_str());
@@ -2610,32 +3026,56 @@ void cmGlobalGenerator::WriteSummary(cmTarget* target)
li != labels.end(); ++li)
{
fout << " " << *li << "\n";
+ lj_target_labels.append(*li);
}
}
// List the source files with any per-source labels.
fout << "# Source files and their labels\n";
- std::vector<cmSourceFile*> const& sources = target->GetSourceFiles();
+ std::vector<cmSourceFile*> sources;
+ std::vector<std::string> configs;
+ target->Target->GetMakefile()->GetConfigurations(configs);
+ if (configs.empty())
+ {
+ configs.push_back("");
+ }
+ for(std::vector<std::string>::const_iterator ci = configs.begin();
+ ci != configs.end(); ++ci)
+ {
+ target->GetSourceFiles(sources, *ci);
+ }
+ std::vector<cmSourceFile*>::const_iterator sourcesEnd
+ = cmRemoveDuplicates(sources);
for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
- si != sources.end(); ++si)
+ si != sourcesEnd; ++si)
{
+ Json::Value& lj_source = lj_sources.append(Json::objectValue);
cmSourceFile* sf = *si;
- fout << sf->GetFullPath() << "\n";
+ std::string const& sfp = sf->GetFullPath();
+ fout << sfp << "\n";
+ lj_source["file"] = sfp;
if(const char* svalue = sf->GetProperty("LABELS"))
{
labels.clear();
+ Json::Value& lj_source_labels =
+ lj_source["labels"] = Json::arrayValue;
cmSystemTools::ExpandListArgument(svalue, labels);
for(std::vector<std::string>::const_iterator li = labels.begin();
li != labels.end(); ++li)
{
fout << " " << *li << "\n";
+ lj_source_labels.append(*li);
}
}
}
+ cmGeneratedFileStream json_fout(json_file.c_str());
+ json_fout << lj_root;
}
else
+#endif
{
- cmSystemTools::RemoveFile(file.c_str());
+ cmSystemTools::RemoveFile(file);
+ cmSystemTools::RemoveFile(json_file);
}
}
@@ -2653,42 +3093,80 @@ std::string cmGlobalGenerator::EscapeJSON(const std::string& s) {
}
//----------------------------------------------------------------------------
-void cmGlobalGenerator::AddEvaluationFile(const std::string &inputFile,
- cmsys::auto_ptr<cmCompiledGeneratorExpression> outputExpr,
- cmMakefile *makefile,
- cmsys::auto_ptr<cmCompiledGeneratorExpression> condition,
- bool inputIsContent)
+void cmGlobalGenerator::SetFilenameTargetDepends(cmSourceFile* sf,
+ std::set<cmGeneratorTarget const*> tgts)
{
- this->EvaluationFiles.push_back(
- new cmGeneratorExpressionEvaluationFile(inputFile, outputExpr,
- makefile, condition,
- inputIsContent));
+ this->FilenameTargetDepends[sf] = tgts;
+}
+
+//----------------------------------------------------------------------------
+std::set<cmGeneratorTarget const*> const&
+cmGlobalGenerator::GetFilenameTargetDepends(cmSourceFile* sf) const {
+ return this->FilenameTargetDepends[sf];
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::CreateEvaluationSourceFiles(
+ std::string const& config) const
+{
+ unsigned int i;
+ for (i = 0; i < this->LocalGenerators.size(); ++i)
+ {
+ this->LocalGenerators[i]->CreateEvaluationFileOutputs(config);
+ }
}
//----------------------------------------------------------------------------
void cmGlobalGenerator::ProcessEvaluationFiles()
{
- std::set<std::string> generatedFiles;
- for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator
- li = this->EvaluationFiles.begin();
- li != this->EvaluationFiles.end();
- ++li)
+ std::vector<std::string> generatedFiles;
+ unsigned int i;
+ for (i = 0; i < this->LocalGenerators.size(); ++i)
{
- (*li)->Generate();
- if (cmSystemTools::GetFatalErrorOccured())
- {
- return;
- }
- std::vector<std::string> files = (*li)->GetFiles();
- for(std::vector<std::string>::const_iterator fi = files.begin();
- fi != files.end(); ++fi)
- {
- if (!generatedFiles.insert(*fi).second)
- {
- cmSystemTools::Error("File to be generated by multiple different "
- "commands: ", fi->c_str());
- return;
- }
- }
+ this->LocalGenerators[i]->ProcessEvaluationFiles(generatedFiles);
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalGenerator::ExpandCFGIntDir(const std::string& str,
+ const std::string& /*config*/) const
+{
+ return str;
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalGenerator::GenerateCPackPropertiesFile()
+{
+ cmake::InstalledFilesMap const& installedFiles =
+ this->CMakeInstance->GetInstalledFiles();
+
+ cmLocalGenerator* lg = this->LocalGenerators[0];
+ cmMakefile* mf = lg->GetMakefile();
+
+ std::vector<std::string> configs;
+ std::string config = mf->GetConfigurations(configs, false);
+
+ std::string path = this->CMakeInstance->GetHomeOutputDirectory();
+ path += "/CPackProperties.cmake";
+
+ if(!cmSystemTools::FileExists(path.c_str()) && installedFiles.empty())
+ {
+ return true;
}
+
+ cmGeneratedFileStream file(path.c_str());
+ file << "# CPack properties\n";
+
+ for(cmake::InstalledFilesMap::const_iterator i = installedFiles.begin();
+ i != installedFiles.end(); ++i)
+ {
+ cmInstalledFile const& installedFile = i->second;
+
+ cmCPackPropertiesGenerator cpackPropertiesGenerator(
+ lg, installedFile, configs);
+
+ cpackPropertiesGenerator.Generate(file, config, configs);
+ }
+
+ return true;
}
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 80916ae59..48fa70406 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -21,19 +21,29 @@
#include "cmExportSetMap.h" // For cmExportSetMap
#include "cmGeneratorTarget.h"
#include "cmGeneratorExpression.h"
+#include "cmState.h"
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+# include "cmFileLockPool.h"
+# ifdef CMake_HAVE_CXX11_UNORDERED_MAP
+# include <unordered_map>
+# else
+# include <cmsys/hash_map.hxx>
+# endif
+#endif
class cmake;
class cmGeneratorTarget;
-class cmGeneratorExpressionEvaluationFile;
class cmMakefile;
class cmLocalGenerator;
class cmExternalMakefileProjectGenerator;
class cmTarget;
class cmInstallTargetGenerator;
class cmInstallFilesGenerator;
+class cmExportBuildFileGenerator;
/** \class cmGlobalGenerator
- * \brief Responable for overseeing the generation process for the entire tree
+ * \brief Responsible for overseeing the generation process for the entire tree
*
* Subclasses of this class generate makefiles for various
* platforms.
@@ -42,18 +52,30 @@ class cmGlobalGenerator
{
public:
///! Free any memory allocated with the GlobalGenerator
- cmGlobalGenerator();
+ cmGlobalGenerator(cmake* cm);
virtual ~cmGlobalGenerator();
- ///! Create a local generator appropriate to this Global Generator
- virtual cmLocalGenerator *CreateLocalGenerator();
+ virtual cmLocalGenerator*
+ CreateLocalGenerator(cmMakefile* mf);
///! Get the name for this generator
- virtual const char *GetName() const { return "Generic"; };
+ virtual std::string GetName() const { return "Generic"; }
+
+ /** Check whether the given name matches the current generator. */
+ virtual bool MatchesGeneratorName(const std::string& name) const
+ { return this->GetName() == name; }
+
+ /** Tell the generator about the target system. */
+ virtual bool SetSystemName(std::string const&, cmMakefile*)
+ { return true; }
+
+ /** Set the generator-specific platform name. Returns true if platform
+ is supported and false otherwise. */
+ virtual bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf);
/** Set the generator-specific toolset name. Returns true if toolset
is supported and false otherwise. */
- virtual bool SetGeneratorToolset(std::string const& ts);
+ virtual bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf);
/**
* Create LocalGenerators and process the CMakeLists files. This does not
@@ -61,6 +83,19 @@ public:
*/
virtual void Configure();
+ bool Compute();
+ virtual void AddExtraIDETargets() {}
+
+ enum TargetTypes {
+ AllTargets,
+ ImportedOnly
+ };
+
+ void CreateImportedGenerationObjects(cmMakefile* mf,
+ std::vector<std::string> const& targets,
+ std::vector<cmGeneratorTarget const*>& exports);
+ void CreateGenerationObjects(TargetTypes targetTypes = AllTargets);
+
/**
* Generate the all required files for building this project/tree. This
* basically creates a series of LocalGenerators for each directory and
@@ -71,12 +106,12 @@ public:
/**
* Set/Get and Clear the enabled languages.
*/
- void SetLanguageEnabled(const char*, cmMakefile* mf);
- bool GetLanguageEnabled(const char*) const;
+ void SetLanguageEnabled(const std::string&, cmMakefile* mf);
+ bool GetLanguageEnabled(const std::string&) const;
void ClearEnabledLanguages();
- void GetEnabledLanguages(std::vector<std::string>& lang);
+ void GetEnabledLanguages(std::vector<std::string>& lang) const;
/**
- * Try to determine system infomation such as shared library
+ * Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
@@ -87,21 +122,22 @@ public:
* Intended to be called from EnableLanguage.
*/
void ResolveLanguageCompiler(const std::string &lang, cmMakefile *mf,
- bool optional);
+ bool optional) const;
/**
- * Try to determine system infomation, get it from another generator
+ * Try to determine system information, get it from another generator
*/
- virtual void EnableLanguagesFromGenerator(cmGlobalGenerator *gen,
+ void EnableLanguagesFromGenerator(cmGlobalGenerator *gen,
cmMakefile* mf);
/**
* Try running cmake and building a file. This is used for dynamically
* loaded commands, not as part of the usual build process.
*/
- virtual int TryCompile(const char *srcdir, const char *bindir,
- const char *projectName, const char *targetName,
- bool fast, std::string *output, cmMakefile* mf);
+ int TryCompile(const std::string& srcdir, const std::string& bindir,
+ const std::string& projectName,
+ const std::string& targetName,
+ bool fast, std::string& output, cmMakefile* mf);
/**
@@ -110,59 +146,65 @@ public:
* empty then all is assumed. clean indicates if a "make clean" should be
* done first.
*/
- int Build(const char *srcdir, const char *bindir,
- const char *projectName, const char *targetName,
- std::string *output,
- const char *makeProgram, const char *config,
- bool clean, bool fast,
+ int Build(const std::string& srcdir, const std::string& bindir,
+ const std::string& projectName, const std::string& targetName,
+ std::string& output,
+ const std::string& makeProgram, const std::string& config,
+ bool clean, bool fast, bool verbose,
double timeout,
cmSystemTools::OutputOption outputflag=cmSystemTools::OUTPUT_NONE,
- const char* extraOptions = 0,
std::vector<std::string> const& nativeOptions =
std::vector<std::string>());
- virtual std::string GenerateBuildCommand(
- const char* makeProgram,
- const char *projectName, const char *projectDir,
- const char* additionalOptions,
- const char *targetName, const char* config,
- bool ignoreErrors, bool fast);
-
-
- ///! Set the CMake instance
- void SetCMakeInstance(cmake *cm);
+ virtual void GenerateBuildCommand(
+ std::vector<std::string>& makeCommand,
+ const std::string& makeProgram,
+ const std::string& projectName, const std::string& projectDir,
+ const std::string& targetName, const std::string& config,
+ bool fast, bool verbose,
+ std::vector<std::string> const& makeOptions = std::vector<std::string>()
+ );
+
+ /** Generate a "cmake --build" call for a given target and config. */
+ std::string GenerateCMakeBuildCommand(const std::string& target,
+ const std::string& config,
+ const std::string& native,
+ bool ignoreErrors);
///! Get the CMake instance
- cmake *GetCMakeInstance() { return this->CMakeInstance; }
- const cmake *GetCMakeInstance() const { return this->CMakeInstance; }
+ cmake *GetCMakeInstance() const { return this->CMakeInstance; }
void SetConfiguredFilesPath(cmGlobalGenerator* gen);
+ const std::vector<cmMakefile*>& GetMakefiles() const {
+ return this->Makefiles;}
const std::vector<cmLocalGenerator *>& GetLocalGenerators() const {
return this->LocalGenerators;}
- cmLocalGenerator* GetCurrentLocalGenerator()
- {return this->CurrentLocalGenerator;}
+ cmMakefile* GetCurrentMakefile() const
+ {
+ return this->CurrentMakefile;
+ }
- void SetCurrentLocalGenerator(cmLocalGenerator* lg)
- {this->CurrentLocalGenerator = lg;}
+ void SetCurrentMakefile(cmMakefile* mf)
+ {this->CurrentMakefile = mf;}
- void AddLocalGenerator(cmLocalGenerator *lg);
+ void AddMakefile(cmMakefile *mf);
///! Set an generator for an "external makefile based project"
void SetExternalMakefileProjectGenerator(
cmExternalMakefileProjectGenerator *extraGenerator);
- const char* GetExtraGeneratorName() const;
+ std::string GetExtraGeneratorName() const;
void AddInstallComponent(const char* component);
- const std::set<cmStdString>* GetInstallComponents() const
+ const std::set<std::string>* GetInstallComponents() const
{ return &this->InstallComponents; }
cmExportSetMap& GetExportSets() {return this->ExportSets;}
/** Add a file to the manifest of generated targets for a configuration. */
- void AddToManifest(const char* config, std::string const& f);
+ void AddToManifest(std::string const& f);
void EnableInstallTarget();
@@ -172,17 +214,21 @@ public:
bool GetToolSupportsColor() const { return this->ToolSupportsColor; }
///! return the language for the given extension
- const char* GetLanguageFromExtension(const char* ext);
+ std::string GetLanguageFromExtension(const char* ext) const;
///! is an extension to be ignored
- bool IgnoreFile(const char* ext);
- ///! What is the preference for linkers and this language (None or Prefered)
- int GetLinkerPreference(const char* lang);
+ bool IgnoreFile(const char* ext) const;
+ ///! What is the preference for linkers and this language (None or Preferred)
+ int GetLinkerPreference(const std::string& lang) const;
///! What is the object file extension for a given source file?
- const char* GetLanguageOutputExtension(cmSourceFile const&);
+ std::string GetLanguageOutputExtension(cmSourceFile const&) const;
///! What is the configurations directory variable called?
virtual const char* GetCMakeCFGIntDir() const { return "."; }
+ ///! expand CFGIntDir for a configuration
+ virtual std::string ExpandCFGIntDir(const std::string& str,
+ const std::string& config) const;
+
/** Get whether the generator should use a script for link commands. */
bool GetUseLinkScript() const { return this->UseLinkScript; }
@@ -193,46 +239,49 @@ public:
/*
* Determine what program to use for building the project.
*/
- void FindMakeProgram(cmMakefile*);
+ virtual void FindMakeProgram(cmMakefile*);
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /** Is this the Visual Studio 6 generator? */
+ bool IsForVS6() const { return this->GetName() == "Visual Studio 6"; }
+#endif
///! Find a target by name by searching the local generators.
- cmTarget* FindTarget(const char* project, const char* name,
- bool excludeAliases = false);
+ cmTarget* FindTarget(const std::string& name,
+ bool excludeAliases = false) const;
- void AddAlias(const char *name, cmTarget *tgt);
- bool IsAlias(const char *name);
+ cmGeneratorTarget* FindGeneratorTarget(const std::string& name) const;
+
+ void AddAlias(const std::string& name, const std::string& tgtName);
+ bool IsAlias(const std::string& name) const;
/** Determine if a name resolves to a framework on disk or a built target
that is a framework. */
- bool NameResolvesToFramework(const std::string& libname);
+ bool NameResolvesToFramework(const std::string& libname) const;
- /** If check to see if the target is linked to by any other
- target in the project */
- bool IsDependedOn(const char* project, cmTarget* target);
+ cmMakefile* FindMakefile(const std::string& start_dir) const;
///! Find a local generator by its startdirectory
- cmLocalGenerator* FindLocalGenerator(const char* start_dir);
+ cmLocalGenerator* FindLocalGenerator(const std::string& start_dir) const;
/** Append the subdirectory for the given configuration. If anything is
appended the given prefix and suffix will be appended around it, which
is useful for leading or trailing slashes. */
- virtual void AppendDirectoryForConfig(const char* prefix,
- const char* config,
- const char* suffix,
+ virtual void AppendDirectoryForConfig(const std::string& prefix,
+ const std::string& config,
+ const std::string& suffix,
std::string& dir);
- /** Get the manifest of all targets that will be built for each
- configuration. This is valid during generation only. */
- cmTargetManifest const& GetTargetManifest() const
- { return this->TargetManifest; }
-
- /** Get the content of a directory. Directory listings are loaded
- from disk at most once and cached. During the generation step
- the content will include the target files to be built even if
+ /** Get the content of a directory. Directory listings are cached
+ and re-loaded from disk only when modified. During the generation
+ step the content will include the target files to be built even if
they do not yet exist. */
- std::set<cmStdString> const& GetDirectoryContent(std::string const& dir,
+ std::set<std::string> const& GetDirectoryContent(std::string const& dir,
bool needDisk = true);
- void AddTarget(cmTarget* t);
+ void IndexTarget(cmTarget* t);
+ void IndexGeneratorTarget(cmGeneratorTarget* gt);
+
+ static bool IsReservedTarget(std::string const& name);
virtual const char* GetAllTargetName() const { return "ALL_BUILD"; }
virtual const char* GetInstallTargetName() const { return "INSTALL"; }
@@ -246,17 +295,18 @@ public:
virtual const char* GetRebuildCacheTargetName() const { return 0; }
virtual const char* GetCleanTargetName() const { return 0; }
+ // Lookup edit_cache target command preferred by this generator.
+ virtual std::string GetEditCacheCommand() const { return ""; }
+
// Class to track a set of dependencies.
typedef cmTargetDependSet TargetDependSet;
// what targets does the specified target depend on directly
// via a target_link_libraries or add_dependencies
- TargetDependSet const& GetTargetDirectDepends(cmTarget & target);
+ TargetDependSet const& GetTargetDirectDepends(
+ const cmGeneratorTarget* target);
- /** Get per-target generator information. */
- cmGeneratorTarget* GetGeneratorTarget(cmTarget*) const;
-
- const std::map<cmStdString, std::vector<cmLocalGenerator*> >& GetProjectMap()
+ const std::map<std::string, std::vector<cmLocalGenerator*> >& GetProjectMap()
const {return this->ProjectMap;}
// track files replaced during a Generate
@@ -267,122 +317,171 @@ public:
std::string const& content);
/** Return whether the given binary directory is unused. */
- bool BinaryDirectoryIsNew(const char* dir)
+ bool BinaryDirectoryIsNew(const std::string& dir)
{
return this->BinaryDirectories.insert(dir).second;
}
- /** Supported systems creates a GUID for the given name */
- virtual void CreateGUID(const char*) {}
/** Return true if the generated build tree may contain multiple builds.
i.e. "Can I build Debug and Release in the same tree?" */
virtual bool IsMultiConfig() { return false; }
- std::string GetSharedLibFlagsForLanguage(std::string const& lang);
+ std::string GetSharedLibFlagsForLanguage(std::string const& lang) const;
/** Generate an <output>.rule file path for a given command output. */
virtual std::string GenerateRuleFile(std::string const& output) const;
static std::string EscapeJSON(const std::string& s);
- void AddEvaluationFile(const std::string &inputFile,
- cmsys::auto_ptr<cmCompiledGeneratorExpression> outputName,
- cmMakefile *makefile,
- cmsys::auto_ptr<cmCompiledGeneratorExpression> condition,
- bool inputIsContent);
-
void ProcessEvaluationFiles();
+ std::map<std::string, cmExportBuildFileGenerator*>& GetBuildExportSets()
+ {return this->BuildExportSets;}
+ void AddBuildExportSet(cmExportBuildFileGenerator*);
+ void AddBuildExportExportSet(cmExportBuildFileGenerator*);
+ bool IsExportedTargetsFile(const std::string &filename) const;
+ bool GenerateImportFile(const std::string &file);
+ cmExportBuildFileGenerator*
+ GetExportedTargetsFile(const std::string &filename) const;
+ void AddCMP0042WarnTarget(const std::string& target);
+
+ virtual void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const;
+
+ bool GenerateCPackPropertiesFile();
+
+ void CreateEvaluationSourceFiles(std::string const& config) const;
+
+ void SetFilenameTargetDepends(cmSourceFile* sf,
+ std::set<const cmGeneratorTarget*> tgts);
+ const std::set<const cmGeneratorTarget*>&
+ GetFilenameTargetDepends(cmSourceFile* sf) const;
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ cmFileLockPool& GetFileLockPool() { return FileLockPool; }
+#endif
+
+ bool GetConfigureDoneCMP0026() const
+ { return this->ConfigureDoneCMP0026AndCMP0024; }
+
+ std::string MakeSilentFlag;
protected:
typedef std::vector<cmLocalGenerator*> GeneratorVector;
// for a project collect all its targets by following depend
// information, and also collect all the targets
- virtual void GetTargetSets(TargetDependSet& projectTargets,
+ void GetTargetSets(TargetDependSet& projectTargets,
TargetDependSet& originalTargets,
cmLocalGenerator* root, GeneratorVector const&);
- virtual bool IsRootOnlyTarget(cmTarget* target);
- void AddTargetDepends(cmTarget* target, TargetDependSet& projectTargets);
- void SetLanguageEnabledFlag(const char* l, cmMakefile* mf);
- void SetLanguageEnabledMaps(const char* l, cmMakefile* mf);
- void FillExtensionToLanguageMap(const char* l, cmMakefile* mf);
+ bool IsRootOnlyTarget(cmGeneratorTarget* target) const;
+ void AddTargetDepends(const cmGeneratorTarget* target,
+ TargetDependSet& projectTargets);
+ void SetLanguageEnabledFlag(const std::string& l, cmMakefile* mf);
+ void SetLanguageEnabledMaps(const std::string& l, cmMakefile* mf);
+ void FillExtensionToLanguageMap(const std::string& l, cmMakefile* mf);
+ virtual void PrintCompilerAdvice(std::ostream& os, std::string const& lang,
+ const char* envVar) const;
virtual bool ComputeTargetDepends();
- virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS();
+ virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const;
- bool CheckTargets();
- void CreateAutomocTargets();
+ std::vector<const cmGeneratorTarget*> CreateQtAutoGeneratorsTargets();
+ std::string SelectMakeProgram(const std::string& makeProgram,
+ const std::string& makeDefault = "") const;
// Fill the ProjectMap, this must be called after LocalGenerators
// has been populated.
void FillProjectMap();
- void CheckLocalGenerators();
- bool IsExcluded(cmLocalGenerator* root, cmLocalGenerator* gen);
- bool IsExcluded(cmLocalGenerator* root, cmTarget& target);
- void FillLocalGeneratorToTargetMap();
+ void CheckTargetProperties();
+ bool IsExcluded(cmState::Snapshot const& root,
+ cmState::Snapshot const& snp) const;
+ bool IsExcluded(cmLocalGenerator* root, cmLocalGenerator* gen) const;
+ bool IsExcluded(cmLocalGenerator* root, cmGeneratorTarget* target) const;
+ virtual void InitializeProgressMarks() {}
void CreateDefaultGlobalTargets(cmTargets* targets);
- cmTarget CreateGlobalTarget(const char* name, const char* message,
+ cmTarget CreateGlobalTarget(const std::string& name, const char* message,
const cmCustomCommandLines* commandLines,
- std::vector<std::string> depends, const char* workingDir);
+ std::vector<std::string> depends, const char* workingDir,
+ bool uses_terminal);
- bool NeedSymbolicMark;
- bool UseLinkScript;
- bool ForceUnixPaths;
- bool ToolSupportsColor;
- cmStdString FindMakeProgramFile;
- cmStdString ConfiguredFilesPath;
+ std::string FindMakeProgramFile;
+ std::string ConfiguredFilesPath;
cmake *CMakeInstance;
+ std::vector<cmMakefile*> Makefiles;
std::vector<cmLocalGenerator *> LocalGenerators;
- cmLocalGenerator* CurrentLocalGenerator;
+ cmMakefile* CurrentMakefile;
// map from project name to vector of local generators in that project
- std::map<cmStdString, std::vector<cmLocalGenerator*> > ProjectMap;
- std::map<cmLocalGenerator*, std::set<cmTarget *> > LocalGeneratorToTargetMap;
+ std::map<std::string, std::vector<cmLocalGenerator*> > ProjectMap;
// Set of named installation components requested by the project.
- std::set<cmStdString> InstallComponents;
- bool InstallTargetEnabled;
+ std::set<std::string> InstallComponents;
// Sets of named target exports
cmExportSetMap ExportSets;
+ std::map<std::string, cmExportBuildFileGenerator*> BuildExportSets;
+ std::map<std::string, cmExportBuildFileGenerator*> BuildExportExportSets;
+
+ std::map<std::string, std::string> AliasTargets;
- // Manifest of all targets that will be built for each configuration.
- // This is computed just before local generators generate.
- cmTargetManifest TargetManifest;
+ cmTarget* FindTargetImpl(std::string const& name) const;
- // All targets in the entire project.
- std::map<cmStdString,cmTarget *> TotalTargets;
- std::map<cmStdString,cmTarget *> AliasTargets;
- std::map<cmStdString,cmTarget *> ImportedTargets;
- std::vector<cmGeneratorExpressionEvaluationFile*> EvaluationFiles;
+ cmGeneratorTarget* FindGeneratorTargetImpl(std::string const& name) const;
+ cmGeneratorTarget*
+ FindImportedGeneratorTargetImpl(std::string const& name) const;
- virtual const char* GetPredefinedTargetsFolder();
+ const char* GetPredefinedTargetsFolder();
virtual bool UseFolderProperty();
- void EnableMinGWLanguage(cmMakefile *mf);
private:
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+# ifdef CMake_HAVE_CXX11_UNORDERED_MAP
+ typedef std::unordered_map<std::string, cmTarget*> TargetMap;
+ typedef std::unordered_map<std::string, cmGeneratorTarget*>
+ GeneratorTargetMap;
+# else
+ typedef cmsys::hash_map<std::string, cmTarget*> TargetMap;
+ typedef cmsys::hash_map<std::string, cmGeneratorTarget*> GeneratorTargetMap;
+# endif
+#else
+ typedef std::map<std::string,cmTarget *> TargetMap;
+ typedef std::map<std::string,cmGeneratorTarget *> GeneratorTargetMap;
+#endif
+ // Map efficiently from target name to cmTarget instance.
+ // Do not use this structure for looping over all targets.
+ // It contains both normal and globally visible imported targets.
+ TargetMap TargetSearchIndex;
+ GeneratorTargetMap GeneratorTargetSearchIndex;
+
cmMakefile* TryCompileOuterMakefile;
- float FirstTimeProgress;
// If you add a new map here, make sure it is copied
// in EnableLanguagesFromGenerator
- std::map<cmStdString, bool> IgnoreExtensions;
- std::map<cmStdString, bool> LanguageEnabled;
- std::set<cmStdString> LanguagesReady; // Ready for try_compile
- std::map<cmStdString, cmStdString> OutputExtensions;
- std::map<cmStdString, cmStdString> LanguageToOutputExtension;
- std::map<cmStdString, cmStdString> ExtensionToLanguage;
- std::map<cmStdString, int> LanguageToLinkerPreference;
- std::map<cmStdString, cmStdString> LanguageToOriginalSharedLibFlags;
+ std::map<std::string, bool> IgnoreExtensions;
+ std::set<std::string> LanguagesReady; // Ready for try_compile
+ std::map<std::string, std::string> OutputExtensions;
+ std::map<std::string, std::string> LanguageToOutputExtension;
+ std::map<std::string, std::string> ExtensionToLanguage;
+ std::map<std::string, int> LanguageToLinkerPreference;
+ std::map<std::string, std::string> LanguageToOriginalSharedLibFlags;
// Record hashes for rules and outputs.
struct RuleHash { char Data[32]; };
- std::map<cmStdString, RuleHash> RuleHashes;
+ std::map<std::string, RuleHash> RuleHashes;
void CheckRuleHashes();
void CheckRuleHashes(std::string const& pfile, std::string const& home);
void WriteRuleHashes(std::string const& pfile);
void WriteSummary();
- void WriteSummary(cmTarget* target);
- void FinalizeTargetCompileDefinitions();
+ void WriteSummary(cmGeneratorTarget* target);
+ void FinalizeTargetCompileInfo();
+
+ virtual void ForceLinkerLanguages();
+
+ void CreateLocalGenerators();
+
+ void CheckCompilerIdCompatibility(cmMakefile* mf,
+ std::string const& lang) const;
+
+ void ComputeBuildFileGenerators();
cmExternalMakefileProjectGenerator* ExtraGenerator;
@@ -390,28 +489,53 @@ private:
std::vector<std::string> FilesReplacedDuringGenerate;
// Store computed inter-target dependencies.
- typedef std::map<cmTarget *, TargetDependSet> TargetDependMap;
+ typedef std::map<cmGeneratorTarget const*, TargetDependSet> TargetDependMap;
TargetDependMap TargetDependencies;
- // Per-target generator information.
- cmGeneratorTargetsType GeneratorTargets;
- void CreateGeneratorTargets();
- void ClearGeneratorTargets();
- virtual void ComputeTargetObjects(cmGeneratorTarget* gt) const;
+ friend class cmake;
+ void CreateGeneratorTargets(TargetTypes targetTypes, cmMakefile* mf,
+ cmLocalGenerator* lg,
+ std::map<cmTarget*, cmGeneratorTarget*> const& importedMap);
+ void CreateGeneratorTargets(TargetTypes targetTypes);
+
+ void ClearGeneratorMembers();
+
+ virtual const char* GetBuildIgnoreErrorsFlag() const { return 0; }
// Cache directory content and target files to be built.
- struct DirectoryContent: public std::set<cmStdString>
+ struct DirectoryContent
{
- typedef std::set<cmStdString> derived;
- bool LoadedFromDisk;
- DirectoryContent(): LoadedFromDisk(false) {}
+ long LastDiskTime;
+ std::set<std::string> All;
+ std::set<std::string> Generated;
+ DirectoryContent(): LastDiskTime(-1) {}
DirectoryContent(DirectoryContent const& dc):
- derived(dc), LoadedFromDisk(dc.LoadedFromDisk) {}
+ LastDiskTime(dc.LastDiskTime), All(dc.All), Generated(dc.Generated) {}
};
- std::map<cmStdString, DirectoryContent> DirectoryContentMap;
+ std::map<std::string, DirectoryContent> DirectoryContentMap;
// Set of binary directories on disk.
- std::set<cmStdString> BinaryDirectories;
+ std::set<std::string> BinaryDirectories;
+
+ // track targets to issue CMP0042 warning for.
+ std::set<std::string> CMP0042WarnTargets;
+
+ mutable std::map<cmSourceFile*, std::set<cmGeneratorTarget const*> >
+ FilenameTargetDepends;
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ // Pool of file locks
+ cmFileLockPool FileLockPool;
+#endif
+
+protected:
+ float FirstTimeProgress;
+ bool NeedSymbolicMark;
+ bool UseLinkScript;
+ bool ForceUnixPaths;
+ bool ToolSupportsColor;
+ bool InstallTargetEnabled;
+ bool ConfigureDoneCMP0026AndCMP0024;
};
#endif
diff --git a/Source/cmGlobalGeneratorFactory.h b/Source/cmGlobalGeneratorFactory.h
index fd1d65fb5..18d4324da 100644
--- a/Source/cmGlobalGeneratorFactory.h
+++ b/Source/cmGlobalGeneratorFactory.h
@@ -15,6 +15,7 @@
#include "cmStandardIncludes.h"
+class cmake;
class cmGlobalGenerator;
struct cmDocumentationEntry;
@@ -29,13 +30,17 @@ public:
virtual ~cmGlobalGeneratorFactory() {}
/** Create a GlobalGenerator */
- virtual cmGlobalGenerator* CreateGlobalGenerator(const char* n) const = 0;
+ virtual cmGlobalGenerator* CreateGlobalGenerator(
+ const std::string& n, cmake* cm) const = 0;
/** Get the documentation entry for this factory */
virtual void GetDocumentation(cmDocumentationEntry& entry) const = 0;
/** Get the names of the current registered generators */
virtual void GetGenerators(std::vector<std::string>& names) const = 0;
+
+ /** Determine whether or not this generator supports toolsets */
+ virtual bool SupportsToolset() const = 0;
};
template<class T>
@@ -43,9 +48,10 @@ class cmGlobalGeneratorSimpleFactory : public cmGlobalGeneratorFactory
{
public:
/** Create a GlobalGenerator */
- virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const {
- if (strcmp(name, T::GetActualName())) return 0;
- return new T; }
+ virtual cmGlobalGenerator*
+ CreateGlobalGenerator(const std::string& name, cmake* cm) const {
+ if (name != T::GetActualName()) return 0;
+ return new T(cm); }
/** Get the documentation entry for this factory */
virtual void GetDocumentation(cmDocumentationEntry& entry) const {
@@ -54,6 +60,9 @@ public:
/** Get the names of the current registered generators */
virtual void GetGenerators(std::vector<std::string>& names) const {
names.push_back(T::GetActualName()); }
+
+ /** Determine whether or not this generator supports toolsets */
+ virtual bool SupportsToolset() const { return T::SupportsToolset(); }
};
#endif
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
new file mode 100644
index 000000000..1bcbd26ad
--- /dev/null
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -0,0 +1,547 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Geoffrey Viola <geoffrey.viola@asirobots.com>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmGlobalGhsMultiGenerator.h"
+#include "cmLocalGhsMultiGenerator.h"
+#include "cmMakefile.h"
+#include "cmVersion.h"
+#include "cmGeneratedFileStream.h"
+#include "cmGhsMultiTargetGenerator.h"
+#include <cmsys/SystemTools.hxx>
+#include <cmAlgorithms.h>
+
+const char *cmGlobalGhsMultiGenerator::FILE_EXTENSION = ".gpj";
+const char *cmGlobalGhsMultiGenerator::DEFAULT_MAKE_PROGRAM = "gbuild";
+
+cmGlobalGhsMultiGenerator::cmGlobalGhsMultiGenerator(cmake* cm)
+ : cmGlobalGenerator(cm), OSDirRelative(false)
+{
+ this->GhsBuildCommandInitialized = false;
+}
+
+cmGlobalGhsMultiGenerator::~cmGlobalGhsMultiGenerator()
+{
+ cmDeleteAll(TargetFolderBuildStreams);
+}
+
+cmLocalGenerator *
+cmGlobalGhsMultiGenerator::CreateLocalGenerator(cmMakefile* mf)
+{
+ return new cmLocalGhsMultiGenerator(this, mf);
+}
+
+void cmGlobalGhsMultiGenerator::GetDocumentation(cmDocumentationEntry &entry)
+{
+ entry.Name = GetActualName();
+ entry.Brief =
+ "Generates Green Hills MULTI files (experimental, work-in-progress).";
+}
+
+void cmGlobalGhsMultiGenerator::EnableLanguage(
+ std::vector<std::string> const &l, cmMakefile *mf, bool optional)
+{
+ mf->AddDefinition("CMAKE_SYSTEM_NAME", "GHS-MULTI");
+ mf->AddDefinition("CMAKE_SYSTEM_PROCESSOR", "ARM");
+
+ const std::string ghsCompRoot(GetCompRoot());
+ mf->AddDefinition("GHS_COMP_ROOT", ghsCompRoot.c_str());
+ std::string ghsCompRootStart =
+ 0 == ghsCompRootStart.size() ? "" : ghsCompRoot + "/";
+ mf->AddDefinition("CMAKE_C_COMPILER",
+ std::string(ghsCompRootStart + "ccarm.exe").c_str());
+ mf->AddDefinition("CMAKE_C_COMPILER_ID_RUN", "TRUE");
+ mf->AddDefinition("CMAKE_C_COMPILER_ID", "GHS");
+ mf->AddDefinition("CMAKE_C_COMPILER_FORCED", "TRUE");
+
+ mf->AddDefinition("CMAKE_CXX_COMPILER",
+ std::string(ghsCompRootStart + "cxarm.exe").c_str());
+ mf->AddDefinition("CMAKE_CXX_COMPILER_ID_RUN", "TRUE");
+ mf->AddDefinition("CMAKE_CXX_COMPILER_ID", "GHS");
+ mf->AddDefinition("CMAKE_CXX_COMPILER_FORCED", "TRUE");
+
+ if (!ghsCompRoot.empty())
+ {
+ static const char *compPreFix = "comp_";
+ std::string compFilename =
+ cmsys::SystemTools::FindLastString(ghsCompRoot.c_str(), compPreFix);
+ cmsys::SystemTools::ReplaceString(compFilename, compPreFix, "");
+ mf->AddDefinition("CMAKE_SYSTEM_VERSION", compFilename.c_str());
+ }
+
+ mf->AddDefinition("GHSMULTI", "1"); // identifier for user CMake files
+ this->cmGlobalGenerator::EnableLanguage(l, mf, optional);
+}
+
+void cmGlobalGhsMultiGenerator::FindMakeProgram(cmMakefile *mf)
+{
+ // The GHS generator knows how to lookup its build tool
+ // directly instead of needing a helper module to do it, so we
+ // do not actually need to put CMAKE_MAKE_PROGRAM into the cache.
+ if (cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM")))
+ {
+ mf->AddDefinition("CMAKE_MAKE_PROGRAM",
+ this->GetGhsBuildCommand().c_str());
+ }
+}
+
+std::string const &cmGlobalGhsMultiGenerator::GetGhsBuildCommand()
+{
+ if (!this->GhsBuildCommandInitialized)
+ {
+ this->GhsBuildCommandInitialized = true;
+ this->GhsBuildCommand = this->FindGhsBuildCommand();
+ }
+ return this->GhsBuildCommand;
+}
+
+std::string cmGlobalGhsMultiGenerator::FindGhsBuildCommand()
+{
+ std::vector<std::string> userPaths;
+ userPaths.push_back(this->GetCompRoot());
+ std::string makeProgram =
+ cmSystemTools::FindProgram(DEFAULT_MAKE_PROGRAM, userPaths);
+ if (makeProgram.empty())
+ {
+ makeProgram = DEFAULT_MAKE_PROGRAM;
+ }
+ return makeProgram;
+}
+
+std::string cmGlobalGhsMultiGenerator::GetCompRoot()
+{
+ std::string output;
+
+ const std::vector<std::string>
+ potentialDirsHardPaths(GetCompRootHardPaths());
+ const std::vector<std::string> potentialDirsRegistry(GetCompRootRegistry());
+
+ std::vector<std::string> potentialDirsComplete;
+ potentialDirsComplete.insert(potentialDirsComplete.end(),
+ potentialDirsHardPaths.begin(),
+ potentialDirsHardPaths.end());
+ potentialDirsComplete.insert(potentialDirsComplete.end(),
+ potentialDirsRegistry.begin(),
+ potentialDirsRegistry.end());
+
+ // Use latest version
+ std::string outputDirName;
+ for (std::vector<std::string>::const_iterator potentialDirsCompleteIt =
+ potentialDirsComplete.begin();
+ potentialDirsCompleteIt != potentialDirsComplete.end();
+ ++potentialDirsCompleteIt)
+ {
+ const std::string dirName(
+ cmsys::SystemTools::GetFilenameName(*potentialDirsCompleteIt));
+ if (dirName.compare(outputDirName) > 0)
+ {
+ output = *potentialDirsCompleteIt;
+ outputDirName = dirName;
+ }
+ }
+
+ return output;
+}
+
+std::vector<std::string> cmGlobalGhsMultiGenerator::GetCompRootHardPaths()
+{
+ std::vector<std::string> output;
+ cmSystemTools::Glob("C:/ghs", "comp_[^;]+", output);
+ for (std::vector<std::string>::iterator outputIt = output.begin();
+ outputIt != output.end(); ++outputIt)
+ {
+ *outputIt = "C:/ghs/" + *outputIt;
+ }
+ return output;
+}
+
+std::vector<std::string> cmGlobalGhsMultiGenerator::GetCompRootRegistry()
+{
+ std::vector<std::string> output(2);
+ cmsys::SystemTools::ReadRegistryValue(
+ "HKEY_LOCAL_"
+ "MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\"
+ "Windows\\CurrentVersion\\Uninstall\\"
+ "GreenHillsSoftwared771f1b4;InstallLocation",
+ output[0]);
+ cmsys::SystemTools::ReadRegistryValue(
+ "HKEY_LOCAL_"
+ "MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\"
+ "Windows\\CurrentVersion\\Uninstall\\"
+ "GreenHillsSoftware9881cef6;InstallLocation",
+ output[1]);
+ return output;
+}
+
+void cmGlobalGhsMultiGenerator::OpenBuildFileStream(
+ std::string const &filepath, cmGeneratedFileStream **filestream)
+{
+ // Get a stream where to generate things.
+ if (NULL == *filestream)
+ {
+ *filestream = new cmGeneratedFileStream(filepath.c_str());
+ if (NULL != *filestream)
+ {
+ OpenBuildFileStream(*filestream);
+ }
+ }
+}
+
+void cmGlobalGhsMultiGenerator::OpenBuildFileStream(
+ cmGeneratedFileStream *filestream)
+{
+ *filestream << "#!gbuild" << std::endl;
+}
+
+void cmGlobalGhsMultiGenerator::OpenBuildFileStream()
+{
+ // Compute GHS MULTI's build file path.
+ std::string buildFilePath =
+ this->GetCMakeInstance()->GetHomeOutputDirectory();
+ buildFilePath += "/";
+ buildFilePath += "default";
+ buildFilePath += FILE_EXTENSION;
+
+ this->Open(std::string(""), buildFilePath, &this->TargetFolderBuildStreams);
+ OpenBuildFileStream(GetBuildFileStream());
+
+ char const *osDir =
+ this->GetCMakeInstance()->GetCacheDefinition("GHS_OS_DIR");
+ if (NULL == osDir)
+ {
+ osDir = "";
+ cmSystemTools::Error("GHS_OS_DIR cache variable must be set");
+ }
+ else
+ {
+ this->GetCMakeInstance()->MarkCliAsUsed("GHS_OS_DIR");
+ }
+ std::string fOSDir(this->trimQuotes(osDir));
+ cmSystemTools::ReplaceString(fOSDir, "\\", "/");
+ if (!fOSDir.empty() && ('c' == fOSDir[0] || 'C' == fOSDir[0]))
+ {
+ this->OSDirRelative = false;
+ }
+ else
+ {
+ this->OSDirRelative = true;
+ }
+
+ char const *bspName =
+ this->GetCMakeInstance()->GetCacheDefinition("GHS_BSP_NAME");
+ if (NULL == bspName)
+ {
+ bspName = "";
+ cmSystemTools::Error("GHS_BSP_NAME cache variable must be set");
+ }
+ else
+ {
+ this->GetCMakeInstance()->MarkCliAsUsed("GHS_BSP_NAME");
+ }
+ std::string fBspName(this->trimQuotes(bspName));
+ cmSystemTools::ReplaceString(fBspName, "\\", "/");
+ this->WriteMacros();
+ this->WriteHighLevelDirectives();
+
+ GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, this->GetBuildFileStream());
+ this->WriteDisclaimer(this->GetBuildFileStream());
+ *this->GetBuildFileStream() << "# Top Level Project File" << std::endl;
+ if (!fBspName.empty())
+ {
+ *this->GetBuildFileStream() << " -bsp " << fBspName << std::endl;
+ }
+ this->WriteCompilerOptions(fOSDir);
+}
+
+void cmGlobalGhsMultiGenerator::CloseBuildFileStream(
+ cmGeneratedFileStream **filestream)
+{
+ if (filestream)
+ {
+ delete *filestream;
+ *filestream = NULL;
+ }
+ else
+ {
+ cmSystemTools::Error("Build file stream was not open.");
+ }
+}
+
+void cmGlobalGhsMultiGenerator::Generate()
+{
+ this->cmGlobalGenerator::Generate();
+
+ if (!this->LocalGenerators.empty())
+ {
+ this->OpenBuildFileStream();
+
+ // Build all the folder build files
+ for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i)
+ {
+ cmLocalGhsMultiGenerator *lg =
+ static_cast<cmLocalGhsMultiGenerator *>(this->LocalGenerators[i]);
+ std::vector<cmGeneratorTarget*> tgts = lg->GetGeneratorTargets();
+ this->UpdateBuildFiles(tgts);
+ }
+ }
+
+ cmDeleteAll(TargetFolderBuildStreams);
+ this->TargetFolderBuildStreams.clear();
+}
+
+void cmGlobalGhsMultiGenerator::GenerateBuildCommand(
+ std::vector<std::string> &makeCommand, const std::string &makeProgram,
+ const std::string & /*projectName*/, const std::string & /*projectDir*/,
+ const std::string &targetName, const std::string & /*config*/,
+ bool /*fast*/, bool /*verbose*/,
+ std::vector<std::string> const &makeOptions)
+{
+ makeCommand.push_back(
+ this->SelectMakeProgram(makeProgram, this->GetGhsBuildCommand())
+ );
+
+ makeCommand.insert(makeCommand.end(),
+ makeOptions.begin(), makeOptions.end());
+ if (!targetName.empty())
+ {
+ if (targetName == "clean")
+ {
+ makeCommand.push_back("-clean");
+ }
+ else
+ {
+ makeCommand.push_back(targetName);
+ }
+ }
+}
+
+void cmGlobalGhsMultiGenerator::WriteMacros()
+{
+ char const *ghsGpjMacros =
+ this->GetCMakeInstance()->GetCacheDefinition("GHS_GPJ_MACROS");
+ if (NULL != ghsGpjMacros)
+ {
+ std::vector<std::string> expandedList;
+ cmSystemTools::ExpandListArgument(std::string(ghsGpjMacros), expandedList);
+ for (std::vector<std::string>::const_iterator expandedListI =
+ expandedList.begin();
+ expandedListI != expandedList.end(); ++expandedListI)
+ {
+ *this->GetBuildFileStream() << "macro " << *expandedListI << std::endl;
+ }
+ }
+}
+
+void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives()
+{
+ *this->GetBuildFileStream() << "primaryTarget=arm_integrity.tgt"
+ << std::endl;
+ char const *const customization =
+ this->GetCMakeInstance()->GetCacheDefinition("GHS_CUSTOMIZATION");
+ if (NULL != customization && strlen(customization) > 0)
+ {
+ *this->GetBuildFileStream() << "customization="
+ << trimQuotes(customization)
+ << std::endl;
+ this->GetCMakeInstance()->MarkCliAsUsed("GHS_CUSTOMIZATION");
+ }
+}
+
+void cmGlobalGhsMultiGenerator::WriteCompilerOptions(std::string const &fOSDir)
+{
+ *this->GetBuildFileStream() << " -os_dir=\"" << fOSDir << "\""
+ << std::endl;
+}
+
+void cmGlobalGhsMultiGenerator::WriteDisclaimer(std::ostream *os)
+{
+ (*os) << "#" << std::endl
+ << "# CMAKE generated file: DO NOT EDIT!" << std::endl
+ << "# Generated by \"" << GetActualName() << "\""
+ << " Generator, CMake Version " << cmVersion::GetMajorVersion() << "."
+ << cmVersion::GetMinorVersion() << std::endl
+ << "#" << std::endl;
+}
+
+void cmGlobalGhsMultiGenerator::AddFilesUpToPath(
+ cmGeneratedFileStream *mainBuildFile,
+ std::map<std::string, cmGeneratedFileStream *> *targetFolderBuildStreams,
+ char const *homeOutputDirectory, std::string const &path,
+ GhsMultiGpj::Types projType, std::string const &relPath)
+{
+ std::string workingPath(path);
+ cmSystemTools::ConvertToUnixSlashes(workingPath);
+ std::vector<cmsys::String> splitPath =
+ cmSystemTools::SplitString(workingPath);
+ std::string workingRelPath(relPath);
+ cmSystemTools::ConvertToUnixSlashes(workingRelPath);
+ if (!workingRelPath.empty())
+ {
+ workingRelPath += "/";
+ }
+ std::string pathUpTo;
+ for (std::vector<cmsys::String>::const_iterator splitPathI =
+ splitPath.begin();
+ splitPath.end() != splitPathI; ++splitPathI)
+ {
+ pathUpTo += *splitPathI;
+ if (targetFolderBuildStreams->end() ==
+ targetFolderBuildStreams->find(pathUpTo))
+ {
+ AddFilesUpToPathNewBuildFile(
+ mainBuildFile, targetFolderBuildStreams, homeOutputDirectory,
+ pathUpTo, splitPath.begin() == splitPathI, workingRelPath, projType);
+ }
+ AddFilesUpToPathAppendNextFile(targetFolderBuildStreams, pathUpTo,
+ splitPathI, splitPath.end(), projType);
+ pathUpTo += "/";
+ }
+}
+
+void cmGlobalGhsMultiGenerator::Open(
+ std::string const &mapKeyName, std::string const &fileName,
+ std::map<std::string, cmGeneratedFileStream *> *fileMap)
+{
+ if (fileMap->end() == fileMap->find(fileName))
+ {
+ cmGeneratedFileStream *temp(new cmGeneratedFileStream);
+ temp->open(fileName.c_str());
+ (*fileMap)[mapKeyName] = temp;
+ }
+}
+
+void cmGlobalGhsMultiGenerator::AddFilesUpToPathNewBuildFile(
+ cmGeneratedFileStream *mainBuildFile,
+ std::map<std::string, cmGeneratedFileStream *> *targetFolderBuildStreams,
+ char const *homeOutputDirectory, std::string const &pathUpTo,
+ bool const isFirst, std::string const &relPath,
+ GhsMultiGpj::Types const projType)
+{
+ // create folders up to file path
+ std::string absPath = std::string(homeOutputDirectory) + "/" + relPath;
+ std::string newPath = absPath + pathUpTo;
+ if (!cmSystemTools::FileExists(newPath.c_str()))
+ {
+ cmSystemTools::MakeDirectory(newPath.c_str());
+ }
+
+ // Write out to filename for first time
+ std::string relFilename(GetFileNameFromPath(pathUpTo));
+ std::string absFilename = absPath + relFilename;
+ Open(pathUpTo, absFilename, targetFolderBuildStreams);
+ OpenBuildFileStream((*targetFolderBuildStreams)[pathUpTo]);
+ GhsMultiGpj::WriteGpjTag(projType, (*targetFolderBuildStreams)[pathUpTo]);
+ WriteDisclaimer((*targetFolderBuildStreams)[pathUpTo]);
+
+ // Add to main build file
+ if (isFirst)
+ {
+ *mainBuildFile << relFilename << " ";
+ GhsMultiGpj::WriteGpjTag(projType, mainBuildFile);
+ }
+}
+
+void cmGlobalGhsMultiGenerator::AddFilesUpToPathAppendNextFile(
+ std::map<std::string, cmGeneratedFileStream *> *targetFolderBuildStreams,
+ std::string const &pathUpTo,
+ std::vector<cmsys::String>::const_iterator splitPathI,
+ std::vector<cmsys::String>::const_iterator end,
+ GhsMultiGpj::Types const projType)
+{
+ std::vector<cmsys::String>::const_iterator splitPathNextI = splitPathI + 1;
+ if (end != splitPathNextI &&
+ targetFolderBuildStreams->end() ==
+ targetFolderBuildStreams->find(pathUpTo + "/" + *splitPathNextI))
+ {
+ std::string nextFilename(*splitPathNextI);
+ nextFilename = GetFileNameFromPath(nextFilename);
+ *(*targetFolderBuildStreams)[pathUpTo] << nextFilename << " ";
+ GhsMultiGpj::WriteGpjTag(projType, (*targetFolderBuildStreams)[pathUpTo]);
+ }
+}
+
+std::string
+cmGlobalGhsMultiGenerator::GetFileNameFromPath(std::string const &path)
+{
+ std::string output(path);
+ if (!path.empty())
+ {
+ cmSystemTools::ConvertToUnixSlashes(output);
+ std::vector<cmsys::String> splitPath = cmSystemTools::SplitString(output);
+ output += "/" + splitPath.back() + FILE_EXTENSION;
+ }
+ return output;
+}
+
+void cmGlobalGhsMultiGenerator::UpdateBuildFiles(
+ std::vector<cmGeneratorTarget*> tgts)
+{
+ for (std::vector<cmGeneratorTarget*>::iterator tgtsI = tgts.begin();
+ tgtsI != tgts.end(); ++tgtsI)
+ {
+ const cmGeneratorTarget *tgt = *tgtsI;
+ if (IsTgtForBuild(tgt))
+ {
+ char const *rawFolderName = tgt->GetProperty("FOLDER");
+ if (NULL == rawFolderName)
+ {
+ rawFolderName = "";
+ }
+ std::string folderName(rawFolderName);
+ if (this->TargetFolderBuildStreams.end() ==
+ this->TargetFolderBuildStreams.find(folderName))
+ {
+ this->AddFilesUpToPath(
+ GetBuildFileStream(), &this->TargetFolderBuildStreams,
+ this->GetCMakeInstance()->GetHomeOutputDirectory(), folderName,
+ GhsMultiGpj::PROJECT);
+ }
+ std::vector<cmsys::String> splitPath = cmSystemTools::SplitString(
+ cmGhsMultiTargetGenerator::GetRelBuildFileName(tgt));
+ std::string foldNameRelBuildFile(*(splitPath.end() - 2) + "/" +
+ splitPath.back());
+ *this->TargetFolderBuildStreams[folderName] << foldNameRelBuildFile
+ << " ";
+ GhsMultiGpj::WriteGpjTag(cmGhsMultiTargetGenerator::GetGpjTag(
+ tgt),
+ this->TargetFolderBuildStreams[folderName]);
+ }
+ }
+}
+
+bool cmGlobalGhsMultiGenerator::IsTgtForBuild(const cmGeneratorTarget *tgt)
+{
+ const std::string config =
+ tgt->Target->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ std::vector<cmSourceFile *> tgtSources;
+ tgt->GetSourceFiles(tgtSources, config);
+ bool tgtInBuild = true;
+ char const *excludeFromAll = tgt->GetProperty("EXCLUDE_FROM_ALL");
+ if (NULL != excludeFromAll && '1' == excludeFromAll[0] &&
+ '\0' == excludeFromAll[1])
+ {
+ tgtInBuild = false;
+ }
+ return !tgtSources.empty() && tgtInBuild;
+}
+
+std::string cmGlobalGhsMultiGenerator::trimQuotes(std::string const &str)
+{
+ std::string result;
+ result.reserve(str.size());
+ for (const char *ch = str.c_str(); *ch != '\0'; ++ch)
+ {
+ if (*ch != '"')
+ {
+ result += *ch;
+ }
+ }
+ return result;
+}
diff --git a/Source/cmGlobalGhsMultiGenerator.h b/Source/cmGlobalGhsMultiGenerator.h
new file mode 100644
index 000000000..6f86c5d4e
--- /dev/null
+++ b/Source/cmGlobalGhsMultiGenerator.h
@@ -0,0 +1,134 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Geoffrey Viola <geoffrey.viola@asirobots.com>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmGhsMultiGenerator_h
+#define cmGhsMultiGenerator_h
+
+#include "cmGlobalGeneratorFactory.h"
+#include "cmGlobalGenerator.h"
+#include "cmGhsMultiGpj.h"
+
+class cmGeneratedFileStream;
+
+class cmGlobalGhsMultiGenerator : public cmGlobalGenerator
+{
+public:
+ /// The default name of GHS MULTI's build file. Typically: monolith.gpj.
+ static const char *FILE_EXTENSION;
+
+ cmGlobalGhsMultiGenerator(cmake* cm);
+ ~cmGlobalGhsMultiGenerator();
+
+ static cmGlobalGeneratorFactory *NewFactory()
+ { return new cmGlobalGeneratorSimpleFactory<cmGlobalGhsMultiGenerator>(); }
+
+ ///! create the correct local generator
+ virtual cmLocalGenerator *CreateLocalGenerator(cmMakefile* mf);
+
+ /// @return the name of this generator.
+ static std::string GetActualName() { return "Green Hills MULTI"; }
+
+ ///! Get the name for this generator
+ virtual std::string GetName() const { return this->GetActualName(); }
+
+ /// Overloaded methods. @see cmGlobalGenerator::GetDocumentation()
+ static void GetDocumentation(cmDocumentationEntry &entry);
+
+ /**
+ * Utilized by the generator factory to determine if this generator
+ * supports toolsets.
+ */
+ static bool SupportsToolset() { return false; }
+
+ /**
+ * Try to determine system information such as shared library
+ * extension, pthreads, byte order etc.
+ */
+ virtual void EnableLanguage(std::vector<std::string> const &languages,
+ cmMakefile *, bool optional);
+ /*
+ * Determine what program to use for building the project.
+ */
+ virtual void FindMakeProgram(cmMakefile *);
+
+ cmGeneratedFileStream *GetBuildFileStream()
+ {
+ return this->TargetFolderBuildStreams[""];
+ }
+
+ static void OpenBuildFileStream(std::string const &filepath,
+ cmGeneratedFileStream **filestream);
+ static void OpenBuildFileStream(cmGeneratedFileStream *filestream);
+ static void CloseBuildFileStream(cmGeneratedFileStream **filestream);
+ /// Write the common disclaimer text at the top of each build file.
+ static void WriteDisclaimer(std::ostream *os);
+ std::vector<std::string> GetLibDirs() { return this->LibDirs; }
+
+ static void AddFilesUpToPath(
+ cmGeneratedFileStream *mainBuildFile,
+ std::map<std::string, cmGeneratedFileStream *> *targetFolderBuildStreams,
+ char const *homeOutputDirectory, std::string const &path,
+ GhsMultiGpj::Types projType, std::string const &relPath = "");
+ static void Open(std::string const &mapKeyName, std::string const &fileName,
+ std::map<std::string, cmGeneratedFileStream *> *fileMap);
+
+ static std::string trimQuotes(std::string const &str);
+ inline bool IsOSDirRelative() { return this->OSDirRelative; }
+
+protected:
+ virtual void Generate();
+ virtual void GenerateBuildCommand(
+ std::vector<std::string> &makeCommand, const std::string &makeProgram,
+ const std::string &projectName, const std::string &projectDir,
+ const std::string &targetName, const std::string &config, bool fast,
+ bool verbose,
+ std::vector<std::string> const& makeOptions = std::vector<std::string>()
+ );
+
+private:
+ std::string const &GetGhsBuildCommand();
+ std::string FindGhsBuildCommand();
+ std::string GetCompRoot();
+ std::vector<std::string> GetCompRootHardPaths();
+ std::vector<std::string> GetCompRootRegistry();
+ void OpenBuildFileStream();
+
+ void WriteMacros();
+ void WriteHighLevelDirectives();
+ void WriteCompilerOptions(std::string const &fOSDir);
+
+ static void AddFilesUpToPathNewBuildFile(
+ cmGeneratedFileStream *mainBuildFile,
+ std::map<std::string, cmGeneratedFileStream *> *targetFolderBuildStreams,
+ char const *homeOutputDirectory, std::string const &pathUpTo,
+ bool isFirst, std::string const &relPath, GhsMultiGpj::Types projType);
+ static void AddFilesUpToPathAppendNextFile(
+ std::map<std::string, cmGeneratedFileStream *> *targetFolderBuildStreams,
+ std::string const &pathUpTo,
+ std::vector<cmsys::String>::const_iterator splitPathI,
+ std::vector<cmsys::String>::const_iterator end,
+ GhsMultiGpj::Types projType);
+ static std::string GetFileNameFromPath(std::string const &path);
+ void UpdateBuildFiles(std::vector<cmGeneratorTarget*> tgts);
+ bool IsTgtForBuild(const cmGeneratorTarget *tgt);
+
+ std::vector<cmGeneratedFileStream *> TargetSubProjects;
+ std::map<std::string, cmGeneratedFileStream *> TargetFolderBuildStreams;
+
+ std::vector<std::string> LibDirs;
+
+ bool OSDirRelative;
+ bool GhsBuildCommandInitialized;
+ std::string GhsBuildCommand;
+ static const char *DEFAULT_MAKE_PROGRAM;
+};
+
+#endif
diff --git a/Source/cmGlobalJOMMakefileGenerator.cxx b/Source/cmGlobalJOMMakefileGenerator.cxx
index 4af06076f..3f33f91fc 100644
--- a/Source/cmGlobalJOMMakefileGenerator.cxx
+++ b/Source/cmGlobalJOMMakefileGenerator.cxx
@@ -13,12 +13,19 @@
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
-cmGlobalJOMMakefileGenerator::cmGlobalJOMMakefileGenerator()
+cmGlobalJOMMakefileGenerator::cmGlobalJOMMakefileGenerator(cmake* cm)
+ : cmGlobalUnixMakefileGenerator3(cm)
{
this->FindMakeProgramFile = "CMakeJOMFindMake.cmake";
this->ForceUnixPaths = false;
this->ToolSupportsColor = true;
this->UseLinkScript = false;
+ cm->GetState()->SetWindowsShell(true);
+ cm->GetState()->SetNMake(true);
+ this->DefineWindowsNULL = true;
+ this->PassMakeflags = true;
+ this->UnixCD = false;
+ this->MakeSilentFlag = "/nologo";
}
void cmGlobalJOMMakefileGenerator
@@ -29,41 +36,29 @@ void cmGlobalJOMMakefileGenerator
// pick a default
mf->AddDefinition("CMAKE_GENERATOR_CC", "cl");
mf->AddDefinition("CMAKE_GENERATOR_CXX", "cl");
- if(!(cmSystemTools::GetEnv("INCLUDE") &&
- cmSystemTools::GetEnv("LIB"))
- )
- {
- std::string message = "To use the JOM generator, cmake must be run "
- "from a shell that can use the compiler cl from the command line. "
- "This environment does not contain INCLUDE, LIB, or LIBPATH, and "
- "these must be set for the cl compiler to work. ";
- mf->IssueMessage(cmake::WARNING,
- message);
- }
-
this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional);
}
-///! Create a local generator appropriate to this Global Generator
-cmLocalGenerator *cmGlobalJOMMakefileGenerator::CreateLocalGenerator()
-{
- cmLocalUnixMakefileGenerator3* lg = new cmLocalUnixMakefileGenerator3;
- lg->SetDefineWindowsNULL(true);
- lg->SetWindowsShell(true);
- lg->SetMakeSilentFlag("/nologo");
- lg->SetGlobalGenerator(this);
- lg->SetIgnoreLibPrefix(true);
- lg->SetPassMakeflags(true);
- lg->SetNMake(true);
- lg->SetUnixCD(false);
- return lg;
-}
-
//----------------------------------------------------------------------------
void cmGlobalJOMMakefileGenerator
::GetDocumentation(cmDocumentationEntry& entry)
{
entry.Name = cmGlobalJOMMakefileGenerator::GetActualName();
entry.Brief = "Generates JOM makefiles.";
- entry.Full = "";
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalJOMMakefileGenerator::PrintCompilerAdvice(std::ostream& os,
+ std::string const& lang,
+ const char* envVar) const
+{
+ if(lang == "CXX" || lang == "C")
+ {
+ os <<
+ "To use the JOM generator with Visual C++, cmake must be run from a "
+ "shell that can use the compiler cl from the command line. This "
+ "environment is unable to invoke the cl compiler. To fix this problem, "
+ "run cmake from the Visual Studio Command Prompt (vcvarsall.bat).\n";
+ }
+ this->cmGlobalUnixMakefileGenerator3::PrintCompilerAdvice(os, lang, envVar);
}
diff --git a/Source/cmGlobalJOMMakefileGenerator.h b/Source/cmGlobalJOMMakefileGenerator.h
index 28893bf27..1869fed79 100644
--- a/Source/cmGlobalJOMMakefileGenerator.h
+++ b/Source/cmGlobalJOMMakefileGenerator.h
@@ -22,29 +22,29 @@
class cmGlobalJOMMakefileGenerator : public cmGlobalUnixMakefileGenerator3
{
public:
- cmGlobalJOMMakefileGenerator();
+ cmGlobalJOMMakefileGenerator(cmake* cm);
static cmGlobalGeneratorFactory* NewFactory() {
return new cmGlobalGeneratorSimpleFactory
<cmGlobalJOMMakefileGenerator>(); }
///! Get the name for the generator.
- virtual const char* GetName() const {
+ virtual std::string GetName() const {
return cmGlobalJOMMakefileGenerator::GetActualName();}
// use NMake Makefiles in the name so that scripts/tests that depend on the
// name NMake Makefiles will work
- static const char* GetActualName() {return "NMake Makefiles JOM";}
+ static std::string GetActualName() {return "NMake Makefiles JOM";}
/** Get the documentation entry for this generator. */
static void GetDocumentation(cmDocumentationEntry& entry);
- ///! Create a local generator appropriate to this Global Generator
- virtual cmLocalGenerator *CreateLocalGenerator();
-
/**
- * Try to determine system infomation such as shared library
+ * Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
cmMakefile *, bool optional);
+private:
+ void PrintCompilerAdvice(std::ostream& os, std::string const& lang,
+ const char* envVar) const;
};
#endif
diff --git a/Source/cmGlobalKdevelopGenerator.cxx b/Source/cmGlobalKdevelopGenerator.cxx
index a81c26c0f..018ab24f0 100644
--- a/Source/cmGlobalKdevelopGenerator.cxx
+++ b/Source/cmGlobalKdevelopGenerator.cxx
@@ -21,23 +21,14 @@
#include <cmsys/SystemTools.hxx>
#include <cmsys/Directory.hxx>
+#include <cmsys/FStream.hxx>
//----------------------------------------------------------------------------
void cmGlobalKdevelopGenerator
-::GetDocumentation(cmDocumentationEntry& entry, const char*) const
+::GetDocumentation(cmDocumentationEntry& entry, const std::string&) const
{
entry.Name = this->GetName();
entry.Brief = "Generates KDevelop 3 project files.";
- entry.Full =
- "Project files for KDevelop 3 will be created in the top directory "
- "and in every subdirectory which features a CMakeLists.txt file "
- "containing a PROJECT() call. "
- "If you change the settings using KDevelop cmake will try its best "
- "to keep your changes when regenerating the project files. "
- "Additionally a hierarchy of UNIX makefiles is generated into the "
- "build tree. Any "
- "standard UNIX-style make program can build the project through the "
- "default make target. A \"make install\" target is also provided.";
}
cmGlobalKdevelopGenerator::cmGlobalKdevelopGenerator()
@@ -53,15 +44,14 @@ void cmGlobalKdevelopGenerator::Generate()
{
// for each sub project in the project create
// a kdevelop project
- for (std::map<cmStdString, std::vector<cmLocalGenerator*> >::const_iterator
+ for (std::map<std::string, std::vector<cmLocalGenerator*> >::const_iterator
it = this->GlobalGenerator->GetProjectMap().begin();
it!= this->GlobalGenerator->GetProjectMap().end();
++it)
{
- cmMakefile* mf = it->second[0]->GetMakefile();
- std::string outputDir=mf->GetStartOutputDirectory();
- std::string projectDir=mf->GetHomeDirectory();
- std::string projectName=mf->GetProjectName();
+ std::string outputDir=it->second[0]->GetCurrentBinaryDirectory();
+ std::string projectDir=it->second[0]->GetSourceDirectory();
+ std::string projectName=it->second[0]->GetProjectName();
std::string cmakeFilePattern("CMakeLists.txt;*.cmake;");
std::string fileToOpen;
const std::vector<cmLocalGenerator*>& lgs= it->second;
@@ -78,14 +68,14 @@ void cmGlobalKdevelopGenerator::Generate()
for (std::vector<cmLocalGenerator*>::const_iterator lg=lgs.begin();
lg!=lgs.end(); lg++)
{
- cmMakefile* makefile=(*lg)->GetMakefile();
- cmTargets& targets=makefile->GetTargets();
- for (cmTargets::iterator ti = targets.begin();
- ti != targets.end(); ti++)
+ std::vector<cmGeneratorTarget*> const& targets =
+ (*lg)->GetGeneratorTargets();
+ for (std::vector<cmGeneratorTarget*>::const_iterator ti =
+ targets.begin(); ti != targets.end(); ti++)
{
- if (ti->second.GetType()==cmTarget::EXECUTABLE)
+ if ((*ti)->GetType()==cmState::EXECUTABLE)
{
- executable = ti->second.GetProperty("LOCATION");
+ executable = (*ti)->GetLocation("");
break;
}
}
@@ -112,9 +102,12 @@ bool cmGlobalKdevelopGenerator
std::string projectDir = projectDirIn + "/";
std::string filename = outputDir+ "/" + projectname +".kdevelop.filelist";
- std::set<cmStdString> files;
+ std::set<std::string> files;
std::string tmp;
+ std::vector<std::string> hdrExts =
+ this->GlobalGenerator->GetCMakeInstance()->GetHeaderExtensions();
+
for (std::vector<cmLocalGenerator*>::const_iterator it=lgs.begin();
it!=lgs.end(); it++)
{
@@ -143,11 +136,14 @@ bool cmGlobalKdevelopGenerator
}
//get all sources
- cmTargets& targets=makefile->GetTargets();
- for (cmTargets::iterator ti = targets.begin();
+ std::vector<cmGeneratorTarget*> targets=(*it)->GetGeneratorTargets();
+ for (std::vector<cmGeneratorTarget*>::iterator ti = targets.begin();
ti != targets.end(); ti++)
{
- const std::vector<cmSourceFile*>& sources=ti->second.GetSourceFiles();
+ std::vector<cmSourceFile*> sources;
+ cmGeneratorTarget* gt = *ti;
+ gt->GetSourceFiles(sources, gt->Target->GetMakefile()
+ ->GetSafeDefinition("CMAKE_BUILD_TYPE"));
for (std::vector<cmSourceFile*>::const_iterator si=sources.begin();
si!=sources.end(); si++)
{
@@ -167,8 +163,7 @@ bool cmGlobalKdevelopGenerator
// check if there's a matching header around
for(std::vector<std::string>::const_iterator
- ext = makefile->GetHeaderExtensions().begin();
- ext != makefile->GetHeaderExtensions().end(); ++ext)
+ ext = hdrExts.begin(); ext != hdrExts.end(); ++ext)
{
std::string hname=headerBasename;
hname += ".";
@@ -191,7 +186,7 @@ bool cmGlobalKdevelopGenerator
(strstr(tmp.c_str(),
cmake::GetCMakeFilesDirectoryPostSlash())==0))
{
- files.insert(tmp.c_str());
+ files.insert(tmp);
}
}
}
@@ -199,7 +194,7 @@ bool cmGlobalKdevelopGenerator
//check if the output file already exists and read it
//insert all files which exist into the set of files
- std::ifstream oldFilelist(filename.c_str());
+ cmsys::ifstream oldFilelist(filename.c_str());
if (oldFilelist)
{
while (cmSystemTools::GetLineFromStream(oldFilelist, tmp))
@@ -225,11 +220,11 @@ bool cmGlobalKdevelopGenerator
}
fileToOpen="";
- for (std::set<cmStdString>::const_iterator it=files.begin();
+ for (std::set<std::string>::const_iterator it=files.begin();
it!=files.end(); it++)
{
// get the full path to the file
- tmp=cmSystemTools::CollapseFullPath(it->c_str(), projectDir.c_str());
+ tmp=cmSystemTools::CollapseFullPath(*it, projectDir.c_str());
// just select the first source file
if (fileToOpen.empty())
{
@@ -243,7 +238,7 @@ bool cmGlobalKdevelopGenerator
// make it relative to the project dir
cmSystemTools::ReplaceString(tmp, projectDir.c_str(), "");
// only put relative paths
- if (tmp.size() && tmp[0] != '/')
+ if (!tmp.empty() && tmp[0] != '/')
{
fout << tmp.c_str() <<"\n";
}
@@ -281,7 +276,7 @@ void cmGlobalKdevelopGenerator
// kdevelop blacklist so they are not monitored for added or removed files
// since this is handled by adding files to the cmake files
cmsys::Directory d;
- if (d.Load(projectDir.c_str()))
+ if (d.Load(projectDir))
{
size_t numf = d.GetNumberOfFiles();
for (unsigned int i = 0; i < numf; i++)
@@ -292,7 +287,7 @@ void cmGlobalKdevelopGenerator
std::string tmp = projectDir;
tmp += "/";
tmp += nextFile;
- if (cmSystemTools::FileIsDirectory(tmp.c_str()))
+ if (cmSystemTools::FileIsDirectory(tmp))
{
tmp += "/CMakeCache.txt";
if ((nextFile == "CMakeFiles")
@@ -320,7 +315,7 @@ void cmGlobalKdevelopGenerator
const std::string& fileToOpen,
const std::string& sessionFilename)
{
- std::ifstream oldProjectFile(filename.c_str());
+ cmsys::ifstream oldProjectFile(filename.c_str());
if (!oldProjectFile)
{
this->CreateNewProjectFile(outputDir, projectDir, filename,
@@ -368,7 +363,7 @@ void cmGlobalKdevelopGenerator
if (strstr(line, "<general>"))
{
fout<< " <projectmanagement>KDevCustomProject</projectmanagement>\n";
- fout<< " <projectdirectory>" <<projectDir.c_str()
+ fout<< " <projectdirectory>" <<projectDir
<< "</projectdirectory>\n"; //this one is important
fout<<" <absoluteprojectpath>true</absoluteprojectpath>\n";
//and this one
@@ -376,14 +371,14 @@ void cmGlobalKdevelopGenerator
// inside kdevcustomproject the <filelistdirectory> must be put
if (strstr(line, "<kdevcustomproject>"))
{
- fout<<" <filelistdirectory>"<<outputDir.c_str()
+ fout<<" <filelistdirectory>"<<outputDir
<<"</filelistdirectory>\n";
}
// buildtool and builddir go inside <build>
if (strstr(line, "<build>"))
{
fout<<" <buildtool>make</buildtool>\n";
- fout<<" <builddir>"<<outputDir.c_str()<<"</builddir>\n";
+ fout<<" <builddir>"<<outputDir<<"</builddir>\n";
}
}
}
@@ -425,7 +420,7 @@ void cmGlobalKdevelopGenerator
" <projectmanagement>KDevCustomProject</projectmanagement>\n"
" <primarylanguage>" << primaryLanguage << "</primarylanguage>\n"
" <ignoreparts/>\n"
- " <projectdirectory>" << projectDir.c_str() <<
+ " <projectdirectory>" << projectDir <<
"</projectdirectory>\n"; //this one is important
fout<<" <absoluteprojectpath>true</absoluteprojectpath>\n"; //and this one
@@ -452,12 +447,12 @@ void cmGlobalKdevelopGenerator
fout<<" </general>\n"
" <kdevcustomproject>\n"
- " <filelistdirectory>" << outputDir.c_str() <<
+ " <filelistdirectory>" << outputDir <<
"</filelistdirectory>\n"
" <run>\n"
- " <mainprogram>" << executable.c_str() << "</mainprogram>\n"
+ " <mainprogram>" << executable << "</mainprogram>\n"
" <directoryradio>custom</directoryradio>\n"
- " <customdirectory>"<<outputDir.c_str()<<"</customdirectory>\n"
+ " <customdirectory>"<<outputDir<<"</customdirectory>\n"
" <programargs></programargs>\n"
" <terminal>false</terminal>\n"
" <autocompile>true</autocompile>\n"
@@ -465,14 +460,14 @@ void cmGlobalKdevelopGenerator
" </run>\n"
" <build>\n"
" <buildtool>make</buildtool>\n"; //this one is important
- fout<<" <builddir>"<<outputDir.c_str()<<"</builddir>\n"; //and this one
+ fout<<" <builddir>"<<outputDir<<"</builddir>\n"; //and this one
fout<<" </build>\n"
" <make>\n"
" <abortonerror>false</abortonerror>\n"
" <numberofjobs>1</numberofjobs>\n"
" <dontact>false</dontact>\n"
" <makebin>" << this->GlobalGenerator->GetLocalGenerators()[0]->
- GetMakefile()->GetRequiredDefinition("CMAKE_BUILD_TOOL")
+ GetMakefile()->GetRequiredDefinition("CMAKE_MAKE_PROGRAM")
<< " </makebin>\n"
" <selectedenvironment>default</selectedenvironment>\n"
" <environments>\n"
@@ -488,7 +483,7 @@ void cmGlobalKdevelopGenerator
dirIt != this->Blacklist.end();
++dirIt)
{
- fout<<" <path>" << dirIt->c_str() << "</path>\n";
+ fout<<" <path>" << *dirIt << "</path>\n";
}
fout<<" </blacklist>\n";
@@ -566,7 +561,7 @@ void cmGlobalKdevelopGenerator
// command
fout<<" <kdevfileview>\n"
" <groups>\n"
- " <group pattern=\"" << cmakeFilePattern.c_str() <<
+ " <group pattern=\"" << cmakeFilePattern <<
"\" name=\"CMake\" />\n";
if (enableCxx)
@@ -609,7 +604,7 @@ void cmGlobalKdevelopGenerator
"<!DOCTYPE KDevPrjSession>\n"
"<KDevPrjSession>\n"
" <DocsAndViews NumberOfDocuments=\"1\" >\n"
- " <Doc0 NumberOfViews=\"1\" URL=\"file://" << fileToOpen.c_str() <<
+ " <Doc0 NumberOfViews=\"1\" URL=\"file://" << fileToOpen <<
"\" >\n"
" <View0 line=\"0\" Type=\"Source\" />\n"
" </Doc0>\n"
diff --git a/Source/cmGlobalKdevelopGenerator.h b/Source/cmGlobalKdevelopGenerator.h
index a1ad39d44..0d59fc578 100644
--- a/Source/cmGlobalKdevelopGenerator.h
+++ b/Source/cmGlobalKdevelopGenerator.h
@@ -33,14 +33,14 @@ class cmGlobalKdevelopGenerator : public cmExternalMakefileProjectGenerator
public:
cmGlobalKdevelopGenerator();
- virtual const char* GetName() const
+ virtual std::string GetName() const
{ return cmGlobalKdevelopGenerator::GetActualName();}
- static const char* GetActualName() { return "KDevelop3";}
+ static std::string GetActualName() { return "KDevelop3";}
static cmExternalMakefileProjectGenerator* New()
{ return new cmGlobalKdevelopGenerator; }
/** Get the documentation entry for this generator. */
virtual void GetDocumentation(cmDocumentationEntry& entry,
- const char* fullName) const;
+ const std::string& fullName) const;
virtual void Generate();
private:
diff --git a/Source/cmGlobalMSYSMakefileGenerator.cxx b/Source/cmGlobalMSYSMakefileGenerator.cxx
index d49639bef..9a6f3ba45 100644
--- a/Source/cmGlobalMSYSMakefileGenerator.cxx
+++ b/Source/cmGlobalMSYSMakefileGenerator.cxx
@@ -13,13 +13,16 @@
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmake.h"
+#include <cmsys/FStream.hxx>
-cmGlobalMSYSMakefileGenerator::cmGlobalMSYSMakefileGenerator()
+cmGlobalMSYSMakefileGenerator::cmGlobalMSYSMakefileGenerator(cmake* cm)
+ : cmGlobalUnixMakefileGenerator3(cm)
{
this->FindMakeProgramFile = "CMakeMSYSFindMake.cmake";
this->ForceUnixPaths = true;
this->ToolSupportsColor = true;
this->UseLinkScript = false;
+ cm->GetState()->SetMSYSShell(true);
}
std::string
@@ -27,7 +30,7 @@ cmGlobalMSYSMakefileGenerator::FindMinGW(std::string const& makeloc)
{
std::string fstab = makeloc;
fstab += "/../etc/fstab";
- std::ifstream fin(fstab.c_str());
+ cmsys::ifstream fin(fstab.c_str());
std::string path;
std::string mount;
std::string mingwBin;
@@ -59,19 +62,19 @@ void cmGlobalMSYSMakefileGenerator
locations.push_back("c:/mingw/bin");
std::string tgcc = cmSystemTools::FindProgram("gcc", locations);
std::string gcc = "gcc.exe";
- if(tgcc.size())
+ if(!tgcc.empty())
{
gcc = tgcc;
}
std::string tgxx = cmSystemTools::FindProgram("g++", locations);
std::string gxx = "g++.exe";
- if(tgxx.size())
+ if(!tgxx.empty())
{
gxx = tgxx;
}
std::string trc = cmSystemTools::FindProgram("windres", locations);
std::string rc = "windres.exe";
- if(trc.size())
+ if(!trc.empty())
{
rc = trc;
}
@@ -91,25 +94,10 @@ void cmGlobalMSYSMakefileGenerator
}
}
-///! Create a local generator appropriate to this Global Generator
-cmLocalGenerator *cmGlobalMSYSMakefileGenerator::CreateLocalGenerator()
-{
- cmLocalUnixMakefileGenerator3* lg = new cmLocalUnixMakefileGenerator3;
- lg->SetWindowsShell(false);
- lg->SetMSYSShell(true);
- lg->SetGlobalGenerator(this);
- lg->SetIgnoreLibPrefix(true);
- lg->SetPassMakeflags(false);
- lg->SetUnixCD(true);
- return lg;
-}
-
//----------------------------------------------------------------------------
void cmGlobalMSYSMakefileGenerator
::GetDocumentation(cmDocumentationEntry& entry)
{
entry.Name = cmGlobalMSYSMakefileGenerator::GetActualName();
entry.Brief = "Generates MSYS makefiles.";
- entry.Full = "The makefiles use /bin/sh as the shell. "
- "They require msys to be installed on the machine.";
}
diff --git a/Source/cmGlobalMSYSMakefileGenerator.h b/Source/cmGlobalMSYSMakefileGenerator.h
index 659de1186..2cefc9755 100644
--- a/Source/cmGlobalMSYSMakefileGenerator.h
+++ b/Source/cmGlobalMSYSMakefileGenerator.h
@@ -22,24 +22,21 @@
class cmGlobalMSYSMakefileGenerator : public cmGlobalUnixMakefileGenerator3
{
public:
- cmGlobalMSYSMakefileGenerator();
+ cmGlobalMSYSMakefileGenerator(cmake* cm);
static cmGlobalGeneratorFactory* NewFactory() {
return new cmGlobalGeneratorSimpleFactory
<cmGlobalMSYSMakefileGenerator>(); }
///! Get the name for the generator.
- virtual const char* GetName() const {
+ virtual std::string GetName() const {
return cmGlobalMSYSMakefileGenerator::GetActualName();}
- static const char* GetActualName() {return "MSYS Makefiles";}
+ static std::string GetActualName() {return "MSYS Makefiles";}
/** Get the documentation entry for this generator. */
static void GetDocumentation(cmDocumentationEntry& entry);
- ///! Create a local generator appropriate to this Global Generator
- virtual cmLocalGenerator *CreateLocalGenerator();
-
/**
- * Try to determine system infomation such as shared library
+ * Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
diff --git a/Source/cmGlobalMinGWMakefileGenerator.cxx b/Source/cmGlobalMinGWMakefileGenerator.cxx
index 1f374d3b8..b6e52d7bc 100644
--- a/Source/cmGlobalMinGWMakefileGenerator.cxx
+++ b/Source/cmGlobalMinGWMakefileGenerator.cxx
@@ -13,12 +13,15 @@
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
-cmGlobalMinGWMakefileGenerator::cmGlobalMinGWMakefileGenerator()
+cmGlobalMinGWMakefileGenerator::cmGlobalMinGWMakefileGenerator(cmake* cm)
+ : cmGlobalUnixMakefileGenerator3(cm)
{
this->FindMakeProgramFile = "CMakeMinGWFindMake.cmake";
this->ForceUnixPaths = true;
this->ToolSupportsColor = true;
this->UseLinkScript = true;
+ cm->GetState()->SetWindowsShell(true);
+ cm->GetState()->SetMinGWMake(true);
}
void cmGlobalMinGWMakefileGenerator
@@ -26,29 +29,40 @@ void cmGlobalMinGWMakefileGenerator
cmMakefile *mf,
bool optional)
{
- this->EnableMinGWLanguage(mf);
+ this->FindMakeProgram(mf);
+ std::string makeProgram = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
+ std::vector<std::string> locations;
+ locations.push_back(cmSystemTools::GetProgramPath(makeProgram));
+ locations.push_back("/mingw/bin");
+ locations.push_back("c:/mingw/bin");
+ std::string tgcc = cmSystemTools::FindProgram("gcc", locations);
+ std::string gcc = "gcc.exe";
+ if(!tgcc.empty())
+ {
+ gcc = tgcc;
+ }
+ std::string tgxx = cmSystemTools::FindProgram("g++", locations);
+ std::string gxx = "g++.exe";
+ if(!tgxx.empty())
+ {
+ gxx = tgxx;
+ }
+ std::string trc = cmSystemTools::FindProgram("windres", locations);
+ std::string rc = "windres.exe";
+ if(!trc.empty())
+ {
+ rc = trc;
+ }
+ mf->AddDefinition("CMAKE_GENERATOR_CC", gcc.c_str());
+ mf->AddDefinition("CMAKE_GENERATOR_CXX", gxx.c_str());
+ mf->AddDefinition("CMAKE_GENERATOR_RC", rc.c_str());
this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional);
}
-///! Create a local generator appropriate to this Global Generator
-cmLocalGenerator *cmGlobalMinGWMakefileGenerator::CreateLocalGenerator()
-{
- cmLocalUnixMakefileGenerator3* lg = new cmLocalUnixMakefileGenerator3;
- lg->SetWindowsShell(true);
- lg->SetGlobalGenerator(this);
- lg->SetIgnoreLibPrefix(true);
- lg->SetPassMakeflags(false);
- lg->SetUnixCD(true);
- lg->SetMinGWMake(true);
- return lg;
-}
-
//----------------------------------------------------------------------------
void cmGlobalMinGWMakefileGenerator
::GetDocumentation(cmDocumentationEntry& entry)
{
entry.Name = cmGlobalMinGWMakefileGenerator::GetActualName();
entry.Brief = "Generates a make file for use with mingw32-make.";
- entry.Full = "The makefiles generated use cmd.exe as the shell. "
- "They do not require msys or a unix shell.";
}
diff --git a/Source/cmGlobalMinGWMakefileGenerator.h b/Source/cmGlobalMinGWMakefileGenerator.h
index 7951e9886..3b0012666 100644
--- a/Source/cmGlobalMinGWMakefileGenerator.h
+++ b/Source/cmGlobalMinGWMakefileGenerator.h
@@ -22,23 +22,20 @@
class cmGlobalMinGWMakefileGenerator : public cmGlobalUnixMakefileGenerator3
{
public:
- cmGlobalMinGWMakefileGenerator();
+ cmGlobalMinGWMakefileGenerator(cmake* cm);
static cmGlobalGeneratorFactory* NewFactory() {
return new cmGlobalGeneratorSimpleFactory
<cmGlobalMinGWMakefileGenerator>(); }
///! Get the name for the generator.
- virtual const char* GetName() const {
+ virtual std::string GetName() const {
return cmGlobalMinGWMakefileGenerator::GetActualName();}
- static const char* GetActualName() {return "MinGW Makefiles";}
+ static std::string GetActualName() {return "MinGW Makefiles";}
/** Get the documentation entry for this generator. */
static void GetDocumentation(cmDocumentationEntry& entry);
- ///! Create a local generator appropriate to this Global Generator
- virtual cmLocalGenerator *CreateLocalGenerator();
-
/**
- * Try to determine system infomation such as shared library
+ * Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
diff --git a/Source/cmGlobalNMakeMakefileGenerator.cxx b/Source/cmGlobalNMakeMakefileGenerator.cxx
index 7af4ee3a8..7c570a627 100644
--- a/Source/cmGlobalNMakeMakefileGenerator.cxx
+++ b/Source/cmGlobalNMakeMakefileGenerator.cxx
@@ -13,12 +13,19 @@
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
-cmGlobalNMakeMakefileGenerator::cmGlobalNMakeMakefileGenerator()
+cmGlobalNMakeMakefileGenerator::cmGlobalNMakeMakefileGenerator(cmake* cm)
+ : cmGlobalUnixMakefileGenerator3(cm)
{
this->FindMakeProgramFile = "CMakeNMakeFindMake.cmake";
this->ForceUnixPaths = false;
this->ToolSupportsColor = true;
this->UseLinkScript = false;
+ cm->GetState()->SetWindowsShell(true);
+ cm->GetState()->SetNMake(true);
+ this->DefineWindowsNULL = true;
+ this->PassMakeflags = true;
+ this->UnixCD = false;
+ this->MakeSilentFlag = "/nologo";
}
void cmGlobalNMakeMakefileGenerator
@@ -29,41 +36,29 @@ void cmGlobalNMakeMakefileGenerator
// pick a default
mf->AddDefinition("CMAKE_GENERATOR_CC", "cl");
mf->AddDefinition("CMAKE_GENERATOR_CXX", "cl");
- if(!(cmSystemTools::GetEnv("INCLUDE") &&
- cmSystemTools::GetEnv("LIB"))
- )
- {
- std::string message = "To use the NMake generator, cmake must be run "
- "from a shell that can use the compiler cl from the command line. "
- "This environment does not contain INCLUDE, LIB, or LIBPATH, and "
- "these must be set for the cl compiler to work. ";
- mf->IssueMessage(cmake::WARNING,
- message);
- }
-
this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional);
}
-///! Create a local generator appropriate to this Global Generator
-cmLocalGenerator *cmGlobalNMakeMakefileGenerator::CreateLocalGenerator()
-{
- cmLocalUnixMakefileGenerator3* lg = new cmLocalUnixMakefileGenerator3;
- lg->SetDefineWindowsNULL(true);
- lg->SetWindowsShell(true);
- lg->SetMakeSilentFlag("/nologo");
- lg->SetGlobalGenerator(this);
- lg->SetIgnoreLibPrefix(true);
- lg->SetPassMakeflags(true);
- lg->SetNMake(true);
- lg->SetUnixCD(false);
- return lg;
-}
-
//----------------------------------------------------------------------------
void cmGlobalNMakeMakefileGenerator
::GetDocumentation(cmDocumentationEntry& entry)
{
entry.Name = cmGlobalNMakeMakefileGenerator::GetActualName();
entry.Brief = "Generates NMake makefiles.";
- entry.Full = "";
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalNMakeMakefileGenerator::PrintCompilerAdvice(std::ostream& os,
+ std::string const& lang,
+ const char* envVar) const
+{
+ if(lang == "CXX" || lang == "C")
+ {
+ os <<
+ "To use the NMake generator with Visual C++, cmake must be run from a "
+ "shell that can use the compiler cl from the command line. This "
+ "environment is unable to invoke the cl compiler. To fix this problem, "
+ "run cmake from the Visual Studio Command Prompt (vcvarsall.bat).\n";
+ }
+ this->cmGlobalUnixMakefileGenerator3::PrintCompilerAdvice(os, lang, envVar);
}
diff --git a/Source/cmGlobalNMakeMakefileGenerator.h b/Source/cmGlobalNMakeMakefileGenerator.h
index 5756fbd0d..3c8375aed 100644
--- a/Source/cmGlobalNMakeMakefileGenerator.h
+++ b/Source/cmGlobalNMakeMakefileGenerator.h
@@ -22,27 +22,27 @@
class cmGlobalNMakeMakefileGenerator : public cmGlobalUnixMakefileGenerator3
{
public:
- cmGlobalNMakeMakefileGenerator();
+ cmGlobalNMakeMakefileGenerator(cmake* cm);
static cmGlobalGeneratorFactory* NewFactory() {
return new cmGlobalGeneratorSimpleFactory
<cmGlobalNMakeMakefileGenerator>(); }
///! Get the name for the generator.
- virtual const char* GetName() const {
+ virtual std::string GetName() const {
return cmGlobalNMakeMakefileGenerator::GetActualName();}
- static const char* GetActualName() {return "NMake Makefiles";}
+ static std::string GetActualName() {return "NMake Makefiles";}
/** Get the documentation entry for this generator. */
static void GetDocumentation(cmDocumentationEntry& entry);
- ///! Create a local generator appropriate to this Global Generator
- virtual cmLocalGenerator *CreateLocalGenerator();
-
/**
- * Try to determine system infomation such as shared library
+ * Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
cmMakefile *, bool optional);
+private:
+ void PrintCompilerAdvice(std::ostream& os, std::string const& lang,
+ const char* envVar) const;
};
#endif
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 1953546de..0f06e439f 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -17,8 +17,11 @@
#include "cmLocalNinjaGenerator.h"
#include "cmMakefile.h"
#include "cmVersion.h"
+#include "cmAlgorithms.h"
#include <algorithm>
+#include <assert.h>
+#include <ctype.h>
const char* cmGlobalNinjaGenerator::NINJA_BUILD_FILE = "build.ninja";
const char* cmGlobalNinjaGenerator::NINJA_RULES_FILE = "rules.ninja";
@@ -55,6 +58,28 @@ void cmGlobalNinjaGenerator::WriteComment(std::ostream& os,
os << "# " << replace.substr(lpos) << "\n\n";
}
+std::string cmGlobalNinjaGenerator::EncodeRuleName(std::string const& name)
+{
+ // Ninja rule names must match "[a-zA-Z0-9_.-]+". Use ".xx" to encode
+ // "." and all invalid characters as hexadecimal.
+ std::string encoded;
+ for (std::string::const_iterator i = name.begin();
+ i != name.end(); ++i)
+ {
+ if (isalnum(*i) || *i == '_' || *i == '-')
+ {
+ encoded += *i;
+ }
+ else
+ {
+ char buf[16];
+ sprintf(buf, ".%02x", static_cast<unsigned int>(*i));
+ encoded += buf;
+ }
+ }
+ return encoded;
+}
+
static bool IsIdentChar(char c)
{
return
@@ -70,7 +95,7 @@ std::string cmGlobalNinjaGenerator::EncodeIdent(const std::string &ident,
if (std::find_if(ident.begin(), ident.end(),
std::not1(std::ptr_fun(IsIdentChar))) != ident.end()) {
static unsigned VarNum = 0;
- cmOStringStream names;
+ std::ostringstream names;
names << "ident" << VarNum++;
vars << names.str() << " = " << ident << "\n";
return "$" + names.str();
@@ -94,7 +119,7 @@ std::string cmGlobalNinjaGenerator::EncodePath(const std::string &path)
{
std::string result = path;
#ifdef _WIN32
- if(UsingMinGW)
+ if (this->IsGCCOnWindows())
cmSystemTools::ReplaceString(result, "\\", "/");
else
cmSystemTools::ReplaceString(result, "/", "\\");
@@ -102,6 +127,13 @@ std::string cmGlobalNinjaGenerator::EncodePath(const std::string &path)
return EncodeLiteral(result);
}
+std::string cmGlobalNinjaGenerator::EncodeDepfileSpace(const std::string &path)
+{
+ std::string result = path;
+ cmSystemTools::ReplaceString(result, " ", "\\ ");
+ return result;
+}
+
void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os,
const std::string& comment,
const std::string& rule,
@@ -111,7 +143,8 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os,
const cmNinjaDeps& orderOnlyDeps,
const cmNinjaVars& variables,
const std::string& rspfile,
- int cmdLineLimit)
+ int cmdLineLimit,
+ bool* usedResponseFile)
{
// Make sure there is a rule.
if(rule.empty())
@@ -133,7 +166,7 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os,
cmGlobalNinjaGenerator::WriteComment(os, comment);
- cmOStringStream arguments;
+ std::string arguments;
// TODO: Better formatting for when there are multiple input/output files.
@@ -142,71 +175,74 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os,
i != explicitDeps.end();
++i)
{
- arguments << " " << EncodeIdent(EncodePath(*i), os);
-
- //we need to track every dependency that comes in, since we are trying
- //to find dependencies that are side effects of build commands
- //
- this->CombinedBuildExplicitDependencies.insert( EncodePath(*i) );
+ arguments += " " + EncodeIdent(EncodePath(*i), os);
}
// Write implicit dependencies.
if(!implicitDeps.empty())
{
- arguments << " |";
+ arguments += " |";
for(cmNinjaDeps::const_iterator i = implicitDeps.begin();
i != implicitDeps.end();
++i)
- arguments << " " << EncodeIdent(EncodePath(*i), os);
+ arguments += " " + EncodeIdent(EncodePath(*i), os);
}
// Write order-only dependencies.
if(!orderOnlyDeps.empty())
{
- arguments << " ||";
+ arguments += " ||";
for(cmNinjaDeps::const_iterator i = orderOnlyDeps.begin();
i != orderOnlyDeps.end();
++i)
- arguments << " " << EncodeIdent(EncodePath(*i), os);
+ arguments += " " + EncodeIdent(EncodePath(*i), os);
}
- arguments << "\n";
+ arguments += "\n";
- cmOStringStream build;
+ std::string build;
// Write outputs files.
- build << "build";
+ build += "build";
for(cmNinjaDeps::const_iterator i = outputs.begin();
i != outputs.end(); ++i)
{
- build << " " << EncodeIdent(EncodePath(*i), os);
- this->CombinedBuildOutputs.insert( EncodePath(*i) );
+ build += " " + EncodeIdent(EncodePath(*i), os);
+ if (this->ComputingUnknownDependencies)
+ {
+ this->CombinedBuildOutputs.insert( EncodePath(*i) );
+ }
}
- build << ":";
+ build += ":";
// Write the rule.
- build << " " << rule;
+ build += " " + rule;
// Write the variables bound to this build statement.
- cmOStringStream variable_assignments;
+ std::ostringstream variable_assignments;
for(cmNinjaVars::const_iterator i = variables.begin();
i != variables.end(); ++i)
cmGlobalNinjaGenerator::WriteVariable(variable_assignments,
i->first, i->second, "", 1);
// check if a response file rule should be used
- std::string buildstr = build.str();
+ std::string buildstr = build;
std::string assignments = variable_assignments.str();
- const std::string args = arguments.str();
+ const std::string& args = arguments;
+ bool useResponseFile = false;
if (cmdLineLimit > 0
&& args.size() + buildstr.size() + assignments.size()
> (size_t) cmdLineLimit) {
- buildstr += "_RSP_FILE";
- variable_assignments.clear();
+ variable_assignments.str(std::string());
cmGlobalNinjaGenerator::WriteVariable(variable_assignments,
"RSP_FILE", rspfile, "", 1);
assignments += variable_assignments.str();
+ useResponseFile = true;
}
+ if (usedResponseFile)
+ {
+ *usedResponseFile = useResponseFile;
+ }
os << buildstr << args << assignments;
}
@@ -236,18 +272,22 @@ void cmGlobalNinjaGenerator::AddCustomCommandRule()
"$DESC",
"Rule for running custom commands.",
/*depfile*/ "",
+ /*deptype*/ "",
/*rspfile*/ "",
/*rspcontent*/ "",
- /*restat*/ true);
+ /*restat*/ "", // bound on each build statement as needed
+ /*generator*/ false);
}
void
cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command,
const std::string& description,
const std::string& comment,
+ bool uses_terminal,
+ bool restat,
const cmNinjaDeps& outputs,
const cmNinjaDeps& deps,
- const cmNinjaDeps& orderOnlyDeps)
+ const cmNinjaDeps& orderOnly)
{
std::string cmd = command;
#ifdef _WIN32
@@ -261,6 +301,14 @@ cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command,
cmNinjaVars vars;
vars["COMMAND"] = cmd;
vars["DESC"] = EncodeLiteral(description);
+ if (restat)
+ {
+ vars["restat"] = "1";
+ }
+ if (uses_terminal && SupportsConsolePool())
+ {
+ vars["pool"] = "console";
+ }
this->WriteBuild(*this->BuildFileStream,
comment,
@@ -268,28 +316,40 @@ cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command,
outputs,
deps,
cmNinjaDeps(),
- orderOnlyDeps,
+ orderOnly,
vars);
+
+ if (this->ComputingUnknownDependencies)
+ {
+ //we need to track every dependency that comes in, since we are trying
+ //to find dependencies that are side effects of build commands
+ for(cmNinjaDeps::const_iterator i = deps.begin(); i != deps.end(); ++i)
+ {
+ this->CombinedCustomCommandExplicitDependencies.insert(EncodePath(*i));
+ }
+ }
}
void
cmGlobalNinjaGenerator::AddMacOSXContentRule()
{
cmLocalGenerator *lg = this->LocalGenerators[0];
- cmMakefile* mfRoot = lg->GetMakefile();
- cmOStringStream cmd;
- cmd << lg->ConvertToOutputFormat(
- mfRoot->GetRequiredDefinition("CMAKE_COMMAND"),
- cmLocalGenerator::SHELL)
+ std::ostringstream cmd;
+ cmd << lg->ConvertToOutputFormat(cmSystemTools::GetCMakeCommand(),
+ cmLocalGenerator::SHELL)
<< " -E copy $in $out";
this->AddRule("COPY_OSX_CONTENT",
cmd.str(),
"Copying OS X Content $out",
- "Rule for copying OS X bundle content file."
+ "Rule for copying OS X bundle content file.",
/*depfile*/ "",
- /*rspfile*/ "");
+ /*deptype*/ "",
+ /*rspfile*/ "",
+ /*rspcontent*/ "",
+ /*restat*/ "",
+ /*generator*/ false);
}
void
@@ -320,9 +380,10 @@ void cmGlobalNinjaGenerator::WriteRule(std::ostream& os,
const std::string& description,
const std::string& comment,
const std::string& depfile,
+ const std::string& deptype,
const std::string& rspfile,
const std::string& rspcontent,
- bool restat,
+ const std::string& restat,
bool generator)
{
// Make sure the rule has a name.
@@ -355,6 +416,13 @@ void cmGlobalNinjaGenerator::WriteRule(std::ostream& os,
os << "depfile = " << depfile << "\n";
}
+ // Write the deptype if any.
+ if (!deptype.empty())
+ {
+ cmGlobalNinjaGenerator::Indent(os, 1);
+ os << "deps = " << deptype << "\n";
+ }
+
// Write the command.
cmGlobalNinjaGenerator::Indent(os, 1);
os << "command = " << command << "\n";
@@ -379,10 +447,10 @@ void cmGlobalNinjaGenerator::WriteRule(std::ostream& os,
os << "rspfile_content = " << rspcontent << "\n";
}
- if(restat)
+ if(!restat.empty())
{
cmGlobalNinjaGenerator::Indent(os, 1);
- os << "restat = 1\n";
+ os << "restat = " << restat << "\n";
}
if(generator)
@@ -441,14 +509,20 @@ void cmGlobalNinjaGenerator::WriteDefault(std::ostream& os,
}
-cmGlobalNinjaGenerator::cmGlobalNinjaGenerator()
- : cmGlobalGenerator()
+cmGlobalNinjaGenerator::cmGlobalNinjaGenerator(cmake* cm)
+ : cmGlobalCommonGenerator(cm)
, BuildFileStream(0)
, RulesFileStream(0)
, CompileCommandsStream(0)
, Rules()
, AllDependencies()
+ , UsingGCCOnWindows(false)
+ , ComputingUnknownDependencies(false)
+ , PolicyCMP0058(cmPolicies::WARN)
{
+#ifdef _WIN32
+ cm->GetState()->SetWindowsShell(true);
+#endif
// // Ninja is not ported to non-Unix OS yet.
// this->ForceUnixPaths = true;
this->FindMakeProgramFile = "CMakeNinjaFindMake.cmake";
@@ -458,22 +532,17 @@ cmGlobalNinjaGenerator::cmGlobalNinjaGenerator()
//----------------------------------------------------------------------------
// Virtual public methods.
-cmLocalGenerator* cmGlobalNinjaGenerator::CreateLocalGenerator()
+cmLocalGenerator*
+cmGlobalNinjaGenerator::CreateLocalGenerator(cmMakefile* mf)
{
- cmLocalGenerator* lg = new cmLocalNinjaGenerator;
- lg->SetGlobalGenerator(this);
- return lg;
+ return new cmLocalNinjaGenerator(this, mf);
}
void cmGlobalNinjaGenerator
::GetDocumentation(cmDocumentationEntry& entry)
{
entry.Name = cmGlobalNinjaGenerator::GetActualName();
- entry.Brief = "Generates build.ninja files (experimental).";
- entry.Full =
- "A build.ninja file is generated into the build tree. Recent "
- "versions of the ninja program can build the project through the "
- "\"all\" target. An \"install\" target is also provided.";
+ entry.Brief = "Generates build.ninja files.";
}
// Implemented in all cmGlobaleGenerator sub-classes.
@@ -482,9 +551,28 @@ void cmGlobalNinjaGenerator
// Source/cmake.cxx
void cmGlobalNinjaGenerator::Generate()
{
+ // Check minimum Ninja version.
+ if (cmSystemTools::VersionCompare(cmSystemTools::OP_LESS,
+ this->NinjaVersion.c_str(),
+ RequiredNinjaVersion().c_str()))
+ {
+ std::ostringstream msg;
+ msg << "The detected version of Ninja (" << this->NinjaVersion;
+ msg << ") is less than the version of Ninja required by CMake (";
+ msg << this->RequiredNinjaVersion() << ").";
+ this->GetCMakeInstance()->IssueMessage(cmake::FATAL_ERROR, msg.str());
+ return;
+ }
this->OpenBuildFileStream();
this->OpenRulesFileStream();
+ this->PolicyCMP0058 =
+ this->LocalGenerators[0]->GetMakefile()
+ ->GetPolicyStatus(cmPolicies::CMP0058);
+ this->ComputingUnknownDependencies =
+ (this->PolicyCMP0058 == cmPolicies::OLD ||
+ this->PolicyCMP0058 == cmPolicies::WARN);
+
this->cmGlobalGenerator::Generate();
this->WriteAssumedSourceDependencies();
@@ -502,77 +590,97 @@ void cmGlobalNinjaGenerator::Generate()
this->CloseBuildFileStream();
}
-// Implemented in all cmGlobaleGenerator sub-classes.
-// Used in:
-// Source/cmMakefile.cxx:
+void cmGlobalNinjaGenerator::FindMakeProgram(cmMakefile* mf)
+{
+ this->cmGlobalGenerator::FindMakeProgram(mf);
+ if (const char* ninjaCommand = mf->GetDefinition("CMAKE_MAKE_PROGRAM"))
+ {
+ this->NinjaCommand = ninjaCommand;
+ std::vector<std::string> command;
+ command.push_back(this->NinjaCommand);
+ command.push_back("--version");
+ std::string version;
+ cmSystemTools::RunSingleCommand(command,
+ &version, 0, 0, 0,
+ cmSystemTools::OUTPUT_NONE);
+ this->NinjaVersion = cmSystemTools::TrimWhitespace(version);
+ }
+}
+
void cmGlobalNinjaGenerator
::EnableLanguage(std::vector<std::string>const& langs,
- cmMakefile* makefile,
+ cmMakefile* mf,
bool optional)
{
- if (makefile->IsOn("CMAKE_COMPILER_IS_MINGW"))
- {
- UsingMinGW = true;
- this->EnableMinGWLanguage(makefile);
- }
if (std::find(langs.begin(), langs.end(), "Fortran") != langs.end())
{
cmSystemTools::Error("The Ninja generator does not support Fortran yet.");
}
- this->cmGlobalGenerator::EnableLanguage(langs, makefile, optional);
+ this->cmGlobalGenerator::EnableLanguage(langs, mf, optional);
+ for(std::vector<std::string>::const_iterator l = langs.begin();
+ l != langs.end(); ++l)
+ {
+ if(*l == "NONE")
+ {
+ continue;
+ }
+ this->ResolveLanguageCompiler(*l, mf, optional);
+ }
+#ifdef _WIN32
+ if (mf->IsOn("CMAKE_COMPILER_IS_MINGW") ||
+ strcmp(mf->GetSafeDefinition("CMAKE_C_COMPILER_ID"), "GNU") == 0 ||
+ strcmp(mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID"), "GNU") == 0 ||
+ strcmp(mf->GetSafeDefinition("CMAKE_C_SIMULATE_ID"), "GNU") == 0 ||
+ strcmp(mf->GetSafeDefinition("CMAKE_CXX_SIMULATE_ID"), "GNU") == 0)
+ {
+ this->UsingGCCOnWindows = true;
+ }
+#endif
}
-bool cmGlobalNinjaGenerator::UsingMinGW = false;
-
// Implemented by:
// cmGlobalUnixMakefileGenerator3
+// cmGlobalGhsMultiGenerator
// cmGlobalVisualStudio10Generator
// cmGlobalVisualStudio6Generator
// cmGlobalVisualStudio7Generator
// cmGlobalXCodeGenerator
// Called by:
// cmGlobalGenerator::Build()
-std::string cmGlobalNinjaGenerator
-::GenerateBuildCommand(const char* makeProgram,
- const char* projectName,
- const char* projectDir,
- const char* additionalOptions,
- const char* targetName,
- const char* config,
- bool ignoreErrors,
- bool fast)
+void cmGlobalNinjaGenerator
+::GenerateBuildCommand(std::vector<std::string>& makeCommand,
+ const std::string& makeProgram,
+ const std::string& /*projectName*/,
+ const std::string& /*projectDir*/,
+ const std::string& targetName,
+ const std::string& /*config*/,
+ bool /*fast*/,
+ bool verbose,
+ std::vector<std::string> const& makeOptions)
{
- // Project name & dir and config are not used yet.
- (void)projectName;
- (void)projectDir;
- (void)config;
- // Ninja does not have -i equivalent option yet.
- (void)ignoreErrors;
- // We do not handle fast build yet.
- (void)fast;
-
- std::string makeCommand =
- cmSystemTools::ConvertToUnixOutputPath(makeProgram);
-
- if(additionalOptions)
+ makeCommand.push_back(
+ this->SelectMakeProgram(makeProgram)
+ );
+
+ if(verbose)
{
- makeCommand += " ";
- makeCommand += additionalOptions;
+ makeCommand.push_back("-v");
}
- if(targetName)
+
+ makeCommand.insert(makeCommand.end(),
+ makeOptions.begin(), makeOptions.end());
+ if(!targetName.empty())
{
- if(strcmp(targetName, "clean") == 0)
+ if(targetName == "clean")
{
- makeCommand += " -t clean";
+ makeCommand.push_back("-t");
+ makeCommand.push_back("clean");
}
else
{
- makeCommand += " ";
- makeCommand += targetName;
+ makeCommand.push_back(targetName);
}
}
-
- return makeCommand;
}
//----------------------------------------------------------------------------
@@ -583,9 +691,10 @@ void cmGlobalNinjaGenerator::AddRule(const std::string& name,
const std::string& description,
const std::string& comment,
const std::string& depfile,
+ const std::string& deptype,
const std::string& rspfile,
const std::string& rspcontent,
- bool restat,
+ const std::string& restat,
bool generator)
{
// Do not add the same rule twice.
@@ -601,6 +710,7 @@ void cmGlobalNinjaGenerator::AddRule(const std::string& name,
description,
comment,
depfile,
+ deptype,
rspfile,
rspcontent,
restat,
@@ -618,29 +728,24 @@ bool cmGlobalNinjaGenerator::HasRule(const std::string &name)
//----------------------------------------------------------------------------
// Private virtual overrides
-// TODO: Refactor to combine with cmGlobalUnixMakefileGenerator3 impl.
-void cmGlobalNinjaGenerator::ComputeTargetObjects(cmGeneratorTarget* gt) const
+std::string cmGlobalNinjaGenerator::GetEditCacheCommand() const
{
- cmTarget* target = gt->Target;
+ // Ninja by design does not run interactive tools in the terminal,
+ // so our only choice is cmake-gui.
+ return cmSystemTools::GetCMakeGUICommand();
+}
+//----------------------------------------------------------------------------
+void cmGlobalNinjaGenerator
+::ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const
+{
// Compute full path to object file directory for this target.
- std::string dir_max;
- dir_max += gt->Makefile->GetCurrentOutputDirectory();
- dir_max += "/";
- dir_max += gt->LocalGenerator->GetTargetDirectory(*target);
- dir_max += "/";
- gt->ObjectDirectory = dir_max;
-
- // Compute the name of each object file.
- for(std::vector<cmSourceFile*>::iterator
- si = gt->ObjectSources.begin();
- si != gt->ObjectSources.end(); ++si)
- {
- cmSourceFile* sf = *si;
- std::string objectName = gt->LocalGenerator
- ->GetObjectFileNameWithoutTarget(*sf, dir_max);
- gt->Objects[sf] = objectName;
- }
+ std::string dir;
+ dir += gt->LocalGenerator->GetCurrentBinaryDirectory();
+ dir += "/";
+ dir += gt->LocalGenerator->GetTargetDirectory(gt);
+ dir += "/";
+ gt->ObjectDirectory = dir;
}
//----------------------------------------------------------------------------
@@ -733,6 +838,17 @@ void cmGlobalNinjaGenerator::CloseRulesFileStream()
}
}
+std::string cmGlobalNinjaGenerator::ConvertToNinjaPath(const std::string& path)
+{
+ cmLocalNinjaGenerator *ng =
+ static_cast<cmLocalNinjaGenerator *>(this->LocalGenerators[0]);
+ std::string convPath = ng->Convert(path, cmOutputConverter::HOME_OUTPUT);
+#ifdef _WIN32
+ cmSystemTools::ReplaceString(convPath, "/", "\\");
+#endif
+ return convPath;
+}
+
void cmGlobalNinjaGenerator::AddCXXCompileCommand(
const std::string &commandLine,
const std::string &sourceFile)
@@ -756,7 +872,7 @@ void cmGlobalNinjaGenerator::AddCXXCompileCommand(
if (!cmSystemTools::FileIsFullPath(sourceFileName.c_str()))
{
sourceFileName = cmSystemTools::CollapseFullPath(
- sourceFileName.c_str(),
+ sourceFileName,
this->GetCMakeInstance()->GetHomeOutputDirectory());
}
@@ -792,7 +908,7 @@ void cmGlobalNinjaGenerator::WriteDisclaimer(std::ostream& os)
<< cmVersion::GetMinorVersion() << "\n\n";
}
-void cmGlobalNinjaGenerator::AddDependencyToAll(cmTarget* target)
+void cmGlobalNinjaGenerator::AddDependencyToAll(cmGeneratorTarget* target)
{
this->AppendTargetOutputs(target, this->AllDependencies);
}
@@ -811,18 +927,18 @@ void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies()
std::copy(i->second.begin(), i->second.end(), std::back_inserter(deps));
WriteCustomCommandBuild(/*command=*/"", /*description=*/"",
"Assume dependencies for generated source file.",
+ /*uses_terminal*/false,
+ /*restat*/true,
cmNinjaDeps(1, i->first), deps);
}
}
void
cmGlobalNinjaGenerator
-::AppendTargetOutputs(cmTarget* target, cmNinjaDeps& outputs)
+::AppendTargetOutputs(cmGeneratorTarget const* target, cmNinjaDeps& outputs)
{
- const char* configName =
- target->GetMakefile()->GetDefinition("CMAKE_BUILD_TYPE");
- cmLocalNinjaGenerator *ng =
- static_cast<cmLocalNinjaGenerator *>(this->LocalGenerators[0]);
+ std::string configName =
+ target->Target->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
// for frameworks, we want the real name, not smple name
// frameworks always appear versioned, and the build.ninja
@@ -831,18 +947,19 @@ cmGlobalNinjaGenerator
bool realname = target->IsFrameworkOnApple();
switch (target->GetType()) {
- case cmTarget::EXECUTABLE:
- case cmTarget::SHARED_LIBRARY:
- case cmTarget::STATIC_LIBRARY:
- case cmTarget::MODULE_LIBRARY:
- outputs.push_back(ng->ConvertToNinjaPath(
- target->GetFullPath(configName, false, realname).c_str()));
+ case cmState::EXECUTABLE:
+ case cmState::SHARED_LIBRARY:
+ case cmState::STATIC_LIBRARY:
+ case cmState::MODULE_LIBRARY:
+ {
+ outputs.push_back(this->ConvertToNinjaPath(
+ target->GetFullPath(configName, false, realname)));
break;
-
- case cmTarget::OBJECT_LIBRARY:
- case cmTarget::UTILITY: {
- std::string path = ng->ConvertToNinjaPath(
- target->GetMakefile()->GetStartOutputDirectory());
+ }
+ case cmState::OBJECT_LIBRARY:
+ case cmState::UTILITY: {
+ std::string path = this->ConvertToNinjaPath(
+ target->GetLocalGenerator()->GetCurrentBinaryDirectory());
if (path.empty() || path == ".")
outputs.push_back(target->GetName());
else {
@@ -853,7 +970,7 @@ cmGlobalNinjaGenerator
break;
}
- case cmTarget::GLOBAL_TARGET:
+ case cmState::GLOBAL_TARGET:
// Always use the target in HOME instead of an unused duplicate in a
// subdirectory.
outputs.push_back(target->GetName());
@@ -866,25 +983,29 @@ cmGlobalNinjaGenerator
void
cmGlobalNinjaGenerator
-::AppendTargetDepends(cmTarget* target, cmNinjaDeps& outputs)
+::AppendTargetDepends(cmGeneratorTarget const* target, cmNinjaDeps& outputs)
{
- if (target->GetType() == cmTarget::GLOBAL_TARGET) {
+ if (target->GetType() == cmState::GLOBAL_TARGET) {
// Global targets only depend on other utilities, which may not appear in
// the TargetDepends set (e.g. "all").
- std::set<cmStdString> const& utils = target->GetUtilities();
+ std::set<std::string> const& utils = target->GetUtilities();
std::copy(utils.begin(), utils.end(), std::back_inserter(outputs));
} else {
- cmTargetDependSet const& targetDeps =
- this->GetTargetDirectDepends(*target);
+ cmTargetDependSet const& targetDeps = this->GetTargetDirectDepends(target);
for (cmTargetDependSet::const_iterator i = targetDeps.begin();
- i != targetDeps.end(); ++i) {
+ i != targetDeps.end(); ++i)
+ {
+ if ((*i)->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ continue;
+ }
this->AppendTargetOutputs(*i, outputs);
}
}
}
void cmGlobalNinjaGenerator::AddTargetAlias(const std::string& alias,
- cmTarget* target) {
+ cmGeneratorTarget* target) {
cmNinjaDeps outputs;
this->AppendTargetOutputs(target, outputs);
// Mark the target's outputs as ambiguous to ensure that no other target uses
@@ -923,6 +1044,18 @@ void cmGlobalNinjaGenerator::WriteTargetAliases(std::ostream& os)
void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os)
{
+ if (!this->ComputingUnknownDependencies)
+ {
+ return;
+ }
+
+ // We need to collect the set of known build outputs.
+ // Start with those generated by WriteBuild calls.
+ // No other method needs this so we can take ownership
+ // of the set locally and throw it out when we are done.
+ std::set<std::string> knownDependencies;
+ knownDependencies.swap(this->CombinedBuildOutputs);
+
//now write out the unknown explicit dependencies.
//union the configured files, evaluations files and the CombinedBuildOutputs,
@@ -936,10 +1069,7 @@ void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os)
//get the list of files that cmake itself has generated as a
//product of configuration.
- cmLocalNinjaGenerator *ng =
- static_cast<cmLocalNinjaGenerator *>(this->LocalGenerators[0]);
- std::set<std::string> knownDependencies;
for (std::vector<cmLocalGenerator *>::const_iterator i =
this->LocalGenerators.begin(); i != this->LocalGenerators.end(); ++i)
{
@@ -950,30 +1080,37 @@ void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os)
typedef std::vector<std::string>::const_iterator vect_it;
for(vect_it j = files.begin(); j != files.end(); ++j)
{
- knownDependencies.insert( ng->ConvertToNinjaPath( j->c_str() ) );
+ knownDependencies.insert( this->ConvertToNinjaPath( *j ) );
}
- }
-
- for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator
- li = this->EvaluationFiles.begin();
- li != this->EvaluationFiles.end();
- ++li)
- {
- //get all the files created by generator expressions and convert them
- //to ninja paths
- std::vector<std::string> files = (*li)->GetFiles();
+ //get list files which are implicit dependencies as well and will be phony
+ //for rebuild manifest
+ std::vector<std::string> const& lf = (*i)->GetMakefile()->GetListFiles();
typedef std::vector<std::string>::const_iterator vect_it;
- for(vect_it j = files.begin(); j != files.end(); ++j)
+ for(vect_it j = lf.begin(); j != lf.end(); ++j)
+ {
+ knownDependencies.insert( this->ConvertToNinjaPath( *j ) );
+ }
+ std::vector<cmGeneratorExpressionEvaluationFile*> const& ef =
+ (*i)->GetMakefile()->GetEvaluationFiles();
+ for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator
+ li = ef.begin(); li != ef.end(); ++li)
{
- knownDependencies.insert( ng->ConvertToNinjaPath( j->c_str() ) );
+ //get all the files created by generator expressions and convert them
+ //to ninja paths
+ std::vector<std::string> evaluationFiles = (*li)->GetFiles();
+ for(vect_it j = evaluationFiles.begin(); j != evaluationFiles.end(); ++j)
+ {
+ knownDependencies.insert( this->ConvertToNinjaPath( *j ) );
+ }
}
}
+ knownDependencies.insert( "CMakeCache.txt" );
for(TargetAliasMap::const_iterator i= this->TargetAliases.begin();
i != this->TargetAliases.end();
++i)
{
- knownDependencies.insert( ng->ConvertToNinjaPath(i->first.c_str()) );
+ knownDependencies.insert( this->ConvertToNinjaPath(i->first) );
}
//remove all source files we know will exist.
@@ -982,58 +1119,72 @@ void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os)
i != this->AssumedSourceDependencies.end();
++i)
{
- knownDependencies.insert( ng->ConvertToNinjaPath(i->first.c_str()) );
- }
-
- //insert outputs from all WirteBuild commands
- for(std::set<std::string>::iterator i = this->CombinedBuildOutputs.begin();
- i != this->CombinedBuildOutputs.end(); ++i)
- {
- //these paths have already be encoded when added to CombinedBuildOutputs
- knownDependencies.insert(*i);
+ knownDependencies.insert( this->ConvertToNinjaPath(i->first) );
}
- //after we have combined the data into knownDependencies we have no need
- //to keep this data around
- this->CombinedBuildOutputs.clear();
-
- //now we difference with CombinedBuildExplicitDependencies to find
+ //now we difference with CombinedCustomCommandExplicitDependencies to find
//the list of items we know nothing about.
- //We have encoded all the paths in CombinedBuildExplicitDependencies
+ //We have encoded all the paths in CombinedCustomCommandExplicitDependencies
//and knownDependencies so no matter if unix or windows paths they
//should all match now.
- std::vector<std::string> unkownExplicitDepends;
- this->CombinedBuildExplicitDependencies.erase("all");
+ std::vector<std::string> unknownExplicitDepends;
+ this->CombinedCustomCommandExplicitDependencies.erase("all");
- std::set_difference(this->CombinedBuildExplicitDependencies.begin(),
- this->CombinedBuildExplicitDependencies.end(),
+ std::set_difference(this->CombinedCustomCommandExplicitDependencies.begin(),
+ this->CombinedCustomCommandExplicitDependencies.end(),
knownDependencies.begin(),
knownDependencies.end(),
- std::back_inserter(unkownExplicitDepends));
-
+ std::back_inserter(unknownExplicitDepends));
std::string const rootBuildDirectory =
this->GetCMakeInstance()->GetHomeOutputDirectory();
+ bool const inSourceBuild =
+ (rootBuildDirectory == this->GetCMakeInstance()->GetHomeDirectory());
+ std::vector<std::string> warnExplicitDepends;
for (std::vector<std::string>::const_iterator
- i = unkownExplicitDepends.begin();
- i != unkownExplicitDepends.end();
+ i = unknownExplicitDepends.begin();
+ i != unknownExplicitDepends.end();
++i)
{
//verify the file is in the build directory
std::string const absDepPath = cmSystemTools::CollapseFullPath(
- i->c_str(), rootBuildDirectory.c_str());
- bool const inBuildDir = cmSystemTools::IsSubDirectory(absDepPath.c_str(),
- rootBuildDirectory.c_str());
+ *i, rootBuildDirectory.c_str());
+ bool const inBuildDir = cmSystemTools::IsSubDirectory(absDepPath,
+ rootBuildDirectory);
if(inBuildDir)
{
cmNinjaDeps deps(1,*i);
this->WritePhonyBuild(os,
"",
deps,
- deps);
+ cmNinjaDeps());
+ if (this->PolicyCMP0058 == cmPolicies::WARN &&
+ !inSourceBuild && warnExplicitDepends.size() < 10)
+ {
+ warnExplicitDepends.push_back(*i);
+ }
}
}
+
+ if (!warnExplicitDepends.empty())
+ {
+ std::ostringstream w;
+ w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0058) << "\n"
+ "This project specifies custom command DEPENDS on files "
+ "in the build tree that are not specified as the OUTPUT or "
+ "BYPRODUCTS of any add_custom_command or add_custom_target:\n"
+ " " << cmJoin(warnExplicitDepends, "\n ") <<
+ "\n"
+ "For compatibility with versions of CMake that did not have "
+ "the BYPRODUCTS option, CMake is generating phony rules for "
+ "such files to convince 'ninja' to build."
+ "\n"
+ "Project authors should add the missing BYPRODUCTS or OUTPUT "
+ "options to the custom commands that produce these files."
+ ;
+ this->GetCMakeInstance()->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ }
}
void cmGlobalNinjaGenerator::WriteBuiltinTargets(std::ostream& os)
@@ -1066,17 +1217,15 @@ void cmGlobalNinjaGenerator::WriteTargetAll(std::ostream& os)
void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
{
cmLocalGenerator *lg = this->LocalGenerators[0];
- cmMakefile* mfRoot = lg->GetMakefile();
- cmOStringStream cmd;
- cmd << lg->ConvertToOutputFormat(
- mfRoot->GetRequiredDefinition("CMAKE_COMMAND"),
- cmLocalGenerator::SHELL)
+ std::ostringstream cmd;
+ cmd << lg->ConvertToOutputFormat(cmSystemTools::GetCMakeCommand(),
+ cmLocalGenerator::SHELL)
<< " -H"
- << lg->ConvertToOutputFormat(mfRoot->GetHomeDirectory(),
+ << lg->ConvertToOutputFormat(lg->GetSourceDirectory(),
cmLocalGenerator::SHELL)
<< " -B"
- << lg->ConvertToOutputFormat(mfRoot->GetHomeOutputDirectory(),
+ << lg->ConvertToOutputFormat(lg->GetBinaryDirectory(),
cmLocalGenerator::SHELL);
WriteRule(*this->RulesFileStream,
"RERUN_CMAKE",
@@ -1084,21 +1233,36 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
"Re-running CMake...",
"Rule for re-running cmake.",
/*depfile=*/ "",
+ /*deptype=*/ "",
/*rspfile=*/ "",
/*rspcontent*/ "",
- /*restat=*/ false,
+ /*restat=*/ "",
/*generator=*/ true);
cmNinjaDeps implicitDeps;
- for (std::vector<cmLocalGenerator *>::const_iterator i =
- this->LocalGenerators.begin(); i != this->LocalGenerators.end(); ++i) {
- const std::vector<std::string>& lf = (*i)->GetMakefile()->GetListFiles();
- implicitDeps.insert(implicitDeps.end(), lf.begin(), lf.end());
- }
+ for(std::vector<cmLocalGenerator*>::const_iterator i =
+ this->LocalGenerators.begin(); i != this->LocalGenerators.end(); ++i)
+ {
+ std::vector<std::string> const& lf = (*i)->GetMakefile()->GetListFiles();
+ for(std::vector<std::string>::const_iterator fi = lf.begin();
+ fi != lf.end(); ++fi)
+ {
+ implicitDeps.push_back(this->ConvertToNinjaPath(*fi));
+ }
+ }
+ implicitDeps.push_back("CMakeCache.txt");
+
std::sort(implicitDeps.begin(), implicitDeps.end());
implicitDeps.erase(std::unique(implicitDeps.begin(), implicitDeps.end()),
implicitDeps.end());
- implicitDeps.push_back("CMakeCache.txt");
+
+ cmNinjaVars variables;
+ // Use 'console' pool to get non buffered output of the CMake re-run call
+ // Available since Ninja 1.5
+ if(SupportsConsolePool())
+ {
+ variables["pool"] = "console";
+ }
this->WriteBuild(os,
"Re-run CMake if any of its inputs changed.",
@@ -1107,7 +1271,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
/*explicitDeps=*/ cmNinjaDeps(),
implicitDeps,
/*orderOnlyDeps=*/ cmNinjaDeps(),
- /*variables=*/ cmNinjaVars());
+ variables);
this->WritePhonyBuild(os,
"A missing CMake input file is not an error.",
@@ -1119,24 +1283,31 @@ std::string cmGlobalNinjaGenerator::ninjaCmd() const
{
cmLocalGenerator* lgen = this->LocalGenerators[0];
if (lgen) {
- return lgen->ConvertToOutputFormat(
- lgen->GetMakefile()->GetRequiredDefinition("CMAKE_MAKE_PROGRAM"),
- cmLocalGenerator::SHELL);
+ return lgen->ConvertToOutputFormat(this->NinjaCommand,
+ cmLocalGenerator::SHELL);
}
return "ninja";
}
+bool cmGlobalNinjaGenerator::SupportsConsolePool() const
+{
+ return cmSystemTools::VersionCompare(cmSystemTools::OP_LESS,
+ this->NinjaVersion.c_str(),
+ RequiredNinjaVersionForConsolePool().c_str()) == false;
+}
+
void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
{
WriteRule(*this->RulesFileStream,
"CLEAN",
- (ninjaCmd() + " -t clean").c_str(),
+ ninjaCmd() + " -t clean",
"Cleaning all built files...",
"Rule for cleaning all built files.",
/*depfile=*/ "",
+ /*deptype=*/ "",
/*rspfile=*/ "",
/*rspcontent*/ "",
- /*restat=*/ false,
+ /*restat=*/ "",
/*generator=*/ false);
WriteBuild(os,
"Clean all the built files.",
@@ -1152,13 +1323,14 @@ void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os)
{
WriteRule(*this->RulesFileStream,
"HELP",
- (ninjaCmd() + " -t targets").c_str(),
+ ninjaCmd() + " -t targets",
"All primary targets available:",
"Rule for printing all primary targets available.",
/*depfile=*/ "",
+ /*deptype=*/ "",
/*rspfile=*/ "",
/*rspcontent*/ "",
- /*restat=*/ false,
+ /*restat=*/ "",
/*generator=*/ false);
WriteBuild(os,
"Print all primary targets available.",
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index e046c7c96..86565902c 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -13,7 +13,7 @@
#ifndef cmGlobalNinjaGenerator_h
# define cmGlobalNinjaGenerator_h
-# include "cmGlobalGenerator.h"
+# include "cmGlobalCommonGenerator.h"
# include "cmGlobalGeneratorFactory.h"
# include "cmNinjaTypes.h"
@@ -42,7 +42,7 @@ class cmGeneratorTarget;
* - We extensively use Ninja variable overloading system to minimize the
* number of generated rules.
*/
-class cmGlobalNinjaGenerator : public cmGlobalGenerator
+class cmGlobalNinjaGenerator : public cmGlobalCommonGenerator
{
public:
/// The default name of Ninja's build file. Typically: build.ninja.
@@ -61,9 +61,11 @@ public:
/// Write a divider in the given output stream @a os.
static void WriteDivider(std::ostream& os);
+ static std::string EncodeRuleName(std::string const& name);
static std::string EncodeIdent(const std::string &ident, std::ostream &vars);
static std::string EncodeLiteral(const std::string &lit);
- static std::string EncodePath(const std::string &path);
+ std::string EncodePath(const std::string &path);
+ static std::string EncodeDepfileSpace(const std::string &path);
/**
* Write the given @a comment to the output stream @a os. It
@@ -72,6 +74,12 @@ public:
static void WriteComment(std::ostream& os, const std::string& comment);
/**
+ * Utilized by the generator factory to determine if this generator
+ * supports toolsets.
+ */
+ static bool SupportsToolset() { return false; }
+
+ /**
* Write a build statement to @a os with the @a comment using
* the @a rule the list of @a outputs files and inputs.
* It also writes the variables bound to this build statement.
@@ -86,7 +94,8 @@ public:
const cmNinjaDeps& orderOnlyDeps,
const cmNinjaVars& variables,
const std::string& rspfile = std::string(),
- int cmdLineLimit = -1);
+ int cmdLineLimit = -1,
+ bool* usedResponseFile = 0);
/**
* Helper to write a build statement with the special 'phony' rule.
@@ -102,9 +111,11 @@ public:
void WriteCustomCommandBuild(const std::string& command,
const std::string& description,
const std::string& comment,
+ bool uses_terminal,
+ bool restat,
const cmNinjaDeps& outputs,
const cmNinjaDeps& deps = cmNinjaDeps(),
- const cmNinjaDeps& orderOnlyDeps = cmNinjaDeps());
+ const cmNinjaDeps& orderOnly = cmNinjaDeps());
void WriteMacOSXContentBuild(const std::string& input,
const std::string& output);
@@ -120,9 +131,10 @@ public:
const std::string& description,
const std::string& comment,
const std::string& depfile,
+ const std::string& deptype,
const std::string& rspfile,
const std::string& rspcontent,
- bool restat,
+ const std::string& restat,
bool generator);
/**
@@ -152,51 +164,39 @@ public:
const cmNinjaDeps& targets,
const std::string& comment = "");
-
- static bool IsMinGW() { return UsingMinGW; }
-
+ bool IsGCCOnWindows() const { return UsingGCCOnWindows; }
public:
- /// Default constructor.
- cmGlobalNinjaGenerator();
+ cmGlobalNinjaGenerator(cmake* cm);
- /// Convenience method for creating an instance of this class.
static cmGlobalGeneratorFactory* NewFactory() {
return new cmGlobalGeneratorSimpleFactory<cmGlobalNinjaGenerator>(); }
- /// Destructor.
virtual ~cmGlobalNinjaGenerator() { }
- /// Overloaded methods. @see cmGlobalGenerator::CreateLocalGenerator()
- virtual cmLocalGenerator* CreateLocalGenerator();
+ virtual cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf);
- /// Overloaded methods. @see cmGlobalGenerator::GetName().
- virtual const char* GetName() const {
+ virtual std::string GetName() const {
return cmGlobalNinjaGenerator::GetActualName(); }
- /// @return the name of this generator.
- static const char* GetActualName() { return "Ninja"; }
+ static std::string GetActualName() { return "Ninja"; }
- /// Overloaded methods. @see cmGlobalGenerator::GetDocumentation()
static void GetDocumentation(cmDocumentationEntry& entry);
- /// Overloaded methods. @see cmGlobalGenerator::Generate()
- virtual void Generate();
-
- /// Overloaded methods. @see cmGlobalGenerator::EnableLanguage()
virtual void EnableLanguage(std::vector<std::string>const& languages,
cmMakefile* mf,
bool optional);
- /// Overloaded methods. @see cmGlobalGenerator::GenerateBuildCommand()
- virtual std::string GenerateBuildCommand(const char* makeProgram,
- const char* projectName,
- const char* projectDir,
- const char* additionalOptions,
- const char* targetName,
- const char* config,
- bool ignoreErrors,
- bool fast);
+ virtual void GenerateBuildCommand(
+ std::vector<std::string>& makeCommand,
+ const std::string& makeProgram,
+ const std::string& projectName,
+ const std::string& projectDir,
+ const std::string& targetName,
+ const std::string& config,
+ bool fast, bool verbose,
+ std::vector<std::string> const& makeOptions = std::vector<std::string>()
+ );
// Setup target names
virtual const char* GetAllTargetName() const { return "all"; }
@@ -227,6 +227,19 @@ public:
cmGeneratedFileStream* GetRulesFileStream() const {
return this->RulesFileStream; }
+ std::string ConvertToNinjaPath(const std::string& path);
+
+ struct MapToNinjaPathImpl {
+ cmGlobalNinjaGenerator* GG;
+ MapToNinjaPathImpl(cmGlobalNinjaGenerator* gg): GG(gg) {}
+ std::string operator()(std::string const& path) {
+ return this->GG->ConvertToNinjaPath(path);
+ }
+ };
+ MapToNinjaPathImpl MapToNinjaPath() {
+ return MapToNinjaPathImpl(this);
+ }
+
void AddCXXCompileCommand(const std::string &commandLine,
const std::string &sourceFile);
@@ -239,11 +252,12 @@ public:
const std::string& command,
const std::string& description,
const std::string& comment,
- const std::string& depfile = "",
- const std::string& rspfile = "",
- const std::string& rspcontent = "",
- bool restat = false,
- bool generator = false);
+ const std::string& depfile,
+ const std::string& deptype,
+ const std::string& rspfile,
+ const std::string& rspcontent,
+ const std::string& restat,
+ bool generator);
bool HasRule(const std::string& name);
@@ -278,34 +292,41 @@ public:
ASD.insert(deps.begin(), deps.end());
}
- void AppendTargetOutputs(cmTarget* target, cmNinjaDeps& outputs);
- void AppendTargetDepends(cmTarget* target, cmNinjaDeps& outputs);
- void AddDependencyToAll(cmTarget* target);
+ void AppendTargetOutputs(cmGeneratorTarget const* target,
+ cmNinjaDeps& outputs);
+ void AppendTargetDepends(cmGeneratorTarget const* target,
+ cmNinjaDeps& outputs);
+ void AddDependencyToAll(cmGeneratorTarget* target);
void AddDependencyToAll(const std::string& input);
const std::vector<cmLocalGenerator*>& GetLocalGenerators() const {
return LocalGenerators; }
- bool IsExcluded(cmLocalGenerator* root, cmTarget& target) {
+ bool IsExcluded(cmLocalGenerator* root, cmGeneratorTarget* target) {
return cmGlobalGenerator::IsExcluded(root, target); }
int GetRuleCmdLength(const std::string& name) {
return RuleCmdLength[name]; }
- void AddTargetAlias(const std::string& alias, cmTarget* target);
+ void AddTargetAlias(const std::string& alias, cmGeneratorTarget* target);
+
+ virtual void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const;
+ // Ninja generator uses 'deps' and 'msvc_deps_prefix' introduced in 1.3
+ static std::string RequiredNinjaVersion() { return "1.3"; }
+ static std::string RequiredNinjaVersionForConsolePool() { return "1.5"; }
+ bool SupportsConsolePool() const;
protected:
- /// Overloaded methods.
- /// @see cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS()
- virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() { return true; }
+ virtual void Generate();
+ virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const { return true; }
-private:
- /// @see cmGlobalGenerator::ComputeTargetObjects
- virtual void ComputeTargetObjects(cmGeneratorTarget* gt) const;
+private:
+ virtual std::string GetEditCacheCommand() const;
+ virtual void FindMakeProgram(cmMakefile* mf);
void OpenBuildFileStream();
void CloseBuildFileStream();
@@ -331,8 +352,7 @@ private:
std::string ninjaCmd() const;
-
- /// The file containing the build statement. (the relation ship of the
+ /// The file containing the build statement. (the relationship of the
/// compilation DAG).
cmGeneratedFileStream* BuildFileStream;
/// The file containing the rule statements. (The action attached to each
@@ -353,28 +373,34 @@ private:
/// The set of dependencies to add to the "all" target.
cmNinjaDeps AllDependencies;
+ bool UsingGCCOnWindows;
+
/// The set of custom commands we have seen.
std::set<cmCustomCommand const*> CustomCommands;
/// The set of custom command outputs we have seen.
std::set<std::string> CustomCommandOutputs;
- //The combined explicit dependencies of all build commands that the global
- //generator has issued. When combined with CombinedBuildOutputs it allows
- //us to detect the set of explicit dependencies that have
- std::set<std::string> CombinedBuildExplicitDependencies;
+ /// Whether we are collecting known build outputs and needed
+ /// dependencies to determine unknown dependencies.
+ bool ComputingUnknownDependencies;
+ cmPolicies::PolicyStatus PolicyCMP0058;
+
+ /// The combined explicit dependencies of custom build commands
+ std::set<std::string> CombinedCustomCommandExplicitDependencies;
+
+ /// When combined with CombinedCustomCommandExplicitDependencies it allows
+ /// us to detect the set of explicit dependencies that have
std::set<std::string> CombinedBuildOutputs;
/// The mapping from source file to assumed dependencies.
std::map<std::string, std::set<std::string> > AssumedSourceDependencies;
- typedef std::map<std::string, cmTarget*> TargetAliasMap;
+ typedef std::map<std::string, cmGeneratorTarget*> TargetAliasMap;
TargetAliasMap TargetAliases;
- static cmLocalGenerator* LocalGenerator;
-
- static bool UsingMinGW;
-
+ std::string NinjaCommand;
+ std::string NinjaVersion;
};
#endif // ! cmGlobalNinjaGenerator_h
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 88cd6e5f8..ce7815d7d 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -15,11 +15,11 @@
#include "cmMakefile.h"
#include "cmake.h"
#include "cmGeneratedFileStream.h"
-#include "cmSourceFile.h"
-#include "cmTarget.h"
#include "cmGeneratorTarget.h"
+#include "cmAlgorithms.h"
-cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3()
+cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3(cmake* cm)
+ : cmGlobalCommonGenerator(cm)
{
// This type of makefile always requires unix style paths
this->ForceUnixPaths = true;
@@ -32,6 +32,11 @@ cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3()
this->UseLinkScript = true;
#endif
this->CommandDatabase = NULL;
+
+ this->IncludeDirective = "include";
+ this->DefineWindowsNULL = false;
+ this->PassMakeflags = false;
+ this->UnixCD = true;
}
void cmGlobalUnixMakefileGenerator3
@@ -52,11 +57,10 @@ void cmGlobalUnixMakefileGenerator3
}
///! Create a local generator appropriate to this Global Generator
-cmLocalGenerator *cmGlobalUnixMakefileGenerator3::CreateLocalGenerator()
+cmLocalGenerator* cmGlobalUnixMakefileGenerator3::CreateLocalGenerator(
+ cmMakefile* mf)
{
- cmLocalGenerator* lg = new cmLocalUnixMakefileGenerator3;
- lg->SetGlobalGenerator(this);
- return lg;
+ return new cmLocalUnixMakefileGenerator3(this, mf);
}
//----------------------------------------------------------------------------
@@ -65,42 +69,64 @@ void cmGlobalUnixMakefileGenerator3
{
entry.Name = cmGlobalUnixMakefileGenerator3::GetActualName();
entry.Brief = "Generates standard UNIX makefiles.";
- entry.Full =
- "A hierarchy of UNIX makefiles is generated into the build tree. Any "
- "standard UNIX-style make program can build the project through the "
- "default make target. A \"make install\" target is also provided.";
}
//----------------------------------------------------------------------------
-void
-cmGlobalUnixMakefileGenerator3
-::ComputeTargetObjects(cmGeneratorTarget* gt) const
+std::string cmGlobalUnixMakefileGenerator3::GetEditCacheCommand() const
{
- cmTarget* target = gt->Target;
- cmLocalUnixMakefileGenerator3* lg =
- static_cast<cmLocalUnixMakefileGenerator3*>(gt->LocalGenerator);
+ // If generating for an extra IDE, the edit_cache target cannot
+ // launch a terminal-interactive tool, so always use cmake-gui.
+ if(!this->GetExtraGeneratorName().empty())
+ {
+ return cmSystemTools::GetCMakeGUICommand();
+ }
- // Compute full path to object file directory for this target.
- std::string dir_max;
- dir_max += gt->Makefile->GetCurrentOutputDirectory();
- dir_max += "/";
- dir_max += gt->LocalGenerator->GetTargetDirectory(*target);
- dir_max += "/";
- gt->ObjectDirectory = dir_max;
-
- // Compute the name of each object file.
- for(std::vector<cmSourceFile*>::iterator
- si = gt->ObjectSources.begin();
- si != gt->ObjectSources.end(); ++si)
+ // Use an internal cache entry to track the latest dialog used
+ // to edit the cache, and use that for the edit_cache target.
+ cmake* cm = this->GetCMakeInstance();
+ std::string editCacheCommand = cm->GetCMakeEditCommand();
+ if(!cm->GetCacheDefinition("CMAKE_EDIT_COMMAND") ||
+ !editCacheCommand.empty())
{
- cmSourceFile* sf = *si;
- bool hasSourceExtension = true;
- std::string objectName = gt->LocalGenerator
- ->GetObjectFileNameWithoutTarget(*sf, dir_max,
- &hasSourceExtension);
- gt->Objects[sf] = objectName;
- lg->AddLocalObjectFile(target, sf, objectName, hasSourceExtension);
+ if(editCacheCommand.empty())
+ {
+ editCacheCommand = cmSystemTools::GetCMakeCursesCommand();
+ }
+ if(editCacheCommand.empty())
+ {
+ editCacheCommand = cmSystemTools::GetCMakeGUICommand();
+ }
+ if(!editCacheCommand.empty())
+ {
+ cm->AddCacheEntry
+ ("CMAKE_EDIT_COMMAND", editCacheCommand.c_str(),
+ "Path to cache edit program executable.", cmState::INTERNAL);
+ }
}
+ const char* edit_cmd = cm->GetCacheDefinition("CMAKE_EDIT_COMMAND");
+ return edit_cmd? edit_cmd : "";
+}
+
+//----------------------------------------------------------------------------
+void
+cmGlobalUnixMakefileGenerator3
+::ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const
+{
+ // Compute full path to object file directory for this target.
+ std::string dir;
+ dir += gt->LocalGenerator->GetCurrentBinaryDirectory();
+ dir += "/";
+ dir += gt->LocalGenerator->GetTargetDirectory(gt);
+ dir += "/";
+ gt->ObjectDirectory = dir;
+}
+
+void cmGlobalUnixMakefileGenerator3::Configure()
+{
+ // Initialize CMAKE_EDIT_COMMAND cache entry.
+ this->GetEditCacheCommand();
+
+ this->cmGlobalGenerator::Configure();
}
void cmGlobalUnixMakefileGenerator3::Generate()
@@ -131,9 +157,8 @@ void cmGlobalUnixMakefileGenerator3::Generate()
}
for(unsigned int i = 0; i < this->LocalGenerators.size(); ++i)
{
- cmLocalUnixMakefileGenerator3 *lg =
- static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]);
- std::string markFileName = lg->GetMakefile()->GetStartOutputDirectory();
+ cmLocalGenerator *lg = this->LocalGenerators[i];
+ std::string markFileName = lg->GetCurrentBinaryDirectory();
markFileName += "/";
markFileName += cmake::GetCMakeFilesDirectory();
markFileName += "/progress.marks";
@@ -281,7 +306,7 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
// Save the generator name
cmakefileStream
<< "# The generator used is:\n"
- << "SET(CMAKE_DEPENDS_GENERATOR \"" << this->GetName() << "\")\n\n";
+ << "set(CMAKE_DEPENDS_GENERATOR \"" << this->GetName() << "\")\n\n";
// for each cmMakefile get its list of dependencies
std::vector<std::string> lfiles;
@@ -312,16 +337,16 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
// Save the list to the cmake file.
cmakefileStream
<< "# The top level Makefile was generated from the following files:\n"
- << "SET(CMAKE_MAKEFILE_DEPENDS\n"
+ << "set(CMAKE_MAKEFILE_DEPENDS\n"
<< " \""
- << lg->Convert(cache.c_str(),
- cmLocalGenerator::START_OUTPUT).c_str() << "\"\n";
+ << lg->Convert(cache,
+ cmLocalGenerator::START_OUTPUT) << "\"\n";
for(std::vector<std::string>::const_iterator i = lfiles.begin();
i != lfiles.end(); ++i)
{
cmakefileStream
<< " \""
- << lg->Convert(i->c_str(), cmLocalGenerator::START_OUTPUT).c_str()
+ << lg->Convert(*i, cmLocalGenerator::START_OUTPUT)
<< "\"\n";
}
cmakefileStream
@@ -335,27 +360,27 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
// Set the corresponding makefile in the cmake file.
cmakefileStream
<< "# The corresponding makefile is:\n"
- << "SET(CMAKE_MAKEFILE_OUTPUTS\n"
+ << "set(CMAKE_MAKEFILE_OUTPUTS\n"
<< " \""
- << lg->Convert(makefileName.c_str(),
- cmLocalGenerator::START_OUTPUT).c_str() << "\"\n"
+ << lg->Convert(makefileName,
+ cmLocalGenerator::START_OUTPUT) << "\"\n"
<< " \""
- << lg->Convert(check.c_str(),
- cmLocalGenerator::START_OUTPUT).c_str() << "\"\n";
+ << lg->Convert(check,
+ cmLocalGenerator::START_OUTPUT) << "\"\n";
cmakefileStream << " )\n\n";
// CMake must rerun if a byproduct is missing.
{
cmakefileStream
<< "# Byproducts of CMake generate step:\n"
- << "SET(CMAKE_MAKEFILE_PRODUCTS\n";
+ << "set(CMAKE_MAKEFILE_PRODUCTS\n";
const std::vector<std::string>& outfiles =
lg->GetMakefile()->GetOutputFiles();
for(std::vector<std::string>::const_iterator k = outfiles.begin();
k != outfiles.end(); ++k)
{
cmakefileStream << " \"" <<
- lg->Convert(k->c_str(),cmLocalGenerator::HOME_OUTPUT).c_str()
+ lg->Convert(*k,cmLocalGenerator::HOME_OUTPUT)
<< "\"\n";
}
@@ -365,11 +390,11 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
{
lg =
static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]);
- tmpStr = lg->GetMakefile()->GetStartOutputDirectory();
+ tmpStr = lg->GetCurrentBinaryDirectory();
tmpStr += cmake::GetCMakeFilesDirectory();
tmpStr += "/CMakeDirectoryInformation.cmake";
cmakefileStream << " \"" <<
- lg->Convert(tmpStr.c_str(),cmLocalGenerator::HOME_OUTPUT).c_str()
+ lg->Convert(tmpStr,cmLocalGenerator::HOME_OUTPUT)
<< "\"\n";
}
cmakefileStream << " )\n\n";
@@ -390,25 +415,27 @@ void cmGlobalUnixMakefileGenerator3
cmakefileStream
<< "# Dependency information for all targets:\n";
cmakefileStream
- << "SET(CMAKE_DEPEND_INFO_FILES\n";
+ << "set(CMAKE_DEPEND_INFO_FILES\n";
for (unsigned int i = 0; i < lGenerators.size(); ++i)
{
lg = static_cast<cmLocalUnixMakefileGenerator3 *>(lGenerators[i]);
// for all of out targets
- for (cmTargets::iterator l = lg->GetMakefile()->GetTargets().begin();
- l != lg->GetMakefile()->GetTargets().end(); l++)
+ std::vector<cmGeneratorTarget*> tgts = lg->GetGeneratorTargets();
+ for (std::vector<cmGeneratorTarget*>::iterator l = tgts.begin();
+ l != tgts.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::OBJECT_LIBRARY) ||
- (l->second.GetType() == cmTarget::UTILITY))
+ if(((*l)->GetType() == cmState::EXECUTABLE) ||
+ ((*l)->GetType() == cmState::STATIC_LIBRARY) ||
+ ((*l)->GetType() == cmState::SHARED_LIBRARY) ||
+ ((*l)->GetType() == cmState::MODULE_LIBRARY) ||
+ ((*l)->GetType() == cmState::OBJECT_LIBRARY) ||
+ ((*l)->GetType() == cmState::UTILITY))
{
- std::string tname = lg->GetRelativeTargetDirectory(l->second);
+ cmGeneratorTarget* gt = *l;
+ std::string tname = lg->GetRelativeTargetDirectory(gt);
tname += "/DependInfo.cmake";
cmSystemTools::ConvertToUnixSlashes(tname);
- cmakefileStream << " \"" << tname.c_str() << "\"\n";
+ cmakefileStream << " \"" << tname << "\"\n";
}
}
}
@@ -424,29 +451,33 @@ cmGlobalUnixMakefileGenerator3
bool check_relink)
{
// Get the relative path to the subdirectory from the top.
- std::string makeTarget = lg->GetMakefile()->GetStartOutputDirectory();
+ std::string makeTarget = lg->GetCurrentBinaryDirectory();
makeTarget += "/";
makeTarget += pass;
// The directory-level rule should depend on the target-level rules
// for all targets in the directory.
std::vector<std::string> depends;
- for(cmTargets::iterator l = lg->GetMakefile()->GetTargets().begin();
- l != lg->GetMakefile()->GetTargets().end(); ++l)
+ std::vector<cmGeneratorTarget*> targets = lg->GetGeneratorTargets();
+ for(std::vector<cmGeneratorTarget*>::iterator l = targets.begin();
+ l != targets.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::OBJECT_LIBRARY) ||
- (l->second.GetType() == cmTarget::UTILITY))
+ cmGeneratorTarget* gtarget = *l;
+ int type = gtarget->GetType();
+ if((type == cmState::EXECUTABLE) ||
+ (type == cmState::STATIC_LIBRARY) ||
+ (type == cmState::SHARED_LIBRARY) ||
+ (type == cmState::MODULE_LIBRARY) ||
+ (type == cmState::OBJECT_LIBRARY) ||
+ (type == cmState::UTILITY))
{
// Add this to the list of depends rules in this directory.
- if((!check_all || !l->second.GetPropertyAsBool("EXCLUDE_FROM_ALL")) &&
+ if((!check_all || !gtarget->GetPropertyAsBool("EXCLUDE_FROM_ALL")) &&
(!check_relink ||
- l->second.NeedRelinkBeforeInstall(lg->ConfigurationName.c_str())))
+ gtarget
+ ->NeedRelinkBeforeInstall(lg->GetConfigName())))
{
- std::string tname = lg->GetRelativeTargetDirectory(l->second);
+ std::string tname = lg->GetRelativeTargetDirectory(gtarget);
tname += "/";
tname += pass;
depends.push_back(tname);
@@ -456,12 +487,12 @@ cmGlobalUnixMakefileGenerator3
// The directory-level rule should depend on the directory-level
// rules of the subdirectories.
- for(std::vector<cmLocalGenerator*>::iterator sdi =
- lg->GetChildren().begin(); sdi != lg->GetChildren().end(); ++sdi)
+ std::vector<cmState::Snapshot> children
+ = lg->GetStateSnapshot().GetChildren();
+ for(std::vector<cmState::Snapshot>::const_iterator
+ ci = children.begin(); ci != children.end(); ++ci)
{
- cmLocalUnixMakefileGenerator3* slg =
- static_cast<cmLocalUnixMakefileGenerator3*>(*sdi);
- std::string subdir = slg->GetMakefile()->GetStartOutputDirectory();
+ std::string subdir = ci->GetDirectory().GetCurrentBinary();
subdir += "/";
subdir += pass;
depends.push_back(subdir);
@@ -480,7 +511,7 @@ cmGlobalUnixMakefileGenerator3
doc += "\" pass in the directory.";
std::vector<std::string> no_commands;
lg->WriteMakeRule(ruleFileStream, doc.c_str(),
- makeTarget.c_str(), depends, no_commands, true);
+ makeTarget, depends, no_commands, true);
}
//----------------------------------------------------------------------------
@@ -490,15 +521,15 @@ cmGlobalUnixMakefileGenerator3
cmLocalUnixMakefileGenerator3* lg)
{
// Only subdirectories need these rules.
- if(!lg->GetParent())
+ if(lg->IsRootMakefile())
{
return;
}
// Begin the directory-level rules section.
- std::string dir = lg->GetMakefile()->GetStartOutputDirectory();
- dir = lg->Convert(dir.c_str(), cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE);
+ std::string dir = lg->GetCurrentBinaryDirectory();
+ dir = lg->Convert(dir, cmLocalGenerator::HOME_OUTPUT,
+ cmLocalGenerator::MAKERULE);
lg->WriteDivider(ruleFileStream);
ruleFileStream
<< "# Directory level rules for directory "
@@ -514,79 +545,68 @@ cmGlobalUnixMakefileGenerator3
this->WriteDirectoryRule2(ruleFileStream, lg, "preinstall", true, true);
}
-
-std::string cmGlobalUnixMakefileGenerator3
-::GenerateBuildCommand(const char* makeProgram, const char *projectName,
- const char *projectDir, const char* additionalOptions,
- const char *targetName, const char* config,
- bool ignoreErrors, bool fast)
+//----------------------------------------------------------------------------
+void cmGlobalUnixMakefileGenerator3
+::GenerateBuildCommand(std::vector<std::string>& makeCommand,
+ const std::string& makeProgram,
+ const std::string& /*projectName*/,
+ const std::string& /*projectDir*/,
+ const std::string& targetName,
+ const std::string& /*config*/,
+ bool fast, bool /*verbose*/,
+ std::vector<std::string> const& makeOptions)
{
- // Project name & dir and config are not used yet.
- (void)projectName;
- (void)projectDir;
- (void)config;
-
- std::string makeCommand =
- cmSystemTools::ConvertToUnixOutputPath(makeProgram);
+ makeCommand.push_back(
+ this->SelectMakeProgram(makeProgram)
+ );
// Since we have full control over the invocation of nmake, let us
// make it quiet.
- if ( strcmp(this->GetName(), "NMake Makefiles") == 0 )
- {
- makeCommand += " /NOLOGO ";
- }
- if ( ignoreErrors )
- {
- makeCommand += " -i";
- }
- if ( additionalOptions )
+ if (cmHasLiteralPrefix(this->GetName(), "NMake Makefiles"))
{
- makeCommand += " ";
- makeCommand += additionalOptions;
+ makeCommand.push_back("/NOLOGO");
}
- if ( targetName && strlen(targetName))
+ makeCommand.insert(makeCommand.end(),
+ makeOptions.begin(), makeOptions.end());
+ if (!targetName.empty())
{
- cmLocalUnixMakefileGenerator3 *lg;
- if (this->LocalGenerators.size())
+ cmMakefile* mf;
+ if (!this->Makefiles.empty())
{
- lg = static_cast<cmLocalUnixMakefileGenerator3 *>
- (this->LocalGenerators[0]);
+ mf = this->Makefiles[0];
}
else
{
- lg = static_cast<cmLocalUnixMakefileGenerator3 *>
- (this->CreateLocalGenerator());
- // set the Start directories
- lg->GetMakefile()->SetStartDirectory
- (this->CMakeInstance->GetStartDirectory());
- lg->GetMakefile()->SetStartOutputDirectory
- (this->CMakeInstance->GetStartOutputDirectory());
- lg->GetMakefile()->MakeStartDirectoriesCurrent();
+ cmState::Snapshot snapshot = this->CMakeInstance->GetCurrentSnapshot();
+ snapshot.GetDirectory().SetCurrentSource
+ (this->CMakeInstance->GetHomeDirectory());
+ snapshot.GetDirectory().SetCurrentBinary
+ (this->CMakeInstance->GetHomeOutputDirectory());
+ snapshot.SetDefaultDefinitions();
+ mf = new cmMakefile(this, snapshot);
}
- makeCommand += " \"";
std::string tname = targetName;
if(fast)
{
tname += "/fast";
}
- tname = lg->Convert(tname.c_str(),cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE);
- makeCommand += tname.c_str();
- makeCommand += "\"";
- if (!this->LocalGenerators.size())
+ cmOutputConverter conv(mf->GetStateSnapshot());
+ tname = conv.Convert(tname,cmOutputConverter::HOME_OUTPUT);
+ cmSystemTools::ConvertToOutputSlashes(tname);
+ makeCommand.push_back(tname);
+ if (this->Makefiles.empty())
{
- delete lg;
+ delete mf;
}
}
- return makeCommand;
}
//----------------------------------------------------------------------------
void
cmGlobalUnixMakefileGenerator3
::WriteConvenienceRules(std::ostream& ruleFileStream,
- std::set<cmStdString> &emitted)
+ std::set<std::string> &emitted)
{
std::vector<std::string> depends;
std::vector<std::string> commands;
@@ -601,44 +621,48 @@ cmGlobalUnixMakefileGenerator3
lg = static_cast<cmLocalUnixMakefileGenerator3 *>
(this->LocalGenerators[i]);
// for each target Generate the rule files for each target.
- cmTargets& targets = lg->GetMakefile()->GetTargets();
- for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
+ std::vector<cmGeneratorTarget*> targets = lg->GetGeneratorTargets();
+ for(std::vector<cmGeneratorTarget*>::iterator t = targets.begin();
+ t != targets.end(); ++t)
{
+ cmGeneratorTarget* gtarget = *t;
// Don't emit the same rule twice (e.g. two targets with the same
// simple name)
- if(t->second.GetName() &&
- strlen(t->second.GetName()) &&
- emitted.insert(t->second.GetName()).second &&
+ int type = gtarget->GetType();
+ std::string name = gtarget->GetName();
+ if(!name.empty() &&
+ emitted.insert(name).second &&
// Handle user targets here. Global targets are handled in
// the local generator on a per-directory basis.
- ((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::OBJECT_LIBRARY) ||
- (t->second.GetType() == cmTarget::UTILITY)))
+ ((type == cmState::EXECUTABLE) ||
+ (type == cmState::STATIC_LIBRARY) ||
+ (type == cmState::SHARED_LIBRARY) ||
+ (type == cmState::MODULE_LIBRARY) ||
+ (type == cmState::OBJECT_LIBRARY) ||
+ (type == cmState::UTILITY)))
{
// Add a rule to build the target by name.
lg->WriteDivider(ruleFileStream);
ruleFileStream
<< "# Target rules for targets named "
- << t->second.GetName() << "\n\n";
+ << name << "\n\n";
// Write the rule.
commands.clear();
std::string tmp = cmake::GetCMakeFilesDirectoryPostSlash();
tmp += "Makefile2";
commands.push_back(lg->GetRecursiveMakeCall
- (tmp.c_str(),t->second.GetName()));
+ (tmp.c_str(),name));
depends.clear();
depends.push_back("cmake_check_build_system");
lg->WriteMakeRule(ruleFileStream,
"Build rule for target.",
- t->second.GetName(), depends, commands,
+ name, depends, commands,
true);
// Add a fast rule to build the target
- std::string localName = lg->GetRelativeTargetDirectory(t->second);
+ std::string localName =
+ lg->GetRelativeTargetDirectory(gtarget);
std::string makefileName;
makefileName = localName;
makefileName += "/build.make";
@@ -646,28 +670,29 @@ cmGlobalUnixMakefileGenerator3
commands.clear();
std::string makeTargetName = localName;
makeTargetName += "/build";
- localName = t->second.GetName();
+ localName = name;
localName += "/fast";
commands.push_back(lg->GetRecursiveMakeCall
- (makefileName.c_str(), makeTargetName.c_str()));
+ (makefileName.c_str(), makeTargetName));
lg->WriteMakeRule(ruleFileStream, "fast build rule for target.",
- localName.c_str(), depends, commands, true);
+ localName, depends, commands, true);
// Add a local name for the rule to relink the target before
// installation.
- if(t->second.NeedRelinkBeforeInstall(lg->ConfigurationName.c_str()))
+ if(gtarget
+ ->NeedRelinkBeforeInstall(lg->GetConfigName()))
{
- makeTargetName = lg->GetRelativeTargetDirectory(t->second);
+ makeTargetName = lg->GetRelativeTargetDirectory(gtarget);
makeTargetName += "/preinstall";
- localName = t->second.GetName();
+ localName = name;
localName += "/preinstall";
depends.clear();
commands.clear();
commands.push_back(lg->GetRecursiveMakeCall
- (makefileName.c_str(), makeTargetName.c_str()));
+ (makefileName.c_str(), makeTargetName));
lg->WriteMakeRule(ruleFileStream,
"Manual pre-install relink rule for target.",
- localName.c_str(), depends, commands, true);
+ localName, depends, commands, true);
}
}
}
@@ -693,25 +718,28 @@ cmGlobalUnixMakefileGenerator3
depends.push_back("cmake_check_build_system");
// for each target Generate the rule files for each target.
- cmTargets& targets = lg->GetMakefile()->GetTargets();
- for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
+ std::vector<cmGeneratorTarget*> targets = lg->GetGeneratorTargets();
+ for(std::vector<cmGeneratorTarget*>::iterator t = targets.begin();
+ t != targets.end(); ++t)
{
- if (t->second.GetName()
- && strlen(t->second.GetName())
- && ((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::OBJECT_LIBRARY)
- || (t->second.GetType() == cmTarget::UTILITY)))
+ cmGeneratorTarget* gtarget = *t;
+ int type = gtarget->GetType();
+ std::string name = gtarget->GetName();
+ if (!name.empty()
+ && ( (type == cmState::EXECUTABLE)
+ || (type == cmState::STATIC_LIBRARY)
+ || (type == cmState::SHARED_LIBRARY)
+ || (type == cmState::MODULE_LIBRARY)
+ || (type == cmState::OBJECT_LIBRARY)
+ || (type == cmState::UTILITY)))
{
std::string makefileName;
// Add a rule to build the target by name.
- localName = lg->GetRelativeTargetDirectory(t->second);
+ localName = lg->GetRelativeTargetDirectory(gtarget);
makefileName = localName;
makefileName += "/build.make";
- bool needRequiresStep = this->NeedRequiresStep(t->second);
+ bool needRequiresStep = this->NeedRequiresStep(gtarget);
lg->WriteDivider(ruleFileStream);
ruleFileStream
@@ -722,7 +750,7 @@ cmGlobalUnixMakefileGenerator3
makeTargetName = localName;
makeTargetName += "/depend";
commands.push_back(lg->GetRecursiveMakeCall
- (makefileName.c_str(),makeTargetName.c_str()));
+ (makefileName.c_str(),makeTargetName));
// add requires if we need it for this generator
if (needRequiresStep)
@@ -730,47 +758,54 @@ cmGlobalUnixMakefileGenerator3
makeTargetName = localName;
makeTargetName += "/requires";
commands.push_back(lg->GetRecursiveMakeCall
- (makefileName.c_str(),makeTargetName.c_str()));
+ (makefileName.c_str(),makeTargetName));
}
makeTargetName = localName;
makeTargetName += "/build";
commands.push_back(lg->GetRecursiveMakeCall
- (makefileName.c_str(),makeTargetName.c_str()));
+ (makefileName.c_str(),makeTargetName));
// Write the rule.
localName += "/all";
depends.clear();
- std::string progressDir =
- lg->GetMakefile()->GetHomeOutputDirectory();
- progressDir += cmake::GetCMakeFilesDirectory();
+ cmLocalUnixMakefileGenerator3::EchoProgress progress;
+ progress.Dir = lg->GetBinaryDirectory();
+ progress.Dir += cmake::GetCMakeFilesDirectory();
+ {
+ std::ostringstream progressArg;
+ const char* sep = "";
+ std::vector<unsigned long>& progFiles =
+ this->ProgressMap[gtarget].Marks;
+ for (std::vector<unsigned long>::iterator i = progFiles.begin();
+ i != progFiles.end(); ++i)
{
- cmOStringStream progCmd;
- progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report ";
- // all target counts
- progCmd << lg->Convert(progressDir.c_str(),
- cmLocalGenerator::FULL,
- cmLocalGenerator::SHELL);
- progCmd << " ";
- std::vector<unsigned long>& progFiles =
- this->ProgressMap[&t->second].Marks;
- for (std::vector<unsigned long>::iterator i = progFiles.begin();
- i != progFiles.end(); ++i)
- {
- progCmd << " " << *i;
- }
- commands.push_back(progCmd.str());
+ progressArg << sep << *i;
+ sep = ",";
}
- progressDir = "Built target ";
- progressDir += t->first;
- lg->AppendEcho(commands,progressDir.c_str());
+ progress.Arg = progressArg.str();
+ }
- this->AppendGlobalTargetDepends(depends,t->second);
+ bool targetMessages = true;
+ if (const char* tgtMsg = this->GetCMakeInstance()
+ ->GetState()
+ ->GetGlobalProperty("TARGET_MESSAGES"))
+ {
+ targetMessages = cmSystemTools::IsOn(tgtMsg);
+ }
+
+ if (targetMessages)
+ {
+ lg->AppendEcho(commands, "Built target " + name,
+ cmLocalUnixMakefileGenerator3::EchoNormal, &progress);
+ }
+
+ this->AppendGlobalTargetDepends(depends, gtarget);
lg->WriteMakeRule(ruleFileStream, "All Build rule for target.",
- localName.c_str(), depends, commands, true);
+ localName, depends, commands, true);
// add the all/all dependency
- if(!this->IsExcluded(this->LocalGenerators[0], t->second))
+ if(!this->IsExcluded(this->LocalGenerators[0], gtarget))
{
depends.clear();
depends.push_back(localName);
@@ -781,31 +816,29 @@ cmGlobalUnixMakefileGenerator3
// Write the rule.
commands.clear();
- progressDir = lg->GetMakefile()->GetHomeOutputDirectory();
- progressDir += cmake::GetCMakeFilesDirectory();
{
// TODO: Convert the total progress count to a make variable.
- cmOStringStream progCmd;
+ std::ostringstream progCmd;
progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start ";
// # in target
- progCmd << lg->Convert(progressDir.c_str(),
+ progCmd << lg->Convert(progress.Dir,
cmLocalGenerator::FULL,
cmLocalGenerator::SHELL);
//
- std::set<cmTarget *> emitted;
+ std::set<cmGeneratorTarget const*> emitted;
progCmd << " "
- << this->CountProgressMarksInTarget(&t->second, emitted);
+ << this->CountProgressMarksInTarget(gtarget, emitted);
commands.push_back(progCmd.str());
}
std::string tmp = cmake::GetCMakeFilesDirectoryPostSlash();
tmp += "Makefile2";
commands.push_back(lg->GetRecursiveMakeCall
- (tmp.c_str(),localName.c_str()));
+ (tmp.c_str(),localName));
{
- cmOStringStream progCmd;
+ std::ostringstream progCmd;
progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0
- progCmd << lg->Convert(progressDir.c_str(),
+ progCmd << lg->Convert(progress.Dir,
cmLocalGenerator::FULL,
cmLocalGenerator::SHELL);
progCmd << " 0";
@@ -813,33 +846,34 @@ cmGlobalUnixMakefileGenerator3
}
depends.clear();
depends.push_back("cmake_check_build_system");
- localName = lg->GetRelativeTargetDirectory(t->second);
+ localName = lg->GetRelativeTargetDirectory(gtarget);
localName += "/rule";
lg->WriteMakeRule(ruleFileStream,
"Build rule for subdir invocation for target.",
- localName.c_str(), depends, commands, true);
+ localName, depends, commands, true);
// Add a target with the canonical name (no prefix, suffix or path).
commands.clear();
depends.clear();
depends.push_back(localName);
lg->WriteMakeRule(ruleFileStream, "Convenience name for target.",
- t->second.GetName(), depends, commands, true);
+ name, depends, commands, true);
// Add rules to prepare the target for installation.
- if(t->second.NeedRelinkBeforeInstall(lg->ConfigurationName.c_str()))
+ if(gtarget
+ ->NeedRelinkBeforeInstall(lg->GetConfigName()))
{
- localName = lg->GetRelativeTargetDirectory(t->second);
+ localName = lg->GetRelativeTargetDirectory(gtarget);
localName += "/preinstall";
depends.clear();
commands.clear();
commands.push_back(lg->GetRecursiveMakeCall
- (makefileName.c_str(), localName.c_str()));
+ (makefileName.c_str(), localName));
lg->WriteMakeRule(ruleFileStream,
"Pre-install relink rule for target.",
- localName.c_str(), depends, commands, true);
+ localName, depends, commands, true);
- if(!this->IsExcluded(this->LocalGenerators[0], t->second))
+ if(!this->IsExcluded(this->LocalGenerators[0], gtarget))
{
depends.clear();
depends.push_back(localName);
@@ -850,15 +884,15 @@ cmGlobalUnixMakefileGenerator3
}
// add the clean rule
- localName = lg->GetRelativeTargetDirectory(t->second);
+ localName = lg->GetRelativeTargetDirectory(gtarget);
makeTargetName = localName;
makeTargetName += "/clean";
depends.clear();
commands.clear();
commands.push_back(lg->GetRecursiveMakeCall
- (makefileName.c_str(), makeTargetName.c_str()));
+ (makefileName.c_str(), makeTargetName));
lg->WriteMakeRule(ruleFileStream, "clean rule for target.",
- makeTargetName.c_str(), depends, commands, true);
+ makeTargetName, depends, commands, true);
commands.clear();
depends.push_back(makeTargetName);
lg->WriteMakeRule(ruleFileStream, "clean rule for target.",
@@ -867,20 +901,76 @@ cmGlobalUnixMakefileGenerator3
}
}
+// Build a map that contains a the set of targets used by each local
+// generator directory level.
+void cmGlobalUnixMakefileGenerator3::InitializeProgressMarks()
+{
+ this->DirectoryTargetsMap.clear();
+ // Loop over all targets in all local generators.
+ for(std::vector<cmLocalGenerator*>::const_iterator
+ lgi = this->LocalGenerators.begin();
+ lgi != this->LocalGenerators.end(); ++lgi)
+ {
+ cmLocalGenerator* lg = *lgi;
+ std::vector<cmGeneratorTarget*> targets = lg->GetGeneratorTargets();
+ for(std::vector<cmGeneratorTarget*>::const_iterator t = targets.begin();
+ t != targets.end(); ++t)
+ {
+ cmGeneratorTarget* gt = *t;
+
+ cmLocalGenerator* tlg = gt->GetLocalGenerator();
+
+ if(gt->GetType() == cmState::INTERFACE_LIBRARY
+ || gt->GetPropertyAsBool("EXCLUDE_FROM_ALL"))
+ {
+ continue;
+ }
+
+ cmState::Snapshot csnp = lg->GetStateSnapshot();
+ cmState::Snapshot tsnp = tlg->GetStateSnapshot();
+
+ // Consider the directory containing the target and all its
+ // parents until something excludes the target.
+ for( ; csnp.IsValid() && !this->IsExcluded(csnp, tsnp);
+ csnp = csnp.GetBuildsystemDirectoryParent())
+ {
+ // This local generator includes the target.
+ std::set<cmGeneratorTarget const*>& targetSet =
+ this->DirectoryTargetsMap[csnp];
+ targetSet.insert(gt);
+
+ // Add dependencies of the included target. An excluded
+ // target may still be included if it is a dependency of a
+ // non-excluded target.
+ TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(gt);
+ for(TargetDependSet::const_iterator ti = tgtdeps.begin();
+ ti != tgtdeps.end(); ++ti)
+ {
+ targetSet.insert(*ti);
+ }
+ }
+ }
+ }
+}
+
//----------------------------------------------------------------------------
size_t
cmGlobalUnixMakefileGenerator3
-::CountProgressMarksInTarget(cmTarget* target,
- std::set<cmTarget*>& emitted)
+::CountProgressMarksInTarget(cmGeneratorTarget const* target,
+ std::set<cmGeneratorTarget const*>& emitted)
{
size_t count = 0;
if(emitted.insert(target).second)
{
count = this->ProgressMap[target].Marks.size();
- TargetDependSet const& depends = this->GetTargetDirectDepends(*target);
+ TargetDependSet const& depends = this->GetTargetDirectDepends(target);
for(TargetDependSet::const_iterator di = depends.begin();
di != depends.end(); ++di)
{
+ if ((*di)->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ continue;
+ }
count += this->CountProgressMarksInTarget(*di, emitted);
}
}
@@ -890,12 +980,13 @@ cmGlobalUnixMakefileGenerator3
//----------------------------------------------------------------------------
size_t
cmGlobalUnixMakefileGenerator3
-::CountProgressMarksInAll(cmLocalUnixMakefileGenerator3* lg)
+::CountProgressMarksInAll(cmLocalGenerator* lg)
{
size_t count = 0;
- std::set<cmTarget*> emitted;
- std::set<cmTarget*> const& targets = this->LocalGeneratorToTargetMap[lg];
- for(std::set<cmTarget*>::const_iterator t = targets.begin();
+ std::set<cmGeneratorTarget const*> emitted;
+ std::set<cmGeneratorTarget const*> const& targets
+ = this->DirectoryTargetsMap[lg->GetStateSnapshot()];
+ for(std::set<cmGeneratorTarget const*>::const_iterator t = targets.begin();
t != targets.end(); ++t)
{
count += this->CountProgressMarksInTarget(*t, emitted);
@@ -908,27 +999,12 @@ void
cmGlobalUnixMakefileGenerator3::RecordTargetProgress(
cmMakefileTargetGenerator* tg)
{
- TargetProgress& tp = this->ProgressMap[tg->GetTarget()];
+ TargetProgress& tp = this->ProgressMap[tg->GetGeneratorTarget()];
tp.NumberOfActions = tg->GetNumberOfProgressActions();
tp.VariableFile = tg->GetProgressFileNameFull();
}
//----------------------------------------------------------------------------
-bool
-cmGlobalUnixMakefileGenerator3::ProgressMapCompare
-::operator()(cmTarget* l, cmTarget* r) const
-{
- // Order by target name.
- if(int c = strcmp(l->GetName(), r->GetName()))
- {
- return c < 0;
- }
- // Order duplicate targets by binary directory.
- return strcmp(l->GetMakefile()->GetCurrentOutputDirectory(),
- r->GetMakefile()->GetCurrentOutputDirectory()) < 0;
-}
-
-//----------------------------------------------------------------------------
void
cmGlobalUnixMakefileGenerator3::TargetProgress
::WriteProgressVariables(unsigned long total, unsigned long &current)
@@ -959,18 +1035,22 @@ cmGlobalUnixMakefileGenerator3::TargetProgress
void
cmGlobalUnixMakefileGenerator3
::AppendGlobalTargetDepends(std::vector<std::string>& depends,
- cmTarget& target)
+ cmGeneratorTarget* target)
{
TargetDependSet const& depends_set = this->GetTargetDirectDepends(target);
for(TargetDependSet::const_iterator i = depends_set.begin();
i != depends_set.end(); ++i)
{
// Create the target-level dependency.
- cmTarget const* dep = *i;
+ cmGeneratorTarget const* dep = *i;
+ if (dep->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ continue;
+ }
cmLocalUnixMakefileGenerator3* lg3 =
- static_cast<cmLocalUnixMakefileGenerator3*>
- (dep->GetMakefile()->GetLocalGenerator());
- std::string tgtName = lg3->GetRelativeTargetDirectory(*dep);
+ static_cast<cmLocalUnixMakefileGenerator3*>(dep->GetLocalGenerator());
+ std::string tgtName =
+ lg3->GetRelativeTargetDirectory(const_cast<cmGeneratorTarget*>(dep));
tgtName += "/all";
depends.push_back(tgtName);
}
@@ -991,7 +1071,7 @@ void cmGlobalUnixMakefileGenerator3::WriteHelpRule
lg->AppendEcho(commands,"... depend");
// Keep track of targets already listed.
- std::set<cmStdString> emittedTargets;
+ std::set<std::string> emittedTargets;
// for each local generator
unsigned int i;
@@ -1002,32 +1082,36 @@ void cmGlobalUnixMakefileGenerator3::WriteHelpRule
static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]);
// for the passed in makefile or if this is the top Makefile wripte out
// the targets
- if (lg2 == lg || !lg->GetParent())
+ if (lg2 == lg || lg->IsRootMakefile())
{
// for each target Generate the rule files for each target.
- cmTargets& targets = lg2->GetMakefile()->GetTargets();
- for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
+ std::vector<cmGeneratorTarget*> targets = lg2->GetGeneratorTargets();
+ for(std::vector<cmGeneratorTarget*>::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::OBJECT_LIBRARY) ||
- (t->second.GetType() == cmTarget::GLOBAL_TARGET) ||
- (t->second.GetType() == cmTarget::UTILITY))
+ cmGeneratorTarget* target = *t;
+ cmState::TargetType type = target->GetType();
+ if((type == cmState::EXECUTABLE) ||
+ (type == cmState::STATIC_LIBRARY) ||
+ (type == cmState::SHARED_LIBRARY) ||
+ (type == cmState::MODULE_LIBRARY) ||
+ (type == cmState::OBJECT_LIBRARY) ||
+ (type == cmState::GLOBAL_TARGET) ||
+ (type == cmState::UTILITY))
{
- if(emittedTargets.insert(t->second.GetName()).second)
+ std::string name = target->GetName();
+ if(emittedTargets.insert(name).second)
{
path = "... ";
- path += t->second.GetName();
+ path += name;
lg->AppendEcho(commands,path.c_str());
}
}
}
}
}
- std::vector<cmStdString> const& localHelp = lg->GetLocalHelp();
- for(std::vector<cmStdString>::const_iterator o = localHelp.begin();
+ std::vector<std::string> const& localHelp = lg->GetLocalHelp();
+ for(std::vector<std::string>::const_iterator o = localHelp.begin();
o != localHelp.end(); ++o)
{
path = "... ";
@@ -1042,17 +1126,19 @@ void cmGlobalUnixMakefileGenerator3::WriteHelpRule
bool cmGlobalUnixMakefileGenerator3
-::NeedRequiresStep(cmTarget const& target)
+::NeedRequiresStep(const cmGeneratorTarget* target)
{
- std::set<cmStdString> languages;
- target.GetLanguages(languages);
- for(std::set<cmStdString>::const_iterator l = languages.begin();
+ std::set<std::string> languages;
+ target->GetLanguages(languages,
+ target->Target->GetMakefile()
+ ->GetSafeDefinition("CMAKE_BUILD_TYPE"));
+ for(std::set<std::string>::const_iterator l = languages.begin();
l != languages.end(); ++l)
{
std::string var = "CMAKE_NEEDS_REQUIRES_STEP_";
var += *l;
var += "_FLAG";
- if(target.GetMakefile()->GetDefinition(var.c_str()))
+ if(target->Target->GetMakefile()->GetDefinition(var))
{
return true;
}
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index 5e9dce3a6..0591a5a59 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -12,7 +12,7 @@
#ifndef cmGlobalUnixMakefileGenerator3_h
#define cmGlobalUnixMakefileGenerator3_h
-#include "cmGlobalGenerator.h"
+#include "cmGlobalCommonGenerator.h"
#include "cmGlobalGeneratorFactory.h"
class cmGeneratedFileStream;
@@ -51,32 +51,39 @@ class cmLocalUnixMakefileGenerator3;
*/
-class cmGlobalUnixMakefileGenerator3 : public cmGlobalGenerator
+class cmGlobalUnixMakefileGenerator3 : public cmGlobalCommonGenerator
{
public:
- cmGlobalUnixMakefileGenerator3();
+ cmGlobalUnixMakefileGenerator3(cmake* cm);
static cmGlobalGeneratorFactory* NewFactory() {
return new cmGlobalGeneratorSimpleFactory
<cmGlobalUnixMakefileGenerator3>(); }
///! Get the name for the generator.
- virtual const char* GetName() const {
+ virtual std::string GetName() const {
return cmGlobalUnixMakefileGenerator3::GetActualName();}
- static const char* GetActualName() {return "Unix Makefiles";}
+ static std::string GetActualName() {return "Unix Makefiles";}
+
+ /**
+ * Utilized by the generator factory to determine if this generator
+ * supports toolsets.
+ */
+ static bool SupportsToolset() { return false; }
/** Get the documentation entry for this generator. */
static void GetDocumentation(cmDocumentationEntry& entry);
- ///! Create a local generator appropriate to this Global Generator3
- virtual cmLocalGenerator *CreateLocalGenerator();
+ virtual cmLocalGenerator *CreateLocalGenerator(cmMakefile* mf);
/**
- * Try to determine system infomation such as shared library
+ * Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
cmMakefile *, bool optional);
+ virtual void Configure();
+
/**
* Generate the all required files for building this project/tree. This
* basically creates a series of LocalGenerators for each directory and
@@ -94,7 +101,7 @@ public:
// write the top level target rules
void WriteConvenienceRules(std::ostream& ruleFileStream,
- std::set<cmStdString> &emitted);
+ std::set<std::string> &emitted);
/** Get the command to use for a target that has no rule. This is
used for multiple output dependencies and for cmake_force. */
@@ -105,12 +112,16 @@ public:
std::string GetEmptyRuleHackDepends() { return this->EmptyRuleHackDepends; }
// change the build command for speed
- virtual std::string GenerateBuildCommand
- (const char* makeProgram,
- const char *projectName, const char *projectDir,
- const char* additionalOptions,
- const char *targetName,
- const char* config, bool ignoreErrors, bool fast);
+ virtual void GenerateBuildCommand(
+ std::vector<std::string>& makeCommand,
+ const std::string& makeProgram,
+ const std::string& projectName,
+ const std::string& projectDir,
+ const std::string& targetName,
+ const std::string& config,
+ bool fast, bool verbose,
+ std::vector<std::string> const& makeOptions = std::vector<std::string>()
+ );
/** Record per-target progress information. */
void RecordTargetProgress(cmMakefileTargetGenerator* tg);
@@ -119,6 +130,18 @@ public:
const std::string &workingDirectory,
const std::string &compileCommand);
+ /** Does the make tool tolerate .NOTPARALLEL? */
+ virtual bool AllowNotParallel() const { return true; }
+
+ /** Does the make tool tolerate .DELETE_ON_ERROR? */
+ virtual bool AllowDeleteOnError() const { return true; }
+
+ virtual void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const;
+
+ std::string IncludeDirective;
+ bool DefineWindowsNULL;
+ bool PassMakeflags;
+ bool UnixCD;
protected:
void WriteMainMakefile2();
void WriteMainCMakefile();
@@ -134,10 +157,10 @@ protected:
cmLocalUnixMakefileGenerator3* lg);
void AppendGlobalTargetDepends(std::vector<std::string>& depends,
- cmTarget& target);
+ cmGeneratorTarget* target);
// does this generator need a requires step for any of its targets
- bool NeedRequiresStep(cmTarget const&);
+ bool NeedRequiresStep(cmGeneratorTarget const*);
// Target name hooks for superclass.
const char* GetAllTargetName() const { return "all"; }
@@ -152,7 +175,7 @@ protected:
const char* GetRebuildCacheTargetName() const { return "rebuild_cache"; }
const char* GetCleanTargetName() const { return "clean"; }
- virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() { return true; }
+ virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const { return true; }
// Some make programs (Borland) do not keep a rule if there are no
// dependencies or commands. This is a problem for creating rules
@@ -175,18 +198,23 @@ protected:
std::vector<unsigned long> Marks;
void WriteProgressVariables(unsigned long total, unsigned long& current);
};
- struct ProgressMapCompare { bool operator()(cmTarget*,cmTarget*) const; };
- typedef std::map<cmTarget*, TargetProgress,
- ProgressMapCompare> ProgressMapType;
+ typedef std::map<cmGeneratorTarget const*, TargetProgress,
+ cmGeneratorTarget::StrictTargetComparison> ProgressMapType;
ProgressMapType ProgressMap;
- size_t CountProgressMarksInTarget(cmTarget* target,
- std::set<cmTarget*>& emitted);
- size_t CountProgressMarksInAll(cmLocalUnixMakefileGenerator3* lg);
+ size_t CountProgressMarksInTarget(cmGeneratorTarget const* target,
+ std::set<cmGeneratorTarget const*>& emitted);
+ size_t CountProgressMarksInAll(cmLocalGenerator* lg);
cmGeneratedFileStream *CommandDatabase;
private:
- virtual void ComputeTargetObjects(cmGeneratorTarget* gt) const;
+ virtual const char* GetBuildIgnoreErrorsFlag() const { return "-i"; }
+ virtual std::string GetEditCacheCommand() const;
+
+ std::map<cmState::Snapshot,
+ std::set<cmGeneratorTarget const*>,
+ cmState::Snapshot::StrictWeakOrder> DirectoryTargetsMap;
+ virtual void InitializeProgressMarks();
};
#endif
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index b2a337cc6..c49008d79 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -17,48 +17,72 @@
#include "cmVisualStudioSlnData.h"
#include "cmVisualStudioSlnParser.h"
#include "cmake.h"
+#include "cmAlgorithms.h"
-static const char vs10Win32generatorName[] = "Visual Studio 10";
-static const char vs10Win64generatorName[] = "Visual Studio 10 Win64";
-static const char vs10IA64generatorName[] = "Visual Studio 10 IA64";
+static const char vs10generatorName[] = "Visual Studio 10 2010";
+
+// Map generator name without year to name with year.
+static const char* cmVS10GenName(const std::string& name, std::string& genName)
+{
+ if(strncmp(name.c_str(), vs10generatorName,
+ sizeof(vs10generatorName)-6) != 0)
+ {
+ return 0;
+ }
+ const char* p = name.c_str() + sizeof(vs10generatorName) - 6;
+ if(cmHasLiteralPrefix(p, " 2010"))
+ {
+ p += 5;
+ }
+ genName = std::string(vs10generatorName) + p;
+ return p;
+}
class cmGlobalVisualStudio10Generator::Factory
: public cmGlobalGeneratorFactory
{
public:
- virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const {
- if(!strcmp(name, vs10Win32generatorName))
+ virtual cmGlobalGenerator*
+ CreateGlobalGenerator(const std::string& name, cmake* cm) const
+ {
+ std::string genName;
+ const char* p = cmVS10GenName(name, genName);
+ if(!p)
+ { return 0; }
+ if(!*p)
{
- return new cmGlobalVisualStudio10Generator(
- name, NULL, NULL);
+ return new cmGlobalVisualStudio10Generator(cm, genName, "");
}
- if(!strcmp(name, vs10Win64generatorName))
+ if(*p++ != ' ')
+ { return 0; }
+ if(strcmp(p, "Win64") == 0)
{
- return new cmGlobalVisualStudio10Generator(
- name, "x64", "CMAKE_FORCE_WIN64");
+ return new cmGlobalVisualStudio10Generator(cm, genName, "x64");
}
- if(!strcmp(name, vs10IA64generatorName))
+ if(strcmp(p, "IA64") == 0)
{
- return new cmGlobalVisualStudio10Generator(
- name, "Itanium", "CMAKE_FORCE_IA64");
+ return new cmGlobalVisualStudio10Generator(cm, genName, "Itanium");
}
return 0;
- }
+ }
- virtual void GetDocumentation(cmDocumentationEntry& entry) const {
- entry.Name = "Visual Studio 10";
- entry.Brief = "Generates Visual Studio 10 (2010) project files.";
- entry.Full =
- "It is possible to append a space followed by the platform name "
- "to create project files for a specific target platform. E.g. "
- "\"Visual Studio 10 Win64\" will create project files for "
- "the x64 processor; \"Visual Studio 10 IA64\" for Itanium.";
- }
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const
+ {
+ entry.Name = std::string(vs10generatorName) + " [arch]";
+ entry.Brief =
+ "Generates Visual Studio 2010 project files. "
+ "Optional [arch] can be \"Win64\" or \"IA64\"."
+ ;
+ }
+
+ virtual void GetGenerators(std::vector<std::string>& names) const
+ {
+ names.push_back(vs10generatorName);
+ names.push_back(vs10generatorName + std::string(" IA64"));
+ names.push_back(vs10generatorName + std::string(" Win64"));
+ }
- virtual void GetGenerators(std::vector<std::string>& names) const {
- names.push_back(vs10Win32generatorName);
- names.push_back(vs10Win64generatorName);
- names.push_back(vs10IA64generatorName); }
+ virtual bool SupportsToolset() const { return true; }
};
//----------------------------------------------------------------------------
@@ -68,37 +92,218 @@ cmGlobalGeneratorFactory* cmGlobalVisualStudio10Generator::NewFactory()
}
//----------------------------------------------------------------------------
-cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator(
- const char* name, const char* platformName,
- const char* additionalPlatformDefinition)
- : cmGlobalVisualStudio8Generator(name, platformName,
- additionalPlatformDefinition)
+cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator(cmake* cm,
+ const std::string& name, const std::string& platformName)
+ : cmGlobalVisualStudio8Generator(cm, name, platformName)
{
- this->FindMakeProgramFile = "CMakeVS10FindMake.cmake";
std::string vc10Express;
this->ExpressEdition = cmSystemTools::ReadRegistryValue(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\10.0\\Setup\\VC;"
"ProductDir", vc10Express, cmSystemTools::KeyWOW64_32);
- this->MasmEnabled = false;
+ this->SystemIsWindowsCE = false;
+ this->SystemIsWindowsPhone = false;
+ this->SystemIsWindowsStore = false;
+ this->MSBuildCommandInitialized = false;
+ this->Version = VS10;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio10Generator::MatchesGeneratorName(
+ const std::string& name) const
+{
+ std::string genName;
+ if(cmVS10GenName(name, genName))
+ {
+ return genName == this->GetName();
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio10Generator::SetSystemName(std::string const& s,
+ cmMakefile* mf)
+{
+ this->SystemName = s;
+ this->SystemVersion = mf->GetSafeDefinition("CMAKE_SYSTEM_VERSION");
+ if(!this->InitializeSystem(mf))
+ {
+ return false;
+ }
+ return this->cmGlobalVisualStudio8Generator::SetSystemName(s, mf);
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio10Generator::SetGeneratorPlatform(std::string const& p,
+ cmMakefile* mf)
+{
+ if(!this->cmGlobalVisualStudio8Generator::SetGeneratorPlatform(p, mf))
+ {
+ return false;
+ }
+ if(this->GetPlatformName() == "Itanium" || this->GetPlatformName() == "x64")
+ {
+ if(this->IsExpressEdition() && !this->Find64BitTools(mf))
+ {
+ return false;
+ }
+ }
+ return true;
}
//----------------------------------------------------------------------------
bool
-cmGlobalVisualStudio10Generator::SetGeneratorToolset(std::string const& ts)
+cmGlobalVisualStudio10Generator::SetGeneratorToolset(std::string const& ts,
+ cmMakefile* mf)
{
- this->PlatformToolset = ts;
+ if (this->SystemIsWindowsCE && ts.empty() &&
+ this->DefaultPlatformToolset.empty())
+ {
+ std::ostringstream e;
+ e << this->GetName() << " Windows CE version '" << this->SystemVersion
+ << "' requires CMAKE_GENERATOR_TOOLSET to be set.";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+
+ this->GeneratorToolset = ts;
+ if(const char* toolset = this->GetPlatformToolset())
+ {
+ mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET", toolset);
+ }
return true;
}
//----------------------------------------------------------------------------
-void cmGlobalVisualStudio10Generator::AddPlatformDefinitions(cmMakefile* mf)
+bool cmGlobalVisualStudio10Generator::InitializeSystem(cmMakefile* mf)
{
- cmGlobalVisualStudio8Generator::AddPlatformDefinitions(mf);
- if(!this->PlatformToolset.empty())
+ if (this->SystemName == "Windows")
+ {
+ if (!this->InitializeWindows(mf))
+ {
+ return false;
+ }
+ }
+ else if (this->SystemName == "WindowsCE")
+ {
+ this->SystemIsWindowsCE = true;
+ if (!this->InitializeWindowsCE(mf))
+ {
+ return false;
+ }
+ }
+ else if (this->SystemName == "WindowsPhone")
+ {
+ this->SystemIsWindowsPhone = true;
+ if(!this->InitializeWindowsPhone(mf))
+ {
+ return false;
+ }
+ }
+ else if (this->SystemName == "WindowsStore")
{
- mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET",
- this->PlatformToolset.c_str());
+ this->SystemIsWindowsStore = true;
+ if(!this->InitializeWindowsStore(mf))
+ {
+ return false;
+ }
}
+ else if(this->SystemName == "Android")
+ {
+ if(this->DefaultPlatformName != "Win32")
+ {
+ std::ostringstream e;
+ e << "CMAKE_SYSTEM_NAME is 'Android' but CMAKE_GENERATOR "
+ << "specifies a platform too: '" << this->GetName() << "'";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+ std::string v = this->GetInstalledNsightTegraVersion();
+ if(v.empty())
+ {
+ mf->IssueMessage(cmake::FATAL_ERROR,
+ "CMAKE_SYSTEM_NAME is 'Android' but "
+ "'NVIDIA Nsight Tegra Visual Studio Edition' "
+ "is not installed.");
+ return false;
+ }
+ this->DefaultPlatformName = "Tegra-Android";
+ this->DefaultPlatformToolset = "Default";
+ this->NsightTegraVersion = v;
+ mf->AddDefinition("CMAKE_VS_NsightTegra_VERSION", v.c_str());
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio10Generator::InitializeWindows(cmMakefile*)
+{
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio10Generator::InitializeWindowsCE(cmMakefile* mf)
+{
+ if (this->DefaultPlatformName != "Win32")
+ {
+ std::ostringstream e;
+ e << "CMAKE_SYSTEM_NAME is 'WindowsCE' but CMAKE_GENERATOR "
+ << "specifies a platform too: '" << this->GetName() << "'";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+
+ this->DefaultPlatformToolset = this->SelectWindowsCEToolset();
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio10Generator::InitializeWindowsPhone(cmMakefile* mf)
+{
+ std::ostringstream e;
+ e << this->GetName() << " does not support Windows Phone.";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio10Generator::InitializeWindowsStore(cmMakefile* mf)
+{
+ std::ostringstream e;
+ e << this->GetName() << " does not support Windows Store.";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio10Generator::SelectWindowsPhoneToolset(
+ std::string& toolset) const
+{
+ toolset = "";
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio10Generator::SelectWindowsStoreToolset(
+ std::string& toolset) const
+{
+ toolset = "";
+ return false;
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudio10Generator::SelectWindowsCEToolset() const
+{
+ if (this->SystemVersion == "8.0")
+ {
+ return "CE800";
+ }
+ return "";
}
//----------------------------------------------------------------------------
@@ -116,24 +321,20 @@ void cmGlobalVisualStudio10Generator::WriteSLNHeader(std::ostream& fout)
}
///! Create a local generator appropriate to this Global Generator
-cmLocalGenerator *cmGlobalVisualStudio10Generator::CreateLocalGenerator()
+cmLocalGenerator* cmGlobalVisualStudio10Generator::CreateLocalGenerator(
+ cmMakefile* mf)
{
- cmLocalVisualStudio10Generator* lg =
- new cmLocalVisualStudio10Generator(cmLocalVisualStudioGenerator::VS10);
- lg->SetPlatformName(this->GetPlatformName());
- lg->SetGlobalGenerator(this);
- return lg;
+ return new cmLocalVisualStudio10Generator(this, mf);
}
-//----------------------------------------------------------------------------
void cmGlobalVisualStudio10Generator::Generate()
{
this->LongestSource = LongestSourcePath();
this->cmGlobalVisualStudio8Generator::Generate();
if(this->LongestSource.Length > 0)
{
- cmMakefile* mf = this->LongestSource.Target->GetMakefile();
- cmOStringStream e;
+ cmLocalGenerator* lg = this->LongestSource.Target->GetLocalGenerator();
+ std::ostringstream e;
e <<
"The binary and/or source directory paths may be too long to generate "
"Visual Studio 10 files for this project. "
@@ -147,13 +348,13 @@ void cmGlobalVisualStudio10Generator::Generate()
" " << this->LongestSource.SourceFile->GetFullPath() << "\n"
"This is because some Visual Studio tools would append the relative "
"path to the end of the referencing directory path, as in:\n"
- " " << mf->GetCurrentOutputDirectory() << "/"
+ " " << lg->GetCurrentBinaryDirectory() << "/"
<< this->LongestSource.SourceRel << "\n"
"and then incorrectly complain that the file does not exist because "
"the path length is too long for some internal buffer or API. "
"To avoid this problem CMake must use a full path for this file "
"which then triggers the VS 10 property dialog bug.";
- mf->IssueMessage(cmake::WARNING, e.str().c_str());
+ lg->IssueMessage(cmake::WARNING, e.str().c_str());
}
}
@@ -162,179 +363,191 @@ void cmGlobalVisualStudio10Generator
::EnableLanguage(std::vector<std::string>const & lang,
cmMakefile *mf, bool optional)
{
- if(this->PlatformName == "Itanium" || this->PlatformName == "x64")
+ cmGlobalVisualStudio8Generator::EnableLanguage(lang, mf, optional);
+}
+
+//----------------------------------------------------------------------------
+const char* cmGlobalVisualStudio10Generator::GetPlatformToolset() const
+{
+ if(!this->GeneratorToolset.empty())
{
- if(this->IsExpressEdition() && !this->Find64BitTools(mf))
- {
- return;
- }
+ return this->GeneratorToolset.c_str();
}
-
- for(std::vector<std::string>::const_iterator it = lang.begin();
- it != lang.end(); ++it)
+ if(!this->DefaultPlatformToolset.empty())
{
- if(*it == "ASM_MASM")
- {
- this->MasmEnabled = true;
- }
+ return this->DefaultPlatformToolset.c_str();
}
+ return 0;
+}
- cmGlobalVisualStudio8Generator::EnableLanguage(lang, mf, optional);
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio10Generator::FindMakeProgram(cmMakefile* mf)
+{
+ this->cmGlobalVisualStudio8Generator::FindMakeProgram(mf);
+ mf->AddDefinition("CMAKE_VS_MSBUILD_COMMAND",
+ this->GetMSBuildCommand().c_str());
}
//----------------------------------------------------------------------------
-const char* cmGlobalVisualStudio10Generator::GetPlatformToolset()
+std::string const& cmGlobalVisualStudio10Generator::GetMSBuildCommand()
{
- if(!this->PlatformToolset.empty())
+ if(!this->MSBuildCommandInitialized)
{
- return this->PlatformToolset.c_str();
+ this->MSBuildCommandInitialized = true;
+ this->MSBuildCommand = this->FindMSBuildCommand();
}
- return 0;
+ return this->MSBuildCommand;
}
//----------------------------------------------------------------------------
-std::string cmGlobalVisualStudio10Generator::GetUserMacrosDirectory()
+std::string cmGlobalVisualStudio10Generator::FindMSBuildCommand()
{
- std::string base;
- std::string path;
-
- // base begins with the VisualStudioProjectsLocation reg value...
- if (cmSystemTools::ReadRegistryValue(
- "HKEY_CURRENT_USER\\Software\\Microsoft\\VisualStudio\\10.0;"
- "VisualStudioProjectsLocation",
- base))
+ std::string msbuild;
+ std::string mskey =
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\";
+ mskey += this->GetToolsVersion();
+ mskey += ";MSBuildToolsPath";
+ if(cmSystemTools::ReadRegistryValue(mskey.c_str(), msbuild,
+ cmSystemTools::KeyWOW64_32))
{
- cmSystemTools::ConvertToUnixSlashes(base);
-
- // 9.0 macros folder:
- path = base + "/VSMacros80";
- // *NOT* a typo; right now in Visual Studio 2008 beta the macros
- // folder is VSMacros80... They may change it to 90 before final
- // release of 2008 or they may not... we'll have to keep our eyes
- // on it
+ cmSystemTools::ConvertToUnixSlashes(msbuild);
+ msbuild += "/";
}
-
- // path is (correctly) still empty if we did not read the base value from
- // the Registry value
- return path;
+ msbuild += "MSBuild.exe";
+ return msbuild;
}
//----------------------------------------------------------------------------
-std::string cmGlobalVisualStudio10Generator::GetUserMacrosRegKeyBase()
+std::string cmGlobalVisualStudio10Generator::FindDevEnvCommand()
{
- return "Software\\Microsoft\\VisualStudio\\10.0\\vsmacros";
+ if(this->ExpressEdition)
+ {
+ // Visual Studio Express >= 10 do not have "devenv.com" or
+ // "VCExpress.exe" that we can use to build reliably.
+ // Tell the caller it needs to use MSBuild instead.
+ return "";
+ }
+ // Skip over the cmGlobalVisualStudio8Generator implementation because
+ // we expect a real devenv and do not want to look for VCExpress.
+ return this->cmGlobalVisualStudio71Generator::FindDevEnvCommand();
}
-
-std::string cmGlobalVisualStudio10Generator
-::GenerateBuildCommand(const char* makeProgram,
- const char *projectName, const char *projectDir,
- const char* additionalOptions, const char *targetName,
- const char* config, bool ignoreErrors, bool fast)
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio10Generator::GenerateBuildCommand(
+ std::vector<std::string>& makeCommand,
+ const std::string& makeProgram,
+ const std::string& projectName,
+ const std::string& projectDir,
+ const std::string& targetName,
+ const std::string& config,
+ bool fast, bool verbose,
+ std::vector<std::string> const& makeOptions)
{
- // now build the test
- std::string makeCommand
- = cmSystemTools::ConvertToOutputPath(makeProgram);
- std::string lowerCaseCommand = makeCommand;
- cmSystemTools::LowerCase(lowerCaseCommand);
+ // Select the caller- or user-preferred make program, else MSBuild.
+ std::string makeProgramSelected =
+ this->SelectMakeProgram(makeProgram, this->GetMSBuildCommand());
- // If makeProgram is devenv, parent class knows how to generate command:
- if (lowerCaseCommand.find("devenv") != std::string::npos ||
- lowerCaseCommand.find("VCExpress") != std::string::npos)
+ // Check if the caller explicitly requested a devenv tool.
+ std::string makeProgramLower = makeProgramSelected;
+ cmSystemTools::LowerCase(makeProgramLower);
+ bool useDevEnv =
+ (makeProgramLower.find("devenv") != std::string::npos ||
+ makeProgramLower.find("vcexpress") != std::string::npos);
+
+ // MSBuild is preferred (and required for VS Express), but if the .sln has
+ // an Intel Fortran .vfproj then we have to use devenv. Parse it to find out.
+ cmSlnData slnData;
+ {
+ std::string slnFile;
+ if(!projectDir.empty())
{
- return cmGlobalVisualStudio7Generator::GenerateBuildCommand(makeProgram,
- projectName, projectDir, additionalOptions, targetName, config,
- ignoreErrors, fast);
+ slnFile = projectDir;
+ slnFile += "/";
}
-
- // Otherwise, assume MSBuild command line, and construct accordingly.
-
- // if there are spaces in the makeCommand, assume a full path
- // and convert it to a path with no spaces in it as the
- // RunSingleCommand does not like spaces
- if(makeCommand.find(' ') != std::string::npos)
+ slnFile += projectName;
+ slnFile += ".sln";
+ cmVisualStudioSlnParser parser;
+ if(parser.ParseFile(slnFile, slnData,
+ cmVisualStudioSlnParser::DataGroupProjects))
+ {
+ std::vector<cmSlnProjectEntry> slnProjects = slnData.GetProjects();
+ for(std::vector<cmSlnProjectEntry>::iterator i = slnProjects.begin();
+ !useDevEnv && i != slnProjects.end(); ++i)
+ {
+ std::string proj = i->GetRelativePath();
+ if(proj.size() > 7 &&
+ proj.substr(proj.size()-7) == ".vfproj")
+ {
+ useDevEnv = true;
+ }
+ }
+ }
+ }
+ if(useDevEnv)
{
- cmSystemTools::GetShortPath(makeCommand.c_str(), makeCommand);
+ // Use devenv to build solutions containing Intel Fortran projects.
+ cmGlobalVisualStudio7Generator::GenerateBuildCommand(
+ makeCommand, makeProgram, projectName, projectDir,
+ targetName, config, fast, verbose, makeOptions);
+ return;
}
+
+ makeCommand.push_back(makeProgramSelected);
+
+ std::string realTarget = targetName;
// msbuild.exe CxxOnly.sln /t:Build /p:Configuration=Debug /target:ALL_BUILD
- if(!targetName || strlen(targetName) == 0)
+ if(realTarget.empty())
{
- targetName = "ALL_BUILD";
+ realTarget = "ALL_BUILD";
}
- bool clean = false;
- if ( targetName && strcmp(targetName, "clean") == 0 )
+ if ( realTarget == "clean" )
{
- clean = true;
- makeCommand += " ";
- makeCommand += projectName;
- makeCommand += ".sln ";
- makeCommand += "/t:Clean ";
+ makeCommand.push_back(std::string(projectName)+".sln");
+ makeCommand.push_back("/t:Clean");
}
else
{
- std::string targetProject(targetName);
+ std::string targetProject(realTarget);
targetProject += ".vcxproj";
if (targetProject.find('/') == std::string::npos)
{
// it might be in a subdir
- cmVisualStudioSlnParser parser;
- cmSlnData slnData;
- std::string slnFile;
- if (projectDir && *projectDir)
- {
- slnFile = projectDir;
- slnFile += '/';
- slnFile += projectName;
- }
- else
- {
- slnFile = projectName;
- }
- if (parser.ParseFile(slnFile + ".sln", slnData,
- cmVisualStudioSlnParser::DataGroupProjects))
+ if (cmSlnProjectEntry const* proj =
+ slnData.GetProjectByName(realTarget))
{
- if (cmSlnProjectEntry const* proj =
- slnData.GetProjectByName(targetName))
- {
- targetProject = proj->GetRelativePath();
- cmSystemTools::ConvertToUnixSlashes(targetProject);
- }
+ targetProject = proj->GetRelativePath();
+ cmSystemTools::ConvertToUnixSlashes(targetProject);
}
}
- makeCommand += " ";
- makeCommand += targetProject;
- makeCommand += " ";
+ makeCommand.push_back(targetProject);
}
- makeCommand += "/p:Configuration=";
- if(config && strlen(config))
+ std::string configArg = "/p:Configuration=";
+ if(!config.empty())
{
- makeCommand += config;
+ configArg += config;
}
else
{
- makeCommand += "Debug";
- }
- makeCommand += " /p:VisualStudioVersion=";
- makeCommand += this->GetIDEVersion();
- if ( additionalOptions )
- {
- makeCommand += " ";
- makeCommand += additionalOptions;
+ configArg += "Debug";
}
- return makeCommand;
+ makeCommand.push_back(configArg);
+ makeCommand.push_back(std::string("/p:VisualStudioVersion=")+
+ this->GetIDEVersion());
+ makeCommand.insert(makeCommand.end(),
+ makeOptions.begin(), makeOptions.end());
}
//----------------------------------------------------------------------------
bool cmGlobalVisualStudio10Generator::Find64BitTools(cmMakefile* mf)
{
- if(!this->PlatformToolset.empty())
+ if(this->GetPlatformToolset())
{
return true;
}
// This edition does not come with 64-bit tools. Look for them.
//
// TODO: Detect available tools? x64\v100 exists but does not work?
- // KHLM\\SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\4.0;VCTargetsPath
+ // HKLM\\SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\4.0;VCTargetsPath
// c:/Program Files (x86)/MSBuild/Microsoft.Cpp/v4.0/Platforms/
// {Itanium,Win32,x64}/PlatformToolsets/{v100,v90,Windows7.1SDK}
std::string winSDK_7_1;
@@ -342,15 +555,15 @@ bool cmGlobalVisualStudio10Generator::Find64BitTools(cmMakefile* mf)
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\"
"Windows\\v7.1;InstallationFolder", winSDK_7_1))
{
- cmOStringStream m;
+ std::ostringstream m;
m << "Found Windows SDK v7.1: " << winSDK_7_1;
mf->DisplayStatus(m.str().c_str(), -1);
- this->PlatformToolset = "Windows7.1SDK";
+ this->DefaultPlatformToolset = "Windows7.1SDK";
return true;
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Cannot enable 64-bit tools with Visual Studio 2010 Express.\n"
<< "Install the Microsoft Windows SDK v7.1 to get 64-bit tools:\n"
<< " http://msdn.microsoft.com/en-us/windows/bb980924.aspx";
@@ -380,9 +593,11 @@ cmGlobalVisualStudio10Generator
//----------------------------------------------------------------------------
void cmGlobalVisualStudio10Generator::PathTooLong(
- cmTarget* target, cmSourceFile* sf, std::string const& sfRel)
+ cmGeneratorTarget *target, cmSourceFile const* sf,
+ std::string const& sfRel)
{
- size_t len = (strlen(target->GetMakefile()->GetCurrentOutputDirectory()) +
+ size_t len =
+ (strlen(target->GetLocalGenerator()->GetCurrentBinaryDirectory()) +
1 + sfRel.length());
if(len > this->LongestSource.Length)
{
@@ -398,3 +613,25 @@ bool cmGlobalVisualStudio10Generator::UseFolderProperty()
{
return IsExpressEdition() ? false : cmGlobalGenerator::UseFolderProperty();
}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio10Generator::IsNsightTegra() const
+{
+ return !this->NsightTegraVersion.empty();
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudio10Generator::GetNsightTegraVersion() const
+{
+ return this->NsightTegraVersion;
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudio10Generator::GetInstalledNsightTegraVersion()
+{
+ std::string version;
+ cmSystemTools::ReadRegistryValue(
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\NVIDIA Corporation\\Nsight Tegra;"
+ "Version", version, cmSystemTools::KeyWOW64_32);
+ return version;
+}
diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h
index 31e122efe..6bf47409d 100644
--- a/Source/cmGlobalVisualStudio10Generator.h
+++ b/Source/cmGlobalVisualStudio10Generator.h
@@ -24,27 +24,32 @@ class cmGlobalVisualStudio10Generator :
public cmGlobalVisualStudio8Generator
{
public:
- cmGlobalVisualStudio10Generator(const char* name,
- const char* platformName, const char* additionalPlatformDefinition);
+ cmGlobalVisualStudio10Generator(cmake* cm, const std::string& name,
+ const std::string& platformName);
static cmGlobalGeneratorFactory* NewFactory();
- virtual bool SetGeneratorToolset(std::string const& ts);
+ virtual bool MatchesGeneratorName(const std::string& name) const;
- virtual std::string
- GenerateBuildCommand(const char* makeProgram,
- const char *projectName, const char *projectDir,
- const char* additionalOptions, const char *targetName,
- const char* config, bool ignoreErrors, bool);
+ virtual bool SetSystemName(std::string const& s, cmMakefile* mf);
+ virtual bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf);
+ virtual bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf);
- virtual void AddPlatformDefinitions(cmMakefile* mf);
+ virtual void GenerateBuildCommand(
+ std::vector<std::string>& makeCommand,
+ const std::string& makeProgram,
+ const std::string& projectName,
+ const std::string& projectDir,
+ const std::string& targetName,
+ const std::string& config,
+ bool fast, bool verbose,
+ std::vector<std::string> const& makeOptions = std::vector<std::string>()
+ );
///! create the correct local generator
- virtual cmLocalGenerator *CreateLocalGenerator();
-
- virtual void Generate();
+ virtual cmLocalGenerator *CreateLocalGenerator(cmMakefile* mf);
/**
- * Try to determine system infomation such as shared library
+ * Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
@@ -54,24 +59,35 @@ public:
/** Is the installed VS an Express edition? */
bool IsExpressEdition() const { return this->ExpressEdition; }
- /** Is the Microsoft Assembler enabled? */
- bool IsMasmEnabled() const { return this->MasmEnabled; }
+ /** Generating for Nsight Tegra VS plugin? */
+ bool IsNsightTegra() const;
+ std::string GetNsightTegraVersion() const;
/** The toolset name for the target platform. */
- const char* GetPlatformToolset();
+ const char* GetPlatformToolset() const;
- /**
- * Where does this version of Visual Studio look for macros for the
- * current user? Returns the empty string if this version of Visual
- * Studio does not implement support for VB macros.
- */
- virtual std::string GetUserMacrosDirectory();
+ /** Return the CMAKE_SYSTEM_NAME. */
+ std::string const& GetSystemName() const { return this->SystemName; }
+
+ /** Return the CMAKE_SYSTEM_VERSION. */
+ std::string const& GetSystemVersion() const { return this->SystemVersion; }
+
+ /** Return the Windows version targeted on VS 2015 and above. */
+ std::string const& GetWindowsTargetPlatformVersion() const
+ { return this->WindowsTargetPlatformVersion; }
+
+ /** Return true if building for WindowsCE */
+ bool TargetsWindowsCE() const
+ { return this->SystemIsWindowsCE; }
+
+ /** Return true if building for WindowsPhone */
+ bool TargetsWindowsPhone() const
+ { return this->SystemIsWindowsPhone; }
+
+ /** Return true if building for WindowsStore */
+ bool TargetsWindowsStore() const
+ { return this->SystemIsWindowsStore; }
- /**
- * What is the reg key path to "vsmacros" for this version of Visual
- * Studio?
- */
- virtual std::string GetUserMacrosRegKeyBase();
virtual const char* GetCMakeCFGIntDir() const
{ return "$(Configuration)";}
bool Find64BitTools(cmMakefile* mf);
@@ -79,17 +95,41 @@ public:
/** Generate an <output>.rule file path for a given command output. */
virtual std::string GenerateRuleFile(std::string const& output) const;
- void PathTooLong(cmTarget* target, cmSourceFile* sf,
+ void PathTooLong(cmGeneratorTarget* target, cmSourceFile const* sf,
std::string const& sfRel);
virtual const char* GetToolsVersion() { return "4.0"; }
+ virtual void FindMakeProgram(cmMakefile*);
+
+ static std::string GetInstalledNsightTegraVersion();
+
protected:
+ virtual void Generate();
+ virtual bool InitializeSystem(cmMakefile* mf);
+ virtual bool InitializeWindows(cmMakefile* mf);
+ virtual bool InitializeWindowsCE(cmMakefile* mf);
+ virtual bool InitializeWindowsPhone(cmMakefile* mf);
+ virtual bool InitializeWindowsStore(cmMakefile* mf);
+
+ virtual std::string SelectWindowsCEToolset() const;
+ virtual bool SelectWindowsPhoneToolset(std::string& toolset) const;
+ virtual bool SelectWindowsStoreToolset(std::string& toolset) const;
+
virtual const char* GetIDEVersion() { return "10.0"; }
- std::string PlatformToolset;
+ std::string const& GetMSBuildCommand();
+
+ std::string GeneratorToolset;
+ std::string DefaultPlatformToolset;
+ std::string WindowsTargetPlatformVersion;
+ std::string SystemName;
+ std::string SystemVersion;
+ std::string NsightTegraVersion;
+ bool SystemIsWindowsCE;
+ bool SystemIsWindowsPhone;
+ bool SystemIsWindowsStore;
bool ExpressEdition;
- bool MasmEnabled;
bool UseFolderProperty();
@@ -99,10 +139,19 @@ private:
{
LongestSourcePath(): Length(0), Target(0), SourceFile(0) {}
size_t Length;
- cmTarget* Target;
- cmSourceFile* SourceFile;
+ cmGeneratorTarget* Target;
+ cmSourceFile const* SourceFile;
std::string SourceRel;
};
LongestSourcePath LongestSource;
+
+ std::string MSBuildCommand;
+ bool MSBuildCommandInitialized;
+ virtual std::string FindMSBuildCommand();
+ virtual std::string FindDevEnvCommand();
+ virtual std::string GetVSMakeProgram() { return this->GetMSBuildCommand(); }
+
+ // We do not use the reload macros for VS >= 10.
+ virtual std::string GetUserMacrosDirectory() { return ""; }
};
#endif
diff --git a/Source/cmGlobalVisualStudio11Generator.cxx b/Source/cmGlobalVisualStudio11Generator.cxx
index 8ae733165..9522f6ee9 100644
--- a/Source/cmGlobalVisualStudio11Generator.cxx
+++ b/Source/cmGlobalVisualStudio11Generator.cxx
@@ -12,43 +12,51 @@
#include "cmGlobalVisualStudio11Generator.h"
#include "cmLocalVisualStudio10Generator.h"
#include "cmMakefile.h"
+#include "cmAlgorithms.h"
-static const char vs11generatorName[] = "Visual Studio 11";
+static const char vs11generatorName[] = "Visual Studio 11 2012";
+
+// Map generator name without year to name with year.
+static const char* cmVS11GenName(const std::string& name, std::string& genName)
+{
+ if(strncmp(name.c_str(), vs11generatorName,
+ sizeof(vs11generatorName)-6) != 0)
+ {
+ return 0;
+ }
+ const char* p = name.c_str() + sizeof(vs11generatorName) - 6;
+ if(cmHasLiteralPrefix(p, " 2012"))
+ {
+ p += 5;
+ }
+ genName = std::string(vs11generatorName) + p;
+ return p;
+}
class cmGlobalVisualStudio11Generator::Factory
: public cmGlobalGeneratorFactory
{
public:
- virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const {
- if(strstr(name, vs11generatorName) != name)
- {
- return 0;
- }
-
- const char* p = name + sizeof(vs11generatorName) - 1;
- if(p[0] == '\0')
- {
- return new cmGlobalVisualStudio11Generator(
- name, NULL, NULL);
- }
-
- if(p[0] != ' ')
+ virtual cmGlobalGenerator*
+ CreateGlobalGenerator(const std::string& name, cmake* cm) const
+ {
+ std::string genName;
+ const char* p = cmVS11GenName(name, genName);
+ if(!p)
+ { return 0; }
+ if(!*p)
{
- return 0;
+ return new cmGlobalVisualStudio11Generator(cm, genName, "");
}
-
- ++p;
-
- if(!strcmp(p, "ARM"))
+ if(*p++ != ' ')
+ { return 0; }
+ if(strcmp(p, "Win64") == 0)
{
- return new cmGlobalVisualStudio11Generator(
- name, "ARM", NULL);
+ return new cmGlobalVisualStudio11Generator(cm, genName, "x64");
}
-
- if(!strcmp(p, "Win64"))
+ if(strcmp(p, "ARM") == 0)
{
- return new cmGlobalVisualStudio11Generator(
- name, "x64", "CMAKE_FORCE_WIN64");
+ return new cmGlobalVisualStudio11Generator(cm, genName, "ARM");
}
std::set<std::string> installedSDKs =
@@ -60,22 +68,22 @@ public:
}
cmGlobalVisualStudio11Generator* ret =
- new cmGlobalVisualStudio11Generator(name, p, NULL);
+ new cmGlobalVisualStudio11Generator(cm, name, p);
ret->WindowsCEVersion = "8.00";
return ret;
- }
-
- virtual void GetDocumentation(cmDocumentationEntry& entry) const {
- entry.Name = "Visual Studio 11";
- entry.Brief = "Generates Visual Studio 11 (2012) project files.";
- entry.Full =
- "It is possible to append a space followed by the platform name "
- "to create project files for a specific target platform. E.g. "
- "\"Visual Studio 11 Win64\" will create project files for "
- "the x64 processor; \"Visual Studio 11 ARM\" for ARM.";
- }
-
- virtual void GetGenerators(std::vector<std::string>& names) const {
+ }
+
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const
+ {
+ entry.Name = std::string(vs11generatorName) + " [arch]";
+ entry.Brief =
+ "Generates Visual Studio 2012 project files. "
+ "Optional [arch] can be \"Win64\" or \"ARM\"."
+ ;
+ }
+
+ virtual void GetGenerators(std::vector<std::string>& names) const
+ {
names.push_back(vs11generatorName);
names.push_back(vs11generatorName + std::string(" ARM"));
names.push_back(vs11generatorName + std::string(" Win64"));
@@ -85,9 +93,11 @@ public:
for(std::set<std::string>::const_iterator i =
installedSDKs.begin(); i != installedSDKs.end(); ++i)
{
- names.push_back("Visual Studio 11 " + *i);
+ names.push_back(std::string(vs11generatorName) + " " + *i);
}
- }
+ }
+
+ virtual bool SupportsToolset() const { return true; }
};
//----------------------------------------------------------------------------
@@ -97,18 +107,119 @@ cmGlobalGeneratorFactory* cmGlobalVisualStudio11Generator::NewFactory()
}
//----------------------------------------------------------------------------
-cmGlobalVisualStudio11Generator::cmGlobalVisualStudio11Generator(
- const char* name, const char* platformName,
- const char* additionalPlatformDefinition)
- : cmGlobalVisualStudio10Generator(name, platformName,
- additionalPlatformDefinition)
+cmGlobalVisualStudio11Generator::cmGlobalVisualStudio11Generator(cmake* cm,
+ const std::string& name, const std::string& platformName)
+ : cmGlobalVisualStudio10Generator(cm, name, platformName)
{
- this->FindMakeProgramFile = "CMakeVS11FindMake.cmake";
std::string vc11Express;
this->ExpressEdition = cmSystemTools::ReadRegistryValue(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\11.0\\Setup\\VC;"
"ProductDir", vc11Express, cmSystemTools::KeyWOW64_32);
- this->PlatformToolset = "v110";
+ this->DefaultPlatformToolset = "v110";
+ this->Version = VS11;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio11Generator::MatchesGeneratorName(
+ const std::string& name) const
+{
+ std::string genName;
+ if(cmVS11GenName(name, genName))
+ {
+ return genName == this->GetName();
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio11Generator::InitializeWindowsPhone(cmMakefile* mf)
+{
+ if(!this->SelectWindowsPhoneToolset(this->DefaultPlatformToolset))
+ {
+ std::ostringstream e;
+ if(this->DefaultPlatformToolset.empty())
+ {
+ e << this->GetName() << " supports Windows Phone '8.0', but not '"
+ << this->SystemVersion << "'. Check CMAKE_SYSTEM_VERSION.";
+ }
+ else
+ {
+ e << "A Windows Phone component with CMake requires both the Windows "
+ << "Desktop SDK as well as the Windows Phone '" << this->SystemVersion
+ << "' SDK. Please make sure that you have both installed";
+ }
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio11Generator::InitializeWindowsStore(cmMakefile* mf)
+{
+ if(!this->SelectWindowsStoreToolset(this->DefaultPlatformToolset))
+ {
+ std::ostringstream e;
+ if(this->DefaultPlatformToolset.empty())
+ {
+ e << this->GetName() << " supports Windows Store '8.0', but not '"
+ << this->SystemVersion << "'. Check CMAKE_SYSTEM_VERSION.";
+ }
+ else
+ {
+ e << "A Windows Store component with CMake requires both the Windows "
+ << "Desktop SDK as well as the Windows Store '" << this->SystemVersion
+ << "' SDK. Please make sure that you have both installed";
+ }
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio11Generator::SelectWindowsPhoneToolset(
+ std::string& toolset) const
+{
+ if(this->SystemVersion == "8.0")
+ {
+ if (this->IsWindowsPhoneToolsetInstalled() &&
+ this->IsWindowsDesktopToolsetInstalled())
+ {
+ toolset = "v110_wp80";
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ return
+ this->cmGlobalVisualStudio10Generator::SelectWindowsPhoneToolset(toolset);
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio11Generator::SelectWindowsStoreToolset(
+ std::string& toolset) const
+{
+ if(this->SystemVersion == "8.0")
+ {
+ if(this->IsWindowsStoreToolsetInstalled() &&
+ this->IsWindowsDesktopToolsetInstalled())
+ {
+ toolset = "v110";
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ return
+ this->cmGlobalVisualStudio10Generator::SelectWindowsStoreToolset(toolset);
}
//----------------------------------------------------------------------------
@@ -126,16 +237,6 @@ void cmGlobalVisualStudio11Generator::WriteSLNHeader(std::ostream& fout)
}
//----------------------------------------------------------------------------
-cmLocalGenerator *cmGlobalVisualStudio11Generator::CreateLocalGenerator()
-{
- cmLocalVisualStudio10Generator* lg =
- new cmLocalVisualStudio10Generator(cmLocalVisualStudioGenerator::VS11);
- lg->SetPlatformName(this->GetPlatformName());
- lg->SetGlobalGenerator(this);
- return lg;
-}
-
-//----------------------------------------------------------------------------
bool cmGlobalVisualStudio11Generator::UseFolderProperty()
{
// Intentionally skip over the parent class implementation and call the
@@ -176,3 +277,68 @@ cmGlobalVisualStudio11Generator::GetInstalledWindowsCESDKs()
return ret;
}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio11Generator::NeedsDeploy(cmState::TargetType type) const
+{
+ if((type == cmState::EXECUTABLE ||
+ type == cmState::SHARED_LIBRARY) &&
+ (this->SystemIsWindowsPhone ||
+ this->SystemIsWindowsStore))
+ {
+ return true;
+ }
+ return cmGlobalVisualStudio10Generator::NeedsDeploy(type);
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio11Generator::IsWindowsDesktopToolsetInstalled() const
+{
+ const char desktop80Key[] =
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
+ "VisualStudio\\11.0\\VC\\Libraries\\Extended";
+ const char VS2012DesktopExpressKey[] =
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
+ "WDExpress\\11.0;InstallDir";
+
+ std::vector<std::string> subkeys;
+ std::string path;
+ return cmSystemTools::ReadRegistryValue(VS2012DesktopExpressKey,
+ path,
+ cmSystemTools::KeyWOW64_32) ||
+ cmSystemTools::GetRegistrySubKeys(desktop80Key,
+ subkeys,
+ cmSystemTools::KeyWOW64_32);
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio11Generator::IsWindowsPhoneToolsetInstalled() const
+{
+ const char wp80Key[] =
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
+ "Microsoft SDKs\\WindowsPhone\\v8.0\\"
+ "Install Path;Install Path";
+
+ std::string path;
+ cmSystemTools::ReadRegistryValue(wp80Key,
+ path,
+ cmSystemTools::KeyWOW64_32);
+ return !path.empty();
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio11Generator::IsWindowsStoreToolsetInstalled() const
+{
+ const char win80Key[] =
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
+ "VisualStudio\\11.0\\VC\\Libraries\\Core\\Arm";
+
+ std::vector<std::string> subkeys;
+ return cmSystemTools::GetRegistrySubKeys(win80Key,
+ subkeys,
+ cmSystemTools::KeyWOW64_32);
+}
diff --git a/Source/cmGlobalVisualStudio11Generator.h b/Source/cmGlobalVisualStudio11Generator.h
index 7cc7e69d9..f3f6b2bae 100644
--- a/Source/cmGlobalVisualStudio11Generator.h
+++ b/Source/cmGlobalVisualStudio11Generator.h
@@ -20,21 +20,35 @@ class cmGlobalVisualStudio11Generator:
public cmGlobalVisualStudio10Generator
{
public:
- cmGlobalVisualStudio11Generator(const char* name,
- const char* platformName, const char* additionalPlatformDefinition);
+ cmGlobalVisualStudio11Generator(cmake* cm, const std::string& name,
+ const std::string& platformName);
static cmGlobalGeneratorFactory* NewFactory();
- virtual void WriteSLNHeader(std::ostream& fout);
+ virtual bool MatchesGeneratorName(const std::string& name) const;
- ///! create the correct local generator
- virtual cmLocalGenerator *CreateLocalGenerator();
+ virtual void WriteSLNHeader(std::ostream& fout);
- /** TODO: VS 11 user macro support. */
- virtual std::string GetUserMacrosDirectory() { return ""; }
protected:
+ virtual bool InitializeWindowsPhone(cmMakefile* mf);
+ virtual bool InitializeWindowsStore(cmMakefile* mf);
+ virtual bool SelectWindowsPhoneToolset(std::string& toolset) const;
+ virtual bool SelectWindowsStoreToolset(std::string& toolset) const;
+
+ // Used to verify that the Desktop toolset for the current generator is
+ // installed on the machine.
+ virtual bool IsWindowsDesktopToolsetInstalled() const;
+
+ // These aren't virtual because we need to check if the selected version
+ // of the toolset is installed
+ bool IsWindowsPhoneToolsetInstalled() const;
+ bool IsWindowsStoreToolsetInstalled() const;
+
virtual const char* GetIDEVersion() { return "11.0"; }
bool UseFolderProperty();
static std::set<std::string> GetInstalledWindowsCESDKs();
+
+ /** Return true if the configuration needs to be deployed */
+ virtual bool NeedsDeploy(cmState::TargetType type) const;
private:
class Factory;
friend class Factory;
diff --git a/Source/cmGlobalVisualStudio12Generator.cxx b/Source/cmGlobalVisualStudio12Generator.cxx
index c56dfff15..568d4d7ff 100644
--- a/Source/cmGlobalVisualStudio12Generator.cxx
+++ b/Source/cmGlobalVisualStudio12Generator.cxx
@@ -12,48 +12,72 @@
#include "cmGlobalVisualStudio12Generator.h"
#include "cmLocalVisualStudio10Generator.h"
#include "cmMakefile.h"
+#include "cmAlgorithms.h"
-static const char vs12Win32generatorName[] = "Visual Studio 12";
-static const char vs12Win64generatorName[] = "Visual Studio 12 Win64";
-static const char vs12ARMgeneratorName[] = "Visual Studio 12 ARM";
+static const char vs12generatorName[] = "Visual Studio 12 2013";
+
+// Map generator name without year to name with year.
+static const char* cmVS12GenName(const std::string& name, std::string& genName)
+{
+ if(strncmp(name.c_str(), vs12generatorName,
+ sizeof(vs12generatorName)-6) != 0)
+ {
+ return 0;
+ }
+ const char* p = name.c_str() + sizeof(vs12generatorName) - 6;
+ if(cmHasLiteralPrefix(p, " 2013"))
+ {
+ p += 5;
+ }
+ genName = std::string(vs12generatorName) + p;
+ return p;
+}
class cmGlobalVisualStudio12Generator::Factory
: public cmGlobalGeneratorFactory
{
public:
- virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const {
- if(!strcmp(name, vs12Win32generatorName))
+ virtual cmGlobalGenerator*
+ CreateGlobalGenerator(const std::string& name, cmake* cm) const
+ {
+ std::string genName;
+ const char* p = cmVS12GenName(name, genName);
+ if(!p)
+ { return 0; }
+ if(!*p)
{
- return new cmGlobalVisualStudio12Generator(
- name, NULL, NULL);
+ return new cmGlobalVisualStudio12Generator(cm, genName, "");
}
- if(!strcmp(name, vs12Win64generatorName))
+ if(*p++ != ' ')
+ { return 0; }
+ if(strcmp(p, "Win64") == 0)
{
- return new cmGlobalVisualStudio12Generator(
- name, "x64", "CMAKE_FORCE_WIN64");
+ return new cmGlobalVisualStudio12Generator(cm, genName, "x64");
}
- if(!strcmp(name, vs12ARMgeneratorName))
+ if(strcmp(p, "ARM") == 0)
{
- return new cmGlobalVisualStudio12Generator(
- name, "ARM", NULL);
+ return new cmGlobalVisualStudio12Generator(cm, genName, "ARM");
}
return 0;
- }
-
- virtual void GetDocumentation(cmDocumentationEntry& entry) const {
- entry.Name = "Visual Studio 12";
- entry.Brief = "Generates Visual Studio 12 (2013) project files.";
- entry.Full =
- "It is possible to append a space followed by the platform name "
- "to create project files for a specific target platform. E.g. "
- "\"Visual Studio 12 Win64\" will create project files for "
- "the x64 processor; \"Visual Studio 12 ARM\" for ARM.";
- }
-
- virtual void GetGenerators(std::vector<std::string>& names) const {
- names.push_back(vs12Win32generatorName);
- names.push_back(vs12Win64generatorName);
- names.push_back(vs12ARMgeneratorName); }
+ }
+
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const
+ {
+ entry.Name = std::string(vs12generatorName) + " [arch]";
+ entry.Brief =
+ "Generates Visual Studio 2013 project files. "
+ "Optional [arch] can be \"Win64\" or \"ARM\"."
+ ;
+ }
+
+ virtual void GetGenerators(std::vector<std::string>& names) const
+ {
+ names.push_back(vs12generatorName);
+ names.push_back(vs12generatorName + std::string(" ARM"));
+ names.push_back(vs12generatorName + std::string(" Win64"));
+ }
+
+ virtual bool SupportsToolset() const { return true; }
};
//----------------------------------------------------------------------------
@@ -63,18 +87,119 @@ cmGlobalGeneratorFactory* cmGlobalVisualStudio12Generator::NewFactory()
}
//----------------------------------------------------------------------------
-cmGlobalVisualStudio12Generator::cmGlobalVisualStudio12Generator(
- const char* name, const char* platformName,
- const char* additionalPlatformDefinition)
- : cmGlobalVisualStudio11Generator(name, platformName,
- additionalPlatformDefinition)
+cmGlobalVisualStudio12Generator::cmGlobalVisualStudio12Generator(cmake* cm,
+ const std::string& name, const std::string& platformName)
+ : cmGlobalVisualStudio11Generator(cm, name, platformName)
{
- this->FindMakeProgramFile = "CMakeVS12FindMake.cmake";
std::string vc12Express;
this->ExpressEdition = cmSystemTools::ReadRegistryValue(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\12.0\\Setup\\VC;"
"ProductDir", vc12Express, cmSystemTools::KeyWOW64_32);
- this->PlatformToolset = "v120";
+ this->DefaultPlatformToolset = "v120";
+ this->Version = VS12;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio12Generator::MatchesGeneratorName(
+ const std::string& name) const
+{
+ std::string genName;
+ if(cmVS12GenName(name, genName))
+ {
+ return genName == this->GetName();
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio12Generator::InitializeWindowsPhone(cmMakefile* mf)
+{
+ if(!this->SelectWindowsPhoneToolset(this->DefaultPlatformToolset))
+ {
+ std::ostringstream e;
+ if(this->DefaultPlatformToolset.empty())
+ {
+ e << this->GetName() << " supports Windows Phone '8.0' and '8.1', but "
+ "not '" << this->SystemVersion << "'. Check CMAKE_SYSTEM_VERSION.";
+ }
+ else
+ {
+ e << "A Windows Phone component with CMake requires both the Windows "
+ << "Desktop SDK as well as the Windows Phone '" << this->SystemVersion
+ << "' SDK. Please make sure that you have both installed";
+ }
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio12Generator::InitializeWindowsStore(cmMakefile* mf)
+{
+ if(!this->SelectWindowsStoreToolset(this->DefaultPlatformToolset))
+ {
+ std::ostringstream e;
+ if(this->DefaultPlatformToolset.empty())
+ {
+ e << this->GetName() << " supports Windows Store '8.0' and '8.1', but "
+ "not '" << this->SystemVersion << "'. Check CMAKE_SYSTEM_VERSION.";
+ }
+ else
+ {
+ e << "A Windows Store component with CMake requires both the Windows "
+ << "Desktop SDK as well as the Windows Store '" << this->SystemVersion
+ << "' SDK. Please make sure that you have both installed";
+ }
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio12Generator::SelectWindowsPhoneToolset(
+ std::string& toolset) const
+{
+ if(this->SystemVersion == "8.1")
+ {
+ if (this->IsWindowsPhoneToolsetInstalled() &&
+ this->IsWindowsDesktopToolsetInstalled())
+ {
+ toolset = "v120_wp81";
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ return
+ this->cmGlobalVisualStudio11Generator::SelectWindowsPhoneToolset(toolset);
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio12Generator::SelectWindowsStoreToolset(
+ std::string& toolset) const
+{
+ if(this->SystemVersion == "8.1")
+ {
+ if(this->IsWindowsStoreToolsetInstalled() &&
+ this->IsWindowsDesktopToolsetInstalled())
+ {
+ toolset = "v120";
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ return
+ this->cmGlobalVisualStudio11Generator::SelectWindowsStoreToolset(toolset);
}
//----------------------------------------------------------------------------
@@ -92,11 +217,44 @@ void cmGlobalVisualStudio12Generator::WriteSLNHeader(std::ostream& fout)
}
//----------------------------------------------------------------------------
-cmLocalGenerator *cmGlobalVisualStudio12Generator::CreateLocalGenerator()
+bool
+cmGlobalVisualStudio12Generator::IsWindowsDesktopToolsetInstalled() const
+{
+ const char desktop81Key[] =
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
+ "VisualStudio\\12.0\\VC\\LibraryDesktop";
+
+ std::vector<std::string> subkeys;
+ return cmSystemTools::GetRegistrySubKeys(desktop81Key,
+ subkeys,
+ cmSystemTools::KeyWOW64_32);
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio12Generator::IsWindowsPhoneToolsetInstalled() const
{
- cmLocalVisualStudio10Generator* lg =
- new cmLocalVisualStudio10Generator(cmLocalVisualStudioGenerator::VS12);
- lg->SetPlatformName(this->GetPlatformName());
- lg->SetGlobalGenerator(this);
- return lg;
+ const char wp81Key[] =
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
+ "Microsoft SDKs\\WindowsPhone\\v8.1\\Install Path;Install Path";
+
+ std::string path;
+ cmSystemTools::ReadRegistryValue(wp81Key,
+ path,
+ cmSystemTools::KeyWOW64_32);
+ return !path.empty();
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio12Generator::IsWindowsStoreToolsetInstalled() const
+{
+ const char win81Key[] =
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
+ "VisualStudio\\12.0\\VC\\Libraries\\Core\\Arm";
+
+ std::vector<std::string> subkeys;
+ return cmSystemTools::GetRegistrySubKeys(win81Key,
+ subkeys,
+ cmSystemTools::KeyWOW64_32);
}
diff --git a/Source/cmGlobalVisualStudio12Generator.h b/Source/cmGlobalVisualStudio12Generator.h
index 8c8aeb1fd..a7939aab6 100644
--- a/Source/cmGlobalVisualStudio12Generator.h
+++ b/Source/cmGlobalVisualStudio12Generator.h
@@ -20,23 +20,32 @@ class cmGlobalVisualStudio12Generator:
public cmGlobalVisualStudio11Generator
{
public:
- cmGlobalVisualStudio12Generator(const char* name,
- const char* platformName, const char* additionalPlatformDefinition);
+ cmGlobalVisualStudio12Generator(cmake* cm, const std::string& name,
+ const std::string& platformName);
static cmGlobalGeneratorFactory* NewFactory();
- virtual void WriteSLNHeader(std::ostream& fout);
-
- ///! create the correct local generator
- virtual cmLocalGenerator *CreateLocalGenerator();
+ virtual bool MatchesGeneratorName(const std::string& name) const;
- /** TODO: VS 12 user macro support. */
- virtual std::string GetUserMacrosDirectory() { return ""; }
+ virtual void WriteSLNHeader(std::ostream& fout);
//in Visual Studio 2013 they detached the MSBuild tools version
//from the .Net Framework version and instead made it have it's own
//version number
virtual const char* GetToolsVersion() { return "12.0"; }
protected:
+ virtual bool InitializeWindowsPhone(cmMakefile* mf);
+ virtual bool InitializeWindowsStore(cmMakefile* mf);
+ virtual bool SelectWindowsPhoneToolset(std::string& toolset) const;
+ virtual bool SelectWindowsStoreToolset(std::string& toolset) const;
+
+ // Used to verify that the Desktop toolset for the current generator is
+ // installed on the machine.
+ virtual bool IsWindowsDesktopToolsetInstalled() const;
+
+ // These aren't virtual because we need to check if the selected version
+ // of the toolset is installed
+ bool IsWindowsPhoneToolsetInstalled() const;
+ bool IsWindowsStoreToolsetInstalled() const;
virtual const char* GetIDEVersion() { return "12.0"; }
private:
class Factory;
diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx
new file mode 100644
index 000000000..c058f8ce4
--- /dev/null
+++ b/Source/cmGlobalVisualStudio14Generator.cxx
@@ -0,0 +1,302 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2014 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmGlobalVisualStudio14Generator.h"
+#include "cmLocalVisualStudio10Generator.h"
+#include "cmMakefile.h"
+#include "cmAlgorithms.h"
+
+static const char vs14generatorName[] = "Visual Studio 14 2015";
+
+// Map generator name without year to name with year.
+static const char* cmVS14GenName(const std::string& name, std::string& genName)
+{
+ if(strncmp(name.c_str(), vs14generatorName,
+ sizeof(vs14generatorName)-6) != 0)
+ {
+ return 0;
+ }
+ const char* p = name.c_str() + sizeof(vs14generatorName) - 6;
+ if(cmHasLiteralPrefix(p, " 2015"))
+ {
+ p += 5;
+ }
+ genName = std::string(vs14generatorName) + p;
+ return p;
+}
+
+class cmGlobalVisualStudio14Generator::Factory
+ : public cmGlobalGeneratorFactory
+{
+public:
+ virtual cmGlobalGenerator*
+ CreateGlobalGenerator(const std::string& name, cmake* cm) const
+ {
+ std::string genName;
+ const char* p = cmVS14GenName(name, genName);
+ if(!p)
+ { return 0; }
+ if(!*p)
+ {
+ return new cmGlobalVisualStudio14Generator(cm, genName, "");
+ }
+ if(*p++ != ' ')
+ { return 0; }
+ if(strcmp(p, "Win64") == 0)
+ {
+ return new cmGlobalVisualStudio14Generator(cm, genName, "x64");
+ }
+ if(strcmp(p, "ARM") == 0)
+ {
+ return new cmGlobalVisualStudio14Generator(cm, genName, "ARM");
+ }
+ return 0;
+ }
+
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const
+ {
+ entry.Name = std::string(vs14generatorName) + " [arch]";
+ entry.Brief =
+ "Generates Visual Studio 2015 project files. "
+ "Optional [arch] can be \"Win64\" or \"ARM\"."
+ ;
+ }
+
+ virtual void GetGenerators(std::vector<std::string>& names) const
+ {
+ names.push_back(vs14generatorName);
+ names.push_back(vs14generatorName + std::string(" ARM"));
+ names.push_back(vs14generatorName + std::string(" Win64"));
+ }
+
+ virtual bool SupportsToolset() const { return true; }
+};
+
+//----------------------------------------------------------------------------
+cmGlobalGeneratorFactory* cmGlobalVisualStudio14Generator::NewFactory()
+{
+ return new Factory;
+}
+
+//----------------------------------------------------------------------------
+cmGlobalVisualStudio14Generator::cmGlobalVisualStudio14Generator(cmake* cm,
+ const std::string& name, const std::string& platformName)
+ : cmGlobalVisualStudio12Generator(cm, name, platformName)
+{
+ std::string vc14Express;
+ this->ExpressEdition = cmSystemTools::ReadRegistryValue(
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\14.0\\Setup\\VC;"
+ "ProductDir", vc14Express, cmSystemTools::KeyWOW64_32);
+ this->DefaultPlatformToolset = "v140";
+ this->Version = VS14;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio14Generator::MatchesGeneratorName(
+ const std::string& name) const
+{
+ std::string genName;
+ if(cmVS14GenName(name, genName))
+ {
+ return genName == this->GetName();
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio14Generator::InitializeWindows(cmMakefile* mf)
+{
+ if (cmHasLiteralPrefix(this->SystemVersion, "10.0"))
+ {
+ return this->SelectWindows10SDK(mf, false);
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio14Generator::InitializeWindowsStore(cmMakefile* mf)
+{
+ std::ostringstream e;
+ if(!this->SelectWindowsStoreToolset(this->DefaultPlatformToolset))
+ {
+ if(this->DefaultPlatformToolset.empty())
+ {
+ e << this->GetName() << " supports Windows Store '8.0', '8.1' and "
+ "'10.0', but not '" << this->SystemVersion <<
+ "'. Check CMAKE_SYSTEM_VERSION.";
+ }
+ else
+ {
+ e << "A Windows Store component with CMake requires both the Windows "
+ << "Desktop SDK as well as the Windows Store '" << this->SystemVersion
+ << "' SDK. Please make sure that you have both installed";
+ }
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+ if (cmHasLiteralPrefix(this->SystemVersion, "10.0"))
+ {
+ return this->SelectWindows10SDK(mf, true);
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio14Generator::SelectWindows10SDK(cmMakefile* mf,
+ bool required)
+{
+ // Find the default version of the Windows 10 SDK.
+ this->WindowsTargetPlatformVersion = this->GetWindows10SDKVersion();
+ if (required && this->WindowsTargetPlatformVersion.empty())
+ {
+ std::ostringstream e;
+ e << "Could not find an appropriate version of the Windows 10 SDK"
+ << " installed on this machine";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+ mf->AddDefinition("CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION",
+ this->WindowsTargetPlatformVersion.c_str());
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio14Generator::SelectWindowsStoreToolset(
+ std::string& toolset) const
+{
+ if (cmHasLiteralPrefix(this->SystemVersion, "10.0"))
+ {
+ if (this->IsWindowsStoreToolsetInstalled() &&
+ this->IsWindowsDesktopToolsetInstalled())
+ {
+ toolset = "v140";
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ return
+ this->cmGlobalVisualStudio12Generator::SelectWindowsStoreToolset(toolset);
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio14Generator::WriteSLNHeader(std::ostream& fout)
+{
+ // Visual Studio 14 writes .sln format 12.00
+ fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
+ if (this->ExpressEdition)
+ {
+ fout << "# Visual Studio Express 14 for Windows Desktop\n";
+ }
+ else
+ {
+ fout << "# Visual Studio 14\n";
+ }
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio14Generator::IsWindowsDesktopToolsetInstalled() const
+{
+ const char desktop10Key[] =
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
+ "VisualStudio\\14.0\\VC\\Runtimes";
+
+ std::vector<std::string> vc14;
+ return cmSystemTools::GetRegistrySubKeys(desktop10Key,
+ vc14, cmSystemTools::KeyWOW64_32);
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio14Generator::IsWindowsStoreToolsetInstalled() const
+{
+ const char universal10Key[] =
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
+ "VisualStudio\\14.0\\Setup\\Build Tools for Windows 10;SrcPath";
+
+ std::string win10SDK;
+ return cmSystemTools::ReadRegistryValue(universal10Key,
+ win10SDK, cmSystemTools::KeyWOW64_32);
+}
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+struct NoWindowsH
+{
+ bool operator()(std::string const& p)
+ {
+ return !cmSystemTools::FileExists(p + "/um/windows.h", true);
+ }
+};
+#endif
+
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudio14Generator::GetWindows10SDKVersion()
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ // This logic is taken from the vcvarsqueryregistry.bat file from VS2015
+ // Try HKLM and then HKCU.
+ std::string win10Root;
+ if (!cmSystemTools::ReadRegistryValue(
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
+ "Windows Kits\\Installed Roots;KitsRoot10", win10Root,
+ cmSystemTools::KeyWOW64_32) &&
+ !cmSystemTools::ReadRegistryValue(
+ "HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\"
+ "Windows Kits\\Installed Roots;KitsRoot10", win10Root,
+ cmSystemTools::KeyWOW64_32))
+ {
+ return std::string();
+ }
+
+ std::vector<std::string> sdks;
+ std::string path = win10Root + "Include/*";
+ // Grab the paths of the different SDKs that are installed
+ cmSystemTools::GlobDirs(path, sdks);
+
+ // Skip SDKs that do not contain <um/windows.h> because that indicates that
+ // only the UCRT MSIs were installed for them.
+ sdks.erase(std::remove_if(sdks.begin(), sdks.end(), NoWindowsH()),
+ sdks.end());
+
+ if (!sdks.empty())
+ {
+ // Only use the filename, which will be the SDK version.
+ for (std::vector<std::string>::iterator i = sdks.begin();
+ i != sdks.end(); ++i)
+ {
+ *i = cmSystemTools::GetFilenameName(*i);
+ }
+
+ // Sort the results to make sure we select the most recent one.
+ std::sort(sdks.begin(), sdks.end(), cmSystemTools::VersionCompareGreater);
+
+ // Look for a SDK exactly matching the requested target version.
+ for (std::vector<std::string>::iterator i = sdks.begin();
+ i != sdks.end(); ++i)
+ {
+ if (cmSystemTools::VersionCompareEqual(*i, this->SystemVersion))
+ {
+ return *i;
+ }
+ }
+
+ // Use the latest Windows 10 SDK since the exact version is not available.
+ return sdks.at(0);
+ }
+#endif
+ // Return an empty string
+ return std::string();
+}
diff --git a/Source/cmGlobalVisualStudio14Generator.h b/Source/cmGlobalVisualStudio14Generator.h
new file mode 100644
index 000000000..57e628418
--- /dev/null
+++ b/Source/cmGlobalVisualStudio14Generator.h
@@ -0,0 +1,53 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2014 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmGlobalVisualStudio14Generator_h
+#define cmGlobalVisualStudio14Generator_h
+
+#include "cmGlobalVisualStudio12Generator.h"
+
+
+/** \class cmGlobalVisualStudio14Generator */
+class cmGlobalVisualStudio14Generator:
+ public cmGlobalVisualStudio12Generator
+{
+public:
+ cmGlobalVisualStudio14Generator(cmake* cm, const std::string& name,
+ const std::string& platformName);
+ static cmGlobalGeneratorFactory* NewFactory();
+
+ virtual bool MatchesGeneratorName(const std::string& name) const;
+
+ virtual void WriteSLNHeader(std::ostream& fout);
+
+ virtual const char* GetToolsVersion() { return "14.0"; }
+protected:
+ virtual bool InitializeWindows(cmMakefile* mf);
+ virtual bool InitializeWindowsStore(cmMakefile* mf);
+ virtual bool SelectWindowsStoreToolset(std::string& toolset) const;
+
+ // These aren't virtual because we need to check if the selected version
+ // of the toolset is installed
+ bool IsWindowsStoreToolsetInstalled() const;
+
+ virtual const char* GetIDEVersion() { return "14.0"; }
+ virtual bool SelectWindows10SDK(cmMakefile* mf, bool required);
+
+ // Used to verify that the Desktop toolset for the current generator is
+ // installed on the machine.
+ virtual bool IsWindowsDesktopToolsetInstalled() const;
+
+ std::string GetWindows10SDKVersion();
+
+private:
+ class Factory;
+};
+#endif
diff --git a/Source/cmGlobalVisualStudio6Generator.cxx b/Source/cmGlobalVisualStudio6Generator.cxx
index b3fabdade..5866c0e7f 100644
--- a/Source/cmGlobalVisualStudio6Generator.cxx
+++ b/Source/cmGlobalVisualStudio6Generator.cxx
@@ -14,6 +14,7 @@
#include "cmMakefile.h"
#include "cmake.h"
#include "cmGeneratedFileStream.h"
+#include <cmsys/FStream.hxx>
// Utility function to make a valid VS6 *.dsp filename out
// of a CMake target name:
@@ -30,9 +31,11 @@ std::string GetVS6TargetName(const std::string& targetName)
return name;
}
-cmGlobalVisualStudio6Generator::cmGlobalVisualStudio6Generator()
+cmGlobalVisualStudio6Generator::cmGlobalVisualStudio6Generator(cmake* cm)
+ : cmGlobalVisualStudioGenerator(cm)
{
- this->FindMakeProgramFile = "CMakeVS6FindMake.cmake";
+ this->MSDevCommandInitialized = false;
+ this->Version = VS6;
}
void cmGlobalVisualStudio6Generator
@@ -40,7 +43,6 @@ void cmGlobalVisualStudio6Generator
cmMakefile *mf,
bool optional)
{
- cmGlobalVisualStudioGenerator::AddPlatformDefinitions(mf);
mf->AddDefinition("CMAKE_GENERATOR_RC", "rc");
mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1");
this->GenerateConfigurations(mf);
@@ -60,7 +62,7 @@ void cmGlobalVisualStudio6Generator::GenerateConfigurations(cmMakefile* mf)
fname += "/Templates";
}
fname += "/CMakeVisualStudio6Configurations.cmake";
- if(!mf->ReadListFile(mf->GetCurrentListFile(), fname.c_str()))
+ if(!mf->ReadDependentFile(fname.c_str()))
{
cmSystemTools::Error("Cannot open ", fname.c_str(),
". Please copy this file from the main "
@@ -77,97 +79,103 @@ void cmGlobalVisualStudio6Generator::GenerateConfigurations(cmMakefile* mf)
}
}
-std::string cmGlobalVisualStudio6Generator
-::GenerateBuildCommand(const char* makeProgram,
- const char *projectName,
- const char *projectDir,
- const char* additionalOptions,
- const char *targetName,
- const char* config,
- bool ignoreErrors,
- bool)
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio6Generator::FindMakeProgram(cmMakefile* mf)
{
- // Visual studio 6 doesn't need project dir
- (void) projectDir;
- // Ingoring errors is not implemented in visual studio 6
- (void) ignoreErrors;
+ this->cmGlobalVisualStudioGenerator::FindMakeProgram(mf);
+ mf->AddDefinition("CMAKE_VS_MSDEV_COMMAND",
+ this->GetMSDevCommand().c_str());
+}
- // now build the test
- std::vector<std::string> mp;
- mp.push_back("[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio"
- "\\6.0\\Setup;VsCommonDir]/MSDev98/Bin");
- cmSystemTools::ExpandRegistryValues(mp[0]);
- std::string originalCommand = makeProgram;
- std::string makeCommand =
- cmSystemTools::FindProgram(makeProgram, mp);
- if(makeCommand.size() == 0)
+//----------------------------------------------------------------------------
+std::string const& cmGlobalVisualStudio6Generator::GetMSDevCommand()
+{
+ if(!this->MSDevCommandInitialized)
{
- std::string e = "Generator cannot find Visual Studio 6 msdev program \"";
- e += originalCommand;
- e += "\" specified by CMAKE_MAKE_PROGRAM cache entry. ";
- e += "Please fix the setting.";
- cmSystemTools::Error(e.c_str());
- return "";
+ this->MSDevCommandInitialized = true;
+ this->MSDevCommand = this->FindMSDevCommand();
}
- makeCommand = cmSystemTools::ConvertToOutputPath(makeCommand.c_str());
+ return this->MSDevCommand;
+}
- // if there are spaces in the makeCommand, assume a full path
- // and convert it to a path with no spaces in it as the
- // RunSingleCommand does not like spaces
-#if defined(_WIN32) && !defined(__CYGWIN__)
- if(makeCommand.find(' ') != std::string::npos)
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudio6Generator::FindMSDevCommand()
+{
+ std::string vscmd;
+ std::string vskey = this->GetRegistryBase() + "\\Setup;VsCommonDir";
+ if(cmSystemTools::ReadRegistryValue(vskey.c_str(), vscmd,
+ cmSystemTools::KeyWOW64_32))
{
- cmSystemTools::GetShortPath(makeCommand.c_str(), makeCommand);
+ cmSystemTools::ConvertToUnixSlashes(vscmd);
+ vscmd += "/MSDev98/Bin/";
}
-#endif
- makeCommand += " ";
- makeCommand += projectName;
- makeCommand += ".dsw /MAKE \"";
+ vscmd += "msdev.exe";
+ return vscmd;
+}
+
+//----------------------------------------------------------------------------
+void
+cmGlobalVisualStudio6Generator::GenerateBuildCommand(
+ std::vector<std::string>& makeCommand,
+ const std::string& makeProgram,
+ const std::string& projectName,
+ const std::string& /*projectDir*/,
+ const std::string& targetName,
+ const std::string& config,
+ bool /*fast*/, bool /*verbose*/,
+ std::vector<std::string> const& makeOptions
+ )
+{
+ // now build the test
+ makeCommand.push_back(
+ this->SelectMakeProgram(makeProgram, this->GetMSDevCommand())
+ );
+
+ makeCommand.push_back(std::string(projectName)+".dsw");
+ makeCommand.push_back("/MAKE");
+ std::string targetArg;
bool clean = false;
- if ( targetName && strcmp(targetName, "clean") == 0 )
+ std::string realTarget = targetName;
+ if ( realTarget == "clean" )
{
clean = true;
- targetName = "ALL_BUILD";
+ realTarget = "ALL_BUILD";
}
- if (targetName && strlen(targetName))
+ if (!realTarget.empty())
{
- makeCommand += targetName;
+ targetArg += realTarget;
}
else
{
- makeCommand += "ALL_BUILD";
+ targetArg += "ALL_BUILD";
}
- makeCommand += " - ";
- if(config && strlen(config))
+ targetArg += " - ";
+ if(!config.empty())
{
- makeCommand += config;
+ targetArg += config;
}
else
{
- makeCommand += "Debug";
+ targetArg += "Debug";
}
+ makeCommand.push_back(targetArg);
if(clean)
{
- makeCommand += "\" /CLEAN";
+ makeCommand.push_back("/CLEAN");
}
else
{
- makeCommand += "\" /BUILD";
+ makeCommand.push_back("/BUILD");
}
- if ( additionalOptions )
- {
- makeCommand += " ";
- makeCommand += additionalOptions;
- }
- return makeCommand;
+ makeCommand.insert(makeCommand.end(),
+ makeOptions.begin(), makeOptions.end());
}
///! Create a local generator appropriate to this Global Generator
-cmLocalGenerator *cmGlobalVisualStudio6Generator::CreateLocalGenerator()
+cmLocalGenerator *
+cmGlobalVisualStudio6Generator::CreateLocalGenerator(cmMakefile* mf)
{
- cmLocalGenerator *lg = new cmLocalVisualStudio6Generator;
- lg->SetGlobalGenerator(this);
- return lg;
+ return new cmLocalVisualStudio6Generator(this, mf);
}
@@ -178,6 +186,22 @@ void cmGlobalVisualStudio6Generator::Generate()
// Now write out the DSW
this->OutputDSWFile();
+
+ if (!this->CMakeInstance->GetIsInTryCompile())
+ {
+ const char* cmakeWarnVS6 =
+ this->CMakeInstance->GetState()->GetCacheEntryValue("CMAKE_WARN_VS6");
+ if (!cmakeWarnVS6 || !cmSystemTools::IsOff(cmakeWarnVS6))
+ {
+ this->CMakeInstance->IssueMessage(
+ cmake::WARNING,
+ "The \"Visual Studio 6\" generator is deprecated "
+ "and will be removed in a future version of CMake."
+ "\n"
+ "Add CMAKE_WARN_VS6=OFF to the cache to disable this warning."
+ );
+ }
+ }
}
// Write a DSW file to the stream
@@ -193,13 +217,17 @@ void cmGlobalVisualStudio6Generator
TargetDependSet projectTargets;
TargetDependSet originalTargets;
this->GetTargetSets(projectTargets, originalTargets, root, generators);
- OrderedTargetDependSet orderedProjectTargets(projectTargets);
+ OrderedTargetDependSet orderedProjectTargets(projectTargets, "ALL_BUILD");
for(OrderedTargetDependSet::const_iterator
tt = orderedProjectTargets.begin();
tt != orderedProjectTargets.end(); ++tt)
{
- cmTarget* target = *tt;
+ cmGeneratorTarget const* target = *tt;
+ if(target->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ continue;
+ }
// Write the project into the DSW file
const char* expath = target->GetProperty("EXTERNAL_MSPROJECT");
if(expath)
@@ -207,14 +235,15 @@ void cmGlobalVisualStudio6Generator
std::string project = target->GetName();
std::string location = expath;
this->WriteExternalProject(fout, project.c_str(),
- location.c_str(), target->GetUtilities());
+ location.c_str(), target->GetUtilities());
}
else
{
std::string dspname = GetVS6TargetName(target->GetName());
- std::string dir = target->GetMakefile()->GetStartOutputDirectory();
+ std::string dir =
+ target->GetLocalGenerator()->GetCurrentBinaryDirectory();
dir = root->Convert(dir.c_str(), cmLocalGenerator::START_OUTPUT);
- this->WriteProject(fout, dspname.c_str(), dir.c_str(), *target);
+ this->WriteProject(fout, dspname.c_str(), dir.c_str(), target);
}
}
@@ -226,15 +255,15 @@ void cmGlobalVisualStudio6Generator
::OutputDSWFile(cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators)
{
- if(generators.size() == 0)
+ if(generators.empty())
{
return;
}
- std::string fname = root->GetMakefile()->GetStartOutputDirectory();
+ std::string fname = root->GetMakefile()->GetCurrentBinaryDirectory();
fname += "/";
- fname += root->GetMakefile()->GetProjectName();
+ fname += root->GetProjectName();
fname += ".dsw";
- std::ofstream fout(fname.c_str());
+ cmsys::ofstream fout(fname.c_str());
if(!fout)
{
cmSystemTools::Error("Error can not open DSW file for write: ",
@@ -248,7 +277,7 @@ void cmGlobalVisualStudio6Generator
// output the DSW file
void cmGlobalVisualStudio6Generator::OutputDSWFile()
{
- std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it;
+ std::map<std::string, std::vector<cmLocalGenerator*> >::iterator it;
for(it = this->ProjectMap.begin(); it!= this->ProjectMap.end(); ++it)
{
this->OutputDSWFile(it->second[0], it->second);
@@ -259,9 +288,9 @@ void cmGlobalVisualStudio6Generator::OutputDSWFile()
// Note, that dependencies from executables to
// the libraries it uses are also done here
void cmGlobalVisualStudio6Generator::WriteProject(std::ostream& fout,
- const char* dspname,
- const char* dir,
- cmTarget& target)
+ const std::string& dspname,
+ const char* dir,
+ const cmGeneratorTarget *target)
{
fout << "#########################################################"
"######################\n\n";
@@ -270,7 +299,7 @@ void cmGlobalVisualStudio6Generator::WriteProject(std::ostream& fout,
fout << "Package=<5>\n{{{\n}}}\n\n";
fout << "Package=<4>\n";
fout << "{{{\n";
- VSDependSet const& depends = this->VSTargetDepends[&target];
+ VSDependSet const& depends = this->VSTargetDepends[target];
for(VSDependSet::const_iterator di = depends.begin();
di != depends.end(); ++di)
{
@@ -281,7 +310,7 @@ void cmGlobalVisualStudio6Generator::WriteProject(std::ostream& fout,
}
fout << "}}}\n\n";
- UtilityDependsMap::iterator ui = this->UtilityDepends.find(&target);
+ UtilityDependsMap::iterator ui = this->UtilityDepends.find(target);
if(ui != this->UtilityDepends.end())
{
const char* uname = ui->second.c_str();
@@ -304,9 +333,9 @@ void cmGlobalVisualStudio6Generator::WriteProject(std::ostream& fout,
// Note, that dependencies from executables to
// the libraries it uses are also done here
void cmGlobalVisualStudio6Generator::WriteExternalProject(std::ostream& fout,
- const char* name,
+ const std::string& name,
const char* location,
- const std::set<cmStdString>& dependencies)
+ const std::set<std::string>& dependencies)
{
fout << "#########################################################"
"######################\n\n";
@@ -317,7 +346,7 @@ void cmGlobalVisualStudio6Generator::WriteExternalProject(std::ostream& fout,
fout << "{{{\n";
- std::set<cmStdString>::const_iterator i, end;
+ std::set<std::string>::const_iterator i, end;
// write dependencies.
i = dependencies.begin();
end = dependencies.end();
@@ -354,12 +383,14 @@ void cmGlobalVisualStudio6Generator::WriteDSWHeader(std::ostream& fout)
//----------------------------------------------------------------------------
std::string
-cmGlobalVisualStudio6Generator::WriteUtilityDepend(cmTarget* target)
+cmGlobalVisualStudio6Generator::WriteUtilityDepend(
+ const cmGeneratorTarget *target)
{
std::string pname = target->GetName();
pname += "_UTILITY";
pname = GetVS6TargetName(pname.c_str());
- std::string fname = target->GetMakefile()->GetStartOutputDirectory();
+ std::string fname =
+ target->GetLocalGenerator()->GetCurrentBinaryDirectory();
fname += "/";
fname += pname;
fname += ".dsp";
@@ -400,19 +431,18 @@ void cmGlobalVisualStudio6Generator
::GetDocumentation(cmDocumentationEntry& entry)
{
entry.Name = cmGlobalVisualStudio6Generator::GetActualName();
- entry.Brief = "Generates Visual Studio 6 project files.";
- entry.Full = "";
+ entry.Brief = "Deprecated. Generates Visual Studio 6 project files.";
}
//----------------------------------------------------------------------------
void
cmGlobalVisualStudio6Generator
-::AppendDirectoryForConfig(const char* prefix,
- const char* config,
- const char* suffix,
+::AppendDirectoryForConfig(const std::string& prefix,
+ const std::string& config,
+ const std::string& suffix,
std::string& dir)
{
- if(config)
+ if(!config.empty())
{
dir += prefix;
dir += config;
diff --git a/Source/cmGlobalVisualStudio6Generator.h b/Source/cmGlobalVisualStudio6Generator.h
index 6bd39ca9a..ae2988e66 100644
--- a/Source/cmGlobalVisualStudio6Generator.h
+++ b/Source/cmGlobalVisualStudio6Generator.h
@@ -15,8 +15,6 @@
#include "cmGlobalVisualStudioGenerator.h"
#include "cmGlobalGeneratorFactory.h"
-class cmTarget;
-
/** \class cmGlobalVisualStudio6Generator
* \brief Write a Unix makefiles.
*
@@ -25,24 +23,30 @@ class cmTarget;
class cmGlobalVisualStudio6Generator : public cmGlobalVisualStudioGenerator
{
public:
- cmGlobalVisualStudio6Generator();
+ cmGlobalVisualStudio6Generator(cmake* cm);
static cmGlobalGeneratorFactory* NewFactory() {
return new cmGlobalGeneratorSimpleFactory
<cmGlobalVisualStudio6Generator>(); }
///! Get the name for the generator.
- virtual const char* GetName() const {
+ virtual std::string GetName() const {
return cmGlobalVisualStudio6Generator::GetActualName();}
- static const char* GetActualName() {return "Visual Studio 6";}
+ static std::string GetActualName() {return "Visual Studio 6";}
/** Get the documentation entry for this generator. */
static void GetDocumentation(cmDocumentationEntry& entry);
+ /**
+ * Utilized by the generator factory to determine if this generator
+ * supports toolsets.
+ */
+ static bool SupportsToolset() { return false; }
+
///! Create a local generator appropriate to this Global Generator
- virtual cmLocalGenerator *CreateLocalGenerator();
+ virtual cmLocalGenerator *CreateLocalGenerator(cmMakefile* mf);
/**
- * Try to determine system infomation such as shared library
+ * Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
@@ -52,21 +56,16 @@ public:
* Try running cmake and building a file. This is used for dynalically
* loaded commands, not as part of the usual build process.
*/
- virtual std::string GenerateBuildCommand(const char* makeProgram,
- const char *projectName,
- const char *projectDir,
- const char* additionalOptions,
- const char *targetName,
- const char* config,
- bool ignoreErrors,
- bool fast);
-
- /**
- * Generate the all required files for building this project/tree. This
- * basically creates a series of LocalGenerators for each directory and
- * requests that they Generate.
- */
- virtual void Generate();
+ virtual void GenerateBuildCommand(
+ std::vector<std::string>& makeCommand,
+ const std::string& makeProgram,
+ const std::string& projectName,
+ const std::string& projectDir,
+ const std::string& targetName,
+ const std::string& config,
+ bool fast, bool verbose,
+ std::vector<std::string> const& makeOptions = std::vector<std::string>()
+ );
/**
* Generate the DSW workspace file.
@@ -79,27 +78,36 @@ public:
std::vector<cmLocalGenerator*>& generators);
/** Append the subdirectory for the given configuration. */
- virtual void AppendDirectoryForConfig(const char* prefix,
- const char* config,
- const char* suffix,
+ virtual void AppendDirectoryForConfig(const std::string& prefix,
+ const std::string& config,
+ const std::string& suffix,
std::string& dir);
///! What is the configurations directory variable called?
virtual const char* GetCMakeCFGIntDir() const { return "$(IntDir)"; }
+ virtual void FindMakeProgram(cmMakefile*);
+
protected:
+ virtual void Generate();
virtual const char* GetIDEVersion() { return "6.0"; }
private:
+ virtual std::string GetVSMakeProgram() { return this->GetMSDevCommand(); }
void GenerateConfigurations(cmMakefile* mf);
void WriteDSWFile(std::ostream& fout);
void WriteDSWHeader(std::ostream& fout);
void WriteProject(std::ostream& fout,
- const char* name, const char* path, cmTarget &t);
+ const std::string& name, const char* path,
+ cmGeneratorTarget const* t);
void WriteExternalProject(std::ostream& fout,
- const char* name, const char* path,
- const std::set<cmStdString>& dependencies);
+ const std::string& name, const char* path,
+ const std::set<std::string>& dependencies);
void WriteDSWFooter(std::ostream& fout);
- virtual std::string WriteUtilityDepend(cmTarget* target);
+ virtual std::string WriteUtilityDepend(const cmGeneratorTarget *target);
+ std::string MSDevCommand;
+ bool MSDevCommandInitialized;
+ std::string const& GetMSDevCommand();
+ std::string FindMSDevCommand();
};
#endif
diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx
index 51efc466c..8227b82da 100644
--- a/Source/cmGlobalVisualStudio71Generator.cxx
+++ b/Source/cmGlobalVisualStudio71Generator.cxx
@@ -16,22 +16,12 @@
#include "cmake.h"
//----------------------------------------------------------------------------
-cmGlobalVisualStudio71Generator::cmGlobalVisualStudio71Generator(
- const char* platformName) : cmGlobalVisualStudio7Generator(platformName)
+cmGlobalVisualStudio71Generator::cmGlobalVisualStudio71Generator(cmake* cm,
+ const std::string& platformName)
+ : cmGlobalVisualStudio7Generator(cm, platformName)
{
- this->FindMakeProgramFile = "CMakeVS71FindMake.cmake";
this->ProjectConfigurationSectionName = "ProjectConfiguration";
-}
-
-//----------------------------------------------------------------------------
-///! Create a local generator appropriate to this Global Generator
-cmLocalGenerator *cmGlobalVisualStudio71Generator::CreateLocalGenerator()
-{
- cmLocalVisualStudio7Generator *lg =
- new cmLocalVisualStudio7Generator(cmLocalVisualStudioGenerator::VS71);
- lg->SetExtraFlagTable(this->GetExtraFlagTableVS7());
- lg->SetGlobalGenerator(this);
- return lg;
+ this->Version = VS71;
}
//----------------------------------------------------------------------------
@@ -93,6 +83,9 @@ void cmGlobalVisualStudio71Generator
cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators)
{
+ std::vector<std::string> configs;
+ root->GetMakefile()->GetConfigurations(configs);
+
// Write out the header for a SLN file
this->WriteSLNHeader(fout);
@@ -101,7 +94,7 @@ void cmGlobalVisualStudio71Generator
TargetDependSet projectTargets;
TargetDependSet originalTargets;
this->GetTargetSets(projectTargets, originalTargets, root, generators);
- OrderedTargetDependSet orderedProjectTargets(projectTargets);
+ OrderedTargetDependSet orderedProjectTargets(projectTargets, "ALL_BUILD");
this->WriteTargetsToSolution(fout, root, orderedProjectTargets);
@@ -114,11 +107,11 @@ void cmGlobalVisualStudio71Generator
// Write out the configurations information for the solution
fout << "Global\n";
// Write out the configurations for the solution
- this->WriteSolutionConfigurations(fout);
+ this->WriteSolutionConfigurations(fout, configs);
fout << "\tGlobalSection(" << this->ProjectConfigurationSectionName
<< ") = postSolution\n";
// Write out the configurations for all the targets in the project
- this->WriteTargetConfigurations(fout, root, orderedProjectTargets);
+ this->WriteTargetConfigurations(fout, configs, orderedProjectTargets);
fout << "\tEndGlobalSection\n";
if (useFolderProperty)
@@ -139,11 +132,12 @@ void cmGlobalVisualStudio71Generator
//----------------------------------------------------------------------------
void
cmGlobalVisualStudio71Generator
-::WriteSolutionConfigurations(std::ostream& fout)
+::WriteSolutionConfigurations(std::ostream& fout,
+ std::vector<std::string> const& configs)
{
fout << "\tGlobalSection(SolutionConfiguration) = preSolution\n";
- for(std::vector<std::string>::iterator i = this->Configurations.begin();
- i != this->Configurations.end(); ++i)
+ for(std::vector<std::string>::const_iterator i = configs.begin();
+ i != configs.end(); ++i)
{
fout << "\t\t" << *i << " = " << *i << "\n";
}
@@ -156,9 +150,9 @@ cmGlobalVisualStudio71Generator
// the libraries it uses are also done here
void
cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout,
- const char* dspname,
+ const std::string& dspname,
const char* dir,
- cmTarget& t)
+ cmGeneratorTarget const* t)
{
// check to see if this is a fortran build
const char* ext = ".vcproj";
@@ -169,7 +163,7 @@ cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout,
ext = ".vfproj";
project = "Project(\"{6989167D-11E4-40FE-8C1A-2192A86A7E90}\") = \"";
}
- const char* targetExt = t.GetProperty("GENERATOR_FILE_NAME_EXT");
+ const char* targetExt = t->GetProperty("GENERATOR_FILE_NAME_EXT");
if(targetExt)
{
ext = targetExt;
@@ -186,7 +180,7 @@ cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout,
fout <<"EndProject\n";
- UtilityDependsMap::iterator ui = this->UtilityDepends.find(&t);
+ UtilityDependsMap::iterator ui = this->UtilityDepends.find(t);
if(ui != this->UtilityDepends.end())
{
const char* uname = ui->second.c_str();
@@ -209,19 +203,19 @@ cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout,
void
cmGlobalVisualStudio71Generator
::WriteProjectDepends(std::ostream& fout,
- const char*,
- const char*, cmTarget& target)
+ const std::string&,
+ const char*, cmGeneratorTarget const* target)
{
- VSDependSet const& depends = this->VSTargetDepends[&target];
+ VSDependSet const& depends = this->VSTargetDepends[target];
for(VSDependSet::const_iterator di = depends.begin();
di != depends.end(); ++di)
{
const char* name = di->c_str();
std::string guid = this->GetGUID(name);
- if(guid.size() == 0)
+ if(guid.empty())
{
std::string m = "Target: ";
- m += target.GetName();
+ m += target->GetName();
m += " depends on unknown target: ";
m += name;
cmSystemTools::Error(m.c_str());
@@ -235,13 +229,13 @@ cmGlobalVisualStudio71Generator
// executables to the libraries it uses are also done here
void cmGlobalVisualStudio71Generator
::WriteExternalProject(std::ostream& fout,
- const char* name,
+ const std::string& name,
const char* location,
const char* typeGuid,
- const std::set<cmStdString>& depends)
+ const std::set<std::string>& depends)
{
fout << "Project(\"{"
- << (typeGuid ? typeGuid : "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942")
+ << (typeGuid ? typeGuid : this->ExternalProjectType(location))
<< "}\") = \""
<< name << "\", \""
<< this->ConvertToSolutionPath(location) << "\", \"{"
@@ -253,10 +247,10 @@ void cmGlobalVisualStudio71Generator
if(!depends.empty())
{
fout << "\tProjectSection(ProjectDependencies) = postProject\n";
- std::set<cmStdString>::const_iterator it;
+ std::set<std::string>::const_iterator it;
for(it = depends.begin(); it != depends.end(); ++it)
{
- if(it->size() > 0)
+ if(!it->empty())
{
fout << "\t\t{"
<< this->GetGUID(it->c_str())
@@ -278,15 +272,16 @@ void cmGlobalVisualStudio71Generator
// executables to the libraries it uses are also done here
void cmGlobalVisualStudio71Generator
::WriteProjectConfigurations(
- std::ostream& fout, const char* name, cmTarget::TargetType,
+ std::ostream& fout, const std::string& name, cmState::TargetType,
+ std::vector<std::string> const& configs,
const std::set<std::string>& configsPartOfDefaultBuild,
- const char* platformMapping)
+ std::string const& platformMapping)
{
- const char* platformName =
- platformMapping ? platformMapping : this->GetPlatformName();
+ const std::string& platformName =
+ !platformMapping.empty() ? platformMapping : this->GetPlatformName();
std::string guid = this->GetGUID(name);
- for(std::vector<std::string>::iterator i = this->Configurations.begin();
- i != this->Configurations.end(); ++i)
+ for(std::vector<std::string>::const_iterator i = configs.begin();
+ i != configs.end(); ++i)
{
fout << "\t\t{" << guid << "}." << *i
<< ".ActiveCfg = " << *i << "|" << platformName << std::endl;
@@ -313,5 +308,4 @@ void cmGlobalVisualStudio71Generator
{
entry.Name = cmGlobalVisualStudio71Generator::GetActualName();
entry.Brief = "Generates Visual Studio .NET 2003 project files.";
- entry.Full = "";
}
diff --git a/Source/cmGlobalVisualStudio71Generator.h b/Source/cmGlobalVisualStudio71Generator.h
index e136db7ea..5035fda65 100644
--- a/Source/cmGlobalVisualStudio71Generator.h
+++ b/Source/cmGlobalVisualStudio71Generator.h
@@ -23,22 +23,20 @@
class cmGlobalVisualStudio71Generator : public cmGlobalVisualStudio7Generator
{
public:
- cmGlobalVisualStudio71Generator(const char* platformName = NULL);
+ cmGlobalVisualStudio71Generator(cmake* cm,
+ const std::string& platformName = "");
static cmGlobalGeneratorFactory* NewFactory() {
return new cmGlobalGeneratorSimpleFactory
<cmGlobalVisualStudio71Generator>(); }
///! Get the name for the generator.
- virtual const char* GetName() const {
+ virtual std::string GetName() const {
return cmGlobalVisualStudio71Generator::GetActualName();}
- static const char* GetActualName() {return "Visual Studio 7 .NET 2003";}
+ static std::string GetActualName() {return "Visual Studio 7 .NET 2003";}
/** Get the documentation entry for this generator. */
static void GetDocumentation(cmDocumentationEntry& entry);
- ///! Create a local generator appropriate to this Global Generator
- virtual cmLocalGenerator *CreateLocalGenerator();
-
/**
* Where does this version of Visual Studio look for macros for the
* current user? Returns the empty string if this version of Visual
@@ -57,20 +55,24 @@ protected:
virtual void WriteSLNFile(std::ostream& fout,
cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators);
- virtual void WriteSolutionConfigurations(std::ostream& fout);
+ virtual void WriteSolutionConfigurations(
+ std::ostream& fout, std::vector<std::string> const& configs);
virtual void WriteProject(std::ostream& fout,
- const char* name, const char* path, cmTarget &t);
+ const std::string& name, const char* path,
+ const cmGeneratorTarget *t);
virtual void WriteProjectDepends(std::ostream& fout,
- const char* name, const char* path, cmTarget &t);
+ const std::string& name, const char* path,
+ cmGeneratorTarget const* t);
virtual void WriteProjectConfigurations(
- std::ostream& fout, const char* name, cmTarget::TargetType type,
+ std::ostream& fout, const std::string& name, cmState::TargetType type,
+ std::vector<std::string> const& configs,
const std::set<std::string>& configsPartOfDefaultBuild,
- const char* platformMapping = NULL);
+ const std::string& platformMapping = "");
virtual void WriteExternalProject(std::ostream& fout,
- const char* name,
+ const std::string& name,
const char* path,
const char* typeGuid,
- const std::set<cmStdString>& depends);
+ const std::set<std::string>& depends);
virtual void WriteSLNHeader(std::ostream& fout);
std::string ProjectConfigurationSectionName;
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index b47566561..f5848ab81 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -15,20 +15,95 @@
#include "cmGeneratedFileStream.h"
#include "cmLocalVisualStudio7Generator.h"
#include "cmMakefile.h"
+#include "cmUuid.h"
#include "cmake.h"
+#include <cmsys/Encoding.hxx>
-cmGlobalVisualStudio7Generator::cmGlobalVisualStudio7Generator(
- const char* platformName)
+//----------------------------------------------------------------------------
+static cmVS7FlagTable cmVS7ExtraFlagTable[] =
+{
+ // Precompiled header and related options. Note that the
+ // UsePrecompiledHeader entries are marked as "Continue" so that the
+ // corresponding PrecompiledHeaderThrough entry can be found.
+ {"UsePrecompiledHeader", "YX", "Automatically Generate", "2",
+ cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
+ {"PrecompiledHeaderThrough", "YX", "Precompiled Header Name", "",
+ cmVS7FlagTable::UserValueRequired},
+ {"UsePrecompiledHeader", "Yu", "Use Precompiled Header", "3",
+ cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
+ {"PrecompiledHeaderThrough", "Yu", "Precompiled Header Name", "",
+ cmVS7FlagTable::UserValueRequired},
+ {"WholeProgramOptimization", "LTCG", "WholeProgramOptimization", "true", 0},
+
+ // Exception handling mode. If no entries match, it will be FALSE.
+ {"ExceptionHandling", "GX", "enable c++ exceptions", "true", 0},
+ {"ExceptionHandling", "EHsc", "enable c++ exceptions", "true", 0},
+ // The EHa option does not have an IDE setting. Let it go to false,
+ // and have EHa passed on the command line by leaving out the table
+ // entry.
+
+ {0,0,0,0,0}
+};
+
+cmGlobalVisualStudio7Generator::cmGlobalVisualStudio7Generator(cmake *cm,
+ const std::string& platformName)
+ : cmGlobalVisualStudioGenerator(cm)
{
- this->FindMakeProgramFile = "CMakeVS7FindMake.cmake";
+ this->IntelProjectVersion = 0;
+ this->DevEnvCommandInitialized = false;
+ this->MasmEnabled = false;
- if (!platformName)
+ if (platformName.empty())
+ {
+ this->DefaultPlatformName = "Win32";
+ }
+ else
{
- platformName = "Win32";
+ this->DefaultPlatformName = platformName;
}
- this->PlatformName = platformName;
+ this->ExtraFlagTable = cmVS7ExtraFlagTable;
+ this->Version = VS7;
+}
+
+cmGlobalVisualStudio7Generator::~cmGlobalVisualStudio7Generator()
+{
+ free(this->IntelProjectVersion);
}
+// Package GUID of Intel Visual Fortran plugin to VS IDE
+#define CM_INTEL_PLUGIN_GUID "{B68A201D-CB9B-47AF-A52F-7EEC72E217E4}"
+
+const char* cmGlobalVisualStudio7Generator::GetIntelProjectVersion()
+{
+ if(!this->IntelProjectVersion)
+ {
+ // Compute the version of the Intel plugin to the VS IDE.
+ // If the key does not exist then use a default guess.
+ std::string intelVersion;
+ std::string vskey = this->GetRegistryBase();
+ vskey += "\\Packages\\" CM_INTEL_PLUGIN_GUID ";ProductVersion";
+ cmSystemTools::ReadRegistryValue(vskey.c_str(), intelVersion,
+ cmSystemTools::KeyWOW64_32);
+ unsigned int intelVersionNumber = ~0u;
+ sscanf(intelVersion.c_str(), "%u", &intelVersionNumber);
+ if(intelVersionNumber >= 11)
+ {
+ // Default to latest known project file version.
+ intelVersion = "11.0";
+ }
+ else if(intelVersionNumber == 10)
+ {
+ // Version 10.x actually uses 9.10 in project files!
+ intelVersion = "9.10";
+ }
+ else
+ {
+ // Version <= 9: use ProductVersion from registry.
+ }
+ this->IntelProjectVersion = strdup(intelVersion.c_str());
+ }
+ return this->IntelProjectVersion;
+}
void cmGlobalVisualStudio7Generator
::EnableLanguage(std::vector<std::string>const & lang,
@@ -36,8 +111,6 @@ void cmGlobalVisualStudio7Generator
{
mf->AddDefinition("CMAKE_GENERATOR_RC", "rc");
mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1");
- mf->AddDefinition("CMAKE_GENERATOR_FC", "ifort");
- this->AddPlatformDefinitions(mf);
if(!mf->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
{
mf->AddCacheDefinition(
@@ -46,12 +119,11 @@ void cmGlobalVisualStudio7Generator
"Semicolon separated list of supported configuration types, "
"only supports Debug, Release, MinSizeRel, and RelWithDebInfo, "
"anything else will be ignored.",
- cmCacheManager::STRING);
+ cmState::STRING);
}
// Create list of configurations requested by user's cache, if any.
this->cmGlobalGenerator::EnableLanguage(lang, mf, optional);
- this->GenerateConfigurations(mf);
// if this environment variable is set, then copy it to
// a static cache entry. It will be used by
@@ -66,140 +138,188 @@ void cmGlobalVisualStudio7Generator
mf->AddCacheDefinition
("CMAKE_MSVCIDE_RUN_PATH", extraPath,
"Saved environment variable CMAKE_MSVCIDE_RUN_PATH",
- cmCacheManager::STATIC);
+ cmState::STATIC);
}
}
-std::string cmGlobalVisualStudio7Generator
-::GenerateBuildCommand(const char* makeProgram,
- const char *projectName, const char *projectDir,
- const char* additionalOptions, const char *targetName,
- const char* config, bool ignoreErrors, bool)
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio7Generator::FindMakeProgram(cmMakefile* mf)
{
- // Visual studio 7 doesn't need project dir
- (void) projectDir;
- // Ingoring errors is not implemented in visual studio 6
- (void) ignoreErrors;
+ this->cmGlobalVisualStudioGenerator::FindMakeProgram(mf);
+ mf->AddDefinition("CMAKE_VS_DEVENV_COMMAND",
+ this->GetDevEnvCommand().c_str());
+}
- // now build the test
- std::string makeCommand =
- cmSystemTools::ConvertToOutputPath(makeProgram);
- std::string lowerCaseCommand = makeCommand;
- cmSystemTools::LowerCase(lowerCaseCommand);
+//----------------------------------------------------------------------------
+std::string const& cmGlobalVisualStudio7Generator::GetDevEnvCommand()
+{
+ if(!this->DevEnvCommandInitialized)
+ {
+ this->DevEnvCommandInitialized = true;
+ this->DevEnvCommand = this->FindDevEnvCommand();
+ }
+ return this->DevEnvCommand;
+}
- // if there are spaces in the makeCommand, assume a full path
- // and convert it to a path with no spaces in it as the
- // RunSingleCommand does not like spaces
-#if defined(_WIN32) && !defined(__CYGWIN__)
- if(makeCommand.find(' ') != std::string::npos)
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudio7Generator::FindDevEnvCommand()
+{
+ std::string vscmd;
+ std::string vskey = this->GetRegistryBase() + ";InstallDir";
+ if(cmSystemTools::ReadRegistryValue(vskey.c_str(), vscmd,
+ cmSystemTools::KeyWOW64_32))
{
- cmSystemTools::GetShortPath(makeCommand.c_str(), makeCommand);
+ cmSystemTools::ConvertToUnixSlashes(vscmd);
+ vscmd += "/";
}
-#endif
- makeCommand += " ";
- makeCommand += projectName;
- makeCommand += ".sln ";
+ vscmd += "devenv.com";
+ return vscmd;
+}
+
+//----------------------------------------------------------------------------
+const char* cmGlobalVisualStudio7Generator::ExternalProjectType(
+ const char* location)
+{
+ std::string extension = cmSystemTools::GetFilenameLastExtension(location);
+ if (extension == ".vbproj")
+ {
+ return "F184B08F-C81C-45F6-A57F-5ABD9991F28F";
+ }
+ else if (extension == ".csproj")
+ {
+ return "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC";
+ }
+ else if (extension == ".fsproj")
+ {
+ return "F2A71F9B-5D33-465A-A702-920D77279786";
+ }
+ else if (extension == ".vdproj")
+ {
+ return "54435603-DBB4-11D2-8724-00A0C9A8B90C";
+ }
+ else if (extension == ".dbproj")
+ {
+ return "C8D11400-126E-41CD-887F-60BD40844F9E";
+ }
+ else if (extension == ".wixproj")
+ {
+ return "930C7802-8A8C-48F9-8165-68863BCCD9DD";
+ }
+ else if (extension == ".pyproj")
+ {
+ return "888888A0-9F3D-457C-B088-3A5042F75D52";
+ }
+ return "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942";
+}
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio7Generator::GenerateBuildCommand(
+ std::vector<std::string>& makeCommand,
+ const std::string& makeProgram,
+ const std::string& projectName,
+ const std::string& /*projectDir*/,
+ const std::string& targetName,
+ const std::string& config,
+ bool /*fast*/, bool /*verbose*/,
+ std::vector<std::string> const& makeOptions)
+{
+ // Select the caller- or user-preferred make program, else devenv.
+ std::string makeProgramSelected =
+ this->SelectMakeProgram(makeProgram, this->GetDevEnvCommand());
+
+ // Ignore the above preference if it is msbuild.
+ // Assume any other value is either a devenv or
+ // command-line compatible with devenv.
+ std::string makeProgramLower = makeProgramSelected;
+ cmSystemTools::LowerCase(makeProgramLower);
+ if(makeProgramLower.find("msbuild") != std::string::npos)
+ {
+ makeProgramSelected = this->GetDevEnvCommand();
+ }
+
+ makeCommand.push_back(makeProgramSelected);
+
+ makeCommand.push_back(std::string(projectName) + ".sln");
+ std::string realTarget = targetName;
bool clean = false;
- if ( targetName && strcmp(targetName, "clean") == 0 )
+ if ( realTarget == "clean" )
{
clean = true;
- targetName = "ALL_BUILD";
+ realTarget = "ALL_BUILD";
}
if(clean)
{
- makeCommand += "/clean ";
+ makeCommand.push_back("/clean");
}
else
{
- makeCommand += "/build ";
+ makeCommand.push_back("/build");
}
- if(config && strlen(config))
+ if(!config.empty())
{
- makeCommand += config;
+ makeCommand.push_back(config);
}
else
{
- makeCommand += "Debug";
+ makeCommand.push_back("Debug");
}
- makeCommand += " /project ";
+ makeCommand.push_back("/project");
- if (targetName && strlen(targetName))
+ if (!realTarget.empty())
{
- makeCommand += targetName;
+ makeCommand.push_back(realTarget);
}
else
{
- makeCommand += "ALL_BUILD";
- }
- if ( additionalOptions )
- {
- makeCommand += " ";
- makeCommand += additionalOptions;
+ makeCommand.push_back("ALL_BUILD");
}
- return makeCommand;
+ makeCommand.insert(makeCommand.end(),
+ makeOptions.begin(), makeOptions.end());
}
///! Create a local generator appropriate to this Global Generator
-cmLocalGenerator *cmGlobalVisualStudio7Generator::CreateLocalGenerator()
+cmLocalGenerator *cmGlobalVisualStudio7Generator::CreateLocalGenerator(
+ cmMakefile* mf)
{
cmLocalVisualStudio7Generator *lg =
- new cmLocalVisualStudio7Generator(cmLocalVisualStudioGenerator::VS7);
- lg->SetExtraFlagTable(this->GetExtraFlagTableVS7());
- lg->SetGlobalGenerator(this);
+ new cmLocalVisualStudio7Generator(this, mf);
return lg;
}
//----------------------------------------------------------------------------
-void cmGlobalVisualStudio7Generator::AddPlatformDefinitions(cmMakefile* mf)
+std::string const& cmGlobalVisualStudio7Generator::GetPlatformName() const
{
- cmGlobalVisualStudioGenerator::AddPlatformDefinitions(mf);
- mf->AddDefinition("CMAKE_VS_PLATFORM_NAME", this->GetPlatformName());
+ if(!this->GeneratorPlatform.empty())
+ {
+ return this->GeneratorPlatform;
+ }
+ return this->DefaultPlatformName;
}
-void cmGlobalVisualStudio7Generator::GenerateConfigurations(cmMakefile* mf)
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio7Generator::SetSystemName(std::string const& s,
+ cmMakefile* mf)
{
- // process the configurations
- const char* ct
- = this->CMakeInstance->GetCacheDefinition("CMAKE_CONFIGURATION_TYPES");
- if ( ct )
- {
- std::vector<std::string> argsOut;
- cmSystemTools::ExpandListArgument(ct, argsOut);
- for(std::vector<std::string>::iterator i = argsOut.begin();
- i != argsOut.end(); ++i)
- {
- if(std::find(this->Configurations.begin(),
- this->Configurations.end(),
- *i) == this->Configurations.end())
- {
- this->Configurations.push_back(*i);
- }
- }
- }
- // default to at least Debug and Release
- if(this->Configurations.size() == 0)
+ mf->AddDefinition("CMAKE_VS_INTEL_Fortran_PROJECT_VERSION",
+ this->GetIntelProjectVersion());
+ return this->cmGlobalVisualStudioGenerator::SetSystemName(s, mf);
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio7Generator::SetGeneratorPlatform(std::string const& p,
+ cmMakefile* mf)
+{
+ if(this->GetPlatformName() == "x64")
{
- this->Configurations.push_back("Debug");
- this->Configurations.push_back("Release");
+ mf->AddDefinition("CMAKE_FORCE_WIN64", "TRUE");
}
-
- // Reset the entry to have a semi-colon separated list.
- std::string configs = this->Configurations[0];
- for(unsigned int i=1; i < this->Configurations.size(); ++i)
+ else if(this->GetPlatformName() == "Itanium")
{
- configs += ";";
- configs += this->Configurations[i];
+ mf->AddDefinition("CMAKE_FORCE_IA64", "TRUE");
}
-
- mf->AddCacheDefinition(
- "CMAKE_CONFIGURATION_TYPES",
- configs.c_str(),
- "Semicolon separated list of supported configuration types, "
- "only supports Debug, Release, MinSizeRel, and RelWithDebInfo, "
- "anything else will be ignored.",
- cmCacheManager::STRING);
+ mf->AddDefinition("CMAKE_VS_PLATFORM_NAME", this->GetPlatformName().c_str());
+ return this->cmGlobalVisualStudioGenerator::SetGeneratorPlatform(p, mf);
}
void cmGlobalVisualStudio7Generator::Generate()
@@ -215,20 +335,37 @@ void cmGlobalVisualStudio7Generator::Generate()
{
this->CallVisualStudioMacro(MacroReload);
}
+
+ if (!this->CMakeInstance->GetIsInTryCompile() &&
+ this->GetName() == "Visual Studio 7")
+ {
+ const char* cmakeWarnVS70 =
+ this->CMakeInstance->GetState()->GetCacheEntryValue("CMAKE_WARN_VS70");
+ if (!cmakeWarnVS70 || !cmSystemTools::IsOff(cmakeWarnVS70))
+ {
+ this->CMakeInstance->IssueMessage(
+ cmake::WARNING,
+ "The \"Visual Studio 7\" generator is deprecated "
+ "and will be removed in a future version of CMake."
+ "\n"
+ "Add CMAKE_WARN_VS70=OFF to the cache to disable this warning."
+ );
+ }
+ }
}
void cmGlobalVisualStudio7Generator
::OutputSLNFile(cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators)
{
- if(generators.size() == 0)
+ if(generators.empty())
{
return;
}
- this->CurrentProject = root->GetMakefile()->GetProjectName();
- std::string fname = root->GetMakefile()->GetStartOutputDirectory();
+ this->CurrentProject = root->GetProjectName();
+ std::string fname = root->GetCurrentBinaryDirectory();
fname += "/";
- fname += root->GetMakefile()->GetProjectName();
+ fname += root->GetProjectName();
fname += ".sln";
cmGeneratedFileStream fout(fname.c_str());
fout.SetCopyIfDifferent(true);
@@ -246,7 +383,7 @@ void cmGlobalVisualStudio7Generator
// output the SLN file
void cmGlobalVisualStudio7Generator::OutputSLNFile()
{
- std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it;
+ std::map<std::string, std::vector<cmLocalGenerator*> >::iterator it;
for(it = this->ProjectMap.begin(); it!= this->ProjectMap.end(); ++it)
{
this->OutputSLNFile(it->second[0], it->second);
@@ -256,7 +393,7 @@ void cmGlobalVisualStudio7Generator::OutputSLNFile()
void cmGlobalVisualStudio7Generator::WriteTargetConfigurations(
std::ostream& fout,
- cmLocalGenerator* root,
+ std::vector<std::string> const& configs,
OrderedTargetDependSet const& projectTargets)
{
// loop over again and write out configurations for each target
@@ -264,27 +401,30 @@ void cmGlobalVisualStudio7Generator::WriteTargetConfigurations(
for(OrderedTargetDependSet::const_iterator tt =
projectTargets.begin(); tt != projectTargets.end(); ++tt)
{
- cmTarget* target = *tt;
+ cmGeneratorTarget const* target = *tt;
+ if(target->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ continue;
+ }
const char* expath = target->GetProperty("EXTERNAL_MSPROJECT");
if(expath)
{
- std::set<std::string> allConfigurations(this->Configurations.begin(),
- this->Configurations.end());
+ std::set<std::string> allConfigurations(configs.begin(), configs.end());
+ const char* mapping = target->GetProperty("VS_PLATFORM_MAPPING");
this->WriteProjectConfigurations(
- fout, target->GetName(), target->GetType(),
- allConfigurations, target->GetProperty("VS_PLATFORM_MAPPING"));
+ fout, target->GetName().c_str(), target->GetType(),
+ configs, allConfigurations, mapping ? mapping : "");
}
else
{
const std::set<std::string>& configsPartOfDefaultBuild =
- this->IsPartOfDefaultBuild(root->GetMakefile()->GetProjectName(),
- target);
+ this->IsPartOfDefaultBuild(configs, projectTargets, target);
const char *vcprojName =
target->GetProperty("GENERATOR_FILE_NAME");
if (vcprojName)
{
this->WriteProjectConfigurations(fout, vcprojName, target->GetType(),
- configsPartOfDefaultBuild);
+ configs, configsPartOfDefaultBuild);
}
}
}
@@ -301,7 +441,11 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
for(OrderedTargetDependSet::const_iterator tt =
projectTargets.begin(); tt != projectTargets.end(); ++tt)
{
- cmTarget* target = *tt;
+ cmGeneratorTarget const* target = *tt;
+ if(target->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ continue;
+ }
bool written = false;
// handle external vc project files
@@ -324,8 +468,8 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
target->GetProperty("GENERATOR_FILE_NAME");
if(vcprojName)
{
- cmMakefile* tmf = target->GetMakefile();
- std::string dir = tmf->GetStartOutputDirectory();
+ cmLocalGenerator* lg = target->GetLocalGenerator();
+ std::string dir = lg->GetCurrentBinaryDirectory();
dir = root->Convert(dir.c_str(),
cmLocalGenerator::START_OUTPUT);
if(dir == ".")
@@ -333,7 +477,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
dir = ""; // msbuild cannot handle ".\" prefix
}
this->WriteProject(fout, vcprojName, dir.c_str(),
- *target);
+ target);
written = true;
}
}
@@ -369,8 +513,6 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
cumulativePath = cumulativePath + "/" + *iter;
}
-
- this->CreateGUID(cumulativePath.c_str());
}
if (!cumulativePath.empty())
@@ -391,15 +533,19 @@ void cmGlobalVisualStudio7Generator::WriteTargetDepends(
for(OrderedTargetDependSet::const_iterator tt =
projectTargets.begin(); tt != projectTargets.end(); ++tt)
{
- cmTarget* target = *tt;
- cmMakefile* mf = target->GetMakefile();
+ cmGeneratorTarget const* target = *tt;
+ if(target->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ continue;
+ }
const char *vcprojName =
target->GetProperty("GENERATOR_FILE_NAME");
if (vcprojName)
{
- std::string dir = mf->GetStartDirectory();
+ std::string dir = target->GetLocalGenerator()
+ ->GetCurrentSourceDirectory();
this->WriteProjectDepends(fout, vcprojName,
- dir.c_str(), *target);
+ dir.c_str(), target);
}
}
}
@@ -411,6 +557,9 @@ void cmGlobalVisualStudio7Generator
cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators)
{
+ std::vector<std::string> configs;
+ root->GetMakefile()->GetConfigurations(configs);
+
// Write out the header for a SLN file
this->WriteSLNHeader(fout);
@@ -419,7 +568,7 @@ void cmGlobalVisualStudio7Generator
TargetDependSet projectTargets;
TargetDependSet originalTargets;
this->GetTargetSets(projectTargets, originalTargets, root, generators);
- OrderedTargetDependSet orderedProjectTargets(projectTargets);
+ OrderedTargetDependSet orderedProjectTargets(projectTargets, "ALL_BUILD");
this->WriteTargetsToSolution(fout, root, orderedProjectTargets);
@@ -434,8 +583,8 @@ void cmGlobalVisualStudio7Generator
<< "\tGlobalSection(SolutionConfiguration) = preSolution\n";
int c = 0;
- for(std::vector<std::string>::iterator i = this->Configurations.begin();
- i != this->Configurations.end(); ++i)
+ for(std::vector<std::string>::iterator i = configs.begin();
+ i != configs.end(); ++i)
{
fout << "\t\tConfigName." << c << " = " << *i << "\n";
c++;
@@ -456,7 +605,7 @@ void cmGlobalVisualStudio7Generator
// Write out the configurations for all the targets in the project
fout << "\tGlobalSection(ProjectConfiguration) = postSolution\n";
- this->WriteTargetConfigurations(fout, root, orderedProjectTargets);
+ this->WriteTargetConfigurations(fout, configs, orderedProjectTargets);
fout << "\tEndGlobalSection\n";
// Write out global sections
@@ -535,8 +684,9 @@ cmGlobalVisualStudio7Generator::ConvertToSolutionPath(const char* path)
// Note, that dependencies from executables to
// the libraries it uses are also done here
void cmGlobalVisualStudio7Generator::WriteProject(std::ostream& fout,
- const char* dspname,
- const char* dir, cmTarget& target)
+ const std::string& dspname,
+ const char* dir,
+ cmGeneratorTarget const* target)
{
// check to see if this is a fortran build
const char* ext = ".vcproj";
@@ -554,7 +704,7 @@ void cmGlobalVisualStudio7Generator::WriteProject(std::ostream& fout,
<< dspname << ext << "\", \"{"
<< this->GetGUID(dspname) << "}\"\nEndProject\n";
- UtilityDependsMap::iterator ui = this->UtilityDepends.find(&target);
+ UtilityDependsMap::iterator ui = this->UtilityDepends.find(target);
if(ui != this->UtilityDepends.end())
{
const char* uname = ui->second.c_str();
@@ -575,21 +725,21 @@ void cmGlobalVisualStudio7Generator::WriteProject(std::ostream& fout,
void
cmGlobalVisualStudio7Generator
::WriteProjectDepends(std::ostream& fout,
- const char* dspname,
- const char*, cmTarget& target)
+ const std::string& dspname,
+ const char*, cmGeneratorTarget const* target)
{
int depcount = 0;
std::string dspguid = this->GetGUID(dspname);
- VSDependSet const& depends = this->VSTargetDepends[&target];
+ VSDependSet const& depends = this->VSTargetDepends[target];
for(VSDependSet::const_iterator di = depends.begin();
di != depends.end(); ++di)
{
const char* name = di->c_str();
std::string guid = this->GetGUID(name);
- if(guid.size() == 0)
+ if(guid.empty())
{
std::string m = "Target: ";
- m += target.GetName();
+ m += target->GetName();
m += " depends on unknown target: ";
m += name;
cmSystemTools::Error(m.c_str());
@@ -598,7 +748,7 @@ cmGlobalVisualStudio7Generator
depcount++;
}
- UtilityDependsMap::iterator ui = this->UtilityDepends.find(&target);
+ UtilityDependsMap::iterator ui = this->UtilityDepends.find(target);
if(ui != this->UtilityDepends.end())
{
const char* uname = ui->second.c_str();
@@ -611,15 +761,16 @@ cmGlobalVisualStudio7Generator
// executables to the libraries it uses are also done here
void cmGlobalVisualStudio7Generator
::WriteProjectConfigurations(
- std::ostream& fout, const char* name, cmTarget::TargetType,
+ std::ostream& fout, const std::string& name, cmState::TargetType,
+ std::vector<std::string> const& configs,
const std::set<std::string>& configsPartOfDefaultBuild,
- const char* platformMapping)
+ const std::string& platformMapping)
{
- const char* platformName =
- platformMapping ? platformMapping : this->GetPlatformName();
+ const std::string& platformName =
+ !platformMapping.empty() ? platformMapping : this->GetPlatformName();
std::string guid = this->GetGUID(name);
- for(std::vector<std::string>::iterator i = this->Configurations.begin();
- i != this->Configurations.end(); ++i)
+ for(std::vector<std::string>::const_iterator i = configs.begin();
+ i != configs.end(); ++i)
{
fout << "\t\t{" << guid << "}." << *i
<< ".ActiveCfg = " << *i << "|" << platformName << "\n";
@@ -639,15 +790,14 @@ void cmGlobalVisualStudio7Generator
// Note, that dependencies from executables to
// the libraries it uses are also done here
void cmGlobalVisualStudio7Generator::WriteExternalProject(std::ostream& fout,
- const char* name,
+ const std::string& name,
const char* location,
const char* typeGuid,
- const std::set<cmStdString>&)
+ const std::set<std::string>&)
{
- std::string d = cmSystemTools::ConvertToOutputPath(location);
fout << "Project("
<< "\"{"
- << (typeGuid ? typeGuid : "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942")
+ << (typeGuid ? typeGuid : this->ExternalProjectType(location))
<< "}\") = \""
<< name << "\", \""
<< this->ConvertToSolutionPath(location) << "\", \"{"
@@ -664,14 +814,15 @@ void cmGlobalVisualStudio7Generator
{
bool extensibilityGlobalsOverridden = false;
bool extensibilityAddInsOverridden = false;
- const cmPropertyMap& props = root->GetMakefile()->GetProperties();
- for(cmPropertyMap::const_iterator itProp = props.begin();
- itProp != props.end(); ++itProp)
+ const std::vector<std::string> propKeys =
+ root->GetMakefile()->GetPropertyKeys();
+ for(std::vector<std::string>::const_iterator it = propKeys.begin();
+ it != propKeys.end(); ++it)
{
- if(itProp->first.find("VS_GLOBAL_SECTION_") == 0)
+ if(it->find("VS_GLOBAL_SECTION_") == 0)
{
std::string sectionType;
- std::string name = itProp->first.substr(18);
+ std::string name = it->substr(18);
if(name.find("PRE_") == 0)
{
name = name.substr(4);
@@ -692,8 +843,9 @@ void cmGlobalVisualStudio7Generator
extensibilityAddInsOverridden = true;
fout << "\tGlobalSection(" << name << ") = " << sectionType << "\n";
std::vector<std::string> keyValuePairs;
- cmSystemTools::ExpandListArgument(itProp->second.GetValue(),
- keyValuePairs);
+ cmSystemTools::ExpandListArgument(
+ root->GetMakefile()->GetProperty(it->c_str()),
+ keyValuePairs);
for(std::vector<std::string>::const_iterator itPair =
keyValuePairs.begin(); itPair != keyValuePairs.end(); ++itPair)
{
@@ -736,21 +888,24 @@ void cmGlobalVisualStudio7Generator::WriteSLNHeader(std::ostream& fout)
//----------------------------------------------------------------------------
std::string
-cmGlobalVisualStudio7Generator::WriteUtilityDepend(cmTarget* target)
+cmGlobalVisualStudio7Generator::WriteUtilityDepend(
+ cmGeneratorTarget const* target)
{
+ std::vector<std::string> configs;
+ target->Target->GetMakefile()->GetConfigurations(configs);
std::string pname = target->GetName();
pname += "_UTILITY";
- std::string fname = target->GetMakefile()->GetStartOutputDirectory();
+ std::string fname = target->GetLocalGenerator()->GetCurrentBinaryDirectory();
fname += "/";
fname += pname;
fname += ".vcproj";
cmGeneratedFileStream fout(fname.c_str());
fout.SetCopyIfDifferent(true);
- this->CreateGUID(pname.c_str());
std::string guid = this->GetGUID(pname.c_str());
fout <<
- "<?xml version=\"1.0\" encoding = \"Windows-1252\"?>\n"
+ "<?xml version=\"1.0\" encoding = \""
+ << this->Encoding() << "\"?>\n"
"<VisualStudioProject\n"
"\tProjectType=\"Visual C++\"\n"
"\tVersion=\"" << this->GetIDEVersion() << "0\"\n"
@@ -760,8 +915,8 @@ cmGlobalVisualStudio7Generator::WriteUtilityDepend(cmTarget* target)
"\t<Platforms><Platform Name=\"Win32\"/></Platforms>\n"
"\t<Configurations>\n"
;
- for(std::vector<std::string>::iterator i = this->Configurations.begin();
- i != this->Configurations.end(); ++i)
+ for(std::vector<std::string>::iterator i = configs.begin();
+ i != configs.end(); ++i)
{
fout <<
"\t\t<Configuration\n"
@@ -789,66 +944,48 @@ cmGlobalVisualStudio7Generator::WriteUtilityDepend(cmTarget* target)
return pname;
}
-std::string cmGlobalVisualStudio7Generator::GetGUID(const char* name)
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudio7Generator::GetGUID(std::string const& name)
{
- std::string guidStoreName = name;
- guidStoreName += "_GUID_CMAKE";
- const char* storedGUID =
- this->CMakeInstance->GetCacheDefinition(guidStoreName.c_str());
- if(storedGUID)
+ std::string const& guidStoreName = name + "_GUID_CMAKE";
+ if (const char* storedGUID =
+ this->CMakeInstance->GetCacheDefinition(guidStoreName.c_str()))
{
return std::string(storedGUID);
}
- cmSystemTools::Error("Unknown Target referenced : ",
- name);
- return "";
-}
+ // Compute a GUID that is deterministic but unique to the build tree.
+ std::string input = this->CMakeInstance->GetState()->GetBinaryDirectory();
+ input += "|";
+ input += name;
+ cmUuid uuidGenerator;
-void cmGlobalVisualStudio7Generator::CreateGUID(const char* name)
-{
- std::string guidStoreName = name;
- guidStoreName += "_GUID_CMAKE";
- if(this->CMakeInstance->GetCacheDefinition(guidStoreName.c_str()))
- {
- return;
- }
- std::string ret;
- UUID uid;
- unsigned char *uidstr;
- UuidCreate(&uid);
- UuidToString(&uid,&uidstr);
- ret = reinterpret_cast<char*>(uidstr);
- RpcStringFree(&uidstr);
- ret = cmSystemTools::UpperCase(ret);
- this->CMakeInstance->AddCacheEntry(guidStoreName.c_str(),
- ret.c_str(), "Stored GUID",
- cmCacheManager::INTERNAL);
-}
+ std::vector<unsigned char> uuidNamespace;
+ uuidGenerator.StringToBinary(
+ "ee30c4be-5192-4fb0-b335-722a2dffe760", uuidNamespace);
-std::vector<std::string> *cmGlobalVisualStudio7Generator::GetConfigurations()
-{
- return &this->Configurations;
-};
+ std::string guid = uuidGenerator.FromMd5(uuidNamespace, input);
+
+ return cmSystemTools::UpperCase(guid);
+}
//----------------------------------------------------------------------------
void cmGlobalVisualStudio7Generator
::GetDocumentation(cmDocumentationEntry& entry)
{
entry.Name = cmGlobalVisualStudio7Generator::GetActualName();
- entry.Brief = "Generates Visual Studio .NET 2002 project files.";
- entry.Full = "";
+ entry.Brief = "Deprecated. Generates Visual Studio .NET 2002 project files.";
}
//----------------------------------------------------------------------------
void
cmGlobalVisualStudio7Generator
-::AppendDirectoryForConfig(const char* prefix,
- const char* config,
- const char* suffix,
+::AppendDirectoryForConfig(const std::string& prefix,
+ const std::string& config,
+ const std::string& suffix,
std::string& dir)
{
- if(config)
+ if(!config.empty())
{
dir += prefix;
dir += config;
@@ -857,24 +994,45 @@ cmGlobalVisualStudio7Generator
}
std::set<std::string>
-cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(const char* project,
- cmTarget* target)
+cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(
+ std::vector<std::string> const& configs,
+ OrderedTargetDependSet const& projectTargets,
+ cmGeneratorTarget const* target)
{
std::set<std::string> activeConfigs;
// if it is a utilitiy target then only make it part of the
// default build if another target depends on it
int type = target->GetType();
- if (type == cmTarget::GLOBAL_TARGET)
+ if (type == cmState::GLOBAL_TARGET)
{
+ // check if INSTALL target is part of default build
+ if(target->GetName() == "INSTALL")
+ {
+ // inspect CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD properties
+ for(std::vector<std::string>::const_iterator i = configs.begin();
+ i != configs.end(); ++i)
+ {
+ const char* propertyValue = target->Target->GetMakefile()
+ ->GetDefinition("CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD");
+ cmGeneratorExpression ge;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression>
+ cge = ge.Parse(propertyValue);
+ if(cmSystemTools::IsOn(cge->Evaluate(target->GetLocalGenerator(),
+ *i)))
+ {
+ activeConfigs.insert(*i);
+ }
+ }
+ }
return activeConfigs;
}
- if(type == cmTarget::UTILITY && !this->IsDependedOn(project, target))
+ if(type == cmState::UTILITY && !this->IsDependedOn(projectTargets, target))
{
return activeConfigs;
}
// inspect EXCLUDE_FROM_DEFAULT_BUILD[_<CONFIG>] properties
- for(std::vector<std::string>::iterator i = this->Configurations.begin();
- i != this->Configurations.end(); ++i)
+ for(std::vector<std::string>::const_iterator i = configs.begin();
+ i != configs.end(); ++i)
{
const char* propertyValue =
target->GetFeature("EXCLUDE_FROM_DEFAULT_BUILD", i->c_str());
@@ -886,32 +1044,30 @@ cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(const char* project,
return activeConfigs;
}
-//----------------------------------------------------------------------------
-static cmVS7FlagTable cmVS7ExtraFlagTable[] =
+bool
+cmGlobalVisualStudio7Generator
+::IsDependedOn(OrderedTargetDependSet const& projectTargets,
+ cmGeneratorTarget const* gtIn)
{
- // Precompiled header and related options. Note that the
- // UsePrecompiledHeader entries are marked as "Continue" so that the
- // corresponding PrecompiledHeaderThrough entry can be found.
- {"UsePrecompiledHeader", "YX", "Automatically Generate", "2",
- cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
- {"PrecompiledHeaderThrough", "YX", "Precompiled Header Name", "",
- cmVS7FlagTable::UserValueRequired},
- {"UsePrecompiledHeader", "Yu", "Use Precompiled Header", "3",
- cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
- {"PrecompiledHeaderThrough", "Yu", "Precompiled Header Name", "",
- cmVS7FlagTable::UserValueRequired},
- {"WholeProgramOptimization", "LTCG", "WholeProgramOptimization", "TRUE", 0},
-
- // Exception handling mode. If no entries match, it will be FALSE.
- {"ExceptionHandling", "GX", "enable c++ exceptions", "TRUE", 0},
- {"ExceptionHandling", "EHsc", "enable c++ exceptions", "TRUE", 0},
- // The EHa option does not have an IDE setting. Let it go to false,
- // and have EHa passed on the command line by leaving out the table
- // entry.
+ for (OrderedTargetDependSet::const_iterator l = projectTargets.begin();
+ l != projectTargets.end(); ++l)
+ {
+ TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(*l);
+ if(tgtdeps.count(gtIn))
+ {
+ return true;
+ }
+ }
+ return false;
+}
- {0,0,0,0,0}
-};
-cmIDEFlagTable const* cmGlobalVisualStudio7Generator::GetExtraFlagTableVS7()
+std::string cmGlobalVisualStudio7Generator::Encoding()
{
- return cmVS7ExtraFlagTable;
+ std::ostringstream encoding;
+#ifdef CMAKE_ENCODING_UTF8
+ encoding << "UTF-8";
+#else
+ encoding << "Windows-1252";
+#endif
+ return encoding.str();
}
diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h
index 4d22cff88..de2d35e99 100644
--- a/Source/cmGlobalVisualStudio7Generator.h
+++ b/Source/cmGlobalVisualStudio7Generator.h
@@ -26,29 +26,40 @@ struct cmIDEFlagTable;
class cmGlobalVisualStudio7Generator : public cmGlobalVisualStudioGenerator
{
public:
- cmGlobalVisualStudio7Generator(const char* platformName = NULL);
+ cmGlobalVisualStudio7Generator(cmake* cm,
+ const std::string& platformName = "");
+ ~cmGlobalVisualStudio7Generator();
+
static cmGlobalGeneratorFactory* NewFactory() {
return new cmGlobalGeneratorSimpleFactory
<cmGlobalVisualStudio7Generator>(); }
///! Get the name for the generator.
- virtual const char* GetName() const {
+ virtual std::string GetName() const {
return cmGlobalVisualStudio7Generator::GetActualName();}
- static const char* GetActualName() {return "Visual Studio 7";}
+ static std::string GetActualName() {return "Visual Studio 7";}
///! Get the name for the platform.
- const char* GetPlatformName() const { return this->PlatformName.c_str(); }
+ std::string const& GetPlatformName() const;
///! Create a local generator appropriate to this Global Generator
- virtual cmLocalGenerator *CreateLocalGenerator();
+ virtual cmLocalGenerator *CreateLocalGenerator(cmMakefile* mf);
+
+ virtual bool SetSystemName(std::string const& s, cmMakefile* mf);
- virtual void AddPlatformDefinitions(cmMakefile* mf);
+ virtual bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf);
/** Get the documentation entry for this generator. */
static void GetDocumentation(cmDocumentationEntry& entry);
/**
- * Try to determine system infomation such as shared library
+ * Utilized by the generator factory to determine if this generator
+ * supports toolsets.
+ */
+ static bool SupportsToolset() { return false; }
+
+ /**
+ * Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
@@ -58,70 +69,81 @@ public:
* Try running cmake and building a file. This is used for dynamically
* loaded commands, not as part of the usual build process.
*/
- virtual std::string GenerateBuildCommand(const char* makeProgram,
- const char *projectName,
- const char *projectDir,
- const char* additionalOptions,
- const char *targetName,
- const char* config,
- bool ignoreErrors,
- bool fast);
-
- /**
- * Generate the all required files for building this project/tree. This
- * basically creates a series of LocalGenerators for each directory and
- * requests that they Generate.
- */
- virtual void Generate();
+ virtual void GenerateBuildCommand(
+ std::vector<std::string>& makeCommand,
+ const std::string& makeProgram,
+ const std::string& projectName,
+ const std::string& projectDir,
+ const std::string& targetName,
+ const std::string& config,
+ bool fast, bool verbose,
+ std::vector<std::string> const& makeOptions = std::vector<std::string>()
+ );
/**
* Generate the DSW workspace file.
*/
virtual void OutputSLNFile();
- /**
- * Get the list of configurations
- */
- std::vector<std::string> *GetConfigurations();
-
- ///! Create a GUID or get an existing one.
- void CreateGUID(const char* name);
- std::string GetGUID(const char* name);
+ ///! Lookup a stored GUID or compute one deterministically.
+ std::string GetGUID(std::string const& name);
/** Append the subdirectory for the given configuration. */
- virtual void AppendDirectoryForConfig(const char* prefix,
- const char* config,
- const char* suffix,
+ virtual void AppendDirectoryForConfig(const std::string& prefix,
+ const std::string& config,
+ const std::string& suffix,
std::string& dir);
///! What is the configurations directory variable called?
- virtual const char* GetCMakeCFGIntDir() const { return "$(OutDir)"; }
+ virtual const char* GetCMakeCFGIntDir() const
+ { return "$(ConfigurationName)"; }
/** Return true if the target project file should have the option
LinkLibraryDependencies and link to .sln dependencies. */
- virtual bool NeedLinkLibraryDependencies(cmTarget&) { return false; }
+ virtual bool NeedLinkLibraryDependencies(cmGeneratorTarget*)
+ { return false; }
+
+ const char* GetIntelProjectVersion();
+
+ virtual void FindMakeProgram(cmMakefile*);
+
+ /** Is the Microsoft Assembler enabled? */
+ bool IsMasmEnabled() const { return this->MasmEnabled; }
+
+ // Encoding for Visual Studio files
+ virtual std::string Encoding();
+
+ cmIDEFlagTable const* ExtraFlagTable;
protected:
+ virtual void Generate();
virtual const char* GetIDEVersion() { return "7.0"; }
- static cmIDEFlagTable const* GetExtraFlagTableVS7();
+ std::string const& GetDevEnvCommand();
+ virtual std::string FindDevEnvCommand();
+
+ static const char* ExternalProjectType(const char* location);
+
virtual void OutputSLNFile(cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators);
virtual void WriteSLNFile(std::ostream& fout, cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators);
virtual void WriteProject(std::ostream& fout,
- const char* name, const char* path, cmTarget &t);
+ const std::string& name, const char* path,
+ const cmGeneratorTarget *t);
virtual void WriteProjectDepends(std::ostream& fout,
- const char* name, const char* path, cmTarget &t);
+ const std::string& name, const char* path,
+ cmGeneratorTarget const* t);
virtual void WriteProjectConfigurations(
- std::ostream& fout, const char* name, cmTarget::TargetType type,
+ std::ostream& fout, const std::string& name, cmState::TargetType type,
+ std::vector<std::string> const& configs,
const std::set<std::string>& configsPartOfDefaultBuild,
- const char* platformMapping = NULL);
+ const std::string& platformMapping = "");
virtual void WriteSLNGlobalSections(std::ostream& fout,
cmLocalGenerator* root);
virtual void WriteSLNFooter(std::ostream& fout);
virtual void WriteSLNHeader(std::ostream& fout);
- virtual std::string WriteUtilityDepend(cmTarget* target);
+ virtual std::string WriteUtilityDepend(const cmGeneratorTarget *target);
virtual void WriteTargetsToSolution(
std::ostream& fout,
@@ -132,24 +154,25 @@ protected:
OrderedTargetDependSet const& projectTargets);
virtual void WriteTargetConfigurations(
std::ostream& fout,
- cmLocalGenerator* root,
+ std::vector<std::string> const& configs,
OrderedTargetDependSet const& projectTargets);
- void GenerateConfigurations(cmMakefile* mf);
-
virtual void WriteExternalProject(std::ostream& fout,
- const char* name,
+ const std::string& name,
const char* path,
const char* typeGuid,
- const std::set<cmStdString>&
+ const std::set<std::string>&
dependencies);
std::string ConvertToSolutionPath(const char* path);
- std::set<std::string> IsPartOfDefaultBuild(const char* project,
- cmTarget* target);
- std::vector<std::string> Configurations;
- std::map<cmStdString, cmStdString> GUIDMap;
+ std::set<std::string>
+ IsPartOfDefaultBuild(std::vector<std::string> const& configs,
+ OrderedTargetDependSet const& projectTargets,
+ cmGeneratorTarget const* target);
+ bool IsDependedOn(OrderedTargetDependSet const& projectTargets,
+ cmGeneratorTarget const* target);
+ std::map<std::string, std::string> GUIDMap;
virtual void WriteFolders(std::ostream& fout);
virtual void WriteFoldersContent(std::ostream& fout);
@@ -158,7 +181,15 @@ protected:
// Set during OutputSLNFile with the name of the current project.
// There is one SLN file per project.
std::string CurrentProject;
- std::string PlatformName;
+ std::string GeneratorPlatform;
+ std::string DefaultPlatformName;
+ bool MasmEnabled;
+
+private:
+ char* IntelProjectVersion;
+ std::string DevEnvCommand;
+ bool DevEnvCommandInitialized;
+ virtual std::string GetVSMakeProgram() { return this->GetDevEnvCommand(); }
};
#define CMAKE_CHECK_BUILD_SYSTEM_TARGET "ZERO_CHECK"
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index e4244e062..3abff6cb5 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -16,6 +16,7 @@
#include "cmVisualStudioWCEPlatformParser.h"
#include "cmake.h"
#include "cmGeneratedFileStream.h"
+#include "cmSourceFile.h"
static const char vs8generatorName[] = "Visual Studio 8 2005";
@@ -23,17 +24,18 @@ class cmGlobalVisualStudio8Generator::Factory
: public cmGlobalGeneratorFactory
{
public:
- virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const {
- if(strstr(name, vs8generatorName) != name)
+ virtual cmGlobalGenerator*
+ CreateGlobalGenerator(const std::string& name, cmake* cm) const {
+ if(strncmp(name.c_str(), vs8generatorName,
+ sizeof(vs8generatorName) - 1) != 0)
{
return 0;
}
- const char* p = name + sizeof(vs8generatorName) - 1;
+ const char* p = name.c_str() + sizeof(vs8generatorName) - 1;
if(p[0] == '\0')
{
- return new cmGlobalVisualStudio8Generator(
- name, NULL, NULL);
+ return new cmGlobalVisualStudio8Generator(cm, name, "");
}
if(p[0] != ' ')
@@ -45,8 +47,7 @@ public:
if(!strcmp(p, "Win64"))
{
- return new cmGlobalVisualStudio8Generator(
- name, "x64", "CMAKE_FORCE_WIN64");
+ return new cmGlobalVisualStudio8Generator(cm, name, "x64");
}
cmVisualStudioWCEPlatformParser parser(p);
@@ -56,20 +57,18 @@ public:
return 0;
}
- cmGlobalVisualStudio8Generator* ret = new cmGlobalVisualStudio8Generator(
- name, p, NULL);
+ cmGlobalVisualStudio8Generator* ret =
+ new cmGlobalVisualStudio8Generator(cm, name, p);
ret->WindowsCEVersion = parser.GetOSVersion();
return ret;
}
virtual void GetDocumentation(cmDocumentationEntry& entry) const {
- entry.Name = vs8generatorName;
- entry.Brief = "Generates Visual Studio 8 2005 project files.";
- entry.Full =
- "It is possible to append a space followed by the platform name "
- "to create project files for a specific target platform. E.g. "
- "\"Visual Studio 8 2005 Win64\" will create project files for "
- "the x64 processor.";
+ entry.Name = std::string(vs8generatorName) + " [arch]";
+ entry.Brief =
+ "Generates Visual Studio 2005 project files. "
+ "Optional [arch] can be \"Win64\"."
+ ;
}
virtual void GetGenerators(std::vector<std::string>& names) const {
@@ -85,6 +84,8 @@ public:
names.push_back("Visual Studio 8 2005 " + *i);
}
}
+
+ virtual bool SupportsToolset() const { return false; }
};
//----------------------------------------------------------------------------
@@ -94,38 +95,56 @@ cmGlobalGeneratorFactory* cmGlobalVisualStudio8Generator::NewFactory()
}
//----------------------------------------------------------------------------
-cmGlobalVisualStudio8Generator::cmGlobalVisualStudio8Generator(
- const char* name, const char* platformName,
- const char* additionalPlatformDefinition)
- : cmGlobalVisualStudio71Generator(platformName)
+cmGlobalVisualStudio8Generator::cmGlobalVisualStudio8Generator(cmake* cm,
+ const std::string& name, const std::string& platformName)
+ : cmGlobalVisualStudio71Generator(cm, platformName)
{
- this->FindMakeProgramFile = "CMakeVS8FindMake.cmake";
this->ProjectConfigurationSectionName = "ProjectConfigurationPlatforms";
this->Name = name;
+ this->ExtraFlagTable = this->GetExtraFlagTableVS8();
+ this->Version = VS8;
+}
- if (additionalPlatformDefinition)
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudio8Generator::FindDevEnvCommand()
+{
+ // First look for VCExpress.
+ std::string vsxcmd;
+ std::string vsxkey =
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\";
+ vsxkey += this->GetIDEVersion();
+ vsxkey += ";InstallDir";
+ if(cmSystemTools::ReadRegistryValue(vsxkey.c_str(), vsxcmd,
+ cmSystemTools::KeyWOW64_32))
{
- this->AdditionalPlatformDefinition = additionalPlatformDefinition;
+ cmSystemTools::ConvertToUnixSlashes(vsxcmd);
+ vsxcmd += "/VCExpress.exe";
+ return vsxcmd;
}
+ // Now look for devenv.
+ return this->cmGlobalVisualStudio71Generator::FindDevEnvCommand();
}
//----------------------------------------------------------------------------
-///! Create a local generator appropriate to this Global Generator
-cmLocalGenerator *cmGlobalVisualStudio8Generator::CreateLocalGenerator()
+void cmGlobalVisualStudio8Generator
+::EnableLanguage(std::vector<std::string>const & lang,
+ cmMakefile *mf, bool optional)
{
- cmLocalVisualStudio7Generator *lg =
- new cmLocalVisualStudio7Generator(cmLocalVisualStudioGenerator::VS8);
- lg->SetPlatformName(this->GetPlatformName());
- lg->SetExtraFlagTable(this->GetExtraFlagTableVS8());
- lg->SetGlobalGenerator(this);
- return lg;
+ for(std::vector<std::string>::const_iterator it = lang.begin();
+ it != lang.end(); ++it)
+ {
+ if(*it == "ASM_MASM")
+ {
+ this->MasmEnabled = true;
+ }
+ }
+ this->AddPlatformDefinitions(mf);
+ cmGlobalVisualStudio7Generator::EnableLanguage(lang, mf, optional);
}
//----------------------------------------------------------------------------
void cmGlobalVisualStudio8Generator::AddPlatformDefinitions(cmMakefile* mf)
{
- cmGlobalVisualStudio71Generator::AddPlatformDefinitions(mf);
-
if(this->TargetsWindowsCE())
{
mf->AddDefinition("CMAKE_VS_WINCE_VERSION",
@@ -134,6 +153,21 @@ void cmGlobalVisualStudio8Generator::AddPlatformDefinitions(cmMakefile* mf)
}
//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio8Generator::SetGeneratorPlatform(std::string const& p,
+ cmMakefile* mf)
+{
+ if(this->DefaultPlatformName == "Win32")
+ {
+ this->GeneratorPlatform = p;
+ return this->cmGlobalVisualStudio7Generator::SetGeneratorPlatform("", mf);
+ }
+ else
+ {
+ return this->cmGlobalVisualStudio7Generator::SetGeneratorPlatform(p, mf);
+ }
+}
+
+//----------------------------------------------------------------------------
// ouput standard header for dsw file
void cmGlobalVisualStudio8Generator::WriteSLNHeader(std::ostream& fout)
{
@@ -147,14 +181,12 @@ void cmGlobalVisualStudio8Generator
{
entry.Name = cmGlobalVisualStudio8Generator::GetActualName();
entry.Brief = "Generates Visual Studio 8 2005 project files.";
- entry.Full = "";
}
//----------------------------------------------------------------------------
void cmGlobalVisualStudio8Generator::Configure()
{
this->cmGlobalVisualStudio7Generator::Configure();
- this->CreateGUID(CMAKE_CHECK_BUILD_SYSTEM_TARGET);
}
//----------------------------------------------------------------------------
@@ -202,7 +234,7 @@ std::string cmGlobalVisualStudio8Generator::GetUserMacrosRegKeyBase()
}
//----------------------------------------------------------------------------
-void cmGlobalVisualStudio8Generator::AddCheckTarget()
+bool cmGlobalVisualStudio8Generator::AddCheckTarget()
{
// Add a special target on which all other targets depend that
// checks the build system and optionally re-runs CMake.
@@ -216,16 +248,18 @@ void cmGlobalVisualStudio8Generator::AddCheckTarget()
// Skip the target if no regeneration is to be done.
if(mf->IsOn("CMAKE_SUPPRESS_REGENERATION"))
{
- return;
+ return false;
}
- std::string cmake_command = mf->GetRequiredDefinition("CMAKE_COMMAND");
cmCustomCommandLines noCommandLines;
cmTarget* tgt =
mf->AddUtilityCommand(CMAKE_CHECK_BUILD_SYSTEM_TARGET, false,
no_working_directory, no_depends,
noCommandLines);
+ cmGeneratorTarget* gt = new cmGeneratorTarget(tgt, lg);
+ lg->AddGeneratorTarget(gt);
+
// Organize in the "predefined targets" folder:
//
if (this->UseFolderProperty())
@@ -239,7 +273,7 @@ void cmGlobalVisualStudio8Generator::AddCheckTarget()
stampList += "generate.stamp.list";
{
std::string stampListFile =
- generators[0]->GetMakefile()->GetCurrentOutputDirectory();
+ generators[0]->GetMakefile()->GetCurrentBinaryDirectory();
stampListFile += "/";
stampListFile += stampList;
std::string stampFile;
@@ -247,7 +281,7 @@ void cmGlobalVisualStudio8Generator::AddCheckTarget()
for(std::vector<cmLocalGenerator*>::const_iterator
gi = generators.begin(); gi != generators.end(); ++gi)
{
- stampFile = (*gi)->GetMakefile()->GetCurrentOutputDirectory();
+ stampFile = (*gi)->GetMakefile()->GetCurrentBinaryDirectory();
stampFile += "/";
stampFile += cmake::GetCMakeFilesDirectoryPostSlash();
stampFile += "generate.stamp";
@@ -277,18 +311,13 @@ void cmGlobalVisualStudio8Generator::AddCheckTarget()
// Create a rule to re-run CMake.
std::string stampName = cmake::GetCMakeFilesDirectoryPostSlash();
stampName += "generate.stamp";
- const char* dsprule = mf->GetRequiredDefinition("CMAKE_COMMAND");
cmCustomCommandLine commandLine;
- commandLine.push_back(dsprule);
+ commandLine.push_back(cmSystemTools::GetCMakeCommand());
std::string argH = "-H";
- argH += lg->Convert(mf->GetHomeDirectory(),
- cmLocalGenerator::START_OUTPUT,
- cmLocalGenerator::UNCHANGED, true);
+ argH += lg->GetSourceDirectory();
commandLine.push_back(argH);
std::string argB = "-B";
- argB += lg->Convert(mf->GetHomeOutputDirectory(),
- cmLocalGenerator::START_OUTPUT,
- cmLocalGenerator::UNCHANGED, true);
+ argB += lg->GetBinaryDirectory();
commandLine.push_back(argB);
commandLine.push_back("--check-stamp-list");
commandLine.push_back(stampList.c_str());
@@ -301,50 +330,57 @@ void cmGlobalVisualStudio8Generator::AddCheckTarget()
// file as the main dependency because it would get
// overwritten by the CreateVCProjBuildRule.
// (this could be avoided with per-target source files)
- const char* no_main_dependency = 0;
+ std::string no_main_dependency = "";
+ std::vector<std::string> no_byproducts;
if(cmSourceFile* file =
mf->AddCustomCommandToOutput(
- stamps, listFiles,
+ stamps, no_byproducts, listFiles,
no_main_dependency, commandLines, "Checking Build System",
no_working_directory, true))
{
- tgt->AddSourceFile(file);
+ gt->AddSource(file->GetFullPath());
}
else
{
cmSystemTools::Error("Error adding rule for ", stamps[0].c_str());
}
}
+
+ return true;
}
//----------------------------------------------------------------------------
-void cmGlobalVisualStudio8Generator::Generate()
+void cmGlobalVisualStudio8Generator::AddExtraIDETargets()
{
- this->AddCheckTarget();
-
- // All targets depend on the build-system check target.
- for(std::map<cmStdString,cmTarget *>::const_iterator
- ti = this->TotalTargets.begin();
- ti != this->TotalTargets.end(); ++ti)
+ cmGlobalVisualStudio7Generator::AddExtraIDETargets();
+ if(this->AddCheckTarget())
{
- if(ti->first != CMAKE_CHECK_BUILD_SYSTEM_TARGET)
+ for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i)
{
- ti->second->AddUtility(CMAKE_CHECK_BUILD_SYSTEM_TARGET);
+ std::vector<cmGeneratorTarget*> tgts =
+ this->LocalGenerators[i]->GetGeneratorTargets();
+ // All targets depend on the build-system check target.
+ for(std::vector<cmGeneratorTarget*>::iterator ti = tgts.begin();
+ ti != tgts.end(); ++ti)
+ {
+ if((*ti)->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET)
+ {
+ (*ti)->Target->AddUtility(CMAKE_CHECK_BUILD_SYSTEM_TARGET);
+ }
+ }
}
}
-
- // Now perform the main generation.
- this->cmGlobalVisualStudio7Generator::Generate();
}
//----------------------------------------------------------------------------
void
cmGlobalVisualStudio8Generator
-::WriteSolutionConfigurations(std::ostream& fout)
+::WriteSolutionConfigurations(std::ostream& fout,
+ std::vector<std::string> const& configs)
{
fout << "\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n";
- for(std::vector<std::string>::iterator i = this->Configurations.begin();
- i != this->Configurations.end(); ++i)
+ for(std::vector<std::string>::const_iterator i = configs.begin();
+ i != configs.end(); ++i)
{
fout << "\t\t" << *i << "|" << this->GetPlatformName()
<< " = " << *i << "|" << this->GetPlatformName() << "\n";
@@ -356,17 +392,19 @@ cmGlobalVisualStudio8Generator
void
cmGlobalVisualStudio8Generator
::WriteProjectConfigurations(
- std::ostream& fout, const char* name, cmTarget::TargetType type,
+ std::ostream& fout, const std::string& name, cmState::TargetType type,
+ std::vector<std::string> const& configs,
const std::set<std::string>& configsPartOfDefaultBuild,
- const char* platformMapping)
+ std::string const& platformMapping)
{
std::string guid = this->GetGUID(name);
- for(std::vector<std::string>::iterator i = this->Configurations.begin();
- i != this->Configurations.end(); ++i)
+ for(std::vector<std::string>::const_iterator i = configs.begin();
+ i != configs.end(); ++i)
{
fout << "\t\t{" << guid << "}." << *i
<< "|" << this->GetPlatformName() << ".ActiveCfg = " << *i << "|"
- << (platformMapping ? platformMapping : this->GetPlatformName())
+ << (!platformMapping.empty()?
+ platformMapping : this->GetPlatformName())
<< "\n";
std::set<std::string>::const_iterator
ci = configsPartOfDefaultBuild.find(*i);
@@ -374,22 +412,31 @@ cmGlobalVisualStudio8Generator
{
fout << "\t\t{" << guid << "}." << *i
<< "|" << this->GetPlatformName() << ".Build.0 = " << *i << "|"
- << (platformMapping ? platformMapping : this->GetPlatformName())
+ << (!platformMapping.empty()?
+ platformMapping : this->GetPlatformName())
<< "\n";
}
- bool needsDeploy = (type == cmTarget::EXECUTABLE ||
- type == cmTarget::SHARED_LIBRARY);
- if(this->TargetsWindowsCE() && needsDeploy)
+ if(this->NeedsDeploy(type))
{
fout << "\t\t{" << guid << "}." << *i
<< "|" << this->GetPlatformName() << ".Deploy.0 = " << *i << "|"
- << (platformMapping ? platformMapping : this->GetPlatformName())
+ << (!platformMapping.empty()?
+ platformMapping : this->GetPlatformName())
<< "\n";
}
}
}
//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio8Generator::NeedsDeploy(cmState::TargetType type) const
+{
+ bool needsDeploy = (type == cmState::EXECUTABLE ||
+ type == cmState::SHARED_LIBRARY);
+ return this->TargetsWindowsCE() && needsDeploy;
+}
+
+//----------------------------------------------------------------------------
bool cmGlobalVisualStudio8Generator::ComputeTargetDepends()
{
// Skip over the cmGlobalVisualStudioGenerator implementation!
@@ -399,30 +446,37 @@ bool cmGlobalVisualStudio8Generator::ComputeTargetDepends()
//----------------------------------------------------------------------------
void cmGlobalVisualStudio8Generator::WriteProjectDepends(
- std::ostream& fout, const char*, const char*, cmTarget& t)
+ std::ostream& fout, const std::string&, const char*,
+ cmGeneratorTarget const* gt)
{
- TargetDependSet const& unordered = this->GetTargetDirectDepends(t);
- OrderedTargetDependSet depends(unordered);
+ TargetDependSet const& unordered = this->GetTargetDirectDepends(gt);
+ OrderedTargetDependSet depends(unordered, std::string());
for(OrderedTargetDependSet::const_iterator i = depends.begin();
i != depends.end(); ++i)
{
- std::string guid = this->GetGUID((*i)->GetName());
+ if((*i)->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ continue;
+ }
+ std::string guid = this->GetGUID((*i)->GetName().c_str());
fout << "\t\t{" << guid << "} = {" << guid << "}\n";
}
}
//----------------------------------------------------------------------------
bool cmGlobalVisualStudio8Generator::NeedLinkLibraryDependencies(
- cmTarget& target)
+ cmGeneratorTarget *target)
{
// Look for utility dependencies that magically link.
- for(std::set<cmStdString>::const_iterator ui =
- target.GetUtilities().begin();
- ui != target.GetUtilities().end(); ++ui)
+ for(std::set<std::string>::const_iterator ui =
+ target->GetUtilities().begin();
+ ui != target->GetUtilities().end(); ++ui)
{
- if(cmTarget* depTarget = this->FindTarget(0, ui->c_str()))
+ if(cmGeneratorTarget* depTarget =
+ target->GetLocalGenerator()->FindGeneratorTargetToUse(ui->c_str()))
{
- if(depTarget->GetProperty("EXTERNAL_MSPROJECT"))
+ if(depTarget->GetType() != cmState::INTERFACE_LIBRARY
+ && depTarget->GetProperty("EXTERNAL_MSPROJECT"))
{
// This utility dependency names an external .vcproj target.
// We use LinkLibraryDependencies="true" to link to it without
diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h
index d18174275..b3093cca0 100644
--- a/Source/cmGlobalVisualStudio8Generator.h
+++ b/Source/cmGlobalVisualStudio8Generator.h
@@ -23,27 +23,27 @@
class cmGlobalVisualStudio8Generator : public cmGlobalVisualStudio71Generator
{
public:
- cmGlobalVisualStudio8Generator(const char* name,
- const char* platformName, const char* additionalPlatformDefinition);
+ cmGlobalVisualStudio8Generator(cmake* cm, const std::string& name,
+ const std::string& platformName);
static cmGlobalGeneratorFactory* NewFactory();
///! Get the name for the generator.
- virtual const char* GetName() const {return this->Name.c_str();}
+ virtual std::string GetName() const {return this->Name;}
/** Get the documentation entry for this generator. */
static void GetDocumentation(cmDocumentationEntry& entry);
- ///! Create a local generator appropriate to this Global Generator
- virtual cmLocalGenerator *CreateLocalGenerator();
-
+ virtual void EnableLanguage(std::vector<std::string>const& languages,
+ cmMakefile *, bool optional);
virtual void AddPlatformDefinitions(cmMakefile* mf);
+ virtual bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf);
+
/**
* Override Configure and Generate to add the build-system check
* target.
*/
virtual void Configure();
- virtual void Generate();
/**
* Where does this version of Visual Studio look for macros for the
@@ -60,29 +60,39 @@ public:
/** Return true if the target project file should have the option
LinkLibraryDependencies and link to .sln dependencies. */
- virtual bool NeedLinkLibraryDependencies(cmTarget& target);
+ virtual bool NeedLinkLibraryDependencies(cmGeneratorTarget* target);
/** Return true if building for Windows CE */
virtual bool TargetsWindowsCE() const {
return !this->WindowsCEVersion.empty(); }
protected:
+ virtual void AddExtraIDETargets();
virtual const char* GetIDEVersion() { return "8.0"; }
+ virtual std::string FindDevEnvCommand();
+
virtual bool VSLinksDependencies() const { return false; }
- void AddCheckTarget();
+ bool AddCheckTarget();
+
+ /** Return true if the configuration needs to be deployed */
+ virtual bool NeedsDeploy(cmState::TargetType type) const;
static cmIDEFlagTable const* GetExtraFlagTableVS8();
virtual void WriteSLNHeader(std::ostream& fout);
- virtual void WriteSolutionConfigurations(std::ostream& fout);
+ virtual void WriteSolutionConfigurations(
+ std::ostream& fout, std::vector<std::string> const& configs);
virtual void WriteProjectConfigurations(
- std::ostream& fout, const char* name, cmTarget::TargetType type,
+ std::ostream& fout, const std::string& name, cmState::TargetType type,
+ std::vector<std::string> const& configs,
const std::set<std::string>& configsPartOfDefaultBuild,
- const char* platformMapping = NULL);
+ const std::string& platformMapping = "");
virtual bool ComputeTargetDepends();
- virtual void WriteProjectDepends(std::ostream& fout, const char* name,
- const char* path, cmTarget &t);
+ virtual void WriteProjectDepends(std::ostream& fout,
+ const std::string& name,
+ const char* path,
+ const cmGeneratorTarget *t);
std::string Name;
std::string WindowsCEVersion;
diff --git a/Source/cmGlobalVisualStudio9Generator.cxx b/Source/cmGlobalVisualStudio9Generator.cxx
index fba6ed1ee..884f7540b 100644
--- a/Source/cmGlobalVisualStudio9Generator.cxx
+++ b/Source/cmGlobalVisualStudio9Generator.cxx
@@ -22,17 +22,18 @@ class cmGlobalVisualStudio9Generator::Factory
: public cmGlobalGeneratorFactory
{
public:
- virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const {
- if(strstr(name, vs9generatorName) != name)
+ virtual cmGlobalGenerator*
+ CreateGlobalGenerator(const std::string& name, cmake* cm) const {
+ if(strncmp(name.c_str(), vs9generatorName,
+ sizeof(vs9generatorName) - 1) != 0)
{
return 0;
}
- const char* p = name + sizeof(vs9generatorName) - 1;
+ const char* p = name.c_str() + sizeof(vs9generatorName) - 1;
if(p[0] == '\0')
{
- return new cmGlobalVisualStudio9Generator(
- name, NULL, NULL);
+ return new cmGlobalVisualStudio9Generator(cm, name, "");
}
if(p[0] != ' ')
@@ -44,14 +45,12 @@ public:
if(!strcmp(p, "IA64"))
{
- return new cmGlobalVisualStudio9Generator(
- name, "Itanium", "CMAKE_FORCE_IA64");
+ return new cmGlobalVisualStudio9Generator(cm, name, "Itanium");
}
if(!strcmp(p, "Win64"))
{
- return new cmGlobalVisualStudio9Generator(
- name, "x64", "CMAKE_FORCE_WIN64");
+ return new cmGlobalVisualStudio9Generator(cm, name, "x64");
}
cmVisualStudioWCEPlatformParser parser(p);
@@ -61,20 +60,18 @@ public:
return 0;
}
- cmGlobalVisualStudio9Generator* ret = new cmGlobalVisualStudio9Generator(
- name, p, NULL);
+ cmGlobalVisualStudio9Generator* ret =
+ new cmGlobalVisualStudio9Generator(cm, name, p);
ret->WindowsCEVersion = parser.GetOSVersion();
return ret;
}
virtual void GetDocumentation(cmDocumentationEntry& entry) const {
- entry.Name = vs9generatorName;
- entry.Brief = "Generates Visual Studio 9 2008 project files.";
- entry.Full =
- "It is possible to append a space followed by the platform name "
- "to create project files for a specific target platform. E.g. "
- "\"Visual Studio 9 2008 Win64\" will create project files for "
- "the x64 processor; \"Visual Studio 9 2008 IA64\" for Itanium.";
+ entry.Name = std::string(vs9generatorName) + " [arch]";
+ entry.Brief =
+ "Generates Visual Studio 2008 project files. "
+ "Optional [arch] can be \"Win64\" or \"IA64\"."
+ ;
}
virtual void GetGenerators(std::vector<std::string>& names) const {
@@ -91,6 +88,8 @@ public:
names.push_back("Visual Studio 9 2008 " + *i);
}
}
+
+ virtual bool SupportsToolset() const { return false; }
};
//----------------------------------------------------------------------------
@@ -100,13 +99,11 @@ cmGlobalGeneratorFactory* cmGlobalVisualStudio9Generator::NewFactory()
}
//----------------------------------------------------------------------------
-cmGlobalVisualStudio9Generator::cmGlobalVisualStudio9Generator(
- const char* name, const char* platformName,
- const char* additionalPlatformDefinition)
- : cmGlobalVisualStudio8Generator(name, platformName,
- additionalPlatformDefinition)
+cmGlobalVisualStudio9Generator::cmGlobalVisualStudio9Generator(cmake* cm,
+ const std::string& name, const std::string& platformName)
+ : cmGlobalVisualStudio8Generator(cm, name, platformName)
{
- this->FindMakeProgramFile = "CMakeVS9FindMake.cmake";
+ this->Version = VS9;
}
//----------------------------------------------------------------------------
@@ -116,25 +113,6 @@ void cmGlobalVisualStudio9Generator::WriteSLNHeader(std::ostream& fout)
fout << "# Visual Studio 2008\n";
}
-///! Create a local generator appropriate to this Global Generator
-cmLocalGenerator *cmGlobalVisualStudio9Generator::CreateLocalGenerator()
-{
- cmLocalVisualStudio7Generator *lg
- = new cmLocalVisualStudio7Generator(cmLocalVisualStudioGenerator::VS9);
- lg->SetPlatformName(this->GetPlatformName());
- lg->SetExtraFlagTable(this->GetExtraFlagTableVS8());
- lg->SetGlobalGenerator(this);
- return lg;
-}
-
-//----------------------------------------------------------------------------
-void cmGlobalVisualStudio9Generator
-::EnableLanguage(std::vector<std::string>const & lang,
- cmMakefile *mf, bool optional)
-{
- cmGlobalVisualStudio8Generator::EnableLanguage(lang, mf, optional);
-}
-
//----------------------------------------------------------------------------
std::string cmGlobalVisualStudio9Generator::GetUserMacrosDirectory()
{
diff --git a/Source/cmGlobalVisualStudio9Generator.h b/Source/cmGlobalVisualStudio9Generator.h
index 202aa8d12..e25a4bec6 100644
--- a/Source/cmGlobalVisualStudio9Generator.h
+++ b/Source/cmGlobalVisualStudio9Generator.h
@@ -24,19 +24,14 @@ class cmGlobalVisualStudio9Generator :
public cmGlobalVisualStudio8Generator
{
public:
- cmGlobalVisualStudio9Generator(const char* name,
- const char* platformName, const char* additionalPlatformDefinition);
+ cmGlobalVisualStudio9Generator(cmake* cm, const std::string& name,
+ const std::string& platformName);
static cmGlobalGeneratorFactory* NewFactory();
- ///! create the correct local generator
- virtual cmLocalGenerator *CreateLocalGenerator();
-
/**
- * Try to determine system infomation such as shared library
+ * Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
- virtual void EnableLanguage(std::vector<std::string>const& languages,
- cmMakefile *, bool optional);
virtual void WriteSLNHeader(std::ostream& fout);
/**
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index 59310162c..6a1aa2958 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -1,3 +1,4 @@
+
/*============================================================================
CMake - Cross Platform Makefile Generator
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
@@ -12,16 +13,21 @@
#include "cmGlobalVisualStudioGenerator.h"
#include "cmCallVisualStudioMacro.h"
+#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmLocalVisualStudioGenerator.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
#include "cmTarget.h"
+#include <cmsys/Encoding.hxx>
+#include "cmAlgorithms.h"
//----------------------------------------------------------------------------
-cmGlobalVisualStudioGenerator::cmGlobalVisualStudioGenerator()
+cmGlobalVisualStudioGenerator::cmGlobalVisualStudioGenerator(cmake* cm)
+ : cmGlobalGenerator(cm)
{
- this->AdditionalPlatformDefinition = NULL;
+ cm->GetState()->SetWindowsShell(true);
+ cm->GetState()->SetWindowsVSIDE(true);
}
//----------------------------------------------------------------------------
@@ -30,6 +36,19 @@ cmGlobalVisualStudioGenerator::~cmGlobalVisualStudioGenerator()
}
//----------------------------------------------------------------------------
+cmGlobalVisualStudioGenerator::VSVersion
+cmGlobalVisualStudioGenerator::GetVersion() const
+{
+ return this->Version;
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudioGenerator::SetVersion(VSVersion v)
+{
+ this->Version = v;
+}
+
+//----------------------------------------------------------------------------
std::string cmGlobalVisualStudioGenerator::GetRegistryBase()
{
return cmGlobalVisualStudioGenerator::GetRegistryBase(
@@ -45,19 +64,19 @@ std::string cmGlobalVisualStudioGenerator::GetRegistryBase(
}
//----------------------------------------------------------------------------
-void cmGlobalVisualStudioGenerator::Generate()
+void cmGlobalVisualStudioGenerator::AddExtraIDETargets()
{
// Add a special target that depends on ALL projects for easy build
// of one configuration only.
const char* no_working_dir = 0;
std::vector<std::string> no_depends;
cmCustomCommandLines no_commands;
- std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it;
+ std::map<std::string, std::vector<cmLocalGenerator*> >::iterator it;
for(it = this->ProjectMap.begin(); it!= this->ProjectMap.end(); ++it)
{
std::vector<cmLocalGenerator*>& gen = it->second;
// add the ALL_BUILD to the first local generator of each project
- if(gen.size())
+ if(!gen.empty())
{
// Use no actual command lines so that the target itself is not
// considered always out of date.
@@ -67,6 +86,9 @@ void cmGlobalVisualStudioGenerator::Generate()
no_depends, no_commands, false,
"Build all projects");
+ cmGeneratorTarget* gt = new cmGeneratorTarget(allBuild, gen[0]);
+ gen[0]->AddGeneratorTarget(gt);
+
#if 0
// Can't activate this code because we want ALL_BUILD
// selected as the default "startup project" when first
@@ -85,13 +107,20 @@ void cmGlobalVisualStudioGenerator::Generate()
for(std::vector<cmLocalGenerator*>::iterator i = gen.begin();
i != gen.end(); ++i)
{
- cmTargets& targets = (*i)->GetMakefile()->GetTargets();
- for(cmTargets::iterator t = targets.begin();
+ std::vector<cmGeneratorTarget*> targets =
+ (*i)->GetGeneratorTargets();
+ for(std::vector<cmGeneratorTarget*>::iterator t = targets.begin();
t != targets.end(); ++t)
{
- if(!this->IsExcluded(gen[0], t->second))
+ cmGeneratorTarget* tgt = *t;
+ if (tgt->GetType() == cmState::GLOBAL_TARGET
+ || tgt->IsImported())
{
- allBuild->AddUtility(t->second.GetName());
+ continue;
+ }
+ if(!this->IsExcluded(gen[0], tgt))
+ {
+ allBuild->AddUtility(tgt->GetName());
}
}
}
@@ -111,55 +140,15 @@ void cmGlobalVisualStudioGenerator::Generate()
static_cast<cmLocalVisualStudioGenerator*>(*lgi);
lg->AddCMakeListsRules();
}
-
- // Run all the local generators.
- this->cmGlobalGenerator::Generate();
}
//----------------------------------------------------------------------------
-void
-cmGlobalVisualStudioGenerator
-::ComputeTargetObjects(cmGeneratorTarget* gt) const
+void cmGlobalVisualStudioGenerator
+::ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const
{
- cmLocalVisualStudioGenerator* lg =
- static_cast<cmLocalVisualStudioGenerator*>(gt->LocalGenerator);
- std::string dir_max = lg->ComputeLongestObjectDirectory(*gt->Target);
-
- // Count the number of object files with each name. Note that
- // windows file names are not case sensitive.
- std::map<cmStdString, int> counts;
- for(std::vector<cmSourceFile*>::const_iterator
- si = gt->ObjectSources.begin();
- si != gt->ObjectSources.end(); ++si)
- {
- cmSourceFile* sf = *si;
- std::string objectNameLower = cmSystemTools::LowerCase(
- cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()));
- objectNameLower += ".obj";
- counts[objectNameLower] += 1;
- }
-
- // For all source files producing duplicate names we need unique
- // object name computation.
- for(std::vector<cmSourceFile*>::const_iterator
- si = gt->ObjectSources.begin();
- si != gt->ObjectSources.end(); ++si)
- {
- cmSourceFile* sf = *si;
- std::string objectName =
- cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath());
- objectName += ".obj";
- if(counts[cmSystemTools::LowerCase(objectName)] > 1)
- {
- gt->ExplicitObjectName.insert(sf);
- objectName = lg->GetObjectFileNameWithoutTarget(*sf, dir_max);
- }
- gt->Objects[sf] = objectName;
- }
-
- std::string dir = gt->Makefile->GetCurrentOutputDirectory();
+ std::string dir = gt->LocalGenerator->GetCurrentBinaryDirectory();
dir += "/";
- std::string tgtDir = lg->GetTargetDirectory(*gt->Target);
+ std::string tgtDir = gt->LocalGenerator->GetTargetDirectory(gt);
if(!tgtDir.empty())
{
dir += tgtDir;
@@ -198,7 +187,7 @@ void cmGlobalVisualStudioGenerator::ConfigureCMakeVisualStudioMacros()
cmMakefile* mf = this->LocalGenerators[0]->GetMakefile();
std::string dir = this->GetUserMacrosDirectory();
- if (mf != 0 && dir != "")
+ if (dir != "")
{
std::string src = mf->GetRequiredDefinition("CMAKE_ROOT");
src += "/Templates/" CMAKE_VSMACROS_FILENAME;
@@ -239,13 +228,12 @@ cmGlobalVisualStudioGenerator
std::string dir = this->GetUserMacrosDirectory();
// Only really try to call the macro if:
- // - mf is non-NULL
// - there is a UserMacrosDirectory
// - the CMake vsmacros file exists
// - the CMake vsmacros file is registered
// - there were .sln/.vcproj files changed during generation
//
- if (mf != 0 && dir != "")
+ if (dir != "")
{
std::string macrosFile = dir + "/CMakeMacros/" CMAKE_VSMACROS_FILENAME;
std::string nextSubkeyName;
@@ -261,9 +249,9 @@ cmGlobalVisualStudioGenerator
}
else
{
- topLevelSlnName = mf->GetStartOutputDirectory();
+ topLevelSlnName = mf->GetCurrentBinaryDirectory();
topLevelSlnName += "/";
- topLevelSlnName += mf->GetProjectName();
+ topLevelSlnName += this->LocalGenerators[0]->GetProjectName();
topLevelSlnName += ".sln";
}
@@ -271,7 +259,7 @@ cmGlobalVisualStudioGenerator
{
std::vector<std::string> filenames;
this->GetFilesReplacedDuringGenerate(filenames);
- if (filenames.size() > 0)
+ if (!filenames.empty())
{
// Convert vector to semi-colon delimited string of filenames:
std::string projects;
@@ -314,12 +302,14 @@ std::string cmGlobalVisualStudioGenerator::GetUserMacrosRegKeyBase()
}
//----------------------------------------------------------------------------
-void cmGlobalVisualStudioGenerator::FillLinkClosure(cmTarget* target,
- TargetSet& linked)
+void cmGlobalVisualStudioGenerator::FillLinkClosure(
+ const cmGeneratorTarget *target,
+ TargetSet& linked)
{
if(linked.insert(target).second)
{
- TargetDependSet const& depends = this->GetTargetDirectDepends(*target);
+ TargetDependSet const& depends =
+ this->GetTargetDirectDepends(target);
for(TargetDependSet::const_iterator di = depends.begin();
di != depends.end(); ++di)
{
@@ -333,7 +323,7 @@ void cmGlobalVisualStudioGenerator::FillLinkClosure(cmTarget* target,
//----------------------------------------------------------------------------
cmGlobalVisualStudioGenerator::TargetSet const&
-cmGlobalVisualStudioGenerator::GetTargetLinkClosure(cmTarget* target)
+cmGlobalVisualStudioGenerator::GetTargetLinkClosure(cmGeneratorTarget* target)
{
TargetSetMap::iterator i = this->TargetLinkClosure.find(target);
if(i == this->TargetLinkClosure.end())
@@ -347,14 +337,19 @@ cmGlobalVisualStudioGenerator::GetTargetLinkClosure(cmTarget* target)
//----------------------------------------------------------------------------
void cmGlobalVisualStudioGenerator::FollowLinkDepends(
- cmTarget* target, std::set<cmTarget*>& linked)
+ const cmGeneratorTarget *target,
+ std::set<const cmGeneratorTarget *> &linked)
{
+ if(target->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ return;
+ }
if(linked.insert(target).second &&
- target->GetType() == cmTarget::STATIC_LIBRARY)
+ target->GetType() == cmState::STATIC_LIBRARY)
{
// Static library targets do not list their link dependencies so
// we must follow them transitively now.
- TargetDependSet const& depends = this->GetTargetDirectDepends(*target);
+ TargetDependSet const& depends = this->GetTargetDirectDepends(target);
for(TargetDependSet::const_iterator di = depends.begin();
di != depends.end(); ++di)
{
@@ -373,18 +368,18 @@ bool cmGlobalVisualStudioGenerator::ComputeTargetDepends()
{
return false;
}
- std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it;
+ std::map<std::string, std::vector<cmLocalGenerator*> >::iterator it;
for(it = this->ProjectMap.begin(); it!= this->ProjectMap.end(); ++it)
{
std::vector<cmLocalGenerator*>& gen = it->second;
for(std::vector<cmLocalGenerator*>::iterator i = gen.begin();
i != gen.end(); ++i)
{
- cmTargets& targets = (*i)->GetMakefile()->GetTargets();
- for(cmTargets::iterator ti = targets.begin();
+ std::vector<cmGeneratorTarget*> targets = (*i)->GetGeneratorTargets();
+ for(std::vector<cmGeneratorTarget*>::iterator ti = targets.begin();
ti != targets.end(); ++ti)
{
- this->ComputeVSTargetDepends(ti->second);
+ this->ComputeVSTargetDepends(*ti);
}
}
}
@@ -392,19 +387,20 @@ bool cmGlobalVisualStudioGenerator::ComputeTargetDepends()
}
//----------------------------------------------------------------------------
-static bool VSLinkable(cmTarget* t)
+static bool VSLinkable(cmGeneratorTarget const* t)
{
- return t->IsLinkable() || t->GetType() == cmTarget::OBJECT_LIBRARY;
+ return t->IsLinkable() || t->GetType() == cmState::OBJECT_LIBRARY;
}
//----------------------------------------------------------------------------
-void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(cmTarget& target)
+void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(
+ cmGeneratorTarget* target)
{
- if(this->VSTargetDepends.find(&target) != this->VSTargetDepends.end())
+ if(this->VSTargetDepends.find(target) != this->VSTargetDepends.end())
{
return;
}
- VSDependSet& vsTargetDepend = this->VSTargetDepends[&target];
+ VSDependSet& vsTargetDepend = this->VSTargetDepends[target];
// VS <= 7.1 has two behaviors that affect solution dependencies.
//
// (1) Solution-level dependencies between a linkable target and a
@@ -424,18 +420,18 @@ void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(cmTarget& target)
// leaving them out for the static library itself but following them
// transitively for other targets.
- bool allowLinkable = (target.GetType() != cmTarget::STATIC_LIBRARY &&
- target.GetType() != cmTarget::SHARED_LIBRARY &&
- target.GetType() != cmTarget::MODULE_LIBRARY &&
- target.GetType() != cmTarget::EXECUTABLE);
+ bool allowLinkable = (target->GetType() != cmState::STATIC_LIBRARY &&
+ target->GetType() != cmState::SHARED_LIBRARY &&
+ target->GetType() != cmState::MODULE_LIBRARY &&
+ target->GetType() != cmState::EXECUTABLE);
TargetDependSet const& depends = this->GetTargetDirectDepends(target);
// Collect implicit link dependencies (target_link_libraries).
// Static libraries cannot depend on their link implementation
// due to behavior (2), but they do not really need to.
- std::set<cmTarget*> linkDepends;
- if(target.GetType() != cmTarget::STATIC_LIBRARY)
+ std::set<cmGeneratorTarget const*> linkDepends;
+ if(target->GetType() != cmState::STATIC_LIBRARY)
{
for(TargetDependSet::const_iterator di = depends.begin();
di != depends.end(); ++di)
@@ -443,69 +439,75 @@ void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(cmTarget& target)
cmTargetDepend dep = *di;
if(dep.IsLink())
{
- this->FollowLinkDepends(dep, linkDepends);
+ this->FollowLinkDepends(*di, linkDepends);
}
}
}
// Collect explicit util dependencies (add_dependencies).
- std::set<cmTarget*> utilDepends;
+ std::set<cmGeneratorTarget const*> utilDepends;
for(TargetDependSet::const_iterator di = depends.begin();
di != depends.end(); ++di)
{
cmTargetDepend dep = *di;
if(dep.IsUtil())
{
- this->FollowLinkDepends(dep, utilDepends);
+ this->FollowLinkDepends(*di, utilDepends);
}
}
// Collect all targets linked by this target so we can avoid
// intermediate targets below.
TargetSet linked;
- if(target.GetType() != cmTarget::STATIC_LIBRARY)
+ if(target->GetType() != cmState::STATIC_LIBRARY)
{
- linked = this->GetTargetLinkClosure(&target);
+ linked = this->GetTargetLinkClosure(target);
}
// Emit link dependencies.
- for(std::set<cmTarget*>::iterator di = linkDepends.begin();
+ for(std::set<cmGeneratorTarget const*>::iterator di = linkDepends.begin();
di != linkDepends.end(); ++di)
{
- cmTarget* dep = *di;
+ cmGeneratorTarget const* dep = *di;
vsTargetDepend.insert(dep->GetName());
}
// Emit util dependencies. Possibly use intermediate targets.
- for(std::set<cmTarget*>::iterator di = utilDepends.begin();
+ for(std::set<cmGeneratorTarget const*>::iterator di = utilDepends.begin();
di != utilDepends.end(); ++di)
{
- cmTarget* dep = *di;
- if(allowLinkable || !VSLinkable(dep) || linked.count(dep))
+ cmGeneratorTarget const* dgt = *di;
+ if(allowLinkable || !VSLinkable(dgt) || linked.count(dgt))
{
// Direct dependency allowed.
- vsTargetDepend.insert(dep->GetName());
+ vsTargetDepend.insert(dgt->GetName());
}
else
{
// Direct dependency on linkable target not allowed.
// Use an intermediate utility target.
- vsTargetDepend.insert(this->GetUtilityDepend(dep));
+ vsTargetDepend.insert(this->GetUtilityDepend(dgt));
}
}
}
//----------------------------------------------------------------------------
-void cmGlobalVisualStudioGenerator::AddPlatformDefinitions(cmMakefile* mf)
+void cmGlobalVisualStudioGenerator::FindMakeProgram(cmMakefile* mf)
{
- if(this->AdditionalPlatformDefinition)
+ // Visual Studio generators know how to lookup their build tool
+ // directly instead of needing a helper module to do it, so we
+ // do not actually need to put CMAKE_MAKE_PROGRAM into the cache.
+ if(cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM")))
{
- mf->AddDefinition(this->AdditionalPlatformDefinition, "TRUE");
+ mf->AddDefinition("CMAKE_MAKE_PROGRAM",
+ this->GetVSMakeProgram().c_str());
}
}
//----------------------------------------------------------------------------
-std::string cmGlobalVisualStudioGenerator::GetUtilityDepend(cmTarget* target)
+std::string
+cmGlobalVisualStudioGenerator::GetUtilityDepend(
+ cmGeneratorTarget const* target)
{
UtilityDependsMap::iterator i = this->UtilityDepends.find(target);
if(i == this->UtilityDepends.end())
@@ -542,52 +544,53 @@ bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile,
keyname = regKeyBase + "\\OtherProjects7";
hkey = NULL;
- result = RegOpenKeyEx(HKEY_CURRENT_USER, keyname.c_str(),
- 0, KEY_READ, &hkey);
+ result = RegOpenKeyExW(HKEY_CURRENT_USER,
+ cmsys::Encoding::ToWide(keyname).c_str(),
+ 0, KEY_READ, &hkey);
if (ERROR_SUCCESS == result)
{
// Iterate the subkeys and look for the values of interest in each subkey:
- CHAR subkeyname[256];
- DWORD cch_subkeyname = sizeof(subkeyname)/sizeof(subkeyname[0]);
- CHAR keyclass[256];
- DWORD cch_keyclass = sizeof(keyclass)/sizeof(keyclass[0]);
+ wchar_t subkeyname[256];
+ DWORD cch_subkeyname = sizeof(subkeyname)*sizeof(subkeyname[0]);
+ wchar_t keyclass[256];
+ DWORD cch_keyclass = sizeof(keyclass)*sizeof(keyclass[0]);
FILETIME lastWriteTime;
lastWriteTime.dwHighDateTime = 0;
lastWriteTime.dwLowDateTime = 0;
- while (ERROR_SUCCESS == RegEnumKeyEx(hkey, index, subkeyname,
+ while (ERROR_SUCCESS == RegEnumKeyExW(hkey, index, subkeyname,
&cch_subkeyname,
0, keyclass, &cch_keyclass, &lastWriteTime))
{
// Open the subkey and query the values of interest:
HKEY hsubkey = NULL;
- result = RegOpenKeyEx(hkey, subkeyname, 0, KEY_READ, &hsubkey);
+ result = RegOpenKeyExW(hkey, subkeyname, 0, KEY_READ, &hsubkey);
if (ERROR_SUCCESS == result)
{
DWORD valueType = REG_SZ;
- CHAR data1[256];
- DWORD cch_data1 = sizeof(data1)/sizeof(data1[0]);
- RegQueryValueEx(hsubkey, "Path", 0, &valueType,
+ wchar_t data1[256];
+ DWORD cch_data1 = sizeof(data1)*sizeof(data1[0]);
+ RegQueryValueExW(hsubkey, L"Path", 0, &valueType,
(LPBYTE) &data1[0], &cch_data1);
DWORD data2 = 0;
DWORD cch_data2 = sizeof(data2);
- RegQueryValueEx(hsubkey, "Security", 0, &valueType,
+ RegQueryValueExW(hsubkey, L"Security", 0, &valueType,
(LPBYTE) &data2, &cch_data2);
DWORD data3 = 0;
DWORD cch_data3 = sizeof(data3);
- RegQueryValueEx(hsubkey, "StorageFormat", 0, &valueType,
+ RegQueryValueExW(hsubkey, L"StorageFormat", 0, &valueType,
(LPBYTE) &data3, &cch_data3);
- s2 = cmSystemTools::LowerCase(data1);
+ s2 = cmSystemTools::LowerCase(cmsys::Encoding::ToNarrow(data1));
cmSystemTools::ConvertToUnixSlashes(s2);
if (s2 == s1)
{
macrosRegistered = true;
}
- std::string fullname(data1);
+ std::string fullname = cmsys::Encoding::ToNarrow(data1);
std::string filename;
std::string filepath;
std::string filepathname;
@@ -619,8 +622,8 @@ bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile,
}
++index;
- cch_subkeyname = sizeof(subkeyname)/sizeof(subkeyname[0]);
- cch_keyclass = sizeof(keyclass)/sizeof(keyclass[0]);
+ cch_subkeyname = sizeof(subkeyname)*sizeof(subkeyname[0]);
+ cch_keyclass = sizeof(keyclass)*sizeof(keyclass[0]);
lastWriteTime.dwHighDateTime = 0;
lastWriteTime.dwLowDateTime = 0;
}
@@ -645,27 +648,28 @@ bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile,
keyname = regKeyBase + "\\RecordingProject7";
hkey = NULL;
- result = RegOpenKeyEx(HKEY_CURRENT_USER, keyname.c_str(),
- 0, KEY_READ, &hkey);
+ result = RegOpenKeyExW(HKEY_CURRENT_USER,
+ cmsys::Encoding::ToWide(keyname).c_str(),
+ 0, KEY_READ, &hkey);
if (ERROR_SUCCESS == result)
{
DWORD valueType = REG_SZ;
- CHAR data1[256];
- DWORD cch_data1 = sizeof(data1)/sizeof(data1[0]);
- RegQueryValueEx(hkey, "Path", 0, &valueType,
+ wchar_t data1[256];
+ DWORD cch_data1 = sizeof(data1)*sizeof(data1[0]);
+ RegQueryValueExW(hkey, L"Path", 0, &valueType,
(LPBYTE) &data1[0], &cch_data1);
DWORD data2 = 0;
DWORD cch_data2 = sizeof(data2);
- RegQueryValueEx(hkey, "Security", 0, &valueType,
+ RegQueryValueExW(hkey, L"Security", 0, &valueType,
(LPBYTE) &data2, &cch_data2);
DWORD data3 = 0;
DWORD cch_data3 = sizeof(data3);
- RegQueryValueEx(hkey, "StorageFormat", 0, &valueType,
+ RegQueryValueExW(hkey, L"StorageFormat", 0, &valueType,
(LPBYTE) &data3, &cch_data3);
- s2 = cmSystemTools::LowerCase(data1);
+ s2 = cmSystemTools::LowerCase(cmsys::Encoding::ToNarrow(data1));
cmSystemTools::ConvertToUnixSlashes(s2);
if (s2 == s1)
{
@@ -697,24 +701,27 @@ void WriteVSMacrosFileRegistryEntry(
{
std::string keyname = regKeyBase + "\\OtherProjects7";
HKEY hkey = NULL;
- LONG result = RegOpenKeyEx(HKEY_CURRENT_USER, keyname.c_str(), 0,
+ LONG result = RegOpenKeyExW(HKEY_CURRENT_USER,
+ cmsys::Encoding::ToWide(keyname).c_str(), 0,
KEY_READ|KEY_WRITE, &hkey);
if (ERROR_SUCCESS == result)
{
// Create the subkey and set the values of interest:
HKEY hsubkey = NULL;
- char lpClass[] = "";
- result = RegCreateKeyEx(hkey, nextAvailableSubKeyName.c_str(), 0,
- lpClass, 0, KEY_READ|KEY_WRITE, 0, &hsubkey, 0);
+ wchar_t lpClass[] = L"";
+ result = RegCreateKeyExW(hkey,
+ cmsys::Encoding::ToWide(nextAvailableSubKeyName).c_str(), 0,
+ lpClass, 0, KEY_READ|KEY_WRITE, 0, &hsubkey, 0);
if (ERROR_SUCCESS == result)
{
DWORD dw = 0;
std::string s(macrosFile);
cmSystemTools::ReplaceString(s, "/", "\\");
+ std::wstring ws = cmsys::Encoding::ToWide(s);
- result = RegSetValueEx(hsubkey, "Path", 0, REG_SZ, (LPBYTE) s.c_str(),
- static_cast<DWORD>(strlen(s.c_str()) + 1));
+ result = RegSetValueExW(hsubkey, L"Path", 0, REG_SZ, (LPBYTE)ws.c_str(),
+ static_cast<DWORD>(ws.size() + 1)*sizeof(wchar_t));
if (ERROR_SUCCESS != result)
{
std::cout << "error result 1: " << result << std::endl;
@@ -724,7 +731,7 @@ void WriteVSMacrosFileRegistryEntry(
// Security value is always "1" for sample macros files (seems to be "2"
// if you put the file somewhere outside the standard VSMacros folder)
dw = 1;
- result = RegSetValueEx(hsubkey, "Security",
+ result = RegSetValueExW(hsubkey, L"Security",
0, REG_DWORD, (LPBYTE) &dw, sizeof(DWORD));
if (ERROR_SUCCESS != result)
{
@@ -734,7 +741,7 @@ void WriteVSMacrosFileRegistryEntry(
// StorageFormat value is always "0" for sample macros files
dw = 0;
- result = RegSetValueEx(hsubkey, "StorageFormat",
+ result = RegSetValueExW(hsubkey, L"StorageFormat",
0, REG_DWORD, (LPBYTE) &dw, sizeof(DWORD));
if (ERROR_SUCCESS != result)
{
@@ -822,11 +829,20 @@ void RegisterVisualStudioMacros(const std::string& macrosFile,
}
}
}
-bool cmGlobalVisualStudioGenerator::TargetIsFortranOnly(cmTarget& target)
+bool
+cmGlobalVisualStudioGenerator::TargetIsFortranOnly(cmGeneratorTarget const* gt)
{
// check to see if this is a fortran build
- std::set<cmStdString> languages;
- target.GetLanguages(languages);
+ std::set<std::string> languages;
+ {
+ // Issue diagnostic if the source files depend on the config.
+ std::vector<cmSourceFile*> sources;
+ if (!gt->GetConfigCommonSourceFiles(sources))
+ {
+ return false;
+ }
+ }
+ gt->GetLanguages(languages, "");
if(languages.size() == 1)
{
if(*languages.begin() == "Fortran")
@@ -840,38 +856,125 @@ bool cmGlobalVisualStudioGenerator::TargetIsFortranOnly(cmTarget& target)
//----------------------------------------------------------------------------
bool
cmGlobalVisualStudioGenerator::TargetCompare
-::operator()(cmTarget const* l, cmTarget const* r) const
+::operator()(cmGeneratorTarget const* l, cmGeneratorTarget const* r) const
{
- // Make sure ALL_BUILD is first so it is the default active project.
- if(strcmp(r->GetName(), "ALL_BUILD") == 0)
+ // Make sure a given named target is ordered first,
+ // e.g. to set ALL_BUILD as the default active project.
+ // When the empty string is named this is a no-op.
+ if (r->GetName() == this->First)
{
return false;
}
- if(strcmp(l->GetName(), "ALL_BUILD") == 0)
+ if (l->GetName() == this->First)
{
return true;
}
- return strcmp(l->GetName(), r->GetName()) < 0;
+ return l->GetName() < r->GetName();
}
//----------------------------------------------------------------------------
cmGlobalVisualStudioGenerator::OrderedTargetDependSet
-::OrderedTargetDependSet(TargetDependSet const& targets)
+::OrderedTargetDependSet(TargetDependSet const& targets,
+ std::string const& first):
+ derived(TargetCompare(first))
{
- for(TargetDependSet::const_iterator ti =
- targets.begin(); ti != targets.end(); ++ti)
- {
- this->insert(*ti);
- }
+ this->insert(targets.begin(), targets.end());
}
//----------------------------------------------------------------------------
cmGlobalVisualStudioGenerator::OrderedTargetDependSet
-::OrderedTargetDependSet(TargetSet const& targets)
+::OrderedTargetDependSet(TargetSet const& targets,
+ std::string const& first):
+ derived(TargetCompare(first))
{
- for(TargetSet::const_iterator ti = targets.begin();
- ti != targets.end(); ++ti)
+ for (TargetSet::const_iterator it = targets.begin();
+ it != targets.end(); ++it)
{
- this->insert(*ti);
+ this->insert(*it);
+ }
+}
+
+std::string cmGlobalVisualStudioGenerator::ExpandCFGIntDir(
+ const std::string& str,
+ const std::string& config) const
+{
+ std::string replace = GetCMakeCFGIntDir();
+
+ std::string tmp = str;
+ for(std::string::size_type i = tmp.find(replace);
+ i != std::string::npos;
+ i = tmp.find(replace, i))
+ {
+ tmp.replace(i, replace.size(), config);
+ i += config.size();
+ }
+ return tmp;
+}
+
+void cmGlobalVisualStudioGenerator::AddSymbolExportCommand(
+ cmGeneratorTarget* gt, std::vector<cmCustomCommand>& commands,
+ std::string const& configName)
+{
+ std::vector<std::string> outputs;
+ std::string deffile = gt->ObjectDirectory;
+ deffile += "/exportall.def";
+ outputs.push_back(deffile);
+ std::vector<std::string> empty;
+ std::vector<cmSourceFile const*> objectSources;
+ gt->GetObjectSources(objectSources, configName);
+ std::map<cmSourceFile const*, std::string> mapping;
+ for(std::vector<cmSourceFile const*>::const_iterator it
+ = objectSources.begin(); it != objectSources.end(); ++it)
+ {
+ mapping[*it];
+ }
+ gt->LocalGenerator->
+ ComputeObjectFilenames(mapping, gt);
+ std::string obj_dir = gt->ObjectDirectory;
+ std::string cmakeCommand = cmSystemTools::GetCMakeCommand();
+ cmSystemTools::ConvertToWindowsExtendedPath(cmakeCommand);
+ cmCustomCommandLine cmdl;
+ cmdl.push_back(cmakeCommand);
+ cmdl.push_back("-E");
+ cmdl.push_back("__create_def");
+ cmdl.push_back(deffile);
+ std::string obj_dir_expanded = obj_dir;
+ cmSystemTools::ReplaceString(obj_dir_expanded,
+ this->GetCMakeCFGIntDir(),
+ configName.c_str());
+ std::string objs_file = obj_dir_expanded;
+ cmSystemTools::MakeDirectory(objs_file.c_str());
+ objs_file += "/objects.txt";
+ cmdl.push_back(objs_file);
+ cmGeneratedFileStream fout(objs_file.c_str());
+ if(!fout)
+ {
+ cmSystemTools::Error("could not open ", objs_file.c_str());
+ return;
+ }
+ for(std::vector<cmSourceFile const*>::const_iterator it
+ = objectSources.begin(); it != objectSources.end(); ++it)
+ {
+ // Find the object file name corresponding to this source file.
+ std::map<cmSourceFile const*, std::string>::const_iterator
+ map_it = mapping.find(*it);
+ // It must exist because we populated the mapping just above.
+ assert(!map_it->second.empty());
+ std::string objFile = obj_dir + map_it->second;
+ // replace $(ConfigurationName) in the object names
+ cmSystemTools::ReplaceString(objFile, this->GetCMakeCFGIntDir(),
+ configName.c_str());
+ if(cmHasLiteralSuffix(objFile, ".obj"))
+ {
+ fout << objFile << "\n";
+ }
}
+ cmCustomCommandLines commandLines;
+ commandLines.push_back(cmdl);
+ cmCustomCommand command(gt->Target->GetMakefile(),
+ outputs, empty, empty,
+ commandLines,
+ "Auto build dll exports",
+ ".");
+ commands.push_back(command);
}
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
index b665158c6..f827f26ce 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -23,13 +23,26 @@
class cmGlobalVisualStudioGenerator : public cmGlobalGenerator
{
public:
- cmGlobalVisualStudioGenerator();
+ /** Known versions of Visual Studio. */
+ enum VSVersion
+ {
+ VS6 = 60,
+ VS7 = 70,
+ VS71 = 71,
+ VS8 = 80,
+ VS9 = 90,
+ VS10 = 100,
+ VS11 = 110,
+ VS12 = 120,
+ /* VS13 = 130 was skipped */
+ VS14 = 140
+ };
+
+ cmGlobalVisualStudioGenerator(cmake* cm);
virtual ~cmGlobalVisualStudioGenerator();
- /**
- * Basic generate implementation for all VS generators.
- */
- virtual void Generate();
+ VSVersion GetVersion() const;
+ void SetVersion(VSVersion v);
/**
* Configure CMake's Visual Studio macros file into the user's Visual
@@ -56,11 +69,11 @@ public:
* Call the ReloadProjects macro if necessary based on
* GetFilesReplacedDuringGenerate results.
*/
- virtual void CallVisualStudioMacro(MacroName m,
- const char* vsSolutionFile = 0);
+ void CallVisualStudioMacro(MacroName m,
+ const char* vsSolutionFile = 0);
// return true if target is fortran only
- bool TargetIsFortranOnly(cmTarget& t);
+ bool TargetIsFortranOnly(const cmGeneratorTarget *gt);
/** Get the top-level registry key for this VS version. */
std::string GetRegistryBase();
@@ -75,14 +88,31 @@ public:
/** Return true if building for Windows CE */
virtual bool TargetsWindowsCE() const { return false; }
- class TargetSet: public std::set<cmTarget*> {};
- struct TargetCompare
+ class TargetSet: public std::set<cmGeneratorTarget const*> {};
+ class TargetCompare
{
- bool operator()(cmTarget const* l, cmTarget const* r) const;
+ std::string First;
+ public:
+ TargetCompare(std::string const& first): First(first) {}
+ bool operator()(cmGeneratorTarget const* l,
+ cmGeneratorTarget const* r) const;
};
class OrderedTargetDependSet;
+ virtual void FindMakeProgram(cmMakefile*);
+
+
+ virtual std::string ExpandCFGIntDir(const std::string& str,
+ const std::string& config) const;
+
+ void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const;
+
+ void AddSymbolExportCommand(
+ cmGeneratorTarget*, std::vector<cmCustomCommand>& commands,
+ std::string const& configName);
protected:
+ virtual void AddExtraIDETargets();
+
// Does this VS version link targets to each other if there are
// dependencies in the SLN file? This was done for VS versions
// below 8.
@@ -90,42 +120,50 @@ protected:
virtual const char* GetIDEVersion() = 0;
- virtual void AddPlatformDefinitions(cmMakefile* mf);
-
virtual bool ComputeTargetDepends();
- class VSDependSet: public std::set<cmStdString> {};
- class VSDependMap: public std::map<cmTarget*, VSDependSet> {};
+ class VSDependSet: public std::set<std::string> {};
+ class VSDependMap: public std::map<cmGeneratorTarget const*, VSDependSet> {};
VSDependMap VSTargetDepends;
- void ComputeVSTargetDepends(cmTarget&);
-
- bool CheckTargetLinks(cmTarget& target, const char* name);
- std::string GetUtilityForTarget(cmTarget& target, const char*);
- virtual std::string WriteUtilityDepend(cmTarget*) = 0;
- std::string GetUtilityDepend(cmTarget* target);
- typedef std::map<cmTarget*, cmStdString> UtilityDependsMap;
+ void ComputeVSTargetDepends(cmGeneratorTarget *);
+
+ bool CheckTargetLinks(cmGeneratorTarget& target, const std::string& name);
+ std::string GetUtilityForTarget(cmGeneratorTarget& target,
+ const std::string&);
+ virtual std::string WriteUtilityDepend(cmGeneratorTarget const*) = 0;
+ std::string GetUtilityDepend(const cmGeneratorTarget *target);
+ typedef std::map<cmGeneratorTarget const*, std::string> UtilityDependsMap;
UtilityDependsMap UtilityDepends;
- const char* AdditionalPlatformDefinition;
+
+protected:
+ VSVersion Version;
private:
- void ComputeTargetObjects(cmGeneratorTarget* gt) const;
+ virtual std::string GetVSMakeProgram() = 0;
+ void PrintCompilerAdvice(std::ostream&, std::string const&,
+ const char*) const {}
- void FollowLinkDepends(cmTarget* target, std::set<cmTarget*>& linked);
+ void FollowLinkDepends(cmGeneratorTarget const* target,
+ std::set<cmGeneratorTarget const*>& linked);
- class TargetSetMap: public std::map<cmTarget*, TargetSet> {};
+ class TargetSetMap: public std::map<cmGeneratorTarget*, TargetSet> {};
TargetSetMap TargetLinkClosure;
- void FillLinkClosure(cmTarget* target, TargetSet& linked);
- TargetSet const& GetTargetLinkClosure(cmTarget* target);
+ void FillLinkClosure(const cmGeneratorTarget *target,
+ TargetSet& linked);
+ TargetSet const& GetTargetLinkClosure(cmGeneratorTarget* target);
};
class cmGlobalVisualStudioGenerator::OrderedTargetDependSet:
public std::multiset<cmTargetDepend,
cmGlobalVisualStudioGenerator::TargetCompare>
{
+ typedef std::multiset<cmTargetDepend,
+ cmGlobalVisualStudioGenerator::TargetCompare>
+ derived;
public:
typedef cmGlobalGenerator::TargetDependSet TargetDependSet;
typedef cmGlobalVisualStudioGenerator::TargetSet TargetSet;
- OrderedTargetDependSet(TargetDependSet const&);
- OrderedTargetDependSet(TargetSet const&);
+ OrderedTargetDependSet(TargetDependSet const&, std::string const& first);
+ OrderedTargetDependSet(TargetSet const&, std::string const& first);
};
#endif
diff --git a/Source/cmGlobalWatcomWMakeGenerator.cxx b/Source/cmGlobalWatcomWMakeGenerator.cxx
index e3cebc4ac..153773fcb 100644
--- a/Source/cmGlobalWatcomWMakeGenerator.cxx
+++ b/Source/cmGlobalWatcomWMakeGenerator.cxx
@@ -13,13 +13,24 @@
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
-cmGlobalWatcomWMakeGenerator::cmGlobalWatcomWMakeGenerator()
+cmGlobalWatcomWMakeGenerator::cmGlobalWatcomWMakeGenerator(cmake* cm)
+ : cmGlobalUnixMakefileGenerator3(cm)
{
this->FindMakeProgramFile = "CMakeFindWMake.cmake";
+#ifdef _WIN32
this->ForceUnixPaths = false;
+#endif
this->ToolSupportsColor = true;
this->NeedSymbolicMark = true;
this->EmptyRuleHackCommand = "@cd .";
+#ifdef _WIN32
+ cm->GetState()->SetWindowsShell(true);
+#endif
+ cm->GetState()->SetWatcomWMake(true);
+ this->IncludeDirective = "!include";
+ this->DefineWindowsNULL = true;
+ this->UnixCD = false;
+ this->MakeSilentFlag = "-h";
}
void cmGlobalWatcomWMakeGenerator
@@ -33,34 +44,15 @@ void cmGlobalWatcomWMakeGenerator
mf->AddDefinition("CMAKE_MANGLE_OBJECT_FILE_NAMES", "1");
mf->AddDefinition("CMAKE_MAKE_LINE_CONTINUE", "&");
mf->AddDefinition("CMAKE_MAKE_SYMBOLIC_RULE", ".SYMBOLIC");
- mf->AddDefinition("CMAKE_NO_QUOTED_OBJECTS", "1");
mf->AddDefinition("CMAKE_GENERATOR_CC", "wcl386");
mf->AddDefinition("CMAKE_GENERATOR_CXX", "wcl386");
this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional);
}
-///! Create a local generator appropriate to this Global Generator
-cmLocalGenerator *cmGlobalWatcomWMakeGenerator::CreateLocalGenerator()
-{
- cmLocalUnixMakefileGenerator3* lg = new cmLocalUnixMakefileGenerator3;
- lg->SetSilentNoColon(true);
- lg->SetDefineWindowsNULL(true);
- lg->SetWindowsShell(true);
- lg->SetWatcomWMake(true);
- lg->SetMakeSilentFlag("-s -h");
- lg->SetGlobalGenerator(this);
- lg->SetIgnoreLibPrefix(true);
- lg->SetPassMakeflags(false);
- lg->SetUnixCD(false);
- lg->SetIncludeDirective("!include");
- return lg;
-}
-
//----------------------------------------------------------------------------
void cmGlobalWatcomWMakeGenerator
::GetDocumentation(cmDocumentationEntry& entry)
{
entry.Name = cmGlobalWatcomWMakeGenerator::GetActualName();
entry.Brief = "Generates Watcom WMake makefiles.";
- entry.Full = "";
}
diff --git a/Source/cmGlobalWatcomWMakeGenerator.h b/Source/cmGlobalWatcomWMakeGenerator.h
index 23e60a1fc..4bfcf0640 100644
--- a/Source/cmGlobalWatcomWMakeGenerator.h
+++ b/Source/cmGlobalWatcomWMakeGenerator.h
@@ -22,27 +22,27 @@
class cmGlobalWatcomWMakeGenerator : public cmGlobalUnixMakefileGenerator3
{
public:
- cmGlobalWatcomWMakeGenerator();
+ cmGlobalWatcomWMakeGenerator(cmake* cm);
static cmGlobalGeneratorFactory* NewFactory() {
return new cmGlobalGeneratorSimpleFactory
<cmGlobalWatcomWMakeGenerator>(); }
///! Get the name for the generator.
- virtual const char* GetName() const {
+ virtual std::string GetName() const {
return cmGlobalWatcomWMakeGenerator::GetActualName();}
- static const char* GetActualName() {return "Watcom WMake";}
+ static std::string GetActualName() {return "Watcom WMake";}
/** Get the documentation entry for this generator. */
static void GetDocumentation(cmDocumentationEntry& entry);
- ///! Create a local generator appropriate to this Global Generator
- virtual cmLocalGenerator *CreateLocalGenerator();
-
/**
- * Try to determine system infomation such as shared library
+ * Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
cmMakefile *, bool optional);
+
+ virtual bool AllowNotParallel() const { return false; }
+ virtual bool AllowDeleteOnError() const { return false; }
};
#endif
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index c181c5926..526e32f98 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -21,6 +21,7 @@
#include "cmCustomCommandGenerator.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGeneratorFactory.h"
+#include "cmAlgorithms.h"
#include <cmsys/auto_ptr.hxx>
@@ -34,17 +35,17 @@ class cmXcodeVersionParser : public cmXMLParser
{
public:
cmXcodeVersionParser(): Version("1.5") {}
- void StartElement(const char* , const char** )
+ void StartElement(const std::string&, const char**)
{
this->Data = "";
}
- void EndElement(const char* name)
+ void EndElement(const std::string& name)
{
- if(strcmp(name, "key") == 0)
+ if(name == "key")
{
this->Key = this->Data;
}
- else if(strcmp(name, "string") == 0)
+ else if(name == "string")
{
if(this->Key == "CFBundleShortVersionString")
{
@@ -116,17 +117,22 @@ public:
class cmGlobalXCodeGenerator::Factory : public cmGlobalGeneratorFactory
{
public:
- virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const;
+ virtual cmGlobalGenerator*
+ CreateGlobalGenerator(const std::string& name, cmake* cm) const;
virtual void GetDocumentation(cmDocumentationEntry& entry) const {
cmGlobalXCodeGenerator::GetDocumentation(entry); }
virtual void GetGenerators(std::vector<std::string>& names) const {
names.push_back(cmGlobalXCodeGenerator::GetActualName()); }
+
+ virtual bool SupportsToolset() const { return true; }
};
//----------------------------------------------------------------------------
-cmGlobalXCodeGenerator::cmGlobalXCodeGenerator(std::string const& version)
+cmGlobalXCodeGenerator::cmGlobalXCodeGenerator(cmake* cm,
+ std::string const& version)
+ : cmGlobalGenerator(cm)
{
this->VersionString = version;
@@ -135,13 +141,13 @@ cmGlobalXCodeGenerator::cmGlobalXCodeGenerator(std::string const& version)
sscanf(this->VersionString.c_str(), "%u.%u", &v[0], &v[1]);
this->XcodeVersion = 10*v[0] + v[1];
- this->FindMakeProgramFile = "CMakeFindXCode.cmake";
this->RootObject = 0;
this->MainGroupChildren = 0;
this->SourcesGroupChildren = 0;
this->ResourcesGroupChildren = 0;
this->CurrentMakefile = 0;
this->CurrentLocalGenerator = 0;
+ this->XcodeBuildCommandInitialized = false;
}
//----------------------------------------------------------------------------
@@ -152,9 +158,9 @@ cmGlobalGeneratorFactory* cmGlobalXCodeGenerator::NewFactory()
//----------------------------------------------------------------------------
cmGlobalGenerator* cmGlobalXCodeGenerator::Factory
-::CreateGlobalGenerator(const char* name) const
+::CreateGlobalGenerator(const std::string& name, cmake* cm) const
{
- if (strcmp(name, GetActualName()))
+ if (name != GetActualName())
return 0;
#if defined(CMAKE_BUILD_WITH_CMAKE)
cmXcodeVersionParser parser;
@@ -162,8 +168,8 @@ cmGlobalGenerator* cmGlobalXCodeGenerator::Factory
{
std::string out;
std::string::size_type pos;
- if(cmSystemTools::RunSingleCommand("xcode-select --print-path", &out, 0, 0,
- cmSystemTools::OUTPUT_NONE) &&
+ if(cmSystemTools::RunSingleCommand("xcode-select --print-path", &out, 0,
+ 0, 0, cmSystemTools::OUTPUT_NONE) &&
(pos = out.find(".app/"), pos != out.npos))
{
versionFile = out.substr(0, pos+5)+"Contents/version.plist";
@@ -185,7 +191,7 @@ cmGlobalGenerator* cmGlobalXCodeGenerator::Factory
("/Developer/Applications/Xcode.app/Contents/version.plist");
}
cmsys::auto_ptr<cmGlobalXCodeGenerator>
- gg(new cmGlobalXCodeGenerator(parser.Version));
+ gg(new cmGlobalXCodeGenerator(cm, parser.Version));
if (gg->XcodeVersion == 20)
{
cmSystemTools::Message("Xcode 2.0 not really supported by cmake, "
@@ -196,21 +202,70 @@ cmGlobalGenerator* cmGlobalXCodeGenerator::Factory
#else
std::cerr << "CMake should be built with cmake to use Xcode, "
"default to Xcode 1.5\n";
- return new cmGlobalXCodeGenerator;
+ return new cmGlobalXCodeGenerator(cm);
#endif
}
//----------------------------------------------------------------------------
-bool cmGlobalXCodeGenerator::SetGeneratorToolset(std::string const& ts)
+void cmGlobalXCodeGenerator::FindMakeProgram(cmMakefile* mf)
+{
+ // The Xcode generator knows how to lookup its build tool
+ // directly instead of needing a helper module to do it, so we
+ // do not actually need to put CMAKE_MAKE_PROGRAM into the cache.
+ if(cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM")))
+ {
+ mf->AddDefinition("CMAKE_MAKE_PROGRAM",
+ this->GetXcodeBuildCommand().c_str());
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string const& cmGlobalXCodeGenerator::GetXcodeBuildCommand()
+{
+ if(!this->XcodeBuildCommandInitialized)
+ {
+ this->XcodeBuildCommandInitialized = true;
+ this->XcodeBuildCommand = this->FindXcodeBuildCommand();
+ }
+ return this->XcodeBuildCommand;
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalXCodeGenerator::FindXcodeBuildCommand()
+{
+ if (this->XcodeVersion >= 40)
+ {
+ std::string makeProgram = cmSystemTools::FindProgram("xcodebuild");
+ if (makeProgram.empty())
+ {
+ makeProgram = "xcodebuild";
+ }
+ return makeProgram;
+ }
+ else
+ {
+ // Use cmakexbuild wrapper to suppress environment dump from output.
+ return cmSystemTools::GetCMakeCommand() + "xbuild";
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalXCodeGenerator::SetGeneratorToolset(std::string const& ts,
+ cmMakefile* mf)
{
if(this->XcodeVersion >= 30)
{
- this->PlatformToolset = ts;
+ this->GeneratorToolset = ts;
+ if(!this->GeneratorToolset.empty())
+ {
+ mf->AddDefinition("CMAKE_XCODE_PLATFORM_TOOLSET",
+ this->GeneratorToolset.c_str());
+ }
return true;
}
else
{
- return cmGlobalGenerator::SetGeneratorToolset(ts);
+ return cmGlobalGenerator::SetGeneratorToolset(ts, mf);
}
}
@@ -234,15 +289,10 @@ void cmGlobalXCodeGenerator::EnableLanguage(std::vector<std::string>const&
"Semicolon separated list of supported configuration types, "
"only supports Debug, Release, MinSizeRel, and RelWithDebInfo, "
"anything else will be ignored.",
- cmCacheManager::STRING);
+ cmState::STRING);
}
}
mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1");
- if(!this->PlatformToolset.empty())
- {
- mf->AddDefinition("CMAKE_XCODE_PLATFORM_TOOLSET",
- this->PlatformToolset.c_str());
- }
this->cmGlobalGenerator::EnableLanguage(lang, mf, optional);
const char* osxArch =
mf->GetDefinition("CMAKE_OSX_ARCHITECTURES");
@@ -257,98 +307,80 @@ void cmGlobalXCodeGenerator::EnableLanguage(std::vector<std::string>const&
}
//----------------------------------------------------------------------------
-std::string cmGlobalXCodeGenerator
-::GenerateBuildCommand(const char* makeProgram,
- const char *projectName,
- const char *projectDir,
- const char* additionalOptions,
- const char *targetName,
- const char* config,
- bool ignoreErrors,
- bool)
+void
+cmGlobalXCodeGenerator::GenerateBuildCommand(
+ std::vector<std::string>& makeCommand,
+ const std::string& makeProgram,
+ const std::string& projectName,
+ const std::string& /*projectDir*/,
+ const std::string& targetName,
+ const std::string& config,
+ bool /*fast*/, bool /*verbose*/,
+ std::vector<std::string> const& makeOptions)
{
- // Config is not used yet
- (void) ignoreErrors;
- (void) projectDir;
-
// now build the test
- if(makeProgram == 0 || !strlen(makeProgram))
- {
- cmSystemTools::Error(
- "Generator cannot find the appropriate make command.");
- return "";
- }
- std::string makeCommand =
- cmSystemTools::ConvertToOutputPath(makeProgram);
- std::string lowerCaseCommand = makeCommand;
- cmSystemTools::LowerCase(lowerCaseCommand);
+ makeCommand.push_back(
+ this->SelectMakeProgram(makeProgram, this->GetXcodeBuildCommand())
+ );
- makeCommand += " -project ";
- makeCommand += projectName;
- makeCommand += ".xcode";
+ makeCommand.push_back("-project");
+ std::string projectArg = projectName;
+ projectArg += ".xcode";
if(this->XcodeVersion > 20)
{
- makeCommand += "proj";
+ projectArg += "proj";
}
+ makeCommand.push_back(projectArg);
bool clean = false;
- if ( targetName && strcmp(targetName, "clean") == 0 )
+ std::string realTarget = targetName;
+ if ( realTarget == "clean" )
{
clean = true;
- targetName = "ALL_BUILD";
+ realTarget = "ALL_BUILD";
}
if(clean)
{
- makeCommand += " clean";
+ makeCommand.push_back("clean");
}
else
{
- makeCommand += " build";
- }
- makeCommand += " -target ";
- // if it is a null string for config don't use it
- if(config && *config == 0)
- {
- config = 0;
+ makeCommand.push_back("build");
}
- if (targetName && strlen(targetName))
+ makeCommand.push_back("-target");
+ if (!realTarget.empty())
{
- makeCommand += targetName;
+ makeCommand.push_back(realTarget);
}
else
{
- makeCommand += "ALL_BUILD";
+ makeCommand.push_back("ALL_BUILD");
}
if(this->XcodeVersion == 15)
{
- makeCommand += " -buildstyle Development ";
+ makeCommand.push_back("-buildstyle");
+ makeCommand.push_back("Development");
}
else
{
- makeCommand += " -configuration ";
- makeCommand += config?config:"Debug";
- }
- if ( additionalOptions )
- {
- makeCommand += " ";
- makeCommand += additionalOptions;
+ makeCommand.push_back("-configuration");
+ makeCommand.push_back(!config.empty()?config:"Debug");
}
- return makeCommand;
+ makeCommand.insert(makeCommand.end(),
+ makeOptions.begin(), makeOptions.end());
}
//----------------------------------------------------------------------------
///! Create a local generator appropriate to this Global Generator
-cmLocalGenerator *cmGlobalXCodeGenerator::CreateLocalGenerator()
+cmLocalGenerator *
+cmGlobalXCodeGenerator::CreateLocalGenerator(cmMakefile* mf)
{
- cmLocalGenerator *lg = new cmLocalXCodeGenerator;
- lg->SetGlobalGenerator(this);
- return lg;
+ return new cmLocalXCodeGenerator(this, mf);
}
-//----------------------------------------------------------------------------
-void cmGlobalXCodeGenerator::Generate()
+void cmGlobalXCodeGenerator::AddExtraIDETargets()
{
- std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it;
+ std::map<std::string, std::vector<cmLocalGenerator*> >::iterator it;
// make sure extra targets are added before calling
// the parent generate which will call trace depends
for(it = this->ProjectMap.begin(); it!= this->ProjectMap.end(); ++it)
@@ -358,12 +390,16 @@ void cmGlobalXCodeGenerator::Generate()
// add ALL_BUILD, INSTALL, etc
this->AddExtraTargets(root, it->second);
}
- this->ForceLinkerLanguages();
+}
+
+void cmGlobalXCodeGenerator::Generate()
+{
this->cmGlobalGenerator::Generate();
if(cmSystemTools::GetErrorOccuredFlag())
{
return;
}
+ std::map<std::string, std::vector<cmLocalGenerator*> >::iterator it;
for(it = this->ProjectMap.begin(); it!= this->ProjectMap.end(); ++it)
{
cmLocalGenerator* root = it->second[0];
@@ -376,15 +412,17 @@ void cmGlobalXCodeGenerator::Generate()
//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::SetGenerationRoot(cmLocalGenerator* root)
{
- this->CurrentProject = root->GetMakefile()->GetProjectName();
+ this->CurrentProject = root->GetProjectName();
this->SetCurrentLocalGenerator(root);
- cmSystemTools::SplitPath(this->CurrentMakefile->GetCurrentDirectory(),
- this->ProjectSourceDirectoryComponents);
- cmSystemTools::SplitPath(this->CurrentMakefile->GetCurrentOutputDirectory(),
- this->ProjectOutputDirectoryComponents);
+ cmSystemTools::SplitPath(
+ this->CurrentLocalGenerator->GetCurrentSourceDirectory(),
+ this->ProjectSourceDirectoryComponents);
+ cmSystemTools::SplitPath(
+ this->CurrentLocalGenerator->GetCurrentBinaryDirectory(),
+ this->ProjectOutputDirectoryComponents);
this->CurrentXCodeHackMakefile =
- root->GetMakefile()->GetCurrentOutputDirectory();
+ root->GetCurrentBinaryDirectory();
this->CurrentXCodeHackMakefile += "/CMakeScripts";
cmSystemTools::MakeDirectory(this->CurrentXCodeHackMakefile.c_str());
this->CurrentXCodeHackMakefile += "/XCODE_DEPEND_HELPER.make";
@@ -418,19 +456,21 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
// Add ALL_BUILD
const char* no_working_directory = 0;
std::vector<std::string> no_depends;
- mf->AddUtilityCommand("ALL_BUILD", true, no_depends,
+ cmTarget* allbuild = mf->AddUtilityCommand("ALL_BUILD", true, no_depends,
no_working_directory,
"echo", "Build all projects");
- cmTarget* allbuild = mf->FindTarget("ALL_BUILD");
+
+ cmGeneratorTarget* allBuildGt = new cmGeneratorTarget(allbuild, root);
+ root->AddGeneratorTarget(allBuildGt);
// Refer to the main build configuration file for easy editing.
- std::string listfile = mf->GetStartDirectory();
+ std::string listfile = root->GetCurrentSourceDirectory();
listfile += "/";
listfile += "CMakeLists.txt";
- allbuild->AddSource(listfile.c_str());
+ allBuildGt->AddSource(listfile.c_str());
// Add XCODE depend helper
- std::string dir = mf->GetCurrentOutputDirectory();
+ std::string dir = root->GetCurrentBinaryDirectory();
cmCustomCommandLine makeHelper;
if(this->XcodeVersion < 50)
{
@@ -450,9 +490,13 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
std::string file = this->ConvertToRelativeForMake(
this->CurrentReRunCMakeMakefile.c_str());
cmSystemTools::ReplaceString(file, "\\ ", " ");
- mf->AddUtilityCommand(CMAKE_CHECK_BUILD_SYSTEM_TARGET, true, no_depends,
+ cmTarget* check = mf->AddUtilityCommand(CMAKE_CHECK_BUILD_SYSTEM_TARGET,
+ true, no_depends,
no_working_directory,
"make", "-f", file.c_str());
+
+ cmGeneratorTarget* checkGt = new cmGeneratorTarget(check, root);
+ root->AddGeneratorTarget(checkGt);
}
// now make the allbuild depend on all the non-utility targets
@@ -466,14 +510,22 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
continue;
}
- cmTargets& tgts = lg->GetMakefile()->GetTargets();
- for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
+ std::vector<cmGeneratorTarget*> tgts = lg->GetGeneratorTargets();
+ for(std::vector<cmGeneratorTarget*>::iterator l = tgts.begin();
+ l != tgts.end(); l++)
{
- cmTarget& target = l->second;
+ cmGeneratorTarget* target = *l;
+
+ if (target->GetType() == cmState::GLOBAL_TARGET)
+ {
+ continue;
+ }
- if (regenerate && (l->first != CMAKE_CHECK_BUILD_SYSTEM_TARGET))
+ std::string targetName = target->GetName();
+
+ if (regenerate && (targetName != CMAKE_CHECK_BUILD_SYSTEM_TARGET))
{
- target.AddUtility(CMAKE_CHECK_BUILD_SYSTEM_TARGET);
+ target->Target->AddUtility(CMAKE_CHECK_BUILD_SYSTEM_TARGET);
}
// make all exe, shared libs and modules
@@ -481,18 +533,20 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
// this will make sure that when the next target is built
// things are up-to-date
if(!makeHelper.empty() &&
- (target.GetType() == cmTarget::EXECUTABLE ||
+ (target->GetType() == cmState::EXECUTABLE ||
// Nope - no post-build for OBJECT_LIRBRARY
-// target.GetType() == cmTarget::OBJECT_LIBRARY ||
- target.GetType() == cmTarget::STATIC_LIBRARY ||
- target.GetType() == cmTarget::SHARED_LIBRARY ||
- target.GetType() == cmTarget::MODULE_LIBRARY))
+// target->GetType() == cmState::OBJECT_LIBRARY ||
+ target->GetType() == cmState::STATIC_LIBRARY ||
+ target->GetType() == cmState::SHARED_LIBRARY ||
+ target->GetType() == cmState::MODULE_LIBRARY))
{
makeHelper[makeHelper.size()-1] = // fill placeholder
- this->PostBuildMakeTarget(target.GetName(), "$(CONFIGURATION)");
+ this->PostBuildMakeTarget(target->GetName(), "$(CONFIGURATION)");
cmCustomCommandLines commandLines;
commandLines.push_back(makeHelper);
- lg->GetMakefile()->AddCustomCommandToTarget(target.GetName(),
+ std::vector<std::string> no_byproducts;
+ lg->GetMakefile()->AddCustomCommandToTarget(target->GetName(),
+ no_byproducts,
no_depends,
commandLines,
cmTarget::POST_BUILD,
@@ -500,16 +554,17 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
dir.c_str());
}
- if(!target.GetPropertyAsBool("EXCLUDE_FROM_ALL"))
+ if(target->GetType() != cmState::INTERFACE_LIBRARY
+ && !target->GetPropertyAsBool("EXCLUDE_FROM_ALL"))
{
- allbuild->AddUtility(target.GetName());
+ allbuild->AddUtility(target->GetName());
}
// Refer to the build configuration file for easy editing.
- listfile = lg->GetMakefile()->GetStartDirectory();
+ listfile = lg->GetCurrentSourceDirectory();
listfile += "/";
listfile += "CMakeLists.txt";
- target.AddSource(listfile.c_str());
+ target->AddSource(listfile.c_str());
}
}
}
@@ -518,7 +573,6 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
void cmGlobalXCodeGenerator::CreateReRunCMakeFile(
cmLocalGenerator* root, std::vector<cmLocalGenerator*> const& gens)
{
- cmMakefile* mf = root->GetMakefile();
std::vector<std::string> lfiles;
for(std::vector<cmLocalGenerator*>::const_iterator gi = gens.begin();
gi != gens.end(); ++gi)
@@ -532,7 +586,7 @@ void cmGlobalXCodeGenerator::CreateReRunCMakeFile(
std::vector<std::string>::iterator new_end =
std::unique(lfiles.begin(), lfiles.end());
lfiles.erase(new_end, lfiles.end());
- this->CurrentReRunCMakeMakefile = mf->GetStartOutputDirectory();
+ this->CurrentReRunCMakeMakefile = root->GetCurrentBinaryDirectory();
this->CurrentReRunCMakeMakefile += "/CMakeScripts";
cmSystemTools::MakeDirectory(this->CurrentReRunCMakeMakefile.c_str());
this->CurrentReRunCMakeMakefile += "/ReRunCMake.make";
@@ -540,7 +594,7 @@ void cmGlobalXCodeGenerator::CreateReRunCMakeFile(
(this->CurrentReRunCMakeMakefile.c_str());
makefileStream.SetCopyIfDifferent(true);
makefileStream << "# Generated by CMake, DO NOT EDIT\n";
- std::string checkCache = mf->GetHomeOutputDirectory();
+ std::string checkCache = root->GetBinaryDirectory();
checkCache += "/";
checkCache += cmake::GetCMakeFilesDirectoryPostSlash();
checkCache += "cmake.check_cache";
@@ -551,12 +605,26 @@ void cmGlobalXCodeGenerator::CreateReRunCMakeFile(
{
makefileStream << "\\\n" << this->ConvertToRelativeForMake(i->c_str());
}
- std::string cmake = mf->GetRequiredDefinition("CMAKE_COMMAND");
- makefileStream << "\n\t" << this->ConvertToRelativeForMake(cmake.c_str())
+ makefileStream << "\n\t" <<
+ this->ConvertToRelativeForMake(cmSystemTools::GetCMakeCommand().c_str())
<< " -H" << this->ConvertToRelativeForMake(
- mf->GetHomeDirectory())
+ root->GetSourceDirectory())
<< " -B" << this->ConvertToRelativeForMake(
- mf->GetHomeOutputDirectory()) << "\n";
+ root->GetBinaryDirectory()) << "\n";
+}
+
+//----------------------------------------------------------------------------
+
+static bool objectIdLessThan(cmXCodeObject* l, cmXCodeObject* r)
+{
+ return l->GetId() < r->GetId();
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalXCodeGenerator::SortXCodeObjects()
+{
+ std::sort(this->XCodeObjects.begin(), this->XCodeObjects.end(),
+ objectIdLessThan);
}
//----------------------------------------------------------------------------
@@ -569,6 +637,7 @@ void cmGlobalXCodeGenerator::ClearXCodeObjects()
}
this->XCodeObjects.clear();
this->XCodeObjectIDs.clear();
+ this->XCodeObjectMap.clear();
this->GroupMap.clear();
this->GroupNameMap.clear();
this->TargetGroup.clear();
@@ -580,7 +649,7 @@ void cmGlobalXCodeGenerator::addObject(cmXCodeObject *obj)
{
if(obj->GetType() == cmXCodeObject::OBJECT)
{
- cmStdString id = obj->GetId();
+ std::string id = obj->GetId();
// If this is a duplicate id, it's an error:
//
@@ -624,7 +693,7 @@ cmGlobalXCodeGenerator::CreateObject(cmXCodeObject::Type type)
//----------------------------------------------------------------------------
cmXCodeObject*
-cmGlobalXCodeGenerator::CreateString(const char* s)
+cmGlobalXCodeGenerator::CreateString(const std::string& s)
{
cmXCodeObject* obj = this->CreateObject(cmXCodeObject::STRING);
obj->SetString(s);
@@ -641,34 +710,44 @@ cmXCodeObject* cmGlobalXCodeGenerator
}
//----------------------------------------------------------------------------
-cmStdString
-GetGroupMapKeyFromPath(cmTarget& cmtarget, const std::string& fullpath)
+cmXCodeObject* cmGlobalXCodeGenerator
+::CreateFlatClone(cmXCodeObject* orig)
+{
+ cmXCodeObject* obj = this->CreateObject(orig->GetType());
+ obj->CopyAttributes(orig);
+ return obj;
+}
+
+//----------------------------------------------------------------------------
+std::string
+GetGroupMapKeyFromPath(cmGeneratorTarget* target, const std::string& fullpath)
{
- cmStdString key(cmtarget.GetName());
+ std::string key(target->GetName());
key += "-";
key += fullpath;
return key;
}
//----------------------------------------------------------------------------
-cmStdString
-GetGroupMapKey(cmTarget& cmtarget, cmSourceFile* sf)
+std::string
+GetGroupMapKey(cmGeneratorTarget* target, cmSourceFile* sf)
{
- return GetGroupMapKeyFromPath(cmtarget, sf->GetFullPath());
+ return GetGroupMapKeyFromPath(target, sf->GetFullPath());
}
//----------------------------------------------------------------------------
cmXCodeObject*
cmGlobalXCodeGenerator::CreateXCodeSourceFileFromPath(
const std::string &fullpath,
- cmTarget& cmtarget,
- const std::string &lang)
+ cmGeneratorTarget* target,
+ const std::string &lang,
+ cmSourceFile* sf)
{
// Using a map and the full path guarantees that we will always get the same
// fileRef object for any given full path.
//
cmXCodeObject* fileRef =
- this->CreateXCodeFileReferenceFromPath(fullpath, cmtarget, lang);
+ this->CreateXCodeFileReferenceFromPath(fullpath, target, lang, sf);
cmXCodeObject* buildFile = this->CreateObject(cmXCodeObject::PBXBuildFile);
buildFile->SetComment(fileRef->GetComment());
@@ -681,7 +760,7 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFileFromPath(
cmXCodeObject*
cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
cmSourceFile* sf,
- cmTarget& cmtarget)
+ cmGeneratorTarget* gtgt)
{
// Add flags from target and source file properties.
std::string flags;
@@ -700,22 +779,18 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
sf->GetProperty("COMPILE_DEFINITIONS"), true);
if (!flagsBuild.IsEmpty())
{
- if (flags.size())
+ if (!flags.empty())
{
flags += ' ';
}
flags += flagsBuild.GetString();
}
- const char* lang =
+ std::string lang =
this->CurrentLocalGenerator->GetSourceFileLanguage(*sf);
- if (!lang)
- {
- lang = "";
- }
cmXCodeObject* buildFile =
- this->CreateXCodeSourceFileFromPath(sf->GetFullPath(), cmtarget, lang);
+ this->CreateXCodeSourceFileFromPath(sf->GetFullPath(), gtgt, lang, sf);
cmXCodeObject* fileRef = buildFile->GetObject("fileRef")->GetObject();
cmXCodeObject* settings =
@@ -724,22 +799,24 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
// Is this a resource file in this target? Add it to the resources group...
//
- cmTarget::SourceFileFlags tsFlags = cmtarget.GetTargetSourceFileFlags(sf);
- bool isResource = (tsFlags.Type == cmTarget::SourceFileTypeResource);
+
+ cmGeneratorTarget::SourceFileFlags tsFlags =
+ gtgt->GetTargetSourceFileFlags(sf);
+ bool isResource = tsFlags.Type == cmGeneratorTarget::SourceFileTypeResource;
// Is this a "private" or "public" framework header file?
// Set the ATTRIBUTES attribute appropriately...
//
- if(cmtarget.IsFrameworkOnApple())
+ if(gtgt->IsFrameworkOnApple())
{
- if(tsFlags.Type == cmTarget::SourceFileTypePrivateHeader)
+ if(tsFlags.Type == cmGeneratorTarget::SourceFileTypePrivateHeader)
{
cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
attrs->AddObject(this->CreateString("Private"));
settings->AddAttribute("ATTRIBUTES", attrs);
isResource = true;
}
- else if(tsFlags.Type == cmTarget::SourceFileTypePublicHeader)
+ else if(tsFlags.Type == cmGeneratorTarget::SourceFileTypePublicHeader)
{
cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
attrs->AddObject(this->CreateString("Public"));
@@ -764,7 +841,8 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
//----------------------------------------------------------------------------
std::string
GetSourcecodeValueFromFileExtension(const std::string& _ext,
- const std::string& lang)
+ const std::string& lang,
+ bool& keepLastKnownFileType)
{
std::string ext = cmSystemTools::LowerCase(_ext);
std::string sourcecode = "sourcecode";
@@ -773,12 +851,18 @@ GetSourcecodeValueFromFileExtension(const std::string& _ext,
{
sourcecode = "compiled.mach-o.objfile";
}
+ else if(ext == "xctest")
+ {
+ sourcecode = "wrapper.cfbundle";
+ }
else if(ext == "xib")
{
+ keepLastKnownFileType = true;
sourcecode = "file.xib";
}
else if(ext == "storyboard")
{
+ keepLastKnownFileType = true;
sourcecode = "file.storyboard";
}
else if(ext == "mm")
@@ -789,9 +873,9 @@ GetSourcecodeValueFromFileExtension(const std::string& _ext,
{
sourcecode += ".c.objc";
}
- else if(ext == "xib")
+ else if (ext == "swift")
{
- sourcecode += ".file.xib";
+ sourcecode += ".swift";
}
else if(ext == "plist")
{
@@ -808,6 +892,7 @@ GetSourcecodeValueFromFileExtension(const std::string& _ext,
}
else if(ext == "png" || ext == "gif" || ext == "jpg")
{
+ keepLastKnownFileType = true;
sourcecode = "image";
}
else if(ext == "txt")
@@ -830,6 +915,10 @@ GetSourcecodeValueFromFileExtension(const std::string& _ext,
{
sourcecode += ".asm";
}
+ else if (ext == "metal")
+ {
+ sourcecode += ".metal";
+ }
//else
// {
// // Already specialized above or we leave sourcecode == "sourcecode"
@@ -845,19 +934,18 @@ GetSourcecodeValueFromFileExtension(const std::string& _ext,
cmXCodeObject*
cmGlobalXCodeGenerator::CreateXCodeFileReferenceFromPath(
const std::string &fullpath,
- cmTarget& cmtarget,
- const std::string &lang)
+ cmGeneratorTarget* target,
+ const std::string &lang,
+ cmSourceFile* sf)
{
- std::string fname = fullpath;
- cmXCodeObject* fileRef = this->FileRefs[fname];
+ std::string key = GetGroupMapKeyFromPath(target, fullpath);
+ cmXCodeObject* fileRef = this->FileRefs[key];
if(!fileRef)
{
fileRef = this->CreateObject(cmXCodeObject::PBXFileReference);
- std::string comment = fname;
- fileRef->SetComment(fname.c_str());
- this->FileRefs[fname] = fileRef;
+ fileRef->SetComment(fullpath);
+ this->FileRefs[key] = fileRef;
}
- cmStdString key = GetGroupMapKeyFromPath(cmtarget, fullpath);
cmXCodeObject* group = this->GroupMap[key];
cmXCodeObject* children = group->GetObject("children");
if (!children->HasObject(fileRef))
@@ -866,22 +954,48 @@ cmGlobalXCodeGenerator::CreateXCodeFileReferenceFromPath(
}
fileRef->AddAttribute("fileEncoding", this->CreateString("4"));
- // Compute the extension.
- std::string ext;
- std::string realExt =
- cmSystemTools::GetFilenameLastExtension(fullpath);
- if(!realExt.empty())
+ bool useLastKnownFileType = false;
+ std::string fileType;
+ if(sf)
+ {
+ if(const char* e = sf->GetProperty("XCODE_EXPLICIT_FILE_TYPE"))
+ {
+ fileType = e;
+ }
+ else if(const char* l = sf->GetProperty("XCODE_LAST_KNOWN_FILE_TYPE"))
+ {
+ useLastKnownFileType = true;
+ fileType = l;
+ }
+ }
+ if(fileType.empty())
{
- // Extension without the leading '.'.
- ext = realExt.substr(1);
+ // Compute the extension without leading '.'.
+ std::string ext = cmSystemTools::GetFilenameLastExtension(fullpath);
+ if(!ext.empty())
+ {
+ ext = ext.substr(1);
+ }
+
+ // If fullpath references a directory, then we need to specify
+ // lastKnownFileType as folder in order for Xcode to be able to
+ // open the contents of the folder.
+ // (Xcode 4.6 does not like explicitFileType=folder).
+ if(cmSystemTools::FileIsDirectory(fullpath.c_str()))
+ {
+ fileType = (ext == "xcassets"? "folder.assetcatalog" : "folder");
+ useLastKnownFileType = true;
+ }
+ else
+ {
+ fileType = GetSourcecodeValueFromFileExtension(
+ ext, lang, useLastKnownFileType);
+ }
}
- std::string sourcecode = GetSourcecodeValueFromFileExtension(ext, lang);
- const char* attribute = (sourcecode == "file.storyboard") ?
- "lastKnownFileType" :
- "explicitFileType";
- fileRef->AddAttribute(attribute,
- this->CreateString(sourcecode.c_str()));
+ fileRef->AddAttribute(useLastKnownFileType? "lastKnownFileType"
+ : "explicitFileType",
+ this->CreateString(fileType));
// Store the file path relative to the top of the source tree.
std::string path = this->RelativeToSource(fullpath.c_str());
@@ -901,17 +1015,13 @@ cmGlobalXCodeGenerator::CreateXCodeFileReferenceFromPath(
//----------------------------------------------------------------------------
cmXCodeObject*
cmGlobalXCodeGenerator::CreateXCodeFileReference(cmSourceFile* sf,
- cmTarget& cmtarget)
+ cmGeneratorTarget* target)
{
- const char* lang =
+ std::string lang =
this->CurrentLocalGenerator->GetSourceFileLanguage(*sf);
- if (!lang)
- {
- lang = "";
- }
return this->CreateXCodeFileReferenceFromPath(
- sf->GetFullPath(), cmtarget, lang);
+ sf->GetFullPath(), target, lang, sf);
}
//----------------------------------------------------------------------------
@@ -937,8 +1047,8 @@ void cmGlobalXCodeGenerator::SetCurrentLocalGenerator(cmLocalGenerator* gen)
this->CurrentLocalGenerator = gen;
this->CurrentMakefile = gen->GetMakefile();
std::string outdir =
- cmSystemTools::CollapseFullPath(this->CurrentMakefile->
- GetCurrentOutputDirectory());
+ cmSystemTools::CollapseFullPath(this->CurrentLocalGenerator->
+ GetCurrentBinaryDirectory());
cmSystemTools::SplitPath(outdir.c_str(),
this->CurrentOutputDirectoryComponents);
@@ -961,34 +1071,79 @@ struct cmSourceFilePathCompare
};
//----------------------------------------------------------------------------
-void
+struct cmCompareTargets
+{
+ bool operator () (std::string const& a, std::string const& b) const
+ {
+ if (a == "ALL_BUILD")
+ {
+ return true;
+ }
+ if (b == "ALL_BUILD")
+ {
+ return false;
+ }
+ return strcmp(a.c_str(), b.c_str()) < 0;
+ }
+};
+
+//----------------------------------------------------------------------------
+bool
cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
std::vector<cmXCodeObject*>&
targets)
{
this->SetCurrentLocalGenerator(gen);
- cmTargets &tgts = this->CurrentMakefile->GetTargets();
- for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
+ std::vector<cmGeneratorTarget*> tgts =
+ this->CurrentLocalGenerator->GetGeneratorTargets();
+ typedef std::map<std::string, cmGeneratorTarget*, cmCompareTargets>
+ cmSortedTargets;
+ cmSortedTargets sortedTargets;
+ for(std::vector<cmGeneratorTarget*>::iterator l = tgts.begin();
+ l != tgts.end(); l++)
+ {
+ sortedTargets[(*l)->GetName()] = *l;
+ }
+ for(cmSortedTargets::iterator l = sortedTargets.begin();
+ l != sortedTargets.end(); l++)
{
- cmTarget& cmtarget = l->second;
+ cmGeneratorTarget* gtgt = l->second;
+
+ std::string targetName = gtgt->GetName();
// make sure ALL_BUILD, INSTALL, etc are only done once
- if(this->SpecialTargetEmitted(l->first.c_str()))
+ if(this->SpecialTargetEmitted(targetName.c_str()))
+ {
+ continue;
+ }
+
+ if(gtgt->GetType() == cmState::INTERFACE_LIBRARY)
{
continue;
}
- if(cmtarget.GetType() == cmTarget::UTILITY ||
- cmtarget.GetType() == cmTarget::GLOBAL_TARGET)
+ if(gtgt->GetType() == cmState::UTILITY ||
+ gtgt->GetType() == cmState::GLOBAL_TARGET)
{
- targets.push_back(this->CreateUtilityTarget(cmtarget));
+ cmXCodeObject* t = this->CreateUtilityTarget(gtgt);
+ if (!t)
+ {
+ return false;
+ }
+ targets.push_back(t);
continue;
}
// organize the sources
- std::vector<cmSourceFile*> classes = cmtarget.GetSourceFiles();
+ std::vector<cmSourceFile*> classes;
+ if (!gtgt->GetConfigCommonSourceFiles(classes))
+ {
+ return false;
+ }
std::sort(classes.begin(), classes.end(), cmSourceFilePathCompare());
+ gtgt->ComputeObjectMapping();
+
std::vector<cmXCodeObject*> externalObjFiles;
std::vector<cmXCodeObject*> headerFiles;
std::vector<cmXCodeObject*> resourceFiles;
@@ -998,25 +1153,29 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
{
cmXCodeObject* xsf =
this->CreateXCodeSourceFile(this->CurrentLocalGenerator,
- *i, cmtarget);
+ *i, gtgt);
cmXCodeObject* fr = xsf->GetObject("fileRef");
cmXCodeObject* filetype =
fr->GetObject()->GetObject("explicitFileType");
- cmTarget::SourceFileFlags tsFlags =
- cmtarget.GetTargetSourceFileFlags(*i);
+ cmGeneratorTarget::SourceFileFlags tsFlags =
+ gtgt->GetTargetSourceFileFlags(*i);
- if(strcmp(filetype->GetString(), "compiled.mach-o.objfile") == 0)
+ if(filetype &&
+ filetype->GetString() == "compiled.mach-o.objfile")
{
- externalObjFiles.push_back(xsf);
+ if ((*i)->GetObjectLibrary().empty())
+ {
+ externalObjFiles.push_back(xsf);
+ }
}
else if(this->IsHeaderFile(*i) ||
- (tsFlags.Type == cmTarget::SourceFileTypePrivateHeader) ||
- (tsFlags.Type == cmTarget::SourceFileTypePublicHeader))
+ (tsFlags.Type == cmGeneratorTarget::SourceFileTypePrivateHeader) ||
+ (tsFlags.Type == cmGeneratorTarget::SourceFileTypePublicHeader))
{
headerFiles.push_back(xsf);
}
- else if(tsFlags.Type == cmTarget::SourceFileTypeResource)
+ else if(tsFlags.Type == cmGeneratorTarget::SourceFileTypeResource)
{
resourceFiles.push_back(xsf);
}
@@ -1025,7 +1184,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
// Include this file in the build if it has a known language
// and has not been listed as an ignored extension for this
// generator.
- if(this->CurrentLocalGenerator->GetSourceFileLanguage(**i) &&
+ if(!this->CurrentLocalGenerator->GetSourceFileLanguage(**i).empty() &&
!this->IgnoreFile((*i)->GetExtension().c_str()))
{
sourceFiles.push_back(xsf);
@@ -1039,21 +1198,21 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
// the externalObjFiles above, except each one is not a cmSourceFile
// within the target.)
std::vector<std::string> objs;
- this->GetGeneratorTarget(&cmtarget)->UseObjectLibraries(objs);
+ gtgt->UseObjectLibraries(objs, "");
for(std::vector<std::string>::const_iterator
oi = objs.begin(); oi != objs.end(); ++oi)
{
std::string obj = *oi;
cmXCodeObject* xsf =
- this->CreateXCodeSourceFileFromPath(obj, cmtarget, "");
+ this->CreateXCodeSourceFileFromPath(obj, gtgt, "", 0);
externalObjFiles.push_back(xsf);
}
}
// some build phases only apply to bundles and/or frameworks
- bool isFrameworkTarget = cmtarget.IsFrameworkOnApple();
- bool isBundleTarget = cmtarget.GetPropertyAsBool("MACOSX_BUNDLE");
- bool isCFBundleTarget = cmtarget.IsCFBundleOnApple();
+ bool isFrameworkTarget = gtgt->IsFrameworkOnApple();
+ bool isBundleTarget = gtgt->GetPropertyAsBool("MACOSX_BUNDLE");
+ bool isCFBundleTarget = gtgt->IsCFBundleOnApple();
cmXCodeObject* buildFiles = 0;
@@ -1123,15 +1282,15 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
std::vector<cmXCodeObject*> contentBuildPhases;
if (isFrameworkTarget || isBundleTarget || isCFBundleTarget)
{
- typedef std::map<cmStdString, std::vector<cmSourceFile*> >
+ typedef std::map<std::string, std::vector<cmSourceFile*> >
mapOfVectorOfSourceFiles;
mapOfVectorOfSourceFiles bundleFiles;
for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
i != classes.end(); ++i)
{
- cmTarget::SourceFileFlags tsFlags =
- cmtarget.GetTargetSourceFileFlags(*i);
- if(tsFlags.Type == cmTarget::SourceFileTypeMacContent)
+ cmGeneratorTarget::SourceFileFlags tsFlags =
+ gtgt->GetTargetSourceFileFlags(*i);
+ if(tsFlags.Type == cmGeneratorTarget::SourceFileTypeMacContent)
{
bundleFiles[tsFlags.MacFolder].push_back(*i);
}
@@ -1146,8 +1305,8 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
this->CreateString("2147483647"));
copyFilesBuildPhase->AddAttribute("dstSubfolderSpec",
this->CreateString("6"));
- cmOStringStream ostr;
- if (cmtarget.IsFrameworkOnApple())
+ std::ostringstream ostr;
+ if (gtgt->IsFrameworkOnApple())
{
// dstPath in frameworks is relative to Versions/<version>
ostr << mit->first;
@@ -1168,7 +1327,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
{
cmXCodeObject* xsf =
this->CreateXCodeSourceFile(this->CurrentLocalGenerator,
- *sfIt, cmtarget);
+ *sfIt, gtgt);
buildFiles->AddObject(xsf);
}
contentBuildPhases.push_back(copyFilesBuildPhase);
@@ -1202,40 +1361,47 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
this->CreateCustomCommands(buildPhases, sourceBuildPhase,
headerBuildPhase, resourceBuildPhase,
contentBuildPhases,
- frameworkBuildPhase, cmtarget);
+ frameworkBuildPhase, gtgt);
- targets.push_back(this->CreateXCodeTarget(cmtarget, buildPhases));
+ targets.push_back(this->CreateXCodeTarget(gtgt, buildPhases));
}
+ return true;
}
//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator::ForceLinkerLanguages()
{
- // This makes sure all targets link using the proper language.
- for(std::map<cmStdString, cmTarget*>::const_iterator
- ti = this->TotalTargets.begin(); ti != this->TotalTargets.end(); ++ti)
+ for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i)
{
- this->ForceLinkerLanguage(*ti->second);
+ std::vector<cmGeneratorTarget*> tgts =
+ this->LocalGenerators[i]->GetGeneratorTargets();
+ // All targets depend on the build-system check target.
+ for(std::vector<cmGeneratorTarget*>::const_iterator ti = tgts.begin();
+ ti != tgts.end(); ++ti)
+ {
+ // This makes sure all targets link using the proper language.
+ this->ForceLinkerLanguage(*ti);
+ }
}
}
//----------------------------------------------------------------------------
-void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmTarget& cmtarget)
+void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmGeneratorTarget* gtgt)
{
// This matters only for targets that link.
- if(cmtarget.GetType() != cmTarget::EXECUTABLE &&
- cmtarget.GetType() != cmTarget::SHARED_LIBRARY &&
- cmtarget.GetType() != cmTarget::MODULE_LIBRARY)
+ if(gtgt->GetType() != cmState::EXECUTABLE &&
+ gtgt->GetType() != cmState::SHARED_LIBRARY &&
+ gtgt->GetType() != cmState::MODULE_LIBRARY)
{
return;
}
- const char* llang = cmtarget.GetLinkerLanguage("NOCONFIG");
- if(!llang) { return; }
+ std::string llang = gtgt->GetLinkerLanguage("NOCONFIG");
+ if(llang.empty()) { return; }
// If the language is compiled as a source trust Xcode to link with it.
- cmTarget::LinkImplementation const* impl =
- cmtarget.GetLinkImplementation("NOCONFIG", &cmtarget);
+ cmLinkImplementation const* impl =
+ gtgt->GetLinkImplementation("NOCONFIG");
for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
li != impl->Languages.end(); ++li)
{
@@ -1245,11 +1411,11 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmTarget& cmtarget)
// Add an empty source file to the target that compiles with the
// linker language. This should convince Xcode to choose the proper
// language.
- cmMakefile* mf = cmtarget.GetMakefile();
- std::string fname = mf->GetCurrentOutputDirectory();
+ cmMakefile* mf = gtgt->Target->GetMakefile();
+ std::string fname = gtgt->GetLocalGenerator()->GetCurrentBinaryDirectory();
fname += cmake::GetCMakeFilesDirectory();
fname += "/";
- fname += cmtarget.GetName();
+ fname += gtgt->GetName();
fname += "-CMakeForceLinker";
fname += ".";
fname += cmSystemTools::LowerCase(llang);
@@ -1259,8 +1425,8 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmTarget& cmtarget)
}
if(cmSourceFile* sf = mf->GetOrCreateSource(fname.c_str()))
{
- sf->SetProperty("LANGUAGE", llang);
- cmtarget.AddSourceFile(sf);
+ sf->SetProperty("LANGUAGE", llang.c_str());
+ gtgt->AddSource(fname);
}
}
@@ -1268,7 +1434,7 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmTarget& cmtarget)
bool cmGlobalXCodeGenerator::IsHeaderFile(cmSourceFile* sf)
{
const std::vector<std::string>& hdrExts =
- this->CurrentMakefile->GetHeaderExtensions();
+ this->CMakeInstance->GetHeaderExtensions();
return (std::find(hdrExts.begin(), hdrExts.end(), sf->GetExtension()) !=
hdrExts.end());
}
@@ -1277,7 +1443,7 @@ bool cmGlobalXCodeGenerator::IsHeaderFile(cmSourceFile* sf)
cmXCodeObject*
cmGlobalXCodeGenerator::CreateBuildPhase(const char* name,
const char* name2,
- cmTarget& cmtarget,
+ cmGeneratorTarget* target,
const std::vector<cmCustomCommand>&
commands)
{
@@ -1297,7 +1463,7 @@ cmGlobalXCodeGenerator::CreateBuildPhase(const char* name,
this->CreateString("0"));
buildPhase->AddAttribute("shellPath",
this->CreateString("/bin/sh"));
- this->AddCommandsToBuildPhase(buildPhase, cmtarget, commands,
+ this->AddCommandsToBuildPhase(buildPhase, target, commands,
name2);
return buildPhase;
}
@@ -1314,31 +1480,31 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases,
contentBuildPhases,
cmXCodeObject*
frameworkBuildPhase,
- cmTarget& cmtarget)
+ cmGeneratorTarget* gtgt)
{
std::vector<cmCustomCommand> const & prebuild
- = cmtarget.GetPreBuildCommands();
+ = gtgt->GetPreBuildCommands();
std::vector<cmCustomCommand> const & prelink
- = cmtarget.GetPreLinkCommands();
+ = gtgt->GetPreLinkCommands();
std::vector<cmCustomCommand> postbuild
- = cmtarget.GetPostBuildCommands();
+ = gtgt->GetPostBuildCommands();
- if(cmtarget.GetType() == cmTarget::SHARED_LIBRARY &&
- !cmtarget.IsFrameworkOnApple())
+ if(gtgt->GetType() == cmState::SHARED_LIBRARY &&
+ !gtgt->IsFrameworkOnApple())
{
cmCustomCommandLines cmd;
cmd.resize(1);
- cmd[0].push_back(this->CurrentMakefile->GetDefinition("CMAKE_COMMAND"));
+ cmd[0].push_back(cmSystemTools::GetCMakeCommand());
cmd[0].push_back("-E");
cmd[0].push_back("cmake_symlink_library");
std::string str_file = "$<TARGET_FILE:";
- str_file += cmtarget.GetName();
+ str_file += gtgt->GetName();
str_file += ">";
std::string str_so_file = "$<TARGET_SONAME_FILE:";
- str_so_file += cmtarget.GetName();
+ str_so_file += gtgt->GetName();
str_so_file += ">";
std::string str_link_file = "$<TARGET_LINKER_FILE:";
- str_link_file += cmtarget.GetName();
+ str_link_file += gtgt->GetName();
str_link_file += ">";
cmd[0].push_back(str_file);
cmd[0].push_back(str_so_file);
@@ -1347,6 +1513,7 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases,
cmCustomCommand command(this->CurrentMakefile,
std::vector<std::string>(),
std::vector<std::string>(),
+ std::vector<std::string>(),
cmd,
"Creating symlinks",
"");
@@ -1354,7 +1521,11 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases,
postbuild.push_back(command);
}
- std::vector<cmSourceFile*>const &classes = cmtarget.GetSourceFiles();
+ std::vector<cmSourceFile*> classes;
+ if (!gtgt->GetConfigCommonSourceFiles(classes))
+ {
+ return;
+ }
// add all the sources
std::vector<cmCustomCommand> commands;
for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
@@ -1369,19 +1540,19 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases,
cmXCodeObject* cmakeRulesBuildPhase =
this->CreateBuildPhase("CMake Rules",
"cmakeRulesBuildPhase",
- cmtarget, commands);
+ gtgt, commands);
// create prebuild phase
cmXCodeObject* preBuildPhase =
this->CreateBuildPhase("CMake PreBuild Rules", "preBuildCommands",
- cmtarget, prebuild);
+ gtgt, prebuild);
// create prelink phase
cmXCodeObject* preLinkPhase =
this->CreateBuildPhase("CMake PreLink Rules", "preLinkCommands",
- cmtarget, prelink);
+ gtgt, prelink);
// create postbuild phase
cmXCodeObject* postBuildPhase =
this->CreateBuildPhase("CMake PostBuild Rules", "postBuildPhase",
- cmtarget, postbuild);
+ gtgt, postbuild);
// The order here is the order they will be built in.
// The order "headers, resources, sources" mimics a native project generated
@@ -1462,45 +1633,92 @@ std::string cmGlobalXCodeGenerator::ExtractFlag(const char* flag,
}
//----------------------------------------------------------------------------
+// This function removes each matching occurrence of the expression and
+// returns the last one (i.e., the dominant flag in GCC)
+std::string cmGlobalXCodeGenerator::ExtractFlagRegex(const char* exp,
+ int matchIndex,
+ std::string& flags)
+{
+ std::string retFlag;
+
+ cmsys::RegularExpression regex(exp);
+ assert(regex.is_valid());
+ if(!regex.is_valid())
+ {
+ return retFlag;
+ }
+
+ std::string::size_type offset = 0;
+
+ while(regex.find(flags.c_str() + offset))
+ {
+ const std::string::size_type startPos = offset + regex.start(matchIndex);
+ const std::string::size_type endPos = offset + regex.end(matchIndex);
+ const std::string::size_type size = endPos - startPos;
+
+ offset = startPos + 1;
+
+ retFlag.assign(flags, startPos, size);
+ flags.replace(startPos, size, size, ' ');
+ }
+
+ return retFlag;
+}
+
+ //----------------------------------------------------------------------------
+// This function strips off Xcode attributes that do not target the current
+// configuration
void
-cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
- cmTarget& target,
- std::vector<cmCustomCommand>
- const & commands,
- const char* name)
+cmGlobalXCodeGenerator
+::FilterConfigurationAttribute(std::string const& configName,
+ std::string& attribute)
{
+ // Handle [variant=<config>] condition explicitly here.
+ std::string::size_type beginVariant = attribute.find("[variant=");
+ if (beginVariant == std::string::npos)
+ {
+ // There is no variant in this attribute.
+ return;
+ }
- // collect multiple outputs of custom commands into a set
- // which will be used for every configuration
- std::map<cmStdString, cmStdString> multipleOutputPairs;
- for(std::vector<cmCustomCommand>::const_iterator i = commands.begin();
- i != commands.end(); ++i)
+ std::string::size_type endVariant = attribute.find("]", beginVariant+9);
+ if (endVariant == std::string::npos)
{
- cmCustomCommand const& cc = *i;
- if(!cc.GetCommandLines().empty())
- {
- const std::vector<std::string>& outputs = cc.GetOutputs();
- if(!outputs.empty())
- {
- // If there are more than one outputs treat the
- // first as the primary output and make the rest depend on it.
- std::vector<std::string>::const_iterator o = outputs.begin();
- std::string primaryOutput = this->ConvertToRelativeForMake(o->c_str());
- for(++o; o != outputs.end(); ++o)
- {
- std::string currentOutput=this->ConvertToRelativeForMake(o->c_str());
- multipleOutputPairs[currentOutput] = primaryOutput;
- }
- }
- }
+ // There is no terminating bracket.
+ return;
+ }
+
+ // Compare the variant to the configuration.
+ std::string variant =
+ attribute.substr(beginVariant+9, endVariant-beginVariant-9);
+ if (variant == configName)
+ {
+ // The variant matches the configuration so use this
+ // attribute but drop the [variant=<config>] condition.
+ attribute.erase(beginVariant, endVariant-beginVariant+1);
}
+ else
+ {
+ // The variant does not match the configuration so
+ // do not use this attribute.
+ attribute.clear();
+ }
+}
- std::string dir = this->CurrentMakefile->GetCurrentOutputDirectory();
+//----------------------------------------------------------------------------
+void
+cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
+ cmGeneratorTarget* target,
+ std::vector<cmCustomCommand>
+ const & commands,
+ const char* name)
+{
+ std::string dir = this->CurrentLocalGenerator->GetCurrentBinaryDirectory();
dir += "/CMakeScripts";
cmSystemTools::MakeDirectory(dir.c_str());
std::string makefile = dir;
makefile += "/";
- makefile += target.GetName();
+ makefile += target->GetName();
makefile += "_";
makefile += name;
makefile += ".make";
@@ -1513,23 +1731,17 @@ cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
this->CreateCustomRulesMakefile(makefile.c_str(),
target,
commands,
- currentConfig->c_str(),
- multipleOutputPairs);
+ currentConfig->c_str());
}
- std::string cdir = this->CurrentMakefile->GetCurrentOutputDirectory();
- cdir = this->ConvertToRelativeForXCode(cdir.c_str());
+ std::string cdir = this->CurrentLocalGenerator->GetCurrentBinaryDirectory();
+ cdir = this->ConvertToRelativeForMake(cdir.c_str());
std::string makecmd = "make -C ";
makecmd += cdir;
makecmd += " -f ";
makecmd += this->ConvertToRelativeForMake(
(makefile+"$CONFIGURATION").c_str());
- if(!multipleOutputPairs.empty())
- {
- makecmd += " cmake_check_multiple_outputs";
- }
makecmd += " all";
- cmSystemTools::ReplaceString(makecmd, "\\ ", "\\\\ ");
buildphase->AddAttribute("shellScript",
this->CreateString(makecmd.c_str()));
buildphase->AddAttribute("showEnvVarsInLog",
@@ -1539,13 +1751,10 @@ cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
//----------------------------------------------------------------------------
void cmGlobalXCodeGenerator
::CreateCustomRulesMakefile(const char* makefileBasename,
- cmTarget& target,
+ cmGeneratorTarget* target,
std::vector<cmCustomCommand>
const & commands,
- const char* configName,
- const std::map<cmStdString,
- cmStdString>& multipleOutputPairs
- )
+ const std::string& configName)
{
std::string makefileName=makefileBasename;
if(this->XcodeVersion > 20)
@@ -1559,22 +1768,22 @@ void cmGlobalXCodeGenerator
}
makefileStream.SetCopyIfDifferent(true);
makefileStream << "# Generated by CMake, DO NOT EDIT\n";
- makefileStream << "# Custom rules for " << target.GetName() << "\n";
+ makefileStream << "# Custom rules for " << target->GetName() << "\n";
// disable the implicit rules
makefileStream << ".SUFFIXES: " << "\n";
// have all depend on all outputs
makefileStream << "all: ";
- std::map<const cmCustomCommand*, cmStdString> tname;
+ std::map<const cmCustomCommand*, std::string> tname;
int count = 0;
for(std::vector<cmCustomCommand>::const_iterator i = commands.begin();
i != commands.end(); ++i)
{
- cmCustomCommand const& cc = *i;
- if(!cc.GetCommandLines().empty())
+ cmCustomCommandGenerator ccg(*i, configName, this->CurrentLocalGenerator);
+ if(ccg.GetNumberOfCommands() > 0)
{
- const std::vector<std::string>& outputs = cc.GetOutputs();
+ const std::vector<std::string>& outputs = ccg.GetOutputs();
if(!outputs.empty())
{
for(std::vector<std::string>::const_iterator o = outputs.begin();
@@ -1586,10 +1795,10 @@ void cmGlobalXCodeGenerator
}
else
{
- cmOStringStream str;
+ std::ostringstream str;
str << "_buildpart_" << count++ ;
- tname[&cc] = std::string(target.GetName()) + str.str();
- makefileStream << "\\\n\t" << tname[&cc];
+ tname[&ccg.GetCC()] = std::string(target->GetName()) + str.str();
+ makefileStream << "\\\n\t" << tname[&ccg.GetCC()];
}
}
}
@@ -1597,27 +1806,32 @@ void cmGlobalXCodeGenerator
for(std::vector<cmCustomCommand>::const_iterator i = commands.begin();
i != commands.end(); ++i)
{
- cmCustomCommand const& cc = *i;
- if(!cc.GetCommandLines().empty())
+ cmCustomCommandGenerator ccg(*i, configName, this->CurrentLocalGenerator);
+ if(ccg.GetNumberOfCommands() > 0)
{
- cmCustomCommandGenerator ccg(cc, configName, this->CurrentMakefile);
makefileStream << "\n";
- const std::vector<std::string>& outputs = cc.GetOutputs();
+ const std::vector<std::string>& outputs = ccg.GetOutputs();
if(!outputs.empty())
{
// There is at least one output, start the rule for it
- std::string primary_output =
- this->ConvertToRelativeForMake(outputs.begin()->c_str());
- makefileStream << primary_output << ": ";
+ const char* sep = "";
+ for(std::vector<std::string>::const_iterator oi = outputs.begin();
+ oi != outputs.end(); ++oi)
+ {
+ makefileStream << sep <<
+ this->ConvertToRelativeForMake(oi->c_str());
+ sep = " ";
+ }
+ makefileStream << ": ";
}
else
{
// There are no outputs. Use the generated force rule name.
- makefileStream << tname[&cc] << ": ";
+ makefileStream << tname[&ccg.GetCC()] << ": ";
}
for(std::vector<std::string>::const_iterator d =
- cc.GetDepends().begin();
- d != cc.GetDepends().end(); ++d)
+ ccg.GetDepends().begin();
+ d != ccg.GetDepends().end(); ++d)
{
std::string dep;
if(this->CurrentLocalGenerator
@@ -1629,11 +1843,11 @@ void cmGlobalXCodeGenerator
}
makefileStream << "\n";
- if(const char* comment = cc.GetComment())
+ if(const char* comment = ccg.GetComment())
{
std::string echo_cmd = "echo ";
echo_cmd += (this->CurrentLocalGenerator->
- EscapeForShell(comment, cc.GetEscapeAllowMakeVars()));
+ EscapeForShell(comment, ccg.GetCC().GetEscapeAllowMakeVars()));
makefileStream << "\t" << echo_cmd.c_str() << "\n";
}
@@ -1645,10 +1859,11 @@ void cmGlobalXCodeGenerator
cmSystemTools::ReplaceString(cmd2, "/./", "/");
cmd2 = this->ConvertToRelativeForMake(cmd2.c_str());
std::string cmd;
- if(cc.GetWorkingDirectory())
+ std::string wd = ccg.GetWorkingDirectory();
+ if(!wd.empty())
{
cmd += "cd ";
- cmd += this->ConvertToRelativeForMake(cc.GetWorkingDirectory());
+ cmd += this->ConvertToRelativeForMake(wd.c_str());
cmd += " && ";
}
cmd += cmd2;
@@ -1657,80 +1872,58 @@ void cmGlobalXCodeGenerator
}
}
}
-
- // Add rules to deal with multiple outputs of custom commands.
- if(!multipleOutputPairs.empty())
- {
- makefileStream <<
- "\n# Dependencies of multiple outputs to their primary outputs \n";
-
- for(std::map<cmStdString, cmStdString>::const_iterator o =
- multipleOutputPairs.begin(); o != multipleOutputPairs.end(); ++o)
- {
- makefileStream << o->first << ": " << o->second << "\n";
- }
-
- makefileStream <<
- "\n"
- "cmake_check_multiple_outputs:\n";
- for(std::map<cmStdString, cmStdString>::const_iterator o =
- multipleOutputPairs.begin(); o != multipleOutputPairs.end(); ++o)
- {
- makefileStream << "\t@if [ ! -f "
- << o->first << " ]; then rm -f "
- << o->second << "; fi\n";
- }
- }
}
//----------------------------------------------------------------------------
-void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
- cmXCodeObject* buildSettings,
- const char* configName)
+void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
+ cmXCodeObject* buildSettings,
+ const std::string& configName)
{
- std::string flags;
+ if(gtgt->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ return;
+ }
+
std::string defFlags;
- bool shared = ((target.GetType() == cmTarget::SHARED_LIBRARY) ||
- (target.GetType() == cmTarget::MODULE_LIBRARY));
- bool binary = ((target.GetType() == cmTarget::OBJECT_LIBRARY) ||
- (target.GetType() == cmTarget::STATIC_LIBRARY) ||
- (target.GetType() == cmTarget::EXECUTABLE) ||
+ bool shared = ((gtgt->GetType() == cmState::SHARED_LIBRARY) ||
+ (gtgt->GetType() == cmState::MODULE_LIBRARY));
+ bool binary = ((gtgt->GetType() == cmState::OBJECT_LIBRARY) ||
+ (gtgt->GetType() == cmState::STATIC_LIBRARY) ||
+ (gtgt->GetType() == cmState::EXECUTABLE) ||
shared);
- const char* lang = target.GetLinkerLanguage(configName);
- std::string cflags;
- if(lang)
+ // Compute the compilation flags for each language.
+ std::set<std::string> languages;
+ gtgt->GetLanguages(languages, configName);
+ std::map<std::string, std::string> cflags;
+ for (std::set<std::string>::iterator li = languages.begin();
+ li != languages.end(); ++li)
{
- // for c++ projects get the c flags as well
- if(strcmp(lang, "CXX") == 0)
- {
- this->CurrentLocalGenerator->AddLanguageFlags(cflags, "C", configName);
- this->CurrentLocalGenerator->AddCMP0018Flags(cflags, &target,
- "C", configName);
- this->CurrentLocalGenerator->
- AddCompileOptions(cflags, &target, "C", configName);
- }
+ std::string const& lang = *li;
+ std::string& flags = cflags[lang];
// Add language-specific flags.
this->CurrentLocalGenerator->AddLanguageFlags(flags, lang, configName);
// Add shared-library flags if needed.
- this->CurrentLocalGenerator->AddCMP0018Flags(flags, &target,
+ this->CurrentLocalGenerator->AddCMP0018Flags(flags, gtgt,
lang, configName);
- this->CurrentLocalGenerator->AddVisibilityPresetFlags(flags, &target,
+ this->CurrentLocalGenerator->AddVisibilityPresetFlags(flags, gtgt,
lang);
this->CurrentLocalGenerator->
- AddCompileOptions(flags, &target, lang, configName);
+ AddCompileOptions(flags, gtgt, lang, configName);
}
- else if(binary)
- {
+
+ std::string llang = gtgt->GetLinkerLanguage(configName);
+ if(binary && llang.empty())
+ {
cmSystemTools::Error
("CMake can not determine linker language for target: ",
- target.GetName());
+ gtgt->GetName().c_str());
return;
- }
+ }
// Add define flags
this->CurrentLocalGenerator->
@@ -1744,33 +1937,32 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
this->AppendDefines(ppDefs,
"CMAKE_INTDIR=\"$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\"");
}
- if(const char* exportMacro = target.GetExportMacro())
+ if(const char* exportMacro = gtgt->GetExportMacro())
{
// Add the export symbol definition for shared library objects.
this->AppendDefines(ppDefs, exportMacro);
}
- cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&target);
std::vector<std::string> targetDefines;
- target.GetCompileDefinitions(targetDefines, configName);
+ gtgt->GetCompileDefinitions(targetDefines, configName, "C");
this->AppendDefines(ppDefs, targetDefines);
buildSettings->AddAttribute
("GCC_PREPROCESSOR_DEFINITIONS", ppDefs.CreateList());
std::string extraLinkOptionsVar;
std::string extraLinkOptions;
- if(target.GetType() == cmTarget::EXECUTABLE)
+ if(gtgt->GetType() == cmState::EXECUTABLE)
{
extraLinkOptionsVar = "CMAKE_EXE_LINKER_FLAGS";
}
- else if(target.GetType() == cmTarget::SHARED_LIBRARY)
+ else if(gtgt->GetType() == cmState::SHARED_LIBRARY)
{
extraLinkOptionsVar = "CMAKE_SHARED_LINKER_FLAGS";
}
- else if(target.GetType() == cmTarget::MODULE_LIBRARY)
+ else if(gtgt->GetType() == cmState::MODULE_LIBRARY)
{
extraLinkOptionsVar = "CMAKE_MODULE_LINKER_FLAGS";
}
- if(extraLinkOptionsVar.size())
+ if(!extraLinkOptionsVar.empty())
{
this->CurrentLocalGenerator
->AddConfigVariableFlags(extraLinkOptions,
@@ -1778,27 +1970,27 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
configName);
}
- if(target.GetType() == cmTarget::OBJECT_LIBRARY ||
- target.GetType() == cmTarget::STATIC_LIBRARY)
+ if(gtgt->GetType() == cmState::OBJECT_LIBRARY ||
+ gtgt->GetType() == cmState::STATIC_LIBRARY)
{
this->CurrentLocalGenerator
->GetStaticLibraryFlags(extraLinkOptions,
cmSystemTools::UpperCase(configName),
- &target);
+ gtgt);
}
else
{
- const char* targetLinkFlags = target.GetProperty("LINK_FLAGS");
+ const char* targetLinkFlags = gtgt->GetProperty("LINK_FLAGS");
if(targetLinkFlags)
{
this->CurrentLocalGenerator->
AppendFlags(extraLinkOptions, targetLinkFlags);
}
- if(configName && *configName)
+ if(!configName.empty())
{
std::string linkFlagsVar = "LINK_FLAGS_";
linkFlagsVar += cmSystemTools::UpperCase(configName);
- if(const char* linkFlags = target.GetProperty(linkFlagsVar.c_str()))
+ if(const char* linkFlags = gtgt->GetProperty(linkFlagsVar.c_str()))
{
this->CurrentLocalGenerator->
AppendFlags(extraLinkOptions, linkFlags);
@@ -1839,11 +2031,11 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
std::string pnprefix;
std::string pnbase;
std::string pnsuffix;
- target.GetFullNameComponents(pnprefix, pnbase, pnsuffix, configName);
+ gtgt->GetFullNameComponents(pnprefix, pnbase, pnsuffix, configName);
- const char* version = target.GetProperty("VERSION");
- const char* soversion = target.GetProperty("SOVERSION");
- if(!target.HasSOName(configName) || target.IsFrameworkOnApple())
+ const char* version = gtgt->GetProperty("VERSION");
+ const char* soversion = gtgt->GetProperty("SOVERSION");
+ if(!gtgt->HasSOName(configName) || gtgt->IsFrameworkOnApple())
{
version = 0;
soversion = 0;
@@ -1868,17 +2060,17 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
}
// Set attributes to specify the proper name for the target.
- std::string pndir = this->CurrentMakefile->GetCurrentOutputDirectory();
- if(target.GetType() == cmTarget::STATIC_LIBRARY ||
- target.GetType() == cmTarget::SHARED_LIBRARY ||
- target.GetType() == cmTarget::MODULE_LIBRARY ||
- target.GetType() == cmTarget::EXECUTABLE)
+ std::string pndir = this->CurrentLocalGenerator->GetCurrentBinaryDirectory();
+ if(gtgt->GetType() == cmState::STATIC_LIBRARY ||
+ gtgt->GetType() == cmState::SHARED_LIBRARY ||
+ gtgt->GetType() == cmState::MODULE_LIBRARY ||
+ gtgt->GetType() == cmState::EXECUTABLE)
{
if(this->XcodeVersion >= 21)
{
- if(!target.UsesDefaultOutputDir(configName, false))
+ if(!gtgt->UsesDefaultOutputDir(configName, false))
{
- std::string pncdir = target.GetDirectory(configName);
+ std::string pncdir = gtgt->GetDirectory(configName);
buildSettings->AddAttribute("CONFIGURATION_BUILD_DIR",
this->CreateString(pncdir.c_str()));
}
@@ -1887,10 +2079,10 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
{
buildSettings->AddAttribute("OBJROOT",
this->CreateString(pndir.c_str()));
- pndir = target.GetDirectory(configName);
+ pndir = gtgt->GetDirectory(configName);
}
- if(target.IsFrameworkOnApple() || target.IsCFBundleOnApple())
+ if(gtgt->IsFrameworkOnApple() || gtgt->IsCFBundleOnApple())
{
pnprefix = "";
}
@@ -1900,16 +2092,16 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
buildSettings->AddAttribute("EXECUTABLE_SUFFIX",
this->CreateString(pnsuffix.c_str()));
}
- else if(target.GetType() == cmTarget::OBJECT_LIBRARY)
+ else if(gtgt->GetType() == cmState::OBJECT_LIBRARY)
{
pnprefix = "lib";
- pnbase = target.GetName();
+ pnbase = gtgt->GetName();
pnsuffix = ".a";
if(this->XcodeVersion >= 21)
{
std::string pncdir = this->GetObjectsNormalDirectory(
- this->CurrentProject, configName, &target);
+ this->CurrentProject, configName, gtgt);
buildSettings->AddAttribute("CONFIGURATION_BUILD_DIR",
this->CreateString(pncdir.c_str()));
}
@@ -1918,7 +2110,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
buildSettings->AddAttribute("OBJROOT",
this->CreateString(pndir.c_str()));
pndir = this->GetObjectsNormalDirectory(
- this->CurrentProject, configName, &target);
+ this->CurrentProject, configName, gtgt);
}
}
@@ -1929,45 +2121,43 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
this->CreateString(pndir.c_str()));
// Handle settings for each target type.
- switch(target.GetType())
+ switch(gtgt->GetType())
{
- case cmTarget::OBJECT_LIBRARY:
- case cmTarget::STATIC_LIBRARY:
+ case cmState::OBJECT_LIBRARY:
+ case cmState::STATIC_LIBRARY:
{
buildSettings->AddAttribute("LIBRARY_STYLE",
this->CreateString("STATIC"));
break;
}
- case cmTarget::MODULE_LIBRARY:
+ case cmState::MODULE_LIBRARY:
{
buildSettings->AddAttribute("LIBRARY_STYLE",
this->CreateString("BUNDLE"));
- if (target.GetPropertyAsBool("BUNDLE"))
+ if (gtgt->IsCFBundleOnApple())
{
// It turns out that a BUNDLE is basically the same
// in many ways as an application bundle, as far as
// link flags go
std::string createFlags =
- this->LookupFlags("CMAKE_SHARED_MODULE_CREATE_", lang, "_FLAGS",
+ this->LookupFlags("CMAKE_SHARED_MODULE_CREATE_", llang, "_FLAGS",
"-bundle");
if(!createFlags.empty())
{
extraLinkOptions += " ";
extraLinkOptions += createFlags;
}
- std::string plist = this->ComputeInfoPListLocation(target);
+ std::string plist = this->ComputeInfoPListLocation(gtgt);
// Xcode will create the final version of Info.plist at build time,
// so let it replace the cfbundle name. This avoids creating
// a per-configuration Info.plist file. The cfbundle plist
// is very similar to the application bundle plist
this->CurrentLocalGenerator
- ->GenerateAppleInfoPList(&target, "$(EXECUTABLE_NAME)",
+ ->GenerateAppleInfoPList(gtgt, "$(EXECUTABLE_NAME)",
plist.c_str());
- std::string path =
- this->ConvertToRelativeForXCode(plist.c_str());
buildSettings->AddAttribute("INFOPLIST_FILE",
- this->CreateString(path.c_str()));
+ this->CreateString(plist));
}
else if(this->XcodeVersion >= 22)
{
@@ -1977,7 +2167,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
this->CreateString("NO"));
// Add the flags to create an executable.
std::string createFlags =
- this->LookupFlags("CMAKE_", lang, "_LINK_FLAGS", "");
+ this->LookupFlags("CMAKE_", llang, "_LINK_FLAGS", "");
if(!createFlags.empty())
{
extraLinkOptions += " ";
@@ -1988,7 +2178,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
{
// Add the flags to create a module.
std::string createFlags =
- this->LookupFlags("CMAKE_SHARED_MODULE_CREATE_", lang, "_FLAGS",
+ this->LookupFlags("CMAKE_SHARED_MODULE_CREATE_", llang, "_FLAGS",
"-bundle");
if(!createFlags.empty())
{
@@ -1998,31 +2188,29 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
}
break;
}
- case cmTarget::SHARED_LIBRARY:
+ case cmState::SHARED_LIBRARY:
{
- if(target.GetPropertyAsBool("FRAMEWORK"))
+ if(gtgt->GetPropertyAsBool("FRAMEWORK"))
{
- std::string fw_version = target.GetFrameworkVersion();
+ std::string fw_version = gtgt->GetFrameworkVersion();
buildSettings->AddAttribute("FRAMEWORK_VERSION",
this->CreateString(fw_version.c_str()));
- std::string plist = this->ComputeInfoPListLocation(target);
+ std::string plist = this->ComputeInfoPListLocation(gtgt);
// Xcode will create the final version of Info.plist at build time,
// so let it replace the framework name. This avoids creating
// a per-configuration Info.plist file.
this->CurrentLocalGenerator
- ->GenerateFrameworkInfoPList(&target, "$(EXECUTABLE_NAME)",
+ ->GenerateFrameworkInfoPList(gtgt, "$(EXECUTABLE_NAME)",
plist.c_str());
- std::string path =
- this->ConvertToRelativeForXCode(plist.c_str());
buildSettings->AddAttribute("INFOPLIST_FILE",
- this->CreateString(path.c_str()));
+ this->CreateString(plist));
}
else
{
// Add the flags to create a shared library.
std::string createFlags =
- this->LookupFlags("CMAKE_SHARED_LIBRARY_CREATE_", lang, "_FLAGS",
+ this->LookupFlags("CMAKE_SHARED_LIBRARY_CREATE_", llang, "_FLAGS",
"-dynamiclib");
if(!createFlags.empty())
{
@@ -2035,11 +2223,11 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
this->CreateString("DYNAMIC"));
break;
}
- case cmTarget::EXECUTABLE:
+ case cmState::EXECUTABLE:
{
// Add the flags to create an executable.
std::string createFlags =
- this->LookupFlags("CMAKE_", lang, "_LINK_FLAGS", "");
+ this->LookupFlags("CMAKE_", llang, "_LINK_FLAGS", "");
if(!createFlags.empty())
{
extraLinkOptions += " ";
@@ -2047,19 +2235,17 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
}
// Handle bundles and normal executables separately.
- if(target.GetPropertyAsBool("MACOSX_BUNDLE"))
+ if(gtgt->GetPropertyAsBool("MACOSX_BUNDLE"))
{
- std::string plist = this->ComputeInfoPListLocation(target);
+ std::string plist = this->ComputeInfoPListLocation(gtgt);
// Xcode will create the final version of Info.plist at build time,
// so let it replace the executable name. This avoids creating
// a per-configuration Info.plist file.
this->CurrentLocalGenerator
- ->GenerateAppleInfoPList(&target, "$(EXECUTABLE_NAME)",
+ ->GenerateAppleInfoPList(gtgt, "$(EXECUTABLE_NAME)",
plist.c_str());
- std::string path =
- this->ConvertToRelativeForXCode(plist.c_str());
buildSettings->AddAttribute("INFOPLIST_FILE",
- this->CreateString(path.c_str()));
+ this->CreateString(plist));
}
}
@@ -2078,7 +2264,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
std::vector<std::string> includes;
this->CurrentLocalGenerator->GetIncludeDirectories(includes, gtgt,
"C", configName);
- std::set<cmStdString> emitted;
+ std::set<std::string> emitted;
emitted.insert("/System/Library/Frameworks");
for(std::vector<std::string>::iterator i = includes.begin();
i != includes.end(); ++i)
@@ -2101,7 +2287,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
}
}
// Add framework search paths needed for linking.
- if(cmComputeLinkInformation* cli = target.GetLinkInformation(configName))
+ if(cmComputeLinkInformation* cli = gtgt->GetLinkInformation(configName))
{
std::vector<std::string> const& fwDirs = cli->GetFrameworkPaths();
for(std::vector<std::string>::const_iterator fdi = fwDirs.begin();
@@ -2123,53 +2309,57 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
buildSettings->AddAttribute("HEADER_SEARCH_PATHS",
dirs.CreateList());
}
- std::string oflagc = this->ExtractFlag("-O", cflags);
- char optLevel[2];
- optLevel[0] = '0';
- optLevel[1] = 0;
- if(oflagc.size() == 3)
- {
- optLevel[0] = oflagc[2];
- }
- if(oflagc.size() == 2)
- {
- optLevel[0] = '1';
- }
- std::string oflag = this->ExtractFlag("-O", flags);
- if(oflag.size() == 3)
- {
- optLevel[0] = oflag[2];
- }
- if(oflag.size() == 2)
- {
- optLevel[0] = '1';
- }
- std::string gflagc = this->ExtractFlag("-g", cflags);
- // put back gdwarf-2 if used since there is no way
- // to represent it in the gui, but we still want debug yes
- if(gflagc == "-gdwarf-2")
- {
- cflags += " ";
- cflags += gflagc;
- }
- std::string gflag = this->ExtractFlag("-g", flags);
- if(gflag == "-gdwarf-2")
+
+ bool same_gflags = true;
+ std::map<std::string, std::string> gflags;
+ std::string const* last_gflag = 0;
+ std::string optLevel = "0";
+
+ // Minimal map of flags to build settings.
+ for (std::set<std::string>::iterator li = languages.begin();
+ li != languages.end(); ++li)
{
- flags += " ";
- flags += gflag;
+ std::string& flags = cflags[*li];
+ std::string& gflag = gflags[*li];
+ std::string oflag =
+ this->ExtractFlagRegex("(^| )(-Ofast|-Os|-O[0-9]*)( |$)", 2, flags);
+ if(oflag.size() == 2)
+ {
+ optLevel = "1";
+ }
+ else if(oflag.size() > 2)
+ {
+ optLevel = oflag.substr(2);
+ }
+ gflag = this->ExtractFlag("-g", flags);
+ // put back gdwarf-2 if used since there is no way
+ // to represent it in the gui, but we still want debug yes
+ if(gflag == "-gdwarf-2")
+ {
+ flags += " ";
+ flags += gflag;
+ }
+ if (last_gflag && *last_gflag != gflag)
+ {
+ same_gflags = false;
+ }
+ last_gflag = &gflag;
}
+
const char* debugStr = "YES";
- // We can't set the Xcode flag differently depending on the language,
- // so put them back in this case.
- if( (lang && strcmp(lang, "CXX") == 0) && gflag != gflagc )
+ if (!same_gflags)
{
- cflags += " ";
- cflags += gflagc;
- flags += " ";
- flags += gflag;
+ // We can't set the Xcode flag differently depending on the language,
+ // so put them back in this case.
+ for (std::set<std::string>::iterator li = languages.begin();
+ li != languages.end(); ++li)
+ {
+ cflags[*li] += " ";
+ cflags[*li] += gflags[*li];
+ }
debugStr = "NO";
}
- if( gflag == "-g0" || gflag.size() == 0 )
+ else if (last_gflag && (last_gflag->empty() || *last_gflag == "-g0"))
{
debugStr = "NO";
}
@@ -2184,29 +2374,30 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
this->CreateString("NO"));
buildSettings->AddAttribute("GCC_INLINES_ARE_PRIVATE_EXTERN",
this->CreateString("NO"));
- if(lang && strcmp(lang, "CXX") == 0)
- {
- flags += " ";
- flags += defFlags;
- buildSettings->AddAttribute("OTHER_CPLUSPLUSFLAGS",
- this->CreateString(flags.c_str()));
- cflags += " ";
- cflags += defFlags;
- buildSettings->AddAttribute("OTHER_CFLAGS",
- this->CreateString(cflags.c_str()));
-
- }
- else
+ for (std::set<std::string>::iterator li = languages.begin();
+ li != languages.end(); ++li)
{
- flags += " ";
- flags += defFlags;
- buildSettings->AddAttribute("OTHER_CFLAGS",
- this->CreateString(flags.c_str()));
+ std::string flags = cflags[*li] + " " + defFlags;
+ if (*li == "CXX")
+ {
+ buildSettings->AddAttribute("OTHER_CPLUSPLUSFLAGS",
+ this->CreateString(flags.c_str()));
+ }
+ else if (*li == "Fortran")
+ {
+ buildSettings->AddAttribute("IFORT_OTHER_FLAGS",
+ this->CreateString(flags.c_str()));
+ }
+ else if (*li == "C")
+ {
+ buildSettings->AddAttribute("OTHER_CFLAGS",
+ this->CreateString(flags.c_str()));
+ }
}
// Add Fortran source format attribute if property is set.
const char* format = 0;
- const char* tgtfmt = target.GetProperty("Fortran_FORMAT");
+ const char* tgtfmt = gtgt->GetProperty("Fortran_FORMAT");
switch(this->CurrentLocalGenerator->GetFortranFormat(tgtfmt))
{
case cmLocalGenerator::FortranFormatFixed: format = "fixed"; break;
@@ -2221,10 +2412,10 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
// Create the INSTALL_PATH attribute.
std::string install_name_dir;
- if(target.GetType() == cmTarget::SHARED_LIBRARY)
+ if(gtgt->GetType() == cmState::SHARED_LIBRARY)
{
// Get the install_name directory for the build tree.
- install_name_dir = target.GetInstallNameDirForBuildTree(configName);
+ install_name_dir = gtgt->GetInstallNameDirForBuildTree(configName);
// Xcode doesn't create the correct install_name in some cases.
// That is, if the INSTALL_PATH is empty, or if we have versioning
// of dylib libraries, we want to specify the install_name.
@@ -2238,7 +2429,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
install_name += install_name_dir;
install_name += "/";
}
- install_name += target.GetSOName(configName);
+ install_name += gtgt->GetSOName(configName);
if((realName != soName) || install_name_dir.empty())
{
@@ -2251,20 +2442,30 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
this->CreateString(install_name_dir.c_str()));
// Create the LD_RUNPATH_SEARCH_PATHS
- cmComputeLinkInformation* pcli = target.GetLinkInformation(configName);
+ cmComputeLinkInformation* pcli = gtgt->GetLinkInformation(configName);
if(pcli)
{
std::string search_paths;
std::vector<std::string> runtimeDirs;
pcli->GetRPath(runtimeDirs, false);
+ // runpath dirs needs to be unique to prevent corruption
+ std::set<std::string> unique_dirs;
+
for(std::vector<std::string>::const_iterator i = runtimeDirs.begin();
i != runtimeDirs.end(); ++i)
{
- if(!search_paths.empty())
+ std::string runpath = *i;
+ runpath = this->ExpandCFGIntDir(runpath, configName);
+
+ if(unique_dirs.find(runpath) == unique_dirs.end())
{
- search_paths += " ";
+ unique_dirs.insert(runpath);
+ if(!search_paths.empty())
+ {
+ search_paths += " ";
+ }
+ search_paths += this->XCodeEscapePath(runpath.c_str());
}
- search_paths += this->XCodeEscapePath((*i).c_str());
}
if(!search_paths.empty())
{
@@ -2273,7 +2474,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
}
}
- buildSettings->AddAttribute("OTHER_LDFLAGS",
+ buildSettings->AddAttribute(this->GetTargetLinkFlagsVar(gtgt),
this->CreateString(extraLinkOptions.c_str()));
buildSettings->AddAttribute("OTHER_REZFLAGS",
this->CreateString(""));
@@ -2287,6 +2488,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
group->AddObject(this->CreateString("-Wmost"));
group->AddObject(this->CreateString("-Wno-four-char-constants"));
group->AddObject(this->CreateString("-Wno-unknown-pragmas"));
+ group->AddObject(this->CreateString("$(inherited)"));
buildSettings->AddAttribute("WARNING_CFLAGS", group);
}
else
@@ -2298,15 +2500,15 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
}
// Runtime version information.
- if(target.GetType() == cmTarget::SHARED_LIBRARY)
+ if(gtgt->GetType() == cmState::SHARED_LIBRARY)
{
int major;
int minor;
int patch;
// VERSION -> current_version
- target.GetTargetVersion(false, major, minor, patch);
- cmOStringStream v;
+ gtgt->GetTargetVersion(false, major, minor, patch);
+ std::ostringstream v;
// Xcode always wants at least 1.0.0 or nothing
if(!(major == 0 && minor == 0 && patch == 0))
@@ -2317,8 +2519,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
this->CreateString(v.str().c_str()));
// SOVERSION -> compatibility_version
- target.GetTargetVersion(true, major, minor, patch);
- cmOStringStream vso;
+ gtgt->GetTargetVersion(true, major, minor, patch);
+ std::ostringstream vso;
// Xcode always wants at least 1.0.0 or nothing
if(!(major == 0 && minor == 0 && patch == 0))
@@ -2331,44 +2533,21 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
// put this last so it can override existing settings
// Convert "XCODE_ATTRIBUTE_*" properties directly.
{
- cmPropertyMap const& props = target.GetProperties();
- for(cmPropertyMap::const_iterator i = props.begin();
+ std::vector<std::string> const& props = gtgt->GetPropertyKeys();
+ for(std::vector<std::string>::const_iterator i = props.begin();
i != props.end(); ++i)
{
- if(i->first.find("XCODE_ATTRIBUTE_") == 0)
+ if(i->find("XCODE_ATTRIBUTE_") == 0)
{
- cmStdString attribute = i->first.substr(16);
- // Handle [variant=<config>] condition explicitly here.
- cmStdString::size_type beginVariant =
- attribute.find("[variant=");
- if (beginVariant != cmStdString::npos)
- {
- cmStdString::size_type endVariant =
- attribute.find("]", beginVariant+9);
- if (endVariant != cmStdString::npos)
- {
- // Compare the variant to the configuration.
- cmStdString variant =
- attribute.substr(beginVariant+9, endVariant-beginVariant-9);
- if (variant == configName)
- {
- // The variant matches the configuration so use this
- // attribute but drop the [variant=<config>] condition.
- attribute.erase(beginVariant, endVariant-beginVariant+1);
- }
- else
- {
- // The variant does not match the configuration so
- // do not use this attribute.
- attribute.clear();
- }
- }
- }
-
+ std::string attribute = i->substr(16);
+ this->FilterConfigurationAttribute(configName, attribute);
if (!attribute.empty())
{
+ cmGeneratorExpression ge;
+ std::string processed = ge.Parse(gtgt->GetProperty(*i))
+ ->Evaluate(this->CurrentLocalGenerator, configName);
buildSettings->AddAttribute(attribute.c_str(),
- this->CreateString(i->second.GetValue()));
+ this->CreateString(processed));
}
}
}
@@ -2377,7 +2556,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
//----------------------------------------------------------------------------
cmXCodeObject*
-cmGlobalXCodeGenerator::CreateUtilityTarget(cmTarget& cmtarget)
+cmGlobalXCodeGenerator::CreateUtilityTarget(cmGeneratorTarget* gtgt)
{
cmXCodeObject* shellBuildPhase =
this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase);
@@ -2401,56 +2580,62 @@ cmGlobalXCodeGenerator::CreateUtilityTarget(cmTarget& cmtarget)
cmXCodeObject* target =
this->CreateObject(cmXCodeObject::PBXAggregateTarget);
- target->SetComment(cmtarget.GetName());
+ target->SetComment(gtgt->GetName().c_str());
cmXCodeObject* buildPhases =
this->CreateObject(cmXCodeObject::OBJECT_LIST);
std::vector<cmXCodeObject*> emptyContentVector;
this->CreateCustomCommands(buildPhases, 0, 0, 0, emptyContentVector, 0,
- cmtarget);
+ gtgt);
target->AddAttribute("buildPhases", buildPhases);
if(this->XcodeVersion > 20)
{
- this->AddConfigurations(target, cmtarget);
+ this->AddConfigurations(target, gtgt);
}
else
{
- const char* theConfig =
- this->CurrentMakefile->GetDefinition("CMAKE_BUILD_TYPE");
+ std::string theConfig =
+ this->CurrentMakefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
cmXCodeObject* buildSettings =
this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
- this->CreateBuildSettings(cmtarget, buildSettings, theConfig);
+ this->CreateBuildSettings(gtgt, buildSettings, theConfig);
target->AddAttribute("buildSettings", buildSettings);
}
cmXCodeObject* dependencies =
this->CreateObject(cmXCodeObject::OBJECT_LIST);
target->AddAttribute("dependencies", dependencies);
- target->AddAttribute("name", this->CreateString(cmtarget.GetName()));
- target->AddAttribute("productName",this->CreateString(cmtarget.GetName()));
- target->SetTarget(&cmtarget);
+ target->AddAttribute("name", this->CreateString(gtgt->GetName()));
+ target->AddAttribute("productName",this->CreateString(gtgt->GetName()));
+ target->SetTarget(gtgt);
+ this->XCodeObjectMap[gtgt] = target;
// Add source files without build rules for editing convenience.
- if(cmtarget.GetType() == cmTarget::UTILITY)
+ if(gtgt->GetType() == cmState::UTILITY)
{
- std::vector<cmSourceFile*> const& sources = cmtarget.GetSourceFiles();
+ std::vector<cmSourceFile*> sources;
+ if (!gtgt->GetConfigCommonSourceFiles(sources))
+ {
+ return 0;
+ }
+
for(std::vector<cmSourceFile*>::const_iterator i = sources.begin();
i != sources.end(); ++i)
{
if(!(*i)->GetPropertyAsBool("GENERATED"))
{
- this->CreateXCodeFileReference(*i, cmtarget);
+ this->CreateXCodeFileReference(*i, gtgt);
}
}
}
target->SetId(this->GetOrCreateId(
- cmtarget.GetName(), target->GetId()).c_str());
+ gtgt->GetName(), target->GetId()).c_str());
return target;
}
//----------------------------------------------------------------------------
std::string cmGlobalXCodeGenerator::AddConfigurations(cmXCodeObject* target,
- cmTarget& cmtarget)
+ cmGeneratorTarget* gtgt)
{
std::string configTypes =
this->CurrentMakefile->GetRequiredDefinition("CMAKE_CONFIGURATION_TYPES");
@@ -2466,7 +2651,7 @@ std::string cmGlobalXCodeGenerator::AddConfigurations(cmXCodeObject* target,
std::string comment = "Build configuration list for ";
comment += cmXCodeObject::PBXTypeNames[target->GetIsA()];
comment += " \"";
- comment += cmtarget.GetName();
+ comment += gtgt->GetName();
comment += "\"";
configlist->SetComment(comment.c_str());
target->AddAttribute("buildConfigurationList",
@@ -2478,13 +2663,13 @@ std::string cmGlobalXCodeGenerator::AddConfigurations(cmXCodeObject* target,
buildConfigurations->AddObject(config);
cmXCodeObject* buildSettings =
this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
- this->CreateBuildSettings(cmtarget, buildSettings,
+ this->CreateBuildSettings(gtgt, buildSettings,
configVector[i].c_str());
config->AddAttribute("name", this->CreateString(configVector[i].c_str()));
config->SetComment(configVector[i].c_str());
config->AddAttribute("buildSettings", buildSettings);
}
- if(configVector.size())
+ if(!configVector.empty())
{
configlist->AddAttribute("defaultConfigurationName",
this->CreateString(configVector[0].c_str()));
@@ -2496,23 +2681,42 @@ std::string cmGlobalXCodeGenerator::AddConfigurations(cmXCodeObject* target,
}
//----------------------------------------------------------------------------
-const char* cmGlobalXCodeGenerator::GetTargetFileType(cmTarget& cmtarget)
+const char* cmGlobalXCodeGenerator::GetTargetLinkFlagsVar(
+ cmGeneratorTarget const* target) const
+{
+ if(this->XcodeVersion >= 60 &&
+ (target->GetType() == cmState::STATIC_LIBRARY ||
+ target->GetType() == cmState::OBJECT_LIBRARY))
+ {
+ return "OTHER_LIBTOOLFLAGS";
+ }
+ else
+ {
+ return "OTHER_LDFLAGS";
+ }
+}
+
+//----------------------------------------------------------------------------
+const char* cmGlobalXCodeGenerator::GetTargetFileType(
+ cmGeneratorTarget* target)
{
- switch(cmtarget.GetType())
+ switch(target->GetType())
{
- case cmTarget::OBJECT_LIBRARY:
- case cmTarget::STATIC_LIBRARY:
+ case cmState::OBJECT_LIBRARY:
+ case cmState::STATIC_LIBRARY:
return "archive.ar";
- case cmTarget::MODULE_LIBRARY:
- if (cmtarget.IsCFBundleOnApple())
+ case cmState::MODULE_LIBRARY:
+ if (target->IsXCTestOnApple())
+ return "wrapper.cfbundle";
+ else if (target->IsCFBundleOnApple())
return "wrapper.plug-in";
else
return ((this->XcodeVersion >= 22)?
"compiled.mach-o.executable" : "compiled.mach-o.dylib");
- case cmTarget::SHARED_LIBRARY:
- return (cmtarget.GetPropertyAsBool("FRAMEWORK")?
+ case cmState::SHARED_LIBRARY:
+ return (target->GetPropertyAsBool("FRAMEWORK")?
"wrapper.framework" : "compiled.mach-o.dylib");
- case cmTarget::EXECUTABLE:
+ case cmState::EXECUTABLE:
return "compiled.mach-o.executable";
default: break;
}
@@ -2520,26 +2724,29 @@ const char* cmGlobalXCodeGenerator::GetTargetFileType(cmTarget& cmtarget)
}
//----------------------------------------------------------------------------
-const char* cmGlobalXCodeGenerator::GetTargetProductType(cmTarget& cmtarget)
+const char* cmGlobalXCodeGenerator::GetTargetProductType(
+ cmGeneratorTarget* target)
{
- switch(cmtarget.GetType())
+ switch(target->GetType())
{
- case cmTarget::OBJECT_LIBRARY:
- case cmTarget::STATIC_LIBRARY:
+ case cmState::OBJECT_LIBRARY:
+ case cmState::STATIC_LIBRARY:
return "com.apple.product-type.library.static";
- case cmTarget::MODULE_LIBRARY:
- if (cmtarget.IsCFBundleOnApple())
+ case cmState::MODULE_LIBRARY:
+ if (target->IsXCTestOnApple())
+ return "com.apple.product-type.bundle.unit-test";
+ else if (target->IsCFBundleOnApple())
return "com.apple.product-type.bundle";
else
return ((this->XcodeVersion >= 22)?
"com.apple.product-type.tool" :
"com.apple.product-type.library.dynamic");
- case cmTarget::SHARED_LIBRARY:
- return (cmtarget.GetPropertyAsBool("FRAMEWORK")?
+ case cmState::SHARED_LIBRARY:
+ return (target->GetPropertyAsBool("FRAMEWORK")?
"com.apple.product-type.framework" :
"com.apple.product-type.library.dynamic");
- case cmTarget::EXECUTABLE:
- return (cmtarget.GetPropertyAsBool("MACOSX_BUNDLE")?
+ case cmState::EXECUTABLE:
+ return (target->GetPropertyAsBool("MACOSX_BUNDLE")?
"com.apple.product-type.application" :
"com.apple.product-type.tool");
default: break;
@@ -2549,9 +2756,13 @@ const char* cmGlobalXCodeGenerator::GetTargetProductType(cmTarget& cmtarget)
//----------------------------------------------------------------------------
cmXCodeObject*
-cmGlobalXCodeGenerator::CreateXCodeTarget(cmTarget& cmtarget,
+cmGlobalXCodeGenerator::CreateXCodeTarget(cmGeneratorTarget* gtgt,
cmXCodeObject* buildPhases)
{
+ if(gtgt->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ return 0;
+ }
cmXCodeObject* target =
this->CreateObject(cmXCodeObject::PBXNativeTarget);
target->AddAttribute("buildPhases", buildPhases);
@@ -2560,78 +2771,78 @@ cmGlobalXCodeGenerator::CreateXCodeTarget(cmTarget& cmtarget,
std::string defConfig;
if(this->XcodeVersion > 20)
{
- defConfig = this->AddConfigurations(target, cmtarget);
+ defConfig = this->AddConfigurations(target, gtgt);
}
else
{
cmXCodeObject* buildSettings =
this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
defConfig = this->CurrentMakefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
- this->CreateBuildSettings(cmtarget, buildSettings, defConfig.c_str());
+ this->CreateBuildSettings(gtgt, buildSettings, defConfig.c_str());
target->AddAttribute("buildSettings", buildSettings);
}
cmXCodeObject* dependencies =
this->CreateObject(cmXCodeObject::OBJECT_LIST);
target->AddAttribute("dependencies", dependencies);
- target->AddAttribute("name", this->CreateString(cmtarget.GetName()));
- target->AddAttribute("productName",this->CreateString(cmtarget.GetName()));
+ target->AddAttribute("name", this->CreateString(gtgt->GetName()));
+ target->AddAttribute("productName",this->CreateString(gtgt->GetName()));
cmXCodeObject* fileRef =
this->CreateObject(cmXCodeObject::PBXFileReference);
- if(const char* fileType = this->GetTargetFileType(cmtarget))
+ if(const char* fileType = this->GetTargetFileType(gtgt))
{
fileRef->AddAttribute("explicitFileType", this->CreateString(fileType));
}
std::string fullName;
- if(cmtarget.GetType() == cmTarget::OBJECT_LIBRARY)
+ if(gtgt->GetType() == cmState::OBJECT_LIBRARY)
{
fullName = "lib";
- fullName += cmtarget.GetName();
+ fullName += gtgt->GetName();
fullName += ".a";
}
else
{
- fullName = cmtarget.GetFullName(defConfig.c_str());
+ fullName = gtgt->GetFullName(defConfig.c_str());
}
fileRef->AddAttribute("path", this->CreateString(fullName.c_str()));
fileRef->AddAttribute("refType", this->CreateString("0"));
fileRef->AddAttribute("sourceTree",
this->CreateString("BUILT_PRODUCTS_DIR"));
- fileRef->SetComment(cmtarget.GetName());
+ fileRef->SetComment(gtgt->GetName().c_str());
target->AddAttribute("productReference",
this->CreateObjectReference(fileRef));
- if(const char* productType = this->GetTargetProductType(cmtarget))
+ if(const char* productType = this->GetTargetProductType(gtgt))
{
target->AddAttribute("productType", this->CreateString(productType));
}
- target->SetTarget(&cmtarget);
+ target->SetTarget(gtgt);
+ this->XCodeObjectMap[gtgt] = target;
target->SetId(this->GetOrCreateId(
- cmtarget.GetName(), target->GetId()).c_str());
+ gtgt->GetName(), target->GetId()).c_str());
return target;
}
//----------------------------------------------------------------------------
-cmXCodeObject* cmGlobalXCodeGenerator::FindXCodeTarget(cmTarget* t)
+cmXCodeObject*
+cmGlobalXCodeGenerator::FindXCodeTarget(cmGeneratorTarget const* t)
{
if(!t)
{
return 0;
}
- for(std::vector<cmXCodeObject*>::iterator i = this->XCodeObjects.begin();
- i != this->XCodeObjects.end(); ++i)
+
+ std::map<cmGeneratorTarget const*, cmXCodeObject*>::const_iterator const i =
+ this->XCodeObjectMap.find(t);
+ if (i == this->XCodeObjectMap.end())
{
- cmXCodeObject* o = *i;
- if(o->GetTarget() == t)
- {
- return o;
- }
+ return 0;
}
- return 0;
+ return i->second;
}
//----------------------------------------------------------------------------
-std::string cmGlobalXCodeGenerator::GetOrCreateId(const char* name,
- const char* id)
+std::string cmGlobalXCodeGenerator::GetOrCreateId(const std::string& name,
+ const std::string& id)
{
std::string guidStoreName = name;
guidStoreName += "_GUID_CMAKE";
@@ -2644,7 +2855,7 @@ std::string cmGlobalXCodeGenerator::GetOrCreateId(const char* name,
}
this->CMakeInstance->AddCacheEntry(guidStoreName.c_str(),
- id, "Stored Xcode object GUID", cmCacheManager::INTERNAL);
+ id.c_str(), "Stored Xcode object GUID", cmState::INTERNAL);
return id;
}
@@ -2713,7 +2924,7 @@ void cmGlobalXCodeGenerator
::AppendBuildSettingAttribute(cmXCodeObject* target,
const char* attribute,
const char* value,
- const char* configName)
+ const std::string& configName)
{
if(this->XcodeVersion < 21)
{
@@ -2736,9 +2947,9 @@ void cmGlobalXCodeGenerator
for(std::vector<cmXCodeObject*>::iterator i = list.begin();
i != list.end(); ++i)
{
- if(configName)
+ if(!configName.empty())
{
- if(strcmp((*i)->GetObject("name")->GetString(), configName) == 0)
+ if((*i)->GetObject("name")->GetString() == configName)
{
cmXCodeObject* settings = (*i)->GetObject("buildSettings");
this->AppendOrAddBuildSetting(settings, attribute, value);
@@ -2757,15 +2968,19 @@ void cmGlobalXCodeGenerator
void cmGlobalXCodeGenerator
::AddDependAndLinkInformation(cmXCodeObject* target)
{
- cmTarget* cmtarget = target->GetTarget();
- if(!cmtarget)
+ cmGeneratorTarget* gt = target->GetTarget();
+ if(!gt)
{
cmSystemTools::Error("Error no target on xobject\n");
return;
}
+ if(gt->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ return;
+ }
// Add dependencies on other CMake targets.
- TargetDependSet const& deps = this->GetTargetDirectDepends(*cmtarget);
+ TargetDependSet const& deps = this->GetTargetDirectDepends(gt);
for(TargetDependSet::const_iterator i = deps.begin(); i != deps.end(); ++i)
{
if(cmXCodeObject* dptarget = this->FindXCodeTarget(*i))
@@ -2780,11 +2995,7 @@ void cmGlobalXCodeGenerator
i != this->CurrentConfigurationTypes.end(); ++i)
{
// Get the current configuration name.
- const char* configName = i->c_str();
- if(!*configName)
- {
- configName = 0;
- }
+ std::string configName = *i;
if(this->XcodeVersion >= 50)
{
@@ -2792,7 +3003,7 @@ void cmGlobalXCodeGenerator
std::string linkObjs;
const char* sep = "";
std::vector<std::string> objs;
- this->GetGeneratorTarget(cmtarget)->UseObjectLibraries(objs);
+ gt->UseObjectLibraries(objs, "");
for(std::vector<std::string>::const_iterator
oi = objs.begin(); oi != objs.end(); ++oi)
{
@@ -2800,19 +3011,20 @@ void cmGlobalXCodeGenerator
sep = " ";
linkObjs += this->XCodeEscapePath(oi->c_str());
}
- this->AppendBuildSettingAttribute(target, "OTHER_LDFLAGS",
- linkObjs.c_str(), configName);
+ this->AppendBuildSettingAttribute(
+ target, this->GetTargetLinkFlagsVar(gt),
+ linkObjs.c_str(), configName);
}
// Skip link information for object libraries.
- if(cmtarget->GetType() == cmTarget::OBJECT_LIBRARY ||
- cmtarget->GetType() == cmTarget::STATIC_LIBRARY)
+ if(gt->GetType() == cmState::OBJECT_LIBRARY ||
+ gt->GetType() == cmState::STATIC_LIBRARY)
{
continue;
}
// Compute the link library and directory information.
- cmComputeLinkInformation* pcli = cmtarget->GetLinkInformation(configName);
+ cmComputeLinkInformation* pcli = gt->GetLinkInformation(configName);
if(!pcli)
{
continue;
@@ -2869,7 +3081,8 @@ void cmGlobalXCodeGenerator
{
linkLibs += this->XCodeEscapePath(li->Value.c_str());
}
- else
+ else if (!li->Target
+ || li->Target->GetType() != cmState::INTERFACE_LIBRARY)
{
linkLibs += li->Value;
}
@@ -2878,14 +3091,15 @@ void cmGlobalXCodeGenerator
target->AddDependTarget(configName, li->Target->GetName());
}
}
- this->AppendBuildSettingAttribute(target, "OTHER_LDFLAGS",
- linkLibs.c_str(), configName);
+ this->AppendBuildSettingAttribute(
+ target, this->GetTargetLinkFlagsVar(gt),
+ linkLibs.c_str(), configName);
}
}
}
//----------------------------------------------------------------------------
-void cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root,
+bool cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root,
std::vector<cmLocalGenerator*>&
generators)
{
@@ -2898,31 +3112,39 @@ void cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root,
}
cmMakefile* mf = (*i)->GetMakefile();
std::vector<cmSourceGroup> sourceGroups = mf->GetSourceGroups();
- cmTargets &tgts = mf->GetTargets();
- for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
+ std::vector<cmGeneratorTarget*> tgts = (*i)->GetGeneratorTargets();
+ for(std::vector<cmGeneratorTarget*>::iterator l = tgts.begin();
+ l != tgts.end(); l++)
{
- cmTarget& cmtarget = l->second;
+ cmGeneratorTarget* gtgt = *l;
// Same skipping logic here as in CreateXCodeTargets so that we do not
// end up with (empty anyhow) ALL_BUILD and XCODE_DEPEND_HELPER source
// groups:
//
- if(cmtarget.GetType() == cmTarget::GLOBAL_TARGET)
+ if(gtgt->GetType() == cmState::GLOBAL_TARGET)
+ {
+ continue;
+ }
+ if(gtgt->GetType() == cmState::INTERFACE_LIBRARY)
{
continue;
}
// add the soon to be generated Info.plist file as a source for a
// MACOSX_BUNDLE file
- if(cmtarget.GetPropertyAsBool("MACOSX_BUNDLE"))
+ if(gtgt->GetPropertyAsBool("MACOSX_BUNDLE"))
{
- std::string plist = this->ComputeInfoPListLocation(cmtarget);
- cmSourceFile* sf = mf->GetOrCreateSource(plist.c_str(), true);
- cmtarget.AddSourceFile(sf);
+ std::string plist = this->ComputeInfoPListLocation(gtgt);
+ mf->GetOrCreateSource(plist, true);
+ gtgt->AddSource(plist);
}
- std::vector<cmSourceFile*> classes = cmtarget.GetSourceFiles();
-
+ std::vector<cmSourceFile*> classes;
+ if (!gtgt->GetConfigCommonSourceFiles(classes))
+ {
+ return false;
+ }
// Put cmSourceFile instances in proper groups:
for(std::vector<cmSourceFile*>::const_iterator s = classes.begin();
s != classes.end(); s++)
@@ -2930,34 +3152,35 @@ void cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root,
cmSourceFile* sf = *s;
// Add the file to the list of sources.
std::string const& source = sf->GetFullPath();
- cmSourceGroup& sourceGroup =
+ cmSourceGroup* sourceGroup =
mf->FindSourceGroup(source.c_str(), sourceGroups);
cmXCodeObject* pbxgroup =
- this->CreateOrGetPBXGroup(cmtarget, &sourceGroup);
- cmStdString key = GetGroupMapKey(cmtarget, sf);
+ this->CreateOrGetPBXGroup(gtgt, sourceGroup);
+ std::string key = GetGroupMapKey(gtgt, sf);
this->GroupMap[key] = pbxgroup;
}
// Put OBJECT_LIBRARY objects in proper groups:
std::vector<std::string> objs;
- this->GetGeneratorTarget(&cmtarget)->UseObjectLibraries(objs);
+ gtgt->UseObjectLibraries(objs, "");
for(std::vector<std::string>::const_iterator
oi = objs.begin(); oi != objs.end(); ++oi)
{
std::string const& source = *oi;
- cmSourceGroup& sourceGroup =
+ cmSourceGroup* sourceGroup =
mf->FindSourceGroup(source.c_str(), sourceGroups);
cmXCodeObject* pbxgroup =
- this->CreateOrGetPBXGroup(cmtarget, &sourceGroup);
- cmStdString key = GetGroupMapKeyFromPath(cmtarget, source);
+ this->CreateOrGetPBXGroup(gtgt, sourceGroup);
+ std::string key = GetGroupMapKeyFromPath(gtgt, source);
this->GroupMap[key] = pbxgroup;
}
}
}
+ return true;
}
cmXCodeObject *cmGlobalXCodeGenerator
-::CreatePBXGroup(cmXCodeObject *parent, cmStdString name)
+::CreatePBXGroup(cmXCodeObject *parent, std::string name)
{
cmXCodeObject* parentChildren = NULL;
if(parent)
@@ -2979,19 +3202,19 @@ cmXCodeObject *cmGlobalXCodeGenerator
//----------------------------------------------------------------------------
cmXCodeObject* cmGlobalXCodeGenerator
-::CreateOrGetPBXGroup(cmTarget& cmtarget, cmSourceGroup* sg)
+::CreateOrGetPBXGroup(cmGeneratorTarget* gtgt, cmSourceGroup* sg)
{
- cmStdString s;
- cmStdString target;
- const char *targetFolder= cmtarget.GetProperty("FOLDER");
+ std::string s;
+ std::string target;
+ const char *targetFolder= gtgt->GetProperty("FOLDER");
if(targetFolder) {
target = targetFolder;
target += "/";
}
- target += cmtarget.GetName();
+ target += gtgt->GetName();
s = target + "/";
s += sg->GetFullName();
- std::map<cmStdString, cmXCodeObject* >::iterator it =
+ std::map<std::string, cmXCodeObject* >::iterator it =
this->GroupNameMap.find(s);
if(it != this->GroupNameMap.end())
{
@@ -3008,26 +3231,26 @@ cmXCodeObject* cmGlobalXCodeGenerator
{
std::vector<std::string> tgt_folders =
cmSystemTools::tokenize(target, "/");
- cmStdString curr_tgt_folder;
+ std::string curr_tgt_folder;
for(std::vector<std::string>::size_type i = 0; i < tgt_folders.size();i++)
{
- curr_tgt_folder += tgt_folders[i];
- it = this->TargetGroup.find(curr_tgt_folder);
- if(it == this->TargetGroup.end())
+ if (i != 0)
{
- tgroup = this->CreatePBXGroup(tgroup,tgt_folders[i]);
- this->TargetGroup[curr_tgt_folder] = tgroup;
+ curr_tgt_folder += "/";
}
- else
+ curr_tgt_folder += tgt_folders[i];
+ it = this->TargetGroup.find(curr_tgt_folder);
+ if(it != this->TargetGroup.end())
{
tgroup = it->second;
continue;
}
+ tgroup = this->CreatePBXGroup(tgroup,tgt_folders[i]);
+ this->TargetGroup[curr_tgt_folder] = tgroup;
if(i == 0)
{
this->SourcesGroupChildren->AddObject(tgroup);
}
- curr_tgt_folder += "/";
}
}
this->TargetGroup[target] = tgroup;
@@ -3035,7 +3258,7 @@ cmXCodeObject* cmGlobalXCodeGenerator
// If it's the default source group (empty name) then put the source file
// directly in the tgroup...
//
- if (cmStdString(sg->GetFullName()) == "")
+ if (std::string(sg->GetFullName()) == "")
{
this->GroupNameMap[s] = tgroup;
return tgroup;
@@ -3046,12 +3269,12 @@ cmXCodeObject* cmGlobalXCodeGenerator
{
std::vector<std::string> folders =
cmSystemTools::tokenize(sg->GetFullName(), "\\");
- cmStdString curr_folder = target;
+ std::string curr_folder = target;
curr_folder += "/";
for(std::vector<std::string>::size_type i = 0; i < folders.size();i++)
{
curr_folder += folders[i];
- std::map<cmStdString, cmXCodeObject* >::iterator i_folder =
+ std::map<std::string, cmXCodeObject* >::iterator i_folder =
this->GroupNameMap.find(curr_folder);
//Create new folder
if(i_folder == this->GroupNameMap.end())
@@ -3074,7 +3297,7 @@ cmXCodeObject* cmGlobalXCodeGenerator
}
//----------------------------------------------------------------------------
-void cmGlobalXCodeGenerator
+bool cmGlobalXCodeGenerator
::CreateXCodeObjects(cmLocalGenerator* root,
std::vector<cmLocalGenerator*>&
generators)
@@ -3155,7 +3378,10 @@ void cmGlobalXCodeGenerator
this->MainGroupChildren->AddObject(resourcesGroup);
// now create the cmake groups
- this->CreateGroups(root, generators);
+ if (!this->CreateGroups(root, generators))
+ {
+ return false;
+ }
cmXCodeObject* productGroup = this->CreateObject(cmXCodeObject::PBXGroup);
productGroup->AddAttribute("name", this->CreateString("Products"));
@@ -3174,7 +3400,7 @@ void cmGlobalXCodeGenerator
this->RootObject->SetComment("Project object");
std::string project_id = "PROJECT_";
- project_id += root->GetMakefile()->GetProjectName();
+ project_id += root->GetProjectName();
this->RootObject->SetId(this->GetOrCreateId(
project_id.c_str(), this->RootObject->GetId()).c_str());
@@ -3190,6 +3416,9 @@ void cmGlobalXCodeGenerator
group = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
group->AddAttribute("BuildIndependentTargetsInParallel",
this->CreateString("YES"));
+ std::ostringstream v;
+ v << std::setfill('0') << std::setw(4) << XcodeVersion * 10;
+ group->AddAttribute("LastUpgradeCheck", this->CreateString(v.str()));
this->RootObject->AddAttribute("attributes", group);
if (this->XcodeVersion >= 32)
this->RootObject->AddAttribute("compatibilityVersion",
@@ -3204,7 +3433,7 @@ void cmGlobalXCodeGenerator
// Point Xcode at the top of the source tree.
{
std::string pdir =
- this->RelativeToBinary(root->GetMakefile()->GetCurrentDirectory());
+ this->RelativeToBinary(root->GetCurrentSourceDirectory());
this->RootObject->AddAttribute("projectDirPath",
this->CreateString(pdir.c_str()));
this->RootObject->AddAttribute("projectRoot", this->CreateString(""));
@@ -3213,18 +3442,19 @@ void cmGlobalXCodeGenerator
this->CreateObject(cmXCodeObject::XCConfigurationList);
cmXCodeObject* buildConfigurations =
this->CreateObject(cmXCodeObject::OBJECT_LIST);
- std::vector<cmXCodeObject*> configs;
+ typedef std::vector<std::pair<std::string, cmXCodeObject*> > Configs;
+ Configs configs;
const char *defaultConfigName = "Debug";
if(this->XcodeVersion == 15)
{
cmXCodeObject* configDebug =
this->CreateObject(cmXCodeObject::XCBuildConfiguration);
configDebug->AddAttribute("name", this->CreateString("Debug"));
- configs.push_back(configDebug);
+ configs.push_back(std::make_pair("Debug", configDebug));
cmXCodeObject* configRelease =
this->CreateObject(cmXCodeObject::XCBuildConfiguration);
configRelease->AddAttribute("name", this->CreateString("Release"));
- configs.push_back(configRelease);
+ configs.push_back(std::make_pair("Release", configRelease));
}
else
{
@@ -3238,17 +3468,16 @@ void cmGlobalXCodeGenerator
cmXCodeObject* config =
this->CreateObject(cmXCodeObject::XCBuildConfiguration);
config->AddAttribute("name", this->CreateString(name));
- configs.push_back(config);
+ configs.push_back(std::make_pair(name, config));
}
}
- for(std::vector<cmXCodeObject*>::iterator c = configs.begin();
- c != configs.end(); ++c)
+ for(Configs::iterator c = configs.begin(); c != configs.end(); ++c)
{
- buildConfigurations->AddObject(*c);
+ buildConfigurations->AddObject(c->second);
}
configlist->AddAttribute("buildConfigurations", buildConfigurations);
- std::string comment = "Build configuration list for PBXProject ";
+ std::string comment = "Build configuration list for PBXProject";
comment += " \"";
comment += this->CurrentProject;
comment += "\"";
@@ -3261,89 +3490,76 @@ void cmGlobalXCodeGenerator
this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
const char* osxArch =
this->CurrentMakefile->GetDefinition("CMAKE_OSX_ARCHITECTURES");
- if(!osxArch || strlen(osxArch) == 0)
- {
- if(this->XcodeVersion >= 32)
- {
- osxArch = "$(ARCHS_STANDARD_32_64_BIT)";
- }
- else if(this->XcodeVersion == 31)
- {
- osxArch = "$(ARCHS_STANDARD_32_BIT)";
- }
- else if(this->XcodeVersion <= 30)
- {
-#ifdef __ppc__
- osxArch = "ppc";
-#endif
-#ifdef __i386
- osxArch = "i386";
-#endif
- }
- buildSettings->AddAttribute("ONLY_ACTIVE_ARCH",
- this->CreateString("YES"));
- }
-
const char* sysroot =
this->CurrentMakefile->GetDefinition("CMAKE_OSX_SYSROOT");
const char* deploymentTarget =
this->CurrentMakefile->GetDefinition("CMAKE_OSX_DEPLOYMENT_TARGET");
- if(osxArch && sysroot)
+ std::string archs;
+ if(sysroot)
{
- // recompute this as it may have been changed since enable language
- this->Architectures.clear();
- cmSystemTools::ExpandListArgument(std::string(osxArch),
- this->Architectures);
- buildSettings->AddAttribute("SDKROOT",
- this->CreateString(sysroot));
- std::string archString;
- const char* sep = "";
- for( std::vector<std::string>::iterator i =
- this->Architectures.begin();
- i != this->Architectures.end(); ++i)
+ if(osxArch)
{
- archString += sep;
- archString += *i;
- sep = " ";
+ // recompute this as it may have been changed since enable language
+ this->Architectures.clear();
+ cmSystemTools::ExpandListArgument(std::string(osxArch),
+ this->Architectures);
+ archs = cmJoin(this->Architectures, " ");
}
- buildSettings->AddAttribute("ARCHS",
- this->CreateString(archString.c_str()));
+ buildSettings->AddAttribute("SDKROOT",
+ this->CreateString(sysroot));
+ }
+ if (archs.empty())
+ {
+ // Tell Xcode to use NATIVE_ARCH instead of ARCHS.
+ buildSettings->AddAttribute("ONLY_ACTIVE_ARCH", this->CreateString("YES"));
+ }
+ else
+ {
+ // Tell Xcode to use ARCHS (ONLY_ACTIVE_ARCH defaults to NO).
+ buildSettings->AddAttribute("ARCHS", this->CreateString(archs.c_str()));
}
if(deploymentTarget && *deploymentTarget)
{
buildSettings->AddAttribute("MACOSX_DEPLOYMENT_TARGET",
this->CreateString(deploymentTarget));
}
- if(!this->PlatformToolset.empty())
+ if(!this->GeneratorToolset.empty())
{
buildSettings->AddAttribute("GCC_VERSION",
- this->CreateString(this->PlatformToolset.c_str()));
- }
-
- // Put this last so it can override existing settings
- // Convert "CMAKE_XCODE_ATTRIBUTE_*" variables directly.
- {
- std::vector<std::string> vars = this->CurrentMakefile->GetDefinitions();
- for(std::vector<std::string>::const_iterator i = vars.begin();
- i != vars.end(); ++i)
- {
- if(i->find("CMAKE_XCODE_ATTRIBUTE_") == 0)
- {
- buildSettings->AddAttribute(i->substr(22).c_str(),
- this->CreateString(
- this->CurrentMakefile->GetDefinition(i->c_str())));
- }
+ this->CreateString(this->GeneratorToolset.c_str()));
}
- }
- std::string symroot = root->GetMakefile()->GetCurrentOutputDirectory();
+ std::string symroot = root->GetCurrentBinaryDirectory();
symroot += "/build";
buildSettings->AddAttribute("SYMROOT", this->CreateString(symroot.c_str()));
- for( std::vector<cmXCodeObject*>::iterator i = configs.begin();
- i != configs.end(); ++i)
+ for(Configs::iterator i = configs.begin(); i != configs.end(); ++i)
{
- (*i)->AddAttribute("buildSettings", buildSettings);
+ cmXCodeObject* buildSettingsForCfg = this->CreateFlatClone(buildSettings);
+
+ // Put this last so it can override existing settings
+ // Convert "CMAKE_XCODE_ATTRIBUTE_*" variables directly.
+ std::vector<std::string> vars = this->CurrentMakefile->GetDefinitions();
+ for(std::vector<std::string>::const_iterator d = vars.begin();
+ d != vars.end(); ++d)
+ {
+ if(d->find("CMAKE_XCODE_ATTRIBUTE_") == 0)
+ {
+ std::string attribute = d->substr(22);
+ this->FilterConfigurationAttribute(i->first, attribute);
+ if(!attribute.empty())
+ {
+ cmGeneratorExpression ge;
+ std::string processed =
+ ge.Parse(this->CurrentMakefile->GetDefinition(*d))
+ ->Evaluate(this->CurrentLocalGenerator, i->first);
+ buildSettingsForCfg->AddAttribute(attribute,
+ this->CreateString(processed));
+ }
+ }
+ }
+ // store per-config buildSettings into configuration object
+ i->second->AddAttribute("buildSettings", buildSettingsForCfg);
}
this->RootObject->AddAttribute("buildConfigurationList",
@@ -3355,7 +3571,10 @@ void cmGlobalXCodeGenerator
{
if(!this->IsExcluded(root, *i))
{
- this->CreateXCodeTargets(*i, targets);
+ if (!this->CreateXCodeTargets(*i, targets))
+ {
+ return false;
+ }
}
}
// loop over all targets and add link and depend info
@@ -3384,6 +3603,7 @@ void cmGlobalXCodeGenerator
}
}
this->RootObject->AddAttribute("targets", allTargets);
+ return true;
}
//----------------------------------------------------------------------------
@@ -3391,10 +3611,10 @@ std::string
cmGlobalXCodeGenerator::GetObjectsNormalDirectory(
const std::string &projName,
const std::string &configName,
- const cmTarget *t) const
+ const cmGeneratorTarget *t) const
{
std::string dir =
- t->GetMakefile()->GetCurrentOutputDirectory();
+ t->GetLocalGenerator()->GetCurrentBinaryDirectory();
dir += "/";
dir += projName;
dir += ".build/";
@@ -3431,14 +3651,14 @@ cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
makefileStream
<< "# For each target create a dummy rule "
"so the target does not have to exist\n";
- std::set<cmStdString> emitted;
+ std::set<std::string> emitted;
for(std::vector<cmXCodeObject*>::iterator i = targets.begin();
i != targets.end(); ++i)
{
cmXCodeObject* target = *i;
- std::map<cmStdString, cmXCodeObject::StringVec> const& deplibs =
+ std::map<std::string, cmXCodeObject::StringVec> const& deplibs =
target->GetDependLibraries();
- for(std::map<cmStdString, cmXCodeObject::StringVec>::const_iterator ci
+ for(std::map<std::string, cmXCodeObject::StringVec>::const_iterator ci
= deplibs.begin(); ci != deplibs.end(); ++ci)
{
for(cmXCodeObject::StringVec::const_iterator d = ci->second.begin();
@@ -3463,43 +3683,39 @@ cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
ct = this->CurrentConfigurationTypes.begin();
ct != this->CurrentConfigurationTypes.end(); ++ct)
{
- const char* configName = 0;
- if(!ct->empty())
- {
- configName = ct->c_str();
- }
+ std::string configName = *ct;
for(std::vector<cmXCodeObject*>::iterator i = targets.begin();
i != targets.end(); ++i)
{
cmXCodeObject* target = *i;
- cmTarget* t =target->GetTarget();
+ cmGeneratorTarget* gt =target->GetTarget();
- if(t->GetType() == cmTarget::EXECUTABLE ||
+ if(gt->GetType() == cmState::EXECUTABLE ||
// Nope - no post-build for OBJECT_LIRBRARY
-// t->GetType() == cmTarget::OBJECT_LIBRARY ||
- t->GetType() == cmTarget::STATIC_LIBRARY ||
- t->GetType() == cmTarget::SHARED_LIBRARY ||
- t->GetType() == cmTarget::MODULE_LIBRARY)
+// gt->GetType() == cmState::OBJECT_LIBRARY ||
+ gt->GetType() == cmState::STATIC_LIBRARY ||
+ gt->GetType() == cmState::SHARED_LIBRARY ||
+ gt->GetType() == cmState::MODULE_LIBRARY)
{
// Declare an entry point for the target post-build phase.
- makefileStream << this->PostBuildMakeTarget(t->GetName(), *ct)
+ makefileStream << this->PostBuildMakeTarget(gt->GetName(), *ct)
<< ":\n";
}
- if(t->GetType() == cmTarget::EXECUTABLE ||
- t->GetType() == cmTarget::SHARED_LIBRARY ||
- t->GetType() == cmTarget::MODULE_LIBRARY)
+ if(gt->GetType() == cmState::EXECUTABLE ||
+ gt->GetType() == cmState::SHARED_LIBRARY ||
+ gt->GetType() == cmState::MODULE_LIBRARY)
{
- std::string tfull = t->GetFullPath(configName);
+ std::string tfull = gt->GetFullPath(configName);
std::string trel = this->ConvertToRelativeForMake(tfull.c_str());
// Add this target to the post-build phases of its dependencies.
- std::map<cmStdString, cmXCodeObject::StringVec>::const_iterator
+ std::map<std::string, cmXCodeObject::StringVec>::const_iterator
y = target->GetDependTargets().find(*ct);
if(y != target->GetDependTargets().end())
{
- std::vector<cmStdString> const& deptgts = y->second;
- for(std::vector<cmStdString>::const_iterator d = deptgts.begin();
+ std::vector<std::string> const& deptgts = y->second;
+ for(std::vector<std::string>::const_iterator d = deptgts.begin();
d != deptgts.end(); ++d)
{
makefileStream << this->PostBuildMakeTarget(*d, *ct) << ": "
@@ -3511,12 +3727,12 @@ cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
makefileStream << trel << ":";
// List dependencies if any exist.
- std::map<cmStdString, cmXCodeObject::StringVec>::const_iterator
+ std::map<std::string, cmXCodeObject::StringVec>::const_iterator
x = target->GetDependLibraries().find(*ct);
if(x != target->GetDependLibraries().end())
{
- std::vector<cmStdString> const& deplibs = x->second;
- for(std::vector<cmStdString>::const_iterator d = deplibs.begin();
+ std::vector<std::string> const& deplibs = x->second;
+ for(std::vector<std::string>::const_iterator d = deplibs.begin();
d != deplibs.end(); ++d)
{
makefileStream << "\\\n\t" <<
@@ -3533,7 +3749,7 @@ cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
if(this->Architectures.size() > 1)
{
std::string universal = this->GetObjectsNormalDirectory(
- this->CurrentProject, configName, t);
+ this->CurrentProject, configName, gt);
for( std::vector<std::string>::iterator arch =
this->Architectures.begin();
arch != this->Architectures.end(); ++arch)
@@ -3541,7 +3757,7 @@ cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
std::string universalFile = universal;
universalFile += *arch;
universalFile += "/";
- universalFile += t->GetFullName(configName);
+ universalFile += gt->GetFullName(configName);
makefileStream << "\t/bin/rm -f "
<<
this->ConvertToRelativeForMake(universalFile.c_str())
@@ -3574,11 +3790,13 @@ cmGlobalXCodeGenerator::OutputXCodeProject(cmLocalGenerator* root,
}
}
- this->CreateXCodeObjects(root,
- generators);
- std::string xcodeDir = root->GetMakefile()->GetStartOutputDirectory();
+ if (!this->CreateXCodeObjects(root, generators))
+ {
+ return;
+ }
+ std::string xcodeDir = root->GetCurrentBinaryDirectory();
xcodeDir += "/";
- xcodeDir += root->GetMakefile()->GetProjectName();
+ xcodeDir += root->GetProjectName();
xcodeDir += ".xcode";
if(this->XcodeVersion > 20)
{
@@ -3597,8 +3815,8 @@ cmGlobalXCodeGenerator::OutputXCodeProject(cmLocalGenerator* root,
// Since this call may have created new cache entries, save the cache:
//
- root->GetMakefile()->GetCacheManager()->SaveCache(
- root->GetMakefile()->GetHomeOutputDirectory());
+ root->GetMakefile()->GetCMakeInstance()->SaveCache(
+ root->GetBinaryDirectory());
}
//----------------------------------------------------------------------------
@@ -3607,6 +3825,8 @@ cmGlobalXCodeGenerator::WriteXCodePBXProj(std::ostream& fout,
cmLocalGenerator* ,
std::vector<cmLocalGenerator*>& )
{
+ SortXCodeObjects();
+
fout << "// !$*UTF8*$!\n";
fout << "{\n";
cmXCodeObject::Indent(1, fout);
@@ -3634,7 +3854,8 @@ cmGlobalXCodeGenerator::WriteXCodePBXProj(std::ostream& fout,
cmXCodeObject::PrintList(this->XCodeObjects, fout);
}
cmXCodeObject::Indent(1, fout);
- fout << "rootObject = " << this->RootObject->GetId() << ";\n";
+ fout << "rootObject = " << this->RootObject->GetId()
+ << " /* Project object */;\n";
fout << "}\n";
}
@@ -3645,44 +3866,41 @@ const char* cmGlobalXCodeGenerator::GetCMakeCFGIntDir() const
"$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)" : ".";
}
-//----------------------------------------------------------------------------
-void cmGlobalXCodeGenerator::GetDocumentation(cmDocumentationEntry& entry)
+std::string cmGlobalXCodeGenerator::ExpandCFGIntDir(const std::string& str,
+ const std::string& config) const
{
- entry.Name = cmGlobalXCodeGenerator::GetActualName();
- entry.Brief = "Generate Xcode project files.";
- entry.Full = "";
-}
+ std::string replace1 = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
+ std::string replace2 = "$(CONFIGURATION)";
-//----------------------------------------------------------------------------
-std::string cmGlobalXCodeGenerator::ConvertToRelativeForMake(const char* p)
-{
- if ( !this->CurrentMakefile->IsOn("CMAKE_USE_RELATIVE_PATHS") )
+ std::string tmp = str;
+ for(std::string::size_type i = tmp.find(replace1);
+ i != std::string::npos;
+ i = tmp.find(replace1, i))
{
- return cmSystemTools::ConvertToOutputPath(p);
+ tmp.replace(i, replace1.size(), config);
+ i += config.size();
}
- else
+ for(std::string::size_type i = tmp.find(replace2);
+ i != std::string::npos;
+ i = tmp.find(replace2, i))
{
- std::string ret =
- this->CurrentLocalGenerator->
- ConvertToRelativePath(this->CurrentOutputDirectoryComponents, p);
- return cmSystemTools::ConvertToOutputPath(ret.c_str());
+ tmp.replace(i, replace2.size(), config);
+ i += config.size();
}
+ return tmp;
}
//----------------------------------------------------------------------------
-std::string cmGlobalXCodeGenerator::ConvertToRelativeForXCode(const char* p)
+void cmGlobalXCodeGenerator::GetDocumentation(cmDocumentationEntry& entry)
{
- if ( !this->CurrentMakefile->IsOn("CMAKE_USE_RELATIVE_PATHS") )
- {
- return cmSystemTools::ConvertToOutputPath(p);
- }
- else
- {
- std::string ret =
- this->CurrentLocalGenerator->
- ConvertToRelativePath(this->ProjectOutputDirectoryComponents, p);
- return cmSystemTools::ConvertToOutputPath(ret.c_str());
- }
+ entry.Name = cmGlobalXCodeGenerator::GetActualName();
+ entry.Brief = "Generate Xcode project files.";
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalXCodeGenerator::ConvertToRelativeForMake(const char* p)
+{
+ return cmSystemTools::ConvertToOutputPath(p);
}
//----------------------------------------------------------------------------
@@ -3718,14 +3936,14 @@ std::string cmGlobalXCodeGenerator::XCodeEscapePath(const char* p)
//----------------------------------------------------------------------------
void
cmGlobalXCodeGenerator
-::AppendDirectoryForConfig(const char* prefix,
- const char* config,
- const char* suffix,
+::AppendDirectoryForConfig(const std::string& prefix,
+ const std::string& config,
+ const std::string& suffix,
std::string& dir)
{
if(this->XcodeVersion > 20)
{
- if(config)
+ if(!config.empty())
{
dir += prefix;
dir += config;
@@ -3735,12 +3953,13 @@ cmGlobalXCodeGenerator
}
//----------------------------------------------------------------------------
-std::string cmGlobalXCodeGenerator::LookupFlags(const char* varNamePrefix,
- const char* varNameLang,
- const char* varNameSuffix,
- const char* default_flags)
+std::string cmGlobalXCodeGenerator::LookupFlags(
+ const std::string& varNamePrefix,
+ const std::string& varNameLang,
+ const std::string& varNameSuffix,
+ const std::string& default_flags)
{
- if(varNameLang)
+ if(!varNameLang.empty())
{
std::string varName = varNamePrefix;
varName += varNameLang;
@@ -3820,8 +4039,8 @@ void cmGlobalXCodeGenerator::AppendFlag(std::string& flags,
// We escape a flag as follows:
// - Place each flag in single quotes ''
- // - Escape a single quote as \\'
- // - Escape a backslash as \\\\ since it itself is an escape
+ // - Escape a single quote as \'
+ // - Escape a backslash as \\ since it itself is an escape
// Note that in the code below we need one more level of escapes for
// C string syntax in this source file.
//
@@ -3841,16 +4060,16 @@ void cmGlobalXCodeGenerator::AppendFlag(std::string& flags,
{
if (this->XcodeVersion >= 40)
{
- flags += "'\\\\''";
+ flags += "'\\''";
}
else
{
- flags += "\\\\'";
+ flags += "\\'";
}
}
else if(*c == '\\')
{
- flags += "\\\\\\\\";
+ flags += "\\\\";
}
else
{
@@ -3867,12 +4086,13 @@ void cmGlobalXCodeGenerator::AppendFlag(std::string& flags,
//----------------------------------------------------------------------------
std::string
-cmGlobalXCodeGenerator::ComputeInfoPListLocation(cmTarget& target)
+cmGlobalXCodeGenerator::ComputeInfoPListLocation(cmGeneratorTarget* target)
{
- std::string plist = target.GetMakefile()->GetCurrentOutputDirectory();
+ std::string plist =
+ target->GetLocalGenerator()->GetCurrentBinaryDirectory();
plist += cmake::GetCMakeFilesDirectory();
plist += "/";
- plist += target.GetName();
+ plist += target->GetName();
plist += ".dir/Info.plist";
return plist;
}
@@ -3892,38 +4112,13 @@ bool cmGlobalXCodeGenerator::IsMultiConfig()
return true;
}
- //----------------------------------------------------------------------------
-void
-cmGlobalXCodeGenerator
-::ComputeTargetObjects(cmGeneratorTarget* gt) const
+//----------------------------------------------------------------------------
+void cmGlobalXCodeGenerator
+::ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const
{
- // Count the number of object files with each name. Warn about duplicate
- // names since Xcode names them uniquely automatically with a numeric suffix
- // to avoid exact duplicate file names. Note that Mac file names are not
- // typically case sensitive, hence the LowerCase.
- std::map<cmStdString, int> counts;
- for(std::vector<cmSourceFile*>::const_iterator
- si = gt->ObjectSources.begin();
- si != gt->ObjectSources.end(); ++si)
- {
- cmSourceFile* sf = *si;
- std::string objectName =
- cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath());
- objectName += ".o";
-
- std::string objectNameLower = cmSystemTools::LowerCase(objectName);
- counts[objectNameLower] += 1;
- if (2 == counts[objectNameLower])
- {
- // TODO: emit warning about duplicate name?
- }
-
- gt->Objects[sf] = objectName;
- }
-
- const char* configName = this->GetCMakeCFGIntDir();
+ std::string configName = this->GetCMakeCFGIntDir();
std::string dir = this->GetObjectsNormalDirectory(
- "$(PROJECT_NAME)", configName, gt->Target);
+ "$(PROJECT_NAME)", configName, gt);
if(this->XcodeVersion >= 21)
{
dir += "$(CURRENT_ARCH)/";
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index c05394346..862746f21 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -16,7 +16,6 @@
#include "cmXCodeObject.h"
#include "cmCustomCommand.h"
class cmGlobalGeneratorFactory;
-class cmTarget;
class cmSourceFile;
class cmSourceGroup;
@@ -29,22 +28,22 @@ class cmSourceGroup;
class cmGlobalXCodeGenerator : public cmGlobalGenerator
{
public:
- cmGlobalXCodeGenerator(std::string const& version);
+ cmGlobalXCodeGenerator(cmake* cm, std::string const& version);
static cmGlobalGeneratorFactory* NewFactory();
///! Get the name for the generator.
- virtual const char* GetName() const {
+ virtual std::string GetName() const {
return cmGlobalXCodeGenerator::GetActualName();}
- static const char* GetActualName() {return "Xcode";}
+ static std::string GetActualName() {return "Xcode";}
/** Get the documentation entry for this generator. */
static void GetDocumentation(cmDocumentationEntry& entry);
///! Create a local generator appropriate to this Global Generator
- virtual cmLocalGenerator *CreateLocalGenerator();
+ virtual cmLocalGenerator *CreateLocalGenerator(cmMakefile *mf);
/**
- * Try to determine system infomation such as shared library
+ * Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
@@ -53,30 +52,30 @@ public:
* Try running cmake and building a file. This is used for dynalically
* loaded commands, not as part of the usual build process.
*/
- virtual std::string GenerateBuildCommand(const char* makeProgram,
- const char *projectName,
- const char *projectDir,
- const char* additionalOptions,
- const char *targetName,
- const char* config,
- bool ignoreErrors,
- bool fast);
-
- /**
- * Generate the all required files for building this project/tree. This
- * basically creates a series of LocalGenerators for each directory and
- * requests that they Generate.
- */
- virtual void Generate();
+ virtual void GenerateBuildCommand(
+ std::vector<std::string>& makeCommand,
+ const std::string& makeProgram,
+ const std::string& projectName,
+ const std::string& projectDir,
+ const std::string& targetName,
+ const std::string& config,
+ bool fast, bool verbose,
+ std::vector<std::string> const& makeOptions = std::vector<std::string>()
+ );
/** Append the subdirectory for the given configuration. */
- virtual void AppendDirectoryForConfig(const char* prefix,
- const char* config,
- const char* suffix,
+ virtual void AppendDirectoryForConfig(const std::string& prefix,
+ const std::string& config,
+ const std::string& suffix,
std::string& dir);
+ virtual void FindMakeProgram(cmMakefile*);
+
///! What is the configurations directory variable called?
virtual const char* GetCMakeCFGIntDir() const;
+ ///! expand CFGIntDir
+ virtual std::string ExpandCFGIntDir(const std::string& str,
+ const std::string& config) const;
void SetCurrentLocalGenerator(cmLocalGenerator*);
@@ -84,20 +83,22 @@ public:
i.e. "Can I build Debug and Release in the same tree?" */
virtual bool IsMultiConfig();
- virtual bool SetGeneratorToolset(std::string const& ts);
+ virtual bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf);
void AppendFlag(std::string& flags, std::string const& flag);
+protected:
+ virtual void AddExtraIDETargets();
+ virtual void Generate();
private:
- cmXCodeObject* CreateOrGetPBXGroup(cmTarget& cmtarget,
+ cmXCodeObject* CreateOrGetPBXGroup(cmGeneratorTarget* gtgt,
cmSourceGroup* sg);
cmXCodeObject* CreatePBXGroup(cmXCodeObject *parent,
- cmStdString name);
- void CreateGroups(cmLocalGenerator* root,
+ std::string name);
+ bool CreateGroups(cmLocalGenerator* root,
std::vector<cmLocalGenerator*>&
generators);
std::string XCodeEscapePath(const char* p);
std::string RelativeToSource(const char* p);
std::string RelativeToBinary(const char* p);
- std::string ConvertToRelativeForXCode(const char* p);
std::string ConvertToRelativeForMake(const char* p);
void CreateCustomCommands(cmXCodeObject* buildPhases,
cmXCodeObject* sourceBuildPhase,
@@ -105,70 +106,78 @@ private:
cmXCodeObject* resourceBuildPhase,
std::vector<cmXCodeObject*> contentBuildPhases,
cmXCodeObject* frameworkBuildPhase,
- cmTarget& cmtarget);
+ cmGeneratorTarget *gtgt);
- std::string ComputeInfoPListLocation(cmTarget& target);
+ std::string ComputeInfoPListLocation(cmGeneratorTarget *target);
void AddCommandsToBuildPhase(cmXCodeObject* buildphase,
- cmTarget& target,
+ cmGeneratorTarget *target,
std::vector<cmCustomCommand>
const & commands,
const char* commandFileName);
void CreateCustomRulesMakefile(const char* makefileBasename,
- cmTarget& target,
+ cmGeneratorTarget* target,
std::vector<cmCustomCommand> const & commands,
- const char* configName,
- const std::map<cmStdString, cmStdString>&
- multipleOutputPairs
- );
+ const std::string& configName);
- cmXCodeObject* FindXCodeTarget(cmTarget*);
- std::string GetOrCreateId(const char* name, const char* id);
+ cmXCodeObject* FindXCodeTarget(const cmGeneratorTarget *);
+ std::string GetOrCreateId(const std::string& name, const std::string& id);
// create cmXCodeObject from these functions so that memory can be managed
// correctly. All objects created are stored in this->XCodeObjects.
cmXCodeObject* CreateObject(cmXCodeObject::PBXType ptype);
cmXCodeObject* CreateObject(cmXCodeObject::Type type);
- cmXCodeObject* CreateString(const char* s);
+ cmXCodeObject* CreateString(const std::string& s);
cmXCodeObject* CreateObjectReference(cmXCodeObject*);
- cmXCodeObject* CreateXCodeTarget(cmTarget& target,
+ cmXCodeObject* CreateFlatClone(cmXCodeObject*);
+ cmXCodeObject* CreateXCodeTarget(cmGeneratorTarget *gtgt,
cmXCodeObject* buildPhases);
void ForceLinkerLanguages();
- void ForceLinkerLanguage(cmTarget& cmtarget);
- const char* GetTargetFileType(cmTarget& cmtarget);
- const char* GetTargetProductType(cmTarget& cmtarget);
- std::string AddConfigurations(cmXCodeObject* target, cmTarget& cmtarget);
+ void ForceLinkerLanguage(cmGeneratorTarget* gtgt);
+ const char* GetTargetLinkFlagsVar(const cmGeneratorTarget *target) const;
+ const char* GetTargetFileType(cmGeneratorTarget* target);
+ const char* GetTargetProductType(cmGeneratorTarget* target);
+ std::string AddConfigurations(cmXCodeObject* target,
+ cmGeneratorTarget *gtgt);
void AppendOrAddBuildSetting(cmXCodeObject* settings, const char* attr,
const char* value);
void AppendBuildSettingAttribute(cmXCodeObject* target, const char* attr,
- const char* value, const char* configName);
- cmXCodeObject* CreateUtilityTarget(cmTarget& target);
+ const char* value,
+ const std::string& configName);
+ cmXCodeObject* CreateUtilityTarget(cmGeneratorTarget *gtgt);
void AddDependAndLinkInformation(cmXCodeObject* target);
- void CreateBuildSettings(cmTarget& target,
+ void CreateBuildSettings(cmGeneratorTarget *gtgt,
cmXCodeObject* buildSettings,
- const char* buildType);
+ const std::string& buildType);
std::string ExtractFlag(const char* flag, std::string& flags);
+ std::string ExtractFlagRegex(const char* exp, int matchIndex,
+ std::string& flags);
+ void FilterConfigurationAttribute(std::string const& configName,
+ std::string& attribute);
+ void SortXCodeObjects();
// delete all objects in the this->XCodeObjects vector.
void ClearXCodeObjects();
- void CreateXCodeObjects(cmLocalGenerator* root,
+ bool CreateXCodeObjects(cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators);
void OutputXCodeProject(cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators);
void WriteXCodePBXProj(std::ostream& fout, cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators);
cmXCodeObject* CreateXCodeFileReferenceFromPath(const std::string &fullpath,
- cmTarget& cmtarget,
- const std::string &lang);
+ cmGeneratorTarget *target,
+ const std::string &lang,
+ cmSourceFile* sf);
cmXCodeObject* CreateXCodeSourceFileFromPath(const std::string &fullpath,
- cmTarget& cmtarget,
- const std::string &lang);
+ cmGeneratorTarget *target,
+ const std::string &lang,
+ cmSourceFile* sf);
cmXCodeObject* CreateXCodeFileReference(cmSourceFile* sf,
- cmTarget& cmtarget);
+ cmGeneratorTarget *target);
cmXCodeObject* CreateXCodeSourceFile(cmLocalGenerator* gen,
cmSourceFile* sf,
- cmTarget& cmtarget);
- void CreateXCodeTargets(cmLocalGenerator* gen,
+ cmGeneratorTarget *gtgt);
+ bool CreateXCodeTargets(cmLocalGenerator* gen,
std::vector<cmXCodeObject*>&);
bool IsHeaderFile(cmSourceFile*);
void AddDependTarget(cmXCodeObject* target,
@@ -180,15 +189,15 @@ private:
std::vector<cmLocalGenerator*>& gens);
cmXCodeObject* CreateBuildPhase(const char* name,
const char* name2,
- cmTarget& cmtarget,
+ cmGeneratorTarget *target,
const std::vector<cmCustomCommand>&);
void CreateReRunCMakeFile(cmLocalGenerator* root,
std::vector<cmLocalGenerator*> const& gens);
- std::string LookupFlags(const char* varNamePrefix,
- const char* varNameLang,
- const char* varNameSuffix,
- const char* default_flags);
+ std::string LookupFlags(const std::string& varNamePrefix,
+ const std::string& varNameLang,
+ const std::string& varNameSuffix,
+ const std::string& default_flags);
class Factory;
class BuildObjectListOrString;
@@ -200,22 +209,28 @@ private:
std::vector<std::string> const& defines,
bool dflag = false);
+ void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const;
protected:
virtual const char* GetInstallTargetName() const { return "install"; }
virtual const char* GetPackageTargetName() const { return "package"; }
unsigned int XcodeVersion;
std::string VersionString;
- std::set<cmStdString> XCodeObjectIDs;
+ std::set<std::string> XCodeObjectIDs;
std::vector<cmXCodeObject*> XCodeObjects;
cmXCodeObject* RootObject;
private:
- void ComputeTargetObjects(cmGeneratorTarget* gt) const;
+ std::string const& GetXcodeBuildCommand();
+ std::string FindXcodeBuildCommand();
+ std::string XcodeBuildCommand;
+ bool XcodeBuildCommandInitialized;
+
+ void PrintCompilerAdvice(std::ostream&, std::string const&,
+ const char*) const {}
- std::string GetObjectsNormalDirectory(
- const std::string &projName,
+ std::string GetObjectsNormalDirectory(const std::string &projName,
const std::string &configName,
- const cmTarget *t) const;
+ const cmGeneratorTarget *t) const;
void addObject(cmXCodeObject *obj);
std::string PostBuildMakeTarget(std::string const& tName,
@@ -229,16 +244,17 @@ private:
std::string CurrentReRunCMakeMakefile;
std::string CurrentXCodeHackMakefile;
std::string CurrentProject;
- std::set<cmStdString> TargetDoneSet;
+ std::set<std::string> TargetDoneSet;
std::vector<std::string> CurrentOutputDirectoryComponents;
std::vector<std::string> ProjectSourceDirectoryComponents;
std::vector<std::string> ProjectOutputDirectoryComponents;
- std::map<cmStdString, cmXCodeObject* > GroupMap;
- std::map<cmStdString, cmXCodeObject* > GroupNameMap;
- std::map<cmStdString, cmXCodeObject* > TargetGroup;
- std::map<cmStdString, cmXCodeObject* > FileRefs;
+ std::map<std::string, cmXCodeObject* > GroupMap;
+ std::map<std::string, cmXCodeObject* > GroupNameMap;
+ std::map<std::string, cmXCodeObject* > TargetGroup;
+ std::map<std::string, cmXCodeObject* > FileRefs;
+ std::map<cmGeneratorTarget const*, cmXCodeObject* > XCodeObjectMap;
std::vector<std::string> Architectures;
- std::string PlatformToolset;
+ std::string GeneratorToolset;
};
#endif
diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx
index 4816da9ea..448306fe4 100644
--- a/Source/cmGraphVizWriter.cxx
+++ b/Source/cmGraphVizWriter.cxx
@@ -17,7 +17,7 @@
-static const char* getShapeForTarget(const cmTarget* target)
+static const char* getShapeForTarget(const cmGeneratorTarget* target)
{
if (!target)
{
@@ -26,13 +26,13 @@ static const char* getShapeForTarget(const cmTarget* target)
switch ( target->GetType() )
{
- case cmTarget::EXECUTABLE:
+ case cmState::EXECUTABLE:
return "house";
- case cmTarget::STATIC_LIBRARY:
+ case cmState::STATIC_LIBRARY:
return "diamond";
- case cmTarget::SHARED_LIBRARY:
+ case cmState::SHARED_LIBRARY:
return "polygon";
- case cmTarget::MODULE_LIBRARY:
+ case cmState::MODULE_LIBRARY:
return "octagon";
default:
break;
@@ -48,12 +48,14 @@ cmGraphVizWriter::cmGraphVizWriter(const std::vector<cmLocalGenerator*>&
,GraphName("GG")
,GraphHeader("node [\n fontsize = \"12\"\n];")
,GraphNodePrefix("node")
+,LocalGenerators(localGenerators)
,GenerateForExecutables(true)
,GenerateForStaticLibs(true)
,GenerateForSharedLibs(true)
,GenerateForModuleLibs(true)
,GenerateForExternals(true)
-,LocalGenerators(localGenerators)
+,GeneratePerTarget(true)
+,GenerateDependers(true)
,HaveTargetsAndLibs(false)
{
}
@@ -63,10 +65,13 @@ void cmGraphVizWriter::ReadSettings(const char* settingsFileName,
const char* fallbackSettingsFileName)
{
cmake cm;
- cmGlobalGenerator ggi;
- ggi.SetCMakeInstance(&cm);
- cmsys::auto_ptr<cmLocalGenerator> lg(ggi.CreateLocalGenerator());
- cmMakefile *mf = lg->GetMakefile();
+ cm.SetHomeDirectory("");
+ cm.SetHomeOutputDirectory("");
+ cm.GetCurrentSnapshot().SetDefaultDefinitions();
+ cmGlobalGenerator ggi(&cm);
+ cmsys::auto_ptr<cmMakefile> mf(
+ new cmMakefile(&ggi, cm.GetCurrentSnapshot()));
+ cmsys::auto_ptr<cmLocalGenerator> lg(ggi.CreateLocalGenerator(mf.get()));
const char* inFileName = settingsFileName;
@@ -79,7 +84,7 @@ void cmGraphVizWriter::ReadSettings(const char* settingsFileName,
}
}
- if ( !mf->ReadListFile(0, inFileName) )
+ if ( !mf->ReadListFile(inFileName) )
{
cmSystemTools::Error("Problem opening GraphViz options file: ",
inFileName);
@@ -116,12 +121,14 @@ void cmGraphVizWriter::ReadSettings(const char* settingsFileName,
__set_bool_if_set(this->GenerateForSharedLibs, "GRAPHVIZ_SHARED_LIBS");
__set_bool_if_set(this->GenerateForModuleLibs, "GRAPHVIZ_MODULE_LIBS");
__set_bool_if_set(this->GenerateForExternals, "GRAPHVIZ_EXTERNAL_LIBS");
+ __set_bool_if_set(this->GeneratePerTarget, "GRAPHVIZ_GENERATE_PER_TARGET");
+ __set_bool_if_set(this->GenerateDependers, "GRAPHVIZ_GENERATE_DEPENDERS");
- cmStdString ignoreTargetsRegexes;
+ std::string ignoreTargetsRegexes;
__set_if_set(ignoreTargetsRegexes, "GRAPHVIZ_IGNORE_TARGETS");
this->TargetsToIgnoreRegex.clear();
- if (ignoreTargetsRegexes.size() > 0)
+ if (!ignoreTargetsRegexes.empty())
{
std::vector<std::string> ignoreTargetsRegExVector;
cmSystemTools::ExpandListArgument(ignoreTargetsRegexes,
@@ -131,7 +138,7 @@ void cmGraphVizWriter::ReadSettings(const char* settingsFileName,
itvIt != ignoreTargetsRegExVector.end();
++ itvIt )
{
- cmStdString currentRegexString(*itvIt);
+ std::string currentRegexString(*itvIt);
cmsys::RegularExpression currentRegex;
if (!currentRegex.compile(currentRegexString.c_str()))
{
@@ -149,9 +156,14 @@ void cmGraphVizWriter::ReadSettings(const char* settingsFileName,
// which other targets depend on it.
void cmGraphVizWriter::WriteTargetDependersFiles(const char* fileName)
{
+ if(this->GenerateDependers == false)
+ {
+ return;
+ }
+
this->CollectTargetsAndLibs();
- for(std::map<cmStdString, const cmTarget*>::const_iterator ptrIt =
+ for(std::map<std::string, const cmGeneratorTarget*>::const_iterator ptrIt =
this->TargetPtrs.begin();
ptrIt != this->TargetPtrs.end();
++ptrIt)
@@ -183,7 +195,7 @@ void cmGraphVizWriter::WriteTargetDependersFiles(const char* fileName)
std::cout << "Writing " << currentFilename << "..." << std::endl;
this->WriteHeader(str);
- this->WriteDependerConnections(ptrIt->first.c_str(),
+ this->WriteDependerConnections(ptrIt->first,
insertedNodes, insertedConnections, str);
this->WriteFooter(str);
@@ -195,9 +207,14 @@ void cmGraphVizWriter::WriteTargetDependersFiles(const char* fileName)
// on which targets it depends.
void cmGraphVizWriter::WritePerTargetFiles(const char* fileName)
{
+ if(this->GeneratePerTarget == false)
+ {
+ return;
+ }
+
this->CollectTargetsAndLibs();
- for(std::map<cmStdString, const cmTarget*>::const_iterator ptrIt =
+ for(std::map<std::string, const cmGeneratorTarget*>::const_iterator ptrIt =
this->TargetPtrs.begin();
ptrIt != this->TargetPtrs.end();
++ptrIt)
@@ -227,7 +244,7 @@ void cmGraphVizWriter::WritePerTargetFiles(const char* fileName)
std::cout << "Writing " << currentFilename << "..." << std::endl;
this->WriteHeader(str);
- this->WriteConnections(ptrIt->first.c_str(),
+ this->WriteConnections(ptrIt->first,
insertedNodes, insertedConnections, str);
this->WriteFooter(str);
}
@@ -251,7 +268,7 @@ void cmGraphVizWriter::WriteGlobalFile(const char* fileName)
std::set<std::string> insertedConnections;
std::set<std::string> insertedNodes;
- for(std::map<cmStdString, const cmTarget*>::const_iterator ptrIt =
+ for(std::map<std::string, const cmGeneratorTarget*>::const_iterator ptrIt =
this->TargetPtrs.begin();
ptrIt != this->TargetPtrs.end();
++ptrIt)
@@ -266,7 +283,7 @@ void cmGraphVizWriter::WriteGlobalFile(const char* fileName)
continue;
}
- this->WriteConnections(ptrIt->first.c_str(),
+ this->WriteConnections(ptrIt->first,
insertedNodes, insertedConnections, str);
}
this->WriteFooter(str);
@@ -275,7 +292,7 @@ void cmGraphVizWriter::WriteGlobalFile(const char* fileName)
void cmGraphVizWriter::WriteHeader(cmGeneratedFileStream& str) const
{
- str << this->GraphType << " " << this->GraphName << " {" << std::endl;
+ str << this->GraphType << " \"" << this->GraphName << "\" {" << std::endl;
str << this->GraphHeader << std::endl;
}
@@ -286,13 +303,13 @@ void cmGraphVizWriter::WriteFooter(cmGeneratedFileStream& str) const
}
-void cmGraphVizWriter::WriteConnections(const char* targetName,
+void cmGraphVizWriter::WriteConnections(const std::string& targetName,
std::set<std::string>& insertedNodes,
std::set<std::string>& insertedConnections,
cmGeneratedFileStream& str) const
{
- std::map<cmStdString, const cmTarget* >::const_iterator targetPtrIt =
- this->TargetPtrs.find(targetName);
+ std::map<std::string, const cmGeneratorTarget* >::const_iterator targetPtrIt
+ = this->TargetPtrs.find(targetName);
if (targetPtrIt == this->TargetPtrs.end()) // not found at all
{
@@ -310,14 +327,14 @@ void cmGraphVizWriter::WriteConnections(const char* targetName,
std::string myNodeName = this->TargetNamesNodes.find(targetName)->second;
const cmTarget::LinkLibraryVectorType* ll =
- &(targetPtrIt->second->GetOriginalLinkLibraries());
+ &(targetPtrIt->second->Target->GetOriginalLinkLibraries());
for (cmTarget::LinkLibraryVectorType::const_iterator llit = ll->begin();
llit != ll->end();
++ llit )
{
const char* libName = llit->first.c_str();
- std::map<cmStdString, cmStdString>::const_iterator libNameIt =
+ std::map<std::string, std::string>::const_iterator libNameIt =
this->TargetNamesNodes.find(libName);
// can happen e.g. if GRAPHVIZ_TARGET_IGNORE_REGEX is used
@@ -335,8 +352,8 @@ void cmGraphVizWriter::WriteConnections(const char* targetName,
this->WriteNode(libName, this->TargetPtrs.find(libName)->second,
insertedNodes, str);
- str << " \"" << myNodeName.c_str() << "\" -> \""
- << libNameIt->second.c_str() << "\"";
+ str << " \"" << myNodeName << "\" -> \""
+ << libNameIt->second << "\"";
str << " // " << targetName << " -> " << libName << std::endl;
this->WriteConnections(libName, insertedNodes, insertedConnections, str);
}
@@ -345,13 +362,13 @@ void cmGraphVizWriter::WriteConnections(const char* targetName,
}
-void cmGraphVizWriter::WriteDependerConnections(const char* targetName,
+void cmGraphVizWriter::WriteDependerConnections(const std::string& targetName,
std::set<std::string>& insertedNodes,
std::set<std::string>& insertedConnections,
cmGeneratedFileStream& str) const
{
- std::map<cmStdString, const cmTarget* >::const_iterator targetPtrIt =
- this->TargetPtrs.find(targetName);
+ std::map<std::string, const cmGeneratorTarget* >::const_iterator targetPtrIt
+ = this->TargetPtrs.find(targetName);
if (targetPtrIt == this->TargetPtrs.end()) // not found at all
{
@@ -369,8 +386,8 @@ void cmGraphVizWriter::WriteDependerConnections(const char* targetName,
std::string myNodeName = this->TargetNamesNodes.find(targetName)->second;
// now search who links against me
- for(std::map<cmStdString, const cmTarget*>::const_iterator dependerIt =
- this->TargetPtrs.begin();
+ for(std::map<std::string, const cmGeneratorTarget*>::const_iterator
+ dependerIt = this->TargetPtrs.begin();
dependerIt != this->TargetPtrs.end();
++dependerIt)
{
@@ -387,17 +404,17 @@ void cmGraphVizWriter::WriteDependerConnections(const char* targetName,
// Now we have a target, check whether it links against targetName.
// If so, draw a connection, and then continue with dependers on that one.
const cmTarget::LinkLibraryVectorType* ll =
- &(dependerIt->second->GetOriginalLinkLibraries());
+ &(dependerIt->second->Target->GetOriginalLinkLibraries());
for (cmTarget::LinkLibraryVectorType::const_iterator llit = ll->begin();
llit != ll->end();
++ llit )
{
- std::string libName = llit->first.c_str();
+ std::string libName = llit->first;
if (libName == targetName)
{
// So this target links against targetName.
- std::map<cmStdString, cmStdString>::const_iterator dependerNodeNameIt =
+ std::map<std::string, std::string>::const_iterator dependerNodeNameIt =
this->TargetNamesNodes.find(dependerIt->first);
if(dependerNodeNameIt != this->TargetNamesNodes.end())
@@ -410,13 +427,13 @@ void cmGraphVizWriter::WriteDependerConnections(const char* targetName,
insertedConnections.end())
{
insertedConnections.insert(connectionName);
- this->WriteNode(dependerIt->first.c_str(), dependerIt->second,
+ this->WriteNode(dependerIt->first, dependerIt->second,
insertedNodes, str);
str << " \"" << dependerNodeNameIt->second << "\" -> \""
<< myNodeName << "\"";
str << " // " <<targetName<< " -> " <<dependerIt->first<<std::endl;
- this->WriteDependerConnections(dependerIt->first.c_str(),
+ this->WriteDependerConnections(dependerIt->first,
insertedNodes, insertedConnections, str);
}
@@ -430,18 +447,18 @@ void cmGraphVizWriter::WriteDependerConnections(const char* targetName,
}
-void cmGraphVizWriter::WriteNode(const char* targetName,
- const cmTarget* target,
+void cmGraphVizWriter::WriteNode(const std::string& targetName,
+ const cmGeneratorTarget* target,
std::set<std::string>& insertedNodes,
cmGeneratedFileStream& str) const
{
if (insertedNodes.find(targetName) == insertedNodes.end())
{
insertedNodes.insert(targetName);
- std::map<cmStdString, cmStdString>::const_iterator nameIt =
+ std::map<std::string, std::string>::const_iterator nameIt =
this->TargetNamesNodes.find(targetName);
- str << " \"" << nameIt->second.c_str() << "\" [ label=\""
+ str << " \"" << nameIt->second << "\" [ label=\""
<< targetName << "\" shape=\"" << getShapeForTarget(target)
<< "\"];" << std::endl;
}
@@ -471,22 +488,21 @@ int cmGraphVizWriter::CollectAllTargets()
lit != this->LocalGenerators.end();
++ lit )
{
- const cmTargets* targets = &((*lit)->GetMakefile()->GetTargets());
- for ( cmTargets::const_iterator tit = targets->begin();
- tit != targets->end();
- ++ tit )
+ std::vector<cmGeneratorTarget*> targets = (*lit)->GetGeneratorTargets();
+ for ( std::vector<cmGeneratorTarget*>::const_iterator it =
+ targets.begin(); it != targets.end(); ++it )
{
- const char* realTargetName = tit->first.c_str();
+ const char* realTargetName = (*it)->GetName().c_str();
if(this->IgnoreThisTarget(realTargetName))
{
// Skip ignored targets
continue;
}
//std::cout << "Found target: " << tit->first.c_str() << std::endl;
- cmOStringStream ostr;
+ std::ostringstream ostr;
ostr << this->GraphNodePrefix << cnt++;
this->TargetNamesNodes[realTargetName] = ostr.str();
- this->TargetPtrs[realTargetName] = &tit->second;
+ this->TargetPtrs[realTargetName] = *it;
}
}
@@ -502,19 +518,18 @@ int cmGraphVizWriter::CollectAllExternalLibs(int cnt)
lit != this->LocalGenerators.end();
++ lit )
{
- const cmTargets* targets = &((*lit)->GetMakefile()->GetTargets());
- for ( cmTargets::const_iterator tit = targets->begin();
- tit != targets->end();
- ++ tit )
+ std::vector<cmGeneratorTarget*> targets = (*lit)->GetGeneratorTargets();
+ for ( std::vector<cmGeneratorTarget*>::const_iterator it =
+ targets.begin(); it != targets.end(); ++it )
{
- const char* realTargetName = tit->first.c_str();
+ const char* realTargetName = (*it)->GetName().c_str();
if (this->IgnoreThisTarget(realTargetName))
{
// Skip ignored targets
continue;
}
const cmTarget::LinkLibraryVectorType* ll =
- &(tit->second.GetOriginalLinkLibraries());
+ &((*it)->Target->GetOriginalLinkLibraries());
for (cmTarget::LinkLibraryVectorType::const_iterator llit = ll->begin();
llit != ll->end();
++ llit )
@@ -526,16 +541,16 @@ int cmGraphVizWriter::CollectAllExternalLibs(int cnt)
continue;
}
- std::map<cmStdString, const cmTarget*>::const_iterator tarIt =
- this->TargetPtrs.find(libName);
+ std::map<std::string, const cmGeneratorTarget*>::const_iterator tarIt
+ = this->TargetPtrs.find(libName);
if ( tarIt == this->TargetPtrs.end() )
{
- cmOStringStream ostr;
+ std::ostringstream ostr;
ostr << this->GraphNodePrefix << cnt++;
this->TargetNamesNodes[libName] = ostr.str();
this->TargetPtrs[libName] = NULL;
- //str << " \"" << ostr.c_str() << "\" [ label=\"" << libName
- //<< "\" shape=\"ellipse\"];" << std::endl;
+ // str << " \"" << ostr.c_str() << "\" [ label=\"" << libName
+ // << "\" shape=\"ellipse\"];" << std::endl;
}
}
}
@@ -544,7 +559,7 @@ int cmGraphVizWriter::CollectAllExternalLibs(int cnt)
}
-bool cmGraphVizWriter::IgnoreThisTarget(const char* name)
+bool cmGraphVizWriter::IgnoreThisTarget(const std::string& name)
{
for(std::vector<cmsys::RegularExpression>::iterator itvIt
= this->TargetsToIgnoreRegex.begin();
@@ -565,18 +580,18 @@ bool cmGraphVizWriter::IgnoreThisTarget(const char* name)
}
-bool cmGraphVizWriter::GenerateForTargetType(cmTarget::TargetType targetType)
+bool cmGraphVizWriter::GenerateForTargetType(cmState::TargetType targetType)
const
{
switch (targetType)
{
- case cmTarget::EXECUTABLE:
+ case cmState::EXECUTABLE:
return this->GenerateForExecutables;
- case cmTarget::STATIC_LIBRARY:
+ case cmState::STATIC_LIBRARY:
return this->GenerateForStaticLibs;
- case cmTarget::SHARED_LIBRARY:
+ case cmState::SHARED_LIBRARY:
return this->GenerateForSharedLibs;
- case cmTarget::MODULE_LIBRARY:
+ case cmState::MODULE_LIBRARY:
return this->GenerateForModuleLibs;
default:
break;
diff --git a/Source/cmGraphVizWriter.h b/Source/cmGraphVizWriter.h
index f784aa0a1..90d31d3be 100644
--- a/Source/cmGraphVizWriter.h
+++ b/Source/cmGraphVizWriter.h
@@ -14,9 +14,9 @@
#include "cmStandardIncludes.h"
#include "cmLocalGenerator.h"
#include "cmGeneratedFileStream.h"
-#include "cmTarget.h"
#include <cmsys/RegularExpression.hxx>
+class cmGeneratorTarget;
/** This class implements writing files for graphviz (dot) for graphs
* representing the dependencies between the targets in the project. */
@@ -44,45 +44,47 @@ protected:
void WriteHeader(cmGeneratedFileStream& str) const;
- void WriteConnections(const char* targetName,
+ void WriteConnections(const std::string& targetName,
std::set<std::string>& insertedNodes,
std::set<std::string>& insertedConnections,
cmGeneratedFileStream& str) const;
- void WriteDependerConnections(const char* targetName,
+ void WriteDependerConnections(const std::string& targetName,
std::set<std::string>& insertedNodes,
std::set<std::string>& insertedConnections,
cmGeneratedFileStream& str) const;
- void WriteNode(const char* targetName, const cmTarget* target,
+ void WriteNode(const std::string& targetName,
+ const cmGeneratorTarget* target,
std::set<std::string>& insertedNodes,
cmGeneratedFileStream& str) const;
void WriteFooter(cmGeneratedFileStream& str) const;
- bool IgnoreThisTarget(const char* name);
+ bool IgnoreThisTarget(const std::string& name);
- bool GenerateForTargetType(cmTarget::TargetType targetType) const;
+ bool GenerateForTargetType(cmState::TargetType targetType) const;
- cmStdString GraphType;
- cmStdString GraphName;
- cmStdString GraphHeader;
- cmStdString GraphNodePrefix;
-
- bool GenerateForExecutables;
- bool GenerateForStaticLibs;
- bool GenerateForSharedLibs;
- bool GenerateForModuleLibs;
- bool GenerateForExternals;
+ std::string GraphType;
+ std::string GraphName;
+ std::string GraphHeader;
+ std::string GraphNodePrefix;
std::vector<cmsys::RegularExpression> TargetsToIgnoreRegex;
const std::vector<cmLocalGenerator*>& LocalGenerators;
- std::map<cmStdString, const cmTarget*> TargetPtrs;
+ std::map<std::string, const cmGeneratorTarget*> TargetPtrs;
// maps from the actual target names to node names in dot:
- std::map<cmStdString, cmStdString> TargetNamesNodes;
+ std::map<std::string, std::string> TargetNamesNodes;
+ bool GenerateForExecutables;
+ bool GenerateForStaticLibs;
+ bool GenerateForSharedLibs;
+ bool GenerateForModuleLibs;
+ bool GenerateForExternals;
+ bool GeneratePerTarget;
+ bool GenerateDependers;
bool HaveTargetsAndLibs;
};
diff --git a/Source/cmHexFileConverter.cxx b/Source/cmHexFileConverter.cxx
index a540825ff..6ea597ea5 100644
--- a/Source/cmHexFileConverter.cxx
+++ b/Source/cmHexFileConverter.cxx
@@ -166,7 +166,7 @@ cmHexFileConverter::FileType cmHexFileConverter::DetermineFileType(
const char* inFileName)
{
char buf[1024];
- FILE* inFile = fopen(inFileName, "rb");
+ FILE* inFile = cmsys::SystemTools::Fopen(inFileName, "rb");
if (inFile == 0)
{
return Binary;
@@ -223,8 +223,8 @@ bool cmHexFileConverter::TryConvert(const char* inFileName,
}
// try to open the file
- FILE* inFile = fopen(inFileName, "rb");
- FILE* outFile = fopen(outFileName, "wb");
+ FILE* inFile = cmsys::SystemTools::Fopen(inFileName, "rb");
+ FILE* outFile = cmsys::SystemTools::Fopen(outFileName, "wb");
if ((inFile == 0) || (outFile == 0))
{
if (inFile != 0)
diff --git a/Source/cmIDEFlagTable.h b/Source/cmIDEFlagTable.h
index e372c0a15..adc77632b 100644
--- a/Source/cmIDEFlagTable.h
+++ b/Source/cmIDEFlagTable.h
@@ -31,6 +31,8 @@ struct cmIDEFlagTable
// old value with semicolons (e.g.
// /NODEFAULTLIB: =>
// IgnoreDefaultLibraryNames)
+ UserFollowing = (1<<5), // expect value in following argument
+ CaseInsensitive = (1<<6), // flag may be any case
UserValueIgnored = UserValue | UserIgnored,
UserValueRequired = UserValue | UserRequired
diff --git a/Source/cmIDEOptions.cxx b/Source/cmIDEOptions.cxx
index 34a9c7c78..509602fbd 100644
--- a/Source/cmIDEOptions.cxx
+++ b/Source/cmIDEOptions.cxx
@@ -13,12 +13,15 @@
#include "cmSystemTools.h"
+#include <cmsys/String.h>
+
//----------------------------------------------------------------------------
cmIDEOptions::cmIDEOptions()
{
this->DoingDefine = false;
this->AllowDefine = true;
this->AllowSlash = false;
+ this->DoingFollowing = 0;
for(int i=0; i < FlagTableCount; ++i)
{
this->FlagTable[i] = 0;
@@ -41,6 +44,14 @@ void cmIDEOptions::HandleFlag(const char* flag)
return;
}
+ // If the last option expected a following value, this is it.
+ if(this->DoingFollowing)
+ {
+ this->FlagMapUpdate(this->DoingFollowing, flag);
+ this->DoingFollowing = 0;
+ return;
+ }
+
// Look for known arguments.
if(flag[0] == '-' || (this->AllowSlash && flag[0] == '/'))
{
@@ -95,44 +106,30 @@ bool cmIDEOptions::CheckFlagTable(cmIDEFlagTable const* table,
// the entry specifies UserRequired we must match only if a
// non-empty value is given.
int n = static_cast<int>(strlen(entry->commandFlag));
- if(strncmp(flag+1, entry->commandFlag, n) == 0 &&
+ if((strncmp(flag+1, entry->commandFlag, n) == 0 ||
+ (entry->special & cmIDEFlagTable::CaseInsensitive &&
+ cmsysString_strncasecmp(flag+1, entry->commandFlag, n))) &&
(!(entry->special & cmIDEFlagTable::UserRequired) ||
static_cast<int>(strlen(flag+1)) > n))
{
- if(entry->special & cmIDEFlagTable::UserIgnored)
- {
- // Ignore the user-specified value.
- this->FlagMap[entry->IDEName] = entry->value;
- }
- else if(entry->special & cmIDEFlagTable::SemicolonAppendable)
- {
- const char *new_value = flag+1+n;
-
- std::map<cmStdString,cmStdString>::iterator itr;
- itr = this->FlagMap.find(entry->IDEName);
- if(itr != this->FlagMap.end())
- {
- // Append to old value (if present) with semicolons;
- itr->second += ";";
- itr->second += new_value;
- }
- else
- {
- this->FlagMap[entry->IDEName] = new_value;
- }
- }
- else
- {
- // Use the user-specified value.
- this->FlagMap[entry->IDEName] = flag+1+n;
- }
+ this->FlagMapUpdate(entry, flag+n+1);
entry_found = true;
}
}
- else if(strcmp(flag+1, entry->commandFlag) == 0)
+ else if(strcmp(flag+1, entry->commandFlag) == 0 ||
+ (entry->special & cmIDEFlagTable::CaseInsensitive &&
+ cmsysString_strcasecmp(flag+1, entry->commandFlag) == 0))
{
- // This flag table entry provides a fixed value.
- this->FlagMap[entry->IDEName] = entry->value;
+ if(entry->special & cmIDEFlagTable::UserFollowing)
+ {
+ // This flag expects a value in the following argument.
+ this->DoingFollowing = entry;
+ }
+ else
+ {
+ // This flag table entry provides a fixed value.
+ this->FlagMap[entry->IDEName] = entry->value;
+ }
entry_found = true;
}
@@ -151,6 +148,26 @@ bool cmIDEOptions::CheckFlagTable(cmIDEFlagTable const* table,
}
//----------------------------------------------------------------------------
+void cmIDEOptions::FlagMapUpdate(cmIDEFlagTable const* entry,
+ const char* new_value)
+{
+ if(entry->special & cmIDEFlagTable::UserIgnored)
+ {
+ // Ignore the user-specified value.
+ this->FlagMap[entry->IDEName] = entry->value;
+ }
+ else if(entry->special & cmIDEFlagTable::SemicolonAppendable)
+ {
+ this->FlagMap[entry->IDEName].push_back(new_value);
+ }
+ else
+ {
+ // Use the user-specified value.
+ this->FlagMap[entry->IDEName] = new_value;
+ }
+}
+
+//----------------------------------------------------------------------------
void cmIDEOptions::AddDefine(const std::string& def)
{
this->Defines.push_back(def);
@@ -178,18 +195,47 @@ void cmIDEOptions::AddFlag(const char* flag, const char* value)
}
//----------------------------------------------------------------------------
+void cmIDEOptions::AddFlag(const char* flag,
+ std::vector<std::string> const& value)
+{
+ this->FlagMap[flag] = value;
+}
+
+//----------------------------------------------------------------------------
+void cmIDEOptions::AppendFlag(std::string const& flag,
+ std::string const& value)
+{
+ this->FlagMap[flag].push_back(value);
+}
+
+//----------------------------------------------------------------------------
+void cmIDEOptions::AppendFlag(std::string const& flag,
+ std::vector<std::string> const& value)
+{
+ FlagValue& fv = this->FlagMap[flag];
+ std::copy(value.begin(), value.end(), std::back_inserter(fv));
+}
+
+//----------------------------------------------------------------------------
void cmIDEOptions::RemoveFlag(const char* flag)
{
this->FlagMap.erase(flag);
}
//----------------------------------------------------------------------------
+bool cmIDEOptions::HasFlag(std::string const& flag) const
+{
+ return this->FlagMap.find(flag) != this->FlagMap.end();
+}
+
+//----------------------------------------------------------------------------
const char* cmIDEOptions::GetFlag(const char* flag)
{
- std::map<cmStdString, cmStdString>::iterator i = this->FlagMap.find(flag);
- if(i != this->FlagMap.end())
+ // This method works only for single-valued flags!
+ std::map<std::string, FlagValue>::iterator i = this->FlagMap.find(flag);
+ if(i != this->FlagMap.end() && i->second.size() == 1)
{
- return i->second.c_str();
+ return i->second[0].c_str();
}
return 0;
}
diff --git a/Source/cmIDEOptions.h b/Source/cmIDEOptions.h
index e78af3ee4..73860164d 100644
--- a/Source/cmIDEOptions.h
+++ b/Source/cmIDEOptions.h
@@ -29,7 +29,12 @@ public:
void AddDefines(const char* defines);
void AddDefines(const std::vector<std::string> &defines);
void AddFlag(const char* flag, const char* value);
+ void AddFlag(const char* flag, std::vector<std::string> const& value);
+ void AppendFlag(std::string const& flag, std::string const& value);
+ void AppendFlag(std::string const& flag,
+ std::vector<std::string> const& value);
void RemoveFlag(const char* flag);
+ bool HasFlag(std::string const& flag) const;
const char* GetFlag(const char* flag);
protected:
@@ -40,22 +45,40 @@ protected:
// Then parse the command line flags specified in CMAKE_CXX_FLAGS
// and CMAKE_C_FLAGS
// and overwrite or add new values to this map
- std::map<cmStdString, cmStdString> FlagMap;
+ class FlagValue: public std::vector<std::string>
+ {
+ typedef std::vector<std::string> derived;
+ public:
+ FlagValue& operator=(std::string const& r)
+ {
+ this->resize(1);
+ this->operator[](0) = r;
+ return *this;
+ }
+ FlagValue& operator=(std::vector<std::string> const& r)
+ {
+ this->derived::operator=(r);
+ return *this;
+ }
+ };
+ std::map<std::string, FlagValue > FlagMap;
// Preprocessor definitions.
std::vector<std::string> Defines;
// Unrecognized flags that get no special handling.
- cmStdString FlagString;
+ std::string FlagString;
bool DoingDefine;
bool AllowDefine;
bool AllowSlash;
+ cmIDEFlagTable const* DoingFollowing;
enum { FlagTableCount = 16 };
cmIDEFlagTable const* FlagTable[FlagTableCount];
void HandleFlag(const char* flag);
bool CheckFlagTable(cmIDEFlagTable const* table, const char* flag,
bool& flag_handled);
+ void FlagMapUpdate(cmIDEFlagTable const* entry, const char* new_value);
virtual void StoreUnknownFlag(const char* flag) = 0;
};
diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx
index 57cec5bbb..5964ef1ee 100644
--- a/Source/cmIfCommand.cxx
+++ b/Source/cmIfCommand.cxx
@@ -11,6 +11,9 @@
============================================================================*/
#include "cmIfCommand.h"
#include "cmStringCommand.h"
+#include "cmOutputConverter.h"
+
+#include "cmConditionEvaluator.h"
#include <stdlib.h> // required for atof
#include <list>
@@ -18,15 +21,14 @@
static std::string cmIfCommandError(
- cmMakefile* mf, std::vector<std::string> const& args)
+ std::vector<cmExpandedCommandArgument> const& args)
{
- cmLocalGenerator* lg = mf->GetLocalGenerator();
std::string err = "given arguments:\n ";
- for(std::vector<std::string>::const_iterator i = args.begin();
+ for(std::vector<cmExpandedCommandArgument>::const_iterator i = args.begin();
i != args.end(); ++i)
{
err += " ";
- err += lg->EscapeForCMake(i->c_str());
+ err += cmOutputConverter::EscapeForCMake(i->GetValue());
}
err += "\n";
return err;
@@ -43,7 +45,7 @@ IsFunctionBlocked(const cmListFileFunction& lff,
{
this->ScopeDepth++;
}
- if (!cmSystemTools::Strucmp(lff.Name.c_str(),"endif"))
+ else if (!cmSystemTools::Strucmp(lff.Name.c_str(),"endif"))
{
this->ScopeDepth--;
// if this is the endif for this if statement, then start executing
@@ -91,10 +93,6 @@ IsFunctionBlocked(const cmListFileFunction& lff,
}
else
{
- // Place this call on the call stack.
- cmMakefileCall stack_manager(&mf, this->Functions[c], status);
- static_cast<void>(stack_manager);
-
// if trace is enabled, print the evaluated "elseif" statement
if(mf.GetCMakeInstance()->GetTrace())
{
@@ -103,20 +101,30 @@ IsFunctionBlocked(const cmListFileFunction& lff,
std::string errorString;
- std::vector<std::string> expandedArguments;
+ std::vector<cmExpandedCommandArgument> expandedArguments;
mf.ExpandArguments(this->Functions[c].Arguments,
expandedArguments);
cmake::MessageType messType;
- bool isTrue =
- cmIfCommand::IsTrue(expandedArguments, errorString,
- &mf, messType);
- if (errorString.size())
+ cmListFileContext conditionContext =
+ cmConditionEvaluator::GetConditionContext(
+ &mf, this->Functions[c],
+ this->GetStartingContext().FilePath);
+
+ cmConditionEvaluator conditionEvaluator(
+ mf, conditionContext,
+ mf.GetBacktrace(this->Functions[c]));
+
+ bool isTrue = conditionEvaluator.IsTrue(
+ expandedArguments, errorString, messType);
+
+ if (!errorString.empty())
{
- std::string err = cmIfCommandError(&mf, expandedArguments);
+ std::string err = cmIfCommandError(expandedArguments);
err += errorString;
- mf.IssueMessage(messType, err);
+ cmListFileBacktrace bt = mf.GetBacktrace(this->Functions[c]);
+ mf.GetCMakeInstance()->IssueMessage(messType, err, bt);
if (messType == cmake::FATAL_ERROR)
{
cmSystemTools::SetFatalErrorOccured();
@@ -147,6 +155,11 @@ IsFunctionBlocked(const cmListFileFunction& lff,
inStatus.SetBreakInvoked(true);
return true;
}
+ if (status.GetContinueInvoked())
+ {
+ inStatus.SetContinueInvoked(true);
+ return true;
+ }
}
}
return true;
@@ -168,7 +181,7 @@ bool cmIfFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
{
// if the endif has arguments, then make sure
// they match the arguments of the matching if
- if (lff.Arguments.size() == 0 ||
+ if (lff.Arguments.empty() ||
lff.Arguments == this->Args)
{
return true;
@@ -185,21 +198,32 @@ bool cmIfCommand
{
std::string errorString;
- std::vector<std::string> expandedArguments;
+ std::vector<cmExpandedCommandArgument> expandedArguments;
this->Makefile->ExpandArguments(args, expandedArguments);
cmake::MessageType status;
- bool isTrue =
- cmIfCommand::IsTrue(expandedArguments,errorString,
- this->Makefile, status);
- if (errorString.size())
+ cmListFileContext execContext = this->Makefile->GetExecutionContext();
+
+ cmCommandContext commandContext;
+ commandContext.Line = execContext.Line;
+ commandContext.Name = execContext.Name;
+
+ cmConditionEvaluator conditionEvaluator(
+ *(this->Makefile), cmConditionEvaluator::GetConditionContext(
+ this->Makefile, commandContext, execContext.FilePath),
+ this->Makefile->GetBacktrace());
+
+ bool isTrue = conditionEvaluator.IsTrue(
+ expandedArguments, errorString, status);
+
+ if (!errorString.empty())
{
- std::string err = cmIfCommandError(this->Makefile, expandedArguments);
+ std::string err = cmIfCommandError(expandedArguments);
err += errorString;
if (status == cmake::FATAL_ERROR)
{
- this->SetError(err.c_str());
+ this->SetError(err);
cmSystemTools::SetFatalErrorOccured();
return false;
}
@@ -222,698 +246,3 @@ bool cmIfCommand
return true;
}
-
-namespace
-{
- //=========================================================================
- bool GetBooleanValue(std::string& arg, cmMakefile* mf)
- {
- // Check basic constants.
- if (arg == "0")
- {
- return false;
- }
- if (arg == "1")
- {
- return true;
- }
-
- // Check named constants.
- if (cmSystemTools::IsOn(arg.c_str()))
- {
- return true;
- }
- if (cmSystemTools::IsOff(arg.c_str()))
- {
- return false;
- }
-
- // Check for numbers.
- if(!arg.empty())
- {
- char* end;
- double d = strtod(arg.c_str(), &end);
- if(*end == '\0')
- {
- // The whole string is a number. Use C conversion to bool.
- return d? true:false;
- }
- }
-
- // Check definition.
- const char* def = mf->GetDefinition(arg.c_str());
- return !cmSystemTools::IsOff(def);
- }
-
- //=========================================================================
- // Boolean value behavior from CMake 2.6.4 and below.
- bool GetBooleanValueOld(std::string const& arg, cmMakefile* mf, bool one)
- {
- if(one)
- {
- // Old IsTrue behavior for single argument.
- if(arg == "0")
- { return false; }
- else if(arg == "1")
- { return true; }
- else
- { return !cmSystemTools::IsOff(mf->GetDefinition(arg.c_str())); }
- }
- else
- {
- // Old GetVariableOrNumber behavior.
- const char* def = mf->GetDefinition(arg.c_str());
- if(!def && atoi(arg.c_str()))
- {
- def = arg.c_str();
- }
- return !cmSystemTools::IsOff(def);
- }
- }
-
- //=========================================================================
- // returns the resulting boolean value
- bool GetBooleanValueWithAutoDereference(
- std::string &newArg,
- cmMakefile *makefile,
- std::string &errorString,
- cmPolicies::PolicyStatus Policy12Status,
- cmake::MessageType &status,
- bool oneArg = false)
- {
- // Use the policy if it is set.
- if (Policy12Status == cmPolicies::NEW)
- {
- return GetBooleanValue(newArg, makefile);
- }
- else if (Policy12Status == cmPolicies::OLD)
- {
- return GetBooleanValueOld(newArg, makefile, oneArg);
- }
-
- // Check policy only if old and new results differ.
- bool newResult = GetBooleanValue(newArg, makefile);
- bool oldResult = GetBooleanValueOld(newArg, makefile, oneArg);
- if(newResult != oldResult)
- {
- switch(Policy12Status)
- {
- case cmPolicies::WARN:
- {
- cmPolicies* policies = makefile->GetPolicies();
- errorString = "An argument named \"" + newArg
- + "\" appears in a conditional statement. "
- + policies->GetPolicyWarning(cmPolicies::CMP0012);
- status = cmake::AUTHOR_WARNING;
- }
- case cmPolicies::OLD:
- return oldResult;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- {
- cmPolicies* policies = makefile->GetPolicies();
- errorString = "An argument named \"" + newArg
- + "\" appears in a conditional statement. "
- + policies->GetRequiredPolicyError(cmPolicies::CMP0012);
- status = cmake::FATAL_ERROR;
- }
- case cmPolicies::NEW:
- break;
- }
- }
- return newResult;
- }
-
- //=========================================================================
- void IncrementArguments(std::list<std::string> &newArgs,
- std::list<std::string>::iterator &argP1,
- std::list<std::string>::iterator &argP2)
- {
- if (argP1 != newArgs.end())
- {
- argP1++;
- argP2 = argP1;
- if (argP1 != newArgs.end())
- {
- argP2++;
- }
- }
- }
-
- //=========================================================================
- // helper function to reduce code duplication
- void HandlePredicate(bool value, int &reducible,
- std::list<std::string>::iterator &arg,
- std::list<std::string> &newArgs,
- std::list<std::string>::iterator &argP1,
- std::list<std::string>::iterator &argP2)
- {
- if(value)
- {
- *arg = "1";
- }
- else
- {
- *arg = "0";
- }
- newArgs.erase(argP1);
- argP1 = arg;
- IncrementArguments(newArgs,argP1,argP2);
- reducible = 1;
- }
-
- //=========================================================================
- // helper function to reduce code duplication
- void HandleBinaryOp(bool value, int &reducible,
- std::list<std::string>::iterator &arg,
- std::list<std::string> &newArgs,
- std::list<std::string>::iterator &argP1,
- std::list<std::string>::iterator &argP2)
- {
- if(value)
- {
- *arg = "1";
- }
- else
- {
- *arg = "0";
- }
- newArgs.erase(argP2);
- newArgs.erase(argP1);
- argP1 = arg;
- IncrementArguments(newArgs,argP1,argP2);
- reducible = 1;
- }
-
- //=========================================================================
- // level 0 processes parenthetical expressions
- bool HandleLevel0(std::list<std::string> &newArgs,
- cmMakefile *makefile,
- std::string &errorString,
- cmake::MessageType &status)
- {
- int reducible;
- do
- {
- reducible = 0;
- std::list<std::string>::iterator arg = newArgs.begin();
- while (arg != newArgs.end())
- {
- if (*arg == "(")
- {
- // search for the closing paren for this opening one
- std::list<std::string>::iterator argClose;
- argClose = arg;
- argClose++;
- unsigned int depth = 1;
- while (argClose != newArgs.end() && depth)
- {
- if (*argClose == "(")
- {
- depth++;
- }
- if (*argClose == ")")
- {
- depth--;
- }
- argClose++;
- }
- if (depth)
- {
- errorString = "mismatched parenthesis in condition";
- status = cmake::FATAL_ERROR;
- return false;
- }
- // store the reduced args in this vector
- std::vector<std::string> newArgs2;
-
- // copy to the list structure
- std::list<std::string>::iterator argP1 = arg;
- argP1++;
- for(; argP1 != argClose; argP1++)
- {
- newArgs2.push_back(*argP1);
- }
- newArgs2.pop_back();
- // now recursively invoke IsTrue to handle the values inside the
- // parenthetical expression
- bool value =
- cmIfCommand::IsTrue(newArgs2, errorString, makefile, status);
- if(value)
- {
- *arg = "1";
- }
- else
- {
- *arg = "0";
- }
- argP1 = arg;
- argP1++;
- // remove the now evaluated parenthetical expression
- newArgs.erase(argP1,argClose);
- }
- ++arg;
- }
- }
- while (reducible);
- return true;
- }
-
- //=========================================================================
- // level one handles most predicates except for NOT
- bool HandleLevel1(std::list<std::string> &newArgs,
- cmMakefile *makefile,
- std::string &, cmake::MessageType &)
- {
- int reducible;
- do
- {
- reducible = 0;
- std::list<std::string>::iterator arg = newArgs.begin();
- std::list<std::string>::iterator argP1;
- std::list<std::string>::iterator argP2;
- while (arg != newArgs.end())
- {
- argP1 = arg;
- IncrementArguments(newArgs,argP1,argP2);
- // does a file exist
- if (*arg == "EXISTS" && argP1 != newArgs.end())
- {
- HandlePredicate(
- cmSystemTools::FileExists((argP1)->c_str()),
- reducible, arg, newArgs, argP1, argP2);
- }
- // does a directory with this name exist
- if (*arg == "IS_DIRECTORY" && argP1 != newArgs.end())
- {
- HandlePredicate(
- cmSystemTools::FileIsDirectory((argP1)->c_str()),
- reducible, arg, newArgs, argP1, argP2);
- }
- // does a symlink with this name exist
- if (*arg == "IS_SYMLINK" && argP1 != newArgs.end())
- {
- HandlePredicate(
- cmSystemTools::FileIsSymlink((argP1)->c_str()),
- reducible, arg, newArgs, argP1, argP2);
- }
- // is the given path an absolute path ?
- if (*arg == "IS_ABSOLUTE" && argP1 != newArgs.end())
- {
- HandlePredicate(
- cmSystemTools::FileIsFullPath((argP1)->c_str()),
- reducible, arg, newArgs, argP1, argP2);
- }
- // does a command exist
- if (*arg == "COMMAND" && argP1 != newArgs.end())
- {
- HandlePredicate(
- makefile->CommandExists((argP1)->c_str()),
- reducible, arg, newArgs, argP1, argP2);
- }
- // does a policy exist
- if (*arg == "POLICY" && argP1 != newArgs.end())
- {
- cmPolicies::PolicyID pid;
- HandlePredicate(
- makefile->GetPolicies()->GetPolicyID((argP1)->c_str(), pid),
- reducible, arg, newArgs, argP1, argP2);
- }
- // does a target exist
- if (*arg == "TARGET" && argP1 != newArgs.end())
- {
- HandlePredicate(
- makefile->FindTargetToUse((argP1)->c_str())? true:false,
- reducible, arg, newArgs, argP1, argP2);
- }
- // is a variable defined
- if (*arg == "DEFINED" && argP1 != newArgs.end())
- {
- size_t argP1len = argP1->size();
- bool bdef = false;
- if(argP1len > 4 && argP1->substr(0, 4) == "ENV{" &&
- argP1->operator[](argP1len-1) == '}')
- {
- std::string env = argP1->substr(4, argP1len-5);
- bdef = cmSystemTools::GetEnv(env.c_str())?true:false;
- }
- else
- {
- bdef = makefile->IsDefinitionSet((argP1)->c_str());
- }
- HandlePredicate(bdef, reducible, arg, newArgs, argP1, argP2);
- }
- ++arg;
- }
- }
- while (reducible);
- return true;
- }
-
- //=========================================================================
- // level two handles most binary operations except for AND OR
- bool HandleLevel2(std::list<std::string> &newArgs,
- cmMakefile *makefile,
- std::string &errorString,
- cmake::MessageType &status)
- {
- int reducible;
- const char *def;
- const char *def2;
- do
- {
- reducible = 0;
- std::list<std::string>::iterator arg = newArgs.begin();
- std::list<std::string>::iterator argP1;
- std::list<std::string>::iterator argP2;
- while (arg != newArgs.end())
- {
- argP1 = arg;
- IncrementArguments(newArgs,argP1,argP2);
- if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
- *(argP1) == "MATCHES")
- {
- def = cmIfCommand::GetVariableOrString(arg->c_str(), makefile);
- const char* rex = (argP2)->c_str();
- cmStringCommand::ClearMatches(makefile);
- cmsys::RegularExpression regEntry;
- if ( !regEntry.compile(rex) )
- {
- cmOStringStream error;
- error << "Regular expression \"" << rex << "\" cannot compile";
- errorString = error.str();
- status = cmake::FATAL_ERROR;
- return false;
- }
- if (regEntry.find(def))
- {
- cmStringCommand::StoreMatches(makefile, regEntry);
- *arg = "1";
- }
- else
- {
- *arg = "0";
- }
- newArgs.erase(argP2);
- newArgs.erase(argP1);
- argP1 = arg;
- IncrementArguments(newArgs,argP1,argP2);
- reducible = 1;
- }
-
- if (argP1 != newArgs.end() && *arg == "MATCHES")
- {
- *arg = "0";
- newArgs.erase(argP1);
- argP1 = arg;
- IncrementArguments(newArgs,argP1,argP2);
- reducible = 1;
- }
-
- if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
- (*(argP1) == "LESS" || *(argP1) == "GREATER" ||
- *(argP1) == "EQUAL"))
- {
- def = cmIfCommand::GetVariableOrString(arg->c_str(), makefile);
- def2 = cmIfCommand::GetVariableOrString((argP2)->c_str(), makefile);
- double lhs;
- double rhs;
- bool result;
- if(sscanf(def, "%lg", &lhs) != 1 ||
- sscanf(def2, "%lg", &rhs) != 1)
- {
- result = false;
- }
- else if (*(argP1) == "LESS")
- {
- result = (lhs < rhs);
- }
- else if (*(argP1) == "GREATER")
- {
- result = (lhs > rhs);
- }
- else
- {
- result = (lhs == rhs);
- }
- HandleBinaryOp(result,
- reducible, arg, newArgs, argP1, argP2);
- }
-
- if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
- (*(argP1) == "STRLESS" ||
- *(argP1) == "STREQUAL" ||
- *(argP1) == "STRGREATER"))
- {
- def = cmIfCommand::GetVariableOrString(arg->c_str(), makefile);
- def2 = cmIfCommand::GetVariableOrString((argP2)->c_str(), makefile);
- int val = strcmp(def,def2);
- bool result;
- if (*(argP1) == "STRLESS")
- {
- result = (val < 0);
- }
- else if (*(argP1) == "STRGREATER")
- {
- result = (val > 0);
- }
- else // strequal
- {
- result = (val == 0);
- }
- HandleBinaryOp(result,
- reducible, arg, newArgs, argP1, argP2);
- }
-
- if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
- (*(argP1) == "VERSION_LESS" || *(argP1) == "VERSION_GREATER" ||
- *(argP1) == "VERSION_EQUAL"))
- {
- def = cmIfCommand::GetVariableOrString(arg->c_str(), makefile);
- def2 = cmIfCommand::GetVariableOrString((argP2)->c_str(), makefile);
- cmSystemTools::CompareOp op = cmSystemTools::OP_EQUAL;
- if(*argP1 == "VERSION_LESS")
- {
- op = cmSystemTools::OP_LESS;
- }
- else if(*argP1 == "VERSION_GREATER")
- {
- op = cmSystemTools::OP_GREATER;
- }
- bool result = cmSystemTools::VersionCompare(op, def, def2);
- HandleBinaryOp(result,
- reducible, arg, newArgs, argP1, argP2);
- }
-
- // is file A newer than file B
- if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
- *(argP1) == "IS_NEWER_THAN")
- {
- int fileIsNewer=0;
- bool success=cmSystemTools::FileTimeCompare(arg->c_str(),
- (argP2)->c_str(),
- &fileIsNewer);
- HandleBinaryOp(
- (success==false || fileIsNewer==1 || fileIsNewer==0),
- reducible, arg, newArgs, argP1, argP2);
- }
-
- ++arg;
- }
- }
- while (reducible);
- return true;
- }
-
- //=========================================================================
- // level 3 handles NOT
- bool HandleLevel3(std::list<std::string> &newArgs,
- cmMakefile *makefile,
- std::string &errorString,
- cmPolicies::PolicyStatus Policy12Status,
- cmake::MessageType &status)
- {
- int reducible;
- do
- {
- reducible = 0;
- std::list<std::string>::iterator arg = newArgs.begin();
- std::list<std::string>::iterator argP1;
- std::list<std::string>::iterator argP2;
- while (arg != newArgs.end())
- {
- argP1 = arg;
- IncrementArguments(newArgs,argP1,argP2);
- if (argP1 != newArgs.end() && *arg == "NOT")
- {
- bool rhs = GetBooleanValueWithAutoDereference(*argP1, makefile,
- errorString,
- Policy12Status,
- status);
- HandlePredicate(!rhs, reducible, arg, newArgs, argP1, argP2);
- }
- ++arg;
- }
- }
- while (reducible);
- return true;
- }
-
- //=========================================================================
- // level 4 handles AND OR
- bool HandleLevel4(std::list<std::string> &newArgs,
- cmMakefile *makefile,
- std::string &errorString,
- cmPolicies::PolicyStatus Policy12Status,
- cmake::MessageType &status)
- {
- int reducible;
- bool lhs;
- bool rhs;
- do
- {
- reducible = 0;
- std::list<std::string>::iterator arg = newArgs.begin();
- std::list<std::string>::iterator argP1;
- std::list<std::string>::iterator argP2;
- while (arg != newArgs.end())
- {
- argP1 = arg;
- IncrementArguments(newArgs,argP1,argP2);
- if (argP1 != newArgs.end() && *(argP1) == "AND" &&
- argP2 != newArgs.end())
- {
- lhs = GetBooleanValueWithAutoDereference(*arg, makefile,
- errorString,
- Policy12Status,
- status);
- rhs = GetBooleanValueWithAutoDereference(*argP2, makefile,
- errorString,
- Policy12Status,
- status);
- HandleBinaryOp((lhs && rhs),
- reducible, arg, newArgs, argP1, argP2);
- }
-
- if (argP1 != newArgs.end() && *(argP1) == "OR" &&
- argP2 != newArgs.end())
- {
- lhs = GetBooleanValueWithAutoDereference(*arg, makefile,
- errorString,
- Policy12Status,
- status);
- rhs = GetBooleanValueWithAutoDereference(*argP2, makefile,
- errorString,
- Policy12Status,
- status);
- HandleBinaryOp((lhs || rhs),
- reducible, arg, newArgs, argP1, argP2);
- }
- ++arg;
- }
- }
- while (reducible);
- return true;
- }
-}
-
-
-//=========================================================================
-// order of operations,
-// 1. ( ) -- parenthetical groups
-// 2. IS_DIRECTORY EXISTS COMMAND DEFINED etc predicates
-// 3. MATCHES LESS GREATER EQUAL STRLESS STRGREATER STREQUAL etc binary ops
-// 4. NOT
-// 5. AND OR
-//
-// There is an issue on whether the arguments should be values of references,
-// for example IF (FOO AND BAR) should that compare the strings FOO and BAR
-// or should it really do IF (${FOO} AND ${BAR}) Currently IS_DIRECTORY
-// EXISTS COMMAND and DEFINED all take values. EQUAL, LESS and GREATER can
-// take numeric values or variable names. STRLESS and STRGREATER take
-// variable names but if the variable name is not found it will use the name
-// directly. AND OR take variables or the values 0 or 1.
-
-
-bool cmIfCommand::IsTrue(const std::vector<std::string> &args,
- std::string &errorString, cmMakefile *makefile,
- cmake::MessageType &status)
-{
- errorString = "";
-
- // handle empty invocation
- if (args.size() < 1)
- {
- return false;
- }
-
- // store the reduced args in this vector
- std::list<std::string> newArgs;
-
- // copy to the list structure
- for(unsigned int i = 0; i < args.size(); ++i)
- {
- newArgs.push_back(args[i]);
- }
-
- // now loop through the arguments and see if we can reduce any of them
- // we do this multiple times. Once for each level of precedence
- // parens
- if (!HandleLevel0(newArgs, makefile, errorString, status))
- {
- return false;
- }
- //predicates
- if (!HandleLevel1(newArgs, makefile, errorString, status))
- {
- return false;
- }
- // binary ops
- if (!HandleLevel2(newArgs, makefile, errorString, status))
- {
- return false;
- }
-
- // used to store the value of policy CMP0012 for performance
- cmPolicies::PolicyStatus Policy12Status =
- makefile->GetPolicyStatus(cmPolicies::CMP0012);
-
- // NOT
- if (!HandleLevel3(newArgs, makefile, errorString,
- Policy12Status, status))
- {
- return false;
- }
- // AND OR
- if (!HandleLevel4(newArgs, makefile, errorString,
- Policy12Status, status))
- {
- return false;
- }
-
- // now at the end there should only be one argument left
- if (newArgs.size() != 1)
- {
- errorString = "Unknown arguments specified";
- status = cmake::FATAL_ERROR;
- return false;
- }
-
- return GetBooleanValueWithAutoDereference(*(newArgs.begin()),
- makefile,
- errorString,
- Policy12Status,
- status, true);
-}
-
-//=========================================================================
-const char* cmIfCommand::GetVariableOrString(const char* str,
- const cmMakefile* mf)
-{
- const char* def = mf->GetDefinition(str);
- if(!def)
- {
- def = str;
- }
- return def;
-}
diff --git a/Source/cmIfCommand.h b/Source/cmIfCommand.h
index f794b78b8..689efce65 100644
--- a/Source/cmIfCommand.h
+++ b/Source/cmIfCommand.h
@@ -58,206 +58,21 @@ public:
* the CMakeLists.txt file.
*/
virtual bool InitialPass(std::vector<std::string> const&,
- cmExecutionStatus &) { return false;};
+ cmExecutionStatus &) { return false;}
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "if";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Conditionally execute a group of commands.";
- }
+ virtual std::string GetName() const { return "if";}
/**
* This determines if the command is invoked when in script mode.
*/
virtual bool IsScriptable() const { return true; }
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " if(expression)\n"
- " # then section.\n"
- " COMMAND1(ARGS ...)\n"
- " COMMAND2(ARGS ...)\n"
- " ...\n"
- " elseif(expression2)\n"
- " # elseif section.\n"
- " COMMAND1(ARGS ...)\n"
- " COMMAND2(ARGS ...)\n"
- " ...\n"
- " else(expression)\n"
- " # else section.\n"
- " COMMAND1(ARGS ...)\n"
- " COMMAND2(ARGS ...)\n"
- " ...\n"
- " endif(expression)\n"
- "Evaluates the given expression. If the result is true, the commands "
- "in the THEN section are invoked. Otherwise, the commands in the "
- "else section are invoked. The elseif and else sections are "
- "optional. You may have multiple elseif clauses. Note that "
- "the expression in the else and endif clause is optional. Long "
- "expressions can be used and there is a traditional order of "
- "precedence. "
- "Parenthetical expressions are evaluated first followed by unary "
- "operators such as EXISTS, COMMAND, and DEFINED. "
- "Then any EQUAL, LESS, GREATER, STRLESS, STRGREATER, STREQUAL, MATCHES "
- "will be evaluated. Then NOT operators and finally AND, OR operators "
- "will be evaluated. Possible expressions are:\n"
- " if(<constant>)\n"
- "True if the constant is 1, ON, YES, TRUE, Y, or a non-zero number. "
- "False if the constant is 0, OFF, NO, FALSE, N, IGNORE, NOTFOUND, '', "
- "or ends in the suffix '-NOTFOUND'. "
- "Named boolean constants are case-insensitive. "
- "If the argument is not one of these constants, "
- "it is treated as a variable:"
- "\n"
- " if(<variable>)\n"
- "True if the variable is defined to a value that is not a false "
- "constant. False otherwise. "
- "(Note macro arguments are not variables.)"
- "\n"
- " if(NOT <expression>)\n"
- "True if the expression is not true."
- "\n"
- " if(<expr1> AND <expr2>)\n"
- "True if both expressions would be considered true individually."
- "\n"
- " if(<expr1> OR <expr2>)\n"
- "True if either expression would be considered true individually."
- "\n"
- " if(COMMAND command-name)\n"
- "True if the given name is a command, macro or function that can be "
- "invoked.\n"
- " if(POLICY policy-id)\n"
- "True if the given name is an existing policy "
- "(of the form CMP<NNNN>).\n"
- " if(TARGET target-name)\n"
- "True if the given name is an existing target, built or imported.\n"
- " if(EXISTS file-name)\n"
- " if(EXISTS directory-name)\n"
- "True if the named file or directory exists. "
- "Behavior is well-defined only for full paths.\n"
- " if(file1 IS_NEWER_THAN file2)\n"
- "True if file1 is newer than file2 or if one of the two files "
- "doesn't exist. "
- "Behavior is well-defined only for full paths. "
- "If the file time stamps are exactly the same, an "
- "IS_NEWER_THAN comparison returns true, so that any dependent "
- "build operations will occur in the event of a tie. "
- "This includes the case of passing the same file name for both "
- "file1 and file2.\n"
- " if(IS_DIRECTORY directory-name)\n"
- "True if the given name is a directory. "
- "Behavior is well-defined only for full paths.\n"
- " if(IS_SYMLINK file-name)\n"
- "True if the given name is a symbolic link. "
- "Behavior is well-defined only for full paths.\n"
- " if(IS_ABSOLUTE path)\n"
- "True if the given path is an absolute path.\n"
- " if(<variable|string> MATCHES regex)\n"
- "True if the given string or variable's value matches the given "
- "regular expression.\n"
- " if(<variable|string> LESS <variable|string>)\n"
- " if(<variable|string> GREATER <variable|string>)\n"
- " if(<variable|string> EQUAL <variable|string>)\n"
- "True if the given string or variable's value is a valid number and "
- "the inequality or equality is true.\n"
- " if(<variable|string> STRLESS <variable|string>)\n"
- " if(<variable|string> STRGREATER <variable|string>)\n"
- " if(<variable|string> STREQUAL <variable|string>)\n"
- "True if the given string or variable's value is lexicographically "
- "less (or greater, or equal) than the string or variable on the right.\n"
- " if(<variable|string> VERSION_LESS <variable|string>)\n"
- " if(<variable|string> VERSION_EQUAL <variable|string>)\n"
- " if(<variable|string> VERSION_GREATER <variable|string>)\n"
- "Component-wise integer version number comparison (version format is "
- "major[.minor[.patch[.tweak]]]).\n"
- " if(DEFINED <variable>)\n"
- "True if the given variable is defined. It does not matter if the "
- "variable is true or false just if it has been set.\n"
- " if((expression) AND (expression OR (expression)))\n"
- "The expressions inside the parenthesis are evaluated first and "
- "then the remaining expression is evaluated as in the previous "
- "examples. Where there are nested parenthesis the innermost are "
- "evaluated as part of evaluating the expression "
- "that contains them."
- "\n"
-
- "The if command was written very early in CMake's history, predating "
- "the ${} variable evaluation syntax, and for convenience evaluates "
- "variables named by its arguments as shown in the above signatures. "
- "Note that normal variable evaluation with ${} applies before the "
- "if command even receives the arguments. "
- "Therefore code like\n"
- " set(var1 OFF)\n"
- " set(var2 \"var1\")\n"
- " if(${var2})\n"
- "appears to the if command as\n"
- " if(var1)\n"
- "and is evaluated according to the if(<variable>) case "
- "documented above. "
- "The result is OFF which is false. "
- "However, if we remove the ${} from the example then the command sees\n"
- " if(var2)\n"
- "which is true because var2 is defined to \"var1\" which is not "
- "a false constant."
- "\n"
- "Automatic evaluation applies in the other cases whenever the "
- "above-documented signature accepts <variable|string>:\n"
-
- "1) The left hand argument to MATCHES is first checked to see "
- "if it is a defined variable, if so the variable's value is "
- "used, otherwise the original value is used. \n"
-
- "2) If the left hand argument to MATCHES is missing it returns "
- "false without error \n"
-
- "3) Both left and right hand arguments to LESS GREATER EQUAL "
- "are independently tested to see if they are defined variables, "
- "if so their defined values are used otherwise the original "
- "value is used. \n"
-
- "4) Both left and right hand arguments to STRLESS STREQUAL "
- "STRGREATER are independently tested to see if they are defined "
- "variables, if so their defined values are used otherwise the "
- "original value is used. \n"
-
- "5) Both left and right hand argumemnts to VERSION_LESS "
- "VERSION_EQUAL VERSION_GREATER are independently tested to see "
- "if they are defined variables, if so their defined values are "
- "used otherwise the original value is used. \n"
-
- "6) The right hand argument to NOT is tested to see if it is a "
- "boolean constant, if so the value is used, otherwise it is "
- "assumed to be a variable and it is dereferenced. \n"
-
- "7) The left and right hand arguments to AND OR are "
- "independently tested to see if they are boolean constants, if "
- "so they are used as such, otherwise they are assumed to be "
- "variables and are dereferenced. \n"
- ;
- }
-
- // this is a shared function for both If and Else to determine if the
- // arguments were valid, and if so, was the response true. If there is
- // an error, the errorString will be set.
- static bool IsTrue(const std::vector<std::string> &args,
- std::string &errorString, cmMakefile *mf,
- cmake::MessageType &status);
-
- // Get a definition from the makefile. If it doesn't exist,
- // return the original string.
- static const char* GetVariableOrString(const char* str,
- const cmMakefile* mf);
+ // Filter the given variable definition based on policy CMP0054.
+ static const char* GetDefinitionIfUnquoted(
+ const cmMakefile* mf, cmExpandedCommandArgument const& argument);
cmTypeMacro(cmIfCommand, cmCommand);
};
diff --git a/Source/cmIncludeCommand.cxx b/Source/cmIncludeCommand.cxx
index bb891d6fc..8890e2b0a 100644
--- a/Source/cmIncludeCommand.cxx
+++ b/Source/cmIncludeCommand.cxx
@@ -19,7 +19,7 @@ bool cmIncludeCommand
if (args.size()< 1 || args.size() > 4)
{
this->SetError("called with wrong number of arguments. "
- "Include only takes one file.");
+ "include() only takes one file.");
return false;
}
bool optional = false;
@@ -40,7 +40,7 @@ bool cmIncludeCommand
}
else if(args[i] == "RESULT_VARIABLE")
{
- if (resultVarName.size() > 0)
+ if (!resultVarName.empty())
{
this->SetError("called with invalid arguments: "
"only one result variable allowed");
@@ -65,7 +65,7 @@ bool cmIncludeCommand
{
std::string errorText = "called with invalid argument: ";
errorText += args[i];
- this->SetError(errorText.c_str());
+ this->SetError(errorText);
return false;
}
}
@@ -83,22 +83,72 @@ bool cmIncludeCommand
std::string module = fname;
module += ".cmake";
std::string mfile = this->Makefile->GetModulesFile(module.c_str());
- if ( mfile.size() )
+ if (!mfile.empty())
{
fname = mfile.c_str();
}
}
- std::string fullFilePath;
+
+ std::string fname_abs =
+ cmSystemTools::CollapseFullPath(fname,
+ this->Makefile->GetCurrentSourceDirectory());
+
+ cmGlobalGenerator *gg = this->Makefile->GetGlobalGenerator();
+ if (gg->IsExportedTargetsFile(fname_abs))
+ {
+ const char *modal = 0;
+ std::ostringstream e;
+ cmake::MessageType messageType = cmake::AUTHOR_WARNING;
+
+ switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0024))
+ {
+ case cmPolicies::WARN:
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0024) << "\n";
+ modal = "should";
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ modal = "may";
+ messageType = cmake::FATAL_ERROR;
+ }
+ if (modal)
+ {
+ e << "The file\n " << fname_abs << "\nwas generated by the export() "
+ "command. It " << modal << " not be used as the argument to the "
+ "include() command. Use ALIAS targets instead to refer to targets "
+ "by alternative names.\n";
+ this->Makefile->IssueMessage(messageType, e.str());
+ if (messageType == cmake::FATAL_ERROR)
+ {
+ return false;
+ }
+ }
+ gg->CreateGenerationObjects();
+ gg->GenerateImportFile(fname_abs);
+ }
+
+ std::string listFile =
+ cmSystemTools::CollapseFullPath(fname.c_str(),
+ this->Makefile->GetCurrentSourceDirectory());
+ if(optional && !cmSystemTools::FileExists(listFile.c_str()))
+ {
+ if (!resultVarName.empty())
+ {
+ this->Makefile->AddDefinition(resultVarName, "NOTFOUND");
+ }
+ return true;
+ }
+
bool readit =
- this->Makefile->ReadListFile( this->Makefile->GetCurrentListFile(),
- fname.c_str(), &fullFilePath,
- noPolicyScope);
+ this->Makefile->ReadDependentFile(listFile.c_str(), noPolicyScope);
// add the location of the included file if a result variable was given
- if (resultVarName.size())
+ if (!resultVarName.empty())
{
- this->Makefile->AddDefinition(resultVarName.c_str(),
- readit?fullFilePath.c_str():"NOTFOUND");
+ this->Makefile->AddDefinition(resultVarName,
+ readit?fname_abs.c_str():"NOTFOUND");
}
if(!optional && !readit && !cmSystemTools::GetFatalErrorOccured())
@@ -107,7 +157,7 @@ bool cmIncludeCommand
"could not find load file:\n"
" ";
m += fname;
- this->SetError(m.c_str());
+ this->SetError(m);
return false;
}
return true;
diff --git a/Source/cmIncludeCommand.h b/Source/cmIncludeCommand.h
index d97b7c3f5..0dcd7de8b 100644
--- a/Source/cmIncludeCommand.h
+++ b/Source/cmIncludeCommand.h
@@ -15,9 +15,7 @@
#include "cmCommand.h"
/** \class cmIncludeCommand
- * \brief
- *
- * cmIncludeCommand defines a list of distant
+ * \brief cmIncludeCommand defines a list of distant
* files that can be "included" in the current list file.
* In almost every sense, this is identical to a C/C++
* #include command. Arguments are first expended as usual.
@@ -48,42 +46,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const {return "include";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Load and run CMake code from a file or module.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " include(<file|module> [OPTIONAL] [RESULT_VARIABLE <VAR>]\n"
- " [NO_POLICY_SCOPE])\n"
- "Load and run CMake code from the file given. "
- "Variable reads and writes access the scope of the caller "
- "(dynamic scoping). "
- "If OPTIONAL is present, then no error "
- "is raised if the file does not exist. If RESULT_VARIABLE is given "
- "the variable will be set to the full filename which "
- "has been included or NOTFOUND if it failed.\n"
- "If a module is specified instead of a file, the file with name "
- "<modulename>.cmake is searched first in CMAKE_MODULE_PATH, then in the "
- "CMake module directory. There is one exception to this: if the file "
- "which calls include() is located itself in the CMake module directory, "
- "then first the CMake module directory is searched and "
- "CMAKE_MODULE_PATH afterwards. See also policy CMP0017."
- "\n"
- "See the cmake_policy() command documentation for discussion of the "
- "NO_POLICY_SCOPE option."
- ;
- }
+ virtual std::string GetName() const {return "include";}
cmTypeMacro(cmIncludeCommand, cmCommand);
};
diff --git a/Source/cmIncludeDirectoryCommand.cxx b/Source/cmIncludeDirectoryCommand.cxx
index 30c174375..5c28cfda4 100644
--- a/Source/cmIncludeDirectoryCommand.cxx
+++ b/Source/cmIncludeDirectoryCommand.cxx
@@ -38,7 +38,7 @@ bool cmIncludeDirectoryCommand
std::vector<std::string> beforeIncludes;
std::vector<std::string> afterIncludes;
- std::set<cmStdString> systemIncludes;
+ std::set<std::string> systemIncludes;
for(; i != args.end(); ++i)
{
@@ -47,7 +47,7 @@ bool cmIncludeDirectoryCommand
system = true;
continue;
}
- if(i->size() == 0)
+ if(i->empty())
{
this->SetError("given empty-string as include directory.");
return false;
@@ -55,7 +55,7 @@ bool cmIncludeDirectoryCommand
std::vector<std::string> includes;
- GetIncludes(*i, includes);
+ this->GetIncludes(*i, includes);
if (before)
{
@@ -71,11 +71,7 @@ bool cmIncludeDirectoryCommand
}
if (system)
{
- for (std::vector<std::string>::const_iterator li = includes.begin();
- li != includes.end(); ++li)
- {
- systemIncludes.insert(*li);
- }
+ systemIncludes.insert(includes.begin(), includes.end());
}
}
std::reverse(beforeIncludes.begin(), beforeIncludes.end());
@@ -153,7 +149,7 @@ void cmIncludeDirectoryCommand::NormalizeInclude(std::string &inc)
{
if(!StartsWithGeneratorExpression(inc))
{
- std::string tmp = this->Makefile->GetStartDirectory();
+ std::string tmp = this->Makefile->GetCurrentSourceDirectory();
tmp += "/";
tmp += inc;
inc = tmp;
diff --git a/Source/cmIncludeDirectoryCommand.h b/Source/cmIncludeDirectoryCommand.h
index 77a340a64..6cc2c8335 100644
--- a/Source/cmIncludeDirectoryCommand.h
+++ b/Source/cmIncludeDirectoryCommand.h
@@ -41,45 +41,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "include_directories";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Add include directories to the build.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)\n"
- "Add the given directories to those the compiler uses to search "
- "for include files. Relative paths are interpreted as relative to "
- "the current source directory. \n"
- "The include directories are added to the directory property "
- "INCLUDE_DIRECTORIES for the current CMakeLists file. "
- "They are also added to the target property INCLUDE_DIRECTORIES "
- "for each target in the current CMakeLists file. "
- "The target property values are the ones used by the generators."
- "\n"
- "By default the directories are appended onto the current list of "
- "directories. "
- "This default behavior can be changed by setting "
- "CMAKE_INCLUDE_DIRECTORIES_BEFORE to ON. "
- "By using AFTER or BEFORE explicitly, you can select between "
- "appending and prepending, independent of the default. "
- "\n"
- "If the SYSTEM option is given, the compiler will be told the "
- "directories are meant as system include directories on some "
- "platforms (signalling this setting might achieve effects such as "
- "the compiler skipping warnings, or these fixed-install system files "
- "not being considered in dependency calculations - see compiler docs).";
- }
+ virtual std::string GetName() const { return "include_directories";}
cmTypeMacro(cmIncludeDirectoryCommand, cmCommand);
diff --git a/Source/cmIncludeExternalMSProjectCommand.cxx b/Source/cmIncludeExternalMSProjectCommand.cxx
index d40d8fe72..c64d1289b 100644
--- a/Source/cmIncludeExternalMSProjectCommand.cxx
+++ b/Source/cmIncludeExternalMSProjectCommand.cxx
@@ -73,11 +73,11 @@ bool cmIncludeExternalMSProjectCommand
std::string guidVariable = utility_name + "_GUID_CMAKE";
this->Makefile->GetCMakeInstance()->AddCacheEntry(
guidVariable.c_str(), customGuid.c_str(),
- "Stored GUID", cmCacheManager::INTERNAL);
+ "Stored GUID", cmState::INTERNAL);
}
// Create a target instance for this utility.
- cmTarget* target=this->Makefile->AddNewTarget(cmTarget::UTILITY,
+ cmTarget* target=this->Makefile->AddNewTarget(cmState::UTILITY,
utility_name.c_str());
target->SetProperty("GENERATOR_FILE_NAME", utility_name.c_str());
diff --git a/Source/cmIncludeExternalMSProjectCommand.h b/Source/cmIncludeExternalMSProjectCommand.h
index d5cec01eb..081f77a01 100644
--- a/Source/cmIncludeExternalMSProjectCommand.h
+++ b/Source/cmIncludeExternalMSProjectCommand.h
@@ -42,39 +42,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const {return "include_external_msproject";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Include an external Microsoft project file in a workspace.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " include_external_msproject(projectname location\n"
- " [TYPE projectTypeGUID]\n"
- " [GUID projectGUID]\n"
- " [PLATFORM platformName]\n"
- " dep1 dep2 ...)\n"
- "Includes an external Microsoft project in the generated workspace "
- "file. Currently does nothing on UNIX. This will create a "
- "target named [projectname]. This can be used in the add_dependencies "
- "command to make things depend on the external project."
- "\n"
- "TYPE, GUID and PLATFORM are optional parameters that allow one "
- "to specify the type of project, id (GUID) of the project and "
- "the name of the target platform. "
- "This is useful for projects requiring values other than the default "
- "(e.g. WIX projects). "
- "These options are not supported by the Visual Studio 6 generator.";
- }
+ virtual std::string GetName() const {return "include_external_msproject";}
cmTypeMacro(cmIncludeExternalMSProjectCommand, cmCommand);
};
diff --git a/Source/cmIncludeRegularExpressionCommand.cxx b/Source/cmIncludeRegularExpressionCommand.cxx
index ef6e8c6ae..d6dfdd2a3 100644
--- a/Source/cmIncludeRegularExpressionCommand.cxx
+++ b/Source/cmIncludeRegularExpressionCommand.cxx
@@ -24,7 +24,7 @@ bool cmIncludeRegularExpressionCommand
if(args.size() > 1)
{
- this->Makefile->SetComplainRegularExpression(args[1].c_str());
+ this->Makefile->SetComplainRegularExpression(args[1]);
}
return true;
diff --git a/Source/cmIncludeRegularExpressionCommand.h b/Source/cmIncludeRegularExpressionCommand.h
index 2e4177548..c58f01876 100644
--- a/Source/cmIncludeRegularExpressionCommand.h
+++ b/Source/cmIncludeRegularExpressionCommand.h
@@ -41,31 +41,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const {return "include_regular_expression";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Set the regular expression used for dependency checking.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " include_regular_expression(regex_match [regex_complain])\n"
- "Set the regular expressions used in dependency checking. Only files "
- "matching regex_match will be traced as dependencies. Only files "
- "matching regex_complain will generate warnings if they cannot be "
- "found "
- "(standard header paths are not searched). The defaults are:\n"
- " regex_match = \"^.*$\" (match everything)\n"
- " regex_complain = \"^$\" (match empty string only)";
- }
+ virtual std::string GetName() const {return "include_regular_expression";}
cmTypeMacro(cmIncludeRegularExpressionCommand, cmCommand);
};
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index 3c76bd638..2d78a4101 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -25,19 +25,29 @@
static cmInstallTargetGenerator* CreateInstallTargetGenerator(cmTarget& target,
const cmInstallCommandArguments& args, bool impLib, bool forceOpt = false)
{
- return new cmInstallTargetGenerator(target, args.GetDestination().c_str(),
+ cmInstallGenerator::MessageLevel message =
+ cmInstallGenerator::SelectMessageLevel(target.GetMakefile());
+ target.SetHaveInstallRule(true);
+ return new cmInstallTargetGenerator(target.GetName(),
+ args.GetDestination().c_str(),
impLib, args.GetPermissions().c_str(),
args.GetConfigurations(), args.GetComponent().c_str(),
+ message,
args.GetOptional() || forceOpt);
}
static cmInstallFilesGenerator* CreateInstallFilesGenerator(
+ cmMakefile* mf,
const std::vector<std::string>& absFiles,
const cmInstallCommandArguments& args, bool programs)
{
- return new cmInstallFilesGenerator(absFiles, args.GetDestination().c_str(),
+ cmInstallGenerator::MessageLevel message =
+ cmInstallGenerator::SelectMessageLevel(mf);
+ return new cmInstallFilesGenerator(
+ absFiles, args.GetDestination().c_str(),
programs, args.GetPermissions().c_str(),
args.GetConfigurations(), args.GetComponent().c_str(),
+ message,
args.GetRename().c_str(), args.GetOptional());
}
@@ -54,8 +64,7 @@ bool cmInstallCommand::InitialPass(std::vector<std::string> const& args,
}
// Enable the install target.
- this->Makefile->GetLocalGenerator()
- ->GetGlobalGenerator()->EnableInstallTarget();
+ this->Makefile->GetGlobalGenerator()->EnableInstallTarget();
this->DefaultComponentName = this->Makefile->GetSafeDefinition(
"CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
@@ -95,9 +104,9 @@ bool cmInstallCommand::InitialPass(std::vector<std::string> const& args,
}
// Unknown mode.
- cmStdString e = "called with unknown mode ";
+ std::string e = "called with unknown mode ";
e += args[0];
- this->SetError(e.c_str());
+ this->SetError(e);
return false;
}
@@ -155,11 +164,11 @@ bool cmInstallCommand::HandleScriptMode(std::vector<std::string> const& args)
std::string script = args[i];
if(!cmSystemTools::FileIsFullPath(script.c_str()))
{
- script = this->Makefile->GetCurrentDirectory();
+ script = this->Makefile->GetCurrentSourceDirectory();
script += "/";
script += args[i];
}
- if(cmSystemTools::FileIsDirectory(script.c_str()))
+ if(cmSystemTools::FileIsDirectory(script))
{
this->SetError("given a directory as value of SCRIPT argument.");
return false;
@@ -190,7 +199,7 @@ bool cmInstallCommand::HandleScriptMode(std::vector<std::string> const& args)
}
//Tell the global generator about any installation component names specified.
- this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ this->Makefile->GetGlobalGenerator()
->AddInstallComponent(component.c_str());
return true;
@@ -265,9 +274,9 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
if(!unknownArgs.empty())
{
// Unknown argument.
- cmOStringStream e;
+ std::ostringstream e;
e << "TARGETS given unknown argument \"" << unknownArgs[0] << "\".";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
@@ -363,36 +372,37 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
++targetIt)
{
- if (this->Makefile->IsAlias(targetIt->c_str()))
+ if (this->Makefile->IsAlias(*targetIt))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "TARGETS given target \"" << (*targetIt)
<< "\" which is an alias.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
// Lookup this target in the current directory.
- if(cmTarget* target=this->Makefile->FindTarget(targetIt->c_str()))
+ if(cmTarget* target=this->Makefile->FindTarget(*targetIt))
{
// Found the target. Check its type.
- if(target->GetType() != cmTarget::EXECUTABLE &&
- target->GetType() != cmTarget::STATIC_LIBRARY &&
- target->GetType() != cmTarget::SHARED_LIBRARY &&
- target->GetType() != cmTarget::MODULE_LIBRARY &&
- target->GetType() != cmTarget::OBJECT_LIBRARY)
+ if(target->GetType() != cmState::EXECUTABLE &&
+ target->GetType() != cmState::STATIC_LIBRARY &&
+ target->GetType() != cmState::SHARED_LIBRARY &&
+ target->GetType() != cmState::MODULE_LIBRARY &&
+ target->GetType() != cmState::OBJECT_LIBRARY &&
+ target->GetType() != cmState::INTERFACE_LIBRARY)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "TARGETS given target \"" << (*targetIt)
<< "\" which is not an executable, library, or module.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
- else if(target->GetType() == cmTarget::OBJECT_LIBRARY)
+ else if(target->GetType() == cmState::OBJECT_LIBRARY)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "TARGETS given OBJECT library \"" << (*targetIt)
<< "\" which may not be installed.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
// Store the target in the list to be installed.
@@ -401,10 +411,10 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
else
{
// Did not find the target.
- cmOStringStream e;
+ std::ostringstream e;
e << "TARGETS given target \"" << (*targetIt)
<< "\" which does not exist in this directory.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
@@ -440,7 +450,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
switch(target.GetType())
{
- case cmTarget::SHARED_LIBRARY:
+ case cmState::SHARED_LIBRARY:
{
// Shared libraries are handled differently on DLL and non-DLL
// platforms. All windows platforms are DLL platforms including
@@ -493,10 +503,10 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "TARGETS given no FRAMEWORK DESTINATION for shared library "
"FRAMEWORK target \"" << target.GetName() << "\".";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
@@ -513,17 +523,17 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "TARGETS given no LIBRARY DESTINATION for shared library "
"target \"" << target.GetName() << "\".";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
}
}
break;
- case cmTarget::STATIC_LIBRARY:
+ case cmState::STATIC_LIBRARY:
{
// Static libraries use ARCHIVE properties.
if (!archiveArgs.GetDestination().empty())
@@ -533,15 +543,15 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "TARGETS given no ARCHIVE DESTINATION for static library "
"target \"" << target.GetName() << "\".";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
break;
- case cmTarget::MODULE_LIBRARY:
+ case cmState::MODULE_LIBRARY:
{
// Modules use LIBRARY properties.
if (!libraryArgs.GetDestination().empty())
@@ -554,15 +564,15 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "TARGETS given no LIBRARY DESTINATION for module target \""
<< target.GetName() << "\".";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
break;
- case cmTarget::EXECUTABLE:
+ case cmState::EXECUTABLE:
{
if(target.IsAppBundleOnApple())
{
@@ -589,10 +599,10 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
}
if(!bundleGenerator)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "TARGETS given no BUNDLE DESTINATION for MACOSX_BUNDLE "
"executable target \"" << target.GetName() << "\".";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
@@ -606,10 +616,10 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "TARGETS given no RUNTIME DESTINATION for executable "
"target \"" << target.GetName() << "\".";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
@@ -626,6 +636,11 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
}
}
break;
+ case cmState::INTERFACE_LIBRARY:
+ // Nothing to do. An INTERFACE_LIBRARY can be installed, but the
+ // only effect of that is to make it exportable. It installs no
+ // other files itself.
+ break;
default:
// This should never happen due to the above type check.
// Ignore the case.
@@ -639,7 +654,8 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
// generators for them.
bool createInstallGeneratorsForTargetFileSets = true;
- if(target.IsFrameworkOnApple())
+ if(target.IsFrameworkOnApple()
+ || target.GetType() == cmState::INTERFACE_LIBRARY)
{
createInstallGeneratorsForTargetFileSets = false;
}
@@ -661,11 +677,12 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
if (!privateHeaderArgs.GetDestination().empty())
{
privateHeaderGenerator =
- CreateInstallFilesGenerator(absFiles, privateHeaderArgs, false);
+ CreateInstallFilesGenerator(this->Makefile, absFiles,
+ privateHeaderArgs, false);
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "INSTALL TARGETS - target " << target.GetName() << " has "
<< "PRIVATE_HEADER files but no PRIVATE_HEADER DESTINATION.";
cmSystemTools::Message(e.str().c_str(), "Warning");
@@ -687,11 +704,12 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
if (!publicHeaderArgs.GetDestination().empty())
{
publicHeaderGenerator =
- CreateInstallFilesGenerator(absFiles, publicHeaderArgs, false);
+ CreateInstallFilesGenerator(this->Makefile, absFiles,
+ publicHeaderArgs, false);
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "INSTALL TARGETS - target " << target.GetName() << " has "
<< "PUBLIC_HEADER files but no PUBLIC_HEADER DESTINATION.";
cmSystemTools::Message(e.str().c_str(), "Warning");
@@ -712,12 +730,12 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
// Create the files install generator.
if (!resourceArgs.GetDestination().empty())
{
- resourceGenerator = CreateInstallFilesGenerator(absFiles,
- resourceArgs, false);
+ resourceGenerator = CreateInstallFilesGenerator(
+ this->Makefile, absFiles, resourceArgs, false);
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "INSTALL TARGETS - target " << target.GetName() << " has "
<< "RESOURCE files but no RESOURCE DESTINATION.";
cmSystemTools::Message(e.str().c_str(), "Warning");
@@ -750,29 +768,18 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
if(!exports.GetString().empty() && !namelinkOnly)
{
cmTargetExport *te = new cmTargetExport;
- te->Target = &target;
+ te->TargetName = target.GetName();
te->ArchiveGenerator = archiveGenerator;
te->BundleGenerator = bundleGenerator;
te->FrameworkGenerator = frameworkGenerator;
te->HeaderGenerator = publicHeaderGenerator;
te->LibraryGenerator = libraryGenerator;
te->RuntimeGenerator = runtimeGenerator;
- this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ this->Makefile->GetGlobalGenerator()
->GetExportSets()[exports.GetString()]->AddTargetExport(te);
- std::vector<std::string> dirs = includesArgs.GetIncludeDirs();
- if(!dirs.empty())
- {
- std::string dirString;
- const char *sep = "";
- for (std::vector<std::string>::const_iterator it = dirs.begin();
- it != dirs.end(); ++it)
- {
- te->InterfaceIncludeDirectories += sep;
- te->InterfaceIncludeDirectories += *it;
- sep = ";";
- }
- }
+ te->InterfaceIncludeDirectories =
+ cmJoin(includesArgs.GetIncludeDirs(), ";");
}
}
@@ -780,43 +787,42 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
// specified
if (installsArchive)
{
- this->Makefile->GetLocalGenerator()->
- GetGlobalGenerator()
+ this->Makefile->GetGlobalGenerator()
->AddInstallComponent(archiveArgs.GetComponent().c_str());
}
if (installsLibrary)
{
- this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ this->Makefile->GetGlobalGenerator()
->AddInstallComponent(libraryArgs.GetComponent().c_str());
}
if (installsRuntime)
{
- this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ this->Makefile->GetGlobalGenerator()
->AddInstallComponent(runtimeArgs.GetComponent().c_str());
}
if (installsFramework)
{
- this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ this->Makefile->GetGlobalGenerator()
->AddInstallComponent(frameworkArgs.GetComponent().c_str());
}
if (installsBundle)
{
- this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ this->Makefile->GetGlobalGenerator()
->AddInstallComponent(bundleArgs.GetComponent().c_str());
}
if (installsPrivateHeader)
{
- this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ this->Makefile->GetGlobalGenerator()
->AddInstallComponent(privateHeaderArgs.GetComponent().c_str());
}
if (installsPublicHeader)
{
- this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ this->Makefile->GetGlobalGenerator()
->AddInstallComponent(publicHeaderArgs.GetComponent().c_str());
}
if (installsResource)
{
- this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ this->Makefile->GetGlobalGenerator()
->AddInstallComponent(resourceArgs.GetComponent().c_str());
}
@@ -838,33 +844,76 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args)
if(!unknownArgs.empty())
{
// Unknown argument.
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " given unknown argument \"" << unknownArgs[0] << "\".";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
+ const std::vector<std::string>& filesVector = files.GetVector();
+
// Check if there is something to do.
- if(files.GetVector().empty())
+ if(filesVector.empty())
{
return true;
}
- if(!ica.GetRename().empty() && files.GetVector().size() > 1)
+ if(!ica.GetRename().empty() && filesVector.size() > 1)
{
// The rename option works only with one file.
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " given RENAME option with more than one file.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
std::vector<std::string> absFiles;
- if (!this->MakeFilesFullPath(args[0].c_str(), files.GetVector(), absFiles))
+ if (!this->MakeFilesFullPath(args[0].c_str(), filesVector, absFiles))
{
return false;
}
+ cmPolicies::PolicyStatus status =
+ this->Makefile->GetPolicyStatus(cmPolicies::CMP0062);
+
+ cmGlobalGenerator *gg = this->Makefile->GetGlobalGenerator();
+ for(std::vector<std::string>::const_iterator fileIt = filesVector.begin();
+ fileIt != filesVector.end(); ++fileIt)
+ {
+ if (gg->IsExportedTargetsFile(*fileIt))
+ {
+ const char *modal = 0;
+ std::ostringstream e;
+ cmake::MessageType messageType = cmake::AUTHOR_WARNING;
+
+ switch(status)
+ {
+ case cmPolicies::WARN:
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0062) << "\n";
+ modal = "should";
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ modal = "may";
+ messageType = cmake::FATAL_ERROR;
+ }
+ if (modal)
+ {
+ e << "The file\n " << *fileIt << "\nwas generated by the export() "
+ "command. It " << modal << " not be installed with the "
+ "install() command. Use the install(EXPORT) mechanism "
+ "instead. See the cmake-packages(7) manual for more.\n";
+ this->Makefile->IssueMessage(messageType, e.str());
+ if (messageType == cmake::FATAL_ERROR)
+ {
+ return false;
+ }
+ }
+ }
+ }
+
if (!ica.Finalize())
{
return false;
@@ -873,18 +922,18 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args)
if(ica.GetDestination().empty())
{
// A destination is required.
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " given no DESTINATION!";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
// Create the files install generator.
this->Makefile->AddInstallGenerator(
- CreateInstallFilesGenerator(absFiles, ica, programs));
+ CreateInstallFilesGenerator(this->Makefile, absFiles, ica, programs));
//Tell the global generator about any installation component names specified.
- this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ this->Makefile->GetGlobalGenerator()
->AddInstallComponent(ica.GetComponent().c_str());
return true;
@@ -900,6 +949,7 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
Doing doing = DoingDirs;
bool in_match_mode = false;
bool optional = false;
+ bool message_never = false;
std::vector<std::string> dirs;
const char* destination = 0;
std::string permissions_file;
@@ -913,10 +963,10 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
{
if(in_match_mode)
{
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " does not allow \""
<< args[i] << "\" after PATTERN or REGEX.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
@@ -927,10 +977,10 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
{
if(in_match_mode)
{
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " does not allow \""
<< args[i] << "\" after PATTERN or REGEX.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
@@ -938,6 +988,21 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
optional = true;
doing = DoingNone;
}
+ else if(args[i] == "MESSAGE_NEVER")
+ {
+ if(in_match_mode)
+ {
+ std::ostringstream e;
+ e << args[0] << " does not allow \""
+ << args[i] << "\" after PATTERN or REGEX.";
+ this->SetError(e.str());
+ return false;
+ }
+
+ // Mark the rule as quiet.
+ message_never = true;
+ doing = DoingNone;
+ }
else if(args[i] == "PATTERN")
{
// Switch to a new pattern match rule.
@@ -955,10 +1020,10 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
// Add this property to the current match rule.
if(!in_match_mode || doing == DoingPattern || doing == DoingRegex)
{
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " does not allow \""
<< args[i] << "\" before a PATTERN or REGEX is given.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
literal_args += " EXCLUDE";
@@ -968,10 +1033,10 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
{
if(!in_match_mode)
{
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " does not allow \""
<< args[i] << "\" before a PATTERN or REGEX is given.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
@@ -983,10 +1048,10 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
{
if(in_match_mode)
{
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " does not allow \""
<< args[i] << "\" after PATTERN or REGEX.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
@@ -997,10 +1062,10 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
{
if(in_match_mode)
{
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " does not allow \""
<< args[i] << "\" after PATTERN or REGEX.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
@@ -1011,10 +1076,10 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
{
if(in_match_mode)
{
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " does not allow \""
<< args[i] << "\" after PATTERN or REGEX.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
@@ -1026,10 +1091,10 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
{
if(in_match_mode)
{
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " does not allow \""
<< args[i] << "\" after PATTERN or REGEX.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
@@ -1041,10 +1106,10 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
{
if(in_match_mode)
{
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " does not allow \""
<< args[i] << "\" after PATTERN or REGEX.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
@@ -1055,10 +1120,10 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
{
if(in_match_mode)
{
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " does not allow \""
<< args[i] << "\" after PATTERN or REGEX.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
@@ -1071,19 +1136,19 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
std::string dir = args[i];
if(!cmSystemTools::FileIsFullPath(dir.c_str()))
{
- dir = this->Makefile->GetCurrentDirectory();
+ dir = this->Makefile->GetCurrentSourceDirectory();
dir += "/";
dir += args[i];
}
// Make sure the name is a directory.
if(cmSystemTools::FileExists(dir.c_str()) &&
- !cmSystemTools::FileIsDirectory(dir.c_str()))
+ !cmSystemTools::FileIsDirectory(dir))
{
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " given non-directory \""
<< args[i] << "\" to install.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
@@ -1136,10 +1201,10 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
// Check the requested permission.
if(!cmInstallCommandArguments::CheckPermissions(args[i],permissions_file))
{
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " given invalid file permission \""
<< args[i] << "\".";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
@@ -1148,10 +1213,10 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
// Check the requested permission.
if(!cmInstallCommandArguments::CheckPermissions(args[i],permissions_dir))
{
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " given invalid directory permission \""
<< args[i] << "\".";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
@@ -1160,19 +1225,19 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
// Check the requested permission.
if(!cmInstallCommandArguments::CheckPermissions(args[i], literal_args))
{
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " given invalid permission \""
<< args[i] << "\".";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
else
{
// Unknown argument.
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " given unknown argument \"" << args[i] << "\".";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
@@ -1191,12 +1256,15 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
if(!destination)
{
// A destination is required.
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " given no DESTINATION!";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
+ cmInstallGenerator::MessageLevel message =
+ cmInstallGenerator::SelectMessageLevel(this->Makefile, message_never);
+
// Create the directory install generator.
this->Makefile->AddInstallGenerator(
new cmInstallDirectoryGenerator(dirs, destination,
@@ -1204,12 +1272,13 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
permissions_dir.c_str(),
configurations,
component.c_str(),
+ message,
literal_args.c_str(),
optional));
// Tell the global generator about any installation component names
// specified.
- this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ this->Makefile->GetGlobalGenerator()
->AddInstallComponent(component.c_str());
return true;
@@ -1234,9 +1303,9 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args)
if (!unknownArgs.empty())
{
// Unknown argument.
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " given unknown argument \"" << unknownArgs[0] << "\".";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
@@ -1249,9 +1318,9 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args)
if(ica.GetDestination().empty())
{
// A destination is required.
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " given no DESTINATION!";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
@@ -1259,11 +1328,11 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args)
std::string fname = filename.GetString();
if(fname.find_first_of(":/\\") != fname.npos)
{
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " given invalid export file name \"" << fname << "\". "
<< "The FILE argument may not contain a path. "
<< "Specify the path in the DESTINATION argument.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
@@ -1271,10 +1340,10 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args)
if(!fname.empty() &&
cmSystemTools::GetFilenameLastExtension(fname) != ".cmake")
{
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " given invalid export file name \"" << fname << "\". "
<< "The FILE argument must specify a name ending in \".cmake\".";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
@@ -1286,18 +1355,18 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args)
if(fname.find_first_of(":/\\") != fname.npos)
{
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " given export name \"" << exp.GetString() << "\". "
<< "This name cannot be safely converted to a file name. "
<< "Specify a different export name or use the FILE option to set "
<< "a file name explicitly.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
- cmExportSet *exportSet = this->Makefile->GetLocalGenerator()
- ->GetGlobalGenerator()->GetExportSets()[exp.GetString()];
+ cmExportSet *exportSet = this->Makefile->GetGlobalGenerator()
+ ->GetExportSets()[exp.GetString()];
if (exportOld.IsEnabled())
{
for(std::vector<cmTargetExport*>::const_iterator
@@ -1305,31 +1374,37 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args)
tei != exportSet->GetTargetExports()->end(); ++tei)
{
cmTargetExport const* te = *tei;
+ cmTarget* tgt =
+ this->Makefile->GetGlobalGenerator()->FindTarget(te->TargetName);
const bool newCMP0022Behavior =
- te->Target->GetPolicyStatusCMP0022() != cmPolicies::WARN
- && te->Target->GetPolicyStatusCMP0022() != cmPolicies::OLD;
+ (tgt &&
+ tgt->GetPolicyStatusCMP0022() != cmPolicies::WARN &&
+ tgt->GetPolicyStatusCMP0022() != cmPolicies::OLD);
if(!newCMP0022Behavior)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "INSTALL(EXPORT) given keyword \""
<< "EXPORT_LINK_INTERFACE_LIBRARIES" << "\", but target \""
- << te->Target->GetName()
+ << te->TargetName
<< "\" does not have policy CMP0022 set to NEW.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
}
+ cmInstallGenerator::MessageLevel message =
+ cmInstallGenerator::SelectMessageLevel(this->Makefile);
+
// Create the export install generator.
cmInstallExportGenerator* exportGenerator =
new cmInstallExportGenerator(
exportSet,
ica.GetDestination().c_str(),
ica.GetPermissions().c_str(), ica.GetConfigurations(),
- ica.GetComponent().c_str(), fname.c_str(),
- name_space.GetCString(), exportOld.IsEnabled(), this->Makefile);
+ ica.GetComponent().c_str(), message, fname.c_str(),
+ name_space.GetCString(), exportOld.IsEnabled());
this->Makefile->AddInstallGenerator(exportGenerator);
return true;
@@ -1344,19 +1419,20 @@ bool cmInstallCommand::MakeFilesFullPath(const char* modeName,
++fileIt)
{
std::string file = (*fileIt);
- if(!cmSystemTools::FileIsFullPath(file.c_str()))
+ std::string::size_type gpos = cmGeneratorExpression::Find(file);
+ if(gpos != 0 && !cmSystemTools::FileIsFullPath(file.c_str()))
{
- file = this->Makefile->GetCurrentDirectory();
+ file = this->Makefile->GetCurrentSourceDirectory();
file += "/";
file += *fileIt;
}
// Make sure the file is not a directory.
- if(cmSystemTools::FileIsDirectory(file.c_str()))
+ if(gpos == file.npos && cmSystemTools::FileIsDirectory(file))
{
- cmOStringStream e;
+ std::ostringstream e;
e << modeName << " given directory \"" << (*fileIt) << "\" to install.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
// Store the file for installation.
@@ -1374,7 +1450,7 @@ bool cmInstallCommand::CheckCMP0006(bool& failure)
{
this->Makefile->IssueMessage(
cmake::AUTHOR_WARNING,
- this->Makefile->GetPolicies()->GetPolicyWarning(cmPolicies::CMP0006)
+ cmPolicies::GetPolicyWarning(cmPolicies::CMP0006)
);
}
case cmPolicies::OLD:
@@ -1388,8 +1464,7 @@ bool cmInstallCommand::CheckCMP0006(bool& failure)
failure = true;
this->Makefile->IssueMessage(
cmake::FATAL_ERROR,
- this->Makefile->GetPolicies()
- ->GetRequiredPolicyError(cmPolicies::CMP0006)
+ cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0006)
);
break;
}
diff --git a/Source/cmInstallCommand.h b/Source/cmInstallCommand.h
index 65095011f..8e14a0828 100644
--- a/Source/cmInstallCommand.h
+++ b/Source/cmInstallCommand.h
@@ -41,308 +41,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "install";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Specify rules to run at install time.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- "This command generates installation rules for a project. "
- "Rules specified by calls to this command within a source directory "
- "are executed in order during installation. "
- "The order across directories is not defined."
- "\n"
- "There are multiple signatures for this command. Some of them define "
- "installation properties for files and targets. Properties common to "
- "multiple signatures are covered here but they are valid only for "
- "signatures that specify them.\n"
- "DESTINATION arguments specify "
- "the directory on disk to which a file will be installed. "
- "If a full path (with a leading slash or drive letter) is given it "
- "is used directly. If a relative path is given it is interpreted "
- "relative to the value of CMAKE_INSTALL_PREFIX. The prefix can "
- "be relocated at install time using DESTDIR mechanism explained in the "
- "CMAKE_INSTALL_PREFIX variable documentation.\n"
- "PERMISSIONS arguments specify permissions for installed files. "
- "Valid permissions are "
- "OWNER_READ, OWNER_WRITE, OWNER_EXECUTE, "
- "GROUP_READ, GROUP_WRITE, GROUP_EXECUTE, "
- "WORLD_READ, WORLD_WRITE, WORLD_EXECUTE, "
- "SETUID, and SETGID. "
- "Permissions that do not make sense on certain platforms are ignored "
- "on those platforms.\n"
- "The CONFIGURATIONS argument specifies a list of build configurations "
- "for which the install rule applies (Debug, Release, etc.).\n"
- "The COMPONENT argument specifies an installation component name "
- "with which the install rule is associated, such as \"runtime\" or "
- "\"development\". During component-specific installation only "
- "install rules associated with the given component name will be "
- "executed. During a full installation all components are installed."
- " If COMPONENT is not provided a default component \"Unspecified\" is"
- " created. The default component name may be controlled with the "
- "CMAKE_INSTALL_DEFAULT_COMPONENT_NAME variable.\n"
- "The RENAME argument specifies a name for an installed file that "
- "may be different from the original file. Renaming is allowed only "
- "when a single file is installed by the command.\n"
- "The OPTIONAL argument specifies that it is not an error if the "
- "file to be installed does not exist. "
- "\n"
- "The TARGETS signature:\n"
- " install(TARGETS targets... [EXPORT <export-name>]\n"
- " [[ARCHIVE|LIBRARY|RUNTIME|FRAMEWORK|BUNDLE|\n"
- " PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE]\n"
- " [DESTINATION <dir>]\n"
- " [INCLUDES DESTINATION [<dir> ...]]\n"
- " [PERMISSIONS permissions...]\n"
- " [CONFIGURATIONS [Debug|Release|...]]\n"
- " [COMPONENT <component>]\n"
- " [OPTIONAL] [NAMELINK_ONLY|NAMELINK_SKIP]\n"
- " ] [...])\n"
- "The TARGETS form specifies rules for installing targets from a "
- "project. There are five kinds of target files that may be "
- "installed: ARCHIVE, LIBRARY, RUNTIME, FRAMEWORK, and BUNDLE. "
-
- "Executables are treated as RUNTIME targets, except that those "
- "marked with the MACOSX_BUNDLE property are treated as BUNDLE "
- "targets on OS X. "
- "Static libraries are always treated as ARCHIVE targets. "
- "Module libraries are always treated as LIBRARY targets. "
- "For non-DLL platforms shared libraries are treated as LIBRARY "
- "targets, except that those marked with the FRAMEWORK property "
- "are treated as FRAMEWORK targets on OS X. "
- "For DLL platforms the DLL part of a shared library is treated as "
- "a RUNTIME target and the corresponding import library is treated as "
- "an ARCHIVE target. "
- "All Windows-based systems including Cygwin are DLL platforms. "
- "The ARCHIVE, LIBRARY, RUNTIME, and FRAMEWORK "
- "arguments change the type of target to which the subsequent "
- "properties "
- "apply. If none is given the installation properties apply to "
- "all target types. If only one is given then only targets of that "
- "type will be installed (which can be used to install just a DLL or "
- "just an import library)."
- "The INCLUDES DESTINATION specifies a list of directories which will "
- "be added to the INTERFACE_INCLUDE_DIRECTORIES of the <targets> when "
- "exported by install(EXPORT). If a relative path is specified, it is "
- "treated as relative to the $<INSTALL_PREFIX>."
- "\n"
- "The PRIVATE_HEADER, PUBLIC_HEADER, and RESOURCE arguments cause "
- "subsequent properties to be applied to installing a FRAMEWORK "
- "shared library target's associated files on non-Apple platforms. "
- "Rules defined by these arguments are ignored on Apple platforms "
- "because the associated files are installed into the appropriate "
- "locations inside the framework folder. "
- "See documentation of the PRIVATE_HEADER, PUBLIC_HEADER, and RESOURCE "
- "target properties for details."
- "\n"
- "Either NAMELINK_ONLY or NAMELINK_SKIP may be specified as a LIBRARY "
- "option. "
- "On some platforms a versioned shared library has a symbolic link "
- "such as\n"
- " lib<name>.so -> lib<name>.so.1\n"
- "where \"lib<name>.so.1\" is the soname of the library and "
- "\"lib<name>.so\" is a \"namelink\" allowing linkers to find the "
- "library when given \"-l<name>\". "
- "The NAMELINK_ONLY option causes installation of only the namelink "
- "when a library target is installed. "
- "The NAMELINK_SKIP option causes installation of library files other "
- "than the namelink when a library target is installed. "
- "When neither option is given both portions are installed. "
- "On platforms where versioned shared libraries do not have namelinks "
- "or when a library is not versioned the NAMELINK_SKIP option installs "
- "the library and the NAMELINK_ONLY option installs nothing. "
- "See the VERSION and SOVERSION target properties for details on "
- "creating versioned shared libraries."
- "\n"
- "One or more groups of properties may be specified in a single call "
- "to the TARGETS form of this command. A target may be installed more "
- "than once to different locations. Consider hypothetical "
- "targets \"myExe\", \"mySharedLib\", and \"myStaticLib\". The code\n"
- " install(TARGETS myExe mySharedLib myStaticLib\n"
- " RUNTIME DESTINATION bin\n"
- " LIBRARY DESTINATION lib\n"
- " ARCHIVE DESTINATION lib/static)\n"
- " install(TARGETS mySharedLib DESTINATION /some/full/path)\n"
- "will install myExe to <prefix>/bin and myStaticLib to "
- "<prefix>/lib/static. "
- "On non-DLL platforms mySharedLib will be installed to <prefix>/lib "
- "and /some/full/path. On DLL platforms the mySharedLib DLL will be "
- "installed to <prefix>/bin and /some/full/path and its import library "
- "will be installed to <prefix>/lib/static and /some/full/path."
- "\n"
- "The EXPORT option associates the installed target files with an "
- "export called <export-name>. "
- "It must appear before any RUNTIME, LIBRARY, or ARCHIVE options. "
- "To actually install the export file itself, call install(EXPORT). "
- "See documentation of the install(EXPORT ...) signature below for "
- "details."
- "\n"
- "Installing a target with EXCLUDE_FROM_ALL set to true has "
- "undefined behavior."
- "\n"
- "The FILES signature:\n"
- " install(FILES files... DESTINATION <dir>\n"
- " [PERMISSIONS permissions...]\n"
- " [CONFIGURATIONS [Debug|Release|...]]\n"
- " [COMPONENT <component>]\n"
- " [RENAME <name>] [OPTIONAL])\n"
- "The FILES form specifies rules for installing files for a "
- "project. File names given as relative paths are interpreted with "
- "respect to the current source directory. Files installed by this "
- "form are by default given permissions OWNER_WRITE, OWNER_READ, "
- "GROUP_READ, and WORLD_READ if no PERMISSIONS argument is given."
- "\n"
- "The PROGRAMS signature:\n"
- " install(PROGRAMS files... DESTINATION <dir>\n"
- " [PERMISSIONS permissions...]\n"
- " [CONFIGURATIONS [Debug|Release|...]]\n"
- " [COMPONENT <component>]\n"
- " [RENAME <name>] [OPTIONAL])\n"
- "The PROGRAMS form is identical to the FILES form except that the "
- "default permissions for the installed file also include "
- "OWNER_EXECUTE, GROUP_EXECUTE, and WORLD_EXECUTE. "
- "This form is intended to install programs that are not targets, "
- "such as shell scripts. Use the TARGETS form to install targets "
- "built within the project."
- "\n"
- "The DIRECTORY signature:\n"
- " install(DIRECTORY dirs... DESTINATION <dir>\n"
- " [FILE_PERMISSIONS permissions...]\n"
- " [DIRECTORY_PERMISSIONS permissions...]\n"
- " [USE_SOURCE_PERMISSIONS] [OPTIONAL]\n"
- " [CONFIGURATIONS [Debug|Release|...]]\n"
- " [COMPONENT <component>] [FILES_MATCHING]\n"
- " [[PATTERN <pattern> | REGEX <regex>]\n"
- " [EXCLUDE] [PERMISSIONS permissions...]] [...])\n"
- "The DIRECTORY form installs contents of one or more directories "
- "to a given destination. "
- "The directory structure is copied verbatim to the destination. "
- "The last component of each directory name is appended to the "
- "destination directory but a trailing slash may be used to "
- "avoid this because it leaves the last component empty. "
- "Directory names given as relative paths are interpreted with "
- "respect to the current source directory. "
- "If no input directory names are given the destination directory "
- "will be created but nothing will be installed into it. "
- "The FILE_PERMISSIONS and DIRECTORY_PERMISSIONS options specify "
- "permissions given to files and directories in the destination. "
- "If USE_SOURCE_PERMISSIONS is specified and FILE_PERMISSIONS is not, "
- "file permissions will be copied from the source directory structure. "
- "If no permissions are specified files will be given the default "
- "permissions specified in the FILES form of the command, and the "
- "directories will be given the default permissions specified in the "
- "PROGRAMS form of the command.\n"
-
- "Installation of directories may be controlled with fine granularity "
- "using the PATTERN or REGEX options. These \"match\" options specify a "
- "globbing pattern or regular expression to match directories or files "
- "encountered within input directories. They may be used to apply "
- "certain options (see below) to a subset of the files and directories "
- "encountered. "
- "The full path to each input file or directory "
- "(with forward slashes) is matched against the expression. "
- "A PATTERN will match only complete file names: the portion of the "
- "full path matching the pattern must occur at the end of the file name "
- "and be preceded by a slash. "
- "A REGEX will match any portion of the full path but it may use "
- "'/' and '$' to simulate the PATTERN behavior. "
- "By default all files and directories are installed whether "
- "or not they are matched. "
- "The FILES_MATCHING option may be given before the first match option "
- "to disable installation of files (but not directories) not matched by "
- "any expression. For example, the code\n"
- " install(DIRECTORY src/ DESTINATION include/myproj\n"
- " FILES_MATCHING PATTERN \"*.h\")\n"
- "will extract and install header files from a source tree.\n"
- "Some options may follow a PATTERN or REGEX expression and are "
- "applied only to files or directories matching them. "
- "The EXCLUDE option will skip the matched file or directory. "
- "The PERMISSIONS option overrides the permissions setting for the "
- "matched file or directory. "
- "For example the code\n"
- " install(DIRECTORY icons scripts/ DESTINATION share/myproj\n"
- " PATTERN \"CVS\" EXCLUDE\n"
- " PATTERN \"scripts/*\"\n"
- " PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ\n"
- " GROUP_EXECUTE GROUP_READ)\n"
- "will install the icons directory to share/myproj/icons and the "
- "scripts directory to share/myproj. The icons will get default file "
- "permissions, the scripts will be given specific permissions, and "
- "any CVS directories will be excluded."
- "\n"
- "The SCRIPT and CODE signature:\n"
- " install([[SCRIPT <file>] [CODE <code>]] [...])\n"
- "The SCRIPT form will invoke the given CMake script files during "
- "installation. If the script file name is a relative path "
- "it will be interpreted with respect to the current source directory. "
- "The CODE form will invoke the given CMake code during installation. "
- "Code is specified as a single argument inside a double-quoted string. "
- "For example, the code\n"
- " install(CODE \"MESSAGE(\\\"Sample install message.\\\")\")\n"
- "will print a message during installation.\n"
- ""
- "The EXPORT signature:\n"
- " install(EXPORT <export-name> DESTINATION <dir>\n"
- " [NAMESPACE <namespace>] [FILE <name>.cmake]\n"
- " [PERMISSIONS permissions...]\n"
- " [CONFIGURATIONS [Debug|Release|...]]\n"
- " [EXPORT_LINK_INTERFACE_LIBRARIES]\n"
- " [COMPONENT <component>])\n"
- "The EXPORT form generates and installs a CMake file containing code "
- "to import targets from the installation tree into another project. "
- "Target installations are associated with the export <export-name> "
- "using the EXPORT option of the install(TARGETS ...) signature "
- "documented above. The NAMESPACE option will prepend <namespace> to "
- "the target names as they are written to the import file. "
- "By default the generated file will be called <export-name>.cmake but "
- "the FILE option may be used to specify a different name. The value "
- "given to the FILE option must be a file name with the \".cmake\" "
- "extension. "
- "If a CONFIGURATIONS option is given then the file will only be "
- "installed when one of the named configurations is installed. "
- "Additionally, the generated import file will reference only the "
- "matching target configurations. "
- "The EXPORT_LINK_INTERFACE_LIBRARIES keyword, if present, causes the "
- "contents of the properties matching "
- "(IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)? to be exported, when "
- "policy CMP0022 is NEW. "
- "If a COMPONENT option is specified that does not match that given "
- "to the targets associated with <export-name> the behavior is "
- "undefined. "
- "If a library target is included in the export but "
- "a target to which it links is not included the behavior is "
- "unspecified."
- "\n"
- "The EXPORT form is useful to help outside projects use targets built "
- "and installed by the current project. For example, the code\n"
- " install(TARGETS myexe EXPORT myproj DESTINATION bin)\n"
- " install(EXPORT myproj NAMESPACE mp_ DESTINATION lib/myproj)\n"
- "will install the executable myexe to <prefix>/bin and code to import "
- "it in the file \"<prefix>/lib/myproj/myproj.cmake\". "
- "An outside project may load this file with the include command "
- "and reference the myexe executable from the installation tree using "
- "the imported target name mp_myexe as if the target were built "
- "in its own tree."
- "\n"
- "NOTE: This command supercedes the INSTALL_TARGETS command and the "
- "target properties PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT. "
- "It also replaces the FILES forms of the INSTALL_FILES and "
- "INSTALL_PROGRAMS commands. "
- "The processing order of these install rules relative to those "
- "generated by INSTALL_TARGETS, INSTALL_FILES, and INSTALL_PROGRAMS "
- "commands is not defined.\n"
- ;
- }
+ virtual std::string GetName() const { return "install";}
cmTypeMacro(cmInstallCommand, cmCommand);
diff --git a/Source/cmInstallCommandArguments.cxx b/Source/cmInstallCommandArguments.cxx
index 91ea861a4..236ca1feb 100644
--- a/Source/cmInstallCommandArguments.cxx
+++ b/Source/cmInstallCommandArguments.cxx
@@ -228,11 +228,6 @@ void cmInstallCommandIncludesArgument::Parse(
for ( ; it != args->end(); ++it)
{
std::string dir = *it;
- if (!cmSystemTools::FileIsFullPath(it->c_str())
- && cmGeneratorExpression::Find(*it) == std::string::npos)
- {
- dir = "$<INSTALL_PREFIX>/" + dir;
- }
cmSystemTools::ConvertToUnixSlashes(dir);
this->IncludeDirs.push_back(dir);
}
diff --git a/Source/cmInstallDirectoryGenerator.cxx b/Source/cmInstallDirectoryGenerator.cxx
index ddf7d08cc..f2e860915 100644
--- a/Source/cmInstallDirectoryGenerator.cxx
+++ b/Source/cmInstallDirectoryGenerator.cxx
@@ -11,7 +11,8 @@
============================================================================*/
#include "cmInstallDirectoryGenerator.h"
-#include "cmTarget.h"
+#include "cmGeneratorExpression.h"
+#include "cmLocalGenerator.h"
//----------------------------------------------------------------------------
cmInstallDirectoryGenerator
@@ -21,12 +22,30 @@ cmInstallDirectoryGenerator
const char* dir_permissions,
std::vector<std::string> const& configurations,
const char* component,
+ MessageLevel message,
const char* literal_args,
bool optional):
- cmInstallGenerator(dest, configurations, component), Directories(dirs),
+ cmInstallGenerator(dest, configurations, component, message),
+ LocalGenerator(0),
+ Directories(dirs),
FilePermissions(file_permissions), DirPermissions(dir_permissions),
LiteralArguments(literal_args), Optional(optional)
{
+ // We need per-config actions if destination have generator expressions.
+ if(cmGeneratorExpression::Find(Destination) != std::string::npos)
+ {
+ this->ActionsPerConfig = true;
+ }
+
+ // We need per-config actions if any directories have generator expressions.
+ for(std::vector<std::string>::const_iterator i = dirs.begin();
+ !this->ActionsPerConfig && i != dirs.end(); ++i)
+ {
+ if(cmGeneratorExpression::Find(*i) != std::string::npos)
+ {
+ this->ActionsPerConfig = true;
+ }
+ }
}
//----------------------------------------------------------------------------
@@ -35,18 +54,67 @@ cmInstallDirectoryGenerator
{
}
+void cmInstallDirectoryGenerator::Compute(cmLocalGenerator* lg)
+{
+ LocalGenerator = lg;
+}
+
//----------------------------------------------------------------------------
void
cmInstallDirectoryGenerator::GenerateScriptActions(std::ostream& os,
Indent const& indent)
{
+ if(this->ActionsPerConfig)
+ {
+ this->cmInstallGenerator::GenerateScriptActions(os, indent);
+ }
+ else
+ {
+ this->AddDirectoryInstallRule(os, "", indent, this->Directories);
+ }
+}
+
+void cmInstallDirectoryGenerator::GenerateScriptForConfig(
+ std::ostream& os,
+ const std::string& config,
+ Indent const& indent)
+{
+ std::vector<std::string> dirs;
+ cmGeneratorExpression ge;
+ for(std::vector<std::string>::const_iterator i = this->Directories.begin();
+ i != this->Directories.end(); ++i)
+ {
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*i);
+ cmSystemTools::ExpandListArgument(cge->Evaluate(
+ this->LocalGenerator, config), dirs);
+ }
+ this->AddDirectoryInstallRule(os, config, indent, dirs);
+}
+
+void cmInstallDirectoryGenerator::AddDirectoryInstallRule(
+ std::ostream& os,
+ const std::string& config,
+ Indent const& indent,
+ std::vector<std::string> const& dirs)
+{
// Write code to install the directories.
const char* no_rename = 0;
- this->AddInstallRule(os, cmInstallType_DIRECTORY,
- this->Directories,
+ this->AddInstallRule(os,
+ this->GetDestination(config),
+ cmInstallType_DIRECTORY,
+ dirs,
this->Optional,
this->FilePermissions.c_str(),
this->DirPermissions.c_str(),
no_rename, this->LiteralArguments.c_str(),
indent);
}
+
+//----------------------------------------------------------------------------
+std::string
+cmInstallDirectoryGenerator::GetDestination(std::string const& config) const
+{
+ cmGeneratorExpression ge;
+ return ge.Parse(this->Destination)
+ ->Evaluate(this->LocalGenerator, config);
+}
diff --git a/Source/cmInstallDirectoryGenerator.h b/Source/cmInstallDirectoryGenerator.h
index d76ef3c4c..9b732d3f1 100644
--- a/Source/cmInstallDirectoryGenerator.h
+++ b/Source/cmInstallDirectoryGenerator.h
@@ -26,12 +26,25 @@ public:
const char* dir_permissions,
std::vector<std::string> const& configurations,
const char* component,
+ MessageLevel message,
const char* literal_args,
bool optional = false);
virtual ~cmInstallDirectoryGenerator();
+ void Compute(cmLocalGenerator* lg);
+
+ std::string GetDestination(std::string const& config) const;
+
protected:
virtual void GenerateScriptActions(std::ostream& os, Indent const& indent);
+ virtual void GenerateScriptForConfig(std::ostream& os,
+ const std::string& config,
+ Indent const& indent);
+ void AddDirectoryInstallRule(std::ostream& os,
+ const std::string& config,
+ Indent const& indent,
+ std::vector<std::string> const& dirs);
+ cmLocalGenerator* LocalGenerator;
std::vector<std::string> Directories;
std::string FilePermissions;
std::string DirPermissions;
diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx
index 3e9e6ac02..9570ba3d8 100644
--- a/Source/cmInstallExportGenerator.cxx
+++ b/Source/cmInstallExportGenerator.cxx
@@ -32,16 +32,16 @@ cmInstallExportGenerator::cmInstallExportGenerator(
const char* file_permissions,
std::vector<std::string> const& configurations,
const char* component,
+ MessageLevel message,
const char* filename, const char* name_space,
- bool exportOld,
- cmMakefile* mf)
- :cmInstallGenerator(destination, configurations, component)
+ bool exportOld)
+ :cmInstallGenerator(destination, configurations, component, message)
,ExportSet(exportSet)
,FilePermissions(file_permissions)
,FileName(filename)
,Namespace(name_space)
,ExportOld(exportOld)
- ,Makefile(mf)
+ ,LocalGenerator(0)
{
this->EFGen = new cmExportInstallFileGenerator(this);
exportSet->AddInstallation(this);
@@ -53,12 +53,19 @@ cmInstallExportGenerator::~cmInstallExportGenerator()
delete this->EFGen;
}
+void cmInstallExportGenerator::Compute(cmLocalGenerator* lg)
+{
+ this->LocalGenerator = lg;
+ this->ExportSet->Compute(lg);
+}
+
//----------------------------------------------------------------------------
void cmInstallExportGenerator::ComputeTempDir()
{
// Choose a temporary directory in which to generate the import
// files to be installed.
- this->TempDir = this->Makefile->GetCurrentOutputDirectory();
+ this->TempDir =
+ this->LocalGenerator->GetCurrentBinaryDirectory();
this->TempDir += cmake::GetCMakeFilesDirectory();
this->TempDir += "/Export";
if(this->Destination.empty())
@@ -94,7 +101,7 @@ void cmInstallExportGenerator::ComputeTempDir()
{
// Replace the destination path with a hash to keep it short.
this->TempDir +=
- cmSystemTools::ComputeStringMD5(this->Destination.c_str());
+ cmSystemTools::ComputeStringMD5(this->Destination);
}
else
{
@@ -120,7 +127,7 @@ void cmInstallExportGenerator::GenerateScript(std::ostream& os)
// Skip empty sets.
if(ExportSet->GetTargetExports()->empty())
{
- cmOStringStream e;
+ std::ostringstream e;
e << "INSTALL(EXPORT) given unknown export \""
<< ExportSet->GetName() << "\"";
cmSystemTools::Error(e.str().c_str());
@@ -138,11 +145,11 @@ void cmInstallExportGenerator::GenerateScript(std::ostream& os)
// Generate the import file for this export set.
this->EFGen->SetExportFile(this->MainImportFile.c_str());
- this->EFGen->SetNamespace(this->Namespace.c_str());
+ this->EFGen->SetNamespace(this->Namespace);
this->EFGen->SetExportOld(this->ExportOld);
if(this->ConfigurationTypes->empty())
{
- if(this->ConfigurationName && *this->ConfigurationName)
+ if(!this->ConfigurationName.empty())
{
this->EFGen->AddConfiguration(this->ConfigurationName);
}
@@ -157,7 +164,7 @@ void cmInstallExportGenerator::GenerateScript(std::ostream& os)
ci = this->ConfigurationTypes->begin();
ci != this->ConfigurationTypes->end(); ++ci)
{
- this->EFGen->AddConfiguration(ci->c_str());
+ this->EFGen->AddConfiguration(*ci);
}
}
this->EFGen->GenerateImportFile();
@@ -177,17 +184,18 @@ cmInstallExportGenerator::GenerateScriptConfigs(std::ostream& os,
// Now create a configuration-specific install rule for the import
// file of each configuration.
std::vector<std::string> files;
- for(std::map<cmStdString, cmStdString>::const_iterator
+ for(std::map<std::string, std::string>::const_iterator
i = this->EFGen->GetConfigImportFiles().begin();
i != this->EFGen->GetConfigImportFiles().end(); ++i)
{
files.push_back(i->second);
- std::string config_test = this->CreateConfigTest(i->first.c_str());
- os << indent << "IF(" << config_test << ")\n";
- this->AddInstallRule(os, cmInstallType_FILES, files, false,
+ std::string config_test = this->CreateConfigTest(i->first);
+ os << indent << "if(" << config_test << ")\n";
+ this->AddInstallRule(os, this->Destination,
+ cmInstallType_FILES, files, false,
this->FilePermissions.c_str(), 0, 0, 0,
indent.Next());
- os << indent << "ENDIF(" << config_test << ")\n";
+ os << indent << "endif()\n";
files.clear();
}
}
@@ -198,31 +206,32 @@ void cmInstallExportGenerator::GenerateScriptActions(std::ostream& os,
{
// Remove old per-configuration export files if the main changes.
std::string installedDir = "$ENV{DESTDIR}";
- installedDir += this->GetInstallDestination();
+ installedDir += this->ConvertToAbsoluteDestination(this->Destination);
installedDir += "/";
std::string installedFile = installedDir;
installedFile += this->FileName;
- os << indent << "IF(EXISTS \"" << installedFile << "\")\n";
+ os << indent << "if(EXISTS \"" << installedFile << "\")\n";
Indent indentN = indent.Next();
Indent indentNN = indentN.Next();
Indent indentNNN = indentNN.Next();
- os << indentN << "FILE(DIFFERENT EXPORT_FILE_CHANGED FILES\n"
+ os << indentN << "file(DIFFERENT EXPORT_FILE_CHANGED FILES\n"
<< indentN << " \"" << installedFile << "\"\n"
<< indentN << " \"" << this->MainImportFile << "\")\n";
- os << indentN << "IF(EXPORT_FILE_CHANGED)\n";
- os << indentNN << "FILE(GLOB OLD_CONFIG_FILES \"" << installedDir
+ os << indentN << "if(EXPORT_FILE_CHANGED)\n";
+ os << indentNN << "file(GLOB OLD_CONFIG_FILES \"" << installedDir
<< this->EFGen->GetConfigImportFileGlob() << "\")\n";
- os << indentNN << "IF(OLD_CONFIG_FILES)\n";
- os << indentNNN << "MESSAGE(STATUS \"Old export file \\\"" << installedFile
+ os << indentNN << "if(OLD_CONFIG_FILES)\n";
+ os << indentNNN << "message(STATUS \"Old export file \\\"" << installedFile
<< "\\\" will be replaced. Removing files [${OLD_CONFIG_FILES}].\")\n";
- os << indentNNN << "FILE(REMOVE ${OLD_CONFIG_FILES})\n";
- os << indentNN << "ENDIF(OLD_CONFIG_FILES)\n";
- os << indentN << "ENDIF(EXPORT_FILE_CHANGED)\n";
- os << indent << "ENDIF()\n";
+ os << indentNNN << "file(REMOVE ${OLD_CONFIG_FILES})\n";
+ os << indentNN << "endif()\n";
+ os << indentN << "endif()\n";
+ os << indent << "endif()\n";
// Install the main export file.
std::vector<std::string> files;
files.push_back(this->MainImportFile);
- this->AddInstallRule(os, cmInstallType_FILES, files, false,
+ this->AddInstallRule(os, this->Destination,
+ cmInstallType_FILES, files, false,
this->FilePermissions.c_str(), 0, 0, 0, indent);
}
diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h
index 37b55932f..885ed0596 100644
--- a/Source/cmInstallExportGenerator.h
+++ b/Source/cmInstallExportGenerator.h
@@ -30,16 +30,22 @@ public:
const char* dest, const char* file_permissions,
const std::vector<std::string>& configurations,
const char* component,
+ MessageLevel message,
const char* filename, const char* name_space,
- bool exportOld, cmMakefile* mf);
+ bool exportOld);
~cmInstallExportGenerator();
cmExportSet* GetExportSet() {return this->ExportSet;}
- cmMakefile* GetMakefile() const { return this->Makefile; }
+ void Compute(cmLocalGenerator* lg);
+
+ cmLocalGenerator* GetLocalGenerator() const { return this->LocalGenerator; }
const std::string& GetNamespace() const { return this->Namespace; }
+ std::string const& GetDestination() const
+ { return this->Destination; }
+
protected:
virtual void GenerateScript(std::ostream& os);
virtual void GenerateScriptConfigs(std::ostream& os, Indent const& indent);
@@ -53,7 +59,7 @@ protected:
std::string FileName;
std::string Namespace;
bool ExportOld;
- cmMakefile* Makefile;
+ cmLocalGenerator* LocalGenerator;
std::string TempDir;
std::string MainImportFile;
diff --git a/Source/cmInstallFilesCommand.cxx b/Source/cmInstallFilesCommand.cxx
index cc62c4bac..68557bd8a 100644
--- a/Source/cmInstallFilesCommand.cxx
+++ b/Source/cmInstallFilesCommand.cxx
@@ -15,20 +15,16 @@
// cmExecutableCommand
bool cmInstallFilesCommand
-::InitialPass(std::vector<std::string> const& argsIn, cmExecutionStatus &)
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
- if(argsIn.size() < 2)
+ if(args.size() < 2)
{
this->SetError("called with incorrect number of arguments");
return false;
}
// Enable the install target.
- this->Makefile->GetLocalGenerator()
- ->GetGlobalGenerator()->EnableInstallTarget();
-
- std::vector<std::string> args;
- this->Makefile->ExpandSourceListArguments(argsIn, args, 2);
+ this->Makefile->GetGlobalGenerator()->EnableInstallTarget();
this->Destination = args[0];
@@ -47,14 +43,11 @@ bool cmInstallFilesCommand
else
{
this->IsFilesForm = false;
- std::vector<std::string>::const_iterator s = args.begin();
- for (++s;s != args.end(); ++s)
- {
- this->FinalArgs.push_back(*s);
- }
+ this->FinalArgs.insert(this->FinalArgs.end(),
+ args.begin() + 1, args.end());
}
- this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ this->Makefile->GetGlobalGenerator()
->AddInstallComponent(this->Makefile->GetSafeDefinition(
"CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"));
@@ -83,7 +76,7 @@ void cmInstallFilesCommand::FinalPass()
{
// replace any variables
std::string temps = *s;
- if (cmSystemTools::GetFilenamePath(temps).size() > 0)
+ if (!cmSystemTools::GetFilenamePath(temps).empty())
{
testf = cmSystemTools::GetFilenamePath(temps) + "/" +
cmSystemTools::GetFilenameWithoutLastExtension(temps) + ext;
@@ -100,9 +93,9 @@ void cmInstallFilesCommand::FinalPass()
else // reg exp list
{
std::vector<std::string> files;
- std::string regex = this->FinalArgs[0].c_str();
- cmSystemTools::Glob(this->Makefile->GetCurrentDirectory(),
- regex.c_str(), files);
+ std::string regex = this->FinalArgs[0];
+ cmSystemTools::Glob(this->Makefile->GetCurrentSourceDirectory(),
+ regex, files);
std::vector<std::string>::iterator s = files.begin();
// for each argument, get the files
@@ -132,11 +125,13 @@ void cmInstallFilesCommand::CreateInstallGenerator() const
std::string no_component = this->Makefile->GetSafeDefinition(
"CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
std::vector<std::string> no_configurations;
+ cmInstallGenerator::MessageLevel message =
+ cmInstallGenerator::SelectMessageLevel(this->Makefile);
this->Makefile->AddInstallGenerator(
new cmInstallFilesGenerator(this->Files,
destination.c_str(), false,
no_permissions, no_configurations,
- no_component.c_str(), no_rename));
+ no_component.c_str(), message, no_rename));
}
@@ -148,17 +143,18 @@ void cmInstallFilesCommand::CreateInstallGenerator() const
*/
std::string cmInstallFilesCommand::FindInstallSource(const char* name) const
{
- if(cmSystemTools::FileIsFullPath(name))
+ if(cmSystemTools::FileIsFullPath(name) ||
+ cmGeneratorExpression::Find(name) == 0)
{
// This is a full path.
return name;
}
// This is a relative path.
- std::string tb = this->Makefile->GetCurrentOutputDirectory();
+ std::string tb = this->Makefile->GetCurrentBinaryDirectory();
tb += "/";
tb += name;
- std::string ts = this->Makefile->GetCurrentDirectory();
+ std::string ts = this->Makefile->GetCurrentSourceDirectory();
ts += "/";
ts += name;
diff --git a/Source/cmInstallFilesCommand.h b/Source/cmInstallFilesCommand.h
index bb0a6ccaf..8062d1199 100644
--- a/Source/cmInstallFilesCommand.h
+++ b/Source/cmInstallFilesCommand.h
@@ -41,15 +41,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "install_files";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Deprecated. Use the install(FILES ) command instead.";
- }
+ virtual std::string GetName() const { return "install_files";}
/**
* This is called at the end after all the information
@@ -60,43 +52,6 @@ public:
virtual void FinalPass();
virtual bool HasFinalPass() const { return !this->IsFilesForm; }
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- "This command has been superceded by the install command. It "
- "is provided for compatibility with older CMake code. "
- "The FILES form is directly replaced by the FILES form of the "
- "install command. The regexp form can be expressed "
- "more clearly using the GLOB form of the file command.\n"
- " install_files(<dir> extension file file ...)\n"
- "Create rules to install the listed files with the given extension "
- "into the given directory. "
- "Only files existing in the current source tree or its corresponding "
- "location in the binary tree may be listed. "
- "If a file specified already has an extension, that extension will be "
- "removed first. This is useful for providing lists of source files "
- "such as foo.cxx when you want the corresponding foo.h to be "
- "installed. A typical extension is '.h'.\n"
- " install_files(<dir> regexp)\n"
- "Any files in the current source directory that match the regular "
- "expression will be installed.\n"
- " install_files(<dir> FILES file file ...)\n"
- "Any files listed after the FILES keyword will be "
- "installed explicitly from the names given. Full paths are allowed in "
- "this form.\n"
- "The directory <dir> is relative to the installation prefix, which "
- "is stored in the variable CMAKE_INSTALL_PREFIX.";
- }
-
- /** This command is kept for compatibility with older CMake versions. */
- virtual bool IsDiscouraged() const
- {
- return true;
- }
-
cmTypeMacro(cmInstallFilesCommand, cmCommand);
protected:
diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx
index ec02bc76a..383031b7f 100644
--- a/Source/cmInstallFilesGenerator.cxx
+++ b/Source/cmInstallFilesGenerator.cxx
@@ -11,6 +11,11 @@
============================================================================*/
#include "cmInstallFilesGenerator.h"
+#include "cmGeneratorExpression.h"
+#include "cmMakefile.h"
+#include "cmSystemTools.h"
+#include "cmLocalGenerator.h"
+
//----------------------------------------------------------------------------
cmInstallFilesGenerator
::cmInstallFilesGenerator(std::vector<std::string> const& files,
@@ -18,13 +23,32 @@ cmInstallFilesGenerator
const char* file_permissions,
std::vector<std::string> const& configurations,
const char* component,
+ MessageLevel message,
const char* rename,
bool optional):
- cmInstallGenerator(dest, configurations, component),
- Files(files), Programs(programs),
+ cmInstallGenerator(dest, configurations, component, message),
+ LocalGenerator(0),
+ Files(files),
FilePermissions(file_permissions),
- Rename(rename), Optional(optional)
+ Rename(rename),
+ Programs(programs),
+ Optional(optional)
{
+ // We need per-config actions if the destination has generator expressions.
+ if(cmGeneratorExpression::Find(Destination) != std::string::npos)
+ {
+ this->ActionsPerConfig = true;
+ }
+
+ // We need per-config actions if any files have generator expressions.
+ for(std::vector<std::string>::const_iterator i = files.begin();
+ !this->ActionsPerConfig && i != files.end(); ++i)
+ {
+ if(cmGeneratorExpression::Find(*i) != std::string::npos)
+ {
+ this->ActionsPerConfig = true;
+ }
+ }
}
//----------------------------------------------------------------------------
@@ -33,18 +57,67 @@ cmInstallFilesGenerator
{
}
+void cmInstallFilesGenerator::Compute(cmLocalGenerator* lg)
+{
+ this->LocalGenerator = lg;
+}
+
//----------------------------------------------------------------------------
-void cmInstallFilesGenerator::GenerateScriptActions(std::ostream& os,
- Indent const& indent)
+std::string
+cmInstallFilesGenerator::GetDestination(std::string const& config) const
+{
+ cmGeneratorExpression ge;
+ return ge.Parse(this->Destination)
+ ->Evaluate(this->LocalGenerator, config);
+}
+
+//----------------------------------------------------------------------------
+void cmInstallFilesGenerator::AddFilesInstallRule(
+ std::ostream& os,
+ const std::string config,
+ Indent const& indent,
+ std::vector<std::string> const& files)
{
// Write code to install the files.
const char* no_dir_permissions = 0;
this->AddInstallRule(os,
+ this->GetDestination(config),
(this->Programs
? cmInstallType_PROGRAMS
: cmInstallType_FILES),
- this->Files,
+ files,
this->Optional,
this->FilePermissions.c_str(), no_dir_permissions,
this->Rename.c_str(), 0, indent);
}
+
+//----------------------------------------------------------------------------
+void cmInstallFilesGenerator::GenerateScriptActions(std::ostream& os,
+ Indent const& indent)
+{
+ if(this->ActionsPerConfig)
+ {
+ this->cmInstallGenerator::GenerateScriptActions(os, indent);
+ }
+ else
+ {
+ this->AddFilesInstallRule(os, "", indent, this->Files);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmInstallFilesGenerator::GenerateScriptForConfig(std::ostream& os,
+ const std::string& config,
+ Indent const& indent)
+{
+ std::vector<std::string> files;
+ cmGeneratorExpression ge;
+ for(std::vector<std::string>::const_iterator i = this->Files.begin();
+ i != this->Files.end(); ++i)
+ {
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*i);
+ cmSystemTools::ExpandListArgument(cge->Evaluate(
+ this->LocalGenerator, config), files);
+ }
+ this->AddFilesInstallRule(os, config, indent, files);
+}
diff --git a/Source/cmInstallFilesGenerator.h b/Source/cmInstallFilesGenerator.h
index 871335c64..bfe403924 100644
--- a/Source/cmInstallFilesGenerator.h
+++ b/Source/cmInstallFilesGenerator.h
@@ -25,16 +25,30 @@ public:
const char* file_permissions,
std::vector<std::string> const& configurations,
const char* component,
+ MessageLevel message,
const char* rename,
bool optional = false);
virtual ~cmInstallFilesGenerator();
+ void Compute(cmLocalGenerator* lg);
+
+ std::string GetDestination(std::string const& config) const;
+
protected:
virtual void GenerateScriptActions(std::ostream& os, Indent const& indent);
+ virtual void GenerateScriptForConfig(std::ostream& os,
+ const std::string& config,
+ Indent const& indent);
+ void AddFilesInstallRule(std::ostream& os,
+ const std::string config,
+ Indent const& indent,
+ std::vector<std::string> const& files);
+
+ cmLocalGenerator* LocalGenerator;
std::vector<std::string> Files;
- bool Programs;
std::string FilePermissions;
std::string Rename;
+ bool Programs;
bool Optional;
};
diff --git a/Source/cmInstallGenerator.cxx b/Source/cmInstallGenerator.cxx
index 3be2c2b14..2e1c5f05f 100644
--- a/Source/cmInstallGenerator.cxx
+++ b/Source/cmInstallGenerator.cxx
@@ -11,16 +11,19 @@
============================================================================*/
#include "cmInstallGenerator.h"
+#include "cmMakefile.h"
#include "cmSystemTools.h"
//----------------------------------------------------------------------------
cmInstallGenerator
::cmInstallGenerator(const char* destination,
std::vector<std::string> const& configurations,
- const char* component):
+ const char* component,
+ MessageLevel message):
cmScriptGenerator("CMAKE_INSTALL_CONFIG_NAME", configurations),
Destination(destination? destination:""),
- Component(component? component:"")
+ Component(component? component:""),
+ Message(message)
{
}
@@ -34,6 +37,7 @@ cmInstallGenerator
void cmInstallGenerator
::AddInstallRule(
std::ostream& os,
+ std::string const& dest,
cmInstallType type,
std::vector<std::string> const& files,
bool optional /* = false */,
@@ -57,7 +61,6 @@ void cmInstallGenerator
case cmInstallType_FILES: stype = "FILE"; break;
}
os << indent;
- std::string dest = this->GetInstallDestination();
if (cmSystemTools::FileIsFullPath(dest.c_str()))
{
os << "list(APPEND CMAKE_ABSOLUTE_DESTINATION_FILES\n";
@@ -80,22 +83,30 @@ void cmInstallGenerator
}
}
os << "\")\n";
- os << indent << "IF (CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION)\n";
+ os << indent << "if(CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION)\n";
os << indent << indent << "message(WARNING \"ABSOLUTE path INSTALL "
<< "DESTINATION : ${CMAKE_ABSOLUTE_DESTINATION_FILES}\")\n";
- os << indent << "ENDIF (CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION)\n";
+ os << indent << "endif()\n";
- os << indent << "IF (CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION)\n";
+ os << indent << "if(CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION)\n";
os << indent << indent << "message(FATAL_ERROR \"ABSOLUTE path INSTALL "
<< "DESTINATION forbidden (by caller): "
<< "${CMAKE_ABSOLUTE_DESTINATION_FILES}\")\n";
- os << indent << "ENDIF (CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION)\n";
+ os << indent << "endif()\n";
}
- os << "FILE(INSTALL DESTINATION \"" << dest << "\" TYPE " << stype.c_str();
+ std::string absDest = this->ConvertToAbsoluteDestination(dest);
+ os << "file(INSTALL DESTINATION \"" << absDest << "\" TYPE " << stype;
if(optional)
{
os << " OPTIONAL";
}
+ switch(this->Message)
+ {
+ case MessageDefault: break;
+ case MessageAlways: os << " MESSAGE_ALWAYS"; break;
+ case MessageLazy: os << " MESSAGE_LAZY"; break;
+ case MessageNever: os << " MESSAGE_NEVER"; break;
+ }
if(permissions_file && *permissions_file)
{
os << " PERMISSIONS" << permissions_file;
@@ -153,30 +164,55 @@ void cmInstallGenerator::GenerateScript(std::ostream& os)
// Begin this block of installation.
std::string component_test =
this->CreateComponentTest(this->Component.c_str());
- os << indent << "IF(" << component_test << ")\n";
+ os << indent << "if(" << component_test << ")\n";
// Generate the script possibly with per-configuration code.
this->GenerateScriptConfigs(os, indent.Next());
// End this block of installation.
- os << indent << "ENDIF(" << component_test << ")\n\n";
+ os << indent << "endif()\n\n";
}
//----------------------------------------------------------------------------
-bool cmInstallGenerator::InstallsForConfig(const char* config)
+bool cmInstallGenerator::InstallsForConfig(const std::string& config)
{
return this->GeneratesForConfig(config);
}
//----------------------------------------------------------------------------
-std::string cmInstallGenerator::GetInstallDestination() const
+std::string
+cmInstallGenerator::ConvertToAbsoluteDestination(std::string const& dest) const
{
std::string result;
- if(!this->Destination.empty() &&
- !cmSystemTools::FileIsFullPath(this->Destination.c_str()))
+ if(!dest.empty() &&
+ !cmSystemTools::FileIsFullPath(dest.c_str()))
{
result = "${CMAKE_INSTALL_PREFIX}/";
}
- result += this->Destination;
+ result += dest;
return result;
}
+
+//----------------------------------------------------------------------------
+cmInstallGenerator::MessageLevel
+cmInstallGenerator::SelectMessageLevel(cmMakefile* mf, bool never)
+{
+ if(never)
+ {
+ return MessageNever;
+ }
+ std::string m = mf->GetSafeDefinition("CMAKE_INSTALL_MESSAGE");
+ if(m == "ALWAYS")
+ {
+ return MessageAlways;
+ }
+ if(m == "LAZY")
+ {
+ return MessageLazy;
+ }
+ if(m == "NEVER")
+ {
+ return MessageNever;
+ }
+ return MessageDefault;
+}
diff --git a/Source/cmInstallGenerator.h b/Source/cmInstallGenerator.h
index c89ab8ac5..b8e5b53cb 100644
--- a/Source/cmInstallGenerator.h
+++ b/Source/cmInstallGenerator.h
@@ -16,6 +16,7 @@
#include "cmScriptGenerator.h"
class cmLocalGenerator;
+class cmMakefile;
/** \class cmInstallGenerator
* \brief Support class for generating install scripts.
@@ -24,13 +25,24 @@ class cmLocalGenerator;
class cmInstallGenerator: public cmScriptGenerator
{
public:
+ enum MessageLevel
+ {
+ MessageDefault,
+ MessageAlways,
+ MessageLazy,
+ MessageNever
+ };
+
cmInstallGenerator(const char* destination,
std::vector<std::string> const& configurations,
- const char* component);
+ const char* component,
+ MessageLevel message);
virtual ~cmInstallGenerator();
void AddInstallRule(
- std::ostream& os, cmInstallType type,
+ std::ostream& os,
+ std::string const& dest,
+ cmInstallType type,
std::vector<std::string> const& files,
bool optional = false,
const char* permissions_file = 0,
@@ -40,15 +52,17 @@ public:
Indent const& indent = Indent()
);
- const char* GetDestination() const
- { return this->Destination.c_str(); }
-
/** Get the install destination as it should appear in the
installation script. */
- std::string GetInstallDestination() const;
+ std::string ConvertToAbsoluteDestination(std::string const& dest) const;
/** Test if this generator installs something for a given configuration. */
- bool InstallsForConfig(const char*);
+ bool InstallsForConfig(const std::string& config);
+
+ /** Select message level from CMAKE_INSTALL_MESSAGE or 'never'. */
+ static MessageLevel SelectMessageLevel(cmMakefile* mf, bool never = false);
+
+ virtual void Compute(cmLocalGenerator*) {}
protected:
virtual void GenerateScript(std::ostream& os);
@@ -58,6 +72,7 @@ protected:
// Information shared by most generator types.
std::string Destination;
std::string Component;
+ MessageLevel Message;
};
#endif
diff --git a/Source/cmInstallProgramsCommand.cxx b/Source/cmInstallProgramsCommand.cxx
index 3a0a3223b..e6fbe8864 100644
--- a/Source/cmInstallProgramsCommand.cxx
+++ b/Source/cmInstallProgramsCommand.cxx
@@ -22,18 +22,13 @@ bool cmInstallProgramsCommand
}
// Enable the install target.
- this->Makefile->GetLocalGenerator()
- ->GetGlobalGenerator()->EnableInstallTarget();
+ this->Makefile->GetGlobalGenerator()->EnableInstallTarget();
this->Destination = args[0];
- std::vector<std::string>::const_iterator s = args.begin();
- for (++s;s != args.end(); ++s)
- {
- this->FinalArgs.push_back(*s);
- }
+ this->FinalArgs.insert(this->FinalArgs.end(), args.begin() + 1, args.end());
- this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ this->Makefile->GetGlobalGenerator()
->AddInstallComponent(this->Makefile->GetSafeDefinition(
"CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"));
@@ -67,8 +62,8 @@ void cmInstallProgramsCommand::FinalPass()
else // reg exp list
{
std::vector<std::string> programs;
- cmSystemTools::Glob(this->Makefile->GetCurrentDirectory(),
- this->FinalArgs[0].c_str(), programs);
+ cmSystemTools::Glob(this->Makefile->GetCurrentSourceDirectory(),
+ this->FinalArgs[0], programs);
std::vector<std::string>::iterator s = programs.begin();
// for each argument, get the programs
@@ -93,11 +88,13 @@ void cmInstallProgramsCommand::FinalPass()
std::string no_component = this->Makefile->GetSafeDefinition(
"CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
std::vector<std::string> no_configurations;
+ cmInstallGenerator::MessageLevel message =
+ cmInstallGenerator::SelectMessageLevel(this->Makefile);
this->Makefile->AddInstallGenerator(
new cmInstallFilesGenerator(this->Files,
destination.c_str(), true,
no_permissions, no_configurations,
- no_component.c_str(), no_rename));
+ no_component.c_str(), message, no_rename));
}
/**
@@ -109,17 +106,18 @@ void cmInstallProgramsCommand::FinalPass()
std::string cmInstallProgramsCommand
::FindInstallSource(const char* name) const
{
- if(cmSystemTools::FileIsFullPath(name))
+ if(cmSystemTools::FileIsFullPath(name) ||
+ cmGeneratorExpression::Find(name) == 0)
{
// This is a full path.
return name;
}
// This is a relative path.
- std::string tb = this->Makefile->GetCurrentOutputDirectory();
+ std::string tb = this->Makefile->GetCurrentBinaryDirectory();
tb += "/";
tb += name;
- std::string ts = this->Makefile->GetCurrentDirectory();
+ std::string ts = this->Makefile->GetCurrentSourceDirectory();
ts += "/";
ts += name;
diff --git a/Source/cmInstallProgramsCommand.h b/Source/cmInstallProgramsCommand.h
index 27a0498e5..524debf8e 100644
--- a/Source/cmInstallProgramsCommand.h
+++ b/Source/cmInstallProgramsCommand.h
@@ -41,15 +41,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "install_programs";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Deprecated. Use the install(PROGRAMS ) command instead.";
- }
+ virtual std::string GetName() const { return "install_programs";}
/**
* This is called at the end after all the information
@@ -61,39 +53,6 @@ public:
virtual bool HasFinalPass() const { return true; }
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- "This command has been superceded by the install command. It "
- "is provided for compatibility with older CMake code. "
- "The FILES form is directly replaced by the PROGRAMS form of the "
- "INSTALL command. The regexp form can be expressed more clearly "
- "using the GLOB form of the FILE command.\n"
- " install_programs(<dir> file1 file2 [file3 ...])\n"
- " install_programs(<dir> FILES file1 [file2 ...])\n"
- "Create rules to install the listed programs into the given directory. "
- "Use the FILES argument to guarantee that the file list version of "
- "the command will be used even when there is only one argument.\n"
- " install_programs(<dir> regexp)\n"
- "In the second form any program in the current source directory that "
- "matches the regular expression will be installed.\n"
- "This command is intended to install programs that are not built "
- "by cmake, such as shell scripts. See the TARGETS form of "
- "the INSTALL command to "
- "create installation rules for targets built by cmake.\n"
- "The directory <dir> is relative to the installation prefix, which "
- "is stored in the variable CMAKE_INSTALL_PREFIX.";
- }
-
- /** This command is kept for compatibility with older CMake versions. */
- virtual bool IsDiscouraged() const
- {
- return true;
- }
-
cmTypeMacro(cmInstallProgramsCommand, cmCommand);
protected:
diff --git a/Source/cmInstallScriptGenerator.cxx b/Source/cmInstallScriptGenerator.cxx
index bcfbe63c5..933aa0782 100644
--- a/Source/cmInstallScriptGenerator.cxx
+++ b/Source/cmInstallScriptGenerator.cxx
@@ -15,7 +15,7 @@
cmInstallScriptGenerator
::cmInstallScriptGenerator(const char* script, bool code,
const char* component) :
- cmInstallGenerator(0, std::vector<std::string>(), component),
+ cmInstallGenerator(0, std::vector<std::string>(), component, MessageDefault),
Script(script), Code(code)
{
}
@@ -32,7 +32,7 @@ void cmInstallScriptGenerator::GenerateScript(std::ostream& os)
Indent indent;
std::string component_test =
this->CreateComponentTest(this->Component.c_str());
- os << indent << "IF(" << component_test << ")\n";
+ os << indent << "if(" << component_test << ")\n";
if(this->Code)
{
@@ -40,8 +40,8 @@ void cmInstallScriptGenerator::GenerateScript(std::ostream& os)
}
else
{
- os << indent.Next() << "INCLUDE(\"" << this->Script << "\")\n";
+ os << indent.Next() << "include(\"" << this->Script << "\")\n";
}
- os << indent << "ENDIF(" << component_test << ")\n\n";
+ os << indent << "endif()\n\n";
}
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index c9624c8e0..5e88fa2c7 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -12,25 +12,34 @@
#include "cmInstallTargetGenerator.h"
#include "cmComputeLinkInformation.h"
+#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#include "cmGeneratorTarget.h"
#include "cmake.h"
+#include "cmGeneratorTarget.h"
#include <assert.h>
//----------------------------------------------------------------------------
cmInstallTargetGenerator
-::cmInstallTargetGenerator(cmTarget& t, const char* dest, bool implib,
+::cmInstallTargetGenerator(const std::string& targetName,
+ const char* dest, bool implib,
const char* file_permissions,
std::vector<std::string> const& configurations,
- const char* component, bool optional):
- cmInstallGenerator(dest, configurations, component), Target(&t),
- ImportLibrary(implib), FilePermissions(file_permissions), Optional(optional)
+ const char* component,
+ MessageLevel message,
+ bool optional):
+ cmInstallGenerator(dest, configurations, component, message),
+ TargetName(targetName),
+ Target(0),
+ FilePermissions(file_permissions),
+ ImportLibrary(implib),
+ Optional(optional)
{
this->ActionsPerConfig = true;
this->NamelinkMode = NamelinkModeNone;
- this->Target->SetHaveInstallRule(true);
}
//----------------------------------------------------------------------------
@@ -45,7 +54,7 @@ void cmInstallTargetGenerator::GenerateScript(std::ostream& os)
// Warn if installing an exclude-from-all target.
if(this->Target->GetPropertyAsBool("EXCLUDE_FROM_ALL"))
{
- cmOStringStream msg;
+ std::ostringstream msg;
msg << "WARNING: Target \"" << this->Target->GetName()
<< "\" has EXCLUDE_FROM_ALL set and will not be built by default "
<< "but an install rule has been provided for it. CMake does "
@@ -59,46 +68,54 @@ void cmInstallTargetGenerator::GenerateScript(std::ostream& os)
//----------------------------------------------------------------------------
void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
- const char* config,
- Indent const& indent)
+ const std::string& config,
+ Indent const& indent)
{
// Compute the build tree directory from which to copy the target.
std::string fromDirConfig;
if(this->Target->NeedRelinkBeforeInstall(config))
{
- fromDirConfig = this->Target->GetMakefile()->GetStartOutputDirectory();
+ fromDirConfig =
+ this->Target->GetLocalGenerator()->GetCurrentBinaryDirectory();
fromDirConfig += cmake::GetCMakeFilesDirectory();
fromDirConfig += "/CMakeRelink.dir/";
}
else
{
- fromDirConfig = this->Target->GetDirectory(config, this->ImportLibrary);
+ fromDirConfig =
+ this->Target->GetDirectory(config, this->ImportLibrary);
fromDirConfig += "/";
}
- std::string toDir = this->GetInstallDestination();
+ std::string toDir =
+ this->ConvertToAbsoluteDestination(this->GetDestination(config));
toDir += "/";
// Compute the list of files to install for this target.
std::vector<std::string> filesFrom;
std::vector<std::string> filesTo;
std::string literal_args;
- cmTarget::TargetType targetType = this->Target->GetType();
+ cmState::TargetType targetType = this->Target->GetType();
cmInstallType type = cmInstallType();
switch(targetType)
{
- case cmTarget::EXECUTABLE: type = cmInstallType_EXECUTABLE; break;
- case cmTarget::STATIC_LIBRARY: type = cmInstallType_STATIC_LIBRARY; break;
- case cmTarget::SHARED_LIBRARY: type = cmInstallType_SHARED_LIBRARY; break;
- case cmTarget::MODULE_LIBRARY: type = cmInstallType_MODULE_LIBRARY; break;
- case cmTarget::OBJECT_LIBRARY:
- case cmTarget::UTILITY:
- case cmTarget::GLOBAL_TARGET:
- case cmTarget::UNKNOWN_LIBRARY:
- this->Target->GetMakefile()->IssueMessage(cmake::INTERNAL_ERROR,
+ case cmState::EXECUTABLE: type = cmInstallType_EXECUTABLE; break;
+ case cmState::STATIC_LIBRARY: type = cmInstallType_STATIC_LIBRARY; break;
+ case cmState::SHARED_LIBRARY: type = cmInstallType_SHARED_LIBRARY; break;
+ case cmState::MODULE_LIBRARY: type = cmInstallType_MODULE_LIBRARY; break;
+ case cmState::INTERFACE_LIBRARY:
+ // Not reachable. We never create a cmInstallTargetGenerator for
+ // an INTERFACE_LIBRARY.
+ assert(0 && "INTERFACE_LIBRARY targets have no installable outputs.");
+ break;
+ case cmState::OBJECT_LIBRARY:
+ case cmState::UTILITY:
+ case cmState::GLOBAL_TARGET:
+ case cmState::UNKNOWN_LIBRARY:
+ this->Target->GetLocalGenerator()->IssueMessage(cmake::INTERNAL_ERROR,
"cmInstallTargetGenerator created with non-installable target.");
return;
}
- if(targetType == cmTarget::EXECUTABLE)
+ if(targetType == cmState::EXECUTABLE)
{
// There is a bug in cmInstallCommand if this fails.
assert(this->NamelinkMode == NamelinkModeNone);
@@ -135,13 +152,19 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
// Handle OSX Bundles.
if(this->Target->IsAppBundleOnApple())
{
+ cmMakefile const* mf = this->Target->Target->GetMakefile();
+
// Install the whole app bundle directory.
type = cmInstallType_DIRECTORY;
literal_args += " USE_SOURCE_PERMISSIONS";
from1 += ".app";
// Tweaks apply to the binary inside the bundle.
- to1 += ".app/Contents/MacOS/";
+ to1 += ".app/";
+ if(!mf->PlatformIsAppleIos())
+ {
+ to1 += "Contents/MacOS/";
+ }
to1 += targetName;
}
else
@@ -167,7 +190,8 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
std::string targetNameReal;
std::string targetNameImport;
std::string targetNamePDB;
- this->Target->GetLibraryNames(targetName, targetNameSO, targetNameReal,
+ this->Target->GetLibraryNames(targetName, targetNameSO,
+ targetNameReal,
targetNameImport, targetNamePDB,
config);
if(this->ImportLibrary)
@@ -208,6 +232,20 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
filesFrom.push_back(from1);
filesTo.push_back(to1);
}
+ else if(this->Target->IsCFBundleOnApple())
+ {
+ // Install the whole app bundle directory.
+ type = cmInstallType_DIRECTORY;
+ literal_args += " USE_SOURCE_PERMISSIONS";
+
+ std::string targetNameBase = targetName.substr(0, targetName.find('/'));
+
+ std::string from1 = fromDirConfig + targetNameBase;
+ std::string to1 = toDir + targetName;
+
+ filesFrom.push_back(from1);
+ filesTo.push_back(to1);
+ }
else
{
bool haveNamelink = false;
@@ -301,8 +339,8 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
const char* no_dir_permissions = 0;
const char* no_rename = 0;
bool optional = this->Optional || this->ImportLibrary;
- this->AddInstallRule(os, type, filesFrom,
- optional,
+ this->AddInstallRule(os, this->GetDestination(config),
+ type, filesFrom, optional,
this->FilePermissions.c_str(), no_dir_permissions,
no_rename, literal_args.c_str(),
indent);
@@ -314,7 +352,16 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
//----------------------------------------------------------------------------
std::string
-cmInstallTargetGenerator::GetInstallFilename(const char* config) const
+cmInstallTargetGenerator::GetDestination(std::string const& config) const
+{
+ cmGeneratorExpression ge;
+ return ge.Parse(this->Destination)
+ ->Evaluate(this->Target->GetLocalGenerator(), config);
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmInstallTargetGenerator::GetInstallFilename(const std::string& config) const
{
NameType nameType = this->ImportLibrary? NameImplib : NameNormal;
return
@@ -323,13 +370,14 @@ cmInstallTargetGenerator::GetInstallFilename(const char* config) const
}
//----------------------------------------------------------------------------
-std::string cmInstallTargetGenerator::GetInstallFilename(cmTarget* target,
- const char* config,
- NameType nameType)
+std::string
+cmInstallTargetGenerator::GetInstallFilename(cmGeneratorTarget const* target,
+ const std::string& config,
+ NameType nameType)
{
std::string fname;
// Compute the name of the library.
- if(target->GetType() == cmTarget::EXECUTABLE)
+ if(target->GetType() == cmState::EXECUTABLE)
{
std::string targetName;
std::string targetNameReal;
@@ -396,28 +444,33 @@ std::string cmInstallTargetGenerator::GetInstallFilename(cmTarget* target,
return fname;
}
+void cmInstallTargetGenerator::Compute(cmLocalGenerator* lg)
+{
+ this->Target = lg->FindGeneratorTarget(this->TargetName);
+}
+
//----------------------------------------------------------------------------
void
cmInstallTargetGenerator
-::AddTweak(std::ostream& os, Indent const& indent, const char* config,
+::AddTweak(std::ostream& os, Indent const& indent, const std::string& config,
std::string const& file, TweakMethod tweak)
{
- cmOStringStream tw;
+ std::ostringstream tw;
(this->*tweak)(tw, indent.Next(), config, file);
std::string tws = tw.str();
if(!tws.empty())
{
- os << indent << "IF(EXISTS \"" << file << "\" AND\n"
+ os << indent << "if(EXISTS \"" << file << "\" AND\n"
<< indent << " NOT IS_SYMLINK \"" << file << "\")\n";
os << tws;
- os << indent << "ENDIF()\n";
+ os << indent << "endif()\n";
}
}
//----------------------------------------------------------------------------
void
cmInstallTargetGenerator
-::AddTweak(std::ostream& os, Indent const& indent, const char* config,
+::AddTweak(std::ostream& os, Indent const& indent, const std::string& config,
std::vector<std::string> const& files, TweakMethod tweak)
{
if(files.size() == 1)
@@ -428,13 +481,13 @@ cmInstallTargetGenerator
else
{
// Generate a foreach loop to tweak multiple files.
- cmOStringStream tw;
+ std::ostringstream tw;
this->AddTweak(tw, indent.Next(), config, "${file}", tweak);
std::string tws = tw.str();
if(!tws.empty())
{
Indent indent2 = indent.Next().Next();
- os << indent << "FOREACH(file\n";
+ os << indent << "foreach(file\n";
for(std::vector<std::string>::const_iterator i = files.begin();
i != files.end(); ++i)
{
@@ -442,7 +495,7 @@ cmInstallTargetGenerator
}
os << indent2 << ")\n";
os << tws;
- os << indent << "ENDFOREACH()\n";
+ os << indent << "endforeach()\n";
}
}
}
@@ -464,7 +517,7 @@ std::string cmInstallTargetGenerator::GetDestDirPath(std::string const& file)
//----------------------------------------------------------------------------
void cmInstallTargetGenerator::PreReplacementTweaks(std::ostream& os,
Indent const& indent,
- const char* config,
+ const std::string& config,
std::string const& file)
{
this->AddRPathCheckRule(os, indent, config, file);
@@ -472,12 +525,13 @@ void cmInstallTargetGenerator::PreReplacementTweaks(std::ostream& os,
//----------------------------------------------------------------------------
void cmInstallTargetGenerator::PostReplacementTweaks(std::ostream& os,
- Indent const& indent,
- const char* config,
- std::string const& file)
+ Indent const& indent,
+ const std::string& config,
+ std::string const& file)
{
this->AddInstallNamePatchRule(os, indent, config, file);
this->AddChrpathPatchRule(os, indent, config, file);
+ this->AddUniversalInstallRule(os, indent, file);
this->AddRanlibRule(os, indent, file);
this->AddStripRule(os, indent, file);
}
@@ -486,35 +540,37 @@ void cmInstallTargetGenerator::PostReplacementTweaks(std::ostream& os,
void
cmInstallTargetGenerator
::AddInstallNamePatchRule(std::ostream& os, Indent const& indent,
- const char* config, std::string const& toDestDirPath)
+ const std::string& config,
+ std::string const& toDestDirPath)
{
if(this->ImportLibrary ||
- !(this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
- this->Target->GetType() == cmTarget::MODULE_LIBRARY ||
- this->Target->GetType() == cmTarget::EXECUTABLE))
+ !(this->Target->GetType() == cmState::SHARED_LIBRARY ||
+ this->Target->GetType() == cmState::MODULE_LIBRARY ||
+ this->Target->GetType() == cmState::EXECUTABLE))
{
return;
}
// Fix the install_name settings in installed binaries.
- std::string installNameTool =
- this->Target->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL");
+ std::string installNameTool = this->Target->Target->GetMakefile()
+ ->GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL");
- if(!installNameTool.size())
+ if(installNameTool.empty())
{
return;
}
// Build a map of build-tree install_name to install-tree install_name for
// shared libraries linked to this target.
- std::map<cmStdString, cmStdString> install_name_remap;
+ std::map<std::string, std::string> install_name_remap;
if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(config))
{
- std::set<cmTarget*> const& sharedLibs = cli->GetSharedLibrariesLinked();
- for(std::set<cmTarget*>::const_iterator j = sharedLibs.begin();
- j != sharedLibs.end(); ++j)
+ std::set<cmGeneratorTarget const*> const& sharedLibs
+ = cli->GetSharedLibrariesLinked();
+ for(std::set<cmGeneratorTarget const*>::const_iterator j
+ = sharedLibs.begin(); j != sharedLibs.end(); ++j)
{
- cmTarget* tgt = *j;
+ cmGeneratorTarget const* tgt = *j;
// The install_name of an imported target does not change.
if(tgt->IsImported())
@@ -548,7 +604,7 @@ cmInstallTargetGenerator
// Edit the install_name of the target itself if necessary.
std::string new_id;
- if(this->Target->GetType() == cmTarget::SHARED_LIBRARY)
+ if(this->Target->GetType() == cmState::SHARED_LIBRARY)
{
std::string for_build =
this->Target->GetInstallNameDirForBuildTree(config);
@@ -577,13 +633,13 @@ cmInstallTargetGenerator
// install_name value and references.
if(!new_id.empty() || !install_name_remap.empty())
{
- os << indent << "EXECUTE_PROCESS(COMMAND \"" << installNameTool;
+ os << indent << "execute_process(COMMAND \"" << installNameTool;
os << "\"";
if(!new_id.empty())
{
os << "\n" << indent << " -id \"" << new_id << "\"";
}
- for(std::map<cmStdString, cmStdString>::const_iterator
+ for(std::map<std::string, std::string>::const_iterator
i = install_name_remap.begin();
i != install_name_remap.end(); ++i)
{
@@ -598,16 +654,17 @@ cmInstallTargetGenerator
void
cmInstallTargetGenerator
::AddRPathCheckRule(std::ostream& os, Indent const& indent,
- const char* config, std::string const& toDestDirPath)
+ const std::string& config,
+ std::string const& toDestDirPath)
{
// Skip the chrpath if the target does not need it.
if(this->ImportLibrary || !this->Target->IsChrpathUsed(config))
{
return;
}
-
// Skip if on Apple
- if(this->Target->GetMakefile()->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
+ if(this->Target->Target->GetMakefile()
+ ->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
{
return;
}
@@ -626,7 +683,7 @@ cmInstallTargetGenerator
// Write a rule to remove the installed file if its rpath is not the
// new rpath. This is needed for existing build/install trees when
// the installed rpath changes but the file is not rebuilt.
- os << indent << "FILE(RPATH_CHECK\n"
+ os << indent << "file(RPATH_CHECK\n"
<< indent << " FILE \"" << toDestDirPath << "\"\n"
<< indent << " RPATH \"" << newRpath << "\")\n";
}
@@ -635,7 +692,8 @@ cmInstallTargetGenerator
void
cmInstallTargetGenerator
::AddChrpathPatchRule(std::ostream& os, Indent const& indent,
- const char* config, std::string const& toDestDirPath)
+ const std::string& config,
+ std::string const& toDestDirPath)
{
// Skip the chrpath if the target does not need it.
if(this->ImportLibrary || !this->Target->IsChrpathUsed(config))
@@ -651,33 +709,71 @@ cmInstallTargetGenerator
return;
}
- if(this->Target->GetMakefile()->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
+ cmMakefile* mf = this->Target->Target->GetMakefile();
+
+ if(mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
{
// If using install_name_tool, set up the rules to modify the rpaths.
std::string installNameTool =
- this->Target->GetMakefile()->
- GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL");
+ mf->GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL");
std::vector<std::string> oldRuntimeDirs, newRuntimeDirs;
cli->GetRPath(oldRuntimeDirs, false);
cli->GetRPath(newRuntimeDirs, true);
- // Note: These are separate commands to avoid install_name_tool
- // corruption on 10.6.
- for(std::vector<std::string>::const_iterator i = oldRuntimeDirs.begin();
- i != oldRuntimeDirs.end(); ++i)
+ std::string darwin_major_version_s =
+ mf->GetSafeDefinition("DARWIN_MAJOR_VERSION");
+
+ std::stringstream ss(darwin_major_version_s);
+ int darwin_major_version;
+ ss >> darwin_major_version;
+ if(!ss.fail() && darwin_major_version <= 9 &&
+ (!oldRuntimeDirs.empty() || !newRuntimeDirs.empty())
+ )
{
- os << indent << "execute_process(COMMAND " << installNameTool << "\n";
- os << indent << " -delete_rpath \"" << *i << "\"\n";
- os << indent << " \"" << toDestDirPath << "\")\n";
+ std::ostringstream msg;
+ msg << "WARNING: Target \"" << this->Target->GetName()
+ << "\" has runtime paths which cannot be changed during install. "
+ << "To change runtime paths, OS X version 10.6 or newer is required. "
+ << "Therefore, runtime paths will not be changed when installing. "
+ << "CMAKE_BUILD_WITH_INSTALL_RPATH may be used to work around"
+ " this limitation.";
+ mf->IssueMessage(cmake::WARNING, msg.str());
}
-
- for(std::vector<std::string>::const_iterator i = newRuntimeDirs.begin();
- i != newRuntimeDirs.end(); ++i)
+ else
{
- os << indent << "execute_process(COMMAND " << installNameTool << "\n";
- os << indent << " -add_rpath \"" << *i << "\"\n";
- os << indent << " \"" << toDestDirPath << "\")\n";
+ // Note: These paths are kept unique to avoid
+ // install_name_tool corruption.
+ std::set<std::string> runpaths;
+ for(std::vector<std::string>::const_iterator i = oldRuntimeDirs.begin();
+ i != oldRuntimeDirs.end(); ++i)
+ {
+ std::string runpath =
+ mf->GetGlobalGenerator()->ExpandCFGIntDir(*i, config);
+
+ if(runpaths.find(runpath) == runpaths.end())
+ {
+ runpaths.insert(runpath);
+ os << indent << "execute_process(COMMAND " << installNameTool <<"\n";
+ os << indent << " -delete_rpath \"" << runpath << "\"\n";
+ os << indent << " \"" << toDestDirPath << "\")\n";
+ }
+ }
+
+ runpaths.clear();
+ for(std::vector<std::string>::const_iterator i = newRuntimeDirs.begin();
+ i != newRuntimeDirs.end(); ++i)
+ {
+ std::string runpath =
+ mf->GetGlobalGenerator()->ExpandCFGIntDir(*i, config);
+
+ if(runpaths.find(runpath) == runpaths.end())
+ {
+ os << indent << "execute_process(COMMAND " << installNameTool <<"\n";
+ os << indent << " -add_rpath \"" << runpath << "\"\n";
+ os << indent << " \"" << toDestDirPath << "\")\n";
+ }
+ }
}
}
else
@@ -695,18 +791,10 @@ cmInstallTargetGenerator
}
// Write a rule to run chrpath to set the install-tree RPATH
- if(newRpath.empty())
- {
- os << indent << "FILE(RPATH_REMOVE\n"
- << indent << " FILE \"" << toDestDirPath << "\")\n";
- }
- else
- {
- os << indent << "FILE(RPATH_CHANGE\n"
- << indent << " FILE \"" << toDestDirPath << "\"\n"
- << indent << " OLD_RPATH \"" << oldRpath << "\"\n"
- << indent << " NEW_RPATH \"" << newRpath << "\")\n";
- }
+ os << indent << "file(RPATH_CHANGE\n"
+ << indent << " FILE \"" << toDestDirPath << "\"\n"
+ << indent << " OLD_RPATH \"" << oldRpath << "\"\n"
+ << indent << " NEW_RPATH \"" << newRpath << "\")\n";
}
}
@@ -719,28 +807,28 @@ cmInstallTargetGenerator::AddStripRule(std::ostream& os,
// don't strip static and import libraries, because it removes the only
// symbol table they have so you can't link to them anymore
- if(this->Target->GetType()==cmTarget::STATIC_LIBRARY || this->ImportLibrary)
+ if(this->Target->GetType()==cmState::STATIC_LIBRARY || this->ImportLibrary)
{
return;
}
// Don't handle OSX Bundles.
- if(this->Target->GetMakefile()->IsOn("APPLE") &&
+ if(this->Target->Target->GetMakefile()->IsOn("APPLE") &&
this->Target->GetPropertyAsBool("MACOSX_BUNDLE"))
{
return;
}
- if(! this->Target->GetMakefile()->IsSet("CMAKE_STRIP"))
+ if(! this->Target->Target->GetMakefile()->IsSet("CMAKE_STRIP"))
{
return;
}
- os << indent << "IF(CMAKE_INSTALL_DO_STRIP)\n";
- os << indent << " EXECUTE_PROCESS(COMMAND \""
- << this->Target->GetMakefile()->GetDefinition("CMAKE_STRIP")
+ os << indent << "if(CMAKE_INSTALL_DO_STRIP)\n";
+ os << indent << " execute_process(COMMAND \""
+ << this->Target->Target->GetMakefile()->GetDefinition("CMAKE_STRIP")
<< "\" \"" << toDestDirPath << "\")\n";
- os << indent << "ENDIF(CMAKE_INSTALL_DO_STRIP)\n";
+ os << indent << "endif()\n";
}
//----------------------------------------------------------------------------
@@ -750,25 +838,68 @@ cmInstallTargetGenerator::AddRanlibRule(std::ostream& os,
const std::string& toDestDirPath)
{
// Static libraries need ranlib on this platform.
- if(this->Target->GetType() != cmTarget::STATIC_LIBRARY)
+ if(this->Target->GetType() != cmState::STATIC_LIBRARY)
{
return;
}
// Perform post-installation processing on the file depending
// on its type.
- if(!this->Target->GetMakefile()->IsOn("APPLE"))
+ if(!this->Target->Target->GetMakefile()->IsOn("APPLE"))
{
return;
}
std::string ranlib =
- this->Target->GetMakefile()->GetRequiredDefinition("CMAKE_RANLIB");
+ this->Target->Target->GetMakefile()->GetRequiredDefinition("CMAKE_RANLIB");
if(ranlib.empty())
{
return;
}
- os << indent << "EXECUTE_PROCESS(COMMAND \""
+ os << indent << "execute_process(COMMAND \""
<< ranlib << "\" \"" << toDestDirPath << "\")\n";
}
+
+//----------------------------------------------------------------------------
+void
+cmInstallTargetGenerator
+::AddUniversalInstallRule(std::ostream& os,
+ Indent const& indent,
+ const std::string& toDestDirPath)
+{
+ cmMakefile const* mf = this->Target->Target->GetMakefile();
+
+ if(!mf->PlatformIsAppleIos() || !mf->IsOn("XCODE"))
+ {
+ return;
+ }
+
+ const char* xcodeVersion = mf->GetDefinition("XCODE_VERSION");
+ if(!xcodeVersion || cmSystemTools::VersionCompareGreater("6", xcodeVersion))
+ {
+ return;
+ }
+
+ switch(this->Target->GetType())
+ {
+ case cmState::EXECUTABLE:
+ case cmState::STATIC_LIBRARY:
+ case cmState::SHARED_LIBRARY:
+ case cmState::MODULE_LIBRARY:
+ break;
+
+ default:
+ return;
+ }
+
+ if(!this->Target->Target->GetPropertyAsBool("IOS_INSTALL_COMBINED"))
+ {
+ return;
+ }
+
+ os << indent << "include(CMakeIOSInstallCombined)\n";
+ os << indent << "ios_install_combined("
+ << "\"" << this->Target->Target->GetName() << "\" "
+ << "\"" << toDestDirPath << "\")\n";
+}
diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h
index 8cf72f975..18b313082 100644
--- a/Source/cmInstallTargetGenerator.h
+++ b/Source/cmInstallTargetGenerator.h
@@ -13,8 +13,8 @@
#define cmInstallTargetGenerator_h
#include "cmInstallGenerator.h"
-#include "cmTarget.h"
-#include "cmGeneratorTarget.h"
+
+class cmGeneratorTarget;
/** \class cmInstallTargetGenerator
* \brief Generate target installation rules.
@@ -23,12 +23,12 @@ class cmInstallTargetGenerator: public cmInstallGenerator
{
public:
cmInstallTargetGenerator(
- cmTarget& t, const char* dest, bool implib,
- const char* file_permissions = "",
- std::vector<std::string> const& configurations
- = std::vector<std::string>(),
- const char* component = "Unspecified",
- bool optional = false
+ std::string const& targetName, const char* dest, bool implib,
+ const char* file_permissions,
+ std::vector<std::string> const& configurations,
+ const char* component,
+ MessageLevel message,
+ bool optional
);
virtual ~cmInstallTargetGenerator();
@@ -43,7 +43,7 @@ public:
void SetNamelinkMode(NamelinkModeType mode) { this->NamelinkMode = mode; }
NamelinkModeType GetNamelinkMode() const { return this->NamelinkMode; }
- std::string GetInstallFilename(const char* config) const;
+ std::string GetInstallFilename(const std::string& config) const;
enum NameType
{
@@ -53,52 +53,63 @@ public:
NameReal
};
- static std::string GetInstallFilename(cmTarget*target, const char* config,
+ static std::string GetInstallFilename(const cmGeneratorTarget* target,
+ const std::string& config,
NameType nameType = NameNormal);
- cmTarget* GetTarget() const { return this->Target; }
+ void Compute(cmLocalGenerator* lg);
+
+ cmGeneratorTarget* GetTarget() const { return this->Target; }
+
bool IsImportLibrary() const { return this->ImportLibrary; }
+ std::string GetDestination(std::string const& config) const;
+
protected:
virtual void GenerateScript(std::ostream& os);
virtual void GenerateScriptForConfig(std::ostream& os,
- const char* config,
+ const std::string& config,
Indent const& indent);
typedef void (cmInstallTargetGenerator::*TweakMethod)(
- std::ostream&, Indent const&, const char*, std::string const&
+ std::ostream&, Indent const&, const std::string&, std::string const&
);
void AddTweak(std::ostream& os, Indent const& indent,
- const char* config, std::string const& file,
+ const std::string& config, std::string const& file,
TweakMethod tweak);
void AddTweak(std::ostream& os, Indent const& indent,
- const char* config, std::vector<std::string> const& files,
+ const std::string& config,
+ std::vector<std::string> const& files,
TweakMethod tweak);
std::string GetDestDirPath(std::string const& file);
void PreReplacementTweaks(std::ostream& os, Indent const& indent,
- const char* config, std::string const& file);
+ const std::string& config,
+ std::string const& file);
void PostReplacementTweaks(std::ostream& os, Indent const& indent,
- const char* config, std::string const& file);
+ const std::string& config,
+ std::string const& file);
void AddInstallNamePatchRule(std::ostream& os, Indent const& indent,
- const char* config,
+ const std::string& config,
const std::string& toDestDirPath);
void AddChrpathPatchRule(std::ostream& os, Indent const& indent,
- const char* config,
+ const std::string& config,
std::string const& toDestDirPath);
void AddRPathCheckRule(std::ostream& os, Indent const& indent,
- const char* config,
+ const std::string& config,
std::string const& toDestDirPath);
void AddStripRule(std::ostream& os, Indent const& indent,
const std::string& toDestDirPath);
void AddRanlibRule(std::ostream& os, Indent const& indent,
const std::string& toDestDirPath);
+ void AddUniversalInstallRule(std::ostream& os, Indent const& indent,
+ const std::string& toDestDirPath);
- cmTarget* Target;
- bool ImportLibrary;
+ std::string TargetName;
+ cmGeneratorTarget* Target;
std::string FilePermissions;
- bool Optional;
NamelinkModeType NamelinkMode;
- cmGeneratorTarget* GeneratorTarget;
+ bool ImportLibrary;
+ bool Optional;
};
#endif
diff --git a/Source/cmInstallTargetsCommand.cxx b/Source/cmInstallTargetsCommand.cxx
index 277ccea43..7e7b8488b 100644
--- a/Source/cmInstallTargetsCommand.cxx
+++ b/Source/cmInstallTargetsCommand.cxx
@@ -22,8 +22,7 @@ bool cmInstallTargetsCommand
}
// Enable the install target.
- this->Makefile->GetLocalGenerator()
- ->GetGlobalGenerator()->EnableInstallTarget();
+ this->Makefile->GetGlobalGenerator()->EnableInstallTarget();
cmTargets &tgts = this->Makefile->GetTargets();
std::vector<std::string>::const_iterator s = args.begin();
@@ -52,12 +51,12 @@ bool cmInstallTargetsCommand
else
{
std::string str = "Cannot find target: \"" + *s + "\" to install.";
- this->SetError(str.c_str());
+ this->SetError(str);
return false;
}
}
- this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ this->Makefile->GetGlobalGenerator()
->AddInstallComponent(this->Makefile->GetSafeDefinition(
"CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"));
diff --git a/Source/cmInstallTargetsCommand.h b/Source/cmInstallTargetsCommand.h
index c47b38700..05160eb18 100644
--- a/Source/cmInstallTargetsCommand.h
+++ b/Source/cmInstallTargetsCommand.h
@@ -42,37 +42,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "install_targets";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Deprecated. Use the install(TARGETS ) command instead.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- "This command has been superceded by the install command. It "
- "is provided for compatibility with older CMake code.\n"
- " install_targets(<dir> [RUNTIME_DIRECTORY dir] target target)\n"
- "Create rules to install the listed targets into the given directory. "
- "The directory <dir> is relative to the installation prefix, which "
- "is stored in the variable CMAKE_INSTALL_PREFIX. If RUNTIME_DIRECTORY "
- "is specified, then on systems with special runtime files "
- "(Windows DLL), the files will be copied to that directory.";
- }
-
- /** This command is kept for compatibility with older CMake versions. */
- virtual bool IsDiscouraged() const
- {
- return true;
- }
+ virtual std::string GetName() const { return "install_targets";}
cmTypeMacro(cmInstallTargetsCommand, cmCommand);
};
diff --git a/Source/cmInstalledFile.cxx b/Source/cmInstalledFile.cxx
new file mode 100644
index 000000000..fa5e81528
--- /dev/null
+++ b/Source/cmInstalledFile.cxx
@@ -0,0 +1,142 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmInstalledFile.h"
+#include "cmSystemTools.h"
+#include "cmMakefile.h"
+#include "cmAlgorithms.h"
+
+//----------------------------------------------------------------------------
+cmInstalledFile::cmInstalledFile():
+ NameExpression(0)
+{
+
+}
+
+//----------------------------------------------------------------------------
+cmInstalledFile::~cmInstalledFile()
+{
+ if(NameExpression)
+ {
+ delete NameExpression;
+ }
+}
+
+cmInstalledFile::Property::Property()
+{
+
+}
+
+cmInstalledFile::Property::~Property()
+{
+ cmDeleteAll(this->ValueExpressions);
+}
+
+//----------------------------------------------------------------------------
+void cmInstalledFile::SetName(cmMakefile* mf, const std::string& name)
+{
+ cmListFileBacktrace backtrace = mf->GetBacktrace();
+ cmGeneratorExpression ge(backtrace);
+
+ this->Name = name;
+ this->NameExpression = ge.Parse(name).release();
+}
+
+//----------------------------------------------------------------------------
+std::string const& cmInstalledFile::GetName() const
+{
+ return this->Name;
+}
+
+//----------------------------------------------------------------------------
+cmCompiledGeneratorExpression const& cmInstalledFile::GetNameExpression() const
+{
+ return *(this->NameExpression);
+}
+
+//----------------------------------------------------------------------------
+void cmInstalledFile::RemoveProperty(const std::string& prop)
+{
+ this->Properties.erase(prop);
+}
+
+//----------------------------------------------------------------------------
+void cmInstalledFile::SetProperty(cmMakefile const* mf,
+ const std::string& prop, const char* value)
+{
+ this->RemoveProperty(prop);
+ this->AppendProperty(mf, prop, value);
+}
+
+//----------------------------------------------------------------------------
+void cmInstalledFile::AppendProperty(cmMakefile const* mf,
+ const std::string& prop, const char* value, bool /*asString*/)
+{
+ cmListFileBacktrace backtrace = mf->GetBacktrace();
+ cmGeneratorExpression ge(backtrace);
+
+ Property& property = this->Properties[prop];
+ property.ValueExpressions.push_back(ge.Parse(value).release());
+}
+
+//----------------------------------------------------------------------------
+bool cmInstalledFile::HasProperty(
+ const std::string& prop) const
+{
+ return this->Properties.find(prop) != this->Properties.end();
+}
+
+//----------------------------------------------------------------------------
+bool cmInstalledFile::GetProperty(
+ const std::string& prop, std::string& value) const
+{
+ PropertyMapType::const_iterator i = this->Properties.find(prop);
+ if(i == this->Properties.end())
+ {
+ return false;
+ }
+
+ Property const& property = i->second;
+
+ std::string output;
+ std::string separator;
+
+ for(ExpressionVectorType::const_iterator
+ j = property.ValueExpressions.begin();
+ j != property.ValueExpressions.end(); ++j)
+ {
+ output += separator;
+ output += (*j)->GetInput();
+ separator = ";";
+ }
+
+ value = output;
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmInstalledFile::GetPropertyAsBool(const std::string& prop) const
+{
+ std::string value;
+ bool isSet = this->GetProperty(prop, value);
+ return isSet && cmSystemTools::IsOn(value.c_str());
+}
+
+//----------------------------------------------------------------------------
+void cmInstalledFile::GetPropertyAsList(const std::string& prop,
+ std::vector<std::string>& list) const
+{
+ std::string value;
+ this->GetProperty(prop, value);
+
+ list.clear();
+ cmSystemTools::ExpandListArgument(value, list);
+}
diff --git a/Source/cmInstalledFile.h b/Source/cmInstalledFile.h
new file mode 100644
index 000000000..3af90a7db
--- /dev/null
+++ b/Source/cmInstalledFile.h
@@ -0,0 +1,77 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmInstalledFile_h
+#define cmInstalledFile_h
+
+#include "cmGeneratorExpression.h"
+
+/** \class cmInstalledFile
+ * \brief Represents a file intended for installation.
+ *
+ * cmInstalledFile represents a file intended for installation.
+ */
+class cmInstalledFile
+{
+public:
+
+ typedef cmsys::auto_ptr<cmCompiledGeneratorExpression>
+ CompiledGeneratorExpressionPtrType;
+
+ typedef std::vector<cmCompiledGeneratorExpression*>
+ ExpressionVectorType;
+
+ struct Property
+ {
+ Property();
+ ~Property();
+
+ ExpressionVectorType ValueExpressions;
+ };
+
+ typedef std::map<std::string, Property> PropertyMapType;
+
+ cmInstalledFile();
+
+ ~cmInstalledFile();
+
+ void RemoveProperty(const std::string& prop);
+
+ void SetProperty(cmMakefile const* mf,
+ const std::string& prop, const char *value);
+
+ void AppendProperty(cmMakefile const* mf,
+ const std::string& prop, const char* value,bool asString=false);
+
+ bool HasProperty(const std::string& prop) const;
+
+ bool GetProperty(const std::string& prop, std::string& value) const;
+
+ bool GetPropertyAsBool(const std::string& prop) const;
+
+ void GetPropertyAsList(const std::string& prop,
+ std::vector<std::string>& list) const;
+
+ void SetName(cmMakefile* mf, const std::string& name);
+
+ std::string const& GetName() const;
+
+ cmCompiledGeneratorExpression const& GetNameExpression() const;
+
+ PropertyMapType const& GetProperties() const { return this->Properties; }
+
+private:
+ std::string Name;
+ cmCompiledGeneratorExpression* NameExpression;
+ PropertyMapType Properties;
+};
+
+#endif
diff --git a/Source/cmLinkDirectoriesCommand.cxx b/Source/cmLinkDirectoriesCommand.cxx
index 4412414a4..b6c0072db 100644
--- a/Source/cmLinkDirectoriesCommand.cxx
+++ b/Source/cmLinkDirectoriesCommand.cxx
@@ -36,22 +36,21 @@ void cmLinkDirectoriesCommand::AddLinkDir(std::string const& dir)
if(!cmSystemTools::FileIsFullPath(unixPath.c_str()))
{
bool convertToAbsolute = false;
- cmOStringStream e;
+ std::ostringstream e;
e << "This command specifies the relative path\n"
<< " " << unixPath << "\n"
<< "as a link directory.\n";
- cmPolicies* policies = this->Makefile->GetPolicies();
switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0015))
{
case cmPolicies::WARN:
- e << policies->GetPolicyWarning(cmPolicies::CMP0015);
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0015);
this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, e.str());
case cmPolicies::OLD:
// OLD behavior does not convert
break;
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
- e << policies->GetRequiredPolicyError(cmPolicies::CMP0015);
+ e << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0015);
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
case cmPolicies::NEW:
// NEW behavior converts
@@ -60,11 +59,11 @@ void cmLinkDirectoriesCommand::AddLinkDir(std::string const& dir)
}
if (convertToAbsolute)
{
- std::string tmp = this->Makefile->GetStartDirectory();
+ std::string tmp = this->Makefile->GetCurrentSourceDirectory();
tmp += "/";
tmp += unixPath;
unixPath = tmp;
}
}
- this->Makefile->AddLinkDirectory(unixPath.c_str());
+ this->Makefile->AppendProperty("LINK_DIRECTORIES", unixPath.c_str());
}
diff --git a/Source/cmLinkDirectoriesCommand.h b/Source/cmLinkDirectoriesCommand.h
index 9218f448d..8e04bafcd 100644
--- a/Source/cmLinkDirectoriesCommand.h
+++ b/Source/cmLinkDirectoriesCommand.h
@@ -43,34 +43,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "link_directories";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Specify directories in which the linker will look for libraries.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " link_directories(directory1 directory2 ...)\n"
- "Specify the paths in which the linker should search for libraries. "
- "The command will apply only to targets created after it is called. "
- "Relative paths given to this command are interpreted as relative to "
- "the current source directory, see CMP0015. \n"
- "Note that this command is rarely necessary. Library locations "
- "returned by find_package() and find_library() are absolute paths. "
- "Pass these absolute library file paths directly to the "
- "target_link_libraries() command. CMake will ensure the linker finds "
- "them."
- ;
- }
+ virtual std::string GetName() const { return "link_directories";}
cmTypeMacro(cmLinkDirectoriesCommand, cmCommand);
private:
diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h
new file mode 100644
index 000000000..b603bcc2a
--- /dev/null
+++ b/Source/cmLinkItem.h
@@ -0,0 +1,145 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2004-2015 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmLinkItem_h
+#define cmLinkItem_h
+
+#include "cmListFileCache.h"
+#include "cmSystemTools.h"
+
+class cmGeneratorTarget;
+
+// Basic information about each link item.
+class cmLinkItem: public std::string
+{
+ typedef std::string std_string;
+public:
+ cmLinkItem(): std_string(), Target(0) {}
+ cmLinkItem(const std_string& n,
+ cmGeneratorTarget const* t): std_string(n), Target(t) {}
+ cmLinkItem(cmLinkItem const& r): std_string(r), Target(r.Target) {}
+ cmGeneratorTarget const* Target;
+};
+
+class cmLinkImplItem: public cmLinkItem
+{
+public:
+ cmLinkImplItem(): cmLinkItem(), Backtrace(), FromGenex(false) {}
+ cmLinkImplItem(std::string const& n,
+ cmGeneratorTarget const* t,
+ cmListFileBacktrace const& bt,
+ bool fromGenex):
+ cmLinkItem(n, t), Backtrace(bt), FromGenex(fromGenex) {}
+ cmLinkImplItem(cmLinkImplItem const& r):
+ cmLinkItem(r), Backtrace(r.Backtrace), FromGenex(r.FromGenex) {}
+ cmListFileBacktrace Backtrace;
+ bool FromGenex;
+};
+
+/** The link implementation specifies the direct library
+ dependencies needed by the object files of the target. */
+struct cmLinkImplementationLibraries
+{
+ // Libraries linked directly in this configuration.
+ std::vector<cmLinkImplItem> Libraries;
+
+ // Libraries linked directly in other configurations.
+ // Needed only for OLD behavior of CMP0003.
+ std::vector<cmLinkItem> WrongConfigLibraries;
+};
+
+struct cmLinkInterfaceLibraries
+{
+ // Libraries listed in the interface.
+ std::vector<cmLinkItem> Libraries;
+};
+
+struct cmLinkInterface: public cmLinkInterfaceLibraries
+{
+ // Languages whose runtime libraries must be linked.
+ std::vector<std::string> Languages;
+
+ // Shared library dependencies needed for linking on some platforms.
+ std::vector<cmLinkItem> SharedDeps;
+
+ // Number of repetitions of a strongly connected component of two
+ // or more static libraries.
+ int Multiplicity;
+
+ // Libraries listed for other configurations.
+ // Needed only for OLD behavior of CMP0003.
+ std::vector<cmLinkItem> WrongConfigLibraries;
+
+ bool ImplementationIsInterface;
+
+ cmLinkInterface(): Multiplicity(0), ImplementationIsInterface(false) {}
+};
+
+struct cmOptionalLinkInterface: public cmLinkInterface
+{
+ cmOptionalLinkInterface():
+ LibrariesDone(false), AllDone(false),
+ Exists(false), HadHeadSensitiveCondition(false),
+ ExplicitLibraries(0) {}
+ bool LibrariesDone;
+ bool AllDone;
+ bool Exists;
+ bool HadHeadSensitiveCondition;
+ const char* ExplicitLibraries;
+};
+
+struct cmHeadToLinkInterfaceMap:
+ public std::map<cmGeneratorTarget const*, cmOptionalLinkInterface>
+{
+};
+
+struct cmLinkImplementation: public cmLinkImplementationLibraries
+{
+ // Languages whose runtime libraries must be linked.
+ std::vector<std::string> Languages;
+};
+
+// Cache link implementation computation from each configuration.
+struct cmOptionalLinkImplementation: public cmLinkImplementation
+{
+ cmOptionalLinkImplementation():
+ LibrariesDone(false), LanguagesDone(false),
+ HadHeadSensitiveCondition(false) {}
+ bool LibrariesDone;
+ bool LanguagesDone;
+ bool HadHeadSensitiveCondition;
+};
+
+/** Compute the link type to use for the given configuration. */
+inline cmTargetLinkLibraryType
+CMP0003_ComputeLinkType(const std::string& config,
+ std::vector<std::string> const& debugConfigs)
+{
+ // No configuration is always optimized.
+ if(config.empty())
+ {
+ return OPTIMIZED_LibraryType;
+ }
+
+ // Check if any entry in the list matches this configuration.
+ std::string configUpper = cmSystemTools::UpperCase(config);
+ if (std::find(debugConfigs.begin(), debugConfigs.end(), configUpper) !=
+ debugConfigs.end())
+ {
+ return DEBUG_LibraryType;
+ }
+ // The current configuration is not a debug configuration.
+ return OPTIMIZED_LibraryType;
+}
+
+
+#endif
diff --git a/Source/cmLinkLibrariesCommand.cxx b/Source/cmLinkLibrariesCommand.cxx
index 2f1db2aa0..eb3bfce37 100644
--- a/Source/cmLinkLibrariesCommand.cxx
+++ b/Source/cmLinkLibrariesCommand.cxx
@@ -33,8 +33,8 @@ bool cmLinkLibrariesCommand
"a library");
return false;
}
- this->Makefile->AddLinkLibrary(i->c_str(),
- cmTarget::DEBUG);
+ this->Makefile->AddLinkLibrary(*i,
+ DEBUG_LibraryType);
}
else if (*i == "optimized")
{
@@ -45,12 +45,12 @@ bool cmLinkLibrariesCommand
"a library");
return false;
}
- this->Makefile->AddLinkLibrary(i->c_str(),
- cmTarget::OPTIMIZED);
+ this->Makefile->AddLinkLibrary(*i,
+ OPTIMIZED_LibraryType);
}
else
{
- this->Makefile->AddLinkLibrary(i->c_str());
+ this->Makefile->AddLinkLibrary(*i);
}
}
diff --git a/Source/cmLinkLibrariesCommand.h b/Source/cmLinkLibrariesCommand.h
index c450a1cb9..1ddefc476 100644
--- a/Source/cmLinkLibrariesCommand.h
+++ b/Source/cmLinkLibrariesCommand.h
@@ -42,38 +42,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "link_libraries";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Deprecated. Use the target_link_libraries() command instead.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- "Link libraries to all targets added later.\n"
- " link_libraries(library1 <debug | optimized> library2 ...)\n"
- "Specify a list of libraries to be linked into "
- "any following targets (typically added with the add_executable "
- "or add_library calls). This command is passed "
- "down to all subdirectories. "
- "The debug and optimized strings may be used to indicate that "
- "the next library listed is to be used only for that specific "
- "type of build.";
- }
-
- /** This command is kept for compatibility with older CMake versions. */
- virtual bool IsDiscouraged() const
- {
- return true;
- }
+ virtual std::string GetName() const { return "link_libraries";}
cmTypeMacro(cmLinkLibrariesCommand, cmCommand);
};
diff --git a/Source/cmLinkedTree.h b/Source/cmLinkedTree.h
new file mode 100644
index 000000000..3b41459c2
--- /dev/null
+++ b/Source/cmLinkedTree.h
@@ -0,0 +1,216 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Stephen Kelly <steveire@gmail.com>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmLinkedTree_h
+#define cmLinkedTree_h
+
+#include "cmStandardIncludes.h"
+
+#include <assert.h>
+
+/**
+ @brief A adaptor for traversing a tree structure in a vector
+
+ This class is not intended to be wholly generic like a standard library
+ container adaptor. Mostly it exists to facilitate code sharing for the
+ needs of the cmState. For example, the Truncate() method is a specific
+ requirement of the cmState.
+
+ An empty cmLinkedTree provides a Root() method, and an Push() method,
+ each of which return iterators. A Tree can be built up by extending
+ from the root, and then extending from any other iterator.
+
+ An iterator resulting from this tree construction can be
+ forward-only-iterated toward the root. Extending the tree never
+ invalidates existing iterators.
+ */
+template<typename T>
+class cmLinkedTree
+{
+ typedef typename std::vector<T>::size_type PositionType;
+ typedef T* PointerType;
+ typedef T& ReferenceType;
+public:
+ class iterator : public std::iterator<std::forward_iterator_tag, T>
+ {
+ friend class cmLinkedTree;
+ cmLinkedTree* Tree;
+
+ // The Position is always 'one past the end'.
+ PositionType Position;
+
+ iterator(cmLinkedTree* tree, PositionType pos)
+ : Tree(tree), Position(pos)
+ {
+
+ }
+
+ public:
+ iterator()
+ : Tree(0), Position(0)
+ {
+
+ }
+
+ void operator++()
+ {
+ assert(this->Tree);
+ assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
+ assert(this->Position <= this->Tree->Data.size());
+ assert(this->Position > 0);
+ this->Position = this->Tree->UpPositions[this->Position - 1];
+ }
+
+ PointerType operator->() const
+ {
+ assert(this->Tree);
+ assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
+ assert(this->Position <= this->Tree->Data.size());
+ assert(this->Position > 0);
+ return this->Tree->GetPointer(this->Position - 1);
+ }
+
+ PointerType operator->()
+ {
+ assert(this->Tree);
+ assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
+ assert(this->Position <= this->Tree->Data.size());
+ assert(this->Position > 0);
+ return this->Tree->GetPointer(this->Position - 1);
+ }
+
+ ReferenceType operator*() const
+ {
+ assert(this->Tree);
+ assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
+ assert(this->Position <= this->Tree->Data.size());
+ assert(this->Position > 0);
+ return this->Tree->GetReference(this->Position - 1);
+ }
+
+ ReferenceType operator*()
+ {
+ assert(this->Tree);
+ assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
+ assert(this->Position <= this->Tree->Data.size());
+ assert(this->Position > 0);
+ return this->Tree->GetReference(this->Position - 1);
+ }
+
+ bool operator==(iterator other) const
+ {
+ assert(this->Tree);
+ assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
+ assert(this->Tree == other.Tree);
+ return this->Position == other.Position;
+ }
+
+ bool operator!=(iterator other) const
+ {
+ assert(this->Tree);
+ assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
+ return !(*this == other);
+ }
+
+ bool IsValid() const
+ {
+ if (!this->Tree)
+ {
+ return false;
+ }
+ return this->Position <= this->Tree->Data.size();
+ }
+
+ bool StrictWeakOrdered(iterator other) const
+ {
+ assert(this->Tree);
+ assert(this->Tree == other.Tree);
+ return this->Position < other.Position;
+ }
+ };
+
+ iterator Root() const
+ {
+ return iterator(const_cast<cmLinkedTree*>(this), 0);
+ }
+
+ iterator Push(iterator it)
+ {
+ return Push_impl(it, T());
+ }
+
+ iterator Push(iterator it, T t)
+ {
+ return Push_impl(it, t);
+ }
+
+ bool IsLast(iterator it)
+ {
+ return it.Position == this->Data.size();
+ }
+
+ iterator Pop(iterator it)
+ {
+ assert(!this->Data.empty());
+ assert(this->UpPositions.size() == this->Data.size());
+ bool const isLast = this->IsLast(it);
+ ++it;
+ // If this is the last entry then no other entry can refer
+ // to it so we can drop its storage.
+ if (isLast)
+ {
+ this->Data.pop_back();
+ this->UpPositions.pop_back();
+ }
+ return it;
+ }
+
+ iterator Truncate()
+ {
+ assert(this->UpPositions.size() > 0);
+ this->UpPositions.erase(this->UpPositions.begin() + 1,
+ this->UpPositions.end());
+ assert(this->Data.size() > 0);
+ this->Data.erase(this->Data.begin() + 1, this->Data.end());
+ return iterator(this, 1);
+ }
+
+ void Clear()
+ {
+ this->UpPositions.clear();
+ this->Data.clear();
+ }
+
+private:
+ T& GetReference(PositionType pos)
+ {
+ return this->Data[pos];
+ }
+
+ T* GetPointer(PositionType pos)
+ {
+ return &this->Data[pos];
+ }
+
+ iterator Push_impl(iterator it, T t)
+ {
+ assert(this->UpPositions.size() == this->Data.size());
+ assert(it.Position <= this->UpPositions.size());
+ this->UpPositions.push_back(it.Position);
+ this->Data.push_back(t);
+ return iterator(this, this->UpPositions.size());
+ }
+
+ std::vector<T> Data;
+ std::vector<PositionType> UpPositions;
+};
+
+#endif
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
index df64695aa..6041fb77d 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -12,6 +12,7 @@
#include "cmListCommand.h"
#include <cmsys/RegularExpression.hxx>
#include <cmsys/SystemTools.hxx>
+#include "cmAlgorithms.h"
#include <stdlib.h> // required for atoi
#include <ctype.h>
@@ -69,17 +70,14 @@ bool cmListCommand
}
std::string e = "does not recognize sub-command "+subCommand;
- this->SetError(e.c_str());
+ this->SetError(e);
return false;
}
//----------------------------------------------------------------------------
-bool cmListCommand::GetListString(std::string& listString, const char* var)
+bool cmListCommand::GetListString(std::string& listString,
+ const std::string& var)
{
- if ( !var )
- {
- return false;
- }
// get the old value
const char* cacheValue
= this->Makefile->GetDefinition(var);
@@ -92,7 +90,8 @@ bool cmListCommand::GetListString(std::string& listString, const char* var)
}
//----------------------------------------------------------------------------
-bool cmListCommand::GetList(std::vector<std::string>& list, const char* var)
+bool cmListCommand::GetList(std::vector<std::string>& list,
+ const std::string& var)
{
std::string listString;
if ( !this->GetListString(listString, var) )
@@ -100,25 +99,14 @@ bool cmListCommand::GetList(std::vector<std::string>& list, const char* var)
return false;
}
// if the size of the list
- if(listString.size() == 0)
+ if(listString.empty())
{
return true;
}
// expand the variable into a list
cmSystemTools::ExpandListArgument(listString, list, true);
- // check the list for empty values
- bool hasEmpty = false;
- for(std::vector<std::string>::iterator i = list.begin();
- i != list.end(); ++i)
- {
- if(i->size() == 0)
- {
- hasEmpty = true;
- break;
- }
- }
// if no empty elements then just return
- if(!hasEmpty)
+ if (std::find(list.begin(), list.end(), std::string()) == list.end())
{
return true;
}
@@ -133,8 +121,7 @@ bool cmListCommand::GetList(std::vector<std::string>& list, const char* var)
// empty values
list.clear();
cmSystemTools::ExpandListArgument(listString, list);
- std::string warn = this->Makefile->GetPolicies()->
- GetPolicyWarning(cmPolicies::CMP0007);
+ std::string warn = cmPolicies::GetPolicyWarning(cmPolicies::CMP0007);
warn += " List has value = [";
warn += listString;
warn += "].";
@@ -155,8 +142,7 @@ bool cmListCommand::GetList(std::vector<std::string>& list, const char* var)
case cmPolicies::REQUIRED_ALWAYS:
this->Makefile->IssueMessage(
cmake::FATAL_ERROR,
- this->Makefile->GetPolicies()
- ->GetRequiredPolicyError(cmPolicies::CMP0007)
+ cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0007)
);
return false;
}
@@ -178,12 +164,12 @@ bool cmListCommand::HandleLengthCommand(std::vector<std::string> const& args)
// do not check the return value here
// if the list var is not found varArgsExpanded will have size 0
// and we will return 0
- this->GetList(varArgsExpanded, listName.c_str());
+ this->GetList(varArgsExpanded, listName);
size_t length = varArgsExpanded.size();
char buffer[1024];
sprintf(buffer, "%d", static_cast<int>(length));
- this->Makefile->AddDefinition(variableName.c_str(), buffer);
+ this->Makefile->AddDefinition(variableName, buffer);
return true;
}
@@ -200,9 +186,9 @@ bool cmListCommand::HandleGetCommand(std::vector<std::string> const& args)
const std::string& variableName = args[args.size() - 1];
// expand the variable
std::vector<std::string> varArgsExpanded;
- if ( !this->GetList(varArgsExpanded, listName.c_str()) )
+ if ( !this->GetList(varArgsExpanded, listName) )
{
- this->Makefile->AddDefinition(variableName.c_str(), "NOTFOUND");
+ this->Makefile->AddDefinition(variableName, "NOTFOUND");
return true;
}
// FIXME: Add policy to make non-existing lists an error like empty lists.
@@ -215,29 +201,29 @@ bool cmListCommand::HandleGetCommand(std::vector<std::string> const& args)
std::string value;
size_t cc;
const char* sep = "";
+ size_t nitem = varArgsExpanded.size();
for ( cc = 2; cc < args.size()-1; cc ++ )
{
int item = atoi(args[cc].c_str());
value += sep;
sep = ";";
- size_t nitem = varArgsExpanded.size();
if ( item < 0 )
{
item = (int)nitem + item;
}
if ( item < 0 || nitem <= (size_t)item )
{
- cmOStringStream str;
+ std::ostringstream str;
str << "index: " << item << " out of range (-"
- << varArgsExpanded.size() << ", "
- << varArgsExpanded.size()-1 << ")";
- this->SetError(str.str().c_str());
+ << nitem << ", "
+ << nitem - 1 << ")";
+ this->SetError(str.str());
return false;
}
value += varArgsExpanded[item];
}
- this->Makefile->AddDefinition(variableName.c_str(), value.c_str());
+ this->Makefile->AddDefinition(variableName, value.c_str());
return true;
}
@@ -255,18 +241,15 @@ bool cmListCommand::HandleAppendCommand(std::vector<std::string> const& args)
const std::string& listName = args[1];
// expand the variable
std::string listString;
- this->GetListString(listString, listName.c_str());
- size_t cc;
- for ( cc = 2; cc < args.size(); ++ cc )
+ this->GetListString(listString, listName);
+
+ if(!listString.empty() && !args.empty())
{
- if(listString.size())
- {
- listString += ";";
- }
- listString += args[cc];
+ listString += ";";
}
+ listString += cmJoin(cmMakeRange(args).advance(2), ";");
- this->Makefile->AddDefinition(listName.c_str(), listString.c_str());
+ this->Makefile->AddDefinition(listName, listString.c_str());
return true;
}
@@ -283,27 +266,23 @@ bool cmListCommand::HandleFindCommand(std::vector<std::string> const& args)
const std::string& variableName = args[args.size() - 1];
// expand the variable
std::vector<std::string> varArgsExpanded;
- if ( !this->GetList(varArgsExpanded, listName.c_str()) )
+ if ( !this->GetList(varArgsExpanded, listName) )
{
- this->Makefile->AddDefinition(variableName.c_str(), "-1");
+ this->Makefile->AddDefinition(variableName, "-1");
return true;
}
- std::vector<std::string>::iterator it;
- unsigned int index = 0;
- for ( it = varArgsExpanded.begin(); it != varArgsExpanded.end(); ++ it )
+ std::vector<std::string>::iterator it =
+ std::find(varArgsExpanded.begin(), varArgsExpanded.end(), args[2]);
+ if (it != varArgsExpanded.end())
{
- if ( *it == args[2] )
- {
- char indexString[32];
- sprintf(indexString, "%d", index);
- this->Makefile->AddDefinition(variableName.c_str(), indexString);
- return true;
- }
- index++;
+ std::ostringstream indexStream;
+ indexStream << std::distance(varArgsExpanded.begin(), it);
+ this->Makefile->AddDefinition(variableName, indexStream.str().c_str());
+ return true;
}
- this->Makefile->AddDefinition(variableName.c_str(), "-1");
+ this->Makefile->AddDefinition(variableName, "-1");
return true;
}
@@ -321,16 +300,16 @@ bool cmListCommand::HandleInsertCommand(std::vector<std::string> const& args)
// expand the variable
int item = atoi(args[2].c_str());
std::vector<std::string> varArgsExpanded;
- if((!this->GetList(varArgsExpanded, listName.c_str())
+ if((!this->GetList(varArgsExpanded, listName)
|| varArgsExpanded.empty()) && item != 0)
{
- cmOStringStream str;
+ std::ostringstream str;
str << "index: " << item << " out of range (0, 0)";
- this->SetError(str.str().c_str());
+ this->SetError(str.str());
return false;
}
- if ( varArgsExpanded.size() != 0 )
+ if (!varArgsExpanded.empty())
{
size_t nitem = varArgsExpanded.size();
if ( item < 0 )
@@ -339,32 +318,20 @@ bool cmListCommand::HandleInsertCommand(std::vector<std::string> const& args)
}
if ( item < 0 || nitem <= (size_t)item )
{
- cmOStringStream str;
+ std::ostringstream str;
str << "index: " << item << " out of range (-"
<< varArgsExpanded.size() << ", "
- << (varArgsExpanded.size() == 0?0:(varArgsExpanded.size()-1)) << ")";
- this->SetError(str.str().c_str());
+ << (varArgsExpanded.empty() ? 0 : (varArgsExpanded.size() - 1)) << ")";
+ this->SetError(str.str());
return false;
}
}
- size_t cc;
- size_t cnt = 0;
- for ( cc = 3; cc < args.size(); ++ cc )
- {
- varArgsExpanded.insert(varArgsExpanded.begin()+item+cnt, args[cc]);
- cnt ++;
- }
- std::string value;
- const char* sep = "";
- for ( cc = 0; cc < varArgsExpanded.size(); cc ++ )
- {
- value += sep;
- value += varArgsExpanded[cc];
- sep = ";";
- }
+ varArgsExpanded.insert(varArgsExpanded.begin()+item,
+ args.begin() + 3, args.end());
- this->Makefile->AddDefinition(listName.c_str(), value.c_str());
+ std::string value = cmJoin(varArgsExpanded, ";");
+ this->Makefile->AddDefinition(listName, value.c_str());
return true;
}
@@ -381,39 +348,23 @@ bool cmListCommand
const std::string& listName = args[1];
// expand the variable
std::vector<std::string> varArgsExpanded;
- if ( !this->GetList(varArgsExpanded, listName.c_str()) )
+ if ( !this->GetList(varArgsExpanded, listName) )
{
this->SetError("sub-command REMOVE_ITEM requires list to be present.");
return false;
}
- size_t cc;
- for ( cc = 2; cc < args.size(); ++ cc )
- {
- size_t kk = 0;
- while ( kk < varArgsExpanded.size() )
- {
- if ( varArgsExpanded[kk] == args[cc] )
- {
- varArgsExpanded.erase(varArgsExpanded.begin()+kk);
- }
- else
- {
- kk ++;
- }
- }
- }
-
- std::string value;
- const char* sep = "";
- for ( cc = 0; cc < varArgsExpanded.size(); cc ++ )
- {
- value += sep;
- value += varArgsExpanded[cc];
- sep = ";";
- }
+ std::vector<std::string> remove(args.begin() + 2, args.end());
+ std::sort(remove.begin(), remove.end());
+ std::vector<std::string>::const_iterator remEnd =
+ std::unique(remove.begin(), remove.end());
+ std::vector<std::string>::const_iterator remBegin = remove.begin();
- this->Makefile->AddDefinition(listName.c_str(), value.c_str());
+ std::vector<std::string>::const_iterator argsEnd =
+ cmRemoveMatching(varArgsExpanded, cmMakeRange(remBegin, remEnd));
+ std::vector<std::string>::const_iterator argsBegin = varArgsExpanded.begin();
+ std::string value = cmJoin(cmMakeRange(argsBegin, argsEnd), ";");
+ this->Makefile->AddDefinition(listName, value.c_str());
return true;
}
@@ -432,23 +383,15 @@ bool cmListCommand
const std::string& listName = args[1];
// expand the variable
std::vector<std::string> varArgsExpanded;
- if ( !this->GetList(varArgsExpanded, listName.c_str()) )
+ if ( !this->GetList(varArgsExpanded, listName) )
{
this->SetError("sub-command REVERSE requires list to be present.");
return false;
}
- std::string value;
- std::vector<std::string>::reverse_iterator it;
- const char* sep = "";
- for ( it = varArgsExpanded.rbegin(); it != varArgsExpanded.rend(); ++ it )
- {
- value += sep;
- value += it->c_str();
- sep = ";";
- }
+ std::string value = cmJoin(cmReverseRange(varArgsExpanded), ";");
- this->Makefile->AddDefinition(listName.c_str(), value.c_str());
+ this->Makefile->AddDefinition(listName, value.c_str());
return true;
}
@@ -467,33 +410,20 @@ bool cmListCommand
const std::string& listName = args[1];
// expand the variable
std::vector<std::string> varArgsExpanded;
- if ( !this->GetList(varArgsExpanded, listName.c_str()) )
+ if ( !this->GetList(varArgsExpanded, listName) )
{
this->SetError(
"sub-command REMOVE_DUPLICATES requires list to be present.");
return false;
}
- std::string value;
-
-
- std::set<std::string> unique;
- std::vector<std::string>::iterator it;
- const char* sep = "";
- for ( it = varArgsExpanded.begin(); it != varArgsExpanded.end(); ++ it )
- {
- if (unique.find(*it) != unique.end())
- {
- continue;
- }
- unique.insert(*it);
- value += sep;
- value += it->c_str();
- sep = ";";
- }
-
+ std::vector<std::string>::const_iterator argsEnd =
+ cmRemoveDuplicates(varArgsExpanded);
+ std::vector<std::string>::const_iterator argsBegin =
+ varArgsExpanded.begin();
+ std::string value = cmJoin(cmMakeRange(argsBegin, argsEnd), ";");
- this->Makefile->AddDefinition(listName.c_str(), value.c_str());
+ this->Makefile->AddDefinition(listName, value.c_str());
return true;
}
@@ -512,7 +442,7 @@ bool cmListCommand
const std::string& listName = args[1];
// expand the variable
std::vector<std::string> varArgsExpanded;
- if ( !this->GetList(varArgsExpanded, listName.c_str()) )
+ if ( !this->GetList(varArgsExpanded, listName) )
{
this->SetError("sub-command SORT requires list to be present.");
return false;
@@ -520,17 +450,8 @@ bool cmListCommand
std::sort(varArgsExpanded.begin(), varArgsExpanded.end());
- std::string value;
- std::vector<std::string>::iterator it;
- const char* sep = "";
- for ( it = varArgsExpanded.begin(); it != varArgsExpanded.end(); ++ it )
- {
- value += sep;
- value += it->c_str();
- sep = ";";
- }
-
- this->Makefile->AddDefinition(listName.c_str(), value.c_str());
+ std::string value = cmJoin(varArgsExpanded, ";");
+ this->Makefile->AddDefinition(listName, value.c_str());
return true;
}
@@ -548,7 +469,7 @@ bool cmListCommand::HandleRemoveAtCommand(
const std::string& listName = args[1];
// expand the variable
std::vector<std::string> varArgsExpanded;
- if ( !this->GetList(varArgsExpanded, listName.c_str()) )
+ if ( !this->GetList(varArgsExpanded, listName) )
{
this->SetError("sub-command REMOVE_AT requires list to be present.");
return false;
@@ -562,49 +483,37 @@ bool cmListCommand::HandleRemoveAtCommand(
size_t cc;
std::vector<size_t> removed;
+ size_t nitem = varArgsExpanded.size();
for ( cc = 2; cc < args.size(); ++ cc )
{
int item = atoi(args[cc].c_str());
- size_t nitem = varArgsExpanded.size();
if ( item < 0 )
{
item = (int)nitem + item;
}
if ( item < 0 || nitem <= (size_t)item )
{
- cmOStringStream str;
+ std::ostringstream str;
str << "index: " << item << " out of range (-"
- << varArgsExpanded.size() << ", "
- << varArgsExpanded.size()-1 << ")";
- this->SetError(str.str().c_str());
+ << nitem << ", "
+ << nitem - 1 << ")";
+ this->SetError(str.str());
return false;
}
removed.push_back(static_cast<size_t>(item));
}
- std::string value;
- const char* sep = "";
- for ( cc = 0; cc < varArgsExpanded.size(); ++ cc )
- {
- size_t kk;
- bool found = false;
- for ( kk = 0; kk < removed.size(); ++ kk )
- {
- if ( cc == removed[kk] )
- {
- found = true;
- }
- }
+ std::sort(removed.begin(), removed.end());
+ std::vector<size_t>::const_iterator remEnd =
+ std::unique(removed.begin(), removed.end());
+ std::vector<size_t>::const_iterator remBegin = removed.begin();
- if ( !found )
- {
- value += sep;
- value += varArgsExpanded[cc];
- sep = ";";
- }
- }
+ std::vector<std::string>::const_iterator argsEnd =
+ cmRemoveIndices(varArgsExpanded, cmMakeRange(remBegin, remEnd));
+ std::vector<std::string>::const_iterator argsBegin = varArgsExpanded.begin();
+ std::string value = cmJoin(cmMakeRange(argsBegin, argsEnd), ";");
- this->Makefile->AddDefinition(listName.c_str(), value.c_str());
+ this->Makefile->AddDefinition(listName, value.c_str());
return true;
}
diff --git a/Source/cmListCommand.h b/Source/cmListCommand.h
index f20aa8a8f..5ea1d9f18 100644
--- a/Source/cmListCommand.h
+++ b/Source/cmListCommand.h
@@ -44,67 +44,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "list";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "List operations.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " list(LENGTH <list> <output variable>)\n"
- " list(GET <list> <element index> [<element index> ...]\n"
- " <output variable>)\n"
- " list(APPEND <list> <element> [<element> ...])\n"
- " list(FIND <list> <value> <output variable>)\n"
- " list(INSERT <list> <element_index> <element> [<element> ...])\n"
- " list(REMOVE_ITEM <list> <value> [<value> ...])\n"
- " list(REMOVE_AT <list> <index> [<index> ...])\n"
- " list(REMOVE_DUPLICATES <list>)\n"
- " list(REVERSE <list>)\n"
- " list(SORT <list>)\n"
- "LENGTH will return a given list's length.\n"
- "GET will return list of elements specified by indices from the list.\n"
- "APPEND will append elements to the list.\n"
- "FIND will return the index of the element specified in the list or -1 "
- "if it wasn't found.\n"
- "INSERT will insert elements to the list to the specified location.\n"
- "REMOVE_AT and REMOVE_ITEM will remove items from the list. The "
- "difference is that REMOVE_ITEM will remove the given items, while "
- "REMOVE_AT will remove the items at the given indices.\n"
- "REMOVE_DUPLICATES will remove duplicated items in the list.\n"
- "REVERSE reverses the contents of the list in-place.\n"
- "SORT sorts the list in-place alphabetically.\n"
- "The list subcommands APPEND, INSERT, REMOVE_AT, REMOVE_ITEM, "
- "REMOVE_DUPLICATES, REVERSE and SORT may create new values for "
- "the list within the current CMake variable scope. Similar to "
- "the SET command, the LIST command creates new variable values "
- "in the current scope, even if the list itself is actually "
- "defined in a parent scope. To propagate the results of these "
- "operations upwards, use SET with PARENT_SCOPE, SET with CACHE "
- "INTERNAL, or some other means of value propagation.\n"
- "NOTES: A list in cmake is a ; separated group of strings. "
- "To create a list the set command can be used. For example, "
- "set(var a b c d e) creates a list with a;b;c;d;e, and "
- "set(var \"a b c d e\") creates a string or a list with one "
- "item in it.\n"
- "When specifying index values, if <element index> is 0 or"
- " greater, it is indexed from the "
- "beginning of the list, with 0 representing the first list element. "
- "If <element index> is -1 or lesser, it is indexed from the end of "
- "the list, with -1 representing the last list element. Be careful "
- "when counting with negative indices: they do not start from 0. "
- "-0 is equivalent to 0, the first list element.\n"
- ;
- }
+ virtual std::string GetName() const { return "list";}
cmTypeMacro(cmListCommand, cmCommand);
protected:
@@ -120,8 +60,8 @@ protected:
bool HandleReverseCommand(std::vector<std::string> const& args);
- bool GetList(std::vector<std::string>& list, const char* var);
- bool GetListString(std::string& listString, const char* var);
+ bool GetList(std::vector<std::string>& list, const std::string& var);
+ bool GetListString(std::string& listString, const std::string& var);
};
diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx
index 898f379ad..7ba61f38e 100644
--- a/Source/cmListFileCache.cxx
+++ b/Source/cmListFileCache.cxx
@@ -12,15 +12,13 @@
#include "cmListFileCache.h"
#include "cmListFileLexer.h"
+#include "cmOutputConverter.h"
#include "cmSystemTools.h"
#include "cmMakefile.h"
#include "cmVersion.h"
#include <cmsys/RegularExpression.hxx>
-#ifdef __BORLANDC__
-# pragma warn -8060 /* possibly incorrect assignment */
-#endif
//----------------------------------------------------------------------------
struct cmListFileParser
@@ -29,14 +27,14 @@ struct cmListFileParser
~cmListFileParser();
bool ParseFile();
bool ParseFunction(const char* name, long line);
- void AddArgument(cmListFileLexer_Token* token,
+ bool AddArgument(cmListFileLexer_Token* token,
cmListFileArgument::Delimiter delim);
cmListFile* ListFile;
cmMakefile* Makefile;
const char* FileName;
cmListFileLexer* Lexer;
cmListFileFunction Function;
- enum { SeparationOkay, SeparationWarning } Separation;
+ enum { SeparationOkay, SeparationWarning, SeparationError} Separation;
};
//----------------------------------------------------------------------------
@@ -57,13 +55,26 @@ cmListFileParser::~cmListFileParser()
bool cmListFileParser::ParseFile()
{
// Open the file.
- if(!cmListFileLexer_SetFileName(this->Lexer, this->FileName))
+ cmListFileLexer_BOM bom;
+ if(!cmListFileLexer_SetFileName(this->Lexer, this->FileName, &bom))
{
cmSystemTools::Error("cmListFileCache: error can not open file ",
this->FileName);
return false;
}
+ // Verify the Byte-Order-Mark, if any.
+ if(bom != cmListFileLexer_BOM_None &&
+ bom != cmListFileLexer_BOM_UTF8)
+ {
+ cmListFileLexer_SetFileName(this->Lexer, 0, 0);
+ std::ostringstream m;
+ m << "File\n " << this->FileName << "\n"
+ << "starts with a Byte-Order-Mark that is not UTF-8.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, m.str());
+ return false;
+ }
+
// Use a simple recursive-descent parser to process the token
// stream.
bool haveNewline = true;
@@ -77,6 +88,10 @@ bool cmListFileParser::ParseFile()
{
haveNewline = true;
}
+ else if(token->type == cmListFileLexer_Token_CommentBracket)
+ {
+ haveNewline = false;
+ }
else if(token->type == cmListFileLexer_Token_Identifier)
{
if(haveNewline)
@@ -93,7 +108,7 @@ bool cmListFileParser::ParseFile()
}
else
{
- cmOStringStream error;
+ std::ostringstream error;
error << "Error in cmake code at\n"
<< this->FileName << ":" << token->line << ":\n"
<< "Parse error. Expected a newline, got "
@@ -105,7 +120,7 @@ bool cmListFileParser::ParseFile()
}
else
{
- cmOStringStream error;
+ std::ostringstream error;
error << "Error in cmake code at\n"
<< this->FileName << ":" << token->line << ":\n"
<< "Parse error. Expected a command name, got "
@@ -124,24 +139,19 @@ bool cmListFile::ParseFile(const char* filename,
bool topLevel,
cmMakefile *mf)
{
- if(!cmSystemTools::FileExists(filename))
+ if(!cmSystemTools::FileExists(filename) ||
+ cmSystemTools::FileIsDirectory(filename))
{
return false;
}
bool parseError = false;
- this->ModifiedTime = cmSystemTools::ModifiedTime(filename);
{
cmListFileParser parser(this, mf, filename);
parseError = !parser.ParseFile();
}
- if(parseError)
- {
- this->ModifiedTime = 0;
- }
-
// do we need a cmake_policy(VERSION call?
if(topLevel)
{
@@ -224,8 +234,7 @@ bool cmListFile::ParseFile(const char* filename,
{
cmListFileFunction project;
project.Name = "PROJECT";
- cmListFileArgument prj("Project", cmListFileArgument::Unquoted,
- filename, 0);
+ cmListFileArgument prj("Project", cmListFileArgument::Unquoted, 0);
project.Arguments.push_back(prj);
this->Functions.insert(this->Functions.begin(),project);
}
@@ -242,7 +251,6 @@ bool cmListFileParser::ParseFunction(const char* name, long line)
{
// Inintialize a new function call.
this->Function = cmListFileFunction();
- this->Function.FilePath = this->FileName;
this->Function.Name = name;
this->Function.Line = line;
@@ -252,7 +260,7 @@ bool cmListFileParser::ParseFunction(const char* name, long line)
token->type == cmListFileLexer_Token_Space) {}
if(!token)
{
- cmOStringStream error;
+ std::ostringstream error;
error << "Error in cmake code at\n" << this->FileName << ":"
<< cmListFileLexer_GetCurrentLine(this->Lexer) << ":\n"
<< "Parse error. Function missing opening \"(\".";
@@ -261,7 +269,7 @@ bool cmListFileParser::ParseFunction(const char* name, long line)
}
if(token->type != cmListFileLexer_Token_ParenLeft)
{
- cmOStringStream error;
+ std::ostringstream error;
error << "Error in cmake code at\n" << this->FileName << ":"
<< cmListFileLexer_GetCurrentLine(this->Lexer) << ":\n"
<< "Parse error. Expected \"(\", got "
@@ -288,7 +296,10 @@ bool cmListFileParser::ParseFunction(const char* name, long line)
{
parenDepth++;
this->Separation = SeparationOkay;
- this->AddArgument(token, cmListFileArgument::Unquoted);
+ if(!this->AddArgument(token, cmListFileArgument::Unquoted))
+ {
+ return false;
+ }
}
else if(token->type == cmListFileLexer_Token_ParenRight)
{
@@ -298,24 +309,45 @@ bool cmListFileParser::ParseFunction(const char* name, long line)
}
parenDepth--;
this->Separation = SeparationOkay;
- this->AddArgument(token, cmListFileArgument::Unquoted);
+ if(!this->AddArgument(token, cmListFileArgument::Unquoted))
+ {
+ return false;
+ }
this->Separation = SeparationWarning;
}
else if(token->type == cmListFileLexer_Token_Identifier ||
token->type == cmListFileLexer_Token_ArgumentUnquoted)
{
- this->AddArgument(token, cmListFileArgument::Unquoted);
+ if(!this->AddArgument(token, cmListFileArgument::Unquoted))
+ {
+ return false;
+ }
this->Separation = SeparationWarning;
}
else if(token->type == cmListFileLexer_Token_ArgumentQuoted)
{
- this->AddArgument(token, cmListFileArgument::Quoted);
+ if(!this->AddArgument(token, cmListFileArgument::Quoted))
+ {
+ return false;
+ }
this->Separation = SeparationWarning;
}
+ else if(token->type == cmListFileLexer_Token_ArgumentBracket)
+ {
+ if(!this->AddArgument(token, cmListFileArgument::Bracket))
+ {
+ return false;
+ }
+ this->Separation = SeparationError;
+ }
+ else if(token->type == cmListFileLexer_Token_CommentBracket)
+ {
+ this->Separation = SeparationError;
+ }
else
{
// Error.
- cmOStringStream error;
+ std::ostringstream error;
error << "Error in cmake code at\n" << this->FileName << ":"
<< cmListFileLexer_GetCurrentLine(this->Lexer) << ":\n"
<< "Parse error. Function missing ending \")\". "
@@ -327,7 +359,7 @@ bool cmListFileParser::ParseFunction(const char* name, long line)
}
}
- cmOStringStream error;
+ std::ostringstream error;
error << "Error in cmake code at\n"
<< this->FileName << ":" << lastLine << ":\n"
<< "Parse error. Function missing ending \")\". "
@@ -338,42 +370,94 @@ bool cmListFileParser::ParseFunction(const char* name, long line)
}
//----------------------------------------------------------------------------
-void cmListFileParser::AddArgument(cmListFileLexer_Token* token,
+bool cmListFileParser::AddArgument(cmListFileLexer_Token* token,
cmListFileArgument::Delimiter delim)
{
- cmListFileArgument a(token->text, delim, this->FileName, token->line);
+ cmListFileArgument a(token->text, delim, token->line);
this->Function.Arguments.push_back(a);
- if(delim == cmListFileArgument::Unquoted)
- {
- // Warn about a future behavior change.
- const char* c = a.Value.c_str();
- if(*c++ == '[')
- {
- while(*c == '=')
- { ++c; }
- if(*c == '[')
- {
- cmOStringStream m;
- m << "Syntax Warning in cmake code at\n"
- << " " << this->FileName << ":" << token->line << ":"
- << token->column << "\n"
- << "A future version of CMake may treat unquoted argument:\n"
- << " " << a.Value << "\n"
- << "as an opening long bracket. Double-quote the argument.";
- this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, m.str().c_str());
- }
- }
- }
if(this->Separation == SeparationOkay)
{
- return;
+ return true;
}
- cmOStringStream m;
- m << "Syntax Warning in cmake code at\n"
+ bool isError = (this->Separation == SeparationError ||
+ delim == cmListFileArgument::Bracket);
+ std::ostringstream m;
+ m << "Syntax " << (isError? "Error":"Warning") << " in cmake code at\n"
<< " " << this->FileName << ":" << token->line << ":"
<< token->column << "\n"
<< "Argument not separated from preceding token by whitespace.";
- this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, m.str().c_str());
+ if(isError)
+ {
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, m.str());
+ return false;
+ }
+ else
+ {
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, m.str());
+ return true;
+ }
+}
+
+cmListFileBacktrace::cmListFileBacktrace(cmState::Snapshot snapshot,
+ cmCommandContext const& cc)
+ : Context(cc)
+ , Snapshot(snapshot)
+{
+ if (this->Snapshot.IsValid())
+ {
+ this->Snapshot.Keep();
+ }
+}
+
+cmListFileBacktrace::~cmListFileBacktrace()
+{
+}
+
+void cmListFileBacktrace::PrintTitle(std::ostream& out) const
+{
+ if (!this->Snapshot.IsValid())
+ {
+ return;
+ }
+ cmOutputConverter converter(this->Snapshot);
+ cmListFileContext lfc =
+ cmListFileContext::FromCommandContext(
+ this->Context, this->Snapshot.GetExecutionListFile());
+ lfc.FilePath = converter.Convert(lfc.FilePath, cmOutputConverter::HOME);
+ out << (lfc.Line ? " at " : " in ") << lfc;
+}
+
+void cmListFileBacktrace::PrintCallStack(std::ostream& out) const
+{
+ if (!this->Snapshot.IsValid())
+ {
+ return;
+ }
+ cmState::Snapshot parent = this->Snapshot.GetCallStackParent();
+ if (!parent.IsValid() || parent.GetExecutionListFile().empty())
+ {
+ return;
+ }
+
+ cmOutputConverter converter(this->Snapshot);
+ std::string commandName = this->Snapshot.GetEntryPointCommand();
+ long commandLine = this->Snapshot.GetEntryPointLine();
+
+ out << "Call Stack (most recent call first):\n";
+ while(parent.IsValid())
+ {
+ cmListFileContext lfc;
+ lfc.Name = commandName;
+ lfc.Line = commandLine;
+
+ lfc.FilePath = converter.Convert(parent.GetExecutionListFile(),
+ cmOutputConverter::HOME);
+ out << " " << lfc << "\n";
+
+ commandName = parent.GetEntryPointCommand();
+ commandLine = parent.GetEntryPointLine();
+ parent = parent.GetCallStackParent();
+ }
}
//----------------------------------------------------------------------------
@@ -390,3 +474,22 @@ std::ostream& operator<<(std::ostream& os, cmListFileContext const& lfc)
}
return os;
}
+
+bool operator<(const cmListFileContext& lhs, const cmListFileContext& rhs)
+{
+ if(lhs.Line != rhs.Line)
+ {
+ return lhs.Line < rhs.Line;
+ }
+ return lhs.FilePath < rhs.FilePath;
+}
+
+bool operator==(const cmListFileContext& lhs, const cmListFileContext& rhs)
+{
+ return lhs.Line == rhs.Line && lhs.FilePath == rhs.FilePath;
+}
+
+bool operator!=(const cmListFileContext& lhs, const cmListFileContext& rhs)
+{
+ return !(lhs == rhs);
+}
diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h
index 7bb3b346c..03e0abe28 100644
--- a/Source/cmListFileCache.h
+++ b/Source/cmListFileCache.h
@@ -14,6 +14,8 @@
#include "cmStandardIncludes.h"
+#include "cmState.h"
+
/** \class cmListFileCache
* \brief A class to cache list file contents.
*
@@ -23,19 +25,26 @@
class cmMakefile;
+struct cmCommandContext
+{
+ std::string Name;
+ long Line;
+ cmCommandContext(): Name(), Line(0) {}
+};
+
struct cmListFileArgument
{
enum Delimiter
{
Unquoted,
- Quoted
+ Quoted,
+ Bracket
};
- cmListFileArgument(): Value(), Delim(Unquoted), FilePath(0), Line(0) {}
- cmListFileArgument(const cmListFileArgument& r):
- Value(r.Value), Delim(r.Delim), FilePath(r.FilePath), Line(r.Line) {}
- cmListFileArgument(const std::string& v, Delimiter d, const char* file,
- long line): Value(v), Delim(d),
- FilePath(file), Line(line) {}
+ cmListFileArgument(): Value(), Delim(Unquoted), Line(0) {}
+ cmListFileArgument(const cmListFileArgument& r)
+ : Value(r.Value), Delim(r.Delim), Line(r.Line) {}
+ cmListFileArgument(const std::string& v, Delimiter d, long line)
+ : Value(v), Delim(d), Line(line) {}
bool operator == (const cmListFileArgument& r) const
{
return (this->Value == r.Value) && (this->Delim == r.Delim);
@@ -46,7 +55,6 @@ struct cmListFileArgument
}
std::string Value;
Delimiter Delim;
- const char* FilePath;
long Line;
};
@@ -56,38 +64,49 @@ struct cmListFileContext
std::string FilePath;
long Line;
cmListFileContext(): Name(), FilePath(), Line(0) {}
+
+ static cmListFileContext FromCommandContext(cmCommandContext const& lfcc,
+ std::string const& fileName)
+ {
+ cmListFileContext lfc;
+ lfc.FilePath = fileName;
+ lfc.Line = lfcc.Line;
+ lfc.Name = lfcc.Name;
+ return lfc;
+ }
};
std::ostream& operator<<(std::ostream&, cmListFileContext const&);
+bool operator<(const cmListFileContext& lhs, const cmListFileContext& rhs);
+bool operator==(cmListFileContext const& lhs, cmListFileContext const& rhs);
+bool operator!=(cmListFileContext const& lhs, cmListFileContext const& rhs);
-struct cmListFileFunction: public cmListFileContext
+struct cmListFileFunction: public cmCommandContext
{
std::vector<cmListFileArgument> Arguments;
};
-class cmListFileBacktrace: public std::vector<cmListFileContext> {};
+class cmListFileBacktrace
+{
+ public:
+ cmListFileBacktrace(cmState::Snapshot snapshot = cmState::Snapshot(),
+ cmCommandContext const& cc = cmCommandContext());
+ ~cmListFileBacktrace();
+
+ void PrintTitle(std::ostream& out) const;
+ void PrintCallStack(std::ostream& out) const;
+ private:
+ cmCommandContext Context;
+ cmState::Snapshot Snapshot;
+};
struct cmListFile
{
- cmListFile()
- :ModifiedTime(0)
- {
- }
bool ParseFile(const char* path,
bool topLevel,
cmMakefile *mf);
- long int ModifiedTime;
std::vector<cmListFileFunction> Functions;
};
-struct cmValueWithOrigin {
- cmValueWithOrigin(const std::string &value,
- const cmListFileBacktrace &bt)
- : Value(value), Backtrace(bt)
- {}
- std::string Value;
- cmListFileBacktrace Backtrace;
-};
-
#endif
diff --git a/Source/cmListFileLexer.c b/Source/cmListFileLexer.c
index 2841fe511..af4fc3dcd 100644
--- a/Source/cmListFileLexer.c
+++ b/Source/cmListFileLexer.c
@@ -369,8 +369,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
*yy_cp = '\0'; \
yyg->yy_c_buf_p = yy_cp;
-#define YY_NUM_RULES 16
-#define YY_END_OF_BUFFER 17
+#define YY_NUM_RULES 24
+#define YY_END_OF_BUFFER 25
/* This struct is not used in this scanner,
but its presence is necessary. */
struct yy_trans_info
@@ -378,13 +378,16 @@ struct yy_trans_info
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
-static yyconst flex_int16_t yy_accept[45] =
+static yyconst flex_int16_t yy_accept[77] =
{ 0,
- 0, 0, 0, 0, 17, 6, 14, 1, 8, 2,
- 6, 3, 4, 6, 15, 9, 11, 12, 13, 6,
- 0, 6, 0, 14, 2, 0, 5, 6, 9, 0,
- 10, 0, 7, 0, 0, 0, 7, 0, 7, 0,
- 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 4, 4,
+ 25, 13, 22, 1, 16, 3, 13, 5, 6, 7,
+ 15, 23, 17, 19, 20, 21, 10, 11, 8, 12,
+ 9, 4, 13, 0, 13, 0, 22, 0, 0, 7,
+ 13, 0, 13, 0, 2, 0, 13, 17, 0, 18,
+ 10, 8, 4, 0, 14, 0, 0, 0, 0, 14,
+ 0, 0, 14, 0, 0, 0, 2, 14, 0, 0,
+ 0, 0, 0, 0, 0, 0
} ;
static yyconst flex_int32_t yy_ec[256] =
@@ -395,14 +398,14 @@ static yyconst flex_int32_t yy_ec[256] =
1, 2, 1, 5, 6, 7, 1, 1, 1, 8,
9, 1, 1, 1, 1, 1, 1, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 1, 1, 1,
- 1, 1, 1, 1, 11, 11, 11, 11, 11, 11,
- 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
- 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
- 1, 12, 1, 1, 11, 1, 11, 11, 11, 11,
-
- 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
- 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
- 11, 11, 1, 1, 1, 1, 1, 1, 1, 1,
+ 11, 1, 1, 1, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 13, 14, 15, 1, 12, 1, 12, 12, 12, 12,
+
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -419,72 +422,111 @@ static yyconst flex_int32_t yy_ec[256] =
1, 1, 1, 1, 1
} ;
-static yyconst flex_int32_t yy_meta[13] =
+static yyconst flex_int32_t yy_meta[16] =
{ 0,
- 1, 2, 3, 2, 4, 1, 1, 1, 5, 5,
- 5, 1
+ 1, 1, 2, 3, 4, 3, 1, 3, 5, 6,
+ 1, 6, 1, 1, 7
} ;
-static yyconst flex_int16_t yy_base[56] =
+static yyconst flex_int16_t yy_base[95] =
{ 0,
- 0, 0, 10, 20, 38, 32, 0, 109, 109, 0,
- 28, 109, 109, 35, 0, 23, 109, 109, 44, 0,
- 49, 26, 0, 0, 0, 22, 0, 0, 18, 24,
- 109, 0, 61, 20, 0, 18, 0, 17, 16, 0,
- 12, 11, 10, 109, 73, 16, 78, 83, 88, 93,
- 12, 98, 11, 103, 9
+ 0, 0, 13, 25, 14, 16, 17, 18, 90, 88,
+ 88, 39, 20, 237, 237, 74, 78, 237, 237, 13,
+ 54, 0, 71, 237, 237, 31, 0, 237, 73, 237,
+ 237, 0, 0, 65, 75, 0, 33, 30, 72, 0,
+ 0, 75, 70, 0, 74, 0, 0, 62, 70, 237,
+ 0, 63, 0, 85, 99, 65, 111, 62, 34, 0,
+ 54, 116, 0, 54, 127, 51, 237, 50, 0, 48,
+ 47, 39, 33, 29, 17, 237, 136, 143, 150, 157,
+ 164, 171, 178, 184, 191, 198, 201, 207, 214, 217,
+ 219, 225, 228, 230
+
} ;
-static yyconst flex_int16_t yy_def[56] =
+static yyconst flex_int16_t yy_def[95] =
{ 0,
- 44, 1, 45, 45, 44, 44, 46, 44, 44, 47,
- 6, 44, 44, 6, 48, 49, 44, 44, 49, 6,
- 44, 6, 50, 46, 47, 51, 14, 6, 49, 49,
- 44, 21, 44, 21, 52, 53, 33, 51, 33, 54,
- 55, 53, 55, 0, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44
+ 76, 1, 77, 77, 78, 78, 79, 79, 80, 80,
+ 76, 76, 76, 76, 76, 76, 12, 76, 76, 12,
+ 76, 81, 82, 76, 76, 82, 83, 76, 76, 76,
+ 76, 84, 12, 85, 12, 86, 76, 76, 87, 20,
+ 12, 88, 12, 21, 76, 89, 12, 82, 82, 76,
+ 83, 76, 84, 85, 76, 54, 85, 90, 76, 55,
+ 87, 88, 55, 62, 88, 91, 76, 55, 92, 93,
+ 90, 94, 91, 93, 94, 0, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76
+
} ;
-static yyconst flex_int16_t yy_nxt[122] =
+static yyconst flex_int16_t yy_nxt[253] =
{ 0,
- 6, 7, 8, 7, 9, 10, 11, 12, 13, 6,
- 14, 15, 17, 43, 18, 42, 38, 24, 32, 33,
- 32, 19, 17, 36, 18, 37, 33, 41, 29, 30,
- 37, 19, 20, 36, 30, 26, 21, 44, 22, 44,
- 44, 20, 20, 23, 27, 27, 31, 44, 29, 32,
- 32, 44, 44, 33, 44, 34, 44, 44, 32, 32,
- 35, 33, 44, 44, 44, 21, 44, 39, 44, 44,
- 33, 33, 40, 16, 16, 16, 16, 16, 25, 25,
- 44, 25, 25, 28, 28, 44, 28, 28, 29, 29,
- 44, 44, 29, 20, 20, 44, 20, 20, 32, 32,
-
- 44, 32, 32, 33, 33, 44, 33, 33, 5, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44
+ 12, 13, 14, 13, 15, 16, 17, 18, 19, 12,
+ 12, 20, 21, 22, 12, 24, 28, 25, 28, 28,
+ 28, 37, 40, 37, 40, 62, 26, 24, 29, 25,
+ 29, 31, 31, 50, 37, 48, 37, 54, 26, 33,
+ 59, 63, 45, 34, 59, 35, 45, 62, 33, 33,
+ 33, 33, 36, 33, 41, 55, 54, 58, 42, 63,
+ 43, 72, 60, 41, 44, 41, 45, 46, 41, 55,
+ 55, 56, 70, 52, 48, 49, 67, 66, 57, 63,
+ 60, 64, 58, 52, 49, 39, 38, 76, 65, 55,
+ 14, 56, 14, 76, 76, 76, 76, 76, 57, 55,
+
+ 76, 76, 76, 34, 76, 68, 76, 76, 55, 55,
+ 55, 55, 69, 55, 54, 76, 54, 76, 54, 54,
+ 63, 76, 64, 76, 76, 76, 76, 76, 76, 65,
+ 62, 76, 62, 76, 62, 62, 23, 23, 23, 23,
+ 23, 23, 23, 27, 27, 27, 27, 27, 27, 27,
+ 30, 30, 30, 30, 30, 30, 30, 32, 32, 32,
+ 32, 32, 32, 32, 47, 76, 47, 47, 47, 47,
+ 47, 48, 76, 48, 76, 48, 48, 48, 51, 76,
+ 51, 51, 51, 51, 53, 76, 53, 53, 53, 53,
+ 53, 54, 76, 76, 54, 76, 54, 54, 33, 76,
+
+ 33, 33, 33, 33, 33, 61, 61, 62, 76, 76,
+ 62, 76, 62, 62, 41, 76, 41, 41, 41, 41,
+ 41, 71, 71, 73, 73, 55, 76, 55, 55, 55,
+ 55, 55, 74, 74, 75, 75, 11, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76
} ;
-static yyconst flex_int16_t yy_chk[122] =
+static yyconst flex_int16_t yy_chk[253] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 3, 55, 3, 53, 51, 46, 43, 42,
- 41, 3, 4, 39, 4, 38, 36, 34, 30, 29,
- 26, 4, 6, 22, 16, 11, 6, 5, 6, 0,
- 0, 6, 6, 6, 14, 14, 19, 0, 19, 21,
- 21, 0, 0, 21, 0, 21, 0, 0, 21, 21,
- 21, 33, 0, 0, 0, 33, 0, 33, 0, 0,
- 33, 33, 33, 45, 45, 45, 45, 45, 47, 47,
- 0, 47, 47, 48, 48, 0, 48, 48, 49, 49,
- 0, 0, 49, 50, 50, 0, 50, 50, 52, 52,
-
- 0, 52, 52, 54, 54, 0, 54, 54, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44
+ 1, 1, 1, 1, 1, 3, 5, 3, 6, 7,
+ 8, 13, 20, 13, 20, 75, 3, 4, 5, 4,
+ 6, 7, 8, 26, 37, 26, 37, 74, 4, 12,
+ 38, 73, 38, 12, 59, 12, 59, 72, 12, 12,
+ 12, 12, 12, 12, 21, 71, 70, 68, 21, 66,
+ 21, 64, 61, 21, 21, 21, 21, 21, 21, 34,
+ 58, 34, 56, 52, 49, 48, 45, 43, 34, 42,
+ 39, 42, 35, 29, 23, 17, 16, 11, 42, 54,
+ 10, 54, 9, 0, 0, 0, 0, 0, 54, 55,
+
+ 0, 0, 0, 55, 0, 55, 0, 0, 55, 55,
+ 55, 55, 55, 55, 57, 0, 57, 0, 57, 57,
+ 62, 0, 62, 0, 0, 0, 0, 0, 0, 62,
+ 65, 0, 65, 0, 65, 65, 77, 77, 77, 77,
+ 77, 77, 77, 78, 78, 78, 78, 78, 78, 78,
+ 79, 79, 79, 79, 79, 79, 79, 80, 80, 80,
+ 80, 80, 80, 80, 81, 0, 81, 81, 81, 81,
+ 81, 82, 0, 82, 0, 82, 82, 82, 83, 0,
+ 83, 83, 83, 83, 84, 0, 84, 84, 84, 84,
+ 84, 85, 0, 0, 85, 0, 85, 85, 86, 0,
+
+ 86, 86, 86, 86, 86, 87, 87, 88, 0, 0,
+ 88, 0, 88, 88, 89, 0, 89, 89, 89, 89,
+ 89, 90, 90, 91, 91, 92, 0, 92, 92, 92,
+ 92, 92, 93, 93, 94, 94, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76
} ;
/* Table of booleans, true if rule could match eol. */
-static yyconst flex_int32_t yy_rule_can_match_eol[17] =
+static yyconst flex_int32_t yy_rule_can_match_eol[25] =
{ 0,
-1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, };
+1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1,
+ 0, 0, 0, 0, 0, };
/* The intent behind this definition is that it'll catch
* any uses of REJECT which flex missed.
@@ -527,6 +569,9 @@ Modify cmListFileLexer.c:
*/
#include "cmStandardLexer.h"
+#ifdef WIN32
+#include <cmsys/Encoding.h>
+#endif
/* Setup the proper cmListFileLexer_yylex declaration. */
#define YY_EXTRA_TYPE cmListFileLexer*
@@ -538,10 +583,13 @@ Modify cmListFileLexer.c:
struct cmListFileLexer_s
{
cmListFileLexer_Token token;
+ int bracket;
+ int comment;
int line;
int column;
int size;
FILE* file;
+ size_t cr;
char* string_buffer;
char* string_position;
int string_left;
@@ -564,10 +612,16 @@ static void cmListFileLexerDestroy(cmListFileLexer* lexer);
/*--------------------------------------------------------------------------*/
-#line 570 "cmListFileLexer.c"
+
+
+
+#line 628 "cmListFileLexer.c"
#define INITIAL 0
#define STRING 1
+#define BRACKET 2
+#define BRACKETEND 3
+#define COMMENT 4
#ifndef YY_NO_UNISTD_H
/* Special case for "unistd.h", since it is non-ANSI. We include it way
@@ -793,10 +847,10 @@ YY_DECL
int yy_act;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-#line 82 "cmListFileLexer.in.l"
+#line 91 "cmListFileLexer.in.l"
-#line 804 "cmListFileLexer.c"
+#line 865 "cmListFileLexer.c"
if ( !yyg->yy_init )
{
@@ -849,13 +903,13 @@ yy_match:
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 45 )
+ if ( yy_current_state >= 77 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
++yy_cp;
}
- while ( yy_base[yy_current_state] != 109 );
+ while ( yy_base[yy_current_state] != 237 );
yy_find_action:
yy_act = yy_accept[yy_current_state];
@@ -894,69 +948,177 @@ do_action: /* This label is used only to access EOF actions. */
case 1:
/* rule 1 can match eol */
YY_RULE_SETUP
-#line 84 "cmListFileLexer.in.l"
+#line 93 "cmListFileLexer.in.l"
{
lexer->token.type = cmListFileLexer_Token_Newline;
cmListFileLexerSetToken(lexer, yytext, yyleng);
++lexer->line;
lexer->column = 1;
+ BEGIN(INITIAL);
return 1;
}
case 2:
+/* rule 2 can match eol */
YY_RULE_SETUP
-#line 92 "cmListFileLexer.in.l"
+#line 102 "cmListFileLexer.in.l"
{
- lexer->column += yyleng;
+ const char* bracket = yytext;
+ lexer->comment = yytext[0] == '#';
+ if(lexer->comment)
+ {
+ lexer->token.type = cmListFileLexer_Token_CommentBracket;
+ bracket += 1;
+ }
+ else
+ {
+ lexer->token.type = cmListFileLexer_Token_ArgumentBracket;
+ }
+ cmListFileLexerSetToken(lexer, "", 0);
+ lexer->bracket = (int)(strchr(bracket+1, '[') - bracket);
+ if(yytext[yyleng-1] == '\n')
+ {
+ ++lexer->line;
+ lexer->column = 1;
+ }
+ else
+ {
+ lexer->column += yyleng;
+ }
+ BEGIN(BRACKET);
}
YY_BREAK
case 3:
YY_RULE_SETUP
-#line 96 "cmListFileLexer.in.l"
+#line 128 "cmListFileLexer.in.l"
+{
+ lexer->column += yyleng;
+ BEGIN(COMMENT);
+}
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 133 "cmListFileLexer.in.l"
+{
+ lexer->column += yyleng;
+}
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 137 "cmListFileLexer.in.l"
{
lexer->token.type = cmListFileLexer_Token_ParenLeft;
cmListFileLexerSetToken(lexer, yytext, yyleng);
lexer->column += yyleng;
return 1;
}
-case 4:
+case 6:
YY_RULE_SETUP
-#line 103 "cmListFileLexer.in.l"
+#line 144 "cmListFileLexer.in.l"
{
lexer->token.type = cmListFileLexer_Token_ParenRight;
cmListFileLexerSetToken(lexer, yytext, yyleng);
lexer->column += yyleng;
return 1;
}
-case 5:
+case 7:
YY_RULE_SETUP
-#line 110 "cmListFileLexer.in.l"
+#line 151 "cmListFileLexer.in.l"
{
lexer->token.type = cmListFileLexer_Token_Identifier;
cmListFileLexerSetToken(lexer, yytext, yyleng);
lexer->column += yyleng;
return 1;
}
-case 6:
+case 8:
+YY_RULE_SETUP
+#line 158 "cmListFileLexer.in.l"
+{
+ /* Handle ]]====]=======]*/
+ cmListFileLexerAppend(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+ if(yyleng == lexer->bracket)
+ {
+ BEGIN(BRACKETEND);
+ }
+}
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 168 "cmListFileLexer.in.l"
+{
+ lexer->column += yyleng;
+ /* Erase the partial bracket from the token. */
+ lexer->token.length -= lexer->bracket;
+ lexer->token.text[lexer->token.length] = 0;
+ BEGIN(INITIAL);
+ return 1;
+}
+case 10:
YY_RULE_SETUP
-#line 117 "cmListFileLexer.in.l"
+#line 177 "cmListFileLexer.in.l"
+{
+ cmListFileLexerAppend(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+}
+ YY_BREAK
+case 11:
+/* rule 11 can match eol */
+YY_RULE_SETUP
+#line 182 "cmListFileLexer.in.l"
+{
+ cmListFileLexerAppend(lexer, yytext, yyleng);
+ ++lexer->line;
+ lexer->column = 1;
+ BEGIN(BRACKET);
+}
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 189 "cmListFileLexer.in.l"
+{
+ cmListFileLexerAppend(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+ BEGIN(BRACKET);
+}
+ YY_BREAK
+case YY_STATE_EOF(BRACKET):
+case YY_STATE_EOF(BRACKETEND):
+#line 195 "cmListFileLexer.in.l"
+{
+ lexer->token.type = cmListFileLexer_Token_BadBracket;
+ BEGIN(INITIAL);
+ return 1;
+}
+case 13:
+YY_RULE_SETUP
+#line 201 "cmListFileLexer.in.l"
{
lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted;
cmListFileLexerSetToken(lexer, yytext, yyleng);
lexer->column += yyleng;
return 1;
}
-case 7:
+case 14:
YY_RULE_SETUP
-#line 124 "cmListFileLexer.in.l"
+#line 208 "cmListFileLexer.in.l"
{
lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted;
cmListFileLexerSetToken(lexer, yytext, yyleng);
lexer->column += yyleng;
return 1;
}
-case 8:
+case 15:
+YY_RULE_SETUP
+#line 215 "cmListFileLexer.in.l"
+{
+ lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted;
+ cmListFileLexerSetToken(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+ return 1;
+}
+case 16:
YY_RULE_SETUP
-#line 131 "cmListFileLexer.in.l"
+#line 222 "cmListFileLexer.in.l"
{
lexer->token.type = cmListFileLexer_Token_ArgumentQuoted;
cmListFileLexerSetToken(lexer, "", 0);
@@ -964,69 +1126,69 @@ YY_RULE_SETUP
BEGIN(STRING);
}
YY_BREAK
-case 9:
+case 17:
YY_RULE_SETUP
-#line 138 "cmListFileLexer.in.l"
+#line 229 "cmListFileLexer.in.l"
{
cmListFileLexerAppend(lexer, yytext, yyleng);
lexer->column += yyleng;
}
YY_BREAK
-case 10:
-/* rule 10 can match eol */
+case 18:
+/* rule 18 can match eol */
YY_RULE_SETUP
-#line 143 "cmListFileLexer.in.l"
+#line 234 "cmListFileLexer.in.l"
{
- cmListFileLexerAppend(lexer, yytext, yyleng);
+ /* Continuation: text is not part of string */
++lexer->line;
lexer->column = 1;
}
YY_BREAK
-case 11:
-/* rule 11 can match eol */
+case 19:
+/* rule 19 can match eol */
YY_RULE_SETUP
-#line 149 "cmListFileLexer.in.l"
+#line 240 "cmListFileLexer.in.l"
{
cmListFileLexerAppend(lexer, yytext, yyleng);
++lexer->line;
lexer->column = 1;
}
YY_BREAK
-case 12:
+case 20:
YY_RULE_SETUP
-#line 155 "cmListFileLexer.in.l"
+#line 246 "cmListFileLexer.in.l"
{
lexer->column += yyleng;
BEGIN(INITIAL);
return 1;
}
-case 13:
+case 21:
YY_RULE_SETUP
-#line 161 "cmListFileLexer.in.l"
+#line 252 "cmListFileLexer.in.l"
{
cmListFileLexerAppend(lexer, yytext, yyleng);
lexer->column += yyleng;
}
YY_BREAK
case YY_STATE_EOF(STRING):
-#line 166 "cmListFileLexer.in.l"
+#line 257 "cmListFileLexer.in.l"
{
lexer->token.type = cmListFileLexer_Token_BadString;
BEGIN(INITIAL);
return 1;
}
-case 14:
+case 22:
YY_RULE_SETUP
-#line 172 "cmListFileLexer.in.l"
+#line 263 "cmListFileLexer.in.l"
{
lexer->token.type = cmListFileLexer_Token_Space;
cmListFileLexerSetToken(lexer, yytext, yyleng);
lexer->column += yyleng;
return 1;
}
-case 15:
+case 23:
YY_RULE_SETUP
-#line 179 "cmListFileLexer.in.l"
+#line 270 "cmListFileLexer.in.l"
{
lexer->token.type = cmListFileLexer_Token_BadCharacter;
cmListFileLexerSetToken(lexer, yytext, yyleng);
@@ -1034,18 +1196,19 @@ YY_RULE_SETUP
return 1;
}
case YY_STATE_EOF(INITIAL):
-#line 186 "cmListFileLexer.in.l"
+case YY_STATE_EOF(COMMENT):
+#line 277 "cmListFileLexer.in.l"
{
lexer->token.type = cmListFileLexer_Token_None;
cmListFileLexerSetToken(lexer, 0, 0);
return 0;
}
-case 16:
+case 24:
YY_RULE_SETUP
-#line 192 "cmListFileLexer.in.l"
+#line 283 "cmListFileLexer.in.l"
ECHO;
YY_BREAK
-#line 1064 "cmListFileLexer.c"
+#line 1238 "cmListFileLexer.c"
case YY_END_OF_BUFFER:
{
@@ -1337,7 +1500,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 45 )
+ if ( yy_current_state >= 77 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1366,11 +1529,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 45 )
+ if ( yy_current_state >= 77 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- yy_is_jam = (yy_current_state == 44);
+ yy_is_jam = (yy_current_state == 76);
return yy_is_jam ? 0 : yy_current_state;
}
@@ -2166,7 +2329,7 @@ void cmListFileLexer_yyfree (void * ptr , yyscan_t yyscanner)
#define YYTABLES_NAME "yytables"
-#line 192 "cmListFileLexer.in.l"
+#line 282 "cmListFileLexer.in.l"
@@ -2243,7 +2406,38 @@ static int cmListFileLexerInput(cmListFileLexer* lexer, char* buffer,
{
if(lexer->file)
{
- return (int)fread(buffer, 1, bufferSize, lexer->file);
+ /* Convert CRLF -> LF explicitly. The C FILE "t"ext mode
+ does not convert newlines on all platforms. Move any
+ trailing CR to the start of the buffer for the next read. */
+ size_t cr = lexer->cr;
+ size_t n;
+ buffer[0] = '\r';
+ n = fread(buffer+cr, 1, bufferSize-cr, lexer->file);
+ if(n)
+ {
+ char* o = buffer;
+ const char* i = buffer;
+ const char* e;
+ n += cr;
+ cr = (buffer[n-1] == '\r')? 1:0;
+ e = buffer + n - cr;
+ while(i != e)
+ {
+ if(i[0] == '\r' && i[1] == '\n')
+ {
+ ++i;
+ }
+ *o++ = *i++;
+ }
+ n = o - buffer;
+ }
+ else
+ {
+ n = cr;
+ cr = 0;
+ }
+ lexer->cr = cr;
+ return n;
}
else if(lexer->string_left)
{
@@ -2271,6 +2465,7 @@ static void cmListFileLexerInit(cmListFileLexer* lexer)
/*--------------------------------------------------------------------------*/
static void cmListFileLexerDestroy(cmListFileLexer* lexer)
{
+ cmListFileLexerSetToken(lexer, 0, 0);
if(lexer->file || lexer->string_buffer)
{
cmListFileLexer_yylex_destroy(lexer->scanner);
@@ -2306,19 +2501,74 @@ cmListFileLexer* cmListFileLexer_New()
/*--------------------------------------------------------------------------*/
void cmListFileLexer_Delete(cmListFileLexer* lexer)
{
- cmListFileLexer_SetFileName(lexer, 0);
+ cmListFileLexer_SetFileName(lexer, 0, 0);
free(lexer);
}
/*--------------------------------------------------------------------------*/
-int cmListFileLexer_SetFileName(cmListFileLexer* lexer, const char* name)
+static cmListFileLexer_BOM cmListFileLexer_ReadBOM(FILE* f)
+{
+ unsigned char b[2];
+ if(fread(b, 1, 2, f) == 2)
+ {
+ if(b[0] == 0xEF && b[1] == 0xBB)
+ {
+ if(fread(b, 1, 1, f) == 1 && b[0] == 0xBF)
+ {
+ return cmListFileLexer_BOM_UTF8;
+ }
+ }
+ else if(b[0] == 0xFE && b[1] == 0xFF)
+ {
+ /* UTF-16 BE */
+ return cmListFileLexer_BOM_UTF16BE;
+ }
+ else if(b[0] == 0 && b[1] == 0)
+ {
+ if(fread(b, 1, 2, f) == 2 && b[0] == 0xFE && b[1] == 0xFF)
+ {
+ return cmListFileLexer_BOM_UTF32BE;
+ }
+ }
+ else if(b[0] == 0xFF && b[1] == 0xFE)
+ {
+ fpos_t p;
+ fgetpos(f, &p);
+ if(fread(b, 1, 2, f) == 2 && b[0] == 0 && b[1] == 0)
+ {
+ return cmListFileLexer_BOM_UTF32LE;
+ }
+ fsetpos(f, &p);
+ return cmListFileLexer_BOM_UTF16LE;
+ }
+ }
+ rewind(f);
+ return cmListFileLexer_BOM_None;
+}
+
+/*--------------------------------------------------------------------------*/
+int cmListFileLexer_SetFileName(cmListFileLexer* lexer, const char* name,
+ cmListFileLexer_BOM* bom)
{
int result = 1;
cmListFileLexerDestroy(lexer);
if(name)
{
- lexer->file = fopen(name, "r");
- if(!lexer->file)
+#ifdef _WIN32
+ wchar_t* wname = cmsysEncoding_DupToWide(name);
+ lexer->file = _wfopen(wname, L"rb");
+ free(wname);
+#else
+ lexer->file = fopen(name, "rb");
+#endif
+ if(lexer->file)
+ {
+ if(bom)
+ {
+ *bom = cmListFileLexer_ReadBOM(lexer->file);
+ }
+ }
+ else
{
result = 0;
}
@@ -2364,7 +2614,7 @@ cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer)
}
else
{
- cmListFileLexer_SetFileName(lexer, 0);
+ cmListFileLexer_SetFileName(lexer, 0, 0);
return 0;
}
}
@@ -2410,7 +2660,10 @@ const char* cmListFileLexer_GetTypeAsString(cmListFileLexer* lexer,
case cmListFileLexer_Token_ParenRight: return "right paren";
case cmListFileLexer_Token_ArgumentUnquoted: return "unquoted argument";
case cmListFileLexer_Token_ArgumentQuoted: return "quoted argument";
+ case cmListFileLexer_Token_ArgumentBracket: return "bracket argument";
+ case cmListFileLexer_Token_CommentBracket: return "bracket comment";
case cmListFileLexer_Token_BadCharacter: return "bad character";
+ case cmListFileLexer_Token_BadBracket: return "unterminated bracket";
case cmListFileLexer_Token_BadString: return "unterminated string";
}
return "unknown token";
diff --git a/Source/cmListFileLexer.h b/Source/cmListFileLexer.h
index cc78b5c2f..bd2868ab6 100644
--- a/Source/cmListFileLexer.h
+++ b/Source/cmListFileLexer.h
@@ -22,7 +22,10 @@ typedef enum cmListFileLexer_Type_e
cmListFileLexer_Token_ParenRight,
cmListFileLexer_Token_ArgumentUnquoted,
cmListFileLexer_Token_ArgumentQuoted,
+ cmListFileLexer_Token_ArgumentBracket,
+ cmListFileLexer_Token_CommentBracket,
cmListFileLexer_Token_BadCharacter,
+ cmListFileLexer_Token_BadBracket,
cmListFileLexer_Token_BadString
} cmListFileLexer_Type;
@@ -36,6 +39,17 @@ struct cmListFileLexer_Token_s
int column;
};
+enum cmListFileLexer_BOM_e
+{
+ cmListFileLexer_BOM_None,
+ cmListFileLexer_BOM_UTF8,
+ cmListFileLexer_BOM_UTF16BE,
+ cmListFileLexer_BOM_UTF16LE,
+ cmListFileLexer_BOM_UTF32BE,
+ cmListFileLexer_BOM_UTF32LE
+};
+typedef enum cmListFileLexer_BOM_e cmListFileLexer_BOM;
+
typedef struct cmListFileLexer_s cmListFileLexer;
#ifdef __cplusplus
@@ -44,7 +58,8 @@ extern "C"
#endif
cmListFileLexer* cmListFileLexer_New();
-int cmListFileLexer_SetFileName(cmListFileLexer*, const char*);
+int cmListFileLexer_SetFileName(cmListFileLexer*, const char*,
+ cmListFileLexer_BOM* bom);
int cmListFileLexer_SetString(cmListFileLexer*, const char*);
cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer*);
long cmListFileLexer_GetCurrentLine(cmListFileLexer*);
diff --git a/Source/cmListFileLexer.in.l b/Source/cmListFileLexer.in.l
index 12b53eef6..a520c7221 100644
--- a/Source/cmListFileLexer.in.l
+++ b/Source/cmListFileLexer.in.l
@@ -31,6 +31,9 @@ Modify cmListFileLexer.c:
*/
#include "cmStandardLexer.h"
+#ifdef WIN32
+#include <cmsys/Encoding.h>
+#endif
/* Setup the proper cmListFileLexer_yylex declaration. */
#define YY_EXTRA_TYPE cmListFileLexer*
@@ -42,10 +45,13 @@ Modify cmListFileLexer.c:
struct cmListFileLexer_s
{
cmListFileLexer_Token token;
+ int bracket;
+ int comment;
int line;
int column;
int size;
FILE* file;
+ size_t cr;
char* string_buffer;
char* string_position;
int string_left;
@@ -74,22 +80,57 @@ static void cmListFileLexerDestroy(cmListFileLexer* lexer);
%option noyywrap
%pointer
%x STRING
+%x BRACKET
+%x BRACKETEND
+%x COMMENT
MAKEVAR \$\([A-Za-z0-9_]*\)
-UNQUOTED ([^ \t\r\n\(\)#\\\"]|\\.)
-LEGACY {MAKEVAR}|{UNQUOTED}|\"({MAKEVAR}|{UNQUOTED}|[ \t])*\"
+UNQUOTED ([^ \t\r\n\(\)#\\\"[=]|\\.)
+LEGACY {MAKEVAR}|{UNQUOTED}|\"({MAKEVAR}|{UNQUOTED}|[ \t[=])*\"
%%
-\n {
+<INITIAL,COMMENT>\n {
lexer->token.type = cmListFileLexer_Token_Newline;
cmListFileLexerSetToken(lexer, yytext, yyleng);
++lexer->line;
lexer->column = 1;
+ BEGIN(INITIAL);
return 1;
}
-#.* {
+#?\[=*\[\n? {
+ const char* bracket = yytext;
+ lexer->comment = yytext[0] == '#';
+ if(lexer->comment)
+ {
+ lexer->token.type = cmListFileLexer_Token_CommentBracket;
+ bracket += 1;
+ }
+ else
+ {
+ lexer->token.type = cmListFileLexer_Token_ArgumentBracket;
+ }
+ cmListFileLexerSetToken(lexer, "", 0);
+ lexer->bracket = (int)(strchr(bracket+1, '[') - bracket);
+ if(yytext[yyleng-1] == '\n')
+ {
+ ++lexer->line;
+ lexer->column = 1;
+ }
+ else
+ {
+ lexer->column += yyleng;
+ }
+ BEGIN(BRACKET);
+}
+
+# {
+ lexer->column += yyleng;
+ BEGIN(COMMENT);
+}
+
+<COMMENT>.* {
lexer->column += yyleng;
}
@@ -107,21 +148,71 @@ LEGACY {MAKEVAR}|{UNQUOTED}|\"({MAKEVAR}|{UNQUOTED}|[ \t])*\"
return 1;
}
-[A-Za-z_][A-Za-z0-9_]+ {
+[A-Za-z_][A-Za-z0-9_]* {
lexer->token.type = cmListFileLexer_Token_Identifier;
cmListFileLexerSetToken(lexer, yytext, yyleng);
lexer->column += yyleng;
return 1;
}
-({UNQUOTED})({UNQUOTED})* {
+<BRACKET>\]=* {
+ /* Handle ]]====]=======]*/
+ cmListFileLexerAppend(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+ if(yyleng == lexer->bracket)
+ {
+ BEGIN(BRACKETEND);
+ }
+}
+
+<BRACKETEND>\] {
+ lexer->column += yyleng;
+ /* Erase the partial bracket from the token. */
+ lexer->token.length -= lexer->bracket;
+ lexer->token.text[lexer->token.length] = 0;
+ BEGIN(INITIAL);
+ return 1;
+}
+
+<BRACKET>([^]\n])+ {
+ cmListFileLexerAppend(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+}
+
+<BRACKET,BRACKETEND>\n {
+ cmListFileLexerAppend(lexer, yytext, yyleng);
+ ++lexer->line;
+ lexer->column = 1;
+ BEGIN(BRACKET);
+}
+
+<BRACKET,BRACKETEND>. {
+ cmListFileLexerAppend(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+ BEGIN(BRACKET);
+}
+
+<BRACKET,BRACKETEND><<EOF>> {
+ lexer->token.type = cmListFileLexer_Token_BadBracket;
+ BEGIN(INITIAL);
+ return 1;
+}
+
+({UNQUOTED}|=|\[=*{UNQUOTED})({UNQUOTED}|[[=])* {
lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted;
cmListFileLexerSetToken(lexer, yytext, yyleng);
lexer->column += yyleng;
return 1;
}
-({MAKEVAR}|{UNQUOTED})({LEGACY})* {
+({MAKEVAR}|{UNQUOTED}|=|\[=*{LEGACY})({LEGACY}|[[=])* {
+ lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted;
+ cmListFileLexerSetToken(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+ return 1;
+}
+
+\[ {
lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted;
cmListFileLexerSetToken(lexer, yytext, yyleng);
lexer->column += yyleng;
@@ -141,7 +232,7 @@ LEGACY {MAKEVAR}|{UNQUOTED}|\"({MAKEVAR}|{UNQUOTED}|[ \t])*\"
}
<STRING>\\\n {
- cmListFileLexerAppend(lexer, yytext, yyleng);
+ /* Continuation: text is not part of string */
++lexer->line;
lexer->column = 1;
}
@@ -264,7 +355,38 @@ static int cmListFileLexerInput(cmListFileLexer* lexer, char* buffer,
{
if(lexer->file)
{
- return (int)fread(buffer, 1, bufferSize, lexer->file);
+ /* Convert CRLF -> LF explicitly. The C FILE "t"ext mode
+ does not convert newlines on all platforms. Move any
+ trailing CR to the start of the buffer for the next read. */
+ size_t cr = lexer->cr;
+ size_t n;
+ buffer[0] = '\r';
+ n = fread(buffer+cr, 1, bufferSize-cr, lexer->file);
+ if(n)
+ {
+ char* o = buffer;
+ const char* i = buffer;
+ const char* e;
+ n += cr;
+ cr = (buffer[n-1] == '\r')? 1:0;
+ e = buffer + n - cr;
+ while(i != e)
+ {
+ if(i[0] == '\r' && i[1] == '\n')
+ {
+ ++i;
+ }
+ *o++ = *i++;
+ }
+ n = o - buffer;
+ }
+ else
+ {
+ n = cr;
+ cr = 0;
+ }
+ lexer->cr = cr;
+ return n;
}
else if(lexer->string_left)
{
@@ -292,6 +414,7 @@ static void cmListFileLexerInit(cmListFileLexer* lexer)
/*--------------------------------------------------------------------------*/
static void cmListFileLexerDestroy(cmListFileLexer* lexer)
{
+ cmListFileLexerSetToken(lexer, 0, 0);
if(lexer->file || lexer->string_buffer)
{
cmListFileLexer_yylex_destroy(lexer->scanner);
@@ -327,19 +450,74 @@ cmListFileLexer* cmListFileLexer_New()
/*--------------------------------------------------------------------------*/
void cmListFileLexer_Delete(cmListFileLexer* lexer)
{
- cmListFileLexer_SetFileName(lexer, 0);
+ cmListFileLexer_SetFileName(lexer, 0, 0);
free(lexer);
}
/*--------------------------------------------------------------------------*/
-int cmListFileLexer_SetFileName(cmListFileLexer* lexer, const char* name)
+static cmListFileLexer_BOM cmListFileLexer_ReadBOM(FILE* f)
+{
+ unsigned char b[2];
+ if(fread(b, 1, 2, f) == 2)
+ {
+ if(b[0] == 0xEF && b[1] == 0xBB)
+ {
+ if(fread(b, 1, 1, f) == 1 && b[0] == 0xBF)
+ {
+ return cmListFileLexer_BOM_UTF8;
+ }
+ }
+ else if(b[0] == 0xFE && b[1] == 0xFF)
+ {
+ /* UTF-16 BE */
+ return cmListFileLexer_BOM_UTF16BE;
+ }
+ else if(b[0] == 0 && b[1] == 0)
+ {
+ if(fread(b, 1, 2, f) == 2 && b[0] == 0xFE && b[1] == 0xFF)
+ {
+ return cmListFileLexer_BOM_UTF32BE;
+ }
+ }
+ else if(b[0] == 0xFF && b[1] == 0xFE)
+ {
+ fpos_t p;
+ fgetpos(f, &p);
+ if(fread(b, 1, 2, f) == 2 && b[0] == 0 && b[1] == 0)
+ {
+ return cmListFileLexer_BOM_UTF32LE;
+ }
+ fsetpos(f, &p);
+ return cmListFileLexer_BOM_UTF16LE;
+ }
+ }
+ rewind(f);
+ return cmListFileLexer_BOM_None;
+}
+
+/*--------------------------------------------------------------------------*/
+int cmListFileLexer_SetFileName(cmListFileLexer* lexer, const char* name,
+ cmListFileLexer_BOM* bom)
{
int result = 1;
cmListFileLexerDestroy(lexer);
if(name)
{
- lexer->file = fopen(name, "r");
- if(!lexer->file)
+#ifdef _WIN32
+ wchar_t* wname = cmsysEncoding_DupToWide(name);
+ lexer->file = _wfopen(wname, L"rb");
+ free(wname);
+#else
+ lexer->file = fopen(name, "rb");
+#endif
+ if(lexer->file)
+ {
+ if(bom)
+ {
+ *bom = cmListFileLexer_ReadBOM(lexer->file);
+ }
+ }
+ else
{
result = 0;
}
@@ -385,7 +563,7 @@ cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer)
}
else
{
- cmListFileLexer_SetFileName(lexer, 0);
+ cmListFileLexer_SetFileName(lexer, 0, 0);
return 0;
}
}
@@ -431,7 +609,10 @@ const char* cmListFileLexer_GetTypeAsString(cmListFileLexer* lexer,
case cmListFileLexer_Token_ParenRight: return "right paren";
case cmListFileLexer_Token_ArgumentUnquoted: return "unquoted argument";
case cmListFileLexer_Token_ArgumentQuoted: return "quoted argument";
+ case cmListFileLexer_Token_ArgumentBracket: return "bracket argument";
+ case cmListFileLexer_Token_CommentBracket: return "bracket comment";
case cmListFileLexer_Token_BadCharacter: return "bad character";
+ case cmListFileLexer_Token_BadBracket: return "unterminated bracket";
case cmListFileLexer_Token_BadString: return "unterminated string";
}
return "unknown token";
diff --git a/Source/cmLoadCacheCommand.cxx b/Source/cmLoadCacheCommand.cxx
index 462e086ef..6ade53542 100644
--- a/Source/cmLoadCacheCommand.cxx
+++ b/Source/cmLoadCacheCommand.cxx
@@ -12,6 +12,7 @@
#include "cmLoadCacheCommand.h"
#include <cmsys/RegularExpression.hxx>
+#include <cmsys/FStream.hxx>
// cmLoadCacheCommand
bool cmLoadCacheCommand
@@ -32,7 +33,7 @@ bool cmLoadCacheCommand
// and they can not be overridden.
bool excludeFiles=false;
unsigned int i;
- std::set<cmStdString> excludes;
+ std::set<std::string> excludes;
for(i=0; i<args.size(); i++)
{
@@ -54,7 +55,7 @@ bool cmLoadCacheCommand
// If this set is empty, no internal cache entries are
// brought in.
bool includeFiles=false;
- std::set<cmStdString> includes;
+ std::set<std::string> includes;
for(i=0; i<args.size(); i++)
{
@@ -80,8 +81,8 @@ bool cmLoadCacheCommand
{
break;
}
- this->Makefile->GetCacheManager()->LoadCache(args[i].c_str(), false,
- excludes, includes);
+ this->Makefile->GetCMakeInstance()->LoadCache(args[i], false,
+ excludes, includes);
}
@@ -103,19 +104,16 @@ bool cmLoadCacheCommand::ReadWithPrefix(std::vector<std::string> const& args)
if(!cmSystemTools::FileExists(cacheFile.c_str()))
{
std::string e = "Cannot load cache file from " + cacheFile;
- this->SetError(e.c_str());
+ this->SetError(e);
return false;
}
// Prepare the table of variables to read.
this->Prefix = args[2];
- for(unsigned int i=3; i < args.size(); ++i)
- {
- this->VariablesToRead.insert(args[i]);
- }
+ this->VariablesToRead.insert(args.begin() + 3, args.end());
// Read the cache file.
- std::ifstream fin(cacheFile.c_str());
+ cmsys::ifstream fin(cacheFile.c_str());
// This is a big hack read loop to overcome a buggy ifstream
// implementation on HP-UX. This should work on all platforms even
@@ -159,7 +157,7 @@ bool cmLoadCacheCommand::ReadWithPrefix(std::vector<std::string> const& args)
}
}
}
- if(line.length())
+ if(!line.empty())
{
// Partial last line.
this->CheckLine(line.c_str());
@@ -174,8 +172,8 @@ void cmLoadCacheCommand::CheckLine(const char* line)
// Check one line of the cache file.
std::string var;
std::string value;
- cmCacheManager::CacheEntryType type = cmCacheManager::UNINITIALIZED;
- if(cmCacheManager::ParseEntry(line, var, value, type))
+ cmState::CacheEntryType type = cmState::UNINITIALIZED;
+ if(cmake::ParseCacheEntry(line, var, value, type))
{
// Found a real entry. See if this one was requested.
if(this->VariablesToRead.find(var) != this->VariablesToRead.end())
@@ -183,13 +181,13 @@ void cmLoadCacheCommand::CheckLine(const char* line)
// This was requested. Set this variable locally with the given
// prefix.
var = this->Prefix + var;
- if(value.length())
+ if(!value.empty())
{
- this->Makefile->AddDefinition(var.c_str(), value.c_str());
+ this->Makefile->AddDefinition(var, value.c_str());
}
else
{
- this->Makefile->RemoveDefinition(var.c_str());
+ this->Makefile->RemoveDefinition(var);
}
}
}
diff --git a/Source/cmLoadCacheCommand.h b/Source/cmLoadCacheCommand.h
index f55cbb3c1..04207d0dd 100644
--- a/Source/cmLoadCacheCommand.h
+++ b/Source/cmLoadCacheCommand.h
@@ -40,45 +40,12 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "load_cache";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Load in the values from another project's CMake cache.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " load_cache(pathToCacheFile READ_WITH_PREFIX\n"
- " prefix entry1...)\n"
- "Read the cache and store the requested entries in variables with "
- "their name prefixed with the given prefix. "
- "This only reads the values, and does not create entries in the local "
- "project's cache.\n"
- " load_cache(pathToCacheFile [EXCLUDE entry1...]\n"
- " [INCLUDE_INTERNALS entry1...])\n"
- "Load in the values from another cache and store them in the local "
- "project's cache as internal entries. This is useful for a project "
- "that depends on another project built in a different tree. "
- "EXCLUDE option can be used to provide a list of entries to be "
- "excluded. "
- "INCLUDE_INTERNALS can be used to provide a list of internal entries "
- "to be included. Normally, no internal entries are brought in. Use "
- "of this form of the command is strongly discouraged, but it is "
- "provided for backward compatibility.";
- }
+ virtual std::string GetName() const { return "load_cache";}
cmTypeMacro(cmLoadCacheCommand, cmCommand);
protected:
- std::set<cmStdString> VariablesToRead;
+ std::set<std::string> VariablesToRead;
std::string Prefix;
bool ReadWithPrefix(std::vector<std::string> const& args);
diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx
index b2acf06ad..403f7fcc8 100644
--- a/Source/cmLoadCommandCommand.cxx
+++ b/Source/cmLoadCommandCommand.cxx
@@ -69,25 +69,8 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return info.Name; }
+ virtual std::string GetName() const { return info.Name; }
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- if (this->info.GetTerseDocumentation)
- {
- cmLoadedCommand::InstallSignalHandlers(info.Name);
- const char* ret = info.GetTerseDocumentation();
- cmLoadedCommand::InstallSignalHandlers(info.Name, 1);
- return ret;
- }
- else
- {
- return "LoadedCommand without any additional documentation";
- }
- }
static const char* LastName;
static void TrapsForSignals(int sig)
{
@@ -120,24 +103,6 @@ public:
}
}
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- if (this->info.GetFullDocumentation)
- {
- cmLoadedCommand::InstallSignalHandlers(info.Name);
- const char* ret = info.GetFullDocumentation();
- cmLoadedCommand::InstallSignalHandlers(info.Name, 1);
- return ret;
- }
- else
- {
- return "LoadedCommand without any additional documentation";
- }
- }
-
cmTypeMacro(cmLoadedCommand, cmCommand);
cmLoadedCommandInfo info;
@@ -224,6 +189,9 @@ cmLoadedCommand::~cmLoadedCommand()
bool cmLoadCommandCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
+ if(this->Disallowed(cmPolicies::CMP0031,
+ "The load_command command should not be called; see CMP0031."))
+ { return true; }
if(args.size() < 1 )
{
return true;
@@ -233,7 +201,7 @@ bool cmLoadCommandCommand
// Start by removing the definition in case of failure.
std::string reportVar = "CMAKE_LOADED_COMMAND_";
reportVar += args[0];
- this->Makefile->RemoveDefinition(reportVar.c_str());
+ this->Makefile->RemoveDefinition(reportVar);
// the file must exist
std::string moduleName =
@@ -251,17 +219,17 @@ bool cmLoadCommandCommand
cmSystemTools::ExpandRegistryValues(exp);
// Glob the entry in case of wildcards.
- cmSystemTools::GlobDirs(exp.c_str(), path);
+ cmSystemTools::GlobDirs(exp, path);
}
// Try to find the program.
std::string fullPath = cmSystemTools::FindFile(moduleName.c_str(), path);
if (fullPath == "")
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Attempt to load command failed from file \""
<< moduleName << "\"";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
@@ -278,12 +246,12 @@ bool cmLoadCommandCommand
err += " Additional error info is:\n";
err += error;
}
- this->SetError(err.c_str());
+ this->SetError(err);
return false;
}
// Report what file was loaded for this command.
- this->Makefile->AddDefinition(reportVar.c_str(), fullPath.c_str());
+ this->Makefile->AddDefinition(reportVar, fullPath.c_str());
// find the init function
std::string initFuncName = args[0] + "Init";
@@ -305,7 +273,7 @@ bool cmLoadCommandCommand
// create a function blocker and set it up
cmLoadedCommand *f = new cmLoadedCommand();
(*initFunction)(&f->info);
- this->Makefile->AddCommand(f);
+ this->Makefile->GetState()->AddCommand(f);
return true;
}
this->SetError("Attempt to load command failed. "
diff --git a/Source/cmLoadCommandCommand.h b/Source/cmLoadCommandCommand.h
index f0b34ee59..445e16772 100644
--- a/Source/cmLoadCommandCommand.h
+++ b/Source/cmLoadCommandCommand.h
@@ -14,59 +14,13 @@
#include "cmCommand.h"
-/** \class cmLoadCommandCommand
- * \brief Load in a Command plugin
- *
- * cmLoadCommandCommand loads a command into CMake
- */
class cmLoadCommandCommand : public cmCommand
{
public:
- /**
- * This is a virtual constructor for the command.
- */
- virtual cmCommand* Clone()
- {
- return new cmLoadCommandCommand;
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
+ virtual cmCommand* Clone() { return new cmLoadCommandCommand; }
virtual bool InitialPass(std::vector<std::string> const& args,
cmExecutionStatus &status);
-
- /**
- * The name of the command as specified in CMakeList.txt.
- */
- virtual const char* GetName() const {return "load_command";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Load a command into a running CMake.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " load_command(COMMAND_NAME <loc1> [loc2 ...])\n"
- "The given locations are searched for a library whose name is "
- "cmCOMMAND_NAME. If found, it is loaded as a module and the command "
- "is added to the set of available CMake commands. Usually, "
- "TRY_COMPILE is used before this command to compile the module. "
- "If the command is successfully loaded a variable named\n"
- " CMAKE_LOADED_COMMAND_<COMMAND_NAME>\n"
- "will be set to the full path of the module that was loaded. "
- "Otherwise the variable will not be set.";
- }
-
+ virtual std::string GetName() const {return "load_command";}
cmTypeMacro(cmLoadCommandCommand, cmCommand);
};
diff --git a/Source/cmLocalCommonGenerator.cxx b/Source/cmLocalCommonGenerator.cxx
new file mode 100644
index 000000000..5a18e2f5f
--- /dev/null
+++ b/Source/cmLocalCommonGenerator.cxx
@@ -0,0 +1,39 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmLocalCommonGenerator.h"
+
+#include "cmMakefile.h"
+
+cmLocalCommonGenerator::cmLocalCommonGenerator(cmGlobalGenerator* gg,
+ cmMakefile* mf):
+ cmLocalGenerator(gg, mf)
+{
+}
+
+cmLocalCommonGenerator::~cmLocalCommonGenerator()
+{
+}
+
+void cmLocalCommonGenerator::SetConfigName()
+{
+ // Store the configuration name that will be generated.
+ if(const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"))
+ {
+ // Use the build type given by the user.
+ this->ConfigName = config;
+ }
+ else
+ {
+ // No configuration type given.
+ this->ConfigName = "";
+ }
+}
diff --git a/Source/cmLocalCommonGenerator.h b/Source/cmLocalCommonGenerator.h
new file mode 100644
index 000000000..6b4b1cdbb
--- /dev/null
+++ b/Source/cmLocalCommonGenerator.h
@@ -0,0 +1,37 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmLocalCommonGenerator_h
+#define cmLocalCommonGenerator_h
+
+#include "cmLocalGenerator.h"
+
+class cmCommonTargetGenerator;
+
+/** \class cmLocalCommonGenerator
+ * \brief Common infrastructure for Makefile and Ninja local generators.
+ */
+class cmLocalCommonGenerator: public cmLocalGenerator
+{
+public:
+ cmLocalCommonGenerator(cmGlobalGenerator* gg, cmMakefile* mf);
+ ~cmLocalCommonGenerator();
+
+ std::string const& GetConfigName() { return this->ConfigName; }
+
+protected:
+ void SetConfigName();
+ std::string ConfigName;
+
+ friend class cmCommonTargetGenerator;
+};
+
+#endif
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 9c0410965..912be0c0f 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -16,110 +16,70 @@
#include "cmGlobalGenerator.h"
#include "cmInstallGenerator.h"
#include "cmInstallFilesGenerator.h"
+#include "cmGeneratorExpressionEvaluationFile.h"
#include "cmInstallScriptGenerator.h"
#include "cmInstallTargetGenerator.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
#include "cmTest.h"
#include "cmTestGenerator.h"
+#include "cmCustomCommandGenerator.h"
#include "cmVersion.h"
#include "cmake.h"
+#include "cmAlgorithms.h"
#if defined(CMAKE_BUILD_WITH_CMAKE)
# define CM_LG_ENCODE_OBJECT_NAMES
# include <cmsys/MD5.h>
#endif
-#include <cmsys/System.h>
-
#include <ctype.h> // for isalpha
#include <assert.h>
#if defined(__HAIKU__)
-#include <StorageKit.h>
+#include <FindDirectory.h>
+#include <StorageDefs.h>
#endif
-cmLocalGenerator::cmLocalGenerator()
-{
- this->Makefile = 0; // moved to after set on global
- this->Parent = 0;
- this->WindowsShell = false;
- this->WindowsVSIDE = false;
- this->WatcomWMake = false;
- this->MinGWMake = false;
- this->NMake = false;
- this->MSYSShell = false;
- this->LinkScriptShell = false;
- this->IgnoreLibPrefix = false;
- this->UseRelativePaths = false;
- this->Configured = false;
+cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg,
+ cmMakefile* makefile)
+ : cmOutputConverter(makefile->GetStateSnapshot()),
+ StateSnapshot(makefile->GetStateSnapshot())
+{
+ this->GlobalGenerator = gg;
+
+ this->Makefile = makefile;
+
+ this->AliasTargets = makefile->GetAliasTargets();
+
this->EmitUniversalBinaryFlags = true;
- this->RelativePathsConfigured = false;
- this->PathConversionsSetup = false;
this->BackwardsCompatibility = 0;
this->BackwardsCompatibilityFinal = false;
+
+ this->ComputeObjectMaxPath();
}
cmLocalGenerator::~cmLocalGenerator()
{
- delete this->Makefile;
+ cmDeleteAll(this->GeneratorTargets);
+ cmDeleteAll(this->OwnedImportedGeneratorTargets);
}
-//----------------------------------------------------------------------------
-class cmLocalGeneratorCurrent
+void cmLocalGenerator::IssueMessage(cmake::MessageType t,
+ std::string const& text) const
{
- cmGlobalGenerator* GG;
- cmLocalGenerator* LG;
-public:
- cmLocalGeneratorCurrent(cmLocalGenerator* lg)
- {
- this->GG = lg->GetGlobalGenerator();
- this->LG = this->GG->GetCurrentLocalGenerator();
- this->GG->SetCurrentLocalGenerator(lg);
- }
- ~cmLocalGeneratorCurrent()
- {
- this->GG->SetCurrentLocalGenerator(this->LG);
- }
-};
-
-//----------------------------------------------------------------------------
-void cmLocalGenerator::Configure()
-{
- // Manage the global generator's current local generator.
- cmLocalGeneratorCurrent clg(this);
- static_cast<void>(clg);
-
- // make sure the CMakeFiles dir is there
- std::string filesDir = this->Makefile->GetStartOutputDirectory();
- filesDir += cmake::GetCMakeFilesDirectory();
- cmSystemTools::MakeDirectory(filesDir.c_str());
+ cmListFileContext lfc;
+ lfc.FilePath = this->StateSnapshot.GetDirectory().GetCurrentSource();
+ lfc.FilePath += "/CMakeLists.txt";
- // find & read the list file
- this->ReadInputFile();
-
- // at the end of the ReadListFile handle any old style subdirs
- // first get all the subdirectories
- std::vector<cmLocalGenerator *> subdirs = this->GetChildren();
-
- // for each subdir recurse
- std::vector<cmLocalGenerator *>::iterator sdi = subdirs.begin();
- for (; sdi != subdirs.end(); ++sdi)
+ if(!this->GlobalGenerator->GetCMakeInstance()->GetIsInTryCompile())
{
- if (!(*sdi)->Configured)
- {
- this->Makefile->ConfigureSubDirectory(*sdi);
- }
+ cmOutputConverter converter(this->StateSnapshot);
+ lfc.FilePath = converter.Convert(lfc.FilePath, cmLocalGenerator::HOME);
}
-
- // Check whether relative paths should be used for optionally
- // relative paths.
- this->UseRelativePaths = this->Makefile->IsOn("CMAKE_USE_RELATIVE_PATHS");
-
- this->ComputeObjectMaxPath();
-
- this->Configured = true;
+ lfc.Line = 0;
+ this->GlobalGenerator->GetCMakeInstance()->IssueMessage(t, text, lfc);
}
//----------------------------------------------------------------------------
@@ -143,123 +103,48 @@ void cmLocalGenerator::ComputeObjectMaxPath()
}
else
{
- cmOStringStream w;
+ std::ostringstream w;
w << "CMAKE_OBJECT_PATH_MAX is set to " << pmax
<< ", which is less than the minimum of 128. "
<< "The value will be ignored.";
- this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ this->IssueMessage(cmake::AUTHOR_WARNING, w.str());
}
}
else
{
- cmOStringStream w;
+ std::ostringstream w;
w << "CMAKE_OBJECT_PATH_MAX is set to \"" << plen
<< "\", which fails to parse as a positive integer. "
<< "The value will be ignored.";
- this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ this->IssueMessage(cmake::AUTHOR_WARNING, w.str());
}
}
this->ObjectMaxPathViolations.clear();
}
-//----------------------------------------------------------------------------
-void cmLocalGenerator::ReadInputFile()
+void cmLocalGenerator::TraceDependencies()
{
- // Look for the CMakeLists.txt file.
- std::string currentStart = this->Makefile->GetStartDirectory();
- currentStart += "/CMakeLists.txt";
- if(cmSystemTools::FileExists(currentStart.c_str(), true))
+ std::vector<std::string> configs;
+ this->Makefile->GetConfigurations(configs);
+ if (configs.empty())
{
- this->Makefile->ReadListFile(currentStart.c_str());
- return;
+ configs.push_back("");
}
-
- if(!this->Parent)
+ for(std::vector<std::string>::const_iterator ci = configs.begin();
+ ci != configs.end(); ++ci)
{
- return;
+ this->GlobalGenerator->CreateEvaluationSourceFiles(*ci);
}
-
- // The file is missing. Check policy CMP0014.
- cmMakefile* mf = this->Parent->GetMakefile();
- cmOStringStream e;
- e << "The source directory\n"
- << " " << this->Makefile->GetStartDirectory() << "\n"
- << "does not contain a CMakeLists.txt file.";
- switch (mf->GetPolicyStatus(cmPolicies::CMP0014))
- {
- case cmPolicies::WARN:
- // Print the warning.
- e << "\n"
- << "CMake does not support this case but it used "
- << "to work accidentally and is being allowed for "
- << "compatibility."
- << "\n"
- << mf->GetPolicies()->GetPolicyWarning(cmPolicies::CMP0014);
- mf->IssueMessage(cmake::AUTHOR_WARNING, e.str());
- case cmPolicies::OLD:
- // OLD behavior does not warn.
- return;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- e << "\n"
- << mf->GetPolicies()->GetRequiredPolicyError(cmPolicies::CMP0014);
- case cmPolicies::NEW:
- // NEW behavior prints the error.
- mf->IssueMessage(cmake::FATAL_ERROR, e.str());
- break;
- }
-}
-
-void cmLocalGenerator::SetupPathConversions()
-{
- // Setup the current output directory components for use by
- // Convert
- std::string outdir;
- outdir =
- cmSystemTools::CollapseFullPath(this->Makefile->GetHomeDirectory());
- cmSystemTools::SplitPath(outdir.c_str(), this->HomeDirectoryComponents);
- outdir =
- cmSystemTools::CollapseFullPath(this->Makefile->GetStartDirectory());
- cmSystemTools::SplitPath(outdir.c_str(), this->StartDirectoryComponents);
-
- outdir = cmSystemTools::CollapseFullPath
- (this->Makefile->GetHomeOutputDirectory());
- cmSystemTools::SplitPath(outdir.c_str(),
- this->HomeOutputDirectoryComponents);
-
- outdir = cmSystemTools::CollapseFullPath
- (this->Makefile->GetStartOutputDirectory());
- cmSystemTools::SplitPath(outdir.c_str(),
- this->StartOutputDirectoryComponents);
-}
-
-
-void cmLocalGenerator::SetGlobalGenerator(cmGlobalGenerator *gg)
-{
- this->GlobalGenerator = gg;
- this->Makefile = new cmMakefile;
- this->Makefile->SetLocalGenerator(this);
-
- // setup the home directories
- this->Makefile->GetProperties().SetCMakeInstance(gg->GetCMakeInstance());
- this->Makefile->SetHomeDirectory(
- gg->GetCMakeInstance()->GetHomeDirectory());
- this->Makefile->SetHomeOutputDirectory(
- gg->GetCMakeInstance()->GetHomeOutputDirectory());
-}
-
-void cmLocalGenerator::ConfigureFinalPass()
-{
- this->Makefile->ConfigureFinalPass();
-}
-
-void cmLocalGenerator::TraceDependencies()
-{
// Generate the rule files for each target.
- cmTargets& targets = this->Makefile->GetTargets();
- for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
+ std::vector<cmGeneratorTarget*> targets = this->GetGeneratorTargets();
+ for(std::vector<cmGeneratorTarget*>::iterator t = targets.begin();
+ t != targets.end(); ++t)
{
- t->second.TraceDependencies();
+ if ((*t)->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ continue;
+ }
+ (*t)->TraceDependencies();
}
}
@@ -272,10 +157,11 @@ void cmLocalGenerator::GenerateTestFiles()
// Compute the set of configurations.
std::vector<std::string> configurationTypes;
- const char* config =
+ const std::string& config =
this->Makefile->GetConfigurations(configurationTypes, false);
- std::string file = this->Makefile->GetStartOutputDirectory();
+ std::string file =
+ this->StateSnapshot.GetDirectory().GetCurrentBinary();
file += "/";
file += "CTestTestfile.cmake";
@@ -284,9 +170,11 @@ void cmLocalGenerator::GenerateTestFiles()
fout << "# CMake generated Testfile for " << std::endl
<< "# Source directory: "
- << this->Makefile->GetStartDirectory() << std::endl
+ << this->StateSnapshot.GetDirectory().GetCurrentSource()
+ << std::endl
<< "# Build directory: "
- << this->Makefile->GetStartOutputDirectory() << std::endl
+ << this->StateSnapshot.GetDirectory().GetCurrentBinary()
+ << std::endl
<< "# " << std::endl
<< "# This file includes the relevant testing commands "
<< "required for " << std::endl
@@ -297,7 +185,7 @@ void cmLocalGenerator::GenerateTestFiles()
this->Makefile->GetProperty("TEST_INCLUDE_FILE");
if ( testIncludeFile )
{
- fout << "INCLUDE(\"" << testIncludeFile << "\")" << std::endl;
+ fout << "include(\"" << testIncludeFile << "\")" << std::endl;
}
// Ask each test generator to write its code.
@@ -306,19 +194,66 @@ void cmLocalGenerator::GenerateTestFiles()
for(std::vector<cmTestGenerator*>::const_iterator gi = testers.begin();
gi != testers.end(); ++gi)
{
+ (*gi)->Compute(this);
(*gi)->Generate(fout, config, configurationTypes);
}
- if ( this->Children.size())
+ size_t i;
+ std::vector<cmState::Snapshot> children
+ = this->Makefile->GetStateSnapshot().GetChildren();
+ for(i = 0; i < children.size(); ++i)
+ {
+ // TODO: Use add_subdirectory instead?
+ fout << "subdirs(";
+ std::string outP = children[i].GetDirectory().GetCurrentBinary();
+ fout << this->Convert(outP,START_OUTPUT);
+ fout << ")" << std::endl;
+ }
+}
+
+void cmLocalGenerator::CreateEvaluationFileOutputs(std::string const& config)
+{
+ std::vector<cmGeneratorExpressionEvaluationFile*> ef =
+ this->Makefile->GetEvaluationFiles();
+ for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator
+ li = ef.begin(); li != ef.end(); ++li)
+ {
+ (*li)->CreateOutputFile(this, config);
+ }
+}
+
+void cmLocalGenerator::ProcessEvaluationFiles(
+ std::vector<std::string>& generatedFiles)
+{
+ std::vector<cmGeneratorExpressionEvaluationFile*> ef =
+ this->Makefile->GetEvaluationFiles();
+ for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator
+ li = ef.begin();
+ li != ef.end();
+ ++li)
{
- size_t i;
- for(i = 0; i < this->Children.size(); ++i)
+ (*li)->Generate(this);
+ if (cmSystemTools::GetFatalErrorOccured())
{
- fout << "SUBDIRS(";
- std::string outP =
- this->Children[i]->GetMakefile()->GetStartOutputDirectory();
- fout << this->Convert(outP.c_str(),START_OUTPUT);
- fout << ")" << std::endl;
+ return;
+ }
+ std::vector<std::string> files = (*li)->GetFiles();
+ std::sort(files.begin(), files.end());
+
+ std::vector<std::string> intersection;
+ std::set_intersection(files.begin(), files.end(),
+ generatedFiles.begin(), generatedFiles.end(),
+ std::back_inserter(intersection));
+ if (!intersection.empty())
+ {
+ cmSystemTools::Error("Files to be generated by multiple different "
+ "commands: ", cmWrap('"', intersection, '"', " ").c_str());
+ return;
}
+
+ generatedFiles.insert(generatedFiles.end(), files.begin(), files.end());
+ std::vector<std::string>::iterator newIt =
+ generatedFiles.end() - files.size();
+ std::inplace_merge(generatedFiles.begin(), newIt, generatedFiles.end());
}
}
@@ -348,16 +283,17 @@ void cmLocalGenerator::GenerateInstallRules()
prefix = prefix_win32.c_str();
}
#elif defined(__HAIKU__)
+ char dir[B_PATH_NAME_LENGTH];
if (!prefix)
{
- BPath dir;
- if (find_directory(B_COMMON_DIRECTORY, &dir) == B_OK)
+ if (find_directory(B_SYSTEM_DIRECTORY, -1, false, dir, sizeof(dir))
+ == B_OK)
{
- prefix = dir.Path();
+ prefix = dir;
}
else
{
- prefix = "/boot/common";
+ prefix = "/boot/system";
}
}
#else
@@ -366,45 +302,43 @@ void cmLocalGenerator::GenerateInstallRules()
prefix = "/usr/local";
}
#endif
+ if (const char *stagingPrefix
+ = this->Makefile->GetDefinition("CMAKE_STAGING_PREFIX"))
+ {
+ prefix = stagingPrefix;
+ }
// Compute the set of configurations.
std::vector<std::string> configurationTypes;
- const char* config =
+ const std::string& config =
this->Makefile->GetConfigurations(configurationTypes, false);
// Choose a default install configuration.
- const char* default_config = config;
+ std::string default_config = config;
const char* default_order[] = {"RELEASE", "MINSIZEREL",
"RELWITHDEBINFO", "DEBUG", 0};
- for(const char** c = default_order; *c && !default_config; ++c)
+ for(const char** c = default_order; *c && default_config.empty(); ++c)
{
for(std::vector<std::string>::iterator i = configurationTypes.begin();
i != configurationTypes.end(); ++i)
{
if(cmSystemTools::UpperCase(*i) == *c)
{
- default_config = i->c_str();
+ default_config = *i;
}
}
}
- if(!default_config && !configurationTypes.empty())
- {
- default_config = configurationTypes[0].c_str();
- }
- if(!default_config)
+ if(default_config.empty() && !configurationTypes.empty())
{
- default_config = "Release";
+ default_config = configurationTypes[0];
}
// Create the install script file.
- std::string file = this->Makefile->GetStartOutputDirectory();
- std::string homedir = this->Makefile->GetHomeOutputDirectory();
- std::string currdir = this->Makefile->GetCurrentOutputDirectory();
- cmSystemTools::ConvertToUnixSlashes(file);
- cmSystemTools::ConvertToUnixSlashes(homedir);
- cmSystemTools::ConvertToUnixSlashes(currdir);
+ std::string file =
+ this->StateSnapshot.GetDirectory().GetCurrentBinary();
+ std::string homedir = this->GetState()->GetBinaryDirectory();
int toplevel_install = 0;
- if ( currdir == homedir )
+ if (file == homedir)
{
toplevel_install = 1;
}
@@ -414,41 +348,42 @@ void cmLocalGenerator::GenerateInstallRules()
// Write the header.
fout << "# Install script for directory: "
- << this->Makefile->GetCurrentDirectory() << std::endl << std::endl;
+ << this->StateSnapshot.GetDirectory().GetCurrentSource()
+ << std::endl << std::endl;
fout << "# Set the install prefix" << std::endl
- << "IF(NOT DEFINED CMAKE_INSTALL_PREFIX)" << std::endl
- << " SET(CMAKE_INSTALL_PREFIX \"" << prefix << "\")" << std::endl
- << "ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX)" << std::endl
- << "STRING(REGEX REPLACE \"/$\" \"\" CMAKE_INSTALL_PREFIX "
+ << "if(NOT DEFINED CMAKE_INSTALL_PREFIX)" << std::endl
+ << " set(CMAKE_INSTALL_PREFIX \"" << prefix << "\")" << std::endl
+ << "endif()" << std::endl
+ << "string(REGEX REPLACE \"/$\" \"\" CMAKE_INSTALL_PREFIX "
<< "\"${CMAKE_INSTALL_PREFIX}\")" << std::endl
<< std::endl;
// Write support code for generating per-configuration install rules.
fout <<
"# Set the install configuration name.\n"
- "IF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)\n"
- " IF(BUILD_TYPE)\n"
- " STRING(REGEX REPLACE \"^[^A-Za-z0-9_]+\" \"\"\n"
+ "if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)\n"
+ " if(BUILD_TYPE)\n"
+ " string(REGEX REPLACE \"^[^A-Za-z0-9_]+\" \"\"\n"
" CMAKE_INSTALL_CONFIG_NAME \"${BUILD_TYPE}\")\n"
- " ELSE(BUILD_TYPE)\n"
- " SET(CMAKE_INSTALL_CONFIG_NAME \"" << default_config << "\")\n"
- " ENDIF(BUILD_TYPE)\n"
- " MESSAGE(STATUS \"Install configuration: "
+ " else()\n"
+ " set(CMAKE_INSTALL_CONFIG_NAME \"" << default_config << "\")\n"
+ " endif()\n"
+ " message(STATUS \"Install configuration: "
"\\\"${CMAKE_INSTALL_CONFIG_NAME}\\\"\")\n"
- "ENDIF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)\n"
+ "endif()\n"
"\n";
// Write support code for dealing with component-specific installs.
fout <<
"# Set the component getting installed.\n"
- "IF(NOT CMAKE_INSTALL_COMPONENT)\n"
- " IF(COMPONENT)\n"
- " MESSAGE(STATUS \"Install component: \\\"${COMPONENT}\\\"\")\n"
- " SET(CMAKE_INSTALL_COMPONENT \"${COMPONENT}\")\n"
- " ELSE(COMPONENT)\n"
- " SET(CMAKE_INSTALL_COMPONENT)\n"
- " ENDIF(COMPONENT)\n"
- "ENDIF(NOT CMAKE_INSTALL_COMPONENT)\n"
+ "if(NOT CMAKE_INSTALL_COMPONENT)\n"
+ " if(COMPONENT)\n"
+ " message(STATUS \"Install component: \\\"${COMPONENT}\\\"\")\n"
+ " set(CMAKE_INSTALL_COMPONENT \"${COMPONENT}\")\n"
+ " else()\n"
+ " set(CMAKE_INSTALL_COMPONENT)\n"
+ " endif()\n"
+ "endif()\n"
"\n";
// Copy user-specified install options to the install code.
@@ -457,9 +392,9 @@ void cmLocalGenerator::GenerateInstallRules()
{
fout <<
"# Install shared libraries without execute permission?\n"
- "IF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)\n"
- " SET(CMAKE_INSTALL_SO_NO_EXE \"" << so_no_exe << "\")\n"
- "ENDIF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)\n"
+ "if(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)\n"
+ " set(CMAKE_INSTALL_SO_NO_EXE \"" << so_no_exe << "\")\n"
+ "endif()\n"
"\n";
}
@@ -477,300 +412,147 @@ void cmLocalGenerator::GenerateInstallRules()
this->GenerateTargetInstallRules(fout, config, configurationTypes);
// Include install scripts from subdirectories.
- if(!this->Children.empty())
+ std::vector<cmState::Snapshot> children
+ = this->Makefile->GetStateSnapshot().GetChildren();
+ if(!children.empty())
{
- fout << "IF(NOT CMAKE_INSTALL_LOCAL_ONLY)\n";
+ fout << "if(NOT CMAKE_INSTALL_LOCAL_ONLY)\n";
fout << " # Include the install script for each subdirectory.\n";
- for(std::vector<cmLocalGenerator*>::const_iterator
- ci = this->Children.begin(); ci != this->Children.end(); ++ci)
+ for(std::vector<cmState::Snapshot>::const_iterator
+ ci = children.begin(); ci != children.end(); ++ci)
{
- if(!(*ci)->GetMakefile()->GetPropertyAsBool("EXCLUDE_FROM_ALL"))
+ if(!ci->GetDirectory().GetPropertyAsBool("EXCLUDE_FROM_ALL"))
{
- std::string odir = (*ci)->GetMakefile()->GetStartOutputDirectory();
+ std::string odir = ci->GetDirectory().GetCurrentBinary();
cmSystemTools::ConvertToUnixSlashes(odir);
- fout << " INCLUDE(\"" << odir.c_str()
+ fout << " include(\"" << odir
<< "/cmake_install.cmake\")" << std::endl;
}
}
fout << "\n";
- fout << "ENDIF(NOT CMAKE_INSTALL_LOCAL_ONLY)\n\n";
+ fout << "endif()\n\n";
}
// Record the install manifest.
if ( toplevel_install )
{
fout <<
- "IF(CMAKE_INSTALL_COMPONENT)\n"
- " SET(CMAKE_INSTALL_MANIFEST \"install_manifest_"
+ "if(CMAKE_INSTALL_COMPONENT)\n"
+ " set(CMAKE_INSTALL_MANIFEST \"install_manifest_"
"${CMAKE_INSTALL_COMPONENT}.txt\")\n"
- "ELSE(CMAKE_INSTALL_COMPONENT)\n"
- " SET(CMAKE_INSTALL_MANIFEST \"install_manifest.txt\")\n"
- "ENDIF(CMAKE_INSTALL_COMPONENT)\n\n";
- fout
- << "FILE(WRITE \""
- << homedir.c_str() << "/${CMAKE_INSTALL_MANIFEST}\" "
- << "\"\")" << std::endl;
- fout
- << "FOREACH(file ${CMAKE_INSTALL_MANIFEST_FILES})" << std::endl
- << " FILE(APPEND \""
- << homedir.c_str() << "/${CMAKE_INSTALL_MANIFEST}\" "
- << "\"${file}\\n\")" << std::endl
- << "ENDFOREACH(file)" << std::endl;
+ "else()\n"
+ " set(CMAKE_INSTALL_MANIFEST \"install_manifest.txt\")\n"
+ "endif()\n"
+ "\n"
+ "string(REPLACE \";\" \"\\n\" CMAKE_INSTALL_MANIFEST_CONTENT\n"
+ " \"${CMAKE_INSTALL_MANIFEST_FILES}\")\n"
+ "file(WRITE \"" << homedir << "/${CMAKE_INSTALL_MANIFEST}\"\n"
+ " \"${CMAKE_INSTALL_MANIFEST_CONTENT}\")\n";
+ }
+}
+
+
+void cmLocalGenerator::AddGeneratorTarget(cmGeneratorTarget* gt)
+{
+ this->GeneratorTargets.push_back(gt);
+ this->GlobalGenerator->IndexGeneratorTarget(gt);
+}
+
+void cmLocalGenerator::AddImportedGeneratorTarget(cmGeneratorTarget* gt)
+{
+ this->ImportedGeneratorTargets.push_back(gt);
+ this->GlobalGenerator->IndexGeneratorTarget(gt);
+}
+
+void cmLocalGenerator::AddOwnedImportedGeneratorTarget(cmGeneratorTarget* gt)
+{
+ this->OwnedImportedGeneratorTargets.push_back(gt);
+}
+
+struct NamedGeneratorTargetFinder
+{
+ NamedGeneratorTargetFinder(std::string const& name)
+ : Name(name)
+ {
+
+ }
+
+ bool operator()(cmGeneratorTarget* tgt)
+ {
+ return tgt->GetName() == this->Name;
+ }
+private:
+ std::string Name;
+};
+
+cmGeneratorTarget* cmLocalGenerator::FindGeneratorTarget(
+ const std::string& name) const
+{
+ std::map<std::string, std::string>::const_iterator i =
+ this->AliasTargets.find(name);
+ if (i != this->AliasTargets.end())
+ {
+ std::vector<cmGeneratorTarget*>::const_iterator ai =
+ std::find_if(this->GeneratorTargets.begin(),
+ this->GeneratorTargets.end(),
+ NamedGeneratorTargetFinder(i->second));
+ return *ai;
+ }
+ std::vector<cmGeneratorTarget*>::const_iterator ti =
+ std::find_if(this->GeneratorTargets.begin(),
+ this->GeneratorTargets.end(),
+ NamedGeneratorTargetFinder(name));
+ if ( ti != this->GeneratorTargets.end() )
+ {
+ return *ti;
}
+
+ return 0;
}
//----------------------------------------------------------------------------
-void cmLocalGenerator::GenerateTargetManifest()
+void cmLocalGenerator::ComputeTargetManifest()
{
// Collect the set of configuration types.
std::vector<std::string> configNames;
this->Makefile->GetConfigurations(configNames);
+ if(configNames.empty())
+ {
+ configNames.push_back("");
+ }
// Add our targets to the manifest for each configuration.
- cmTargets& targets = this->Makefile->GetTargets();
- for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
+ std::vector<cmGeneratorTarget*> targets = this->GetGeneratorTargets();
+ for(std::vector<cmGeneratorTarget*>::iterator t = targets.begin();
+ t != targets.end(); ++t)
{
- cmTarget& target = t->second;
- if(configNames.empty())
+ cmGeneratorTarget* target = *t;
+ if (target->GetType() == cmState::INTERFACE_LIBRARY)
{
- target.GenerateTargetManifest(0);
+ continue;
}
- else
+ for(std::vector<std::string>::iterator ci = configNames.begin();
+ ci != configNames.end(); ++ci)
{
- for(std::vector<std::string>::iterator ci = configNames.begin();
- ci != configNames.end(); ++ci)
- {
- const char* config = ci->c_str();
- target.GenerateTargetManifest(config);
- }
+ const char* config = ci->c_str();
+ target->ComputeTargetManifest(config);
}
}
}
-void cmLocalGenerator::AddCustomCommandToCreateObject(const char* ofname,
- const char* lang,
- cmSourceFile& source,
- cmGeneratorTarget& target)
-{
- std::string objectDir = cmSystemTools::GetFilenamePath(std::string(ofname));
- objectDir = this->Convert(objectDir.c_str(),START_OUTPUT,SHELL);
- std::string objectFile = this->Convert(ofname,START_OUTPUT,SHELL);
- std::string sourceFile =
- this->Convert(source.GetFullPath().c_str(),START_OUTPUT,SHELL,true);
- std::string varString = "CMAKE_";
- varString += lang;
- varString += "_COMPILE_OBJECT";
- std::vector<std::string> rules;
- rules.push_back(this->Makefile->GetRequiredDefinition(varString.c_str()));
- varString = "CMAKE_";
- varString += lang;
- varString += "_FLAGS";
- std::string flags;
- flags += this->Makefile->GetSafeDefinition(varString.c_str());
- flags += " ";
- {
- std::vector<std::string> includes;
- this->GetIncludeDirectories(includes, &target, lang);
- flags += this->GetIncludeFlags(includes, &target, lang);
- }
- flags += this->Makefile->GetDefineFlags();
-
- // Construct the command lines.
- cmCustomCommandLines commandLines;
- std::vector<std::string> commands;
- cmSystemTools::ExpandList(rules, commands);
- cmLocalGenerator::RuleVariables vars;
- vars.Language = lang;
- vars.Source = sourceFile.c_str();
- vars.Object = objectFile.c_str();
- vars.ObjectDir = objectDir.c_str();
- vars.Flags = flags.c_str();
- for(std::vector<std::string>::iterator i = commands.begin();
- i != commands.end(); ++i)
- {
- // Expand the full command line string.
- this->ExpandRuleVariables(*i, vars);
-
- // Parse the string to get the custom command line.
- cmCustomCommandLine commandLine;
- std::vector<cmStdString> cmd = cmSystemTools::ParseArguments(i->c_str());
- for(std::vector<cmStdString>::iterator a = cmd.begin();
- a != cmd.end(); ++a)
- {
- commandLine.push_back(*a);
- }
-
- // Store this command line.
- commandLines.push_back(commandLine);
- }
-
- // Check for extra object-file dependencies.
- std::vector<std::string> depends;
- const char* additionalDeps = source.GetProperty("OBJECT_DEPENDS");
- if(additionalDeps)
- {
- cmSystemTools::ExpandListArgument(additionalDeps, depends);
- }
-
- // Generate a meaningful comment for the command.
- std::string comment = "Building ";
- comment += lang;
- comment += " object ";
- comment += this->Convert(ofname, START_OUTPUT);
-
- // Add the custom command to build the object file.
- this->Makefile->AddCustomCommandToOutput(
- ofname,
- depends,
- source.GetFullPath().c_str(),
- commandLines,
- comment.c_str(),
- this->Makefile->GetStartOutputDirectory()
- );
-}
-
-void cmLocalGenerator::AddBuildTargetRule(const char* llang,
- cmGeneratorTarget& target)
-{
- cmStdString objs;
- std::vector<std::string> objVector;
- // Add all the sources outputs to the depends of the target
- std::vector<cmSourceFile*> const& classes = target.GetSourceFiles();
- for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
- i != classes.end(); ++i)
- {
- cmSourceFile* sf = *i;
- if(!sf->GetCustomCommand() &&
- !sf->GetPropertyAsBool("HEADER_FILE_ONLY") &&
- !sf->GetPropertyAsBool("EXTERNAL_OBJECT"))
- {
- std::string dir_max;
- dir_max += this->Makefile->GetCurrentOutputDirectory();
- dir_max += "/";
- std::string obj = this->GetObjectFileNameWithoutTarget(*sf, dir_max);
- if(!obj.empty())
- {
- std::string ofname = this->Makefile->GetCurrentOutputDirectory();
- ofname += "/";
- ofname += obj;
- objVector.push_back(ofname);
- this->AddCustomCommandToCreateObject(ofname.c_str(),
- llang, *(*i), target);
- objs += this->Convert(ofname.c_str(),START_OUTPUT,MAKEFILE);
- objs += " ";
- }
- }
- }
- std::string createRule = "CMAKE_";
- createRule += llang;
- createRule += target.GetCreateRuleVariable();
- std::string targetName = target.Target->GetFullName();
- // Executable :
- // Shared Library:
- // Static Library:
- // Shared Module:
- std::string linkLibs; // should be set
- std::string frameworkPath;
- std::string linkPath;
- std::string flags; // should be set
- std::string linkFlags; // should be set
- this->GetTargetFlags(linkLibs, frameworkPath, linkPath, flags, linkFlags,
- &target);
- linkLibs = frameworkPath + linkPath + linkLibs;
- cmLocalGenerator::RuleVariables vars;
- vars.Language = llang;
- vars.Objects = objs.c_str();
- vars.ObjectDir = ".";
- vars.Target = targetName.c_str();
- vars.LinkLibraries = linkLibs.c_str();
- vars.Flags = flags.c_str();
- vars.LinkFlags = linkFlags.c_str();
-
- std::string langFlags;
- this->AddLanguageFlags(langFlags, llang, 0);
- this->AddArchitectureFlags(langFlags, &target, llang, 0);
- vars.LanguageCompileFlags = langFlags.c_str();
-
- cmCustomCommandLines commandLines;
- std::vector<std::string> rules;
- rules.push_back(this->Makefile->GetRequiredDefinition(createRule.c_str()));
- std::vector<std::string> commands;
- cmSystemTools::ExpandList(rules, commands);
- for(std::vector<std::string>::iterator i = commands.begin();
- i != commands.end(); ++i)
- {
- // Expand the full command line string.
- this->ExpandRuleVariables(*i, vars);
- // Parse the string to get the custom command line.
- cmCustomCommandLine commandLine;
- std::vector<cmStdString> cmd = cmSystemTools::ParseArguments(i->c_str());
- for(std::vector<cmStdString>::iterator a = cmd.begin();
- a != cmd.end(); ++a)
- {
- commandLine.push_back(*a);
- }
-
- // Store this command line.
- commandLines.push_back(commandLine);
- }
- std::string targetFullPath = target.Target->GetFullPath();
- // Generate a meaningful comment for the command.
- std::string comment = "Linking ";
- comment += llang;
- comment += " target ";
- comment += this->Convert(targetFullPath.c_str(), START_OUTPUT);
- this->Makefile->AddCustomCommandToOutput(
- targetFullPath.c_str(),
- objVector,
- 0,
- commandLines,
- comment.c_str(),
- this->Makefile->GetStartOutputDirectory()
- );
- target.Target->AddSourceFile
- (this->Makefile->GetSource(targetFullPath.c_str()));
+bool cmLocalGenerator::IsRootMakefile() const
+{
+ return !this->StateSnapshot.GetBuildsystemDirectoryParent().IsValid();
}
+cmState* cmLocalGenerator::GetState() const
+{
+ return this->GlobalGenerator->GetCMakeInstance()->GetState();
+}
-void cmLocalGenerator
-::CreateCustomTargetsAndCommands(std::set<cmStdString> const& lang)
+cmState::Snapshot cmLocalGenerator::GetStateSnapshot() const
{
- cmGeneratorTargetsType tgts = this->Makefile->GetGeneratorTargets();
- for(cmGeneratorTargetsType::iterator l = tgts.begin();
- l != tgts.end(); l++)
- {
- if (l->first->IsImported())
- {
- continue;
- }
- cmGeneratorTarget& target = *l->second;
- switch(target.GetType())
- {
- case cmTarget::STATIC_LIBRARY:
- case cmTarget::SHARED_LIBRARY:
- case cmTarget::MODULE_LIBRARY:
- case cmTarget::EXECUTABLE:
- {
- const char* llang = target.Target->GetLinkerLanguage();
- if(!llang)
- {
- cmSystemTools::Error
- ("CMake can not determine linker language for target: ",
- target.Target->GetName());
- return;
- }
- // if the language is not in the set lang then create custom
- // commands to build the target
- if(lang.count(llang) == 0)
- {
- this->AddBuildTargetRule(llang, target);
- }
- }
- break;
- default:
- break;
- }
- }
+ return this->Makefile->GetStateSnapshot();
}
// List of variables that are replaced when
@@ -793,6 +575,7 @@ static const char* ruleReplaceVars[] =
"CMAKE_CURRENT_BINARY_DIR",
"CMAKE_RANLIB",
"CMAKE_LINKER",
+ "CMAKE_CL_SHOWINCLUDES_PREFIX",
0
};
@@ -807,6 +590,13 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
return replaceValues.LinkFlags;
}
}
+ if(replaceValues.Manifests)
+ {
+ if(variable == "MANIFESTS")
+ {
+ return replaceValues.Manifests;
+ }
+ }
if(replaceValues.Flags)
{
if(variable == "FLAGS")
@@ -850,6 +640,13 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
return replaceValues.ObjectDir;
}
}
+ if(replaceValues.ObjectFileDir)
+ {
+ if(variable == "OBJECT_FILE_DIR")
+ {
+ return replaceValues.ObjectFileDir;
+ }
+ }
if(replaceValues.Objects)
{
if(variable == "OBJECTS")
@@ -868,6 +665,10 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
{
return replaceValues.Defines;
}
+ if(replaceValues.Includes && variable == "INCLUDES")
+ {
+ return replaceValues.Includes;
+ }
if(replaceValues.TargetPDB )
{
if(variable == "TARGET_PDB")
@@ -875,6 +676,13 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
return replaceValues.TargetPDB;
}
}
+ if(replaceValues.TargetCompilePDB)
+ {
+ if(variable == "TARGET_COMPILE_PDB")
+ {
+ return replaceValues.TargetCompilePDB;
+ }
+ }
if(replaceValues.DependencyFile )
{
if(variable == "DEP_FILE")
@@ -888,7 +696,7 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
if(variable == "TARGET_QUOTED")
{
std::string targetQuoted = replaceValues.Target;
- if(targetQuoted.size() && targetQuoted[0] != '\"')
+ if(!targetQuoted.empty() && targetQuoted[0] != '\"')
{
targetQuoted = '\"';
targetQuoted += replaceValues.Target;
@@ -1008,7 +816,7 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
}
if(variable == "TARGET_TYPE")
{
- return cmTarget::GetTargetTypeName(replaceValues.CMTarget->GetType());
+ return cmState::GetTargetTypeName(replaceValues.CMTarget->GetType());
}
}
if(replaceValues.Output)
@@ -1020,12 +828,10 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
}
if(variable == "CMAKE_COMMAND")
{
- const char* cmcommand =
- this->GetMakefile()->GetDefinition("CMAKE_COMMAND");
- return this->Convert(cmcommand, FULL, SHELL);
+ return this->Convert(cmSystemTools::GetCMakeCommand(), FULL, SHELL);
}
- std::vector<std::string> enabledLanguages;
- this->GlobalGenerator->GetEnabledLanguages(enabledLanguages);
+ std::vector<std::string> enabledLanguages =
+ this->GetState()->GetEnabledLanguages();
// loop over language specific replace variables
int pos = 0;
while(ruleReplaceVars[pos])
@@ -1038,11 +844,38 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
// If this is the compiler then look for the extra variable
// _COMPILER_ARG1 which must be the first argument to the compiler
const char* compilerArg1 = 0;
+ const char* compilerTarget = 0;
+ const char* compilerOptionTarget = 0;
+ const char* compilerExternalToolchain = 0;
+ const char* compilerOptionExternalToolchain = 0;
+ const char* compilerSysroot = 0;
+ const char* compilerOptionSysroot = 0;
if(actualReplace == "CMAKE_${LANG}_COMPILER")
{
std::string arg1 = actualReplace + "_ARG1";
cmSystemTools::ReplaceString(arg1, "${LANG}", lang);
- compilerArg1 = this->Makefile->GetDefinition(arg1.c_str());
+ compilerArg1 = this->Makefile->GetDefinition(arg1);
+ compilerTarget
+ = this->Makefile->GetDefinition(
+ std::string("CMAKE_") + lang + "_COMPILER_TARGET");
+ compilerOptionTarget
+ = this->Makefile->GetDefinition(
+ std::string("CMAKE_") + lang +
+ "_COMPILE_OPTIONS_TARGET");
+ compilerExternalToolchain
+ = this->Makefile->GetDefinition(
+ std::string("CMAKE_") + lang +
+ "_COMPILER_EXTERNAL_TOOLCHAIN");
+ compilerOptionExternalToolchain
+ = this->Makefile->GetDefinition(
+ std::string("CMAKE_") + lang +
+ "_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN");
+ compilerSysroot
+ = this->Makefile->GetDefinition("CMAKE_SYSROOT");
+ compilerOptionSysroot
+ = this->Makefile->GetDefinition(
+ std::string("CMAKE_") + lang +
+ "_COMPILE_OPTIONS_SYSROOT");
}
if(actualReplace.find("${LANG}") != actualReplace.npos)
{
@@ -1051,11 +884,11 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
if(actualReplace == variable)
{
std::string replace =
- this->Makefile->GetSafeDefinition(variable.c_str());
+ this->Makefile->GetSafeDefinition(variable);
// if the variable is not a FLAG then treat it like a path
if(variable.find("_FLAG") == variable.npos)
{
- std::string ret = this->ConvertToOutputForExisting(replace.c_str());
+ std::string ret = this->ConvertToOutputForExisting(replace);
// if there is a required first argument to the compiler add it
// to the compiler string
if(compilerArg1)
@@ -1063,6 +896,24 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
ret += " ";
ret += compilerArg1;
}
+ if (compilerTarget && compilerOptionTarget)
+ {
+ ret += " ";
+ ret += compilerOptionTarget;
+ ret += compilerTarget;
+ }
+ if (compilerExternalToolchain && compilerOptionExternalToolchain)
+ {
+ ret += " ";
+ ret += compilerOptionExternalToolchain;
+ ret += this->EscapeForShell(compilerExternalToolchain, true);
+ }
+ if (compilerSysroot && compilerOptionSysroot)
+ {
+ ret += " ";
+ ret += compilerOptionSysroot;
+ ret += this->EscapeForShell(compilerSysroot, true);
+ }
return ret;
}
return replace;
@@ -1078,8 +929,11 @@ void
cmLocalGenerator::ExpandRuleVariables(std::string& s,
const RuleVariables& replaceValues)
{
- this->InsertRuleLauncher(s, replaceValues.CMTarget,
- replaceValues.RuleLauncher);
+ if(replaceValues.RuleLauncher)
+ {
+ this->InsertRuleLauncher(s, replaceValues.CMTarget,
+ replaceValues.RuleLauncher);
+ }
std::string::size_type start = s.find('<');
// no variables to expand
if(start == s.npos)
@@ -1122,8 +976,8 @@ cmLocalGenerator::ExpandRuleVariables(std::string& s,
}
//----------------------------------------------------------------------------
-const char* cmLocalGenerator::GetRuleLauncher(cmTarget* target,
- const char* prop)
+const char* cmLocalGenerator::GetRuleLauncher(cmGeneratorTarget* target,
+ const std::string& prop)
{
if(target)
{
@@ -1136,12 +990,13 @@ const char* cmLocalGenerator::GetRuleLauncher(cmTarget* target,
}
//----------------------------------------------------------------------------
-void cmLocalGenerator::InsertRuleLauncher(std::string& s, cmTarget* target,
- const char* prop)
+void cmLocalGenerator::InsertRuleLauncher(std::string& s,
+ cmGeneratorTarget* target,
+ const std::string& prop)
{
if(const char* val = this->GetRuleLauncher(target, prop))
{
- cmOStringStream wrapped;
+ std::ostringstream wrapped;
wrapped << val << " " << s;
s = wrapped.str();
}
@@ -1149,79 +1004,38 @@ void cmLocalGenerator::InsertRuleLauncher(std::string& s, cmTarget* target,
//----------------------------------------------------------------------------
std::string
-cmLocalGenerator::ConvertToOutputForExistingCommon(const char* remote,
- std::string const& result)
+cmLocalGenerator::ConvertToIncludeReference(std::string const& path,
+ OutputFormat format,
+ bool forceFullPaths)
{
- // If this is a windows shell, the result has a space, and the path
- // already exists, we can use a short-path to reference it without a
- // space.
- if(this->WindowsShell && result.find(' ') != result.npos &&
- cmSystemTools::FileExists(remote))
- {
- std::string tmp;
- if(cmSystemTools::GetShortPath(remote, tmp))
- {
- return this->Convert(tmp.c_str(), NONE, SHELL, true);
- }
- }
-
- // Otherwise, leave it unchanged.
- return result;
-}
-
-//----------------------------------------------------------------------------
-std::string
-cmLocalGenerator::ConvertToOutputForExisting(const char* remote,
- RelativeRoot local)
-{
- // Perform standard conversion.
- std::string result = this->Convert(remote, local, SHELL, true);
-
- // Consider short-path.
- return this->ConvertToOutputForExistingCommon(remote, result);
-}
-
-//----------------------------------------------------------------------------
-std::string
-cmLocalGenerator::ConvertToOutputForExisting(RelativeRoot remote,
- const char* local)
-{
- // Perform standard conversion.
- std::string result = this->Convert(remote, local, SHELL, true);
-
- // Consider short-path.
- const char* remotePath = this->GetRelativeRootPath(remote);
- return this->ConvertToOutputForExistingCommon(remotePath, result);
-}
-
-//----------------------------------------------------------------------------
-std::string
-cmLocalGenerator::ConvertToIncludeReference(std::string const& path)
-{
- return this->ConvertToOutputForExisting(path.c_str());
+ return this->ConvertToOutputForExisting(
+ path, forceFullPaths? FULL : START_OUTPUT, format);
}
//----------------------------------------------------------------------------
std::string cmLocalGenerator::GetIncludeFlags(
const std::vector<std::string> &includes,
cmGeneratorTarget* target,
- const char* lang, bool forResponseFile,
- const char *config)
+ const std::string& lang,
+ bool forceFullPaths,
+ bool forResponseFile,
+ const std::string& config)
{
- if(!lang)
+ if(lang.empty())
{
return "";
}
- cmOStringStream includeFlags;
+ OutputFormat shellFormat = forResponseFile? RESPONSE : SHELL;
+ std::ostringstream includeFlags;
std::string flagVar = "CMAKE_INCLUDE_FLAG_";
flagVar += lang;
const char* includeFlag =
- this->Makefile->GetSafeDefinition(flagVar.c_str());
+ this->Makefile->GetSafeDefinition(flagVar);
flagVar = "CMAKE_INCLUDE_FLAG_SEP_";
flagVar += lang;
- const char* sep = this->Makefile->GetDefinition(flagVar.c_str());
+ const char* sep = this->Makefile->GetDefinition(flagVar);
bool quotePaths = false;
if(this->Makefile->GetDefinition("CMAKE_QUOTE_INCLUDE_PATHS"))
{
@@ -1247,29 +1061,47 @@ std::string cmLocalGenerator::GetIncludeFlags(
const char* sysIncludeFlag = 0;
if(repeatFlag)
{
- sysIncludeFlag = this->Makefile->GetDefinition(sysFlagVar.c_str());
+ sysIncludeFlag = this->Makefile->GetDefinition(sysFlagVar);
}
+ std::string fwSearchFlagVar = "CMAKE_";
+ fwSearchFlagVar += lang;
+ fwSearchFlagVar += "_FRAMEWORK_SEARCH_FLAG";
+ const char* fwSearchFlag =
+ this->Makefile->GetDefinition(fwSearchFlagVar);
+
+ std::string sysFwSearchFlagVar = "CMAKE_";
+ sysFwSearchFlagVar += lang;
+ sysFwSearchFlagVar += "_SYSTEM_FRAMEWORK_SEARCH_FLAG";
+ const char* sysFwSearchFlag =
+ this->Makefile->GetDefinition(sysFwSearchFlagVar);
+
bool flagUsed = false;
- std::set<cmStdString> emitted;
+ std::set<std::string> emitted;
#ifdef __APPLE__
emitted.insert("/System/Library/Frameworks");
#endif
std::vector<std::string>::const_iterator i;
for(i = includes.begin(); i != includes.end(); ++i)
{
- if(this->Makefile->IsOn("APPLE")
+ if(fwSearchFlag && *fwSearchFlag && this->Makefile->IsOn("APPLE")
&& cmSystemTools::IsPathToFramework(i->c_str()))
{
std::string frameworkDir = *i;
frameworkDir += "/../";
- frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir.c_str());
+ frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir);
if(emitted.insert(frameworkDir).second)
{
- OutputFormat format = forResponseFile? RESPONSE : SHELL;
- includeFlags
- << "-F" << this->Convert(frameworkDir.c_str(),
- START_OUTPUT, format, true)
+ if (sysFwSearchFlag && target &&
+ target->IsSystemIncludeDirectory(*i, config))
+ {
+ includeFlags << sysFwSearchFlag;
+ }
+ else
+ {
+ includeFlags << fwSearchFlag;
+ }
+ includeFlags << this->ConvertToOutputFormat(frameworkDir, shellFormat)
<< " ";
}
continue;
@@ -1278,7 +1110,7 @@ std::string cmLocalGenerator::GetIncludeFlags(
if(!flagUsed || repeatFlag)
{
if(sysIncludeFlag && target &&
- target->IsSystemIncludeDirectory(i->c_str(), config))
+ target->IsSystemIncludeDirectory(*i, config))
{
includeFlags << sysIncludeFlag;
}
@@ -1288,22 +1120,14 @@ std::string cmLocalGenerator::GetIncludeFlags(
}
flagUsed = true;
}
- std::string includePath;
- if(forResponseFile)
- {
- includePath = this->Convert(i->c_str(), START_OUTPUT,
- RESPONSE, true);
- }
- else
- {
- includePath = this->ConvertToIncludeReference(*i);
- }
- if(quotePaths && includePath.size() && includePath[0] != '\"')
+ std::string includePath =
+ this->ConvertToIncludeReference(*i, shellFormat, forceFullPaths);
+ if(quotePaths && !includePath.empty() && includePath[0] != '\"')
{
includeFlags << "\"";
}
includeFlags << includePath;
- if(quotePaths && includePath.size() && includePath[0] != '\"')
+ if(quotePaths && !includePath.empty() && includePath[0] != '\"')
{
includeFlags << "\"";
}
@@ -1311,7 +1135,7 @@ std::string cmLocalGenerator::GetIncludeFlags(
}
std::string flags = includeFlags.str();
// remove trailing separators
- if((sep[0] != ' ') && flags.size()>0 && flags[flags.size()-1] == sep[0])
+ if((sep[0] != ' ') && !flags.empty() && flags[flags.size()-1] == sep[0])
{
flags[flags.size()-1] = ' ';
}
@@ -1320,24 +1144,25 @@ std::string cmLocalGenerator::GetIncludeFlags(
//----------------------------------------------------------------------------
void cmLocalGenerator::AddCompileDefinitions(std::set<std::string>& defines,
- cmTarget* target,
- const char* config)
+ cmGeneratorTarget const* target,
+ const std::string& config,
+ const std::string& lang)
{
std::vector<std::string> targetDefines;
- target->GetCompileDefinitions(targetDefines,
- config);
+ target->GetCompileDefinitions(targetDefines, config, lang);
this->AppendDefines(defines, targetDefines);
}
//----------------------------------------------------------------------------
void cmLocalGenerator::AddCompileOptions(
- std::string& flags, cmTarget* target,
- const char* lang, const char* config
+ std::string& flags, cmGeneratorTarget* target,
+ const std::string& lang, const std::string& config
)
{
std::string langFlagRegexVar = std::string("CMAKE_")+lang+"_FLAG_REGEX";
+
if(const char* langFlagRegexStr =
- this->Makefile->GetDefinition(langFlagRegexVar.c_str()))
+ this->Makefile->GetDefinition(langFlagRegexVar))
{
// Filter flags acceptable to this language.
cmsys::RegularExpression r(langFlagRegexStr);
@@ -1346,7 +1171,7 @@ void cmLocalGenerator::AddCompileOptions(
{
cmSystemTools::ParseWindowsCommandLine(targetFlags, opts);
}
- target->GetCompileOptions(opts, config);
+ target->GetCompileOptions(opts, config, lang);
for(std::vector<std::string>::const_iterator i = opts.begin();
i != opts.end(); ++i)
{
@@ -1354,7 +1179,7 @@ void cmLocalGenerator::AddCompileOptions(
{
// (Re-)Escape this flag. COMPILE_FLAGS were already parsed
// as a command line above, and COMPILE_OPTIONS are escaped.
- this->AppendFlagEscape(flags, i->c_str());
+ this->AppendFlagEscape(flags, *i);
}
}
}
@@ -1367,23 +1192,59 @@ void cmLocalGenerator::AddCompileOptions(
this->AppendFlags(flags, targetFlags);
}
std::vector<std::string> opts;
- target->GetCompileOptions(opts, config);
+ target->GetCompileOptions(opts, config, lang);
for(std::vector<std::string>::const_iterator i = opts.begin();
i != opts.end(); ++i)
{
// COMPILE_OPTIONS are escaped.
- this->AppendFlagEscape(flags, i->c_str());
+ this->AppendFlagEscape(flags, *i);
+ }
+ }
+ std::vector<std::string> features;
+ target->GetCompileFeatures(features, config);
+ for(std::vector<std::string>::const_iterator it = features.begin();
+ it != features.end(); ++it)
+ {
+ if (!this->Makefile->AddRequiredTargetFeature(target->Target, *it))
+ {
+ return;
+ }
+ }
+
+ for(std::map<std::string, std::string>::const_iterator it
+ = target->GetMaxLanguageStandards().begin();
+ it != target->GetMaxLanguageStandards().end(); ++it)
+ {
+ const char* standard = target->GetProperty(it->first + "_STANDARD");
+ if(!standard)
+ {
+ continue;
+ }
+ if (this->Makefile->IsLaterStandard(it->first, standard, it->second))
+ {
+ std::ostringstream e;
+ e << "The COMPILE_FEATURES property of target \""
+ << target->GetName() << "\" was evaluated when computing the link "
+ "implementation, and the \"" << it->first << "_STANDARD\" was \""
+ << it->second << "\" for that computation. Computing the "
+ "COMPILE_FEATURES based on the link implementation resulted in a "
+ "higher \"" << it->first << "_STANDARD\" \"" << standard << "\". "
+ "This is not permitted. The COMPILE_FEATURES may not both depend on "
+ "and be depended on by the link implementation." << std::endl;
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return;
}
}
+ this->AddCompilerRequirementFlag(flags, target, lang);
}
//----------------------------------------------------------------------------
void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs,
- cmGeneratorTarget* target,
- const char* lang,
- const char *config,
+ cmGeneratorTarget const* target,
+ const std::string& lang,
+ const std::string& config,
bool stripImplicitInclDirs
- )
+ ) const
{
// Need to decide whether to automatically include the source and
// binary directories at the beginning of the include path.
@@ -1403,53 +1264,26 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs,
includeBinaryDir = true;
}
- // CMake versions below 2.0 would add the source tree to the -I path
- // automatically. Preserve compatibility.
- if(this->NeedBackwardsCompatibility(1,9))
- {
- includeSourceDir = true;
- }
-
- // Hack for VTK 4.0 - 4.4 which depend on the old behavior but do
- // not set the backwards compatibility level automatically.
- const char* vtkSourceDir =
- this->Makefile->GetDefinition("VTK_SOURCE_DIR");
- if(vtkSourceDir)
- {
- const char* vtk_major =
- this->Makefile->GetDefinition("VTK_MAJOR_VERSION");
- const char* vtk_minor =
- this->Makefile->GetDefinition("VTK_MINOR_VERSION");
- vtk_major = vtk_major? vtk_major : "4";
- vtk_minor = vtk_minor? vtk_minor : "4";
- int vmajor = 0;
- int vminor = 0;
- if(sscanf(vtk_major, "%d", &vmajor) &&
- sscanf(vtk_minor, "%d", &vminor) && vmajor == 4 && vminor <= 4)
- {
- includeSourceDir = true;
- }
- }
-
// Do not repeat an include path.
- std::set<cmStdString> emitted;
+ std::set<std::string> emitted;
// Store the automatic include paths.
if(includeBinaryDir)
{
- if(emitted.find(
- this->Makefile->GetStartOutputDirectory()) == emitted.end())
+ std::string binDir = this->StateSnapshot.GetDirectory().GetCurrentBinary();
+ if(emitted.find(binDir) == emitted.end())
{
- dirs.push_back(this->Makefile->GetStartOutputDirectory());
- emitted.insert(this->Makefile->GetStartOutputDirectory());
+ dirs.push_back(binDir);
+ emitted.insert(binDir);
}
}
if(includeSourceDir)
{
- if(emitted.find(this->Makefile->GetStartDirectory()) == emitted.end())
+ std::string srcDir = this->StateSnapshot.GetDirectory().GetCurrentSource();
+ if(emitted.find(srcDir) == emitted.end())
{
- dirs.push_back(this->Makefile->GetStartDirectory());
- emitted.insert(this->Makefile->GetStartDirectory());
+ dirs.push_back(srcDir);
+ emitted.insert(srcDir);
}
}
@@ -1458,19 +1292,23 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs,
return;
}
+ std::string rootPath = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT");
+
std::vector<std::string> implicitDirs;
// Load implicit include directories for this language.
std::string impDirVar = "CMAKE_";
impDirVar += lang;
impDirVar += "_IMPLICIT_INCLUDE_DIRECTORIES";
- if(const char* value = this->Makefile->GetDefinition(impDirVar.c_str()))
+ if(const char* value = this->Makefile->GetDefinition(impDirVar))
{
std::vector<std::string> impDirVec;
cmSystemTools::ExpandListArgument(value, impDirVec);
for(std::vector<std::string>::const_iterator i = impDirVec.begin();
i != impDirVec.end(); ++i)
{
- emitted.insert(*i);
+ std::string d = rootPath + *i;
+ cmSystemTools::ConvertToUnixSlashes(d);
+ emitted.insert(d);
if (!stripImplicitInclDirs)
{
implicitDirs.push_back(*i);
@@ -1481,23 +1319,23 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs,
// Get the target-specific include directories.
std::vector<std::string> includes;
- includes = target->GetIncludeDirectories(config);
+ includes = target->GetIncludeDirectories(config, lang);
// Support putting all the in-project include directories first if
// it is requested by the project.
if(this->Makefile->IsOn("CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE"))
{
- const char* topSourceDir = this->Makefile->GetHomeDirectory();
- const char* topBinaryDir = this->Makefile->GetHomeOutputDirectory();
+ const char* topSourceDir = this->GetState()->GetSourceDirectory();
+ const char* topBinaryDir = this->GetState()->GetBinaryDirectory();
for(std::vector<std::string>::const_iterator i = includes.begin();
i != includes.end(); ++i)
{
// Emit this directory only if it is a subdirectory of the
// top-level source or binary tree.
- if(cmSystemTools::ComparePath(i->c_str(), topSourceDir) ||
- cmSystemTools::ComparePath(i->c_str(), topBinaryDir) ||
- cmSystemTools::IsSubDirectory(i->c_str(), topSourceDir) ||
- cmSystemTools::IsSubDirectory(i->c_str(), topBinaryDir))
+ if(cmSystemTools::ComparePath(*i, topSourceDir) ||
+ cmSystemTools::ComparePath(*i, topBinaryDir) ||
+ cmSystemTools::IsSubDirectory(*i, topSourceDir) ||
+ cmSystemTools::IsSubDirectory(*i, topBinaryDir))
{
if(emitted.insert(*i).second)
{
@@ -1529,20 +1367,20 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs,
void cmLocalGenerator::GetStaticLibraryFlags(std::string& flags,
std::string const& config,
- cmTarget* target)
+ cmGeneratorTarget* target)
{
this->AppendFlags(flags,
this->Makefile->GetSafeDefinition("CMAKE_STATIC_LINKER_FLAGS"));
if(!config.empty())
{
std::string name = "CMAKE_STATIC_LINKER_FLAGS_" + config;
- this->AppendFlags(flags, this->Makefile->GetSafeDefinition(name.c_str()));
+ this->AppendFlags(flags, this->Makefile->GetSafeDefinition(name));
}
this->AppendFlags(flags, target->GetProperty("STATIC_LIBRARY_FLAGS"));
if(!config.empty())
{
std::string name = "STATIC_LIBRARY_FLAGS_" + config;
- this->AppendFlags(flags, target->GetProperty(name.c_str()));
+ this->AppendFlags(flags, target->GetProperty(name));
}
}
@@ -1551,7 +1389,8 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs,
std::string& linkFlags,
std::string& frameworkPath,
std::string& linkPath,
- cmGeneratorTarget* target)
+ cmGeneratorTarget* target,
+ bool useWatcomQuote)
{
std::string buildType =
this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
@@ -1561,12 +1400,12 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs,
switch(target->GetType())
{
- case cmTarget::STATIC_LIBRARY:
- this->GetStaticLibraryFlags(linkFlags, buildType, target->Target);
+ case cmState::STATIC_LIBRARY:
+ this->GetStaticLibraryFlags(linkFlags, buildType, target);
break;
- case cmTarget::MODULE_LIBRARY:
+ case cmState::MODULE_LIBRARY:
libraryLinkVariable = "CMAKE_MODULE_LINKER_FLAGS";
- case cmTarget::SHARED_LIBRARY:
+ case cmState::SHARED_LIBRARY:
{
linkFlags = this->Makefile->GetSafeDefinition(libraryLinkVariable);
linkFlags += " ";
@@ -1575,13 +1414,14 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs,
std::string build = libraryLinkVariable;
build += "_";
build += buildType;
- linkFlags += this->Makefile->GetSafeDefinition(build.c_str());
+ linkFlags += this->Makefile->GetSafeDefinition(build);
linkFlags += " ";
}
if(this->Makefile->IsOn("WIN32") &&
!(this->Makefile->IsOn("CYGWIN") || this->Makefile->IsOn("MINGW")))
{
- const std::vector<cmSourceFile*>& sources = target->GetSourceFiles();
+ std::vector<cmSourceFile*> sources;
+ target->GetSourceFiles(sources, buildType);
for(std::vector<cmSourceFile*>::const_iterator i = sources.begin();
i != sources.end(); ++i)
{
@@ -1590,7 +1430,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs,
{
linkFlags +=
this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
- linkFlags += this->Convert(sf->GetFullPath().c_str(),
+ linkFlags += this->Convert(sf->GetFullPath(),
FULL, SHELL);
linkFlags += " ";
}
@@ -1606,7 +1446,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs,
{
std::string configLinkFlags = "LINK_FLAGS_";
configLinkFlags += buildType;
- targetLinkFlags = target->GetProperty(configLinkFlags.c_str());
+ targetLinkFlags = target->GetProperty(configLinkFlags);
if(targetLinkFlags)
{
linkFlags += targetLinkFlags;
@@ -1614,10 +1454,10 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs,
}
}
this->OutputLinkLibraries(linkLibs, frameworkPath, linkPath,
- *target, false);
+ *target, false, false, useWatcomQuote);
}
break;
- case cmTarget::EXECUTABLE:
+ case cmState::EXECUTABLE:
{
linkFlags +=
this->Makefile->GetSafeDefinition("CMAKE_EXE_LINKER_FLAGS");
@@ -1626,26 +1466,26 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs,
{
std::string build = "CMAKE_EXE_LINKER_FLAGS_";
build += buildType;
- linkFlags += this->Makefile->GetSafeDefinition(build.c_str());
+ linkFlags += this->Makefile->GetSafeDefinition(build);
linkFlags += " ";
}
- const char* linkLanguage = target->Target->GetLinkerLanguage();
- if(!linkLanguage)
+ std::string linkLanguage = target->GetLinkerLanguage(buildType);
+ if(linkLanguage.empty())
{
cmSystemTools::Error
("CMake can not determine linker language for target: ",
- target->Target->GetName());
+ target->GetName().c_str());
return;
}
- this->AddLanguageFlags(flags, linkLanguage, buildType.c_str());
+ this->AddLanguageFlags(flags, linkLanguage, buildType);
this->OutputLinkLibraries(linkLibs, frameworkPath, linkPath,
- *target, false);
+ *target, false, false, useWatcomQuote);
if(cmSystemTools::IsOn
(this->Makefile->GetDefinition("BUILD_SHARED_LIBS")))
{
std::string sFlagVar = std::string("CMAKE_SHARED_BUILD_")
+ linkLanguage + std::string("_FLAGS");
- linkFlags += this->Makefile->GetSafeDefinition(sFlagVar.c_str());
+ linkFlags += this->Makefile->GetSafeDefinition(sFlagVar);
linkFlags += " ";
}
if ( target->GetPropertyAsBool("WIN32_EXECUTABLE") )
@@ -1660,14 +1500,14 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs,
this->Makefile->GetSafeDefinition("CMAKE_CREATE_CONSOLE_EXE");
linkFlags += " ";
}
- if (target->Target->IsExecutableWithExports())
+ if (target->IsExecutableWithExports())
{
std::string exportFlagVar = "CMAKE_EXE_EXPORTS_";
exportFlagVar += linkLanguage;
exportFlagVar += "_FLAG";
linkFlags +=
- this->Makefile->GetSafeDefinition(exportFlagVar.c_str());
+ this->Makefile->GetSafeDefinition(exportFlagVar);
linkFlags += " ";
}
const char* targetLinkFlags = target->GetProperty("LINK_FLAGS");
@@ -1680,7 +1520,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs,
{
std::string configLinkFlags = "LINK_FLAGS_";
configLinkFlags += buildType;
- targetLinkFlags = target->GetProperty(configLinkFlags.c_str());
+ targetLinkFlags = target->GetProperty(configLinkFlags);
if(targetLinkFlags)
{
linkFlags += targetLinkFlags;
@@ -1694,12 +1534,12 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs,
}
}
-std::string cmLocalGenerator::ConvertToLinkReference(std::string const& lib)
+std::string cmLocalGenerator::ConvertToLinkReference(std::string const& lib,
+ OutputFormat format)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
- // Work-ardound command line parsing limitations in MSVC 6.0 and
- // Watcom.
- if(this->Makefile->IsOn("MSVC60") || this->Makefile->IsOn("WATCOM"))
+ // Work-ardound command line parsing limitations in MSVC 6.0
+ if(this->Makefile->IsOn("MSVC60"))
{
// Search for the last space.
std::string::size_type pos = lib.rfind(' ');
@@ -1716,14 +1556,14 @@ std::string cmLocalGenerator::ConvertToLinkReference(std::string const& lib)
sp += lib.substr(pos);
// Convert to an output path.
- return this->Convert(sp.c_str(), NONE, SHELL);
+ return this->Convert(sp.c_str(), NONE, format);
}
}
}
#endif
// Normal behavior.
- return this->Convert(lib.c_str(), START_OUTPUT, SHELL);
+ return this->Convert(lib, START_OUTPUT, format);
}
/**
@@ -1735,11 +1575,16 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries,
std::string& frameworkPath,
std::string& linkPath,
cmGeneratorTarget &tgt,
- bool relink)
-{
- cmOStringStream fout;
- const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE");
- cmComputeLinkInformation* pcli = tgt.Target->GetLinkInformation(config);
+ bool relink,
+ bool forResponseFile,
+ bool useWatcomQuote)
+{
+ OutputFormat shellFormat = (forResponseFile) ? RESPONSE :
+ ((useWatcomQuote) ? WATCOMQUOTE : SHELL);
+ bool escapeAllowMakeVars = !forResponseFile;
+ std::ostringstream fout;
+ std::string config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ cmComputeLinkInformation* pcli = tgt.GetLinkInformation(config);
if(!pcli)
{
return;
@@ -1749,7 +1594,7 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries,
// Collect library linking flags command line options.
std::string linkLibs;
- const char* linkLanguage = cli.GetLinkLanguage();
+ std::string linkLanguage = cli.GetLinkLanguage();
std::string libPathFlag =
this->Makefile->GetRequiredDefinition("CMAKE_LIBRARY_PATH_FLAG");
@@ -1757,23 +1602,67 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries,
this->Makefile->GetSafeDefinition("CMAKE_LIBRARY_PATH_TERMINATOR");
// Flags to link an executable to shared libraries.
- std::string linkFlagsVar = "CMAKE_SHARED_LIBRARY_LINK_";
- linkFlagsVar += linkLanguage;
- linkFlagsVar += "_FLAGS";
- if( tgt.GetType() == cmTarget::EXECUTABLE )
+ if (tgt.GetType() == cmState::EXECUTABLE &&
+ this->StateSnapshot.GetState()->
+ GetGlobalPropertyAsBool("TARGET_SUPPORTS_SHARED_LIBS"))
{
- linkLibs = this->Makefile->GetSafeDefinition(linkFlagsVar.c_str());
- linkLibs += " ";
+ bool add_shlib_flags = false;
+ switch(tgt.GetPolicyStatusCMP0065())
+ {
+ case cmPolicies::WARN:
+ if(!tgt.GetPropertyAsBool("ENABLE_EXPORTS") &&
+ this->Makefile->PolicyOptionalWarningEnabled(
+ "CMAKE_POLICY_WARNING_CMP0065"))
+ {
+ std::ostringstream w;
+ w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0065) << "\n"
+ "For compatibility with older versions of CMake, "
+ "additional flags may be added to export symbols on all "
+ "executables regardless of thier ENABLE_EXPORTS property.";
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ }
+ case cmPolicies::OLD:
+ // OLD behavior is to always add the flags
+ add_shlib_flags = true;
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0065)
+ );
+ case cmPolicies::NEW:
+ // NEW behavior is to only add the flags if ENABLE_EXPORTS is on
+ add_shlib_flags = tgt.GetPropertyAsBool("ENABLE_EXPORTS");
+ break;
+ }
+
+ if(add_shlib_flags)
+ {
+ std::string linkFlagsVar = "CMAKE_SHARED_LIBRARY_LINK_";
+ linkFlagsVar += linkLanguage;
+ linkFlagsVar += "_FLAGS";
+ linkLibs = this->Makefile->GetSafeDefinition(linkFlagsVar);
+ linkLibs += " ";
+ }
}
// Append the framework search path flags.
- std::vector<std::string> const& fwDirs = cli.GetFrameworkPaths();
- for(std::vector<std::string>::const_iterator fdi = fwDirs.begin();
- fdi != fwDirs.end(); ++fdi)
+ std::string fwSearchFlagVar = "CMAKE_";
+ fwSearchFlagVar += linkLanguage;
+ fwSearchFlagVar += "_FRAMEWORK_SEARCH_FLAG";
+ const char* fwSearchFlag =
+ this->Makefile->GetDefinition(fwSearchFlagVar);
+ if(fwSearchFlag && *fwSearchFlag)
{
- frameworkPath += "-F";
- frameworkPath += this->Convert(fdi->c_str(), NONE, SHELL, false);
- frameworkPath += " ";
+ std::vector<std::string> const& fwDirs = cli.GetFrameworkPaths();
+ for(std::vector<std::string>::const_iterator fdi = fwDirs.begin();
+ fdi != fwDirs.end(); ++fdi)
+ {
+ frameworkPath += fwSearchFlag;
+ frameworkPath += this->Convert(*fdi, NONE, shellFormat);
+ frameworkPath += " ";
+ }
}
// Append the library search path flags.
@@ -1781,7 +1670,9 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries,
for(std::vector<std::string>::const_iterator libDir = libDirs.begin();
libDir != libDirs.end(); ++libDir)
{
- std::string libpath = this->ConvertToOutputForExisting(libDir->c_str());
+ std::string libpath = this->ConvertToOutputForExisting(*libDir,
+ START_OUTPUT,
+ shellFormat);
linkPath += " " + libPathFlag;
linkPath += libpath;
linkPath += libPathTerminator;
@@ -1793,9 +1684,13 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries,
ItemVector const& items = cli.GetItems();
for(ItemVector::const_iterator li = items.begin(); li != items.end(); ++li)
{
+ if(li->Target && li->Target->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ continue;
+ }
if(li->IsPath)
{
- linkLibs += this->ConvertToLinkReference(li->Value);
+ linkLibs += this->ConvertToLinkReference(li->Value, shellFormat);
}
else
{
@@ -1807,20 +1702,19 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries,
// Write the library flags to the build rule.
fout << linkLibs;
- // Get the RPATH entries.
- std::vector<std::string> runtimeDirs;
- cli.GetRPath(runtimeDirs, relink);
-
// Check what kind of rpath flags to use.
if(cli.GetRuntimeSep().empty())
{
// Each rpath entry gets its own option ("-R a -R b -R c")
+ std::vector<std::string> runtimeDirs;
+ cli.GetRPath(runtimeDirs, relink);
+
std::string rpath;
for(std::vector<std::string>::iterator ri = runtimeDirs.begin();
ri != runtimeDirs.end(); ++ri)
{
rpath += cli.GetRuntimeFlag();
- rpath += this->Convert(ri->c_str(), NONE, SHELL, false);
+ rpath += this->Convert(*ri, NONE, shellFormat);
rpath += " ";
}
fout << rpath;
@@ -1834,7 +1728,7 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries,
if(!rpath.empty())
{
fout << cli.GetRuntimeFlag();
- fout << this->EscapeForShell(rpath.c_str(), true);
+ fout << this->EscapeForShell(rpath, escapeAllowMakeVars);
fout << " ";
}
}
@@ -1844,7 +1738,7 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries,
if(!cli.GetRPathLinkFlag().empty() && !rpath_link.empty())
{
fout << cli.GetRPathLinkFlag();
- fout << this->EscapeForShell(rpath_link.c_str(), true);
+ fout << this->EscapeForShell(rpath_link, escapeAllowMakeVars);
fout << " ";
}
@@ -1853,7 +1747,7 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries,
standardLibsVar += cli.GetLinkLanguage();
standardLibsVar += "_STANDARD_LIBRARIES";
if(const char* stdLibs =
- this->Makefile->GetDefinition(standardLibsVar.c_str()))
+ this->Makefile->GetDefinition(standardLibsVar))
{
fout << stdLibs << " ";
}
@@ -1864,9 +1758,9 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries,
//----------------------------------------------------------------------------
void cmLocalGenerator::AddArchitectureFlags(std::string& flags,
- cmGeneratorTarget* target,
- const char *lang,
- const char* config)
+ cmGeneratorTarget const* target,
+ const std::string& lang,
+ const std::string& config)
{
// Only add Mac OS X specific flags on Darwin platforms (OSX and iphone):
if(!this->Makefile->IsOn("APPLE"))
@@ -1884,14 +1778,14 @@ void cmLocalGenerator::AddArchitectureFlags(std::string& flags,
std::string sysrootFlagVar =
std::string("CMAKE_") + lang + "_SYSROOT_FLAG";
const char* sysrootFlag =
- this->Makefile->GetDefinition(sysrootFlagVar.c_str());
+ this->Makefile->GetDefinition(sysrootFlagVar);
const char* deploymentTarget =
this->Makefile->GetDefinition("CMAKE_OSX_DEPLOYMENT_TARGET");
std::string deploymentTargetFlagVar =
std::string("CMAKE_") + lang + "_OSX_DEPLOYMENT_TARGET_FLAG";
const char* deploymentTargetFlag =
- this->Makefile->GetDefinition(deploymentTargetFlagVar.c_str());
- if(!archs.empty() && lang && (lang[0] =='C' || lang[0] == 'F'))
+ this->Makefile->GetDefinition(deploymentTargetFlagVar);
+ if(!archs.empty() && !lang.empty() && (lang[0] =='C' || lang[0] == 'F'))
{
for(std::vector<std::string>::iterator i = archs.begin();
i != archs.end(); ++i)
@@ -1906,7 +1800,7 @@ void cmLocalGenerator::AddArchitectureFlags(std::string& flags,
flags += " ";
flags += sysrootFlag;
flags += " ";
- flags += sysroot;
+ flags += this->Convert(sysroot, NONE, SHELL);
}
if (deploymentTargetFlag && *deploymentTargetFlag &&
@@ -1922,19 +1816,40 @@ void cmLocalGenerator::AddArchitectureFlags(std::string& flags,
//----------------------------------------------------------------------------
void cmLocalGenerator::AddLanguageFlags(std::string& flags,
- const char* lang,
- const char* config)
+ const std::string& lang,
+ const std::string& config)
{
// Add language-specific flags.
std::string flagsVar = "CMAKE_";
flagsVar += lang;
flagsVar += "_FLAGS";
- this->AddConfigVariableFlags(flags, flagsVar.c_str(), config);
+ this->AddConfigVariableFlags(flags, flagsVar, config);
+}
+
+//----------------------------------------------------------------------------
+cmGeneratorTarget*
+cmLocalGenerator::FindGeneratorTargetToUse(const std::string& name) const
+{
+ std::vector<cmGeneratorTarget*>::const_iterator
+ imported = std::find_if(this->ImportedGeneratorTargets.begin(),
+ this->ImportedGeneratorTargets.end(),
+ NamedGeneratorTargetFinder(name));
+ if(imported != this->ImportedGeneratorTargets.end())
+ {
+ return *imported;
+ }
+
+ if(cmGeneratorTarget* t = this->FindGeneratorTarget(name))
+ {
+ return t;
+ }
+
+ return this->GetGlobalGenerator()->FindGeneratorTarget(name);
}
//----------------------------------------------------------------------------
-bool cmLocalGenerator::GetRealDependency(const char* inName,
- const char* config,
+bool cmLocalGenerator::GetRealDependency(const std::string& inName,
+ const std::string& config,
std::string& dep)
{
// Older CMake code may specify the dependency using the target
@@ -1957,23 +1872,24 @@ bool cmLocalGenerator::GetRealDependency(const char* inName,
}
// Look for a CMake target with the given name.
- if(cmTarget* target = this->Makefile->FindTargetToUse(name.c_str()))
+ if(cmGeneratorTarget* target =
+ this->FindGeneratorTargetToUse(name))
{
// make sure it is not just a coincidence that the target name
// found is part of the inName
- if(cmSystemTools::FileIsFullPath(inName))
+ if(cmSystemTools::FileIsFullPath(inName.c_str()))
{
std::string tLocation;
- if(target->GetType() >= cmTarget::EXECUTABLE &&
- target->GetType() <= cmTarget::MODULE_LIBRARY)
+ if(target->GetType() >= cmState::EXECUTABLE &&
+ target->GetType() <= cmState::MODULE_LIBRARY)
{
tLocation = target->GetLocation(config);
tLocation = cmSystemTools::GetFilenamePath(tLocation);
- tLocation = cmSystemTools::CollapseFullPath(tLocation.c_str());
+ tLocation = cmSystemTools::CollapseFullPath(tLocation);
}
std::string depLocation = cmSystemTools::GetFilenamePath(
std::string(inName));
- depLocation = cmSystemTools::CollapseFullPath(depLocation.c_str());
+ depLocation = cmSystemTools::CollapseFullPath(depLocation);
if(depLocation != tLocation)
{
// it is a full path to a depend that has the same name
@@ -1985,19 +1901,23 @@ bool cmLocalGenerator::GetRealDependency(const char* inName,
}
switch (target->GetType())
{
- case cmTarget::EXECUTABLE:
- case cmTarget::STATIC_LIBRARY:
- case cmTarget::SHARED_LIBRARY:
- case cmTarget::MODULE_LIBRARY:
- case cmTarget::UNKNOWN_LIBRARY:
+ case cmState::EXECUTABLE:
+ case cmState::STATIC_LIBRARY:
+ case cmState::SHARED_LIBRARY:
+ case cmState::MODULE_LIBRARY:
+ case cmState::UNKNOWN_LIBRARY:
dep = target->GetLocation(config);
return true;
- case cmTarget::OBJECT_LIBRARY:
+ case cmState::OBJECT_LIBRARY:
// An object library has no single file on which to depend.
// This was listed to get the target-level dependency.
return false;
- case cmTarget::UTILITY:
- case cmTarget::GLOBAL_TARGET:
+ case cmState::INTERFACE_LIBRARY:
+ // An interface library has no file on which to depend.
+ // This was listed to get the target-level dependency.
+ return false;
+ case cmState::UTILITY:
+ case cmState::GLOBAL_TARGET:
// A utility target has no file on which to depend. This was listed
// only to get the target-level dependency.
return false;
@@ -2005,7 +1925,7 @@ bool cmLocalGenerator::GetRealDependency(const char* inName,
}
// The name was not that of a CMake target. It must name a file.
- if(cmSystemTools::FileIsFullPath(inName))
+ if(cmSystemTools::FileIsFullPath(inName.c_str()))
{
// This is a full path. Return it as given.
dep = inName;
@@ -2022,7 +1942,7 @@ bool cmLocalGenerator::GetRealDependency(const char* inName,
// Treat the name as relative to the source directory in which it
// was given.
- dep = this->Makefile->GetCurrentDirectory();
+ dep = this->StateSnapshot.GetDirectory().GetCurrentSource();
dep += "/";
dep += inName;
return true;
@@ -2030,7 +1950,7 @@ bool cmLocalGenerator::GetRealDependency(const char* inName,
//----------------------------------------------------------------------------
void cmLocalGenerator::AddSharedFlags(std::string& flags,
- const char* lang,
+ const std::string& lang,
bool shared)
{
std::string flagsVar;
@@ -2041,49 +1961,185 @@ void cmLocalGenerator::AddSharedFlags(std::string& flags,
flagsVar = "CMAKE_SHARED_LIBRARY_";
flagsVar += lang;
flagsVar += "_FLAGS";
- this->AppendFlags(flags, this->Makefile->GetDefinition(flagsVar.c_str()));
+ this->AppendFlags(flags, this->Makefile->GetDefinition(flagsVar));
}
}
-static void AddVisibilityCompileOption(std::string &flags, cmTarget* target,
- cmLocalGenerator *lg, const char *lang)
+//----------------------------------------------------------------------------
+void cmLocalGenerator::
+AddCompilerRequirementFlag(std::string &flags,
+ cmGeneratorTarget const* target,
+ const std::string& lang)
+{
+ if (lang.empty())
+ {
+ return;
+ }
+ const char* defaultStd
+ = this->Makefile->GetDefinition("CMAKE_" + lang + "_STANDARD_DEFAULT");
+ if (!defaultStd || !*defaultStd)
+ {
+ // This compiler has no notion of language standard levels.
+ return;
+ }
+ std::string stdProp = lang + "_STANDARD";
+ const char *standardProp = target->GetProperty(stdProp);
+ if (!standardProp)
+ {
+ return;
+ }
+ std::string extProp = lang + "_EXTENSIONS";
+ std::string type = "EXTENSION";
+ bool ext = true;
+ if (const char* extPropValue = target->GetProperty(extProp))
+ {
+ if (cmSystemTools::IsOff(extPropValue))
+ {
+ ext = false;
+ type = "STANDARD";
+ }
+ }
+
+ if (target->GetPropertyAsBool(lang + "_STANDARD_REQUIRED"))
+ {
+ std::string option_flag =
+ "CMAKE_" + lang + standardProp
+ + "_" + type + "_COMPILE_OPTION";
+
+ const char *opt = target->Target->GetMakefile()
+ ->GetDefinition(option_flag);
+ if (!opt)
+ {
+ std::ostringstream e;
+ e << "Target \"" << target->GetName() << "\" requires the language "
+ "dialect \"" << lang << standardProp << "\" "
+ << (ext ? "(with compiler extensions)" : "") << ", but CMake "
+ "does not know the compile flags to use to enable it.";
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
+ }
+ else
+ {
+ this->AppendFlagEscape(flags, opt);
+ }
+ return;
+ }
+
+ static std::map<std::string, std::vector<std::string> > langStdMap;
+ if (langStdMap.empty())
+ {
+ // Maintain sorted order, most recent first.
+ langStdMap["CXX"].push_back("14");
+ langStdMap["CXX"].push_back("11");
+ langStdMap["CXX"].push_back("98");
+
+ langStdMap["C"].push_back("11");
+ langStdMap["C"].push_back("99");
+ langStdMap["C"].push_back("90");
+ }
+
+ std::string standard(standardProp);
+
+ std::vector<std::string>& stds = langStdMap[lang];
+
+ std::vector<std::string>::const_iterator stdIt =
+ std::find(stds.begin(), stds.end(), standard);
+ if (stdIt == stds.end())
+ {
+ std::string e =
+ lang + "_STANDARD is set to invalid value '" + standard + "'";
+ this->GetGlobalGenerator()->GetCMakeInstance()
+ ->IssueMessage(cmake::FATAL_ERROR, e, target->GetBacktrace());
+ return;
+ }
+
+ std::vector<std::string>::const_iterator defaultStdIt =
+ std::find(stds.begin(), stds.end(), defaultStd);
+ if (defaultStdIt == stds.end())
+ {
+ std::string e =
+ "CMAKE_" + lang + "_STANDARD_DEFAULT is set to invalid value '" +
+ std::string(defaultStd) + "'";
+ this->IssueMessage(cmake::INTERNAL_ERROR, e);
+ return;
+ }
+
+ // Greater or equal because the standards are stored in
+ // backward chronological order.
+ if (stdIt >= defaultStdIt)
+ {
+ std::string option_flag =
+ "CMAKE_" + lang + *stdIt
+ + "_" + type + "_COMPILE_OPTION";
+
+ const char *opt =
+ target->Target->GetMakefile()->GetRequiredDefinition(option_flag);
+ this->AppendFlagEscape(flags, opt);
+ return;
+ }
+
+ for ( ; stdIt < defaultStdIt; ++stdIt)
+ {
+ std::string option_flag =
+ "CMAKE_" + lang + *stdIt
+ + "_" + type + "_COMPILE_OPTION";
+
+ if (const char *opt = target->Target
+ ->GetMakefile()->GetDefinition(option_flag))
+ {
+ this->AppendFlagEscape(flags, opt);
+ return;
+ }
+ }
+}
+
+static void AddVisibilityCompileOption(std::string &flags,
+ cmGeneratorTarget const* target,
+ cmLocalGenerator *lg,
+ const std::string& lang,
+ std::string* warnCMP0063)
{
std::string l(lang);
std::string compileOption = "CMAKE_" + l + "_COMPILE_OPTIONS_VISIBILITY";
- const char *opt = lg->GetMakefile()->GetDefinition(compileOption.c_str());
+ const char *opt = lg->GetMakefile()->GetDefinition(compileOption);
if (!opt)
{
return;
}
std::string flagDefine = l + "_VISIBILITY_PRESET";
- const char *prop = target->GetProperty(flagDefine.c_str());
+ const char *prop = target->GetProperty(flagDefine);
if (!prop)
{
return;
}
+ if (warnCMP0063)
+ {
+ *warnCMP0063 += " " + flagDefine + "\n";
+ return;
+ }
if (strcmp(prop, "hidden") != 0
&& strcmp(prop, "default") != 0
&& strcmp(prop, "protected") != 0
&& strcmp(prop, "internal") != 0 )
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Target " << target->GetName() << " uses unsupported value \""
<< prop << "\" for " << flagDefine << ".";
cmSystemTools::Error(e.str().c_str());
return;
}
std::string option = std::string(opt) + prop;
- lg->AppendFlags(flags, option.c_str());
+ lg->AppendFlags(flags, option);
}
static void AddInlineVisibilityCompileOption(std::string &flags,
- cmTarget* target,
- cmLocalGenerator *lg)
+ cmGeneratorTarget const* target,
+ cmLocalGenerator *lg,
+ std::string* warnCMP0063)
{
std::string compileOption
= "CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN";
- const char *opt = lg->GetMakefile()->GetDefinition(compileOption.c_str());
+ const char *opt = lg->GetMakefile()->GetDefinition(compileOption);
if (!opt)
{
return;
@@ -2094,49 +2150,84 @@ static void AddInlineVisibilityCompileOption(std::string &flags,
{
return;
}
+ if (warnCMP0063)
+ {
+ *warnCMP0063 += " VISIBILITY_INLINES_HIDDEN\n";
+ return;
+ }
lg->AppendFlags(flags, opt);
}
//----------------------------------------------------------------------------
void cmLocalGenerator
-::AddVisibilityPresetFlags(std::string &flags, cmTarget* target,
- const char *lang)
+::AddVisibilityPresetFlags(std::string &flags, cmGeneratorTarget const* target,
+ const std::string& lang)
{
- int targetType = target->GetType();
- bool suitableTarget = ((targetType == cmTarget::SHARED_LIBRARY)
- || (targetType == cmTarget::MODULE_LIBRARY)
- || (target->IsExecutableWithExports()));
-
- if (!suitableTarget)
+ if (lang.empty())
{
return;
}
- if (!lang)
+ std::string warnCMP0063;
+ std::string *pWarnCMP0063 = 0;
+ if (target->GetType() != cmState::SHARED_LIBRARY &&
+ target->GetType() != cmState::MODULE_LIBRARY &&
+ !target->IsExecutableWithExports())
{
- return;
+ switch (target->GetPolicyStatusCMP0063())
+ {
+ case cmPolicies::OLD:
+ return;
+ case cmPolicies::WARN:
+ pWarnCMP0063 = &warnCMP0063;
+ break;
+ default:
+ break;
+ }
+ }
+
+ AddVisibilityCompileOption(flags, target, this, lang, pWarnCMP0063);
+
+ if(lang == "CXX")
+ {
+ AddInlineVisibilityCompileOption(flags, target, this, pWarnCMP0063);
+ }
+
+ if (!warnCMP0063.empty() &&
+ this->WarnCMP0063.insert(target).second)
+ {
+ std::ostringstream w;
+ w <<
+ cmPolicies::GetPolicyWarning(cmPolicies::CMP0063) << "\n"
+ "Target \"" << target->GetName() << "\" of "
+ "type \"" << cmState::GetTargetTypeName(target->GetType()) << "\" "
+ "has the following visibility properties set for " << lang << ":\n" <<
+ warnCMP0063 <<
+ "For compatibility CMake is not honoring them for this target.";
+ target->GetLocalGenerator()->GetCMakeInstance()
+ ->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
+ target->GetBacktrace());
}
- AddVisibilityCompileOption(flags, target, this, lang);
- AddInlineVisibilityCompileOption(flags, target, this);
}
//----------------------------------------------------------------------------
-void cmLocalGenerator::AddCMP0018Flags(std::string &flags, cmTarget* target,
+void cmLocalGenerator::AddCMP0018Flags(std::string &flags,
+ cmGeneratorTarget const* target,
std::string const& lang,
- const char *config)
+ const std::string& config)
{
int targetType = target->GetType();
- bool shared = ((targetType == cmTarget::SHARED_LIBRARY) ||
- (targetType == cmTarget::MODULE_LIBRARY));
+ bool shared = ((targetType == cmState::SHARED_LIBRARY) ||
+ (targetType == cmState::MODULE_LIBRARY));
if (this->GetShouldUseOldFlags(shared, lang))
{
- this->AddSharedFlags(flags, lang.c_str(), shared);
+ this->AddSharedFlags(flags, lang, shared);
}
else
{
- if (target->GetType() == cmTarget::OBJECT_LIBRARY)
+ if (target->GetType() == cmState::OBJECT_LIBRARY)
{
if (target->GetPropertyAsBool("POSITION_INDEPENDENT_CODE"))
{
@@ -2153,7 +2244,7 @@ void cmLocalGenerator::AddCMP0018Flags(std::string &flags, cmTarget* target,
}
if (shared)
{
- this->AppendFeatureOptions(flags, lang.c_str(), "DLL");
+ this->AppendFeatureOptions(flags, lang, "DLL");
}
}
}
@@ -2170,24 +2261,23 @@ bool cmLocalGenerator::GetShouldUseOldFlags(bool shared,
flagsVar += lang;
flagsVar += "_FLAGS";
const char* flags =
- this->Makefile->GetSafeDefinition(flagsVar.c_str());
+ this->Makefile->GetSafeDefinition(flagsVar);
if (flags && flags != originalFlags)
{
- switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0018))
+ switch (this->GetPolicyStatus(cmPolicies::CMP0018))
{
case cmPolicies::WARN:
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Variable " << flagsVar << " has been modified. CMake "
"will ignore the POSITION_INDEPENDENT_CODE target property for "
"shared libraries and will use the " << flagsVar << " variable "
"instead. This may cause errors if the original content of "
<< flagsVar << " was removed.\n"
- << this->Makefile->GetPolicies()->GetPolicyWarning(
- cmPolicies::CMP0018);
+ << cmPolicies::GetPolicyWarning(cmPolicies::CMP0018);
- this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, e.str());
+ this->IssueMessage(cmake::AUTHOR_WARNING, e.str());
// fall through to OLD behaviour
}
case cmPolicies::OLD:
@@ -2195,7 +2285,6 @@ bool cmLocalGenerator::GetShouldUseOldFlags(bool shared,
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
- default:
return false;
}
}
@@ -2210,19 +2299,19 @@ void cmLocalGenerator::AddPositionIndependentFlags(std::string& flags,
{
const char* picFlags = 0;
- if(targetType == cmTarget::EXECUTABLE)
+ if(targetType == cmState::EXECUTABLE)
{
std::string flagsVar = "CMAKE_";
flagsVar += lang;
flagsVar += "_COMPILE_OPTIONS_PIE";
- picFlags = this->Makefile->GetSafeDefinition(flagsVar.c_str());
+ picFlags = this->Makefile->GetSafeDefinition(flagsVar);
}
if (!picFlags)
{
std::string flagsVar = "CMAKE_";
flagsVar += lang;
flagsVar += "_COMPILE_OPTIONS_PIC";
- picFlags = this->Makefile->GetSafeDefinition(flagsVar.c_str());
+ picFlags = this->Makefile->GetSafeDefinition(flagsVar);
}
if (picFlags)
{
@@ -2231,36 +2320,35 @@ void cmLocalGenerator::AddPositionIndependentFlags(std::string& flags,
for(std::vector<std::string>::const_iterator oi = options.begin();
oi != options.end(); ++oi)
{
- this->AppendFlagEscape(flags, oi->c_str());
+ this->AppendFlagEscape(flags, *oi);
}
}
}
//----------------------------------------------------------------------------
void cmLocalGenerator::AddConfigVariableFlags(std::string& flags,
- const char* var,
- const char* config)
+ const std::string& var,
+ const std::string& config)
{
// Add the flags from the variable itself.
std::string flagsVar = var;
- this->AppendFlags(flags, this->Makefile->GetDefinition(flagsVar.c_str()));
+ this->AppendFlags(flags, this->Makefile->GetDefinition(flagsVar));
// Add the flags from the build-type specific variable.
- if(config && *config)
+ if(!config.empty())
{
flagsVar += "_";
flagsVar += cmSystemTools::UpperCase(config);
- this->AppendFlags(flags, this->Makefile->GetDefinition(flagsVar.c_str()));
+ this->AppendFlags(flags, this->Makefile->GetDefinition(flagsVar));
}
}
//----------------------------------------------------------------------------
void cmLocalGenerator::AppendFlags(std::string& flags,
- const char* newFlags)
+ const std::string& newFlags)
{
- if(newFlags && *newFlags)
+ if(!newFlags.empty())
{
- std::string newf = newFlags;
- if(flags.size())
+ if(!flags.empty())
{
flags += " ";
}
@@ -2269,10 +2357,20 @@ void cmLocalGenerator::AppendFlags(std::string& flags,
}
//----------------------------------------------------------------------------
+void cmLocalGenerator::AppendFlags(std::string& flags,
+ const char* newFlags)
+{
+ if(newFlags && *newFlags)
+ {
+ this->AppendFlags(flags, std::string(newFlags));
+ }
+}
+
+//----------------------------------------------------------------------------
void cmLocalGenerator::AppendFlagEscape(std::string& flags,
- const char* rawFlag)
+ const std::string& rawFlag)
{
- this->AppendFlags(flags, this->EscapeForShell(rawFlag).c_str());
+ this->AppendFlags(flags, this->EscapeForShell(rawFlag));
}
//----------------------------------------------------------------------------
@@ -2310,16 +2408,16 @@ void cmLocalGenerator::AppendDefines(std::set<std::string>& defines,
//----------------------------------------------------------------------------
void cmLocalGenerator::JoinDefines(const std::set<std::string>& defines,
std::string &definesString,
- const char* lang)
+ const std::string& lang)
{
// Lookup the define flag for the current language.
std::string dflag = "-D";
- if(lang)
+ if(!lang.empty())
{
std::string defineFlagVar = "CMAKE_";
defineFlagVar += lang;
defineFlagVar += "_DEFINE_FLAG";
- const char* df = this->Makefile->GetDefinition(defineFlagVar.c_str());
+ const char* df = this->Makefile->GetDefinition(defineFlagVar);
if(df && *df)
{
dflag = df;
@@ -2333,7 +2431,7 @@ void cmLocalGenerator::JoinDefines(const std::set<std::string>& defines,
{
// Append the definition with proper escaping.
std::string def = dflag;
- if(this->WatcomWMake)
+ if(this->GetState()->UseWatcomWMake())
{
// The Watcom compiler does its own command line parsing instead
// of using the windows shell rules. Definitions are one of
@@ -2374,401 +2472,131 @@ void cmLocalGenerator::JoinDefines(const std::set<std::string>& defines,
//----------------------------------------------------------------------------
void cmLocalGenerator::AppendFeatureOptions(
- std::string& flags, const char* lang, const char* feature)
+ std::string& flags, const std::string& lang, const char* feature)
{
std::string optVar = "CMAKE_";
optVar += lang;
optVar += "_COMPILE_OPTIONS_";
optVar += feature;
- if(const char* optionList = this->Makefile->GetDefinition(optVar.c_str()))
+ if(const char* optionList = this->Makefile->GetDefinition(optVar))
{
std::vector<std::string> options;
cmSystemTools::ExpandListArgument(optionList, options);
for(std::vector<std::string>::const_iterator oi = options.begin();
oi != options.end(); ++oi)
{
- this->AppendFlagEscape(flags, oi->c_str());
+ this->AppendFlagEscape(flags, *oi);
}
}
}
//----------------------------------------------------------------------------
-std::string
-cmLocalGenerator::ConstructComment(const cmCustomCommand& cc,
- const char* default_comment)
+const char* cmLocalGenerator::GetFeature(const std::string& feature,
+ const std::string& config)
{
- // Check for a comment provided with the command.
- if(cc.GetComment())
+ std::string featureName = feature;
+ // TODO: Define accumulation policy for features (prepend, append, replace).
+ // Currently we always replace.
+ if(!config.empty())
{
- return cc.GetComment();
+ featureName += "_";
+ featureName += cmSystemTools::UpperCase(config);
}
-
- // Construct a reasonable default comment if possible.
- if(!cc.GetOutputs().empty())
+ cmState::Snapshot snp = this->StateSnapshot;
+ while(snp.IsValid())
{
- std::string comment;
- comment = "Generating ";
- const char* sep = "";
- for(std::vector<std::string>::const_iterator o = cc.GetOutputs().begin();
- o != cc.GetOutputs().end(); ++o)
+ if(const char* value = snp.GetDirectory().GetProperty(featureName))
{
- comment += sep;
- comment += this->Convert(o->c_str(), cmLocalGenerator::START_OUTPUT);
- sep = ", ";
+ return value;
}
- return comment;
- }
-
- // Otherwise use the provided default.
- return default_comment;
-}
-
-//----------------------------------------------------------------------------
-std::string
-cmLocalGenerator::ConvertToOptionallyRelativeOutputPath(const char* remote)
-{
- return this->Convert(remote, START_OUTPUT, SHELL, true);
-}
-
-//----------------------------------------------------------------------------
-const char* cmLocalGenerator::GetRelativeRootPath(RelativeRoot relroot)
-{
- switch (relroot)
- {
- case HOME: return this->Makefile->GetHomeDirectory();
- case START: return this->Makefile->GetStartDirectory();
- case HOME_OUTPUT: return this->Makefile->GetHomeOutputDirectory();
- case START_OUTPUT: return this->Makefile->GetStartOutputDirectory();
- default: break;
+ snp = snp.GetBuildsystemDirectoryParent();
}
return 0;
}
-//----------------------------------------------------------------------------
-std::string cmLocalGenerator::Convert(const char* source,
- RelativeRoot relative,
- OutputFormat output,
- bool optional)
+std::string cmLocalGenerator::GetProjectName() const
{
- // Make sure the relative path conversion components are set.
- if(!this->PathConversionsSetup)
- {
- this->SetupPathConversions();
- this->PathConversionsSetup = true;
- }
-
- // Convert the path to a relative path.
- std::string result = source;
-
- if (!optional || this->UseRelativePaths)
- {
- switch (relative)
- {
- case HOME:
- //result = cmSystemTools::CollapseFullPath(result.c_str());
- result = this->ConvertToRelativePath(this->HomeDirectoryComponents,
- result.c_str());
- break;
- case START:
- //result = cmSystemTools::CollapseFullPath(result.c_str());
- result = this->ConvertToRelativePath(this->StartDirectoryComponents,
- result.c_str());
- break;
- case HOME_OUTPUT:
- //result = cmSystemTools::CollapseFullPath(result.c_str());
- result =
- this->ConvertToRelativePath(this->HomeOutputDirectoryComponents,
- result.c_str());
- break;
- case START_OUTPUT:
- //result = cmSystemTools::CollapseFullPath(result.c_str());
- result =
- this->ConvertToRelativePath(this->StartOutputDirectoryComponents,
- result.c_str());
- break;
- case FULL:
- result = cmSystemTools::CollapseFullPath(result.c_str());
- break;
- case NONE:
- break;
- }
- }
- return this->ConvertToOutputFormat(result.c_str(), output);
-}
-
-//----------------------------------------------------------------------------
-std::string cmLocalGenerator::ConvertToOutputFormat(const char* source,
- OutputFormat output)
-{
- std::string result = source;
- // Convert it to an output path.
- if (output == MAKEFILE)
- {
- result = cmSystemTools::ConvertToOutputPath(result.c_str());
- }
- else if( output == SHELL)
- {
- // For the MSYS shell convert drive letters to posix paths, so
- // that c:/some/path becomes /c/some/path. This is needed to
- // avoid problems with the shell path translation.
- if(this->MSYSShell && !this->LinkScriptShell)
- {
- if(result.size() > 2 && result[1] == ':')
- {
- result[1] = result[0];
- result[0] = '/';
- }
- }
- if(this->WindowsShell)
- {
- std::string::size_type pos = 0;
- while((pos = result.find('/', pos)) != std::string::npos)
- {
- result[pos] = '\\';
- pos++;
- }
- }
- result = this->EscapeForShell(result.c_str(), true, false);
- }
- else if(output == RESPONSE)
- {
- result = this->EscapeForShell(result.c_str(), false, false);
- }
- return result;
-}
-
-//----------------------------------------------------------------------------
-std::string cmLocalGenerator::Convert(RelativeRoot remote,
- const char* local,
- OutputFormat output,
- bool optional)
-{
- const char* remotePath = this->GetRelativeRootPath(remote);
-
- // The relative root must have a path (i.e. not FULL or NONE)
- assert(remotePath != 0);
-
- if(local && (!optional || this->UseRelativePaths))
- {
- std::vector<std::string> components;
- cmSystemTools::SplitPath(local, components);
- std::string result = this->ConvertToRelativePath(components, remotePath);
- return this->ConvertToOutputFormat(result.c_str(), output);
- }
- else
- {
- return this->ConvertToOutputFormat(remotePath, output);
- }
+ return this->StateSnapshot.GetProjectName();
}
//----------------------------------------------------------------------------
-std::string cmLocalGenerator::FindRelativePathTopSource()
+std::string
+cmLocalGenerator::ConstructComment(cmCustomCommandGenerator const& ccg,
+ const char* default_comment)
{
- // Relative path conversion within a single tree managed by CMake is
- // safe. We can use our parent relative path top if and only if
- // this is a subdirectory of that top.
- if(cmLocalGenerator* parent = this->GetParent())
+ // Check for a comment provided with the command.
+ if(ccg.GetComment())
{
- std::string parentTop = parent->FindRelativePathTopSource();
- if(cmSystemTools::IsSubDirectory(
- this->Makefile->GetStartDirectory(), parentTop.c_str()))
- {
- return parentTop;
- }
+ return ccg.GetComment();
}
- // Otherwise this directory itself is the new top.
- return this->Makefile->GetStartDirectory();
-}
-
-//----------------------------------------------------------------------------
-std::string cmLocalGenerator::FindRelativePathTopBinary()
-{
- // Relative path conversion within a single tree managed by CMake is
- // safe. We can use our parent relative path top if and only if
- // this is a subdirectory of that top.
- if(cmLocalGenerator* parent = this->GetParent())
+ // Construct a reasonable default comment if possible.
+ if(!ccg.GetOutputs().empty())
{
- std::string parentTop = parent->FindRelativePathTopBinary();
- if(cmSystemTools::IsSubDirectory(
- this->Makefile->GetStartOutputDirectory(), parentTop.c_str()))
+ std::string comment;
+ comment = "Generating ";
+ const char* sep = "";
+ for(std::vector<std::string>::const_iterator o = ccg.GetOutputs().begin();
+ o != ccg.GetOutputs().end(); ++o)
{
- return parentTop;
+ comment += sep;
+ comment += this->Convert(*o, cmLocalGenerator::START_OUTPUT);
+ sep = ", ";
}
+ return comment;
}
- // Otherwise this directory itself is the new top.
- return this->Makefile->GetStartOutputDirectory();
-}
-
-//----------------------------------------------------------------------------
-void cmLocalGenerator::ConfigureRelativePaths()
-{
- // Relative path conversion inside the source tree is not used to
- // construct relative paths passed to build tools so it is safe to
- // even when the source is a network path.
- std::string source = this->FindRelativePathTopSource();
- this->RelativePathTopSource = source;
-
- // The current working directory on Windows cannot be a network
- // path. Therefore relative paths cannot work when the binary tree
- // is a network path.
- std::string binary = this->FindRelativePathTopBinary();
- if(binary.size() < 2 || binary.substr(0, 2) != "//")
- {
- this->RelativePathTopBinary = binary;
- }
- else
- {
- this->RelativePathTopBinary = "";
- }
-}
-
-//----------------------------------------------------------------------------
-static bool cmLocalGeneratorNotAbove(const char* a, const char* b)
-{
- return (cmSystemTools::ComparePath(a, b) ||
- cmSystemTools::IsSubDirectory(a, b));
+ // Otherwise use the provided default.
+ return default_comment;
}
//----------------------------------------------------------------------------
-std::string
-cmLocalGenerator::ConvertToRelativePath(const std::vector<std::string>& local,
- const char* in_remote, bool force)
+class cmInstallTargetGeneratorLocal: public cmInstallTargetGenerator
{
- // The path should never be quoted.
- assert(in_remote[0] != '\"');
-
- // The local path should never have a trailing slash.
- assert(local.size() > 0 && !(local[local.size()-1] == ""));
-
- // If the path is already relative then just return the path.
- if(!cmSystemTools::FileIsFullPath(in_remote))
- {
- return in_remote;
- }
-
- // Make sure relative path conversion is configured.
- if(!this->RelativePathsConfigured)
- {
- this->ConfigureRelativePaths();
- this->RelativePathsConfigured = true;
- }
-
- if(!force)
- {
- // Skip conversion if the path and local are not both in the source
- // or both in the binary tree.
- std::string local_path = cmSystemTools::JoinPath(local);
- if(!((cmLocalGeneratorNotAbove(local_path.c_str(),
- this->RelativePathTopBinary.c_str()) &&
- cmLocalGeneratorNotAbove(in_remote,
- this->RelativePathTopBinary.c_str())) ||
- (cmLocalGeneratorNotAbove(local_path.c_str(),
- this->RelativePathTopSource.c_str()) &&
- cmLocalGeneratorNotAbove(in_remote,
- this->RelativePathTopSource.c_str()))))
- {
- return in_remote;
- }
- }
-
- // Identify the longest shared path component between the remote
- // path and the local path.
- std::vector<std::string> remote;
- cmSystemTools::SplitPath(in_remote, remote);
- unsigned int common=0;
- while(common < remote.size() &&
- common < local.size() &&
- cmSystemTools::ComparePath(remote[common].c_str(),
- local[common].c_str()))
- {
- ++common;
- }
-
- // If no part of the path is in common then return the full path.
- if(common == 0)
- {
- return in_remote;
- }
-
- // If the entire path is in common then just return a ".".
- if(common == remote.size() &&
- common == local.size())
- {
- return ".";
- }
-
- // If the entire path is in common except for a trailing slash then
- // just return a "./".
- if(common+1 == remote.size() &&
- remote[common].size() == 0 &&
- common == local.size())
- {
- return "./";
- }
-
- // Construct the relative path.
- std::string relative;
-
- // First add enough ../ to get up to the level of the shared portion
- // of the path. Leave off the trailing slash. Note that the last
- // component of local will never be empty because local should never
- // have a trailing slash.
- for(unsigned int i=common; i < local.size(); ++i)
- {
- relative += "..";
- if(i < local.size()-1)
- {
- relative += "/";
- }
- }
-
- // Now add the portion of the destination path that is not included
- // in the shared portion of the path. Add a slash the first time
- // only if there was already something in the path. If there was a
- // trailing slash in the input then the last iteration of the loop
- // will add a slash followed by an empty string which will preserve
- // the trailing slash in the output.
- for(unsigned int i=common; i < remote.size(); ++i)
- {
- if(relative.size() > 0)
- {
- relative += "/";
- }
- relative += remote[i];
- }
-
- // Finally return the path.
- return relative;
-}
+public:
+ cmInstallTargetGeneratorLocal(cmLocalGenerator* lg, std::string const& t,
+ const char* dest, bool implib):
+ cmInstallTargetGenerator(
+ t, dest, implib, "", std::vector<std::string>(), "Unspecified",
+ cmInstallGenerator::SelectMessageLevel(lg->GetMakefile()),
+ false)
+ {
+ this->Compute(lg);
+ }
+};
//----------------------------------------------------------------------------
void
cmLocalGenerator
::GenerateTargetInstallRules(
- std::ostream& os, const char* config,
+ std::ostream& os, const std::string& config,
std::vector<std::string> const& configurationTypes)
{
// Convert the old-style install specification from each target to
// an install generator and run it.
- cmTargets& tgts = this->Makefile->GetTargets();
- for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); ++l)
+ std::vector<cmGeneratorTarget*> tgts = this->GetGeneratorTargets();
+ for(std::vector<cmGeneratorTarget*>::iterator l = tgts.begin();
+ l != tgts.end(); ++l)
{
+ if ((*l)->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ continue;
+ }
+
// Include the user-specified pre-install script for this target.
- if(const char* preinstall = l->second.GetProperty("PRE_INSTALL_SCRIPT"))
+ if(const char* preinstall = (*l)->GetProperty("PRE_INSTALL_SCRIPT"))
{
cmInstallScriptGenerator g(preinstall, false, 0);
g.Generate(os, config, configurationTypes);
}
// Install this target if a destination is given.
- if(l->second.GetInstallPath() != "")
+ if((*l)->Target->GetInstallPath() != "")
{
// Compute the full install destination. Note that converting
// to unix slashes also removes any trailing slash.
// We also skip over the leading slash given by the user.
- std::string destination = l->second.GetInstallPath().substr(1);
+ std::string destination = (*l)->Target->GetInstallPath().substr(1);
cmSystemTools::ConvertToUnixSlashes(destination);
if(destination.empty())
{
@@ -2776,33 +2604,37 @@ cmLocalGenerator
}
// Generate the proper install generator for this target type.
- switch(l->second.GetType())
+ switch((*l)->GetType())
{
- case cmTarget::EXECUTABLE:
- case cmTarget::STATIC_LIBRARY:
- case cmTarget::MODULE_LIBRARY:
+ case cmState::EXECUTABLE:
+ case cmState::STATIC_LIBRARY:
+ case cmState::MODULE_LIBRARY:
{
// Use a target install generator.
- cmInstallTargetGenerator g(l->second, destination.c_str(), false);
+ cmInstallTargetGeneratorLocal
+ g(this, (*l)->GetName(), destination.c_str(), false);
g.Generate(os, config, configurationTypes);
}
break;
- case cmTarget::SHARED_LIBRARY:
+ case cmState::SHARED_LIBRARY:
{
#if defined(_WIN32) || defined(__CYGWIN__)
// Special code to handle DLL. Install the import library
// to the normal destination and the DLL to the runtime
// destination.
- cmInstallTargetGenerator g1(l->second, destination.c_str(), true);
+ cmInstallTargetGeneratorLocal
+ g1(this, (*l)->GetName(), destination.c_str(), true);
g1.Generate(os, config, configurationTypes);
// We also skip over the leading slash given by the user.
- destination = l->second.GetRuntimeInstallPath().substr(1);
+ destination = (*l)->Target->GetRuntimeInstallPath().substr(1);
cmSystemTools::ConvertToUnixSlashes(destination);
- cmInstallTargetGenerator g2(l->second, destination.c_str(), false);
+ cmInstallTargetGeneratorLocal
+ g2(this, (*l)->GetName(), destination.c_str(), false);
g2.Generate(os, config, configurationTypes);
#else
// Use a target install generator.
- cmInstallTargetGenerator g(l->second, destination.c_str(), false);
+ cmInstallTargetGeneratorLocal
+ g(this, (*l)->GetName(), destination.c_str(), false);
g.Generate(os, config, configurationTypes);
#endif
}
@@ -2813,7 +2645,7 @@ cmLocalGenerator
}
// Include the user-specified post-install script for this target.
- if(const char* postinstall = l->second.GetProperty("POST_INSTALL_SCRIPT"))
+ if(const char* postinstall = (*l)->GetProperty("POST_INSTALL_SCRIPT"))
{
cmInstallScriptGenerator g(postinstall, false, 0);
g.Generate(os, config, configurationTypes);
@@ -2889,11 +2721,11 @@ bool cmLocalGeneratorCheckObjectName(std::string& objName,
//----------------------------------------------------------------------------
std::string&
cmLocalGenerator
-::CreateSafeUniqueObjectFileName(const char* sin,
+::CreateSafeUniqueObjectFileName(const std::string& sin,
std::string const& dir_max)
{
// Look for an existing mapped name for this object file.
- std::map<cmStdString,cmStdString>::iterator it =
+ std::map<std::string,std::string>::iterator it =
this->UniqueObjectNamesMap.find(sin);
// If no entry exists create one.
@@ -2903,11 +2735,7 @@ cmLocalGenerator
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);
+ ssin.erase(0, ssin.find_first_not_of("/"));
// Avoid full paths by removing colons.
cmSystemTools::ReplaceString(ssin, ":", "_");
@@ -2957,7 +2785,7 @@ cmLocalGenerator
// Warn if this is the first time the path has been seen.
if(this->ObjectMaxPathViolations.insert(dir_max).second)
{
- cmOStringStream m;
+ std::ostringstream m;
m << "The object file directory\n"
<< " " << dir_max << "\n"
<< "has " << dir_max.size() << " characters. "
@@ -2968,7 +2796,7 @@ cmLocalGenerator
<< " " << ssin << "\n"
<< "cannot be safely placed under this directory. "
<< "The build may not work correctly.";
- this->Makefile->IssueMessage(cmake::WARNING, m.str());
+ this->IssueMessage(cmake::WARNING, m.str());
}
}
#else
@@ -2976,7 +2804,7 @@ cmLocalGenerator
#endif
// Insert the newly mapped object file name.
- std::map<cmStdString, cmStdString>::value_type e(sin, ssin);
+ std::map<std::string, std::string>::value_type e(sin, ssin);
it = this->UniqueObjectNamesMap.insert(e).first;
}
@@ -2985,6 +2813,34 @@ cmLocalGenerator
}
//----------------------------------------------------------------------------
+void cmLocalGenerator::ComputeObjectFilenames(
+ std::map<cmSourceFile const*, std::string>&,
+ cmGeneratorTarget const*)
+{
+
+}
+
+bool cmLocalGenerator::IsWindowsShell() const
+{
+ return this->GetState()->UseWindowsShell();
+}
+
+bool cmLocalGenerator::IsWatcomWMake() const
+{
+ return this->GetState()->UseWatcomWMake();
+}
+
+bool cmLocalGenerator::IsMinGWMake() const
+{
+ return this->GetState()->UseMinGWMake();
+}
+
+bool cmLocalGenerator::IsNMake() const
+{
+ return this->GetState()->UseNMake();
+}
+
+//----------------------------------------------------------------------------
std::string
cmLocalGenerator
::GetObjectFileNameWithoutTarget(const cmSourceFile& source,
@@ -3046,15 +2902,16 @@ cmLocalGenerator
// Decide whether this language wants to replace the source
// extension with the object extension. For CMake 2.4
// compatibility do this by default.
- bool replaceExt = this->NeedBackwardsCompatibility(2, 4);
+ bool replaceExt = this->NeedBackwardsCompatibility_2_4();
if(!replaceExt)
{
- if(const char* lang = source.GetLanguage())
+ std::string lang = source.GetLanguage();
+ if(!lang.empty())
{
std::string repVar = "CMAKE_";
repVar += lang;
repVar += "_OUTPUT_EXTENSION_REPLACE";
- replaceExt = this->Makefile->IsOn(repVar.c_str());
+ replaceExt = this->Makefile->IsOn(repVar);
}
}
@@ -3079,186 +2936,45 @@ cmLocalGenerator
}
// Convert to a safe name.
- return this->CreateSafeUniqueObjectFileName(objectName.c_str(), dir_max);
+ return this->CreateSafeUniqueObjectFileName(objectName, dir_max);
}
//----------------------------------------------------------------------------
-const char*
+std::string
cmLocalGenerator
::GetSourceFileLanguage(const cmSourceFile& source)
{
return source.GetLanguage();
}
-//----------------------------------------------------------------------------
-std::string cmLocalGenerator::EscapeForShellOldStyle(const char* str)
+cmake* cmLocalGenerator::GetCMakeInstance() const
{
- std::string result;
-#if defined(_WIN32) && !defined(__CYGWIN__)
- // if there are spaces
- std::string temp = str;
- if (temp.find(" ") != std::string::npos &&
- temp.find("\"")==std::string::npos)
- {
- result = "\"";
- result += str;
- result += "\"";
- return result;
- }
- return str;
-#else
- for(const char* ch = str; *ch != '\0'; ++ch)
- {
- if(*ch == ' ')
- {
- result += '\\';
- }
- result += *ch;
- }
- return result;
-#endif
+ return this->GlobalGenerator->GetCMakeInstance();
}
-//----------------------------------------------------------------------------
-static bool cmLocalGeneratorIsShellOperator(const char* str)
-{
- if(strcmp(str, "<") == 0 ||
- strcmp(str, ">") == 0 ||
- strcmp(str, "<<") == 0 ||
- strcmp(str, ">>") == 0 ||
- strcmp(str, "|") == 0 ||
- strcmp(str, "||") == 0 ||
- strcmp(str, "&&") == 0 ||
- strcmp(str, "&>") == 0 ||
- strcmp(str, "1>") == 0 ||
- strcmp(str, "2>") == 0 ||
- strcmp(str, "2>&1") == 0 ||
- strcmp(str, "1>&2") == 0)
- {
- return true;
- }
- return false;
+const char* cmLocalGenerator::GetSourceDirectory() const
+{
+ return this->GetCMakeInstance()->GetHomeDirectory();
}
-//----------------------------------------------------------------------------
-std::string cmLocalGenerator::EscapeForShell(const char* str, bool makeVars,
- bool forEcho)
+const char* cmLocalGenerator::GetBinaryDirectory() const
{
- // Do not escape shell operators.
- if(cmLocalGeneratorIsShellOperator(str))
- {
- return str;
- }
-
- // Compute the flags for the target shell environment.
- int flags = 0;
- if(this->WindowsVSIDE)
- {
- flags |= cmsysSystem_Shell_Flag_VSIDE;
- }
- else if(!this->LinkScriptShell)
- {
- flags |= cmsysSystem_Shell_Flag_Make;
- }
- if(makeVars)
- {
- flags |= cmsysSystem_Shell_Flag_AllowMakeVariables;
- }
- if(forEcho)
- {
- flags |= cmsysSystem_Shell_Flag_EchoWindows;
- }
- if(this->WatcomWMake)
- {
- flags |= cmsysSystem_Shell_Flag_WatcomWMake;
- }
- if(this->MinGWMake)
- {
- flags |= cmsysSystem_Shell_Flag_MinGWMake;
- }
- if(this->NMake)
- {
- flags |= cmsysSystem_Shell_Flag_NMake;
- }
-
- // Compute the buffer size needed.
- int size = (this->WindowsShell ?
- cmsysSystem_Shell_GetArgumentSizeForWindows(str, flags) :
- cmsysSystem_Shell_GetArgumentSizeForUnix(str, flags));
-
- // Compute the shell argument itself.
- std::vector<char> arg(size);
- if(this->WindowsShell)
- {
- cmsysSystem_Shell_GetArgumentForWindows(str, &arg[0], flags);
- }
- else
- {
- cmsysSystem_Shell_GetArgumentForUnix(str, &arg[0], flags);
- }
- return std::string(&arg[0]);
+ return this->GetCMakeInstance()->GetHomeOutputDirectory();
}
-//----------------------------------------------------------------------------
-std::string cmLocalGenerator::EscapeForCMake(const char* str)
+const char* cmLocalGenerator::GetCurrentBinaryDirectory() const
{
- // Always double-quote the argument to take care of most escapes.
- std::string result = "\"";
- for(const char* c = str; *c; ++c)
- {
- if(*c == '"')
- {
- // Escape the double quote to avoid ending the argument.
- result += "\\\"";
- }
- else if(*c == '$')
- {
- // Escape the dollar to avoid expanding variables.
- result += "\\$";
- }
- else if(*c == '\\')
- {
- // Escape the backslash to avoid other escapes.
- result += "\\\\";
- }
- else
- {
- // Other characters will be parsed correctly.
- result += *c;
- }
- }
- result += "\"";
- return result;
+ return this->StateSnapshot.GetDirectory().GetCurrentBinary();
}
-//----------------------------------------------------------------------------
-cmLocalGenerator::FortranFormat
-cmLocalGenerator::GetFortranFormat(const char* value)
+const char* cmLocalGenerator::GetCurrentSourceDirectory() const
{
- FortranFormat format = FortranFormatNone;
- if(value && *value)
- {
- std::vector<std::string> fmt;
- cmSystemTools::ExpandListArgument(value, fmt);
- for(std::vector<std::string>::iterator fi = fmt.begin();
- fi != fmt.end(); ++fi)
- {
- if(*fi == "FIXED")
- {
- format = FortranFormatFixed;
- }
- if(*fi == "FREE")
- {
- format = FortranFormatFree;
- }
- }
- }
- return format;
+ return this->StateSnapshot.GetDirectory().GetCurrentSource();
}
//----------------------------------------------------------------------------
std::string
-cmLocalGenerator::GetTargetDirectory(cmTarget const&) const
+cmLocalGenerator::GetTargetDirectory(const cmGeneratorTarget*) const
{
cmSystemTools::Error("GetTargetDirectory"
" called on cmLocalGenerator");
@@ -3266,7 +2982,7 @@ cmLocalGenerator::GetTargetDirectory(cmTarget const&) const
}
//----------------------------------------------------------------------------
-unsigned int cmLocalGenerator::GetBackwardsCompatibility()
+KWIML_INT_uint64_t cmLocalGenerator::GetBackwardsCompatibility()
{
// The computed version may change until the project is fully
// configured.
@@ -3286,20 +3002,18 @@ unsigned int cmLocalGenerator::GetBackwardsCompatibility()
}
}
this->BackwardsCompatibility = CMake_VERSION_ENCODE(major, minor, patch);
- this->BackwardsCompatibilityFinal = this->Configured;
+ this->BackwardsCompatibilityFinal = true;
}
return this->BackwardsCompatibility;
}
//----------------------------------------------------------------------------
-bool cmLocalGenerator::NeedBackwardsCompatibility(unsigned int major,
- unsigned int minor,
- unsigned int patch)
+bool cmLocalGenerator::NeedBackwardsCompatibility_2_4()
{
// Check the policy to decide whether to pay attention to this
// variable.
- switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0001))
+ switch(this->GetPolicyStatus(cmPolicies::CMP0001))
{
case cmPolicies::WARN:
// WARN is just OLD without warning because user code does not
@@ -3321,40 +3035,41 @@ bool cmLocalGenerator::NeedBackwardsCompatibility(unsigned int major,
// Compatibility is needed if CMAKE_BACKWARDS_COMPATIBILITY is set
// equal to or lower than the given version.
- unsigned int actual_compat = this->GetBackwardsCompatibility();
+ KWIML_INT_uint64_t actual_compat = this->GetBackwardsCompatibility();
return (actual_compat &&
- actual_compat <= CMake_VERSION_ENCODE(major, minor, patch));
+ actual_compat <= CMake_VERSION_ENCODE(2, 4, 255));
+}
+
+cmPolicies::PolicyStatus
+cmLocalGenerator::GetPolicyStatus(cmPolicies::PolicyID id) const
+{
+ return this->Makefile->GetPolicyStatus(id);
}
//----------------------------------------------------------------------------
bool cmLocalGenerator::CheckDefinition(std::string const& define) const
{
// Many compilers do not support -DNAME(arg)=sdf so we disable it.
- bool function_style = false;
- for(const char* c = define.c_str(); *c && *c != '='; ++c)
- {
- if(*c == '(')
- {
- function_style = true;
- break;
+ std::string::size_type pos = define.find_first_of("(=");
+ if (pos != std::string::npos)
+ {
+ if (define[pos] == '(')
+ {
+ std::ostringstream e;
+ e << "WARNING: Function-style preprocessor definitions may not be "
+ << "passed on the compiler command line because many compilers "
+ << "do not support it.\n"
+ << "CMake is dropping a preprocessor definition: " << define << "\n"
+ << "Consider defining the macro in a (configured) header file.\n";
+ cmSystemTools::Message(e.str().c_str());
+ return false;
}
}
- if(function_style)
- {
- cmOStringStream e;
- e << "WARNING: Function-style preprocessor definitions may not be "
- << "passed on the compiler command line because many compilers "
- << "do not support it.\n"
- << "CMake is dropping a preprocessor definition: " << define << "\n"
- << "Consider defining the macro in a (configured) header file.\n";
- cmSystemTools::Message(e.str().c_str());
- return false;
- }
// Many compilers do not support # in the value so we disable it.
if(define.find_first_of("#") != define.npos)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "WARNING: Preprocessor definitions containing '#' may not be "
<< "passed on the compiler command line because many compilers "
<< "do not support it.\n"
@@ -3369,7 +3084,8 @@ bool cmLocalGenerator::CheckDefinition(std::string const& define) const
}
//----------------------------------------------------------------------------
-static void cmLGInfoProp(cmMakefile* mf, cmTarget* target, const char* prop)
+static void cmLGInfoProp(cmMakefile* mf, cmGeneratorTarget* target,
+ const std::string& prop)
{
if(const char* val = target->GetProperty(prop))
{
@@ -3378,8 +3094,8 @@ static void cmLGInfoProp(cmMakefile* mf, cmTarget* target, const char* prop)
}
//----------------------------------------------------------------------------
-void cmLocalGenerator::GenerateAppleInfoPList(cmTarget* target,
- const char* targetName,
+void cmLocalGenerator::GenerateAppleInfoPList(cmGeneratorTarget* target,
+ const std::string& targetName,
const char* fname)
{
// Find the Info.plist template.
@@ -3395,7 +3111,7 @@ void cmLocalGenerator::GenerateAppleInfoPList(cmTarget* target,
}
if(!cmSystemTools::FileExists(inFile.c_str(), true))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Target " << target->GetName() << " Info.plist template \""
<< inFile << "\" could not be found.";
cmSystemTools::Error(e.str().c_str());
@@ -3407,8 +3123,8 @@ void cmLocalGenerator::GenerateAppleInfoPList(cmTarget* target,
// override user make variables. If not the configuration will fall
// back to the directory-level values set by the user.
cmMakefile* mf = this->Makefile;
- mf->PushScope();
- mf->AddDefinition("MACOSX_BUNDLE_EXECUTABLE_NAME", targetName);
+ cmMakefile::ScopePushPop varScope(mf);
+ mf->AddDefinition("MACOSX_BUNDLE_EXECUTABLE_NAME", targetName.c_str());
cmLGInfoProp(mf, target, "MACOSX_BUNDLE_INFO_STRING");
cmLGInfoProp(mf, target, "MACOSX_BUNDLE_ICON_FILE");
cmLGInfoProp(mf, target, "MACOSX_BUNDLE_GUI_IDENTIFIER");
@@ -3418,13 +3134,12 @@ void cmLocalGenerator::GenerateAppleInfoPList(cmTarget* target,
cmLGInfoProp(mf, target, "MACOSX_BUNDLE_BUNDLE_VERSION");
cmLGInfoProp(mf, target, "MACOSX_BUNDLE_COPYRIGHT");
mf->ConfigureFile(inFile.c_str(), fname, false, false, false);
- mf->PopScope();
}
//----------------------------------------------------------------------------
-void cmLocalGenerator::GenerateFrameworkInfoPList(cmTarget* target,
- const char* targetName,
- const char* fname)
+void cmLocalGenerator::GenerateFrameworkInfoPList(cmGeneratorTarget* target,
+ const std::string& targetName,
+ const char* fname)
{
// Find the Info.plist template.
const char* in = target->GetProperty("MACOSX_FRAMEWORK_INFO_PLIST");
@@ -3439,7 +3154,7 @@ void cmLocalGenerator::GenerateFrameworkInfoPList(cmTarget* target,
}
if(!cmSystemTools::FileExists(inFile.c_str(), true))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Target " << target->GetName() << " Info.plist template \""
<< inFile << "\" could not be found.";
cmSystemTools::Error(e.str().c_str());
@@ -3451,12 +3166,11 @@ void cmLocalGenerator::GenerateFrameworkInfoPList(cmTarget* target,
// override user make variables. If not the configuration will fall
// back to the directory-level values set by the user.
cmMakefile* mf = this->Makefile;
- mf->PushScope();
- mf->AddDefinition("MACOSX_FRAMEWORK_NAME", targetName);
+ cmMakefile::ScopePushPop varScope(mf);
+ mf->AddDefinition("MACOSX_FRAMEWORK_NAME", targetName.c_str());
cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_ICON_FILE");
cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_IDENTIFIER");
cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_SHORT_VERSION_STRING");
cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_BUNDLE_VERSION");
mf->ConfigureFile(inFile.c_str(), fname, false, false, false);
- mf->PopScope();
}
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 10f0b1a6c..68e766741 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -13,14 +13,17 @@
#define cmLocalGenerator_h
#include "cmStandardIncludes.h"
+#include "cmState.h"
+#include "cmake.h"
+#include "cmOutputConverter.h"
class cmMakefile;
class cmGlobalGenerator;
class cmGeneratorTarget;
-class cmTarget;
class cmTargetManifest;
class cmSourceFile;
class cmCustomCommand;
+class cmCustomCommandGenerator;
/** \class cmLocalGenerator
* \brief Create required build files for a directory.
@@ -29,10 +32,10 @@ class cmCustomCommand;
* platforms. This class should never be constructed directly. A
* GlobalGenerator will create it and invoke the appropriate commands on it.
*/
-class cmLocalGenerator
+class cmLocalGenerator : public cmOutputConverter
{
public:
- cmLocalGenerator();
+ cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile);
virtual ~cmLocalGenerator();
/**
@@ -40,11 +43,7 @@ public:
*/
virtual void Generate() {}
- /**
- * Process the CMakeLists files for this directory to fill in the
- * Makefile ivar
- */
- virtual void Configure();
+ virtual void ComputeHomeRelativeOutputPath() {}
/**
* Calls TraceVSDependencies() on all targets of this generator.
@@ -54,11 +53,6 @@ public:
virtual void AddHelperCommands() {}
/**
- * Perform any final calculations prior to generation
- */
- void ConfigureFinalPass();
-
- /**
* Generate the install rules files in this directory.
*/
void GenerateInstallRules();
@@ -71,90 +65,72 @@ public:
/**
* Generate a manifest of target files that will be built.
*/
- void GenerateTargetManifest();
+ void ComputeTargetManifest();
+
+ bool IsRootMakefile() const;
///! Get the makefile for this generator
cmMakefile *GetMakefile() {
- return this->Makefile; };
+ return this->Makefile; }
///! Get the makefile for this generator, const version
const cmMakefile *GetMakefile() const {
- return this->Makefile; };
+ return this->Makefile; }
///! Get the GlobalGenerator this is associated with
cmGlobalGenerator *GetGlobalGenerator() {
- return this->GlobalGenerator; };
+ return this->GlobalGenerator; }
const cmGlobalGenerator *GetGlobalGenerator() const {
- return this->GlobalGenerator; };
-
- ///! Set the Global Generator, done on creation by the GlobalGenerator
- void SetGlobalGenerator(cmGlobalGenerator *gg);
-
- /**
- * Convert something to something else. This is a centralized conversion
- * routine used by the generators to handle relative paths and the like.
- * The flags determine what is actually done.
- *
- * relative: treat the argument as a directory and convert it to make it
- * relative or full or unchanged. If relative (HOME, START etc) then that
- * specifies what it should be relative to.
- *
- * output: make the result suitable for output to a...
- *
- * optional: should any relative path operation be controlled by the rel
- * path setting
- */
- enum RelativeRoot { NONE, FULL, HOME, START, HOME_OUTPUT, START_OUTPUT };
- enum OutputFormat { UNCHANGED, MAKEFILE, SHELL, RESPONSE };
- std::string ConvertToOutputFormat(const char* source, OutputFormat output);
- std::string Convert(const char* remote, RelativeRoot local,
- OutputFormat output = UNCHANGED,
- bool optional = false);
- std::string Convert(RelativeRoot remote, const char* local,
- OutputFormat output = UNCHANGED,
- bool optional = false);
-
- /**
- * Get path for the specified relative root.
- */
- const char* GetRelativeRootPath(RelativeRoot relroot);
-
- /**
- * Convert the given path to an output path that is optionally
- * relative based on the cache option CMAKE_USE_RELATIVE_PATHS. The
- * remote path must use forward slashes and not already be escaped
- * or quoted.
- */
- std::string ConvertToOptionallyRelativeOutputPath(const char* remote);
-
- ///! set/get the parent generator
- cmLocalGenerator* GetParent(){return this->Parent;}
- void SetParent(cmLocalGenerator* g) { this->Parent = g; g->AddChild(this); }
-
- ///! set/get the children
- void AddChild(cmLocalGenerator* g) { this->Children.push_back(g); }
- std::vector<cmLocalGenerator*>& GetChildren() { return this->Children; };
-
-
- void AddArchitectureFlags(std::string& flags, cmGeneratorTarget* target,
- const char *lang, const char* config);
-
- void AddLanguageFlags(std::string& flags, const char* lang,
- const char* config);
- void AddCMP0018Flags(std::string &flags, cmTarget* target,
- std::string const& lang, const char *config);
- void AddVisibilityPresetFlags(std::string &flags, cmTarget* target,
- const char *lang);
- void AddConfigVariableFlags(std::string& flags, const char* var,
- const char* config);
+ return this->GlobalGenerator; }
+
+ cmState* GetState() const;
+ cmState::Snapshot GetStateSnapshot() const;
+
+ void AddArchitectureFlags(std::string& flags,
+ cmGeneratorTarget const* target,
+ const std::string&lang, const std::string& config);
+
+ void AddLanguageFlags(std::string& flags, const std::string& lang,
+ const std::string& config);
+ void AddCMP0018Flags(std::string &flags, cmGeneratorTarget const* target,
+ std::string const& lang, const std::string& config);
+ void AddVisibilityPresetFlags(std::string &flags,
+ cmGeneratorTarget const* target,
+ const std::string& lang);
+ void AddConfigVariableFlags(std::string& flags, const std::string& var,
+ const std::string& config);
+ void AddCompilerRequirementFlag(std::string &flags,
+ cmGeneratorTarget const* target,
+ const std::string& lang);
///! Append flags to a string.
+ virtual void AppendFlags(std::string& flags, const std::string& newFlags);
virtual void AppendFlags(std::string& flags, const char* newFlags);
- virtual void AppendFlagEscape(std::string& flags, const char* rawFlag);
+ virtual void AppendFlagEscape(std::string& flags,
+ const std::string& rawFlag);
///! Get the include flags for the current makefile and language
std::string GetIncludeFlags(const std::vector<std::string> &includes,
cmGeneratorTarget* target,
- const char* lang, bool forResponseFile = false,
- const char *config = 0);
+ const std::string& lang,
+ bool forceFullPaths = false,
+ bool forResponseFile = false,
+ const std::string& config = "");
+
+ const std::vector<cmGeneratorTarget*> &GetGeneratorTargets() const
+ {
+ return this->GeneratorTargets;
+ }
+
+ const std::vector<cmGeneratorTarget*> &GetImportedGeneratorTargets() const
+ {
+ return this->ImportedGeneratorTargets;
+ }
+
+ void AddGeneratorTarget(cmGeneratorTarget* gt);
+ void AddImportedGeneratorTarget(cmGeneratorTarget* gt);
+ void AddOwnedImportedGeneratorTarget(cmGeneratorTarget* gt);
+
+ cmGeneratorTarget* FindGeneratorTarget(const std::string& name) const;
+ cmGeneratorTarget* FindGeneratorTargetToUse(const std::string& name) const;
/**
* Encode a list of preprocessor definitions for the compiler
@@ -175,12 +151,15 @@ public:
*/
void JoinDefines(const std::set<std::string>& defines,
std::string &definesString,
- const char* lang);
+ const std::string& lang);
/** Lookup and append options associated with a particular feature. */
- void AppendFeatureOptions(std::string& flags, const char* lang,
+ void AppendFeatureOptions(std::string& flags, const std::string& lang,
const char* feature);
+ const char* GetFeature(const std::string& feature,
+ const std::string& config);
+
/** \brief Get absolute path to dependency \a name
*
* Translate a dependency as given in CMake code to the name to
@@ -193,19 +172,12 @@ public:
* the source directory of this generator. This should only be
* used for dependencies of custom commands.
*/
- bool GetRealDependency(const char* name, const char* config,
+ bool GetRealDependency(const std::string& name, const std::string& config,
std::string& dep);
- ///! for existing files convert to output path and short path if spaces
- std::string ConvertToOutputForExisting(const char* remote,
- RelativeRoot local = START_OUTPUT);
-
- /** For existing path identified by RelativeRoot convert to output
- path and short path if spaces. */
- std::string ConvertToOutputForExisting(RelativeRoot remote,
- const char* local = 0);
-
- virtual std::string ConvertToIncludeReference(std::string const& path);
+ virtual std::string ConvertToIncludeReference(std::string const& path,
+ OutputFormat format = SHELL,
+ bool forceFullPaths = false);
/** Called from command-line hook to clear dependencies. */
virtual void ClearDependencies(cmMakefile* /* mf */,
@@ -219,20 +191,25 @@ public:
/** Get the include flags for the current makefile and language. */
void GetIncludeDirectories(std::vector<std::string>& dirs,
- cmGeneratorTarget* target,
- const char* lang = "C", const char *config = 0,
- bool stripImplicitInclDirs = true);
- void AddCompileOptions(std::string& flags, cmTarget* target,
- const char* lang, const char* config);
- void AddCompileDefinitions(std::set<std::string>& defines, cmTarget* target,
- const char* config);
+ cmGeneratorTarget const* target,
+ const std::string& lang = "C",
+ const std::string& config = "",
+ bool stripImplicitInclDirs = true) const;
+ void AddCompileOptions(std::string& flags, cmGeneratorTarget* target,
+ const std::string& lang, const std::string& config);
+ void AddCompileDefinitions(std::set<std::string>& defines,
+ cmGeneratorTarget const* target,
+ const std::string& config,
+ const std::string& lang);
+
+ std::string GetProjectName() const;
/** Compute the language used to compile the given source file. */
- const char* GetSourceFileLanguage(const cmSourceFile& source);
+ std::string GetSourceFileLanguage(const cmSourceFile& source);
// Fill the vector with the target names for the object files,
// preprocessed files and assembly files.
- virtual void GetIndividualFileTargets(std::vector<std::string>&) {}
+ void GetIndividualFileTargets(std::vector<std::string>&) {}
// Create a struct to hold the varibles passed into
// ExpandRuleVariables
@@ -242,8 +219,9 @@ public:
{
memset(this, 0, sizeof(*this));
}
- cmTarget* CMTarget;
+ cmGeneratorTarget* CMTarget;
const char* TargetPDB;
+ const char* TargetCompilePDB;
const char* TargetVersionMajor;
const char* TargetVersionMinor;
const char* Language;
@@ -256,58 +234,28 @@ public:
const char* Output;
const char* Object;
const char* ObjectDir;
+ const char* ObjectFileDir;
const char* Flags;
const char* ObjectsQuoted;
const char* SONameFlag;
const char* TargetSOName;
const char* TargetInstallNameDir;
const char* LinkFlags;
+ const char* Manifests;
const char* LanguageCompileFlags;
const char* Defines;
+ const char* Includes;
const char* RuleLauncher;
const char* DependencyFile;
+ const char* FilterPrefix;
};
- /** Set whether to treat conversions to SHELL as a link script shell. */
- void SetLinkScriptShell(bool b) { this->LinkScriptShell = b; }
-
- /** Escape the given string to be used as a command line argument in
- the native build system shell. Optionally allow the build
- system to replace make variable references. Optionally adjust
- escapes for the special case of passing to the native echo
- command. */
- std::string EscapeForShell(const char* str, bool makeVars = false,
- bool forEcho = false);
-
- /** Backwards-compatibility version of EscapeForShell. */
- std::string EscapeForShellOldStyle(const char* str);
-
- /** Escape the given string as an argument in a CMake script. */
- static std::string EscapeForCMake(const char* str);
-
- enum FortranFormat
- {
- FortranFormatNone,
- FortranFormatFixed,
- FortranFormatFree
- };
- FortranFormat GetFortranFormat(const char* value);
-
- /**
- * Convert the given remote path to a relative path with respect to
- * the given local path. The local path must be given in component
- * form (see SystemTools::SplitPath) without a trailing slash. The
- * remote path must use forward slashes and not already be escaped
- * or quoted.
- */
- std::string ConvertToRelativePath(const std::vector<std::string>& local,
- const char* remote, bool force=false);
-
/**
* Get the relative path from the generator output directory to a
* per-target support directory.
*/
- virtual std::string GetTargetDirectory(cmTarget const& target) const;
+ virtual std::string
+ GetTargetDirectory(cmGeneratorTarget const* target) const;
/**
* Get the level of backwards compatibility requested by the project
@@ -319,29 +267,38 @@ public:
*
* and is monotonically increasing with the CMake version.
*/
- unsigned int GetBackwardsCompatibility();
+ KWIML_INT_uint64_t GetBackwardsCompatibility();
/**
* Test whether compatibility is set to a given version or lower.
*/
- bool NeedBackwardsCompatibility(unsigned int major,
- unsigned int minor,
- unsigned int patch = 0xFFu);
+ bool NeedBackwardsCompatibility_2_4();
+
+ cmPolicies::PolicyStatus GetPolicyStatus(cmPolicies::PolicyID id) const;
+
+ cmake* GetCMakeInstance() const;
+
+ const char* GetSourceDirectory() const;
+ const char* GetBinaryDirectory() const;
+
+ const char* GetCurrentBinaryDirectory() const;
+ const char* GetCurrentSourceDirectory() const;
/**
* Generate a Mac OS X application bundle Info.plist file.
*/
- void GenerateAppleInfoPList(cmTarget* target, const char* targetName,
+ void GenerateAppleInfoPList(cmGeneratorTarget* target,
+ const std::string& targetName,
const char* fname);
/**
* Generate a Mac OS X framework Info.plist file.
*/
- void GenerateFrameworkInfoPList(cmTarget* target,
- const char* targetName,
+ void GenerateFrameworkInfoPList(cmGeneratorTarget* target,
+ const std::string& targetName,
const char* fname);
/** Construct a comment for a custom command. */
- std::string ConstructComment(const cmCustomCommand& cc,
+ std::string ConstructComment(cmCustomCommandGenerator const& ccg,
const char* default_comment = "");
// Compute object file names.
std::string GetObjectFileNameWithoutTarget(const cmSourceFile& source,
@@ -351,7 +308,7 @@ public:
/** Fill out the static linker flags for the given target. */
void GetStaticLibraryFlags(std::string& flags,
std::string const& config,
- cmTarget* target);
+ cmGeneratorTarget* target);
/** Fill out these strings for the given target. Libraries to link,
* flags, and linkflags. */
@@ -360,15 +317,32 @@ public:
std::string& linkFlags,
std::string& frameworkPath,
std::string& linkPath,
- cmGeneratorTarget* target);
+ cmGeneratorTarget* target,
+ bool useWatcomQuote);
+
+ virtual void ComputeObjectFilenames(
+ std::map<cmSourceFile const*, std::string>& mapping,
+ cmGeneratorTarget const* gt = 0);
+
+ bool IsWindowsShell() const;
+ bool IsWatcomWMake() const;
+ bool IsMinGWMake() const;
+ bool IsNMake() const;
+
+ void IssueMessage(cmake::MessageType t, std::string const& text) const;
+
+ void CreateEvaluationFileOutputs(const std::string& config);
+ void ProcessEvaluationFiles(std::vector<std::string>& generatedFiles);
protected:
///! put all the libraries for a target on into the given stream
- virtual void OutputLinkLibraries(std::string& linkLibraries,
+ void OutputLinkLibraries(std::string& linkLibraries,
std::string& frameworkPath,
std::string& linkPath,
cmGeneratorTarget &,
- bool relink);
+ bool relink,
+ bool forResponseFile,
+ bool useWatcomQuote);
// Expand rule variables in CMake of the type found in language rules
void ExpandRuleVariables(std::string& string,
@@ -377,99 +351,55 @@ protected:
std::string ExpandRuleVariable(std::string const& variable,
const RuleVariables& replaceValues);
- const char* GetRuleLauncher(cmTarget* target, const char* prop);
- void InsertRuleLauncher(std::string& s, cmTarget* target,
- const char* prop);
-
-
- /** Convert a target to a utility target for unsupported
- * languages of a generator */
- void AddBuildTargetRule(const char* llang, cmGeneratorTarget& target);
- ///! add a custom command to build a .o file that is part of a target
- void AddCustomCommandToCreateObject(const char* ofname,
- const char* lang,
- cmSourceFile& source,
- cmGeneratorTarget& target);
- // Create Custom Targets and commands for unsupported languages
- // The set passed in should contain the languages supported by the
- // generator directly. Any targets containing files that are not
- // of the types listed will be compiled as custom commands and added
- // to a custom target.
- void CreateCustomTargetsAndCommands(std::set<cmStdString> const&);
+ const char* GetRuleLauncher(cmGeneratorTarget* target,
+ const std::string& prop);
+ void InsertRuleLauncher(std::string& s, cmGeneratorTarget* target,
+ const std::string& prop);
// Handle old-style install rules stored in the targets.
void GenerateTargetInstallRules(
- std::ostream& os, const char* config,
+ std::ostream& os, const std::string& config,
std::vector<std::string> const& configurationTypes);
- std::string& CreateSafeUniqueObjectFileName(const char* sin,
+ std::string& CreateSafeUniqueObjectFileName(const std::string& sin,
std::string const& dir_max);
- void ComputeObjectMaxPath();
-
- void ConfigureRelativePaths();
- std::string FindRelativePathTopSource();
- std::string FindRelativePathTopBinary();
- void SetupPathConversions();
- virtual std::string ConvertToLinkReference(std::string const& lib);
+ virtual std::string ConvertToLinkReference(std::string const& lib,
+ OutputFormat format = SHELL);
/** Check whether the native build system supports the given
definition. Issues a warning. */
virtual bool CheckDefinition(std::string const& define) const;
- /** Read the input CMakeLists.txt file. */
- void ReadInputFile();
-
cmMakefile *Makefile;
+ cmState::Snapshot StateSnapshot;
cmGlobalGenerator *GlobalGenerator;
- // members used for relative path function ConvertToMakefilePath
- std::string RelativePathToSourceDir;
- std::string RelativePathToBinaryDir;
- std::vector<std::string> HomeDirectoryComponents;
- std::vector<std::string> StartDirectoryComponents;
- std::vector<std::string> HomeOutputDirectoryComponents;
- std::vector<std::string> StartOutputDirectoryComponents;
- cmLocalGenerator* Parent;
- std::vector<cmLocalGenerator*> Children;
- std::map<cmStdString, cmStdString> UniqueObjectNamesMap;
+ std::map<std::string, std::string> UniqueObjectNamesMap;
std::string::size_type ObjectPathMax;
- std::set<cmStdString> ObjectMaxPathViolations;
- bool WindowsShell;
- bool WindowsVSIDE;
- bool WatcomWMake;
- bool MinGWMake;
- bool NMake;
- bool ForceUnixPath;
- bool MSYSShell;
- bool LinkScriptShell;
- bool UseRelativePaths;
- bool IgnoreLibPrefix;
- bool Configured;
+ std::set<std::string> ObjectMaxPathViolations;
+
+ std::set<cmGeneratorTarget const*> WarnCMP0063;
+ std::vector<cmGeneratorTarget*> GeneratorTargets;
+ std::vector<cmGeneratorTarget*> ImportedGeneratorTargets;
+ std::vector<cmGeneratorTarget*> OwnedImportedGeneratorTargets;
+ std::map<std::string, std::string> AliasTargets;
+
bool EmitUniversalBinaryFlags;
+
// Hack for ExpandRuleVariable until object-oriented version is
// committed.
std::string TargetImplib;
- // The top-most directories for relative path conversion. Both the
- // source and destination location of a relative path conversion
- // must be underneath one of these directories (both under source or
- // both under binary) in order for the relative path to be evaluated
- // safely by the build tools.
- std::string RelativePathTopSource;
- std::string RelativePathTopBinary;
- bool RelativePathsConfigured;
- bool PathConversionsSetup;
-
- unsigned int BackwardsCompatibility;
+ KWIML_INT_uint64_t BackwardsCompatibility;
bool BackwardsCompatibilityFinal;
private:
- std::string ConvertToOutputForExistingCommon(const char* remote,
- std::string const& result);
-
- void AddSharedFlags(std::string& flags, const char* lang, bool shared);
+ void AddSharedFlags(std::string& flags, const std::string& lang,
+ bool shared);
bool GetShouldUseOldFlags(bool shared, const std::string &lang) const;
void AddPositionIndependentFlags(std::string& flags, std::string const& l,
int targetType);
+
+ void ComputeObjectMaxPath();
};
#endif
diff --git a/Source/cmLocalGhsMultiGenerator.cxx b/Source/cmLocalGhsMultiGenerator.cxx
new file mode 100644
index 000000000..a77a75e02
--- /dev/null
+++ b/Source/cmLocalGhsMultiGenerator.cxx
@@ -0,0 +1,41 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Geoffrey Viola <geoffrey.viola@asirobots.com>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmLocalGhsMultiGenerator.h"
+#include "cmGlobalGhsMultiGenerator.h"
+#include "cmGeneratorTarget.h"
+#include "cmMakefile.h"
+#include "cmGhsMultiTargetGenerator.h"
+#include "cmGeneratedFileStream.h"
+
+cmLocalGhsMultiGenerator::cmLocalGhsMultiGenerator(cmGlobalGenerator* gg,
+ cmMakefile* mf)
+ : cmLocalGenerator(gg, mf)
+{
+}
+
+cmLocalGhsMultiGenerator::~cmLocalGhsMultiGenerator() {}
+
+void cmLocalGhsMultiGenerator::Generate()
+{
+ std::vector<cmGeneratorTarget*> tgts = this->GetGeneratorTargets();
+
+ for (std::vector<cmGeneratorTarget*>::iterator l = tgts.begin();
+ l != tgts.end(); ++l)
+ {
+ if ((*l)->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ continue;
+ }
+ cmGhsMultiTargetGenerator tg(*l);
+ tg.Generate();
+ }
+}
diff --git a/Source/cmLocalGhsMultiGenerator.h b/Source/cmLocalGhsMultiGenerator.h
new file mode 100644
index 000000000..b6a9a33f7
--- /dev/null
+++ b/Source/cmLocalGhsMultiGenerator.h
@@ -0,0 +1,38 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Geoffrey Viola <geoffrey.viola@asirobots.com>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmLocalGhsMultiGenerator_h
+#define cmLocalGhsMultiGenerator_h
+
+#include "cmLocalGenerator.h"
+
+class cmGeneratedFileStream;
+
+/** \class cmLocalGhsMultiGenerator
+ * \brief Write Green Hills MULTI project files.
+ *
+ * cmLocalGhsMultiGenerator produces a set of .gpj
+ * file for each target in its mirrored directory.
+ */
+class cmLocalGhsMultiGenerator : public cmLocalGenerator
+{
+public:
+ cmLocalGhsMultiGenerator(cmGlobalGenerator* gg, cmMakefile* mf);
+
+ virtual ~cmLocalGhsMultiGenerator();
+
+ /**
+ * Generate the makefile for this directory.
+ */
+ virtual void Generate();
+};
+
+#endif
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index a522e37e2..b2927a96e 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -17,19 +17,16 @@
#include "cmNinjaTargetGenerator.h"
#include "cmGeneratedFileStream.h"
#include "cmSourceFile.h"
-#include "cmComputeLinkInformation.h"
#include "cmake.h"
+#include "cmState.h"
#include <assert.h>
-cmLocalNinjaGenerator::cmLocalNinjaGenerator()
- : cmLocalGenerator()
- , ConfigName("")
+cmLocalNinjaGenerator::cmLocalNinjaGenerator(cmGlobalGenerator* gg,
+ cmMakefile* mf)
+ : cmLocalCommonGenerator(gg, mf)
, HomeRelativeOutputPath("")
{
-#ifdef _WIN32
- this->WindowsShell = true;
-#endif
this->TargetImplib = "$TARGET_IMPLIB";
}
@@ -42,6 +39,15 @@ cmLocalNinjaGenerator::~cmLocalNinjaGenerator()
void cmLocalNinjaGenerator::Generate()
{
+ // Compute the path to use when referencing the current output
+ // directory from the top output directory.
+ this->HomeRelativeOutputPath =
+ this->Convert(this->GetCurrentBinaryDirectory(), HOME_OUTPUT);
+ if(this->HomeRelativeOutputPath == ".")
+ {
+ this->HomeRelativeOutputPath = "";
+ }
+
this->SetConfigName();
this->WriteProcessedMakefile(this->GetBuildFileStream());
@@ -49,20 +55,41 @@ void cmLocalNinjaGenerator::Generate()
this->WriteProcessedMakefile(this->GetRulesFileStream());
#endif
- this->WriteBuildFileTop();
+ // We do that only once for the top CMakeLists.txt file.
+ if(this->IsRootMakefile())
+ {
+ this->WriteBuildFileTop();
+
+ this->WritePools(this->GetRulesFileStream());
- cmTargets& targets = this->GetMakefile()->GetTargets();
- for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
+ const std::string showIncludesPrefix = this->GetMakefile()
+ ->GetSafeDefinition("CMAKE_CL_SHOWINCLUDES_PREFIX");
+ if (!showIncludesPrefix.empty())
+ {
+ cmGlobalNinjaGenerator::WriteComment(this->GetRulesFileStream(),
+ "localized /showIncludes string");
+ this->GetRulesFileStream()
+ << "msvc_deps_prefix = " << showIncludesPrefix << "\n\n";
+ }
+ }
+
+ std::vector<cmGeneratorTarget*> targets = this->GetGeneratorTargets();
+ for(std::vector<cmGeneratorTarget*>::iterator t = targets.begin();
+ t != targets.end(); ++t)
{
- cmNinjaTargetGenerator* tg = cmNinjaTargetGenerator::New(&t->second);
+ if ((*t)->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ continue;
+ }
+ cmNinjaTargetGenerator* tg = cmNinjaTargetGenerator::New(*t);
if(tg)
{
tg->Generate();
// Add the target to "all" if required.
if (!this->GetGlobalNinjaGenerator()->IsExcluded(
this->GetGlobalNinjaGenerator()->GetLocalGenerators()[0],
- t->second))
- this->GetGlobalNinjaGenerator()->AddDependencyToAll(&t->second);
+ *t))
+ this->GetGlobalNinjaGenerator()->AddDependencyToAll(*t);
delete tg;
}
}
@@ -70,31 +97,12 @@ void cmLocalNinjaGenerator::Generate()
this->WriteCustomCommandBuildStatements();
}
-// Implemented in:
-// cmLocalUnixMakefileGenerator3.
-// Used in:
-// Source/cmMakefile.cxx
-// Source/cmGlobalGenerator.cxx
-void cmLocalNinjaGenerator::Configure()
-{
- // Compute the path to use when referencing the current output
- // directory from the top output directory.
- this->HomeRelativeOutputPath =
- this->Convert(this->Makefile->GetStartOutputDirectory(), HOME_OUTPUT);
- if(this->HomeRelativeOutputPath == ".")
- {
- this->HomeRelativeOutputPath = "";
- }
- this->cmLocalGenerator::Configure();
-
-}
-
// TODO: Picked up from cmLocalUnixMakefileGenerator3. Refactor it.
std::string cmLocalNinjaGenerator
-::GetTargetDirectory(cmTarget const& target) const
+::GetTargetDirectory(cmGeneratorTarget const* target) const
{
std::string dir = cmake::GetCMakeFilesDirectoryPostSlash();
- dir += target.GetName();
+ dir += target->GetName();
#if defined(__VMS)
dir += "_dir";
#else
@@ -122,15 +130,18 @@ cmGlobalNinjaGenerator* cmLocalNinjaGenerator::GetGlobalNinjaGenerator()
// Virtual protected methods.
std::string
-cmLocalNinjaGenerator::ConvertToLinkReference(std::string const& lib)
+cmLocalNinjaGenerator::ConvertToLinkReference(std::string const& lib,
+ OutputFormat format)
{
- return this->Convert(lib.c_str(), HOME_OUTPUT, SHELL);
+ return this->Convert(lib, HOME_OUTPUT, format);
}
std::string
-cmLocalNinjaGenerator::ConvertToIncludeReference(std::string const& path)
+cmLocalNinjaGenerator::ConvertToIncludeReference(std::string const& path,
+ OutputFormat format,
+ bool forceFullPaths)
{
- return this->Convert(path.c_str(), HOME_OUTPUT, SHELL);
+ return this->Convert(path, forceFullPaths? FULL : HOME_OUTPUT, format);
}
//----------------------------------------------------------------------------
@@ -156,20 +167,11 @@ cmake* cmLocalNinjaGenerator::GetCMakeInstance()
return this->GetGlobalGenerator()->GetCMakeInstance();
}
-bool cmLocalNinjaGenerator::isRootMakefile() const
-{
- return (strcmp(this->Makefile->GetCurrentDirectory(),
- this->GetCMakeInstance()->GetHomeDirectory()) == 0);
-}
-
void cmLocalNinjaGenerator::WriteBuildFileTop()
{
- // We do that only once for the top CMakeLists.txt file.
- if(!this->isRootMakefile())
- return;
-
// For the build file.
this->WriteProjectHeader(this->GetBuildFileStream());
+ this->WriteNinjaRequiredVersion(this->GetBuildFileStream());
this->WriteNinjaFilesInclusion(this->GetBuildFileStream());
// For the rule file.
@@ -180,12 +182,67 @@ void cmLocalNinjaGenerator::WriteProjectHeader(std::ostream& os)
{
cmGlobalNinjaGenerator::WriteDivider(os);
os
- << "# Project: " << this->GetMakefile()->GetProjectName() << std::endl
+ << "# Project: " << this->GetProjectName() << std::endl
<< "# Configuration: " << this->ConfigName << std::endl
;
cmGlobalNinjaGenerator::WriteDivider(os);
}
+void cmLocalNinjaGenerator::WriteNinjaRequiredVersion(std::ostream& os)
+{
+ // Default required version
+ std::string requiredVersion =
+ this->GetGlobalNinjaGenerator()->RequiredNinjaVersion();
+
+ // Ninja generator uses the 'console' pool if available (>= 1.5)
+ if(this->GetGlobalNinjaGenerator()->SupportsConsolePool())
+ {
+ requiredVersion =
+ this->GetGlobalNinjaGenerator()->RequiredNinjaVersionForConsolePool();
+ }
+
+ cmGlobalNinjaGenerator::WriteComment(os,
+ "Minimal version of Ninja required by this file");
+ os
+ << "ninja_required_version = "
+ << requiredVersion
+ << std::endl << std::endl
+ ;
+}
+
+void cmLocalNinjaGenerator::WritePools(std::ostream& os)
+{
+ cmGlobalNinjaGenerator::WriteDivider(os);
+
+ const char* jobpools = this->GetCMakeInstance()->GetState()
+ ->GetGlobalProperty("JOB_POOLS");
+ if (jobpools)
+ {
+ cmGlobalNinjaGenerator::WriteComment(os,
+ "Pools defined by global property JOB_POOLS");
+ std::vector<std::string> pools;
+ cmSystemTools::ExpandListArgument(jobpools, pools);
+ for (size_t i = 0; i < pools.size(); ++i)
+ {
+ const std::string pool = pools[i];
+ const std::string::size_type eq = pool.find("=");
+ unsigned int jobs;
+ if (eq != std::string::npos &&
+ sscanf(pool.c_str() + eq, "=%u", &jobs) == 1)
+ {
+ os << "pool " << pool.substr(0, eq) << std::endl;
+ os << " depth = " << jobs << std::endl;
+ os << std::endl;
+ }
+ else
+ {
+ cmSystemTools::Error("Invalid pool defined by property 'JOB_POOLS': ",
+ pool.c_str());
+ }
+ }
+ }
+}
+
void cmLocalNinjaGenerator::WriteNinjaFilesInclusion(std::ostream& os)
{
cmGlobalNinjaGenerator::WriteDivider(os);
@@ -199,19 +256,17 @@ void cmLocalNinjaGenerator::WriteNinjaFilesInclusion(std::ostream& os)
os << "\n";
}
-void cmLocalNinjaGenerator::SetConfigName()
+//----------------------------------------------------------------------------
+void cmLocalNinjaGenerator::ComputeObjectFilenames(
+ std::map<cmSourceFile const*, std::string>& mapping,
+ cmGeneratorTarget const* gt)
{
- // Store the configuration name that will be generated.
- if(const char* config =
- this->GetMakefile()->GetDefinition("CMAKE_BUILD_TYPE"))
+ for(std::map<cmSourceFile const*, std::string>::iterator
+ si = mapping.begin(); si != mapping.end(); ++si)
{
- // Use the build type given by the user.
- this->ConfigName = config;
- }
- else
- {
- // No configuration type given.
- this->ConfigName = "";
+ cmSourceFile const* sf = si->first;
+ si->second = this->GetObjectFileNameWithoutTarget(*sf,
+ gt->ObjectDirectory);
}
}
@@ -220,46 +275,39 @@ void cmLocalNinjaGenerator::WriteProcessedMakefile(std::ostream& os)
cmGlobalNinjaGenerator::WriteDivider(os);
os
<< "# Write statements declared in CMakeLists.txt:" << std::endl
- << "# " << this->Makefile->GetCurrentListFile() << std::endl
- ;
- if(this->isRootMakefile())
+ << "# "
+ << this->Makefile->GetDefinition("CMAKE_CURRENT_LIST_FILE") << std::endl;
+ if(this->IsRootMakefile())
os << "# Which is the root file." << std::endl;
cmGlobalNinjaGenerator::WriteDivider(os);
os << std::endl;
}
-std::string cmLocalNinjaGenerator::ConvertToNinjaPath(const char *path)
-{
- std::string convPath = this->Convert(path, cmLocalGenerator::HOME_OUTPUT);
-#ifdef _WIN32
- cmSystemTools::ReplaceString(convPath, "/", "\\");
-#endif
- return convPath;
-}
-
void
cmLocalNinjaGenerator
-::AppendTargetOutputs(cmTarget* target, cmNinjaDeps& outputs)
+::AppendTargetOutputs(cmGeneratorTarget* target, cmNinjaDeps& outputs)
{
this->GetGlobalNinjaGenerator()->AppendTargetOutputs(target, outputs);
}
void
cmLocalNinjaGenerator
-::AppendTargetDepends(cmTarget* target, cmNinjaDeps& outputs)
+::AppendTargetDepends(cmGeneratorTarget* target, cmNinjaDeps& outputs)
{
this->GetGlobalNinjaGenerator()->AppendTargetDepends(target, outputs);
}
-void cmLocalNinjaGenerator::AppendCustomCommandDeps(const cmCustomCommand *cc,
- cmNinjaDeps &ninjaDeps)
+void cmLocalNinjaGenerator::AppendCustomCommandDeps(
+ cmCustomCommandGenerator const& ccg,
+ cmNinjaDeps &ninjaDeps)
{
- const std::vector<std::string> &deps = cc->GetDepends();
+ const std::vector<std::string> &deps = ccg.GetDepends();
for (std::vector<std::string>::const_iterator i = deps.begin();
i != deps.end(); ++i) {
std::string dep;
- if (this->GetRealDependency(i->c_str(), this->GetConfigName(), dep))
- ninjaDeps.push_back(ConvertToNinjaPath(dep.c_str()));
+ if (this->GetRealDependency(*i, this->GetConfigName(), dep))
+ ninjaDeps.push_back(
+ this->GetGlobalNinjaGenerator()->ConvertToNinjaPath(dep));
}
}
@@ -276,31 +324,47 @@ std::string cmLocalNinjaGenerator::BuildCommandLine(
return ":";
#endif
- cmOStringStream cmd;
+ std::ostringstream cmd;
for (std::vector<std::string>::const_iterator li = cmdLines.begin();
- li != cmdLines.end(); ++li) {
- if (li != cmdLines.begin()) {
- cmd << " && ";
+ li != cmdLines.end(); ++li)
#ifdef _WIN32
- } else if (cmdLines.size() > 1) {
- cmd << "cmd.exe /c ";
-#endif
+ {
+ if (li != cmdLines.begin())
+ {
+ cmd << " && ";
+ }
+ else if (cmdLines.size() > 1)
+ {
+ cmd << "cmd.exe /C \"";
+ }
+ cmd << *li;
+ }
+ if (cmdLines.size() > 1)
+ {
+ cmd << "\"";
}
+#else
+ {
+ if (li != cmdLines.begin())
+ {
+ cmd << " && ";
+ }
cmd << *li;
- }
+ }
+#endif
return cmd.str();
}
-void cmLocalNinjaGenerator::AppendCustomCommandLines(const cmCustomCommand *cc,
- std::vector<std::string> &cmdLines)
+void cmLocalNinjaGenerator::AppendCustomCommandLines(
+ cmCustomCommandGenerator const& ccg,
+ std::vector<std::string> &cmdLines)
{
- cmCustomCommandGenerator ccg(*cc, this->GetConfigName(), this->Makefile);
if (ccg.GetNumberOfCommands() > 0) {
- const char* wd = cc->GetWorkingDirectory();
- if (!wd)
- wd = this->GetMakefile()->GetStartOutputDirectory();
+ std::string wd = ccg.GetWorkingDirectory();
+ if (wd.empty())
+ wd = this->GetCurrentBinaryDirectory();
- cmOStringStream cdCmd;
+ std::ostringstream cdCmd;
#ifdef _WIN32
std::string cdStr = "cd /D ";
#else
@@ -309,9 +373,13 @@ void cmLocalNinjaGenerator::AppendCustomCommandLines(const cmCustomCommand *cc,
cdCmd << cdStr << this->ConvertToOutputFormat(wd, SHELL);
cmdLines.push_back(cdCmd.str());
}
+
+ std::string launcher = this->MakeCustomLauncher(ccg);
+
for (unsigned i = 0; i != ccg.GetNumberOfCommands(); ++i) {
- cmdLines.push_back(this->ConvertToOutputFormat(ccg.GetCommand(i).c_str(),
- SHELL));
+ cmdLines.push_back(launcher +
+ this->ConvertToOutputFormat(ccg.GetCommand(i), SHELL));
+
std::string& cmd = cmdLines.back();
ccg.AppendArguments(i, cmd);
}
@@ -324,19 +392,41 @@ cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
if (this->GetGlobalNinjaGenerator()->SeenCustomCommand(cc))
return;
- const std::vector<std::string> &outputs = cc->GetOutputs();
- cmNinjaDeps ninjaOutputs(outputs.size()), ninjaDeps;
+ cmCustomCommandGenerator ccg(*cc, this->GetConfigName(), this);
+
+ const std::vector<std::string> &outputs = ccg.GetOutputs();
+ const std::vector<std::string> &byproducts = ccg.GetByproducts();
+ cmNinjaDeps ninjaOutputs(outputs.size()+byproducts.size()), ninjaDeps;
+ bool symbolic = false;
+ for (std::vector<std::string>::const_iterator o = outputs.begin();
+ o != outputs.end(); ++o)
+ {
+ if (cmSourceFile* sf = this->Makefile->GetSource(*o))
+ {
+ symbolic = sf->GetPropertyAsBool("SYMBOLIC");
+ }
+ }
+
+#if 0
+#error TODO: Once CC in an ExternalProject target must provide the \
+ file of each imported target that has an add_dependencies pointing \
+ at us. How to know which ExternalProject step actually provides it?
+#endif
std::transform(outputs.begin(), outputs.end(),
- ninjaOutputs.begin(), MapToNinjaPath());
- this->AppendCustomCommandDeps(cc, ninjaDeps);
+ ninjaOutputs.begin(),
+ this->GetGlobalNinjaGenerator()->MapToNinjaPath());
+ std::transform(byproducts.begin(), byproducts.end(),
+ ninjaOutputs.begin() + outputs.size(),
+ this->GetGlobalNinjaGenerator()->MapToNinjaPath());
+ this->AppendCustomCommandDeps(ccg, ninjaDeps);
for (cmNinjaDeps::iterator i = ninjaOutputs.begin(); i != ninjaOutputs.end();
++i)
this->GetGlobalNinjaGenerator()->SeenCustomCommandOutput(*i);
std::vector<std::string> cmdLines;
- this->AppendCustomCommandLines(cc, cmdLines);
+ this->AppendCustomCommandLines(ccg, cmdLines);
if (cmdLines.empty()) {
this->GetGlobalNinjaGenerator()->WritePhonyBuild(
@@ -351,8 +441,10 @@ cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
} else {
this->GetGlobalNinjaGenerator()->WriteCustomCommandBuild(
this->BuildCommandLine(cmdLines),
- this->ConstructComment(*cc),
+ this->ConstructComment(ccg),
"Custom command for " + ninjaOutputs[0],
+ cc->GetUsesTerminal(),
+ /*restat*/!symbolic,
ninjaOutputs,
ninjaDeps,
orderOnlyDeps);
@@ -360,7 +452,7 @@ cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
}
void cmLocalNinjaGenerator::AddCustomCommandTarget(cmCustomCommand const* cc,
- cmTarget* target)
+ cmGeneratorTarget* target)
{
this->CustomCommandTargets[cc].insert(target);
}
@@ -378,7 +470,7 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements()
//
// FIXME: This won't work in certain obscure scenarios involving indirect
// dependencies.
- std::set<cmTarget*>::iterator j = i->second.begin();
+ std::set<cmGeneratorTarget*>::iterator j = i->second.begin();
assert(j != i->second.end());
std::vector<std::string> ccTargetDeps;
this->AppendTargetDepends(*j, ccTargetDeps);
@@ -398,3 +490,39 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements()
this->WriteCustomCommandBuildStatement(i->first, ccTargetDeps);
}
}
+
+std::string cmLocalNinjaGenerator::MakeCustomLauncher(
+ cmCustomCommandGenerator const& ccg)
+{
+ const char* property = "RULE_LAUNCH_CUSTOM";
+ const char* property_value = this->Makefile->GetProperty(property);
+
+ if(!property_value || !*property_value)
+ {
+ return std::string();
+ }
+
+ // Expand rules in the empty string. It may insert the launcher and
+ // perform replacements.
+ RuleVariables vars;
+ vars.RuleLauncher = property;
+ std::string output;
+ const std::vector<std::string>& outputs = ccg.GetOutputs();
+ if(!outputs.empty())
+ {
+ RelativeRoot relative_root =
+ ccg.GetWorkingDirectory().empty() ? START_OUTPUT : NONE;
+
+ output = this->Convert(outputs[0], relative_root, SHELL);
+ }
+ vars.Output = output.c_str();
+
+ std::string launcher;
+ this->ExpandRuleVariables(launcher, vars);
+ if(!launcher.empty())
+ {
+ launcher += " ";
+ }
+
+ return launcher;
+}
diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h
index c450841af..b6987efc4 100644
--- a/Source/cmLocalNinjaGenerator.h
+++ b/Source/cmLocalNinjaGenerator.h
@@ -13,9 +13,10 @@
#ifndef cmLocalNinjaGenerator_h
# define cmLocalNinjaGenerator_h
-# include "cmLocalGenerator.h"
+# include "cmLocalCommonGenerator.h"
# include "cmNinjaTypes.h"
+class cmCustomCommandGenerator;
class cmGlobalNinjaGenerator;
class cmGeneratedFileStream;
class cmake;
@@ -27,60 +28,29 @@ class cmake;
* cmLocalNinjaGenerator produces a local build.ninja file from its
* member Makefile.
*/
-class cmLocalNinjaGenerator : public cmLocalGenerator
+class cmLocalNinjaGenerator : public cmLocalCommonGenerator
{
public:
- /// Default constructor.
- cmLocalNinjaGenerator();
+ cmLocalNinjaGenerator(cmGlobalGenerator* gg, cmMakefile* mf);
- /// Destructor.
virtual ~cmLocalNinjaGenerator();
- /// Overloaded methods. @see cmLocalGenerator::Generate()
virtual void Generate();
- /// Overloaded methods. @see cmLocalGenerator::Configure()
- virtual void Configure();
-
- /// Overloaded methods. @see cmLocalGenerator::GetTargetDirectory()
- virtual std::string GetTargetDirectory(cmTarget const& target) const;
+ virtual
+ std::string GetTargetDirectory(cmGeneratorTarget const* target) const;
const cmGlobalNinjaGenerator* GetGlobalNinjaGenerator() const;
cmGlobalNinjaGenerator* GetGlobalNinjaGenerator();
- /**
- * Shortcut to get the cmake instance throw the global generator.
- * @return an instance of the cmake object.
- */
const cmake* GetCMakeInstance() const;
cmake* GetCMakeInstance();
- const char* GetConfigName() const
- { return this->ConfigName.c_str(); }
-
- /// @return whether we are processing the top CMakeLists.txt file.
- bool isRootMakefile() const;
-
/// @returns the relative path between the HomeOutputDirectory and this
/// local generators StartOutputDirectory.
std::string GetHomeRelativeOutputPath() const
{ return this->HomeRelativeOutputPath; }
- std::string ConvertToNinjaPath(const char *path);
-
- struct map_to_ninja_path {
- cmLocalNinjaGenerator *LocalGenerator;
- map_to_ninja_path(cmLocalNinjaGenerator *LocalGen)
- : LocalGenerator(LocalGen) {}
- std::string operator()(const std::string &path) {
- return LocalGenerator->ConvertToNinjaPath(path.c_str());
- }
- };
-
- map_to_ninja_path MapToNinjaPath() {
- return map_to_ninja_path(this);
- }
-
void ExpandRuleVariables(std::string& string,
const RuleVariables& replaceValues) {
cmLocalGenerator::ExpandRuleVariables(string, replaceValues);
@@ -88,20 +58,28 @@ public:
std::string BuildCommandLine(const std::vector<std::string> &cmdLines);
- void AppendTargetOutputs(cmTarget* target, cmNinjaDeps& outputs);
- void AppendTargetDepends(cmTarget* target, cmNinjaDeps& outputs);
+ void AppendTargetOutputs(cmGeneratorTarget* target, cmNinjaDeps& outputs);
+ void AppendTargetDepends(cmGeneratorTarget* target, cmNinjaDeps& outputs);
- void AddCustomCommandTarget(cmCustomCommand const* cc, cmTarget* target);
- void AppendCustomCommandLines(const cmCustomCommand *cc,
+ void AddCustomCommandTarget(cmCustomCommand const* cc,
+ cmGeneratorTarget* target);
+ void AppendCustomCommandLines(cmCustomCommandGenerator const& ccg,
std::vector<std::string> &cmdLines);
- void AppendCustomCommandDeps(const cmCustomCommand *cc,
+ void AppendCustomCommandDeps(cmCustomCommandGenerator const& ccg,
cmNinjaDeps &ninjaDeps);
- virtual std::string ConvertToLinkReference(std::string const& lib);
+ virtual std::string ConvertToLinkReference(std::string const& lib,
+ OutputFormat format = SHELL);
+
+ virtual void ComputeObjectFilenames(
+ std::map<cmSourceFile const*, std::string>& mapping,
+ cmGeneratorTarget const* gt = 0);
protected:
- virtual std::string ConvertToIncludeReference(std::string const& path);
+ virtual std::string ConvertToIncludeReference(std::string const& path,
+ OutputFormat format = SHELL,
+ bool forceFullPaths = false);
private:
@@ -110,10 +88,10 @@ private:
void WriteBuildFileTop();
void WriteProjectHeader(std::ostream& os);
+ void WriteNinjaRequiredVersion(std::ostream& os);
void WriteNinjaFilesInclusion(std::ostream& os);
void WriteProcessedMakefile(std::ostream& os);
-
- void SetConfigName();
+ void WritePools(std::ostream& os);
void WriteCustomCommandRule();
void WriteCustomCommandBuildStatement(cmCustomCommand const *cc,
@@ -121,11 +99,11 @@ private:
void WriteCustomCommandBuildStatements();
+ std::string MakeCustomLauncher(cmCustomCommandGenerator const& ccg);
- std::string ConfigName;
std::string HomeRelativeOutputPath;
- typedef std::map<cmCustomCommand const*, std::set<cmTarget*> >
+ typedef std::map<cmCustomCommand const*, std::set<cmGeneratorTarget*> >
CustomCommandTargetMap;
CustomCommandTargetMap CustomCommandTargets;
};
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 56da1f936..62fea3d84 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -20,6 +20,7 @@
#include "cmVersion.h"
#include "cmFileTimeComparison.h"
#include "cmCustomCommandGenerator.h"
+#include "cmAlgorithms.h"
// Include dependency scanners for supported languages. Only the
// C/C++ scanner is needed for bootstrapping CMake.
@@ -27,10 +28,10 @@
#ifdef CMAKE_BUILD_WITH_CMAKE
# include "cmDependsFortran.h"
# include "cmDependsJava.h"
-# include <cmsys/Terminal.h>
#endif
#include <cmsys/auto_ptr.hxx>
+#include <cmsys/Terminal.h>
#include <queue>
@@ -78,16 +79,11 @@ static std::string cmSplitExtension(std::string const& in, std::string& base)
}
//----------------------------------------------------------------------------
-cmLocalUnixMakefileGenerator3::cmLocalUnixMakefileGenerator3()
+cmLocalUnixMakefileGenerator3::
+cmLocalUnixMakefileGenerator3(cmGlobalGenerator* gg, cmMakefile* mf)
+ : cmLocalCommonGenerator(gg, mf)
{
- this->SilentNoColon = false;
- this->WindowsShell = false;
- this->IncludeDirective = "include";
this->MakefileVariableSize = 0;
- this->IgnoreLibPrefix = false;
- this->PassMakeflags = false;
- this->DefineWindowsNULL = false;
- this->UnixCD = true;
this->ColorMakefile = false;
this->SkipPreprocessedSourceRules = false;
this->SkipAssemblySourceRules = false;
@@ -101,37 +97,9 @@ cmLocalUnixMakefileGenerator3::~cmLocalUnixMakefileGenerator3()
}
//----------------------------------------------------------------------------
-void cmLocalUnixMakefileGenerator3::Configure()
-{
- // Compute the path to use when referencing the current output
- // directory from the top output directory.
- this->HomeRelativeOutputPath =
- this->Convert(this->Makefile->GetStartOutputDirectory(), HOME_OUTPUT);
- if(this->HomeRelativeOutputPath == ".")
- {
- this->HomeRelativeOutputPath = "";
- }
- if(!this->HomeRelativeOutputPath.empty())
- {
- this->HomeRelativeOutputPath += "/";
- }
- this->cmLocalGenerator::Configure();
-}
-
-//----------------------------------------------------------------------------
void cmLocalUnixMakefileGenerator3::Generate()
{
- // Store the configuration name that will be generated.
- if(const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"))
- {
- // Use the build type given by the user.
- this->ConfigurationName = config;
- }
- else
- {
- // No configuration type given.
- this->ConfigurationName = "";
- }
+ this->SetConfigName();
// Record whether some options are enabled to avoid checking many
// times later.
@@ -145,13 +113,18 @@ void cmLocalUnixMakefileGenerator3::Generate()
this->Makefile->IsOn("CMAKE_SKIP_ASSEMBLY_SOURCE_RULES");
// Generate the rule files for each target.
- cmTargets& targets = this->Makefile->GetTargets();
+ std::vector<cmGeneratorTarget*> targets = this->GetGeneratorTargets();
cmGlobalUnixMakefileGenerator3* gg =
static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
- for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
+ for(std::vector<cmGeneratorTarget*>::iterator t = targets.begin();
+ t != targets.end(); ++t)
{
+ if ((*t)->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ continue;
+ }
cmsys::auto_ptr<cmMakefileTargetGenerator> tg(
- cmMakefileTargetGenerator::New(&(t->second)));
+ cmMakefileTargetGenerator::New(*t));
if (tg.get())
{
tg->WriteRuleFiles();
@@ -166,27 +139,88 @@ void cmLocalUnixMakefileGenerator3::Generate()
this->WriteDirectoryInformationFile();
}
+void cmLocalUnixMakefileGenerator3::ComputeHomeRelativeOutputPath()
+{
+ // Compute the path to use when referencing the current output
+ // directory from the top output directory.
+ this->HomeRelativeOutputPath =
+ this->Convert(this->GetCurrentBinaryDirectory(), HOME_OUTPUT);
+ if(this->HomeRelativeOutputPath == ".")
+ {
+ this->HomeRelativeOutputPath = "";
+ }
+ if(!this->HomeRelativeOutputPath.empty())
+ {
+ this->HomeRelativeOutputPath += "/";
+ }
+}
+
//----------------------------------------------------------------------------
-void cmLocalUnixMakefileGenerator3::AddLocalObjectFile(
- cmTarget* target, cmSourceFile* sf, std::string objNoTargetDir,
- bool hasSourceExtension)
+void cmLocalUnixMakefileGenerator3::ComputeObjectFilenames(
+ std::map<cmSourceFile const*, std::string>& mapping,
+ cmGeneratorTarget const* gt)
{
- if(cmSystemTools::FileIsFullPath(objNoTargetDir.c_str()))
+ for(std::map<cmSourceFile const*, std::string>::iterator
+ si = mapping.begin(); si != mapping.end(); ++si)
{
- objNoTargetDir = cmSystemTools::GetFilenameName(objNoTargetDir);
+ cmSourceFile const* sf = si->first;
+ si->second = this->GetObjectFileNameWithoutTarget(*sf,
+ gt->ObjectDirectory);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmLocalUnixMakefileGenerator3::
+GetLocalObjectFiles(std::map<std::string, LocalObjectInfo> &localObjectFiles)
+{
+ std::vector<cmGeneratorTarget*> targets = this->GetGeneratorTargets();
+ for(std::vector<cmGeneratorTarget*>::iterator ti = targets.begin();
+ ti != targets.end(); ++ti)
+ {
+ cmGeneratorTarget* gt = *ti;
+ if (gt->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ continue;
+ }
+ std::vector<cmSourceFile const*> objectSources;
+ gt->GetObjectSources(objectSources, this->Makefile
+ ->GetSafeDefinition("CMAKE_BUILD_TYPE"));
+ // Compute full path to object file directory for this target.
+ std::string dir;
+ dir += gt->LocalGenerator->GetCurrentBinaryDirectory();
+ dir += "/";
+ dir += this->GetTargetDirectory(gt);
+ dir += "/";
+ // Compute the name of each object file.
+ for(std::vector<cmSourceFile const*>::iterator
+ si = objectSources.begin();
+ si != objectSources.end(); ++si)
+ {
+ cmSourceFile const* sf = *si;
+ bool hasSourceExtension = true;
+ std::string objectName = this->GetObjectFileNameWithoutTarget(*sf,
+ dir,
+ &hasSourceExtension);
+ if(cmSystemTools::FileIsFullPath(objectName.c_str()))
+ {
+ objectName = cmSystemTools::GetFilenameName(objectName);
+ }
+ LocalObjectInfo& info = localObjectFiles[objectName];
+ info.HasSourceExtension = hasSourceExtension;
+ info.push_back(LocalObjectEntry(gt, sf->GetLanguage()));
+ }
}
- LocalObjectInfo& info = this->LocalObjectFiles[objNoTargetDir];
- info.HasSourceExtension = hasSourceExtension;
- info.push_back(LocalObjectEntry(target, sf->GetLanguage()));
}
//----------------------------------------------------------------------------
void cmLocalUnixMakefileGenerator3::GetIndividualFileTargets
(std::vector<std::string>& targets)
{
- for (std::map<cmStdString, LocalObjectInfo>::iterator lo =
- this->LocalObjectFiles.begin();
- lo != this->LocalObjectFiles.end(); ++lo)
+ std::map<std::string, LocalObjectInfo> localObjectFiles;
+ this->GetLocalObjectFiles(localObjectFiles);
+ for (std::map<std::string, LocalObjectInfo>::iterator lo =
+ localObjectFiles.begin();
+ lo != localObjectFiles.end(); ++lo)
{
targets.push_back(lo->first);
@@ -219,7 +253,7 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
return;
}
// always write the top makefile
- if (this->Parent)
+ if (!this->IsRootMakefile())
{
ruleFileStream.SetCopyIfDifferent(true);
}
@@ -229,8 +263,8 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
// only write local targets unless at the top Keep track of targets already
// listed.
- std::set<cmStdString> emittedTargets;
- if (this->Parent)
+ std::set<std::string> emittedTargets;
+ if (!this->IsRootMakefile())
{
// write our targets, and while doing it collect up the object
// file rules
@@ -248,11 +282,14 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
bool do_assembly_rules =
this->GetCreateAssemblySourceRules();
+ std::map<std::string, LocalObjectInfo> localObjectFiles;
+ this->GetLocalObjectFiles(localObjectFiles);
+
// now write out the object rules
// for each object file name
- for (std::map<cmStdString, LocalObjectInfo>::iterator lo =
- this->LocalObjectFiles.begin();
- lo != this->LocalObjectFiles.end(); ++lo)
+ for (std::map<std::string, LocalObjectInfo>::iterator lo =
+ localObjectFiles.begin();
+ lo != localObjectFiles.end(); ++lo)
{
// Add a convenience rule for building the object file.
this->WriteObjectConvenienceRule(ruleFileStream,
@@ -261,36 +298,43 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
// Check whether preprocessing and assembly rules make sense.
// They make sense only for C and C++ sources.
- bool lang_is_c_or_cxx = false;
+ bool lang_has_preprocessor = false;
+ bool lang_has_assembly = false;
+
for(std::vector<LocalObjectEntry>::const_iterator ei =
lo->second.begin(); ei != lo->second.end(); ++ei)
{
- if(ei->Language == "C" || ei->Language == "CXX")
+ if(ei->Language == "C" ||
+ ei->Language == "CXX" ||
+ ei->Language == "Fortran")
{
- lang_is_c_or_cxx = true;
+ // Right now, C, C++ and Fortran have both a preprocessor and the
+ // ability to generate assembly code
+ lang_has_preprocessor = true;
+ lang_has_assembly = true;
break;
}
}
// Add convenience rules for preprocessed and assembly files.
- if(lang_is_c_or_cxx && (do_preprocess_rules || do_assembly_rules))
+ if(lang_has_preprocessor && do_preprocess_rules)
{
std::string::size_type dot_pos = lo->first.rfind(".");
std::string base = lo->first.substr(0, dot_pos);
- if(do_preprocess_rules)
- {
- this->WriteObjectConvenienceRule(
- ruleFileStream, "target to preprocess a source file",
- (base + ".i").c_str(), lo->second);
- lo->second.HasPreprocessRule = true;
- }
- if(do_assembly_rules)
- {
- this->WriteObjectConvenienceRule(
- ruleFileStream, "target to generate assembly for a file",
- (base + ".s").c_str(), lo->second);
- lo->second.HasAssembleRule = true;
- }
+ this->WriteObjectConvenienceRule(
+ ruleFileStream, "target to preprocess a source file",
+ (base + ".i").c_str(), lo->second);
+ lo->second.HasPreprocessRule = true;
+ }
+
+ if(lang_has_assembly && do_assembly_rules)
+ {
+ std::string::size_type dot_pos = lo->first.rfind(".");
+ std::string base = lo->first.substr(0, dot_pos);
+ this->WriteObjectConvenienceRule(
+ ruleFileStream, "target to generate assembly for a file",
+ (base + ".s").c_str(), lo->second);
+ lo->second.HasAssembleRule = true;
}
}
@@ -333,7 +377,7 @@ cmLocalUnixMakefileGenerator3
depends.push_back(output);
std::vector<std::string> no_commands;
this->WriteMakeRule(ruleFileStream, 0,
- outNoExt.c_str(), depends, no_commands, true, true);
+ outNoExt, depends, no_commands, true, true);
inHelp = false;
}
@@ -343,17 +387,17 @@ cmLocalUnixMakefileGenerator3
t != info.end(); ++t)
{
std::string tgtMakefileName =
- this->GetRelativeTargetDirectory(*(t->Target));
+ this->GetRelativeTargetDirectory(t->Target);
std::string targetName = tgtMakefileName;
tgtMakefileName += "/build.make";
targetName += "/";
targetName += output;
commands.push_back(
- this->GetRecursiveMakeCall(tgtMakefileName.c_str(), targetName.c_str())
+ this->GetRecursiveMakeCall(tgtMakefileName.c_str(), targetName)
);
}
this->CreateCDCommand(commands,
- this->Makefile->GetHomeOutputDirectory(),
+ this->GetBinaryDirectory(),
cmLocalGenerator::START_OUTPUT);
// Write the rule to the makefile.
@@ -365,28 +409,29 @@ cmLocalUnixMakefileGenerator3
//----------------------------------------------------------------------------
void cmLocalUnixMakefileGenerator3
::WriteLocalMakefileTargets(std::ostream& ruleFileStream,
- std::set<cmStdString> &emitted)
+ std::set<std::string> &emitted)
{
std::vector<std::string> depends;
std::vector<std::string> commands;
// for each target we just provide a rule to cd up to the top and do a make
// on the target
- cmTargets& targets = this->Makefile->GetTargets();
+ std::vector<cmGeneratorTarget*> targets = this->GetGeneratorTargets();
std::string localName;
- 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::OBJECT_LIBRARY) ||
- (t->second.GetType() == cmTarget::UTILITY))
+ for(std::vector<cmGeneratorTarget*>::iterator t = targets.begin();
+ t != targets.end(); ++t)
+ {
+ if(((*t)->GetType() == cmState::EXECUTABLE) ||
+ ((*t)->GetType() == cmState::STATIC_LIBRARY) ||
+ ((*t)->GetType() == cmState::SHARED_LIBRARY) ||
+ ((*t)->GetType() == cmState::MODULE_LIBRARY) ||
+ ((*t)->GetType() == cmState::OBJECT_LIBRARY) ||
+ ((*t)->GetType() == cmState::UTILITY))
{
- emitted.insert(t->second.GetName());
+ emitted.insert((*t)->GetName());
// for subdirs add a rule to build this specific target by name.
- localName = this->GetRelativeTargetDirectory(t->second);
+ localName = this->GetRelativeTargetDirectory(*t);
localName += "/rule";
commands.clear();
depends.clear();
@@ -395,59 +440,60 @@ void cmLocalUnixMakefileGenerator3
std::string makefile2 = cmake::GetCMakeFilesDirectoryPostSlash();
makefile2 += "Makefile2";
commands.push_back(this->GetRecursiveMakeCall
- (makefile2.c_str(),localName.c_str()));
+ (makefile2.c_str(),localName));
this->CreateCDCommand(commands,
- this->Makefile->GetHomeOutputDirectory(),
+ this->GetBinaryDirectory(),
cmLocalGenerator::START_OUTPUT);
this->WriteMakeRule(ruleFileStream, "Convenience name for target.",
- localName.c_str(), depends, commands, true);
+ localName, depends, commands, true);
// Add a target with the canonical name (no prefix, suffix or path).
- if(localName != t->second.GetName())
+ if(localName != (*t)->GetName())
{
commands.clear();
depends.push_back(localName);
this->WriteMakeRule(ruleFileStream, "Convenience name for target.",
- t->second.GetName(), depends, commands, true);
+ (*t)->GetName(), depends, commands, true);
}
// Add a fast rule to build the target
- std::string makefileName = this->GetRelativeTargetDirectory(t->second);
+ std::string makefileName =
+ this->GetRelativeTargetDirectory(*t);
makefileName += "/build.make";
// make sure the makefile name is suitable for a makefile
std::string makeTargetName =
- this->GetRelativeTargetDirectory(t->second);
+ this->GetRelativeTargetDirectory(*t);
makeTargetName += "/build";
- localName = t->second.GetName();
+ localName = (*t)->GetName();
localName += "/fast";
depends.clear();
commands.clear();
commands.push_back(this->GetRecursiveMakeCall
- (makefileName.c_str(), makeTargetName.c_str()));
+ (makefileName.c_str(), makeTargetName));
this->CreateCDCommand(commands,
- this->Makefile->GetHomeOutputDirectory(),
+ this->GetBinaryDirectory(),
cmLocalGenerator::START_OUTPUT);
this->WriteMakeRule(ruleFileStream, "fast build rule for target.",
- localName.c_str(), depends, commands, true);
+ localName, depends, commands, true);
// Add a local name for the rule to relink the target before
// installation.
- if(t->second.NeedRelinkBeforeInstall(this->ConfigurationName.c_str()))
+ if((*t)->NeedRelinkBeforeInstall(this->ConfigName))
{
- makeTargetName = this->GetRelativeTargetDirectory(t->second);
+ makeTargetName = this->GetRelativeTargetDirectory(*t);
makeTargetName += "/preinstall";
- localName = t->second.GetName();
+ localName = (*t)->GetName();
localName += "/preinstall";
depends.clear();
commands.clear();
commands.push_back(this->GetRecursiveMakeCall
- (makefile2.c_str(), makeTargetName.c_str()));
+ (makefile2.c_str(), makeTargetName));
this->CreateCDCommand(commands,
- this->Makefile->GetHomeOutputDirectory(),
+ this->GetBinaryDirectory(),
cmLocalGenerator::START_OUTPUT);
this->WriteMakeRule(ruleFileStream,
"Manual pre-install relink rule for target.",
- localName.c_str(), depends, commands, true);
+ localName, depends, commands, true);
}
}
}
@@ -456,7 +502,7 @@ void cmLocalUnixMakefileGenerator3
//----------------------------------------------------------------------------
void cmLocalUnixMakefileGenerator3::WriteDirectoryInformationFile()
{
- std::string infoFileName = this->Makefile->GetStartOutputDirectory();
+ std::string infoFileName = this->GetCurrentBinaryDirectory();
infoFileName += cmake::GetCMakeFilesDirectory();
infoFileName += "/CMakeDirectoryInformation.cmake";
@@ -474,9 +520,11 @@ void cmLocalUnixMakefileGenerator3::WriteDirectoryInformationFile()
// Setup relative path conversion tops.
infoFileStream
<< "# Relative path conversion top directories.\n"
- << "SET(CMAKE_RELATIVE_PATH_TOP_SOURCE \"" << this->RelativePathTopSource
+ << "set(CMAKE_RELATIVE_PATH_TOP_SOURCE \""
+ << this->StateSnapshot.GetDirectory().GetRelativePathTopSource()
<< "\")\n"
- << "SET(CMAKE_RELATIVE_PATH_TOP_BINARY \"" << this->RelativePathTopBinary
+ << "set(CMAKE_RELATIVE_PATH_TOP_BINARY \""
+ << this->StateSnapshot.GetDirectory().GetRelativePathTopBinary()
<< "\")\n"
<< "\n";
@@ -485,7 +533,7 @@ void cmLocalUnixMakefileGenerator3::WriteDirectoryInformationFile()
{
infoFileStream
<< "# Force unix paths in dependencies.\n"
- << "SET(CMAKE_FORCE_UNIX_PATHS 1)\n"
+ << "set(CMAKE_FORCE_UNIX_PATHS 1)\n"
<< "\n";
}
@@ -495,21 +543,21 @@ void cmLocalUnixMakefileGenerator3::WriteDirectoryInformationFile()
<< "# The C and CXX include file regular expressions for "
<< "this directory.\n";
infoFileStream
- << "SET(CMAKE_C_INCLUDE_REGEX_SCAN ";
+ << "set(CMAKE_C_INCLUDE_REGEX_SCAN ";
this->WriteCMakeArgument(infoFileStream,
this->Makefile->GetIncludeRegularExpression());
infoFileStream
<< ")\n";
infoFileStream
- << "SET(CMAKE_C_INCLUDE_REGEX_COMPLAIN ";
+ << "set(CMAKE_C_INCLUDE_REGEX_COMPLAIN ";
this->WriteCMakeArgument(infoFileStream,
this->Makefile->GetComplainRegularExpression());
infoFileStream
<< ")\n";
infoFileStream
- << "SET(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN})\n";
+ << "set(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN})\n";
infoFileStream
- << "SET(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN "
+ << "set(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN "
"${CMAKE_C_INCLUDE_REGEX_COMPLAIN})\n";
}
@@ -518,7 +566,7 @@ std::string
cmLocalUnixMakefileGenerator3
::ConvertToFullPath(const std::string& localPath)
{
- std::string dir = this->Makefile->GetStartOutputDirectory();
+ std::string dir = this->GetCurrentBinaryDirectory();
dir += "/";
dir += localPath;
return dir;
@@ -530,20 +578,19 @@ const std::string &cmLocalUnixMakefileGenerator3::GetHomeRelativeOutputPath()
return this->HomeRelativeOutputPath;
}
-
//----------------------------------------------------------------------------
void
cmLocalUnixMakefileGenerator3
::WriteMakeRule(std::ostream& os,
const char* comment,
- const char* target,
+ const std::string& target,
const std::vector<std::string>& depends,
const std::vector<std::string>& commands,
bool symbolic,
bool in_help)
{
// Make sure there is a target.
- if(!target || !*target)
+ if(target.empty())
{
cmSystemTools::Error("No target for WriteMakeRule! called with comment: ",
comment);
@@ -567,8 +614,8 @@ cmLocalUnixMakefileGenerator3
}
// Construct the left hand side of the rule.
- replace = target;
- std::string tgt = this->Convert(replace.c_str(),HOME_OUTPUT,MAKEFILE);
+ std::string tgt = this->Convert(target, HOME_OUTPUT, MAKERULE);
+
const char* space = "";
if(tgt.size() == 1)
{
@@ -601,19 +648,14 @@ cmLocalUnixMakefileGenerator3
dep != depends.end(); ++dep)
{
replace = *dep;
- replace = this->Convert(replace.c_str(),HOME_OUTPUT,MAKEFILE);
+ replace = this->Convert(replace,HOME_OUTPUT,MAKERULE);
os << cmMakeSafe(tgt) << space << ": " << cmMakeSafe(replace) << "\n";
}
}
// Write the list of commands.
- for(std::vector<std::string>::const_iterator i = commands.begin();
- i != commands.end(); ++i)
- {
- replace = *i;
- os << "\t" << replace.c_str() << "\n";
- }
- if(symbolic && !this->WatcomWMake)
+ os << cmWrap("\t", commands, "", "\n") << "\n";
+ if(symbolic && !this->IsWatcomWMake())
{
os << ".PHONY : " << cmMakeSafe(tgt) << "\n";
}
@@ -630,7 +672,7 @@ std::string
cmLocalUnixMakefileGenerator3
::ConvertShellCommand(std::string const& cmd, RelativeRoot root)
{
- if(this->WatcomWMake &&
+ if(this->IsWatcomWMake() &&
cmSystemTools::FileIsFullPath(cmd.c_str()) &&
cmd.find_first_of("( )") != cmd.npos)
{
@@ -638,12 +680,12 @@ cmLocalUnixMakefileGenerator3
// name. This is needed to avoid funny quoting problems on
// lines with shell redirection operators.
std::string scmd;
- if(cmSystemTools::GetShortPath(cmd.c_str(), scmd))
+ if(cmSystemTools::GetShortPath(cmd, scmd))
{
- return this->Convert(scmd.c_str(), NONE, SHELL);
+ return this->Convert(scmd, NONE, SHELL);
}
}
- return this->Convert(cmd.c_str(), root, SHELL);
+ return this->Convert(cmd, root, SHELL);
}
//----------------------------------------------------------------------------
@@ -655,7 +697,9 @@ cmLocalUnixMakefileGenerator3
makefileStream
<< "# Set environment variables for the build.\n"
<< "\n";
- if(this->DefineWindowsNULL)
+ cmGlobalUnixMakefileGenerator3* gg =
+ static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
+ if(gg->DefineWindowsNULL)
{
makefileStream
<< "!IF \"$(OS)\" == \"Windows_NT\"\n"
@@ -664,7 +708,7 @@ cmLocalUnixMakefileGenerator3
<< "NULL=nul\n"
<< "!ENDIF\n";
}
- if(this->WindowsShell)
+ if(this->IsWindowsShell())
{
makefileStream
<< "SHELL = cmd.exe\n"
@@ -680,45 +724,32 @@ cmLocalUnixMakefileGenerator3
#endif
}
- std::string cmakecommand =
- this->Makefile->GetRequiredDefinition("CMAKE_COMMAND");
makefileStream
<< "# The CMake executable.\n"
<< "CMAKE_COMMAND = "
- << this->ConvertShellCommand(cmakecommand, FULL)
+ << this->ConvertShellCommand(cmSystemTools::GetCMakeCommand(), FULL)
<< "\n"
<< "\n";
makefileStream
<< "# The command to remove a file.\n"
<< "RM = "
- << this->ConvertShellCommand(cmakecommand, FULL)
+ << this->ConvertShellCommand(cmSystemTools::GetCMakeCommand(), FULL)
<< " -E remove -f\n"
<< "\n";
makefileStream
<< "# Escaping for special characters.\n"
<< "EQUALS = =\n"
<< "\n";
-
- if(const char* edit_cmd =
- this->Makefile->GetDefinition("CMAKE_EDIT_COMMAND"))
- {
- makefileStream
- << "# The program to use to edit the cache.\n"
- << "CMAKE_EDIT_COMMAND = "
- << this->ConvertShellCommand(edit_cmd, FULL) << "\n"
- << "\n";
- }
-
makefileStream
<< "# The top-level source directory on which CMake was run.\n"
<< "CMAKE_SOURCE_DIR = "
- << this->Convert(this->Makefile->GetHomeDirectory(), FULL, SHELL)
+ << this->Convert(this->GetSourceDirectory(), FULL, SHELL)
<< "\n"
<< "\n";
makefileStream
<< "# The top-level build directory on which CMake was run.\n"
<< "CMAKE_BINARY_DIR = "
- << this->Convert(this->Makefile->GetHomeOutputDirectory(), FULL, SHELL)
+ << this->Convert(this->GetBinaryDirectory(), FULL, SHELL)
<< "\n"
<< "\n";
}
@@ -743,7 +774,8 @@ cmLocalUnixMakefileGenerator3
makefileStream, "Disable implicit rules so canonical targets will work.",
".SUFFIXES", no_depends, no_commands, false);
- if(!this->NMake && !this->WatcomWMake && !this->BorlandMakeCurlyHack)
+ if(!this->IsNMake()
+ && !this->IsWatcomWMake() && !this->BorlandMakeCurlyHack)
{
// turn off RCS and SCCS automatic stuff from gmake
makefileStream
@@ -755,15 +787,17 @@ cmLocalUnixMakefileGenerator3
depends.push_back(".hpux_make_needs_suffix_list");
this->WriteMakeRule(makefileStream, 0,
".SUFFIXES", depends, no_commands, false);
-
- cmGlobalUnixMakefileGenerator3* gg =
- static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
- // Write special target to silence make output. This must be after
- // the default target in case VERBOSE is set (which changes the
- // name). The setting of CMAKE_VERBOSE_MAKEFILE to ON will cause a
- // "VERBOSE=1" to be added as a make variable which will change the
- // name of this special target. This gives a make-time choice to
- // the user.
+ if(this->IsWatcomWMake())
+ {
+ // Switch on WMake feature, if an error or interrupt occurs during
+ // makefile processing, the current target being made may be deleted
+ // without prompting (the same as command line -e option).
+ makefileStream <<
+ "\n"
+ ".ERASE\n"
+ "\n"
+ ;
+ }
if(this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"))
{
makefileStream
@@ -771,12 +805,23 @@ cmLocalUnixMakefileGenerator3
<< "VERBOSE = 1\n"
<< "\n";
}
- if(this->SilentNoColon)
+ if(this->IsWatcomWMake())
{
- makefileStream << "$(VERBOSE).SILENT\n";
+ makefileStream <<
+ "!ifndef VERBOSE\n"
+ ".SILENT\n"
+ "!endif\n"
+ "\n"
+ ;
}
else
{
+ // Write special target to silence make output. This must be after
+ // the default target in case VERBOSE is set (which changes the
+ // name). The setting of CMAKE_VERBOSE_MAKEFILE to ON will cause a
+ // "VERBOSE=1" to be added as a make variable which will change the
+ // name of this special target. This gives a make-time choice to
+ // the user.
this->WriteMakeRule(makefileStream,
"Suppress display of executed commands.",
"$(VERBOSE).SILENT",
@@ -786,6 +831,8 @@ cmLocalUnixMakefileGenerator3
// Work-around for makes that drop rules that have no dependencies
// or commands.
+ cmGlobalUnixMakefileGenerator3* gg =
+ static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
std::string hack = gg->GetEmptyRuleHackDepends();
if(!hack.empty())
{
@@ -826,16 +873,16 @@ void cmLocalUnixMakefileGenerator3
std::string runRule =
"$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)";
runRule += " --check-build-system ";
- runRule += this->Convert(cmakefileName.c_str(),NONE,SHELL);
+ runRule += this->Convert(cmakefileName,NONE,SHELL);
runRule += " 0";
std::vector<std::string> no_depends;
std::vector<std::string> commands;
commands.push_back(runRule);
- if(this->Parent)
+ if(!this->IsRootMakefile())
{
this->CreateCDCommand(commands,
- this->Makefile->GetHomeOutputDirectory(),
+ this->GetBinaryDirectory(),
cmLocalGenerator::START_OUTPUT);
}
this->WriteMakeRule(makefileStream,
@@ -856,11 +903,11 @@ void cmLocalUnixMakefileGenerator3
void
cmLocalUnixMakefileGenerator3
::WriteConvenienceRule(std::ostream& ruleFileStream,
- const char* realTarget,
- const char* helpTarget)
+ const std::string& realTarget,
+ const std::string& helpTarget)
{
// A rule is only needed if the names are different.
- if(strcmp(realTarget, helpTarget) != 0)
+ if(realTarget != helpTarget)
{
// The helper target depends on the real target.
std::vector<std::string> depends;
@@ -879,26 +926,26 @@ cmLocalUnixMakefileGenerator3
//----------------------------------------------------------------------------
std::string
cmLocalUnixMakefileGenerator3
-::GetRelativeTargetDirectory(cmTarget const& target)
+::GetRelativeTargetDirectory(cmGeneratorTarget* target)
{
std::string dir = this->HomeRelativeOutputPath;
dir += this->GetTargetDirectory(target);
- return this->Convert(dir.c_str(),NONE,UNCHANGED);
+ return this->Convert(dir,NONE,UNCHANGED);
}
//----------------------------------------------------------------------------
void cmLocalUnixMakefileGenerator3::AppendFlags(std::string& flags,
- const char* newFlags)
+ const std::string& newFlags)
{
- if(this->WatcomWMake && newFlags && *newFlags)
+ if(this->IsWatcomWMake() && !newFlags.empty())
{
std::string newf = newFlags;
if(newf.find("\\\"") != newf.npos)
{
cmSystemTools::ReplaceString(newf, "\\\"", "\"");
- this->cmLocalGenerator::AppendFlags(flags, newf.c_str());
+ this->cmLocalGenerator::AppendFlags(flags, newf);
return;
}
}
@@ -906,6 +953,13 @@ void cmLocalUnixMakefileGenerator3::AppendFlags(std::string& flags,
}
//----------------------------------------------------------------------------
+void cmLocalUnixMakefileGenerator3::AppendFlags(std::string& flags,
+ const char* newFlags)
+{
+ this->cmLocalGenerator::AppendFlags(flags, newFlags);
+}
+
+//----------------------------------------------------------------------------
void
cmLocalUnixMakefileGenerator3
::AppendRuleDepend(std::vector<std::string>& depends,
@@ -944,7 +998,8 @@ cmLocalUnixMakefileGenerator3
for(std::vector<cmCustomCommand>::const_iterator i = ccs.begin();
i != ccs.end(); ++i)
{
- this->AppendCustomDepend(depends, *i);
+ cmCustomCommandGenerator ccg(*i, this->ConfigName, this);
+ this->AppendCustomDepend(depends, ccg);
}
}
@@ -952,14 +1007,14 @@ cmLocalUnixMakefileGenerator3
void
cmLocalUnixMakefileGenerator3
::AppendCustomDepend(std::vector<std::string>& depends,
- const cmCustomCommand& cc)
+ cmCustomCommandGenerator const& ccg)
{
- for(std::vector<std::string>::const_iterator d = cc.GetDepends().begin();
- d != cc.GetDepends().end(); ++d)
+ for(std::vector<std::string>::const_iterator d = ccg.GetDepends().begin();
+ d != ccg.GetDepends().end(); ++d)
{
// Lookup the real name of the dependency in case it is a CMake target.
std::string dep;
- if(this->GetRealDependency(d->c_str(), this->ConfigurationName.c_str(),
+ if(this->GetRealDependency(*d, this->ConfigName,
dep))
{
depends.push_back(dep);
@@ -972,13 +1027,14 @@ void
cmLocalUnixMakefileGenerator3
::AppendCustomCommands(std::vector<std::string>& commands,
const std::vector<cmCustomCommand>& ccs,
- cmTarget* target,
+ cmGeneratorTarget* target,
cmLocalGenerator::RelativeRoot relative)
{
for(std::vector<cmCustomCommand>::const_iterator i = ccs.begin();
i != ccs.end(); ++i)
{
- this->AppendCustomCommand(commands, *i, target, true, relative);
+ cmCustomCommandGenerator ccg(*i, this->ConfigName, this);
+ this->AppendCustomCommand(commands, ccg, target, true, relative);
}
}
@@ -986,8 +1042,8 @@ cmLocalUnixMakefileGenerator3
void
cmLocalUnixMakefileGenerator3
::AppendCustomCommand(std::vector<std::string>& commands,
- const cmCustomCommand& cc,
- cmTarget* target,
+ cmCustomCommandGenerator const& ccg,
+ cmGeneratorTarget* target,
bool echo_comment,
cmLocalGenerator::RelativeRoot relative,
std::ostream* content)
@@ -998,7 +1054,7 @@ cmLocalUnixMakefileGenerator3
// their comments generated elsewhere.
if(echo_comment)
{
- const char* comment = cc.GetComment();
+ const char* comment = ccg.GetComment();
if(comment && *comment)
{
this->AppendEcho(commands, comment,
@@ -1007,9 +1063,9 @@ cmLocalUnixMakefileGenerator3
}
// if the command specified a working directory use it.
- const char* dir = this->Makefile->GetStartOutputDirectory();
- const char* workingDir = cc.GetWorkingDirectory();
- if(workingDir)
+ std::string dir = this->GetCurrentBinaryDirectory();
+ std::string workingDir = ccg.GetWorkingDirectory();
+ if(!workingDir.empty())
{
dir = workingDir;
}
@@ -1017,8 +1073,6 @@ cmLocalUnixMakefileGenerator3
{
*content << dir;
}
- cmCustomCommandGenerator ccg(cc, this->ConfigurationName.c_str(),
- this->Makefile);
// Add each command line to the set of commands.
std::vector<std::string> commands1;
@@ -1026,14 +1080,14 @@ cmLocalUnixMakefileGenerator3
{
// Build the command line in a single string.
std::string cmd = ccg.GetCommand(c);
- if (cmd.size())
+ if (!cmd.empty())
{
// Use "call " before any invocations of .bat or .cmd files
// invoked as custom commands in the WindowsShell.
//
bool useCall = false;
- if (this->WindowsShell)
+ if (this->IsWindowsShell())
{
std::string suffix;
if (cmd.size() > 4)
@@ -1050,9 +1104,9 @@ cmLocalUnixMakefileGenerator3
// Convert the command to a relative path only if the current
// working directory will be the start-output directory.
bool had_slash = cmd.find("/") != cmd.npos;
- if(!workingDir)
+ if(workingDir.empty())
{
- cmd = this->Convert(cmd.c_str(),START_OUTPUT);
+ cmd = this->Convert(cmd,START_OUTPUT);
}
bool has_slash = cmd.find("/") != cmd.npos;
if(had_slash && !has_slash)
@@ -1063,7 +1117,8 @@ cmLocalUnixMakefileGenerator3
cmd = "./" + cmd;
}
std::string launcher =
- this->MakeLauncher(cc, target, workingDir? NONE : START_OUTPUT);
+ this->MakeLauncher(ccg, target,
+ workingDir.empty()? START_OUTPUT : NONE);
cmd = launcher + this->ConvertShellCommand(cmd, NONE);
ccg.AppendArguments(c, cmd);
@@ -1099,7 +1154,7 @@ cmLocalUnixMakefileGenerator3
{
cmd = "call " + cmd;
}
- else if (this->NMake && cmd[0]=='"')
+ else if (this->IsNMake() && cmd[0]=='"')
{
cmd = "echo >nul && " + cmd;
}
@@ -1109,7 +1164,7 @@ cmLocalUnixMakefileGenerator3
}
// Setup the proper working directory for the commands.
- this->CreateCDCommand(commands1, dir, relative);
+ this->CreateCDCommand(commands1, dir.c_str(), relative);
// push back the custom commands
commands.insert(commands.end(), commands1.begin(), commands1.end());
@@ -1117,9 +1172,9 @@ cmLocalUnixMakefileGenerator3
//----------------------------------------------------------------------------
std::string
-cmLocalUnixMakefileGenerator3::MakeLauncher(const cmCustomCommand& cc,
- cmTarget* target,
- RelativeRoot relative)
+cmLocalUnixMakefileGenerator3::MakeLauncher(
+ cmCustomCommandGenerator const& ccg,
+ cmGeneratorTarget* target, RelativeRoot relative)
{
// Short-circuit if there is no launcher.
const char* prop = "RULE_LAUNCH_CUSTOM";
@@ -1135,10 +1190,10 @@ cmLocalUnixMakefileGenerator3::MakeLauncher(const cmCustomCommand& cc,
vars.RuleLauncher = prop;
vars.CMTarget = target;
std::string output;
- const std::vector<std::string>& outputs = cc.GetOutputs();
+ const std::vector<std::string>& outputs = ccg.GetOutputs();
if(!outputs.empty())
{
- output = this->Convert(outputs[0].c_str(), relative, SHELL);
+ output = this->Convert(outputs[0], relative, SHELL);
}
vars.Output = output.c_str();
@@ -1156,69 +1211,64 @@ void
cmLocalUnixMakefileGenerator3
::AppendCleanCommand(std::vector<std::string>& commands,
const std::vector<std::string>& files,
- cmTarget& target, const char* filename)
+ cmGeneratorTarget* target, const char* filename)
{
+ std::string cleanfile = this->GetCurrentBinaryDirectory();
+ cleanfile += "/";
+ cleanfile += this->GetTargetDirectory(target);
+ cleanfile += "/cmake_clean";
+ if(filename)
+ {
+ cleanfile += "_";
+ cleanfile += filename;
+ }
+ cleanfile += ".cmake";
+ std::string cleanfilePath = this->Convert(cleanfile, FULL);
+ cmsys::ofstream fout(cleanfilePath.c_str());
+ if(!fout)
+ {
+ cmSystemTools::Error("Could not create ", cleanfilePath.c_str());
+ }
if(!files.empty())
{
- std::string cleanfile = this->Makefile->GetCurrentOutputDirectory();
- cleanfile += "/";
- cleanfile += this->GetTargetDirectory(target);
- cleanfile += "/cmake_clean";
- if(filename)
- {
- cleanfile += "_";
- cleanfile += filename;
- }
- cleanfile += ".cmake";
- std::string cleanfilePath = this->Convert(cleanfile.c_str(), FULL);
- std::ofstream fout(cleanfilePath.c_str());
- if(!fout)
- {
- cmSystemTools::Error("Could not create ", cleanfilePath.c_str());
- }
- fout << "FILE(REMOVE_RECURSE\n";
- std::string remove = "$(CMAKE_COMMAND) -P ";
- remove += this->Convert(cleanfile.c_str(), START_OUTPUT, SHELL);
+ fout << "file(REMOVE_RECURSE\n";
for(std::vector<std::string>::const_iterator f = files.begin();
f != files.end(); ++f)
{
- std::string fc = this->Convert(f->c_str(),START_OUTPUT,UNCHANGED);
- fout << " " << this->EscapeForCMake(fc.c_str()) << "\n";
+ std::string fc = this->Convert(*f,START_OUTPUT,UNCHANGED);
+ fout << " " << cmOutputConverter::EscapeForCMake(fc) << "\n";
}
fout << ")\n";
- commands.push_back(remove);
+ }
+ std::string remove = "$(CMAKE_COMMAND) -P ";
+ remove += this->Convert(cleanfile, START_OUTPUT, SHELL);
+ commands.push_back(remove);
- // For the main clean rule add per-language cleaning.
- if(!filename)
- {
- // Get the set of source languages in the target.
- std::set<cmStdString> languages;
- target.GetLanguages(languages);
- fout << "\n"
- << "# Per-language clean rules from dependency scanning.\n"
- << "FOREACH(lang";
- for(std::set<cmStdString>::const_iterator l = languages.begin();
- l != languages.end(); ++l)
- {
- fout << " " << *l;
- }
- fout << ")\n"
- << " INCLUDE(" << this->GetTargetDirectory(target)
- << "/cmake_clean_${lang}.cmake OPTIONAL)\n"
- << "ENDFOREACH(lang)\n";
- }
+ // For the main clean rule add per-language cleaning.
+ if(!filename)
+ {
+ // Get the set of source languages in the target.
+ std::set<std::string> languages;
+ target->GetLanguages(languages,
+ this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
+ fout << "\n"
+ << "# Per-language clean rules from dependency scanning.\n"
+ << "foreach(lang " << cmJoin(languages, " ") << ")\n"
+ << " include(" << this->GetTargetDirectory(target)
+ << "/cmake_clean_${lang}.cmake OPTIONAL)\n"
+ << "endforeach()\n";
}
}
//----------------------------------------------------------------------------
void
cmLocalUnixMakefileGenerator3::AppendEcho(std::vector<std::string>& commands,
- const char* text,
- EchoColor color)
+ std::string const& text,
+ EchoColor color,
+ EchoProgress const* progress)
{
// Choose the color for the text.
std::string color_name;
-#ifdef CMAKE_BUILD_WITH_CMAKE
if(this->GlobalGenerator->GetToolSupportsColor() && this->ColorMakefile)
{
// See cmake::ExecuteEchoColor in cmake.cxx for these options.
@@ -1234,7 +1284,7 @@ cmLocalUnixMakefileGenerator3::AppendEcho(std::vector<std::string>& commands,
color_name = "--green ";
break;
case EchoLink:
- color_name = "--red --bold ";
+ color_name = "--green --bold ";
break;
case EchoGenerate:
color_name = "--blue --bold ";
@@ -1244,14 +1294,11 @@ cmLocalUnixMakefileGenerator3::AppendEcho(std::vector<std::string>& commands,
break;
}
}
-#else
- (void)color;
-#endif
// Echo one line at a time.
std::string line;
line.reserve(200);
- for(const char* c = text;; ++c)
+ for(const char* c = text.c_str();; ++c)
{
if(*c == '\n' || *c == '\0')
{
@@ -1260,18 +1307,29 @@ cmLocalUnixMakefileGenerator3::AppendEcho(std::vector<std::string>& commands,
{
// Add a command to echo this line.
std::string cmd;
- if(color_name.empty())
+ if(color_name.empty() && !progress)
{
// Use the native echo command.
cmd = "@echo ";
- cmd += this->EscapeForShell(line.c_str(), false, true);
+ cmd += this->EscapeForShell(line, false, true);
}
else
{
// Use cmake to echo the text in color.
cmd = "@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) ";
cmd += color_name;
- cmd += this->EscapeForShell(line.c_str());
+ if (progress)
+ {
+ cmd += "--progress-dir=";
+ cmd += this->Convert(progress->Dir,
+ cmLocalGenerator::FULL,
+ cmLocalGenerator::SHELL);
+ cmd += " ";
+ cmd += "--progress-num=";
+ cmd += progress->Arg;
+ cmd += " ";
+ }
+ cmd += this->EscapeForShell(line);
}
commands.push_back(cmd);
}
@@ -1279,6 +1337,9 @@ cmLocalUnixMakefileGenerator3::AppendEcho(std::vector<std::string>& commands,
// Reset the line to emtpy.
line = "";
+ // Progress appears only on first line.
+ progress = 0;
+
// Terminate on end-of-string.
if(*c == '\0')
{
@@ -1296,7 +1357,7 @@ cmLocalUnixMakefileGenerator3::AppendEcho(std::vector<std::string>& commands,
//----------------------------------------------------------------------------
std::string
cmLocalUnixMakefileGenerator3
-::CreateMakeVariable(const char* sin, const char* s2in)
+::CreateMakeVariable(const std::string& sin, const std::string& s2in)
{
std::string s = sin;
std::string s2 = s2in;
@@ -1314,7 +1375,7 @@ cmLocalUnixMakefileGenerator3
// see if the variable has been defined before and return
// the modified version of the variable
- std::map<cmStdString, cmStdString>::iterator i =
+ std::map<std::string, std::string>::iterator i =
this->MakeVariableMap.find(unmodified);
if(i != this->MakeVariableMap.end())
{
@@ -1391,7 +1452,7 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(const char* tgtInfo,
bool color)
{
// read in the target info file
- if(!this->Makefile->ReadListFile(0, tgtInfo) ||
+ if(!this->Makefile->ReadListFile(tgtInfo) ||
cmSystemTools::GetErrorOccuredFlag())
{
cmSystemTools::Error("Target DependInfo.cmake file not found");
@@ -1418,7 +1479,7 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(const char* tgtInfo,
{
if(verbose)
{
- cmOStringStream msg;
+ std::ostringstream msg;
msg << "Dependee \"" << tgtInfo
<< "\" is newer than depender \""
<< internalDependFile << "\"." << std::endl;
@@ -1431,7 +1492,7 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(const char* tgtInfo,
// If the directory information is newer than depend.internal, include dirs
// may have changed. In this case discard all old dependencies.
bool needRescanDirInfo = false;
- std::string dirInfoFile = this->Makefile->GetStartOutputDirectory();
+ std::string dirInfoFile = this->GetCurrentBinaryDirectory();
dirInfoFile += cmake::GetCMakeFilesDirectory();
dirInfoFile += "/CMakeDirectoryInformation.cmake";
{
@@ -1441,7 +1502,7 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(const char* tgtInfo,
{
if(verbose)
{
- cmOStringStream msg;
+ std::ostringstream msg;
msg << "Dependee \"" << dirInfoFile
<< "\" is newer than depender \""
<< internalDependFile << "\"." << std::endl;
@@ -1484,14 +1545,10 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(const char* tgtInfo,
targetName = targetName.substr(0, targetName.length()-4);
std::string message = "Scanning dependencies of target ";
message += targetName;
-#ifdef CMAKE_BUILD_WITH_CMAKE
cmSystemTools::MakefileColorEcho(
cmsysTerminal_Color_ForegroundMagenta |
cmsysTerminal_Color_ForegroundBold,
message.c_str(), true, color);
-#else
- fprintf(stdout, "%s\n", message.c_str());
-#endif
return this->ScanDependencies(dir.c_str(), validDependencies);
}
@@ -1509,10 +1566,10 @@ cmLocalUnixMakefileGenerator3
// Read the directory information file.
cmMakefile* mf = this->Makefile;
bool haveDirectoryInfo = false;
- std::string dirInfoFile = this->Makefile->GetStartOutputDirectory();
+ std::string dirInfoFile = this->GetCurrentBinaryDirectory();
dirInfoFile += cmake::GetCMakeFilesDirectory();
dirInfoFile += "/CMakeDirectoryInformation.cmake";
- if(mf->ReadListFile(0, dirInfoFile.c_str()) &&
+ if(mf->ReadListFile(dirInfoFile.c_str()) &&
!cmSystemTools::GetErrorOccuredFlag())
{
haveDirectoryInfo = true;
@@ -1531,16 +1588,17 @@ cmLocalUnixMakefileGenerator3
}
// Setup relative path top directories.
- this->RelativePathsConfigured = true;
if(const char* relativePathTopSource =
mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_SOURCE"))
{
- this->RelativePathTopSource = relativePathTopSource;
+ this->StateSnapshot.GetDirectory()
+ .SetRelativePathTopSource(relativePathTopSource);
}
if(const char* relativePathTopBinary =
mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_BINARY"))
{
- this->RelativePathTopBinary = relativePathTopBinary;
+ this->StateSnapshot.GetDirectory()
+ .SetRelativePathTopBinary(relativePathTopBinary);
}
}
else
@@ -1585,14 +1643,14 @@ cmLocalUnixMakefileGenerator3
langs.begin(); li != langs.end(); ++li)
{
// construct the checker
- std::string lang = li->c_str();
+ std::string lang = *li;
// Create the scanner for this language
cmDepends *scanner = 0;
if(lang == "C" || lang == "CXX" || lang == "RC" || lang == "ASM")
{
// TODO: Handle RC (resource files) dependencies correctly.
- scanner = new cmDependsC(this, targetDir, lang.c_str(), &validDeps);
+ scanner = new cmDependsC(this, targetDir, lang, &validDeps);
}
#ifdef CMAKE_BUILD_WITH_CMAKE
else if(lang == "Fortran")
@@ -1610,7 +1668,7 @@ cmLocalUnixMakefileGenerator3
scanner->SetLocalGenerator(this);
scanner->SetFileComparison
(this->GlobalGenerator->GetCMakeInstance()->GetFileComparison());
- scanner->SetLanguage(lang.c_str());
+ scanner->SetLanguage(lang);
scanner->SetTargetDirectory(dir.c_str());
scanner->Write(ruleFileStream, internalRuleFileStream);
@@ -1650,13 +1708,13 @@ void cmLocalUnixMakefileGenerator3::CheckMultipleOutputs(bool verbose)
{
if(verbose)
{
- cmOStringStream msg;
+ std::ostringstream msg;
msg << "Deleting primary custom command output \"" << dependee
<< "\" because another output \""
<< depender << "\" does not exist." << std::endl;
cmSystemTools::Stdout(msg.str().c_str());
}
- cmSystemTools::RemoveFile(dependee.c_str());
+ cmSystemTools::RemoveFile(dependee);
}
}
}
@@ -1682,6 +1740,17 @@ void cmLocalUnixMakefileGenerator3
"default_target",
depends,
no_commands, true);
+
+ // Help out users that try "gmake target1 target2 -j".
+ cmGlobalUnixMakefileGenerator3* gg =
+ static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
+ if(gg->AllowNotParallel())
+ {
+ std::vector<std::string> no_depends;
+ this->WriteMakeRule(ruleFileStream,
+ "Allow only one \"make -f Makefile2\" at a time, but pass parallelism.",
+ ".NOTPARALLEL", no_depends, no_commands, false);
+ }
}
this->WriteSpecialTargetsTop(ruleFileStream);
@@ -1692,47 +1761,45 @@ void cmLocalUnixMakefileGenerator3
ruleFileStream
<< "# Targets provided globally by CMake.\n"
<< "\n";
- cmTargets* targets = &(this->Makefile->GetTargets());
- cmTargets::iterator glIt;
- for ( glIt = targets->begin(); glIt != targets->end(); ++ glIt )
+ std::vector<cmGeneratorTarget*> targets = this->GetGeneratorTargets();
+ std::vector<cmGeneratorTarget*>::iterator glIt;
+ for ( glIt = targets.begin(); glIt != targets.end(); ++ glIt )
{
- if ( glIt->second.GetType() == cmTarget::GLOBAL_TARGET )
+ if ( (*glIt)->GetType() == cmState::GLOBAL_TARGET )
{
- std::string targetString = "Special rule for the target " + glIt->first;
+ std::string targetString = "Special rule for the target " +
+ (*glIt)->GetName();
std::vector<std::string> commands;
std::vector<std::string> depends;
- const char* text = glIt->second.GetProperty("EchoString");
+ const char* text = (*glIt)->GetProperty("EchoString");
if ( !text )
{
text = "Running external command ...";
}
- std::set<cmStdString>::const_iterator dit;
- for ( dit = glIt->second.GetUtilities().begin();
- dit != glIt->second.GetUtilities().end();
- ++ dit )
- {
- depends.push_back(dit->c_str());
- }
+ depends.insert(depends.end(), (*glIt)->GetUtilities().begin(),
+ (*glIt)->GetUtilities().end());
this->AppendEcho(commands, text,
cmLocalUnixMakefileGenerator3::EchoGlobal);
+ cmGeneratorTarget* gt = *glIt;
+
// Global targets store their rules in pre- and post-build commands.
this->AppendCustomDepends(depends,
- glIt->second.GetPreBuildCommands());
+ gt->GetPreBuildCommands());
this->AppendCustomDepends(depends,
- glIt->second.GetPostBuildCommands());
+ gt->GetPostBuildCommands());
this->AppendCustomCommands(commands,
- glIt->second.GetPreBuildCommands(),
- &glIt->second,
+ gt->GetPreBuildCommands(),
+ gt,
cmLocalGenerator::START_OUTPUT);
this->AppendCustomCommands(commands,
- glIt->second.GetPostBuildCommands(),
- &glIt->second,
+ gt->GetPostBuildCommands(),
+ gt,
cmLocalGenerator::START_OUTPUT);
- std::string targetName = glIt->second.GetName();
+ std::string targetName = gt->GetName();
this->WriteMakeRule(ruleFileStream, targetString.c_str(),
- targetName.c_str(), depends, commands, true);
+ targetName, depends, commands, true);
// Provide a "/fast" version of the target.
depends.clear();
@@ -1752,7 +1819,7 @@ void cmLocalUnixMakefileGenerator3
}
targetName += "/fast";
this->WriteMakeRule(ruleFileStream, targetString.c_str(),
- targetName.c_str(), depends, commands, true);
+ targetName, depends, commands, true);
}
}
@@ -1760,27 +1827,26 @@ void cmLocalUnixMakefileGenerator3
std::vector<std::string> commands;
// Write the all rule.
- std::string dir;
- std::string recursiveTarget = this->Makefile->GetStartOutputDirectory();
+ std::string recursiveTarget = this->GetCurrentBinaryDirectory();
recursiveTarget += "/all";
depends.push_back("cmake_check_build_system");
- std::string progressDir = this->Makefile->GetHomeOutputDirectory();
+ std::string progressDir = this->GetBinaryDirectory();
progressDir += cmake::GetCMakeFilesDirectory();
{
- cmOStringStream progCmd;
+ std::ostringstream progCmd;
progCmd <<
"$(CMAKE_COMMAND) -E cmake_progress_start ";
- progCmd << this->Convert(progressDir.c_str(),
+ progCmd << this->Convert(progressDir,
cmLocalGenerator::FULL,
cmLocalGenerator::SHELL);
std::string progressFile = cmake::GetCMakeFilesDirectory();
progressFile += "/progress.marks";
std::string progressFileNameFull =
- this->ConvertToFullPath(progressFile.c_str());
- progCmd << " " << this->Convert(progressFileNameFull.c_str(),
+ this->ConvertToFullPath(progressFile);
+ progCmd << " " << this->Convert(progressFileNameFull,
cmLocalGenerator::FULL,
cmLocalGenerator::SHELL);
commands.push_back(progCmd.str());
@@ -1788,14 +1854,14 @@ void cmLocalUnixMakefileGenerator3
std::string mf2Dir = cmake::GetCMakeFilesDirectoryPostSlash();
mf2Dir += "Makefile2";
commands.push_back(this->GetRecursiveMakeCall(mf2Dir.c_str(),
- recursiveTarget.c_str()));
+ recursiveTarget));
this->CreateCDCommand(commands,
- this->Makefile->GetHomeOutputDirectory(),
+ this->GetBinaryDirectory(),
cmLocalGenerator::START_OUTPUT);
{
- cmOStringStream progCmd;
+ std::ostringstream progCmd;
progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0
- progCmd << this->Convert(progressDir.c_str(),
+ progCmd << this->Convert(progressDir,
cmLocalGenerator::FULL,
cmLocalGenerator::SHELL);
progCmd << " 0";
@@ -1805,14 +1871,14 @@ void cmLocalUnixMakefileGenerator3
depends, commands, true);
// Write the clean rule.
- recursiveTarget = this->Makefile->GetStartOutputDirectory();
+ recursiveTarget = this->GetCurrentBinaryDirectory();
recursiveTarget += "/clean";
commands.clear();
depends.clear();
commands.push_back(this->GetRecursiveMakeCall(mf2Dir.c_str(),
- recursiveTarget.c_str()));
+ recursiveTarget));
this->CreateCDCommand(commands,
- this->Makefile->GetHomeOutputDirectory(),
+ this->GetBinaryDirectory(),
cmLocalGenerator::START_OUTPUT);
this->WriteMakeRule(ruleFileStream, "The main clean target", "clean",
depends, commands, true);
@@ -1823,7 +1889,7 @@ void cmLocalUnixMakefileGenerator3
depends, commands, true);
// Write the preinstall rule.
- recursiveTarget = this->Makefile->GetStartOutputDirectory();
+ recursiveTarget = this->GetCurrentBinaryDirectory();
recursiveTarget += "/preinstall";
commands.clear();
depends.clear();
@@ -1840,9 +1906,9 @@ void cmLocalUnixMakefileGenerator3
depends.push_back("cmake_check_build_system");
}
commands.push_back
- (this->GetRecursiveMakeCall(mf2Dir.c_str(), recursiveTarget.c_str()));
+ (this->GetRecursiveMakeCall(mf2Dir.c_str(), recursiveTarget));
this->CreateCDCommand(commands,
- this->Makefile->GetHomeOutputDirectory(),
+ this->GetBinaryDirectory(),
cmLocalGenerator::START_OUTPUT);
this->WriteMakeRule(ruleFileStream, "Prepare targets for installation.",
"preinstall", depends, commands, true);
@@ -1858,12 +1924,12 @@ void cmLocalUnixMakefileGenerator3
std::string runRule =
"$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)";
runRule += " --check-build-system ";
- runRule += this->Convert(cmakefileName.c_str(),cmLocalGenerator::NONE,
+ runRule += this->Convert(cmakefileName,cmLocalGenerator::NONE,
cmLocalGenerator::SHELL);
runRule += " 1";
commands.push_back(runRule);
this->CreateCDCommand(commands,
- this->Makefile->GetHomeOutputDirectory(),
+ this->GetBinaryDirectory(),
cmLocalGenerator::START_OUTPUT);
this->WriteMakeRule(ruleFileStream, "clear depends",
"depend",
@@ -1891,7 +1957,7 @@ void cmLocalUnixMakefileGenerator3::ClearDependencies(cmMakefile* mf,
for(std::vector<std::string>::iterator l = files.begin();
l != files.end(); ++l)
{
- std::string dir = cmSystemTools::GetFilenamePath(l->c_str());
+ std::string dir = cmSystemTools::GetFilenamePath(*l);
// Clear the implicit dependency makefile.
std::string dependFile = dir + "/depend.make";
@@ -1900,13 +1966,14 @@ void cmLocalUnixMakefileGenerator3::ClearDependencies(cmMakefile* mf,
// Remove the internal dependency check file to force
// regeneration.
std::string internalDependFile = dir + "/depend.internal";
- cmSystemTools::RemoveFile(internalDependFile.c_str());
+ cmSystemTools::RemoveFile(internalDependFile);
}
}
void cmLocalUnixMakefileGenerator3
-::WriteDependLanguageInfo(std::ostream& cmakefileStream, cmTarget &target)
+::WriteDependLanguageInfo(std::ostream& cmakefileStream,
+ cmGeneratorTarget* target)
{
ImplicitDependLanguageMap const& implicitLangs =
this->GetImplicitDepends(target);
@@ -1915,11 +1982,11 @@ void cmLocalUnixMakefileGenerator3
cmakefileStream
<< "# The set of languages for which implicit dependencies are needed:\n";
cmakefileStream
- << "SET(CMAKE_DEPENDS_LANGUAGES\n";
+ << "set(CMAKE_DEPENDS_LANGUAGES\n";
for(ImplicitDependLanguageMap::const_iterator
l = implicitLangs.begin(); l != implicitLangs.end(); ++l)
{
- cmakefileStream << " \"" << l->first.c_str() << "\"\n";
+ cmakefileStream << " \"" << l->first << "\"\n";
}
cmakefileStream << " )\n";
@@ -1930,7 +1997,7 @@ void cmLocalUnixMakefileGenerator3
l = implicitLangs.begin(); l != implicitLangs.end(); ++l)
{
cmakefileStream
- << "SET(CMAKE_DEPENDS_CHECK_" << l->first.c_str() << "\n";
+ << "set(CMAKE_DEPENDS_CHECK_" << l->first << "\n";
ImplicitDependFileMap const& implicitPairs = l->second;
// for each file pair
@@ -1950,30 +2017,54 @@ void cmLocalUnixMakefileGenerator3
std::string cidVar = "CMAKE_";
cidVar += l->first;
cidVar += "_COMPILER_ID";
- const char* cid = this->Makefile->GetDefinition(cidVar.c_str());
+ const char* cid = this->Makefile->GetDefinition(cidVar);
if(cid && *cid)
{
cmakefileStream
- << "SET(CMAKE_" << l->first.c_str() << "_COMPILER_ID \""
+ << "set(CMAKE_" << l->first << "_COMPILER_ID \""
<< cid << "\")\n";
}
- }
- // Build a list of preprocessor definitions for the target.
- std::set<std::string> defines;
- this->AddCompileDefinitions(defines, &target,
- this->ConfigurationName.c_str());
- if(!defines.empty())
- {
+ // Build a list of preprocessor definitions for the target.
+ std::set<std::string> defines;
+ this->AddCompileDefinitions(defines, target,
+ this->ConfigName, l->first);
+ if(!defines.empty())
+ {
+ cmakefileStream
+ << "\n"
+ << "# Preprocessor definitions for this target.\n"
+ << "set(CMAKE_TARGET_DEFINITIONS_" << l->first << "\n";
+ for(std::set<std::string>::const_iterator di = defines.begin();
+ di != defines.end(); ++di)
+ {
+ cmakefileStream
+ << " " << cmOutputConverter::EscapeForCMake(*di) << "\n";
+ }
+ cmakefileStream
+ << " )\n";
+ }
+
+ // Target-specific include directories:
cmakefileStream
<< "\n"
- << "# Preprocessor definitions for this target.\n"
- << "SET(CMAKE_TARGET_DEFINITIONS\n";
- for(std::set<std::string>::const_iterator di = defines.begin();
- di != defines.end(); ++di)
+ << "# The include file search paths:\n";
+ cmakefileStream
+ << "set(CMAKE_" << l->first << "_TARGET_INCLUDE_PATH\n";
+ std::vector<std::string> includes;
+
+
+ const std::string& config =
+ this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ this->GetIncludeDirectories(includes, target,
+ l->first, config);
+ for(std::vector<std::string>::iterator i = includes.begin();
+ i != includes.end(); ++i)
{
cmakefileStream
- << " " << this->EscapeForCMake(di->c_str()) << "\n";
+ << " \""
+ << this->Convert(*i, cmLocalGenerator::HOME_OUTPUT)
+ << "\"\n";
}
cmakefileStream
<< " )\n";
@@ -1988,18 +2079,19 @@ void cmLocalUnixMakefileGenerator3
cmSystemTools::ExpandListArgument(xform, transformRules);
}
if(const char* xform =
- target.GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM"))
+ target->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM"))
{
cmSystemTools::ExpandListArgument(xform, transformRules);
}
if(!transformRules.empty())
{
cmakefileStream
- << "SET(CMAKE_INCLUDE_TRANSFORMS\n";
+ << "set(CMAKE_INCLUDE_TRANSFORMS\n";
for(std::vector<std::string>::const_iterator tri = transformRules.begin();
tri != transformRules.end(); ++tri)
{
- cmakefileStream << " " << this->EscapeForCMake(tri->c_str()) << "\n";
+ cmakefileStream << " "
+ << cmOutputConverter::EscapeForCMake(*tri) << "\n";
}
cmakefileStream
<< " )\n";
@@ -2020,7 +2112,7 @@ void cmLocalUnixMakefileGenerator3::WriteDisclaimer(std::ostream& os)
//----------------------------------------------------------------------------
std::string
cmLocalUnixMakefileGenerator3
-::GetRecursiveMakeCall(const char *makefile, const char* tgt)
+::GetRecursiveMakeCall(const char *makefile, const std::string& tgt)
{
// Call make on the given file.
std::string cmd;
@@ -2028,10 +2120,12 @@ cmLocalUnixMakefileGenerator3
cmd += this->Convert(makefile,NONE,SHELL);
cmd += " ";
+ cmGlobalUnixMakefileGenerator3* gg =
+ static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
// Pass down verbosity level.
- if(this->GetMakeSilentFlag().size())
+ if(!gg->MakeSilentFlag.empty())
{
- cmd += this->GetMakeSilentFlag();
+ cmd += gg->MakeSilentFlag;
cmd += " ";
}
@@ -2039,13 +2133,13 @@ cmLocalUnixMakefileGenerator3
// sub-invoked makes via an environment variable. However, some
// makes do not support that, so you have to pass the flags
// explicitly.
- if(this->GetPassMakeflags())
+ if(gg->PassMakeflags)
{
cmd += "-$(MAKEFLAGS) ";
}
// Add the target.
- if (tgt && tgt[0] != '\0')
+ if (!tgt.empty())
{
// The make target is always relative to the top of the build tree.
std::string tgt2 = this->Convert(tgt, HOME_OUTPUT);
@@ -2056,12 +2150,12 @@ cmLocalUnixMakefileGenerator3
// Escape one extra time if the make tool requires it.
if(this->MakeCommandEscapeTargetTwice)
{
- tgt2 = this->EscapeForShell(tgt2.c_str(), true, false);
+ tgt2 = this->EscapeForShell(tgt2, true, false);
}
// The target name is now a string that should be passed verbatim
// on the command line.
- cmd += this->EscapeForShell(tgt2.c_str(), true, false);
+ cmd += this->EscapeForShell(tgt2, true, false);
}
return cmd;
}
@@ -2102,59 +2196,80 @@ cmLocalUnixMakefileGenerator3
//----------------------------------------------------------------------------
std::string
-cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(const char* p)
+cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(const char* p,
+ bool useWatcomQuote)
{
-
// Split the path into its components.
std::vector<std::string> components;
cmSystemTools::SplitPath(p, components);
- // Return an empty path if there are no components.
- if(components.empty())
+ // Open the quoted result.
+ std::string result;
+ if(useWatcomQuote)
{
- return "\"\"";
- }
-
- // Choose a slash direction and fix root component.
- const char* slash = "/";
#if defined(_WIN32) && !defined(__CYGWIN__)
- if(!cmSystemTools::GetForceUnixPaths())
- {
- slash = "\\";
- for(std::string::iterator i = components[0].begin();
- i != components[0].end(); ++i)
- {
- if(*i == '/')
- {
- *i = '\\';
- }
- }
- }
+ result = "'";
+#else
+ result = "\"'";
#endif
+ }
+ else
+ {
+ result = "\"";
+ }
- // Begin the quoted result with the root component.
- std::string result = "\"";
- result += components[0];
-
- // Now add the rest of the components separated by the proper slash
- // direction for this platform.
- bool first = true;
- for(unsigned int i=1; i < components.size(); ++i)
+ // Return an empty path if there are no components.
+ if(!components.empty())
{
- // Only the last component can be empty to avoid double slashes.
- if(components[i].length() > 0 || (i == (components.size()-1)))
+ // Choose a slash direction and fix root component.
+ const char* slash = "/";
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if(!cmSystemTools::GetForceUnixPaths())
{
- if(!first)
+ slash = "\\";
+ for(std::string::iterator i = components[0].begin();
+ i != components[0].end(); ++i)
{
- result += slash;
+ if(*i == '/')
+ {
+ *i = '\\';
+ }
}
- result += components[i];
- first = false;
+ }
+#endif
+
+ // Begin the quoted result with the root component.
+ result += components[0];
+
+ if (components.size() > 1)
+ {
+ // Now add the rest of the components separated by the proper slash
+ // direction for this platform.
+ std::vector<std::string>::const_iterator compEnd
+ = std::remove(components.begin() + 1, components.end() - 1,
+ std::string());
+ std::vector<std::string>::const_iterator compStart
+ = components.begin() + 1;
+ result += cmJoin(cmMakeRange(compStart, compEnd), slash);
+ // Only the last component can be empty to avoid double slashes.
+ result += slash;
+ result += components.back();
}
}
// Close the quoted result.
- result += "\"";
+ if(useWatcomQuote)
+ {
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ result += "'";
+#else
+ result += "'\"";
+#endif
+ }
+ else
+ {
+ result += "\"";
+ }
return result;
}
@@ -2162,10 +2277,10 @@ cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(const char* p)
//----------------------------------------------------------------------------
std::string
cmLocalUnixMakefileGenerator3
-::GetTargetDirectory(cmTarget const& target) const
+::GetTargetDirectory(cmGeneratorTarget const* target) const
{
std::string dir = cmake::GetCMakeFilesDirectoryPostSlash();
- dir += target.GetName();
+ dir += target->GetName();
#if defined(__VMS)
dir += "_dir";
#else
@@ -2176,19 +2291,20 @@ cmLocalUnixMakefileGenerator3
//----------------------------------------------------------------------------
cmLocalUnixMakefileGenerator3::ImplicitDependLanguageMap const&
-cmLocalUnixMakefileGenerator3::GetImplicitDepends(cmTarget const& tgt)
+cmLocalUnixMakefileGenerator3::GetImplicitDepends(
+ const cmGeneratorTarget* tgt)
{
- return this->ImplicitDepends[tgt.GetName()];
+ return this->ImplicitDepends[tgt->GetName()];
}
//----------------------------------------------------------------------------
void
-cmLocalUnixMakefileGenerator3::AddImplicitDepends(cmTarget const& tgt,
- const char* lang,
+cmLocalUnixMakefileGenerator3::AddImplicitDepends(const cmGeneratorTarget* tgt,
+ const std::string& lang,
const char* obj,
const char* src)
{
- this->ImplicitDepends[tgt.GetName()][lang][obj].push_back(src);
+ this->ImplicitDepends[tgt->GetName()][lang][obj].push_back(src);
}
//----------------------------------------------------------------------------
@@ -2208,9 +2324,11 @@ void cmLocalUnixMakefileGenerator3
// used by NMake and Borland make does not support "cd /d" so this
// feature simply cannot work with them (Borland make does not even
// support changing the drive letter with just "d:").
- const char* cd_cmd = this->MinGWMake? "cd /d " : "cd ";
+ const char* cd_cmd = this->IsMinGWMake() ? "cd /d " : "cd ";
- if(!this->UnixCD)
+ cmGlobalUnixMakefileGenerator3* gg =
+ static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
+ if(!gg->UnixCD)
{
// On Windows we must perform each step separately and then change
// back because the shell keeps the working directory between
@@ -2229,14 +2347,10 @@ void cmLocalUnixMakefileGenerator3
// On UNIX we must construct a single shell command to change
// directory and build because make resets the directory between
// each command.
- std::vector<std::string>::iterator i = commands.begin();
- for (; i != commands.end(); ++i)
- {
- std::string cmd = cd_cmd;
- cmd += this->ConvertToOutputForExisting(tgtDir, relRetDir);
- cmd += " && ";
- cmd += *i;
- *i = cmd;
- }
+ std::string outputForExisting =
+ this->ConvertToOutputForExisting(tgtDir, relRetDir);
+ std::string prefix = cd_cmd + outputForExisting + " && ";
+ std::transform(commands.begin(), commands.end(), commands.begin(),
+ std::bind1st(std::plus<std::string>(), prefix));
}
}
diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h
index 703369e1c..8f6931170 100644
--- a/Source/cmLocalUnixMakefileGenerator3.h
+++ b/Source/cmLocalUnixMakefileGenerator3.h
@@ -12,16 +12,15 @@
#ifndef cmLocalUnixMakefileGenerator3_h
#define cmLocalUnixMakefileGenerator3_h
-#include "cmLocalGenerator.h"
+#include "cmLocalCommonGenerator.h"
// for cmDepends::DependencyVector
#include "cmDepends.h"
class cmCustomCommand;
-class cmDependInformation;
+class cmCustomCommandGenerator;
class cmDepends;
class cmMakefileTargetGenerator;
-class cmTarget;
class cmSourceFile;
/** \class cmLocalUnixMakefileGenerator3
@@ -30,24 +29,19 @@ class cmSourceFile;
* cmLocalUnixMakefileGenerator3 produces a LocalUnix makefile from its
* member Makefile.
*/
-class cmLocalUnixMakefileGenerator3 : public cmLocalGenerator
+class cmLocalUnixMakefileGenerator3 : public cmLocalCommonGenerator
{
public:
- cmLocalUnixMakefileGenerator3();
+ cmLocalUnixMakefileGenerator3(cmGlobalGenerator* gg, cmMakefile* mf);
virtual ~cmLocalUnixMakefileGenerator3();
- /**
- * Process the CMakeLists files for this directory to fill in the
- * Makefile ivar
- */
- virtual void Configure();
+ virtual void ComputeHomeRelativeOutputPath();
/**
* Generate the makefile for this directory.
*/
virtual void Generate();
-
// this returns the relative path between the HomeOutputDirectory and this
// local generators StartOutputDirectory
const std::string &GetHomeRelativeOutputPath();
@@ -55,7 +49,7 @@ public:
// Write out a make rule
void WriteMakeRule(std::ostream& os,
const char* comment,
- const char* target,
+ const std::string& target,
const std::vector<std::string>& depends,
const std::vector<std::string>& commands,
bool symbolic,
@@ -65,86 +59,11 @@ public:
void WriteMakeVariables(std::ostream& makefileStream);
/**
- * If true, then explicitly pass MAKEFLAGS on the make all target for makes
- * that do not use environment variables.
- *
- */
- void SetPassMakeflags(bool s){this->PassMakeflags = s;}
- bool GetPassMakeflags() { return this->PassMakeflags; }
-
- /**
- * Set the flag used to keep the make program silent.
- */
- void SetMakeSilentFlag(const char* s) { this->MakeSilentFlag = s; }
- std::string &GetMakeSilentFlag() { return this->MakeSilentFlag; }
-
- /**
- * Set to true if the shell being used is the windows shell.
- * This controls if statements in the makefile and the SHELL variable.
- * The default is false.
- */
- void SetWindowsShell(bool v) {this->WindowsShell = v;}
-
- /**
- * Set to true if the make tool being used is Watcom WMake.
- */
- void SetWatcomWMake(bool v) {this->WatcomWMake = v;}
-
- /**
- * Set to true if the make tool being used is MinGW Make.
- */
- void SetMinGWMake(bool v) {this->MinGWMake = v;}
-
- /**
- * Set to true if the make tool being used is NMake.
- */
- void SetNMake(bool v) {this->NMake = v;}
-
- /**
- * Set to true if the shell being used is the MSYS shell.
- * This controls if statements in the makefile and the SHELL variable.
- * The default is false.
- */
- void SetMSYSShell(bool v) {this->MSYSShell = v;}
-
- /**
- * If set to true, then NULL is set to nil for non Windows_NT.
- * This uses make syntax used by nmake and borland.
- * The default is false.
- */
- void SetDefineWindowsNULL(bool v) {this->DefineWindowsNULL = v;}
-
- /**
- * If set to true, cd dir && command is used to
- * run commands in a different directory.
- */
- void SetUnixCD(bool v) {this->UnixCD = v;}
-
- /**
- * Set Support Verbose Variable. If true, then .SILENT will
- * be not end with : i.e. .SILENT: or .SILENT
- */
- void SetSilentNoColon(bool v) {this->SilentNoColon = v;}
-
- /**
- * Set the string used to include one makefile into another default
- * is include.
- */
- void SetIncludeDirective(const char* s) { this->IncludeDirective = s; }
- const char *GetIncludeDirective() { return this->IncludeDirective.c_str(); }
-
- /**
* Set max makefile variable size, default is 0 which means unlimited.
*/
void SetMakefileVariableSize(int s) { this->MakefileVariableSize = s; }
/**
- * If ignore lib prefix is true, then do not strip lib from the name
- * of a library.
- */
- void SetIgnoreLibPrefix(bool s) { this->IgnoreLibPrefix = s; }
-
- /**
* Set whether passing a make target on a command line requires an
* extra level of escapes.
*/
@@ -168,30 +87,36 @@ public:
void WriteDivider(std::ostream& os);
/** used to create a recursive make call */
- std::string GetRecursiveMakeCall(const char *makefile, const char* tgt);
+ std::string GetRecursiveMakeCall(const char *makefile,
+ const std::string& tgt);
// append flags to a string
+ virtual void AppendFlags(std::string& flags, const std::string& newFlags);
virtual void AppendFlags(std::string& flags, const char* newFlags);
// append an echo command
enum EchoColor { EchoNormal, EchoDepend, EchoBuild, EchoLink,
EchoGenerate, EchoGlobal };
- void AppendEcho(std::vector<std::string>& commands, const char* text,
- EchoColor color = EchoNormal);
+ struct EchoProgress { std::string Dir; std::string Arg; };
+ void AppendEcho(std::vector<std::string>& commands, std::string const& text,
+ EchoColor color = EchoNormal, EchoProgress const* = 0);
/** Get whether the makefile is to have color. */
bool GetColorMakefile() const { return this->ColorMakefile; }
- virtual std::string GetTargetDirectory(cmTarget const& target) const;
+ virtual
+ std::string GetTargetDirectory(cmGeneratorTarget const* target) const;
// create a command that cds to the start dir then runs the commands
void CreateCDCommand(std::vector<std::string>& commands,
const char *targetDir,
cmLocalGenerator::RelativeRoot returnDir);
- static std::string ConvertToQuotedOutputPath(const char* p);
+ static std::string ConvertToQuotedOutputPath(const char* p,
+ bool useWatcomQuote);
- std::string CreateMakeVariable(const char* sin, const char* s2in);
+ std::string CreateMakeVariable(const std::string& sin,
+ const std::string& s2in);
/** Called from command-line hook to bring dependencies up to date
for a target. */
@@ -205,32 +130,27 @@ public:
void WriteSpecialTargetsTop(std::ostream& makefileStream);
void WriteSpecialTargetsBottom(std::ostream& makefileStream);
- std::string GetRelativeTargetDirectory(cmTarget const& target);
+ std::string GetRelativeTargetDirectory(cmGeneratorTarget* target);
// File pairs for implicit dependency scanning. The key of the map
// is the depender and the value is the explicit dependee.
struct ImplicitDependFileMap:
- public std::map<cmStdString, cmDepends::DependencyVector> {};
+ public std::map<std::string, cmDepends::DependencyVector> {};
struct ImplicitDependLanguageMap:
- public std::map<cmStdString, ImplicitDependFileMap> {};
+ public std::map<std::string, ImplicitDependFileMap> {};
struct ImplicitDependTargetMap:
- public std::map<cmStdString, ImplicitDependLanguageMap> {};
- ImplicitDependLanguageMap const& GetImplicitDepends(cmTarget const& tgt);
+ public std::map<std::string, ImplicitDependLanguageMap> {};
+ ImplicitDependLanguageMap const&
+ GetImplicitDepends(cmGeneratorTarget const* tgt);
- void AddImplicitDepends(cmTarget const& tgt, const char* lang,
+ void AddImplicitDepends(cmGeneratorTarget const* tgt,
+ const std::string& lang,
const char* obj, const char* src);
- void AppendGlobalTargetDepends(std::vector<std::string>& depends,
- cmTarget& target);
-
// write the target rules for the local Makefile into the stream
void WriteLocalAllRules(std::ostream& ruleFileStream);
- void AddLocalObjectFile(cmTarget* target, cmSourceFile* sf,
- std::string objNoTargetDir,
- bool hasSourceExtension);
-
- std::vector<cmStdString> const& GetLocalHelp() { return this->LocalHelp; }
+ std::vector<std::string> const& GetLocalHelp() { return this->LocalHelp; }
/** Get whether to create rules to generate preprocessed and
assembly sources. This could be converted to a variable lookup
@@ -255,14 +175,15 @@ protected:
// write the target rules for the local Makefile into the stream
void WriteLocalMakefileTargets(std::ostream& ruleFileStream,
- std::set<cmStdString> &emitted);
+ std::set<std::string> &emitted);
// this method Writes the Directory information files
void WriteDirectoryInformationFile();
// write the depend info
- void WriteDependLanguageInfo(std::ostream& cmakefileStream, cmTarget &tgt);
+ void WriteDependLanguageInfo(std::ostream& cmakefileStream,
+ cmGeneratorTarget *tgt);
// write the local help rule
void WriteHelpRule(std::ostream& ruleFileStream);
@@ -273,16 +194,16 @@ protected:
void WriteConvenienceRule(std::ostream& ruleFileStream,
- const char* realTarget,
- const char* helpTarget);
+ const std::string& realTarget,
+ const std::string& helpTarget);
void WriteTargetDependRule(std::ostream& ruleFileStream,
- cmTarget& target);
+ cmGeneratorTarget* target);
void WriteTargetCleanRule(std::ostream& ruleFileStream,
- cmTarget& target,
+ cmGeneratorTarget* target,
const std::vector<std::string>& files);
void WriteTargetRequiresRule(std::ostream& ruleFileStream,
- cmTarget& target,
+ cmGeneratorTarget* target,
const std::vector<std::string>& objects);
void AppendRuleDepend(std::vector<std::string>& depends,
@@ -292,22 +213,22 @@ protected:
void AppendCustomDepends(std::vector<std::string>& depends,
const std::vector<cmCustomCommand>& ccs);
void AppendCustomDepend(std::vector<std::string>& depends,
- const cmCustomCommand& cc);
+ cmCustomCommandGenerator const& cc);
void AppendCustomCommands(std::vector<std::string>& commands,
const std::vector<cmCustomCommand>& ccs,
- cmTarget* target,
+ cmGeneratorTarget* target,
cmLocalGenerator::RelativeRoot relative =
cmLocalGenerator::HOME_OUTPUT);
void AppendCustomCommand(std::vector<std::string>& commands,
- const cmCustomCommand& cc,
- cmTarget* target,
+ cmCustomCommandGenerator const& ccg,
+ cmGeneratorTarget* target,
bool echo_comment=false,
cmLocalGenerator::RelativeRoot relative =
cmLocalGenerator::HOME_OUTPUT,
std::ostream* content = 0);
void AppendCleanCommand(std::vector<std::string>& commands,
const std::vector<std::string>& files,
- cmTarget& target, const char* filename =0);
+ cmGeneratorTarget* target, const char* filename =0);
// Helper methods for dependeny updates.
bool ScanDependencies(const char* targetDir,
@@ -316,8 +237,12 @@ protected:
private:
std::string ConvertShellCommand(std::string const& cmd, RelativeRoot root);
- std::string MakeLauncher(const cmCustomCommand& cc, cmTarget* target,
- RelativeRoot relative);
+ std::string MakeLauncher(cmCustomCommandGenerator const& ccg,
+ cmGeneratorTarget* target, RelativeRoot relative);
+
+ virtual void ComputeObjectFilenames(
+ std::map<cmSourceFile const*, std::string>& mapping,
+ cmGeneratorTarget const* gt = 0);
friend class cmMakefileTargetGenerator;
friend class cmMakefileExecutableTargetGenerator;
@@ -327,38 +252,14 @@ private:
ImplicitDependTargetMap ImplicitDepends;
- //==========================================================================
- // Configuration settings.
- int MakefileVariableSize;
- std::string IncludeDirective;
- std::string MakeSilentFlag;
- std::string ConfigurationName;
- bool DefineWindowsNULL;
- bool UnixCD;
- bool PassMakeflags;
- bool SilentNoColon;
- bool MakeCommandEscapeTargetTwice;
- bool BorlandMakeCurlyHack;
- //==========================================================================
-
std::string HomeRelativeOutputPath;
- /* Copy the setting of CMAKE_COLOR_MAKEFILE from the makefile at the
- beginning of generation to avoid many duplicate lookups. */
- bool ColorMakefile;
-
- /* Copy the setting of CMAKE_SKIP_PREPROCESSED_SOURCE_RULES and
- CMAKE_SKIP_ASSEMBLY_SOURCE_RULES at the beginning of generation to
- avoid many duplicate lookups. */
- bool SkipPreprocessedSourceRules;
- bool SkipAssemblySourceRules;
-
struct LocalObjectEntry
{
- cmTarget* Target;
+ cmGeneratorTarget* Target;
std::string Language;
LocalObjectEntry(): Target(0), Language() {}
- LocalObjectEntry(cmTarget* t, const char* lang):
+ LocalObjectEntry(cmGeneratorTarget* t, const std::string& lang):
Target(t), Language(lang) {}
};
struct LocalObjectInfo: public std::vector<LocalObjectEntry>
@@ -369,16 +270,25 @@ private:
LocalObjectInfo():HasSourceExtension(false), HasPreprocessRule(false),
HasAssembleRule(false) {}
};
- std::map<cmStdString, LocalObjectInfo> LocalObjectFiles;
+ void GetLocalObjectFiles(
+ std::map<std::string, LocalObjectInfo> &localObjectFiles);
+
void WriteObjectConvenienceRule(std::ostream& ruleFileStream,
const char* comment, const char* output,
LocalObjectInfo const& info);
- std::vector<cmStdString> LocalHelp;
+ std::vector<std::string> LocalHelp;
/* does the work for each target */
- std::map<cmStdString, cmStdString> MakeVariableMap;
- std::map<cmStdString, cmStdString> ShortMakeVariableMap;
+ std::map<std::string, std::string> MakeVariableMap;
+ std::map<std::string, std::string> ShortMakeVariableMap;
+
+ int MakefileVariableSize;
+ bool MakeCommandEscapeTargetTwice;
+ bool BorlandMakeCurlyHack;
+ bool ColorMakefile;
+ bool SkipPreprocessedSourceRules;
+ bool SkipAssemblySourceRules;
};
#endif
diff --git a/Source/cmLocalVisualStudio10Generator.cxx b/Source/cmLocalVisualStudio10Generator.cxx
index c3789a022..d0784add2 100644
--- a/Source/cmLocalVisualStudio10Generator.cxx
+++ b/Source/cmLocalVisualStudio10Generator.cxx
@@ -10,7 +10,6 @@
See the License for more information.
============================================================================*/
#include "cmLocalVisualStudio10Generator.h"
-#include "cmTarget.h"
#include "cmMakefile.h"
#include "cmVisualStudio10TargetGenerator.h"
#include "cmGlobalVisualStudio10Generator.h"
@@ -19,7 +18,7 @@
class cmVS10XMLParser : public cmXMLParser
{
public:
- virtual void EndElement(const char* /* name */)
+ virtual void EndElement(const std::string& /* name */)
{
}
virtual void CharacterDataHandler(const char* data, int length)
@@ -30,14 +29,14 @@ class cmVS10XMLParser : public cmXMLParser
this->DoGUID = false;
}
}
- virtual void StartElement(const char* name, const char**)
+ virtual void StartElement(const std::string& name, const char**)
{
// once the GUID is found do nothing
- if(this->GUID.size())
+ if(!this->GUID.empty())
{
return;
}
- if(strcmp("ProjectGUID", name) == 0 || strcmp("ProjectGuid", name) == 0)
+ if("ProjectGUID" == name || "ProjectGuid" == name)
{
this->DoGUID = true;
}
@@ -61,8 +60,9 @@ class cmVS10XMLParser : public cmXMLParser
//----------------------------------------------------------------------------
-cmLocalVisualStudio10Generator::cmLocalVisualStudio10Generator(VSVersion v):
- cmLocalVisualStudio7Generator(v)
+cmLocalVisualStudio10Generator
+::cmLocalVisualStudio10Generator(cmGlobalGenerator* gg, cmMakefile* mf):
+ cmLocalVisualStudio7Generator(gg, mf)
{
}
@@ -73,18 +73,23 @@ cmLocalVisualStudio10Generator::~cmLocalVisualStudio10Generator()
void cmLocalVisualStudio10Generator::Generate()
{
- cmTargets &tgts = this->Makefile->GetTargets();
- for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); ++l)
+ std::vector<cmGeneratorTarget*> tgts = this->GetGeneratorTargets();
+ for(std::vector<cmGeneratorTarget*>::iterator l = tgts.begin();
+ l != tgts.end(); ++l)
{
+ if((*l)->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ continue;
+ }
if(static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator)
- ->TargetIsFortranOnly(l->second))
+ ->TargetIsFortranOnly(*l))
{
- this->CreateSingleVCProj(l->first.c_str(),l->second);
+ this->CreateSingleVCProj((*l)->GetName().c_str(), *l);
}
else
{
cmVisualStudio10TargetGenerator tg(
- &l->second, static_cast<cmGlobalVisualStudio10Generator*>(
+ *l, static_cast<cmGlobalVisualStudio10Generator*>(
this->GetGlobalGenerator()));
tg.Generate();
}
@@ -94,16 +99,15 @@ void cmLocalVisualStudio10Generator::Generate()
void cmLocalVisualStudio10Generator
-::ReadAndStoreExternalGUID(const char* name,
+::ReadAndStoreExternalGUID(const std::string& name,
const char* path)
{
cmVS10XMLParser parser;
parser.ParseFile(path);
- // if we can not find a GUID then create one
+ // if we can not find a GUID then we will generate one later
if(parser.GUID.empty())
{
- this->GlobalGenerator->CreateGUID(name);
return;
}
@@ -114,7 +118,7 @@ void cmLocalVisualStudio10Generator
AddCacheEntry(guidStoreName.c_str(),
parser.GUID.c_str(),
"Stored GUID",
- cmCacheManager::INTERNAL);
+ cmState::INTERNAL);
}
//----------------------------------------------------------------------------
diff --git a/Source/cmLocalVisualStudio10Generator.h b/Source/cmLocalVisualStudio10Generator.h
index 41db735b2..e18759096 100644
--- a/Source/cmLocalVisualStudio10Generator.h
+++ b/Source/cmLocalVisualStudio10Generator.h
@@ -25,7 +25,7 @@ class cmLocalVisualStudio10Generator : public cmLocalVisualStudio7Generator
{
public:
///! Set cache only and recurse to false by default.
- cmLocalVisualStudio10Generator(VSVersion v);
+ cmLocalVisualStudio10Generator(cmGlobalGenerator* gg, cmMakefile* mf);
virtual ~cmLocalVisualStudio10Generator();
@@ -34,7 +34,7 @@ public:
* Generate the makefile for this directory.
*/
virtual void Generate();
- virtual void ReadAndStoreExternalGUID(const char* name,
+ virtual void ReadAndStoreExternalGUID(const std::string& name,
const char* path);
protected:
diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx
index e5b4057d2..cdacb9ec6 100644
--- a/Source/cmLocalVisualStudio6Generator.cxx
+++ b/Source/cmLocalVisualStudio6Generator.cxx
@@ -14,16 +14,18 @@
#include "cmMakefile.h"
#include "cmSystemTools.h"
#include "cmSourceFile.h"
-#include "cmCacheManager.h"
#include "cmGeneratorTarget.h"
+#include "cmCustomCommandGenerator.h"
#include "cmake.h"
#include "cmComputeLinkInformation.h"
#include <cmsys/RegularExpression.hxx>
+#include <cmsys/FStream.hxx>
-cmLocalVisualStudio6Generator::cmLocalVisualStudio6Generator():
- cmLocalVisualStudioGenerator(VS6)
+cmLocalVisualStudio6Generator
+::cmLocalVisualStudio6Generator(cmGlobalGenerator* gg, cmMakefile* mf):
+ cmLocalVisualStudioGenerator(gg, mf)
{
}
@@ -37,7 +39,7 @@ class cmLocalVisualStudio6Generator::EventWriter
{
public:
EventWriter(cmLocalVisualStudio6Generator* lg,
- const char* config, std::string& code):
+ const std::string& config, std::string& code):
LG(lg), Config(config), Code(code), First(true) {}
void Start(const char* event)
{
@@ -58,6 +60,7 @@ public:
}
void Write(cmCustomCommand const& cc)
{
+ cmCustomCommandGenerator ccg(cc, this->Config, this->LG);
if(this->First)
{
this->Code += this->Event + "_Cmds=";
@@ -67,37 +70,35 @@ public:
{
this->Code += "\\\n\t";
}
- this->Code += this->LG->ConstructScript(cc, this->Config, "\\\n\t");
+ this->Code += this->LG->ConstructScript(ccg, "\\\n\t");
}
private:
cmLocalVisualStudio6Generator* LG;
- const char* Config;
+ std::string Config;
std::string& Code;
bool First;
std::string Event;
};
-void cmLocalVisualStudio6Generator::AddHelperCommands()
-{
- std::set<cmStdString> lang;
- lang.insert("C");
- lang.insert("CXX");
- this->CreateCustomTargetsAndCommands(lang);
-}
-
void cmLocalVisualStudio6Generator::AddCMakeListsRules()
{
- cmTargets &tgts = this->Makefile->GetTargets();
- for(cmTargets::iterator l = tgts.begin();
- l != tgts.end(); l++)
+ std::vector<cmGeneratorTarget*> tgts = this->GetGeneratorTargets();
+ for(std::vector<cmGeneratorTarget*>::iterator l = tgts.begin();
+ l != tgts.end(); ++l)
{
+ if ((*l)->GetType() == cmState::INTERFACE_LIBRARY
+ || (*l)->GetType() == cmState::GLOBAL_TARGET)
+ {
+ continue;
+ }
+
// Add a rule to regenerate the build system when the target
// specification source changes.
const char* suppRegenRule =
this->Makefile->GetDefinition("CMAKE_SUPPRESS_REGENERATION");
if (!cmSystemTools::IsOn(suppRegenRule))
{
- this->AddDSPBuildRule(l->second);
+ this->AddDSPBuildRule(*l);
}
}
}
@@ -110,65 +111,69 @@ void cmLocalVisualStudio6Generator::Generate()
void cmLocalVisualStudio6Generator::OutputDSPFile()
{
// If not an in source build, then create the output directory
- if(strcmp(this->Makefile->GetStartOutputDirectory(),
- this->Makefile->GetHomeDirectory()) != 0)
+ if(strcmp(this->GetCurrentBinaryDirectory(),
+ this->GetSourceDirectory()) != 0)
{
if(!cmSystemTools::MakeDirectory
- (this->Makefile->GetStartOutputDirectory()))
+ (this->GetCurrentBinaryDirectory()))
{
cmSystemTools::Error("Error creating directory ",
- this->Makefile->GetStartOutputDirectory());
+ this->GetCurrentBinaryDirectory());
}
}
// Create the DSP or set of DSP's for libraries and executables
- cmTargets &tgts = this->Makefile->GetTargets();
-
- // build any targets
- for(cmTargets::iterator l = tgts.begin();
- l != tgts.end(); l++)
+ std::vector<cmGeneratorTarget*> tgts = this->GetGeneratorTargets();
+ for(std::vector<cmGeneratorTarget*>::iterator l = tgts.begin();
+ l != tgts.end(); ++l)
{
- switch(l->second.GetType())
+ switch((*l)->GetType())
{
- case cmTarget::STATIC_LIBRARY:
- case cmTarget::OBJECT_LIBRARY:
- this->SetBuildType(STATIC_LIBRARY, l->first.c_str(), l->second);
+ case cmState::STATIC_LIBRARY:
+ case cmState::OBJECT_LIBRARY:
+ this->SetBuildType(STATIC_LIBRARY,
+ (*l)->GetName().c_str(), *l);
break;
- case cmTarget::SHARED_LIBRARY:
- case cmTarget::MODULE_LIBRARY:
- this->SetBuildType(DLL, l->first.c_str(), l->second);
+ case cmState::SHARED_LIBRARY:
+ case cmState::MODULE_LIBRARY:
+ this->SetBuildType(DLL,
+ (*l)->GetName().c_str(), *l);
break;
- case cmTarget::EXECUTABLE:
- this->SetBuildType(EXECUTABLE,l->first.c_str(), l->second);
+ case cmState::EXECUTABLE:
+ this->SetBuildType(EXECUTABLE,
+ (*l)->GetName().c_str(), *l);
break;
- case cmTarget::UTILITY:
- case cmTarget::GLOBAL_TARGET:
- this->SetBuildType(UTILITY, l->first.c_str(), l->second);
+ case cmState::UTILITY:
+ case cmState::GLOBAL_TARGET:
+ this->SetBuildType(UTILITY,
+ (*l)->GetName().c_str(), *l);
break;
+ case cmState::INTERFACE_LIBRARY:
+ continue;
default:
- cmSystemTools::Error("Bad target type", l->first.c_str());
+ cmSystemTools::Error("Bad target type: ", (*l)->GetName().c_str());
break;
}
// INCLUDE_EXTERNAL_MSPROJECT command only affects the workspace
// so don't build a projectfile for it
const char* path =
- l->second.GetProperty("EXTERNAL_MSPROJECT");
+ (*l)->GetProperty("EXTERNAL_MSPROJECT");
if(!path)
{
// check to see if the dsp is going into a sub-directory
- std::string::size_type pos = l->first.rfind('/');
+ std::string::size_type pos = (*l)->GetName().rfind('/');
if(pos != std::string::npos)
{
- std::string dir = this->Makefile->GetStartOutputDirectory();
+ std::string dir = this->GetCurrentBinaryDirectory();
dir += "/";
- dir += l->first.substr(0, pos);
+ dir += (*l)->GetName().substr(0, pos);
if(!cmSystemTools::MakeDirectory(dir.c_str()))
{
- cmSystemTools::Error("Error creating directory ", dir.c_str());
+ cmSystemTools::Error("Error creating directory: ", dir.c_str());
}
}
- this->CreateSingleDSP(l->first.c_str(),l->second);
+ this->CreateSingleDSP((*l)->GetName().c_str(), *l);
}
}
}
@@ -178,22 +183,22 @@ void cmLocalVisualStudio6Generator::OutputDSPFile()
//
extern std::string GetVS6TargetName(const std::string& targetName);
-void cmLocalVisualStudio6Generator::CreateSingleDSP(const char *lname,
- cmTarget &target)
+void cmLocalVisualStudio6Generator::CreateSingleDSP(const std::string& lname,
+ cmGeneratorTarget* target)
{
// add to the list of projects
std::string pname = GetVS6TargetName(lname);
// create the dsp.cmake file
std::string fname;
- fname = this->Makefile->GetStartOutputDirectory();
+ fname = this->GetCurrentBinaryDirectory();
fname += "/";
fname += pname;
fname += ".dsp";
// save the name of the real dsp file
std::string realDSP = fname;
fname += ".cmake";
- std::ofstream fout(fname.c_str());
+ cmsys::ofstream fout(fname.c_str());
if(!fout)
{
cmSystemTools::Error("Error Writing ", fname.c_str());
@@ -206,15 +211,13 @@ void cmLocalVisualStudio6Generator::CreateSingleDSP(const char *lname,
}
-void cmLocalVisualStudio6Generator::AddDSPBuildRule(cmTarget& tgt)
+void cmLocalVisualStudio6Generator::AddDSPBuildRule(cmGeneratorTarget *tgt)
{
- std::string dspname = GetVS6TargetName(tgt.GetName());
+ std::string dspname = GetVS6TargetName(tgt->GetName());
dspname += ".dsp.cmake";
- const char* dsprule =
- this->Makefile->GetRequiredDefinition("CMAKE_COMMAND");
cmCustomCommandLine commandLine;
- commandLine.push_back(dsprule);
- std::string makefileIn = this->Makefile->GetStartDirectory();
+ commandLine.push_back(cmSystemTools::GetCMakeCommand());
+ std::string makefileIn = this->GetCurrentSourceDirectory();
makefileIn += "/";
makefileIn += "CMakeLists.txt";
if(!cmSystemTools::FileExists(makefileIn.c_str()))
@@ -225,13 +228,10 @@ void cmLocalVisualStudio6Generator::AddDSPBuildRule(cmTarget& tgt)
comment += makefileIn;
std::string args;
args = "-H";
- args += this->Convert(this->Makefile->GetHomeDirectory(),
- START_OUTPUT, UNCHANGED, true);
+ args += this->GetSourceDirectory();
commandLine.push_back(args);
args = "-B";
- args +=
- this->Convert(this->Makefile->GetHomeOutputDirectory(),
- START_OUTPUT, UNCHANGED, true);
+ args += this->GetBinaryDirectory();
commandLine.push_back(args);
std::vector<std::string> const& listFiles = this->Makefile->GetListFiles();
@@ -243,9 +243,9 @@ void cmLocalVisualStudio6Generator::AddDSPBuildRule(cmTarget& tgt)
makefileIn.c_str(), commandLines,
comment.c_str(),
no_working_directory, true);
- if(cmSourceFile* file = this->Makefile->GetSource(makefileIn.c_str()))
+ if(this->Makefile->GetSource(makefileIn.c_str()))
{
- tgt.AddSourceFile(file);
+ tgt->AddSource(makefileIn);
}
else
{
@@ -255,8 +255,8 @@ void cmLocalVisualStudio6Generator::AddDSPBuildRule(cmTarget& tgt)
void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
- const char *libName,
- cmTarget &target)
+ const std::string& libName,
+ cmGeneratorTarget *target)
{
// For utility targets need custom command since pre- and post-
// build does not do anything in Visual Studio 6. In order for the
@@ -264,23 +264,23 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
// special care for dependencies. The first rule must depend on all
// the dependencies of all the rules. The later rules must each
// depend only on the previous rule.
- if ((target.GetType() == cmTarget::UTILITY ||
- target.GetType() == cmTarget::GLOBAL_TARGET) &&
- (!target.GetPreBuildCommands().empty() ||
- !target.GetPostBuildCommands().empty()))
+ if ((target->GetType() == cmState::UTILITY ||
+ target->GetType() == cmState::GLOBAL_TARGET) &&
+ (!target->GetPreBuildCommands().empty() ||
+ !target->GetPostBuildCommands().empty()))
{
// Accumulate the dependencies of all the commands.
std::vector<std::string> depends;
for (std::vector<cmCustomCommand>::const_iterator cr =
- target.GetPreBuildCommands().begin();
- cr != target.GetPreBuildCommands().end(); ++cr)
+ target->GetPreBuildCommands().begin();
+ cr != target->GetPreBuildCommands().end(); ++cr)
{
depends.insert(depends.end(),
cr->GetDepends().begin(), cr->GetDepends().end());
}
for (std::vector<cmCustomCommand>::const_iterator cr =
- target.GetPostBuildCommands().begin();
- cr != target.GetPostBuildCommands().end(); ++cr)
+ target->GetPostBuildCommands().begin();
+ cr != target->GetPostBuildCommands().end(); ++cr)
{
depends.insert(depends.end(),
cr->GetDepends().begin(), cr->GetDepends().end());
@@ -289,14 +289,14 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
// Add the pre- and post-build commands in order.
int count = 1;
for (std::vector<cmCustomCommand>::const_iterator cr =
- target.GetPreBuildCommands().begin();
- cr != target.GetPreBuildCommands().end(); ++cr)
+ target->GetPreBuildCommands().begin();
+ cr != target->GetPreBuildCommands().end(); ++cr)
{
this->AddUtilityCommandHack(target, count++, depends, *cr);
}
for (std::vector<cmCustomCommand>::const_iterator cr =
- target.GetPostBuildCommands().begin();
- cr != target.GetPostBuildCommands().end(); ++cr)
+ target->GetPostBuildCommands().begin();
+ cr != target->GetPostBuildCommands().end(); ++cr)
{
this->AddUtilityCommandHack(target, count++, depends, *cr);
}
@@ -306,18 +306,27 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
// get the classes from the source lists then add them to the groups
- std::vector<cmSourceFile*> const & classes = target.GetSourceFiles();
+ std::vector<cmSourceFile*> classes;
+ if (!target->GetConfigCommonSourceFiles(classes))
+ {
+ return;
+ }
// now all of the source files have been properly assigned to the target
// now stick them into source groups using the reg expressions
for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
i != classes.end(); i++)
{
+ if (!(*i)->GetObjectLibrary().empty())
+ {
+ continue;
+ }
+
// Add the file to the list of sources.
std::string source = (*i)->GetFullPath();
- cmSourceGroup& sourceGroup =
+ cmSourceGroup* sourceGroup =
this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
- sourceGroup.AssignSource(*i);
+ sourceGroup->AssignSource(*i);
// while we are at it, if it is a .rule file then for visual studio 6 we
// must generate it
if ((*i)->GetPropertyAsBool("__CMAKE_RULE"))
@@ -329,11 +338,11 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
std::string path = cmSystemTools::GetFilenamePath(source);
cmSystemTools::MakeDirectory(path.c_str());
#if defined(_WIN32) || defined(__CYGWIN__)
- std::ofstream sourceFout(source.c_str(),
+ cmsys::ofstream sourceFout(source.c_str(),
std::ios::binary | std::ios::out
| std::ios::trunc);
#else
- std::ofstream sourceFout(source.c_str(),
+ cmsys::ofstream sourceFout(source.c_str(),
std::ios::out | std::ios::trunc);
#endif
if(sourceFout)
@@ -362,11 +371,9 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
}
void cmLocalVisualStudio6Generator
-::WriteGroup(const cmSourceGroup *sg, cmTarget& target,
- std::ostream &fout, const char *libName)
+::WriteGroup(const cmSourceGroup *sg, cmGeneratorTarget* target,
+ std::ostream &fout, const std::string& libName)
{
- cmGeneratorTarget* gt =
- this->GlobalGenerator->GetGeneratorTarget(&target);
const std::vector<const cmSourceFile *> &sourceFiles =
sg->GetSourceFiles();
// If the group is empty, don't write it at all.
@@ -387,15 +394,21 @@ void cmLocalVisualStudio6Generator
for(std::vector<const cmSourceFile *>::const_iterator sf =
sourceFiles.begin(); sf != sourceFiles.end(); ++sf)
{
+ if (!(*sf)->GetObjectLibrary().empty())
+ {
+ continue;
+ }
+
std::string source = (*sf)->GetFullPath();
const cmCustomCommand *command =
(*sf)->GetCustomCommand();
std::string compileFlags;
std::vector<std::string> depends;
std::string objectNameDir;
- if(gt->ExplicitObjectName.find(*sf) != gt->ExplicitObjectName.end())
+ if(target->HasExplicitObjectName(*sf))
{
- objectNameDir = cmSystemTools::GetFilenamePath(gt->Objects[*sf]);
+ objectNameDir =
+ cmSystemTools::GetFilenamePath(target->GetObjectName(*sf));
}
// Add per-source file flags.
@@ -404,23 +417,20 @@ void cmLocalVisualStudio6Generator
compileFlags += cflags;
}
- const char* lang = this->GetSourceFileLanguage(*(*sf));
- if(lang)
+ const std::string& lang = this->GetSourceFileLanguage(*(*sf));
+ if(lang == "CXX")
{
- if(strcmp(lang, "CXX") == 0)
- {
- // force a C++ file type
- compileFlags += " /TP ";
- }
- else if(strcmp(lang, "C") == 0)
- {
- // force to c file type
- compileFlags += " /TC ";
- }
+ // force a C++ file type
+ compileFlags += " /TP ";
+ }
+ else if(lang == "C")
+ {
+ // force to c file type
+ compileFlags += " /TC ";
}
// Add per-source and per-configuration preprocessor definitions.
- std::map<cmStdString, cmStdString> cdmap;
+ std::map<std::string, std::string> cdmap;
{
std::set<std::string> targetCompileDefinitions;
@@ -460,7 +470,7 @@ void cmLocalVisualStudio6Generator
}
bool excludedFromBuild =
- (lang && (*sf)->GetPropertyAsBool("HEADER_FILE_ONLY"));
+ (!lang.empty() && (*sf)->GetPropertyAsBool("HEADER_FILE_ONLY"));
// Check for extra object-file dependencies.
const char* dependsValue = (*sf)->GetProperty("OBJECT_DEPENDS");
@@ -469,15 +479,15 @@ void cmLocalVisualStudio6Generator
cmSystemTools::ExpandListArgument(dependsValue, depends);
}
if (GetVS6TargetName(source) != libName ||
- target.GetType() == cmTarget::UTILITY ||
- target.GetType() == cmTarget::GLOBAL_TARGET)
+ target->GetType() == cmState::UTILITY ||
+ target->GetType() == cmState::GLOBAL_TARGET)
{
fout << "# Begin Source File\n\n";
// Tell MS-Dev what the source is. If the compiler knows how to
// build it, then it will.
fout << "SOURCE=" <<
- this->ConvertToOptionallyRelativeOutputPath(source.c_str()) << "\n\n";
+ this->ConvertToOutputFormat(source.c_str(), SHELL) << "\n\n";
if(!depends.empty())
{
// Write out the dependencies for the rule.
@@ -486,7 +496,7 @@ void cmLocalVisualStudio6Generator
d != depends.end(); ++d)
{
fout << "\\\n\t" <<
- this->ConvertToOptionallyRelativeOutputPath(d->c_str());
+ this->ConvertToOutputFormat(d->c_str(), SHELL);
}
fout << "\n";
}
@@ -520,7 +530,7 @@ void cmLocalVisualStudio6Generator
{
fout << "\n# ADD CPP " << compileFlags << "\n\n";
}
- std::map<cmStdString, cmStdString>::iterator cdi =
+ std::map<std::string, std::string>::iterator cdi =
cdmap.find(cmSystemTools::UpperCase(config));
if(cdi != cdmap.end() && !cdi->second.empty())
{
@@ -560,26 +570,30 @@ void cmLocalVisualStudio6Generator
void
cmLocalVisualStudio6Generator
-::AddUtilityCommandHack(cmTarget& target, int count,
+::AddUtilityCommandHack(cmGeneratorTarget *target, int count,
std::vector<std::string>& depends,
const cmCustomCommand& origCommand)
{
// Create a fake output that forces the rule to run.
- char* output = new char[(strlen(this->Makefile->GetStartOutputDirectory()) +
- strlen(target.GetName()) + 30)];
- sprintf(output,"%s/%s_force_%i", this->Makefile->GetStartOutputDirectory(),
- target.GetName(), count);
- std::string comment = this->ConstructComment(origCommand, "<hack>");
+ char* output = new char[(strlen(this->GetCurrentBinaryDirectory())
+ + target->GetName().size() + 30)];
+ sprintf(output,"%s/%s_force_%i", this->GetCurrentBinaryDirectory(),
+ target->GetName().c_str(), count);
+ const char* comment = origCommand.GetComment();
+ if(!comment && origCommand.GetOutputs().empty())
+ {
+ comment = "<hack>";
+ }
// Add the rule with the given dependencies and commands.
- const char* no_main_dependency = 0;
+ std::string no_main_dependency = "";
if(cmSourceFile* outsf =
this->Makefile->AddCustomCommandToOutput(
output, depends, no_main_dependency,
- origCommand.GetCommandLines(), comment.c_str(),
- origCommand.GetWorkingDirectory()))
+ origCommand.GetCommandLines(), comment,
+ origCommand.GetWorkingDirectory().c_str()))
{
- target.AddSourceFile(outsf);
+ target->AddSource(outsf->GetFullPath());
}
// Replace the dependencies with the output of this rule so that the
@@ -598,20 +612,21 @@ cmLocalVisualStudio6Generator
const cmCustomCommand& command,
const char* flags)
{
- std::string comment =
- this->ConstructComment(command, "Building Custom Rule $(InputPath)");
- if(comment == "<hack>")
- {
- comment = "";
- }
-
// Write the rule for each configuration.
std::vector<std::string>::iterator i;
for(i = this->Configurations.begin(); i != this->Configurations.end(); ++i)
{
std::string config = this->GetConfigName(*i);
+ cmCustomCommandGenerator ccg(command, config, this);
+ std::string comment =
+ this->ConstructComment(ccg, "Building Custom Rule $(InputPath)");
+ if(comment == "<hack>")
+ {
+ comment = "";
+ }
+
std::string script =
- this->ConstructScript(command, config.c_str(), "\\\n\t");
+ this->ConstructScript(ccg, "\\\n\t");
if (i == this->Configurations.begin())
{
@@ -628,8 +643,8 @@ cmLocalVisualStudio6Generator
// Write out the dependencies for the rule.
fout << "USERDEP__HACK=";
for(std::vector<std::string>::const_iterator d =
- command.GetDepends().begin();
- d != command.GetDepends().end();
+ ccg.GetDepends().begin();
+ d != ccg.GetDepends().end();
++d)
{
// Lookup the real name of the dependency in case it is a CMake target.
@@ -637,7 +652,7 @@ cmLocalVisualStudio6Generator
if(this->GetRealDependency(d->c_str(), config.c_str(), dep))
{
fout << "\\\n\t" <<
- this->ConvertToOptionallyRelativeOutputPath(dep.c_str());
+ this->ConvertToOutputFormat(dep.c_str(), SHELL);
}
}
fout << "\n";
@@ -649,7 +664,7 @@ cmLocalVisualStudio6Generator
fout << " " << comment.c_str();
}
fout << "\n\n";
- if(command.GetOutputs().empty())
+ if(ccg.GetOutputs().empty())
{
fout << source
<< "_force : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"\n\t";
@@ -658,12 +673,12 @@ cmLocalVisualStudio6Generator
else
{
for(std::vector<std::string>::const_iterator o =
- command.GetOutputs().begin();
- o != command.GetOutputs().end();
+ ccg.GetOutputs().begin();
+ o != ccg.GetOutputs().end();
++o)
{
// Write a rule for every output generated by this command.
- fout << this->ConvertToOptionallyRelativeOutputPath(o->c_str())
+ fout << this->ConvertToOutputFormat(o->c_str(), SHELL)
<< " : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"\n\t";
fout << script.c_str() << "\n\n";
}
@@ -693,8 +708,8 @@ void cmLocalVisualStudio6Generator::WriteDSPEndGroup(std::ostream& fout)
void cmLocalVisualStudio6Generator::SetBuildType(BuildType b,
- const char* libName,
- cmTarget& target)
+ const std::string& libName,
+ cmGeneratorTarget *target)
{
std::string root= this->Makefile->GetRequiredDefinition("CMAKE_ROOT");
const char *def=
@@ -726,7 +741,7 @@ void cmLocalVisualStudio6Generator::SetBuildType(BuildType b,
this->DSPFooterTemplate += "/DLLFooter.dsptemplate";
break;
case EXECUTABLE:
- if ( target.GetPropertyAsBool("WIN32_EXECUTABLE") )
+ if ( target->GetPropertyAsBool("WIN32_EXECUTABLE") )
{
this->DSPHeaderTemplate = root;
this->DSPHeaderTemplate += "/EXEWinHeader.dsptemplate";
@@ -751,7 +766,7 @@ void cmLocalVisualStudio6Generator::SetBuildType(BuildType b,
// once the build type is set, determine what configurations are
// possible
- std::ifstream fin(this->DSPHeaderTemplate.c_str());
+ cmsys::ifstream fin(this->DSPHeaderTemplate.c_str());
cmsys::RegularExpression reg("# Name ");
if(!fin)
@@ -778,27 +793,30 @@ void cmLocalVisualStudio6Generator::SetBuildType(BuildType b,
//----------------------------------------------------------------------------
cmsys::auto_ptr<cmCustomCommand>
-cmLocalVisualStudio6Generator::MaybeCreateOutputDir(cmTarget& target,
- const char* config)
+cmLocalVisualStudio6Generator::MaybeCreateOutputDir(cmGeneratorTarget* target,
+ const std::string& config)
{
cmsys::auto_ptr<cmCustomCommand> pcc;
// VS6 forgets to create the output directory for archives if it
// differs from the intermediate directory.
- if(target.GetType() != cmTarget::STATIC_LIBRARY) { return pcc; }
- std::string outDir = target.GetDirectory(config, false);
+ if(target->GetType() != cmState::STATIC_LIBRARY) { return pcc; }
+
+ std::string outDir = target->GetDirectory(config, false);
// Add a pre-link event to create the directory.
cmCustomCommandLine command;
- command.push_back(this->Makefile->GetRequiredDefinition("CMAKE_COMMAND"));
+ command.push_back(cmSystemTools::GetCMakeCommand());
command.push_back("-E");
command.push_back("make_directory");
command.push_back(outDir);
std::vector<std::string> no_output;
+ std::vector<std::string> no_byproducts;
std::vector<std::string> no_depends;
cmCustomCommandLines commands;
commands.push_back(command);
- pcc.reset(new cmCustomCommand(0, no_output, no_depends, commands, 0, 0));
+ pcc.reset(new cmCustomCommand(0, no_output, no_byproducts,
+ no_depends, commands, 0, 0));
pcc->SetEscapeOldStyle(false);
pcc->SetEscapeAllowMakeVars(true);
return pcc;
@@ -806,11 +824,11 @@ cmLocalVisualStudio6Generator::MaybeCreateOutputDir(cmTarget& target,
// look for custom rules on a target and collect them together
std::string
-cmLocalVisualStudio6Generator::CreateTargetRules(cmTarget &target,
- const char* configName,
- const char * /* libName */)
+cmLocalVisualStudio6Generator::CreateTargetRules(cmGeneratorTarget *target,
+ const std::string& configName,
+ const std::string& /* libName */)
{
- if (target.GetType() >= cmTarget::UTILITY )
+ if (target->GetType() >= cmState::UTILITY )
{
return "";
}
@@ -820,8 +838,8 @@ cmLocalVisualStudio6Generator::CreateTargetRules(cmTarget &target,
// Write the pre-build and pre-link together (VS6 does not support both).
event.Start("PreLink");
- event.Write(target.GetPreBuildCommands());
- event.Write(target.GetPreLinkCommands());
+ event.Write(target->GetPreBuildCommands());
+ event.Write(target->GetPreLinkCommands());
cmsys::auto_ptr<cmCustomCommand> pcc(
this->MaybeCreateImplibDir(target, configName, false));
if(pcc.get())
@@ -837,7 +855,7 @@ cmLocalVisualStudio6Generator::CreateTargetRules(cmTarget &target,
// Write the post-build rules.
event.Start("PostBuild");
- event.Write(target.GetPostBuildCommands());
+ event.Write(target->GetPostBuildCommands());
event.Finish();
customRuleCode += "# End Special Build Tool\n";
@@ -856,8 +874,9 @@ inline std::string removeQuotes(const std::string& s)
std::string
-cmLocalVisualStudio6Generator::GetTargetIncludeOptions(cmTarget &target,
- const char *config)
+cmLocalVisualStudio6Generator::GetTargetIncludeOptions(
+ cmGeneratorTarget *target,
+ const std::string& config)
{
std::string includeOptions;
@@ -867,18 +886,16 @@ cmLocalVisualStudio6Generator::GetTargetIncludeOptions(cmTarget &target,
unsigned int maxIncludeLength = 3000;
bool useShortPath = false;
- cmGeneratorTarget* gt =
- this->GlobalGenerator->GetGeneratorTarget(&target);
for(int j=0; j < 2; ++j)
{
std::vector<std::string> includes;
- this->GetIncludeDirectories(includes, gt, "C", config);
+ this->GetIncludeDirectories(includes, target, "C", config);
std::vector<std::string>::iterator i;
for(i = includes.begin(); i != includes.end(); ++i)
{
std::string tmp =
- this->ConvertToOptionallyRelativeOutputPath(i->c_str());
+ this->ConvertToOutputFormat(i->c_str(), SHELL);
if(useShortPath)
{
cmSystemTools::GetShortPath(tmp.c_str(), tmp);
@@ -920,11 +937,11 @@ cmLocalVisualStudio6Generator::GetTargetIncludeOptions(cmTarget &target,
void cmLocalVisualStudio6Generator
::WriteDSPHeader(std::ostream& fout,
- const char *libName, cmTarget &target,
+ const std::string& libName, cmGeneratorTarget* target,
std::vector<cmSourceGroup> &)
{
- bool targetBuilds = (target.GetType() >= cmTarget::EXECUTABLE &&
- target.GetType() <= cmTarget::MODULE_LIBRARY);
+ bool targetBuilds = (target->GetType() >= cmState::EXECUTABLE &&
+ target->GetType() <= cmState::MODULE_LIBRARY);
#ifdef CM_USE_OLD_VS6
// Lookup the library and executable output directories.
std::string libPath;
@@ -966,17 +983,17 @@ void cmLocalVisualStudio6Generator
std::string libMultiLineDebugOptions;
std::string libMultiLineOptimizedOptions;
- if(libPath.size())
+ if(!libPath.empty())
{
std::string lpath =
- this->ConvertToOptionallyRelativeOutputPath(libPath.c_str());
- if(lpath.size() == 0)
+ this->ConvertToOutputFormat(libPath.c_str(), SHELL);
+ if(lpath.empty())
{
lpath = ".";
}
std::string lpathIntDir = libPath + "$(INTDIR)";
lpathIntDir =
- this->ConvertToOptionallyRelativeOutputPath(lpathIntDir.c_str());
+ this->ConvertToOutputFormat(lpathIntDir.c_str(), SHELL);
if(pathEmitted.insert(lpath).second)
{
libOptions += " /LIBPATH:";
@@ -999,17 +1016,17 @@ void cmLocalVisualStudio6Generator
libMultiLineOptionsForDebug += " \n";
}
}
- if(exePath.size())
+ if(!exePath.empty())
{
std::string lpath =
- this->ConvertToOptionallyRelativeOutputPath(exePath.c_str());
- if(lpath.size() == 0)
+ this->ConvertToOutputFormat(exePath.c_str(), SHELL);
+ if(lpath.empty())
{
lpath = ".";
}
std::string lpathIntDir = exePath + "$(INTDIR)";
lpathIntDir =
- this->ConvertToOptionallyRelativeOutputPath(lpathIntDir.c_str());
+ this->ConvertToOutputFormat(lpathIntDir.c_str(), SHELL);
if(pathEmitted.insert(lpath).second)
{
@@ -1034,7 +1051,8 @@ void cmLocalVisualStudio6Generator
}
}
std::vector<std::string>::const_iterator i;
- const std::vector<std::string>& libdirs = target.GetLinkDirectories();
+ const std::vector<std::string>& libdirs =
+ target->GetLinkDirectories();
for(i = libdirs.begin(); i != libdirs.end(); ++i)
{
std::string path = *i;
@@ -1043,14 +1061,14 @@ void cmLocalVisualStudio6Generator
path += "/";
}
std::string lpath =
- this->ConvertToOptionallyRelativeOutputPath(path.c_str());
- if(lpath.size() == 0)
+ this->ConvertToOutputFormat(path.c_str(), SHELL);
+ if(lpath.empty())
{
lpath = ".";
}
std::string lpathIntDir = path + "$(INTDIR)";
lpathIntDir =
- this->ConvertToOptionallyRelativeOutputPath(lpathIntDir.c_str());
+ this->ConvertToOutputFormat(lpathIntDir.c_str(), SHELL);
if(pathEmitted.insert(lpath).second)
{
libOptions += " /LIBPATH:";
@@ -1075,25 +1093,27 @@ void cmLocalVisualStudio6Generator
}
}
// find link libraries
- const cmTarget::LinkLibraryVectorType& libs = target.GetLinkLibraries();
+ const cmTarget::LinkLibraryVectorType& libs =
+ target->Target->GetLinkLibrariesForVS6();
cmTarget::LinkLibraryVectorType::const_iterator j;
for(j = libs.begin(); j != libs.end(); ++j)
{
// add libraries to executables and dlls (but never include
// a library in a library, bad recursion)
// NEVER LINK STATIC LIBRARIES TO OTHER STATIC LIBRARIES
- if ((target.GetType() != cmTarget::SHARED_LIBRARY
- && target.GetType() != cmTarget::STATIC_LIBRARY
- && target.GetType() != cmTarget::MODULE_LIBRARY) ||
- (target.GetType()==cmTarget::SHARED_LIBRARY
+ if ((target->GetType() != cmState::SHARED_LIBRARY
+ && target->GetType() != cmState::STATIC_LIBRARY
+ && target->GetType() != cmState::MODULE_LIBRARY) ||
+ (target->GetType()==cmState::SHARED_LIBRARY
&& libName != GetVS6TargetName(j->first)) ||
- (target.GetType()==cmTarget::MODULE_LIBRARY
+ (target->GetType()==cmState::MODULE_LIBRARY
&& libName != GetVS6TargetName(j->first)))
{
// Compute the proper name to use to link this library.
std::string lib;
std::string libDebug;
- cmTarget* tgt = this->GlobalGenerator->FindTarget(0, j->first.c_str());
+ cmGeneratorTarget* tgt =
+ this->GlobalGenerator->FindGeneratorTarget(j->first.c_str());
if(tgt)
{
lib = cmSystemTools::GetFilenameWithoutExtension
@@ -1113,11 +1133,11 @@ void cmLocalVisualStudio6Generator
libDebug += ".lib";
}
}
- lib = this->ConvertToOptionallyRelativeOutputPath(lib.c_str());
+ lib = this->ConvertToOutputFormat(lib.c_str(), SHELL);
libDebug =
- this->ConvertToOptionallyRelativeOutputPath(libDebug.c_str());
+ this->ConvertToOutputFormat(libDebug.c_str(), SHELL);
- if (j->second == cmTarget::GENERAL)
+ if (j->second == GENERAL_LibraryType)
{
libOptions += " ";
libOptions += lib;
@@ -1128,7 +1148,7 @@ void cmLocalVisualStudio6Generator
libMultiLineOptionsForDebug += libDebug;
libMultiLineOptionsForDebug += "\n";
}
- if (j->second == cmTarget::DEBUG)
+ if (j->second == DEBUG_LibraryType)
{
libDebugOptions += " ";
libDebugOptions += lib;
@@ -1137,7 +1157,7 @@ void cmLocalVisualStudio6Generator
libMultiLineDebugOptions += libDebug;
libMultiLineDebugOptions += "\n";
}
- if (j->second == cmTarget::OPTIMIZED)
+ if (j->second == OPTIMIZED_LibraryType)
{
libOptimizedOptions += " ";
libOptimizedOptions += lib;
@@ -1167,7 +1187,7 @@ void cmLocalVisualStudio6Generator
std::string extraLinkOptionsRelease;
std::string extraLinkOptionsMinSizeRel;
std::string extraLinkOptionsRelWithDebInfo;
- if(target.GetType() == cmTarget::EXECUTABLE)
+ if(target->GetType() == cmState::EXECUTABLE)
{
extraLinkOptions = this->Makefile->
GetRequiredDefinition("CMAKE_EXE_LINKER_FLAGS");
@@ -1180,7 +1200,7 @@ void cmLocalVisualStudio6Generator
extraLinkOptionsRelWithDebInfo = this->Makefile->
GetRequiredDefinition("CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO");
}
- if(target.GetType() == cmTarget::SHARED_LIBRARY)
+ if(target->GetType() == cmState::SHARED_LIBRARY)
{
extraLinkOptions = this->Makefile->
GetRequiredDefinition("CMAKE_SHARED_LINKER_FLAGS");
@@ -1193,7 +1213,7 @@ void cmLocalVisualStudio6Generator
extraLinkOptionsRelWithDebInfo = this->Makefile->
GetRequiredDefinition("CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO");
}
- if(target.GetType() == cmTarget::MODULE_LIBRARY)
+ if(target->GetType() == cmState::MODULE_LIBRARY)
{
extraLinkOptions = this->Makefile->
GetRequiredDefinition("CMAKE_MODULE_LINKER_FLAGS");
@@ -1208,50 +1228,61 @@ void cmLocalVisualStudio6Generator
}
// Get extra linker options for this target.
- if(const char* targetLinkFlags = target.GetProperty("LINK_FLAGS"))
+ if(const char* targetLinkFlags = target->GetProperty("LINK_FLAGS"))
{
extraLinkOptions += " ";
extraLinkOptions += targetLinkFlags;
}
- if(const char* targetLinkFlags = target.GetProperty("LINK_FLAGS_DEBUG"))
+ if(const char* targetLinkFlags = target->GetProperty("LINK_FLAGS_DEBUG"))
{
extraLinkOptionsDebug += " ";
extraLinkOptionsDebug += targetLinkFlags;
}
- if(const char* targetLinkFlags = target.GetProperty("LINK_FLAGS_RELEASE"))
+ if(const char* targetLinkFlags = target->GetProperty("LINK_FLAGS_RELEASE"))
{
extraLinkOptionsRelease += " ";
extraLinkOptionsRelease += targetLinkFlags;
}
- if(const char* targetLinkFlags = target.GetProperty("LINK_FLAGS_MINSIZEREL"))
+ if(const char* targetLinkFlags =
+ target->GetProperty("LINK_FLAGS_MINSIZEREL"))
{
extraLinkOptionsMinSizeRel += " ";
extraLinkOptionsMinSizeRel += targetLinkFlags;
}
if(const char* targetLinkFlags =
- target.GetProperty("LINK_FLAGS_RELWITHDEBINFO"))
+ target->GetProperty("LINK_FLAGS_RELWITHDEBINFO"))
{
extraLinkOptionsRelWithDebInfo += " ";
extraLinkOptionsRelWithDebInfo += targetLinkFlags;
}
-
-
-
// Get standard libraries for this language.
if(targetBuilds)
{
// Get the language to use for linking.
- const char* linkLanguage = target.GetLinkerLanguage();
- if(!linkLanguage)
+ std::vector<std::string> configs;
+ target->Target->GetMakefile()->GetConfigurations(configs);
+ std::vector<std::string>::const_iterator it = configs.begin();
+ const std::string& linkLanguage = target->GetLinkerLanguage(*it);
+ for ( ; it != configs.end(); ++it)
+ {
+ const std::string& configLinkLanguage = target->GetLinkerLanguage(*it);
+ if (configLinkLanguage != linkLanguage)
+ {
+ cmSystemTools::Error
+ ("Linker language must not vary by configuration for target: ",
+ target->GetName().c_str());
+ }
+ }
+ if(linkLanguage.empty())
{
cmSystemTools::Error
("CMake can not determine linker language for target: ",
- target.GetName());
+ target->GetName().c_str());
return;
}
@@ -1272,14 +1303,14 @@ void cmLocalVisualStudio6Generator
// Compute version number information.
std::string targetVersionFlag;
- if(target.GetType() == cmTarget::EXECUTABLE ||
- target.GetType() == cmTarget::SHARED_LIBRARY ||
- target.GetType() == cmTarget::MODULE_LIBRARY)
+ if(target->GetType() == cmState::EXECUTABLE ||
+ target->GetType() == cmState::SHARED_LIBRARY ||
+ target->GetType() == cmState::MODULE_LIBRARY)
{
int major;
int minor;
- target.GetTargetVersion(major, minor);
- cmOStringStream targetVersionStream;
+ target->GetTargetVersion(major, minor);
+ std::ostringstream targetVersionStream;
targetVersionStream << "/version:" << major << "." << minor;
targetVersionFlag = targetVersionStream.str();
}
@@ -1291,20 +1322,20 @@ void cmLocalVisualStudio6Generator
std::string outputNameRelease = outputName;
std::string outputNameMinSizeRel = outputName;
std::string outputNameRelWithDebInfo = outputName;
- if(target.GetType() == cmTarget::EXECUTABLE ||
- target.GetType() == cmTarget::STATIC_LIBRARY ||
- target.GetType() == cmTarget::SHARED_LIBRARY ||
- target.GetType() == cmTarget::MODULE_LIBRARY)
+ if(target->GetType() == cmState::EXECUTABLE ||
+ target->GetType() == cmState::STATIC_LIBRARY ||
+ target->GetType() == cmState::SHARED_LIBRARY ||
+ target->GetType() == cmState::MODULE_LIBRARY)
{
- outputName = target.GetFullName();
- outputNameDebug = target.GetFullName("Debug");
- outputNameRelease = target.GetFullName("Release");
- outputNameMinSizeRel = target.GetFullName("MinSizeRel");
- outputNameRelWithDebInfo = target.GetFullName("RelWithDebInfo");
+ outputName = target->GetFullName();
+ outputNameDebug = target->GetFullName("Debug");
+ outputNameRelease = target->GetFullName("Release");
+ outputNameMinSizeRel = target->GetFullName("MinSizeRel");
+ outputNameRelWithDebInfo = target->GetFullName("RelWithDebInfo");
}
- else if(target.GetType() == cmTarget::OBJECT_LIBRARY)
+ else if(target->GetType() == cmState::OBJECT_LIBRARY)
{
- outputName = target.GetName();
+ outputName = target->GetName();
outputName += ".lib";
outputNameDebug = outputName;
outputNameRelease = outputName;
@@ -1318,30 +1349,30 @@ void cmLocalVisualStudio6Generator
std::string outputDirRelease;
std::string outputDirMinSizeRel;
std::string outputDirRelWithDebInfo;
- if(target.GetType() == cmTarget::EXECUTABLE ||
- target.GetType() == cmTarget::STATIC_LIBRARY ||
- target.GetType() == cmTarget::SHARED_LIBRARY ||
- target.GetType() == cmTarget::MODULE_LIBRARY)
+ if(target->GetType() == cmState::EXECUTABLE ||
+ target->GetType() == cmState::STATIC_LIBRARY ||
+ target->GetType() == cmState::SHARED_LIBRARY ||
+ target->GetType() == cmState::MODULE_LIBRARY)
{
#ifdef CM_USE_OLD_VS6
outputDirOld =
- removeQuotes(this->ConvertToOptionallyRelativeOutputPath
- (target.GetDirectory().c_str()));
+ removeQuotes(this->ConvertToOutputFormat
+ (target->GetDirectory().c_str(), SHELL));
#endif
outputDirDebug =
- removeQuotes(this->ConvertToOptionallyRelativeOutputPath(
- target.GetDirectory("Debug").c_str()));
+ removeQuotes(this->ConvertToOutputFormat(
+ target->GetDirectory("Debug").c_str(), SHELL));
outputDirRelease =
- removeQuotes(this->ConvertToOptionallyRelativeOutputPath(
- target.GetDirectory("Release").c_str()));
+ removeQuotes(this->ConvertToOutputFormat(
+ target->GetDirectory("Release").c_str(), SHELL));
outputDirMinSizeRel =
- removeQuotes(this->ConvertToOptionallyRelativeOutputPath(
- target.GetDirectory("MinSizeRel").c_str()));
+ removeQuotes(this->ConvertToOutputFormat(
+ target->GetDirectory("MinSizeRel").c_str(), SHELL));
outputDirRelWithDebInfo =
- removeQuotes(this->ConvertToOptionallyRelativeOutputPath(
- target.GetDirectory("RelWithDebInfo").c_str()));
+ removeQuotes(this->ConvertToOutputFormat(
+ target->GetDirectory("RelWithDebInfo").c_str(), SHELL));
}
- else if(target.GetType() == cmTarget::OBJECT_LIBRARY)
+ else if(target->GetType() == cmState::OBJECT_LIBRARY)
{
std::string outputDir = cmake::GetCMakeFilesDirectoryPostSlash();
outputDirDebug = outputDir + "Debug";
@@ -1355,9 +1386,9 @@ void cmLocalVisualStudio6Generator
std::string optionsRelease;
std::string optionsMinSizeRel;
std::string optionsRelWithDebInfo;
- if(target.GetType() == cmTarget::EXECUTABLE ||
- target.GetType() == cmTarget::SHARED_LIBRARY ||
- target.GetType() == cmTarget::MODULE_LIBRARY)
+ if(target->GetType() == cmState::EXECUTABLE ||
+ target->GetType() == cmState::SHARED_LIBRARY ||
+ target->GetType() == cmState::MODULE_LIBRARY)
{
extraLinkOptionsDebug =
extraLinkOptions + " " + extraLinkOptionsDebug;
@@ -1383,44 +1414,42 @@ void cmLocalVisualStudio6Generator
std::string targetImplibFlagRelease;
std::string targetImplibFlagMinSizeRel;
std::string targetImplibFlagRelWithDebInfo;
- if(target.GetType() == cmTarget::SHARED_LIBRARY ||
- target.GetType() == cmTarget::MODULE_LIBRARY ||
- target.GetType() == cmTarget::EXECUTABLE)
+ if(target->GetType() == cmState::SHARED_LIBRARY ||
+ target->GetType() == cmState::MODULE_LIBRARY ||
+ target->GetType() == cmState::EXECUTABLE)
{
- std::string fullPathImpDebug = target.GetDirectory("Debug", true);
- std::string fullPathImpRelease = target.GetDirectory("Release", true);
+ std::string fullPathImpDebug = target->GetDirectory("Debug", true);
+ std::string fullPathImpRelease = target->GetDirectory("Release", true);
std::string fullPathImpMinSizeRel =
- target.GetDirectory("MinSizeRel", true);
+ target->GetDirectory("MinSizeRel", true);
std::string fullPathImpRelWithDebInfo =
- target.GetDirectory("RelWithDebInfo", true);
+ target->GetDirectory("RelWithDebInfo", true);
fullPathImpDebug += "/";
fullPathImpRelease += "/";
fullPathImpMinSizeRel += "/";
fullPathImpRelWithDebInfo += "/";
- fullPathImpDebug += target.GetFullName("Debug", true);
- fullPathImpRelease += target.GetFullName("Release", true);
- fullPathImpMinSizeRel += target.GetFullName("MinSizeRel", true);
- fullPathImpRelWithDebInfo += target.GetFullName("RelWithDebInfo", true);
+ fullPathImpDebug += target->GetFullName("Debug", true);
+ fullPathImpRelease += target->GetFullName("Release", true);
+ fullPathImpMinSizeRel += target->GetFullName("MinSizeRel", true);
+ fullPathImpRelWithDebInfo += target->GetFullName("RelWithDebInfo", true);
targetImplibFlagDebug = "/implib:";
targetImplibFlagRelease = "/implib:";
targetImplibFlagMinSizeRel = "/implib:";
targetImplibFlagRelWithDebInfo = "/implib:";
targetImplibFlagDebug +=
- this->ConvertToOptionallyRelativeOutputPath(fullPathImpDebug.c_str());
+ this->ConvertToOutputFormat(fullPathImpDebug.c_str(), SHELL);
targetImplibFlagRelease +=
- this->ConvertToOptionallyRelativeOutputPath(fullPathImpRelease.c_str());
+ this->ConvertToOutputFormat(fullPathImpRelease.c_str(), SHELL);
targetImplibFlagMinSizeRel +=
- this->ConvertToOptionallyRelativeOutputPath(
- fullPathImpMinSizeRel.c_str());
+ this->ConvertToOutputFormat(fullPathImpMinSizeRel.c_str(), SHELL);
targetImplibFlagRelWithDebInfo +=
- this->ConvertToOptionallyRelativeOutputPath(
- fullPathImpRelWithDebInfo.c_str());
+ this->ConvertToOutputFormat(fullPathImpRelWithDebInfo.c_str(), SHELL);
}
#ifdef CM_USE_OLD_VS6
// Compute link information for the target.
- if(extraLinkOptions.size())
+ if(!extraLinkOptions.empty())
{
libOptions += " ";
libOptions += extraLinkOptions;
@@ -1445,7 +1474,7 @@ void cmLocalVisualStudio6Generator
std::string customRuleCodeRelWithDebInfo
= this->CreateTargetRules(target, "RELWITHDEBINFO", libName);
- std::ifstream fin(this->DSPHeaderTemplate.c_str());
+ cmsys::ifstream fin(this->DSPHeaderTemplate.c_str());
if(!fin)
{
cmSystemTools::Error("Error Reading ", this->DSPHeaderTemplate.c_str());
@@ -1455,7 +1484,7 @@ void cmLocalVisualStudio6Generator
std::string staticLibOptionsRelease;
std::string staticLibOptionsMinSizeRel;
std::string staticLibOptionsRelWithDebInfo;
- if(target.GetType() == cmTarget::STATIC_LIBRARY )
+ if(target->GetType() == cmState::STATIC_LIBRARY )
{
const char *libflagsGlobal =
this->Makefile->GetSafeDefinition("CMAKE_STATIC_LINKER_FLAGS");
@@ -1474,7 +1503,7 @@ void cmLocalVisualStudio6Generator
this->AppendFlags(staticLibOptionsRelWithDebInfo, this->Makefile->
GetSafeDefinition("CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO"));
- const char *libflags = target.GetProperty("STATIC_LIBRARY_FLAGS");
+ const char *libflags = target->GetProperty("STATIC_LIBRARY_FLAGS");
this->AppendFlags(staticLibOptions, libflags);
this->AppendFlags(staticLibOptionsDebug, libflags);
this->AppendFlags(staticLibOptionsRelease, libflags);
@@ -1482,13 +1511,13 @@ void cmLocalVisualStudio6Generator
this->AppendFlags(staticLibOptionsRelWithDebInfo, libflags);
this->AppendFlags(staticLibOptionsDebug,
- target.GetProperty("STATIC_LIBRARY_FLAGS_DEBUG"));
+ target->GetProperty("STATIC_LIBRARY_FLAGS_DEBUG"));
this->AppendFlags(staticLibOptionsRelease,
- target.GetProperty("STATIC_LIBRARY_FLAGS_RELEASE"));
+ target->GetProperty("STATIC_LIBRARY_FLAGS_RELEASE"));
this->AppendFlags(staticLibOptionsMinSizeRel,
- target.GetProperty("STATIC_LIBRARY_FLAGS_MINSIZEREL"));
+ target->GetProperty("STATIC_LIBRARY_FLAGS_MINSIZEREL"));
this->AppendFlags(staticLibOptionsRelWithDebInfo,
- target.GetProperty("STATIC_LIBRARY_FLAGS_RELWITHDEBINFO"));
+ target->GetProperty("STATIC_LIBRARY_FLAGS_RELWITHDEBINFO"));
std::string objects;
this->OutputObjects(target, "LIB", objects);
@@ -1504,14 +1533,14 @@ void cmLocalVisualStudio6Generator
// Add the export symbol definition for shared library objects.
std::string exportSymbol;
- if(const char* exportMacro = target.GetExportMacro())
+ if(const char* exportMacro = target->GetExportMacro())
{
exportSymbol = exportMacro;
}
std::string line;
std::string libnameExports;
- if(exportSymbol.size())
+ if(!exportSymbol.empty())
{
libnameExports = "/D \"";
libnameExports += exportSymbol;
@@ -1528,8 +1557,8 @@ void cmLocalVisualStudio6Generator
libnameExports.c_str());
cmSystemTools::ReplaceString(line, "CMAKE_MFC_FLAG",
mfcFlag);
- if(target.GetType() == cmTarget::STATIC_LIBRARY ||
- target.GetType() == cmTarget::OBJECT_LIBRARY)
+ if(target->GetType() == cmState::STATIC_LIBRARY ||
+ target->GetType() == cmState::OBJECT_LIBRARY)
{
cmSystemTools::ReplaceString(line, "CM_STATIC_LIB_ARGS_DEBUG",
staticLibOptionsDebug.c_str());
@@ -1627,15 +1656,15 @@ void cmLocalVisualStudio6Generator
// to convert to output path for unix to win32 conversion
cmSystemTools::ReplaceString
(line, "LIBRARY_OUTPUT_PATH",
- removeQuotes(this->ConvertToOptionallyRelativeOutputPath
- (libPath.c_str())).c_str());
+ removeQuotes(this->ConvertToOutputFormat
+ (libPath.c_str(), SHELL)).c_str());
cmSystemTools::ReplaceString
(line, "EXECUTABLE_OUTPUT_PATH",
- removeQuotes(this->ConvertToOptionallyRelativeOutputPath
- (exePath.c_str())).c_str());
+ removeQuotes(this->ConvertToOutputFormat
+ (exePath.c_str(), SHELL)).c_str());
#endif
- if(targetBuilds || target.GetType() == cmTarget::OBJECT_LIBRARY)
+ if(targetBuilds || target->GetType() == cmState::OBJECT_LIBRARY)
{
cmSystemTools::ReplaceString(line, "OUTPUT_DIRECTORY_DEBUG",
outputDirDebug.c_str());
@@ -1659,21 +1688,34 @@ void cmLocalVisualStudio6Generator
= this->Makefile->GetDefinition("CMAKE_DEBUG_POSTFIX");
cmSystemTools::ReplaceString(line, "DEBUG_POSTFIX",
debugPostfix?debugPostfix:"");
- // store flags for each configuration
- std::string flags = " ";
- std::string flagsRelease = " ";
- std::string flagsMinSizeRel = " ";
- std::string flagsDebug = " ";
- std::string flagsRelWithDebInfo = " ";
- if(target.GetType() >= cmTarget::EXECUTABLE &&
- target.GetType() <= cmTarget::OBJECT_LIBRARY)
+ if(target->GetType() >= cmState::EXECUTABLE &&
+ target->GetType() <= cmState::OBJECT_LIBRARY)
{
- const char* linkLanguage = target.GetLinkerLanguage();
- if(!linkLanguage)
+ // store flags for each configuration
+ std::string flags = " ";
+ std::string flagsRelease = " ";
+ std::string flagsMinSizeRel = " ";
+ std::string flagsDebug = " ";
+ std::string flagsRelWithDebInfo = " ";
+ std::vector<std::string> configs;
+ target->Target->GetMakefile()->GetConfigurations(configs);
+ std::vector<std::string>::const_iterator it = configs.begin();
+ const std::string& linkLanguage = target->GetLinkerLanguage(*it);
+ for ( ; it != configs.end(); ++it)
+ {
+ const std::string& configLinkLanguage = target->GetLinkerLanguage(*it);
+ if (configLinkLanguage != linkLanguage)
+ {
+ cmSystemTools::Error
+ ("Linker language must not vary by configuration for target: ",
+ target->GetName().c_str());
+ }
+ }
+ if(linkLanguage.empty())
{
cmSystemTools::Error
("CMake can not determine linker language for target: ",
- target.GetName());
+ target->GetName().c_str());
return;
}
// if CXX is on and the target contains cxx code then add the cxx flags
@@ -1698,79 +1740,84 @@ void cmLocalVisualStudio6Generator
flagsRelWithDebInfo = this->Makefile->GetSafeDefinition(flagVar.c_str());
flagsRelWithDebInfo += " -DCMAKE_INTDIR=\\\"RelWithDebInfo\\\" ";
- this->AddCompileOptions(flags, &target, linkLanguage, 0);
- this->AddCompileOptions(flagsDebug, &target, linkLanguage, "Debug");
- this->AddCompileOptions(flagsRelease, &target, linkLanguage, "Release");
- this->AddCompileOptions(flagsMinSizeRel, &target, linkLanguage,
+ this->AddCompileOptions(flags, target, linkLanguage, "");
+ this->AddCompileOptions(flagsDebug, target, linkLanguage, "Debug");
+ this->AddCompileOptions(flagsRelease, target, linkLanguage, "Release");
+ this->AddCompileOptions(flagsMinSizeRel, target, linkLanguage,
"MinSizeRel");
- this->AddCompileOptions(flagsRelWithDebInfo, &target, linkLanguage,
+ this->AddCompileOptions(flagsRelWithDebInfo, target, linkLanguage,
"RelWithDebInfo");
- }
- // if _UNICODE and _SBCS are not found, then add -D_MBCS
- std::string defs = this->Makefile->GetDefineFlags();
- if(flags.find("D_UNICODE") == flags.npos &&
- defs.find("D_UNICODE") == flags.npos &&
- flags.find("D_SBCS") == flags.npos &&
- defs.find("D_SBCS") == flags.npos)
- {
- flags += " /D \"_MBCS\"";
- }
+ // if _UNICODE and _SBCS are not found, then add -D_MBCS
+ std::string defs = this->Makefile->GetDefineFlags();
+ if(flags.find("D_UNICODE") == flags.npos &&
+ defs.find("D_UNICODE") == flags.npos &&
+ flags.find("D_SBCS") == flags.npos &&
+ defs.find("D_SBCS") == flags.npos)
+ {
+ flags += " /D \"_MBCS\"";
+ }
- // Add per-target and per-configuration preprocessor definitions.
- std::set<std::string> definesSet;
- std::set<std::string> debugDefinesSet;
- std::set<std::string> releaseDefinesSet;
- std::set<std::string> minsizeDefinesSet;
- std::set<std::string> debugrelDefinesSet;
-
- this->AddCompileDefinitions(definesSet, &target, 0);
- this->AddCompileDefinitions(debugDefinesSet, &target, "DEBUG");
- this->AddCompileDefinitions(releaseDefinesSet, &target, "RELEASE");
- this->AddCompileDefinitions(minsizeDefinesSet, &target, "MINSIZEREL");
- this->AddCompileDefinitions(debugrelDefinesSet, &target, "RELWITHDEBINFO");
-
- std::string defines = " ";
- std::string debugDefines = " ";
- std::string releaseDefines = " ";
- std::string minsizeDefines = " ";
- std::string debugrelDefines = " ";
-
- this->JoinDefines(definesSet, defines, 0);
- this->JoinDefines(debugDefinesSet, debugDefines, 0);
- this->JoinDefines(releaseDefinesSet, releaseDefines, 0);
- this->JoinDefines(minsizeDefinesSet, minsizeDefines, 0);
- this->JoinDefines(debugrelDefinesSet, debugrelDefines, 0);
-
- flags += defines;
- flagsDebug += debugDefines;
- flagsRelease += releaseDefines;
- flagsMinSizeRel += minsizeDefines;
- flagsRelWithDebInfo += debugrelDefines;
-
- // The template files have CXX FLAGS in them, that need to be replaced.
- // There are not separate CXX and C template files, so we use the same
- // variable names. The previous code sets up flags* variables to contain
- // the correct C or CXX flags
- cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_MINSIZEREL",
- flagsMinSizeRel.c_str());
- cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_DEBUG",
- flagsDebug.c_str());
- cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_RELWITHDEBINFO",
- flagsRelWithDebInfo.c_str());
- cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_RELEASE",
- flagsRelease.c_str());
- cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS", flags.c_str());
-
- cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_MINSIZEREL",
- minsizeDefines.c_str());
- cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_DEBUG",
- debugDefines.c_str());
- cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_RELWITHDEBINFO",
- debugrelDefines.c_str());
- cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_RELEASE",
- releaseDefines.c_str());
- cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS", defines.c_str());
+ // Add per-target and per-configuration preprocessor definitions.
+ std::set<std::string> definesSet;
+ std::set<std::string> debugDefinesSet;
+ std::set<std::string> releaseDefinesSet;
+ std::set<std::string> minsizeDefinesSet;
+ std::set<std::string> debugrelDefinesSet;
+
+ this->AddCompileDefinitions(definesSet, target, "", linkLanguage);
+ this->AddCompileDefinitions(debugDefinesSet, target,
+ "DEBUG", linkLanguage);
+ this->AddCompileDefinitions(releaseDefinesSet, target,
+ "RELEASE", linkLanguage);
+ this->AddCompileDefinitions(minsizeDefinesSet, target,
+ "MINSIZEREL", linkLanguage);
+ this->AddCompileDefinitions(debugrelDefinesSet, target,
+ "RELWITHDEBINFO", linkLanguage);
+
+ std::string defines = " ";
+ std::string debugDefines = " ";
+ std::string releaseDefines = " ";
+ std::string minsizeDefines = " ";
+ std::string debugrelDefines = " ";
+
+ this->JoinDefines(definesSet, defines, "");
+ this->JoinDefines(debugDefinesSet, debugDefines, "");
+ this->JoinDefines(releaseDefinesSet, releaseDefines, "");
+ this->JoinDefines(minsizeDefinesSet, minsizeDefines, "");
+ this->JoinDefines(debugrelDefinesSet, debugrelDefines, "");
+
+ flags += defines;
+ flagsDebug += debugDefines;
+ flagsRelease += releaseDefines;
+ flagsMinSizeRel += minsizeDefines;
+ flagsRelWithDebInfo += debugrelDefines;
+
+ // The template files have CXX FLAGS in them, that need to be replaced.
+ // There are not separate CXX and C template files, so we use the same
+ // variable names. The previous code sets up flags* variables to
+ // contain the correct C or CXX flags
+ cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_MINSIZEREL",
+ flagsMinSizeRel.c_str());
+ cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_DEBUG",
+ flagsDebug.c_str());
+ cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_RELWITHDEBINFO",
+ flagsRelWithDebInfo.c_str());
+ cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_RELEASE",
+ flagsRelease.c_str());
+ cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS", flags.c_str());
+
+ cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_MINSIZEREL",
+ minsizeDefines.c_str());
+ cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_DEBUG",
+ debugDefines.c_str());
+ cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_RELWITHDEBINFO",
+ debugrelDefines.c_str());
+ cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_RELEASE",
+ releaseDefines.c_str());
+ cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS",
+ defines.c_str());
+ }
fout << line.c_str() << std::endl;
}
@@ -1778,7 +1825,7 @@ void cmLocalVisualStudio6Generator
void cmLocalVisualStudio6Generator::WriteDSPFooter(std::ostream& fout)
{
- std::ifstream fin(this->DSPFooterTemplate.c_str());
+ cmsys::ifstream fin(this->DSPFooterTemplate.c_str());
if(!fin)
{
cmSystemTools::Error("Error Reading ",
@@ -1793,13 +1840,13 @@ void cmLocalVisualStudio6Generator::WriteDSPFooter(std::ostream& fout)
//----------------------------------------------------------------------------
void cmLocalVisualStudio6Generator
-::ComputeLinkOptions(cmTarget& target,
- const char* configName,
+::ComputeLinkOptions(cmGeneratorTarget *target,
+ const std::string& configName,
const std::string extraOptions,
std::string& options)
{
// Compute the link information for this configuration.
- cmComputeLinkInformation* pcli = target.GetLinkInformation(configName);
+ cmComputeLinkInformation* pcli = target->GetLinkInformation(configName);
if(!pcli)
{
return;
@@ -1824,9 +1871,9 @@ void cmLocalVisualStudio6Generator
}
dir += "$(IntDir)";
options += "# ADD LINK32 /LIBPATH:";
- options += this->ConvertToOptionallyRelativeOutputPath(dir.c_str());
+ options += this->ConvertToOutputFormat(dir.c_str(), SHELL);
options += " /LIBPATH:";
- options += this->ConvertToOptionallyRelativeOutputPath(d->c_str());
+ options += this->ConvertToOutputFormat(d->c_str(), SHELL);
options += "\n";
}
}
@@ -1837,9 +1884,10 @@ void cmLocalVisualStudio6Generator
if(l->IsPath)
{
options +=
- this->ConvertToOptionallyRelativeOutputPath(l->Value.c_str());
+ this->ConvertToOutputFormat(l->Value.c_str(), SHELL);
}
- else
+ else if (!l->Target
+ || l->Target->GetType() != cmState::INTERFACE_LIBRARY)
{
options += l->Value;
}
@@ -1857,29 +1905,27 @@ void cmLocalVisualStudio6Generator
//----------------------------------------------------------------------------
void cmLocalVisualStudio6Generator
-::OutputObjects(cmTarget& target, const char* tool,
+::OutputObjects(cmGeneratorTarget* target, const char* tool,
std::string& options)
{
// VS 6 does not support per-config source locations so we
// list object library content on the link line instead.
- cmGeneratorTarget* gt =
- this->GlobalGenerator->GetGeneratorTarget(&target);
std::vector<std::string> objs;
- gt->UseObjectLibraries(objs);
+ target->UseObjectLibraries(objs, "");
for(std::vector<std::string>::const_iterator
oi = objs.begin(); oi != objs.end(); ++oi)
{
options += "# ADD ";
options += tool;
options += "32 ";
- options += this->ConvertToOptionallyRelativeOutputPath(oi->c_str());
+ options += this->ConvertToOutputFormat(oi->c_str(), SHELL);
options += "\n";
}
}
std::string
cmLocalVisualStudio6Generator
-::GetTargetDirectory(cmTarget const&) const
+::GetTargetDirectory(cmGeneratorTarget const*) const
{
// No per-target directory for this generator (yet).
return "";
@@ -1888,7 +1934,7 @@ cmLocalVisualStudio6Generator
//----------------------------------------------------------------------------
std::string
cmLocalVisualStudio6Generator
-::ComputeLongestObjectDirectory(cmTarget&) const
+::ComputeLongestObjectDirectory(cmGeneratorTarget const*) const
{
// Compute the maximum length configuration name.
std::string config_max;
@@ -1908,7 +1954,7 @@ cmLocalVisualStudio6Generator
// files directory for any configuration. This is used to construct
// object file names that do not produce paths that are too long.
std::string dir_max;
- dir_max += this->Makefile->GetCurrentOutputDirectory();
+ dir_max += this->GetCurrentBinaryDirectory();
dir_max += "/";
dir_max += config_max;
dir_max += "/";
@@ -1942,7 +1988,7 @@ cmLocalVisualStudio6Generator
if(define.find_first_of(" ") != define.npos &&
define.find_first_of("\"$;") != define.npos)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "WARNING: The VS6 IDE does not support preprocessor definition "
<< "values with spaces and '\"', '$', or ';'.\n"
<< "CMake is dropping a preprocessor definition: " << define << "\n"
diff --git a/Source/cmLocalVisualStudio6Generator.h b/Source/cmLocalVisualStudio6Generator.h
index f45bc1758..dab32a5f8 100644
--- a/Source/cmLocalVisualStudio6Generator.h
+++ b/Source/cmLocalVisualStudio6Generator.h
@@ -14,7 +14,6 @@
#include "cmLocalVisualStudioGenerator.h"
-class cmTarget;
class cmSourceFile;
class cmSourceGroup;
class cmCustomCommand;
@@ -29,11 +28,10 @@ class cmLocalVisualStudio6Generator : public cmLocalVisualStudioGenerator
{
public:
///! Set cache only and recurse to false by default.
- cmLocalVisualStudio6Generator();
+ cmLocalVisualStudio6Generator(cmGlobalGenerator* gg, cmMakefile* mf);
virtual ~cmLocalVisualStudio6Generator();
- virtual void AddHelperCommands();
virtual void AddCMakeListsRules();
/**
@@ -48,49 +46,53 @@ public:
/**
* Specify the type of the build: static, dll, or executable.
*/
- void SetBuildType(BuildType, const char* libName, cmTarget&);
+ void SetBuildType(BuildType, const std::string& libName, cmGeneratorTarget*);
- virtual std::string GetTargetDirectory(cmTarget const& target) const;
- virtual std::string ComputeLongestObjectDirectory(cmTarget&) const;
+ virtual
+ std::string GetTargetDirectory(cmGeneratorTarget const* target) const;
+ virtual std::string
+ ComputeLongestObjectDirectory(cmGeneratorTarget const*) const;
private:
std::string DSPHeaderTemplate;
std::string DSPFooterTemplate;
- void CreateSingleDSP(const char *lname, cmTarget &tgt);
- void WriteDSPFile(std::ostream& fout, const char *libName,
- cmTarget &tgt);
+ void CreateSingleDSP(const std::string& lname, cmGeneratorTarget* tgt);
+ void WriteDSPFile(std::ostream& fout, const std::string& libName,
+ cmGeneratorTarget* tgt);
void WriteDSPBeginGroup(std::ostream& fout,
const char* group,
const char* filter);
void WriteDSPEndGroup(std::ostream& fout);
- void WriteDSPHeader(std::ostream& fout, const char *libName,
- cmTarget &tgt, std::vector<cmSourceGroup> &sgs);
+ void WriteDSPHeader(std::ostream& fout, const std::string& libName,
+ cmGeneratorTarget* tgt, std::vector<cmSourceGroup> &sgs);
void WriteDSPFooter(std::ostream& fout);
- void AddDSPBuildRule(cmTarget& tgt);
+ void AddDSPBuildRule(cmGeneratorTarget* tgt);
void WriteCustomRule(std::ostream& fout,
const char* source,
const cmCustomCommand& command,
const char* flags);
- void AddUtilityCommandHack(cmTarget& target, int count,
+ void AddUtilityCommandHack(cmGeneratorTarget* target, int count,
std::vector<std::string>& depends,
const cmCustomCommand& origCommand);
- void WriteGroup(const cmSourceGroup *sg, cmTarget& target,
- std::ostream &fout, const char *libName);
+ void WriteGroup(const cmSourceGroup *sg, cmGeneratorTarget* target,
+ std::ostream &fout, const std::string& libName);
class EventWriter;
friend class EventWriter;
cmsys::auto_ptr<cmCustomCommand>
- MaybeCreateOutputDir(cmTarget& target, const char* config);
- std::string CreateTargetRules(cmTarget &target,
- const char* configName,
- const char *libName);
- void ComputeLinkOptions(cmTarget& target, const char* configName,
+ MaybeCreateOutputDir(cmGeneratorTarget *target, const std::string& config);
+ std::string CreateTargetRules(cmGeneratorTarget* target,
+ const std::string& configName,
+ const std::string& libName);
+ void ComputeLinkOptions(cmGeneratorTarget* target,
+ const std::string& configName,
const std::string extraOptions,
std::string& options);
- void OutputObjects(cmTarget& target, const char* tool,
+ void OutputObjects(cmGeneratorTarget* target, const char* tool,
std::string& options);
- std::string GetTargetIncludeOptions(cmTarget &target, const char *config);
+ std::string GetTargetIncludeOptions(cmGeneratorTarget* target,
+ const std::string& config);
std::vector<std::string> Configurations;
std::string GetConfigName(std::string const& configuration) const;
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 8ffd96eb1..ae6a24e26 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -16,20 +16,15 @@
#include "cmMakefile.h"
#include "cmSystemTools.h"
#include "cmSourceFile.h"
-#include "cmCacheManager.h"
#include "cmGeneratorTarget.h"
+#include "cmCustomCommandGenerator.h"
#include "cmake.h"
#include "cmComputeLinkInformation.h"
#include "cmGeneratedFileStream.h"
-#include <cmsys/System.h>
-
#include <ctype.h> // for isspace
-// Package GUID of Intel Visual Fortran plugin to VS IDE
-#define CM_INTEL_PLUGIN_GUID "{B68A201D-CB9B-47AF-A52F-7EEC72E217E4}"
-
static bool cmLVS6G_IsFAT(const char* dir);
class cmLocalVisualStudio7GeneratorInternals
@@ -39,19 +34,29 @@ public:
LocalGenerator(e) {}
typedef cmComputeLinkInformation::ItemVector ItemVector;
void OutputLibraries(std::ostream& fout, ItemVector const& libs);
- void OutputObjects(std::ostream& fout, cmTarget* t, const char* isep = 0);
+ void OutputObjects(std::ostream& fout, cmGeneratorTarget* t,
+ const char* isep = 0);
private:
cmLocalVisualStudio7Generator* LocalGenerator;
};
extern cmVS7FlagTable cmLocalVisualStudio7GeneratorFlagTable[];
+static void cmConvertToWindowsSlash(std::string& s)
+{
+ std::string::size_type pos = 0;
+ while((pos = s.find('/', pos)) != std::string::npos)
+ {
+ s[pos] = '\\';
+ pos++;
+ }
+}
+
//----------------------------------------------------------------------------
-cmLocalVisualStudio7Generator::cmLocalVisualStudio7Generator(VSVersion v):
- cmLocalVisualStudioGenerator(v)
+cmLocalVisualStudio7Generator
+::cmLocalVisualStudio7Generator(cmGlobalGenerator* gg, cmMakefile* mf):
+ cmLocalVisualStudioGenerator(gg, mf)
{
- this->PlatformName = "Win32";
- this->ExtraFlagTable = 0;
this->Internal = new cmLocalVisualStudio7GeneratorInternals(this);
}
@@ -62,31 +67,20 @@ cmLocalVisualStudio7Generator::~cmLocalVisualStudio7Generator()
void cmLocalVisualStudio7Generator::AddHelperCommands()
{
- std::set<cmStdString> lang;
- lang.insert("C");
- lang.insert("CXX");
- lang.insert("RC");
- lang.insert("IDL");
- lang.insert("DEF");
- lang.insert("Fortran");
- this->CreateCustomTargetsAndCommands(lang);
-
// Now create GUIDs for targets
- cmTargets &tgts = this->Makefile->GetTargets();
-
- cmGlobalVisualStudio7Generator* gg =
- static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator);
- for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
+ std::vector<cmGeneratorTarget*> tgts = this->GetGeneratorTargets();
+ for(std::vector<cmGeneratorTarget*>::iterator l = tgts.begin();
+ l != tgts.end(); ++l)
{
- const char* path = l->second.GetProperty("EXTERNAL_MSPROJECT");
- if(path)
+ if((*l)->GetType() == cmState::INTERFACE_LIBRARY)
{
- this->ReadAndStoreExternalGUID(
- l->second.GetName(), path);
+ continue;
}
- else
+ const char* path = (*l)->GetProperty("EXTERNAL_MSPROJECT");
+ if(path)
{
- gg->CreateGUID(l->first.c_str());
+ this->ReadAndStoreExternalGUID(
+ (*l)->GetName().c_str(), path);
}
}
@@ -102,7 +96,6 @@ void cmLocalVisualStudio7Generator::Generate()
void cmLocalVisualStudio7Generator::AddCMakeListsRules()
{
- cmTargets &tgts = this->Makefile->GetTargets();
// Create the regeneration custom rule.
if(!this->Makefile->IsOn("CMAKE_SUPPRESS_REGENERATION"))
{
@@ -111,11 +104,17 @@ void cmLocalVisualStudio7Generator::AddCMakeListsRules()
if(cmSourceFile* sf = this->CreateVCProjBuildRule())
{
// Add the rule to targets that need it.
- for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); ++l)
+ std::vector<cmGeneratorTarget*> tgts = this->GetGeneratorTargets();
+ for(std::vector<cmGeneratorTarget*>::iterator l = tgts.begin();
+ l != tgts.end(); ++l)
{
- if(l->first != CMAKE_CHECK_BUILD_SYSTEM_TARGET)
+ if ((*l)->GetType() == cmState::GLOBAL_TARGET)
{
- l->second.AddSourceFile(sf);
+ continue;
+ }
+ if((*l)->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET)
+ {
+ (*l)->AddSource(sf->GetFullPath());
}
}
}
@@ -127,12 +126,11 @@ void cmLocalVisualStudio7Generator::FixGlobalTargets()
// Visual Studio .NET 2003 Service Pack 1 will not run post-build
// commands for targets in which no sources are built. Add dummy
// rules to force these targets to build.
- cmTargets &tgts = this->Makefile->GetTargets();
- for(cmTargets::iterator l = tgts.begin();
+ std::vector<cmGeneratorTarget*> tgts = this->GetGeneratorTargets();
+ for(std::vector<cmGeneratorTarget*>::iterator l = tgts.begin();
l != tgts.end(); l++)
{
- cmTarget& tgt = l->second;
- if(tgt.GetType() == cmTarget::GLOBAL_TARGET)
+ if((*l)->GetType() == cmState::GLOBAL_TARGET)
{
std::vector<std::string> no_depends;
cmCustomCommandLine force_command;
@@ -140,18 +138,18 @@ void cmLocalVisualStudio7Generator::FixGlobalTargets()
force_command.push_back(".");
cmCustomCommandLines force_commands;
force_commands.push_back(force_command);
- const char* no_main_dependency = 0;
- std::string force = this->Makefile->GetStartOutputDirectory();
+ std::string no_main_dependency = "";
+ std::string force = this->GetCurrentBinaryDirectory();
force += cmake::GetCMakeFilesDirectory();
force += "/";
- force += tgt.GetName();
+ force += (*l)->GetName();
force += "_force";
if(cmSourceFile* file =
this->Makefile->AddCustomCommandToOutput(
force.c_str(), no_depends, no_main_dependency,
force_commands, " ", 0, true))
{
- tgt.AddSourceFile(file);
+ (*l)->AddSource(file->GetFullPath());
}
}
}
@@ -163,29 +161,33 @@ void cmLocalVisualStudio7Generator::FixGlobalTargets()
void cmLocalVisualStudio7Generator::WriteProjectFiles()
{
// If not an in source build, then create the output directory
- if(strcmp(this->Makefile->GetStartOutputDirectory(),
- this->Makefile->GetHomeDirectory()) != 0)
+ if(strcmp(this->GetCurrentBinaryDirectory(),
+ this->GetSourceDirectory()) != 0)
{
if(!cmSystemTools::MakeDirectory
- (this->Makefile->GetStartOutputDirectory()))
+ (this->GetCurrentBinaryDirectory()))
{
cmSystemTools::Error("Error creating directory ",
- this->Makefile->GetStartOutputDirectory());
+ this->GetCurrentBinaryDirectory());
}
}
// Get the set of targets in this directory.
- cmTargets &tgts = this->Makefile->GetTargets();
+ std::vector<cmGeneratorTarget*> tgts = this->GetGeneratorTargets();
// Create the project file for each target.
- for(cmTargets::iterator l = tgts.begin();
+ for(std::vector<cmGeneratorTarget*>::iterator l = tgts.begin();
l != tgts.end(); l++)
{
+ if((*l)->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ continue;
+ }
// INCLUDE_EXTERNAL_MSPROJECT command only affects the workspace
// so don't build a projectfile for it
- if(!l->second.GetProperty("EXTERNAL_MSPROJECT"))
+ if(!(*l)->GetProperty("EXTERNAL_MSPROJECT"))
{
- this->CreateSingleVCProj(l->first.c_str(),l->second);
+ this->CreateSingleVCProj((*l)->GetName().c_str(), *l);
}
}
}
@@ -195,12 +197,12 @@ void cmLocalVisualStudio7Generator::WriteStampFiles()
{
// Touch a timestamp file used to determine when the project file is
// out of date.
- std::string stampName = this->Makefile->GetStartOutputDirectory();
+ std::string stampName = this->GetCurrentBinaryDirectory();
stampName += cmake::GetCMakeFilesDirectory();
cmSystemTools::MakeDirectory(stampName.c_str());
stampName += "/";
stampName += "generate.stamp";
- std::ofstream stamp(stampName.c_str());
+ cmsys::ofstream stamp(stampName.c_str());
stamp << "# CMake generation timestamp file for this directory.\n";
// Create a helper file so CMake can determine when it is run
@@ -211,7 +213,7 @@ void cmLocalVisualStudio7Generator::WriteStampFiles()
// the stamp file can just be touched.
std::string depName = stampName;
depName += ".depend";
- std::ofstream depFile(depName.c_str());
+ cmsys::ofstream depFile(depName.c_str());
depFile << "# CMake generation dependency list for this directory.\n";
std::vector<std::string> const& listFiles = this->Makefile->GetListFiles();
for(std::vector<std::string>::const_iterator lf = listFiles.begin();
@@ -223,28 +225,26 @@ void cmLocalVisualStudio7Generator::WriteStampFiles()
//----------------------------------------------------------------------------
void cmLocalVisualStudio7Generator
-::CreateSingleVCProj(const char *lname, cmTarget &target)
+::CreateSingleVCProj(const std::string& lname, cmGeneratorTarget *target)
{
- this->FortranProject =
- static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator)
- ->TargetIsFortranOnly(target);
- this->WindowsCEProject =
- static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator)
- ->TargetsWindowsCE();
+ cmGlobalVisualStudioGenerator* gg
+ = static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator);
+ this->FortranProject = gg->TargetIsFortranOnly(target);
+ this->WindowsCEProject = gg->TargetsWindowsCE();
// Intel Fortran for VS10 uses VS9 format ".vfproj" files.
- VSVersion realVersion = this->Version;
- if(this->FortranProject && this->Version >= VS10)
+ cmGlobalVisualStudioGenerator::VSVersion realVersion = gg->GetVersion();
+ if(this->FortranProject
+ && gg->GetVersion() >= cmGlobalVisualStudioGenerator::VS10)
{
- this->Version = VS9;
+ gg->SetVersion(cmGlobalVisualStudioGenerator::VS9);
}
// add to the list of projects
- std::string pname = lname;
- target.SetProperty("GENERATOR_FILE_NAME",lname);
+ target->Target->SetProperty("GENERATOR_FILE_NAME",lname.c_str());
// create the dsp.cmake file
std::string fname;
- fname = this->Makefile->GetStartOutputDirectory();
+ fname = this->GetCurrentBinaryDirectory();
fname += "/";
fname += lname;
if(this->FortranProject)
@@ -267,21 +267,19 @@ void cmLocalVisualStudio7Generator
this->GlobalGenerator->FileReplacedDuringGenerate(fname);
}
- this->Version = realVersion;
+ gg->SetVersion(realVersion);
}
//----------------------------------------------------------------------------
cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
{
- std::string stampName = this->Makefile->GetCurrentOutputDirectory();
+ std::string stampName = this->GetCurrentBinaryDirectory();
stampName += "/";
stampName += cmake::GetCMakeFilesDirectoryPostSlash();
stampName += "generate.stamp";
- const char* dsprule =
- this->Makefile->GetRequiredDefinition("CMAKE_COMMAND");
cmCustomCommandLine commandLine;
- commandLine.push_back(dsprule);
- std::string makefileIn = this->Makefile->GetStartDirectory();
+ commandLine.push_back(cmSystemTools::GetCMakeCommand());
+ std::string makefileIn = this->GetCurrentSourceDirectory();
makefileIn += "/";
makefileIn += "CMakeLists.txt";
makefileIn = cmSystemTools::CollapseFullPath(makefileIn.c_str());
@@ -293,13 +291,10 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
comment += makefileIn;
std::string args;
args = "-H";
- args += this->Convert(this->Makefile->GetHomeDirectory(),
- START_OUTPUT, UNCHANGED, true);
+ args += this->GetSourceDirectory();
commandLine.push_back(args);
args = "-B";
- args +=
- this->Convert(this->Makefile->GetHomeOutputDirectory(),
- START_OUTPUT, UNCHANGED, true);
+ args += this->GetBinaryDirectory();
commandLine.push_back(args);
commandLine.push_back("--check-stamp-file");
std::string stampFilename = this->Convert(stampName.c_str(), FULL,
@@ -328,17 +323,15 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
}
}
-void cmLocalVisualStudio7Generator::WriteConfigurations(std::ostream& fout,
- const char *libName,
- cmTarget &target)
+void cmLocalVisualStudio7Generator::WriteConfigurations(
+ std::ostream& fout,
+ std::vector<std::string> const& configs,
+ const std::string& libName, cmGeneratorTarget *target
+ )
{
- std::vector<std::string> *configs =
- static_cast<cmGlobalVisualStudio7Generator *>
- (this->GlobalGenerator)->GetConfigurations();
-
fout << "\t<Configurations>\n";
- for( std::vector<std::string>::iterator i = configs->begin();
- i != configs->end(); ++i)
+ for (std::vector<std::string>::const_iterator i = configs.begin();
+ i != configs.end(); ++i)
{
this->WriteConfiguration(fout, i->c_str(), libName, target);
}
@@ -377,6 +370,13 @@ cmVS7FlagTable cmLocalVisualStudio7GeneratorFortranFlagTable[] =
{"OptimizeForProcessor", "QxT", "", "codeExclusivelyCore2Duo", 0},
{"OptimizeForProcessor", "QxO", "", "codeExclusivelyCore2StreamingSIMD", 0},
{"OptimizeForProcessor", "QxS", "", "codeExclusivelyCore2StreamingSIMD4", 0},
+ {"OpenMP", "Qopenmp", "", "OpenMPParallelCode", 0},
+ {"OpenMP", "Qopenmp-stubs", "", "OpenMPSequentialCode", 0},
+ {"Traceback", "traceback", "", "true", 0},
+ {"Traceback", "notraceback", "", "false", 0},
+ {"FloatingPointExceptionHandling", "fpe:0", "", "fpe0", 0},
+ {"FloatingPointExceptionHandling", "fpe:1", "", "fpe1", 0},
+ {"FloatingPointExceptionHandling", "fpe:3", "", "fpe3", 0},
{"ModulePath", "module:", "", "",
cmVS7FlagTable::UserValueRequired},
@@ -481,34 +481,34 @@ cmVS7FlagTable cmLocalVisualStudio7GeneratorFlagTable[] =
cmVS7FlagTable::UserValue},
// boolean flags
- {"BufferSecurityCheck", "GS", "Buffer security check", "TRUE", 0},
- {"BufferSecurityCheck", "GS-", "Turn off Buffer security check", "FALSE", 0},
+ {"BufferSecurityCheck", "GS", "Buffer security check", "true", 0},
+ {"BufferSecurityCheck", "GS-", "Turn off Buffer security check", "false", 0},
{"Detect64BitPortabilityProblems", "Wp64",
- "Detect 64-bit Portability Problems", "TRUE", 0},
+ "Detect 64-bit Portability Problems", "true", 0},
{"EnableFiberSafeOptimizations", "GT", "Enable Fiber-safe Optimizations",
- "TRUE", 0},
+ "true", 0},
{"EnableFunctionLevelLinking", "Gy",
- "EnableFunctionLevelLinking", "TRUE", 0},
- {"EnableIntrinsicFunctions", "Oi", "EnableIntrinsicFunctions", "TRUE", 0},
- {"GlobalOptimizations", "Og", "Global Optimize", "TRUE", 0},
+ "EnableFunctionLevelLinking", "true", 0},
+ {"EnableIntrinsicFunctions", "Oi", "EnableIntrinsicFunctions", "true", 0},
+ {"GlobalOptimizations", "Og", "Global Optimize", "true", 0},
{"ImproveFloatingPointConsistency", "Op",
- "ImproveFloatingPointConsistency", "TRUE", 0},
- {"MinimalRebuild", "Gm", "minimal rebuild", "TRUE", 0},
- {"OmitFramePointers", "Oy", "OmitFramePointers", "TRUE", 0},
- {"OptimizeForWindowsApplication", "GA", "Optimize for windows", "TRUE", 0},
+ "ImproveFloatingPointConsistency", "true", 0},
+ {"MinimalRebuild", "Gm", "minimal rebuild", "true", 0},
+ {"OmitFramePointers", "Oy", "OmitFramePointers", "true", 0},
+ {"OptimizeForWindowsApplication", "GA", "Optimize for windows", "true", 0},
{"RuntimeTypeInfo", "GR",
- "Turn on Run time type information for c++", "TRUE", 0},
+ "Turn on Run time type information for c++", "true", 0},
{"RuntimeTypeInfo", "GR-",
- "Turn off Run time type information for c++", "FALSE", 0},
- {"SmallerTypeCheck", "RTCc", "smaller type check", "TRUE", 0},
- {"SuppressStartupBanner", "nologo", "SuppressStartupBanner", "TRUE", 0},
+ "Turn off Run time type information for c++", "false", 0},
+ {"SmallerTypeCheck", "RTCc", "smaller type check", "true", 0},
+ {"SuppressStartupBanner", "nologo", "SuppressStartupBanner", "true", 0},
{"WholeProgramOptimization", "GL",
- "Enables whole program optimization", "TRUE", 0},
+ "Enables whole program optimization", "true", 0},
{"WholeProgramOptimization", "GL-",
- "Disables whole program optimization", "FALSE", 0},
- {"WarnAsError", "WX", "Treat warnings as errors", "TRUE", 0},
+ "Disables whole program optimization", "false", 0},
+ {"WarnAsError", "WX", "Treat warnings as errors", "true", 0},
{"BrowseInformation", "FR", "Generate browse information", "1", 0},
- {"StringPooling", "GF", "Enable StringPooling", "TRUE", 0},
+ {"StringPooling", "GF", "Enable StringPooling", "true", 0},
{0,0,0,0,0}
};
@@ -518,8 +518,8 @@ cmVS7FlagTable cmLocalVisualStudio7GeneratorLinkFlagTable[] =
{
// option flags (some flags map to the same option)
{"GenerateManifest", "MANIFEST:NO",
- "disable manifest generation", "FALSE", 0},
- {"GenerateManifest", "MANIFEST", "enable manifest generation", "TRUE", 0},
+ "disable manifest generation", "false", 0},
+ {"GenerateManifest", "MANIFEST", "enable manifest generation", "true", 0},
{"LinkIncremental", "INCREMENTAL:NO", "link incremental", "1", 0},
{"LinkIncremental", "INCREMENTAL:YES", "link incremental", "2", 0},
{"CLRUnmanagedCodeCheck", "CLRUNMANAGEDCODECHECK:NO", "", "false", 0},
@@ -535,7 +535,7 @@ cmVS7FlagTable cmLocalVisualStudio7GeneratorLinkFlagTable[] =
{"IgnoreDefaultLibraryNames", "NODEFAULTLIB:", "default libs to ignore", "",
cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
{"IgnoreAllDefaultLibraries", "NODEFAULTLIB", "ignore all default libs",
- "TRUE", 0},
+ "true", 0},
{"FixedBaseAddress", "FIXED:NO", "Generate a relocation section", "1", 0},
{"FixedBaseAddress", "FIXED", "Image must be loaded at a fixed address",
"2", 0},
@@ -574,7 +574,16 @@ cmVS7FlagTable cmLocalVisualStudio7GeneratorLinkFlagTable[] =
"No assembly even if CLR information is present in objects.", "true", 0},
{"ModuleDefinitionFile", "DEF:", "add an export def file", "",
cmVS7FlagTable::UserValue},
- {"GenerateMapFile", "MAP", "enable generation of map file", "TRUE", 0},
+ {"GenerateMapFile", "MAP", "enable generation of map file", "true", 0},
+ {0,0,0,0,0}
+};
+
+cmVS7FlagTable cmLocalVisualStudio7GeneratorFortranLinkFlagTable[] =
+{
+ {"LinkIncremental", "INCREMENTAL:NO", "link incremental",
+ "linkIncrementalNo", 0},
+ {"LinkIncremental", "INCREMENTAL:YES", "link incremental",
+ "linkIncrementalYes", 0},
{0,0,0,0,0}
};
@@ -584,7 +593,7 @@ class cmLocalVisualStudio7Generator::EventWriter
{
public:
EventWriter(cmLocalVisualStudio7Generator* lg,
- const char* config, std::ostream& os):
+ const std::string& config, std::ostream& os):
LG(lg), Config(config), Stream(os), First(true) {}
void Start(const char* tool)
{
@@ -605,9 +614,10 @@ public:
}
void Write(cmCustomCommand const& cc)
{
+ cmCustomCommandGenerator ccg(cc, this->Config, this->LG);
if(this->First)
{
- const char* comment = cc.GetComment();
+ const char* comment = ccg.GetComment();
if(comment && *comment)
{
this->Stream << "\nDescription=\""
@@ -620,30 +630,32 @@ public:
{
this->Stream << this->LG->EscapeForXML("\n");
}
- std::string script = this->LG->ConstructScript(cc, this->Config);
+ std::string script = this->LG->ConstructScript(ccg);
this->Stream << this->LG->EscapeForXML(script.c_str());
}
private:
cmLocalVisualStudio7Generator* LG;
- const char* Config;
+ std::string Config;
std::ostream& Stream;
bool First;
};
//----------------------------------------------------------------------------
void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
- const char* configName,
- const char *libName,
- cmTarget &target)
+ const std::string& configName,
+ const std::string& libName,
+ cmGeneratorTarget *target)
{
const char* mfcFlag = this->Makefile->GetDefinition("CMAKE_MFC_FLAG");
if(!mfcFlag)
{
mfcFlag = "0";
}
+ cmGlobalVisualStudio7Generator* gg =
+ static_cast<cmGlobalVisualStudio7Generator*>(this->GlobalGenerator);
fout << "\t\t<Configuration\n"
- << "\t\t\tName=\"" << configName << "|" << this->PlatformName << "\"\n"
- << "\t\t\tOutputDirectory=\"" << configName << "\"\n";
+ << "\t\t\tName=\"" << configName
+ << "|" << gg->GetPlatformName() << "\"\n";
// This is an internal type to Visual Studio, it seems that:
// 4 == static library
// 2 == dll
@@ -652,24 +664,25 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
const char* configType = "10";
const char* projectType = 0;
bool targetBuilds = true;
- switch(target.GetType())
+
+ switch(target->GetType())
{
- case cmTarget::OBJECT_LIBRARY:
- targetBuilds = false; // TODO: PDB for object library?
- case cmTarget::STATIC_LIBRARY:
+ case cmState::OBJECT_LIBRARY:
+ targetBuilds = false; // no manifest tool for object library
+ case cmState::STATIC_LIBRARY:
projectType = "typeStaticLibrary";
configType = "4";
break;
- case cmTarget::SHARED_LIBRARY:
- case cmTarget::MODULE_LIBRARY:
+ case cmState::SHARED_LIBRARY:
+ case cmState::MODULE_LIBRARY:
projectType = "typeDynamicLibrary";
configType = "2";
break;
- case cmTarget::EXECUTABLE:
+ case cmState::EXECUTABLE:
configType = "1";
break;
- case cmTarget::UTILITY:
- case cmTarget::GLOBAL_TARGET:
+ case cmState::UTILITY:
+ case cmState::GLOBAL_TARGET:
configType = "10";
default:
targetBuilds = false;
@@ -682,17 +695,18 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
std::string flags;
if(strcmp(configType, "10") != 0)
{
- const char* linkLanguage = (this->FortranProject? "Fortran":
- target.GetLinkerLanguage(configName));
- if(!linkLanguage)
+ const std::string& linkLanguage = (this->FortranProject?
+ std::string("Fortran"):
+ target->GetLinkerLanguage(configName));
+ if(linkLanguage.empty())
{
cmSystemTools::Error
("CMake can not determine linker language for target: ",
- target.GetName());
+ target->GetName().c_str());
return;
}
- if(strcmp(linkLanguage, "C") == 0 || strcmp(linkLanguage, "CXX") == 0
- || strcmp(linkLanguage, "Fortran") == 0)
+ if(linkLanguage == "C" || linkLanguage == "CXX"
+ || linkLanguage == "Fortran")
{
std::string baseFlagVar = "CMAKE_";
baseFlagVar += linkLanguage;
@@ -704,22 +718,22 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
flags += this->Makefile->GetRequiredDefinition(flagVar.c_str());
}
// set the correct language
- if(strcmp(linkLanguage, "C") == 0)
+ if(linkLanguage == "C")
{
flags += " /TC ";
}
- if(strcmp(linkLanguage, "CXX") == 0)
+ if(linkLanguage == "CXX")
{
flags += " /TP ";
}
// Add the target-specific flags.
- this->AddCompileOptions(flags, &target, linkLanguage, configName);
+ this->AddCompileOptions(flags, target, linkLanguage, configName);
}
if(this->FortranProject)
{
- switch(this->GetFortranFormat(target.GetProperty("Fortran_FORMAT")))
+ switch(this->GetFortranFormat(target->GetProperty("Fortran_FORMAT")))
{
case FortranFormatFixed: flags += " -fixed"; break;
case FortranFormatFree: flags += " -free"; break;
@@ -738,17 +752,15 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
}
Options targetOptions(this, t,
table,
- this->ExtraFlagTable);
+ gg->ExtraFlagTable);
targetOptions.FixExceptionHandlingDefault();
- std::string asmLocation = std::string(configName) + "/";
+ std::string asmLocation = configName + "/";
targetOptions.AddFlag("AssemblerListingLocation", asmLocation.c_str());
targetOptions.Parse(flags.c_str());
targetOptions.Parse(defineFlags.c_str());
targetOptions.ParseFinish();
- cmGeneratorTarget* gt =
- this->GlobalGenerator->GetGeneratorTarget(&target);
std::vector<std::string> targetDefines;
- target.GetCompileDefinitions(targetDefines, configName);
+ target->GetCompileDefinitions(targetDefines, configName, "CXX");
targetOptions.AddDefines(targetDefines);
targetOptions.SetVerboseMakefile(
this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
@@ -760,7 +772,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
targetOptions.AddDefine(configDefine);
// Add the export symbol definition for shared library objects.
- if(const char* exportMacro = target.GetExportMacro())
+ if(const char* exportMacro = target->GetExportMacro())
{
targetOptions.AddDefine(exportMacro);
}
@@ -770,12 +782,36 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
std::string intermediateDir = this->GetTargetDirectory(target);
intermediateDir += "/";
intermediateDir += configName;
+
+ if (target->GetType() < cmState::UTILITY)
+ {
+ std::string const& outDir =
+ target->GetType() == cmState::OBJECT_LIBRARY?
+ intermediateDir : target->GetDirectory(configName);
+ fout << "\t\t\tOutputDirectory=\""
+ << this->ConvertToXMLOutputPathSingle(outDir.c_str()) << "\"\n";
+ }
+
fout << "\t\t\tIntermediateDirectory=\""
<< this->ConvertToXMLOutputPath(intermediateDir.c_str())
<< "\"\n"
<< "\t\t\tConfigurationType=\"" << configType << "\"\n"
<< "\t\t\tUseOfMFC=\"" << mfcFlag << "\"\n"
- << "\t\t\tATLMinimizesCRunTimeLibraryUsage=\"FALSE\"\n";
+ << "\t\t\tATLMinimizesCRunTimeLibraryUsage=\"false\"\n";
+
+ if (this->FortranProject)
+ {
+ // Intel Fortran >= 15.0 uses TargetName property.
+ std::string targetNameFull = target->GetFullName(configName);
+ std::string targetName =
+ cmSystemTools::GetFilenameWithoutLastExtension(targetNameFull);
+ std::string targetExt =
+ cmSystemTools::GetFilenameLastExtension(targetNameFull);
+ fout <<
+ "\t\t\tTargetName=\"" << this->EscapeForXML(targetName) << "\"\n"
+ "\t\t\tTargetExt=\"" << this->EscapeForXML(targetExt) << "\"\n"
+ ;
+ }
// If unicode is enabled change the character set to unicode, if not
// then default to MBCS.
@@ -801,7 +837,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
if(this->FortranProject)
{
const char* target_mod_dir =
- target.GetProperty("Fortran_MODULE_DIRECTORY");
+ target->GetProperty("Fortran_MODULE_DIRECTORY");
std::string modDir;
if(target_mod_dir)
{
@@ -820,7 +856,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
targetOptions.OutputAdditionalOptions(fout, "\t\t\t\t", "\n");
fout << "\t\t\t\tAdditionalIncludeDirectories=\"";
std::vector<std::string> includes;
- this->GetIncludeDirectories(includes, gt, "C", configName);
+ this->GetIncludeDirectories(includes, target, "C", configName);
std::vector<std::string>::iterator i = includes.begin();
for(;i != includes.end(); ++i)
{
@@ -841,7 +877,43 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
targetOptions.OutputFlagMap(fout, "\t\t\t\t");
targetOptions.OutputPreprocessorDefinitions(fout, "\t\t\t\t", "\n", "CXX");
fout << "\t\t\t\tObjectFile=\"$(IntDir)\\\"\n";
+ if(target->GetType() <= cmState::OBJECT_LIBRARY)
+ {
+ // Specify the compiler program database file if configured.
+ std::string pdb = target->GetCompilePDBPath(configName);
+ if(!pdb.empty())
+ {
+ fout << "\t\t\t\tProgramDataBaseFileName=\""
+ << this->ConvertToXMLOutputPathSingle(pdb.c_str())
+ << "\"\n";
+ }
+ }
fout << "/>\n"; // end of <Tool Name=VCCLCompilerTool
+ if(gg->IsMasmEnabled() && !this->FortranProject)
+ {
+ Options masmOptions(this, Options::MasmCompiler, 0, 0);
+ fout <<
+ "\t\t\t<Tool\n"
+ "\t\t\t\tName=\"MASM\"\n"
+ "\t\t\t\tIncludePaths=\""
+ ;
+ const char* sep = "";
+ for(i = includes.begin(); i != includes.end(); ++i)
+ {
+ std::string inc = *i;
+ cmConvertToWindowsSlash(inc);
+ fout << sep << this->EscapeForXML(inc);
+ sep = ";";
+ }
+ fout << "\"\n";
+ // Use same preprocessor definitions as VCCLCompilerTool.
+ targetOptions.OutputPreprocessorDefinitions(fout, "\t\t\t\t", "\n",
+ "ASM_MASM");
+ masmOptions.OutputFlagMap(fout, "\t\t\t\t");
+ fout <<
+ "\t\t\t\tObjectFile=\"$(IntDir)\\\"\n"
+ "\t\t\t/>\n";
+ }
tool = "VCCustomBuildTool";
if(this->FortranProject)
{
@@ -877,12 +949,12 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
fout << ipath << ";";
}
fout << "\"\n";
- fout << "\t\t\t\tMkTypLibCompatible=\"FALSE\"\n";
- if( this->PlatformName == "x64" )
+ fout << "\t\t\t\tMkTypLibCompatible=\"false\"\n";
+ if( gg->GetPlatformName() == "x64" )
{
fout << "\t\t\t\tTargetEnvironment=\"3\"\n";
}
- else if( this->PlatformName == "ia64" )
+ else if( gg->GetPlatformName() == "ia64" )
{
fout << "\t\t\t\tTargetEnvironment=\"2\"\n";
}
@@ -890,7 +962,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
{
fout << "\t\t\t\tTargetEnvironment=\"1\"\n";
}
- fout << "\t\t\t\tGenerateStublessProxies=\"TRUE\"\n";
+ fout << "\t\t\t\tGenerateStublessProxies=\"true\"\n";
fout << "\t\t\t\tTypeLibraryName=\"$(InputName).tlb\"\n";
fout << "\t\t\t\tOutputDirectory=\"$(IntDir)\"\n";
fout << "\t\t\t\tHeaderFileName=\"$(InputName).h\"\n";
@@ -899,25 +971,43 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
fout << "\t\t\t\tProxyFileName=\"$(InputName)_p.c\"/>\n";
// end of <Tool Name=VCMIDLTool
- // Check if we need the FAT32 workaround.
- if(targetBuilds && this->Version >= VS8)
+ // Add manifest tool settings.
+ if(targetBuilds && this->GetVersion() >= cmGlobalVisualStudioGenerator::VS8)
{
+ const char* manifestTool = "VCManifestTool";
+ if (this->FortranProject)
+ {
+ manifestTool = "VFManifestTool";
+ }
+ fout <<
+ "\t\t\t<Tool\n"
+ "\t\t\t\tName=\"" << manifestTool << "\"";
+
+ std::vector<cmSourceFile const*> manifest_srcs;
+ target->GetManifests(manifest_srcs, configName);
+ if (!manifest_srcs.empty())
+ {
+ fout << "\n\t\t\t\tAdditionalManifestFiles=\"";
+ for (std::vector<cmSourceFile const*>::const_iterator
+ mi = manifest_srcs.begin(); mi != manifest_srcs.end(); ++mi)
+ {
+ std::string m = (*mi)->GetFullPath();
+ fout << this->ConvertToXMLOutputPath(m.c_str()) << ";";
+ }
+ fout << "\"";
+ }
+
+ // Check if we need the FAT32 workaround.
// Check the filesystem type where the target will be written.
- if(cmLVS6G_IsFAT(target.GetDirectory(configName).c_str()))
+ if (cmLVS6G_IsFAT(target->GetDirectory(configName).c_str()))
{
// Add a flag telling the manifest tool to use a workaround
// for FAT32 file systems, which can cause an empty manifest
// to be embedded into the resulting executable. See CMake
// bug #2617.
- const char* manifestTool = "VCManifestTool";
- if(this->FortranProject)
- {
- manifestTool = "VFManifestTool";
- }
- fout << "\t\t\t<Tool\n\t\t\t\tName=\"" << manifestTool << "\"\n"
- << "\t\t\t\tUseFAT32Workaround=\"true\"\n"
- << "\t\t\t/>\n";
+ fout << "\n\t\t\t\tUseFAT32Workaround=\"true\"";
}
+ fout << "/>\n";
}
this->OutputTargetRules(fout, configName, target, libName);
@@ -928,7 +1018,8 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
//----------------------------------------------------------------------------
std::string
cmLocalVisualStudio7Generator
-::GetBuildTypeLinkerFlags(std::string rootLinkerFlags, const char* configName)
+::GetBuildTypeLinkerFlags(std::string rootLinkerFlags,
+ const std::string& configName)
{
std::string configTypeUpper = cmSystemTools::UpperCase(configName);
std::string extraLinkOptionsBuildTypeDef =
@@ -942,27 +1033,28 @@ cmLocalVisualStudio7Generator
}
void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
- const char* configName, cmTarget &target, const Options& targetOptions)
+ const std::string& configName, cmGeneratorTarget* target,
+ const Options& targetOptions)
{
cmGlobalVisualStudio7Generator* gg =
static_cast<cmGlobalVisualStudio7Generator*>(this->GlobalGenerator);
std::string temp;
std::string extraLinkOptions;
- if(target.GetType() == cmTarget::EXECUTABLE)
+ if(target->GetType() == cmState::EXECUTABLE)
{
extraLinkOptions =
this->Makefile->GetRequiredDefinition("CMAKE_EXE_LINKER_FLAGS")
+ std::string(" ")
+ GetBuildTypeLinkerFlags("CMAKE_EXE_LINKER_FLAGS", configName);
}
- if(target.GetType() == cmTarget::SHARED_LIBRARY)
+ if(target->GetType() == cmState::SHARED_LIBRARY)
{
extraLinkOptions =
this->Makefile->GetRequiredDefinition("CMAKE_SHARED_LINKER_FLAGS")
+ std::string(" ")
+ GetBuildTypeLinkerFlags("CMAKE_SHARED_LINKER_FLAGS", configName);
}
- if(target.GetType() == cmTarget::MODULE_LIBRARY)
+ if(target->GetType() == cmState::MODULE_LIBRARY)
{
extraLinkOptions =
this->Makefile->GetRequiredDefinition("CMAKE_MODULE_LINKER_FLAGS")
@@ -970,7 +1062,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
+ GetBuildTypeLinkerFlags("CMAKE_MODULE_LINKER_FLAGS", configName);
}
- const char* targetLinkFlags = target.GetProperty("LINK_FLAGS");
+ const char* targetLinkFlags = target->GetProperty("LINK_FLAGS");
if(targetLinkFlags)
{
extraLinkOptions += " ";
@@ -979,32 +1071,46 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
std::string configTypeUpper = cmSystemTools::UpperCase(configName);
std::string linkFlagsConfig = "LINK_FLAGS_";
linkFlagsConfig += configTypeUpper;
- targetLinkFlags = target.GetProperty(linkFlagsConfig.c_str());
+ targetLinkFlags = target->GetProperty(linkFlagsConfig.c_str());
if(targetLinkFlags)
{
extraLinkOptions += " ";
extraLinkOptions += targetLinkFlags;
}
- Options linkOptions(this, Options::Linker,
- cmLocalVisualStudio7GeneratorLinkFlagTable);
+ Options linkOptions(this, Options::Linker);
+ if(this->FortranProject)
+ {
+ linkOptions.AddTable(cmLocalVisualStudio7GeneratorFortranLinkFlagTable);
+ }
+ linkOptions.AddTable(cmLocalVisualStudio7GeneratorLinkFlagTable);
+
linkOptions.Parse(extraLinkOptions.c_str());
if(!this->ModuleDefinitionFile.empty())
{
std::string defFile =
- this->ConvertToXMLOutputPath(this->ModuleDefinitionFile.c_str());
+ this->ConvertToOutputFormat(this->ModuleDefinitionFile, SHELL);
linkOptions.AddFlag("ModuleDefinitionFile", defFile.c_str());
}
- switch(target.GetType())
+
+ if (target->GetType() == cmState::SHARED_LIBRARY &&
+ this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
{
- case cmTarget::UNKNOWN_LIBRARY:
+ if (target->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+ {
+ linkOptions.AddFlag("ModuleDefinitionFile", "$(IntDir)/exportall.def");
+ }
+ }
+ switch(target->GetType())
+ {
+ case cmState::UNKNOWN_LIBRARY:
break;
- case cmTarget::OBJECT_LIBRARY:
+ case cmState::OBJECT_LIBRARY:
{
std::string libpath = this->GetTargetDirectory(target);
libpath += "/";
libpath += configName;
libpath += "/";
- libpath += target.GetName();
+ libpath += target->GetName();
libpath += ".lib";
const char* tool =
this->FortranProject? "VFLibrarianTool":"VCLibrarianTool";
@@ -1014,10 +1120,10 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
<< this->ConvertToXMLOutputPathSingle(libpath.c_str()) << "\"/>\n";
break;
}
- case cmTarget::STATIC_LIBRARY:
+ case cmState::STATIC_LIBRARY:
{
- std::string targetNameFull = target.GetFullName(configName);
- std::string libpath = target.GetDirectory(configName);
+ std::string targetNameFull = target->GetFullName(configName);
+ std::string libpath = target->GetDirectory(configName);
libpath += "/";
libpath += targetNameFull;
const char* tool = "VCLibrarianTool";
@@ -1028,17 +1134,18 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
fout << "\t\t\t<Tool\n"
<< "\t\t\t\tName=\"" << tool << "\"\n";
- if(this->GetVersion() < VS8)
+ if(this->GetVersion() < cmGlobalVisualStudioGenerator::VS8
+ || this->FortranProject)
{
- cmOStringStream libdeps;
- this->Internal->OutputObjects(libdeps, &target);
+ std::ostringstream libdeps;
+ this->Internal->OutputObjects(libdeps, target);
if(!libdeps.str().empty())
{
fout << "\t\t\t\tAdditionalDependencies=\"" << libdeps.str() << "\"\n";
}
}
std::string libflags;
- this->GetStaticLibraryFlags(libflags, configTypeUpper, &target);
+ this->GetStaticLibraryFlags(libflags, configTypeUpper, target);
if(!libflags.empty())
{
fout << "\t\t\t\tAdditionalOptions=\"" << libflags << "\"\n";
@@ -1047,25 +1154,25 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
<< this->ConvertToXMLOutputPathSingle(libpath.c_str()) << "\"/>\n";
break;
}
- case cmTarget::SHARED_LIBRARY:
- case cmTarget::MODULE_LIBRARY:
+ case cmState::SHARED_LIBRARY:
+ case cmState::MODULE_LIBRARY:
{
std::string targetName;
std::string targetNameSO;
std::string targetNameFull;
std::string targetNameImport;
std::string targetNamePDB;
- target.GetLibraryNames(targetName, targetNameSO, targetNameFull,
+ target->GetLibraryNames(targetName, targetNameSO, targetNameFull,
targetNameImport, targetNamePDB, configName);
// Compute the link library and directory information.
- cmComputeLinkInformation* pcli = target.GetLinkInformation(configName);
+ cmComputeLinkInformation* pcli = target->GetLinkInformation(configName);
if(!pcli)
{
return;
}
cmComputeLinkInformation& cli = *pcli;
- const char* linkLanguage = cli.GetLinkLanguage();
+ std::string linkLanguage = cli.GetLinkLanguage();
// Compute the variable name to lookup standard libraries for this
// language.
@@ -1088,14 +1195,15 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
// libraries which may be set by the user to something bad.
fout << "\t\t\t\tAdditionalDependencies=\"$(NOINHERIT) "
<< this->Makefile->GetSafeDefinition(standardLibsVar.c_str());
- if(this->GetVersion() < VS8)
+ if(this->GetVersion() < cmGlobalVisualStudioGenerator::VS8
+ || this->FortranProject)
{
- this->Internal->OutputObjects(fout, &target, " ");
+ this->Internal->OutputObjects(fout, target, " ");
}
fout << " ";
this->Internal->OutputLibraries(fout, cli.GetItems());
fout << "\"\n";
- temp = target.GetDirectory(configName);
+ temp = target->GetDirectory(configName);
temp += "/";
temp += targetNameFull;
fout << "\t\t\t\tOutputFile=\""
@@ -1105,18 +1213,18 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
this->OutputLibraryDirectories(fout, cli.GetDirectories());
fout << "\"\n";
- temp = target.GetPDBDirectory(configName);
+ temp = target->GetPDBDirectory(configName);
temp += "/";
temp += targetNamePDB;
fout << "\t\t\t\tProgramDatabaseFile=\"" <<
this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
if(targetOptions.IsDebug())
{
- fout << "\t\t\t\tGenerateDebugInformation=\"TRUE\"\n";
+ fout << "\t\t\t\tGenerateDebugInformation=\"true\"\n";
}
if(this->WindowsCEProject)
{
- if(this->GetVersion() < VS9)
+ if(this->GetVersion() < cmGlobalVisualStudioGenerator::VS9)
{
fout << "\t\t\t\tSubSystem=\"9\"\n";
}
@@ -1133,7 +1241,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
{
fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\"\n";
}
- temp = target.GetDirectory(configName, true);
+ temp = target->GetDirectory(configName, true);
temp += "/";
temp += targetNameImport;
fout << "\t\t\t\tImportLibrary=\""
@@ -1145,25 +1253,25 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
fout << "/>\n";
}
break;
- case cmTarget::EXECUTABLE:
+ case cmState::EXECUTABLE:
{
std::string targetName;
std::string targetNameFull;
std::string targetNameImport;
std::string targetNamePDB;
- target.GetExecutableNames(targetName, targetNameFull,
+ target->GetExecutableNames(targetName, targetNameFull,
targetNameImport, targetNamePDB, configName);
// Compute the link library and directory information.
- cmComputeLinkInformation* pcli = target.GetLinkInformation(configName);
+ cmComputeLinkInformation* pcli = target->GetLinkInformation(configName);
if(!pcli)
{
return;
}
cmComputeLinkInformation& cli = *pcli;
- const char* linkLanguage = cli.GetLinkLanguage();
+ std::string linkLanguage = cli.GetLinkLanguage();
- bool isWin32Executable = target.GetPropertyAsBool("WIN32_EXECUTABLE");
+ bool isWin32Executable = target->GetPropertyAsBool("WIN32_EXECUTABLE");
// Compute the variable name to lookup standard libraries for this
// language.
@@ -1186,14 +1294,15 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
// libraries which may be set by the user to something bad.
fout << "\t\t\t\tAdditionalDependencies=\"$(NOINHERIT) "
<< this->Makefile->GetSafeDefinition(standardLibsVar.c_str());
- if(this->GetVersion() < VS8)
+ if(this->GetVersion() < cmGlobalVisualStudioGenerator::VS8
+ || this->FortranProject)
{
- this->Internal->OutputObjects(fout, &target, " ");
+ this->Internal->OutputObjects(fout, target, " ");
}
fout << " ";
this->Internal->OutputLibraries(fout, cli.GetItems());
fout << "\"\n";
- temp = target.GetDirectory(configName);
+ temp = target->GetDirectory(configName);
temp += "/";
temp += targetNameFull;
fout << "\t\t\t\tOutputFile=\""
@@ -1204,17 +1313,17 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
this->OutputLibraryDirectories(fout, cli.GetDirectories());
fout << "\"\n";
std::string path = this->ConvertToXMLOutputPathSingle(
- target.GetPDBDirectory(configName).c_str());
+ target->GetPDBDirectory(configName).c_str());
fout << "\t\t\t\tProgramDatabaseFile=\""
<< path << "/" << targetNamePDB
<< "\"\n";
if(targetOptions.IsDebug())
{
- fout << "\t\t\t\tGenerateDebugInformation=\"TRUE\"\n";
+ fout << "\t\t\t\tGenerateDebugInformation=\"true\"\n";
}
if ( this->WindowsCEProject )
{
- if(this->GetVersion() < VS9)
+ if(this->GetVersion() < cmGlobalVisualStudioGenerator::VS9)
{
fout << "\t\t\t\tSubSystem=\"9\"\n";
}
@@ -1251,15 +1360,16 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
{
fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\"";
}
- temp = target.GetDirectory(configName, true);
+ temp = target->GetDirectory(configName, true);
temp += "/";
temp += targetNameImport;
fout << "\t\t\t\tImportLibrary=\""
<< this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"/>\n";
break;
}
- case cmTarget::UTILITY:
- case cmTarget::GLOBAL_TARGET:
+ case cmState::UTILITY:
+ case cmState::GLOBAL_TARGET:
+ case cmState::INTERFACE_LIBRARY:
break;
}
}
@@ -1267,11 +1377,11 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
//----------------------------------------------------------------------------
void
cmLocalVisualStudio7Generator
-::WriteTargetVersionAttribute(std::ostream& fout, cmTarget& target)
+::WriteTargetVersionAttribute(std::ostream& fout, cmGeneratorTarget* gt)
{
int major;
int minor;
- target.GetTargetVersion(major, minor);
+ gt->GetTargetVersion(major, minor);
fout << "\t\t\t\tVersion=\"" << major << "." << minor << "\"\n";
}
@@ -1290,7 +1400,8 @@ cmLocalVisualStudio7GeneratorInternals
cmLocalGenerator::UNCHANGED);
fout << lg->ConvertToXMLOutputPath(rel.c_str()) << " ";
}
- else
+ else if (!l->Target
+ || l->Target->GetType() != cmState::INTERFACE_LIBRARY)
{
fout << l->Value << " ";
}
@@ -1300,15 +1411,13 @@ cmLocalVisualStudio7GeneratorInternals
//----------------------------------------------------------------------------
void
cmLocalVisualStudio7GeneratorInternals
-::OutputObjects(std::ostream& fout, cmTarget* t, const char* isep)
+::OutputObjects(std::ostream& fout, cmGeneratorTarget* gt, const char* isep)
{
// VS < 8 does not support per-config source locations so we
// list object library content on the link line instead.
cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
- cmGeneratorTarget* gt =
- lg->GetGlobalGenerator()->GetGeneratorTarget(t);
std::vector<std::string> objs;
- gt->UseObjectLibraries(objs);
+ gt->UseObjectLibraries(objs, "");
const char* sep = isep? isep : "";
for(std::vector<std::string>::const_iterator
oi = objs.begin(); oi != objs.end(); ++oi)
@@ -1354,45 +1463,52 @@ cmLocalVisualStudio7Generator
// First search a configuration-specific subdirectory and then the
// original directory.
- fout << comma << this->ConvertToXMLOutputPath((dir+"/$(OutDir)").c_str())
+ fout << comma
+ << this->ConvertToXMLOutputPath((dir+"/$(ConfigurationName)").c_str())
<< "," << this->ConvertToXMLOutputPath(dir.c_str());
comma = ",";
}
}
void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
- const char *libName,
- cmTarget &target)
+ const std::string& libName,
+ cmGeneratorTarget* target)
{
- // get the configurations
- std::vector<std::string> *configs =
- static_cast<cmGlobalVisualStudio7Generator *>
- (this->GlobalGenerator)->GetConfigurations();
+ std::vector<std::string> configs;
+ this->Makefile->GetConfigurations(configs);
// We may be modifying the source groups temporarily, so make a copy.
std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
// get the classes from the source lists then add them to the groups
this->ModuleDefinitionFile = "";
- std::vector<cmSourceFile*>const & classes = target.GetSourceFiles();
+ std::vector<cmSourceFile*> classes;
+ if (!target->GetConfigCommonSourceFiles(classes))
+ {
+ return;
+ }
for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
i != classes.end(); i++)
{
+ if (!(*i)->GetObjectLibrary().empty())
+ {
+ continue;
+ }
// Add the file to the list of sources.
std::string source = (*i)->GetFullPath();
if(cmSystemTools::UpperCase((*i)->GetExtension()) == "DEF")
{
this->ModuleDefinitionFile = (*i)->GetFullPath();
}
- cmSourceGroup& sourceGroup =
+ cmSourceGroup* sourceGroup =
this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
- sourceGroup.AssignSource(*i);
+ sourceGroup->AssignSource(*i);
}
// open the project
this->WriteProjectStart(fout, libName, target, sourceGroups);
// write the configuration information
- this->WriteConfigurations(fout, libName, target);
+ this->WriteConfigurations(fout, configs, libName, target);
fout << "\t<Files>\n";
@@ -1404,14 +1520,13 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
this->WriteGroup(&sg, target, fout, libName, configs);
}
- if(this->GetVersion() >= VS8)
+ if(this->GetVersion() >= cmGlobalVisualStudioGenerator::VS8
+ && !this->FortranProject)
{
// VS >= 8 support per-config source locations so we
// list object library content as external objects.
- cmGeneratorTarget* gt =
- this->GlobalGenerator->GetGeneratorTarget(&target);
std::vector<std::string> objs;
- gt->UseObjectLibraries(objs);
+ target->UseObjectLibraries(objs, "");
if(!objs.empty())
{
// TODO: Separate sub-filter for each object library used?
@@ -1446,29 +1561,27 @@ class cmLocalVisualStudio7GeneratorFCInfo
{
public:
cmLocalVisualStudio7GeneratorFCInfo(cmLocalVisualStudio7Generator* lg,
- cmTarget& target,
+ cmGeneratorTarget* target,
cmSourceFile const& sf,
- std::vector<std::string>* configs);
- std::map<cmStdString, cmLVS7GFileConfig> FileConfigMap;
+ std::vector<std::string> const& configs);
+ std::map<std::string, cmLVS7GFileConfig> FileConfigMap;
};
cmLocalVisualStudio7GeneratorFCInfo
::cmLocalVisualStudio7GeneratorFCInfo(cmLocalVisualStudio7Generator* lg,
- cmTarget& target,
+ cmGeneratorTarget* gt,
cmSourceFile const& sf,
- std::vector<std::string>* configs)
+ std::vector<std::string> const& configs)
{
- cmGeneratorTarget* gt =
- lg->GetGlobalGenerator()->GetGeneratorTarget(&target);
std::string objectName;
- if(gt->ExplicitObjectName.find(&sf) != gt->ExplicitObjectName.end())
+ if(gt->HasExplicitObjectName(&sf))
{
- objectName = gt->Objects[&sf];
+ objectName = gt->GetObjectName(&sf);
}
// Compute per-source, per-config information.
- for(std::vector<std::string>::iterator i = configs->begin();
- i != configs->end(); ++i)
+ for(std::vector<std::string>::const_iterator i = configs.begin();
+ i != configs.end(); ++i)
{
std::string configUpper = cmSystemTools::UpperCase(*i);
cmLVS7GFileConfig fc;
@@ -1527,14 +1640,14 @@ cmLocalVisualStudio7GeneratorFCInfo
}
}
- const char* lang =
+ std::string lang =
lg->GlobalGenerator->GetLanguageFromExtension
(sf.GetExtension().c_str());
- const char* sourceLang = lg->GetSourceFileLanguage(sf);
- const char* linkLanguage = target.GetLinkerLanguage(i->c_str());
+ const std::string& sourceLang = lg->GetSourceFileLanguage(sf);
+ const std::string& linkLanguage = gt->GetLinkerLanguage(i->c_str());
bool needForceLang = false;
// source file does not match its extension language
- if(lang && sourceLang && strcmp(lang, sourceLang) != 0)
+ if(lang != sourceLang)
{
needForceLang = true;
lang = sourceLang;
@@ -1550,16 +1663,15 @@ cmLocalVisualStudio7GeneratorFCInfo
// if the source file does not match the linker language
// then force c or c++
- if(needForceLang || (linkLanguage && lang
- && strcmp(lang, linkLanguage) != 0))
+ if(needForceLang || (linkLanguage != lang))
{
- if(strcmp(lang, "CXX") == 0)
+ if(lang == "CXX")
{
// force a C++ file type
fc.CompileFlags += " /TP ";
needfc = true;
}
- else if(strcmp(lang, "C") == 0)
+ else if(lang == "C")
{
// force to c
fc.CompileFlags += " /TC ";
@@ -1577,15 +1689,15 @@ cmLocalVisualStudio7GeneratorFCInfo
//----------------------------------------------------------------------------
std::string
cmLocalVisualStudio7Generator
-::ComputeLongestObjectDirectory(cmTarget& target) const
+::ComputeLongestObjectDirectory(cmGeneratorTarget const* target) const
{
- std::vector<std::string> *configs =
- static_cast<cmGlobalVisualStudio7Generator *>
- (this->GlobalGenerator)->GetConfigurations();
+ std::vector<std::string> configs;
+ target->Target->GetMakefile()->GetConfigurations(configs);
+
// Compute the maximum length configuration name.
std::string config_max;
- for(std::vector<std::string>::iterator i = configs->begin();
- i != configs->end(); ++i)
+ for(std::vector<std::string>::iterator i = configs.begin();
+ i != configs.end(); ++i)
{
if(i->size() > config_max.size())
{
@@ -1597,7 +1709,7 @@ cmLocalVisualStudio7Generator
// files directory for any configuration. This is used to construct
// object file names that do not produce paths that are too long.
std::string dir_max;
- dir_max += this->Makefile->GetCurrentOutputDirectory();
+ dir_max += this->GetCurrentBinaryDirectory();
dir_max += "/";
dir_max += this->GetTargetDirectory(target);
dir_max += "/";
@@ -1607,17 +1719,19 @@ cmLocalVisualStudio7Generator
}
bool cmLocalVisualStudio7Generator
-::WriteGroup(const cmSourceGroup *sg, cmTarget& target,
- std::ostream &fout, const char *libName,
- std::vector<std::string> *configs)
+::WriteGroup(const cmSourceGroup *sg, cmGeneratorTarget* target,
+ std::ostream &fout, const std::string& libName,
+ std::vector<std::string> const& configs)
{
+ cmGlobalVisualStudio7Generator* gg =
+ static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator);
const std::vector<const cmSourceFile *> &sourceFiles =
sg->GetSourceFiles();
std::vector<cmSourceGroup> const& children = sg->GetGroupChildren();
// Write the children to temporary output.
bool hasChildrenWithSources = false;
- cmOStringStream tmpOut;
+ std::ostringstream tmpOut;
for(unsigned int i=0;i<children.size();++i)
{
if(this->WriteGroup(&children[i], target, tmpOut, libName, configs))
@@ -1640,15 +1754,14 @@ bool cmLocalVisualStudio7Generator
}
// Loop through each source in the source group.
- std::string objectName;
for(std::vector<const cmSourceFile *>::const_iterator sf =
sourceFiles.begin(); sf != sourceFiles.end(); ++sf)
{
std::string source = (*sf)->GetFullPath();
FCInfo fcinfo(this, target, *(*sf), configs);
- if (source != libName || target.GetType() == cmTarget::UTILITY ||
- target.GetType() == cmTarget::GLOBAL_TARGET )
+ if (source != libName || target->GetType() == cmState::UTILITY ||
+ target->GetType() == cmState::GLOBAL_TARGET )
{
fout << "\t\t\t<File\n";
std::string d = this->ConvertToXMLOutputPathSingle(source.c_str());
@@ -1657,16 +1770,18 @@ bool cmLocalVisualStudio7Generator
fout << "\t\t\t\tRelativePath=\"" << d << "\">\n";
if(cmCustomCommand const* command = (*sf)->GetCustomCommand())
{
- this->WriteCustomRule(fout, source.c_str(), *command, fcinfo);
+ this->WriteCustomRule(fout, configs, source.c_str(),
+ *command, fcinfo);
}
else if(!fcinfo.FileConfigMap.empty())
{
const char* aCompilerTool = "VCCLCompilerTool";
- const char* lang = "CXX";
+ const char* ppLang = "CXX";
if(this->FortranProject)
{
aCompilerTool = "VFFortranCompilerTool";
}
+ std::string const& lang = (*sf)->GetLanguage();
std::string ext = (*sf)->GetExtension();
ext = cmSystemTools::LowerCase(ext);
if(ext == "idl")
@@ -1680,7 +1795,7 @@ bool cmLocalVisualStudio7Generator
if(ext == "rc")
{
aCompilerTool = "VCResourceCompilerTool";
- lang = "RC";
+ ppLang = "RC";
if(this->FortranProject)
{
aCompilerTool = "VFResourceCompilerTool";
@@ -1694,14 +1809,19 @@ bool cmLocalVisualStudio7Generator
aCompilerTool = "VFCustomBuildTool";
}
}
- for(std::map<cmStdString, cmLVS7GFileConfig>::const_iterator
+ if (gg->IsMasmEnabled() && !this->FortranProject &&
+ lang == "ASM_MASM")
+ {
+ aCompilerTool = "MASM";
+ }
+ for(std::map<std::string, cmLVS7GFileConfig>::const_iterator
fci = fcinfo.FileConfigMap.begin();
fci != fcinfo.FileConfigMap.end(); ++fci)
{
cmLVS7GFileConfig const& fc = fci->second;
fout << "\t\t\t\t<FileConfiguration\n"
<< "\t\t\t\t\tName=\"" << fci->first
- << "|" << this->PlatformName << "\"";
+ << "|" << gg->GetPlatformName() << "\"";
if(fc.ExcludedFromBuild)
{
fout << " ExcludedFromBuild=\"true\"";
@@ -1722,7 +1842,7 @@ bool cmLocalVisualStudio7Generator
table = cmLocalVisualStudio7GeneratorFortranFlagTable;
}
Options fileOptions(this, tool, table,
- this->ExtraFlagTable);
+ gg->ExtraFlagTable);
fileOptions.Parse(fc.CompileFlags.c_str());
fileOptions.AddDefines(fc.CompileDefs.c_str());
fileOptions.AddDefines(fc.CompileDefsConfig.c_str());
@@ -1730,7 +1850,7 @@ bool cmLocalVisualStudio7Generator
fileOptions.OutputFlagMap(fout, "\t\t\t\t\t");
fileOptions.OutputPreprocessorDefinitions(fout,
"\t\t\t\t\t", "\n",
- lang);
+ ppLang);
}
if(!fc.AdditionalDeps.empty())
{
@@ -1767,17 +1887,15 @@ bool cmLocalVisualStudio7Generator
void cmLocalVisualStudio7Generator::
WriteCustomRule(std::ostream& fout,
+ std::vector<std::string> const& configs,
const char* source,
const cmCustomCommand& command,
FCInfo& fcinfo)
{
- std::string comment = this->ConstructComment(command);
+ cmGlobalVisualStudio7Generator* gg =
+ static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator);
// Write the rule for each configuration.
- std::vector<std::string>::iterator i;
- std::vector<std::string> *configs =
- static_cast<cmGlobalVisualStudio7Generator *>
- (this->GlobalGenerator)->GetConfigurations();
const char* compileTool = "VCCLCompilerTool";
if(this->FortranProject)
{
@@ -1788,11 +1906,14 @@ WriteCustomRule(std::ostream& fout,
{
customTool = "VFCustomBuildTool";
}
- for(i = configs->begin(); i != configs->end(); ++i)
+ for (std::vector<std::string>::const_iterator i = configs.begin();
+ i != configs.end(); ++i)
{
+ cmCustomCommandGenerator ccg(command, *i, this);
cmLVS7GFileConfig const& fc = fcinfo.FileConfigMap[*i];
fout << "\t\t\t\t<FileConfiguration\n";
- fout << "\t\t\t\t\tName=\"" << *i << "|" << this->PlatformName << "\">\n";
+ fout << "\t\t\t\t\tName=\"" << *i << "|"
+ << gg->GetPlatformName() << "\">\n";
if(!fc.CompileFlags.empty())
{
fout << "\t\t\t\t\t<Tool\n"
@@ -1801,7 +1922,8 @@ WriteCustomRule(std::ostream& fout,
<< this->EscapeForXML(fc.CompileFlags.c_str()) << "\"/>\n";
}
- std::string script = this->ConstructScript(command, i->c_str());
+ std::string comment = this->ConstructComment(ccg);
+ std::string script = this->ConstructScript(ccg);
if(this->FortranProject)
{
cmSystemTools::ReplaceString(script, "$(Configuration)", i->c_str());
@@ -1813,13 +1935,13 @@ WriteCustomRule(std::ostream& fout,
<< "\t\t\t\t\tCommandLine=\""
<< this->EscapeForXML(script.c_str()) << "\"\n"
<< "\t\t\t\t\tAdditionalDependencies=\"";
- if(command.GetDepends().empty())
+ if(ccg.GetDepends().empty())
{
// There are no real dependencies. Produce an artificial one to
// make sure the rule runs reliably.
if(!cmSystemTools::FileExists(source))
{
- std::ofstream depout(source);
+ cmsys::ofstream depout(source);
depout << "Artificial dependency for a custom command.\n";
}
fout << this->ConvertToXMLOutputPath(source);
@@ -1828,8 +1950,8 @@ WriteCustomRule(std::ostream& fout,
{
// Write out the dependencies for the rule.
for(std::vector<std::string>::const_iterator d =
- command.GetDepends().begin();
- d != command.GetDepends().end();
+ ccg.GetDepends().begin();
+ d != ccg.GetDepends().end();
++d)
{
// Get the real name of the dependency in case it is a CMake target.
@@ -1843,7 +1965,7 @@ WriteCustomRule(std::ostream& fout,
}
fout << "\"\n";
fout << "\t\t\t\t\tOutputs=\"";
- if(command.GetOutputs().empty())
+ if(ccg.GetOutputs().empty())
{
fout << source << "_force";
}
@@ -1852,8 +1974,8 @@ WriteCustomRule(std::ostream& fout,
// Write a rule for the output generated by this command.
const char* sep = "";
for(std::vector<std::string>::const_iterator o =
- command.GetOutputs().begin();
- o != command.GetOutputs().end();
+ ccg.GetOutputs().begin();
+ o != ccg.GetOutputs().end();
++o)
{
fout << sep << this->ConvertToXMLOutputPathSingle(o->c_str());
@@ -1885,11 +2007,11 @@ void cmLocalVisualStudio7Generator::WriteVCProjEndGroup(std::ostream& fout)
// look for custom rules on a target and collect them together
void cmLocalVisualStudio7Generator
::OutputTargetRules(std::ostream& fout,
- const char* configName,
- cmTarget &target,
- const char * /*libName*/)
+ const std::string& configName,
+ cmGeneratorTarget *target,
+ const std::string& /*libName*/)
{
- if (target.GetType() > cmTarget::GLOBAL_TARGET)
+ if (target->GetType() > cmState::GLOBAL_TARGET)
{
return;
}
@@ -1899,15 +2021,35 @@ void cmLocalVisualStudio7Generator
const char* tool =
this->FortranProject? "VFPreBuildEventTool":"VCPreBuildEventTool";
event.Start(tool);
- event.Write(target.GetPreBuildCommands());
+ event.Write(target->GetPreBuildCommands());
event.Finish();
// Add pre-link event.
tool = this->FortranProject? "VFPreLinkEventTool":"VCPreLinkEventTool";
event.Start(tool);
- event.Write(target.GetPreLinkCommands());
+ bool addedPrelink = false;
+ if (target->GetType() == cmState::SHARED_LIBRARY &&
+ this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+ {
+ if (target->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+ {
+ addedPrelink = true;
+ std::vector<cmCustomCommand> commands =
+ target->GetPreLinkCommands();
+ cmGlobalVisualStudioGenerator* gg
+ = static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator);
+ gg->AddSymbolExportCommand(
+ target, commands, configName);
+ event.Write(commands);
+ }
+ }
+ if (!addedPrelink)
+ {
+ event.Write(target->GetPreLinkCommands());
+ }
cmsys::auto_ptr<cmCustomCommand> pcc(
- this->MaybeCreateImplibDir(target, configName, this->FortranProject));
+ this->MaybeCreateImplibDir(target,
+ configName, this->FortranProject));
if(pcc.get())
{
event.Write(*pcc);
@@ -1917,18 +2059,18 @@ void cmLocalVisualStudio7Generator
// Add post-build event.
tool = this->FortranProject? "VFPostBuildEventTool":"VCPostBuildEventTool";
event.Start(tool);
- event.Write(target.GetPostBuildCommands());
+ event.Write(target->GetPostBuildCommands());
event.Finish();
}
void cmLocalVisualStudio7Generator::WriteProjectSCC(std::ostream& fout,
- cmTarget& target)
+ cmGeneratorTarget* target)
{
// if we have all the required Source code control tags
// then add that to the project
- const char* vsProjectname = target.GetProperty("VS_SCC_PROJECTNAME");
- const char* vsLocalpath = target.GetProperty("VS_SCC_LOCALPATH");
- const char* vsProvider = target.GetProperty("VS_SCC_PROVIDER");
+ const char* vsProjectname = target->GetProperty("VS_SCC_PROJECTNAME");
+ const char* vsLocalpath = target->GetProperty("VS_SCC_LOCALPATH");
+ const char* vsProvider = target->GetProperty("VS_SCC_PROVIDER");
if(vsProvider && vsLocalpath && vsProjectname)
{
@@ -1936,7 +2078,7 @@ void cmLocalVisualStudio7Generator::WriteProjectSCC(std::ostream& fout,
<< "\tSccLocalPath=\"" << vsLocalpath << "\"\n"
<< "\tSccProvider=\"" << vsProvider << "\"\n";
- const char* vsAuxPath = target.GetProperty("VS_SCC_AUXPATH");
+ const char* vsAuxPath = target->GetProperty("VS_SCC_AUXPATH");
if(vsAuxPath)
{
fout << "\tSccAuxPath=\"" << vsAuxPath << "\"\n";
@@ -1947,73 +2089,49 @@ void cmLocalVisualStudio7Generator::WriteProjectSCC(std::ostream& fout,
void
cmLocalVisualStudio7Generator
::WriteProjectStartFortran(std::ostream& fout,
- const char *libName,
- cmTarget & target)
+ const std::string& libName,
+ cmGeneratorTarget *target)
{
cmGlobalVisualStudio7Generator* gg =
static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator);
-
- // Compute the version of the Intel plugin to the VS IDE.
- // If the key does not exist then use a default guess.
- std::string intelVersion;
- std::string vskey = gg->GetRegistryBase();
- vskey += "\\Packages\\" CM_INTEL_PLUGIN_GUID ";ProductVersion";
- cmSystemTools::ReadRegistryValue(vskey.c_str(), intelVersion,
- cmSystemTools::KeyWOW64_32);
- unsigned int intelVersionNumber = ~0u;
- sscanf(intelVersion.c_str(), "%u", &intelVersionNumber);
- if(intelVersionNumber >= 11)
- {
- // Default to latest known project file version.
- intelVersion = "11.0";
- }
- else if(intelVersionNumber == 10)
- {
- // Version 10.x actually uses 9.10 in project files!
- intelVersion = "9.10";
- }
- else
- {
- // Version <= 9: use ProductVersion from registry.
- }
-
- fout << "<?xml version=\"1.0\" encoding = \"Windows-1252\"?>\n"
+ fout << "<?xml version=\"1.0\" encoding = \""
+ << gg->Encoding() << "\"?>\n"
<< "<VisualStudioProject\n"
<< "\tProjectCreator=\"Intel Fortran\"\n"
- << "\tVersion=\"" << intelVersion << "\"\n";
- const char* keyword = target.GetProperty("VS_KEYWORD");
+ << "\tVersion=\"" << gg->GetIntelProjectVersion() << "\"\n";
+ const char* keyword = target->GetProperty("VS_KEYWORD");
if(!keyword)
{
keyword = "Console Application";
}
const char* projectType = 0;
- switch(target.GetType())
+ switch(target->GetType())
{
- case cmTarget::STATIC_LIBRARY:
+ case cmState::STATIC_LIBRARY:
projectType = "typeStaticLibrary";
if(keyword)
{
keyword = "Static Library";
}
break;
- case cmTarget::SHARED_LIBRARY:
- case cmTarget::MODULE_LIBRARY:
+ case cmState::SHARED_LIBRARY:
+ case cmState::MODULE_LIBRARY:
projectType = "typeDynamicLibrary";
if(!keyword)
{
keyword = "Dll";
}
break;
- case cmTarget::EXECUTABLE:
+ case cmState::EXECUTABLE:
if(!keyword)
{
keyword = "Console Application";
}
projectType = 0;
break;
- case cmTarget::UTILITY:
- case cmTarget::GLOBAL_TARGET:
+ case cmState::UTILITY:
+ case cmState::GLOBAL_TARGET:
default:
break;
}
@@ -2023,17 +2141,17 @@ cmLocalVisualStudio7Generator
}
this->WriteProjectSCC(fout, target);
fout<< "\tKeyword=\"" << keyword << "\">\n"
- << "\tProjectGUID=\"{" << gg->GetGUID(libName) << "}\">\n"
+ << "\tProjectGUID=\"{" << gg->GetGUID(libName.c_str()) << "}\">\n"
<< "\t<Platforms>\n"
- << "\t\t<Platform\n\t\t\tName=\"" << this->PlatformName << "\"/>\n"
+ << "\t\t<Platform\n\t\t\tName=\"" << gg->GetPlatformName() << "\"/>\n"
<< "\t</Platforms>\n";
}
void
cmLocalVisualStudio7Generator::WriteProjectStart(std::ostream& fout,
- const char *libName,
- cmTarget & target,
+ const std::string& libName,
+ cmGeneratorTarget *target,
std::vector<cmSourceGroup> &)
{
if(this->FortranProject)
@@ -2041,58 +2159,78 @@ cmLocalVisualStudio7Generator::WriteProjectStart(std::ostream& fout,
this->WriteProjectStartFortran(fout, libName, target);
return;
}
- fout << "<?xml version=\"1.0\" encoding = \"Windows-1252\"?>\n"
+
+ cmGlobalVisualStudio7Generator* gg =
+ static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator);
+
+ fout << "<?xml version=\"1.0\" encoding = \""
+ << gg->Encoding() << "\"?>\n"
<< "<VisualStudioProject\n"
<< "\tProjectType=\"Visual C++\"\n";
- if(this->Version == VS71)
+ if(gg->GetVersion() == cmGlobalVisualStudioGenerator::VS71)
{
fout << "\tVersion=\"7.10\"\n";
}
else
{
- fout << "\tVersion=\"" << (this->Version/10) << ".00\"\n";
+ fout << "\tVersion=\"" << (gg->GetVersion()/10) << ".00\"\n";
}
- const char* projLabel = target.GetProperty("PROJECT_LABEL");
+ const char* projLabel = target->GetProperty("PROJECT_LABEL");
if(!projLabel)
{
- projLabel = libName;
+ projLabel = libName.c_str();
}
- const char* keyword = target.GetProperty("VS_KEYWORD");
+ const char* keyword = target->GetProperty("VS_KEYWORD");
if(!keyword)
{
keyword = "Win32Proj";
}
- cmGlobalVisualStudio7Generator* gg =
- static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator);
fout << "\tName=\"" << projLabel << "\"\n";
- if(this->Version >= VS8)
+ if(gg->GetVersion() >= cmGlobalVisualStudioGenerator::VS8)
{
- fout << "\tProjectGUID=\"{" << gg->GetGUID(libName) << "}\"\n";
+ fout << "\tProjectGUID=\"{" << gg->GetGUID(libName.c_str()) << "}\"\n";
}
this->WriteProjectSCC(fout, target);
+ if(const char* targetFrameworkVersion =
+ target->GetProperty("VS_DOTNET_TARGET_FRAMEWORK_VERSION"))
+ {
+ fout << "\tTargetFrameworkVersion=\"" << targetFrameworkVersion << "\"\n";
+ }
fout << "\tKeyword=\"" << keyword << "\">\n"
<< "\t<Platforms>\n"
- << "\t\t<Platform\n\t\t\tName=\"" << this->PlatformName << "\"/>\n"
+ << "\t\t<Platform\n\t\t\tName=\"" << gg->GetPlatformName() << "\"/>\n"
<< "\t</Platforms>\n";
+ if(gg->IsMasmEnabled())
+ {
+ fout <<
+ "\t<ToolFiles>\n"
+ "\t\t<DefaultToolFile\n"
+ "\t\t\tFileName=\"masm.rules\"\n"
+ "\t\t/>\n"
+ "\t</ToolFiles>\n"
+ ;
+ }
}
-void cmLocalVisualStudio7Generator::WriteVCProjFooter(std::ostream& fout,
- cmTarget &target)
+void cmLocalVisualStudio7Generator::WriteVCProjFooter(
+ std::ostream& fout,
+ cmGeneratorTarget *target)
{
fout << "\t<Globals>\n";
- cmPropertyMap const& props = target.GetProperties();
- for(cmPropertyMap::const_iterator i = props.begin(); i != props.end(); ++i)
+ std::vector<std::string> const& props = target->GetPropertyKeys();
+ for(std::vector<std::string>::const_iterator i = props.begin();
+ i != props.end(); ++i)
{
- if(i->first.find("VS_GLOBAL_") == 0)
+ if(i->find("VS_GLOBAL_") == 0)
{
- std::string name = i->first.substr(10);
+ std::string name = i->substr(10);
if(name != "")
{
fout << "\t\t<Global\n"
<< "\t\t\tName=\"" << name << "\"\n"
- << "\t\t\tValue=\"" << i->second.GetValue() << "\"\n"
+ << "\t\t\tValue=\"" << target->GetProperty(*i) << "\"\n"
<< "\t\t/>\n";
}
}
@@ -2102,7 +2240,7 @@ void cmLocalVisualStudio7Generator::WriteVCProjFooter(std::ostream& fout,
<< "</VisualStudioProject>\n";
}
-std::string cmLocalVisualStudio7GeneratorEscapeForXML(const char* s)
+std::string cmLocalVisualStudio7GeneratorEscapeForXML(const std::string& s)
{
std::string ret = s;
cmSystemTools::ReplaceString(ret, "&", "&amp;");
@@ -2113,7 +2251,7 @@ std::string cmLocalVisualStudio7GeneratorEscapeForXML(const char* s)
return ret;
}
-std::string cmLocalVisualStudio7Generator::EscapeForXML(const char* s)
+std::string cmLocalVisualStudio7Generator::EscapeForXML(const std::string& s)
{
return cmLocalVisualStudio7GeneratorEscapeForXML(s);
}
@@ -2121,7 +2259,7 @@ std::string cmLocalVisualStudio7Generator::EscapeForXML(const char* s)
std::string cmLocalVisualStudio7Generator
::ConvertToXMLOutputPath(const char* path)
{
- std::string ret = this->ConvertToOptionallyRelativeOutputPath(path);
+ std::string ret = this->ConvertToOutputFormat(path, SHELL);
cmSystemTools::ReplaceString(ret, "&", "&amp;");
cmSystemTools::ReplaceString(ret, "\"", "&quot;");
cmSystemTools::ReplaceString(ret, "<", "&lt;");
@@ -2132,7 +2270,7 @@ std::string cmLocalVisualStudio7Generator
std::string cmLocalVisualStudio7Generator
::ConvertToXMLOutputPathSingle(const char* path)
{
- std::string ret = this->ConvertToOptionallyRelativeOutputPath(path);
+ std::string ret = this->ConvertToOutputFormat(path, SHELL);
cmSystemTools::ReplaceString(ret, "\"", "");
cmSystemTools::ReplaceString(ret, "&", "&amp;");
cmSystemTools::ReplaceString(ret, "<", "&lt;");
@@ -2146,18 +2284,18 @@ std::string cmLocalVisualStudio7Generator
class cmVS7XMLParser : public cmXMLParser
{
public:
- virtual void EndElement(const char* /* name */)
+ virtual void EndElement(const std::string& /* name */)
{
}
- virtual void StartElement(const char* name, const char** atts)
+ virtual void StartElement(const std::string& name, const char** atts)
{
// once the GUID is found do nothing
- if(this->GUID.size())
+ if(!this->GUID.empty())
{
return;
}
int i =0;
- if(strcmp("VisualStudioProject", name) == 0)
+ if("VisualStudioProject" == name)
{
while(atts[i])
{
@@ -2194,17 +2332,14 @@ public:
};
void cmLocalVisualStudio7Generator::ReadAndStoreExternalGUID(
- const char* name,
+ const std::string& name,
const char* path)
{
cmVS7XMLParser parser;
parser.ParseFile(path);
- // if we can not find a GUID then create one
- if(parser.GUID.size() == 0)
+ // if we can not find a GUID then we will generate one later
+ if(parser.GUID.empty())
{
- cmGlobalVisualStudio7Generator* gg =
- static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator);
- gg->CreateGUID(name);
return;
}
std::string guidStoreName = name;
@@ -2214,16 +2349,16 @@ void cmLocalVisualStudio7Generator::ReadAndStoreExternalGUID(
AddCacheEntry(guidStoreName.c_str(),
parser.GUID.c_str(),
"Stored GUID",
- cmCacheManager::INTERNAL);
+ cmState::INTERNAL);
}
//----------------------------------------------------------------------------
std::string cmLocalVisualStudio7Generator
-::GetTargetDirectory(cmTarget const& target) const
+::GetTargetDirectory(cmGeneratorTarget const* target) const
{
std::string dir;
- dir += target.GetName();
+ dir += target->GetName();
dir += ".dir";
return dir;
}
@@ -2237,7 +2372,7 @@ static bool cmLVS6G_IsFAT(const char* dir)
char volRoot[4] = "_:/";
volRoot[0] = dir[0];
char fsName[16];
- if(GetVolumeInformation(volRoot, 0, 0, 0, 0, 0, fsName, 16) &&
+ if(GetVolumeInformationA(volRoot, 0, 0, 0, 0, 0, fsName, 16) &&
strstr(fsName, "FAT") != 0)
{
return true;
diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h
index 92e4d3c12..7bb9cc6a0 100644
--- a/Source/cmLocalVisualStudio7Generator.h
+++ b/Source/cmLocalVisualStudio7Generator.h
@@ -15,7 +15,6 @@
#include "cmLocalVisualStudioGenerator.h"
#include "cmVisualStudioGeneratorOptions.h"
-class cmTarget;
class cmSourceFile;
class cmCustomCommand;
class cmSourceGroup;
@@ -35,7 +34,7 @@ class cmLocalVisualStudio7Generator : public cmLocalVisualStudioGenerator
{
public:
///! Set cache only and recurse to false by default.
- cmLocalVisualStudio7Generator(VSVersion v);
+ cmLocalVisualStudio7Generator(cmGlobalGenerator* gg, cmMakefile* mf);
virtual ~cmLocalVisualStudio7Generator();
@@ -51,67 +50,73 @@ public:
/**
* Specify the type of the build: static, dll, or executable.
*/
- void SetBuildType(BuildType,const char *name);
+ void SetBuildType(BuildType,const std::string& name);
- void SetPlatformName(const char* n) { this->PlatformName = n;}
-
- void SetExtraFlagTable(cmVS7FlagTable const* table)
- { this->ExtraFlagTable = table; }
- virtual std::string GetTargetDirectory(cmTarget const&) const;
+ virtual
+ std::string GetTargetDirectory(cmGeneratorTarget const* target) const;
cmSourceFile* CreateVCProjBuildRule();
void WriteStampFiles();
- virtual std::string ComputeLongestObjectDirectory(cmTarget&) const;
+ virtual std::string
+ ComputeLongestObjectDirectory(cmGeneratorTarget const*) const;
- virtual void ReadAndStoreExternalGUID(const char* name,
+ virtual void ReadAndStoreExternalGUID(const std::string& name,
const char* path);
virtual void AddCMakeListsRules();
protected:
- void CreateSingleVCProj(const char *lname, cmTarget &tgt);
+ void CreateSingleVCProj(const std::string& lname,
+ cmGeneratorTarget *tgt);
private:
typedef cmVisualStudioGeneratorOptions Options;
typedef cmLocalVisualStudio7GeneratorFCInfo FCInfo;
std::string GetBuildTypeLinkerFlags(std::string rootLinkerFlags,
- const char* configName);
+ const std::string& configName);
void FixGlobalTargets();
void WriteProjectFiles();
- void WriteVCProjHeader(std::ostream& fout, const char *libName,
- cmTarget &tgt, std::vector<cmSourceGroup> &sgs);
- void WriteVCProjFooter(std::ostream& fout, cmTarget &target);
- void WriteVCProjFile(std::ostream& fout, const char *libName,
- cmTarget &tgt);
+ void WriteVCProjHeader(std::ostream& fout, const std::string& libName,
+ cmGeneratorTarget* tgt,
+ std::vector<cmSourceGroup> &sgs);
+ void WriteVCProjFooter(std::ostream& fout, cmGeneratorTarget* target);
+ void WriteVCProjFile(std::ostream& fout, const std::string& libName,
+ cmGeneratorTarget* tgt);
void WriteConfigurations(std::ostream& fout,
- const char *libName, cmTarget &tgt);
+ std::vector<std::string> const& configs,
+ const std::string& libName, cmGeneratorTarget* tgt);
void WriteConfiguration(std::ostream& fout,
- const char* configName,
- const char* libName, cmTarget &tgt);
- std::string EscapeForXML(const char* s);
+ const std::string& configName,
+ const std::string& libName, cmGeneratorTarget* tgt);
+ std::string EscapeForXML(const std::string& s);
std::string ConvertToXMLOutputPath(const char* path);
std::string ConvertToXMLOutputPathSingle(const char* path);
- void OutputTargetRules(std::ostream& fout, const char* configName,
- cmTarget &target, const char *libName);
- void OutputBuildTool(std::ostream& fout, const char* configName,
- cmTarget& t, const Options& targetOptions);
+ void OutputTargetRules(std::ostream& fout, const std::string& configName,
+ cmGeneratorTarget* target,
+ const std::string& libName);
+ void OutputBuildTool(std::ostream& fout, const std::string& configName,
+ cmGeneratorTarget* t, const Options& targetOptions);
void OutputLibraryDirectories(std::ostream& fout,
std::vector<std::string> const& dirs);
- void WriteProjectSCC(std::ostream& fout, cmTarget& target);
- void WriteProjectStart(std::ostream& fout, const char *libName,
- cmTarget &tgt, std::vector<cmSourceGroup> &sgs);
- void WriteProjectStartFortran(std::ostream& fout, const char *libName,
- cmTarget &tgt);
+ void WriteProjectSCC(std::ostream& fout, cmGeneratorTarget *target);
+ void WriteProjectStart(std::ostream& fout, const std::string& libName,
+ cmGeneratorTarget* tgt,
+ std::vector<cmSourceGroup> &sgs);
+ void WriteProjectStartFortran(std::ostream& fout, const std::string& libName,
+ cmGeneratorTarget* tgt);
void WriteVCProjBeginGroup(std::ostream& fout,
const char* group,
const char* filter);
void WriteVCProjEndGroup(std::ostream& fout);
void WriteCustomRule(std::ostream& fout,
+ std::vector<std::string> const& configs,
const char* source,
const cmCustomCommand& command,
FCInfo& fcinfo);
- void WriteTargetVersionAttribute(std::ostream& fout, cmTarget& target);
+ void WriteTargetVersionAttribute(std::ostream& fout,
+ cmGeneratorTarget* gt);
bool WriteGroup(const cmSourceGroup *sg,
- cmTarget& target, std::ostream &fout,
- const char *libName, std::vector<std::string> *configs);
+ cmGeneratorTarget* target, std::ostream &fout,
+ const std::string& libName,
+ std::vector<std::string> const& configs);
friend class cmLocalVisualStudio7GeneratorFCInfo;
friend class cmLocalVisualStudio7GeneratorInternals;
@@ -119,11 +124,9 @@ private:
class EventWriter;
friend class EventWriter;
- cmVS7FlagTable const* ExtraFlagTable;
std::string ModuleDefinitionFile;
bool FortranProject;
bool WindowsCEProject;
- std::string PlatformName; // Win32 or x64
cmLocalVisualStudio7GeneratorInternals* Internal;
};
diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx
index ef2bb1d99..561f9a136 100644
--- a/Source/cmLocalVisualStudioGenerator.cxx
+++ b/Source/cmLocalVisualStudioGenerator.cxx
@@ -18,11 +18,10 @@
#include "windows.h"
//----------------------------------------------------------------------------
-cmLocalVisualStudioGenerator::cmLocalVisualStudioGenerator(VSVersion v)
+cmLocalVisualStudioGenerator
+::cmLocalVisualStudioGenerator(cmGlobalGenerator* gg, cmMakefile* mf)
+ : cmLocalGenerator(gg, mf)
{
- this->WindowsShell = true;
- this->WindowsVSIDE = true;
- this->Version = v;
}
//----------------------------------------------------------------------------
@@ -31,9 +30,58 @@ cmLocalVisualStudioGenerator::~cmLocalVisualStudioGenerator()
}
//----------------------------------------------------------------------------
+cmGlobalVisualStudioGenerator::VSVersion
+cmLocalVisualStudioGenerator::GetVersion() const
+{
+ cmGlobalVisualStudioGenerator* gg =
+ static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator);
+ return gg->GetVersion();
+}
+
+//----------------------------------------------------------------------------
+void cmLocalVisualStudioGenerator::ComputeObjectFilenames(
+ std::map<cmSourceFile const*, std::string>& mapping,
+ cmGeneratorTarget const* gt)
+{
+ std::string dir_max = this->ComputeLongestObjectDirectory(gt);
+
+ // Count the number of object files with each name. Note that
+ // windows file names are not case sensitive.
+ std::map<std::string, int> counts;
+
+ for(std::map<cmSourceFile const*, std::string>::iterator
+ si = mapping.begin(); si != mapping.end(); ++si)
+ {
+ cmSourceFile const* sf = si->first;
+ std::string objectNameLower = cmSystemTools::LowerCase(
+ cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()));
+ objectNameLower += this->GlobalGenerator->GetLanguageOutputExtension(*sf);
+ counts[objectNameLower] += 1;
+ }
+
+ // For all source files producing duplicate names we need unique
+ // object name computation.
+
+ for(std::map<cmSourceFile const*, std::string>::iterator
+ si = mapping.begin(); si != mapping.end(); ++si)
+ {
+ cmSourceFile const* sf = si->first;
+ std::string objectName =
+ cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath());
+ objectName += this->GlobalGenerator->GetLanguageOutputExtension(*sf);
+ if(counts[cmSystemTools::LowerCase(objectName)] > 1)
+ {
+ const_cast<cmGeneratorTarget*>(gt)->AddExplicitObjectName(sf);
+ objectName = this->GetObjectFileNameWithoutTarget(*sf, dir_max);
+ }
+ si->second = objectName;
+ }
+}
+
+//----------------------------------------------------------------------------
cmsys::auto_ptr<cmCustomCommand>
-cmLocalVisualStudioGenerator::MaybeCreateImplibDir(cmTarget& target,
- const char* config,
+cmLocalVisualStudioGenerator::MaybeCreateImplibDir(cmGeneratorTarget* target,
+ const std::string& config,
bool isFortran)
{
cmsys::auto_ptr<cmCustomCommand> pcc;
@@ -41,24 +89,26 @@ cmLocalVisualStudioGenerator::MaybeCreateImplibDir(cmTarget& target,
// If an executable exports symbols then VS wants to create an
// import library but forgets to create the output directory.
// The Intel Fortran plugin always forgets to the directory.
- if(target.GetType() != cmTarget::EXECUTABLE &&
- !(isFortran && target.GetType() == cmTarget::SHARED_LIBRARY))
+ if(target->GetType() != cmState::EXECUTABLE &&
+ !(isFortran && target->GetType() == cmState::SHARED_LIBRARY))
{ return pcc; }
- std::string outDir = target.GetDirectory(config, false);
- std::string impDir = target.GetDirectory(config, true);
+ std::string outDir = target->GetDirectory(config, false);
+ std::string impDir = target->GetDirectory(config, true);
if(impDir == outDir) { return pcc; }
// Add a pre-build event to create the directory.
cmCustomCommandLine command;
- command.push_back(this->Makefile->GetRequiredDefinition("CMAKE_COMMAND"));
+ command.push_back(cmSystemTools::GetCMakeCommand());
command.push_back("-E");
command.push_back("make_directory");
command.push_back(impDir);
std::vector<std::string> no_output;
+ std::vector<std::string> no_byproducts;
std::vector<std::string> no_depends;
cmCustomCommandLines commands;
commands.push_back(command);
- pcc.reset(new cmCustomCommand(0, no_output, no_depends, commands, 0, 0));
+ pcc.reset(new cmCustomCommand(0, no_output, no_byproducts,
+ no_depends, commands, 0, 0));
pcc->SetEscapeOldStyle(false);
pcc->SetEscapeAllowMakeVars(true);
return pcc;
@@ -79,17 +129,15 @@ const char* cmLocalVisualStudioGenerator::GetReportErrorLabel() const
//----------------------------------------------------------------------------
std::string
cmLocalVisualStudioGenerator
-::ConstructScript(cmCustomCommand const& cc,
- const char* configName,
- const char* newline_text)
+::ConstructScript(cmCustomCommandGenerator const& ccg,
+ const std::string& newline_text)
{
bool useLocal = this->CustomCommandUseLocal();
- const char* workingDirectory = cc.GetWorkingDirectory();
- cmCustomCommandGenerator ccg(cc, configName, this->Makefile);
- RelativeRoot relativeRoot = workingDirectory? NONE : START_OUTPUT;
+ std::string workingDirectory = ccg.GetWorkingDirectory();
+ RelativeRoot relativeRoot = workingDirectory.empty()? START_OUTPUT : NONE;
// Avoid leading or trailing newlines.
- const char* newline = "";
+ std::string newline = "";
// Line to check for error between commands.
std::string check_error = newline_text;
@@ -114,7 +162,7 @@ cmLocalVisualStudioGenerator
script += "setlocal";
}
- if(workingDirectory)
+ if(!workingDirectory.empty())
{
// Change the working directory.
script += newline;
@@ -124,7 +172,7 @@ cmLocalVisualStudioGenerator
script += check_error;
// Change the working drive.
- if(workingDirectory[0] && workingDirectory[1] == ':')
+ if(workingDirectory.size() > 1 && workingDirectory[1] == ':')
{
script += newline;
newline = newline_text;
diff --git a/Source/cmLocalVisualStudioGenerator.h b/Source/cmLocalVisualStudioGenerator.h
index 1a3499a96..f95eefaed 100644
--- a/Source/cmLocalVisualStudioGenerator.h
+++ b/Source/cmLocalVisualStudioGenerator.h
@@ -13,12 +13,14 @@
#define cmLocalVisualStudioGenerator_h
#include "cmLocalGenerator.h"
+#include "cmGlobalVisualStudioGenerator.h"
#include <cmsys/auto_ptr.hxx>
class cmSourceFile;
class cmSourceGroup;
class cmCustomCommand;
+class cmCustomCommandGenerator;
/** \class cmLocalVisualStudioGenerator
* \brief Base class for Visual Studio generators.
@@ -29,47 +31,37 @@ class cmCustomCommand;
class cmLocalVisualStudioGenerator : public cmLocalGenerator
{
public:
- /** Known versions of Visual Studio. */
- enum VSVersion
- {
- VS6 = 60,
- VS7 = 70,
- VS71 = 71,
- VS8 = 80,
- VS9 = 90,
- VS10 = 100,
- VS11 = 110,
- VS12 = 120
- };
-
- cmLocalVisualStudioGenerator(VSVersion v);
+ cmLocalVisualStudioGenerator(cmGlobalGenerator* gg, cmMakefile* mf);
virtual ~cmLocalVisualStudioGenerator();
/** Construct a script from the given list of command lines. */
- std::string ConstructScript(cmCustomCommand const& cc,
- const char* configName,
- const char* newline = "\n");
+ std::string ConstructScript(cmCustomCommandGenerator const& ccg,
+ const std::string& newline = "\n");
/** Label to which to jump in a batch file after a failed step in a
sequence of custom commands. */
const char* GetReportErrorLabel() const;
- /** Version of Visual Studio. */
- VSVersion GetVersion() const { return this->Version; }
+ cmGlobalVisualStudioGenerator::VSVersion GetVersion() const;
- virtual std::string ComputeLongestObjectDirectory(cmTarget&) const = 0;
+ virtual std::string
+ ComputeLongestObjectDirectory(cmGeneratorTarget const*) const = 0;
virtual void AddCMakeListsRules() = 0;
+ virtual void ComputeObjectFilenames(
+ std::map<cmSourceFile const*, std::string>& mapping,
+ cmGeneratorTarget const* = 0);
+
protected:
virtual const char* ReportErrorLabel() const;
virtual bool CustomCommandUseLocal() const { return false; }
/** Construct a custom command to make exe import lib dir. */
cmsys::auto_ptr<cmCustomCommand>
- MaybeCreateImplibDir(cmTarget& target, const char* config, bool isFortran);
-
- VSVersion Version;
+ MaybeCreateImplibDir(cmGeneratorTarget *target,
+ const std::string& config,
+ bool isFortran);
};
#endif
diff --git a/Source/cmLocalXCodeGenerator.cxx b/Source/cmLocalXCodeGenerator.cxx
index 7c5f69df5..aec260366 100644
--- a/Source/cmLocalXCodeGenerator.cxx
+++ b/Source/cmLocalXCodeGenerator.cxx
@@ -12,9 +12,12 @@
#include "cmLocalXCodeGenerator.h"
#include "cmGlobalXCodeGenerator.h"
#include "cmSourceFile.h"
+#include "cmMakefile.h"
//----------------------------------------------------------------------------
-cmLocalXCodeGenerator::cmLocalXCodeGenerator()
+cmLocalXCodeGenerator::cmLocalXCodeGenerator(cmGlobalGenerator* gg,
+ cmMakefile* mf)
+ : cmLocalGenerator(gg, mf)
{
// the global generator does this, so do not
// put these flags into the language flags
@@ -28,7 +31,7 @@ cmLocalXCodeGenerator::~cmLocalXCodeGenerator()
//----------------------------------------------------------------------------
std::string
-cmLocalXCodeGenerator::GetTargetDirectory(cmTarget const&) const
+cmLocalXCodeGenerator::GetTargetDirectory(cmGeneratorTarget const*) const
{
// No per-target directory for this generator (yet).
return "";
@@ -36,9 +39,63 @@ cmLocalXCodeGenerator::GetTargetDirectory(cmTarget const&) const
//----------------------------------------------------------------------------
void cmLocalXCodeGenerator::AppendFlagEscape(std::string& flags,
- const char* rawFlag)
+ const std::string& rawFlag)
{
cmGlobalXCodeGenerator* gg =
static_cast<cmGlobalXCodeGenerator*>(this->GlobalGenerator);
gg->AppendFlag(flags, rawFlag);
}
+
+//----------------------------------------------------------------------------
+void cmLocalXCodeGenerator::Generate()
+{
+ cmLocalGenerator::Generate();
+
+ std::vector<cmGeneratorTarget*> targets = this->GetGeneratorTargets();
+ for(std::vector<cmGeneratorTarget*>::iterator iter = targets.begin();
+ iter != targets.end(); ++iter)
+ {
+ (*iter)->HasMacOSXRpathInstallNameDir("");
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmLocalXCodeGenerator::GenerateInstallRules()
+{
+ cmLocalGenerator::GenerateInstallRules();
+
+ std::vector<cmGeneratorTarget*> targets = this->GetGeneratorTargets();
+ for(std::vector<cmGeneratorTarget*>::iterator iter = targets.begin();
+ iter != targets.end(); ++iter)
+ {
+ (*iter)->HasMacOSXRpathInstallNameDir("");
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmLocalXCodeGenerator::ComputeObjectFilenames(
+ std::map<cmSourceFile const*, std::string>& mapping,
+ cmGeneratorTarget const*)
+{
+ // Count the number of object files with each name. Warn about duplicate
+ // names since Xcode names them uniquely automatically with a numeric suffix
+ // to avoid exact duplicate file names. Note that Mac file names are not
+ // typically case sensitive, hence the LowerCase.
+ std::map<std::string, int> counts;
+ for(std::map<cmSourceFile const*, std::string>::iterator
+ si = mapping.begin(); si != mapping.end(); ++si)
+ {
+ cmSourceFile const* sf = si->first;
+ std::string objectName =
+ cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath());
+ objectName += ".o";
+
+ std::string objectNameLower = cmSystemTools::LowerCase(objectName);
+ counts[objectNameLower] += 1;
+ if (2 == counts[objectNameLower])
+ {
+ // TODO: emit warning about duplicate name?
+ }
+ si->second = objectName;
+ }
+}
diff --git a/Source/cmLocalXCodeGenerator.h b/Source/cmLocalXCodeGenerator.h
index d97a41cea..4381a6de8 100644
--- a/Source/cmLocalXCodeGenerator.h
+++ b/Source/cmLocalXCodeGenerator.h
@@ -24,11 +24,19 @@ class cmLocalXCodeGenerator : public cmLocalGenerator
{
public:
///! Set cache only and recurse to false by default.
- cmLocalXCodeGenerator();
+ cmLocalXCodeGenerator(cmGlobalGenerator* gg,
+ cmMakefile* mf);
virtual ~cmLocalXCodeGenerator();
- virtual std::string GetTargetDirectory(cmTarget const& target) const;
- virtual void AppendFlagEscape(std::string& flags, const char* rawFlag);
+ virtual
+ std::string GetTargetDirectory(cmGeneratorTarget const* target) const;
+ virtual void AppendFlagEscape(std::string& flags,
+ const std::string& rawFlag);
+ virtual void Generate();
+ virtual void GenerateInstallRules();
+ virtual void ComputeObjectFilenames(
+ std::map<cmSourceFile const*, std::string>& mapping,
+ cmGeneratorTarget const* gt = 0);
private:
};
diff --git a/Source/cmLocale.h b/Source/cmLocale.h
new file mode 100644
index 000000000..727f0f5d4
--- /dev/null
+++ b/Source/cmLocale.h
@@ -0,0 +1,31 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmLocale_h
+#define cmLocale_h
+
+#include <locale.h>
+
+class cmLocaleRAII
+{
+ const char* OldLocale;
+public:
+ cmLocaleRAII(): OldLocale(setlocale(LC_CTYPE, 0))
+ {
+ setlocale(LC_CTYPE, "");
+ }
+ ~cmLocaleRAII()
+ {
+ setlocale(LC_CTYPE, this->OldLocale);
+ }
+};
+
+#endif
diff --git a/Source/cmMachO.cxx b/Source/cmMachO.cxx
new file mode 100644
index 000000000..1607845d7
--- /dev/null
+++ b/Source/cmMachO.cxx
@@ -0,0 +1,419 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmStandardIncludes.h" // to get CMAKE_USE_MACH_PARSER first
+#include "cmMachO.h"
+
+#include <cmsys/FStream.hxx>
+
+// Include the Mach-O format information system header.
+#include <mach-o/loader.h>
+#include <mach-o/fat.h>
+
+/**
+
+ https://developer.apple.com/library/mac/documentation/
+ DeveloperTools/Conceptual/MachORuntime/index.html
+
+ A Mach-O file has 3 major regions: header, load commands and segments.
+ Data Structures are provided from <mach-o/loader.h> which
+ correspond to the file structure.
+
+ The header can be either a struct mach_header or struct mach_header_64.
+ One can peek at the first 4 bytes to identify the type of header.
+
+ Following is the load command region which starts with
+ struct load_command, and is followed by n number of load commands.
+
+ In the case of a universal binary (an archive of multiple Mach-O files),
+ the file begins with a struct fat_header and is followed by multiple
+ struct fat_arch instances. The struct fat_arch indicates the offset
+ for each Mach-O file.
+
+ */
+
+namespace {
+
+ // peek in the file
+ template <typename T>
+ bool peek(cmsys::ifstream& fin, T &v)
+ {
+ std::streampos p = fin.tellg();
+ if(!fin.read(reinterpret_cast<char*>(&v), sizeof(T)))
+ {
+ return false;
+ }
+ fin.seekg(p);
+ return fin.good();
+ }
+
+ // read from the file and fill a data structure
+ template <typename T>
+ bool read(cmsys::ifstream& fin, T& v)
+ {
+ if(!fin.read(reinterpret_cast<char*>(&v), sizeof(T)))
+ {
+ return false;
+ }
+ return true;
+ }
+
+ // read from the file and fill multiple data structures where
+ // the vector has been resized
+ template <typename T>
+ bool read(cmsys::ifstream& fin, std::vector<T>& v)
+ {
+ // nothing to read
+ if(v.empty())
+ {
+ return true;
+ }
+ if(!fin.read(reinterpret_cast<char*>(&v[0]), sizeof(T) * v.size()))
+ {
+ return false;
+ }
+ return true;
+ }
+}
+
+
+// Contains header and load commands for a single Mach-O file
+class cmMachOHeaderAndLoadCommands
+{
+public:
+ // A load_command and its associated data
+ struct RawLoadCommand
+ {
+ uint32_t type(const cmMachOHeaderAndLoadCommands* m) const
+ {
+ if(this->LoadCommand.size() < sizeof(load_command))
+ {
+ return 0;
+ }
+ const load_command* cmd =
+ reinterpret_cast<const load_command*>(&this->LoadCommand[0]);
+ return m->swap(cmd->cmd);
+ }
+ std::vector<char> LoadCommand;
+ };
+
+ cmMachOHeaderAndLoadCommands(bool _swap)
+ : Swap(_swap)
+ {
+ }
+ virtual ~cmMachOHeaderAndLoadCommands()
+ {
+ }
+
+ virtual bool read_mach_o(cmsys::ifstream& fin) = 0;
+
+ const std::vector<RawLoadCommand>& load_commands() const
+ {
+ return this->LoadCommands;
+ }
+
+ uint32_t swap(uint32_t v) const
+ {
+ if(this->Swap)
+ {
+ char* c = reinterpret_cast<char*>(&v);
+ std::swap(c[0], c[3]);
+ std::swap(c[1], c[2]);
+ }
+ return v;
+ }
+
+protected:
+ bool read_load_commands(uint32_t ncmds, uint32_t sizeofcmds,
+ cmsys::ifstream& fin);
+
+ bool Swap;
+ std::vector<RawLoadCommand> LoadCommands;
+};
+
+// Implementation for reading Mach-O header and load commands.
+// This is 32 or 64 bit arch specific.
+template <class T>
+class cmMachOHeaderAndLoadCommandsImpl : public cmMachOHeaderAndLoadCommands
+{
+public:
+ cmMachOHeaderAndLoadCommandsImpl(bool _swap)
+ : cmMachOHeaderAndLoadCommands(_swap)
+ {
+ }
+ bool read_mach_o(cmsys::ifstream& fin)
+ {
+ if(!read(fin, this->Header))
+ {
+ return false;
+ }
+ this->Header.cputype = swap(this->Header.cputype);
+ this->Header.cpusubtype = swap(this->Header.cpusubtype);
+ this->Header.filetype = swap(this->Header.filetype);
+ this->Header.ncmds = swap(this->Header.ncmds);
+ this->Header.sizeofcmds = swap(this->Header.sizeofcmds);
+ this->Header.flags = swap(this->Header.flags);
+
+ return read_load_commands(this->Header.ncmds,
+ this->Header.sizeofcmds,
+ fin);
+ }
+protected:
+ T Header;
+};
+
+
+bool cmMachOHeaderAndLoadCommands::read_load_commands(uint32_t ncmds,
+ uint32_t sizeofcmds,
+ cmsys::ifstream& fin)
+{
+ uint32_t size_read = 0;
+ this->LoadCommands.resize(ncmds);
+ for(uint32_t i = 0; i<ncmds; i++)
+ {
+ load_command lc;
+ if(!peek(fin, lc))
+ {
+ return false;
+ }
+ lc.cmd = swap(lc.cmd);
+ lc.cmdsize = swap(lc.cmdsize);
+ size_read += lc.cmdsize;
+
+ RawLoadCommand& c = this->LoadCommands[i];
+ c.LoadCommand.resize(lc.cmdsize);
+ if(!read(fin, c.LoadCommand))
+ {
+ return false;
+ }
+ }
+
+ if(size_read != sizeofcmds)
+ {
+ this->LoadCommands.clear();
+ return false;
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+class cmMachOInternal
+{
+public:
+ cmMachOInternal(const char* fname);
+ ~cmMachOInternal();
+
+ // read a Mach-O file
+ bool read_mach_o(uint32_t file_offset);
+
+ // the file we are reading
+ cmsys::ifstream Fin;
+
+ // The archs in the universal binary
+ // If the binary is not a universal binary, this will be empty.
+ std::vector<fat_arch> FatArchs;
+
+ // the error message while parsing
+ std::string ErrorMessage;
+
+ // the list of Mach-O's
+ std::vector<cmMachOHeaderAndLoadCommands*> MachOList;
+};
+
+cmMachOInternal::cmMachOInternal(const char* fname)
+ : Fin(fname)
+{
+ // Quit now if the file could not be opened.
+ if(!this->Fin || !this->Fin.get() )
+ {
+ this->ErrorMessage = "Error opening input file.";
+ return;
+ }
+
+ if(!this->Fin.seekg(0))
+ {
+ this->ErrorMessage = "Error seeking to beginning of file.";
+ return;
+ }
+
+ // Read the binary identification block.
+ uint32_t magic = 0;
+ if(!peek(this->Fin, magic))
+ {
+ this->ErrorMessage = "Error reading Mach-O identification.";
+ return;
+ }
+
+ // Verify the binary identification.
+ if(!(magic == MH_CIGAM ||
+ magic == MH_MAGIC ||
+ magic == MH_CIGAM_64 ||
+ magic == MH_MAGIC_64 ||
+ magic == FAT_CIGAM ||
+ magic == FAT_MAGIC))
+ {
+ this->ErrorMessage = "File does not have a valid Mach-O identification.";
+ return;
+ }
+
+ if(magic == FAT_MAGIC || magic == FAT_CIGAM)
+ {
+ // this is a universal binary
+ fat_header header;
+ if(!read(this->Fin, header))
+ {
+ this->ErrorMessage = "Error reading fat header.";
+ return;
+ }
+
+ // read fat_archs
+ this->FatArchs.resize(OSSwapBigToHostInt32(header.nfat_arch));
+ if(!read(this->Fin, this->FatArchs))
+ {
+ this->ErrorMessage = "Error reading fat header archs.";
+ return;
+ }
+
+ // parse each Mach-O file
+ for(size_t i=0; i<this->FatArchs.size(); i++)
+ {
+ const fat_arch& arch = this->FatArchs[i];
+ if(!this->read_mach_o(OSSwapBigToHostInt32(arch.offset)))
+ {
+ return;
+ }
+ }
+ }
+ else
+ {
+ // parse Mach-O file at the beginning of the file
+ this->read_mach_o(0);
+ }
+}
+
+cmMachOInternal::~cmMachOInternal()
+{
+ for(size_t i=0; i<this->MachOList.size(); i++)
+ {
+ delete this->MachOList[i];
+ }
+}
+
+bool cmMachOInternal::read_mach_o(uint32_t file_offset)
+{
+ if(!this->Fin.seekg(file_offset))
+ {
+ this->ErrorMessage = "Failed to locate Mach-O content.";
+ return false;
+ }
+
+ uint32_t magic;
+ if(!peek(this->Fin, magic))
+ {
+ this->ErrorMessage = "Error reading Mach-O identification.";
+ return false;
+ }
+
+ cmMachOHeaderAndLoadCommands* f = NULL;
+ if(magic == MH_CIGAM || magic == MH_MAGIC)
+ {
+ bool swap = false;
+ if(magic == MH_CIGAM)
+ {
+ swap = true;
+ }
+ f = new cmMachOHeaderAndLoadCommandsImpl<mach_header>(swap);
+ }
+ else if(magic == MH_CIGAM_64 || magic == MH_MAGIC_64)
+ {
+ bool swap = false;
+ if(magic == MH_CIGAM_64)
+ {
+ swap = true;
+ }
+ f = new cmMachOHeaderAndLoadCommandsImpl<mach_header_64>(swap);
+ }
+
+ if(f && f->read_mach_o(this->Fin))
+ {
+ this->MachOList.push_back(f);
+ }
+ else
+ {
+ delete f;
+ this->ErrorMessage = "Failed to read Mach-O header.";
+ return false;
+ }
+
+ return true;
+}
+
+//============================================================================
+// External class implementation.
+
+//----------------------------------------------------------------------------
+cmMachO::cmMachO(const char* fname): Internal(0)
+{
+ this->Internal = new cmMachOInternal(fname);
+
+}
+
+//----------------------------------------------------------------------------
+cmMachO::~cmMachO()
+{
+ delete this->Internal;
+}
+
+std::string const& cmMachO::GetErrorMessage() const
+{
+ return this->Internal->ErrorMessage;
+}
+
+//----------------------------------------------------------------------------
+bool cmMachO::Valid() const
+{
+ return !this->Internal->MachOList.empty();
+}
+
+bool cmMachO::GetInstallName(std::string& install_name)
+{
+ if(this->Internal->MachOList.empty())
+ {
+ return false;
+ }
+
+ // grab the first Mach-O and get the install name from that one
+ cmMachOHeaderAndLoadCommands* macho = this->Internal->MachOList[0];
+ for(size_t i=0; i<macho->load_commands().size(); i++)
+ {
+ const cmMachOHeaderAndLoadCommands::RawLoadCommand &cmd =
+ macho->load_commands()[i];
+ uint32_t lc_cmd = cmd.type(macho);
+ if(lc_cmd == LC_ID_DYLIB ||
+ lc_cmd == LC_LOAD_WEAK_DYLIB ||
+ lc_cmd == LC_LOAD_DYLIB)
+ {
+ if(sizeof(dylib_command) < cmd.LoadCommand.size())
+ {
+ uint32_t namelen = cmd.LoadCommand.size() - sizeof(dylib_command);
+ install_name.assign(&cmd.LoadCommand[sizeof(dylib_command)], namelen);
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+void cmMachO::PrintInfo(std::ostream& /*os*/) const
+{
+}
diff --git a/Source/cmMachO.h b/Source/cmMachO.h
new file mode 100644
index 000000000..f06f8ded0
--- /dev/null
+++ b/Source/cmMachO.h
@@ -0,0 +1,51 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmMachO_h
+#define cmMachO_h
+
+#if !defined(CMAKE_USE_MACH_PARSER)
+# error "This file may be included only if CMAKE_USE_MACH_PARSER is enabled."
+#endif
+
+class cmMachOInternal;
+
+/** \class cmMachO
+ * \brief Executable and Link Format (Mach-O) parser.
+ */
+class cmMachO
+{
+public:
+ /** Construct with the name of the Mach-O input file to parse. */
+ cmMachO(const char* fname);
+
+ /** Destruct. */
+ ~cmMachO();
+
+ /** Get the error message if any. */
+ std::string const& GetErrorMessage() const;
+
+ /** Boolean conversion. True if the Mach-O file is valid. */
+ operator bool() const { return this->Valid(); }
+
+ /** Get Install name from binary **/
+ bool GetInstallName(std::string& install_name);
+
+ /** Print human-readable information about the Mach-O file. */
+ void PrintInfo(std::ostream& os) const;
+
+private:
+ friend class cmMachOInternal;
+ bool Valid() const;
+ cmMachOInternal* Internal;
+};
+
+#endif
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index 8ba612cc9..71de7a723 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -12,6 +12,7 @@
#include "cmMacroCommand.h"
#include "cmake.h"
+#include "cmAlgorithms.h"
// define the class for macro commands
class cmMacroHelperCommand : public cmCommand
@@ -20,7 +21,7 @@ public:
cmMacroHelperCommand() {}
///! clean up any memory allocated by the macro
- ~cmMacroHelperCommand() {};
+ ~cmMacroHelperCommand() {}
/**
* This is used to avoid including this command
@@ -60,30 +61,12 @@ public:
cmExecutionStatus &);
virtual bool InitialPass(std::vector<std::string> const&,
- cmExecutionStatus &) { return false; };
+ cmExecutionStatus &) { return false; }
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return this->Args[0].c_str(); }
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- std::string docs = "Macro named: ";
- docs += this->GetName();
- return docs.c_str();
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return this->GetTerseDocumentation();
- }
+ virtual std::string GetName() const { return this->Args[0]; }
cmTypeMacro(cmMacroHelperCommand, cmCommand);
@@ -102,10 +85,6 @@ bool cmMacroHelperCommand::InvokeInitialPass
std::vector<std::string> expandedArgs;
this->Makefile->ExpandArguments(args, expandedArgs);
- std::string tmps;
- cmListFileArgument arg;
- std::string variable;
-
// make sure the number of arguments passed is at least the number
// required by the signature
if (expandedArgs.size() < this->Args.size() - 1)
@@ -113,30 +92,36 @@ bool cmMacroHelperCommand::InvokeInitialPass
std::string errorMsg =
"Macro invoked with incorrect arguments for macro named: ";
errorMsg += this->Args[0];
- this->SetError(errorMsg.c_str());
+ this->SetError(errorMsg);
return false;
}
- // Enforce matching logical blocks inside the macro.
- cmMakefile::LexicalPushPop lexScope(this->Makefile);
-
- // Push a weak policy scope which restores the policies recorded at
- // macro creation.
- cmMakefile::PolicyPushPop polScope(this->Makefile, true, this->Policies);
+ cmMakefile::MacroPushPop macroScope(this->Makefile,
+ this->FilePath,
+ this->Policies);
// set the value of argc
- cmOStringStream argcDefStream;
+ std::ostringstream argcDefStream;
argcDefStream << expandedArgs.size();
std::string argcDef = argcDefStream.str();
- // declare varuiables for ARGV ARGN but do not compute until needed
- std::string argvDef;
- std::string argnDef;
- bool argnDefInitialized = false;
- bool argvDefInitialized = false;
- if( this->Functions.size())
+ std::vector<std::string>::const_iterator eit
+ = expandedArgs.begin() + (this->Args.size() - 1);
+ std::string expandedArgn = cmJoin(cmMakeRange(eit, expandedArgs.end()), ";");
+ std::string expandedArgv = cmJoin(expandedArgs, ";");
+ std::vector<std::string> variables;
+ variables.reserve(this->Args.size() - 1);
+ for (unsigned int j = 1; j < this->Args.size(); ++j)
{
- this->FilePath = this->Functions[0].FilePath;
+ variables.push_back("${" + this->Args[j] + "}");
+ }
+ std::vector<std::string> argVs;
+ argVs.reserve(expandedArgs.size());
+ char argvName[60];
+ for (unsigned int j = 0; j < expandedArgs.size(); ++j)
+ {
+ sprintf(argvName,"${ARGV%i}",j);
+ argVs.push_back(argvName);
}
// Invoke all the functions that were collected in the block.
cmListFileFunction newLFF;
@@ -147,7 +132,6 @@ bool cmMacroHelperCommand::InvokeInitialPass
newLFF.Arguments.clear();
newLFF.Arguments.reserve(this->Functions[c].Arguments.size());
newLFF.Name = this->Functions[c].Name;
- newLFF.FilePath = this->Functions[c].FilePath;
newLFF.Line = this->Functions[c].Line;
// for each argument of the current function
@@ -155,80 +139,34 @@ bool cmMacroHelperCommand::InvokeInitialPass
this->Functions[c].Arguments.begin();
k != this->Functions[c].Arguments.end(); ++k)
{
- // Set the FilePath on the arguments to match the function since it is
- // not stored and the original values may be freed
- k->FilePath = this->FilePath.c_str();
- tmps = k->Value;
- // replace formal arguments
- for (unsigned int j = 1; j < this->Args.size(); ++j)
+ cmListFileArgument arg;
+ arg.Value = k->Value;
+ if(k->Delim != cmListFileArgument::Bracket)
{
- variable = "${";
- variable += this->Args[j];
- variable += "}";
- cmSystemTools::ReplaceString(tmps, variable.c_str(),
- expandedArgs[j-1].c_str());
- }
- // replace argc
- cmSystemTools::ReplaceString(tmps, "${ARGC}",argcDef.c_str());
-
- // repleace ARGN
- if (tmps.find("${ARGN}") != std::string::npos)
- {
- if (!argnDefInitialized)
+ // replace formal arguments
+ for (unsigned int j = 0; j < variables.size(); ++j)
{
- std::vector<std::string>::const_iterator eit;
- std::vector<std::string>::size_type cnt = 0;
- for ( eit = expandedArgs.begin(); eit != expandedArgs.end(); ++eit )
- {
- if ( cnt >= this->Args.size()-1 )
- {
- if ( argnDef.size() > 0 )
- {
- argnDef += ";";
- }
- argnDef += *eit;
- }
- cnt ++;
- }
- argnDefInitialized = true;
+ cmSystemTools::ReplaceString(arg.Value, variables[j],
+ expandedArgs[j]);
}
- cmSystemTools::ReplaceString(tmps, "${ARGN}", argnDef.c_str());
- }
+ // replace argc
+ cmSystemTools::ReplaceString(arg.Value, "${ARGC}", argcDef);
- // if the current argument of the current function has ${ARGV in it
- // then try replacing ARGV values
- if (tmps.find("${ARGV") != std::string::npos)
- {
- char argvName[60];
+ cmSystemTools::ReplaceString(arg.Value, "${ARGN}", expandedArgn);
+ cmSystemTools::ReplaceString(arg.Value, "${ARGV}", expandedArgv);
- // repleace ARGV, compute it only once
- if (!argvDefInitialized)
+ // if the current argument of the current function has ${ARGV in it
+ // then try replacing ARGV values
+ if (arg.Value.find("${ARGV") != std::string::npos)
{
- std::vector<std::string>::const_iterator eit;
- for ( eit = expandedArgs.begin(); eit != expandedArgs.end(); ++eit )
+ for (unsigned int t = 0; t < expandedArgs.size(); ++t)
{
- if ( argvDef.size() > 0 )
- {
- argvDef += ";";
- }
- argvDef += *eit;
+ cmSystemTools::ReplaceString(arg.Value, argVs[t],
+ expandedArgs[t]);
}
- argvDefInitialized = true;
- }
- cmSystemTools::ReplaceString(tmps, "${ARGV}", argvDef.c_str());
-
- // also replace the ARGV1 ARGV2 ... etc
- for (unsigned int t = 0; t < expandedArgs.size(); ++t)
- {
- sprintf(argvName,"${ARGV%i}",t);
- cmSystemTools::ReplaceString(tmps, argvName,
- expandedArgs[t].c_str());
}
}
-
- arg.Value = tmps;
arg.Delim = k->Delim;
- arg.FilePath = k->FilePath;
arg.Line = k->Line;
newLFF.Arguments.push_back(arg);
}
@@ -238,8 +176,7 @@ bool cmMacroHelperCommand::InvokeInitialPass
{
// The error message should have already included the call stack
// so we do not need to report an error here.
- lexScope.Quiet();
- polScope.Quiet();
+ macroScope.Quiet();
inStatus.SetNestedError(true);
return false;
}
@@ -272,24 +209,16 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
// if this is the endmacro for this macro then execute
if (!this->Depth)
{
- std::string name = this->Args[0];
- std::vector<std::string>::size_type cc;
- name += "(";
- for ( cc = 0; cc < this->Args.size(); cc ++ )
- {
- name += " " + this->Args[cc];
- }
- name += " )";
- mf.AddMacro(this->Args[0].c_str(), name.c_str());
+ mf.AppendProperty("MACROS", this->Args[0].c_str());
// create a new command and add it to cmake
cmMacroHelperCommand *f = new cmMacroHelperCommand();
f->Args = this->Args;
f->Functions = this->Functions;
+ f->FilePath = this->GetStartingContext().FilePath;
mf.RecordPolicies(f->Policies);
std::string newName = "_" + this->Args[0];
- mf.GetCMakeInstance()->RenameCommand(this->Args[0].c_str(),
- newName.c_str());
- mf.AddCommand(f);
+ mf.GetState()->RenameCommand(this->Args[0], newName);
+ mf.GetState()->AddCommand(f);
// remove the function blocker now that the macro is defined
mf.RemoveFunctionBlocker(this, lff);
@@ -315,7 +244,8 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf)
if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endmacro"))
{
std::vector<std::string> expandedArguments;
- mf.ExpandArguments(lff.Arguments, expandedArguments);
+ mf.ExpandArguments(lff.Arguments, expandedArguments,
+ this->GetStartingContext().FilePath.c_str());
// if the endmacro has arguments make sure they
// match the arguments of the macro
if ((expandedArguments.empty() ||
@@ -339,11 +269,7 @@ bool cmMacroCommand::InitialPass(std::vector<std::string> const& args,
// create a function blocker
cmMacroFunctionBlocker *f = new cmMacroFunctionBlocker();
- for(std::vector<std::string>::const_iterator j = args.begin();
- j != args.end(); ++j)
- {
- f->Args.push_back(*j);
- }
+ f->Args.insert(f->Args.end(), args.begin(), args.end());
this->Makefile->AddFunctionBlocker(f);
return true;
}
diff --git a/Source/cmMacroCommand.h b/Source/cmMacroCommand.h
index aedbb4ddc..5c1cc000a 100644
--- a/Source/cmMacroCommand.h
+++ b/Source/cmMacroCommand.h
@@ -57,52 +57,8 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "macro";}
+ virtual std::string GetName() const { return "macro";}
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Start recording a macro for later invocation as a command.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " macro(<name> [arg1 [arg2 [arg3 ...]]])\n"
- " COMMAND1(ARGS ...)\n"
- " COMMAND2(ARGS ...)\n"
- " ...\n"
- " endmacro(<name>)\n"
- "Define a macro named <name> that takes arguments named "
- "arg1 arg2 arg3 (...). Commands listed after macro, "
- "but before the matching endmacro, are not invoked until the macro "
- "is invoked. When it is invoked, the commands recorded in the "
- "macro are first modified by replacing formal parameters (${arg1}) "
- "with the arguments passed, and then invoked as normal commands. In "
- "addition to referencing the formal parameters you can reference "
- "the values ${ARGC} which will be set to the number of arguments "
- "passed into the function as well as ${ARGV0} ${ARGV1} ${ARGV2} "
- "... which "
- "will have the actual values of the arguments passed in. This "
- "facilitates creating macros with optional arguments. Additionally "
- "${ARGV} holds the list of all arguments given to the macro and "
- "${ARGN} "
- "holds the list of arguments past the last expected argument. "
- "Note that the parameters to a macro and values such as ARGN "
- "are not variables in the usual CMake sense. They are string "
- "replacements much like the C preprocessor would do with a macro. "
- "If you want true CMake variables and/or better CMake scope control "
- "you should look at the function command."
- "\n"
- "See the cmake_policy() command documentation for the behavior of "
- "policies inside macros."
- ;
- }
cmTypeMacro(cmMacroCommand, cmCommand);
};
diff --git a/Source/cmMakeDepend.cxx b/Source/cmMakeDepend.cxx
deleted file mode 100644
index 2ae35ef14..000000000
--- a/Source/cmMakeDepend.cxx
+++ /dev/null
@@ -1,364 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#include "cmMakeDepend.h"
-#include "cmSystemTools.h"
-#include "cmGeneratorExpression.h"
-
-#include <cmsys/RegularExpression.hxx>
-
-void cmDependInformation::AddDependencies(cmDependInformation* info)
-{
- if(this != info)
- {
- this->DependencySet.insert(info);
- }
-}
-
-cmMakeDepend::cmMakeDepend()
-{
- this->Verbose = false;
- this->IncludeFileRegularExpression.compile("^.*$");
- this->ComplainFileRegularExpression.compile("^$");
-}
-
-
-cmMakeDepend::~cmMakeDepend()
-{
- for(DependInformationMapType::iterator i =
- this->DependInformationMap.begin();
- i != this->DependInformationMap.end(); ++i)
- {
- delete i->second;
- }
-}
-
-
-// Set the makefile that depends will be made from.
-// The pointer is kept so the cmSourceFile array can
-// be updated with the depend information in the cmMakefile.
-
-void cmMakeDepend::SetMakefile(cmMakefile* makefile)
-{
- this->Makefile = makefile;
-
- // Now extract the include file regular expression from the makefile.
- this->IncludeFileRegularExpression.compile(
- this->Makefile->IncludeFileRegularExpression.c_str());
- this->ComplainFileRegularExpression.compile(
- this->Makefile->ComplainFileRegularExpression.c_str());
-
- // Now extract any include paths from the targets
- std::set<std::string> uniqueIncludes;
- std::vector<std::string> orderedAndUniqueIncludes;
- cmTargets &targets = this->Makefile->GetTargets();
- for (cmTargets::iterator l = targets.begin();
- l != targets.end(); ++l)
- {
- const char *incDirProp = l->second.GetProperty("INCLUDE_DIRECTORIES");
- if (!incDirProp)
- {
- continue;
- }
-
- std::string incDirs = cmGeneratorExpression::Preprocess(incDirProp,
- cmGeneratorExpression::StripAllGeneratorExpressions);
-
- std::vector<std::string> includes;
- cmSystemTools::ExpandListArgument(incDirs.c_str(), includes);
-
- for(std::vector<std::string>::const_iterator j = includes.begin();
- j != includes.end(); ++j)
- {
- std::string path = *j;
- this->Makefile->ExpandVariablesInString(path);
- if(uniqueIncludes.insert(path).second)
- {
- orderedAndUniqueIncludes.push_back(path);
- }
- }
- }
-
- for(std::vector<std::string>::const_iterator
- it = orderedAndUniqueIncludes.begin();
- it != orderedAndUniqueIncludes.end();
- ++it)
- {
- this->AddSearchPath(it->c_str());
- }
-}
-
-
-const cmDependInformation* cmMakeDepend::FindDependencies(const char* file)
-{
- cmDependInformation* info = this->GetDependInformation(file,0);
- this->GenerateDependInformation(info);
- return info;
-}
-
-void cmMakeDepend::GenerateDependInformation(cmDependInformation* info)
-{
- // If dependencies are already done, stop now.
- if(info->DependDone)
- {
- return;
- }
- else
- {
- // Make sure we don't visit the same file more than once.
- info->DependDone = true;
- }
- const char* path = info->FullPath.c_str();
- if(!path)
- {
- cmSystemTools::Error(
- "Attempt to find dependencies for file without path!");
- return;
- }
-
- bool found = false;
-
- // If the file exists, use it to find dependency information.
- if(cmSystemTools::FileExists(path, true))
- {
- // Use the real file to find its dependencies.
- this->DependWalk(info);
- found = true;
- }
-
-
- // See if the cmSourceFile for it has any files specified as
- // dependency hints.
- if(info->SourceFile != 0)
- {
-
- // Get the cmSourceFile corresponding to this.
- const cmSourceFile& cFile = *(info->SourceFile);
- // See if there are any hints for finding dependencies for the missing
- // file.
- if(!cFile.GetDepends().empty())
- {
- // Dependency hints have been given. Use them to begin the
- // recursion.
- for(std::vector<std::string>::const_iterator file =
- cFile.GetDepends().begin(); file != cFile.GetDepends().end();
- ++file)
- {
- this->AddDependency(info, file->c_str());
- }
-
- // Found dependency information. We are done.
- found = true;
- }
- }
-
- if(!found)
- {
- // Try to find the file amongst the sources
- cmSourceFile *srcFile = this->Makefile->GetSource
- (cmSystemTools::GetFilenameWithoutExtension(path).c_str());
- if (srcFile)
- {
- if (srcFile->GetFullPath() == path)
- {
- found=true;
- }
- else
- {
- //try to guess which include path to use
- for(std::vector<std::string>::iterator t =
- this->IncludeDirectories.begin();
- t != this->IncludeDirectories.end(); ++t)
- {
- std::string incpath = *t;
- if (incpath.size() && incpath[incpath.size() - 1] != '/')
- {
- incpath = incpath + "/";
- }
- incpath = incpath + path;
- if (srcFile->GetFullPath() == incpath)
- {
- // set the path to the guessed path
- info->FullPath = incpath;
- found=true;
- }
- }
- }
- }
- }
-
- if(!found)
- {
- // Couldn't find any dependency information.
- if(this->ComplainFileRegularExpression.find(info->IncludeName.c_str()))
- {
- cmSystemTools::Error("error cannot find dependencies for ", path);
- }
- else
- {
- // Destroy the name of the file so that it won't be output as a
- // dependency.
- info->FullPath = "";
- }
- }
-}
-
-// This function actually reads the file specified and scans it for
-// #include directives
-void cmMakeDepend::DependWalk(cmDependInformation* info)
-{
- cmsys::RegularExpression includeLine
- ("^[ \t]*#[ \t]*include[ \t]*[<\"]([^\">]+)[\">]");
- std::ifstream fin(info->FullPath.c_str());
- if(!fin)
- {
- cmSystemTools::Error("Cannot open ", info->FullPath.c_str());
- return;
- }
-
- // TODO: Write real read loop (see cmSystemTools::CopyFile).
- std::string line;
- while( cmSystemTools::GetLineFromStream(fin, line) )
- {
- if(includeLine.find(line.c_str()))
- {
- // extract the file being included
- std::string includeFile = includeLine.match(1);
- // see if the include matches the regular expression
- if(!this->IncludeFileRegularExpression.find(includeFile))
- {
- if(this->Verbose)
- {
- std::string message = "Skipping ";
- message += includeFile;
- message += " for file ";
- message += info->FullPath.c_str();
- cmSystemTools::Error(message.c_str(), 0);
- }
- continue;
- }
-
- // Add this file and all its dependencies.
- this->AddDependency(info, includeFile.c_str());
- }
- }
-}
-
-
-void cmMakeDepend::AddDependency(cmDependInformation* info, const char* file)
-{
- cmDependInformation* dependInfo =
- this->GetDependInformation(file, info->PathOnly.c_str());
- this->GenerateDependInformation(dependInfo);
- info->AddDependencies(dependInfo);
-}
-
-cmDependInformation* cmMakeDepend::GetDependInformation(const char* file,
- const char *extraPath)
-{
- // Get the full path for the file so that lookup is unambiguous.
- std::string fullPath = this->FullPath(file, extraPath);
-
- // Try to find the file's instance of cmDependInformation.
- DependInformationMapType::const_iterator result =
- this->DependInformationMap.find(fullPath);
- if(result != this->DependInformationMap.end())
- {
- // Found an instance, return it.
- return result->second;
- }
- else
- {
- // Didn't find an instance. Create a new one and save it.
- cmDependInformation* info = new cmDependInformation;
- info->FullPath = fullPath;
- info->PathOnly = cmSystemTools::GetFilenamePath(fullPath.c_str());
- info->IncludeName = file;
- this->DependInformationMap[fullPath] = info;
- return info;
- }
-}
-
-
-// find the full path to fname by searching the this->IncludeDirectories array
-std::string cmMakeDepend::FullPath(const char* fname, const char *extraPath)
-{
- DirectoryToFileToPathMapType::iterator m;
- if(extraPath)
- {
- m = this->DirectoryToFileToPathMap.find(extraPath);
- }
- else
- {
- m = this->DirectoryToFileToPathMap.find("");
- }
-
- if(m != this->DirectoryToFileToPathMap.end())
- {
- FileToPathMapType& map = m->second;
- FileToPathMapType::iterator p = map.find(fname);
- if(p != map.end())
- {
- return p->second;
- }
- }
-
- if(cmSystemTools::FileExists(fname, true))
- {
- std::string fp = cmSystemTools::CollapseFullPath(fname);
- this->DirectoryToFileToPathMap[extraPath? extraPath: ""][fname] = fp;
- return fp;
- }
-
- for(std::vector<std::string>::iterator i = this->IncludeDirectories.begin();
- i != this->IncludeDirectories.end(); ++i)
- {
- std::string path = *i;
- if (path.size() && path[path.size() - 1] != '/')
- {
- path = path + "/";
- }
- path = path + fname;
- if(cmSystemTools::FileExists(path.c_str(), true)
- && !cmSystemTools::FileIsDirectory(path.c_str()))
- {
- std::string fp = cmSystemTools::CollapseFullPath(path.c_str());
- this->DirectoryToFileToPathMap[extraPath? extraPath: ""][fname] = fp;
- return fp;
- }
- }
-
- if (extraPath)
- {
- std::string path = extraPath;
- if (path.size() && path[path.size() - 1] != '/')
- {
- path = path + "/";
- }
- path = path + fname;
- if(cmSystemTools::FileExists(path.c_str(), true)
- && !cmSystemTools::FileIsDirectory(path.c_str()))
- {
- std::string fp = cmSystemTools::CollapseFullPath(path.c_str());
- this->DirectoryToFileToPathMap[extraPath][fname] = fp;
- return fp;
- }
- }
-
- // Couldn't find the file.
- return std::string(fname);
-}
-
-// Add a directory to the search path
-void cmMakeDepend::AddSearchPath(const char* path)
-{
- this->IncludeDirectories.push_back(path);
-}
diff --git a/Source/cmMakeDepend.h b/Source/cmMakeDepend.h
deleted file mode 100644
index b6e3928e9..000000000
--- a/Source/cmMakeDepend.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef cmMakeDepend_h
-#define cmMakeDepend_h
-
-#include "cmMakefile.h"
-#include "cmSourceFile.h"
-
-#include <cmsys/RegularExpression.hxx>
-
-/** \class cmDependInformation
- * \brief Store dependency information for a single source file.
- *
- * This structure stores the depend information for a single source file.
- */
-class cmDependInformation
-{
-public:
- /**
- * Construct with dependency generation marked not done; instance
- * not placed in cmMakefile's list.
- */
- cmDependInformation(): DependDone(false), SourceFile(0) {}
-
- /**
- * The set of files on which this one depends.
- */
- typedef std::set<cmDependInformation*> DependencySetType;
- DependencySetType DependencySet;
-
- /**
- * This flag indicates whether dependency checking has been
- * performed for this file.
- */
- bool DependDone;
-
- /**
- * If this object corresponds to a cmSourceFile instance, this points
- * to it.
- */
- const cmSourceFile *SourceFile;
-
- /**
- * Full path to this file.
- */
- std::string FullPath;
-
- /**
- * Full path not including file name.
- */
- std::string PathOnly;
-
- /**
- * Name used to #include this file.
- */
- std::string IncludeName;
-
- /**
- * This method adds the dependencies of another file to this one.
- */
- void AddDependencies(cmDependInformation*);
-};
-
-
-// cmMakeDepend is used to generate dependancy information for
-// the classes in a makefile
-class cmMakeDepend
-{
-public:
- /**
- * Construct the object with verbose turned off.
- */
- cmMakeDepend();
-
- /**
- * Destructor.
- */
- virtual ~cmMakeDepend();
-
- /**
- * Set the makefile that is used as a source of classes.
- */
- virtual void SetMakefile(cmMakefile* makefile);
-
- /**
- * Add a directory to the search path for include files.
- */
- virtual void AddSearchPath(const char*);
-
- /**
- * Generate dependencies for the file given. Returns a pointer to
- * the cmDependInformation object for the file.
- */
- const cmDependInformation* FindDependencies(const char* file);
-
-protected:
- /**
- * Compute the depend information for this class.
- */
- virtual void DependWalk(cmDependInformation* info);
-
- /**
- * Add a dependency. Possibly walk it for more dependencies.
- */
- virtual void AddDependency(cmDependInformation* info, const char* file);
-
- /**
- * Fill in the given object with dependency information. If the
- * information is already complete, nothing is done.
- */
- void GenerateDependInformation(cmDependInformation* info);
-
- /**
- * Get an instance of cmDependInformation corresponding to the given file
- * name.
- */
- cmDependInformation* GetDependInformation(const char* file,
- const char *extraPath);
-
- /**
- * Find the full path name for the given file name.
- * This uses the include directories.
- * TODO: Cache path conversions to reduce FileExists calls.
- */
- std::string FullPath(const char *filename, const char *extraPath);
-
- cmMakefile* Makefile;
- bool Verbose;
- cmsys::RegularExpression IncludeFileRegularExpression;
- cmsys::RegularExpression ComplainFileRegularExpression;
- std::vector<std::string> IncludeDirectories;
- typedef std::map<cmStdString, cmStdString> FileToPathMapType;
- typedef std::map<cmStdString, FileToPathMapType>
- DirectoryToFileToPathMapType;
- typedef std::map<cmStdString, cmDependInformation*>
- DependInformationMapType;
- DependInformationMapType DependInformationMap;
- DirectoryToFileToPathMapType DirectoryToFileToPathMap;
-};
-
-#endif
diff --git a/Source/cmMakeDirectoryCommand.cxx b/Source/cmMakeDirectoryCommand.cxx
index 63be62734..cc871c93c 100644
--- a/Source/cmMakeDirectoryCommand.cxx
+++ b/Source/cmMakeDirectoryCommand.cxx
@@ -24,7 +24,7 @@ bool cmMakeDirectoryCommand
{
std::string e = "attempted to create a directory: " + args[0]
+ " into a source directory.";
- this->SetError(e.c_str());
+ this->SetError(e);
cmSystemTools::SetFatalErrorOccured();
return false;
}
diff --git a/Source/cmMakeDirectoryCommand.h b/Source/cmMakeDirectoryCommand.h
index a0f866a5f..617f1fef4 100644
--- a/Source/cmMakeDirectoryCommand.h
+++ b/Source/cmMakeDirectoryCommand.h
@@ -44,39 +44,13 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "make_directory";}
+ virtual std::string GetName() const { return "make_directory";}
/**
* This determines if the command is invoked when in script mode.
*/
virtual bool IsScriptable() const { return true; }
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Deprecated. Use the file(MAKE_DIRECTORY ) command instead.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " make_directory(directory)\n"
- "Creates the specified directory. Full paths should be given. Any "
- "parent directories that do not exist will also be created. Use with "
- "care.";
- }
-
- /** This command is kept for compatibility with older CMake versions. */
- virtual bool IsDiscouraged() const
- {
- return true;
- }
-
cmTypeMacro(cmMakeDirectoryCommand, cmCommand);
};
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 34541e996..600c985f0 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -16,14 +16,13 @@
#include "cmSourceFileLocation.h"
#include "cmSystemTools.h"
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
#include "cmCommands.h"
-#include "cmCacheManager.h"
+#include "cmState.h"
+#include "cmOutputConverter.h"
#include "cmFunctionBlocker.h"
+#include "cmGeneratorExpressionEvaluationFile.h"
#include "cmListFileCache.h"
-#include "cmDocumentGeneratorExpressions.h"
#include "cmCommandArgumentParserHelper.h"
-#include "cmDocumentCompileDefinitions.h"
#include "cmGeneratorExpression.h"
#include "cmTest.h"
#ifdef CMAKE_BUILD_WITH_CMAKE
@@ -31,345 +30,192 @@
#endif
#include "cmInstallGenerator.h"
#include "cmTestGenerator.h"
-#include "cmDefinitions.h"
+#include "cmAlgorithms.h"
#include "cmake.h"
#include <stdlib.h> // required for atoi
#include <cmsys/RegularExpression.hxx>
-
+#include <cmsys/FStream.hxx>
#include <cmsys/auto_ptr.hxx>
-#include <stack>
+#include <list>
#include <ctype.h> // for isspace
#include <assert.h>
-class cmMakefile::Internals
-{
-public:
- std::stack<cmDefinitions, std::list<cmDefinitions> > VarStack;
- std::stack<std::set<cmStdString> > VarInitStack;
- std::stack<std::set<cmStdString> > VarUsageStack;
- bool IsSourceFileTryCompile;
-};
-
// default is not to be building executables
-cmMakefile::cmMakefile(): Internal(new Internals)
+cmMakefile::cmMakefile(cmGlobalGenerator* globalGenerator,
+ cmState::Snapshot const& snapshot)
+ : GlobalGenerator(globalGenerator),
+ StateSnapshot(snapshot)
{
- const cmDefinitions& defs = cmDefinitions();
- const std::set<cmStdString> globalKeys = defs.LocalKeys();
- this->Internal->VarStack.push(defs);
- this->Internal->VarInitStack.push(globalKeys);
- this->Internal->VarUsageStack.push(globalKeys);
- this->Internal->IsSourceFileTryCompile = false;
+ this->IsSourceFileTryCompile = false;
- // Initialize these first since AddDefaultDefinitions calls AddDefinition
- this->WarnUnused = false;
- this->CheckSystemVars = false;
+ this->WarnUnused = this->GetCMakeInstance()->GetWarnUnused();
+ this->CheckSystemVars = this->GetCMakeInstance()->GetCheckSystemVars();
+
+ this->SuppressWatches = false;
- // Setup the default include file regular expression (match everything).
- this->IncludeFileRegularExpression = "^.*$";
// Setup the default include complaint regular expression (match nothing).
this->ComplainFileRegularExpression = "^$";
- // Source and header file extensions that we can handle
-
- // Set up a list of source and header extensions
- // these are used to find files when the extension
- // is not given
- // The "c" extension MUST precede the "C" extension.
- this->SourceFileExtensions.push_back( "c" );
- this->SourceFileExtensions.push_back( "C" );
-
- this->SourceFileExtensions.push_back( "c++" );
- this->SourceFileExtensions.push_back( "cc" );
- this->SourceFileExtensions.push_back( "cpp" );
- this->SourceFileExtensions.push_back( "cxx" );
- this->SourceFileExtensions.push_back( "m" );
- this->SourceFileExtensions.push_back( "M" );
- this->SourceFileExtensions.push_back( "mm" );
-
- this->HeaderFileExtensions.push_back( "h" );
- this->HeaderFileExtensions.push_back( "hh" );
- this->HeaderFileExtensions.push_back( "h++" );
- this->HeaderFileExtensions.push_back( "hm" );
- this->HeaderFileExtensions.push_back( "hpp" );
- this->HeaderFileExtensions.push_back( "hxx" );
- this->HeaderFileExtensions.push_back( "in" );
- this->HeaderFileExtensions.push_back( "txx" );
this->DefineFlags = " ";
- this->LocalGenerator = 0;
-
- this->AddDefaultDefinitions();
- this->Initialize();
- this->PreOrder = false;
- this->GeneratingBuildSystem = false;
-}
-
-cmMakefile::cmMakefile(const cmMakefile& mf): Internal(new Internals)
-{
- this->Internal->VarStack.push(mf.Internal->VarStack.top().Closure());
- this->Internal->VarInitStack.push(mf.Internal->VarInitStack.top());
- this->Internal->VarUsageStack.push(mf.Internal->VarUsageStack.top());
-
- 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->LinkDirectories = mf.LinkDirectories;
- this->SystemIncludeDirectories = mf.SystemIncludeDirectories;
- this->ListFiles = mf.ListFiles;
- this->OutputFiles = mf.OutputFiles;
- this->LinkLibraries = mf.LinkLibraries;
- this->InstallGenerators = mf.InstallGenerators;
- this->TestGenerators = mf.TestGenerators;
- this->IncludeFileRegularExpression = mf.IncludeFileRegularExpression;
- this->ComplainFileRegularExpression = mf.ComplainFileRegularExpression;
- this->SourceFileExtensions = mf.SourceFileExtensions;
- this->HeaderFileExtensions = mf.HeaderFileExtensions;
- this->DefineFlags = mf.DefineFlags;
- this->DefineFlagsOrig = mf.DefineFlagsOrig;
-
-#if defined(CMAKE_BUILD_WITH_CMAKE)
- this->SourceGroups = mf.SourceGroups;
-#endif
-
- this->LocalGenerator = mf.LocalGenerator;
- this->FunctionBlockers = mf.FunctionBlockers;
- this->MacrosMap = mf.MacrosMap;
- this->SubDirectoryOrder = mf.SubDirectoryOrder;
- this->Properties = mf.Properties;
- this->PreOrder = mf.PreOrder;
- this->WarnUnused = mf.WarnUnused;
- this->Initialize();
- this->CheckSystemVars = mf.CheckSystemVars;
- this->ListFileStack = mf.ListFileStack;
- this->OutputToSource = mf.OutputToSource;
-}
-//----------------------------------------------------------------------------
-void cmMakefile::Initialize()
-{
this->cmDefineRegex.compile("#cmakedefine[ \t]+([A-Za-z_0-9]*)");
this->cmDefine01Regex.compile("#cmakedefine01[ \t]+([A-Za-z_0-9]*)");
this->cmAtVarRegex.compile("(@[A-Za-z_0-9/.+-]+@)");
+ this->cmNamedCurly.compile("^[A-Za-z0-9/_.+-]+{");
+
+ this->StateSnapshot = this->StateSnapshot.GetState()
+ ->CreatePolicyScopeSnapshot(this->StateSnapshot);
// Enter a policy level for this directory.
this->PushPolicy();
- // Protect the directory-level policies.
- this->PushPolicyBarrier();
+ // push empty loop block
+ this->PushLoopBlockBarrier();
// By default the check is not done. It is enabled by
// cmListFileCache in the top level if necessary.
this->CheckCMP0000 = false;
-}
-
-unsigned int cmMakefile::GetCacheMajorVersion()
-{
- return this->GetCacheManager()->GetCacheMajorVersion();
-}
-unsigned int cmMakefile::GetCacheMinorVersion()
-{
- return this->GetCacheManager()->GetCacheMinorVersion();
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ this->AddSourceGroup("", "^.*$");
+ this->AddSourceGroup
+ ("Source Files",
+ "\\.(C|M|c|c\\+\\+|cc|cpp|cxx|f|f90|for|fpp"
+ "|ftn|m|mm|rc|def|r|odl|idl|hpj|bat)$");
+ this->AddSourceGroup("Header Files", CM_HEADER_REGEX);
+ this->AddSourceGroup("CMake Rules", "\\.rule$");
+ this->AddSourceGroup("Resources", "\\.plist$");
+ this->AddSourceGroup("Object Files", "\\.(lo|o|obj)$");
+#endif
}
-bool cmMakefile::NeedCacheCompatibility(int major, int minor)
+cmMakefile::~cmMakefile()
{
- return this->GetCacheManager()->NeedCacheCompatibility(major, minor);
+ cmDeleteAll(this->InstallGenerators);
+ cmDeleteAll(this->TestGenerators);
+ cmDeleteAll(this->SourceFiles);
+ cmDeleteAll(this->Tests);
+ cmDeleteAll(this->ImportedTargetsOwned);
+ cmDeleteAll(this->FinalPassCommands);
+ cmDeleteAll(this->FunctionBlockers);
+ cmDeleteAll(this->EvaluationFiles);
}
-cmMakefile::~cmMakefile()
+//----------------------------------------------------------------------------
+void cmMakefile::IssueMessage(cmake::MessageType t,
+ std::string const& text,
+ bool force) const
{
- for(std::vector<cmInstallGenerator*>::iterator
- i = this->InstallGenerators.begin();
- i != this->InstallGenerators.end(); ++i)
- {
- delete *i;
- }
- for(std::vector<cmTestGenerator*>::iterator
- i = this->TestGenerators.begin();
- i != this->TestGenerators.end(); ++i)
- {
- delete *i;
- }
- for(std::vector<cmSourceFile*>::iterator i = this->SourceFiles.begin();
- i != this->SourceFiles.end(); ++i)
- {
- delete *i;
- }
- for(std::map<cmStdString, cmTest*>::iterator i = this->Tests.begin();
- i != this->Tests.end(); ++i)
- {
- delete i->second;
- }
- for(std::vector<cmTarget*>::iterator
- i = this->ImportedTargetsOwned.begin();
- i != this->ImportedTargetsOwned.end(); ++i)
- {
- delete *i;
- }
- for(unsigned int i=0; i < this->FinalPassCommands.size(); i++)
+ // Collect context information.
+ if(!this->ExecutionStatusStack.empty())
{
- delete this->FinalPassCommands[i];
+ if((t == cmake::FATAL_ERROR) || (t == cmake::INTERNAL_ERROR))
+ {
+ this->ExecutionStatusStack.back()->SetNestedError(true);
+ }
+ this->GetCMakeInstance()->IssueMessage(t, text, this->GetBacktrace(),
+ force);
}
- std::vector<cmFunctionBlocker*>::iterator pos;
- for (pos = this->FunctionBlockers.begin();
- pos != this->FunctionBlockers.end(); ++pos)
+ else
{
- cmFunctionBlocker* b = *pos;
- delete b;
+ cmListFileContext lfc;
+ // We are not currently executing a command. Add whatever context
+ // information we have.
+ lfc.FilePath = this->GetExecutionFilePath();
+
+ if(!this->GetCMakeInstance()->GetIsInTryCompile())
+ {
+ cmOutputConverter converter(this->StateSnapshot);
+ lfc.FilePath = converter.Convert(lfc.FilePath, cmOutputConverter::HOME);
+ }
+ lfc.Line = 0;
+ this->GetCMakeInstance()->IssueMessage(t, text, lfc, force);
}
- this->FunctionBlockers.clear();
- if (this->PolicyStack.size() != 1)
- {
- cmSystemTools::Error("Internal CMake Error, Policy Stack has not been"
- " popped properly");
- }
}
-void cmMakefile::PrintStringVector(const char* s,
- const std::vector<std::string>& v) const
+cmStringRange cmMakefile::GetIncludeDirectoriesEntries() const
{
- std::cout << s << ": ( \n";
- for(std::vector<std::string>::const_iterator i = v.begin();
- i != v.end(); ++i)
- {
- std::cout << (*i).c_str() << " ";
- }
- std::cout << " )\n";
+ return this->StateSnapshot.GetDirectory().GetIncludeDirectoriesEntries();
}
-void cmMakefile
-::PrintStringVector(const char* s,
- const std::vector<std::pair<cmStdString, bool> >& v) const
+cmBacktraceRange cmMakefile::GetIncludeDirectoriesBacktraces() const
{
- std::cout << s << ": ( \n";
- for(std::vector<std::pair<cmStdString, bool> >::const_iterator i
- = v.begin(); i != v.end(); ++i)
- {
- std::cout << i->first.c_str() << " " << i->second;
- }
- std::cout << " )\n";
+ return this->StateSnapshot.GetDirectory()
+ .GetIncludeDirectoriesEntryBacktraces();
}
-
-// call print on all the classes in the makefile
-void cmMakefile::Print()
+cmStringRange cmMakefile::GetCompileOptionsEntries() const
{
- // print the class lists
- std::cout << "classes:\n";
+ return this->StateSnapshot.GetDirectory().GetCompileOptionsEntries();
+}
- std::cout << " this->Targets: ";
- for (cmTargets::iterator l = this->Targets.begin();
- l != this->Targets.end(); l++)
- {
- std::cout << l->first << std::endl;
- }
-
- std::cout << " this->StartOutputDirectory; " <<
- this->StartOutputDirectory.c_str() << std::endl;
- std::cout << " this->HomeOutputDirectory; " <<
- this->HomeOutputDirectory.c_str() << std::endl;
- std::cout << " this->cmStartDirectory; " <<
- this->cmStartDirectory.c_str() << std::endl;
- std::cout << " this->cmHomeDirectory; " <<
- this->cmHomeDirectory.c_str() << std::endl;
- std::cout << " this->ProjectName; "
- << this->ProjectName.c_str() << std::endl;
- this->PrintStringVector("this->LinkDirectories", this->LinkDirectories);
-#if defined(CMAKE_BUILD_WITH_CMAKE)
- for( std::vector<cmSourceGroup>::const_iterator i =
- this->SourceGroups.begin(); i != this->SourceGroups.end(); ++i)
- {
- std::cout << "Source Group: " << i->GetName() << std::endl;
- }
-#endif
+cmBacktraceRange cmMakefile::GetCompileOptionsBacktraces() const
+{
+ return this->StateSnapshot.GetDirectory().GetCompileOptionsEntryBacktraces();
}
-bool cmMakefile::CommandExists(const char* name) const
+cmStringRange cmMakefile::GetCompileDefinitionsEntries() const
{
- return this->GetCMakeInstance()->CommandExists(name);
+ return this->StateSnapshot.GetDirectory().GetCompileDefinitionsEntries();
}
+cmBacktraceRange cmMakefile::GetCompileDefinitionsBacktraces() const
+{
+ return this->StateSnapshot.GetDirectory()
+ .GetCompileDefinitionsEntryBacktraces();
+}
//----------------------------------------------------------------------------
-void cmMakefile::IssueMessage(cmake::MessageType t,
- std::string const& text) const
+cmListFileBacktrace cmMakefile::GetBacktrace() const
{
- // Collect context information.
cmListFileBacktrace backtrace;
- if(!this->CallStack.empty())
+ if (!this->ContextStack.empty())
{
- if((t == cmake::FATAL_ERROR) || (t == cmake::INTERNAL_ERROR))
- {
- this->CallStack.back().Status->SetNestedError(true);
- }
- this->GetBacktrace(backtrace);
- }
- else
- {
- cmListFileContext lfc;
- if(this->ListFileStack.empty())
- {
- // We are not processing the project. Add the directory-level context.
- lfc.FilePath = this->GetCurrentDirectory();
- lfc.FilePath += "/CMakeLists.txt";
- }
- else
- {
- // We are processing the project but are not currently executing a
- // command. Add whatever context information we have.
- lfc.FilePath = this->ListFileStack.back();
- }
- lfc.Line = 0;
- if(!this->GetCMakeInstance()->GetIsInTryCompile())
- {
- lfc.FilePath = this->LocalGenerator->Convert(lfc.FilePath.c_str(),
- cmLocalGenerator::HOME);
- }
- backtrace.push_back(lfc);
+ backtrace = cmListFileBacktrace(this->StateSnapshot,
+ *this->ContextStack.back());
}
+ return backtrace;
+}
- // Issue the message.
- this->GetCMakeInstance()->IssueMessage(t, text, backtrace);
+//----------------------------------------------------------------------------
+cmListFileBacktrace
+cmMakefile::GetBacktrace(cmCommandContext const& cc) const
+{
+ cmState::Snapshot snp = this->StateSnapshot;
+ return cmListFileBacktrace(snp, cc);
}
//----------------------------------------------------------------------------
-bool cmMakefile::GetBacktrace(cmListFileBacktrace& backtrace) const
+cmListFileContext cmMakefile::GetExecutionContext() const
{
- if(this->CallStack.empty())
- {
- return false;
- }
- for(CallStackType::const_reverse_iterator i = this->CallStack.rbegin();
- i != this->CallStack.rend(); ++i)
- {
- cmListFileContext lfc = *(*i).Context;
- lfc.FilePath = this->LocalGenerator->Convert(lfc.FilePath.c_str(),
- cmLocalGenerator::HOME);
- backtrace.push_back(lfc);
- }
- return true;
+ return cmListFileContext::FromCommandContext(
+ *this->ContextStack.back(),
+ this->StateSnapshot.GetExecutionListFile());
}
//----------------------------------------------------------------------------
-void cmMakefile::PrintCommandTrace(const cmListFileFunction& lff)
+void cmMakefile::PrintCommandTrace(const cmListFileFunction& lff) const
{
- cmOStringStream msg;
- msg << lff.FilePath << "(" << lff.Line << "): ";
+ std::ostringstream msg;
+ msg << this->GetExecutionFilePath() << "(" << lff.Line << "): ";
msg << lff.Name << "(";
+ bool expand = this->GetCMakeInstance()->GetTraceExpand();
+ std::string temp;
for(std::vector<cmListFileArgument>::const_iterator i =
lff.Arguments.begin(); i != lff.Arguments.end(); ++i)
{
- msg << i->Value;
+ if (expand)
+ {
+ temp = i->Value;
+ this->ExpandVariablesInString(temp);
+ msg << temp;
+ }
+ else
+ {
+ msg << i->Value;
+ }
msg << " ";
}
msg << ")";
@@ -396,7 +242,7 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
static_cast<void>(stack_manager);
// Lookup the command prototype.
- if(cmCommand* proto = this->GetCMakeInstance()->GetCommand(name.c_str()))
+ if(cmCommand* proto = this->GetState()->GetCommand(name))
{
// Clone the prototype.
cmsys::auto_ptr<cmCommand> pcmd(proto->Clone());
@@ -465,12 +311,12 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
class cmMakefile::IncludeScope
{
public:
- IncludeScope(cmMakefile* mf, const char* fname, bool noPolicyScope);
+ IncludeScope(cmMakefile* mf, std::string const& filenametoread,
+ bool noPolicyScope);
~IncludeScope();
void Quiet() { this->ReportError = false; }
private:
cmMakefile* Makefile;
- const char* File;
bool NoPolicyScope;
bool CheckCMP0011;
bool ReportError;
@@ -478,11 +324,20 @@ private:
};
//----------------------------------------------------------------------------
-cmMakefile::IncludeScope::IncludeScope(cmMakefile* mf, const char* fname,
+cmMakefile::IncludeScope::IncludeScope(cmMakefile* mf,
+ std::string const& filenametoread,
bool noPolicyScope):
- Makefile(mf), File(fname), NoPolicyScope(noPolicyScope),
+ Makefile(mf), NoPolicyScope(noPolicyScope),
CheckCMP0011(false), ReportError(true)
{
+ this->Makefile->PushFunctionBlockerBarrier();
+
+ this->Makefile->StateSnapshot =
+ this->Makefile->GetState()->CreateCallStackSnapshot(
+ this->Makefile->StateSnapshot,
+ this->Makefile->ContextStack.back()->Name,
+ this->Makefile->ContextStack.back()->Line,
+ filenametoread);
if(!this->NoPolicyScope)
{
// Check CMP0011 to determine the policy scope type.
@@ -511,24 +366,19 @@ cmMakefile::IncludeScope::IncludeScope(cmMakefile* mf, const char* fname,
break;
}
}
-
- // The included file cannot pop our policy scope.
- this->Makefile->PushPolicyBarrier();
}
//----------------------------------------------------------------------------
cmMakefile::IncludeScope::~IncludeScope()
{
- // Enforce matching policy scopes inside the included file.
- this->Makefile->PopPolicyBarrier(this->ReportError);
-
if(!this->NoPolicyScope)
{
// If we need to enforce policy CMP0011 then the top entry is the
// one we pushed above. If the entry is empty, then the included
// script did not set any policies that might affect the includer so
// we do not need to enforce the policy.
- if(this->CheckCMP0011 && this->Makefile->PolicyStack.back().empty())
+ if(this->CheckCMP0011
+ && !this->Makefile->StateSnapshot.HasDefinedPolicyCMP0011())
{
this->CheckCMP0011 = false;
}
@@ -543,6 +393,9 @@ cmMakefile::IncludeScope::~IncludeScope()
this->EnforceCMP0011();
}
}
+ this->Makefile->PopSnapshot(this->ReportError);
+
+ this->Makefile->PopFunctionBlockerBarrier(this->ReportError);
}
//----------------------------------------------------------------------------
@@ -550,15 +403,15 @@ void cmMakefile::IncludeScope::EnforceCMP0011()
{
// We check the setting of this policy again because the included
// script might actually set this policy for its includer.
- cmPolicies* policies = this->Makefile->GetPolicies();
switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0011))
{
case cmPolicies::WARN:
// Warn because the user did not set this policy.
{
- cmOStringStream w;
- w << policies->GetPolicyWarning(cmPolicies::CMP0011) << "\n"
- << "The included script\n " << this->File << "\n"
+ std::ostringstream w;
+ w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0011) << "\n"
+ << "The included script\n "
+ << this->Makefile->GetExecutionFilePath() << "\n"
<< "affects policy settings. "
<< "CMake is implying the NO_POLICY_SCOPE option for compatibility, "
<< "so the effects are applied to the including context.";
@@ -568,9 +421,10 @@ void cmMakefile::IncludeScope::EnforceCMP0011()
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
{
- cmOStringStream e;
- e << policies->GetRequiredPolicyError(cmPolicies::CMP0011) << "\n"
- << "The included script\n " << this->File << "\n"
+ std::ostringstream e;
+ e << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0011) << "\n"
+ << "The included script\n "
+ << this->Makefile->GetExecutionFilePath() << "\n"
<< "affects policy settings, so it requires this policy to be set.";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
}
@@ -584,123 +438,137 @@ void cmMakefile::IncludeScope::EnforceCMP0011()
}
}
-//----------------------------------------------------------------------------
-// Parse the given CMakeLists.txt file executing all commands
-//
-bool cmMakefile::ReadListFile(const char* filename_in,
- const char *external_in,
- std::string* fullPath,
- bool noPolicyScope)
+class cmParseFileScope
{
- std::string currentParentFile
- = this->GetSafeDefinition("CMAKE_PARENT_LIST_FILE");
- std::string currentFile
- = this->GetSafeDefinition("CMAKE_CURRENT_LIST_FILE");
- this->AddDefinition("CMAKE_PARENT_LIST_FILE", filename_in);
- this->MarkVariableAsUsed("CMAKE_PARENT_LIST_FILE");
+public:
+ cmParseFileScope(cmMakefile* mf)
+ : Makefile(mf)
+ {
+ this->Makefile->ContextStack.push_back(&this->Context);
+ }
+
+ ~cmParseFileScope()
+ {
+ this->Makefile->ContextStack.pop_back();
+ }
+
+private:
+ cmMakefile* Makefile;
+ cmCommandContext Context;
+};
- const char* external = 0;
- std::string external_abs;
+bool cmMakefile::ReadDependentFile(const char* filename, bool noPolicyScope)
+{
+ this->AddDefinition("CMAKE_PARENT_LIST_FILE",
+ this->GetDefinition("CMAKE_CURRENT_LIST_FILE"));
+ std::string filenametoread =
+ cmSystemTools::CollapseFullPath(filename,
+ this->GetCurrentSourceDirectory());
- const char* filename = filename_in;
- std::string filename_abs;
+ IncludeScope incScope(this, filenametoread, noPolicyScope);
- if (external_in)
+ cmListFile listFile;
+ {
+ cmParseFileScope pfs(this);
+ if (!listFile.ParseFile(filenametoread.c_str(), false, this))
{
- external_abs =
- cmSystemTools::CollapseFullPath(external_in,
- this->cmStartDirectory.c_str());
- external = external_abs.c_str();
- if (filename_in)
- {
- filename_abs =
- cmSystemTools::CollapseFullPath(filename_in,
- this->cmStartDirectory.c_str());
- filename = filename_abs.c_str();
- }
+ return false;
}
+ }
- // keep track of the current file being read
- if (filename)
+ this->ReadListFile(listFile, filenametoread);
+ if(cmSystemTools::GetFatalErrorOccured())
{
- if(this->cmCurrentListFile != filename)
+ incScope.Quiet();
+ }
+ return true;
+}
+
+class cmMakefile::ListFileScope
+{
+public:
+ ListFileScope(cmMakefile* mf, std::string const& filenametoread)
+ : Makefile(mf), ReportError(true)
+ {
+ long line = 0;
+ std::string name;
+ if (!this->Makefile->ContextStack.empty())
{
- this->cmCurrentListFile = filename;
+ line = this->Makefile->ContextStack.back()->Line;
+ name = this->Makefile->ContextStack.back()->Name;
}
- }
+ this->Makefile->StateSnapshot =
+ this->Makefile->GetState()->CreateInlineListFileSnapshot(
+ this->Makefile->StateSnapshot, name, line, filenametoread);
+ assert(this->Makefile->StateSnapshot.IsValid());
- // Now read the input file
- const char *filenametoread= filename;
+ this->Makefile->PushFunctionBlockerBarrier();
+ }
- if( external)
- {
- filenametoread= external;
- }
+ ~ListFileScope()
+ {
+ this->Makefile->PopSnapshot(this->ReportError);
+ this->Makefile->PopFunctionBlockerBarrier(this->ReportError);
+ }
- this->AddDefinition("CMAKE_CURRENT_LIST_FILE", filenametoread);
- this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE");
- this->AddDefinition("CMAKE_CURRENT_LIST_DIR",
- cmSystemTools::GetFilenamePath(filenametoread).c_str());
- this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR");
+ void Quiet() { this->ReportError = false; }
+private:
+ cmMakefile* Makefile;
+ bool ReportError;
+};
- // try to see if the list file is the top most
- // list file for a project, and if it is, then it
- // must have a project command. If there is not
- // one, then cmake will provide one via the
- // cmListFileCache class.
- bool requireProjectCommand = false;
- if(!external && this->cmStartDirectory == this->cmHomeDirectory)
- {
- if(cmSystemTools::LowerCase(
- cmSystemTools::GetFilenameName(filename)) == "cmakelists.txt")
- {
- requireProjectCommand = true;
- }
- }
+bool cmMakefile::ReadListFile(const char* filename)
+{
+ std::string filenametoread =
+ cmSystemTools::CollapseFullPath(filename,
+ this->GetCurrentSourceDirectory());
- // push the listfile onto the stack
- this->ListFileStack.push_back(filenametoread);
- if(fullPath!=0)
+ ListFileScope scope(this, filenametoread);
+
+ cmListFile listFile;
+ {
+ cmParseFileScope pfs(this);
+ if (!listFile.ParseFile(filenametoread.c_str(), false, this))
{
- *fullPath=filenametoread;
+ return false;
}
- cmListFile cacheFile;
- if( !cacheFile.ParseFile(filenametoread, requireProjectCommand, this) )
+ }
+
+ this->ReadListFile(listFile, filenametoread);
+ if(cmSystemTools::GetFatalErrorOccured())
{
- // pop the listfile off the stack
- this->ListFileStack.pop_back();
- if(fullPath!=0)
- {
- *fullPath = "";
- }
- this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str());
- this->MarkVariableAsUsed("CMAKE_PARENT_LIST_FILE");
- this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str());
- this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE");
- this->AddDefinition("CMAKE_CURRENT_LIST_DIR",
- cmSystemTools::GetFilenamePath(currentFile).c_str());
- this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR");
- return false;
+ scope.Quiet();
}
+ return true;
+}
+
+void cmMakefile::ReadListFile(cmListFile const& listFile,
+ std::string const& filenametoread)
+{
// add this list file to the list of dependencies
- this->ListFiles.push_back( filenametoread);
+ this->ListFiles.push_back(filenametoread);
- // Enforce balanced blocks (if/endif, function/endfunction, etc.).
- {
- LexicalPushPop lexScope(this);
- IncludeScope incScope(this, filenametoread, noPolicyScope);
+ std::string currentParentFile
+ = this->GetSafeDefinition("CMAKE_PARENT_LIST_FILE");
+ std::string currentFile
+ = this->GetSafeDefinition("CMAKE_CURRENT_LIST_FILE");
+
+ this->AddDefinition("CMAKE_CURRENT_LIST_FILE", filenametoread.c_str());
+ this->AddDefinition("CMAKE_CURRENT_LIST_DIR",
+ cmSystemTools::GetFilenamePath(filenametoread).c_str());
+
+ this->MarkVariableAsUsed("CMAKE_PARENT_LIST_FILE");
+ this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE");
+ this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR");
// Run the parsed commands.
- const size_t numberFunctions = cacheFile.Functions.size();
+ const size_t numberFunctions = listFile.Functions.size();
for(size_t i =0; i < numberFunctions; ++i)
{
cmExecutionStatus status;
- this->ExecuteCommand(cacheFile.Functions[i],status);
+ this->ExecuteCommand(listFile.Functions[i],status);
if(cmSystemTools::GetFatalErrorOccured())
{
- // Exit early due to error.
- lexScope.Quiet();
- incScope.Quiet();
break;
}
if(status.GetReturnInvoked())
@@ -709,39 +577,24 @@ bool cmMakefile::ReadListFile(const char* filename_in,
break;
}
}
- }
-
- // If this is the directory-level CMakeLists.txt file then perform
- // some extra checks.
- if(this->ListFileStack.size() == 1)
- {
- this->EnforceDirectoryLevelRules();
- }
+ this->CheckForUnusedVariables();
this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str());
- this->MarkVariableAsUsed("CMAKE_PARENT_LIST_FILE");
this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str());
- this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE");
this->AddDefinition("CMAKE_CURRENT_LIST_DIR",
cmSystemTools::GetFilenamePath(currentFile).c_str());
+ this->MarkVariableAsUsed("CMAKE_PARENT_LIST_FILE");
+ this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE");
this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR");
-
- // pop the listfile off the stack
- this->ListFileStack.pop_back();
-
- // Check for unused variables
- this->CheckForUnusedVariables();
-
- return true;
}
//----------------------------------------------------------------------------
-void cmMakefile::EnforceDirectoryLevelRules()
+void cmMakefile::EnforceDirectoryLevelRules() const
{
// Diagnose a violation of CMP0000 if necessary.
if(this->CheckCMP0000)
{
- cmOStringStream msg;
+ std::ostringstream msg;
msg << "No cmake_minimum_required command is present. "
<< "A line of code such as\n"
<< " cmake_minimum_required(VERSION "
@@ -758,7 +611,7 @@ void cmMakefile::EnforceDirectoryLevelRules()
case cmPolicies::WARN:
// Warn because the user did not provide a mimimum required
// version.
- this->IssueMessage(cmake::AUTHOR_WARNING, msg.str().c_str());
+ this->IssueMessage(cmake::AUTHOR_WARNING, msg.str());
case cmPolicies::OLD:
// OLD behavior is to use policy version 2.4 set in
// cmListFileCache.
@@ -767,55 +620,52 @@ void cmMakefile::EnforceDirectoryLevelRules()
case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
// NEW behavior is to issue an error.
- this->IssueMessage(cmake::FATAL_ERROR, msg.str().c_str());
+ this->IssueMessage(cmake::FATAL_ERROR, msg.str());
cmSystemTools::SetFatalErrorOccured();
return;
}
}
}
-void cmMakefile::AddCommand(cmCommand* wg)
+void cmMakefile::AddEvaluationFile(const std::string& inputFile,
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> outputName,
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> condition,
+ bool inputIsContent)
{
- this->GetCMakeInstance()->AddCommand(wg);
+ this->EvaluationFiles.push_back(
+ new cmGeneratorExpressionEvaluationFile(inputFile, outputName,
+ condition,
+ inputIsContent));
}
-// Set the make file
-void cmMakefile::SetLocalGenerator(cmLocalGenerator* lg)
+std::vector<cmGeneratorExpressionEvaluationFile*>
+cmMakefile::GetEvaluationFiles() const
{
- this->LocalGenerator = lg;
- // the source groups need to access the global generator
- // so don't create them until the lg is set
-#if defined(CMAKE_BUILD_WITH_CMAKE)
- this->AddSourceGroup("", "^.*$");
- this->AddSourceGroup
- ("Source Files",
- "\\.(C|M|c|c\\+\\+|cc|cpp|cxx|f|f90|for|fpp"
- "|ftn|m|mm|rc|def|r|odl|idl|hpj|bat)$");
- this->AddSourceGroup("Header Files", CM_HEADER_REGEX);
- this->AddSourceGroup("CMake Rules", "\\.rule$");
- this->AddSourceGroup("Resources", "\\.plist$");
- this->AddSourceGroup("Object Files", "\\.(lo|o|obj)$");
-#endif
+ return this->EvaluationFiles;
+}
- this->WarnUnused = this->GetCMakeInstance()->GetWarnUnused();
- this->CheckSystemVars = this->GetCMakeInstance()->GetCheckSystemVars();
+std::vector<cmExportBuildFileGenerator*>
+cmMakefile::GetExportBuildFileGenerators() const
+{
+ return this->ExportBuildFileGenerators;
}
-bool cmMakefile::NeedBackwardsCompatibility(unsigned int major,
- unsigned int minor,
- unsigned int patch)
+void cmMakefile::RemoveExportBuildFileGeneratorCMP0024(
+ cmExportBuildFileGenerator* gen)
{
- if(this->LocalGenerator)
+ std::vector<cmExportBuildFileGenerator*>::iterator it =
+ std::find(this->ExportBuildFileGenerators.begin(),
+ this->ExportBuildFileGenerators.end(), gen);
+ if(it != this->ExportBuildFileGenerators.end())
{
- return
- this->LocalGenerator->NeedBackwardsCompatibility(major, minor, patch);
- }
- else
- {
- return false;
+ this->ExportBuildFileGenerators.erase(it);
}
}
+void cmMakefile::AddExportBuildFileGenerator(cmExportBuildFileGenerator* gen)
+{
+ this->ExportBuildFileGenerators.push_back(gen);
+}
namespace
{
@@ -873,74 +723,158 @@ void cmMakefile::ConfigureFinalPass()
this->FinalPass();
const char* oldValue
= this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
- if (oldValue && atof(oldValue) <= 1.2)
- {
- cmSystemTools::Error("You have requested backwards compatibility "
- "with CMake version 1.2 or earlier. This version "
- "of CMake only supports backwards compatibility "
- "with CMake 1.4 or later. For compatibility with "
- "1.2 or earlier please use CMake 2.0");
- }
- for (cmTargets::iterator l = this->Targets.begin();
- l != this->Targets.end(); l++)
- {
- l->second.FinishConfigure();
+ if (oldValue && cmSystemTools::VersionCompare(
+ cmSystemTools::OP_LESS, oldValue, "2.4"))
+ {
+ this->IssueMessage(
+ cmake::FATAL_ERROR,
+ "You have set CMAKE_BACKWARDS_COMPATIBILITY to a CMake version less "
+ "than 2.4. This version of CMake only supports backwards compatibility "
+ "with CMake 2.4 or later. For compatibility with older versions please "
+ "use any CMake 2.8.x release or lower.");
+ }
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ // Do old-style link dependency analysis only for CM_USE_OLD_VS6.
+ if(this->GetGlobalGenerator()->IsForVS6())
+ {
+ for (cmTargets::iterator l = this->Targets.begin();
+ l != this->Targets.end(); l++)
+ {
+ if (l->second.GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ continue;
+ }
+ // Erase any cached link information that might have been comptued
+ // on-demand during the configuration. This ensures that build
+ // system generation uses up-to-date information even if other cache
+ // invalidation code in this source file is buggy.
+
+ l->second.AnalyzeLibDependenciesForVS6(*this);
+ }
}
+#endif
}
//----------------------------------------------------------------------------
void
-cmMakefile::AddCustomCommandToTarget(const char* target,
+cmMakefile::AddCustomCommandToTarget(const std::string& target,
+ const std::vector<std::string>& byproducts,
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines,
cmTarget::CustomCommandType type,
const char* comment,
const char* workingDir,
- bool escapeOldStyle)
+ bool escapeOldStyle,
+ bool uses_terminal)
{
// Find the target to which to add the custom command.
cmTargets::iterator ti = this->Targets.find(target);
- if(ti != this->Targets.end())
+
+ if(ti == this->Targets.end())
{
- if(ti->second.GetType() == cmTarget::OBJECT_LIBRARY)
+ cmake::MessageType messageType = cmake::AUTHOR_WARNING;
+ bool issueMessage = false;
+ std::ostringstream e;
+ switch(this->GetPolicyStatus(cmPolicies::CMP0040))
{
- cmOStringStream e;
- e << "Target \"" << target << "\" is an OBJECT library "
- "that may not have PRE_BUILD, PRE_LINK, or POST_BUILD commands.";
- this->IssueMessage(cmake::FATAL_ERROR, e.str());
- return;
+ case cmPolicies::WARN:
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0040) << "\n";
+ issueMessage = true;
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::NEW:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ issueMessage = true;
+ messageType = cmake::FATAL_ERROR;
}
- // Add the command to the appropriate build step for the target.
- std::vector<std::string> no_output;
- cmCustomCommand cc(this, no_output, depends,
- commandLines, comment, workingDir);
- cc.SetEscapeOldStyle(escapeOldStyle);
- cc.SetEscapeAllowMakeVars(true);
- switch(type)
+
+ if(issueMessage)
{
- case cmTarget::PRE_BUILD:
- ti->second.GetPreBuildCommands().push_back(cc);
- break;
- case cmTarget::PRE_LINK:
- ti->second.GetPreLinkCommands().push_back(cc);
- break;
- case cmTarget::POST_BUILD:
- ti->second.GetPostBuildCommands().push_back(cc);
- break;
+ if (cmTarget const* t = this->FindTargetToUse(target))
+ {
+ if (t->IsImported())
+ {
+ e << "TARGET '" << target
+ << "' is IMPORTED and does not build here.";
+ }
+ else
+ {
+ e << "TARGET '" << target
+ << "' was not created in this directory.";
+ }
+ }
+ else
+ {
+ e << "No TARGET '" << target
+ << "' has been created in this directory.";
+ }
+ IssueMessage(messageType, e.str());
}
+
+ return;
+ }
+
+ if(ti->second.GetType() == cmState::OBJECT_LIBRARY)
+ {
+ std::ostringstream e;
+ e << "Target \"" << target << "\" is an OBJECT library "
+ "that may not have PRE_BUILD, PRE_LINK, or POST_BUILD commands.";
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return;
+ }
+ if(ti->second.GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ std::ostringstream e;
+ e << "Target \"" << target << "\" is an INTERFACE library "
+ "that may not have PRE_BUILD, PRE_LINK, or POST_BUILD commands.";
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return;
+ }
+
+ // Always create the byproduct sources and mark them generated.
+ for(std::vector<std::string>::const_iterator o = byproducts.begin();
+ o != byproducts.end(); ++o)
+ {
+ if(cmSourceFile* out = this->GetOrCreateSource(*o, true))
+ {
+ out->SetProperty("GENERATED", "1");
+ }
+ }
+
+ // Add the command to the appropriate build step for the target.
+ std::vector<std::string> no_output;
+ cmCustomCommand cc(this, no_output, byproducts, depends,
+ commandLines, comment, workingDir);
+ cc.SetEscapeOldStyle(escapeOldStyle);
+ cc.SetEscapeAllowMakeVars(true);
+ cc.SetUsesTerminal(uses_terminal);
+ switch(type)
+ {
+ case cmTarget::PRE_BUILD:
+ ti->second.AddPreBuildCommand(cc);
+ break;
+ case cmTarget::PRE_LINK:
+ ti->second.AddPreLinkCommand(cc);
+ break;
+ case cmTarget::POST_BUILD:
+ ti->second.AddPostBuildCommand(cc);
+ break;
}
}
//----------------------------------------------------------------------------
cmSourceFile*
cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
+ const std::vector<std::string>& byproducts,
const std::vector<std::string>& depends,
- const char* main_dependency,
+ const std::string& main_dependency,
const cmCustomCommandLines& commandLines,
const char* comment,
const char* workingDir,
bool replace,
- bool escapeOldStyle)
+ bool escapeOldStyle,
+ bool uses_terminal)
{
// Make sure there is at least one output.
if(outputs.empty())
@@ -956,7 +890,7 @@ cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
cmCustomCommandLine const& cl = *i;
if(!cl.empty() && !cl[0].empty() && cl[0][0] == '"')
{
- cmOStringStream e;
+ std::ostringstream e;
e << "COMMAND may not contain literal quotes:\n " << cl[0] << "\n";
this->IssueMessage(cmake::FATAL_ERROR, e.str());
return 0;
@@ -965,7 +899,7 @@ cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
// Choose a source file on which to store the custom command.
cmSourceFile* file = 0;
- if(main_dependency && main_dependency[0])
+ if(!commandLines.empty() && !main_dependency.empty())
{
// The main dependency was specified. Use it unless a different
// custom command already used it.
@@ -986,24 +920,22 @@ cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
file = 0;
}
}
- else
+ else if (!file)
{
- // The main dependency does not have a custom command or we are
- // allowed to replace it. Use it to store the command.
- file = this->GetOrCreateSource(main_dependency);
+ file = this->CreateSource(main_dependency);
}
}
// Generate a rule file if the main dependency is not available.
if(!file)
{
- cmGlobalGenerator* gg = this->LocalGenerator->GetGlobalGenerator();
+ cmGlobalGenerator* gg = this->GetGlobalGenerator();
// Construct a rule file associated with the first output produced.
std::string outName = gg->GenerateRuleFile(outputs[0]);
// Check if the rule file already exists.
- file = this->GetSource(outName.c_str());
+ file = this->GetSource(outName);
if(file && file->GetCustomCommand() && !replace)
{
// The rule file already exists.
@@ -1017,7 +949,10 @@ cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
}
// Create a cmSourceFile for the rule file.
- file = this->GetOrCreateSource(outName.c_str(), true);
+ if (!file)
+ {
+ file = this->CreateSource(outName, true);
+ }
file->SetProperty("__CMAKE_RULE", "1");
}
@@ -1025,27 +960,36 @@ cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
for(std::vector<std::string>::const_iterator o = outputs.begin();
o != outputs.end(); ++o)
{
- if(cmSourceFile* out = this->GetOrCreateSource(o->c_str(), true))
+ if(cmSourceFile* out = this->GetOrCreateSource(*o, true))
{
out->SetProperty("GENERATED", "1");
}
}
-
- // Construct a complete list of dependencies.
- std::vector<std::string> depends2(depends);
- if(main_dependency && main_dependency[0])
+ for(std::vector<std::string>::const_iterator o = byproducts.begin();
+ o != byproducts.end(); ++o)
{
- depends2.push_back(main_dependency);
+ if(cmSourceFile* out = this->GetOrCreateSource(*o, true))
+ {
+ out->SetProperty("GENERATED", "1");
+ }
}
// Attach the custom command to the file.
if(file)
{
+ // Construct a complete list of dependencies.
+ std::vector<std::string> depends2(depends);
+ if(!main_dependency.empty())
+ {
+ depends2.push_back(main_dependency);
+ }
+
cmCustomCommand* cc =
- new cmCustomCommand(this, outputs, depends2, commandLines,
- comment, workingDir);
+ new cmCustomCommand(this, outputs, byproducts, depends2,
+ commandLines, comment, workingDir);
cc->SetEscapeOldStyle(escapeOldStyle);
cc->SetEscapeAllowMakeVars(true);
+ cc->SetUsesTerminal(uses_terminal);
file->SetCustomCommand(cc);
this->UpdateOutputToSourceMap(outputs, file);
}
@@ -1087,39 +1031,45 @@ cmMakefile::UpdateOutputToSourceMap(std::string const& output,
//----------------------------------------------------------------------------
cmSourceFile*
-cmMakefile::AddCustomCommandToOutput(const char* output,
+cmMakefile::AddCustomCommandToOutput(const std::string& output,
const std::vector<std::string>& depends,
- const char* main_dependency,
+ const std::string& main_dependency,
const cmCustomCommandLines& commandLines,
const char* comment,
const char* workingDir,
bool replace,
- bool escapeOldStyle)
+ bool escapeOldStyle,
+ bool uses_terminal)
{
std::vector<std::string> outputs;
outputs.push_back(output);
- return this->AddCustomCommandToOutput(outputs, depends, main_dependency,
+ std::vector<std::string> no_byproducts;
+ return this->AddCustomCommandToOutput(outputs, no_byproducts,
+ depends, main_dependency,
commandLines, comment, workingDir,
- replace, escapeOldStyle);
+ replace, escapeOldStyle,
+ uses_terminal);
}
//----------------------------------------------------------------------------
void
-cmMakefile::AddCustomCommandOldStyle(const char* target,
+cmMakefile::AddCustomCommandOldStyle(const std::string& target,
const std::vector<std::string>& outputs,
const std::vector<std::string>& depends,
- const char* source,
+ const std::string& source,
const cmCustomCommandLines& commandLines,
const char* comment)
{
// Translate the old-style signature to one of the new-style
// signatures.
- if(strcmp(source, target) == 0)
+ if(source == target)
{
// In the old-style signature if the source and target were the
// same then it added a post-build rule to the target. Preserve
// this behavior.
- this->AddCustomCommandToTarget(target, depends, commandLines,
+ std::vector<std::string> no_byproducts;
+ this->AddCustomCommandToTarget(target, no_byproducts,
+ depends, commandLines,
cmTarget::POST_BUILD, comment, 0);
return;
}
@@ -1145,7 +1095,7 @@ cmMakefile::AddCustomCommandOldStyle(const char* target,
else
{
// The source may not be a real file. Do not use a main dependency.
- const char* no_main_dependency = 0;
+ std::string no_main_dependency = "";
std::vector<std::string> depends2 = depends;
depends2.push_back(source);
sf = this->AddCustomCommandToOutput(output, depends2, no_main_dependency,
@@ -1159,12 +1109,13 @@ cmMakefile::AddCustomCommandOldStyle(const char* target,
{
if (this->Targets.find(target) != this->Targets.end())
{
- this->Targets[target].AddSourceFile(sf);
+ this->Targets[target].AddSource(sf->GetFullPath());
}
else
{
cmSystemTools::Error("Attempt to add a custom rule to a target "
- "that does not exist yet for target ", target);
+ "that does not exist yet for target ",
+ target.c_str());
return;
}
}
@@ -1172,15 +1123,16 @@ cmMakefile::AddCustomCommandOldStyle(const char* target,
}
//----------------------------------------------------------------------------
-void cmMakefile::AddUtilityCommand(const char* utilityName,
- bool excludeFromAll,
- const std::vector<std::string>& depends,
- const char* workingDirectory,
- const char* command,
- const char* arg1,
- const char* arg2,
- const char* arg3,
- const char* arg4)
+cmTarget*
+cmMakefile::AddUtilityCommand(const std::string& utilityName,
+ bool excludeFromAll,
+ const std::vector<std::string>& depends,
+ const char* workingDirectory,
+ const char* command,
+ const char* arg1,
+ const char* arg2,
+ const char* arg3,
+ const char* arg4)
{
// Construct the command line for the custom command.
cmCustomCommandLine commandLine;
@@ -1205,21 +1157,39 @@ void cmMakefile::AddUtilityCommand(const char* utilityName,
commandLines.push_back(commandLine);
// Call the real signature of this method.
- this->AddUtilityCommand(utilityName, excludeFromAll, workingDirectory,
- depends, commandLines);
+ return this->AddUtilityCommand(utilityName, excludeFromAll, workingDirectory,
+ depends, commandLines);
}
//----------------------------------------------------------------------------
cmTarget*
-cmMakefile::AddUtilityCommand(const char* utilityName,
+cmMakefile::AddUtilityCommand(const std::string& utilityName,
bool excludeFromAll,
const char* workingDirectory,
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines,
- bool escapeOldStyle, const char* comment)
+ bool escapeOldStyle, const char* comment,
+ bool uses_terminal)
+{
+ std::vector<std::string> no_byproducts;
+ return this->AddUtilityCommand(utilityName, excludeFromAll, workingDirectory,
+ no_byproducts, depends, commandLines,
+ escapeOldStyle, comment, uses_terminal);
+}
+
+//----------------------------------------------------------------------------
+cmTarget*
+cmMakefile::AddUtilityCommand(const std::string& utilityName,
+ bool excludeFromAll,
+ const char* workingDirectory,
+ const std::vector<std::string>& byproducts,
+ const std::vector<std::string>& depends,
+ const cmCustomCommandLines& commandLines,
+ bool escapeOldStyle, const char* comment,
+ bool uses_terminal)
{
// Create a target instance for this utility.
- cmTarget* target = this->AddNewTarget(cmTarget::UTILITY, utilityName);
+ cmTarget* target = this->AddNewTarget(cmState::UTILITY, utilityName);
if (excludeFromAll)
{
target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
@@ -1231,28 +1201,43 @@ cmMakefile::AddUtilityCommand(const char* utilityName,
}
// Store the custom command in the target.
- std::string force = this->GetStartOutputDirectory();
- force += cmake::GetCMakeFilesDirectory();
- force += "/";
- force += utilityName;
- const char* no_main_dependency = 0;
- bool no_replace = false;
- this->AddCustomCommandToOutput(force.c_str(), depends,
- no_main_dependency,
- commandLines, comment,
- workingDirectory, no_replace,
- escapeOldStyle);
- cmSourceFile* sf = target->AddSource(force.c_str());
-
- // The output is not actually created so mark it symbolic.
- if(sf)
- {
- sf->SetProperty("SYMBOLIC", "1");
- }
- else
- {
- cmSystemTools::Error("Could not get source file entry for ",
- force.c_str());
+ if (!commandLines.empty() || !depends.empty())
+ {
+ std::string force = this->GetCurrentBinaryDirectory();
+ force += cmake::GetCMakeFilesDirectory();
+ force += "/";
+ force += utilityName;
+ std::vector<std::string> forced;
+ forced.push_back(force);
+ std::string no_main_dependency = "";
+ bool no_replace = false;
+ this->AddCustomCommandToOutput(forced, byproducts,
+ depends, no_main_dependency,
+ commandLines, comment,
+ workingDirectory, no_replace,
+ escapeOldStyle, uses_terminal);
+ cmSourceFile* sf = target->AddSourceCMP0049(force);
+
+ // The output is not actually created so mark it symbolic.
+ if(sf)
+ {
+ sf->SetProperty("SYMBOLIC", "1");
+ }
+ else
+ {
+ cmSystemTools::Error("Could not get source file entry for ",
+ force.c_str());
+ }
+
+ // Always create the byproduct sources and mark them generated.
+ for(std::vector<std::string>::const_iterator o = byproducts.begin();
+ o != byproducts.end(); ++o)
+ {
+ if(cmSourceFile* out = this->GetOrCreateSource(*o, true))
+ {
+ out->SetProperty("GENERATED", "1");
+ }
+ }
}
return target;
}
@@ -1280,22 +1265,11 @@ void cmMakefile::AddDefineFlag(const char* flag)
void cmMakefile::AddDefineFlag(const char* flag, std::string& dflags)
{
// remove any \n\r
- std::string ret = flag;
- std::string::size_type pos = 0;
- while((pos = ret.find('\n', pos)) != std::string::npos)
- {
- ret[pos] = ' ';
- pos++;
- }
- pos = 0;
- while((pos = ret.find('\r', pos)) != std::string::npos)
- {
- ret[pos] = ' ';
- pos++;
- }
-
- dflags += " ";
- dflags += ret;
+ std::string::size_type initSize = dflags.size();
+ dflags += std::string(" ") + flag;
+ std::string::iterator flagStart = dflags.begin() + initSize + 1;
+ std::replace(flagStart, dflags.end(), '\n', ' ');
+ std::replace(flagStart, dflags.end(), '\r', ' ');
}
@@ -1362,8 +1336,7 @@ bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove)
// VS6 IDE does not support definition values with spaces in
// combination with '"', '$', or ';'.
- if((strcmp(this->LocalGenerator->GetGlobalGenerator()->GetName(),
- "Visual Studio 6") == 0) &&
+ if((this->GetGlobalGenerator()->GetName() == "Visual Studio 6") &&
(def.find(" ") != def.npos && def.find_first_of("\"$;") != def.npos))
{
return false;
@@ -1380,7 +1353,7 @@ bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove)
case cmPolicies::WARN:
this->IssueMessage(
cmake::AUTHOR_WARNING,
- this->GetPolicies()->GetPolicyWarning(cmPolicies::CMP0005)
+ cmPolicies::GetPolicyWarning(cmPolicies::CMP0005)
);
case cmPolicies::OLD:
// OLD behavior is to not escape the value. We should not
@@ -1390,7 +1363,7 @@ bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove)
case cmPolicies::REQUIRED_ALWAYS:
this->IssueMessage(
cmake::FATAL_ERROR,
- this->GetPolicies()->GetRequiredPolicyError(cmPolicies::CMP0005)
+ cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0005)
);
return false;
case cmPolicies::NEW:
@@ -1412,18 +1385,11 @@ bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove)
cmSystemTools::ExpandListArgument(cdefs, defs);
// Recompose the list without the definition.
- std::string ndefs;
- const char* sep = "";
- for(std::vector<std::string>::const_iterator di = defs.begin();
- di != defs.end(); ++di)
- {
- if(*di != define)
- {
- ndefs += sep;
- sep = ";";
- ndefs += *di;
- }
- }
+ std::vector<std::string>::const_iterator defEnd =
+ std::remove(defs.begin(), defs.end(), define);
+ std::vector<std::string>::const_iterator defBegin =
+ defs.begin();
+ std::string ndefs = cmJoin(cmMakeRange(defBegin, defEnd), ";");
// Store the new list.
this->SetProperty("COMPILE_DEFINITIONS", ndefs.c_str());
@@ -1438,8 +1404,8 @@ bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove)
return true;
}
-void cmMakefile::AddLinkLibrary(const char* lib,
- cmTarget::LinkLibraryType llt)
+void cmMakefile::AddLinkLibrary(const std::string& lib,
+ cmTargetLinkLibraryType llt)
{
cmTarget::LibraryID tmp;
tmp.first = lib;
@@ -1447,74 +1413,55 @@ void cmMakefile::AddLinkLibrary(const char* lib,
this->LinkLibraries.push_back(tmp);
}
-void cmMakefile::AddLinkLibraryForTarget(const char *target,
- const char* lib,
- cmTarget::LinkLibraryType llt)
+void cmMakefile::AddLinkLibraryForTarget(const std::string& target,
+ const std::string& lib,
+ cmTargetLinkLibraryType llt)
{
cmTargets::iterator i = this->Targets.find(target);
if ( i != this->Targets.end())
{
- cmTarget* tgt =
- this->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(0,lib);
+ cmTarget* tgt = this->GetGlobalGenerator()->FindTarget(lib);
if(tgt)
{
- // CMake versions below 2.4 allowed linking to modules.
- bool allowModules = this->NeedBackwardsCompatibility(2,2);
// if it is not a static or shared library then you can not link to it
- if(!((tgt->GetType() == cmTarget::STATIC_LIBRARY) ||
- (tgt->GetType() == cmTarget::SHARED_LIBRARY) ||
+ if(!((tgt->GetType() == cmState::STATIC_LIBRARY) ||
+ (tgt->GetType() == cmState::SHARED_LIBRARY) ||
+ (tgt->GetType() == cmState::INTERFACE_LIBRARY) ||
tgt->IsExecutableWithExports()))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Target \"" << lib << "\" of type "
- << cmTarget::GetTargetTypeName(tgt->GetType())
+ << cmState::GetTargetTypeName(tgt->GetType())
<< " may not be linked into another target. "
<< "One may link only to STATIC or SHARED libraries, or "
<< "to executables with the ENABLE_EXPORTS property set.";
- // in older versions of cmake linking to modules was allowed
- if( tgt->GetType() == cmTarget::MODULE_LIBRARY )
- {
- e << "\n"
- << "If you are developing a new project, re-organize it to avoid "
- << "linking to modules. "
- << "If you are just trying to build an existing project, "
- << "set CMAKE_BACKWARDS_COMPATIBILITY to 2.2 or lower to allow "
- << "linking to modules.";
- }
- // if no modules are allowed then this is always an error
- if(!allowModules ||
- // if we allow modules but the type is not a module then it is
- // still an error
- (allowModules && tgt->GetType() != cmTarget::MODULE_LIBRARY))
- {
- this->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
- }
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
}
}
i->second.AddLinkLibrary( *this, target, lib, llt );
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Attempt to add link library \""
<< lib << "\" to target \""
<< target << "\" which is not built in this directory.";
- this->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
}
}
-void cmMakefile::AddLinkDirectoryForTarget(const char *target,
- const char* d)
+void cmMakefile::AddLinkDirectoryForTarget(const std::string& target,
+ const std::string& d)
{
cmTargets::iterator i = this->Targets.find(target);
if ( i != this->Targets.end())
{
if(this->IsAlias(target))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "ALIAS target \"" << target << "\" "
<< "may not be linked into another target.";
- this->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
i->second.AddLinkDirectory( d );
@@ -1523,74 +1470,17 @@ void cmMakefile::AddLinkDirectoryForTarget(const char *target,
{
cmSystemTools::Error
("Attempt to add link directories to non-existent target: ",
- target, " for directory ", d);
+ target.c_str(), " for directory ", d.c_str());
}
}
-void cmMakefile::AddLinkLibrary(const char* lib)
-{
- this->AddLinkLibrary(lib,cmTarget::GENERAL);
-}
-
-void cmMakefile::AddLinkDirectory(const char* dir)
+void cmMakefile::AddLinkLibrary(const std::string& lib)
{
- // Don't add a link directory that is already present. Yes, this
- // linear search results in n^2 behavior, but n won't be getting
- // much bigger than 20. We cannot use a set because of order
- // dependency of the link search path.
-
- if(!dir)
- {
- return;
- }
- // remove trailing slashes
- if(dir[strlen(dir)-1] == '/')
- {
- std::string newdir = dir;
- newdir = newdir.substr(0, newdir.size()-1);
- if(std::find(this->LinkDirectories.begin(),
- this->LinkDirectories.end(),
- newdir.c_str()) == this->LinkDirectories.end())
- {
- this->LinkDirectories.push_back(newdir);
- }
- }
- else
- {
- if(std::find(this->LinkDirectories.begin(),
- this->LinkDirectories.end(), dir)
- == this->LinkDirectories.end())
- {
- this->LinkDirectories.push_back(dir);
- }
- }
+ this->AddLinkLibrary(lib,GENERAL_LibraryType);
}
-void cmMakefile::InitializeFromParent()
+void cmMakefile::InitializeFromParent(cmMakefile* parent)
{
- cmMakefile *parent = this->LocalGenerator->GetParent()->GetMakefile();
-
- // Initialize definitions with the closure of the parent scope.
- this->Internal->VarStack.top() = parent->Internal->VarStack.top().Closure();
-
- const std::vector<cmValueWithOrigin> parentIncludes =
- parent->GetIncludeDirectoriesEntries();
- this->IncludeDirectoriesEntries.insert(this->IncludeDirectoriesEntries.end(),
- parentIncludes.begin(),
- parentIncludes.end());
-
- const std::vector<cmValueWithOrigin> parentOptions =
- parent->GetCompileOptionsEntries();
- this->CompileOptionsEntries.insert(this->CompileOptionsEntries.end(),
- parentOptions.begin(),
- parentOptions.end());
-
- const std::vector<cmValueWithOrigin> parentDefines =
- parent->GetCompileDefinitionsEntries();
- this->CompileDefinitionsEntries.insert(this->CompileDefinitionsEntries.end(),
- parentDefines.begin(),
- parentDefines.end());
-
this->SystemIncludeDirectories = parent->SystemIncludeDirectories;
// define flags
@@ -1604,88 +1494,251 @@ void cmMakefile::InitializeFromParent()
}
// compile definitions property and per-config versions
- {
- this->SetProperty("COMPILE_DEFINITIONS",
- parent->GetProperty("COMPILE_DEFINITIONS"));
- std::vector<std::string> configs;
- this->GetConfigurations(configs);
- for(std::vector<std::string>::const_iterator ci = configs.begin();
- ci != configs.end(); ++ci)
- {
- std::string defPropName = "COMPILE_DEFINITIONS_";
- defPropName += cmSystemTools::UpperCase(*ci);
- this->SetProperty(defPropName.c_str(),
- parent->GetProperty(defPropName.c_str()));
+ cmPolicies::PolicyStatus polSt = this->GetPolicyStatus(cmPolicies::CMP0043);
+ if (polSt == cmPolicies::WARN || polSt == cmPolicies::OLD)
+ {
+ this->SetProperty("COMPILE_DEFINITIONS",
+ parent->GetProperty("COMPILE_DEFINITIONS"));
+ std::vector<std::string> configs;
+ this->GetConfigurations(configs);
+ for(std::vector<std::string>::const_iterator ci = configs.begin();
+ ci != configs.end(); ++ci)
+ {
+ std::string defPropName = "COMPILE_DEFINITIONS_";
+ defPropName += cmSystemTools::UpperCase(*ci);
+ const char* prop = parent->GetProperty(defPropName);
+ this->SetProperty(defPropName, prop);
+ }
}
- }
// link libraries
this->LinkLibraries = parent->LinkLibraries;
// link directories
- this->LinkDirectories = parent->LinkDirectories;
+ this->SetProperty("LINK_DIRECTORIES",
+ parent->GetProperty("LINK_DIRECTORIES"));
// the initial project name
- this->ProjectName = parent->ProjectName;
+ this->StateSnapshot.SetProjectName(parent->StateSnapshot.GetProjectName());
// Copy include regular expressions.
- this->IncludeFileRegularExpression = parent->IncludeFileRegularExpression;
this->ComplainFileRegularExpression = parent->ComplainFileRegularExpression;
// Imported targets.
this->ImportedTargets = parent->ImportedTargets;
}
-void cmMakefile::ConfigureSubDirectory(cmLocalGenerator *lg2)
+void cmMakefile::PushFunctionScope(std::string const& fileName,
+ const cmPolicies::PolicyMap& pm)
{
- // copy our variables from the child makefile
- lg2->GetMakefile()->InitializeFromParent();
- lg2->GetMakefile()->MakeStartDirectoriesCurrent();
- if (this->GetCMakeInstance()->GetDebugOutput())
+ this->StateSnapshot =
+ this->GetState()->CreateFunctionCallSnapshot(
+ this->StateSnapshot,
+ this->ContextStack.back()->Name, this->ContextStack.back()->Line,
+ fileName);
+ assert(this->StateSnapshot.IsValid());
+
+ this->PushLoopBlockBarrier();
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ this->GetGlobalGenerator()->GetFileLockPool().PushFunctionScope();
+#endif
+
+ this->PushFunctionBlockerBarrier();
+
+ this->PushPolicy(true, pm);
+}
+
+void cmMakefile::PopFunctionScope(bool reportError)
+{
+ this->PopPolicy();
+
+ this->PopSnapshot(reportError);
+
+ this->PopFunctionBlockerBarrier(reportError);
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ this->GetGlobalGenerator()->GetFileLockPool().PopFunctionScope();
+#endif
+
+ this->PopLoopBlockBarrier();
+
+ this->CheckForUnusedVariables();
+}
+
+void cmMakefile::PushMacroScope(std::string const& fileName,
+ const cmPolicies::PolicyMap& pm)
+{
+ this->StateSnapshot =
+ this->GetState()->CreateMacroCallSnapshot(
+ this->StateSnapshot,
+ this->ContextStack.back()->Name, this->ContextStack.back()->Line,
+ fileName);
+ assert(this->StateSnapshot.IsValid());
+
+ this->PushFunctionBlockerBarrier();
+
+ this->PushPolicy(true, pm);
+}
+
+void cmMakefile::PopMacroScope(bool reportError)
+{
+ this->PopPolicy();
+ this->PopSnapshot(reportError);
+
+ this->PopFunctionBlockerBarrier(reportError);
+}
+
+bool cmMakefile::IsRootMakefile() const
+{
+ return !this->StateSnapshot.GetBuildsystemDirectoryParent().IsValid();
+}
+
+class cmMakefile::BuildsystemFileScope
+{
+public:
+ BuildsystemFileScope(cmMakefile* mf)
+ : Makefile(mf), ReportError(true)
+ {
+ std::string currentStart =
+ this->Makefile->StateSnapshot.GetDirectory().GetCurrentSource();
+ currentStart += "/CMakeLists.txt";
+ this->Makefile->StateSnapshot.SetListFile(currentStart);
+ this->Makefile->StateSnapshot = this->Makefile->StateSnapshot.GetState()
+ ->CreatePolicyScopeSnapshot(this->Makefile->StateSnapshot);
+ this->Makefile->PushFunctionBlockerBarrier();
+
+ this->GG = mf->GetGlobalGenerator();
+ this->CurrentMakefile = this->GG->GetCurrentMakefile();
+ this->Snapshot = this->GG->GetCMakeInstance()->GetCurrentSnapshot();
+ this->GG->GetCMakeInstance()->SetCurrentSnapshot(this->Snapshot);
+ this->GG->SetCurrentMakefile(mf);
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ this->GG->GetFileLockPool().PushFileScope();
+#endif
+ }
+
+ ~BuildsystemFileScope()
+ {
+ this->Makefile->PopFunctionBlockerBarrier(this->ReportError);
+ this->Makefile->PopSnapshot(this->ReportError);
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ this->GG->GetFileLockPool().PopFileScope();
+#endif
+ this->GG->SetCurrentMakefile(this->CurrentMakefile);
+ this->GG->GetCMakeInstance()->SetCurrentSnapshot(this->Snapshot);
+ }
+
+ void Quiet() { this->ReportError = false; }
+private:
+ cmMakefile* Makefile;
+ cmGlobalGenerator* GG;
+ cmMakefile* CurrentMakefile;
+ cmState::Snapshot Snapshot;
+ bool ReportError;
+};
+
+//----------------------------------------------------------------------------
+void cmMakefile::Configure()
+{
+ BuildsystemFileScope scope(this);
+
+ // make sure the CMakeFiles dir is there
+ std::string filesDir = this->StateSnapshot.GetDirectory().GetCurrentBinary();
+ filesDir += cmake::GetCMakeFilesDirectory();
+ cmSystemTools::MakeDirectory(filesDir.c_str());
+
+ std::string currentStart =
+ this->StateSnapshot.GetDirectory().GetCurrentSource();
+ currentStart += "/CMakeLists.txt";
+ assert(cmSystemTools::FileExists(currentStart.c_str(), true));
+ this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentStart.c_str());
+
+ cmListFile listFile;
+ {
+ cmParseFileScope pfs(this);
+ if (!listFile.ParseFile(currentStart.c_str(), this->IsRootMakefile(), this))
{
- std::string msg=" Entering ";
- msg += lg2->GetMakefile()->GetCurrentDirectory();
- cmSystemTools::Message(msg.c_str());
+ return;
}
- // finally configure the subdir
- lg2->Configure();
- if (this->GetCMakeInstance()->GetDebugOutput())
+ }
+ this->ReadListFile(listFile, currentStart);
+ if(cmSystemTools::GetFatalErrorOccured())
{
- std::string msg=" Returning to ";
- msg += this->GetCurrentDirectory();
- cmSystemTools::Message(msg.c_str());
+ scope.Quiet();
+ }
+
+ // at the end handle any old style subdirs
+ std::vector<cmMakefile*> subdirs = this->UnConfiguredDirectories;
+
+ // for each subdir recurse
+ std::vector<cmMakefile*>::iterator sdi = subdirs.begin();
+ for (; sdi != subdirs.end(); ++sdi)
+ {
+ (*sdi)->StateSnapshot.InitializeFromParent_ForSubdirsCommand();
+ this->ConfigureSubDirectory(*sdi);
}
+
+ this->AddCMakeDependFilesFromUser();
}
-void cmMakefile::AddSubDirectory(const char* sub,
- bool excludeFromAll, bool preorder)
+void cmMakefile::ConfigureSubDirectory(cmMakefile *mf)
{
- // the source path must be made full if it isn't already
- std::string srcPath = sub;
- if (!cmSystemTools::FileIsFullPath(srcPath.c_str()))
+ mf->InitializeFromParent(this);
+ std::string currentStart = mf->GetCurrentSourceDirectory();
+ if (this->GetCMakeInstance()->GetDebugOutput())
{
- srcPath = this->GetCurrentDirectory();
- srcPath += "/";
- srcPath += sub;
+ std::string msg=" Entering ";
+ msg += currentStart;
+ cmSystemTools::Message(msg.c_str());
}
- // binary path must be made full if it isn't already
- std::string binPath = sub;
- if (!cmSystemTools::FileIsFullPath(binPath.c_str()))
+ std::string const currentStartFile = currentStart + "/CMakeLists.txt";
+ if (!cmSystemTools::FileExists(currentStartFile, true))
{
- binPath = this->GetCurrentOutputDirectory();
- binPath += "/";
- binPath += sub;
+ // The file is missing. Check policy CMP0014.
+ std::ostringstream e;
+ e << "The source directory\n"
+ << " " << currentStart << "\n"
+ << "does not contain a CMakeLists.txt file.";
+ switch (this->GetPolicyStatus(cmPolicies::CMP0014))
+ {
+ case cmPolicies::WARN:
+ // Print the warning.
+ e << "\n"
+ << "CMake does not support this case but it used "
+ << "to work accidentally and is being allowed for "
+ << "compatibility."
+ << "\n"
+ << cmPolicies::GetPolicyWarning(cmPolicies::CMP0014);
+ this->IssueMessage(cmake::AUTHOR_WARNING, e.str());
+ case cmPolicies::OLD:
+ // OLD behavior does not warn.
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ e << "\n"
+ << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0014);
+ case cmPolicies::NEW:
+ // NEW behavior prints the error.
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
+ }
+ return;
}
+ // finally configure the subdir
+ mf->Configure();
-
- this->AddSubDirectory(srcPath.c_str(), binPath.c_str(),
- excludeFromAll, preorder, false);
+ if (this->GetCMakeInstance()->GetDebugOutput())
+ {
+ std::string msg=" Returning to ";
+ msg += this->GetCurrentSourceDirectory();
+ cmSystemTools::Message(msg.c_str());
+ }
}
-
-void cmMakefile::AddSubDirectory(const char* srcPath, const char *binPath,
- bool excludeFromAll, bool preorder,
+void cmMakefile::AddSubDirectory(const std::string& srcPath,
+ const std::string& binPath,
+ bool excludeFromAll,
bool immediate)
{
// Make sure the binary directory is unique.
@@ -1694,27 +1747,56 @@ void cmMakefile::AddSubDirectory(const char* srcPath, const char *binPath,
return;
}
- // create a new local generator and set its parent
- cmLocalGenerator *lg2 =
- this->LocalGenerator->GetGlobalGenerator()->CreateLocalGenerator();
- lg2->SetParent(this->LocalGenerator);
- this->LocalGenerator->GetGlobalGenerator()->AddLocalGenerator(lg2);
+ cmState::Snapshot newSnapshot = this->GetState()
+ ->CreateBuildsystemDirectorySnapshot(this->StateSnapshot,
+ this->ContextStack.back()->Name,
+ this->ContextStack.back()->Line);
+
+ newSnapshot.GetDirectory().SetCurrentSource(srcPath);
+ newSnapshot.GetDirectory().SetCurrentBinary(binPath);
+
+ cmSystemTools::MakeDirectory(binPath.c_str());
+
+ cmMakefile* subMf = new cmMakefile(this->GlobalGenerator, newSnapshot);
+ this->GetGlobalGenerator()->AddMakefile(subMf);
- // set the subdirs start dirs
- lg2->GetMakefile()->SetStartDirectory(srcPath);
- lg2->GetMakefile()->SetStartOutputDirectory(binPath);
if(excludeFromAll)
{
- lg2->GetMakefile()->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
+ subMf->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
}
- lg2->GetMakefile()->SetPreOrder(preorder);
if (immediate)
{
- this->ConfigureSubDirectory(lg2);
+ this->ConfigureSubDirectory(subMf);
+ }
+ else
+ {
+ this->UnConfiguredDirectories.push_back(subMf);
}
}
+const char* cmMakefile::GetCurrentSourceDirectory() const
+{
+ return this->StateSnapshot.GetDirectory().GetCurrentSource();
+}
+
+const char* cmMakefile::GetCurrentBinaryDirectory() const
+{
+ return this->StateSnapshot.GetDirectory().GetCurrentBinary();
+}
+
+std::vector<cmTarget*> cmMakefile::GetImportedTargets() const
+{
+ std::vector<cmTarget*> tgts;
+ tgts.reserve(this->ImportedTargets.size());
+ for (TargetMap::const_iterator it = this->ImportedTargets.begin();
+ it != this->ImportedTargets.end(); ++it)
+ {
+ tgts.push_back(it->second);
+ }
+ return tgts;
+}
+
//----------------------------------------------------------------------------
void cmMakefile::AddIncludeDirectories(const std::vector<std::string> &incs,
bool before)
@@ -1724,43 +1806,33 @@ void cmMakefile::AddIncludeDirectories(const std::vector<std::string> &incs,
return;
}
- std::string incString;
- std::string sep;
-
- for(std::vector<std::string>::const_iterator li = incs.begin();
- li != incs.end(); ++li)
+ cmListFileBacktrace lfbt = this->GetBacktrace();
+ std::string entryString = cmJoin(incs, ";");
+ if (before)
{
- incString += sep + *li;
- sep = ";";
+ this->StateSnapshot.GetDirectory()
+ .PrependIncludeDirectoriesEntry(entryString, lfbt);
+ }
+ else
+ {
+ this->StateSnapshot.GetDirectory()
+ .AppendIncludeDirectoriesEntry(entryString, lfbt);
}
-
- std::vector<cmValueWithOrigin>::iterator position =
- before ? this->IncludeDirectoriesEntries.begin()
- : this->IncludeDirectoriesEntries.end();
-
- cmListFileBacktrace lfbt;
- this->GetBacktrace(lfbt);
- cmValueWithOrigin entry(incString, lfbt);
- this->IncludeDirectoriesEntries.insert(position, entry);
// Property on each target:
for (cmTargets::iterator l = this->Targets.begin();
l != this->Targets.end(); ++l)
{
cmTarget &t = l->second;
- t.InsertInclude(entry, before);
+ t.InsertInclude(entryString, lfbt, before);
}
}
//----------------------------------------------------------------------------
void
-cmMakefile::AddSystemIncludeDirectories(const std::set<cmStdString> &incs)
+cmMakefile::AddSystemIncludeDirectories(const std::set<std::string> &incs)
{
- for(std::set<cmStdString>::const_iterator li = incs.begin();
- li != incs.end(); ++li)
- {
- this->SystemIncludeDirectories.insert(*li);
- }
+ this->SystemIncludeDirectories.insert(incs.begin(), incs.end());
for (cmTargets::iterator l = this->Targets.begin();
l != this->Targets.end(); ++l)
@@ -1770,29 +1842,18 @@ cmMakefile::AddSystemIncludeDirectories(const std::set<cmStdString> &incs)
}
}
-void cmMakefile::AddDefinition(const char* name, const char* value)
+void cmMakefile::AddDefinition(const std::string& name, const char* value)
{
if (!value )
{
return;
}
-#ifdef CMAKE_STRICT
- if (this->GetCMakeInstance())
+ if (this->VariableInitialized(name))
{
- this->GetCMakeInstance()->
- RecordPropertyAccess(name,cmProperty::VARIABLE);
+ this->LogUnused("changing definition", name);
}
-#endif
-
- this->Internal->VarStack.top().Set(name, value);
- if (this->Internal->VarUsageStack.size() &&
- this->VariableInitialized(name))
- {
- this->CheckForUnused("changing definition", name);
- this->Internal->VarUsageStack.top().erase(name);
- }
- this->Internal->VarInitStack.top().insert(name);
+ this->StateSnapshot.SetDefinition(name, value);
#ifdef CMAKE_BUILD_WITH_CMAKE
cmVariableWatch* vv = this->GetVariableWatch();
@@ -1807,24 +1868,27 @@ void cmMakefile::AddDefinition(const char* name, const char* value)
}
-void cmMakefile::AddCacheDefinition(const char* name, const char* value,
+void cmMakefile::AddCacheDefinition(const std::string& name, const char* value,
const char* doc,
- cmCacheManager::CacheEntryType type,
+ cmState::CacheEntryType type,
bool force)
{
- const char* val = value;
- cmCacheManager::CacheIterator it =
- this->GetCacheManager()->GetCacheIterator(name);
- if(!it.IsAtEnd() && (it.GetType() == cmCacheManager::UNINITIALIZED) &&
- it.Initialized())
+ bool haveVal = value ? true : false;
+ std::string val = haveVal ? value : "";
+ const char* existingValue =
+ this->GetState()->GetInitializedCacheValue(name);
+ if(existingValue
+ && (this->GetState()->GetCacheEntryType(name)
+ == cmState::UNINITIALIZED))
{
// if this is not a force, then use the value from the cache
// if it is a force, then use the value being passed in
if(!force)
{
- val = it.GetValue();
+ val = existingValue;
+ haveVal = true;
}
- if ( type == cmCacheManager::PATH || type == cmCacheManager::FILEPATH )
+ if ( type == cmState::PATH || type == cmState::FILEPATH )
{
std::vector<std::string>::size_type cc;
std::vector<std::string> files;
@@ -1834,7 +1898,7 @@ void cmMakefile::AddCacheDefinition(const char* name, const char* value,
{
if(!cmSystemTools::IsOff(files[cc].c_str()))
{
- files[cc] = cmSystemTools::CollapseFullPath(files[cc].c_str());
+ files[cc] = cmSystemTools::CollapseFullPath(files[cc]);
}
if ( cc > 0 )
{
@@ -1843,27 +1907,28 @@ void cmMakefile::AddCacheDefinition(const char* name, const char* value,
nvalue += files[cc];
}
- this->GetCacheManager()->AddCacheEntry(name, nvalue.c_str(), doc, type);
- val = it.GetValue();
+ this->GetCMakeInstance()->AddCacheEntry(name, nvalue.c_str(), doc, type);
+ val = this->GetState()->GetInitializedCacheValue(name);
+ haveVal = true;
}
}
- this->GetCacheManager()->AddCacheEntry(name, val, doc, type);
+ this->GetCMakeInstance()->AddCacheEntry(name, haveVal ? val.c_str() : 0,
+ doc, type);
// if there was a definition then remove it
- this->Internal->VarStack.top().Set(name, 0);
+ this->StateSnapshot.RemoveDefinition(name);
}
-void cmMakefile::AddDefinition(const char* name, bool value)
+void cmMakefile::AddDefinition(const std::string& name, bool value)
{
- this->Internal->VarStack.top().Set(name, value? "ON" : "OFF");
- if (this->Internal->VarUsageStack.size() &&
- this->VariableInitialized(name))
+ if (this->VariableInitialized(name))
{
- this->CheckForUnused("changing definition", name);
- this->Internal->VarUsageStack.top().erase(name);
+ this->LogUnused("changing definition", name);
}
- this->Internal->VarInitStack.top().insert(name);
+
+ this->StateSnapshot.SetDefinition(name, value ? "ON" : "OFF");
+
#ifdef CMAKE_BUILD_WITH_CMAKE
cmVariableWatch* vv = this->GetVariableWatch();
if ( vv )
@@ -1880,88 +1945,70 @@ void cmMakefile::CheckForUnusedVariables() const
{
return;
}
- const cmDefinitions& defs = this->Internal->VarStack.top();
- const std::set<cmStdString>& locals = defs.LocalKeys();
- std::set<cmStdString>::const_iterator it = locals.begin();
- for (; it != locals.end(); ++it)
+ const std::vector<std::string>& unused = this->StateSnapshot.UnusedKeys();
+ std::vector<std::string>::const_iterator it = unused.begin();
+ for (; it != unused.end(); ++it)
{
- this->CheckForUnused("out of scope", it->c_str());
+ this->LogUnused("out of scope", *it);
}
}
-void cmMakefile::MarkVariableAsUsed(const char* var)
+void cmMakefile::MarkVariableAsUsed(const std::string& var)
{
- this->Internal->VarUsageStack.top().insert(var);
-}
-
-bool cmMakefile::VariableInitialized(const char* var) const
-{
- if(this->Internal->VarInitStack.top().find(var) !=
- this->Internal->VarInitStack.top().end())
- {
- return true;
- }
- return false;
+ this->StateSnapshot.GetDefinition(var);
}
-bool cmMakefile::VariableUsed(const char* var) const
+bool cmMakefile::VariableInitialized(const std::string& var) const
{
- if(this->Internal->VarUsageStack.top().find(var) !=
- this->Internal->VarUsageStack.top().end())
- {
- return true;
- }
- return false;
+ return this->StateSnapshot.IsInitialized(var);
}
-void cmMakefile::CheckForUnused(const char* reason, const char* name) const
+void cmMakefile::LogUnused(const char* reason,
+ const std::string& name) const
{
- if (this->WarnUnused && !this->VariableUsed(name))
+ if (this->WarnUnused)
{
- cmStdString path;
- cmListFileBacktrace bt;
- if (this->CallStack.size())
+ std::string path;
+ cmListFileContext lfc;
+ if (!this->ExecutionStatusStack.empty())
{
- const cmListFileContext* file = this->CallStack.back().Context;
- bt.push_back(*file);
- path = file->FilePath.c_str();
+ lfc = this->GetExecutionContext();
+ path = lfc.FilePath;
}
else
{
- path = this->GetStartDirectory();
+ path = this->GetCurrentSourceDirectory();
path += "/CMakeLists.txt";
- cmListFileContext lfc;
lfc.FilePath = path;
lfc.Line = 0;
- bt.push_back(lfc);
}
+ cmOutputConverter converter(this->StateSnapshot);
+ lfc.FilePath = converter.Convert(lfc.FilePath, cmOutputConverter::HOME);
+
if (this->CheckSystemVars ||
- cmSystemTools::IsSubDirectory(path.c_str(),
+ cmSystemTools::IsSubDirectory(path,
this->GetHomeDirectory()) ||
- (cmSystemTools::IsSubDirectory(path.c_str(),
+ (cmSystemTools::IsSubDirectory(path,
this->GetHomeOutputDirectory()) &&
- !cmSystemTools::IsSubDirectory(path.c_str(),
+ !cmSystemTools::IsSubDirectory(path,
cmake::GetCMakeFilesDirectory())))
{
- cmOStringStream msg;
+ std::ostringstream msg;
msg << "unused variable (" << reason << ") \'" << name << "\'";
this->GetCMakeInstance()->IssueMessage(cmake::AUTHOR_WARNING,
- msg.str().c_str(),
- bt);
+ msg.str(),
+ lfc);
}
}
}
-void cmMakefile::RemoveDefinition(const char* name)
+void cmMakefile::RemoveDefinition(const std::string& name)
{
- this->Internal->VarStack.top().Set(name, 0);
- if (this->Internal->VarUsageStack.size() &&
- this->VariableInitialized(name))
+ if (this->VariableInitialized(name))
{
- this->CheckForUnused("unsetting", name);
- this->Internal->VarUsageStack.top().erase(name);
+ this->LogUnused("unsetting", name);
}
- this->Internal->VarInitStack.top().insert(name);
+ this->StateSnapshot.RemoveDefinition(name);
#ifdef CMAKE_BUILD_WITH_CMAKE
cmVariableWatch* vv = this->GetVariableWatch();
if ( vv )
@@ -1972,56 +2019,76 @@ void cmMakefile::RemoveDefinition(const char* name)
#endif
}
-void cmMakefile::RemoveCacheDefinition(const char* name)
+void cmMakefile::RemoveCacheDefinition(const std::string& name)
{
- this->GetCacheManager()->RemoveCacheEntry(name);
+ this->GetState()->RemoveCacheEntry(name);
}
-void cmMakefile::SetProjectName(const char* p)
+void cmMakefile::SetProjectName(std::string const& p)
{
- this->ProjectName = p;
+ this->StateSnapshot.SetProjectName(p);
}
-
-void cmMakefile::AddGlobalLinkInformation(const char* name, cmTarget& target)
+void cmMakefile::AddGlobalLinkInformation(const std::string& name,
+ cmTarget& target)
{
// for these targets do not add anything
switch(target.GetType())
{
- case cmTarget::UTILITY:
- case cmTarget::GLOBAL_TARGET:
+ case cmState::UTILITY:
+ case cmState::GLOBAL_TARGET:
+ case cmState::INTERFACE_LIBRARY:
return;
default:;
}
- std::vector<std::string>::iterator j;
- for(j = this->LinkDirectories.begin();
- j != this->LinkDirectories.end(); ++j)
+ if (const char* linkDirsProp = this->GetProperty("LINK_DIRECTORIES"))
{
- target.AddLinkDirectory(j->c_str());
+ std::vector<std::string> linkDirs;
+ cmSystemTools::ExpandListArgument(linkDirsProp, linkDirs);
+
+ for(std::vector<std::string>::iterator j = linkDirs.begin();
+ j != linkDirs.end(); ++j)
+ {
+ std::string newdir = *j;
+ // remove trailing slashes
+ if(*j->rbegin() == '/')
+ {
+ newdir = j->substr(0, j->size()-1);
+ }
+ if(std::find(this->LinkDirectories.begin(),
+ this->LinkDirectories.end(), newdir)
+ == this->LinkDirectories.end())
+ {
+ target.AddLinkDirectory(*j);
+ }
+ }
}
target.MergeLinkLibraries( *this, name, this->LinkLibraries );
}
-void cmMakefile::AddAlias(const char* lname, cmTarget *tgt)
+void cmMakefile::AddAlias(const std::string& lname,
+ std::string const& tgtName)
{
- this->AliasTargets[lname] = tgt;
- this->LocalGenerator->GetGlobalGenerator()->AddAlias(lname, tgt);
+ this->AliasTargets[lname] = tgtName;
+ this->GetGlobalGenerator()->AddAlias(lname, tgtName);
}
-cmTarget* cmMakefile::AddLibrary(const char* lname, cmTarget::TargetType type,
+cmTarget* cmMakefile::AddLibrary(const std::string& lname,
+ cmState::TargetType type,
const std::vector<std::string> &srcs,
bool excludeFromAll)
{
// wrong type ? default to STATIC
- if ( (type != cmTarget::STATIC_LIBRARY)
- && (type != cmTarget::SHARED_LIBRARY)
- && (type != cmTarget::MODULE_LIBRARY)
- && (type != cmTarget::OBJECT_LIBRARY))
+ if ( (type != cmState::STATIC_LIBRARY)
+ && (type != cmState::SHARED_LIBRARY)
+ && (type != cmState::MODULE_LIBRARY)
+ && (type != cmState::OBJECT_LIBRARY)
+ && (type != cmState::INTERFACE_LIBRARY))
{
this->IssueMessage(cmake::INTERNAL_ERROR,
"cmMakefile::AddLibrary given invalid target type.");
- type = cmTarget::STATIC_LIBRARY;
+ type = cmState::STATIC_LIBRARY;
}
cmTarget* target = this->AddNewTarget(type, lname);
@@ -2042,7 +2109,7 @@ cmTarget* cmMakefile::AddExecutable(const char *exeName,
const std::vector<std::string> &srcs,
bool excludeFromAll)
{
- cmTarget* target = this->AddNewTarget(cmTarget::EXECUTABLE, exeName);
+ cmTarget* target = this->AddNewTarget(cmState::EXECUTABLE, exeName);
if(excludeFromAll)
{
target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
@@ -2054,20 +2121,20 @@ cmTarget* cmMakefile::AddExecutable(const char *exeName,
//----------------------------------------------------------------------------
cmTarget*
-cmMakefile::AddNewTarget(cmTarget::TargetType type, const char* name)
+cmMakefile::AddNewTarget(cmState::TargetType type, const std::string& name)
{
cmTargets::iterator it =
this->Targets.insert(cmTargets::value_type(name, cmTarget())).first;
cmTarget& target = it->second;
target.SetType(type, name);
target.SetMakefile(this);
- this->LocalGenerator->GetGlobalGenerator()->AddTarget(&it->second);
+ this->GetGlobalGenerator()->IndexTarget(&it->second);
return &it->second;
}
-cmSourceFile *cmMakefile::LinearGetSourceFileWithOutput(const char *cname)
+cmSourceFile*
+cmMakefile::LinearGetSourceFileWithOutput(const std::string& name) const
{
- std::string name = cname;
std::string out;
// look through all the source files that have custom commands
@@ -2078,7 +2145,7 @@ cmSourceFile *cmMakefile::LinearGetSourceFileWithOutput(const char *cname)
// does this source file have a custom command?
if ((*i)->GetCustomCommand())
{
- // is the output of the custom command match the source files name
+ // Does the output of the custom command match the source file name?
const std::vector<std::string>& outputs =
(*i)->GetCustomCommand()->GetOutputs();
for(std::vector<std::string>::const_iterator o = outputs.begin();
@@ -2101,18 +2168,17 @@ cmSourceFile *cmMakefile::LinearGetSourceFileWithOutput(const char *cname)
return 0;
}
-cmSourceFile *cmMakefile::GetSourceFileWithOutput(const char *cname)
+cmSourceFile *cmMakefile::GetSourceFileWithOutput(
+ const std::string& name) const
{
- std::string name = cname;
-
// If the queried path is not absolute we use the backward compatible
// linear-time search for an output with a matching suffix.
- if(!cmSystemTools::FileIsFullPath(cname))
+ if(!cmSystemTools::FileIsFullPath(name.c_str()))
{
- return LinearGetSourceFileWithOutput(cname);
+ return this->LinearGetSourceFileWithOutput(name);
}
// Otherwise we use an efficient lookup map.
- OutputToSourceMap::iterator o = this->OutputToSource.find(name);
+ OutputToSourceMap::const_iterator o = this->OutputToSource.find(name);
if (o != this->OutputToSource.end())
{
return (*o).second;
@@ -2121,19 +2187,20 @@ cmSourceFile *cmMakefile::GetSourceFileWithOutput(const char *cname)
}
#if defined(CMAKE_BUILD_WITH_CMAKE)
-cmSourceGroup* cmMakefile::GetSourceGroup(const std::vector<std::string>&name)
+cmSourceGroup*
+cmMakefile::GetSourceGroup(const std::vector<std::string>&name) const
{
cmSourceGroup* sg = 0;
- // first look for source group starting with the same as the one we wants
- for (std::vector<cmSourceGroup>::iterator sgIt = this->SourceGroups.begin();
- sgIt != this->SourceGroups.end(); ++sgIt)
-
+ // first look for source group starting with the same as the one we want
+ for (std::vector<cmSourceGroup>::const_iterator
+ sgIt = this->SourceGroups.begin();
+ sgIt != this->SourceGroups.end(); ++sgIt)
{
std::string sgName = sgIt->GetName();
if(sgName == name[0])
{
- sg = &(*sgIt);
+ sg = const_cast<cmSourceGroup*>(&(*sgIt));
break;
}
}
@@ -2143,7 +2210,7 @@ cmSourceGroup* cmMakefile::GetSourceGroup(const std::vector<std::string>&name)
// iterate through its children to find match source group
for(unsigned int i=1; i<name.size(); ++i)
{
- sg = sg->lookupChild(name[i].c_str());
+ sg = sg->LookupChild(name[i].c_str());
if(sg == 0)
{
break;
@@ -2153,15 +2220,12 @@ cmSourceGroup* cmMakefile::GetSourceGroup(const std::vector<std::string>&name)
return sg;
}
- void cmMakefile::AddSourceGroup(const char* name,
+void cmMakefile::AddSourceGroup(const std::string& name,
const char* regex)
{
- if (name)
- {
- std::vector<std::string> nameVector;
- nameVector.push_back(name);
- AddSourceGroup(nameVector, regex);
- }
+ std::vector<std::string> nameVector;
+ nameVector.push_back(name);
+ this->AddSourceGroup(nameVector, regex);
}
void cmMakefile::AddSourceGroup(const std::vector<std::string>& name,
@@ -2185,7 +2249,7 @@ void cmMakefile::AddSourceGroup(const std::vector<std::string>& name,
if(i==lastElement)
{
// group already exists, replace its regular expression
- if ( regex )
+ if ( regex && sg)
{
// We only want to set the regular expression. If there are already
// source files in the group, we don't want to remove them.
@@ -2201,27 +2265,16 @@ void cmMakefile::AddSourceGroup(const std::vector<std::string>& name,
sg = this->GetSourceGroup(currentName);
i = 0; // last component found
}
-
- // build the whole source group path
- const char* fullname = sg->GetFullName();
- cmGlobalGenerator* gg = this->LocalGenerator->GetGlobalGenerator();
- if(strlen(fullname))
+ if(!sg)
{
- std::string guidName = "SG_Filter_";
- guidName += fullname;
- gg->CreateGUID(guidName.c_str());
+ cmSystemTools::Error("Could not create source group ");
+ return;
}
+ // build the whole source group path
for(++i; i<=lastElement; ++i)
{
sg->AddChild(cmSourceGroup(name[i].c_str(), 0, sg->GetFullName()));
- sg = sg->lookupChild(name[i].c_str());
- fullname = sg->GetFullName();
- if(strlen(fullname))
- {
- std::string guidName = "SG_Filter_";
- guidName += fullname;
- gg->CreateGUID(guidName.c_str());
- }
+ sg = sg->LookupChild(name[i].c_str());
}
sg->SetGroupRegex(regex);
@@ -2229,11 +2282,6 @@ void cmMakefile::AddSourceGroup(const std::vector<std::string>& name,
#endif
-void cmMakefile::AddExtraDirectory(const char* dir)
-{
- this->AuxSourceDirectories.push_back(dir);
-}
-
static bool mightExpandVariablesCMP0019(const char* s)
{
return s && *s && strstr(s,"${") && strchr(s,'}');
@@ -2247,7 +2295,7 @@ void cmMakefile::ExpandVariablesCMP0019()
{
return;
}
- cmOStringStream w;
+ std::ostringstream w;
const char *includeDirs = this->GetProperty("INCLUDE_DIRECTORIES");
if(mightExpandVariablesCMP0019(includeDirs))
@@ -2269,6 +2317,11 @@ void cmMakefile::ExpandVariablesCMP0019()
l != this->Targets.end(); ++l)
{
cmTarget &t = l->second;
+ if (t.GetType() == cmState::INTERFACE_LIBRARY
+ || t.GetType() == cmState::GLOBAL_TARGET)
+ {
+ continue;
+ }
includeDirs = t.GetProperty("INCLUDE_DIRECTORIES");
if(mightExpandVariablesCMP0019(includeDirs))
{
@@ -2285,19 +2338,19 @@ void cmMakefile::ExpandVariablesCMP0019()
}
}
- for(std::vector<std::string>::iterator d = this->LinkDirectories.begin();
- d != this->LinkDirectories.end(); ++d)
+ if (const char* linkDirsProp = this->GetProperty("LINK_DIRECTORIES"))
{
- if(mightExpandVariablesCMP0019(d->c_str()))
+ if(mightExpandVariablesCMP0019(linkDirsProp))
{
- std::string orig = *d;
- this->ExpandVariablesInString(*d, true, true);
- if(pol == cmPolicies::WARN && *d != orig)
+ std::string d = linkDirsProp;
+ std::string orig = linkDirsProp;
+ this->ExpandVariablesInString(d, true, true);
+ if(pol == cmPolicies::WARN && d != orig)
{
- w << "Evaluated link directory\n"
+ w << "Evaluated link directories\n"
<< " " << orig << "\n"
<< "as\n"
- << " " << *d << "\n";
+ << " " << d << "\n";
}
}
}
@@ -2321,8 +2374,8 @@ void cmMakefile::ExpandVariablesCMP0019()
if(!w.str().empty())
{
- cmOStringStream m;
- m << this->GetPolicies()->GetPolicyWarning(cmPolicies::CMP0019)
+ std::ostringstream m;
+ m << cmPolicies::GetPolicyWarning(cmPolicies::CMP0019)
<< "\n"
<< "The following variable evaluations were encountered:\n"
<< w.str();
@@ -2330,13 +2383,13 @@ void cmMakefile::ExpandVariablesCMP0019()
}
}
-bool cmMakefile::IsOn(const char* name) const
+bool cmMakefile::IsOn(const std::string& name) const
{
const char* value = this->GetDefinition(name);
return cmSystemTools::IsOn(value);
}
-bool cmMakefile::IsSet(const char* name) const
+bool cmMakefile::IsSet(const std::string& name) const
{
const char* value = this->GetDefinition(name);
if ( !value )
@@ -2366,19 +2419,44 @@ bool cmMakefile::PlatformIs64Bit() const
return false;
}
-const char* cmMakefile::GetSONameFlag(const char* language) const
+bool cmMakefile::PlatformIsAppleIos() const
+{
+ std::string sdkRoot;
+ sdkRoot = this->GetSafeDefinition("CMAKE_OSX_SYSROOT");
+ sdkRoot = cmSystemTools::LowerCase(sdkRoot);
+
+ const std::string embedded[] =
+ {
+ "appletvos", "appletvsimulator",
+ "iphoneos", "iphonesimulator",
+ "watchos", "watchsimulator",
+ };
+
+ for(size_t i = 0; i < sizeof(embedded) / sizeof(embedded[0]); ++i)
+ {
+ if(sdkRoot.find(embedded[i]) == 0 ||
+ sdkRoot.find(std::string("/") + embedded[i]) != std::string::npos)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+const char* cmMakefile::GetSONameFlag(const std::string& language) const
{
std::string name = "CMAKE_SHARED_LIBRARY_SONAME";
- if(language)
+ if(!language.empty())
{
name += "_";
name += language;
}
name += "_FLAG";
- return GetDefinition(name.c_str());
+ return GetDefinition(name);
}
-bool cmMakefile::CanIWriteThisFile(const char* fileName)
+bool cmMakefile::CanIWriteThisFile(const char* fileName) const
{
if ( !this->IsOn("CMAKE_DISABLE_SOURCE_CHANGES") )
{
@@ -2407,7 +2485,7 @@ bool cmMakefile::CanIWriteThisFile(const char* fileName)
return true;
}
-const char* cmMakefile::GetRequiredDefinition(const char* name) const
+const char* cmMakefile::GetRequiredDefinition(const std::string& name) const
{
const char* ret = this->GetDefinition(name);
if(!ret)
@@ -2415,19 +2493,18 @@ const char* cmMakefile::GetRequiredDefinition(const char* name) const
cmSystemTools::Error("Error required internal CMake variable not "
"set, cmake may be not be built correctly.\n",
"Missing variable is:\n",
- name);
+ name.c_str());
return "";
}
return ret;
}
-bool cmMakefile::IsDefinitionSet(const char* name) const
+bool cmMakefile::IsDefinitionSet(const std::string& name) const
{
- const char* def = this->Internal->VarStack.top().Get(name);
- this->Internal->VarUsageStack.top().insert(name);
+ const char* def = this->StateSnapshot.GetDefinition(name);
if(!def)
{
- def = this->GetCacheManager()->GetCacheValue(name);
+ def = this->GetState()->GetInitializedCacheValue(name);
}
#ifdef CMAKE_BUILD_WITH_CMAKE
if(cmVariableWatch* vv = this->GetVariableWatch())
@@ -2443,47 +2520,32 @@ bool cmMakefile::IsDefinitionSet(const char* name) const
return def?true:false;
}
-const char* cmMakefile::GetDefinition(const char* name) const
+const char* cmMakefile::GetDefinition(const std::string& name) const
{
-#ifdef CMAKE_STRICT
- if (this->GetCMakeInstance())
- {
- this->GetCMakeInstance()->
- RecordPropertyAccess(name,cmProperty::VARIABLE);
- }
-#endif
- if (this->WarnUnused)
- {
- this->Internal->VarUsageStack.top().insert(name);
- }
- const char* def = this->Internal->VarStack.top().Get(name);
+ const char* def = this->StateSnapshot.GetDefinition(name);
if(!def)
{
- def = this->GetCacheManager()->GetCacheValue(name);
+ def = this->GetState()->GetInitializedCacheValue(name);
}
#ifdef CMAKE_BUILD_WITH_CMAKE
cmVariableWatch* vv = this->GetVariableWatch();
- if ( vv )
+ if ( vv && !this->SuppressWatches )
{
- if ( def )
- {
- vv->VariableAccessed(name, cmVariableWatch::VARIABLE_READ_ACCESS,
- def, this);
- }
- else
+ bool const watch_function_executed =
+ vv->VariableAccessed(name,
+ def ? cmVariableWatch::VARIABLE_READ_ACCESS
+ : cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS,
+ def, this);
+
+ if (watch_function_executed)
{
- // are unknown access allowed
- const char* allow = this->Internal->VarStack.top()
- .Get("CMAKE_ALLOW_UNKNOWN_VARIABLE_READ_ACCESS");
- if(cmSystemTools::IsOn(allow))
- {
- vv->VariableAccessed(name,
- cmVariableWatch::ALLOWED_UNKNOWN_VARIABLE_READ_ACCESS, def, this);
- }
- else
+ // A callback was executed and may have caused re-allocation of the
+ // variable storage. Look it up again for now.
+ // FIXME: Refactor variable storage to avoid this problem.
+ def = this->StateSnapshot.GetDefinition(name);
+ if(!def)
{
- vv->VariableAccessed(name,
- cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS, def, this);
+ def = this->GetState()->GetInitializedCacheValue(name);
}
}
}
@@ -2491,7 +2553,7 @@ const char* cmMakefile::GetDefinition(const char* name) const
return def;
}
-const char* cmMakefile::GetSafeDefinition(const char* def) const
+const char* cmMakefile::GetSafeDefinition(const std::string& def) const
{
const char* ret = this->GetDefinition(def);
if(!ret)
@@ -2501,33 +2563,17 @@ const char* cmMakefile::GetSafeDefinition(const char* def) const
return ret;
}
-std::vector<std::string> cmMakefile
-::GetDefinitions(int cacheonly /* = 0 */) const
+std::vector<std::string> cmMakefile::GetDefinitions() const
{
- std::set<cmStdString> definitions;
- if ( !cacheonly )
- {
- definitions = this->Internal->VarStack.top().ClosureKeys();
- }
- cmCacheManager::CacheIterator cit =
- this->GetCacheManager()->GetCacheIterator();
- for ( cit.Begin(); !cit.IsAtEnd(); cit.Next() )
- {
- definitions.insert(cit.GetName());
- }
-
- std::vector<std::string> res;
-
- std::set<cmStdString>::iterator fit;
- for ( fit = definitions.begin(); fit != definitions.end(); fit ++ )
- {
- res.push_back(*fit);
- }
+ std::vector<std::string> res = this->StateSnapshot.ClosureKeys();
+ std::vector<std::string> cacheKeys = this->GetState()->GetCacheEntryKeys();
+ res.insert(res.end(), cacheKeys.begin(), cacheKeys.end());
+ std::sort(res.begin(), res.end());
return res;
}
-const char *cmMakefile::ExpandVariablesInString(std::string& source)
+const char *cmMakefile::ExpandVariablesInString(std::string& source) const
{
return this->ExpandVariablesInString(source, false, false);
}
@@ -2539,25 +2585,135 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source,
const char* filename,
long line,
bool removeEmpty,
- bool replaceAt)
+ bool replaceAt) const
{
- if ( source.empty() || source.find_first_of("$@\\") == source.npos)
+ bool compareResults = false;
+ cmake::MessageType mtype = cmake::LOG;
+ std::string errorstr;
+ std::string original;
+
+ // Sanity check the @ONLY mode.
+ if(atOnly && (!noEscapes || !removeEmpty))
{
+ // This case should never be called. At-only is for
+ // configure-file/string which always does no escapes.
+ this->IssueMessage(cmake::INTERNAL_ERROR,
+ "ExpandVariablesInString @ONLY called "
+ "on something with escapes.");
return source.c_str();
}
- // Special-case the @ONLY mode.
- if(atOnly)
+ // Variables used in the WARN case.
+ std::string newResult;
+ std::string newErrorstr;
+ cmake::MessageType newError = cmake::LOG;
+
+ switch(this->GetPolicyStatus(cmPolicies::CMP0053))
{
- if(!noEscapes || !removeEmpty || !replaceAt)
+ case cmPolicies::WARN:
{
- // This case should never be called. At-only is for
- // configure-file/string which always does no escapes.
- this->IssueMessage(cmake::INTERNAL_ERROR,
- "ExpandVariablesInString @ONLY called "
- "on something with escapes.");
+ // Save the original string for the warning.
+ original = source;
+ newResult = source;
+ compareResults = true;
+ // Suppress variable watches to avoid calling hooks twice. Suppress new
+ // dereferences since the OLD behavior is still what is actually used.
+ this->SuppressWatches = true;
+ newError =
+ ExpandVariablesInStringNew(newErrorstr, newResult, escapeQuotes,
+ noEscapes, atOnly, filename, line,
+ removeEmpty, replaceAt);
+ this->SuppressWatches = false;
}
+ case cmPolicies::OLD:
+ mtype = ExpandVariablesInStringOld(errorstr, source, escapeQuotes,
+ noEscapes, atOnly, filename,
+ line, removeEmpty, true);
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ // Messaging here would be *very* verbose.
+ case cmPolicies::NEW:
+ mtype = ExpandVariablesInStringNew(errorstr, source, escapeQuotes,
+ noEscapes, atOnly, filename,
+ line, removeEmpty, replaceAt);
+ break;
+ }
+ // If it's an error in either case, just report the error...
+ if(mtype != cmake::LOG)
+ {
+ if(mtype == cmake::FATAL_ERROR)
+ {
+ cmSystemTools::SetFatalErrorOccured();
+ }
+ this->IssueMessage(mtype, errorstr);
+ }
+ // ...otherwise, see if there's a difference that needs to be warned about.
+ else if(compareResults && (newResult != source || newError != mtype))
+ {
+ std::string msg =
+ cmPolicies::GetPolicyWarning(cmPolicies::CMP0053);
+ msg += "\n";
+
+ std::string msg_input = original;
+ cmSystemTools::ReplaceString(msg_input, "\n", "\n ");
+ msg += "For input:\n '";
+ msg += msg_input;
+ msg += "'\n";
+
+ std::string msg_old = source;
+ cmSystemTools::ReplaceString(msg_old, "\n", "\n ");
+ msg += "the old evaluation rules produce:\n '";
+ msg += msg_old;
+ msg += "'\n";
+
+ if(newError == mtype)
+ {
+ std::string msg_new = newResult;
+ cmSystemTools::ReplaceString(msg_new, "\n", "\n ");
+ msg += "but the new evaluation rules produce:\n '";
+ msg += msg_new;
+ msg += "'\n";
+ }
+ else
+ {
+ std::string msg_err = newErrorstr;
+ cmSystemTools::ReplaceString(msg_err, "\n", "\n ");
+ msg += "but the new evaluation rules produce an error:\n ";
+ msg += msg_err;
+ msg += "\n";
+ }
+
+ msg +=
+ "Using the old result for compatibility since the policy is not set.";
+
+ this->IssueMessage(cmake::AUTHOR_WARNING, msg);
+ }
+
+ return source.c_str();
+}
+
+cmake::MessageType cmMakefile::ExpandVariablesInStringOld(
+ std::string& errorstr,
+ std::string& source,
+ bool escapeQuotes,
+ bool noEscapes,
+ bool atOnly,
+ const char* filename,
+ long line,
+ bool removeEmpty,
+ bool replaceAt) const
+{
+ // Fast path strings without any special characters.
+ if ( source.find_first_of("$@\\") == source.npos)
+ {
+ return cmake::LOG;
+ }
+
+ // Special-case the @ONLY mode.
+ if(atOnly)
+ {
// Store an original copy of the input.
std::string input = source;
@@ -2577,7 +2733,7 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source,
// Lookup the definition of VAR.
std::string var(first+1, last-first-2);
- if(const char* val = this->GetDefinition(var.c_str()))
+ if(const char* val = this->GetDefinition(var))
{
// Store the value in the output escaping as requested.
if(escapeQuotes)
@@ -2597,7 +2753,7 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source,
// Append the rest of the unchanged part of the string.
source.append(in);
- return source.c_str();
+ return cmake::LOG;
}
// This method replaces ${VAR} and @VAR@ where VAR is looked up
@@ -2614,6 +2770,7 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source,
parser.SetRemoveEmpty(removeEmpty);
int res = parser.ParseString(source.c_str(), 0);
const char* emsg = parser.GetError();
+ cmake::MessageType mtype = cmake::LOG;
if ( res && !emsg[0] )
{
source = parser.GetResult();
@@ -2621,7 +2778,7 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source,
else
{
// Construct the main error message.
- cmOStringStream error;
+ std::ostringstream error;
error << "Syntax error in cmake code ";
if(filename && line > 0)
{
@@ -2632,7 +2789,7 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source,
<< " " << filename << ":" << line << "\n";
}
error << "when parsing string\n"
- << " " << source.c_str() << "\n";
+ << " " << source << "\n";
error << emsg;
// If the parser failed ("res" is false) then this is a real
@@ -2640,7 +2797,7 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source,
// parser reported an error message without failing because the
// helper implementation is unhappy, which has always reported an
// error.
- cmake::MessageType mtype = cmake::FATAL_ERROR;
+ mtype = cmake::FATAL_ERROR;
if(!res)
{
// This is a real argument parsing error. Use policy CMP0010 to
@@ -2648,9 +2805,7 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source,
switch(this->GetPolicyStatus(cmPolicies::CMP0010))
{
case cmPolicies::WARN:
- error << "\n"
- << (this->GetPolicies()
- ->GetPolicyWarning(cmPolicies::CMP0010));
+ error << "\n" << cmPolicies::GetPolicyWarning(cmPolicies::CMP0010);
case cmPolicies::OLD:
// OLD behavior is to just warn and continue.
mtype = cmake::AUTHOR_WARNING;
@@ -2658,17 +2813,338 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source,
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
error << "\n"
- << (this->GetPolicies()
- ->GetRequiredPolicyError(cmPolicies::CMP0010));
+ << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0010);
case cmPolicies::NEW:
// NEW behavior is to report the error.
- cmSystemTools::SetFatalErrorOccured();
break;
}
}
- this->IssueMessage(mtype, error.str());
+ errorstr = error.str();
}
- return source.c_str();
+ return mtype;
+}
+
+typedef enum
+ {
+ NORMAL,
+ ENVIRONMENT,
+ CACHE
+ } t_domain;
+struct t_lookup
+ {
+ t_lookup(): domain(NORMAL), loc(0) {}
+ t_domain domain;
+ size_t loc;
+ };
+
+cmake::MessageType cmMakefile::ExpandVariablesInStringNew(
+ std::string& errorstr,
+ std::string& source,
+ bool escapeQuotes,
+ bool noEscapes,
+ bool atOnly,
+ const char* filename,
+ long line,
+ bool removeEmpty,
+ bool replaceAt) const
+{
+ // This method replaces ${VAR} and @VAR@ where VAR is looked up
+ // with GetDefinition(), if not found in the map, nothing is expanded.
+ // It also supports the $ENV{VAR} syntax where VAR is looked up in
+ // the current environment variables.
+
+ const char* in = source.c_str();
+ const char* last = in;
+ std::string result;
+ result.reserve(source.size());
+ std::vector<t_lookup> openstack;
+ bool error = false;
+ bool done = false;
+ cmake::MessageType mtype = cmake::LOG;
+
+ cmState* state = this->GetCMakeInstance()->GetState();
+
+ do
+ {
+ char inc = *in;
+ switch(inc)
+ {
+ case '}':
+ if(!openstack.empty())
+ {
+ t_lookup var = openstack.back();
+ openstack.pop_back();
+ result.append(last, in - last);
+ std::string const& lookup = result.substr(var.loc);
+ const char* value = NULL;
+ std::string varresult;
+ static const std::string lineVar = "CMAKE_CURRENT_LIST_LINE";
+ switch(var.domain)
+ {
+ case NORMAL:
+ if(filename && lookup == lineVar)
+ {
+ std::ostringstream ostr;
+ ostr << line;
+ varresult = ostr.str();
+ }
+ else
+ {
+ value = this->GetDefinition(lookup);
+ }
+ break;
+ case ENVIRONMENT:
+ value = cmSystemTools::GetEnv(lookup.c_str());
+ break;
+ case CACHE:
+ value = state->GetCacheEntryValue(lookup);
+ break;
+ }
+ // Get the string we're meant to append to.
+ if(value)
+ {
+ if(escapeQuotes)
+ {
+ varresult = cmSystemTools::EscapeQuotes(value);
+ }
+ else
+ {
+ varresult = value;
+ }
+ }
+ else if(!removeEmpty)
+ {
+ // check to see if we need to print a warning
+ // if strict mode is on and the variable has
+ // not been "cleared"/initialized with a set(foo ) call
+ if(this->GetCMakeInstance()->GetWarnUninitialized() &&
+ !this->VariableInitialized(lookup))
+ {
+ if (this->CheckSystemVars ||
+ cmSystemTools::IsSubDirectory(filename,
+ this->GetHomeDirectory()) ||
+ cmSystemTools::IsSubDirectory(filename,
+ this->GetHomeOutputDirectory()))
+ {
+ std::ostringstream msg;
+ cmListFileContext lfc;
+ cmOutputConverter converter(this->StateSnapshot);
+ lfc.FilePath =
+ converter.Convert(filename, cmOutputConverter::HOME);
+ lfc.Line = line;
+ msg << "uninitialized variable \'" << lookup << "\'";
+ this->GetCMakeInstance()->IssueMessage(cmake::AUTHOR_WARNING,
+ msg.str(), lfc);
+ }
+ }
+ }
+ result.replace(var.loc, result.size() - var.loc, varresult);
+ // Start looking from here on out.
+ last = in + 1;
+ }
+ break;
+ case '$':
+ if(!atOnly)
+ {
+ t_lookup lookup;
+ const char* next = in + 1;
+ const char* start = NULL;
+ char nextc = *next;
+ if(nextc == '{')
+ {
+ // Looking for a variable.
+ start = in + 2;
+ lookup.domain = NORMAL;
+ }
+ else if(nextc == '<')
+ {
+ }
+ else if(!nextc)
+ {
+ result.append(last, next - last);
+ last = next;
+ }
+ else if(cmHasLiteralPrefix(next, "ENV{"))
+ {
+ // Looking for an environment variable.
+ start = in + 5;
+ lookup.domain = ENVIRONMENT;
+ }
+ else if(cmHasLiteralPrefix(next, "CACHE{"))
+ {
+ // Looking for a cache variable.
+ start = in + 7;
+ lookup.domain = CACHE;
+ }
+ else
+ {
+ if(this->cmNamedCurly.find(next))
+ {
+ errorstr = "Syntax $"
+ + std::string(next, this->cmNamedCurly.end())
+ + "{} is not supported. Only ${}, $ENV{}, "
+ "and $CACHE{} are allowed.";
+ mtype = cmake::FATAL_ERROR;
+ error = true;
+ }
+ }
+ if(start)
+ {
+ result.append(last, in - last);
+ last = start;
+ in = start - 1;
+ lookup.loc = result.size();
+ openstack.push_back(lookup);
+ }
+ break;
+ }
+ case '\\':
+ if(!noEscapes)
+ {
+ const char* next = in + 1;
+ char nextc = *next;
+ if(nextc == 't')
+ {
+ result.append(last, in - last);
+ result.append("\t");
+ last = next + 1;
+ }
+ else if(nextc == 'n')
+ {
+ result.append(last, in - last);
+ result.append("\n");
+ last = next + 1;
+ }
+ else if(nextc == 'r')
+ {
+ result.append(last, in - last);
+ result.append("\r");
+ last = next + 1;
+ }
+ else if(nextc == ';' && openstack.empty())
+ {
+ // Handled in ExpandListArgument; pass the backslash literally.
+ }
+ else if (isalnum(nextc) || nextc == '\0')
+ {
+ errorstr += "Invalid character escape '\\";
+ if (nextc)
+ {
+ errorstr += nextc;
+ errorstr += "'.";
+ }
+ else
+ {
+ errorstr += "' (at end of input).";
+ }
+ error = true;
+ }
+ else
+ {
+ // Take what we've found so far, skipping the escape character.
+ result.append(last, in - last);
+ // Start tracking from the next character.
+ last = in + 1;
+ }
+ // Skip the next character since it was escaped, but don't read past
+ // the end of the string.
+ if(*last)
+ {
+ ++in;
+ }
+ }
+ break;
+ case '\n':
+ // Onto the next line.
+ ++line;
+ break;
+ case '\0':
+ done = true;
+ break;
+ case '@':
+ if(replaceAt)
+ {
+ const char* nextAt = strchr(in + 1, '@');
+ if(nextAt && nextAt != in + 1 &&
+ nextAt == in + 1 + strspn(in + 1,
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789/_.+-"))
+ {
+ std::string variable(in + 1, nextAt - in - 1);
+ std::string varresult = this->GetSafeDefinition(variable);
+ if(escapeQuotes)
+ {
+ varresult = cmSystemTools::EscapeQuotes(varresult);
+ }
+ // Skip over the variable.
+ result.append(last, in - last);
+ result.append(varresult);
+ in = nextAt;
+ last = in + 1;
+ break;
+ }
+ }
+ // Failed to find a valid @ expansion; treat it as literal.
+ /* FALLTHROUGH */
+ default:
+ {
+ if(!openstack.empty() &&
+ !(isalnum(inc) || inc == '_' ||
+ inc == '/' || inc == '.' ||
+ inc == '+' || inc == '-'))
+ {
+ errorstr += "Invalid character (\'";
+ errorstr += inc;
+ result.append(last, in - last);
+ errorstr += "\') in a variable name: "
+ "'" + result.substr(openstack.back().loc) + "'";
+ mtype = cmake::FATAL_ERROR;
+ error = true;
+ }
+ break;
+ }
+ }
+ // Look at the next character.
+ } while(!error && !done && *++in);
+
+ // Check for open variable references yet.
+ if(!error && !openstack.empty())
+ {
+ // There's an open variable reference waiting. Policy CMP0010 flags
+ // whether this is an error or not. The new parser now enforces
+ // CMP0010 as well.
+ errorstr += "There is an unterminated variable reference.";
+ error = true;
+ }
+
+ if(error)
+ {
+ std::ostringstream emsg;
+ emsg << "Syntax error in cmake code ";
+ if(filename)
+ {
+ // This filename and line number may be more specific than the
+ // command context because one command invocation can have
+ // arguments on multiple lines.
+ emsg << "at\n"
+ << " " << filename << ":" << line << "\n";
+ }
+ emsg << "when parsing string\n"
+ << " " << source << "\n";
+ emsg << errorstr;
+ mtype = cmake::FATAL_ERROR;
+ errorstr = emsg.str();
+ }
+ else
+ {
+ // Append the rest of the unchanged part of the string.
+ result.append(last);
+
+ source = result;
+ }
+
+ return mtype;
}
void cmMakefile::RemoveVariablesInString(std::string& source,
@@ -2698,76 +3174,24 @@ void cmMakefile::RemoveVariablesInString(std::string& source,
}
}
-/**
- * Add the default definitions to the makefile. These values must not
- * be dependent on anything that isn't known when this cmMakefile instance
- * is constructed.
- */
-void cmMakefile::AddDefaultDefinitions()
-{
-/* Up to CMake 2.4 here only WIN32, UNIX and APPLE were set.
- With CMake must separate between target and host platform. In most cases
- the tests for WIN32, UNIX and APPLE will be for the target system, so an
- additional set of variables for the host system is required ->
- CMAKE_HOST_WIN32, CMAKE_HOST_UNIX, CMAKE_HOST_APPLE.
- WIN32, UNIX and APPLE are now set in the platform files in
- Modules/Platforms/.
- To keep cmake scripts (-P) and custom language and compiler modules
- working, these variables are still also set here in this place, but they
- will be reset in CMakeSystemSpecificInformation.cmake before the platform
- files are executed. */
-#if defined(_WIN32)
- this->AddDefinition("WIN32", "1");
- this->AddDefinition("CMAKE_HOST_WIN32", "1");
-#else
- this->AddDefinition("UNIX", "1");
- this->AddDefinition("CMAKE_HOST_UNIX", "1");
-#endif
-#if defined(__CYGWIN__)
- if(cmSystemTools::IsOn(cmSystemTools::GetEnv("CMAKE_LEGACY_CYGWIN_WIN32")))
- {
- this->AddDefinition("WIN32", "1");
- this->AddDefinition("CMAKE_HOST_WIN32", "1");
- }
-#endif
-#if defined(__APPLE__)
- this->AddDefinition("APPLE", "1");
- this->AddDefinition("CMAKE_HOST_APPLE", "1");
-#endif
-
- char temp[1024];
- sprintf(temp, "%d", cmVersion::GetMinorVersion());
- this->AddDefinition("CMAKE_MINOR_VERSION", temp);
- sprintf(temp, "%d", cmVersion::GetMajorVersion());
- this->AddDefinition("CMAKE_MAJOR_VERSION", temp);
- sprintf(temp, "%d", cmVersion::GetPatchVersion());
- this->AddDefinition("CMAKE_PATCH_VERSION", temp);
- sprintf(temp, "%d", cmVersion::GetTweakVersion());
- this->AddDefinition("CMAKE_TWEAK_VERSION", temp);
- this->AddDefinition("CMAKE_VERSION", cmVersion::GetCMakeVersion());
-
- this->AddDefinition("CMAKE_FILES_DIRECTORY",
- cmake::GetCMakeFilesDirectory());
-}
-
//----------------------------------------------------------------------------
-const char*
+std::string
cmMakefile::GetConfigurations(std::vector<std::string>& configs,
- bool single) const
+ bool singleConfig) const
{
- if(this->LocalGenerator->GetGlobalGenerator()->IsMultiConfig())
+ if(this->GetGlobalGenerator()->IsMultiConfig())
{
if(const char* configTypes =
this->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
{
cmSystemTools::ExpandListArgument(configTypes, configs);
}
- return 0;
+ return "";
}
else
{
- const char* buildType = this->GetDefinition("CMAKE_BUILD_TYPE");
- if(single && buildType && *buildType)
+ const std::string& buildType = this->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ if(singleConfig && !buildType.empty())
{
configs.push_back(buildType);
}
@@ -2783,9 +3207,9 @@ cmMakefile::GetConfigurations(std::vector<std::string>& configs,
* non-inherited SOURCE_GROUP commands will have precedence over
* inherited ones.
*/
-cmSourceGroup&
+cmSourceGroup*
cmMakefile::FindSourceGroup(const char* source,
- std::vector<cmSourceGroup> &groups)
+ std::vector<cmSourceGroup> &groups) const
{
// First search for a group that lists the file explicitly.
for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
@@ -2794,7 +3218,7 @@ cmMakefile::FindSourceGroup(const char* source,
cmSourceGroup *result = sg->MatchChildrenFiles(source);
if(result)
{
- return *result;
+ return result;
}
}
@@ -2805,13 +3229,13 @@ cmMakefile::FindSourceGroup(const char* source,
cmSourceGroup *result = sg->MatchChildrenRegex(source);
if(result)
{
- return *result;
+ return result;
}
}
// Shouldn't get here, but just in case, return the default group.
- return groups.front();
+ return &groups.front();
}
#endif
@@ -2859,7 +3283,7 @@ void cmMakefile::PopFunctionBlockerBarrier(bool reportError)
{
// Report the context in which the unclosed block was opened.
cmListFileContext const& lfc = fb->GetStartingContext();
- cmOStringStream e;
+ std::ostringstream e;
e << "A logical block opening on the line\n"
<< " " << lfc << "\n"
<< "is not closed.";
@@ -2872,20 +3296,69 @@ void cmMakefile::PopFunctionBlockerBarrier(bool reportError)
this->FunctionBlockerBarriers.pop_back();
}
+//----------------------------------------------------------------------------
+void cmMakefile::PushLoopBlock()
+{
+ assert(!this->LoopBlockCounter.empty());
+ this->LoopBlockCounter.top()++;
+}
+
+void cmMakefile::PopLoopBlock()
+{
+ assert(!this->LoopBlockCounter.empty());
+ assert(this->LoopBlockCounter.top() > 0);
+ this->LoopBlockCounter.top()--;
+}
+
+void cmMakefile::PushLoopBlockBarrier()
+{
+ this->LoopBlockCounter.push(0);
+}
+
+void cmMakefile::PopLoopBlockBarrier()
+{
+ assert(!this->LoopBlockCounter.empty());
+ assert(this->LoopBlockCounter.top() == 0);
+ this->LoopBlockCounter.pop();
+}
+
+bool cmMakefile::IsLoopBlock() const
+{
+ assert(!this->LoopBlockCounter.empty());
+ return !this->LoopBlockCounter.empty() && this->LoopBlockCounter.top() > 0;
+}
+
+std::string cmMakefile::GetExecutionFilePath() const
+{
+ assert(this->StateSnapshot.IsValid());
+ return this->StateSnapshot.GetExecutionListFile();
+}
+
+//----------------------------------------------------------------------------
bool cmMakefile::ExpandArguments(
std::vector<cmListFileArgument> const& inArgs,
- std::vector<std::string>& outArgs)
+ std::vector<std::string>& outArgs, const char* filename) const
{
+ std::string efp = this->GetExecutionFilePath();
+ if (!filename)
+ {
+ filename = efp.c_str();
+ }
std::vector<cmListFileArgument>::const_iterator i;
std::string value;
outArgs.reserve(inArgs.size());
for(i = inArgs.begin(); i != inArgs.end(); ++i)
{
+ // No expansion in a bracket argument.
+ if(i->Delim == cmListFileArgument::Bracket)
+ {
+ outArgs.push_back(i->Value);
+ continue;
+ }
// Expand the variables in the argument.
value = i->Value;
this->ExpandVariablesInString(value, false, false, false,
- i->FilePath, i->Line,
- false, true);
+ filename, i->Line, false, false);
// If the argument is quoted, it should be one argument.
// Otherwise, it may be a list of arguments.
@@ -2902,12 +3375,57 @@ bool cmMakefile::ExpandArguments(
}
//----------------------------------------------------------------------------
+bool cmMakefile::ExpandArguments(
+ std::vector<cmListFileArgument> const& inArgs,
+ std::vector<cmExpandedCommandArgument>& outArgs, const char* filename) const
+{
+ std::string efp = this->GetExecutionFilePath();
+ if (!filename)
+ {
+ filename = efp.c_str();
+ }
+ std::vector<cmListFileArgument>::const_iterator i;
+ std::string value;
+ outArgs.reserve(inArgs.size());
+ for(i = inArgs.begin(); i != inArgs.end(); ++i)
+ {
+ // No expansion in a bracket argument.
+ if(i->Delim == cmListFileArgument::Bracket)
+ {
+ outArgs.push_back(cmExpandedCommandArgument(i->Value, true));
+ continue;
+ }
+ // Expand the variables in the argument.
+ value = i->Value;
+ this->ExpandVariablesInString(value, false, false, false,
+ filename, i->Line, false, false);
+
+ // If the argument is quoted, it should be one argument.
+ // Otherwise, it may be a list of arguments.
+ if(i->Delim == cmListFileArgument::Quoted)
+ {
+ outArgs.push_back(cmExpandedCommandArgument(value, true));
+ }
+ else
+ {
+ std::vector<std::string> stringArgs;
+ cmSystemTools::ExpandListArgument(value, stringArgs);
+ for(size_t j = 0; j < stringArgs.size(); ++j)
+ {
+ outArgs.push_back(cmExpandedCommandArgument(stringArgs[j], false));
+ }
+ }
+ }
+ return !cmSystemTools::GetFatalErrorOccured();
+}
+
+//----------------------------------------------------------------------------
void cmMakefile::AddFunctionBlocker(cmFunctionBlocker* fb)
{
- if(!this->CallStack.empty())
+ if(!this->ExecutionStatusStack.empty())
{
// Record the context in which the blocker is created.
- fb->SetStartingContext(*(this->CallStack.back().Context));
+ fb->SetStartingContext(this->GetExecutionContext());
}
this->FunctionBlockers.push_back(fb);
@@ -2937,11 +3455,13 @@ cmMakefile::RemoveFunctionBlocker(cmFunctionBlocker* fb,
if(!(*pos)->ShouldRemove(lff, *this))
{
cmListFileContext const& lfc = fb->GetStartingContext();
- cmOStringStream e;
+ cmListFileContext closingContext =
+ cmListFileContext::FromCommandContext(lff, lfc.FilePath);
+ std::ostringstream e;
e << "A logical block opening on the line\n"
<< " " << lfc << "\n"
<< "closes on the line\n"
- << " " << lff << "\n"
+ << " " << closingContext << "\n"
<< "with mis-matching arguments.";
this->IssueMessage(cmake::AUTHOR_WARNING, e.str());
}
@@ -2954,40 +3474,14 @@ cmMakefile::RemoveFunctionBlocker(cmFunctionBlocker* fb,
return cmsys::auto_ptr<cmFunctionBlocker>();
}
-//----------------------------------------------------------------------------
-cmMakefile::LexicalPushPop::LexicalPushPop(cmMakefile* mf):
- Makefile(mf), ReportError(true)
-{
- this->Makefile->PushFunctionBlockerBarrier();
-}
-
-//----------------------------------------------------------------------------
-cmMakefile::LexicalPushPop::~LexicalPushPop()
+const char* cmMakefile::GetHomeDirectory() const
{
- this->Makefile->PopFunctionBlockerBarrier(this->ReportError);
+ return this->GetCMakeInstance()->GetHomeDirectory();
}
-void cmMakefile::SetHomeDirectory(const char* dir)
+const char* cmMakefile::GetHomeOutputDirectory() const
{
- this->cmHomeDirectory = dir;
- cmSystemTools::ConvertToUnixSlashes(this->cmHomeDirectory);
- this->AddDefinition("CMAKE_SOURCE_DIR", this->GetHomeDirectory());
- if ( !this->GetDefinition("CMAKE_CURRENT_SOURCE_DIR") )
- {
- this->AddDefinition("CMAKE_CURRENT_SOURCE_DIR", this->GetHomeDirectory());
- }
-}
-
-void cmMakefile::SetHomeOutputDirectory(const char* lib)
-{
- this->HomeOutputDirectory = lib;
- cmSystemTools::ConvertToUnixSlashes(this->HomeOutputDirectory);
- this->AddDefinition("CMAKE_BINARY_DIR", this->GetHomeOutputDirectory());
- if ( !this->GetDefinition("CMAKE_CURRENT_BINARY_DIR") )
- {
- this->AddDefinition("CMAKE_CURRENT_BINARY_DIR",
- this->GetHomeOutputDirectory());
- }
+ return this->GetCMakeInstance()->GetHomeOutputDirectory();
}
void cmMakefile::SetScriptModeFile(const char* scriptfile)
@@ -2997,22 +3491,22 @@ void cmMakefile::SetScriptModeFile(const char* scriptfile)
void cmMakefile::SetArgcArgv(const std::vector<std::string>& args)
{
- cmOStringStream strStream;
+ std::ostringstream strStream;
strStream << args.size();
this->AddDefinition("CMAKE_ARGC", strStream.str().c_str());
//this->MarkVariableAsUsed("CMAKE_ARGC");
for (unsigned int t = 0; t < args.size(); ++t)
{
- cmOStringStream tmpStream;
+ std::ostringstream tmpStream;
tmpStream << "CMAKE_ARGV" << t;
- this->AddDefinition(tmpStream.str().c_str(), args[t].c_str());
+ this->AddDefinition(tmpStream.str(), args[t].c_str());
//this->MarkVariableAsUsed(tmpStream.str().c_str());
}
}
//----------------------------------------------------------------------------
-cmSourceFile* cmMakefile::GetSource(const char* sourceName)
+cmSourceFile* cmMakefile::GetSource(const std::string& sourceName) const
{
cmSourceFileLocation sfl(this, sourceName);
for(std::vector<cmSourceFile*>::const_iterator
@@ -3029,7 +3523,20 @@ cmSourceFile* cmMakefile::GetSource(const char* sourceName)
}
//----------------------------------------------------------------------------
-cmSourceFile* cmMakefile::GetOrCreateSource(const char* sourceName,
+cmSourceFile* cmMakefile::CreateSource(const std::string& sourceName,
+ bool generated)
+{
+ cmSourceFile* sf = new cmSourceFile(this, sourceName);
+ if(generated)
+ {
+ sf->SetProperty("GENERATED", "1");
+ }
+ this->SourceFiles.push_back(sf);
+ return sf;
+}
+
+//----------------------------------------------------------------------------
+cmSourceFile* cmMakefile::GetOrCreateSource(const std::string& sourceName,
bool generated)
{
if(cmSourceFile* esf = this->GetSource(sourceName))
@@ -3038,13 +3545,7 @@ cmSourceFile* cmMakefile::GetOrCreateSource(const char* sourceName,
}
else
{
- cmSourceFile* sf = new cmSourceFile(this, sourceName);
- if(generated)
- {
- sf->SetProperty("GENERATED", "1");
- }
- this->SourceFiles.push_back(sf);
- return sf;
+ return this->CreateSource(sourceName, generated);
}
}
@@ -3052,36 +3553,23 @@ void cmMakefile::EnableLanguage(std::vector<std::string> const & lang,
bool optional)
{
this->AddDefinition("CMAKE_CFG_INTDIR",
- this->LocalGenerator->GetGlobalGenerator()
- ->GetCMakeCFGIntDir());
- this->LocalGenerator->GetGlobalGenerator()->EnableLanguage(lang, this,
- optional);
+ this->GetGlobalGenerator()->GetCMakeCFGIntDir());
+ this->GetGlobalGenerator()->EnableLanguage(lang, this, optional);
}
-void cmMakefile::ExpandSourceListArguments(
- std::vector<std::string> const& arguments,
- std::vector<std::string>& newargs, unsigned int /* start */)
-{
- // now expand the args
- unsigned int i;
- for(i = 0; i < arguments.size(); ++i)
- {
- // List expansion will have been done already.
- newargs.push_back(arguments[i]);
- }
-}
-
-int cmMakefile::TryCompile(const char *srcdir, const char *bindir,
- const char *projectName, const char *targetName,
+int cmMakefile::TryCompile(const std::string& srcdir,
+ const std::string& bindir,
+ const std::string& projectName,
+ const std::string& targetName,
bool fast,
const std::vector<std::string> *cmakeArgs,
- std::string *output)
+ std::string& output)
{
- this->Internal->IsSourceFileTryCompile = fast;
+ this->IsSourceFileTryCompile = fast;
// does the binary directory exist ? If not create it...
if (!cmSystemTools::FileIsDirectory(bindir))
{
- cmSystemTools::MakeDirectory(bindir);
+ cmSystemTools::MakeDirectory(bindir.c_str());
}
// change to the tests directory and run cmake
@@ -3092,18 +3580,17 @@ int cmMakefile::TryCompile(const char *srcdir, const char *bindir,
// make sure the same generator is used
// use this program as the cmake to be run, it should not
// be run that way but the cmake object requires a vailid path
- std::string cmakeCommand = this->GetDefinition("CMAKE_COMMAND");
cmake cm;
cm.SetIsInTryCompile(true);
cmGlobalGenerator *gg = cm.CreateGlobalGenerator
- (this->LocalGenerator->GetGlobalGenerator()->GetName());
+ (this->GetGlobalGenerator()->GetName());
if (!gg)
{
cmSystemTools::Error(
"Internal CMake error, TryCompile bad GlobalGenerator");
// return to the original directory
- cmSystemTools::ChangeDirectory(cwd.c_str());
- this->Internal->IsSourceFileTryCompile = false;
+ cmSystemTools::ChangeDirectory(cwd);
+ this->IsSourceFileTryCompile = false;
return 1;
}
cm.SetGlobalGenerator(gg);
@@ -3111,9 +3598,7 @@ int cmMakefile::TryCompile(const char *srcdir, const char *bindir,
// do a configure
cm.SetHomeDirectory(srcdir);
cm.SetHomeOutputDirectory(bindir);
- cm.SetStartDirectory(srcdir);
- cm.SetStartOutputDirectory(bindir);
- cm.SetCMakeCommand(cmakeCommand.c_str());
+ cm.SetGeneratorPlatform(this->GetCMakeInstance()->GetGeneratorPlatform());
cm.SetGeneratorToolset(this->GetCMakeInstance()->GetGeneratorToolset());
cm.LoadCache();
if(!gg->IsMultiConfig())
@@ -3125,7 +3610,7 @@ int cmMakefile::TryCompile(const char *srcdir, const char *bindir,
// Add this before the user-provided CMake arguments in case
// one of the arguments is -DCMAKE_BUILD_TYPE=...
cm.AddCacheEntry("CMAKE_BUILD_TYPE", config,
- "Build configuration", cmCacheManager::STRING);
+ "Build configuration", cmState::STRING);
}
}
// if cmake args were provided then pass them in
@@ -3159,25 +3644,24 @@ int cmMakefile::TryCompile(const char *srcdir, const char *bindir,
cm.SetCacheArgs(*cmakeArgs);
}
// to save time we pass the EnableLanguage info directly
- gg->EnableLanguagesFromGenerator
- (this->LocalGenerator->GetGlobalGenerator(), this);
+ gg->EnableLanguagesFromGenerator(this->GetGlobalGenerator(), this);
if(this->IsOn("CMAKE_SUPPRESS_DEVELOPER_WARNINGS"))
{
cm.AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS",
- "TRUE", "", cmCacheManager::INTERNAL);
+ "TRUE", "", cmState::INTERNAL);
}
else
{
cm.AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS",
- "FALSE", "", cmCacheManager::INTERNAL);
+ "FALSE", "", cmState::INTERNAL);
}
if (cm.Configure() != 0)
{
cmSystemTools::Error(
"Internal CMake error, TryCompile configure of cmake failed");
// return to the original directory
- cmSystemTools::ChangeDirectory(cwd.c_str());
- this->Internal->IsSourceFileTryCompile = false;
+ cmSystemTools::ChangeDirectory(cwd);
+ this->IsSourceFileTryCompile = false;
return 1;
}
@@ -3186,37 +3670,37 @@ int cmMakefile::TryCompile(const char *srcdir, const char *bindir,
cmSystemTools::Error(
"Internal CMake error, TryCompile generation of cmake failed");
// return to the original directory
- cmSystemTools::ChangeDirectory(cwd.c_str());
- this->Internal->IsSourceFileTryCompile = false;
+ cmSystemTools::ChangeDirectory(cwd);
+ this->IsSourceFileTryCompile = false;
return 1;
}
// finally call the generator to actually build the resulting project
- int ret =
- this->LocalGenerator->GetGlobalGenerator()->TryCompile(srcdir,bindir,
- projectName,
- targetName,
- fast,
- output,
- this);
-
- cmSystemTools::ChangeDirectory(cwd.c_str());
- this->Internal->IsSourceFileTryCompile = false;
+ int ret = this->GetGlobalGenerator()->TryCompile(srcdir,bindir,
+ projectName,
+ targetName,
+ fast,
+ output,
+ this);
+
+ cmSystemTools::ChangeDirectory(cwd);
+ this->IsSourceFileTryCompile = false;
return ret;
}
bool cmMakefile::GetIsSourceFileTryCompile() const
{
- return this->Internal->IsSourceFileTryCompile;
+ return this->IsSourceFileTryCompile;
}
cmake *cmMakefile::GetCMakeInstance() const
{
- if ( this->LocalGenerator && this->LocalGenerator->GetGlobalGenerator() )
- {
- return this->LocalGenerator->GetGlobalGenerator()->GetCMakeInstance();
- }
- return 0;
+ return this->GlobalGenerator->GetCMakeInstance();
+}
+
+cmGlobalGenerator* cmMakefile::GetGlobalGenerator() const
+{
+ return this->GlobalGenerator;
}
#ifdef CMAKE_BUILD_WITH_CMAKE
@@ -3231,40 +3715,14 @@ cmVariableWatch *cmMakefile::GetVariableWatch() const
}
#endif
-void cmMakefile::AddMacro(const char* name, const char* signature)
-{
- if ( !name || !signature )
- {
- return;
- }
- this->MacrosMap[name] = signature;
-}
-
-void cmMakefile::GetListOfMacros(std::string& macros)
-{
- StringStringMap::iterator it;
- macros = "";
- int cc = 0;
- for ( it = this->MacrosMap.begin(); it != this->MacrosMap.end(); ++it )
- {
- if ( cc > 0 )
- {
- macros += ";";
- }
- macros += it->first;
- cc ++;
- }
-}
-
-cmCacheManager *cmMakefile::GetCacheManager() const
+cmState *cmMakefile::GetState() const
{
- return this->GetCMakeInstance()->GetCacheManager();
+ return this->GetCMakeInstance()->GetState();
}
-void cmMakefile::DisplayStatus(const char* message, float s)
+void cmMakefile::DisplayStatus(const char* message, float s) const
{
- cmake* cm = this->GetLocalGenerator()->GetGlobalGenerator()
- ->GetCMakeInstance();
+ cmake* cm = this->GetCMakeInstance();
if (cm->GetWorkingMode() == cmake::FIND_PACKAGE_MODE)
{
// don't output any STATUS message in FIND_PACKAGE_MODE, since they will
@@ -3274,7 +3732,7 @@ void cmMakefile::DisplayStatus(const char* message, float s)
cm->UpdateProgress(message, s);
}
-std::string cmMakefile::GetModulesFile(const char* filename)
+std::string cmMakefile::GetModulesFile(const char* filename) const
{
std::string result;
@@ -3332,26 +3790,27 @@ std::string cmMakefile::GetModulesFile(const char* filename)
// from which we are being called is located itself in CMAKE_ROOT, then
// prefer results from CMAKE_ROOT depending on the policy setting.
result = moduleInCMakeModulePath;
- if (result.size() == 0)
+ if (result.empty())
{
result = moduleInCMakeRoot;
}
- if ((moduleInCMakeModulePath.size()>0) && (moduleInCMakeRoot.size()>0))
+ if (!moduleInCMakeModulePath.empty() && !moduleInCMakeRoot.empty())
{
const char* currentFile = this->GetDefinition("CMAKE_CURRENT_LIST_FILE");
- if (currentFile && (strstr(currentFile, cmakeRoot) == currentFile))
+ std::string mods = cmakeRoot + std::string("/Modules/");
+ if (currentFile && strncmp(currentFile, mods.c_str(), mods.size()) == 0)
{
switch (this->GetPolicyStatus(cmPolicies::CMP0017))
{
case cmPolicies::WARN:
{
- cmOStringStream e;
+ std::ostringstream e;
e << "File " << currentFile << " includes "
<< moduleInCMakeModulePath
<< " (found via CMAKE_MODULE_PATH) which shadows "
<< moduleInCMakeRoot << ". This may cause errors later on .\n"
- << this->GetPolicies()->GetPolicyWarning(cmPolicies::CMP0017);
+ << cmPolicies::GetPolicyWarning(cmPolicies::CMP0017);
this->IssueMessage(cmake::AUTHOR_WARNING, e.str());
// break; // fall through to OLD behaviour
@@ -3362,7 +3821,6 @@ std::string cmMakefile::GetModulesFile(const char* filename)
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
- default:
result = moduleInCMakeRoot;
break;
}
@@ -3374,7 +3832,7 @@ std::string cmMakefile::GetModulesFile(const char* filename)
void cmMakefile::ConfigureString(const std::string& input,
std::string& output, bool atOnly,
- bool escapeQuotes)
+ bool escapeQuotes) const
{
// Split input to handle one line at a time.
std::string::const_iterator lineStart = input.begin();
@@ -3401,7 +3859,7 @@ void cmMakefile::ConfigureString(const std::string& input,
if(this->cmDefineRegex.find(line))
{
const char* def =
- this->GetDefinition(this->cmDefineRegex.match(1).c_str());
+ this->GetDefinition(this->cmDefineRegex.match(1));
if(!cmSystemTools::IsOff(def))
{
cmSystemTools::ReplaceString(line, "#cmakedefine", "#define");
@@ -3417,7 +3875,7 @@ void cmMakefile::ConfigureString(const std::string& input,
else if(this->cmDefine01Regex.find(line))
{
const char* def =
- this->GetDefinition(this->cmDefine01Regex.match(1).c_str());
+ this->GetDefinition(this->cmDefine01Regex.match(1));
cmSystemTools::ReplaceString(line, "#cmakedefine01", "#define");
output += line;
if(!cmSystemTools::IsOff(def))
@@ -3445,7 +3903,7 @@ void cmMakefile::ConfigureString(const std::string& input,
// Perform variable replacements.
this->ExpandVariablesInString(output, escapeQuotes, true,
- atOnly, 0, -1, true);
+ atOnly, 0, -1, true, true);
}
int cmMakefile::ConfigureFile(const char* infile, const char* outfile,
@@ -3506,7 +3964,7 @@ int cmMakefile::ConfigureFile(const char* infile, const char* outfile,
}
std::string tempOutputFile = soutfile;
tempOutputFile += ".tmp";
- std::ofstream fout(tempOutputFile.c_str(), omode);
+ cmsys::ofstream fout(tempOutputFile.c_str(), omode);
if(!fout)
{
cmSystemTools::Error(
@@ -3515,7 +3973,7 @@ int cmMakefile::ConfigureFile(const char* infile, const char* outfile,
cmSystemTools::ReportLastSystemError("");
return 0;
}
- std::ifstream fin(sinfile.c_str());
+ cmsys::ifstream fin(sinfile.c_str());
if(!fin)
{
cmSystemTools::Error("Could not open file for read in copy operation ",
@@ -3523,6 +3981,20 @@ int cmMakefile::ConfigureFile(const char* infile, const char* outfile,
return 0;
}
+ cmsys::FStream::BOM bom = cmsys::FStream::ReadBOM(fin);
+ if(bom != cmsys::FStream::BOM_None &&
+ bom != cmsys::FStream::BOM_UTF8)
+ {
+ std::ostringstream e;
+ e << "File starts with a Byte-Order-Mark that is not UTF-8:\n "
+ << sinfile;
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return 0;
+ }
+ // rewind to copy BOM to output file
+ fin.seekg(0);
+
+
// now copy input to output and expand variables in the
// input file at the same time
std::string inLine;
@@ -3545,340 +4017,62 @@ int cmMakefile::ConfigureFile(const char* infile, const char* outfile,
{
cmSystemTools::SetPermissions(soutfile.c_str(), perm);
}
- cmSystemTools::RemoveFile(tempOutputFile.c_str());
+ cmSystemTools::RemoveFile(tempOutputFile);
}
return res;
}
-void cmMakefile::SetProperty(const char* prop, const char* value)
+void cmMakefile::SetProperty(const std::string& prop, const char* value)
{
- if (!prop)
- {
- return;
- }
-
- // handle special props
- std::string propname = prop;
-
- if ( propname == "LINK_DIRECTORIES" )
- {
- std::vector<std::string> varArgsExpanded;
- if(value)
- {
- cmSystemTools::ExpandListArgument(value, varArgsExpanded);
- }
- this->SetLinkDirectories(varArgsExpanded);
- return;
- }
- if (propname == "INCLUDE_DIRECTORIES")
- {
- this->IncludeDirectoriesEntries.clear();
- if (!value)
- {
- return;
- }
- cmListFileBacktrace lfbt;
- this->GetBacktrace(lfbt);
- this->IncludeDirectoriesEntries.push_back(
- cmValueWithOrigin(value, lfbt));
- return;
- }
- if (propname == "COMPILE_OPTIONS")
- {
- this->CompileOptionsEntries.clear();
- if (!value)
- {
- return;
- }
- cmListFileBacktrace lfbt;
- this->GetBacktrace(lfbt);
- this->CompileOptionsEntries.push_back(cmValueWithOrigin(value, lfbt));
- return;
- }
- if (propname == "COMPILE_DEFINITIONS")
- {
- this->CompileDefinitionsEntries.clear();
- if (!value)
- {
- return;
- }
- cmListFileBacktrace lfbt;
- this->GetBacktrace(lfbt);
- cmValueWithOrigin entry(value, lfbt);
- this->CompileDefinitionsEntries.push_back(entry);
- return;
- }
-
- if ( propname == "INCLUDE_REGULAR_EXPRESSION" )
- {
- this->SetIncludeRegularExpression(value);
- return;
- }
-
- if ( propname == "ADDITIONAL_MAKE_CLEAN_FILES" )
- {
- // This property is not inherrited
- if ( strcmp(this->GetCurrentDirectory(),
- this->GetStartDirectory()) != 0 )
- {
- return;
- }
- }
-
- this->Properties.SetProperty(prop,value,cmProperty::DIRECTORY);
+ cmListFileBacktrace lfbt = this->GetBacktrace();
+ this->StateSnapshot.GetDirectory().SetProperty(prop, value, lfbt);
}
-void cmMakefile::AppendProperty(const char* prop, const char* value,
+void cmMakefile::AppendProperty(const std::string& prop,
+ const char* value,
bool asString)
{
- if (!prop)
- {
- return;
- }
-
- // handle special props
- std::string propname = prop;
-
- if (propname == "INCLUDE_DIRECTORIES")
- {
- cmListFileBacktrace lfbt;
- this->GetBacktrace(lfbt);
- this->IncludeDirectoriesEntries.push_back(
- cmValueWithOrigin(value, lfbt));
- return;
- }
- if (propname == "COMPILE_OPTIONS")
- {
- cmListFileBacktrace lfbt;
- this->GetBacktrace(lfbt);
- this->CompileOptionsEntries.push_back(
- cmValueWithOrigin(value, lfbt));
- return;
- }
- if (propname == "COMPILE_DEFINITIONS")
- {
- cmListFileBacktrace lfbt;
- this->GetBacktrace(lfbt);
- this->CompileDefinitionsEntries.push_back(
- cmValueWithOrigin(value, lfbt));
- return;
- }
- if ( propname == "LINK_DIRECTORIES" )
- {
- std::vector<std::string> varArgsExpanded;
- cmSystemTools::ExpandListArgument(value, varArgsExpanded);
- for(std::vector<std::string>::const_iterator vi = varArgsExpanded.begin();
- vi != varArgsExpanded.end(); ++vi)
- {
- this->AddLinkDirectory(vi->c_str());
- }
- return;
- }
-
- this->Properties.AppendProperty(prop,value,cmProperty::DIRECTORY,asString);
+ cmListFileBacktrace lfbt = this->GetBacktrace();
+ this->StateSnapshot.GetDirectory().AppendProperty(prop, value,
+ asString, lfbt);
}
-const char *cmMakefile::GetPropertyOrDefinition(const char* prop)
+const char *cmMakefile::GetProperty(const std::string& prop) const
{
- const char *ret = this->GetProperty(prop, cmProperty::DIRECTORY);
- if (!ret)
- {
- ret = this->GetDefinition(prop);
- }
- return ret;
+ return this->StateSnapshot.GetDirectory().GetProperty(prop);
}
-const char *cmMakefile::GetProperty(const char* prop)
+const char *cmMakefile::GetProperty(const std::string& prop,
+ bool chain) const
{
- return this->GetProperty(prop, cmProperty::DIRECTORY);
+ return this->StateSnapshot.GetDirectory().GetProperty(prop, chain);
}
-const char *cmMakefile::GetProperty(const char* prop,
- cmProperty::ScopeType scope)
-{
- if(!prop)
- {
- return 0;
- }
- // watch for specific properties
- static std::string output;
- output = "";
- if (!strcmp("PARENT_DIRECTORY",prop))
- {
- if(cmLocalGenerator* plg = this->LocalGenerator->GetParent())
- {
- output = plg->GetMakefile()->GetStartDirectory();
- }
- return output.c_str();
- }
- else if (!strcmp("INCLUDE_REGULAR_EXPRESSION",prop) )
- {
- output = this->GetIncludeRegularExpression();
- return output.c_str();
- }
- else if (!strcmp("LISTFILE_STACK",prop))
- {
- for (std::deque<cmStdString>::iterator i = this->ListFileStack.begin();
- i != this->ListFileStack.end(); ++i)
- {
- if (i != this->ListFileStack.begin())
- {
- output += ";";
- }
- output += *i;
- }
- return output.c_str();
- }
- else if (!strcmp("VARIABLES",prop) || !strcmp("CACHE_VARIABLES",prop))
- {
- int cacheonly = 0;
- if ( !strcmp("CACHE_VARIABLES",prop) )
- {
- cacheonly = 1;
- }
- std::vector<std::string> vars = this->GetDefinitions(cacheonly);
- for (unsigned int cc = 0; cc < vars.size(); cc ++ )
- {
- if ( cc > 0 )
- {
- output += ";";
- }
- output += vars[cc];
- }
- return output.c_str();
- }
- else if (!strcmp("MACROS",prop))
- {
- this->GetListOfMacros(output);
- return output.c_str();
- }
- else if (!strcmp("DEFINITIONS",prop))
- {
- output += this->DefineFlagsOrig;
- return output.c_str();
- }
- else if (!strcmp("LINK_DIRECTORIES",prop))
- {
- cmOStringStream str;
- for (std::vector<std::string>::const_iterator
- it = this->GetLinkDirectories().begin();
- it != this->GetLinkDirectories().end();
- ++ it )
- {
- if ( it != this->GetLinkDirectories().begin())
- {
- str << ";";
- }
- str << it->c_str();
- }
- output = str.str();
- return output.c_str();
- }
- else if (!strcmp("INCLUDE_DIRECTORIES",prop))
- {
- std::string sep;
- for (std::vector<cmValueWithOrigin>::const_iterator
- it = this->IncludeDirectoriesEntries.begin(),
- end = this->IncludeDirectoriesEntries.end();
- it != end; ++it)
- {
- output += sep;
- output += it->Value;
- sep = ";";
- }
- return output.c_str();
- }
- else if (!strcmp("COMPILE_OPTIONS",prop))
- {
- std::string sep;
- for (std::vector<cmValueWithOrigin>::const_iterator
- it = this->CompileOptionsEntries.begin(),
- end = this->CompileOptionsEntries.end();
- it != end; ++it)
- {
- output += sep;
- output += it->Value;
- sep = ";";
- }
- return output.c_str();
- }
- else if (!strcmp("COMPILE_DEFINITIONS",prop))
- {
- std::string sep;
- for (std::vector<cmValueWithOrigin>::const_iterator
- it = this->CompileDefinitionsEntries.begin(),
- end = this->CompileDefinitionsEntries.end();
- it != end; ++it)
- {
- output += sep;
- output += it->Value;
- sep = ";";
- }
- return output.c_str();
- }
-
- bool chain = false;
- const char *retVal =
- this->Properties.GetPropertyValue(prop, scope, chain);
- if (chain)
- {
- if(this->LocalGenerator->GetParent())
- {
- return this->LocalGenerator->GetParent()->GetMakefile()->
- GetProperty(prop, scope);
- }
- return this->GetCMakeInstance()->GetProperty(prop,scope);
- }
-
- return retVal;
-}
-
-bool cmMakefile::GetPropertyAsBool(const char* prop)
+bool cmMakefile::GetPropertyAsBool(const std::string& prop) const
{
return cmSystemTools::IsOn(this->GetProperty(prop));
}
-//----------------------------------------------------------------------------
-const char* cmMakefile::GetFeature(const char* feature, const char* config)
+std::vector<std::string> cmMakefile::GetPropertyKeys() const
{
- // TODO: Define accumulation policy for features (prepend, append, replace).
- // Currently we always replace.
- if(config && *config)
- {
- std::string featureConfig = feature;
- featureConfig += "_";
- featureConfig += cmSystemTools::UpperCase(config);
- if(const char* value = this->GetProperty(featureConfig.c_str()))
- {
- return value;
- }
- }
- if(const char* value = this->GetProperty(feature))
- {
- return value;
- }
- if(cmLocalGenerator* parent = this->LocalGenerator->GetParent())
- {
- return parent->GetMakefile()->GetFeature(feature, config);
- }
- return 0;
+ return this->StateSnapshot.GetDirectory().GetPropertyKeys();
}
-cmTarget* cmMakefile::FindTarget(const char* name, bool excludeAliases)
+cmTarget* cmMakefile::FindTarget(const std::string& name,
+ bool excludeAliases) const
{
if (!excludeAliases)
{
- std::map<std::string, cmTarget*>::iterator i
- = this->AliasTargets.find(name);
+ std::map<std::string, std::string>::const_iterator i =
+ this->AliasTargets.find(name);
if (i != this->AliasTargets.end())
{
- return i->second;
+ cmTargets::iterator ai = this->Targets.find(i->second);
+ return &ai->second;
}
}
- cmTargets& tgts = this->GetTargets();
-
- cmTargets::iterator i = tgts.find ( name );
- if ( i != tgts.end() )
+ cmTargets::iterator i = this->Targets.find( name );
+ if ( i != this->Targets.end() )
{
return &i->second;
}
@@ -3887,12 +4081,8 @@ cmTarget* cmMakefile::FindTarget(const char* name, bool excludeAliases)
}
//----------------------------------------------------------------------------
-cmTest* cmMakefile::CreateTest(const char* testName)
+cmTest* cmMakefile::CreateTest(const std::string& testName)
{
- if ( !testName )
- {
- return 0;
- }
cmTest* test = this->GetTest(testName);
if ( test )
{
@@ -3905,30 +4095,59 @@ cmTest* cmMakefile::CreateTest(const char* testName)
}
//----------------------------------------------------------------------------
-cmTest* cmMakefile::GetTest(const char* testName) const
+cmTest* cmMakefile::GetTest(const std::string& testName) const
+{
+ std::map<std::string, cmTest*>::const_iterator
+ mi = this->Tests.find(testName);
+ if(mi != this->Tests.end())
+ {
+ return mi->second;
+ }
+ return 0;
+}
+
+void cmMakefile::AddCMakeDependFilesFromUser()
{
- if(testName)
+ std::vector<std::string> deps;
+ if(const char* deps_str = this->GetProperty("CMAKE_CONFIGURE_DEPENDS"))
+ {
+ cmSystemTools::ExpandListArgument(deps_str, deps);
+ }
+ for(std::vector<std::string>::iterator i = deps.begin();
+ i != deps.end(); ++i)
{
- std::map<cmStdString, cmTest*>::const_iterator
- mi = this->Tests.find(testName);
- if(mi != this->Tests.end())
+ if(cmSystemTools::FileIsFullPath(i->c_str()))
+ {
+ this->AddCMakeDependFile(*i);
+ }
+ else
{
- return mi->second;
+ std::string f = this->GetCurrentSourceDirectory();
+ f += "/";
+ f += *i;
+ this->AddCMakeDependFile(f);
}
}
- return 0;
}
-std::string cmMakefile::GetListFileStack()
+std::string cmMakefile::FormatListFileStack() const
{
- cmOStringStream tmp;
- size_t depth = this->ListFileStack.size();
+ std::vector<std::string> listFiles;
+ cmState::Snapshot snp = this->StateSnapshot;
+ while (snp.IsValid())
+ {
+ listFiles.push_back(snp.GetExecutionListFile());
+ snp = snp.GetCallStackParent();
+ }
+ std::reverse(listFiles.begin(), listFiles.end());
+ std::ostringstream tmp;
+ size_t depth = listFiles.size();
if (depth > 0)
{
- std::deque<cmStdString>::iterator it = this->ListFileStack.end();
+ std::vector<std::string>::const_iterator it = listFiles.end();
do
{
- if (depth != this->ListFileStack.size())
+ if (depth != listFiles.size())
{
tmp << "\n ";
}
@@ -3939,7 +4158,7 @@ std::string cmMakefile::GetListFileStack()
tmp << *it;
depth--;
}
- while (it != this->ListFileStack.begin());
+ while (it != listFiles.begin());
}
return tmp.str();
}
@@ -3947,351 +4166,67 @@ std::string cmMakefile::GetListFileStack()
void cmMakefile::PushScope()
{
- cmDefinitions* parent = &this->Internal->VarStack.top();
- const std::set<cmStdString>& init = this->Internal->VarInitStack.top();
- const std::set<cmStdString>& usage = this->Internal->VarUsageStack.top();
- this->Internal->VarStack.push(cmDefinitions(parent));
- this->Internal->VarInitStack.push(init);
- this->Internal->VarUsageStack.push(usage);
+ std::string commandName;
+ long line = 0;
+ if (!this->ContextStack.empty())
+ {
+ commandName = this->ContextStack.back()->Name;
+ line = this->ContextStack.back()->Line;
+ }
+ this->StateSnapshot = this->GetState()->CreateVariableScopeSnapshot(
+ this->StateSnapshot,
+ commandName,
+ line);
+ this->PushLoopBlockBarrier();
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ this->GetGlobalGenerator()->GetFileLockPool().PushFunctionScope();
+#endif
}
void cmMakefile::PopScope()
{
- cmDefinitions* current = &this->Internal->VarStack.top();
- std::set<cmStdString> init = this->Internal->VarInitStack.top();
- std::set<cmStdString> usage = this->Internal->VarUsageStack.top();
- const std::set<cmStdString>& locals = current->LocalKeys();
- // Remove initialization and usage information for variables in the local
- // scope.
- std::set<cmStdString>::const_iterator it = locals.begin();
- for (; it != locals.end(); ++it)
- {
- init.erase(*it);
- if (!this->VariableUsed(it->c_str()))
- {
- this->CheckForUnused("out of scope", it->c_str());
- }
- else
- {
- usage.erase(*it);
- }
- }
- this->Internal->VarStack.pop();
- this->Internal->VarInitStack.pop();
- this->Internal->VarUsageStack.pop();
- // Push initialization and usage up to the parent scope.
- it = init.begin();
- for (; it != init.end(); ++it)
- {
- this->Internal->VarInitStack.top().insert(*it);
- }
- it = usage.begin();
- for (; it != usage.end(); ++it)
- {
- this->Internal->VarUsageStack.top().insert(*it);
- }
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ this->GetGlobalGenerator()->GetFileLockPool().PopFunctionScope();
+#endif
+
+ this->PopLoopBlockBarrier();
+
+ this->CheckForUnusedVariables();
+
+ this->PopSnapshot();
}
-void cmMakefile::RaiseScope(const char *var, const char *varDef)
+void cmMakefile::RaiseScope(const std::string& var, const char *varDef)
{
- if (!var || !strlen(var))
+ if (var.empty())
{
return;
}
- cmDefinitions& cur = this->Internal->VarStack.top();
- if(cmDefinitions* up = cur.GetParent())
+ if (!this->StateSnapshot.RaiseScope(var, varDef))
{
- // First localize the definition in the current scope.
- cur.Get(var);
-
- // Now update the definition in the parent scope.
- up->Set(var, varDef);
- }
- else if(cmLocalGenerator* plg = this->LocalGenerator->GetParent())
- {
- // Update the definition in the parent directory top scope. This
- // directory's scope was initialized by the closure of the parent
- // scope, so we do not need to localize the definition first.
- cmMakefile* parent = plg->GetMakefile();
- if (varDef)
- {
- parent->AddDefinition(var, varDef);
- }
- else
- {
- parent->RemoveDefinition(var);
- }
- }
- else
- {
- cmOStringStream m;
+ std::ostringstream m;
m << "Cannot set \"" << var << "\": current scope has no parent.";
this->IssueMessage(cmake::AUTHOR_WARNING, m.str());
}
}
-
-// define properties
-void cmMakefile::DefineProperties(cmake *cm)
-{
- cm->DefineProperty
- ("ADDITIONAL_MAKE_CLEAN_FILES", cmProperty::DIRECTORY,
- "Additional files to clean during the make clean stage.",
- "A list of files that will be cleaned as a part of the "
- "\"make clean\" stage. ");
-
- cm->DefineProperty
- ("CLEAN_NO_CUSTOM", cmProperty::DIRECTORY,
- "Should the output of custom commands be left.",
- "If this is true then the outputs of custom commands for this "
- "directory will not be removed during the \"make clean\" stage. ");
-
- cm->DefineProperty
- ("LISTFILE_STACK", cmProperty::DIRECTORY,
- "The current stack of listfiles being processed.",
- "This property is mainly useful when trying to debug errors "
- "in your CMake scripts. It returns a list of what list files "
- "are currently being processed, in order. So if one listfile "
- "does an INCLUDE command then that is effectively pushing "
- "the included listfile onto the stack.", false);
-
- cm->DefineProperty
- ("TEST_INCLUDE_FILE", cmProperty::DIRECTORY,
- "A cmake file that will be included when ctest is run.",
- "If you specify TEST_INCLUDE_FILE, that file will be "
- "included and processed when ctest is run on the directory.");
-
- cm->DefineProperty
- ("COMPILE_DEFINITIONS", cmProperty::DIRECTORY,
- "Preprocessor definitions for compiling a directory's sources.",
- "The COMPILE_DEFINITIONS property may be set to a "
- "semicolon-separated list of preprocessor "
- "definitions using the syntax VAR or VAR=value. Function-style "
- "definitions are not supported. CMake will automatically escape "
- "the value correctly for the native build system (note that CMake "
- "language syntax may require escapes to specify some values). "
- "This property may be set on a per-configuration basis using the name "
- "COMPILE_DEFINITIONS_<CONFIG> where <CONFIG> is an upper-case name "
- "(ex. \"COMPILE_DEFINITIONS_DEBUG\"). "
- "This property will be initialized in each directory by its value "
- "in the directory's parent.\n"
- "CMake will automatically drop some definitions that "
- "are not supported by the native build tool. "
- "The VS6 IDE does not support definition values with spaces "
- "(but NMake does).\n"
- CM_DOCUMENT_COMPILE_DEFINITIONS_DISCLAIMER);
-
- cm->DefineProperty
- ("COMPILE_DEFINITIONS_<CONFIG>", cmProperty::DIRECTORY,
- "Per-configuration preprocessor definitions in a directory.",
- "This is the configuration-specific version of COMPILE_DEFINITIONS. "
- "This property will be initialized in each directory by its value "
- "in the directory's parent.\n");
-
- cm->DefineProperty
- ("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM", cmProperty::DIRECTORY,
- "Specify #include line transforms for dependencies in a directory.",
- "This property specifies rules to transform macro-like #include lines "
- "during implicit dependency scanning of C and C++ source files. "
- "The list of rules must be semicolon-separated with each entry of "
- "the form \"A_MACRO(%)=value-with-%\" (the % must be literal). "
- "During dependency scanning occurrences of A_MACRO(...) on #include "
- "lines will be replaced by the value given with the macro argument "
- "substituted for '%'. For example, the entry\n"
- " MYDIR(%)=<mydir/%>\n"
- "will convert lines of the form\n"
- " #include MYDIR(myheader.h)\n"
- "to\n"
- " #include <mydir/myheader.h>\n"
- "allowing the dependency to be followed.\n"
- "This property applies to sources in all targets within a directory. "
- "The property value is initialized in each directory by its value "
- "in the directory's parent.");
-
- cm->DefineProperty
- ("EXCLUDE_FROM_ALL", cmProperty::DIRECTORY,
- "Exclude the directory from the all target of its parent.",
- "A property on a directory that indicates if its targets are excluded "
- "from the default build target. If it is not, then with a Makefile "
- "for example typing make will cause the targets to be built. "
- "The same concept applies to the default build of other generators.",
- false);
-
- cm->DefineProperty
- ("PARENT_DIRECTORY", cmProperty::DIRECTORY,
- "Source directory that added current subdirectory.",
- "This read-only property specifies the source directory that "
- "added the current source directory as a subdirectory of the build. "
- "In the top-level directory the value is the empty-string.", false);
-
- cm->DefineProperty
- ("INCLUDE_REGULAR_EXPRESSION", cmProperty::DIRECTORY,
- "Include file scanning regular expression.",
- "This read-only property specifies the regular expression used "
- "during dependency scanning to match include files that should "
- "be followed. See the include_regular_expression command.", false);
-
- cm->DefineProperty
- ("INTERPROCEDURAL_OPTIMIZATION", cmProperty::DIRECTORY,
- "Enable interprocedural optimization for targets in a directory.",
- "If set to true, enables interprocedural optimizations "
- "if they are known to be supported by the compiler.");
-
- cm->DefineProperty
- ("INTERPROCEDURAL_OPTIMIZATION_<CONFIG>", cmProperty::DIRECTORY,
- "Per-configuration interprocedural optimization for a directory.",
- "This is a per-configuration version of INTERPROCEDURAL_OPTIMIZATION. "
- "If set, this property overrides the generic property "
- "for the named configuration.");
-
- cm->DefineProperty
- ("VARIABLES", cmProperty::DIRECTORY,
- "List of variables defined in the current directory.",
- "This read-only property specifies the list of CMake variables "
- "currently defined. "
- "It is intended for debugging purposes.", false);
-
- cm->DefineProperty
- ("CACHE_VARIABLES", cmProperty::DIRECTORY,
- "List of cache variables available in the current directory.",
- "This read-only property specifies the list of CMake cache "
- "variables currently defined. "
- "It is intended for debugging purposes.", false);
-
- cm->DefineProperty
- ("MACROS", cmProperty::DIRECTORY,
- "List of macro commands available in the current directory.",
- "This read-only property specifies the list of CMake macros "
- "currently defined. "
- "It is intended for debugging purposes. "
- "See the macro command.", false);
-
- cm->DefineProperty
- ("DEFINITIONS", cmProperty::DIRECTORY,
- "For CMake 2.4 compatibility only. Use COMPILE_DEFINITIONS instead.",
- "This read-only property specifies the list of flags given so far "
- "to the add_definitions command. "
- "It is intended for debugging purposes. "
- "Use the COMPILE_DEFINITIONS instead.", false);
-
- cm->DefineProperty
- ("INCLUDE_DIRECTORIES", cmProperty::DIRECTORY,
- "List of preprocessor include file search directories.",
- "This property specifies the list of directories given "
- "so far to the include_directories command. "
- "This property exists on directories and targets. "
- "In addition to accepting values from the include_directories "
- "command, values may be set directly on any directory or any "
- "target using the set_property command. "
- "A target gets its initial value for this property from the value "
- "of the directory property. "
- "A directory gets its initial value from its parent directory if "
- "it has one. "
- "Both directory and target property values are adjusted by calls "
- "to the include_directories command."
- "\n"
- "The target property values are used by the generators to set "
- "the include paths for the compiler. "
- "See also the include_directories command.");
-
- cm->DefineProperty
- ("COMPILE_OPTIONS", cmProperty::DIRECTORY,
- "List of options to pass to the compiler.",
- "This property specifies the list of directories given "
- "so far for this property. "
- "This property exists on directories and targets."
- "\n"
- "The target property values are used by the generators to set "
- "the options for the compiler.\n"
- "Contents of COMPILE_OPTIONS may use \"generator expressions\" with "
- "the syntax \"$<...>\". "
- CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS);
-
- cm->DefineProperty
- ("LINK_DIRECTORIES", cmProperty::DIRECTORY,
- "List of linker search directories.",
- "This read-only property specifies the list of directories given "
- "so far to the link_directories command. "
- "It is intended for debugging purposes.", false);
-
- cm->DefineProperty
- ("RULE_LAUNCH_COMPILE", cmProperty::DIRECTORY,
- "Specify a launcher for compile rules.",
- "See the global property of the same name for details. "
- "This overrides the global property for a directory.",
- true);
- cm->DefineProperty
- ("RULE_LAUNCH_LINK", cmProperty::DIRECTORY,
- "Specify a launcher for link rules.",
- "See the global property of the same name for details. "
- "This overrides the global property for a directory.",
- true);
- cm->DefineProperty
- ("RULE_LAUNCH_CUSTOM", cmProperty::DIRECTORY,
- "Specify a launcher for custom rules.",
- "See the global property of the same name for details. "
- "This overrides the global property for a directory.",
- true);
-
- cm->DefineProperty
- ("VS_GLOBAL_SECTION_PRE_<section>", cmProperty::DIRECTORY,
- "Specify a preSolution global section in Visual Studio.",
- "Setting a property like this generates an entry of the following form "
- "in the solution file:\n"
- " GlobalSection(<section>) = preSolution\n"
- " <contents based on property value>\n"
- " EndGlobalSection\n"
- "The property must be set to a semicolon-separated list of key=value "
- "pairs. Each such pair will be transformed into an entry in the solution "
- "global section. Whitespace around key and value is ignored. List "
- "elements which do not contain an equal sign are skipped."
- "\n"
- "This property only works for Visual Studio 7 and above; it is ignored "
- "on other generators. The property only applies when set on a directory "
- "whose CMakeLists.txt contains a project() command.");
- cm->DefineProperty
- ("VS_GLOBAL_SECTION_POST_<section>", cmProperty::DIRECTORY,
- "Specify a postSolution global section in Visual Studio.",
- "Setting a property like this generates an entry of the following form "
- "in the solution file:\n"
- " GlobalSection(<section>) = postSolution\n"
- " <contents based on property value>\n"
- " EndGlobalSection\n"
- "The property must be set to a semicolon-separated list of key=value "
- "pairs. Each such pair will be transformed into an entry in the solution "
- "global section. Whitespace around key and value is ignored. List "
- "elements which do not contain an equal sign are skipped."
- "\n"
- "This property only works for Visual Studio 7 and above; it is ignored "
- "on other generators. The property only applies when set on a directory "
- "whose CMakeLists.txt contains a project() command."
- "\n"
- "Note that CMake generates postSolution sections ExtensibilityGlobals "
- "and ExtensibilityAddIns by default. If you set the corresponding "
- "property, it will override the default section. For example, setting "
- "VS_GLOBAL_SECTION_POST_ExtensibilityGlobals will override the default "
- "contents of the ExtensibilityGlobals section, while keeping "
- "ExtensibilityAddIns on its default.");
-}
-
//----------------------------------------------------------------------------
cmTarget*
-cmMakefile::AddImportedTarget(const char* name, cmTarget::TargetType type,
+cmMakefile::AddImportedTarget(const std::string& name,
+ cmState::TargetType type,
bool global)
{
// Create the target.
cmsys::auto_ptr<cmTarget> target(new cmTarget);
target->SetType(type, name);
+ target->MarkAsImported(global);
target->SetMakefile(this);
- target->MarkAsImported();
// Add to the set of available imported targets.
this->ImportedTargets[name] = target.get();
- if(global)
- {
- this->LocalGenerator->GetGlobalGenerator()->AddTarget(target.get());
- }
+ this->GetGlobalGenerator()->IndexTarget(target.get());
// Transfer ownership to this cmMakefile object.
this->ImportedTargetsOwned.push_back(target.get());
@@ -4299,11 +4234,12 @@ cmMakefile::AddImportedTarget(const char* name, cmTarget::TargetType type,
}
//----------------------------------------------------------------------------
-cmTarget* cmMakefile::FindTargetToUse(const char* name, bool excludeAliases)
+cmTarget* cmMakefile::FindTargetToUse(const std::string& name,
+ bool excludeAliases) const
{
// Look for an imported target. These take priority because they
// are more local in scope and do not have to be globally unique.
- std::map<cmStdString, cmTarget*>::const_iterator
+ TargetMap::const_iterator
imported = this->ImportedTargets.find(name);
if(imported != this->ImportedTargets.end())
{
@@ -4317,38 +4253,30 @@ cmTarget* cmMakefile::FindTargetToUse(const char* name, bool excludeAliases)
}
// Look for a target built in this project.
- return this->LocalGenerator->GetGlobalGenerator()->FindTarget(0, name,
- excludeAliases);
+ return this->GetGlobalGenerator()->FindTarget(name, excludeAliases);
}
//----------------------------------------------------------------------------
-bool cmMakefile::IsAlias(const char *name)
+bool cmMakefile::IsAlias(const std::string& name) const
{
if (this->AliasTargets.find(name) != this->AliasTargets.end())
return true;
- return this->GetLocalGenerator()->GetGlobalGenerator()->IsAlias(name);
-}
-
-//----------------------------------------------------------------------------
-cmGeneratorTarget* cmMakefile::FindGeneratorTargetToUse(const char* name)
-{
- cmTarget *t = this->FindTargetToUse(name);
- return this->LocalGenerator->GetGlobalGenerator()->GetGeneratorTarget(t);
+ return this->GetGlobalGenerator()->IsAlias(name);
}
//----------------------------------------------------------------------------
bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg,
- bool isCustom)
+ bool isCustom) const
{
- if(this->IsAlias(name.c_str()))
+ if(this->IsAlias(name))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "cannot create target \"" << name
<< "\" because an alias with the same name already exists.";
msg = e.str();
return false;
}
- if(cmTarget* existing = this->FindTargetToUse(name.c_str()))
+ if(cmTarget* existing = this->FindTargetToUse(name))
{
// The name given conflicts with an existing target. Produce an
// error in a compatible way.
@@ -4356,7 +4284,7 @@ bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg,
{
// Imported targets were not supported in previous versions.
// This is new code, so we can make it an error.
- cmOStringStream e;
+ std::ostringstream e;
e << "cannot create target \"" << name
<< "\" because an imported target with the same name already exists.";
msg = e.str();
@@ -4368,14 +4296,14 @@ bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg,
switch (this->GetPolicyStatus(cmPolicies::CMP0002))
{
case cmPolicies::WARN:
- this->IssueMessage(cmake::AUTHOR_WARNING, this->GetPolicies()->
+ this->IssueMessage(cmake::AUTHOR_WARNING, cmPolicies::
GetPolicyWarning(cmPolicies::CMP0002));
case cmPolicies::OLD:
return true;
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
this->IssueMessage(cmake::FATAL_ERROR,
- this->GetPolicies()->GetRequiredPolicyError(cmPolicies::CMP0002)
+ cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0002)
);
return true;
case cmPolicies::NEW:
@@ -4384,42 +4312,45 @@ bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg,
// The conflict is with a non-imported target.
// Allow this if the user has requested support.
- cmake* cm =
- this->LocalGenerator->GetGlobalGenerator()->GetCMakeInstance();
- if(isCustom && existing->GetType() == cmTarget::UTILITY &&
+ cmake* cm = this->GetCMakeInstance();
+ if(isCustom && existing->GetType() == cmState::UTILITY &&
this != existing->GetMakefile() &&
- cm->GetPropertyAsBool("ALLOW_DUPLICATE_CUSTOM_TARGETS"))
+ cm->GetState()
+ ->GetGlobalPropertyAsBool("ALLOW_DUPLICATE_CUSTOM_TARGETS"))
{
return true;
}
// Produce an error that tells the user how to work around the
// problem.
- cmOStringStream e;
+ std::ostringstream e;
e << "cannot create target \"" << name
<< "\" because another target with the same name already exists. "
<< "The existing target is ";
switch(existing->GetType())
{
- case cmTarget::EXECUTABLE:
+ case cmState::EXECUTABLE:
e << "an executable ";
break;
- case cmTarget::STATIC_LIBRARY:
+ case cmState::STATIC_LIBRARY:
e << "a static library ";
break;
- case cmTarget::SHARED_LIBRARY:
+ case cmState::SHARED_LIBRARY:
e << "a shared library ";
break;
- case cmTarget::MODULE_LIBRARY:
+ case cmState::MODULE_LIBRARY:
e << "a module library ";
break;
- case cmTarget::UTILITY:
+ case cmState::UTILITY:
e << "a custom target ";
break;
+ case cmState::INTERFACE_LIBRARY:
+ e << "an interface library ";
+ break;
default: break;
}
e << "created in source directory \""
- << existing->GetMakefile()->GetCurrentDirectory() << "\". "
+ << existing->GetMakefile()->GetCurrentSourceDirectory() << "\". "
<< "See documentation for policy CMP0002 for more details.";
msg = e.str();
return false;
@@ -4429,20 +4360,21 @@ bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg,
}
//----------------------------------------------------------------------------
-bool cmMakefile::EnforceUniqueDir(const char* srcPath, const char* binPath)
+bool cmMakefile::EnforceUniqueDir(const std::string& srcPath,
+ const std::string& binPath) const
{
// Make sure the binary directory is unique.
- cmGlobalGenerator* gg = this->LocalGenerator->GetGlobalGenerator();
+ cmGlobalGenerator* gg = this->GetGlobalGenerator();
if(gg->BinaryDirectoryIsNew(binPath))
{
return true;
}
- cmOStringStream e;
+ std::ostringstream e;
switch (this->GetPolicyStatus(cmPolicies::CMP0013))
{
case cmPolicies::WARN:
// Print the warning.
- e << this->GetPolicies()->GetPolicyWarning(cmPolicies::CMP0013)
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0013)
<< "\n"
<< "The binary directory\n"
<< " " << binPath << "\n"
@@ -4459,7 +4391,7 @@ bool cmMakefile::EnforceUniqueDir(const char* srcPath, const char* binPath)
return true;
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
- e << this->GetPolicies()->GetRequiredPolicyError(cmPolicies::CMP0013)
+ e << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0013)
<< "\n";
case cmPolicies::NEW:
// NEW behavior prints the error.
@@ -4477,66 +4409,116 @@ bool cmMakefile::EnforceUniqueDir(const char* srcPath, const char* binPath)
}
//----------------------------------------------------------------------------
-cmPolicies::PolicyStatus
-cmMakefile::GetPolicyStatus(cmPolicies::PolicyID id)
+void cmMakefile::AddQtUiFileWithOptions(cmSourceFile *sf)
{
- // Get the current setting of the policy.
- cmPolicies::PolicyStatus cur = this->GetPolicyStatusInternal(id);
+ this->QtUiFilesWithOptions.push_back(sf);
+}
+
+//----------------------------------------------------------------------------
+std::vector<cmSourceFile*> cmMakefile::GetQtUiFilesWithOptions() const
+{
+ return this->QtUiFilesWithOptions;
+}
+
+static std::string const matchVariables[] = {
+ "CMAKE_MATCH_0",
+ "CMAKE_MATCH_1",
+ "CMAKE_MATCH_2",
+ "CMAKE_MATCH_3",
+ "CMAKE_MATCH_4",
+ "CMAKE_MATCH_5",
+ "CMAKE_MATCH_6",
+ "CMAKE_MATCH_7",
+ "CMAKE_MATCH_8",
+ "CMAKE_MATCH_9"
+};
+
+static std::string const nMatchesVariable = "CMAKE_MATCH_COUNT";
- // If the policy is required to be set to NEW but is not, ignore the
- // current setting and tell the caller.
- if(cur != cmPolicies::NEW)
+//----------------------------------------------------------------------------
+void cmMakefile::ClearMatches()
+{
+ const char* nMatchesStr = this->GetDefinition(nMatchesVariable);
+ if (!nMatchesStr)
{
- if(cur == cmPolicies::REQUIRED_ALWAYS ||
- cur == cmPolicies::REQUIRED_IF_USED)
+ return;
+ }
+ int nMatches = atoi(nMatchesStr);
+ for (int i=0; i<=nMatches; i++)
+ {
+ std::string const& var = matchVariables[i];
+ std::string const& s = this->GetSafeDefinition(var);
+ if(!s.empty())
{
- return cur;
+ this->AddDefinition(var, "");
+ this->MarkVariableAsUsed(var);
}
- cmPolicies::PolicyStatus def = this->GetPolicies()->GetPolicyStatus(id);
- if(def == cmPolicies::REQUIRED_ALWAYS ||
- def == cmPolicies::REQUIRED_IF_USED)
+ }
+ this->AddDefinition(nMatchesVariable, "0");
+ this->MarkVariableAsUsed(nMatchesVariable);
+}
+
+//----------------------------------------------------------------------------
+void cmMakefile::StoreMatches(cmsys::RegularExpression& re)
+{
+ char highest = 0;
+ for (int i=0; i<10; i++)
+ {
+ std::string const& m = re.match(i);
+ if(!m.empty())
{
- return def;
+ std::string const& var = matchVariables[i];
+ this->AddDefinition(var, m.c_str());
+ this->MarkVariableAsUsed(var);
+ highest = static_cast<char>('0' + i);
}
}
+ char nMatches[] = {highest, '\0'};
+ this->AddDefinition(nMatchesVariable, nMatches);
+ this->MarkVariableAsUsed(nMatchesVariable);
+}
- // The current setting is okay.
- return cur;
+cmState::Snapshot cmMakefile::GetStateSnapshot() const
+{
+ return this->StateSnapshot;
+}
+
+const char* cmMakefile::GetDefineFlagsCMP0059() const
+{
+ return this->DefineFlagsOrig.c_str();
}
//----------------------------------------------------------------------------
cmPolicies::PolicyStatus
-cmMakefile::GetPolicyStatusInternal(cmPolicies::PolicyID id)
+cmMakefile::GetPolicyStatus(cmPolicies::PolicyID id) const
+{
+ return this->StateSnapshot.GetPolicy(id);
+}
+
+//----------------------------------------------------------------------------
+bool cmMakefile::PolicyOptionalWarningEnabled(std::string const& var)
{
- // Is the policy set in our stack?
- for(PolicyStackType::reverse_iterator psi = this->PolicyStack.rbegin();
- psi != this->PolicyStack.rend(); ++psi)
+ // Check for an explicit CMAKE_POLICY_WARNING_CMP<NNNN> setting.
+ if(!var.empty())
{
- PolicyStackEntry::const_iterator pse = psi->find(id);
- if(pse != psi->end())
+ if(const char* val = this->GetDefinition(var))
{
- return pse->second;
+ return cmSystemTools::IsOn(val);
}
}
-
- // If we have a parent directory, recurse up to it.
- if(this->LocalGenerator->GetParent())
- {
- cmMakefile* parent = this->LocalGenerator->GetParent()->GetMakefile();
- return parent->GetPolicyStatusInternal(id);
- }
-
- // The policy is not set. Use the default for this CMake version.
- return this->GetPolicies()->GetPolicyStatus(id);
+ // Enable optional policy warnings with --debug-output, --trace,
+ // or --trace-expand.
+ cmake* cm = this->GetCMakeInstance();
+ return cm->GetDebugOutput() || cm->GetTrace();
}
bool cmMakefile::SetPolicy(const char *id,
cmPolicies::PolicyStatus status)
{
cmPolicies::PolicyID pid;
- if (!this->GetPolicies()->GetPolicyID(id, /* out */ pid))
+ if (!cmPolicies::GetPolicyID(id, /* out */ pid))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Policy \"" << id << "\" is not known to this version of CMake.";
this->IssueMessage(cmake::FATAL_ERROR, e.str());
return false;
@@ -4550,77 +4532,41 @@ bool cmMakefile::SetPolicy(cmPolicies::PolicyID id,
{
// A REQUIRED_ALWAYS policy may be set only to NEW.
if(status != cmPolicies::NEW &&
- this->GetPolicies()->GetPolicyStatus(id) ==
+ cmPolicies::GetPolicyStatus(id) ==
cmPolicies::REQUIRED_ALWAYS)
{
std::string msg =
- this->GetPolicies()->GetRequiredAlwaysPolicyError(id);
- this->IssueMessage(cmake::FATAL_ERROR, msg.c_str());
+ cmPolicies::GetRequiredAlwaysPolicyError(id);
+ this->IssueMessage(cmake::FATAL_ERROR, msg);
return false;
}
- // Update the policy stack from the top to the top-most strong entry.
- bool previous_was_weak = true;
- for(PolicyStackType::reverse_iterator psi = this->PolicyStack.rbegin();
- previous_was_weak && psi != this->PolicyStack.rend(); ++psi)
- {
- (*psi)[id] = status;
- previous_was_weak = psi->Weak;
- }
-
- // Special hook for presenting compatibility variable as soon as
- // the user requests it.
- if(id == cmPolicies::CMP0001 &&
- (status == cmPolicies::WARN || status == cmPolicies::OLD))
- {
- if(!(this->GetCacheManager()
- ->GetCacheValue("CMAKE_BACKWARDS_COMPATIBILITY")))
- {
- // Set it to 2.4 because that is the last version where the
- // variable had meaning.
- this->AddCacheDefinition
- ("CMAKE_BACKWARDS_COMPATIBILITY", "2.4",
- "For backwards compatibility, what version of CMake "
- "commands and "
- "syntax should this version of CMake try to support.",
- cmCacheManager::STRING);
- }
- }
-
+ this->StateSnapshot.SetPolicy(id, status);
return true;
}
//----------------------------------------------------------------------------
-cmMakefile::PolicyPushPop::PolicyPushPop(cmMakefile* m, bool weak,
- cmPolicies::PolicyMap const& pm):
- Makefile(m), ReportError(true)
+cmMakefile::PolicyPushPop::PolicyPushPop(cmMakefile* m): Makefile(m)
{
- this->Makefile->PushPolicy(weak, pm);
- this->Makefile->PushPolicyBarrier();
+ this->Makefile->PushPolicy();
}
//----------------------------------------------------------------------------
cmMakefile::PolicyPushPop::~PolicyPushPop()
{
- this->Makefile->PopPolicyBarrier(this->ReportError);
this->Makefile->PopPolicy();
}
//----------------------------------------------------------------------------
void cmMakefile::PushPolicy(bool weak, cmPolicies::PolicyMap const& pm)
{
- // Allocate a new stack entry.
- this->PolicyStack.push_back(PolicyStackEntry(pm, weak));
+ this->StateSnapshot.PushPolicy(pm, weak);
}
//----------------------------------------------------------------------------
void cmMakefile::PopPolicy()
{
- if(this->PolicyStack.size() > this->PolicyBarriers.back())
- {
- this->PolicyStack.pop_back();
- }
- else
+ if (!this->StateSnapshot.PopPolicy())
{
this->IssueMessage(cmake::FATAL_ERROR,
"cmake_policy POP without matching PUSH");
@@ -4628,17 +4574,12 @@ void cmMakefile::PopPolicy()
}
//----------------------------------------------------------------------------
-void cmMakefile::PushPolicyBarrier()
-{
- this->PolicyBarriers.push_back(this->PolicyStack.size());
-}
-
-//----------------------------------------------------------------------------
-void cmMakefile::PopPolicyBarrier(bool reportError)
+void cmMakefile::PopSnapshot(bool reportError)
{
- // Remove any extra entries pushed on the barrier.
- PolicyStackType::size_type barrier = this->PolicyBarriers.back();
- while(this->PolicyStack.size() > barrier)
+ // cmState::Snapshot manages nested policy scopes within it.
+ // Since the scope corresponding to the snapshot is closing,
+ // reject any still-open nested policy scopes with an error.
+ while (!this->StateSnapshot.CanPopPolicyScope())
{
if(reportError)
{
@@ -4649,23 +4590,21 @@ void cmMakefile::PopPolicyBarrier(bool reportError)
this->PopPolicy();
}
- // Remove the barrier.
- this->PolicyBarriers.pop_back();
+ this->StateSnapshot = this->GetState()->Pop(this->StateSnapshot);
+ assert(this->StateSnapshot.IsValid());
}
+//----------------------------------------------------------------------------
bool cmMakefile::SetPolicyVersion(const char *version)
{
- return this->GetCMakeInstance()->GetPolicies()->
- ApplyPolicyVersion(this,version);
+ return cmPolicies::ApplyPolicyVersion(this,version);
}
-cmPolicies *cmMakefile::GetPolicies()
+//----------------------------------------------------------------------------
+bool cmMakefile::HasCMP0054AlreadyBeenReported(
+ cmListFileContext const& context) const
{
- if (!this->GetCMakeInstance())
- {
- return 0;
- }
- return this->GetCMakeInstance()->GetPolicies();
+ return !this->CMP0054ReportedIds.insert(context).second;
}
//----------------------------------------------------------------------------
@@ -4676,6 +4615,593 @@ void cmMakefile::RecordPolicies(cmPolicies::PolicyMap& pm)
for(PolicyID pid = cmPolicies::CMP0000;
pid != cmPolicies::CMPCOUNT; pid = PolicyID(pid+1))
{
- pm[pid] = this->GetPolicyStatus(pid);
+ pm.Set(pid, this->GetPolicyStatus(pid));
}
}
+
+//----------------------------------------------------------------------------
+bool cmMakefile::IgnoreErrorsCMP0061() const
+{
+ bool ignoreErrors = true;
+ switch (this->GetPolicyStatus(cmPolicies::CMP0061))
+ {
+ case cmPolicies::WARN:
+ // No warning for this policy!
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ ignoreErrors = false;
+ break;
+ }
+ return ignoreErrors;
+}
+
+//----------------------------------------------------------------------------
+#define FEATURE_STRING(F) , #F
+static const char * const C_FEATURES[] = {
+ 0
+ FOR_EACH_C_FEATURE(FEATURE_STRING)
+};
+
+static const char * const CXX_FEATURES[] = {
+ 0
+ FOR_EACH_CXX_FEATURE(FEATURE_STRING)
+};
+#undef FEATURE_STRING
+
+static const char * const C_STANDARDS[] = {
+ "90"
+ , "99"
+ , "11"
+};
+static const char * const CXX_STANDARDS[] = {
+ "98"
+ , "11"
+ , "14"
+};
+
+//----------------------------------------------------------------------------
+bool cmMakefile::
+AddRequiredTargetFeature(cmTarget *target, const std::string& feature,
+ std::string *error) const
+{
+ if (cmGeneratorExpression::Find(feature) != std::string::npos)
+ {
+ target->AppendProperty("COMPILE_FEATURES", feature.c_str());
+ return true;
+ }
+
+ std::string lang;
+ if (!this->CompileFeatureKnown(target, feature, lang, error))
+ {
+ return false;
+ }
+
+ const char* features = this->CompileFeaturesAvailable(lang, error);
+ if (!features)
+ {
+ return false;
+ }
+
+ std::vector<std::string> availableFeatures;
+ cmSystemTools::ExpandListArgument(features, availableFeatures);
+ if (std::find(availableFeatures.begin(),
+ availableFeatures.end(),
+ feature) == availableFeatures.end())
+ {
+ std::ostringstream e;
+ e << "The compiler feature \"" << feature
+ << "\" is not known to " << lang << " compiler\n\""
+ << this->GetDefinition("CMAKE_" + lang + "_COMPILER_ID")
+ << "\"\nversion "
+ << this->GetDefinition("CMAKE_" + lang + "_COMPILER_VERSION") << ".";
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+
+ target->AppendProperty("COMPILE_FEATURES", feature.c_str());
+
+ return lang == "C"
+ ? this->AddRequiredTargetCFeature(target, feature)
+ : this->AddRequiredTargetCxxFeature(target, feature);
+}
+
+//----------------------------------------------------------------------------
+bool cmMakefile::
+CompileFeatureKnown(cmTarget const* target, const std::string& feature,
+ std::string& lang, std::string *error) const
+{
+ assert(cmGeneratorExpression::Find(feature) == std::string::npos);
+
+ bool isCFeature = std::find_if(cmArrayBegin(C_FEATURES) + 1,
+ cmArrayEnd(C_FEATURES), cmStrCmp(feature))
+ != cmArrayEnd(C_FEATURES);
+ if (isCFeature)
+ {
+ lang = "C";
+ return true;
+ }
+ bool isCxxFeature = std::find_if(cmArrayBegin(CXX_FEATURES) + 1,
+ cmArrayEnd(CXX_FEATURES), cmStrCmp(feature))
+ != cmArrayEnd(CXX_FEATURES);
+ if (isCxxFeature)
+ {
+ lang = "CXX";
+ return true;
+ }
+ std::ostringstream e;
+ if (error)
+ {
+ e << "specified";
+ }
+ else
+ {
+ e << "Specified";
+ }
+ e << " unknown feature \"" << feature << "\" for "
+ "target \"" << target->GetName() << "\".";
+ if (error)
+ {
+ *error = e.str();
+ }
+ else
+ {
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+const char* cmMakefile::
+CompileFeaturesAvailable(const std::string& lang, std::string *error) const
+{
+ const char* featuresKnown =
+ this->GetDefinition("CMAKE_" + lang + "_COMPILE_FEATURES");
+
+ if (!featuresKnown || !*featuresKnown)
+ {
+ std::ostringstream e;
+ if (error)
+ {
+ e << "no";
+ }
+ else
+ {
+ e << "No";
+ }
+ e << " known features for " << lang << " compiler\n\""
+ << this->GetDefinition("CMAKE_" + lang + "_COMPILER_ID")
+ << "\"\nversion "
+ << this->GetDefinition("CMAKE_" + lang + "_COMPILER_VERSION") << ".";
+ if (error)
+ {
+ *error = e.str();
+ }
+ else
+ {
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
+ }
+ return 0;
+ }
+ return featuresKnown;
+}
+
+//----------------------------------------------------------------------------
+bool cmMakefile::HaveStandardAvailable(cmTarget const* target,
+ std::string const& lang,
+ const std::string& feature) const
+{
+ return lang == "C"
+ ? this->HaveCStandardAvailable(target, feature)
+ : this->HaveCxxStandardAvailable(target, feature);
+}
+
+//----------------------------------------------------------------------------
+bool cmMakefile::
+HaveCStandardAvailable(cmTarget const* target,
+ const std::string& feature) const
+{
+ const char* defaultCStandard =
+ this->GetDefinition("CMAKE_C_STANDARD_DEFAULT");
+ if (!defaultCStandard)
+ {
+ std::ostringstream e;
+ e << "CMAKE_C_STANDARD_DEFAULT is not set. COMPILE_FEATURES support "
+ "not fully configured for this compiler.";
+ this->IssueMessage(cmake::INTERNAL_ERROR, e.str());
+ // Return true so the caller does not try to lookup the default standard.
+ return true;
+ }
+ if (std::find_if(cmArrayBegin(C_STANDARDS), cmArrayEnd(C_STANDARDS),
+ cmStrCmp(defaultCStandard)) == cmArrayEnd(C_STANDARDS))
+ {
+ std::ostringstream e;
+ e << "The CMAKE_C_STANDARD_DEFAULT variable contains an "
+ "invalid value: \"" << defaultCStandard << "\".";
+ this->IssueMessage(cmake::INTERNAL_ERROR, e.str());
+ return false;
+ }
+
+ bool needC90 = false;
+ bool needC99 = false;
+ bool needC11 = false;
+
+ this->CheckNeededCLanguage(feature, needC90, needC99, needC11);
+
+ const char *existingCStandard = target->GetProperty("C_STANDARD");
+ if (!existingCStandard)
+ {
+ existingCStandard = defaultCStandard;
+ }
+
+ if (std::find_if(cmArrayBegin(C_STANDARDS), cmArrayEnd(C_STANDARDS),
+ cmStrCmp(existingCStandard)) == cmArrayEnd(C_STANDARDS))
+ {
+ std::ostringstream e;
+ e << "The C_STANDARD property on target \"" << target->GetName()
+ << "\" contained an invalid value: \"" << existingCStandard << "\".";
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+
+ const char * const *existingCIt = existingCStandard
+ ? std::find_if(cmArrayBegin(C_STANDARDS),
+ cmArrayEnd(C_STANDARDS),
+ cmStrCmp(existingCStandard))
+ : cmArrayEnd(C_STANDARDS);
+
+ if (needC11 && existingCStandard && existingCIt <
+ std::find_if(cmArrayBegin(C_STANDARDS),
+ cmArrayEnd(C_STANDARDS),
+ cmStrCmp("11")))
+ {
+ return false;
+ }
+ else if(needC99 && existingCStandard && existingCIt <
+ std::find_if(cmArrayBegin(C_STANDARDS),
+ cmArrayEnd(C_STANDARDS),
+ cmStrCmp("99")))
+ {
+ return false;
+ }
+ else if(needC90 && existingCStandard && existingCIt <
+ std::find_if(cmArrayBegin(C_STANDARDS),
+ cmArrayEnd(C_STANDARDS),
+ cmStrCmp("90")))
+ {
+ return false;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmMakefile::IsLaterStandard(std::string const& lang,
+ std::string const& lhs,
+ std::string const& rhs)
+{
+ if (lang == "C")
+ {
+ const char * const *rhsIt = std::find_if(cmArrayBegin(C_STANDARDS),
+ cmArrayEnd(C_STANDARDS),
+ cmStrCmp(rhs));
+
+ return std::find_if(rhsIt, cmArrayEnd(C_STANDARDS),
+ cmStrCmp(lhs)) != cmArrayEnd(C_STANDARDS);
+ }
+ const char * const *rhsIt = std::find_if(cmArrayBegin(CXX_STANDARDS),
+ cmArrayEnd(CXX_STANDARDS),
+ cmStrCmp(rhs));
+
+ return std::find_if(rhsIt, cmArrayEnd(CXX_STANDARDS),
+ cmStrCmp(lhs)) != cmArrayEnd(CXX_STANDARDS);
+}
+
+//----------------------------------------------------------------------------
+bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
+ const std::string& feature) const
+{
+ const char* defaultCxxStandard =
+ this->GetDefinition("CMAKE_CXX_STANDARD_DEFAULT");
+ if (!defaultCxxStandard)
+ {
+ std::ostringstream e;
+ e << "CMAKE_CXX_STANDARD_DEFAULT is not set. COMPILE_FEATURES support "
+ "not fully configured for this compiler.";
+ this->IssueMessage(cmake::INTERNAL_ERROR, e.str());
+ // Return true so the caller does not try to lookup the default standard.
+ return true;
+ }
+ if (std::find_if(cmArrayBegin(CXX_STANDARDS), cmArrayEnd(CXX_STANDARDS),
+ cmStrCmp(defaultCxxStandard)) == cmArrayEnd(CXX_STANDARDS))
+ {
+ std::ostringstream e;
+ e << "The CMAKE_CXX_STANDARD_DEFAULT variable contains an "
+ "invalid value: \"" << defaultCxxStandard << "\".";
+ this->IssueMessage(cmake::INTERNAL_ERROR, e.str());
+ return false;
+ }
+
+ bool needCxx98 = false;
+ bool needCxx11 = false;
+ bool needCxx14 = false;
+ this->CheckNeededCxxLanguage(feature, needCxx98, needCxx11, needCxx14);
+
+ const char *existingCxxStandard = target->GetProperty("CXX_STANDARD");
+ if (!existingCxxStandard)
+ {
+ existingCxxStandard = defaultCxxStandard;
+ }
+
+ if (std::find_if(cmArrayBegin(CXX_STANDARDS), cmArrayEnd(CXX_STANDARDS),
+ cmStrCmp(existingCxxStandard)) == cmArrayEnd(CXX_STANDARDS))
+ {
+ std::ostringstream e;
+ e << "The CXX_STANDARD property on target \"" << target->GetName()
+ << "\" contained an invalid value: \"" << existingCxxStandard << "\".";
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+
+ const char * const *existingCxxIt = existingCxxStandard
+ ? std::find_if(cmArrayBegin(CXX_STANDARDS),
+ cmArrayEnd(CXX_STANDARDS),
+ cmStrCmp(existingCxxStandard))
+ : cmArrayEnd(CXX_STANDARDS);
+
+ if (needCxx11 && existingCxxIt < std::find_if(cmArrayBegin(CXX_STANDARDS),
+ cmArrayEnd(CXX_STANDARDS),
+ cmStrCmp("11")))
+ {
+ return false;
+ }
+ else if(needCxx98 && existingCxxIt <
+ std::find_if(cmArrayBegin(CXX_STANDARDS),
+ cmArrayEnd(CXX_STANDARDS),
+ cmStrCmp("98")))
+ {
+ return false;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void cmMakefile::CheckNeededCxxLanguage(const std::string& feature,
+ bool& needCxx98,
+ bool& needCxx11,
+ bool& needCxx14) const
+{
+ if (const char *propCxx98 =
+ this->GetDefinition("CMAKE_CXX98_COMPILE_FEATURES"))
+ {
+ std::vector<std::string> props;
+ cmSystemTools::ExpandListArgument(propCxx98, props);
+ needCxx98 = std::find(props.begin(), props.end(), feature) != props.end();
+ }
+ if (const char *propCxx11 =
+ this->GetDefinition("CMAKE_CXX11_COMPILE_FEATURES"))
+ {
+ std::vector<std::string> props;
+ cmSystemTools::ExpandListArgument(propCxx11, props);
+ needCxx11 = std::find(props.begin(), props.end(), feature) != props.end();
+ }
+ if (const char *propCxx14 =
+ this->GetDefinition("CMAKE_CXX14_COMPILE_FEATURES"))
+ {
+ std::vector<std::string> props;
+ cmSystemTools::ExpandListArgument(propCxx14, props);
+ needCxx14 = std::find(props.begin(), props.end(), feature) != props.end();
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmMakefile::
+AddRequiredTargetCxxFeature(cmTarget *target,
+ const std::string& feature) const
+{
+ bool needCxx98 = false;
+ bool needCxx11 = false;
+ bool needCxx14 = false;
+
+ this->CheckNeededCxxLanguage(feature, needCxx98, needCxx11, needCxx14);
+
+ const char *existingCxxStandard = target->GetProperty("CXX_STANDARD");
+ if (existingCxxStandard)
+ {
+ if (std::find_if(cmArrayBegin(CXX_STANDARDS), cmArrayEnd(CXX_STANDARDS),
+ cmStrCmp(existingCxxStandard)) == cmArrayEnd(CXX_STANDARDS))
+ {
+ std::ostringstream e;
+ e << "The CXX_STANDARD property on target \"" << target->GetName()
+ << "\" contained an invalid value: \"" << existingCxxStandard << "\".";
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+ }
+ const char * const *existingCxxIt = existingCxxStandard
+ ? std::find_if(cmArrayBegin(CXX_STANDARDS),
+ cmArrayEnd(CXX_STANDARDS),
+ cmStrCmp(existingCxxStandard))
+ : cmArrayEnd(CXX_STANDARDS);
+
+ bool setCxx98 = needCxx98 && !existingCxxStandard;
+ bool setCxx11 = needCxx11 && !existingCxxStandard;
+ bool setCxx14 = needCxx14 && !existingCxxStandard;
+
+ if (needCxx14 && existingCxxStandard && existingCxxIt <
+ std::find_if(cmArrayBegin(CXX_STANDARDS),
+ cmArrayEnd(CXX_STANDARDS),
+ cmStrCmp("14")))
+ {
+ setCxx14 = true;
+ }
+ else if (needCxx11 && existingCxxStandard && existingCxxIt <
+ std::find_if(cmArrayBegin(CXX_STANDARDS),
+ cmArrayEnd(CXX_STANDARDS),
+ cmStrCmp("11")))
+ {
+ setCxx11 = true;
+ }
+ else if(needCxx98 && existingCxxStandard && existingCxxIt <
+ std::find_if(cmArrayBegin(CXX_STANDARDS),
+ cmArrayEnd(CXX_STANDARDS),
+ cmStrCmp("98")))
+ {
+ setCxx98 = true;
+ }
+
+ if (setCxx14)
+ {
+ target->SetProperty("CXX_STANDARD", "14");
+ }
+ else if (setCxx11)
+ {
+ target->SetProperty("CXX_STANDARD", "11");
+ }
+ else if (setCxx98)
+ {
+ target->SetProperty("CXX_STANDARD", "98");
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void cmMakefile::CheckNeededCLanguage(const std::string& feature,
+ bool& needC90,
+ bool& needC99,
+ bool& needC11) const
+{
+ if (const char *propC90 =
+ this->GetDefinition("CMAKE_C90_COMPILE_FEATURES"))
+ {
+ std::vector<std::string> props;
+ cmSystemTools::ExpandListArgument(propC90, props);
+ needC90 = std::find(props.begin(), props.end(), feature) != props.end();
+ }
+ if (const char *propC99 =
+ this->GetDefinition("CMAKE_C99_COMPILE_FEATURES"))
+ {
+ std::vector<std::string> props;
+ cmSystemTools::ExpandListArgument(propC99, props);
+ needC99 = std::find(props.begin(), props.end(), feature) != props.end();
+ }
+ if (const char *propC11 =
+ this->GetDefinition("CMAKE_C11_COMPILE_FEATURES"))
+ {
+ std::vector<std::string> props;
+ cmSystemTools::ExpandListArgument(propC11, props);
+ needC11 = std::find(props.begin(), props.end(), feature) != props.end();
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmMakefile::
+AddRequiredTargetCFeature(cmTarget *target, const std::string& feature) const
+{
+ bool needC90 = false;
+ bool needC99 = false;
+ bool needC11 = false;
+
+ this->CheckNeededCLanguage(feature, needC90, needC99, needC11);
+
+ const char *existingCStandard = target->GetProperty("C_STANDARD");
+ if (existingCStandard)
+ {
+ if (std::find_if(cmArrayBegin(C_STANDARDS), cmArrayEnd(C_STANDARDS),
+ cmStrCmp(existingCStandard)) == cmArrayEnd(C_STANDARDS))
+ {
+ std::ostringstream e;
+ e << "The C_STANDARD property on target \"" << target->GetName()
+ << "\" contained an invalid value: \"" << existingCStandard << "\".";
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+ }
+ const char * const *existingCIt = existingCStandard
+ ? std::find_if(cmArrayBegin(C_STANDARDS),
+ cmArrayEnd(C_STANDARDS),
+ cmStrCmp(existingCStandard))
+ : cmArrayEnd(C_STANDARDS);
+
+ bool setC90 = needC90 && !existingCStandard;
+ bool setC99 = needC99 && !existingCStandard;
+ bool setC11 = needC11 && !existingCStandard;
+
+ if (needC11 && existingCStandard && existingCIt <
+ std::find_if(cmArrayBegin(C_STANDARDS),
+ cmArrayEnd(C_STANDARDS),
+ cmStrCmp("11")))
+ {
+ setC11 = true;
+ }
+ else if(needC99 && existingCStandard && existingCIt <
+ std::find_if(cmArrayBegin(C_STANDARDS),
+ cmArrayEnd(C_STANDARDS),
+ cmStrCmp("99")))
+ {
+ setC99 = true;
+ }
+ else if(needC90 && existingCStandard && existingCIt <
+ std::find_if(cmArrayBegin(C_STANDARDS),
+ cmArrayEnd(C_STANDARDS),
+ cmStrCmp("90")))
+ {
+ setC90 = true;
+ }
+
+ if (setC11)
+ {
+ target->SetProperty("C_STANDARD", "11");
+ }
+ else if (setC99)
+ {
+ target->SetProperty("C_STANDARD", "99");
+ }
+ else if (setC90)
+ {
+ target->SetProperty("C_STANDARD", "90");
+ }
+ return true;
+}
+
+
+cmMakefile::FunctionPushPop::FunctionPushPop(cmMakefile* mf,
+ const std::string& fileName,
+ cmPolicies::PolicyMap const& pm)
+ : Makefile(mf), ReportError(true)
+{
+ this->Makefile->PushFunctionScope(fileName, pm);
+}
+
+cmMakefile::FunctionPushPop::~FunctionPushPop()
+{
+ this->Makefile->PopFunctionScope(this->ReportError);
+}
+
+
+cmMakefile::MacroPushPop::MacroPushPop(cmMakefile* mf,
+ const std::string& fileName,
+ const cmPolicies::PolicyMap& pm)
+ : Makefile(mf), ReportError(true)
+{
+ this->Makefile->PushMacroScope(fileName, pm);
+}
+
+cmMakefile::MacroPushPop::~MacroPushPop()
+{
+ this->Makefile->PopMacroScope(this->ReportError);
+}
+
+cmMakefileCall::cmMakefileCall(cmMakefile* mf, const cmCommandContext& lfc,
+ cmExecutionStatus& status): Makefile(mf)
+{
+ this->Makefile->ContextStack.push_back(&lfc);
+ this->Makefile->ExecutionStatusStack.push_back(&status);
+}
+
+cmMakefileCall::~cmMakefileCall()
+{
+ this->Makefile->ExecutionStatusStack.pop_back();
+ this->Makefile->ContextStack.pop_back();
+}
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 8bce9fd65..362ea75fb 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -12,16 +12,15 @@
#ifndef cmMakefile_h
#define cmMakefile_h
-#include "cmCacheManager.h"
#include "cmExecutionStatus.h"
#include "cmListFileCache.h"
-#include "cmPolicies.h"
-#include "cmPropertyMap.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmNewLineStyle.h"
-#include "cmGeneratorTarget.h"
+#include "cmExpandedCommandArgument.h"
#include "cmake.h"
+#include "cmState.h"
+#include "cmAlgorithms.h"
#if defined(CMAKE_BUILD_WITH_CMAKE)
#include "cmSourceGroup.h"
@@ -30,14 +29,18 @@
#include <cmsys/auto_ptr.hxx>
#include <cmsys/RegularExpression.hxx>
#if defined(CMAKE_BUILD_WITH_CMAKE)
-# include <cmsys/hash_map.hxx>
+# ifdef CMake_HAVE_CXX11_UNORDERED_MAP
+# include <unordered_map>
+# else
+# include <cmsys/hash_map.hxx>
+# endif
#endif
+#include <stack>
+
class cmFunctionBlocker;
class cmCommand;
class cmInstallGenerator;
-class cmLocalGenerator;
-class cmMakeDepend;
class cmSourceFile;
class cmTest;
class cmTestGenerator;
@@ -45,6 +48,8 @@ class cmVariableWatch;
class cmake;
class cmMakefileCall;
class cmCMakePolicyCommand;
+class cmGeneratorExpressionEvaluationFile;
+class cmExportBuildFileGenerator;
/** \class cmMakefile
* \brief Process the input CMakeLists.txt file.
@@ -55,53 +60,37 @@ class cmCMakePolicyCommand;
*/
class cmMakefile
{
- class Internals;
- cmsys::auto_ptr<Internals> Internal;
public:
- /**
- * Return the major and minor version of the cmake that
- * was used to write the currently loaded cache, note
- * this method will not work before the cache is loaded.
- */
- unsigned int GetCacheMajorVersion();
- unsigned int GetCacheMinorVersion();
-
- /* Check for unused variables in this scope */
- void CheckForUnusedVariables() const;
/* Mark a variable as used */
- void MarkVariableAsUsed(const char* var);
+ void MarkVariableAsUsed(const std::string& var);
/* return true if a variable has been initialized */
- bool VariableInitialized(const char* ) const;
- /* return true if a variable has been used */
- bool VariableUsed(const char* ) const;
- /** Return whether compatibility features needed for a version of
- the cache or lower should be enabled. */
- bool NeedCacheCompatibility(int major, int minor);
+ bool VariableInitialized(const std::string& ) const;
/**
* Construct an empty makefile.
*/
- cmMakefile();
- cmMakefile(const cmMakefile& mf);
+ cmMakefile(cmGlobalGenerator* globalGenerator,
+ const cmState::Snapshot& snapshot);
/**
* Destructor.
*/
~cmMakefile();
- /**
- * Read and parse a CMakeLists.txt file.
- */
- bool ReadListFile(const char* listfile,
- const char* external= 0,
- std::string* fullPath= 0,
- bool noPolicyScope = true);
+ bool ReadListFile(const char* filename);
+
+ bool ReadDependentFile(const char* filename, bool noPolicyScope = true);
+
+ bool ProcessBuildsystemFile(const char* filename);
/**
* Add a function blocker to this makefile
*/
void AddFunctionBlocker(cmFunctionBlocker* fb);
+ /// @return whether we are processing the top CMakeLists.txt file.
+ bool IsRootMakefile() const;
+
/**
* Remove the function blocker whose scope ends with the given command.
* This returns ownership of the function blocker object.
@@ -109,54 +98,23 @@ public:
cmsys::auto_ptr<cmFunctionBlocker>
RemoveFunctionBlocker(cmFunctionBlocker* fb, const cmListFileFunction& lff);
- /** Push/pop a lexical (function blocker) barrier automatically. */
- class LexicalPushPop
- {
- public:
- LexicalPushPop(cmMakefile* mf);
- ~LexicalPushPop();
- void Quiet() { this->ReportError = false; }
- private:
- cmMakefile* Makefile;
- bool ReportError;
- };
- friend class LexicalPushPop;
-
/**
* Try running cmake and building a file. This is used for dynalically
* loaded commands, not as part of the usual build process.
*/
- int TryCompile(const char *srcdir, const char *bindir,
- const char *projectName, const char *targetName,
+ int TryCompile(const std::string& srcdir, const std::string& bindir,
+ const std::string& projectName, const std::string& targetName,
bool fast,
const std::vector<std::string> *cmakeArgs,
- std::string *output);
+ std::string& output);
bool GetIsSourceFileTryCompile() const;
/**
- * Specify the makefile generator. This is platform/compiler
- * dependent, although the interface is through a generic
- * superclass.
- */
- void SetLocalGenerator(cmLocalGenerator*);
-
- ///! Get the current makefile generator.
- cmLocalGenerator* GetLocalGenerator()
- { return this->LocalGenerator;}
-
- /**
- * Test whether compatibility is set to a given version or lower.
- */
- bool NeedBackwardsCompatibility(unsigned int major,
- unsigned int minor,
- unsigned int patch = 0xFFu);
-
- /**
* Help enforce global target name uniqueness.
*/
bool EnforceUniqueName(std::string const& name, std::string& msg,
- bool isCustom = false);
+ bool isCustom = false) const;
/**
* Perform FinalPass, Library dependency analysis etc before output of the
@@ -169,38 +127,38 @@ public:
*/
void FinalPass();
- /**
- * Print the object state to std::cout.
- */
- void Print();
-
/** Add a custom command to the build. */
- void AddCustomCommandToTarget(const char* target,
+ void AddCustomCommandToTarget(const std::string& target,
+ const std::vector<std::string>& byproducts,
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines,
cmTarget::CustomCommandType type,
const char* comment, const char* workingDir,
- bool escapeOldStyle = true);
+ bool escapeOldStyle = true,
+ bool uses_terminal = false);
cmSourceFile* AddCustomCommandToOutput(
const std::vector<std::string>& outputs,
+ const std::vector<std::string>& byproducts,
const std::vector<std::string>& depends,
- const char* main_dependency,
+ const std::string& main_dependency,
const cmCustomCommandLines& commandLines,
const char* comment, const char* workingDir,
bool replace = false,
- bool escapeOldStyle = true);
+ bool escapeOldStyle = true,
+ bool uses_terminal = false);
cmSourceFile* AddCustomCommandToOutput(
- const char* output,
+ const std::string& output,
const std::vector<std::string>& depends,
- const char* main_dependency,
+ const std::string& main_dependency,
const cmCustomCommandLines& commandLines,
const char* comment, const char* workingDir,
bool replace = false,
- bool escapeOldStyle = true);
- void AddCustomCommandOldStyle(const char* target,
+ bool escapeOldStyle = true,
+ bool uses_terminal = false);
+ void AddCustomCommandOldStyle(const std::string& target,
const std::vector<std::string>& outputs,
const std::vector<std::string>& depends,
- const char* source,
+ const std::string& source,
const cmCustomCommandLines& commandLines,
const char* comment);
@@ -212,10 +170,11 @@ public:
void AddCompileOption(const char* option);
/** Create a new imported target with the name and type given. */
- cmTarget* AddImportedTarget(const char* name, cmTarget::TargetType type,
+ cmTarget* AddImportedTarget(const std::string& name,
+ cmState::TargetType type,
bool global);
- cmTarget* AddNewTarget(cmTarget::TargetType type, const char* name);
+ cmTarget* AddNewTarget(cmState::TargetType type, const std::string& name);
/**
* Add an executable to the build.
@@ -228,64 +187,56 @@ public:
* Add a utility to the build. A utiltity target is a command that
* is run every time the target is built.
*/
- void AddUtilityCommand(const char* utilityName, bool excludeFromAll,
- const std::vector<std::string>& depends,
- const char* workingDirectory,
- const char* command,
- const char* arg1=0,
- const char* arg2=0,
- const char* arg3=0,
- const char* arg4=0);
- cmTarget* AddUtilityCommand(const char* utilityName, bool excludeFromAll,
+ cmTarget* AddUtilityCommand(const std::string& utilityName,
+ bool excludeFromAll,
+ const std::vector<std::string>& depends,
+ const char* workingDirectory,
+ const char* command,
+ const char* arg1=0,
+ const char* arg2=0,
+ const char* arg3=0,
+ const char* arg4=0);
+ cmTarget* AddUtilityCommand(const std::string& utilityName,
+ bool excludeFromAll,
+ const char* workingDirectory,
+ const std::vector<std::string>& depends,
+ const cmCustomCommandLines& commandLines,
+ bool escapeOldStyle = true,
+ const char* comment = 0,
+ bool uses_terminal = false);
+ cmTarget* AddUtilityCommand(const std::string& utilityName,
+ bool excludeFromAll,
const char* workingDirectory,
+ const std::vector<std::string>& byproducts,
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines,
bool escapeOldStyle = true,
- const char* comment = 0);
+ const char* comment = 0,
+ bool uses_terminal = false);
/**
* Add a link library to the build.
*/
- void AddLinkLibrary(const char*);
- void AddLinkLibrary(const char*, cmTarget::LinkLibraryType type);
- void AddLinkLibraryForTarget(const char *tgt, const char*,
- cmTarget::LinkLibraryType type);
- void AddLinkDirectoryForTarget(const char *tgt, const char* d);
-
- /**
- * Add a link directory to the build.
- */
- void AddLinkDirectory(const char*);
-
- /**
- * Get the list of link directories
- */
- std::vector<std::string>& GetLinkDirectories()
- {
- return this->LinkDirectories;
- }
- const std::vector<std::string>& GetLinkDirectories() const
- {
- return this->LinkDirectories;
- }
- void SetLinkDirectories(const std::vector<std::string>& vec)
- {
- this->LinkDirectories = vec;
- }
+ void AddLinkLibrary(const std::string&);
+ void AddLinkLibrary(const std::string&, cmTargetLinkLibraryType type);
+ void AddLinkLibraryForTarget(const std::string& tgt, const std::string&,
+ cmTargetLinkLibraryType type);
+ void AddLinkDirectoryForTarget(const std::string& tgt, const std::string& d);
/**
* Add a subdirectory to the build.
*/
- void AddSubDirectory(const char*, bool excludeFromAll=false,
- bool preorder = false);
- void AddSubDirectory(const char* fullSrcDir,const char *fullBinDir,
- bool excludeFromAll, bool preorder,
+ void AddSubDirectory(const std::string& fullSrcDir,
+ const std::string& fullBinDir,
+ bool excludeFromAll,
bool immediate);
+ void Configure();
+
/**
* Configure a subdirectory
*/
- void ConfigureSubDirectory(cmLocalGenerator *);
+ void ConfigureSubDirectory(cmMakefile* mf);
/**
* Add an include directory to the build.
@@ -297,56 +248,48 @@ public:
* Add a variable definition to the build. This variable
* can be used in CMake to refer to lists, directories, etc.
*/
- void AddDefinition(const char* name, const char* value);
+ void AddDefinition(const std::string& name, const char* value);
///! Add a definition to this makefile and the global cmake cache.
- void AddCacheDefinition(const char* name, const char* value,
+ void AddCacheDefinition(const std::string& name, const char* value,
const char* doc,
- cmCacheManager::CacheEntryType type,
+ cmState::CacheEntryType type,
bool force = false);
/**
* Add bool variable definition to the build.
*/
- void AddDefinition(const char* name, bool);
+ void AddDefinition(const std::string& name, bool);
/**
* Remove a variable definition from the build. This is not valid
* for cache entries, and will only affect the current makefile.
*/
- void RemoveDefinition(const char* name);
+ void RemoveDefinition(const std::string& name);
///! Remove a definition from the cache.
- void RemoveCacheDefinition(const char* name);
+ void RemoveCacheDefinition(const std::string& name);
/**
* Specify the name of the project for this build.
*/
- void SetProjectName(const char*);
-
- /**
- * Get the name of the project for this build.
- */
- const char* GetProjectName() const
- {
- return this->ProjectName.c_str();
- }
+ void SetProjectName(std::string const& name);
/** Get the configurations to be generated. */
- const char* GetConfigurations(std::vector<std::string>& configs,
+ std::string GetConfigurations(std::vector<std::string>& configs,
bool single = true) const;
/**
* Set the name of the library.
*/
- cmTarget* AddLibrary(const char *libname, cmTarget::TargetType type,
+ cmTarget* AddLibrary(const std::string& libname, cmState::TargetType type,
const std::vector<std::string> &srcs,
bool excludeFromAll = false);
- void AddAlias(const char *libname, cmTarget *tgt);
+ void AddAlias(const std::string& libname, const std::string& tgt);
#if defined(CMAKE_BUILD_WITH_CMAKE)
/**
* Add a root source group for consideration when adding a new source.
*/
- void AddSourceGroup(const char* name, const char* regex=0);
+ void AddSourceGroup(const std::string& name, const char* regex=0);
/**
* Add a source group for consideration when adding a new source.
@@ -363,7 +306,7 @@ public:
*/
bool SetPolicy(cmPolicies::PolicyID id, cmPolicies::PolicyStatus status);
bool SetPolicy(const char *id, cmPolicies::PolicyStatus status);
- cmPolicies::PolicyStatus GetPolicyStatus(cmPolicies::PolicyID id);
+ cmPolicies::PolicyStatus GetPolicyStatus(cmPolicies::PolicyID id) const;
bool SetPolicyVersion(const char *version);
void RecordPolicies(cmPolicies::PolicyMap& pm);
//@}
@@ -372,58 +315,23 @@ public:
class PolicyPushPop
{
public:
- PolicyPushPop(cmMakefile* m,
- bool weak = false,
- cmPolicies::PolicyMap const& pm = cmPolicies::PolicyMap());
+ PolicyPushPop(cmMakefile* m);
~PolicyPushPop();
- void Quiet() { this->ReportError = false; }
private:
cmMakefile* Makefile;
- bool ReportError;
};
friend class PolicyPushPop;
/**
- * Get the Policies Instance
- */
- cmPolicies *GetPolicies();
-
- /**
- * Add an auxiliary directory to the build.
+ * Determine if the given context, name pair has already been reported
+ * in context of CMP0054.
*/
- void AddExtraDirectory(const char* dir);
+ bool HasCMP0054AlreadyBeenReported(const cmListFileContext &context) const;
+ bool IgnoreErrorsCMP0061() const;
- /**
- * Add an auxiliary directory to the build.
- */
- void MakeStartDirectoriesCurrent()
- {
- this->AddDefinition("CMAKE_CURRENT_SOURCE_DIR",
- this->cmStartDirectory.c_str());
- this->AddDefinition("CMAKE_CURRENT_BINARY_DIR",
- this->StartOutputDirectory.c_str());
- }
-
- //@{
- /**
- * Set/Get the home directory (or output directory) in the project. The
- * home directory is the top directory of the project. It is where
- * CMakeSetup or configure was run. Remember that CMake processes
- * CMakeLists files by recursing up the tree starting at the StartDirectory
- * and going up until it reaches the HomeDirectory.
- */
- void SetHomeDirectory(const char* dir);
- const char* GetHomeDirectory() const
- {
- return this->cmHomeDirectory.c_str();
- }
- void SetHomeOutputDirectory(const char* lib);
- const char* GetHomeOutputDirectory() const
- {
- return this->HomeOutputDirectory.c_str();
- }
- //@}
+ const char* GetHomeDirectory() const;
+ const char* GetHomeOutputDirectory() const;
/**
* Set CMAKE_SCRIPT_MODE_FILE variable when running a -P script.
@@ -435,59 +343,8 @@ public:
*/
void SetArgcArgv(const std::vector<std::string>& args);
- //@{
- /**
- * Set/Get the start directory (or output directory). The start directory
- * is the directory of the CMakeLists.txt file that started the current
- * round of processing. Remember that CMake processes CMakeLists files by
- * recursing up the tree starting at the StartDirectory and going up until
- * it reaches the HomeDirectory.
- */
- void SetStartDirectory(const char* dir)
- {
- this->cmStartDirectory = dir;
- cmSystemTools::ConvertToUnixSlashes(this->cmStartDirectory);
- this->cmStartDirectory =
- cmSystemTools::CollapseFullPath(this->cmStartDirectory.c_str());
- this->AddDefinition("CMAKE_CURRENT_SOURCE_DIR",
- this->cmStartDirectory.c_str());
- }
- const char* GetStartDirectory() const
- {
- return this->cmStartDirectory.c_str();
- }
- void SetStartOutputDirectory(const char* lib)
- {
- this->StartOutputDirectory = lib;
- cmSystemTools::ConvertToUnixSlashes(this->StartOutputDirectory);
- this->StartOutputDirectory =
- cmSystemTools::CollapseFullPath(this->StartOutputDirectory.c_str());
- cmSystemTools::MakeDirectory(this->StartOutputDirectory.c_str());
- this->AddDefinition("CMAKE_CURRENT_BINARY_DIR",
- this->StartOutputDirectory.c_str());
- }
- const char* GetStartOutputDirectory() const
- {
- return this->StartOutputDirectory.c_str();
- }
- //@}
-
- const char* GetCurrentDirectory() const
- {
- return this->cmStartDirectory.c_str();
- }
- const char* GetCurrentOutputDirectory() const
- {
- return this->StartOutputDirectory.c_str();
- }
-
- /* Get the current CMakeLists.txt file that is being processed. This
- * is just used in order to be able to 'branch' from one file to a second
- * transparently */
- const char* GetCurrentListFile() const
- {
- return this->cmCurrentListFile.c_str();
- }
+ const char* GetCurrentSourceDirectory() const;
+ const char* GetCurrentBinaryDirectory() const;
//@}
@@ -497,22 +354,22 @@ public:
*/
void SetIncludeRegularExpression(const char* regex)
{
- this->IncludeFileRegularExpression = regex;
+ this->SetProperty("INCLUDE_REGULAR_EXPRESSION", regex);
}
- const char* GetIncludeRegularExpression()
+ const char* GetIncludeRegularExpression() const
{
- return this->IncludeFileRegularExpression.c_str();
+ return this->GetProperty("INCLUDE_REGULAR_EXPRESSION");
}
/**
* Set a regular expression that include files that are not found
* must match in order to be considered a problem.
*/
- void SetComplainRegularExpression(const char* regex)
+ void SetComplainRegularExpression(const std::string& regex)
{
this->ComplainFileRegularExpression = regex;
}
- const char* GetComplainRegularExpression()
+ const char* GetComplainRegularExpression() const
{
return this->ComplainFileRegularExpression.c_str();
}
@@ -529,110 +386,91 @@ public:
{
return this->ImportedTargetsOwned;
}
+ std::vector<cmTarget*> GetImportedTargets() const;
- const cmGeneratorTargetsType &GetGeneratorTargets() const
- {
- return this->GeneratorTargets;
- }
-
- void SetGeneratorTargets(const cmGeneratorTargetsType &targets)
- {
- this->GeneratorTargets = targets;
- }
-
- cmTarget* FindTarget(const char* name, bool excludeAliases = false);
+ cmTarget* FindTarget(const std::string& name,
+ bool excludeAliases = false) const;
/** Find a target to use in place of the given name. The target
returned may be imported or built within the project. */
- cmTarget* FindTargetToUse(const char* name, bool excludeAliases = false);
- bool IsAlias(const char *name);
- cmGeneratorTarget* FindGeneratorTargetToUse(const char* name);
+ cmTarget* FindTargetToUse(const std::string& name,
+ bool excludeAliases = false) const;
+ bool IsAlias(const std::string& name) const;
+
+ std::map<std::string, std::string> GetAliasTargets() const
+ {
+ return this->AliasTargets;
+ }
/**
* Mark include directories as system directories.
*/
- void AddSystemIncludeDirectories(const std::set<cmStdString> &incs);
- bool IsSystemIncludeDirectory(const char* dir, const char *config);
-
- /** Expand out any arguements in the vector that have ; separated
- * strings into multiple arguements. A new vector is created
- * containing the expanded versions of all arguments in argsIn.
- * This method differes from the one in cmSystemTools in that if
- * the CmakeLists file is version 1.2 or earlier it will check for
- * source lists being used without ${} around them
- */
- void ExpandSourceListArguments(std::vector<std::string> const& argsIn,
- std::vector<std::string>& argsOut,
- unsigned int startArgumentIndex);
+ void AddSystemIncludeDirectories(const std::set<std::string> &incs);
/** Get a cmSourceFile pointer for a given source name, if the name is
* not found, then a null pointer is returned.
*/
- cmSourceFile* GetSource(const char* sourceName);
+ cmSourceFile* GetSource(const std::string& sourceName) const;
+
+ /** Create the source file and return it. generated
+ * indicates if it is a generated file, this is used in determining
+ * how to create the source file instance e.g. name
+ */
+ cmSourceFile* CreateSource(const std::string& sourceName,
+ bool generated = false);
/** Get a cmSourceFile pointer for a given source name, if the name is
* not found, then create the source file and return it. generated
* indicates if it is a generated file, this is used in determining
* how to create the source file instance e.g. name
*/
- cmSourceFile* GetOrCreateSource(const char* sourceName,
+ cmSourceFile* GetOrCreateSource(const std::string& sourceName,
bool generated = false);
/**
- * Obtain a list of auxiliary source directories.
- */
- std::vector<std::string>& GetAuxSourceDirectories()
- {return this->AuxSourceDirectories;}
-
- //@{
- /**
- * Return a list of extensions associated with source and header
- * files
- */
- const std::vector<std::string>& GetSourceExtensions() const
- {return this->SourceFileExtensions;}
- const std::vector<std::string>& GetHeaderExtensions() const
- {return this->HeaderFileExtensions;}
- //@}
-
- /**
* Given a variable name, return its value (as a string).
* If the variable is not found in this makefile instance, the
* cache is then queried.
*/
- const char* GetDefinition(const char*) const;
- const char* GetSafeDefinition(const char*) const;
- const char* GetRequiredDefinition(const char* name) const;
- bool IsDefinitionSet(const char*) const;
+ const char* GetDefinition(const std::string&) const;
+ const char* GetSafeDefinition(const std::string&) const;
+ const char* GetRequiredDefinition(const std::string& name) const;
+ bool IsDefinitionSet(const std::string&) const;
/**
* Get the list of all variables in the current space. If argument
* cacheonly is specified and is greater than 0, then only cache
* variables will be listed.
*/
- std::vector<std::string> GetDefinitions(int cacheonly=0) const;
+ std::vector<std::string> GetDefinitions() const;
- /** Test a boolean cache entry to see if it is true or false,
- * returns false if no entry defined.
+ /**
+ * Test a boolean variable to see if it is true or false.
+ * If the variable is not found in this makefile instance, the
+ * cache is then queried.
+ * Returns false if no entry defined.
*/
- bool IsOn(const char* name) const;
- bool IsSet(const char* name) const;
+ bool IsOn(const std::string& name) const;
+ bool IsSet(const std::string& name) const;
/** Return whether the target platform is 64-bit. */
bool PlatformIs64Bit() const;
+ /** Return whether the target platform is Apple iOS. */
+ bool PlatformIsAppleIos() const;
+
/** Retrieve soname flag for the specified language if supported */
- const char* GetSONameFlag(const char* language) const;
+ const char* GetSONameFlag(const std::string& language) const;
/**
* Get a list of preprocessor define flags.
*/
- const char* GetDefineFlags()
+ const char* GetDefineFlags() const
{return this->DefineFlags.c_str();}
/**
* Make sure CMake can write this file
*/
- bool CanIWriteThisFile(const char* fileName);
+ bool CanIWriteThisFile(const char* fileName) const;
#if defined(CMAKE_BUILD_WITH_CMAKE)
/**
@@ -644,7 +482,7 @@ public:
/**
* Get the source group
*/
- cmSourceGroup* GetSourceGroup(const std::vector<std::string>&name);
+ cmSourceGroup* GetSourceGroup(const std::vector<std::string>&name) const;
#endif
/**
@@ -655,16 +493,16 @@ public:
///! When the file changes cmake will be re-run from the build system.
void AddCMakeDependFile(const std::string& file)
{ this->ListFiles.push_back(file);}
+ void AddCMakeDependFilesFromUser();
- /**
- * Get the list file stack as a string
- */
- std::string GetListFileStack();
+ std::string FormatListFileStack() const;
/**
* Get the current context backtrace.
*/
- bool GetBacktrace(cmListFileBacktrace& backtrace) const;
+ cmListFileBacktrace GetBacktrace() const;
+ cmListFileBacktrace GetBacktrace(cmCommandContext const& lfc) const;
+ cmListFileContext GetExecutionContext() const;
/**
* Get the vector of files created by this makefile
@@ -681,14 +519,14 @@ public:
* entry in the this->Definitions map. Also \@var\@ is
* expanded to match autoconf style expansions.
*/
- const char *ExpandVariablesInString(std::string& source);
+ const char *ExpandVariablesInString(std::string& source) const;
const char *ExpandVariablesInString(std::string& source, bool escapeQuotes,
bool noEscapes,
bool atOnly = false,
const char* filename = 0,
long line = -1,
bool removeEmpty = false,
- bool replaceAt = true);
+ bool replaceAt = false) const;
/**
* Remove any remaining variables in the string. Anything with ${var} or
@@ -707,7 +545,7 @@ public:
* See cmConfigureFileCommand for details.
*/
void ConfigureString(const std::string& input, std::string& output,
- bool atOnly, bool escapeQuotes);
+ bool atOnly, bool escapeQuotes) const;
/**
* Copy file but change lines acording to ConfigureString
@@ -721,14 +559,14 @@ public:
/**
* find what source group this source is in
*/
- cmSourceGroup& FindSourceGroup(const char* source,
- std::vector<cmSourceGroup> &groups);
+ cmSourceGroup* FindSourceGroup(const char* source,
+ std::vector<cmSourceGroup> &groups) const;
#endif
/**
* Print a command's invocation
*/
- void PrintCommandTrace(const cmListFileFunction& lff);
+ void PrintCommandTrace(const cmListFileFunction& lff) const;
/**
* Execute a single CMake command. Returns true if the command
@@ -737,23 +575,11 @@ public:
bool ExecuteCommand(const cmListFileFunction& lff,
cmExecutionStatus &status);
- /** Check if a command exists. */
- bool CommandExists(const char* name) const;
-
- /**
- * Add a command to this cmake instance
- */
- void AddCommand(cmCommand* );
-
///! Enable support for named language, if nil then all languages are
///enabled.
void EnableLanguage(std::vector<std::string>const& languages, bool optional);
- /**
- * Set/Get the name of the parent directories CMakeLists file
- * given a current CMakeLists file name
- */
- cmCacheManager *GetCacheManager() const;
+ cmState *GetState() const;
/**
* Get the variable watch. This is used to determine when certain variables
@@ -764,18 +590,25 @@ public:
#endif
///! Display progress or status message.
- void DisplayStatus(const char*, float);
+ void DisplayStatus(const char*, float) const;
/**
* Expand the given list file arguments into the full set after
* variable replacement and list expansion.
*/
bool ExpandArguments(std::vector<cmListFileArgument> const& inArgs,
- std::vector<std::string>& outArgs);
+ std::vector<std::string>& outArgs,
+ const char* filename = 0) const;
+
+ bool ExpandArguments(std::vector<cmListFileArgument> const& inArgs,
+ std::vector<cmExpandedCommandArgument>& outArgs,
+ const char* filename = 0) const;
+
/**
* Get the instance
*/
cmake *GetCMakeInstance() const;
+ cmGlobalGenerator* GetGlobalGenerator() const;
/**
* Get all the source files this makefile knows about
@@ -788,51 +621,32 @@ public:
* Is there a source file that has the provided source file as an output?
* if so then return it
*/
- cmSourceFile *GetSourceFileWithOutput(const char *outName);
-
- /**
- * Add a macro to the list of macros. The arguments should be name of the
- * macro and a documentation signature of it
- */
- void AddMacro(const char* name, const char* signature);
+ cmSourceFile *GetSourceFileWithOutput(const std::string& outName) const;
///! Add a new cmTest to the list of tests for this makefile.
- cmTest* CreateTest(const char* testName);
+ cmTest* CreateTest(const std::string& testName);
/** Get a cmTest pointer for a given test name, if the name is
* not found, then a null pointer is returned.
*/
- cmTest* GetTest(const char* testName) const;
-
- /**
- * Get a list of macros as a ; separated string
- */
- void GetListOfMacros(std::string& macros);
+ cmTest* GetTest(const std::string& testName) const;
/**
* Return a location of a file in cmake or custom modules directory
*/
- std::string GetModulesFile(const char* name);
+ std::string GetModulesFile(const char* name) const;
///! Set/Get a property of this directory
- void SetProperty(const char *prop, const char *value);
- void AppendProperty(const char *prop, const char *value,bool asString=false);
- const char *GetProperty(const char *prop);
- const char *GetPropertyOrDefinition(const char *prop);
- const char *GetProperty(const char *prop, cmProperty::ScopeType scope);
- bool GetPropertyAsBool(const char *prop);
-
- const char* GetFeature(const char* feature, const char* config);
-
- // Get the properties
- cmPropertyMap &GetProperties() { return this->Properties; };
+ void SetProperty(const std::string& prop, const char *value);
+ void AppendProperty(const std::string& prop, const char *value,
+ bool asString=false);
+ const char *GetProperty(const std::string& prop) const;
+ const char *GetProperty(const std::string& prop, bool chain) const;
+ bool GetPropertyAsBool(const std::string& prop) const;
+ std::vector<std::string> GetPropertyKeys() const;
///! Initialize a makefile from its parent
- void InitializeFromParent();
-
- ///! Set/Get the preorder flag
- void SetPreOrder(bool p) { this->PreOrder = p; }
- bool GetPreOrder() const { return this->PreOrder; }
+ void InitializeFromParent(cmMakefile* parent);
void AddInstallGenerator(cmInstallGenerator* g)
{ if(g) this->InstallGenerators.push_back(g); }
@@ -841,16 +655,48 @@ public:
void AddTestGenerator(cmTestGenerator* g)
{ if(g) this->TestGenerators.push_back(g); }
- std::vector<cmTestGenerator*>& GetTestGenerators()
+ const std::vector<cmTestGenerator*>& GetTestGenerators() const
{ return this->TestGenerators; }
- // Define the properties
- static void DefineProperties(cmake *cm);
+ class FunctionPushPop
+ {
+ public:
+ FunctionPushPop(cmMakefile* mf, std::string const& fileName,
+ cmPolicies::PolicyMap const& pm);
+ ~FunctionPushPop();
+
+ void Quiet() { this->ReportError = false; }
+ private:
+ cmMakefile* Makefile;
+ bool ReportError;
+ };
+
+ class MacroPushPop
+ {
+ public:
+ MacroPushPop(cmMakefile* mf, std::string const& fileName,
+ cmPolicies::PolicyMap const& pm);
+ ~MacroPushPop();
+
+ void Quiet() { this->ReportError = false; }
+ private:
+ cmMakefile* Makefile;
+ bool ReportError;
+ };
- // push and pop variable scopes
+ void PushFunctionScope(std::string const& fileName,
+ cmPolicies::PolicyMap const& pm);
+ void PopFunctionScope(bool reportError);
+ void PushMacroScope(std::string const& fileName,
+ cmPolicies::PolicyMap const& pm);
+ void PopMacroScope(bool reportError);
void PushScope();
void PopScope();
- void RaiseScope(const char *var, const char *value);
+ void RaiseScope(const std::string& var, const char *value);
+
+ // push and pop loop scopes
+ void PushLoopBlockBarrier();
+ void PopLoopBlockBarrier();
/** Helper class to push and pop scopes automatically. */
class ScopePushPop
@@ -863,83 +709,114 @@ public:
};
void IssueMessage(cmake::MessageType t,
- std::string const& text) const;
+ std::string const& text,
+ bool force = false) const;
/** Set whether or not to report a CMP0000 violation. */
void SetCheckCMP0000(bool b) { this->CheckCMP0000 = b; }
- std::vector<cmValueWithOrigin> GetIncludeDirectoriesEntries() const
- {
- return this->IncludeDirectoriesEntries;
- }
- std::vector<cmValueWithOrigin> GetCompileOptionsEntries() const
- {
- return this->CompileOptionsEntries;
- }
- std::vector<cmValueWithOrigin> GetCompileDefinitionsEntries() const
- {
- return this->CompileDefinitionsEntries;
- }
+ cmStringRange GetIncludeDirectoriesEntries() const;
+ cmBacktraceRange GetIncludeDirectoriesBacktraces() const;
+ cmStringRange GetCompileOptionsEntries() const;
+ cmBacktraceRange GetCompileOptionsBacktraces() const;
+ cmStringRange GetCompileDefinitionsEntries() const;
+ cmBacktraceRange GetCompileDefinitionsBacktraces() const;
- bool IsGeneratingBuildSystem(){ return this->GeneratingBuildSystem; }
- void SetGeneratingBuildSystem(){ this->GeneratingBuildSystem = true; }
+ void AddQtUiFileWithOptions(cmSourceFile *sf);
+ std::vector<cmSourceFile*> GetQtUiFilesWithOptions() const;
- std::set<cmStdString> const & GetSystemIncludeDirectories() const
+ std::set<std::string> const & GetSystemIncludeDirectories() const
{ return this->SystemIncludeDirectories; }
+ bool PolicyOptionalWarningEnabled(std::string const& var);
+
+ bool AddRequiredTargetFeature(cmTarget *target,
+ const std::string& feature,
+ std::string *error = 0) const;
+
+ bool CompileFeatureKnown(cmTarget const* target, const std::string& feature,
+ std::string& lang, std::string *error) const;
+
+ const char* CompileFeaturesAvailable(const std::string& lang,
+ std::string *error) const;
+
+ bool HaveStandardAvailable(cmTarget const* target, std::string const& lang,
+ const std::string& feature) const;
+
+ bool IsLaterStandard(std::string const& lang,
+ std::string const& lhs,
+ std::string const& rhs);
+
+ void PushLoopBlock();
+ void PopLoopBlock();
+ bool IsLoopBlock() const;
+
+ void ClearMatches();
+ void StoreMatches(cmsys::RegularExpression& re);
+
+ cmState::Snapshot GetStateSnapshot() const;
+
+ const char* GetDefineFlagsCMP0059() const;
+
+ std::string GetExecutionFilePath() const;
+
+ void EnforceDirectoryLevelRules() const;
+
+ void AddEvaluationFile(const std::string &inputFile,
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> outputName,
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> condition,
+ bool inputIsContent);
+ std::vector<cmGeneratorExpressionEvaluationFile*> GetEvaluationFiles() const;
+
+ std::vector<cmExportBuildFileGenerator*>
+ GetExportBuildFileGenerators() const;
+ void RemoveExportBuildFileGeneratorCMP0024(cmExportBuildFileGenerator* gen);
+ void AddExportBuildFileGenerator(cmExportBuildFileGenerator* gen);
+
protected:
// add link libraries and directories to the target
- void AddGlobalLinkInformation(const char* name, cmTarget& target);
+ void AddGlobalLinkInformation(const std::string& name, cmTarget& target);
// Check for a an unused variable
- void CheckForUnused(const char* reason, const char* name) const;
+ void LogUnused(const char* reason, const std::string& name) const;
- std::string Prefix;
- std::vector<std::string> AuxSourceDirectories; //
-
- std::string cmStartDirectory;
- std::string StartOutputDirectory;
- std::string cmHomeDirectory;
- std::string HomeOutputDirectory;
- std::string cmCurrentListFile;
-
- std::string ProjectName; // project name
+ mutable std::set<cmListFileContext> CMP0054ReportedIds;
// libraries, classes, and executables
- cmTargets Targets;
- std::map<std::string, cmTarget*> AliasTargets;
- cmGeneratorTargetsType GeneratorTargets;
+ mutable cmTargets Targets;
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+#ifdef CMake_HAVE_CXX11_UNORDERED_MAP
+ typedef std::unordered_map<std::string, cmTarget*> TargetMap;
+#else
+ typedef cmsys::hash_map<std::string, cmTarget*> TargetMap;
+#endif
+#else
+ typedef std::map<std::string, cmTarget*> TargetMap;
+#endif
+ std::map<std::string, std::string> AliasTargets;
std::vector<cmSourceFile*> SourceFiles;
// Tests
- std::map<cmStdString, cmTest*> Tests;
+ std::map<std::string, cmTest*> Tests;
// The link-library paths. Order matters, use std::vector (not std::set).
std::vector<std::string> LinkDirectories;
// The set of include directories that are marked as system include
// directories.
- std::set<cmStdString> SystemIncludeDirectories;
-
- std::vector<std::string> ListFiles; // list of command files loaded
- std::vector<std::string> OutputFiles; // list of command files loaded
+ std::set<std::string> SystemIncludeDirectories;
+ std::vector<std::string> ListFiles;
+ std::vector<std::string> OutputFiles;
cmTarget::LinkLibraryVectorType LinkLibraries;
std::vector<cmInstallGenerator*> InstallGenerators;
std::vector<cmTestGenerator*> TestGenerators;
- std::string IncludeFileRegularExpression;
std::string ComplainFileRegularExpression;
- std::vector<std::string> SourceFileExtensions;
- std::vector<std::string> HeaderFileExtensions;
std::string DefineFlags;
- std::vector<cmValueWithOrigin> IncludeDirectoriesEntries;
- std::vector<cmValueWithOrigin> CompileOptionsEntries;
- std::vector<cmValueWithOrigin> CompileDefinitionsEntries;
-
// Track the value of the computed DEFINITIONS property.
void AddDefineFlag(const char*, std::string&);
void RemoveDefineFlag(const char*, std::string::size_type, std::string&);
@@ -950,109 +827,101 @@ protected:
#endif
std::vector<cmCommand*> FinalPassCommands;
- cmLocalGenerator* LocalGenerator;
+ cmGlobalGenerator* GlobalGenerator;
bool IsFunctionBlocked(const cmListFileFunction& lff,
cmExecutionStatus &status);
private:
- void Initialize();
+ cmMakefile(const cmMakefile& mf);
+ cmMakefile& operator=(const cmMakefile& mf);
- bool ParseDefineFlag(std::string const& definition, bool remove);
+ cmState::Snapshot StateSnapshot;
- bool EnforceUniqueDir(const char* srcPath, const char* binPath);
+ void ReadListFile(cmListFile const& listFile,
+ const std::string& filenametoread);
- void ReadSources(std::ifstream& fin, bool t);
- friend class cmMakeDepend; // make depend needs direct access
- // to the Sources array
- void PrintStringVector(const char* s, const
- std::vector<std::pair<cmStdString, bool> >& v) const;
- void PrintStringVector(const char* s,
- const std::vector<std::string>& v) const;
+ bool ParseDefineFlag(std::string const& definition, bool remove);
+
+ bool EnforceUniqueDir(const std::string& srcPath,
+ const std::string& binPath) const;
- void AddDefaultDefinitions();
typedef std::vector<cmFunctionBlocker*> FunctionBlockersType;
FunctionBlockersType FunctionBlockers;
std::vector<FunctionBlockersType::size_type> FunctionBlockerBarriers;
void PushFunctionBlockerBarrier();
void PopFunctionBlockerBarrier(bool reportError = true);
- typedef std::map<cmStdString, cmStdString> StringStringMap;
- StringStringMap MacrosMap;
-
- std::map<cmStdString, bool> SubDirectoryOrder;
+ std::stack<int> LoopBlockCounter;
- cmsys::RegularExpression cmDefineRegex;
- cmsys::RegularExpression cmDefine01Regex;
- cmsys::RegularExpression cmAtVarRegex;
+ mutable cmsys::RegularExpression cmDefineRegex;
+ mutable cmsys::RegularExpression cmDefine01Regex;
+ mutable cmsys::RegularExpression cmAtVarRegex;
+ mutable cmsys::RegularExpression cmNamedCurly;
- cmPropertyMap Properties;
+ std::vector<cmMakefile*> UnConfiguredDirectories;
+ std::vector<cmExportBuildFileGenerator*> ExportBuildFileGenerators;
- // should this makefile be processed before or after processing the parent
- bool PreOrder;
+ std::vector<cmGeneratorExpressionEvaluationFile*> EvaluationFiles;
- // Unused variable flags
- bool WarnUnused;
- bool CheckSystemVars;
-
- // stack of list files being read
- std::deque<cmStdString> ListFileStack;
-
- // stack of commands being invoked.
- struct CallStackEntry
- {
- cmListFileContext const* Context;
- cmExecutionStatus* Status;
- };
- typedef std::deque<CallStackEntry> CallStackType;
- CallStackType CallStack;
+ std::vector<cmCommandContext const*> ContextStack;
+ std::vector<cmExecutionStatus*> ExecutionStatusStack;
friend class cmMakefileCall;
+ friend class cmParseFileScope;
- cmTarget* FindBasicTarget(const char* name);
std::vector<cmTarget*> ImportedTargetsOwned;
- std::map<cmStdString, cmTarget*> ImportedTargets;
+ TargetMap ImportedTargets;
// Internal policy stack management.
void PushPolicy(bool weak = false,
cmPolicies::PolicyMap const& pm = cmPolicies::PolicyMap());
void PopPolicy();
- void PushPolicyBarrier();
- void PopPolicyBarrier(bool reportError = true);
+ void PopSnapshot(bool reportError = true);
friend class cmCMakePolicyCommand;
class IncludeScope;
friend class IncludeScope;
-
- // stack of policy settings
- struct PolicyStackEntry: public cmPolicies::PolicyMap
- {
- typedef cmPolicies::PolicyMap derived;
- PolicyStackEntry(bool w = false): derived(), Weak(w) {}
- PolicyStackEntry(derived const& d, bool w = false): derived(d), Weak(w) {}
- PolicyStackEntry(PolicyStackEntry const& r): derived(r), Weak(r.Weak) {}
- bool Weak;
- };
- typedef std::vector<PolicyStackEntry> PolicyStackType;
- PolicyStackType PolicyStack;
- std::vector<PolicyStackType::size_type> PolicyBarriers;
- cmPolicies::PolicyStatus GetPolicyStatusInternal(cmPolicies::PolicyID id);
-
- bool CheckCMP0000;
-
- // Enforce rules about CMakeLists.txt files.
- void EnforceDirectoryLevelRules();
-
- bool GeneratingBuildSystem;
-
- /**
- * Old version of GetSourceFileWithOutput(const char*) kept for
+ class ListFileScope;
+ friend class ListFileScope;
+ class BuildsystemFileScope;
+ friend class BuildsystemFileScope;
+
+
+ // CMP0053 == old
+ cmake::MessageType ExpandVariablesInStringOld(
+ std::string& errorstr,
+ std::string& source,
+ bool escapeQuotes,
+ bool noEscapes,
+ bool atOnly,
+ const char* filename,
+ long line,
+ bool removeEmpty,
+ bool replaceAt) const;
+ // CMP0053 == new
+ cmake::MessageType ExpandVariablesInStringNew(
+ std::string& errorstr,
+ std::string& source,
+ bool escapeQuotes,
+ bool noEscapes,
+ bool atOnly,
+ const char* filename,
+ long line,
+ bool removeEmpty,
+ bool replaceAt) const;
+ /**
+ * Old version of GetSourceFileWithOutput(const std::string&) kept for
* backward-compatibility. It implements a linear search and support
* relative file paths. It is used as a fall back by
- * GetSourceFileWithOutput(const char*).
+ * GetSourceFileWithOutput(const std::string&).
*/
- cmSourceFile *LinearGetSourceFileWithOutput(const char *cname);
+ cmSourceFile *LinearGetSourceFileWithOutput(const std::string& cname) const;
// A map for fast output to input look up.
#if defined(CMAKE_BUILD_WITH_CMAKE)
+#ifdef CMake_HAVE_CXX11_UNORDERED_MAP
+ typedef std::unordered_map<std::string, cmSourceFile*> OutputToSourceMap;
+#else
typedef cmsys::hash_map<std::string, cmSourceFile*> OutputToSourceMap;
+#endif
#else
typedef std::map<std::string, cmSourceFile*> OutputToSourceMap;
#endif
@@ -1062,6 +931,33 @@ private:
cmSourceFile* source);
void UpdateOutputToSourceMap(std::string const& output,
cmSourceFile* source);
+
+ std::vector<cmSourceFile*> QtUiFilesWithOptions;
+
+ bool AddRequiredTargetCFeature(cmTarget *target,
+ const std::string& feature) const;
+
+ bool AddRequiredTargetCxxFeature(cmTarget *target,
+ const std::string& feature) const;
+
+ void CheckNeededCLanguage(const std::string& feature, bool& needC90,
+ bool& needC99, bool& needC11) const;
+ void CheckNeededCxxLanguage(const std::string& feature, bool& needCxx98,
+ bool& needCxx11, bool& needCxx14) const;
+
+ bool HaveCStandardAvailable(cmTarget const* target,
+ const std::string& feature) const;
+ bool HaveCxxStandardAvailable(cmTarget const* target,
+ const std::string& feature) const;
+
+ void CheckForUnusedVariables() const;
+
+ // Unused variable flags
+ bool WarnUnused;
+ bool CheckSystemVars;
+ bool CheckCMP0000;
+ bool IsSourceFileTryCompile;
+ mutable bool SuppressWatches;
};
//----------------------------------------------------------------------------
@@ -1070,16 +966,9 @@ class cmMakefileCall
{
public:
cmMakefileCall(cmMakefile* mf,
- cmListFileContext const& lfc,
- cmExecutionStatus& status): Makefile(mf)
- {
- cmMakefile::CallStackEntry entry = {&lfc, &status};
- this->Makefile->CallStack.push_back(entry);
- }
- ~cmMakefileCall()
- {
- this->Makefile->CallStack.pop_back();
- }
+ cmCommandContext const& lfc,
+ cmExecutionStatus& status);
+ ~cmMakefileCall();
private:
cmMakefile* Makefile;
};
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 3a71bd6eb..9e35e4c2b 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -16,20 +16,19 @@
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
-#include "cmTarget.h"
#include "cmake.h"
//----------------------------------------------------------------------------
cmMakefileExecutableTargetGenerator
-::cmMakefileExecutableTargetGenerator(cmTarget* target):
+::cmMakefileExecutableTargetGenerator(cmGeneratorTarget* target):
cmMakefileTargetGenerator(target)
{
this->CustomCommandDriver = OnDepends;
- this->Target->GetExecutableNames(
+ this->GeneratorTarget->GetExecutableNames(
this->TargetNameOut, this->TargetNameReal, this->TargetNameImport,
this->TargetNamePDB, this->ConfigName);
- this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target,
+ this->OSXBundleGenerator = new cmOSXBundleGenerator(target,
this->ConfigName);
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
}
@@ -58,7 +57,7 @@ void cmMakefileExecutableTargetGenerator::WriteRuleFiles()
// write the link rules
this->WriteExecutableRule(false);
- if(this->Target->NeedRelinkBeforeInstall(this->ConfigName))
+ if(this->GeneratorTarget->NeedRelinkBeforeInstall(this->ConfigName))
{
// Write rules to link an installable version of the target.
this->WriteExecutableRule(true);
@@ -94,13 +93,13 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
std::string targetNameReal;
std::string targetNameImport;
std::string targetNamePDB;
- this->Target->GetExecutableNames
+ this->GeneratorTarget->GetExecutableNames
(targetName, targetNameReal, targetNameImport, targetNamePDB,
this->ConfigName);
// Construct the full path version of the names.
- std::string outpath = this->Target->GetDirectory(this->ConfigName);
- if(this->Target->IsAppBundleOnApple())
+ std::string outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
+ if(this->GeneratorTarget->IsAppBundleOnApple())
{
this->OSXBundleGenerator->CreateAppBundle(targetName, outpath);
}
@@ -108,7 +107,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
std::string outpathImp;
if(relink)
{
- outpath = this->Makefile->GetStartOutputDirectory();
+ outpath = this->Makefile->GetCurrentBinaryDirectory();
outpath += cmake::GetCMakeFilesDirectory();
outpath += "/CMakeRelink.dir";
cmSystemTools::MakeDirectory(outpath.c_str());
@@ -123,13 +122,18 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
cmSystemTools::MakeDirectory(outpath.c_str());
if(!targetNameImport.empty())
{
- outpathImp = this->Target->GetDirectory(this->ConfigName, true);
+ outpathImp = this->GeneratorTarget->GetDirectory(this->ConfigName, true);
cmSystemTools::MakeDirectory(outpathImp.c_str());
outpathImp += "/";
}
}
- std::string pdbOutputPath = this->Target->GetPDBDirectory();
+ std::string compilePdbOutputPath =
+ this->GeneratorTarget->GetCompilePDBDirectory(this->ConfigName);
+ cmSystemTools::MakeDirectory(compilePdbOutputPath.c_str());
+
+ std::string pdbOutputPath =
+ this->GeneratorTarget->GetPDBDirectory(this->ConfigName);
cmSystemTools::MakeDirectory(pdbOutputPath.c_str());
pdbOutputPath += "/";
@@ -138,44 +142,48 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
std::string targetFullPathPDB = pdbOutputPath + targetNamePDB;
std::string targetFullPathImport = outpathImp + targetNameImport;
std::string targetOutPathPDB =
- this->Convert(targetFullPathPDB.c_str(),
+ this->Convert(targetFullPathPDB,
cmLocalGenerator::NONE,
cmLocalGenerator::SHELL);
// Convert to the output path to use in constructing commands.
std::string targetOutPath =
- this->Convert(targetFullPath.c_str(),
+ this->Convert(targetFullPath,
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::SHELL);
std::string targetOutPathReal =
- this->Convert(targetFullPathReal.c_str(),
+ this->Convert(targetFullPathReal,
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::SHELL);
std::string targetOutPathImport =
- this->Convert(targetFullPathImport.c_str(),
+ this->Convert(targetFullPathImport,
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::SHELL);
// Get the language to use for linking this executable.
- const char* linkLanguage =
- this->Target->GetLinkerLanguage(this->ConfigName);
+ std::string linkLanguage =
+ this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
// Make sure we have a link language.
- if(!linkLanguage)
+ if(linkLanguage.empty())
{
cmSystemTools::Error("Cannot determine link language for target \"",
- this->Target->GetName(), "\".");
+ this->GeneratorTarget->GetName().c_str(), "\".");
return;
}
+ this->NumberOfProgressActions++;
if(!this->NoRuleMessages)
{
+ cmLocalUnixMakefileGenerator3::EchoProgress progress;
+ this->MakeEchoProgress(progress);
// Add the link message.
std::string buildEcho = "Linking ";
buildEcho += linkLanguage;
buildEcho += " executable ";
buildEcho += targetOutPath;
this->LocalGenerator->AppendEcho(commands, buildEcho.c_str(),
- cmLocalUnixMakefileGenerator3::EchoLink);
+ cmLocalUnixMakefileGenerator3::EchoLink,
+ &progress);
}
// Build a list of compiler flags and linker flags.
@@ -188,7 +196,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
this->ConfigName);
- if(this->Target->GetPropertyAsBool("WIN32_EXECUTABLE"))
+ if(this->GeneratorTarget->GetPropertyAsBool("WIN32_EXECUTABLE"))
{
this->LocalGenerator->AppendFlags
(linkFlags, this->Makefile->GetDefinition("CMAKE_CREATE_WIN32_EXE"));
@@ -200,13 +208,13 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
}
// Add symbol export flags if necessary.
- if(this->Target->IsExecutableWithExports())
+ if(this->GeneratorTarget->IsExecutableWithExports())
{
std::string export_flag_var = "CMAKE_EXE_EXPORTS_";
export_flag_var += linkLanguage;
export_flag_var += "_FLAG";
this->LocalGenerator->AppendFlags
- (linkFlags, this->Makefile->GetDefinition(export_flag_var.c_str()));
+ (linkFlags, this->Makefile->GetDefinition(export_flag_var));
}
// Add language feature flags.
@@ -217,18 +225,18 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// Add target-specific linker flags.
this->LocalGenerator->AppendFlags
- (linkFlags, this->Target->GetProperty("LINK_FLAGS"));
+ (linkFlags, this->GeneratorTarget->GetProperty("LINK_FLAGS"));
std::string linkFlagsConfig = "LINK_FLAGS_";
linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName);
this->LocalGenerator->AppendFlags
- (linkFlags, this->Target->GetProperty(linkFlagsConfig.c_str()));
+ (linkFlags, this->GeneratorTarget->GetProperty(linkFlagsConfig));
this->AddModuleDefinitionFlag(linkFlags);
// Construct a list of files associated with this executable that
// may need to be cleaned.
std::vector<std::string> exeCleanFiles;
- exeCleanFiles.push_back(this->Convert(targetFullPath.c_str(),
+ exeCleanFiles.push_back(this->Convert(targetFullPath,
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::UNCHANGED));
#ifdef _WIN32
@@ -240,19 +248,19 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
#endif
if(targetNameReal != targetName)
{
- exeCleanFiles.push_back(this->Convert(targetFullPathReal.c_str(),
+ exeCleanFiles.push_back(this->Convert(targetFullPathReal,
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::UNCHANGED));
}
if(!targetNameImport.empty())
{
- exeCleanFiles.push_back(this->Convert(targetFullPathImport.c_str(),
+ exeCleanFiles.push_back(this->Convert(targetFullPathImport,
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::UNCHANGED));
std::string implib;
- if(this->Target->GetImplibGNUtoMS(targetFullPathImport, implib))
+ if(this->GeneratorTarget->GetImplibGNUtoMS(targetFullPathImport, implib))
{
- exeCleanFiles.push_back(this->Convert(implib.c_str(),
+ exeCleanFiles.push_back(this->Convert(implib,
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::UNCHANGED));
}
@@ -262,7 +270,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// cleaned. We do not want to delete the .pdb file just before
// linking the target.
this->CleanFiles.push_back
- (this->Convert(targetFullPathPDB.c_str(),
+ (this->Convert(targetFullPathPDB,
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::UNCHANGED));
@@ -270,11 +278,13 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
if(!relink)
{
this->LocalGenerator
- ->AppendCustomCommands(commands, this->Target->GetPreBuildCommands(),
- this->Target);
+ ->AppendCustomCommands(commands,
+ this->GeneratorTarget->GetPreBuildCommands(),
+ this->GeneratorTarget);
this->LocalGenerator
- ->AppendCustomCommands(commands, this->Target->GetPreLinkCommands(),
- this->Target);
+ ->AppendCustomCommands(commands,
+ this->GeneratorTarget->GetPreLinkCommands(),
+ this->GeneratorTarget);
}
// Determine whether a link script will be used.
@@ -285,10 +295,10 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
std::string linkRuleVar = "CMAKE_";
linkRuleVar += linkLanguage;
linkRuleVar += "_LINK_EXECUTABLE";
- std::string linkRule = this->GetLinkRule(linkRuleVar.c_str());
+ std::string linkRule = this->GetLinkRule(linkRuleVar);
std::vector<std::string> commands1;
cmSystemTools::ExpandListArgument(linkRule, real_link_commands);
- if(this->Target->IsExecutableWithExports())
+ if(this->GeneratorTarget->IsExecutableWithExports())
{
// If a separate rule for creating an import library is specified
// add it now.
@@ -296,65 +306,84 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
implibRuleVar += linkLanguage;
implibRuleVar += "_CREATE_IMPORT_LIBRARY";
if(const char* rule =
- this->Makefile->GetDefinition(implibRuleVar.c_str()))
+ this->Makefile->GetDefinition(implibRuleVar))
{
cmSystemTools::ExpandListArgument(rule, real_link_commands);
}
}
// Select whether to use a response file for objects.
- bool useResponseFile = false;
+ bool useResponseFileForObjects = false;
{
std::string responseVar = "CMAKE_";
responseVar += linkLanguage;
responseVar += "_USE_RESPONSE_FILE_FOR_OBJECTS";
- if(this->Makefile->IsOn(responseVar.c_str()))
+ if(this->Makefile->IsOn(responseVar))
+ {
+ useResponseFileForObjects = true;
+ }
+ }
+
+ // Select whether to use a response file for libraries.
+ bool useResponseFileForLibs = false;
+ {
+ std::string responseVar = "CMAKE_";
+ responseVar += linkLanguage;
+ responseVar += "_USE_RESPONSE_FILE_FOR_LIBRARIES";
+ if(this->Makefile->IsOn(responseVar))
{
- useResponseFile = true;
+ useResponseFileForLibs = true;
}
}
// Expand the rule variables.
{
+ bool useWatcomQuote = this->Makefile->IsOn(linkRuleVar+"_USE_WATCOM_QUOTE");
+
// Set path conversion for link script shells.
this->LocalGenerator->SetLinkScriptShell(useLinkScript);
// Collect up flags to link in needed libraries.
std::string linkLibs;
- std::string frameworkPath;
- std::string linkPath;
- this->LocalGenerator->OutputLinkLibraries(linkLibs, frameworkPath, linkPath,
- *this->GeneratorTarget,
- relink);
- linkLibs = frameworkPath + linkPath + linkLibs;
+ this->CreateLinkLibs(linkLibs, relink, useResponseFileForLibs, depends,
+ useWatcomQuote);
+
// Construct object file lists that may be needed to expand the
// rule.
std::string buildObjs;
- this->CreateObjectLists(useLinkScript, false, useResponseFile,
- buildObjs, depends);
+ this->CreateObjectLists(useLinkScript, false,
+ useResponseFileForObjects, buildObjs, depends,
+ useWatcomQuote);
+
+ std::string manifests = this->GetManifests();
cmLocalGenerator::RuleVariables vars;
vars.RuleLauncher = "RULE_LAUNCH_LINK";
- vars.CMTarget = this->Target;
- vars.Language = linkLanguage;
+ vars.CMTarget = this->GeneratorTarget;
+ vars.Language = linkLanguage.c_str();
vars.Objects = buildObjs.c_str();
- std::string objectDir = this->Target->GetSupportDirectory();
- objectDir = this->Convert(objectDir.c_str(),
+ std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
+ objectDir = this->Convert(objectDir,
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::SHELL);
vars.ObjectDir = objectDir.c_str();
- vars.Target = targetOutPathReal.c_str();
+ cmLocalGenerator::OutputFormat output = (useWatcomQuote) ?
+ cmLocalGenerator::WATCOMQUOTE : cmLocalGenerator::SHELL;
+ std::string target = this->Convert(targetFullPathReal,
+ cmLocalGenerator::START_OUTPUT,
+ output);
+ vars.Target = target.c_str();
vars.TargetPDB = targetOutPathPDB.c_str();
// Setup the target version.
std::string targetVersionMajor;
std::string targetVersionMinor;
{
- cmOStringStream majorStream;
- cmOStringStream minorStream;
+ std::ostringstream majorStream;
+ std::ostringstream minorStream;
int major;
int minor;
- this->Target->GetTargetVersion(major, minor);
+ this->GeneratorTarget->GetTargetVersion(major, minor);
majorStream << major;
minorStream << minor;
targetVersionMajor = majorStream.str();
@@ -366,6 +395,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
vars.LinkLibraries = linkLibs.c_str();
vars.Flags = flags.c_str();
vars.LinkFlags = linkFlags.c_str();
+ vars.Manifests = manifests.c_str();
+
// Expand placeholders in the commands.
this->LocalGenerator->TargetImplib = targetOutPathImport;
for(std::vector<std::string>::iterator i = real_link_commands.begin();
@@ -394,7 +425,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
}
this->LocalGenerator->CreateCDCommand
(commands1,
- this->Makefile->GetStartOutputDirectory(),
+ this->Makefile->GetCurrentBinaryDirectory(),
cmLocalGenerator::HOME_OUTPUT);
commands.insert(commands.end(), commands1.begin(), commands1.end());
commands1.clear();
@@ -408,7 +439,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
symlink += targetOutPath;
commands1.push_back(symlink);
this->LocalGenerator->CreateCDCommand(commands1,
- this->Makefile->GetStartOutputDirectory(),
+ this->Makefile->GetCurrentBinaryDirectory(),
cmLocalGenerator::HOME_OUTPUT);
commands.insert(commands.end(), commands1.begin(), commands1.end());
commands1.clear();
@@ -418,14 +449,15 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
if(!relink)
{
this->LocalGenerator->
- AppendCustomCommands(commands, this->Target->GetPostBuildCommands(),
- this->Target);
+ AppendCustomCommands(commands,
+ this->GeneratorTarget->GetPostBuildCommands(),
+ this->GeneratorTarget);
}
// Write the build rule.
this->LocalGenerator->WriteMakeRule(*this->BuildFileStream,
0,
- targetFullPathReal.c_str(),
+ targetFullPathReal,
depends, commands, false);
// The symlink name for the target should depend on the real target
@@ -435,14 +467,14 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
{
depends.clear();
commands.clear();
- depends.push_back(targetFullPathReal.c_str());
+ depends.push_back(targetFullPathReal);
this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
- targetFullPath.c_str(),
+ targetFullPath,
depends, commands, false);
}
// Write the main driver rule to build everything in this target.
- this->WriteTargetDriverRule(targetFullPath.c_str(), relink);
+ this->WriteTargetDriverRule(targetFullPath, relink);
// Clean all the possible executable names and symlinks.
this->CleanFiles.insert(this->CleanFiles.end(),
diff --git a/Source/cmMakefileExecutableTargetGenerator.h b/Source/cmMakefileExecutableTargetGenerator.h
index 3b18166ff..940226b1a 100644
--- a/Source/cmMakefileExecutableTargetGenerator.h
+++ b/Source/cmMakefileExecutableTargetGenerator.h
@@ -17,7 +17,7 @@
class cmMakefileExecutableTargetGenerator: public cmMakefileTargetGenerator
{
public:
- cmMakefileExecutableTargetGenerator(cmTarget* target);
+ cmMakefileExecutableTargetGenerator(cmGeneratorTarget* target);
virtual ~cmMakefileExecutableTargetGenerator();
/* the main entry point for this class. Writes the Makefiles associated
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index ffe68e5b2..1923ea4fb 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -16,20 +16,23 @@
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
-#include "cmTarget.h"
#include "cmake.h"
+#include "cmAlgorithms.h"
//----------------------------------------------------------------------------
cmMakefileLibraryTargetGenerator
-::cmMakefileLibraryTargetGenerator(cmTarget* target):
+::cmMakefileLibraryTargetGenerator(cmGeneratorTarget* target):
cmMakefileTargetGenerator(target)
{
this->CustomCommandDriver = OnDepends;
- this->Target->GetLibraryNames(
- this->TargetNameOut, this->TargetNameSO, this->TargetNameReal,
- this->TargetNameImport, this->TargetNamePDB, this->ConfigName);
+ if (this->GeneratorTarget->GetType() != cmState::INTERFACE_LIBRARY)
+ {
+ this->GeneratorTarget->GetLibraryNames(
+ this->TargetNameOut, this->TargetNameSO, this->TargetNameReal,
+ this->TargetNameImport, this->TargetNamePDB, this->ConfigName);
+ }
- this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target,
+ this->OSXBundleGenerator = new cmOSXBundleGenerator(target,
this->ConfigName);
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
}
@@ -58,28 +61,28 @@ void cmMakefileLibraryTargetGenerator::WriteRuleFiles()
// write the link rules
// Write the rule for this target type.
- switch(this->Target->GetType())
+ switch(this->GeneratorTarget->GetType())
{
- case cmTarget::STATIC_LIBRARY:
+ case cmState::STATIC_LIBRARY:
this->WriteStaticLibraryRules();
break;
- case cmTarget::SHARED_LIBRARY:
+ case cmState::SHARED_LIBRARY:
this->WriteSharedLibraryRules(false);
- if(this->Target->NeedRelinkBeforeInstall(this->ConfigName))
+ if(this->GeneratorTarget->NeedRelinkBeforeInstall(this->ConfigName))
{
// Write rules to link an installable version of the target.
this->WriteSharedLibraryRules(true);
}
break;
- case cmTarget::MODULE_LIBRARY:
+ case cmState::MODULE_LIBRARY:
this->WriteModuleLibraryRules(false);
- if(this->Target->NeedRelinkBeforeInstall(this->ConfigName))
+ if(this->GeneratorTarget->NeedRelinkBeforeInstall(this->ConfigName))
{
// Write rules to link an installable version of the target.
this->WriteModuleLibraryRules(true);
}
break;
- case cmTarget::OBJECT_LIBRARY:
+ case cmState::OBJECT_LIBRARY:
this->WriteObjectLibraryRules();
break;
default:
@@ -110,131 +113,120 @@ void cmMakefileLibraryTargetGenerator::WriteObjectLibraryRules()
// Add post-build rules.
this->LocalGenerator->
- AppendCustomCommands(commands, this->Target->GetPostBuildCommands(),
- this->Target);
+ AppendCustomCommands(commands,
+ this->GeneratorTarget->GetPostBuildCommands(),
+ this->GeneratorTarget);
// Depend on the object files.
this->AppendObjectDepends(depends);
// Write the rule.
this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
- this->Target->GetName(),
+ this->GeneratorTarget->GetName(),
depends, commands, true);
// Write the main driver rule to build everything in this target.
- this->WriteTargetDriverRule(this->Target->GetName(), false);
+ this->WriteTargetDriverRule(this->GeneratorTarget->GetName(), false);
}
//----------------------------------------------------------------------------
void cmMakefileLibraryTargetGenerator::WriteStaticLibraryRules()
{
- const char* linkLanguage =
- this->Target->GetLinkerLanguage(this->ConfigName);
+ std::string linkLanguage =
+ this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
std::string linkRuleVar = "CMAKE_";
- if (linkLanguage)
- {
- linkRuleVar += linkLanguage;
- }
+ linkRuleVar += linkLanguage;
linkRuleVar += "_CREATE_STATIC_LIBRARY";
if(this->GetFeatureAsBool("INTERPROCEDURAL_OPTIMIZATION") &&
- this->Makefile->GetDefinition((linkRuleVar+"_IPO").c_str()))
+ this->Makefile->GetDefinition(linkRuleVar+"_IPO"))
{
linkRuleVar += "_IPO";
}
std::string extraFlags;
this->LocalGenerator->GetStaticLibraryFlags(extraFlags,
- cmSystemTools::UpperCase(this->ConfigName), this->Target);
- this->WriteLibraryRules(linkRuleVar.c_str(), extraFlags.c_str(), false);
+ cmSystemTools::UpperCase(this->ConfigName), this->GeneratorTarget);
+ this->WriteLibraryRules(linkRuleVar, extraFlags, false);
}
//----------------------------------------------------------------------------
void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
{
- if(this->Target->IsFrameworkOnApple())
+ if(this->GeneratorTarget->IsFrameworkOnApple())
{
this->WriteFrameworkRules(relink);
return;
}
- const char* linkLanguage =
- this->Target->GetLinkerLanguage(this->ConfigName);
+ std::string linkLanguage =
+ this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
std::string linkRuleVar = "CMAKE_";
- if (linkLanguage)
- {
- linkRuleVar += linkLanguage;
- }
+ linkRuleVar += linkLanguage;
linkRuleVar += "_CREATE_SHARED_LIBRARY";
std::string extraFlags;
this->LocalGenerator->AppendFlags
- (extraFlags, this->Target->GetProperty("LINK_FLAGS"));
+ (extraFlags, this->GeneratorTarget->GetProperty("LINK_FLAGS"));
std::string linkFlagsConfig = "LINK_FLAGS_";
linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName);
this->LocalGenerator->AppendFlags
- (extraFlags, this->Target->GetProperty(linkFlagsConfig.c_str()));
+ (extraFlags, this->GeneratorTarget->GetProperty(linkFlagsConfig));
this->LocalGenerator->AddConfigVariableFlags
(extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->ConfigName);
this->AddModuleDefinitionFlag(extraFlags);
- this->WriteLibraryRules(linkRuleVar.c_str(), extraFlags.c_str(), relink);
+ this->WriteLibraryRules(linkRuleVar, extraFlags, relink);
}
//----------------------------------------------------------------------------
void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
{
- const char* linkLanguage =
- this->Target->GetLinkerLanguage(this->ConfigName);
+ std::string linkLanguage =
+ this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
std::string linkRuleVar = "CMAKE_";
- if (linkLanguage)
- {
- linkRuleVar += linkLanguage;
- }
+ linkRuleVar += linkLanguage;
linkRuleVar += "_CREATE_SHARED_MODULE";
std::string extraFlags;
this->LocalGenerator->AppendFlags(extraFlags,
- this->Target->GetProperty("LINK_FLAGS"));
+ this->GeneratorTarget->GetProperty("LINK_FLAGS"));
std::string linkFlagsConfig = "LINK_FLAGS_";
linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName);
this->LocalGenerator->AppendFlags
- (extraFlags, this->Target->GetProperty(linkFlagsConfig.c_str()));
+ (extraFlags, this->GeneratorTarget->GetProperty(linkFlagsConfig));
this->LocalGenerator->AddConfigVariableFlags
(extraFlags, "CMAKE_MODULE_LINKER_FLAGS", this->ConfigName);
this->AddModuleDefinitionFlag(extraFlags);
- this->WriteLibraryRules(linkRuleVar.c_str(), extraFlags.c_str(), relink);
+ this->WriteLibraryRules(linkRuleVar, extraFlags, relink);
}
//----------------------------------------------------------------------------
void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink)
{
- const char* linkLanguage =
- this->Target->GetLinkerLanguage(this->ConfigName);
+ std::string linkLanguage =
+ this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
std::string linkRuleVar = "CMAKE_";
- if (linkLanguage)
- {
- linkRuleVar += linkLanguage;
- }
+ linkRuleVar += linkLanguage;
linkRuleVar += "_CREATE_MACOSX_FRAMEWORK";
std::string extraFlags;
this->LocalGenerator->AppendFlags(extraFlags,
- this->Target->GetProperty("LINK_FLAGS"));
+ this->GeneratorTarget->GetProperty("LINK_FLAGS"));
std::string linkFlagsConfig = "LINK_FLAGS_";
linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName);
this->LocalGenerator->AppendFlags
- (extraFlags, this->Target->GetProperty(linkFlagsConfig.c_str()));
+ (extraFlags, this->GeneratorTarget->GetProperty(linkFlagsConfig));
this->LocalGenerator->AddConfigVariableFlags
(extraFlags, "CMAKE_MACOSX_FRAMEWORK_LINKER_FLAGS", this->ConfigName);
- this->WriteLibraryRules(linkRuleVar.c_str(), extraFlags.c_str(), relink);
+ this->WriteLibraryRules(linkRuleVar, extraFlags, relink);
}
//----------------------------------------------------------------------------
void cmMakefileLibraryTargetGenerator::WriteLibraryRules
-(const char* linkRuleVar, const char* extraFlags, bool relink)
+(const std::string& linkRuleVar, const std::string& extraFlags, bool relink)
{
// TODO: Merge the methods that call this method to avoid
// code duplication.
@@ -245,14 +237,14 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
this->AppendLinkDepends(depends);
// Get the language to use for linking this library.
- const char* linkLanguage =
- this->Target->GetLinkerLanguage(this->ConfigName);
+ std::string linkLanguage =
+ this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
// Make sure we have a link language.
- if(!linkLanguage)
+ if(linkLanguage.empty())
{
cmSystemTools::Error("Cannot determine link language for target \"",
- this->Target->GetName(), "\".");
+ this->GeneratorTarget->GetName().c_str(), "\".");
return;
}
@@ -261,8 +253,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
this->LocalGenerator->AppendFlags(linkFlags, extraFlags);
// Add OSX version flags, if any.
- if(this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
- this->Target->GetType() == cmTarget::MODULE_LIBRARY)
+ if(this->GeneratorTarget->GetType() == cmState::SHARED_LIBRARY ||
+ this->GeneratorTarget->GetType() == cmState::MODULE_LIBRARY)
{
this->AppendOSXVerFlag(linkFlags, linkLanguage, "COMPATIBILITY", true);
this->AppendOSXVerFlag(linkFlags, linkLanguage, "CURRENT", false);
@@ -274,28 +266,28 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
std::string targetNameReal;
std::string targetNameImport;
std::string targetNamePDB;
- this->Target->GetLibraryNames(
+ this->GeneratorTarget->GetLibraryNames(
targetName, targetNameSO, targetNameReal, targetNameImport, targetNamePDB,
this->ConfigName);
// Construct the full path version of the names.
std::string outpath;
std::string outpathImp;
- if(this->Target->IsFrameworkOnApple())
+ if(this->GeneratorTarget->IsFrameworkOnApple())
{
- outpath = this->Target->GetDirectory(this->ConfigName);
+ outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
this->OSXBundleGenerator->CreateFramework(targetName, outpath);
outpath += "/";
}
- else if(this->Target->IsCFBundleOnApple())
+ else if(this->GeneratorTarget->IsCFBundleOnApple())
{
- outpath = this->Target->GetDirectory(this->ConfigName);
+ outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
this->OSXBundleGenerator->CreateCFBundle(targetName, outpath);
outpath += "/";
}
else if(relink)
{
- outpath = this->Makefile->GetStartOutputDirectory();
+ outpath = this->Makefile->GetCurrentBinaryDirectory();
outpath += cmake::GetCMakeFilesDirectory();
outpath += "/CMakeRelink.dir";
cmSystemTools::MakeDirectory(outpath.c_str());
@@ -307,18 +299,23 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
}
else
{
- outpath = this->Target->GetDirectory(this->ConfigName);
+ outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
cmSystemTools::MakeDirectory(outpath.c_str());
outpath += "/";
if(!targetNameImport.empty())
{
- outpathImp = this->Target->GetDirectory(this->ConfigName, true);
+ outpathImp = this->GeneratorTarget->GetDirectory(this->ConfigName, true);
cmSystemTools::MakeDirectory(outpathImp.c_str());
outpathImp += "/";
}
}
- std::string pdbOutputPath = this->Target->GetPDBDirectory();
+ std::string compilePdbOutputPath =
+ this->GeneratorTarget->GetCompilePDBDirectory(this->ConfigName);
+ cmSystemTools::MakeDirectory(compilePdbOutputPath.c_str());
+
+ std::string pdbOutputPath =
+ this->GeneratorTarget->GetPDBDirectory(this->ConfigName);
cmSystemTools::MakeDirectory(pdbOutputPath.c_str());
pdbOutputPath += "/";
@@ -331,36 +328,39 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
// Construct the output path version of the names for use in command
// arguments.
std::string targetOutPathPDB =
- this->Convert(targetFullPathPDB.c_str(),cmLocalGenerator::NONE,
+ this->Convert(targetFullPathPDB,cmLocalGenerator::NONE,
cmLocalGenerator::SHELL);
std::string targetOutPath =
- this->Convert(targetFullPath.c_str(),cmLocalGenerator::START_OUTPUT,
+ this->Convert(targetFullPath,cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::SHELL);
std::string targetOutPathSO =
- this->Convert(targetFullPathSO.c_str(),cmLocalGenerator::START_OUTPUT,
+ this->Convert(targetFullPathSO,cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::SHELL);
std::string targetOutPathReal =
- this->Convert(targetFullPathReal.c_str(),cmLocalGenerator::START_OUTPUT,
+ this->Convert(targetFullPathReal,cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::SHELL);
std::string targetOutPathImport =
- this->Convert(targetFullPathImport.c_str(),cmLocalGenerator::START_OUTPUT,
+ this->Convert(targetFullPathImport,cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::SHELL);
+ this->NumberOfProgressActions++;
if(!this->NoRuleMessages)
{
+ cmLocalUnixMakefileGenerator3::EchoProgress progress;
+ this->MakeEchoProgress(progress);
// Add the link message.
std::string buildEcho = "Linking ";
buildEcho += linkLanguage;
- switch(this->Target->GetType())
+ switch(this->GeneratorTarget->GetType())
{
- case cmTarget::STATIC_LIBRARY:
+ case cmState::STATIC_LIBRARY:
buildEcho += " static library ";
break;
- case cmTarget::SHARED_LIBRARY:
+ case cmState::SHARED_LIBRARY:
buildEcho += " shared library ";
break;
- case cmTarget::MODULE_LIBRARY:
- if (this->Target->IsCFBundleOnApple())
+ case cmState::MODULE_LIBRARY:
+ if (this->GeneratorTarget->IsCFBundleOnApple())
buildEcho += " CFBundle";
buildEcho += " shared module ";
break;
@@ -370,16 +370,17 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
}
buildEcho += targetOutPath.c_str();
this->LocalGenerator->AppendEcho(commands, buildEcho.c_str(),
- cmLocalUnixMakefileGenerator3::EchoLink);
+ cmLocalUnixMakefileGenerator3::EchoLink,
+ &progress);
}
const char* forbiddenFlagVar = 0;
- switch(this->Target->GetType())
+ switch(this->GeneratorTarget->GetType())
{
- case cmTarget::SHARED_LIBRARY:
+ case cmState::SHARED_LIBRARY:
forbiddenFlagVar = "_CREATE_SHARED_LIBRARY_FORBIDDEN_FLAGS";
break;
- case cmTarget::MODULE_LIBRARY:
+ case cmState::MODULE_LIBRARY:
forbiddenFlagVar = "_CREATE_SHARED_MODULE_FORBIDDEN_FLAGS";
break;
default: break;
@@ -387,31 +388,31 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
// Clean files associated with this library.
std::vector<std::string> libCleanFiles;
- libCleanFiles.push_back(this->Convert(targetFullPath.c_str(),
+ libCleanFiles.push_back(this->Convert(targetFullPath,
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::UNCHANGED));
if(targetNameReal != targetName)
{
- libCleanFiles.push_back(this->Convert(targetFullPathReal.c_str(),
+ libCleanFiles.push_back(this->Convert(targetFullPathReal,
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::UNCHANGED));
}
if(targetNameSO != targetName &&
targetNameSO != targetNameReal)
{
- libCleanFiles.push_back(this->Convert(targetFullPathSO.c_str(),
+ libCleanFiles.push_back(this->Convert(targetFullPathSO,
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::UNCHANGED));
}
if(!targetNameImport.empty())
{
- libCleanFiles.push_back(this->Convert(targetFullPathImport.c_str(),
+ libCleanFiles.push_back(this->Convert(targetFullPathImport,
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::UNCHANGED));
std::string implib;
- if(this->Target->GetImplibGNUtoMS(targetFullPathImport, implib))
+ if(this->GeneratorTarget->GetImplibGNUtoMS(targetFullPathImport, implib))
{
- libCleanFiles.push_back(this->Convert(implib.c_str(),
+ libCleanFiles.push_back(this->Convert(implib,
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::UNCHANGED));
}
@@ -421,14 +422,14 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
// cleaned. We do not want to delete the .pdb file just before
// linking the target.
this->CleanFiles.push_back
- (this->Convert(targetFullPathPDB.c_str(),
+ (this->Convert(targetFullPathPDB,
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::UNCHANGED));
#ifdef _WIN32
// There may be a manifest file for this target. Add it to the
// clean set just in case.
- if(this->Target->GetType() != cmTarget::STATIC_LIBRARY)
+ if(this->GeneratorTarget->GetType() != cmState::STATIC_LIBRARY)
{
libCleanFiles.push_back(
this->Convert((targetFullPath+".manifest").c_str(),
@@ -440,13 +441,13 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
std::vector<std::string> commands1;
// Add a command to remove any existing files for this library.
// for static libs only
- if(this->Target->GetType() == cmTarget::STATIC_LIBRARY)
+ if(this->GeneratorTarget->GetType() == cmState::STATIC_LIBRARY)
{
this->LocalGenerator->AppendCleanCommand(commands1, libCleanFiles,
- *this->Target, "target");
+ this->GeneratorTarget, "target");
this->LocalGenerator->CreateCDCommand
(commands1,
- this->Makefile->GetStartOutputDirectory(),
+ this->Makefile->GetCurrentBinaryDirectory(),
cmLocalGenerator::HOME_OUTPUT);
commands.insert(commands.end(), commands1.begin(), commands1.end());
commands1.clear();
@@ -456,25 +457,39 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
if(!relink)
{
this->LocalGenerator
- ->AppendCustomCommands(commands, this->Target->GetPreBuildCommands(),
- this->Target);
+ ->AppendCustomCommands(commands,
+ this->GeneratorTarget->GetPreBuildCommands(),
+ this->GeneratorTarget);
this->LocalGenerator
- ->AppendCustomCommands(commands, this->Target->GetPreLinkCommands(),
- this->Target);
+ ->AppendCustomCommands(commands,
+ this->GeneratorTarget->GetPreLinkCommands(),
+ this->GeneratorTarget);
}
// Determine whether a link script will be used.
bool useLinkScript = this->GlobalGenerator->GetUseLinkScript();
// Select whether to use a response file for objects.
- bool useResponseFile = false;
+ bool useResponseFileForObjects = false;
{
std::string responseVar = "CMAKE_";
responseVar += linkLanguage;
responseVar += "_USE_RESPONSE_FILE_FOR_OBJECTS";
- if(this->Makefile->IsOn(responseVar.c_str()))
+ if(this->Makefile->IsOn(responseVar))
{
- useResponseFile = true;
+ useResponseFileForObjects = true;
+ }
+ }
+
+ // Select whether to use a response file for libraries.
+ bool useResponseFileForLibs = false;
+ {
+ std::string responseVar = "CMAKE_";
+ responseVar += linkLanguage;
+ responseVar += "_USE_RESPONSE_FILE_FOR_LIBRARIES";
+ if(this->Makefile->IsOn(responseVar))
+ {
+ useResponseFileForLibs = true;
}
}
@@ -484,28 +499,28 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
std::vector<std::string> archiveAppendCommands;
std::vector<std::string> archiveFinishCommands;
std::string::size_type archiveCommandLimit = std::string::npos;
- if(this->Target->GetType() == cmTarget::STATIC_LIBRARY)
+ if(this->GeneratorTarget->GetType() == cmState::STATIC_LIBRARY)
{
haveStaticLibraryRule =
this->Makefile->GetDefinition(linkRuleVar)? true:false;
std::string arCreateVar = "CMAKE_";
arCreateVar += linkLanguage;
arCreateVar += "_ARCHIVE_CREATE";
- if(const char* rule = this->Makefile->GetDefinition(arCreateVar.c_str()))
+ if(const char* rule = this->Makefile->GetDefinition(arCreateVar))
{
cmSystemTools::ExpandListArgument(rule, archiveCreateCommands);
}
std::string arAppendVar = "CMAKE_";
arAppendVar += linkLanguage;
arAppendVar += "_ARCHIVE_APPEND";
- if(const char* rule = this->Makefile->GetDefinition(arAppendVar.c_str()))
+ if(const char* rule = this->Makefile->GetDefinition(arAppendVar))
{
cmSystemTools::ExpandListArgument(rule, archiveAppendCommands);
}
std::string arFinishVar = "CMAKE_";
arFinishVar += linkLanguage;
arFinishVar += "_ARCHIVE_FINISH";
- if(const char* rule = this->Makefile->GetDefinition(arFinishVar.c_str()))
+ if(const char* rule = this->Makefile->GetDefinition(arFinishVar))
{
cmSystemTools::ExpandListArgument(rule, archiveFinishCommands);
}
@@ -521,7 +536,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
useLinkScript = true;
// Archiving rules never use a response file.
- useResponseFile = false;
+ useResponseFileForObjects = false;
// Limit the length of individual object lists to less than the
// 32K command line length limit on Windows. We could make this a
@@ -532,26 +547,79 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
// Expand the rule variables.
std::vector<std::string> real_link_commands;
{
+ bool useWatcomQuote = this->Makefile->IsOn(linkRuleVar+"_USE_WATCOM_QUOTE");
+
// Set path conversion for link script shells.
this->LocalGenerator->SetLinkScriptShell(useLinkScript);
// Collect up flags to link in needed libraries.
std::string linkLibs;
- if(this->Target->GetType() != cmTarget::STATIC_LIBRARY)
+ if(this->GeneratorTarget->GetType() != cmState::STATIC_LIBRARY)
{
- std::string frameworkPath;
- std::string linkPath;
- this->LocalGenerator
- ->OutputLinkLibraries(linkLibs, frameworkPath, linkPath,
- *this->GeneratorTarget, relink);
- linkLibs = frameworkPath + linkPath + linkLibs;
+ this->CreateLinkLibs(linkLibs, relink, useResponseFileForLibs, depends,
+ useWatcomQuote);
}
// Construct object file lists that may be needed to expand the
// rule.
std::string buildObjs;
- this->CreateObjectLists(useLinkScript, useArchiveRules, useResponseFile,
- buildObjs, depends);
+ this->CreateObjectLists(useLinkScript, useArchiveRules,
+ useResponseFileForObjects, buildObjs, depends,
+ useWatcomQuote);
+
+ // maybe create .def file from list of objects
+ if (this->GeneratorTarget->GetType() == cmState::SHARED_LIBRARY &&
+ this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+ {
+ if(this->GeneratorTarget->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+ {
+ std::string name_of_def_file =
+ this->GeneratorTarget->GetSupportDirectory();
+ name_of_def_file += std::string("/") +
+ this->GeneratorTarget->GetName();
+ name_of_def_file += ".def";
+ std::string cmd = cmSystemTools::GetCMakeCommand();
+ cmd = this->Convert(cmd, cmLocalGenerator::NONE,
+ cmLocalGenerator::SHELL);
+ cmd += " -E __create_def ";
+ cmd += this->Convert(name_of_def_file,
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::SHELL);
+ cmd += " ";
+ std::string objlist_file = name_of_def_file;
+ objlist_file += ".objs";
+ cmd += this->Convert(objlist_file,
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::SHELL);
+ real_link_commands.push_back(cmd);
+ // create a list of obj files for the -E __create_def to read
+ cmGeneratedFileStream fout(objlist_file.c_str());
+ for(std::vector<std::string>::const_iterator i = this->Objects.begin();
+ i != this->Objects.end(); ++i)
+ {
+ if(cmHasLiteralSuffix(*i, ".obj"))
+ {
+ fout << *i << "\n";
+ }
+ }
+ for(std::vector<std::string>::const_iterator i =
+ this->ExternalObjects.begin();
+ i != this->ExternalObjects.end(); ++i)
+ {
+ fout << *i << "\n";
+ }
+ // now add the def file link flag
+ linkFlags += " ";
+ linkFlags +=
+ this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
+ linkFlags += this->Convert(name_of_def_file,
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::SHELL);
+ linkFlags += " ";
+ }
+ }
+
+ std::string manifests = this->GetManifests();
cmLocalGenerator::RuleVariables vars;
vars.TargetPDB = targetOutPathPDB.c_str();
@@ -560,11 +628,11 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
std::string targetVersionMajor;
std::string targetVersionMinor;
{
- cmOStringStream majorStream;
- cmOStringStream minorStream;
+ std::ostringstream majorStream;
+ std::ostringstream minorStream;
int major;
int minor;
- this->Target->GetTargetVersion(major, minor);
+ this->GeneratorTarget->GetTargetVersion(major, minor);
majorStream << major;
minorStream << minor;
targetVersionMajor = majorStream.str();
@@ -574,31 +642,38 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
vars.TargetVersionMinor = targetVersionMinor.c_str();
vars.RuleLauncher = "RULE_LAUNCH_LINK";
- vars.CMTarget = this->Target;
- vars.Language = linkLanguage;
+ vars.CMTarget = this->GeneratorTarget;
+ vars.Language = linkLanguage.c_str();
vars.Objects = buildObjs.c_str();
- std::string objectDir = this->Target->GetSupportDirectory();
- objectDir = this->Convert(objectDir.c_str(),
+ std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
+ objectDir = this->Convert(objectDir,
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::SHELL);
vars.ObjectDir = objectDir.c_str();
- vars.Target = targetOutPathReal.c_str();
+ cmLocalGenerator::OutputFormat output = (useWatcomQuote) ?
+ cmLocalGenerator::WATCOMQUOTE : cmLocalGenerator::SHELL;
+ std::string target = this->Convert(targetFullPathReal,
+ cmLocalGenerator::START_OUTPUT,
+ output);
+ vars.Target = target.c_str();
vars.LinkLibraries = linkLibs.c_str();
vars.ObjectsQuoted = buildObjs.c_str();
- if (this->Target->HasSOName(this->ConfigName))
+ if (this->GeneratorTarget->HasSOName(this->ConfigName))
{
vars.SONameFlag = this->Makefile->GetSONameFlag(linkLanguage);
vars.TargetSOName= targetNameSO.c_str();
}
vars.LinkFlags = linkFlags.c_str();
+ vars.Manifests = manifests.c_str();
+
// Compute the directory portion of the install_name setting.
std::string install_name_dir;
- if(this->Target->GetType() == cmTarget::SHARED_LIBRARY)
+ if(this->GeneratorTarget->GetType() == cmState::SHARED_LIBRARY)
{
// Get the install_name directory for the build tree.
install_name_dir =
- this->Target->GetInstallNameDirForBuildTree(this->ConfigName);
+ this->GeneratorTarget->GetInstallNameDirForBuildTree(this->ConfigName);
// Set the rule variable replacement value.
if(install_name_dir.empty())
@@ -609,9 +684,9 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
{
// Convert to a path for the native build tool.
install_name_dir =
- this->LocalGenerator->Convert(install_name_dir.c_str(),
+ this->LocalGenerator->Convert(install_name_dir,
cmLocalGenerator::NONE,
- cmLocalGenerator::SHELL, false);
+ cmLocalGenerator::SHELL);
vars.TargetInstallNameDir = install_name_dir.c_str();
}
}
@@ -711,14 +786,15 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
}
this->LocalGenerator->CreateCDCommand
(commands1,
- this->Makefile->GetStartOutputDirectory(),
+ this->Makefile->GetCurrentBinaryDirectory(),
cmLocalGenerator::HOME_OUTPUT);
commands.insert(commands.end(), commands1.begin(), commands1.end());
commands1.clear();
// Add a rule to create necessary symlinks for the library.
// Frameworks are handled by cmOSXBundleGenerator.
- if(targetOutPath != targetOutPathReal && !this->Target->IsFrameworkOnApple())
+ if(targetOutPath != targetOutPathReal
+ && !this->GeneratorTarget->IsFrameworkOnApple())
{
std::string symlink = "$(CMAKE_COMMAND) -E cmake_symlink_library ";
symlink += targetOutPathReal;
@@ -728,7 +804,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
symlink += targetOutPath;
commands1.push_back(symlink);
this->LocalGenerator->CreateCDCommand(commands1,
- this->Makefile->GetStartOutputDirectory(),
+ this->Makefile->GetCurrentBinaryDirectory(),
cmLocalGenerator::HOME_OUTPUT);
commands.insert(commands.end(), commands1.begin(), commands1.end());
commands1.clear();
@@ -737,32 +813,29 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
if(!relink)
{
this->LocalGenerator->
- AppendCustomCommands(commands, this->Target->GetPostBuildCommands(),
- this->Target);
+ AppendCustomCommands(commands,
+ this->GeneratorTarget->GetPostBuildCommands(),
+ this->GeneratorTarget);
}
- // Write the build rule.
- this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
- targetFullPathReal.c_str(),
- depends, commands, false);
-
- // Some targets have more than one output file. Create rules to
- // drive the build if any extra outputs are missing.
- std::vector<std::string> extraOutputs;
+ // Compute the list of outputs.
+ std::vector<std::string> outputs(1, targetFullPathReal);
if(targetNameSO != targetNameReal)
{
- this->GenerateExtraOutput(targetFullPathSO.c_str(),
- targetFullPathReal.c_str());
+ outputs.push_back(targetFullPathSO);
}
if(targetName != targetNameSO &&
targetName != targetNameReal)
{
- this->GenerateExtraOutput(targetFullPath.c_str(),
- targetFullPathReal.c_str());
+ outputs.push_back(targetFullPath);
}
+ // Write the build rule.
+ this->WriteMakeRule(*this->BuildFileStream, 0, outputs,
+ depends, commands, false);
+
// Write the main driver rule to build everything in this target.
- this->WriteTargetDriverRule(targetFullPath.c_str(), relink);
+ this->WriteTargetDriverRule(targetFullPath, relink);
// Clean all the possible library names and symlinks.
this->CleanFiles.insert(this->CleanFiles.end(),
@@ -772,7 +845,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
//----------------------------------------------------------------------------
void
cmMakefileLibraryTargetGenerator
-::AppendOSXVerFlag(std::string& flags, const char* lang,
+::AppendOSXVerFlag(std::string& flags, const std::string& lang,
const char* name, bool so)
{
// Lookup the flag to specify the version.
@@ -781,7 +854,7 @@ cmMakefileLibraryTargetGenerator
fvar += "_OSX_";
fvar += name;
fvar += "_VERSION_FLAG";
- const char* flag = this->Makefile->GetDefinition(fvar.c_str());
+ const char* flag = this->Makefile->GetDefinition(fvar);
// Skip if no such flag.
if(!flag)
@@ -793,12 +866,12 @@ cmMakefileLibraryTargetGenerator
int major;
int minor;
int patch;
- this->Target->GetTargetVersion(so, major, minor, patch);
+ this->GeneratorTarget->GetTargetVersion(so, major, minor, patch);
if(major > 0 || minor > 0 || patch > 0)
{
// Append the flag since a non-zero version is specified.
- cmOStringStream vflag;
+ std::ostringstream vflag;
vflag << flag << major << "." << minor << "." << patch;
- this->LocalGenerator->AppendFlags(flags, vflag.str().c_str());
+ this->LocalGenerator->AppendFlags(flags, vflag.str());
}
}
diff --git a/Source/cmMakefileLibraryTargetGenerator.h b/Source/cmMakefileLibraryTargetGenerator.h
index 07f828b7d..68980c3ff 100644
--- a/Source/cmMakefileLibraryTargetGenerator.h
+++ b/Source/cmMakefileLibraryTargetGenerator.h
@@ -18,7 +18,7 @@ class cmMakefileLibraryTargetGenerator:
public cmMakefileTargetGenerator
{
public:
- cmMakefileLibraryTargetGenerator(cmTarget* target);
+ cmMakefileLibraryTargetGenerator(cmGeneratorTarget* target);
virtual ~cmMakefileLibraryTargetGenerator();
/* the main entry point for this class. Writes the Makefiles associated
@@ -30,7 +30,8 @@ protected:
void WriteStaticLibraryRules();
void WriteSharedLibraryRules(bool relink);
void WriteModuleLibraryRules(bool relink);
- void WriteLibraryRules(const char *linkRule, const char *extraFlags,
+ void WriteLibraryRules(const std::string& linkRule,
+ const std::string& extraFlags,
bool relink);
// MacOSX Framework support methods
void WriteFrameworkRules(bool relink);
@@ -38,7 +39,7 @@ protected:
// Store the computd framework version for OS X Frameworks.
std::string FrameworkVersion;
- void AppendOSXVerFlag(std::string& flags, const char* lang,
+ void AppendOSXVerFlag(std::string& flags, const std::string& lang,
const char* name, bool so);
};
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 5e6c54822..eedc6abdb 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -18,37 +18,37 @@
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
-#include "cmTarget.h"
#include "cmake.h"
+#include "cmState.h"
#include "cmComputeLinkInformation.h"
+#include "cmCustomCommandGenerator.h"
+#include "cmGeneratorExpression.h"
+#include "cmAlgorithms.h"
#include "cmMakefileExecutableTargetGenerator.h"
#include "cmMakefileLibraryTargetGenerator.h"
#include "cmMakefileUtilityTargetGenerator.h"
+#include <ctype.h>
-cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmTarget* target)
- : OSXBundleGenerator(0)
+cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmGeneratorTarget* target)
+ : cmCommonTargetGenerator(cmOutputConverter::START_OUTPUT, target)
+ , OSXBundleGenerator(0)
, MacOSXContentGenerator(0)
{
this->BuildFileStream = 0;
this->InfoFileStream = 0;
this->FlagFileStream = 0;
this->CustomCommandDriver = OnBuild;
- this->FortranModuleDirectoryComputed = false;
- this->Target = target;
- this->Makefile = this->Target->GetMakefile();
this->LocalGenerator =
- static_cast<cmLocalUnixMakefileGenerator3*>(
- this->Makefile->GetLocalGenerator());
- this->ConfigName = this->LocalGenerator->ConfigurationName.c_str();
+ static_cast<cmLocalUnixMakefileGenerator3*>(target->GetLocalGenerator());
this->GlobalGenerator =
static_cast<cmGlobalUnixMakefileGenerator3*>(
this->LocalGenerator->GetGlobalGenerator());
- this->GeneratorTarget = this->GlobalGenerator->GetGeneratorTarget(target);
cmake* cm = this->GlobalGenerator->GetCMakeInstance();
this->NoRuleMessages = false;
- if(const char* ruleStatus = cm->GetProperty("RULE_MESSAGES"))
+ if(const char* ruleStatus = cm->GetState()
+ ->GetGlobalProperty("RULE_MESSAGES"))
{
this->NoRuleMessages = cmSystemTools::IsOff(ruleStatus);
}
@@ -61,22 +61,22 @@ cmMakefileTargetGenerator::~cmMakefileTargetGenerator()
}
cmMakefileTargetGenerator *
-cmMakefileTargetGenerator::New(cmTarget *tgt)
+cmMakefileTargetGenerator::New(cmGeneratorTarget *tgt)
{
cmMakefileTargetGenerator *result = 0;
switch (tgt->GetType())
{
- case cmTarget::EXECUTABLE:
+ case cmState::EXECUTABLE:
result = new cmMakefileExecutableTargetGenerator(tgt);
break;
- case cmTarget::STATIC_LIBRARY:
- case cmTarget::SHARED_LIBRARY:
- case cmTarget::MODULE_LIBRARY:
- case cmTarget::OBJECT_LIBRARY:
+ case cmState::STATIC_LIBRARY:
+ case cmState::SHARED_LIBRARY:
+ case cmState::MODULE_LIBRARY:
+ case cmState::OBJECT_LIBRARY:
result = new cmMakefileLibraryTargetGenerator(tgt);
break;
- case cmTarget::UTILITY:
+ case cmState::UTILITY:
result = new cmMakefileUtilityTargetGenerator(tgt);
break;
default:
@@ -91,7 +91,7 @@ void cmMakefileTargetGenerator::CreateRuleFile()
{
// Create a directory for this target.
this->TargetBuildDirectory =
- this->LocalGenerator->GetTargetDirectory(*this->Target);
+ this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
this->TargetBuildDirectoryFull =
this->LocalGenerator->ConvertToFullPath(this->TargetBuildDirectory);
cmSystemTools::MakeDirectory(this->TargetBuildDirectoryFull.c_str());
@@ -119,19 +119,38 @@ void cmMakefileTargetGenerator::CreateRuleFile()
return;
}
this->LocalGenerator->WriteDisclaimer(*this->BuildFileStream);
+ if (this->GlobalGenerator->AllowDeleteOnError())
+ {
+ std::vector<std::string> no_depends;
+ std::vector<std::string> no_commands;
+ this->LocalGenerator->WriteMakeRule(
+ *this->BuildFileStream, "Delete rule output on recipe failure.",
+ ".DELETE_ON_ERROR", no_depends, no_commands, false);
+ }
this->LocalGenerator->WriteSpecialTargetsTop(*this->BuildFileStream);
}
//----------------------------------------------------------------------------
void cmMakefileTargetGenerator::WriteTargetBuildRules()
{
+ const std::string& config =
+ this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+
// write the custom commands for this target
// Look for files registered for cleaning in this directory.
if(const char* additional_clean_files =
this->Makefile->GetProperty
("ADDITIONAL_MAKE_CLEAN_FILES"))
{
- cmSystemTools::ExpandListArgument(additional_clean_files,
+ cmGeneratorExpression ge;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(additional_clean_files);
+
+ cmSystemTools::ExpandListArgument(cge->Evaluate(this->LocalGenerator,
+ config,
+ false,
+ this->GeneratorTarget,
+ 0, 0),
this->CleanFiles);
}
@@ -142,47 +161,55 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
// First generate the object rule files. Save a list of all object
// files for this target.
- for(std::vector<cmSourceFile*>::const_iterator
- si = this->GeneratorTarget->CustomCommands.begin();
- si != this->GeneratorTarget->CustomCommands.end(); ++si)
- {
- cmCustomCommand const* cc = (*si)->GetCustomCommand();
- this->GenerateCustomRuleFile(*cc);
+ std::vector<cmSourceFile const*> customCommands;
+ this->GeneratorTarget->GetCustomCommands(customCommands, config);
+ for(std::vector<cmSourceFile const*>::const_iterator
+ si = customCommands.begin();
+ si != customCommands.end(); ++si)
+ {
+ cmCustomCommandGenerator ccg(*(*si)->GetCustomCommand(),
+ this->ConfigName,
+ this->LocalGenerator);
+ this->GenerateCustomRuleFile(ccg);
if (clean)
{
- const std::vector<std::string>& outputs = cc->GetOutputs();
+ const std::vector<std::string>& outputs = ccg.GetOutputs();
for(std::vector<std::string>::const_iterator o = outputs.begin();
o != outputs.end(); ++o)
{
this->CleanFiles.push_back
- (this->Convert(o->c_str(),
+ (this->Convert(*o,
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::UNCHANGED));
}
}
}
+ std::vector<cmSourceFile const*> headerSources;
+ this->GeneratorTarget->GetHeaderSources(headerSources, config);
this->OSXBundleGenerator->GenerateMacOSXContentStatements(
- this->GeneratorTarget->HeaderSources,
+ headerSources,
this->MacOSXContentGenerator);
+ std::vector<cmSourceFile const*> extraSources;
+ this->GeneratorTarget->GetExtraSources(extraSources, config);
this->OSXBundleGenerator->GenerateMacOSXContentStatements(
- this->GeneratorTarget->ExtraSources,
+ extraSources,
this->MacOSXContentGenerator);
- for(std::vector<cmSourceFile*>::const_iterator
- si = this->GeneratorTarget->ExternalObjects.begin();
- si != this->GeneratorTarget->ExternalObjects.end(); ++si)
+ std::vector<cmSourceFile const*> externalObjects;
+ this->GeneratorTarget->GetExternalObjects(externalObjects, config);
+ for(std::vector<cmSourceFile const*>::const_iterator
+ si = externalObjects.begin();
+ si != externalObjects.end(); ++si)
{
this->ExternalObjects.push_back((*si)->GetFullPath());
}
- for(std::vector<cmSourceFile*>::const_iterator
- si = this->GeneratorTarget->ObjectSources.begin();
- si != this->GeneratorTarget->ObjectSources.end(); ++si)
+ std::vector<cmSourceFile const*> objectSources;
+ this->GeneratorTarget->GetObjectSources(objectSources, config);
+ for(std::vector<cmSourceFile const*>::const_iterator
+ si = objectSources.begin(); si != objectSources.end(); ++si)
{
// Generate this object file's rule file.
this->WriteObjectRuleFiles(**si);
}
-
- // Add object library contents as external objects.
- this->GeneratorTarget->UseObjectLibraries(this->ExternalObjects);
}
//----------------------------------------------------------------------------
@@ -196,10 +223,10 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
dependFileNameFull += "/depend.make";
*this->BuildFileStream
<< "# Include any dependencies generated for this target.\n"
- << this->LocalGenerator->IncludeDirective << " " << root
- << this->Convert(dependFileNameFull.c_str(),
+ << this->GlobalGenerator->IncludeDirective << " " << root
+ << this->Convert(dependFileNameFull,
cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE)
+ cmLocalGenerator::MAKERULE)
<< "\n\n";
if(!this->NoRuleMessages)
@@ -207,10 +234,10 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
// Include the progress variables for the target.
*this->BuildFileStream
<< "# Include the progress variables for this target.\n"
- << this->LocalGenerator->IncludeDirective << " " << root
- << this->Convert(this->ProgressFileNameFull.c_str(),
+ << this->GlobalGenerator->IncludeDirective << " " << root
+ << this->Convert(this->ProgressFileNameFull,
cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE)
+ cmLocalGenerator::MAKERULE)
<< "\n\n";
}
@@ -220,7 +247,8 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
// Write an empty dependency file.
cmGeneratedFileStream depFileStream(dependFileNameFull.c_str());
depFileStream
- << "# Empty dependencies file for " << this->Target->GetName() << ".\n"
+ << "# Empty dependencies file for "
+ << this->GeneratorTarget->GetName() << ".\n"
<< "# This may be replaced when dependencies are built." << std::endl;
}
@@ -240,110 +268,44 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
// Include the flags for the target.
*this->BuildFileStream
<< "# Include the compile flags for this target's objects.\n"
- << this->LocalGenerator->IncludeDirective << " " << root
- << this->Convert(this->FlagFileNameFull.c_str(),
+ << this->GlobalGenerator->IncludeDirective << " " << root
+ << this->Convert(this->FlagFileNameFull,
cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE)
+ cmLocalGenerator::MAKERULE)
<< "\n\n";
}
-//----------------------------------------------------------------------------
-std::string cmMakefileTargetGenerator::GetFlags(const std::string &l)
-{
- ByLanguageMap::iterator i = this->FlagsByLanguage.find(l);
- if (i == this->FlagsByLanguage.end())
- {
- std::string flags;
- const char *lang = l.c_str();
-
- // Add language feature flags.
- this->AddFeatureFlags(flags, lang);
-
- this->LocalGenerator->AddArchitectureFlags(flags, this->GeneratorTarget,
- lang, this->ConfigName);
-
- // Fortran-specific flags computed for this target.
- if(l == "Fortran")
- {
- this->AddFortranFlags(flags);
- }
-
- this->LocalGenerator->AddCMP0018Flags(flags, this->Target,
- lang, this->ConfigName);
-
- this->LocalGenerator->AddVisibilityPresetFlags(flags, this->Target,
- lang);
-
- // Add include directory flags.
- this->AddIncludeFlags(flags, lang);
-
- // Append old-style preprocessor definition flags.
- this->LocalGenerator->
- AppendFlags(flags, this->Makefile->GetDefineFlags());
-
- // Add include directory flags.
- this->LocalGenerator->
- AppendFlags(flags,this->GetFrameworkFlags().c_str());
-
- // Add target-specific flags.
- this->LocalGenerator->AddCompileOptions(flags, this->Target,
- lang, this->ConfigName);
-
- ByLanguageMap::value_type entry(l, flags);
- i = this->FlagsByLanguage.insert(entry).first;
- }
- return i->second;
-}
-
-std::string cmMakefileTargetGenerator::GetDefines(const std::string &l)
-{
- ByLanguageMap::iterator i = this->DefinesByLanguage.find(l);
- if (i == this->DefinesByLanguage.end())
- {
- std::set<std::string> defines;
- const char *lang = l.c_str();
- // Add the export symbol definition for shared library objects.
- if(const char* exportMacro = this->Target->GetExportMacro())
- {
- this->LocalGenerator->AppendDefines(defines, exportMacro);
- }
-
- // Add preprocessor definitions for this target and configuration.
- this->LocalGenerator->AddCompileDefinitions(defines, this->Target,
- this->LocalGenerator->ConfigurationName.c_str());
-
- std::string definesString;
- this->LocalGenerator->JoinDefines(defines, definesString, lang);
-
- ByLanguageMap::value_type entry(l, definesString);
- i = this->DefinesByLanguage.insert(entry).first;
- }
- return i->second;
-}
-
void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
{
// write language flags for target
- std::set<cmStdString> languages;
- this->Target->GetLanguages(languages);
- // put the compiler in the rules.make file so that if it changes
+ std::set<std::string> languages;
+ this->GeneratorTarget->GetLanguages(languages,
+ this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
+ // put the compiler in the rules.make file so that if it changes
// things rebuild
- for(std::set<cmStdString>::const_iterator l = languages.begin();
+ for(std::set<std::string>::const_iterator l = languages.begin();
l != languages.end(); ++l)
{
- cmStdString compiler = "CMAKE_";
+ std::string compiler = "CMAKE_";
compiler += *l;
compiler += "_COMPILER";
- *this->FlagFileStream << "# compile " << l->c_str() << " with " <<
- this->Makefile->GetSafeDefinition(compiler.c_str()) << "\n";
+ *this->FlagFileStream << "# compile " << *l << " with " <<
+ this->Makefile->GetSafeDefinition(compiler) << "\n";
}
- for(std::set<cmStdString>::const_iterator l = languages.begin();
+ for(std::set<std::string>::const_iterator l = languages.begin();
l != languages.end(); ++l)
{
- *this->FlagFileStream << *l << "_FLAGS = " << this->GetFlags(*l) << "\n\n";
- *this->FlagFileStream << *l << "_DEFINES = " << this->GetDefines(*l) <<
- "\n\n";
+ std::string flags = this->GetFlags(*l);
+ std::string defines = this->GetDefines(*l);
+ std::string includes = this->GetIncludes(*l);
+ // Escape comment characters so they do not terminate assignment.
+ cmSystemTools::ReplaceString(flags, "#", "\\#");
+ cmSystemTools::ReplaceString(defines, "#", "\\#");
+ cmSystemTools::ReplaceString(includes, "#", "\\#");
+ *this->FlagFileStream << *l << "_FLAGS = " << flags << "\n\n";
+ *this->FlagFileStream << *l << "_DEFINES = " << defines << "\n\n";
+ *this->FlagFileStream << *l << "_INCLUDES = " << includes << "\n\n";
}
}
@@ -351,10 +313,10 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
//----------------------------------------------------------------------------
void
cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator()
- (cmSourceFile& source, const char* pkgloc)
+ (cmSourceFile const& source, const char* pkgloc)
{
// Skip OS X content when not building a Framework or Bundle.
- if(!this->Generator->GetTarget()->IsBundleOnApple())
+ if(!this->Generator->GetGeneratorTarget()->IsBundleOnApple())
{
return;
}
@@ -370,9 +332,9 @@ cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator()
output += "/";
output += cmSystemTools::GetFilenameName(input);
this->Generator->CleanFiles.push_back(
- this->Generator->Convert(output.c_str(),
+ this->Generator->Convert(output,
cmLocalGenerator::START_OUTPUT));
- output = this->Generator->Convert(output.c_str(),
+ output = this->Generator->Convert(output,
cmLocalGenerator::HOME_OUTPUT);
// Create a rule to copy the content into the bundle.
@@ -385,35 +347,39 @@ cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator()
commands, copyEcho.c_str(),
cmLocalUnixMakefileGenerator3::EchoBuild);
std::string copyCommand = "$(CMAKE_COMMAND) -E copy ";
- copyCommand += this->Generator->Convert(input.c_str(),
+ copyCommand += this->Generator->Convert(input,
cmLocalGenerator::NONE,
cmLocalGenerator::SHELL);
copyCommand += " ";
- copyCommand += this->Generator->Convert(output.c_str(),
+ copyCommand += this->Generator->Convert(output,
cmLocalGenerator::NONE,
cmLocalGenerator::SHELL);
commands.push_back(copyCommand);
this->Generator->LocalGenerator->WriteMakeRule(
*this->Generator->BuildFileStream, 0,
- output.c_str(),
+ output,
depends, commands, false);
this->Generator->ExtraFiles.insert(output);
}
//----------------------------------------------------------------------------
-void cmMakefileTargetGenerator::WriteObjectRuleFiles(cmSourceFile& source)
+void cmMakefileTargetGenerator
+::WriteObjectRuleFiles(cmSourceFile const& source)
{
// Identify the language of the source file.
- const char* lang = this->LocalGenerator->GetSourceFileLanguage(source);
- if(!lang)
+ const std::string& lang =
+ this->LocalGenerator->GetSourceFileLanguage(source);
+ if(lang.empty())
{
// don't know anything about this file so skip it
return;
}
// Get the full path name of the object file.
- std::string const& objectName = this->GeneratorTarget->Objects[&source];
- std::string obj = this->LocalGenerator->GetTargetDirectory(*this->Target);
+ std::string const& objectName = this->GeneratorTarget
+ ->GetObjectName(&source);
+ std::string obj =
+ this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
obj += "/";
obj += objectName;
@@ -424,11 +390,11 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(cmSourceFile& source)
}
else
{
- cmOStringStream err;
+ std::ostringstream err;
err << "Warning: Source file \""
<< source.GetFullPath()
<< "\" is listed multiple times for target \""
- << this->Target->GetName()
+ << this->GeneratorTarget->GetName()
<< "\".";
cmSystemTools::Message(err.str().c_str(), "Warning");
return;
@@ -436,7 +402,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(cmSourceFile& source)
// Create the directory containing the object file. This may be a
// subdirectory under the target's directory.
- std::string dir = cmSystemTools::GetFilenamePath(obj.c_str());
+ std::string dir = cmSystemTools::GetFilenamePath(obj);
cmSystemTools::MakeDirectory
(this->LocalGenerator->ConvertToFullPath(dir).c_str());
@@ -452,21 +418,20 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(cmSourceFile& source)
// 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;
- std::string depMakeFile;
// generate the build rule file
this->WriteObjectBuildFile(obj, lang, source, depends);
// The object file should be checked for dependency integrity.
- std::string objFullPath = this->Makefile->GetCurrentOutputDirectory();
+ std::string objFullPath = this->LocalGenerator->GetCurrentBinaryDirectory();
objFullPath += "/";
objFullPath += obj;
objFullPath =
- this->Convert(objFullPath.c_str(), cmLocalGenerator::FULL);
+ this->Convert(objFullPath, cmLocalGenerator::FULL);
std::string srcFullPath =
- this->Convert(source.GetFullPath().c_str(), cmLocalGenerator::FULL);
+ this->Convert(source.GetFullPath(), cmLocalGenerator::FULL);
this->LocalGenerator->
- AddImplicitDepends(*this->Target, lang,
+ AddImplicitDepends(this->GeneratorTarget, lang,
objFullPath.c_str(),
srcFullPath.c_str());
}
@@ -474,38 +439,9 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(cmSourceFile& source)
//----------------------------------------------------------------------------
void
cmMakefileTargetGenerator
-::AppendFortranFormatFlags(std::string& flags, cmSourceFile& source)
-{
- const char* srcfmt = source.GetProperty("Fortran_FORMAT");
- cmLocalGenerator::FortranFormat format =
- this->LocalGenerator->GetFortranFormat(srcfmt);
- if(format == cmLocalGenerator::FortranFormatNone)
- {
- const char* tgtfmt = this->Target->GetProperty("Fortran_FORMAT");
- format = this->LocalGenerator->GetFortranFormat(tgtfmt);
- }
- const char* var = 0;
- switch (format)
- {
- case cmLocalGenerator::FortranFormatFixed:
- var = "CMAKE_Fortran_FORMAT_FIXED_FLAG"; break;
- case cmLocalGenerator::FortranFormatFree:
- var = "CMAKE_Fortran_FORMAT_FREE_FLAG"; break;
- default: break;
- }
- if(var)
- {
- this->LocalGenerator->AppendFlags(
- flags, this->Makefile->GetDefinition(var));
- }
-}
-
-//----------------------------------------------------------------------------
-void
-cmMakefileTargetGenerator
::WriteObjectBuildFile(std::string &obj,
- const char *lang,
- cmSourceFile& source,
+ const std::string& lang,
+ cmSourceFile const& source,
std::vector<std::string>& depends)
{
this->LocalGenerator->AppendRuleDepend(depends,
@@ -527,13 +463,13 @@ cmMakefileTargetGenerator
std::string langFlags = "$(";
langFlags += lang;
langFlags += "_FLAGS)";
- this->LocalGenerator->AppendFlags(flags, langFlags.c_str());
+ this->LocalGenerator->AppendFlags(flags, langFlags);
std::string configUpper =
- cmSystemTools::UpperCase(this->LocalGenerator->ConfigurationName);
+ cmSystemTools::UpperCase(this->LocalGenerator->GetConfigName());
// Add Fortran format flags.
- if(strcmp(lang, "Fortran") == 0)
+ if(lang == "Fortran")
{
this->AppendFortranFormatFlags(flags, source);
}
@@ -565,7 +501,7 @@ cmMakefileTargetGenerator
std::string defPropName = "COMPILE_DEFINITIONS_";
defPropName += configUpper;
if(const char* config_compile_defs =
- source.GetProperty(defPropName.c_str()))
+ source.GetProperty(defPropName))
{
this->LocalGenerator->AppendDefines(defines, config_compile_defs);
*this->FlagFileStream
@@ -576,13 +512,7 @@ cmMakefileTargetGenerator
}
// Get the output paths for source and object files.
- std::string sourceFile = source.GetFullPath();
- if(this->LocalGenerator->UseRelativePaths)
- {
- sourceFile = this->Convert(sourceFile.c_str(),
- cmLocalGenerator::START_OUTPUT);
- }
- sourceFile = this->Convert(sourceFile.c_str(),
+ std::string sourceFile = this->Convert(source.GetFullPath(),
cmLocalGenerator::NONE,
cmLocalGenerator::SHELL);
@@ -591,58 +521,94 @@ cmMakefileTargetGenerator
std::vector<std::string> commands;
// add in a progress call if needed
- this->AppendProgress(commands);
+ this->NumberOfProgressActions++;
if(!this->NoRuleMessages)
{
+ cmLocalUnixMakefileGenerator3::EchoProgress progress;
+ this->MakeEchoProgress(progress);
std::string buildEcho = "Building ";
buildEcho += lang;
buildEcho += " object ";
buildEcho += relativeObj;
this->LocalGenerator->AppendEcho
- (commands, buildEcho.c_str(), cmLocalUnixMakefileGenerator3::EchoBuild);
+ (commands, buildEcho.c_str(), cmLocalUnixMakefileGenerator3::EchoBuild,
+ &progress);
}
std::string targetOutPathReal;
std::string targetOutPathPDB;
+ std::string targetOutPathCompilePDB;
{
std::string targetFullPathReal;
std::string targetFullPathPDB;
- if(this->Target->GetType() == cmTarget::EXECUTABLE ||
- this->Target->GetType() == cmTarget::STATIC_LIBRARY ||
- this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
- this->Target->GetType() == cmTarget::MODULE_LIBRARY)
+ std::string targetFullPathCompilePDB;
+ if(this->GeneratorTarget->GetType() == cmState::EXECUTABLE ||
+ this->GeneratorTarget->GetType() == cmState::STATIC_LIBRARY ||
+ this->GeneratorTarget->GetType() == cmState::SHARED_LIBRARY ||
+ this->GeneratorTarget->GetType() == cmState::MODULE_LIBRARY)
{
targetFullPathReal =
- this->Target->GetFullPath(this->ConfigName, false, true);
- targetFullPathPDB = this->Target->GetPDBDirectory(this->ConfigName);
+ this->GeneratorTarget->GetFullPath(this->ConfigName, false, true);
+ targetFullPathPDB =
+ this->GeneratorTarget->GetPDBDirectory(this->ConfigName);
targetFullPathPDB += "/";
- targetFullPathPDB += this->Target->GetPDBName(this->ConfigName);
+ targetFullPathPDB += this->GeneratorTarget->GetPDBName(this->ConfigName);
}
- targetOutPathReal = this->Convert(targetFullPathReal.c_str(),
+ if(this->GeneratorTarget->GetType() <= cmState::OBJECT_LIBRARY)
+ {
+ targetFullPathCompilePDB =
+ this->GeneratorTarget->GetCompilePDBPath(this->ConfigName);
+ if(targetFullPathCompilePDB.empty())
+ {
+ targetFullPathCompilePDB =
+ this->GeneratorTarget->GetSupportDirectory() + "/";
+ }
+ }
+
+ targetOutPathReal = this->Convert(targetFullPathReal,
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::SHELL);
targetOutPathPDB =
- this->Convert(targetFullPathPDB.c_str(),cmLocalGenerator::NONE,
+ this->Convert(targetFullPathPDB,cmLocalGenerator::NONE,
cmLocalGenerator::SHELL);
+ targetOutPathCompilePDB =
+ this->Convert(targetFullPathCompilePDB,
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::SHELL);
+
+ if (this->LocalGenerator->IsMinGWMake() &&
+ cmHasLiteralSuffix(targetOutPathCompilePDB, "\\"))
+ {
+ // mingw32-make incorrectly interprets 'a\ b c' as 'a b' and 'c'
+ // (but 'a\ b "c"' as 'a\', 'b', and 'c'!). Workaround this by
+ // avoiding a trailing backslash in the argument.
+ targetOutPathCompilePDB[targetOutPathCompilePDB.size()-1] = '/';
+ }
}
cmLocalGenerator::RuleVariables vars;
vars.RuleLauncher = "RULE_LAUNCH_COMPILE";
- vars.CMTarget = this->Target;
- vars.Language = lang;
+ vars.CMTarget = this->GeneratorTarget;
+ vars.Language = lang.c_str();
vars.Target = targetOutPathReal.c_str();
vars.TargetPDB = targetOutPathPDB.c_str();
+ vars.TargetCompilePDB = targetOutPathCompilePDB.c_str();
vars.Source = sourceFile.c_str();
std::string shellObj =
- this->Convert(obj.c_str(),
+ this->Convert(obj,
cmLocalGenerator::NONE,
- cmLocalGenerator::SHELL).c_str();
+ cmLocalGenerator::SHELL);
vars.Object = shellObj.c_str();
- std::string objectDir = this->Target->GetSupportDirectory();
- objectDir = this->Convert(objectDir.c_str(),
+ std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
+ objectDir = this->Convert(objectDir,
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::SHELL);
vars.ObjectDir = objectDir.c_str();
+ std::string objectFileDir = cmSystemTools::GetFilenamePath(obj);
+ objectFileDir = this->Convert(objectFileDir,
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::SHELL);
+ vars.ObjectFileDir = objectFileDir.c_str();
vars.Flags = flags.c_str();
std::string definesString = "$(";
@@ -653,8 +619,17 @@ cmMakefileTargetGenerator
vars.Defines = definesString.c_str();
- bool lang_is_c_or_cxx = ((strcmp(lang, "C") == 0) ||
- (strcmp(lang, "CXX") == 0));
+ std::string const includesString = "$(" + lang + "_INCLUDES)";
+ vars.Includes = includesString.c_str();
+
+ // At the moment, it is assumed that C, C++, and Fortran have both
+ // assembly and preprocessor capabilities. The same is true for the
+ // ability to export compile commands
+ bool lang_has_preprocessor = ((lang == "C") ||
+ (lang == "CXX") ||
+ (lang == "Fortran"));
+ bool const lang_has_assembly = lang_has_preprocessor;
+ bool const lang_can_export_cmds = lang_has_preprocessor;
// Construct the compile rules.
{
@@ -662,27 +637,64 @@ cmMakefileTargetGenerator
compileRuleVar += lang;
compileRuleVar += "_COMPILE_OBJECT";
std::string compileRule =
- this->Makefile->GetRequiredDefinition(compileRuleVar.c_str());
+ this->Makefile->GetRequiredDefinition(compileRuleVar);
std::vector<std::string> compileCommands;
cmSystemTools::ExpandListArgument(compileRule, compileCommands);
if (this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS") &&
- lang_is_c_or_cxx && compileCommands.size() == 1)
+ lang_can_export_cmds && compileCommands.size() == 1)
{
std::string compileCommand = compileCommands[0];
this->LocalGenerator->ExpandRuleVariables(compileCommand, vars);
std::string workingDirectory =
this->LocalGenerator->Convert(
- this->Makefile->GetStartOutputDirectory(), cmLocalGenerator::FULL);
+ this->LocalGenerator->GetCurrentBinaryDirectory(),
+ cmLocalGenerator::FULL);
compileCommand.replace(compileCommand.find(langFlags),
langFlags.size(), this->GetFlags(lang));
std::string langDefines = std::string("$(") + lang + "_DEFINES)";
compileCommand.replace(compileCommand.find(langDefines),
langDefines.size(), this->GetDefines(lang));
+ std::string langIncludes = std::string("$(") + lang + "_INCLUDES)";
+ compileCommand.replace(compileCommand.find(langIncludes),
+ langIncludes.size(), this->GetIncludes(lang));
this->GlobalGenerator->AddCXXCompileCommand(
source.GetFullPath(), workingDirectory, compileCommand);
}
+ // Maybe insert an include-what-you-use runner.
+ if (!compileCommands.empty() && (lang == "C" || lang == "CXX"))
+ {
+ std::string const iwyu_prop = lang + "_INCLUDE_WHAT_YOU_USE";
+ const char *iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
+ if (iwyu && *iwyu)
+ {
+ std::string run_iwyu = "$(CMAKE_COMMAND) -E __run_iwyu --iwyu=";
+ run_iwyu += this->LocalGenerator->EscapeForShell(iwyu);
+ run_iwyu += " -- ";
+ compileCommands.front().insert(0, run_iwyu);
+ }
+ }
+
+ // Maybe insert a compiler launcher like ccache or distcc
+ if (!compileCommands.empty() && (lang == "C" || lang == "CXX"))
+ {
+ std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER";
+ const char *clauncher = this->GeneratorTarget->GetProperty(clauncher_prop);
+ if (clauncher && *clauncher)
+ {
+ std::vector<std::string> launcher_cmd;
+ cmSystemTools::ExpandListArgument(clauncher, launcher_cmd, true);
+ for (std::vector<std::string>::iterator i = launcher_cmd.begin(),
+ e = launcher_cmd.end(); i != e; ++i)
+ {
+ *i = this->LocalGenerator->EscapeForShell(*i);
+ }
+ std::string const& run_launcher = cmJoin(launcher_cmd, " ") + " ";
+ compileCommands.front().insert(0, run_launcher);
+ }
+ }
+
// Expand placeholders in the commands.
for(std::vector<std::string>::iterator i = compileCommands.begin();
i != compileCommands.end(); ++i)
@@ -693,39 +705,30 @@ cmMakefileTargetGenerator
// Change the command working directory to the local build tree.
this->LocalGenerator->CreateCDCommand
(compileCommands,
- this->Makefile->GetStartOutputDirectory(),
+ this->LocalGenerator->GetCurrentBinaryDirectory(),
cmLocalGenerator::HOME_OUTPUT);
commands.insert(commands.end(),
compileCommands.begin(), compileCommands.end());
}
- // Write the rule.
- this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
- relativeObj.c_str(),
- depends, commands, false);
-
// Check for extra outputs created by the compilation.
+ std::vector<std::string> outputs(1, relativeObj);
if(const char* extra_outputs_str =
source.GetProperty("OBJECT_OUTPUTS"))
{
- std::vector<std::string> extra_outputs;
- cmSystemTools::ExpandListArgument(extra_outputs_str, extra_outputs);
- for(std::vector<std::string>::const_iterator eoi = extra_outputs.begin();
- eoi != extra_outputs.end(); ++eoi)
- {
- // Register this as an extra output for the object file rule.
- // This will cause the object file to be rebuilt if the extra
- // output is missing.
- this->GenerateExtraOutput(eoi->c_str(), relativeObj.c_str(), false);
-
- // Register this as an extra file to clean.
- this->CleanFiles.push_back(eoi->c_str());
- }
+ // Register these as extra files to clean.
+ cmSystemTools::ExpandListArgument(extra_outputs_str, outputs);
+ this->CleanFiles.insert(this->CleanFiles.end(),
+ outputs.begin() + 1, outputs.end());
}
- bool do_preprocess_rules = lang_is_c_or_cxx &&
+ // Write the rule.
+ this->WriteMakeRule(*this->BuildFileStream, 0, outputs,
+ depends, commands);
+
+ bool do_preprocess_rules = lang_has_preprocessor &&
this->LocalGenerator->GetCreatePreprocessedSourceRules();
- bool do_assembly_rules = lang_is_c_or_cxx &&
+ bool do_assembly_rules = lang_has_assembly &&
this->LocalGenerator->GetCreateAssemblySourceRules();
if(do_preprocess_rules || do_assembly_rules)
{
@@ -755,15 +758,15 @@ cmMakefileTargetGenerator
preprocessRuleVar += lang;
preprocessRuleVar += "_CREATE_PREPROCESSED_SOURCE";
if(const char* preprocessRule =
- this->Makefile->GetDefinition(preprocessRuleVar.c_str()))
+ this->Makefile->GetDefinition(preprocessRuleVar))
{
std::vector<std::string> preprocessCommands;
cmSystemTools::ExpandListArgument(preprocessRule, preprocessCommands);
std::string shellObjI =
- this->Convert(objI.c_str(),
+ this->Convert(objI,
cmLocalGenerator::NONE,
- cmLocalGenerator::SHELL).c_str();
+ cmLocalGenerator::SHELL);
vars.PreprocessedSource = shellObjI.c_str();
// Expand placeholders in the commands.
@@ -775,7 +778,7 @@ cmMakefileTargetGenerator
this->LocalGenerator->CreateCDCommand
(preprocessCommands,
- this->Makefile->GetStartOutputDirectory(),
+ this->LocalGenerator->GetCurrentBinaryDirectory(),
cmLocalGenerator::HOME_OUTPUT);
commands.insert(commands.end(),
preprocessCommands.begin(),
@@ -789,7 +792,7 @@ cmMakefileTargetGenerator
}
this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
- relativeObjI.c_str(),
+ relativeObjI,
force_depends, commands, false);
}
@@ -812,15 +815,15 @@ cmMakefileTargetGenerator
assemblyRuleVar += lang;
assemblyRuleVar += "_CREATE_ASSEMBLY_SOURCE";
if(const char* assemblyRule =
- this->Makefile->GetDefinition(assemblyRuleVar.c_str()))
+ this->Makefile->GetDefinition(assemblyRuleVar))
{
std::vector<std::string> assemblyCommands;
cmSystemTools::ExpandListArgument(assemblyRule, assemblyCommands);
std::string shellObjS =
- this->Convert(objS.c_str(),
+ this->Convert(objS,
cmLocalGenerator::NONE,
- cmLocalGenerator::SHELL).c_str();
+ cmLocalGenerator::SHELL);
vars.AssemblySource = shellObjS.c_str();
// Expand placeholders in the commands.
@@ -832,7 +835,7 @@ cmMakefileTargetGenerator
this->LocalGenerator->CreateCDCommand
(assemblyCommands,
- this->Makefile->GetStartOutputDirectory(),
+ this->LocalGenerator->GetCurrentBinaryDirectory(),
cmLocalGenerator::HOME_OUTPUT);
commands.insert(commands.end(),
assemblyCommands.begin(),
@@ -846,7 +849,7 @@ cmMakefileTargetGenerator
}
this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
- relativeObjS.c_str(),
+ relativeObjS,
force_depends, commands, false);
}
}
@@ -858,7 +861,7 @@ cmMakefileTargetGenerator
std::vector<std::string> p_depends;
// always provide an empty requires target
this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
- objectRequires.c_str(), p_depends,
+ objectRequires, p_depends,
no_commands, true);
// write a build rule to recursively build what this obj provides
@@ -868,23 +871,23 @@ cmMakefileTargetGenerator
temp += ".provides.build";
std::vector<std::string> r_commands;
std::string tgtMakefileName =
- this->LocalGenerator->GetRelativeTargetDirectory(*this->Target);
+ this->LocalGenerator->GetRelativeTargetDirectory(this->GeneratorTarget);
tgtMakefileName += "/build.make";
r_commands.push_back
(this->LocalGenerator->GetRecursiveMakeCall(tgtMakefileName.c_str(),
- temp.c_str()));
+ temp));
p_depends.clear();
p_depends.push_back(objectRequires);
this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
- objectProvides.c_str(), p_depends,
+ objectProvides, p_depends,
r_commands, true);
// write the provides.build rule dependency on the obj file
p_depends.clear();
p_depends.push_back(relativeObj);
this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
- temp.c_str(), p_depends, no_commands,
+ temp, p_depends, no_commands,
false);
}
@@ -896,7 +899,7 @@ void cmMakefileTargetGenerator::WriteTargetRequiresRules()
// Construct the name of the dependency generation target.
std::string depTarget =
- this->LocalGenerator->GetRelativeTargetDirectory(*this->Target);
+ this->LocalGenerator->GetRelativeTargetDirectory(this->GeneratorTarget);
depTarget += "/requires";
// This target drives dependency generation for all object files.
@@ -913,7 +916,7 @@ void cmMakefileTargetGenerator::WriteTargetRequiresRules()
// Write the rule.
this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
- depTarget.c_str(),
+ depTarget,
depends, no_commands, true);
}
@@ -925,29 +928,105 @@ void cmMakefileTargetGenerator::WriteTargetCleanRules()
// Construct the clean target name.
std::string cleanTarget =
- this->LocalGenerator->GetRelativeTargetDirectory(*this->Target);
+ this->LocalGenerator->GetRelativeTargetDirectory(this->GeneratorTarget);
cleanTarget += "/clean";
// Construct the clean command.
this->LocalGenerator->AppendCleanCommand(commands, this->CleanFiles,
- *this->Target);
+ this->GeneratorTarget);
this->LocalGenerator->CreateCDCommand
(commands,
- this->Makefile->GetStartOutputDirectory(),
+ this->LocalGenerator->GetCurrentBinaryDirectory(),
cmLocalGenerator::HOME_OUTPUT);
// Write the rule.
this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
- cleanTarget.c_str(),
+ cleanTarget,
depends, commands, true);
}
+//----------------------------------------------------------------------------
+bool cmMakefileTargetGenerator::WriteMakeRule(
+ std::ostream& os,
+ const char* comment,
+ const std::vector<std::string>& outputs,
+ const std::vector<std::string>& depends,
+ const std::vector<std::string>& commands,
+ bool in_help)
+{
+ bool symbolic = false;
+ if (outputs.size() == 0)
+ {
+ return symbolic;
+ }
+
+ // Check whether we need to bother checking for a symbolic output.
+ bool need_symbolic = this->GlobalGenerator->GetNeedSymbolicMark();
+
+ // Check whether the first output is marked as symbolic.
+ if(need_symbolic)
+ {
+ if(cmSourceFile* sf = this->Makefile->GetSource(outputs[0]))
+ {
+ symbolic = sf->GetPropertyAsBool("SYMBOLIC");
+ }
+ }
+
+ // We always attach the actual commands to the first output.
+ this->LocalGenerator->WriteMakeRule(os, comment, outputs[0], depends,
+ commands, symbolic, in_help);
+
+ // For single outputs, we are done.
+ if (outputs.size() == 1)
+ {
+ return symbolic;
+ }
+
+ // For multiple outputs, make the extra ones depend on the first one.
+ std::vector<std::string> const output_depends(1, outputs[0]);
+ for (std::vector<std::string>::const_iterator o = outputs.begin()+1;
+ o != outputs.end(); ++o)
+ {
+ // Touch the extra output so "make" knows that it was updated,
+ // but only if the output was acually created.
+ std::string const out = this->Convert(*o, cmLocalGenerator::HOME_OUTPUT,
+ cmLocalGenerator::SHELL);
+ std::vector<std::string> output_commands;
+
+ bool o_symbolic = false;
+ if(need_symbolic)
+ {
+ if(cmSourceFile* sf = this->Makefile->GetSource(*o))
+ {
+ o_symbolic = sf->GetPropertyAsBool("SYMBOLIC");
+ }
+ }
+ symbolic = symbolic && o_symbolic;
+
+ if (!o_symbolic)
+ {
+ output_commands.push_back("@$(CMAKE_COMMAND) -E touch_nocreate " + out);
+ }
+ this->LocalGenerator->WriteMakeRule(os, 0, *o, output_depends,
+ output_commands, o_symbolic, in_help);
+
+ if (!o_symbolic)
+ {
+ // At build time, remove the first output if this one does not exist
+ // so that "make" will rerun the real commands that create this one.
+ MultipleOutputPairsType::value_type p(*o, outputs[0]);
+ this->MultipleOutputPairs.insert(p);
+ }
+ }
+ return symbolic;
+}
//----------------------------------------------------------------------------
void cmMakefileTargetGenerator::WriteTargetDependRules()
{
// must write the targets depend info file
- std::string dir = this->LocalGenerator->GetTargetDirectory(*this->Target);
+ std::string dir =
+ this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
this->InfoFileNameFull = dir;
this->InfoFileNameFull += "/DependInfo.cmake";
this->InfoFileNameFull =
@@ -960,7 +1039,7 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
return;
}
this->LocalGenerator->
- WriteDependLanguageInfo(*this->InfoFileStream,*this->Target);
+ WriteDependLanguageInfo(*this->InfoFileStream, this->GeneratorTarget);
// Store multiple output pairs in the depend info file.
if(!this->MultipleOutputPairs.empty())
@@ -968,14 +1047,14 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
*this->InfoFileStream
<< "\n"
<< "# Pairs of files generated by the same build rule.\n"
- << "SET(CMAKE_MULTIPLE_OUTPUT_PAIRS\n";
+ << "set(CMAKE_MULTIPLE_OUTPUT_PAIRS\n";
for(MultipleOutputPairsType::const_iterator pi =
this->MultipleOutputPairs.begin();
pi != this->MultipleOutputPairs.end(); ++pi)
{
*this->InfoFileStream
- << " " << this->LocalGenerator->EscapeForCMake(pi->first.c_str())
- << " " << this->LocalGenerator->EscapeForCMake(pi->second.c_str())
+ << " " << cmOutputConverter::EscapeForCMake(pi->first)
+ << " " << cmOutputConverter::EscapeForCMake(pi->second)
<< "\n";
}
*this->InfoFileStream << " )\n\n";
@@ -986,73 +1065,22 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
*this->InfoFileStream
<< "\n"
<< "# Targets to which this target links.\n"
- << "SET(CMAKE_TARGET_LINKED_INFO_FILES\n";
- std::set<cmTarget const*> emitted;
- const char* cfg = this->LocalGenerator->ConfigurationName.c_str();
- if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg))
- {
- cmComputeLinkInformation::ItemVector const& items = cli->GetItems();
- for(cmComputeLinkInformation::ItemVector::const_iterator
- i = items.begin(); i != items.end(); ++i)
- {
- cmTarget const* linkee = i->Target;
- if(linkee && !linkee->IsImported() && emitted.insert(linkee).second)
- {
- cmMakefile* mf = linkee->GetMakefile();
- cmLocalGenerator* lg = mf->GetLocalGenerator();
- std::string di = mf->GetStartOutputDirectory();
- di += "/";
- di += lg->GetTargetDirectory(*linkee);
- di += "/DependInfo.cmake";
- *this->InfoFileStream << " \"" << di << "\"\n";
- }
- }
+ << "set(CMAKE_TARGET_LINKED_INFO_FILES\n";
+ std::vector<std::string> dirs = this->GetLinkedTargetDirectories();
+ for (std::vector<std::string>::iterator i = dirs.begin();
+ i != dirs.end(); ++i)
+ {
+ *this->InfoFileStream << " \"" << *i << "/DependInfo.cmake\"\n";
}
*this->InfoFileStream
<< " )\n";
}
- // Check for a target-specific module output directory.
- if(const char* mdir = this->GetFortranModuleDirectory())
- {
- *this->InfoFileStream
- << "\n"
- << "# Fortran module output directory.\n"
- << "SET(CMAKE_Fortran_TARGET_MODULE_DIR \"" << mdir << "\")\n";
- }
-
- // Target-specific include directories:
*this->InfoFileStream
<< "\n"
- << "# The include file search paths:\n";
- *this->InfoFileStream
- << "SET(CMAKE_C_TARGET_INCLUDE_PATH\n";
- std::vector<std::string> includes;
-
- const char *config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE");
- this->LocalGenerator->GetIncludeDirectories(includes,
- this->GeneratorTarget,
- "C", config);
- for(std::vector<std::string>::iterator i = includes.begin();
- i != includes.end(); ++i)
- {
- *this->InfoFileStream
- << " \""
- << this->LocalGenerator->Convert(i->c_str(),
- cmLocalGenerator::HOME_OUTPUT)
- << "\"\n";
- }
- *this->InfoFileStream
- << " )\n";
- *this->InfoFileStream
- << "SET(CMAKE_CXX_TARGET_INCLUDE_PATH "
- << "${CMAKE_C_TARGET_INCLUDE_PATH})\n";
- *this->InfoFileStream
- << "SET(CMAKE_Fortran_TARGET_INCLUDE_PATH "
- << "${CMAKE_C_TARGET_INCLUDE_PATH})\n";
- *this->InfoFileStream
- << "SET(CMAKE_ASM_TARGET_INCLUDE_PATH "
- << "${CMAKE_C_TARGET_INCLUDE_PATH})\n";
+ << "# Fortran module output directory.\n"
+ << "set(CMAKE_Fortran_TARGET_MODULE_DIR \""
+ << this->GetFortranModuleDirectory() << "\")\n";
// and now write the rule to use it
std::vector<std::string> depends;
@@ -1060,12 +1088,12 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
// Construct the name of the dependency generation target.
std::string depTarget =
- this->LocalGenerator->GetRelativeTargetDirectory(*this->Target);
+ this->LocalGenerator->GetRelativeTargetDirectory(this->GeneratorTarget);
depTarget += "/depend";
// Add a command to call CMake to scan dependencies. CMake will
// touch the corresponding depends file after scanning dependencies.
- cmOStringStream depCmd;
+ std::ostringstream depCmd;
// TODO: Account for source file properties and directory-level
// definitions when scanning for dependencies.
#if !defined(_WIN32) || defined(__CYGWIN__)
@@ -1075,7 +1103,7 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
// translation table for the dependency scanning process.
depCmd << "cd "
<< (this->LocalGenerator->Convert(
- this->Makefile->GetHomeOutputDirectory(),
+ this->LocalGenerator->GetBinaryDirectory(),
cmLocalGenerator::FULL, cmLocalGenerator::SHELL))
<< " && ";
#endif
@@ -1090,19 +1118,19 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
// the state of our local generator sufficiently for its needs.
depCmd << "$(CMAKE_COMMAND) -E cmake_depends \""
<< this->GlobalGenerator->GetName() << "\" "
- << this->Convert(this->Makefile->GetHomeDirectory(),
+ << this->Convert(this->LocalGenerator->GetSourceDirectory(),
cmLocalGenerator::FULL, cmLocalGenerator::SHELL)
<< " "
- << this->Convert(this->Makefile->GetStartDirectory(),
+ << this->Convert(this->LocalGenerator->GetCurrentSourceDirectory(),
cmLocalGenerator::FULL, cmLocalGenerator::SHELL)
<< " "
- << this->Convert(this->Makefile->GetHomeOutputDirectory(),
+ << this->Convert(this->LocalGenerator->GetBinaryDirectory(),
cmLocalGenerator::FULL, cmLocalGenerator::SHELL)
<< " "
- << this->Convert(this->Makefile->GetStartOutputDirectory(),
+ << this->Convert(this->LocalGenerator->GetCurrentBinaryDirectory(),
cmLocalGenerator::FULL, cmLocalGenerator::SHELL)
<< " "
- << this->Convert(this->InfoFileNameFull.c_str(),
+ << this->Convert(this->InfoFileNameFull,
cmLocalGenerator::FULL, cmLocalGenerator::SHELL);
if(this->LocalGenerator->GetColorMakefile())
{
@@ -1118,7 +1146,7 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
// Write the rule.
this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
- depTarget.c_str(),
+ depTarget,
depends, commands, true);
}
@@ -1128,26 +1156,25 @@ cmMakefileTargetGenerator
::DriveCustomCommands(std::vector<std::string>& depends)
{
// Depend on all custom command outputs.
- const std::vector<cmSourceFile*>& sources =
- this->Target->GetSourceFiles();
+ std::vector<cmSourceFile*> sources;
+ this->GeneratorTarget->GetSourceFiles(sources,
+ this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
source != sources.end(); ++source)
{
if(cmCustomCommand* cc = (*source)->GetCustomCommand())
{
- const std::vector<std::string>& outputs = cc->GetOutputs();
- for(std::vector<std::string>::const_iterator o = outputs.begin();
- o != outputs.end(); ++o)
- {
- depends.push_back(*o);
- }
+ cmCustomCommandGenerator ccg(*cc, this->ConfigName,
+ this->LocalGenerator);
+ const std::vector<std::string>& outputs = ccg.GetOutputs();
+ depends.insert(depends.end(), outputs.begin(), outputs.end());
}
}
}
//----------------------------------------------------------------------------
void cmMakefileTargetGenerator
-::WriteObjectDependRules(cmSourceFile& source,
+::WriteObjectDependRules(cmSourceFile const& source,
std::vector<std::string>& depends)
{
// Create the list of dependencies known at cmake time. These are
@@ -1155,97 +1182,65 @@ void cmMakefileTargetGenerator
depends.push_back(source.GetFullPath());
if(const char* objectDeps = source.GetProperty("OBJECT_DEPENDS"))
{
- std::vector<std::string> deps;
- cmSystemTools::ExpandListArgument(objectDeps, deps);
- for(std::vector<std::string>::iterator i = deps.begin();
- i != deps.end(); ++i)
- {
- depends.push_back(i->c_str());
- }
+ cmSystemTools::ExpandListArgument(objectDeps, depends);
}
}
//----------------------------------------------------------------------------
void cmMakefileTargetGenerator
-::GenerateCustomRuleFile(const cmCustomCommand& cc)
+::GenerateCustomRuleFile(cmCustomCommandGenerator const& ccg)
{
// Collect the commands.
std::vector<std::string> commands;
- std::string comment = this->LocalGenerator->ConstructComment(cc);
+ std::string comment = this->LocalGenerator->ConstructComment(ccg);
if(!comment.empty())
{
// add in a progress call if needed
- this->AppendProgress(commands);
+ this->NumberOfProgressActions++;
if(!this->NoRuleMessages)
{
+ cmLocalUnixMakefileGenerator3::EchoProgress progress;
+ this->MakeEchoProgress(progress);
this->LocalGenerator
->AppendEcho(commands, comment.c_str(),
- cmLocalUnixMakefileGenerator3::EchoGenerate);
+ cmLocalUnixMakefileGenerator3::EchoGenerate,
+ &progress);
}
}
// Now append the actual user-specified commands.
- cmOStringStream content;
- this->LocalGenerator->AppendCustomCommand(commands, cc, this->Target, false,
+ std::ostringstream content;
+ this->LocalGenerator->AppendCustomCommand(commands, ccg,
+ this->GeneratorTarget, false,
cmLocalGenerator::HOME_OUTPUT,
&content);
// Collect the dependencies.
std::vector<std::string> depends;
- this->LocalGenerator->AppendCustomDepend(depends, cc);
-
- // Check whether we need to bother checking for a symbolic output.
- bool need_symbolic = this->GlobalGenerator->GetNeedSymbolicMark();
+ this->LocalGenerator->AppendCustomDepend(depends, ccg);
// Write the rule.
- const std::vector<std::string>& outputs = cc.GetOutputs();
- std::vector<std::string>::const_iterator o = outputs.begin();
- {
- bool symbolic = false;
- if(need_symbolic)
- {
- if(cmSourceFile* sf = this->Makefile->GetSource(o->c_str()))
- {
- symbolic = sf->GetPropertyAsBool("SYMBOLIC");
- }
- }
- this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
- o->c_str(), depends, commands,
- symbolic);
+ const std::vector<std::string>& outputs = ccg.GetOutputs();
+ bool symbolic = this->WriteMakeRule(*this->BuildFileStream, 0,
+ outputs, depends, commands);
// If the rule has changed make sure the output is rebuilt.
if(!symbolic)
{
- this->GlobalGenerator->AddRuleHash(cc.GetOutputs(), content.str());
- }
- }
-
- // Write rules to drive building any outputs beyond the first.
- const char* in = o->c_str();
- for(++o; o != outputs.end(); ++o)
- {
- bool symbolic = false;
- if(need_symbolic)
- {
- if(cmSourceFile* sf = this->Makefile->GetSource(o->c_str()))
- {
- symbolic = sf->GetPropertyAsBool("SYMBOLIC");
- }
- }
- this->GenerateExtraOutput(o->c_str(), in, symbolic);
+ this->GlobalGenerator->AddRuleHash(ccg.GetOutputs(), content.str());
}
// Setup implicit dependency scanning.
for(cmCustomCommand::ImplicitDependsList::const_iterator
- idi = cc.GetImplicitDepends().begin();
- idi != cc.GetImplicitDepends().end(); ++idi)
+ idi = ccg.GetCC().GetImplicitDepends().begin();
+ idi != ccg.GetCC().GetImplicitDepends().end(); ++idi)
{
std::string objFullPath =
- this->Convert(outputs[0].c_str(), cmLocalGenerator::FULL);
+ this->Convert(outputs[0], cmLocalGenerator::FULL);
std::string srcFullPath =
- this->Convert(idi->second.c_str(), cmLocalGenerator::FULL);
+ this->Convert(idi->second, cmLocalGenerator::FULL);
this->LocalGenerator->
- AddImplicitDepends(*this->Target, idi->first.c_str(),
+ AddImplicitDepends(this->GeneratorTarget, idi->first,
objFullPath.c_str(),
srcFullPath.c_str());
}
@@ -1254,66 +1249,31 @@ void cmMakefileTargetGenerator
//----------------------------------------------------------------------------
void
cmMakefileTargetGenerator
-::GenerateExtraOutput(const char* out, const char* in, bool symbolic)
+::MakeEchoProgress(cmLocalUnixMakefileGenerator3::EchoProgress& progress) const
{
- // Add a rule to build the primary output if the extra output needs
- // to be created.
- std::vector<std::string> commands;
- std::vector<std::string> depends;
- std::string emptyCommand = this->GlobalGenerator->GetEmptyRuleHackCommand();
- if(!emptyCommand.empty())
- {
- commands.push_back(emptyCommand);
- }
- depends.push_back(in);
- this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
- out, depends, commands,
- symbolic);
-
- // Register the extra output as paired with the first output so that
- // the check-build-system step will remove the primary output if any
- // extra outputs are missing. This forces the rule to regenerate
- // all outputs.
- this->AddMultipleOutputPair(out, in);
-}
-
-//----------------------------------------------------------------------------
-void
-cmMakefileTargetGenerator::AppendProgress(std::vector<std::string>& commands)
-{
- this->NumberOfProgressActions++;
- if(this->NoRuleMessages)
- {
- return;
- }
- 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);
- progCmd << " $(CMAKE_PROGRESS_" << this->NumberOfProgressActions << ")";
- commands.push_back(progCmd.str());
+ progress.Dir = this->LocalGenerator->GetBinaryDirectory();
+ progress.Dir += cmake::GetCMakeFilesDirectory();
+ std::ostringstream progressArg;
+ progressArg << "$(CMAKE_PROGRESS_" << this->NumberOfProgressActions << ")";
+ progress.Arg = progressArg.str();
}
//----------------------------------------------------------------------------
void
cmMakefileTargetGenerator
::WriteObjectsVariable(std::string& variableName,
- std::string& variableNameExternal)
+ std::string& variableNameExternal,
+ bool useWatcomQuote)
{
// Write a make variable assignment that lists all objects for the
// target.
variableName =
- this->LocalGenerator->CreateMakeVariable(this->Target->GetName(),
+ this->LocalGenerator->CreateMakeVariable(this->GeneratorTarget->GetName(),
"_OBJECTS");
*this->BuildFileStream
- << "# Object files for target " << this->Target->GetName() << "\n"
- << variableName.c_str() << " =";
+ << "# Object files for target " << this->GeneratorTarget->GetName() << "\n"
+ << variableName << " =";
std::string object;
- const char* objName =
- this->Makefile->GetDefinition("CMAKE_NO_QUOTED_OBJECTS");
const char* lineContinue =
this->Makefile->GetDefinition("CMAKE_MAKE_LINE_CONTINUE");
if(!lineContinue)
@@ -1324,49 +1284,33 @@ cmMakefileTargetGenerator
i != this->Objects.end(); ++i)
{
*this->BuildFileStream << " " << lineContinue << "\n";
- if(objName)
- {
- *this->BuildFileStream <<
- this->Convert(i->c_str(), cmLocalGenerator::START_OUTPUT,
- cmLocalGenerator::MAKEFILE);
- }
- else
- {
- *this->BuildFileStream <<
- this->LocalGenerator->ConvertToQuotedOutputPath(i->c_str());
- }
+ *this->BuildFileStream <<
+ this->LocalGenerator->ConvertToQuotedOutputPath(i->c_str(),
+ useWatcomQuote);
}
*this->BuildFileStream << "\n";
// Write a make variable assignment that lists all external objects
// for the target.
variableNameExternal =
- this->LocalGenerator->CreateMakeVariable(this->Target->GetName(),
+ this->LocalGenerator->CreateMakeVariable(this->GeneratorTarget->GetName(),
"_EXTERNAL_OBJECTS");
*this->BuildFileStream
<< "\n"
<< "# External object files for target "
- << this->Target->GetName() << "\n"
- << variableNameExternal.c_str() << " =";
+ << this->GeneratorTarget->GetName() << "\n"
+ << variableNameExternal << " =";
for(std::vector<std::string>::const_iterator i =
this->ExternalObjects.begin();
i != this->ExternalObjects.end(); ++i)
{
- object = this->Convert(i->c_str(),cmLocalGenerator::START_OUTPUT);
+ object = this->Convert(*i,cmLocalGenerator::START_OUTPUT);
*this->BuildFileStream
<< " " << lineContinue << "\n"
<< this->Makefile->GetSafeDefinition("CMAKE_OBJECT_NAME");
- if(objName)
- {
- *this->BuildFileStream <<
- this->Convert(i->c_str(), cmLocalGenerator::START_OUTPUT,
- cmLocalGenerator::MAKEFILE);
- }
- else
- {
- *this->BuildFileStream <<
- this->LocalGenerator->ConvertToQuotedOutputPath(i->c_str());
- }
+ *this->BuildFileStream <<
+ this->LocalGenerator->ConvertToQuotedOutputPath(i->c_str(),
+ useWatcomQuote);
}
*this->BuildFileStream << "\n" << "\n";
}
@@ -1396,7 +1340,7 @@ public:
{
// Construct the name of the next object.
this->NextObject =
- this->LocalGenerator->Convert(obj.c_str(),
+ this->LocalGenerator->Convert(obj,
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::RESPONSE);
@@ -1453,24 +1397,22 @@ cmMakefileTargetGenerator
}
//----------------------------------------------------------------------------
-void cmMakefileTargetGenerator::WriteTargetDriverRule(const char* main_output,
- bool relink)
+void cmMakefileTargetGenerator::WriteTargetDriverRule(
+ const std::string& main_output,
+ bool relink)
{
// Compute the name of the driver target.
std::string dir =
- this->LocalGenerator->GetRelativeTargetDirectory(*this->Target);
+ this->LocalGenerator->GetRelativeTargetDirectory(this->GeneratorTarget);
std::string buildTargetRuleName = dir;
buildTargetRuleName += relink?"/preinstall":"/build";
- buildTargetRuleName = this->Convert(buildTargetRuleName.c_str(),
+ buildTargetRuleName = this->Convert(buildTargetRuleName,
cmLocalGenerator::HOME_OUTPUT,
cmLocalGenerator::UNCHANGED);
// Build the list of target outputs to drive.
std::vector<std::string> depends;
- if(main_output)
- {
- depends.push_back(main_output);
- }
+ depends.push_back(main_output);
const char* comment = 0;
if(relink)
@@ -1490,93 +1432,34 @@ void cmMakefileTargetGenerator::WriteTargetDriverRule(const char* main_output,
}
// Make sure the extra files are built.
- for(std::set<cmStdString>::const_iterator i = this->ExtraFiles.begin();
- i != this->ExtraFiles.end(); ++i)
- {
- depends.push_back(*i);
- }
+ depends.insert(depends.end(),
+ this->ExtraFiles.begin(), this->ExtraFiles.end());
}
// Write the driver rule.
std::vector<std::string> no_commands;
this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, comment,
- buildTargetRuleName.c_str(),
+ buildTargetRuleName,
depends, no_commands, true);
}
//----------------------------------------------------------------------------
-std::string cmMakefileTargetGenerator::GetFrameworkFlags()
-{
- if(!this->Makefile->IsOn("APPLE"))
- {
- return std::string();
- }
-
- std::set<cmStdString> emitted;
-#ifdef __APPLE__ /* don't insert this when crosscompiling e.g. to iphone */
- emitted.insert("/System/Library/Frameworks");
-#endif
- std::vector<std::string> includes;
-
- const char *config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE");
- this->LocalGenerator->GetIncludeDirectories(includes,
- this->GeneratorTarget,
- "C", config);
- // check all include directories for frameworks as this
- // will already have added a -F for the framework
- for(std::vector<std::string>::iterator i = includes.begin();
- i != includes.end(); ++i)
- {
- if(this->Target->NameResolvesToFramework(i->c_str()))
- {
- std::string frameworkDir = *i;
- frameworkDir += "/../";
- frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir.c_str());
- emitted.insert(frameworkDir);
- }
- }
-
- std::string flags;
- const char* cfg = this->LocalGenerator->ConfigurationName.c_str();
- if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg))
- {
- std::vector<std::string> const& frameworks = cli->GetFrameworkPaths();
- for(std::vector<std::string>::const_iterator i = frameworks.begin();
- i != frameworks.end(); ++i)
- {
- if(emitted.insert(*i).second)
- {
- flags += "-F";
- flags += this->Convert(i->c_str(),
- cmLocalGenerator::START_OUTPUT,
- cmLocalGenerator::SHELL, true);
- flags += " ";
- }
- }
- }
- return flags;
-}
-
-//----------------------------------------------------------------------------
void cmMakefileTargetGenerator
::AppendTargetDepends(std::vector<std::string>& depends)
{
// Static libraries never depend on anything for linking.
- if(this->Target->GetType() == cmTarget::STATIC_LIBRARY)
+ if(this->GeneratorTarget->GetType() == cmState::STATIC_LIBRARY)
{
return;
}
// Loop over all library dependencies.
- const char* cfg = this->LocalGenerator->ConfigurationName.c_str();
- if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg))
+ const char* cfg = this->LocalGenerator->GetConfigName().c_str();
+ if(cmComputeLinkInformation* cli =
+ this->GeneratorTarget->GetLinkInformation(cfg))
{
std::vector<std::string> const& libDeps = cli->GetDepends();
- for(std::vector<std::string>::const_iterator j = libDeps.begin();
- j != libDeps.end(); ++j)
- {
- depends.push_back(*j);
- }
+ depends.insert(depends.end(), libDeps.begin(), libDeps.end());
}
}
@@ -1596,12 +1479,8 @@ void cmMakefileTargetGenerator
}
// Add dependencies on the external object files.
- for(std::vector<std::string>::const_iterator obj
- = this->ExternalObjects.begin();
- obj != this->ExternalObjects.end(); ++obj)
- {
- depends.push_back(*obj);
- }
+ depends.insert(depends.end(),
+ this->ExternalObjects.begin(), this->ExternalObjects.end());
// Add a dependency on the rule file itself.
this->LocalGenerator->AppendRuleDepend(depends,
@@ -1618,29 +1497,39 @@ void cmMakefileTargetGenerator
this->AppendTargetDepends(depends);
// Add a dependency on the link definitions file, if any.
- if(!this->GeneratorTarget->ModuleDefinitionFile.empty())
+ if(this->ModuleDefinitionFile)
+ {
+ depends.push_back(this->ModuleDefinitionFile->GetFullPath());
+ }
+
+ // Add a dependency on user-specified manifest files, if any.
+ std::vector<cmSourceFile const*> manifest_srcs;
+ this->GeneratorTarget->GetManifests(manifest_srcs, this->ConfigName);
+ for (std::vector<cmSourceFile const*>::iterator mi = manifest_srcs.begin();
+ mi != manifest_srcs.end(); ++mi)
{
- depends.push_back(this->GeneratorTarget->ModuleDefinitionFile);
+ depends.push_back((*mi)->GetFullPath());
}
// Add user-specified dependencies.
if(const char* linkDepends =
- this->Target->GetProperty("LINK_DEPENDS"))
+ this->GeneratorTarget->GetProperty("LINK_DEPENDS"))
{
cmSystemTools::ExpandListArgument(linkDepends, depends);
}
}
//----------------------------------------------------------------------------
-std::string cmMakefileTargetGenerator::GetLinkRule(const char* linkRuleVar)
+std::string cmMakefileTargetGenerator::GetLinkRule(
+ const std::string& linkRuleVar)
{
std::string linkRule = this->Makefile->GetRequiredDefinition(linkRuleVar);
- if(this->Target->HasImplibGNUtoMS())
+ if(this->GeneratorTarget->HasImplibGNUtoMS())
{
std::string ruleVar = "CMAKE_";
- ruleVar += this->Target->GetLinkerLanguage(this->ConfigName);
+ ruleVar += this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
ruleVar += "_GNUtoMS_RULE";
- if(const char* rule = this->Makefile->GetDefinition(ruleVar.c_str()))
+ if(const char* rule = this->Makefile->GetDefinition(ruleVar))
{
linkRule += rule;
}
@@ -1658,8 +1547,8 @@ void cmMakefileTargetGenerator
}
void cmMakefileTargetGenerator::RemoveForbiddenFlags(const char* flagVar,
- const char* linkLang,
- std::string& linkFlags)
+ const std::string& linkLang,
+ std::string& linkFlags)
{
// check for language flags that are not allowed at link time, and
// remove them, -w on darwin for gcc -w -dynamiclib sends -w to libtool
@@ -1669,23 +1558,46 @@ void cmMakefileTargetGenerator::RemoveForbiddenFlags(const char* flagVar,
removeFlags += linkLang;
removeFlags += flagVar;
std::string removeflags =
- this->Makefile->GetSafeDefinition(removeFlags.c_str());
+ this->Makefile->GetSafeDefinition(removeFlags);
std::vector<std::string> removeList;
cmSystemTools::ExpandListArgument(removeflags, removeList);
+
for(std::vector<std::string>::iterator i = removeList.begin();
i != removeList.end(); ++i)
{
- cmSystemTools::ReplaceString(linkFlags, i->c_str(), "");
- }
-}
+ std::string tmp;
+ std::string::size_type lastPosition = 0;
-//----------------------------------------------------------------------------
-void
-cmMakefileTargetGenerator
-::AddMultipleOutputPair(const char* depender, const char* dependee)
-{
- MultipleOutputPairsType::value_type p(depender, dependee);
- this->MultipleOutputPairs.insert(p);
+ for(;;)
+ {
+ std::string::size_type position = linkFlags.find(*i, lastPosition);
+
+ if(position == std::string::npos)
+ {
+ tmp += linkFlags.substr(lastPosition);
+ break;
+ }
+ else
+ {
+ std::string::size_type prefixLength = position - lastPosition;
+ tmp += linkFlags.substr(lastPosition, prefixLength);
+ lastPosition = position + i->length();
+
+ bool validFlagStart = position == 0 ||
+ isspace(linkFlags[position - 1]);
+
+ bool validFlagEnd = lastPosition == linkFlags.size() ||
+ isspace(linkFlags[lastPosition]);
+
+ if(!validFlagStart || !validFlagEnd)
+ {
+ tmp += *i;
+ }
+ }
+ }
+
+ linkFlags = tmp;
+ }
}
//----------------------------------------------------------------------------
@@ -1715,7 +1627,7 @@ cmMakefileTargetGenerator
// Create the makefile command to invoke the link script.
std::string link_command = "$(CMAKE_COMMAND) -E cmake_link_script ";
- link_command += this->Convert(linkScriptName.c_str(),
+ link_command += this->Convert(linkScriptName,
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::SHELL);
link_command += " --verbose=$(VERBOSE)";
@@ -1751,13 +1663,58 @@ cmMakefileTargetGenerator
//----------------------------------------------------------------------------
void
cmMakefileTargetGenerator
+::CreateLinkLibs(std::string& linkLibs, bool relink,
+ bool useResponseFile,
+ std::vector<std::string>& makefile_depends,
+ bool useWatcomQuote)
+{
+ std::string frameworkPath;
+ std::string linkPath;
+ this->LocalGenerator
+ ->OutputLinkLibraries(linkLibs, frameworkPath, linkPath,
+ *this->GeneratorTarget, relink,
+ useResponseFile,
+ useWatcomQuote);
+ linkLibs = frameworkPath + linkPath + linkLibs;
+
+ if(useResponseFile && linkLibs.find_first_not_of(" ") != linkLibs.npos)
+ {
+ // Lookup the response file reference flag.
+ std::string responseFlagVar = "CMAKE_";
+ responseFlagVar += this->GeneratorTarget
+ ->GetLinkerLanguage(this->ConfigName);
+ responseFlagVar += "_RESPONSE_FILE_LINK_FLAG";
+ const char* responseFlag =
+ this->Makefile->GetDefinition(responseFlagVar);
+ if(!responseFlag)
+ {
+ responseFlag = "@";
+ }
+
+ // Create this response file.
+ std::string link_rsp =
+ this->CreateResponseFile("linklibs.rsp", linkLibs, makefile_depends);
+
+ // Reference the response file.
+ linkLibs = responseFlag;
+ linkLibs += this->Convert(link_rsp,
+ cmLocalGenerator::NONE,
+ cmLocalGenerator::SHELL);
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmMakefileTargetGenerator
::CreateObjectLists(bool useLinkScript, bool useArchiveRules,
bool useResponseFile, std::string& buildObjs,
- std::vector<std::string>& makefile_depends)
+ std::vector<std::string>& makefile_depends,
+ bool useWatcomQuote)
{
std::string variableName;
std::string variableNameExternal;
- this->WriteObjectsVariable(variableName, variableNameExternal);
+ this->WriteObjectsVariable(variableName, variableNameExternal,
+ useWatcomQuote);
if(useResponseFile)
{
// MSVC response files cannot exceed 128K.
@@ -1769,10 +1726,11 @@ cmMakefileTargetGenerator
// Lookup the response file reference flag.
std::string responseFlagVar = "CMAKE_";
- responseFlagVar += this->Target->GetLinkerLanguage(this->ConfigName);
+ responseFlagVar += this->GeneratorTarget
+ ->GetLinkerLanguage(this->ConfigName);
responseFlagVar += "_RESPONSE_FILE_LINK_FLAG";
const char* responseFlag =
- this->Makefile->GetDefinition(responseFlagVar.c_str());
+ this->Makefile->GetDefinition(responseFlagVar);
if(!responseFlag)
{
responseFlag = "@";
@@ -1796,7 +1754,7 @@ cmMakefileTargetGenerator
// Reference the response file.
buildObjs += responseFlag;
- buildObjs += this->Convert(objects_rsp.c_str(),
+ buildObjs += this->Convert(objects_rsp,
cmLocalGenerator::NONE,
cmLocalGenerator::SHELL);
}
@@ -1820,23 +1778,25 @@ cmMakefileTargetGenerator
//----------------------------------------------------------------------------
void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags,
- const char* lang)
+ const std::string& lang)
{
std::string responseVar = "CMAKE_";
responseVar += lang;
responseVar += "_USE_RESPONSE_FILE_FOR_INCLUDES";
- bool useResponseFile = this->Makefile->IsOn(responseVar.c_str());
+ bool useResponseFile = this->Makefile->IsOn(responseVar);
std::vector<std::string> includes;
- const char *config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE");
+ const std::string& config =
+ this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
this->LocalGenerator->GetIncludeDirectories(includes,
this->GeneratorTarget,
lang, config);
std::string includeFlags =
this->LocalGenerator->GetIncludeFlags(includes, this->GeneratorTarget,
- lang, useResponseFile);
+ lang, false, useResponseFile,
+ config);
if(includeFlags.empty())
{
return;
@@ -1850,154 +1810,10 @@ void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags,
std::string arg = "@" +
this->CreateResponseFile(name.c_str(), includeFlags,
this->FlagFileDepends[lang]);
- this->LocalGenerator->AppendFlags(flags, arg.c_str());
+ this->LocalGenerator->AppendFlags(flags, arg);
}
else
{
- this->LocalGenerator->AppendFlags(flags, includeFlags.c_str());
- }
-}
-
-//----------------------------------------------------------------------------
-const char* cmMakefileTargetGenerator::GetFortranModuleDirectory()
-{
- // Compute the module directory.
- if(!this->FortranModuleDirectoryComputed)
- {
- const char* target_mod_dir =
- this->Target->GetProperty("Fortran_MODULE_DIRECTORY");
- const char* moddir_flag =
- this->Makefile->GetDefinition("CMAKE_Fortran_MODDIR_FLAG");
- if(target_mod_dir && moddir_flag)
- {
- // Compute the full path to the module directory.
- if(cmSystemTools::FileIsFullPath(target_mod_dir))
- {
- // Already a full path.
- this->FortranModuleDirectory = target_mod_dir;
- }
- else
- {
- // Interpret relative to the current output directory.
- this->FortranModuleDirectory =
- this->Makefile->GetCurrentOutputDirectory();
- this->FortranModuleDirectory += "/";
- this->FortranModuleDirectory += target_mod_dir;
- }
-
- // Make sure the module output directory exists.
- cmSystemTools::MakeDirectory(this->FortranModuleDirectory.c_str());
- }
- this->FortranModuleDirectoryComputed = true;
- }
-
- // Return the computed directory.
- if(this->FortranModuleDirectory.empty())
- {
- return 0;
- }
- else
- {
- return this->FortranModuleDirectory.c_str();
- }
-}
-
-//----------------------------------------------------------------------------
-void cmMakefileTargetGenerator::AddFortranFlags(std::string& flags)
-{
- // Enable module output if necessary.
- if(const char* modout_flag =
- this->Makefile->GetDefinition("CMAKE_Fortran_MODOUT_FLAG"))
- {
- this->LocalGenerator->AppendFlags(flags, modout_flag);
- }
-
- // Add a module output directory flag if necessary.
- const char* mod_dir = this->GetFortranModuleDirectory();
- if(!mod_dir)
- {
- mod_dir = this->Makefile->GetDefinition("CMAKE_Fortran_MODDIR_DEFAULT");
- }
- if(mod_dir)
- {
- const char* moddir_flag =
- this->Makefile->GetRequiredDefinition("CMAKE_Fortran_MODDIR_FLAG");
- std::string modflag = moddir_flag;
- modflag += this->Convert(mod_dir,
- cmLocalGenerator::START_OUTPUT,
- cmLocalGenerator::SHELL);
- this->LocalGenerator->AppendFlags(flags, modflag.c_str());
- }
-
- // If there is a separate module path flag then duplicate the
- // include path with it. This compiler does not search the include
- // path for modules.
- if(const char* modpath_flag =
- this->Makefile->GetDefinition("CMAKE_Fortran_MODPATH_FLAG"))
- {
- std::vector<std::string> includes;
- const char *config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE");
- this->LocalGenerator->GetIncludeDirectories(includes,
- this->GeneratorTarget,
- "C", config);
- for(std::vector<std::string>::const_iterator idi = includes.begin();
- idi != includes.end(); ++idi)
- {
- std::string flg = modpath_flag;
- flg += this->Convert(idi->c_str(),
- cmLocalGenerator::NONE,
- cmLocalGenerator::SHELL);
- this->LocalGenerator->AppendFlags(flags, flg.c_str());
- }
- }
-}
-
-//----------------------------------------------------------------------------
-void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags)
-{
- if(this->GeneratorTarget->ModuleDefinitionFile.empty())
- {
- return;
- }
-
- // TODO: Create a per-language flag variable.
- const char* defFileFlag =
- this->Makefile->GetDefinition("CMAKE_LINK_DEF_FILE_FLAG");
- if(!defFileFlag)
- {
- return;
- }
-
- // Append the flag and value. Use ConvertToLinkReference to help
- // vs6's "cl -link" pass it to the linker.
- std::string flag = defFileFlag;
- flag += (this->LocalGenerator->ConvertToLinkReference(
- this->GeneratorTarget->ModuleDefinitionFile.c_str()));
- this->LocalGenerator->AppendFlags(flags, flag.c_str());
-}
-
-//----------------------------------------------------------------------------
-const char* cmMakefileTargetGenerator::GetFeature(const char* feature)
-{
- return this->Target->GetFeature(feature, this->ConfigName);
-}
-
-//----------------------------------------------------------------------------
-bool cmMakefileTargetGenerator::GetFeatureAsBool(const char* feature)
-{
- return cmSystemTools::IsOn(this->GetFeature(feature));
-}
-
-//----------------------------------------------------------------------------
-void cmMakefileTargetGenerator::AddFeatureFlags(
- std::string& flags, const char* lang
- )
-{
- // Add language-specific flags.
- this->LocalGenerator->AddLanguageFlags(flags, lang, this->ConfigName);
-
- if(this->GetFeatureAsBool("INTERPROCEDURAL_OPTIMIZATION"))
- {
- this->LocalGenerator->AppendFeatureOptions(flags, lang, "IPO");
+ this->LocalGenerator->AppendFlags(flags, includeFlags);
}
}
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index f7a1e2e56..38f40c082 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -12,33 +12,33 @@
#ifndef cmMakefileTargetGenerator_h
#define cmMakefileTargetGenerator_h
+#include "cmCommonTargetGenerator.h"
+
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmOSXBundleGenerator.h"
-class cmCustomCommand;
-class cmDependInformation;
+class cmCustomCommandGenerator;
class cmDepends;
class cmGeneratorTarget;
class cmGeneratedFileStream;
class cmGlobalUnixMakefileGenerator3;
class cmLocalUnixMakefileGenerator3;
class cmMakefile;
-class cmTarget;
class cmSourceFile;
/** \class cmMakefileTargetGenerator
* \brief Support Routines for writing makefiles
*
*/
-class cmMakefileTargetGenerator
+class cmMakefileTargetGenerator: public cmCommonTargetGenerator
{
public:
// constructor to set the ivars
- cmMakefileTargetGenerator(cmTarget* target);
+ cmMakefileTargetGenerator(cmGeneratorTarget* target);
virtual ~cmMakefileTargetGenerator();
// construct using this factory call
- static cmMakefileTargetGenerator *New(cmTarget *tgt);
+ static cmMakefileTargetGenerator *New(cmGeneratorTarget *tgt);
/* the main entry point for this class. Writes the Makefiles associated
with this target */
@@ -50,7 +50,7 @@ public:
std::string GetProgressFileNameFull()
{ return this->ProgressFileNameFull; }
- cmTarget* GetTarget() { return this->Target;}
+ cmGeneratorTarget* GetGeneratorTarget() { return this->GeneratorTarget;}
protected:
@@ -81,7 +81,7 @@ protected:
MacOSXContentGeneratorType(cmMakefileTargetGenerator* gen) :
Generator(gen) {}
- void operator()(cmSourceFile& source, const char* pkgloc);
+ void operator()(cmSourceFile const& source, const char* pkgloc);
private:
cmMakefileTargetGenerator* Generator;
@@ -89,45 +89,41 @@ protected:
friend struct MacOSXContentGeneratorType;
// write the rules for an object
- void WriteObjectRuleFiles(cmSourceFile& source);
+ void WriteObjectRuleFiles(cmSourceFile const& source);
// write the build rule for an object
void WriteObjectBuildFile(std::string &obj,
- const char *lang,
- cmSourceFile& source,
+ const std::string& lang,
+ cmSourceFile const& source,
std::vector<std::string>& depends);
// write the depend.make file for an object
- void WriteObjectDependRules(cmSourceFile& source,
+ void WriteObjectDependRules(cmSourceFile const& source,
std::vector<std::string>& depends);
// write the build rule for a custom command
- void GenerateCustomRuleFile(const cmCustomCommand& cc);
+ void GenerateCustomRuleFile(cmCustomCommandGenerator const& ccg);
// write a rule to drive building of more than one output from
// another rule
void GenerateExtraOutput(const char* out, const char* in,
bool symbolic = false);
- void AppendProgress(std::vector<std::string>& commands);
+ void MakeEchoProgress(cmLocalUnixMakefileGenerator3::EchoProgress&) const;
// write out the variable that lists the objects for this target
void WriteObjectsVariable(std::string& variableName,
- std::string& variableNameExternal);
+ std::string& variableNameExternal,
+ bool useWatcomQuote);
void WriteObjectsString(std::string& buildObjs);
void WriteObjectsStrings(std::vector<std::string>& objStrings,
std::string::size_type limit = std::string::npos);
// write the driver rule to build target outputs
- void WriteTargetDriverRule(const char* main_output, bool relink);
+ void WriteTargetDriverRule(const std::string& main_output, bool relink);
void DriveCustomCommands(std::vector<std::string>& depends);
- // Return the a string with -F flags on apple
- std::string GetFrameworkFlags();
-
- void AppendFortranFormatFlags(std::string& flags, cmSourceFile& source);
-
// append intertarget dependencies
void AppendTargetDepends(std::vector<std::string>& depends);
@@ -138,16 +134,7 @@ protected:
void AppendLinkDepends(std::vector<std::string>& depends);
// Lookup the link rule for this target.
- std::string GetLinkRule(const char* linkRuleVar);
-
- /** In order to support parallel builds for custom commands with
- multiple outputs the outputs are given a serial order, and only
- the first output actually has the build rule. Other outputs
- just depend on the first one. The check-build-system step must
- remove a dependee if the depender is missing to make sure both
- are regenerated properly. This method is used by the local
- makefile generators to register such pairs. */
- void AddMultipleOutputPair(const char* depender, const char* dependee);
+ std::string GetLinkRule(const std::string& linkRuleVar);
/** Create a script to hold link rules and a command to invoke the
script at build time. */
@@ -163,22 +150,25 @@ protected:
std::string const& options,
std::vector<std::string>& makefile_depends);
+ /** Create list of flags for link libraries. */
+ void CreateLinkLibs(std::string& linkLibs, bool relink,
+ bool useResponseFile,
+ std::vector<std::string>& makefile_depends,
+ bool useWatcomQuote);
+
/** Create lists of object files for linking and cleaning. */
void CreateObjectLists(bool useLinkScript, bool useArchiveRules,
bool useResponseFile, std::string& buildObjs,
- std::vector<std::string>& makefile_depends);
+ std::vector<std::string>& makefile_depends,
+ bool useWatcomQuote);
- void AddIncludeFlags(std::string& flags, const char* lang);
+ void AddIncludeFlags(std::string& flags, const std::string& lang);
virtual void CloseFileStreams();
- void RemoveForbiddenFlags(const char* flagVar, const char* linkLang,
+ void RemoveForbiddenFlags(const char* flagVar, const std::string& linkLang,
std::string& linkFlags);
- cmTarget *Target;
- cmGeneratorTarget* GeneratorTarget;
cmLocalUnixMakefileGenerator3 *LocalGenerator;
cmGlobalUnixMakefileGenerator3 *GlobalGenerator;
- cmMakefile *Makefile;
- const char *ConfigName;
enum CustomCommandDriveType { OnBuild, OnDepends, OnUtility };
CustomCommandDriveType CustomCommandDriver;
@@ -203,7 +193,7 @@ protected:
std::string FlagFileNameFull;
cmGeneratedFileStream *FlagFileStream;
class StringList: public std::vector<std::string> {};
- std::map<cmStdString, StringList> FlagFileDepends;
+ std::map<std::string, StringList> FlagFileDepends;
// the stream for the info file
std::string InfoFileNameFull;
@@ -217,13 +207,19 @@ protected:
std::vector<std::string> ExternalObjects;
// Set of object file names that will be built in this directory.
- std::set<cmStdString> ObjectFiles;
+ std::set<std::string> ObjectFiles;
// Set of extra output files to be driven by the build.
- std::set<cmStdString> ExtraFiles;
+ std::set<std::string> ExtraFiles;
- typedef std::map<cmStdString, cmStdString> MultipleOutputPairsType;
+ typedef std::map<std::string, std::string> MultipleOutputPairsType;
MultipleOutputPairsType MultipleOutputPairs;
+ bool WriteMakeRule(std::ostream& os,
+ const char* comment,
+ const std::vector<std::string>& outputs,
+ const std::vector<std::string>& depends,
+ const std::vector<std::string>& commands,
+ bool in_help = false);
// Target name info.
std::string TargetNameOut;
@@ -233,46 +229,9 @@ protected:
std::string TargetNamePDB;
// Mac OS X content info.
- std::set<cmStdString> MacContentFolders;
+ std::set<std::string> MacContentFolders;
cmOSXBundleGenerator* OSXBundleGenerator;
MacOSXContentGeneratorType* MacOSXContentGenerator;
-
- typedef std::map<cmStdString, cmStdString> ByLanguageMap;
- std::string GetFlags(const std::string &l);
- ByLanguageMap FlagsByLanguage;
- std::string GetDefines(const std::string &l);
- ByLanguageMap DefinesByLanguage;
-
- // Target-wide Fortran module output directory.
- bool FortranModuleDirectoryComputed;
- std::string FortranModuleDirectory;
- const char* GetFortranModuleDirectory();
-
- // Compute target-specific Fortran language flags.
- void AddFortranFlags(std::string& flags);
-
- // Helper to add flag for windows .def file.
- void AddModuleDefinitionFlag(std::string& flags);
-
- // Add language feature flags.
- void AddFeatureFlags(std::string& flags, const char* lang);
-
- // Feature query methods.
- const char* GetFeature(const char* feature);
- bool GetFeatureAsBool(const char* feature);
-
- //==================================================================
- // Convenience routines that do nothing more than forward to
- // implementaitons
- std::string Convert(const char* source,
- cmLocalGenerator::RelativeRoot relative,
- cmLocalGenerator::OutputFormat output =
- cmLocalGenerator::UNCHANGED,
- bool optional = false)
- {
- return this->LocalGenerator->Convert(source, relative, output, optional);
- }
-
};
#endif
diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx
index 1fa4e95b6..5b62cbf3b 100644
--- a/Source/cmMakefileUtilityTargetGenerator.cxx
+++ b/Source/cmMakefileUtilityTargetGenerator.cxx
@@ -16,15 +16,14 @@
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
-#include "cmTarget.h"
//----------------------------------------------------------------------------
cmMakefileUtilityTargetGenerator
-::cmMakefileUtilityTargetGenerator(cmTarget* target):
+::cmMakefileUtilityTargetGenerator(cmGeneratorTarget* target):
cmMakefileTargetGenerator(target)
{
this->CustomCommandDriver = OnUtility;
- this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target,
+ this->OSXBundleGenerator = new cmOSXBundleGenerator(target,
this->ConfigName);
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
}
@@ -42,7 +41,8 @@ void cmMakefileUtilityTargetGenerator::WriteRuleFiles()
this->CreateRuleFile();
*this->BuildFileStream
- << "# Utility rule file for " << this->Target->GetName() << ".\n\n";
+ << "# Utility rule file for "
+ << this->GeneratorTarget->GetName() << ".\n\n";
if(!this->NoRuleMessages)
{
@@ -51,10 +51,10 @@ void cmMakefileUtilityTargetGenerator::WriteRuleFiles()
// Include the progress variables for the target.
*this->BuildFileStream
<< "# Include the progress variables for this target.\n"
- << this->LocalGenerator->IncludeDirective << " " << root
- << this->Convert(this->ProgressFileNameFull.c_str(),
+ << this->GlobalGenerator->IncludeDirective << " " << root
+ << this->Convert(this->ProgressFileNameFull,
cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE)
+ cmLocalGenerator::MAKERULE)
<< "\n\n";
}
@@ -67,19 +67,21 @@ void cmMakefileUtilityTargetGenerator::WriteRuleFiles()
// Utility targets store their rules in pre- and post-build commands.
this->LocalGenerator->AppendCustomDepends
- (depends, this->Target->GetPreBuildCommands());
+ (depends, this->GeneratorTarget->GetPreBuildCommands());
this->LocalGenerator->AppendCustomDepends
- (depends, this->Target->GetPostBuildCommands());
+ (depends, this->GeneratorTarget->GetPostBuildCommands());
this->LocalGenerator->AppendCustomCommands
- (commands, this->Target->GetPreBuildCommands(), this->Target);
+ (commands, this->GeneratorTarget->GetPreBuildCommands(),
+ this->GeneratorTarget);
// Depend on all custom command outputs for sources
this->DriveCustomCommands(depends);
this->LocalGenerator->AppendCustomCommands
- (commands, this->Target->GetPostBuildCommands(), this->Target);
+ (commands, this->GeneratorTarget->GetPostBuildCommands(),
+ this->GeneratorTarget);
// Add dependencies on targets that must be built first.
this->AppendTargetDepends(depends);
@@ -101,11 +103,11 @@ void cmMakefileUtilityTargetGenerator::WriteRuleFiles()
// Write the rule.
this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
- this->Target->GetName(),
+ this->GeneratorTarget->GetName(),
depends, commands, true);
// Write the main driver rule to build everything in this target.
- this->WriteTargetDriverRule(this->Target->GetName(), false);
+ this->WriteTargetDriverRule(this->GeneratorTarget->GetName(), false);
// Write clean target
this->WriteTargetCleanRules();
diff --git a/Source/cmMakefileUtilityTargetGenerator.h b/Source/cmMakefileUtilityTargetGenerator.h
index fc47b3891..8f9930052 100644
--- a/Source/cmMakefileUtilityTargetGenerator.h
+++ b/Source/cmMakefileUtilityTargetGenerator.h
@@ -18,7 +18,7 @@ class cmMakefileUtilityTargetGenerator:
public cmMakefileTargetGenerator
{
public:
- cmMakefileUtilityTargetGenerator(cmTarget* target);
+ cmMakefileUtilityTargetGenerator(cmGeneratorTarget* target);
virtual ~cmMakefileUtilityTargetGenerator();
/* the main entry point for this class. Writes the Makefiles associated
diff --git a/Source/cmMarkAsAdvancedCommand.cxx b/Source/cmMarkAsAdvancedCommand.cxx
index 4236d102c..8d0e2b3a4 100644
--- a/Source/cmMarkAsAdvancedCommand.cxx
+++ b/Source/cmMarkAsAdvancedCommand.cxx
@@ -36,25 +36,21 @@ bool cmMarkAsAdvancedCommand
for(; i < args.size(); ++i)
{
std::string variable = args[i];
- cmCacheManager* manager = this->Makefile->GetCacheManager();
- cmCacheManager::CacheIterator it =
- manager->GetCacheIterator(variable.c_str());
- if ( it.IsAtEnd() )
+ cmState* state = this->Makefile->GetState();
+ if (!state->GetCacheEntryValue(variable))
{
- this->Makefile->GetCacheManager()
- ->AddCacheEntry(variable.c_str(), 0, 0,
- cmCacheManager::UNINITIALIZED);
+ this->Makefile->GetCMakeInstance()->AddCacheEntry(
+ variable, 0, 0, cmState::UNINITIALIZED);
overwrite = true;
}
- it.Find(variable.c_str());
- if ( it.IsAtEnd() )
+ if (!state->GetCacheEntryValue(variable))
{
cmSystemTools::Error("This should never happen...");
return false;
}
- if ( !it.PropertyExists("ADVANCED") || overwrite )
+ if (!state->GetCacheEntryProperty(variable, "ADVANCED") || overwrite)
{
- it.SetProperty("ADVANCED", value);
+ state->SetCacheEntryProperty(variable, "ADVANCED", value);
}
}
return true;
diff --git a/Source/cmMarkAsAdvancedCommand.h b/Source/cmMarkAsAdvancedCommand.h
index 246eb8aa3..38064a326 100644
--- a/Source/cmMarkAsAdvancedCommand.h
+++ b/Source/cmMarkAsAdvancedCommand.h
@@ -40,34 +40,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const {return "mark_as_advanced";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Mark cmake cached variables as advanced.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " mark_as_advanced([CLEAR|FORCE] VAR VAR2 VAR...)\n"
- "Mark the named cached variables as advanced. An advanced variable "
- "will not be displayed in any of the cmake GUIs unless the show "
- "advanced option is on. "
- "If CLEAR is the first argument advanced variables are changed back "
- "to unadvanced. "
- "If FORCE is the first argument, then the variable is made advanced. "
- "If neither FORCE nor CLEAR is specified, new values will be marked as "
- "advanced, but if the variable already has an advanced/non-advanced "
- "state, it will not be changed.\n"
- "It does nothing in script mode.";
- }
+ virtual std::string GetName() const {return "mark_as_advanced";}
/**
* This determines if the command is invoked when in script mode.
diff --git a/Source/cmMathCommand.cxx b/Source/cmMathCommand.cxx
index 9fc42659a..f1942c546 100644
--- a/Source/cmMathCommand.cxx
+++ b/Source/cmMathCommand.cxx
@@ -28,7 +28,7 @@ bool cmMathCommand
return this->HandleExprCommand(args);
}
std::string e = "does not recognize sub-command "+subCommand;
- this->SetError(e.c_str());
+ this->SetError(e);
return false;
}
@@ -49,13 +49,13 @@ bool cmMathCommand::HandleExprCommand(std::vector<std::string> const& args)
{
std::string e = "cannot parse the expression: \""+expression+"\": ";
e += helper.GetError();
- this->SetError(e.c_str());
+ this->SetError(e);
return false;
}
char buffer[1024];
sprintf(buffer, "%d", helper.GetResult());
- this->Makefile->AddDefinition(outputVariable.c_str(), buffer);
+ this->Makefile->AddDefinition(outputVariable, buffer);
return true;
}
diff --git a/Source/cmMathCommand.h b/Source/cmMathCommand.h
index dc0ceb340..76dc102bd 100644
--- a/Source/cmMathCommand.h
+++ b/Source/cmMathCommand.h
@@ -41,29 +41,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "math";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Mathematical expressions.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " math(EXPR <output variable> <math expression>)\n"
- "EXPR evaluates mathematical expression and returns result in the "
- "output variable. Example mathematical expression is "
- "'5 * ( 10 + 13 )'. Supported operators are "
- "+ - * / % | & ^ ~ << >> * / %. They have the same meaning "
- " as they do in C code.";
- }
+ virtual std::string GetName() const { return "math";}
cmTypeMacro(cmMathCommand, cmCommand);
protected:
diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx
index e1dbf349d..1c67ceace 100644
--- a/Source/cmMessageCommand.cxx
+++ b/Source/cmMessageCommand.cxx
@@ -20,12 +20,12 @@ bool cmMessageCommand
this->SetError("called with incorrect number of arguments");
return false;
}
- std::string message;
std::vector<std::string>::const_iterator i = args.begin();
cmake::MessageType type = cmake::MESSAGE;
bool status = false;
bool fatal = false;
+ cmake* cm = this->Makefile->GetCMakeInstance();
if (*i == "SEND_ERROR")
{
type = cmake::FATAL_ERROR;
@@ -44,7 +44,19 @@ bool cmMessageCommand
}
else if (*i == "AUTHOR_WARNING")
{
- type = cmake::AUTHOR_WARNING;
+ if (cm->GetDevWarningsAsErrors(this->Makefile))
+ {
+ fatal = true;
+ type = cmake::AUTHOR_ERROR;
+ }
+ else if (!cm->GetSuppressDevWarnings(this->Makefile))
+ {
+ type = cmake::AUTHOR_WARNING;
+ }
+ else
+ {
+ return true;
+ }
++i;
}
else if (*i == "STATUS")
@@ -52,15 +64,30 @@ bool cmMessageCommand
status = true;
++i;
}
-
- for(;i != args.end(); ++i)
+ else if (*i == "DEPRECATION")
{
- message += *i;
+ if (cm->GetDeprecatedWarningsAsErrors(this->Makefile))
+ {
+ fatal = true;
+ type = cmake::DEPRECATION_ERROR;
+ }
+ else if (!cm->GetSuppressDeprecatedWarnings(this->Makefile))
+ {
+ type = cmake::DEPRECATION_WARNING;
+ }
+ else
+ {
+ return true;
+ }
+ ++i;
}
+ std::string message = cmJoin(cmMakeRange(i, args.end()), std::string());
+
if (type != cmake::MESSAGE)
{
- this->Makefile->IssueMessage(type, message.c_str());
+ // we've overriden the message type, above, so force IssueMessage to use it
+ this->Makefile->IssueMessage(type, message, true);
}
else
{
diff --git a/Source/cmMessageCommand.h b/Source/cmMessageCommand.h
index fc61810c3..c0ae2a322 100644
--- a/Source/cmMessageCommand.h
+++ b/Source/cmMessageCommand.h
@@ -39,52 +39,13 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "message";}
+ virtual std::string GetName() const { return "message";}
/**
* This determines if the command is invoked when in script mode.
*/
virtual bool IsScriptable() const { return true; }
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Display a message to the user.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " message([STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR]\n"
- " \"message to display\" ...)\n"
- "The optional keyword determines the type of message:\n"
- " (none) = Important information\n"
- " STATUS = Incidental information\n"
- " WARNING = CMake Warning, continue processing\n"
- " AUTHOR_WARNING = CMake Warning (dev), continue processing\n"
- " SEND_ERROR = CMake Error, continue processing,\n"
- " but skip generation\n"
- " FATAL_ERROR = CMake Error, stop processing and generation\n"
- "The CMake command-line tool displays STATUS messages on stdout "
- "and all other message types on stderr. "
- "The CMake GUI displays all messages in its log area. "
- "The interactive dialogs (ccmake and CMakeSetup) show STATUS messages "
- "one at a time on a status line and other messages in interactive "
- "pop-up boxes."
- "\n"
- "CMake Warning and Error message text displays using a simple "
- "markup language. "
- "Non-indented text is formatted in line-wrapped paragraphs delimited "
- "by newlines. "
- "Indented text is considered pre-formatted."
- ;
- }
-
cmTypeMacro(cmMessageCommand, cmCommand);
};
diff --git a/Source/cmNewLineStyle.cxx b/Source/cmNewLineStyle.cxx
index 6f7b6a949..08f0b5b09 100644
--- a/Source/cmNewLineStyle.cxx
+++ b/Source/cmNewLineStyle.cxx
@@ -76,9 +76,7 @@ const std::string cmNewLineStyle::GetCharacters() const
return "\n";
case CRLF:
return "\r\n";
- default:
- ;
- };
+ }
return "";
}
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 57adeba23..17561b5ab 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -17,9 +17,13 @@
#include "cmGeneratedFileStream.h"
#include "cmMakefile.h"
#include "cmOSXBundleGenerator.h"
+#include "cmGeneratorTarget.h"
+#include "cmCustomCommandGenerator.h"
+#include "cmAlgorithms.h"
#include <assert.h>
#include <algorithm>
+#include <limits>
#ifndef _WIN32
#include <unistd.h>
@@ -27,31 +31,31 @@
cmNinjaNormalTargetGenerator::
-cmNinjaNormalTargetGenerator(cmTarget* target)
+cmNinjaNormalTargetGenerator(cmGeneratorTarget* target)
: cmNinjaTargetGenerator(target)
, TargetNameOut()
, TargetNameSO()
, TargetNameReal()
, TargetNameImport()
, TargetNamePDB()
- , TargetLinkLanguage(0)
+ , TargetLinkLanguage("")
{
this->TargetLinkLanguage = target->GetLinkerLanguage(this->GetConfigName());
- if (target->GetType() == cmTarget::EXECUTABLE)
- target->GetExecutableNames(this->TargetNameOut,
+ if (target->GetType() == cmState::EXECUTABLE)
+ this->GetGeneratorTarget()->GetExecutableNames(this->TargetNameOut,
this->TargetNameReal,
this->TargetNameImport,
this->TargetNamePDB,
GetLocalGenerator()->GetConfigName());
else
- target->GetLibraryNames(this->TargetNameOut,
+ this->GetGeneratorTarget()->GetLibraryNames(this->TargetNameOut,
this->TargetNameSO,
this->TargetNameReal,
this->TargetNameImport,
this->TargetNamePDB,
GetLocalGenerator()->GetConfigName());
- if(target->GetType() != cmTarget::OBJECT_LIBRARY)
+ if(target->GetType() != cmState::OBJECT_LIBRARY)
{
// on Windows the output dir is already needed at compile time
// ensure the directory exists (OutDir test)
@@ -70,10 +74,10 @@ cmNinjaNormalTargetGenerator::~cmNinjaNormalTargetGenerator()
void cmNinjaNormalTargetGenerator::Generate()
{
- if (!this->TargetLinkLanguage) {
+ if (this->TargetLinkLanguage.empty()) {
cmSystemTools::Error("CMake can not determine linker language for "
"target: ",
- this->GetTarget()->GetName());
+ this->GetGeneratorTarget()->GetName().c_str());
return;
}
@@ -83,14 +87,12 @@ void cmNinjaNormalTargetGenerator::Generate()
// Write the build statements
this->WriteObjectBuildStatements();
- if(this->GetTarget()->GetType() == cmTarget::OBJECT_LIBRARY)
+ if(this->GetGeneratorTarget()->GetType() == cmState::OBJECT_LIBRARY)
{
this->WriteObjectLibStatement();
}
else
{
- this->WriteLinkRule(false); // write rule without rspfile support
- this->WriteLinkRule(true); // write rule with rspfile support
this->WriteLinkStatement();
}
}
@@ -101,33 +103,47 @@ void cmNinjaNormalTargetGenerator::WriteLanguagesRules()
cmGlobalNinjaGenerator::WriteDivider(this->GetRulesFileStream());
this->GetRulesFileStream()
<< "# Rules for each languages for "
- << cmTarget::GetTargetTypeName(this->GetTarget()->GetType())
+ << cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType())
<< " target "
<< this->GetTargetName()
<< "\n\n";
#endif
- std::set<cmStdString> languages;
- this->GetTarget()->GetLanguages(languages);
- for(std::set<cmStdString>::const_iterator l = languages.begin();
+ // Write rules for languages compiled in this target.
+ std::set<std::string> languages;
+ std::vector<cmSourceFile*> sourceFiles;
+ this->GetGeneratorTarget()->GetSourceFiles(sourceFiles,
+ this->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE"));
+ for(std::vector<cmSourceFile*>::const_iterator
+ i = sourceFiles.begin(); i != sourceFiles.end(); ++i)
+ {
+ const std::string& lang = (*i)->GetLanguage();
+ if(!lang.empty())
+ {
+ languages.insert(lang);
+ }
+ }
+ for(std::set<std::string>::const_iterator l = languages.begin();
l != languages.end();
++l)
+ {
this->WriteLanguageRules(*l);
+ }
}
const char *cmNinjaNormalTargetGenerator::GetVisibleTypeName() const
{
- switch (this->GetTarget()->GetType()) {
- case cmTarget::STATIC_LIBRARY:
+ switch (this->GetGeneratorTarget()->GetType()) {
+ case cmState::STATIC_LIBRARY:
return "static library";
- case cmTarget::SHARED_LIBRARY:
+ case cmState::SHARED_LIBRARY:
return "shared library";
- case cmTarget::MODULE_LIBRARY:
- if (this->GetTarget()->IsCFBundleOnApple())
+ case cmState::MODULE_LIBRARY:
+ if (this->GetGeneratorTarget()->IsCFBundleOnApple())
return "CFBundle shared module";
else
return "shared module";
- case cmTarget::EXECUTABLE:
+ case cmState::EXECUTABLE:
return "executable";
default:
return 0;
@@ -138,20 +154,22 @@ std::string
cmNinjaNormalTargetGenerator
::LanguageLinkerRule() const
{
- return std::string(this->TargetLinkLanguage)
+ return this->TargetLinkLanguage
+ "_"
- + cmTarget::GetTargetTypeName(this->GetTarget()->GetType())
- + "_LINKER";
+ + cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType())
+ + "_LINKER__"
+ + cmGlobalNinjaGenerator::EncodeRuleName(
+ this->GetGeneratorTarget()->GetName())
+ ;
}
void
cmNinjaNormalTargetGenerator
::WriteLinkRule(bool useResponseFile)
{
- cmTarget::TargetType targetType = this->GetTarget()->GetType();
+ cmState::TargetType targetType =
+ this->GetGeneratorTarget()->GetType();
std::string ruleName = this->LanguageLinkerRule();
- if (useResponseFile)
- ruleName += "_RSP_FILE";
// Select whether to use a response file for objects.
std::string rspfile;
@@ -160,8 +178,8 @@ cmNinjaNormalTargetGenerator
if (!this->GetGlobalGenerator()->HasRule(ruleName)) {
cmLocalGenerator::RuleVariables vars;
vars.RuleLauncher = "RULE_LAUNCH_LINK";
- vars.CMTarget = this->GetTarget();
- vars.Language = this->TargetLinkLanguage;
+ vars.CMTarget = this->GetGeneratorTarget();
+ vars.Language = this->TargetLinkLanguage.c_str();
std::string responseFlag;
if (!useResponseFile) {
@@ -173,7 +191,7 @@ cmNinjaNormalTargetGenerator
// build response file name
std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_LINK_FLAG";
- const char * flag = GetMakefile()->GetDefinition(cmakeLinkVar.c_str());
+ const char * flag = GetMakefile()->GetDefinition(cmakeLinkVar);
if(flag) {
responseFlag = flag;
} else {
@@ -183,24 +201,19 @@ cmNinjaNormalTargetGenerator
responseFlag += rspfile;
// build response file content
- std::string linkOptionVar = cmakeVarLang;
- linkOptionVar += "_COMPILER_LINKER_OPTION_FLAG_";
- linkOptionVar += cmTarget::GetTargetTypeName(targetType);
- const std::string linkOption =
- GetMakefile()->GetSafeDefinition(linkOptionVar.c_str());
- rspcontent = "$in_newline "+linkOption+" $LINK_PATH $LINK_LIBRARIES";
+ if (this->GetGlobalGenerator()->IsGCCOnWindows()) {
+ rspcontent = "$in";
+ } else {
+ rspcontent = "$in_newline";
+ }
+ rspcontent += " $LINK_PATH $LINK_LIBRARIES";
vars.Objects = responseFlag.c_str();
vars.LinkLibraries = "";
}
vars.ObjectDir = "$OBJECT_DIR";
- // TODO:
- // Makefile generator expands <TARGET> to the plain target name
- // with suffix. $out expands to a relative path. This difference
- // could make trouble when switching to Ninja generator. Maybe
- // using TARGET_NAME and RuleVariables::TargetName is a fix.
- vars.Target = "$out";
+ vars.Target = "$TARGET_FILE";
vars.SONameFlag = "$SONAME_FLAG";
vars.TargetSOName = "$SONAME";
@@ -211,11 +224,11 @@ cmNinjaNormalTargetGenerator
std::string targetVersionMajor;
std::string targetVersionMinor;
{
- cmOStringStream majorStream;
- cmOStringStream minorStream;
+ std::ostringstream majorStream;
+ std::ostringstream minorStream;
int major;
int minor;
- this->GetTarget()->GetTargetVersion(major, minor);
+ this->GetGeneratorTarget()->GetTargetVersion(major, minor);
majorStream << major;
minorStream << minor;
targetVersionMajor = majorStream.str();
@@ -226,15 +239,14 @@ cmNinjaNormalTargetGenerator
vars.Flags = "$FLAGS";
vars.LinkFlags = "$LINK_FLAGS";
+ vars.Manifests = "$MANIFESTS";
std::string langFlags;
- if (targetType != cmTarget::EXECUTABLE) {
- this->GetLocalGenerator()->AddLanguageFlags(langFlags,
- this->TargetLinkLanguage,
- this->GetConfigName());
- langFlags += " $ARCH_FLAGS";
+ if (targetType != cmState::EXECUTABLE)
+ {
+ langFlags += "$LANGUAGE_COMPILE_FLAGS $ARCH_FLAGS";
vars.LanguageCompileFlags = langFlags.c_str();
- }
+ }
// Rule for linking library/executable.
std::vector<std::string> linkCmds = this->ComputeLinkCmd();
@@ -250,41 +262,57 @@ cmNinjaNormalTargetGenerator
this->GetLocalGenerator()->BuildCommandLine(linkCmds);
// Write the linker rule with response file if needed.
- cmOStringStream comment;
+ std::ostringstream comment;
comment << "Rule for linking " << this->TargetLinkLanguage << " "
<< this->GetVisibleTypeName() << ".";
- cmOStringStream description;
+ std::ostringstream description;
description << "Linking " << this->TargetLinkLanguage << " "
- << this->GetVisibleTypeName() << " $out";
+ << this->GetVisibleTypeName() << " $TARGET_FILE";
this->GetGlobalGenerator()->AddRule(ruleName,
linkCmd,
description.str(),
comment.str(),
/*depfile*/ "",
+ /*deptype*/ "",
rspfile,
- rspcontent);
+ rspcontent,
+ /*restat*/ "$RESTAT",
+ /*generator*/ false);
}
if (this->TargetNameOut != this->TargetNameReal &&
- !this->GetTarget()->IsFrameworkOnApple()) {
+ !this->GetGeneratorTarget()->IsFrameworkOnApple()) {
std::string cmakeCommand =
this->GetLocalGenerator()->ConvertToOutputFormat(
- this->GetMakefile()->GetRequiredDefinition("CMAKE_COMMAND"),
- cmLocalGenerator::SHELL);
- if (targetType == cmTarget::EXECUTABLE)
+ cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
+ if (targetType == cmState::EXECUTABLE)
this->GetGlobalGenerator()->AddRule("CMAKE_SYMLINK_EXECUTABLE",
cmakeCommand +
" -E cmake_symlink_executable"
" $in $out && $POST_BUILD",
"Creating executable symlink $out",
- "Rule for creating executable symlink.");
+ "Rule for creating "
+ "executable symlink.",
+ /*depfile*/ "",
+ /*deptype*/ "",
+ /*rspfile*/ "",
+ /*rspcontent*/ "",
+ /*restat*/ "",
+ /*generator*/ false);
else
this->GetGlobalGenerator()->AddRule("CMAKE_SYMLINK_LIBRARY",
cmakeCommand +
" -E cmake_symlink_library"
" $in $SONAME $out && $POST_BUILD",
"Creating library symlink $out",
- "Rule for creating library symlink.");
+ "Rule for creating "
+ "library symlink.",
+ /*depfile*/ "",
+ /*deptype*/ "",
+ /*rspfile*/ "",
+ /*rspcontent*/ "",
+ /*restat*/ "",
+ /*generator*/ false);
}
}
@@ -293,129 +321,131 @@ cmNinjaNormalTargetGenerator
::ComputeLinkCmd()
{
std::vector<std::string> linkCmds;
- cmTarget::TargetType targetType = this->GetTarget()->GetType();
- switch (targetType) {
- case cmTarget::STATIC_LIBRARY: {
- // Check if you have a non archive way to create the static library.
- {
- std::string linkCmdVar = "CMAKE_";
- linkCmdVar += this->TargetLinkLanguage;
- linkCmdVar += "_CREATE_STATIC_LIBRARY";
- if (const char *linkCmd =
- this->GetMakefile()->GetDefinition(linkCmdVar.c_str()))
- {
- cmSystemTools::ExpandListArgument(linkCmd, linkCmds);
- return linkCmds;
- }
- }
-
+ cmMakefile* mf = this->GetMakefile();
+ {
+ std::string linkCmdVar = this->GetGeneratorTarget()
+ ->GetCreateRuleVariable(this->TargetLinkLanguage, this->GetConfigName());
+ const char *linkCmd = mf->GetDefinition(linkCmdVar);
+ if (linkCmd)
+ {
+ cmSystemTools::ExpandListArgument(linkCmd, linkCmds);
+ return linkCmds;
+ }
+ }
+ switch (this->GetGeneratorTarget()->GetType()) {
+ case cmState::STATIC_LIBRARY: {
// We have archive link commands set. First, delete the existing archive.
+ {
std::string cmakeCommand =
this->GetLocalGenerator()->ConvertToOutputFormat(
- this->GetMakefile()->GetRequiredDefinition("CMAKE_COMMAND"),
- cmLocalGenerator::SHELL);
- linkCmds.push_back(cmakeCommand + " -E remove $out");
-
+ cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
+ linkCmds.push_back(cmakeCommand + " -E remove $TARGET_FILE");
+ }
// TODO: Use ARCHIVE_APPEND for archives over a certain size.
{
std::string linkCmdVar = "CMAKE_";
linkCmdVar += this->TargetLinkLanguage;
linkCmdVar += "_ARCHIVE_CREATE";
- const char *linkCmd =
- this->GetMakefile()->GetRequiredDefinition(linkCmdVar.c_str());
+ const char *linkCmd = mf->GetRequiredDefinition(linkCmdVar);
cmSystemTools::ExpandListArgument(linkCmd, linkCmds);
}
{
std::string linkCmdVar = "CMAKE_";
linkCmdVar += this->TargetLinkLanguage;
linkCmdVar += "_ARCHIVE_FINISH";
- const char *linkCmd =
- this->GetMakefile()->GetRequiredDefinition(linkCmdVar.c_str());
+ const char *linkCmd = mf->GetRequiredDefinition(linkCmdVar);
cmSystemTools::ExpandListArgument(linkCmd, linkCmds);
}
return linkCmds;
}
- case cmTarget::SHARED_LIBRARY:
- case cmTarget::MODULE_LIBRARY:
- case cmTarget::EXECUTABLE: {
- std::string linkCmdVar = "CMAKE_";
- linkCmdVar += this->TargetLinkLanguage;
- switch (targetType) {
- case cmTarget::SHARED_LIBRARY:
- linkCmdVar += "_CREATE_SHARED_LIBRARY";
- break;
- case cmTarget::MODULE_LIBRARY:
- linkCmdVar += "_CREATE_SHARED_MODULE";
- break;
- case cmTarget::EXECUTABLE:
- linkCmdVar += "_LINK_EXECUTABLE";
- break;
- default:
- assert(0 && "Unexpected target type");
- }
-
- const char *linkCmd =
- this->GetMakefile()->GetRequiredDefinition(linkCmdVar.c_str());
- cmSystemTools::ExpandListArgument(linkCmd, linkCmds);
- return linkCmds;
- }
+ case cmState::SHARED_LIBRARY:
+ case cmState::MODULE_LIBRARY:
+ case cmState::EXECUTABLE:
+ break;
default:
assert(0 && "Unexpected target type");
}
return std::vector<std::string>();
}
-void cmNinjaNormalTargetGenerator::WriteLinkStatement()
+
+static int calculateCommandLineLengthLimit(int linkRuleLength)
{
- cmTarget::TargetType targetType = this->GetTarget()->GetType();
+ static int const limits[] = {
+#ifdef _WIN32
+ 8000,
+#endif
+#if defined(__APPLE__) || defined(__HAIKU__) || defined(__linux)
+ // for instance ARG_MAX is 2096152 on Ubuntu or 262144 on Mac
+ ((int)sysconf(_SC_ARG_MAX)) - 1000,
+#endif
+#if defined(__linux)
+ // #define MAX_ARG_STRLEN (PAGE_SIZE * 32) in Linux's binfmts.h
+ ((int)sysconf(_SC_PAGESIZE) * 32) - 1000,
+#endif
+ std::numeric_limits<int>::max()
+ };
+ size_t const arrSz = cmArraySize(limits);
+ int const sz = *std::min_element(limits, limits + arrSz);
+ if (sz == std::numeric_limits<int>::max())
+ {
+ return -1;
+ }
+
+ return sz - linkRuleLength;
+}
+
+
+void cmNinjaNormalTargetGenerator::WriteLinkStatement()
+{
+ cmGeneratorTarget& gt = *this->GetGeneratorTarget();
+ const std::string cfgName = this->GetConfigName();
std::string targetOutput = ConvertToNinjaPath(
- this->GetTarget()->GetFullPath(this->GetConfigName()).c_str());
+ gt.GetFullPath(cfgName));
std::string targetOutputReal = ConvertToNinjaPath(
- this->GetTarget()->GetFullPath(this->GetConfigName(),
- /*implib=*/false,
- /*realpath=*/true).c_str());
+ gt.GetFullPath(cfgName,
+ /*implib=*/false,
+ /*realpath=*/true));
std::string targetOutputImplib = ConvertToNinjaPath(
- this->GetTarget()->GetFullPath(this->GetConfigName(),
- /*implib=*/true).c_str());
+ gt.GetFullPath(cfgName,
+ /*implib=*/true));
- if (this->GetTarget()->IsAppBundleOnApple())
+ if (gt.IsAppBundleOnApple())
{
// Create the app bundle
- std::string outpath =
- this->GetTarget()->GetDirectory(this->GetConfigName());
+ std::string outpath = gt.GetDirectory(cfgName);
this->OSXBundleGenerator->CreateAppBundle(this->TargetNameOut, outpath);
// Calculate the output path
targetOutput = outpath;
targetOutput += "/";
targetOutput += this->TargetNameOut;
- targetOutput = this->ConvertToNinjaPath(targetOutput.c_str());
+ targetOutput = this->ConvertToNinjaPath(targetOutput);
targetOutputReal = outpath;
targetOutputReal += "/";
targetOutputReal += this->TargetNameReal;
- targetOutputReal = this->ConvertToNinjaPath(targetOutputReal.c_str());
+ targetOutputReal = this->ConvertToNinjaPath(targetOutputReal);
}
- else if (this->GetTarget()->IsFrameworkOnApple())
+ else if (gt.IsFrameworkOnApple())
{
// Create the library framework.
- std::string outpath =
- this->GetTarget()->GetDirectory(this->GetConfigName());
- this->OSXBundleGenerator->CreateFramework(this->TargetNameOut, outpath);
+ this->OSXBundleGenerator->CreateFramework(this->TargetNameOut,
+ gt.GetDirectory(cfgName));
}
- else if(this->GetTarget()->IsCFBundleOnApple())
+ else if(gt.IsCFBundleOnApple())
{
// Create the core foundation bundle.
- std::string outpath =
- this->GetTarget()->GetDirectory(this->GetConfigName());
- this->OSXBundleGenerator->CreateCFBundle(this->TargetNameOut, outpath);
+ this->OSXBundleGenerator->CreateCFBundle(this->TargetNameOut,
+ gt.GetDirectory(cfgName));
}
// Write comments.
cmGlobalNinjaGenerator::WriteDivider(this->GetBuildFileStream());
+ const cmState::TargetType targetType = gt.GetType();
this->GetBuildFileStream()
<< "# Link build statements for "
- << cmTarget::GetTargetTypeName(targetType)
+ << cmState::GetTargetTypeName(targetType)
<< " target "
<< this->GetTargetName()
<< "\n\n";
@@ -424,9 +454,9 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
cmNinjaVars vars;
// Compute the comment.
- cmOStringStream comment;
- comment << "Link the " << this->GetVisibleTypeName() << " "
- << targetOutputReal;
+ std::ostringstream comment;
+ comment <<
+ "Link the " << this->GetVisibleTypeName() << " " << targetOutputReal;
// Compute outputs.
cmNinjaDeps outputs;
@@ -436,62 +466,105 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
cmNinjaDeps explicitDeps = this->GetObjects();
cmNinjaDeps implicitDeps = this->ComputeLinkDeps();
+ cmMakefile* mf = this->GetMakefile();
+
std::string frameworkPath;
std::string linkPath;
- this->GetLocalGenerator()->GetTargetFlags(vars["LINK_LIBRARIES"],
- vars["FLAGS"],
- vars["LINK_FLAGS"],
- frameworkPath,
- linkPath,
- this->GetGeneratorTarget());
+ cmGeneratorTarget& genTarget = *this->GetGeneratorTarget();
+
+ std::string createRule =
+ genTarget.GetCreateRuleVariable(this->TargetLinkLanguage,
+ this->GetConfigName());
+ bool useWatcomQuote = mf->IsOn(createRule+"_USE_WATCOM_QUOTE");
+ cmLocalNinjaGenerator& localGen = *this->GetLocalGenerator();
+
+ vars["TARGET_FILE"] =
+ localGen.ConvertToOutputFormat(targetOutputReal, cmLocalGenerator::SHELL);
+
+ localGen.GetTargetFlags(vars["LINK_LIBRARIES"],
+ vars["FLAGS"],
+ vars["LINK_FLAGS"],
+ frameworkPath,
+ linkPath,
+ &genTarget,
+ useWatcomQuote);
+ if(this->GetMakefile()->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")
+ && gt.GetType() == cmState::SHARED_LIBRARY)
+ {
+ if(gt.GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+ {
+ std::string name_of_def_file
+ = gt.GetSupportDirectory();
+ name_of_def_file += "/" + gt.GetName();
+ name_of_def_file += ".def ";
+ vars["LINK_FLAGS"] += " /DEF:";
+ vars["LINK_FLAGS"] += this->GetLocalGenerator()
+ ->ConvertToOutputFormat(name_of_def_file.c_str(),
+ cmLocalGenerator::SHELL);
+ }
+ }
+
+ this->addPoolNinjaVariable("JOB_POOL_LINK", &gt, vars);
this->AddModuleDefinitionFlag(vars["LINK_FLAGS"]);
vars["LINK_FLAGS"] = cmGlobalNinjaGenerator
::EncodeLiteral(vars["LINK_FLAGS"]);
+ vars["MANIFESTS"] = this->GetManifests();
+
vars["LINK_PATH"] = frameworkPath + linkPath;
// Compute architecture specific link flags. Yes, these go into a different
// variable for executables, probably due to a mistake made when duplicating
// code between the Makefile executable and library generators.
- std::string flags = (targetType == cmTarget::EXECUTABLE
- ? vars["FLAGS"]
- : vars["ARCH_FLAGS"]);
- this->GetLocalGenerator()->AddArchitectureFlags(flags,
- this->GetGeneratorTarget(),
- this->TargetLinkLanguage,
- this->GetConfigName());
- if (targetType == cmTarget::EXECUTABLE) {
- vars["FLAGS"] = flags;
- } else {
- vars["ARCH_FLAGS"] = flags;
- }
- if (this->GetTarget()->HasSOName(this->GetConfigName())) {
- vars["SONAME_FLAG"] =
- this->GetMakefile()->GetSONameFlag(this->TargetLinkLanguage);
+ if (targetType == cmState::EXECUTABLE)
+ {
+ std::string t = vars["FLAGS"];
+ localGen.AddArchitectureFlags(t, &genTarget, TargetLinkLanguage, cfgName);
+ vars["FLAGS"] = t;
+ }
+ else
+ {
+ std::string t = vars["ARCH_FLAGS"];
+ localGen.AddArchitectureFlags(t, &genTarget, TargetLinkLanguage, cfgName);
+ vars["ARCH_FLAGS"] = t;
+ t = "";
+ localGen.AddLanguageFlags(t, TargetLinkLanguage, cfgName);
+ vars["LANGUAGE_COMPILE_FLAGS"] = t;
+ }
+
+ if (this->GetGeneratorTarget()->HasSOName(cfgName))
+ {
+ vars["SONAME_FLAG"] = mf->GetSONameFlag(this->TargetLinkLanguage);
vars["SONAME"] = this->TargetNameSO;
- if (targetType == cmTarget::SHARED_LIBRARY) {
- std::string install_name_dir = this->GetTarget()
- ->GetInstallNameDirForBuildTree(this->GetConfigName());
-
- if (!install_name_dir.empty()) {
- vars["INSTALLNAME_DIR"] =
- this->GetLocalGenerator()->Convert(install_name_dir.c_str(),
- cmLocalGenerator::NONE,
- cmLocalGenerator::SHELL, false);
+ if (targetType == cmState::SHARED_LIBRARY)
+ {
+ std::string install_dir =
+ this->GetGeneratorTarget()->GetInstallNameDirForBuildTree(cfgName);
+ if (!install_dir.empty())
+ {
+ vars["INSTALLNAME_DIR"] = localGen.Convert(install_dir,
+ cmLocalGenerator::NONE,
+ cmLocalGenerator::SHELL);
+ }
}
}
- }
- if (!this->TargetNameImport.empty()) {
- const std::string impLibPath = this->GetLocalGenerator()
- ->ConvertToOutputFormat(targetOutputImplib.c_str(),
- cmLocalGenerator::SHELL);
+ cmNinjaDeps byproducts;
+
+ if (!this->TargetNameImport.empty())
+ {
+ const std::string impLibPath = localGen.ConvertToOutputFormat(
+ targetOutputImplib,
+ cmLocalGenerator::SHELL);
vars["TARGET_IMPLIB"] = impLibPath;
EnsureParentDirectoryExists(impLibPath);
- }
+ if(genTarget.HasImportLibrary())
+ {
+ byproducts.push_back(targetOutputImplib);
+ }
+ }
- cmMakefile* mf = this->GetMakefile();
if (!this->SetMsvcTargetPdbVariable(vars))
{
// It is common to place debug symbols at a specific place,
@@ -499,28 +572,35 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
std::string prefix;
std::string base;
std::string suffix;
- this->GetTarget()->GetFullNameComponents(prefix, base, suffix);
+ this->GetGeneratorTarget()->GetFullNameComponents(prefix, base, suffix);
std::string dbg_suffix = ".dbg";
// TODO: Where to document?
if (mf->GetDefinition("CMAKE_DEBUG_SYMBOL_SUFFIX"))
+ {
dbg_suffix = mf->GetDefinition("CMAKE_DEBUG_SYMBOL_SUFFIX");
+ }
vars["TARGET_PDB"] = base + suffix + dbg_suffix;
}
- if (mf->IsOn("CMAKE_COMPILER_IS_MINGW"))
+ const std::string objPath = GetGeneratorTarget()->GetSupportDirectory();
+ vars["OBJECT_DIR"] =
+ this->GetLocalGenerator()->ConvertToOutputFormat(
+ this->ConvertToNinjaPath(objPath), cmLocalGenerator::SHELL);
+ EnsureDirectoryExists(objPath);
+
+ if (this->GetGlobalGenerator()->IsGCCOnWindows())
{
- const std::string objPath = GetTarget()->GetSupportDirectory();
- vars["OBJECT_DIR"] = ConvertToNinjaPath(objPath.c_str());
- EnsureDirectoryExists(objPath);
// ar.exe can't handle backslashes in rsp files (implicitly used by gcc)
std::string& linkLibraries = vars["LINK_LIBRARIES"];
std::replace(linkLibraries.begin(), linkLibraries.end(), '\\', '/');
+ std::string& link_path = vars["LINK_PATH"];
+ std::replace(link_path.begin(), link_path.end(), '\\', '/');
}
- std::vector<cmCustomCommand> *cmdLists[3] = {
- &this->GetTarget()->GetPreBuildCommands(),
- &this->GetTarget()->GetPreLinkCommands(),
- &this->GetTarget()->GetPostBuildCommands()
+ const std::vector<cmCustomCommand> *cmdLists[3] = {
+ &gt.GetPreBuildCommands(),
+ &gt.GetPreLinkCommands(),
+ &gt.GetPostBuildCommands()
};
std::vector<std::string> preLinkCmdLines, postBuildCmdLines;
@@ -530,99 +610,156 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
&postBuildCmdLines
};
- for (unsigned i = 0; i != 3; ++i) {
+ for (unsigned i = 0; i != 3; ++i)
+ {
for (std::vector<cmCustomCommand>::const_iterator
ci = cmdLists[i]->begin();
- ci != cmdLists[i]->end(); ++ci) {
- this->GetLocalGenerator()->AppendCustomCommandLines(&*ci,
- *cmdLineLists[i]);
+ ci != cmdLists[i]->end(); ++ci)
+ {
+ cmCustomCommandGenerator ccg(*ci, cfgName, this->GetLocalGenerator());
+ localGen.AppendCustomCommandLines(ccg, *cmdLineLists[i]);
+ std::vector<std::string> const& ccByproducts = ccg.GetByproducts();
+ std::transform(ccByproducts.begin(), ccByproducts.end(),
+ std::back_inserter(byproducts), MapToNinjaPath());
+ }
}
- }
+ // maybe create .def file from list of objects
+ if (gt.GetType() == cmState::SHARED_LIBRARY &&
+ this->GetMakefile()->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+ {
+ if(gt.GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+ {
+ std::string cmakeCommand =
+ this->GetLocalGenerator()->ConvertToOutputFormat(
+ cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
+ std::string name_of_def_file
+ = gt.GetSupportDirectory();
+ name_of_def_file += "/" + gt.GetName();
+ name_of_def_file += ".def";
+ std::string cmd = cmakeCommand;
+ cmd += " -E __create_def ";
+ cmd += this->GetLocalGenerator()
+ ->ConvertToOutputFormat(name_of_def_file.c_str(),
+ cmLocalGenerator::SHELL);
+ cmd += " ";
+ cmNinjaDeps objs = this->GetObjects();
+ std::string obj_list_file = name_of_def_file;
+ obj_list_file += ".objs";
+ cmd += this->GetLocalGenerator()
+ ->ConvertToOutputFormat(obj_list_file.c_str(),
+ cmLocalGenerator::SHELL);
+ preLinkCmdLines.push_back(cmd);
+ // create a list of obj files for the -E __create_def to read
+ cmGeneratedFileStream fout(obj_list_file.c_str());
+ for(cmNinjaDeps::iterator i=objs.begin(); i != objs.end(); ++i)
+ {
+ if(cmHasLiteralSuffix(*i, ".obj"))
+ {
+ fout << *i << "\n";
+ }
+ }
+ }
+ }
// If we have any PRE_LINK commands, we need to go back to HOME_OUTPUT for
// the link commands.
- if (!preLinkCmdLines.empty()) {
- const std::string homeOutDir = this->GetLocalGenerator()
- ->ConvertToOutputFormat(this->GetMakefile()->GetHomeOutputDirectory(),
- cmLocalGenerator::SHELL);
+ if (!preLinkCmdLines.empty())
+ {
+ const std::string homeOutDir = localGen.ConvertToOutputFormat(
+ localGen.GetBinaryDirectory(),
+ cmLocalGenerator::SHELL);
preLinkCmdLines.push_back("cd " + homeOutDir);
- }
+ }
- vars["PRE_LINK"] =
- this->GetLocalGenerator()->BuildCommandLine(preLinkCmdLines);
- std::string postBuildCmdLine =
- this->GetLocalGenerator()->BuildCommandLine(postBuildCmdLines);
+ vars["PRE_LINK"] = localGen.BuildCommandLine(preLinkCmdLines);
+ std::string postBuildCmdLine = localGen.BuildCommandLine(postBuildCmdLines);
cmNinjaVars symlinkVars;
- if (targetOutput == targetOutputReal) {
+ if (targetOutput == targetOutputReal)
+ {
vars["POST_BUILD"] = postBuildCmdLine;
- } else {
+ }
+ else
+ {
vars["POST_BUILD"] = ":";
symlinkVars["POST_BUILD"] = postBuildCmdLine;
- }
+ }
- int linkRuleLength = this->GetGlobalGenerator()->
- GetRuleCmdLength(this->LanguageLinkerRule());
+ cmGlobalNinjaGenerator& globalGen = *this->GetGlobalGenerator();
int commandLineLengthLimit = 1;
const char* forceRspFile = "CMAKE_NINJA_FORCE_RESPONSE_FILE";
- if (!this->GetMakefile()->IsDefinitionSet(forceRspFile) &&
- cmSystemTools::GetEnv(forceRspFile) == 0) {
-#ifdef _WIN32
- commandLineLengthLimit = 8000 - linkRuleLength;
-#elif defined(__linux) || defined(__APPLE__)
- // for instance ARG_MAX is 2096152 on Ubuntu or 262144 on Mac
- commandLineLengthLimit = ((int)sysconf(_SC_ARG_MAX))-linkRuleLength-1000;
-#else
- (void)linkRuleLength;
- commandLineLengthLimit = -1;
-#endif
- }
+ if (!mf->IsDefinitionSet(forceRspFile) &&
+ cmSystemTools::GetEnv(forceRspFile) == 0)
+ {
+ commandLineLengthLimit = calculateCommandLineLengthLimit(
+ globalGen.GetRuleCmdLength(this->LanguageLinkerRule()));
+ }
- //Get the global generator as we are going to be call WriteBuild numerous
- //times in the following section
- cmGlobalNinjaGenerator* globalGenerator = this->GetGlobalGenerator();
+ const std::string rspfile =
+ std::string(cmake::GetCMakeFilesDirectoryPostSlash())
+ + gt.GetName() + ".rsp";
+ // Gather order-only dependencies.
+ cmNinjaDeps orderOnlyDeps;
+ this->GetLocalGenerator()->AppendTargetDepends(this->GetGeneratorTarget(),
+ orderOnlyDeps);
- const std::string rspfile = std::string
- (cmake::GetCMakeFilesDirectoryPostSlash()) +
- this->GetTarget()->GetName() + ".rsp";
+ // Ninja should restat after linking if and only if there are byproducts.
+ vars["RESTAT"] = byproducts.empty()? "" : "1";
+
+ for (cmNinjaDeps::const_iterator oi = byproducts.begin(),
+ oe = byproducts.end();
+ oi != oe; ++oi)
+ {
+ this->GetGlobalGenerator()->SeenCustomCommandOutput(*oi);
+ outputs.push_back(*oi);
+ }
// Write the build statement for this target.
- globalGenerator->WriteBuild(this->GetBuildFileStream(),
- comment.str(),
- this->LanguageLinkerRule(),
- outputs,
- explicitDeps,
- implicitDeps,
- emptyDeps,
- vars,
- rspfile,
- commandLineLengthLimit);
-
- if (targetOutput != targetOutputReal &&
- !this->GetTarget()->IsFrameworkOnApple()) {
- if (targetType == cmTarget::EXECUTABLE) {
- globalGenerator->WriteBuild(this->GetBuildFileStream(),
- "Create executable symlink " + targetOutput,
- "CMAKE_SYMLINK_EXECUTABLE",
- cmNinjaDeps(1, targetOutput),
- cmNinjaDeps(1, targetOutputReal),
- emptyDeps,
- emptyDeps,
- symlinkVars);
- } else {
+ bool usedResponseFile = false;
+ globalGen.WriteBuild(this->GetBuildFileStream(),
+ comment.str(),
+ this->LanguageLinkerRule(),
+ outputs,
+ explicitDeps,
+ implicitDeps,
+ orderOnlyDeps,
+ vars,
+ rspfile,
+ commandLineLengthLimit,
+ &usedResponseFile);
+ this->WriteLinkRule(usedResponseFile);
+
+ if (targetOutput != targetOutputReal && !gt.IsFrameworkOnApple())
+ {
+ if (targetType == cmState::EXECUTABLE)
+ {
+ globalGen.WriteBuild(this->GetBuildFileStream(),
+ "Create executable symlink " + targetOutput,
+ "CMAKE_SYMLINK_EXECUTABLE",
+ cmNinjaDeps(1, targetOutput),
+ cmNinjaDeps(1, targetOutputReal),
+ emptyDeps,
+ emptyDeps,
+ symlinkVars);
+ }
+ else
+ {
cmNinjaDeps symlinks;
const std::string soName = this->GetTargetFilePath(this->TargetNameSO);
// If one link has to be created.
- if (targetOutputReal == soName || targetOutput == soName) {
+ if (targetOutputReal == soName || targetOutput == soName)
+ {
symlinkVars["SONAME"] = soName;
- } else {
+ }
+ else
+ {
symlinkVars["SONAME"] = "";
symlinks.push_back(soName);
- }
+ }
symlinks.push_back(targetOutput);
- globalGenerator->WriteBuild(this->GetBuildFileStream(),
+ globalGen.WriteBuild(this->GetBuildFileStream(),
"Create library symlink " + targetOutput,
"CMAKE_SYMLINK_LIBRARY",
symlinks,
@@ -630,23 +767,12 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
emptyDeps,
emptyDeps,
symlinkVars);
+ }
}
- }
-
- if (!this->TargetNameImport.empty()) {
- // Since using multiple outputs would mess up the $out variable, use an
- // alias for the import library.
- globalGenerator->WritePhonyBuild(this->GetBuildFileStream(),
- "Alias for import library.",
- cmNinjaDeps(1, targetOutputImplib),
- cmNinjaDeps(1, targetOutputReal));
- }
// Add aliases for the file name and the target name.
- globalGenerator->AddTargetAlias(this->TargetNameOut,
- this->GetTarget());
- globalGenerator->AddTargetAlias(this->GetTargetName(),
- this->GetTarget());
+ globalGen.AddTargetAlias(this->TargetNameOut, &gt);
+ globalGen.AddTargetAlias(this->GetTargetName(), &gt);
}
//----------------------------------------------------------------------------
@@ -654,7 +780,8 @@ void cmNinjaNormalTargetGenerator::WriteObjectLibStatement()
{
// Write a phony output that depends on all object files.
cmNinjaDeps outputs;
- this->GetLocalGenerator()->AppendTargetOutputs(this->GetTarget(), outputs);
+ this->GetLocalGenerator()->AppendTargetOutputs(this->GetGeneratorTarget(),
+ outputs);
cmNinjaDeps depends = this->GetObjects();
this->GetGlobalGenerator()->WritePhonyBuild(this->GetBuildFileStream(),
"Object library "
@@ -664,5 +791,5 @@ void cmNinjaNormalTargetGenerator::WriteObjectLibStatement()
// Add aliases for the target name.
this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(),
- this->GetTarget());
+ this->GetGeneratorTarget());
}
diff --git a/Source/cmNinjaNormalTargetGenerator.h b/Source/cmNinjaNormalTargetGenerator.h
index 284804b08..556ed5e13 100644
--- a/Source/cmNinjaNormalTargetGenerator.h
+++ b/Source/cmNinjaNormalTargetGenerator.h
@@ -21,11 +21,12 @@
class cmSourceFile;
class cmOSXBundleGenerator;
+class cmGeneratorTarget;
class cmNinjaNormalTargetGenerator : public cmNinjaTargetGenerator
{
public:
- cmNinjaNormalTargetGenerator(cmTarget* target);
+ cmNinjaNormalTargetGenerator(cmGeneratorTarget* target);
~cmNinjaNormalTargetGenerator();
void Generate();
@@ -46,7 +47,7 @@ private:
std::string TargetNameReal;
std::string TargetNameImport;
std::string TargetNamePDB;
- const char *TargetLinkLanguage;
+ std::string TargetLinkLanguage;
};
#endif // ! cmNinjaNormalTargetGenerator_h
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 9c8b4810b..5ff4fdb38 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -22,30 +22,31 @@
#include "cmComputeLinkInformation.h"
#include "cmSourceFile.h"
#include "cmCustomCommandGenerator.h"
+#include "cmAlgorithms.h"
#include <algorithm>
cmNinjaTargetGenerator *
-cmNinjaTargetGenerator::New(cmTarget* target)
+cmNinjaTargetGenerator::New(cmGeneratorTarget* target)
{
switch (target->GetType())
{
- case cmTarget::EXECUTABLE:
- case cmTarget::SHARED_LIBRARY:
- case cmTarget::STATIC_LIBRARY:
- case cmTarget::MODULE_LIBRARY:
- case cmTarget::OBJECT_LIBRARY:
+ case cmState::EXECUTABLE:
+ case cmState::SHARED_LIBRARY:
+ case cmState::STATIC_LIBRARY:
+ case cmState::MODULE_LIBRARY:
+ case cmState::OBJECT_LIBRARY:
return new cmNinjaNormalTargetGenerator(target);
- case cmTarget::UTILITY:
+ case cmState::UTILITY:
return new cmNinjaUtilityTargetGenerator(target);;
- case cmTarget::GLOBAL_TARGET: {
+ case cmState::GLOBAL_TARGET: {
// We only want to process global targets that live in the home
// (i.e. top-level) directory. CMake creates copies of these targets
// in every directory, which we don't need.
- cmMakefile *mf = target->GetMakefile();
- if (strcmp(mf->GetStartDirectory(), mf->GetHomeDirectory()) == 0)
+ if (strcmp(target->GetLocalGenerator()->GetCurrentSourceDirectory(),
+ target->GetLocalGenerator()->GetSourceDirectory()) == 0)
return new cmNinjaUtilityTargetGenerator(target);
// else fallthrough
}
@@ -55,19 +56,15 @@ cmNinjaTargetGenerator::New(cmTarget* target)
}
}
-cmNinjaTargetGenerator::cmNinjaTargetGenerator(cmTarget* target)
- :
+cmNinjaTargetGenerator::cmNinjaTargetGenerator(cmGeneratorTarget* target)
+ : cmCommonTargetGenerator(cmOutputConverter::HOME_OUTPUT, target),
MacOSXContentGenerator(0),
OSXBundleGenerator(0),
MacContentFolders(),
- Target(target),
- Makefile(target->GetMakefile()),
LocalGenerator(
- static_cast<cmLocalNinjaGenerator*>(Makefile->GetLocalGenerator())),
+ static_cast<cmLocalNinjaGenerator*>(target->GetLocalGenerator())),
Objects()
{
- this->GeneratorTarget =
- this->GetGlobalGenerator()->GetGeneratorTarget(target);
MacOSXContentGenerator = new MacOSXContentGeneratorType(this);
}
@@ -91,34 +88,17 @@ cmGlobalNinjaGenerator* cmNinjaTargetGenerator::GetGlobalGenerator() const
return this->LocalGenerator->GetGlobalNinjaGenerator();
}
-const char* cmNinjaTargetGenerator::GetConfigName() const
+std::string cmNinjaTargetGenerator::LanguageCompilerRule(
+ const std::string& lang) const
{
- return this->LocalGenerator->GetConfigName();
+ return lang + "_COMPILER__" +
+ cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName());
}
-// TODO: Picked up from cmMakefileTargetGenerator. Refactor it.
-const char* cmNinjaTargetGenerator::GetFeature(const char* feature)
-{
- return this->Target->GetFeature(feature, this->GetConfigName());
-}
-
-// TODO: Picked up from cmMakefileTargetGenerator. Refactor it.
-bool cmNinjaTargetGenerator::GetFeatureAsBool(const char* feature)
-{
- return cmSystemTools::IsOn(this->GetFeature(feature));
-}
-
-// TODO: Picked up from cmMakefileTargetGenerator. Refactor it.
-void cmNinjaTargetGenerator::AddFeatureFlags(std::string& flags,
- const char* lang)
+std::string
+cmNinjaTargetGenerator::OrderDependsTargetForTarget()
{
- // Add language-specific flags.
- this->LocalGenerator->AddLanguageFlags(flags, lang, this->GetConfigName());
-
- if(this->GetFeatureAsBool("INTERPROCEDURAL_OPTIMIZATION"))
- {
- this->LocalGenerator->AppendFeatureOptions(flags, lang, "IPO");
- }
+ return "cmake_order_depends_target_" + this->GetTargetName();
}
// TODO: Most of the code is picked up from
@@ -126,84 +106,60 @@ void cmNinjaTargetGenerator::AddFeatureFlags(std::string& flags,
// void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
// Refactor it.
std::string
-cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source,
+cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile const* source,
const std::string& language)
{
- std::string flags;
+ std::string flags = this->GetFlags(language);
- this->AddFeatureFlags(flags, language.c_str());
-
- this->GetLocalGenerator()->AddArchitectureFlags(flags,
- this->GeneratorTarget,
- language.c_str(),
- this->GetConfigName());
-
- // TODO: Fortran support.
- // // Fortran-specific flags computed for this target.
- // if(*l == "Fortran")
- // {
- // this->AddFortranFlags(flags);
- // }
+ // Add Fortran format flags.
+ if(language == "Fortran")
+ {
+ this->AppendFortranFormatFlags(flags, *source);
+ }
- // Add shared-library flags if needed.
- this->LocalGenerator->AddCMP0018Flags(flags, this->Target,
- language.c_str(),
- this->GetConfigName());
+ // Add source file specific flags.
+ this->LocalGenerator->AppendFlags(flags,
+ source->GetProperty("COMPILE_FLAGS"));
- this->LocalGenerator->AddVisibilityPresetFlags(flags, this->Target,
- language.c_str());
+ return flags;
+}
- // Add include directory flags.
- const char *config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE");
- {
+void cmNinjaTargetGenerator::AddIncludeFlags(std::string& languageFlags,
+ std::string const& language)
+{
std::vector<std::string> includes;
this->LocalGenerator->GetIncludeDirectories(includes,
this->GeneratorTarget,
- language.c_str(), config);
+ language,
+ this->GetConfigName());
+ // Add include directory flags.
std::string includeFlags =
this->LocalGenerator->GetIncludeFlags(includes, this->GeneratorTarget,
- language.c_str(),
- language == "RC" ? true : false); // full include paths for RC
- // needed by cmcldeps
- if(cmGlobalNinjaGenerator::IsMinGW())
+ language,
+ language == "RC" ? true : false, // full include paths for RC
+ // needed by cmcldeps
+ false,
+ this->GetConfigName());
+ if (this->GetGlobalGenerator()->IsGCCOnWindows())
cmSystemTools::ReplaceString(includeFlags, "\\", "/");
- this->LocalGenerator->AppendFlags(flags, includeFlags.c_str());
- }
-
- // Append old-style preprocessor definition flags.
- this->LocalGenerator->AppendFlags(flags, this->Makefile->GetDefineFlags());
-
- // Add target-specific flags.
- this->LocalGenerator->AddCompileOptions(flags, this->Target,
- language.c_str(), config);
-
- // Add source file specific flags.
- this->LocalGenerator->AppendFlags(flags,
- source->GetProperty("COMPILE_FLAGS"));
-
- // TODO: Handle Apple frameworks.
+ this->LocalGenerator->AppendFlags(languageFlags, includeFlags);
+}
- return flags;
+bool cmNinjaTargetGenerator::NeedDepTypeMSVC(const std::string& lang) const
+{
+ return strcmp(
+ this->GetMakefile()->GetSafeDefinition("CMAKE_NINJA_DEPTYPE_" + lang),
+ "msvc") == 0;
}
// TODO: Refactor with
// void cmMakefileTargetGenerator::WriteTargetLanguageFlags().
std::string
cmNinjaTargetGenerator::
-ComputeDefines(cmSourceFile *source, const std::string& language)
+ComputeDefines(cmSourceFile const* source, const std::string& language)
{
std::set<std::string> defines;
-
- // Add the export symbol definition for shared library objects.
- if(const char* exportMacro = this->Target->GetExportMacro())
- {
- this->LocalGenerator->AppendDefines(defines, exportMacro);
- }
-
- // Add preprocessor definitions for this target and configuration.
- this->LocalGenerator->AddCompileDefinitions(defines, this->Target,
- this->GetConfigName());
this->LocalGenerator->AppendDefines
(defines,
source->GetProperty("COMPILE_DEFINITIONS"));
@@ -212,12 +168,12 @@ ComputeDefines(cmSourceFile *source, const std::string& language)
defPropName += cmSystemTools::UpperCase(this->GetConfigName());
this->LocalGenerator->AppendDefines
(defines,
- source->GetProperty(defPropName.c_str()));
+ source->GetProperty(defPropName));
}
- std::string definesString;
+ std::string definesString = this->GetDefines(language);
this->LocalGenerator->JoinDefines(defines, definesString,
- language.c_str());
+ language);
return definesString;
}
@@ -225,12 +181,12 @@ ComputeDefines(cmSourceFile *source, const std::string& language)
cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const
{
// Static libraries never depend on other targets for linking.
- if (this->Target->GetType() == cmTarget::STATIC_LIBRARY ||
- this->Target->GetType() == cmTarget::OBJECT_LIBRARY)
+ if (this->GeneratorTarget->GetType() == cmState::STATIC_LIBRARY ||
+ this->GeneratorTarget->GetType() == cmState::OBJECT_LIBRARY)
return cmNinjaDeps();
cmComputeLinkInformation* cli =
- this->Target->GetLinkInformation(this->GetConfigName());
+ this->GeneratorTarget->GetLinkInformation(this->GetConfigName());
if(!cli)
return cmNinjaDeps();
@@ -239,9 +195,29 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const
std::transform(deps.begin(), deps.end(), result.begin(), MapToNinjaPath());
// Add a dependency on the link definitions file, if any.
- if(!this->ModuleDefinitionFile.empty())
+ if(this->ModuleDefinitionFile)
{
- result.push_back(this->ModuleDefinitionFile);
+ result.push_back(this->ConvertToNinjaPath(
+ this->ModuleDefinitionFile->GetFullPath()));
+ }
+
+ // Add a dependency on user-specified manifest files, if any.
+ std::vector<cmSourceFile const*> manifest_srcs;
+ this->GeneratorTarget->GetManifests(manifest_srcs, this->ConfigName);
+ for (std::vector<cmSourceFile const*>::iterator mi = manifest_srcs.begin();
+ mi != manifest_srcs.end(); ++mi)
+ {
+ result.push_back(this->ConvertToNinjaPath((*mi)->GetFullPath()));
+ }
+
+ // Add user-specified dependencies.
+ if (const char* linkDepends =
+ this->GeneratorTarget->GetProperty("LINK_DEPENDS"))
+ {
+ std::vector<std::string> linkDeps;
+ cmSystemTools::ExpandListArgument(linkDepends, linkDeps);
+ std::transform(linkDeps.begin(), linkDeps.end(),
+ std::back_inserter(result), MapToNinjaPath());
}
return result;
@@ -249,20 +225,21 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const
std::string
cmNinjaTargetGenerator
-::GetSourceFilePath(cmSourceFile* source) const
+::GetSourceFilePath(cmSourceFile const* source) const
{
- return ConvertToNinjaPath(source->GetFullPath().c_str());
+ return ConvertToNinjaPath(source->GetFullPath());
}
std::string
cmNinjaTargetGenerator
-::GetObjectFilePath(cmSourceFile* source) const
+::GetObjectFilePath(cmSourceFile const* source) const
{
std::string path = this->LocalGenerator->GetHomeRelativeOutputPath();
if(!path.empty())
path += "/";
- std::string const& objectName = this->GeneratorTarget->Objects[source];
- path += this->LocalGenerator->GetTargetDirectory(*this->Target);
+ std::string const& objectName = this->GeneratorTarget
+ ->GetObjectName(source);
+ path += this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
path += "/";
path += objectName;
return path;
@@ -270,8 +247,8 @@ cmNinjaTargetGenerator
std::string cmNinjaTargetGenerator::GetTargetOutputDir() const
{
- std::string dir = this->Target->GetDirectory(this->GetConfigName());
- return ConvertToNinjaPath(dir.c_str());
+ std::string dir = this->GeneratorTarget->GetDirectory(this->GetConfigName());
+ return ConvertToNinjaPath(dir);
}
std::string
@@ -288,7 +265,7 @@ cmNinjaTargetGenerator
std::string cmNinjaTargetGenerator::GetTargetName() const
{
- return this->Target->GetName();
+ return this->GeneratorTarget->GetName();
}
@@ -299,20 +276,36 @@ bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable(cmNinjaVars& vars) const
mf->GetDefinition("MSVC_CXX_ARCHITECTURE_ID"))
{
std::string pdbPath;
- if(this->Target->GetType() == cmTarget::EXECUTABLE ||
- this->Target->GetType() == cmTarget::STATIC_LIBRARY ||
- this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
- this->Target->GetType() == cmTarget::MODULE_LIBRARY)
+ std::string compilePdbPath;
+ if(this->GeneratorTarget->GetType() == cmState::EXECUTABLE ||
+ this->GeneratorTarget->GetType() == cmState::STATIC_LIBRARY ||
+ this->GeneratorTarget->GetType() == cmState::SHARED_LIBRARY ||
+ this->GeneratorTarget->GetType() == cmState::MODULE_LIBRARY)
{
- pdbPath = this->Target->GetPDBDirectory(this->GetConfigName());
+ pdbPath = this->GeneratorTarget->GetPDBDirectory(this->GetConfigName());
pdbPath += "/";
- pdbPath += this->Target->GetPDBName(this->GetConfigName());
+ pdbPath += this->GeneratorTarget->GetPDBName(this->GetConfigName());
+ }
+ if(this->GeneratorTarget->GetType() <= cmState::OBJECT_LIBRARY)
+ {
+ compilePdbPath =
+ this->GeneratorTarget->GetCompilePDBPath(this->GetConfigName());
+ if(compilePdbPath.empty())
+ {
+ compilePdbPath = this->GeneratorTarget->GetSupportDirectory() + "/";
+ }
}
vars["TARGET_PDB"] = this->GetLocalGenerator()->ConvertToOutputFormat(
- ConvertToNinjaPath(pdbPath.c_str()).c_str(),
+ ConvertToNinjaPath(pdbPath),
cmLocalGenerator::SHELL);
+ vars["TARGET_COMPILE_PDB"] =
+ this->GetLocalGenerator()->ConvertToOutputFormat(
+ ConvertToNinjaPath(compilePdbPath),
+ cmLocalGenerator::SHELL);
+
EnsureParentDirectoryExists(pdbPath);
+ EnsureParentDirectoryExists(compilePdbPath);
return true;
}
return false;
@@ -331,76 +324,121 @@ cmNinjaTargetGenerator
void
cmNinjaTargetGenerator
-::WriteCompileRule(const std::string& language)
+::WriteCompileRule(const std::string& lang)
{
cmLocalGenerator::RuleVariables vars;
vars.RuleLauncher = "RULE_LAUNCH_COMPILE";
- vars.CMTarget = this->GetTarget();
- std::string lang = language;
+ vars.CMTarget = this->GetGeneratorTarget();
vars.Language = lang.c_str();
vars.Source = "$in";
vars.Object = "$out";
- std::string flags = "$FLAGS";
vars.Defines = "$DEFINES";
+ vars.Includes = "$INCLUDES";
vars.TargetPDB = "$TARGET_PDB";
+ vars.TargetCompilePDB = "$TARGET_COMPILE_PDB";
vars.ObjectDir = "$OBJECT_DIR";
+ vars.ObjectFileDir = "$OBJECT_FILE_DIR";
cmMakefile* mf = this->GetMakefile();
- bool useClDeps = false;
- std::string clBinary;
- std::string clDepsBinary;
- std::string clShowPrefix;
- if (lang == "C" || lang == "CXX" || lang == "RC")
+ // Tell ninja dependency format so all deps can be loaded into a database
+ std::string deptype;
+ std::string depfile;
+ std::string cldeps;
+ std::string flags = "$FLAGS";
+ if (this->NeedDepTypeMSVC(lang))
{
- clDepsBinary = mf->GetSafeDefinition("CMAKE_CMCLDEPS_EXECUTABLE");
- if (!clDepsBinary.empty() && !mf->GetIsSourceFileTryCompile())
+ deptype = "msvc";
+ depfile = "";
+ flags += " /showIncludes";
+ }
+ else if (mf->IsOn("CMAKE_NINJA_CMCLDEPS_"+lang))
+ {
+ // For the MS resource compiler we need cmcldeps, but skip dependencies
+ // for source-file try_compile cases because they are always fresh.
+ if (!mf->GetIsSourceFileTryCompile())
{
- clShowPrefix = mf->GetSafeDefinition("CMAKE_CL_SHOWINCLUDE_PREFIX");
- clBinary = mf->GetDefinition("CMAKE_C_COMPILER") ?
- mf->GetSafeDefinition("CMAKE_C_COMPILER") :
- mf->GetSafeDefinition("CMAKE_CXX_COMPILER");
- if (!clBinary.empty() && !clShowPrefix.empty())
- {
- useClDeps = true;
- const std::string quote = " \"";
- clBinary = quote + clBinary + "\" ";
- clDepsBinary = quote + clDepsBinary + "\" ";
- clShowPrefix = quote + clShowPrefix + "\" ";
- vars.DependencyFile = "$DEP_FILE";
- }
+ deptype = "gcc";
+ depfile = "$DEP_FILE";
+ const std::string cl = mf->GetDefinition("CMAKE_C_COMPILER") ?
+ mf->GetSafeDefinition("CMAKE_C_COMPILER") :
+ mf->GetSafeDefinition("CMAKE_CXX_COMPILER");
+ cldeps = "\"";
+ cldeps += cmSystemTools::GetCMClDepsCommand();
+ cldeps += "\" " + lang + " $in \"$DEP_FILE\" $out \"";
+ cldeps += mf->GetSafeDefinition("CMAKE_CL_SHOWINCLUDES_PREFIX");
+ cldeps += "\" \"" + cl + "\" ";
}
}
-
-
- std::string depfile;
- std::string depfileFlagsName = "CMAKE_DEPFILE_FLAGS_" + language;
- const char *depfileFlags = mf->GetDefinition(depfileFlagsName.c_str());
- if (depfileFlags || useClDeps) {
- std::string depFlagsStr = depfileFlags ? depfileFlags : "";
+ else
+ {
+ deptype = "gcc";
+ const char* langdeptype = mf->GetDefinition("CMAKE_NINJA_DEPTYPE_" + lang);
+ if (langdeptype)
+ {
+ deptype = langdeptype;
+ }
depfile = "$DEP_FILE";
- cmSystemTools::ReplaceString(depFlagsStr, "<DEPFILE>", "\"$DEP_FILE\"");
- cmSystemTools::ReplaceString(depFlagsStr, "<OBJECT>", "$out");
- cmSystemTools::ReplaceString(depFlagsStr, "<CMAKE_C_COMPILER>",
- mf->GetDefinition("CMAKE_C_COMPILER"));
- flags += " " + depFlagsStr;
- }
- vars.Flags = flags.c_str();
+ const std::string flagsName = "CMAKE_DEPFILE_FLAGS_" + lang;
+ std::string depfileFlags = mf->GetSafeDefinition(flagsName);
+ if (!depfileFlags.empty())
+ {
+ cmSystemTools::ReplaceString(depfileFlags, "<DEPFILE>", "$DEP_FILE");
+ cmSystemTools::ReplaceString(depfileFlags, "<OBJECT>", "$out");
+ cmSystemTools::ReplaceString(depfileFlags, "<CMAKE_C_COMPILER>",
+ mf->GetDefinition("CMAKE_C_COMPILER"));
+ flags += " " + depfileFlags;
+ }
+ }
+ vars.Flags = flags.c_str();
+ vars.DependencyFile = depfile.c_str();
// Rule for compiling object file.
- std::string compileCmdVar = "CMAKE_";
- compileCmdVar += language;
- compileCmdVar += "_COMPILE_OBJECT";
- std::string compileCmd = mf->GetRequiredDefinition(compileCmdVar.c_str());
+ const std::string cmdVar = std::string("CMAKE_") + lang + "_COMPILE_OBJECT";
+ std::string compileCmd = mf->GetRequiredDefinition(cmdVar);
std::vector<std::string> compileCmds;
cmSystemTools::ExpandListArgument(compileCmd, compileCmds);
- if(useClDeps)
+ // Maybe insert an include-what-you-use runner.
+ if (!compileCmds.empty() && (lang == "C" || lang == "CXX"))
{
- std::string cmdPrefix = clDepsBinary + lang + " $in \"$DEP_FILE\" $out " +
- clShowPrefix + clBinary;
- compileCmds.front().insert(0, cmdPrefix);
+ std::string const iwyu_prop = lang + "_INCLUDE_WHAT_YOU_USE";
+ const char *iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
+ if (iwyu && *iwyu)
+ {
+ std::string run_iwyu =
+ this->GetLocalGenerator()->ConvertToOutputFormat(
+ cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
+ run_iwyu += " -E __run_iwyu --iwyu=";
+ run_iwyu += this->GetLocalGenerator()->EscapeForShell(iwyu);
+ run_iwyu += " -- ";
+ compileCmds.front().insert(0, run_iwyu);
+ }
+ }
+
+ // Maybe insert a compiler launcher like ccache or distcc
+ if (!compileCmds.empty() && (lang == "C" || lang == "CXX"))
+ {
+ std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER";
+ const char *clauncher = this->GeneratorTarget->GetProperty(clauncher_prop);
+ if (clauncher && *clauncher)
+ {
+ std::vector<std::string> launcher_cmd;
+ cmSystemTools::ExpandListArgument(clauncher, launcher_cmd, true);
+ for (std::vector<std::string>::iterator i = launcher_cmd.begin(),
+ e = launcher_cmd.end(); i != e; ++i)
+ {
+ *i = this->LocalGenerator->EscapeForShell(*i);
+ }
+ std::string const& run_launcher = cmJoin(launcher_cmd, " ") + " ";
+ compileCmds.front().insert(0, run_launcher);
+ }
+ }
+
+ if (!compileCmds.empty())
+ {
+ compileCmds.front().insert(0, cldeps);
}
for (std::vector<std::string>::iterator i = compileCmds.begin();
@@ -412,15 +450,20 @@ cmNinjaTargetGenerator
// Write the rule for compiling file of the given language.
- cmOStringStream comment;
- comment << "Rule for compiling " << language << " files.";
- cmOStringStream description;
- description << "Building " << language << " object $out";
- this->GetGlobalGenerator()->AddRule(this->LanguageCompilerRule(language),
+ std::ostringstream comment;
+ comment << "Rule for compiling " << lang << " files.";
+ std::ostringstream description;
+ description << "Building " << lang << " object $out";
+ this->GetGlobalGenerator()->AddRule(this->LanguageCompilerRule(lang),
cmdLine,
description.str(),
comment.str(),
- depfile);
+ depfile,
+ deptype,
+ /*rspfile*/ "",
+ /*rspcontent*/ "",
+ /*restat*/ "",
+ /*generator*/ false);
}
void
@@ -431,100 +474,147 @@ cmNinjaTargetGenerator
cmGlobalNinjaGenerator::WriteDivider(this->GetBuildFileStream());
this->GetBuildFileStream()
<< "# Object build statements for "
- << cmTarget::GetTargetTypeName(this->GetTarget()->GetType())
+ << cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType())
<< " target "
<< this->GetTargetName()
<< "\n\n";
- for(std::vector<cmSourceFile*>::const_iterator
- si = this->GeneratorTarget->CustomCommands.begin();
- si != this->GeneratorTarget->CustomCommands.end(); ++si)
+ std::string config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ std::vector<cmSourceFile const*> customCommands;
+ this->GeneratorTarget->GetCustomCommands(customCommands, config);
+ for(std::vector<cmSourceFile const*>::const_iterator
+ si = customCommands.begin();
+ si != customCommands.end(); ++si)
{
cmCustomCommand const* cc = (*si)->GetCustomCommand();
- this->GetLocalGenerator()->AddCustomCommandTarget(cc, this->GetTarget());
+ this->GetLocalGenerator()->AddCustomCommandTarget(cc,
+ this->GetGeneratorTarget());
+ // Record the custom commands for this target. The container is used
+ // in WriteObjectBuildStatement when called in a loop below.
+ this->CustomCommands.push_back(cc);
}
+ std::vector<cmSourceFile const*> headerSources;
+ this->GeneratorTarget->GetHeaderSources(headerSources, config);
this->OSXBundleGenerator->GenerateMacOSXContentStatements(
- this->GeneratorTarget->HeaderSources,
+ headerSources,
this->MacOSXContentGenerator);
+ std::vector<cmSourceFile const*> extraSources;
+ this->GeneratorTarget->GetExtraSources(extraSources, config);
this->OSXBundleGenerator->GenerateMacOSXContentStatements(
- this->GeneratorTarget->ExtraSources,
+ extraSources,
this->MacOSXContentGenerator);
- for(std::vector<cmSourceFile*>::const_iterator
- si = this->GeneratorTarget->ExternalObjects.begin();
- si != this->GeneratorTarget->ExternalObjects.end(); ++si)
+ std::vector<cmSourceFile const*> externalObjects;
+ this->GeneratorTarget->GetExternalObjects(externalObjects, config);
+ for(std::vector<cmSourceFile const*>::const_iterator
+ si = externalObjects.begin();
+ si != externalObjects.end(); ++si)
{
this->Objects.push_back(this->GetSourceFilePath(*si));
}
- for(std::vector<cmSourceFile*>::const_iterator
- si = this->GeneratorTarget->ObjectSources.begin();
- si != this->GeneratorTarget->ObjectSources.end(); ++si)
+
+ cmNinjaDeps orderOnlyDeps;
+ this->GetLocalGenerator()->AppendTargetDepends(this->GeneratorTarget,
+ orderOnlyDeps);
+
+ // Add order-only dependencies on custom command outputs.
+ for(std::vector<cmCustomCommand const*>::const_iterator
+ cci = this->CustomCommands.begin();
+ cci != this->CustomCommands.end(); ++cci)
{
- this->WriteObjectBuildStatement(*si);
+ cmCustomCommand const* cc = *cci;
+ cmCustomCommandGenerator ccg(*cc, this->GetConfigName(),
+ this->GetLocalGenerator());
+ const std::vector<std::string>& ccoutputs = ccg.GetOutputs();
+ const std::vector<std::string>& ccbyproducts= ccg.GetByproducts();
+ std::transform(ccoutputs.begin(), ccoutputs.end(),
+ std::back_inserter(orderOnlyDeps), MapToNinjaPath());
+ std::transform(ccbyproducts.begin(), ccbyproducts.end(),
+ std::back_inserter(orderOnlyDeps), MapToNinjaPath());
}
- if(!this->GeneratorTarget->ModuleDefinitionFile.empty())
+
+ if (!orderOnlyDeps.empty())
{
- this->ModuleDefinitionFile = this->ConvertToNinjaPath(
- this->GeneratorTarget->ModuleDefinitionFile.c_str());
+ cmNinjaDeps orderOnlyTarget;
+ orderOnlyTarget.push_back(this->OrderDependsTargetForTarget());
+ this->GetGlobalGenerator()->WritePhonyBuild(this->GetBuildFileStream(),
+ "Order-only phony target for "
+ + this->GetTargetName(),
+ orderOnlyTarget,
+ cmNinjaDeps(),
+ cmNinjaDeps(),
+ orderOnlyDeps);
}
-
- {
- // Add object library contents as external objects.
- std::vector<std::string> objs;
- this->GeneratorTarget->UseObjectLibraries(objs);
- for(std::vector<std::string>::iterator oi = objs.begin();
- oi != objs.end(); ++oi)
+ std::vector<cmSourceFile const*> objectSources;
+ this->GeneratorTarget->GetObjectSources(objectSources, config);
+ for(std::vector<cmSourceFile const*>::const_iterator
+ si = objectSources.begin(); si != objectSources.end(); ++si)
{
- this->Objects.push_back(ConvertToNinjaPath(oi->c_str()));
+ this->WriteObjectBuildStatement(*si, !orderOnlyDeps.empty());
}
- }
this->GetBuildFileStream() << "\n";
}
void
cmNinjaTargetGenerator
-::WriteObjectBuildStatement(cmSourceFile* source)
+::WriteObjectBuildStatement(
+ cmSourceFile const* source, bool writeOrderDependsTargetForTarget)
{
+ std::string const language = source->GetLanguage();
+ std::string const sourceFileName =
+ language=="RC" ? source->GetFullPath() : this->GetSourceFilePath(source);
+ std::string const objectDir = this->GeneratorTarget->GetSupportDirectory();
+ std::string const objectFileName = this->GetObjectFilePath(source);
+ std::string const objectFileDir =
+ cmSystemTools::GetFilenamePath(objectFileName);
+
+ cmNinjaVars vars;
+ vars["FLAGS"] = this->ComputeFlagsForObject(source, language);
+ vars["DEFINES"] = this->ComputeDefines(source, language);
+ vars["INCLUDES"] = this->GetIncludes(language);
+ if (!this->NeedDepTypeMSVC(language))
+ {
+ vars["DEP_FILE"] =
+ cmGlobalNinjaGenerator::EncodeDepfileSpace(objectFileName + ".d");
+ }
+
+ this->ExportObjectCompileCommand(
+ language, sourceFileName,
+ objectDir, objectFileName, objectFileDir,
+ vars["FLAGS"], vars["DEFINES"], vars["INCLUDES"]
+ );
+
std::string comment;
- const std::string language = source->GetLanguage();
std::string rule = this->LanguageCompilerRule(language);
cmNinjaDeps outputs;
- std::string objectFileName = this->GetObjectFilePath(source);
outputs.push_back(objectFileName);
// Add this object to the list of object files.
this->Objects.push_back(objectFileName);
cmNinjaDeps explicitDeps;
- std::string sourceFileName;
- if (language == "RC")
- sourceFileName = source->GetFullPath();
- else
- sourceFileName = this->GetSourceFilePath(source);
explicitDeps.push_back(sourceFileName);
- // Ensure that the target dependencies are built before any source file in
- // the target, using order-only dependencies.
- cmNinjaDeps orderOnlyDeps;
- this->GetLocalGenerator()->AppendTargetDepends(this->Target, orderOnlyDeps);
-
cmNinjaDeps implicitDeps;
if(const char* objectDeps = source->GetProperty("OBJECT_DEPENDS")) {
std::vector<std::string> depList;
cmSystemTools::ExpandListArgument(objectDeps, depList);
+ for(std::vector<std::string>::iterator odi = depList.begin();
+ odi != depList.end(); ++odi)
+ {
+ if (cmSystemTools::FileIsFullPath(*odi))
+ {
+ *odi = cmSystemTools::CollapseFullPath(*odi);
+ }
+ }
std::transform(depList.begin(), depList.end(),
std::back_inserter(implicitDeps), MapToNinjaPath());
}
- // Add order-only dependencies on custom command outputs.
- for(std::vector<cmSourceFile*>::const_iterator
- si = this->GeneratorTarget->CustomCommands.begin();
- si != this->GeneratorTarget->CustomCommands.end(); ++si)
+ cmNinjaDeps orderOnlyDeps;
+ if (writeOrderDependsTargetForTarget)
{
- cmCustomCommand const* cc = (*si)->GetCustomCommand();
- const std::vector<std::string>& ccoutputs = cc->GetOutputs();
- std::transform(ccoutputs.begin(), ccoutputs.end(),
- std::back_inserter(orderOnlyDeps), MapToNinjaPath());
+ orderOnlyDeps.push_back(this->OrderDependsTargetForTarget());
}
// If the source file is GENERATED and does not have a custom command
@@ -537,64 +627,19 @@ cmNinjaTargetGenerator
orderOnlyDeps);
}
- cmNinjaVars vars;
- vars["FLAGS"] = this->ComputeFlagsForObject(source, language);
- vars["DEFINES"] = this->ComputeDefines(source, language);
- vars["DEP_FILE"] = objectFileName + ".d";;
EnsureParentDirectoryExists(objectFileName);
- std::string objectDir = this->Target->GetSupportDirectory();
vars["OBJECT_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat(
- ConvertToNinjaPath(objectDir.c_str()).c_str(),
+ ConvertToNinjaPath(objectDir),
cmLocalGenerator::SHELL);
+ vars["OBJECT_FILE_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat(
+ ConvertToNinjaPath(objectFileDir),
+ cmLocalGenerator::SHELL);
- this->SetMsvcTargetPdbVariable(vars);
-
- if(this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS"))
- {
- cmLocalGenerator::RuleVariables compileObjectVars;
- std::string lang = language;
- compileObjectVars.Language = lang.c_str();
-
- std::string escapedSourceFileName = sourceFileName;
-
- if (!cmSystemTools::FileIsFullPath(sourceFileName.c_str()))
- {
- escapedSourceFileName = cmSystemTools::CollapseFullPath(
- escapedSourceFileName.c_str(),
- this->GetGlobalGenerator()->GetCMakeInstance()->
- GetHomeOutputDirectory());
- }
+ this->addPoolNinjaVariable("JOB_POOL_COMPILE",
+ this->GetGeneratorTarget(), vars);
- escapedSourceFileName =
- this->LocalGenerator->ConvertToOutputFormat(
- escapedSourceFileName.c_str(), cmLocalGenerator::SHELL);
-
- compileObjectVars.Source = escapedSourceFileName.c_str();
- compileObjectVars.Object = objectFileName.c_str();
- compileObjectVars.ObjectDir = objectDir.c_str();
- compileObjectVars.Flags = vars["FLAGS"].c_str();
- compileObjectVars.Defines = vars["DEFINES"].c_str();
-
- // Rule for compiling object file.
- std::string compileCmdVar = "CMAKE_";
- compileCmdVar += language;
- compileCmdVar += "_COMPILE_OBJECT";
- std::string compileCmd =
- this->GetMakefile()->GetRequiredDefinition(compileCmdVar.c_str());
- std::vector<std::string> compileCmds;
- cmSystemTools::ExpandListArgument(compileCmd, compileCmds);
-
- for (std::vector<std::string>::iterator i = compileCmds.begin();
- i != compileCmds.end(); ++i)
- this->GetLocalGenerator()->ExpandRuleVariables(*i, compileObjectVars);
-
- std::string cmdLine =
- this->GetLocalGenerator()->BuildCommandLine(compileCmds);
-
- this->GetGlobalGenerator()->AddCXXCompileCommand(cmdLine,
- sourceFileName);
- }
+ this->SetMsvcTargetPdbVariable(vars);
this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(),
comment,
@@ -617,30 +662,67 @@ cmNinjaTargetGenerator
}
}
-//----------------------------------------------------------------------------
void
cmNinjaTargetGenerator
-::AddModuleDefinitionFlag(std::string& flags)
+::ExportObjectCompileCommand(
+ std::string const& language,
+ std::string const& sourceFileName,
+ std::string const& objectDir,
+ std::string const& objectFileName,
+ std::string const& objectFileDir,
+ std::string const& flags,
+ std::string const& defines,
+ std::string const& includes
+ )
{
- if(this->ModuleDefinitionFile.empty())
+ if(!this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS"))
{
return;
}
- // TODO: Create a per-language flag variable.
- const char* defFileFlag =
- this->Makefile->GetDefinition("CMAKE_LINK_DEF_FILE_FLAG");
- if(!defFileFlag)
+ cmLocalGenerator::RuleVariables compileObjectVars;
+ compileObjectVars.Language = language.c_str();
+
+ std::string escapedSourceFileName = sourceFileName;
+
+ if (!cmSystemTools::FileIsFullPath(sourceFileName.c_str()))
{
- return;
+ escapedSourceFileName = cmSystemTools::CollapseFullPath(
+ escapedSourceFileName,
+ this->GetGlobalGenerator()->GetCMakeInstance()->
+ GetHomeOutputDirectory());
}
- // Append the flag and value. Use ConvertToLinkReference to help
- // vs6's "cl -link" pass it to the linker.
- std::string flag = defFileFlag;
- flag += (this->LocalGenerator->ConvertToLinkReference(
- this->ModuleDefinitionFile.c_str()));
- this->LocalGenerator->AppendFlags(flags, flag.c_str());
+ escapedSourceFileName =
+ this->LocalGenerator->ConvertToOutputFormat(
+ escapedSourceFileName, cmLocalGenerator::SHELL);
+
+ compileObjectVars.Source = escapedSourceFileName.c_str();
+ compileObjectVars.Object = objectFileName.c_str();
+ compileObjectVars.ObjectDir = objectDir.c_str();
+ compileObjectVars.ObjectFileDir = objectFileDir.c_str();
+ compileObjectVars.Flags = flags.c_str();
+ compileObjectVars.Defines = defines.c_str();
+ compileObjectVars.Includes = includes.c_str();
+
+ // Rule for compiling object file.
+ std::string compileCmdVar = "CMAKE_";
+ compileCmdVar += language;
+ compileCmdVar += "_COMPILE_OBJECT";
+ std::string compileCmd =
+ this->GetMakefile()->GetRequiredDefinition(compileCmdVar);
+ std::vector<std::string> compileCmds;
+ cmSystemTools::ExpandListArgument(compileCmd, compileCmds);
+
+ for (std::vector<std::string>::iterator i = compileCmds.begin();
+ i != compileCmds.end(); ++i)
+ this->GetLocalGenerator()->ExpandRuleVariables(*i, compileObjectVars);
+
+ std::string cmdLine =
+ this->GetLocalGenerator()->BuildCommandLine(compileCmds);
+
+ this->GetGlobalGenerator()->AddCXXCompileCommand(cmdLine,
+ sourceFileName);
}
void
@@ -664,17 +746,17 @@ void
cmNinjaTargetGenerator
::EnsureParentDirectoryExists(const std::string& path) const
{
- EnsureDirectoryExists(cmSystemTools::GetParentDirectory(path.c_str()));
+ EnsureDirectoryExists(cmSystemTools::GetParentDirectory(path));
}
//----------------------------------------------------------------------------
void
cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()(
- cmSourceFile& source, const char* pkgloc)
+ cmSourceFile const& source, const char* pkgloc)
{
// Skip OS X content when not building a Framework or Bundle.
- if(!this->Generator->GetTarget()->IsBundleOnApple())
+ if(!this->Generator->GetGeneratorTarget()->IsBundleOnApple())
{
return;
}
@@ -685,14 +767,14 @@ cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()(
// Get the input file location.
std::string input = source.GetFullPath();
input =
- this->Generator->GetLocalGenerator()->ConvertToNinjaPath(input.c_str());
+ this->Generator->GetGlobalGenerator()->ConvertToNinjaPath(input);
// Get the output file location.
std::string output = macdir;
output += "/";
output += cmSystemTools::GetFilenameName(input);
output =
- this->Generator->GetLocalGenerator()->ConvertToNinjaPath(output.c_str());
+ this->Generator->GetGlobalGenerator()->ConvertToNinjaPath(output);
// Write a build statement to copy the content into the bundle.
this->Generator->GetGlobalGenerator()->WriteMacOSXContentBuild(input,
@@ -701,3 +783,15 @@ cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()(
// Add as a dependency of all target so that it gets called.
this->Generator->GetGlobalGenerator()->AddDependencyToAll(output);
}
+
+void cmNinjaTargetGenerator::addPoolNinjaVariable(
+ const std::string& pool_property,
+ cmGeneratorTarget* target,
+ cmNinjaVars& vars)
+{
+ const char* pool = target->GetProperty(pool_property);
+ if (pool)
+ {
+ vars["pool"] = pool;
+ }
+}
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
index cf06bfdf5..e3ec4232f 100644
--- a/Source/cmNinjaTargetGenerator.h
+++ b/Source/cmNinjaTargetGenerator.h
@@ -13,27 +13,29 @@
#ifndef cmNinjaTargetGenerator_h
#define cmNinjaTargetGenerator_h
+#include "cmCommonTargetGenerator.h"
+
#include "cmStandardIncludes.h"
#include "cmNinjaTypes.h"
+#include "cmGlobalNinjaGenerator.h"
#include "cmLocalNinjaGenerator.h"
#include "cmOSXBundleGenerator.h"
class cmTarget;
-class cmGlobalNinjaGenerator;
class cmGeneratedFileStream;
class cmGeneratorTarget;
class cmMakefile;
class cmSourceFile;
class cmCustomCommand;
-class cmNinjaTargetGenerator
+class cmNinjaTargetGenerator: public cmCommonTargetGenerator
{
public:
/// Create a cmNinjaTargetGenerator according to the @a target's type.
- static cmNinjaTargetGenerator* New(cmTarget* target);
+ static cmNinjaTargetGenerator* New(cmGeneratorTarget* target);
/// Build a NinjaTargetGenerator.
- cmNinjaTargetGenerator(cmTarget* target);
+ cmNinjaTargetGenerator(cmGeneratorTarget* target);
/// Destructor.
virtual ~cmNinjaTargetGenerator();
@@ -42,6 +44,8 @@ public:
std::string GetTargetName() const;
+ bool NeedDepTypeMSVC(const std::string& lang) const;
+
protected:
bool SetMsvcTargetPdbVariable(cmNinjaVars&) const;
@@ -49,9 +53,6 @@ protected:
cmGeneratedFileStream& GetBuildFileStream() const;
cmGeneratedFileStream& GetRulesFileStream() const;
- cmTarget* GetTarget() const
- { return this->Target; }
-
cmGeneratorTarget* GetGeneratorTarget() const
{ return this->GeneratorTarget; }
@@ -63,41 +64,40 @@ protected:
cmMakefile* GetMakefile() const
{ return this->Makefile; }
- const char* GetConfigName() const;
+ std::string LanguageCompilerRule(const std::string& lang) const;
- std::string LanguageCompilerRule(const std::string& lang) const
- { return lang + "_COMPILER"; }
+ std::string OrderDependsTargetForTarget();
- const char* GetFeature(const char* feature);
- bool GetFeatureAsBool(const char* feature);
- void AddFeatureFlags(std::string& flags, const char* lang);
+ std::string ComputeOrderDependsForTarget();
/**
* Compute the flags for compilation of object files for a given @a language.
* @note Generally it is the value of the variable whose name is computed
* by LanguageFlagsVarName().
*/
- std::string ComputeFlagsForObject(cmSourceFile *source,
+ std::string ComputeFlagsForObject(cmSourceFile const* source,
const std::string& language);
- std::string ComputeDefines(cmSourceFile *source,
+ void AddIncludeFlags(std::string& flags, std::string const& lang);
+
+ std::string ComputeDefines(cmSourceFile const* source,
const std::string& language);
- std::string ConvertToNinjaPath(const char *path) const {
- return this->GetLocalGenerator()->ConvertToNinjaPath(path);
+ std::string ConvertToNinjaPath(const std::string& path) const {
+ return this->GetGlobalGenerator()->ConvertToNinjaPath(path);
}
- cmLocalNinjaGenerator::map_to_ninja_path MapToNinjaPath() const {
- return this->GetLocalGenerator()->MapToNinjaPath();
+ cmGlobalNinjaGenerator::MapToNinjaPathImpl MapToNinjaPath() const {
+ return this->GetGlobalGenerator()->MapToNinjaPath();
}
/// @return the list of link dependency for the given target @a target.
cmNinjaDeps ComputeLinkDeps() const;
/// @return the source file path for the given @a source.
- std::string GetSourceFilePath(cmSourceFile* source) const;
+ std::string GetSourceFilePath(cmSourceFile const* source) const;
/// @return the object file path for the given @a source.
- std::string GetObjectFilePath(cmSourceFile* source) const;
+ std::string GetObjectFilePath(cmSourceFile const* source) const;
/// @return the file path where the target named @a name is generated.
std::string GetTargetFilePath(const std::string& name) const;
@@ -108,15 +108,23 @@ protected:
void WriteLanguageRules(const std::string& language);
void WriteCompileRule(const std::string& language);
void WriteObjectBuildStatements();
- void WriteObjectBuildStatement(cmSourceFile* source);
- void WriteCustomCommandBuildStatement(cmCustomCommand *cc);
+ void WriteObjectBuildStatement(cmSourceFile const* source,
+ bool writeOrderDependsTargetForTarget);
+
+ void ExportObjectCompileCommand(
+ std::string const& language,
+ std::string const& sourceFileName,
+ std::string const& objectDir,
+ std::string const& objectFileName,
+ std::string const& objectFileDir,
+ std::string const& flags,
+ std::string const& defines,
+ std::string const& includes
+ );
cmNinjaDeps GetObjects() const
{ return this->Objects; }
- // Helper to add flag for windows .def file.
- void AddModuleDefinitionFlag(std::string& flags);
-
void EnsureDirectoryExists(const std::string& dir) const;
void EnsureParentDirectoryExists(const std::string& path) const;
@@ -127,30 +135,28 @@ protected:
MacOSXContentGeneratorType(cmNinjaTargetGenerator* g) :
Generator(g) {}
- void operator()(cmSourceFile& source, const char* pkgloc);
+ void operator()(cmSourceFile const& source, const char* pkgloc);
private:
cmNinjaTargetGenerator* Generator;
};
friend struct MacOSXContentGeneratorType;
-protected:
+
MacOSXContentGeneratorType* MacOSXContentGenerator;
// Properly initialized by sub-classes.
cmOSXBundleGenerator* OSXBundleGenerator;
- std::set<cmStdString> MacContentFolders;
+ std::set<std::string> MacContentFolders;
+ void addPoolNinjaVariable(const std::string& pool_property,
+ cmGeneratorTarget* target,
+ cmNinjaVars& vars);
private:
- cmTarget* Target;
- cmGeneratorTarget* GeneratorTarget;
- cmMakefile* Makefile;
cmLocalNinjaGenerator* LocalGenerator;
/// List of object files for this target.
cmNinjaDeps Objects;
-
- // The windows module definition source file (.def), if any.
- std::string ModuleDefinitionFile;
+ std::vector<cmCustomCommand const*> CustomCommands;
};
#endif // ! cmNinjaTargetGenerator_h
diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx
index 755ce6edc..ac66fcd00 100644
--- a/Source/cmNinjaUtilityTargetGenerator.cxx
+++ b/Source/cmNinjaUtilityTargetGenerator.cxx
@@ -16,49 +16,72 @@
#include "cmGlobalNinjaGenerator.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
-#include "cmTarget.h"
+#include "cmCustomCommandGenerator.h"
-cmNinjaUtilityTargetGenerator::cmNinjaUtilityTargetGenerator(cmTarget *target)
+cmNinjaUtilityTargetGenerator::cmNinjaUtilityTargetGenerator(
+ cmGeneratorTarget *target)
: cmNinjaTargetGenerator(target) {}
cmNinjaUtilityTargetGenerator::~cmNinjaUtilityTargetGenerator() {}
void cmNinjaUtilityTargetGenerator::Generate()
{
+ std::string utilCommandName = cmake::GetCMakeFilesDirectoryPostSlash();
+ utilCommandName += this->GetTargetName() + ".util";
+
std::vector<std::string> commands;
- cmNinjaDeps deps, outputs;
+ cmNinjaDeps deps, outputs, util_outputs(1, utilCommandName);
const std::vector<cmCustomCommand> *cmdLists[2] = {
- &this->GetTarget()->GetPreBuildCommands(),
- &this->GetTarget()->GetPostBuildCommands()
+ &this->GetGeneratorTarget()->GetPreBuildCommands(),
+ &this->GetGeneratorTarget()->GetPostBuildCommands()
};
+ bool uses_terminal = false;
+
for (unsigned i = 0; i != 2; ++i) {
for (std::vector<cmCustomCommand>::const_iterator
ci = cmdLists[i]->begin(); ci != cmdLists[i]->end(); ++ci) {
- this->GetLocalGenerator()->AppendCustomCommandDeps(&*ci, deps);
- this->GetLocalGenerator()->AppendCustomCommandLines(&*ci, commands);
+ cmCustomCommandGenerator ccg(*ci, this->GetConfigName(),
+ this->GetLocalGenerator());
+ this->GetLocalGenerator()->AppendCustomCommandDeps(ccg, deps);
+ this->GetLocalGenerator()->AppendCustomCommandLines(ccg, commands);
+ std::vector<std::string> const& ccByproducts = ccg.GetByproducts();
+ std::transform(ccByproducts.begin(), ccByproducts.end(),
+ std::back_inserter(util_outputs), MapToNinjaPath());
+ if (ci->GetUsesTerminal())
+ uses_terminal = true;
}
}
- const std::vector<cmSourceFile*>& sources =
- this->GetTarget()->GetSourceFiles();
+ std::vector<cmSourceFile*> sources;
+ std::string config = this->GetMakefile()
+ ->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ this->GetGeneratorTarget()->GetSourceFiles(sources, config);
for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
source != sources.end(); ++source)
{
if(cmCustomCommand* cc = (*source)->GetCustomCommand())
{
- this->GetLocalGenerator()->AddCustomCommandTarget(cc, this->GetTarget());
+ cmCustomCommandGenerator ccg(*cc, this->GetConfigName(),
+ this->GetLocalGenerator());
+ this->GetLocalGenerator()->AddCustomCommandTarget(cc,
+ this->GetGeneratorTarget());
// Depend on all custom command outputs.
- const std::vector<std::string>& ccOutputs = cc->GetOutputs();
+ const std::vector<std::string>& ccOutputs = ccg.GetOutputs();
+ const std::vector<std::string>& ccByproducts = ccg.GetByproducts();
std::transform(ccOutputs.begin(), ccOutputs.end(),
std::back_inserter(deps), MapToNinjaPath());
+ std::transform(ccByproducts.begin(), ccByproducts.end(),
+ std::back_inserter(deps), MapToNinjaPath());
}
}
- this->GetLocalGenerator()->AppendTargetOutputs(this->GetTarget(), outputs);
- this->GetLocalGenerator()->AppendTargetDepends(this->GetTarget(), deps);
+ this->GetLocalGenerator()->AppendTargetOutputs(this->GetGeneratorTarget(),
+ outputs);
+ this->GetLocalGenerator()->AppendTargetDepends(this->GetGeneratorTarget(),
+ deps);
if (commands.empty()) {
this->GetGlobalGenerator()->WritePhonyBuild(this->GetBuildFileStream(),
@@ -69,7 +92,8 @@ void cmNinjaUtilityTargetGenerator::Generate()
} else {
std::string command =
this->GetLocalGenerator()->BuildCommandLine(commands);
- const char *echoStr = this->GetTarget()->GetProperty("EchoString");
+ const char *echoStr =
+ this->GetGeneratorTarget()->GetProperty("EchoString");
std::string desc;
if (echoStr)
desc = echoStr;
@@ -82,27 +106,33 @@ void cmNinjaUtilityTargetGenerator::Generate()
command,
"$(CMAKE_SOURCE_DIR)",
this->GetLocalGenerator()->ConvertToOutputFormat(
- this->GetTarget()->GetMakefile()->GetHomeDirectory(),
+ this->GetLocalGenerator()->GetSourceDirectory(),
cmLocalGenerator::SHELL).c_str());
cmSystemTools::ReplaceString(
command,
"$(CMAKE_BINARY_DIR)",
this->GetLocalGenerator()->ConvertToOutputFormat(
- this->GetTarget()->GetMakefile()->GetHomeOutputDirectory(),
+ this->GetLocalGenerator()->GetBinaryDirectory(),
cmLocalGenerator::SHELL).c_str());
cmSystemTools::ReplaceString(command, "$(ARGS)", "");
if (command.find('$') != std::string::npos)
return;
- std::string utilCommandName = cmake::GetCMakeFilesDirectoryPostSlash();
- utilCommandName += this->GetTargetName() + ".util";
+ for (cmNinjaDeps::const_iterator
+ oi = util_outputs.begin(), oe = util_outputs.end();
+ oi != oe; ++oi)
+ {
+ this->GetGlobalGenerator()->SeenCustomCommandOutput(*oi);
+ }
this->GetGlobalGenerator()->WriteCustomCommandBuild(
command,
desc,
"Utility command for " + this->GetTargetName(),
- cmNinjaDeps(1, utilCommandName),
+ uses_terminal,
+ /*restat*/true,
+ util_outputs,
deps);
this->GetGlobalGenerator()->WritePhonyBuild(this->GetBuildFileStream(),
@@ -113,5 +143,5 @@ void cmNinjaUtilityTargetGenerator::Generate()
}
this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(),
- this->GetTarget());
+ this->GetGeneratorTarget());
}
diff --git a/Source/cmNinjaUtilityTargetGenerator.h b/Source/cmNinjaUtilityTargetGenerator.h
index 8b82ce49a..add0291a5 100644
--- a/Source/cmNinjaUtilityTargetGenerator.h
+++ b/Source/cmNinjaUtilityTargetGenerator.h
@@ -21,7 +21,7 @@ class cmSourceFile;
class cmNinjaUtilityTargetGenerator : public cmNinjaTargetGenerator
{
public:
- cmNinjaUtilityTargetGenerator(cmTarget* target);
+ cmNinjaUtilityTargetGenerator(cmGeneratorTarget* target);
~cmNinjaUtilityTargetGenerator();
void Generate();
diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx
index a475c7cfa..934e1986a 100644
--- a/Source/cmOSXBundleGenerator.cxx
+++ b/Source/cmOSXBundleGenerator.cxx
@@ -18,11 +18,11 @@
//----------------------------------------------------------------------------
cmOSXBundleGenerator::
-cmOSXBundleGenerator(cmTarget* target,
- const char* configName)
- : Target(target)
- , Makefile(target->GetMakefile())
- , LocalGenerator(Makefile->GetLocalGenerator())
+cmOSXBundleGenerator(cmGeneratorTarget* target,
+ const std::string& configName)
+ : GT(target)
+ , Makefile(target->Target->GetMakefile())
+ , LocalGenerator(target->GetLocalGenerator())
, ConfigName(configName)
, MacContentFolders(0)
{
@@ -34,7 +34,7 @@ cmOSXBundleGenerator(cmTarget* target,
//----------------------------------------------------------------------------
bool cmOSXBundleGenerator::MustSkip()
{
- return !this->Target->HaveWellDefinedOutputFiles();
+ return !this->GT->HaveWellDefinedOutputFiles();
}
//----------------------------------------------------------------------------
@@ -47,7 +47,7 @@ void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName,
// Compute bundle directory names.
std::string out = outpath;
out += "/";
- out += this->Target->GetAppBundleDirectory(this->ConfigName, false);
+ out += this->GT->GetAppBundleDirectory(this->ConfigName, false);
cmSystemTools::MakeDirectory(out.c_str());
this->Makefile->AddCMakeOutputFile(out);
@@ -57,10 +57,10 @@ void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName,
// to be set.
std::string plist = outpath;
plist += "/";
- plist += this->Target->GetAppBundleDirectory(this->ConfigName, true);
+ plist += this->GT->GetAppBundleDirectory(this->ConfigName, true);
plist += "/Info.plist";
- this->LocalGenerator->GenerateAppleInfoPList(this->Target,
- targetName.c_str(),
+ this->LocalGenerator->GenerateAppleInfoPList(this->GT,
+ targetName,
plist.c_str());
this->Makefile->AddCMakeOutputFile(plist);
outpath = newoutpath;
@@ -77,23 +77,32 @@ void cmOSXBundleGenerator::CreateFramework(
// Compute the location of the top-level foo.framework directory.
std::string contentdir = outpath + "/" +
- this->Target->GetFrameworkDirectory(this->ConfigName, true);
+ this->GT->GetFrameworkDirectory(this->ConfigName, true);
contentdir += "/";
std::string newoutpath = outpath + "/" +
- this->Target->GetFrameworkDirectory(this->ConfigName, false);
+ this->GT->GetFrameworkDirectory(this->ConfigName, false);
- std::string frameworkVersion = this->Target->GetFrameworkVersion();
+ std::string frameworkVersion = this->GT->GetFrameworkVersion();
- // Configure the Info.plist file into the Resources directory.
- this->MacContentFolders->insert("Resources");
+ // Configure the Info.plist file
std::string plist = newoutpath;
- plist += "/Resources/Info.plist";
+ if (!this->Makefile->PlatformIsAppleIos())
+ {
+ // Put the Info.plist file into the Resources directory.
+ this->MacContentFolders->insert("Resources");
+ plist += "/Resources";
+ }
+ plist += "/Info.plist";
std::string name = cmSystemTools::GetFilenameName(targetName);
- this->LocalGenerator->GenerateFrameworkInfoPList(this->Target,
- name.c_str(),
+ this->LocalGenerator->GenerateFrameworkInfoPList(this->GT,
+ name,
plist.c_str());
+ // Generate Versions directory only for MacOSX frameworks
+ if (this->Makefile->PlatformIsAppleIos())
+ return;
+
// TODO: Use the cmMakefileTargetGenerator::ExtraFiles vector to
// drive rules to create these files at build time.
std::string oldName;
@@ -112,8 +121,8 @@ void cmOSXBundleGenerator::CreateFramework(
oldName = frameworkVersion;
newName = versions;
newName += "/Current";
- cmSystemTools::RemoveFile(newName.c_str());
- cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str());
+ cmSystemTools::RemoveFile(newName);
+ cmSystemTools::CreateSymlink(oldName, newName);
this->Makefile->AddCMakeOutputFile(newName);
// foo -> Versions/Current/foo
@@ -121,8 +130,8 @@ void cmOSXBundleGenerator::CreateFramework(
oldName += name;
newName = contentdir;
newName += name;
- cmSystemTools::RemoveFile(newName.c_str());
- cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str());
+ cmSystemTools::RemoveFile(newName);
+ cmSystemTools::CreateSymlink(oldName, newName);
this->Makefile->AddCMakeOutputFile(newName);
// Resources -> Versions/Current/Resources
@@ -132,8 +141,8 @@ void cmOSXBundleGenerator::CreateFramework(
oldName = "Versions/Current/Resources";
newName = contentdir;
newName += "Resources";
- cmSystemTools::RemoveFile(newName.c_str());
- cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str());
+ cmSystemTools::RemoveFile(newName);
+ cmSystemTools::CreateSymlink(oldName, newName);
this->Makefile->AddCMakeOutputFile(newName);
}
@@ -144,8 +153,8 @@ void cmOSXBundleGenerator::CreateFramework(
oldName = "Versions/Current/Headers";
newName = contentdir;
newName += "Headers";
- cmSystemTools::RemoveFile(newName.c_str());
- cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str());
+ cmSystemTools::RemoveFile(newName);
+ cmSystemTools::CreateSymlink(oldName, newName);
this->Makefile->AddCMakeOutputFile(newName);
}
@@ -156,8 +165,8 @@ void cmOSXBundleGenerator::CreateFramework(
oldName = "Versions/Current/PrivateHeaders";
newName = contentdir;
newName += "PrivateHeaders";
- cmSystemTools::RemoveFile(newName.c_str());
- cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str());
+ cmSystemTools::RemoveFile(newName);
+ cmSystemTools::CreateSymlink(oldName, newName);
this->Makefile->AddCMakeOutputFile(newName);
}
}
@@ -172,17 +181,18 @@ void cmOSXBundleGenerator::CreateCFBundle(const std::string& targetName,
// Compute bundle directory names.
std::string out = root;
out += "/";
- out += this->Target->GetCFBundleDirectory(this->ConfigName, false);
+ out += this->GT->GetCFBundleDirectory(this->ConfigName, false);
cmSystemTools::MakeDirectory(out.c_str());
this->Makefile->AddCMakeOutputFile(out);
// Configure the Info.plist file. Note that it needs the executable name
// to be set.
- std::string plist =
- this->Target->GetCFBundleDirectory(this->ConfigName, true);
+ std::string plist = root + "/" +
+ this->GT->GetCFBundleDirectory(this->ConfigName, true);
plist += "/Info.plist";
- this->LocalGenerator->GenerateAppleInfoPList(this->Target,
- targetName.c_str(),
+ std::string name = cmSystemTools::GetFilenameName(targetName);
+ this->LocalGenerator->GenerateAppleInfoPList(this->GT,
+ name,
plist.c_str());
this->Makefile->AddCMakeOutputFile(plist);
}
@@ -190,18 +200,19 @@ void cmOSXBundleGenerator::CreateCFBundle(const std::string& targetName,
//----------------------------------------------------------------------------
void
cmOSXBundleGenerator::
-GenerateMacOSXContentStatements(std::vector<cmSourceFile*> const& sources,
- MacOSXContentGeneratorType* generator)
+GenerateMacOSXContentStatements(
+ std::vector<cmSourceFile const*> const& sources,
+ MacOSXContentGeneratorType* generator)
{
if (this->MustSkip())
return;
- for(std::vector<cmSourceFile*>::const_iterator
+ for(std::vector<cmSourceFile const*>::const_iterator
si = sources.begin(); si != sources.end(); ++si)
{
- cmTarget::SourceFileFlags tsFlags =
- this->Target->GetTargetSourceFileFlags(*si);
- if(tsFlags.Type != cmTarget::SourceFileTypeNormal)
+ cmGeneratorTarget::SourceFileFlags tsFlags =
+ this->GT->GetTargetSourceFileFlags(*si);
+ if(tsFlags.Type != cmGeneratorTarget::SourceFileTypeNormal)
{
(*generator)(**si, tsFlags.MacFolder);
}
@@ -215,7 +226,7 @@ cmOSXBundleGenerator::InitMacOSXContentDirectory(const char* pkgloc)
// Construct the full path to the content subdirectory.
std::string macdir =
- this->Target->GetMacContentDirectory(this->ConfigName,
+ this->GT->GetMacContentDirectory(this->ConfigName,
/*implib*/ false);
macdir += "/";
macdir += pkgloc;
diff --git a/Source/cmOSXBundleGenerator.h b/Source/cmOSXBundleGenerator.h
index ec82b9a15..f945c15a8 100644
--- a/Source/cmOSXBundleGenerator.h
+++ b/Source/cmOSXBundleGenerator.h
@@ -21,12 +21,13 @@
class cmTarget;
class cmMakefile;
class cmLocalGenerator;
+class cmGeneratorTarget;
class cmOSXBundleGenerator
{
public:
- cmOSXBundleGenerator(cmTarget* target,
- const char* configName);
+ cmOSXBundleGenerator(cmGeneratorTarget* target,
+ const std::string& configName);
// create an app bundle at a given root, and return
// the directory within the bundle that contains the executable
@@ -43,26 +44,27 @@ public:
struct MacOSXContentGeneratorType
{
virtual ~MacOSXContentGeneratorType() {}
- virtual void operator()(cmSourceFile& source, const char* pkgloc) = 0;
+ virtual void operator()(cmSourceFile const& source,
+ const char* pkgloc) = 0;
};
void GenerateMacOSXContentStatements(
- std::vector<cmSourceFile*> const& sources,
+ std::vector<cmSourceFile const*> const& sources,
MacOSXContentGeneratorType* generator);
std::string InitMacOSXContentDirectory(const char* pkgloc);
- void SetMacContentFolders(std::set<cmStdString>* macContentFolders)
+ void SetMacContentFolders(std::set<std::string>* macContentFolders)
{ this->MacContentFolders = macContentFolders; }
private:
bool MustSkip();
private:
- cmTarget* Target;
+ cmGeneratorTarget* GT;
cmMakefile* Makefile;
cmLocalGenerator* LocalGenerator;
- const char* ConfigName;
- std::set<cmStdString>* MacContentFolders;
+ std::string ConfigName;
+ std::set<std::string>* MacContentFolders;
};
diff --git a/Source/cmOptionCommand.cxx b/Source/cmOptionCommand.cxx
index 776a3a443..92be5f1ab 100644
--- a/Source/cmOptionCommand.cxx
+++ b/Source/cmOptionCommand.cxx
@@ -34,38 +34,31 @@ bool cmOptionCommand
if(argError)
{
std::string m = "called with incorrect number of arguments: ";
- for(size_t i =0; i < args.size(); ++i)
- {
- m += args[i];
- m += " ";
- }
- this->SetError(m.c_str());
+ m += cmJoin(args, " ");
+ this->SetError(m);
return false;
}
std::string initialValue = "Off";
// Now check and see if the value has been stored in the cache
// already, if so use that value and don't look for the program
- cmCacheManager::CacheIterator it =
- this->Makefile->GetCacheManager()->GetCacheIterator(args[0].c_str());
- if(!it.IsAtEnd())
+ cmState* state = this->Makefile->GetState();
+ const char* existingValue = state->GetCacheEntryValue(args[0]);
+ if(existingValue)
{
- if ( it.GetType() != cmCacheManager::UNINITIALIZED )
+ if (state->GetCacheEntryType(args[0]) != cmState::UNINITIALIZED)
{
- it.SetProperty("HELPSTRING", args[1].c_str());
+ state->SetCacheEntryProperty(args[0], "HELPSTRING", args[1]);
return true;
}
- if ( it.GetValue() )
- {
- initialValue = it.GetValue();
- }
+ initialValue = existingValue;
}
if(args.size() == 3)
{
initialValue = args[2];
}
bool init = cmSystemTools::IsOn(initialValue.c_str());
- this->Makefile->AddCacheDefinition(args[0].c_str(), init? "ON":"OFF",
- args[1].c_str(), cmCacheManager::BOOL);
+ this->Makefile->AddCacheDefinition(args[0], init? "ON":"OFF",
+ args[1].c_str(), cmState::BOOL);
return true;
}
diff --git a/Source/cmOptionCommand.h b/Source/cmOptionCommand.h
index 7d0240050..12a647227 100644
--- a/Source/cmOptionCommand.h
+++ b/Source/cmOptionCommand.h
@@ -40,30 +40,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const {return "option";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Provides an option that the user can optionally select.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " option(<option_variable> \"help string describing option\"\n"
- " [initial value])\n"
- "Provide an option for the user to select as ON or OFF. If no "
- "initial value is provided, OFF is used.\n"
- "If you have options that depend on the values of other "
- "options, see the module help for CMakeDependentOption."
- ;
- }
+ virtual std::string GetName() const {return "option";}
/**
* This determines if the command is invoked when in script mode.
diff --git a/Source/cmOrderDirectories.cxx b/Source/cmOrderDirectories.cxx
index 022082519..61efd01e4 100644
--- a/Source/cmOrderDirectories.cxx
+++ b/Source/cmOrderDirectories.cxx
@@ -14,6 +14,7 @@
#include "cmGlobalGenerator.h"
#include "cmSystemTools.h"
#include "cmake.h"
+#include "cmAlgorithms.h"
#include <assert.h>
@@ -39,8 +40,8 @@ public:
if(file.rfind(".framework") != std::string::npos)
{
- cmsys::RegularExpression splitFramework;
- splitFramework.compile("^(.*)/(.*).framework/(.*)$");
+ static cmsys::RegularExpression
+ splitFramework("^(.*)/(.*).framework/(.*)$");
if(splitFramework.find(file) &&
(std::string::npos !=
splitFramework.match(3).find(splitFramework.match(2))))
@@ -72,7 +73,8 @@ public:
{
// Check if this directory conflicts with the entry.
std::string const& dir = this->OD->OriginalDirectories[i];
- if(dir != this->Directory && this->FindConflict(dir))
+ if (!this->OD->IsSameDirectory(dir, this->Directory) &&
+ this->FindConflict(dir))
{
// The library will be found in this directory but this is not
// the directory named for it. Add an entry to make sure the
@@ -83,14 +85,17 @@ public:
}
}
- void FindImplicitConflicts(cmOStringStream& w)
+ void FindImplicitConflicts(std::ostringstream& w)
{
bool first = true;
for(unsigned int i=0; i < this->OD->OriginalDirectories.size(); ++i)
{
// Check if this directory conflicts with the entry.
std::string const& dir = this->OD->OriginalDirectories[i];
- if(dir != this->Directory && this->FindConflict(dir))
+ if(dir != this->Directory &&
+ cmSystemTools::GetRealPath(dir) !=
+ cmSystemTools::GetRealPath(this->Directory) &&
+ this->FindConflict(dir))
{
// The library will be found in this directory but it is
// supposed to be found in an implicit search directory.
@@ -134,13 +139,13 @@ bool cmOrderDirectoriesConstraint::FileMayConflict(std::string const& dir,
{
// The file conflicts only if it is not the same as the original
// file due to a symlink or hardlink.
- return !cmSystemTools::SameFile(this->FullPath.c_str(), file.c_str());
+ return !cmSystemTools::SameFile(this->FullPath, file);
}
// Check if the file will be built by cmake.
- std::set<cmStdString> const& files =
+ std::set<std::string> const& files =
(this->GlobalGenerator->GetDirectoryContent(dir, false));
- std::set<cmStdString>::const_iterator fi = files.find(name);
+ std::set<std::string>::const_iterator fi = files.find(name);
return fi != files.end();
}
@@ -200,7 +205,7 @@ bool cmOrderDirectoriesConstraintSOName::FindConflict(std::string const& dir)
{
// We do not have the soname. Look for files in the directory
// that may conflict.
- std::set<cmStdString> const& files =
+ std::set<std::string> const& files =
(this->GlobalGenerator
->GetDirectoryContent(dir, true));
@@ -208,9 +213,9 @@ bool cmOrderDirectoriesConstraintSOName::FindConflict(std::string const& dir)
// know the soname just look at all files that start with the
// file name. Usually the soname starts with the library name.
std::string base = this->FileName;
- std::set<cmStdString>::const_iterator first = files.lower_bound(base);
+ std::set<std::string>::const_iterator first = files.lower_bound(base);
++base[base.size()-1];
- std::set<cmStdString>::const_iterator last = files.upper_bound(base);
+ std::set<std::string>::const_iterator last = files.upper_bound(base);
if(first != last)
{
return true;
@@ -251,8 +256,8 @@ bool cmOrderDirectoriesConstraintLibrary::FindConflict(std::string const& dir)
if(!this->OD->LinkExtensions.empty() &&
this->OD->RemoveLibraryExtension.find(this->FileName))
{
- cmStdString lib = this->OD->RemoveLibraryExtension.match(1);
- cmStdString ext = this->OD->RemoveLibraryExtension.match(2);
+ std::string lib = this->OD->RemoveLibraryExtension.match(1);
+ std::string ext = this->OD->RemoveLibraryExtension.match(2);
for(std::vector<std::string>::iterator
i = this->OD->LinkExtensions.begin();
i != this->OD->LinkExtensions.end(); ++i)
@@ -261,7 +266,7 @@ bool cmOrderDirectoriesConstraintLibrary::FindConflict(std::string const& dir)
{
std::string fname = lib;
fname += *i;
- if(this->FileMayConflict(dir, fname.c_str()))
+ if(this->FileMayConflict(dir, fname))
{
return true;
}
@@ -273,7 +278,7 @@ bool cmOrderDirectoriesConstraintLibrary::FindConflict(std::string const& dir)
//----------------------------------------------------------------------------
cmOrderDirectories::cmOrderDirectories(cmGlobalGenerator* gg,
- cmTarget* target,
+ const cmGeneratorTarget* target,
const char* purpose)
{
this->GlobalGenerator = gg;
@@ -285,18 +290,8 @@ cmOrderDirectories::cmOrderDirectories(cmGlobalGenerator* gg,
//----------------------------------------------------------------------------
cmOrderDirectories::~cmOrderDirectories()
{
- for(std::vector<cmOrderDirectoriesConstraint*>::iterator
- i = this->ConstraintEntries.begin();
- i != this->ConstraintEntries.end(); ++i)
- {
- delete *i;
- }
- for(std::vector<cmOrderDirectoriesConstraint*>::iterator
- i = this->ImplicitDirEntries.begin();
- i != this->ImplicitDirEntries.end(); ++i)
- {
- delete *i;
- }
+ cmDeleteAll(this->ConstraintEntries);
+ cmDeleteAll(this->ImplicitDirEntries);
}
//----------------------------------------------------------------------------
@@ -326,8 +321,8 @@ void cmOrderDirectories::AddRuntimeLibrary(std::string const& fullPath,
if(fullPath.rfind(".framework") != std::string::npos)
{
- cmsys::RegularExpression splitFramework;
- splitFramework.compile("^(.*)/(.*).framework/(.*)$");
+ static cmsys::RegularExpression
+ splitFramework("^(.*)/(.*).framework/(.*)$");
if(splitFramework.find(fullPath) &&
(std::string::npos !=
splitFramework.match(3).find(splitFramework.match(2))))
@@ -407,7 +402,7 @@ cmOrderDirectories
//----------------------------------------------------------------------------
void
cmOrderDirectories
-::SetImplicitDirectories(std::set<cmStdString> const& implicitDirs)
+::SetImplicitDirectories(std::set<std::string> const& implicitDirs)
{
this->ImplicitDirectories = implicitDirs;
}
@@ -444,11 +439,11 @@ void cmOrderDirectories::CollectOriginalDirectories()
int cmOrderDirectories::AddOriginalDirectory(std::string const& dir)
{
// Add the runtime directory with a unique index.
- std::map<cmStdString, int>::iterator i =
+ std::map<std::string, int>::iterator i =
this->DirectoryIndex.find(dir);
if(i == this->DirectoryIndex.end())
{
- std::map<cmStdString, int>::value_type
+ std::map<std::string, int>::value_type
entry(dir, static_cast<int>(this->OriginalDirectories.size()));
i = this->DirectoryIndex.insert(entry).first;
this->OriginalDirectories.push_back(dir);
@@ -535,7 +530,7 @@ void cmOrderDirectories::FindImplicitConflicts()
{
// Check for items in implicit link directories that have conflicts
// in the explicit directories.
- cmOStringStream conflicts;
+ std::ostringstream conflicts;
for(unsigned int i=0; i < this->ImplicitDirEntries.size(); ++i)
{
this->ImplicitDirEntries[i]->FindImplicitConflicts(conflicts);
@@ -549,7 +544,7 @@ void cmOrderDirectories::FindImplicitConflicts()
}
// Warn about the conflicts.
- cmOStringStream w;
+ std::ostringstream w;
w << "Cannot generate a safe " << this->Purpose
<< " for target " << this->Target->GetName()
<< " because files in some directories may conflict with "
@@ -557,7 +552,8 @@ void cmOrderDirectories::FindImplicitConflicts()
<< text
<< "Some of these libraries may not be found correctly.";
this->GlobalGenerator->GetCMakeInstance()
- ->IssueMessage(cmake::WARNING, w.str(), this->Target->GetBacktrace());
+ ->IssueMessage(cmake::WARNING, w.str(),
+ this->Target->GetBacktrace());
}
//----------------------------------------------------------------------------
@@ -618,7 +614,7 @@ void cmOrderDirectories::DiagnoseCycle()
this->CycleDiagnosed = true;
// Construct the message.
- cmOStringStream e;
+ std::ostringstream e;
e << "Cannot generate a safe " << this->Purpose
<< " for target " << this->Target->GetName()
<< " because there is a cycle in the constraint graph:\n";
@@ -638,5 +634,26 @@ void cmOrderDirectories::DiagnoseCycle()
}
e << "Some of these libraries may not be found correctly.";
this->GlobalGenerator->GetCMakeInstance()
- ->IssueMessage(cmake::WARNING, e.str(), this->Target->GetBacktrace());
+ ->IssueMessage(cmake::WARNING, e.str(),
+ this->Target->GetBacktrace());
+}
+
+bool cmOrderDirectories::IsSameDirectory(std::string const& l,
+ std::string const& r)
+{
+ return this->GetRealPath(l) == this->GetRealPath(r);
+}
+
+std::string const& cmOrderDirectories::GetRealPath(std::string const& dir)
+{
+ std::map<std::string, std::string>::iterator i =
+ this->RealPaths.lower_bound(dir);
+ if (i == this->RealPaths.end() ||
+ this->RealPaths.key_comp()(dir, i->first))
+ {
+ typedef std::map<std::string, std::string>::value_type value_type;
+ i = this->RealPaths.insert(
+ i, value_type(dir, cmSystemTools::GetRealPath(dir)));
+ }
+ return i->second;
}
diff --git a/Source/cmOrderDirectories.h b/Source/cmOrderDirectories.h
index 96a75de17..477216bbd 100644
--- a/Source/cmOrderDirectories.h
+++ b/Source/cmOrderDirectories.h
@@ -19,7 +19,7 @@
class cmGlobalGenerator;
class cmOrderDirectoriesConstraint;
class cmOrderDirectoriesConstraintLibrary;
-class cmTarget;
+class cmGeneratorTarget;
/** \class cmOrderDirectories
* \brief Compute a safe runtime path order for a set of shared libraries.
@@ -27,25 +27,23 @@ class cmTarget;
class cmOrderDirectories
{
public:
- cmOrderDirectories(cmGlobalGenerator* gg, cmTarget* target,
+ cmOrderDirectories(cmGlobalGenerator* gg, cmGeneratorTarget const* target,
const char* purpose);
~cmOrderDirectories();
void AddRuntimeLibrary(std::string const& fullPath, const char* soname = 0);
void AddLinkLibrary(std::string const& fullPath);
void AddUserDirectories(std::vector<std::string> const& extra);
void AddLanguageDirectories(std::vector<std::string> const& dirs);
- void SetImplicitDirectories(std::set<cmStdString> const& implicitDirs);
+ void SetImplicitDirectories(std::set<std::string> const& implicitDirs);
void SetLinkExtensionInfo(std::vector<std::string> const& linkExtensions,
std::string const& removeExtRegex);
std::vector<std::string> const& GetOrderedDirectories();
private:
cmGlobalGenerator* GlobalGenerator;
- cmTarget* Target;
+ cmGeneratorTarget const* Target;
std::string Purpose;
- bool Computed;
-
std::vector<std::string> OrderedDirectories;
std::vector<cmOrderDirectoriesConstraint*> ConstraintEntries;
@@ -54,11 +52,11 @@ private:
std::vector<std::string> LanguageDirectories;
cmsys::RegularExpression RemoveLibraryExtension;
std::vector<std::string> LinkExtensions;
- std::set<cmStdString> ImplicitDirectories;
- std::set<cmStdString> EmmittedConstraintSOName;
- std::set<cmStdString> EmmittedConstraintLibrary;
+ std::set<std::string> ImplicitDirectories;
+ std::set<std::string> EmmittedConstraintSOName;
+ std::set<std::string> EmmittedConstraintLibrary;
std::vector<std::string> OriginalDirectories;
- std::map<cmStdString, int> DirectoryIndex;
+ std::map<std::string, int> DirectoryIndex;
std::vector<int> DirectoryVisited;
void CollectOriginalDirectories();
int AddOriginalDirectory(std::string const& dir);
@@ -68,8 +66,9 @@ private:
void OrderDirectories();
void VisitDirectory(unsigned int i);
void DiagnoseCycle();
- bool CycleDiagnosed;
int WalkId;
+ bool CycleDiagnosed;
+ bool Computed;
// Adjacency-list representation of runtime path ordering graph.
// This maps from directory to those that must come *before* it.
@@ -81,6 +80,12 @@ private:
struct ConflictList: public std::vector<ConflictPair> {};
std::vector<ConflictList> ConflictGraph;
+ // Compare directories after resolving symlinks.
+ bool IsSameDirectory(std::string const& l, std::string const& r);
+
+ std::string const& GetRealPath(std::string const& dir);
+ std::map<std::string, std::string> RealPaths;
+
friend class cmOrderDirectoriesConstraint;
friend class cmOrderDirectoriesConstraintLibrary;
};
diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx
new file mode 100644
index 000000000..5acae2f82
--- /dev/null
+++ b/Source/cmOutputConverter.cxx
@@ -0,0 +1,1065 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmOutputConverter.h"
+
+#include "cmAlgorithms.h"
+#include "cmake.h"
+
+#include <assert.h>
+
+#include <string.h> /* strlen */
+#include <ctype.h> /* isalpha */
+
+cmOutputConverter::cmOutputConverter(cmState::Snapshot snapshot)
+ : StateSnapshot(snapshot), LinkScriptShell(false)
+{
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmOutputConverter::ConvertToOutputForExistingCommon(const std::string& remote,
+ std::string const& result,
+ OutputFormat format) const
+{
+ // If this is a windows shell, the result has a space, and the path
+ // already exists, we can use a short-path to reference it without a
+ // space.
+ if(this->GetState()->UseWindowsShell() && result.find(' ') != result.npos &&
+ cmSystemTools::FileExists(remote.c_str()))
+ {
+ std::string tmp;
+ if(cmSystemTools::GetShortPath(remote, tmp))
+ {
+ return this->ConvertToOutputFormat(tmp, format);
+ }
+ }
+
+ // Otherwise, leave it unchanged.
+ return result;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmOutputConverter::ConvertToOutputForExisting(const std::string& remote,
+ RelativeRoot local,
+ OutputFormat format) const
+{
+ static_cast<void>(local);
+
+ // Perform standard conversion.
+ std::string result = this->ConvertToOutputFormat(remote, format);
+
+ // Consider short-path.
+ return this->ConvertToOutputForExistingCommon(remote, result, format);
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmOutputConverter::ConvertToOutputForExisting(RelativeRoot remote,
+ const std::string& local,
+ OutputFormat format) const
+{
+ // Perform standard conversion.
+ std::string result = this->Convert(remote, local, format, true);
+
+ // Consider short-path.
+ const char* remotePath = this->GetRelativeRootPath(remote);
+ return this->ConvertToOutputForExistingCommon(remotePath, result, format);
+}
+
+//----------------------------------------------------------------------------
+const char* cmOutputConverter::GetRelativeRootPath(RelativeRoot relroot) const
+{
+ switch (relroot)
+ {
+ case HOME:
+ return this->GetState()->GetSourceDirectory();
+ case START:
+ return this->StateSnapshot.GetDirectory().GetCurrentSource();
+ case HOME_OUTPUT:
+ return this->GetState()->GetBinaryDirectory();
+ case START_OUTPUT:
+ return this->StateSnapshot.GetDirectory().GetCurrentBinary();
+ default: break;
+ }
+ return 0;
+}
+
+std::string cmOutputConverter::Convert(const std::string& source,
+ RelativeRoot relative,
+ OutputFormat output) const
+{
+ // Convert the path to a relative path.
+ std::string result = source;
+
+ switch (relative)
+ {
+ case HOME:
+ result = this->ConvertToRelativePath(
+ this->GetState()->GetSourceDirectoryComponents(), result);
+ break;
+ case START:
+ result = this->ConvertToRelativePath(
+ this->StateSnapshot.GetDirectory().GetCurrentSourceComponents(),
+ result);
+ break;
+ case HOME_OUTPUT:
+ result = this->ConvertToRelativePath(
+ this->GetState()->GetBinaryDirectoryComponents(), result);
+ break;
+ case START_OUTPUT:
+ result = this->ConvertToRelativePath(
+ this->StateSnapshot.GetDirectory().GetCurrentBinaryComponents(),
+ result);
+ break;
+ case FULL:
+ result = cmSystemTools::CollapseFullPath(result);
+ break;
+ case NONE:
+ break;
+ }
+ return this->ConvertToOutputFormat(result, output);
+}
+
+//----------------------------------------------------------------------------
+std::string cmOutputConverter::ConvertToOutputFormat(const std::string& source,
+ OutputFormat output) const
+{
+ std::string result = source;
+ // Convert it to an output path.
+ if (output == MAKERULE)
+ {
+ result = cmSystemTools::ConvertToOutputPath(result.c_str());
+ }
+ else if(output == SHELL || output == WATCOMQUOTE)
+ {
+ result = this->ConvertDirectorySeparatorsForShell(source);
+ result = this->EscapeForShell(result, true, false, output == WATCOMQUOTE);
+ }
+ else if(output == RESPONSE)
+ {
+ result = this->EscapeForShell(result, false, false, false);
+ }
+ return result;
+}
+
+//----------------------------------------------------------------------------
+std::string cmOutputConverter::ConvertDirectorySeparatorsForShell(
+ const std::string& source) const
+{
+ std::string result = source;
+ // For the MSYS shell convert drive letters to posix paths, so
+ // that c:/some/path becomes /c/some/path. This is needed to
+ // avoid problems with the shell path translation.
+ if(this->GetState()->UseMSYSShell() && !this->LinkScriptShell)
+ {
+ if(result.size() > 2 && result[1] == ':')
+ {
+ result[1] = result[0];
+ result[0] = '/';
+ }
+ }
+ if(this->GetState()->UseWindowsShell())
+ {
+ std::replace(result.begin(), result.end(), '/', '\\');
+ }
+ return result;
+}
+
+//----------------------------------------------------------------------------
+std::string cmOutputConverter::Convert(RelativeRoot remote,
+ const std::string& local,
+ OutputFormat output,
+ bool optional) const
+{
+ const char* remotePath = this->GetRelativeRootPath(remote);
+
+ // The relative root must have a path (i.e. not FULL or NONE)
+ assert(remotePath != 0);
+
+ if(!local.empty() && !optional)
+ {
+ std::vector<std::string> components;
+ cmSystemTools::SplitPath(local, components);
+ std::string result = this->ConvertToRelativePath(components, remotePath);
+ return this->ConvertToOutputFormat(result, output);
+ }
+
+ return this->ConvertToOutputFormat(remotePath, output);
+}
+
+//----------------------------------------------------------------------------
+static bool cmOutputConverterNotAbove(const char* a, const char* b)
+{
+ return (cmSystemTools::ComparePath(a, b) ||
+ cmSystemTools::IsSubDirectory(a, b));
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmOutputConverter::ConvertToRelativePath(const std::vector<std::string>& local,
+ const std::string& in_remote,
+ bool force) const
+{
+ // The path should never be quoted.
+ assert(in_remote[0] != '\"');
+
+ // The local path should never have a trailing slash.
+ assert(!local.empty() && !(local[local.size()-1] == ""));
+
+ // If the path is already relative then just return the path.
+ if(!cmSystemTools::FileIsFullPath(in_remote.c_str()))
+ {
+ return in_remote;
+ }
+
+ if(!force)
+ {
+ // Skip conversion if the path and local are not both in the source
+ // or both in the binary tree.
+ std::string local_path = cmSystemTools::JoinPath(local);
+ if(!((cmOutputConverterNotAbove(local_path.c_str(),
+ this->StateSnapshot.GetDirectory().GetRelativePathTopBinary())
+ && cmOutputConverterNotAbove(in_remote.c_str(),
+ this->StateSnapshot.GetDirectory().GetRelativePathTopBinary()))
+ || (cmOutputConverterNotAbove(local_path.c_str(),
+ this->StateSnapshot.GetDirectory().GetRelativePathTopSource())
+ && cmOutputConverterNotAbove(in_remote.c_str(),
+ this->StateSnapshot.GetDirectory().GetRelativePathTopSource()))))
+ {
+ return in_remote;
+ }
+ }
+
+ // Identify the longest shared path component between the remote
+ // path and the local path.
+ std::vector<std::string> remote;
+ cmSystemTools::SplitPath(in_remote, remote);
+ unsigned int common=0;
+ while(common < remote.size() &&
+ common < local.size() &&
+ cmSystemTools::ComparePath(remote[common],
+ local[common]))
+ {
+ ++common;
+ }
+
+ // If no part of the path is in common then return the full path.
+ if(common == 0)
+ {
+ return in_remote;
+ }
+
+ // If the entire path is in common then just return a ".".
+ if(common == remote.size() &&
+ common == local.size())
+ {
+ return ".";
+ }
+
+ // If the entire path is in common except for a trailing slash then
+ // just return a "./".
+ if(common+1 == remote.size() &&
+ remote[common].empty() &&
+ common == local.size())
+ {
+ return "./";
+ }
+
+ // Construct the relative path.
+ std::string relative;
+
+ // First add enough ../ to get up to the level of the shared portion
+ // of the path. Leave off the trailing slash. Note that the last
+ // component of local will never be empty because local should never
+ // have a trailing slash.
+ for(unsigned int i=common; i < local.size(); ++i)
+ {
+ relative += "..";
+ if(i < local.size()-1)
+ {
+ relative += "/";
+ }
+ }
+
+ // Now add the portion of the destination path that is not included
+ // in the shared portion of the path. Add a slash the first time
+ // only if there was already something in the path. If there was a
+ // trailing slash in the input then the last iteration of the loop
+ // will add a slash followed by an empty string which will preserve
+ // the trailing slash in the output.
+
+ if(!relative.empty() && !remote.empty())
+ {
+ relative += "/";
+ }
+ relative += cmJoin(cmMakeRange(remote).advance(common), "/");
+
+ // Finally return the path.
+ return relative;
+}
+
+//----------------------------------------------------------------------------
+static bool cmOutputConverterIsShellOperator(const std::string& str)
+{
+ static std::set<std::string> shellOperators;
+ if(shellOperators.empty())
+ {
+ shellOperators.insert("<");
+ shellOperators.insert(">");
+ shellOperators.insert("<<");
+ shellOperators.insert(">>");
+ shellOperators.insert("|");
+ shellOperators.insert("||");
+ shellOperators.insert("&&");
+ shellOperators.insert("&>");
+ shellOperators.insert("1>");
+ shellOperators.insert("2>");
+ shellOperators.insert("2>&1");
+ shellOperators.insert("1>&2");
+ }
+ return shellOperators.count(str) > 0;
+}
+
+//----------------------------------------------------------------------------
+std::string cmOutputConverter::EscapeForShell(const std::string& str,
+ bool makeVars,
+ bool forEcho,
+ bool useWatcomQuote) const
+{
+ // Do not escape shell operators.
+ if(cmOutputConverterIsShellOperator(str))
+ {
+ return str;
+ }
+
+ // Compute the flags for the target shell environment.
+ int flags = 0;
+ if(this->GetState()->UseWindowsVSIDE())
+ {
+ flags |= Shell_Flag_VSIDE;
+ }
+ else if(!this->LinkScriptShell)
+ {
+ flags |= Shell_Flag_Make;
+ }
+ if(makeVars)
+ {
+ flags |= Shell_Flag_AllowMakeVariables;
+ }
+ if(forEcho)
+ {
+ flags |= Shell_Flag_EchoWindows;
+ }
+ if(useWatcomQuote)
+ {
+ flags |= Shell_Flag_WatcomQuote;
+ }
+ if(this->GetState()->UseWatcomWMake())
+ {
+ flags |= Shell_Flag_WatcomWMake;
+ }
+ if(this->GetState()->UseMinGWMake())
+ {
+ flags |= Shell_Flag_MinGWMake;
+ }
+ if(this->GetState()->UseNMake())
+ {
+ flags |= Shell_Flag_NMake;
+ }
+
+ // Compute the buffer size needed.
+ int size = (this->GetState()->UseWindowsShell() ?
+ Shell_GetArgumentSizeForWindows(str.c_str(), flags) :
+ Shell_GetArgumentSizeForUnix(str.c_str(), flags));
+
+ // Compute the shell argument itself.
+ std::vector<char> arg(size);
+ if(this->GetState()->UseWindowsShell())
+ {
+ Shell_GetArgumentForWindows(str.c_str(), &arg[0], flags);
+ }
+ else
+ {
+ Shell_GetArgumentForUnix(str.c_str(), &arg[0], flags);
+ }
+ return std::string(&arg[0]);
+}
+
+//----------------------------------------------------------------------------
+std::string cmOutputConverter::EscapeForCMake(const std::string& str)
+{
+ // Always double-quote the argument to take care of most escapes.
+ std::string result = "\"";
+ for(const char* c = str.c_str(); *c; ++c)
+ {
+ if(*c == '"')
+ {
+ // Escape the double quote to avoid ending the argument.
+ result += "\\\"";
+ }
+ else if(*c == '$')
+ {
+ // Escape the dollar to avoid expanding variables.
+ result += "\\$";
+ }
+ else if(*c == '\\')
+ {
+ // Escape the backslash to avoid other escapes.
+ result += "\\\\";
+ }
+ else
+ {
+ // Other characters will be parsed correctly.
+ result += *c;
+ }
+ }
+ result += "\"";
+ return result;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmOutputConverter::EscapeWindowsShellArgument(const char* arg, int shell_flags)
+{
+ char local_buffer[1024];
+ char* buffer = local_buffer;
+ int size = Shell_GetArgumentSizeForWindows(arg, shell_flags);
+ if(size > 1024)
+ {
+ buffer = new char[size];
+ }
+ Shell_GetArgumentForWindows(arg, buffer, shell_flags);
+ std::string result(buffer);
+ if(buffer != local_buffer)
+ {
+ delete [] buffer;
+ }
+ return result;
+}
+
+//----------------------------------------------------------------------------
+cmOutputConverter::FortranFormat
+cmOutputConverter::GetFortranFormat(const char* value)
+{
+ FortranFormat format = FortranFormatNone;
+ if(value && *value)
+ {
+ std::vector<std::string> fmt;
+ cmSystemTools::ExpandListArgument(value, fmt);
+ for(std::vector<std::string>::iterator fi = fmt.begin();
+ fi != fmt.end(); ++fi)
+ {
+ if(*fi == "FIXED")
+ {
+ format = FortranFormatFixed;
+ }
+ if(*fi == "FREE")
+ {
+ format = FortranFormatFree;
+ }
+ }
+ }
+ return format;
+}
+
+void cmOutputConverter::SetLinkScriptShell(bool linkScriptShell)
+{
+ this->LinkScriptShell = linkScriptShell;
+}
+
+cmState* cmOutputConverter::GetState() const
+{
+ return this->StateSnapshot.GetState();
+}
+
+//----------------------------------------------------------------------------
+/*
+
+Notes:
+
+Make variable replacements open a can of worms. Sometimes they should
+be quoted and sometimes not. Sometimes their replacement values are
+already quoted.
+
+VS variables cause problems. In order to pass the referenced value
+with spaces the reference must be quoted. If the variable value ends
+in a backslash then it will escape the ending quote! In order to make
+the ending backslash appear we need this:
+
+ "$(InputDir)\"
+
+However if there is not a trailing backslash then this will put a
+quote in the value so we need:
+
+ "$(InputDir)"
+
+Make variable references are platform specific so we should probably
+just NOT quote them and let the listfile author deal with it.
+
+*/
+
+/*
+TODO: For windows echo:
+
+To display a pipe (|) or redirection character (< or >) when using the
+echo command, use a caret character immediately before the pipe or
+redirection character (for example, ^>, ^<, or ^| ). If you need to
+use the caret character itself (^), use two in a row (^^).
+*/
+
+/*--------------------------------------------------------------------------*/
+int cmOutputConverter::Shell__CharIsWhitespace(char c)
+{
+ return ((c == ' ') || (c == '\t'));
+}
+
+/*--------------------------------------------------------------------------*/
+int cmOutputConverter::Shell__CharNeedsQuotesOnUnix(char c)
+{
+ return ((c == '\'') || (c == '`') || (c == ';') || (c == '#') ||
+ (c == '&') || (c == '$') || (c == '(') || (c == ')') ||
+ (c == '~') || (c == '<') || (c == '>') || (c == '|') ||
+ (c == '*') || (c == '^') || (c == '\\'));
+}
+
+/*--------------------------------------------------------------------------*/
+int cmOutputConverter::Shell__CharNeedsQuotesOnWindows(char c)
+{
+ return ((c == '\'') || (c == '#') || (c == '&') ||
+ (c == '<') || (c == '>') || (c == '|') || (c == '^'));
+}
+
+/*--------------------------------------------------------------------------*/
+int cmOutputConverter::Shell__CharNeedsQuotes(char c, int isUnix, int flags)
+{
+ /* On Windows the built-in command shell echo never needs quotes. */
+ if(!isUnix && (flags & Shell_Flag_EchoWindows))
+ {
+ return 0;
+ }
+
+ /* On all platforms quotes are needed to preserve whitespace. */
+ if(Shell__CharIsWhitespace(c))
+ {
+ return 1;
+ }
+
+ if(isUnix)
+ {
+ /* On UNIX several special characters need quotes to preserve them. */
+ if(Shell__CharNeedsQuotesOnUnix(c))
+ {
+ return 1;
+ }
+ }
+ else
+ {
+ /* On Windows several special characters need quotes to preserve them. */
+ if(Shell__CharNeedsQuotesOnWindows(c))
+ {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/*--------------------------------------------------------------------------*/
+int cmOutputConverter::Shell__CharIsMakeVariableName(char c)
+{
+ return c && (c == '_' || isalpha(((int)c)));
+}
+
+/*--------------------------------------------------------------------------*/
+const char* cmOutputConverter::Shell__SkipMakeVariables(const char* c)
+{
+ while(*c == '$' && *(c+1) == '(')
+ {
+ const char* skip = c+2;
+ while(Shell__CharIsMakeVariableName(*skip))
+ {
+ ++skip;
+ }
+ if(*skip == ')')
+ {
+ c = skip+1;
+ }
+ else
+ {
+ break;
+ }
+ }
+ return c;
+}
+
+/*
+Allowing make variable replacements opens a can of worms. Sometimes
+they should be quoted and sometimes not. Sometimes their replacement
+values are already quoted or contain escapes.
+
+Some Visual Studio variables cause problems. In order to pass the
+referenced value with spaces the reference must be quoted. If the
+variable value ends in a backslash then it will escape the ending
+quote! In order to make the ending backslash appear we need this:
+
+ "$(InputDir)\"
+
+However if there is not a trailing backslash then this will put a
+quote in the value so we need:
+
+ "$(InputDir)"
+
+This macro decides whether we quote an argument just because it
+contains a make variable reference. This should be replaced with a
+flag later when we understand applications of this better.
+*/
+#define KWSYS_SYSTEM_SHELL_QUOTE_MAKE_VARIABLES 0
+
+/*--------------------------------------------------------------------------*/
+int cmOutputConverter::Shell__ArgumentNeedsQuotes(const char* in,
+ int isUnix, int flags)
+{
+ /* The empty string needs quotes. */
+ if(!*in)
+ {
+ return 1;
+ }
+
+ /* Scan the string for characters that require quoting. */
+ {
+ const char* c;
+ for(c=in; *c; ++c)
+ {
+ /* Look for $(MAKEVAR) syntax if requested. */
+ if(flags & Shell_Flag_AllowMakeVariables)
+ {
+#if KWSYS_SYSTEM_SHELL_QUOTE_MAKE_VARIABLES
+ const char* skip = Shell__SkipMakeVariables(c);
+ if(skip != c)
+ {
+ /* We need to quote make variable references to preserve the
+ string with contents substituted in its place. */
+ return 1;
+ }
+#else
+ /* Skip over the make variable references if any are present. */
+ c = Shell__SkipMakeVariables(c);
+
+ /* Stop if we have reached the end of the string. */
+ if(!*c)
+ {
+ break;
+ }
+#endif
+ }
+
+ /* Check whether this character needs quotes. */
+ if(Shell__CharNeedsQuotes(*c, isUnix, flags))
+ {
+ return 1;
+ }
+ }
+ }
+
+ /* On Windows some single character arguments need quotes. */
+ if(!isUnix && *in && !*(in+1))
+ {
+ char c = *in;
+ if((c == '?') || (c == '&') || (c == '^') || (c == '|') || (c == '#'))
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/*--------------------------------------------------------------------------*/
+int cmOutputConverter::Shell__GetArgumentSize(const char* in,
+ int isUnix, int flags)
+{
+ /* Start with the length of the original argument, plus one for
+ either a terminating null or a separating space. */
+ int size = (int)strlen(in) + 1;
+
+ /* String iterator. */
+ const char* c;
+
+ /* Keep track of how many backslashes have been encountered in a row. */
+ int windows_backslashes = 0;
+
+ /* Scan the string for characters that require escaping or quoting. */
+ for(c=in; *c; ++c)
+ {
+ /* Look for $(MAKEVAR) syntax if requested. */
+ if(flags & Shell_Flag_AllowMakeVariables)
+ {
+ /* Skip over the make variable references if any are present. */
+ c = Shell__SkipMakeVariables(c);
+
+ /* Stop if we have reached the end of the string. */
+ if(!*c)
+ {
+ break;
+ }
+ }
+
+ /* Check whether this character needs escaping for the shell. */
+ if(isUnix)
+ {
+ /* On Unix a few special characters need escaping even inside a
+ quoted argument. */
+ if(*c == '\\' || *c == '"' || *c == '`' || *c == '$')
+ {
+ /* This character needs a backslash to escape it. */
+ ++size;
+ }
+ }
+ else if(flags & Shell_Flag_EchoWindows)
+ {
+ /* On Windows the built-in command shell echo never needs escaping. */
+ }
+ else
+ {
+ /* On Windows only backslashes and double-quotes need escaping. */
+ if(*c == '\\')
+ {
+ /* Found a backslash. It may need to be escaped later. */
+ ++windows_backslashes;
+ }
+ else if(*c == '"')
+ {
+ /* Found a double-quote. We need to escape it and all
+ immediately preceding backslashes. */
+ size += windows_backslashes + 1;
+ windows_backslashes = 0;
+ }
+ else
+ {
+ /* Found another character. This eliminates the possibility
+ that any immediately preceding backslashes will be
+ escaped. */
+ windows_backslashes = 0;
+ }
+ }
+
+ /* Check whether this character needs escaping for a make tool. */
+ if(*c == '$')
+ {
+ if(flags & Shell_Flag_Make)
+ {
+ /* In Makefiles a dollar is written $$ so we need one extra
+ character. */
+ ++size;
+ }
+ else if(flags & Shell_Flag_VSIDE)
+ {
+ /* In a VS IDE a dollar is written "$" so we need two extra
+ characters. */
+ size += 2;
+ }
+ }
+ else if(*c == '#')
+ {
+ if((flags & Shell_Flag_Make) &&
+ (flags & Shell_Flag_WatcomWMake))
+ {
+ /* In Watcom WMake makefiles a pound is written $# so we need
+ one extra character. */
+ ++size;
+ }
+ }
+ else if(*c == '%')
+ {
+ if((flags & Shell_Flag_VSIDE) ||
+ ((flags & Shell_Flag_Make) &&
+ ((flags & Shell_Flag_MinGWMake) ||
+ (flags & Shell_Flag_NMake))))
+ {
+ /* In the VS IDE, NMake, or MinGW make a percent is written %%
+ so we need one extra characters. */
+ size += 1;
+ }
+ }
+ else if(*c == ';')
+ {
+ if(flags & Shell_Flag_VSIDE)
+ {
+ /* In a VS IDE a semicolon is written ";" so we need two extra
+ characters. */
+ size += 2;
+ }
+ }
+ }
+
+ /* Check whether the argument needs surrounding quotes. */
+ if(Shell__ArgumentNeedsQuotes(in, isUnix, flags))
+ {
+ /* Surrounding quotes are needed. Allocate space for them. */
+ if((flags & Shell_Flag_WatcomQuote) && (isUnix))
+ {
+ size += 2;
+ }
+ size += 2;
+
+ /* We must escape all ending backslashes when quoting on windows. */
+ size += windows_backslashes;
+ }
+
+ return size;
+}
+
+/*--------------------------------------------------------------------------*/
+char* cmOutputConverter::Shell__GetArgument(const char* in, char* out,
+ int isUnix, int flags)
+{
+ /* String iterator. */
+ const char* c;
+
+ /* Keep track of how many backslashes have been encountered in a row. */
+ int windows_backslashes = 0;
+
+ /* Whether the argument must be quoted. */
+ int needQuotes = Shell__ArgumentNeedsQuotes(in, isUnix, flags);
+ if(needQuotes)
+ {
+ /* Add the opening quote for this argument. */
+ if(flags & Shell_Flag_WatcomQuote)
+ {
+ if(isUnix)
+ {
+ *out++ = '"';
+ }
+ *out++ = '\'';
+ }
+ else
+ {
+ *out++ = '"';
+ }
+ }
+
+ /* Scan the string for characters that require escaping or quoting. */
+ for(c=in; *c; ++c)
+ {
+ /* Look for $(MAKEVAR) syntax if requested. */
+ if(flags & Shell_Flag_AllowMakeVariables)
+ {
+ const char* skip = Shell__SkipMakeVariables(c);
+ if(skip != c)
+ {
+ /* Copy to the end of the make variable references. */
+ while(c != skip)
+ {
+ *out++ = *c++;
+ }
+
+ /* The make variable reference eliminates any escaping needed
+ for preceding backslashes. */
+ windows_backslashes = 0;
+
+ /* Stop if we have reached the end of the string. */
+ if(!*c)
+ {
+ break;
+ }
+ }
+ }
+
+ /* Check whether this character needs escaping for the shell. */
+ if(isUnix)
+ {
+ /* On Unix a few special characters need escaping even inside a
+ quoted argument. */
+ if(*c == '\\' || *c == '"' || *c == '`' || *c == '$')
+ {
+ /* This character needs a backslash to escape it. */
+ *out++ = '\\';
+ }
+ }
+ else if(flags & Shell_Flag_EchoWindows)
+ {
+ /* On Windows the built-in command shell echo never needs escaping. */
+ }
+ else
+ {
+ /* On Windows only backslashes and double-quotes need escaping. */
+ if(*c == '\\')
+ {
+ /* Found a backslash. It may need to be escaped later. */
+ ++windows_backslashes;
+ }
+ else if(*c == '"')
+ {
+ /* Found a double-quote. Escape all immediately preceding
+ backslashes. */
+ while(windows_backslashes > 0)
+ {
+ --windows_backslashes;
+ *out++ = '\\';
+ }
+
+ /* Add the backslash to escape the double-quote. */
+ *out++ = '\\';
+ }
+ else
+ {
+ /* We encountered a normal character. This eliminates any
+ escaping needed for preceding backslashes. */
+ windows_backslashes = 0;
+ }
+ }
+
+ /* Check whether this character needs escaping for a make tool. */
+ if(*c == '$')
+ {
+ if(flags & Shell_Flag_Make)
+ {
+ /* In Makefiles a dollar is written $$. The make tool will
+ replace it with just $ before passing it to the shell. */
+ *out++ = '$';
+ *out++ = '$';
+ }
+ else if(flags & Shell_Flag_VSIDE)
+ {
+ /* In a VS IDE a dollar is written "$". If this is written in
+ an un-quoted argument it starts a quoted segment, inserts
+ the $ and ends the segment. If it is written in a quoted
+ argument it ends quoting, inserts the $ and restarts
+ quoting. Either way the $ is isolated from surrounding
+ text to avoid looking like a variable reference. */
+ *out++ = '"';
+ *out++ = '$';
+ *out++ = '"';
+ }
+ else
+ {
+ /* Otherwise a dollar is written just $. */
+ *out++ = '$';
+ }
+ }
+ else if(*c == '#')
+ {
+ if((flags & Shell_Flag_Make) &&
+ (flags & Shell_Flag_WatcomWMake))
+ {
+ /* In Watcom WMake makefiles a pound is written $#. The make
+ tool will replace it with just # before passing it to the
+ shell. */
+ *out++ = '$';
+ *out++ = '#';
+ }
+ else
+ {
+ /* Otherwise a pound is written just #. */
+ *out++ = '#';
+ }
+ }
+ else if(*c == '%')
+ {
+ if((flags & Shell_Flag_VSIDE) ||
+ ((flags & Shell_Flag_Make) &&
+ ((flags & Shell_Flag_MinGWMake) ||
+ (flags & Shell_Flag_NMake))))
+ {
+ /* In the VS IDE, NMake, or MinGW make a percent is written %%. */
+ *out++ = '%';
+ *out++ = '%';
+ }
+ else
+ {
+ /* Otherwise a percent is written just %. */
+ *out++ = '%';
+ }
+ }
+ else if(*c == ';')
+ {
+ if(flags & Shell_Flag_VSIDE)
+ {
+ /* In a VS IDE a semicolon is written ";". If this is written
+ in an un-quoted argument it starts a quoted segment,
+ inserts the ; and ends the segment. If it is written in a
+ quoted argument it ends quoting, inserts the ; and restarts
+ quoting. Either way the ; is isolated. */
+ *out++ = '"';
+ *out++ = ';';
+ *out++ = '"';
+ }
+ else
+ {
+ /* Otherwise a semicolon is written just ;. */
+ *out++ = ';';
+ }
+ }
+ else
+ {
+ /* Store this character. */
+ *out++ = *c;
+ }
+ }
+
+ if(needQuotes)
+ {
+ /* Add enough backslashes to escape any trailing ones. */
+ while(windows_backslashes > 0)
+ {
+ --windows_backslashes;
+ *out++ = '\\';
+ }
+
+ /* Add the closing quote for this argument. */
+ if(flags & Shell_Flag_WatcomQuote)
+ {
+ *out++ = '\'';
+ if(isUnix)
+ {
+ *out++ = '"';
+ }
+ }
+ else
+ {
+ *out++ = '"';
+ }
+ }
+
+ /* Store a terminating null without incrementing. */
+ *out = 0;
+
+ return out;
+}
+
+/*--------------------------------------------------------------------------*/
+char* cmOutputConverter::Shell_GetArgumentForWindows(const char* in,
+ char* out, int flags)
+{
+ return Shell__GetArgument(in, out, 0, flags);
+}
+
+/*--------------------------------------------------------------------------*/
+char* cmOutputConverter::Shell_GetArgumentForUnix(const char* in,
+ char* out, int flags)
+{
+ return Shell__GetArgument(in, out, 1, flags);
+}
+
+/*--------------------------------------------------------------------------*/
+int cmOutputConverter::Shell_GetArgumentSizeForWindows(const char* in,
+ int flags)
+{
+ return Shell__GetArgumentSize(in, 0, flags);
+}
+
+/*--------------------------------------------------------------------------*/
+int cmOutputConverter::Shell_GetArgumentSizeForUnix(const char* in,
+ int flags)
+{
+ return Shell__GetArgumentSize(in, 1, flags);
+}
diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h
new file mode 100644
index 000000000..852df5d26
--- /dev/null
+++ b/Source/cmOutputConverter.h
@@ -0,0 +1,183 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmOutputConverter_h
+#define cmOutputConverter_h
+
+#include "cmStandardIncludes.h"
+
+#include "cmGlobalGenerator.h"
+#include "cmState.h"
+
+class cmOutputConverter
+{
+public:
+ cmOutputConverter(cmState::Snapshot snapshot);
+
+ /**
+ * Convert something to something else. This is a centralized conversion
+ * routine used by the generators to handle relative paths and the like.
+ * The flags determine what is actually done.
+ *
+ * relative: treat the argument as a directory and convert it to make it
+ * relative or full or unchanged. If relative (HOME, START etc) then that
+ * specifies what it should be relative to.
+ *
+ * output: make the result suitable for output to a...
+ *
+ * optional: should any relative path operation be controlled by the rel
+ * path setting
+ */
+ enum RelativeRoot { NONE, FULL, HOME, START, HOME_OUTPUT, START_OUTPUT };
+ enum OutputFormat { UNCHANGED, MAKERULE, SHELL, WATCOMQUOTE, RESPONSE };
+ std::string ConvertToOutputFormat(const std::string& source,
+ OutputFormat output) const;
+ std::string Convert(const std::string& remote, RelativeRoot local,
+ OutputFormat output = UNCHANGED) const;
+ std::string Convert(RelativeRoot remote, const std::string& local,
+ OutputFormat output = UNCHANGED,
+ bool optional = false) const;
+ std::string ConvertDirectorySeparatorsForShell(
+ const std::string& source) const;
+
+ /**
+ * Get path for the specified relative root.
+ */
+ const char* GetRelativeRootPath(RelativeRoot relroot) const;
+
+ ///! for existing files convert to output path and short path if spaces
+ std::string ConvertToOutputForExisting(const std::string& remote,
+ RelativeRoot local = START_OUTPUT,
+ OutputFormat format = SHELL) const;
+
+ /** For existing path identified by RelativeRoot convert to output
+ path and short path if spaces. */
+ std::string ConvertToOutputForExisting(RelativeRoot remote,
+ const std::string& local = "",
+ OutputFormat format = SHELL) const;
+
+ void SetLinkScriptShell(bool linkScriptShell);
+
+ /**
+ * Flags to pass to Shell_GetArgumentForWindows or
+ * Shell_GetArgumentForUnix. These modify the generated
+ * quoting and escape sequences to work under alternative
+ * environments.
+ */
+ enum Shell_Flag_e
+ {
+ /** The target shell is in a makefile. */
+ Shell_Flag_Make = (1<<0),
+
+ /** The target shell is in a VS project file. Do not use with
+ Shell_Flag_Make. */
+ Shell_Flag_VSIDE = (1<<1),
+
+ /** In a windows shell the argument is being passed to "echo". */
+ Shell_Flag_EchoWindows = (1<<2),
+
+ /** The target shell is in a Watcom WMake makefile. */
+ Shell_Flag_WatcomWMake = (1<<3),
+
+ /** The target shell is in a MinGW Make makefile. */
+ Shell_Flag_MinGWMake = (1<<4),
+
+ /** The target shell is in a NMake makefile. */
+ Shell_Flag_NMake = (1<<5),
+
+ /** Make variable reference syntax $(MAKEVAR) should not be escaped
+ to allow a build tool to replace it. Replacement values
+ containing spaces, quotes, backslashes, or other
+ non-alphanumeric characters that have significance to some makes
+ or shells produce undefined behavior. */
+ Shell_Flag_AllowMakeVariables = (1<<6),
+
+ /** The target shell quoting uses extra single Quotes for Watcom tools. */
+ Shell_Flag_WatcomQuote = (1<<7)
+ };
+
+ /**
+ * Transform the given command line argument for use in a Windows or
+ * Unix shell. Returns a pointer to the end of the command line
+ * argument in the provided output buffer. Flags may be passed to
+ * modify the generated quoting and escape sequences to work under
+ * alternative environments.
+ */
+ static char* Shell_GetArgumentForWindows(const char* in, char* out,
+ int flags);
+ static char* Shell_GetArgumentForUnix(const char* in, char* out, int flags);
+
+ /**
+ * Compute the size of the buffer required to store the output from
+ * Shell_GetArgumentForWindows or Shell_GetArgumentForUnix. The flags
+ * passed must be identical between the two calls.
+ */
+ static int Shell_GetArgumentSizeForWindows(const char* in, int flags);
+ static int Shell_GetArgumentSizeForUnix(const char* in, int flags);
+
+ std::string EscapeForShell(const std::string& str,
+ bool makeVars = false,
+ bool forEcho = false,
+ bool useWatcomQuote = false) const;
+
+ static std::string EscapeForCMake(const std::string& str);
+
+ /** Compute an escaped version of the given argument for use in a
+ windows shell. */
+ static std::string EscapeWindowsShellArgument(const char* arg,
+ int shell_flags);
+
+ enum FortranFormat
+ {
+ FortranFormatNone,
+ FortranFormatFixed,
+ FortranFormatFree
+ };
+ static FortranFormat GetFortranFormat(const char* value);
+
+ /**
+ * Convert the given remote path to a relative path with respect to
+ * the given local path. The local path must be given in component
+ * form (see SystemTools::SplitPath) without a trailing slash. The
+ * remote path must use forward slashes and not already be escaped
+ * or quoted.
+ */
+ std::string ConvertToRelativePath(const std::vector<std::string>& local,
+ const std::string& in_remote,
+ bool force = false) const;
+
+private:
+ cmState* GetState() const;
+
+ std::string ConvertToOutputForExistingCommon(const std::string& remote,
+ std::string const& result,
+ OutputFormat format) const;
+
+ static int Shell__CharIsWhitespace(char c);
+ static int Shell__CharNeedsQuotesOnUnix(char c);
+ static int Shell__CharNeedsQuotesOnWindows(char c);
+ static int Shell__CharNeedsQuotes(char c, int isUnix, int flags);
+ static int Shell__CharIsMakeVariableName(char c);
+ static const char* Shell__SkipMakeVariables(const char* c);
+ static int Shell__ArgumentNeedsQuotes(const char* in,
+ int isUnix, int flags);
+ static int Shell__GetArgumentSize(const char* in,
+ int isUnix, int flags);
+ static char* Shell__GetArgument(const char* in, char* out,
+ int isUnix, int flags);
+
+private:
+ cmState::Snapshot StateSnapshot;
+
+ bool LinkScriptShell;
+};
+
+#endif
diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx
index 01fc2cf8a..54208acbe 100644
--- a/Source/cmOutputRequiredFilesCommand.cxx
+++ b/Source/cmOutputRequiredFilesCommand.cxx
@@ -10,106 +10,239 @@
See the License for more information.
============================================================================*/
#include "cmOutputRequiredFilesCommand.h"
-#include "cmMakeDepend.h"
+#include "cmAlgorithms.h"
+#include <cmsys/FStream.hxx>
-class cmLBDepend : public cmMakeDepend
+/** \class cmDependInformation
+ * \brief Store dependency information for a single source file.
+ *
+ * This structure stores the depend information for a single source file.
+ */
+class cmDependInformation
{
+public:
/**
- * Compute the depend information for this class.
+ * Construct with dependency generation marked not done; instance
+ * not placed in cmMakefile's list.
*/
- virtual void DependWalk(cmDependInformation* info);
-};
+ cmDependInformation(): DependDone(false), SourceFile(0) {}
-void cmLBDepend::DependWalk(cmDependInformation* info)
-{
- std::ifstream fin(info->FullPath.c_str());
- if(!fin)
+ /**
+ * The set of files on which this one depends.
+ */
+ typedef std::set<cmDependInformation*> DependencySetType;
+ DependencySetType DependencySet;
+
+ /**
+ * This flag indicates whether dependency checking has been
+ * performed for this file.
+ */
+ bool DependDone;
+
+ /**
+ * If this object corresponds to a cmSourceFile instance, this points
+ * to it.
+ */
+ const cmSourceFile *SourceFile;
+
+ /**
+ * Full path to this file.
+ */
+ std::string FullPath;
+
+ /**
+ * Full path not including file name.
+ */
+ std::string PathOnly;
+
+ /**
+ * Name used to #include this file.
+ */
+ std::string IncludeName;
+
+ /**
+ * This method adds the dependencies of another file to this one.
+ */
+ void AddDependencies(cmDependInformation* info)
+ {
+ if(this != info)
{
- cmSystemTools::Error("error can not open ", info->FullPath.c_str());
- return;
+ this->DependencySet.insert(info);
}
+ }
+};
- std::string line;
- while(cmSystemTools::GetLineFromStream(fin, line))
- {
- if(!strncmp(line.c_str(), "#include", 8))
- {
- // if it is an include line then create a string class
- std::string currentline = line;
- size_t qstart = currentline.find('\"', 8);
- size_t qend;
- // if a quote is not found look for a <
- if(qstart == std::string::npos)
- {
- qstart = currentline.find('<', 8);
- // if a < is not found then move on
- if(qstart == std::string::npos)
- {
- cmSystemTools::Error("unknown include directive ",
- currentline.c_str() );
- continue;
- }
- else
- {
- qend = currentline.find('>', qstart+1);
- }
- }
- else
+class cmLBDepend
+{
+public:
+ /**
+ * Construct the object with verbose turned off.
+ */
+ cmLBDepend()
+ {
+ this->Verbose = false;
+ this->IncludeFileRegularExpression.compile("^.*$");
+ this->ComplainFileRegularExpression.compile("^$");
+ }
+
+ /**
+ * Destructor.
+ */
+ ~cmLBDepend()
+ {
+ cmDeleteAll(this->DependInformationMap);
+ }
+
+ /**
+ * Set the makefile that is used as a source of classes.
+ */
+ void SetMakefile(cmMakefile* makefile)
+ {
+ this->Makefile = makefile;
+
+ // Now extract the include file regular expression from the makefile.
+ this->IncludeFileRegularExpression.compile(
+ this->Makefile->GetIncludeRegularExpression());
+ this->ComplainFileRegularExpression.compile(
+ this->Makefile->GetComplainRegularExpression());
+
+ // Now extract any include paths from the targets
+ std::set<std::string> uniqueIncludes;
+ std::vector<std::string> orderedAndUniqueIncludes;
+ cmTargets &targets = this->Makefile->GetTargets();
+ for (cmTargets::iterator l = targets.begin();
+ l != targets.end(); ++l)
+ {
+ const char *incDirProp = l->second.GetProperty("INCLUDE_DIRECTORIES");
+ if (!incDirProp)
{
- qend = currentline.find('\"', qstart+1);
+ continue;
}
- // extract the file being included
- std::string includeFile = currentline.substr(qstart+1, qend - qstart-1);
- // see if the include matches the regular expression
- if(!this->IncludeFileRegularExpression.find(includeFile))
+
+ std::string incDirs =
+ cmGeneratorExpression::Preprocess(incDirProp,
+ cmGeneratorExpression::StripAllGeneratorExpressions);
+
+ std::vector<std::string> includes;
+ cmSystemTools::ExpandListArgument(incDirs, includes);
+
+ for(std::vector<std::string>::const_iterator j = includes.begin();
+ j != includes.end(); ++j)
{
- if(this->Verbose)
+ std::string path = *j;
+ this->Makefile->ExpandVariablesInString(path);
+ if(uniqueIncludes.insert(path).second)
{
- std::string message = "Skipping ";
- message += includeFile;
- message += " for file ";
- message += info->FullPath.c_str();
- cmSystemTools::Error(message.c_str(), 0);
+ orderedAndUniqueIncludes.push_back(path);
}
- continue;
}
+ }
- // Add this file and all its dependencies.
- this->AddDependency(info, includeFile.c_str());
- /// add the cxx file if it exists
- std::string cxxFile = includeFile;
- std::string::size_type pos = cxxFile.rfind('.');
- if(pos != std::string::npos)
+ for(std::vector<std::string>::const_iterator
+ it = orderedAndUniqueIncludes.begin();
+ it != orderedAndUniqueIncludes.end();
+ ++it)
+ {
+ this->AddSearchPath(*it);
+ }
+ }
+
+ /**
+ * Add a directory to the search path for include files.
+ */
+ void AddSearchPath(const std::string& path)
+ {
+ this->IncludeDirectories.push_back(path);
+ }
+
+ /**
+ * Generate dependencies for the file given. Returns a pointer to
+ * the cmDependInformation object for the file.
+ */
+ const cmDependInformation* FindDependencies(const char* file)
+ {
+ cmDependInformation* info = this->GetDependInformation(file,0);
+ this->GenerateDependInformation(info);
+ return info;
+ }
+
+protected:
+ /**
+ * Compute the depend information for this class.
+ */
+
+ void DependWalk(cmDependInformation* info)
+ {
+ cmsys::ifstream fin(info->FullPath.c_str());
+ if(!fin)
+ {
+ cmSystemTools::Error("error can not open ", info->FullPath.c_str());
+ return;
+ }
+
+ std::string line;
+ while(cmSystemTools::GetLineFromStream(fin, line))
+ {
+ if(cmHasLiteralPrefix(line.c_str(), "#include"))
{
- std::string root = cxxFile.substr(0, pos);
- cxxFile = root + ".cxx";
- bool found = false;
- // try jumping to .cxx .cpp and .c in order
- if(cmSystemTools::FileExists(cxxFile.c_str()))
+ // if it is an include line then create a string class
+ std::string currentline = line;
+ size_t qstart = currentline.find('\"', 8);
+ size_t qend;
+ // if a quote is not found look for a <
+ if(qstart == std::string::npos)
{
- found = true;
+ qstart = currentline.find('<', 8);
+ // if a < is not found then move on
+ if(qstart == std::string::npos)
+ {
+ cmSystemTools::Error("unknown include directive ",
+ currentline.c_str() );
+ continue;
+ }
+ else
+ {
+ qend = currentline.find('>', qstart+1);
+ }
}
- for(std::vector<std::string>::iterator i =
- this->IncludeDirectories.begin();
- i != this->IncludeDirectories.end(); ++i)
+ else
+ {
+ qend = currentline.find('\"', qstart+1);
+ }
+ // extract the file being included
+ std::string includeFile =
+ currentline.substr(qstart+1, qend - qstart-1);
+ // see if the include matches the regular expression
+ if(!this->IncludeFileRegularExpression.find(includeFile))
{
- std::string path = *i;
- path = path + "/";
- path = path + cxxFile;
- if(cmSystemTools::FileExists(path.c_str()))
+ if(this->Verbose)
{
- found = true;
+ std::string message = "Skipping ";
+ message += includeFile;
+ message += " for file ";
+ message += info->FullPath.c_str();
+ cmSystemTools::Error(message.c_str(), 0);
}
+ continue;
}
- if (!found)
+
+ // Add this file and all its dependencies.
+ this->AddDependency(info, includeFile.c_str());
+ /// add the cxx file if it exists
+ std::string cxxFile = includeFile;
+ std::string::size_type pos = cxxFile.rfind('.');
+ if(pos != std::string::npos)
{
- cxxFile = root + ".cpp";
+ std::string root = cxxFile.substr(0, pos);
+ cxxFile = root + ".cxx";
+ bool found = false;
+ // try jumping to .cxx .cpp and .c in order
if(cmSystemTools::FileExists(cxxFile.c_str()))
{
found = true;
}
for(std::vector<std::string>::iterator i =
- this->IncludeDirectories.begin();
+ this->IncludeDirectories.begin();
i != this->IncludeDirectories.end(); ++i)
{
std::string path = *i;
@@ -120,60 +253,322 @@ void cmLBDepend::DependWalk(cmDependInformation* info)
found = true;
}
}
- }
- if (!found)
- {
- cxxFile = root + ".c";
- if(cmSystemTools::FileExists(cxxFile.c_str()))
+ if (!found)
{
- found = true;
- }
- for(std::vector<std::string>::iterator i =
- this->IncludeDirectories.begin();
- i != this->IncludeDirectories.end(); ++i)
- {
- std::string path = *i;
- path = path + "/";
- path = path + cxxFile;
- if(cmSystemTools::FileExists(path.c_str()))
+ cxxFile = root + ".cpp";
+ if(cmSystemTools::FileExists(cxxFile.c_str()))
{
found = true;
}
+ for(std::vector<std::string>::iterator i =
+ this->IncludeDirectories.begin();
+ i != this->IncludeDirectories.end(); ++i)
+ {
+ std::string path = *i;
+ path = path + "/";
+ path = path + cxxFile;
+ if(cmSystemTools::FileExists(path.c_str()))
+ {
+ found = true;
+ }
+ }
}
- }
- if (!found)
- {
- cxxFile = root + ".txx";
- if(cmSystemTools::FileExists(cxxFile.c_str()))
+ if (!found)
{
- found = true;
- }
- for(std::vector<std::string>::iterator i =
+ cxxFile = root + ".c";
+ if(cmSystemTools::FileExists(cxxFile.c_str()))
+ {
+ found = true;
+ }
+ for(std::vector<std::string>::iterator i =
this->IncludeDirectories.begin();
- i != this->IncludeDirectories.end(); ++i)
+ i != this->IncludeDirectories.end(); ++i)
+ {
+ std::string path = *i;
+ path = path + "/";
+ path = path + cxxFile;
+ if(cmSystemTools::FileExists(path.c_str()))
+ {
+ found = true;
+ }
+ }
+ }
+ if (!found)
{
- std::string path = *i;
- path = path + "/";
- path = path + cxxFile;
- if(cmSystemTools::FileExists(path.c_str()))
+ cxxFile = root + ".txx";
+ if(cmSystemTools::FileExists(cxxFile.c_str()))
{
found = true;
}
+ for(std::vector<std::string>::iterator i =
+ this->IncludeDirectories.begin();
+ i != this->IncludeDirectories.end(); ++i)
+ {
+ std::string path = *i;
+ path = path + "/";
+ path = path + cxxFile;
+ if(cmSystemTools::FileExists(path.c_str()))
+ {
+ found = true;
+ }
+ }
+ }
+ if (found)
+ {
+ this->AddDependency(info, cxxFile.c_str());
}
}
- if (found)
+ }
+ }
+ }
+
+ /**
+ * Add a dependency. Possibly walk it for more dependencies.
+ */
+ void AddDependency(cmDependInformation* info, const char* file)
+ {
+ cmDependInformation* dependInfo =
+ this->GetDependInformation(file, info->PathOnly.c_str());
+ this->GenerateDependInformation(dependInfo);
+ info->AddDependencies(dependInfo);
+ }
+
+ /**
+ * Fill in the given object with dependency information. If the
+ * information is already complete, nothing is done.
+ */
+ void GenerateDependInformation(cmDependInformation* info)
+ {
+ // If dependencies are already done, stop now.
+ if(info->DependDone)
+ {
+ return;
+ }
+ else
+ {
+ // Make sure we don't visit the same file more than once.
+ info->DependDone = true;
+ }
+ const char* path = info->FullPath.c_str();
+ if(!path)
+ {
+ cmSystemTools::Error(
+ "Attempt to find dependencies for file without path!");
+ return;
+ }
+
+ bool found = false;
+
+ // If the file exists, use it to find dependency information.
+ if(cmSystemTools::FileExists(path, true))
+ {
+ // Use the real file to find its dependencies.
+ this->DependWalk(info);
+ found = true;
+ }
+
+
+ // See if the cmSourceFile for it has any files specified as
+ // dependency hints.
+ if(info->SourceFile != 0)
+ {
+
+ // Get the cmSourceFile corresponding to this.
+ const cmSourceFile& cFile = *(info->SourceFile);
+ // See if there are any hints for finding dependencies for the missing
+ // file.
+ if(!cFile.GetDepends().empty())
+ {
+ // Dependency hints have been given. Use them to begin the
+ // recursion.
+ for(std::vector<std::string>::const_iterator file =
+ cFile.GetDepends().begin(); file != cFile.GetDepends().end();
+ ++file)
{
- this->AddDependency(info, cxxFile.c_str());
+ this->AddDependency(info, file->c_str());
}
+
+ // Found dependency information. We are done.
+ found = true;
}
}
- }
-}
+
+ if(!found)
+ {
+ // Try to find the file amongst the sources
+ cmSourceFile *srcFile = this->Makefile->GetSource
+ (cmSystemTools::GetFilenameWithoutExtension(path));
+ if (srcFile)
+ {
+ if (srcFile->GetFullPath() == path)
+ {
+ found=true;
+ }
+ else
+ {
+ //try to guess which include path to use
+ for(std::vector<std::string>::iterator t =
+ this->IncludeDirectories.begin();
+ t != this->IncludeDirectories.end(); ++t)
+ {
+ std::string incpath = *t;
+ if (!incpath.empty() && incpath[incpath.size() - 1] != '/')
+ {
+ incpath = incpath + "/";
+ }
+ incpath = incpath + path;
+ if (srcFile->GetFullPath() == incpath)
+ {
+ // set the path to the guessed path
+ info->FullPath = incpath;
+ found=true;
+ }
+ }
+ }
+ }
+ }
+
+ if(!found)
+ {
+ // Couldn't find any dependency information.
+ if(this->ComplainFileRegularExpression.find(info->IncludeName.c_str()))
+ {
+ cmSystemTools::Error("error cannot find dependencies for ", path);
+ }
+ else
+ {
+ // Destroy the name of the file so that it won't be output as a
+ // dependency.
+ info->FullPath = "";
+ }
+ }
+ }
+
+ /**
+ * Get an instance of cmDependInformation corresponding to the given file
+ * name.
+ */
+ cmDependInformation* GetDependInformation(const char* file,
+ const char *extraPath)
+ {
+ // Get the full path for the file so that lookup is unambiguous.
+ std::string fullPath = this->FullPath(file, extraPath);
+
+ // Try to find the file's instance of cmDependInformation.
+ DependInformationMapType::const_iterator result =
+ this->DependInformationMap.find(fullPath);
+ if(result != this->DependInformationMap.end())
+ {
+ // Found an instance, return it.
+ return result->second;
+ }
+ else
+ {
+ // Didn't find an instance. Create a new one and save it.
+ cmDependInformation* info = new cmDependInformation;
+ info->FullPath = fullPath;
+ info->PathOnly = cmSystemTools::GetFilenamePath(fullPath);
+ info->IncludeName = file;
+ this->DependInformationMap[fullPath] = info;
+ return info;
+ }
+ }
+
+ /**
+ * Find the full path name for the given file name.
+ * This uses the include directories.
+ * TODO: Cache path conversions to reduce FileExists calls.
+ */
+ std::string FullPath(const char *fname, const char *extraPath)
+ {
+ DirectoryToFileToPathMapType::iterator m;
+ if(extraPath)
+ {
+ m = this->DirectoryToFileToPathMap.find(extraPath);
+ }
+ else
+ {
+ m = this->DirectoryToFileToPathMap.find("");
+ }
+
+ if(m != this->DirectoryToFileToPathMap.end())
+ {
+ FileToPathMapType& map = m->second;
+ FileToPathMapType::iterator p = map.find(fname);
+ if(p != map.end())
+ {
+ return p->second;
+ }
+ }
+
+ if(cmSystemTools::FileExists(fname, true))
+ {
+ std::string fp = cmSystemTools::CollapseFullPath(fname);
+ this->DirectoryToFileToPathMap[extraPath? extraPath: ""][fname] = fp;
+ return fp;
+ }
+
+ for(std::vector<std::string>::iterator i =
+ this->IncludeDirectories.begin();
+ i != this->IncludeDirectories.end(); ++i)
+ {
+ std::string path = *i;
+ if (!path.empty() && path[path.size() - 1] != '/')
+ {
+ path = path + "/";
+ }
+ path = path + fname;
+ if(cmSystemTools::FileExists(path.c_str(), true)
+ && !cmSystemTools::FileIsDirectory(path))
+ {
+ std::string fp = cmSystemTools::CollapseFullPath(path);
+ this->DirectoryToFileToPathMap[extraPath? extraPath: ""][fname] = fp;
+ return fp;
+ }
+ }
+
+ if (extraPath)
+ {
+ std::string path = extraPath;
+ if (!path.empty() && path[path.size() - 1] != '/')
+ {
+ path = path + "/";
+ }
+ path = path + fname;
+ if(cmSystemTools::FileExists(path.c_str(), true)
+ && !cmSystemTools::FileIsDirectory(path))
+ {
+ std::string fp = cmSystemTools::CollapseFullPath(path);
+ this->DirectoryToFileToPathMap[extraPath][fname] = fp;
+ return fp;
+ }
+ }
+
+ // Couldn't find the file.
+ return std::string(fname);
+ }
+
+ cmMakefile* Makefile;
+ bool Verbose;
+ cmsys::RegularExpression IncludeFileRegularExpression;
+ cmsys::RegularExpression ComplainFileRegularExpression;
+ std::vector<std::string> IncludeDirectories;
+ typedef std::map<std::string, std::string> FileToPathMapType;
+ typedef std::map<std::string, FileToPathMapType>
+ DirectoryToFileToPathMapType;
+ typedef std::map<std::string, cmDependInformation*>
+ DependInformationMapType;
+ DependInformationMapType DependInformationMap;
+ DirectoryToFileToPathMapType DirectoryToFileToPathMap;
+};
// cmOutputRequiredFilesCommand
bool cmOutputRequiredFilesCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
+ if(this->Disallowed(cmPolicies::CMP0032,
+ "The output_required_files command should not be called; see CMP0032."))
+ { return true; }
if(args.size() != 2 )
{
this->SetError("called with incorrect number of arguments");
@@ -187,18 +582,18 @@ bool cmOutputRequiredFilesCommand
// compute the list of files
cmLBDepend md;
md.SetMakefile(this->Makefile);
- md.AddSearchPath(this->Makefile->GetStartDirectory());
+ md.AddSearchPath(this->Makefile->GetCurrentSourceDirectory());
// find the depends for a file
const cmDependInformation *info = md.FindDependencies(this->File.c_str());
if (info)
{
// write them out
- FILE *fout = fopen(this->OutputFile.c_str(),"w");
+ FILE *fout = cmsys::SystemTools::Fopen(this->OutputFile.c_str(),"w");
if(!fout)
{
std::string err = "Can not open output file: ";
err += this->OutputFile;
- this->SetError(err.c_str());
+ this->SetError(err);
return false;
}
std::set<cmDependInformation const*> visited;
diff --git a/Source/cmOutputRequiredFilesCommand.h b/Source/cmOutputRequiredFilesCommand.h
index 1d7e39457..b5eb9329a 100644
--- a/Source/cmOutputRequiredFilesCommand.h
+++ b/Source/cmOutputRequiredFilesCommand.h
@@ -13,71 +13,21 @@
#define cmOutputRequiredFilesCommand_h
#include "cmCommand.h"
-#include "cmMakeDepend.h"
-/** \class cmOutputRequiredFilesCommand
- * \brief Output a list of required files for a source file
- *
- */
+class cmDependInformation;
+
class cmOutputRequiredFilesCommand : public cmCommand
{
public:
- /**
- * This is a virtual constructor for the command.
- */
- virtual cmCommand* Clone()
- {
- return new cmOutputRequiredFilesCommand;
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
+ cmTypeMacro(cmOutputRequiredFilesCommand, cmCommand);
+ virtual cmCommand* Clone() { return new cmOutputRequiredFilesCommand; }
virtual bool InitialPass(std::vector<std::string> const& args,
cmExecutionStatus &status);
+ virtual std::string GetName() const { return "output_required_files";}
- /**
- * The name of the command as specified in CMakeList.txt.
- */
- virtual const char* GetName() const { return "output_required_files";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Deprecated. Approximate C preprocessor dependency scanning.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- "This command exists only because ancient CMake versions provided it. "
- "CMake handles preprocessor dependency scanning automatically using a "
- "more advanced scanner.\n"
- " output_required_files(srcfile outputfile)\n"
- "Outputs a list of all the source files that are required by the "
- "specified srcfile. This list is written into outputfile. This is "
- "similar to writing out the dependencies for srcfile except that it "
- "jumps from .h files into .cxx, .c and .cpp files if possible.";
- }
-
- /** This command is kept for compatibility with older CMake versions. */
- virtual bool IsDiscouraged() const
- {
- return true;
- }
-
-
- cmTypeMacro(cmOutputRequiredFilesCommand, cmCommand);
void ListDependencies(cmDependInformation const *info,
FILE *fout,
std::set<cmDependInformation const*> *visited);
-
private:
std::string File;
std::string OutputFile;
diff --git a/Source/cmParseArgumentsCommand.cxx b/Source/cmParseArgumentsCommand.cxx
new file mode 100644
index 000000000..ca76c889d
--- /dev/null
+++ b/Source/cmParseArgumentsCommand.cxx
@@ -0,0 +1,200 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Matthias Maennich <matthias@maennich.net>
+ Copyright 2010 Alexander Neundorf <neundorf@kde.org>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmParseArgumentsCommand.h"
+#include "cmAlgorithms.h"
+
+//----------------------------------------------------------------------------
+bool cmParseArgumentsCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ // cmake_parse_arguments(prefix options single multi <ARGN>)
+ // 1 2 3 4
+ if (args.size() < 4)
+ {
+ this->SetError("must be called with at least 4 arguments.");
+ return false;
+ }
+
+ std::vector<std::string>::const_iterator argIter = args.begin(),
+ argEnd = args.end();
+ // the first argument is the prefix
+ const std::string prefix = (*argIter++) + "_";
+
+ // define the result maps holding key/value pairs for
+ // options, single values and multi values
+ typedef std::map<std::string, bool> options_map;
+ typedef std::map<std::string, std::string> single_map;
+ typedef std::map<std::string, std::vector<std::string> > multi_map;
+ options_map options;
+ single_map single;
+ multi_map multi;
+
+ // anything else is put into a vector of unparsed strings
+ std::vector<std::string> unparsed;
+
+ // remember already defined keywords
+ std::set<std::string> used_keywords;
+ const std::string dup_warning = "keyword defined more than once: ";
+
+ // the second argument is a (cmake) list of options without argument
+ std::vector<std::string> list;
+ cmSystemTools::ExpandListArgument(*argIter++, list);
+ for (std::vector<std::string>::const_iterator iter = list.begin(),
+ end = list.end();
+ iter != end; ++iter)
+ {
+ if (!used_keywords.insert(*iter).second)
+ {
+ this->GetMakefile()->IssueMessage(cmake::WARNING, dup_warning + *iter);
+ }
+ options[*iter]; // default initialize
+ }
+
+ // the third argument is a (cmake) list of single argument options
+ list.clear();
+ cmSystemTools::ExpandListArgument(*argIter++, list);
+ for (std::vector<std::string>::const_iterator iter = list.begin(),
+ end = list.end();
+ iter != end; ++iter)
+ {
+ if (!used_keywords.insert(*iter).second)
+ {
+ this->GetMakefile()->IssueMessage(cmake::WARNING, dup_warning + *iter);
+ }
+ single[*iter]; // default initialize
+ }
+
+ // the fourth argument is a (cmake) list of multi argument options
+ list.clear();
+ cmSystemTools::ExpandListArgument(*argIter++, list);
+ for (std::vector<std::string>::const_iterator iter = list.begin(),
+ end = list.end();
+ iter != end; ++iter)
+ {
+ if (!used_keywords.insert(*iter).second)
+ {
+ this->GetMakefile()->IssueMessage(cmake::WARNING, dup_warning + *iter);
+ }
+ multi[*iter]; // default initialize
+ }
+
+ enum insideValues
+ {
+ NONE,
+ SINGLE,
+ MULTI
+ } insideValues = NONE;
+ std::string currentArgName;
+
+ // Flatten ;-lists in the arguments into a single list as was done
+ // by the original function(CMAKE_PARSE_ARGUMENTS).
+ list.clear();
+ for(; argIter != argEnd; ++argIter)
+ {
+ cmSystemTools::ExpandListArgument(*argIter, list);
+ }
+
+ // iterate over the arguments list and fill in the values where applicable
+ for (argIter = list.begin(), argEnd = list.end();
+ argIter != argEnd; ++argIter)
+ {
+ const options_map::iterator optIter = options.find(*argIter);
+ if (optIter != options.end())
+ {
+ insideValues = NONE;
+ optIter->second = true;
+ continue;
+ }
+
+ const single_map::iterator singleIter = single.find(*argIter);
+ if (singleIter != single.end())
+ {
+ insideValues = SINGLE;
+ currentArgName = *argIter;
+ continue;
+ }
+
+ const multi_map::iterator multiIter = multi.find(*argIter);
+ if (multiIter != multi.end())
+ {
+ insideValues = MULTI;
+ currentArgName = *argIter;
+ continue;
+ }
+
+ switch(insideValues)
+ {
+ case SINGLE:
+ single[currentArgName] = *argIter;
+ insideValues = NONE;
+ break;
+ case MULTI:
+ multi[currentArgName].push_back(*argIter);
+ break;
+ default:
+ unparsed.push_back(*argIter);
+ break;
+ }
+ }
+
+ // now iterate over the collected values and update their definition
+ // within the current scope. undefine if necessary.
+
+ for (options_map::const_iterator iter = options.begin(), end = options.end();
+ iter != end; ++iter)
+ {
+ this->Makefile->AddDefinition(prefix + iter->first,
+ iter->second? "TRUE": "FALSE");
+ }
+ for (single_map::const_iterator iter = single.begin(), end = single.end();
+ iter != end; ++iter)
+ {
+ if (!iter->second.empty())
+ {
+ this->Makefile->AddDefinition(prefix + iter->first,
+ iter->second.c_str());
+ }
+ else
+ {
+ this->Makefile->RemoveDefinition(prefix + iter->first);
+ }
+ }
+
+ for (multi_map::const_iterator iter = multi.begin(), end = multi.end();
+ iter != end; ++iter)
+ {
+ if (!iter->second.empty())
+ {
+ this->Makefile->AddDefinition(prefix + iter->first,
+ cmJoin(cmMakeRange(iter->second), ";")
+ .c_str());
+ }
+ else
+ {
+ this->Makefile->RemoveDefinition(prefix + iter->first);
+ }
+ }
+
+ if (!unparsed.empty())
+ {
+ this->Makefile->AddDefinition(prefix + "UNPARSED_ARGUMENTS",
+ cmJoin(cmMakeRange(unparsed), ";").c_str());
+ }
+ else
+ {
+ this->Makefile->RemoveDefinition(prefix + "UNPARSED_ARGUMENTS");
+ }
+
+ return true;
+}
diff --git a/Source/cmParseArgumentsCommand.h b/Source/cmParseArgumentsCommand.h
new file mode 100644
index 000000000..7fbf64296
--- /dev/null
+++ b/Source/cmParseArgumentsCommand.h
@@ -0,0 +1,54 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Matthias Maennich <matthias@maennich.net>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmParseArgumentsCommand_h
+#define cmParseArgumentsCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmParseArgumentsCommand
+ *
+ */
+class cmParseArgumentsCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmParseArgumentsCommand;
+ }
+
+ /**
+ * This is called when the command is first encountered in
+ * the CMakeLists.txt file.
+ */
+ virtual bool InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus &status);
+
+ /**
+ * This determines if the command is invoked when in script mode.
+ */
+ virtual bool IsScriptable() const { return true; }
+
+ /**
+ * The name of the command as specified in CMakeList.txt.
+ */
+ virtual std::string GetName() const { return "cmake_parse_arguments";}
+
+ cmTypeMacro(cmParseArgumentsCommand, cmCommand);
+
+};
+
+
+#endif
diff --git a/Source/cmPathLabel.cxx b/Source/cmPathLabel.cxx
new file mode 100644
index 000000000..67d56e180
--- /dev/null
+++ b/Source/cmPathLabel.cxx
@@ -0,0 +1,41 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmPathLabel.h"
+
+//----------------------------------------------------------------------------
+cmPathLabel::cmPathLabel(const std::string& label)
+: Label(label), Hash(0)
+{
+ // Use a Jenkins one-at-a-time hash with under/over-flow protection
+ for(size_t i = 0; i < this->Label.size(); ++i)
+ {
+ this->Hash += this->Label[i];
+ this->Hash += ((this->Hash & 0x003FFFFF) << 10);
+ this->Hash ^= ((this->Hash & 0xFFFFFFC0) >> 6);
+ }
+ this->Hash += ((this->Hash & 0x1FFFFFFF) << 3);
+ this->Hash ^= ((this->Hash & 0xFFFFF800) >> 11);
+ this->Hash += ((this->Hash & 0x0001FFFF) << 15);
+}
+
+//----------------------------------------------------------------------------
+bool cmPathLabel::operator < (const cmPathLabel& l) const
+{
+ return this->Hash < l.Hash;
+}
+
+//----------------------------------------------------------------------------
+bool cmPathLabel::operator == (const cmPathLabel& l) const
+{
+ return this->Hash == l.Hash;
+}
diff --git a/Source/cmPathLabel.h b/Source/cmPathLabel.h
new file mode 100644
index 000000000..02d526123
--- /dev/null
+++ b/Source/cmPathLabel.h
@@ -0,0 +1,44 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmPathLabel_h
+#define cmPathLabel_h
+
+#include "cmStandardIncludes.h"
+
+/** \class cmPathLabel
+ * \brief Helper class for text based labels
+ *
+ * cmPathLabel is extended in different classes to act as an inheritable
+ * enum. Comparisons are done on a precomputed Jenkins hash of the string
+ * label for indexing and searchig.
+ */
+class cmPathLabel
+{
+public:
+ cmPathLabel(const std::string& label);
+
+ // The comparison operators are only for quick sorting and searching and
+ // in no way imply any lexicographical order of the label
+ bool operator < (const cmPathLabel& l) const;
+ bool operator == (const cmPathLabel& l) const;
+
+ const std::string& GetLabel() const { return this->Label; }
+ const unsigned int& GetHash() const { return this->Hash; }
+
+protected:
+ cmPathLabel();
+
+ std::string Label;
+ unsigned int Hash;
+};
+
+#endif
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index a823f0595..3eb19bb96 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -1,646 +1,179 @@
#include "cmPolicies.h"
#include "cmake.h"
#include "cmMakefile.h"
-#include "cmSourceFile.h"
#include "cmVersion.h"
#include "cmVersionMacros.h"
+#include "cmAlgorithms.h"
#include <map>
#include <set>
#include <queue>
#include <assert.h>
-const char* cmPolicies::PolicyStatusNames[] = {
- "OLD", "WARN", "NEW", "REQUIRED_IF_USED", "REQUIRED_ALWAYS"
-};
-
-class cmPolicy
+static bool stringToId(const char* input, cmPolicies::PolicyID& pid)
{
-public:
- cmPolicy(cmPolicies::PolicyID iD,
- const char *idString,
- const char *shortDescription,
- const char *longDescription,
- unsigned int majorVersionIntroduced,
- unsigned int minorVersionIntroduced,
- unsigned int patchVersionIntroduced,
- unsigned int tweakVersionIntroduced,
- cmPolicies::PolicyStatus status)
- {
- if (!idString || !shortDescription || ! longDescription)
- {
- cmSystemTools::Error("Attempt to define a policy without "
- "all parameters being specified!");
- return;
- }
- this->ID = iD;
- this->IDString = idString;
- this->ShortDescription = shortDescription;
- this->LongDescription = longDescription;
- this->MajorVersionIntroduced = majorVersionIntroduced;
- this->MinorVersionIntroduced = minorVersionIntroduced;
- this->PatchVersionIntroduced = patchVersionIntroduced;
- this->TweakVersionIntroduced = tweakVersionIntroduced;
- this->Status = status;
- }
-
- std::string GetVersionString()
- {
- cmOStringStream v;
- v << this->MajorVersionIntroduced << "." << this->MinorVersionIntroduced;
- v << "." << this->PatchVersionIntroduced;
- if(this->TweakVersionIntroduced > 0)
- {
- v << "." << this->TweakVersionIntroduced;
- }
- return v.str();
- }
-
- bool IsPolicyNewerThan(unsigned int majorV,
- unsigned int minorV,
- unsigned int patchV,
- unsigned int tweakV)
- {
- if (majorV < this->MajorVersionIntroduced)
+ assert(input);
+ if (strlen(input) != 7)
{
- return true;
+ return false;
}
- if (majorV > this->MajorVersionIntroduced)
+ if (!cmHasLiteralPrefix(input, "CMP"))
{
- return false;
+ return false;
}
- if (minorV < this->MinorVersionIntroduced)
+ if (cmHasLiteralSuffix(input, "0000"))
{
- return true;
+ pid = cmPolicies::CMP0000;
+ return true;
}
- if (minorV > this->MinorVersionIntroduced)
+ for (int i = 3; i < 7; ++i)
{
+ if (!isdigit(*(input + i)))
+ {
return false;
+ }
}
- if (patchV < this->PatchVersionIntroduced)
+ long id;
+ if (!cmSystemTools::StringToLong(input + 3, &id))
{
- return true;
+ return false;
}
- if (patchV > this->PatchVersionIntroduced)
+ if (id >= cmPolicies::CMPCOUNT)
{
- return false;
+ return false;
}
- return (tweakV < this->TweakVersionIntroduced);
- }
-
- cmPolicies::PolicyID ID;
- std::string IDString;
- std::string ShortDescription;
- std::string LongDescription;
- unsigned int MajorVersionIntroduced;
- unsigned int MinorVersionIntroduced;
- unsigned int PatchVersionIntroduced;
- unsigned int TweakVersionIntroduced;
- cmPolicies::PolicyStatus Status;
-};
-
-cmPolicies::cmPolicies()
-{
- // define all the policies
- this->DefinePolicy(
- CMP0000, "CMP0000",
- "A minimum required CMake version must be specified.",
- "CMake requires that projects specify the version of CMake to which "
- "they have been written. "
- "This policy has been put in place so users trying to build the project "
- "may be told when they need to update their CMake. "
- "Specifying a version also helps the project build with CMake versions "
- "newer than that specified. "
- "Use the cmake_minimum_required command at the top of your main "
- " CMakeLists.txt file:\n"
- " cmake_minimum_required(VERSION <major>.<minor>)\n"
- "where \"<major>.<minor>\" is the version of CMake you want to support "
- "(such as \"2.6\"). "
- "The command will ensure that at least the given version of CMake is "
- "running and help newer versions be compatible with the project. "
- "See documentation of cmake_minimum_required for details.\n"
- "Note that the command invocation must appear in the CMakeLists.txt "
- "file itself; a call in an included file is not sufficient. "
- "However, the cmake_policy command may be called to set policy "
- "CMP0000 to OLD or NEW behavior explicitly. "
- "The OLD behavior is to silently ignore the missing invocation. "
- "The NEW behavior is to issue an error instead of a warning. "
- "An included file may set CMP0000 explicitly to affect how this "
- "policy is enforced for the main CMakeLists.txt file.",
- 2,6,0,0, cmPolicies::WARN
- );
-
- this->DefinePolicy(
- CMP0001, "CMP0001",
- "CMAKE_BACKWARDS_COMPATIBILITY should no longer be used.",
- "The OLD behavior is to check CMAKE_BACKWARDS_COMPATIBILITY and present "
- "it to the user. "
- "The NEW behavior is to ignore CMAKE_BACKWARDS_COMPATIBILITY "
- "completely.\n"
- "In CMake 2.4 and below the variable CMAKE_BACKWARDS_COMPATIBILITY was "
- "used to request compatibility with earlier versions of CMake. "
- "In CMake 2.6 and above all compatibility issues are handled by policies "
- "and the cmake_policy command. "
- "However, CMake must still check CMAKE_BACKWARDS_COMPATIBILITY for "
- "projects written for CMake 2.4 and below.",
- 2,6,0,0, cmPolicies::WARN
- );
-
- this->DefinePolicy(
- CMP0002, "CMP0002",
- "Logical target names must be globally unique.",
- "Targets names created with "
- "add_executable, add_library, or add_custom_target "
- "are logical build target names. "
- "Logical target names must be globally unique because:\n"
- " - Unique names may be referenced unambiguously both in CMake\n"
- " code and on make tool command lines.\n"
- " - Logical names are used by Xcode and VS IDE generators\n"
- " to produce meaningful project names for the targets.\n"
- "The logical name of executable and library targets does not "
- "have to correspond to the physical file names built. "
- "Consider using the OUTPUT_NAME target property to create two "
- "targets with the same physical name while keeping logical "
- "names distinct. "
- "Custom targets must simply have globally unique names (unless one "
- "uses the global property ALLOW_DUPLICATE_CUSTOM_TARGETS with a "
- "Makefiles generator).",
- 2,6,0,0, cmPolicies::WARN
- );
-
- this->DefinePolicy(
- CMP0003, "CMP0003",
- "Libraries linked via full path no longer produce linker search paths.",
- "This policy affects how libraries whose full paths are NOT known "
- "are found at link time, but was created due to a change in how CMake "
- "deals with libraries whose full paths are known. "
- "Consider the code\n"
- " target_link_libraries(myexe /path/to/libA.so)\n"
- "CMake 2.4 and below implemented linking to libraries whose full paths "
- "are known by splitting them on the link line into separate components "
- "consisting of the linker search path and the library name. "
- "The example code might have produced something like\n"
- " ... -L/path/to -lA ...\n"
- "in order to link to library A. "
- "An analysis was performed to order multiple link directories such that "
- "the linker would find library A in the desired location, but there "
- "are cases in which this does not work. "
- "CMake versions 2.6 and above use the more reliable approach of passing "
- "the full path to libraries directly to the linker in most cases. "
- "The example code now produces something like\n"
- " ... /path/to/libA.so ....\n"
- "Unfortunately this change can break code like\n"
- " target_link_libraries(myexe /path/to/libA.so B)\n"
- "where \"B\" is meant to find \"/path/to/libB.so\". "
- "This code is wrong because the user is asking the linker to find "
- "library B but has not provided a linker search path (which may be "
- "added with the link_directories command). "
- "However, with the old linking implementation the code would work "
- "accidentally because the linker search path added for library A "
- "allowed library B to be found."
- "\n"
- "In order to support projects depending on linker search paths "
- "added by linking to libraries with known full paths, the OLD "
- "behavior for this policy will add the linker search paths even "
- "though they are not needed for their own libraries. "
- "When this policy is set to OLD, CMake will produce a link line such as\n"
- " ... -L/path/to /path/to/libA.so -lB ...\n"
- "which will allow library B to be found as it was previously. "
- "When this policy is set to NEW, CMake will produce a link line such as\n"
- " ... /path/to/libA.so -lB ...\n"
- "which more accurately matches what the project specified."
- "\n"
- "The setting for this policy used when generating the link line is that "
- "in effect when the target is created by an add_executable or "
- "add_library command. For the example described above, the code\n"
- " cmake_policy(SET CMP0003 OLD) # or cmake_policy(VERSION 2.4)\n"
- " add_executable(myexe myexe.c)\n"
- " target_link_libraries(myexe /path/to/libA.so B)\n"
- "will work and suppress the warning for this policy. "
- "It may also be updated to work with the corrected linking approach:\n"
- " cmake_policy(SET CMP0003 NEW) # or cmake_policy(VERSION 2.6)\n"
- " link_directories(/path/to) # needed to find library B\n"
- " add_executable(myexe myexe.c)\n"
- " target_link_libraries(myexe /path/to/libA.so B)\n"
- "Even better, library B may be specified with a full path:\n"
- " add_executable(myexe myexe.c)\n"
- " target_link_libraries(myexe /path/to/libA.so /path/to/libB.so)\n"
- "When all items on the link line have known paths CMake does not check "
- "this policy so it has no effect.\n"
- "Note that the warning for this policy will be issued for at most "
- "one target. This avoids flooding users with messages for every "
- "target when setting the policy once will probably fix all targets.",
- 2,6,0,0, cmPolicies::WARN);
-
- this->DefinePolicy(
- CMP0004, "CMP0004",
- "Libraries linked may not have leading or trailing whitespace.",
- "CMake versions 2.4 and below silently removed leading and trailing "
- "whitespace from libraries linked with code like\n"
- " target_link_libraries(myexe \" A \")\n"
- "This could lead to subtle errors in user projects.\n"
- "The OLD behavior for this policy is to silently remove leading and "
- "trailing whitespace. "
- "The NEW behavior for this policy is to diagnose the existence of "
- "such whitespace as an error. "
- "The setting for this policy used when checking the library names is "
- "that in effect when the target is created by an add_executable or "
- "add_library command.",
- 2,6,0,0, cmPolicies::WARN);
-
- this->DefinePolicy(
- CMP0005, "CMP0005",
- "Preprocessor definition values are now escaped automatically.",
- "This policy determines whether or not CMake should generate escaped "
- "preprocessor definition values added via add_definitions. "
- "CMake versions 2.4 and below assumed that only trivial values would "
- "be given for macros in add_definitions calls. "
- "It did not attempt to escape non-trivial values such as string "
- "literals in generated build rules. "
- "CMake versions 2.6 and above support escaping of most values, but "
- "cannot assume the user has not added escapes already in an attempt to "
- "work around limitations in earlier versions.\n"
- "The OLD behavior for this policy is to place definition values given "
- "to add_definitions directly in the generated build rules without "
- "attempting to escape anything. "
- "The NEW behavior for this policy is to generate correct escapes "
- "for all native build tools automatically. "
- "See documentation of the COMPILE_DEFINITIONS target property for "
- "limitations of the escaping implementation.",
- 2,6,0,0, cmPolicies::WARN);
-
- this->DefinePolicy(
- CMP0006, "CMP0006",
- "Installing MACOSX_BUNDLE targets requires a BUNDLE DESTINATION.",
- "This policy determines whether the install(TARGETS) command must be "
- "given a BUNDLE DESTINATION when asked to install a target with the "
- "MACOSX_BUNDLE property set. "
- "CMake 2.4 and below did not distinguish application bundles from "
- "normal executables when installing targets. "
- "CMake 2.6 provides a BUNDLE option to the install(TARGETS) command "
- "that specifies rules specific to application bundles on the Mac. "
- "Projects should use this option when installing a target with the "
- "MACOSX_BUNDLE property set.\n"
- "The OLD behavior for this policy is to fall back to the RUNTIME "
- "DESTINATION if a BUNDLE DESTINATION is not given. "
- "The NEW behavior for this policy is to produce an error if a bundle "
- "target is installed without a BUNDLE DESTINATION.",
- 2,6,0,0, cmPolicies::WARN);
-
- this->DefinePolicy(
- CMP0007, "CMP0007",
- "list command no longer ignores empty elements.",
- "This policy determines whether the list command will "
- "ignore empty elements in the list. "
- "CMake 2.4 and below list commands ignored all empty elements"
- " in the list. For example, a;b;;c would have length 3 and not 4. "
- "The OLD behavior for this policy is to ignore empty list elements. "
- "The NEW behavior for this policy is to correctly count empty "
- "elements in a list. ",
- 2,6,0,0, cmPolicies::WARN);
-
- this->DefinePolicy(
- CMP0008, "CMP0008",
- "Libraries linked by full-path must have a valid library file name.",
- "In CMake 2.4 and below it is possible to write code like\n"
- " target_link_libraries(myexe /full/path/to/somelib)\n"
- "where \"somelib\" is supposed to be a valid library file name "
- "such as \"libsomelib.a\" or \"somelib.lib\". "
- "For Makefile generators this produces an error at build time "
- "because the dependency on the full path cannot be found. "
- "For VS IDE and Xcode generators this used to work by accident because "
- "CMake would always split off the library directory and ask the "
- "linker to search for the library by name (-lsomelib or somelib.lib). "
- "Despite the failure with Makefiles, some projects have code like this "
- "and build only with VS and/or Xcode. "
- "This version of CMake prefers to pass the full path directly to the "
- "native build tool, which will fail in this case because it does "
- "not name a valid library file."
- "\n"
- "This policy determines what to do with full paths that do not appear "
- "to name a valid library file. "
- "The OLD behavior for this policy is to split the library name from the "
- "path and ask the linker to search for it. "
- "The NEW behavior for this policy is to trust the given path and "
- "pass it directly to the native build tool unchanged.",
- 2,6,1,0, cmPolicies::WARN);
-
- this->DefinePolicy(
- CMP0009, "CMP0009",
- "FILE GLOB_RECURSE calls should not follow symlinks by default.",
- "In CMake 2.6.1 and below, FILE GLOB_RECURSE calls would follow "
- "through symlinks, sometimes coming up with unexpectedly large "
- "result sets because of symlinks to top level directories that "
- "contain hundreds of thousands of files."
- "\n"
- "This policy determines whether or not to follow symlinks "
- "encountered during a FILE GLOB_RECURSE call. "
- "The OLD behavior for this policy is to follow the symlinks. "
- "The NEW behavior for this policy is not to follow the symlinks "
- "by default, but only if FOLLOW_SYMLINKS is given as an additional "
- "argument to the FILE command.",
- 2,6,2,0, cmPolicies::WARN);
-
- this->DefinePolicy(
- CMP0010, "CMP0010",
- "Bad variable reference syntax is an error.",
- "In CMake 2.6.2 and below, incorrect variable reference syntax such as "
- "a missing close-brace (\"${FOO\") was reported but did not stop "
- "processing of CMake code. "
- "This policy determines whether a bad variable reference is an error. "
- "The OLD behavior for this policy is to warn about the error, leave "
- "the string untouched, and continue. "
- "The NEW behavior for this policy is to report an error.",
- 2,6,3,0, cmPolicies::WARN);
-
- this->DefinePolicy(
- CMP0011, "CMP0011",
- "Included scripts do automatic cmake_policy PUSH and POP.",
- "In CMake 2.6.2 and below, CMake Policy settings in scripts loaded by "
- "the include() and find_package() commands would affect the includer. "
- "Explicit invocations of cmake_policy(PUSH) and cmake_policy(POP) were "
- "required to isolate policy changes and protect the includer. "
- "While some scripts intend to affect the policies of their includer, "
- "most do not. "
- "In CMake 2.6.3 and above, include() and find_package() by default PUSH "
- "and POP an entry on the policy stack around an included script, "
- "but provide a NO_POLICY_SCOPE option to disable it. "
- "This policy determines whether or not to imply NO_POLICY_SCOPE for "
- "compatibility. "
- "The OLD behavior for this policy is to imply NO_POLICY_SCOPE for "
- "include() and find_package() commands. "
- "The NEW behavior for this policy is to allow the commands to do their "
- "default cmake_policy PUSH and POP.",
- 2,6,3,0, cmPolicies::WARN);
-
- this->DefinePolicy(
- CMP0012, "CMP0012",
- "if() recognizes numbers and boolean constants.",
- "In CMake versions 2.6.4 and lower the if() command implicitly "
- "dereferenced arguments corresponding to variables, even those named "
- "like numbers or boolean constants, except for 0 and 1. "
- "Numbers and boolean constants such as true, false, yes, no, "
- "on, off, y, n, notfound, ignore (all case insensitive) were recognized "
- "in some cases but not all. "
- "For example, the code \"if(TRUE)\" might have evaluated as false. "
- "Numbers such as 2 were recognized only in "
- "boolean expressions like \"if(NOT 2)\" (leading to false) "
- "but not as a single-argument like \"if(2)\" (also leading to false). "
- "Later versions of CMake prefer to treat numbers and boolean constants "
- "literally, so they should not be used as variable names."
- "\n"
- "The OLD behavior for this policy is to implicitly dereference variables "
- "named like numbers and boolean constants. "
- "The NEW behavior for this policy is to recognize numbers and "
- "boolean constants without dereferencing variables with such names.",
- 2,8,0,0, cmPolicies::WARN);
-
- this->DefinePolicy(
- CMP0013, "CMP0013",
- "Duplicate binary directories are not allowed.",
- "CMake 2.6.3 and below silently permitted add_subdirectory() calls "
- "to create the same binary directory multiple times. "
- "During build system generation files would be written and then "
- "overwritten in the build tree and could lead to strange behavior. "
- "CMake 2.6.4 and above explicitly detect duplicate binary directories. "
- "CMake 2.6.4 always considers this case an error. "
- "In CMake 2.8.0 and above this policy determines whether or not "
- "the case is an error. "
- "The OLD behavior for this policy is to allow duplicate binary "
- "directories. "
- "The NEW behavior for this policy is to disallow duplicate binary "
- "directories with an error.",
- 2,8,0,0, cmPolicies::WARN);
-
- this->DefinePolicy(
- CMP0014, "CMP0014",
- "Input directories must have CMakeLists.txt.",
- "CMake versions before 2.8 silently ignored missing CMakeLists.txt "
- "files in directories referenced by add_subdirectory() or subdirs(), "
- "treating them as if present but empty. "
- "In CMake 2.8.0 and above this policy determines whether or not "
- "the case is an error. "
- "The OLD behavior for this policy is to silently ignore the problem. "
- "The NEW behavior for this policy is to report an error.",
- 2,8,0,0, cmPolicies::WARN);
-
- this->DefinePolicy(
- CMP0015, "CMP0015",
- "link_directories() treats paths relative to the source dir.",
- "In CMake 2.8.0 and lower the link_directories() command passed relative "
- "paths unchanged to the linker. "
- "In CMake 2.8.1 and above the link_directories() command prefers to "
- "interpret relative paths with respect to CMAKE_CURRENT_SOURCE_DIR, "
- "which is consistent with include_directories() and other commands. "
- "The OLD behavior for this policy is to use relative paths verbatim in "
- "the linker command. "
- "The NEW behavior for this policy is to convert relative paths to "
- "absolute paths by appending the relative path to "
- "CMAKE_CURRENT_SOURCE_DIR.",
- 2,8,1,0, cmPolicies::WARN);
-
- this->DefinePolicy(
- CMP0016, "CMP0016",
- "target_link_libraries() reports error if its only argument "
- "is not a target.",
- "In CMake 2.8.2 and lower the target_link_libraries() command silently "
- "ignored if it was called with only one argument, and this argument "
- "wasn't a valid target. "
- "In CMake 2.8.3 and above it reports an error in this case.",
- 2,8,3,0, cmPolicies::WARN);
-
- this->DefinePolicy(
- CMP0017, "CMP0017",
- "Prefer files from the CMake module directory when including from there.",
- "Starting with CMake 2.8.4, if a cmake-module shipped with CMake (i.e. "
- "located in the CMake module directory) calls include() or "
- "find_package(), the files located in the CMake module directory are "
- "preferred over the files in CMAKE_MODULE_PATH. "
- "This makes sure that the modules belonging to "
- "CMake always get those files included which they expect, and against "
- "which they were developed and tested. "
- "In all other cases, the files found in "
- "CMAKE_MODULE_PATH still take precedence over the ones in "
- "the CMake module directory. "
- "The OLD behaviour is to always prefer files from CMAKE_MODULE_PATH over "
- "files from the CMake modules directory.",
- 2,8,4,0, cmPolicies::WARN);
+ pid = cmPolicies::PolicyID(id);
+ return true;
+}
- this->DefinePolicy(
- CMP0018, "CMP0018",
- "Ignore CMAKE_SHARED_LIBRARY_<Lang>_FLAGS variable.",
- "CMake 2.8.8 and lower compiled sources in SHARED and MODULE libraries "
- "using the value of the undocumented CMAKE_SHARED_LIBRARY_<Lang>_FLAGS "
- "platform variable. The variable contained platform-specific flags "
- "needed to compile objects for shared libraries. Typically it included "
- "a flag such as -fPIC for position independent code but also included "
- "other flags needed on certain platforms. CMake 2.8.9 and higher "
- "prefer instead to use the POSITION_INDEPENDENT_CODE target property to "
- "determine what targets should be position independent, and new "
- "undocumented platform variables to select flags while ignoring "
- "CMAKE_SHARED_LIBRARY_<Lang>_FLAGS completely."
- "\n"
- "The default for either approach produces identical compilation flags, "
- "but if a project modifies CMAKE_SHARED_LIBRARY_<Lang>_FLAGS from its "
- "original value this policy determines which approach to use."
- "\n"
- "The OLD behavior for this policy is to ignore the "
- "POSITION_INDEPENDENT_CODE property for all targets and use the modified "
- "value of CMAKE_SHARED_LIBRARY_<Lang>_FLAGS for SHARED and MODULE "
- "libraries."
- "\n"
- "The NEW behavior for this policy is to ignore "
- "CMAKE_SHARED_LIBRARY_<Lang>_FLAGS whether it is modified or not and "
- "honor the POSITION_INDEPENDENT_CODE target property.",
- 2,8,9,0, cmPolicies::WARN);
+#define CM_SELECT_ID_VERSION(F, A1, A2, A3, A4, A5, A6) F(A1, A3, A4, A5)
+#define CM_FOR_EACH_POLICY_ID_VERSION(POLICY) \
+ CM_FOR_EACH_POLICY_TABLE(POLICY, CM_SELECT_ID_VERSION)
- this->DefinePolicy(
- CMP0019, "CMP0019",
- "Do not re-expand variables in include and link information.",
- "CMake 2.8.10 and lower re-evaluated values given to the "
- "include_directories, link_directories, and link_libraries "
- "commands to expand any leftover variable references at the "
- "end of the configuration step. "
- "This was for strict compatibility with VERY early CMake versions "
- "because all variable references are now normally evaluated during "
- "CMake language processing. "
- "CMake 2.8.11 and higher prefer to skip the extra evaluation."
- "\n"
- "The OLD behavior for this policy is to re-evaluate the values "
- "for strict compatibility. "
- "The NEW behavior for this policy is to leave the values untouched.",
- 2,8,11,0, cmPolicies::WARN);
+#define CM_SELECT_ID_DOC(F, A1, A2, A3, A4, A5, A6) F(A1, A2)
+#define CM_FOR_EACH_POLICY_ID_DOC(POLICY) \
+ CM_FOR_EACH_POLICY_TABLE(POLICY, CM_SELECT_ID_DOC)
- this->DefinePolicy(
- CMP0020, "CMP0020",
- "Automatically link Qt executables to qtmain target on Windows.",
- "CMake 2.8.10 and lower required users of Qt to always specify a link "
- "dependency to the qtmain.lib static library manually on Windows. CMake "
- "2.8.11 gained the ability to evaluate generator expressions while "
- "determining the link dependencies from IMPORTED targets. This allows "
- "CMake itself to automatically link executables which link to Qt to the "
- "qtmain.lib library when using IMPORTED Qt targets. For applications "
- "already linking to qtmain.lib, this should have little impact. For "
- "applications which supply their own alternative WinMain implementation "
- "and for applications which use the QAxServer library, this automatic "
- "linking will need to be disabled as per the documentation."
- "\n"
- "The OLD behavior for this policy is not to link executables to "
- "qtmain.lib automatically when they link to the QtCore IMPORTED"
- "target. "
- "The NEW behavior for this policy is to link executables to "
- "qtmain.lib automatically when they link to QtCore IMPORTED target.",
- 2,8,11,0, cmPolicies::WARN);
+static const char* idToString(cmPolicies::PolicyID id)
+{
+ switch(id)
+ {
+#define POLICY_CASE(ID) \
+ case cmPolicies::ID: \
+ return #ID;
+ CM_FOR_EACH_POLICY_ID(POLICY_CASE)
+#undef POLICY_CASE
+ case cmPolicies::CMPCOUNT:
+ return 0;
+ }
+ return 0;
+}
- this->DefinePolicy(
- CMP0021, "CMP0021",
- "Fatal error on relative paths in INCLUDE_DIRECTORIES target property.",
- "CMake 2.8.10.2 and lower allowed the INCLUDE_DIRECTORIES target "
- "property to contain relative paths. The base path for such relative "
- "entries is not well defined. CMake 2.8.12 issues a FATAL_ERROR if the "
- "INCLUDE_DIRECTORIES property contains a relative path."
- "\n"
- "The OLD behavior for this policy is not to warn about relative paths in "
- "the INCLUDE_DIRECTORIES target property. "
- "The NEW behavior for this policy is to issue a FATAL_ERROR if "
- "INCLUDE_DIRECTORIES contains a relative path.",
- 2,8,12,0, cmPolicies::WARN);
+static const char* idToVersion(cmPolicies::PolicyID id)
+{
+ switch(id)
+ {
+#define POLICY_CASE(ID, V_MAJOR, V_MINOR, V_PATCH) \
+ case cmPolicies::ID: \
+ return #V_MAJOR "." #V_MINOR "." #V_PATCH;
+ CM_FOR_EACH_POLICY_ID_VERSION(POLICY_CASE)
+#undef POLICY_CASE
+ case cmPolicies::CMPCOUNT:
+ return 0;
+ }
+ return 0;
+}
- this->DefinePolicy(
- CMP0022, "CMP0022",
- "INTERFACE_LINK_LIBRARIES defines the link interface.",
- "CMake 2.8.11 constructed the 'link interface' of a target from "
- "properties matching (IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)?. "
- "The modern way to specify config-sensitive content is to use generator "
- "expressions and the IMPORTED_ prefix makes uniform processing of the "
- "link interface with generator expressions impossible. The "
- "INTERFACE_LINK_LIBRARIES target property was introduced as a "
- "replacement in CMake 2.8.12. This new property is named consistently "
- "with the INTERFACE_COMPILE_DEFINITIONS, INTERFACE_INCLUDE_DIRECTORIES "
- "and INTERFACE_COMPILE_OPTIONS properties. For in-build targets, CMake "
- "will use the INTERFACE_LINK_LIBRARIES property as the source of the "
- "link interface only if policy CMP0022 is NEW. "
- "When exporting a target which has this policy set to NEW, only the "
- "INTERFACE_LINK_LIBRARIES property will be processed and generated for "
- "the IMPORTED target by default. A new option to the install(EXPORT) "
- "and export commands allows export of the old-style properties for "
- "compatibility with downstream users of CMake versions older than "
- "2.8.12. "
- "The target_link_libraries command will no longer populate the "
- "properties matching LINK_INTERFACE_LIBRARIES(_<CONFIG>)? if this policy "
- "is NEW."
- "\n"
- "The OLD behavior for this policy is to ignore the "
- "INTERFACE_LINK_LIBRARIES property for in-build targets. "
- "The NEW behavior for this policy is to use the INTERFACE_LINK_LIBRARIES "
- "property for in-build targets, and ignore the old properties matching "
- "(IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)?.",
- 2,8,12,0, cmPolicies::WARN);
+static bool isPolicyNewerThan(cmPolicies::PolicyID id,
+ unsigned int majorV,
+ unsigned int minorV,
+ unsigned int patchV)
+{
+ switch(id)
+ {
+#define POLICY_CASE(ID, V_MAJOR, V_MINOR, V_PATCH) \
+ case cmPolicies::ID: \
+ return (majorV < V_MAJOR || \
+ (majorV == V_MAJOR && \
+ minorV + 1 < V_MINOR + 1) || \
+ (majorV == V_MAJOR && \
+ minorV == V_MINOR && \
+ patchV + 1 < V_PATCH + 1));
+ CM_FOR_EACH_POLICY_ID_VERSION(POLICY_CASE)
+#undef POLICY_CASE
+ case cmPolicies::CMPCOUNT:
+ return false;
+ }
+ return false;
+}
- this->DefinePolicy(
- CMP0023, "CMP0023",
- "Plain and keyword target_link_libraries signatures cannot be mixed.",
- "CMake 2.8.12 introduced the target_link_libraries signature using "
- "the PUBLIC, PRIVATE, and INTERFACE keywords to generalize the "
- "LINK_PUBLIC and LINK_PRIVATE keywords introduced in CMake 2.8.7. "
- "Use of signatures with any of these keywords sets the link interface "
- "of a target explicitly, even if empty. "
- "This produces confusing behavior when used in combination with the "
- "historical behavior of the plain target_link_libraries signature. "
- "For example, consider the code:\n"
- " target_link_libraries(mylib A)\n"
- " target_link_libraries(mylib PRIVATE B)\n"
- "After the first line the link interface has not been set explicitly "
- "so CMake would use the link implementation, A, as the link interface. "
- "However, the second line sets the link interface to empty. "
- "In order to avoid this subtle behavior CMake now prefers to disallow "
- "mixing the plain and keyword signatures of target_link_libraries for "
- "a single target."
- "\n"
- "The OLD behavior for this policy is to allow keyword and plain "
- "target_link_libraries signatures to be mixed. "
- "The NEW behavior for this policy is to not to allow mixing of the "
- "keyword and plain signatures.",
- 2,8,12,0, cmPolicies::WARN);
+const char* idToShortDescription(cmPolicies::PolicyID id)
+{
+ switch(id)
+ {
+#define POLICY_CASE(ID, SHORT_DESCRIPTION) \
+ case cmPolicies::ID: \
+ return SHORT_DESCRIPTION;
+ CM_FOR_EACH_POLICY_ID_DOC(POLICY_CASE)
+#undef POLICY_CASE
+ case cmPolicies::CMPCOUNT:
+ return 0;
+ }
+ return 0;
}
-cmPolicies::~cmPolicies()
+//----------------------------------------------------------------------------
+static void DiagnoseAncientPolicies(
+ std::vector<cmPolicies::PolicyID> const& ancient,
+ unsigned int majorVer,
+ unsigned int minorVer,
+ unsigned int patchVer,
+ cmMakefile* mf)
{
- // free the policies
- std::map<cmPolicies::PolicyID,cmPolicy *>::iterator i
- = this->Policies.begin();
- for (;i != this->Policies.end(); ++i)
- {
- delete i->second;
- }
+ std::ostringstream e;
+ e << "The project requests behavior compatible with CMake version \""
+ << majorVer << "." << minorVer << "." << patchVer
+ << "\", which requires the OLD behavior for some policies:\n";
+ for(std::vector<cmPolicies::PolicyID>::const_iterator
+ i = ancient.begin(); i != ancient.end(); ++i)
+ {
+ e << " " << idToString(*i) << ": " << idToShortDescription(*i) << "\n";
+ }
+ e << "However, this version of CMake no longer supports the OLD "
+ << "behavior for these policies. "
+ << "Please either update your CMakeLists.txt files to conform to "
+ << "the new behavior or use an older version of CMake that still "
+ << "supports the old behavior.";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
}
-void cmPolicies::DefinePolicy(cmPolicies::PolicyID iD,
- const char *idString,
- const char *shortDescription,
- const char *longDescription,
- unsigned int majorVersionIntroduced,
- unsigned int minorVersionIntroduced,
- unsigned int patchVersionIntroduced,
- unsigned int tweakVersionIntroduced,
- cmPolicies::PolicyStatus status)
+//----------------------------------------------------------------------------
+static bool GetPolicyDefault(cmMakefile* mf, std::string const& policy,
+ cmPolicies::PolicyStatus* defaultSetting)
{
- // a policy must be unique and can only be defined once
- if (this->Policies.find(iD) != this->Policies.end())
- {
- cmSystemTools::Error("Attempt to redefine a CMake policy for policy "
- "ID ", this->GetPolicyIDString(iD).c_str());
- return;
- }
+ std::string defaultVar = "CMAKE_POLICY_DEFAULT_" + policy;
+ std::string defaultValue = mf->GetSafeDefinition(defaultVar);
+ if(defaultValue == "NEW")
+ {
+ *defaultSetting = cmPolicies::NEW;
+ }
+ else if(defaultValue == "OLD")
+ {
+ *defaultSetting = cmPolicies::OLD;
+ }
+ else if(defaultValue == "")
+ {
+ *defaultSetting = cmPolicies::WARN;
+ }
+ else
+ {
+ std::ostringstream e;
+ e << defaultVar << " has value \"" << defaultValue
+ << "\" but must be \"OLD\", \"NEW\", or \"\" (empty).";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
- this->Policies[iD] = new cmPolicy(iD, idString,
- shortDescription,
- longDescription,
- majorVersionIntroduced,
- minorVersionIntroduced,
- patchVersionIntroduced,
- tweakVersionIntroduced,
- status);
- this->PolicyStringMap[idString] = iD;
+ return true;
}
//----------------------------------------------------------------------------
@@ -663,7 +196,7 @@ bool cmPolicies::ApplyPolicyVersion(cmMakefile *mf,
if(sscanf(ver.c_str(), "%u.%u.%u.%u",
&majorVer, &minorVer, &patchVer, &tweakVer) < 2)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Invalid policy version value \"" << ver << "\". "
<< "A numeric major.minor[.patch[.tweak]] must be given.";
mf->IssueMessage(cmake::FATAL_ERROR, e.str());
@@ -674,15 +207,9 @@ bool cmPolicies::ApplyPolicyVersion(cmMakefile *mf,
if (majorVer < 2 || (majorVer == 2 && minorVer < 4))
{
mf->IssueMessage(cmake::FATAL_ERROR,
- "An attempt was made to set the policy version of CMake to something "
- "earlier than \"2.4\". "
- "In CMake 2.4 and below backwards compatibility was handled with the "
- "CMAKE_BACKWARDS_COMPATIBILITY variable. "
- "In order to get compatibility features supporting versions earlier "
- "than 2.4 set policy CMP0001 to OLD to tell CMake to check the "
- "CMAKE_BACKWARDS_COMPATIBILITY variable. "
- "One way to do this is to set the policy version to 2.4 exactly."
- );
+ "Compatibility with CMake < 2.4 is not supported by CMake >= 3.0. "
+ "For compatibility with older versions please use any CMake 2.8.x "
+ "release or lower.");
return false;
}
@@ -699,7 +226,7 @@ bool cmPolicies::ApplyPolicyVersion(cmMakefile *mf,
patchVer == cmVersion::GetPatchVersion() &&
tweakVer > cmVersion::GetTweakVersion()))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "An attempt was made to set the policy version of CMake to \""
<< version << "\" which is greater than this version of CMake. "
<< "This is not allowed because the greater version may have new "
@@ -711,28 +238,44 @@ bool cmPolicies::ApplyPolicyVersion(cmMakefile *mf,
// now loop over all the policies and set them as appropriate
std::vector<cmPolicies::PolicyID> ancientPolicies;
- for(std::map<cmPolicies::PolicyID,cmPolicy *>::iterator i
- = this->Policies.begin(); i != this->Policies.end(); ++i)
+ for(PolicyID pid = cmPolicies::CMP0000;
+ pid != cmPolicies::CMPCOUNT; pid = PolicyID(pid+1))
{
- if (i->second->IsPolicyNewerThan(majorVer,minorVer,patchVer,tweakVer))
+ if (isPolicyNewerThan(pid, majorVer, minorVer, patchVer))
{
- if(i->second->Status == cmPolicies::REQUIRED_ALWAYS)
+ if(cmPolicies::GetPolicyStatus(pid) == cmPolicies::REQUIRED_ALWAYS)
{
- ancientPolicies.push_back(i->first);
+ ancientPolicies.push_back(pid);
}
else
{
cmPolicies::PolicyStatus status = cmPolicies::WARN;
- if(!this->GetPolicyDefault(mf, i->second->IDString, &status) ||
- !mf->SetPolicy(i->second->ID, status))
+ if(!GetPolicyDefault(mf, idToString(pid), &status) ||
+ !mf->SetPolicy(pid, status))
{
return false;
}
+ if(pid == cmPolicies::CMP0001 &&
+ (status == cmPolicies::WARN || status == cmPolicies::OLD))
+ {
+ if(!(mf->GetState()
+ ->GetInitializedCacheValue("CMAKE_BACKWARDS_COMPATIBILITY")))
+ {
+ // Set it to 2.4 because that is the last version where the
+ // variable had meaning.
+ mf->AddCacheDefinition
+ ("CMAKE_BACKWARDS_COMPATIBILITY", "2.4",
+ "For backwards compatibility, what version of CMake "
+ "commands and "
+ "syntax should this version of CMake try to support.",
+ cmState::STRING);
+ }
+ }
}
}
else
{
- if (!mf->SetPolicy(i->second->ID, cmPolicies::NEW))
+ if (!mf->SetPolicy(pid, cmPolicies::NEW))
{
return false;
}
@@ -742,8 +285,8 @@ bool cmPolicies::ApplyPolicyVersion(cmMakefile *mf,
// Make sure the project does not use any ancient policies.
if(!ancientPolicies.empty())
{
- this->DiagnoseAncientPolicies(ancientPolicies,
- majorVer, minorVer, patchVer, mf);
+ DiagnoseAncientPolicies(ancientPolicies,
+ majorVer, minorVer, patchVer, mf);
cmSystemTools::SetFatalErrorOccured();
return false;
}
@@ -751,81 +294,19 @@ bool cmPolicies::ApplyPolicyVersion(cmMakefile *mf,
return true;
}
-//----------------------------------------------------------------------------
-bool cmPolicies::GetPolicyDefault(cmMakefile* mf, std::string const& policy,
- cmPolicies::PolicyStatus* defaultSetting)
-{
- std::string defaultVar = "CMAKE_POLICY_DEFAULT_" + policy;
- std::string defaultValue = mf->GetSafeDefinition(defaultVar.c_str());
- if(defaultValue == "NEW")
- {
- *defaultSetting = cmPolicies::NEW;
- }
- else if(defaultValue == "OLD")
- {
- *defaultSetting = cmPolicies::OLD;
- }
- else if(defaultValue == "")
- {
- *defaultSetting = cmPolicies::WARN;
- }
- else
- {
- cmOStringStream e;
- e << defaultVar << " has value \"" << defaultValue
- << "\" but must be \"OLD\", \"NEW\", or \"\" (empty).";
- mf->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
- return false;
- }
-
- return true;
-}
-
bool cmPolicies::GetPolicyID(const char *id, cmPolicies::PolicyID &pid)
{
- if (!id || strlen(id) < 1)
- {
- return false;
- }
- std::map<std::string,cmPolicies::PolicyID>::iterator pos =
- this->PolicyStringMap.find(id);
- if (pos == this->PolicyStringMap.end())
- {
- return false;
- }
- pid = pos->second;
- return true;
+ return stringToId(id, pid);
}
-std::string cmPolicies::GetPolicyIDString(cmPolicies::PolicyID pid)
-{
- std::map<cmPolicies::PolicyID,cmPolicy *>::iterator pos =
- this->Policies.find(pid);
- if (pos == this->Policies.end())
- {
- return "";
- }
- return pos->second->IDString;
-}
-
-
///! return a warning string for a given policy
std::string cmPolicies::GetPolicyWarning(cmPolicies::PolicyID id)
{
- std::map<cmPolicies::PolicyID,cmPolicy *>::iterator pos =
- this->Policies.find(id);
- if (pos == this->Policies.end())
- {
- cmSystemTools::Error(
- "Request for warning text for undefined policy!");
- return "Request for warning text for undefined policy!";
- }
-
- cmOStringStream msg;
+ std::ostringstream msg;
msg <<
- "Policy " << pos->second->IDString << " is not set: "
- "" << pos->second->ShortDescription << " "
- "Run \"cmake --help-policy " << pos->second->IDString << "\" for "
+ "Policy " << idToString(id) << " is not set: "
+ "" << idToShortDescription(id) << " "
+ "Run \"cmake --help-policy " << idToString(id) << "\" for "
"policy details. "
"Use the cmake_policy command to set the policy "
"and suppress this warning.";
@@ -836,26 +317,17 @@ std::string cmPolicies::GetPolicyWarning(cmPolicies::PolicyID id)
///! return an error string for when a required policy is unspecified
std::string cmPolicies::GetRequiredPolicyError(cmPolicies::PolicyID id)
{
- std::map<cmPolicies::PolicyID,cmPolicy *>::iterator pos =
- this->Policies.find(id);
- if (pos == this->Policies.end())
- {
- cmSystemTools::Error(
- "Request for error text for undefined policy!");
- return "Request for error text for undefined policy!";
- }
-
- cmOStringStream error;
+ std::ostringstream error;
error <<
- "Policy " << pos->second->IDString << " is not set to NEW: "
- "" << pos->second->ShortDescription << " "
- "Run \"cmake --help-policy " << pos->second->IDString << "\" for "
+ "Policy " << idToString(id) << " is not set to NEW: "
+ "" << idToShortDescription(id) << " "
+ "Run \"cmake --help-policy " << idToString(id) << "\" for "
"policy details. "
"CMake now requires this policy to be set to NEW by the project. "
"The policy may be set explicitly using the code\n"
- " cmake_policy(SET " << pos->second->IDString << " NEW)\n"
+ " cmake_policy(SET " << idToString(id) << " NEW)\n"
"or by upgrading all policies with the code\n"
- " cmake_policy(VERSION " << pos->second->GetVersionString() <<
+ " cmake_policy(VERSION " << idToVersion(id) <<
") # or later\n"
"Run \"cmake --help-command cmake_policy\" for more information.";
return error.str();
@@ -863,76 +335,21 @@ std::string cmPolicies::GetRequiredPolicyError(cmPolicies::PolicyID id)
///! Get the default status for a policy
cmPolicies::PolicyStatus
-cmPolicies::GetPolicyStatus(cmPolicies::PolicyID id)
+cmPolicies::GetPolicyStatus(cmPolicies::PolicyID)
{
- // if the policy is not know then what?
- std::map<cmPolicies::PolicyID,cmPolicy *>::iterator pos =
- this->Policies.find(id);
- if (pos == this->Policies.end())
- {
- // TODO is this right?
- return cmPolicies::WARN;
- }
-
- return pos->second->Status;
-}
-
-void cmPolicies::GetDocumentation(std::vector<cmDocumentationEntry>& v)
-{
- // now loop over all the policies and set them as appropriate
- std::map<cmPolicies::PolicyID,cmPolicy *>::iterator i
- = this->Policies.begin();
- for (;i != this->Policies.end(); ++i)
- {
- cmOStringStream full;
- full << i->second->LongDescription;
- full << "\nThis policy was introduced in CMake version ";
- full << i->second->GetVersionString() << ".";
- if(i->first != cmPolicies::CMP0000)
- {
- full << " "
- << "CMake version " << cmVersion::GetCMakeVersion() << " ";
- // add in some more text here based on status
- switch (i->second->Status)
- {
- case cmPolicies::WARN:
- full << "warns when the policy is not set and uses OLD behavior. "
- << "Use the cmake_policy command to set it to OLD or NEW "
- << "explicitly.";
- break;
- case cmPolicies::OLD:
- full << "defaults to the OLD behavior for this policy.";
- break;
- case cmPolicies::NEW:
- full << "defaults to the NEW behavior for this policy.";
- break;
- case cmPolicies::REQUIRED_IF_USED:
- full << "requires the policy to be set to NEW if you use it. "
- << "Use the cmake_policy command to set it to NEW.";
- break;
- case cmPolicies::REQUIRED_ALWAYS:
- full << "requires the policy to be set to NEW. "
- << "Use the cmake_policy command to set it to NEW.";
- break;
- }
- }
- cmDocumentationEntry e(i->second->IDString.c_str(),
- i->second->ShortDescription.c_str(),
- full.str().c_str());
- v.push_back(e);
- }
+ return cmPolicies::WARN;
}
//----------------------------------------------------------------------------
std::string
cmPolicies::GetRequiredAlwaysPolicyError(cmPolicies::PolicyID id)
{
- std::string pid = this->GetPolicyIDString(id);
- cmOStringStream e;
+ std::string pid = idToString(id);
+ std::ostringstream e;
e << "Policy " << pid << " may not be set to OLD behavior because this "
<< "version of CMake no longer supports it. "
<< "The policy was introduced in "
- << "CMake version " << this->Policies[id]->GetVersionString()
+ << "CMake version " << idToVersion(id)
<< ", and use of NEW behavior is now required."
<< "\n"
<< "Please either update your CMakeLists.txt files to conform to "
@@ -942,28 +359,38 @@ cmPolicies::GetRequiredAlwaysPolicyError(cmPolicies::PolicyID id)
return e.str();
}
-//----------------------------------------------------------------------------
-void
-cmPolicies::DiagnoseAncientPolicies(std::vector<PolicyID> const& ancient,
- unsigned int majorVer,
- unsigned int minorVer,
- unsigned int patchVer,
- cmMakefile* mf)
+cmPolicies::PolicyStatus
+cmPolicies::PolicyMap::Get(cmPolicies::PolicyID id) const
{
- cmOStringStream e;
- e << "The project requests behavior compatible with CMake version \""
- << majorVer << "." << minorVer << "." << patchVer
- << "\", which requires the OLD behavior for some policies:\n";
- for(std::vector<PolicyID>::const_iterator
- i = ancient.begin(); i != ancient.end(); ++i)
+ PolicyStatus status = cmPolicies::WARN;
+
+ if (this->Status[(POLICY_STATUS_COUNT * id) + OLD])
{
- cmPolicy const* policy = this->Policies[*i];
- e << " " << policy->IDString << ": " << policy->ShortDescription << "\n";
+ status = cmPolicies::OLD;
}
- e << "However, this version of CMake no longer supports the OLD "
- << "behavior for these policies. "
- << "Please either update your CMakeLists.txt files to conform to "
- << "the new behavior or use an older version of CMake that still "
- << "supports the old behavior.";
- mf->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
+ else if (this->Status[(POLICY_STATUS_COUNT * id) + NEW])
+ {
+ status = cmPolicies::NEW;
+ }
+ return status;
+}
+
+void cmPolicies::PolicyMap::Set(cmPolicies::PolicyID id,
+ cmPolicies::PolicyStatus status)
+{
+ this->Status[(POLICY_STATUS_COUNT * id) + OLD] = (status == OLD);
+ this->Status[(POLICY_STATUS_COUNT * id) + WARN] = (status == WARN);
+ this->Status[(POLICY_STATUS_COUNT * id) + NEW] = (status == NEW);
+}
+
+bool cmPolicies::PolicyMap::IsDefined(cmPolicies::PolicyID id) const
+{
+ return this->Status[(POLICY_STATUS_COUNT * id) + OLD]
+ || this->Status[(POLICY_STATUS_COUNT * id) + WARN]
+ || this->Status[(POLICY_STATUS_COUNT * id) + NEW];
+}
+
+bool cmPolicies::PolicyMap::IsEmpty() const
+{
+ return this->Status.none();
}
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 5b843a9ad..502305517 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -12,25 +12,252 @@
#ifndef cmPolicies_h
#define cmPolicies_h
-#include "cmCustomCommand.h"
+#include "cmStandardIncludes.h"
+
+#include <bitset>
-class cmake;
class cmMakefile;
class cmPolicy;
+#define CM_FOR_EACH_POLICY_TABLE(POLICY, SELECT) \
+ SELECT(POLICY, CMP0000, \
+ "A minimum required CMake version must be specified.", \
+ 2, 6, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0001, \
+ "CMAKE_BACKWARDS_COMPATIBILITY should no longer be used.", \
+ 2, 6, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0002, \
+ "Logical target names must be globally unique.", \
+ 2, 6, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0003, \
+ "Libraries linked via full path no longer produce linker search paths.", \
+ 2, 6, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0004, \
+ "Libraries linked may not have leading or trailing whitespace.", \
+ 2, 6, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0005, \
+ "Preprocessor definition values are now escaped automatically.", \
+ 2, 6, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0006, \
+ "Installing MACOSX_BUNDLE targets requires a BUNDLE DESTINATION.", \
+ 2, 6, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0007, \
+ "list command no longer ignores empty elements.", \
+ 2, 6, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0008, \
+ "Libraries linked by full-path must have a valid library file name.", \
+ 2, 6, 1, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0009, \
+ "FILE GLOB_RECURSE calls should not follow symlinks by default.", \
+ 2, 6, 2, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0010, \
+ "Bad variable reference syntax is an error.", \
+ 2, 6, 3, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0011, \
+ "Included scripts do automatic cmake_policy PUSH and POP.", \
+ 2, 6, 3, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0012, \
+ "if() recognizes numbers and boolean constants.", \
+ 2, 8, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0013, \
+ "Duplicate binary directories are not allowed.", \
+ 2, 8, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0014, \
+ "Input directories must have CMakeLists.txt.", \
+ 2, 8, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0015, \
+ "link_directories() treats paths relative to the source dir.", \
+ 2, 8, 1, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0016, \
+ "target_link_libraries() reports error if its only argument " \
+ "is not a target.", \
+ 2, 8, 3, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0017, \
+ "Prefer files from the CMake module directory when including from " \
+ "there.", \
+ 2, 8, 4, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0018, \
+ "Ignore CMAKE_SHARED_LIBRARY_<Lang>_FLAGS variable.", \
+ 2, 8, 9, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0019, \
+ "Do not re-expand variables in include and link information.", \
+ 2, 8, 11, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0020, \
+ "Automatically link Qt executables to qtmain target on Windows.", \
+ 2, 8, 11, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0021, \
+ "Fatal error on relative paths in INCLUDE_DIRECTORIES target property.", \
+ 2, 8, 12, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0022, \
+ "INTERFACE_LINK_LIBRARIES defines the link interface.", \
+ 2, 8, 12, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0023, \
+ "Plain and keyword target_link_libraries signatures cannot be mixed.", \
+ 2, 8, 12, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0024, \
+ "Disallow include export result.", \
+ 3, 0, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0025, \
+ "Compiler id for Apple Clang is now AppleClang.", \
+ 3, 0, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0026, \
+ "Disallow use of the LOCATION target property.", \
+ 3, 0, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0027, \
+ "Conditionally linked imported targets with missing include " \
+ "directories.", \
+ 3, 0, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0028, \
+ "Double colon in target name means ALIAS or IMPORTED target.", \
+ 3, 0, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0029, \
+ "The subdir_depends command should not be called.", \
+ 3, 0, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0030, \
+ "The use_mangled_mesa command should not be called.", \
+ 3, 0, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0031, \
+ "The load_command command should not be called.", \
+ 3, 0, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0032, \
+ "The output_required_files command should not be called.", \
+ 3, 0, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0033, \
+ "The export_library_dependencies command should not be called.", \
+ 3, 0, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0034, \
+ "The utility_source command should not be called.", \
+ 3, 0, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0035, \
+ "The variable_requires command should not be called.", \
+ 3, 0, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0036, \
+ "The build_name command should not be called.", \
+ 3, 0, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0037, \
+ "Target names should not be reserved and should match a validity " \
+ "pattern.", \
+ 3, 0, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0038, \
+ "Targets may not link directly to themselves.", \
+ 3, 0, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0039, \
+ "Utility targets may not have link dependencies.", \
+ 3, 0, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0040, \
+ "The target in the TARGET signature of add_custom_command() must " \
+ "exist.", \
+ 3, 0, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0041, \
+ "Error on relative include with generator expression.", \
+ 3, 0, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0042, \
+ "MACOSX_RPATH is enabled by default.", \
+ 3, 0, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0043, \
+ "Ignore COMPILE_DEFINITIONS_<Config> properties.", \
+ 3, 0, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0044, \
+ "Case sensitive <LANG>_COMPILER_ID generator expressions.", \
+ 3, 0, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0045, \
+ "Error on non-existent target in get_target_property.", \
+ 3, 0, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0046, \
+ "Error on non-existent dependency in add_dependencies.", \
+ 3, 0, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0047, \
+ "Use QCC compiler id for the qcc drivers on QNX.", \
+ 3, 0, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0048, \
+ "project() command manages VERSION variables.", \
+ 3, 0, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0049, \
+ "Do not expand variables in target source entries.", \
+ 3, 0, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0050, \
+ "Disallow add_custom_command SOURCE signatures.", \
+ 3, 0, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0051, \
+ "List TARGET_OBJECTS in SOURCES target property.", \
+ 3, 1, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0052, \
+ "Reject source and build dirs in installed " \
+ "INTERFACE_INCLUDE_DIRECTORIES.", \
+ 3, 1, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0053, \
+ "Simplify variable reference and escape sequence evaluation.", \
+ 3, 1, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0054, \
+ "Only interpret if() arguments as variables or keywords when unquoted.", \
+ 3, 1, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0055, \
+ "Strict checking for break() command.", \
+ 3, 2, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0056, \
+ "Honor link flags in try_compile() source-file signature.", \
+ 3, 2, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0057, \
+ "Support new IN_LIST if() operator.", \
+ 3, 3, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0058, \
+ "Ninja requires custom command byproducts to be explicit.", \
+ 3, 3, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0059, \
+ "Do no treat DEFINITIONS as a built-in directory property.", \
+ 3, 3, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0060, \
+ "Link libraries by full path even in implicit directories.", \
+ 3, 3, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0061, \
+ "CTest does not by default tell make to ignore errors (-i).", \
+ 3, 3, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0062, \
+ "Disallow install() of export() result.", \
+ 3, 3, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0063, \
+ "Honor visibility properties for all target types.", \
+ 3, 3, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0064, \
+ "Support new TEST if() operator.", \
+ 3, 4, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0065, \
+ "Do not add flags to export symbols from executables without " \
+ "the ENABLE_EXPORTS target property.", \
+ 3, 4, 0, cmPolicies::WARN)
+
+#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
+#define CM_FOR_EACH_POLICY_ID(POLICY) \
+ CM_FOR_EACH_POLICY_TABLE(POLICY, CM_SELECT_ID)
+
+#define CM_FOR_EACH_TARGET_POLICY(F) \
+ F(CMP0003) \
+ F(CMP0004) \
+ F(CMP0008) \
+ F(CMP0020) \
+ F(CMP0021) \
+ F(CMP0022) \
+ F(CMP0027) \
+ F(CMP0038) \
+ F(CMP0041) \
+ F(CMP0042) \
+ F(CMP0046) \
+ F(CMP0052) \
+ F(CMP0060) \
+ F(CMP0063) \
+ F(CMP0065)
+
+
/** \class cmPolicies
* \brief Handles changes in CMake behavior and policies
*
* See the cmake wiki section on
- * <a href="http://www.cmake.org/Wiki/CMake/Policies">policies</a>
+ * <a href="https://cmake.org/Wiki/CMake/Policies">policies</a>
* for an overview of this class's purpose
*/
class cmPolicies
{
public:
- cmPolicies();
- ~cmPolicies();
-
/// Status of a policy
enum PolicyStatus {
OLD, ///< Use old behavior
@@ -41,39 +268,13 @@ public:
REQUIRED_IF_USED,
REQUIRED_ALWAYS ///< Issue an error unless user sets policy status to NEW.
};
- static const char* PolicyStatusNames[];
/// Policy identifiers
enum PolicyID
{
- CMP0000, ///< Policy version specification
- CMP0001, ///< Ignore old compatibility variable
- CMP0002, ///< Target names must be unique
- CMP0003, ///< Linking does not include extra -L paths
- CMP0004, ///< Libraries linked may not have leading or trailing whitespace
- CMP0005, ///< Definition value escaping
- CMP0006, ///< BUNDLE install rules needed for MACOSX_BUNDLE targets
- CMP0007, ///< list command handling of empty elements
- CMP0008, ///< Full-path libraries must be a valid library file name
- CMP0009, ///< GLOB_RECURSE should not follow symlinks by default
- CMP0010, ///< Bad variable reference syntax is an error
- CMP0011, ///< Strong policy scope for include and find_package
- CMP0012, ///< Recognize numbers and boolean constants in if()
- CMP0013, ///< Duplicate binary directories not allowed
- CMP0014, ///< Input directories must have CMakeLists.txt
- CMP0015, ///< link_directories() treats paths relative to source dir
- /// target_link_libraries() fails if only argument is not a target
- CMP0016,
- CMP0017, ///< Prefer files in CMAKE_ROOT when including from CMAKE_ROOT
- CMP0018, ///< Ignore language flags for shared libs, and adhere to
- /// POSITION_INDEPENDENT_CODE property and *_COMPILE_OPTIONS_PI{E,C}
- /// instead.
- CMP0019, ///< No variable re-expansion in include and link info
- CMP0020, ///< Automatically link Qt executables to qtmain target
- CMP0021, ///< Fatal error on relative paths in INCLUDE_DIRECTORIES
- /// target property
- CMP0022, ///< INTERFACE_LINK_LIBRARIES defines the link interface
- CMP0023, ///< Disallow mixing keyword and plain tll signatures
+#define POLICY_ENUM(POLICY_ID) POLICY_ID,
+ CM_FOR_EACH_POLICY_ID(POLICY_ENUM)
+#undef POLICY_ENUM
/** \brief Always the last entry.
*
@@ -84,53 +285,35 @@ public:
};
///! convert a string policy ID into a number
- bool GetPolicyID(const char *id, /* out */ cmPolicies::PolicyID &pid);
- std::string GetPolicyIDString(cmPolicies::PolicyID pid);
+ static bool GetPolicyID(const char *id, /* out */ cmPolicies::PolicyID &pid);
///! Get the default status for a policy
- cmPolicies::PolicyStatus GetPolicyStatus(cmPolicies::PolicyID id);
-
- ///! Define a Policy for CMake
- void DefinePolicy(cmPolicies::PolicyID id,
- const char *stringID,
- const char *shortDescription,
- const char *longDescription,
- unsigned int majorVersionIntroduced,
- unsigned int minorVersionIntroduced,
- unsigned int patchVersionIntroduced,
- unsigned int tweakVersionIntroduced,
- cmPolicies::PolicyStatus status);
+ static cmPolicies::PolicyStatus GetPolicyStatus(cmPolicies::PolicyID id);
///! Set a policy level for this listfile
- bool ApplyPolicyVersion(cmMakefile *mf, const char *version);
+ static bool ApplyPolicyVersion(cmMakefile *mf, const char *version);
///! return a warning string for a given policy
- std::string GetPolicyWarning(cmPolicies::PolicyID id);
+ static std::string GetPolicyWarning(cmPolicies::PolicyID id);
///! return an error string for when a required policy is unspecified
- std::string GetRequiredPolicyError(cmPolicies::PolicyID id);
+ static std::string GetRequiredPolicyError(cmPolicies::PolicyID id);
///! return an error string for when a required policy is unspecified
- std::string GetRequiredAlwaysPolicyError(cmPolicies::PolicyID id);
-
- ///! Get docs for policies
- void GetDocumentation(std::vector<cmDocumentationEntry>& v);
+ static std::string GetRequiredAlwaysPolicyError(cmPolicies::PolicyID id);
/** Represent a set of policy values. */
- typedef std::map<PolicyID, PolicyStatus> PolicyMap;
+ struct PolicyMap
+ {
+ PolicyStatus Get(PolicyID id) const;
+ void Set(PolicyID id, PolicyStatus status);
+ bool IsDefined(PolicyID id) const;
+ bool IsEmpty() const;
private:
- // might have to make these internal for VS6 not sure yet
- std::map<PolicyID,cmPolicy *> Policies;
- std::map<std::string,PolicyID> PolicyStringMap;
-
- void DiagnoseAncientPolicies(std::vector<PolicyID> const& ancient,
- unsigned int majorVer, unsigned int minorVer,
- unsigned int patchVer, cmMakefile* mf);
-
- bool GetPolicyDefault(cmMakefile* mf, std::string const& policy,
- cmPolicies::PolicyStatus* defaultStatus);
-
+#define POLICY_STATUS_COUNT 3
+ std::bitset<cmPolicies::CMPCOUNT * POLICY_STATUS_COUNT> Status;
+ };
};
#endif
diff --git a/Source/cmProcessTools.cxx b/Source/cmProcessTools.cxx
index d2f7bf320..15d9ed065 100644
--- a/Source/cmProcessTools.cxx
+++ b/Source/cmProcessTools.cxx
@@ -44,7 +44,7 @@ void cmProcessTools::RunProcess(struct cmsysProcess_s* cp,
//----------------------------------------------------------------------------
cmProcessTools::LineParser::LineParser(char sep, bool ignoreCR):
- Separator(sep), IgnoreCR(ignoreCR), Log(0), Prefix(0), LineEnd('\0')
+ Log(0), Prefix(0), Separator(sep), LineEnd('\0'), IgnoreCR(ignoreCR)
{
}
diff --git a/Source/cmProcessTools.h b/Source/cmProcessTools.h
index 439726dd0..23833cabd 100644
--- a/Source/cmProcessTools.h
+++ b/Source/cmProcessTools.h
@@ -51,12 +51,12 @@ public:
/** Configure logging of lines as they are extracted. */
void SetLog(std::ostream* log, const char* prefix);
protected:
- char Separator;
- bool IgnoreCR;
std::ostream* Log;
const char* Prefix;
- char LineEnd;
std::string Line;
+ char Separator;
+ char LineEnd;
+ bool IgnoreCR;
virtual bool ProcessChunk(const char* data, int length);
/** Implement in a subclass to process one line of input. It
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index 11f9a7621..71231259c 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -20,7 +20,7 @@ bool cmProjectCommand
this->SetError("PROJECT called with incorrect number of arguments");
return false;
}
- this->Makefile->SetProjectName(args[0].c_str());
+ this->Makefile->SetProjectName(args[0]);
std::string bindir = args[0];
bindir += "_BINARY_DIR";
@@ -28,21 +28,21 @@ bool cmProjectCommand
srcdir += "_SOURCE_DIR";
this->Makefile->AddCacheDefinition
- (bindir.c_str(),
- this->Makefile->GetCurrentOutputDirectory(),
- "Value Computed by CMake", cmCacheManager::STATIC);
+ (bindir,
+ this->Makefile->GetCurrentBinaryDirectory(),
+ "Value Computed by CMake", cmState::STATIC);
this->Makefile->AddCacheDefinition
- (srcdir.c_str(),
- this->Makefile->GetCurrentDirectory(),
- "Value Computed by CMake", cmCacheManager::STATIC);
+ (srcdir,
+ this->Makefile->GetCurrentSourceDirectory(),
+ "Value Computed by CMake", cmState::STATIC);
bindir = "PROJECT_BINARY_DIR";
srcdir = "PROJECT_SOURCE_DIR";
- this->Makefile->AddDefinition(bindir.c_str(),
- this->Makefile->GetCurrentOutputDirectory());
- this->Makefile->AddDefinition(srcdir.c_str(),
- this->Makefile->GetCurrentDirectory());
+ this->Makefile->AddDefinition(bindir,
+ this->Makefile->GetCurrentBinaryDirectory());
+ this->Makefile->AddDefinition(srcdir,
+ this->Makefile->GetCurrentSourceDirectory());
this->Makefile->AddDefinition("PROJECT_NAME", args[0].c_str());
@@ -53,24 +53,176 @@ bool cmProjectCommand
// CMAKE_PROJECT_NAME will match PROJECT_NAME, and cmake --build
// will work.
if(!this->Makefile->GetDefinition("CMAKE_PROJECT_NAME")
- || (this->Makefile->GetLocalGenerator()->GetParent() == 0) )
+ || (this->Makefile->IsRootMakefile()))
{
this->Makefile->AddDefinition("CMAKE_PROJECT_NAME", args[0].c_str());
this->Makefile->AddCacheDefinition
("CMAKE_PROJECT_NAME",
args[0].c_str(),
- "Value Computed by CMake", cmCacheManager::STATIC);
+ "Value Computed by CMake", cmState::STATIC);
}
+ bool haveVersion = false;
+ bool haveLanguages = false;
+ std::string version;
std::vector<std::string> languages;
- if(args.size() > 1)
+ enum Doing { DoingLanguages, DoingVersion };
+ Doing doing = DoingLanguages;
+ for(size_t i = 1; i < args.size(); ++i)
{
- for(size_t i =1; i < args.size(); ++i)
+ if(args[i] == "LANGUAGES")
+ {
+ if(haveLanguages)
+ {
+ this->Makefile->IssueMessage
+ (cmake::FATAL_ERROR, "LANGUAGES may be specified at most once.");
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
+ }
+ haveLanguages = true;
+ doing = DoingLanguages;
+ }
+ else if (args[i] == "VERSION")
+ {
+ if(haveVersion)
+ {
+ this->Makefile->IssueMessage
+ (cmake::FATAL_ERROR, "VERSION may be specified at most once.");
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
+ }
+ haveVersion = true;
+ doing = DoingVersion;
+ }
+ else if(doing == DoingVersion)
+ {
+ doing = DoingLanguages;
+ version = args[i];
+ }
+ else // doing == DoingLanguages
{
languages.push_back(args[i]);
}
}
- else
+
+ if (haveVersion && !haveLanguages && !languages.empty())
+ {
+ this->Makefile->IssueMessage
+ (cmake::FATAL_ERROR,
+ "project with VERSION must use LANGUAGES before language names.");
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
+ }
+ if (haveLanguages && languages.empty())
+ {
+ languages.push_back("NONE");
+ }
+
+ cmPolicies::PolicyStatus cmp0048 =
+ this->Makefile->GetPolicyStatus(cmPolicies::CMP0048);
+ if (haveVersion)
+ {
+ // Set project VERSION variables to given values
+ if (cmp0048 == cmPolicies::OLD ||
+ cmp0048 == cmPolicies::WARN)
+ {
+ this->Makefile->IssueMessage
+ (cmake::FATAL_ERROR,
+ "VERSION not allowed unless CMP0048 is set to NEW");
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
+ }
+
+ cmsys::RegularExpression
+ vx("^([0-9]+(\\.[0-9]+(\\.[0-9]+(\\.[0-9]+)?)?)?)?$");
+ if(!vx.find(version))
+ {
+ std::string e = "VERSION \"" + version + "\" format invalid.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e);
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
+ }
+
+ std::string vs;
+ const char* sep = "";
+ char vb[4][64];
+ unsigned int v[4] = {0,0,0,0};
+ int vc = sscanf(version.c_str(), "%u.%u.%u.%u",
+ &v[0], &v[1], &v[2], &v[3]);
+ for(int i=0; i < 4; ++i)
+ {
+ if(i < vc)
+ {
+ sprintf(vb[i], "%u", v[i]);
+ vs += sep;
+ vs += vb[i];
+ sep = ".";
+ }
+ else
+ {
+ vb[i][0] = 0;
+ }
+ }
+
+ std::string vv;
+ vv = args[0] + "_VERSION";
+ this->Makefile->AddDefinition("PROJECT_VERSION", vs.c_str());
+ this->Makefile->AddDefinition(vv, vs.c_str());
+ vv = args[0] + "_VERSION_MAJOR";
+ this->Makefile->AddDefinition("PROJECT_VERSION_MAJOR", vb[0]);
+ this->Makefile->AddDefinition(vv, vb[0]);
+ vv = args[0] + "_VERSION_MINOR";
+ this->Makefile->AddDefinition("PROJECT_VERSION_MINOR", vb[1]);
+ this->Makefile->AddDefinition(vv, vb[1]);
+ vv = args[0] + "_VERSION_PATCH";
+ this->Makefile->AddDefinition("PROJECT_VERSION_PATCH", vb[2]);
+ this->Makefile->AddDefinition(vv, vb[2]);
+ vv = args[0] + "_VERSION_TWEAK";
+ this->Makefile->AddDefinition("PROJECT_VERSION_TWEAK", vb[3]);
+ this->Makefile->AddDefinition(vv, vb[3]);
+ }
+ else if(cmp0048 != cmPolicies::OLD)
+ {
+ // Set project VERSION variables to empty
+ std::vector<std::string> vv;
+ vv.push_back("PROJECT_VERSION");
+ vv.push_back("PROJECT_VERSION_MAJOR");
+ vv.push_back("PROJECT_VERSION_MINOR");
+ vv.push_back("PROJECT_VERSION_PATCH");
+ vv.push_back("PROJECT_VERSION_TWEAK");
+ vv.push_back(args[0] + "_VERSION");
+ vv.push_back(args[0] + "_VERSION_MAJOR");
+ vv.push_back(args[0] + "_VERSION_MINOR");
+ vv.push_back(args[0] + "_VERSION_PATCH");
+ vv.push_back(args[0] + "_VERSION_TWEAK");
+ std::string vw;
+ for(std::vector<std::string>::iterator i = vv.begin();
+ i != vv.end(); ++i)
+ {
+ const char* v = this->Makefile->GetDefinition(*i);
+ if(v && *v)
+ {
+ if(cmp0048 == cmPolicies::WARN)
+ {
+ vw += "\n ";
+ vw += *i;
+ }
+ else
+ {
+ this->Makefile->AddDefinition(*i, "");
+ }
+ }
+ }
+ if(!vw.empty())
+ {
+ std::ostringstream w;
+ w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0048)
+ << "\nThe following variable(s) would be set to empty:" << vw;
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ }
+ }
+
+ if (languages.empty())
{
// if no language is specified do c and c++
languages.push_back("C");
@@ -78,20 +230,18 @@ bool cmProjectCommand
}
this->Makefile->EnableLanguage(languages, false);
std::string extraInclude = "CMAKE_PROJECT_" + args[0] + "_INCLUDE";
- const char* include = this->Makefile->GetDefinition(extraInclude.c_str());
+ const char* include = this->Makefile->GetDefinition(extraInclude);
if(include)
{
- std::string fullFilePath;
bool readit =
- this->Makefile->ReadListFile( this->Makefile->GetCurrentListFile(),
- include);
+ this->Makefile->ReadDependentFile(include);
if(!readit && !cmSystemTools::GetFatalErrorOccured())
{
std::string m =
"could not find file:\n"
" ";
m += include;
- this->SetError(m.c_str());
+ this->SetError(m);
return false;
}
}
diff --git a/Source/cmProjectCommand.h b/Source/cmProjectCommand.h
index 9547c4c8f..7aacb5537 100644
--- a/Source/cmProjectCommand.h
+++ b/Source/cmProjectCommand.h
@@ -43,42 +43,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const {return "project";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Set a name for the entire project.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " project(<projectname> [languageName1 languageName2 ... ] )\n"
- "Sets the name of the project. "
- "Additionally this sets the variables <projectName>_BINARY_DIR and "
- "<projectName>_SOURCE_DIR to the respective values.\n"
- "Optionally you can specify which languages your project supports. "
- "Example languages are CXX (i.e. C++), C, Fortran, etc. "
- "By default C and CXX are enabled. E.g. if you do not have a "
- "C++ compiler, you can disable the check for it by explicitly listing "
- "the languages you want to support, e.g. C. By using the special "
- "language \"NONE\" all checks for any language can be disabled. "
- "If a variable exists called CMAKE_PROJECT_<projectName>_INCLUDE, "
- "the file pointed to by that variable will be included as the last step "
- "of the project command."
- "\n"
- "The top-level CMakeLists.txt file for a project must contain a "
- "literal, direct call to the project() command; loading one through "
- "the include() command is not sufficient. "
- "If no such call exists CMake will implicitly add one to the top that "
- "enables the default languages (C and CXX).";
- }
+ virtual std::string GetName() const {return "project";}
cmTypeMacro(cmProjectCommand, cmCommand);
};
diff --git a/Source/cmProperty.cxx b/Source/cmProperty.cxx
index 3b37cf3b8..ef57068ad 100644
--- a/Source/cmProperty.cxx
+++ b/Source/cmProperty.cxx
@@ -12,16 +12,14 @@
#include "cmProperty.h"
#include "cmSystemTools.h"
-void cmProperty::Set(const char *name, const char *value)
+void cmProperty::Set(const char *value)
{
- this->Name = name;
this->Value = value;
this->ValueHasBeenSet = true;
}
-void cmProperty::Append(const char *name, const char *value, bool asString)
+void cmProperty::Append(const char *value, bool asString)
{
- this->Name = name;
if(!this->Value.empty() && *value && !asString)
{
this->Value += ";";
diff --git a/Source/cmProperty.h b/Source/cmProperty.h
index bb75bb0b9..e026372db 100644
--- a/Source/cmProperty.h
+++ b/Source/cmProperty.h
@@ -18,22 +18,21 @@ class cmProperty
{
public:
enum ScopeType { TARGET, SOURCE_FILE, DIRECTORY, GLOBAL, CACHE,
- TEST, VARIABLE, CACHED_VARIABLE };
+ TEST, VARIABLE, CACHED_VARIABLE, INSTALL };
// set this property
- void Set(const char *name, const char *value);
+ void Set(const char *value);
// append to this property
- void Append(const char *name, const char *value, bool asString = false);
+ void Append(const char *value, bool asString = false);
// get the value
const char *GetValue() const;
// construct with the value not set
- cmProperty() { this->ValueHasBeenSet = false; };
+ cmProperty() { this->ValueHasBeenSet = false; }
protected:
- std::string Name;
std::string Value;
bool ValueHasBeenSet;
};
diff --git a/Source/cmPropertyDefinition.cxx b/Source/cmPropertyDefinition.cxx
index b80c863f1..1af967c94 100644
--- a/Source/cmPropertyDefinition.cxx
+++ b/Source/cmPropertyDefinition.cxx
@@ -12,20 +12,10 @@
#include "cmPropertyDefinition.h"
#include "cmSystemTools.h"
-cmDocumentationEntry cmPropertyDefinition::GetDocumentation() const
-{
- cmDocumentationEntry e;
- e.Name = this->Name;
- e.Brief = this->ShortDescription;
- e.Full = this->FullDescription;
- return e;
-}
-
void cmPropertyDefinition
-::DefineProperty(const char *name, cmProperty::ScopeType scope,
+::DefineProperty(const std::string& name, cmProperty::ScopeType scope,
const char *shortDescription,
const char *fullDescription,
- const char *sec,
bool chain)
{
this->Name = name;
@@ -39,9 +29,5 @@ void cmPropertyDefinition
{
this->FullDescription = fullDescription;
}
- if (sec)
- {
- this->DocumentationSection = sec;
- }
}
diff --git a/Source/cmPropertyDefinition.h b/Source/cmPropertyDefinition.h
index 296366dca..098fadb75 100644
--- a/Source/cmPropertyDefinition.h
+++ b/Source/cmPropertyDefinition.h
@@ -27,42 +27,33 @@ class cmPropertyDefinition
{
public:
/// Define this property
- void DefineProperty(const char *name, cmProperty::ScopeType scope,
+ void DefineProperty(const std::string& name, cmProperty::ScopeType scope,
const char *ShortDescription,
const char *FullDescription,
- const char *DocumentationSection,
bool chained);
- /// Get the documentation string
- cmDocumentationEntry GetDocumentation() const;
-
/// Default constructor
- cmPropertyDefinition() { this->Chained = false; };
+ cmPropertyDefinition() { this->Chained = false; }
/// Is the property chained?
- bool IsChained() const { return this->Chained; };
-
- /// Get the section if any
- const std::string &GetDocumentationSection() const {
- return this->DocumentationSection; };
+ bool IsChained() const { return this->Chained; }
/// Get the scope
cmProperty::ScopeType GetScope() const {
- return this->Scope; };
+ return this->Scope; }
/// Get the documentation (short version)
const std::string &GetShortDescription() const {
- return this->ShortDescription; };
+ return this->ShortDescription; }
/// Get the documentation (full version)
const std::string &GetFullDescription() const {
- return this->FullDescription; };
+ return this->FullDescription; }
protected:
std::string Name;
std::string ShortDescription;
std::string FullDescription;
- std::string DocumentationSection;
cmProperty::ScopeType Scope;
bool Chained;
};
diff --git a/Source/cmPropertyDefinitionMap.cxx b/Source/cmPropertyDefinitionMap.cxx
index 20fa07c43..776fad1dc 100644
--- a/Source/cmPropertyDefinitionMap.cxx
+++ b/Source/cmPropertyDefinitionMap.cxx
@@ -14,92 +14,24 @@
#include "cmDocumentationSection.h"
void cmPropertyDefinitionMap
-::DefineProperty(const char *name, cmProperty::ScopeType scope,
+::DefineProperty(const std::string& name, cmProperty::ScopeType scope,
const char *ShortDescription,
const char *FullDescription,
- const char *DocumentationSection,
bool chain)
{
- if (!name)
- {
- return;
- }
-
cmPropertyDefinitionMap::iterator it = this->find(name);
cmPropertyDefinition *prop;
if (it == this->end())
{
prop = &(*this)[name];
prop->DefineProperty(name,scope,ShortDescription, FullDescription,
- DocumentationSection, chain);
- }
-}
-
-void cmPropertyDefinitionMap
-::GetPropertiesDocumentation(std::map<std::string,
- cmDocumentationSection *>& v) const
-{
- for(cmPropertyDefinitionMap::const_iterator j = this->begin();
- j != this->end(); ++j)
- {
- // add a section if needed
- std::string secName = j->second.GetDocumentationSection();
- // if a section was not specified then use the scope
- if (!secName.size())
- {
- switch (j->second.GetScope())
- {
- case cmProperty::GLOBAL:
- secName = "Properties of Global Scope";
- break;
- case cmProperty::TARGET:
- secName = "Properties on Targets";
- break;
- case cmProperty::SOURCE_FILE:
- secName = "Properties on Source Files";
- break;
- case cmProperty::DIRECTORY:
- secName = "Properties on Directories";
- break;
- case cmProperty::TEST:
- secName = "Properties on Tests";
- break;
- case cmProperty::CACHE:
- secName = "Properties on Cache Entries";
- break;
- case cmProperty::VARIABLE:
- secName = "Variables";
- break;
- case cmProperty::CACHED_VARIABLE:
- secName = "Cached Variables";
- break;
- default:
- secName = "Properties of Unknown Scope";
- break;
- }
- }
- if (!v[secName])
- {
- v[secName] = new
- cmDocumentationSection(secName.c_str(),
- cmSystemTools::UpperCase(secName).c_str());
- }
- cmDocumentationEntry e = j->second.GetDocumentation();
- if (e.Brief.size() || e.Full.size())
- {
- v[secName]->Append(e);
- }
+ chain);
}
}
-bool cmPropertyDefinitionMap::IsPropertyDefined(const char *name)
+bool cmPropertyDefinitionMap::IsPropertyDefined(const std::string& name) const
{
- if (!name)
- {
- return false;
- }
-
- cmPropertyDefinitionMap::iterator it = this->find(name);
+ cmPropertyDefinitionMap::const_iterator it = this->find(name);
if (it == this->end())
{
return false;
@@ -108,14 +40,9 @@ bool cmPropertyDefinitionMap::IsPropertyDefined(const char *name)
return true;
}
-bool cmPropertyDefinitionMap::IsPropertyChained(const char *name)
+bool cmPropertyDefinitionMap::IsPropertyChained(const std::string& name) const
{
- if (!name)
- {
- return false;
- }
-
- cmPropertyDefinitionMap::iterator it = this->find(name);
+ cmPropertyDefinitionMap::const_iterator it = this->find(name);
if (it == this->end())
{
return false;
diff --git a/Source/cmPropertyDefinitionMap.h b/Source/cmPropertyDefinitionMap.h
index 007e26515..f95c721a8 100644
--- a/Source/cmPropertyDefinitionMap.h
+++ b/Source/cmPropertyDefinitionMap.h
@@ -17,24 +17,20 @@
class cmDocumentationSection;
class cmPropertyDefinitionMap :
-public std::map<cmStdString,cmPropertyDefinition>
+public std::map<std::string,cmPropertyDefinition>
{
public:
// define the property
- void DefineProperty(const char *name, cmProperty::ScopeType scope,
+ void DefineProperty(const std::string& name, cmProperty::ScopeType scope,
const char *ShortDescription,
const char *FullDescription,
- const char *DocumentaitonSection,
bool chain);
// has a named property been defined
- bool IsPropertyDefined(const char *name);
+ bool IsPropertyDefined(const std::string& name) const;
// is a named property set to chain
- bool IsPropertyChained(const char *name);
-
- void GetPropertiesDocumentation(std::map<std::string,
- cmDocumentationSection *>&) const;
+ bool IsPropertyChained(const std::string& name) const;
};
#endif
diff --git a/Source/cmPropertyMap.cxx b/Source/cmPropertyMap.cxx
index 78f378ab7..ef09dbcf0 100644
--- a/Source/cmPropertyMap.cxx
+++ b/Source/cmPropertyMap.cxx
@@ -12,8 +12,11 @@
#include "cmPropertyMap.h"
#include "cmSystemTools.h"
#include "cmake.h"
+#include "cmState.h"
-cmProperty *cmPropertyMap::GetOrCreateProperty(const char *name)
+#include <assert.h>
+
+cmProperty *cmPropertyMap::GetOrCreateProperty(const std::string& name)
{
cmPropertyMap::iterator it = this->find(name);
cmProperty *prop;
@@ -28,94 +31,39 @@ cmProperty *cmPropertyMap::GetOrCreateProperty(const char *name)
return prop;
}
-void cmPropertyMap::SetProperty(const char *name, const char *value,
- cmProperty::ScopeType scope)
+void cmPropertyMap::SetProperty(const std::string& name, const char *value)
{
- if (!name)
- {
- return;
- }
if(!value)
{
this->erase(name);
return;
}
-#ifdef CMAKE_STRICT
- if (!this->CMakeInstance)
- {
- cmSystemTools::Error("CMakeInstance not set on a property map!");
- abort();
- }
- else
- {
- this->CMakeInstance->RecordPropertyAccess(name,scope);
- }
-#else
- (void)scope;
-#endif
cmProperty *prop = this->GetOrCreateProperty(name);
- prop->Set(name,value);
+ prop->Set(value);
}
-void cmPropertyMap::AppendProperty(const char* name, const char* value,
- cmProperty::ScopeType scope, bool asString)
+void cmPropertyMap::AppendProperty(const std::string& name, const char* value,
+ bool asString)
{
// Skip if nothing to append.
- if(!name || !value || !*value)
+ if(!value || !*value)
{
return;
}
-#ifdef CMAKE_STRICT
- if (!this->CMakeInstance)
- {
- cmSystemTools::Error("CMakeInstance not set on a property map!");
- abort();
- }
- else
- {
- this->CMakeInstance->RecordPropertyAccess(name,scope);
- }
-#else
- (void)scope;
-#endif
cmProperty *prop = this->GetOrCreateProperty(name);
- prop->Append(name,value,asString);
+ prop->Append(value,asString);
}
const char *cmPropertyMap
-::GetPropertyValue(const char *name,
- cmProperty::ScopeType scope,
- bool &chain) const
+::GetPropertyValue(const std::string& name) const
{
- chain = false;
- if (!name)
- {
- return 0;
- }
-
- // has the property been defined?
-#ifdef CMAKE_STRICT
- if (!this->CMakeInstance)
- {
- cmSystemTools::Error("CMakeInstance not set on a property map!");
- abort();
- }
- else
- {
- this->CMakeInstance->RecordPropertyAccess(name,scope);
- }
-#endif
+ assert(!name.empty());
cmPropertyMap::const_iterator it = this->find(name);
if (it == this->end())
{
- // should we chain up?
- if (this->CMakeInstance)
- {
- chain = this->CMakeInstance->IsPropertyChained(name,scope);
- }
return 0;
}
return it->second.GetValue();
diff --git a/Source/cmPropertyMap.h b/Source/cmPropertyMap.h
index 0c3aad461..a9062dbbd 100644
--- a/Source/cmPropertyMap.h
+++ b/Source/cmPropertyMap.h
@@ -14,29 +14,17 @@
#include "cmProperty.h"
-class cmake;
-
-class cmPropertyMap : public std::map<cmStdString,cmProperty>
+class cmPropertyMap : public std::map<std::string,cmProperty>
{
public:
- cmProperty *GetOrCreateProperty(const char *name);
-
- void SetProperty(const char *name, const char *value,
- cmProperty::ScopeType scope);
-
- void AppendProperty(const char* name, const char* value,
- cmProperty::ScopeType scope, bool asString=false);
-
- const char *GetPropertyValue(const char *name,
- cmProperty::ScopeType scope,
- bool &chain) const;
+ cmProperty *GetOrCreateProperty(const std::string& name);
- void SetCMakeInstance(cmake *cm) { this->CMakeInstance = cm; };
+ void SetProperty(const std::string& name, const char *value);
- cmPropertyMap() { this->CMakeInstance = 0;};
+ void AppendProperty(const std::string& name, const char* value,
+ bool asString=false);
-private:
- cmake *CMakeInstance;
+ const char *GetPropertyValue(const std::string& name) const;
};
#endif
diff --git a/Source/cmQTWrapCPPCommand.cxx b/Source/cmQTWrapCPPCommand.cxx
index 0d3c9941c..aae1bb967 100644
--- a/Source/cmQTWrapCPPCommand.cxx
+++ b/Source/cmQTWrapCPPCommand.cxx
@@ -12,19 +12,15 @@
#include "cmQTWrapCPPCommand.h"
// cmQTWrapCPPCommand
-bool cmQTWrapCPPCommand::InitialPass(std::vector<std::string> const& argsIn,
+bool cmQTWrapCPPCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus &)
{
- if(argsIn.size() < 3 )
+ if(args.size() < 3 )
{
this->SetError("called with incorrect number of arguments");
return false;
}
- // This command supports source list inputs for compatibility.
- std::vector<std::string> args;
- this->Makefile->ExpandSourceListArguments(argsIn, args, 2);
-
// Get the moc executable to run in the custom command.
const char* moc_exe =
this->Makefile->GetRequiredDefinition("QT_MOC_EXECUTABLE");
@@ -32,25 +28,25 @@ bool cmQTWrapCPPCommand::InitialPass(std::vector<std::string> const& argsIn,
// Get the variable holding the list of sources.
std::string const& sourceList = args[1];
std::string sourceListValue =
- this->Makefile->GetSafeDefinition(sourceList.c_str());
+ this->Makefile->GetSafeDefinition(sourceList);
// Create a rule for all sources listed.
- for(std::vector<std::string>::iterator j = (args.begin() + 2);
+ for(std::vector<std::string>::const_iterator j = (args.begin() + 2);
j != args.end(); ++j)
{
- cmSourceFile *curr = this->Makefile->GetSource(j->c_str());
+ cmSourceFile *curr = this->Makefile->GetSource(*j);
// if we should wrap the class
if(!(curr && curr->GetPropertyAsBool("WRAP_EXCLUDE")))
{
// Compute the name of the file to generate.
std::string srcName =
cmSystemTools::GetFilenameWithoutLastExtension(*j);
- std::string newName = this->Makefile->GetCurrentOutputDirectory();
+ std::string newName = this->Makefile->GetCurrentBinaryDirectory();
newName += "/moc_";
newName += srcName;
newName += ".cxx";
cmSourceFile* sf =
- this->Makefile->GetOrCreateSource(newName.c_str(), true);
+ this->Makefile->GetOrCreateSource(newName, true);
if (curr)
{
sf->SetProperty("ABSTRACT", curr->GetProperty("ABSTRACT"));
@@ -66,11 +62,11 @@ bool cmQTWrapCPPCommand::InitialPass(std::vector<std::string> const& argsIn,
{
if(curr && curr->GetPropertyAsBool("GENERATED"))
{
- hname = this->Makefile->GetCurrentOutputDirectory();
+ hname = this->Makefile->GetCurrentBinaryDirectory();
}
else
{
- hname = this->Makefile->GetCurrentDirectory();
+ hname = this->Makefile->GetCurrentSourceDirectory();
}
hname += "/";
hname += *j;
@@ -97,9 +93,9 @@ bool cmQTWrapCPPCommand::InitialPass(std::vector<std::string> const& argsIn,
depends.push_back(moc_exe);
depends.push_back(hname);
- const char* no_main_dependency = 0;
+ std::string no_main_dependency = "";
const char* no_working_dir = 0;
- this->Makefile->AddCustomCommandToOutput(newName.c_str(),
+ this->Makefile->AddCustomCommandToOutput(newName,
depends,
no_main_dependency,
commandLines,
@@ -109,7 +105,7 @@ bool cmQTWrapCPPCommand::InitialPass(std::vector<std::string> const& argsIn,
}
// Store the final list of source files.
- this->Makefile->AddDefinition(sourceList.c_str(),
+ this->Makefile->AddDefinition(sourceList,
sourceListValue.c_str());
return true;
}
diff --git a/Source/cmQTWrapCPPCommand.h b/Source/cmQTWrapCPPCommand.h
index 4863402e4..85729ddc9 100644
--- a/Source/cmQTWrapCPPCommand.h
+++ b/Source/cmQTWrapCPPCommand.h
@@ -45,28 +45,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "qt_wrap_cpp";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Create Qt Wrappers.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " qt_wrap_cpp(resultingLibraryName DestName\n"
- " SourceLists ...)\n"
- "Produce moc files for all the .h files listed in the SourceLists. "
- "The moc files will be added to the library using the DestName "
- "source list.";
- }
+ virtual std::string GetName() const { return "qt_wrap_cpp";}
};
diff --git a/Source/cmQTWrapUICommand.cxx b/Source/cmQTWrapUICommand.cxx
index a6a4b5158..3adea2967 100644
--- a/Source/cmQTWrapUICommand.cxx
+++ b/Source/cmQTWrapUICommand.cxx
@@ -12,19 +12,15 @@
#include "cmQTWrapUICommand.h"
// cmQTWrapUICommand
-bool cmQTWrapUICommand::InitialPass(std::vector<std::string> const& argsIn,
+bool cmQTWrapUICommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus &)
{
- if(argsIn.size() < 4 )
+ if(args.size() < 4 )
{
this->SetError("called with incorrect number of arguments");
return false;
}
- // This command supports source list inputs for compatibility.
- std::vector<std::string> args;
- this->Makefile->ExpandSourceListArguments(argsIn, args, 3);
-
// Get the uic and moc executables to run in the custom commands.
const char* uic_exe =
this->Makefile->GetRequiredDefinition("QT_UIC_EXECUTABLE");
@@ -35,30 +31,30 @@ bool cmQTWrapUICommand::InitialPass(std::vector<std::string> const& argsIn,
std::string const& headerList = args[1];
std::string const& sourceList = args[2];
std::string headerListValue =
- this->Makefile->GetSafeDefinition(headerList.c_str());
+ this->Makefile->GetSafeDefinition(headerList);
std::string sourceListValue =
- this->Makefile->GetSafeDefinition(sourceList.c_str());
+ this->Makefile->GetSafeDefinition(sourceList);
// Create rules for all sources listed.
- for(std::vector<std::string>::iterator j = (args.begin() + 3);
+ for(std::vector<std::string>::const_iterator j = (args.begin() + 3);
j != args.end(); ++j)
{
- cmSourceFile *curr = this->Makefile->GetSource(j->c_str());
+ cmSourceFile *curr = this->Makefile->GetSource(*j);
// if we should wrap the class
if(!(curr && curr->GetPropertyAsBool("WRAP_EXCLUDE")))
{
// Compute the name of the files to generate.
std::string srcName =
cmSystemTools::GetFilenameWithoutLastExtension(*j);
- std::string hName = this->Makefile->GetCurrentOutputDirectory();
+ std::string hName = this->Makefile->GetCurrentBinaryDirectory();
hName += "/";
hName += srcName;
hName += ".h";
- std::string cxxName = this->Makefile->GetCurrentOutputDirectory();
+ std::string cxxName = this->Makefile->GetCurrentBinaryDirectory();
cxxName += "/";
cxxName += srcName;
cxxName += ".cxx";
- std::string mocName = this->Makefile->GetCurrentOutputDirectory();
+ std::string mocName = this->Makefile->GetCurrentBinaryDirectory();
mocName += "/moc_";
mocName += srcName;
mocName += ".cxx";
@@ -73,11 +69,11 @@ bool cmQTWrapUICommand::InitialPass(std::vector<std::string> const& argsIn,
{
if(curr && curr->GetPropertyAsBool("GENERATED"))
{
- uiName = this->Makefile->GetCurrentOutputDirectory();
+ uiName = this->Makefile->GetCurrentBinaryDirectory();
}
else
{
- uiName = this->Makefile->GetCurrentDirectory();
+ uiName = this->Makefile->GetCurrentSourceDirectory();
}
uiName += "/";
uiName += *j;
@@ -128,10 +124,10 @@ bool cmQTWrapUICommand::InitialPass(std::vector<std::string> const& argsIn,
std::vector<std::string> depends;
depends.push_back(uiName);
- const char* no_main_dependency = 0;
+ std::string no_main_dependency = "";
const char* no_comment = 0;
const char* no_working_dir = 0;
- this->Makefile->AddCustomCommandToOutput(hName.c_str(),
+ this->Makefile->AddCustomCommandToOutput(hName,
depends,
no_main_dependency,
hCommandLines,
@@ -139,7 +135,7 @@ bool cmQTWrapUICommand::InitialPass(std::vector<std::string> const& argsIn,
no_working_dir);
depends.push_back(hName);
- this->Makefile->AddCustomCommandToOutput(cxxName.c_str(),
+ this->Makefile->AddCustomCommandToOutput(cxxName,
depends,
no_main_dependency,
cxxCommandLines,
@@ -148,7 +144,7 @@ bool cmQTWrapUICommand::InitialPass(std::vector<std::string> const& argsIn,
depends.clear();
depends.push_back(hName);
- this->Makefile->AddCustomCommandToOutput(mocName.c_str(),
+ this->Makefile->AddCustomCommandToOutput(mocName,
depends,
no_main_dependency,
mocCommandLines,
@@ -158,9 +154,9 @@ bool cmQTWrapUICommand::InitialPass(std::vector<std::string> const& argsIn,
}
// Store the final list of source files and headers.
- this->Makefile->AddDefinition(sourceList.c_str(),
+ this->Makefile->AddDefinition(sourceList,
sourceListValue.c_str());
- this->Makefile->AddDefinition(headerList.c_str(),
+ this->Makefile->AddDefinition(headerList,
headerListValue.c_str());
return true;
}
diff --git a/Source/cmQTWrapUICommand.h b/Source/cmQTWrapUICommand.h
index b15c5cde0..4aa9a614a 100644
--- a/Source/cmQTWrapUICommand.h
+++ b/Source/cmQTWrapUICommand.h
@@ -43,31 +43,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "qt_wrap_ui";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Create Qt user interfaces Wrappers.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " qt_wrap_ui(resultingLibraryName HeadersDestName\n"
- " SourcesDestName SourceLists ...)\n"
- "Produce .h and .cxx files for all the .ui files listed "
- "in the SourceLists. "
- "The .h files will be added to the library using the HeadersDestName"
- "source list. "
- "The .cxx files will be added to the library using the SourcesDestName"
- "source list.";
- }
+ virtual std::string GetName() const { return "qt_wrap_ui";}
};
diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx
new file mode 100644
index 000000000..08caea3c2
--- /dev/null
+++ b/Source/cmQtAutoGeneratorInitializer.cxx
@@ -0,0 +1,1072 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2004-2011 Kitware, Inc.
+ Copyright 2011 Alexander Neundorf (neundorf@kde.org)
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmQtAutoGeneratorInitializer.h"
+
+#include "cmLocalGenerator.h"
+#include "cmMakefile.h"
+#include "cmSourceFile.h"
+
+#include <sys/stat.h>
+
+#include <cmsys/FStream.hxx>
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# include "cmGlobalVisualStudioGenerator.h"
+#endif
+
+static void SetupSourceFiles(cmGeneratorTarget const* target,
+ std::vector<std::string>& skipMoc,
+ std::vector<std::string>& mocSources,
+ std::vector<std::string>& mocHeaders,
+ std::vector<std::string>& skipUic)
+{
+ cmMakefile* makefile = target->Target->GetMakefile();
+
+ std::vector<cmSourceFile*> srcFiles;
+ target->GetConfigCommonSourceFiles(srcFiles);
+
+ std::vector<std::string> newRccFiles;
+
+ for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
+ fileIt != srcFiles.end();
+ ++fileIt)
+ {
+ cmSourceFile* sf = *fileIt;
+ std::string absFile = cmsys::SystemTools::GetRealPath(
+ sf->GetFullPath());
+ bool skipFileForMoc =
+ cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOMOC"));
+ bool generated = cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"));
+
+ if(cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOUIC")))
+ {
+ skipUic.push_back(absFile);
+ }
+
+ std::string ext = sf->GetExtension();
+
+ if (target->GetPropertyAsBool("AUTORCC"))
+ {
+ if (ext == "qrc"
+ && !cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC")))
+ {
+ std::string basename = cmsys::SystemTools::
+ GetFilenameWithoutLastExtension(absFile);
+
+ std::string rcc_output_dir = target->GetSupportDirectory();
+ cmSystemTools::MakeDirectory(rcc_output_dir.c_str());
+ std::string rcc_output_file = rcc_output_dir;
+ rcc_output_file += "/qrc_" + basename + ".cpp";
+ makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
+ rcc_output_file.c_str(), false);
+ makefile->GetOrCreateSource(rcc_output_file, true);
+ newRccFiles.push_back(rcc_output_file);
+ }
+ }
+
+ if (!generated)
+ {
+ if (skipFileForMoc)
+ {
+ skipMoc.push_back(absFile);
+ }
+ else
+ {
+ cmSystemTools::FileFormat fileType = cmSystemTools::GetFileFormat(
+ ext.c_str());
+ if (fileType == cmSystemTools::CXX_FILE_FORMAT)
+ {
+ mocSources.push_back(absFile);
+ }
+ else if (fileType == cmSystemTools::HEADER_FILE_FORMAT)
+ {
+ mocHeaders.push_back(absFile);
+ }
+ }
+ }
+ }
+
+ for(std::vector<std::string>::const_iterator fileIt = newRccFiles.begin();
+ fileIt != newRccFiles.end();
+ ++fileIt)
+ {
+ const_cast<cmGeneratorTarget*>(target)->AddSource(*fileIt);
+ }
+}
+
+static void GetCompileDefinitionsAndDirectories(
+ cmGeneratorTarget const* target,
+ const std::string& config,
+ std::string &incs,
+ std::string &defs)
+{
+ std::vector<std::string> includeDirs;
+ cmLocalGenerator *localGen = target->GetLocalGenerator();
+ // Get the include dirs for this target, without stripping the implicit
+ // include dirs off, see http://public.kitware.com/Bug/view.php?id=13667
+ localGen->GetIncludeDirectories(includeDirs, target, "CXX", config, false);
+
+ incs = cmJoin(includeDirs, ";");
+
+ std::set<std::string> defines;
+ localGen->AddCompileDefinitions(defines, target, config, "CXX");
+
+ defs += cmJoin(defines, ";");
+}
+
+static void SetupAutoMocTarget(cmGeneratorTarget const* target,
+ const std::string &autogenTargetName,
+ std::vector<std::string> const& skipMoc,
+ std::vector<std::string> const& mocHeaders,
+ std::map<std::string, std::string> &configIncludes,
+ std::map<std::string, std::string> &configDefines)
+{
+ cmLocalGenerator* lg = target->GetLocalGenerator();
+ cmMakefile* makefile = target->Target->GetMakefile();
+
+ const char* tmp = target->GetProperty("AUTOMOC_MOC_OPTIONS");
+ std::string _moc_options = (tmp!=0 ? tmp : "");
+ makefile->AddDefinition("_moc_options",
+ cmOutputConverter::EscapeForCMake(_moc_options).c_str());
+ makefile->AddDefinition("_skip_moc",
+ cmOutputConverter::EscapeForCMake(cmJoin(skipMoc, ";")).c_str());
+ makefile->AddDefinition("_moc_headers",
+ cmOutputConverter::EscapeForCMake(cmJoin(mocHeaders, ";")).c_str());
+ bool relaxedMode = makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE");
+ makefile->AddDefinition("_moc_relaxed_mode", relaxedMode ? "TRUE" : "FALSE");
+
+ std::string _moc_incs;
+ std::string _moc_compile_defs;
+ std::vector<std::string> configs;
+ const std::string& config = makefile->GetConfigurations(configs);
+ GetCompileDefinitionsAndDirectories(target, config,
+ _moc_incs, _moc_compile_defs);
+
+ makefile->AddDefinition("_moc_incs",
+ cmOutputConverter::EscapeForCMake(_moc_incs).c_str());
+ makefile->AddDefinition("_moc_compile_defs",
+ cmOutputConverter::EscapeForCMake(_moc_compile_defs).c_str());
+
+ for (std::vector<std::string>::const_iterator li = configs.begin();
+ li != configs.end(); ++li)
+ {
+ std::string config_moc_incs;
+ std::string config_moc_compile_defs;
+ GetCompileDefinitionsAndDirectories(target, *li,
+ config_moc_incs,
+ config_moc_compile_defs);
+ if (config_moc_incs != _moc_incs)
+ {
+ configIncludes[*li] =
+ cmOutputConverter::EscapeForCMake(config_moc_incs);
+ if(_moc_incs.empty())
+ {
+ _moc_incs = config_moc_incs;
+ }
+ }
+ if (config_moc_compile_defs != _moc_compile_defs)
+ {
+ configDefines[*li] =
+ cmOutputConverter::EscapeForCMake(config_moc_compile_defs);
+ if(_moc_compile_defs.empty())
+ {
+ _moc_compile_defs = config_moc_compile_defs;
+ }
+ }
+ }
+
+ const char *qtVersion = makefile->GetDefinition("_target_qt_version");
+ if (strcmp(qtVersion, "5") == 0)
+ {
+ cmGeneratorTarget *qt5Moc =
+ lg->FindGeneratorTargetToUse("Qt5::moc");
+ if (!qt5Moc)
+ {
+ cmSystemTools::Error("Qt5::moc target not found ",
+ autogenTargetName.c_str());
+ return;
+ }
+ makefile->AddDefinition("_qt_moc_executable",
+ qt5Moc->ImportedGetLocation(""));
+ }
+ else if (strcmp(qtVersion, "4") == 0)
+ {
+ cmGeneratorTarget *qt4Moc =
+ lg->FindGeneratorTargetToUse("Qt4::moc");
+ if (!qt4Moc)
+ {
+ cmSystemTools::Error("Qt4::moc target not found ",
+ autogenTargetName.c_str());
+ return;
+ }
+ makefile->AddDefinition("_qt_moc_executable",
+ qt4Moc->ImportedGetLocation(""));
+ }
+ else
+ {
+ cmSystemTools::Error("The CMAKE_AUTOMOC feature supports only Qt 4 and "
+ "Qt 5 ", autogenTargetName.c_str());
+ }
+}
+
+static void GetUicOpts(cmGeneratorTarget const* target,
+ const std::string& config,
+ std::string &optString)
+{
+ std::vector<std::string> opts;
+ target->GetAutoUicOptions(opts, config);
+ optString = cmJoin(opts, ";");
+}
+
+static void SetupAutoUicTarget(cmGeneratorTarget const* target,
+ std::vector<std::string> const& skipUic,
+ std::map<std::string, std::string> &configUicOptions)
+{
+ cmLocalGenerator* lg = target->GetLocalGenerator();
+ cmMakefile *makefile = target->Target->GetMakefile();
+
+ std::set<std::string> skipped;
+ skipped.insert(skipUic.begin(), skipUic.end());
+
+ makefile->AddDefinition("_skip_uic",
+ cmOutputConverter::EscapeForCMake(cmJoin(skipUic, ";")).c_str());
+
+ std::vector<cmSourceFile*> uiFilesWithOptions
+ = makefile->GetQtUiFilesWithOptions();
+
+ const char *qtVersion = makefile->GetDefinition("_target_qt_version");
+
+ std::string _uic_opts;
+ std::vector<std::string> configs;
+ const std::string& config = makefile->GetConfigurations(configs);
+ GetUicOpts(target, config, _uic_opts);
+
+ if (!_uic_opts.empty())
+ {
+ _uic_opts = cmOutputConverter::EscapeForCMake(_uic_opts);
+ makefile->AddDefinition("_uic_target_options", _uic_opts.c_str());
+ }
+ for (std::vector<std::string>::const_iterator li = configs.begin();
+ li != configs.end(); ++li)
+ {
+ std::string config_uic_opts;
+ GetUicOpts(target, *li, config_uic_opts);
+ if (config_uic_opts != _uic_opts)
+ {
+ configUicOptions[*li] =
+ cmOutputConverter::EscapeForCMake(config_uic_opts);
+ if(_uic_opts.empty())
+ {
+ _uic_opts = config_uic_opts;
+ }
+ }
+ }
+
+ std::string uiFileFiles;
+ std::string uiFileOptions;
+ const char* sep = "";
+
+ for(std::vector<cmSourceFile*>::const_iterator fileIt =
+ uiFilesWithOptions.begin();
+ fileIt != uiFilesWithOptions.end();
+ ++fileIt)
+ {
+ cmSourceFile* sf = *fileIt;
+ std::string absFile = cmsys::SystemTools::GetRealPath(
+ sf->GetFullPath());
+
+ if (!skipped.insert(absFile).second)
+ {
+ continue;
+ }
+ uiFileFiles += sep;
+ uiFileFiles += absFile;
+ uiFileOptions += sep;
+ std::string opts = sf->GetProperty("AUTOUIC_OPTIONS");
+ cmSystemTools::ReplaceString(opts, ";", "@list_sep@");
+ uiFileOptions += opts;
+ sep = ";";
+ }
+
+ makefile->AddDefinition("_qt_uic_options_files",
+ cmOutputConverter::EscapeForCMake(uiFileFiles).c_str());
+ makefile->AddDefinition("_qt_uic_options_options",
+ cmOutputConverter::EscapeForCMake(uiFileOptions).c_str());
+
+ std::string targetName = target->GetName();
+ if (strcmp(qtVersion, "5") == 0)
+ {
+ cmGeneratorTarget *qt5Uic =
+ lg->FindGeneratorTargetToUse("Qt5::uic");
+ if (!qt5Uic)
+ {
+ // Project does not use Qt5Widgets, but has AUTOUIC ON anyway
+ }
+ else
+ {
+ makefile->AddDefinition("_qt_uic_executable",
+ qt5Uic->ImportedGetLocation(""));
+ }
+ }
+ else if (strcmp(qtVersion, "4") == 0)
+ {
+ cmGeneratorTarget *qt4Uic =
+ lg->FindGeneratorTargetToUse("Qt4::uic");
+ if (!qt4Uic)
+ {
+ cmSystemTools::Error("Qt4::uic target not found ",
+ targetName.c_str());
+ return;
+ }
+ makefile->AddDefinition("_qt_uic_executable",
+ qt4Uic->ImportedGetLocation(""));
+ }
+ else
+ {
+ cmSystemTools::Error("The CMAKE_AUTOUIC feature supports only Qt 4 and "
+ "Qt 5 ", targetName.c_str());
+ }
+}
+
+static std::string GetRccExecutable(cmGeneratorTarget const* target)
+{
+ cmLocalGenerator* lg = target->GetLocalGenerator();
+ cmMakefile *makefile = target->Target->GetMakefile();
+ const char *qtVersion = makefile->GetDefinition("_target_qt_version");
+ if (!qtVersion)
+ {
+ qtVersion = makefile->GetDefinition("Qt5Core_VERSION_MAJOR");
+ if (!qtVersion)
+ {
+ qtVersion = makefile->GetDefinition("QT_VERSION_MAJOR");
+ }
+ if (const char *targetQtVersion =
+ target->GetLinkInterfaceDependentStringProperty("QT_MAJOR_VERSION",
+ ""))
+ {
+ qtVersion = targetQtVersion;
+ }
+ }
+
+ std::string targetName = target->GetName();
+ if (strcmp(qtVersion, "5") == 0)
+ {
+ cmGeneratorTarget *qt5Rcc =
+ lg->FindGeneratorTargetToUse("Qt5::rcc");
+ if (!qt5Rcc)
+ {
+ cmSystemTools::Error("Qt5::rcc target not found ",
+ targetName.c_str());
+ return std::string();
+ }
+ return qt5Rcc->ImportedGetLocation("");
+ }
+ else if (strcmp(qtVersion, "4") == 0)
+ {
+ cmGeneratorTarget *qt4Rcc =
+ lg->FindGeneratorTargetToUse("Qt4::rcc");
+ if (!qt4Rcc)
+ {
+ cmSystemTools::Error("Qt4::rcc target not found ",
+ targetName.c_str());
+ return std::string();
+ }
+ return qt4Rcc->ImportedGetLocation("");
+ }
+
+ cmSystemTools::Error("The CMAKE_AUTORCC feature supports only Qt 4 and "
+ "Qt 5 ", targetName.c_str());
+ return std::string();
+}
+
+static void MergeRccOptions(std::vector<std::string> &opts,
+ const std::vector<std::string> &fileOpts,
+ bool isQt5)
+{
+ static const char* valueOptions[] = {
+ "name",
+ "root",
+ "compress",
+ "threshold"
+ };
+ std::vector<std::string> extraOpts;
+ for(std::vector<std::string>::const_iterator it = fileOpts.begin();
+ it != fileOpts.end(); ++it)
+ {
+ std::vector<std::string>::iterator existingIt
+ = std::find(opts.begin(), opts.end(), *it);
+ if (existingIt != opts.end())
+ {
+ const char *o = it->c_str();
+ if (*o == '-')
+ {
+ ++o;
+ }
+ if (isQt5 && *o == '-')
+ {
+ ++o;
+ }
+ if (std::find_if(cmArrayBegin(valueOptions), cmArrayEnd(valueOptions),
+ cmStrCmp(*it)) != cmArrayEnd(valueOptions))
+ {
+ assert(existingIt + 1 != opts.end());
+ *(existingIt + 1) = *(it + 1);
+ ++it;
+ }
+ }
+ else
+ {
+ extraOpts.push_back(*it);
+ }
+ }
+ opts.insert(opts.end(), extraOpts.begin(), extraOpts.end());
+}
+
+std::string GetAutogenTargetName(
+ cmGeneratorTarget const* target)
+{
+ std::string autogenTargetName = target->GetName();
+ autogenTargetName += "_automoc";
+ return autogenTargetName;
+}
+
+std::string GetAutogenTargetDir(
+ cmGeneratorTarget const* target)
+{
+ cmMakefile* makefile = target->Target->GetMakefile();
+ std::string targetDir = makefile->GetCurrentBinaryDirectory();
+ targetDir += makefile->GetCMakeInstance()->GetCMakeFilesDirectory();
+ targetDir += "/";
+ targetDir += GetAutogenTargetName(target);
+ targetDir += ".dir/";
+ return targetDir;
+}
+
+static void copyTargetProperty(cmTarget* destinationTarget,
+ cmTarget* sourceTarget,
+ const std::string& propertyName)
+{
+ const char* propertyValue = sourceTarget->GetProperty(propertyName);
+ if (propertyValue)
+ {
+ destinationTarget->SetProperty(propertyName, propertyValue);
+ }
+}
+
+static std::string cmQtAutoGeneratorsStripCR(std::string const& line)
+{
+ // Strip CR characters rcc may have printed (possibly more than one!).
+ std::string::size_type cr = line.find('\r');
+ if (cr != line.npos)
+ {
+ return line.substr(0, cr);
+ }
+ return line;
+}
+
+static std::string ReadAll(const std::string& filename)
+{
+ cmsys::ifstream file(filename.c_str());
+ std::stringstream stream;
+ stream << file.rdbuf();
+ file.close();
+ return stream.str();
+}
+
+static std::string ListQt5RccInputs(cmSourceFile* sf,
+ cmGeneratorTarget const* target,
+ std::vector<std::string>& depends)
+{
+ std::string rccCommand
+ = GetRccExecutable(target);
+
+ bool hasDashDashList = false;
+ {
+ std::vector<std::string> command;
+ command.push_back(rccCommand);
+ command.push_back("--help");
+ std::string rccStdOut;
+ std::string rccStdErr;
+ int retVal = 0;
+ bool result = cmSystemTools::RunSingleCommand(
+ command, &rccStdOut, &rccStdErr,
+ &retVal, 0, cmSystemTools::OUTPUT_NONE);
+ if (result && retVal == 0 &&
+ rccStdOut.find("--list") != std::string::npos)
+ {
+ hasDashDashList = true;
+ }
+ }
+
+ std::vector<std::string> qrcEntries;
+
+ std::vector<std::string> command;
+ command.push_back(rccCommand);
+ command.push_back(hasDashDashList? "--list" : "-list");
+
+ std::string absFile = cmsys::SystemTools::GetRealPath(
+ sf->GetFullPath());
+
+ command.push_back(absFile);
+
+ std::string rccStdOut;
+ std::string rccStdErr;
+ int retVal = 0;
+ bool result = cmSystemTools::RunSingleCommand(
+ command, &rccStdOut, &rccStdErr,
+ &retVal, 0, cmSystemTools::OUTPUT_NONE);
+ if (!result || retVal)
+ {
+ std::cerr << "AUTOGEN: error: Rcc list process for " << sf->GetFullPath()
+ << " failed:\n" << rccStdOut << "\n" << rccStdErr << std::endl;
+ return std::string();
+ }
+
+ {
+ std::istringstream ostr(rccStdOut);
+ std::string oline;
+ while(std::getline(ostr, oline))
+ {
+ oline = cmQtAutoGeneratorsStripCR(oline);
+ if(!oline.empty())
+ {
+ qrcEntries.push_back(oline);
+ }
+ }
+ }
+
+ {
+ std::istringstream estr(rccStdErr);
+ std::string eline;
+ while(std::getline(estr, eline))
+ {
+ eline = cmQtAutoGeneratorsStripCR(eline);
+ if (cmHasLiteralPrefix(eline, "RCC: Error in"))
+ {
+ static std::string searchString = "Cannot find file '";
+
+ std::string::size_type pos = eline.find(searchString);
+ if (pos == std::string::npos)
+ {
+ std::cerr << "AUTOGEN: error: Rcc lists unparsable output "
+ << eline << std::endl;
+ return std::string();
+ }
+ pos += searchString.length();
+ std::string::size_type sz = eline.size() - pos - 1;
+ qrcEntries.push_back(eline.substr(pos, sz));
+ }
+ }
+ }
+
+ depends.insert(depends.end(), qrcEntries.begin(), qrcEntries.end());
+ return cmJoin(qrcEntries, "@list_sep@");
+}
+
+static std::string ListQt4RccInputs(cmSourceFile* sf,
+ std::vector<std::string>& depends)
+{
+ const std::string qrcContents = ReadAll(sf->GetFullPath());
+
+ cmsys::RegularExpression fileMatchRegex("(<file[^<]+)");
+
+ std::string entriesList;
+ const char* sep = "";
+
+ size_t offset = 0;
+ while (fileMatchRegex.find(qrcContents.c_str() + offset))
+ {
+ std::string qrcEntry = fileMatchRegex.match(1);
+
+ offset += qrcEntry.size();
+
+ cmsys::RegularExpression fileReplaceRegex("(^<file[^>]*>)");
+ fileReplaceRegex.find(qrcEntry);
+ std::string tag = fileReplaceRegex.match(1);
+
+ qrcEntry = qrcEntry.substr(tag.size());
+
+ if (!cmSystemTools::FileIsFullPath(qrcEntry.c_str()))
+ {
+ qrcEntry = sf->GetLocation().GetDirectory() + "/" + qrcEntry;
+ }
+
+ entriesList += sep;
+ entriesList += qrcEntry;
+ sep = "@list_sep@";
+ depends.push_back(qrcEntry);
+ }
+ return entriesList;
+}
+
+static void SetupAutoRccTarget(cmGeneratorTarget const* target)
+{
+ std::string _rcc_files;
+ const char* sepRccFiles = "";
+ cmMakefile *makefile = target->Target->GetMakefile();
+
+ std::vector<cmSourceFile*> srcFiles;
+ target->GetConfigCommonSourceFiles(srcFiles);
+
+ std::string qrcInputs;
+ const char* qrcInputsSep = "";
+
+ std::string rccFileFiles;
+ std::string rccFileOptions;
+ const char *optionSep = "";
+
+ const char *qtVersion = makefile->GetDefinition("_target_qt_version");
+
+ std::vector<std::string> rccOptions;
+ if (const char* opts = target->GetProperty("AUTORCC_OPTIONS"))
+ {
+ cmSystemTools::ExpandListArgument(opts, rccOptions);
+ }
+ std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR");
+ if (qtMajorVersion == "")
+ {
+ qtMajorVersion = makefile->GetSafeDefinition("Qt5Core_VERSION_MAJOR");
+ }
+
+ for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
+ fileIt != srcFiles.end();
+ ++fileIt)
+ {
+ cmSourceFile* sf = *fileIt;
+ std::string ext = sf->GetExtension();
+ if (ext == "qrc")
+ {
+ std::string absFile = cmsys::SystemTools::GetRealPath(
+ sf->GetFullPath());
+ bool skip = cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC"));
+
+ if (!skip)
+ {
+ _rcc_files += sepRccFiles;
+ _rcc_files += absFile;
+ sepRccFiles = ";";
+
+ if (const char *prop = sf->GetProperty("AUTORCC_OPTIONS"))
+ {
+ std::vector<std::string> optsVec;
+ cmSystemTools::ExpandListArgument(prop, optsVec);
+ MergeRccOptions(rccOptions, optsVec,
+ strcmp(qtVersion, "5") == 0);
+ }
+
+ if (!rccOptions.empty())
+ {
+ rccFileFiles += optionSep;
+ rccFileFiles += absFile;
+ rccFileOptions += optionSep;
+ }
+ const char *listSep = "";
+ for(std::vector<std::string>::const_iterator it = rccOptions.begin();
+ it != rccOptions.end();
+ ++it)
+ {
+ rccFileOptions += listSep;
+ rccFileOptions += *it;
+ listSep = "@list_sep@";
+ }
+ optionSep = ";";
+
+ std::vector<std::string> depends;
+
+ std::string entriesList;
+ if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED")))
+ {
+ if (qtMajorVersion == "5")
+ {
+ entriesList = ListQt5RccInputs(sf, target, depends);
+ }
+ else
+ {
+ entriesList = ListQt4RccInputs(sf, depends);
+ }
+ if (entriesList.empty())
+ {
+ return;
+ }
+ }
+ qrcInputs += qrcInputsSep;
+ qrcInputs += entriesList;
+ qrcInputsSep = ";";
+ }
+ }
+ }
+ makefile->AddDefinition("_qt_rcc_inputs_" + target->GetName(),
+ cmOutputConverter::EscapeForCMake(qrcInputs).c_str());
+
+ makefile->AddDefinition("_rcc_files",
+ cmOutputConverter::EscapeForCMake(_rcc_files).c_str());
+
+ makefile->AddDefinition("_qt_rcc_options_files",
+ cmOutputConverter::EscapeForCMake(rccFileFiles).c_str());
+ makefile->AddDefinition("_qt_rcc_options_options",
+ cmOutputConverter::EscapeForCMake(rccFileOptions).c_str());
+
+ makefile->AddDefinition("_qt_rcc_executable",
+ GetRccExecutable(target).c_str());
+}
+
+void cmQtAutoGeneratorInitializer::InitializeAutogenSources(
+ cmGeneratorTarget* target)
+{
+ cmMakefile* makefile = target->Target->GetMakefile();
+
+ if (target->GetPropertyAsBool("AUTOMOC"))
+ {
+ std::string automocTargetName = GetAutogenTargetName(target);
+ std::string mocCppFile = makefile->GetCurrentBinaryDirectory();
+ mocCppFile += "/";
+ mocCppFile += automocTargetName;
+ mocCppFile += ".cpp";
+ makefile->GetOrCreateSource(mocCppFile, true);
+ makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
+ mocCppFile.c_str(), false);
+
+ target->AddSource(mocCppFile);
+ }
+}
+
+void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
+ cmLocalGenerator* lg,
+ cmGeneratorTarget* target)
+{
+ cmMakefile* makefile = target->Target->GetMakefile();
+
+ std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR");
+ if (qtMajorVersion == "")
+ {
+ qtMajorVersion = makefile->GetSafeDefinition("Qt5Core_VERSION_MAJOR");
+ }
+
+ // create a custom target for running generators at buildtime:
+ std::string autogenTargetName = GetAutogenTargetName(target);
+
+ std::string targetDir = GetAutogenTargetDir(target);
+
+ cmCustomCommandLine currentLine;
+ currentLine.push_back(cmSystemTools::GetCMakeCommand());
+ currentLine.push_back("-E");
+ currentLine.push_back("cmake_autogen");
+ currentLine.push_back(targetDir);
+ currentLine.push_back("$<CONFIGURATION>");
+
+ cmCustomCommandLines commandLines;
+ commandLines.push_back(currentLine);
+
+ std::string workingDirectory = cmSystemTools::CollapseFullPath(
+ "", makefile->GetCurrentBinaryDirectory());
+
+ std::vector<std::string> depends;
+ if (const char *autogenDepends =
+ target->GetProperty("AUTOGEN_TARGET_DEPENDS"))
+ {
+ cmSystemTools::ExpandListArgument(autogenDepends, depends);
+ }
+ std::vector<std::string> toolNames;
+ if (target->GetPropertyAsBool("AUTOMOC"))
+ {
+ toolNames.push_back("moc");
+ }
+ if (target->GetPropertyAsBool("AUTOUIC"))
+ {
+ toolNames.push_back("uic");
+ }
+ if (target->GetPropertyAsBool("AUTORCC"))
+ {
+ toolNames.push_back("rcc");
+ }
+
+ std::string tools = toolNames[0];
+ toolNames.erase(toolNames.begin());
+ while (toolNames.size() > 1)
+ {
+ tools += ", " + toolNames[0];
+ toolNames.erase(toolNames.begin());
+ }
+ if (toolNames.size() == 1)
+ {
+ tools += " and " + toolNames[0];
+ }
+ std::string autogenComment = "Automatic " + tools + " for target ";
+ autogenComment += target->GetName();
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ bool usePRE_BUILD = false;
+ cmGlobalGenerator* gg = lg->GetGlobalGenerator();
+ if(gg->GetName().find("Visual Studio") != std::string::npos)
+ {
+ cmGlobalVisualStudioGenerator* vsgg =
+ static_cast<cmGlobalVisualStudioGenerator*>(gg);
+ // Under VS >= 7 use a PRE_BUILD event instead of a separate target to
+ // reduce the number of targets loaded into the IDE.
+ // This also works around a VS 11 bug that may skip updating the target:
+ // https://connect.microsoft.com/VisualStudio/feedback/details/769495
+ usePRE_BUILD = vsgg->GetVersion() >= cmGlobalVisualStudioGenerator::VS7;
+ if(usePRE_BUILD)
+ {
+ for (std::vector<std::string>::iterator it = depends.begin();
+ it != depends.end(); ++it)
+ {
+ if(!makefile->FindTargetToUse(it->c_str()))
+ {
+ usePRE_BUILD = false;
+ break;
+ }
+ }
+ }
+ }
+#endif
+
+ std::vector<std::string> rcc_output;
+ bool const isNinja =
+ lg->GetGlobalGenerator()->GetName() == "Ninja";
+ if(isNinja
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ || usePRE_BUILD
+#endif
+ )
+ {
+ std::vector<cmSourceFile*> srcFiles;
+ target->GetConfigCommonSourceFiles(srcFiles);
+ for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
+ fileIt != srcFiles.end();
+ ++fileIt)
+ {
+ cmSourceFile* sf = *fileIt;
+ std::string absFile = cmsys::SystemTools::GetRealPath(
+ sf->GetFullPath());
+
+ std::string ext = sf->GetExtension();
+
+ if (target->GetPropertyAsBool("AUTORCC"))
+ {
+ if (ext == "qrc"
+ && !cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC")))
+ {
+ std::string basename = cmsys::SystemTools::
+ GetFilenameWithoutLastExtension(absFile);
+
+ std::string rcc_output_dir = target->GetSupportDirectory();
+ cmSystemTools::MakeDirectory(rcc_output_dir.c_str());
+ std::string rcc_output_file = rcc_output_dir;
+ rcc_output_file += "/qrc_" + basename + ".cpp";
+ rcc_output.push_back(rcc_output_file);
+
+ if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED")))
+ {
+ if (qtMajorVersion == "5")
+ {
+ ListQt5RccInputs(sf, target, depends);
+ }
+ else
+ {
+ ListQt4RccInputs(sf, depends);
+ }
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ // Cannot use PRE_BUILD because the resource files themselves
+ // may not be sources within the target so VS may not know the
+ // target needs to re-build at all.
+ usePRE_BUILD = false;
+#endif
+ }
+ }
+ }
+ }
+ }
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if(usePRE_BUILD)
+ {
+ // Add the pre-build command directly to bypass the OBJECT_LIBRARY
+ // rejection in cmMakefile::AddCustomCommandToTarget because we know
+ // PRE_BUILD will work for an OBJECT_LIBRARY in this specific case.
+ std::vector<std::string> no_output;
+ std::vector<std::string> no_byproducts;
+ cmCustomCommand cc(makefile, no_output, no_byproducts, depends,
+ commandLines, autogenComment.c_str(),
+ workingDirectory.c_str());
+ cc.SetEscapeOldStyle(false);
+ cc.SetEscapeAllowMakeVars(true);
+ target->Target->AddPreBuildCommand(cc);
+ }
+ else
+#endif
+ {
+ cmTarget* autogenTarget = makefile->AddUtilityCommand(
+ autogenTargetName, true,
+ workingDirectory.c_str(),
+ /*byproducts=*/rcc_output, depends,
+ commandLines, false, autogenComment.c_str());
+
+ cmGeneratorTarget* gt = new cmGeneratorTarget(autogenTarget, lg);
+ lg->AddGeneratorTarget(gt);
+
+ // Set target folder
+ const char* autogenFolder = makefile->GetState()
+ ->GetGlobalProperty("AUTOMOC_TARGETS_FOLDER");
+ if (!autogenFolder)
+ {
+ autogenFolder = makefile->GetState()
+ ->GetGlobalProperty("AUTOGEN_TARGETS_FOLDER");
+ }
+ if (autogenFolder && *autogenFolder)
+ {
+ autogenTarget->SetProperty("FOLDER", autogenFolder);
+ }
+ else
+ {
+ // inherit FOLDER property from target (#13688)
+ copyTargetProperty(gt->Target, target->Target, "FOLDER");
+ }
+
+ target->Target->AddUtility(autogenTargetName);
+ }
+}
+
+void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget(
+ cmGeneratorTarget const* target)
+{
+ cmMakefile* makefile = target->Target->GetMakefile();
+
+ // forget the variables added here afterwards again:
+ cmMakefile::ScopePushPop varScope(makefile);
+ static_cast<void>(varScope);
+
+ // create a custom target for running generators at buildtime:
+ std::string autogenTargetName = GetAutogenTargetName(target);
+
+ makefile->AddDefinition("_moc_target_name",
+ cmOutputConverter::EscapeForCMake(autogenTargetName).c_str());
+ makefile->AddDefinition("_origin_target_name",
+ cmOutputConverter::EscapeForCMake(target->GetName()).c_str());
+
+ std::string targetDir = GetAutogenTargetDir(target);
+
+ const char *qtVersion = makefile->GetDefinition("Qt5Core_VERSION_MAJOR");
+ if (!qtVersion)
+ {
+ qtVersion = makefile->GetDefinition("QT_VERSION_MAJOR");
+ }
+ if (const char *targetQtVersion =
+ target->GetLinkInterfaceDependentStringProperty("QT_MAJOR_VERSION", ""))
+ {
+ qtVersion = targetQtVersion;
+ }
+ if (qtVersion)
+ {
+ makefile->AddDefinition("_target_qt_version", qtVersion);
+ }
+
+ std::vector<std::string> skipUic;
+ std::vector<std::string> skipMoc;
+ std::vector<std::string> mocSources;
+ std::vector<std::string> mocHeaders;
+ std::map<std::string, std::string> configIncludes;
+ std::map<std::string, std::string> configDefines;
+ std::map<std::string, std::string> configUicOptions;
+
+ if (target->GetPropertyAsBool("AUTOMOC")
+ || target->GetPropertyAsBool("AUTOUIC")
+ || target->GetPropertyAsBool("AUTORCC"))
+ {
+ SetupSourceFiles(target, skipMoc, mocSources, mocHeaders, skipUic);
+ }
+ makefile->AddDefinition("_cpp_files",
+ cmOutputConverter::EscapeForCMake(cmJoin(mocSources, ";")).c_str());
+ if (target->GetPropertyAsBool("AUTOMOC"))
+ {
+ SetupAutoMocTarget(target, autogenTargetName,
+ skipMoc, mocHeaders,
+ configIncludes, configDefines);
+ }
+ if (target->GetPropertyAsBool("AUTOUIC"))
+ {
+ SetupAutoUicTarget(target, skipUic, configUicOptions);
+ }
+ if (target->GetPropertyAsBool("AUTORCC"))
+ {
+ SetupAutoRccTarget(target);
+ }
+
+ const char* cmakeRoot = makefile->GetSafeDefinition("CMAKE_ROOT");
+ std::string inputFile = cmakeRoot;
+ inputFile += "/Modules/AutogenInfo.cmake.in";
+ std::string outputFile = targetDir;
+ outputFile += "/AutogenInfo.cmake";
+ makefile->AddDefinition("_qt_rcc_inputs",
+ makefile->GetDefinition("_qt_rcc_inputs_" + target->GetName()));
+ makefile->ConfigureFile(inputFile.c_str(), outputFile.c_str(),
+ false, true, false);
+
+ // Ensure we have write permission in case .in was read-only.
+ mode_t perm = 0;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ mode_t mode_write = S_IWRITE;
+#else
+ mode_t mode_write = S_IWUSR;
+#endif
+ cmSystemTools::GetPermissions(outputFile, perm);
+ if (!(perm & mode_write))
+ {
+ cmSystemTools::SetPermissions(outputFile, perm | mode_write);
+ }
+ if (!configDefines.empty()
+ || !configIncludes.empty()
+ || !configUicOptions.empty())
+ {
+ cmsys::ofstream infoFile(outputFile.c_str(), std::ios::app);
+ if ( !infoFile )
+ {
+ std::string error = "Internal CMake error when trying to open file: ";
+ error += outputFile.c_str();
+ error += " for writing.";
+ cmSystemTools::Error(error.c_str());
+ return;
+ }
+ if (!configDefines.empty())
+ {
+ for (std::map<std::string, std::string>::iterator
+ it = configDefines.begin(), end = configDefines.end();
+ it != end; ++it)
+ {
+ infoFile << "set(AM_MOC_COMPILE_DEFINITIONS_" << it->first <<
+ " " << it->second << ")\n";
+ }
+ }
+ if (!configIncludes.empty())
+ {
+ for (std::map<std::string, std::string>::iterator
+ it = configIncludes.begin(), end = configIncludes.end();
+ it != end; ++it)
+ {
+ infoFile << "set(AM_MOC_INCLUDES_" << it->first <<
+ " " << it->second << ")\n";
+ }
+ }
+ if (!configUicOptions.empty())
+ {
+ for (std::map<std::string, std::string>::iterator
+ it = configUicOptions.begin(), end = configUicOptions.end();
+ it != end; ++it)
+ {
+ infoFile << "set(AM_UIC_TARGET_OPTIONS_" << it->first <<
+ " " << it->second << ")\n";
+ }
+ }
+ }
+}
diff --git a/Source/cmQtAutoGeneratorInitializer.h b/Source/cmQtAutoGeneratorInitializer.h
new file mode 100644
index 000000000..eaf140d26
--- /dev/null
+++ b/Source/cmQtAutoGeneratorInitializer.h
@@ -0,0 +1,36 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2004-2011 Kitware, Inc.
+ Copyright 2011 Alexander Neundorf (neundorf@kde.org)
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmQtAutoGeneratorInitializer_h
+#define cmQtAutoGeneratorInitializer_h
+
+#include "cmStandardIncludes.h"
+
+#include <string>
+#include <vector>
+#include <map>
+
+class cmSourceFile;
+class cmGeneratorTarget;
+class cmLocalGenerator;
+
+class cmQtAutoGeneratorInitializer
+{
+public:
+ static void InitializeAutogenSources(cmGeneratorTarget* target);
+ static void InitializeAutogenTarget(cmLocalGenerator* lg,
+ cmGeneratorTarget* target);
+ static void SetupAutoGenerateTarget(cmGeneratorTarget const* target);
+};
+
+#endif
diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx
new file mode 100644
index 000000000..b16eccda3
--- /dev/null
+++ b/Source/cmQtAutoGenerators.cxx
@@ -0,0 +1,1385 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2004-2011 Kitware, Inc.
+ Copyright 2011 Alexander Neundorf (neundorf@kde.org)
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmGlobalGenerator.h"
+#include "cmOutputConverter.h"
+#include "cmMakefile.h"
+#include "cmSystemTools.h"
+#include "cmState.h"
+#include "cmAlgorithms.h"
+
+#include <sys/stat.h>
+
+#include <cmsys/Terminal.h>
+#include <cmsys/FStream.hxx>
+#include <assert.h>
+
+#include <string.h>
+#if defined(__APPLE__)
+#include <unistd.h>
+#endif
+
+#include "cmQtAutoGenerators.h"
+
+static bool requiresMocing(const std::string& text, std::string &macroName)
+{
+ // this simple check is much much faster than the regexp
+ if (strstr(text.c_str(), "Q_OBJECT") == NULL
+ && strstr(text.c_str(), "Q_GADGET") == NULL)
+ {
+ return false;
+ }
+
+ cmsys::RegularExpression qObjectRegExp("[\n][ \t]*Q_OBJECT[^a-zA-Z0-9_]");
+ if (qObjectRegExp.find(text))
+ {
+ macroName = "Q_OBJECT";
+ return true;
+ }
+ cmsys::RegularExpression qGadgetRegExp("[\n][ \t]*Q_GADGET[^a-zA-Z0-9_]");
+ if (qGadgetRegExp.find(text))
+ {
+ macroName = "Q_GADGET";
+ return true;
+ }
+ return false;
+}
+
+
+static std::string findMatchingHeader(const std::string& absPath,
+ const std::string& mocSubDir,
+ const std::string& basename,
+ const std::vector<std::string>& headerExtensions)
+{
+ std::string header;
+ for(std::vector<std::string>::const_iterator ext = headerExtensions.begin();
+ ext != headerExtensions.end();
+ ++ext)
+ {
+ std::string sourceFilePath = absPath + basename + "." + (*ext);
+ if (cmsys::SystemTools::FileExists(sourceFilePath.c_str()))
+ {
+ header = sourceFilePath;
+ break;
+ }
+ if (!mocSubDir.empty())
+ {
+ sourceFilePath = mocSubDir + basename + "." + (*ext);
+ if (cmsys::SystemTools::FileExists(sourceFilePath.c_str()))
+ {
+ header = sourceFilePath;
+ break;
+ }
+ }
+ }
+
+ return header;
+}
+
+
+static std::string extractSubDir(const std::string& absPath,
+ const std::string& currentMoc)
+{
+ std::string subDir;
+ if (currentMoc.find_first_of('/') != std::string::npos)
+ {
+ subDir = absPath
+ + cmsys::SystemTools::GetFilenamePath(currentMoc) + '/';
+ }
+ return subDir;
+}
+
+cmQtAutoGenerators::cmQtAutoGenerators()
+:Verbose(cmsys::SystemTools::GetEnv("VERBOSE") != 0)
+,ColorOutput(true)
+,RunMocFailed(false)
+,RunUicFailed(false)
+,RunRccFailed(false)
+,GenerateAll(false)
+{
+
+ std::string colorEnv = "";
+ cmsys::SystemTools::GetEnv("COLOR", colorEnv);
+ if(!colorEnv.empty())
+ {
+ if(cmSystemTools::IsOn(colorEnv.c_str()))
+ {
+ this->ColorOutput = true;
+ }
+ else
+ {
+ this->ColorOutput = false;
+ }
+ }
+}
+
+void cmQtAutoGenerators::MergeUicOptions(std::vector<std::string> &opts,
+ const std::vector<std::string> &fileOpts,
+ bool isQt5)
+{
+ static const char* valueOptions[] = {
+ "tr",
+ "translate",
+ "postfix",
+ "generator",
+ "include", // Since Qt 5.3
+ "g"
+ };
+ std::vector<std::string> extraOpts;
+ for(std::vector<std::string>::const_iterator it = fileOpts.begin();
+ it != fileOpts.end(); ++it)
+ {
+ std::vector<std::string>::iterator existingIt
+ = std::find(opts.begin(), opts.end(), *it);
+ if (existingIt != opts.end())
+ {
+ const char *o = it->c_str();
+ if (*o == '-')
+ {
+ ++o;
+ }
+ if (isQt5 && *o == '-')
+ {
+ ++o;
+ }
+ if (std::find_if(cmArrayBegin(valueOptions), cmArrayEnd(valueOptions),
+ cmStrCmp(*it)) != cmArrayEnd(valueOptions))
+ {
+ assert(existingIt + 1 != opts.end());
+ *(existingIt + 1) = *(it + 1);
+ ++it;
+ }
+ }
+ else
+ {
+ extraOpts.push_back(*it);
+ }
+ }
+ opts.insert(opts.end(), extraOpts.begin(), extraOpts.end());
+}
+
+bool cmQtAutoGenerators::Run(const std::string& targetDirectory,
+ const std::string& config)
+{
+ bool success = true;
+ cmake cm;
+ cm.SetHomeOutputDirectory(targetDirectory);
+ cm.SetHomeDirectory(targetDirectory);
+ cm.GetCurrentSnapshot().SetDefaultDefinitions();
+ cmGlobalGenerator gg(&cm);
+
+ cmState::Snapshot snapshot = cm.GetCurrentSnapshot();
+ snapshot.GetDirectory().SetCurrentBinary(targetDirectory);
+ snapshot.GetDirectory().SetCurrentSource(targetDirectory);
+
+ cmsys::auto_ptr<cmMakefile> mf(new cmMakefile(&gg, snapshot));
+ gg.SetCurrentMakefile(mf.get());
+
+ this->ReadAutogenInfoFile(mf.get(), targetDirectory, config);
+ this->ReadOldMocDefinitionsFile(mf.get(), targetDirectory);
+
+ this->Init();
+
+ if (this->QtMajorVersion == "4" || this->QtMajorVersion == "5")
+ {
+ success = this->RunAutogen(mf.get());
+ }
+
+ this->WriteOldMocDefinitionsFile(targetDirectory);
+
+ return success;
+}
+
+bool cmQtAutoGenerators::ReadAutogenInfoFile(cmMakefile* makefile,
+ const std::string& targetDirectory,
+ const std::string& config)
+{
+ std::string filename(
+ cmSystemTools::CollapseFullPath(targetDirectory));
+ cmSystemTools::ConvertToUnixSlashes(filename);
+ filename += "/AutogenInfo.cmake";
+
+ if (!makefile->ReadListFile(filename.c_str()))
+ {
+ cmSystemTools::Error("Error processing file: ", filename.c_str());
+ return false;
+ }
+
+ this->QtMajorVersion = makefile->GetSafeDefinition("AM_QT_VERSION_MAJOR");
+ if (this->QtMajorVersion == "")
+ {
+ this->QtMajorVersion = makefile->GetSafeDefinition(
+ "AM_Qt5Core_VERSION_MAJOR");
+ }
+ this->Sources = makefile->GetSafeDefinition("AM_SOURCES");
+ {
+ std::string rccSources = makefile->GetSafeDefinition("AM_RCC_SOURCES");
+ cmSystemTools::ExpandListArgument(rccSources, this->RccSources);
+ }
+ this->SkipMoc = makefile->GetSafeDefinition("AM_SKIP_MOC");
+ this->SkipUic = makefile->GetSafeDefinition("AM_SKIP_UIC");
+ this->Headers = makefile->GetSafeDefinition("AM_HEADERS");
+ this->IncludeProjectDirsBefore = makefile->IsOn(
+ "AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE");
+ this->Srcdir = makefile->GetSafeDefinition("AM_CMAKE_CURRENT_SOURCE_DIR");
+ this->Builddir = makefile->GetSafeDefinition("AM_CMAKE_CURRENT_BINARY_DIR");
+ this->MocExecutable = makefile->GetSafeDefinition("AM_QT_MOC_EXECUTABLE");
+ this->UicExecutable = makefile->GetSafeDefinition("AM_QT_UIC_EXECUTABLE");
+ this->RccExecutable = makefile->GetSafeDefinition("AM_QT_RCC_EXECUTABLE");
+ {
+ std::string compileDefsPropOrig = "AM_MOC_COMPILE_DEFINITIONS";
+ std::string compileDefsProp = compileDefsPropOrig;
+ if(!config.empty())
+ {
+ compileDefsProp += "_";
+ compileDefsProp += config;
+ }
+ const char *compileDefs = makefile->GetDefinition(compileDefsProp);
+ this->MocCompileDefinitionsStr = compileDefs ? compileDefs
+ : makefile->GetSafeDefinition(compileDefsPropOrig);
+ }
+ {
+ std::string includesPropOrig = "AM_MOC_INCLUDES";
+ std::string includesProp = includesPropOrig;
+ if(!config.empty())
+ {
+ includesProp += "_";
+ includesProp += config;
+ }
+ const char *includes = makefile->GetDefinition(includesProp);
+ this->MocIncludesStr = includes ? includes
+ : makefile->GetSafeDefinition(includesPropOrig);
+ }
+ this->MocOptionsStr = makefile->GetSafeDefinition("AM_MOC_OPTIONS");
+ this->ProjectBinaryDir = makefile->GetSafeDefinition("AM_CMAKE_BINARY_DIR");
+ this->ProjectSourceDir = makefile->GetSafeDefinition("AM_CMAKE_SOURCE_DIR");
+ this->TargetName = makefile->GetSafeDefinition("AM_TARGET_NAME");
+ this->OriginTargetName
+ = makefile->GetSafeDefinition("AM_ORIGIN_TARGET_NAME");
+
+ {
+ const char *uicOptionsFiles
+ = makefile->GetSafeDefinition("AM_UIC_OPTIONS_FILES");
+ std::string uicOptionsPropOrig = "AM_UIC_TARGET_OPTIONS";
+ std::string uicOptionsProp = uicOptionsPropOrig;
+ if(!config.empty())
+ {
+ uicOptionsProp += "_";
+ uicOptionsProp += config;
+ }
+ const char *uicTargetOptions
+ = makefile->GetSafeDefinition(uicOptionsProp);
+ cmSystemTools::ExpandListArgument(
+ uicTargetOptions ? uicTargetOptions
+ : makefile->GetSafeDefinition(uicOptionsPropOrig),
+ this->UicTargetOptions);
+ const char *uicOptionsOptions
+ = makefile->GetSafeDefinition("AM_UIC_OPTIONS_OPTIONS");
+ std::vector<std::string> uicFilesVec;
+ cmSystemTools::ExpandListArgument(uicOptionsFiles, uicFilesVec);
+ std::vector<std::string> uicOptionsVec;
+ cmSystemTools::ExpandListArgument(uicOptionsOptions, uicOptionsVec);
+ if (uicFilesVec.size() != uicOptionsVec.size())
+ {
+ return false;
+ }
+ for (std::vector<std::string>::iterator fileIt = uicFilesVec.begin(),
+ optionIt = uicOptionsVec.begin();
+ fileIt != uicFilesVec.end();
+ ++fileIt, ++optionIt)
+ {
+ cmSystemTools::ReplaceString(*optionIt, "@list_sep@", ";");
+ this->UicOptions[*fileIt] = *optionIt;
+ }
+ }
+ {
+ const char *rccOptionsFiles
+ = makefile->GetSafeDefinition("AM_RCC_OPTIONS_FILES");
+ const char *rccOptionsOptions
+ = makefile->GetSafeDefinition("AM_RCC_OPTIONS_OPTIONS");
+ std::vector<std::string> rccFilesVec;
+ cmSystemTools::ExpandListArgument(rccOptionsFiles, rccFilesVec);
+ std::vector<std::string> rccOptionsVec;
+ cmSystemTools::ExpandListArgument(rccOptionsOptions, rccOptionsVec);
+ if (rccFilesVec.size() != rccOptionsVec.size())
+ {
+ return false;
+ }
+ for (std::vector<std::string>::iterator fileIt = rccFilesVec.begin(),
+ optionIt = rccOptionsVec.begin();
+ fileIt != rccFilesVec.end();
+ ++fileIt, ++optionIt)
+ {
+ cmSystemTools::ReplaceString(*optionIt, "@list_sep@", ";");
+ this->RccOptions[*fileIt] = *optionIt;
+ }
+
+ const char *rccInputs = makefile->GetSafeDefinition("AM_RCC_INPUTS");
+ std::vector<std::string> rccInputLists;
+ cmSystemTools::ExpandListArgument(rccInputs, rccInputLists);
+
+ if (this->RccSources.size() != rccInputLists.size())
+ {
+ cmSystemTools::Error("Error processing file: ", filename.c_str());
+ return false;
+ }
+
+ for (std::vector<std::string>::iterator fileIt = this->RccSources.begin(),
+ inputIt = rccInputLists.begin();
+ fileIt != this->RccSources.end();
+ ++fileIt, ++inputIt)
+ {
+ cmSystemTools::ReplaceString(*inputIt, "@list_sep@", ";");
+ std::vector<std::string> rccInputFiles;
+ cmSystemTools::ExpandListArgument(*inputIt, rccInputFiles);
+
+ this->RccInputs[*fileIt] = rccInputFiles;
+ }
+ }
+ this->CurrentCompileSettingsStr = this->MakeCompileSettingsString(makefile);
+
+ this->RelaxedMode = makefile->IsOn("AM_RELAXED_MODE");
+
+ return true;
+}
+
+
+std::string cmQtAutoGenerators::MakeCompileSettingsString(cmMakefile* makefile)
+{
+ std::string s;
+ s += makefile->GetSafeDefinition("AM_MOC_COMPILE_DEFINITIONS");
+ s += " ~~~ ";
+ s += makefile->GetSafeDefinition("AM_MOC_INCLUDES");
+ s += " ~~~ ";
+ s += makefile->GetSafeDefinition("AM_MOC_OPTIONS");
+ s += " ~~~ ";
+ s += makefile->IsOn("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE") ? "TRUE"
+ : "FALSE";
+ s += " ~~~ ";
+
+ return s;
+}
+
+
+bool cmQtAutoGenerators::ReadOldMocDefinitionsFile(cmMakefile* makefile,
+ const std::string& targetDirectory)
+{
+ std::string filename(
+ cmSystemTools::CollapseFullPath(targetDirectory));
+ cmSystemTools::ConvertToUnixSlashes(filename);
+ filename += "/AutomocOldMocDefinitions.cmake";
+
+ if (makefile->ReadListFile(filename.c_str()))
+ {
+ this->OldCompileSettingsStr =
+ makefile->GetSafeDefinition("AM_OLD_COMPILE_SETTINGS");
+ }
+ return true;
+}
+
+
+void
+cmQtAutoGenerators::WriteOldMocDefinitionsFile(
+ const std::string& targetDirectory)
+{
+ std::string filename(
+ cmSystemTools::CollapseFullPath(targetDirectory));
+ cmSystemTools::ConvertToUnixSlashes(filename);
+ filename += "/AutomocOldMocDefinitions.cmake";
+
+ cmsys::ofstream outfile;
+ outfile.open(filename.c_str(),
+ std::ios::trunc);
+ outfile << "set(AM_OLD_COMPILE_SETTINGS "
+ << cmOutputConverter::EscapeForCMake(
+ this->CurrentCompileSettingsStr) << ")\n";
+
+ outfile.close();
+}
+
+
+void cmQtAutoGenerators::Init()
+{
+ this->OutMocCppFilename = this->Builddir;
+ this->OutMocCppFilename += this->TargetName;
+ this->OutMocCppFilename += ".cpp";
+
+ std::vector<std::string> cdefList;
+ cmSystemTools::ExpandListArgument(this->MocCompileDefinitionsStr, cdefList);
+ for(std::vector<std::string>::const_iterator it = cdefList.begin();
+ it != cdefList.end();
+ ++it)
+ {
+ this->MocDefinitions.push_back("-D" + (*it));
+ }
+
+ cmSystemTools::ExpandListArgument(this->MocOptionsStr, this->MocOptions);
+
+ std::vector<std::string> incPaths;
+ cmSystemTools::ExpandListArgument(this->MocIncludesStr, incPaths);
+
+ std::set<std::string> frameworkPaths;
+ for(std::vector<std::string>::const_iterator it = incPaths.begin();
+ it != incPaths.end();
+ ++it)
+ {
+ const std::string &path = *it;
+ this->MocIncludes.push_back("-I" + path);
+ if (cmHasLiteralSuffix(path, ".framework/Headers"))
+ {
+ // Go up twice to get to the framework root
+ std::vector<std::string> pathComponents;
+ cmsys::SystemTools::SplitPath(path, pathComponents);
+ std::string frameworkPath =cmsys::SystemTools::JoinPath(
+ pathComponents.begin(), pathComponents.end() - 2);
+ frameworkPaths.insert(frameworkPath);
+ }
+ }
+
+ for (std::set<std::string>::const_iterator it = frameworkPaths.begin();
+ it != frameworkPaths.end(); ++it)
+ {
+ this->MocIncludes.push_back("-F");
+ this->MocIncludes.push_back(*it);
+ }
+
+
+ if (this->IncludeProjectDirsBefore)
+ {
+ const std::string binDir = "-I" + this->ProjectBinaryDir;
+
+ const std::string srcDir = "-I" + this->ProjectSourceDir;
+
+ std::list<std::string> sortedMocIncludes;
+ std::list<std::string>::iterator it = this->MocIncludes.begin();
+ while (it != this->MocIncludes.end())
+ {
+ if (this->StartsWith(*it, binDir))
+ {
+ sortedMocIncludes.push_back(*it);
+ it = this->MocIncludes.erase(it);
+ }
+ else
+ {
+ ++it;
+ }
+ }
+ it = this->MocIncludes.begin();
+ while (it != this->MocIncludes.end())
+ {
+ if (this->StartsWith(*it, srcDir))
+ {
+ sortedMocIncludes.push_back(*it);
+ it = this->MocIncludes.erase(it);
+ }
+ else
+ {
+ ++it;
+ }
+ }
+ sortedMocIncludes.insert(sortedMocIncludes.end(),
+ this->MocIncludes.begin(), this->MocIncludes.end());
+ this->MocIncludes = sortedMocIncludes;
+ }
+
+}
+
+static std::string ReadAll(const std::string& filename)
+{
+ cmsys::ifstream file(filename.c_str());
+ std::stringstream stream;
+ stream << file.rdbuf();
+ file.close();
+ return stream.str();
+}
+
+bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile)
+{
+ if (!cmsys::SystemTools::FileExists(this->OutMocCppFilename.c_str())
+ || (this->OldCompileSettingsStr != this->CurrentCompileSettingsStr))
+ {
+ this->GenerateAll = true;
+ }
+
+ // the program goes through all .cpp files to see which moc files are
+ // included. It is not really interesting how the moc file is named, but
+ // what file the moc is created from. Once a moc is included the same moc
+ // may not be included in the _automoc.cpp file anymore. OTOH if there's a
+ // header containing Q_OBJECT where no corresponding moc file is included
+ // anywhere a moc_<filename>.cpp file is created and included in
+ // the _automoc.cpp file.
+
+ // key = moc source filepath, value = moc output filepath
+ std::map<std::string, std::string> includedMocs;
+ // collect all headers which may need to be mocced
+ std::set<std::string> headerFiles;
+
+ std::vector<std::string> sourceFiles;
+ cmSystemTools::ExpandListArgument(this->Sources, sourceFiles);
+
+ const std::vector<std::string>& headerExtensions =
+ makefile->GetCMakeInstance()->GetHeaderExtensions();
+
+ std::map<std::string, std::vector<std::string> > includedUis;
+ std::map<std::string, std::vector<std::string> > skippedUis;
+ std::vector<std::string> uicSkipped;
+ cmSystemTools::ExpandListArgument(this->SkipUic, uicSkipped);
+
+ for (std::vector<std::string>::const_iterator it = sourceFiles.begin();
+ it != sourceFiles.end();
+ ++it)
+ {
+ const bool skipUic = std::find(uicSkipped.begin(), uicSkipped.end(), *it)
+ != uicSkipped.end();
+ std::map<std::string, std::vector<std::string> >& uiFiles
+ = skipUic ? skippedUis : includedUis;
+ const std::string &absFilename = *it;
+ if (this->Verbose)
+ {
+ std::cout << "AUTOGEN: Checking " << absFilename << std::endl;
+ }
+ if (this->RelaxedMode)
+ {
+ this->ParseCppFile(absFilename, headerExtensions, includedMocs,
+ uiFiles);
+ }
+ else
+ {
+ this->StrictParseCppFile(absFilename, headerExtensions, includedMocs,
+ uiFiles);
+ }
+ this->SearchHeadersForCppFile(absFilename, headerExtensions, headerFiles);
+ }
+
+ {
+ std::vector<std::string> mocSkipped;
+ cmSystemTools::ExpandListArgument(this->SkipMoc, mocSkipped);
+ for (std::vector<std::string>::const_iterator it = mocSkipped.begin();
+ it != mocSkipped.end();
+ ++it)
+ {
+ if (std::find(uicSkipped.begin(), uicSkipped.end(), *it)
+ != uicSkipped.end())
+ {
+ const std::string &absFilename = *it;
+ if (this->Verbose)
+ {
+ std::cout << "AUTOGEN: Checking " << absFilename << std::endl;
+ }
+ this->ParseForUic(absFilename, includedUis);
+ }
+ }
+ }
+
+ std::vector<std::string> headerFilesVec;
+ cmSystemTools::ExpandListArgument(this->Headers, headerFilesVec);
+ headerFiles.insert(headerFilesVec.begin(), headerFilesVec.end());
+
+ // key = moc source filepath, value = moc output filename
+ std::map<std::string, std::string> notIncludedMocs;
+ this->ParseHeaders(headerFiles, includedMocs, notIncludedMocs, includedUis);
+
+ // run moc on all the moc's that are #included in source files
+ for(std::map<std::string, std::string>::const_iterator
+ it = includedMocs.begin();
+ it != includedMocs.end();
+ ++it)
+ {
+ this->GenerateMoc(it->first, it->second);
+ }
+ for(std::map<std::string, std::vector<std::string> >::const_iterator
+ it = includedUis.begin();
+ it != includedUis.end();
+ ++it)
+ {
+ for (std::vector<std::string>::const_iterator nit = it->second.begin();
+ nit != it->second.end();
+ ++nit)
+ {
+ this->GenerateUi(it->first, *nit);
+ }
+ }
+
+ if(!this->RccExecutable.empty())
+ {
+ this->GenerateQrc();
+ }
+
+ std::stringstream outStream;
+ outStream << "/* This file is autogenerated, do not edit*/\n";
+
+ bool automocCppChanged = false;
+ if (notIncludedMocs.empty())
+ {
+ outStream << "enum some_compilers { need_more_than_nothing };\n";
+ }
+ else
+ {
+ // run moc on the remaining headers and include them in
+ // the _automoc.cpp file
+ for(std::map<std::string, std::string>::const_iterator
+ it = notIncludedMocs.begin();
+ it != notIncludedMocs.end();
+ ++it)
+ {
+ bool mocSuccess = this->GenerateMoc(it->first, it->second);
+ if (mocSuccess)
+ {
+ automocCppChanged = true;
+ }
+ outStream << "#include \"" << it->second << "\"\n";
+ }
+ }
+
+ if (this->RunMocFailed)
+ {
+ std::cerr << "moc failed..." << std::endl;
+ return false;
+ }
+
+ if (this->RunUicFailed)
+ {
+ std::cerr << "uic failed..." << std::endl;
+ return false;
+ }
+ if (this->RunRccFailed)
+ {
+ std::cerr << "rcc failed..." << std::endl;
+ return false;
+ }
+ outStream.flush();
+ std::string automocSource = outStream.str();
+ if (!automocCppChanged)
+ {
+ // compare contents of the _automoc.cpp file
+ const std::string oldContents = ReadAll(this->OutMocCppFilename);
+ if (oldContents == automocSource)
+ {
+ // nothing changed: don't touch the _automoc.cpp file
+ return true;
+ }
+ }
+
+ // source file that includes all remaining moc files (_automoc.cpp file)
+ cmsys::ofstream outfile;
+ outfile.open(this->OutMocCppFilename.c_str(),
+ std::ios::trunc);
+ outfile << automocSource;
+ outfile.close();
+
+ return true;
+}
+
+
+void cmQtAutoGenerators::ParseCppFile(const std::string& absFilename,
+ const std::vector<std::string>& headerExtensions,
+ std::map<std::string, std::string>& includedMocs,
+ std::map<std::string, std::vector<std::string> > &includedUis)
+{
+ cmsys::RegularExpression mocIncludeRegExp(
+ "[\n][ \t]*#[ \t]*include[ \t]+"
+ "[\"<](([^ \">]+/)?moc_[^ \">/]+\\.cpp|[^ \">]+\\.moc)[\">]");
+
+ const std::string contentsString = ReadAll(absFilename);
+ if (contentsString.empty())
+ {
+ std::cerr << "AUTOGEN: warning: " << absFilename << ": file is empty\n"
+ << std::endl;
+ return;
+ }
+ this->ParseForUic(absFilename, contentsString, includedUis);
+ if (this->MocExecutable.empty())
+ {
+ return;
+ }
+
+ const std::string absPath = cmsys::SystemTools::GetFilenamePath(
+ cmsys::SystemTools::GetRealPath(absFilename)) + '/';
+ const std::string scannedFileBasename = cmsys::SystemTools::
+ GetFilenameWithoutLastExtension(absFilename);
+ std::string macroName;
+ const bool requiresMoc = requiresMocing(contentsString, macroName);
+ bool dotMocIncluded = false;
+ bool mocUnderscoreIncluded = false;
+ std::string ownMocUnderscoreFile;
+ std::string ownDotMocFile;
+ std::string ownMocHeaderFile;
+
+ std::string::size_type matchOffset = 0;
+ // first a simple string check for "moc" is *much* faster than the regexp,
+ // and if the string search already fails, we don't have to try the
+ // expensive regexp
+ if ((strstr(contentsString.c_str(), "moc") != NULL)
+ && (mocIncludeRegExp.find(contentsString)))
+ {
+ // for every moc include in the file
+ do
+ {
+ const std::string currentMoc = mocIncludeRegExp.match(1);
+ //std::cout << "found moc include: " << currentMoc << std::endl;
+
+ std::string basename = cmsys::SystemTools::
+ GetFilenameWithoutLastExtension(currentMoc);
+ const bool moc_style = cmHasLiteralPrefix(basename, "moc_");
+
+ // If the moc include is of the moc_foo.cpp style we expect
+ // the Q_OBJECT class declaration in a header file.
+ // If the moc include is of the foo.moc style we need to look for
+ // a Q_OBJECT macro in the current source file, if it contains the
+ // macro we generate the moc file from the source file.
+ // Q_OBJECT
+ if (moc_style)
+ {
+ // basename should be the part of the moc filename used for
+ // finding the correct header, so we need to remove the moc_ part
+ basename = basename.substr(4);
+ std::string mocSubDir = extractSubDir(absPath, currentMoc);
+ std::string headerToMoc = findMatchingHeader(
+ absPath, mocSubDir, basename, headerExtensions);
+
+ if (!headerToMoc.empty())
+ {
+ includedMocs[headerToMoc] = currentMoc;
+ if (basename == scannedFileBasename)
+ {
+ mocUnderscoreIncluded = true;
+ ownMocUnderscoreFile = currentMoc;
+ ownMocHeaderFile = headerToMoc;
+ }
+ }
+ else
+ {
+ std::cerr << "AUTOGEN: error: " << absFilename << ": The file "
+ << "includes the moc file \"" << currentMoc << "\", "
+ << "but could not find header \"" << basename
+ << '{' << this->Join(headerExtensions, ',') << "}\" ";
+ if (mocSubDir.empty())
+ {
+ std::cerr << "in " << absPath << "\n" << std::endl;
+ }
+ else
+ {
+ std::cerr << "neither in " << absPath
+ << " nor in " << mocSubDir << "\n" << std::endl;
+ }
+
+ ::exit(EXIT_FAILURE);
+ }
+ }
+ else
+ {
+ std::string fileToMoc = absFilename;
+ if ((basename != scannedFileBasename) || (requiresMoc==false))
+ {
+ std::string mocSubDir = extractSubDir(absPath, currentMoc);
+ std::string headerToMoc = findMatchingHeader(
+ absPath, mocSubDir, basename, headerExtensions);
+ if (!headerToMoc.empty())
+ {
+ // this is for KDE4 compatibility:
+ fileToMoc = headerToMoc;
+ if ((requiresMoc==false) &&(basename==scannedFileBasename))
+ {
+ std::cerr << "AUTOGEN: warning: " << absFilename << ": The file "
+ "includes the moc file \"" << currentMoc <<
+ "\", but does not contain a " << macroName
+ << " macro. Running moc on "
+ << "\"" << headerToMoc << "\" ! Include \"moc_"
+ << basename << ".cpp\" for a compatiblity with "
+ "strict mode (see CMAKE_AUTOMOC_RELAXED_MODE).\n"
+ << std::endl;
+ }
+ else
+ {
+ std::cerr << "AUTOGEN: warning: " << absFilename << ": The file "
+ "includes the moc file \"" << currentMoc <<
+ "\" instead of \"moc_" << basename << ".cpp\". "
+ "Running moc on "
+ << "\"" << headerToMoc << "\" ! Include \"moc_"
+ << basename << ".cpp\" for compatiblity with "
+ "strict mode (see CMAKE_AUTOMOC_RELAXED_MODE).\n"
+ << std::endl;
+ }
+ }
+ else
+ {
+ std::cerr <<"AUTOGEN: error: " << absFilename << ": The file "
+ "includes the moc file \"" << currentMoc <<
+ "\", which seems to be the moc file from a different "
+ "source file. CMake also could not find a matching "
+ "header.\n" << std::endl;
+ ::exit(EXIT_FAILURE);
+ }
+ }
+ else
+ {
+ dotMocIncluded = true;
+ ownDotMocFile = currentMoc;
+ }
+ includedMocs[fileToMoc] = currentMoc;
+ }
+ matchOffset += mocIncludeRegExp.end();
+ } while(mocIncludeRegExp.find(contentsString.c_str() + matchOffset));
+ }
+
+ // In this case, check whether the scanned file itself contains a Q_OBJECT.
+ // If this is the case, the moc_foo.cpp should probably be generated from
+ // foo.cpp instead of foo.h, because otherwise it won't build.
+ // But warn, since this is not how it is supposed to be used.
+ if ((dotMocIncluded == false) && (requiresMoc == true))
+ {
+ if (mocUnderscoreIncluded == true)
+ {
+ // this is for KDE4 compatibility:
+ std::cerr << "AUTOGEN: warning: " << absFilename << ": The file "
+ << "contains a " << macroName << " macro, but does not "
+ "include "
+ << "\"" << scannedFileBasename << ".moc\", but instead "
+ "includes "
+ << "\"" << ownMocUnderscoreFile << "\". Running moc on "
+ << "\"" << absFilename << "\" ! Better include \""
+ << scannedFileBasename << ".moc\" for compatiblity with "
+ "strict mode (see CMAKE_AUTOMOC_RELAXED_MODE).\n"
+ << std::endl;
+ includedMocs[absFilename] = ownMocUnderscoreFile;
+ includedMocs.erase(ownMocHeaderFile);
+ }
+ else
+ {
+ // otherwise always error out since it will not compile:
+ std::cerr << "AUTOGEN: error: " << absFilename << ": The file "
+ << "contains a " << macroName << " macro, but does not "
+ "include "
+ << "\"" << scannedFileBasename << ".moc\" !\n"
+ << std::endl;
+ ::exit(EXIT_FAILURE);
+ }
+ }
+
+}
+
+
+void cmQtAutoGenerators::StrictParseCppFile(const std::string& absFilename,
+ const std::vector<std::string>& headerExtensions,
+ std::map<std::string, std::string>& includedMocs,
+ std::map<std::string, std::vector<std::string> >& includedUis)
+{
+ cmsys::RegularExpression mocIncludeRegExp(
+ "[\n][ \t]*#[ \t]*include[ \t]+"
+ "[\"<](([^ \">]+/)?moc_[^ \">/]+\\.cpp|[^ \">]+\\.moc)[\">]");
+
+ const std::string contentsString = ReadAll(absFilename);
+ if (contentsString.empty())
+ {
+ std::cerr << "AUTOGEN: warning: " << absFilename << ": file is empty\n"
+ << std::endl;
+ return;
+ }
+ this->ParseForUic(absFilename, contentsString, includedUis);
+ if (this->MocExecutable.empty())
+ {
+ return;
+ }
+
+ const std::string absPath = cmsys::SystemTools::GetFilenamePath(
+ cmsys::SystemTools::GetRealPath(absFilename)) + '/';
+ const std::string scannedFileBasename = cmsys::SystemTools::
+ GetFilenameWithoutLastExtension(absFilename);
+
+ bool dotMocIncluded = false;
+
+ std::string::size_type matchOffset = 0;
+ // first a simple string check for "moc" is *much* faster than the regexp,
+ // and if the string search already fails, we don't have to try the
+ // expensive regexp
+ if ((strstr(contentsString.c_str(), "moc") != NULL)
+ && (mocIncludeRegExp.find(contentsString)))
+ {
+ // for every moc include in the file
+ do
+ {
+ const std::string currentMoc = mocIncludeRegExp.match(1);
+
+ std::string basename = cmsys::SystemTools::
+ GetFilenameWithoutLastExtension(currentMoc);
+ const bool mocUnderscoreStyle = cmHasLiteralPrefix(basename, "moc_");
+
+ // If the moc include is of the moc_foo.cpp style we expect
+ // the Q_OBJECT class declaration in a header file.
+ // If the moc include is of the foo.moc style we need to look for
+ // a Q_OBJECT macro in the current source file, if it contains the
+ // macro we generate the moc file from the source file.
+ if (mocUnderscoreStyle)
+ {
+ // basename should be the part of the moc filename used for
+ // finding the correct header, so we need to remove the moc_ part
+ basename = basename.substr(4);
+ std::string mocSubDir = extractSubDir(absPath, currentMoc);
+ std::string headerToMoc = findMatchingHeader(
+ absPath, mocSubDir, basename, headerExtensions);
+
+ if (!headerToMoc.empty())
+ {
+ includedMocs[headerToMoc] = currentMoc;
+ }
+ else
+ {
+ std::cerr << "AUTOGEN: error: " << absFilename << " The file "
+ << "includes the moc file \"" << currentMoc << "\", "
+ << "but could not find header \"" << basename
+ << '{' << this->Join(headerExtensions, ',') << "}\" ";
+ if (mocSubDir.empty())
+ {
+ std::cerr << "in " << absPath << "\n" << std::endl;
+ }
+ else
+ {
+ std::cerr << "neither in " << absPath
+ << " nor in " << mocSubDir << "\n" << std::endl;
+ }
+
+ ::exit(EXIT_FAILURE);
+ }
+ }
+ else
+ {
+ if (basename != scannedFileBasename)
+ {
+ std::cerr <<"AUTOGEN: error: " << absFilename << ": The file "
+ "includes the moc file \"" << currentMoc <<
+ "\", which seems to be the moc file from a different "
+ "source file. This is not supported. "
+ "Include \"" << scannedFileBasename << ".moc\" to run "
+ "moc on this source file.\n" << std::endl;
+ ::exit(EXIT_FAILURE);
+ }
+ dotMocIncluded = true;
+ includedMocs[absFilename] = currentMoc;
+ }
+ matchOffset += mocIncludeRegExp.end();
+ } while(mocIncludeRegExp.find(contentsString.c_str() + matchOffset));
+ }
+
+ // In this case, check whether the scanned file itself contains a Q_OBJECT.
+ // If this is the case, the moc_foo.cpp should probably be generated from
+ // foo.cpp instead of foo.h, because otherwise it won't build.
+ // But warn, since this is not how it is supposed to be used.
+ std::string macroName;
+ if ((dotMocIncluded == false) && (requiresMocing(contentsString,
+ macroName)))
+ {
+ // otherwise always error out since it will not compile:
+ std::cerr << "AUTOGEN: error: " << absFilename << ": The file "
+ << "contains a " << macroName << " macro, but does not include "
+ << "\"" << scannedFileBasename << ".moc\" !\n"
+ << std::endl;
+ ::exit(EXIT_FAILURE);
+ }
+
+}
+
+
+void cmQtAutoGenerators::ParseForUic(const std::string& absFilename,
+ std::map<std::string, std::vector<std::string> >& includedUis)
+{
+ if (this->UicExecutable.empty())
+ {
+ return;
+ }
+ const std::string contentsString = ReadAll(absFilename);
+ if (contentsString.empty())
+ {
+ std::cerr << "AUTOGEN: warning: " << absFilename << ": file is empty\n"
+ << std::endl;
+ return;
+ }
+ this->ParseForUic(absFilename, contentsString, includedUis);
+}
+
+
+void cmQtAutoGenerators::ParseForUic(const std::string& absFilename,
+ const std::string& contentsString,
+ std::map<std::string, std::vector<std::string> >& includedUis)
+{
+ if (this->UicExecutable.empty())
+ {
+ return;
+ }
+ cmsys::RegularExpression uiIncludeRegExp(
+ "[\n][ \t]*#[ \t]*include[ \t]+"
+ "[\"<](([^ \">]+/)?ui_[^ \">/]+\\.h)[\">]");
+
+ std::string::size_type matchOffset = 0;
+
+ const std::string realName =
+ cmsys::SystemTools::GetRealPath(absFilename);
+
+ matchOffset = 0;
+ if ((strstr(contentsString.c_str(), "ui_") != NULL)
+ && (uiIncludeRegExp.find(contentsString)))
+ {
+ do
+ {
+ const std::string currentUi = uiIncludeRegExp.match(1);
+
+ std::string basename = cmsys::SystemTools::
+ GetFilenameWithoutLastExtension(currentUi);
+
+ // basename should be the part of the ui filename used for
+ // finding the correct header, so we need to remove the ui_ part
+ basename = basename.substr(3);
+
+ includedUis[realName].push_back(basename);
+
+ matchOffset += uiIncludeRegExp.end();
+ } while(uiIncludeRegExp.find(contentsString.c_str() + matchOffset));
+ }
+}
+
+
+void
+cmQtAutoGenerators::SearchHeadersForCppFile(const std::string& absFilename,
+ const std::vector<std::string>& headerExtensions,
+ std::set<std::string>& absHeaders)
+{
+ // search for header files and private header files we may need to moc:
+ const std::string basename =
+ cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename);
+ const std::string absPath = cmsys::SystemTools::GetFilenamePath(
+ cmsys::SystemTools::GetRealPath(absFilename)) + '/';
+
+ for(std::vector<std::string>::const_iterator ext = headerExtensions.begin();
+ ext != headerExtensions.end();
+ ++ext)
+ {
+ const std::string headerName = absPath + basename + "." + (*ext);
+ if (cmsys::SystemTools::FileExists(headerName.c_str()))
+ {
+ absHeaders.insert(headerName);
+ break;
+ }
+ }
+ for(std::vector<std::string>::const_iterator ext = headerExtensions.begin();
+ ext != headerExtensions.end();
+ ++ext)
+ {
+ const std::string privateHeaderName = absPath+basename+"_p."+(*ext);
+ if (cmsys::SystemTools::FileExists(privateHeaderName.c_str()))
+ {
+ absHeaders.insert(privateHeaderName);
+ break;
+ }
+ }
+
+}
+
+
+void cmQtAutoGenerators::ParseHeaders(const std::set<std::string>& absHeaders,
+ const std::map<std::string, std::string>& includedMocs,
+ std::map<std::string, std::string>& notIncludedMocs,
+ std::map<std::string, std::vector<std::string> >& includedUis)
+{
+ for(std::set<std::string>::const_iterator hIt=absHeaders.begin();
+ hIt!=absHeaders.end();
+ ++hIt)
+ {
+ const std::string& headerName = *hIt;
+ const std::string contents = ReadAll(headerName);
+
+ if (!this->MocExecutable.empty()
+ && includedMocs.find(headerName) == includedMocs.end())
+ {
+ if (this->Verbose)
+ {
+ std::cout << "AUTOGEN: Checking " << headerName << std::endl;
+ }
+
+ const std::string basename = cmsys::SystemTools::
+ GetFilenameWithoutLastExtension(headerName);
+
+ const std::string currentMoc = "moc_" + basename + ".cpp";
+ std::string macroName;
+ if (requiresMocing(contents, macroName))
+ {
+ //std::cout << "header contains Q_OBJECT macro";
+ notIncludedMocs[headerName] = currentMoc;
+ }
+ }
+ this->ParseForUic(headerName, contents, includedUis);
+ }
+}
+
+bool cmQtAutoGenerators::GenerateMoc(const std::string& sourceFile,
+ const std::string& mocFileName)
+{
+ const std::string mocFilePath = this->Builddir + mocFileName;
+ int sourceNewerThanMoc = 0;
+ bool success = cmsys::SystemTools::FileTimeCompare(sourceFile,
+ mocFilePath,
+ &sourceNewerThanMoc);
+ if (this->GenerateAll || !success || sourceNewerThanMoc >= 0)
+ {
+ // make sure the directory for the resulting moc file exists
+ std::string mocDir = mocFilePath.substr(0, mocFilePath.rfind('/'));
+ if (!cmsys::SystemTools::FileExists(mocDir.c_str(), false))
+ {
+ cmsys::SystemTools::MakeDirectory(mocDir.c_str());
+ }
+
+ std::string msg = "Generating ";
+ msg += mocFileName;
+ cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundBlue
+ |cmsysTerminal_Color_ForegroundBold,
+ msg.c_str(), true, this->ColorOutput);
+
+ std::vector<std::string> command;
+ command.push_back(this->MocExecutable);
+ command.insert(command.end(),
+ this->MocIncludes.begin(), this->MocIncludes.end());
+ command.insert(command.end(),
+ this->MocDefinitions.begin(), this->MocDefinitions.end());
+ command.insert(command.end(),
+ this->MocOptions.begin(), this->MocOptions.end());
+#ifdef _WIN32
+ command.push_back("-DWIN32");
+#endif
+ command.push_back("-o");
+ command.push_back(mocFilePath);
+ command.push_back(sourceFile);
+
+ if (this->Verbose)
+ {
+ for(std::vector<std::string>::const_iterator cmdIt = command.begin();
+ cmdIt != command.end();
+ ++cmdIt)
+ {
+ std::cout << *cmdIt << " ";
+ }
+ std::cout << std::endl;
+ }
+
+ std::string output;
+ int retVal = 0;
+ bool result = cmSystemTools::RunSingleCommand(command, &output, &output,
+ &retVal);
+ if (!result || retVal)
+ {
+ std::cerr << "AUTOGEN: error: process for " << mocFilePath <<" failed:\n"
+ << output << std::endl;
+ this->RunMocFailed = true;
+ cmSystemTools::RemoveFile(mocFilePath);
+ }
+ return true;
+ }
+ return false;
+}
+
+bool cmQtAutoGenerators::GenerateUi(const std::string& realName,
+ const std::string& uiFileName)
+{
+ if (!cmsys::SystemTools::FileExists(this->Builddir.c_str(), false))
+ {
+ cmsys::SystemTools::MakeDirectory(this->Builddir.c_str());
+ }
+
+ const std::string path = cmsys::SystemTools::GetFilenamePath(
+ realName) + '/';
+
+ std::string ui_output_file = "ui_" + uiFileName + ".h";
+ std::string ui_input_file = path + uiFileName + ".ui";
+
+ int sourceNewerThanUi = 0;
+ bool success = cmsys::SystemTools::FileTimeCompare(ui_input_file,
+ this->Builddir + ui_output_file,
+ &sourceNewerThanUi);
+ if (this->GenerateAll || !success || sourceNewerThanUi >= 0)
+ {
+ std::string msg = "Generating ";
+ msg += ui_output_file;
+ cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundBlue
+ |cmsysTerminal_Color_ForegroundBold,
+ msg.c_str(), true, this->ColorOutput);
+
+ std::vector<std::string> command;
+ command.push_back(this->UicExecutable);
+
+ std::vector<std::string> opts = this->UicTargetOptions;
+ std::map<std::string, std::string>::const_iterator optionIt
+ = this->UicOptions.find(ui_input_file);
+ if (optionIt != this->UicOptions.end())
+ {
+ std::vector<std::string> fileOpts;
+ cmSystemTools::ExpandListArgument(optionIt->second, fileOpts);
+ cmQtAutoGenerators::MergeUicOptions(opts, fileOpts,
+ this->QtMajorVersion == "5");
+ }
+ command.insert(command.end(), opts.begin(), opts.end());
+
+ command.push_back("-o");
+ command.push_back(this->Builddir + ui_output_file);
+ command.push_back(ui_input_file);
+
+ if (this->Verbose)
+ {
+ for(std::vector<std::string>::const_iterator cmdIt = command.begin();
+ cmdIt != command.end();
+ ++cmdIt)
+ {
+ std::cout << *cmdIt << " ";
+ }
+ std::cout << std::endl;
+ }
+ std::string output;
+ int retVal = 0;
+ bool result = cmSystemTools::RunSingleCommand(command, &output, &output,
+ &retVal);
+ if (!result || retVal)
+ {
+ std::cerr << "AUTOUIC: error: process for " << ui_output_file <<
+ " needed by\n \"" << realName << "\"\nfailed:\n" << output
+ << std::endl;
+ this->RunUicFailed = true;
+ cmSystemTools::RemoveFile(ui_output_file);
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
+
+bool cmQtAutoGenerators::InputFilesNewerThanQrc(const std::string& qrcFile,
+ const std::string& rccOutput)
+{
+ std::vector<std::string> const& files = this->RccInputs[qrcFile];
+ for (std::vector<std::string>::const_iterator it = files.begin();
+ it != files.end(); ++it)
+ {
+ int inputNewerThanQrc = 0;
+ bool success = cmsys::SystemTools::FileTimeCompare(*it,
+ rccOutput,
+ &inputNewerThanQrc);
+ if (!success || inputNewerThanQrc >= 0)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool cmQtAutoGenerators::GenerateQrc()
+{
+ for(std::vector<std::string>::const_iterator si = this->RccSources.begin();
+ si != this->RccSources.end(); ++si)
+ {
+ std::string ext = cmsys::SystemTools::GetFilenameLastExtension(*si);
+
+ if (ext != ".qrc")
+ {
+ continue;
+ }
+ std::vector<std::string> command;
+ command.push_back(this->RccExecutable);
+
+ std::string basename = cmsys::SystemTools::
+ GetFilenameWithoutLastExtension(*si);
+
+ std::string rcc_output_file = this->Builddir
+ + "CMakeFiles/" + this->OriginTargetName
+ + ".dir/qrc_" + basename + ".cpp";
+
+ int sourceNewerThanQrc = 0;
+ bool generateQrc = !cmsys::SystemTools::FileTimeCompare(*si,
+ rcc_output_file,
+ &sourceNewerThanQrc);
+ generateQrc = generateQrc || (sourceNewerThanQrc >= 0);
+ generateQrc = generateQrc || this->InputFilesNewerThanQrc(*si,
+ rcc_output_file);
+
+ if (this->GenerateAll || generateQrc)
+ {
+ std::map<std::string, std::string>::const_iterator optionIt
+ = this->RccOptions.find(*si);
+ if (optionIt != this->RccOptions.end())
+ {
+ cmSystemTools::ExpandListArgument(optionIt->second, command);
+ }
+
+ command.push_back("-name");
+ command.push_back(basename);
+ command.push_back("-o");
+ command.push_back(rcc_output_file);
+ command.push_back(*si);
+
+ if (this->Verbose)
+ {
+ for(std::vector<std::string>::const_iterator cmdIt = command.begin();
+ cmdIt != command.end();
+ ++cmdIt)
+ {
+ std::cout << *cmdIt << " ";
+ }
+ std::cout << std::endl;
+ }
+ std::string output;
+ int retVal = 0;
+ bool result = cmSystemTools::RunSingleCommand(command, &output, &output,
+ &retVal);
+ if (!result || retVal)
+ {
+ std::cerr << "AUTORCC: error: process for " << rcc_output_file <<
+ " failed:\n" << output << std::endl;
+ this->RunRccFailed = true;
+ cmSystemTools::RemoveFile(rcc_output_file);
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+std::string cmQtAutoGenerators::Join(const std::vector<std::string>& lst,
+ char separator)
+{
+ if (lst.empty())
+ {
+ return "";
+ }
+
+ std::string result;
+ for (std::vector<std::string>::const_iterator it = lst.begin();
+ it != lst.end();
+ ++it)
+ {
+ result += "." + (*it) + separator;
+ }
+ result.erase(result.end() - 1);
+ return result;
+}
+
+
+bool cmQtAutoGenerators::StartsWith(const std::string& str,
+ const std::string& with)
+{
+ return (str.substr(0, with.length()) == with);
+}
+
+
+bool cmQtAutoGenerators::EndsWith(const std::string& str,
+ const std::string& with)
+{
+ if (with.length() > (str.length()))
+ {
+ return false;
+ }
+ return (str.substr(str.length() - with.length(), with.length()) == with);
+}
diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h
new file mode 100644
index 000000000..ab7b6ed22
--- /dev/null
+++ b/Source/cmQtAutoGenerators.h
@@ -0,0 +1,123 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2004-2011 Kitware, Inc.
+ Copyright 2011 Alexander Neundorf (neundorf@kde.org)
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmQtAutoGenerators_h
+#define cmQtAutoGenerators_h
+
+#include <list>
+#include <vector>
+#include <string>
+#include <map>
+
+class cmMakefile;
+
+class cmQtAutoGenerators
+{
+public:
+ cmQtAutoGenerators();
+ bool Run(const std::string& targetDirectory, const std::string& config);
+
+private:
+
+ bool ReadAutogenInfoFile(cmMakefile* makefile,
+ const std::string& targetDirectory,
+ const std::string& config);
+ bool ReadOldMocDefinitionsFile(cmMakefile* makefile,
+ const std::string& targetDirectory);
+ void WriteOldMocDefinitionsFile(const std::string& targetDirectory);
+
+ std::string MakeCompileSettingsString(cmMakefile* makefile);
+
+ bool RunAutogen(cmMakefile* makefile);
+ bool GenerateMoc(const std::string& sourceFile,
+ const std::string& mocFileName);
+ bool GenerateUi(const std::string& realName, const std::string& uiFileName);
+ bool GenerateQrc();
+ void ParseCppFile(const std::string& absFilename,
+ const std::vector<std::string>& headerExtensions,
+ std::map<std::string, std::string>& includedMocs,
+ std::map<std::string, std::vector<std::string> >& includedUis);
+ void StrictParseCppFile(const std::string& absFilename,
+ const std::vector<std::string>& headerExtensions,
+ std::map<std::string, std::string>& includedMocs,
+ std::map<std::string, std::vector<std::string> >& includedUis);
+ void SearchHeadersForCppFile(const std::string& absFilename,
+ const std::vector<std::string>& headerExtensions,
+ std::set<std::string>& absHeaders);
+
+ void ParseHeaders(const std::set<std::string>& absHeaders,
+ const std::map<std::string, std::string>& includedMocs,
+ std::map<std::string, std::string>& notIncludedMocs,
+ std::map<std::string, std::vector<std::string> >& includedUis);
+
+ void ParseForUic(const std::string& fileName,
+ const std::string& contentsString,
+ std::map<std::string, std::vector<std::string> >& includedUis);
+
+ void ParseForUic(const std::string& fileName,
+ std::map<std::string, std::vector<std::string> >& includedUis);
+
+ void Init();
+
+ std::string Join(const std::vector<std::string>& lst, char separator);
+ bool EndsWith(const std::string& str, const std::string& with);
+ bool StartsWith(const std::string& str, const std::string& with);
+
+ static void MergeUicOptions(std::vector<std::string> &opts,
+ const std::vector<std::string> &fileOpts, bool isQt5);
+
+ bool InputFilesNewerThanQrc(const std::string& qrcFile,
+ const std::string& rccOutput);
+
+ std::string QtMajorVersion;
+ std::string Sources;
+ std::vector<std::string> RccSources;
+ std::string SkipMoc;
+ std::string SkipUic;
+ std::string Headers;
+ std::string Srcdir;
+ std::string Builddir;
+ std::string MocExecutable;
+ std::string UicExecutable;
+ std::string RccExecutable;
+ std::string MocCompileDefinitionsStr;
+ std::string MocIncludesStr;
+ std::string MocOptionsStr;
+ std::string ProjectBinaryDir;
+ std::string ProjectSourceDir;
+ std::string TargetName;
+ std::string OriginTargetName;
+
+ std::string CurrentCompileSettingsStr;
+ std::string OldCompileSettingsStr;
+
+ std::string OutMocCppFilename;
+ std::list<std::string> MocIncludes;
+ std::list<std::string> MocDefinitions;
+ std::vector<std::string> MocOptions;
+ std::vector<std::string> UicTargetOptions;
+ std::map<std::string, std::string> UicOptions;
+ std::map<std::string, std::string> RccOptions;
+ std::map<std::string, std::vector<std::string> > RccInputs;
+
+ bool IncludeProjectDirsBefore;
+ bool Verbose;
+ bool ColorOutput;
+ bool RunMocFailed;
+ bool RunUicFailed;
+ bool RunRccFailed;
+ bool GenerateAll;
+ bool RelaxedMode;
+};
+
+#endif
diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx
deleted file mode 100644
index 93e39abeb..000000000
--- a/Source/cmQtAutomoc.cxx
+++ /dev/null
@@ -1,1299 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2004-2011 Kitware, Inc.
- Copyright 2011 Alexander Neundorf (neundorf@kde.org)
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-
-#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
-#include "cmMakefile.h"
-#include "cmSourceFile.h"
-#include "cmSystemTools.h"
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-# include "cmLocalVisualStudioGenerator.h"
-#endif
-
-#include <cmsys/Terminal.h>
-#include <cmsys/ios/sstream>
-
-#include <string.h>
-#if defined(__APPLE__)
-#include <unistd.h>
-#endif
-
-#include "cmQtAutomoc.h"
-
-
-static bool containsQ_OBJECT(const std::string& text)
-{
- // this simple check is much much faster than the regexp
- if (strstr(text.c_str(), "Q_OBJECT") == NULL)
- {
- return false;
- }
-
- cmsys::RegularExpression qObjectRegExp("[\n][ \t]*Q_OBJECT[^a-zA-Z0-9_]");
- return qObjectRegExp.find(text);
-}
-
-
-static std::string findMatchingHeader(const std::string& absPath,
- const std::string& mocSubDir,
- const std::string& basename,
- const std::vector<std::string>& headerExtensions)
-{
- std::string header;
- for(std::vector<std::string>::const_iterator ext = headerExtensions.begin();
- ext != headerExtensions.end();
- ++ext)
- {
- std::string sourceFilePath = absPath + basename + "." + (*ext);
- if (cmsys::SystemTools::FileExists(sourceFilePath.c_str()))
- {
- header = sourceFilePath;
- break;
- }
- if (!mocSubDir.empty())
- {
- sourceFilePath = mocSubDir + basename + "." + (*ext);
- if (cmsys::SystemTools::FileExists(sourceFilePath.c_str()))
- {
- header = sourceFilePath;
- break;
- }
- }
- }
-
- return header;
-}
-
-
-static std::string extractSubDir(const std::string& absPath,
- const std::string& currentMoc)
-{
- std::string subDir;
- if (currentMoc.find_first_of('/') != std::string::npos)
- {
- subDir = absPath
- + cmsys::SystemTools::GetFilenamePath(currentMoc) + '/';
- }
- return subDir;
-}
-
-
-static void copyTargetProperty(cmTarget* destinationTarget,
- cmTarget* sourceTarget,
- const char* propertyName)
-{
- const char* propertyValue = sourceTarget->GetProperty(propertyName);
- if (propertyValue)
- {
- destinationTarget->SetProperty(propertyName, propertyValue);
- }
-}
-
-
-cmQtAutomoc::cmQtAutomoc()
-:Verbose(cmsys::SystemTools::GetEnv("VERBOSE") != 0)
-,ColorOutput(true)
-,RunMocFailed(false)
-,GenerateAll(false)
-{
-
- std::string colorEnv = "";
- cmsys::SystemTools::GetEnv("COLOR", colorEnv);
- if(!colorEnv.empty())
- {
- if(cmSystemTools::IsOn(colorEnv.c_str()))
- {
- this->ColorOutput = true;
- }
- else
- {
- this->ColorOutput = false;
- }
- }
-}
-
-bool cmQtAutomoc::InitializeMocSourceFile(cmTarget* target)
-{
- cmMakefile* makefile = target->GetMakefile();
- // don't do anything if there is no Qt4 or Qt5Core (which contains moc):
- std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR");
- if (qtMajorVersion == "")
- {
- qtMajorVersion = makefile->GetSafeDefinition("Qt5Core_VERSION_MAJOR");
- }
- if (qtMajorVersion != "4" && qtMajorVersion != "5")
- {
- return false;
- }
-
- std::string automocTargetName = target->GetName();
- automocTargetName += "_automoc";
- std::string mocCppFile = makefile->GetCurrentOutputDirectory();
- mocCppFile += "/";
- mocCppFile += automocTargetName;
- mocCppFile += ".cpp";
- cmSourceFile* mocCppSource = makefile->GetOrCreateSource(mocCppFile.c_str(),
- true);
- makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
- mocCppFile.c_str(), false);
-
- target->AddSourceFile(mocCppSource);
- return true;
-}
-
-static void GetCompileDefinitionsAndDirectories(cmTarget *target,
- const char * config,
- std::string &incs,
- std::string &defs)
-{
- cmMakefile* makefile = target->GetMakefile();
- cmLocalGenerator* localGen = makefile->GetLocalGenerator();
- std::vector<std::string> includeDirs;
- cmGeneratorTarget gtgt(target);
- // Get the include dirs for this target, without stripping the implicit
- // include dirs off, see http://public.kitware.com/Bug/view.php?id=13667
- localGen->GetIncludeDirectories(includeDirs, &gtgt, "CXX", config, false);
- const char* sep = "";
- incs = "";
- for(std::vector<std::string>::const_iterator incDirIt = includeDirs.begin();
- incDirIt != includeDirs.end();
- ++incDirIt)
- {
- incs += sep;
- sep = ";";
- incs += *incDirIt;
- }
-
- std::set<std::string> defines;
- localGen->AddCompileDefinitions(defines, target, config);
-
- sep = "";
- for(std::set<std::string>::const_iterator defIt = defines.begin();
- defIt != defines.end();
- ++defIt)
- {
- defs += sep;
- sep = ";";
- defs += *defIt;
- }
-}
-
-void cmQtAutomoc::SetupAutomocTarget(cmTarget* target)
-{
- cmMakefile* makefile = target->GetMakefile();
- const char* targetName = target->GetName();
-
- bool relaxedMode = makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE");
-
- // create a custom target for running automoc at buildtime:
- std::string automocTargetName = targetName;
- automocTargetName += "_automoc";
-
- std::string targetDir = makefile->GetCurrentOutputDirectory();
- targetDir += makefile->GetCMakeInstance()->GetCMakeFilesDirectory();
- targetDir += "/";
- targetDir += automocTargetName;
- targetDir += ".dir/";
-
- cmCustomCommandLine currentLine;
- currentLine.push_back(makefile->GetSafeDefinition("CMAKE_COMMAND"));
- currentLine.push_back("-E");
- currentLine.push_back("cmake_automoc");
- currentLine.push_back(targetDir);
- currentLine.push_back("$<CONFIGURATION>");
-
- cmCustomCommandLines commandLines;
- commandLines.push_back(currentLine);
-
- std::string workingDirectory = cmSystemTools::CollapseFullPath(
- "", makefile->GetCurrentOutputDirectory());
-
- std::vector<std::string> depends;
- std::string automocComment = "Automoc for target ";
- automocComment += targetName;
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- bool usePRE_BUILD = false;
- cmLocalGenerator* localGen = makefile->GetLocalGenerator();
- cmGlobalGenerator* gg = localGen->GetGlobalGenerator();
- if(strstr(gg->GetName(), "Visual Studio"))
- {
- cmLocalVisualStudioGenerator* vslg =
- static_cast<cmLocalVisualStudioGenerator*>(localGen);
- // Under VS >= 7 use a PRE_BUILD event instead of a separate target to
- // reduce the number of targets loaded into the IDE.
- // This also works around a VS 11 bug that may skip updating the target:
- // https://connect.microsoft.com/VisualStudio/feedback/details/769495
- usePRE_BUILD = vslg->GetVersion() >= cmLocalVisualStudioGenerator::VS7;
- }
- if(usePRE_BUILD)
- {
- // Add the pre-build command directly to bypass the OBJECT_LIBRARY
- // rejection in cmMakefile::AddCustomCommandToTarget because we know
- // PRE_BUILD will work for an OBJECT_LIBRARY in this specific case.
- std::vector<std::string> no_output;
- cmCustomCommand cc(makefile, no_output, depends,
- commandLines, automocComment.c_str(),
- workingDirectory.c_str());
- cc.SetEscapeOldStyle(false);
- cc.SetEscapeAllowMakeVars(true);
- target->GetPreBuildCommands().push_back(cc);
- }
- else
-#endif
- {
- cmTarget* automocTarget = makefile->AddUtilityCommand(
- automocTargetName.c_str(), true,
- workingDirectory.c_str(), depends,
- commandLines, false, automocComment.c_str());
- // Set target folder
- const char* automocFolder = makefile->GetCMakeInstance()->GetProperty(
- "AUTOMOC_TARGETS_FOLDER");
- if (automocFolder && *automocFolder)
- {
- automocTarget->SetProperty("FOLDER", automocFolder);
- }
- else
- {
- // inherit FOLDER property from target (#13688)
- copyTargetProperty(automocTarget, target, "FOLDER");
- }
-
- target->AddUtility(automocTargetName.c_str());
- }
-
- // configure a file to get all information to automoc at buildtime:
- std::string _moc_files;
- std::string _moc_headers;
- const char* sepFiles = "";
- const char* sepHeaders = "";
-
- const std::vector<cmSourceFile*>& srcFiles = target->GetSourceFiles();
-
- for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
- fileIt != srcFiles.end();
- ++fileIt)
- {
- cmSourceFile* sf = *fileIt;
- std::string absFile = cmsys::SystemTools::GetRealPath(
- sf->GetFullPath().c_str());
- bool skip = cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOMOC"));
- bool generated = cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"));
-
- if ((skip==false) && (generated == false))
- {
- std::string ext = sf->GetExtension();
- cmSystemTools::FileFormat fileType = cmSystemTools::GetFileFormat(
- ext.c_str());
- if (fileType == cmSystemTools::CXX_FILE_FORMAT)
- {
- _moc_files += sepFiles;
- _moc_files += absFile;
- sepFiles = ";";
- }
- else if (fileType == cmSystemTools::HEADER_FILE_FORMAT)
- {
- _moc_headers += sepHeaders;
- _moc_headers += absFile;
- sepHeaders = ";";
- }
- }
- }
-
- const char* tmp = target->GetProperty("AUTOMOC_MOC_OPTIONS");
- std::string _moc_options = (tmp!=0 ? tmp : "");
-
- // forget the variables added here afterwards again:
- cmMakefile::ScopePushPop varScope(makefile);
- static_cast<void>(varScope);
-
- makefile->AddDefinition("_moc_target_name",
- cmLocalGenerator::EscapeForCMake(automocTargetName.c_str()).c_str());
- makefile->AddDefinition("_moc_options",
- cmLocalGenerator::EscapeForCMake(_moc_options.c_str()).c_str());
- makefile->AddDefinition("_moc_files",
- cmLocalGenerator::EscapeForCMake(_moc_files.c_str()).c_str());
- makefile->AddDefinition("_moc_headers",
- cmLocalGenerator::EscapeForCMake(_moc_headers.c_str()).c_str());
- makefile->AddDefinition("_moc_relaxed_mode", relaxedMode ? "TRUE" : "FALSE");
-
- std::string _moc_incs;
- std::string _moc_compile_defs;
- std::vector<std::string> configs;
- const char *config = makefile->GetConfigurations(configs);
- GetCompileDefinitionsAndDirectories(target, config,
- _moc_incs, _moc_compile_defs);
-
- makefile->AddDefinition("_moc_incs",
- cmLocalGenerator::EscapeForCMake(_moc_incs.c_str()).c_str());
- makefile->AddDefinition("_moc_compile_defs",
- cmLocalGenerator::EscapeForCMake(_moc_compile_defs.c_str()).c_str());
-
- std::map<std::string, std::string> configIncludes;
- std::map<std::string, std::string> configDefines;
-
- for (std::vector<std::string>::const_iterator li = configs.begin();
- li != configs.end(); ++li)
- {
- std::string config_moc_incs;
- std::string config_moc_compile_defs;
- GetCompileDefinitionsAndDirectories(target, li->c_str(),
- config_moc_incs,
- config_moc_compile_defs);
- if (config_moc_incs != _moc_incs)
- {
- configIncludes["_moc_incs_" + *li] =
- cmLocalGenerator::EscapeForCMake(config_moc_incs.c_str());
- if(_moc_incs.empty())
- {
- _moc_incs = config_moc_incs;
- }
- }
- if (config_moc_compile_defs != _moc_compile_defs)
- {
- configDefines["_moc_compile_defs_" + *li] =
- cmLocalGenerator::EscapeForCMake(config_moc_compile_defs.c_str());
- if(_moc_compile_defs.empty())
- {
- _moc_compile_defs = config_moc_compile_defs;
- }
- }
- }
-
- const char *qtVersion = makefile->GetDefinition("Qt5Core_VERSION_MAJOR");
- if (!qtVersion)
- {
- qtVersion = makefile->GetDefinition("QT_VERSION_MAJOR");
- }
- if (const char *targetQtVersion =
- target->GetLinkInterfaceDependentStringProperty("QT_MAJOR_VERSION", 0))
- {
- qtVersion = targetQtVersion;
- }
- if (qtVersion)
- {
- makefile->AddDefinition("_target_qt_version", qtVersion);
- }
-
- {
- const char *qtMoc = makefile->GetSafeDefinition("QT_MOC_EXECUTABLE");
- makefile->AddDefinition("_qt_moc_executable", qtMoc);
- }
-
- if (strcmp(qtVersion, "5") == 0)
- {
- cmTarget *qt5Moc = makefile->FindTargetToUse("Qt5::moc");
- if (!qt5Moc)
- {
- cmSystemTools::Error("Qt5::moc target not found ",
- automocTargetName.c_str());
- return;
- }
- makefile->AddDefinition("_qt_moc_executable", qt5Moc->GetLocation(0));
- }
- else
- {
- if (strcmp(qtVersion, "4") != 0)
- {
- cmSystemTools::Error("The CMAKE_AUTOMOC feature supports only Qt 4 and "
- "Qt 5 ", automocTargetName.c_str());
- }
- }
-
- const char* cmakeRoot = makefile->GetSafeDefinition("CMAKE_ROOT");
- std::string inputFile = cmakeRoot;
- inputFile += "/Modules/AutomocInfo.cmake.in";
- std::string outputFile = targetDir;
- outputFile += "/AutomocInfo.cmake";
- makefile->ConfigureFile(inputFile.c_str(), outputFile.c_str(),
- false, true, false);
-
- if (!configDefines.empty() || !configIncludes.empty())
- {
- std::ofstream infoFile(outputFile.c_str(), std::ios::app);
- if ( !infoFile )
- {
- std::string error = "Internal CMake error when trying to open file: ";
- error += outputFile.c_str();
- error += " for writing.";
- cmSystemTools::Error(error.c_str());
- return;
- }
- if (!configDefines.empty())
- {
- for (std::map<std::string, std::string>::iterator
- it = configDefines.begin(), end = configDefines.end();
- it != end; ++it)
- {
- infoFile << "SET(AM_MOC_COMPILE_DEFINITIONS_" << it->first <<
- " " << it->second << ")\n";
- }
- }
- if (!configIncludes.empty())
- {
- for (std::map<std::string, std::string>::iterator
- it = configIncludes.begin(), end = configIncludes.end();
- it != end; ++it)
- {
- infoFile << "SET(AM_MOC_INCLUDES_" << it->first <<
- " " << it->second << ")\n";
- }
- }
- }
-}
-
-
-bool cmQtAutomoc::Run(const char* targetDirectory, const char *config)
-{
- bool success = true;
- cmake cm;
- cmGlobalGenerator* gg = this->CreateGlobalGenerator(&cm, targetDirectory);
- cmMakefile* makefile = gg->GetCurrentLocalGenerator()->GetMakefile();
-
- this->ReadAutomocInfoFile(makefile, targetDirectory, config);
- this->ReadOldMocDefinitionsFile(makefile, targetDirectory);
-
- this->Init();
-
- if (this->QtMajorVersion == "4" || this->QtMajorVersion == "5")
- {
- success = this->RunAutomoc(makefile);
- }
-
- this->WriteOldMocDefinitionsFile(targetDirectory);
-
- delete gg;
- gg = NULL;
- makefile = NULL;
- return success;
-}
-
-
-cmGlobalGenerator* cmQtAutomoc::CreateGlobalGenerator(cmake* cm,
- const char* targetDirectory)
-{
- cmGlobalGenerator* gg = new cmGlobalGenerator();
- gg->SetCMakeInstance(cm);
-
- cmLocalGenerator* lg = gg->CreateLocalGenerator();
- lg->GetMakefile()->SetHomeOutputDirectory(targetDirectory);
- lg->GetMakefile()->SetStartOutputDirectory(targetDirectory);
- lg->GetMakefile()->SetHomeDirectory(targetDirectory);
- lg->GetMakefile()->SetStartDirectory(targetDirectory);
- gg->SetCurrentLocalGenerator(lg);
-
- return gg;
-}
-
-
-bool cmQtAutomoc::ReadAutomocInfoFile(cmMakefile* makefile,
- const char* targetDirectory,
- const char *config)
-{
- std::string filename(cmSystemTools::CollapseFullPath(targetDirectory));
- cmSystemTools::ConvertToUnixSlashes(filename);
- filename += "/AutomocInfo.cmake";
-
- if (!makefile->ReadListFile(0, filename.c_str()))
- {
- cmSystemTools::Error("Error processing file: ", filename.c_str());
- return false;
- }
-
- this->QtMajorVersion = makefile->GetSafeDefinition("AM_QT_VERSION_MAJOR");
- if (this->QtMajorVersion == "")
- {
- this->QtMajorVersion = makefile->GetSafeDefinition(
- "AM_Qt5Core_VERSION_MAJOR");
- }
- this->Sources = makefile->GetSafeDefinition("AM_SOURCES");
- this->Headers = makefile->GetSafeDefinition("AM_HEADERS");
- this->IncludeProjectDirsBefore = makefile->IsOn(
- "AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE");
- this->Srcdir = makefile->GetSafeDefinition("AM_CMAKE_CURRENT_SOURCE_DIR");
- this->Builddir = makefile->GetSafeDefinition("AM_CMAKE_CURRENT_BINARY_DIR");
- this->MocExecutable = makefile->GetSafeDefinition("AM_QT_MOC_EXECUTABLE");
- std::string compileDefsPropOrig = "AM_MOC_COMPILE_DEFINITIONS";
- std::string compileDefsProp = compileDefsPropOrig;
- if(config)
- {
- compileDefsProp += "_";
- compileDefsProp += config;
- }
- const char *compileDefs = makefile->GetDefinition(compileDefsProp.c_str());
- this->MocCompileDefinitionsStr = compileDefs ? compileDefs
- : makefile->GetSafeDefinition(compileDefsPropOrig.c_str());
- std::string includesPropOrig = "AM_MOC_INCLUDES";
- std::string includesProp = includesPropOrig;
- if(config)
- {
- includesProp += "_";
- includesProp += config;
- }
- const char *includes = makefile->GetDefinition(includesProp.c_str());
- this->MocIncludesStr = includes ? includes
- : makefile->GetSafeDefinition(includesPropOrig.c_str());
- this->MocOptionsStr = makefile->GetSafeDefinition("AM_MOC_OPTIONS");
- this->ProjectBinaryDir = makefile->GetSafeDefinition("AM_CMAKE_BINARY_DIR");
- this->ProjectSourceDir = makefile->GetSafeDefinition("AM_CMAKE_SOURCE_DIR");
- this->TargetName = makefile->GetSafeDefinition("AM_TARGET_NAME");
-
- this->CurrentCompileSettingsStr = this->MakeCompileSettingsString(makefile);
-
- this->RelaxedMode = makefile->IsOn("AM_RELAXED_MODE");
-
- return true;
-}
-
-
-std::string cmQtAutomoc::MakeCompileSettingsString(cmMakefile* makefile)
-{
- std::string s;
- s += makefile->GetSafeDefinition("AM_MOC_COMPILE_DEFINITIONS");
- s += " ~~~ ";
- s += makefile->GetSafeDefinition("AM_MOC_INCLUDES");
- s += " ~~~ ";
- s += makefile->GetSafeDefinition("AM_MOC_OPTIONS");
- s += " ~~~ ";
- s += makefile->IsOn("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE") ? "TRUE"
- : "FALSE";
- s += " ~~~ ";
-
- return s;
-}
-
-
-bool cmQtAutomoc::ReadOldMocDefinitionsFile(cmMakefile* makefile,
- const char* targetDirectory)
-{
- std::string filename(cmSystemTools::CollapseFullPath(targetDirectory));
- cmSystemTools::ConvertToUnixSlashes(filename);
- filename += "/AutomocOldMocDefinitions.cmake";
-
- if (makefile->ReadListFile(0, filename.c_str()))
- {
- this->OldCompileSettingsStr =
- makefile->GetSafeDefinition("AM_OLD_COMPILE_SETTINGS");
- }
- return true;
-}
-
-
-void cmQtAutomoc::WriteOldMocDefinitionsFile(const char* targetDirectory)
-{
- std::string filename(cmSystemTools::CollapseFullPath(targetDirectory));
- cmSystemTools::ConvertToUnixSlashes(filename);
- filename += "/AutomocOldMocDefinitions.cmake";
-
- std::fstream outfile;
- outfile.open(filename.c_str(),
- std::ios::out | std::ios::trunc);
- outfile << "set(AM_OLD_COMPILE_SETTINGS "
- << cmLocalGenerator::EscapeForCMake(
- this->CurrentCompileSettingsStr.c_str()) << ")\n";
-
- outfile.close();
-}
-
-
-void cmQtAutomoc::Init()
-{
- this->OutMocCppFilename = this->Builddir;
- this->OutMocCppFilename += this->TargetName;
- this->OutMocCppFilename += ".cpp";
-
- std::vector<std::string> cdefList;
- cmSystemTools::ExpandListArgument(this->MocCompileDefinitionsStr, cdefList);
- for(std::vector<std::string>::const_iterator it = cdefList.begin();
- it != cdefList.end();
- ++it)
- {
- this->MocDefinitions.push_back("-D" + (*it));
- }
-
- cmSystemTools::ExpandListArgument(this->MocOptionsStr, this->MocOptions);
-
- std::vector<std::string> incPaths;
- cmSystemTools::ExpandListArgument(this->MocIncludesStr, incPaths);
-
- std::set<std::string> frameworkPaths;
- for(std::vector<std::string>::const_iterator it = incPaths.begin();
- it != incPaths.end();
- ++it)
- {
- const std::string &path = *it;
- this->MocIncludes.push_back("-I" + path);
- if (this->EndsWith(path, ".framework/Headers"))
- {
- // Go up twice to get to the framework root
- std::vector<std::string> pathComponents;
- cmsys::SystemTools::SplitPath(path.c_str(), pathComponents);
- std::string frameworkPath =cmsys::SystemTools::JoinPath(
- pathComponents.begin(), pathComponents.end() - 2);
- frameworkPaths.insert(frameworkPath);
- }
- }
-
- for (std::set<std::string>::const_iterator it = frameworkPaths.begin();
- it != frameworkPaths.end(); ++it)
- {
- this->MocIncludes.push_back("-F");
- this->MocIncludes.push_back(*it);
- }
-
-
- if (this->IncludeProjectDirsBefore)
- {
- const std::string &binDir = "-I" + this->ProjectBinaryDir;
-
- const std::string srcDir = "-I" + this->ProjectSourceDir;
-
- std::list<std::string> sortedMocIncludes;
- std::list<std::string>::iterator it = this->MocIncludes.begin();
- while (it != this->MocIncludes.end())
- {
- if (this->StartsWith(*it, binDir))
- {
- sortedMocIncludes.push_back(*it);
- it = this->MocIncludes.erase(it);
- }
- else
- {
- ++it;
- }
- }
- it = this->MocIncludes.begin();
- while (it != this->MocIncludes.end())
- {
- if (this->StartsWith(*it, srcDir))
- {
- sortedMocIncludes.push_back(*it);
- it = this->MocIncludes.erase(it);
- }
- else
- {
- ++it;
- }
- }
- sortedMocIncludes.insert(sortedMocIncludes.end(),
- this->MocIncludes.begin(), this->MocIncludes.end());
- this->MocIncludes = sortedMocIncludes;
- }
-
-}
-
-
-bool cmQtAutomoc::RunAutomoc(cmMakefile* makefile)
-{
- if (!cmsys::SystemTools::FileExists(this->OutMocCppFilename.c_str())
- || (this->OldCompileSettingsStr != this->CurrentCompileSettingsStr))
- {
- this->GenerateAll = true;
- }
-
- // the program goes through all .cpp files to see which moc files are
- // included. It is not really interesting how the moc file is named, but
- // what file the moc is created from. Once a moc is included the same moc
- // may not be included in the _automoc.cpp file anymore. OTOH if there's a
- // header containing Q_OBJECT where no corresponding moc file is included
- // anywhere a moc_<filename>.cpp file is created and included in
- // the _automoc.cpp file.
-
- // key = moc source filepath, value = moc output filepath
- std::map<std::string, std::string> includedMocs;
- // collect all headers which may need to be mocced
- std::set<std::string> headerFiles;
-
- std::vector<std::string> sourceFiles;
- cmSystemTools::ExpandListArgument(this->Sources, sourceFiles);
-
- const std::vector<std::string>& headerExtensions =
- makefile->GetHeaderExtensions();
-
- for (std::vector<std::string>::const_iterator it = sourceFiles.begin();
- it != sourceFiles.end();
- ++it)
- {
- const std::string &absFilename = *it;
- if (this->Verbose)
- {
- std::cout << "AUTOMOC: Checking " << absFilename << std::endl;
- }
- if (this->RelaxedMode)
- {
- this->ParseCppFile(absFilename, headerExtensions, includedMocs);
- }
- else
- {
- this->StrictParseCppFile(absFilename, headerExtensions, includedMocs);
- }
- this->SearchHeadersForCppFile(absFilename, headerExtensions, headerFiles);
- }
-
- std::vector<std::string> headerFilesVec;
- cmSystemTools::ExpandListArgument(this->Headers, headerFilesVec);
- for (std::vector<std::string>::const_iterator it = headerFilesVec.begin();
- it != headerFilesVec.end();
- ++it)
- {
- headerFiles.insert(*it);
- }
-
- // key = moc source filepath, value = moc output filename
- std::map<std::string, std::string> notIncludedMocs;
- this->ParseHeaders(headerFiles, includedMocs, notIncludedMocs);
-
- // run moc on all the moc's that are #included in source files
- for(std::map<std::string, std::string>::const_iterator
- it = includedMocs.begin();
- it != includedMocs.end();
- ++it)
- {
- this->GenerateMoc(it->first, it->second);
- }
-
- cmsys_ios::stringstream outStream;
- outStream << "/* This file is autogenerated, do not edit*/\n";
-
- bool automocCppChanged = false;
- if (notIncludedMocs.empty())
- {
- outStream << "enum some_compilers { need_more_than_nothing };\n";
- }
- else
- {
- // run moc on the remaining headers and include them in
- // the _automoc.cpp file
- for(std::map<std::string, std::string>::const_iterator
- it = notIncludedMocs.begin();
- it != notIncludedMocs.end();
- ++it)
- {
- bool mocSuccess = this->GenerateMoc(it->first, it->second);
- if (mocSuccess)
- {
- automocCppChanged = true;
- }
- outStream << "#include \"" << it->second << "\"\n";
- }
- }
-
- if (this->RunMocFailed)
- {
- std::cerr << "moc failed..."<< std::endl;
- return false;
- }
- outStream.flush();
- std::string automocSource = outStream.str();
- if (!automocCppChanged)
- {
- // compare contents of the _automoc.cpp file
- const std::string oldContents = this->ReadAll(this->OutMocCppFilename);
- if (oldContents == automocSource)
- {
- // nothing changed: don't touch the _automoc.cpp file
- return true;
- }
- }
-
- // source file that includes all remaining moc files (_automoc.cpp file)
- std::fstream outfile;
- outfile.open(this->OutMocCppFilename.c_str(),
- std::ios::out | std::ios::trunc);
- outfile << automocSource;
- outfile.close();
-
- return true;
-}
-
-
-void cmQtAutomoc::ParseCppFile(const std::string& absFilename,
- const std::vector<std::string>& headerExtensions,
- std::map<std::string, std::string>& includedMocs)
-{
- cmsys::RegularExpression mocIncludeRegExp(
- "[\n][ \t]*#[ \t]*include[ \t]+"
- "[\"<](([^ \">]+/)?moc_[^ \">/]+\\.cpp|[^ \">]+\\.moc)[\">]");
-
- const std::string contentsString = this->ReadAll(absFilename);
- if (contentsString.empty())
- {
- std::cerr << "AUTOMOC: warning: " << absFilename << ": file is empty\n"
- << std::endl;
- return;
- }
- const std::string absPath = cmsys::SystemTools::GetFilenamePath(
- cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/';
- const std::string scannedFileBasename = cmsys::SystemTools::
- GetFilenameWithoutLastExtension(absFilename);
- const bool cppContainsQ_OBJECT = containsQ_OBJECT(contentsString);
- bool dotMocIncluded = false;
- bool mocUnderscoreIncluded = false;
- std::string ownMocUnderscoreFile;
- std::string ownDotMocFile;
- std::string ownMocHeaderFile;
-
- std::string::size_type matchOffset = 0;
- // first a simple string check for "moc" is *much* faster than the regexp,
- // and if the string search already fails, we don't have to try the
- // expensive regexp
- if ((strstr(contentsString.c_str(), "moc") != NULL)
- && (mocIncludeRegExp.find(contentsString)))
- {
- // for every moc include in the file
- do
- {
- const std::string currentMoc = mocIncludeRegExp.match(1);
- //std::cout << "found moc include: " << currentMoc << std::endl;
-
- std::string basename = cmsys::SystemTools::
- GetFilenameWithoutLastExtension(currentMoc);
- const bool moc_style = this->StartsWith(basename, "moc_");
-
- // If the moc include is of the moc_foo.cpp style we expect
- // the Q_OBJECT class declaration in a header file.
- // If the moc include is of the foo.moc style we need to look for
- // a Q_OBJECT macro in the current source file, if it contains the
- // macro we generate the moc file from the source file.
- // Q_OBJECT
- if (moc_style)
- {
- // basename should be the part of the moc filename used for
- // finding the correct header, so we need to remove the moc_ part
- basename = basename.substr(4);
- std::string mocSubDir = extractSubDir(absPath, currentMoc);
- std::string headerToMoc = findMatchingHeader(
- absPath, mocSubDir, basename, headerExtensions);
-
- if (!headerToMoc.empty())
- {
- includedMocs[headerToMoc] = currentMoc;
- if (basename == scannedFileBasename)
- {
- mocUnderscoreIncluded = true;
- ownMocUnderscoreFile = currentMoc;
- ownMocHeaderFile = headerToMoc;
- }
- }
- else
- {
- std::cerr << "AUTOMOC: error: " << absFilename << " The file "
- << "includes the moc file \"" << currentMoc << "\", "
- << "but could not find header \"" << basename
- << '{' << this->Join(headerExtensions, ',') << "}\" ";
- if (mocSubDir.empty())
- {
- std::cerr << "in " << absPath << "\n" << std::endl;
- }
- else
- {
- std::cerr << "neither in " << absPath
- << " nor in " << mocSubDir << "\n" << std::endl;
- }
-
- ::exit(EXIT_FAILURE);
- }
- }
- else
- {
- std::string fileToMoc = absFilename;
- if ((basename != scannedFileBasename) || (cppContainsQ_OBJECT==false))
- {
- std::string mocSubDir = extractSubDir(absPath, currentMoc);
- std::string headerToMoc = findMatchingHeader(
- absPath, mocSubDir, basename, headerExtensions);
- if (!headerToMoc.empty())
- {
- // this is for KDE4 compatibility:
- fileToMoc = headerToMoc;
- if ((cppContainsQ_OBJECT==false) &&(basename==scannedFileBasename))
- {
- std::cerr << "AUTOMOC: warning: " << absFilename << ": The file "
- "includes the moc file \"" << currentMoc <<
- "\", but does not contain a Q_OBJECT macro. "
- "Running moc on "
- << "\"" << headerToMoc << "\" ! Include \"moc_"
- << basename << ".cpp\" for a compatiblity with "
- "strict mode (see CMAKE_AUTOMOC_RELAXED_MODE).\n"
- << std::endl;
- }
- else
- {
- std::cerr << "AUTOMOC: warning: " << absFilename << ": The file "
- "includes the moc file \"" << currentMoc <<
- "\" instead of \"moc_" << basename << ".cpp\". "
- "Running moc on "
- << "\"" << headerToMoc << "\" ! Include \"moc_"
- << basename << ".cpp\" for compatiblity with "
- "strict mode (see CMAKE_AUTOMOC_RELAXED_MODE).\n"
- << std::endl;
- }
- }
- else
- {
- std::cerr <<"AUTOMOC: error: " << absFilename << ": The file "
- "includes the moc file \"" << currentMoc <<
- "\", which seems to be the moc file from a different "
- "source file. CMake also could not find a matching "
- "header.\n" << std::endl;
- ::exit(EXIT_FAILURE);
- }
- }
- else
- {
- dotMocIncluded = true;
- ownDotMocFile = currentMoc;
- }
- includedMocs[fileToMoc] = currentMoc;
- }
- matchOffset += mocIncludeRegExp.end();
- } while(mocIncludeRegExp.find(contentsString.c_str() + matchOffset));
- }
-
- // In this case, check whether the scanned file itself contains a Q_OBJECT.
- // If this is the case, the moc_foo.cpp should probably be generated from
- // foo.cpp instead of foo.h, because otherwise it won't build.
- // But warn, since this is not how it is supposed to be used.
- if ((dotMocIncluded == false) && (cppContainsQ_OBJECT == true))
- {
- if (mocUnderscoreIncluded == true)
- {
- // this is for KDE4 compatibility:
- std::cerr << "AUTOMOC: warning: " << absFilename << ": The file "
- << "contains a Q_OBJECT macro, but does not include "
- << "\"" << scannedFileBasename << ".moc\", but instead "
- "includes "
- << "\"" << ownMocUnderscoreFile << "\". Running moc on "
- << "\"" << absFilename << "\" ! Better include \""
- << scannedFileBasename << ".moc\" for compatiblity with "
- "strict mode (see CMAKE_AUTOMOC_RELAXED_MODE).\n"
- << std::endl;
- includedMocs[absFilename] = ownMocUnderscoreFile;
- includedMocs.erase(ownMocHeaderFile);
- }
- else
- {
- // otherwise always error out since it will not compile:
- std::cerr << "AUTOMOC: error: " << absFilename << ": The file "
- << "contains a Q_OBJECT macro, but does not include "
- << "\"" << scannedFileBasename << ".moc\" !\n"
- << std::endl;
- ::exit(EXIT_FAILURE);
- }
- }
-
-}
-
-
-void cmQtAutomoc::StrictParseCppFile(const std::string& absFilename,
- const std::vector<std::string>& headerExtensions,
- std::map<std::string, std::string>& includedMocs)
-{
- cmsys::RegularExpression mocIncludeRegExp(
- "[\n][ \t]*#[ \t]*include[ \t]+"
- "[\"<](([^ \">]+/)?moc_[^ \">/]+\\.cpp|[^ \">]+\\.moc)[\">]");
-
- const std::string contentsString = this->ReadAll(absFilename);
- if (contentsString.empty())
- {
- std::cerr << "AUTOMOC: warning: " << absFilename << ": file is empty\n"
- << std::endl;
- return;
- }
- const std::string absPath = cmsys::SystemTools::GetFilenamePath(
- cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/';
- const std::string scannedFileBasename = cmsys::SystemTools::
- GetFilenameWithoutLastExtension(absFilename);
-
- bool dotMocIncluded = false;
-
- std::string::size_type matchOffset = 0;
- // first a simple string check for "moc" is *much* faster than the regexp,
- // and if the string search already fails, we don't have to try the
- // expensive regexp
- if ((strstr(contentsString.c_str(), "moc") != NULL)
- && (mocIncludeRegExp.find(contentsString)))
- {
- // for every moc include in the file
- do
- {
- const std::string currentMoc = mocIncludeRegExp.match(1);
-
- std::string basename = cmsys::SystemTools::
- GetFilenameWithoutLastExtension(currentMoc);
- const bool mocUnderscoreStyle = this->StartsWith(basename, "moc_");
-
- // If the moc include is of the moc_foo.cpp style we expect
- // the Q_OBJECT class declaration in a header file.
- // If the moc include is of the foo.moc style we need to look for
- // a Q_OBJECT macro in the current source file, if it contains the
- // macro we generate the moc file from the source file.
- if (mocUnderscoreStyle)
- {
- // basename should be the part of the moc filename used for
- // finding the correct header, so we need to remove the moc_ part
- basename = basename.substr(4);
- std::string mocSubDir = extractSubDir(absPath, currentMoc);
- std::string headerToMoc = findMatchingHeader(
- absPath, mocSubDir, basename, headerExtensions);
-
- if (!headerToMoc.empty())
- {
- includedMocs[headerToMoc] = currentMoc;
- }
- else
- {
- std::cerr << "AUTOMOC: error: " << absFilename << " The file "
- << "includes the moc file \"" << currentMoc << "\", "
- << "but could not find header \"" << basename
- << '{' << this->Join(headerExtensions, ',') << "}\" ";
- if (mocSubDir.empty())
- {
- std::cerr << "in " << absPath << "\n" << std::endl;
- }
- else
- {
- std::cerr << "neither in " << absPath
- << " nor in " << mocSubDir << "\n" << std::endl;
- }
-
- ::exit(EXIT_FAILURE);
- }
- }
- else
- {
- if (basename != scannedFileBasename)
- {
- std::cerr <<"AUTOMOC: error: " << absFilename << ": The file "
- "includes the moc file \"" << currentMoc <<
- "\", which seems to be the moc file from a different "
- "source file. This is not supported. "
- "Include \"" << scannedFileBasename << ".moc\" to run "
- "moc on this source file.\n" << std::endl;
- ::exit(EXIT_FAILURE);
- }
- dotMocIncluded = true;
- includedMocs[absFilename] = currentMoc;
- }
- matchOffset += mocIncludeRegExp.end();
- } while(mocIncludeRegExp.find(contentsString.c_str() + matchOffset));
- }
-
- // In this case, check whether the scanned file itself contains a Q_OBJECT.
- // If this is the case, the moc_foo.cpp should probably be generated from
- // foo.cpp instead of foo.h, because otherwise it won't build.
- // But warn, since this is not how it is supposed to be used.
- if ((dotMocIncluded == false) && (containsQ_OBJECT(contentsString)))
- {
- // otherwise always error out since it will not compile:
- std::cerr << "AUTOMOC: error: " << absFilename << ": The file "
- << "contains a Q_OBJECT macro, but does not include "
- << "\"" << scannedFileBasename << ".moc\" !\n"
- << std::endl;
- ::exit(EXIT_FAILURE);
- }
-
-}
-
-
-void cmQtAutomoc::SearchHeadersForCppFile(const std::string& absFilename,
- const std::vector<std::string>& headerExtensions,
- std::set<std::string>& absHeaders)
-{
- // search for header files and private header files we may need to moc:
- const std::string basename =
- cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename);
- const std::string absPath = cmsys::SystemTools::GetFilenamePath(
- cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/';
-
- for(std::vector<std::string>::const_iterator ext = headerExtensions.begin();
- ext != headerExtensions.end();
- ++ext)
- {
- const std::string headerName = absPath + basename + "." + (*ext);
- if (cmsys::SystemTools::FileExists(headerName.c_str()))
- {
- absHeaders.insert(headerName);
- break;
- }
- }
- for(std::vector<std::string>::const_iterator ext = headerExtensions.begin();
- ext != headerExtensions.end();
- ++ext)
- {
- const std::string privateHeaderName = absPath+basename+"_p."+(*ext);
- if (cmsys::SystemTools::FileExists(privateHeaderName.c_str()))
- {
- absHeaders.insert(privateHeaderName);
- break;
- }
- }
-
-}
-
-
-void cmQtAutomoc::ParseHeaders(const std::set<std::string>& absHeaders,
- const std::map<std::string, std::string>& includedMocs,
- std::map<std::string, std::string>& notIncludedMocs)
-{
- for(std::set<std::string>::const_iterator hIt=absHeaders.begin();
- hIt!=absHeaders.end();
- ++hIt)
- {
- const std::string& headerName = *hIt;
-
- if (includedMocs.find(headerName) == includedMocs.end())
- {
- if (this->Verbose)
- {
- std::cout << "AUTOMOC: Checking " << headerName << std::endl;
- }
-
- const std::string basename = cmsys::SystemTools::
- GetFilenameWithoutLastExtension(headerName);
-
- const std::string currentMoc = "moc_" + basename + ".cpp";
- const std::string contents = this->ReadAll(headerName);
- if (containsQ_OBJECT(contents))
- {
- //std::cout << "header contains Q_OBJECT macro";
- notIncludedMocs[headerName] = currentMoc;
- }
- }
- }
-
-}
-
-
-bool cmQtAutomoc::GenerateMoc(const std::string& sourceFile,
- const std::string& mocFileName)
-{
- const std::string mocFilePath = this->Builddir + mocFileName;
- int sourceNewerThanMoc = 0;
- bool success = cmsys::SystemTools::FileTimeCompare(sourceFile.c_str(),
- mocFilePath.c_str(),
- &sourceNewerThanMoc);
- if (this->GenerateAll || !success || sourceNewerThanMoc >= 0)
- {
- // make sure the directory for the resulting moc file exists
- std::string mocDir = mocFilePath.substr(0, mocFilePath.rfind('/'));
- if (!cmsys::SystemTools::FileExists(mocDir.c_str(), false))
- {
- cmsys::SystemTools::MakeDirectory(mocDir.c_str());
- }
-
- std::string msg = "Generating ";
- msg += mocFileName;
- cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundBlue
- |cmsysTerminal_Color_ForegroundBold,
- msg.c_str(), true, this->ColorOutput);
-
- std::vector<cmStdString> command;
- command.push_back(this->MocExecutable);
- for (std::list<std::string>::const_iterator it = this->MocIncludes.begin();
- it != this->MocIncludes.end();
- ++it)
- {
- command.push_back(*it);
- }
- for(std::list<std::string>::const_iterator it=this->MocDefinitions.begin();
- it != this->MocDefinitions.end();
- ++it)
- {
- command.push_back(*it);
- }
- for(std::vector<std::string>::const_iterator it=this->MocOptions.begin();
- it != this->MocOptions.end();
- ++it)
- {
- command.push_back(*it);
- }
-#ifdef _WIN32
- command.push_back("-DWIN32");
-#endif
- command.push_back("-o");
- command.push_back(mocFilePath);
- command.push_back(sourceFile);
-
- if (this->Verbose)
- {
- for(std::vector<cmStdString>::const_iterator cmdIt = command.begin();
- cmdIt != command.end();
- ++cmdIt)
- {
- std::cout << *cmdIt << " ";
- }
- std::cout << std::endl;
- }
-
- std::string output;
- int retVal = 0;
- bool result = cmSystemTools::RunSingleCommand(command, &output, &retVal);
- if (!result || retVal)
- {
- std::cerr << "AUTOMOC: error: process for " << mocFilePath <<" failed:\n"
- << output << std::endl;
- this->RunMocFailed = true;
- cmSystemTools::RemoveFile(mocFilePath.c_str());
- }
- return true;
- }
- return false;
-}
-
-
-std::string cmQtAutomoc::Join(const std::vector<std::string>& lst,
- char separator)
-{
- if (lst.empty())
- {
- return "";
- }
-
- std::string result;
- for (std::vector<std::string>::const_iterator it = lst.begin();
- it != lst.end();
- ++it)
- {
- result += "." + (*it) + separator;
- }
- result.erase(result.end() - 1);
- return result;
-}
-
-
-bool cmQtAutomoc::StartsWith(const std::string& str, const std::string& with)
-{
- return (str.substr(0, with.length()) == with);
-}
-
-
-bool cmQtAutomoc::EndsWith(const std::string& str, const std::string& with)
-{
- if (with.length() > (str.length()))
- {
- return false;
- }
- return (str.substr(str.length() - with.length(), with.length()) == with);
-}
-
-
-std::string cmQtAutomoc::ReadAll(const std::string& filename)
-{
- std::ifstream file(filename.c_str());
- cmsys_ios::stringstream stream;
- stream << file.rdbuf();
- file.close();
- return stream.str();
-}
diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutomoc.h
deleted file mode 100644
index ebeeb0eee..000000000
--- a/Source/cmQtAutomoc.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2004-2011 Kitware, Inc.
- Copyright 2011 Alexander Neundorf (neundorf@kde.org)
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-
-#ifndef cmQtAutomoc_h
-#define cmQtAutomoc_h
-
-class cmGlobalGenerator;
-class cmMakefile;
-
-class cmQtAutomoc
-{
-public:
- cmQtAutomoc();
- bool Run(const char* targetDirectory, const char *config);
-
- bool InitializeMocSourceFile(cmTarget* target);
- void SetupAutomocTarget(cmTarget* target);
-
-private:
- cmGlobalGenerator* CreateGlobalGenerator(cmake* cm,
- const char* targetDirectory);
-
- bool ReadAutomocInfoFile(cmMakefile* makefile,
- const char* targetDirectory,
- const char *config);
- bool ReadOldMocDefinitionsFile(cmMakefile* makefile,
- const char* targetDirectory);
- void WriteOldMocDefinitionsFile(const char* targetDirectory);
-
- std::string MakeCompileSettingsString(cmMakefile* makefile);
-
- bool RunAutomoc(cmMakefile* makefile);
- bool GenerateMoc(const std::string& sourceFile,
- const std::string& mocFileName);
- void ParseCppFile(const std::string& absFilename,
- const std::vector<std::string>& headerExtensions,
- std::map<std::string, std::string>& includedMocs);
- void StrictParseCppFile(const std::string& absFilename,
- const std::vector<std::string>& headerExtensions,
- std::map<std::string, std::string>& includedMocs);
- void SearchHeadersForCppFile(const std::string& absFilename,
- const std::vector<std::string>& headerExtensions,
- std::set<std::string>& absHeaders);
-
- void ParseHeaders(const std::set<std::string>& absHeaders,
- const std::map<std::string, std::string>& includedMocs,
- std::map<std::string, std::string>& notIncludedMocs);
-
- void Init();
-
- std::string Join(const std::vector<std::string>& lst, char separator);
- bool EndsWith(const std::string& str, const std::string& with);
- bool StartsWith(const std::string& str, const std::string& with);
- std::string ReadAll(const std::string& filename);
-
- std::string QtMajorVersion;
- std::string Sources;
- std::string Headers;
- bool IncludeProjectDirsBefore;
- std::string Srcdir;
- std::string Builddir;
- std::string MocExecutable;
- std::string MocCompileDefinitionsStr;
- std::string MocIncludesStr;
- std::string MocOptionsStr;
- std::string ProjectBinaryDir;
- std::string ProjectSourceDir;
- std::string TargetName;
-
- std::string CurrentCompileSettingsStr;
- std::string OldCompileSettingsStr;
-
- std::string OutMocCppFilename;
- std::list<std::string> MocIncludes;
- std::list<std::string> MocDefinitions;
- std::vector<std::string> MocOptions;
-
- bool Verbose;
- bool ColorOutput;
- bool RunMocFailed;
- bool GenerateAll;
- bool RelaxedMode;
-
-};
-
-#endif
diff --git a/Source/cmRST.cxx b/Source/cmRST.cxx
new file mode 100644
index 000000000..cb61ed995
--- /dev/null
+++ b/Source/cmRST.cxx
@@ -0,0 +1,499 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2013 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmRST.h"
+
+#include "cmSystemTools.h"
+#include "cmAlgorithms.h"
+#include "cmVersion.h"
+#include <cmsys/FStream.hxx>
+#include <ctype.h>
+
+//----------------------------------------------------------------------------
+cmRST::cmRST(std::ostream& os, std::string const& docroot):
+ OS(os),
+ DocRoot(docroot),
+ IncludeDepth(0),
+ OutputLinePending(false),
+ LastLineEndedInColonColon(false),
+ Markup(MarkupNone),
+ Directive(DirectiveNone),
+ CMakeDirective("^.. (cmake:)?("
+ "command|variable"
+ ")::[ \t]+([^ \t\n]+)$"),
+ CMakeModuleDirective("^.. cmake-module::[ \t]+([^ \t\n]+)$"),
+ ParsedLiteralDirective("^.. parsed-literal::[ \t]*(.*)$"),
+ CodeBlockDirective("^.. code-block::[ \t]*(.*)$"),
+ ReplaceDirective("^.. (\\|[^|]+\\|) replace::[ \t]*(.*)$"),
+ IncludeDirective("^.. include::[ \t]+([^ \t\n]+)$"),
+ TocTreeDirective("^.. toctree::[ \t]*(.*)$"),
+ ProductionListDirective("^.. productionlist::[ \t]*(.*)$"),
+ NoteDirective("^.. note::[ \t]*(.*)$"),
+ ModuleRST("^#\\[(=*)\\[\\.rst:$"),
+ CMakeRole("(:cmake)?:("
+ "command|generator|variable|module|policy|"
+ "prop_cache|prop_dir|prop_gbl|prop_inst|prop_sf|"
+ "prop_test|prop_tgt|"
+ "manual"
+ "):`(<*([^`<]|[^` \t]<)*)([ \t]+<[^`]*>)?`"),
+ Substitution("(^|[^A-Za-z0-9_])"
+ "((\\|[^| \t\r\n]([^|\r\n]*[^| \t\r\n])?\\|)(__|_|))"
+ "([^A-Za-z0-9_]|$)")
+{
+ this->Replace["|release|"] = cmVersion::GetCMakeVersion();
+}
+
+//----------------------------------------------------------------------------
+bool cmRST::ProcessFile(std::string const& fname, bool isModule)
+{
+ cmsys::ifstream fin(fname.c_str());
+ if(fin)
+ {
+ this->DocDir = cmSystemTools::GetFilenamePath(fname);
+ if(isModule)
+ {
+ this->ProcessModule(fin);
+ }
+ else
+ {
+ this->ProcessRST(fin);
+ }
+ this->OutputLinePending = true;
+ return true;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+void cmRST::ProcessRST(std::istream& is)
+{
+ std::string line;
+ while(cmSystemTools::GetLineFromStream(is, line))
+ {
+ this->ProcessLine(line);
+ }
+ this->Reset();
+}
+
+//----------------------------------------------------------------------------
+void cmRST::ProcessModule(std::istream& is)
+{
+ std::string line;
+ std::string rst;
+ while(cmSystemTools::GetLineFromStream(is, line))
+ {
+ if(!rst.empty() && rst != "#")
+ {
+ // Bracket mode: check for end bracket
+ std::string::size_type pos = line.find(rst);
+ if(pos == line.npos)
+ {
+ this->ProcessLine(line);
+ }
+ else
+ {
+ if(line[0] != '#')
+ {
+ this->ProcessLine(line.substr(0, pos));
+ }
+ rst = "";
+ this->Reset();
+ this->OutputLinePending = true;
+ }
+ }
+ else
+ {
+ // Line mode: check for .rst start (bracket or line)
+ if(rst == "#")
+ {
+ if(line == "#")
+ {
+ this->ProcessLine("");
+ continue;
+ }
+ else if(line.substr(0, 2) == "# ")
+ {
+ this->ProcessLine(line.substr(2, line.npos));
+ continue;
+ }
+ else
+ {
+ rst = "";
+ this->Reset();
+ this->OutputLinePending = true;
+ }
+ }
+ if(line == "#.rst:")
+ {
+ rst = "#";
+ }
+ else if(this->ModuleRST.find(line))
+ {
+ rst = "]" + this->ModuleRST.match(1) + "]";
+ }
+ }
+ }
+ if(rst == "#")
+ {
+ this->Reset();
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmRST::Reset()
+{
+ if(!this->MarkupLines.empty())
+ {
+ this->UnindentLines(this->MarkupLines);
+ }
+ switch(this->Directive)
+ {
+ case DirectiveNone: break;
+ case DirectiveParsedLiteral: this->ProcessDirectiveParsedLiteral(); break;
+ case DirectiveLiteralBlock: this->ProcessDirectiveLiteralBlock(); break;
+ case DirectiveCodeBlock: this->ProcessDirectiveCodeBlock(); break;
+ case DirectiveReplace: this->ProcessDirectiveReplace(); break;
+ case DirectiveTocTree: this->ProcessDirectiveTocTree(); break;
+ }
+ this->Markup = MarkupNone;
+ this->Directive = DirectiveNone;
+ this->MarkupLines.clear();
+}
+
+//----------------------------------------------------------------------------
+void cmRST::ProcessLine(std::string const& line)
+{
+ bool lastLineEndedInColonColon = this->LastLineEndedInColonColon;
+ this->LastLineEndedInColonColon = false;
+
+ // A line starting in .. is an explicit markup start.
+ if(line == ".." || (line.size() >= 3 && line[0] == '.' &&
+ line[1] == '.' && isspace(line[2])))
+ {
+ this->Reset();
+ this->Markup = (line.find_first_not_of(" \t", 2) == line.npos ?
+ MarkupEmpty : MarkupNormal);
+ if(this->CMakeDirective.find(line))
+ {
+ // Output cmake domain directives and their content normally.
+ this->NormalLine(line);
+ }
+ else if(this->CMakeModuleDirective.find(line))
+ {
+ // Process cmake-module directive: scan .cmake file comments.
+ std::string file = this->CMakeModuleDirective.match(1);
+ if(file.empty() || !this->ProcessInclude(file, IncludeModule))
+ {
+ this->NormalLine(line);
+ }
+ }
+ else if(this->ParsedLiteralDirective.find(line))
+ {
+ // Record the literal lines to output after whole block.
+ this->Directive = DirectiveParsedLiteral;
+ this->MarkupLines.push_back(this->ParsedLiteralDirective.match(1));
+ }
+ else if(this->CodeBlockDirective.find(line))
+ {
+ // Record the literal lines to output after whole block.
+ // Ignore the language spec and record the opening line as blank.
+ this->Directive = DirectiveCodeBlock;
+ this->MarkupLines.push_back("");
+ }
+ else if(this->ReplaceDirective.find(line))
+ {
+ // Record the replace directive content.
+ this->Directive = DirectiveReplace;
+ this->ReplaceName = this->ReplaceDirective.match(1);
+ this->MarkupLines.push_back(this->ReplaceDirective.match(2));
+ }
+ else if(this->IncludeDirective.find(line))
+ {
+ // Process the include directive or output the directive and its
+ // content normally if it fails.
+ std::string file = this->IncludeDirective.match(1);
+ if(file.empty() || !this->ProcessInclude(file, IncludeNormal))
+ {
+ this->NormalLine(line);
+ }
+ }
+ else if(this->TocTreeDirective.find(line))
+ {
+ // Record the toctree entries to process after whole block.
+ this->Directive = DirectiveTocTree;
+ this->MarkupLines.push_back(this->TocTreeDirective.match(1));
+ }
+ else if(this->ProductionListDirective.find(line))
+ {
+ // Output productionlist directives and their content normally.
+ this->NormalLine(line);
+ }
+ else if(this->NoteDirective.find(line))
+ {
+ // Output note directives and their content normally.
+ this->NormalLine(line);
+ }
+ }
+ // An explicit markup start followed nothing but whitespace and a
+ // blank line does not consume any indented text following.
+ else if(this->Markup == MarkupEmpty && line.empty())
+ {
+ this->NormalLine(line);
+ }
+ // Indented lines following an explicit markup start are explicit markup.
+ else if(this->Markup && (line.empty() || isspace(line[0])))
+ {
+ this->Markup = MarkupNormal;
+ // Record markup lines if the start line was recorded.
+ if(!this->MarkupLines.empty())
+ {
+ this->MarkupLines.push_back(line);
+ }
+ }
+ // A blank line following a paragraph ending in "::" starts a literal block.
+ else if(lastLineEndedInColonColon && line.empty())
+ {
+ // Record the literal lines to output after whole block.
+ this->Markup = MarkupNormal;
+ this->Directive = DirectiveLiteralBlock;
+ this->MarkupLines.push_back("");
+ this->OutputLine("", false);
+ }
+ // Print non-markup lines.
+ else
+ {
+ this->NormalLine(line);
+ this->LastLineEndedInColonColon = (line.size() >= 2
+ && line[line.size()-2] == ':' && line[line.size()-1] == ':');
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmRST::NormalLine(std::string const& line)
+{
+ this->Reset();
+ this->OutputLine(line, true);
+}
+
+//----------------------------------------------------------------------------
+void cmRST::OutputLine(std::string const& line_in, bool inlineMarkup)
+{
+ if(this->OutputLinePending)
+ {
+ this->OS << "\n";
+ this->OutputLinePending = false;
+ }
+ if(inlineMarkup)
+ {
+ std::string line = this->ReplaceSubstitutions(line_in);
+ std::string::size_type pos = 0;
+ while(this->CMakeRole.find(line.c_str()+pos))
+ {
+ this->OS << line.substr(pos, this->CMakeRole.start());
+ std::string text = this->CMakeRole.match(3);
+ // If a command reference has no explicit target and
+ // no explicit "(...)" then add "()" to the text.
+ if(this->CMakeRole.match(2) == "command" &&
+ this->CMakeRole.match(5).empty() &&
+ text.find_first_of("()") == text.npos)
+ {
+ text += "()";
+ }
+ this->OS << "``" << text << "``";
+ pos += this->CMakeRole.end();
+ }
+ this->OS << line.substr(pos) << "\n";
+ }
+ else
+ {
+ this->OS << line_in << "\n";
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmRST::ReplaceSubstitutions(std::string const& line)
+{
+ std::string out;
+ std::string::size_type pos = 0;
+ while(this->Substitution.find(line.c_str()+pos))
+ {
+ std::string::size_type start = this->Substitution.start(2);
+ std::string::size_type end = this->Substitution.end(2);
+ std::string substitute = this->Substitution.match(3);
+ std::map<std::string, std::string>::iterator
+ replace = this->Replace.find(substitute);
+ if(replace != this->Replace.end())
+ {
+ std::pair<std::set<std::string>::iterator, bool> replaced =
+ this->Replaced.insert(substitute);
+ if(replaced.second)
+ {
+ substitute = this->ReplaceSubstitutions(replace->second);
+ this->Replaced.erase(replaced.first);
+ }
+ }
+ out += line.substr(pos, start);
+ out += substitute;
+ pos += end;
+ }
+ out += line.substr(pos);
+ return out;
+}
+
+//----------------------------------------------------------------------------
+void cmRST::OutputMarkupLines(bool inlineMarkup)
+{
+ for(std::vector<std::string>::iterator i = this->MarkupLines.begin();
+ i != this->MarkupLines.end(); ++i)
+ {
+ std::string line = *i;
+ if(!line.empty())
+ {
+ line = " " + line;
+ }
+ this->OutputLine(line, inlineMarkup);
+ }
+ this->OutputLinePending = true;
+}
+
+//----------------------------------------------------------------------------
+bool cmRST::ProcessInclude(std::string file, IncludeType type)
+{
+ bool found = false;
+ if(this->IncludeDepth < 10)
+ {
+ cmRST r(this->OS, this->DocRoot);
+ r.IncludeDepth = this->IncludeDepth + 1;
+ r.OutputLinePending = this->OutputLinePending;
+ if(type != IncludeTocTree)
+ {
+ r.Replace = this->Replace;
+ }
+ if(file[0] == '/')
+ {
+ file = this->DocRoot + file;
+ }
+ else
+ {
+ file = this->DocDir + "/" + file;
+ }
+ found = r.ProcessFile(file, type == IncludeModule);
+ if(type != IncludeTocTree)
+ {
+ this->Replace = r.Replace;
+ }
+ this->OutputLinePending = r.OutputLinePending;
+ }
+ return found;
+}
+
+//----------------------------------------------------------------------------
+void cmRST::ProcessDirectiveParsedLiteral()
+{
+ this->OutputMarkupLines(true);
+}
+
+//----------------------------------------------------------------------------
+void cmRST::ProcessDirectiveLiteralBlock()
+{
+ this->OutputMarkupLines(false);
+}
+
+//----------------------------------------------------------------------------
+void cmRST::ProcessDirectiveCodeBlock()
+{
+ this->OutputMarkupLines(false);
+}
+
+//----------------------------------------------------------------------------
+void cmRST::ProcessDirectiveReplace()
+{
+ // Record markup lines as replacement text.
+ std::string& replacement = this->Replace[this->ReplaceName];
+ replacement += cmJoin(this->MarkupLines, " ");
+ this->ReplaceName = "";
+}
+
+//----------------------------------------------------------------------------
+void cmRST::ProcessDirectiveTocTree()
+{
+ // Process documents referenced by toctree directive.
+ for(std::vector<std::string>::iterator i = this->MarkupLines.begin();
+ i != this->MarkupLines.end(); ++i)
+ {
+ if(!i->empty() && i->find_first_of(":") == i->npos)
+ {
+ this->ProcessInclude(*i + ".rst", IncludeTocTree);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmRST::UnindentLines(std::vector<std::string>& lines)
+{
+ // Remove the common indentation from the second and later lines.
+ std::string indentText;
+ std::string::size_type indentEnd = 0;
+ bool first = true;
+ for(size_t i = 1; i < lines.size(); ++i)
+ {
+ std::string const& line = lines[i];
+
+ // Do not consider empty lines.
+ if(line.empty())
+ {
+ continue;
+ }
+
+ // Record indentation on first non-empty line.
+ if(first)
+ {
+ first = false;
+ indentEnd = line.find_first_not_of(" \t");
+ indentText = line.substr(0, indentEnd);
+ continue;
+ }
+
+ // Truncate indentation to match that on this line.
+ indentEnd = std::min(indentEnd, line.size());
+ for(std::string::size_type j = 0; j != indentEnd; ++j)
+ {
+ if(line[j] != indentText[j])
+ {
+ indentEnd = j;
+ break;
+ }
+ }
+ }
+
+ // Update second and later lines.
+ for(size_t i = 1; i < lines.size(); ++i)
+ {
+ std::string& line = lines[i];
+ if(!line.empty())
+ {
+ line = line.substr(indentEnd);
+ }
+ }
+
+ std::vector<std::string>::const_iterator it = lines.begin();
+ size_t leadingEmpty = std::distance(it, cmFindNot(lines, std::string()));
+
+ std::vector<std::string>::const_reverse_iterator rit = lines.rbegin();
+ size_t trailingEmpty = std::distance(rit,
+ cmFindNot(cmReverseRange(lines), std::string()));
+
+ std::vector<std::string>::iterator contentEnd
+ = cmRotate(lines.begin(),
+ lines.begin() + leadingEmpty,
+ lines.end() - trailingEmpty);
+ lines.erase(contentEnd, lines.end());
+}
diff --git a/Source/cmRST.h b/Source/cmRST.h
new file mode 100644
index 000000000..b9b236642
--- /dev/null
+++ b/Source/cmRST.h
@@ -0,0 +1,100 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2013 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef _cmRST_h
+#define _cmRST_h
+
+#include "cmStandardIncludes.h"
+
+#include <cmsys/RegularExpression.hxx>
+
+/** \class cmRST
+ * \brief Perform basic .rst processing for command-line help
+ *
+ * This class implements a subset of reStructuredText and Sphinx
+ * document processing. It is used to print command-line help.
+ *
+ * If you modify the capabilities of this class, be sure to update
+ * the Help/manual/cmake-developer.7.rst documentation and to update
+ * the Tests/CMakeLib/testRST.(rst|expect) test input and output.
+ */
+class cmRST
+{
+public:
+ cmRST(std::ostream& os, std::string const& docroot);
+ bool ProcessFile(std::string const& fname, bool isModule = false);
+private:
+ enum IncludeType
+ {
+ IncludeNormal,
+ IncludeModule,
+ IncludeTocTree
+ };
+ enum MarkupType
+ {
+ MarkupNone,
+ MarkupNormal,
+ MarkupEmpty
+ };
+ enum DirectiveType
+ {
+ DirectiveNone,
+ DirectiveParsedLiteral,
+ DirectiveLiteralBlock,
+ DirectiveCodeBlock,
+ DirectiveReplace,
+ DirectiveTocTree
+ };
+
+ void ProcessRST(std::istream& is);
+ void ProcessModule(std::istream& is);
+ void Reset();
+ void ProcessLine(std::string const& line);
+ void NormalLine(std::string const& line);
+ void OutputLine(std::string const& line, bool inlineMarkup);
+ std::string ReplaceSubstitutions(std::string const& line);
+ void OutputMarkupLines(bool inlineMarkup);
+ bool ProcessInclude(std::string file, IncludeType type);
+ void ProcessDirectiveParsedLiteral();
+ void ProcessDirectiveLiteralBlock();
+ void ProcessDirectiveCodeBlock();
+ void ProcessDirectiveReplace();
+ void ProcessDirectiveTocTree();
+ static void UnindentLines(std::vector<std::string>& lines);
+
+ std::ostream& OS;
+ std::string DocRoot;
+ int IncludeDepth;
+ bool OutputLinePending;
+ bool LastLineEndedInColonColon;
+ MarkupType Markup;
+ DirectiveType Directive;
+ cmsys::RegularExpression CMakeDirective;
+ cmsys::RegularExpression CMakeModuleDirective;
+ cmsys::RegularExpression ParsedLiteralDirective;
+ cmsys::RegularExpression CodeBlockDirective;
+ cmsys::RegularExpression ReplaceDirective;
+ cmsys::RegularExpression IncludeDirective;
+ cmsys::RegularExpression TocTreeDirective;
+ cmsys::RegularExpression ProductionListDirective;
+ cmsys::RegularExpression NoteDirective;
+ cmsys::RegularExpression ModuleRST;
+ cmsys::RegularExpression CMakeRole;
+ cmsys::RegularExpression Substitution;
+
+ std::vector<std::string> MarkupLines;
+ std::string DocDir;
+ std::map<std::string, std::string> Replace;
+ std::set<std::string> Replaced;
+ std::string ReplaceName;
+};
+
+#endif
diff --git a/Source/cmRemoveCommand.cxx b/Source/cmRemoveCommand.cxx
index bcb856438..bad38be4a 100644
--- a/Source/cmRemoveCommand.cxx
+++ b/Source/cmRemoveCommand.cxx
@@ -39,10 +39,7 @@ bool cmRemoveCommand
// check for REMOVE(VAR v1 v2 ... vn)
std::vector<std::string> argsExpanded;
std::vector<std::string> temp;
- for(unsigned int j = 1; j < args.size(); ++j)
- {
- temp.push_back(args[j]);
- }
+ temp.insert(temp.end(), args.begin() + 1, args.end());
cmSystemTools::ExpandList(temp, argsExpanded);
// now create the new value
@@ -60,7 +57,7 @@ bool cmRemoveCommand
}
if (!found)
{
- if (value.size())
+ if (!value.empty())
{
value += ";";
}
diff --git a/Source/cmRemoveCommand.h b/Source/cmRemoveCommand.h
index 5aedc26e5..410b3705a 100644
--- a/Source/cmRemoveCommand.h
+++ b/Source/cmRemoveCommand.h
@@ -45,33 +45,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const {return "remove";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Deprecated. Use the list(REMOVE_ITEM ) command instead.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " remove(VAR VALUE VALUE ...)\n"
- "Removes VALUE from the variable VAR. "
- "This is typically used to remove entries from a vector "
- "(e.g. semicolon separated list). VALUE is expanded.";
- }
-
- /** This command is kept for compatibility with older CMake versions. */
- virtual bool IsDiscouraged() const
- {
- return true;
- }
+ virtual std::string GetName() const {return "remove";}
cmTypeMacro(cmRemoveCommand, cmCommand);
};
diff --git a/Source/cmRemoveDefinitionsCommand.h b/Source/cmRemoveDefinitionsCommand.h
index 18f617124..cac94bef2 100644
--- a/Source/cmRemoveDefinitionsCommand.h
+++ b/Source/cmRemoveDefinitionsCommand.h
@@ -42,26 +42,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const {return "remove_definitions";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Removes -D define flags added by add_definitions.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " remove_definitions(-DFOO -DBAR ...)\n"
- "Removes flags (added by add_definitions) from the compiler command "
- "line for sources in the current directory and below.";
- }
+ virtual std::string GetName() const {return "remove_definitions";}
cmTypeMacro(cmRemoveDefinitionsCommand, cmCommand);
};
diff --git a/Source/cmReturnCommand.h b/Source/cmReturnCommand.h
index a6e87eff3..4ff81effa 100644
--- a/Source/cmReturnCommand.h
+++ b/Source/cmReturnCommand.h
@@ -45,33 +45,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const {return "return";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Return from a file, directory or function.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " return()\n"
- "Returns from a file, directory or function. When this command is "
- "encountered in an included file (via include() or find_package()), "
- "it causes processing of the current file to stop and control is "
- "returned to the including file. If it is encountered in a file which "
- "is not included by another file, e.g. a CMakeLists.txt, control is "
- "returned to the parent directory if there is one. "
- "If return is called in a function, control is returned to the caller "
- "of the function. Note that a macro "
- "is not a function and does not handle return like a function does.";
- }
+ virtual std::string GetName() const {return "return";}
cmTypeMacro(cmReturnCommand, cmCommand);
};
diff --git a/Source/cmScriptGenerator.cxx b/Source/cmScriptGenerator.cxx
index cabe98a51..e44b2364a 100644
--- a/Source/cmScriptGenerator.cxx
+++ b/Source/cmScriptGenerator.cxx
@@ -15,11 +15,11 @@
//----------------------------------------------------------------------------
cmScriptGenerator
-::cmScriptGenerator(const char* config_var,
+::cmScriptGenerator(const std::string& config_var,
std::vector<std::string> const& configurations):
RuntimeConfigVariable(config_var),
Configurations(configurations),
- ConfigurationName(0),
+ ConfigurationName(""),
ConfigurationTypes(0),
ActionsPerConfig(false)
{
@@ -34,21 +34,21 @@ cmScriptGenerator
//----------------------------------------------------------------------------
void
cmScriptGenerator
-::Generate(std::ostream& os, const char* config,
+::Generate(std::ostream& os, const std::string& config,
std::vector<std::string> const& configurationTypes)
{
this->ConfigurationName = config;
this->ConfigurationTypes = &configurationTypes;
this->GenerateScript(os);
- this->ConfigurationName = 0;
+ this->ConfigurationName = "";
this->ConfigurationTypes = 0;
}
//----------------------------------------------------------------------------
-static void cmScriptGeneratorEncodeConfig(const char* config,
+static void cmScriptGeneratorEncodeConfig(const std::string& config,
std::string& result)
{
- for(const char* c = config; *c; ++c)
+ for(const char* c = config.c_str(); *c; ++c)
{
if(*c >= 'a' && *c <= 'z')
{
@@ -73,12 +73,12 @@ static void cmScriptGeneratorEncodeConfig(const char* config,
//----------------------------------------------------------------------------
std::string
-cmScriptGenerator::CreateConfigTest(const char* config)
+cmScriptGenerator::CreateConfigTest(const std::string& config)
{
std::string result = "\"${";
result += this->RuntimeConfigVariable;
result += "}\" MATCHES \"^(";
- if(config && *config)
+ if(!config.empty())
{
cmScriptGeneratorEncodeConfig(config, result);
}
@@ -99,7 +99,7 @@ cmScriptGenerator::CreateConfigTest(std::vector<std::string> const& configs)
{
result += sep;
sep = "|";
- cmScriptGeneratorEncodeConfig(ci->c_str(), result);
+ cmScriptGeneratorEncodeConfig(*ci, result);
}
result += ")$\"";
return result;
@@ -142,14 +142,15 @@ void cmScriptGenerator::GenerateScriptActions(std::ostream& os,
}
//----------------------------------------------------------------------------
-void cmScriptGenerator::GenerateScriptForConfig(std::ostream&, const char*,
+void cmScriptGenerator::GenerateScriptForConfig(std::ostream&,
+ const std::string&,
Indent const&)
{
// No actions for this generator.
}
//----------------------------------------------------------------------------
-bool cmScriptGenerator::GeneratesForConfig(const char* config)
+bool cmScriptGenerator::GeneratesForConfig(const std::string& config)
{
// If this is not a configuration-specific rule then we install.
if(this->Configurations.empty())
@@ -159,7 +160,7 @@ bool cmScriptGenerator::GeneratesForConfig(const char* config)
// This is a configuration-specific rule. Check if the config
// matches this rule.
- std::string config_upper = cmSystemTools::UpperCase(config?config:"");
+ std::string config_upper = cmSystemTools::UpperCase(config);
for(std::vector<std::string>::const_iterator i =
this->Configurations.begin();
i != this->Configurations.end(); ++i)
@@ -185,9 +186,9 @@ void cmScriptGenerator::GenerateScriptActionsOnce(std::ostream& os,
{
// Generate a per-configuration block.
std::string config_test = this->CreateConfigTest(this->Configurations);
- os << indent << "IF(" << config_test << ")\n";
+ os << indent << "if(" << config_test << ")\n";
this->GenerateScriptActions(os, indent.Next());
- os << indent << "ENDIF(" << config_test << ")\n";
+ os << indent << "endif(" << config_test << ")\n";
}
}
@@ -219,7 +220,7 @@ void cmScriptGenerator::GenerateScriptActionsPerConfig(std::ostream& os,
{
// Generate a per-configuration block.
std::string config_test = this->CreateConfigTest(config);
- os << indent << (first? "IF(" : "ELSEIF(") << config_test << ")\n";
+ os << indent << (first? "if(" : "elseif(") << config_test << ")\n";
this->GenerateScriptForConfig(os, config, indent.Next());
first = false;
}
@@ -228,10 +229,10 @@ void cmScriptGenerator::GenerateScriptActionsPerConfig(std::ostream& os,
{
if(this->NeedsScriptNoConfig())
{
- os << indent << "ELSE()\n";
+ os << indent << "else()\n";
this->GenerateScriptNoConfig(os, indent.Next());
}
- os << indent << "ENDIF()\n";
+ os << indent << "endif()\n";
}
}
}
diff --git a/Source/cmScriptGenerator.h b/Source/cmScriptGenerator.h
index 8b2ca335f..bc9372f7c 100644
--- a/Source/cmScriptGenerator.h
+++ b/Source/cmScriptGenerator.h
@@ -47,31 +47,28 @@ inline std::ostream& operator<<(std::ostream& os,
class cmScriptGenerator
{
public:
- cmScriptGenerator(const char* config_var,
+ cmScriptGenerator(const std::string& config_var,
std::vector<std::string> const& configurations);
virtual ~cmScriptGenerator();
- void Generate(std::ostream& os, const char* config,
+ void Generate(std::ostream& os, const std::string& config,
std::vector<std::string> const& configurationTypes);
- const std::vector<std::string>& GetConfigurations() const
- { return this->Configurations; }
-
protected:
typedef cmScriptGeneratorIndent Indent;
virtual void GenerateScript(std::ostream& os);
virtual void GenerateScriptConfigs(std::ostream& os, Indent const& indent);
virtual void GenerateScriptActions(std::ostream& os, Indent const& indent);
virtual void GenerateScriptForConfig(std::ostream& os,
- const char* config,
+ const std::string& config,
Indent const& indent);
virtual void GenerateScriptNoConfig(std::ostream&, Indent const&) {}
virtual bool NeedsScriptNoConfig() const { return false; }
// Test if this generator does something for a given configuration.
- bool GeneratesForConfig(const char*);
+ bool GeneratesForConfig(const std::string&);
- std::string CreateConfigTest(const char* config);
+ std::string CreateConfigTest(const std::string& config);
std::string CreateConfigTest(std::vector<std::string> const& configs);
std::string CreateComponentTest(const char* component);
@@ -80,7 +77,7 @@ protected:
std::vector<std::string> const Configurations;
// Information used during generation.
- const char* ConfigurationName;
+ std::string ConfigurationName;
std::vector<std::string> const* ConfigurationTypes;
// True if the subclass needs to generate an explicit rule for each
diff --git a/Source/cmSearchPath.cxx b/Source/cmSearchPath.cxx
new file mode 100644
index 000000000..c9cc81737
--- /dev/null
+++ b/Source/cmSearchPath.cxx
@@ -0,0 +1,274 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmSearchPath.h"
+#include "cmFindCommon.h"
+#include "cmAlgorithms.h"
+
+//----------------------------------------------------------------------------
+cmSearchPath::cmSearchPath(cmFindCommon* findCmd)
+: FC(findCmd)
+{
+}
+
+//----------------------------------------------------------------------------
+cmSearchPath::~cmSearchPath()
+{
+}
+
+//----------------------------------------------------------------------------
+
+void cmSearchPath::ExtractWithout(const std::set<std::string>& ignore,
+ std::vector<std::string>& outPaths,
+ bool clear) const
+{
+ if(clear)
+ {
+ outPaths.clear();
+ }
+ for(std::vector<std::string>::const_iterator p = this->Paths.begin();
+ p != this->Paths.end(); ++p)
+ {
+ if(ignore.count(*p) == 0)
+ {
+ outPaths.push_back(*p);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmSearchPath::AddPath(const std::string& path)
+{
+ this->AddPathInternal(path);
+}
+
+//----------------------------------------------------------------------------
+void cmSearchPath::AddUserPath(const std::string& path)
+{
+ assert(this->FC != NULL);
+
+ std::vector<std::string> outPaths;
+
+ // We should view the registry as the target application would view
+ // it.
+ cmSystemTools::KeyWOW64 view = cmSystemTools::KeyWOW64_32;
+ cmSystemTools::KeyWOW64 other_view = cmSystemTools::KeyWOW64_64;
+ if(this->FC->Makefile->PlatformIs64Bit())
+ {
+ view = cmSystemTools::KeyWOW64_64;
+ other_view = cmSystemTools::KeyWOW64_32;
+ }
+
+ // Expand using the view of the target application.
+ std::string expanded = path;
+ cmSystemTools::ExpandRegistryValues(expanded, view);
+ cmSystemTools::GlobDirs(expanded, outPaths);
+
+ // Executables can be either 32-bit or 64-bit, so expand using the
+ // alternative view.
+ if(expanded != path && this->FC->CMakePathName == "PROGRAM")
+ {
+ expanded = path;
+ cmSystemTools::ExpandRegistryValues(expanded, other_view);
+ cmSystemTools::GlobDirs(expanded, outPaths);
+ }
+
+ // Process them all from the current directory
+ for(std::vector<std::string>::const_iterator p = outPaths.begin();
+ p != outPaths.end(); ++p)
+ {
+ this->AddPathInternal(*p, this->FC->Makefile->GetCurrentSourceDirectory());
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmSearchPath::AddCMakePath(const std::string& variable)
+{
+ assert(this->FC != NULL);
+
+ // Get a path from a CMake variable.
+ if(const char* value = this->FC->Makefile->GetDefinition(variable))
+ {
+ std::vector<std::string> expanded;
+ cmSystemTools::ExpandListArgument(value, expanded);
+
+ for(std::vector<std::string>::const_iterator p = expanded.begin();
+ p!= expanded.end(); ++p)
+ {
+ this->AddPathInternal(*p,
+ this->FC->Makefile->GetCurrentSourceDirectory());
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmSearchPath::AddEnvPath(const std::string& variable)
+{
+ std::vector<std::string> expanded;
+ cmSystemTools::GetPath(expanded, variable.c_str());
+ for(std::vector<std::string>::const_iterator p = expanded.begin();
+ p!= expanded.end(); ++p)
+ {
+ this->AddPathInternal(*p);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmSearchPath::AddCMakePrefixPath(const std::string& variable)
+{
+ assert(this->FC != NULL);
+
+ // Get a path from a CMake variable.
+ if(const char* value = this->FC->Makefile->GetDefinition(variable))
+ {
+ std::vector<std::string> expanded;
+ cmSystemTools::ExpandListArgument(value, expanded);
+
+ this->AddPrefixPaths(expanded,
+ this->FC->Makefile->GetCurrentSourceDirectory());
+ }
+}
+
+//----------------------------------------------------------------------------
+static std::string cmSearchPathStripBin(std::string const& s)
+{
+ // If the path is a PREFIX/bin case then add its parent instead.
+ if((cmHasLiteralSuffix(s, "/bin")) ||
+ (cmHasLiteralSuffix(s, "/sbin")))
+ {
+ return cmSystemTools::GetFilenamePath(s);
+ }
+ else
+ {
+ return s;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmSearchPath::AddEnvPrefixPath(const std::string& variable, bool stripBin)
+{
+ std::vector<std::string> expanded;
+ cmSystemTools::GetPath(expanded, variable.c_str());
+ if (stripBin)
+ {
+ std::transform(expanded.begin(), expanded.end(), expanded.begin(),
+ cmSearchPathStripBin);
+ }
+ this->AddPrefixPaths(expanded);
+}
+
+//----------------------------------------------------------------------------
+void cmSearchPath::AddSuffixes(const std::vector<std::string>& suffixes)
+{
+ std::vector<std::string> inPaths;
+ inPaths.swap(this->Paths);
+ this->Paths.reserve(inPaths.size()*(suffixes.size()+1));
+
+ for(std::vector<std::string>::iterator ip = inPaths.begin();
+ ip != inPaths.end(); ++ip)
+ {
+ cmSystemTools::ConvertToUnixSlashes(*ip);
+
+ // if *i is only / then do not add a //
+ // this will get incorrectly considered a network
+ // path on windows and cause huge delays.
+ std::string p = *ip;
+ if(!p.empty() && *p.rbegin() != '/')
+ {
+ p += "/";
+ }
+
+ // Combine with all the suffixes
+ for(std::vector<std::string>::const_iterator s = suffixes.begin();
+ s != suffixes.end(); ++s)
+ {
+ this->Paths.push_back(p+*s);
+ }
+
+ // And now the original w/o any suffix
+ this->Paths.push_back(*ip);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmSearchPath::AddPrefixPaths(const std::vector<std::string>& paths,
+ const char *base)
+{
+ assert(this->FC != NULL);
+
+ // default for programs
+ std::string subdir = "bin";
+
+ if (this->FC->CMakePathName == "INCLUDE")
+ {
+ subdir = "include";
+ }
+ else if (this->FC->CMakePathName == "LIBRARY")
+ {
+ subdir = "lib";
+ }
+ else if (this->FC->CMakePathName == "FRAMEWORK")
+ {
+ subdir = ""; // ? what to do for frameworks ?
+ }
+
+ for(std::vector<std::string>::const_iterator p = paths.begin();
+ p != paths.end(); ++p)
+ {
+ std::string dir = *p;
+ if(!subdir.empty() && !dir.empty() && *dir.rbegin() != '/')
+ {
+ dir += "/";
+ }
+ if(subdir == "include" || subdir == "lib")
+ {
+ const char* arch =
+ this->FC->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE");
+ if(arch && *arch)
+ {
+ this->AddPathInternal(dir+subdir+"/"+arch, base);
+ }
+ }
+ std::string add = dir + subdir;
+ if(add != "/")
+ {
+ this->AddPathInternal(add, base);
+ }
+ if (subdir == "bin")
+ {
+ this->AddPathInternal(dir+"sbin", base);
+ }
+ if(!subdir.empty() && *p != "/")
+ {
+ this->AddPathInternal(*p, base);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmSearchPath::AddPathInternal(const std::string& path, const char *base)
+{
+ assert(this->FC != NULL);
+
+ std::string collapsed = cmSystemTools::CollapseFullPath(path, base);
+
+ if(collapsed.empty())
+ {
+ return;
+ }
+
+ // Insert the path if has not already been emitted.
+ if(this->FC->SearchPathsEmitted.insert(collapsed).second)
+ {
+ this->Paths.push_back(collapsed);
+ }
+}
diff --git a/Source/cmSearchPath.h b/Source/cmSearchPath.h
new file mode 100644
index 000000000..41c680d14
--- /dev/null
+++ b/Source/cmSearchPath.h
@@ -0,0 +1,57 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmSearchPath_h
+#define cmSearchPath_h
+
+#include "cmStandardIncludes.h"
+
+class cmFindCommon;
+
+/** \class cmSearchPath
+ * \brief Container for encapsulating a set of search paths
+ *
+ * cmSearchPath is a container that encapsulates search path construction and
+ * management
+ */
+class cmSearchPath
+{
+public:
+ // cmSearchPath must be initialized from a valid pointer. The only reason
+ // for teh default is to allow it to be easily used in stl containers.
+ // Attempting to initialize with a NULL value will fail an assertion
+ cmSearchPath(cmFindCommon* findCmd = 0);
+ ~cmSearchPath();
+
+ const std::vector<std::string>& GetPaths() const { return this->Paths; }
+
+ void ExtractWithout(const std::set<std::string>& ignore,
+ std::vector<std::string>& outPaths,
+ bool clear = false) const;
+
+ void AddPath(const std::string& path);
+ void AddUserPath(const std::string& path);
+ void AddCMakePath(const std::string& variable);
+ void AddEnvPath(const std::string& variable);
+ void AddCMakePrefixPath(const std::string& variable);
+ void AddEnvPrefixPath(const std::string& variable, bool stripBin = false);
+ void AddSuffixes(const std::vector<std::string>& suffixes);
+
+protected:
+ void AddPrefixPaths(const std::vector<std::string>& paths,
+ const char *base = 0);
+ void AddPathInternal(const std::string& path, const char *base = 0);
+
+ cmFindCommon *FC;
+ std::vector<std::string> Paths;
+};
+
+#endif
diff --git a/Source/cmSeparateArgumentsCommand.cxx b/Source/cmSeparateArgumentsCommand.cxx
index 6f620918b..8e6c31141 100644
--- a/Source/cmSeparateArgumentsCommand.cxx
+++ b/Source/cmSeparateArgumentsCommand.cxx
@@ -51,9 +51,9 @@ bool cmSeparateArgumentsCommand
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "given unknown argument " << args[i];
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
@@ -61,11 +61,11 @@ bool cmSeparateArgumentsCommand
if(mode == ModeOld)
{
// Original space-replacement version of command.
- if(const char* def = this->Makefile->GetDefinition(var.c_str()))
+ if(const char* def = this->Makefile->GetDefinition(var))
{
std::string value = def;
cmSystemTools::ReplaceString(value, " ", ";");
- this->Makefile->AddDefinition(var.c_str(), value.c_str());
+ this->Makefile->AddDefinition(var, value.c_str());
}
}
else
@@ -102,7 +102,7 @@ bool cmSeparateArgumentsCommand
value += *si;
}
}
- this->Makefile->AddDefinition(var.c_str(), value.c_str());
+ this->Makefile->AddDefinition(var, value.c_str());
}
return true;
diff --git a/Source/cmSeparateArgumentsCommand.h b/Source/cmSeparateArgumentsCommand.h
index d62baf787..a527ae7b2 100644
--- a/Source/cmSeparateArgumentsCommand.h
+++ b/Source/cmSeparateArgumentsCommand.h
@@ -45,44 +45,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const {return "separate_arguments";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return
- "Parse space-separated arguments into a semicolon-separated list.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " separate_arguments(<var> <UNIX|WINDOWS>_COMMAND \"<args>\")\n"
- "Parses a unix- or windows-style command-line string \"<args>\" and "
- "stores a semicolon-separated list of the arguments in <var>. "
- "The entire command line must be given in one \"<args>\" argument."
- "\n"
- "The UNIX_COMMAND mode separates arguments by unquoted whitespace. "
- "It recognizes both single-quote and double-quote pairs. "
- "A backslash escapes the next literal character (\\\" is \"); "
- "there are no special escapes (\\n is just n)."
- "\n"
- "The WINDOWS_COMMAND mode parses a windows command-line using the "
- "same syntax the runtime library uses to construct argv at startup. "
- "It separates arguments by whitespace that is not double-quoted. "
- "Backslashes are literal unless they precede double-quotes. "
- "See the MSDN article \"Parsing C Command-Line Arguments\" for details."
- "\n"
- " separate_arguments(VARIABLE)\n"
- "Convert the value of VARIABLE to a semi-colon separated list. "
- "All spaces are replaced with ';'. This helps with generating "
- "command lines.";
- }
+ virtual std::string GetName() const {return "separate_arguments";}
cmTypeMacro(cmSeparateArgumentsCommand, cmCommand);
};
diff --git a/Source/cmSetCommand.cxx b/Source/cmSetCommand.cxx
index 20f38be10..1d70ad6e4 100644
--- a/Source/cmSetCommand.cxx
+++ b/Source/cmSetCommand.cxx
@@ -23,7 +23,7 @@ bool cmSetCommand
// watch for ENV signatures
const char* variable = args[0].c_str(); // VAR is always first
- if (!strncmp(variable,"ENV{",4) && strlen(variable) > 5)
+ if (cmHasLiteralPrefix(variable, "ENV{") && strlen(variable) > 5)
{
// what is the variable name
char *varName = new char [strlen(variable)];
@@ -37,21 +37,21 @@ bool cmSetCommand
delete [] varName;
// will it be set to something, then set it
- if (args.size() > 1 && args[1].size())
+ if (args.size() > 1 && !args[1].empty())
{
// but only if it is different from current value
if (!currValue || strcmp(currValue,args[1].c_str()))
{
putEnvArg += args[1];
- cmSystemTools::PutEnv(putEnvArg.c_str());
+ cmSystemTools::PutEnv(putEnvArg);
}
return true;
}
- // if it will be cleared, then clear it if it isn;t already clear
+ // if it will be cleared, then clear it if it isn't already clear
if (currValue)
{
- cmSystemTools::PutEnv(putEnvArg.c_str());
+ cmSystemTools::PutEnv(putEnvArg);
}
return true;
}
@@ -59,20 +59,28 @@ bool cmSetCommand
// SET (VAR) // Removes the definition of VAR.
if (args.size() == 1)
{
- this->Makefile->RemoveDefinition(args[0].c_str());
+ this->Makefile->RemoveDefinition(variable);
+ return true;
+ }
+ // SET (VAR PARENT_SCOPE) // Removes the definition of VAR
+ // in the parent scope.
+ else if (args.size() == 2 && args[args.size()-1] == "PARENT_SCOPE")
+ {
+ this->Makefile->RaiseScope(variable, 0);
return true;
}
// here are the remaining options
// SET (VAR value )
+ // SET (VAR value PARENT_SCOPE)
// SET (VAR CACHE TYPE "doc String" [FORCE])
// SET (VAR value CACHE TYPE "doc string" [FORCE])
std::string value; // optional
bool cache = false; // optional
bool force = false; // optional
bool parentScope = false;
- cmCacheManager::CacheEntryType type
- = cmCacheManager::STRING; // required if cache
+ cmState::CacheEntryType type
+ = cmState::STRING; // required if cache
const char* docstring = 0; // required if cache
unsigned int ignoreLastArgs = 0;
@@ -100,29 +108,12 @@ bool cmSetCommand
}
// collect any values into a single semi-colon separated value list
- if(static_cast<unsigned short>(args.size()) >
- static_cast<unsigned short>(1 + ignoreLastArgs))
- {
- value = args[1];
- size_t endPos = args.size() - ignoreLastArgs;
- for(size_t i = 2; i < endPos; ++i)
- {
- value += ";";
- value += args[i];
- }
- }
+ value = cmJoin(cmMakeRange(args).advance(1).retreat(ignoreLastArgs), ";");
if (parentScope)
{
- if (value.empty())
- {
- this->Makefile->RaiseScope(variable, 0);
- }
- else
- {
- this->Makefile->RaiseScope(variable, value.c_str());
- }
- return true;
+ this->Makefile->RaiseScope(variable, value.c_str());
+ return true;
}
@@ -140,20 +131,21 @@ bool cmSetCommand
if(cache)
{
std::string::size_type cacheStart = args.size() - 3 - (force ? 1 : 0);
- type = cmCacheManager::StringToType(args[cacheStart+1].c_str());
+ type = cmState::StringToCacheEntryType(args[cacheStart+1].c_str());
docstring = args[cacheStart+2].c_str();
}
// see if this is already in the cache
- cmCacheManager::CacheIterator it =
- this->Makefile->GetCacheManager()->GetCacheIterator(variable);
- if(!it.IsAtEnd() && (it.GetType() != cmCacheManager::UNINITIALIZED))
+ cmState* state = this->Makefile->GetState();
+ const char* existingValue = state->GetCacheEntryValue(variable);
+ if(existingValue &&
+ (state->GetCacheEntryType(variable) != cmState::UNINITIALIZED))
{
// if the set is trying to CACHE the value but the value
// is already in the cache and the type is not internal
// then leave now without setting any definitions in the cache
// or the makefile
- if(cache && type != cmCacheManager::INTERNAL && !force)
+ if(cache && type != cmState::INTERNAL && !force)
{
return true;
}
diff --git a/Source/cmSetCommand.h b/Source/cmSetCommand.h
index fe1d58df6..4adc2d9f0 100644
--- a/Source/cmSetCommand.h
+++ b/Source/cmSetCommand.h
@@ -45,115 +45,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const {return "set";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Set a CMake, cache or environment variable to a given value.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " set(<variable> <value>\n"
- " [[CACHE <type> <docstring> [FORCE]] | PARENT_SCOPE])\n"
- "Within CMake sets <variable> to the value <value>. "
- "<value> is expanded before <variable> is set to it. "
- "Normally, set will set a regular CMake variable. "
- "If CACHE is present, then the <variable> is put in the cache "
- "instead, unless it is already in the cache. "
- "See section 'Variable types in CMake' below for details of "
- "regular and cache variables and their interactions. "
- "If CACHE is used, <type> and <docstring> are required. <type> is used "
- "by the CMake GUI to choose a widget with which the user sets a value. "
- "The value for <type> may be one of\n"
- " FILEPATH = File chooser dialog.\n"
- " PATH = Directory chooser dialog.\n"
- " STRING = Arbitrary string.\n"
- " BOOL = Boolean ON/OFF checkbox.\n"
- " INTERNAL = No GUI entry (used for persistent variables).\n"
- "If <type> is INTERNAL, the cache variable is marked as internal, "
- "and will not be shown to the user in tools like cmake-gui. "
- "This is intended for values that should be persisted in the cache, "
- "but which users should not normally change. INTERNAL implies FORCE."
- "\n"
- "Normally, set(...CACHE...) creates cache variables, but does not "
- "modify them. "
- "If FORCE is specified, the value of the cache variable is set, even "
- "if the variable is already in the cache. This should normally be "
- "avoided, as it will remove any changes to the cache variable's value "
- "by the user.\n"
- "If PARENT_SCOPE is present, the variable will be set in the scope "
- "above the current scope. Each new directory or function creates a new "
- "scope. This command will set the value of a variable into the parent "
- "directory or calling function (whichever is applicable to the case at "
- "hand). PARENT_SCOPE cannot be combined with CACHE.\n"
- "If <value> is not specified then the variable is removed "
- "instead of set. See also: the unset() command.\n"
- " set(<variable> <value1> ... <valueN>)\n"
- "In this case <variable> is set to a semicolon separated list of "
- "values.\n"
- "<variable> can be an environment variable such as:\n"
- " set( ENV{PATH} /home/martink )\n"
- "in which case the environment variable will be set.\n"
- "*** Variable types in CMake ***\n"
- "In CMake there are two types of variables: normal variables and cache "
- "variables. Normal variables are meant for the internal use of the "
- "script (just like variables in most programming languages); they are "
- "not persisted across CMake runs. "
- "Cache variables (unless set with INTERNAL) are mostly intended for "
- "configuration settings where the first CMake run determines a "
- "suitable default value, which the user can then override, by editing "
- "the cache with tools such as ccmake or cmake-gui. "
- "Cache variables are stored in the CMake cache file, and "
- "are persisted across CMake runs. \n"
- "Both types can exist at the same time with the same name "
- "but different values. "
- "When ${FOO} is evaluated, CMake first looks for "
- "a normal variable 'FOO' in scope and uses it if set. "
- "If and only if no normal variable exists then it falls back to the "
- "cache variable 'FOO'.\n"
- "Some examples:\n"
- "The code 'set(FOO \"x\")' sets the normal variable 'FOO'. It does not "
- "touch the cache, but it will hide any existing cache value 'FOO'.\n"
- "The code 'set(FOO \"x\" CACHE ...)' checks for 'FOO' in the cache, "
- "ignoring any normal variable of the same name. If 'FOO' is in the "
- "cache then nothing happens to either the normal variable or the cache "
- "variable. If 'FOO' is not in the cache, then it is added to the "
- "cache.\n"
- "Finally, whenever a cache variable is added or modified by a command, "
- "CMake also *removes* the normal variable of the same name from the "
- "current scope so that an immediately following evaluation of "
- "it will expose the newly cached value.\n"
- "Normally projects should avoid using normal and cache variables of "
- "the same name, as this interaction can be hard to follow. "
- "However, in some situations it can be useful. "
- "One example (used by some projects):"
- "\n"
- "A project has a subproject in its source tree. The child project has "
- "its own CMakeLists.txt, which is included from the parent "
- "CMakeLists.txt using add_subdirectory(). "
- "Now, if the parent and the child project provide the same option "
- "(for example a compiler option), the parent gets the first chance "
- "to add a user-editable option to the cache. "
- "Normally, the child would then use the same value "
- "that the parent uses. "
- "However, it may be necessary to hard-code the value for the child "
- "project's option while still allowing the user to edit the value used "
- "by the parent project. The parent project can achieve this simply by "
- "setting a normal variable with the same name as the option in a scope "
- "sufficient to hide the option's cache variable from the child "
- "completely. The parent has already set the cache variable, so the "
- "child's set(...CACHE...) will do nothing, and evaluating the option "
- "variable will use the value from the normal variable, which hides the "
- "cache variable.";
- }
+ virtual std::string GetName() const {return "set";}
cmTypeMacro(cmSetCommand, cmCommand);
};
diff --git a/Source/cmSetDirectoryPropertiesCommand.cxx b/Source/cmSetDirectoryPropertiesCommand.cxx
index 62c9b87c7..3d4b7a980 100644
--- a/Source/cmSetDirectoryPropertiesCommand.cxx
+++ b/Source/cmSetDirectoryPropertiesCommand.cxx
@@ -30,7 +30,7 @@ bool cmSetDirectoryPropertiesCommand
args.end(), errors);
if (!ret)
{
- this->SetError(errors.c_str());
+ this->SetError(errors);
}
return ret;
}
@@ -62,7 +62,7 @@ bool cmSetDirectoryPropertiesCommand
"Commands and macros cannot be set using SET_CMAKE_PROPERTIES";
return false;
}
- mf->SetProperty(prop.c_str(), value.c_str());
+ mf->SetProperty(prop, value.c_str());
}
return true;
diff --git a/Source/cmSetDirectoryPropertiesCommand.h b/Source/cmSetDirectoryPropertiesCommand.h
index 8a50c60ff..f444a1bb2 100644
--- a/Source/cmSetDirectoryPropertiesCommand.h
+++ b/Source/cmSetDirectoryPropertiesCommand.h
@@ -37,15 +37,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "set_directory_properties";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Set a property of the directory.";
- }
+ virtual std::string GetName() const { return "set_directory_properties";}
/**
* Static entry point for use by other commands
@@ -55,21 +47,6 @@ public:
std::vector<std::string>::const_iterator aitend,
std::string &errors);
- /**
- * Longer documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " set_directory_properties(PROPERTIES prop1 value1 prop2 value2)\n"
- "Set a property for the current directory and subdirectories. If the "
- "property is not found, CMake will report an error. The properties "
- "include: INCLUDE_DIRECTORIES, LINK_DIRECTORIES, "
- "INCLUDE_REGULAR_EXPRESSION, and ADDITIONAL_MAKE_CLEAN_FILES. "
- "ADDITIONAL_MAKE_CLEAN_FILES is a list of files that will be cleaned "
- "as a part of \"make clean\" stage.";
- }
-
cmTypeMacro(cmSetDirectoryPropertiesCommand, cmCommand);
};
diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx
index 42078605a..17ad475bf 100644
--- a/Source/cmSetPropertyCommand.cxx
+++ b/Source/cmSetPropertyCommand.cxx
@@ -14,7 +14,6 @@
#include "cmSetTestsPropertiesCommand.h"
#include "cmSetSourceFilesPropertiesCommand.h"
-#include "cmCacheManager.h"
//----------------------------------------------------------------------------
cmSetPropertyCommand::cmSetPropertyCommand()
@@ -61,12 +60,17 @@ bool cmSetPropertyCommand
{
scope = cmProperty::CACHE;
}
+ else if(*arg == "INSTALL")
+ {
+ scope = cmProperty::INSTALL;
+ }
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "given invalid scope " << *arg << ". "
- << "Valid scopes are GLOBAL, DIRECTORY, TARGET, SOURCE, TEST, CACHE.";
- this->SetError(e.str().c_str());
+ << "Valid scopes are GLOBAL, DIRECTORY, "
+ "TARGET, SOURCE, TEST, CACHE, INSTALL.";
+ this->SetError(e.str());
return false;
}
@@ -112,9 +116,9 @@ bool cmSetPropertyCommand
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "given invalid argument \"" << *arg << "\".";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
@@ -135,6 +139,7 @@ bool cmSetPropertyCommand
case cmProperty::SOURCE_FILE: return this->HandleSourceMode();
case cmProperty::TEST: return this->HandleTestMode();
case cmProperty::CACHE: return this->HandleCacheMode();
+ case cmProperty::INSTALL: return this->HandleInstallMode();
case cmProperty::VARIABLE:
case cmProperty::CACHED_VARIABLE:
@@ -192,23 +197,16 @@ bool cmSetPropertyCommand::HandleDirectoryMode()
std::string dir = *this->Names.begin();
if(!cmSystemTools::FileIsFullPath(dir.c_str()))
{
- dir = this->Makefile->GetCurrentDirectory();
+ dir = this->Makefile->GetCurrentSourceDirectory();
dir += "/";
dir += *this->Names.begin();
}
// The local generators are associated with collapsed paths.
- dir = cmSystemTools::CollapseFullPath(dir.c_str());
+ dir = cmSystemTools::CollapseFullPath(dir);
- // Lookup the generator.
- if(cmLocalGenerator* lg =
- (this->Makefile->GetLocalGenerator()
- ->GetGlobalGenerator()->FindLocalGenerator(dir.c_str())))
- {
- // Use the makefile for the directory found.
- mf = lg->GetMakefile();
- }
- else
+ mf = this->Makefile->GetGlobalGenerator()->FindMakefile(dir);
+ if (!mf)
{
// Could not find the directory.
this->SetError
@@ -241,15 +239,15 @@ bool cmSetPropertyCommand::HandleDirectoryMode()
//----------------------------------------------------------------------------
bool cmSetPropertyCommand::HandleTargetMode()
{
- for(std::set<cmStdString>::const_iterator ni = this->Names.begin();
+ for(std::set<std::string>::const_iterator ni = this->Names.begin();
ni != this->Names.end(); ++ni)
{
- if (this->Makefile->IsAlias(ni->c_str()))
+ if (this->Makefile->IsAlias(*ni))
{
this->SetError("can not be used on an ALIAS target.");
return false;
}
- if(cmTarget* target = this->Makefile->FindTargetToUse(ni->c_str()))
+ if(cmTarget* target = this->Makefile->FindTargetToUse(*ni))
{
// Handle the current target.
if(!this->HandleTarget(target))
@@ -259,10 +257,10 @@ bool cmSetPropertyCommand::HandleTargetMode()
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "could not find TARGET " << *ni
<< ". Perhaps it has not yet been created.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
@@ -297,11 +295,11 @@ bool cmSetPropertyCommand::HandleTarget(cmTarget* target)
//----------------------------------------------------------------------------
bool cmSetPropertyCommand::HandleSourceMode()
{
- for(std::set<cmStdString>::const_iterator ni = this->Names.begin();
+ for(std::set<std::string>::const_iterator ni = this->Names.begin();
ni != this->Names.end(); ++ni)
{
// Get the source file.
- if(cmSourceFile* sf = this->Makefile->GetOrCreateSource(ni->c_str()))
+ if(cmSourceFile* sf = this->Makefile->GetOrCreateSource(*ni))
{
if(!this->HandleSource(sf))
{
@@ -310,9 +308,9 @@ bool cmSetPropertyCommand::HandleSourceMode()
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "given SOURCE name that could not be found or created: " << *ni;
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
@@ -345,13 +343,13 @@ bool cmSetPropertyCommand::HandleSource(cmSourceFile* sf)
bool cmSetPropertyCommand::HandleTestMode()
{
// Look for tests with all names given.
- std::set<cmStdString>::iterator next;
- for(std::set<cmStdString>::iterator ni = this->Names.begin();
+ std::set<std::string>::iterator next;
+ for(std::set<std::string>::iterator ni = this->Names.begin();
ni != this->Names.end(); ni = next)
{
next = ni;
++next;
- if(cmTest* test = this->Makefile->GetTest(ni->c_str()))
+ if(cmTest* test = this->Makefile->GetTest(*ni))
{
if(this->HandleTest(test))
{
@@ -367,14 +365,14 @@ bool cmSetPropertyCommand::HandleTestMode()
// Names that are still left were not found.
if(!this->Names.empty())
{
- cmOStringStream e;
+ std::ostringstream e;
e << "given TEST names that do not exist:\n";
- for(std::set<cmStdString>::const_iterator ni = this->Names.begin();
+ for(std::set<std::string>::const_iterator ni = this->Names.begin();
ni != this->Names.end(); ++ni)
{
e << " " << *ni << "\n";
}
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
return true;
@@ -411,20 +409,20 @@ bool cmSetPropertyCommand::HandleCacheMode()
!cmSystemTools::IsOn(this->PropertyValue.c_str()) &&
!cmSystemTools::IsOff(this->PropertyValue.c_str()))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "given non-boolean value \"" << this->PropertyValue
<< "\" for CACHE property \"ADVANCED\". ";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
else if(this->PropertyName == "TYPE")
{
- if(!cmCacheManager::IsType(this->PropertyValue.c_str()))
+ if(!cmState::IsCacheEntryType(this->PropertyValue.c_str()))
{
- cmOStringStream e;
+ std::ostringstream e;
e << "given invalid CACHE entry TYPE \"" << this->PropertyValue << "\"";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
@@ -432,35 +430,35 @@ bool cmSetPropertyCommand::HandleCacheMode()
this->PropertyName != "STRINGS" &&
this->PropertyName != "VALUE")
{
- cmOStringStream e;
+ std::ostringstream e;
e << "given invalid CACHE property " << this->PropertyName << ". "
<< "Settable CACHE properties are: "
<< "ADVANCED, HELPSTRING, STRINGS, TYPE, and VALUE.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
- for(std::set<cmStdString>::const_iterator ni = this->Names.begin();
+ for(std::set<std::string>::const_iterator ni = this->Names.begin();
ni != this->Names.end(); ++ni)
{
// Get the source file.
cmMakefile* mf = this->GetMakefile();
cmake* cm = mf->GetCMakeInstance();
- cmCacheManager::CacheIterator it =
- cm->GetCacheManager()->GetCacheIterator(ni->c_str());
- if(!it.IsAtEnd())
+ const char* existingValue
+ = cm->GetState()->GetCacheEntryValue(*ni);
+ if(existingValue)
{
- if(!this->HandleCacheEntry(it))
+ if(!this->HandleCacheEntry(*ni))
{
return false;
}
}
else
{
- cmOStringStream e;
+ std::ostringstream e;
e << "could not find CACHE variable " << *ni
<< ". Perhaps it has not yet been created.";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
}
@@ -468,23 +466,76 @@ bool cmSetPropertyCommand::HandleCacheMode()
}
//----------------------------------------------------------------------------
-bool cmSetPropertyCommand::HandleCacheEntry(cmCacheManager::CacheIterator& it)
+bool cmSetPropertyCommand::HandleCacheEntry(std::string const& cacheKey)
{
// Set or append the property.
const char* name = this->PropertyName.c_str();
const char* value = this->PropertyValue.c_str();
+ cmState* state = this->Makefile->GetState();
if (this->Remove)
{
- value = 0;
+ state->RemoveCacheEntryProperty(cacheKey, name);
}
if(this->AppendMode)
{
- it.AppendProperty(name, value, this->AppendAsString);
+ state->AppendCacheEntryProperty(cacheKey, name, value,
+ this->AppendAsString);
}
else
{
- it.SetProperty(name, value);
+ state->SetCacheEntryProperty(cacheKey, name, value);
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmSetPropertyCommand::HandleInstallMode()
+{
+ cmake* cm = this->Makefile->GetCMakeInstance();
+
+ for(std::set<std::string>::const_iterator i = this->Names.begin();
+ i != this->Names.end(); ++i)
+ {
+ if(cmInstalledFile* file = cm->GetOrCreateInstalledFile(
+ this->Makefile, *i))
+ {
+ if(!this->HandleInstall(file))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ std::ostringstream e;
+ e << "given INSTALL name that could not be found or created: " << *i;
+ this->SetError(e.str());
+ return false;
+ }
}
+ return true;
+}
+//----------------------------------------------------------------------------
+bool cmSetPropertyCommand::HandleInstall(cmInstalledFile* file)
+{
+ // Set or append the property.
+ std::string const& name = this->PropertyName;
+
+ cmMakefile* mf = this->Makefile;
+
+ const char *value = this->PropertyValue.c_str();
+ if (this->Remove)
+ {
+ file->RemoveProperty(name);
+ }
+ else if(this->AppendMode)
+ {
+ file->AppendProperty(mf, name, value, this->AppendAsString);
+ }
+ else
+ {
+ file->SetProperty(mf, name, value);
+ }
return true;
}
diff --git a/Source/cmSetPropertyCommand.h b/Source/cmSetPropertyCommand.h
index 830299d46..3285e60ab 100644
--- a/Source/cmSetPropertyCommand.h
+++ b/Source/cmSetPropertyCommand.h
@@ -34,54 +34,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "set_property";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Set a named property in a given scope.";
- }
-
- /**
- * Longer documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " set_property(<GLOBAL |\n"
- " DIRECTORY [dir] |\n"
- " TARGET [target1 [target2 ...]] |\n"
- " SOURCE [src1 [src2 ...]] |\n"
- " TEST [test1 [test2 ...]] |\n"
- " CACHE [entry1 [entry2 ...]]>\n"
- " [APPEND] [APPEND_STRING]\n"
- " PROPERTY <name> [value1 [value2 ...]])\n"
- "Set one property on zero or more objects of a scope. "
- "The first argument determines the scope in which the property "
- "is set. It must be one of the following:\n"
- "GLOBAL scope is unique and does not accept a name.\n"
- "DIRECTORY scope defaults to the current directory but another "
- "directory (already processed by CMake) may be named by full or "
- "relative path.\n"
- "TARGET scope may name zero or more existing targets.\n"
- "SOURCE scope may name zero or more source files. "
- "Note that source file properties are visible only to targets "
- "added in the same directory (CMakeLists.txt).\n"
- "TEST scope may name zero or more existing tests.\n"
- "CACHE scope must name zero or more cache existing entries.\n"
- "The required PROPERTY option is immediately followed by the name "
- "of the property to set. Remaining arguments are used to "
- "compose the property value in the form of a semicolon-separated "
- "list. "
- "If the APPEND option is given the list is appended to any "
- "existing property value."
- "If the APPEND_STRING option is given the string is append to any "
- "existing property value as string, i.e. it results in a longer "
- "string and not a list of strings."
- ;
- }
+ virtual std::string GetName() const { return "set_property";}
/**
* This determines if the command is invoked when in script mode.
@@ -91,7 +44,7 @@ public:
cmTypeMacro(cmSetPropertyCommand, cmCommand);
private:
- std::set<cmStdString> Names;
+ std::set<std::string> Names;
std::string PropertyName;
std::string PropertyValue;
bool Remove;
@@ -108,7 +61,9 @@ private:
bool HandleTestMode();
bool HandleTest(cmTest* test);
bool HandleCacheMode();
- bool HandleCacheEntry(cmCacheManager::CacheIterator&);
+ bool HandleCacheEntry(std::string const&);
+ bool HandleInstallMode();
+ bool HandleInstall(cmInstalledFile* file);
};
diff --git a/Source/cmSetSourceFilesPropertiesCommand.cxx b/Source/cmSetSourceFilesPropertiesCommand.cxx
index 619dfc5a5..19c681944 100644
--- a/Source/cmSetSourceFilesPropertiesCommand.cxx
+++ b/Source/cmSetSourceFilesPropertiesCommand.cxx
@@ -51,7 +51,7 @@ bool cmSetSourceFilesPropertiesCommand
args.end(), errors);
if (!ret)
{
- this->SetError(errors.c_str());
+ this->SetError(errors);
}
return ret;
}
@@ -154,14 +154,14 @@ bool cmSetSourceFilesPropertiesCommand
{
// get the source file
cmSourceFile* sf =
- mf->GetOrCreateSource(j->c_str(), generated);
+ mf->GetOrCreateSource(*j, generated);
if(sf)
{
// now loop through all the props and set them
unsigned int k;
for (k = 0; k < propertyPairs.size(); k = k + 2)
{
- sf->SetProperty(propertyPairs[k].c_str(),propertyPairs[k+1].c_str());
+ sf->SetProperty(propertyPairs[k],propertyPairs[k+1].c_str());
}
}
}
diff --git a/Source/cmSetSourceFilesPropertiesCommand.h b/Source/cmSetSourceFilesPropertiesCommand.h
index f7009e781..5fa5a3ac7 100644
--- a/Source/cmSetSourceFilesPropertiesCommand.h
+++ b/Source/cmSetSourceFilesPropertiesCommand.h
@@ -32,32 +32,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "set_source_files_properties";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Source files can have properties that affect how they are built.";
- }
-
- /**
- * Longer documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " set_source_files_properties([file1 [file2 [...]]]\n"
- " PROPERTIES prop1 value1\n"
- " [prop2 value2 [...]])\n"
- "Set properties associated with source files using a key/value "
- "paired list. "
- "See properties documentation for those known to CMake. "
- "Unrecognized properties are ignored. "
- "Source file properties are visible only to targets "
- "added in the same directory (CMakeLists.txt).";
- }
+ virtual std::string GetName() const { return "set_source_files_properties";}
cmTypeMacro(cmSetSourceFilesPropertiesCommand, cmCommand);
diff --git a/Source/cmSetTargetPropertiesCommand.cxx b/Source/cmSetTargetPropertiesCommand.cxx
index 78ef393cc..b1c13ac96 100644
--- a/Source/cmSetTargetPropertiesCommand.cxx
+++ b/Source/cmSetTargetPropertiesCommand.cxx
@@ -10,7 +10,6 @@
See the License for more information.
============================================================================*/
#include "cmSetTargetPropertiesCommand.h"
-#include "cmLocalGenerator.h"
#include "cmGlobalGenerator.h"
// cmSetTargetPropertiesCommand
@@ -25,43 +24,28 @@ bool cmSetTargetPropertiesCommand
// first collect up the list of files
std::vector<std::string> propertyPairs;
- bool doingFiles = true;
int numFiles = 0;
std::vector<std::string>::const_iterator j;
for(j= args.begin(); j != args.end();++j)
{
if(*j == "PROPERTIES")
{
- doingFiles = false;
// now loop through the rest of the arguments, new style
++j;
- while (j != args.end())
+ if (std::distance(j, args.end()) % 2 != 0)
{
- propertyPairs.push_back(*j);
- ++j;
- if(j == args.end())
- {
- this->SetError("called with incorrect number of arguments.");
- return false;
- }
- propertyPairs.push_back(*j);
- ++j;
+ this->SetError("called with incorrect number of arguments.");
+ return false;
}
- // break out of the loop because j is already == end
+ propertyPairs.insert(propertyPairs.end(), j, args.end());
break;
}
- else if (doingFiles)
- {
- numFiles++;
- }
else
{
- this->SetError("called with illegal arguments, maybe missing "
- "a PROPERTIES specifier?");
- return false;
+ numFiles++;
}
}
- if(propertyPairs.size() == 0)
+ if(propertyPairs.empty())
{
this->SetError("called with illegal arguments, maybe missing "
"a PROPERTIES specifier?");
@@ -72,18 +56,18 @@ bool cmSetTargetPropertiesCommand
int i;
for(i = 0; i < numFiles; ++i)
{
- if (this->Makefile->IsAlias(args[i].c_str()))
+ if (this->Makefile->IsAlias(args[i]))
{
this->SetError("can not be used on an ALIAS target.");
return false;
}
bool ret = cmSetTargetPropertiesCommand::SetOneTarget
- (args[i].c_str(),propertyPairs,this->Makefile);
+ (args[i],propertyPairs,this->Makefile);
if (!ret)
{
std::string message = "Can not find target to add properties to: ";
message += args[i];
- this->SetError(message.c_str());
+ this->SetError(message);
return false;
}
}
@@ -91,7 +75,7 @@ bool cmSetTargetPropertiesCommand
}
bool cmSetTargetPropertiesCommand
-::SetOneTarget(const char *tname,
+::SetOneTarget(const std::string& tname,
std::vector<std::string> &propertyPairs,
cmMakefile *mf)
{
@@ -101,9 +85,9 @@ bool cmSetTargetPropertiesCommand
unsigned int k;
for (k = 0; k < propertyPairs.size(); k = k + 2)
{
- target->SetProperty(propertyPairs[k].c_str(),
+ target->SetProperty(propertyPairs[k],
propertyPairs[k+1].c_str());
- target->CheckProperty(propertyPairs[k].c_str(), mf);
+ target->CheckProperty(propertyPairs[k], mf);
}
}
// if file is not already in the makefile, then add it
diff --git a/Source/cmSetTargetPropertiesCommand.h b/Source/cmSetTargetPropertiesCommand.h
index cf9c19350..3981ef3d1 100644
--- a/Source/cmSetTargetPropertiesCommand.h
+++ b/Source/cmSetTargetPropertiesCommand.h
@@ -32,136 +32,15 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "set_target_properties";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Targets can have properties that affect how they are built.";
- }
+ virtual std::string GetName() const { return "set_target_properties";}
/**
* Used by this command and cmSetPropertiesCommand
*/
- static bool SetOneTarget(const char *tname,
+ static bool SetOneTarget(const std::string& tname,
std::vector<std::string> &propertyPairs,
cmMakefile *mf);
- /**
- * Longer documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " set_target_properties(target1 target2 ...\n"
- " PROPERTIES prop1 value1\n"
- " prop2 value2 ...)\n"
- "Set properties on a target. The syntax for the command is to "
- "list all the files you want "
- "to change, and then provide the values you want to set next. "
- "You can use any prop value pair you want and "
- "extract it later with the GET_TARGET_PROPERTY command.\n"
- "Properties that affect the name of a target's output file are "
- "as follows. "
- "The PREFIX and SUFFIX properties override the default target name "
- "prefix (such as \"lib\") and suffix (such as \".so\"). "
- "IMPORT_PREFIX and IMPORT_SUFFIX are the equivalent properties for "
- "the import library corresponding to a DLL "
- "(for SHARED library targets). "
- "OUTPUT_NAME sets the real name of a target when it is built and "
- "can be used to help create two targets of the same name even though "
- "CMake requires unique logical target names. There is also a "
- "<CONFIG>_OUTPUT_NAME that can set the output name on a "
- "per-configuration basis. "
- "<CONFIG>_POSTFIX sets a postfix for the real name of the target "
- "when it is built under the configuration named by <CONFIG> "
- "(in upper-case, such as \"DEBUG_POSTFIX\"). The value of "
- "this property is initialized when the target is created to the "
- "value of the variable CMAKE_<CONFIG>_POSTFIX (except for executable "
- "targets because earlier CMake versions which did not use this "
- "variable for executables)."
- "\n"
- "The LINK_FLAGS property can be used to add extra flags to the "
- "link step of a target. LINK_FLAGS_<CONFIG> will add to the "
- "configuration <CONFIG>, "
- "for example, DEBUG, RELEASE, MINSIZEREL, RELWITHDEBINFO. "
- "DEFINE_SYMBOL sets the name of the preprocessor symbol defined when "
- "compiling sources in a shared library. "
- "If not set here then it is set to target_EXPORTS by default "
- "(with some substitutions if the target is not a valid C "
- "identifier). This is useful for headers to know whether they are "
- "being included from inside their library or outside to properly "
- "setup dllexport/dllimport decorations. "
- "The COMPILE_FLAGS property sets additional compiler flags used "
- "to build sources within the target. It may also be used to pass "
- "additional preprocessor definitions."
- "\n"
- "The LINKER_LANGUAGE property is used to change the tool "
- "used to link an executable or shared library. The default is "
- "set the language to match the files in the library. CXX and C "
- "are common values for this property."
- "\n"
- "For shared libraries VERSION and SOVERSION can be used to specify "
- "the build version and API version respectively. When building or "
- "installing appropriate symlinks are created if the platform "
- "supports symlinks and the linker supports so-names. "
- "If only one of both is specified the missing is assumed to have "
- "the same version number. "
- "For executables VERSION can be used to specify the build version. "
- "When building or installing appropriate symlinks are created if "
- "the platform supports symlinks. "
- "For shared libraries and executables on Windows the VERSION "
- "attribute is parsed to extract a \"major.minor\" version number. "
- "These numbers are used as the image version of the binary. "
- "\n"
- "There are a few properties used to specify RPATH rules. "
- "INSTALL_RPATH is a semicolon-separated list specifying the rpath "
- "to use in installed targets (for platforms that support it). "
- "INSTALL_RPATH_USE_LINK_PATH is a boolean that if set to true will "
- "append directories in the linker search path and outside the "
- "project to the INSTALL_RPATH. "
- "SKIP_BUILD_RPATH is a boolean specifying whether to skip automatic "
- "generation of an rpath allowing the target to run from the "
- "build tree. "
- "BUILD_WITH_INSTALL_RPATH is a boolean specifying whether to link "
- "the target in the build tree with the INSTALL_RPATH. This takes "
- "precedence over SKIP_BUILD_RPATH and avoids the need for relinking "
- "before installation. INSTALL_NAME_DIR is a string specifying the "
- "directory portion of the \"install_name\" field of shared libraries "
- "on Mac OSX to use in the installed targets. "
- "When the target is created the values of "
- "the variables CMAKE_INSTALL_RPATH, "
- "CMAKE_INSTALL_RPATH_USE_LINK_PATH, CMAKE_SKIP_BUILD_RPATH, "
- "CMAKE_BUILD_WITH_INSTALL_RPATH, and CMAKE_INSTALL_NAME_DIR "
- "are used to initialize these properties.\n"
- "PROJECT_LABEL can be used to change the name of "
- "the target in an IDE like visual studio. VS_KEYWORD can be set "
- "to change the visual studio keyword, for example Qt integration "
- "works better if this is set to Qt4VSv1.0.\n"
- "VS_SCC_PROJECTNAME, VS_SCC_LOCALPATH, VS_SCC_PROVIDER and "
- "VS_SCC_AUXPATH can be set "
- "to add support for source control bindings in a Visual Studio "
- "project file.\n"
- "VS_GLOBAL_<variable> can be set to add a Visual Studio "
- "project-specific global variable. "
- "Qt integration works better if VS_GLOBAL_QtVersion is set to "
- "the Qt version FindQt4.cmake found. For example, \"4.7.3\"\n"
- "The PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT properties are the "
- "old way to specify CMake scripts to run before and after "
- "installing a target. They are used only when the old "
- "INSTALL_TARGETS command is used to install the target. Use the "
- "INSTALL command instead."
- "\n"
- "The EXCLUDE_FROM_DEFAULT_BUILD property is used by the visual "
- "studio generators. If it is set to 1 the target will not be "
- "part of the default build when you select \"Build Solution\". "
- "This can also be set on a per-configuration basis using "
- "EXCLUDE_FROM_DEFAULT_BUILD_<CONFIG>."
- ;
- }
-
cmTypeMacro(cmSetTargetPropertiesCommand, cmCommand);
};
diff --git a/Source/cmSetTestsPropertiesCommand.cxx b/Source/cmSetTestsPropertiesCommand.cxx
index 3d52cf242..53dc5a8a6 100644
--- a/Source/cmSetTestsPropertiesCommand.cxx
+++ b/Source/cmSetTestsPropertiesCommand.cxx
@@ -26,62 +26,46 @@ bool cmSetTestsPropertiesCommand
// first collect up the list of files
std::vector<std::string> propertyPairs;
- bool doingFiles = true;
int numFiles = 0;
std::vector<std::string>::const_iterator j;
for(j= args.begin(); j != args.end();++j)
{
if(*j == "PROPERTIES")
{
- doingFiles = false;
// now loop through the rest of the arguments, new style
++j;
- while (j != args.end())
+ if (std::distance(j, args.end()) % 2 != 0)
{
- propertyPairs.push_back(*j);
- ++j;
- if(j == args.end())
- {
- this->SetError("called with incorrect number of arguments.");
- return false;
- }
- propertyPairs.push_back(*j);
- ++j;
+ this->SetError("called with incorrect number of arguments.");
+ return false;
}
- // break out of the loop because j is already == end
+ propertyPairs.insert(propertyPairs.end(), j, args.end());
break;
}
- else if (doingFiles)
- {
- numFiles++;
- }
else
{
- this->SetError("called with illegal arguments, maybe "
- "missing a PROPERTIES specifier?");
- return false;
+ numFiles++;
}
}
- if(propertyPairs.size() == 0)
+ if(propertyPairs.empty())
{
this->SetError("called with illegal arguments, maybe "
"missing a PROPERTIES specifier?");
return false;
}
-
// now loop over all the targets
int i;
for(i = 0; i < numFiles; ++i)
{
std::string errors;
bool ret =
- cmSetTestsPropertiesCommand::SetOneTest(args[i].c_str(),
+ cmSetTestsPropertiesCommand::SetOneTest(args[i],
propertyPairs,
this->Makefile, errors);
if (!ret)
{
- this->SetError(errors.c_str());
+ this->SetError(errors);
return ret;
}
}
@@ -91,7 +75,7 @@ bool cmSetTestsPropertiesCommand
bool cmSetTestsPropertiesCommand
-::SetOneTest(const char *tname,
+::SetOneTest(const std::string& tname,
std::vector<std::string> &propertyPairs,
cmMakefile *mf, std::string &errors)
{
@@ -101,8 +85,10 @@ bool cmSetTestsPropertiesCommand
unsigned int k;
for (k = 0; k < propertyPairs.size(); k = k + 2)
{
- test->SetProperty(propertyPairs[k].c_str(),
- propertyPairs[k+1].c_str());
+ if (!propertyPairs[k].empty())
+ {
+ test->SetProperty(propertyPairs[k], propertyPairs[k+1].c_str());
+ }
}
}
else
diff --git a/Source/cmSetTestsPropertiesCommand.h b/Source/cmSetTestsPropertiesCommand.h
index 3a592189b..dabe9448d 100644
--- a/Source/cmSetTestsPropertiesCommand.h
+++ b/Source/cmSetTestsPropertiesCommand.h
@@ -32,45 +32,11 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "set_tests_properties";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Set a property of the tests.";
- }
-
- /**
- * Longer documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " set_tests_properties(test1 [test2...] PROPERTIES prop1 value1 prop2"
- " value2)\n"
- "Set a property for the tests. If the property is not found, CMake "
- "will report an error. The properties include:\n"
- "WILL_FAIL: If set to true, this will invert the pass/fail flag of the"
- " test.\n"
- "PASS_REGULAR_EXPRESSION: If set, the test output will be checked "
- "against the specified regular expressions and at least one of the"
- " regular "
- "expressions has to match, otherwise the test will fail.\n"
- " Example: PASS_REGULAR_EXPRESSION \"TestPassed;All ok\"\n"
- "FAIL_REGULAR_EXPRESSION: If set, if the output will match to one of "
- "specified regular expressions, the test will fail.\n"
- " Example: PASS_REGULAR_EXPRESSION \"[^a-z]Error;ERROR;Failed\"\n"
- "Both PASS_REGULAR_EXPRESSION and FAIL_REGULAR_EXPRESSION expect a "
- "list of regular expressions.\n"
- "TIMEOUT: Setting this will limit the test runtime to the number of "
- "seconds specified.\n";
- }
+ virtual std::string GetName() const { return "set_tests_properties";}
cmTypeMacro(cmSetTestsPropertiesCommand, cmCommand);
- static bool SetOneTest(const char *tname,
+ static bool SetOneTest(const std::string& tname,
std::vector<std::string> &propertyPairs,
cmMakefile *mf,
std::string &errors);
diff --git a/Source/cmSiteNameCommand.cxx b/Source/cmSiteNameCommand.cxx
index 2bdd1ad28..e2970e505 100644
--- a/Source/cmSiteNameCommand.cxx
+++ b/Source/cmSiteNameCommand.cxx
@@ -31,7 +31,7 @@ bool cmSiteNameCommand
paths.push_back("/usr/local/bin");
const char* cacheValue
- = this->Makefile->GetDefinition(args[0].c_str());
+ = this->Makefile->GetDefinition(args[0]);
if(cacheValue)
{
return true;
@@ -63,10 +63,10 @@ bool cmSiteNameCommand
{
std::string host;
cmSystemTools::RunSingleCommand(hostname_cmd.c_str(),
- &host, 0, 0, cmSystemTools::OUTPUT_NONE);
+ &host, 0, 0, 0, cmSystemTools::OUTPUT_NONE);
// got the hostname
- if (host.length())
+ if (!host.empty())
{
// remove any white space from the host name
std::string hostRegExp = "[ \t\n\r]*([^\t\n\r ]*)[ \t\n\r]*";
@@ -77,7 +77,7 @@ bool cmSiteNameCommand
host = hostReg.match(1);
}
- if(host.length())
+ if(!host.empty())
{
siteName = host;
}
@@ -85,10 +85,10 @@ bool cmSiteNameCommand
}
#endif
this->Makefile->
- AddCacheDefinition(args[0].c_str(),
+ AddCacheDefinition(args[0],
siteName.c_str(),
"Name of the computer/site where compile is being run",
- cmCacheManager::STRING);
+ cmState::STRING);
return true;
}
diff --git a/Source/cmSiteNameCommand.h b/Source/cmSiteNameCommand.h
index 52a63bc9c..ec63ef860 100644
--- a/Source/cmSiteNameCommand.h
+++ b/Source/cmSiteNameCommand.h
@@ -45,24 +45,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const {return "site_name";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Set the given variable to the name of the computer.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " site_name(variable)\n";
- }
+ virtual std::string GetName() const {return "site_name";}
cmTypeMacro(cmSiteNameCommand, cmCommand);
};
diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx
index 8bb7d96f5..a9ac5497b 100644
--- a/Source/cmSourceFile.cxx
+++ b/Source/cmSourceFile.cxx
@@ -12,19 +12,18 @@
#include "cmSourceFile.h"
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
#include "cmake.h"
-#include "cmDocumentCompileDefinitions.h"
//----------------------------------------------------------------------------
-cmSourceFile::cmSourceFile(cmMakefile* mf, const char* name):
+cmSourceFile::cmSourceFile(cmMakefile* mf, const std::string& name):
Location(mf, name)
{
this->CustomCommand = 0;
- this->Properties.SetCMakeInstance(mf->GetCMakeInstance());
this->FindFullPathFailed = false;
+ this->IsUiFile = (".ui" ==
+ cmSystemTools::GetFilenameLastExtension(this->Location.GetName()));
}
//----------------------------------------------------------------------------
@@ -39,11 +38,25 @@ std::string const& cmSourceFile::GetExtension() const
return this->Extension;
}
+const std::string cmSourceFile::propLANGUAGE = "LANGUAGE";
+
+//----------------------------------------------------------------------------
+void cmSourceFile::SetObjectLibrary(std::string const& objlib)
+{
+ this->ObjectLibrary = objlib;
+}
+
//----------------------------------------------------------------------------
-const char* cmSourceFile::GetLanguage()
+std::string cmSourceFile::GetObjectLibrary() const
+{
+ return this->ObjectLibrary;
+}
+
+//----------------------------------------------------------------------------
+std::string cmSourceFile::GetLanguage()
{
// If the language was set explicitly by the user then use it.
- if(const char* lang = this->GetProperty("LANGUAGE"))
+ if(const char* lang = this->GetProperty(propLANGUAGE))
{
return lang;
}
@@ -77,10 +90,10 @@ const char* cmSourceFile::GetLanguage()
}
//----------------------------------------------------------------------------
-const char* cmSourceFile::GetLanguage() const
+std::string cmSourceFile::GetLanguage() const
{
// If the language was set explicitly by the user then use it.
- if(const char* lang = this->GetProperty("LANGUAGE"))
+ if(const char* lang = this->GetProperty(propLANGUAGE))
{
return lang;
}
@@ -88,11 +101,11 @@ const char* cmSourceFile::GetLanguage() const
// If the language was determined from the source file extension use it.
if(!this->Language.empty())
{
- return this->Language.c_str();
+ return this->Language;
}
// The language is not known.
- return 0;
+ return "";
}
//----------------------------------------------------------------------------
@@ -143,19 +156,21 @@ bool cmSourceFile::FindFullPath(std::string* error)
}
// The file is not generated. It must exist on disk.
- cmMakefile* mf = this->Location.GetMakefile();
+ cmMakefile const* mf = this->Location.GetMakefile();
const char* tryDirs[3] = {0, 0, 0};
if(this->Location.DirectoryIsAmbiguous())
{
- tryDirs[0] = mf->GetCurrentDirectory();
- tryDirs[1] = mf->GetCurrentOutputDirectory();
+ tryDirs[0] = mf->GetCurrentSourceDirectory();
+ tryDirs[1] = mf->GetCurrentBinaryDirectory();
}
else
{
tryDirs[0] = "";
}
- const std::vector<std::string>& srcExts = mf->GetSourceExtensions();
- const std::vector<std::string>& hdrExts = mf->GetHeaderExtensions();
+ const std::vector<std::string>& srcExts =
+ mf->GetCMakeInstance()->GetSourceExtensions();
+ std::vector<std::string> hdrExts =
+ mf->GetCMakeInstance()->GetHeaderExtensions();
for(const char* const* di = tryDirs; *di; ++di)
{
std::string tryPath = this->Location.GetDirectory();
@@ -164,15 +179,15 @@ bool cmSourceFile::FindFullPath(std::string* error)
tryPath += "/";
}
tryPath += this->Location.GetName();
- tryPath = cmSystemTools::CollapseFullPath(tryPath.c_str(), *di);
- if(this->TryFullPath(tryPath.c_str(), 0))
+ tryPath = cmSystemTools::CollapseFullPath(tryPath, *di);
+ if(this->TryFullPath(tryPath, ""))
{
return true;
}
for(std::vector<std::string>::const_iterator ei = srcExts.begin();
ei != srcExts.end(); ++ei)
{
- if(this->TryFullPath(tryPath.c_str(), ei->c_str()))
+ if(this->TryFullPath(tryPath, *ei))
{
return true;
}
@@ -180,14 +195,14 @@ bool cmSourceFile::FindFullPath(std::string* error)
for(std::vector<std::string>::const_iterator ei = hdrExts.begin();
ei != hdrExts.end(); ++ei)
{
- if(this->TryFullPath(tryPath.c_str(), ei->c_str()))
+ if(this->TryFullPath(tryPath, *ei))
{
return true;
}
}
}
- cmOStringStream e;
+ std::ostringstream e;
std::string missing = this->Location.GetDirectory();
if(!missing.empty())
{
@@ -218,10 +233,11 @@ bool cmSourceFile::FindFullPath(std::string* error)
}
//----------------------------------------------------------------------------
-bool cmSourceFile::TryFullPath(const char* tp, const char* ext)
+bool cmSourceFile::TryFullPath(const std::string& path,
+ const std::string& ext)
{
- std::string tryPath = tp;
- if(ext && *ext)
+ std::string tryPath = path;
+ if(!ext.empty())
{
tryPath += ".";
tryPath += ext;
@@ -265,9 +281,10 @@ void cmSourceFile::CheckExtension()
void cmSourceFile::CheckLanguage(std::string const& ext)
{
// Try to identify the source file language from the extension.
- cmMakefile* mf = this->Location.GetMakefile();
- cmGlobalGenerator* gg = mf->GetLocalGenerator()->GetGlobalGenerator();
- if(const char* l = gg->GetLanguageFromExtension(ext.c_str()))
+ cmMakefile const* mf = this->Location.GetMakefile();
+ cmGlobalGenerator* gg = mf->GetGlobalGenerator();
+ std::string l = gg->GetLanguageFromExtension(ext.c_str());
+ if(!l.empty())
{
this->Language = l;
}
@@ -280,30 +297,29 @@ bool cmSourceFile::Matches(cmSourceFileLocation const& loc)
}
//----------------------------------------------------------------------------
-void cmSourceFile::SetProperty(const char* prop, const char* value)
+void cmSourceFile::SetProperty(const std::string& prop, const char* value)
{
- if (!prop)
+ this->Properties.SetProperty(prop, value);
+
+ if (this->IsUiFile)
{
- return;
+ cmMakefile const* mf = this->Location.GetMakefile();
+ if (prop == "AUTOUIC_OPTIONS")
+ {
+ const_cast<cmMakefile*>(mf)->AddQtUiFileWithOptions(this);
+ }
}
-
- this->Properties.SetProperty(prop, value, cmProperty::SOURCE_FILE);
}
//----------------------------------------------------------------------------
-void cmSourceFile::AppendProperty(const char* prop, const char* value,
+void cmSourceFile::AppendProperty(const std::string& prop, const char* value,
bool asString)
{
- if (!prop)
- {
- return;
- }
- this->Properties.AppendProperty(prop, value, cmProperty::SOURCE_FILE,
- asString);
+ this->Properties.AppendProperty(prop, value, asString);
}
//----------------------------------------------------------------------------
-const char* cmSourceFile::GetPropertyForUser(const char *prop)
+const char* cmSourceFile::GetPropertyForUser(const std::string& prop)
{
// This method is a consequence of design history and backwards
// compatibility. GetProperty is (and should be) a const method.
@@ -319,7 +335,7 @@ const char* cmSourceFile::GetPropertyForUser(const char *prop)
// cmSourceFileLocation class to commit to a particular full path to
// the source file as late as possible. If the users requests the
// LOCATION property we must commit now.
- if(strcmp(prop, "LOCATION") == 0)
+ if(prop == "LOCATION")
{
// Commit to a location.
this->GetFullPath();
@@ -330,10 +346,10 @@ const char* cmSourceFile::GetPropertyForUser(const char *prop)
}
//----------------------------------------------------------------------------
-const char* cmSourceFile::GetProperty(const char* prop) const
+const char* cmSourceFile::GetProperty(const std::string& prop) const
{
// Check for computed properties.
- if(strcmp(prop, "LOCATION") == 0)
+ if(prop == "LOCATION")
{
if(this->FullPath.empty())
{
@@ -345,20 +361,23 @@ const char* cmSourceFile::GetProperty(const char* prop) const
}
}
- bool chain = false;
- const char *retVal =
- this->Properties.GetPropertyValue(prop, cmProperty::SOURCE_FILE, chain);
- if (chain)
+ const char *retVal = this->Properties.GetPropertyValue(prop);
+ if (!retVal)
{
- cmMakefile* mf = this->Location.GetMakefile();
- return mf->GetProperty(prop,cmProperty::SOURCE_FILE);
+ cmMakefile const* mf = this->Location.GetMakefile();
+ const bool chain = mf->GetState()->
+ IsPropertyChained(prop, cmProperty::SOURCE_FILE);
+ if (chain)
+ {
+ return mf->GetProperty(prop, chain);
+ }
}
return retVal;
}
//----------------------------------------------------------------------------
-bool cmSourceFile::GetPropertyAsBool(const char* prop) const
+bool cmSourceFile::GetPropertyAsBool(const std::string& prop) const
{
return cmSystemTools::IsOn(this->GetProperty(prop));
}
@@ -382,176 +401,3 @@ void cmSourceFile::SetCustomCommand(cmCustomCommand* cc)
this->CustomCommand = cc;
delete old;
}
-
-//----------------------------------------------------------------------------
-void cmSourceFile::DefineProperties(cmake *cm)
-{
- // define properties
- cm->DefineProperty
- ("ABSTRACT", cmProperty::SOURCE_FILE,
- "Is this source file an abstract class.",
- "A property on a source file that indicates if the source file "
- "represents a class that is abstract. This only makes sense for "
- "languages that have a notion of an abstract class and it is "
- "only used by some tools that wrap classes into other languages.");
-
- cm->DefineProperty
- ("COMPILE_FLAGS", cmProperty::SOURCE_FILE,
- "Additional flags to be added when compiling this source file.",
- "These flags will be added to the list of compile flags when "
- "this source file builds. Use COMPILE_DEFINITIONS to pass additional "
- "preprocessor definitions.");
-
- cm->DefineProperty
- ("COMPILE_DEFINITIONS", cmProperty::SOURCE_FILE,
- "Preprocessor definitions for compiling a source file.",
- "The COMPILE_DEFINITIONS property may be set to a "
- "semicolon-separated list of preprocessor "
- "definitions using the syntax VAR or VAR=value. Function-style "
- "definitions are not supported. CMake will automatically escape "
- "the value correctly for the native build system (note that CMake "
- "language syntax may require escapes to specify some values). "
- "This property may be set on a per-configuration basis using the name "
- "COMPILE_DEFINITIONS_<CONFIG> where <CONFIG> is an upper-case name "
- "(ex. \"COMPILE_DEFINITIONS_DEBUG\").\n"
- "CMake will automatically drop some definitions that "
- "are not supported by the native build tool. "
- "The VS6 IDE does not support definition values with spaces "
- "(but NMake does). Xcode does not support per-configuration "
- "definitions on source files.\n"
- CM_DOCUMENT_COMPILE_DEFINITIONS_DISCLAIMER);
-
- cm->DefineProperty
- ("COMPILE_DEFINITIONS_<CONFIG>", cmProperty::SOURCE_FILE,
- "Per-configuration preprocessor definitions on a source file.",
- "This is the configuration-specific version of "
- "COMPILE_DEFINITIONS. Note that Xcode does not support "
- "per-configuration source file flags so this property will "
- "be ignored by the Xcode generator.");
-
- cm->DefineProperty
- ("EXTERNAL_OBJECT", cmProperty::SOURCE_FILE,
- "If set to true then this is an object file.",
- "If this property is set to true then the source file "
- "is really an object file and should not be compiled. "
- "It will still be linked into the target though.");
-
- cm->DefineProperty
- ("Fortran_FORMAT", cmProperty::SOURCE_FILE,
- "Set to FIXED or FREE to indicate the Fortran source layout.",
- "This property tells CMake whether a given Fortran source file "
- "uses fixed-format or free-format. "
- "CMake will pass the corresponding format flag to the compiler. "
- "Consider using the target-wide Fortran_FORMAT property if all "
- "source files in a target share the same format.");
-
- cm->DefineProperty
- ("GENERATED", cmProperty::SOURCE_FILE,
- "Is this source file generated as part of the build process.",
- "If a source file is generated by the build process CMake will "
- "handle it differently in terms of dependency checking etc. "
- "Otherwise having a non-existent source file could create problems.");
-
- cm->DefineProperty
- ("HEADER_FILE_ONLY", cmProperty::SOURCE_FILE,
- "Is this source file only a header file.",
- "A property on a source file that indicates if the source file "
- "is a header file with no associated implementation. This is "
- "set automatically based on the file extension and is used by "
- "CMake to determine if certain dependency information should be "
- "computed.");
-
- cm->DefineProperty
- ("KEEP_EXTENSION", cmProperty::SOURCE_FILE,
- "Make the output file have the same extension as the source file.",
- "If this property is set then the file extension of the output "
- "file will be the same as that of the source file. Normally "
- "the output file extension is computed based on the language "
- "of the source file, for example .cxx will go to a .o extension.");
-
- cm->DefineProperty
- ("LABELS", cmProperty::SOURCE_FILE,
- "Specify a list of text labels associated with a source file.",
- "This property has meaning only when the source file is listed in "
- "a target whose LABELS property is also set. "
- "No other semantics are currently specified.");
-
- cm->DefineProperty
- ("LANGUAGE", cmProperty::SOURCE_FILE,
- "What programming language is the file.",
- "A property that can be set to indicate what programming language "
- "the source file is. If it is not set the language is determined "
- "based on the file extension. Typical values are CXX C etc. Setting "
- "this property for a file means this file will be compiled. "
- "Do not set this for headers or files that should not be compiled.");
-
- cm->DefineProperty
- ("LOCATION", cmProperty::SOURCE_FILE,
- "The full path to a source file.",
- "A read only property on a SOURCE FILE that contains the full path "
- "to the source file.");
-
- cm->DefineProperty
- ("MACOSX_PACKAGE_LOCATION", cmProperty::SOURCE_FILE,
- "Place a source file inside a Mac OS X bundle, CFBundle, or framework.",
- "Executable targets with the MACOSX_BUNDLE property set are built "
- "as Mac OS X application bundles on Apple platforms. "
- "Shared library targets with the FRAMEWORK property set are built "
- "as Mac OS X frameworks on Apple platforms. "
- "Module library targets with the BUNDLE property set are built "
- "as Mac OS X CFBundle bundles on Apple platforms. "
- "Source files listed in the target with this property set will "
- "be copied to a directory inside the bundle or framework content "
- "folder specified by the property value. "
- "For bundles the content folder is \"<name>.app/Contents\". "
- "For frameworks the content folder is "
- "\"<name>.framework/Versions/<version>\". "
- "For cfbundles the content folder is "
- "\"<name>.bundle/Contents\" (unless the extension is changed). "
- "See the PUBLIC_HEADER, PRIVATE_HEADER, and RESOURCE target "
- "properties for specifying files meant for Headers, PrivateHeaders, "
- "or Resources directories.");
-
- cm->DefineProperty
- ("OBJECT_DEPENDS", cmProperty::SOURCE_FILE,
- "Additional files on which a compiled object file depends.",
- "Specifies a semicolon-separated list of full-paths to files on which "
- "any object files compiled from this source file depend. "
- "An object file will be recompiled if any of the named files is newer "
- "than it.\n"
- "This property need not be used to specify the dependency of a "
- "source file on a generated header file that it includes. "
- "Although the property was originally introduced for this purpose, it "
- "is no longer necessary. "
- "If the generated header file is created by a custom command in the "
- "same target as the source file, the automatic dependency scanning "
- "process will recognize the dependency. "
- "If the generated header file is created by another target, an "
- "inter-target dependency should be created with the add_dependencies "
- "command (if one does not already exist due to linking relationships).");
-
- cm->DefineProperty
- ("OBJECT_OUTPUTS", cmProperty::SOURCE_FILE,
- "Additional outputs for a Makefile rule.",
- "Additional outputs created by compilation of this source file. "
- "If any of these outputs is missing the object will be recompiled. "
- "This is supported only on Makefile generators and will be ignored "
- "on other generators.");
-
- cm->DefineProperty
- ("SYMBOLIC", cmProperty::SOURCE_FILE,
- "Is this just a name for a rule.",
- "If SYMBOLIC (boolean) is set to true the build system will be "
- "informed that the source file is not actually created on disk but "
- "instead used as a symbolic name for a build rule.");
-
- cm->DefineProperty
- ("WRAP_EXCLUDE", cmProperty::SOURCE_FILE,
- "Exclude this source file from any code wrapping techniques.",
- "Some packages can wrap source files into alternate languages "
- "to provide additional functionality. For example, C++ code "
- "can be wrapped into Java or Python etc using SWIG etc. "
- "If WRAP_EXCLUDE is set to true (1 etc) that indicates that "
- "this source file should not be wrapped.");
-}
-
diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h
index 6c68b8745..1433b54f0 100644
--- a/Source/cmSourceFile.h
+++ b/Source/cmSourceFile.h
@@ -31,7 +31,7 @@ public:
* Construct with the makefile storing the source and the initial
* name referencing it.
*/
- cmSourceFile(cmMakefile* mf, const char* name);
+ cmSourceFile(cmMakefile* mf, const std::string& name);
~cmSourceFile();
@@ -43,14 +43,15 @@ public:
void SetCustomCommand(cmCustomCommand *cc);
///! Set/Get a property of this source file
- void SetProperty(const char *prop, const char *value);
- void AppendProperty(const char* prop, const char* value,bool asString=false);
- const char *GetProperty(const char *prop) const;
- bool GetPropertyAsBool(const char *prop) const;
+ void SetProperty(const std::string& prop, const char *value);
+ void AppendProperty(const std::string& prop,
+ const char* value,bool asString=false);
+ const char *GetProperty(const std::string& prop) const;
+ bool GetPropertyAsBool(const std::string& prop) const;
/** Implement getting a property when called from a CMake language
command like get_property or get_source_file_property. */
- const char* GetPropertyForUser(const char *prop);
+ const char* GetPropertyForUser(const std::string& prop);
/**
* The full path to the file. The non-const version of this method
@@ -78,20 +79,17 @@ public:
/**
* Get the language of the compiler to use for this source file.
*/
- const char* GetLanguage();
- const char* GetLanguage() const;
+ std::string GetLanguage();
+ std::string GetLanguage() const;
/**
* Return the vector that holds the list of dependencies
*/
const std::vector<std::string> &GetDepends() const {return this->Depends;}
- void AddDepend(const char* d) { this->Depends.push_back(d); }
+ void AddDepend(const std::string& d) { this->Depends.push_back(d); }
// Get the properties
- cmPropertyMap &GetProperties() { return this->Properties; };
-
- // Define the properties
- static void DefineProperties(cmake *cm);
+ cmPropertyMap &GetProperties() { return this->Properties; }
/**
* Check whether the given source file location could refer to this
@@ -99,6 +97,9 @@ public:
*/
bool Matches(cmSourceFileLocation const&);
+ void SetObjectLibrary(std::string const& objlib);
+ std::string GetObjectLibrary() const;
+
private:
cmSourceFileLocation Location;
cmPropertyMap Properties;
@@ -106,14 +107,18 @@ private:
std::string Extension;
std::string Language;
std::string FullPath;
+ std::string ObjectLibrary;
+ std::vector<std::string> Depends;
bool FindFullPathFailed;
+ bool IsUiFile;
bool FindFullPath(std::string* error);
- bool TryFullPath(const char* tryPath, const char* ext);
+ bool TryFullPath(const std::string& path, const std::string& ext);
void CheckExtension();
void CheckLanguage(std::string const& ext);
- std::vector<std::string> Depends;
+
+ static const std::string propLANGUAGE;
};
// TODO: Factor out into platform information modules.
diff --git a/Source/cmSourceFileLocation.cxx b/Source/cmSourceFileLocation.cxx
index 5525b618a..00d5d6afe 100644
--- a/Source/cmSourceFileLocation.cxx
+++ b/Source/cmSourceFileLocation.cxx
@@ -12,32 +12,61 @@
#include "cmSourceFileLocation.h"
#include "cmMakefile.h"
-#include "cmLocalGenerator.h"
#include "cmGlobalGenerator.h"
#include "cmSystemTools.h"
+#include "cmAlgorithms.h"
+
+#include "assert.h"
//----------------------------------------------------------------------------
-cmSourceFileLocation
-::cmSourceFileLocation(cmMakefile* mf, const char* name): Makefile(mf)
+cmSourceFileLocation::cmSourceFileLocation()
+ : Makefile(0), AmbiguousDirectory(true), AmbiguousExtension(true)
{
- this->AmbiguousDirectory = !cmSystemTools::FileIsFullPath(name);
- this->AmbiguousExtension = true;
- this->Directory = cmSystemTools::GetFilenamePath(name);
- this->Name = cmSystemTools::GetFilenameName(name);
- this->UpdateExtension(name);
+
}
//----------------------------------------------------------------------------
-void cmSourceFileLocation::Update(const char* name)
+cmSourceFileLocation::cmSourceFileLocation(const cmSourceFileLocation& loc)
+ : Makefile(loc.Makefile)
{
- if(this->AmbiguousDirectory)
+ this->AmbiguousDirectory = loc.AmbiguousDirectory;
+ this->AmbiguousExtension = loc.AmbiguousExtension;
+ this->Directory = loc.Directory;
+ this->Name = loc.Name;
+}
+
+//----------------------------------------------------------------------------
+cmSourceFileLocation&
+cmSourceFileLocation::operator=(const cmSourceFileLocation& loc)
+{
+ if(this == &loc)
{
- this->UpdateDirectory(name);
+ return *this;
}
- if(this->AmbiguousExtension)
+ this->Makefile = loc.Makefile;
+ this->AmbiguousDirectory = loc.AmbiguousDirectory;
+ this->AmbiguousExtension = loc.AmbiguousExtension;
+ this->Directory = loc.Directory;
+ this->Name = loc.Name;
+ this->UpdateExtension(this->Name);
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+cmSourceFileLocation
+::cmSourceFileLocation(cmMakefile const* mf, const std::string& name)
+ : Makefile(mf)
+{
+ this->AmbiguousDirectory = !cmSystemTools::FileIsFullPath(name.c_str());
+ this->AmbiguousExtension = true;
+ this->Directory = cmSystemTools::GetFilenamePath(name);
+ if (cmSystemTools::FileIsFullPath(this->Directory.c_str()))
{
- this->UpdateExtension(name);
+ this->Directory
+ = cmSystemTools::CollapseFullPath(this->Directory);
}
+ this->Name = cmSystemTools::GetFilenameName(name);
+ this->UpdateExtension(name);
}
//----------------------------------------------------------------------------
@@ -58,11 +87,12 @@ void cmSourceFileLocation::Update(cmSourceFileLocation const& loc)
//----------------------------------------------------------------------------
void cmSourceFileLocation::DirectoryUseSource()
{
+ assert(this->Makefile);
if(this->AmbiguousDirectory)
{
this->Directory =
cmSystemTools::CollapseFullPath(
- this->Directory.c_str(), this->Makefile->GetCurrentDirectory());
+ this->Directory, this->Makefile->GetCurrentSourceDirectory());
this->AmbiguousDirectory = false;
}
}
@@ -70,29 +100,32 @@ void cmSourceFileLocation::DirectoryUseSource()
//----------------------------------------------------------------------------
void cmSourceFileLocation::DirectoryUseBinary()
{
+ assert(this->Makefile);
if(this->AmbiguousDirectory)
{
this->Directory =
cmSystemTools::CollapseFullPath(
- this->Directory.c_str(), this->Makefile->GetCurrentOutputDirectory());
+ this->Directory, this->Makefile->GetCurrentBinaryDirectory());
this->AmbiguousDirectory = false;
}
}
//----------------------------------------------------------------------------
-void cmSourceFileLocation::UpdateExtension(const char* name)
+void cmSourceFileLocation::UpdateExtension(const std::string& name)
{
+ assert(this->Makefile);
// Check the extension.
std::string ext = cmSystemTools::GetFilenameLastExtension(name);
if(!ext.empty()) { ext = ext.substr(1); }
// The global generator checks extensions of enabled languages.
- cmGlobalGenerator* gg =
- this->Makefile->GetLocalGenerator()->GetGlobalGenerator();
- cmMakefile* mf = this->Makefile;
- const std::vector<std::string>& srcExts = mf->GetSourceExtensions();
- const std::vector<std::string>& hdrExts = mf->GetHeaderExtensions();
- if(gg->GetLanguageFromExtension(ext.c_str()) ||
+ cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
+ cmMakefile const* mf = this->Makefile;
+ const std::vector<std::string>& srcExts =
+ mf->GetCMakeInstance()->GetSourceExtensions();
+ const std::vector<std::string>& hdrExts =
+ mf->GetCMakeInstance()->GetHeaderExtensions();
+ if(!gg->GetLanguageFromExtension(ext.c_str()).empty() ||
std::find(srcExts.begin(), srcExts.end(), ext) != srcExts.end() ||
std::find(hdrExts.begin(), hdrExts.end(), ext) != hdrExts.end())
{
@@ -110,7 +143,7 @@ void cmSourceFileLocation::UpdateExtension(const char* name)
// Check the source tree only because a file in the build tree should
// be specified by full path at least once. We do not want this
// detection to depend on whether the project has already been built.
- tryPath = this->Makefile->GetCurrentDirectory();
+ tryPath = this->Makefile->GetCurrentSourceDirectory();
tryPath += "/";
}
if(!this->Directory.empty())
@@ -136,21 +169,11 @@ void cmSourceFileLocation::UpdateExtension(const char* name)
}
//----------------------------------------------------------------------------
-void cmSourceFileLocation::UpdateDirectory(const char* name)
-{
- // If a full path was given we know the directory.
- if(cmSystemTools::FileIsFullPath(name))
- {
- this->Directory = cmSystemTools::GetFilenamePath(name);
- this->AmbiguousDirectory = false;
- }
-}
-
-//----------------------------------------------------------------------------
bool
cmSourceFileLocation
::MatchesAmbiguousExtension(cmSourceFileLocation const& loc) const
{
+ assert(this->Makefile);
// This location's extension is not ambiguous but loc's extension
// is. See if the names match as-is.
if(this->Name == loc.Name)
@@ -161,22 +184,25 @@ cmSourceFileLocation
// Check if loc's name could possibly be extended to our name by
// adding an extension.
if(!(this->Name.size() > loc.Name.size() &&
- this->Name.substr(0, loc.Name.size()) == loc.Name &&
- this->Name[loc.Name.size()] == '.'))
+ this->Name[loc.Name.size()] == '.' &&
+ cmHasLiteralPrefixImpl(this->Name.c_str(),
+ loc.Name.c_str(), loc.Name.size())))
{
return false;
}
// Only a fixed set of extensions will be tried to match a file on
// disk. One of these must match if loc refers to this source file.
- std::string ext = this->Name.substr(loc.Name.size()+1);
- cmMakefile* mf = this->Makefile;
- const std::vector<std::string>& srcExts = mf->GetSourceExtensions();
+ std::string const& ext = this->Name.substr(loc.Name.size()+1);
+ cmMakefile const* mf = this->Makefile;
+ const std::vector<std::string>& srcExts =
+ mf->GetCMakeInstance()->GetSourceExtensions();
if(std::find(srcExts.begin(), srcExts.end(), ext) != srcExts.end())
{
return true;
}
- const std::vector<std::string>& hdrExts = mf->GetHeaderExtensions();
+ std::vector<std::string> hdrExts =
+ mf->GetCMakeInstance()->GetHeaderExtensions();
if(std::find(hdrExts.begin(), hdrExts.end(), ext) != hdrExts.end())
{
return true;
@@ -187,36 +213,35 @@ cmSourceFileLocation
//----------------------------------------------------------------------------
bool cmSourceFileLocation::Matches(cmSourceFileLocation const& loc)
{
- if(this->AmbiguousExtension && loc.AmbiguousExtension)
+ assert(this->Makefile);
+ if(this->AmbiguousExtension == loc.AmbiguousExtension)
{
- // Both extensions are ambiguous. Since only the old fixed set of
- // extensions will be tried, the names must match at this point to
- // be the same file.
- if(this->Name != loc.Name)
+ // Both extensions are similarly ambiguous. Since only the old fixed set
+ // of extensions will be tried, the names must match at this point to be
+ // the same file.
+ if(this->Name.size() != loc.Name.size() ||
+ !cmSystemTools::ComparePath(this->Name, loc.Name))
{
return false;
}
}
- else if(this->AmbiguousExtension)
+ else
{
- // Only "this" extension is ambiguous.
- if(!loc.MatchesAmbiguousExtension(*this))
+ const cmSourceFileLocation* loc1;
+ const cmSourceFileLocation* loc2;
+ if(this->AmbiguousExtension)
{
- return false;
+ // Only "this" extension is ambiguous.
+ loc1 = &loc;
+ loc2 = this;
}
- }
- else if(loc.AmbiguousExtension)
- {
- // Only "loc" extension is ambiguous.
- if(!this->MatchesAmbiguousExtension(loc))
+ else
{
- return false;
+ // Only "loc" extension is ambiguous.
+ loc1 = this;
+ loc2 = &loc;
}
- }
- else
- {
- // Neither extension is ambiguous.
- if(this->Name != loc.Name)
+ if(!loc1->MatchesAmbiguousExtension(*loc2))
{
return false;
}
@@ -230,37 +255,39 @@ bool cmSourceFileLocation::Matches(cmSourceFileLocation const& loc)
return false;
}
}
- else if(this->AmbiguousDirectory && loc.AmbiguousDirectory &&
- this->Makefile == loc.Makefile)
+ else if(this->AmbiguousDirectory && loc.AmbiguousDirectory)
{
- // Both sides have directories relative to the same location.
- if(this->Directory != loc.Directory)
+ if (this->Makefile == loc.Makefile)
{
+ // Both sides have directories relative to the same location.
+ if(this->Directory != loc.Directory)
+ {
+ return false;
+ }
+ }
+ else
+ {
+ // Each side has a directory relative to a different location.
+ // This can occur when referencing a source file from a different
+ // directory. This is not yet allowed.
+ this->Makefile->IssueMessage(
+ cmake::INTERNAL_ERROR,
+ "Matches error: Each side has a directory relative to a different "
+ "location. This can occur when referencing a source file from a "
+ "different directory. This is not yet allowed."
+ );
return false;
}
}
- else if(this->AmbiguousDirectory && loc.AmbiguousDirectory)
- {
- // Each side has a directory relative to a different location.
- // This can occur when referencing a source file from a different
- // directory. This is not yet allowed.
- this->Makefile->IssueMessage(
- cmake::INTERNAL_ERROR,
- "Matches error: Each side has a directory relative to a different "
- "location. This can occur when referencing a source file from a "
- "different directory. This is not yet allowed."
- );
- return false;
- }
else if(this->AmbiguousDirectory)
{
// Compare possible directory combinations.
- std::string srcDir =
+ std::string const& srcDir =
cmSystemTools::CollapseFullPath(
- this->Directory.c_str(), this->Makefile->GetCurrentDirectory());
- std::string binDir =
+ this->Directory, this->Makefile->GetCurrentSourceDirectory());
+ std::string const& binDir =
cmSystemTools::CollapseFullPath(
- this->Directory.c_str(), this->Makefile->GetCurrentOutputDirectory());
+ this->Directory, this->Makefile->GetCurrentBinaryDirectory());
if(srcDir != loc.Directory &&
binDir != loc.Directory)
{
@@ -270,12 +297,12 @@ bool cmSourceFileLocation::Matches(cmSourceFileLocation const& loc)
else if(loc.AmbiguousDirectory)
{
// Compare possible directory combinations.
- std::string srcDir =
+ std::string const& srcDir =
cmSystemTools::CollapseFullPath(
- loc.Directory.c_str(), loc.Makefile->GetCurrentDirectory());
- std::string binDir =
+ loc.Directory, loc.Makefile->GetCurrentSourceDirectory());
+ std::string const& binDir =
cmSystemTools::CollapseFullPath(
- loc.Directory.c_str(), loc.Makefile->GetCurrentOutputDirectory());
+ loc.Directory, loc.Makefile->GetCurrentBinaryDirectory());
if(srcDir != this->Directory &&
binDir != this->Directory)
{
diff --git a/Source/cmSourceFileLocation.h b/Source/cmSourceFileLocation.h
index 216dd07b8..af3651a29 100644
--- a/Source/cmSourceFileLocation.h
+++ b/Source/cmSourceFileLocation.h
@@ -33,7 +33,10 @@ public:
* Construct for a source file created in a given cmMakefile
* instance with an initial name.
*/
- cmSourceFileLocation(cmMakefile* mf, const char* name);
+ cmSourceFileLocation(cmMakefile const* mf, const std::string& name);
+ cmSourceFileLocation();
+ cmSourceFileLocation(const cmSourceFileLocation& loc);
+ cmSourceFileLocation& operator=(const cmSourceFileLocation& loc);
/**
* Return whether the givne source file location could refers to the
@@ -68,7 +71,7 @@ public:
* Otherwise it will be a relative path (possibly empty) that is
* either with respect to the source or build tree.
*/
- const char* GetDirectory() const { return this->Directory.c_str(); }
+ const std::string& GetDirectory() const { return this->Directory; }
/**
* Get the file name as best is currently known. If
@@ -76,14 +79,14 @@ public:
* final name (but could be). Otherwise the returned name is the
* final name.
*/
- const char* GetName() const { return this->Name.c_str(); }
+ const std::string& GetName() const { return this->Name; }
/**
* Get the cmMakefile instance for which the source file was created.
*/
- cmMakefile* GetMakefile() const { return this->Makefile; }
+ cmMakefile const* GetMakefile() const { return this->Makefile; }
private:
- cmMakefile* Makefile;
+ cmMakefile const* Makefile;
bool AmbiguousDirectory;
bool AmbiguousExtension;
std::string Directory;
@@ -93,9 +96,7 @@ private:
// Update the location with additional knowledge.
void Update(cmSourceFileLocation const& loc);
- void Update(const char* name);
- void UpdateExtension(const char* name);
- void UpdateDirectory(const char* name);
+ void UpdateExtension(const std::string& name);
};
#endif
diff --git a/Source/cmSourceGroup.cxx b/Source/cmSourceGroup.cxx
index f09976f44..8fed95e11 100644
--- a/Source/cmSourceGroup.cxx
+++ b/Source/cmSourceGroup.cxx
@@ -73,7 +73,7 @@ void cmSourceGroup::SetGroupRegex(const char* regex)
}
//----------------------------------------------------------------------------
-void cmSourceGroup::AddGroupFile(const char* name)
+void cmSourceGroup::AddGroupFile(const std::string& name)
{
this->GroupFiles.insert(name);
}
@@ -99,7 +99,7 @@ bool cmSourceGroup::MatchesRegex(const char* name)
//----------------------------------------------------------------------------
bool cmSourceGroup::MatchesFiles(const char* name)
{
- std::set<cmStdString>::const_iterator i = this->GroupFiles.find(name);
+ std::set<std::string>::const_iterator i = this->GroupFiles.find(name);
if(i != this->GroupFiles.end())
{
return true;
@@ -126,12 +126,12 @@ void cmSourceGroup::AddChild(cmSourceGroup child)
}
//----------------------------------------------------------------------------
-cmSourceGroup *cmSourceGroup::lookupChild(const char* name)
+cmSourceGroup *cmSourceGroup::LookupChild(const char* name) const
{
// initializing iterators
- std::vector<cmSourceGroup>::iterator iter =
+ std::vector<cmSourceGroup>::const_iterator iter =
this->Internal->GroupChildren.begin();
- std::vector<cmSourceGroup>::iterator end =
+ const std::vector<cmSourceGroup>::const_iterator end =
this->Internal->GroupChildren.end();
// st
@@ -142,7 +142,7 @@ cmSourceGroup *cmSourceGroup::lookupChild(const char* name)
// look if descenened is the one were looking for
if(sgName == name)
{
- return &(*iter); // if it so return it
+ return const_cast<cmSourceGroup*>(&(*iter)); // if it so return it
}
}
diff --git a/Source/cmSourceGroup.h b/Source/cmSourceGroup.h
index 11a0c74ae..e8cf519d4 100644
--- a/Source/cmSourceGroup.h
+++ b/Source/cmSourceGroup.h
@@ -46,7 +46,7 @@ public:
/**
* Add a file name to the explicit list of files for this group.
*/
- void AddGroupFile(const char* name);
+ void AddGroupFile(const std::string& name);
/**
* Add child to this sourcegroup
@@ -56,7 +56,7 @@ public:
/**
* Looks up child and returns it
*/
- cmSourceGroup *lookupChild(const char *name);
+ cmSourceGroup *LookupChild(const char *name) const;
/**
* Get the name of this group.
@@ -118,7 +118,7 @@ private:
/**
* Set of file names explicitly added to this group.
*/
- std::set<cmStdString> GroupFiles;
+ std::set<std::string> GroupFiles;
/**
* Vector of all source files that have been assigned to
diff --git a/Source/cmSourceGroupCommand.cxx b/Source/cmSourceGroupCommand.cxx
index 9cb80f617..fadb17299 100644
--- a/Source/cmSourceGroupCommand.cxx
+++ b/Source/cmSourceGroupCommand.cxx
@@ -78,22 +78,22 @@ bool cmSourceGroupCommand
else if(doingFiles)
{
// Convert name to full path and add to the group's list.
- std::string src = args[i].c_str();
+ std::string src = args[i];
if(!cmSystemTools::FileIsFullPath(src.c_str()))
{
- src = this->Makefile->GetCurrentDirectory();
+ src = this->Makefile->GetCurrentSourceDirectory();
src += "/";
src += args[i];
}
src = cmSystemTools::CollapseFullPath(src.c_str());
- sg->AddGroupFile(src.c_str());
+ sg->AddGroupFile(src);
}
else
{
- cmOStringStream err;
- err << "Unknown argument \"" << args[i].c_str() << "\". "
+ std::ostringstream err;
+ err << "Unknown argument \"" << args[i] << "\". "
<< "Perhaps the FILES keyword is missing.\n";
- this->SetError(err.str().c_str());
+ this->SetError(err.str());
return false;
}
}
diff --git a/Source/cmSourceGroupCommand.h b/Source/cmSourceGroupCommand.h
index 9f6b7e4f9..410411be9 100644
--- a/Source/cmSourceGroupCommand.h
+++ b/Source/cmSourceGroupCommand.h
@@ -41,37 +41,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const {return "source_group";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Define a grouping for sources in the makefile.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " source_group(name [REGULAR_EXPRESSION regex] "
- "[FILES src1 src2 ...])\n"
- "Defines a group into which sources will be placed in project files. "
- "This is mainly used to setup file tabs in Visual Studio. "
- "Any file whose name is listed or matches the regular expression will "
- "be placed in this group. If a file matches multiple groups, the LAST "
- "group that explicitly lists the file will be favored, if any. If no "
- "group explicitly lists the file, the LAST group whose regular "
- "expression matches the file will be favored.\n"
- "The name of the group may contain backslashes to specify subgroups:\n"
- " source_group(outer\\\\inner ...)\n"
- "For backwards compatibility, this command also supports the "
- "format:\n"
- " source_group(name regex)";
- }
+ virtual std::string GetName() const {return "source_group";}
cmTypeMacro(cmSourceGroupCommand, cmCommand);
};
diff --git a/Source/cmStandardIncludes.cxx b/Source/cmStandardIncludes.cxx
deleted file mode 100644
index a4bdb2e32..000000000
--- a/Source/cmStandardIncludes.cxx
+++ /dev/null
@@ -1,16 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2010 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#include "cmStandardIncludes.h"
-#if !defined(CMAKE_NO_ANSI_STRING_STREAM)
-cmOStringStream::cmOStringStream() {}
-cmOStringStream::~cmOStringStream() {}
-#endif
diff --git a/Source/cmStandardIncludes.h b/Source/cmStandardIncludes.h
index a4aec2e12..272c1361d 100644
--- a/Source/cmStandardIncludes.h
+++ b/Source/cmStandardIncludes.h
@@ -16,87 +16,27 @@
#ifndef cmStandardIncludes_h
#define cmStandardIncludes_h
-// include configure generated header to define CMAKE_NO_ANSI_STREAM_HEADERS,
-// CMAKE_NO_STD_NAMESPACE, and other macros.
#include <cmConfigure.h>
#include <cmsys/Configure.hxx>
#ifdef _MSC_VER
#pragma warning ( disable : 4786 )
#pragma warning ( disable : 4503 )
-#pragma warning ( disable : 4512 ) /* operator=() could not be generated */
-#define CMAKE_NO_ANSI_FOR_SCOPE
#endif
-#ifdef __BORLANDC__
-# pragma warn -8030 /* Temporary used for parameter */
-# pragma warn -8027 /* 'for' not inlined. */
-# pragma warn -8026 /* 'exception' not inlined. */
-# pragma warn -8004 /* value never used */
-#endif
#ifdef __ICL
#pragma warning ( disable : 985 )
#pragma warning ( disable : 1572 ) /* floating-point equality test */
#endif
-#include <stdarg.h> // Work-around for SGI MIPSpro 7.4.2m header bug
-
-// This is a hack to prevent warnings about these functions being
-// declared but not referenced.
-#if defined(__sgi) && !defined(__GNUC__)
-# pragma set woff 3970 /* conversion from pointer to same-sized */
-# include <sys/termios.h>
-class cmStandardIncludesHack
-{
-public:
- enum
- {
- Ref1 = sizeof(cfgetospeed(0)),
- Ref2 = sizeof(cfgetispeed(0)),
- Ref3 = sizeof(tcgetattr(0, 0)),
- Ref4 = sizeof(tcsetattr(0, 0, 0)),
- Ref5 = sizeof(cfsetospeed(0,0)),
- Ref6 = sizeof(cfsetispeed(0,0))
- };
-};
-#endif
-
-// Include stream compatibility layer from KWSys.
-// This is needed to work with large file support
-// on some platforms whose stream operators do not
-// support the large integer types.
-#if defined(CMAKE_BUILD_WITH_CMAKE)
-# include <cmsys/IOStream.hxx>
-# undef GetCurrentDirectory // Borland <iosfwd> includes windows.h
-#endif
-
-// Avoid warnings in system headers.
-#if defined(_MSC_VER)
-# pragma warning (push,1)
-#endif
-#if defined(__BORLANDC__)
-# pragma warn -8008 /* condition is always false (RESET BELOW!) */
-# pragma warn -8066 /* unreachable code (RESET BELOW!) */
-#endif
+// Provide fixed-size integer types.
+#include <cm_kwiml.h>
-#ifndef CMAKE_NO_ANSI_STREAM_HEADERS
-# include <fstream>
-# include <iostream>
-# include <iomanip>
-#else
-# include <fstream.h>
-# include <iostream.h>
-# include <iomanip.h>
-#endif
-
-#if !defined(CMAKE_NO_ANSI_STRING_STREAM)
-# include <sstream>
-#elif !defined(CMAKE_NO_ANSI_STREAM_HEADERS)
-# include <strstream>
-#else
-# include <strstream.h>
-#endif
+#include <fstream>
+#include <iostream>
+#include <iomanip>
+#include <sstream>
// we must have stl with the standard include style
#include <vector>
@@ -105,230 +45,39 @@ public:
#include <algorithm>
#include <functional>
#include <map>
-#include <list>
#include <set>
-#include <deque>
-
-#if defined(__BORLANDC__)
-# pragma warn .8008 /* condition is always false (disabled above) */
-# pragma warn .8066 /* unreachable code (disabled above) */
-#endif
-#if defined(_MSC_VER)
-# pragma warning(pop)
-#endif
// include the "c" string header
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
-// Borland C++ defines several of the stdlib.h and string.h symbols in
-// sub-headers search.h and mem.h. These sub-headers have using
-// declarations to pull functions from the std namespace to the global
-// namespace, but they are defined only if the header was not included
-// through the C++-style cstdlib or cstring header. These outer
-// headers are included by the streams library in C++-style and
-// include blockers are put in place that prevent including the
-// C-style versions from ever including the sub-headers. Therefore we
-// have to include the sub-headers here to get the using declarations.
-#if defined(__BORLANDC__)
-# include <mem.h> /* mem... functions from string.h */
-# include <search.h> /* search functions from stdlib.h */
-#endif
-
-
-#if !defined(_WIN32) && defined(__COMO__)
-// Hack for como strict mode to avoid defining _SVID_SOURCE or _BSD_SOURCE.
-extern "C"
-{
-extern FILE *popen (__const char *__command, __const char *__modes) __THROW;
-extern int pclose (FILE *__stream) __THROW;
-extern char *realpath (__const char *__restrict __name,
- char *__restrict __resolved) __THROW;
-extern char *strdup (__const char *__s) __THROW;
-extern int putenv (char *__string) __THROW;
-}
-#endif
-
-// if std:: is not supported, then just #define it away
-#ifdef CMAKE_NO_STD_NAMESPACE
-#define std
-#endif
-
-// if the compiler does not support ansi for scoping of vars use a
-// #define hack
-#ifdef CMAKE_NO_ANSI_FOR_SCOPE
-#define for if(false) {} else for
-#endif
-
-// Provide std::ios_base on ancient GCC 2.9x
-#if defined(__GNUC__) && __GNUC__ < 3
-namespace std { typedef ios ios_base; }
-#endif
-
-// check for the 720 compiler on the SGI
-// which has some strange properties that I don't think are worth
-// checking for in a general way in configure
-#if defined(__sgi) && !defined(__GNUC__)
-# if (_COMPILER_VERSION >= 730)
-# define CM_SGI_CC_730
-# elif (_COMPILER_VERSION >= 720)
-# define CM_HAS_STD_BUT_NOT_FOR_IOSTREAM
-# endif
-#endif
-
-#ifdef __DECCXX_VER
-# if __DECCXX_VER <= 60390008
-# define CM_HAS_STD_BUT_NOT_FOR_IOSTREAM
-# endif
-#endif
-
#if defined( _MSC_VER )
typedef unsigned short mode_t;
-#endif
-
-
-#ifdef CM_HAS_STD_BUT_NOT_FOR_IOSTREAM
-// some compilers have std:: but not for the stream library,
-// so we have to bring it into the std namespace by hand.
-namespace std {
-using ::ostream;
-using ::istream;
-using ::ios;
-using ::cout;
-using ::cerr;
-using ::cin;
-using ::ifstream;
-using ::ofstream;
-
-#if !defined(CMAKE_NO_ANSI_STRING_STREAM)
- using ::ostringstream;
- using ::istringstream;
#else
- using ::ostrstream;
- using ::istrstream;
-#endif
-
-using ::endl;
-using ::ends;
-using ::flush;
-using ::dec;
-using ::hex;
-using ::setw;
-using ::setiosflags;
-using ::setfill;
-using ::setprecision;
-}
-// The string class is missing these operators so add them
-#if !defined(cmsys_STL_STRING_NEQ_CHAR_DEFINED)
-# define cmsys_STL_STRING_NO_NEQ_CHAR
-inline bool operator!=(std::string const& a, const char* b)
-{ return !(a==std::string(b)); }
-#endif
-
-inline bool operator==(std::string const& a, const char* b)
-{ return (a==std::string(b)); }
-# endif // end CM_SGI_CC_720
-
-#if defined(__sgi) && !defined(__GNUC__)
-# pragma set woff 1375 /* base class destructor not virtual */
+# include <sys/types.h>
#endif
// use this class to shrink the size of symbols in .o files
// std::string is really basic_string<....lots of stuff....>
// when combined with a map or set, the symbols can be > 2000 chars!
#include <cmsys/String.hxx>
-typedef cmsys::String cmStdString;
-
-// Define cmOStringStream and cmIStringStream wrappers to hide
-// differences between std::stringstream and the old strstream.
-#if !defined(CMAKE_NO_ANSI_STRING_STREAM)
-class cmOStringStream: public std::ostringstream
-{
-public:
- cmOStringStream();
- ~cmOStringStream();
-private:
- cmOStringStream(const cmOStringStream&);
- void operator=(const cmOStringStream&);
-};
-class cmIStringStream: public std::istringstream
-{
-public:
- typedef std::istringstream Superclass;
- cmIStringStream() {}
- cmIStringStream(const std::string& s): Superclass(s) {}
-private:
- cmIStringStream(const cmIStringStream&);
- void operator=(const cmIStringStream&);
-};
-#else
-class cmOStrStreamCleanup
-{
-public:
- cmOStrStreamCleanup(std::ostrstream& ostr): OStrStream(ostr) {}
- ~cmOStrStreamCleanup() { this->OStrStream.rdbuf()->freeze(0); }
- static void IgnoreUnusedVariable(const cmOStrStreamCleanup&) {}
-protected:
- std::ostrstream& OStrStream;
-};
-
-class cmOStringStream: public std::ostrstream
-{
-public:
- typedef std::ostrstream Superclass;
- cmOStringStream() {}
- std::string str()
- {
- cmOStrStreamCleanup cleanup(*this);
- cmOStrStreamCleanup::IgnoreUnusedVariable(cleanup);
- int pcount = this->pcount();
- const char* ptr = this->Superclass::str();
- return std::string(ptr?ptr:"", pcount);
- }
-private:
- cmOStringStream(const cmOStringStream&);
- void operator=(const cmOStringStream&);
-};
-
-class cmIStringStream: private std::string, public std::istrstream
-{
-public:
- typedef std::string StdString;
- typedef std::istrstream IStrStream;
- cmIStringStream(): StdString(), IStrStream(StdString::c_str()) {}
- cmIStringStream(const std::string& s):
- StdString(s), IStrStream(StdString::c_str()) {}
- std::string str() const { return *this; }
- void str(const std::string& s)
- {
- // Very dangerous. If this throws, the object is hosed. When the
- // destructor is later called, the program is hosed too.
- this->~cmIStringStream();
- new (this) cmIStringStream(s);
- }
-private:
- cmIStringStream(const cmIStringStream&);
- void operator=(const cmIStringStream&);
-};
-#endif
+//typedef cmsys::String std::string;
/* Poison this operator to avoid common mistakes. */
-extern void operator << (std::ostream&, const cmOStringStream&);
+extern void operator << (std::ostream&, const std::ostringstream&);
/** Standard documentation entry for cmDocumentation's formatting. */
struct cmDocumentationEntry
{
std::string Name;
std::string Brief;
- std::string Full;
- cmDocumentationEntry(){};
- cmDocumentationEntry(const char *doc[3])
+ cmDocumentationEntry(){}
+ cmDocumentationEntry(const char *doc[2])
{ if (doc[0]) this->Name = doc[0];
- if (doc[1]) this->Brief = doc[1];
- if (doc[2]) this->Full = doc[2]; };
- cmDocumentationEntry(const char *n, const char *b, const char *f)
- { if (n) this->Name = n; if (b) this->Brief = b; if (f) this->Full = f; };
+ if (doc[1]) this->Brief = doc[1];}
+ cmDocumentationEntry(const char *n, const char *b)
+ { if (n) this->Name = n; if (b) this->Brief = b; }
};
/** Data structure to represent a single command line. */
@@ -349,10 +98,6 @@ public:
typedef Superclass::const_iterator const_iterator;
};
-#if defined(__sgi) && !defined(__GNUC__)
-# pragma reset woff 1375 /* base class destructor not virtual */
-#endif
-
// All subclasses of cmCommand or cmCTestGenericHandler should
// invoke this macro.
#define cmTypeMacro(thisClass,superclass) \
@@ -377,8 +122,13 @@ static thisClass* SafeDownCast(cmObject *c) \
return static_cast<thisClass *>(c); \
} \
return 0;\
-}
-
+} \
+class cmTypeMacro_UseTrailingSemicolon
+enum cmTargetLinkLibraryType {
+ GENERAL_LibraryType,
+ DEBUG_LibraryType,
+ OPTIMIZED_LibraryType
+};
#endif
diff --git a/Source/cmStandardLexer.h b/Source/cmStandardLexer.h
index acd636c43..bd08ac7da 100644
--- a/Source/cmStandardLexer.h
+++ b/Source/cmStandardLexer.h
@@ -25,31 +25,6 @@
# pragma warning ( disable : 4786 )
#endif
-#if defined(__BORLANDC__)
-# pragma warn -8008 /* condition always returns true */
-# pragma warn -8066 /* unreachable code */
-#endif
-
-/* Borland system header defines these macros without first undef-ing them. */
-#if defined(__BORLANDC__) && __BORLANDC__ >= 0x580
-# undef INT8_MIN
-# undef INT16_MIN
-# undef INT32_MIN
-# undef INT8_MAX
-# undef INT16_MAX
-# undef INT32_MAX
-# undef UINT8_MAX
-# undef UINT16_MAX
-# undef UINT32_MAX
-# include <stdint.h>
-#endif
-
-/* Make sure SGI termios does not define ECHO differently. */
-#if defined(__sgi) && !defined(__GNUC__)
-# include <sys/termios.h>
-# undef ECHO
-#endif
-
/* Define isatty on windows. */
#if defined(_WIN32) && !defined(__CYGWIN__)
# include <io.h>
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
new file mode 100644
index 000000000..b8e604b2c
--- /dev/null
+++ b/Source/cmState.cxx
@@ -0,0 +1,2010 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Stephen Kelly <steveire@gmail.com>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmState.h"
+
+#include "cmake.h"
+#include "cmVersion.h"
+#include "cmCacheManager.h"
+#include "cmCommand.h"
+#include "cmAlgorithms.h"
+#include "cmDefinitions.h"
+
+#include <assert.h>
+
+struct cmState::SnapshotDataType
+{
+ cmState::PositionType ScopeParent;
+ cmState::PositionType DirectoryParent;
+ cmLinkedTree<cmState::PolicyStackEntry>::iterator Policies;
+ cmLinkedTree<cmState::PolicyStackEntry>::iterator PolicyRoot;
+ cmLinkedTree<cmState::PolicyStackEntry>::iterator PolicyScope;
+ cmState::SnapshotType SnapshotType;
+ bool Keep;
+ cmLinkedTree<std::string>::iterator ExecutionListFile;
+ cmLinkedTree<cmState::BuildsystemDirectoryStateType>::iterator
+ BuildSystemDirectory;
+ cmLinkedTree<cmDefinitions>::iterator Vars;
+ cmLinkedTree<cmDefinitions>::iterator Root;
+ cmLinkedTree<cmDefinitions>::iterator Parent;
+ std::string EntryPointCommand;
+ long EntryPointLine;
+ std::vector<std::string>::size_type IncludeDirectoryPosition;
+ std::vector<std::string>::size_type CompileDefinitionsPosition;
+ std::vector<std::string>::size_type CompileOptionsPosition;
+};
+
+struct cmState::PolicyStackEntry: public cmPolicies::PolicyMap
+{
+ typedef cmPolicies::PolicyMap derived;
+ PolicyStackEntry(bool w = false): derived(), Weak(w) {}
+ PolicyStackEntry(derived const& d, bool w): derived(d), Weak(w) {}
+ PolicyStackEntry(PolicyStackEntry const& r): derived(r), Weak(r.Weak) {}
+ bool Weak;
+};
+
+struct cmState::BuildsystemDirectoryStateType
+{
+ cmState::PositionType DirectoryEnd;
+
+ std::string Location;
+ std::string OutputLocation;
+
+ std::vector<std::string> CurrentSourceDirectoryComponents;
+ std::vector<std::string> CurrentBinaryDirectoryComponents;
+ // The top-most directories for relative path conversion. Both the
+ // source and destination location of a relative path conversion
+ // must be underneath one of these directories (both under source or
+ // both under binary) in order for the relative path to be evaluated
+ // safely by the build tools.
+ std::string RelativePathTopSource;
+ std::string RelativePathTopBinary;
+
+ std::vector<std::string> IncludeDirectories;
+ std::vector<cmListFileBacktrace> IncludeDirectoryBacktraces;
+
+ std::vector<std::string> CompileDefinitions;
+ std::vector<cmListFileBacktrace> CompileDefinitionsBacktraces;
+
+ std::vector<std::string> CompileOptions;
+ std::vector<cmListFileBacktrace> CompileOptionsBacktraces;
+
+ std::string ProjectName;
+
+ cmPropertyMap Properties;
+
+ std::vector<cmState::Snapshot> Children;
+};
+
+cmState::cmState()
+ : IsInTryCompile(false),
+ WindowsShell(false),
+ WindowsVSIDE(false),
+ WatcomWMake(false),
+ MinGWMake(false),
+ NMake(false),
+ MSYSShell(false)
+{
+ this->CacheManager = new cmCacheManager;
+}
+
+cmState::~cmState()
+{
+ delete this->CacheManager;
+ cmDeleteAll(this->Commands);
+}
+
+const char* cmState::GetTargetTypeName(cmState::TargetType targetType)
+{
+ switch( targetType )
+ {
+ case cmState::STATIC_LIBRARY:
+ return "STATIC_LIBRARY";
+ case cmState::MODULE_LIBRARY:
+ return "MODULE_LIBRARY";
+ case cmState::SHARED_LIBRARY:
+ return "SHARED_LIBRARY";
+ case cmState::OBJECT_LIBRARY:
+ return "OBJECT_LIBRARY";
+ case cmState::EXECUTABLE:
+ return "EXECUTABLE";
+ case cmState::UTILITY:
+ return "UTILITY";
+ case cmState::GLOBAL_TARGET:
+ return "GLOBAL_TARGET";
+ case cmState::INTERFACE_LIBRARY:
+ return "INTERFACE_LIBRARY";
+ case cmState::UNKNOWN_LIBRARY:
+ return "UNKNOWN_LIBRARY";
+ }
+ assert(0 && "Unexpected target type");
+ return 0;
+}
+
+const char* cmCacheEntryTypes[] =
+{ "BOOL",
+ "PATH",
+ "FILEPATH",
+ "STRING",
+ "INTERNAL",
+ "STATIC",
+ "UNINITIALIZED",
+ 0
+};
+
+const char*
+cmState::CacheEntryTypeToString(cmState::CacheEntryType type)
+{
+ if ( type > 6 )
+ {
+ return cmCacheEntryTypes[6];
+ }
+ return cmCacheEntryTypes[type];
+}
+
+cmState::CacheEntryType
+cmState::StringToCacheEntryType(const char* s)
+{
+ int i = 0;
+ while(cmCacheEntryTypes[i])
+ {
+ if(strcmp(s, cmCacheEntryTypes[i]) == 0)
+ {
+ return static_cast<cmState::CacheEntryType>(i);
+ }
+ ++i;
+ }
+ return STRING;
+}
+
+bool cmState::IsCacheEntryType(std::string const& key)
+{
+ for(int i=0; cmCacheEntryTypes[i]; ++i)
+ {
+ if(strcmp(key.c_str(), cmCacheEntryTypes[i]) == 0)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool cmState::LoadCache(const std::string& path, bool internal,
+ std::set<std::string>& excludes,
+ std::set<std::string>& includes)
+{
+ return this->CacheManager->LoadCache(path, internal,
+ excludes, includes);
+}
+
+bool cmState::SaveCache(const std::string& path)
+{
+ return this->CacheManager->SaveCache(path);
+}
+
+bool cmState::DeleteCache(const std::string& path)
+{
+ return this->CacheManager->DeleteCache(path);
+}
+
+std::vector<std::string> cmState::GetCacheEntryKeys() const
+{
+ std::vector<std::string> definitions;
+ definitions.reserve(this->CacheManager->GetSize());
+ cmCacheManager::CacheIterator cit =
+ this->CacheManager->GetCacheIterator();
+ for ( cit.Begin(); !cit.IsAtEnd(); cit.Next() )
+ {
+ definitions.push_back(cit.GetName());
+ }
+ return definitions;
+}
+
+const char* cmState::GetCacheEntryValue(std::string const& key) const
+{
+ cmCacheManager::CacheEntry* e = this->CacheManager
+ ->GetCacheEntry(key);
+ if (!e)
+ {
+ return 0;
+ }
+ return e->Value.c_str();
+}
+
+const char*
+cmState::GetInitializedCacheValue(std::string const& key) const
+{
+ return this->CacheManager->GetInitializedCacheValue(key);
+}
+
+cmState::CacheEntryType
+cmState::GetCacheEntryType(std::string const& key) const
+{
+ cmCacheManager::CacheIterator it =
+ this->CacheManager->GetCacheIterator(key.c_str());
+ return it.GetType();
+}
+
+void cmState::SetCacheEntryValue(std::string const& key,
+ std::string const& value)
+{
+ this->CacheManager->SetCacheEntryValue(key, value);
+}
+
+void cmState::SetCacheEntryProperty(std::string const& key,
+ std::string const& propertyName,
+ std::string const& value)
+{
+ cmCacheManager::CacheIterator it =
+ this->CacheManager->GetCacheIterator(key.c_str());
+ it.SetProperty(propertyName, value.c_str());
+}
+
+void cmState::SetCacheEntryBoolProperty(std::string const& key,
+ std::string const& propertyName,
+ bool value)
+{
+ cmCacheManager::CacheIterator it =
+ this->CacheManager->GetCacheIterator(key.c_str());
+ it.SetProperty(propertyName, value);
+}
+
+const char* cmState::GetCacheEntryProperty(std::string const& key,
+ std::string const& propertyName)
+{
+ cmCacheManager::CacheIterator it = this->CacheManager
+ ->GetCacheIterator(key.c_str());
+ if (!it.PropertyExists(propertyName))
+ {
+ return 0;
+ }
+ return it.GetProperty(propertyName);
+}
+
+bool cmState::GetCacheEntryPropertyAsBool(std::string const& key,
+ std::string const& propertyName)
+{
+ return this->CacheManager
+ ->GetCacheIterator(key.c_str()).GetPropertyAsBool(propertyName);
+}
+
+void cmState::AddCacheEntry(const std::string& key, const char* value,
+ const char* helpString,
+ cmState::CacheEntryType type)
+{
+ this->CacheManager->AddCacheEntry(key, value,
+ helpString, type);
+}
+
+void cmState::RemoveCacheEntry(std::string const& key)
+{
+ this->CacheManager->RemoveCacheEntry(key);
+}
+
+void cmState::AppendCacheEntryProperty(const std::string& key,
+ const std::string& property,
+ const std::string& value,
+ bool asString)
+{
+ this->CacheManager
+ ->GetCacheIterator(key.c_str()).AppendProperty(property,
+ value.c_str(),
+ asString);
+}
+
+void cmState::RemoveCacheEntryProperty(std::string const& key,
+ std::string const& propertyName)
+{
+ this->CacheManager
+ ->GetCacheIterator(key.c_str()).SetProperty(propertyName, (void*)0);
+}
+
+cmState::Snapshot cmState::Reset()
+{
+ this->GlobalProperties.clear();
+ this->PropertyDefinitions.clear();
+
+ PositionType pos = this->SnapshotData.Truncate();
+ this->ExecutionListFiles.Truncate();
+
+ {
+ cmLinkedTree<BuildsystemDirectoryStateType>::iterator it =
+ this->BuildsystemDirectory.Truncate();
+ it->IncludeDirectories.clear();
+ it->IncludeDirectoryBacktraces.clear();
+ it->CompileDefinitions.clear();
+ it->CompileDefinitionsBacktraces.clear();
+ it->CompileOptions.clear();
+ it->CompileOptionsBacktraces.clear();
+ it->DirectoryEnd = pos;
+ it->Properties.clear();
+ it->Children.clear();
+ }
+
+ this->PolicyStack.Clear();
+ pos->Policies = this->PolicyStack.Root();
+ pos->PolicyRoot = this->PolicyStack.Root();
+ pos->PolicyScope = this->PolicyStack.Root();
+ assert(pos->Policies.IsValid());
+ assert(pos->PolicyRoot.IsValid());
+
+ {
+ std::string srcDir =
+ cmDefinitions::Get("CMAKE_SOURCE_DIR", pos->Vars, pos->Root);
+ std::string binDir =
+ cmDefinitions::Get("CMAKE_BINARY_DIR", pos->Vars, pos->Root);
+ this->VarTree.Clear();
+ pos->Vars = this->VarTree.Push(this->VarTree.Root());
+ pos->Parent = this->VarTree.Root();
+ pos->Root = this->VarTree.Root();
+
+ pos->Vars->Set("CMAKE_SOURCE_DIR", srcDir.c_str());
+ pos->Vars->Set("CMAKE_BINARY_DIR", binDir.c_str());
+ }
+
+ this->DefineProperty
+ ("RULE_LAUNCH_COMPILE", cmProperty::DIRECTORY,
+ "", "", true);
+ this->DefineProperty
+ ("RULE_LAUNCH_LINK", cmProperty::DIRECTORY,
+ "", "", true);
+ this->DefineProperty
+ ("RULE_LAUNCH_CUSTOM", cmProperty::DIRECTORY,
+ "", "", true);
+
+ this->DefineProperty
+ ("RULE_LAUNCH_COMPILE", cmProperty::TARGET,
+ "", "", true);
+ this->DefineProperty
+ ("RULE_LAUNCH_LINK", cmProperty::TARGET,
+ "", "", true);
+ this->DefineProperty
+ ("RULE_LAUNCH_CUSTOM", cmProperty::TARGET,
+ "", "", true);
+
+ return Snapshot(this, pos);
+}
+
+void cmState::DefineProperty(const std::string& name,
+ cmProperty::ScopeType scope,
+ const char *ShortDescription,
+ const char *FullDescription,
+ bool chained)
+{
+ this->PropertyDefinitions[scope].DefineProperty(name,scope,ShortDescription,
+ FullDescription,
+ chained);
+}
+
+cmPropertyDefinition const* cmState
+::GetPropertyDefinition(const std::string& name,
+ cmProperty::ScopeType scope) const
+{
+ if (this->IsPropertyDefined(name,scope))
+ {
+ cmPropertyDefinitionMap const& defs =
+ this->PropertyDefinitions.find(scope)->second;
+ return &defs.find(name)->second;
+ }
+ return 0;
+}
+
+bool cmState::IsPropertyDefined(const std::string& name,
+ cmProperty::ScopeType scope) const
+{
+ std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::const_iterator it
+ = this->PropertyDefinitions.find(scope);
+ if (it == this->PropertyDefinitions.end())
+ {
+ return false;
+ }
+ return it->second.IsPropertyDefined(name);
+}
+
+bool cmState::IsPropertyChained(const std::string& name,
+ cmProperty::ScopeType scope) const
+{
+ std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::const_iterator it
+ = this->PropertyDefinitions.find(scope);
+ if (it == this->PropertyDefinitions.end())
+ {
+ return false;
+ }
+ return it->second.IsPropertyChained(name);
+}
+
+void cmState::SetLanguageEnabled(std::string const& l)
+{
+ std::vector<std::string>::iterator it =
+ std::lower_bound(this->EnabledLanguages.begin(),
+ this->EnabledLanguages.end(), l);
+ if (it == this->EnabledLanguages.end() || *it != l)
+ {
+ this->EnabledLanguages.insert(it, l);
+ }
+}
+
+bool cmState::GetLanguageEnabled(std::string const& l) const
+{
+ return std::binary_search(this->EnabledLanguages.begin(),
+ this->EnabledLanguages.end(), l);
+}
+
+std::vector<std::string> cmState::GetEnabledLanguages() const
+{
+ return this->EnabledLanguages;
+}
+
+void cmState::SetEnabledLanguages(std::vector<std::string> const& langs)
+{
+ this->EnabledLanguages = langs;
+}
+
+void cmState::ClearEnabledLanguages()
+{
+ this->EnabledLanguages.clear();
+}
+
+bool cmState::GetIsInTryCompile() const
+{
+ return this->IsInTryCompile;
+}
+
+void cmState::SetIsInTryCompile(bool b)
+{
+ this->IsInTryCompile = b;
+}
+
+void cmState::RenameCommand(std::string const& oldName,
+ std::string const& newName)
+{
+ // if the command already exists, free the old one
+ std::string sOldName = cmSystemTools::LowerCase(oldName);
+ std::string sNewName = cmSystemTools::LowerCase(newName);
+ std::map<std::string, cmCommand*>::iterator pos =
+ this->Commands.find(sOldName);
+ if ( pos == this->Commands.end() )
+ {
+ return;
+ }
+ cmCommand* cmd = pos->second;
+
+ pos = this->Commands.find(sNewName);
+ if (pos != this->Commands.end())
+ {
+ delete pos->second;
+ this->Commands.erase(pos);
+ }
+ this->Commands.insert(std::make_pair(sNewName, cmd));
+ pos = this->Commands.find(sOldName);
+ this->Commands.erase(pos);
+}
+
+void cmState::AddCommand(cmCommand* command)
+{
+ std::string name = cmSystemTools::LowerCase(command->GetName());
+ // if the command already exists, free the old one
+ std::map<std::string, cmCommand*>::iterator pos = this->Commands.find(name);
+ if (pos != this->Commands.end())
+ {
+ delete pos->second;
+ this->Commands.erase(pos);
+ }
+ this->Commands.insert(std::make_pair(name, command));
+}
+
+void cmState::RemoveUnscriptableCommands()
+{
+ std::vector<std::string> unscriptableCommands;
+ for (std::map<std::string, cmCommand*>::iterator
+ pos = this->Commands.begin();
+ pos != this->Commands.end(); )
+ {
+ if (!pos->second->IsScriptable())
+ {
+ delete pos->second;
+ this->Commands.erase(pos++);
+ }
+ else
+ {
+ ++pos;
+ }
+ }
+}
+
+cmCommand* cmState::GetCommand(std::string const& name) const
+{
+ cmCommand* command = 0;
+ std::string sName = cmSystemTools::LowerCase(name);
+ std::map<std::string, cmCommand*>::const_iterator pos =
+ this->Commands.find(sName);
+ if (pos != this->Commands.end())
+ {
+ command = (*pos).second;
+ }
+ return command;
+}
+
+std::vector<std::string> cmState::GetCommandNames() const
+{
+ std::vector<std::string> commandNames;
+ commandNames.reserve(this->Commands.size());
+ std::map<std::string, cmCommand*>::const_iterator cmds
+ = this->Commands.begin();
+ for ( ; cmds != this->Commands.end(); ++ cmds )
+ {
+ commandNames.push_back(cmds->first);
+ }
+ return commandNames;
+}
+
+void cmState::RemoveUserDefinedCommands()
+{
+ std::vector<cmCommand*> renamedCommands;
+ for(std::map<std::string, cmCommand*>::iterator j = this->Commands.begin();
+ j != this->Commands.end(); )
+ {
+ if (j->second->IsA("cmMacroHelperCommand") ||
+ j->second->IsA("cmFunctionHelperCommand"))
+ {
+ delete j->second;
+ this->Commands.erase(j++);
+ }
+ else if (j->first != j->second->GetName())
+ {
+ renamedCommands.push_back(j->second);
+ this->Commands.erase(j++);
+ }
+ else
+ {
+ ++j;
+ }
+ }
+ for (std::vector<cmCommand*>::const_iterator it = renamedCommands.begin();
+ it != renamedCommands.end(); ++it)
+ {
+ this->Commands[cmSystemTools::LowerCase((*it)->GetName())] = *it;
+ }
+}
+
+void cmState::SetGlobalProperty(const std::string& prop, const char* value)
+{
+ this->GlobalProperties.SetProperty(prop, value);
+}
+
+void cmState::AppendGlobalProperty(const std::string& prop,
+ const char* value, bool asString)
+{
+ this->GlobalProperties.AppendProperty(prop, value, asString);
+}
+
+const char *cmState::GetGlobalProperty(const std::string& prop)
+{
+ if ( prop == "CACHE_VARIABLES" )
+ {
+ std::vector<std::string> cacheKeys = this->GetCacheEntryKeys();
+ this->SetGlobalProperty("CACHE_VARIABLES", cmJoin(cacheKeys, ";").c_str());
+ }
+ else if ( prop == "COMMANDS" )
+ {
+ std::vector<std::string> commands = this->GetCommandNames();
+ this->SetGlobalProperty("COMMANDS", cmJoin(commands, ";").c_str());
+ }
+ else if ( prop == "IN_TRY_COMPILE" )
+ {
+ this->SetGlobalProperty("IN_TRY_COMPILE",
+ this->IsInTryCompile ? "1" : "0");
+ }
+ else if ( prop == "ENABLED_LANGUAGES" )
+ {
+ std::string langs;
+ langs = cmJoin(this->EnabledLanguages, ";");
+ this->SetGlobalProperty("ENABLED_LANGUAGES", langs.c_str());
+ }
+#define STRING_LIST_ELEMENT(F) ";" #F
+ if (prop == "CMAKE_C_KNOWN_FEATURES")
+ {
+ return FOR_EACH_C_FEATURE(STRING_LIST_ELEMENT) + 1;
+ }
+ if (prop == "CMAKE_CXX_KNOWN_FEATURES")
+ {
+ return FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT) + 1;
+ }
+#undef STRING_LIST_ELEMENT
+ return this->GlobalProperties.GetPropertyValue(prop);
+}
+
+bool cmState::GetGlobalPropertyAsBool(const std::string& prop)
+{
+ return cmSystemTools::IsOn(this->GetGlobalProperty(prop));
+}
+
+void cmState::SetSourceDirectory(std::string const& sourceDirectory)
+{
+ this->SourceDirectory = sourceDirectory;
+ cmSystemTools::ConvertToUnixSlashes(this->SourceDirectory);
+
+ cmSystemTools::SplitPath(
+ cmSystemTools::CollapseFullPath(this->SourceDirectory),
+ this->SourceDirectoryComponents);
+}
+
+const char* cmState::GetSourceDirectory() const
+{
+ return this->SourceDirectory.c_str();
+}
+
+std::vector<std::string> const& cmState::GetSourceDirectoryComponents() const
+{
+ return this->SourceDirectoryComponents;
+}
+
+void cmState::SetBinaryDirectory(std::string const& binaryDirectory)
+{
+ this->BinaryDirectory = binaryDirectory;
+ cmSystemTools::ConvertToUnixSlashes(this->BinaryDirectory);
+
+ cmSystemTools::SplitPath(
+ cmSystemTools::CollapseFullPath(this->BinaryDirectory),
+ this->BinaryDirectoryComponents);
+}
+
+void cmState::SetWindowsShell(bool windowsShell)
+{
+ this->WindowsShell = windowsShell;
+}
+
+bool cmState::UseWindowsShell() const
+{
+ return this->WindowsShell;
+}
+
+void cmState::SetWindowsVSIDE(bool windowsVSIDE)
+{
+ this->WindowsVSIDE = windowsVSIDE;
+}
+
+bool cmState::UseWindowsVSIDE() const
+{
+ return this->WindowsVSIDE;
+}
+
+void cmState::SetWatcomWMake(bool watcomWMake)
+{
+ this->WatcomWMake = watcomWMake;
+}
+
+bool cmState::UseWatcomWMake() const
+{
+ return this->WatcomWMake;
+}
+
+void cmState::SetMinGWMake(bool minGWMake)
+{
+ this->MinGWMake = minGWMake;
+}
+
+bool cmState::UseMinGWMake() const
+{
+ return this->MinGWMake;
+}
+
+void cmState::SetNMake(bool nMake)
+{
+ this->NMake = nMake;
+}
+
+bool cmState::UseNMake() const
+{
+ return this->NMake;
+}
+
+void cmState::SetMSYSShell(bool mSYSShell)
+{
+ this->MSYSShell = mSYSShell;
+}
+
+bool cmState::UseMSYSShell() const
+{
+ return this->MSYSShell;
+}
+
+unsigned int cmState::GetCacheMajorVersion() const
+{
+ return this->CacheManager->GetCacheMajorVersion();
+}
+
+unsigned int cmState::GetCacheMinorVersion() const
+{
+ return this->CacheManager->GetCacheMinorVersion();
+}
+
+const char* cmState::GetBinaryDirectory() const
+{
+ return this->BinaryDirectory.c_str();
+}
+
+std::vector<std::string> const& cmState::GetBinaryDirectoryComponents() const
+{
+ return this->BinaryDirectoryComponents;
+}
+
+void cmState::Directory::ComputeRelativePathTopSource()
+{
+ // Relative path conversion inside the source tree is not used to
+ // construct relative paths passed to build tools so it is safe to use
+ // even when the source is a network path.
+
+ cmState::Snapshot snapshot = this->Snapshot_;
+ std::vector<cmState::Snapshot> snapshots;
+ snapshots.push_back(snapshot);
+ while (true)
+ {
+ snapshot = snapshot.GetBuildsystemDirectoryParent();
+ if (snapshot.IsValid())
+ {
+ snapshots.push_back(snapshot);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ std::string result = snapshots.front().GetDirectory().GetCurrentSource();
+
+ for (std::vector<cmState::Snapshot>::const_iterator it =
+ snapshots.begin() + 1; it != snapshots.end(); ++it)
+ {
+ std::string currentSource = it->GetDirectory().GetCurrentSource();
+ if(cmSystemTools::IsSubDirectory(result, currentSource))
+ {
+ result = currentSource;
+ }
+ }
+ this->DirectoryState->RelativePathTopSource = result;
+}
+
+void cmState::Directory::ComputeRelativePathTopBinary()
+{
+ cmState::Snapshot snapshot = this->Snapshot_;
+ std::vector<cmState::Snapshot> snapshots;
+ snapshots.push_back(snapshot);
+ while (true)
+ {
+ snapshot = snapshot.GetBuildsystemDirectoryParent();
+ if (snapshot.IsValid())
+ {
+ snapshots.push_back(snapshot);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ std::string result =
+ snapshots.front().GetDirectory().GetCurrentBinary();
+
+ for (std::vector<cmState::Snapshot>::const_iterator it =
+ snapshots.begin() + 1; it != snapshots.end(); ++it)
+ {
+ std::string currentBinary = it->GetDirectory().GetCurrentBinary();
+ if(cmSystemTools::IsSubDirectory(result, currentBinary))
+ {
+ result = currentBinary;
+ }
+ }
+
+ // The current working directory on Windows cannot be a network
+ // path. Therefore relative paths cannot work when the binary tree
+ // is a network path.
+ if(result.size() < 2 || result.substr(0, 2) != "//")
+ {
+ this->DirectoryState->RelativePathTopBinary = result;
+ }
+ else
+ {
+ this->DirectoryState->RelativePathTopBinary = "";
+ }
+}
+
+cmState::Snapshot cmState::CreateBaseSnapshot()
+{
+ PositionType pos = this->SnapshotData.Push(this->SnapshotData.Root());
+ pos->DirectoryParent = this->SnapshotData.Root();
+ pos->ScopeParent = this->SnapshotData.Root();
+ pos->SnapshotType = BaseType;
+ pos->Keep = true;
+ pos->BuildSystemDirectory =
+ this->BuildsystemDirectory.Push(this->BuildsystemDirectory.Root());
+ pos->ExecutionListFile =
+ this->ExecutionListFiles.Push(this->ExecutionListFiles.Root());
+ pos->IncludeDirectoryPosition = 0;
+ pos->CompileDefinitionsPosition = 0;
+ pos->CompileOptionsPosition = 0;
+ pos->BuildSystemDirectory->DirectoryEnd = pos;
+ pos->Policies = this->PolicyStack.Root();
+ pos->PolicyRoot = this->PolicyStack.Root();
+ pos->PolicyScope = this->PolicyStack.Root();
+ assert(pos->Policies.IsValid());
+ assert(pos->PolicyRoot.IsValid());
+ pos->Vars = this->VarTree.Push(this->VarTree.Root());
+ assert(pos->Vars.IsValid());
+ pos->Parent = this->VarTree.Root();
+ pos->Root = this->VarTree.Root();
+ return cmState::Snapshot(this, pos);
+}
+
+cmState::Snapshot
+cmState::CreateBuildsystemDirectorySnapshot(Snapshot originSnapshot,
+ std::string const& entryPointCommand,
+ long entryPointLine)
+{
+ assert(originSnapshot.IsValid());
+ PositionType pos = this->SnapshotData.Push(originSnapshot.Position);
+ pos->EntryPointLine = entryPointLine;
+ pos->EntryPointCommand = entryPointCommand;
+ pos->DirectoryParent = originSnapshot.Position;
+ pos->ScopeParent = originSnapshot.Position;
+ pos->SnapshotType = BuildsystemDirectoryType;
+ pos->Keep = true;
+ pos->BuildSystemDirectory =
+ this->BuildsystemDirectory.Push(
+ originSnapshot.Position->BuildSystemDirectory);
+ pos->ExecutionListFile =
+ this->ExecutionListFiles.Push(
+ originSnapshot.Position->ExecutionListFile);
+ pos->BuildSystemDirectory->DirectoryEnd = pos;
+ pos->Policies = originSnapshot.Position->Policies;
+ pos->PolicyRoot = originSnapshot.Position->Policies;
+ pos->PolicyScope = originSnapshot.Position->Policies;
+ assert(pos->Policies.IsValid());
+ assert(pos->PolicyRoot.IsValid());
+
+ cmLinkedTree<cmDefinitions>::iterator origin =
+ originSnapshot.Position->Vars;
+ pos->Parent = origin;
+ pos->Root = origin;
+ pos->Vars = this->VarTree.Push(origin);
+
+ cmState::Snapshot snapshot = cmState::Snapshot(this, pos);
+ originSnapshot.Position->BuildSystemDirectory->Children.push_back(snapshot);
+ snapshot.SetDefaultDefinitions();
+ snapshot.InitializeFromParent();
+ snapshot.SetDirectoryDefinitions();
+ return snapshot;
+}
+
+cmState::Snapshot
+cmState::CreateFunctionCallSnapshot(cmState::Snapshot originSnapshot,
+ std::string const& entryPointCommand,
+ long entryPointLine,
+ std::string const& fileName)
+{
+ PositionType pos = this->SnapshotData.Push(originSnapshot.Position,
+ *originSnapshot.Position);
+ pos->ScopeParent = originSnapshot.Position;
+ pos->EntryPointLine = entryPointLine;
+ pos->EntryPointCommand = entryPointCommand;
+ pos->SnapshotType = FunctionCallType;
+ pos->Keep = false;
+ pos->ExecutionListFile = this->ExecutionListFiles.Push(
+ originSnapshot.Position->ExecutionListFile, fileName);
+ pos->BuildSystemDirectory->DirectoryEnd = pos;
+ pos->PolicyScope = originSnapshot.Position->Policies;
+ assert(originSnapshot.Position->Vars.IsValid());
+ cmLinkedTree<cmDefinitions>::iterator origin =
+ originSnapshot.Position->Vars;
+ pos->Parent = origin;
+ pos->Vars = this->VarTree.Push(origin);
+ return cmState::Snapshot(this, pos);
+}
+
+
+cmState::Snapshot
+cmState::CreateMacroCallSnapshot(cmState::Snapshot originSnapshot,
+ std::string const& entryPointCommand,
+ long entryPointLine,
+ std::string const& fileName)
+{
+ PositionType pos = this->SnapshotData.Push(originSnapshot.Position,
+ *originSnapshot.Position);
+ pos->EntryPointLine = entryPointLine;
+ pos->EntryPointCommand = entryPointCommand;
+ pos->SnapshotType = MacroCallType;
+ pos->Keep = false;
+ pos->ExecutionListFile = this->ExecutionListFiles.Push(
+ originSnapshot.Position->ExecutionListFile, fileName);
+ assert(originSnapshot.Position->Vars.IsValid());
+ pos->BuildSystemDirectory->DirectoryEnd = pos;
+ pos->PolicyScope = originSnapshot.Position->Policies;
+ return cmState::Snapshot(this, pos);
+}
+
+cmState::Snapshot
+cmState::CreateCallStackSnapshot(cmState::Snapshot originSnapshot,
+ const std::string& entryPointCommand,
+ long entryPointLine,
+ const std::string& fileName)
+{
+ PositionType pos = this->SnapshotData.Push(originSnapshot.Position,
+ *originSnapshot.Position);
+ pos->EntryPointLine = entryPointLine;
+ pos->EntryPointCommand = entryPointCommand;
+ pos->SnapshotType = CallStackType;
+ pos->Keep = true;
+ pos->ExecutionListFile = this->ExecutionListFiles.Push(
+ originSnapshot.Position->ExecutionListFile, fileName);
+ assert(originSnapshot.Position->Vars.IsValid());
+ pos->BuildSystemDirectory->DirectoryEnd = pos;
+ pos->PolicyScope = originSnapshot.Position->Policies;
+ return cmState::Snapshot(this, pos);
+}
+
+cmState::Snapshot
+cmState::CreateVariableScopeSnapshot(cmState::Snapshot originSnapshot,
+ std::string const& entryPointCommand,
+ long entryPointLine)
+{
+ PositionType pos = this->SnapshotData.Push(originSnapshot.Position,
+ *originSnapshot.Position);
+ pos->ScopeParent = originSnapshot.Position;
+ pos->EntryPointLine = entryPointLine;
+ pos->EntryPointCommand = entryPointCommand;
+ pos->SnapshotType = VariableScopeType;
+ pos->Keep = false;
+ pos->PolicyScope = originSnapshot.Position->Policies;
+ assert(originSnapshot.Position->Vars.IsValid());
+
+ cmLinkedTree<cmDefinitions>::iterator origin =
+ originSnapshot.Position->Vars;
+ pos->Parent = origin;
+ pos->Vars = this->VarTree.Push(origin);
+ assert(pos->Vars.IsValid());
+ return cmState::Snapshot(this, pos);
+}
+
+cmState::Snapshot
+cmState::CreateInlineListFileSnapshot(cmState::Snapshot originSnapshot,
+ const std::string& entryPointCommand,
+ long entryPointLine,
+ const std::string& fileName)
+{
+ PositionType pos = this->SnapshotData.Push(originSnapshot.Position,
+ *originSnapshot.Position);
+ pos->EntryPointLine = entryPointLine;
+ pos->EntryPointCommand = entryPointCommand;
+ pos->SnapshotType = InlineListFileType;
+ pos->Keep = true;
+ pos->ExecutionListFile = this->ExecutionListFiles.Push(
+ originSnapshot.Position->ExecutionListFile, fileName);
+ pos->BuildSystemDirectory->DirectoryEnd = pos;
+ pos->PolicyScope = originSnapshot.Position->Policies;
+ return cmState::Snapshot(this, pos);
+}
+
+cmState::Snapshot
+cmState::CreatePolicyScopeSnapshot(cmState::Snapshot originSnapshot)
+{
+ PositionType pos = this->SnapshotData.Push(originSnapshot.Position,
+ *originSnapshot.Position);
+ pos->SnapshotType = PolicyScopeType;
+ pos->Keep = false;
+ pos->BuildSystemDirectory->DirectoryEnd = pos;
+ pos->PolicyScope = originSnapshot.Position->Policies;
+ return cmState::Snapshot(this, pos);
+}
+
+cmState::Snapshot cmState::Pop(cmState::Snapshot originSnapshot)
+{
+ PositionType pos = originSnapshot.Position;
+ PositionType prevPos = pos;
+ ++prevPos;
+ prevPos->IncludeDirectoryPosition =
+ prevPos->BuildSystemDirectory->IncludeDirectories.size();
+ prevPos->CompileDefinitionsPosition =
+ prevPos->BuildSystemDirectory->CompileDefinitions.size();
+ prevPos->CompileOptionsPosition =
+ prevPos->BuildSystemDirectory->CompileOptions.size();
+ prevPos->BuildSystemDirectory->DirectoryEnd = prevPos;
+
+ if (!pos->Keep && this->SnapshotData.IsLast(pos))
+ {
+ if (pos->Vars != prevPos->Vars)
+ {
+ assert(this->VarTree.IsLast(pos->Vars));
+ this->VarTree.Pop(pos->Vars);
+ }
+ if (pos->ExecutionListFile != prevPos->ExecutionListFile)
+ {
+ assert(this->ExecutionListFiles.IsLast(pos->ExecutionListFile));
+ this->ExecutionListFiles.Pop(pos->ExecutionListFile);
+ }
+ this->SnapshotData.Pop(pos);
+ }
+
+ return Snapshot(this, prevPos);
+}
+
+cmState::Snapshot::Snapshot(cmState* state)
+ : State(state)
+ , Position()
+{
+}
+
+std::vector<cmState::Snapshot> cmState::Snapshot::GetChildren()
+{
+ return this->Position->BuildSystemDirectory->Children;
+}
+
+cmState::Snapshot::Snapshot(cmState* state, PositionType position)
+ : State(state),
+ Position(position)
+{
+
+}
+
+cmState::SnapshotType cmState::Snapshot::GetType() const
+{
+ return this->Position->SnapshotType;
+}
+
+const char* cmState::Directory::GetCurrentSource() const
+{
+ return this->DirectoryState->Location.c_str();
+}
+
+void cmState::Directory::SetCurrentSource(std::string const& dir)
+{
+ std::string& loc = this->DirectoryState->Location;
+ loc = dir;
+ cmSystemTools::ConvertToUnixSlashes(loc);
+ loc = cmSystemTools::CollapseFullPath(loc);
+
+ cmSystemTools::SplitPath(
+ loc,
+ this->DirectoryState->CurrentSourceDirectoryComponents);
+ this->ComputeRelativePathTopSource();
+
+ this->Snapshot_.SetDefinition("CMAKE_CURRENT_SOURCE_DIR", loc.c_str());
+}
+
+const char* cmState::Directory::GetCurrentBinary() const
+{
+ return this->DirectoryState->OutputLocation.c_str();
+}
+
+void cmState::Directory::SetCurrentBinary(std::string const& dir)
+{
+ std::string& loc = this->DirectoryState->OutputLocation;
+ loc = dir;
+ cmSystemTools::ConvertToUnixSlashes(loc);
+ loc = cmSystemTools::CollapseFullPath(loc);
+
+ cmSystemTools::SplitPath(
+ loc,
+ this->DirectoryState->CurrentBinaryDirectoryComponents);
+ this->ComputeRelativePathTopBinary();
+
+ this->Snapshot_.SetDefinition("CMAKE_CURRENT_BINARY_DIR", loc.c_str());
+}
+
+void cmState::Snapshot::Keep()
+{
+ this->Position->Keep = true;
+}
+
+void cmState::Snapshot::SetListFile(const std::string& listfile)
+{
+ *this->Position->ExecutionListFile = listfile;
+}
+
+std::vector<std::string> const&
+cmState::Directory::GetCurrentSourceComponents() const
+{
+ return this->DirectoryState->CurrentSourceDirectoryComponents;
+}
+
+std::vector<std::string> const&
+cmState::Directory::GetCurrentBinaryComponents() const
+{
+ return this->DirectoryState->CurrentBinaryDirectoryComponents;
+}
+
+const char* cmState::Directory::GetRelativePathTopSource() const
+{
+ return this->DirectoryState->RelativePathTopSource.c_str();
+}
+
+const char* cmState::Directory::GetRelativePathTopBinary() const
+{
+ return this->DirectoryState->RelativePathTopBinary.c_str();
+}
+
+void cmState::Directory::SetRelativePathTopSource(const char* dir)
+{
+ this->DirectoryState->RelativePathTopSource = dir;
+}
+
+void cmState::Directory::SetRelativePathTopBinary(const char* dir)
+{
+ this->DirectoryState->RelativePathTopBinary = dir;
+}
+
+std::string cmState::Snapshot::GetExecutionListFile() const
+{
+ return *this->Position->ExecutionListFile;
+}
+
+std::string cmState::Snapshot::GetEntryPointCommand() const
+{
+ return this->Position->EntryPointCommand;
+}
+
+long cmState::Snapshot::GetEntryPointLine() const
+{
+ return this->Position->EntryPointLine;
+}
+
+bool cmState::Snapshot::IsValid() const
+{
+ return this->State && this->Position.IsValid()
+ ? this->Position != this->State->SnapshotData.Root()
+ : false;
+}
+
+cmState::Snapshot cmState::Snapshot::GetBuildsystemDirectoryParent() const
+{
+ Snapshot snapshot;
+ if (!this->State || this->Position == this->State->SnapshotData.Root())
+ {
+ return snapshot;
+ }
+ PositionType parentPos = this->Position->DirectoryParent;
+ if (parentPos != this->State->SnapshotData.Root())
+ {
+ snapshot = Snapshot(this->State,
+ parentPos->BuildSystemDirectory->DirectoryEnd);
+ }
+
+ return snapshot;
+}
+
+cmState::Snapshot cmState::Snapshot::GetCallStackParent() const
+{
+ assert(this->State);
+ assert(this->Position != this->State->SnapshotData.Root());
+
+ Snapshot snapshot;
+ PositionType parentPos = this->Position;
+ while (parentPos->SnapshotType == cmState::PolicyScopeType ||
+ parentPos->SnapshotType == cmState::VariableScopeType)
+ {
+ ++parentPos;
+ }
+ if (parentPos->SnapshotType == cmState::BuildsystemDirectoryType
+ || parentPos->SnapshotType == cmState::BaseType)
+ {
+ return snapshot;
+ }
+
+ ++parentPos;
+ while (parentPos->SnapshotType == cmState::PolicyScopeType ||
+ parentPos->SnapshotType == cmState::VariableScopeType)
+ {
+ ++parentPos;
+ }
+
+ if (parentPos == this->State->SnapshotData.Root())
+ {
+ return snapshot;
+ }
+
+ snapshot = Snapshot(this->State, parentPos);
+ return snapshot;
+}
+
+void cmState::Snapshot::PushPolicy(cmPolicies::PolicyMap entry, bool weak)
+{
+ PositionType pos = this->Position;
+ pos->Policies =
+ this->State->PolicyStack.Push(pos->Policies,
+ PolicyStackEntry(entry, weak));
+}
+
+bool cmState::Snapshot::PopPolicy()
+{
+ PositionType pos = this->Position;
+ if (pos->Policies == pos->PolicyScope)
+ {
+ return false;
+ }
+ pos->Policies = this->State->PolicyStack.Pop(pos->Policies);
+ return true;
+}
+
+bool cmState::Snapshot::CanPopPolicyScope()
+{
+ return this->Position->Policies == this->Position->PolicyScope;
+}
+
+void cmState::Snapshot::SetPolicy(cmPolicies::PolicyID id,
+ cmPolicies::PolicyStatus status)
+{
+ // Update the policy stack from the top to the top-most strong entry.
+ bool previous_was_weak = true;
+ for(cmLinkedTree<PolicyStackEntry>::iterator psi = this->Position->Policies;
+ previous_was_weak && psi != this->Position->PolicyRoot; ++psi)
+ {
+ psi->Set(id, status);
+ previous_was_weak = psi->Weak;
+ }
+}
+
+cmPolicies::PolicyStatus
+cmState::Snapshot::GetPolicy(cmPolicies::PolicyID id) const
+{
+ cmPolicies::PolicyStatus status = cmPolicies::GetPolicyStatus(id);
+
+ if(status == cmPolicies::REQUIRED_ALWAYS ||
+ status == cmPolicies::REQUIRED_IF_USED)
+ {
+ return status;
+ }
+
+ cmLinkedTree<BuildsystemDirectoryStateType>::iterator dir =
+ this->Position->BuildSystemDirectory;
+
+ while (true)
+ {
+ assert(dir.IsValid());
+ cmLinkedTree<PolicyStackEntry>::iterator leaf =
+ dir->DirectoryEnd->Policies;
+ cmLinkedTree<PolicyStackEntry>::iterator root =
+ dir->DirectoryEnd->PolicyRoot;
+ for( ; leaf != root; ++leaf)
+ {
+ if(leaf->IsDefined(id))
+ {
+ status = leaf->Get(id);
+ return status;
+ }
+ }
+ cmState::PositionType e = dir->DirectoryEnd;
+ cmState::PositionType p = e->DirectoryParent;
+ if (p == this->State->SnapshotData.Root())
+ {
+ break;
+ }
+ dir = p->BuildSystemDirectory;
+ }
+ return status;
+}
+
+bool cmState::Snapshot::HasDefinedPolicyCMP0011()
+{
+ return !this->Position->Policies->IsEmpty();
+}
+
+const char* cmState::Snapshot::GetDefinition(std::string const& name) const
+{
+ assert(this->Position->Vars.IsValid());
+ return cmDefinitions::Get(name, this->Position->Vars,
+ this->Position->Root);
+}
+
+bool cmState::Snapshot::IsInitialized(std::string const& name) const
+{
+ return cmDefinitions::HasKey(name, this->Position->Vars,
+ this->Position->Root);
+}
+
+void cmState::Snapshot::SetDefinition(std::string const& name,
+ std::string const& value)
+{
+ this->Position->Vars->Set(name, value.c_str());
+}
+
+void cmState::Snapshot::RemoveDefinition(std::string const& name)
+{
+ this->Position->Vars->Set(name, 0);
+}
+
+std::vector<std::string> cmState::Snapshot::UnusedKeys() const
+{
+ return this->Position->Vars->UnusedKeys();
+}
+
+std::vector<std::string> cmState::Snapshot::ClosureKeys() const
+{
+ return cmDefinitions::ClosureKeys(this->Position->Vars,
+ this->Position->Root);
+}
+
+bool cmState::Snapshot::RaiseScope(std::string const& var, const char* varDef)
+{
+ if(this->Position->ScopeParent == this->Position->DirectoryParent)
+ {
+ Snapshot parentDir = this->GetBuildsystemDirectoryParent();
+ if(!parentDir.IsValid())
+ {
+ return false;
+ }
+ // Update the definition in the parent directory top scope. This
+ // directory's scope was initialized by the closure of the parent
+ // scope, so we do not need to localize the definition first.
+ if (varDef)
+ {
+ parentDir.SetDefinition(var, varDef);
+ }
+ else
+ {
+ parentDir.RemoveDefinition(var);
+ }
+ return true;
+ }
+ // First localize the definition in the current scope.
+ cmDefinitions::Raise(var, this->Position->Vars,
+ this->Position->Root);
+
+ // Now update the definition in the parent scope.
+ this->Position->Parent->Set(var, varDef);
+ return true;
+}
+
+static const std::string cmPropertySentinal = std::string();
+
+template<typename T, typename U, typename V>
+void InitializeContentFromParent(T& parentContent,
+ T& thisContent,
+ U& parentBacktraces,
+ U& thisBacktraces,
+ V& contentEndPosition)
+{
+ std::vector<std::string>::const_iterator parentBegin =
+ parentContent.begin();
+ std::vector<std::string>::const_iterator parentEnd =
+ parentContent.end();
+
+ std::vector<std::string>::const_reverse_iterator parentRbegin =
+ cmMakeReverseIterator(parentEnd);
+ std::vector<std::string>::const_reverse_iterator parentRend =
+ parentContent.rend();
+ parentRbegin = std::find(parentRbegin, parentRend, cmPropertySentinal);
+ std::vector<std::string>::const_iterator parentIt = parentRbegin.base();
+
+ thisContent = std::vector<std::string>(parentIt, parentEnd);
+
+ std::vector<cmListFileBacktrace>::const_iterator btIt =
+ parentBacktraces.begin() + std::distance(parentBegin, parentIt);
+ std::vector<cmListFileBacktrace>::const_iterator btEnd =
+ parentBacktraces.end();
+
+ thisBacktraces = std::vector<cmListFileBacktrace>(btIt, btEnd);
+
+ contentEndPosition = thisContent.size();
+}
+
+void cmState::Snapshot::SetDefaultDefinitions()
+{
+ /* Up to CMake 2.4 here only WIN32, UNIX and APPLE were set.
+ With CMake must separate between target and host platform. In most cases
+ the tests for WIN32, UNIX and APPLE will be for the target system, so an
+ additional set of variables for the host system is required ->
+ CMAKE_HOST_WIN32, CMAKE_HOST_UNIX, CMAKE_HOST_APPLE.
+ WIN32, UNIX and APPLE are now set in the platform files in
+ Modules/Platforms/.
+ To keep cmake scripts (-P) and custom language and compiler modules
+ working, these variables are still also set here in this place, but they
+ will be reset in CMakeSystemSpecificInformation.cmake before the platform
+ files are executed. */
+ #if defined(_WIN32)
+ this->SetDefinition("WIN32", "1");
+ this->SetDefinition("CMAKE_HOST_WIN32", "1");
+ #else
+ this->SetDefinition("UNIX", "1");
+ this->SetDefinition("CMAKE_HOST_UNIX", "1");
+ #endif
+ #if defined(__CYGWIN__)
+ if(cmSystemTools::IsOn(cmSystemTools::GetEnv("CMAKE_LEGACY_CYGWIN_WIN32")))
+ {
+ this->SetDefinition("WIN32", "1");
+ this->SetDefinition("CMAKE_HOST_WIN32", "1");
+ }
+ #endif
+ #if defined(__APPLE__)
+ this->SetDefinition("APPLE", "1");
+ this->SetDefinition("CMAKE_HOST_APPLE", "1");
+ #endif
+
+ char temp[1024];
+ sprintf(temp, "%d", cmVersion::GetMinorVersion());
+ this->SetDefinition("CMAKE_MINOR_VERSION", temp);
+ sprintf(temp, "%d", cmVersion::GetMajorVersion());
+ this->SetDefinition("CMAKE_MAJOR_VERSION", temp);
+ sprintf(temp, "%d", cmVersion::GetPatchVersion());
+ this->SetDefinition("CMAKE_PATCH_VERSION", temp);
+ sprintf(temp, "%d", cmVersion::GetTweakVersion());
+ this->SetDefinition("CMAKE_TWEAK_VERSION", temp);
+ this->SetDefinition("CMAKE_VERSION",
+ cmVersion::GetCMakeVersion());
+
+ this->SetDefinition("CMAKE_FILES_DIRECTORY",
+ cmake::GetCMakeFilesDirectory());
+
+ // Setup the default include file regular expression (match everything).
+ this->Position->BuildSystemDirectory
+ ->Properties.SetProperty("INCLUDE_REGULAR_EXPRESSION", "^.*$");
+}
+
+void cmState::Snapshot::SetDirectoryDefinitions()
+{
+ this->SetDefinition("CMAKE_SOURCE_DIR",
+ this->State->GetSourceDirectory());
+ this->SetDefinition("CMAKE_CURRENT_SOURCE_DIR",
+ this->State->GetSourceDirectory());
+ this->SetDefinition("CMAKE_BINARY_DIR",
+ this->State->GetBinaryDirectory());
+ this->SetDefinition("CMAKE_CURRENT_BINARY_DIR",
+ this->State->GetBinaryDirectory());
+}
+
+void cmState::Snapshot::InitializeFromParent()
+{
+ PositionType parent = this->Position->DirectoryParent;
+ assert(this->Position->Vars.IsValid());
+ assert(parent->Vars.IsValid());
+
+ *this->Position->Vars =
+ cmDefinitions::MakeClosure(parent->Vars, parent->Root);
+
+ InitializeContentFromParent(parent->BuildSystemDirectory->IncludeDirectories,
+ this->Position->BuildSystemDirectory->IncludeDirectories,
+ parent->BuildSystemDirectory->IncludeDirectoryBacktraces,
+ this->Position->BuildSystemDirectory->IncludeDirectoryBacktraces,
+ this->Position->IncludeDirectoryPosition);
+
+ InitializeContentFromParent(parent->BuildSystemDirectory->CompileDefinitions,
+ this->Position->BuildSystemDirectory->CompileDefinitions,
+ parent->BuildSystemDirectory->CompileDefinitionsBacktraces,
+ this->Position->BuildSystemDirectory->CompileDefinitionsBacktraces,
+ this->Position->CompileDefinitionsPosition);
+
+ InitializeContentFromParent(parent->BuildSystemDirectory->CompileOptions,
+ this->Position->BuildSystemDirectory->CompileOptions,
+ parent->BuildSystemDirectory->CompileOptionsBacktraces,
+ this->Position->BuildSystemDirectory->CompileOptionsBacktraces,
+ this->Position->CompileOptionsPosition);
+}
+
+cmState* cmState::Snapshot::GetState() const
+{
+ return this->State;
+}
+
+cmState::Directory cmState::Snapshot::GetDirectory() const
+{
+ return Directory(this->Position->BuildSystemDirectory, *this);
+}
+
+void cmState::Snapshot::SetProjectName(const std::string& name)
+{
+ this->Position->BuildSystemDirectory->ProjectName = name;
+}
+
+std::string cmState::Snapshot::GetProjectName() const
+{
+ return this->Position->BuildSystemDirectory->ProjectName;
+}
+
+void cmState::Snapshot::InitializeFromParent_ForSubdirsCommand()
+{
+ std::string currentSrcDir = this->GetDefinition("CMAKE_CURRENT_SOURCE_DIR");
+ std::string currentBinDir = this->GetDefinition("CMAKE_CURRENT_BINARY_DIR");
+ this->InitializeFromParent();
+ this->SetDefinition("CMAKE_SOURCE_DIR",
+ this->State->GetSourceDirectory());
+ this->SetDefinition("CMAKE_BINARY_DIR",
+ this->State->GetBinaryDirectory());
+
+ this->SetDefinition("CMAKE_CURRENT_SOURCE_DIR", currentSrcDir.c_str());
+ this->SetDefinition("CMAKE_CURRENT_BINARY_DIR", currentBinDir.c_str());
+}
+
+cmState::Directory::Directory(
+ cmLinkedTree<BuildsystemDirectoryStateType>::iterator iter,
+ const cmState::Snapshot& snapshot)
+ : DirectoryState(iter), Snapshot_(snapshot)
+{
+
+}
+
+template <typename T, typename U>
+cmStringRange GetPropertyContent(T const& content, U contentEndPosition)
+{
+ std::vector<std::string>::const_iterator end =
+ content.begin() + contentEndPosition;
+
+ std::vector<std::string>::const_reverse_iterator rbegin =
+ cmMakeReverseIterator(end);
+ rbegin = std::find(rbegin, content.rend(), cmPropertySentinal);
+
+ return cmMakeRange(rbegin.base(), end);
+}
+
+template <typename T, typename U, typename V>
+cmBacktraceRange GetPropertyBacktraces(T const& content,
+ U const& backtraces,
+ V contentEndPosition)
+{
+ std::vector<std::string>::const_iterator entryEnd =
+ content.begin() + contentEndPosition;
+
+ std::vector<std::string>::const_reverse_iterator rbegin =
+ cmMakeReverseIterator(entryEnd);
+ rbegin = std::find(rbegin, content.rend(), cmPropertySentinal);
+
+ std::vector<cmListFileBacktrace>::const_iterator it =
+ backtraces.begin() + std::distance(content.begin(), rbegin.base());
+
+ std::vector<cmListFileBacktrace>::const_iterator end = backtraces.end();
+ return cmMakeRange(it, end);
+}
+
+template <typename T, typename U, typename V>
+void AppendEntry(T& content, U& backtraces, V& endContentPosition,
+ const std::string& value, const cmListFileBacktrace& lfbt)
+{
+ if (value.empty())
+ {
+ return;
+ }
+
+ assert(endContentPosition == content.size());
+
+ content.push_back(value);
+ backtraces.push_back(lfbt);
+
+ endContentPosition = content.size();
+}
+
+template <typename T, typename U, typename V>
+void SetContent(T& content, U& backtraces, V& endContentPosition,
+ const std::string& vec, const cmListFileBacktrace& lfbt)
+{
+ assert(endContentPosition == content.size());
+
+ content.resize(content.size() + 2);
+ backtraces.resize(backtraces.size() + 2);
+
+ content.back() = vec;
+ backtraces.back() = lfbt;
+
+ endContentPosition = content.size();
+}
+
+template <typename T, typename U, typename V>
+void ClearContent(T& content, U& backtraces, V& endContentPosition)
+{
+ assert(endContentPosition == content.size());
+
+ content.resize(content.size() + 1);
+ backtraces.resize(backtraces.size() + 1);
+
+ endContentPosition = content.size();
+}
+
+cmStringRange
+cmState::Directory::GetIncludeDirectoriesEntries() const
+{
+ return GetPropertyContent(this->DirectoryState->IncludeDirectories,
+ this->Snapshot_.Position->IncludeDirectoryPosition);
+}
+
+cmBacktraceRange
+cmState::Directory::GetIncludeDirectoriesEntryBacktraces() const
+{
+ return GetPropertyBacktraces(this->DirectoryState->IncludeDirectories,
+ this->DirectoryState->IncludeDirectoryBacktraces,
+ this->Snapshot_.Position->IncludeDirectoryPosition);
+}
+
+void cmState::Directory::AppendIncludeDirectoriesEntry(
+ const std::string& vec, const cmListFileBacktrace& lfbt)
+{
+ AppendEntry(this->DirectoryState->IncludeDirectories,
+ this->DirectoryState->IncludeDirectoryBacktraces,
+ this->Snapshot_.Position->IncludeDirectoryPosition,
+ vec, lfbt);
+}
+
+void cmState::Directory::PrependIncludeDirectoriesEntry(
+ const std::string& vec, const cmListFileBacktrace& lfbt)
+{
+ std::vector<std::string>::iterator entryEnd =
+ this->DirectoryState->IncludeDirectories.begin()
+ + this->Snapshot_.Position->IncludeDirectoryPosition;
+
+ std::vector<std::string>::reverse_iterator rend =
+ this->DirectoryState->IncludeDirectories.rend();
+ std::vector<std::string>::reverse_iterator rbegin =
+ cmMakeReverseIterator(entryEnd);
+ rbegin = std::find(rbegin, rend, cmPropertySentinal);
+
+ std::vector<std::string>::iterator entryIt = rbegin.base();
+ std::vector<std::string>::iterator entryBegin =
+ this->DirectoryState->IncludeDirectories.begin();
+
+ std::vector<cmListFileBacktrace>::iterator btIt =
+ this->DirectoryState->IncludeDirectoryBacktraces.begin()
+ + std::distance(entryBegin, entryIt);
+
+ this->DirectoryState->IncludeDirectories.insert(entryIt, vec);
+ this->DirectoryState->IncludeDirectoryBacktraces.insert(btIt, lfbt);
+
+ this->Snapshot_.Position->IncludeDirectoryPosition =
+ this->DirectoryState->IncludeDirectories.size();
+}
+
+void cmState::Directory::SetIncludeDirectories(
+ const std::string& vec, const cmListFileBacktrace& lfbt)
+{
+ SetContent(this->DirectoryState->IncludeDirectories,
+ this->DirectoryState->IncludeDirectoryBacktraces,
+ this->Snapshot_.Position->IncludeDirectoryPosition,
+ vec, lfbt);
+}
+
+void cmState::Directory::ClearIncludeDirectories()
+{
+ ClearContent(this->DirectoryState->IncludeDirectories,
+ this->DirectoryState->IncludeDirectoryBacktraces,
+ this->Snapshot_.Position->IncludeDirectoryPosition);
+}
+
+cmStringRange cmState::Directory::GetCompileDefinitionsEntries() const
+{
+ return GetPropertyContent(this->DirectoryState->CompileDefinitions,
+ this->Snapshot_.Position->CompileDefinitionsPosition);
+}
+
+cmBacktraceRange
+cmState::Directory::GetCompileDefinitionsEntryBacktraces() const
+{
+ return GetPropertyBacktraces(this->DirectoryState->CompileDefinitions,
+ this->DirectoryState->CompileDefinitionsBacktraces,
+ this->Snapshot_.Position->CompileDefinitionsPosition);
+}
+
+void cmState::Directory::AppendCompileDefinitionsEntry(const std::string& vec,
+ const cmListFileBacktrace& lfbt)
+{
+ AppendEntry(this->DirectoryState->CompileDefinitions,
+ this->DirectoryState->CompileDefinitionsBacktraces,
+ this->Snapshot_.Position->CompileDefinitionsPosition,
+ vec, lfbt);
+}
+
+void cmState::Directory::SetCompileDefinitions(const std::string& vec,
+ const cmListFileBacktrace& lfbt)
+{
+ SetContent(this->DirectoryState->CompileDefinitions,
+ this->DirectoryState->CompileDefinitionsBacktraces,
+ this->Snapshot_.Position->CompileDefinitionsPosition,
+ vec, lfbt);
+}
+
+void cmState::Directory::ClearCompileDefinitions()
+{
+ ClearContent(this->DirectoryState->CompileDefinitions,
+ this->DirectoryState->CompileDefinitionsBacktraces,
+ this->Snapshot_.Position->CompileDefinitionsPosition);
+}
+
+cmStringRange cmState::Directory::GetCompileOptionsEntries() const
+{
+ return GetPropertyContent(this->DirectoryState->CompileOptions,
+ this->Snapshot_.Position->CompileOptionsPosition);
+}
+
+cmBacktraceRange cmState::Directory::GetCompileOptionsEntryBacktraces() const
+{
+ return GetPropertyBacktraces(this->DirectoryState->CompileOptions,
+ this->DirectoryState->CompileOptionsBacktraces,
+ this->Snapshot_.Position->CompileOptionsPosition);
+}
+
+void
+cmState::Directory::AppendCompileOptionsEntry(const std::string& vec,
+ const cmListFileBacktrace& lfbt)
+{
+ AppendEntry(this->DirectoryState->CompileOptions,
+ this->DirectoryState->CompileOptionsBacktraces,
+ this->Snapshot_.Position->CompileOptionsPosition,
+ vec, lfbt);
+}
+
+void cmState::Directory::SetCompileOptions(const std::string& vec,
+ const cmListFileBacktrace& lfbt)
+{
+ SetContent(this->DirectoryState->CompileOptions,
+ this->DirectoryState->CompileOptionsBacktraces,
+ this->Snapshot_.Position->CompileOptionsPosition,
+ vec, lfbt);
+}
+
+void cmState::Directory::ClearCompileOptions()
+{
+ ClearContent(this->DirectoryState->CompileOptions,
+ this->DirectoryState->CompileOptionsBacktraces,
+ this->Snapshot_.Position->CompileOptionsPosition);
+}
+
+bool cmState::Snapshot::StrictWeakOrder::operator()(
+ const cmState::Snapshot& lhs, const cmState::Snapshot& rhs) const
+{
+ return lhs.Position.StrictWeakOrdered(rhs.Position);
+}
+
+void cmState::Directory::SetProperty(const std::string& prop,
+ const char* value,
+ cmListFileBacktrace lfbt)
+{
+ if (prop == "INCLUDE_DIRECTORIES")
+ {
+ if (!value)
+ {
+ this->ClearIncludeDirectories();
+ return;
+ }
+ this->SetIncludeDirectories(value, lfbt);
+ return;
+ }
+ if (prop == "COMPILE_OPTIONS")
+ {
+ if (!value)
+ {
+ this->ClearCompileOptions();
+ return;
+ }
+ this->SetCompileOptions(value, lfbt);
+ return;
+ }
+ if (prop == "COMPILE_DEFINITIONS")
+ {
+ if (!value)
+ {
+ this->ClearCompileDefinitions();
+ return;
+ }
+ this->SetCompileDefinitions(value, lfbt);
+ return;
+ }
+
+ this->DirectoryState->Properties.SetProperty(prop, value);
+}
+
+void cmState::Directory::AppendProperty(const std::string& prop,
+ const char* value,
+ bool asString,
+ cmListFileBacktrace lfbt)
+{
+ if (prop == "INCLUDE_DIRECTORIES")
+ {
+ this->AppendIncludeDirectoriesEntry(value, lfbt);
+ return;
+ }
+ if (prop == "COMPILE_OPTIONS")
+ {
+ this->AppendCompileOptionsEntry(value, lfbt);
+ return;
+ }
+ if (prop == "COMPILE_DEFINITIONS")
+ {
+ this->AppendCompileDefinitionsEntry(value, lfbt);
+ return;
+ }
+
+ this->DirectoryState->Properties.AppendProperty(prop, value, asString);
+}
+
+const char*cmState::Directory::GetProperty(const std::string& prop) const
+{
+ const bool chain = this->Snapshot_.State->
+ IsPropertyChained(prop, cmProperty::DIRECTORY);
+ return this->GetProperty(prop, chain);
+}
+
+const char*
+cmState::Directory::GetProperty(const std::string& prop, bool chain) const
+{
+ static std::string output;
+ output = "";
+ if (prop == "PARENT_DIRECTORY")
+ {
+ cmState::Snapshot parent =
+ this->Snapshot_.GetBuildsystemDirectoryParent();
+ if(parent.IsValid())
+ {
+ return parent.GetDirectory().GetCurrentSource();
+ }
+ return "";
+ }
+ else if (prop == "LISTFILE_STACK")
+ {
+ std::vector<std::string> listFiles;
+ cmState::Snapshot snp = this->Snapshot_;
+ while (snp.IsValid())
+ {
+ listFiles.push_back(snp.GetExecutionListFile());
+ snp = snp.GetCallStackParent();
+ }
+ std::reverse(listFiles.begin(), listFiles.end());
+ output = cmJoin(listFiles, ";");
+ return output.c_str();
+ }
+ else if ( prop == "CACHE_VARIABLES" )
+ {
+ output = cmJoin(this->Snapshot_.State->GetCacheEntryKeys(), ";");
+ return output.c_str();
+ }
+ else if (prop == "VARIABLES")
+ {
+ std::vector<std::string> res = this->Snapshot_.ClosureKeys();
+ std::vector<std::string> cacheKeys =
+ this->Snapshot_.State->GetCacheEntryKeys();
+ res.insert(res.end(), cacheKeys.begin(), cacheKeys.end());
+ std::sort(res.begin(), res.end());
+ output = cmJoin(res, ";");
+ return output.c_str();
+ }
+ else if (prop == "INCLUDE_DIRECTORIES")
+ {
+ output = cmJoin(this->GetIncludeDirectoriesEntries(), ";");
+ return output.c_str();
+ }
+ else if (prop == "COMPILE_OPTIONS")
+ {
+ output = cmJoin(this->GetCompileOptionsEntries(), ";");
+ return output.c_str();
+ }
+ else if (prop == "COMPILE_DEFINITIONS")
+ {
+ output = cmJoin(this->GetCompileDefinitionsEntries(), ";");
+ return output.c_str();
+ }
+
+ const char *retVal = this->DirectoryState->Properties.GetPropertyValue(prop);
+ if (!retVal && chain)
+ {
+ Snapshot parentSnapshot = this->Snapshot_.GetBuildsystemDirectoryParent();
+ if (parentSnapshot.IsValid())
+ {
+ return parentSnapshot.GetDirectory().GetProperty(prop, chain);
+ }
+ return this->Snapshot_.State->GetGlobalProperty(prop);
+ }
+
+ return retVal;
+}
+
+bool cmState::Directory::GetPropertyAsBool(const std::string& prop) const
+{
+ return cmSystemTools::IsOn(this->GetProperty(prop));
+}
+
+std::vector<std::string> cmState::Directory::GetPropertyKeys() const
+{
+ std::vector<std::string> keys;
+ keys.reserve(this->DirectoryState->Properties.size());
+ for(cmPropertyMap::const_iterator it =
+ this->DirectoryState->Properties.begin();
+ it != this->DirectoryState->Properties.end(); ++it)
+ {
+ keys.push_back(it->first);
+ }
+ return keys;
+}
+
+bool operator==(const cmState::Snapshot& lhs, const cmState::Snapshot& rhs)
+{
+ return lhs.Position == rhs.Position;
+}
+
+bool operator!=(const cmState::Snapshot& lhs, const cmState::Snapshot& rhs)
+{
+ return lhs.Position != rhs.Position;
+}
+
+static bool ParseEntryWithoutType(const std::string& entry,
+ std::string& var,
+ std::string& value)
+{
+ // input line is: key=value
+ static cmsys::RegularExpression reg(
+ "^([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
+ // input line is: "key"=value
+ static cmsys::RegularExpression regQuoted(
+ "^\"([^\"]*)\"=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
+ bool flag = false;
+ if(regQuoted.find(entry))
+ {
+ var = regQuoted.match(1);
+ value = regQuoted.match(2);
+ flag = true;
+ }
+ else if (reg.find(entry))
+ {
+ var = reg.match(1);
+ value = reg.match(2);
+ flag = true;
+ }
+
+ // if value is enclosed in single quotes ('foo') then remove them
+ // it is used to enclose trailing space or tab
+ if (flag &&
+ value.size() >= 2 &&
+ value[0] == '\'' &&
+ value[value.size() - 1] == '\'')
+ {
+ value = value.substr(1,
+ value.size() - 2);
+ }
+
+ return flag;
+}
+
+bool cmState::ParseCacheEntry(const std::string& entry,
+ std::string& var,
+ std::string& value,
+ CacheEntryType& type)
+{
+ // input line is: key:type=value
+ static cmsys::RegularExpression reg(
+ "^([^=:]*):([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
+ // input line is: "key":type=value
+ static cmsys::RegularExpression regQuoted(
+ "^\"([^\"]*)\":([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
+ bool flag = false;
+ if(regQuoted.find(entry))
+ {
+ var = regQuoted.match(1);
+ type = cmState::StringToCacheEntryType(regQuoted.match(2).c_str());
+ value = regQuoted.match(3);
+ flag = true;
+ }
+ else if (reg.find(entry))
+ {
+ var = reg.match(1);
+ type = cmState::StringToCacheEntryType(reg.match(2).c_str());
+ value = reg.match(3);
+ flag = true;
+ }
+
+ // if value is enclosed in single quotes ('foo') then remove them
+ // it is used to enclose trailing space or tab
+ if (flag &&
+ value.size() >= 2 &&
+ value[0] == '\'' &&
+ value[value.size() - 1] == '\'')
+ {
+ value = value.substr(1,
+ value.size() - 2);
+ }
+
+ if (!flag)
+ {
+ return ParseEntryWithoutType(entry, var, value);
+ }
+
+ return flag;
+}
diff --git a/Source/cmState.h b/Source/cmState.h
new file mode 100644
index 000000000..6717481c5
--- /dev/null
+++ b/Source/cmState.h
@@ -0,0 +1,364 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Stephen Kelly <steveire@gmail.com>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmState_h
+#define cmState_h
+
+#include "cmStandardIncludes.h"
+#include "cmPropertyDefinitionMap.h"
+#include "cmPropertyMap.h"
+#include "cmLinkedTree.h"
+#include "cmAlgorithms.h"
+#include "cmPolicies.h"
+
+class cmake;
+class cmCommand;
+class cmDefinitions;
+class cmListFileBacktrace;
+class cmCacheManager;
+
+class cmState
+{
+ struct SnapshotDataType;
+ struct PolicyStackEntry;
+ struct BuildsystemDirectoryStateType;
+ typedef cmLinkedTree<SnapshotDataType>::iterator PositionType;
+ friend class Snapshot;
+public:
+ cmState();
+ ~cmState();
+
+ enum SnapshotType
+ {
+ BaseType,
+ BuildsystemDirectoryType,
+ FunctionCallType,
+ MacroCallType,
+ CallStackType,
+ InlineListFileType,
+ PolicyScopeType,
+ VariableScopeType
+ };
+
+ class Directory;
+
+ class Snapshot {
+ public:
+ Snapshot(cmState* state = 0);
+ Snapshot(cmState* state, PositionType position);
+
+ const char* GetDefinition(std::string const& name) const;
+ bool IsInitialized(std::string const& name) const;
+ void SetDefinition(std::string const& name, std::string const& value);
+ void RemoveDefinition(std::string const& name);
+ std::vector<std::string> UnusedKeys() const;
+ std::vector<std::string> ClosureKeys() const;
+ bool RaiseScope(std::string const& var, const char* varDef);
+
+ void Keep();
+ void SetListFile(std::string const& listfile);
+
+ std::string GetExecutionListFile() const;
+
+ std::vector<Snapshot> GetChildren();
+ std::string GetEntryPointCommand() const;
+ long GetEntryPointLine() const;
+
+ bool IsValid() const;
+ Snapshot GetBuildsystemDirectoryParent() const;
+ Snapshot GetCallStackParent() const;
+ SnapshotType GetType() const;
+
+ void SetPolicy(cmPolicies::PolicyID id, cmPolicies::PolicyStatus status);
+ cmPolicies::PolicyStatus GetPolicy(cmPolicies::PolicyID id) const;
+ bool HasDefinedPolicyCMP0011();
+ void PushPolicy(cmPolicies::PolicyMap entry, bool weak);
+ bool PopPolicy();
+ bool CanPopPolicyScope();
+
+ cmState* GetState() const;
+
+ Directory GetDirectory() const;
+
+ void SetProjectName(std::string const& name);
+ std::string GetProjectName() const;
+
+ void InitializeFromParent_ForSubdirsCommand();
+
+ struct StrictWeakOrder
+ {
+ bool operator()(const cmState::Snapshot& lhs,
+ const cmState::Snapshot& rhs) const;
+ };
+
+ void SetDirectoryDefinitions();
+ void SetDefaultDefinitions();
+
+ private:
+ friend bool operator==(const cmState::Snapshot& lhs,
+ const cmState::Snapshot& rhs);
+ friend bool operator!=(const cmState::Snapshot& lhs,
+ const cmState::Snapshot& rhs);
+ friend class cmState;
+ friend class Directory;
+ friend struct StrictWeakOrder;
+
+ void InitializeFromParent();
+
+ cmState* State;
+ cmState::PositionType Position;
+ };
+
+ class Directory
+ {
+ Directory(cmLinkedTree<BuildsystemDirectoryStateType>::iterator iter,
+ Snapshot const& snapshot);
+ public:
+ const char* GetCurrentSource() const;
+ void SetCurrentSource(std::string const& dir);
+ const char* GetCurrentBinary() const;
+ void SetCurrentBinary(std::string const& dir);
+
+ std::vector<std::string> const&
+ GetCurrentSourceComponents() const;
+ std::vector<std::string> const&
+ GetCurrentBinaryComponents() const;
+
+ const char* GetRelativePathTopSource() const;
+ const char* GetRelativePathTopBinary() const;
+ void SetRelativePathTopSource(const char* dir);
+ void SetRelativePathTopBinary(const char* dir);
+
+ cmStringRange GetIncludeDirectoriesEntries() const;
+ cmBacktraceRange GetIncludeDirectoriesEntryBacktraces() const;
+ void AppendIncludeDirectoriesEntry(std::string const& vec,
+ cmListFileBacktrace const& lfbt);
+ void PrependIncludeDirectoriesEntry(std::string const& vec,
+ cmListFileBacktrace const& lfbt);
+ void SetIncludeDirectories(std::string const& vec,
+ cmListFileBacktrace const& lfbt);
+ void ClearIncludeDirectories();
+
+ cmStringRange GetCompileDefinitionsEntries() const;
+ cmBacktraceRange GetCompileDefinitionsEntryBacktraces() const;
+ void AppendCompileDefinitionsEntry(std::string const& vec,
+ cmListFileBacktrace const& lfbt);
+ void SetCompileDefinitions(std::string const& vec,
+ cmListFileBacktrace const& lfbt);
+ void ClearCompileDefinitions();
+
+ cmStringRange GetCompileOptionsEntries() const;
+ cmBacktraceRange GetCompileOptionsEntryBacktraces() const;
+ void AppendCompileOptionsEntry(std::string const& vec,
+ cmListFileBacktrace const& lfbt);
+ void SetCompileOptions(std::string const& vec,
+ cmListFileBacktrace const& lfbt);
+ void ClearCompileOptions();
+
+ void SetProperty(const std::string& prop, const char *value,
+ cmListFileBacktrace lfbt);
+ void AppendProperty(const std::string& prop, const char *value,
+ bool asString, cmListFileBacktrace lfbt);
+ const char *GetProperty(const std::string& prop) const;
+ const char *GetProperty(const std::string& prop, bool chain) const;
+ bool GetPropertyAsBool(const std::string& prop) const;
+ std::vector<std::string> GetPropertyKeys() const;
+
+ private:
+ void ComputeRelativePathTopSource();
+ void ComputeRelativePathTopBinary();
+
+ private:
+ cmLinkedTree<BuildsystemDirectoryStateType>::iterator DirectoryState;
+ Snapshot Snapshot_;
+ friend class Snapshot;
+ };
+
+ enum TargetType { EXECUTABLE, STATIC_LIBRARY,
+ SHARED_LIBRARY, MODULE_LIBRARY,
+ OBJECT_LIBRARY, UTILITY, GLOBAL_TARGET,
+ INTERFACE_LIBRARY,
+ UNKNOWN_LIBRARY};
+
+ static const char* GetTargetTypeName(cmState::TargetType targetType);
+
+ Snapshot CreateBaseSnapshot();
+ Snapshot
+ CreateBuildsystemDirectorySnapshot(Snapshot originSnapshot,
+ std::string const& entryPointCommand,
+ long entryPointLine);
+ Snapshot CreateFunctionCallSnapshot(Snapshot originSnapshot,
+ std::string const& entryPointCommand,
+ long entryPointLine,
+ std::string const& fileName);
+ Snapshot CreateMacroCallSnapshot(Snapshot originSnapshot,
+ std::string const& entryPointCommand,
+ long entryPointLine,
+ std::string const& fileName);
+ Snapshot CreateCallStackSnapshot(Snapshot originSnapshot,
+ std::string const& entryPointCommand,
+ long entryPointLine,
+ std::string const& fileName);
+ Snapshot CreateVariableScopeSnapshot(Snapshot originSnapshot,
+ std::string const& entryPointCommand,
+ long entryPointLine);
+ Snapshot CreateInlineListFileSnapshot(Snapshot originSnapshot,
+ const std::string& entryPointCommand,
+ long entryPointLine,
+ std::string const& fileName);
+ Snapshot CreatePolicyScopeSnapshot(Snapshot originSnapshot);
+ Snapshot Pop(Snapshot originSnapshot);
+
+ enum CacheEntryType{ BOOL=0, PATH, FILEPATH, STRING, INTERNAL,STATIC,
+ UNINITIALIZED };
+ static CacheEntryType StringToCacheEntryType(const char*);
+ static const char* CacheEntryTypeToString(CacheEntryType);
+ static bool IsCacheEntryType(std::string const& key);
+
+ bool LoadCache(const std::string& path, bool internal,
+ std::set<std::string>& excludes,
+ std::set<std::string>& includes);
+
+ bool SaveCache(const std::string& path) ;
+
+ bool DeleteCache(const std::string& path);
+
+ std::vector<std::string> GetCacheEntryKeys() const;
+ const char* GetCacheEntryValue(std::string const& key) const;
+ const char* GetInitializedCacheValue(std::string const& key) const;
+ CacheEntryType GetCacheEntryType(std::string const& key) const;
+ void SetCacheEntryValue(std::string const& key, std::string const& value);
+ void SetCacheValue(std::string const& key, std::string const& value);
+
+ void RemoveCacheEntry(std::string const& key);
+
+ void SetCacheEntryProperty(std::string const& key,
+ std::string const& propertyName,
+ std::string const& value);
+ void SetCacheEntryBoolProperty(std::string const& key,
+ std::string const& propertyName,
+ bool value);
+ const char* GetCacheEntryProperty(std::string const& key,
+ std::string const& propertyName);
+ bool GetCacheEntryPropertyAsBool(std::string const& key,
+ std::string const& propertyName);
+ void AppendCacheEntryProperty(std::string const& key,
+ const std::string& property,
+ const std::string& value,
+ bool asString = false);
+ void RemoveCacheEntryProperty(std::string const& key,
+ std::string const& propertyName);
+
+ ///! Break up a line like VAR:type="value" into var, type and value
+ static bool ParseCacheEntry(const std::string& entry,
+ std::string& var,
+ std::string& value,
+ CacheEntryType& type);
+
+ Snapshot Reset();
+ // Define a property
+ void DefineProperty(const std::string& name, cmProperty::ScopeType scope,
+ const char *ShortDescription,
+ const char *FullDescription,
+ bool chain = false);
+
+ // get property definition
+ cmPropertyDefinition const* GetPropertyDefinition
+ (const std::string& name, cmProperty::ScopeType scope) const;
+
+ // Is a property defined?
+ bool IsPropertyDefined(const std::string& name,
+ cmProperty::ScopeType scope) const;
+ bool IsPropertyChained(const std::string& name,
+ cmProperty::ScopeType scope) const;
+
+ void SetLanguageEnabled(std::string const& l);
+ bool GetLanguageEnabled(std::string const& l) const;
+ std::vector<std::string> GetEnabledLanguages() const;
+ void SetEnabledLanguages(std::vector<std::string> const& langs);
+ void ClearEnabledLanguages();
+
+ bool GetIsInTryCompile() const;
+ void SetIsInTryCompile(bool b);
+
+ cmCommand* GetCommand(std::string const& name) const;
+ void AddCommand(cmCommand* command);
+ void RemoveUnscriptableCommands();
+ void RenameCommand(std::string const& oldName, std::string const& newName);
+ void RemoveUserDefinedCommands();
+ std::vector<std::string> GetCommandNames() const;
+
+ void SetGlobalProperty(const std::string& prop, const char *value);
+ void AppendGlobalProperty(const std::string& prop,
+ const char *value,bool asString=false);
+ const char *GetGlobalProperty(const std::string& prop);
+ bool GetGlobalPropertyAsBool(const std::string& prop);
+
+ const char* GetSourceDirectory() const;
+ void SetSourceDirectory(std::string const& sourceDirectory);
+ const char* GetBinaryDirectory() const;
+ void SetBinaryDirectory(std::string const& binaryDirectory);
+
+ std::vector<std::string> const& GetSourceDirectoryComponents() const;
+ std::vector<std::string> const& GetBinaryDirectoryComponents() const;
+
+ void SetWindowsShell(bool windowsShell);
+ bool UseWindowsShell() const;
+ void SetWindowsVSIDE(bool windowsVSIDE);
+ bool UseWindowsVSIDE() const;
+ void SetWatcomWMake(bool watcomWMake);
+ bool UseWatcomWMake() const;
+ void SetMinGWMake(bool minGWMake);
+ bool UseMinGWMake() const;
+ void SetNMake(bool nMake);
+ bool UseNMake() const;
+ void SetMSYSShell(bool mSYSShell);
+ bool UseMSYSShell() const;
+
+ unsigned int GetCacheMajorVersion() const;
+ unsigned int GetCacheMinorVersion() const;
+
+private:
+ friend class cmake;
+ void AddCacheEntry(const std::string& key, const char* value,
+ const char* helpString, CacheEntryType type);
+
+ std::map<cmProperty::ScopeType, cmPropertyDefinitionMap> PropertyDefinitions;
+ std::vector<std::string> EnabledLanguages;
+ std::map<std::string, cmCommand*> Commands;
+ cmPropertyMap GlobalProperties;
+ cmCacheManager* CacheManager;
+
+ cmLinkedTree<BuildsystemDirectoryStateType> BuildsystemDirectory;
+
+ cmLinkedTree<std::string> ExecutionListFiles;
+
+ cmLinkedTree<PolicyStackEntry> PolicyStack;
+ cmLinkedTree<SnapshotDataType> SnapshotData;
+ cmLinkedTree<cmDefinitions> VarTree;
+
+ std::vector<std::string> SourceDirectoryComponents;
+ std::vector<std::string> BinaryDirectoryComponents;
+ std::string SourceDirectory;
+ std::string BinaryDirectory;
+ bool IsInTryCompile;
+ bool WindowsShell;
+ bool WindowsVSIDE;
+ bool WatcomWMake;
+ bool MinGWMake;
+ bool NMake;
+ bool MSYSShell;
+};
+
+bool operator==(const cmState::Snapshot& lhs, const cmState::Snapshot& rhs);
+bool operator!=(const cmState::Snapshot& lhs, const cmState::Snapshot& rhs);
+
+#endif
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index 68ba13f62..649fb3933 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -20,6 +20,7 @@
#include <time.h>
#include <cmTimestamp.h>
+#include <cmUuid.h>
//----------------------------------------------------------------------------
bool cmStringCommand
@@ -73,6 +74,14 @@ bool cmStringCommand
{
return this->HandleLengthCommand(args);
}
+ else if(subCommand == "APPEND")
+ {
+ return this->HandleAppendCommand(args);
+ }
+ else if(subCommand == "CONCAT")
+ {
+ return this->HandleConcatCommand(args);
+ }
else if(subCommand == "SUBSTRING")
{
return this->HandleSubstringCommand(args);
@@ -97,9 +106,17 @@ bool cmStringCommand
{
return this->HandleMakeCIdentifierCommand(args);
}
+ else if(subCommand == "GENEX_STRIP")
+ {
+ return this->HandleGenexStripCommand(args);
+ }
+ else if(subCommand == "UUID")
+ {
+ return this->HandleUuidCommand(args);
+ }
std::string e = "does not recognize sub-command "+subCommand;
- this->SetError(e.c_str());
+ this->SetError(e);
return false;
}
@@ -109,22 +126,22 @@ bool cmStringCommand::HandleHashCommand(std::vector<std::string> const& args)
#if defined(CMAKE_BUILD_WITH_CMAKE)
if(args.size() != 3)
{
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " requires an output variable and an input string";
- this->SetError(e.str().c_str());
+ this->SetError(e.str());
return false;
}
cmsys::auto_ptr<cmCryptoHash> hash(cmCryptoHash::New(args[0].c_str()));
if(hash.get())
{
- std::string out = hash->HashString(args[2].c_str());
- this->Makefile->AddDefinition(args[1].c_str(), out.c_str());
+ std::string out = hash->HashString(args[2]);
+ this->Makefile->AddDefinition(args[1], out.c_str());
return true;
}
return false;
#else
- cmOStringStream e;
+ std::ostringstream e;
e << args[0] << " not available during bootstrap";
this->SetError(e.str().c_str());
return false;
@@ -154,7 +171,7 @@ bool cmStringCommand::HandleToUpperLowerCommand(
}
// Store the output in the provided variable.
- this->Makefile->AddDefinition(outvar.c_str(), output.c_str());
+ this->Makefile->AddDefinition(outvar, output.c_str());
return true;
}
@@ -181,12 +198,12 @@ bool cmStringCommand::HandleAsciiCommand(std::vector<std::string> const& args)
std::string error = "Character with code ";
error += args[cc];
error += " does not exist.";
- this->SetError(error.c_str());
+ this->SetError(error);
return false;
}
}
// Store the output in the provided variable.
- this->Makefile->AddDefinition(outvar.c_str(), output.c_str());
+ this->Makefile->AddDefinition(outvar, output.c_str());
return true;
}
@@ -220,9 +237,9 @@ bool cmStringCommand::HandleConfigureCommand(
}
else
{
- cmOStringStream err;
+ std::ostringstream err;
err << "Unrecognized argument \"" << args[i] << "\"";
- this->SetError(err.str().c_str());
+ this->SetError(err.str());
return false;
}
}
@@ -232,7 +249,7 @@ bool cmStringCommand::HandleConfigureCommand(
this->Makefile->ConfigureString(args[1], output, atOnly, escapeQuotes);
// Store the output in the provided variable.
- this->Makefile->AddDefinition(args[2].c_str(), output.c_str());
+ this->Makefile->AddDefinition(args[2], output.c_str());
return true;
}
@@ -278,7 +295,7 @@ bool cmStringCommand::HandleRegexCommand(std::vector<std::string> const& args)
}
std::string e = "sub-command REGEX does not recognize mode "+mode;
- this->SetError(e.c_str());
+ this->SetError(e);
return false;
}
@@ -290,29 +307,25 @@ bool cmStringCommand::RegexMatch(std::vector<std::string> const& args)
std::string regex = args[2];
std::string outvar = args[3];
- // Concatenate all the last arguments together.
- std::string input = args[4];
- for(unsigned int i=5; i < args.size(); ++i)
- {
- input += args[i];
- }
-
- this->ClearMatches(this->Makefile);
+ this->Makefile->ClearMatches();
// Compile the regular expression.
cmsys::RegularExpression re;
if(!re.compile(regex.c_str()))
{
std::string e =
"sub-command REGEX, mode MATCH failed to compile regex \""+regex+"\".";
- this->SetError(e.c_str());
+ this->SetError(e);
return false;
}
+ // Concatenate all the last arguments together.
+ std::string input = cmJoin(cmMakeRange(args).advance(4), std::string());
+
// Scan through the input for all matches.
std::string output;
if(re.find(input.c_str()))
{
- this->StoreMatches(this->Makefile, re);
+ this->Makefile->StoreMatches(re);
std::string::size_type l = re.start();
std::string::size_type r = re.end();
if(r-l == 0)
@@ -320,14 +333,14 @@ bool cmStringCommand::RegexMatch(std::vector<std::string> const& args)
std::string e =
"sub-command REGEX, mode MATCH regex \""+regex+
"\" matched an empty string.";
- this->SetError(e.c_str());
+ this->SetError(e);
return false;
}
output = input.substr(l, r-l);
}
// Store the output in the provided variable.
- this->Makefile->AddDefinition(outvar.c_str(), output.c_str());
+ this->Makefile->AddDefinition(outvar, output.c_str());
return true;
}
@@ -339,14 +352,7 @@ bool cmStringCommand::RegexMatchAll(std::vector<std::string> const& args)
std::string regex = args[2];
std::string outvar = args[3];
- // Concatenate all the last arguments together.
- std::string input = args[4];
- for(unsigned int i=5; i < args.size(); ++i)
- {
- input += args[i];
- }
-
- this->ClearMatches(this->Makefile);
+ this->Makefile->ClearMatches();
// Compile the regular expression.
cmsys::RegularExpression re;
if(!re.compile(regex.c_str()))
@@ -354,26 +360,29 @@ bool cmStringCommand::RegexMatchAll(std::vector<std::string> const& args)
std::string e =
"sub-command REGEX, mode MATCHALL failed to compile regex \""+
regex+"\".";
- this->SetError(e.c_str());
+ this->SetError(e);
return false;
}
+ // Concatenate all the last arguments together.
+ std::string input = cmJoin(cmMakeRange(args).advance(4), std::string());
+
// Scan through the input for all matches.
std::string output;
const char* p = input.c_str();
while(re.find(p))
{
- this->StoreMatches(this->Makefile, re);
+ this->Makefile->StoreMatches(re);
std::string::size_type l = re.start();
std::string::size_type r = re.end();
if(r-l == 0)
{
std::string e = "sub-command REGEX, mode MATCHALL regex \""+
regex+"\" matched an empty string.";
- this->SetError(e.c_str());
+ this->SetError(e);
return false;
}
- if(output.length() > 0)
+ if(!output.empty())
{
output += ";";
}
@@ -382,7 +391,7 @@ bool cmStringCommand::RegexMatchAll(std::vector<std::string> const& args)
}
// Store the output in the provided variable.
- this->Makefile->AddDefinition(outvar.c_str(), output.c_str());
+ this->Makefile->AddDefinition(outvar, output.c_str());
return true;
}
@@ -435,7 +444,7 @@ bool cmStringCommand::RegexReplace(std::vector<std::string> const& args)
std::string e = "sub-command REGEX, mode REPLACE: Unknown escape \"";
e += replace.substr(r, 2);
e += "\" in replace-expression.";
- this->SetError(e.c_str());
+ this->SetError(e);
return false;
}
r += 2;
@@ -443,14 +452,7 @@ bool cmStringCommand::RegexReplace(std::vector<std::string> const& args)
l = r;
}
- // Concatenate all the last arguments together.
- std::string input = args[5];
- for(unsigned int i=6; i < args.size(); ++i)
- {
- input += args[i];
- }
-
- this->ClearMatches(this->Makefile);
+ this->Makefile->ClearMatches();
// Compile the regular expression.
cmsys::RegularExpression re;
if(!re.compile(regex.c_str()))
@@ -458,16 +460,19 @@ bool cmStringCommand::RegexReplace(std::vector<std::string> const& args)
std::string e =
"sub-command REGEX, mode REPLACE failed to compile regex \""+
regex+"\".";
- this->SetError(e.c_str());
+ this->SetError(e);
return false;
}
+ // Concatenate all the last arguments together.
+ std::string input = cmJoin(cmMakeRange(args).advance(5), std::string());
+
// Scan through the input for all matches.
std::string output;
std::string::size_type base = 0;
while(re.find(input.c_str()+base))
{
- this->StoreMatches(this->Makefile, re);
+ this->Makefile->StoreMatches(re);
std::string::size_type l2 = re.start();
std::string::size_type r = re.end();
@@ -479,7 +484,7 @@ bool cmStringCommand::RegexReplace(std::vector<std::string> const& args)
{
std::string e = "sub-command REGEX, mode REPLACE regex \""+
regex+"\" matched an empty string.";
- this->SetError(e.c_str());
+ this->SetError(e);
return false;
}
@@ -509,7 +514,7 @@ bool cmStringCommand::RegexReplace(std::vector<std::string> const& args)
"sub-command REGEX, mode REPLACE: replace expression \""+
replace+"\" contains an out-of-range escape for regex \""+
regex+"\".";
- this->SetError(e.c_str());
+ this->SetError(e);
return false;
}
}
@@ -523,43 +528,11 @@ bool cmStringCommand::RegexReplace(std::vector<std::string> const& args)
output += input.substr(base, input.length()-base);
// Store the output in the provided variable.
- this->Makefile->AddDefinition(outvar.c_str(), output.c_str());
+ this->Makefile->AddDefinition(outvar, output.c_str());
return true;
}
//----------------------------------------------------------------------------
-void cmStringCommand::ClearMatches(cmMakefile* mf)
-{
- for (unsigned int i=0; i<10; i++)
- {
- char name[128];
- sprintf(name, "CMAKE_MATCH_%d", i);
- const char* s = mf->GetDefinition(name);
- if(s && *s != 0)
- {
- mf->AddDefinition(name, "");
- mf->MarkVariableAsUsed(name);
- }
- }
-}
-
-//----------------------------------------------------------------------------
-void cmStringCommand::StoreMatches(cmMakefile* mf,cmsys::RegularExpression& re)
-{
- for (unsigned int i=0; i<10; i++)
- {
- std::string m = re.match(i);
- if(m.size() > 0)
- {
- char name[128];
- sprintf(name, "CMAKE_MATCH_%d", i);
- mf->AddDefinition(name, re.match(i).c_str());
- mf->MarkVariableAsUsed(name);
- }
- }
-}
-
-//----------------------------------------------------------------------------
bool cmStringCommand::HandleFindCommand(std::vector<std::string> const&
args)
{
@@ -610,14 +583,14 @@ bool cmStringCommand::HandleFindCommand(std::vector<std::string> const&
}
if(std::string::npos != pos)
{
- cmOStringStream s;
+ std::ostringstream s;
s << pos;
- this->Makefile->AddDefinition(outvar.c_str(), s.str().c_str());
+ this->Makefile->AddDefinition(outvar, s.str().c_str());
return true;
}
// the character was not found, but this is not really an error
- this->Makefile->AddDefinition(outvar.c_str(), "-1");
+ this->Makefile->AddDefinition(outvar, "-1");
return true;
}
@@ -639,7 +612,7 @@ bool cmStringCommand::HandleCompareCommand(std::vector<std::string> const&
std::string e = "sub-command COMPARE, mode ";
e += mode;
e += " needs at least 5 arguments total to command.";
- this->SetError(e.c_str());
+ this->SetError(e);
return false;
}
@@ -665,16 +638,16 @@ bool cmStringCommand::HandleCompareCommand(std::vector<std::string> const&
}
if(result)
{
- this->Makefile->AddDefinition(outvar.c_str(), "1");
+ this->Makefile->AddDefinition(outvar, "1");
}
else
{
- this->Makefile->AddDefinition(outvar.c_str(), "0");
+ this->Makefile->AddDefinition(outvar, "0");
}
return true;
}
std::string e = "sub-command COMPARE does not recognize mode "+mode;
- this->SetError(e.c_str());
+ this->SetError(e);
return false;
}
@@ -692,16 +665,12 @@ bool cmStringCommand::HandleReplaceCommand(std::vector<std::string> const&
const std::string& replaceExpression = args[2];
const std::string& variableName = args[3];
- std::string input = args[4];
- for(unsigned int i=5; i < args.size(); ++i)
- {
- input += args[i];
- }
+ std::string input = cmJoin(cmMakeRange(args).advance(4), std::string());
cmsys::SystemTools::ReplaceString(input, matchExpression.c_str(),
replaceExpression.c_str());
- this->Makefile->AddDefinition(variableName.c_str(), input.c_str());
+ this->Makefile->AddDefinition(variableName, input.c_str());
return true;
}
@@ -724,23 +693,21 @@ bool cmStringCommand::HandleSubstringCommand(std::vector<std::string> const&
int intStringLength = static_cast<int>(stringLength);
if ( begin < 0 || begin > intStringLength )
{
- cmOStringStream ostr;
+ std::ostringstream ostr;
ostr << "begin index: " << begin << " is out of range 0 - "
<< stringLength;
- this->SetError(ostr.str().c_str());
+ this->SetError(ostr.str());
return false;
}
- int leftOverLength = intStringLength - begin;
- if ( end < -1 || end > leftOverLength )
+ if ( end < -1 )
{
- cmOStringStream ostr;
- ostr << "end index: " << end << " is out of range -1 - "
- << leftOverLength;
- this->SetError(ostr.str().c_str());
+ std::ostringstream ostr;
+ ostr << "end index: " << end << " should be -1 or greater";
+ this->SetError(ostr.str());
return false;
}
- this->Makefile->AddDefinition(variableName.c_str(),
+ this->Makefile->AddDefinition(variableName,
stringValue.substr(begin, end).c_str());
return true;
}
@@ -762,7 +729,52 @@ bool cmStringCommand
char buffer[1024];
sprintf(buffer, "%d", static_cast<int>(length));
- this->Makefile->AddDefinition(variableName.c_str(), buffer);
+ this->Makefile->AddDefinition(variableName, buffer);
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmStringCommand::HandleAppendCommand(std::vector<std::string> const& args)
+{
+ if(args.size() < 2)
+ {
+ this->SetError("sub-command APPEND requires at least one argument.");
+ return false;
+ }
+
+ // Skip if nothing to append.
+ if(args.size() < 3)
+ {
+ return true;
+ }
+
+ const std::string& variable = args[1];
+
+ std::string value;
+ const char* oldValue = this->Makefile->GetDefinition(variable);
+ if(oldValue)
+ {
+ value = oldValue;
+ }
+ value += cmJoin(cmMakeRange(args).advance(2), std::string());
+ this->Makefile->AddDefinition(variable, value.c_str());
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmStringCommand
+::HandleConcatCommand(std::vector<std::string> const& args)
+{
+ if(args.size() < 2)
+ {
+ this->SetError("sub-command CONCAT requires at least one argument.");
+ return false;
+ }
+
+ std::string const& variableName = args[1];
+ std::string value = cmJoin(cmMakeRange(args).advance(2), std::string());
+
+ this->Makefile->AddDefinition(variableName, value.c_str());
return true;
}
@@ -779,8 +791,29 @@ bool cmStringCommand
const std::string& input = args[1];
const std::string& variableName = args[2];
- this->Makefile->AddDefinition(variableName.c_str(),
- cmSystemTools::MakeCidentifier(input.c_str()).c_str());
+ this->Makefile->AddDefinition(variableName,
+ cmSystemTools::MakeCidentifier(input).c_str());
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmStringCommand
+::HandleGenexStripCommand(std::vector<std::string> const& args)
+{
+ if(args.size() != 3)
+ {
+ this->SetError("sub-command GENEX_STRIP requires two arguments.");
+ return false;
+ }
+
+ const std::string& input = args[1];
+
+ std::string result = cmGeneratorExpression::Preprocess(input,
+ cmGeneratorExpression::StripAllGeneratorExpressions);
+
+ const std::string& variableName = args[2];
+
+ this->Makefile->AddDefinition(variableName, result.c_str());
return true;
}
@@ -828,7 +861,7 @@ bool cmStringCommand::HandleStripCommand(
outLength=endPos - startPos + 1;
}
- this->Makefile->AddDefinition(variableName.c_str(),
+ this->Makefile->AddDefinition(variableName,
stringValue.substr(startPos, outLength).c_str());
return true;
}
@@ -877,7 +910,7 @@ bool cmStringCommand
}
}
}
- if ( !alphabet.size() )
+ if (alphabet.empty())
{
alphabet = cmStringCommandDefaultAlphabet;
}
@@ -912,7 +945,7 @@ bool cmStringCommand
}
result.push_back(0);
- this->Makefile->AddDefinition(variableName.c_str(), &*result.begin());
+ this->Makefile->AddDefinition(variableName, &*result.begin());
return true;
}
@@ -952,14 +985,125 @@ bool cmStringCommand
{
std::string e = " TIMESTAMP sub-command does not recognize option " +
args[argsIndex] + ".";
- this->SetError(e.c_str());
+ this->SetError(e);
return false;
}
}
cmTimestamp timestamp;
std::string result = timestamp.CurrentTime(formatString, utcFlag);
- this->Makefile->AddDefinition(outputVariable.c_str(), result.c_str());
+ this->Makefile->AddDefinition(outputVariable, result.c_str());
+
+ return true;
+}
+
+bool cmStringCommand
+::HandleUuidCommand(std::vector<std::string> const& args)
+{
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ unsigned int argsIndex = 1;
+
+ if(args.size() < 2)
+ {
+ this->SetError("UUID sub-command requires an output variable.");
+ return false;
+ }
+
+ const std::string &outputVariable = args[argsIndex++];
+
+ std::string uuidNamespaceString;
+ std::string uuidName;
+ std::string uuidType;
+ bool uuidUpperCase = false;
+
+ while(args.size() > argsIndex)
+ {
+ if(args[argsIndex] == "NAMESPACE")
+ {
+ ++argsIndex;
+ if(argsIndex >= args.size())
+ {
+ this->SetError("UUID sub-command, NAMESPACE requires a value.");
+ return false;
+ }
+ uuidNamespaceString = args[argsIndex++];
+ }
+ else if(args[argsIndex] == "NAME")
+ {
+ ++argsIndex;
+ if(argsIndex >= args.size())
+ {
+ this->SetError("UUID sub-command, NAME requires a value.");
+ return false;
+ }
+ uuidName = args[argsIndex++];
+ }
+ else if(args[argsIndex] == "TYPE")
+ {
+ ++argsIndex;
+ if(argsIndex >= args.size())
+ {
+ this->SetError("UUID sub-command, TYPE requires a value.");
+ return false;
+ }
+ uuidType = args[argsIndex++];
+ }
+ else if(args[argsIndex] == "UPPER")
+ {
+ ++argsIndex;
+ uuidUpperCase = true;
+ }
+ else
+ {
+ std::string e = "UUID sub-command does not recognize option " +
+ args[argsIndex] + ".";
+ this->SetError(e);
+ return false;
+ }
+ }
+
+ std::string uuid;
+ cmUuid uuidGenerator;
+
+ std::vector<unsigned char> uuidNamespace;
+ if(!uuidGenerator.StringToBinary(uuidNamespaceString, uuidNamespace))
+ {
+ this->SetError("UUID sub-command, malformed NAMESPACE UUID.");
+ return false;
+ }
+ if(uuidType == "MD5")
+ {
+ uuid = uuidGenerator.FromMd5(uuidNamespace, uuidName);
+ }
+ else if(uuidType == "SHA1")
+ {
+ uuid = uuidGenerator.FromSha1(uuidNamespace, uuidName);
+ }
+ else
+ {
+ std::string e = "UUID sub-command, unknown TYPE '" + uuidType + "'.";
+ this->SetError(e);
+ return false;
+ }
+
+ if(uuid.empty())
+ {
+ this->SetError("UUID sub-command, generation failed.");
+ return false;
+ }
+
+ if(uuidUpperCase)
+ {
+ uuid = cmSystemTools::UpperCase(uuid);
+ }
+
+ this->Makefile->AddDefinition(outputVariable, uuid.c_str());
return true;
+#else
+ std::ostringstream e;
+ e << args[0] << " not available during bootstrap";
+ this->SetError(e.str().c_str());
+ return false;
+#endif
}
diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h
index f584cfdbf..3ed17ebd3 100644
--- a/Source/cmStringCommand.h
+++ b/Source/cmStringCommand.h
@@ -50,141 +50,9 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "string";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "String operations.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " string(REGEX MATCH <regular_expression>\n"
- " <output variable> <input> [<input>...])\n"
- " string(REGEX MATCHALL <regular_expression>\n"
- " <output variable> <input> [<input>...])\n"
- " string(REGEX REPLACE <regular_expression>\n"
- " <replace_expression> <output variable>\n"
- " <input> [<input>...])\n"
- " string(REPLACE <match_string>\n"
- " <replace_string> <output variable>\n"
- " <input> [<input>...])\n"
- " string(<MD5|SHA1|SHA224|SHA256|SHA384|SHA512>\n"
- " <output variable> <input>)\n"
- " string(COMPARE EQUAL <string1> <string2> <output variable>)\n"
- " string(COMPARE NOTEQUAL <string1> <string2> <output variable>)\n"
- " string(COMPARE LESS <string1> <string2> <output variable>)\n"
- " string(COMPARE GREATER <string1> <string2> <output variable>)\n"
- " string(ASCII <number> [<number> ...] <output variable>)\n"
- " string(CONFIGURE <string1> <output variable>\n"
- " [@ONLY] [ESCAPE_QUOTES])\n"
- " string(TOUPPER <string1> <output variable>)\n"
- " string(TOLOWER <string1> <output variable>)\n"
- " string(LENGTH <string> <output variable>)\n"
- " string(SUBSTRING <string> <begin> <length> <output variable>)\n"
- " string(STRIP <string> <output variable>)\n"
- " string(RANDOM [LENGTH <length>] [ALPHABET <alphabet>]\n"
- " [RANDOM_SEED <seed>] <output variable>)\n"
- " string(FIND <string> <substring> <output variable> [REVERSE])\n"
- " string(TIMESTAMP <output variable> [<format string>] [UTC])\n"
- " string(MAKE_C_IDENTIFIER <input string> <output variable>)\n"
- "REGEX MATCH will match the regular expression once and store the "
- "match in the output variable.\n"
- "REGEX MATCHALL will match the regular expression as many times as "
- "possible and store the matches in the output variable as a list.\n"
- "REGEX REPLACE will match the regular expression as many times as "
- "possible and substitute the replacement expression for the match "
- "in the output. The replace expression may refer to paren-delimited "
- "subexpressions of the match using \\1, \\2, ..., \\9. Note that "
- "two backslashes (\\\\1) are required in CMake code to get a "
- "backslash through argument parsing.\n"
- "REPLACE will replace all occurrences of match_string in the input with "
- "replace_string and store the result in the output.\n"
- "MD5, SHA1, SHA224, SHA256, SHA384, and SHA512 "
- "will compute a cryptographic hash of the input string.\n"
- "COMPARE EQUAL/NOTEQUAL/LESS/GREATER will compare the strings and "
- "store true or false in the output variable.\n"
- "ASCII will convert all numbers into corresponding ASCII characters.\n"
- "CONFIGURE will transform a string like CONFIGURE_FILE transforms "
- "a file.\n"
- "TOUPPER/TOLOWER will convert string to upper/lower characters.\n"
- "LENGTH will return a given string's length.\n"
- "SUBSTRING will return a substring of a given string. If length is "
- "-1 the remainder of the string starting at begin will be returned.\n"
- "STRIP will return a substring of a given string with leading "
- "and trailing spaces removed.\n"
- "RANDOM will return a random string of given length consisting of "
- "characters from the given alphabet. Default length is 5 "
- "characters and default alphabet is all numbers and upper and "
- "lower case letters. If an integer RANDOM_SEED is given, its "
- "value will be used to seed the random number generator.\n"
- "FIND will return the position where the given substring was found "
- "in the supplied string. If the REVERSE flag was used, the command "
- "will search for the position of the last occurrence of the "
- "specified substring.\n"
- "The following characters have special meaning in regular expressions:\n"
- " ^ Matches at beginning of input\n"
- " $ Matches at end of input\n"
- " . Matches any single character\n"
- " [ ] Matches any character(s) inside the brackets\n"
- " [^ ] Matches any character(s) not inside the brackets\n"
- " - Inside brackets, specifies an inclusive range between\n"
- " characters on either side e.g. [a-f] is [abcdef]\n"
- " To match a literal - using brackets, make it the first\n"
- " or the last character e.g. [+*/-] matches basic\n"
- " mathematical operators.\n"
- " * Matches preceding pattern zero or more times\n"
- " + Matches preceding pattern one or more times\n"
- " ? Matches preceding pattern zero or once only\n"
- " | Matches a pattern on either side of the |\n"
- " () Saves a matched subexpression, which can be referenced \n"
- " in the REGEX REPLACE operation. Additionally it is saved\n"
- " by all regular expression-related commands, including \n"
- " e.g. if( MATCHES ), in the variables CMAKE_MATCH_(0..9).\n"
- "*, + and ? have higher precedence than concatenation. | has lower "
- "precedence than concatenation. This means that the regular expression "
- "\"^ab+d$\" matches \"abbd\" but not \"ababd\", and the regular "
- "expression \"^(ab|cd)$\" matches \"ab\" but not \"abd\".\n"
- "TIMESTAMP will write a string representation of "
- "the current date and/or time to the output variable.\n"
- "Should the command be unable to obtain a timestamp "
- "the output variable will be set to the empty string \"\".\n"
- "The optional UTC flag requests the current date/time "
- "representation to be in Coordinated Universal Time (UTC) "
- "rather than local time.\n"
- "The optional <format string> may contain the following "
- "format specifiers: \n"
- " %d The day of the current month (01-31).\n"
- " %H The hour on a 24-hour clock (00-23).\n"
- " %I The hour on a 12-hour clock (01-12).\n"
- " %j The day of the current year (001-366).\n"
- " %m The month of the current year (01-12).\n"
- " %M The minute of the current hour (00-59).\n"
- " %S The second of the current minute.\n"
- " 60 represents a leap second. (00-60)\n"
- " %U The week number of the current year (00-53).\n"
- " %w The day of the current week. 0 is Sunday. (0-6)\n"
- " %y The last two digits of the current year (00-99)\n"
- " %Y The current year. \n"
- "Unknown format specifiers will be ignored "
- "and copied to the output as-is.\n"
- "If no explicit <format string> is given it will default to:\n"
- " %Y-%m-%dT%H:%M:%S for local time.\n"
- " %Y-%m-%dT%H:%M:%SZ for UTC.\n"
- "MAKE_C_IDENTIFIER will write a string which can be used as an "
- "identifier in C.";
- }
+ virtual std::string GetName() const { return "string";}
cmTypeMacro(cmStringCommand, cmCommand);
- static void ClearMatches(cmMakefile* mf);
- static void StoreMatches(cmMakefile* mf, cmsys::RegularExpression& re);
protected:
bool HandleConfigureCommand(std::vector<std::string> const& args);
bool HandleAsciiCommand(std::vector<std::string> const& args);
@@ -199,11 +67,15 @@ protected:
bool HandleReplaceCommand(std::vector<std::string> const& args);
bool HandleLengthCommand(std::vector<std::string> const& args);
bool HandleSubstringCommand(std::vector<std::string> const& args);
+ bool HandleAppendCommand(std::vector<std::string> const& args);
+ bool HandleConcatCommand(std::vector<std::string> const& args);
bool HandleStripCommand(std::vector<std::string> const& args);
bool HandleRandomCommand(std::vector<std::string> const& args);
bool HandleFindCommand(std::vector<std::string> const& args);
bool HandleTimestampCommand(std::vector<std::string> const& args);
bool HandleMakeCIdentifierCommand(std::vector<std::string> const& args);
+ bool HandleGenexStripCommand(std::vector<std::string> const& args);
+ bool HandleUuidCommand(std::vector<std::string> const& args);
class RegexReplacement
{
@@ -211,7 +83,7 @@ protected:
RegexReplacement(const char* s): number(-1), value(s) {}
RegexReplacement(const std::string& s): number(-1), value(s) {}
RegexReplacement(int n): number(n), value() {}
- RegexReplacement() {};
+ RegexReplacement() {}
int number;
std::string value;
};
diff --git a/Source/cmSubdirCommand.cxx b/Source/cmSubdirCommand.cxx
index e497b4642..6a4a83551 100644
--- a/Source/cmSubdirCommand.cxx
+++ b/Source/cmSubdirCommand.cxx
@@ -22,7 +22,6 @@ bool cmSubdirCommand
}
bool res = true;
bool excludeFromAll = false;
- bool preorder = false;
for(std::vector<std::string>::const_iterator i = args.begin();
i != args.end(); ++i)
@@ -34,38 +33,38 @@ bool cmSubdirCommand
}
if(*i == "PREORDER")
{
- preorder = true;
+ // Ignored
continue;
}
// if they specified a relative path then compute the full
std::string srcPath =
- std::string(this->Makefile->GetCurrentDirectory()) +
+ std::string(this->Makefile->GetCurrentSourceDirectory()) +
"/" + i->c_str();
- if (cmSystemTools::FileIsDirectory(srcPath.c_str()))
+ if (cmSystemTools::FileIsDirectory(srcPath))
{
std::string binPath =
- std::string(this->Makefile->GetCurrentOutputDirectory()) +
+ std::string(this->Makefile->GetCurrentBinaryDirectory()) +
"/" + i->c_str();
- this->Makefile->AddSubDirectory(srcPath.c_str(), binPath.c_str(),
- excludeFromAll, preorder, false);
+ this->Makefile->AddSubDirectory(srcPath, binPath,
+ excludeFromAll, false);
}
// otherwise it is a full path
- else if ( cmSystemTools::FileIsDirectory(i->c_str()) )
+ else if ( cmSystemTools::FileIsDirectory(*i) )
{
// we must compute the binPath from the srcPath, we just take the last
// element from the source path and use that
std::string binPath =
- std::string(this->Makefile->GetCurrentOutputDirectory()) +
- "/" + cmSystemTools::GetFilenameName(i->c_str());
- this->Makefile->AddSubDirectory(i->c_str(), binPath.c_str(),
- excludeFromAll, preorder, false);
+ std::string(this->Makefile->GetCurrentBinaryDirectory()) +
+ "/" + cmSystemTools::GetFilenameName(*i);
+ this->Makefile->AddSubDirectory(*i, binPath,
+ excludeFromAll, false);
}
else
{
std::string error = "Incorrect SUBDIRS command. Directory: ";
error += *i + " does not exist.";
- this->SetError(error.c_str());
+ this->SetError(error);
res = false;
}
}
diff --git a/Source/cmSubdirCommand.h b/Source/cmSubdirCommand.h
index 618d5ff2b..bcefd2cc0 100644
--- a/Source/cmSubdirCommand.h
+++ b/Source/cmSubdirCommand.h
@@ -42,47 +42,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "subdirs";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Deprecated. Use the add_subdirectory() command instead.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- "Add a list of subdirectories to the build.\n"
- " subdirs(dir1 dir2 ..."
- "[EXCLUDE_FROM_ALL exclude_dir1 exclude_dir2 ...]\n"
- " [PREORDER] )\n"
- "Add a list of subdirectories to the build. The add_subdirectory "
- "command should be used instead of subdirs although subdirs will "
- "still work. "
- "This will cause any CMakeLists.txt files in the sub directories "
- "to be processed by CMake. Any directories after the PREORDER flag "
- "are traversed first by makefile builds, the PREORDER flag has no "
- "effect on IDE projects. "
- " Any directories after the EXCLUDE_FROM_ALL marker "
- "will not be included in the top level makefile or project file. "
- "This is useful for having CMake create makefiles or projects for "
- "a set of examples in a project. You would want CMake to "
- "generate makefiles or project files for all the examples at "
- "the same time, but you would not want them to show up in the "
- "top level project or be built each time make is run from the top.";
- }
-
- /** This command is kept for compatibility with older CMake versions. */
- virtual bool IsDiscouraged() const
- {
- return true;
- }
+ virtual std::string GetName() const { return "subdirs";}
cmTypeMacro(cmSubdirCommand, cmCommand);
};
diff --git a/Source/cmSubdirDependsCommand.cxx b/Source/cmSubdirDependsCommand.cxx
index 2af7bf1c9..938198300 100644
--- a/Source/cmSubdirDependsCommand.cxx
+++ b/Source/cmSubdirDependsCommand.cxx
@@ -11,10 +11,10 @@
============================================================================*/
#include "cmSubdirDependsCommand.h"
-// cmSubdirDependsCommand
bool cmSubdirDependsCommand::InitialPass(std::vector<std::string> const& ,
cmExecutionStatus &)
{
+ this->Disallowed(cmPolicies::CMP0029,
+ "The subdir_depends command should not be called; see CMP0029.");
return true;
}
-
diff --git a/Source/cmSubdirDependsCommand.h b/Source/cmSubdirDependsCommand.h
index b274d0196..3f3507e96 100644
--- a/Source/cmSubdirDependsCommand.h
+++ b/Source/cmSubdirDependsCommand.h
@@ -14,64 +14,14 @@
#include "cmCommand.h"
-/** \class cmSubdirDependsCommand
- * \brief Legacy command. Do not use.
- *
- * cmSubdirDependsCommand has been left in CMake for compatability with
- * projects already using it. Its functionality in supporting parallel
- * builds is now automatic. The command does not do anything.
- */
class cmSubdirDependsCommand : public cmCommand
{
public:
- /**
- * This is a virtual constructor for the command.
- */
- virtual cmCommand* Clone()
- {
- return new cmSubdirDependsCommand;
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
+ virtual cmCommand* Clone() { return new cmSubdirDependsCommand; }
virtual bool InitialPass(std::vector<std::string> const& args,
cmExecutionStatus &status);
-
- /**
- * The name of the command as specified in CMakeList.txt.
- */
- virtual const char* GetName() const { return "subdir_depends";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Deprecated. Does nothing.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " subdir_depends(subdir dep1 dep2 ...)\n"
- "Does not do anything. This command used to help projects order "
- "parallel builds correctly. This functionality is now automatic.";
- }
-
- /** This command is kept for compatibility with older CMake versions. */
- virtual bool IsDiscouraged() const
- {
- return true;
- }
-
+ virtual std::string GetName() const { return "subdir_depends";}
cmTypeMacro(cmSubdirDependsCommand, cmCommand);
};
-
-
#endif
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 9ec49382a..3ba72876c 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -9,15 +9,15 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#if defined(_MSC_VER) && _MSC_VER < 1300
-# define _WIN32_WINNT 0x0400 /* for wincrypt.h */
-#endif
+
#include "cmSystemTools.h"
+#include "cmAlgorithms.h"
#include <ctype.h>
#include <errno.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
+#include <assert.h>
#ifdef __QNX__
# include <malloc.h> /* for malloc/free on QNX */
#endif
@@ -25,12 +25,17 @@
#include <cmsys/RegularExpression.hxx>
#include <cmsys/Directory.hxx>
#include <cmsys/System.h>
+#include <cmsys/Encoding.hxx>
#if defined(CMAKE_BUILD_WITH_CMAKE)
# include "cmArchiveWrite.h"
+# include "cmLocale.h"
# include <cm_libarchive.h>
-# include <cmsys/Terminal.h>
+# ifndef __LA_INT64_T
+# define __LA_INT64_T la_int64_t
+# endif
#endif
-#include <cmsys/stl/algorithm>
+#include <cmsys/FStream.hxx>
+#include <cmsys/Terminal.h>
#if defined(_WIN32)
# include <windows.h>
@@ -43,11 +48,14 @@
# include <sys/wait.h>
#endif
+#if defined(__APPLE__)
+# include <mach-o/dyld.h>
+#endif
+
#include <sys/stat.h>
#if defined(_WIN32) && \
- (defined(_MSC_VER) || defined(__WATCOMC__) || \
- defined(__BORLANDC__) || defined(__MINGW32__))
+ (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__MINGW32__))
# include <io.h>
#endif
@@ -60,6 +68,15 @@
# include "cmELF.h"
#endif
+#if defined(CMAKE_USE_MACH_PARSER)
+# include "cmMachO.h"
+#endif
+
+static bool cm_isspace(char c)
+{
+ return ((c & 0x80) == 0) && isspace(c);
+}
+
class cmSystemToolsFileTime
{
public:
@@ -72,10 +89,6 @@ public:
#endif
};
-#if defined(__sgi) && !defined(__GNUC__)
-# pragma set woff 1375 /* base class destructor not virtual */
-#endif
-
#if !defined(HAVE_ENVIRON_NOT_REQUIRE_PROTOTYPE)
// For GetEnvironmentVariables
# if defined(_WIN32)
@@ -85,6 +98,31 @@ extern char** environ;
# endif
#endif
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+static std::string
+cm_archive_entry_pathname(struct archive_entry *entry)
+{
+#if cmsys_STL_HAS_WSTRING
+ return cmsys::Encoding::ToNarrow(
+ archive_entry_pathname_w(entry));
+#else
+ return archive_entry_pathname(entry);
+#endif
+}
+
+static int cm_archive_read_open_file(struct archive* a,
+ const char* file,
+ int block_size)
+{
+#if cmsys_STL_HAS_WSTRING
+ std::wstring wfile = cmsys::Encoding::ToWide(file);
+ return archive_read_open_filename_w(a, wfile.c_str(), block_size);
+#else
+ return archive_read_open_filename(a, file, block_size);
+#endif
+}
+#endif
+
#ifdef _WIN32
class cmSystemToolsWindowsHandle
{
@@ -115,26 +153,14 @@ bool cmSystemTools::s_FatalErrorOccured = false;
bool cmSystemTools::s_DisableMessages = false;
bool cmSystemTools::s_ForceUnixPaths = false;
-std::string cmSystemTools::s_Windows9xComspecSubstitute = "command.com";
-void cmSystemTools::SetWindows9xComspecSubstitute(const char* str)
-{
- if ( str )
- {
- cmSystemTools::s_Windows9xComspecSubstitute = str;
- }
-}
-const char* cmSystemTools::GetWindows9xComspecSubstitute()
-{
- return cmSystemTools::s_Windows9xComspecSubstitute.c_str();
-}
-
-void (*cmSystemTools::s_ErrorCallback)(const char*, const char*,
- bool&, void*);
-void (*cmSystemTools::s_StdoutCallback)(const char*, int len, void*);
-void* cmSystemTools::s_ErrorCallbackClientData = 0;
-void* cmSystemTools::s_StdoutCallbackClientData = 0;
-bool (*cmSystemTools::s_InterruptCallback)(void*);
-void* cmSystemTools::s_InterruptCallbackClientData = 0;
+cmSystemTools::MessageCallback cmSystemTools::s_MessageCallback;
+cmSystemTools::OutputCallback cmSystemTools::s_StdoutCallback;
+cmSystemTools::OutputCallback cmSystemTools::s_StderrCallback;
+cmSystemTools::InterruptCallback cmSystemTools::s_InterruptCallback;
+void* cmSystemTools::s_MessageCallbackClientData;
+void* cmSystemTools::s_StdoutCallbackClientData;
+void* cmSystemTools::s_StderrCallbackClientData;
+void* cmSystemTools::s_InterruptCallbackClientData;
// replace replace with with as many times as it shows up in source.
// write the result into source.
@@ -186,10 +212,11 @@ void cmSystemTools::ExpandRegistryValues(std::string& source, KeyWOW64)
}
#endif
-std::string cmSystemTools::EscapeQuotes(const char* str)
+std::string cmSystemTools::EscapeQuotes(const std::string& str)
{
- std::string result = "";
- for(const char* ch = str; *ch != '\0'; ++ch)
+ std::string result;
+ result.reserve(str.size());
+ for(const char* ch = str.c_str(); *ch != '\0'; ++ch)
{
if(*ch == '"')
{
@@ -200,16 +227,23 @@ std::string cmSystemTools::EscapeQuotes(const char* str)
return result;
}
+std::string cmSystemTools::HelpFileName(std::string name)
+{
+ cmSystemTools::ReplaceString(name, "<", "");
+ cmSystemTools::ReplaceString(name, ">", "");
+ return name;
+}
+
std::string cmSystemTools::TrimWhitespace(const std::string& s)
{
std::string::const_iterator start = s.begin();
- while(start != s.end() && *start <= ' ')
+ while (start != s.end() && cm_isspace(*start))
++start;
if (start == s.end())
return "";
std::string::const_iterator stop = s.end()-1;
- while(*stop <= ' ')
+ while (cm_isspace(*stop))
--stop;
return std::string(start, stop+1);
}
@@ -253,39 +287,48 @@ bool cmSystemTools::GetInterruptFlag()
return false;
}
-void cmSystemTools::SetErrorCallback(ErrorCallback f, void* clientData)
+void cmSystemTools::SetMessageCallback(MessageCallback f, void* clientData)
{
- s_ErrorCallback = f;
- s_ErrorCallbackClientData = clientData;
+ s_MessageCallback = f;
+ s_MessageCallbackClientData = clientData;
}
-void cmSystemTools::SetStdoutCallback(StdoutCallback f, void* clientData)
+void cmSystemTools::SetStdoutCallback(OutputCallback f, void* clientData)
{
s_StdoutCallback = f;
s_StdoutCallbackClientData = clientData;
}
+void cmSystemTools::SetStderrCallback(OutputCallback f, void* clientData)
+{
+ s_StderrCallback = f;
+ s_StderrCallbackClientData = clientData;
+}
+
void cmSystemTools::Stdout(const char* s)
{
- if(s_StdoutCallback)
+ cmSystemTools::Stdout(s, strlen(s));
+}
+
+void cmSystemTools::Stderr(const char* s)
+{
+ cmSystemTools::Stderr(s, strlen(s));
+}
+
+void cmSystemTools::Stderr(const char* s, size_t length)
+{
+ if(s_StderrCallback)
{
- (*s_StdoutCallback)(s, static_cast<int>(strlen(s)),
- s_StdoutCallbackClientData);
+ (*s_StderrCallback)(s, length, s_StderrCallbackClientData);
}
else
{
- std::cout << s;
- std::cout.flush();
- }
-}
-
-void cmSystemTools::Stderr(const char* s, int length)
-{
std::cerr.write(s, length);
std::cerr.flush();
+ }
}
-void cmSystemTools::Stdout(const char* s, int length)
+void cmSystemTools::Stdout(const char* s, size_t length)
{
if(s_StdoutCallback)
{
@@ -304,10 +347,10 @@ void cmSystemTools::Message(const char* m1, const char *title)
{
return;
}
- if(s_ErrorCallback)
+ if(s_MessageCallback)
{
- (*s_ErrorCallback)(m1, title, s_DisableMessages,
- s_ErrorCallbackClientData);
+ (*s_MessageCallback)(m1, title, s_DisableMessages,
+ s_MessageCallbackClientData);
return;
}
else
@@ -333,13 +376,17 @@ bool cmSystemTools::IsInternallyOn(const char* val)
return false;
}
std::basic_string<char> v = val;
+ if (v.size() > 4)
+ {
+ return false;
+ }
for(std::basic_string<char>::iterator c = v.begin();
c != v.end(); c++)
{
*c = static_cast<char>(toupper(*c));
}
- return (v == "I_ON" || v == "i_on");
+ return v == "I_ON";
}
bool cmSystemTools::IsOn(const char* val)
@@ -348,48 +395,71 @@ bool cmSystemTools::IsOn(const char* val)
{
return false;
}
- std::basic_string<char> v = val;
+ size_t len = strlen(val);
+ if (len > 4)
+ {
+ return false;
+ }
+ std::basic_string<char> v(val, len);
+ static std::set<std::string> onValues;
+ if(onValues.empty())
+ {
+ onValues.insert("ON");
+ onValues.insert("1");
+ onValues.insert("YES");
+ onValues.insert("TRUE");
+ onValues.insert("Y");
+ }
for(std::basic_string<char>::iterator c = v.begin();
c != v.end(); c++)
{
*c = static_cast<char>(toupper(*c));
}
- return (v == "ON" || v == "1" || v == "YES" || v == "TRUE" || v == "Y");
+ return (onValues.count(v) > 0);
}
bool cmSystemTools::IsNOTFOUND(const char* val)
{
- size_t len = strlen(val);
- const char* notfound = "-NOTFOUND";
- const size_t lenNotFound = 9;
- if(len < lenNotFound-1)
- {
- return false;
- }
- if(len == lenNotFound-1)
+ if(strcmp(val, "NOTFOUND") == 0)
{
- return ( strcmp(val, "NOTFOUND") == 0);
+ return true;
}
- return ((strncmp((val + (len - lenNotFound)), notfound, lenNotFound) == 0));
+ return cmHasLiteralSuffix(val, "-NOTFOUND");
}
bool cmSystemTools::IsOff(const char* val)
{
- if (!val || strlen(val) == 0)
+ if (!val || !*val)
{
return true;
}
- std::basic_string<char> v = val;
+ size_t len = strlen(val);
+ // Try and avoid toupper() for large strings.
+ if (len > 6)
+ {
+ return cmSystemTools::IsNOTFOUND(val);
+ }
+ static std::set<std::string> offValues;
+ if(offValues.empty())
+ {
+ offValues.insert("OFF");
+ offValues.insert("0");
+ offValues.insert("NO");
+ offValues.insert("FALSE");
+ offValues.insert("N");
+ offValues.insert("IGNORE");
+ }
+ // Try and avoid toupper().
+ std::basic_string<char> v(val, len);
for(std::basic_string<char>::iterator c = v.begin();
c != v.end(); c++)
{
*c = static_cast<char>(toupper(*c));
}
- return (v == "OFF" || v == "0" || v == "NO" || v == "FALSE" ||
- v == "N" || cmSystemTools::IsNOTFOUND(v.c_str()) || v == "IGNORE");
+ return (offValues.count(v) > 0);
}
//----------------------------------------------------------------------------
@@ -435,7 +505,7 @@ void cmSystemTools::ParseWindowsCommandLine(const char* command,
{
arg.append(backslashes, '\\');
backslashes = 0;
- if(isspace(*c))
+ if (cm_isspace(*c))
{
if(in_quotes)
{
@@ -483,13 +553,6 @@ public:
args.push_back(*arg);
}
}
- void Store(std::vector<cmStdString>& args) const
- {
- for(char** arg = this->ArgV; arg && *arg; ++arg)
- {
- args.push_back(*arg);
- }
- }
};
//----------------------------------------------------------------------------
@@ -501,37 +564,9 @@ void cmSystemTools::ParseUnixCommandLine(const char* command,
argv.Store(args);
}
-//----------------------------------------------------------------------------
-void cmSystemTools::ParseUnixCommandLine(const char* command,
- std::vector<cmStdString>& args)
+std::vector<std::string> cmSystemTools::ParseArguments(const char* command)
{
- // Invoke the underlying parser.
- cmSystemToolsArgV argv = cmsysSystem_Parse_CommandForUnix(command, 0);
- argv.Store(args);
-}
-
-std::string cmSystemTools::EscapeWindowsShellArgument(const char* arg,
- int shell_flags)
-{
- char local_buffer[1024];
- char* buffer = local_buffer;
- int size = cmsysSystem_Shell_GetArgumentSizeForWindows(arg, shell_flags);
- if(size > 1024)
- {
- buffer = new char[size];
- }
- cmsysSystem_Shell_GetArgumentForWindows(arg, buffer, shell_flags);
- std::string result(buffer);
- if(buffer != local_buffer)
- {
- delete [] buffer;
- }
- return result;
-}
-
-std::vector<cmStdString> cmSystemTools::ParseArguments(const char* command)
-{
- std::vector<cmStdString> args;
+ std::vector<std::string> args;
std::string arg;
bool win_path = false;
@@ -612,23 +647,20 @@ std::vector<cmStdString> cmSystemTools::ParseArguments(const char* command)
}
-bool cmSystemTools::RunSingleCommand(std::vector<cmStdString>const& command,
- std::string* output ,
+bool cmSystemTools::RunSingleCommand(std::vector<std::string>const& command,
+ std::string* captureStdOut,
+ std::string* captureStdErr,
int* retVal , const char* dir ,
OutputOption outputflag ,
double timeout )
{
std::vector<const char*> argv;
- for(std::vector<cmStdString>::const_iterator a = command.begin();
+ for(std::vector<std::string>::const_iterator a = command.begin();
a != command.end(); ++a)
{
argv.push_back(a->c_str());
}
argv.push_back(0);
- if ( output )
- {
- *output = "";
- }
cmsysProcess* cp = cmsysProcess_New();
cmsysProcess_SetCommand(cp, &*argv.begin());
@@ -642,61 +674,74 @@ bool cmSystemTools::RunSingleCommand(std::vector<cmStdString>const& command,
{
cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDOUT, 1);
cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDERR, 1);
+ captureStdOut = 0;
+ captureStdErr = 0;
}
+ else if (outputflag == OUTPUT_MERGE ||
+ (captureStdErr && captureStdErr == captureStdOut))
+ {
+ cmsysProcess_SetOption(cp, cmsysProcess_Option_MergeOutput, 1);
+ captureStdErr = 0;
+ }
+ assert(!captureStdErr || captureStdErr != captureStdOut);
cmsysProcess_SetTimeout(cp, timeout);
cmsysProcess_Execute(cp);
- std::vector<char> tempOutput;
+ std::vector<char> tempStdOut;
+ std::vector<char> tempStdErr;
char* data;
int length;
int pipe;
- if(outputflag != OUTPUT_PASSTHROUGH && (output || outputflag != OUTPUT_NONE))
+ if(outputflag != OUTPUT_PASSTHROUGH &&
+ (captureStdOut || captureStdErr || outputflag != OUTPUT_NONE))
{
while((pipe = cmsysProcess_WaitForData(cp, &data, &length, 0)) > 0)
{
- if(output || outputflag != OUTPUT_NONE)
+ // Translate NULL characters in the output into valid text.
+ // Visual Studio 7 puts these characters in the output of its
+ // build process.
+ for(int i=0; i < length; ++i)
{
- // Translate NULL characters in the output into valid text.
- // Visual Studio 7 puts these characters in the output of its
- // build process.
- for(int i=0; i < length; ++i)
+ if(data[i] == '\0')
{
- if(data[i] == '\0')
- {
- data[i] = ' ';
- }
+ data[i] = ' ';
}
}
- if ( output )
+
+ if (pipe == cmsysProcess_Pipe_STDOUT)
{
- tempOutput.insert(tempOutput.end(), data, data+length);
+ if (outputflag != OUTPUT_NONE)
+ {
+ cmSystemTools::Stdout(data, length);
+ }
+ if (captureStdOut)
+ {
+ tempStdOut.insert(tempStdOut.end(), data, data+length);
+ }
}
- if(outputflag != OUTPUT_NONE)
+ else if (pipe == cmsysProcess_Pipe_STDERR)
{
- if(outputflag == OUTPUT_MERGE)
+ if (outputflag != OUTPUT_NONE)
{
- cmSystemTools::Stdout(data, length);
+ cmSystemTools::Stderr(data, length);
}
- else
+ if (captureStdErr)
{
- if(pipe == cmsysProcess_Pipe_STDERR)
- {
- cmSystemTools::Stderr(data, length);
- }
- else if(pipe == cmsysProcess_Pipe_STDOUT)
- {
- cmSystemTools::Stdout(data, length);
- }
+ tempStdErr.insert(tempStdErr.end(), data, data+length);
}
}
}
}
cmsysProcess_WaitForExit(cp, 0);
- if ( output && tempOutput.begin() != tempOutput.end())
+ if (captureStdOut)
{
- output->append(&*tempOutput.begin(), tempOutput.size());
+ captureStdOut->assign(tempStdOut.begin(), tempStdOut.end());
+ }
+ if (captureStdErr)
+ {
+ captureStdErr->assign(tempStdErr.begin(), tempStdErr.end());
}
bool result = true;
@@ -721,9 +766,9 @@ bool cmSystemTools::RunSingleCommand(std::vector<cmStdString>const& command,
{
std::cerr << exception_str << std::endl;
}
- if ( output )
+ if ( captureStdErr )
{
- output->append(exception_str, strlen(exception_str));
+ captureStdErr->append(exception_str, strlen(exception_str));
}
result = false;
}
@@ -734,9 +779,9 @@ bool cmSystemTools::RunSingleCommand(std::vector<cmStdString>const& command,
{
std::cerr << error_str << std::endl;
}
- if ( output )
+ if ( captureStdErr )
{
- output->append(error_str, strlen(error_str));
+ captureStdErr->append(error_str, strlen(error_str));
}
result = false;
}
@@ -747,9 +792,9 @@ bool cmSystemTools::RunSingleCommand(std::vector<cmStdString>const& command,
{
std::cerr << error_str << std::endl;
}
- if ( output )
+ if ( captureStdErr )
{
- output->append(error_str, strlen(error_str));
+ captureStdErr->append(error_str, strlen(error_str));
}
result = false;
}
@@ -760,7 +805,8 @@ bool cmSystemTools::RunSingleCommand(std::vector<cmStdString>const& command,
bool cmSystemTools::RunSingleCommand(
const char* command,
- std::string* output,
+ std::string* captureStdOut,
+ std::string* captureStdErr,
int *retVal,
const char* dir,
OutputOption outputflag,
@@ -771,359 +817,25 @@ bool cmSystemTools::RunSingleCommand(
outputflag = OUTPUT_NONE;
}
- std::vector<cmStdString> args = cmSystemTools::ParseArguments(command);
+ std::vector<std::string> args = cmSystemTools::ParseArguments(command);
if(args.size() < 1)
{
return false;
}
- return cmSystemTools::RunSingleCommand(args, output,retVal,
- dir, outputflag, timeout);
-}
-bool cmSystemTools::RunCommand(const char* command,
- std::string& output,
- const char* dir,
- bool verbose,
- int timeout)
-{
- int dummy;
- return cmSystemTools::RunCommand(command, output, dummy,
- dir, verbose, timeout);
-}
-
-#if defined(WIN32) && !defined(__CYGWIN__)
-#include "cmWin32ProcessExecution.h"
-// use this for shell commands like echo and dir
-bool RunCommandViaWin32(const char* command,
- const char* dir,
- std::string& output,
- int& retVal,
- bool verbose,
- int timeout)
-{
-#if defined(__BORLANDC__)
- return
- cmWin32ProcessExecution::
- BorlandRunCommand(command, dir, output,
- retVal,
- verbose, timeout,
- cmSystemTools::GetRunCommandHideConsole());
-#else // Visual studio
- ::SetLastError(ERROR_SUCCESS);
- if ( ! command )
- {
- cmSystemTools::Error("No command specified");
- return false;
- }
- cmWin32ProcessExecution resProc;
- if(cmSystemTools::GetRunCommandHideConsole())
- {
- resProc.SetHideWindows(true);
- }
-
- if ( cmSystemTools::GetWindows9xComspecSubstitute() )
- {
- resProc.SetConsoleSpawn(cmSystemTools::GetWindows9xComspecSubstitute() );
- }
- if ( !resProc.StartProcess(command, dir, verbose) )
- {
- output = resProc.GetOutput();
- if(verbose)
- {
- cmSystemTools::Stdout(output.c_str());
- }
- return false;
- }
- resProc.Wait(timeout);
- output = resProc.GetOutput();
- retVal = resProc.GetExitValue();
- return true;
-#endif
-}
-
-// use this for shell commands like echo and dir
-bool RunCommandViaSystem(const char* command,
- const char* dir,
- std::string& output,
- int& retVal,
- bool verbose)
-{
- std::cout << "@@ " << command << std::endl;
-
- std::string commandInDir;
- if(dir)
- {
- commandInDir = "cd ";
- commandInDir += cmSystemTools::ConvertToOutputPath(dir);
- commandInDir += " && ";
- commandInDir += command;
- }
- else
- {
- commandInDir = command;
- }
- command = commandInDir.c_str();
- std::string commandToFile = command;
- commandToFile += " > ";
- std::string tempFile;
- tempFile += _tempnam(0, "cmake");
-
- commandToFile += tempFile;
- retVal = system(commandToFile.c_str());
- std::ifstream fin(tempFile.c_str());
- if(!fin)
- {
- if(verbose)
- {
- std::string errormsg = "RunCommand produced no output: command: \"";
- errormsg += command;
- errormsg += "\"";
- errormsg += "\nOutput file: ";
- errormsg += tempFile;
- cmSystemTools::Error(errormsg.c_str());
- }
- fin.close();
- cmSystemTools::RemoveFile(tempFile.c_str());
- return false;
- }
- bool multiLine = false;
- std::string line;
- while(cmSystemTools::GetLineFromStream(fin, line))
- {
- output += line;
- if(multiLine)
- {
- output += "\n";
- }
- multiLine = true;
- }
- fin.close();
- cmSystemTools::RemoveFile(tempFile.c_str());
- return true;
-}
-
-#else // We have popen
-
-// BeOS seems to return from a successful pclose() before the process has
-// legitimately exited, or at least before SIGCHLD is thrown...the signal may
-// come quite some time after pclose returns! This causes havoc with later
-// parts of CMake that expect to catch the signal from other child processes,
-// so we explicitly wait to catch it here. This should be safe to do with
-// popen() so long as we don't actually collect the zombie process ourselves.
-#ifdef __BEOS__
-#include <signal.h>
-#undef SIGBUS // this is the same as SIGSEGV on BeOS and causes issues below.
-static volatile bool beos_seen_signal = false;
-static void beos_popen_workaround(int sig)
-{
- beos_seen_signal = true;
+ return cmSystemTools::RunSingleCommand(args, captureStdOut, captureStdErr,
+ retVal, dir, outputflag, timeout);
}
-#endif
-bool RunCommandViaPopen(const char* command,
- const char* dir,
- std::string& output,
- int& retVal,
- bool verbose,
- int /*timeout*/)
+std::string
+cmSystemTools::PrintSingleCommand(std::vector<std::string> const& command)
{
- // if only popen worked on windows.....
- std::string commandInDir;
- if(dir)
- {
- commandInDir = "cd \"";
- commandInDir += dir;
- commandInDir += "\" && ";
- commandInDir += command;
- }
- else
- {
- commandInDir = command;
- }
-#ifndef __VMS
- commandInDir += " 2>&1";
-#endif
- command = commandInDir.c_str();
- const int BUFFER_SIZE = 4096;
- char buffer[BUFFER_SIZE];
- if(verbose)
+ if (command.empty())
{
- cmSystemTools::Stdout("running ");
- cmSystemTools::Stdout(command);
- cmSystemTools::Stdout("\n");
+ return std::string();
}
- fflush(stdout);
- fflush(stderr);
-
-#ifdef __BEOS__
- beos_seen_signal = false;
- signal(SIGCHLD, beos_popen_workaround);
-#endif
- FILE* cpipe = popen(command, "r");
- if(!cpipe)
- {
-#ifdef __BEOS__
- signal(SIGCHLD, SIG_DFL);
-#endif
- return false;
- }
- if (!fgets(buffer, BUFFER_SIZE, cpipe))
- {
- buffer[0] = 0;
- }
- while(!feof(cpipe))
- {
- if(verbose)
- {
- cmSystemTools::Stdout(buffer);
- }
- output += buffer;
- if(!fgets(buffer, BUFFER_SIZE, cpipe))
- {
- buffer[0] = 0;
- }
- }
-
- retVal = pclose(cpipe);
-
-#ifdef __BEOS__
- for (int i = 0; (!beos_seen_signal) && (i < 3); i++)
- {
- ::sleep(1); // signals should interrupt this...
- }
-
- if (!beos_seen_signal)
- {
- signal(SIGCHLD, SIG_DFL); // oh well, didn't happen. Go on anyhow.
- }
-#endif
-
- if (WIFEXITED(retVal))
- {
- retVal = WEXITSTATUS(retVal);
- return true;
- }
- if (WIFSIGNALED(retVal))
- {
- retVal = WTERMSIG(retVal);
- cmOStringStream error;
- error << "\nProcess terminated due to ";
- switch (retVal)
- {
-#ifdef SIGKILL
- case SIGKILL:
- error << "SIGKILL";
- break;
-#endif
-#ifdef SIGFPE
- case SIGFPE:
- error << "SIGFPE";
- break;
-#endif
-#ifndef __HAIKU__
-#ifdef SIGBUS
- case SIGBUS:
- error << "SIGBUS";
- break;
-#endif
-#endif
-#ifdef SIGSEGV
- case SIGSEGV:
- error << "SIGSEGV";
- break;
-#endif
- default:
- error << "signal " << retVal;
- break;
- }
- output += error.str();
- }
- return false;
-}
-
-#endif // endif WIN32 not CYGWIN
-
-
-// run a command unix uses popen (easy)
-// windows uses system and ShortPath
-bool cmSystemTools::RunCommand(const char* command,
- std::string& output,
- int &retVal,
- const char* dir,
- bool verbose,
- int timeout)
-{
- if(s_DisableRunCommandOutput)
- {
- verbose = false;
- }
-
-#if defined(WIN32) && !defined(__CYGWIN__)
- // if the command does not start with a quote, then
- // try to find the program, and if the program can not be
- // found use system to run the command as it must be a built in
- // shell command like echo or dir
- int count = 0;
- if(command[0] == '\"')
- {
- // count the number of quotes
- for(const char* s = command; *s != 0; ++s)
- {
- if(*s == '\"')
- {
- count++;
- if(count > 2)
- {
- break;
- }
- }
- }
- // if there are more than two double quotes use
- // GetShortPathName, the cmd.exe program in windows which
- // is used by system fails to execute if there are more than
- // one set of quotes in the arguments
- if(count > 2)
- {
- cmsys::RegularExpression quoted("^\"([^\"]*)\"[ \t](.*)");
- if(quoted.find(command))
- {
- std::string shortCmd;
- std::string cmd = quoted.match(1);
- std::string args = quoted.match(2);
- if(! cmSystemTools::FileExists(cmd.c_str()) )
- {
- shortCmd = cmd;
- }
- else if(!cmSystemTools::GetShortPath(cmd.c_str(), shortCmd))
- {
- cmSystemTools::Error("GetShortPath failed for " , cmd.c_str());
- return false;
- }
- shortCmd += " ";
- shortCmd += args;
-
- //return RunCommandViaSystem(shortCmd.c_str(), dir,
- // output, retVal, verbose);
- //return WindowsRunCommand(shortCmd.c_str(), dir,
- //output, retVal, verbose);
- return RunCommandViaWin32(shortCmd.c_str(), dir,
- output, retVal, verbose, timeout);
- }
- else
- {
- cmSystemTools::Error("Could not parse command line with quotes ",
- command);
- }
- }
- }
- // if there is only one set of quotes or no quotes then just run the command
- //return RunCommandViaSystem(command, dir, output, retVal, verbose);
- //return WindowsRunCommand(command, dir, output, retVal, verbose);
- return ::RunCommandViaWin32(command, dir, output, retVal, verbose, timeout);
-#else
- return ::RunCommandViaPopen(command, dir, output, retVal, verbose, timeout);
-#endif
+ return cmWrap('"', command, '"', " ");
}
bool cmSystemTools::DoesFileExistWithExtensions(
@@ -1166,7 +878,7 @@ std::string cmSystemTools::FileExistsInParentDirectories(const char* fname,
break;
}
prevDir = dir;
- dir = cmSystemTools::GetParentDirectory(dir.c_str());
+ dir = cmSystemTools::GetParentDirectory(dir);
}
return "";
}
@@ -1183,6 +895,44 @@ bool cmSystemTools::CopyFileIfDifferent(const char* source,
}
//----------------------------------------------------------------------------
+#ifdef _WIN32
+cmSystemTools::WindowsFileRetry cmSystemTools::GetWindowsFileRetry()
+{
+ static WindowsFileRetry retry = {0,0};
+ if(!retry.Count)
+ {
+ unsigned int data[2] = {0,0};
+ HKEY const keys[2] = {HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE};
+ wchar_t const* const values[2] = {L"FilesystemRetryCount",
+ L"FilesystemRetryDelay"};
+ for(int k=0; k < 2; ++k)
+ {
+ HKEY hKey;
+ if(RegOpenKeyExW(keys[k], L"Software\\Kitware\\CMake\\Config",
+ 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
+ {
+ for(int v=0; v < 2; ++v)
+ {
+ DWORD dwData, dwType, dwSize = 4;
+ if(!data[v] &&
+ RegQueryValueExW(hKey, values[v], 0, &dwType, (BYTE *)&dwData,
+ &dwSize) == ERROR_SUCCESS &&
+ dwType == REG_DWORD && dwSize == 4)
+ {
+ data[v] = static_cast<unsigned int>(dwData);
+ }
+ }
+ RegCloseKey(hKey);
+ }
+ }
+ retry.Count = data[0]? data[0] : 5;
+ retry.Delay = data[1]? data[1] : 500;
+ }
+ return retry;
+}
+#endif
+
+//----------------------------------------------------------------------------
bool cmSystemTools::RenameFile(const char* oldname, const char* newname)
{
#ifdef _WIN32
@@ -1193,35 +943,44 @@ bool cmSystemTools::RenameFile(const char* oldname, const char* newname)
fails then remove the read-only attribute from any existing destination.
Try multiple times since we may be racing against another process
creating/opening the destination file just before our MoveFileEx. */
- int tries = 5;
- while(!MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING) && --tries)
+ WindowsFileRetry retry = cmSystemTools::GetWindowsFileRetry();
+ while(!MoveFileExW(
+ SystemTools::ConvertToWindowsExtendedPath(oldname).c_str(),
+ SystemTools::ConvertToWindowsExtendedPath(newname).c_str(),
+ MOVEFILE_REPLACE_EXISTING) && --retry.Count)
{
- // Try again only if failure was due to access permissions.
- if(GetLastError() != ERROR_ACCESS_DENIED)
+ DWORD last_error = GetLastError();
+ // Try again only if failure was due to access/sharing permissions.
+ if(last_error != ERROR_ACCESS_DENIED &&
+ last_error != ERROR_SHARING_VIOLATION)
{
return false;
}
- DWORD attrs = GetFileAttributes(newname);
+ DWORD attrs =
+ GetFileAttributesW(
+ SystemTools::ConvertToWindowsExtendedPath(newname).c_str());
if((attrs != INVALID_FILE_ATTRIBUTES) &&
(attrs & FILE_ATTRIBUTE_READONLY))
{
// Remove the read-only attribute from the destination file.
- SetFileAttributes(newname, attrs & ~FILE_ATTRIBUTE_READONLY);
+ SetFileAttributesW(
+ SystemTools::ConvertToWindowsExtendedPath(newname).c_str(),
+ attrs & ~FILE_ATTRIBUTE_READONLY);
}
else
{
// The file may be temporarily in use so wait a bit.
- cmSystemTools::Delay(100);
+ cmSystemTools::Delay(retry.Delay);
}
}
- return tries > 0;
+ return retry.Count > 0;
#else
/* On UNIX we have an OS-provided call to do this atomically. */
return rename(oldname, newname) == 0;
#endif
}
-bool cmSystemTools::ComputeFileMD5(const char* source, char* md5out)
+bool cmSystemTools::ComputeFileMD5(const std::string& source, char* md5out)
{
#if defined(CMAKE_BUILD_WITH_CMAKE)
cmCryptoHashMD5 md5;
@@ -1236,7 +995,7 @@ bool cmSystemTools::ComputeFileMD5(const char* source, char* md5out)
#endif
}
-std::string cmSystemTools::ComputeStringMD5(const char* input)
+std::string cmSystemTools::ComputeStringMD5(const std::string& input)
{
#if defined(CMAKE_BUILD_WITH_CMAKE)
cmCryptoHashMD5 md5;
@@ -1248,11 +1007,101 @@ std::string cmSystemTools::ComputeStringMD5(const char* input)
#endif
}
-void cmSystemTools::Glob(const char *directory, const char *regexp,
+//----------------------------------------------------------------------------
+std::string cmSystemTools::ComputeCertificateThumbprint(
+ const std::string& source)
+{
+ std::string thumbprint;
+
+#if defined(CMAKE_BUILD_WITH_CMAKE) && defined(_WIN32)
+ BYTE* certData = NULL;
+ CRYPT_INTEGER_BLOB cryptBlob;
+ HCERTSTORE certStore = NULL;
+ PCCERT_CONTEXT certContext = NULL;
+
+ HANDLE certFile =
+ CreateFileW(cmsys::Encoding::ToWide(source.c_str()).c_str(),
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (certFile != INVALID_HANDLE_VALUE && certFile != NULL)
+ {
+ DWORD fileSize = GetFileSize(certFile, NULL);
+ if (fileSize != INVALID_FILE_SIZE)
+ {
+ certData = new BYTE[fileSize];
+ if (certData != NULL)
+ {
+ DWORD dwRead = 0;
+ if (ReadFile(certFile, certData, fileSize, &dwRead, NULL))
+ {
+ cryptBlob.cbData = fileSize;
+ cryptBlob.pbData = certData;
+
+ // Verify that this is a valid cert
+ if (PFXIsPFXBlob(&cryptBlob))
+ {
+ // Open the certificate as a store
+ certStore = PFXImportCertStore(
+ &cryptBlob, NULL, CRYPT_EXPORTABLE);
+ if (certStore != NULL)
+ {
+ // There should only be 1 cert.
+ certContext = CertEnumCertificatesInStore(certStore,
+ certContext);
+ if (certContext != NULL)
+ {
+ // The hash is 20 bytes
+ BYTE hashData[20];
+ DWORD hashLength = 20;
+
+ // Buffer to print the hash. Each byte takes 2 chars +
+ // terminating character
+ char hashPrint[41];
+ char *pHashPrint = hashPrint;
+ // Get the hash property from the certificate
+ if (CertGetCertificateContextProperty(certContext,
+ CERT_HASH_PROP_ID, hashData, &hashLength))
+ {
+ for (DWORD i = 0; i < hashLength; i++)
+ {
+ // Convert each byte to hexadecimal
+ sprintf(pHashPrint, "%02X", hashData[i]);
+ pHashPrint += 2;
+ }
+ *pHashPrint = '\0';
+ thumbprint = hashPrint;
+ }
+ CertFreeCertificateContext(certContext);
+ }
+ CertCloseStore(certStore, 0);
+ }
+ }
+ }
+ delete[] certData;
+ }
+ }
+ CloseHandle(certFile);
+ }
+#else
+ (void)source;
+ cmSystemTools::Message("ComputeCertificateThumbprint is not implemented",
+ "Error");
+#endif
+
+ return thumbprint;
+}
+
+void cmSystemTools::Glob(const std::string& directory,
+ const std::string& regexp,
std::vector<std::string>& files)
{
cmsys::Directory d;
- cmsys::RegularExpression reg(regexp);
+ cmsys::RegularExpression reg(regexp.c_str());
if (d.Load(directory))
{
@@ -1271,21 +1120,20 @@ void cmSystemTools::Glob(const char *directory, const char *regexp,
}
-void cmSystemTools::GlobDirs(const char *fullPath,
+void cmSystemTools::GlobDirs(const std::string& path,
std::vector<std::string>& files)
{
- std::string path = fullPath;
std::string::size_type pos = path.find("/*");
if(pos == std::string::npos)
{
- files.push_back(fullPath);
+ files.push_back(path);
return;
}
std::string startPath = path.substr(0, pos);
std::string finishPath = path.substr(pos+2);
cmsys::Directory d;
- if (d.Load(startPath.c_str()))
+ if (d.Load(startPath))
{
for (unsigned int i = 0; i < d.GetNumberOfFiles(); ++i)
{
@@ -1295,10 +1143,10 @@ void cmSystemTools::GlobDirs(const char *fullPath,
std::string fname = startPath;
fname +="/";
fname += d.GetFile(i);
- if(cmSystemTools::FileIsDirectory(fname.c_str()))
+ if(cmSystemTools::FileIsDirectory(fname))
{
fname += finishPath;
- cmSystemTools::GlobDirs(fname.c_str(), files);
+ cmSystemTools::GlobDirs(fname, files);
}
}
}
@@ -1321,7 +1169,7 @@ void cmSystemTools::ExpandListArgument(const std::string& arg,
bool emptyArgs)
{
// If argument is empty, it is an empty list.
- if(arg.length() == 0 && !emptyArgs)
+ if(!emptyArgs && arg.empty())
{
return;
}
@@ -1331,10 +1179,11 @@ void cmSystemTools::ExpandListArgument(const std::string& arg,
newargs.push_back(arg);
return;
}
- std::vector<char> newArgVec;
+ std::string newArg;
+ const char *last = arg.c_str();
// Break the string at non-escaped semicolons not nested in [].
int squareNesting = 0;
- for(const char* c = arg.c_str(); *c; ++c)
+ for(const char* c = last; *c; ++c)
{
switch(*c)
{
@@ -1342,34 +1191,21 @@ void cmSystemTools::ExpandListArgument(const std::string& arg,
{
// We only want to allow escaping of semicolons. Other
// escapes should not be processed here.
- ++c;
- if(*c == ';')
+ const char* next = c + 1;
+ if(*next == ';')
{
- newArgVec.push_back(*c);
- }
- else
- {
- newArgVec.push_back('\\');
- if(*c)
- {
- newArgVec.push_back(*c);
- }
- else
- {
- // Terminate the loop properly.
- --c;
- }
+ newArg.append(last, c - last);
+ // Skip over the escape character
+ last = c = next;
}
} break;
case '[':
{
++squareNesting;
- newArgVec.push_back(*c);
} break;
case ']':
{
--squareNesting;
- newArgVec.push_back(*c);
} break;
case ';':
{
@@ -1377,36 +1213,33 @@ void cmSystemTools::ExpandListArgument(const std::string& arg,
// brackets.
if(squareNesting == 0)
{
- if ( newArgVec.size() || emptyArgs )
+ newArg.append(last, c - last);
+ // Skip over the semicolon
+ last = c + 1;
+ if ( !newArg.empty() || emptyArgs )
{
// Add the last argument if the string is not empty.
- newArgVec.push_back(0);
- newargs.push_back(&*newArgVec.begin());
- newArgVec.clear();
+ newargs.push_back(newArg);
+ newArg = "";
}
}
- else
- {
- newArgVec.push_back(*c);
- }
} break;
default:
{
// Just append this character.
- newArgVec.push_back(*c);
} break;
}
}
- if ( newArgVec.size() || emptyArgs )
+ newArg.append(last);
+ if ( !newArg.empty() || emptyArgs )
{
// Add the last argument if the string is not empty.
- newArgVec.push_back(0);
- newargs.push_back(&*newArgVec.begin());
+ newargs.push_back(newArg);
}
}
-bool cmSystemTools::SimpleGlob(const cmStdString& glob,
- std::vector<cmStdString>& files,
+bool cmSystemTools::SimpleGlob(const std::string& glob,
+ std::vector<std::string>& files,
int type /* = 0 */)
{
files.clear();
@@ -1417,14 +1250,14 @@ bool cmSystemTools::SimpleGlob(const cmStdString& glob,
std::string path = cmSystemTools::GetFilenamePath(glob);
std::string ppath = cmSystemTools::GetFilenameName(glob);
ppath = ppath.substr(0, ppath.size()-1);
- if ( path.size() == 0 )
+ if (path.empty())
{
path = "/";
}
bool res = false;
cmsys::Directory d;
- if (d.Load(path.c_str()))
+ if (d.Load(path))
{
for (unsigned int i = 0; i < d.GetNumberOfFiles(); ++i)
{
@@ -1438,11 +1271,11 @@ bool cmSystemTools::SimpleGlob(const cmStdString& glob,
}
fname += d.GetFile(i);
std::string sfname = d.GetFile(i);
- if ( type > 0 && cmSystemTools::FileIsDirectory(fname.c_str()) )
+ if ( type > 0 && cmSystemTools::FileIsDirectory(fname) )
{
continue;
}
- if ( type < 0 && !cmSystemTools::FileIsDirectory(fname.c_str()) )
+ if ( type < 0 && !cmSystemTools::FileIsDirectory(fname) )
{
continue;
}
@@ -1524,15 +1357,11 @@ cmSystemTools::FileFormat cmSystemTools::GetFileFormat(const char* cext)
return cmSystemTools::UNKNOWN_FILE_FORMAT;
}
-bool cmSystemTools::Split(const char* s, std::vector<cmStdString>& l)
+bool cmSystemTools::Split(const char* s, std::vector<std::string>& l)
{
std::vector<std::string> temp;
bool res = Superclass::Split(s, temp);
- for(std::vector<std::string>::const_iterator i = temp.begin();
- i != temp.end(); ++i)
- {
- l.push_back(*i);
- }
+ l.insert(l.end(), temp.begin(), temp.end());
return res;
}
@@ -1575,15 +1404,6 @@ std::string cmSystemTools::ConvertToRunCommandPath(const char* path)
#endif
}
-bool cmSystemTools::StringEndsWith(const char* str1, const char* str2)
-{
- if ( !str1 || !str2 || strlen(str1) < strlen(str2) )
- {
- return 0;
- }
- return !strncmp(str1 + (strlen(str1)-strlen(str2)), str2, strlen(str2));
-}
-
// compute the relative path from here to there
std::string cmSystemTools::RelativePath(const char* local, const char* remote)
{
@@ -1610,8 +1430,8 @@ std::string cmSystemTools::CollapseCombinedPath(std::string const& dir,
std::vector<std::string> dirComponents;
std::vector<std::string> fileComponents;
- cmSystemTools::SplitPath(dir.c_str(), dirComponents);
- cmSystemTools::SplitPath(file.c_str(), fileComponents);
+ cmSystemTools::SplitPath(dir, dirComponents);
+ cmSystemTools::SplitPath(file, fileComponents);
if(fileComponents.empty())
{
@@ -1666,7 +1486,7 @@ void cmSystemTools::AppendEnv(std::vector<std::string> const& env)
for(std::vector<std::string>::const_iterator eit = env.begin();
eit != env.end(); ++eit)
{
- cmSystemTools::PutEnv(eit->c_str());
+ cmSystemTools::PutEnv(*eit);
}
}
@@ -1724,24 +1544,19 @@ void cmSystemTools::EnableVSConsoleOutput()
bool cmSystemTools::IsPathToFramework(const char* path)
{
- if(cmSystemTools::FileIsFullPath(path))
- {
- std::string libname = path;
- if(libname.find(".framework") == libname.size()+1-sizeof(".framework"))
- {
- return true;
- }
- }
- return false;
+ return (cmSystemTools::FileIsFullPath(path) &&
+ cmHasLiteralSuffix(path, ".framework"));
}
bool cmSystemTools::CreateTar(const char* outFileName,
- const std::vector<cmStdString>& files,
- bool gzip, bool bzip2, bool verbose)
+ const std::vector<std::string>& files,
+ cmTarCompression compressType,
+ bool verbose, std::string const& mtime,
+ std::string const& format)
{
#if defined(CMAKE_BUILD_WITH_CMAKE)
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
- std::ofstream fout(outFileName, std::ios::out | cmsys_ios_binary);
+ cmsys::ofstream fout(outFileName, std::ios::out | std::ios::binary);
if(!fout)
{
std::string e = "Cannot open output file \"";
@@ -1751,12 +1566,29 @@ bool cmSystemTools::CreateTar(const char* outFileName,
cmSystemTools::Error(e.c_str());
return false;
}
- cmArchiveWrite a(fout, (gzip? cmArchiveWrite::CompressGZip :
- (bzip2? cmArchiveWrite::CompressBZip2 :
- cmArchiveWrite::CompressNone)),
- cmArchiveWrite::TypeTAR);
+ cmArchiveWrite::Compress compress = cmArchiveWrite::CompressNone;
+ switch (compressType)
+ {
+ case TarCompressGZip:
+ compress = cmArchiveWrite::CompressGZip;
+ break;
+ case TarCompressBZip2:
+ compress = cmArchiveWrite::CompressBZip2;
+ break;
+ case TarCompressXZ:
+ compress = cmArchiveWrite::CompressXZ;
+ break;
+ case TarCompressNone:
+ compress = cmArchiveWrite::CompressNone;
+ break;
+ }
+
+ cmArchiveWrite a(fout, compress,
+ format.empty() ? "paxr" : format);
+
+ a.SetMTime(mtime);
a.SetVerbose(verbose);
- for(std::vector<cmStdString>::const_iterator i = files.begin();
+ for(std::vector<std::string>::const_iterator i = files.begin();
i != files.end(); ++i)
{
std::string path = *i;
@@ -1779,7 +1611,6 @@ bool cmSystemTools::CreateTar(const char* outFileName,
#else
(void)outFileName;
(void)files;
- (void)gzip;
(void)verbose;
return false;
#endif
@@ -1892,7 +1723,7 @@ namespace{
}
strftime(tmp, sizeof(tmp), fmt, localtime(&tim));
fprintf(out, " %s ", tmp);
- fprintf(out, "%s", archive_entry_pathname(entry));
+ fprintf(out, "%s", cm_archive_entry_pathname(entry).c_str());
/* Extra information for links. */
if (archive_entry_hardlink(entry)) /* Hard link */
@@ -1905,9 +1736,6 @@ namespace{
fprintf(out, " -> %s", archive_entry_symlink(entry));
}
}
-#ifdef __BORLANDC__
-# pragma warn -8066 /* unreachable code */
-#endif
long copy_data(struct archive *ar, struct archive *aw)
{
@@ -1939,22 +1767,28 @@ long copy_data(struct archive *ar, struct archive *aw)
return (r);
}
}
- return r;
+#if !defined(__clang__) && !defined(__HP_aCC)
+ return r; /* this should not happen but it quiets some compilers */
+#endif
}
bool extract_tar(const char* outFileName, bool verbose,
bool extract)
{
+ cmLocaleRAII localeRAII;
+ static_cast<void>(localeRAII);
struct archive* a = archive_read_new();
struct archive *ext = archive_write_disk_new();
- archive_read_support_compression_all(a);
+ archive_read_support_filter_all(a);
archive_read_support_format_all(a);
struct archive_entry *entry;
- int r = archive_read_open_file(a, outFileName, 10240);
+ int r = cm_archive_read_open_file(a, outFileName, 10240);
if(r)
{
cmSystemTools::Error("Problem with archive_read_open_file(): ",
archive_error_string(a));
+ archive_write_free(ext);
+ archive_read_close(a);
return false;
}
for (;;)
@@ -1970,18 +1804,23 @@ bool extract_tar(const char* outFileName, bool verbose,
archive_error_string(a));
break;
}
- if (verbose && extract)
- {
- cmSystemTools::Stdout("x ");
- cmSystemTools::Stdout(archive_entry_pathname(entry));
- }
- if(verbose && !extract)
+ if(verbose)
{
- list_item_verbose(stdout, entry);
+ if(extract)
+ {
+ cmSystemTools::Stdout("x ");
+ cmSystemTools::Stdout(cm_archive_entry_pathname(entry).c_str());
+ }
+ else
+ {
+ list_item_verbose(stdout, entry);
+ }
+ cmSystemTools::Stdout("\n");
}
else if(!extract)
{
- cmSystemTools::Stdout(archive_entry_pathname(entry));
+ cmSystemTools::Stdout(cm_archive_entry_pathname(entry).c_str());
+ cmSystemTools::Stdout("\n");
}
if(extract)
{
@@ -1995,15 +1834,7 @@ bool extract_tar(const char* outFileName, bool verbose,
}
r = archive_write_header(ext, entry);
- if (r != ARCHIVE_OK)
- {
- cmSystemTools::Error("Problem with archive_write_header(): ",
- archive_error_string(ext));
- cmSystemTools::Error("Current file: ",
- archive_entry_pathname(entry));
- break;
- }
- else
+ if (r == ARCHIVE_OK)
{
copy_data(a, ext);
r = archive_write_finish_entry(ext);
@@ -2014,21 +1845,35 @@ bool extract_tar(const char* outFileName, bool verbose,
break;
}
}
- }
- if (verbose || !extract)
- {
- cmSystemTools::Stdout("\n");
+#ifdef _WIN32
+ else if(const char* linktext = archive_entry_symlink(entry))
+ {
+ std::cerr << "cmake -E tar: warning: skipping symbolic link \""
+ << cm_archive_entry_pathname(entry)
+ << "\" -> \""
+ << linktext << "\"." << std::endl;
+ }
+#endif
+ else
+ {
+ cmSystemTools::Error("Problem with archive_write_header(): ",
+ archive_error_string(ext));
+ cmSystemTools::Error("Current file: ",
+ cm_archive_entry_pathname(entry).c_str());
+ break;
+ }
}
}
+ archive_write_free(ext);
archive_read_close(a);
- archive_read_finish(a);
+ archive_read_free(a);
return r == ARCHIVE_EOF || r == ARCHIVE_OK;
}
}
#endif
bool cmSystemTools::ExtractTar(const char* outFileName,
- bool , bool verbose)
+ bool verbose)
{
#if defined(CMAKE_BUILD_WITH_CMAKE)
return extract_tar(outFileName, verbose, true);
@@ -2040,7 +1885,6 @@ bool cmSystemTools::ExtractTar(const char* outFileName,
}
bool cmSystemTools::ListTar(const char* outFileName,
- bool ,
bool verbose)
{
#if defined(CMAKE_BUILD_WITH_CMAKE)
@@ -2189,10 +2033,13 @@ bool cmSystemTools::CopyFileTime(const char* fromFile, const char* toFile)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
cmSystemToolsWindowsHandle hFrom =
- CreateFile(fromFile, GENERIC_READ, FILE_SHARE_READ, 0,
- OPEN_EXISTING, 0, 0);
+ CreateFileW(SystemTools::ConvertToWindowsExtendedPath(fromFile).c_str(),
+ GENERIC_READ, FILE_SHARE_READ, 0,
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
cmSystemToolsWindowsHandle hTo =
- CreateFile(toFile, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
+ CreateFileW(SystemTools::ConvertToWindowsExtendedPath(toFile).c_str(),
+ FILE_WRITE_ATTRIBUTES, 0, 0, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS, 0);
if(!hFrom || !hTo)
{
return false;
@@ -2243,7 +2090,9 @@ bool cmSystemTools::FileTimeGet(const char* fname, cmSystemToolsFileTime* t)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
cmSystemToolsWindowsHandle h =
- CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
+ CreateFileW(SystemTools::ConvertToWindowsExtendedPath(fname).c_str(),
+ GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS, 0);
if(!h)
{
return false;
@@ -2269,7 +2118,9 @@ bool cmSystemTools::FileTimeSet(const char* fname, cmSystemToolsFileTime* t)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
cmSystemToolsWindowsHandle h =
- CreateFile(fname, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
+ CreateFileW(SystemTools::ConvertToWindowsExtendedPath(fname).c_str(),
+ FILE_WRITE_ATTRIBUTES, 0, 0, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS, 0);
if(!h)
{
return false;
@@ -2333,7 +2184,7 @@ unsigned int cmSystemTools::RandomSeed()
} seed;
// Try using a real random source.
- std::ifstream fin("/dev/urandom");
+ cmsys::ifstream fin("/dev/urandom");
if(fin && fin.read(seed.bytes, sizeof(seed)) &&
fin.gcount() == sizeof(seed))
{
@@ -2353,41 +2204,190 @@ unsigned int cmSystemTools::RandomSeed()
}
//----------------------------------------------------------------------------
-static std::string cmSystemToolsExecutableDirectory;
-void cmSystemTools::FindExecutableDirectory(const char* argv0)
-{
+static std::string cmSystemToolsCMakeCommand;
+static std::string cmSystemToolsCTestCommand;
+static std::string cmSystemToolsCPackCommand;
+static std::string cmSystemToolsCMakeCursesCommand;
+static std::string cmSystemToolsCMakeGUICommand;
+static std::string cmSystemToolsCMClDepsCommand;
+static std::string cmSystemToolsCMakeRoot;
+void cmSystemTools::FindCMakeResources(const char* argv0)
+{
+ std::string exe_dir;
#if defined(_WIN32) && !defined(__CYGWIN__)
(void)argv0; // ignore this on windows
- char modulepath[_MAX_PATH];
- ::GetModuleFileName(NULL, modulepath, sizeof(modulepath));
- cmSystemToolsExecutableDirectory =
- cmSystemTools::GetFilenamePath(modulepath);
- return;
+ wchar_t modulepath[_MAX_PATH];
+ ::GetModuleFileNameW(NULL, modulepath, sizeof(modulepath));
+ exe_dir =
+ cmSystemTools::GetFilenamePath(cmsys::Encoding::ToNarrow(modulepath));
+#elif defined(__APPLE__)
+ (void)argv0; // ignore this on OS X
+# define CM_EXE_PATH_LOCAL_SIZE 16384
+ char exe_path_local[CM_EXE_PATH_LOCAL_SIZE];
+# if defined(MAC_OS_X_VERSION_10_3) && !defined(MAC_OS_X_VERSION_10_4)
+ unsigned long exe_path_size = CM_EXE_PATH_LOCAL_SIZE;
+# else
+ uint32_t exe_path_size = CM_EXE_PATH_LOCAL_SIZE;
+# endif
+# undef CM_EXE_PATH_LOCAL_SIZE
+ char* exe_path = exe_path_local;
+ if(_NSGetExecutablePath(exe_path, &exe_path_size) < 0)
+ {
+ exe_path = (char*)malloc(exe_path_size);
+ _NSGetExecutablePath(exe_path, &exe_path_size);
+ }
+ exe_dir =
+ cmSystemTools::GetFilenamePath(
+ cmSystemTools::GetRealPath(exe_path));
+ if(exe_path != exe_path_local)
+ {
+ free(exe_path);
+ }
+ if(cmSystemTools::GetFilenameName(exe_dir) == "MacOS")
+ {
+ // The executable is inside an application bundle.
+ // Look for ../bin (install tree) and then fall back to
+ // ../../../bin (build tree).
+ exe_dir = cmSystemTools::GetFilenamePath(exe_dir);
+ if(cmSystemTools::FileExists((exe_dir+"/bin/cmake").c_str()))
+ {
+ exe_dir += "/bin";
+ }
+ else
+ {
+ exe_dir = cmSystemTools::GetFilenamePath(exe_dir);
+ exe_dir = cmSystemTools::GetFilenamePath(exe_dir);
+ }
+ }
#else
std::string errorMsg;
std::string exe;
if(cmSystemTools::FindProgramPath(argv0, exe, errorMsg))
{
// remove symlinks
- exe = cmSystemTools::GetRealPath(exe.c_str());
- cmSystemToolsExecutableDirectory =
- cmSystemTools::GetFilenamePath(exe.c_str());
+ exe = cmSystemTools::GetRealPath(exe);
+ exe_dir =
+ cmSystemTools::GetFilenamePath(exe);
}
else
{
// ???
}
#endif
+ cmSystemToolsCMakeCommand = exe_dir;
+ cmSystemToolsCMakeCommand += "/cmake";
+ cmSystemToolsCMakeCommand += cmSystemTools::GetExecutableExtension();
+#ifndef CMAKE_BUILD_WITH_CMAKE
+ // The bootstrap cmake does not provide the other tools,
+ // so use the directory where they are about to be built.
+ exe_dir = CMAKE_BOOTSTRAP_BINARY_DIR "/bin";
+#endif
+ cmSystemToolsCTestCommand = exe_dir;
+ cmSystemToolsCTestCommand += "/ctest";
+ cmSystemToolsCTestCommand += cmSystemTools::GetExecutableExtension();
+ cmSystemToolsCPackCommand = exe_dir;
+ cmSystemToolsCPackCommand += "/cpack";
+ cmSystemToolsCPackCommand += cmSystemTools::GetExecutableExtension();
+ cmSystemToolsCMakeGUICommand = exe_dir;
+ cmSystemToolsCMakeGUICommand += "/cmake-gui";
+ cmSystemToolsCMakeGUICommand += cmSystemTools::GetExecutableExtension();
+ if(!cmSystemTools::FileExists(cmSystemToolsCMakeGUICommand.c_str()))
+ {
+ cmSystemToolsCMakeGUICommand = "";
+ }
+ cmSystemToolsCMakeCursesCommand = exe_dir;
+ cmSystemToolsCMakeCursesCommand += "/ccmake";
+ cmSystemToolsCMakeCursesCommand += cmSystemTools::GetExecutableExtension();
+ if(!cmSystemTools::FileExists(cmSystemToolsCMakeCursesCommand.c_str()))
+ {
+ cmSystemToolsCMakeCursesCommand = "";
+ }
+ cmSystemToolsCMClDepsCommand = exe_dir;
+ cmSystemToolsCMClDepsCommand += "/cmcldeps";
+ cmSystemToolsCMClDepsCommand += cmSystemTools::GetExecutableExtension();
+ if(!cmSystemTools::FileExists(cmSystemToolsCMClDepsCommand.c_str()))
+ {
+ cmSystemToolsCMClDepsCommand = "";
+ }
+
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ // Install tree has "<prefix>/bin/cmake" and "<prefix><CMAKE_DATA_DIR>".
+ std::string dir = cmSystemTools::GetFilenamePath(exe_dir);
+ cmSystemToolsCMakeRoot = dir + CMAKE_DATA_DIR;
+ if(!cmSystemTools::FileExists(
+ (cmSystemToolsCMakeRoot+"/Modules/CMake.cmake").c_str()))
+ {
+ // Build tree has "<build>/bin[/<config>]/cmake" and
+ // "<build>/CMakeFiles/CMakeSourceDir.txt".
+ std::string src_dir_txt = dir + "/CMakeFiles/CMakeSourceDir.txt";
+ cmsys::ifstream fin(src_dir_txt.c_str());
+ std::string src_dir;
+ if(fin && cmSystemTools::GetLineFromStream(fin, src_dir) &&
+ cmSystemTools::FileIsDirectory(src_dir))
+ {
+ cmSystemToolsCMakeRoot = src_dir;
+ }
+ else
+ {
+ dir = cmSystemTools::GetFilenamePath(dir);
+ src_dir_txt = dir + "/CMakeFiles/CMakeSourceDir.txt";
+ cmsys::ifstream fin2(src_dir_txt.c_str());
+ if(fin2 && cmSystemTools::GetLineFromStream(fin2, src_dir) &&
+ cmSystemTools::FileIsDirectory(src_dir))
+ {
+ cmSystemToolsCMakeRoot = src_dir;
+ }
+ }
+ }
+#else
+ // Bootstrap build knows its source.
+ cmSystemToolsCMakeRoot = CMAKE_BOOTSTRAP_SOURCE_DIR;
+#endif
}
//----------------------------------------------------------------------------
-const char* cmSystemTools::GetExecutableDirectory()
+std::string const& cmSystemTools::GetCMakeCommand()
{
- return cmSystemToolsExecutableDirectory.c_str();
+ return cmSystemToolsCMakeCommand;
+}
+
+//----------------------------------------------------------------------------
+std::string const& cmSystemTools::GetCTestCommand()
+{
+ return cmSystemToolsCTestCommand;
+}
+
+//----------------------------------------------------------------------------
+std::string const& cmSystemTools::GetCPackCommand()
+{
+ return cmSystemToolsCPackCommand;
+}
+
+//----------------------------------------------------------------------------
+std::string const& cmSystemTools::GetCMakeCursesCommand()
+{
+ return cmSystemToolsCMakeCursesCommand;
+}
+
+//----------------------------------------------------------------------------
+std::string const& cmSystemTools::GetCMakeGUICommand()
+{
+ return cmSystemToolsCMakeGUICommand;
+}
+
+//----------------------------------------------------------------------------
+std::string const& cmSystemTools::GetCMClDepsCommand()
+{
+ return cmSystemToolsCMClDepsCommand;
+}
+
+//----------------------------------------------------------------------------
+std::string const& cmSystemTools::GetCMakeRoot()
+{
+ return cmSystemToolsCMakeRoot;
}
//----------------------------------------------------------------------------
-#if defined(CMAKE_BUILD_WITH_CMAKE)
void cmSystemTools::MakefileColorEcho(int color, const char* message,
bool newline, bool enabled)
{
@@ -2406,18 +2406,23 @@ void cmSystemTools::MakefileColorEcho(int color, const char* message,
assumeTTY = 0;
}
- if(enabled)
+ if(enabled && color != cmsysTerminal_Color_Normal)
{
- cmsysTerminal_cfprintf(color | assumeTTY, stdout, "%s%s",
- message, newline? "\n" : "");
+ // Print with color. Delay the newline until later so that
+ // all color restore sequences appear before it.
+ cmsysTerminal_cfprintf(color | assumeTTY, stdout, "%s", message);
}
else
{
// Color is disabled. Print without color.
- fprintf(stdout, "%s%s", message, newline? "\n" : "");
+ fprintf(stdout, "%s", message);
+ }
+
+ if(newline)
+ {
+ fprintf(stdout, "\n");
}
}
-#endif
//----------------------------------------------------------------------------
bool cmSystemTools::GuessLibrarySOName(std::string const& fullPath,
@@ -2434,11 +2439,11 @@ bool cmSystemTools::GuessLibrarySOName(std::string const& fullPath,
#endif
// If the file is not a symlink we have no guess for its soname.
- if(!cmSystemTools::FileIsSymlink(fullPath.c_str()))
+ if(!cmSystemTools::FileIsSymlink(fullPath))
{
return false;
}
- if(!cmSystemTools::ReadSymlink(fullPath.c_str(), soname))
+ if(!cmSystemTools::ReadSymlink(fullPath, soname))
{
return false;
}
@@ -2464,31 +2469,17 @@ bool cmSystemTools::GuessLibrarySOName(std::string const& fullPath,
bool cmSystemTools::GuessLibraryInstallName(std::string const& fullPath,
std::string& soname)
{
- std::vector<cmStdString> cmds;
- cmds.push_back("otool");
- cmds.push_back("-D");
- cmds.push_back(fullPath.c_str());
-
- std::string output;
- if(!RunSingleCommand(cmds, &output, 0, 0, OUTPUT_NONE))
+#if defined(CMAKE_USE_MACH_PARSER)
+ cmMachO macho(fullPath.c_str());
+ if(macho)
{
- cmds.insert(cmds.begin(), "-r");
- cmds.insert(cmds.begin(), "xcrun");
- if(!RunSingleCommand(cmds, &output, 0, 0, OUTPUT_NONE))
- {
- return false;
- }
+ return macho.GetInstallName(soname);
}
+#else
+ (void)fullPath;
+ (void)soname;
+#endif
- std::vector<std::string> strs = cmSystemTools::tokenize(output, "\n");
- // otool returns extra lines reporting multiple install names
- // in case the binary is multi-arch and none of the architectures
- // is native (e.g. i386;ppc on x86_64)
- if(strs.size() >= 2)
- {
- soname = strs[1];
- return true;
- }
return false;
}
@@ -2561,6 +2552,7 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
*changed = false;
}
int rp_count = 0;
+ bool remove_rpath = true;
cmSystemToolsRPathInfo rp[2];
{
// Parse the ELF binary.
@@ -2618,11 +2610,12 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
// If it contains the new rpath instead then it is okay.
if(cmSystemToolsFindRPath(se[i]->Value, newRPath) != std::string::npos)
{
+ remove_rpath = false;
continue;
}
if(emsg)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "The current " << se_name[i] << " is:\n"
<< " " << se[i]->Value << "\n"
<< "which does not contain:\n"
@@ -2638,13 +2631,30 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
rp[rp_count].Size = se[i]->Size;
rp[rp_count].Name = se_name[i];
+ std::string::size_type prefix_len = pos;
+
+ // If oldRPath was at the end of the file's RPath, and newRPath is empty,
+ // we should remove the unnecessary ':' at the end.
+ if (newRPath.empty() &&
+ pos > 0 &&
+ se[i]->Value[pos - 1] == ':' &&
+ pos + oldRPath.length() == se[i]->Value.length())
+ {
+ prefix_len--;
+ }
+
// Construct the new value which preserves the part of the path
// not being changed.
- rp[rp_count].Value = se[i]->Value.substr(0, pos);
+ rp[rp_count].Value = se[i]->Value.substr(0, prefix_len);
rp[rp_count].Value += newRPath;
rp[rp_count].Value += se[i]->Value.substr(pos+oldRPath.length(),
oldRPath.npos);
+ if (!rp[rp_count].Value.empty())
+ {
+ remove_rpath = false;
+ }
+
// Make sure there is enough room to store the new rpath and at
// least one null terminator.
if(rp[rp_count].Size < rp[rp_count].Value.length()+1)
@@ -2669,9 +2679,15 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
return true;
}
+ // If the resulting rpath is empty, just remove the entire entry instead.
+ if (remove_rpath)
+ {
+ return cmSystemTools::RemoveRPath(file, emsg, changed);
+ }
+
{
// Open the file for update.
- std::ofstream f(file.c_str(),
+ cmsys::ofstream f(file.c_str(),
std::ios::in | std::ios::out | std::ios::binary);
if(!f)
{
@@ -2739,35 +2755,59 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
bool cmSystemTools::VersionCompare(cmSystemTools::CompareOp op,
const char* lhss, const char* rhss)
{
- // Parse out up to 8 components.
- unsigned int lhs[8] = {0,0,0,0,0,0,0,0};
- unsigned int rhs[8] = {0,0,0,0,0,0,0,0};
- sscanf(lhss, "%u.%u.%u.%u.%u.%u.%u.%u",
- &lhs[0], &lhs[1], &lhs[2], &lhs[3],
- &lhs[4], &lhs[5], &lhs[6], &lhs[7]);
- sscanf(rhss, "%u.%u.%u.%u.%u.%u.%u.%u",
- &rhs[0], &rhs[1], &rhs[2], &rhs[3],
- &rhs[4], &rhs[5], &rhs[6], &rhs[7]);
+ const char *endl = lhss;
+ const char *endr = rhss;
+ unsigned long lhs, rhs;
- // Do component-wise comparison.
- for(unsigned int i=0; i < 8; ++i)
+ while (((*endl >= '0') && (*endl <= '9')) ||
+ ((*endr >= '0') && (*endr <= '9')))
{
- if(lhs[i] < rhs[i])
+ // Do component-wise comparison.
+ lhs = strtoul(endl, const_cast<char**>(&endl), 10);
+ rhs = strtoul(endr, const_cast<char**>(&endr), 10);
+
+ if(lhs < rhs)
{
// lhs < rhs, so true if operation is LESS
return op == cmSystemTools::OP_LESS;
}
- else if(lhs[i] > rhs[i])
+ else if(lhs > rhs)
{
// lhs > rhs, so true if operation is GREATER
return op == cmSystemTools::OP_GREATER;
}
+
+ if (*endr == '.')
+ {
+ endr++;
+ }
+
+ if (*endl == '.')
+ {
+ endl++;
+ }
}
// lhs == rhs, so true if operation is EQUAL
return op == cmSystemTools::OP_EQUAL;
}
//----------------------------------------------------------------------------
+bool cmSystemTools::VersionCompareEqual(std::string const& lhs,
+ std::string const& rhs)
+{
+ return cmSystemTools::VersionCompare(
+ cmSystemTools::OP_EQUAL, lhs.c_str(), rhs.c_str());
+}
+
+//----------------------------------------------------------------------------
+bool cmSystemTools::VersionCompareGreater(std::string const& lhs,
+ std::string const& rhs)
+{
+ return cmSystemTools::VersionCompare(
+ cmSystemTools::OP_GREATER, lhs.c_str(), rhs.c_str());
+}
+
+//----------------------------------------------------------------------------
bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
bool* removed)
{
@@ -2804,7 +2844,7 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
}
if(se_count == 2 && se[1]->IndexInSection < se[0]->IndexInSection)
{
- cmsys_stl::swap(se[0], se[1]);
+ std::swap(se[0], se[1]);
}
// Get the size of the dynamic section header.
@@ -2869,7 +2909,7 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
}
// Open the file for update.
- std::ofstream f(file.c_str(),
+ cmsys::ofstream f(file.c_str(),
std::ios::in | std::ios::out | std::ios::binary);
if(!f)
{
@@ -3022,3 +3062,21 @@ std::vector<std::string> cmSystemTools::tokenize(const std::string& str,
}
return tokens;
}
+
+//----------------------------------------------------------------------------
+bool cmSystemTools::StringToLong(const char* str, long* value)
+{
+ errno = 0;
+ char *endp;
+ *value = strtol(str, &endp, 10);
+ return (*endp == '\0') && (endp != str) && (errno == 0);
+}
+
+//----------------------------------------------------------------------------
+bool cmSystemTools::StringToULong(const char* str, unsigned long* value)
+{
+ errno = 0;
+ char *endp;
+ *value = strtoul(str, &endp, 10);
+ return (*endp == '\0') && (endp != str) && (errno == 0);
+}
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 9d7dae9ef..f511ae43d 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -47,21 +47,24 @@ public:
KeyWOW64 view = KeyWOW64_Default);
///! Escape quotes in a string.
- static std::string EscapeQuotes(const char* str);
+ static std::string EscapeQuotes(const std::string& str);
+
+ /** Map help document name to file name. */
+ static std::string HelpFileName(std::string);
/**
* Returns a string that has whitespace removed from the start and the end.
*/
static std::string TrimWhitespace(const std::string& s);
- typedef void (*ErrorCallback)(const char*, const char*, bool&, void*);
+ typedef void (*MessageCallback)(const char*, const char*, bool&, void*);
/**
* Set the function used by GUIs to display error messages
* Function gets passed: message as a const char*,
* title as a const char*, and a reference to bool that when
* set to false, will disable furthur messages (cancel).
*/
- static void SetErrorCallback(ErrorCallback f, void* clientData=0);
+ static void SetMessageCallback(MessageCallback f, void* clientData=0);
/**
* Display an error message.
@@ -74,14 +77,17 @@ public:
*/
static void Message(const char* m, const char* title=0);
+ typedef void (*OutputCallback)(const char*, size_t length, void*);
+
///! Send a string to stdout
static void Stdout(const char* s);
- static void Stdout(const char* s, int length);
- typedef void (*StdoutCallback)(const char*, int length, void*);
- static void SetStdoutCallback(StdoutCallback, void* clientData=0);
+ static void Stdout(const char* s, size_t length);
+ static void SetStdoutCallback(OutputCallback, void* clientData=0);
- ///! Send a string to stderr. Stdout callbacks will not be invoced.
- static void Stderr(const char* s, int length);
+ ///! Send a string to stderr
+ static void Stderr(const char* s);
+ static void Stderr(const char* s, size_t length);
+ static void SetStderrCallback(OutputCallback, void* clientData=0);
typedef bool (*InterruptCallback)(void*);
@@ -155,9 +161,10 @@ public:
static std::string FileExistsInParentDirectories(const char* fname,
const char* directory, const char* toplevel);
- static void Glob(const char *directory, const char *regexp,
+ static void Glob(const std::string& directory, const std::string& regexp,
std::vector<std::string>& files);
- static void GlobDirs(const char *fullPath, std::vector<std::string>& files);
+ static void GlobDirs(const std::string& fullPath,
+ std::vector<std::string>& files);
/**
* Try to find a list of files that match the "simple" globbing
@@ -168,8 +175,8 @@ public:
* want to find. 0 means all files, -1 means directories, 1 means
* files only. This method returns true if search was succesfull.
*/
- static bool SimpleGlob(const cmStdString& glob,
- std::vector<cmStdString>& files,
+ static bool SimpleGlob(const std::string& glob,
+ std::vector<std::string>& files,
int type = 0);
///! Copy a file.
@@ -182,35 +189,21 @@ public:
static bool RenameFile(const char* oldname, const char* newname);
///! Compute the md5sum of a file
- static bool ComputeFileMD5(const char* source, char* md5out);
+ static bool ComputeFileMD5(const std::string& source, char* md5out);
/** Compute the md5sum of a string. */
- static std::string ComputeStringMD5(const char* input);
+ static std::string ComputeStringMD5(const std::string& input);
+
+ ///! Get the SHA thumbprint for a certificate file
+ static std::string ComputeCertificateThumbprint(const std::string& source);
- /**
- * Run an executable command and put the stdout in output.
- * A temporary file is created in the binaryDir for storing the
- * output because windows does not have popen.
- *
- * If verbose is false, no user-viewable output from the program
- * being run will be generated.
- *
- * If timeout is specified, the command will be terminated after
- * timeout expires.
- */
- static bool RunCommand(const char* command, std::string& output,
- const char* directory = 0,
- bool verbose = true, int timeout = 0);
- static bool RunCommand(const char* command, std::string& output,
- int &retVal, const char* directory = 0,
- bool verbose = true, int timeout = 0);
/**
* Run a single executable command
*
* Output is controlled with outputflag. If outputflag is OUTPUT_NONE, no
* user-viewable output from the program being run will be generated.
* OUTPUT_MERGE is the legacy behaviour where stdout and stderr are merged
- * into stdout. OUTPUT_NORMAL passes through the output to stdout/stderr as
+ * into stdout. OUTPUT_FORWARD copies the output to stdout/stderr as
* it was received. OUTPUT_PASSTHROUGH passes through the original handles.
*
* If timeout is specified, the command will be terminated after
@@ -230,10 +223,12 @@ public:
{
OUTPUT_NONE = 0,
OUTPUT_MERGE,
- OUTPUT_NORMAL,
+ OUTPUT_FORWARD,
OUTPUT_PASSTHROUGH
};
- static bool RunSingleCommand(const char* command, std::string* output = 0,
+ static bool RunSingleCommand(const char* command,
+ std::string* captureStdOut = 0,
+ std::string* captureStdErr = 0,
int* retVal = 0, const char* dir = 0,
OutputOption outputflag = OUTPUT_MERGE,
double timeout = 0.0);
@@ -242,16 +237,19 @@ public:
* the command to run, and each argument to the command should
* be in comand[1]...command[command.size()]
*/
- static bool RunSingleCommand(std::vector<cmStdString> const& command,
- std::string* output = 0,
+ static bool RunSingleCommand(std::vector<std::string> const& command,
+ std::string* captureStdOut = 0,
+ std::string* captureStdErr = 0,
int* retVal = 0, const char* dir = 0,
OutputOption outputflag = OUTPUT_MERGE,
double timeout = 0.0);
+ static std::string PrintSingleCommand(std::vector<std::string> const&);
+
/**
* Parse arguments out of a single string command
*/
- static std::vector<cmStdString> ParseArguments(const char* command);
+ static std::vector<std::string> ParseArguments(const char* command);
/** Parse arguments out of a windows command line string. */
static void ParseWindowsCommandLine(const char* command,
@@ -260,13 +258,6 @@ public:
/** Parse arguments out of a unix command line string. */
static void ParseUnixCommandLine(const char* command,
std::vector<std::string>& args);
- static void ParseUnixCommandLine(const char* command,
- std::vector<cmStdString>& args);
-
- /** Compute an escaped version of the given argument for use in a
- windows shell. See kwsys/System.h.in for details. */
- static std::string EscapeWindowsShellArgument(const char* arg,
- int shell_flags);
static void EnableMessages() { s_DisableMessages = false; }
static void DisableMessages() { s_DisableMessages = true; }
@@ -303,20 +294,16 @@ public:
* Compare versions
*/
static bool VersionCompare(CompareOp op, const char* lhs, const char* rhs);
+ static bool VersionCompareEqual(std::string const& lhs,
+ std::string const& rhs);
+ static bool VersionCompareGreater(std::string const& lhs,
+ std::string const& rhs);
/**
* Determine the file type based on the extension
*/
static FileFormat GetFileFormat(const char* ext);
- /**
- * On Windows 9x we need a comspec (command.com) substitute to run
- * programs correctly. This string has to be constant available
- * through the running of program. This method does not create a copy.
- */
- static void SetWindows9xComspecSubstitute(const char*);
- static const char* GetWindows9xComspecSubstitute();
-
/** Windows if this is true, the CreateProcess in RunCommand will
* not show new consol windows when running programs.
*/
@@ -335,7 +322,7 @@ public:
/** Split a string on its newlines into multiple lines. Returns
false only if the last line stored had no newline. */
- static bool Split(const char* s, std::vector<cmStdString>& l);
+ static bool Split(const char* s, std::vector<std::string>& l);
static void SetForceUnixPaths(bool v)
{
s_ForceUnixPaths = v;
@@ -353,8 +340,6 @@ public:
// be used when RunCommand is called from cmake, because the
// running cmake needs paths to be in its format
static std::string ConvertToRunCommandPath(const char* path);
- //! Check if the first string ends with the second one.
- static bool StringEndsWith(const char* str1, const char* str2);
/** compute the relative path from local to remote. local must
be a directory. remote can be a file or a directory.
@@ -401,13 +386,21 @@ public:
static void EnableVSConsoleOutput();
/** Create tar */
+ enum cmTarCompression
+ {
+ TarCompressGZip,
+ TarCompressBZip2,
+ TarCompressXZ,
+ TarCompressNone
+ };
static bool ListTar(const char* outFileName,
- bool gzip, bool verbose);
+ bool verbose);
static bool CreateTar(const char* outFileName,
- const std::vector<cmStdString>& files, bool gzip,
- bool bzip2, bool verbose);
- static bool ExtractTar(const char* inFileName, bool gzip,
- bool verbose);
+ const std::vector<std::string>& files,
+ cmTarCompression compressType, bool verbose,
+ std::string const& mtime = std::string(),
+ std::string const& format = std::string());
+ static bool ExtractTar(const char* inFileName, bool verbose);
// This should be called first thing in main
// it will keep child processes from inheriting the
// stdin and stdout of this process. This is important
@@ -428,19 +421,21 @@ public:
/** Random seed generation. */
static unsigned int RandomSeed();
- /** Find the directory containing the running executable. Save it
- in a global location to be queried by GetExecutableDirectory
- later. */
- static void FindExecutableDirectory(const char* argv0);
+ /** Find the directory containing CMake executables. */
+ static void FindCMakeResources(const char* argv0);
- /** Get the directory containing the currently running executable. */
- static const char* GetExecutableDirectory();
+ /** Get the CMake resource paths, after FindCMakeResources. */
+ static std::string const& GetCTestCommand();
+ static std::string const& GetCPackCommand();
+ static std::string const& GetCMakeCommand();
+ static std::string const& GetCMakeGUICommand();
+ static std::string const& GetCMakeCursesCommand();
+ static std::string const& GetCMClDepsCommand();
+ static std::string const& GetCMakeRoot();
-#if defined(CMAKE_BUILD_WITH_CMAKE)
/** Echo a message in color using KWSys's Terminal cprintf. */
static void MakefileColorEcho(int color, const char* message,
bool newLine, bool enabled);
-#endif
/** Try to guess the soname of a shared library. */
static bool GuessLibrarySOName(std::string const& fullPath,
@@ -472,6 +467,19 @@ public:
/** Tokenize a string */
static std::vector<std::string> tokenize(const std::string& str,
const std::string& sep);
+
+ /** Convert string to long. Expected that the whole string is an integer */
+ static bool StringToLong(const char* str, long* value);
+ static bool StringToULong(const char* str, unsigned long* value);
+
+#ifdef _WIN32
+ struct WindowsFileRetry
+ {
+ unsigned int Count;
+ unsigned int Delay;
+ };
+ static WindowsFileRetry GetWindowsFileRetry();
+#endif
private:
static bool s_ForceUnixPaths;
static bool s_RunCommandHideConsole;
@@ -479,14 +487,14 @@ private:
static bool s_FatalErrorOccured;
static bool s_DisableMessages;
static bool s_DisableRunCommandOutput;
- static ErrorCallback s_ErrorCallback;
- static StdoutCallback s_StdoutCallback;
+ static MessageCallback s_MessageCallback;
+ static OutputCallback s_StdoutCallback;
+ static OutputCallback s_StderrCallback;
static InterruptCallback s_InterruptCallback;
- static void* s_ErrorCallbackClientData;
+ static void* s_MessageCallbackClientData;
static void* s_StdoutCallbackClientData;
+ static void* s_StderrCallbackClientData;
static void* s_InterruptCallbackClientData;
-
- static std::string s_Windows9xComspecSubstitute;
};
#endif
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 4ba6c1981..1986e5fd3 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -13,1586 +13,66 @@
#include "cmake.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
-#include "cmLocalGenerator.h"
+#include "cmOutputConverter.h"
#include "cmGlobalGenerator.h"
#include "cmComputeLinkInformation.h"
-#include "cmDocumentCompileDefinitions.h"
-#include "cmDocumentGeneratorExpressions.h"
-#include "cmDocumentLocationUndefined.h"
#include "cmListFileCache.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionDAGChecker.h"
+#include "cmAlgorithms.h"
#include <cmsys/RegularExpression.hxx>
#include <map>
#include <set>
-#include <queue>
#include <stdlib.h> // required for atof
#include <assert.h>
-
-const char* cmTarget::GetTargetTypeName(TargetType targetType)
-{
- switch( targetType )
- {
- case cmTarget::STATIC_LIBRARY:
- return "STATIC_LIBRARY";
- case cmTarget::MODULE_LIBRARY:
- return "MODULE_LIBRARY";
- case cmTarget::SHARED_LIBRARY:
- return "SHARED_LIBRARY";
- case cmTarget::OBJECT_LIBRARY:
- return "OBJECT_LIBRARY";
- case cmTarget::EXECUTABLE:
- return "EXECUTABLE";
- case cmTarget::UTILITY:
- return "UTILITY";
- case cmTarget::GLOBAL_TARGET:
- return "GLOBAL_TARGET";
- case cmTarget::UNKNOWN_LIBRARY:
- return "UNKNOWN_LIBRARY";
- }
- assert(0 && "Unexpected target type");
- return 0;
-}
-
-//----------------------------------------------------------------------------
-struct cmTarget::OutputInfo
-{
- std::string OutDir;
- std::string ImpDir;
- std::string PdbDir;
-};
-
-//----------------------------------------------------------------------------
-struct cmTarget::ImportInfo
-{
- bool NoSOName;
- std::string Location;
- std::string SOName;
- std::string ImportLibrary;
- cmTarget::LinkInterface LinkInterface;
-};
-
-struct TargetConfigPair : public std::pair<cmTarget*, std::string> {
- TargetConfigPair(cmTarget* tgt, const std::string &config)
- : std::pair<cmTarget*, std::string>(tgt, config) {}
-};
+#include <errno.h>
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+#include <cmsys/hash_set.hxx>
+#define UNORDERED_SET cmsys::hash_set
+#else
+#define UNORDERED_SET std::set
+#endif
//----------------------------------------------------------------------------
class cmTargetInternals
{
public:
- cmTargetInternals()
- {
- this->PolicyWarnedCMP0022 = false;
- this->SourceFileFlagsConstructed = false;
- }
- cmTargetInternals(cmTargetInternals const& r)
- {
- this->PolicyWarnedCMP0022 = false;
- this->SourceFileFlagsConstructed = false;
- // Only some of these entries are part of the object state.
- // Others not copied here are result caches.
- this->SourceEntries = r.SourceEntries;
- }
- ~cmTargetInternals();
- typedef cmTarget::SourceFileFlags SourceFileFlags;
- std::map<cmSourceFile const*, SourceFileFlags> SourceFlagsMap;
- bool SourceFileFlagsConstructed;
-
- // The backtrace when the target was created.
- cmListFileBacktrace Backtrace;
-
- // Cache link interface computation from each configuration.
- struct OptionalLinkInterface: public cmTarget::LinkInterface
- {
- OptionalLinkInterface(): Exists(false) {}
- bool Exists;
- };
- typedef std::map<TargetConfigPair, OptionalLinkInterface>
- LinkInterfaceMapType;
- LinkInterfaceMapType LinkInterfaceMap;
- bool PolicyWarnedCMP0022;
-
- typedef std::map<cmStdString, cmTarget::OutputInfo> OutputInfoMapType;
- OutputInfoMapType OutputInfoMap;
-
- typedef std::map<TargetConfigPair, cmTarget::ImportInfo>
- ImportInfoMapType;
- ImportInfoMapType ImportInfoMap;
-
- // Cache link implementation computation from each configuration.
- typedef std::map<TargetConfigPair,
- cmTarget::LinkImplementation> LinkImplMapType;
- LinkImplMapType LinkImplMap;
-
- typedef std::map<TargetConfigPair, cmTarget::LinkClosure>
- LinkClosureMapType;
- LinkClosureMapType LinkClosureMap;
-
- struct SourceEntry { std::vector<cmSourceFile*> Depends; };
- typedef std::map<cmSourceFile*, SourceEntry> SourceEntriesType;
- SourceEntriesType SourceEntries;
-
- struct TargetPropertyEntry {
- TargetPropertyEntry(cmsys::auto_ptr<cmCompiledGeneratorExpression> cge,
- const std::string &targetName = std::string())
- : ge(cge), TargetName(targetName)
- {}
- const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge;
- std::vector<std::string> CachedEntries;
- const std::string TargetName;
- };
- std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
- std::vector<TargetPropertyEntry*> CompileOptionsEntries;
- std::vector<TargetPropertyEntry*> CompileDefinitionsEntries;
- std::vector<cmValueWithOrigin> LinkInterfacePropertyEntries;
-
- std::map<std::string, std::vector<TargetPropertyEntry*> >
- CachedLinkInterfaceIncludeDirectoriesEntries;
- std::map<std::string, std::vector<TargetPropertyEntry*> >
- CachedLinkInterfaceCompileOptionsEntries;
- std::map<std::string, std::vector<TargetPropertyEntry*> >
- CachedLinkInterfaceCompileDefinitionsEntries;
-
- std::map<std::string, bool> CacheLinkInterfaceIncludeDirectoriesDone;
- std::map<std::string, bool> CacheLinkInterfaceCompileDefinitionsDone;
- std::map<std::string, bool> CacheLinkInterfaceCompileOptionsDone;
+ std::vector<std::string> IncludeDirectoriesEntries;
+ std::vector<cmListFileBacktrace> IncludeDirectoriesBacktraces;
+ std::vector<std::string> CompileOptionsEntries;
+ std::vector<cmListFileBacktrace> CompileOptionsBacktraces;
+ std::vector<std::string> CompileFeaturesEntries;
+ std::vector<cmListFileBacktrace> CompileFeaturesBacktraces;
+ std::vector<std::string> CompileDefinitionsEntries;
+ std::vector<cmListFileBacktrace> CompileDefinitionsBacktraces;
+ std::vector<std::string> SourceEntries;
+ std::vector<cmListFileBacktrace> SourceBacktraces;
+ std::vector<std::string> LinkImplementationPropertyEntries;
+ std::vector<cmListFileBacktrace> LinkImplementationPropertyBacktraces;
};
//----------------------------------------------------------------------------
-void deleteAndClear(
- std::vector<cmTargetInternals::TargetPropertyEntry*> &entries)
-{
- for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
- it = entries.begin(),
- end = entries.end();
- it != end; ++it)
- {
- delete *it;
- }
- entries.clear();
-}
-
-//----------------------------------------------------------------------------
-void deleteAndClear(
- std::map<std::string,
- std::vector<cmTargetInternals::TargetPropertyEntry*> > &entries)
-{
- for (std::map<std::string,
- std::vector<cmTargetInternals::TargetPropertyEntry*> >::iterator
- it = entries.begin(), end = entries.end(); it != end; ++it)
- {
- deleteAndClear(it->second);
- }
-}
-
-//----------------------------------------------------------------------------
-cmTargetInternals::~cmTargetInternals()
-{
- deleteAndClear(this->CachedLinkInterfaceIncludeDirectoriesEntries);
- deleteAndClear(this->CachedLinkInterfaceCompileOptionsEntries);
- deleteAndClear(this->CachedLinkInterfaceCompileDefinitionsEntries);
-}
-
-//----------------------------------------------------------------------------
cmTarget::cmTarget()
{
-#define INITIALIZE_TARGET_POLICY_MEMBER(POLICY) \
- this->PolicyStatus ## POLICY = cmPolicies::WARN;
-
- CM_FOR_EACH_TARGET_POLICY(INITIALIZE_TARGET_POLICY_MEMBER)
-
-#undef INITIALIZE_TARGET_POLICY_MEMBER
-
this->Makefile = 0;
- this->LinkLibrariesAnalyzed = false;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ this->LinkLibrariesForVS6Analyzed = false;
+#endif
this->HaveInstallRule = false;
this->DLLPlatform = false;
- this->IsApple = false;
+ this->IsAndroid = false;
this->IsImportedTarget = false;
+ this->ImportedGloballyVisible = false;
this->BuildInterfaceIncludesAppended = false;
- this->DebugIncludesDone = false;
- this->DebugCompileOptionsDone = false;
- this->DebugCompileDefinitionsDone = false;
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::DefineProperties(cmake *cm)
-{
- cm->DefineProperty
- ("AUTOMOC", cmProperty::TARGET,
- "Should the target be processed with automoc (for Qt projects).",
- "AUTOMOC is a boolean specifying whether CMake will handle "
- "the Qt moc preprocessor automatically, i.e. without having to use "
- "the QT4_WRAP_CPP() or QT5_WRAP_CPP() macro. Currently Qt4 and Qt5 are "
- "supported. "
- "When this property is set to TRUE, CMake will scan the source files "
- "at build time and invoke moc accordingly. "
- "If an #include statement like #include \"moc_foo.cpp\" is found, "
- "the Q_OBJECT class declaration is expected in the header, and moc is "
- "run on the header file. "
- "If an #include statement like #include \"foo.moc\" is found, "
- "then a Q_OBJECT is expected in the current source file and moc "
- "is run on the file itself. "
- "Additionally, all header files are parsed for Q_OBJECT macros, "
- "and if found, moc is also executed on those files. The resulting "
- "moc files, which are not included as shown above in any of the source "
- "files are included in a generated <targetname>_automoc.cpp file, "
- "which is compiled as part of the target."
- "This property is initialized by the value of the variable "
- "CMAKE_AUTOMOC if it is set when a target is created.\n"
- "Additional command line options for moc can be set via the "
- "AUTOMOC_MOC_OPTIONS property.\n"
- "By setting the CMAKE_AUTOMOC_RELAXED_MODE variable to TRUE the rules "
- "for searching the files which will be processed by moc can be relaxed. "
- "See the documentation for this variable for more details.\n"
- "The global property AUTOMOC_TARGETS_FOLDER can be used to group the "
- "automoc targets together in an IDE, e.g. in MSVS.");
-
- cm->DefineProperty
- ("AUTOMOC_MOC_OPTIONS", cmProperty::TARGET,
- "Additional options for moc when using automoc (see the AUTOMOC property)",
- "This property is only used if the AUTOMOC property is set to TRUE for "
- "this target. In this case, it holds additional command line options "
- "which will be used when moc is executed during the build, i.e. it is "
- "equivalent to the optional OPTIONS argument of the qt4_wrap_cpp() "
- "macro.\n"
- "By default it is empty.");
-
- cm->DefineProperty
- ("BUILD_WITH_INSTALL_RPATH", cmProperty::TARGET,
- "Should build tree targets have install tree rpaths.",
- "BUILD_WITH_INSTALL_RPATH is a boolean specifying whether to link "
- "the target in the build tree with the INSTALL_RPATH. This takes "
- "precedence over SKIP_BUILD_RPATH and avoids the need for relinking "
- "before installation. "
- "This property is initialized by the value of the variable "
- "CMAKE_BUILD_WITH_INSTALL_RPATH if it is set when a target is created.");
-
- cm->DefineProperty
- ("COMPILE_FLAGS", cmProperty::TARGET,
- "Additional flags to use when compiling this target's sources.",
- "The COMPILE_FLAGS property sets additional compiler flags used "
- "to build sources within the target. Use COMPILE_DEFINITIONS "
- "to pass additional preprocessor definitions.");
-
- cm->DefineProperty
- ("COMPILE_DEFINITIONS", cmProperty::TARGET,
- "Preprocessor definitions for compiling a target's sources.",
- "The COMPILE_DEFINITIONS property may be set to a "
- "semicolon-separated list of preprocessor "
- "definitions using the syntax VAR or VAR=value. Function-style "
- "definitions are not supported. CMake will automatically escape "
- "the value correctly for the native build system (note that CMake "
- "language syntax may require escapes to specify some values). "
- "This property may be set on a per-configuration basis using the name "
- "COMPILE_DEFINITIONS_<CONFIG> where <CONFIG> is an upper-case name "
- "(ex. \"COMPILE_DEFINITIONS_DEBUG\").\n"
- "CMake will automatically drop some definitions that "
- "are not supported by the native build tool. "
- "The VS6 IDE does not support definition values with spaces "
- "(but NMake does).\n"
- "Contents of COMPILE_DEFINITIONS may use \"generator expressions\" with "
- "the syntax \"$<...>\". "
- CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS
- CM_DOCUMENT_COMPILE_DEFINITIONS_DISCLAIMER);
-
- cm->DefineProperty
- ("COMPILE_DEFINITIONS_<CONFIG>", cmProperty::TARGET,
- "Per-configuration preprocessor definitions on a target.",
- "This is the configuration-specific version of COMPILE_DEFINITIONS.");
-
- cm->DefineProperty
- ("COMPILE_OPTIONS", cmProperty::TARGET,
- "List of options to pass to the compiler.",
- "This property specifies the list of options specified "
- "so far for this property. "
- "This property exists on directories and targets."
- "\n"
- "The target property values are used by the generators to set "
- "the options for the compiler.\n"
- "Contents of COMPILE_OPTIONS may use \"generator expressions\" with "
- "the syntax \"$<...>\". "
- CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS);
-
- cm->DefineProperty
- ("INTERFACE_COMPILE_OPTIONS", cmProperty::TARGET,
- "List of interface options to pass to the compiler.",
- "Targets may populate this property to publish the compile options "
- "required to compile against the headers for the target. Consuming "
- "targets can add entries to their own COMPILE_OPTIONS property such "
- "as $<TARGET_PROPERTY:foo,INTERFACE_COMPILE_OPTIONS> to use the "
- "compile options specified in the interface of 'foo'."
- "\n"
- CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS);
-
- cm->DefineProperty
- ("DEFINE_SYMBOL", cmProperty::TARGET,
- "Define a symbol when compiling this target's sources.",
- "DEFINE_SYMBOL sets the name of the preprocessor symbol defined when "
- "compiling sources in a shared library. "
- "If not set here then it is set to target_EXPORTS by default "
- "(with some substitutions if the target is not a valid C "
- "identifier). This is useful for headers to know whether they are "
- "being included from inside their library or outside to properly "
- "setup dllexport/dllimport decorations. ");
-
- cm->DefineProperty
- ("DEBUG_POSTFIX", cmProperty::TARGET,
- "See target property <CONFIG>_POSTFIX.",
- "This property is a special case of the more-general <CONFIG>_POSTFIX "
- "property for the DEBUG configuration.");
-
- cm->DefineProperty
- ("<CONFIG>_POSTFIX", cmProperty::TARGET,
- "Postfix to append to the target file name for configuration <CONFIG>.",
- "When building with configuration <CONFIG> the value of this property "
- "is appended to the target file name built on disk. "
- "For non-executable targets, this property is initialized by the value "
- "of the variable CMAKE_<CONFIG>_POSTFIX if it is set when a target is "
- "created. "
- "This property is ignored on the Mac for Frameworks and App Bundles.");
-
- cm->DefineProperty
- ("EchoString", cmProperty::TARGET,
- "A message to be displayed when the target is built.",
- "A message to display on some generators (such as makefiles) when "
- "the target is built.");
-
- cm->DefineProperty
- ("BUNDLE", cmProperty::TARGET,
- "This target is a CFBundle on the Mac.",
- "If a module library target has this property set to true it will "
- "be built as a CFBundle when built on the mac. It will have the "
- "directory structure required for a CFBundle and will be suitable "
- "to be used for creating Browser Plugins or other application "
- "resources.");
-
- cm->DefineProperty
- ("BUNDLE_EXTENSION", cmProperty::TARGET,
- "The file extension used to name a BUNDLE target on the Mac.",
- "The default value is \"bundle\" - you can also use \"plugin\" or "
- "whatever file extension is required by the host app for your "
- "bundle.");
-
- cm->DefineProperty
- ("EXCLUDE_FROM_DEFAULT_BUILD", cmProperty::TARGET,
- "Exclude target from \"Build Solution\".",
- "This property is only used by Visual Studio generators 7 and above. "
- "When set to TRUE, the target will not be built when you press "
- "\"Build Solution\".");
-
- cm->DefineProperty
- ("EXCLUDE_FROM_DEFAULT_BUILD_<CONFIG>", cmProperty::TARGET,
- "Per-configuration version of target exclusion from \"Build Solution\". ",
- "This is the configuration-specific version of "
- "EXCLUDE_FROM_DEFAULT_BUILD. If the generic EXCLUDE_FROM_DEFAULT_BUILD "
- "is also set on a target, EXCLUDE_FROM_DEFAULT_BUILD_<CONFIG> takes "
- "precedence in configurations for which it has a value.");
-
- cm->DefineProperty
- ("FRAMEWORK", cmProperty::TARGET,
- "This target is a framework on the Mac.",
- "If a shared library target has this property set to true it will "
- "be built as a framework when built on the mac. It will have the "
- "directory structure required for a framework and will be suitable "
- "to be used with the -framework option");
-
- cm->DefineProperty
- ("HAS_CXX", cmProperty::TARGET,
- "Link the target using the C++ linker tool (obsolete).",
- "This is equivalent to setting the LINKER_LANGUAGE property to CXX. "
- "See that property's documentation for details.");
-
- cm->DefineProperty
- ("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM", cmProperty::TARGET,
- "Specify #include line transforms for dependencies in a target.",
- "This property specifies rules to transform macro-like #include lines "
- "during implicit dependency scanning of C and C++ source files. "
- "The list of rules must be semicolon-separated with each entry of "
- "the form \"A_MACRO(%)=value-with-%\" (the % must be literal). "
- "During dependency scanning occurrences of A_MACRO(...) on #include "
- "lines will be replaced by the value given with the macro argument "
- "substituted for '%'. For example, the entry\n"
- " MYDIR(%)=<mydir/%>\n"
- "will convert lines of the form\n"
- " #include MYDIR(myheader.h)\n"
- "to\n"
- " #include <mydir/myheader.h>\n"
- "allowing the dependency to be followed.\n"
- "This property applies to sources in the target on which it is set.");
-
- cm->DefineProperty
- ("IMPORT_PREFIX", cmProperty::TARGET,
- "What comes before the import library name.",
- "Similar to the target property PREFIX, but used for import libraries "
- "(typically corresponding to a DLL) instead of regular libraries. "
- "A target property that can be set to override the prefix "
- "(such as \"lib\") on an import library name.");
-
- cm->DefineProperty
- ("IMPORT_SUFFIX", cmProperty::TARGET,
- "What comes after the import library name.",
- "Similar to the target property SUFFIX, but used for import libraries "
- "(typically corresponding to a DLL) instead of regular libraries. "
- "A target property that can be set to override the suffix "
- "(such as \".lib\") on an import library name.");
-
- cm->DefineProperty
- ("IMPORTED", cmProperty::TARGET,
- "Read-only indication of whether a target is IMPORTED.",
- "The boolean value of this property is true for targets created with "
- "the IMPORTED option to add_executable or add_library. "
- "It is false for targets built within the project.");
-
- cm->DefineProperty
- ("IMPORTED_CONFIGURATIONS", cmProperty::TARGET,
- "Configurations provided for an IMPORTED target.",
- "Set this to the list of configuration names available for an "
- "IMPORTED target. "
- "The names correspond to configurations defined in the project from "
- "which the target is imported. "
- "If the importing project uses a different set of configurations "
- "the names may be mapped using the MAP_IMPORTED_CONFIG_<CONFIG> "
- "property. "
- "Ignored for non-imported targets.");
-
- cm->DefineProperty
- ("IMPORTED_IMPLIB", cmProperty::TARGET,
- "Full path to the import library for an IMPORTED target.",
- "Set this to the location of the \".lib\" part of a windows DLL. "
- "Ignored for non-imported targets.");
-
- cm->DefineProperty
- ("IMPORTED_IMPLIB_<CONFIG>", cmProperty::TARGET,
- "<CONFIG>-specific version of IMPORTED_IMPLIB property.",
- "Configuration names correspond to those provided by the project "
- "from which the target is imported.");
-
- cm->DefineProperty
- ("IMPORTED_LINK_DEPENDENT_LIBRARIES", cmProperty::TARGET,
- "Dependent shared libraries of an imported shared library.",
- "Shared libraries may be linked to other shared libraries as part "
- "of their implementation. On some platforms the linker searches "
- "for the dependent libraries of shared libraries they are including "
- "in the link. "
- "Set this property to the list of dependent shared libraries of an "
- "imported library. "
- "The list "
- "should be disjoint from the list of interface libraries in the "
- "INTERFACE_LINK_LIBRARIES property. On platforms requiring "
- "dependent shared libraries to be found at link time CMake uses this "
- "list to add appropriate files or paths to the link command line. "
- "Ignored for non-imported targets.");
-
- cm->DefineProperty
- ("IMPORTED_LINK_DEPENDENT_LIBRARIES_<CONFIG>", cmProperty::TARGET,
- "<CONFIG>-specific version of IMPORTED_LINK_DEPENDENT_LIBRARIES.",
- "Configuration names correspond to those provided by the project "
- "from which the target is imported. "
- "If set, this property completely overrides the generic property "
- "for the named configuration.");
-
- cm->DefineProperty
- ("IMPORTED_LINK_INTERFACE_LIBRARIES", cmProperty::TARGET,
- "Transitive link interface of an IMPORTED target.",
- "Set this to the list of libraries whose interface is included when "
- "an IMPORTED library target is linked to another target. "
- "The libraries will be included on the link line for the target. "
- "Unlike the LINK_INTERFACE_LIBRARIES property, this property applies "
- "to all imported target types, including STATIC libraries. "
- "This property is ignored for non-imported targets.\n"
- "This property is ignored if the target also has a non-empty "
- "INTERFACE_LINK_LIBRARIES property.\n"
- "This property is deprecated. Use INTERFACE_LINK_LIBRARIES instead.");
-
- cm->DefineProperty
- ("IMPORTED_LINK_INTERFACE_LIBRARIES_<CONFIG>", cmProperty::TARGET,
- "<CONFIG>-specific version of IMPORTED_LINK_INTERFACE_LIBRARIES.",
- "Configuration names correspond to those provided by the project "
- "from which the target is imported. "
- "If set, this property completely overrides the generic property "
- "for the named configuration.\n"
- "This property is ignored if the target also has a non-empty "
- "INTERFACE_LINK_LIBRARIES property.\n"
- "This property is deprecated. Use INTERFACE_LINK_LIBRARIES instead.");
-
- cm->DefineProperty
- ("IMPORTED_LINK_INTERFACE_LANGUAGES", cmProperty::TARGET,
- "Languages compiled into an IMPORTED static library.",
- "Set this to the list of languages of source files compiled to "
- "produce a STATIC IMPORTED library (such as \"C\" or \"CXX\"). "
- "CMake accounts for these languages when computing how to link a "
- "target to the imported library. "
- "For example, when a C executable links to an imported C++ static "
- "library CMake chooses the C++ linker to satisfy language runtime "
- "dependencies of the static library. "
- "\n"
- "This property is ignored for targets that are not STATIC libraries. "
- "This property is ignored for non-imported targets.");
-
- cm->DefineProperty
- ("IMPORTED_LINK_INTERFACE_LANGUAGES_<CONFIG>", cmProperty::TARGET,
- "<CONFIG>-specific version of IMPORTED_LINK_INTERFACE_LANGUAGES.",
- "Configuration names correspond to those provided by the project "
- "from which the target is imported. "
- "If set, this property completely overrides the generic property "
- "for the named configuration.");
-
- cm->DefineProperty
- ("IMPORTED_LINK_INTERFACE_MULTIPLICITY", cmProperty::TARGET,
- "Repetition count for cycles of IMPORTED static libraries.",
- "This is LINK_INTERFACE_MULTIPLICITY for IMPORTED targets.");
- cm->DefineProperty
- ("IMPORTED_LINK_INTERFACE_MULTIPLICITY_<CONFIG>", cmProperty::TARGET,
- "<CONFIG>-specific version of IMPORTED_LINK_INTERFACE_MULTIPLICITY.",
- "If set, this property completely overrides the generic property "
- "for the named configuration.");
-
- cm->DefineProperty
- ("IMPORTED_LOCATION", cmProperty::TARGET,
- "Full path to the main file on disk for an IMPORTED target.",
- "Set this to the location of an IMPORTED target file on disk. "
- "For executables this is the location of the executable file. "
- "For bundles on OS X this is the location of the executable file "
- "inside Contents/MacOS under the application bundle folder. "
- "For static libraries and modules this is the location of the "
- "library or module. "
- "For shared libraries on non-DLL platforms this is the location of "
- "the shared library. "
- "For frameworks on OS X this is the location of the library file "
- "symlink just inside the framework folder. "
- "For DLLs this is the location of the \".dll\" part of the library. "
- "For UNKNOWN libraries this is the location of the file to be linked. "
- "Ignored for non-imported targets."
- "\n"
- "Projects may skip IMPORTED_LOCATION if the configuration-specific "
- "property IMPORTED_LOCATION_<CONFIG> is set. "
- "To get the location of an imported target read one of the "
- "LOCATION or LOCATION_<CONFIG> properties.");
-
- cm->DefineProperty
- ("IMPORTED_LOCATION_<CONFIG>", cmProperty::TARGET,
- "<CONFIG>-specific version of IMPORTED_LOCATION property.",
- "Configuration names correspond to those provided by the project "
- "from which the target is imported.");
-
- cm->DefineProperty
- ("IMPORTED_SONAME", cmProperty::TARGET,
- "The \"soname\" of an IMPORTED target of shared library type.",
- "Set this to the \"soname\" embedded in an imported shared library. "
- "This is meaningful only on platforms supporting the feature. "
- "Ignored for non-imported targets.");
-
- cm->DefineProperty
- ("IMPORTED_SONAME_<CONFIG>", cmProperty::TARGET,
- "<CONFIG>-specific version of IMPORTED_SONAME property.",
- "Configuration names correspond to those provided by the project "
- "from which the target is imported.");
-
- cm->DefineProperty
- ("IMPORTED_NO_SONAME", cmProperty::TARGET,
- "Specifies that an IMPORTED shared library target has no \"soname\". ",
- "Set this property to true for an imported shared library file that "
- "has no \"soname\" field. "
- "CMake may adjust generated link commands for some platforms to prevent "
- "the linker from using the path to the library in place of its missing "
- "soname. "
- "Ignored for non-imported targets.");
-
- cm->DefineProperty
- ("IMPORTED_NO_SONAME_<CONFIG>", cmProperty::TARGET,
- "<CONFIG>-specific version of IMPORTED_NO_SONAME property.",
- "Configuration names correspond to those provided by the project "
- "from which the target is imported.");
-
- cm->DefineProperty
- ("EXCLUDE_FROM_ALL", cmProperty::TARGET,
- "Exclude the target from the all target.",
- "A property on a target that indicates if the target is excluded "
- "from the default build target. If it is not, then with a Makefile "
- "for example typing make will cause this target to be built. "
- "The same concept applies to the default build of other generators. "
- "Installing a target with EXCLUDE_FROM_ALL set to true has "
- "undefined behavior.");
-
- cm->DefineProperty
- ("LINK_LIBRARIES", cmProperty::TARGET,
- "List of direct link dependencies.",
- "This property specifies the list of libraries or targets which will be "
- "used for linking. "
- "In addition to accepting values from the target_link_libraries "
- "command, values may be set directly on any target using the "
- "set_property command. "
- "\n"
- "The target property values are used by the generators to set "
- "the link libraries for the compiler. "
- "See also the target_link_libraries command.\n"
- "Contents of LINK_LIBRARIES may use \"generator expressions\" with "
- "the syntax \"$<...>\". "
- CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS);
-
- cm->DefineProperty
- ("INCLUDE_DIRECTORIES", cmProperty::TARGET,
- "List of preprocessor include file search directories.",
- "This property specifies the list of directories given "
- "so far to the include_directories command. "
- "This property exists on directories and targets. "
- "In addition to accepting values from the include_directories "
- "command, values may be set directly on any directory or any "
- "target using the set_property command. "
- "A target gets its initial value for this property from the value "
- "of the directory property. "
- "A directory gets its initial value from its parent directory if "
- "it has one. "
- "Both directory and target property values are adjusted by calls "
- "to the include_directories command."
- "\n"
- "The target property values are used by the generators to set "
- "the include paths for the compiler. "
- "See also the include_directories command.\n"
- "Contents of INCLUDE_DIRECTORIES may use \"generator expressions\" with "
- "the syntax \"$<...>\". "
- CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS);
-
- cm->DefineProperty
- ("INSTALL_NAME_DIR", cmProperty::TARGET,
- "Mac OSX directory name for installed targets.",
- "INSTALL_NAME_DIR is a string specifying the "
- "directory portion of the \"install_name\" field of shared libraries "
- "on Mac OSX to use in the installed targets. ");
-
- cm->DefineProperty
- ("INSTALL_RPATH", cmProperty::TARGET,
- "The rpath to use for installed targets.",
- "A semicolon-separated list specifying the rpath "
- "to use in installed targets (for platforms that support it). "
- "This property is initialized by the value of the variable "
- "CMAKE_INSTALL_RPATH if it is set when a target is created.");
-
- cm->DefineProperty
- ("INSTALL_RPATH_USE_LINK_PATH", cmProperty::TARGET,
- "Add paths to linker search and installed rpath.",
- "INSTALL_RPATH_USE_LINK_PATH is a boolean that if set to true will "
- "append directories in the linker search path and outside the "
- "project to the INSTALL_RPATH. "
- "This property is initialized by the value of the variable "
- "CMAKE_INSTALL_RPATH_USE_LINK_PATH if it is set when a target is "
- "created.");
-
- cm->DefineProperty
- ("INTERPROCEDURAL_OPTIMIZATION", cmProperty::TARGET,
- "Enable interprocedural optimization for a target.",
- "If set to true, enables interprocedural optimizations "
- "if they are known to be supported by the compiler.");
-
- cm->DefineProperty
- ("INTERPROCEDURAL_OPTIMIZATION_<CONFIG>", cmProperty::TARGET,
- "Per-configuration interprocedural optimization for a target.",
- "This is a per-configuration version of INTERPROCEDURAL_OPTIMIZATION. "
- "If set, this property overrides the generic property "
- "for the named configuration.");
-
- cm->DefineProperty
- ("LABELS", cmProperty::TARGET,
- "Specify a list of text labels associated with a target.",
- "Target label semantics are currently unspecified.");
-
- cm->DefineProperty
- ("LINK_FLAGS", cmProperty::TARGET,
- "Additional flags to use when linking this target.",
- "The LINK_FLAGS property can be used to add extra flags to the "
- "link step of a target. LINK_FLAGS_<CONFIG> will add to the "
- "configuration <CONFIG>, "
- "for example, DEBUG, RELEASE, MINSIZEREL, RELWITHDEBINFO. ");
-
- cm->DefineProperty
- ("LINK_FLAGS_<CONFIG>", cmProperty::TARGET,
- "Per-configuration linker flags for a target.",
- "This is the configuration-specific version of LINK_FLAGS.");
-
-#define CM_LINK_SEARCH_SUMMARY \
- "Some linkers support switches such as -Bstatic and -Bdynamic " \
- "to determine whether to use static or shared libraries for -lXXX " \
- "options. CMake uses these options to set the link type for " \
- "libraries whose full paths are not known or (in some cases) are in " \
- "implicit link directories for the platform. "
-
- cm->DefineProperty
- ("LINK_SEARCH_START_STATIC", cmProperty::TARGET,
- "Assume the linker looks for static libraries by default.",
- CM_LINK_SEARCH_SUMMARY
- "By default the linker search type is assumed to be -Bdynamic at "
- "the beginning of the library list. This property switches the "
- "assumption to -Bstatic. It is intended for use when linking an "
- "executable statically (e.g. with the GNU -static option). "
- "See also LINK_SEARCH_END_STATIC.");
-
- cm->DefineProperty
- ("LINK_SEARCH_END_STATIC", cmProperty::TARGET,
- "End a link line such that static system libraries are used.",
- CM_LINK_SEARCH_SUMMARY
- "By default CMake adds an option at the end of the library list (if "
- "necessary) to set the linker search type back to its starting type. "
- "This property switches the final linker search type to -Bstatic "
- "regardless of how it started. "
- "See also LINK_SEARCH_START_STATIC.");
-
- cm->DefineProperty
- ("LINKER_LANGUAGE", cmProperty::TARGET,
- "Specifies language whose compiler will invoke the linker.",
- "For executables, shared libraries, and modules, this sets the "
- "language whose compiler is used to link the target "
- "(such as \"C\" or \"CXX\"). "
- "A typical value for an executable is the language of the source "
- "file providing the program entry point (main). "
- "If not set, the language with the highest linker preference "
- "value is the default. "
- "See documentation of CMAKE_<LANG>_LINKER_PREFERENCE variables."
- "\n"
- "If this property is not set by the user, it will be calculated at "
- "generate-time by CMake."
- );
-
- cm->DefineProperty
- ("LOCATION", cmProperty::TARGET,
- "Read-only location of a target on disk.",
- "For an imported target, this read-only property returns the value of "
- "the LOCATION_<CONFIG> property for an unspecified configuration "
- "<CONFIG> provided by the target.\n"
- "For a non-imported target, this property is provided for compatibility "
- "with CMake 2.4 and below. "
- "It was meant to get the location of an executable target's output file "
- "for use in add_custom_command. "
- "The path may contain a build-system-specific portion that "
- "is replaced at build time with the configuration getting built "
- "(such as \"$(ConfigurationName)\" in VS). "
- "In CMake 2.6 and above add_custom_command automatically recognizes a "
- "target name in its COMMAND and DEPENDS options and computes the "
- "target location. "
- "In CMake 2.8.4 and above add_custom_command recognizes generator "
- "expressions to refer to target locations anywhere in the command. "
- "Therefore this property is not needed for creating custom commands."
- CM_LOCATION_UNDEFINED_BEHAVIOR("reading this property"));
-
- cm->DefineProperty
- ("LOCATION_<CONFIG>", cmProperty::TARGET,
- "Read-only property providing a target location on disk.",
- "A read-only property that indicates where a target's main file is "
- "located on disk for the configuration <CONFIG>. "
- "The property is defined only for library and executable targets. "
- "An imported target may provide a set of configurations different "
- "from that of the importing project. "
- "By default CMake looks for an exact-match but otherwise uses an "
- "arbitrary available configuration. "
- "Use the MAP_IMPORTED_CONFIG_<CONFIG> property to map imported "
- "configurations explicitly."
- CM_LOCATION_UNDEFINED_BEHAVIOR("reading this property"));
-
- cm->DefineProperty
- ("LINK_DEPENDS", cmProperty::TARGET,
- "Additional files on which a target binary depends for linking.",
- "Specifies a semicolon-separated list of full-paths to files on which "
- "the link rule for this target depends. "
- "The target binary will be linked if any of the named files is newer "
- "than it."
- "\n"
- "This property is ignored by non-Makefile generators. "
- "It is intended to specify dependencies on \"linker scripts\" for "
- "custom Makefile link rules.");
-
- cm->DefineProperty
- ("LINK_DEPENDS_NO_SHARED", cmProperty::TARGET,
- "Do not depend on linked shared library files.",
- "Set this property to true to tell CMake generators not to add "
- "file-level dependencies on the shared library files linked by "
- "this target. "
- "Modification to the shared libraries will not be sufficient to "
- "re-link this target. "
- "Logical target-level dependencies will not be affected so the "
- "linked shared libraries will still be brought up to date before "
- "this target is built."
- "\n"
- "This property is initialized by the value of the variable "
- "CMAKE_LINK_DEPENDS_NO_SHARED if it is set when a target is "
- "created.");
-
- cm->DefineProperty
- ("LINK_INTERFACE_LIBRARIES", cmProperty::TARGET,
- "List public interface libraries for a shared library or executable.",
- "By default linking to a shared library target transitively "
- "links to targets with which the library itself was linked. "
- "For an executable with exports (see the ENABLE_EXPORTS property) "
- "no default transitive link dependencies are used. "
- "This property replaces the default transitive link dependencies with "
- "an explicit list. "
- "When the target is linked into another target the libraries "
- "listed (and recursively their link interface libraries) will be "
- "provided to the other target also. "
- "If the list is empty then no transitive link dependencies will be "
- "incorporated when this target is linked into another target even if "
- "the default set is non-empty. "
- "This property is initialized by the value of the variable "
- "CMAKE_LINK_INTERFACE_LIBRARIES if it is set when a target is "
- "created. "
- "This property is ignored for STATIC libraries.\n"
- "This property is overridden by the INTERFACE_LINK_LIBRARIES property if "
- "policy CMP0022 is NEW.\n"
- "This property is deprecated. Use INTERFACE_LINK_LIBRARIES instead.");
-
- cm->DefineProperty
- ("LINK_INTERFACE_LIBRARIES_<CONFIG>", cmProperty::TARGET,
- "Per-configuration list of public interface libraries for a target.",
- "This is the configuration-specific version of "
- "LINK_INTERFACE_LIBRARIES. "
- "If set, this property completely overrides the generic property "
- "for the named configuration.\n"
- "This property is overridden by the INTERFACE_LINK_LIBRARIES property if "
- "policy CMP0022 is NEW.\n"
- "This property is deprecated. Use INTERFACE_LINK_LIBRARIES instead.");
-
- cm->DefineProperty
- ("INTERFACE_LINK_LIBRARIES", cmProperty::TARGET,
- "List public interface libraries for a library.",
- "This property contains the list of transitive link dependencies. "
- "When the target is linked into another target the libraries "
- "listed (and recursively their link interface libraries) will be "
- "provided to the other target also. "
- "This property is overridden by the LINK_INTERFACE_LIBRARIES or "
- "LINK_INTERFACE_LIBRARIES_<CONFIG> property if "
- "policy CMP0022 is OLD or unset.\n"
- "\n"
- CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS);
-
- cm->DefineProperty
- ("INTERFACE_INCLUDE_DIRECTORIES", cmProperty::TARGET,
- "List of public include directories for a library.",
- "Targets may populate this property to publish the include directories "
- "required to compile against the headers for the target. Consuming "
- "targets can add entries to their own INCLUDE_DIRECTORIES property such "
- "as $<TARGET_PROPERTY:foo,INTERFACE_INCLUDE_DIRECTORIES> to use the "
- "include directories specified in the interface of 'foo'."
- "\n"
- CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS);
-
- cm->DefineProperty
- ("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", cmProperty::TARGET,
- "List of public system include directories for a library.",
- "Targets may populate this property to publish the include directories "
- "which contain system headers, and therefore should not result in "
- "compiler warnings. Consuming targets will then mark the same include "
- "directories as system headers."
- "\n"
- CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS);
-
- cm->DefineProperty
- ("INTERFACE_COMPILE_DEFINITIONS", cmProperty::TARGET,
- "List of public compile definitions for a library.",
- "Targets may populate this property to publish the compile definitions "
- "required to compile against the headers for the target. Consuming "
- "targets can add entries to their own COMPILE_DEFINITIONS property such "
- "as $<TARGET_PROPERTY:foo,INTERFACE_COMPILE_DEFINITIONS> to use the "
- "compile definitions specified in the interface of 'foo'."
- "\n"
- CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS);
-
- cm->DefineProperty
- ("LINK_INTERFACE_MULTIPLICITY", cmProperty::TARGET,
- "Repetition count for STATIC libraries with cyclic dependencies.",
- "When linking to a STATIC library target with cyclic dependencies the "
- "linker may need to scan more than once through the archives in the "
- "strongly connected component of the dependency graph. "
- "CMake by default constructs the link line so that the linker will "
- "scan through the component at least twice. "
- "This property specifies the minimum number of scans if it is larger "
- "than the default. "
- "CMake uses the largest value specified by any target in a component.");
- cm->DefineProperty
- ("LINK_INTERFACE_MULTIPLICITY_<CONFIG>", cmProperty::TARGET,
- "Per-configuration repetition count for cycles of STATIC libraries.",
- "This is the configuration-specific version of "
- "LINK_INTERFACE_MULTIPLICITY. "
- "If set, this property completely overrides the generic property "
- "for the named configuration.");
-
- cm->DefineProperty
- ("MAP_IMPORTED_CONFIG_<CONFIG>", cmProperty::TARGET,
- "Map from project configuration to IMPORTED target's configuration.",
- "Set this to the list of configurations of an imported target that "
- "may be used for the current project's <CONFIG> configuration. "
- "Targets imported from another project may not provide the same set "
- "of configuration names available in the current project. "
- "Setting this property tells CMake what imported configurations are "
- "suitable for use when building the <CONFIG> configuration. "
- "The first configuration in the list found to be provided by the "
- "imported target is selected. If this property is set and no matching "
- "configurations are available, then the imported target is considered "
- "to be not found. This property is ignored for non-imported targets.",
- false /* TODO: make this chained */ );
-
- cm->DefineProperty
- ("OSX_ARCHITECTURES", cmProperty::TARGET,
- "Target specific architectures for OS X.",
- "The OSX_ARCHITECTURES property sets the target binary architecture "
- "for targets on OS X. "
- "This property is initialized by the value of the variable "
- "CMAKE_OSX_ARCHITECTURES if it is set when a target is created. "
- "Use OSX_ARCHITECTURES_<CONFIG> to set the binary architectures on a "
- "per-configuration basis. "
- "<CONFIG> is an upper-case name (ex: \"OSX_ARCHITECTURES_DEBUG\").");
-
- cm->DefineProperty
- ("OSX_ARCHITECTURES_<CONFIG>", cmProperty::TARGET,
- "Per-configuration OS X binary architectures for a target.",
- "This property is the configuration-specific version of "
- "OSX_ARCHITECTURES.");
-
- cm->DefineProperty
- ("NAME", cmProperty::TARGET,
- "Logical name for the target.",
- "Read-only logical name for the target as used by CMake.");
-
- cm->DefineProperty
- ("EXPORT_NAME", cmProperty::TARGET,
- "Exported name for target files.",
- "This sets the name for the IMPORTED target generated when it this "
- "target is is exported. "
- "If not set, the logical target name is used by default.");
-
- cm->DefineProperty
- ("OUTPUT_NAME", cmProperty::TARGET,
- "Output name for target files.",
- "This sets the base name for output files created for an executable or "
- "library target. "
- "If not set, the logical target name is used by default.");
-
- cm->DefineProperty
- ("OUTPUT_NAME_<CONFIG>", cmProperty::TARGET,
- "Per-configuration target file base name.",
- "This is the configuration-specific version of OUTPUT_NAME.");
-
- cm->DefineProperty
- ("ALIASED_TARGET", cmProperty::TARGET,
- "Name of target aliased by this target.",
- "If this is an ALIAS target, this property contains the name of the "
- "target aliased.");
-
- cm->DefineProperty
- ("<CONFIG>_OUTPUT_NAME", cmProperty::TARGET,
- "Old per-configuration target file base name.",
- "This is a configuration-specific version of OUTPUT_NAME. "
- "Use OUTPUT_NAME_<CONFIG> instead.");
-
- cm->DefineProperty
- ("PDB_NAME", cmProperty::TARGET,
- "Output name for MS debug symbols .pdb file from linker.",
- "Set the base name for debug symbols file created for an "
- "executable or shared library target. "
- "If not set, the logical target name is used by default. "
- "\n"
- "This property is not implemented by the Visual Studio 6 generator.");
-
- cm->DefineProperty
- ("PDB_NAME_<CONFIG>", cmProperty::TARGET,
- "Per-configuration name for MS debug symbols .pdb file. ",
- "This is the configuration-specific version of PDB_NAME. "
- "\n"
- "This property is not implemented by the Visual Studio 6 generator.");
-
- cm->DefineProperty
- ("PRE_INSTALL_SCRIPT", cmProperty::TARGET,
- "Deprecated install support.",
- "The PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT properties are the "
- "old way to specify CMake scripts to run before and after "
- "installing a target. They are used only when the old "
- "INSTALL_TARGETS command is used to install the target. Use the "
- "INSTALL command instead.");
-
- cm->DefineProperty
- ("PREFIX", cmProperty::TARGET,
- "What comes before the library name.",
- "A target property that can be set to override the prefix "
- "(such as \"lib\") on a library name.");
-
- cm->DefineProperty
- ("<LANG>_VISIBILITY_PRESET", cmProperty::TARGET,
- "Value for symbol visibility compile flags",
- "The <LANG>_VISIBILITY_PRESET property determines the value passed in "
- "a visibility related compile option, such as -fvisibility= for <LANG>. "
- "This property only has an affect for libraries and executables with "
- "exports. This property is initialized by the value of the variable "
- "CMAKE_<LANG>_VISIBILITY_PRESET if it is set when a target is created.");
-
- cm->DefineProperty
- ("VISIBILITY_INLINES_HIDDEN", cmProperty::TARGET,
- "Whether to add a compile flag to hide symbols of inline functions",
- "The VISIBILITY_INLINES_HIDDEN property determines whether a flag for "
- "hiding symbols for inline functions. the value passed used in "
- "a visibility related compile option, such as -fvisibility=. This "
- "property only has an affect for libraries and executables with "
- "exports. This property is initialized by the value of the variable "
- "CMAKE_VISIBILITY_INLINES_HIDDEN if it is set when a target is "
- "created.");
-
- cm->DefineProperty
- ("POSITION_INDEPENDENT_CODE", cmProperty::TARGET,
- "Whether to create a position-independent target",
- "The POSITION_INDEPENDENT_CODE property determines whether position "
- "independent executables or shared libraries will be created. "
- "This property is true by default for SHARED and MODULE library "
- "targets and false otherwise. "
- "This property is initialized by the value of the variable "
- "CMAKE_POSITION_INDEPENDENT_CODE if it is set when a target is "
- "created.");
-
- cm->DefineProperty
- ("INTERFACE_POSITION_INDEPENDENT_CODE", cmProperty::TARGET,
- "Whether consumers need to create a position-independent target",
- "The INTERFACE_POSITION_INDEPENDENT_CODE property informs consumers of "
- "this target whether they must set their POSITION_INDEPENDENT_CODE "
- "property to ON. If this property is set to ON, then the "
- "POSITION_INDEPENDENT_CODE property on all consumers will be set to "
- "ON. Similarly, if this property is set to OFF, then the "
- "POSITION_INDEPENDENT_CODE property on all consumers will be set to "
- "OFF. If this property is undefined, then consumers will determine "
- "their POSITION_INDEPENDENT_CODE property by other means. Consumers "
- "must ensure that the targets that they link to have a consistent "
- "requirement for their INTERFACE_POSITION_INDEPENDENT_CODE property.");
-
- cm->DefineProperty
- ("COMPATIBLE_INTERFACE_BOOL", cmProperty::TARGET,
- "Properties which must be compatible with their link interface",
- "The COMPATIBLE_INTERFACE_BOOL property may contain a list of properties"
- "for this target which must be consistent when evaluated as a boolean "
- "in the INTERFACE of all linked dependees. For example, if a "
- "property \"FOO\" appears in the list, then for each dependee, the "
- "\"INTERFACE_FOO\" property content in all of its dependencies must be "
- "consistent with each other, and with the \"FOO\" property in the "
- "dependee. Consistency in this sense has the meaning that if the "
- "property is set, then it must have the same boolean value as all "
- "others, and if the property is not set, then it is ignored. Note that "
- "for each dependee, the set of properties from this property must not "
- "intersect with the set of properties from the "
- "COMPATIBLE_INTERFACE_STRING property.");
-
- cm->DefineProperty
- ("COMPATIBLE_INTERFACE_STRING", cmProperty::TARGET,
- "Properties which must be string-compatible with their link interface",
- "The COMPATIBLE_INTERFACE_STRING property may contain a list of "
- "properties for this target which must be the same when evaluated as "
- "a string in the INTERFACE of all linked dependees. For example, "
- "if a property \"FOO\" appears in the list, then for each dependee, the "
- "\"INTERFACE_FOO\" property content in all of its dependencies must be "
- "equal with each other, and with the \"FOO\" property in the dependee. "
- "If the property is not set, then it is ignored. Note that for each "
- "dependee, the set of properties from this property must not intersect "
- "with the set of properties from the COMPATIBLE_INTERFACE_BOOL "
- "property.");
-
- cm->DefineProperty
- ("POST_INSTALL_SCRIPT", cmProperty::TARGET,
- "Deprecated install support.",
- "The PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT properties are the "
- "old way to specify CMake scripts to run before and after "
- "installing a target. They are used only when the old "
- "INSTALL_TARGETS command is used to install the target. Use the "
- "INSTALL command instead.");
-
- cm->DefineProperty
- ("PRIVATE_HEADER", cmProperty::TARGET,
- "Specify private header files in a FRAMEWORK shared library target.",
- "Shared library targets marked with the FRAMEWORK property generate "
- "frameworks on OS X and normal shared libraries on other platforms. "
- "This property may be set to a list of header files to be placed "
- "in the PrivateHeaders directory inside the framework folder. "
- "On non-Apple platforms these headers may be installed using the "
- "PRIVATE_HEADER option to the install(TARGETS) command.");
-
- cm->DefineProperty
- ("PUBLIC_HEADER", cmProperty::TARGET,
- "Specify public header files in a FRAMEWORK shared library target.",
- "Shared library targets marked with the FRAMEWORK property generate "
- "frameworks on OS X and normal shared libraries on other platforms. "
- "This property may be set to a list of header files to be placed "
- "in the Headers directory inside the framework folder. "
- "On non-Apple platforms these headers may be installed using the "
- "PUBLIC_HEADER option to the install(TARGETS) command.");
-
- cm->DefineProperty
- ("RESOURCE", cmProperty::TARGET,
- "Specify resource files in a FRAMEWORK shared library target.",
- "Shared library targets marked with the FRAMEWORK property generate "
- "frameworks on OS X and normal shared libraries on other platforms. "
- "This property may be set to a list of files to be placed "
- "in the Resources directory inside the framework folder. "
- "On non-Apple platforms these files may be installed using the "
- "RESOURCE option to the install(TARGETS) command.");
-
- cm->DefineProperty
- ("RULE_LAUNCH_COMPILE", cmProperty::TARGET,
- "Specify a launcher for compile rules.",
- "See the global property of the same name for details. "
- "This overrides the global and directory property for a target.",
- true);
- cm->DefineProperty
- ("RULE_LAUNCH_LINK", cmProperty::TARGET,
- "Specify a launcher for link rules.",
- "See the global property of the same name for details. "
- "This overrides the global and directory property for a target.",
- true);
- cm->DefineProperty
- ("RULE_LAUNCH_CUSTOM", cmProperty::TARGET,
- "Specify a launcher for custom rules.",
- "See the global property of the same name for details. "
- "This overrides the global and directory property for a target.",
- true);
-
- cm->DefineProperty
- ("SKIP_BUILD_RPATH", cmProperty::TARGET,
- "Should rpaths be used for the build tree.",
- "SKIP_BUILD_RPATH is a boolean specifying whether to skip automatic "
- "generation of an rpath allowing the target to run from the "
- "build tree. "
- "This property is initialized by the value of the variable "
- "CMAKE_SKIP_BUILD_RPATH if it is set when a target is created.");
-
- cm->DefineProperty
- ("NO_SONAME", cmProperty::TARGET,
- "Whether to set \"soname\" when linking a shared library or module.",
- "Enable this boolean property if a generated shared library or module "
- "should not have \"soname\" set. Default is to set \"soname\" on all "
- "shared libraries and modules as long as the platform supports it. "
- "Generally, use this property only for leaf private libraries or "
- "plugins. If you use it on normal shared libraries which other targets "
- "link against, on some platforms a linker will insert a full path to "
- "the library (as specified at link time) into the dynamic section of "
- "the dependent binary. Therefore, once installed, dynamic loader may "
- "eventually fail to locate the library for the binary.");
-
- cm->DefineProperty
- ("SOVERSION", cmProperty::TARGET,
- "What version number is this target.",
- "For shared libraries VERSION and SOVERSION can be used to specify "
- "the build version and API version respectively. When building or "
- "installing appropriate symlinks are created if the platform "
- "supports symlinks and the linker supports so-names. "
- "If only one of both is specified the missing is assumed to have "
- "the same version number. "
- "SOVERSION is ignored if NO_SONAME property is set. "
- "For shared libraries and executables on Windows the VERSION "
- "attribute is parsed to extract a \"major.minor\" version number. "
- "These numbers are used as the image version of the binary. ");
-
- cm->DefineProperty
- ("STATIC_LIBRARY_FLAGS", cmProperty::TARGET,
- "Extra flags to use when linking static libraries.",
- "Extra flags to use when linking a static library.");
-
- cm->DefineProperty
- ("STATIC_LIBRARY_FLAGS_<CONFIG>", cmProperty::TARGET,
- "Per-configuration flags for creating a static library.",
- "This is the configuration-specific version of STATIC_LIBRARY_FLAGS.");
-
- cm->DefineProperty
- ("SUFFIX", cmProperty::TARGET,
- "What comes after the target name.",
- "A target property that can be set to override the suffix "
- "(such as \".so\" or \".exe\") on the name of a library, module or "
- "executable.");
-
- cm->DefineProperty
- ("TYPE", cmProperty::TARGET,
- "The type of the target.",
- "This read-only property can be used to test the type of the given "
- "target. It will be one of STATIC_LIBRARY, MODULE_LIBRARY, "
- "SHARED_LIBRARY, EXECUTABLE or one of the internal target types.");
-
- cm->DefineProperty
- ("VERSION", cmProperty::TARGET,
- "What version number is this target.",
- "For shared libraries VERSION and SOVERSION can be used to specify "
- "the build version and API version respectively. When building or "
- "installing appropriate symlinks are created if the platform "
- "supports symlinks and the linker supports so-names. "
- "If only one of both is specified the missing is assumed to have "
- "the same version number. "
- "For executables VERSION can be used to specify the build version. "
- "When building or installing appropriate symlinks are created if "
- "the platform supports symlinks. "
- "For shared libraries and executables on Windows the VERSION "
- "attribute is parsed to extract a \"major.minor\" version number. "
- "These numbers are used as the image version of the binary. ");
-
-
- cm->DefineProperty
- ("WIN32_EXECUTABLE", cmProperty::TARGET,
- "Build an executable with a WinMain entry point on windows.",
- "When this property is set to true the executable when linked "
- "on Windows will be created with a WinMain() entry point instead "
- "of just main(). "
- "This makes it a GUI executable instead of a console application. "
- "See the CMAKE_MFC_FLAG variable documentation to configure use "
- "of MFC for WinMain executables. "
- "This property is initialized by the value of the variable "
- "CMAKE_WIN32_EXECUTABLE if it is set when a target is created.");
-
- cm->DefineProperty
- ("MACOSX_BUNDLE", cmProperty::TARGET,
- "Build an executable as an application bundle on Mac OS X.",
- "When this property is set to true the executable when built "
- "on Mac OS X will be created as an application bundle. "
- "This makes it a GUI executable that can be launched from "
- "the Finder. "
- "See the MACOSX_BUNDLE_INFO_PLIST target property for information "
- "about creation of the Info.plist file for the application bundle. "
- "This property is initialized by the value of the variable "
- "CMAKE_MACOSX_BUNDLE if it is set when a target is created.");
-
- cm->DefineProperty
- ("MACOSX_BUNDLE_INFO_PLIST", cmProperty::TARGET,
- "Specify a custom Info.plist template for a Mac OS X App Bundle.",
- "An executable target with MACOSX_BUNDLE enabled will be built as an "
- "application bundle on Mac OS X. "
- "By default its Info.plist file is created by configuring a template "
- "called MacOSXBundleInfo.plist.in located in the CMAKE_MODULE_PATH. "
- "This property specifies an alternative template file name which "
- "may be a full path.\n"
- "The following target properties may be set to specify content to "
- "be configured into the file:\n"
- " MACOSX_BUNDLE_INFO_STRING\n"
- " MACOSX_BUNDLE_ICON_FILE\n"
- " MACOSX_BUNDLE_GUI_IDENTIFIER\n"
- " MACOSX_BUNDLE_LONG_VERSION_STRING\n"
- " MACOSX_BUNDLE_BUNDLE_NAME\n"
- " MACOSX_BUNDLE_SHORT_VERSION_STRING\n"
- " MACOSX_BUNDLE_BUNDLE_VERSION\n"
- " MACOSX_BUNDLE_COPYRIGHT\n"
- "CMake variables of the same name may be set to affect all targets "
- "in a directory that do not have each specific property set. "
- "If a custom Info.plist is specified by this property it may of course "
- "hard-code all the settings instead of using the target properties.");
-
- cm->DefineProperty
- ("MACOSX_FRAMEWORK_INFO_PLIST", cmProperty::TARGET,
- "Specify a custom Info.plist template for a Mac OS X Framework.",
- "A library target with FRAMEWORK enabled will be built as a "
- "framework on Mac OS X. "
- "By default its Info.plist file is created by configuring a template "
- "called MacOSXFrameworkInfo.plist.in located in the CMAKE_MODULE_PATH. "
- "This property specifies an alternative template file name which "
- "may be a full path.\n"
- "The following target properties may be set to specify content to "
- "be configured into the file:\n"
- " MACOSX_FRAMEWORK_ICON_FILE\n"
- " MACOSX_FRAMEWORK_IDENTIFIER\n"
- " MACOSX_FRAMEWORK_SHORT_VERSION_STRING\n"
- " MACOSX_FRAMEWORK_BUNDLE_VERSION\n"
- "CMake variables of the same name may be set to affect all targets "
- "in a directory that do not have each specific property set. "
- "If a custom Info.plist is specified by this property it may of course "
- "hard-code all the settings instead of using the target properties.");
-
- cm->DefineProperty
- ("MACOSX_RPATH", cmProperty::TARGET,
- "Whether to use rpaths on Mac OS X.",
- "When this property is set to true, the directory portion of the"
- "\"install_name\" field of shared libraries will default to \"@rpath\"."
- "Runtime paths will also be embedded in binaries using this target."
- "This property is initialized by the value of the variable "
- "CMAKE_MACOSX_RPATH if it is set when a target is created.");
-
- cm->DefineProperty
- ("ENABLE_EXPORTS", cmProperty::TARGET,
- "Specify whether an executable exports symbols for loadable modules.",
- "Normally an executable does not export any symbols because it is "
- "the final program. It is possible for an executable to export "
- "symbols to be used by loadable modules. When this property is "
- "set to true CMake will allow other targets to \"link\" to the "
- "executable with the TARGET_LINK_LIBRARIES command. "
- "On all platforms a target-level dependency on the executable is "
- "created for targets that link to it. "
- "For DLL platforms an import library will be created for the "
- "exported symbols and then used for linking. "
- "All Windows-based systems including Cygwin are DLL platforms. "
- "For non-DLL platforms that require all symbols to be resolved at "
- "link time, such as Mac OS X, the module will \"link\" to the "
- "executable using a flag like \"-bundle_loader\". "
- "For other non-DLL platforms the link rule is simply ignored since "
- "the dynamic loader will automatically bind symbols when the "
- "module is loaded. "
- );
-
- cm->DefineProperty
- ("Fortran_FORMAT", cmProperty::TARGET,
- "Set to FIXED or FREE to indicate the Fortran source layout.",
- "This property tells CMake whether the Fortran source files "
- "in a target use fixed-format or free-format. "
- "CMake will pass the corresponding format flag to the compiler. "
- "Use the source-specific Fortran_FORMAT property to change the "
- "format of a specific source file. "
- "If the variable CMAKE_Fortran_FORMAT is set when a target "
- "is created its value is used to initialize this property.");
-
- cm->DefineProperty
- ("Fortran_MODULE_DIRECTORY", cmProperty::TARGET,
- "Specify output directory for Fortran modules provided by the target.",
- "If the target contains Fortran source files that provide modules "
- "and the compiler supports a module output directory this specifies "
- "the directory in which the modules will be placed. "
- "When this property is not set the modules will be placed in the "
- "build directory corresponding to the target's source directory. "
- "If the variable CMAKE_Fortran_MODULE_DIRECTORY is set when a target "
- "is created its value is used to initialize this property."
- "\n"
- "Note that some compilers will automatically search the module output "
- "directory for modules USEd during compilation but others will not. "
- "If your sources USE modules their location must be specified by "
- "INCLUDE_DIRECTORIES regardless of this property.");
-
- cm->DefineProperty
- ("GNUtoMS", cmProperty::TARGET,
- "Convert GNU import library (.dll.a) to MS format (.lib).",
- "When linking a shared library or executable that exports symbols "
- "using GNU tools on Windows (MinGW/MSYS) with Visual Studio installed "
- "convert the import library (.dll.a) from GNU to MS format (.lib). "
- "Both import libraries will be installed by install(TARGETS) and "
- "exported by install(EXPORT) and export() to be linked by applications "
- "with either GNU- or MS-compatible tools."
- "\n"
- "If the variable CMAKE_GNUtoMS is set when a target "
- "is created its value is used to initialize this property. "
- "The variable must be set prior to the first command that enables "
- "a language such as project() or enable_language(). "
- "CMake provides the variable as an option to the user automatically "
- "when configuring on Windows with GNU tools.");
-
- cm->DefineProperty
- ("XCODE_ATTRIBUTE_<an-attribute>", cmProperty::TARGET,
- "Set Xcode target attributes directly.",
- "Tell the Xcode generator to set '<an-attribute>' to a given value "
- "in the generated Xcode project. Ignored on other generators.");
-
- cm->DefineProperty
- ("GENERATOR_FILE_NAME", cmProperty::TARGET,
- "Generator's file for this target.",
- "An internal property used by some generators to record the name of the "
- "project or dsp file associated with this target. Note that at configure "
- "time, this property is only set for targets created by "
- "include_external_msproject().");
-
- cm->DefineProperty
- ("SOURCES", cmProperty::TARGET,
- "Source names specified for a target.",
- "Read-only list of sources specified for a target. "
- "The names returned are suitable for passing to the "
- "set_source_files_properties command.");
-
- cm->DefineProperty
- ("FOLDER", cmProperty::TARGET,
- "Set the folder name. Use to organize targets in an IDE.",
- "Targets with no FOLDER property will appear as top level "
- "entities in IDEs like Visual Studio. Targets with the same "
- "FOLDER property value will appear next to each other in a "
- "folder of that name. To nest folders, use FOLDER values such "
- "as 'GUI/Dialogs' with '/' characters separating folder levels.");
-
- cm->DefineProperty
- ("PROJECT_LABEL", cmProperty::TARGET,
- "Change the name of a target in an IDE.",
- "Can be used to change the name of the target in an IDE "
- "like Visual Studio. ");
- cm->DefineProperty
- ("VS_KEYWORD", cmProperty::TARGET,
- "Visual Studio project keyword.",
- "Can be set to change the visual studio keyword, for example "
- "Qt integration works better if this is set to Qt4VSv1.0. ");
- cm->DefineProperty
- ("VS_SCC_PROVIDER", cmProperty::TARGET,
- "Visual Studio Source Code Control Provider.",
- "Can be set to change the visual studio source code control "
- "provider property.");
- cm->DefineProperty
- ("VS_SCC_LOCALPATH", cmProperty::TARGET,
- "Visual Studio Source Code Control Local Path.",
- "Can be set to change the visual studio source code control "
- "local path property.");
- cm->DefineProperty
- ("VS_SCC_PROJECTNAME", cmProperty::TARGET,
- "Visual Studio Source Code Control Project.",
- "Can be set to change the visual studio source code control "
- "project name property.");
- cm->DefineProperty
- ("VS_SCC_AUXPATH", cmProperty::TARGET,
- "Visual Studio Source Code Control Aux Path.",
- "Can be set to change the visual studio source code control "
- "auxpath property.");
- cm->DefineProperty
- ("VS_GLOBAL_PROJECT_TYPES", cmProperty::TARGET,
- "Visual Studio project type(s).",
- "Can be set to one or more UUIDs recognized by Visual Studio "
- "to indicate the type of project. This value is copied "
- "verbatim into the generated project file. Example for a "
- "managed C++ unit testing project:\n"
- " {3AC096D0-A1C2-E12C-1390-A8335801FDAB};"
- "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\n"
- "UUIDs are semicolon-delimited.");
- cm->DefineProperty
- ("VS_GLOBAL_KEYWORD", cmProperty::TARGET,
- "Visual Studio project keyword.",
- "Sets the \"keyword\" attribute for a generated Visual Studio "
- "project. Defaults to \"Win32Proj\". You may wish to override "
- "this value with \"ManagedCProj\", for example, in a Visual "
- "Studio managed C++ unit test project.");
- cm->DefineProperty
- ("VS_GLOBAL_ROOTNAMESPACE", cmProperty::TARGET,
- "Visual Studio project root namespace.",
- "Sets the \"RootNamespace\" attribute for a generated Visual Studio "
- "project. The attribute will be generated only if this is set.");
- cm->DefineProperty
- ("VS_DOTNET_TARGET_FRAMEWORK_VERSION", cmProperty::TARGET,
- "Specify the .NET target framework version.",
- "Used to specify the .NET target framework version for C++/CLI. "
- "For example, \"v4.5\".");
- cm->DefineProperty
- ("VS_DOTNET_REFERENCES", cmProperty::TARGET,
- "Visual Studio managed project .NET references",
- "Adds one or more semicolon-delimited .NET references to a "
- "generated Visual Studio project. For example, \"System;"
- "System.Windows.Forms\".");
- cm->DefineProperty
- ("VS_WINRT_EXTENSIONS", cmProperty::TARGET,
- "Visual Studio project C++/CX language extensions for Windows Runtime",
- "Can be set to enable C++/CX language extensions.");
- cm->DefineProperty
- ("VS_WINRT_REFERENCES", cmProperty::TARGET,
- "Visual Studio project Windows Runtime Metadata references",
- "Adds one or more semicolon-delimited WinRT references to a "
- "generated Visual Studio project. For example, \"Windows;"
- "Windows.UI.Core\".");
- cm->DefineProperty
- ("VS_GLOBAL_<variable>", cmProperty::TARGET,
- "Visual Studio project-specific global variable.",
- "Tell the Visual Studio generator to set the global variable "
- "'<variable>' to a given value in the generated Visual Studio "
- "project. Ignored on other generators. Qt integration works "
- "better if VS_GLOBAL_QtVersion is set to the version "
- "FindQt4.cmake found. For example, \"4.7.3\"");
-
-#define CM_TARGET_FILE_TYPES_DOC \
- "There are three kinds of target files that may be built: " \
- "archive, library, and runtime. " \
- "Executables are always treated as runtime targets. " \
- "Static libraries are always treated as archive targets. " \
- "Module libraries are always treated as library targets. " \
- "For non-DLL platforms shared libraries are treated as library " \
- "targets. " \
- "For DLL platforms the DLL part of a shared library is treated as " \
- "a runtime target and the corresponding import library is treated as " \
- "an archive target. " \
- "All Windows-based systems including Cygwin are DLL platforms."
-
-#define CM_TARGET_OUTDIR_DOC(TYPE, type) \
- "This property specifies the directory into which " #type " target " \
- "files should be built. " \
- "Multi-configuration generators (VS, Xcode) append " \
- "a per-configuration subdirectory to the specified directory. " \
- CM_TARGET_FILE_TYPES_DOC " " \
- "This property is initialized by the value of the variable " \
- "CMAKE_" #TYPE "_OUTPUT_DIRECTORY if it is set when a target is created."
-
-#define CM_TARGET_OUTDIR_CONFIG_DOC(TYPE) \
- "This is a per-configuration version of " #TYPE "_OUTPUT_DIRECTORY, " \
- "but multi-configuration generators (VS, Xcode) do NOT append " \
- "a per-configuration subdirectory to the specified directory. " \
- "This property is initialized by the value of the variable " \
- "CMAKE_" #TYPE "_OUTPUT_DIRECTORY_<CONFIG> " \
- "if it is set when a target is created."
-
- cm->DefineProperty
- ("ARCHIVE_OUTPUT_DIRECTORY", cmProperty::TARGET,
- "Output directory in which to build ARCHIVE target files.",
- CM_TARGET_OUTDIR_DOC(ARCHIVE, archive));
- cm->DefineProperty
- ("ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>", cmProperty::TARGET,
- "Per-configuration output directory for ARCHIVE target files.",
- CM_TARGET_OUTDIR_CONFIG_DOC(ARCHIVE));
- cm->DefineProperty
- ("LIBRARY_OUTPUT_DIRECTORY", cmProperty::TARGET,
- "Output directory in which to build LIBRARY target files.",
- CM_TARGET_OUTDIR_DOC(LIBRARY, library));
- cm->DefineProperty
- ("LIBRARY_OUTPUT_DIRECTORY_<CONFIG>", cmProperty::TARGET,
- "Per-configuration output directory for LIBRARY target files.",
- CM_TARGET_OUTDIR_CONFIG_DOC(LIBRARY));
- cm->DefineProperty
- ("RUNTIME_OUTPUT_DIRECTORY", cmProperty::TARGET,
- "Output directory in which to build RUNTIME target files.",
- CM_TARGET_OUTDIR_DOC(RUNTIME, runtime));
- cm->DefineProperty
- ("RUNTIME_OUTPUT_DIRECTORY_<CONFIG>", cmProperty::TARGET,
- "Per-configuration output directory for RUNTIME target files.",
- CM_TARGET_OUTDIR_CONFIG_DOC(RUNTIME));
-
- cm->DefineProperty
- ("PDB_OUTPUT_DIRECTORY", cmProperty::TARGET,
- "Output directory for MS debug symbols .pdb file from linker.",
- "This property specifies the directory into which the MS debug symbols "
- "will be placed by the linker. "
- "This property is initialized by the value of the variable "
- "CMAKE_PDB_OUTPUT_DIRECTORY if it is set when a target is created."
- "\n"
- "This property is not implemented by the Visual Studio 6 generator.");
- cm->DefineProperty
- ("PDB_OUTPUT_DIRECTORY_<CONFIG>", cmProperty::TARGET,
- "Per-configuration output directory for MS debug symbols .pdb files.",
- "This is a per-configuration version of PDB_OUTPUT_DIRECTORY, "
- "but multi-configuration generators (VS, Xcode) do NOT append "
- "a per-configuration subdirectory to the specified directory. "
- "This property is initialized by the value of the variable "
- "CMAKE_PDB_OUTPUT_DIRECTORY_<CONFIG> "
- "if it is set when a target is created."
- "\n"
- "This property is not implemented by the Visual Studio 6 generator.");
-
- cm->DefineProperty
- ("ARCHIVE_OUTPUT_NAME", cmProperty::TARGET,
- "Output name for ARCHIVE target files.",
- "This property specifies the base name for archive target files. "
- "It overrides OUTPUT_NAME and OUTPUT_NAME_<CONFIG> properties. "
- CM_TARGET_FILE_TYPES_DOC);
- cm->DefineProperty
- ("ARCHIVE_OUTPUT_NAME_<CONFIG>", cmProperty::TARGET,
- "Per-configuration output name for ARCHIVE target files.",
- "This is the configuration-specific version of ARCHIVE_OUTPUT_NAME.");
- cm->DefineProperty
- ("LIBRARY_OUTPUT_NAME", cmProperty::TARGET,
- "Output name for LIBRARY target files.",
- "This property specifies the base name for library target files. "
- "It overrides OUTPUT_NAME and OUTPUT_NAME_<CONFIG> properties. "
- CM_TARGET_FILE_TYPES_DOC);
- cm->DefineProperty
- ("LIBRARY_OUTPUT_NAME_<CONFIG>", cmProperty::TARGET,
- "Per-configuration output name for LIBRARY target files.",
- "This is the configuration-specific version of LIBRARY_OUTPUT_NAME.");
- cm->DefineProperty
- ("RUNTIME_OUTPUT_NAME", cmProperty::TARGET,
- "Output name for RUNTIME target files.",
- "This property specifies the base name for runtime target files. "
- "It overrides OUTPUT_NAME and OUTPUT_NAME_<CONFIG> properties. "
- CM_TARGET_FILE_TYPES_DOC);
- cm->DefineProperty
- ("RUNTIME_OUTPUT_NAME_<CONFIG>", cmProperty::TARGET,
- "Per-configuration output name for RUNTIME target files.",
- "This is the configuration-specific version of RUNTIME_OUTPUT_NAME.");
}
-void cmTarget::SetType(TargetType type, const char* name)
+void cmTarget::SetType(cmState::TargetType type, const std::string& name)
{
this->Name = name;
// only add dependency information for library targets
this->TargetTypeValue = type;
- if(this->TargetTypeValue >= STATIC_LIBRARY
- && this->TargetTypeValue <= MODULE_LIBRARY)
+ if(this->TargetTypeValue >= cmState::STATIC_LIBRARY
+ && this->TargetTypeValue <= cmState::MODULE_LIBRARY)
{
this->RecordDependencies = true;
}
@@ -1608,724 +88,450 @@ void cmTarget::SetMakefile(cmMakefile* mf)
// Set our makefile.
this->Makefile = mf;
- // set the cmake instance of the properties
- this->Properties.SetCMakeInstance(mf->GetCMakeInstance());
-
// Check whether this is a DLL platform.
this->DLLPlatform = (this->Makefile->IsOn("WIN32") ||
this->Makefile->IsOn("CYGWIN") ||
this->Makefile->IsOn("MINGW"));
- // Check whether we are targeting an Apple platform.
- this->IsApple = this->Makefile->IsOn("APPLE");
+ // Check whether we are targeting an Android platform.
+ this->IsAndroid =
+ strcmp(this->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME"),
+ "Android") == 0;
// Setup default property values.
- this->SetPropertyDefault("INSTALL_NAME_DIR", 0);
- this->SetPropertyDefault("INSTALL_RPATH", "");
- this->SetPropertyDefault("INSTALL_RPATH_USE_LINK_PATH", "OFF");
- this->SetPropertyDefault("SKIP_BUILD_RPATH", "OFF");
- this->SetPropertyDefault("BUILD_WITH_INSTALL_RPATH", "OFF");
- this->SetPropertyDefault("ARCHIVE_OUTPUT_DIRECTORY", 0);
- this->SetPropertyDefault("LIBRARY_OUTPUT_DIRECTORY", 0);
- this->SetPropertyDefault("RUNTIME_OUTPUT_DIRECTORY", 0);
- this->SetPropertyDefault("PDB_OUTPUT_DIRECTORY", 0);
- this->SetPropertyDefault("Fortran_FORMAT", 0);
- this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", 0);
- this->SetPropertyDefault("GNUtoMS", 0);
- this->SetPropertyDefault("OSX_ARCHITECTURES", 0);
- this->SetPropertyDefault("AUTOMOC", 0);
- this->SetPropertyDefault("AUTOMOC_MOC_OPTIONS", 0);
- this->SetPropertyDefault("LINK_DEPENDS_NO_SHARED", 0);
- this->SetPropertyDefault("LINK_INTERFACE_LIBRARIES", 0);
- this->SetPropertyDefault("WIN32_EXECUTABLE", 0);
- this->SetPropertyDefault("MACOSX_BUNDLE", 0);
- this->SetPropertyDefault("MACOSX_RPATH", 0);
-
+ if (this->GetType() != cmState::INTERFACE_LIBRARY
+ && this->GetType() != cmState::UTILITY)
+ {
+ this->SetPropertyDefault("ANDROID_API", 0);
+ this->SetPropertyDefault("ANDROID_API_MIN", 0);
+ this->SetPropertyDefault("ANDROID_ARCH", 0);
+ this->SetPropertyDefault("ANDROID_STL_TYPE", 0);
+ this->SetPropertyDefault("ANDROID_SKIP_ANT_STEP", 0);
+ this->SetPropertyDefault("ANDROID_PROCESS_MAX", 0);
+ this->SetPropertyDefault("ANDROID_PROGUARD", 0);
+ this->SetPropertyDefault("ANDROID_PROGUARD_CONFIG_PATH", 0);
+ this->SetPropertyDefault("ANDROID_SECURE_PROPS_PATH", 0);
+ this->SetPropertyDefault("ANDROID_NATIVE_LIB_DIRECTORIES", 0);
+ this->SetPropertyDefault("ANDROID_NATIVE_LIB_DEPENDENCIES", 0);
+ this->SetPropertyDefault("ANDROID_JAVA_SOURCE_DIR", 0);
+ this->SetPropertyDefault("ANDROID_JAR_DIRECTORIES", 0);
+ this->SetPropertyDefault("ANDROID_JAR_DEPENDENCIES", 0);
+ this->SetPropertyDefault("ANDROID_ASSETS_DIRECTORIES", 0);
+ this->SetPropertyDefault("ANDROID_ANT_ADDITIONAL_OPTIONS", 0);
+ this->SetPropertyDefault("INSTALL_NAME_DIR", 0);
+ this->SetPropertyDefault("INSTALL_RPATH", "");
+ this->SetPropertyDefault("INSTALL_RPATH_USE_LINK_PATH", "OFF");
+ this->SetPropertyDefault("SKIP_BUILD_RPATH", "OFF");
+ this->SetPropertyDefault("BUILD_WITH_INSTALL_RPATH", "OFF");
+ this->SetPropertyDefault("ARCHIVE_OUTPUT_DIRECTORY", 0);
+ this->SetPropertyDefault("LIBRARY_OUTPUT_DIRECTORY", 0);
+ this->SetPropertyDefault("RUNTIME_OUTPUT_DIRECTORY", 0);
+ this->SetPropertyDefault("PDB_OUTPUT_DIRECTORY", 0);
+ this->SetPropertyDefault("COMPILE_PDB_OUTPUT_DIRECTORY", 0);
+ this->SetPropertyDefault("Fortran_FORMAT", 0);
+ this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", 0);
+ this->SetPropertyDefault("GNUtoMS", 0);
+ this->SetPropertyDefault("OSX_ARCHITECTURES", 0);
+ this->SetPropertyDefault("IOS_INSTALL_COMBINED", 0);
+ this->SetPropertyDefault("AUTOMOC", 0);
+ this->SetPropertyDefault("AUTOUIC", 0);
+ this->SetPropertyDefault("AUTORCC", 0);
+ this->SetPropertyDefault("AUTOMOC_MOC_OPTIONS", 0);
+ this->SetPropertyDefault("AUTOUIC_OPTIONS", 0);
+ this->SetPropertyDefault("AUTORCC_OPTIONS", 0);
+ this->SetPropertyDefault("LINK_DEPENDS_NO_SHARED", 0);
+ this->SetPropertyDefault("LINK_INTERFACE_LIBRARIES", 0);
+ this->SetPropertyDefault("WIN32_EXECUTABLE", 0);
+ this->SetPropertyDefault("MACOSX_BUNDLE", 0);
+ this->SetPropertyDefault("MACOSX_RPATH", 0);
+ this->SetPropertyDefault("NO_SYSTEM_FROM_IMPORTED", 0);
+ this->SetPropertyDefault("C_COMPILER_LAUNCHER", 0);
+ this->SetPropertyDefault("C_INCLUDE_WHAT_YOU_USE", 0);
+ this->SetPropertyDefault("C_STANDARD", 0);
+ this->SetPropertyDefault("C_STANDARD_REQUIRED", 0);
+ this->SetPropertyDefault("C_EXTENSIONS", 0);
+ this->SetPropertyDefault("CXX_COMPILER_LAUNCHER", 0);
+ this->SetPropertyDefault("CXX_INCLUDE_WHAT_YOU_USE", 0);
+ this->SetPropertyDefault("CXX_STANDARD", 0);
+ this->SetPropertyDefault("CXX_STANDARD_REQUIRED", 0);
+ this->SetPropertyDefault("CXX_EXTENSIONS", 0);
+ this->SetPropertyDefault("LINK_SEARCH_START_STATIC", 0);
+ this->SetPropertyDefault("LINK_SEARCH_END_STATIC", 0);
+ }
// Collect the set of configuration types.
std::vector<std::string> configNames;
mf->GetConfigurations(configNames);
// Setup per-configuration property default values.
- const char* configProps[] = {
- "ARCHIVE_OUTPUT_DIRECTORY_",
- "LIBRARY_OUTPUT_DIRECTORY_",
- "RUNTIME_OUTPUT_DIRECTORY_",
- "PDB_OUTPUT_DIRECTORY_",
- 0};
- for(std::vector<std::string>::iterator ci = configNames.begin();
- ci != configNames.end(); ++ci)
- {
- std::string configUpper = cmSystemTools::UpperCase(*ci);
- for(const char** p = configProps; *p; ++p)
- {
- std::string property = *p;
- property += configUpper;
- this->SetPropertyDefault(property.c_str(), 0);
- }
+ if (this->GetType() != cmState::UTILITY)
+ {
+ const char* configProps[] = {
+ "ARCHIVE_OUTPUT_DIRECTORY_",
+ "LIBRARY_OUTPUT_DIRECTORY_",
+ "RUNTIME_OUTPUT_DIRECTORY_",
+ "PDB_OUTPUT_DIRECTORY_",
+ "COMPILE_PDB_OUTPUT_DIRECTORY_",
+ "MAP_IMPORTED_CONFIG_",
+ 0};
+ for(std::vector<std::string>::iterator ci = configNames.begin();
+ ci != configNames.end(); ++ci)
+ {
+ std::string configUpper = cmSystemTools::UpperCase(*ci);
+ for(const char** p = configProps; *p; ++p)
+ {
+ if (this->TargetTypeValue == cmState::INTERFACE_LIBRARY
+ && strcmp(*p, "MAP_IMPORTED_CONFIG_") != 0)
+ {
+ continue;
+ }
+ std::string property = *p;
+ property += configUpper;
+ this->SetPropertyDefault(property, 0);
+ }
- // Initialize per-configuration name postfix property from the
- // variable only for non-executable targets. This preserves
- // compatibility with previous CMake versions in which executables
- // did not support this variable. Projects may still specify the
- // property directly. TODO: Make this depend on backwards
- // compatibility setting.
- if(this->TargetTypeValue != cmTarget::EXECUTABLE)
- {
- std::string property = cmSystemTools::UpperCase(*ci);
- property += "_POSTFIX";
- this->SetPropertyDefault(property.c_str(), 0);
+ // Initialize per-configuration name postfix property from the
+ // variable only for non-executable targets. This preserves
+ // compatibility with previous CMake versions in which executables
+ // did not support this variable. Projects may still specify the
+ // property directly.
+ if(this->TargetTypeValue != cmState::EXECUTABLE
+ && this->TargetTypeValue != cmState::INTERFACE_LIBRARY)
+ {
+ std::string property = cmSystemTools::UpperCase(*ci);
+ property += "_POSTFIX";
+ this->SetPropertyDefault(property, 0);
+ }
}
}
// Save the backtrace of target construction.
- this->Makefile->GetBacktrace(this->Internal->Backtrace);
+ this->Backtrace = this->Makefile->GetBacktrace();
- // Initialize the INCLUDE_DIRECTORIES property based on the current value
- // of the same directory property:
- const std::vector<cmValueWithOrigin> parentIncludes =
- this->Makefile->GetIncludeDirectoriesEntries();
-
- for (std::vector<cmValueWithOrigin>::const_iterator it
- = parentIncludes.begin(); it != parentIncludes.end(); ++it)
+ if (!this->IsImported())
{
- this->InsertInclude(*it);
- }
+ // Initialize the INCLUDE_DIRECTORIES property based on the current value
+ // of the same directory property:
+ const cmStringRange parentIncludes =
+ this->Makefile->GetIncludeDirectoriesEntries();
+ const cmBacktraceRange parentIncludesBts =
+ this->Makefile->GetIncludeDirectoriesBacktraces();
- const std::set<cmStdString> parentSystemIncludes =
- this->Makefile->GetSystemIncludeDirectories();
+ this->Internal->IncludeDirectoriesEntries.insert(
+ this->Internal->IncludeDirectoriesEntries.end(),
+ parentIncludes.begin(), parentIncludes.end());
+ this->Internal->IncludeDirectoriesBacktraces.insert(
+ this->Internal->IncludeDirectoriesBacktraces.end(),
+ parentIncludesBts.begin(), parentIncludesBts.end());
- for (std::set<cmStdString>::const_iterator it
- = parentSystemIncludes.begin();
- it != parentSystemIncludes.end(); ++it)
- {
- this->SystemIncludeDirectories.insert(*it);
- }
+ const std::set<std::string> parentSystemIncludes =
+ this->Makefile->GetSystemIncludeDirectories();
- const std::vector<cmValueWithOrigin> parentOptions =
- this->Makefile->GetCompileOptionsEntries();
+ this->SystemIncludeDirectories.insert(parentSystemIncludes.begin(),
+ parentSystemIncludes.end());
- for (std::vector<cmValueWithOrigin>::const_iterator it
- = parentOptions.begin(); it != parentOptions.end(); ++it)
- {
- this->InsertCompileOption(*it);
+ const cmStringRange parentOptions =
+ this->Makefile->GetCompileOptionsEntries();
+ const cmBacktraceRange parentOptionsBts =
+ this->Makefile->GetCompileOptionsBacktraces();
+
+ this->Internal->CompileOptionsEntries.insert(
+ this->Internal->CompileOptionsEntries.end(),
+ parentOptions.begin(), parentOptions.end());
+ this->Internal->CompileOptionsBacktraces.insert(
+ this->Internal->CompileOptionsBacktraces.end(),
+ parentOptionsBts.begin(), parentOptionsBts.end());
}
- this->SetPropertyDefault("C_VISIBILITY_PRESET", 0);
- this->SetPropertyDefault("CXX_VISIBILITY_PRESET", 0);
- this->SetPropertyDefault("VISIBILITY_INLINES_HIDDEN", 0);
+ if (this->GetType() != cmState::INTERFACE_LIBRARY
+ && this->GetType() != cmState::UTILITY)
+ {
+ this->SetPropertyDefault("C_VISIBILITY_PRESET", 0);
+ this->SetPropertyDefault("CXX_VISIBILITY_PRESET", 0);
+ this->SetPropertyDefault("VISIBILITY_INLINES_HIDDEN", 0);
+ }
- if(this->TargetTypeValue == cmTarget::SHARED_LIBRARY
- || this->TargetTypeValue == cmTarget::MODULE_LIBRARY)
+ if(this->TargetTypeValue == cmState::EXECUTABLE)
+ {
+ this->SetPropertyDefault("ANDROID_GUI", 0);
+ this->SetPropertyDefault("CROSSCOMPILING_EMULATOR", 0);
+ this->SetPropertyDefault("ENABLE_EXPORTS", 0);
+ }
+ if(this->TargetTypeValue == cmState::SHARED_LIBRARY
+ || this->TargetTypeValue == cmState::MODULE_LIBRARY)
{
this->SetProperty("POSITION_INDEPENDENT_CODE", "True");
}
- this->SetPropertyDefault("POSITION_INDEPENDENT_CODE", 0);
+ if(this->TargetTypeValue == cmState::SHARED_LIBRARY)
+ {
+ this->SetPropertyDefault("WINDOWS_EXPORT_ALL_SYMBOLS", 0);
+ }
- // Record current policies for later use.
-#define CAPTURE_TARGET_POLICY(POLICY) \
- this->PolicyStatus ## POLICY = \
- this->Makefile->GetPolicyStatus(cmPolicies::POLICY);
+ if (this->GetType() != cmState::INTERFACE_LIBRARY
+ && this->GetType() != cmState::UTILITY)
+ {
+ this->SetPropertyDefault("POSITION_INDEPENDENT_CODE", 0);
+ }
- CM_FOR_EACH_TARGET_POLICY(CAPTURE_TARGET_POLICY)
+ // Record current policies for later use.
+ this->Makefile->RecordPolicies(this->PolicyMap);
-#undef CAPTURE_TARGET_POLICY
-}
+ if (this->TargetTypeValue == cmState::INTERFACE_LIBRARY)
+ {
+ // This policy is checked in a few conditions. The properties relevant
+ // to the policy are always ignored for cmState::INTERFACE_LIBRARY targets,
+ // so ensure that the conditions don't lead to nonsense.
+ this->PolicyMap.Set(cmPolicies::CMP0022, cmPolicies::NEW);
+ }
-//----------------------------------------------------------------------------
-void cmTarget::FinishConfigure()
-{
- // Erase any cached link information that might have been comptued
- // on-demand during the configuration. This ensures that build
- // system generation uses up-to-date information even if other cache
- // invalidation code in this source file is buggy.
- this->ClearLinkMaps();
-
- // Do old-style link dependency analysis.
- this->AnalyzeLibDependencies(*this->Makefile);
+ if (this->GetType() != cmState::INTERFACE_LIBRARY
+ && this->GetType() != cmState::UTILITY)
+ {
+ this->SetPropertyDefault("JOB_POOL_COMPILE", 0);
+ this->SetPropertyDefault("JOB_POOL_LINK", 0);
+ }
}
//----------------------------------------------------------------------------
-void cmTarget::ClearLinkMaps()
+void cmTarget::AddUtility(const std::string& u, cmMakefile *makefile)
{
- this->Internal->LinkImplMap.clear();
- this->Internal->LinkInterfaceMap.clear();
- this->Internal->LinkClosureMap.clear();
- for (cmTargetLinkInformationMap::const_iterator it
- = this->LinkInformation.begin();
- it != this->LinkInformation.end(); ++it)
+ if(this->Utilities.insert(u).second && makefile)
{
- delete it->second;
+ this->UtilityBacktraces.insert(
+ std::make_pair(u, makefile->GetBacktrace()));
}
- this->LinkInformation.clear();
}
//----------------------------------------------------------------------------
-cmListFileBacktrace const& cmTarget::GetBacktrace() const
+cmListFileBacktrace const* cmTarget::GetUtilityBacktrace(
+ const std::string& u) const
{
- return this->Internal->Backtrace;
-}
+ std::map<std::string, cmListFileBacktrace>::const_iterator i =
+ this->UtilityBacktraces.find(u);
+ if(i == this->UtilityBacktraces.end()) return 0;
-//----------------------------------------------------------------------------
-std::string cmTarget::GetSupportDirectory() const
-{
- std::string dir = this->Makefile->GetCurrentOutputDirectory();
- dir += cmake::GetCMakeFilesDirectory();
- dir += "/";
- dir += this->Name;
-#if defined(__VMS)
- dir += "_dir";
-#else
- dir += ".dir";
-#endif
- return dir;
+ return &i->second;
}
//----------------------------------------------------------------------------
-bool cmTarget::IsExecutableWithExports()
+cmListFileBacktrace const& cmTarget::GetBacktrace() const
{
- return (this->GetType() == cmTarget::EXECUTABLE &&
- this->GetPropertyAsBool("ENABLE_EXPORTS"));
+ return this->Backtrace;
}
//----------------------------------------------------------------------------
-bool cmTarget::IsLinkable()
+bool cmTarget::IsExecutableWithExports() const
{
- return (this->GetType() == cmTarget::STATIC_LIBRARY ||
- this->GetType() == cmTarget::SHARED_LIBRARY ||
- this->GetType() == cmTarget::MODULE_LIBRARY ||
- this->GetType() == cmTarget::UNKNOWN_LIBRARY ||
- this->IsExecutableWithExports());
+ return (this->GetType() == cmState::EXECUTABLE &&
+ this->GetPropertyAsBool("ENABLE_EXPORTS"));
}
//----------------------------------------------------------------------------
-bool cmTarget::HasImportLibrary()
+bool cmTarget::HasImportLibrary() const
{
return (this->DLLPlatform &&
- (this->GetType() == cmTarget::SHARED_LIBRARY ||
+ (this->GetType() == cmState::SHARED_LIBRARY ||
this->IsExecutableWithExports()));
}
//----------------------------------------------------------------------------
-bool cmTarget::IsFrameworkOnApple()
+bool cmTarget::IsFrameworkOnApple() const
{
- return (this->GetType() == cmTarget::SHARED_LIBRARY &&
+ return (this->GetType() == cmState::SHARED_LIBRARY &&
this->Makefile->IsOn("APPLE") &&
this->GetPropertyAsBool("FRAMEWORK"));
}
//----------------------------------------------------------------------------
-bool cmTarget::IsAppBundleOnApple()
+bool cmTarget::IsAppBundleOnApple() const
{
- return (this->GetType() == cmTarget::EXECUTABLE &&
+ return (this->GetType() == cmState::EXECUTABLE &&
this->Makefile->IsOn("APPLE") &&
this->GetPropertyAsBool("MACOSX_BUNDLE"));
}
//----------------------------------------------------------------------------
-bool cmTarget::IsCFBundleOnApple()
-{
- return (this->GetType() == cmTarget::MODULE_LIBRARY &&
- this->Makefile->IsOn("APPLE") &&
- this->GetPropertyAsBool("BUNDLE"));
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::IsBundleOnApple()
-{
- return this->IsFrameworkOnApple() || this->IsAppBundleOnApple() ||
- this->IsCFBundleOnApple();
-}
-
-//----------------------------------------------------------------------------
-class cmTargetTraceDependencies
-{
-public:
- cmTargetTraceDependencies(cmTarget* target, cmTargetInternals* internal);
- void Trace();
-private:
- cmTarget* Target;
- cmTargetInternals* Internal;
- cmMakefile* Makefile;
- cmGlobalGenerator* GlobalGenerator;
- typedef cmTargetInternals::SourceEntry SourceEntry;
- SourceEntry* CurrentEntry;
- std::queue<cmSourceFile*> SourceQueue;
- std::set<cmSourceFile*> SourcesQueued;
- typedef std::map<cmStdString, cmSourceFile*> NameMapType;
- NameMapType NameMap;
-
- void QueueSource(cmSourceFile* sf);
- void FollowName(std::string const& name);
- void FollowNames(std::vector<std::string> const& names);
- bool IsUtility(std::string const& dep);
- void CheckCustomCommand(cmCustomCommand const& cc);
- void CheckCustomCommands(const std::vector<cmCustomCommand>& commands);
-};
-
-//----------------------------------------------------------------------------
-cmTargetTraceDependencies
-::cmTargetTraceDependencies(cmTarget* target, cmTargetInternals* internal):
- Target(target), Internal(internal)
-{
- // Convenience.
- this->Makefile = this->Target->GetMakefile();
- this->GlobalGenerator =
- this->Makefile->GetLocalGenerator()->GetGlobalGenerator();
- this->CurrentEntry = 0;
-
- // Queue all the source files already specified for the target.
- std::vector<cmSourceFile*> const& sources = this->Target->GetSourceFiles();
- for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
- si != sources.end(); ++si)
- {
- this->QueueSource(*si);
- }
-
- // Queue pre-build, pre-link, and post-build rule dependencies.
- this->CheckCustomCommands(this->Target->GetPreBuildCommands());
- this->CheckCustomCommands(this->Target->GetPreLinkCommands());
- this->CheckCustomCommands(this->Target->GetPostBuildCommands());
-}
-
-//----------------------------------------------------------------------------
-void cmTargetTraceDependencies::Trace()
-{
- // Process one dependency at a time until the queue is empty.
- while(!this->SourceQueue.empty())
- {
- // Get the next source from the queue.
- cmSourceFile* sf = this->SourceQueue.front();
- this->SourceQueue.pop();
- this->CurrentEntry = &this->Internal->SourceEntries[sf];
-
- // Queue dependencies added explicitly by the user.
- if(const char* additionalDeps = sf->GetProperty("OBJECT_DEPENDS"))
- {
- std::vector<std::string> objDeps;
- cmSystemTools::ExpandListArgument(additionalDeps, objDeps);
- this->FollowNames(objDeps);
- }
-
- // Queue the source needed to generate this file, if any.
- this->FollowName(sf->GetFullPath());
-
- // Queue dependencies added programatically by commands.
- this->FollowNames(sf->GetDepends());
-
- // Queue custom command dependencies.
- if(cmCustomCommand const* cc = sf->GetCustomCommand())
- {
- this->CheckCustomCommand(*cc);
- }
- }
- this->CurrentEntry = 0;
-}
-
-//----------------------------------------------------------------------------
-void cmTargetTraceDependencies::QueueSource(cmSourceFile* sf)
+void cmTarget::AddTracedSources(std::vector<std::string> const& srcs)
{
- if(this->SourcesQueued.insert(sf).second)
+ if (!srcs.empty())
{
- this->SourceQueue.push(sf);
-
- // Make sure this file is in the target.
- this->Target->AddSourceFile(sf);
+ cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+ this->Internal->SourceEntries.push_back(cmJoin(srcs, ";"));
+ this->Internal->SourceBacktraces.push_back(lfbt);
}
}
//----------------------------------------------------------------------------
-void cmTargetTraceDependencies::FollowName(std::string const& name)
-{
- NameMapType::iterator i = this->NameMap.find(name);
- if(i == this->NameMap.end())
- {
- // Check if we know how to generate this file.
- cmSourceFile* sf = this->Makefile->GetSourceFileWithOutput(name.c_str());
- NameMapType::value_type entry(name, sf);
- i = this->NameMap.insert(entry).first;
- }
- if(cmSourceFile* sf = i->second)
- {
- // Record the dependency we just followed.
- if(this->CurrentEntry)
- {
- this->CurrentEntry->Depends.push_back(sf);
- }
-
- this->QueueSource(sf);
- }
-}
-
-//----------------------------------------------------------------------------
-void
-cmTargetTraceDependencies::FollowNames(std::vector<std::string> const& names)
-{
- for(std::vector<std::string>::const_iterator i = names.begin();
- i != names.end(); ++i)
- {
- this->FollowName(*i);
- }
-}
-
-//----------------------------------------------------------------------------
-bool cmTargetTraceDependencies::IsUtility(std::string const& dep)
+void cmTarget::AddSources(std::vector<std::string> const& srcs)
{
- // Dependencies on targets (utilities) are supposed to be named by
- // just the target name. However for compatibility we support
- // naming the output file generated by the target (assuming there is
- // no output-name property which old code would not have set). In
- // that case the target name will be the file basename of the
- // dependency.
- std::string util = cmSystemTools::GetFilenameName(dep);
- if(cmSystemTools::GetFilenameLastExtension(util) == ".exe")
+ std::string srcFiles;
+ const char* sep = "";
+ for(std::vector<std::string>::const_iterator i = srcs.begin();
+ i != srcs.end(); ++i)
{
- util = cmSystemTools::GetFilenameWithoutLastExtension(util);
- }
+ std::string filename = *i;
+ const char* src = filename.c_str();
- // Check for a target with this name.
- if(cmTarget* t = this->Makefile->FindTargetToUse(util.c_str()))
- {
- // If we find the target and the dep was given as a full path,
- // then make sure it was not a full path to something else, and
- // the fact that the name matched a target was just a coincidence.
- if(cmSystemTools::FileIsFullPath(dep.c_str()))
+ if(!(src[0] == '$' && src[1] == '<'))
{
- if(t->GetType() >= cmTarget::EXECUTABLE &&
- t->GetType() <= cmTarget::MODULE_LIBRARY)
+ if(!filename.empty())
{
- // This is really only for compatibility so we do not need to
- // worry about configuration names and output names.
- std::string tLocation = t->GetLocation(0);
- tLocation = cmSystemTools::GetFilenamePath(tLocation);
- std::string depLocation = cmSystemTools::GetFilenamePath(dep);
- depLocation = cmSystemTools::CollapseFullPath(depLocation.c_str());
- tLocation = cmSystemTools::CollapseFullPath(tLocation.c_str());
- if(depLocation == tLocation)
+ filename = this->ProcessSourceItemCMP0049(filename);
+ if(filename.empty())
{
- this->Target->AddUtility(util.c_str());
- return true;
+ return;
}
}
+ this->Makefile->GetOrCreateSource(filename);
}
- else
- {
- // The original name of the dependency was not a full path. It
- // must name a target, so add the target-level dependency.
- this->Target->AddUtility(util.c_str());
- return true;
- }
+ srcFiles += sep;
+ srcFiles += filename;
+ sep = ";";
+ }
+ if (!srcFiles.empty())
+ {
+ cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+ this->Internal->SourceEntries.push_back(srcFiles);
+ this->Internal->SourceBacktraces.push_back(lfbt);
}
-
- // The dependency does not name a target built in this project.
- return false;
}
//----------------------------------------------------------------------------
-void
-cmTargetTraceDependencies
-::CheckCustomCommand(cmCustomCommand const& cc)
+std::string cmTarget::ProcessSourceItemCMP0049(const std::string& s)
{
- // Transform command names that reference targets built in this
- // project to corresponding target-level dependencies.
- cmGeneratorExpression ge(cc.GetBacktrace());
-
- // Add target-level dependencies referenced by generator expressions.
- std::set<cmTarget*> targets;
+ std::string src = s;
- for(cmCustomCommandLines::const_iterator cit = cc.GetCommandLines().begin();
- cit != cc.GetCommandLines().end(); ++cit)
+ // For backwards compatibility replace varibles in source names.
+ // This should eventually be removed.
+ this->Makefile->ExpandVariablesInString(src);
+ if (src != s)
{
- std::string const& command = *cit->begin();
- // Check for a target with this name.
- if(cmTarget* t = this->Makefile->FindTargetToUse(command.c_str()))
+ std::ostringstream e;
+ bool noMessage = false;
+ cmake::MessageType messageType = cmake::AUTHOR_WARNING;
+ switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0049))
{
- if(t->GetType() == cmTarget::EXECUTABLE)
- {
- // The command refers to an executable target built in
- // this project. Add the target-level dependency to make
- // sure the executable is up to date before this custom
- // command possibly runs.
- this->Target->AddUtility(command.c_str());
- }
+ case cmPolicies::WARN:
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0049) << "\n";
+ break;
+ case cmPolicies::OLD:
+ noMessage = true;
+ break;
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::NEW:
+ messageType = cmake::FATAL_ERROR;
}
-
- // Check for target references in generator expressions.
- for(cmCustomCommandLine::const_iterator cli = cit->begin();
- cli != cit->end(); ++cli)
+ if (!noMessage)
{
- const cmsys::auto_ptr<cmCompiledGeneratorExpression> cge
- = ge.Parse(*cli);
- cge->Evaluate(this->Makefile, 0, true);
- std::set<cmTarget*> geTargets = cge->GetTargets();
- for(std::set<cmTarget*>::const_iterator it = geTargets.begin();
- it != geTargets.end(); ++it)
+ e << "Legacy variable expansion in source file \""
+ << s << "\" expanded to \"" << src << "\" in target \""
+ << this->GetName() << "\". This behavior will be removed in a "
+ "future version of CMake.";
+ this->Makefile->IssueMessage(messageType, e.str());
+ if (messageType == cmake::FATAL_ERROR)
{
- targets.insert(*it);
+ return "";
}
}
}
-
- for(std::set<cmTarget*>::iterator ti = targets.begin();
- ti != targets.end(); ++ti)
- {
- this->Target->AddUtility((*ti)->GetName());
- }
-
- // Queue the custom command dependencies.
- std::vector<std::string> const& depends = cc.GetDepends();
- for(std::vector<std::string>::const_iterator di = depends.begin();
- di != depends.end(); ++di)
- {
- std::string const& dep = *di;
- if(!this->IsUtility(dep))
- {
- // The dependency does not name a target and may be a file we
- // know how to generate. Queue it.
- this->FollowName(dep);
- }
- }
+ return src;
}
//----------------------------------------------------------------------------
-void
-cmTargetTraceDependencies
-::CheckCustomCommands(const std::vector<cmCustomCommand>& commands)
+cmSourceFile* cmTarget::AddSourceCMP0049(const std::string& s)
{
- for(std::vector<cmCustomCommand>::const_iterator cli = commands.begin();
- cli != commands.end(); ++cli)
+ std::string src = this->ProcessSourceItemCMP0049(s);
+ if(!s.empty() && src.empty())
{
- this->CheckCustomCommand(*cli);
+ return 0;
}
+ return this->AddSource(src);
}
//----------------------------------------------------------------------------
-void cmTarget::TraceDependencies()
+struct CreateLocation
{
- // CMake-generated targets have no dependencies to trace. Normally tracing
- // would find nothing anyway, but when building CMake itself the "install"
- // target command ends up referencing the "cmake" target but we do not
- // really want the dependency because "install" depend on "all" anyway.
- if(this->GetType() == cmTarget::GLOBAL_TARGET)
- {
- return;
- }
-
- // Use a helper object to trace the dependencies.
- cmTargetTraceDependencies tracer(this, this->Internal.Get());
- tracer.Trace();
-}
+ cmMakefile const* Makefile;
-//----------------------------------------------------------------------------
-bool cmTarget::FindSourceFiles()
-{
- for(std::vector<cmSourceFile*>::const_iterator
- si = this->SourceFiles.begin();
- si != this->SourceFiles.end(); ++si)
- {
- std::string e;
- if((*si)->GetFullPath(&e).empty())
- {
- if(!e.empty())
- {
- cmake* cm = this->Makefile->GetCMakeInstance();
- cm->IssueMessage(cmake::FATAL_ERROR, e,
- this->GetBacktrace());
- }
- return false;
- }
- }
- return true;
-}
+ CreateLocation(cmMakefile const* mf)
+ : Makefile(mf)
+ {
-//----------------------------------------------------------------------------
-std::vector<cmSourceFile*> const& cmTarget::GetSourceFiles()
-{
- return this->SourceFiles;
-}
+ }
-//----------------------------------------------------------------------------
-void cmTarget::AddSourceFile(cmSourceFile* sf)
-{
- typedef cmTargetInternals::SourceEntriesType SourceEntriesType;
- SourceEntriesType::iterator i = this->Internal->SourceEntries.find(sf);
- if(i == this->Internal->SourceEntries.end())
- {
- typedef cmTargetInternals::SourceEntry SourceEntry;
- SourceEntriesType::value_type entry(sf, SourceEntry());
- i = this->Internal->SourceEntries.insert(entry).first;
- this->SourceFiles.push_back(sf);
- }
-}
+ cmSourceFileLocation operator()(const std::string& filename)
+ {
+ return cmSourceFileLocation(this->Makefile, filename);
+ }
+};
//----------------------------------------------------------------------------
-std::vector<cmSourceFile*> const*
-cmTarget::GetSourceDepends(cmSourceFile* sf)
+struct LocationMatcher
{
- typedef cmTargetInternals::SourceEntriesType SourceEntriesType;
- SourceEntriesType::iterator i = this->Internal->SourceEntries.find(sf);
- if(i != this->Internal->SourceEntries.end())
- {
- return &i->second.Depends;
- }
- return 0;
-}
+ const cmSourceFileLocation& Needle;
-//----------------------------------------------------------------------------
-void cmTarget::AddSources(std::vector<std::string> const& srcs)
-{
- for(std::vector<std::string>::const_iterator i = srcs.begin();
- i != srcs.end(); ++i)
- {
- const char* src = i->c_str();
- if(src[0] == '$' && src[1] == '<')
- {
- this->ProcessSourceExpression(*i);
- }
- else
- {
- this->AddSource(src);
- }
- }
-}
+ LocationMatcher(const cmSourceFileLocation& needle)
+ : Needle(needle)
+ {
-//----------------------------------------------------------------------------
-cmSourceFile* cmTarget::AddSource(const char* s)
-{
- std::string src = s;
+ }
- // For backwards compatibility replace varibles in source names.
- // This should eventually be removed.
- this->Makefile->ExpandVariablesInString(src);
+ bool operator()(cmSourceFileLocation &loc)
+ {
+ return loc.Matches(this->Needle);
+ }
+};
- cmSourceFile* sf = this->Makefile->GetOrCreateSource(src.c_str());
- this->AddSourceFile(sf);
- return sf;
-}
//----------------------------------------------------------------------------
-void cmTarget::ProcessSourceExpression(std::string const& expr)
+struct TargetPropertyEntryFinder
{
- if(strncmp(expr.c_str(), "$<TARGET_OBJECTS:", 17) == 0 &&
- expr[expr.size()-1] == '>')
- {
- std::string objLibName = expr.substr(17, expr.size()-18);
- this->ObjectLibraries.push_back(objLibName);
- }
- else
- {
- cmOStringStream e;
- e << "Unrecognized generator expression:\n"
- << " " << expr;
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
- }
-}
+private:
+ const cmSourceFileLocation& Needle;
+public:
+ TargetPropertyEntryFinder(const cmSourceFileLocation& needle)
+ : Needle(needle)
+ {
-//----------------------------------------------------------------------------
-struct cmTarget::SourceFileFlags
-cmTarget::GetTargetSourceFileFlags(const cmSourceFile* sf)
-{
- struct SourceFileFlags flags;
- this->ConstructSourceFileFlags();
- std::map<cmSourceFile const*, SourceFileFlags>::iterator si =
- this->Internal->SourceFlagsMap.find(sf);
- if(si != this->Internal->SourceFlagsMap.end())
- {
- flags = si->second;
- }
- return flags;
-}
+ }
+
+ bool operator()(std::string const& entry)
+ {
+ std::vector<std::string> files;
+ cmSystemTools::ExpandListArgument(entry, files);
+ std::vector<cmSourceFileLocation> locations(files.size());
+ std::transform(files.begin(), files.end(), locations.begin(),
+ CreateLocation(this->Needle.GetMakefile()));
+
+ return std::find_if(locations.begin(), locations.end(),
+ LocationMatcher(this->Needle)) != locations.end();
+ }
+};
//----------------------------------------------------------------------------
-void cmTarget::ConstructSourceFileFlags()
+cmSourceFile* cmTarget::AddSource(const std::string& src)
{
- if(this->Internal->SourceFileFlagsConstructed)
+ cmSourceFileLocation sfl(this->Makefile, src);
+ if (std::find_if(this->Internal->SourceEntries.begin(),
+ this->Internal->SourceEntries.end(),
+ TargetPropertyEntryFinder(sfl))
+ == this->Internal->SourceEntries.end())
{
- return;
+ cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+ this->Internal->SourceEntries.push_back(src);
+ this->Internal->SourceBacktraces.push_back(lfbt);
}
- this->Internal->SourceFileFlagsConstructed = true;
-
- // Process public headers to mark the source files.
- if(const char* files = this->GetProperty("PUBLIC_HEADER"))
+ if (cmGeneratorExpression::Find(src) != std::string::npos)
{
- std::vector<std::string> relFiles;
- cmSystemTools::ExpandListArgument(files, relFiles);
- for(std::vector<std::string>::iterator it = relFiles.begin();
- it != relFiles.end(); ++it)
- {
- if(cmSourceFile* sf = this->Makefile->GetSource(it->c_str()))
- {
- SourceFileFlags& flags = this->Internal->SourceFlagsMap[sf];
- flags.MacFolder = "Headers";
- flags.Type = cmTarget::SourceFileTypePublicHeader;
- }
- }
- }
-
- // Process private headers after public headers so that they take
- // precedence if a file is listed in both.
- if(const char* files = this->GetProperty("PRIVATE_HEADER"))
- {
- std::vector<std::string> relFiles;
- cmSystemTools::ExpandListArgument(files, relFiles);
- for(std::vector<std::string>::iterator it = relFiles.begin();
- it != relFiles.end(); ++it)
- {
- if(cmSourceFile* sf = this->Makefile->GetSource(it->c_str()))
- {
- SourceFileFlags& flags = this->Internal->SourceFlagsMap[sf];
- flags.MacFolder = "PrivateHeaders";
- flags.Type = cmTarget::SourceFileTypePrivateHeader;
- }
- }
- }
-
- // Mark sources listed as resources.
- if(const char* files = this->GetProperty("RESOURCE"))
- {
- std::vector<std::string> relFiles;
- cmSystemTools::ExpandListArgument(files, relFiles);
- for(std::vector<std::string>::iterator it = relFiles.begin();
- it != relFiles.end(); ++it)
- {
- if(cmSourceFile* sf = this->Makefile->GetSource(it->c_str()))
- {
- SourceFileFlags& flags = this->Internal->SourceFlagsMap[sf];
- flags.MacFolder = "Resources";
- flags.Type = cmTarget::SourceFileTypeResource;
- }
- }
- }
-
- // Handle the MACOSX_PACKAGE_LOCATION property on source files that
- // were not listed in one of the other lists.
- std::vector<cmSourceFile*> const& sources = this->GetSourceFiles();
- for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
- si != sources.end(); ++si)
- {
- cmSourceFile* sf = *si;
- if(const char* location = sf->GetProperty("MACOSX_PACKAGE_LOCATION"))
- {
- SourceFileFlags& flags = this->Internal->SourceFlagsMap[sf];
- if(flags.Type == cmTarget::SourceFileTypeNormal)
- {
- flags.MacFolder = location;
- if(strcmp(location, "Resources") == 0)
- {
- flags.Type = cmTarget::SourceFileTypeResource;
- }
- else
- {
- flags.Type = cmTarget::SourceFileTypeMacContent;
- }
- }
- }
+ return 0;
}
+ return this->Makefile->GetOrCreateSource(src);
}
//----------------------------------------------------------------------------
void cmTarget::MergeLinkLibraries( cmMakefile& mf,
- const char *selfname,
+ const std::string& selfname,
const LinkLibraryVectorType& libs )
{
// Only add on libraries we haven't added on before.
@@ -2335,15 +541,15 @@ void cmTarget::MergeLinkLibraries( cmMakefile& mf,
for( ; i != libs.end(); ++i )
{
// This is equivalent to the target_link_libraries plain signature.
- this->AddLinkLibrary( mf, selfname, i->first.c_str(), i->second );
+ this->AddLinkLibrary( mf, selfname, i->first, i->second );
this->AppendProperty("INTERFACE_LINK_LIBRARIES",
- this->GetDebugGeneratorExpressions(i->first.c_str(), i->second).c_str());
+ this->GetDebugGeneratorExpressions(i->first, i->second).c_str());
}
this->PrevLinkedLibraries = libs;
}
//----------------------------------------------------------------------------
-void cmTarget::AddLinkDirectory(const char* d)
+void cmTarget::AddLinkDirectory(const std::string& d)
{
// Make sure we don't add unnecessary search directories.
if(this->LinkDirectoriesEmmitted.insert(d).second)
@@ -2353,42 +559,14 @@ void cmTarget::AddLinkDirectory(const char* d)
}
//----------------------------------------------------------------------------
-const std::vector<std::string>& cmTarget::GetLinkDirectories()
+const std::vector<std::string>& cmTarget::GetLinkDirectories() const
{
return this->LinkDirectories;
}
//----------------------------------------------------------------------------
-cmTarget::LinkLibraryType cmTarget::ComputeLinkType(const char* config)
-{
- // No configuration is always optimized.
- if(!(config && *config))
- {
- return cmTarget::OPTIMIZED;
- }
-
- // Get the list of configurations considered to be DEBUG.
- std::vector<std::string> const& debugConfigs =
- this->Makefile->GetCMakeInstance()->GetDebugConfigs();
-
- // Check if any entry in the list matches this configuration.
- std::string configUpper = cmSystemTools::UpperCase(config);
- for(std::vector<std::string>::const_iterator i = debugConfigs.begin();
- i != debugConfigs.end(); ++i)
- {
- if(*i == configUpper)
- {
- return cmTarget::DEBUG;
- }
- }
-
- // The current configuration is not a debug configuration.
- return cmTarget::OPTIMIZED;
-}
-
-//----------------------------------------------------------------------------
void cmTarget::ClearDependencyInformation( cmMakefile& mf,
- const char* target )
+ const std::string& target )
{
// Clear the dependencies. The cache variable must exist iff we are
// recording dependency information for this target.
@@ -2396,12 +574,12 @@ void cmTarget::ClearDependencyInformation( cmMakefile& mf,
depname += "_LIB_DEPENDS";
if (this->RecordDependencies)
{
- mf.AddCacheDefinition(depname.c_str(), "",
- "Dependencies for target", cmCacheManager::STATIC);
+ mf.AddCacheDefinition(depname, "",
+ "Dependencies for target", cmState::STATIC);
}
else
{
- if (mf.GetDefinition( depname.c_str() ))
+ if (mf.GetDefinition( depname ))
{
std::string message = "Target ";
message += target;
@@ -2415,56 +593,16 @@ void cmTarget::ClearDependencyInformation( cmMakefile& mf,
}
//----------------------------------------------------------------------------
-bool cmTarget::NameResolvesToFramework(const std::string& libname)
-{
- return this->GetMakefile()->GetLocalGenerator()->GetGlobalGenerator()->
- NameResolvesToFramework(libname);
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GetDirectLinkLibraries(const char *config,
- std::vector<std::string> &libs, cmTarget *head)
-{
- const char *prop = this->GetProperty("LINK_LIBRARIES");
- if (prop)
- {
- cmListFileBacktrace lfbt;
- cmGeneratorExpression ge(lfbt);
- const cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
-
- cmGeneratorExpressionDAGChecker dagChecker(lfbt,
- this->GetName(),
- "LINK_LIBRARIES", 0, 0);
- cmSystemTools::ExpandListArgument(cge->Evaluate(this->Makefile,
- config,
- false,
- head,
- &dagChecker),
- libs);
-
- std::set<cmStdString> seenProps = cge->GetSeenTargetProperties();
- for (std::set<cmStdString>::const_iterator it = seenProps.begin();
- it != seenProps.end(); ++it)
- {
- if (!this->GetProperty(it->c_str()))
- {
- this->LinkImplicitNullProperties.insert(*it);
- }
- }
- }
-}
-
-//----------------------------------------------------------------------------
std::string cmTarget::GetDebugGeneratorExpressions(const std::string &value,
- cmTarget::LinkLibraryType llt)
+ cmTargetLinkLibraryType llt) const
{
- if (llt == GENERAL)
+ if (llt == GENERAL_LibraryType)
{
return value;
}
// Get the list of configurations considered to be DEBUG.
- std::vector<std::string> const& debugConfigs =
+ std::vector<std::string> debugConfigs =
this->Makefile->GetCMakeInstance()->GetDebugConfigs();
std::string configString = "$<CONFIG:" + debugConfigs[0] + ">";
@@ -2479,7 +617,7 @@ std::string cmTarget::GetDebugGeneratorExpressions(const std::string &value,
configString = "$<OR:" + configString + ">";
}
- if (llt == OPTIMIZED)
+ if (llt == OPTIMIZED_LibraryType)
{
configString = "$<NOT:" + configString + ">";
}
@@ -2487,13 +625,14 @@ std::string cmTarget::GetDebugGeneratorExpressions(const std::string &value,
}
//----------------------------------------------------------------------------
-static std::string targetNameGenex(const char *lib)
+static std::string targetNameGenex(const std::string& lib)
{
- return std::string("$<TARGET_NAME:") + lib + ">";
+ return "$<TARGET_NAME:" + lib + ">";
}
//----------------------------------------------------------------------------
-bool cmTarget::PushTLLCommandTrace(TLLSignature signature)
+bool cmTarget::PushTLLCommandTrace(TLLSignature signature,
+ cmListFileContext const& lfc)
{
bool ret = true;
if (!this->TLLCommands.empty())
@@ -2503,76 +642,56 @@ bool cmTarget::PushTLLCommandTrace(TLLSignature signature)
ret = false;
}
}
- cmListFileBacktrace lfbt;
- this->Makefile->GetBacktrace(lfbt);
- this->TLLCommands.push_back(std::make_pair(signature, lfbt));
+ if (this->TLLCommands.empty() || this->TLLCommands.back().second != lfc)
+ {
+ this->TLLCommands.push_back(std::make_pair(signature, lfc));
+ }
return ret;
}
//----------------------------------------------------------------------------
-void cmTarget::GetTllSignatureTraces(cmOStringStream &s,
+void cmTarget::GetTllSignatureTraces(std::ostringstream &s,
TLLSignature sig) const
{
- std::vector<cmListFileBacktrace> sigs;
- typedef std::vector<std::pair<TLLSignature, cmListFileBacktrace> > Container;
+ const char *sigString = (sig == cmTarget::KeywordTLLSignature ? "keyword"
+ : "plain");
+ s << "The uses of the " << sigString << " signature are here:\n";
+ typedef std::vector<std::pair<TLLSignature, cmListFileContext> > Container;
+ cmOutputConverter converter(this->GetMakefile()->GetStateSnapshot());
for(Container::const_iterator it = this->TLLCommands.begin();
it != this->TLLCommands.end(); ++it)
{
if (it->first == sig)
{
- sigs.push_back(it->second);
- }
- }
- if (!sigs.empty())
- {
- const char *sigString
- = (sig == cmTarget::KeywordTLLSignature ? "keyword"
- : "plain");
- s << "The uses of the " << sigString << " signature are here:\n";
- std::set<cmStdString> emitted;
- for(std::vector<cmListFileBacktrace>::const_iterator it = sigs.begin();
- it != sigs.end(); ++it)
- {
- cmListFileBacktrace::const_iterator i = it->begin();
- if(i != it->end())
- {
- cmListFileContext const& lfc = *i;
- cmOStringStream line;
- line << " * " << (lfc.Line? "": " in ") << lfc << std::endl;
- if (emitted.insert(line.str()).second)
- {
- s << line.str();
- }
- ++i;
- }
+ cmListFileContext lfc = it->second;
+ lfc.FilePath = converter.Convert(lfc.FilePath, cmOutputConverter::HOME);
+ s << " * " << lfc << std::endl;
}
}
}
//----------------------------------------------------------------------------
void cmTarget::AddLinkLibrary(cmMakefile& mf,
- const char *target, const char* lib,
- LinkLibraryType llt)
+ const std::string& target,
+ const std::string& lib,
+ cmTargetLinkLibraryType llt)
{
- // Never add a self dependency, even if the user asks for it.
- if(strcmp( target, lib ) == 0)
- {
- return;
- }
-
- {
cmTarget *tgt = this->Makefile->FindTargetToUse(lib);
+ {
const bool isNonImportedTarget = tgt && !tgt->IsImported();
- const std::string libName = (isNonImportedTarget && llt != GENERAL)
- ? targetNameGenex(lib)
- : std::string(lib);
+ const std::string libName =
+ (isNonImportedTarget && llt != GENERAL_LibraryType)
+ ? targetNameGenex(lib)
+ : lib;
this->AppendProperty("LINK_LIBRARIES",
this->GetDebugGeneratorExpressions(libName,
llt).c_str());
}
- if (cmGeneratorExpression::Find(lib) != std::string::npos)
+ if (cmGeneratorExpression::Find(lib) != std::string::npos
+ || (tgt && tgt->GetType() == cmState::INTERFACE_LIBRARY)
+ || (target == lib ))
{
return;
}
@@ -2580,9 +699,10 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf,
cmTarget::LibraryID tmp;
tmp.first = lib;
tmp.second = llt;
- this->LinkLibraries.push_back( tmp );
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ this->LinkLibrariesForVS6.push_back( tmp );
+#endif
this->OriginalLinkLibraries.push_back(tmp);
- this->ClearLinkMaps();
// Add the explicit dependency information for this target. This is
// simply a set of libraries separated by ";". There should always
@@ -2597,91 +717,104 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf,
std::string targetEntry = target;
targetEntry += "_LIB_DEPENDS";
std::string dependencies;
- const char* old_val = mf.GetDefinition( targetEntry.c_str() );
+ const char* old_val = mf.GetDefinition( targetEntry );
if( old_val )
{
dependencies += old_val;
}
switch (llt)
{
- case cmTarget::GENERAL:
+ case GENERAL_LibraryType:
dependencies += "general";
break;
- case cmTarget::DEBUG:
+ case DEBUG_LibraryType:
dependencies += "debug";
break;
- case cmTarget::OPTIMIZED:
+ case OPTIMIZED_LibraryType:
dependencies += "optimized";
break;
}
dependencies += ";";
dependencies += lib;
dependencies += ";";
- mf.AddCacheDefinition( targetEntry.c_str(), dependencies.c_str(),
+ mf.AddCacheDefinition( targetEntry, dependencies.c_str(),
"Dependencies for the target",
- cmCacheManager::STATIC );
+ cmState::STATIC );
}
}
//----------------------------------------------------------------------------
void
-cmTarget::AddSystemIncludeDirectories(const std::set<cmStdString> &incs)
+cmTarget::AddSystemIncludeDirectories(const std::set<std::string> &incs)
{
- for(std::set<cmStdString>::const_iterator li = incs.begin();
- li != incs.end(); ++li)
- {
- this->SystemIncludeDirectories.insert(*li);
- }
+ this->SystemIncludeDirectories.insert(incs.begin(), incs.end());
}
-//----------------------------------------------------------------------------
-void
-cmTarget::AddSystemIncludeDirectories(const std::vector<std::string> &incs)
+cmStringRange cmTarget::GetIncludeDirectoriesEntries() const
{
- for(std::vector<std::string>::const_iterator li = incs.begin();
- li != incs.end(); ++li)
- {
- this->SystemIncludeDirectories.insert(*li);
- }
+ return cmMakeRange(this->Internal->IncludeDirectoriesEntries);
}
-//----------------------------------------------------------------------------
-void cmTarget::FinalizeSystemIncludeDirectories()
+cmBacktraceRange cmTarget::GetIncludeDirectoriesBacktraces() const
{
- for (std::vector<cmValueWithOrigin>::const_iterator
- it = this->Internal->LinkInterfacePropertyEntries.begin(),
- end = this->Internal->LinkInterfacePropertyEntries.end();
- it != end; ++it)
- {
- {
- cmListFileBacktrace lfbt;
- cmGeneratorExpression ge(lfbt);
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(it->Value);
- std::string targetName = cge->Evaluate(this->Makefile, 0,
- false, this, 0, 0);
- if (!this->Makefile->FindTargetToUse(targetName.c_str()))
- {
- continue;
- }
- }
- std::string includeGenex = "$<TARGET_PROPERTY:" +
- it->Value + ",INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>";
- if (cmGeneratorExpression::Find(it->Value) != std::string::npos)
- {
- // Because it->Value is a generator expression, ensure that it
- // evaluates to the non-empty string before being used in the
- // TARGET_PROPERTY expression.
- includeGenex = "$<$<BOOL:" + it->Value + ">:" + includeGenex + ">";
- }
- this->SystemIncludeDirectories.insert(includeGenex);
- }
+ return cmMakeRange(this->Internal->IncludeDirectoriesBacktraces);
}
+cmStringRange cmTarget::GetCompileOptionsEntries() const
+{
+ return cmMakeRange(this->Internal->CompileOptionsEntries);
+}
+
+cmBacktraceRange cmTarget::GetCompileOptionsBacktraces() const
+{
+ return cmMakeRange(this->Internal->CompileOptionsBacktraces);
+}
+
+cmStringRange cmTarget::GetCompileFeaturesEntries() const
+{
+ return cmMakeRange(this->Internal->CompileFeaturesEntries);
+}
+
+cmBacktraceRange cmTarget::GetCompileFeaturesBacktraces() const
+{
+ return cmMakeRange(this->Internal->CompileFeaturesBacktraces);
+}
+
+cmStringRange cmTarget::GetCompileDefinitionsEntries() const
+{
+ return cmMakeRange(this->Internal->CompileDefinitionsEntries);
+}
+
+cmBacktraceRange cmTarget::GetCompileDefinitionsBacktraces() const
+{
+ return cmMakeRange(this->Internal->CompileDefinitionsBacktraces);
+}
+
+cmStringRange cmTarget::GetSourceEntries() const
+{
+ return cmMakeRange(this->Internal->SourceEntries);
+}
+
+cmBacktraceRange cmTarget::GetSourceBacktraces() const
+{
+ return cmMakeRange(this->Internal->SourceBacktraces);
+}
+
+cmStringRange cmTarget::GetLinkImplementationEntries() const
+{
+ return cmMakeRange(this->Internal->LinkImplementationPropertyEntries);
+}
+
+cmBacktraceRange cmTarget::GetLinkImplementationBacktraces() const
+{
+ return cmMakeRange(this->Internal->LinkImplementationPropertyBacktraces);
+}
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
//----------------------------------------------------------------------------
void
-cmTarget::AnalyzeLibDependencies( const cmMakefile& mf )
+cmTarget::AnalyzeLibDependenciesForVS6( const cmMakefile& mf )
{
// There are two key parts of the dependency analysis: (1)
// determining the libraries in the link line, and (2) constructing
@@ -2758,8 +891,8 @@ cmTarget::AnalyzeLibDependencies( const cmMakefile& mf )
// eventually be removed. This code was moved here from the end of
// old source list processing code which was called just before this
// method.
- for(LinkLibraryVectorType::iterator p = this->LinkLibraries.begin();
- p != this->LinkLibraries.end(); ++p)
+ for(LinkLibraryVectorType::iterator p = this->LinkLibrariesForVS6.begin();
+ p != this->LinkLibrariesForVS6.end(); ++p)
{
this->Makefile->ExpandVariablesInString(p->first, true, true);
}
@@ -2771,22 +904,22 @@ cmTarget::AnalyzeLibDependencies( const cmMakefile& mf )
// 1. Build the dependency graph
//
for(LinkLibraryVectorType::reverse_iterator lib
- = this->LinkLibraries.rbegin();
- lib != this->LinkLibraries.rend(); ++lib)
+ = this->LinkLibrariesForVS6.rbegin();
+ lib != this->LinkLibrariesForVS6.rend(); ++lib)
{
- this->GatherDependencies( mf, *lib, dep_map);
+ this->GatherDependenciesForVS6( mf, *lib, dep_map);
}
// 2. Remove any dependencies that are already satisfied in the original
// link line.
//
- for(LinkLibraryVectorType::iterator lib = this->LinkLibraries.begin();
- lib != this->LinkLibraries.end(); ++lib)
+ for(LinkLibraryVectorType::iterator lib = this->LinkLibrariesForVS6.begin();
+ lib != this->LinkLibrariesForVS6.end(); ++lib)
{
for( LinkLibraryVectorType::iterator lib2 = lib;
- lib2 != this->LinkLibraries.end(); ++lib2)
+ lib2 != this->LinkLibrariesForVS6.end(); ++lib2)
{
- this->DeleteDependency( dep_map, *lib, *lib2);
+ this->DeleteDependencyForVS6( dep_map, *lib, *lib2);
}
}
@@ -2795,43 +928,43 @@ cmTarget::AnalyzeLibDependencies( const cmMakefile& mf )
// missing. Start from the back and keep adding.
//
std::set<DependencyMap::key_type> done, visited;
- std::vector<DependencyMap::key_type> newLinkLibraries;
+ std::vector<DependencyMap::key_type> newLinkLibrariesForVS6;
for(LinkLibraryVectorType::reverse_iterator lib =
- this->LinkLibraries.rbegin();
- lib != this->LinkLibraries.rend(); ++lib)
+ this->LinkLibrariesForVS6.rbegin();
+ lib != this->LinkLibrariesForVS6.rend(); ++lib)
{
// skip zero size library entries, this may happen
// if a variable expands to nothing.
- if (lib->first.size() != 0)
+ if (!lib->first.empty())
{
- this->Emit( *lib, dep_map, done, visited, newLinkLibraries );
+ this->EmitForVS6( *lib, dep_map, done, visited, newLinkLibrariesForVS6 );
}
}
// 4. Add the new libraries to the link line.
//
for( std::vector<DependencyMap::key_type>::reverse_iterator k =
- newLinkLibraries.rbegin();
- k != newLinkLibraries.rend(); ++k )
+ newLinkLibrariesForVS6.rbegin();
+ k != newLinkLibrariesForVS6.rend(); ++k )
{
// get the llt from the dep_map
- this->LinkLibraries.push_back( std::make_pair(k->first,k->second) );
+ this->LinkLibrariesForVS6.push_back( std::make_pair(k->first,k->second) );
}
- this->LinkLibrariesAnalyzed = true;
+ this->LinkLibrariesForVS6Analyzed = true;
}
//----------------------------------------------------------------------------
-void cmTarget::InsertDependency( DependencyMap& depMap,
- const LibraryID& lib,
- const LibraryID& dep)
+void cmTarget::InsertDependencyForVS6( DependencyMap& depMap,
+ const LibraryID& lib,
+ const LibraryID& dep)
{
depMap[lib].push_back(dep);
}
//----------------------------------------------------------------------------
-void cmTarget::DeleteDependency( DependencyMap& depMap,
- const LibraryID& lib,
- const LibraryID& dep)
+void cmTarget::DeleteDependencyForVS6( DependencyMap& depMap,
+ const LibraryID& lib,
+ const LibraryID& dep)
{
// Make sure there is an entry in the map for lib. If so, delete all
// dependencies to dep. There may be repeated entries because of
@@ -2840,21 +973,18 @@ void cmTarget::DeleteDependency( DependencyMap& depMap,
if( map_itr != depMap.end() )
{
DependencyList& depList = map_itr->second;
- DependencyList::iterator itr;
- while( (itr = std::find(depList.begin(), depList.end(), dep)) !=
- depList.end() )
- {
- depList.erase( itr );
- }
+ DependencyList::iterator begin =
+ std::remove(depList.begin(), depList.end(), dep);
+ depList.erase(begin, depList.end());
}
}
//----------------------------------------------------------------------------
-void cmTarget::Emit(const LibraryID lib,
- const DependencyMap& dep_map,
- std::set<LibraryID>& emitted,
- std::set<LibraryID>& visited,
- DependencyList& link_line )
+void cmTarget::EmitForVS6(const LibraryID lib,
+ const DependencyMap& dep_map,
+ std::set<LibraryID>& emitted,
+ std::set<LibraryID>& visited,
+ DependencyList& link_line )
{
// It's already been emitted
if( emitted.find(lib) != emitted.end() )
@@ -2900,7 +1030,7 @@ void cmTarget::Emit(const LibraryID lib,
if( emitted.find(*i) == emitted.end() )
{
// emit dependencies
- Emit( *i, dep_map, emitted, visited, link_line );
+ this->EmitForVS6( *i, dep_map, emitted, visited, link_line );
// emit self
emitted.insert(*i);
emitted_here.insert(*i);
@@ -2913,9 +1043,9 @@ void cmTarget::Emit(const LibraryID lib,
}
//----------------------------------------------------------------------------
-void cmTarget::GatherDependencies( const cmMakefile& mf,
- const LibraryID& lib,
- DependencyMap& dep_map)
+void cmTarget::GatherDependenciesForVS6( const cmMakefile& mf,
+ const LibraryID& lib,
+ DependencyMap& dep_map)
{
// If the library is already in the dependency map, then it has
// already been fully processed.
@@ -2924,7 +1054,7 @@ void cmTarget::GatherDependencies( const cmMakefile& mf,
return;
}
- const char* deps = mf.GetDefinition( (lib.first+"_LIB_DEPENDS").c_str() );
+ const char* deps = mf.GetDefinition( lib.first+"_LIB_DEPENDS" );
if( deps && strcmp(deps,"") != 0 )
{
// Make sure this library is in the map, even if it has an empty
@@ -2934,7 +1064,7 @@ void cmTarget::GatherDependencies( const cmMakefile& mf,
// Parse the dependency information, which is a set of
// type, library pairs separated by ";". There is always a trailing ";".
- cmTarget::LinkLibraryType llt = cmTarget::GENERAL;
+ cmTargetLinkLibraryType llt = GENERAL_LibraryType;
std::string depline = deps;
std::string::size_type start = 0;
std::string::size_type end;
@@ -2942,838 +1072,347 @@ void cmTarget::GatherDependencies( const cmMakefile& mf,
while( end != std::string::npos )
{
std::string l = depline.substr( start, end-start );
- if( l.size() != 0 )
+ if(!l.empty())
{
if (l == "debug")
{
- llt = cmTarget::DEBUG;
+ llt = DEBUG_LibraryType;
}
else if (l == "optimized")
{
- llt = cmTarget::OPTIMIZED;
+ llt = OPTIMIZED_LibraryType;
}
else if (l == "general")
{
- llt = cmTarget::GENERAL;
+ llt = GENERAL_LibraryType;
}
else
{
LibraryID lib2(l,llt);
- this->InsertDependency( dep_map, lib, lib2);
- this->GatherDependencies( mf, lib2, dep_map);
- llt = cmTarget::GENERAL;
+ this->InsertDependencyForVS6( dep_map, lib, lib2);
+ this->GatherDependenciesForVS6( mf, lib2, dep_map);
+ llt = GENERAL_LibraryType;
}
}
start = end+1; // skip the ;
end = depline.find( ";", start );
}
// cannot depend on itself
- this->DeleteDependency( dep_map, lib, lib);
+ this->DeleteDependencyForVS6( dep_map, lib, lib);
}
}
+#endif
//----------------------------------------------------------------------------
-void cmTarget::SetProperty(const char* prop, const char* value)
+static bool whiteListedInterfaceProperty(const std::string& prop)
{
- if (!prop)
- {
- return;
- }
- if (strcmp(prop, "NAME") == 0)
+ if(cmHasLiteralPrefix(prop, "INTERFACE_"))
{
- cmOStringStream e;
- e << "NAME property is read-only\n";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
- return;
- }
- if(strcmp(prop,"INCLUDE_DIRECTORIES") == 0)
- {
- cmListFileBacktrace lfbt;
- this->Makefile->GetBacktrace(lfbt);
- cmGeneratorExpression ge(lfbt);
- deleteAndClear(this->Internal->IncludeDirectoriesEntries);
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
- this->Internal->IncludeDirectoriesEntries.push_back(
- new cmTargetInternals::TargetPropertyEntry(cge));
- return;
- }
- if(strcmp(prop,"COMPILE_OPTIONS") == 0)
- {
- cmListFileBacktrace lfbt;
- this->Makefile->GetBacktrace(lfbt);
- cmGeneratorExpression ge(lfbt);
- deleteAndClear(this->Internal->CompileOptionsEntries);
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
- this->Internal->CompileOptionsEntries.push_back(
- new cmTargetInternals::TargetPropertyEntry(cge));
- return;
+ return true;
}
- if(strcmp(prop,"COMPILE_DEFINITIONS") == 0)
+ static UNORDERED_SET<std::string> builtIns;
+ if (builtIns.empty())
{
- cmListFileBacktrace lfbt;
- this->Makefile->GetBacktrace(lfbt);
- cmGeneratorExpression ge(lfbt);
- deleteAndClear(this->Internal->CompileDefinitionsEntries);
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
- this->Internal->CompileDefinitionsEntries.push_back(
- new cmTargetInternals::TargetPropertyEntry(cge));
- return;
+ builtIns.insert("COMPATIBLE_INTERFACE_BOOL");
+ builtIns.insert("COMPATIBLE_INTERFACE_NUMBER_MAX");
+ builtIns.insert("COMPATIBLE_INTERFACE_NUMBER_MIN");
+ builtIns.insert("COMPATIBLE_INTERFACE_STRING");
+ builtIns.insert("EXPORT_NAME");
+ builtIns.insert("IMPORTED");
+ builtIns.insert("NAME");
+ builtIns.insert("TYPE");
}
- if(strcmp(prop,"EXPORT_NAME") == 0 && this->IsImported())
+
+ if (builtIns.count(prop))
{
- cmOStringStream e;
- e << "EXPORT_NAME property can't be set on imported targets (\""
- << this->Name << "\")\n";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
- return;
+ return true;
}
- if (strcmp(prop, "LINK_LIBRARIES") == 0)
+
+ if (cmHasLiteralPrefix(prop, "MAP_IMPORTED_CONFIG_"))
{
- this->Internal->LinkInterfacePropertyEntries.clear();
- if (cmGeneratorExpression::IsValidTargetName(value)
- || cmGeneratorExpression::Find(value) != std::string::npos)
- {
- cmListFileBacktrace lfbt;
- this->Makefile->GetBacktrace(lfbt);
- cmValueWithOrigin entry(value, lfbt);
- this->Internal->LinkInterfacePropertyEntries.push_back(entry);
- }
- // Fall through
+ return true;
}
- this->Properties.SetProperty(prop, value, cmProperty::TARGET);
- this->MaybeInvalidatePropertyCache(prop);
+
+ return false;
}
//----------------------------------------------------------------------------
-void cmTarget::AppendProperty(const char* prop, const char* value,
- bool asString)
+void cmTarget::SetProperty(const std::string& prop, const char* value)
{
- if (!prop)
+ if (this->GetType() == cmState::INTERFACE_LIBRARY
+ && !whiteListedInterfaceProperty(prop))
{
+ std::ostringstream e;
+ e << "INTERFACE_LIBRARY targets may only have whitelisted properties. "
+ "The property \"" << prop << "\" is not allowed.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
- if (strcmp(prop, "NAME") == 0)
+ else if (prop == "NAME")
{
- cmOStringStream e;
+ std::ostringstream e;
e << "NAME property is read-only\n";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
- if(strcmp(prop,"INCLUDE_DIRECTORIES") == 0)
+ else if(prop == "INCLUDE_DIRECTORIES")
{
- cmListFileBacktrace lfbt;
- this->Makefile->GetBacktrace(lfbt);
- cmGeneratorExpression ge(lfbt);
- this->Internal->IncludeDirectoriesEntries.push_back(
- new cmTargetInternals::TargetPropertyEntry(ge.Parse(value)));
- return;
+ this->Internal->IncludeDirectoriesEntries.clear();
+ this->Internal->IncludeDirectoriesBacktraces.clear();
+ if (value)
+ {
+ this->Internal->IncludeDirectoriesEntries.push_back(value);
+ cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+ this->Internal->IncludeDirectoriesBacktraces.push_back(lfbt);
+ }
}
- if(strcmp(prop,"COMPILE_OPTIONS") == 0)
+ else if(prop == "COMPILE_OPTIONS")
{
- cmListFileBacktrace lfbt;
- this->Makefile->GetBacktrace(lfbt);
- cmGeneratorExpression ge(lfbt);
- this->Internal->CompileOptionsEntries.push_back(
- new cmTargetInternals::TargetPropertyEntry(ge.Parse(value)));
- return;
+ this->Internal->CompileOptionsEntries.clear();
+ this->Internal->CompileOptionsBacktraces.clear();
+ if (value)
+ {
+ this->Internal->CompileOptionsEntries.push_back(value);
+ cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+ this->Internal->CompileOptionsBacktraces.push_back(lfbt);
+ }
}
- if(strcmp(prop,"COMPILE_DEFINITIONS") == 0)
+ else if(prop == "COMPILE_FEATURES")
{
- cmListFileBacktrace lfbt;
- this->Makefile->GetBacktrace(lfbt);
- cmGeneratorExpression ge(lfbt);
- this->Internal->CompileDefinitionsEntries.push_back(
- new cmTargetInternals::TargetPropertyEntry(ge.Parse(value)));
- return;
+ this->Internal->CompileFeaturesEntries.clear();
+ this->Internal->CompileFeaturesBacktraces.clear();
+ if (value)
+ {
+ this->Internal->CompileFeaturesEntries.push_back(value);
+ cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+ this->Internal->CompileFeaturesBacktraces.push_back(lfbt);
+ }
}
- if(strcmp(prop,"EXPORT_NAME") == 0 && this->IsImported())
+ else if(prop == "COMPILE_DEFINITIONS")
{
- cmOStringStream e;
+ this->Internal->CompileDefinitionsEntries.clear();
+ this->Internal->CompileDefinitionsBacktraces.clear();
+ if (value)
+ {
+ this->Internal->CompileDefinitionsEntries.push_back(value);
+ cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+ this->Internal->CompileDefinitionsBacktraces.push_back(lfbt);
+ }
+ }
+ else if(prop == "EXPORT_NAME" && this->IsImported())
+ {
+ std::ostringstream e;
e << "EXPORT_NAME property can't be set on imported targets (\""
<< this->Name << "\")\n";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
- return;
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
}
- if (strcmp(prop, "LINK_LIBRARIES") == 0)
+ else if (prop == "LINK_LIBRARIES")
{
- if (cmGeneratorExpression::IsValidTargetName(value)
- || cmGeneratorExpression::Find(value) != std::string::npos)
+ this->Internal->LinkImplementationPropertyEntries.clear();
+ this->Internal->LinkImplementationPropertyBacktraces.clear();
+ if (value)
{
- cmListFileBacktrace lfbt;
- this->Makefile->GetBacktrace(lfbt);
- cmValueWithOrigin entry(value, lfbt);
- this->Internal->LinkInterfacePropertyEntries.push_back(entry);
+ cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+ this->Internal->LinkImplementationPropertyEntries.push_back(value);
+ this->Internal->LinkImplementationPropertyBacktraces.push_back(lfbt);
}
- // Fall through
}
- this->Properties.AppendProperty(prop, value, cmProperty::TARGET, asString);
- this->MaybeInvalidatePropertyCache(prop);
-}
-
-//----------------------------------------------------------------------------
-const char* cmTarget::GetExportName()
-{
- const char *exportName = this->GetProperty("EXPORT_NAME");
-
- if (exportName && *exportName)
+ else if (prop == "SOURCES")
{
- if (!cmGeneratorExpression::IsValidTargetName(exportName))
+ if(this->IsImported())
{
- cmOStringStream e;
- e << "EXPORT_NAME property \"" << exportName << "\" for \""
- << this->GetName() << "\": is not valid.";
- cmSystemTools::Error(e.str().c_str());
- return "";
+ std::ostringstream e;
+ e << "SOURCES property can't be set on imported targets (\""
+ << this->Name << "\")\n";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return;
}
- return exportName;
+
+ this->Internal->SourceEntries.clear();
+ this->Internal->SourceBacktraces.clear();
+ if (value)
+ {
+ cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+ this->Internal->SourceEntries.push_back(value);
+ this->Internal->SourceBacktraces.push_back(lfbt);
+ }
+ }
+ else
+ {
+ this->Properties.SetProperty(prop, value);
}
- return this->GetName();
}
//----------------------------------------------------------------------------
-void cmTarget::AppendBuildInterfaceIncludes()
+void cmTarget::AppendProperty(const std::string& prop, const char* value,
+ bool asString)
{
- if(this->GetType() != cmTarget::SHARED_LIBRARY &&
- this->GetType() != cmTarget::STATIC_LIBRARY &&
- this->GetType() != cmTarget::MODULE_LIBRARY &&
- !this->IsExecutableWithExports())
+ if (this->GetType() == cmState::INTERFACE_LIBRARY
+ && !whiteListedInterfaceProperty(prop))
{
+ std::ostringstream e;
+ e << "INTERFACE_LIBRARY targets may only have whitelisted properties. "
+ "The property \"" << prop << "\" is not allowed.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
- if (this->BuildInterfaceIncludesAppended)
+ else if (prop == "NAME")
{
+ std::ostringstream e;
+ e << "NAME property is read-only\n";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
- this->BuildInterfaceIncludesAppended = true;
-
- if (this->Makefile->IsOn("CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE"))
+ else if(prop == "INCLUDE_DIRECTORIES")
{
- const char *binDir = this->Makefile->GetStartOutputDirectory();
- const char *srcDir = this->Makefile->GetStartDirectory();
- const std::string dirs = std::string(binDir ? binDir : "")
- + std::string(binDir ? ";" : "")
- + std::string(srcDir ? srcDir : "");
- if (!dirs.empty())
+ if (value && *value)
{
- this->AppendProperty("INTERFACE_INCLUDE_DIRECTORIES",
- ("$<BUILD_INTERFACE:" + dirs + ">").c_str());
+ this->Internal->IncludeDirectoriesEntries.push_back(value);
+ cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+ this->Internal->IncludeDirectoriesBacktraces.push_back(lfbt);
}
}
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::InsertInclude(const cmValueWithOrigin &entry,
- bool before)
-{
- cmGeneratorExpression ge(entry.Backtrace);
-
- std::vector<cmTargetInternals::TargetPropertyEntry*>::iterator position
- = before ? this->Internal->IncludeDirectoriesEntries.begin()
- : this->Internal->IncludeDirectoriesEntries.end();
-
- this->Internal->IncludeDirectoriesEntries.insert(position,
- new cmTargetInternals::TargetPropertyEntry(ge.Parse(entry.Value)));
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::InsertCompileOption(const cmValueWithOrigin &entry,
- bool before)
-{
- cmGeneratorExpression ge(entry.Backtrace);
-
- std::vector<cmTargetInternals::TargetPropertyEntry*>::iterator position
- = before ? this->Internal->CompileOptionsEntries.begin()
- : this->Internal->CompileOptionsEntries.end();
-
- this->Internal->CompileOptionsEntries.insert(position,
- new cmTargetInternals::TargetPropertyEntry(ge.Parse(entry.Value)));
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::InsertCompileDefinition(const cmValueWithOrigin &entry,
- bool before)
-{
- cmGeneratorExpression ge(entry.Backtrace);
-
- std::vector<cmTargetInternals::TargetPropertyEntry*>::iterator position
- = before ? this->Internal->CompileDefinitionsEntries.begin()
- : this->Internal->CompileDefinitionsEntries.end();
-
- this->Internal->CompileDefinitionsEntries.insert(position,
- new cmTargetInternals::TargetPropertyEntry(ge.Parse(entry.Value)));
-}
-
-//----------------------------------------------------------------------------
-static void processIncludeDirectories(cmTarget *tgt,
- const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
- std::vector<std::string> &includes,
- std::set<std::string> &uniqueIncludes,
- cmGeneratorExpressionDAGChecker *dagChecker,
- const char *config, bool debugIncludes)
-{
- cmMakefile *mf = tgt->GetMakefile();
-
- for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
- it = entries.begin(), end = entries.end(); it != end; ++it)
+ else if(prop == "COMPILE_OPTIONS")
{
- bool testIsOff = true;
- bool cacheIncludes = false;
- std::vector<std::string> entryIncludes = (*it)->CachedEntries;
- if(!entryIncludes.empty())
- {
- testIsOff = false;
- }
- else
+ if (value && *value)
{
- cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
- config,
- false,
- tgt,
- dagChecker),
- entryIncludes);
- if (mf->IsGeneratingBuildSystem()
- && !(*it)->ge->GetHadContextSensitiveCondition())
- {
- cacheIncludes = true;
- }
+ this->Internal->CompileOptionsEntries.push_back(value);
+ cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+ this->Internal->CompileOptionsBacktraces.push_back(lfbt);
}
- std::string usedIncludes;
- for(std::vector<std::string>::iterator
- li = entryIncludes.begin(); li != entryIncludes.end(); ++li)
- {
- cmTarget *dependentTarget =
- mf->FindTargetToUse((*it)->TargetName.c_str());
-
- const bool fromImported = dependentTarget
- && dependentTarget->IsImported();
-
- if (fromImported && !cmSystemTools::FileExists(li->c_str()))
- {
- cmOStringStream e;
- e << "Imported target \"" << (*it)->TargetName << "\" includes "
- "non-existent path\n \"" << *li << "\"\nin its "
- "INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:\n"
- "* The path was deleted, renamed, or moved to another "
- "location.\n"
- "* An install or uninstall procedure did not complete "
- "successfully.\n"
- "* The installation package was faulty and references files it "
- "does not provide.\n";
- tgt->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
- return;
- }
-
- if (!cmSystemTools::FileIsFullPath(li->c_str()))
- {
- cmOStringStream e;
- bool noMessage = false;
- cmake::MessageType messageType = cmake::FATAL_ERROR;
- if (!(*it)->TargetName.empty())
- {
- e << "Target \"" << (*it)->TargetName << "\" contains relative "
- "path in its INTERFACE_INCLUDE_DIRECTORIES:\n"
- " \"" << *li << "\"";
- }
- else
- {
- switch(tgt->GetPolicyStatusCMP0021())
- {
- case cmPolicies::WARN:
- {
- cmOStringStream w;
- e << (mf->GetPolicies()
- ->GetPolicyWarning(cmPolicies::CMP0021)) << "\n";
- messageType = cmake::AUTHOR_WARNING;
- }
- break;
- case cmPolicies::OLD:
- noMessage = true;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::NEW:
- // Issue the fatal message.
- break;
- }
- e << "Found relative path while evaluating include directories of "
- "\"" << tgt->GetName() << "\":\n \"" << *li << "\"\n";
- }
- if (!noMessage)
- {
- tgt->GetMakefile()->IssueMessage(messageType, e.str().c_str());
- if (messageType == cmake::FATAL_ERROR)
- {
- return;
- }
- }
- }
-
- if (testIsOff && !cmSystemTools::IsOff(li->c_str()))
- {
- cmSystemTools::ConvertToUnixSlashes(*li);
- }
- std::string inc = *li;
-
- if(uniqueIncludes.insert(inc).second)
- {
- includes.push_back(inc);
- if (debugIncludes)
- {
- usedIncludes += " * " + inc + "\n";
- }
- }
- }
- if (cacheIncludes)
- {
- (*it)->CachedEntries = entryIncludes;
- }
- if (!usedIncludes.empty())
+ }
+ else if(prop == "COMPILE_FEATURES")
+ {
+ if (value && *value)
{
- mf->GetCMakeInstance()->IssueMessage(cmake::LOG,
- std::string("Used includes for target ")
- + tgt->GetName() + ":\n"
- + usedIncludes, (*it)->ge->GetBacktrace());
+ this->Internal->CompileFeaturesEntries.push_back(value);
+ cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+ this->Internal->CompileFeaturesBacktraces.push_back(lfbt);
}
}
-}
-
-//----------------------------------------------------------------------------
-std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config)
-{
- std::vector<std::string> includes;
- std::set<std::string> uniqueIncludes;
- cmListFileBacktrace lfbt;
-
- cmGeneratorExpressionDAGChecker dagChecker(lfbt,
- this->GetName(),
- "INCLUDE_DIRECTORIES", 0, 0);
-
- this->AppendBuildInterfaceIncludes();
-
- std::vector<std::string> debugProperties;
- const char *debugProp =
- this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
- if (debugProp)
+ else if(prop == "COMPILE_DEFINITIONS")
{
- cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+ if (value && *value)
+ {
+ this->Internal->CompileDefinitionsEntries.push_back(value);
+ cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+ this->Internal->CompileDefinitionsBacktraces.push_back(lfbt);
+ }
}
-
- bool debugIncludes = !this->DebugIncludesDone
- && std::find(debugProperties.begin(),
- debugProperties.end(),
- "INCLUDE_DIRECTORIES")
- != debugProperties.end();
-
- if (this->Makefile->IsGeneratingBuildSystem())
+ else if(prop == "EXPORT_NAME" && this->IsImported())
{
- this->DebugIncludesDone = true;
+ std::ostringstream e;
+ e << "EXPORT_NAME property can't be set on imported targets (\""
+ << this->Name << "\")\n";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
}
-
- processIncludeDirectories(this,
- this->Internal->IncludeDirectoriesEntries,
- includes,
- uniqueIncludes,
- &dagChecker,
- config,
- debugIncludes);
-
- std::string configString = config ? config : "";
- if (!this->Internal->CacheLinkInterfaceIncludeDirectoriesDone[configString])
+ else if (prop == "LINK_LIBRARIES")
{
- for (std::vector<cmValueWithOrigin>::const_iterator
- it = this->Internal->LinkInterfacePropertyEntries.begin(),
- end = this->Internal->LinkInterfacePropertyEntries.end();
- it != end; ++it)
+ if (value && *value)
{
- {
- cmGeneratorExpression ge(lfbt);
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(it->Value);
- std::string result = cge->Evaluate(this->Makefile, config,
- false, this, 0, 0);
- if (!this->Makefile->FindTargetToUse(result.c_str()))
- {
- continue;
- }
- }
- std::string includeGenex = "$<TARGET_PROPERTY:" +
- it->Value + ",INTERFACE_INCLUDE_DIRECTORIES>";
- if (cmGeneratorExpression::Find(it->Value) != std::string::npos)
- {
- // Because it->Value is a generator expression, ensure that it
- // evaluates to the non-empty string before being used in the
- // TARGET_PROPERTY expression.
- includeGenex = "$<$<BOOL:" + it->Value + ">:" + includeGenex + ">";
- }
- cmGeneratorExpression ge(it->Backtrace);
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(
- includeGenex);
-
- this->Internal
- ->CachedLinkInterfaceIncludeDirectoriesEntries[configString].push_back(
- new cmTargetInternals::TargetPropertyEntry(cge,
- it->Value));
- }
-
- if(this->Makefile->IsOn("APPLE"))
- {
- LinkImplementation const* impl = this->GetLinkImplementation(config,
- this);
- for(std::vector<std::string>::const_iterator
- it = impl->Libraries.begin();
- it != impl->Libraries.end(); ++it)
- {
- std::string libDir = cmSystemTools::CollapseFullPath(it->c_str());
-
- static cmsys::RegularExpression
- frameworkCheck("(.*\\.framework)(/Versions/[^/]+)?/[^/]+$");
- if(!frameworkCheck.find(libDir))
- {
- continue;
- }
-
- libDir = frameworkCheck.match(1);
-
- cmGeneratorExpression ge(lfbt);
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(libDir.c_str());
- this->Internal
- ->CachedLinkInterfaceIncludeDirectoriesEntries[configString]
- .push_back(new cmTargetInternals::TargetPropertyEntry(cge));
- }
+ cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+ this->Internal->LinkImplementationPropertyEntries.push_back(value);
+ this->Internal->LinkImplementationPropertyBacktraces.push_back(lfbt);
}
}
-
- processIncludeDirectories(this,
- this->Internal->CachedLinkInterfaceIncludeDirectoriesEntries[configString],
- includes,
- uniqueIncludes,
- &dagChecker,
- config,
- debugIncludes);
-
- if (!this->Makefile->IsGeneratingBuildSystem())
+ else if (prop == "SOURCES")
{
- deleteAndClear(
- this->Internal->CachedLinkInterfaceIncludeDirectoriesEntries);
+ if(this->IsImported())
+ {
+ std::ostringstream e;
+ e << "SOURCES property can't be set on imported targets (\""
+ << this->Name << "\")\n";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return;
+ }
+ cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+ this->Internal->SourceEntries.push_back(value);
+ this->Internal->SourceBacktraces.push_back(lfbt);
}
else
{
- this->Internal->CacheLinkInterfaceIncludeDirectoriesDone[configString]
- = true;
- }
-
- return includes;
-}
-
-//----------------------------------------------------------------------------
-static void processCompileOptionsInternal(cmTarget *tgt,
- const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
- std::vector<std::string> &options,
- std::set<std::string> &uniqueOptions,
- cmGeneratorExpressionDAGChecker *dagChecker,
- const char *config, bool debugOptions, const char *logName)
-{
- cmMakefile *mf = tgt->GetMakefile();
-
- for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
- it = entries.begin(), end = entries.end(); it != end; ++it)
- {
- bool cacheOptions = false;
- std::vector<std::string> entryOptions = (*it)->CachedEntries;
- if(entryOptions.empty())
- {
- cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
- config,
- false,
- tgt,
- dagChecker),
- entryOptions);
- if (mf->IsGeneratingBuildSystem()
- && !(*it)->ge->GetHadContextSensitiveCondition())
- {
- cacheOptions = true;
- }
- }
- std::string usedOptions;
- for(std::vector<std::string>::iterator
- li = entryOptions.begin(); li != entryOptions.end(); ++li)
- {
- std::string opt = *li;
-
- if(uniqueOptions.insert(opt).second)
- {
- options.push_back(opt);
- if (debugOptions)
- {
- usedOptions += " * " + opt + "\n";
- }
- }
- }
- if (cacheOptions)
- {
- (*it)->CachedEntries = entryOptions;
- }
- if (!usedOptions.empty())
- {
- mf->GetCMakeInstance()->IssueMessage(cmake::LOG,
- std::string("Used compile ") + logName
- + std::string(" for target ")
- + tgt->GetName() + ":\n"
- + usedOptions, (*it)->ge->GetBacktrace());
- }
+ this->Properties.AppendProperty(prop, value, asString);
}
}
//----------------------------------------------------------------------------
-static void processCompileOptions(cmTarget *tgt,
- const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
- std::vector<std::string> &options,
- std::set<std::string> &uniqueOptions,
- cmGeneratorExpressionDAGChecker *dagChecker,
- const char *config, bool debugOptions)
-{
- processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
- dagChecker, config, debugOptions, "options");
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GetCompileOptions(std::vector<std::string> &result,
- const char *config)
+void cmTarget::AppendBuildInterfaceIncludes()
{
- std::set<std::string> uniqueOptions;
- cmListFileBacktrace lfbt;
-
- cmGeneratorExpressionDAGChecker dagChecker(lfbt,
- this->GetName(),
- "COMPILE_OPTIONS", 0, 0);
-
- std::vector<std::string> debugProperties;
- const char *debugProp =
- this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
- if (debugProp)
+ if(this->GetType() != cmState::SHARED_LIBRARY &&
+ this->GetType() != cmState::STATIC_LIBRARY &&
+ this->GetType() != cmState::MODULE_LIBRARY &&
+ this->GetType() != cmState::INTERFACE_LIBRARY &&
+ !this->IsExecutableWithExports())
{
- cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+ return;
}
-
- bool debugOptions = !this->DebugCompileOptionsDone
- && std::find(debugProperties.begin(),
- debugProperties.end(),
- "COMPILE_OPTIONS")
- != debugProperties.end();
-
- if (this->Makefile->IsGeneratingBuildSystem())
+ if (this->BuildInterfaceIncludesAppended)
{
- this->DebugCompileOptionsDone = true;
+ return;
}
+ this->BuildInterfaceIncludesAppended = true;
- processCompileOptions(this,
- this->Internal->CompileOptionsEntries,
- result,
- uniqueOptions,
- &dagChecker,
- config,
- debugOptions);
-
- std::string configString = config ? config : "";
- if (!this->Internal->CacheLinkInterfaceCompileOptionsDone[configString])
+ if (this->Makefile->IsOn("CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE"))
{
- for (std::vector<cmValueWithOrigin>::const_iterator
- it = this->Internal->LinkInterfacePropertyEntries.begin(),
- end = this->Internal->LinkInterfacePropertyEntries.end();
- it != end; ++it)
- {
+ const char *binDir = this->Makefile->GetCurrentBinaryDirectory();
+ const char *srcDir = this->Makefile->GetCurrentSourceDirectory();
+ const std::string dirs = std::string(binDir ? binDir : "")
+ + std::string(binDir ? ";" : "")
+ + std::string(srcDir ? srcDir : "");
+ if (!dirs.empty())
{
- cmGeneratorExpression ge(lfbt);
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(it->Value);
- std::string targetResult = cge->Evaluate(this->Makefile, config,
- false, this, 0, 0);
- if (!this->Makefile->FindTargetToUse(targetResult.c_str()))
- {
- continue;
- }
- }
- std::string optionGenex = "$<TARGET_PROPERTY:" +
- it->Value + ",INTERFACE_COMPILE_OPTIONS>";
- if (cmGeneratorExpression::Find(it->Value) != std::string::npos)
- {
- // Because it->Value is a generator expression, ensure that it
- // evaluates to the non-empty string before being used in the
- // TARGET_PROPERTY expression.
- optionGenex = "$<$<BOOL:" + it->Value + ">:" + optionGenex + ">";
- }
- cmGeneratorExpression ge(it->Backtrace);
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(
- optionGenex);
-
- this->Internal
- ->CachedLinkInterfaceCompileOptionsEntries[configString].push_back(
- new cmTargetInternals::TargetPropertyEntry(cge,
- it->Value));
+ this->AppendProperty("INTERFACE_INCLUDE_DIRECTORIES",
+ ("$<BUILD_INTERFACE:" + dirs + ">").c_str());
}
}
-
- processCompileOptions(this,
- this->Internal->CachedLinkInterfaceCompileOptionsEntries[configString],
- result,
- uniqueOptions,
- &dagChecker,
- config,
- debugOptions);
-
- if (!this->Makefile->IsGeneratingBuildSystem())
- {
- deleteAndClear(this->Internal->CachedLinkInterfaceCompileOptionsEntries);
- }
- else
- {
- this->Internal->CacheLinkInterfaceCompileOptionsDone[configString] = true;
- }
}
//----------------------------------------------------------------------------
-static void processCompileDefinitions(cmTarget *tgt,
- const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
- std::vector<std::string> &options,
- std::set<std::string> &uniqueOptions,
- cmGeneratorExpressionDAGChecker *dagChecker,
- const char *config, bool debugOptions)
+void cmTarget::InsertInclude(std::string const& entry,
+ cmListFileBacktrace const& bt,
+ bool before)
{
- processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
- dagChecker, config, debugOptions,
- "definitions");
+ std::vector<std::string>::iterator position =
+ before ? this->Internal->IncludeDirectoriesEntries.begin()
+ : this->Internal->IncludeDirectoriesEntries.end();
+
+ std::vector<cmListFileBacktrace>::iterator btPosition =
+ before ? this->Internal->IncludeDirectoriesBacktraces.begin()
+ : this->Internal->IncludeDirectoriesBacktraces.end();
+
+ this->Internal->IncludeDirectoriesEntries.insert(position, entry);
+ this->Internal->IncludeDirectoriesBacktraces.insert(btPosition, bt);
}
//----------------------------------------------------------------------------
-void cmTarget::GetCompileDefinitions(std::vector<std::string> &list,
- const char *config)
+void cmTarget::InsertCompileOption(std::string const& entry,
+ cmListFileBacktrace const& bt,
+ bool before)
{
- std::set<std::string> uniqueOptions;
- cmListFileBacktrace lfbt;
-
- cmGeneratorExpressionDAGChecker dagChecker(lfbt,
- this->GetName(),
- "COMPILE_DEFINITIONS", 0, 0);
-
- std::vector<std::string> debugProperties;
- const char *debugProp =
- this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
- if (debugProp)
- {
- cmSystemTools::ExpandListArgument(debugProp, debugProperties);
- }
-
- bool debugDefines = !this->DebugCompileDefinitionsDone
- && std::find(debugProperties.begin(),
- debugProperties.end(),
- "COMPILE_DEFINITIONS")
- != debugProperties.end();
-
- if (this->Makefile->IsGeneratingBuildSystem())
- {
- this->DebugCompileDefinitionsDone = true;
- }
-
- processCompileDefinitions(this,
- this->Internal->CompileDefinitionsEntries,
- list,
- uniqueOptions,
- &dagChecker,
- config,
- debugDefines);
-
- std::string configString = config ? config : "";
- if (!this->Internal->CacheLinkInterfaceCompileDefinitionsDone[configString])
- {
- for (std::vector<cmValueWithOrigin>::const_iterator
- it = this->Internal->LinkInterfacePropertyEntries.begin(),
- end = this->Internal->LinkInterfacePropertyEntries.end();
- it != end; ++it)
- {
- {
- cmGeneratorExpression ge(lfbt);
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(it->Value);
- std::string targetResult = cge->Evaluate(this->Makefile, config,
- false, this, 0, 0);
- if (!this->Makefile->FindTargetToUse(targetResult.c_str()))
- {
- continue;
- }
- }
- std::string defsGenex = "$<TARGET_PROPERTY:" +
- it->Value + ",INTERFACE_COMPILE_DEFINITIONS>";
- if (cmGeneratorExpression::Find(it->Value) != std::string::npos)
- {
- // Because it->Value is a generator expression, ensure that it
- // evaluates to the non-empty string before being used in the
- // TARGET_PROPERTY expression.
- defsGenex = "$<$<BOOL:" + it->Value + ">:" + defsGenex + ">";
- }
- cmGeneratorExpression ge(it->Backtrace);
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(
- defsGenex);
-
- this->Internal
- ->CachedLinkInterfaceCompileDefinitionsEntries[configString].push_back(
- new cmTargetInternals::TargetPropertyEntry(cge,
- it->Value));
- }
- if (config)
- {
- std::string configPropName = "COMPILE_DEFINITIONS_"
- + cmSystemTools::UpperCase(config);
- const char *configProp = this->GetProperty(configPropName.c_str());
- std::string defsString = (configProp ? configProp : "");
-
- cmGeneratorExpression ge(lfbt);
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(defsString);
- this->Internal
- ->CachedLinkInterfaceCompileDefinitionsEntries[configString].push_back(
- new cmTargetInternals::TargetPropertyEntry(cge));
- }
+ std::vector<std::string>::iterator position =
+ before ? this->Internal->CompileOptionsEntries.begin()
+ : this->Internal->CompileOptionsEntries.end();
- }
-
- processCompileDefinitions(this,
- this->Internal->CachedLinkInterfaceCompileDefinitionsEntries[configString],
- list,
- uniqueOptions,
- &dagChecker,
- config,
- debugDefines);
+ std::vector<cmListFileBacktrace>::iterator btPosition =
+ before ? this->Internal->CompileOptionsBacktraces.begin()
+ : this->Internal->CompileOptionsBacktraces.end();
- if (!this->Makefile->IsGeneratingBuildSystem())
- {
- deleteAndClear(this->Internal
- ->CachedLinkInterfaceCompileDefinitionsEntries);
- }
- else
- {
- this->Internal->CacheLinkInterfaceCompileDefinitionsDone[configString]
- = true;
- }
+ this->Internal->CompileOptionsEntries.insert(position, entry);
+ this->Internal->CompileOptionsBacktraces.insert(btPosition, bt);
}
//----------------------------------------------------------------------------
-void cmTarget::MaybeInvalidatePropertyCache(const char* prop)
+void cmTarget::InsertCompileDefinition(std::string const& entry,
+ cmListFileBacktrace const& bt)
{
- // Wipe out maps caching information affected by this property.
- if(this->IsImported() && strncmp(prop, "IMPORTED", 8) == 0)
- {
- this->Internal->ImportInfoMap.clear();
- }
- if(!this->IsImported() && strncmp(prop, "LINK_INTERFACE_", 15) == 0)
- {
- this->ClearLinkMaps();
- }
+ this->Internal->CompileDefinitionsEntries.push_back(entry);
+ this->Internal->CompileDefinitionsBacktraces.push_back(bt);
}
//----------------------------------------------------------------------------
static void cmTargetCheckLINK_INTERFACE_LIBRARIES(
- const char* prop, const char* value, cmMakefile* context, bool imported
- )
+ const std::string& prop, const char* value, cmMakefile* context,
+ bool imported)
{
// Look for link-type keywords in the value.
static cmsys::RegularExpression
@@ -3789,7 +1428,7 @@ static void cmTargetCheckLINK_INTERFACE_LIBRARIES(
"LINK_INTERFACE_LIBRARIES");
// Report an error.
- cmOStringStream e;
+ std::ostringstream e;
e << "Property " << prop << " may not contain link-type keyword \""
<< keys.match(2) << "\". "
<< "The " << base << " property has a per-configuration "
@@ -3826,7 +1465,7 @@ static void cmTargetCheckINTERFACE_LINK_LIBRARIES(const char* value,
}
// Report an error.
- cmOStringStream e;
+ std::ostringstream e;
e << "Property INTERFACE_LINK_LIBRARIES may not contain link-type "
"keyword \"" << keys.match(2) << "\". The INTERFACE_LINK_LIBRARIES "
@@ -3837,24 +1476,25 @@ static void cmTargetCheckINTERFACE_LINK_LIBRARIES(const char* value,
}
//----------------------------------------------------------------------------
-void cmTarget::CheckProperty(const char* prop, cmMakefile* context)
+void cmTarget::CheckProperty(const std::string& prop,
+ cmMakefile* context) const
{
// Certain properties need checking.
- if(strncmp(prop, "LINK_INTERFACE_LIBRARIES", 24) == 0)
+ if(cmHasLiteralPrefix(prop, "LINK_INTERFACE_LIBRARIES"))
{
if(const char* value = this->GetProperty(prop))
{
cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, value, context, false);
}
}
- if(strncmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES", 33) == 0)
+ if(cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES"))
{
if(const char* value = this->GetProperty(prop))
{
cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, value, context, true);
}
}
- if(strncmp(prop, "INTERFACE_LINK_LIBRARIES", 24) == 0)
+ if(cmHasLiteralPrefix(prop, "INTERFACE_LINK_LIBRARIES"))
{
if(const char* value = this->GetProperty(prop))
{
@@ -3864,577 +1504,401 @@ void cmTarget::CheckProperty(const char* prop, cmMakefile* context)
}
//----------------------------------------------------------------------------
-void cmTarget::MarkAsImported()
+void cmTarget::MarkAsImported(bool global)
{
this->IsImportedTarget = true;
+ this->ImportedGloballyVisible = global;
}
//----------------------------------------------------------------------------
-bool cmTarget::HaveWellDefinedOutputFiles()
-{
- return
- this->GetType() == cmTarget::STATIC_LIBRARY ||
- this->GetType() == cmTarget::SHARED_LIBRARY ||
- this->GetType() == cmTarget::MODULE_LIBRARY ||
- this->GetType() == cmTarget::EXECUTABLE;
-}
-
-//----------------------------------------------------------------------------
-cmTarget::OutputInfo const* cmTarget::GetOutputInfo(const char* config)
-{
- // There is no output information for imported targets.
- if(this->IsImported())
- {
- return 0;
- }
-
- // Only libraries and executables have well-defined output files.
- if(!this->HaveWellDefinedOutputFiles())
- {
- std::string msg = "cmTarget::GetOutputInfo called for ";
- msg += this->GetName();
- msg += " which has type ";
- msg += cmTarget::GetTargetTypeName(this->GetType());
- this->GetMakefile()->IssueMessage(cmake::INTERNAL_ERROR, msg);
- abort();
- return 0;
- }
-
- // Lookup/compute/cache the output information for this configuration.
- std::string config_upper;
- if(config && *config)
- {
- config_upper = cmSystemTools::UpperCase(config);
- }
- typedef cmTargetInternals::OutputInfoMapType OutputInfoMapType;
- OutputInfoMapType::const_iterator i =
- this->Internal->OutputInfoMap.find(config_upper);
- if(i == this->Internal->OutputInfoMap.end())
- {
- OutputInfo info;
- this->ComputeOutputDir(config, false, info.OutDir);
- this->ComputeOutputDir(config, true, info.ImpDir);
- if(!this->ComputePDBOutputDir(config, info.PdbDir))
- {
- info.PdbDir = info.OutDir;
- }
- OutputInfoMapType::value_type entry(config_upper, info);
- i = this->Internal->OutputInfoMap.insert(entry).first;
- }
- return &i->second;
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetDirectory(const char* config, bool implib)
-{
- if (this->IsImported())
- {
- // Return the directory from which the target is imported.
- return
- cmSystemTools::GetFilenamePath(
- this->ImportedGetFullPath(config, implib));
- }
- else if(OutputInfo const* info = this->GetOutputInfo(config))
- {
- // Return the directory in which the target will be built.
- return implib? info->ImpDir : info->OutDir;
- }
- return "";
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetPDBDirectory(const char* config)
-{
- if(OutputInfo const* info = this->GetOutputInfo(config))
- {
- // Return the directory in which the target will be built.
- return info->PdbDir;
- }
- return "";
-}
-
-//----------------------------------------------------------------------------
-const char* cmTarget::GetLocation(const char* config)
+bool cmTarget::HandleLocationPropertyPolicy(cmMakefile* context) const
{
if (this->IsImported())
{
- return this->ImportedGetLocation(config);
- }
- else
- {
- return this->NormalGetLocation(config);
- }
-}
-
-//----------------------------------------------------------------------------
-const char* cmTarget::ImportedGetLocation(const char* config)
-{
- this->Location = this->ImportedGetFullPath(config, false);
- return this->Location.c_str();
-}
-
-//----------------------------------------------------------------------------
-const char* cmTarget::NormalGetLocation(const char* config)
-{
- // Handle the configuration-specific case first.
- if(config)
- {
- this->Location = this->GetFullPath(config, false);
- return this->Location.c_str();
- }
-
- // Now handle the deprecated build-time configuration location.
- this->Location = this->GetDirectory();
- const char* cfgid = this->Makefile->GetDefinition("CMAKE_CFG_INTDIR");
- if(cfgid && strcmp(cfgid, ".") != 0)
- {
- this->Location += "/";
- this->Location += cfgid;
+ return true;
}
-
- if(this->IsAppBundleOnApple())
+ std::ostringstream e;
+ const char *modal = 0;
+ cmake::MessageType messageType = cmake::AUTHOR_WARNING;
+ switch (context->GetPolicyStatus(cmPolicies::CMP0026))
{
- std::string macdir = this->BuildMacContentDirectory("", config, false);
- if(!macdir.empty())
- {
- this->Location += "/";
- this->Location += macdir;
- }
+ case cmPolicies::WARN:
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0026) << "\n";
+ modal = "should";
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::NEW:
+ modal = "may";
+ messageType = cmake::FATAL_ERROR;
}
- this->Location += "/";
- this->Location += this->GetFullName(config, false);
- return this->Location.c_str();
-}
-//----------------------------------------------------------------------------
-void cmTarget::GetTargetVersion(int& major, int& minor)
-{
- int patch;
- this->GetTargetVersion(false, major, minor, patch);
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GetTargetVersion(bool soversion,
- int& major, int& minor, int& patch)
-{
- // Set the default values.
- major = 0;
- minor = 0;
- patch = 0;
-
- // Look for a VERSION or SOVERSION property.
- const char* prop = soversion? "SOVERSION" : "VERSION";
- if(const char* version = this->GetProperty(prop))
+ if (modal)
{
- // Try to parse the version number and store the results that were
- // successfully parsed.
- int parsed_major;
- int parsed_minor;
- int parsed_patch;
- switch(sscanf(version, "%d.%d.%d",
- &parsed_major, &parsed_minor, &parsed_patch))
- {
- case 3: patch = parsed_patch; // no break!
- case 2: minor = parsed_minor; // no break!
- case 1: major = parsed_major; // no break!
- default: break;
- }
+ e << "The LOCATION property " << modal << " not be read from target \""
+ << this->GetName() << "\". Use the target name directly with "
+ "add_custom_command, or use the generator expression $<TARGET_FILE>, "
+ "as appropriate.\n";
+ context->IssueMessage(messageType, e.str());
}
-}
-//----------------------------------------------------------------------------
-const char* cmTarget::GetFeature(const char* feature, const char* config)
-{
- if(config && *config)
- {
- std::string featureConfig = feature;
- featureConfig += "_";
- featureConfig += cmSystemTools::UpperCase(config);
- if(const char* value = this->GetProperty(featureConfig.c_str()))
- {
- return value;
- }
- }
- if(const char* value = this->GetProperty(feature))
- {
- return value;
- }
- return this->Makefile->GetFeature(feature, config);
+ return messageType != cmake::FATAL_ERROR;
}
//----------------------------------------------------------------------------
-const char *cmTarget::GetProperty(const char* prop)
+const char *cmTarget::GetProperty(const std::string& prop) const
{
- return this->GetProperty(prop, cmProperty::TARGET);
+ return this->GetProperty(prop, this->Makefile);
}
//----------------------------------------------------------------------------
-const char *cmTarget::GetProperty(const char* prop,
- cmProperty::ScopeType scope)
+const char *cmTarget::GetProperty(const std::string& prop,
+ cmMakefile* context) const
{
- if(!prop)
+ if (this->GetType() == cmState::INTERFACE_LIBRARY
+ && !whiteListedInterfaceProperty(prop))
{
+ std::ostringstream e;
+ e << "INTERFACE_LIBRARY targets may only have whitelisted properties. "
+ "The property \"" << prop << "\" is not allowed.";
+ context->IssueMessage(cmake::FATAL_ERROR, e.str());
return 0;
}
- if (strcmp(prop, "NAME") == 0)
- {
- return this->GetName();
- }
-
// Watch for special "computed" properties that are dependent on
// other properties or variables. Always recompute them.
- if(this->GetType() == cmTarget::EXECUTABLE ||
- this->GetType() == cmTarget::STATIC_LIBRARY ||
- this->GetType() == cmTarget::SHARED_LIBRARY ||
- this->GetType() == cmTarget::MODULE_LIBRARY ||
- this->GetType() == cmTarget::UNKNOWN_LIBRARY)
+ if(this->GetType() == cmState::EXECUTABLE ||
+ this->GetType() == cmState::STATIC_LIBRARY ||
+ this->GetType() == cmState::SHARED_LIBRARY ||
+ this->GetType() == cmState::MODULE_LIBRARY ||
+ this->GetType() == cmState::UNKNOWN_LIBRARY)
{
- if(strcmp(prop,"LOCATION") == 0)
+ static const std::string propLOCATION = "LOCATION";
+ if(prop == propLOCATION)
{
+ if (!this->HandleLocationPropertyPolicy(context))
+ {
+ return 0;
+ }
+
// Set the LOCATION property of the target.
//
// For an imported target this is the location of an arbitrary
// available configuration.
//
- // For a non-imported target this is deprecated because it
- // cannot take into account the per-configuration name of the
- // target because the configuration type may not be known at
- // CMake time.
- this->SetProperty("LOCATION", this->GetLocation(0));
+ if(this->IsImported())
+ {
+ this->Properties.SetProperty(
+ propLOCATION, this->ImportedGetFullPath("", false).c_str());
+ }
+ else
+ {
+ // For a non-imported target this is deprecated because it
+ // cannot take into account the per-configuration name of the
+ // target because the configuration type may not be known at
+ // CMake time.
+ cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
+ gg->CreateGenerationObjects();
+ cmGeneratorTarget* gt = gg->FindGeneratorTarget(this->GetName());
+ this->Properties.SetProperty(propLOCATION,
+ gt->GetLocationForBuild());
+ }
+
}
// Support "LOCATION_<CONFIG>".
- if(strncmp(prop, "LOCATION_", 9) == 0)
+ else if(cmHasLiteralPrefix(prop, "LOCATION_"))
{
- std::string configName = prop+9;
- this->SetProperty(prop, this->GetLocation(configName.c_str()));
+ if (!this->HandleLocationPropertyPolicy(context))
+ {
+ return 0;
+ }
+ const char* configName = prop.c_str() + 9;
+
+ if (this->IsImported())
+ {
+ this->Properties.SetProperty(
+ prop, this->ImportedGetFullPath(configName, false).c_str());
+ }
+ else
+ {
+ cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
+ gg->CreateGenerationObjects();
+ cmGeneratorTarget* gt = gg->FindGeneratorTarget(this->GetName());
+ this->Properties.SetProperty(
+ prop, gt->GetFullPath(configName, false).c_str());
+ }
}
- else
+ // Support "<CONFIG>_LOCATION".
+ else if(cmHasLiteralSuffix(prop, "_LOCATION"))
{
- // Support "<CONFIG>_LOCATION" for compatiblity.
- int len = static_cast<int>(strlen(prop));
- if(len > 9 && strcmp(prop+len-9, "_LOCATION") == 0)
+ std::string configName(prop.c_str(), prop.size() - 9);
+ if(configName != "IMPORTED")
{
- std::string configName(prop, len-9);
- if(configName != "IMPORTED")
+ if (!this->HandleLocationPropertyPolicy(context))
{
- this->SetProperty(prop, this->GetLocation(configName.c_str()));
+ return 0;
+ }
+ if (this->IsImported())
+ {
+ this->Properties.SetProperty(
+ prop, this->ImportedGetFullPath(configName, false).c_str());
+ }
+ else
+ {
+ cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
+ gg->CreateGenerationObjects();
+ cmGeneratorTarget* gt = gg->FindGeneratorTarget(this->GetName());
+ this->Properties.SetProperty(
+ prop, gt->GetFullPath(configName, false).c_str());
}
}
}
}
- if(strcmp(prop,"INCLUDE_DIRECTORIES") == 0)
- {
- static std::string output;
- output = "";
- std::string sep;
- typedef cmTargetInternals::TargetPropertyEntry
- TargetPropertyEntry;
- for (std::vector<TargetPropertyEntry*>::const_iterator
- it = this->Internal->IncludeDirectoriesEntries.begin(),
- end = this->Internal->IncludeDirectoriesEntries.end();
- it != end; ++it)
- {
- output += sep;
- output += (*it)->ge->GetInput();
- sep = ";";
+ static UNORDERED_SET<std::string> specialProps;
+#define MAKE_STATIC_PROP(PROP) \
+ static const std::string prop##PROP = #PROP
+ MAKE_STATIC_PROP(LINK_LIBRARIES);
+ MAKE_STATIC_PROP(TYPE);
+ MAKE_STATIC_PROP(INCLUDE_DIRECTORIES);
+ MAKE_STATIC_PROP(COMPILE_FEATURES);
+ MAKE_STATIC_PROP(COMPILE_OPTIONS);
+ MAKE_STATIC_PROP(COMPILE_DEFINITIONS);
+ MAKE_STATIC_PROP(IMPORTED);
+ MAKE_STATIC_PROP(NAME);
+ MAKE_STATIC_PROP(BINARY_DIR);
+ MAKE_STATIC_PROP(SOURCE_DIR);
+ MAKE_STATIC_PROP(SOURCES);
+#undef MAKE_STATIC_PROP
+ if(specialProps.empty())
+ {
+ specialProps.insert(propLINK_LIBRARIES);
+ specialProps.insert(propTYPE);
+ specialProps.insert(propINCLUDE_DIRECTORIES);
+ specialProps.insert(propCOMPILE_FEATURES);
+ specialProps.insert(propCOMPILE_OPTIONS);
+ specialProps.insert(propCOMPILE_DEFINITIONS);
+ specialProps.insert(propIMPORTED);
+ specialProps.insert(propNAME);
+ specialProps.insert(propBINARY_DIR);
+ specialProps.insert(propSOURCE_DIR);
+ specialProps.insert(propSOURCES);
+ }
+ if(specialProps.count(prop))
+ {
+ if(prop == propLINK_LIBRARIES)
+ {
+ if (this->Internal->LinkImplementationPropertyEntries.empty())
+ {
+ return 0;
+ }
+
+ static std::string output;
+ output = cmJoin(this->Internal->LinkImplementationPropertyEntries, ";");
+ return output.c_str();
}
- return output.c_str();
- }
- if(strcmp(prop,"COMPILE_OPTIONS") == 0)
- {
- static std::string output;
- output = "";
- std::string sep;
- typedef cmTargetInternals::TargetPropertyEntry
- TargetPropertyEntry;
- for (std::vector<TargetPropertyEntry*>::const_iterator
- it = this->Internal->CompileOptionsEntries.begin(),
- end = this->Internal->CompileOptionsEntries.end();
- it != end; ++it)
+ // the type property returns what type the target is
+ else if (prop == propTYPE)
{
- output += sep;
- output += (*it)->ge->GetInput();
- sep = ";";
+ return cmState::GetTargetTypeName(this->GetType());
}
- return output.c_str();
- }
- if(strcmp(prop,"COMPILE_DEFINITIONS") == 0)
- {
- static std::string output;
- output = "";
- std::string sep;
- typedef cmTargetInternals::TargetPropertyEntry
- TargetPropertyEntry;
- for (std::vector<TargetPropertyEntry*>::const_iterator
- it = this->Internal->CompileDefinitionsEntries.begin(),
- end = this->Internal->CompileDefinitionsEntries.end();
- it != end; ++it)
+ else if(prop == propINCLUDE_DIRECTORIES)
{
- output += sep;
- output += (*it)->ge->GetInput();
- sep = ";";
- }
- return output.c_str();
- }
-
- if (strcmp(prop,"IMPORTED") == 0)
- {
- return this->IsImported()?"TRUE":"FALSE";
- }
+ if (this->Internal->IncludeDirectoriesEntries.empty())
+ {
+ return 0;
+ }
- if(!strcmp(prop,"SOURCES"))
- {
- cmOStringStream ss;
- const char* sep = "";
- for(std::vector<cmSourceFile*>::const_iterator
- i = this->SourceFiles.begin();
- i != this->SourceFiles.end(); ++i)
+ static std::string output;
+ output = cmJoin(this->Internal->IncludeDirectoriesEntries, ";");
+ return output.c_str();
+ }
+ else if(prop == propCOMPILE_FEATURES)
{
- // Separate from the previous list entries.
- ss << sep;
- sep = ";";
-
- // Construct what is known about this source file location.
- cmSourceFileLocation const& location = (*i)->GetLocation();
- std::string sname = location.GetDirectory();
- if(!sname.empty())
+ if (this->Internal->CompileFeaturesEntries.empty())
{
- sname += "/";
+ return 0;
}
- sname += location.GetName();
- // Append this list entry.
- ss << sname;
+ static std::string output;
+ output = cmJoin(this->Internal->CompileFeaturesEntries, ";");
+ return output.c_str();
}
- this->SetProperty("SOURCES", ss.str().c_str());
- }
-
- // the type property returns what type the target is
- if (!strcmp(prop,"TYPE"))
- {
- return cmTarget::GetTargetTypeName(this->GetType());
- }
- bool chain = false;
- const char *retVal =
- this->Properties.GetPropertyValue(prop, scope, chain);
- if (chain)
- {
- return this->Makefile->GetProperty(prop,scope);
- }
- return retVal;
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::GetPropertyAsBool(const char* prop)
-{
- return cmSystemTools::IsOn(this->GetProperty(prop));
-}
-
-//----------------------------------------------------------------------------
-class cmTargetCollectLinkLanguages
-{
-public:
- cmTargetCollectLinkLanguages(cmTarget* target, const char* config,
- std::set<cmStdString>& languages,
- cmTarget* head):
- Config(config), Languages(languages), HeadTarget(head)
- { this->Visited.insert(target); }
-
- void Visit(cmTarget* target)
- {
- if(!target || !this->Visited.insert(target).second)
+ else if(prop == propCOMPILE_OPTIONS)
{
- return;
- }
-
- cmTarget::LinkInterface const* iface =
- target->GetLinkInterface(this->Config, this->HeadTarget);
- if(!iface) { return; }
+ if (this->Internal->CompileOptionsEntries.empty())
+ {
+ return 0;
+ }
- for(std::vector<std::string>::const_iterator
- li = iface->Languages.begin(); li != iface->Languages.end(); ++li)
- {
- this->Languages.insert(*li);
+ static std::string output;
+ output = cmJoin(this->Internal->CompileOptionsEntries, ";");
+ return output.c_str();
}
+ else if(prop == propCOMPILE_DEFINITIONS)
+ {
+ if (this->Internal->CompileDefinitionsEntries.empty())
+ {
+ return 0;
+ }
- cmMakefile* mf = target->GetMakefile();
- for(std::vector<std::string>::const_iterator
- li = iface->Libraries.begin(); li != iface->Libraries.end(); ++li)
+ static std::string output;
+ output = cmJoin(this->Internal->CompileDefinitionsEntries, ";");
+ return output.c_str();
+ }
+ else if (prop == propIMPORTED)
{
- this->Visit(mf->FindTargetToUse(li->c_str()));
+ return this->IsImported()?"TRUE":"FALSE";
}
- }
-private:
- const char* Config;
- std::set<cmStdString>& Languages;
- cmTarget* HeadTarget;
- std::set<cmTarget*> Visited;
-};
-
-//----------------------------------------------------------------------------
-const char* cmTarget::GetLinkerLanguage(const char* config, cmTarget *head)
-{
- cmTarget *headTarget = head ? head : this;
- const char* lang = this->GetLinkClosure(config, headTarget)
- ->LinkerLanguage.c_str();
- return *lang? lang : 0;
-}
-
-//----------------------------------------------------------------------------
-cmTarget::LinkClosure const* cmTarget::GetLinkClosure(const char* config,
- cmTarget *head)
-{
- TargetConfigPair key(head, cmSystemTools::UpperCase(config ? config : ""));
- cmTargetInternals::LinkClosureMapType::iterator
- i = this->Internal->LinkClosureMap.find(key);
- if(i == this->Internal->LinkClosureMap.end())
- {
- LinkClosure lc;
- this->ComputeLinkClosure(config, lc, head);
- cmTargetInternals::LinkClosureMapType::value_type entry(key, lc);
- i = this->Internal->LinkClosureMap.insert(entry).first;
- }
- return &i->second;
-}
-
-//----------------------------------------------------------------------------
-class cmTargetSelectLinker
-{
- int Preference;
- cmTarget* Target;
- cmMakefile* Makefile;
- cmGlobalGenerator* GG;
- std::set<cmStdString> Preferred;
-public:
- cmTargetSelectLinker(cmTarget* target): Preference(0), Target(target)
- {
- this->Makefile = this->Target->GetMakefile();
- this->GG = this->Makefile->GetLocalGenerator()->GetGlobalGenerator();
- }
- void Consider(const char* lang)
- {
- int preference = this->GG->GetLinkerPreference(lang);
- if(preference > this->Preference)
+ else if (prop == propNAME)
{
- this->Preference = preference;
- this->Preferred.clear();
+ return this->GetName().c_str();
}
- if(preference == this->Preference)
+ else if (prop == propBINARY_DIR)
{
- this->Preferred.insert(lang);
+ return this->GetMakefile()->GetCurrentBinaryDirectory();
}
- }
- std::string Choose()
- {
- if(this->Preferred.empty())
+ else if (prop == propSOURCE_DIR)
{
- return "";
+ return this->GetMakefile()->GetCurrentSourceDirectory();
}
- else if(this->Preferred.size() > 1)
+ else if(prop == propSOURCES)
{
- cmOStringStream e;
- e << "Target " << this->Target->GetName()
- << " contains multiple languages with the highest linker preference"
- << " (" << this->Preference << "):\n";
- for(std::set<cmStdString>::const_iterator
- li = this->Preferred.begin(); li != this->Preferred.end(); ++li)
+ if (this->Internal->SourceEntries.empty())
{
- e << " " << *li << "\n";
+ return 0;
}
- e << "Set the LINKER_LANGUAGE property for this target.";
- cmake* cm = this->Makefile->GetCMakeInstance();
- cm->IssueMessage(cmake::FATAL_ERROR, e.str(),
- this->Target->GetBacktrace());
- }
- return *this->Preferred.begin();
- }
-};
-//----------------------------------------------------------------------------
-void cmTarget::ComputeLinkClosure(const char* config, LinkClosure& lc,
- cmTarget *head)
-{
- // Get languages built in this target.
- std::set<cmStdString> languages;
- LinkImplementation const* impl = this->GetLinkImplementation(config, head);
- for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
- li != impl->Languages.end(); ++li)
- {
- languages.insert(*li);
- }
+ std::ostringstream ss;
+ const char* sep = "";
+ for(std::vector<std::string>::const_iterator
+ i = this->Internal->SourceEntries.begin();
+ i != this->Internal->SourceEntries.end(); ++i)
+ {
+ std::string const& entry = *i;
- // Add interface languages from linked targets.
- cmTargetCollectLinkLanguages cll(this, config, languages, head);
- for(std::vector<std::string>::const_iterator li = impl->Libraries.begin();
- li != impl->Libraries.end(); ++li)
- {
- cll.Visit(this->Makefile->FindTargetToUse(li->c_str()));
- }
+ std::vector<std::string> files;
+ cmSystemTools::ExpandListArgument(entry, files);
+ for (std::vector<std::string>::const_iterator
+ li = files.begin(); li != files.end(); ++li)
+ {
+ if(cmHasLiteralPrefix(*li, "$<TARGET_OBJECTS:") &&
+ (*li)[li->size() - 1] == '>')
+ {
+ std::string objLibName = li->substr(17, li->size()-18);
- // Store the transitive closure of languages.
- for(std::set<cmStdString>::const_iterator li = languages.begin();
- li != languages.end(); ++li)
- {
- lc.Languages.push_back(*li);
- }
+ if (cmGeneratorExpression::Find(objLibName) != std::string::npos)
+ {
+ ss << sep;
+ sep = ";";
+ ss << *li;
+ continue;
+ }
- // Choose the language whose linker should be used.
- if(this->GetProperty("HAS_CXX"))
- {
- lc.LinkerLanguage = "CXX";
- }
- else if(const char* linkerLang = this->GetProperty("LINKER_LANGUAGE"))
- {
- lc.LinkerLanguage = linkerLang;
- }
- else
- {
- // Find the language with the highest preference value.
- cmTargetSelectLinker tsl(this);
+ bool addContent = false;
+ bool noMessage = true;
+ std::ostringstream e;
+ cmake::MessageType messageType = cmake::AUTHOR_WARNING;
+ switch(context->GetPolicyStatus(cmPolicies::CMP0051))
+ {
+ case cmPolicies::WARN:
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0051) << "\n";
+ noMessage = false;
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::NEW:
+ addContent = true;
+ }
+ if (!noMessage)
+ {
+ e << "Target \"" << this->Name << "\" contains "
+ "$<TARGET_OBJECTS> generator expression in its sources list. "
+ "This content was not previously part of the SOURCES property "
+ "when that property was read at configure time. Code reading "
+ "that property needs to be adapted to ignore the generator "
+ "expression using the string(GENEX_STRIP) command.";
+ context->IssueMessage(messageType, e.str());
+ }
+ if (addContent)
+ {
+ ss << sep;
+ sep = ";";
+ ss << *li;
+ }
+ }
+ else if (cmGeneratorExpression::Find(*li) == std::string::npos)
+ {
+ ss << sep;
+ sep = ";";
+ ss << *li;
+ }
+ else
+ {
+ cmSourceFile *sf = this->Makefile->GetOrCreateSource(*li);
+ // Construct what is known about this source file location.
+ cmSourceFileLocation const& location = sf->GetLocation();
+ std::string sname = location.GetDirectory();
+ if(!sname.empty())
+ {
+ sname += "/";
+ }
+ sname += location.GetName();
- // First select from the languages compiled directly in this target.
- for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
- li != impl->Languages.end(); ++li)
- {
- tsl.Consider(li->c_str());
+ ss << sep;
+ sep = ";";
+ // Append this list entry.
+ ss << sname;
+ }
+ }
+ }
+ this->Properties.SetProperty("SOURCES", ss.str().c_str());
}
+ }
- // Now consider languages that propagate from linked targets.
- for(std::set<cmStdString>::const_iterator sit = languages.begin();
- sit != languages.end(); ++sit)
+ const char *retVal = this->Properties.GetPropertyValue(prop);
+ if (!retVal)
+ {
+ const bool chain = this->GetMakefile()->GetState()->
+ IsPropertyChained(prop, cmProperty::TARGET);
+ if (chain)
{
- std::string propagates = "CMAKE_"+*sit+"_LINKER_PREFERENCE_PROPAGATES";
- if(this->Makefile->IsOn(propagates.c_str()))
- {
- tsl.Consider(sit->c_str());
- }
+ return this->Makefile->GetProperty(prop, chain);
}
-
- lc.LinkerLanguage = tsl.Choose();
}
+ return retVal;
+}
+
+//----------------------------------------------------------------------------
+bool cmTarget::GetPropertyAsBool(const std::string& prop) const
+{
+ return cmSystemTools::IsOn(this->GetProperty(prop));
}
//----------------------------------------------------------------------------
-const char* cmTarget::GetSuffixVariableInternal(bool implib)
+const char* cmTarget::GetSuffixVariableInternal(bool implib) const
{
switch(this->GetType())
{
- case cmTarget::STATIC_LIBRARY:
+ case cmState::STATIC_LIBRARY:
return "CMAKE_STATIC_LIBRARY_SUFFIX";
- case cmTarget::SHARED_LIBRARY:
+ case cmState::SHARED_LIBRARY:
return (implib
? "CMAKE_IMPORT_LIBRARY_SUFFIX"
: "CMAKE_SHARED_LIBRARY_SUFFIX");
- case cmTarget::MODULE_LIBRARY:
+ case cmState::MODULE_LIBRARY:
return (implib
? "CMAKE_IMPORT_LIBRARY_SUFFIX"
: "CMAKE_SHARED_MODULE_SUFFIX");
- case cmTarget::EXECUTABLE:
+ case cmState::EXECUTABLE:
return (implib
? "CMAKE_IMPORT_LIBRARY_SUFFIX"
- : "CMAKE_EXECUTABLE_SUFFIX");
+ // Android GUI application packages store the native
+ // binary as a shared library.
+ : (this->IsAndroid && this->GetPropertyAsBool("ANDROID_GUI")?
+ "CMAKE_SHARED_LIBRARY_SUFFIX" : "CMAKE_EXECUTABLE_SUFFIX"));
default:
break;
}
@@ -4443,22 +1907,27 @@ const char* cmTarget::GetSuffixVariableInternal(bool implib)
//----------------------------------------------------------------------------
-const char* cmTarget::GetPrefixVariableInternal(bool implib)
+const char* cmTarget::GetPrefixVariableInternal(bool implib) const
{
switch(this->GetType())
{
- case cmTarget::STATIC_LIBRARY:
+ case cmState::STATIC_LIBRARY:
return "CMAKE_STATIC_LIBRARY_PREFIX";
- case cmTarget::SHARED_LIBRARY:
+ case cmState::SHARED_LIBRARY:
return (implib
? "CMAKE_IMPORT_LIBRARY_PREFIX"
: "CMAKE_SHARED_LIBRARY_PREFIX");
- case cmTarget::MODULE_LIBRARY:
+ case cmState::MODULE_LIBRARY:
return (implib
? "CMAKE_IMPORT_LIBRARY_PREFIX"
: "CMAKE_SHARED_MODULE_PREFIX");
- case cmTarget::EXECUTABLE:
- return (implib? "CMAKE_IMPORT_LIBRARY_PREFIX" : "");
+ case cmState::EXECUTABLE:
+ return (implib
+ ? "CMAKE_IMPORT_LIBRARY_PREFIX"
+ // Android GUI application packages store the native
+ // binary as a shared library.
+ : (this->IsAndroid && this->GetPropertyAsBool("ANDROID_GUI")?
+ "CMAKE_SHARED_LIBRARY_PREFIX" : ""));
default:
break;
}
@@ -4466,293 +1935,76 @@ const char* cmTarget::GetPrefixVariableInternal(bool implib)
}
//----------------------------------------------------------------------------
-std::string cmTarget::GetPDBName(const char* config)
+std::string
+cmTarget::ImportedGetFullPath(const std::string& config, bool pimplib) const
{
- std::string prefix;
- std::string base;
- std::string suffix;
- this->GetFullNameInternal(config, false, prefix, base, suffix);
+ assert(this->IsImported());
- std::vector<std::string> props;
- std::string configUpper =
- cmSystemTools::UpperCase(config? config : "");
- if(!configUpper.empty())
+ // Lookup/compute/cache the import information for this
+ // configuration.
+ std::string config_upper;
+ if(!config.empty())
{
- // PDB_NAME_<CONFIG>
- props.push_back("PDB_NAME_" + configUpper);
+ config_upper = cmSystemTools::UpperCase(config);
}
-
- // PDB_NAME
- props.push_back("PDB_NAME");
-
- for(std::vector<std::string>::const_iterator i = props.begin();
- i != props.end(); ++i)
+ else
{
- if(const char* outName = this->GetProperty(i->c_str()))
- {
- base = outName;
- break;
- }
+ config_upper = "NOCONFIG";
}
- return prefix+base+".pdb";
-}
-//----------------------------------------------------------------------------
-bool cmTarget::HasSOName(const char* config)
-{
- // soname is supported only for shared libraries and modules,
- // and then only when the platform supports an soname flag.
- return ((this->GetType() == cmTarget::SHARED_LIBRARY ||
- this->GetType() == cmTarget::MODULE_LIBRARY) &&
- !this->GetPropertyAsBool("NO_SONAME") &&
- this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config,
- this)));
-}
+ std::string result;
-//----------------------------------------------------------------------------
-std::string cmTarget::GetSOName(const char* config)
-{
- if(this->IsImported())
+ const char* loc = 0;
+ const char* imp = 0;
+ std::string suffix;
+
+ if(this->GetType() != cmState::INTERFACE_LIBRARY
+ && this->GetMappedConfig(config_upper, &loc, &imp, suffix))
{
- // Lookup the imported soname.
- if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this))
+ if (!pimplib)
{
- if(info->NoSOName)
+ if(loc)
{
- // The imported library has no builtin soname so the name
- // searched at runtime will be just the filename.
- return cmSystemTools::GetFilenameName(info->Location);
+ result = loc;
}
else
{
- // Use the soname given if any.
- if(info->SOName.find("@rpath/") == 0)
+ std::string impProp = "IMPORTED_LOCATION";
+ impProp += suffix;
+ if(const char* config_location = this->GetProperty(impProp))
{
- return info->SOName.substr(6);
+ result = config_location;
+ }
+ else if(const char* location =
+ this->GetProperty("IMPORTED_LOCATION"))
+ {
+ result = location;
}
- return info->SOName;
}
}
else
{
- return "";
- }
- }
- else
- {
- // Compute the soname that will be built.
- std::string name;
- std::string soName;
- std::string realName;
- std::string impName;
- std::string pdbName;
- this->GetLibraryNames(name, soName, realName, impName, pdbName, config);
- return soName;
- }
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::HasMacOSXRpath(const char* config)
-{
- bool install_name_is_rpath = false;
- bool macosx_rpath = this->GetPropertyAsBool("MACOSX_RPATH");
-
- if(!this->IsImportedTarget)
- {
- const char* install_name = this->GetProperty("INSTALL_NAME_DIR");
- bool use_install_name =
- this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH");
- if(install_name && use_install_name &&
- std::string(install_name) == "@rpath")
- {
- install_name_is_rpath = true;
- }
- else if(install_name && use_install_name)
- {
- return false;
- }
- }
- else
- {
- // Lookup the imported soname.
- if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this))
- {
- if(!info->NoSOName && !info->SOName.empty())
+ if(imp)
{
- if(info->SOName.find("@rpath/") == 0)
- {
- install_name_is_rpath = true;
- }
+ result = imp;
}
- else
+ else if(this->GetType() == cmState::SHARED_LIBRARY ||
+ this->IsExecutableWithExports())
{
- std::string install_name;
- cmSystemTools::GuessLibraryInstallName(info->Location, install_name);
- if(install_name.find("@rpath") != std::string::npos)
+ std::string impProp = "IMPORTED_IMPLIB";
+ impProp += suffix;
+ if(const char* config_implib = this->GetProperty(impProp))
{
- install_name_is_rpath = true;
+ result = config_implib;
+ }
+ else if(const char* implib = this->GetProperty("IMPORTED_IMPLIB"))
+ {
+ result = implib;
}
}
}
}
- if(!install_name_is_rpath && !macosx_rpath)
- {
- return false;
- }
-
- if(!this->Makefile->IsSet("CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG"))
- {
- cmOStringStream w;
- w << "Attempting to use";
- if(macosx_rpath)
- {
- w << " MACOSX_RPATH";
- }
- else
- {
- w << " @rpath";
- }
- w << " without CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG being set.";
- w << " This could be because you are using a Mac OS X version";
- w << " less than 10.5 or because CMake's platform configuration is";
- w << " corrupt.";
- cmake* cm = this->Makefile->GetCMakeInstance();
- cm->IssueMessage(cmake::FATAL_ERROR, w.str(), this->GetBacktrace());
- }
-
- return true;
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::IsImportedSharedLibWithoutSOName(const char* config)
-{
- if(this->IsImported() && this->GetType() == cmTarget::SHARED_LIBRARY)
- {
- if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this))
- {
- return info->NoSOName;
- }
- }
- return false;
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::NormalGetRealName(const char* config)
-{
- // This should not be called for imported targets.
- // TODO: Split cmTarget into a class hierarchy to get compile-time
- // enforcement of the limited imported target API.
- if(this->IsImported())
- {
- std::string msg = "NormalGetRealName called on imported target: ";
- msg += this->GetName();
- this->GetMakefile()->
- IssueMessage(cmake::INTERNAL_ERROR,
- msg.c_str());
- }
-
- if(this->GetType() == cmTarget::EXECUTABLE)
- {
- // Compute the real name that will be built.
- std::string name;
- std::string realName;
- std::string impName;
- std::string pdbName;
- this->GetExecutableNames(name, realName, impName, pdbName, config);
- return realName;
- }
- else
- {
- // Compute the real name that will be built.
- std::string name;
- std::string soName;
- std::string realName;
- std::string impName;
- std::string pdbName;
- this->GetLibraryNames(name, soName, realName, impName, pdbName, config);
- return realName;
- }
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetFullName(const char* config, bool implib)
-{
- if(this->IsImported())
- {
- return this->GetFullNameImported(config, implib);
- }
- else
- {
- return this->GetFullNameInternal(config, implib);
- }
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetFullNameImported(const char* config, bool implib)
-{
- return cmSystemTools::GetFilenameName(
- this->ImportedGetFullPath(config, implib));
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GetFullNameComponents(std::string& prefix, std::string& base,
- std::string& suffix, const char* config,
- bool implib)
-{
- this->GetFullNameInternal(config, implib, prefix, base, suffix);
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetFullPath(const char* config, bool implib,
- bool realname)
-{
- if(this->IsImported())
- {
- return this->ImportedGetFullPath(config, implib);
- }
- else
- {
- return this->NormalGetFullPath(config, implib, realname);
- }
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::NormalGetFullPath(const char* config, bool implib,
- bool realname)
-{
- std::string fpath = this->GetDirectory(config, implib);
- fpath += "/";
- if(this->IsAppBundleOnApple())
- {
- fpath = this->BuildMacContentDirectory(fpath, config, false);
- fpath += "/";
- }
-
- // Add the full name of the target.
- if(implib)
- {
- fpath += this->GetFullName(config, true);
- }
- else if(realname)
- {
- fpath += this->NormalGetRealName(config);
- }
- else
- {
- fpath += this->GetFullName(config, false);
- }
- return fpath;
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::ImportedGetFullPath(const char* config, bool implib)
-{
- std::string result;
- if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this))
- {
- result = implib? info->ImportLibrary : info->Location;
- }
if(result.empty())
{
result = this->GetName();
@@ -4762,416 +2014,14 @@ std::string cmTarget::ImportedGetFullPath(const char* config, bool implib)
}
//----------------------------------------------------------------------------
-std::string cmTarget::GetFullNameInternal(const char* config, bool implib)
-{
- std::string prefix;
- std::string base;
- std::string suffix;
- this->GetFullNameInternal(config, implib, prefix, base, suffix);
- return prefix+base+suffix;
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GetFullNameInternal(const char* config,
- bool implib,
- std::string& outPrefix,
- std::string& outBase,
- std::string& outSuffix)
-{
- // Use just the target name for non-main target types.
- if(this->GetType() != cmTarget::STATIC_LIBRARY &&
- this->GetType() != cmTarget::SHARED_LIBRARY &&
- this->GetType() != cmTarget::MODULE_LIBRARY &&
- this->GetType() != cmTarget::EXECUTABLE)
- {
- outPrefix = "";
- outBase = this->GetName();
- outSuffix = "";
- return;
- }
-
- // Return an empty name for the import library if this platform
- // does not support import libraries.
- if(implib &&
- !this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"))
- {
- outPrefix = "";
- outBase = "";
- outSuffix = "";
- return;
- }
-
- // The implib option is only allowed for shared libraries, module
- // libraries, and executables.
- if(this->GetType() != cmTarget::SHARED_LIBRARY &&
- this->GetType() != cmTarget::MODULE_LIBRARY &&
- this->GetType() != cmTarget::EXECUTABLE)
- {
- implib = false;
- }
-
- // Compute the full name for main target types.
- const char* targetPrefix = (implib
- ? this->GetProperty("IMPORT_PREFIX")
- : this->GetProperty("PREFIX"));
- const char* targetSuffix = (implib
- ? this->GetProperty("IMPORT_SUFFIX")
- : this->GetProperty("SUFFIX"));
- const char* configPostfix = 0;
- if(config && *config)
- {
- std::string configProp = cmSystemTools::UpperCase(config);
- configProp += "_POSTFIX";
- configPostfix = this->GetProperty(configProp.c_str());
- // Mac application bundles and frameworks have no postfix.
- if(configPostfix &&
- (this->IsAppBundleOnApple() || this->IsFrameworkOnApple()))
- {
- configPostfix = 0;
- }
- }
- const char* prefixVar = this->GetPrefixVariableInternal(implib);
- const char* suffixVar = this->GetSuffixVariableInternal(implib);
-
- // Check for language-specific default prefix and suffix.
- if(const char* ll = this->GetLinkerLanguage(config, this))
- {
- if(!targetSuffix && suffixVar && *suffixVar)
- {
- std::string langSuff = suffixVar + std::string("_") + ll;
- targetSuffix = this->Makefile->GetDefinition(langSuff.c_str());
- }
- if(!targetPrefix && prefixVar && *prefixVar)
- {
- std::string langPrefix = prefixVar + std::string("_") + ll;
- targetPrefix = this->Makefile->GetDefinition(langPrefix.c_str());
- }
- }
-
- // if there is no prefix on the target use the cmake definition
- if(!targetPrefix && prefixVar)
- {
- targetPrefix = this->Makefile->GetSafeDefinition(prefixVar);
- }
- // if there is no suffix on the target use the cmake definition
- if(!targetSuffix && suffixVar)
- {
- targetSuffix = this->Makefile->GetSafeDefinition(suffixVar);
- }
-
- // frameworks have directory prefix but no suffix
- std::string fw_prefix;
- if(this->IsFrameworkOnApple())
- {
- fw_prefix = this->GetOutputName(config, false);
- fw_prefix += ".framework/";
- targetPrefix = fw_prefix.c_str();
- targetSuffix = 0;
- }
-
- if(this->IsCFBundleOnApple())
- {
- fw_prefix = this->GetOutputName(config, false);
- fw_prefix += ".";
- const char *ext = this->GetProperty("BUNDLE_EXTENSION");
- if (!ext)
- {
- ext = "bundle";
- }
- fw_prefix += ext;
- fw_prefix += "/Contents/MacOS/";
- targetPrefix = fw_prefix.c_str();
- targetSuffix = 0;
- }
-
- // Begin the final name with the prefix.
- outPrefix = targetPrefix?targetPrefix:"";
-
- // Append the target name or property-specified name.
- outBase += this->GetOutputName(config, implib);
-
- // Append the per-configuration postfix.
- outBase += configPostfix?configPostfix:"";
-
- // Name shared libraries with their version number on some platforms.
- if(const char* soversion = this->GetProperty("SOVERSION"))
- {
- if(this->GetType() == cmTarget::SHARED_LIBRARY && !implib &&
- this->Makefile->IsOn("CMAKE_SHARED_LIBRARY_NAME_WITH_VERSION"))
- {
- outBase += "-";
- outBase += soversion;
- }
- }
-
- // Append the suffix.
- outSuffix = targetSuffix?targetSuffix:"";
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GetLibraryNames(std::string& name,
- std::string& soName,
- std::string& realName,
- std::string& impName,
- std::string& pdbName,
- const char* config)
-{
- // This should not be called for imported targets.
- // TODO: Split cmTarget into a class hierarchy to get compile-time
- // enforcement of the limited imported target API.
- if(this->IsImported())
- {
- std::string msg = "GetLibraryNames called on imported target: ";
- msg += this->GetName();
- this->Makefile->IssueMessage(cmake::INTERNAL_ERROR,
- msg.c_str());
- return;
- }
-
- // Check for library version properties.
- const char* version = this->GetProperty("VERSION");
- const char* soversion = this->GetProperty("SOVERSION");
- if(!this->HasSOName(config) ||
- this->IsFrameworkOnApple())
- {
- // Versioning is supported only for shared libraries and modules,
- // and then only when the platform supports an soname flag.
- version = 0;
- soversion = 0;
- }
- if(version && !soversion)
- {
- // The soversion must be set if the library version is set. Use
- // the library version as the soversion.
- soversion = version;
- }
- if(!version && soversion)
- {
- // Use the soversion as the library version.
- version = soversion;
- }
-
- // Get the components of the library name.
- std::string prefix;
- std::string base;
- std::string suffix;
- this->GetFullNameInternal(config, false, prefix, base, suffix);
-
- // The library name.
- name = prefix+base+suffix;
-
- if(this->IsFrameworkOnApple())
- {
- realName = prefix;
- realName += "Versions/";
- realName += this->GetFrameworkVersion();
- realName += "/";
- realName += base;
- soName = realName;
- }
- else
- {
- // The library's soname.
- this->ComputeVersionedName(soName, prefix, base, suffix,
- name, soversion);
- // The library's real name on disk.
- this->ComputeVersionedName(realName, prefix, base, suffix,
- name, version);
- }
-
- // The import library name.
- if(this->GetType() == cmTarget::SHARED_LIBRARY ||
- this->GetType() == cmTarget::MODULE_LIBRARY)
- {
- impName = this->GetFullNameInternal(config, true);
- }
- else
- {
- impName = "";
- }
-
- // The program database file name.
- pdbName = this->GetPDBName(config);
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::ComputeVersionedName(std::string& vName,
- std::string const& prefix,
- std::string const& base,
- std::string const& suffix,
- std::string const& name,
- const char* version)
-{
- vName = this->IsApple? (prefix+base) : name;
- if(version)
- {
- vName += ".";
- vName += version;
- }
- vName += this->IsApple? suffix : std::string();
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GetExecutableNames(std::string& name,
- std::string& realName,
- std::string& impName,
- std::string& pdbName,
- const char* config)
-{
- // This should not be called for imported targets.
- // TODO: Split cmTarget into a class hierarchy to get compile-time
- // enforcement of the limited imported target API.
- if(this->IsImported())
- {
- std::string msg =
- "GetExecutableNames called on imported target: ";
- msg += this->GetName();
- this->GetMakefile()->IssueMessage(cmake::INTERNAL_ERROR, msg.c_str());
- }
-
- // This versioning is supported only for executables and then only
- // when the platform supports symbolic links.
-#if defined(_WIN32) && !defined(__CYGWIN__)
- const char* version = 0;
-#else
- // Check for executable version properties.
- const char* version = this->GetProperty("VERSION");
- if(this->GetType() != cmTarget::EXECUTABLE || this->Makefile->IsOn("XCODE"))
- {
- version = 0;
- }
-#endif
-
- // Get the components of the executable name.
- std::string prefix;
- std::string base;
- std::string suffix;
- this->GetFullNameInternal(config, false, prefix, base, suffix);
-
- // The executable name.
- name = prefix+base+suffix;
-
- // The executable's real name on disk.
-#if defined(__CYGWIN__)
- realName = prefix+base;
-#else
- realName = name;
-#endif
- if(version)
- {
- realName += "-";
- realName += version;
- }
-#if defined(__CYGWIN__)
- realName += suffix;
-#endif
-
- // The import library name.
- impName = this->GetFullNameInternal(config, true);
-
- // The program database file name.
- pdbName = this->GetPDBName(config);
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::HasImplibGNUtoMS()
-{
- return this->HasImportLibrary() && this->GetPropertyAsBool("GNUtoMS");
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::GetImplibGNUtoMS(std::string const& gnuName,
- std::string& out, const char* newExt)
-{
- if(this->HasImplibGNUtoMS() &&
- gnuName.size() > 6 && gnuName.substr(gnuName.size()-6) == ".dll.a")
- {
- out = gnuName.substr(0, gnuName.size()-6);
- out += newExt? newExt : ".lib";
- return true;
- }
- return false;
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GenerateTargetManifest(const char* config)
-{
- cmMakefile* mf = this->Makefile;
- cmLocalGenerator* lg = mf->GetLocalGenerator();
- cmGlobalGenerator* gg = lg->GetGlobalGenerator();
-
- // Get the names.
- std::string name;
- std::string soName;
- std::string realName;
- std::string impName;
- std::string pdbName;
- if(this->GetType() == cmTarget::EXECUTABLE)
- {
- this->GetExecutableNames(name, realName, impName, pdbName, config);
- }
- else if(this->GetType() == cmTarget::STATIC_LIBRARY ||
- this->GetType() == cmTarget::SHARED_LIBRARY ||
- this->GetType() == cmTarget::MODULE_LIBRARY)
- {
- this->GetLibraryNames(name, soName, realName, impName, pdbName, config);
- }
- else
- {
- return;
- }
-
- // Get the directory.
- std::string dir = this->GetDirectory(config, false);
-
- // Add each name.
- std::string f;
- if(!name.empty())
- {
- f = dir;
- f += "/";
- f += name;
- gg->AddToManifest(config? config:"", f);
- }
- if(!soName.empty())
- {
- f = dir;
- f += "/";
- f += soName;
- gg->AddToManifest(config? config:"", f);
- }
- if(!realName.empty())
- {
- f = dir;
- f += "/";
- f += realName;
- gg->AddToManifest(config? config:"", f);
- }
- if(!pdbName.empty())
- {
- f = this->GetPDBDirectory(config);
- f += "/";
- f += pdbName;
- gg->AddToManifest(config? config:"", f);
- }
- if(!impName.empty())
- {
- f = this->GetDirectory(config, true);
- f += "/";
- f += impName;
- gg->AddToManifest(config? config:"", f);
- }
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::SetPropertyDefault(const char* property,
+void cmTarget::SetPropertyDefault(const std::string& property,
const char* default_value)
{
// Compute the name of the variable holding the default value.
std::string var = "CMAKE_";
var += property;
- if(const char* value = this->Makefile->GetDefinition(var.c_str()))
+ if(const char* value = this->Makefile->GetDefinition(var))
{
this->SetProperty(property, value);
}
@@ -5181,837 +2031,20 @@ void cmTarget::SetPropertyDefault(const char* property,
}
}
-//----------------------------------------------------------------------------
-bool cmTarget::HaveBuildTreeRPATH(const char *config)
-{
- if (this->GetPropertyAsBool("SKIP_BUILD_RPATH"))
- {
- return false;
- }
- std::vector<std::string> libs;
- this->GetDirectLinkLibraries(config, libs, this);
- return !libs.empty();
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::HaveInstallTreeRPATH()
-{
- const char* install_rpath = this->GetProperty("INSTALL_RPATH");
- return (install_rpath && *install_rpath) &&
- !this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH");
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::NeedRelinkBeforeInstall(const char* config)
-{
- // Only executables and shared libraries can have an rpath and may
- // need relinking.
- if(this->TargetTypeValue != cmTarget::EXECUTABLE &&
- this->TargetTypeValue != cmTarget::SHARED_LIBRARY &&
- this->TargetTypeValue != cmTarget::MODULE_LIBRARY)
- {
- return false;
- }
-
- // If there is no install location this target will not be installed
- // and therefore does not need relinking.
- if(!this->GetHaveInstallRule())
- {
- return false;
- }
-
- // If skipping all rpaths completely then no relinking is needed.
- if(this->Makefile->IsOn("CMAKE_SKIP_RPATH"))
- {
- return false;
- }
-
- // If building with the install-tree rpath no relinking is needed.
- if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
- {
- return false;
- }
-
- // If chrpath is going to be used no relinking is needed.
- if(this->IsChrpathUsed(config))
- {
- return false;
- }
-
- // Check for rpath support on this platform.
- if(const char* ll = this->GetLinkerLanguage(config, this))
- {
- std::string flagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
- flagVar += ll;
- flagVar += "_FLAG";
- if(!this->Makefile->IsSet(flagVar.c_str()))
- {
- // There is no rpath support on this platform so nothing needs
- // relinking.
- return false;
- }
- }
- else
- {
- // No linker language is known. This error will be reported by
- // other code.
- return false;
- }
-
- // If either a build or install tree rpath is set then the rpath
- // will likely change between the build tree and install tree and
- // this target must be relinked.
- return this->HaveBuildTreeRPATH(config) || this->HaveInstallTreeRPATH();
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetInstallNameDirForBuildTree(const char* config)
-{
- // If building directly for installation then the build tree install_name
- // is the same as the install tree.
- if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
- {
- return GetInstallNameDirForInstallTree();
- }
-
- // Use the build tree directory for the target.
- if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME") &&
- !this->Makefile->IsOn("CMAKE_SKIP_RPATH") &&
- !this->GetPropertyAsBool("SKIP_BUILD_RPATH"))
- {
- std::string dir;
- if(this->GetPropertyAsBool("MACOSX_RPATH"))
- {
- dir = "@rpath";
- }
- else
- {
- dir = this->GetDirectory(config);
- }
- dir += "/";
- return dir;
- }
- else
- {
- return "";
- }
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetInstallNameDirForInstallTree()
-{
- if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
- {
- std::string dir;
- const char* install_name_dir = this->GetProperty("INSTALL_NAME_DIR");
-
- if(!this->Makefile->IsOn("CMAKE_SKIP_RPATH") &&
- !this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH"))
- {
- if(install_name_dir && *install_name_dir)
- {
- dir = install_name_dir;
- dir += "/";
- }
- }
- if(!install_name_dir && this->GetPropertyAsBool("MACOSX_RPATH"))
- {
- dir = "@rpath/";
- }
- return dir;
- }
- else
- {
- return "";
- }
-}
-
-//----------------------------------------------------------------------------
-const char* cmTarget::GetOutputTargetType(bool implib)
-{
- switch(this->GetType())
- {
- case cmTarget::SHARED_LIBRARY:
- if(this->DLLPlatform)
- {
- if(implib)
- {
- // A DLL import library is treated as an archive target.
- return "ARCHIVE";
- }
- else
- {
- // A DLL shared library is treated as a runtime target.
- return "RUNTIME";
- }
- }
- else
- {
- // For non-DLL platforms shared libraries are treated as
- // library targets.
- return "LIBRARY";
- }
- case cmTarget::STATIC_LIBRARY:
- // Static libraries are always treated as archive targets.
- return "ARCHIVE";
- case cmTarget::MODULE_LIBRARY:
- if(implib)
- {
- // Module libraries are always treated as library targets.
- return "ARCHIVE";
- }
- else
- {
- // Module import libraries are treated as archive targets.
- return "LIBRARY";
- }
- case cmTarget::EXECUTABLE:
- if(implib)
- {
- // Executable import libraries are treated as archive targets.
- return "ARCHIVE";
- }
- else
- {
- // Executables are always treated as runtime targets.
- return "RUNTIME";
- }
- default:
- break;
- }
- return "";
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::ComputeOutputDir(const char* config,
- bool implib, std::string& out)
-{
- bool usesDefaultOutputDir = false;
-
- // Look for a target property defining the target output directory
- // based on the target type.
- std::string targetTypeName = this->GetOutputTargetType(implib);
- const char* propertyName = 0;
- std::string propertyNameStr = targetTypeName;
- if(!propertyNameStr.empty())
- {
- propertyNameStr += "_OUTPUT_DIRECTORY";
- propertyName = propertyNameStr.c_str();
- }
-
- // Check for a per-configuration output directory target property.
- std::string configUpper = cmSystemTools::UpperCase(config? config : "");
- const char* configProp = 0;
- std::string configPropStr = targetTypeName;
- if(!configPropStr.empty())
- {
- configPropStr += "_OUTPUT_DIRECTORY_";
- configPropStr += configUpper;
- configProp = configPropStr.c_str();
- }
-
- // Select an output directory.
- if(const char* config_outdir = this->GetProperty(configProp))
- {
- // Use the user-specified per-configuration output directory.
- out = config_outdir;
-
- // Skip per-configuration subdirectory.
- config = 0;
- }
- else if(const char* outdir = this->GetProperty(propertyName))
- {
- // Use the user-specified output directory.
- out = outdir;
- }
- else if(this->GetType() == cmTarget::EXECUTABLE)
- {
- // Lookup the output path for executables.
- out = this->Makefile->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH");
- }
- else if(this->GetType() == cmTarget::STATIC_LIBRARY ||
- this->GetType() == cmTarget::SHARED_LIBRARY ||
- this->GetType() == cmTarget::MODULE_LIBRARY)
- {
- // Lookup the output path for libraries.
- out = this->Makefile->GetSafeDefinition("LIBRARY_OUTPUT_PATH");
- }
- if(out.empty())
- {
- // Default to the current output directory.
- usesDefaultOutputDir = true;
- out = ".";
- }
-
- // Convert the output path to a full path in case it is
- // specified as a relative path. Treat a relative path as
- // relative to the current output directory for this makefile.
- out = (cmSystemTools::CollapseFullPath
- (out.c_str(), this->Makefile->GetStartOutputDirectory()));
-
- // The generator may add the configuration's subdirectory.
- if(config && *config)
- {
- const char *platforms = this->Makefile->GetDefinition(
- "CMAKE_XCODE_EFFECTIVE_PLATFORMS");
- std::string suffix =
- usesDefaultOutputDir && platforms ? "$(EFFECTIVE_PLATFORM_NAME)" : "";
- this->Makefile->GetLocalGenerator()->GetGlobalGenerator()->
- AppendDirectoryForConfig("/", config, suffix.c_str(), out);
- }
-
- return usesDefaultOutputDir;
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::ComputePDBOutputDir(const char* config, std::string& out)
-{
- // Look for a target property defining the target output directory
- // based on the target type.
- std::string targetTypeName = "PDB";
- const char* propertyName = 0;
- std::string propertyNameStr = targetTypeName;
- if(!propertyNameStr.empty())
- {
- propertyNameStr += "_OUTPUT_DIRECTORY";
- propertyName = propertyNameStr.c_str();
- }
-
- // Check for a per-configuration output directory target property.
- std::string configUpper = cmSystemTools::UpperCase(config? config : "");
- const char* configProp = 0;
- std::string configPropStr = targetTypeName;
- if(!configPropStr.empty())
- {
- configPropStr += "_OUTPUT_DIRECTORY_";
- configPropStr += configUpper;
- configProp = configPropStr.c_str();
- }
-
- // Select an output directory.
- if(const char* config_outdir = this->GetProperty(configProp))
- {
- // Use the user-specified per-configuration output directory.
- out = config_outdir;
-
- // Skip per-configuration subdirectory.
- config = 0;
- }
- else if(const char* outdir = this->GetProperty(propertyName))
- {
- // Use the user-specified output directory.
- out = outdir;
- }
- if(out.empty())
- {
- return false;
- }
-
- // Convert the output path to a full path in case it is
- // specified as a relative path. Treat a relative path as
- // relative to the current output directory for this makefile.
- out = (cmSystemTools::CollapseFullPath
- (out.c_str(), this->Makefile->GetStartOutputDirectory()));
-
- // The generator may add the configuration's subdirectory.
- if(config && *config)
- {
- this->Makefile->GetLocalGenerator()->GetGlobalGenerator()->
- AppendDirectoryForConfig("/", config, "", out);
- }
- return true;
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::UsesDefaultOutputDir(const char* config, bool implib)
-{
- std::string dir;
- return this->ComputeOutputDir(config, implib, dir);
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetOutputName(const char* config, bool implib)
-{
- std::vector<std::string> props;
- std::string type = this->GetOutputTargetType(implib);
- std::string configUpper = cmSystemTools::UpperCase(config? config : "");
- if(!type.empty() && !configUpper.empty())
- {
- // <ARCHIVE|LIBRARY|RUNTIME>_OUTPUT_NAME_<CONFIG>
- props.push_back(type + "_OUTPUT_NAME_" + configUpper);
- }
- if(!type.empty())
- {
- // <ARCHIVE|LIBRARY|RUNTIME>_OUTPUT_NAME
- props.push_back(type + "_OUTPUT_NAME");
- }
- if(!configUpper.empty())
- {
- // OUTPUT_NAME_<CONFIG>
- props.push_back("OUTPUT_NAME_" + configUpper);
- // <CONFIG>_OUTPUT_NAME
- props.push_back(configUpper + "_OUTPUT_NAME");
- }
- // OUTPUT_NAME
- props.push_back("OUTPUT_NAME");
-
- for(std::vector<std::string>::const_iterator i = props.begin();
- i != props.end(); ++i)
- {
- if(const char* outName = this->GetProperty(i->c_str()))
- {
- return outName;
- }
- }
- return this->GetName();
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetFrameworkVersion()
-{
- if(const char* fversion = this->GetProperty("FRAMEWORK_VERSION"))
- {
- return fversion;
- }
- else if(const char* tversion = this->GetProperty("VERSION"))
- {
- return tversion;
- }
- else
- {
- return "A";
- }
-}
-
-//----------------------------------------------------------------------------
-const char* cmTarget::GetExportMacro()
-{
- // Define the symbol for targets that export symbols.
- if(this->GetType() == cmTarget::SHARED_LIBRARY ||
- this->GetType() == cmTarget::MODULE_LIBRARY ||
- this->IsExecutableWithExports())
- {
- if(const char* custom_export_name = this->GetProperty("DEFINE_SYMBOL"))
- {
- this->ExportMacro = custom_export_name;
- }
- else
- {
- std::string in = this->GetName();
- in += "_EXPORTS";
- this->ExportMacro = cmSystemTools::MakeCindentifier(in.c_str());
- }
- return this->ExportMacro.c_str();
- }
- else
- {
- return 0;
- }
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::IsNullImpliedByLinkLibraries(const std::string &p)
-{
- return this->LinkImplicitNullProperties.find(p)
- != this->LinkImplicitNullProperties.end();
-}
-
-//----------------------------------------------------------------------------
-template<typename PropertyType>
-PropertyType getTypedProperty(cmTarget *tgt, const char *prop,
- PropertyType *);
-
-//----------------------------------------------------------------------------
-template<>
-bool getTypedProperty<bool>(cmTarget *tgt, const char *prop, bool *)
-{
- return tgt->GetPropertyAsBool(prop);
-}
-
-//----------------------------------------------------------------------------
-template<>
-const char *getTypedProperty<const char *>(cmTarget *tgt, const char *prop,
- const char **)
-{
- return tgt->GetProperty(prop);
-}
-
-//----------------------------------------------------------------------------
-template<typename PropertyType>
-bool consistentProperty(PropertyType lhs, PropertyType rhs);
-
-//----------------------------------------------------------------------------
-template<>
-bool consistentProperty(bool lhs, bool rhs)
-{
- return lhs == rhs;
-}
-
-//----------------------------------------------------------------------------
-template<>
-bool consistentProperty(const char *lhs, const char *rhs)
-{
- if (!lhs && !rhs)
- return true;
- if (!lhs || !rhs)
- return false;
- return strcmp(lhs, rhs) == 0;
-}
-
-//----------------------------------------------------------------------------
-template<typename PropertyType>
-PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt,
- const std::string &p,
- const char *config,
- const char *defaultValue,
- PropertyType *)
-{
- PropertyType propContent = getTypedProperty<PropertyType>(tgt, p.c_str(),
- 0);
- const bool explicitlySet = tgt->GetProperties()
- .find(p.c_str())
- != tgt->GetProperties().end();
- const bool impliedByUse =
- tgt->IsNullImpliedByLinkLibraries(p);
- assert((impliedByUse ^ explicitlySet)
- || (!impliedByUse && !explicitlySet));
-
- cmComputeLinkInformation *info = tgt->GetLinkInformation(config);
- if(!info)
- {
- return propContent;
- }
- const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
- bool propInitialized = explicitlySet;
-
- for(cmComputeLinkInformation::ItemVector::const_iterator li =
- deps.begin();
- li != deps.end(); ++li)
- {
- // An error should be reported if one dependency
- // has INTERFACE_POSITION_INDEPENDENT_CODE ON and the other
- // has INTERFACE_POSITION_INDEPENDENT_CODE OFF, or if the
- // target itself has a POSITION_INDEPENDENT_CODE which disagrees
- // with a dependency.
-
- if (!li->Target)
- {
- continue;
- }
-
- const bool ifaceIsSet = li->Target->GetProperties()
- .find("INTERFACE_" + p)
- != li->Target->GetProperties().end();
- PropertyType ifacePropContent =
- getTypedProperty<PropertyType>(li->Target,
- ("INTERFACE_" + p).c_str(), 0);
- if (explicitlySet)
- {
- if (ifaceIsSet)
- {
- if (!consistentProperty(propContent, ifacePropContent))
- {
- cmOStringStream e;
- e << "Property " << p << " on target \""
- << tgt->GetName() << "\" does\nnot match the "
- "INTERFACE_" << p << " property requirement\nof "
- "dependency \"" << li->Target->GetName() << "\".\n";
- cmSystemTools::Error(e.str().c_str());
- break;
- }
- else
- {
- // Agree
- continue;
- }
- }
- else
- {
- // Explicitly set on target and not set in iface. Can't disagree.
- continue;
- }
- }
- else if (impliedByUse)
- {
- if (ifaceIsSet)
- {
- if (!consistentProperty(propContent, ifacePropContent))
- {
- cmOStringStream e;
- e << "Property " << p << " on target \""
- << tgt->GetName() << "\" is\nimplied to be " << defaultValue
- << " because it was used to determine the link libraries\n"
- "already. The INTERFACE_" << p << " property on\ndependency \""
- << li->Target->GetName() << "\" is in conflict.\n";
- cmSystemTools::Error(e.str().c_str());
- break;
- }
- else
- {
- // Agree
- continue;
- }
- }
- else
- {
- // Implicitly set on target and not set in iface. Can't disagree.
- continue;
- }
- }
- else
- {
- if (ifaceIsSet)
- {
- if (propInitialized)
- {
- if (!consistentProperty(propContent, ifacePropContent))
- {
- cmOStringStream e;
- e << "The INTERFACE_" << p << " property of \""
- << li->Target->GetName() << "\" does\nnot agree with the value "
- "of " << p << " already determined\nfor \""
- << tgt->GetName() << "\".\n";
- cmSystemTools::Error(e.str().c_str());
- break;
- }
- else
- {
- // Agree.
- continue;
- }
- }
- else
- {
- propContent = ifacePropContent;
- propInitialized = true;
- }
- }
- else
- {
- // Not set. Nothing to agree on.
- continue;
- }
- }
- }
- return propContent;
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
- const char *config)
-{
- return checkInterfacePropertyCompatibility<bool>(this, p, config, "FALSE",
- 0);
-}
-
-//----------------------------------------------------------------------------
-const char * cmTarget::GetLinkInterfaceDependentStringProperty(
- const std::string &p,
- const char *config)
-{
- return checkInterfacePropertyCompatibility<const char *>(this,
- p,
- config,
- "empty", 0);
-}
-
-//----------------------------------------------------------------------------
-bool isLinkDependentProperty(cmTarget *tgt, const std::string &p,
- const char *interfaceProperty,
- const char *config)
-{
- cmComputeLinkInformation *info = tgt->GetLinkInformation(config);
- if(!info)
- {
- return false;
- }
-
- const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
-
- for(cmComputeLinkInformation::ItemVector::const_iterator li =
- deps.begin();
- li != deps.end(); ++li)
- {
- if (!li->Target)
- {
- continue;
- }
- const char *prop = li->Target->GetProperty(interfaceProperty);
- if (!prop)
- {
- continue;
- }
-
- std::vector<std::string> props;
- cmSystemTools::ExpandListArgument(prop, props);
-
- for(std::vector<std::string>::iterator pi = props.begin();
- pi != props.end(); ++pi)
- {
- if (*pi == p)
- {
- return true;
- }
- }
- }
-
- return false;
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::IsLinkInterfaceDependentBoolProperty(const std::string &p,
- const char *config)
-{
- if (this->TargetTypeValue == OBJECT_LIBRARY)
- {
- return false;
- }
- return (p == "POSITION_INDEPENDENT_CODE") ||
- isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_BOOL",
- config);
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::IsLinkInterfaceDependentStringProperty(const std::string &p,
- const char *config)
-{
- if (this->TargetTypeValue == OBJECT_LIBRARY)
- {
- return false;
- }
- return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_STRING",
- config);
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GetLanguages(std::set<cmStdString>& languages) const
-{
- for(std::vector<cmSourceFile*>::const_iterator
- i = this->SourceFiles.begin(); i != this->SourceFiles.end(); ++i)
- {
- if(const char* lang = (*i)->GetLanguage())
- {
- languages.insert(lang);
- }
- }
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::IsChrpathUsed(const char* config)
+bool cmTarget::GetMappedConfig(std::string const& desired_config,
+ const char** loc,
+ const char** imp,
+ std::string& suffix) const
{
- // Only certain target types have an rpath.
- if(!(this->GetType() == cmTarget::SHARED_LIBRARY ||
- this->GetType() == cmTarget::MODULE_LIBRARY ||
- this->GetType() == cmTarget::EXECUTABLE))
- {
- return false;
- }
-
- // If the target will not be installed we do not need to change its
- // rpath.
- if(!this->GetHaveInstallRule())
- {
- return false;
- }
-
- // Skip chrpath if skipping rpath altogether.
- if(this->Makefile->IsOn("CMAKE_SKIP_RPATH"))
- {
- return false;
- }
-
- // Skip chrpath if it does not need to be changed at install time.
- if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
- {
- return false;
- }
-
- // Allow the user to disable builtin chrpath explicitly.
- if(this->Makefile->IsOn("CMAKE_NO_BUILTIN_CHRPATH"))
- {
- return false;
- }
-
- if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
+ if (this->GetType() == cmState::INTERFACE_LIBRARY)
{
+ // This method attempts to find a config-specific LOCATION for the
+ // IMPORTED library. In the case of cmState::INTERFACE_LIBRARY, there is no
+ // LOCATION at all, so leaving *loc and *imp unchanged is the appropriate
+ // and valid response.
return true;
}
-#if defined(CMAKE_USE_ELF_PARSER)
- // Enable if the rpath flag uses a separator and the target uses ELF
- // binaries.
- if(const char* ll = this->GetLinkerLanguage(config, this))
- {
- std::string sepVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
- sepVar += ll;
- sepVar += "_FLAG_SEP";
- const char* sep = this->Makefile->GetDefinition(sepVar.c_str());
- if(sep && *sep)
- {
- // TODO: Add ELF check to ABI detection and get rid of
- // CMAKE_EXECUTABLE_FORMAT.
- if(const char* fmt =
- this->Makefile->GetDefinition("CMAKE_EXECUTABLE_FORMAT"))
- {
- return strcmp(fmt, "ELF") == 0;
- }
- }
- }
-#endif
- static_cast<void>(config);
- return false;
-}
-
-//----------------------------------------------------------------------------
-cmTarget::ImportInfo const*
-cmTarget::GetImportInfo(const char* config, cmTarget *headTarget)
-{
- // There is no imported information for non-imported targets.
- if(!this->IsImported())
- {
- return 0;
- }
-
- // Lookup/compute/cache the import information for this
- // configuration.
- std::string config_upper;
- if(config && *config)
- {
- config_upper = cmSystemTools::UpperCase(config);
- }
- else
- {
- config_upper = "NOCONFIG";
- }
- TargetConfigPair key(headTarget, config_upper);
- typedef cmTargetInternals::ImportInfoMapType ImportInfoMapType;
-
- ImportInfoMapType::const_iterator i =
- this->Internal->ImportInfoMap.find(key);
- if(i == this->Internal->ImportInfoMap.end())
- {
- ImportInfo info;
- this->ComputeImportInfo(config_upper, info, headTarget);
- ImportInfoMapType::value_type entry(key, info);
- i = this->Internal->ImportInfoMap.insert(entry).first;
- }
-
- // If the location is empty then the target is not available for
- // this configuration.
- if(i->second.Location.empty() && i->second.ImportLibrary.empty())
- {
- return 0;
- }
-
- // Return the import information.
- return &i->second;
-}
-
-bool cmTarget::GetMappedConfig(std::string const& desired_config,
- const char** loc,
- const char** imp,
- std::string& suffix)
-{
// Track the configuration-specific property suffix.
suffix = "_";
suffix += desired_config;
@@ -6020,7 +2053,7 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
{
std::string mapProp = "MAP_IMPORTED_CONFIG_";
mapProp += desired_config;
- if(const char* mapValue = this->GetProperty(mapProp.c_str()))
+ if(const char* mapValue = this->GetProperty(mapProp))
{
cmSystemTools::ExpandListArgument(mapValue, mappedConfigs);
}
@@ -6036,15 +2069,15 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
!*loc && !*imp && mci != mappedConfigs.end(); ++mci)
{
// Look for this configuration.
- std::string mcUpper = cmSystemTools::UpperCase(mci->c_str());
+ std::string mcUpper = cmSystemTools::UpperCase(*mci);
std::string locProp = "IMPORTED_LOCATION_";
locProp += mcUpper;
- *loc = this->GetProperty(locProp.c_str());
+ *loc = this->GetProperty(locProp);
if(allowImp)
{
std::string impProp = "IMPORTED_IMPLIB_";
impProp += mcUpper;
- *imp = this->GetProperty(impProp.c_str());
+ *imp = this->GetProperty(impProp);
}
// If it was found, use it for all properties below.
@@ -6069,12 +2102,12 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
{
std::string locProp = "IMPORTED_LOCATION";
locProp += suffix;
- *loc = this->GetProperty(locProp.c_str());
+ *loc = this->GetProperty(locProp);
if(allowImp)
{
std::string impProp = "IMPORTED_IMPLIB";
impProp += suffix;
- *imp = this->GetProperty(impProp.c_str());
+ *imp = this->GetProperty(impProp);
}
}
@@ -6111,12 +2144,12 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
suffix += cmSystemTools::UpperCase(*aci);
std::string locProp = "IMPORTED_LOCATION";
locProp += suffix;
- *loc = this->GetProperty(locProp.c_str());
+ *loc = this->GetProperty(locProp);
if(allowImp)
{
std::string impProp = "IMPORTED_IMPLIB";
impProp += suffix;
- *imp = this->GetProperty(impProp.c_str());
+ *imp = this->GetProperty(impProp);
}
}
}
@@ -6130,922 +2163,6 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
}
//----------------------------------------------------------------------------
-void cmTarget::ComputeImportInfo(std::string const& desired_config,
- ImportInfo& info,
- cmTarget *headTarget)
-{
- // This method finds information about an imported target from its
- // properties. The "IMPORTED_" namespace is reserved for properties
- // defined by the project exporting the target.
-
- // Initialize members.
- info.NoSOName = false;
-
- const char* loc = 0;
- const char* imp = 0;
- std::string suffix;
- if (!this->GetMappedConfig(desired_config, &loc, &imp, suffix))
- {
- return;
- }
-
- // A provided configuration has been chosen. Load the
- // configuration's properties.
-
- // Get the location.
- if(loc)
- {
- info.Location = loc;
- }
- else
- {
- std::string impProp = "IMPORTED_LOCATION";
- impProp += suffix;
- if(const char* config_location = this->GetProperty(impProp.c_str()))
- {
- info.Location = config_location;
- }
- else if(const char* location = this->GetProperty("IMPORTED_LOCATION"))
- {
- info.Location = location;
- }
- }
-
- // Get the soname.
- if(this->GetType() == cmTarget::SHARED_LIBRARY)
- {
- std::string soProp = "IMPORTED_SONAME";
- soProp += suffix;
- if(const char* config_soname = this->GetProperty(soProp.c_str()))
- {
- info.SOName = config_soname;
- }
- else if(const char* soname = this->GetProperty("IMPORTED_SONAME"))
- {
- info.SOName = soname;
- }
- }
-
- // Get the "no-soname" mark.
- if(this->GetType() == cmTarget::SHARED_LIBRARY)
- {
- std::string soProp = "IMPORTED_NO_SONAME";
- soProp += suffix;
- if(const char* config_no_soname = this->GetProperty(soProp.c_str()))
- {
- info.NoSOName = cmSystemTools::IsOn(config_no_soname);
- }
- else if(const char* no_soname = this->GetProperty("IMPORTED_NO_SONAME"))
- {
- info.NoSOName = cmSystemTools::IsOn(no_soname);
- }
- }
-
- // Get the import library.
- if(imp)
- {
- info.ImportLibrary = imp;
- }
- else if(this->GetType() == cmTarget::SHARED_LIBRARY ||
- this->IsExecutableWithExports())
- {
- std::string impProp = "IMPORTED_IMPLIB";
- impProp += suffix;
- if(const char* config_implib = this->GetProperty(impProp.c_str()))
- {
- info.ImportLibrary = config_implib;
- }
- else if(const char* implib = this->GetProperty("IMPORTED_IMPLIB"))
- {
- info.ImportLibrary = implib;
- }
- }
-
- // Get the link interface.
- {
- std::string linkProp = "INTERFACE_LINK_LIBRARIES";
- const char *propertyLibs = this->GetProperty(linkProp.c_str());
-
- if (!propertyLibs)
- {
- linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES";
- linkProp += suffix;
- propertyLibs = this->GetProperty(linkProp.c_str());
- }
-
- if(!propertyLibs)
- {
- linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES";
- propertyLibs = this->GetProperty(linkProp.c_str());
- }
- if(propertyLibs)
- {
- cmListFileBacktrace lfbt;
- cmGeneratorExpression ge(lfbt);
-
- cmGeneratorExpressionDAGChecker dagChecker(lfbt,
- this->GetName(),
- linkProp, 0, 0);
- cmSystemTools::ExpandListArgument(ge.Parse(propertyLibs)
- ->Evaluate(this->Makefile,
- desired_config.c_str(),
- false,
- headTarget,
- this,
- &dagChecker),
- info.LinkInterface.Libraries);
- }
- }
-
- // Get the link dependencies.
- {
- std::string linkProp = "IMPORTED_LINK_DEPENDENT_LIBRARIES";
- linkProp += suffix;
- if(const char* config_libs = this->GetProperty(linkProp.c_str()))
- {
- cmSystemTools::ExpandListArgument(config_libs,
- info.LinkInterface.SharedDeps);
- }
- else if(const char* libs =
- this->GetProperty("IMPORTED_LINK_DEPENDENT_LIBRARIES"))
- {
- cmSystemTools::ExpandListArgument(libs, info.LinkInterface.SharedDeps);
- }
- }
-
- // Get the link languages.
- if(this->LinkLanguagePropagatesToDependents())
- {
- std::string linkProp = "IMPORTED_LINK_INTERFACE_LANGUAGES";
- linkProp += suffix;
- if(const char* config_libs = this->GetProperty(linkProp.c_str()))
- {
- cmSystemTools::ExpandListArgument(config_libs,
- info.LinkInterface.Languages);
- }
- else if(const char* libs =
- this->GetProperty("IMPORTED_LINK_INTERFACE_LANGUAGES"))
- {
- cmSystemTools::ExpandListArgument(libs,
- info.LinkInterface.Languages);
- }
- }
-
- // Get the cyclic repetition count.
- if(this->GetType() == cmTarget::STATIC_LIBRARY)
- {
- std::string linkProp = "IMPORTED_LINK_INTERFACE_MULTIPLICITY";
- linkProp += suffix;
- if(const char* config_reps = this->GetProperty(linkProp.c_str()))
- {
- sscanf(config_reps, "%u", &info.LinkInterface.Multiplicity);
- }
- else if(const char* reps =
- this->GetProperty("IMPORTED_LINK_INTERFACE_MULTIPLICITY"))
- {
- sscanf(reps, "%u", &info.LinkInterface.Multiplicity);
- }
- }
-}
-
-//----------------------------------------------------------------------------
-cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config,
- cmTarget *head)
-{
- // Imported targets have their own link interface.
- if(this->IsImported())
- {
- if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, head))
- {
- return &info->LinkInterface;
- }
- return 0;
- }
-
- // Link interfaces are not supported for executables that do not
- // export symbols.
- if(this->GetType() == cmTarget::EXECUTABLE &&
- !this->IsExecutableWithExports())
- {
- return 0;
- }
-
- // Lookup any existing link interface for this configuration.
- TargetConfigPair key(head, cmSystemTools::UpperCase(config? config : ""));
-
- cmTargetInternals::LinkInterfaceMapType::iterator
- i = this->Internal->LinkInterfaceMap.find(key);
- if(i == this->Internal->LinkInterfaceMap.end())
- {
- // Compute the link interface for this configuration.
- cmTargetInternals::OptionalLinkInterface iface;
- iface.Exists = this->ComputeLinkInterface(config, iface, head);
-
- // Store the information for this configuration.
- cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface);
- i = this->Internal->LinkInterfaceMap.insert(entry).first;
- }
-
- return i->second.Exists? &i->second : 0;
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GetTransitivePropertyLinkLibraries(
- const char* config,
- cmTarget *headTarget,
- std::vector<std::string> &libs)
-{
- cmTarget::LinkInterface const* iface = this->GetLinkInterface(config,
- headTarget);
- if (!iface)
- {
- return;
- }
- if(this->GetType() != STATIC_LIBRARY
- || this->GetPolicyStatusCMP0022() == cmPolicies::WARN
- || this->GetPolicyStatusCMP0022() == cmPolicies::OLD)
- {
- libs = iface->Libraries;
- return;
- }
-
- const char* linkIfaceProp = "INTERFACE_LINK_LIBRARIES";
- const char* interfaceLibs = this->GetProperty(linkIfaceProp);
-
- if (!interfaceLibs)
- {
- return;
- }
-
- // The interface libraries have been explicitly set.
- cmListFileBacktrace lfbt;
- cmGeneratorExpression ge(lfbt);
- cmGeneratorExpressionDAGChecker dagChecker(lfbt, this->GetName(),
- linkIfaceProp, 0, 0);
- dagChecker.SetTransitivePropertiesOnly();
- cmSystemTools::ExpandListArgument(ge.Parse(interfaceLibs)->Evaluate(
- this->Makefile,
- config,
- false,
- headTarget,
- this, &dagChecker), libs);
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
- cmTarget *headTarget)
-{
- // Construct the property name suffix for this configuration.
- std::string suffix = "_";
- if(config && *config)
- {
- suffix += cmSystemTools::UpperCase(config);
- }
- else
- {
- suffix += "NOCONFIG";
- }
-
- // An explicit list of interface libraries may be set for shared
- // libraries and executables that export symbols.
- const char* explicitLibraries = 0;
- std::string linkIfaceProp;
- if(this->PolicyStatusCMP0022 != cmPolicies::OLD &&
- this->PolicyStatusCMP0022 != cmPolicies::WARN)
- {
- // CMP0022 NEW behavior is to use INTERFACE_LINK_LIBRARIES.
- linkIfaceProp = "INTERFACE_LINK_LIBRARIES";
- explicitLibraries = this->GetProperty(linkIfaceProp.c_str());
- }
- else if(this->GetType() == cmTarget::SHARED_LIBRARY ||
- this->IsExecutableWithExports())
- {
- // CMP0022 OLD behavior is to use LINK_INTERFACE_LIBRARIES if set on a
- // shared lib or executable.
-
- // Lookup the per-configuration property.
- linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
- linkIfaceProp += suffix;
- explicitLibraries = this->GetProperty(linkIfaceProp.c_str());
-
- // If not set, try the generic property.
- if(!explicitLibraries)
- {
- linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
- explicitLibraries = this->GetProperty(linkIfaceProp.c_str());
- }
- }
-
- if(explicitLibraries && this->PolicyStatusCMP0022 == cmPolicies::WARN &&
- !this->Internal->PolicyWarnedCMP0022)
- {
- // Compare the explicitly set old link interface properties to the
- // preferred new link interface property one and warn if different.
- const char* newExplicitLibraries =
- this->GetProperty("INTERFACE_LINK_LIBRARIES");
- if (newExplicitLibraries
- && strcmp(newExplicitLibraries, explicitLibraries) != 0)
- {
- cmOStringStream w;
- w <<
- (this->Makefile->GetPolicies()
- ->GetPolicyWarning(cmPolicies::CMP0022)) << "\n"
- "Target \"" << this->GetName() << "\" has an "
- "INTERFACE_LINK_LIBRARIES property which differs from its " <<
- linkIfaceProp << " properties."
- "\n"
- "INTERFACE_LINK_LIBRARIES:\n"
- " " << newExplicitLibraries << "\n" <<
- linkIfaceProp << ":\n"
- " " << (explicitLibraries ? explicitLibraries : "(empty)") << "\n";
- this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
- this->Internal->PolicyWarnedCMP0022 = true;
- }
- }
-
- // There is no implicit link interface for executables or modules
- // so if none was explicitly set then there is no link interface.
- // Note that CMake versions 2.2 and below allowed linking to modules.
- bool canLinkModules = this->Makefile->NeedBackwardsCompatibility(2,2);
- if(!explicitLibraries &&
- (this->GetType() == cmTarget::EXECUTABLE ||
- (this->GetType() == cmTarget::MODULE_LIBRARY && !canLinkModules)))
- {
- return false;
- }
-
- if(explicitLibraries)
- {
- // The interface libraries have been explicitly set.
- cmListFileBacktrace lfbt;
- cmGeneratorExpression ge(lfbt);
- cmGeneratorExpressionDAGChecker dagChecker(lfbt, this->GetName(),
- linkIfaceProp, 0, 0);
- cmSystemTools::ExpandListArgument(ge.Parse(explicitLibraries)->Evaluate(
- this->Makefile,
- config,
- false,
- headTarget,
- this, &dagChecker), iface.Libraries);
-
- if(this->GetType() == cmTarget::SHARED_LIBRARY
- || this->GetType() == cmTarget::STATIC_LIBRARY)
- {
- // Shared libraries may have runtime implementation dependencies
- // on other shared libraries that are not in the interface.
- std::set<cmStdString> emitted;
- for(std::vector<std::string>::const_iterator
- li = iface.Libraries.begin(); li != iface.Libraries.end(); ++li)
- {
- emitted.insert(*li);
- }
- LinkImplementation const* impl = this->GetLinkImplementation(config,
- headTarget);
- for(std::vector<std::string>::const_iterator
- li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
- {
- if(emitted.insert(*li).second)
- {
- if(cmTarget* tgt = this->Makefile->FindTargetToUse(li->c_str()))
- {
- // This is a runtime dependency on another shared library.
- if(tgt->GetType() == cmTarget::SHARED_LIBRARY)
- {
- iface.SharedDeps.push_back(*li);
- }
- }
- else
- {
- // TODO: Recognize shared library file names. Perhaps this
- // should be moved to cmComputeLinkInformation, but that creates
- // a chicken-and-egg problem since this list is needed for its
- // construction.
- }
- }
- }
- if(this->LinkLanguagePropagatesToDependents())
- {
- // Targets using this archive need its language runtime libraries.
- iface.Languages = impl->Languages;
- }
- }
- }
- else if (this->PolicyStatusCMP0022 == cmPolicies::WARN
- || this->PolicyStatusCMP0022 == cmPolicies::OLD)
- // If CMP0022 is NEW then the plain tll signature sets the
- // INTERFACE_LINK_LIBRARIES, so if we get here then the project
- // cleared the property explicitly and we should not fall back
- // to the link implementation.
- {
- // The link implementation is the default link interface.
- LinkImplementation const* impl = this->GetLinkImplementation(config,
- headTarget);
- iface.ImplementationIsInterface = true;
- iface.Libraries = impl->Libraries;
- iface.WrongConfigLibraries = impl->WrongConfigLibraries;
- if(this->LinkLanguagePropagatesToDependents())
- {
- // Targets using this archive need its language runtime libraries.
- iface.Languages = impl->Languages;
- }
-
- if(this->PolicyStatusCMP0022 == cmPolicies::WARN &&
- !this->Internal->PolicyWarnedCMP0022)
- {
- // Compare the link implementation fallback link interface to the
- // preferred new link interface property and warn if different.
- cmListFileBacktrace lfbt;
- cmGeneratorExpression ge(lfbt);
- cmGeneratorExpressionDAGChecker dagChecker(lfbt, this->GetName(),
- "INTERFACE_LINK_LIBRARIES", 0, 0);
- std::vector<std::string> ifaceLibs;
- const char* newExplicitLibraries =
- this->GetProperty("INTERFACE_LINK_LIBRARIES");
- cmSystemTools::ExpandListArgument(
- ge.Parse(newExplicitLibraries)->Evaluate(this->Makefile,
- config,
- false,
- headTarget,
- this, &dagChecker),
- ifaceLibs);
- if (ifaceLibs != impl->Libraries)
- {
- std::string oldLibraries;
- std::string newLibraries;
- const char *sep = "";
- for(std::vector<std::string>::const_iterator it
- = impl->Libraries.begin(); it != impl->Libraries.end(); ++it)
- {
- oldLibraries += sep;
- oldLibraries += *it;
- sep = ";";
- }
- sep = "";
- for(std::vector<std::string>::const_iterator it
- = ifaceLibs.begin(); it != ifaceLibs.end(); ++it)
- {
- newLibraries += sep;
- newLibraries += *it;
- sep = ";";
- }
- if(oldLibraries.empty())
- { oldLibraries = "(empty)"; }
- if(newLibraries.empty())
- { newLibraries = "(empty)"; }
-
- cmOStringStream w;
- w <<
- (this->Makefile->GetPolicies()
- ->GetPolicyWarning(cmPolicies::CMP0022)) << "\n"
- "Target \"" << this->GetName() << "\" has an "
- "INTERFACE_LINK_LIBRARIES property. "
- "This should be preferred as the source of the link interface "
- "for this library but because CMP0022 is not set CMake is "
- "ignoring the property and using the link implementation "
- "as the link interface instead."
- "\n"
- "INTERFACE_LINK_LIBRARIES:\n"
- " " << newLibraries << "\n"
- "Link implementation:\n"
- " " << oldLibraries << "\n";
- this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
- this->Internal->PolicyWarnedCMP0022 = true;
- }
- }
- }
-
- if(this->GetType() == cmTarget::STATIC_LIBRARY)
- {
- // How many repetitions are needed if this library has cyclic
- // dependencies?
- std::string propName = "LINK_INTERFACE_MULTIPLICITY";
- propName += suffix;
- if(const char* config_reps = this->GetProperty(propName.c_str()))
- {
- sscanf(config_reps, "%u", &iface.Multiplicity);
- }
- else if(const char* reps =
- this->GetProperty("LINK_INTERFACE_MULTIPLICITY"))
- {
- sscanf(reps, "%u", &iface.Multiplicity);
- }
- }
-
- return true;
-}
-
-//----------------------------------------------------------------------------
-cmTarget::LinkImplementation const*
-cmTarget::GetLinkImplementation(const char* config, cmTarget *head)
-{
- // There is no link implementation for imported targets.
- if(this->IsImported())
- {
- return 0;
- }
-
- // Lookup any existing link implementation for this configuration.
- TargetConfigPair key(head, cmSystemTools::UpperCase(config? config : ""));
-
- cmTargetInternals::LinkImplMapType::iterator
- i = this->Internal->LinkImplMap.find(key);
- if(i == this->Internal->LinkImplMap.end())
- {
- // Compute the link implementation for this configuration.
- LinkImplementation impl;
- this->ComputeLinkImplementation(config, impl, head);
-
- // Store the information for this configuration.
- cmTargetInternals::LinkImplMapType::value_type entry(key, impl);
- i = this->Internal->LinkImplMap.insert(entry).first;
- }
-
- return &i->second;
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::ComputeLinkImplementation(const char* config,
- LinkImplementation& impl,
- cmTarget *head)
-{
- // Compute which library configuration to link.
- cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config);
-
- // Collect libraries directly linked in this configuration.
- std::vector<std::string> llibs;
- this->GetDirectLinkLibraries(config, llibs, head);
- for(std::vector<std::string>::const_iterator li = llibs.begin();
- li != llibs.end(); ++li)
- {
- // Skip entries that resolve to the target itself or are empty.
- std::string item = this->CheckCMP0004(*li);
- if(item == this->GetName() || item.empty())
- {
- continue;
- }
- // The entry is meant for this configuration.
- impl.Libraries.push_back(item);
- }
-
- LinkLibraryVectorType const& oldllibs = this->GetOriginalLinkLibraries();
- for(cmTarget::LinkLibraryVectorType::const_iterator li = oldllibs.begin();
- li != oldllibs.end(); ++li)
- {
- if(li->second != cmTarget::GENERAL && li->second != linkType)
- {
- std::string item = this->CheckCMP0004(li->first);
- if(item == this->GetName() || item.empty())
- {
- continue;
- }
- // Support OLD behavior for CMP0003.
- impl.WrongConfigLibraries.push_back(item);
- }
- }
-
- // This target needs runtime libraries for its source languages.
- std::set<cmStdString> languages;
- // Get languages used in our source files.
- this->GetLanguages(languages);
- // Get languages used in object library sources.
- for(std::vector<std::string>::iterator i = this->ObjectLibraries.begin();
- i != this->ObjectLibraries.end(); ++i)
- {
- if(cmTarget* objLib = this->Makefile->FindTargetToUse(i->c_str()))
- {
- if(objLib->GetType() == cmTarget::OBJECT_LIBRARY)
- {
- objLib->GetLanguages(languages);
- }
- }
- }
- // Copy the set of langauges to the link implementation.
- for(std::set<cmStdString>::iterator li = languages.begin();
- li != languages.end(); ++li)
- {
- impl.Languages.push_back(*li);
- }
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::CheckCMP0004(std::string const& item)
-{
- // Strip whitespace off the library names because we used to do this
- // in case variables were expanded at generate time. We no longer
- // do the expansion but users link to libraries like " ${VAR} ".
- std::string lib = item;
- std::string::size_type pos = lib.find_first_not_of(" \t\r\n");
- if(pos != lib.npos)
- {
- lib = lib.substr(pos, lib.npos);
- }
- pos = lib.find_last_not_of(" \t\r\n");
- if(pos != lib.npos)
- {
- lib = lib.substr(0, pos+1);
- }
- if(lib != item)
- {
- cmake* cm = this->Makefile->GetCMakeInstance();
- switch(this->PolicyStatusCMP0004)
- {
- case cmPolicies::WARN:
- {
- cmOStringStream w;
- w << (this->Makefile->GetPolicies()
- ->GetPolicyWarning(cmPolicies::CMP0004)) << "\n"
- << "Target \"" << this->GetName() << "\" links to item \""
- << item << "\" which has leading or trailing whitespace.";
- cm->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
- this->GetBacktrace());
- }
- case cmPolicies::OLD:
- break;
- case cmPolicies::NEW:
- {
- cmOStringStream e;
- e << "Target \"" << this->GetName() << "\" links to item \""
- << item << "\" which has leading or trailing whitespace. "
- << "This is now an error according to policy CMP0004.";
- cm->IssueMessage(cmake::FATAL_ERROR, e.str(), this->GetBacktrace());
- }
- break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- {
- cmOStringStream e;
- e << (this->Makefile->GetPolicies()
- ->GetRequiredPolicyError(cmPolicies::CMP0004)) << "\n"
- << "Target \"" << this->GetName() << "\" links to item \""
- << item << "\" which has leading or trailing whitespace.";
- cm->IssueMessage(cmake::FATAL_ERROR, e.str(), this->GetBacktrace());
- }
- break;
- }
- }
- return lib;
-}
-
-template<typename PropertyType>
-PropertyType getLinkInterfaceDependentProperty(cmTarget *tgt,
- const std::string prop,
- const char *config,
- PropertyType *);
-
-template<>
-bool getLinkInterfaceDependentProperty(cmTarget *tgt,
- const std::string prop,
- const char *config, bool *)
-{
- return tgt->GetLinkInterfaceDependentBoolProperty(prop, config);
-}
-
-template<>
-const char * getLinkInterfaceDependentProperty(cmTarget *tgt,
- const std::string prop,
- const char *config,
- const char **)
-{
- return tgt->GetLinkInterfaceDependentStringProperty(prop, config);
-}
-
-//----------------------------------------------------------------------------
-template<typename PropertyType>
-void checkPropertyConsistency(cmTarget *depender, cmTarget *dependee,
- const char *propName,
- std::set<cmStdString> &emitted,
- const char *config,
- PropertyType *)
-{
- const char *prop = dependee->GetProperty(propName);
- if (!prop)
- {
- return;
- }
-
- std::vector<std::string> props;
- cmSystemTools::ExpandListArgument(prop, props);
-
- for(std::vector<std::string>::iterator pi = props.begin();
- pi != props.end(); ++pi)
- {
- if (depender->GetMakefile()->GetCMakeInstance()
- ->GetIsPropertyDefined(pi->c_str(),
- cmProperty::TARGET))
- {
- cmOStringStream e;
- e << "Target \"" << dependee->GetName() << "\" has property \""
- << *pi << "\" listed in its " << propName << " property. "
- "This is not allowed. Only user-defined properties may appear "
- "listed in the " << propName << " property.";
- depender->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, e.str());
- return;
- }
- if(emitted.insert(*pi).second)
- {
- getLinkInterfaceDependentProperty<PropertyType>(depender, *pi, config,
- 0);
- if (cmSystemTools::GetErrorOccuredFlag())
- {
- return;
- }
- }
- }
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
- const char* config)
-{
- const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
-
- std::set<cmStdString> emittedBools;
- std::set<cmStdString> emittedStrings;
-
- for(cmComputeLinkInformation::ItemVector::const_iterator li =
- deps.begin();
- li != deps.end(); ++li)
- {
- if (!li->Target)
- {
- continue;
- }
-
- checkPropertyConsistency<bool>(this, li->Target,
- "COMPATIBLE_INTERFACE_BOOL",
- emittedBools, config, 0);
- if (cmSystemTools::GetErrorOccuredFlag())
- {
- return;
- }
- checkPropertyConsistency<const char *>(this, li->Target,
- "COMPATIBLE_INTERFACE_STRING",
- emittedStrings, config, 0);
- if (cmSystemTools::GetErrorOccuredFlag())
- {
- return;
- }
- }
-
- for(std::set<cmStdString>::const_iterator li = emittedBools.begin();
- li != emittedBools.end(); ++li)
- {
- const std::set<cmStdString>::const_iterator si = emittedStrings.find(*li);
- if (si != emittedStrings.end())
- {
- cmOStringStream e;
- e << "Property \"" << *li << "\" appears in both the "
- "COMPATIBLE_INTERFACE_BOOL and the COMPATIBLE_INTERFACE_STRING "
- "property in the dependencies of target \"" << this->GetName() <<
- "\". This is not allowed. A property may only require compatibility "
- "in a boolean interpretation or a string interpretation, but not both.";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
- break;
- }
- }
-}
-
-//----------------------------------------------------------------------------
-cmComputeLinkInformation*
-cmTarget::GetLinkInformation(const char* config, cmTarget *head)
-{
- cmTarget *headTarget = head ? head : this;
- // Lookup any existing information for this configuration.
- TargetConfigPair key(headTarget,
- cmSystemTools::UpperCase(config?config:""));
- cmTargetLinkInformationMap::iterator
- i = this->LinkInformation.find(key);
- if(i == this->LinkInformation.end())
- {
- // Compute information for this configuration.
- cmComputeLinkInformation* info =
- new cmComputeLinkInformation(this, config, headTarget);
- if(!info || !info->Compute())
- {
- delete info;
- info = 0;
- }
-
- // Store the information for this configuration.
- cmTargetLinkInformationMap::value_type entry(key, info);
- i = this->LinkInformation.insert(entry).first;
-
- if (info)
- {
- this->CheckPropertyCompatibility(info, config);
- }
- }
- return i->second;
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetFrameworkDirectory(const char* config,
- bool rootDir)
-{
- std::string fpath;
- fpath += this->GetOutputName(config, false);
- fpath += ".framework";
- if(!rootDir)
- {
- fpath += "/Versions/";
- fpath += this->GetFrameworkVersion();
- }
- return fpath;
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetCFBundleDirectory(const char* config,
- bool contentOnly)
-{
- std::string fpath;
- fpath += this->GetOutputName(config, false);
- fpath += ".";
- const char *ext = this->GetProperty("BUNDLE_EXTENSION");
- if (!ext)
- {
- ext = "bundle";
- }
- fpath += ext;
- fpath += "/Contents";
- if(!contentOnly)
- fpath += "/MacOS";
- return fpath;
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetAppBundleDirectory(const char* config,
- bool contentOnly)
-{
- std::string fpath = this->GetFullName(config, false);
- fpath += ".app/Contents";
- if(!contentOnly)
- fpath += "/MacOS";
- return fpath;
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::BuildMacContentDirectory(const std::string& base,
- const char* config,
- bool contentOnly)
-{
- std::string fpath = base;
- if(this->IsAppBundleOnApple())
- {
- fpath += this->GetAppBundleDirectory(config, contentOnly);
- }
- if(this->IsFrameworkOnApple())
- {
- fpath += this->GetFrameworkDirectory(config, contentOnly);
- }
- if(this->IsCFBundleOnApple())
- {
- fpath += this->GetCFBundleDirectory(config, contentOnly);
- }
- return fpath;
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetMacContentDirectory(const char* config,
- bool implib)
-{
- // Start with the output directory for the target.
- std::string fpath = this->GetDirectory(config, implib);
- fpath += "/";
- bool contentOnly = true;
- if(this->IsFrameworkOnApple())
- {
- // additional files with a framework go into the version specific
- // directory
- contentOnly = false;
- }
- fpath = this->BuildMacContentDirectory(fpath, config, contentOnly);
- return fpath;
-}
-
-//----------------------------------------------------------------------------
-cmTargetLinkInformationMap
-::cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r): derived()
-{
- // Ideally cmTarget instances should never be copied. However until
- // we can make a sweep to remove that, this copy constructor avoids
- // allowing the resources (LinkInformation) from getting copied. In
- // the worst case this will lead to extra cmComputeLinkInformation
- // instances. We also enforce in debug mode that the map be emptied
- // when copied.
- static_cast<void>(r);
- assert(r.empty());
-}
-
-//----------------------------------------------------------------------------
-cmTargetLinkInformationMap::~cmTargetLinkInformationMap()
-{
- for(derived::iterator i = this->begin(); i != this->end(); ++i)
- {
- delete i->second;
- }
-}
-
-//----------------------------------------------------------------------------
cmTargetInternalPointer::cmTargetInternalPointer()
{
this->Pointer = new cmTargetInternals;
@@ -7064,9 +2181,6 @@ cmTargetInternalPointer
//----------------------------------------------------------------------------
cmTargetInternalPointer::~cmTargetInternalPointer()
{
- deleteAndClear(this->Pointer->IncludeDirectoriesEntries);
- deleteAndClear(this->Pointer->CompileOptionsEntries);
- deleteAndClear(this->Pointer->CompileDefinitionsEntries);
delete this->Pointer;
}
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 27b74ca4b..97b087140 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -18,32 +18,22 @@
#include "cmListFileCache.h"
#include <cmsys/auto_ptr.hxx>
-
-#define CM_FOR_EACH_TARGET_POLICY(F) \
- F(CMP0003) \
- F(CMP0004) \
- F(CMP0008) \
- F(CMP0020) \
- F(CMP0021) \
- F(CMP0022)
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+# ifdef CMake_HAVE_CXX11_UNORDERED_MAP
+# include <unordered_map>
+# else
+# include <cmsys/hash_map.hxx>
+# endif
+#endif
class cmake;
class cmMakefile;
class cmSourceFile;
class cmGlobalGenerator;
-class cmComputeLinkInformation;
class cmListFileBacktrace;
class cmTarget;
-
-struct cmTargetLinkInformationMap:
- public std::map<std::pair<cmTarget*, std::string>, cmComputeLinkInformation*>
-{
- typedef std::map<std::pair<cmTarget*, std::string>,
- cmComputeLinkInformation*> derived;
- cmTargetLinkInformationMap() {}
- cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r);
- ~cmTargetLinkInformationMap();
-};
+class cmGeneratorTarget;
+class cmTargetTraceDependencies;
class cmTargetInternals;
class cmTargetInternalPointer
@@ -69,17 +59,12 @@ class cmTarget
{
public:
cmTarget();
- enum TargetType { EXECUTABLE, STATIC_LIBRARY,
- SHARED_LIBRARY, MODULE_LIBRARY,
- OBJECT_LIBRARY, UTILITY, GLOBAL_TARGET,
- UNKNOWN_LIBRARY};
- static const char* GetTargetTypeName(TargetType targetType);
enum CustomCommandType { PRE_BUILD, PRE_LINK, POST_BUILD };
/**
* Return the type of target.
*/
- TargetType GetType() const
+ cmState::TargetType GetType() const
{
return this->TargetTypeValue;
}
@@ -87,21 +72,20 @@ public:
/**
* Set the target type
*/
- void SetType(TargetType f, const char* name);
+ void SetType(cmState::TargetType f, const std::string& name);
- void MarkAsImported();
+ void MarkAsImported(bool global = false);
///! Set/Get the name of the target
- const char* GetName() const {return this->Name.c_str();}
- const char* GetExportName();
+ const std::string& GetName() const {return this->Name;}
///! Set the cmMakefile that owns this target
void SetMakefile(cmMakefile *mf);
- cmMakefile *GetMakefile() const { return this->Makefile;};
+ cmMakefile *GetMakefile() const { return this->Makefile;}
#define DECLARE_TARGET_POLICY(POLICY) \
cmPolicies::PolicyStatus GetPolicyStatus ## POLICY () const \
- { return this->PolicyStatus ## POLICY; }
+ { return this->PolicyMap.Get(cmPolicies::POLICY); }
CM_FOR_EACH_TARGET_POLICY(DECLARE_TARGET_POLICY)
@@ -110,455 +94,172 @@ public:
/**
* Get the list of the custom commands for this target
*/
- std::vector<cmCustomCommand> &GetPreBuildCommands()
+ std::vector<cmCustomCommand> const &GetPreBuildCommands() const
{return this->PreBuildCommands;}
- std::vector<cmCustomCommand> &GetPreLinkCommands()
+ std::vector<cmCustomCommand> const &GetPreLinkCommands() const
{return this->PreLinkCommands;}
- std::vector<cmCustomCommand> &GetPostBuildCommands()
+ std::vector<cmCustomCommand> const &GetPostBuildCommands() const
{return this->PostBuildCommands;}
-
- /**
- * Get the list of the source files used by this target
- */
- std::vector<cmSourceFile*> const& GetSourceFiles();
- void AddSourceFile(cmSourceFile* sf);
- std::vector<std::string> const& GetObjectLibraries() const
- {
- return this->ObjectLibraries;
- }
-
- /** Get sources that must be built before the given source. */
- std::vector<cmSourceFile*> const* GetSourceDepends(cmSourceFile* sf);
-
- /**
- * Flags for a given source file as used in this target. Typically assigned
- * via SET_TARGET_PROPERTIES when the property is a list of source files.
- */
- enum SourceFileType
- {
- SourceFileTypeNormal,
- SourceFileTypePrivateHeader, // is in "PRIVATE_HEADER" target property
- SourceFileTypePublicHeader, // is in "PUBLIC_HEADER" target property
- SourceFileTypeResource, // is in "RESOURCE" target property *or*
- // has MACOSX_PACKAGE_LOCATION=="Resources"
- SourceFileTypeMacContent // has MACOSX_PACKAGE_LOCATION!="Resources"
- };
- struct SourceFileFlags
- {
- SourceFileFlags(): Type(SourceFileTypeNormal), MacFolder(0) {}
- SourceFileFlags(SourceFileFlags const& r):
- Type(r.Type), MacFolder(r.MacFolder) {}
- SourceFileType Type;
- const char* MacFolder; // location inside Mac content folders
- };
-
- /**
- * Get the flags for a given source file as used in this target
- */
- struct SourceFileFlags GetTargetSourceFileFlags(const cmSourceFile* sf);
+ void AddPreBuildCommand(cmCustomCommand const &cmd)
+ {this->PreBuildCommands.push_back(cmd);}
+ void AddPreLinkCommand(cmCustomCommand const &cmd)
+ {this->PreLinkCommands.push_back(cmd);}
+ void AddPostBuildCommand(cmCustomCommand const &cmd)
+ {this->PostBuildCommands.push_back(cmd);}
/**
* Add sources to the target.
*/
void AddSources(std::vector<std::string> const& srcs);
- cmSourceFile* AddSource(const char* src);
-
- enum LinkLibraryType {GENERAL, DEBUG, OPTIMIZED};
+ void AddTracedSources(std::vector<std::string> const& srcs);
+ cmSourceFile* AddSourceCMP0049(const std::string& src);
+ cmSourceFile* AddSource(const std::string& src);
//* how we identify a library, by name and type
- typedef std::pair<cmStdString, LinkLibraryType> LibraryID;
+ typedef std::pair<std::string, cmTargetLinkLibraryType> LibraryID;
typedef std::vector<LibraryID > LinkLibraryVectorType;
- const LinkLibraryVectorType &GetLinkLibraries() const {
- return this->LinkLibraries;}
const LinkLibraryVectorType &GetOriginalLinkLibraries() const
{return this->OriginalLinkLibraries;}
- void GetDirectLinkLibraries(const char *config,
- std::vector<std::string> &,
- cmTarget *head);
-
- /** Compute the link type to use for the given configuration. */
- LinkLibraryType ComputeLinkType(const char* config);
/**
* Clear the dependency information recorded for this target, if any.
*/
- void ClearDependencyInformation(cmMakefile& mf, const char* target);
+ void ClearDependencyInformation(cmMakefile& mf, const std::string& target);
- // Check to see if a library is a framework and treat it different on Mac
- bool NameResolvesToFramework(const std::string& libname);
void AddLinkLibrary(cmMakefile& mf,
- const char *target, const char* lib,
- LinkLibraryType llt);
+ const std::string& target, const std::string& lib,
+ cmTargetLinkLibraryType llt);
enum TLLSignature {
KeywordTLLSignature,
PlainTLLSignature
};
- bool PushTLLCommandTrace(TLLSignature signature);
- void GetTllSignatureTraces(cmOStringStream &s, TLLSignature sig) const;
+ bool PushTLLCommandTrace(TLLSignature signature,
+ cmListFileContext const& lfc);
+ void GetTllSignatureTraces(std::ostringstream &s, TLLSignature sig) const;
- void MergeLinkLibraries( cmMakefile& mf, const char* selfname,
+ void MergeLinkLibraries( cmMakefile& mf, const std::string& selfname,
const LinkLibraryVectorType& libs );
- const std::vector<std::string>& GetLinkDirectories();
+ const std::vector<std::string>& GetLinkDirectories() const;
- void AddLinkDirectory(const char* d);
+ void AddLinkDirectory(const std::string& d);
/**
* Set the path where this target should be installed. This is relative to
* INSTALL_PREFIX
*/
- std::string GetInstallPath() {return this->InstallPath;}
+ std::string GetInstallPath() const {return this->InstallPath;}
void SetInstallPath(const char *name) {this->InstallPath = name;}
/**
* Set the path where this target (if it has a runtime part) should be
* installed. This is relative to INSTALL_PREFIX
*/
- std::string GetRuntimeInstallPath() {return this->RuntimeInstallPath;}
+ std::string GetRuntimeInstallPath() const {return this->RuntimeInstallPath;}
void SetRuntimeInstallPath(const char *name) {
this->RuntimeInstallPath = name; }
/**
* Get/Set whether there is an install rule for this target.
*/
- bool GetHaveInstallRule() { return this->HaveInstallRule; }
+ bool GetHaveInstallRule() const { return this->HaveInstallRule; }
void SetHaveInstallRule(bool h) { this->HaveInstallRule = h; }
/** Add a utility on which this project depends. A utility is an executable
* name as would be specified to the ADD_EXECUTABLE or UTILITY_SOURCE
* commands. It is not a full path nor does it have an extension.
*/
- void AddUtility(const char* u) { this->Utilities.insert(u);}
+ void AddUtility(const std::string& u, cmMakefile *makefile = 0);
///! Get the utilities used by this target
- std::set<cmStdString>const& GetUtilities() const { return this->Utilities; }
-
- /** Finalize the target at the end of the Configure step. */
- void FinishConfigure();
+ std::set<std::string>const& GetUtilities() const { return this->Utilities; }
+ cmListFileBacktrace const* GetUtilityBacktrace(const std::string& u) const;
///! Set/Get a property of this target file
- void SetProperty(const char *prop, const char *value);
- void AppendProperty(const char* prop, const char* value,bool asString=false);
- const char *GetProperty(const char *prop);
- const char *GetProperty(const char *prop, cmProperty::ScopeType scope);
- bool GetPropertyAsBool(const char *prop);
- void CheckProperty(const char* prop, cmMakefile* context);
-
- const char* GetFeature(const char* feature, const char* config);
+ void SetProperty(const std::string& prop, const char *value);
+ void AppendProperty(const std::string& prop, const char* value,
+ bool asString=false);
+ const char *GetProperty(const std::string& prop) const;
+ const char *GetProperty(const std::string& prop, cmMakefile* context) const;
+ bool GetPropertyAsBool(const std::string& prop) const;
+ void CheckProperty(const std::string& prop, cmMakefile* context) const;
bool IsImported() const {return this->IsImportedTarget;}
-
- /** The link interface specifies transitive library dependencies and
- other information needed by targets that link to this target. */
- struct LinkInterface
- {
- // Languages whose runtime libraries must be linked.
- std::vector<std::string> Languages;
-
- // Libraries listed in the interface.
- std::vector<std::string> Libraries;
-
- // Shared library dependencies needed for linking on some platforms.
- std::vector<std::string> SharedDeps;
-
- // Number of repetitions of a strongly connected component of two
- // or more static libraries.
- int Multiplicity;
-
- // Libraries listed for other configurations.
- // Needed only for OLD behavior of CMP0003.
- std::vector<std::string> WrongConfigLibraries;
-
- bool ImplementationIsInterface;
-
- LinkInterface(): Multiplicity(0), ImplementationIsInterface(false) {}
- };
-
- /** Get the link interface for the given configuration. Returns 0
- if the target cannot be linked. */
- LinkInterface const* GetLinkInterface(const char* config,
- cmTarget *headTarget);
- void GetTransitivePropertyLinkLibraries(const char* config,
- cmTarget *headTarget,
- std::vector<std::string> &libs);
-
- /** The link implementation specifies the direct library
- dependencies needed by the object files of the target. */
- struct LinkImplementation
- {
- // Languages whose runtime libraries must be linked.
- std::vector<std::string> Languages;
-
- // Libraries linked directly in this configuration.
- std::vector<std::string> Libraries;
-
- // Libraries linked directly in other configurations.
- // Needed only for OLD behavior of CMP0003.
- std::vector<std::string> WrongConfigLibraries;
- };
- LinkImplementation const* GetLinkImplementation(const char* config,
- cmTarget *head);
-
- /** Link information from the transitive closure of the link
- implementation and the interfaces of its dependencies. */
- struct LinkClosure
- {
- // The preferred linker language.
- std::string LinkerLanguage;
-
- // Languages whose runtime libraries must be linked.
- std::vector<std::string> Languages;
- };
- LinkClosure const* GetLinkClosure(const char* config, cmTarget *head);
-
- /** Strip off leading and trailing whitespace from an item named in
- the link dependencies of this target. */
- std::string CheckCMP0004(std::string const& item);
-
- /** Get the directory in which this target will be built. If the
- configuration name is given then the generator will add its
- subdirectory for that configuration. Otherwise just the canonical
- output directory is given. */
- std::string GetDirectory(const char* config = 0, bool implib = false);
-
- /** Get the directory in which this targets .pdb files will be placed.
- If the configuration name is given then the generator will add its
- subdirectory for that configuration. Otherwise just the canonical
- pdb output directory is given. */
- std::string GetPDBDirectory(const char* config = 0);
-
- /** Get the location of the target in the build tree for the given
- configuration. This location is suitable for use as the LOCATION
- target property. */
- const char* GetLocation(const char* config);
-
- /** Get the target major and minor version numbers interpreted from
- the VERSION property. Version 0 is returned if the property is
- not set or cannot be parsed. */
- void GetTargetVersion(int& major, int& minor);
-
- /** Get the target major, minor, and patch version numbers
- interpreted from the VERSION or SOVERSION property. Version 0
- is returned if the property is not set or cannot be parsed. */
- void GetTargetVersion(bool soversion, int& major, int& minor, int& patch);
-
- /**
- * Trace through the source files in this target and add al source files
- * that they depend on, used by all generators
- */
- void TraceDependencies();
-
- /**
- * Make sure the full path to all source files is known.
- */
- bool FindSourceFiles();
-
- ///! Return the preferred linker language for this target
- const char* GetLinkerLanguage(const char* config = 0, cmTarget *head = 0);
-
- /** Get the full name of the target according to the settings in its
- makefile. */
- std::string GetFullName(const char* config=0, bool implib = false);
- void GetFullNameComponents(std::string& prefix,
- std::string& base, std::string& suffix,
- const char* config=0, bool implib = false);
-
- /** Get the name of the pdb file for the target. */
- std::string GetPDBName(const char* config=0);
-
- /** Whether this library has soname enabled and platform supports it. */
- bool HasSOName(const char* config);
-
- /** Get the soname of the target. Allowed only for a shared library. */
- std::string GetSOName(const char* config);
-
- /** Whether this library has @rpath and platform supports it. */
- bool HasMacOSXRpath(const char* config);
-
- /** Test for special case of a third-party shared library that has
- no soname at all. */
- bool IsImportedSharedLibWithoutSOName(const char* config);
-
- /** Get the full path to the target according to the settings in its
- makefile and the configuration type. */
- std::string GetFullPath(const char* config=0, bool implib = false,
- bool realname = false);
-
- /** Get the names of the library needed to generate a build rule
- that takes into account shared library version numbers. This
- should be called only on a library target. */
- void GetLibraryNames(std::string& name, std::string& soName,
- std::string& realName, std::string& impName,
- std::string& pdbName, const char* config);
-
- /** Get the names of the executable needed to generate a build rule
- that takes into account executable version numbers. This should
- be called only on an executable target. */
- void GetExecutableNames(std::string& name, std::string& realName,
- std::string& impName,
- std::string& pdbName, const char* config);
-
- /** Does this target have a GNU implib to convert to MS format? */
- bool HasImplibGNUtoMS();
-
- /** Convert the given GNU import library name (.dll.a) to a name with a new
- extension (.lib or ${CMAKE_IMPORT_LIBRARY_SUFFIX}). */
- bool GetImplibGNUtoMS(std::string const& gnuName, std::string& out,
- const char* newExt = 0);
-
- /** Add the target output files to the global generator manifest. */
- void GenerateTargetManifest(const char* config);
-
- /**
- * Compute whether this target must be relinked before installing.
- */
- bool NeedRelinkBeforeInstall(const char* config);
-
- bool HaveBuildTreeRPATH(const char *config);
- bool HaveInstallTreeRPATH();
-
- /** Return true if builtin chrpath will work for this target */
- bool IsChrpathUsed(const char* config);
-
- /** Return the install name directory for the target in the
- * build tree. For example: "@rpath/", "@loader_path/",
- * or "/full/path/to/library". */
- std::string GetInstallNameDirForBuildTree(const char* config);
-
- /** Return the install name directory for the target in the
- * install tree. For example: "@rpath/" or "@loader_path/". */
- std::string GetInstallNameDirForInstallTree();
-
- cmComputeLinkInformation* GetLinkInformation(const char* config,
- cmTarget *head = 0);
+ bool IsImportedGloballyVisible() const
+ { return this->ImportedGloballyVisible; }
// Get the properties
- cmPropertyMap &GetProperties() { return this->Properties; };
+ cmPropertyMap &GetProperties() const { return this->Properties; }
bool GetMappedConfig(std::string const& desired_config,
const char** loc,
const char** imp,
- std::string& suffix);
-
- // Define the properties
- static void DefineProperties(cmake *cm);
-
- /** Get the macro to define when building sources in this target.
- If no macro should be defined null is returned. */
- const char* GetExportMacro();
-
- void GetCompileDefinitions(std::vector<std::string> &result,
- const char *config);
-
- // Compute the set of languages compiled by the target. This is
- // computed every time it is called because the languages can change
- // when source file properties are changed and we do not have enough
- // information to forward these property changes to the targets
- // until we have per-target object file properties.
- void GetLanguages(std::set<cmStdString>& languages) const;
+ std::string& suffix) const;
/** Return whether this target is an executable with symbol exports
enabled. */
- bool IsExecutableWithExports();
-
- /** Return whether this target may be used to link another target. */
- bool IsLinkable();
-
- /** Return whether or not the target is for a DLL platform. */
- bool IsDLLPlatform() { return this->DLLPlatform; }
-
- /** Return whether or not the target has a DLL import library. */
- bool HasImportLibrary();
+ bool IsExecutableWithExports() const;
/** Return whether this target is a shared library Framework on
Apple. */
- bool IsFrameworkOnApple();
-
- /** Return whether this target is a CFBundle (plugin) on Apple. */
- bool IsCFBundleOnApple();
+ bool IsFrameworkOnApple() const;
/** Return whether this target is an executable Bundle on Apple. */
- bool IsAppBundleOnApple();
-
- /** Return whether this target is an executable Bundle, a framework
- or CFBundle on Apple. */
- bool IsBundleOnApple();
-
- /** Return the framework version string. Undefined if
- IsFrameworkOnApple returns false. */
- std::string GetFrameworkVersion();
+ bool IsAppBundleOnApple() const;
/** Get a backtrace from the creation of the target. */
cmListFileBacktrace const& GetBacktrace() const;
- /** Get a build-tree directory in which to place target support files. */
- std::string GetSupportDirectory() const;
-
- /** Return whether this target uses the default value for its output
- directory. */
- bool UsesDefaultOutputDir(const char* config, bool implib);
-
- /** @return the mac content directory for this target. */
- std::string GetMacContentDirectory(const char* config,
- bool implib);
-
- /** @return whether this target have a well defined output file name. */
- bool HaveWellDefinedOutputFiles();
-
- /** @return the Mac framework directory without the base. */
- std::string GetFrameworkDirectory(const char* config, bool rootDir);
-
- /** @return the Mac CFBundle directory without the base */
- std::string GetCFBundleDirectory(const char* config, bool contentOnly);
-
- /** @return the Mac App directory without the base */
- std::string GetAppBundleDirectory(const char* config, bool contentOnly);
-
- std::vector<std::string> GetIncludeDirectories(const char *config);
- void InsertInclude(const cmValueWithOrigin &entry,
- bool before = false);
- void InsertCompileOption(const cmValueWithOrigin &entry,
- bool before = false);
- void InsertCompileDefinition(const cmValueWithOrigin &entry,
+ void InsertInclude(std::string const& entry,
+ cmListFileBacktrace const& bt,
bool before = false);
+ void InsertCompileOption(std::string const& entry,
+ cmListFileBacktrace const& bt,
+ bool before = false);
+ void InsertCompileDefinition(std::string const& entry,
+ cmListFileBacktrace const& bt);
void AppendBuildInterfaceIncludes();
- void GetCompileOptions(std::vector<std::string> &result,
- const char *config);
+ std::string GetDebugGeneratorExpressions(const std::string &value,
+ cmTargetLinkLibraryType llt) const;
- bool IsNullImpliedByLinkLibraries(const std::string &p);
- bool IsLinkInterfaceDependentBoolProperty(const std::string &p,
- const char *config);
- bool IsLinkInterfaceDependentStringProperty(const std::string &p,
- const char *config);
+ void AddSystemIncludeDirectories(const std::set<std::string> &incs);
+ std::set<std::string> const & GetSystemIncludeDirectories() const
+ { return this->SystemIncludeDirectories; }
- bool GetLinkInterfaceDependentBoolProperty(const std::string &p,
- const char *config);
+ cmStringRange GetIncludeDirectoriesEntries() const;
+ cmBacktraceRange GetIncludeDirectoriesBacktraces() const;
- const char *GetLinkInterfaceDependentStringProperty(const std::string &p,
- const char *config);
+ cmStringRange GetCompileOptionsEntries() const;
+ cmBacktraceRange GetCompileOptionsBacktraces() const;
- std::string GetDebugGeneratorExpressions(const std::string &value,
- cmTarget::LinkLibraryType llt);
+ cmStringRange GetCompileFeaturesEntries() const;
+ cmBacktraceRange GetCompileFeaturesBacktraces() const;
- void AddSystemIncludeDirectories(const std::set<cmStdString> &incs);
- void AddSystemIncludeDirectories(const std::vector<std::string> &incs);
- std::set<cmStdString> const & GetSystemIncludeDirectories() const
- { return this->SystemIncludeDirectories; }
+ cmStringRange GetCompileDefinitionsEntries() const;
+ cmBacktraceRange GetCompileDefinitionsBacktraces() const;
- void FinalizeSystemIncludeDirectories();
+ cmStringRange GetSourceEntries() const;
+ cmBacktraceRange GetSourceBacktraces() const;
+ cmStringRange GetLinkImplementationEntries() const;
+ cmBacktraceRange GetLinkImplementationBacktraces() const;
- bool LinkLanguagePropagatesToDependents() const
- { return this->TargetTypeValue == STATIC_LIBRARY; }
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ const LinkLibraryVectorType &GetLinkLibrariesForVS6() const {
+ return this->LinkLibrariesForVS6;}
-private:
- // The set of include directories that are marked as system include
- // directories.
- std::set<cmStdString> SystemIncludeDirectories;
+ void AnalyzeLibDependenciesForVS6( const cmMakefile& mf );
+#endif
- std::vector<std::pair<TLLSignature, cmListFileBacktrace> > TLLCommands;
+ struct StrictTargetComparison {
+ bool operator()(cmTarget const* t1, cmTarget const* t2) const;
+ };
+
+private:
+ bool HandleLocationPropertyPolicy(cmMakefile* context) const;
+#if defined(_WIN32) && !defined(__CYGWIN__)
/**
* A list of direct dependencies. Use in conjunction with DependencyMap.
*/
@@ -575,16 +276,16 @@ private:
/**
* Inserts \a dep at the end of the dependency list of \a lib.
*/
- void InsertDependency( DependencyMap& depMap,
- const LibraryID& lib,
- const LibraryID& dep);
+ void InsertDependencyForVS6( DependencyMap& depMap,
+ const LibraryID& lib,
+ const LibraryID& dep);
/*
* Deletes \a dep from the dependency list of \a lib.
*/
- void DeleteDependency( DependencyMap& depMap,
- const LibraryID& lib,
- const LibraryID& dep);
+ void DeleteDependencyForVS6( DependencyMap& depMap,
+ const LibraryID& lib,
+ const LibraryID& dep);
/**
* Emits the library \a lib and all its dependencies into link_line.
@@ -594,148 +295,90 @@ private:
* link_line is in reverse order, in that the dependencies of a
* library are listed before the library itself.
*/
- void Emit( const LibraryID lib,
- const DependencyMap& dep_map,
- std::set<LibraryID>& emitted,
- std::set<LibraryID>& visited,
- DependencyList& link_line);
+ void EmitForVS6( const LibraryID lib,
+ const DependencyMap& dep_map,
+ std::set<LibraryID>& emitted,
+ std::set<LibraryID>& visited,
+ DependencyList& link_line);
/**
* Finds the dependencies for \a lib and inserts them into \a
* dep_map.
*/
- void GatherDependencies( const cmMakefile& mf,
- const LibraryID& lib,
- DependencyMap& dep_map);
-
- void AnalyzeLibDependencies( const cmMakefile& mf );
+ void GatherDependenciesForVS6( const cmMakefile& mf,
+ const LibraryID& lib,
+ DependencyMap& dep_map);
+#endif
- const char* GetSuffixVariableInternal(bool implib);
- const char* GetPrefixVariableInternal(bool implib);
- std::string GetFullNameInternal(const char* config, bool implib);
- void GetFullNameInternal(const char* config, bool implib,
- std::string& outPrefix, std::string& outBase,
- std::string& outSuffix);
+ const char* GetSuffixVariableInternal(bool implib) const;
+ const char* GetPrefixVariableInternal(bool implib) const;
// Use a makefile variable to set a default for the given property.
// If the variable is not defined use the given default instead.
- void SetPropertyDefault(const char* property, const char* default_value);
-
- // Returns ARCHIVE, LIBRARY, or RUNTIME based on platform and type.
- const char* GetOutputTargetType(bool implib);
-
- // Get the target base name.
- std::string GetOutputName(const char* config, bool implib);
+ void SetPropertyDefault(const std::string& property,
+ const char* default_value);
- const char* ImportedGetLocation(const char* config);
- const char* NormalGetLocation(const char* config);
-
- std::string GetFullNameImported(const char* config, bool implib);
-
- std::string ImportedGetFullPath(const char* config, bool implib);
- std::string NormalGetFullPath(const char* config, bool implib,
- bool realname);
-
- /** Get the real name of the target. Allowed only for non-imported
- targets. When a library or executable file is versioned this is
- the full versioned name. If the target is not versioned this is
- the same as GetFullName. */
- std::string NormalGetRealName(const char* config);
-
- /** Append to @a base the mac content directory and return it. */
- std::string BuildMacContentDirectory(const std::string& base,
- const char* config,
- bool contentOnly);
+ std::string ImportedGetFullPath(const std::string& config,
+ bool implib) const;
private:
+ mutable cmPropertyMap Properties;
+ std::set<std::string> SystemIncludeDirectories;
+ std::set<std::string> LinkDirectoriesEmmitted;
+ std::set<std::string> Utilities;
+ std::map<std::string, cmListFileBacktrace> UtilityBacktraces;
+ cmPolicies::PolicyMap PolicyMap;
std::string Name;
+ std::string InstallPath;
+ std::string RuntimeInstallPath;
+ std::vector<std::string> LinkDirectories;
std::vector<cmCustomCommand> PreBuildCommands;
std::vector<cmCustomCommand> PreLinkCommands;
std::vector<cmCustomCommand> PostBuildCommands;
- TargetType TargetTypeValue;
- std::vector<cmSourceFile*> SourceFiles;
- std::vector<std::string> ObjectLibraries;
- LinkLibraryVectorType LinkLibraries;
+ std::vector<std::pair<TLLSignature, cmListFileContext> > TLLCommands;
LinkLibraryVectorType PrevLinkedLibraries;
- bool LinkLibrariesAnalyzed;
- std::vector<std::string> LinkDirectories;
- std::set<cmStdString> LinkDirectoriesEmmitted;
+ LinkLibraryVectorType OriginalLinkLibraries;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ LinkLibraryVectorType LinkLibrariesForVS6;
+#endif
+ cmMakefile* Makefile;
+ cmTargetInternalPointer Internal;
+ cmState::TargetType TargetTypeValue;
bool HaveInstallRule;
- std::string InstallPath;
- std::string RuntimeInstallPath;
- std::string Location;
- std::string ExportMacro;
- std::set<cmStdString> Utilities;
bool RecordDependencies;
- cmPropertyMap Properties;
- LinkLibraryVectorType OriginalLinkLibraries;
bool DLLPlatform;
- bool IsApple;
+ bool IsAndroid;
bool IsImportedTarget;
- bool DebugIncludesDone;
- bool DebugCompileOptionsDone;
- bool DebugCompileDefinitionsDone;
- mutable std::set<std::string> LinkImplicitNullProperties;
+ bool ImportedGloballyVisible;
bool BuildInterfaceIncludesAppended;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ bool LinkLibrariesForVS6Analyzed;
+#endif
- // Cache target output paths for each configuration.
- struct OutputInfo;
- OutputInfo const* GetOutputInfo(const char* config);
- bool ComputeOutputDir(const char* config, bool implib, std::string& out);
- bool ComputePDBOutputDir(const char* config, std::string& out);
-
- // Cache import information from properties for each configuration.
- struct ImportInfo;
- ImportInfo const* GetImportInfo(const char* config,
- cmTarget *workingTarget);
- void ComputeImportInfo(std::string const& desired_config, ImportInfo& info,
- cmTarget *head);
-
- cmTargetLinkInformationMap LinkInformation;
- void CheckPropertyCompatibility(cmComputeLinkInformation *info,
- const char* config);
-
- bool ComputeLinkInterface(const char* config, LinkInterface& iface,
- cmTarget *head);
-
- void ComputeLinkImplementation(const char* config,
- LinkImplementation& impl, cmTarget *head);
- void ComputeLinkClosure(const char* config, LinkClosure& lc, cmTarget *head);
-
- void ClearLinkMaps();
-
- void MaybeInvalidatePropertyCache(const char* prop);
-
- void ProcessSourceExpression(std::string const& expr);
-
- // The cmMakefile instance that owns this target. This should
- // always be set.
- cmMakefile* Makefile;
-
- // Policy status recorded when target was created.
-#define TARGET_POLICY_MEMBER(POLICY) \
- cmPolicies::PolicyStatus PolicyStatus ## POLICY;
-
- CM_FOR_EACH_TARGET_POLICY(TARGET_POLICY_MEMBER)
+ std::string ProcessSourceItemCMP0049(const std::string& s);
-#undef TARGET_POLICY_MEMBER
+ /** Return whether or not the target has a DLL import library. */
+ bool HasImportLibrary() const;
// Internal representation details.
friend class cmTargetInternals;
- cmTargetInternalPointer Internal;
+ friend class cmGeneratorTarget;
+ friend class cmTargetTraceDependencies;
- void ConstructSourceFileFlags();
- void ComputeVersionedName(std::string& vName,
- std::string const& prefix,
- std::string const& base,
- std::string const& suffix,
- std::string const& name,
- const char* version);
+ cmListFileBacktrace Backtrace;
};
-typedef std::map<cmStdString,cmTarget> cmTargets;
+#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifdef CMake_HAVE_CXX11_UNORDERED_MAP
+typedef std::unordered_map<std::string, cmTarget> cmTargets;
+#else
+typedef cmsys::hash_map<std::string, cmTarget> cmTargets;
+#endif
+#else
+typedef std::map<std::string,cmTarget> cmTargets;
+#endif
-class cmTargetSet: public std::set<cmStdString> {};
-class cmTargetManifest: public std::map<cmStdString, cmTargetSet> {};
+class cmTargetSet: public std::set<std::string> {};
+class cmTargetManifest: public std::map<std::string, cmTargetSet> {};
#endif
diff --git a/Source/cmTargetCompileDefinitionsCommand.cxx b/Source/cmTargetCompileDefinitionsCommand.cxx
index 46c9666ef..394a16627 100644
--- a/Source/cmTargetCompileDefinitionsCommand.cxx
+++ b/Source/cmTargetCompileDefinitionsCommand.cxx
@@ -11,6 +11,8 @@
============================================================================*/
#include "cmTargetCompileDefinitionsCommand.h"
+#include "cmAlgorithms.h"
+
bool cmTargetCompileDefinitionsCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
@@ -20,7 +22,7 @@ bool cmTargetCompileDefinitionsCommand
void cmTargetCompileDefinitionsCommand
::HandleImportedTarget(const std::string &tgt)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Cannot specify compile definitions for imported target \""
<< tgt << "\".";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
@@ -29,7 +31,7 @@ void cmTargetCompileDefinitionsCommand
void cmTargetCompileDefinitionsCommand
::HandleMissingTarget(const std::string &name)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Cannot specify compile definitions for target \"" << name << "\" "
"which is not built by this project.";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
@@ -44,7 +46,7 @@ std::string cmTargetCompileDefinitionsCommand
for(std::vector<std::string>::const_iterator it = content.begin();
it != content.end(); ++it)
{
- if (strncmp(it->c_str(), "-D", 2) == 0)
+ if (cmHasLiteralPrefix(it->c_str(), "-D"))
{
defs += sep + it->substr(2);
}
@@ -58,9 +60,10 @@ std::string cmTargetCompileDefinitionsCommand
}
//----------------------------------------------------------------------------
-void cmTargetCompileDefinitionsCommand
+bool cmTargetCompileDefinitionsCommand
::HandleDirectContent(cmTarget *tgt, const std::vector<std::string> &content,
bool, bool)
{
tgt->AppendProperty("COMPILE_DEFINITIONS", this->Join(content).c_str());
+ return true;
}
diff --git a/Source/cmTargetCompileDefinitionsCommand.h b/Source/cmTargetCompileDefinitionsCommand.h
index 585485d2a..b548c70a0 100644
--- a/Source/cmTargetCompileDefinitionsCommand.h
+++ b/Source/cmTargetCompileDefinitionsCommand.h
@@ -36,42 +36,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "target_compile_definitions";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return
- "Add compile definitions to a target.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " target_compile_definitions(<target> "
- "<INTERFACE|PUBLIC|PRIVATE> [items1...]\n"
- " [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])\n"
- "Specify compile definitions to use when compiling a given target. "
- "The named <target> must have been created by a command such as "
- "add_executable or add_library and must not be an IMPORTED target. "
- "The INTERFACE, PUBLIC and PRIVATE keywords are required to specify "
- "the scope of the following arguments. PRIVATE and PUBLIC items will "
- "populate the COMPILE_DEFINITIONS property of <target>. PUBLIC and "
- "INTERFACE items will populate the INTERFACE_COMPILE_DEFINITIONS "
- "property of <target>. "
- "The following arguments specify compile definitions. "
- "Repeated calls for the same <target> append items in the order called."
- "\n"
- "Arguments to target_compile_definitions may use \"generator "
- "expressions\" with the syntax \"$<...>\". "
- CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS
- ;
- }
+ virtual std::string GetName() const { return "target_compile_definitions";}
cmTypeMacro(cmTargetCompileDefinitionsCommand, cmTargetPropCommandBase);
@@ -79,7 +44,7 @@ private:
virtual void HandleImportedTarget(const std::string &tgt);
virtual void HandleMissingTarget(const std::string &name);
- virtual void HandleDirectContent(cmTarget *tgt,
+ virtual bool HandleDirectContent(cmTarget *tgt,
const std::vector<std::string> &content,
bool prepend, bool system);
virtual std::string Join(const std::vector<std::string> &content);
diff --git a/Source/cmTargetCompileFeaturesCommand.cxx b/Source/cmTargetCompileFeaturesCommand.cxx
new file mode 100644
index 000000000..823afa1bd
--- /dev/null
+++ b/Source/cmTargetCompileFeaturesCommand.cxx
@@ -0,0 +1,64 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2013 Stephen Kelly <steveire@gmail.com>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmTargetCompileFeaturesCommand.h"
+
+#include "cmAlgorithms.h"
+
+bool cmTargetCompileFeaturesCommand::InitialPass(
+ std::vector<std::string> const& args,
+ cmExecutionStatus &)
+{
+ return this->HandleArguments(args, "COMPILE_FEATURES", NO_FLAGS);
+}
+
+void cmTargetCompileFeaturesCommand
+::HandleImportedTarget(const std::string &tgt)
+{
+ std::ostringstream e;
+ e << "Cannot specify compile features for imported target \""
+ << tgt << "\".";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+}
+
+void cmTargetCompileFeaturesCommand
+::HandleMissingTarget(const std::string &name)
+{
+ std::ostringstream e;
+ e << "Cannot specify compile features for target \"" << name << "\" "
+ "which is not built by this project.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+}
+
+//----------------------------------------------------------------------------
+std::string cmTargetCompileFeaturesCommand
+::Join(const std::vector<std::string> &content)
+{
+ return cmJoin(content, ";");
+}
+
+//----------------------------------------------------------------------------
+bool cmTargetCompileFeaturesCommand
+::HandleDirectContent(cmTarget *tgt, const std::vector<std::string> &content,
+ bool, bool)
+{
+ for(std::vector<std::string>::const_iterator it = content.begin();
+ it != content.end(); ++it)
+ {
+ std::string error;
+ if(!this->Makefile->AddRequiredTargetFeature(tgt, *it, &error))
+ {
+ this->SetError(error);
+ return false;
+ }
+ }
+ return true;
+}
diff --git a/Source/cmTargetCompileFeaturesCommand.h b/Source/cmTargetCompileFeaturesCommand.h
new file mode 100644
index 000000000..fa7ae8d07
--- /dev/null
+++ b/Source/cmTargetCompileFeaturesCommand.h
@@ -0,0 +1,41 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2013 Stephen Kelly <steveire@gmail.com>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmTargetCompileFeaturesCommand_h
+#define cmTargetCompileFeaturesCommand_h
+
+#include "cmTargetPropCommandBase.h"
+
+class cmTargetCompileFeaturesCommand : public cmTargetPropCommandBase
+{
+ virtual cmCommand* Clone()
+ {
+ return new cmTargetCompileFeaturesCommand;
+ }
+
+ virtual bool InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus &status);
+
+ virtual std::string GetName() const { return "target_compile_features";}
+
+ cmTypeMacro(cmTargetCompileFeaturesCommand, cmTargetPropCommandBase);
+
+private:
+ virtual void HandleImportedTarget(const std::string &tgt);
+ virtual void HandleMissingTarget(const std::string &name);
+
+ virtual bool HandleDirectContent(cmTarget *tgt,
+ const std::vector<std::string> &content,
+ bool prepend, bool system);
+ virtual std::string Join(const std::vector<std::string> &content);
+};
+
+#endif
diff --git a/Source/cmTargetCompileOptionsCommand.cxx b/Source/cmTargetCompileOptionsCommand.cxx
index 254acc73d..8e86f0f79 100644
--- a/Source/cmTargetCompileOptionsCommand.cxx
+++ b/Source/cmTargetCompileOptionsCommand.cxx
@@ -11,6 +11,8 @@
============================================================================*/
#include "cmTargetCompileOptionsCommand.h"
+#include "cmAlgorithms.h"
+
bool cmTargetCompileOptionsCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
@@ -20,7 +22,7 @@ bool cmTargetCompileOptionsCommand
void cmTargetCompileOptionsCommand
::HandleImportedTarget(const std::string &tgt)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Cannot specify compile options for imported target \""
<< tgt << "\".";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
@@ -29,7 +31,7 @@ void cmTargetCompileOptionsCommand
void cmTargetCompileOptionsCommand
::HandleMissingTarget(const std::string &name)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Cannot specify compile options for target \"" << name << "\" "
"which is not built by this project.";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
@@ -39,24 +41,15 @@ void cmTargetCompileOptionsCommand
std::string cmTargetCompileOptionsCommand
::Join(const std::vector<std::string> &content)
{
- std::string defs;
- std::string sep;
- for(std::vector<std::string>::const_iterator it = content.begin();
- it != content.end(); ++it)
- {
- defs += sep + *it;
- sep = ";";
- }
- return defs;
+ return cmJoin(content, ";");
}
//----------------------------------------------------------------------------
-void cmTargetCompileOptionsCommand
+bool cmTargetCompileOptionsCommand
::HandleDirectContent(cmTarget *tgt, const std::vector<std::string> &content,
bool, bool)
{
- cmListFileBacktrace lfbt;
- this->Makefile->GetBacktrace(lfbt);
- cmValueWithOrigin entry(this->Join(content), lfbt);
- tgt->InsertCompileOption(entry);
+ cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+ tgt->InsertCompileOption(this->Join(content), lfbt);
+ return true;
}
diff --git a/Source/cmTargetCompileOptionsCommand.h b/Source/cmTargetCompileOptionsCommand.h
index b9afd7169..d43534d4a 100644
--- a/Source/cmTargetCompileOptionsCommand.h
+++ b/Source/cmTargetCompileOptionsCommand.h
@@ -36,44 +36,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "target_compile_options";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return
- "Add compile options to a target.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " target_compile_options(<target> [BEFORE] "
- "<INTERFACE|PUBLIC|PRIVATE> [items1...]\n"
- " [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])\n"
- "Specify compile options to use when compiling a given target. "
- "The named <target> must have been created by a command such as "
- "add_executable or add_library and must not be an IMPORTED target. "
- "If BEFORE is specified, the content will be prepended to the property "
- "instead of being appended.\n"
- "The INTERFACE, PUBLIC and PRIVATE keywords are required to specify "
- "the scope of the following arguments. PRIVATE and PUBLIC items will "
- "populate the COMPILE_OPTIONS property of <target>. PUBLIC and "
- "INTERFACE items will populate the INTERFACE_COMPILE_OPTIONS "
- "property of <target>. "
- "The following arguments specify compile opitions. "
- "Repeated calls for the same <target> append items in the order called."
- "\n"
- "Arguments to target_compile_options may use \"generator "
- "expressions\" with the syntax \"$<...>\". "
- CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS
- ;
- }
+ virtual std::string GetName() const { return "target_compile_options";}
cmTypeMacro(cmTargetCompileOptionsCommand, cmTargetPropCommandBase);
@@ -81,7 +44,7 @@ private:
virtual void HandleImportedTarget(const std::string &tgt);
virtual void HandleMissingTarget(const std::string &name);
- virtual void HandleDirectContent(cmTarget *tgt,
+ virtual bool HandleDirectContent(cmTarget *tgt,
const std::vector<std::string> &content,
bool prepend, bool system);
virtual std::string Join(const std::vector<std::string> &content);
diff --git a/Source/cmTargetDepend.h b/Source/cmTargetDepend.h
index 258bacd6d..c5059ee2b 100644
--- a/Source/cmTargetDepend.h
+++ b/Source/cmTargetDepend.h
@@ -14,23 +14,24 @@
#include "cmStandardIncludes.h"
-class cmTarget;
+class cmGeneratorTarget;
/** One edge in the global target dependency graph.
It may be marked as a 'link' or 'util' edge or both. */
class cmTargetDepend
{
- cmTarget* Target;
+ cmGeneratorTarget const* Target;
// The set order depends only on the Target, so we use
// mutable members to acheive a map with set syntax.
mutable bool Link;
mutable bool Util;
public:
- cmTargetDepend(cmTarget* t): Target(t), Link(false), Util(false) {}
- operator cmTarget*() const { return this->Target; }
- cmTarget* operator->() const { return this->Target; }
- cmTarget& operator*() const { return *this->Target; }
+ cmTargetDepend(cmGeneratorTarget const* t)
+ : Target(t), Link(false), Util(false) {}
+ operator cmGeneratorTarget const*() const { return this->Target; }
+ cmGeneratorTarget const* operator->() const { return this->Target; }
+ cmGeneratorTarget const& operator*() const { return *this->Target; }
friend bool operator < (cmTargetDepend const& l, cmTargetDepend const& r)
{ return l.Target < r.Target; }
void SetType(bool strong) const
diff --git a/Source/cmTargetExport.h b/Source/cmTargetExport.h
index 76658887d..2781337fe 100644
--- a/Source/cmTargetExport.h
+++ b/Source/cmTargetExport.h
@@ -14,7 +14,7 @@
#include "cmStandardIncludes.h"
-class cmTarget;
+class cmGeneratorTarget;
class cmInstallTargetGenerator;
class cmInstallFilesGenerator;
@@ -25,7 +25,8 @@ class cmInstallFilesGenerator;
class cmTargetExport
{
public:
- cmTarget* Target; ///< The target
+ std::string TargetName;
+ cmGeneratorTarget* Target;
///@name Generators
///@{
diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx
index e7b906c9e..7dfe9ca38 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.cxx
+++ b/Source/cmTargetIncludeDirectoriesCommand.cxx
@@ -11,6 +11,8 @@
============================================================================*/
#include "cmTargetIncludeDirectoriesCommand.h"
+#include "cmGeneratorExpression.h"
+
//----------------------------------------------------------------------------
bool cmTargetIncludeDirectoriesCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
@@ -23,7 +25,7 @@ bool cmTargetIncludeDirectoriesCommand
void cmTargetIncludeDirectoriesCommand
::HandleImportedTarget(const std::string &tgt)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Cannot specify include directories for imported target \""
<< tgt << "\".";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
@@ -33,7 +35,7 @@ void cmTargetIncludeDirectoriesCommand
void cmTargetIncludeDirectoriesCommand
::HandleMissingTarget(const std::string &name)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Cannot specify include directories for target \"" << name << "\" "
"which is not built by this project.";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
@@ -45,12 +47,13 @@ std::string cmTargetIncludeDirectoriesCommand
{
std::string dirs;
std::string sep;
- std::string prefix = this->Makefile->GetStartDirectory() + std::string("/");
+ std::string prefix =
+ this->Makefile->GetCurrentSourceDirectory() + std::string("/");
for(std::vector<std::string>::const_iterator it = content.begin();
it != content.end(); ++it)
{
if (cmSystemTools::FileIsFullPath(it->c_str())
- || cmGeneratorExpression::Find(*it) != std::string::npos)
+ || cmGeneratorExpression::Find(*it) == 0)
{
dirs += sep + *it;
}
@@ -64,18 +67,33 @@ std::string cmTargetIncludeDirectoriesCommand
}
//----------------------------------------------------------------------------
-void cmTargetIncludeDirectoriesCommand
+bool cmTargetIncludeDirectoriesCommand
::HandleDirectContent(cmTarget *tgt, const std::vector<std::string> &content,
bool prepend, bool system)
{
- cmListFileBacktrace lfbt;
- this->Makefile->GetBacktrace(lfbt);
- cmValueWithOrigin entry(this->Join(content), lfbt);
- tgt->InsertInclude(entry, prepend);
+ cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+ tgt->InsertInclude(this->Join(content), lfbt, prepend);
if (system)
{
- tgt->AddSystemIncludeDirectories(content);
+ std::string prefix =
+ this->Makefile->GetCurrentSourceDirectory() + std::string("/");
+ std::set<std::string> sdirs;
+ for (std::vector<std::string>::const_iterator it = content.begin();
+ it != content.end(); ++it)
+ {
+ if (cmSystemTools::FileIsFullPath(it->c_str())
+ || cmGeneratorExpression::Find(*it) == 0)
+ {
+ sdirs.insert(*it);
+ }
+ else
+ {
+ sdirs.insert(prefix + *it);
+ }
+ }
+ tgt->AddSystemIncludeDirectories(sdirs);
}
+ return true;
}
//----------------------------------------------------------------------------
@@ -89,15 +107,7 @@ void cmTargetIncludeDirectoriesCommand
if (system)
{
- std::string joined;
- std::string sep;
- for(std::vector<std::string>::const_iterator it = content.begin();
- it != content.end(); ++it)
- {
- joined += sep;
- sep = ";";
- joined += *it;
- }
+ std::string joined = this->Join(content);
tgt->AppendProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES",
joined.c_str());
}
diff --git a/Source/cmTargetIncludeDirectoriesCommand.h b/Source/cmTargetIncludeDirectoriesCommand.h
index fcc37f06a..2a7814e78 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.h
+++ b/Source/cmTargetIncludeDirectoriesCommand.h
@@ -37,54 +37,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "target_include_directories";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return
- "Add include directories to a target.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " target_include_directories(<target> [SYSTEM] [BEFORE] "
- "<INTERFACE|PUBLIC|PRIVATE> [items1...]\n"
- " [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])\n"
- "Specify include directories or targets to use when compiling a given "
- "target. "
- "The named <target> must have been created by a command such as "
- "add_executable or add_library and must not be an IMPORTED target.\n"
- "If BEFORE is specified, the content will be prepended to the property "
- "instead of being appended.\n"
- "The INTERFACE, PUBLIC and PRIVATE keywords are required to specify "
- "the scope of the following arguments. PRIVATE and PUBLIC items will "
- "populate the INCLUDE_DIRECTORIES property of <target>. PUBLIC and "
- "INTERFACE items will populate the INTERFACE_INCLUDE_DIRECTORIES "
- "property of <target>. "
- "The following arguments specify include directories. Specified "
- "include directories may be absolute paths or relative paths. "
- "Repeated calls for the same <target> append items in the order called."
- "If SYSTEM is specified, the compiler will be told the "
- "directories are meant as system include directories on some "
- "platforms (signalling this setting might achieve effects such as "
- "the compiler skipping warnings, or these fixed-install system files "
- "not being considered in dependency calculations - see compiler "
- "docs). If SYSTEM is used together with PUBLIC or INTERFACE, the "
- "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES target property will be "
- "populated with the specified directories."
- "\n"
- "Arguments to target_include_directories may use \"generator "
- "expressions\" with the syntax \"$<...>\". "
- CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS
- ;
- }
+ virtual std::string GetName() const { return "target_include_directories";}
cmTypeMacro(cmTargetIncludeDirectoriesCommand, cmTargetPropCommandBase);
@@ -92,7 +45,7 @@ private:
virtual void HandleImportedTarget(const std::string &tgt);
virtual void HandleMissingTarget(const std::string &name);
- virtual void HandleDirectContent(cmTarget *tgt,
+ virtual bool HandleDirectContent(cmTarget *tgt,
const std::vector<std::string> &content,
bool prepend, bool system);
virtual void HandleInterfaceContent(cmTarget *tgt,
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index c2f46a1b1..435346a30 100644
--- a/Source/cmTargetLinkLibrariesCommand.cxx
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -31,7 +31,7 @@ bool cmTargetLinkLibrariesCommand
return false;
}
- if (this->Makefile->IsAlias(args[0].c_str()))
+ if (this->Makefile->IsAlias(args[0]))
{
this->SetError("can not be used on an ALIAS target.");
return false;
@@ -39,11 +39,11 @@ bool cmTargetLinkLibrariesCommand
// Lookup the target for which libraries are specified.
this->Target =
this->Makefile->GetCMakeInstance()
- ->GetGlobalGenerator()->FindTarget(0, args[0].c_str());
+ ->GetGlobalGenerator()->FindTarget(args[0]);
if(!this->Target)
{
cmake::MessageType t = cmake::FATAL_ERROR; // fail by default
- cmOStringStream e;
+ std::ostringstream e;
e << "Cannot specify link libraries for target \"" << args[0] << "\" "
<< "which is not built by this project.";
// The bad target is the only argument. Check how policy CMP0016 is set,
@@ -58,19 +58,16 @@ bool cmTargetLinkLibrariesCommand
e << "\n"
<< "CMake does not support this but it used to work accidentally "
<< "and is being allowed for compatibility."
- << "\n" << this->Makefile->GetPolicies()->
- GetPolicyWarning(cmPolicies::CMP0016);
+ << "\n" << cmPolicies::GetPolicyWarning(cmPolicies::CMP0016);
break;
case cmPolicies::OLD: // OLD behavior does not warn.
t = cmake::MESSAGE;
break;
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
- e << "\n" << this->Makefile->GetPolicies()->
- GetRequiredPolicyError(cmPolicies::CMP0016);
+ e << "\n" << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0016);
break;
case cmPolicies::NEW: // NEW behavior prints the error.
- default:
break;
}
}
@@ -91,9 +88,9 @@ bool cmTargetLinkLibrariesCommand
return true;
}
- if(this->Target->GetType() == cmTarget::OBJECT_LIBRARY)
+ if(this->Target->GetType() == cmState::OBJECT_LIBRARY)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "Object library target \"" << args[0] << "\" "
<< "may not link to anything.";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
@@ -101,6 +98,37 @@ bool cmTargetLinkLibrariesCommand
return true;
}
+ if (this->Target->GetType() == cmState::UTILITY)
+ {
+ std::ostringstream e;
+ const char *modal = 0;
+ cmake::MessageType messageType = cmake::AUTHOR_WARNING;
+ switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0039))
+ {
+ case cmPolicies::WARN:
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0039) << "\n";
+ modal = "should";
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::NEW:
+ modal = "must";
+ messageType = cmake::FATAL_ERROR;
+ }
+ if (modal)
+ {
+ e <<
+ "Utility target \"" << this->Target->GetName() << "\" " << modal
+ << " not be used as the target of a target_link_libraries call.";
+ this->Makefile->IssueMessage(messageType, e.str());
+ if(messageType == cmake::FATAL_ERROR)
+ {
+ return false;
+ }
+ }
+ }
+
// but we might not have any libs after variable expansion
if(args.size() < 2)
{
@@ -108,7 +136,7 @@ bool cmTargetLinkLibrariesCommand
}
// Keep track of link configuration specifiers.
- cmTarget::LinkLibraryType llt = cmTarget::GENERAL;
+ cmTargetLinkLibraryType llt = GENERAL_LibraryType;
bool haveLLT = false;
// Start with primary linking and switch to link interface
@@ -151,7 +179,8 @@ bool cmTargetLinkLibrariesCommand
else if(args[i] == "LINK_PUBLIC")
{
if(i != 1
- && this->CurrentProcessingState != ProcessingPlainPrivateInterface)
+ && this->CurrentProcessingState != ProcessingPlainPrivateInterface
+ && this->CurrentProcessingState != ProcessingPlainPublicInterface)
{
this->Makefile->IssueMessage(
cmake::FATAL_ERROR,
@@ -181,7 +210,8 @@ bool cmTargetLinkLibrariesCommand
else if(args[i] == "LINK_PRIVATE")
{
if(i != 1
- && this->CurrentProcessingState != ProcessingPlainPublicInterface)
+ && this->CurrentProcessingState != ProcessingPlainPublicInterface
+ && this->CurrentProcessingState != ProcessingPlainPrivateInterface)
{
this->Makefile->IssueMessage(
cmake::FATAL_ERROR,
@@ -212,34 +242,34 @@ bool cmTargetLinkLibrariesCommand
{
if(haveLLT)
{
- this->LinkLibraryTypeSpecifierWarning(llt, cmTarget::DEBUG);
+ this->LinkLibraryTypeSpecifierWarning(llt, DEBUG_LibraryType);
}
- llt = cmTarget::DEBUG;
+ llt = DEBUG_LibraryType;
haveLLT = true;
}
else if(args[i] == "optimized")
{
if(haveLLT)
{
- this->LinkLibraryTypeSpecifierWarning(llt, cmTarget::OPTIMIZED);
+ this->LinkLibraryTypeSpecifierWarning(llt, OPTIMIZED_LibraryType);
}
- llt = cmTarget::OPTIMIZED;
+ llt = OPTIMIZED_LibraryType;
haveLLT = true;
}
else if(args[i] == "general")
{
if(haveLLT)
{
- this->LinkLibraryTypeSpecifierWarning(llt, cmTarget::GENERAL);
+ this->LinkLibraryTypeSpecifierWarning(llt, GENERAL_LibraryType);
}
- llt = cmTarget::GENERAL;
+ llt = GENERAL_LibraryType;
haveLLT = true;
}
else if(haveLLT)
{
// The link type was specified by the previous argument.
haveLLT = false;
- if (!this->HandleLibrary(args[i].c_str(), llt))
+ if (!this->HandleLibrary(args[i], llt))
{
return false;
}
@@ -252,23 +282,23 @@ bool cmTargetLinkLibrariesCommand
// specifed that a library is both debug and optimized. (this check is
// only there for backwards compatibility when mixing projects built
// with old versions of CMake and new)
- llt = cmTarget::GENERAL;
+ llt = GENERAL_LibraryType;
std::string linkType = args[0];
linkType += "_LINK_TYPE";
const char* linkTypeString =
- this->Makefile->GetDefinition( linkType.c_str() );
+ this->Makefile->GetDefinition( linkType );
if(linkTypeString)
{
if(strcmp(linkTypeString, "debug") == 0)
{
- llt = cmTarget::DEBUG;
+ llt = DEBUG_LibraryType;
}
if(strcmp(linkTypeString, "optimized") == 0)
{
- llt = cmTarget::OPTIMIZED;
+ llt = OPTIMIZED_LibraryType;
}
}
- if (!this->HandleLibrary(args[i].c_str(), llt))
+ if (!this->HandleLibrary(args[i], llt))
{
return false;
}
@@ -278,7 +308,7 @@ bool cmTargetLinkLibrariesCommand
// Make sure the last argument was not a library type specifier.
if(haveLLT)
{
- cmOStringStream e;
+ std::ostringstream e;
e << "The \"" << this->LinkLibraryTypeNames[llt]
<< "\" argument must be followed by a library.";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
@@ -309,7 +339,7 @@ void
cmTargetLinkLibrariesCommand
::LinkLibraryTypeSpecifierWarning(int left, int right)
{
- cmOStringStream w;
+ std::ostringstream w;
w << "Link library type specifier \""
<< this->LinkLibraryTypeNames[left] << "\" is followed by specifier \""
<< this->LinkLibraryTypeNames[right] << "\" instead of a library name. "
@@ -319,9 +349,18 @@ cmTargetLinkLibrariesCommand
//----------------------------------------------------------------------------
bool
-cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
- cmTarget::LinkLibraryType llt)
+cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib,
+ cmTargetLinkLibraryType llt)
{
+ if(this->Target->GetType() == cmState::INTERFACE_LIBRARY
+ && this->CurrentProcessingState != ProcessingKeywordLinkInterface)
+ {
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR,
+ "INTERFACE library can only be used with the INTERFACE keyword of "
+ "target_link_libraries");
+ return false;
+ }
+
cmTarget::TLLSignature sig =
(this->CurrentProcessingState == ProcessingPlainPrivateInterface
|| this->CurrentProcessingState == ProcessingPlainPublicInterface
@@ -329,13 +368,16 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
|| this->CurrentProcessingState == ProcessingKeywordPublicInterface
|| this->CurrentProcessingState == ProcessingKeywordLinkInterface)
? cmTarget::KeywordTLLSignature : cmTarget::PlainTLLSignature;
- if (!this->Target->PushTLLCommandTrace(sig))
+ if (!this->Target->PushTLLCommandTrace(
+ sig, this->Makefile->GetExecutionContext()))
{
+ std::ostringstream e;
const char *modal = 0;
cmake::MessageType messageType = cmake::AUTHOR_WARNING;
switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0023))
{
case cmPolicies::WARN:
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0023) << "\n";
modal = "should";
case cmPolicies::OLD:
break;
@@ -348,14 +390,12 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
if(modal)
{
- cmOStringStream e;
// If the sig is a keyword form and there is a conflict, the existing
// form must be the plain form.
const char *existingSig
= (sig == cmTarget::KeywordTLLSignature ? "plain"
: "keyword");
- e << this->Makefile->GetPolicies()
- ->GetPolicyWarning(cmPolicies::CMP0023) << "\n"
+ e <<
"The " << existingSig << " signature for target_link_libraries "
"has already been used with the target \""
<< this->Target->GetName() << "\". All uses of "
@@ -365,7 +405,7 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
sig == cmTarget::KeywordTLLSignature
? cmTarget::PlainTLLSignature
: cmTarget::KeywordTLLSignature);
- this->Makefile->IssueMessage(messageType, e.str().c_str());
+ this->Makefile->IssueMessage(messageType, e.str());
if(messageType == cmake::FATAL_ERROR)
{
return false;
@@ -388,7 +428,7 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
else if(this->CurrentProcessingState != ProcessingKeywordPublicInterface
&& this->CurrentProcessingState != ProcessingPlainPublicInterface)
{
- if (this->Target->GetType() == cmTarget::STATIC_LIBRARY)
+ if (this->Target->GetType() == cmState::STATIC_LIBRARY)
{
std::string configLib = this->Target
->GetDebugGeneratorExpressions(lib, llt);
@@ -418,13 +458,18 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
return true;
}
+ if (this->Target->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ return true;
+ }
+
// Get the list of configurations considered to be DEBUG.
- std::vector<std::string> const& debugConfigs =
+ std::vector<std::string> debugConfigs =
this->Makefile->GetCMakeInstance()->GetDebugConfigs();
std::string prop;
// Include this library in the link interface for the target.
- if(llt == cmTarget::DEBUG || llt == cmTarget::GENERAL)
+ if(llt == DEBUG_LibraryType || llt == GENERAL_LibraryType)
{
// Put in the DEBUG configuration interfaces.
for(std::vector<std::string>::const_iterator i = debugConfigs.begin();
@@ -432,13 +477,13 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
{
prop = "LINK_INTERFACE_LIBRARIES_";
prop += *i;
- this->Target->AppendProperty(prop.c_str(), lib);
+ this->Target->AppendProperty(prop, lib.c_str());
}
}
- if(llt == cmTarget::OPTIMIZED || llt == cmTarget::GENERAL)
+ if(llt == OPTIMIZED_LibraryType || llt == GENERAL_LibraryType)
{
// Put in the non-DEBUG configuration interfaces.
- this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES", lib);
+ this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES", lib.c_str());
// Make sure the DEBUG configuration interfaces exist so that the
// general one will not be used as a fall-back.
@@ -447,9 +492,9 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
{
prop = "LINK_INTERFACE_LIBRARIES_";
prop += *i;
- if(!this->Target->GetProperty(prop.c_str()))
+ if(!this->Target->GetProperty(prop))
{
- this->Target->SetProperty(prop.c_str(), "");
+ this->Target->SetProperty(prop, "");
}
}
}
diff --git a/Source/cmTargetLinkLibrariesCommand.h b/Source/cmTargetLinkLibrariesCommand.h
index 2cf6b03ef..f061e6d84 100644
--- a/Source/cmTargetLinkLibrariesCommand.h
+++ b/Source/cmTargetLinkLibrariesCommand.h
@@ -13,7 +13,6 @@
#define cmTargetLinkLibrariesCommand_h
#include "cmCommand.h"
-#include "cmDocumentGeneratorExpressions.h"
/** \class cmTargetLinkLibrariesCommand
* \brief Specify a list of libraries to link into executables.
@@ -43,157 +42,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "target_link_libraries";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return
- "Link a target to given libraries.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " target_link_libraries(<target> [item1 [item2 [...]]]\n"
- " [[debug|optimized|general] <item>] ...)\n"
- "Specify libraries or flags to use when linking a given target. "
- "The named <target> must have been created in the current directory "
- "by a command such as add_executable or add_library. "
- "The remaining arguments specify library names or flags. "
- "Repeated calls for the same <target> append items in the order called."
- "\n"
- "If a library name matches that of another target in the project "
- "a dependency will automatically be added in the build system to make "
- "sure the library being linked is up-to-date before the target links. "
- "Item names starting with '-', but not '-l' or '-framework', are "
- "treated as linker flags."
- "\n"
- "A \"debug\", \"optimized\", or \"general\" keyword indicates that "
- "the library immediately following it is to be used only for the "
- "corresponding build configuration. "
- "The \"debug\" keyword corresponds to the Debug configuration "
- "(or to configurations named in the DEBUG_CONFIGURATIONS global "
- "property if it is set). "
- "The \"optimized\" keyword corresponds to all other configurations. "
- "The \"general\" keyword corresponds to all configurations, and is "
- "purely optional (assumed if omitted). "
- "Higher granularity may be achieved for per-configuration rules "
- "by creating and linking to IMPORTED library targets. "
- "See the IMPORTED mode of the add_library command for more "
- "information. "
- "\n"
- "Library dependencies are transitive by default with this signature. "
- "When this target is linked into another target then the libraries "
- "linked to this target will appear on the link line for the other "
- "target too. "
- "This transitive \"link interface\" is stored in the "
- "INTERFACE_LINK_LIBRARIES target property when policy CMP0022 is set "
- "to NEW and may be overridden by setting the property directly. "
- "("
- "When CMP0022 is not set to NEW, transitive linking is builtin "
- "but may be overridden by the LINK_INTERFACE_LIBRARIES property. "
- "Calls to other signatures of this command may set the property "
- "making any libraries linked exclusively by this signature private."
- ")"
- "\n"
- "CMake will also propagate \"usage requirements\" from linked library "
- "targets. "
- "Usage requirements affect compilation of sources in the <target>. "
- "They are specified by properties defined on linked targets. "
- "During generation of the build system, CMake integrates "
- "usage requirement property values with the corresponding "
- "build properties for <target>:\n"
- " INTERFACE_COMPILE_DEFINITONS: Appends to COMPILE_DEFINITONS\n"
- " INTERFACE_INCLUDE_DIRECTORIES: Appends to INCLUDE_DIRECTORIES\n"
- " INTERFACE_POSITION_INDEPENDENT_CODE: Sets POSITION_INDEPENDENT_CODE\n"
- " or checked for consistency with existing value\n"
- "\n"
- "If an <item> is a library in a Mac OX framework, the Headers "
- "directory of the framework will also be processed as a \"usage "
- "requirement\". This has the same effect as passing the framework "
- "directory as an include directory."
- " target_link_libraries(<target>\n"
- " <PRIVATE|PUBLIC|INTERFACE> <lib> ...\n"
- " [<PRIVATE|PUBLIC|INTERFACE> <lib> ... ] ...])\n"
- "The PUBLIC, PRIVATE and INTERFACE keywords can be used to specify "
- "both the link dependencies and the link interface in one command. "
- "Libraries and targets following PUBLIC are linked to, and are "
- "made part of the link interface. Libraries and targets "
- "following PRIVATE are linked to, but are not made part of the "
- "link interface. Libraries following INTERFACE are appended "
- "to the link interface and are not used for linking <target>."
- "\n"
- " target_link_libraries(<target> LINK_INTERFACE_LIBRARIES\n"
- " [[debug|optimized|general] <lib>] ...)\n"
- "The LINK_INTERFACE_LIBRARIES mode appends the libraries "
- "to the INTERFACE_LINK_LIBRARIES target property instead of using them "
- "for linking. If policy CMP0022 is not NEW, then this mode also "
- "appends libraries to the LINK_INTERFACE_LIBRARIES and its "
- "per-configuration equivalent. This signature "
- "is for compatibility only. Prefer the INTERFACE mode instead. "
- "Libraries specified as \"debug\" are wrapped in a generator "
- "expression to correspond to debug builds. If policy CMP0022 is not "
- "NEW, the libraries are also appended to the "
- "LINK_INTERFACE_LIBRARIES_DEBUG property (or to the properties "
- "corresponding to configurations listed in the DEBUG_CONFIGURATIONS "
- "global property if it is set). "
- "Libraries specified as \"optimized\" are appended to the "
- "INTERFACE_LINK_LIBRARIES property. If policy CMP0022 is not NEW, "
- "they are also appended to the LINK_INTERFACE_LIBRARIES property. "
- "Libraries specified as \"general\" (or without any keyword) are "
- "treated as if specified for both \"debug\" and \"optimized\"."
- "\n"
- " target_link_libraries(<target>\n"
- " <LINK_PRIVATE|LINK_PUBLIC>\n"
- " [[debug|optimized|general] <lib>] ...\n"
- " [<LINK_PRIVATE|LINK_PUBLIC>\n"
- " [[debug|optimized|general] <lib>] ...])\n"
- "The LINK_PUBLIC and LINK_PRIVATE modes can be used to specify both "
- "the link dependencies and the link interface in one command. This "
- "signature is for compatibility only. Prefer the PUBLIC or PRIVATE "
- "keywords instead. "
- "Libraries and targets following LINK_PUBLIC are linked to, and are "
- "made part of the INTERFACE_LINK_LIBRARIES. If policy CMP0022 is not "
- "NEW, they are also made part of the LINK_INTERFACE_LIBRARIES. "
- "Libraries and targets following LINK_PRIVATE are linked to, but are "
- "not made part of the INTERFACE_LINK_LIBRARIES (or "
- "LINK_INTERFACE_LIBRARIES)."
- "\n"
- "The library dependency graph is normally acyclic (a DAG), but in the "
- "case of mutually-dependent STATIC libraries CMake allows the graph "
- "to contain cycles (strongly connected components). "
- "When another target links to one of the libraries CMake repeats "
- "the entire connected component. "
- "For example, the code\n"
- " add_library(A STATIC a.c)\n"
- " add_library(B STATIC b.c)\n"
- " target_link_libraries(A B)\n"
- " target_link_libraries(B A)\n"
- " add_executable(main main.c)\n"
- " target_link_libraries(main A)\n"
- "links 'main' to 'A B A B'. "
- "("
- "While one repetition is usually sufficient, pathological object "
- "file and symbol arrangements can require more. "
- "One may handle such cases by manually repeating the component in "
- "the last target_link_libraries call. "
- "However, if two archives are really so interdependent they should "
- "probably be combined into a single archive."
- ")"
- "\n"
- "Arguments to target_link_libraries may use \"generator expressions\" "
- "with the syntax \"$<...>\". Note however, that generator expressions "
- "will not be used in OLD handling of CMP0003 or CMP0004."
- "\n"
- CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS
- ;
- }
+ virtual std::string GetName() const { return "target_link_libraries";}
cmTypeMacro(cmTargetLinkLibrariesCommand, cmCommand);
private:
@@ -213,7 +62,7 @@ private:
ProcessingState CurrentProcessingState;
- bool HandleLibrary(const char* lib, cmTarget::LinkLibraryType llt);
+ bool HandleLibrary(const std::string& lib, cmTargetLinkLibraryType llt);
};
diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx
index 1862cb696..bfc19a48d 100644
--- a/Source/cmTargetPropCommandBase.cxx
+++ b/Source/cmTargetPropCommandBase.cxx
@@ -16,8 +16,9 @@
//----------------------------------------------------------------------------
bool cmTargetPropCommandBase
-::HandleArguments(std::vector<std::string> const& args, const char *prop,
- ArgumentFlags flags)
+::HandleArguments(std::vector<std::string> const& args,
+ const std::string& prop,
+ ArgumentFlags flags)
{
if(args.size() < 2)
{
@@ -26,28 +27,29 @@ bool cmTargetPropCommandBase
}
// Lookup the target for which libraries are specified.
- if (this->Makefile->IsAlias(args[0].c_str()))
+ if (this->Makefile->IsAlias(args[0]))
{
this->SetError("can not be used on an ALIAS target.");
return false;
}
this->Target =
this->Makefile->GetCMakeInstance()
- ->GetGlobalGenerator()->FindTarget(0, args[0].c_str());
+ ->GetGlobalGenerator()->FindTarget(args[0]);
if(!this->Target)
{
- this->Target = this->Makefile->FindTargetToUse(args[0].c_str());
+ this->Target = this->Makefile->FindTargetToUse(args[0]);
}
if(!this->Target)
{
this->HandleMissingTarget(args[0]);
return false;
}
- if ((this->Target->GetType() != cmTarget::SHARED_LIBRARY)
- && (this->Target->GetType() != cmTarget::STATIC_LIBRARY)
- && (this->Target->GetType() != cmTarget::OBJECT_LIBRARY)
- && (this->Target->GetType() != cmTarget::MODULE_LIBRARY)
- && (this->Target->GetType() != cmTarget::EXECUTABLE))
+ if ((this->Target->GetType() != cmState::SHARED_LIBRARY)
+ && (this->Target->GetType() != cmState::STATIC_LIBRARY)
+ && (this->Target->GetType() != cmState::OBJECT_LIBRARY)
+ && (this->Target->GetType() != cmState::MODULE_LIBRARY)
+ && (this->Target->GetType() != cmState::INTERFACE_LIBRARY)
+ && (this->Target->GetType() != cmState::EXECUTABLE))
{
this->SetError("called with non-compilable target type");
return false;
@@ -112,6 +114,14 @@ bool cmTargetPropCommandBase
return false;
}
+ if (this->Target->GetType() == cmState::INTERFACE_LIBRARY
+ && scope != "INTERFACE")
+ {
+ this->SetError("may only be set INTERFACE properties on INTERFACE "
+ "targets");
+ return false;
+ }
+
++argIndex;
std::vector<std::string> content;
@@ -122,29 +132,31 @@ bool cmTargetPropCommandBase
|| args[i] == "PRIVATE"
|| args[i] == "INTERFACE" )
{
- this->PopulateTargetProperies(scope, content, prepend, system);
- return true;
+ return this->PopulateTargetProperies(scope, content, prepend, system);
}
content.push_back(args[i]);
}
- this->PopulateTargetProperies(scope, content, prepend, system);
- return true;
+ return this->PopulateTargetProperies(scope, content, prepend, system);
}
//----------------------------------------------------------------------------
-void cmTargetPropCommandBase
+bool cmTargetPropCommandBase
::PopulateTargetProperies(const std::string &scope,
const std::vector<std::string> &content,
bool prepend, bool system)
{
if (scope == "PRIVATE" || scope == "PUBLIC")
{
- this->HandleDirectContent(this->Target, content, prepend, system);
+ if (!this->HandleDirectContent(this->Target, content, prepend, system))
+ {
+ return false;
+ }
}
if (scope == "INTERFACE" || scope == "PUBLIC")
{
this->HandleInterfaceContent(this->Target, content, prepend, system);
}
+ return true;
}
//----------------------------------------------------------------------------
@@ -155,15 +167,15 @@ void cmTargetPropCommandBase::HandleInterfaceContent(cmTarget *tgt,
if (prepend)
{
const std::string propName = std::string("INTERFACE_") + this->Property;
- const char *propValue = tgt->GetProperty(propName.c_str());
+ const char *propValue = tgt->GetProperty(propName);
const std::string totalContent = this->Join(content) + (propValue
? std::string(";") + propValue
: std::string());
- tgt->SetProperty(propName.c_str(), totalContent.c_str());
+ tgt->SetProperty(propName, totalContent.c_str());
}
else
{
- tgt->AppendProperty(("INTERFACE_" + this->Property).c_str(),
+ tgt->AppendProperty("INTERFACE_" + this->Property,
this->Join(content).c_str());
}
}
diff --git a/Source/cmTargetPropCommandBase.h b/Source/cmTargetPropCommandBase.h
index 690582fdd..d42b588c9 100644
--- a/Source/cmTargetPropCommandBase.h
+++ b/Source/cmTargetPropCommandBase.h
@@ -14,7 +14,6 @@
#define cmTargetPropCommandBase_h
#include "cmCommand.h"
-#include "cmDocumentGeneratorExpressions.h"
class cmTarget;
@@ -30,7 +29,8 @@ public:
};
bool HandleArguments(std::vector<std::string> const& args,
- const char *prop, ArgumentFlags flags = NO_FLAGS);
+ const std::string& prop,
+ ArgumentFlags flags = NO_FLAGS);
cmTypeMacro(cmTargetPropCommandBase, cmCommand);
protected:
@@ -44,7 +44,7 @@ private:
virtual void HandleImportedTarget(const std::string &tgt) = 0;
virtual void HandleMissingTarget(const std::string &name) = 0;
- virtual void HandleDirectContent(cmTarget *tgt,
+ virtual bool HandleDirectContent(cmTarget *tgt,
const std::vector<std::string> &content,
bool prepend, bool system) = 0;
@@ -52,7 +52,7 @@ private:
bool ProcessContentArgs(std::vector<std::string> const& args,
unsigned int &argIndex, bool prepend, bool system);
- void PopulateTargetProperies(const std::string &scope,
+ bool PopulateTargetProperies(const std::string &scope,
const std::vector<std::string> &content,
bool prepend, bool system);
};
diff --git a/Source/cmTargetSourcesCommand.cxx b/Source/cmTargetSourcesCommand.cxx
new file mode 100644
index 000000000..0a44d6f54
--- /dev/null
+++ b/Source/cmTargetSourcesCommand.cxx
@@ -0,0 +1,57 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Stephen Kelly <steveire@gmail.com>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmTargetSourcesCommand.h"
+
+#include "cmGeneratorExpression.h"
+
+//----------------------------------------------------------------------------
+bool cmTargetSourcesCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ return this->HandleArguments(args, "SOURCES");
+}
+
+//----------------------------------------------------------------------------
+void cmTargetSourcesCommand
+::HandleImportedTarget(const std::string &tgt)
+{
+ std::ostringstream e;
+ e << "Cannot specify sources for imported target \""
+ << tgt << "\".";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+}
+
+//----------------------------------------------------------------------------
+void cmTargetSourcesCommand
+::HandleMissingTarget(const std::string &name)
+{
+ std::ostringstream e;
+ e << "Cannot specify sources for target \"" << name << "\" "
+ "which is not built by this project.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+}
+
+//----------------------------------------------------------------------------
+std::string cmTargetSourcesCommand
+::Join(const std::vector<std::string> &content)
+{
+ return cmJoin(content, ";");
+}
+
+//----------------------------------------------------------------------------
+bool cmTargetSourcesCommand
+::HandleDirectContent(cmTarget *tgt, const std::vector<std::string> &content,
+ bool, bool)
+{
+ tgt->AppendProperty("SOURCES", this->Join(content).c_str());
+ return true;
+}
diff --git a/Source/cmTargetSourcesCommand.h b/Source/cmTargetSourcesCommand.h
new file mode 100644
index 000000000..a170e3637
--- /dev/null
+++ b/Source/cmTargetSourcesCommand.h
@@ -0,0 +1,55 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Stephen Kelly <steveire@gmail.com>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmTargetSourcesCommand_h
+#define cmTargetSourcesCommand_h
+
+#include "cmTargetPropCommandBase.h"
+
+//----------------------------------------------------------------------------
+class cmTargetSourcesCommand : public cmTargetPropCommandBase
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmTargetSourcesCommand;
+ }
+
+ /**
+ * This is called when the command is first encountered in
+ * the CMakeLists.txt file.
+ */
+ virtual bool InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus &status);
+
+ /**
+ * The name of the command as specified in CMakeList.txt.
+ */
+ virtual std::string GetName() const { return "target_sources";}
+
+ cmTypeMacro(cmTargetSourcesCommand, cmTargetPropCommandBase);
+
+private:
+ virtual void HandleImportedTarget(const std::string &tgt);
+ virtual void HandleMissingTarget(const std::string &name);
+
+ virtual bool HandleDirectContent(cmTarget *tgt,
+ const std::vector<std::string> &content,
+ bool prepend, bool system);
+
+ virtual std::string Join(const std::vector<std::string> &content);
+};
+
+#endif
diff --git a/Source/cmTest.cxx b/Source/cmTest.cxx
index 0904431d1..6fcd0dc95 100644
--- a/Source/cmTest.cxx
+++ b/Source/cmTest.cxx
@@ -17,33 +17,26 @@
//----------------------------------------------------------------------------
cmTest::cmTest(cmMakefile* mf)
+ : Backtrace(mf->GetBacktrace())
{
this->Makefile = mf;
this->OldStyle = true;
- this->Properties.SetCMakeInstance(mf->GetCMakeInstance());
- this->Backtrace = new cmListFileBacktrace;
- this->Makefile->GetBacktrace(*this->Backtrace);
}
//----------------------------------------------------------------------------
cmTest::~cmTest()
{
- delete this->Backtrace;
}
//----------------------------------------------------------------------------
cmListFileBacktrace const& cmTest::GetBacktrace() const
{
- return *this->Backtrace;
+ return this->Backtrace;
}
//----------------------------------------------------------------------------
-void cmTest::SetName(const char* name)
+void cmTest::SetName(const std::string& name)
{
- if ( !name )
- {
- name = "";
- }
this->Name = name;
}
@@ -54,152 +47,36 @@ void cmTest::SetCommand(std::vector<std::string> const& command)
}
//----------------------------------------------------------------------------
-const char *cmTest::GetProperty(const char* prop) const
+const char *cmTest::GetProperty(const std::string& prop) const
{
- bool chain = false;
- const char *retVal =
- this->Properties.GetPropertyValue(prop, cmProperty::TEST, chain);
- if (chain)
+ const char *retVal = this->Properties.GetPropertyValue(prop);
+ if (!retVal)
{
- return this->Makefile->GetProperty(prop,cmProperty::TEST);
+ const bool chain = this->Makefile->GetState()->
+ IsPropertyChained(prop, cmProperty::TEST);
+ if (chain)
+ {
+ return this->Makefile->GetProperty(prop, chain);
+ }
}
return retVal;
}
//----------------------------------------------------------------------------
-bool cmTest::GetPropertyAsBool(const char* prop) const
+bool cmTest::GetPropertyAsBool(const std::string& prop) const
{
return cmSystemTools::IsOn(this->GetProperty(prop));
}
//----------------------------------------------------------------------------
-void cmTest::SetProperty(const char* prop, const char* value)
+void cmTest::SetProperty(const std::string& prop, const char* value)
{
- if (!prop)
- {
- return;
- }
-
- this->Properties.SetProperty(prop, value, cmProperty::TEST);
+ this->Properties.SetProperty(prop, value);
}
//----------------------------------------------------------------------------
-void cmTest::AppendProperty(const char* prop, const char* value, bool asString)
+void cmTest::AppendProperty(const std::string& prop,
+ const char* value, bool asString)
{
- if (!prop)
- {
- return;
- }
- this->Properties.AppendProperty(prop, value, cmProperty::TEST, asString);
-}
-
-//----------------------------------------------------------------------------
-void cmTest::DefineProperties(cmake *cm)
-{
- cm->DefineProperty
- ("ATTACHED_FILES", cmProperty::TEST,
- "Attach a list of files to a dashboard submission.",
- "Set this property to a list of files that will be encoded and "
- "submitted to the dashboard as an addition to the test result.");
-
- cm->DefineProperty
- ("ATTACHED_FILES_ON_FAIL", cmProperty::TEST,
- "Attach a list of files to a dashboard submission if the test fails.",
- "Same as ATTACHED_FILES, but these files will only be included if the "
- "test does not pass.");
-
- cm->DefineProperty
- ("COST", cmProperty::TEST,
- "Set this to a floating point value. Tests in a test set will be "
- "run in descending order of cost.", "This property describes the cost "
- "of a test. You can explicitly set this value; tests with higher COST "
- "values will run first.");
-
- cm->DefineProperty
- ("DEPENDS", cmProperty::TEST,
- "Specifies that this test should only be run after the specified "
- "list of tests.",
- "Set this to a list of tests that must finish before this test is run.");
-
- cm->DefineProperty
- ("ENVIRONMENT", cmProperty::TEST,
- "Specify environment variables that should be defined for running "
- "a test.",
- "If set to a list of environment variables and values of the form "
- "MYVAR=value those environment variables will be defined while "
- "running the test. The environment is restored to its previous state "
- "after the test is done.");
-
- cm->DefineProperty
- ("FAIL_REGULAR_EXPRESSION", cmProperty::TEST,
- "If the output matches this regular expression the test will fail.",
- "If set, if the output matches one of "
- "specified regular expressions, the test will fail."
- "For example: FAIL_REGULAR_EXPRESSION \"[^a-z]Error;ERROR;Failed\"");
-
- cm->DefineProperty
- ("LABELS", cmProperty::TEST,
- "Specify a list of text labels associated with a test.",
- "The list is reported in dashboard submissions.");
-
- cm->DefineProperty
- ("RESOURCE_LOCK", cmProperty::TEST,
- "Specify a list of resources that are locked by this test.",
- "If multiple tests specify the same resource lock, they are guaranteed "
- "not to run concurrently.");
-
- cm->DefineProperty
- ("MEASUREMENT", cmProperty::TEST,
- "Specify a CDASH measurement and value to be reported for a test.",
- "If set to a name then that name will be reported to CDASH as a "
- "named measurement with a value of 1. You may also specify a value "
- "by setting MEASUREMENT to \"measurement=value\".");
-
- cm->DefineProperty
- ("PASS_REGULAR_EXPRESSION", cmProperty::TEST,
- "The output must match this regular expression for the test to pass.",
- "If set, the test output will be checked "
- "against the specified regular expressions and at least one of the"
- " regular expressions has to match, otherwise the test will fail.");
-
- cm->DefineProperty
- ("PROCESSORS", cmProperty::TEST,
- "How many process slots this test requires",
- "Denotes the number of processors that this test will require. This is "
- "typically used for MPI tests, and should be used in conjunction with "
- "the ctest_test PARALLEL_LEVEL option.");
-
- cm->DefineProperty
- ("REQUIRED_FILES", cmProperty::TEST,
- "List of files required to run the test.",
- "If set to a list of files, the test will not be run unless all of the "
- "files exist.");
-
- cm->DefineProperty
- ("RUN_SERIAL", cmProperty::TEST,
- "Do not run this test in parallel with any other test.",
- "Use this option in conjunction with the ctest_test PARALLEL_LEVEL "
- "option to specify that this test should not be run in parallel with "
- "any other tests.");
-
- cm->DefineProperty
- ("TIMEOUT", cmProperty::TEST,
- "How many seconds to allow for this test.",
- "This property if set will limit a test to not take more than "
- "the specified number of seconds to run. If it exceeds that the "
- "test process will be killed and ctest will move to the next test. "
- "This setting takes precedence over "
- "CTEST_TESTING_TIMEOUT.");
-
- cm->DefineProperty
- ("WILL_FAIL", cmProperty::TEST,
- "If set to true, this will invert the pass/fail flag of the test.",
- "This property can be used for tests that are expected to fail and "
- "return a non zero return code.");
-
- cm->DefineProperty
- ("WORKING_DIRECTORY", cmProperty::TEST,
- "The directory from which the test executable will be called.",
- "If this is not set it is called from the directory the test executable "
- "is located in.");
+ this->Properties.AppendProperty(prop, value, asString);
}
diff --git a/Source/cmTest.h b/Source/cmTest.h
index 73ac133f1..ca88afecd 100644
--- a/Source/cmTest.h
+++ b/Source/cmTest.h
@@ -14,8 +14,8 @@
#include "cmCustomCommand.h"
#include "cmPropertyMap.h"
+#include "cmListFileCache.h"
class cmMakefile;
-class cmListFileBacktrace;
/** \class cmTest
* \brief Represent a test
@@ -31,8 +31,8 @@ public:
~cmTest();
///! Set the test name
- void SetName(const char* name);
- const char* GetName() const { return this->Name.c_str(); }
+ void SetName(const std::string& name);
+ std::string GetName() const { return this->Name; }
void SetCommand(std::vector<std::string> const& command);
std::vector<std::string> const& GetCommand() const
@@ -40,23 +40,16 @@ public:
return this->Command;
}
- /**
- * Print the structure to std::cout.
- */
- void Print() const;
-
///! Set/Get a property of this source file
- void SetProperty(const char *prop, const char *value);
- void AppendProperty(const char* prop, const char* value,bool asString=false);
- const char *GetProperty(const char *prop) const;
- bool GetPropertyAsBool(const char *prop) const;
- cmPropertyMap &GetProperties() { return this->Properties; };
-
- // Define the properties
- static void DefineProperties(cmake *cm);
+ void SetProperty(const std::string& prop, const char *value);
+ void AppendProperty(const std::string& prop,
+ const char* value,bool asString=false);
+ const char *GetProperty(const std::string& prop) const;
+ bool GetPropertyAsBool(const std::string& prop) const;
+ cmPropertyMap &GetProperties() { return this->Properties; }
/** Get the cmMakefile instance that owns this test. */
- cmMakefile *GetMakefile() { return this->Makefile;};
+ cmMakefile *GetMakefile() { return this->Makefile;}
/** Get the backtrace of the command that created this test. */
cmListFileBacktrace const& GetBacktrace() const;
@@ -67,13 +60,13 @@ public:
private:
cmPropertyMap Properties;
- cmStdString Name;
+ std::string Name;
std::vector<std::string> Command;
bool OldStyle;
cmMakefile* Makefile;
- cmListFileBacktrace* Backtrace;
+ cmListFileBacktrace Backtrace;
};
#endif
diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx
index 42f511ea3..b411f15e4 100644
--- a/Source/cmTestGenerator.cxx
+++ b/Source/cmTestGenerator.cxx
@@ -12,10 +12,9 @@
#include "cmTestGenerator.h"
#include "cmGeneratorExpression.h"
+#include "cmOutputConverter.h"
#include "cmLocalGenerator.h"
-#include "cmMakefile.h"
#include "cmSystemTools.h"
-#include "cmTarget.h"
#include "cmTest.h"
//----------------------------------------------------------------------------
@@ -27,6 +26,7 @@ cmTestGenerator
{
this->ActionsPerConfig = !test->GetOldStyle();
this->TestGenerated = false;
+ this->LG = 0;
}
//----------------------------------------------------------------------------
@@ -35,33 +35,17 @@ cmTestGenerator
{
}
+void cmTestGenerator::Compute(cmLocalGenerator* lg)
+{
+ this->LG = lg;
+}
+
//----------------------------------------------------------------------------
void cmTestGenerator::GenerateScriptConfigs(std::ostream& os,
Indent const& indent)
{
- // First create the tests.
+ // Create the tests.
this->cmScriptGenerator::GenerateScriptConfigs(os, indent);
-
- // Now generate the test properties.
- if(this->TestGenerated)
- {
- cmTest* test = this->Test;
- cmMakefile* mf = test->GetMakefile();
- cmLocalGenerator* lg = mf->GetLocalGenerator();
- std::ostream& fout = os;
- cmPropertyMap::const_iterator pit;
- cmPropertyMap* mpit = &test->GetProperties();
- if ( mpit->size() )
- {
- fout << "SET_TESTS_PROPERTIES(" << test->GetName() << " PROPERTIES ";
- for ( pit = mpit->begin(); pit != mpit->end(); ++ pit )
- {
- fout << " " << pit->first
- << " " << lg->EscapeForCMake(pit->second.GetValue());
- }
- fout << ")" << std::endl;
- }
- }
}
//----------------------------------------------------------------------------
@@ -85,7 +69,7 @@ void cmTestGenerator::GenerateScriptActions(std::ostream& os,
//----------------------------------------------------------------------------
void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
- const char* config,
+ const std::string& config,
Indent const& indent)
{
this->TestGenerated = true;
@@ -94,7 +78,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
cmGeneratorExpression ge(this->Test->GetBacktrace());
// Start the test command.
- os << indent << "ADD_TEST(" << this->Test->GetName() << " ";
+ os << indent << "add_test(" << this->Test->GetName() << " ";
// Get the test command line to be executed.
std::vector<std::string> const& command = this->Test->GetCommand();
@@ -102,38 +86,75 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
// Check whether the command executable is a target whose name is to
// be translated.
std::string exe = command[0];
- cmMakefile* mf = this->Test->GetMakefile();
- cmTarget* target = mf->FindTargetToUse(exe.c_str());
- if(target && target->GetType() == cmTarget::EXECUTABLE)
+ cmGeneratorTarget* target =
+ this->LG->FindGeneratorTargetToUse(exe);
+ if(target && target->GetType() == cmState::EXECUTABLE)
{
// Use the target file on disk.
exe = target->GetFullPath(config);
+
+ // Prepend with the emulator when cross compiling if required.
+ const char * emulator =
+ target->GetProperty("CROSSCOMPILING_EMULATOR");
+ if (emulator != 0)
+ {
+ std::vector<std::string> emulatorWithArgs;
+ cmSystemTools::ExpandListArgument(emulator, emulatorWithArgs);
+ std::string emulatorExe(emulatorWithArgs[0]);
+ cmSystemTools::ConvertToUnixSlashes(emulatorExe);
+ os << cmOutputConverter::EscapeForCMake(emulatorExe) << " ";
+ for(std::vector<std::string>::const_iterator ei =
+ emulatorWithArgs.begin()+1;
+ ei != emulatorWithArgs.end();
+ ++ei)
+ {
+ os << cmOutputConverter::EscapeForCMake(*ei) << " ";
+ }
+ }
}
else
{
// Use the command name given.
- exe = ge.Parse(exe.c_str())->Evaluate(mf, config);
+ exe = ge.Parse(exe.c_str())->Evaluate(this->LG, config);
cmSystemTools::ConvertToUnixSlashes(exe);
}
// Generate the command line with full escapes.
- cmLocalGenerator* lg = mf->GetLocalGenerator();
- os << lg->EscapeForCMake(exe.c_str());
+ os << cmOutputConverter::EscapeForCMake(exe);
for(std::vector<std::string>::const_iterator ci = command.begin()+1;
ci != command.end(); ++ci)
{
- os << " " << lg->EscapeForCMake(ge.Parse(*ci)->Evaluate(mf, config));
+ os << " " << cmOutputConverter::EscapeForCMake(
+ ge.Parse(*ci)->Evaluate(
+ this->LG, config));
}
// Finish the test command.
os << ")\n";
+
+ // Output properties for the test.
+ cmPropertyMap& pm = this->Test->GetProperties();
+ if(!pm.empty())
+ {
+ os << indent << "set_tests_properties(" << this->Test->GetName()
+ << " PROPERTIES ";
+ for(cmPropertyMap::const_iterator i = pm.begin();
+ i != pm.end(); ++i)
+ {
+ os << " " << i->first
+ << " " << cmOutputConverter::EscapeForCMake(
+ ge.Parse(i->second.GetValue())->Evaluate(this->LG,
+ config));
+ }
+ os << ")" << std::endl;
+ }
}
//----------------------------------------------------------------------------
void cmTestGenerator::GenerateScriptNoConfig(std::ostream& os,
Indent const& indent)
{
- os << indent << "ADD_TEST(" << this->Test->GetName() << " NOT_AVAILABLE)\n";
+ os << indent << "add_test(" << this->Test->GetName() << " NOT_AVAILABLE)\n";
}
//----------------------------------------------------------------------------
@@ -157,7 +178,7 @@ void cmTestGenerator::GenerateOldStyle(std::ostream& fout,
std::string exe = command[0];
cmSystemTools::ConvertToUnixSlashes(exe);
fout << indent;
- fout << "ADD_TEST(";
+ fout << "add_test(";
fout << this->Test->GetName() << " \"" << exe << "\"";
for(std::vector<std::string>::const_iterator argit = command.begin()+1;
@@ -181,4 +202,19 @@ void cmTestGenerator::GenerateOldStyle(std::ostream& fout,
fout << "\"";
}
fout << ")" << std::endl;
+
+ // Output properties for the test.
+ cmPropertyMap& pm = this->Test->GetProperties();
+ if(!pm.empty())
+ {
+ fout << indent << "set_tests_properties(" << this->Test->GetName()
+ << " PROPERTIES ";
+ for(cmPropertyMap::const_iterator i = pm.begin();
+ i != pm.end(); ++i)
+ {
+ fout << " " << i->first
+ << " " << cmOutputConverter::EscapeForCMake(i->second.GetValue());
+ }
+ fout << ")" << std::endl;
+ }
}
diff --git a/Source/cmTestGenerator.h b/Source/cmTestGenerator.h
index 2c69fc3c5..de8ab78ef 100644
--- a/Source/cmTestGenerator.h
+++ b/Source/cmTestGenerator.h
@@ -15,6 +15,7 @@
#include "cmScriptGenerator.h"
class cmTest;
+class cmLocalGenerator;
/** \class cmTestGenerator
* \brief Support class for generating install scripts.
@@ -28,16 +29,19 @@ public:
configurations = std::vector<std::string>());
virtual ~cmTestGenerator();
+ void Compute(cmLocalGenerator* lg);
+
protected:
virtual void GenerateScriptConfigs(std::ostream& os, Indent const& indent);
virtual void GenerateScriptActions(std::ostream& os, Indent const& indent);
virtual void GenerateScriptForConfig(std::ostream& os,
- const char* config,
+ const std::string& config,
Indent const& indent);
virtual void GenerateScriptNoConfig(std::ostream& os, Indent const& indent);
virtual bool NeedsScriptNoConfig() const;
void GenerateOldStyle(std::ostream& os, Indent const& indent);
+ cmLocalGenerator* LG;
cmTest* Test;
bool TestGenerated;
};
diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx
index ac26503c6..6fd6ab7b4 100644
--- a/Source/cmTimestamp.cxx
+++ b/Source/cmTimestamp.cxx
@@ -33,15 +33,13 @@ std::string cmTimestamp::CurrentTime(
std::string cmTimestamp::FileModificationTime(const char* path,
const std::string& formatString, bool utcFlag)
{
- struct stat info;
- memset(&info, 0, sizeof(info));
-
- if(stat(path, &info) != 0)
+ if(!cmsys::SystemTools::FileExists(path))
{
return std::string();
}
- return CreateTimestampFromTimeT(info.st_mtime, formatString, utcFlag);
+ time_t mtime = cmsys::SystemTools::ModifiedTime(path);
+ return CreateTimestampFromTimeT(mtime, formatString, utcFlag);
}
//----------------------------------------------------------------------------
diff --git a/Source/cmTryCompileCommand.h b/Source/cmTryCompileCommand.h
index a20594cbe..a09c47ff3 100644
--- a/Source/cmTryCompileCommand.h
+++ b/Source/cmTryCompileCommand.h
@@ -40,82 +40,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "try_compile";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Try building some code.";
- }
-
- /**
- * More documentation. */
- virtual const char* GetFullDocumentation() const
- {
- return
- " try_compile(RESULT_VAR <bindir> <srcdir>\n"
- " <projectName> [targetName] [CMAKE_FLAGS flags...]\n"
- " [OUTPUT_VARIABLE <var>])\n"
- "Try building a project. In this form, srcdir should contain a "
- "complete CMake project with a CMakeLists.txt file and all sources. "
- "The bindir and srcdir will not be deleted after this command is run. "
- "Specify targetName to build a specific target instead of the 'all' or "
- "'ALL_BUILD' target."
- "\n"
- " try_compile(RESULT_VAR <bindir> <srcfile|SOURCES srcfile...>\n"
- " [CMAKE_FLAGS flags...]\n"
- " [COMPILE_DEFINITIONS flags...]\n"
- " [LINK_LIBRARIES libs...]\n"
- " [OUTPUT_VARIABLE <var>]\n"
- " [COPY_FILE <fileName> [COPY_FILE_ERROR <var>]])\n"
- "Try building an executable from one or more source files. "
- "In this form the user need only supply one or more source files "
- "that include a definition for 'main'. "
- "CMake will create a CMakeLists.txt file to build the source(s) "
- "as an executable. "
- "Specify COPY_FILE to get a copy of the linked executable at the "
- "given fileName and optionally COPY_FILE_ERROR to capture any error."
- "\n"
- "In this version all files in bindir/CMakeFiles/CMakeTmp "
- "will be cleaned automatically. For debugging, --debug-trycompile can "
- "be passed to cmake to avoid this clean. However, multiple sequential "
- "try_compile operations reuse this single output directory. If you "
- "use --debug-trycompile, you can only debug one try_compile call at a "
- "time. The recommended procedure is to configure with cmake all the "
- "way through once, then delete the cache entry associated with "
- "the try_compile call of interest, and then re-run cmake again with "
- "--debug-trycompile."
- "\n"
- "Some extra flags that can be included are, "
- "INCLUDE_DIRECTORIES, LINK_DIRECTORIES, and LINK_LIBRARIES. "
- "COMPILE_DEFINITIONS are -Ddefinition that will be passed to the "
- "compile line.\n"
- "The srcfile signature also accepts a LINK_LIBRARIES argument which "
- "may contain a list of libraries or IMPORTED targets which will be "
- "linked to in the generated project. If LINK_LIBRARIES is specified "
- "as a parameter to try_compile, then any LINK_LIBRARIES passed as "
- "CMAKE_FLAGS will be ignored.\n"
- "try_compile creates a CMakeList.txt "
- "file on the fly that looks like this:\n"
- " add_definitions( <expanded COMPILE_DEFINITIONS from calling "
- "cmake>)\n"
- " include_directories(${INCLUDE_DIRECTORIES})\n"
- " link_directories(${LINK_DIRECTORIES})\n"
- " add_executable(cmTryCompileExec sources)\n"
- " target_link_libraries(cmTryCompileExec ${LINK_LIBRARIES})\n"
- "In both versions of the command, "
- "if OUTPUT_VARIABLE is specified, then the "
- "output from the build process is stored in the given variable. "
- "The success or failure of the try_compile, i.e. TRUE or FALSE "
- "respectively, is returned in "
- "RESULT_VAR. CMAKE_FLAGS can be used to pass -DVAR:TYPE=VALUE flags "
- "to the cmake that is run during the build. "
- "Set variable CMAKE_TRY_COMPILE_CONFIGURATION to choose a build "
- "configuration."
- ;
- }
+ virtual std::string GetName() const { return "try_compile";}
cmTypeMacro(cmTryCompileCommand, cmCoreTryCompile);
diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx
index 4fc0b13c0..b9ffe5e0f 100644
--- a/Source/cmTryRunCommand.cxx
+++ b/Source/cmTryRunCommand.cxx
@@ -10,8 +10,8 @@
See the License for more information.
============================================================================*/
#include "cmTryRunCommand.h"
-#include "cmCacheManager.h"
#include "cmTryCompileCommand.h"
+#include <cmsys/FStream.hxx>
// cmTryRunCommand
bool cmTryRunCommand
@@ -47,7 +47,8 @@ bool cmTryRunCommand
{
++i;
while (i < argv.size() && argv[i] != "COMPILE_DEFINITIONS" &&
- argv[i] != "CMAKE_FLAGS")
+ argv[i] != "CMAKE_FLAGS" &&
+ argv[i] != "LINK_LIBRARIES")
{
runArgs += " ";
runArgs += argv[i];
@@ -103,8 +104,8 @@ bool cmTryRunCommand
// although they could be used together, don't allow it, because
// using OUTPUT_VARIABLE makes crosscompiling harder
if (this->OutputVariable.size()
- && ((this->RunOutputVariable.size())
- || (this->CompileOutputVariable.size())))
+ && (!this->RunOutputVariable.empty()
+ || !this->CompileOutputVariable.empty()))
{
cmSystemTools::Error(
"You cannot use OUTPUT_VARIABLE together with COMPILE_OUTPUT_VARIABLE "
@@ -114,18 +115,18 @@ bool cmTryRunCommand
}
bool captureRunOutput = false;
- if (this->OutputVariable.size())
+ if (!this->OutputVariable.empty())
{
captureRunOutput = true;
tryCompile.push_back("OUTPUT_VARIABLE");
tryCompile.push_back(this->OutputVariable);
}
- if (this->CompileOutputVariable.size())
+ if (!this->CompileOutputVariable.empty())
{
tryCompile.push_back("OUTPUT_VARIABLE");
tryCompile.push_back(this->CompileOutputVariable);
}
- if (this->RunOutputVariable.size())
+ if (!this->RunOutputVariable.empty())
{
captureRunOutput = true;
}
@@ -139,7 +140,7 @@ bool cmTryRunCommand
// now try running the command if it compiled
if (!res)
{
- if (this->OutputFile.size() == 0)
+ if (this->OutputFile.empty())
{
cmSystemTools::Error(this->FindErrorMessage.c_str());
}
@@ -147,7 +148,8 @@ bool cmTryRunCommand
{
// "run" it and capture the output
std::string runOutputContents;
- if (this->Makefile->IsOn("CMAKE_CROSSCOMPILING"))
+ if (this->Makefile->IsOn("CMAKE_CROSSCOMPILING") &&
+ !this->Makefile->IsDefinitionSet("CMAKE_CROSSCOMPILING_EMULATOR"))
{
this->DoNotRunExecutable(runArgs,
argv[3],
@@ -159,23 +161,23 @@ bool cmTryRunCommand
}
// now put the output into the variables
- if(this->RunOutputVariable.size())
+ if(!this->RunOutputVariable.empty())
{
- this->Makefile->AddDefinition(this->RunOutputVariable.c_str(),
+ this->Makefile->AddDefinition(this->RunOutputVariable,
runOutputContents.c_str());
}
- if(this->OutputVariable.size())
+ if(!this->OutputVariable.empty())
{
// if the TryCompileCore saved output in this outputVariable then
// prepend that output to this output
const char* compileOutput
- = this->Makefile->GetDefinition(this->OutputVariable.c_str());
+ = this->Makefile->GetDefinition(this->OutputVariable);
if (compileOutput)
{
runOutputContents = std::string(compileOutput) + runOutputContents;
}
- this->Makefile->AddDefinition(this->OutputVariable.c_str(),
+ this->Makefile->AddDefinition(this->OutputVariable,
runOutputContents.c_str());
}
}
@@ -193,15 +195,36 @@ void cmTryRunCommand::RunExecutable(const std::string& runArgs,
std::string* out)
{
int retVal = -1;
- std::string finalCommand = cmSystemTools::ConvertToRunCommandPath(
+
+ std::string finalCommand;
+ const std::string emulator =
+ this->Makefile->GetSafeDefinition("CMAKE_CROSSCOMPILING_EMULATOR");
+ if (!emulator.empty())
+ {
+ std::vector<std::string> emulatorWithArgs;
+ cmSystemTools::ExpandListArgument(emulator, emulatorWithArgs);
+ finalCommand += cmSystemTools::ConvertToRunCommandPath(
+ emulatorWithArgs[0].c_str());
+ finalCommand += " ";
+ for (std::vector<std::string>::const_iterator ei =
+ emulatorWithArgs.begin()+1;
+ ei != emulatorWithArgs.end(); ++ei)
+ {
+ finalCommand += "\"";
+ finalCommand += *ei;
+ finalCommand += "\"";
+ finalCommand += " ";
+ }
+ }
+ finalCommand += cmSystemTools::ConvertToRunCommandPath(
this->OutputFile.c_str());
- if (runArgs.size())
+ if (!runArgs.empty())
{
finalCommand += runArgs;
}
int timeout = 0;
bool worked = cmSystemTools::RunSingleCommand(finalCommand.c_str(),
- out, &retVal,
+ out, out, &retVal,
0, cmSystemTools::OUTPUT_NONE, timeout);
// set the run var
char retChar[1000];
@@ -213,9 +236,9 @@ void cmTryRunCommand::RunExecutable(const std::string& runArgs,
{
strcpy(retChar, "FAILED_TO_RUN");
}
- this->Makefile->AddCacheDefinition(this->RunResultVariable.c_str(), retChar,
+ this->Makefile->AddCacheDefinition(this->RunResultVariable, retChar,
"Result of TRY_RUN",
- cmCacheManager::INTERNAL);
+ cmState::INTERNAL);
}
/* This is only used when cross compiling. Instead of running the
@@ -234,11 +257,11 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
copyDest += cmake::GetCMakeFilesDirectory();
copyDest += "/";
copyDest += cmSystemTools::GetFilenameWithoutExtension(
- this->OutputFile.c_str());
+ this->OutputFile);
copyDest += "-";
copyDest += this->RunResultVariable;
- copyDest += cmSystemTools::GetFilenameExtension(this->OutputFile.c_str());
- cmSystemTools::CopyFileAlways(this->OutputFile.c_str(), copyDest.c_str());
+ copyDest += cmSystemTools::GetFilenameExtension(this->OutputFile);
+ cmSystemTools::CopyFileAlways(this->OutputFile, copyDest);
std::string resultFileName = this->Makefile->GetHomeOutputDirectory();
resultFileName += "/TryRunResults.cmake";
@@ -249,7 +272,7 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
std::string internalRunOutputName=this->RunResultVariable+"__TRYRUN_OUTPUT";
bool error = false;
- if (this->Makefile->GetDefinition(this->RunResultVariable.c_str()) == 0)
+ if (this->Makefile->GetDefinition(this->RunResultVariable) == 0)
{
// if the variables doesn't exist, create it with a helpful error text
// and mark it as advanced
@@ -257,16 +280,17 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
comment += "Run result of TRY_RUN(), indicates whether the executable "
"would have been able to run on its target platform.\n";
comment += detailsString;
- this->Makefile->AddCacheDefinition(this->RunResultVariable.c_str(),
+ this->Makefile->AddCacheDefinition(this->RunResultVariable,
"PLEASE_FILL_OUT-FAILED_TO_RUN",
comment.c_str(),
- cmCacheManager::STRING);
+ cmState::STRING);
- cmCacheManager::CacheIterator it = this->Makefile->GetCacheManager()->
- GetCacheIterator(this->RunResultVariable.c_str());
- if ( !it.IsAtEnd() )
+ cmState* state = this->Makefile->GetState();
+ const char* existingValue
+ = state->GetCacheEntryValue(this->RunResultVariable);
+ if (existingValue)
{
- it.SetProperty("ADVANCED", "1");
+ state->SetCacheEntryProperty(this->RunResultVariable, "ADVANCED", "1");
}
error = true;
@@ -275,7 +299,7 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
// is the output from the executable used ?
if (out!=0)
{
- if (this->Makefile->GetDefinition(internalRunOutputName.c_str()) == 0)
+ if (this->Makefile->GetDefinition(internalRunOutputName) == 0)
{
// if the variables doesn't exist, create it with a helpful error text
// and mark it as advanced
@@ -284,15 +308,17 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
"would have printed on stdout and stderr on its target platform.\n";
comment += detailsString;
- this->Makefile->AddCacheDefinition(internalRunOutputName.c_str(),
+ this->Makefile->AddCacheDefinition(internalRunOutputName,
"PLEASE_FILL_OUT-NOTFOUND",
comment.c_str(),
- cmCacheManager::STRING);
- cmCacheManager::CacheIterator it = this->Makefile->GetCacheManager()->
- GetCacheIterator(internalRunOutputName.c_str());
- if ( !it.IsAtEnd() )
+ cmState::STRING);
+ cmState* state = this->Makefile->GetState();
+ const char* existing =
+ state->GetCacheEntryValue(internalRunOutputName);
+ if (existing)
{
- it.SetProperty("ADVANCED", "1");
+ state->SetCacheEntryProperty(internalRunOutputName,
+ "ADVANCED", "1");
}
error = true;
@@ -302,7 +328,7 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
if (error)
{
static bool firstTryRun = true;
- std::ofstream file(resultFileName.c_str(),
+ cmsys::ofstream file(resultFileName.c_str(),
firstTryRun ? std::ios::out : std::ios::app);
if ( file )
{
@@ -349,18 +375,18 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
comment += "Run arguments : ";
comment += runArgs;
comment += "\n";
- comment += " Called from: " + this->Makefile->GetListFileStack();
+ comment += " Called from: " + this->Makefile->FormatListFileStack();
cmsys::SystemTools::ReplaceString(comment, "\n", "\n# ");
file << comment << "\n\n";
- file << "SET( " << this->RunResultVariable << " \n \""
- << this->Makefile->GetDefinition(this->RunResultVariable.c_str())
+ file << "set( " << this->RunResultVariable << " \n \""
+ << this->Makefile->GetDefinition(this->RunResultVariable)
<< "\"\n CACHE STRING \"Result from TRY_RUN\" FORCE)\n\n";
if (out!=0)
{
- file << "SET( " << internalRunOutputName << " \n \""
- << this->Makefile->GetDefinition(internalRunOutputName.c_str())
+ file << "set( " << internalRunOutputName << " \n \""
+ << this->Makefile->GetDefinition(internalRunOutputName)
<< "\"\n CACHE STRING \"Output from TRY_RUN\" FORCE)\n\n";
}
file.close();
@@ -382,6 +408,6 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
if (out!=0)
{
- (*out) = this->Makefile->GetDefinition(internalRunOutputName.c_str());
+ (*out) = this->Makefile->GetDefinition(internalRunOutputName);
}
}
diff --git a/Source/cmTryRunCommand.h b/Source/cmTryRunCommand.h
index 13b997307..9b97b16a2 100644
--- a/Source/cmTryRunCommand.h
+++ b/Source/cmTryRunCommand.h
@@ -40,64 +40,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "try_run";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Try compiling and then running some code.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " try_run(RUN_RESULT_VAR COMPILE_RESULT_VAR\n"
- " bindir srcfile [CMAKE_FLAGS <Flags>]\n"
- " [COMPILE_DEFINITIONS <flags>]\n"
- " [COMPILE_OUTPUT_VARIABLE comp]\n"
- " [RUN_OUTPUT_VARIABLE run]\n"
- " [OUTPUT_VARIABLE var]\n"
- " [ARGS <arg1> <arg2>...])\n"
- "Try compiling a srcfile. Return TRUE or FALSE for success or failure "
- "in COMPILE_RESULT_VAR. Then if the compile succeeded, run the "
- "executable and return its exit code in RUN_RESULT_VAR. "
- "If the executable was built, but failed to run, then RUN_RESULT_VAR "
- "will be set to FAILED_TO_RUN. "
- "COMPILE_OUTPUT_VARIABLE specifies the variable where the output from "
- "the compile step goes. RUN_OUTPUT_VARIABLE specifies the variable "
- "where the output from the running executable goes.\n"
- "For compatibility reasons OUTPUT_VARIABLE is still supported, which "
- "gives you the output from the compile and run step combined.\n"
- "Cross compiling issues\n"
- "When cross compiling, the executable compiled in the first step "
- "usually cannot be run on the build host. try_run() checks the "
- "CMAKE_CROSSCOMPILING variable to detect whether CMake is in "
- "crosscompiling mode. If that's the case, it will still try to compile "
- "the executable, but it will not try to run the executable. Instead it "
- "will create cache variables which must be filled by the user or by "
- "presetting them in some CMake script file to the values the "
- "executable would have produced if it had been run on its actual "
- "target platform. These variables are RUN_RESULT_VAR (explanation see "
- "above) and if RUN_OUTPUT_VARIABLE (or OUTPUT_VARIABLE) was used, an "
- "additional cache variable "
- "RUN_RESULT_VAR__COMPILE_RESULT_VAR__TRYRUN_OUTPUT."
- "This is intended to hold stdout and stderr from the executable.\n"
- "In order to make cross compiling your project easier, use try_run "
- "only if really required. If you use try_run, use RUN_OUTPUT_VARIABLE "
- "(or OUTPUT_VARIABLE) only if really required. Using them will require "
- "that when crosscompiling, the cache variables will have to be set "
- "manually to the output of the executable. You can also \"guard\" the "
- "calls to try_run with if(CMAKE_CROSSCOMPILING) and provide an "
- "easy-to-preset alternative for this case.\n"
- "Set variable CMAKE_TRY_COMPILE_CONFIGURATION to choose a build "
- "configuration."
- ;
- }
+ virtual std::string GetName() const { return "try_run";}
cmTypeMacro(cmTryRunCommand, cmCoreTryCompile);
private:
diff --git a/Source/cmUnsetCommand.cxx b/Source/cmUnsetCommand.cxx
index 5c0cfaa03..053cdfc7d 100644
--- a/Source/cmUnsetCommand.cxx
+++ b/Source/cmUnsetCommand.cxx
@@ -24,7 +24,7 @@ bool cmUnsetCommand::InitialPass(std::vector<std::string> const& args,
const char* variable = args[0].c_str();
// unset(ENV{VAR})
- if (!strncmp(variable,"ENV{",4) && strlen(variable) > 5)
+ if (cmHasLiteralPrefix(variable, "ENV{") && strlen(variable) > 5)
{
// what is the variable name
char *envVarName = new char [strlen(variable)];
@@ -49,7 +49,13 @@ bool cmUnsetCommand::InitialPass(std::vector<std::string> const& args,
this->Makefile->RemoveCacheDefinition(variable);
return true;
}
- // ERROR: second argument isn't CACHE
+ // unset(VAR PARENT_SCOPE)
+ else if ((args.size() == 2) && (args[1] == "PARENT_SCOPE"))
+ {
+ this->Makefile->RaiseScope(variable, 0);
+ return true;
+ }
+ // ERROR: second argument isn't CACHE or PARENT_SCOPE
else
{
this->SetError("called with an invalid second argument");
diff --git a/Source/cmUnsetCommand.h b/Source/cmUnsetCommand.h
index 9cf95d98d..62c2bd39b 100644
--- a/Source/cmUnsetCommand.h
+++ b/Source/cmUnsetCommand.h
@@ -45,31 +45,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const {return "unset";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Unset a variable, cache variable, or environment variable.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " unset(<variable> [CACHE])\n"
- "Removes the specified variable causing it to become undefined. "
- "If CACHE is present then the variable is removed from the cache "
- "instead of the current scope.\n"
- "<variable> can be an environment variable such as:\n"
- " unset(ENV{LD_LIBRARY_PATH})\n"
- "in which case the variable will be removed from the current "
- "environment.";
- }
+ virtual std::string GetName() const {return "unset";}
cmTypeMacro(cmUnsetCommand, cmCommand);
};
diff --git a/Source/cmUseMangledMesaCommand.cxx b/Source/cmUseMangledMesaCommand.cxx
index 4c189e665..2ee664fd1 100644
--- a/Source/cmUseMangledMesaCommand.cxx
+++ b/Source/cmUseMangledMesaCommand.cxx
@@ -13,11 +13,14 @@
#include "cmSystemTools.h"
#include <cmsys/RegularExpression.hxx>
+#include <cmsys/FStream.hxx>
-// cmUseMangledMesaCommand
bool cmUseMangledMesaCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
+ if(this->Disallowed(cmPolicies::CMP0030,
+ "The use_mangled_mesa command should not be called; see CMP0030."))
+ { return true; }
// expected two arguments:
// arguement one: the full path to gl_mangle.h
// arguement two : directory for output of edited headers
@@ -35,13 +38,13 @@ bool cmUseMangledMesaCommand
std::string e = "Bad path to Mesa, could not find: ";
e += glh;
e += " ";
- this->SetError(e.c_str());
+ this->SetError(e);
return false;
}
const char* destDir = args[1].c_str();
std::vector<std::string> files;
cmSystemTools::Glob(inputDir, "\\.h$", files);
- if(files.size() == 0)
+ if(files.empty())
{
cmSystemTools::Error("Could not open Mesa Directory ", inputDir);
return false;
@@ -71,7 +74,7 @@ CopyAndFullPathMesaHeader(const char* source,
outFile += file;
std::string tempOutputFile = outFile;
tempOutputFile += ".tmp";
- std::ofstream fout(tempOutputFile.c_str());
+ cmsys::ofstream fout(tempOutputFile.c_str());
if(!fout)
{
cmSystemTools::Error("Could not open file for write in copy operation: ",
@@ -79,7 +82,7 @@ CopyAndFullPathMesaHeader(const char* source,
cmSystemTools::ReportLastSystemError("");
return;
}
- std::ifstream fin(source);
+ cmsys::ifstream fin(source);
if(!fin)
{
cmSystemTools::Error("Could not open file for read in copy operation",
@@ -104,12 +107,12 @@ CopyAndFullPathMesaHeader(const char* source,
if(glDirLine.find(includeFile.c_str()))
{
std::string gfile = glDirLine.match(3);
- fout << "#include \"" << outdir << "/" << gfile.c_str() << "\"\n";
+ fout << "#include \"" << outdir << "/" << gfile << "\"\n";
}
else if(glLine.find(includeFile.c_str()))
{
fout << "#include \"" << outdir << "/" <<
- includeLine.match(1).c_str() << "\"\n";
+ includeLine.match(1) << "\"\n";
}
else
{
diff --git a/Source/cmUseMangledMesaCommand.h b/Source/cmUseMangledMesaCommand.h
index 2f52960c4..1af2bfee1 100644
--- a/Source/cmUseMangledMesaCommand.h
+++ b/Source/cmUseMangledMesaCommand.h
@@ -14,75 +14,18 @@
#include "cmCommand.h"
-#include "cmSourceFile.h"
-
-/** \class cmUseMangledMesaCommand
- * \brief Create Tcl Wrappers for VTK classes.
- *
- * cmUseMangledMesaCommand is used to define a CMake variable include
- * path location by specifying a file and list of directories.
- */
class cmUseMangledMesaCommand : public cmCommand
{
public:
cmTypeMacro(cmUseMangledMesaCommand, cmCommand);
-
- /**
- * This is a virtual constructor for the command.
- */
- virtual cmCommand* Clone()
- {
- return new cmUseMangledMesaCommand;
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
+ virtual cmCommand* Clone() { return new cmUseMangledMesaCommand; }
virtual bool InitialPass(std::vector<std::string> const& args,
cmExecutionStatus &status);
-
- /**
- * The name of the command as specified in CMakeList.txt.
- */
- virtual const char* GetName() const { return "use_mangled_mesa";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Copy mesa headers for use in combination with system GL.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " use_mangled_mesa(PATH_TO_MESA OUTPUT_DIRECTORY)\n"
- "The path to mesa includes, should contain gl_mangle.h. "
- "The mesa headers are copied to the specified output directory. "
- "This allows mangled mesa headers to override other GL headers by "
- "being added to the include directory path earlier.";
- }
-
- /**
- * This determines if the command is invoked when in script mode.
- */
+ virtual std::string GetName() const { return "use_mangled_mesa";}
virtual bool IsScriptable() const { return true; }
-
- /** This command is kept for compatibility with older CMake versions. */
- virtual bool IsDiscouraged() const
- {
- return true;
- }
-
protected:
void CopyAndFullPathMesaHeader(const char* source,
const char* outdir);
};
-
#endif
diff --git a/Source/cmUtilitySourceCommand.cxx b/Source/cmUtilitySourceCommand.cxx
index 6ea3dfac8..3f1e33317 100644
--- a/Source/cmUtilitySourceCommand.cxx
+++ b/Source/cmUtilitySourceCommand.cxx
@@ -15,6 +15,9 @@
bool cmUtilitySourceCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
+ if(this->Disallowed(cmPolicies::CMP0034,
+ "The utility_source command should not be called; see CMP0034."))
+ { return true; }
if(args.size() < 3)
{
this->SetError("called with incorrect number of arguments");
@@ -26,7 +29,7 @@ bool cmUtilitySourceCommand
// The first argument is the cache entry name.
std::string cacheEntry = *arg++;
const char* cacheValue =
- this->Makefile->GetDefinition(cacheEntry.c_str());
+ this->Makefile->GetDefinition(cacheEntry);
// If it exists already and appears up to date then we are done. If
// the string contains "(IntDir)" but that is not the
// CMAKE_CFG_INTDIR setting then the value is out of date.
@@ -49,11 +52,13 @@ bool cmUtilitySourceCommand
}
else
{
+ cmState *state =
+ this->Makefile->GetState();
haveCacheValue = (cacheValue &&
(strstr(cacheValue, "(IntDir)") == 0 ||
(intDir && strcmp(intDir, "$(IntDir)") == 0)) &&
- (this->Makefile->GetCacheMajorVersion() != 0 &&
- this->Makefile->GetCacheMinorVersion() != 0 ));
+ (state->GetCacheMajorVersion() != 0 &&
+ state->GetCacheMinorVersion() != 0 ));
}
if(haveCacheValue)
@@ -68,7 +73,7 @@ bool cmUtilitySourceCommand
// The third argument specifies the relative directory of the source
// of the utility.
std::string relativeSource = *arg++;
- std::string utilitySource = this->Makefile->GetCurrentDirectory();
+ std::string utilitySource = this->Makefile->GetCurrentSourceDirectory();
utilitySource = utilitySource+"/"+relativeSource;
// If the directory doesn't exist, the source has not been included.
@@ -86,13 +91,13 @@ bool cmUtilitySourceCommand
// The source exists.
std::string cmakeCFGout =
this->Makefile->GetRequiredDefinition("CMAKE_CFG_INTDIR");
- std::string utilityDirectory = this->Makefile->GetCurrentOutputDirectory();
+ std::string utilityDirectory = this->Makefile->GetCurrentBinaryDirectory();
std::string exePath;
if (this->Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH"))
{
exePath = this->Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH");
}
- if(exePath.size())
+ if(!exePath.empty())
{
utilityDirectory = exePath;
}
@@ -110,17 +115,17 @@ bool cmUtilitySourceCommand
cmSystemTools::ReplaceString(utilityExecutable, "/./", "/");
// Enter the value into the cache.
- this->Makefile->AddCacheDefinition(cacheEntry.c_str(),
+ this->Makefile->AddCacheDefinition(cacheEntry,
utilityExecutable.c_str(),
"Path to an internal program.",
- cmCacheManager::FILEPATH);
+ cmState::FILEPATH);
// add a value into the cache that maps from the
// full path to the name of the project
cmSystemTools::ConvertToUnixSlashes(utilityExecutable);
- this->Makefile->AddCacheDefinition(utilityExecutable.c_str(),
+ this->Makefile->AddCacheDefinition(utilityExecutable,
utilityName.c_str(),
"Executable to project name.",
- cmCacheManager::INTERNAL);
+ cmState::INTERNAL);
return true;
}
diff --git a/Source/cmUtilitySourceCommand.h b/Source/cmUtilitySourceCommand.h
index 195f605f2..8863ff594 100644
--- a/Source/cmUtilitySourceCommand.h
+++ b/Source/cmUtilitySourceCommand.h
@@ -14,77 +14,14 @@
#include "cmCommand.h"
-/** \class cmUtilitySourceCommand
- * \brief A command to setup a cache entry with the location of a third-party
- * utility's source.
- *
- * cmUtilitySourceCommand is used when a third-party utility's source is
- * included in the project's source tree. It specifies the location of
- * the executable's source, and any files that may be needed to confirm the
- * identity of the source.
- */
class cmUtilitySourceCommand : public cmCommand
{
public:
- /**
- * This is a virtual constructor for the command.
- */
- virtual cmCommand* Clone()
- {
- return new cmUtilitySourceCommand;
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
+ cmTypeMacro(cmUtilitySourceCommand, cmCommand);
+ virtual cmCommand* Clone() { return new cmUtilitySourceCommand; }
virtual bool InitialPass(std::vector<std::string> const& args,
cmExecutionStatus &status);
-
- /**
- * The name of the command as specified in CMakeList.txt.
- */
- virtual const char* GetName() const { return "utility_source";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Specify the source tree of a third-party utility.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " utility_source(cache_entry executable_name\n"
- " path_to_source [file1 file2 ...])\n"
- "When a third-party utility's source is included in the distribution, "
- "this command specifies its location and name. The cache entry will "
- "not be set unless the path_to_source and all listed files exist. It "
- "is assumed that the source tree of the utility will have been built "
- "before it is needed.\n"
- "When cross compiling CMake will print a warning if a utility_source() "
- "command is executed, because in many cases it is used to build an "
- "executable which is executed later on. This doesn't work when "
- "cross compiling, since the executable can run only on their target "
- "platform. So in this case the cache entry has to be adjusted manually "
- "so it points to an executable which is runnable on the build host.";
- }
-
- /** This command is kept for compatibility with older CMake versions. */
- virtual bool IsDiscouraged() const
- {
- return true;
- }
-
-
- cmTypeMacro(cmUtilitySourceCommand, cmCommand);
+ virtual std::string GetName() const { return "utility_source";}
};
-
-
#endif
diff --git a/Source/cmUuid.cxx b/Source/cmUuid.cxx
new file mode 100644
index 000000000..e2d0049eb
--- /dev/null
+++ b/Source/cmUuid.cxx
@@ -0,0 +1,214 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmUuid.h"
+
+#include <string.h>
+
+#include <cmsys/MD5.h>
+#include "cm_sha2.h"
+
+cmUuid::cmUuid()
+{
+ Groups.push_back(4);
+ Groups.push_back(2);
+ Groups.push_back(2);
+ Groups.push_back(2);
+ Groups.push_back(6);
+}
+
+std::string cmUuid::FromMd5(std::vector<unsigned char> const& uuidNamespace,
+ std::string const& name) const
+{
+ std::vector<unsigned char> hashInput;
+ this->CreateHashInput(uuidNamespace, name, hashInput);
+
+ cmsysMD5_s *md5 = cmsysMD5_New();
+ cmsysMD5_Initialize(md5);
+ cmsysMD5_Append(md5, &hashInput[0], int(hashInput.size()));
+
+ unsigned char digest[16] = {0};
+ cmsysMD5_Finalize(md5, digest);
+
+ cmsysMD5_Delete(md5);
+
+ return this->FromDigest(digest, 3);
+}
+
+std::string cmUuid::FromSha1(std::vector<unsigned char> const& uuidNamespace,
+ std::string const& name) const
+{
+ std::vector<unsigned char> hashInput;
+ this->CreateHashInput(uuidNamespace, name, hashInput);
+
+ SHA_CTX *sha = new SHA_CTX;
+ SHA1_Init(sha);
+ SHA1_Update(sha, &hashInput[0], hashInput.size());
+
+ unsigned char digest[SHA1_DIGEST_LENGTH] = {0};
+ SHA1_Final(digest, sha);
+
+ delete sha;
+
+ return this->FromDigest(digest, 5);
+}
+
+void cmUuid::CreateHashInput(std::vector<unsigned char> const& uuidNamespace,
+ std::string const& name, std::vector<unsigned char> &output) const
+{
+ output = uuidNamespace;
+
+ if(!name.empty())
+ {
+ output.resize(output.size() + name.size());
+
+ memcpy(&output[0] + uuidNamespace.size(),
+ name.c_str(), name.size());
+ }
+}
+
+std::string cmUuid::FromDigest(
+ const unsigned char* digest, unsigned char version) const
+{
+ typedef unsigned char byte_t;
+
+ byte_t uuid[16] = {0};
+ memcpy(uuid, digest, 16);
+
+ uuid[6] &= 0xF;
+ uuid[6] |= byte_t(version << 4);
+
+ uuid[8] &= 0x3F;
+ uuid[8] |= 0x80;
+
+ return this->BinaryToString(uuid);
+}
+
+bool cmUuid::StringToBinary(std::string const& input,
+ std::vector<unsigned char> &output) const
+{
+ output.clear();
+ output.reserve(16);
+
+ if(input.length() != 36)
+ {
+ return false;
+ }
+ size_t index = 0;
+ for(size_t i = 0; i < this->Groups.size(); ++i)
+ {
+ if(i != 0 && input[index++] != '-')
+ {
+ return false;
+ }
+ size_t digits = this->Groups[i] * 2;
+ if(!StringToBinaryImpl(input.substr(index, digits), output))
+ {
+ return false;
+ }
+
+ index += digits;
+ }
+
+ return true;
+}
+
+std::string cmUuid::BinaryToString(const unsigned char* input) const
+{
+ std::string output;
+
+ size_t inputIndex = 0;
+ for(size_t i = 0; i < this->Groups.size(); ++i)
+ {
+ if(i != 0)
+ {
+ output += '-';
+ }
+
+ size_t bytes = this->Groups[i];
+ for(size_t j = 0; j < bytes; ++j)
+ {
+ unsigned char byte = input[inputIndex++];
+ output += this->ByteToHex(byte);
+ }
+ }
+
+ return output;
+}
+
+std::string cmUuid::ByteToHex(unsigned char byte) const
+{
+ std::string result;
+ for(int i = 0; i < 2; ++i)
+ {
+ unsigned char rest = byte % 16;
+ byte /= 16;
+
+ char c = (rest < 0xA) ?
+ char('0' + rest) :
+ char('a' + (rest - 0xA));
+
+ result = c + result;
+ }
+
+ return result;
+}
+
+bool cmUuid::StringToBinaryImpl(std::string const& input,
+ std::vector<unsigned char> &output) const
+{
+ if(input.size()%2)
+ {
+ return false;
+ }
+
+ for(size_t i = 0; i < input.size(); i +=2)
+ {
+ char c1 = 0;
+ if(!IntFromHexDigit(input[i], c1))
+ {
+ return false;
+ }
+
+ char c2 = 0;
+ if(!IntFromHexDigit(input[i + 1], c2))
+ {
+ return false;
+ }
+
+ output.push_back(char(c1 << 4 | c2));
+ }
+
+ return true;
+}
+
+bool cmUuid::IntFromHexDigit(char input, char& output) const
+{
+ if(input >= '0' && input <= '9')
+ {
+ output = char(input - '0');
+ return true;
+ }
+ else if(input >= 'a' && input <= 'f')
+ {
+ output = char(input - 'a' + 0xA);
+ return true;
+ }
+ else if(input >= 'A' && input <= 'F')
+ {
+ output = char(input - 'A' + 0xA);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
diff --git a/Source/cmUuid.h b/Source/cmUuid.h
new file mode 100644
index 000000000..0dda35758
--- /dev/null
+++ b/Source/cmUuid.h
@@ -0,0 +1,55 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmUuid_h
+#define cmUuid_h
+
+#include "cmStandardIncludes.h"
+
+/** \class cmUuid
+ * \brief Utility class to generate UUIDs as defined by RFC4122
+ *
+ */
+class cmUuid
+{
+public:
+ cmUuid();
+
+ std::string FromMd5(std::vector<unsigned char> const& uuidNamespace,
+ std::string const& name) const;
+
+ std::string FromSha1(std::vector<unsigned char> const& uuidNamespace,
+ std::string const& name) const;
+
+ bool StringToBinary(std::string const& input,
+ std::vector<unsigned char> &output) const;
+
+private:
+ std::string ByteToHex(unsigned char byte) const;
+
+ void CreateHashInput(std::vector<unsigned char> const& uuidNamespace,
+ std::string const& name, std::vector<unsigned char> &output) const;
+
+ std::string FromDigest(const unsigned char* digest,
+ unsigned char version) const;
+
+ bool StringToBinaryImpl(std::string const& input,
+ std::vector<unsigned char> &output) const;
+
+ std::string BinaryToString(const unsigned char* input) const;
+
+ bool IntFromHexDigit(char input, char& output) const;
+
+ std::vector<int> Groups;
+};
+
+
+#endif
diff --git a/Source/cmVS10LinkFlagTable.h b/Source/cmVS10LinkFlagTable.h
index 5d1562002..dd9232986 100644
--- a/Source/cmVS10LinkFlagTable.h
+++ b/Source/cmVS10LinkFlagTable.h
@@ -155,7 +155,8 @@ static cmVS7FlagTable cmVS10LinkFlagTable[] =
{"AllowIsolation", "ALLOWISOLATION:NO", "", "false", 0},
{"UACUIAccess", "uiAccess='false'", "", "false", 0},
{"UACUIAccess", "uiAccess='true'", "", "true", 0},
- {"GenerateDebugInformation", "DEBUG", "", "true", 0},
+ {"GenerateDebugInformation", "DEBUG", "", "true",
+ cmVS7FlagTable::CaseInsensitive},
{"MapExports", "MAPINFO:EXPORTS", "", "true", 0},
{"AssemblyDebug", "ASSEMBLYDEBUG:DISABLE", "", "false", 0},
{"AssemblyDebug", "ASSEMBLYDEBUG", "", "true", 0},
@@ -191,10 +192,7 @@ static cmVS7FlagTable cmVS10LinkFlagTable[] =
{"LinkDLL", "DLL", "", "true", 0},
//Bool Properties With Argument
- {"EnableUAC", "MANIFESTUAC:NO", "", "false",
- cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
- {"EnableUAC", "MANIFESTUAC:NO", "Enable User Account Control (UAC)", "",
- cmVS7FlagTable::UserValueRequired},
+ {"EnableUAC", "MANIFESTUAC:NO", "", "false", 0},
{"EnableUAC", "MANIFESTUAC:", "", "true",
cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
{"UACUIAccess", "MANIFESTUAC:", "Enable User Account Control (UAC)", "",
diff --git a/Source/cmVS10MASMFlagTable.h b/Source/cmVS10MASMFlagTable.h
new file mode 100644
index 000000000..8fb6f3328
--- /dev/null
+++ b/Source/cmVS10MASMFlagTable.h
@@ -0,0 +1,96 @@
+static cmVS7FlagTable cmVS10MASMFlagTable[] =
+{
+
+ //Enum Properties
+ {"PreserveIdentifierCase", "",
+ "Default", "0", 0},
+ {"PreserveIdentifierCase", "/Cp",
+ "Preserves Identifier Case (/Cp)", "1", 0},
+ {"PreserveIdentifierCase", "/Cu",
+ "Maps all identifiers to upper case. (/Cu)", "2", 0},
+ {"PreserveIdentifierCase", "/Cx",
+ "Preserves case in public and extern symbols. (/Cx)", "3", 0},
+
+ {"WarningLevel", "/W0",
+ "Warning Level 0 (/W0)", "0", 0},
+ {"WarningLevel", "/W1",
+ "Warning Level 1 (/W1)", "1", 0},
+ {"WarningLevel", "/W2",
+ "Warning Level 2 (/W2)", "2", 0},
+ {"WarningLevel", "/W3",
+ "Warning Level 3 (/W3)", "3", 0},
+
+ {"PackAlignmentBoundary", "",
+ "Default", "0", 0},
+ {"PackAlignmentBoundary", "/Zp1",
+ "One Byte Boundary (/Zp1)", "1", 0},
+ {"PackAlignmentBoundary", "/Zp2",
+ "Two Byte Boundary (/Zp2)", "2", 0},
+ {"PackAlignmentBoundary", "/Zp4",
+ "Four Byte Boundary (/Zp4)", "3", 0},
+ {"PackAlignmentBoundary", "/Zp8",
+ "Eight Byte Boundary (/Zp8)", "4", 0},
+ {"PackAlignmentBoundary", "/Zp16",
+ "Sixteen Byte Boundary (/Zp16)", "5", 0},
+
+ {"CallingConvention", "",
+ "Default", "0", 0},
+ {"CallingConvention", "/Gd",
+ "Use C-style Calling Convention (/Gd)", "1", 0},
+ {"CallingConvention", "/Gz",
+ "Use stdcall Calling Convention (/Gz)", "2", 0},
+ {"CallingConvention", "/Gc",
+ "Use Pascal Calling Convention (/Gc)", "3", 0},
+
+ {"ErrorReporting", "/errorReport:prompt",
+ "Prompt to send report immediately (/errorReport:prompt)", "0", 0},
+ {"ErrorReporting", "/errorReport:queue",
+ "Prompt to send report at the next logon (/errorReport:queue)", "1", 0},
+ {"ErrorReporting", "/errorReport:send",
+ "Automatically send report (/errorReport:send)", "2", 0},
+ {"ErrorReporting", "/errorReport:none",
+ "Do not send report (/errorReport:none)", "3", 0},
+
+
+ //Bool Properties
+ {"NoLogo", "/nologo", "", "true", 0},
+ {"GeneratePreprocessedSourceListing", "/EP", "", "true", 0},
+ {"ListAllAvailableInformation", "/Sa", "", "true", 0},
+ {"UseSafeExceptionHandlers", "/safeseh", "", "true", 0},
+ {"AddFirstPassListing", "/Sf", "", "true", 0},
+ {"EnableAssemblyGeneratedCodeListing", "/Sg", "", "true", 0},
+ {"DisableSymbolTable", "/Sn", "", "true", 0},
+ {"EnableFalseConditionalsInListing", "/Sx", "", "true", 0},
+ {"TreatWarningsAsErrors", "/WX", "", "true", 0},
+ {"MakeAllSymbolsPublic", "/Zf", "", "true", 0},
+ {"GenerateDebugInformation", "/Zi", "", "true", 0},
+ {"EnableMASM51Compatibility", "/Zm", "", "true", 0},
+ {"PerformSyntaxCheckOnly", "/Zs", "", "true", 0},
+
+ //Bool Properties With Argument
+
+ //String List Properties
+ {"PreprocessorDefinitions", "/D",
+ "Preprocessor Definitions",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"IncludePaths", "/I",
+ "Include Paths",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"BrowseFile", "/FR",
+ "Generate Browse Information File",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ // Skip [AdditionalDependencies] - no command line Switch.
+
+ //String Properties
+ // Skip [Inputs] - no command line Switch.
+ {"ObjectFileName", "/Fo",
+ "Object File Name",
+ "", cmVS7FlagTable::UserValue},
+ {"AssembledCodeListingFile", "/Fl",
+ "Assembled Code Listing File",
+ "", cmVS7FlagTable::UserValue},
+ // Skip [CommandLineTemplate] - no command line Switch.
+ // Skip [ExecutionDescription] - no command line Switch.
+ // Skip [AdditionalOptions] - no command line Switch.
+ {0,0,0,0,0}
+};
diff --git a/Source/cmVS10RCFlagTable.h b/Source/cmVS10RCFlagTable.h
new file mode 100644
index 000000000..90499861b
--- /dev/null
+++ b/Source/cmVS10RCFlagTable.h
@@ -0,0 +1,7 @@
+static cmVS7FlagTable cmVS10RCFlagTable[] =
+{
+ //Bool Properties
+ {"NullTerminateStrings", "n", "", "true", 0},
+
+ {0,0,0,0,0}
+};
diff --git a/Source/cmVS11CLFlagTable.h b/Source/cmVS11CLFlagTable.h
index 5ab8ebbb3..a61ab1609 100644
--- a/Source/cmVS11CLFlagTable.h
+++ b/Source/cmVS11CLFlagTable.h
@@ -248,9 +248,9 @@ static cmVS7FlagTable cmVS11CLFlagTable[] =
{"ForcedUsingFiles", "FU",
"Forced #using File",
"", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
- {"PREfastAdditionalOptions", "analyze:",
- "Additional Code Analysis Native options",
- "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"PREfastLog", "analyze:log",
+ "Code Analysis Log",
+ "", cmVS7FlagTable::UserFollowing},
{"PREfastAdditionalPlugins", "analyze:plugin",
"Additional Code Analysis Native plugins",
"", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
@@ -283,9 +283,6 @@ static cmVS7FlagTable cmVS11CLFlagTable[] =
"", cmVS7FlagTable::UserValue},
// Skip [XMLDocumentationFileName] - no command line Switch.
// Skip [BrowseInformationFile] - no command line Switch.
- {"PREfastLog", "analyze:log ",
- "Code Analysis Log",
- "", cmVS7FlagTable::UserValue},
// Skip [AdditionalOptions] - no command line Switch.
{0,0,0,0,0}
};
diff --git a/Source/cmVS11LinkFlagTable.h b/Source/cmVS11LinkFlagTable.h
index b4587a836..2d6f6c074 100644
--- a/Source/cmVS11LinkFlagTable.h
+++ b/Source/cmVS11LinkFlagTable.h
@@ -177,7 +177,8 @@ static cmVS7FlagTable cmVS11LinkFlagTable[] =
{"UACUIAccess", "uiAccess='false'", "", "false", 0},
{"UACUIAccess", "uiAccess='true'", "", "true", 0},
{"ManifestEmbed", "manifest:embed", "", "true", 0},
- {"GenerateDebugInformation", "DEBUG", "", "true", 0},
+ {"GenerateDebugInformation", "DEBUG", "", "true",
+ cmVS7FlagTable::CaseInsensitive},
{"MapExports", "MAPINFO:EXPORTS", "", "true", 0},
{"AssemblyDebug", "ASSEMBLYDEBUG:DISABLE", "", "false", 0},
{"AssemblyDebug", "ASSEMBLYDEBUG", "", "true", 0},
@@ -217,10 +218,7 @@ static cmVS7FlagTable cmVS11LinkFlagTable[] =
{"LinkDLL", "DLL", "", "true", 0},
//Bool Properties With Argument
- {"EnableUAC", "MANIFESTUAC:NO", "", "false",
- cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
- {"EnableUAC", "MANIFESTUAC:NO", "Enable User Account Control (UAC)", "",
- cmVS7FlagTable::UserValueRequired},
+ {"EnableUAC", "MANIFESTUAC:NO", "", "false", 0},
{"EnableUAC", "MANIFESTUAC:", "", "true",
cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
{"UACUIAccess", "MANIFESTUAC:", "Enable User Account Control (UAC)", "",
diff --git a/Source/cmVS11MASMFlagTable.h b/Source/cmVS11MASMFlagTable.h
new file mode 100644
index 000000000..2ff95adc1
--- /dev/null
+++ b/Source/cmVS11MASMFlagTable.h
@@ -0,0 +1,96 @@
+static cmVS7FlagTable cmVS11MASMFlagTable[] =
+{
+
+ //Enum Properties
+ {"PreserveIdentifierCase", "",
+ "Default", "0", 0},
+ {"PreserveIdentifierCase", "/Cp",
+ "Preserves Identifier Case (/Cp)", "1", 0},
+ {"PreserveIdentifierCase", "/Cu",
+ "Maps all identifiers to upper case. (/Cu)", "2", 0},
+ {"PreserveIdentifierCase", "/Cx",
+ "Preserves case in public and extern symbols. (/Cx)", "3", 0},
+
+ {"WarningLevel", "/W0",
+ "Warning Level 0 (/W0)", "0", 0},
+ {"WarningLevel", "/W1",
+ "Warning Level 1 (/W1)", "1", 0},
+ {"WarningLevel", "/W2",
+ "Warning Level 2 (/W2)", "2", 0},
+ {"WarningLevel", "/W3",
+ "Warning Level 3 (/W3)", "3", 0},
+
+ {"PackAlignmentBoundary", "",
+ "Default", "0", 0},
+ {"PackAlignmentBoundary", "/Zp1",
+ "One Byte Boundary (/Zp1)", "1", 0},
+ {"PackAlignmentBoundary", "/Zp2",
+ "Two Byte Boundary (/Zp2)", "2", 0},
+ {"PackAlignmentBoundary", "/Zp4",
+ "Four Byte Boundary (/Zp4)", "3", 0},
+ {"PackAlignmentBoundary", "/Zp8",
+ "Eight Byte Boundary (/Zp8)", "4", 0},
+ {"PackAlignmentBoundary", "/Zp16",
+ "Sixteen Byte Boundary (/Zp16)", "5", 0},
+
+ {"CallingConvention", "",
+ "Default", "0", 0},
+ {"CallingConvention", "/Gd",
+ "Use C-style Calling Convention (/Gd)", "1", 0},
+ {"CallingConvention", "/Gz",
+ "Use stdcall Calling Convention (/Gz)", "2", 0},
+ {"CallingConvention", "/Gc",
+ "Use Pascal Calling Convention (/Gc)", "3", 0},
+
+ {"ErrorReporting", "/errorReport:prompt",
+ "Prompt to send report immediately (/errorReport:prompt)", "0", 0},
+ {"ErrorReporting", "/errorReport:queue",
+ "Prompt to send report at the next logon (/errorReport:queue)", "1", 0},
+ {"ErrorReporting", "/errorReport:send",
+ "Automatically send report (/errorReport:send)", "2", 0},
+ {"ErrorReporting", "/errorReport:none",
+ "Do not send report (/errorReport:none)", "3", 0},
+
+
+ //Bool Properties
+ {"NoLogo", "/nologo", "", "true", 0},
+ {"GeneratePreprocessedSourceListing", "/EP", "", "true", 0},
+ {"ListAllAvailableInformation", "/Sa", "", "true", 0},
+ {"UseSafeExceptionHandlers", "/safeseh", "", "true", 0},
+ {"AddFirstPassListing", "/Sf", "", "true", 0},
+ {"EnableAssemblyGeneratedCodeListing", "/Sg", "", "true", 0},
+ {"DisableSymbolTable", "/Sn", "", "true", 0},
+ {"EnableFalseConditionalsInListing", "/Sx", "", "true", 0},
+ {"TreatWarningsAsErrors", "/WX", "", "true", 0},
+ {"MakeAllSymbolsPublic", "/Zf", "", "true", 0},
+ {"GenerateDebugInformation", "/Zi", "", "true", 0},
+ {"EnableMASM51Compatibility", "/Zm", "", "true", 0},
+ {"PerformSyntaxCheckOnly", "/Zs", "", "true", 0},
+
+ //Bool Properties With Argument
+
+ //String List Properties
+ {"PreprocessorDefinitions", "/D",
+ "Preprocessor Definitions",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"IncludePaths", "/I",
+ "Include Paths",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"BrowseFile", "/FR",
+ "Generate Browse Information File",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ // Skip [AdditionalDependencies] - no command line Switch.
+
+ //String Properties
+ // Skip [Inputs] - no command line Switch.
+ {"ObjectFileName", "/Fo",
+ "Object File Name",
+ "", cmVS7FlagTable::UserValue},
+ {"AssembledCodeListingFile", "/Fl",
+ "Assembled Code Listing File",
+ "", cmVS7FlagTable::UserValue},
+ // Skip [CommandLineTemplate] - no command line Switch.
+ // Skip [ExecutionDescription] - no command line Switch.
+ // Skip [AdditionalOptions] - no command line Switch.
+ {0,0,0,0,0}
+};
diff --git a/Source/cmVS11RCFlagTable.h b/Source/cmVS11RCFlagTable.h
new file mode 100644
index 000000000..a7d2de1e3
--- /dev/null
+++ b/Source/cmVS11RCFlagTable.h
@@ -0,0 +1,7 @@
+static cmVS7FlagTable cmVS11RCFlagTable[] =
+{
+ //Bool Properties
+ {"NullTerminateStrings", "n", "", "true", 0},
+
+ {0,0,0,0,0}
+};
diff --git a/Source/cmVS12CLFlagTable.h b/Source/cmVS12CLFlagTable.h
index 8f5131989..0a7916f1b 100644
--- a/Source/cmVS12CLFlagTable.h
+++ b/Source/cmVS12CLFlagTable.h
@@ -254,9 +254,9 @@ static cmVS7FlagTable cmVS12CLFlagTable[] =
{"ForcedUsingFiles", "FU",
"Forced #using File",
"", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
- {"PREfastAdditionalOptions", "analyze:",
- "Additional Code Analysis Native options",
- "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"PREfastLog", "analyze:log",
+ "Code Analysis Log",
+ "", cmVS7FlagTable::UserFollowing},
{"PREfastAdditionalPlugins", "analyze:plugin",
"Additional Code Analysis Native plugins",
"", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
@@ -289,9 +289,6 @@ static cmVS7FlagTable cmVS12CLFlagTable[] =
"", cmVS7FlagTable::UserValue},
// Skip [XMLDocumentationFileName] - no command line Switch.
// Skip [BrowseInformationFile] - no command line Switch.
- {"PREfastLog", "analyze:log ",
- "Code Analysis Log",
- "", cmVS7FlagTable::UserValue},
// Skip [AdditionalOptions] - no command line Switch.
{0,0,0,0,0}
};
diff --git a/Source/cmVS12LinkFlagTable.h b/Source/cmVS12LinkFlagTable.h
index 73d450a9d..0be5e340d 100644
--- a/Source/cmVS12LinkFlagTable.h
+++ b/Source/cmVS12LinkFlagTable.h
@@ -177,7 +177,8 @@ static cmVS7FlagTable cmVS12LinkFlagTable[] =
{"UACUIAccess", "uiAccess='false'", "", "false", 0},
{"UACUIAccess", "uiAccess='true'", "", "true", 0},
{"ManifestEmbed", "manifest:embed", "", "true", 0},
- {"GenerateDebugInformation", "DEBUG", "", "true", 0},
+ {"GenerateDebugInformation", "DEBUG", "", "true",
+ cmVS7FlagTable::CaseInsensitive},
{"MapExports", "MAPINFO:EXPORTS", "", "true", 0},
{"AssemblyDebug", "ASSEMBLYDEBUG:DISABLE", "", "false", 0},
{"AssemblyDebug", "ASSEMBLYDEBUG", "", "true", 0},
@@ -217,10 +218,7 @@ static cmVS7FlagTable cmVS12LinkFlagTable[] =
{"LinkDLL", "DLL", "", "true", 0},
//Bool Properties With Argument
- {"EnableUAC", "MANIFESTUAC:NO", "", "false",
- cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
- {"EnableUAC", "MANIFESTUAC:NO", "Enable User Account Control (UAC)", "",
- cmVS7FlagTable::UserValueRequired},
+ {"EnableUAC", "MANIFESTUAC:NO", "", "false", 0},
{"EnableUAC", "MANIFESTUAC:", "", "true",
cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
{"UACUIAccess", "MANIFESTUAC:", "Enable User Account Control (UAC)", "",
diff --git a/Source/cmVS12MASMFlagTable.h b/Source/cmVS12MASMFlagTable.h
new file mode 100644
index 000000000..74d529c06
--- /dev/null
+++ b/Source/cmVS12MASMFlagTable.h
@@ -0,0 +1,96 @@
+static cmVS7FlagTable cmVS12MASMFlagTable[] =
+{
+
+ //Enum Properties
+ {"PreserveIdentifierCase", "",
+ "Default", "0", 0},
+ {"PreserveIdentifierCase", "/Cp",
+ "Preserves Identifier Case (/Cp)", "1", 0},
+ {"PreserveIdentifierCase", "/Cu",
+ "Maps all identifiers to upper case. (/Cu)", "2", 0},
+ {"PreserveIdentifierCase", "/Cx",
+ "Preserves case in public and extern symbols. (/Cx)", "3", 0},
+
+ {"WarningLevel", "/W0",
+ "Warning Level 0 (/W0)", "0", 0},
+ {"WarningLevel", "/W1",
+ "Warning Level 1 (/W1)", "1", 0},
+ {"WarningLevel", "/W2",
+ "Warning Level 2 (/W2)", "2", 0},
+ {"WarningLevel", "/W3",
+ "Warning Level 3 (/W3)", "3", 0},
+
+ {"PackAlignmentBoundary", "",
+ "Default", "0", 0},
+ {"PackAlignmentBoundary", "/Zp1",
+ "One Byte Boundary (/Zp1)", "1", 0},
+ {"PackAlignmentBoundary", "/Zp2",
+ "Two Byte Boundary (/Zp2)", "2", 0},
+ {"PackAlignmentBoundary", "/Zp4",
+ "Four Byte Boundary (/Zp4)", "3", 0},
+ {"PackAlignmentBoundary", "/Zp8",
+ "Eight Byte Boundary (/Zp8)", "4", 0},
+ {"PackAlignmentBoundary", "/Zp16",
+ "Sixteen Byte Boundary (/Zp16)", "5", 0},
+
+ {"CallingConvention", "",
+ "Default", "0", 0},
+ {"CallingConvention", "/Gd",
+ "Use C-style Calling Convention (/Gd)", "1", 0},
+ {"CallingConvention", "/Gz",
+ "Use stdcall Calling Convention (/Gz)", "2", 0},
+ {"CallingConvention", "/Gc",
+ "Use Pascal Calling Convention (/Gc)", "3", 0},
+
+ {"ErrorReporting", "/errorReport:prompt",
+ "Prompt to send report immediately (/errorReport:prompt)", "0", 0},
+ {"ErrorReporting", "/errorReport:queue",
+ "Prompt to send report at the next logon (/errorReport:queue)", "1", 0},
+ {"ErrorReporting", "/errorReport:send",
+ "Automatically send report (/errorReport:send)", "2", 0},
+ {"ErrorReporting", "/errorReport:none",
+ "Do not send report (/errorReport:none)", "3", 0},
+
+
+ //Bool Properties
+ {"NoLogo", "/nologo", "", "true", 0},
+ {"GeneratePreprocessedSourceListing", "/EP", "", "true", 0},
+ {"ListAllAvailableInformation", "/Sa", "", "true", 0},
+ {"UseSafeExceptionHandlers", "/safeseh", "", "true", 0},
+ {"AddFirstPassListing", "/Sf", "", "true", 0},
+ {"EnableAssemblyGeneratedCodeListing", "/Sg", "", "true", 0},
+ {"DisableSymbolTable", "/Sn", "", "true", 0},
+ {"EnableFalseConditionalsInListing", "/Sx", "", "true", 0},
+ {"TreatWarningsAsErrors", "/WX", "", "true", 0},
+ {"MakeAllSymbolsPublic", "/Zf", "", "true", 0},
+ {"GenerateDebugInformation", "/Zi", "", "true", 0},
+ {"EnableMASM51Compatibility", "/Zm", "", "true", 0},
+ {"PerformSyntaxCheckOnly", "/Zs", "", "true", 0},
+
+ //Bool Properties With Argument
+
+ //String List Properties
+ {"PreprocessorDefinitions", "/D",
+ "Preprocessor Definitions",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"IncludePaths", "/I",
+ "Include Paths",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"BrowseFile", "/FR",
+ "Generate Browse Information File",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ // Skip [AdditionalDependencies] - no command line Switch.
+
+ //String Properties
+ // Skip [Inputs] - no command line Switch.
+ {"ObjectFileName", "/Fo",
+ "Object File Name",
+ "", cmVS7FlagTable::UserValue},
+ {"AssembledCodeListingFile", "/Fl",
+ "Assembled Code Listing File",
+ "", cmVS7FlagTable::UserValue},
+ // Skip [CommandLineTemplate] - no command line Switch.
+ // Skip [ExecutionDescription] - no command line Switch.
+ // Skip [AdditionalOptions] - no command line Switch.
+ {0,0,0,0,0}
+};
diff --git a/Source/cmVS12RCFlagTable.h b/Source/cmVS12RCFlagTable.h
new file mode 100644
index 000000000..1551c66f9
--- /dev/null
+++ b/Source/cmVS12RCFlagTable.h
@@ -0,0 +1,7 @@
+static cmVS7FlagTable cmVS12RCFlagTable[] =
+{
+ //Bool Properties
+ {"NullTerminateStrings", "n", "", "true", 0},
+
+ {0,0,0,0,0}
+};
diff --git a/Source/cmVS14CLFlagTable.h b/Source/cmVS14CLFlagTable.h
new file mode 100644
index 000000000..422f47b43
--- /dev/null
+++ b/Source/cmVS14CLFlagTable.h
@@ -0,0 +1,296 @@
+static cmVS7FlagTable cmVS14CLFlagTable[] =
+{
+
+ //Enum Properties
+ {"DebugInformationFormat", "",
+ "None", "None", 0},
+ {"DebugInformationFormat", "Z7",
+ "C7 compatible", "OldStyle", 0},
+ {"DebugInformationFormat", "Zi",
+ "Program Database", "ProgramDatabase", 0},
+ {"DebugInformationFormat", "ZI",
+ "Program Database for Edit And Continue", "EditAndContinue", 0},
+
+ {"WarningLevel", "W0",
+ "Turn Off All Warnings", "TurnOffAllWarnings", 0},
+ {"WarningLevel", "W1",
+ "Level1", "Level1", 0},
+ {"WarningLevel", "W2",
+ "Level2", "Level2", 0},
+ {"WarningLevel", "W3",
+ "Level3", "Level3", 0},
+ {"WarningLevel", "W4",
+ "Level4", "Level4", 0},
+ {"WarningLevel", "Wall",
+ "EnableAllWarnings", "EnableAllWarnings", 0},
+
+ {"Optimization", "",
+ "Custom", "Custom", 0},
+ {"Optimization", "Od",
+ "Disabled", "Disabled", 0},
+ {"Optimization", "O1",
+ "Minimize Size", "MinSpace", 0},
+ {"Optimization", "O2",
+ "Maximize Speed", "MaxSpeed", 0},
+ {"Optimization", "Ox",
+ "Full Optimization", "Full", 0},
+
+ {"InlineFunctionExpansion", "",
+ "Default", "Default", 0},
+ {"InlineFunctionExpansion", "Ob0",
+ "Disabled", "Disabled", 0},
+ {"InlineFunctionExpansion", "Ob1",
+ "Only __inline", "OnlyExplicitInline", 0},
+ {"InlineFunctionExpansion", "Ob2",
+ "Any Suitable", "AnySuitable", 0},
+
+ {"FavorSizeOrSpeed", "Os",
+ "Favor small code", "Size", 0},
+ {"FavorSizeOrSpeed", "Ot",
+ "Favor fast code", "Speed", 0},
+ {"FavorSizeOrSpeed", "",
+ "Neither", "Neither", 0},
+
+ {"ExceptionHandling", "EHa",
+ "Yes with SEH Exceptions", "Async", 0},
+ {"ExceptionHandling", "EHsc",
+ "Yes", "Sync", 0},
+ {"ExceptionHandling", "EHs",
+ "Yes with Extern C functions", "SyncCThrow", 0},
+ {"ExceptionHandling", "",
+ "No", "false", 0},
+
+ {"BasicRuntimeChecks", "RTCs",
+ "Stack Frames", "StackFrameRuntimeCheck", 0},
+ {"BasicRuntimeChecks", "RTCu",
+ "Uninitialized variables", "UninitializedLocalUsageCheck", 0},
+ {"BasicRuntimeChecks", "RTC1",
+ "Both (/RTC1, equiv. to /RTCsu)", "EnableFastChecks", 0},
+ {"BasicRuntimeChecks", "",
+ "Default", "Default", 0},
+
+ {"RuntimeLibrary", "MT",
+ "Multi-threaded", "MultiThreaded", 0},
+ {"RuntimeLibrary", "MTd",
+ "Multi-threaded Debug", "MultiThreadedDebug", 0},
+ {"RuntimeLibrary", "MD",
+ "Multi-threaded DLL", "MultiThreadedDLL", 0},
+ {"RuntimeLibrary", "MDd",
+ "Multi-threaded Debug DLL", "MultiThreadedDebugDLL", 0},
+
+ {"StructMemberAlignment", "Zp1",
+ "1 Byte", "1Byte", 0},
+ {"StructMemberAlignment", "Zp2",
+ "2 Bytes", "2Bytes", 0},
+ {"StructMemberAlignment", "Zp4",
+ "4 Byte", "4Bytes", 0},
+ {"StructMemberAlignment", "Zp8",
+ "8 Bytes", "8Bytes", 0},
+ {"StructMemberAlignment", "Zp16",
+ "16 Bytes", "16Bytes", 0},
+ {"StructMemberAlignment", "",
+ "Default", "Default", 0},
+
+ {"BufferSecurityCheck", "GS-",
+ "Disable Security Check", "false", 0},
+ {"BufferSecurityCheck", "GS",
+ "Enable Security Check", "true", 0},
+
+ {"EnableEnhancedInstructionSet", "arch:SSE",
+ "Streaming SIMD Extensions", "StreamingSIMDExtensions", 0},
+ {"EnableEnhancedInstructionSet", "arch:SSE2",
+ "Streaming SIMD Extensions 2", "StreamingSIMDExtensions2", 0},
+ {"EnableEnhancedInstructionSet", "arch:AVX",
+ "Advanced Vector Extensions", "AdvancedVectorExtensions", 0},
+ {"EnableEnhancedInstructionSet", "arch:AVX2",
+ "Advanced Vector Extensions 2", "AdvancedVectorExtensions2", 0},
+ {"EnableEnhancedInstructionSet", "arch:IA32",
+ "No Enhanced Instructions", "NoExtensions", 0},
+ {"EnableEnhancedInstructionSet", "",
+ "Not Set", "NotSet", 0},
+
+ {"FloatingPointModel", "fp:precise",
+ "Precise", "Precise", 0},
+ {"FloatingPointModel", "fp:strict",
+ "Strict", "Strict", 0},
+ {"FloatingPointModel", "fp:fast",
+ "Fast", "Fast", 0},
+
+ {"PrecompiledHeader", "Yc",
+ "Create", "Create",
+ cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
+ {"PrecompiledHeader", "Yu",
+ "Use", "Use",
+ cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
+ {"PrecompiledHeader", "",
+ "Not Using Precompiled Headers", "NotUsing", 0},
+
+ {"AssemblerOutput", "",
+ "No Listing", "NoListing", 0},
+ {"AssemblerOutput", "FA",
+ "Assembly-Only Listing", "AssemblyCode", 0},
+ {"AssemblerOutput", "FAc",
+ "Assembly With Machine Code", "AssemblyAndMachineCode", 0},
+ {"AssemblerOutput", "FAs",
+ "Assembly With Source Code", "AssemblyAndSourceCode", 0},
+ {"AssemblerOutput", "FAcs",
+ "Assembly, Machine Code and Source", "All", 0},
+
+ {"CallingConvention", "Gd",
+ "__cdecl", "Cdecl", 0},
+ {"CallingConvention", "Gr",
+ "__fastcall", "FastCall", 0},
+ {"CallingConvention", "Gz",
+ "__stdcall", "StdCall", 0},
+ {"CallingConvention", "Gv",
+ "__vectorcall", "VectorCall", 0},
+
+ {"CompileAs", "",
+ "Default", "Default", 0},
+ {"CompileAs", "TC",
+ "Compile as C Code", "CompileAsC", 0},
+ {"CompileAs", "TP",
+ "Compile as C++ Code", "CompileAsCpp", 0},
+
+ {"ErrorReporting", "errorReport:none",
+ "Do Not Send Report", "None", 0},
+ {"ErrorReporting", "errorReport:prompt",
+ "Prompt Immediately", "Prompt", 0},
+ {"ErrorReporting", "errorReport:queue",
+ "Queue For Next Login", "Queue", 0},
+ {"ErrorReporting", "errorReport:send",
+ "Send Automatically", "Send", 0},
+
+ {"CompileAsManaged", "",
+ "No Common Language RunTime Support", "false", 0},
+ {"CompileAsManaged", "clr",
+ "Common Language RunTime Support", "true", 0},
+ {"CompileAsManaged", "clr:pure",
+ "Pure MSIL Common Language RunTime Support", "Pure", 0},
+ {"CompileAsManaged", "clr:safe",
+ "Safe MSIL Common Language RunTime Support", "Safe", 0},
+ {"CompileAsManaged", "clr:oldSyntax",
+ "Common Language RunTime Support, Old Syntax", "OldSyntax", 0},
+
+
+ //Bool Properties
+ {"CompileAsWinRT", "ZW", "", "true", 0},
+ {"WinRTNoStdLib", "ZW:nostdlib", "", "true", 0},
+ {"SuppressStartupBanner", "nologo", "", "true", 0},
+ {"TreatWarningAsError", "WX-", "", "false", 0},
+ {"TreatWarningAsError", "WX", "", "true", 0},
+ {"SDLCheck", "sdl-", "", "false", 0},
+ {"SDLCheck", "sdl", "", "true", 0},
+ {"IntrinsicFunctions", "Oi", "", "true", 0},
+ {"OmitFramePointers", "Oy-", "", "false", 0},
+ {"OmitFramePointers", "Oy", "", "true", 0},
+ {"EnableFiberSafeOptimizations", "GT", "", "true", 0},
+ {"WholeProgramOptimization", "GL", "", "true", 0},
+ {"UndefineAllPreprocessorDefinitions", "u", "", "true", 0},
+ {"IgnoreStandardIncludePath", "X", "", "true", 0},
+ {"PreprocessToFile", "P", "", "true", 0},
+ {"PreprocessSuppressLineNumbers", "EP", "", "true", 0},
+ {"PreprocessKeepComments", "C", "", "true", 0},
+ {"StringPooling", "GF-", "", "false", 0},
+ {"StringPooling", "GF", "", "true", 0},
+ {"MinimalRebuild", "Gm-", "", "false", 0},
+ {"MinimalRebuild", "Gm", "", "true", 0},
+ {"SmallerTypeCheck", "RTCc", "", "true", 0},
+ {"FunctionLevelLinking", "Gy-", "", "false", 0},
+ {"FunctionLevelLinking", "Gy", "", "true", 0},
+ {"EnableParallelCodeGeneration", "Qpar-", "", "false", 0},
+ {"EnableParallelCodeGeneration", "Qpar", "", "true", 0},
+ {"FloatingPointExceptions", "fp:except-", "", "false", 0},
+ {"FloatingPointExceptions", "fp:except", "", "true", 0},
+ {"CreateHotpatchableImage", "hotpatch", "", "true", 0},
+ {"DisableLanguageExtensions", "Za", "", "true", 0},
+ {"TreatWChar_tAsBuiltInType", "Zc:wchar_t-", "", "false", 0},
+ {"TreatWChar_tAsBuiltInType", "Zc:wchar_t", "", "true", 0},
+ {"ForceConformanceInForLoopScope", "Zc:forScope-", "", "false", 0},
+ {"ForceConformanceInForLoopScope", "Zc:forScope", "", "true", 0},
+ {"RuntimeTypeInfo", "GR-", "", "false", 0},
+ {"RuntimeTypeInfo", "GR", "", "true", 0},
+ {"OpenMPSupport", "openmp-", "", "false", 0},
+ {"OpenMPSupport", "openmp", "", "true", 0},
+ {"ExpandAttributedSource", "Fx", "", "true", 0},
+ {"UseUnicodeForAssemblerListing", "FAu", "", "true", 0},
+ {"ShowIncludes", "showIncludes", "", "true", 0},
+ {"EnablePREfast", "analyze-", "", "false", 0},
+ {"EnablePREfast", "analyze", "", "true", 0},
+ {"UseFullPaths", "FC", "", "true", 0},
+ {"OmitDefaultLibName", "Zl", "", "true", 0},
+
+ //Bool Properties With Argument
+ {"MultiProcessorCompilation", "MP", "", "true",
+ cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
+ {"ProcessorNumber", "MP", "Multi-processor Compilation", "",
+ cmVS7FlagTable::UserValueRequired},
+ {"GenerateXMLDocumentationFiles", "doc", "", "true",
+ cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
+ {"XMLDocumentationFileName", "doc", "Generate XML Documentation Files", "",
+ cmVS7FlagTable::UserValueRequired},
+ {"BrowseInformation", "FR", "", "true",
+ cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
+ {"BrowseInformationFile", "FR", "Enable Browse Information", "",
+ cmVS7FlagTable::UserValueRequired},
+
+ //String List Properties
+ {"AdditionalIncludeDirectories", "I",
+ "Additional Include Directories",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"AdditionalUsingDirectories", "AI",
+ "Additional #using Directories",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"PreprocessorDefinitions", "D ",
+ "Preprocessor Definitions",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"UndefinePreprocessorDefinitions", "U",
+ "Undefine Preprocessor Definitions",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"DisableSpecificWarnings", "wd",
+ "Disable Specific Warnings",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"ForcedIncludeFiles", "FI",
+ "Forced Include File",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"ForcedUsingFiles", "FU",
+ "Forced #using File",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"PREfastLog", "analyze:log",
+ "Code Analysis Log",
+ "", cmVS7FlagTable::UserFollowing},
+ {"PREfastAdditionalPlugins", "analyze:plugin",
+ "Additional Code Analysis Native plugins",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"TreatSpecificWarningsAsErrors", "we",
+ "Treat Specific Warnings As Errors",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+
+ //String Properties
+ // Skip [TrackerLogDirectory] - no command line Switch.
+ {"PreprocessOutputPath", "Fi",
+ "Preprocess Output Path",
+ "", cmVS7FlagTable::UserValue},
+ {"PrecompiledHeaderFile", "Yc",
+ "Precompiled Header Name",
+ "", cmVS7FlagTable::UserValueRequired},
+ {"PrecompiledHeaderFile", "Yu",
+ "Precompiled Header Name",
+ "", cmVS7FlagTable::UserValueRequired},
+ {"PrecompiledHeaderOutputFile", "Fp",
+ "Precompiled Header Output File",
+ "", cmVS7FlagTable::UserValue},
+ {"AssemblerListingLocation", "Fa",
+ "ASM List Location",
+ "", cmVS7FlagTable::UserValue},
+ {"ObjectFileName", "Fo",
+ "Object File Name",
+ "", cmVS7FlagTable::UserValue},
+ {"ProgramDataBaseFileName", "Fd",
+ "Program Database File Name",
+ "", cmVS7FlagTable::UserValue},
+ // Skip [XMLDocumentationFileName] - no command line Switch.
+ // Skip [BrowseInformationFile] - no command line Switch.
+ // Skip [AdditionalOptions] - no command line Switch.
+ {0,0,0,0,0}
+};
diff --git a/Source/cmVS14LibFlagTable.h b/Source/cmVS14LibFlagTable.h
new file mode 100644
index 000000000..a33f273bb
--- /dev/null
+++ b/Source/cmVS14LibFlagTable.h
@@ -0,0 +1,102 @@
+static cmVS7FlagTable cmVS14LibFlagTable[] =
+{
+
+ //Enum Properties
+ {"ErrorReporting", "ERRORREPORT:PROMPT",
+ "PromptImmediately", "PromptImmediately", 0},
+ {"ErrorReporting", "ERRORREPORT:QUEUE",
+ "Queue For Next Login", "QueueForNextLogin", 0},
+ {"ErrorReporting", "ERRORREPORT:SEND",
+ "Send Error Report", "SendErrorReport", 0},
+ {"ErrorReporting", "ERRORREPORT:NONE",
+ "No Error Report", "NoErrorReport", 0},
+
+ {"TargetMachine", "MACHINE:ARM",
+ "MachineARM", "MachineARM", 0},
+ {"TargetMachine", "MACHINE:EBC",
+ "MachineEBC", "MachineEBC", 0},
+ {"TargetMachine", "MACHINE:IA64",
+ "MachineIA64", "MachineIA64", 0},
+ {"TargetMachine", "MACHINE:MIPS",
+ "MachineMIPS", "MachineMIPS", 0},
+ {"TargetMachine", "MACHINE:MIPS16",
+ "MachineMIPS16", "MachineMIPS16", 0},
+ {"TargetMachine", "MACHINE:MIPSFPU",
+ "MachineMIPSFPU", "MachineMIPSFPU", 0},
+ {"TargetMachine", "MACHINE:MIPSFPU16",
+ "MachineMIPSFPU16", "MachineMIPSFPU16", 0},
+ {"TargetMachine", "MACHINE:SH4",
+ "MachineSH4", "MachineSH4", 0},
+ {"TargetMachine", "MACHINE:THUMB",
+ "MachineTHUMB", "MachineTHUMB", 0},
+ {"TargetMachine", "MACHINE:X64",
+ "MachineX64", "MachineX64", 0},
+ {"TargetMachine", "MACHINE:X86",
+ "MachineX86", "MachineX86", 0},
+
+ {"SubSystem", "SUBSYSTEM:CONSOLE",
+ "Console", "Console", 0},
+ {"SubSystem", "SUBSYSTEM:WINDOWS",
+ "Windows", "Windows", 0},
+ {"SubSystem", "SUBSYSTEM:NATIVE",
+ "Native", "Native", 0},
+ {"SubSystem", "SUBSYSTEM:EFI_APPLICATION",
+ "EFI Application", "EFI Application", 0},
+ {"SubSystem", "SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER",
+ "EFI Boot Service Driver", "EFI Boot Service Driver", 0},
+ {"SubSystem", "SUBSYSTEM:EFI_ROM",
+ "EFI ROM", "EFI ROM", 0},
+ {"SubSystem", "SUBSYSTEM:EFI_RUNTIME_DRIVER",
+ "EFI Runtime", "EFI Runtime", 0},
+ {"SubSystem", "SUBSYSTEM:WINDOWSCE",
+ "WindowsCE", "WindowsCE", 0},
+ {"SubSystem", "SUBSYSTEM:POSIX",
+ "POSIX", "POSIX", 0},
+
+
+ //Bool Properties
+ {"SuppressStartupBanner", "NOLOGO", "", "true", 0},
+ {"IgnoreAllDefaultLibraries", "NODEFAULTLIB", "", "true", 0},
+ {"TreatLibWarningAsErrors", "WX:NO", "", "false", 0},
+ {"TreatLibWarningAsErrors", "WX", "", "true", 0},
+ {"Verbose", "VERBOSE", "", "true", 0},
+ {"LinkTimeCodeGeneration", "LTCG", "", "true", 0},
+
+ //Bool Properties With Argument
+
+ //String List Properties
+ // Skip [AdditionalDependencies] - no command line Switch.
+ {"AdditionalLibraryDirectories", "LIBPATH:",
+ "Additional Library Directories",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"IgnoreSpecificDefaultLibraries", "NODEFAULTLIB:",
+ "Ignore Specific Default Libraries",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"ExportNamedFunctions", "EXPORT:",
+ "Export Named Functions",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"RemoveObjects", "REMOVE:",
+ "Remove Objects",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+
+ //String Properties
+ {"OutputFile", "OUT:",
+ "Output File",
+ "", cmVS7FlagTable::UserValue},
+ {"ModuleDefinitionFile", "DEF:",
+ "Module Definition File Name",
+ "", cmVS7FlagTable::UserValue},
+ {"ForceSymbolReferences", "INCLUDE:",
+ "Force Symbol References",
+ "", cmVS7FlagTable::UserValue},
+ {"DisplayLibrary", "LIST:",
+ "Display Library to standard output",
+ "", cmVS7FlagTable::UserValue},
+ // Skip [MinimumRequiredVersion] - no command line Switch.
+ {"Name", "NAME:",
+ "Name",
+ "", cmVS7FlagTable::UserValue},
+ // Skip [AdditionalOptions] - no command line Switch.
+ // Skip [TrackerLogDirectory] - no command line Switch.
+ {0,0,0,0,0}
+};
diff --git a/Source/cmVS14LinkFlagTable.h b/Source/cmVS14LinkFlagTable.h
new file mode 100644
index 000000000..29e3d8606
--- /dev/null
+++ b/Source/cmVS14LinkFlagTable.h
@@ -0,0 +1,343 @@
+static cmVS7FlagTable cmVS14LinkFlagTable[] =
+{
+
+ //Enum Properties
+ {"ShowProgress", "",
+ "Not Set", "NotSet", 0},
+ {"ShowProgress", "VERBOSE",
+ "Display all progress messages", "LinkVerbose", 0},
+ {"ShowProgress", "VERBOSE:Lib",
+ "For Libraries Searched", "LinkVerboseLib", 0},
+ {"ShowProgress", "VERBOSE:ICF",
+ "About COMDAT folding during optimized linking", "LinkVerboseICF", 0},
+ {"ShowProgress", "VERBOSE:REF",
+ "About data removed during optimized linking", "LinkVerboseREF", 0},
+ {"ShowProgress", "VERBOSE:SAFESEH",
+ "About Modules incompatible with SEH", "LinkVerboseSAFESEH", 0},
+ {"ShowProgress", "VERBOSE:CLR",
+ "About linker activity related to managed code", "LinkVerboseCLR", 0},
+
+ {"ForceFileOutput", "FORCE",
+ "Enabled", "Enabled", 0},
+ {"ForceFileOutput", "FORCE:MULTIPLE",
+ "Multiply Defined Symbol Only", "MultiplyDefinedSymbolOnly", 0},
+ {"ForceFileOutput", "FORCE:UNRESOLVED",
+ "Undefined Symbol Only", "UndefinedSymbolOnly", 0},
+
+ {"CreateHotPatchableImage", "FUNCTIONPADMIN",
+ "Enabled", "Enabled", 0},
+ {"CreateHotPatchableImage", "FUNCTIONPADMIN:5",
+ "X86 Image Only", "X86Image", 0},
+ {"CreateHotPatchableImage", "FUNCTIONPADMIN:6",
+ "X64 Image Only", "X64Image", 0},
+ {"CreateHotPatchableImage", "FUNCTIONPADMIN:16",
+ "Itanium Image Only", "ItaniumImage", 0},
+
+ {"UACExecutionLevel", "level='asInvoker'",
+ "asInvoker", "AsInvoker", 0},
+ {"UACExecutionLevel", "level='highestAvailable'",
+ "highestAvailable", "HighestAvailable", 0},
+ {"UACExecutionLevel", "level='requireAdministrator'",
+ "requireAdministrator", "RequireAdministrator", 0},
+
+ {"SubSystem", "",
+ "Not Set", "NotSet", 0},
+ {"SubSystem", "SUBSYSTEM:CONSOLE",
+ "Console", "Console", 0},
+ {"SubSystem", "SUBSYSTEM:WINDOWS",
+ "Windows", "Windows", 0},
+ {"SubSystem", "SUBSYSTEM:NATIVE",
+ "Native", "Native", 0},
+ {"SubSystem", "SUBSYSTEM:EFI_APPLICATION",
+ "EFI Application", "EFI Application", 0},
+ {"SubSystem", "SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER",
+ "EFI Boot Service Driver", "EFI Boot Service Driver", 0},
+ {"SubSystem", "SUBSYSTEM:EFI_ROM",
+ "EFI ROM", "EFI ROM", 0},
+ {"SubSystem", "SUBSYSTEM:EFI_RUNTIME_DRIVER",
+ "EFI Runtime", "EFI Runtime", 0},
+ {"SubSystem", "SUBSYSTEM:POSIX",
+ "POSIX", "POSIX", 0},
+
+ {"Driver", "",
+ "Not Set", "NotSet", 0},
+ {"Driver", "Driver",
+ "Driver", "Driver", 0},
+ {"Driver", "DRIVER:UPONLY",
+ "UP Only", "UpOnly", 0},
+ {"Driver", "DRIVER:WDM",
+ "WDM", "WDM", 0},
+
+ {"LinkTimeCodeGeneration", "",
+ "Default", "Default", 0},
+ {"LinkTimeCodeGeneration", "LTCG",
+ "Use Link Time Code Generation", "UseLinkTimeCodeGeneration", 0},
+ {"LinkTimeCodeGeneration", "LTCG:PGInstrument",
+ "Profile Guided Optimization - Instrument", "PGInstrument", 0},
+ {"LinkTimeCodeGeneration", "LTCG:PGOptimize",
+ "Profile Guided Optimization - Optimization", "PGOptimization", 0},
+ {"LinkTimeCodeGeneration", "LTCG:PGUpdate",
+ "Profile Guided Optimization - Update", "PGUpdate", 0},
+
+ {"GenerateWindowsMetadata", "WINMD",
+ "Yes", "true", 0},
+ {"GenerateWindowsMetadata", "WINMD:NO",
+ "No", "false", 0},
+
+ {"WindowsMetadataSignHash", "WINMDSIGNHASH:SHA1",
+ "SHA1", "SHA1", 0},
+ {"WindowsMetadataSignHash", "WINMDSIGNHASH:SHA256",
+ "SHA256", "SHA256", 0},
+ {"WindowsMetadataSignHash", "WINMDSIGNHASH:SHA384",
+ "SHA384", "SHA384", 0},
+ {"WindowsMetadataSignHash", "WINMDSIGNHASH:SHA512",
+ "SHA512", "SHA512", 0},
+
+ {"TargetMachine", "",
+ "Not Set", "NotSet", 0},
+ {"TargetMachine", "MACHINE:ARM",
+ "MachineARM", "MachineARM", 0},
+ {"TargetMachine", "MACHINE:EBC",
+ "MachineEBC", "MachineEBC", 0},
+ {"TargetMachine", "MACHINE:IA64",
+ "MachineIA64", "MachineIA64", 0},
+ {"TargetMachine", "MACHINE:MIPS",
+ "MachineMIPS", "MachineMIPS", 0},
+ {"TargetMachine", "MACHINE:MIPS16",
+ "MachineMIPS16", "MachineMIPS16", 0},
+ {"TargetMachine", "MACHINE:MIPSFPU",
+ "MachineMIPSFPU", "MachineMIPSFPU", 0},
+ {"TargetMachine", "MACHINE:MIPSFPU16",
+ "MachineMIPSFPU16", "MachineMIPSFPU16", 0},
+ {"TargetMachine", "MACHINE:SH4",
+ "MachineSH4", "MachineSH4", 0},
+ {"TargetMachine", "MACHINE:THUMB",
+ "MachineTHUMB", "MachineTHUMB", 0},
+ {"TargetMachine", "MACHINE:X64",
+ "MachineX64", "MachineX64", 0},
+ {"TargetMachine", "MACHINE:X86",
+ "MachineX86", "MachineX86", 0},
+
+ {"CLRThreadAttribute", "CLRTHREADATTRIBUTE:MTA",
+ "MTA threading attribute", "MTAThreadingAttribute", 0},
+ {"CLRThreadAttribute", "CLRTHREADATTRIBUTE:STA",
+ "STA threading attribute", "STAThreadingAttribute", 0},
+ {"CLRThreadAttribute", "CLRTHREADATTRIBUTE:NONE",
+ "Default threading attribute", "DefaultThreadingAttribute", 0},
+
+ {"CLRImageType", "CLRIMAGETYPE:IJW",
+ "Force IJW image", "ForceIJWImage", 0},
+ {"CLRImageType", "CLRIMAGETYPE:PURE",
+ "Force Pure IL Image", "ForcePureILImage", 0},
+ {"CLRImageType", "CLRIMAGETYPE:SAFE",
+ "Force Safe IL Image", "ForceSafeILImage", 0},
+ {"CLRImageType", "",
+ "Default image type", "Default", 0},
+
+ {"SignHash", "CLRSIGNHASH:SHA1",
+ "SHA1", "SHA1", 0},
+ {"SignHash", "CLRSIGNHASH:SHA256",
+ "SHA256", "SHA256", 0},
+ {"SignHash", "CLRSIGNHASH:SHA384",
+ "SHA384", "SHA384", 0},
+ {"SignHash", "CLRSIGNHASH:SHA512",
+ "SHA512", "SHA512", 0},
+
+ {"LinkErrorReporting", "ERRORREPORT:PROMPT",
+ "PromptImmediately", "PromptImmediately", 0},
+ {"LinkErrorReporting", "ERRORREPORT:QUEUE",
+ "Queue For Next Login", "QueueForNextLogin", 0},
+ {"LinkErrorReporting", "ERRORREPORT:SEND",
+ "Send Error Report", "SendErrorReport", 0},
+ {"LinkErrorReporting", "ERRORREPORT:NONE",
+ "No Error Report", "NoErrorReport", 0},
+
+ {"CLRSupportLastError", "CLRSupportLastError",
+ "Enabled", "Enabled", 0},
+ {"CLRSupportLastError", "CLRSupportLastError:NO",
+ "Disabled", "Disabled", 0},
+ {"CLRSupportLastError", "CLRSupportLastError:SYSTEMDLL",
+ "System Dlls Only", "SystemDlls", 0},
+
+
+ //Bool Properties
+ {"LinkIncremental", "INCREMENTAL:NO", "", "false", 0},
+ {"LinkIncremental", "INCREMENTAL", "", "true", 0},
+ {"SuppressStartupBanner", "NOLOGO", "", "true", 0},
+ {"LinkStatus", "LTCG:NOSTATUS", "", "false", 0},
+ {"LinkStatus", "LTCG:STATUS", "", "true", 0},
+ {"PreventDllBinding", "ALLOWBIND:NO", "", "false", 0},
+ {"PreventDllBinding", "ALLOWBIND", "", "true", 0},
+ {"TreatLinkerWarningAsErrors", "WX:NO", "", "false", 0},
+ {"TreatLinkerWarningAsErrors", "WX", "", "true", 0},
+ {"IgnoreAllDefaultLibraries", "NODEFAULTLIB", "", "true", 0},
+ {"GenerateManifest", "MANIFEST:NO", "", "false", 0},
+ {"GenerateManifest", "MANIFEST", "", "true", 0},
+ {"AllowIsolation", "ALLOWISOLATION:NO", "", "false", 0},
+ {"UACUIAccess", "uiAccess='false'", "", "false", 0},
+ {"UACUIAccess", "uiAccess='true'", "", "true", 0},
+ {"ManifestEmbed", "manifest:embed", "", "true", 0},
+ {"GenerateDebugInformation", "DEBUG:FASTLINK", "", "DebugFastLink",
+ cmVS7FlagTable::CaseInsensitive},
+ {"GenerateDebugInformation", "DEBUG", "", "Debug",
+ cmVS7FlagTable::CaseInsensitive},
+ {"MapExports", "MAPINFO:EXPORTS", "", "true", 0},
+ {"AssemblyDebug", "ASSEMBLYDEBUG:DISABLE", "", "false", 0},
+ {"AssemblyDebug", "ASSEMBLYDEBUG", "", "true", 0},
+ {"LargeAddressAware", "LARGEADDRESSAWARE:NO", "", "false", 0},
+ {"LargeAddressAware", "LARGEADDRESSAWARE", "", "true", 0},
+ {"TerminalServerAware", "TSAWARE:NO", "", "false", 0},
+ {"TerminalServerAware", "TSAWARE", "", "true", 0},
+ {"SwapRunFromCD", "SWAPRUN:CD", "", "true", 0},
+ {"SwapRunFromNET", "SWAPRUN:NET", "", "true", 0},
+ {"OptimizeReferences", "OPT:NOREF", "", "false", 0},
+ {"OptimizeReferences", "OPT:REF", "", "true", 0},
+ {"EnableCOMDATFolding", "OPT:NOICF", "", "false", 0},
+ {"EnableCOMDATFolding", "OPT:ICF", "", "true", 0},
+ {"IgnoreEmbeddedIDL", "IGNOREIDL", "", "true", 0},
+ {"AppContainer", "APPCONTAINER", "", "true", 0},
+ {"WindowsMetadataLinkDelaySign", "WINMDDELAYSIGN:NO", "", "false", 0},
+ {"WindowsMetadataLinkDelaySign", "WINMDDELAYSIGN", "", "true", 0},
+ {"NoEntryPoint", "NOENTRY", "", "true", 0},
+ {"SetChecksum", "RELEASE", "", "true", 0},
+ {"RandomizedBaseAddress", "DYNAMICBASE:NO", "", "false", 0},
+ {"RandomizedBaseAddress", "DYNAMICBASE", "", "true", 0},
+ {"FixedBaseAddress", "FIXED:NO", "", "false", 0},
+ {"FixedBaseAddress", "FIXED", "", "true", 0},
+ {"DataExecutionPrevention", "NXCOMPAT:NO", "", "false", 0},
+ {"DataExecutionPrevention", "NXCOMPAT", "", "true", 0},
+ {"TurnOffAssemblyGeneration", "NOASSEMBLY", "", "true", 0},
+ {"SupportUnloadOfDelayLoadedDLL", "DELAY:UNLOAD", "", "true", 0},
+ {"SupportNobindOfDelayLoadedDLL", "DELAY:NOBIND", "", "true", 0},
+ {"Profile", "PROFILE", "", "true", 0},
+ {"LinkDelaySign", "DELAYSIGN:NO", "", "false", 0},
+ {"LinkDelaySign", "DELAYSIGN", "", "true", 0},
+ {"CLRUnmanagedCodeCheck", "CLRUNMANAGEDCODECHECK:NO", "", "false", 0},
+ {"CLRUnmanagedCodeCheck", "CLRUNMANAGEDCODECHECK", "", "true", 0},
+ {"DetectOneDefinitionRule", "ODR", "", "true", 0},
+ {"ImageHasSafeExceptionHandlers", "SAFESEH:NO", "", "false", 0},
+ {"ImageHasSafeExceptionHandlers", "SAFESEH", "", "true", 0},
+ {"LinkDLL", "DLL", "", "true", 0},
+
+ //Bool Properties With Argument
+ {"EnableUAC", "MANIFESTUAC:NO", "", "false", 0},
+ {"EnableUAC", "MANIFESTUAC:", "", "true",
+ cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
+ {"UACUIAccess", "MANIFESTUAC:", "Enable User Account Control (UAC)", "",
+ cmVS7FlagTable::UserValueRequired},
+ {"GenerateMapFile", "MAP", "", "true",
+ cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
+ {"MapFileName", "MAP:", "Generate Map File", "",
+ cmVS7FlagTable::UserValueRequired},
+
+ //String List Properties
+ {"AdditionalLibraryDirectories", "LIBPATH:",
+ "Additional Library Directories",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ // Skip [AdditionalDependencies] - no command line Switch.
+ {"IgnoreSpecificDefaultLibraries", "NODEFAULTLIB:",
+ "Ignore Specific Default Libraries",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"AddModuleNamesToAssembly", "ASSEMBLYMODULE:",
+ "Add Module to Assembly",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"EmbedManagedResourceFile", "ASSEMBLYRESOURCE:",
+ "Embed Managed Resource File",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"ForceSymbolReferences", "INCLUDE:",
+ "Force Symbol References",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"DelayLoadDLLs", "DELAYLOAD:",
+ "Delay Loaded Dlls",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"AssemblyLinkResource", "ASSEMBLYLINKRESOURCE:",
+ "Assembly Link Resource",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"AdditionalManifestDependencies", "MANIFESTDEPENDENCY:",
+ "Additional Manifest Dependencies",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"ManifestInput", "manifestinput:",
+ "Manifest Input",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+
+ //String Properties
+ {"OutputFile", "OUT:",
+ "Output File",
+ "", cmVS7FlagTable::UserValue},
+ {"Version", "VERSION:",
+ "Version",
+ "", cmVS7FlagTable::UserValue},
+ {"SpecifySectionAttributes", "SECTION:",
+ "Specify Section Attributes",
+ "", cmVS7FlagTable::UserValue},
+ {"MSDOSStubFileName", "STUB:",
+ "MS-DOS Stub File Name",
+ "", cmVS7FlagTable::UserValue},
+ // Skip [TrackerLogDirectory] - no command line Switch.
+ {"ModuleDefinitionFile", "DEF:",
+ "Module Definition File",
+ "", cmVS7FlagTable::UserValue},
+ {"ManifestFile", "ManifestFile:",
+ "Manifest File",
+ "", cmVS7FlagTable::UserValue},
+ {"ProgramDatabaseFile", "PDB:",
+ "Generate Program Database File",
+ "", cmVS7FlagTable::UserValue},
+ {"StripPrivateSymbols", "PDBSTRIPPED:",
+ "Strip Private Symbols",
+ "", cmVS7FlagTable::UserValue},
+ // Skip [MapFileName] - no command line Switch.
+ // Skip [MinimumRequiredVersion] - no command line Switch.
+ {"HeapReserveSize", "HEAP:",
+ "Heap Reserve Size",
+ "", cmVS7FlagTable::UserValue},
+ // Skip [HeapCommitSize] - no command line Switch.
+ {"StackReserveSize", "STACK:",
+ "Stack Reserve Size",
+ "", cmVS7FlagTable::UserValue},
+ // Skip [StackCommitSize] - no command line Switch.
+ {"FunctionOrder", "ORDER:@",
+ "Function Order",
+ "", cmVS7FlagTable::UserValue},
+ {"ProfileGuidedDatabase", "PGD:",
+ "Profile Guided Database",
+ "", cmVS7FlagTable::UserValue},
+ {"MidlCommandFile", "MIDL:@",
+ "MIDL Commands",
+ "", cmVS7FlagTable::UserValue},
+ {"MergedIDLBaseFileName", "IDLOUT:",
+ "Merged IDL Base File Name",
+ "", cmVS7FlagTable::UserValue},
+ {"TypeLibraryFile", "TLBOUT:",
+ "Type Library",
+ "", cmVS7FlagTable::UserValue},
+ {"WindowsMetadataFile", "WINMDFILE:",
+ "Windows Metadata File",
+ "", cmVS7FlagTable::UserValue},
+ {"WindowsMetadataLinkKeyFile", "WINMDKEYFILE:",
+ "Windows Metadata Key File",
+ "", cmVS7FlagTable::UserValue},
+ {"WindowsMetadataKeyContainer", "WINMDKEYCONTAINER:",
+ "Windows Metadata Key Container",
+ "", cmVS7FlagTable::UserValue},
+ {"EntryPointSymbol", "ENTRY:",
+ "Entry Point",
+ "", cmVS7FlagTable::UserValue},
+ {"BaseAddress", "BASE:",
+ "Base Address",
+ "", cmVS7FlagTable::UserValue},
+ {"ImportLibrary", "IMPLIB:",
+ "Import Library",
+ "", cmVS7FlagTable::UserValue},
+ {"MergeSections", "MERGE:",
+ "Merge Sections",
+ "", cmVS7FlagTable::UserValue},
+ {"LinkKeyFile", "KEYFILE:",
+ "Key File",
+ "", cmVS7FlagTable::UserValue},
+ {"KeyContainer", "KEYCONTAINER:",
+ "Key Container",
+ "", cmVS7FlagTable::UserValue},
+ // Skip [AdditionalOptions] - no command line Switch.
+ {0,0,0,0,0}
+};
diff --git a/Source/cmVS14MASMFlagTable.h b/Source/cmVS14MASMFlagTable.h
new file mode 100644
index 000000000..dce846f92
--- /dev/null
+++ b/Source/cmVS14MASMFlagTable.h
@@ -0,0 +1,96 @@
+static cmVS7FlagTable cmVS14MASMFlagTable[] =
+{
+
+ //Enum Properties
+ {"PreserveIdentifierCase", "",
+ "Default", "0", 0},
+ {"PreserveIdentifierCase", "/Cp",
+ "Preserves Identifier Case (/Cp)", "1", 0},
+ {"PreserveIdentifierCase", "/Cu",
+ "Maps all identifiers to upper case. (/Cu)", "2", 0},
+ {"PreserveIdentifierCase", "/Cx",
+ "Preserves case in public and extern symbols. (/Cx)", "3", 0},
+
+ {"WarningLevel", "/W0",
+ "Warning Level 0 (/W0)", "0", 0},
+ {"WarningLevel", "/W1",
+ "Warning Level 1 (/W1)", "1", 0},
+ {"WarningLevel", "/W2",
+ "Warning Level 2 (/W2)", "2", 0},
+ {"WarningLevel", "/W3",
+ "Warning Level 3 (/W3)", "3", 0},
+
+ {"PackAlignmentBoundary", "",
+ "Default", "0", 0},
+ {"PackAlignmentBoundary", "/Zp1",
+ "One Byte Boundary (/Zp1)", "1", 0},
+ {"PackAlignmentBoundary", "/Zp2",
+ "Two Byte Boundary (/Zp2)", "2", 0},
+ {"PackAlignmentBoundary", "/Zp4",
+ "Four Byte Boundary (/Zp4)", "3", 0},
+ {"PackAlignmentBoundary", "/Zp8",
+ "Eight Byte Boundary (/Zp8)", "4", 0},
+ {"PackAlignmentBoundary", "/Zp16",
+ "Sixteen Byte Boundary (/Zp16)", "5", 0},
+
+ {"CallingConvention", "",
+ "Default", "0", 0},
+ {"CallingConvention", "/Gd",
+ "Use C-style Calling Convention (/Gd)", "1", 0},
+ {"CallingConvention", "/Gz",
+ "Use stdcall Calling Convention (/Gz)", "2", 0},
+ {"CallingConvention", "/Gc",
+ "Use Pascal Calling Convention (/Gc)", "3", 0},
+
+ {"ErrorReporting", "/errorReport:prompt",
+ "Prompt to send report immediately (/errorReport:prompt)", "0", 0},
+ {"ErrorReporting", "/errorReport:queue",
+ "Prompt to send report at the next logon (/errorReport:queue)", "1", 0},
+ {"ErrorReporting", "/errorReport:send",
+ "Automatically send report (/errorReport:send)", "2", 0},
+ {"ErrorReporting", "/errorReport:none",
+ "Do not send report (/errorReport:none)", "3", 0},
+
+
+ //Bool Properties
+ {"NoLogo", "/nologo", "", "true", 0},
+ {"GeneratePreprocessedSourceListing", "/EP", "", "true", 0},
+ {"ListAllAvailableInformation", "/Sa", "", "true", 0},
+ {"UseSafeExceptionHandlers", "/safeseh", "", "true", 0},
+ {"AddFirstPassListing", "/Sf", "", "true", 0},
+ {"EnableAssemblyGeneratedCodeListing", "/Sg", "", "true", 0},
+ {"DisableSymbolTable", "/Sn", "", "true", 0},
+ {"EnableFalseConditionalsInListing", "/Sx", "", "true", 0},
+ {"TreatWarningsAsErrors", "/WX", "", "true", 0},
+ {"MakeAllSymbolsPublic", "/Zf", "", "true", 0},
+ {"GenerateDebugInformation", "/Zi", "", "true", 0},
+ {"EnableMASM51Compatibility", "/Zm", "", "true", 0},
+ {"PerformSyntaxCheckOnly", "/Zs", "", "true", 0},
+
+ //Bool Properties With Argument
+
+ //String List Properties
+ {"PreprocessorDefinitions", "/D",
+ "Preprocessor Definitions",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"IncludePaths", "/I",
+ "Include Paths",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"BrowseFile", "/FR",
+ "Generate Browse Information File",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ // Skip [AdditionalDependencies] - no command line Switch.
+
+ //String Properties
+ // Skip [Inputs] - no command line Switch.
+ {"ObjectFileName", "/Fo",
+ "Object File Name",
+ "", cmVS7FlagTable::UserValue},
+ {"AssembledCodeListingFile", "/Fl",
+ "Assembled Code Listing File",
+ "", cmVS7FlagTable::UserValue},
+ // Skip [CommandLineTemplate] - no command line Switch.
+ // Skip [ExecutionDescription] - no command line Switch.
+ // Skip [AdditionalOptions] - no command line Switch.
+ {0,0,0,0,0}
+};
diff --git a/Source/cmVS14RCFlagTable.h b/Source/cmVS14RCFlagTable.h
new file mode 100644
index 000000000..ebd8d656e
--- /dev/null
+++ b/Source/cmVS14RCFlagTable.h
@@ -0,0 +1,7 @@
+static cmVS7FlagTable cmVS14RCFlagTable[] =
+{
+ //Bool Properties
+ {"NullTerminateStrings", "n", "", "true", 0},
+
+ {0,0,0,0,0}
+};
diff --git a/Source/cmVariableRequiresCommand.cxx b/Source/cmVariableRequiresCommand.cxx
index 747e9be5e..1d33db13c 100644
--- a/Source/cmVariableRequiresCommand.cxx
+++ b/Source/cmVariableRequiresCommand.cxx
@@ -10,12 +10,15 @@
See the License for more information.
============================================================================*/
#include "cmVariableRequiresCommand.h"
-#include "cmCacheManager.h"
+#include "cmState.h"
// cmLibraryCommand
bool cmVariableRequiresCommand
::InitialPass(std::vector<std::string>const& args, cmExecutionStatus &)
{
+ if(this->Disallowed(cmPolicies::CMP0035,
+ "The variable_requires command should not be called; see CMP0035."))
+ { return true; }
if(args.size() < 3 )
{
this->SetError("called with incorrect number of arguments");
@@ -23,7 +26,7 @@ bool cmVariableRequiresCommand
}
std::string testVariable = args[0];
- if(!this->Makefile->IsOn(testVariable.c_str()))
+ if(!this->Makefile->IsOn(testVariable))
{
return true;
}
@@ -31,28 +34,28 @@ bool cmVariableRequiresCommand
bool requirementsMet = true;
std::string notSet;
bool hasAdvanced = false;
+ cmState* state = this->Makefile->GetState();
for(unsigned int i = 2; i < args.size(); ++i)
{
- if(!this->Makefile->IsOn(args[i].c_str()))
+ if(!this->Makefile->IsOn(args[i]))
{
requirementsMet = false;
notSet += args[i];
notSet += "\n";
- cmCacheManager::CacheIterator it =
- this->Makefile->GetCacheManager()->GetCacheIterator(args[i].c_str());
- if(!it.IsAtEnd() && it.GetPropertyAsBool("ADVANCED"))
+ if(state->GetCacheEntryValue(args[i]) &&
+ state->GetCacheEntryPropertyAsBool(args[i], "ADVANCED"))
{
hasAdvanced = true;
}
}
}
- const char* reqVar = this->Makefile->GetDefinition(resultVariable.c_str());
+ const char* reqVar = this->Makefile->GetDefinition(resultVariable);
// if reqVar is unset, then set it to requirementsMet
// if reqVar is set to true, but requirementsMet is false , then
// set reqVar to false.
if(!reqVar || (!requirementsMet && this->Makefile->IsOn(reqVar)))
{
- this->Makefile->AddDefinition(resultVariable.c_str(), requirementsMet);
+ this->Makefile->AddDefinition(resultVariable, requirementsMet);
}
if(!requirementsMet)
diff --git a/Source/cmVariableRequiresCommand.h b/Source/cmVariableRequiresCommand.h
index c86f43dc6..5b0477f75 100644
--- a/Source/cmVariableRequiresCommand.h
+++ b/Source/cmVariableRequiresCommand.h
@@ -14,68 +14,14 @@
#include "cmCommand.h"
-/** \class cmVariableRequiresCommand
- * \brief Displays a message to the user
- *
- */
class cmVariableRequiresCommand : public cmCommand
{
public:
- /**
- * This is a virtual constructor for the command.
- */
- virtual cmCommand* Clone()
- {
- return new cmVariableRequiresCommand;
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
+ cmTypeMacro(cmVariableRequiresCommand, cmCommand);
+ virtual cmCommand* Clone() { return new cmVariableRequiresCommand; }
virtual bool InitialPass(std::vector<std::string> const& args,
cmExecutionStatus &status);
-
- /**
- * The name of the command as specified in CMakeList.txt.
- */
- virtual const char* GetName() const { return "variable_requires";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Deprecated. Use the if() command instead.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- "Assert satisfaction of an option's required variables.\n"
- " variable_requires(TEST_VARIABLE RESULT_VARIABLE\n"
- " REQUIRED_VARIABLE1\n"
- " REQUIRED_VARIABLE2 ...)\n"
- "The first argument (TEST_VARIABLE) is the name of the variable to be "
- "tested, if that variable is false nothing else is done. If "
- "TEST_VARIABLE is true, then "
- "the next argument (RESULT_VARIABLE) is a variable that is set to true "
- "if all the required variables are set. "
- "The rest of the arguments are variables that must be true or not "
- "set to NOTFOUND to avoid an error. If any are not true, an error "
- "is reported.";
- }
-
- /** This command is kept for compatibility with older CMake versions. */
- virtual bool IsDiscouraged() const
- {
- return true;
- }
-
- cmTypeMacro(cmVariableRequiresCommand, cmCommand);
+ virtual std::string GetName() const { return "variable_requires";}
};
diff --git a/Source/cmVariableWatch.cxx b/Source/cmVariableWatch.cxx
index 8ad6fce8f..a20071859 100644
--- a/Source/cmVariableWatch.cxx
+++ b/Source/cmVariableWatch.cxx
@@ -11,12 +11,13 @@
============================================================================*/
#include "cmVariableWatch.h"
+#include "cmAlgorithms.h"
+
static const char* const cmVariableWatchAccessStrings[] =
{
"READ_ACCESS",
"UNKNOWN_READ_ACCESS",
"UNKNOWN_DEFINED_ACCESS",
- "ALLOWED_UNKNOWN_READ_ACCESS",
"MODIFIED_ACCESS",
"REMOVED_ACCESS",
"NO_ACCESS"
@@ -35,21 +36,16 @@ cmVariableWatch::cmVariableWatch()
{
}
-cmVariableWatch::~cmVariableWatch()
+template<typename C>
+void deleteAllSecond(typename C::value_type it)
{
- cmVariableWatch::StringToVectorOfPairs::iterator svp_it;
-
- for ( svp_it = this->WatchMap.begin();
- svp_it != this->WatchMap.end(); ++svp_it )
- {
- cmVariableWatch::VectorOfPairs::iterator p_it;
+ cmDeleteAll(it.second);
+}
- for ( p_it = svp_it->second.begin();
- p_it != svp_it->second.end(); ++p_it )
- {
- delete *p_it;
- }
- }
+cmVariableWatch::~cmVariableWatch()
+{
+ std::for_each(this->WatchMap.begin(), this->WatchMap.end(),
+ deleteAllSecond<cmVariableWatch::StringToVectorOfPairs>);
}
bool cmVariableWatch::AddWatch(const std::string& variable,
@@ -100,7 +96,7 @@ void cmVariableWatch::RemoveWatch(const std::string& variable,
}
}
-void cmVariableWatch::VariableAccessed(const std::string& variable,
+bool cmVariableWatch::VariableAccessed(const std::string& variable,
int access_type,
const char* newValue,
const cmMakefile* mf) const
@@ -116,5 +112,7 @@ void cmVariableWatch::VariableAccessed(const std::string& variable,
(*it)->Method(variable, access_type, (*it)->ClientData,
newValue, mf);
}
+ return true;
}
+ return false;
}
diff --git a/Source/cmVariableWatch.h b/Source/cmVariableWatch.h
index 790c75acc..2f082afe2 100644
--- a/Source/cmVariableWatch.h
+++ b/Source/cmVariableWatch.h
@@ -42,7 +42,7 @@ public:
/**
* This method is called when variable is accessed
*/
- void VariableAccessed(const std::string& variable, int access_type,
+ bool VariableAccessed(const std::string& variable, int access_type,
const char* newValue, const cmMakefile* mf) const;
/**
@@ -53,7 +53,6 @@ public:
VARIABLE_READ_ACCESS = 0,
UNKNOWN_VARIABLE_READ_ACCESS,
UNKNOWN_VARIABLE_DEFINED_ACCESS,
- ALLOWED_UNKNOWN_VARIABLE_READ_ACCESS,
VARIABLE_MODIFIED_ACCESS,
VARIABLE_REMOVED_ACCESS,
NO_ACCESS
@@ -81,7 +80,7 @@ protected:
};
typedef std::vector< Pair* > VectorOfPairs;
- typedef std::map<cmStdString, VectorOfPairs > StringToVectorOfPairs;
+ typedef std::map<std::string, VectorOfPairs > StringToVectorOfPairs;
StringToVectorOfPairs WatchMap;
};
diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx
index 33e159bce..98a397cf2 100644
--- a/Source/cmVariableWatchCommand.cxx
+++ b/Source/cmVariableWatchCommand.cxx
@@ -49,30 +49,26 @@ static void cmVariableWatchCommandVariableAccessed(
newLFF.Arguments.clear();
newLFF.Arguments.push_back(
cmListFileArgument(variable, cmListFileArgument::Quoted,
- "unknown", 9999));
+ 9999));
newLFF.Arguments.push_back(
cmListFileArgument(accessString, cmListFileArgument::Quoted,
- "unknown", 9999));
+ 9999));
newLFF.Arguments.push_back(
cmListFileArgument(newValue?newValue:"", cmListFileArgument::Quoted,
- "unknown", 9999));
+ 9999));
newLFF.Arguments.push_back(
cmListFileArgument(currentListFile, cmListFileArgument::Quoted,
- "unknown", 9999));
+ 9999));
newLFF.Arguments.push_back(
cmListFileArgument(stack, cmListFileArgument::Quoted,
- "unknown", 9999));
+ 9999));
newLFF.Name = data->Command;
- newLFF.FilePath = "Some weird path";
newLFF.Line = 9999;
cmExecutionStatus status;
if(!makefile->ExecuteCommand(newLFF,status))
{
- arg.FilePath = "Unknown";
- arg.Line = 0;
- cmOStringStream error;
- error << "Error in cmake code at\n"
- << arg.FilePath << ":" << arg.Line << ":\n"
+ std::ostringstream error;
+ error << "Error in cmake code at\nUnknown:0:\n"
<< "A command failed during the invocation of callback \""
<< data->Command << "\".";
cmSystemTools::Error(error.str().c_str());
@@ -83,8 +79,8 @@ static void cmVariableWatchCommandVariableAccessed(
}
if ( !processed )
{
- cmOStringStream msg;
- msg << "Variable \"" << variable.c_str() << "\" was accessed using "
+ std::ostringstream msg;
+ msg << "Variable \"" << variable << "\" was accessed using "
<< accessString << " with value \"" << (newValue?newValue:"") << "\".";
makefile->IssueMessage(cmake::LOG, msg.str());
}
@@ -135,9 +131,9 @@ bool cmVariableWatchCommand
}
if ( variable == "CMAKE_CURRENT_LIST_FILE" )
{
- cmOStringStream ostr;
- ostr << "cannot be set on the variable: " << variable.c_str();
- this->SetError(ostr.str().c_str());
+ std::ostringstream ostr;
+ ostr << "cannot be set on the variable: " << variable;
+ this->SetError(ostr.str());
return false;
}
diff --git a/Source/cmVariableWatchCommand.h b/Source/cmVariableWatchCommand.h
index 545535c40..c1ee9b14e 100644
--- a/Source/cmVariableWatchCommand.h
+++ b/Source/cmVariableWatchCommand.h
@@ -54,28 +54,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "variable_watch";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Watch the CMake variable for change.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " variable_watch(<variable name> [<command to execute>])\n"
- "If the specified variable changes, the message will be printed about "
- "the variable being changed. If the command is specified, the command "
- "will be executed. The command will receive the following arguments:"
- " COMMAND(<variable> <access> <value> <current list file> <stack>)";
- }
+ virtual std::string GetName() const { return "variable_watch";}
cmTypeMacro(cmVariableWatchCommand, cmCommand);
diff --git a/Source/cmVersion.cxx b/Source/cmVersion.cxx
index 047d24d74..9cb0cd6a7 100644
--- a/Source/cmVersion.cxx
+++ b/Source/cmVersion.cxx
@@ -16,7 +16,7 @@
unsigned int cmVersion::GetMajorVersion() { return CMake_VERSION_MAJOR; }
unsigned int cmVersion::GetMinorVersion() { return CMake_VERSION_MINOR; }
unsigned int cmVersion::GetPatchVersion() { return CMake_VERSION_PATCH; }
-unsigned int cmVersion::GetTweakVersion() { return CMake_VERSION_TWEAK; }
+unsigned int cmVersion::GetTweakVersion() { return 0; }
const char* cmVersion::GetCMakeVersion()
{
diff --git a/Source/cmVersion.h b/Source/cmVersion.h
index e31352476..84f750f19 100644
--- a/Source/cmVersion.h
+++ b/Source/cmVersion.h
@@ -32,8 +32,13 @@ public:
static const char* GetCMakeVersion();
};
+/* Encode with room for up to 1000 minor releases between major releases
+ and to encode dates until the year 10000 in the patch level. */
+#define CMake_VERSION_ENCODE__BASE KWIML_INT_UINT64_C(100000000)
#define CMake_VERSION_ENCODE(major, minor, patch) \
- ((major)*0x10000u + (minor)*0x100u + (patch))
+ ((((major) * 1000u) * CMake_VERSION_ENCODE__BASE) + \
+ (((minor) % 1000u) * CMake_VERSION_ENCODE__BASE) + \
+ (((patch) % CMake_VERSION_ENCODE__BASE)))
#endif
diff --git a/Source/cmVersionConfig.h.in b/Source/cmVersionConfig.h.in
index 76bc8fe94..16aeabe9e 100644
--- a/Source/cmVersionConfig.h.in
+++ b/Source/cmVersionConfig.h.in
@@ -12,5 +12,4 @@
#define CMake_VERSION_MAJOR @CMake_VERSION_MAJOR@
#define CMake_VERSION_MINOR @CMake_VERSION_MINOR@
#define CMake_VERSION_PATCH @CMake_VERSION_PATCH@
-#define CMake_VERSION_TWEAK @CMake_VERSION_TWEAK@
#define CMake_VERSION "@CMake_VERSION@"
diff --git a/Source/cmVersionMacros.h b/Source/cmVersionMacros.h
index 67f58ca41..cf7f678a7 100644
--- a/Source/cmVersionMacros.h
+++ b/Source/cmVersionMacros.h
@@ -14,8 +14,8 @@
#include "cmVersionConfig.h"
-#define CMake_VERSION_TWEAK_IS_RELEASE(tweak) ((tweak) < 20000000)
-#if CMake_VERSION_TWEAK_IS_RELEASE(CMake_VERSION_TWEAK)
+#define CMake_VERSION_PATCH_IS_RELEASE(patch) ((patch) < 20000000)
+#if CMake_VERSION_PATCH_IS_RELEASE(CMake_VERSION_PATCH)
# define CMake_VERSION_IS_RELEASE 1
#endif
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 6376376a0..da950bea9 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -9,59 +9,128 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
+#include "windows.h"
#include "cmVisualStudio10TargetGenerator.h"
#include "cmGlobalVisualStudio10Generator.h"
#include "cmGeneratorTarget.h"
-#include "cmTarget.h"
#include "cmComputeLinkInformation.h"
#include "cmGeneratedFileStream.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
#include "cmVisualStudioGeneratorOptions.h"
#include "cmLocalVisualStudio7Generator.h"
+#include "cmCustomCommandGenerator.h"
#include "cmVS10CLFlagTable.h"
+#include "cmVS10RCFlagTable.h"
#include "cmVS10LinkFlagTable.h"
#include "cmVS10LibFlagTable.h"
+#include "cmVS10MASMFlagTable.h"
#include "cmVS11CLFlagTable.h"
+#include "cmVS11RCFlagTable.h"
#include "cmVS11LinkFlagTable.h"
#include "cmVS11LibFlagTable.h"
+#include "cmVS11MASMFlagTable.h"
#include "cmVS12CLFlagTable.h"
+#include "cmVS12RCFlagTable.h"
#include "cmVS12LinkFlagTable.h"
#include "cmVS12LibFlagTable.h"
+#include "cmVS12MASMFlagTable.h"
+#include "cmVS14CLFlagTable.h"
+#include "cmVS14RCFlagTable.h"
+#include "cmVS14LinkFlagTable.h"
+#include "cmVS14LibFlagTable.h"
+#include "cmVS14MASMFlagTable.h"
#include <cmsys/auto_ptr.hxx>
-static cmVS7FlagTable const*
-cmVSGetCLFlagTable(cmLocalVisualStudioGenerator* lg)
+cmIDEFlagTable const* cmVisualStudio10TargetGenerator::GetClFlagTable() const
{
- if(lg->GetVersion() >= cmLocalVisualStudioGenerator::VS12)
- { return cmVS12CLFlagTable; }
- else if(lg->GetVersion() == cmLocalVisualStudioGenerator::VS11)
- { return cmVS11CLFlagTable; }
- else
- { return cmVS10CLFlagTable; }
+ if(this->MSTools)
+ {
+ cmGlobalVisualStudioGenerator::VSVersion
+ v = this->LocalGenerator->GetVersion();
+ if(v >= cmGlobalVisualStudioGenerator::VS14)
+ { return cmVS14CLFlagTable; }
+ else if(v >= cmGlobalVisualStudioGenerator::VS12)
+ { return cmVS12CLFlagTable; }
+ else if(v == cmGlobalVisualStudioGenerator::VS11)
+ { return cmVS11CLFlagTable; }
+ else
+ { return cmVS10CLFlagTable; }
+ }
+ return 0;
}
-static cmVS7FlagTable const*
-cmVSGetLibFlagTable(cmLocalVisualStudioGenerator* lg)
+cmIDEFlagTable const* cmVisualStudio10TargetGenerator::GetRcFlagTable() const
{
- if(lg->GetVersion() >= cmLocalVisualStudioGenerator::VS12)
- { return cmVS12LibFlagTable; }
- else if(lg->GetVersion() == cmLocalVisualStudioGenerator::VS11)
- { return cmVS11LibFlagTable; }
- else
- { return cmVS10LibFlagTable; }
+ if(this->MSTools)
+ {
+ cmGlobalVisualStudioGenerator::VSVersion
+ v = this->LocalGenerator->GetVersion();
+ if(v >= cmGlobalVisualStudioGenerator::VS14)
+ { return cmVS14RCFlagTable; }
+ else if(v >= cmGlobalVisualStudioGenerator::VS12)
+ { return cmVS12RCFlagTable; }
+ else if(v == cmGlobalVisualStudioGenerator::VS11)
+ { return cmVS11RCFlagTable; }
+ else
+ { return cmVS10RCFlagTable; }
+ }
+ return 0;
}
-static cmVS7FlagTable const*
-cmVSGetLinkFlagTable(cmLocalVisualStudioGenerator* lg)
+cmIDEFlagTable const* cmVisualStudio10TargetGenerator::GetLibFlagTable() const
{
- if(lg->GetVersion() >= cmLocalVisualStudioGenerator::VS12)
- { return cmVS12LinkFlagTable; }
- else if(lg->GetVersion() == cmLocalVisualStudioGenerator::VS11)
- { return cmVS11LinkFlagTable; }
- else
- { return cmVS10LinkFlagTable; }
+ if(this->MSTools)
+ {
+ cmGlobalVisualStudioGenerator::VSVersion
+ v = this->LocalGenerator->GetVersion();
+ if(v >= cmGlobalVisualStudioGenerator::VS14)
+ { return cmVS14LibFlagTable; }
+ else if(v >= cmGlobalVisualStudioGenerator::VS12)
+ { return cmVS12LibFlagTable; }
+ else if(v == cmGlobalVisualStudioGenerator::VS11)
+ { return cmVS11LibFlagTable; }
+ else
+ { return cmVS10LibFlagTable; }
+ }
+ return 0;
+}
+
+cmIDEFlagTable const* cmVisualStudio10TargetGenerator::GetLinkFlagTable() const
+{
+ if(this->MSTools)
+ {
+ cmGlobalVisualStudioGenerator::VSVersion
+ v = this->LocalGenerator->GetVersion();
+ if(v >= cmGlobalVisualStudioGenerator::VS14)
+ { return cmVS14LinkFlagTable; }
+ else if(v >= cmGlobalVisualStudioGenerator::VS12)
+ { return cmVS12LinkFlagTable; }
+ else if(v == cmGlobalVisualStudioGenerator::VS11)
+ { return cmVS11LinkFlagTable; }
+ else
+ { return cmVS10LinkFlagTable; }
+ }
+ return 0;
+}
+
+cmIDEFlagTable const* cmVisualStudio10TargetGenerator::GetMasmFlagTable() const
+{
+ if(this->MSTools)
+ {
+ cmGlobalVisualStudioGenerator::VSVersion
+ v = this->LocalGenerator->GetVersion();
+ if(v >= cmGlobalVisualStudioGenerator::VS14)
+ { return cmVS14MASMFlagTable; }
+ else if(v >= cmGlobalVisualStudioGenerator::VS12)
+ { return cmVS12MASMFlagTable; }
+ else if(v == cmGlobalVisualStudioGenerator::VS11)
+ { return cmVS11MASMFlagTable; }
+ else
+ { return cmVS10MASMFlagTable; }
+ }
+ return 0;
}
static std::string cmVS10EscapeXML(std::string arg)
@@ -97,21 +166,35 @@ static std::string cmVS10EscapeComment(std::string comment)
}
cmVisualStudio10TargetGenerator::
-cmVisualStudio10TargetGenerator(cmTarget* target,
+cmVisualStudio10TargetGenerator(cmGeneratorTarget* target,
cmGlobalVisualStudio10Generator* gg)
{
this->GlobalGenerator = gg;
- this->Target = target;
- this->GeneratorTarget = gg->GetGeneratorTarget(target);
- this->Makefile = target->GetMakefile();
+ this->GeneratorTarget = target;
+ this->Makefile = target->Target->GetMakefile();
+ this->Makefile->GetConfigurations(this->Configurations);
this->LocalGenerator =
(cmLocalVisualStudio7Generator*)
- this->Makefile->GetLocalGenerator();
- this->Name = this->Target->GetName();
- this->GlobalGenerator->CreateGUID(this->Name.c_str());
+ this->GeneratorTarget->GetLocalGenerator();
+ this->Name = this->GeneratorTarget->GetName();
this->GUID = this->GlobalGenerator->GetGUID(this->Name.c_str());
this->Platform = gg->GetPlatformName();
+ this->NsightTegra = gg->IsNsightTegra();
+ for(int i =
+ sscanf(gg->GetNsightTegraVersion().c_str(), "%u.%u.%u.%u",
+ &this->NsightTegraVersion[0], &this->NsightTegraVersion[1],
+ &this->NsightTegraVersion[2], &this->NsightTegraVersion[3]);
+ i < 4; ++i)
+ {
+ this->NsightTegraVersion[i] = 0;
+ }
+ this->MSTools = !this->NsightTegra;
+ this->TargetCompileAsWinRT = false;
this->BuildFileStream = 0;
+ this->IsMissingFiles = false;
+ this->DefaultArtifactDir =
+ this->LocalGenerator->GetCurrentBinaryDirectory() + std::string("/") +
+ this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
}
cmVisualStudio10TargetGenerator::~cmVisualStudio10TargetGenerator()
@@ -140,7 +223,7 @@ cmVisualStudio10TargetGenerator::~cmVisualStudio10TargetGenerator()
void cmVisualStudio10TargetGenerator::WritePlatformConfigTag(
const char* tag,
- const char* config,
+ const std::string& config,
int indentLevel,
const char* attribute,
const char* end,
@@ -184,27 +267,36 @@ void cmVisualStudio10TargetGenerator::WriteString(const char* line,
void cmVisualStudio10TargetGenerator::Generate()
{
// do not generate external ms projects
- if(this->Target->GetProperty("EXTERNAL_MSPROJECT"))
+ if(this->GeneratorTarget->GetType() == cmState::INTERFACE_LIBRARY
+ || this->GeneratorTarget->GetProperty("EXTERNAL_MSPROJECT"))
{
return;
}
// Tell the global generator the name of the project file
- this->Target->SetProperty("GENERATOR_FILE_NAME",this->Name.c_str());
- this->Target->SetProperty("GENERATOR_FILE_NAME_EXT",
+ this->GeneratorTarget->Target
+ ->SetProperty("GENERATOR_FILE_NAME",this->Name.c_str());
+ this->GeneratorTarget->Target->SetProperty("GENERATOR_FILE_NAME_EXT",
".vcxproj");
- if(this->Target->GetType() <= cmTarget::OBJECT_LIBRARY)
+ if(this->GeneratorTarget->GetType() <= cmState::OBJECT_LIBRARY)
{
if(!this->ComputeClOptions())
{
return;
}
+ if(!this->ComputeRcOptions())
+ {
+ return;
+ }
+ if(!this->ComputeMasmOptions())
+ {
+ return;
+ }
if(!this->ComputeLinkOptions())
{
return;
}
}
- cmMakefile* mf = this->Target->GetMakefile();
- std::string path = mf->GetStartOutputDirectory();
+ std::string path = this->LocalGenerator->GetCurrentBinaryDirectory();
path += "/";
path += this->Name;
path += ".vcxproj";
@@ -214,25 +306,68 @@ void cmVisualStudio10TargetGenerator::Generate()
this->BuildFileStream->SetCopyIfDifferent(true);
// Write the encoding header into the file
- char magic[] = {0xEF,0xBB, 0xBF};
+ char magic[] = {char(0xEF), char(0xBB), char(0xBF)};
this->BuildFileStream->write(magic, 3);
//get the tools version to use
const std::string toolsVer(this->GlobalGenerator->GetToolsVersion());
- std::string project_defaults="<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
+ std::string project_defaults=
+ "<?xml version=\"1.0\" encoding=\"" +
+ this->GlobalGenerator->Encoding() + "\"?>\n";
project_defaults.append("<Project DefaultTargets=\"Build\" ToolsVersion=\"");
project_defaults.append(toolsVer +"\" ");
project_defaults.append(
"xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n");
this->WriteString(project_defaults.c_str(),0);
+ if(this->NsightTegra)
+ {
+ this->WriteString("<PropertyGroup Label=\"NsightTegraProject\">\n", 1);
+ const int nsightTegraMajorVersion = this->NsightTegraVersion[0];
+ const int nsightTegraMinorVersion = this->NsightTegraVersion[1];
+ if (nsightTegraMajorVersion >= 2)
+ {
+ this->WriteString("<NsightTegraProjectRevisionNumber>", 2);
+ if (nsightTegraMajorVersion > 3 ||
+ (nsightTegraMajorVersion == 3 && nsightTegraMinorVersion >= 1))
+ {
+ (*this->BuildFileStream) << "11";
+ }
+ else
+ {
+ // Nsight Tegra 2.0 uses project revision 9.
+ (*this->BuildFileStream) << "9";
+ }
+ (*this->BuildFileStream) << "</NsightTegraProjectRevisionNumber>\n";
+ // Tell newer versions to upgrade silently when loading.
+ this->WriteString("<NsightTegraUpgradeOnceWithoutPrompt>"
+ "true"
+ "</NsightTegraUpgradeOnceWithoutPrompt>\n", 2);
+ }
+ else
+ {
+ // Require Nsight Tegra 1.6 for JCompile support.
+ this->WriteString("<NsightTegraProjectRevisionNumber>"
+ "7"
+ "</NsightTegraProjectRevisionNumber>\n", 2);
+ }
+ this->WriteString("</PropertyGroup>\n", 1);
+ }
+
this->WriteProjectConfigurations();
this->WriteString("<PropertyGroup Label=\"Globals\">\n", 1);
this->WriteString("<ProjectGUID>", 2);
(*this->BuildFileStream) << "{" << this->GUID << "}</ProjectGUID>\n";
+ if(this->MSTools
+ && this->GeneratorTarget->GetType() <= cmState::GLOBAL_TARGET)
+ {
+ this->WriteApplicationTypeSettings();
+ this->VerifyNecessaryFiles();
+ }
+
const char* vsProjectTypes =
- this->Target->GetProperty("VS_GLOBAL_PROJECT_TYPES");
+ this->GeneratorTarget->GetProperty("VS_GLOBAL_PROJECT_TYPES");
if(vsProjectTypes)
{
this->WriteString("<ProjectTypes>", 2);
@@ -240,9 +375,12 @@ void cmVisualStudio10TargetGenerator::Generate()
"</ProjectTypes>\n";
}
- const char* vsProjectName = this->Target->GetProperty("VS_SCC_PROJECTNAME");
- const char* vsLocalPath = this->Target->GetProperty("VS_SCC_LOCALPATH");
- const char* vsProvider = this->Target->GetProperty("VS_SCC_PROVIDER");
+ const char* vsProjectName =
+ this->GeneratorTarget->GetProperty("VS_SCC_PROJECTNAME");
+ const char* vsLocalPath =
+ this->GeneratorTarget->GetProperty("VS_SCC_LOCALPATH");
+ const char* vsProvider =
+ this->GeneratorTarget->GetProperty("VS_SCC_PROVIDER");
if( vsProjectName && vsLocalPath && vsProvider )
{
@@ -256,7 +394,8 @@ void cmVisualStudio10TargetGenerator::Generate()
(*this->BuildFileStream) << cmVS10EscapeXML(vsProvider) <<
"</SccProvider>\n";
- const char* vsAuxPath = this->Target->GetProperty("VS_SCC_AUXPATH");
+ const char* vsAuxPath =
+ this->GeneratorTarget->GetProperty("VS_SCC_AUXPATH");
if( vsAuxPath )
{
this->WriteString("<SccAuxPath>", 2);
@@ -265,8 +404,13 @@ void cmVisualStudio10TargetGenerator::Generate()
}
}
+ if(this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_COMPONENT"))
+ {
+ this->WriteString("<WinMDAssembly>true</WinMDAssembly>\n", 2);
+ }
+
const char* vsGlobalKeyword =
- this->Target->GetProperty("VS_GLOBAL_KEYWORD");
+ this->GeneratorTarget->GetProperty("VS_GLOBAL_KEYWORD");
if(!vsGlobalKeyword)
{
this->WriteString("<Keyword>Win32Proj</Keyword>\n", 2);
@@ -279,7 +423,7 @@ void cmVisualStudio10TargetGenerator::Generate()
}
const char* vsGlobalRootNamespace =
- this->Target->GetProperty("VS_GLOBAL_ROOTNAMESPACE");
+ this->GeneratorTarget->GetProperty("VS_GLOBAL_ROOTNAMESPACE");
if(vsGlobalRootNamespace)
{
this->WriteString("<RootNamespace>", 2);
@@ -288,21 +432,48 @@ void cmVisualStudio10TargetGenerator::Generate()
}
this->WriteString("<Platform>", 2);
- (*this->BuildFileStream) << this->Platform << "</Platform>\n";
- const char* projLabel = this->Target->GetProperty("PROJECT_LABEL");
+ (*this->BuildFileStream) << cmVS10EscapeXML(this->Platform)
+ << "</Platform>\n";
+ const char* projLabel = this->GeneratorTarget->GetProperty("PROJECT_LABEL");
if(!projLabel)
{
projLabel = this->Name.c_str();
}
this->WriteString("<ProjectName>", 2);
- (*this->BuildFileStream) << projLabel << "</ProjectName>\n";
- if(const char* targetFrameworkVersion = this->Target->GetProperty(
+ (*this->BuildFileStream) << cmVS10EscapeXML(projLabel) << "</ProjectName>\n";
+ if(const char* targetFrameworkVersion = this->GeneratorTarget->GetProperty(
"VS_DOTNET_TARGET_FRAMEWORK_VERSION"))
{
this->WriteString("<TargetFrameworkVersion>", 2);
- (*this->BuildFileStream) << targetFrameworkVersion
+ (*this->BuildFileStream) << cmVS10EscapeXML(targetFrameworkVersion)
<< "</TargetFrameworkVersion>\n";
}
+
+ std::vector<std::string> keys = this->GeneratorTarget->GetPropertyKeys();
+ for(std::vector<std::string>::const_iterator keyIt = keys.begin();
+ keyIt != keys.end(); ++keyIt)
+ {
+ static const char* prefix = "VS_GLOBAL_";
+ if(keyIt->find(prefix) != 0)
+ continue;
+ std::string globalKey = keyIt->substr(strlen(prefix));
+ // Skip invalid or separately-handled properties.
+ if(globalKey == "" ||
+ globalKey == "PROJECT_TYPES" ||
+ globalKey == "ROOTNAMESPACE" ||
+ globalKey == "KEYWORD")
+ {
+ continue;
+ }
+ const char* value = this->GeneratorTarget->GetProperty(keyIt->c_str());
+ if (!value)
+ continue;
+ this->WriteString("<", 2);
+ (*this->BuildFileStream) << globalKey << ">"
+ << cmVS10EscapeXML(value)
+ << "</" << globalKey << ">\n";
+ }
+
this->WriteString("</PropertyGroup>\n", 1);
this->WriteString("<Import Project="
"\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n",
@@ -320,20 +491,25 @@ void cmVisualStudio10TargetGenerator::Generate()
this->WriteString("<ImportGroup Label=\"PropertySheets\">\n", 1);
this->WriteString("<Import Project=\"" VS10_USER_PROPS "\""
" Condition=\"exists('" VS10_USER_PROPS "')\""
- " Label=\"LocalAppDataPlatform\" />", 2);
+ " Label=\"LocalAppDataPlatform\" />\n", 2);
+ this->WritePlatformExtensions();
this->WriteString("</ImportGroup>\n", 1);
this->WriteString("<PropertyGroup Label=\"UserMacros\" />\n", 1);
+ this->WriteWinRTPackageCertificateKeyFile();
this->WritePathAndIncrementalLinkOptions();
this->WriteItemDefinitionGroups();
this->WriteCustomCommands();
this->WriteAllSources();
this->WriteDotNetReferences();
this->WriteEmbeddedResourceGroup();
+ this->WriteXamlFilesGroup();
this->WriteWinRTReferences();
this->WriteProjectReferences();
+ this->WriteSDKReferences();
this->WriteString(
"<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\""
" />\n", 1);
+ this->WriteTargetSpecificReferences();
this->WriteString("<ImportGroup Label=\"ExtensionTargets\">\n", 1);
if (this->GlobalGenerator->IsMasmEnabled())
{
@@ -350,7 +526,7 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReferences()
{
std::vector<std::string> references;
if(const char* vsDotNetReferences =
- this->Target->GetProperty("VS_DOTNET_REFERENCES"))
+ this->GeneratorTarget->GetProperty("VS_DOTNET_REFERENCES"))
{
cmSystemTools::ExpandListArgument(vsDotNetReferences, references);
}
@@ -374,12 +550,12 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReferences()
void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup()
{
- std::vector<cmSourceFile*> const& resxObjs =
- this->GeneratorTarget->ResxSources;
+ std::vector<cmSourceFile const*> resxObjs;
+ this->GeneratorTarget->GetResxSources(resxObjs, "");
if(!resxObjs.empty())
{
this->WriteString("<ItemGroup>\n", 1);
- for(std::vector<cmSourceFile*>::const_iterator oi = resxObjs.begin();
+ for(std::vector<cmSourceFile const*>::const_iterator oi = resxObjs.begin();
oi != resxObjs.end(); ++oi)
{
std::string obj = (*oi)->GetFullPath();
@@ -389,16 +565,14 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup()
this->WriteString("<DependentUpon>", 3);
std::string hFileName = obj.substr(0, obj.find_last_of(".")) + ".h";
- (*this->BuildFileStream ) << hFileName;
- this->WriteString("</DependentUpon>\n", 3);
+ (*this->BuildFileStream) << hFileName << "</DependentUpon>\n";
- std::vector<std::string> const * configs =
- this->GlobalGenerator->GetConfigurations();
- for(std::vector<std::string>::const_iterator i = configs->begin();
- i != configs->end(); ++i)
+ for(std::vector<std::string>::const_iterator
+ i = this->Configurations.begin();
+ i != this->Configurations.end(); ++i)
{
this->WritePlatformConfigTag("LogicalName", i->c_str(), 3);
- if(this->Target->GetProperty("VS_GLOBAL_ROOTNAMESPACE"))
+ if(this->GeneratorTarget->GetProperty("VS_GLOBAL_ROOTNAMESPACE"))
{
(*this->BuildFileStream ) << "$(RootNamespace).";
}
@@ -413,14 +587,69 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup()
}
}
+void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup()
+{
+ std::vector<cmSourceFile const*> xamlObjs;
+ this->GeneratorTarget->GetXamlSources(xamlObjs, "");
+ if (!xamlObjs.empty())
+ {
+ this->WriteString("<ItemGroup>\n", 1);
+ for (std::vector<cmSourceFile const*>::const_iterator
+ oi = xamlObjs.begin(); oi != xamlObjs.end(); ++oi)
+ {
+ std::string obj = (*oi)->GetFullPath();
+ std::string xamlType;
+ const char * xamlTypeProperty = (*oi)->GetProperty("VS_XAML_TYPE");
+ if (xamlTypeProperty)
+ {
+ xamlType = xamlTypeProperty;
+ }
+ else
+ {
+ xamlType = "Page";
+ }
+
+ this->WriteSource(xamlType, *oi, ">\n");
+ this->WriteString("<SubType>Designer</SubType>\n", 3);
+ this->WriteString("</", 2);
+ (*this->BuildFileStream) << xamlType << ">\n";
+
+ }
+ this->WriteString("</ItemGroup>\n", 1);
+ }
+}
+
+void cmVisualStudio10TargetGenerator::WriteTargetSpecificReferences()
+{
+ if(this->MSTools)
+ {
+ if(this->GlobalGenerator->TargetsWindowsPhone() &&
+ this->GlobalGenerator->GetSystemVersion() == "8.0")
+ {
+ this->WriteString(
+ "<Import Project=\""
+ "$(MSBuildExtensionsPath)\\Microsoft\\WindowsPhone\\v"
+ "$(TargetPlatformVersion)\\Microsoft.Cpp.WindowsPhone."
+ "$(TargetPlatformVersion).targets\" />\n", 1);
+ }
+ }
+}
+
void cmVisualStudio10TargetGenerator::WriteWinRTReferences()
{
std::vector<std::string> references;
if(const char* vsWinRTReferences =
- this->Target->GetProperty("VS_WINRT_REFERENCES"))
+ this->GeneratorTarget->GetProperty("VS_WINRT_REFERENCES"))
{
cmSystemTools::ExpandListArgument(vsWinRTReferences, references);
}
+
+ if(this->GlobalGenerator->TargetsWindowsPhone() &&
+ this->GlobalGenerator->GetSystemVersion() == "8.0" &&
+ references.empty())
+ {
+ references.push_back("platform.winmd");
+ }
if(!references.empty())
{
this->WriteString("<ItemGroup>\n", 1);
@@ -441,18 +670,17 @@ void cmVisualStudio10TargetGenerator::WriteWinRTReferences()
void cmVisualStudio10TargetGenerator::WriteProjectConfigurations()
{
this->WriteString("<ItemGroup Label=\"ProjectConfigurations\">\n", 1);
- std::vector<std::string> *configs =
- static_cast<cmGlobalVisualStudio7Generator *>
- (this->GlobalGenerator)->GetConfigurations();
- for(std::vector<std::string>::iterator i = configs->begin();
- i != configs->end(); ++i)
+ for(std::vector<std::string>::const_iterator
+ i = this->Configurations.begin();
+ i != this->Configurations.end(); ++i)
{
this->WriteString("<ProjectConfiguration Include=\"", 2);
(*this->BuildFileStream ) << *i << "|" << this->Platform << "\">\n";
this->WriteString("<Configuration>", 3);
(*this->BuildFileStream ) << *i << "</Configuration>\n";
this->WriteString("<Platform>", 3);
- (*this->BuildFileStream) << this->Platform << "</Platform>\n";
+ (*this->BuildFileStream) << cmVS10EscapeXML(this->Platform)
+ << "</Platform>\n";
this->WriteString("</ProjectConfiguration>\n", 2);
}
this->WriteString("</ItemGroup>\n", 1);
@@ -460,46 +688,82 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurations()
void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues()
{
- cmGlobalVisualStudio10Generator* gg =
- static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator);
- std::vector<std::string> *configs =
- static_cast<cmGlobalVisualStudio7Generator *>
- (this->GlobalGenerator)->GetConfigurations();
- for(std::vector<std::string>::iterator i = configs->begin();
- i != configs->end(); ++i)
+ for(std::vector<std::string>::const_iterator
+ i = this->Configurations.begin();
+ i != this->Configurations.end(); ++i)
{
this->WritePlatformConfigTag("PropertyGroup",
i->c_str(),
1, " Label=\"Configuration\"", "\n");
std::string configType = "<ConfigurationType>";
- switch(this->Target->GetType())
+ switch(this->GeneratorTarget->GetType())
{
- case cmTarget::SHARED_LIBRARY:
- case cmTarget::MODULE_LIBRARY:
+ case cmState::SHARED_LIBRARY:
+ case cmState::MODULE_LIBRARY:
configType += "DynamicLibrary";
break;
- case cmTarget::OBJECT_LIBRARY:
- case cmTarget::STATIC_LIBRARY:
+ case cmState::OBJECT_LIBRARY:
+ case cmState::STATIC_LIBRARY:
configType += "StaticLibrary";
break;
- case cmTarget::EXECUTABLE:
- configType += "Application";
+ case cmState::EXECUTABLE:
+ if(this->NsightTegra &&
+ !this->GeneratorTarget->GetPropertyAsBool("ANDROID_GUI"))
+ {
+ // Android executables are .so too.
+ configType += "DynamicLibrary";
+ }
+ else
+ {
+ configType += "Application";
+ }
break;
- case cmTarget::UTILITY:
- configType += "Utility";
+ case cmState::UTILITY:
+ case cmState::GLOBAL_TARGET:
+ if(this->NsightTegra)
+ {
+ // Tegra-Android platform does not understand "Utility".
+ configType += "StaticLibrary";
+ }
+ else
+ {
+ configType += "Utility";
+ }
break;
- case cmTarget::GLOBAL_TARGET:
- case cmTarget::UNKNOWN_LIBRARY:
+ case cmState::UNKNOWN_LIBRARY:
+ case cmState::INTERFACE_LIBRARY:
break;
}
configType += "</ConfigurationType>\n";
this->WriteString(configType.c_str(), 2);
- const char* mfcFlag =
- this->Target->GetMakefile()->GetDefinition("CMAKE_MFC_FLAG");
- std::string mfcFlagValue = mfcFlag ? mfcFlag : "0";
+ if(this->MSTools)
+ {
+ this->WriteMSToolConfigurationValues(*i);
+ }
+ else if(this->NsightTegra)
+ {
+ this->WriteNsightTegraConfigurationValues(*i);
+ }
- std::string useOfMfcValue = "false";
+ this->WriteString("</PropertyGroup>\n", 1);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmVisualStudio10TargetGenerator
+::WriteMSToolConfigurationValues(std::string const& config)
+{
+ cmGlobalVisualStudio10Generator* gg =
+ static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator);
+ const char* mfcFlag =
+ this->GeneratorTarget->
+ Target->GetMakefile()->GetDefinition("CMAKE_MFC_FLAG");
+ std::string mfcFlagValue = mfcFlag ? mfcFlag : "0";
+
+ std::string useOfMfcValue = "false";
+ if(this->GeneratorTarget->GetType() <= cmState::OBJECT_LIBRARY)
+ {
if(mfcFlagValue == "1")
{
useOfMfcValue = "Static";
@@ -508,60 +772,106 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues()
{
useOfMfcValue = "Dynamic";
}
- std::string mfcLine = "<UseOfMfc>";
- mfcLine += useOfMfcValue + "</UseOfMfc>\n";
- this->WriteString(mfcLine.c_str(), 2);
+ }
+ std::string mfcLine = "<UseOfMfc>";
+ mfcLine += useOfMfcValue + "</UseOfMfc>\n";
+ this->WriteString(mfcLine.c_str(), 2);
- if((this->Target->GetType() <= cmTarget::OBJECT_LIBRARY &&
- this->ClOptions[*i]->UsingUnicode()) ||
- this->Target->GetPropertyAsBool("VS_WINRT_EXTENSIONS"))
- {
- this->WriteString("<CharacterSet>Unicode</CharacterSet>\n", 2);
- }
- else if (this->Target->GetType() <= cmTarget::MODULE_LIBRARY &&
- this->ClOptions[*i]->UsingSBCS())
- {
- this->WriteString("<CharacterSet>NotSet</CharacterSet>\n", 2);
- }
- else
- {
- this->WriteString("<CharacterSet>MultiByte</CharacterSet>\n", 2);
- }
- if(const char* toolset = gg->GetPlatformToolset())
- {
- std::string pts = "<PlatformToolset>";
- pts += toolset;
- pts += "</PlatformToolset>\n";
- this->WriteString(pts.c_str(), 2);
- }
- if(this->Target->GetPropertyAsBool("VS_WINRT_EXTENSIONS"))
- {
- this->WriteString("<WindowsAppContainer>true"
- "</WindowsAppContainer>\n", 2);
- }
+ if((this->GeneratorTarget->GetType() <= cmState::OBJECT_LIBRARY &&
+ this->ClOptions[config]->UsingUnicode()) ||
+ this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_COMPONENT") ||
+ this->GlobalGenerator->TargetsWindowsPhone() ||
+ this->GlobalGenerator->TargetsWindowsStore() ||
+ this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_EXTENSIONS"))
+ {
+ this->WriteString("<CharacterSet>Unicode</CharacterSet>\n", 2);
+ }
+ else if (this->GeneratorTarget->GetType() <= cmState::MODULE_LIBRARY &&
+ this->ClOptions[config]->UsingSBCS())
+ {
+ this->WriteString("<CharacterSet>NotSet</CharacterSet>\n", 2);
+ }
+ else
+ {
+ this->WriteString("<CharacterSet>MultiByte</CharacterSet>\n", 2);
+ }
+ if(const char* toolset = gg->GetPlatformToolset())
+ {
+ std::string pts = "<PlatformToolset>";
+ pts += toolset;
+ pts += "</PlatformToolset>\n";
+ this->WriteString(pts.c_str(), 2);
+ }
+ if(this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_COMPONENT") ||
+ this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_EXTENSIONS"))
+ {
+ this->WriteString("<WindowsAppContainer>true"
+ "</WindowsAppContainer>\n", 2);
+ }
+}
- this->WriteString("</PropertyGroup>\n", 1);
+//----------------------------------------------------------------------------
+void cmVisualStudio10TargetGenerator
+::WriteNsightTegraConfigurationValues(std::string const&)
+{
+ cmGlobalVisualStudio10Generator* gg =
+ static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator);
+ const char* toolset = gg->GetPlatformToolset();
+ std::string ntv = "<NdkToolchainVersion>";
+ ntv += toolset? toolset : "Default";
+ ntv += "</NdkToolchainVersion>\n";
+ this->WriteString(ntv.c_str(), 2);
+ if(const char* minApi =
+ this->GeneratorTarget->GetProperty("ANDROID_API_MIN"))
+ {
+ this->WriteString("<AndroidMinAPI>", 2);
+ (*this->BuildFileStream ) <<
+ "android-" << cmVS10EscapeXML(minApi) << "</AndroidMinAPI>\n";
+ }
+ if(const char* api = this->GeneratorTarget->GetProperty("ANDROID_API"))
+ {
+ this->WriteString("<AndroidTargetAPI>", 2);
+ (*this->BuildFileStream ) <<
+ "android-" << cmVS10EscapeXML(api) << "</AndroidTargetAPI>\n";
+ }
+
+ if(const char* cpuArch = this->GeneratorTarget->GetProperty("ANDROID_ARCH"))
+ {
+ this->WriteString("<AndroidArch>", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(cpuArch) <<
+ "</AndroidArch>\n";
+ }
+
+ if(const char* stlType =
+ this->GeneratorTarget->GetProperty("ANDROID_STL_TYPE"))
+ {
+ this->WriteString("<AndroidStlType>", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(stlType) <<
+ "</AndroidStlType>\n";
}
}
void cmVisualStudio10TargetGenerator::WriteCustomCommands()
{
this->SourcesVisited.clear();
- for(std::vector<cmSourceFile*>::const_iterator
- si = this->GeneratorTarget->CustomCommands.begin();
- si != this->GeneratorTarget->CustomCommands.end(); ++si)
+ std::vector<cmSourceFile const*> customCommands;
+ this->GeneratorTarget->GetCustomCommands(customCommands, "");
+ for(std::vector<cmSourceFile const*>::const_iterator
+ si = customCommands.begin();
+ si != customCommands.end(); ++si)
{
this->WriteCustomCommand(*si);
}
}
//----------------------------------------------------------------------------
-void cmVisualStudio10TargetGenerator::WriteCustomCommand(cmSourceFile* sf)
+void cmVisualStudio10TargetGenerator
+::WriteCustomCommand(cmSourceFile const* sf)
{
if(this->SourcesVisited.insert(sf).second)
{
if(std::vector<cmSourceFile*> const* depends =
- this->Target->GetSourceDepends(sf))
+ this->GeneratorTarget->GetSourceDepends(sf))
{
for(std::vector<cmSourceFile*>::const_iterator di = depends->begin();
di != depends->end(); ++di)
@@ -579,7 +889,7 @@ void cmVisualStudio10TargetGenerator::WriteCustomCommand(cmSourceFile* sf)
}
void
-cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile* source,
+cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile const* source,
cmCustomCommand const &
command)
{
@@ -593,12 +903,15 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile* source,
// Make sure the path exists for the file
std::string path = cmSystemTools::GetFilenamePath(sourcePath);
cmSystemTools::MakeDirectory(path.c_str());
- std::ofstream fout(sourcePath.c_str());
+ cmsys::ofstream fout(sourcePath.c_str());
if(fout)
{
fout << "# generated from CMake\n";
fout.flush();
fout.close();
+ // Force given file to have a very old timestamp, thus
+ // preventing dependent rebuilds.
+ this->ForceOld(sourcePath);
}
else
{
@@ -611,53 +924,53 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile* source,
}
}
cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
- std::string comment = lg->ConstructComment(command);
- comment = cmVS10EscapeComment(comment);
- std::vector<std::string> *configs =
- static_cast<cmGlobalVisualStudio7Generator *>
- (this->GlobalGenerator)->GetConfigurations();
this->WriteSource("CustomBuild", source, ">\n");
- for(std::vector<std::string>::iterator i = configs->begin();
- i != configs->end(); ++i)
+ for(std::vector<std::string>::const_iterator
+ i = this->Configurations.begin();
+ i != this->Configurations.end(); ++i)
{
+ cmCustomCommandGenerator ccg(command, *i, this->LocalGenerator);
+ std::string comment = lg->ConstructComment(ccg);
+ comment = cmVS10EscapeComment(comment);
std::string script =
- cmVS10EscapeXML(lg->ConstructScript(command, i->c_str()));
+ cmVS10EscapeXML(lg->ConstructScript(ccg));
this->WritePlatformConfigTag("Message",i->c_str(), 3);
(*this->BuildFileStream ) << cmVS10EscapeXML(comment) << "</Message>\n";
this->WritePlatformConfigTag("Command", i->c_str(), 3);
(*this->BuildFileStream ) << script << "</Command>\n";
this->WritePlatformConfigTag("AdditionalInputs", i->c_str(), 3);
- (*this->BuildFileStream ) << source->GetFullPath();
+ (*this->BuildFileStream ) << cmVS10EscapeXML(source->GetFullPath());
for(std::vector<std::string>::const_iterator d =
- command.GetDepends().begin();
- d != command.GetDepends().end();
+ ccg.GetDepends().begin();
+ d != ccg.GetDepends().end();
++d)
{
std::string dep;
if(this->LocalGenerator->GetRealDependency(d->c_str(), i->c_str(), dep))
{
this->ConvertToWindowsSlash(dep);
- (*this->BuildFileStream ) << ";" << dep;
+ (*this->BuildFileStream ) << ";" << cmVS10EscapeXML(dep);
}
}
(*this->BuildFileStream ) << ";%(AdditionalInputs)</AdditionalInputs>\n";
this->WritePlatformConfigTag("Outputs", i->c_str(), 3);
const char* sep = "";
for(std::vector<std::string>::const_iterator o =
- command.GetOutputs().begin();
- o != command.GetOutputs().end();
+ ccg.GetOutputs().begin();
+ o != ccg.GetOutputs().end();
++o)
{
std::string out = *o;
this->ConvertToWindowsSlash(out);
- (*this->BuildFileStream ) << sep << out;
+ (*this->BuildFileStream ) << sep << cmVS10EscapeXML(out);
sep = ";";
}
(*this->BuildFileStream ) << "</Outputs>\n";
- if(this->LocalGenerator->GetVersion() > cmLocalVisualStudioGenerator::VS10)
+ if(this->LocalGenerator->GetVersion()
+ > cmGlobalVisualStudioGenerator::VS10)
{
// VS >= 11 let us turn off linking of custom command outputs.
this->WritePlatformConfigTag("LinkObjects", i->c_str(), 3);
@@ -673,10 +986,8 @@ cmVisualStudio10TargetGenerator::ConvertPath(std::string const& path,
{
return forceRelative
? cmSystemTools::RelativePath(
- this->Makefile->GetCurrentOutputDirectory(), path.c_str())
- : this->LocalGenerator->Convert(path.c_str(),
- cmLocalGenerator::START_OUTPUT,
- cmLocalGenerator::UNCHANGED);
+ this->LocalGenerator->GetCurrentBinaryDirectory(), path.c_str())
+ : path.c_str();
}
void cmVisualStudio10TargetGenerator::ConvertToWindowsSlash(std::string& s)
@@ -694,7 +1005,11 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
// collect up group information
std::vector<cmSourceGroup> sourceGroups =
this->Makefile->GetSourceGroups();
- std::vector<cmSourceFile*> classes = this->Target->GetSourceFiles();
+ std::vector<cmSourceFile*> classes;
+ if (!this->GeneratorTarget->GetConfigCommonSourceFiles(classes))
+ {
+ return;
+ }
std::set<cmSourceGroup*> groupsUsed;
for(std::vector<cmSourceFile*>::const_iterator s = classes.begin();
@@ -702,28 +1017,30 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
{
cmSourceFile* sf = *s;
std::string const& source = sf->GetFullPath();
- cmSourceGroup& sourceGroup =
+ cmSourceGroup* sourceGroup =
this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
- groupsUsed.insert(&sourceGroup);
+ groupsUsed.insert(sourceGroup);
}
this->AddMissingSourceGroups(groupsUsed, sourceGroups);
// Write out group file
- std::string path = this->Makefile->GetStartOutputDirectory();
+ std::string path = this->LocalGenerator->GetCurrentBinaryDirectory();
path += "/";
path += this->Name;
path += ".vcxproj.filters";
cmGeneratedFileStream fout(path.c_str());
fout.SetCopyIfDifferent(true);
- char magic[] = {0xEF,0xBB, 0xBF};
+ char magic[] = {char(0xEF), char(0xBB), char(0xBF)};
fout.write(magic, 3);
cmGeneratedFileStream* save = this->BuildFileStream;
this->BuildFileStream = & fout;
//get the tools version to use
const std::string toolsVer(this->GlobalGenerator->GetToolsVersion());
- std::string project_defaults="<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
+ std::string project_defaults=
+ "<?xml version=\"1.0\" encoding=\"" +
+ this->GlobalGenerator->Encoding() + "\"?>\n";
project_defaults.append("<Project ToolsVersion=\"");
project_defaults.append(toolsVer +"\" ");
project_defaults.append(
@@ -736,18 +1053,61 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
this->WriteGroupSources(ti->first.c_str(), ti->second, sourceGroups);
}
- std::vector<cmSourceFile*> const& resxObjs =
- this->GeneratorTarget->ResxSources;
+ // Added files are images and the manifest.
+ if (!this->AddedFiles.empty())
+ {
+ this->WriteString("<ItemGroup>\n", 1);
+ for(std::vector<std::string>::const_iterator
+ oi = this->AddedFiles.begin(); oi != this->AddedFiles.end(); ++oi)
+ {
+ std::string fileName = cmSystemTools::LowerCase(
+ cmSystemTools::GetFilenameName(*oi));
+ if (fileName == "wmappmanifest.xml")
+ {
+ this->WriteString("<XML Include=\"", 2);
+ (*this->BuildFileStream) << *oi << "\">\n";
+ this->WriteString("<Filter>Resource Files</Filter>\n", 3);
+ this->WriteString("</XML>\n", 2);
+ }
+ else if(cmSystemTools::GetFilenameExtension(fileName) ==
+ ".appxmanifest")
+ {
+ this->WriteString("<AppxManifest Include=\"", 2);
+ (*this->BuildFileStream) << *oi << "\">\n";
+ this->WriteString("<Filter>Resource Files</Filter>\n", 3);
+ this->WriteString("</AppxManifest>\n", 2);
+ }
+ else if(cmSystemTools::GetFilenameExtension(fileName) ==
+ ".pfx")
+ {
+ this->WriteString("<None Include=\"", 2);
+ (*this->BuildFileStream) << *oi << "\">\n";
+ this->WriteString("<Filter>Resource Files</Filter>\n", 3);
+ this->WriteString("</None>\n", 2);
+ }
+ else
+ {
+ this->WriteString("<Image Include=\"", 2);
+ (*this->BuildFileStream) << *oi << "\">\n";
+ this->WriteString("<Filter>Resource Files</Filter>\n", 3);
+ this->WriteString("</Image>\n", 2);
+ }
+ }
+ this->WriteString("</ItemGroup>\n", 1);
+ }
+
+ std::vector<cmSourceFile const*> resxObjs;
+ this->GeneratorTarget->GetResxSources(resxObjs, "");
if(!resxObjs.empty())
{
this->WriteString("<ItemGroup>\n", 1);
- for(std::vector<cmSourceFile*>::const_iterator oi = resxObjs.begin();
+ for(std::vector<cmSourceFile const*>::const_iterator oi = resxObjs.begin();
oi != resxObjs.end(); ++oi)
{
std::string obj = (*oi)->GetFullPath();
this->WriteString("<EmbeddedResource Include=\"", 2);
this->ConvertToWindowsSlash(obj);
- (*this->BuildFileStream ) << obj << "\">\n";
+ (*this->BuildFileStream ) << cmVS10EscapeXML(obj) << "\">\n";
this->WriteString("<Filter>Resource Files</Filter>\n", 3);
this->WriteString("</EmbeddedResource>\n", 2);
}
@@ -756,7 +1116,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
// Add object library contents as external objects.
std::vector<std::string> objs;
- this->GeneratorTarget->UseObjectLibraries(objs);
+ this->GeneratorTarget->UseObjectLibraries(objs, "");
if(!objs.empty())
{
this->WriteString("<ItemGroup>\n", 1);
@@ -766,7 +1126,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
std::string obj = *oi;
this->WriteString("<Object Include=\"", 2);
this->ConvertToWindowsSlash(obj);
- (*this->BuildFileStream ) << obj << "\">\n";
+ (*this->BuildFileStream ) << cmVS10EscapeXML(obj) << "\">\n";
this->WriteString("<Filter>Object Libraries</Filter>\n", 3);
this->WriteString("</Object>\n", 2);
}
@@ -785,7 +1145,6 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
(*this->BuildFileStream) << name << "\">\n";
std::string guidName = "SG_Filter_";
guidName += name;
- this->GlobalGenerator->CreateGUID(guidName.c_str());
this->WriteString("<UniqueIdentifier>", 3);
std::string guid
= this->GlobalGenerator->GetGUID(guidName.c_str());
@@ -800,7 +1159,6 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
{
this->WriteString("<Filter Include=\"Object Libraries\">\n", 2);
std::string guidName = "SG_Filter_Object Libraries";
- this->GlobalGenerator->CreateGUID(guidName.c_str());
this->WriteString("<UniqueIdentifier>", 3);
std::string guid =
this->GlobalGenerator->GetGUID(guidName.c_str());
@@ -809,11 +1167,10 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
this->WriteString("</Filter>\n", 2);
}
- if(!this->GeneratorTarget->ResxSources.empty())
+ if(!resxObjs.empty() || !this->AddedFiles.empty())
{
this->WriteString("<Filter Include=\"Resource Files\">\n", 2);
std::string guidName = "SG_Filter_Resource Files";
- this->GlobalGenerator->CreateGUID(guidName.c_str());
this->WriteString("<UniqueIdentifier>", 3);
std::string guid =
this->GlobalGenerator->GetGUID(guidName.c_str());
@@ -892,16 +1249,16 @@ WriteGroupSources(const char* name,
for(ToolSources::const_iterator s = sources.begin();
s != sources.end(); ++s)
{
- cmSourceFile* sf = s->SourceFile;
+ cmSourceFile const* sf = s->SourceFile;
std::string const& source = sf->GetFullPath();
- cmSourceGroup& sourceGroup =
+ cmSourceGroup* sourceGroup =
this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
- const char* filter = sourceGroup.GetFullName();
+ const char* filter = sourceGroup->GetFullName();
this->WriteString("<", 2);
std::string path = this->ConvertPath(source, s->RelativePath);
this->ConvertToWindowsSlash(path);
(*this->BuildFileStream) << name << " Include=\""
- << path;
+ << cmVS10EscapeXML(path);
if(strlen(filter))
{
(*this->BuildFileStream) << "\">\n";
@@ -918,18 +1275,205 @@ WriteGroupSources(const char* name,
this->WriteString("</ItemGroup>\n", 1);
}
+void cmVisualStudio10TargetGenerator::WriteHeaderSource(cmSourceFile const* sf)
+{
+ std::string const& fileName = sf->GetFullPath();
+ if (this->IsResxHeader(fileName))
+ {
+ this->WriteSource("ClInclude", sf, ">\n");
+ this->WriteString("<FileType>CppForm</FileType>\n", 3);
+ this->WriteString("</ClInclude>\n", 2);
+ }
+ else if (this->IsXamlHeader(fileName))
+ {
+ this->WriteSource("ClInclude", sf, ">\n");
+ this->WriteString("<DependentUpon>", 3);
+ std::string xamlFileName = fileName.substr(0, fileName.find_last_of("."));
+ (*this->BuildFileStream) << xamlFileName << "</DependentUpon>\n";
+ this->WriteString("</ClInclude>\n", 2);
+ }
+ else
+ {
+ this->WriteSource("ClInclude", sf);
+ }
+}
+
+void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf)
+{
+ bool toolHasSettings = false;
+ std::string tool = "None";
+ std::string shaderType;
+ std::string shaderEntryPoint;
+ std::string shaderModel;
+ std::string shaderAdditionalFlags;
+ std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
+ if(ext == "hlsl")
+ {
+ tool = "FXCompile";
+ // Figure out the type of shader compiler to use.
+ if(const char* st = sf->GetProperty("VS_SHADER_TYPE"))
+ {
+ shaderType = st;
+ toolHasSettings = true;
+ }
+ // Figure out which entry point to use if any
+ if (const char* se = sf->GetProperty("VS_SHADER_ENTRYPOINT"))
+ {
+ shaderEntryPoint = se;
+ toolHasSettings = true;
+ }
+ // Figure out which shader model to use if any
+ if (const char* sm = sf->GetProperty("VS_SHADER_MODEL"))
+ {
+ shaderModel = sm;
+ toolHasSettings = true;
+ }
+ // Figure out if there's any additional flags to use
+ if (const char* saf = sf->GetProperty("VS_SHADER_FLAGS"))
+ {
+ shaderAdditionalFlags = saf;
+ toolHasSettings = true;
+ }
+ }
+ else if(ext == "jpg" ||
+ ext == "png")
+ {
+ tool = "Image";
+ }
+ else if(ext == "resw")
+ {
+ tool = "PRIResource";
+ }
+ else if(ext == "xml")
+ {
+ tool = "XML";
+ }
+
+ if(this->NsightTegra)
+ {
+ // Nsight Tegra needs specific file types to check up-to-dateness.
+ std::string name =
+ cmSystemTools::LowerCase(sf->GetLocation().GetName());
+ if(name == "androidmanifest.xml" ||
+ name == "build.xml" ||
+ name == "proguard.cfg" ||
+ name == "proguard-project.txt" ||
+ ext == "properties")
+ {
+ tool = "AndroidBuild";
+ }
+ else if(ext == "java")
+ {
+ tool = "JCompile";
+ }
+ else if(ext == "asm" || ext == "s")
+ {
+ tool = "ClCompile";
+ }
+ }
+
+ std::string deployContent;
+ std::string deployLocation;
+ if(this->GlobalGenerator->TargetsWindowsPhone() ||
+ this->GlobalGenerator->TargetsWindowsStore())
+ {
+ const char* content = sf->GetProperty("VS_DEPLOYMENT_CONTENT");
+ if(content && *content)
+ {
+ toolHasSettings = true;
+ deployContent = content;
+
+ const char* location = sf->GetProperty("VS_DEPLOYMENT_LOCATION");
+ if(location && *location)
+ {
+ deployLocation = location;
+ }
+ }
+ }
+
+ if(toolHasSettings)
+ {
+ this->WriteSource(tool, sf, ">\n");
+
+ if(!deployContent.empty())
+ {
+ cmGeneratorExpression ge;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(deployContent);
+ // Deployment location cannot be set on a configuration basis
+ if(!deployLocation.empty())
+ {
+ this->WriteString("<Link>", 3);
+ (*this->BuildFileStream) << deployLocation
+ << "\\%(FileName)%(Extension)";
+ this->WriteString("</Link>\n", 0);
+ }
+ for(size_t i = 0; i != this->Configurations.size(); ++i)
+ {
+ if(0 == strcmp(cge->Evaluate(this->LocalGenerator,
+ this->Configurations[i]), "1"))
+ {
+ this->WriteString("<DeploymentContent Condition=\""
+ "'$(Configuration)|$(Platform)'=='", 3);
+ (*this->BuildFileStream) << this->Configurations[i] << "|"
+ << this->Platform << "'\">true";
+ this->WriteString("</DeploymentContent>\n", 0);
+ }
+ else
+ {
+ this->WriteString("<ExcludedFromBuild Condition=\""
+ "'$(Configuration)|$(Platform)'=='", 3);
+ (*this->BuildFileStream) << this->Configurations[i] << "|"
+ << this->Platform << "'\">true";
+ this->WriteString("</ExcludedFromBuild>\n", 0);
+ }
+ }
+ }
+ if(!shaderType.empty())
+ {
+ this->WriteString("<ShaderType>", 3);
+ (*this->BuildFileStream) << cmVS10EscapeXML(shaderType)
+ << "</ShaderType>\n";
+ }
+ if(!shaderEntryPoint.empty())
+ {
+ this->WriteString("<EntryPointName>", 3);
+ (*this->BuildFileStream) << cmVS10EscapeXML(shaderEntryPoint)
+ << "</EntryPointName>\n";
+ }
+ if(!shaderModel.empty())
+ {
+ this->WriteString("<ShaderModel>", 3);
+ (*this->BuildFileStream) << cmVS10EscapeXML(shaderModel)
+ << "</ShaderModel>\n";
+ }
+ if(!shaderAdditionalFlags.empty())
+ {
+ this->WriteString("<AdditionalOptions>", 3);
+ (*this->BuildFileStream) << cmVS10EscapeXML(shaderAdditionalFlags)
+ << "</AdditionalOptions>\n";
+ }
+ this->WriteString("</", 2);
+ (*this->BuildFileStream) << tool << ">\n";
+ }
+ else
+ {
+ this->WriteSource(tool, sf);
+ }
+}
+
void cmVisualStudio10TargetGenerator::WriteSource(
- const char* tool, cmSourceFile* sf, const char* end)
+ std::string const& tool, cmSourceFile const* sf, const char* end)
{
// Visual Studio tools append relative paths to the current dir, as in:
//
// c:\path\to\current\dir\..\..\..\relative\path\to\source.c
//
// and fail if this exceeds the maximum allowed path length. Our path
- // conversion uses full paths outside the build tree to allow deeper trees.
+ // conversion uses full paths when possible to allow deeper trees.
bool forceRelative = false;
std::string sourceFile = this->ConvertPath(sf->GetFullPath(), false);
- if(this->LocalGenerator->GetVersion() == cmLocalVisualStudioGenerator::VS10
+ if(this->LocalGenerator->GetVersion() == cmGlobalVisualStudioGenerator::VS10
&& cmSystemTools::FileIsFullPath(sourceFile.c_str()))
{
// Normal path conversion resulted in a full path. VS 10 (but not 11)
@@ -943,7 +1487,7 @@ void cmVisualStudio10TargetGenerator::WriteSource(
std::string sourceRel = this->ConvertPath(sf->GetFullPath(), true);
size_t const maxLen = 250;
if(sf->GetCustomCommand() ||
- ((strlen(this->Makefile->GetCurrentOutputDirectory()) + 1 +
+ ((strlen(this->LocalGenerator->GetCurrentBinaryDirectory()) + 1 +
sourceRel.length()) <= maxLen))
{
forceRelative = true;
@@ -951,33 +1495,24 @@ void cmVisualStudio10TargetGenerator::WriteSource(
}
else
{
- this->GlobalGenerator->PathTooLong(this->Target, sf, sourceRel);
+ this->GlobalGenerator->PathTooLong(this->GeneratorTarget,
+ sf, sourceRel);
}
}
this->ConvertToWindowsSlash(sourceFile);
this->WriteString("<", 2);
- (*this->BuildFileStream ) << tool << " Include=\"" << sourceFile << "\"";
-
- if(sf->GetExtension() == "h" &&
- this->IsResxHeader(sf->GetFullPath()))
- {
- (*this->BuildFileStream ) << ">\n";
- this->WriteString("<FileType>CppForm</FileType>\n", 3);
- this->WriteString("</ClInclude>\n", 2);
- }
- else
- {
- (*this->BuildFileStream ) << (end? end : " />\n");
- }
+ (*this->BuildFileStream ) << tool << " Include=\""
+ << cmVS10EscapeXML(sourceFile) << "\""
+ << (end? end : " />\n");
ToolSource toolSource = {sf, forceRelative};
this->Tools[tool].push_back(toolSource);
}
void cmVisualStudio10TargetGenerator::WriteSources(
- const char* tool, std::vector<cmSourceFile*> const& sources)
+ std::string const& tool, std::vector<cmSourceFile const*> const& sources)
{
- for(std::vector<cmSourceFile*>::const_iterator
+ for(std::vector<cmSourceFile const*>::const_iterator
si = sources.begin(); si != sources.end(); ++si)
{
this->WriteSource(tool, *si);
@@ -986,36 +1521,46 @@ void cmVisualStudio10TargetGenerator::WriteSources(
void cmVisualStudio10TargetGenerator::WriteAllSources()
{
- if(this->Target->GetType() > cmTarget::UTILITY)
+ if(this->GeneratorTarget->GetType() > cmState::UTILITY)
{
return;
}
this->WriteString("<ItemGroup>\n", 1);
- this->WriteSources("ClInclude", this->GeneratorTarget->HeaderSources);
- this->WriteSources("Midl", this->GeneratorTarget->IDLSources);
+ std::vector<cmSourceFile const*> headerSources;
+ this->GeneratorTarget->GetHeaderSources(headerSources, "");
+ for(std::vector<cmSourceFile const*>::const_iterator
+ si = headerSources.begin(); si != headerSources.end(); ++si)
+ {
+ this->WriteHeaderSource(*si);
+ }
+ std::vector<cmSourceFile const*> idlSources;
+ this->GeneratorTarget->GetIDLSources(idlSources, "");
+ this->WriteSources("Midl", idlSources);
- for(std::vector<cmSourceFile*>::const_iterator
- si = this->GeneratorTarget->ObjectSources.begin();
- si != this->GeneratorTarget->ObjectSources.end(); ++si)
+ std::vector<cmSourceFile const*> objectSources;
+ this->GeneratorTarget->GetObjectSources(objectSources, "");
+ for(std::vector<cmSourceFile const*>::const_iterator
+ si = objectSources.begin();
+ si != objectSources.end(); ++si)
{
- const char* lang = (*si)->GetLanguage();
- const char* tool = NULL;
- if (strcmp(lang, "C") == 0 || strcmp(lang, "CXX") == 0)
+ const std::string& lang = (*si)->GetLanguage();
+ std::string tool;
+ if (lang == "C"|| lang == "CXX")
{
tool = "ClCompile";
}
- else if (strcmp(lang, "ASM_MASM") == 0 &&
+ else if (lang == "ASM_MASM" &&
this->GlobalGenerator->IsMasmEnabled())
{
tool = "MASM";
}
- else if (strcmp(lang, "RC") == 0)
+ else if (lang == "RC")
{
tool = "ResourceCompile";
}
- if (tool)
+ if (!tool.empty())
{
this->WriteSource(tool, *si, " ");
if (this->OutputSourceSpecificFlags(*si))
@@ -1034,52 +1579,92 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
}
}
- if(this->LocalGenerator->GetVersion() > cmLocalVisualStudioGenerator::VS10)
+ std::vector<cmSourceFile const*> manifestSources;
+ this->GeneratorTarget->GetAppManifest(manifestSources, "");
+ this->WriteSources("AppxManifest", manifestSources);
+
+ std::vector<cmSourceFile const*> certificateSources;
+ this->GeneratorTarget->GetCertificates(certificateSources, "");
+ this->WriteSources("None", certificateSources);
+
+ std::vector<cmSourceFile const*> externalObjects;
+ this->GeneratorTarget->GetExternalObjects(externalObjects, "");
+ for(std::vector<cmSourceFile const*>::iterator
+ si = externalObjects.begin();
+ si != externalObjects.end(); )
+ {
+ if (!(*si)->GetObjectLibrary().empty())
+ {
+ si = externalObjects.erase(si);
+ }
+ else
+ {
+ ++si;
+ }
+ }
+ if(this->LocalGenerator->GetVersion() > cmGlobalVisualStudioGenerator::VS10)
{
// For VS >= 11 we use LinkObjects to avoid linking custom command
// outputs. Use Object for all external objects, generated or not.
- this->WriteSources("Object", this->GeneratorTarget->ExternalObjects);
+ this->WriteSources("Object", externalObjects);
}
else
{
// If an object file is generated in this target, then vs10 will use
// it in the build, and we have to list it as None instead of Object.
- for(std::vector<cmSourceFile*>::const_iterator
- si = this->GeneratorTarget->ExternalObjects.begin();
- si != this->GeneratorTarget->ExternalObjects.end(); ++si)
+ for(std::vector<cmSourceFile const*>::const_iterator
+ si = externalObjects.begin();
+ si != externalObjects.end(); ++si)
{
- std::vector<cmSourceFile*> const* d=this->Target->GetSourceDepends(*si);
+ std::vector<cmSourceFile*> const* d =
+ this->GeneratorTarget->GetSourceDepends(*si);
this->WriteSource((d && !d->empty())? "None":"Object", *si);
}
}
- this->WriteSources("None", this->GeneratorTarget->ExtraSources);
+ std::vector<cmSourceFile const*> extraSources;
+ this->GeneratorTarget->GetExtraSources(extraSources, "");
+ for(std::vector<cmSourceFile const*>::const_iterator
+ si = extraSources.begin(); si != extraSources.end(); ++si)
+ {
+ this->WriteExtraSource(*si);
+ }
// Add object library contents as external objects.
std::vector<std::string> objs;
- this->GeneratorTarget->UseObjectLibraries(objs);
+ this->GeneratorTarget->UseObjectLibraries(objs, "");
for(std::vector<std::string>::const_iterator
oi = objs.begin(); oi != objs.end(); ++oi)
{
std::string obj = *oi;
this->WriteString("<Object Include=\"", 2);
this->ConvertToWindowsSlash(obj);
- (*this->BuildFileStream ) << obj << "\" />\n";
+ (*this->BuildFileStream ) << cmVS10EscapeXML(obj) << "\" />\n";
+ }
+
+ if (cmSourceFile const* defsrc =
+ this->GeneratorTarget->GetModuleDefinitionFile(""))
+ {
+ this->WriteSource("None", defsrc);
+ }
+
+ if (this->IsMissingFiles)
+ {
+ this->WriteMissingFiles();
}
this->WriteString("</ItemGroup>\n", 1);
}
bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
- cmSourceFile* source)
+ cmSourceFile const* source)
{
- cmSourceFile& sf = *source;
+ cmSourceFile const& sf = *source;
std::string objectName;
- if(this->GeneratorTarget->ExplicitObjectName.find(&sf)
- != this->GeneratorTarget->ExplicitObjectName.end())
+ if(this->GeneratorTarget->HasExplicitObjectName(&sf))
{
- objectName = this->GeneratorTarget->Objects[&sf];
+ objectName = this->GeneratorTarget->GetObjectName(&sf);
}
std::string flags;
std::string defines;
@@ -1091,39 +1676,40 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
{
defines += cdefs;
}
- const char* lang =
+ std::string lang =
this->GlobalGenerator->GetLanguageFromExtension
(sf.GetExtension().c_str());
- const char* sourceLang = this->LocalGenerator->GetSourceFileLanguage(sf);
- const char* linkLanguage = this->Target->GetLinkerLanguage();
+ std::string sourceLang = this->LocalGenerator->GetSourceFileLanguage(sf);
+ const std::string& linkLanguage = this->GeneratorTarget->GetLinkerLanguage();
bool needForceLang = false;
// source file does not match its extension language
- if(lang && sourceLang && strcmp(lang, sourceLang) != 0)
+ if(lang != sourceLang)
{
needForceLang = true;
lang = sourceLang;
}
// if the source file does not match the linker language
// then force c or c++
- if(needForceLang || (linkLanguage && lang
- && strcmp(lang, linkLanguage) != 0))
+ const char* compileAs = 0;
+ if(needForceLang || (linkLanguage != lang))
{
- if(strcmp(lang, "CXX") == 0)
+ if(lang == "CXX")
{
// force a C++ file type
- flags += " /TP ";
+ compileAs = "CompileAsCpp";
}
- else if(strcmp(lang, "C") == 0)
+ else if(lang == "C")
{
// force to c
- flags += " /TC ";
+ compileAs = "CompileAsC";
}
}
+ bool noWinRT = this->TargetCompileAsWinRT && lang == "C";
bool hasFlags = false;
// for the first time we need a new line if there is something
// produced here.
const char* firstString = ">\n";
- if(objectName.size())
+ if(!objectName.empty())
{
(*this->BuildFileStream ) << firstString;
firstString = "";
@@ -1132,11 +1718,9 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
(*this->BuildFileStream )
<< "$(IntDir)/" << objectName << "</ObjectFileName>\n";
}
- std::vector<std::string> *configs =
- static_cast<cmGlobalVisualStudio7Generator *>
- (this->GlobalGenerator)->GetConfigurations();
- for( std::vector<std::string>::iterator config = configs->begin();
- config != configs->end(); ++config)
+ for(std::vector<std::string>::const_iterator
+ config = this->Configurations.begin();
+ config != this->Configurations.end(); ++config)
{
std::string configUpper = cmSystemTools::UpperCase(*config);
std::string configDefines = defines;
@@ -1144,7 +1728,7 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
defPropName += configUpper;
if(const char* ccdefs = sf.GetProperty(defPropName.c_str()))
{
- if(configDefines.size())
+ if(!configDefines.empty())
{
configDefines += ";";
}
@@ -1152,7 +1736,7 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
}
// if we have flags or defines for this config then
// use them
- if(flags.size() || configDefines.size())
+ if(!flags.empty() || !configDefines.empty() || compileAs || noWinRT)
{
(*this->BuildFileStream ) << firstString;
firstString = ""; // only do firstString once
@@ -1160,8 +1744,26 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
cmVisualStudioGeneratorOptions
clOptions(this->LocalGenerator,
cmVisualStudioGeneratorOptions::Compiler,
- cmVSGetCLFlagTable(this->LocalGenerator), 0, this);
+ this->GetClFlagTable(), 0, this);
+ if(compileAs)
+ {
+ clOptions.AddFlag("CompileAs", compileAs);
+ }
+ if(noWinRT)
+ {
+ clOptions.AddFlag("CompileAsWinRT", "false");
+ }
clOptions.Parse(flags.c_str());
+ if(clOptions.HasFlag("AdditionalIncludeDirectories"))
+ {
+ clOptions.AppendFlag("AdditionalIncludeDirectories",
+ "%(AdditionalIncludeDirectories)");
+ }
+ if(clOptions.HasFlag("DisableSpecificWarnings"))
+ {
+ clOptions.AppendFlag("DisableSpecificWarnings",
+ "%(DisableSpecificWarnings)");
+ }
clOptions.AddDefines(configDefines.c_str());
clOptions.SetConfiguration((*config).c_str());
clOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", "");
@@ -1170,14 +1772,25 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
" ", "\n", lang);
}
}
+ if (this->IsXamlSource(source->GetFullPath()))
+ {
+ (*this->BuildFileStream) << firstString;
+ firstString = ""; // only do firstString once
+ hasFlags = true;
+ this->WriteString("<DependentUpon>", 3);
+ const std::string& fileName = source->GetFullPath();
+ std::string xamlFileName = fileName.substr(0, fileName.find_last_of("."));
+ (*this->BuildFileStream) << xamlFileName << "</DependentUpon>\n";
+ }
+
return hasFlags;
}
void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions()
{
- cmTarget::TargetType ttype = this->Target->GetType();
- if(ttype > cmTarget::GLOBAL_TARGET)
+ cmState::TargetType ttype = this->GeneratorTarget->GetType();
+ if(ttype > cmState::GLOBAL_TARGET)
{
return;
}
@@ -1185,13 +1798,11 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions()
this->WriteString("<PropertyGroup>\n", 2);
this->WriteString("<_ProjectFileVersion>10.0.20506.1"
"</_ProjectFileVersion>\n", 3);
- std::vector<std::string> *configs =
- static_cast<cmGlobalVisualStudio7Generator *>
- (this->GlobalGenerator)->GetConfigurations();
- for(std::vector<std::string>::iterator config = configs->begin();
- config != configs->end(); ++config)
+ for(std::vector<std::string>::const_iterator
+ config = this->Configurations.begin();
+ config != this->Configurations.end(); ++config)
{
- if(ttype >= cmTarget::UTILITY)
+ if(ttype >= cmState::UTILITY)
{
this->WritePlatformConfigTag("IntDir", config->c_str(), 3);
*this->BuildFileStream
@@ -1201,44 +1812,49 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions()
else
{
std::string intermediateDir = this->LocalGenerator->
- GetTargetDirectory(*this->Target);
+ GetTargetDirectory(this->GeneratorTarget);
intermediateDir += "/";
intermediateDir += *config;
intermediateDir += "/";
std::string outDir;
std::string targetNameFull;
- if(ttype == cmTarget::OBJECT_LIBRARY)
+ if(ttype == cmState::OBJECT_LIBRARY)
{
outDir = intermediateDir;
- targetNameFull = this->Target->GetName();
+ targetNameFull = this->GeneratorTarget->GetName();
targetNameFull += ".lib";
}
else
{
- outDir = this->Target->GetDirectory(config->c_str()) + "/";
- targetNameFull = this->Target->GetFullName(config->c_str());
+ outDir = this->GeneratorTarget->GetDirectory(config->c_str()) + "/";
+ targetNameFull = this->GeneratorTarget->GetFullName(config->c_str());
}
this->ConvertToWindowsSlash(intermediateDir);
this->ConvertToWindowsSlash(outDir);
this->WritePlatformConfigTag("OutDir", config->c_str(), 3);
- *this->BuildFileStream << outDir
+ *this->BuildFileStream << cmVS10EscapeXML(outDir)
<< "</OutDir>\n";
this->WritePlatformConfigTag("IntDir", config->c_str(), 3);
- *this->BuildFileStream << intermediateDir
+ *this->BuildFileStream << cmVS10EscapeXML(intermediateDir)
<< "</IntDir>\n";
+ std::string name =
+ cmSystemTools::GetFilenameWithoutLastExtension(targetNameFull);
this->WritePlatformConfigTag("TargetName", config->c_str(), 3);
- *this->BuildFileStream
- << cmSystemTools::GetFilenameWithoutLastExtension(
- targetNameFull.c_str())
- << "</TargetName>\n";
+ *this->BuildFileStream << cmVS10EscapeXML(name) << "</TargetName>\n";
+ std::string ext =
+ cmSystemTools::GetFilenameLastExtension(targetNameFull);
+ if(ext.empty())
+ {
+ // An empty TargetExt causes a default extension to be used.
+ // A single "." appears to be treated as an empty extension.
+ ext = ".";
+ }
this->WritePlatformConfigTag("TargetExt", config->c_str(), 3);
- *this->BuildFileStream
- << cmSystemTools::GetFilenameLastExtension(targetNameFull.c_str())
- << "</TargetExt>\n";
+ *this->BuildFileStream << cmVS10EscapeXML(ext) << "</TargetExt>\n";
this->OutputLinkIncremental(*config);
}
@@ -1252,10 +1868,14 @@ void
cmVisualStudio10TargetGenerator::
OutputLinkIncremental(std::string const& configName)
{
+ if(!this->MSTools)
+ {
+ return;
+ }
// static libraries and things greater than modules do not need
// to set this option
- if(this->Target->GetType() == cmTarget::STATIC_LIBRARY
- || this->Target->GetType() > cmTarget::MODULE_LIBRARY)
+ if(this->GeneratorTarget->GetType() == cmState::STATIC_LIBRARY
+ || this->GeneratorTarget->GetType() > cmState::MODULE_LIBRARY)
{
return;
}
@@ -1294,10 +1914,9 @@ OutputLinkIncremental(std::string const& configName)
//----------------------------------------------------------------------------
bool cmVisualStudio10TargetGenerator::ComputeClOptions()
{
- std::vector<std::string> const* configs =
- this->GlobalGenerator->GetConfigurations();
- for(std::vector<std::string>::const_iterator i = configs->begin();
- i != configs->end(); ++i)
+ for(std::vector<std::string>::const_iterator
+ i = this->Configurations.begin();
+ i != this->Configurations.end(); ++i)
{
if(!this->ComputeClOptions(*i))
{
@@ -1317,73 +1936,108 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
cmsys::auto_ptr<Options> pOptions(
new Options(this->LocalGenerator, Options::Compiler,
- cmVSGetCLFlagTable(this->LocalGenerator)));
+ this->GetClFlagTable()));
Options& clOptions = *pOptions;
std::string flags;
- // collect up flags for
- if(this->Target->GetType() < cmTarget::UTILITY)
+ const std::string& linkLanguage =
+ this->GeneratorTarget->GetLinkerLanguage(configName.c_str());
+ if(linkLanguage.empty())
{
- const char* linkLanguage =
- this->Target->GetLinkerLanguage(configName.c_str());
- if(!linkLanguage)
- {
- cmSystemTools::Error
- ("CMake can not determine linker language for target: ",
- this->Name.c_str());
- return false;
- }
- if(strcmp(linkLanguage, "C") == 0 || strcmp(linkLanguage, "CXX") == 0
- || strcmp(linkLanguage, "Fortran") == 0)
- {
- std::string baseFlagVar = "CMAKE_";
- baseFlagVar += linkLanguage;
- baseFlagVar += "_FLAGS";
- flags = this->
- Target->GetMakefile()->GetRequiredDefinition(baseFlagVar.c_str());
- std::string flagVar = baseFlagVar + std::string("_") +
- cmSystemTools::UpperCase(configName);
- flags += " ";
- flags += this->
- Target->GetMakefile()->GetRequiredDefinition(flagVar.c_str());
- }
- // set the correct language
- if(strcmp(linkLanguage, "C") == 0)
- {
- flags += " /TC ";
- }
- if(strcmp(linkLanguage, "CXX") == 0)
- {
- flags += " /TP ";
- }
- this->LocalGenerator->AddCompileOptions(flags, this->Target,
- linkLanguage, configName.c_str());
+ cmSystemTools::Error
+ ("CMake can not determine linker language for target: ",
+ this->Name.c_str());
+ return false;
+ }
+ if(linkLanguage == "C" || linkLanguage == "CXX"
+ || linkLanguage == "Fortran")
+ {
+ std::string baseFlagVar = "CMAKE_";
+ baseFlagVar += linkLanguage;
+ baseFlagVar += "_FLAGS";
+ flags = this->GeneratorTarget->
+ Target->GetMakefile()->GetRequiredDefinition(baseFlagVar.c_str());
+ std::string flagVar = baseFlagVar + std::string("_") +
+ cmSystemTools::UpperCase(configName);
+ flags += " ";
+ flags += this->GeneratorTarget->
+ Target->GetMakefile()->GetRequiredDefinition(flagVar.c_str());
}
+ // set the correct language
+ if(linkLanguage == "C")
+ {
+ clOptions.AddFlag("CompileAs", "CompileAsC");
+ }
+ if(linkLanguage == "CXX")
+ {
+ clOptions.AddFlag("CompileAs", "CompileAsCpp");
+ }
+ this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget,
+ linkLanguage, configName.c_str());
// Get preprocessor definitions for this directory.
- std::string defineFlags = this->Target->GetMakefile()->GetDefineFlags();
- clOptions.FixExceptionHandlingDefault();
- clOptions.AddFlag("PrecompiledHeader", "NotUsing");
- std::string asmLocation = configName + "/";
- clOptions.AddFlag("AssemblerListingLocation", asmLocation.c_str());
+ std::string defineFlags =
+ this->GeneratorTarget->Target->GetMakefile()->GetDefineFlags();
+ if(this->MSTools)
+ {
+ clOptions.FixExceptionHandlingDefault();
+ clOptions.AddFlag("PrecompiledHeader", "NotUsing");
+ std::string asmLocation = configName + "/";
+ clOptions.AddFlag("AssemblerListingLocation", asmLocation.c_str());
+ }
clOptions.Parse(flags.c_str());
clOptions.Parse(defineFlags.c_str());
std::vector<std::string> targetDefines;
- this->Target->GetCompileDefinitions(targetDefines, configName.c_str());
+ this->GeneratorTarget->GetCompileDefinitions(targetDefines,
+ configName.c_str(), "CXX");
clOptions.AddDefines(targetDefines);
- clOptions.SetVerboseMakefile(
- this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
+ if(this->MSTools)
+ {
+ clOptions.SetVerboseMakefile(
+ this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
+ }
// Add a definition for the configuration name.
std::string configDefine = "CMAKE_INTDIR=\"";
configDefine += configName;
configDefine += "\"";
clOptions.AddDefine(configDefine);
- if(const char* exportMacro = this->Target->GetExportMacro())
+ if(const char* exportMacro =
+ this->GeneratorTarget->GetExportMacro())
{
clOptions.AddDefine(exportMacro);
}
+ if (this->MSTools)
+ {
+ // If we have the VS_WINRT_COMPONENT set then force Compile as WinRT.
+ if (this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_COMPONENT"))
+ {
+ clOptions.AddFlag("CompileAsWinRT", "true");
+ // For WinRT components, add the _WINRT_DLL define to produce a lib
+ if (this->GeneratorTarget->GetType() == cmState::SHARED_LIBRARY ||
+ this->GeneratorTarget->GetType() == cmState::MODULE_LIBRARY )
+ {
+ clOptions.AddDefine("_WINRT_DLL");
+ }
+ }
+ else if (this->GlobalGenerator->TargetsWindowsStore() ||
+ this->GlobalGenerator->TargetsWindowsPhone())
+ {
+ if (!clOptions.IsWinRt())
+ {
+ clOptions.AddFlag("CompileAsWinRT", "false");
+ }
+ }
+ if(const char* winRT = clOptions.GetFlag("CompileAsWinRT"))
+ {
+ if(cmSystemTools::IsOn(winRT))
+ {
+ this->TargetCompileAsWinRT = true;
+ }
+ }
+ }
+
this->ClOptions[configName] = pOptions.release();
return true;
}
@@ -1396,88 +2050,392 @@ void cmVisualStudio10TargetGenerator::WriteClOptions(
Options& clOptions = *(this->ClOptions[configName]);
this->WriteString("<ClCompile>\n", 2);
clOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", "");
- this->OutputIncludes(includes);
+ clOptions.AppendFlag("AdditionalIncludeDirectories", includes);
+ clOptions.AppendFlag("AdditionalIncludeDirectories",
+ "%(AdditionalIncludeDirectories)");
clOptions.OutputFlagMap(*this->BuildFileStream, " ");
+ clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ",
+ "\n", "CXX");
- // If not in debug mode, write the DebugInformationFormat field
- // without value so PDBs don't get generated uselessly.
- if(!clOptions.IsDebug())
+ if(this->NsightTegra)
{
- this->WriteString("<DebugInformationFormat>"
- "</DebugInformationFormat>\n", 3);
+ if(const char* processMax =
+ this->GeneratorTarget->GetProperty("ANDROID_PROCESS_MAX"))
+ {
+ this->WriteString("<ProcessMax>", 3);
+ *this->BuildFileStream << cmVS10EscapeXML(processMax) <<
+ "</ProcessMax>\n";
+ }
+ }
+
+ if(this->MSTools)
+ {
+ this->WriteString("<ObjectFileName>$(IntDir)</ObjectFileName>\n", 3);
+
+ // If not in debug mode, write the DebugInformationFormat field
+ // without value so PDBs don't get generated uselessly.
+ if(!clOptions.IsDebug())
+ {
+ this->WriteString("<DebugInformationFormat>"
+ "</DebugInformationFormat>\n", 3);
+ }
+
+ // Specify the compiler program database file if configured.
+ std::string pdb =
+ this->GeneratorTarget->GetCompilePDBPath(configName.c_str());
+ if(!pdb.empty())
+ {
+ this->ConvertToWindowsSlash(pdb);
+ this->WriteString("<ProgramDataBaseFileName>", 3);
+ *this->BuildFileStream << cmVS10EscapeXML(pdb)
+ << "</ProgramDataBaseFileName>\n";
+ }
}
- clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ",
- "\n", "CXX");
- this->WriteString("<ObjectFileName>$(IntDir)</ObjectFileName>\n", 3);
this->WriteString("</ClCompile>\n", 2);
}
-void cmVisualStudio10TargetGenerator::
-OutputIncludes(std::vector<std::string> const & includes)
+//----------------------------------------------------------------------------
+bool cmVisualStudio10TargetGenerator::ComputeRcOptions()
{
- this->WriteString("<AdditionalIncludeDirectories>", 3);
- for(std::vector<std::string>::const_iterator i = includes.begin();
- i != includes.end(); ++i)
+ for(std::vector<std::string>::const_iterator
+ i = this->Configurations.begin();
+ i != this->Configurations.end(); ++i)
{
- std::string incDir = *i;
- this->ConvertToWindowsSlash(incDir);
- *this->BuildFileStream << cmVS10EscapeXML(incDir) << ";";
+ if(!this->ComputeRcOptions(*i))
+ {
+ return false;
+ }
}
- this->WriteString("%(AdditionalIncludeDirectories)"
- "</AdditionalIncludeDirectories>\n", 0);
+ return true;
}
-
+//----------------------------------------------------------------------------
+bool cmVisualStudio10TargetGenerator::ComputeRcOptions(
+ std::string const& configName)
+{
+ cmsys::auto_ptr<Options> pOptions(
+ new Options(this->LocalGenerator, Options::ResourceCompiler,
+ this->GetRcFlagTable()));
+ Options& rcOptions = *pOptions;
+
+ std::string CONFIG = cmSystemTools::UpperCase(configName);
+ std::string rcConfigFlagsVar = std::string("CMAKE_RC_FLAGS_") + CONFIG;
+ std::string flags =
+ std::string(this->Makefile->GetSafeDefinition("CMAKE_RC_FLAGS")) +
+ std::string(" ") +
+ std::string(this->Makefile->GetSafeDefinition(rcConfigFlagsVar));
+
+ rcOptions.Parse(flags.c_str());
+ this->RcOptions[configName] = pOptions.release();
+ return true;
+}
void cmVisualStudio10TargetGenerator::
WriteRCOptions(std::string const& configName,
std::vector<std::string> const & includes)
{
+ if(!this->MSTools)
+ {
+ return;
+ }
this->WriteString("<ResourceCompile>\n", 2);
+
+ // Preprocessor definitions and includes are shared with clOptions.
Options& clOptions = *(this->ClOptions[configName]);
clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ",
"\n", "RC");
- this->OutputIncludes(includes);
+
+ Options& rcOptions = *(this->RcOptions[configName]);
+ rcOptions.AppendFlag("AdditionalIncludeDirectories", includes);
+ rcOptions.AppendFlag("AdditionalIncludeDirectories",
+ "%(AdditionalIncludeDirectories)");
+ rcOptions.OutputFlagMap(*this->BuildFileStream, " ");
+ rcOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", "");
+
this->WriteString("</ResourceCompile>\n", 2);
}
+//----------------------------------------------------------------------------
+bool cmVisualStudio10TargetGenerator::ComputeMasmOptions()
+{
+ if(!this->GlobalGenerator->IsMasmEnabled())
+ {
+ return true;
+ }
+ for(std::vector<std::string>::const_iterator
+ i = this->Configurations.begin();
+ i != this->Configurations.end(); ++i)
+ {
+ if(!this->ComputeMasmOptions(*i))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmVisualStudio10TargetGenerator::ComputeMasmOptions(
+ std::string const& configName)
+{
+ cmsys::auto_ptr<Options> pOptions(
+ new Options(this->LocalGenerator, Options::MasmCompiler,
+ this->GetMasmFlagTable()));
+ Options& masmOptions = *pOptions;
+
+ std::string CONFIG = cmSystemTools::UpperCase(configName);
+ std::string configFlagsVar = std::string("CMAKE_ASM_MASM_FLAGS_") + CONFIG;
+ std::string flags =
+ std::string(this->Makefile->GetSafeDefinition("CMAKE_ASM_MASM_FLAGS")) +
+ std::string(" ") +
+ std::string(this->Makefile->GetSafeDefinition(configFlagsVar));
+
+ masmOptions.Parse(flags.c_str());
+ this->MasmOptions[configName] = pOptions.release();
+ return true;
+}
+
+void cmVisualStudio10TargetGenerator::
+WriteMasmOptions(std::string const& configName,
+ std::vector<std::string> const& includes)
+{
+ if(!this->MSTools || !this->GlobalGenerator->IsMasmEnabled())
+ {
+ return;
+ }
+ this->WriteString("<MASM>\n", 2);
+
+ // Preprocessor definitions and includes are shared with clOptions.
+ Options& clOptions = *(this->ClOptions[configName]);
+ clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ",
+ "\n", "ASM_MASM");
+
+ Options& masmOptions = *(this->MasmOptions[configName]);
+ masmOptions.AppendFlag("IncludePaths", includes);
+ masmOptions.AppendFlag("IncludePaths", "%(IncludePaths)");
+ masmOptions.OutputFlagMap(*this->BuildFileStream, " ");
+ masmOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", "");
+
+ this->WriteString("</MASM>\n", 2);
+}
+
void
cmVisualStudio10TargetGenerator::WriteLibOptions(std::string const& config)
{
- if(this->Target->GetType() != cmTarget::STATIC_LIBRARY)
+ if(this->GeneratorTarget->GetType() != cmState::STATIC_LIBRARY &&
+ this->GeneratorTarget->GetType() != cmState::OBJECT_LIBRARY)
{
return;
}
std::string libflags;
this->LocalGenerator->GetStaticLibraryFlags(libflags,
- cmSystemTools::UpperCase(config), this->Target);
+ cmSystemTools::UpperCase(config), this->GeneratorTarget);
if(!libflags.empty())
{
this->WriteString("<Lib>\n", 2);
cmVisualStudioGeneratorOptions
libOptions(this->LocalGenerator,
cmVisualStudioGeneratorOptions::Linker,
- cmVSGetLibFlagTable(this->LocalGenerator), 0, this);
+ this->GetLibFlagTable(), 0, this);
libOptions.Parse(libflags.c_str());
libOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", "");
libOptions.OutputFlagMap(*this->BuildFileStream, " ");
this->WriteString("</Lib>\n", 2);
}
+
+ // We cannot generate metadata for static libraries. WindowsPhone
+ // and WindowsStore tools look at GenerateWindowsMetadata in the
+ // Link tool options even for static libraries.
+ if(this->GlobalGenerator->TargetsWindowsPhone() ||
+ this->GlobalGenerator->TargetsWindowsStore())
+ {
+ this->WriteString("<Link>\n", 2);
+ this->WriteString("<GenerateWindowsMetadata>false"
+ "</GenerateWindowsMetadata>\n", 3);
+ this->WriteString("</Link>\n", 2);
+ }
+}
+
+void cmVisualStudio10TargetGenerator::WriteManifestOptions(
+ std::string const& config)
+{
+ if (this->GeneratorTarget->GetType() != cmState::EXECUTABLE &&
+ this->GeneratorTarget->GetType() != cmState::SHARED_LIBRARY &&
+ this->GeneratorTarget->GetType() != cmState::MODULE_LIBRARY)
+ {
+ return;
+ }
+
+ std::vector<cmSourceFile const*> manifest_srcs;
+ this->GeneratorTarget->GetManifests(manifest_srcs, config);
+ if (!manifest_srcs.empty())
+ {
+ this->WriteString("<Manifest>\n", 2);
+ this->WriteString("<AdditionalManifestFiles>", 3);
+ for (std::vector<cmSourceFile const*>::const_iterator
+ mi = manifest_srcs.begin(); mi != manifest_srcs.end(); ++mi)
+ {
+ std::string m = this->ConvertPath((*mi)->GetFullPath(), false);
+ this->ConvertToWindowsSlash(m);
+ (*this->BuildFileStream) << m << ";";
+ }
+ (*this->BuildFileStream) << "</AdditionalManifestFiles>\n";
+ this->WriteString("</Manifest>\n", 2);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmVisualStudio10TargetGenerator::WriteAntBuildOptions(
+ std::string const& configName)
+{
+ // Look through the sources for AndroidManifest.xml and use
+ // its location as the root source directory.
+ std::string rootDir = this->LocalGenerator->GetCurrentSourceDirectory();
+ {
+ std::vector<cmSourceFile const*> extraSources;
+ this->GeneratorTarget->GetExtraSources(extraSources, "");
+ for(std::vector<cmSourceFile const*>::const_iterator si =
+ extraSources.begin(); si != extraSources.end(); ++si)
+ {
+ if("androidmanifest.xml" == cmSystemTools::LowerCase(
+ (*si)->GetLocation().GetName()))
+ {
+ rootDir = (*si)->GetLocation().GetDirectory();
+ break;
+ }
+ }
+ }
+
+ // Tell MSBuild to launch Ant.
+ {
+ std::string antBuildPath = rootDir;
+ this->WriteString("<AntBuild>\n", 2);
+ this->WriteString("<AntBuildPath>", 3);
+ this->ConvertToWindowsSlash(antBuildPath);
+ (*this->BuildFileStream) <<
+ cmVS10EscapeXML(antBuildPath) << "</AntBuildPath>\n";
+ }
+
+ if (this->GeneratorTarget->GetPropertyAsBool("ANDROID_SKIP_ANT_STEP"))
+ {
+ this->WriteString("<SkipAntStep>true</SkipAntStep>\n", 3);
+ }
+
+ if (this->GeneratorTarget->GetPropertyAsBool("ANDROID_PROGUARD"))
+ {
+ this->WriteString("<EnableProGuard>true</EnableProGuard>\n", 3);
+ }
+
+ if (const char* proGuardConfigLocation =
+ this->GeneratorTarget->GetProperty("ANDROID_PROGUARD_CONFIG_PATH"))
+ {
+ this->WriteString("<ProGuardConfigLocation>", 3);
+ (*this->BuildFileStream) << cmVS10EscapeXML(proGuardConfigLocation) <<
+ "</ProGuardConfigLocation>\n";
+ }
+
+ if (const char* securePropertiesLocation =
+ this->GeneratorTarget->GetProperty("ANDROID_SECURE_PROPS_PATH"))
+ {
+ this->WriteString("<SecurePropertiesLocation>", 3);
+ (*this->BuildFileStream) << cmVS10EscapeXML(securePropertiesLocation) <<
+ "</SecurePropertiesLocation>\n";
+ }
+
+ if (const char* nativeLibDirectoriesExpression =
+ this->GeneratorTarget->GetProperty("ANDROID_NATIVE_LIB_DIRECTORIES"))
+ {
+ cmGeneratorExpression ge;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(nativeLibDirectoriesExpression);
+ std::string nativeLibDirs = cge->Evaluate(this->LocalGenerator,
+ configName);
+ this->WriteString("<NativeLibDirectories>", 3);
+ (*this->BuildFileStream) << cmVS10EscapeXML(nativeLibDirs) <<
+ "</NativeLibDirectories>\n";
+ }
+
+ if (const char* nativeLibDependenciesExpression =
+ this->GeneratorTarget->GetProperty("ANDROID_NATIVE_LIB_DEPENDENCIES"))
+ {
+ cmGeneratorExpression ge;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(nativeLibDependenciesExpression);
+ std::string nativeLibDeps = cge->Evaluate(this->LocalGenerator,
+ configName);
+ this->WriteString("<NativeLibDependencies>", 3);
+ (*this->BuildFileStream) << cmVS10EscapeXML(nativeLibDeps) <<
+ "</NativeLibDependencies>\n";
+ }
+
+ if (const char* javaSourceDir =
+ this->GeneratorTarget->GetProperty("ANDROID_JAVA_SOURCE_DIR"))
+ {
+ this->WriteString("<JavaSourceDir>", 3);
+ (*this->BuildFileStream) << cmVS10EscapeXML(javaSourceDir) <<
+ "</JavaSourceDir>\n";
+ }
+
+ if (const char* jarDirectoriesExpression =
+ this->GeneratorTarget->GetProperty("ANDROID_JAR_DIRECTORIES"))
+ {
+ cmGeneratorExpression ge;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(jarDirectoriesExpression);
+ std::string jarDirectories = cge->Evaluate(this->LocalGenerator,
+ configName);
+ this->WriteString("<JarDirectories>", 3);
+ (*this->BuildFileStream) << cmVS10EscapeXML(jarDirectories) <<
+ "</JarDirectories>\n";
+ }
+
+ if (const char* jarDeps =
+ this->GeneratorTarget->GetProperty("ANDROID_JAR_DEPENDENCIES"))
+ {
+ this->WriteString("<JarDependencies>", 3);
+ (*this->BuildFileStream) << cmVS10EscapeXML(jarDeps) <<
+ "</JarDependencies>\n";
+ }
+
+ if (const char* assetsDirectories =
+ this->GeneratorTarget->GetProperty("ANDROID_ASSETS_DIRECTORIES"))
+ {
+ this->WriteString("<AssetsDirectories>", 3);
+ (*this->BuildFileStream) << cmVS10EscapeXML(assetsDirectories) <<
+ "</AssetsDirectories>\n";
+ }
+
+ {
+ std::string manifest_xml = rootDir + "/AndroidManifest.xml";
+ this->ConvertToWindowsSlash(manifest_xml);
+ this->WriteString("<AndroidManifestLocation>", 3);
+ (*this->BuildFileStream) <<
+ cmVS10EscapeXML(manifest_xml) << "</AndroidManifestLocation>\n";
+ }
+
+ if (const char* antAdditionalOptions =
+ this->GeneratorTarget->GetProperty("ANDROID_ANT_ADDITIONAL_OPTIONS"))
+ {
+ this->WriteString("<AdditionalOptions>", 3);
+ (*this->BuildFileStream) << cmVS10EscapeXML(antAdditionalOptions) <<
+ " %(AdditionalOptions)</AdditionalOptions>\n";
+ }
+
+ this->WriteString("</AntBuild>\n", 2);
}
//----------------------------------------------------------------------------
bool cmVisualStudio10TargetGenerator::ComputeLinkOptions()
{
- if(this->Target->GetType() == cmTarget::EXECUTABLE ||
- this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
- this->Target->GetType() == cmTarget::MODULE_LIBRARY)
+ if(this->GeneratorTarget->GetType() == cmState::EXECUTABLE ||
+ this->GeneratorTarget->GetType() == cmState::SHARED_LIBRARY ||
+ this->GeneratorTarget->GetType() == cmState::MODULE_LIBRARY)
{
- std::vector<std::string> const* configs =
- this->GlobalGenerator->GetConfigurations();
- for(std::vector<std::string>::const_iterator i = configs->begin();
- i != configs->end(); ++i)
+ for(std::vector<std::string>::const_iterator
+ i = this->Configurations.begin();
+ i != this->Configurations.end(); ++i)
{
if(!this->ComputeLinkOptions(*i))
{
@@ -1494,12 +2452,12 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
{
cmsys::auto_ptr<Options> pOptions(
new Options(this->LocalGenerator, Options::Linker,
- cmVSGetLinkFlagTable(this->LocalGenerator), 0, this));
+ this->GetLinkFlagTable(), 0, this));
Options& linkOptions = *pOptions;
- const char* linkLanguage =
- this->Target->GetLinkerLanguage(config.c_str());
- if(!linkLanguage)
+ const std::string& linkLanguage =
+ this->GeneratorTarget->GetLinkerLanguage(config.c_str());
+ if(linkLanguage.empty())
{
cmSystemTools::Error
("CMake can not determine linker language for target: ",
@@ -1510,35 +2468,27 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
std::string CONFIG = cmSystemTools::UpperCase(config);
const char* linkType = "SHARED";
- if(this->Target->GetType() == cmTarget::MODULE_LIBRARY)
+ if(this->GeneratorTarget->GetType() == cmState::MODULE_LIBRARY)
{
linkType = "MODULE";
}
- if(this->Target->GetType() == cmTarget::EXECUTABLE)
+ if(this->GeneratorTarget->GetType() == cmState::EXECUTABLE)
{
linkType = "EXE";
}
- std::string stackVar = "CMAKE_";
- stackVar += linkLanguage;
- stackVar += "_STACK_SIZE";
- const char* stackVal = this->Makefile->GetDefinition(stackVar.c_str());
std::string flags;
- if(stackVal)
- {
- flags += " /STACK:";
- flags += stackVal;
- }
std::string linkFlagVarBase = "CMAKE_";
linkFlagVarBase += linkType;
linkFlagVarBase += "_LINKER_FLAGS";
flags += " ";
- flags += this->
+ flags += this->GeneratorTarget->
Target->GetMakefile()->GetRequiredDefinition(linkFlagVarBase.c_str());
std::string linkFlagVar = linkFlagVarBase + "_" + CONFIG;
flags += " ";
- flags += this->
+ flags += this->GeneratorTarget->
Target->GetMakefile()->GetRequiredDefinition(linkFlagVar.c_str());
- const char* targetLinkFlags = this->Target->GetProperty("LINK_FLAGS");
+ const char* targetLinkFlags =
+ this->GeneratorTarget->GetProperty("LINK_FLAGS");
if(targetLinkFlags)
{
flags += " ";
@@ -1546,19 +2496,12 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
}
std::string flagsProp = "LINK_FLAGS_";
flagsProp += CONFIG;
- if(const char* flagsConfig = this->Target->GetProperty(flagsProp.c_str()))
+ if(const char* flagsConfig =
+ this->GeneratorTarget->GetProperty(flagsProp.c_str()))
{
flags += " ";
flags += flagsConfig;
}
- if ( this->Target->GetPropertyAsBool("WIN32_EXECUTABLE") )
- {
- linkOptions.AddFlag("SubSystem", "Windows");
- }
- else
- {
- linkOptions.AddFlag("SubSystem", "Console");
- }
std::string standardLibsVar = "CMAKE_";
standardLibsVar += linkLanguage;
standardLibsVar += "_STANDARD_LIBRARIES";
@@ -1566,7 +2509,7 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
libs = this->Makefile->GetSafeDefinition(standardLibsVar.c_str());
// Remove trailing spaces from libs
std::string::size_type pos = libs.size()-1;
- if(libs.size() != 0)
+ if(!libs.empty())
{
while(libs[pos] == ' ')
{
@@ -1579,8 +2522,11 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
}
// Replace spaces in libs with ;
cmSystemTools::ReplaceString(libs, " ", ";");
+ std::vector<std::string> libVec;
+ cmSystemTools::ExpandListArgument(libs, libVec);
+
cmComputeLinkInformation* pcli =
- this->Target->GetLinkInformation(config.c_str());
+ this->GeneratorTarget->GetLinkInformation(config.c_str());
if(!pcli)
{
cmSystemTools::Error
@@ -1590,69 +2536,194 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
}
// add the libraries for the target to libs string
cmComputeLinkInformation& cli = *pcli;
- this->AddLibraries(cli, libs);
- linkOptions.AddFlag("AdditionalDependencies", libs.c_str());
+ this->AddLibraries(cli, libVec);
+ linkOptions.AddFlag("AdditionalDependencies", libVec);
std::vector<std::string> const& ldirs = cli.GetDirectories();
- const char* sep = "";
- std::string linkDirs;
+ std::vector<std::string> linkDirs;
for(std::vector<std::string>::const_iterator d = ldirs.begin();
d != ldirs.end(); ++d)
{
// first just full path
- linkDirs += sep;
- linkDirs += *d;
- sep = ";";
- linkDirs += sep;
+ linkDirs.push_back(*d);
// next path with configuration type Debug, Release, etc
- linkDirs += *d;
- linkDirs += "/$(Configuration)";
- linkDirs += sep;
- }
- linkDirs += "%(AdditionalLibraryDirectories)";
- linkOptions.AddFlag("AdditionalLibraryDirectories", linkDirs.c_str());
- linkOptions.AddFlag("AdditionalDependencies", libs.c_str());
- linkOptions.AddFlag("Version", "");
- if(linkOptions.IsDebug() || flags.find("/debug") != flags.npos)
- {
- linkOptions.AddFlag("GenerateDebugInformation", "true");
- }
- else
- {
- linkOptions.AddFlag("GenerateDebugInformation", "false");
+ linkDirs.push_back(*d + "/$(Configuration)");
}
+ linkDirs.push_back("%(AdditionalLibraryDirectories)");
+ linkOptions.AddFlag("AdditionalLibraryDirectories", linkDirs);
+
std::string targetName;
std::string targetNameSO;
std::string targetNameFull;
std::string targetNameImport;
std::string targetNamePDB;
- if(this->Target->GetType() == cmTarget::EXECUTABLE)
+ if(this->GeneratorTarget->GetType() == cmState::EXECUTABLE)
{
- this->Target->GetExecutableNames(targetName, targetNameFull,
+ this->GeneratorTarget->GetExecutableNames(targetName, targetNameFull,
targetNameImport, targetNamePDB,
config.c_str());
}
else
{
- this->Target->GetLibraryNames(targetName, targetNameSO, targetNameFull,
+ this->GeneratorTarget->GetLibraryNames(targetName, targetNameSO,
+ targetNameFull,
targetNameImport, targetNamePDB,
config.c_str());
}
- std::string pdb = this->Target->GetPDBDirectory(config.c_str());
- pdb += "/";
- pdb += targetNamePDB;
- std::string imLib = this->Target->GetDirectory(config.c_str(), true);
- imLib += "/";
- imLib += targetNameImport;
+ if(this->MSTools)
+ {
+ linkOptions.AddFlag("Version", "");
+
+ if ( this->GeneratorTarget->GetPropertyAsBool("WIN32_EXECUTABLE") )
+ {
+ if (this->GlobalGenerator->TargetsWindowsCE())
+ {
+ linkOptions.AddFlag("SubSystem", "WindowsCE");
+ if (this->GeneratorTarget->GetType() == cmState::EXECUTABLE)
+ {
+ if (this->ClOptions[config]->UsingUnicode())
+ {
+ linkOptions.AddFlag("EntryPointSymbol", "wWinMainCRTStartup");
+ }
+ else
+ {
+ linkOptions.AddFlag("EntryPointSymbol", "WinMainCRTStartup");
+ }
+ }
+ }
+ else
+ {
+ linkOptions.AddFlag("SubSystem", "Windows");
+ }
+ }
+ else
+ {
+ if (this->GlobalGenerator->TargetsWindowsCE())
+ {
+ linkOptions.AddFlag("SubSystem", "WindowsCE");
+ if (this->GeneratorTarget->GetType() == cmState::EXECUTABLE)
+ {
+ if (this->ClOptions[config]->UsingUnicode())
+ {
+ linkOptions.AddFlag("EntryPointSymbol", "mainWCRTStartup");
+ }
+ else
+ {
+ linkOptions.AddFlag("EntryPointSymbol", "mainACRTStartup");
+ }
+ }
+ }
+ else
+ {
+ linkOptions.AddFlag("SubSystem", "Console");
+ };
+ }
+
+ if(const char* stackVal =
+ this->Makefile->GetDefinition("CMAKE_"+linkLanguage+"_STACK_SIZE"))
+ {
+ linkOptions.AddFlag("StackReserveSize", stackVal);
+ }
+
+ if (this->LocalGenerator->GetVersion() >=
+ cmGlobalVisualStudioGenerator::VS14)
+ {
+ linkOptions.AddFlag("GenerateDebugInformation", "No");
+ }
+ else
+ {
+ linkOptions.AddFlag("GenerateDebugInformation", "false");
+ }
+
+ std::string pdb = this->GeneratorTarget->GetPDBDirectory(config.c_str());
+ pdb += "/";
+ pdb += targetNamePDB;
+ std::string imLib =
+ this->GeneratorTarget->GetDirectory(config.c_str(), true);
+ imLib += "/";
+ imLib += targetNameImport;
+
+ linkOptions.AddFlag("ImportLibrary", imLib.c_str());
+ linkOptions.AddFlag("ProgramDataBaseFile", pdb.c_str());
+
+ // A Windows Runtime component uses internal .NET metadata,
+ // so does not have an import library.
+ if(this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_COMPONENT") &&
+ this->GeneratorTarget->GetType() != cmState::EXECUTABLE)
+ {
+ linkOptions.AddFlag("GenerateWindowsMetadata", "true");
+ }
+ else if (this->GlobalGenerator->TargetsWindowsPhone() ||
+ this->GlobalGenerator->TargetsWindowsStore())
+ {
+ // WindowsPhone and WindowsStore components are in an app container
+ // and produce WindowsMetadata. If we are not producing a WINRT
+ // component, then do not generate the metadata here.
+ linkOptions.AddFlag("GenerateWindowsMetadata", "false");
+ }
+
+ if (this->GlobalGenerator->TargetsWindowsPhone() &&
+ this->GlobalGenerator->GetSystemVersion() == "8.0")
+ {
+ // WindowsPhone 8.0 does not have ole32.
+ linkOptions.AppendFlag("IgnoreSpecificDefaultLibraries", "ole32.lib");
+ }
+ }
+ else if(this->NsightTegra)
+ {
+ linkOptions.AddFlag("SoName", targetNameSO.c_str());
+ }
- linkOptions.AddFlag("ImportLibrary", imLib.c_str());
- linkOptions.AddFlag("ProgramDataBaseFile", pdb.c_str());
linkOptions.Parse(flags.c_str());
- if(!this->GeneratorTarget->ModuleDefinitionFile.empty())
+
+ if(this->MSTools)
{
- linkOptions.AddFlag("ModuleDefinitionFile",
- this->GeneratorTarget->ModuleDefinitionFile.c_str());
+ if (cmSourceFile const* defsrc =
+ this->GeneratorTarget->GetModuleDefinitionFile(""))
+ {
+ linkOptions.AddFlag("ModuleDefinitionFile",
+ defsrc->GetFullPath().c_str());
+ }
+ linkOptions.AppendFlag("IgnoreSpecificDefaultLibraries",
+ "%(IgnoreSpecificDefaultLibraries)");
+ }
+
+ if (this->GeneratorTarget->GetType() == cmState::SHARED_LIBRARY &&
+ this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+ {
+ if (this->GeneratorTarget->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+ {
+ linkOptions.AddFlag("ModuleDefinitionFile", "$(IntDir)exportall.def");
+ }
+ }
+
+ // Hack to fix flag version selection in a common use case.
+ // FIXME: Select flag table based on toolset instead of VS version.
+ if (this->LocalGenerator->GetVersion() >=
+ cmGlobalVisualStudioGenerator::VS14)
+ {
+ cmGlobalVisualStudio10Generator* gg =
+ static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator);
+ const char* toolset = gg->GetPlatformToolset();
+ if (toolset &&
+ (cmHasLiteralPrefix(toolset, "v100") ||
+ cmHasLiteralPrefix(toolset, "v110") ||
+ cmHasLiteralPrefix(toolset, "v120")))
+ {
+ if (const char* debug = linkOptions.GetFlag("GenerateDebugInformation"))
+ {
+ // Convert value from enumeration back to boolean for older toolsets.
+ if (strcmp(debug, "No") == 0)
+ {
+ linkOptions.AddFlag("GenerateDebugInformation", "false");
+ }
+ else if (strcmp(debug, "Debug") == 0)
+ {
+ linkOptions.AddFlag("GenerateDebugInformation", "true");
+ }
+ }
+ }
}
this->LinkOptions[config] = pOptions.release();
@@ -1663,8 +2734,8 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
void
cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& config)
{
- if(this->Target->GetType() == cmTarget::STATIC_LIBRARY
- || this->Target->GetType() > cmTarget::MODULE_LIBRARY)
+ if(this->GeneratorTarget->GetType() == cmState::STATIC_LIBRARY
+ || this->GeneratorTarget->GetType() > cmState::MODULE_LIBRARY)
{
return;
}
@@ -1675,22 +2746,22 @@ cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& config)
linkOptions.OutputFlagMap(*this->BuildFileStream, " ");
this->WriteString("</Link>\n", 2);
- if(!this->GlobalGenerator->NeedLinkLibraryDependencies(*this->Target))
+ if(!this->GlobalGenerator->NeedLinkLibraryDependencies(
+ this->GeneratorTarget))
{
this->WriteString("<ProjectReference>\n", 2);
this->WriteString(
- " <LinkLibraryDependencies>false</LinkLibraryDependencies>\n", 2);
+ "<LinkLibraryDependencies>false</LinkLibraryDependencies>\n", 3);
this->WriteString("</ProjectReference>\n", 2);
}
}
void cmVisualStudio10TargetGenerator::AddLibraries(
cmComputeLinkInformation& cli,
- std::string& libstring)
+ std::vector<std::string>& libVec)
{
typedef cmComputeLinkInformation::ItemVector ItemVector;
ItemVector libs = cli.GetItems();
- const char* sep = ";";
for(ItemVector::const_iterator l = libs.begin(); l != libs.end(); ++l)
{
if(l->IsPath)
@@ -1700,13 +2771,12 @@ void cmVisualStudio10TargetGenerator::AddLibraries(
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::UNCHANGED);
this->ConvertToWindowsSlash(path);
- libstring += sep;
- libstring += path;
+ libVec.push_back(path);
}
- else
+ else if (!l->Target
+ || l->Target->GetType() != cmState::INTERFACE_LIBRARY)
{
- libstring += sep;
- libstring += l->Value;
+ libVec.push_back(l->Value);
}
}
}
@@ -1716,6 +2786,11 @@ void cmVisualStudio10TargetGenerator::
WriteMidlOptions(std::string const& /*config*/,
std::vector<std::string> const & includes)
{
+ if(!this->MSTools)
+ {
+ return;
+ }
+
// This processes *any* of the .idl files specified in the project's file
// list (and passed as the item metadata %(Filename) expressing the rule
// input filename) into output files at the per-config *build* dir
@@ -1732,8 +2807,16 @@ WriteMidlOptions(std::string const& /*config*/,
// only). Perhaps there's something to be done to make this more automatic
// on the CMake side?
this->WriteString("<Midl>\n", 2);
- this->OutputIncludes(includes);
- this->WriteString("<OutputDirectory>$(IntDir)</OutputDirectory>\n", 3);
+ this->WriteString("<AdditionalIncludeDirectories>", 3);
+ for(std::vector<std::string>::const_iterator i = includes.begin();
+ i != includes.end(); ++i)
+ {
+ *this->BuildFileStream << cmVS10EscapeXML(*i) << ";";
+ }
+ this->WriteString("%(AdditionalIncludeDirectories)"
+ "</AdditionalIncludeDirectories>\n", 0);
+ this->WriteString("<OutputDirectory>$(ProjectDir)/$(IntDir)"
+ "</OutputDirectory>\n", 3);
this->WriteString("<HeaderFileName>%(Filename).h</HeaderFileName>\n", 3);
this->WriteString(
"<TypeLibraryName>%(Filename).tlb</TypeLibraryName>\n", 3);
@@ -1747,24 +2830,28 @@ WriteMidlOptions(std::string const& /*config*/,
void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups()
{
- std::vector<std::string> *configs =
- static_cast<cmGlobalVisualStudio7Generator *>
- (this->GlobalGenerator)->GetConfigurations();
- for(std::vector<std::string>::iterator i = configs->begin();
- i != configs->end(); ++i)
+ for(std::vector<std::string>::const_iterator
+ i = this->Configurations.begin();
+ i != this->Configurations.end(); ++i)
{
std::vector<std::string> includes;
this->LocalGenerator->GetIncludeDirectories(includes,
this->GeneratorTarget,
"C", i->c_str());
+ for(std::vector<std::string>::iterator ii = includes.begin();
+ ii != includes.end(); ++ii)
+ {
+ this->ConvertToWindowsSlash(*ii);
+ }
this->WritePlatformConfigTag("ItemDefinitionGroup", i->c_str(), 1);
*this->BuildFileStream << "\n";
// output cl compile flags <ClCompile></ClCompile>
- if(this->Target->GetType() <= cmTarget::OBJECT_LIBRARY)
+ if(this->GeneratorTarget->GetType() <= cmState::OBJECT_LIBRARY)
{
this->WriteClOptions(*i, includes);
// output rc compile flags <ResourceCompile></ResourceCompile>
this->WriteRCOptions(*i, includes);
+ this->WriteMasmOptions(*i, includes);
}
// output midl flags <Midl></Midl>
this->WriteMidlOptions(*i, includes);
@@ -1774,6 +2861,14 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups()
this->WriteLinkOptions(*i);
// output lib flags <Lib></Lib>
this->WriteLibOptions(*i);
+ // output manifest flags <Manifest></Manifest>
+ this->WriteManifestOptions(*i);
+ if(this->NsightTegra &&
+ this->GeneratorTarget->GetType() == cmState::EXECUTABLE &&
+ this->GeneratorTarget->GetPropertyAsBool("ANDROID_GUI"))
+ {
+ this->WriteAntBuildOptions(*i);
+ }
this->WriteString("</ItemDefinitionGroup>\n", 1);
}
}
@@ -1781,20 +2876,37 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups()
void
cmVisualStudio10TargetGenerator::WriteEvents(std::string const& configName)
{
- this->WriteEvent("PreLinkEvent",
- this->Target->GetPreLinkCommands(), configName);
+ bool addedPrelink = false;
+ if (this->GeneratorTarget->GetType() == cmState::SHARED_LIBRARY &&
+ this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+ {
+ if (this->GeneratorTarget->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+ {
+ addedPrelink = true;
+ std::vector<cmCustomCommand> commands =
+ this->GeneratorTarget->GetPreLinkCommands();
+ this->GlobalGenerator->AddSymbolExportCommand(
+ this->GeneratorTarget, commands, configName);
+ this->WriteEvent("PreLinkEvent", commands, configName);
+ }
+ }
+ if (!addedPrelink)
+ {
+ this->WriteEvent("PreLinkEvent",
+ this->GeneratorTarget->GetPreLinkCommands(), configName);
+ }
this->WriteEvent("PreBuildEvent",
- this->Target->GetPreBuildCommands(), configName);
+ this->GeneratorTarget->GetPreBuildCommands(), configName);
this->WriteEvent("PostBuildEvent",
- this->Target->GetPostBuildCommands(), configName);
+ this->GeneratorTarget->GetPostBuildCommands(), configName);
}
void cmVisualStudio10TargetGenerator::WriteEvent(
const char* name,
- std::vector<cmCustomCommand> & commands,
+ std::vector<cmCustomCommand> const& commands,
std::string const& configName)
{
- if(commands.size() == 0)
+ if(commands.empty())
{
return;
}
@@ -1804,16 +2916,15 @@ void cmVisualStudio10TargetGenerator::WriteEvent(
std::string script;
const char* pre = "";
std::string comment;
- for(std::vector<cmCustomCommand>::iterator i = commands.begin();
+ for(std::vector<cmCustomCommand>::const_iterator i = commands.begin();
i != commands.end(); ++i)
{
- cmCustomCommand& command = *i;
+ cmCustomCommandGenerator ccg(*i, configName, this->LocalGenerator);
comment += pre;
- comment += lg->ConstructComment(command);
+ comment += lg->ConstructComment(ccg);
script += pre;
pre = "\n";
- script +=
- cmVS10EscapeXML(lg->ConstructScript(command, configName.c_str()));
+ script += cmVS10EscapeXML(lg->ConstructScript(ccg));
}
comment = cmVS10EscapeComment(comment);
this->WriteString("<Message>",3);
@@ -1829,24 +2940,28 @@ void cmVisualStudio10TargetGenerator::WriteEvent(
void cmVisualStudio10TargetGenerator::WriteProjectReferences()
{
cmGlobalGenerator::TargetDependSet const& unordered
- = this->GlobalGenerator->GetTargetDirectDepends(*this->Target);
+ = this->GlobalGenerator->GetTargetDirectDepends(this->GeneratorTarget);
typedef cmGlobalVisualStudioGenerator::OrderedTargetDependSet
OrderedTargetDependSet;
- OrderedTargetDependSet depends(unordered);
+ OrderedTargetDependSet depends(unordered, CMAKE_CHECK_BUILD_SYSTEM_TARGET);
this->WriteString("<ItemGroup>\n", 1);
for( OrderedTargetDependSet::const_iterator i = depends.begin();
i != depends.end(); ++i)
{
- cmTarget* dt = *i;
+ cmGeneratorTarget const* dt = *i;
+ if(dt->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ continue;
+ }
// skip fortran targets as they can not be processed by MSBuild
// the only reference will be in the .sln file
if(static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator)
- ->TargetIsFortranOnly(*dt))
+ ->TargetIsFortranOnly(dt))
{
continue;
}
this->WriteString("<ProjectReference Include=\"", 2);
- cmMakefile* mf = dt->GetMakefile();
+ cmLocalGenerator* lg = dt->GetLocalGenerator();
std::string name = dt->GetName();
std::string path;
const char* p = dt->GetProperty("EXTERNAL_MSPROJECT");
@@ -1856,12 +2971,12 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences()
}
else
{
- path = mf->GetStartOutputDirectory();
+ path = lg->GetCurrentBinaryDirectory();
path += "/";
path += dt->GetName();
path += ".vcxproj";
}
- (*this->BuildFileStream) << path << "\">\n";
+ (*this->BuildFileStream) << cmVS10EscapeXML(path) << "\">\n";
this->WriteString("<Project>", 3);
(*this->BuildFileStream)
<< this->GlobalGenerator->GetGUID(name.c_str())
@@ -1871,11 +2986,816 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences()
this->WriteString("</ItemGroup>\n", 1);
}
+void cmVisualStudio10TargetGenerator::WritePlatformExtensions()
+{
+ // This only applies to Windows 10 apps
+ if (this->GlobalGenerator->TargetsWindowsStore() &&
+ cmHasLiteralPrefix(this->GlobalGenerator->GetSystemVersion(), "10.0"))
+ {
+ const char* desktopExtensionsVersion =
+ this->GeneratorTarget->GetProperty("VS_DESKTOP_EXTENSIONS_VERSION");
+ if (desktopExtensionsVersion)
+ {
+ this->WriteSinglePlatformExtension("WindowsDesktop",
+ desktopExtensionsVersion);
+ }
+ const char* mobileExtensionsVersion =
+ this->GeneratorTarget->GetProperty("VS_MOBILE_EXTENSIONS_VERSION");
+ if (mobileExtensionsVersion)
+ {
+ this->WriteSinglePlatformExtension("WindowsMobile",
+ mobileExtensionsVersion);
+ }
+ }
+}
+
+void cmVisualStudio10TargetGenerator::WriteSinglePlatformExtension(
+ std::string const& extension,
+ std::string const& version
+ )
+{
+ this->WriteString("<Import Project=", 2);
+ (*this->BuildFileStream)
+ << "\"$([Microsoft.Build.Utilities.ToolLocationHelper]"
+ << "::GetPlatformExtensionSDKLocation(`"
+ << extension <<", Version=" << version
+ << "`, $(TargetPlatformIdentifier), $(TargetPlatformVersion), null, "
+ << "$(ExtensionSDKDirectoryRoot), null))"
+ << "\\DesignTime\\CommonConfiguration\\Neutral\\"
+ << extension << ".props\" "
+ << "Condition=\"exists('$("
+ << "[Microsoft.Build.Utilities.ToolLocationHelper]"
+ << "::GetPlatformExtensionSDKLocation(`"
+ << extension << ", Version=" << version
+ << "`, $(TargetPlatformIdentifier), $(TargetPlatformVersion), null, "
+ << "$(ExtensionSDKDirectoryRoot), null))"
+ << "\\DesignTime\\CommonConfiguration\\Neutral\\"
+ << extension << ".props')\" />\n";
+}
+
+void cmVisualStudio10TargetGenerator::WriteSDKReferences()
+{
+ // This only applies to Windows 10 apps
+ if (this->GlobalGenerator->TargetsWindowsStore() &&
+ cmHasLiteralPrefix(this->GlobalGenerator->GetSystemVersion(), "10.0"))
+ {
+ const char* desktopExtensionsVersion =
+ this->GeneratorTarget->GetProperty("VS_DESKTOP_EXTENSIONS_VERSION");
+ const char* mobileExtensionsVersion =
+ this->GeneratorTarget->GetProperty("VS_MOBILE_EXTENSIONS_VERSION");
+ const char* iotExtensionsVersion =
+ this->GeneratorTarget->GetProperty("VS_IOT_EXTENSIONS_VERSION");
+
+ if(desktopExtensionsVersion || mobileExtensionsVersion ||
+ iotExtensionsVersion)
+ {
+ this->WriteString("<ItemGroup>\n", 1);
+ if(desktopExtensionsVersion)
+ {
+ this->WriteSingleSDKReference("WindowsDesktop",
+ desktopExtensionsVersion);
+ }
+ if(mobileExtensionsVersion)
+ {
+ this->WriteSingleSDKReference("WindowsMobile",
+ mobileExtensionsVersion);
+ }
+ if(iotExtensionsVersion)
+ {
+ this->WriteSingleSDKReference("WindowsIoT",
+ iotExtensionsVersion);
+ }
+ this->WriteString("</ItemGroup>\n", 1);
+ }
+ }
+}
+
+void cmVisualStudio10TargetGenerator::WriteSingleSDKReference(
+ std::string const& extension,
+ std::string const& version
+ )
+{
+ this->WriteString("<SDKReference Include=\"", 2);
+ (*this->BuildFileStream) << extension
+ << ", Version=" << version << "\" />\n";
+}
+
+
+void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile()
+{
+ if((this->GlobalGenerator->TargetsWindowsStore() ||
+ this->GlobalGenerator->TargetsWindowsPhone())
+ && (cmState::EXECUTABLE == this->GeneratorTarget->GetType()))
+ {
+ std::string pfxFile;
+ std::vector<cmSourceFile const*> certificates;
+ this->GeneratorTarget->GetCertificates(certificates, "");
+ for(std::vector<cmSourceFile const*>::const_iterator si =
+ certificates.begin(); si != certificates.end(); ++si)
+ {
+ pfxFile = this->ConvertPath((*si)->GetFullPath(), false);
+ this->ConvertToWindowsSlash(pfxFile);
+ break;
+ }
+
+ if(this->IsMissingFiles &&
+ !(this->GlobalGenerator->TargetsWindowsPhone() &&
+ this->GlobalGenerator->GetSystemVersion() == "8.0"))
+ {
+ // Move the manifest to a project directory to avoid clashes
+ std::string artifactDir =
+ this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
+ this->ConvertToWindowsSlash(artifactDir);
+ this->WriteString("<PropertyGroup>\n", 1);
+ this->WriteString("<AppxPackageArtifactsDir>", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(artifactDir) <<
+ "\\</AppxPackageArtifactsDir>\n";
+ this->WriteString("<ProjectPriFullPath>"
+ "$(TargetDir)resources.pri</ProjectPriFullPath>\n", 2);
+
+ // If we are missing files and we don't have a certificate and
+ // aren't targeting WP8.0, add a default certificate
+ if(pfxFile.empty())
+ {
+ std::string templateFolder = cmSystemTools::GetCMakeRoot() +
+ "/Templates/Windows";
+ pfxFile = this->DefaultArtifactDir + "/Windows_TemporaryKey.pfx";
+ cmSystemTools::CopyAFile(templateFolder + "/Windows_TemporaryKey.pfx",
+ pfxFile, false);
+ this->ConvertToWindowsSlash(pfxFile);
+ this->AddedFiles.push_back(pfxFile);
+ }
+
+ this->WriteString("<", 2);
+ (*this->BuildFileStream) << "PackageCertificateKeyFile>"
+ << pfxFile << "</PackageCertificateKeyFile>\n";
+ std::string thumb = cmSystemTools::ComputeCertificateThumbprint(pfxFile);
+ if (!thumb.empty())
+ {
+ this->WriteString("<PackageCertificateThumbprint>", 2);
+ (*this->BuildFileStream) << thumb
+ << "</PackageCertificateThumbprint>\n";
+ }
+ this->WriteString("</PropertyGroup>\n", 1);
+ }
+ else if(!pfxFile.empty())
+ {
+ this->WriteString("<PropertyGroup>\n", 1);
+ this->WriteString("<", 2);
+ (*this->BuildFileStream) << "PackageCertificateKeyFile>"
+ << pfxFile << "</PackageCertificateKeyFile>\n";
+ std::string thumb = cmSystemTools::ComputeCertificateThumbprint(pfxFile);
+ if (!thumb.empty())
+ {
+ this->WriteString("<PackageCertificateThumbprint>", 2);
+ (*this->BuildFileStream) << thumb
+ << "</PackageCertificateThumbprint>\n";
+ }
+ this->WriteString("</PropertyGroup>\n", 1);
+ }
+ }
+}
+
bool cmVisualStudio10TargetGenerator::
IsResxHeader(const std::string& headerFile)
{
- std::set<std::string>::iterator it =
- this->GeneratorTarget->ExpectedResxHeaders.find(headerFile);
+ std::set<std::string> expectedResxHeaders;
+ this->GeneratorTarget->GetExpectedResxHeaders(expectedResxHeaders, "");
+
+ std::set<std::string>::const_iterator it =
+ expectedResxHeaders.find(headerFile);
+ return it != expectedResxHeaders.end();
+}
+
+bool cmVisualStudio10TargetGenerator::
+IsXamlHeader(const std::string& headerFile)
+{
+ std::set<std::string> expectedXamlHeaders;
+ this->GeneratorTarget->GetExpectedXamlHeaders(expectedXamlHeaders, "");
+
+ std::set<std::string>::const_iterator it =
+ expectedXamlHeaders.find(headerFile);
+ return it != expectedXamlHeaders.end();
+}
+
+bool cmVisualStudio10TargetGenerator::
+IsXamlSource(const std::string& sourceFile)
+{
+ std::set<std::string> expectedXamlSources;
+ this->GeneratorTarget->GetExpectedXamlSources(expectedXamlSources, "");
+
+ std::set<std::string>::const_iterator it =
+ expectedXamlSources.find(sourceFile);
+ return it != expectedXamlSources.end();
+}
+
+void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings()
+{
+ cmGlobalVisualStudio10Generator* gg =
+ static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator);
+ bool isAppContainer = false;
+ bool const isWindowsPhone = this->GlobalGenerator->TargetsWindowsPhone();
+ bool const isWindowsStore = this->GlobalGenerator->TargetsWindowsStore();
+ std::string const& v = this->GlobalGenerator->GetSystemVersion();
+ if(isWindowsPhone || isWindowsStore)
+ {
+ this->WriteString("<ApplicationType>", 2);
+ (*this->BuildFileStream) << (isWindowsPhone ?
+ "Windows Phone" : "Windows Store")
+ << "</ApplicationType>\n";
+ this->WriteString("<DefaultLanguage>en-US"
+ "</DefaultLanguage>\n", 2);
+ if (cmHasLiteralPrefix(v, "10.0"))
+ {
+ this->WriteString("<ApplicationTypeRevision>", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML("10.0")
+ << "</ApplicationTypeRevision>\n";
+ // Visual Studio 14.0 is necessary for building 10.0 apps
+ this->WriteString("<MinimumVisualStudioVersion>14.0"
+ "</MinimumVisualStudioVersion>\n", 2);
+
+ if(this->GeneratorTarget->GetType() < cmState::UTILITY)
+ {
+ isAppContainer = true;
+ }
+ }
+ else if(v == "8.1")
+ {
+ this->WriteString("<ApplicationTypeRevision>", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(v)
+ << "</ApplicationTypeRevision>\n";
+ // Visual Studio 12.0 is necessary for building 8.1 apps
+ this->WriteString("<MinimumVisualStudioVersion>12.0"
+ "</MinimumVisualStudioVersion>\n", 2);
+
+ if (this->GeneratorTarget->GetType() < cmState::UTILITY)
+ {
+ isAppContainer = true;
+ }
+ }
+ else if (v == "8.0")
+ {
+ this->WriteString("<ApplicationTypeRevision>", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(v)
+ << "</ApplicationTypeRevision>\n";
+ // Visual Studio 11.0 is necessary for building 8.0 apps
+ this->WriteString("<MinimumVisualStudioVersion>11.0"
+ "</MinimumVisualStudioVersion>\n", 2);
+
+ if (isWindowsStore
+ && this->GeneratorTarget->GetType() < cmState::UTILITY)
+ {
+ isAppContainer = true;
+ }
+ else if (isWindowsPhone &&
+ this->GeneratorTarget->GetType() == cmState::EXECUTABLE)
+ {
+ this->WriteString("<XapOutputs>true</XapOutputs>\n", 2);
+ this->WriteString("<XapFilename>", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(this->Name.c_str()) <<
+ "_$(Configuration)_$(Platform).xap</XapFilename>\n";
+ }
+ }
+ }
+ if(isAppContainer)
+ {
+ this->WriteString("<AppContainerApplication>true"
+ "</AppContainerApplication>\n", 2);
+ }
+ else if (this->Platform == "ARM")
+ {
+ this->WriteString("<WindowsSDKDesktopARMSupport>true"
+ "</WindowsSDKDesktopARMSupport>\n", 2);
+ }
+ std::string const& targetPlatformVersion =
+ gg->GetWindowsTargetPlatformVersion();
+ if (!targetPlatformVersion.empty())
+ {
+ this->WriteString("<WindowsTargetPlatformVersion>", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(targetPlatformVersion) <<
+ "</WindowsTargetPlatformVersion>\n";
+ }
+ const char* targetPlatformMinVersion =
+ this->GeneratorTarget
+ ->GetProperty("VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION");
+ if(targetPlatformMinVersion)
+ {
+ this->WriteString("<WindowsTargetPlatformMinVersion>", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(targetPlatformMinVersion) <<
+ "</WindowsTargetPlatformMinVersion>\n";
+ }
+ else if (isWindowsStore && cmHasLiteralPrefix(v, "10.0"))
+ {
+ // If the min version is not set, then use the TargetPlatformVersion
+ if (!targetPlatformVersion.empty())
+ {
+ this->WriteString("<WindowsTargetPlatformMinVersion>", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(targetPlatformVersion) <<
+ "</WindowsTargetPlatformMinVersion>\n";
+ }
+ }
+
+ // Added IoT Startup Task support
+ if(this->GeneratorTarget->GetPropertyAsBool("VS_IOT_STARTUP_TASK"))
+ {
+ this->WriteString("<ContainsStartupTask>true</ContainsStartupTask>\n", 2);
+ }
+}
+
+void cmVisualStudio10TargetGenerator::VerifyNecessaryFiles()
+{
+ // For Windows and Windows Phone executables, we will assume that if a
+ // manifest is not present that we need to add all the necessary files
+ if (this->GeneratorTarget->GetType() == cmState::EXECUTABLE)
+ {
+ std::vector<cmSourceFile const*> manifestSources;
+ this->GeneratorTarget->GetAppManifest(manifestSources, "");
+ {
+ std::string const& v = this->GlobalGenerator->GetSystemVersion();
+ if(this->GlobalGenerator->TargetsWindowsPhone())
+ {
+ if (v == "8.0")
+ {
+ // Look through the sources for WMAppManifest.xml
+ std::vector<cmSourceFile const*> extraSources;
+ this->GeneratorTarget->GetExtraSources(extraSources, "");
+ bool foundManifest = false;
+ for(std::vector<cmSourceFile const*>::const_iterator si =
+ extraSources.begin(); si != extraSources.end(); ++si)
+ {
+ // Need to do a lowercase comparison on the filename
+ if("wmappmanifest.xml" == cmSystemTools::LowerCase(
+ (*si)->GetLocation().GetName()))
+ {
+ foundManifest = true;
+ break;
+ }
+ }
+ if (!foundManifest)
+ {
+ this->IsMissingFiles = true;
+ }
+ }
+ else if (v == "8.1")
+ {
+ if(manifestSources.empty())
+ {
+ this->IsMissingFiles = true;
+ }
+ }
+ }
+ else if (this->GlobalGenerator->TargetsWindowsStore())
+ {
+ if (manifestSources.empty())
+ {
+ if (v == "8.0")
+ {
+ this->IsMissingFiles = true;
+ }
+ else if (v == "8.1" || cmHasLiteralPrefix(v, "10.0"))
+ {
+ this->IsMissingFiles = true;
+ }
+ }
+ }
+ }
+ }
+}
- return it != this->GeneratorTarget->ExpectedResxHeaders.end();
+void cmVisualStudio10TargetGenerator::WriteMissingFiles()
+{
+ std::string const& v = this->GlobalGenerator->GetSystemVersion();
+ if(this->GlobalGenerator->TargetsWindowsPhone())
+ {
+ if (v == "8.0")
+ {
+ this->WriteMissingFilesWP80();
+ }
+ else if (v == "8.1")
+ {
+ this->WriteMissingFilesWP81();
+ }
+ }
+ else if (this->GlobalGenerator->TargetsWindowsStore())
+ {
+ if (v == "8.0")
+ {
+ this->WriteMissingFilesWS80();
+ }
+ else if (v == "8.1")
+ {
+ this->WriteMissingFilesWS81();
+ }
+ else if (cmHasLiteralPrefix(v, "10.0"))
+ {
+ this->WriteMissingFilesWS10_0();
+ }
+ }
+}
+
+void cmVisualStudio10TargetGenerator::WriteMissingFilesWP80()
+{
+ std::string templateFolder = cmSystemTools::GetCMakeRoot() +
+ "/Templates/Windows";
+
+ // For WP80, the manifest needs to be in the same folder as the project
+ // this can cause an overwrite problem if projects aren't organized in
+ // folders
+ std::string manifestFile =
+ this->LocalGenerator->GetCurrentBinaryDirectory() +
+ std::string("/WMAppManifest.xml");
+ std::string artifactDir =
+ this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
+ this->ConvertToWindowsSlash(artifactDir);
+ std::string artifactDirXML = cmVS10EscapeXML(artifactDir);
+ std::string targetNameXML =
+ cmVS10EscapeXML(this->GeneratorTarget->GetName());
+
+ cmGeneratedFileStream fout(manifestFile.c_str());
+ fout.SetCopyIfDifferent(true);
+
+ fout <<
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<Deployment"
+ " xmlns=\"http://schemas.microsoft.com/windowsphone/2012/deployment\""
+ " AppPlatformVersion=\"8.0\">\n"
+ "\t<DefaultLanguage xmlns=\"\" code=\"en-US\"/>\n"
+ "\t<App xmlns=\"\" ProductID=\"{" << this->GUID << "}\""
+ " Title=\"CMake Test Program\" RuntimeType=\"Modern Native\""
+ " Version=\"1.0.0.0\" Genre=\"apps.normal\" Author=\"CMake\""
+ " Description=\"Default CMake App\" Publisher=\"CMake\""
+ " PublisherID=\"{" << this->GUID << "}\">\n"
+ "\t\t<IconPath IsRelative=\"true\" IsResource=\"false\">"
+ << artifactDirXML << "\\ApplicationIcon.png</IconPath>\n"
+ "\t\t<Capabilities/>\n"
+ "\t\t<Tasks>\n"
+ "\t\t\t<DefaultTask Name=\"_default\""
+ " ImagePath=\"" << targetNameXML << ".exe\" ImageParams=\"\" />\n"
+ "\t\t</Tasks>\n"
+ "\t\t<Tokens>\n"
+ "\t\t\t<PrimaryToken TokenID=\"" << targetNameXML << "Token\""
+ " TaskName=\"_default\">\n"
+ "\t\t\t\t<TemplateFlip>\n"
+ "\t\t\t\t\t<SmallImageURI IsRelative=\"true\" IsResource=\"false\">"
+ << artifactDirXML << "\\SmallLogo.png</SmallImageURI>\n"
+ "\t\t\t\t\t<Count>0</Count>\n"
+ "\t\t\t\t\t<BackgroundImageURI IsRelative=\"true\" IsResource=\"false\">"
+ << artifactDirXML << "\\Logo.png</BackgroundImageURI>\n"
+ "\t\t\t\t</TemplateFlip>\n"
+ "\t\t\t</PrimaryToken>\n"
+ "\t\t</Tokens>\n"
+ "\t\t<ScreenResolutions>\n"
+ "\t\t\t<ScreenResolution Name=\"ID_RESOLUTION_WVGA\" />\n"
+ "\t\t</ScreenResolutions>\n"
+ "\t</App>\n"
+ "</Deployment>\n";
+
+ std::string sourceFile = this->ConvertPath(manifestFile, false);
+ this->ConvertToWindowsSlash(sourceFile);
+ this->WriteString("<Xml Include=\"", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(sourceFile) << "\">\n";
+ this->WriteString("<SubType>Designer</SubType>\n", 3);
+ this->WriteString("</Xml>\n", 2);
+ this->AddedFiles.push_back(sourceFile);
+
+ std::string smallLogo = this->DefaultArtifactDir + "/SmallLogo.png";
+ cmSystemTools::CopyAFile(templateFolder + "/SmallLogo.png",
+ smallLogo, false);
+ this->ConvertToWindowsSlash(smallLogo);
+ this->WriteString("<Image Include=\"", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(smallLogo) << "\" />\n";
+ this->AddedFiles.push_back(smallLogo);
+
+ std::string logo = this->DefaultArtifactDir + "/Logo.png";
+ cmSystemTools::CopyAFile(templateFolder + "/Logo.png",
+ logo, false);
+ this->ConvertToWindowsSlash(logo);
+ this->WriteString("<Image Include=\"", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(logo) << "\" />\n";
+ this->AddedFiles.push_back(logo);
+
+ std::string applicationIcon =
+ this->DefaultArtifactDir + "/ApplicationIcon.png";
+ cmSystemTools::CopyAFile(templateFolder + "/ApplicationIcon.png",
+ applicationIcon, false);
+ this->ConvertToWindowsSlash(applicationIcon);
+ this->WriteString("<Image Include=\"", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(applicationIcon) << "\" />\n";
+ this->AddedFiles.push_back(applicationIcon);
+}
+
+void cmVisualStudio10TargetGenerator::WriteMissingFilesWP81()
+{
+ std::string manifestFile =
+ this->DefaultArtifactDir + "/package.appxManifest";
+ std::string artifactDir =
+ this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
+ this->ConvertToWindowsSlash(artifactDir);
+ std::string artifactDirXML = cmVS10EscapeXML(artifactDir);
+ std::string targetNameXML =
+ cmVS10EscapeXML(this->GeneratorTarget->GetName());
+
+ cmGeneratedFileStream fout(manifestFile.c_str());
+ fout.SetCopyIfDifferent(true);
+
+ fout <<
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<Package xmlns=\"http://schemas.microsoft.com/appx/2010/manifest\""
+ " xmlns:m2=\"http://schemas.microsoft.com/appx/2013/manifest\""
+ " xmlns:mp=\"http://schemas.microsoft.com/appx/2014/phone/manifest\">\n"
+ "\t<Identity Name=\"" << this->GUID << "\" Publisher=\"CN=CMake\""
+ " Version=\"1.0.0.0\" />\n"
+ "\t<mp:PhoneIdentity PhoneProductId=\"" << this->GUID << "\""
+ " PhonePublisherId=\"00000000-0000-0000-0000-000000000000\"/>\n"
+ "\t<Properties>\n"
+ "\t\t<DisplayName>" << targetNameXML << "</DisplayName>\n"
+ "\t\t<PublisherDisplayName>CMake</PublisherDisplayName>\n"
+ "\t\t<Logo>" << artifactDirXML << "\\StoreLogo.png</Logo>\n"
+ "\t</Properties>\n"
+ "\t<Prerequisites>\n"
+ "\t\t<OSMinVersion>6.3.1</OSMinVersion>\n"
+ "\t\t<OSMaxVersionTested>6.3.1</OSMaxVersionTested>\n"
+ "\t</Prerequisites>\n"
+ "\t<Resources>\n"
+ "\t\t<Resource Language=\"x-generate\" />\n"
+ "\t</Resources>\n"
+ "\t<Applications>\n"
+ "\t\t<Application Id=\"App\""
+ " Executable=\"" << targetNameXML << ".exe\""
+ " EntryPoint=\"" << targetNameXML << ".App\">\n"
+ "\t\t\t<m2:VisualElements\n"
+ "\t\t\t\tDisplayName=\"" << targetNameXML << "\"\n"
+ "\t\t\t\tDescription=\"" << targetNameXML << "\"\n"
+ "\t\t\t\tBackgroundColor=\"#336699\"\n"
+ "\t\t\t\tForegroundText=\"light\"\n"
+ "\t\t\t\tSquare150x150Logo=\"" << artifactDirXML << "\\Logo.png\"\n"
+ "\t\t\t\tSquare30x30Logo=\"" << artifactDirXML << "\\SmallLogo.png\">\n"
+ "\t\t\t\t<m2:DefaultTile ShortName=\"" << targetNameXML << "\">\n"
+ "\t\t\t\t\t<m2:ShowNameOnTiles>\n"
+ "\t\t\t\t\t\t<m2:ShowOn Tile=\"square150x150Logo\" />\n"
+ "\t\t\t\t\t</m2:ShowNameOnTiles>\n"
+ "\t\t\t\t</m2:DefaultTile>\n"
+ "\t\t\t\t<m2:SplashScreen"
+ " Image=\"" << artifactDirXML << "\\SplashScreen.png\" />\n"
+ "\t\t\t</m2:VisualElements>\n"
+ "\t\t</Application>\n"
+ "\t</Applications>\n"
+ "</Package>\n";
+
+ this->WriteCommonMissingFiles(manifestFile);
+}
+
+void cmVisualStudio10TargetGenerator::WriteMissingFilesWS80()
+{
+ std::string manifestFile =
+ this->DefaultArtifactDir + "/package.appxManifest";
+ std::string artifactDir =
+ this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
+ this->ConvertToWindowsSlash(artifactDir);
+ std::string artifactDirXML = cmVS10EscapeXML(artifactDir);
+ std::string targetNameXML =
+ cmVS10EscapeXML(this->GeneratorTarget->GetName());
+
+ cmGeneratedFileStream fout(manifestFile.c_str());
+ fout.SetCopyIfDifferent(true);
+
+ fout <<
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<Package xmlns=\"http://schemas.microsoft.com/appx/2010/manifest\">\n"
+ "\t<Identity Name=\"" << this->GUID << "\" Publisher=\"CN=CMake\""
+ " Version=\"1.0.0.0\" />\n"
+ "\t<Properties>\n"
+ "\t\t<DisplayName>" << targetNameXML << "</DisplayName>\n"
+ "\t\t<PublisherDisplayName>CMake</PublisherDisplayName>\n"
+ "\t\t<Logo>" << artifactDirXML << "\\StoreLogo.png</Logo>\n"
+ "\t</Properties>\n"
+ "\t<Prerequisites>\n"
+ "\t\t<OSMinVersion>6.2.1</OSMinVersion>\n"
+ "\t\t<OSMaxVersionTested>6.2.1</OSMaxVersionTested>\n"
+ "\t</Prerequisites>\n"
+ "\t<Resources>\n"
+ "\t\t<Resource Language=\"x-generate\" />\n"
+ "\t</Resources>\n"
+ "\t<Applications>\n"
+ "\t\t<Application Id=\"App\""
+ " Executable=\"" << targetNameXML << ".exe\""
+ " EntryPoint=\"" << targetNameXML << ".App\">\n"
+ "\t\t\t<VisualElements"
+ " DisplayName=\"" << targetNameXML << "\""
+ " Description=\"" << targetNameXML << "\""
+ " BackgroundColor=\"#336699\" ForegroundText=\"light\""
+ " Logo=\"" << artifactDirXML << "\\Logo.png\""
+ " SmallLogo=\"" << artifactDirXML << "\\SmallLogo.png\">\n"
+ "\t\t\t\t<DefaultTile ShowName=\"allLogos\""
+ " ShortName=\"" << targetNameXML << "\" />\n"
+ "\t\t\t\t<SplashScreen"
+ " Image=\"" << artifactDirXML << "\\SplashScreen.png\" />\n"
+ "\t\t\t</VisualElements>\n"
+ "\t\t</Application>\n"
+ "\t</Applications>\n"
+ "</Package>\n";
+
+ this->WriteCommonMissingFiles(manifestFile);
+}
+
+void cmVisualStudio10TargetGenerator::WriteMissingFilesWS81()
+{
+ std::string manifestFile =
+ this->DefaultArtifactDir + "/package.appxManifest";
+ std::string artifactDir =
+ this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
+ this->ConvertToWindowsSlash(artifactDir);
+ std::string artifactDirXML = cmVS10EscapeXML(artifactDir);
+ std::string targetNameXML =
+ cmVS10EscapeXML(this->GeneratorTarget->GetName());
+
+ cmGeneratedFileStream fout(manifestFile.c_str());
+ fout.SetCopyIfDifferent(true);
+
+ fout <<
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<Package xmlns=\"http://schemas.microsoft.com/appx/2010/manifest\""
+ " xmlns:m2=\"http://schemas.microsoft.com/appx/2013/manifest\">\n"
+ "\t<Identity Name=\"" << this->GUID << "\" Publisher=\"CN=CMake\""
+ " Version=\"1.0.0.0\" />\n"
+ "\t<Properties>\n"
+ "\t\t<DisplayName>" << targetNameXML << "</DisplayName>\n"
+ "\t\t<PublisherDisplayName>CMake</PublisherDisplayName>\n"
+ "\t\t<Logo>" << artifactDirXML << "\\StoreLogo.png</Logo>\n"
+ "\t</Properties>\n"
+ "\t<Prerequisites>\n"
+ "\t\t<OSMinVersion>6.3</OSMinVersion>\n"
+ "\t\t<OSMaxVersionTested>6.3</OSMaxVersionTested>\n"
+ "\t</Prerequisites>\n"
+ "\t<Resources>\n"
+ "\t\t<Resource Language=\"x-generate\" />\n"
+ "\t</Resources>\n"
+ "\t<Applications>\n"
+ "\t\t<Application Id=\"App\""
+ " Executable=\"" << targetNameXML << ".exe\""
+ " EntryPoint=\"" << targetNameXML << ".App\">\n"
+ "\t\t\t<m2:VisualElements\n"
+ "\t\t\t\tDisplayName=\"" << targetNameXML << "\"\n"
+ "\t\t\t\tDescription=\"" << targetNameXML << "\"\n"
+ "\t\t\t\tBackgroundColor=\"#336699\"\n"
+ "\t\t\t\tForegroundText=\"light\"\n"
+ "\t\t\t\tSquare150x150Logo=\"" << artifactDirXML << "\\Logo.png\"\n"
+ "\t\t\t\tSquare30x30Logo=\"" << artifactDirXML << "\\SmallLogo.png\">\n"
+ "\t\t\t\t<m2:DefaultTile ShortName=\"" << targetNameXML << "\">\n"
+ "\t\t\t\t\t<m2:ShowNameOnTiles>\n"
+ "\t\t\t\t\t\t<m2:ShowOn Tile=\"square150x150Logo\" />\n"
+ "\t\t\t\t\t</m2:ShowNameOnTiles>\n"
+ "\t\t\t\t</m2:DefaultTile>\n"
+ "\t\t\t\t<m2:SplashScreen"
+ " Image=\"" << artifactDirXML << "\\SplashScreen.png\" />\n"
+ "\t\t\t</m2:VisualElements>\n"
+ "\t\t</Application>\n"
+ "\t</Applications>\n"
+ "</Package>\n";
+
+ this->WriteCommonMissingFiles(manifestFile);
+}
+
+void cmVisualStudio10TargetGenerator::WriteMissingFilesWS10_0()
+{
+ std::string manifestFile =
+ this->DefaultArtifactDir + "/package.appxManifest";
+ std::string artifactDir =
+ this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
+ this->ConvertToWindowsSlash(artifactDir);
+ std::string artifactDirXML = cmVS10EscapeXML(artifactDir);
+ std::string targetNameXML =
+ cmVS10EscapeXML(this->GeneratorTarget->GetName());
+
+ cmGeneratedFileStream fout(manifestFile.c_str());
+ fout.SetCopyIfDifferent(true);
+
+ fout <<
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<Package\n\t"
+ "xmlns=\"http://schemas.microsoft.com/appx/manifest/foundation/windows10\""
+ "\txmlns:mp=\"http://schemas.microsoft.com/appx/2014/phone/manifest\"\n"
+ "\txmlns:uap=\"http://schemas.microsoft.com/appx/manifest/uap/windows10\""
+ "\n\tIgnorableNamespaces=\"uap mp\">\n\n"
+ "\t<Identity Name=\"" << this->GUID << "\" Publisher=\"CN=CMake\""
+ " Version=\"1.0.0.0\" />\n"
+ "\t<mp:PhoneIdentity PhoneProductId=\"" << this->GUID <<
+ "\" PhonePublisherId=\"00000000-0000-0000-0000-000000000000\"/>\n"
+ "\t<Properties>\n"
+ "\t\t<DisplayName>" << targetNameXML << "</DisplayName>\n"
+ "\t\t<PublisherDisplayName>CMake</PublisherDisplayName>\n"
+ "\t\t<Logo>" << artifactDirXML << "\\StoreLogo.png</Logo>\n"
+ "\t</Properties>\n"
+ "\t<Dependencies>\n"
+ "\t\t<TargetDeviceFamily Name=\"Windows.Universal\" "
+ "MinVersion=\"10.0.0.0\" MaxVersionTested=\"10.0.0.0\" />\n"
+ "\t</Dependencies>\n"
+
+ "\t<Resources>\n"
+ "\t\t<Resource Language=\"x-generate\" />\n"
+ "\t</Resources>\n"
+ "\t<Applications>\n"
+ "\t\t<Application Id=\"App\""
+ " Executable=\"" << targetNameXML << ".exe\""
+ " EntryPoint=\"" << targetNameXML << ".App\">\n"
+ "\t\t\t<uap:VisualElements\n"
+ "\t\t\t\tDisplayName=\"" << targetNameXML << "\"\n"
+ "\t\t\t\tDescription=\"" << targetNameXML << "\"\n"
+ "\t\t\t\tBackgroundColor=\"#336699\"\n"
+ "\t\t\t\tSquare150x150Logo=\"" << artifactDirXML << "\\Logo.png\"\n"
+ "\t\t\t\tSquare44x44Logo=\"" << artifactDirXML <<
+ "\\SmallLogo44x44.png\">\n"
+ "\t\t\t\t<uap:SplashScreen"
+ " Image=\"" << artifactDirXML << "\\SplashScreen.png\" />\n"
+ "\t\t\t</uap:VisualElements>\n"
+ "\t\t</Application>\n"
+ "\t</Applications>\n"
+ "</Package>\n";
+
+ this->WriteCommonMissingFiles(manifestFile);
+}
+
+void
+cmVisualStudio10TargetGenerator
+::WriteCommonMissingFiles(const std::string& manifestFile)
+{
+ std::string templateFolder = cmSystemTools::GetCMakeRoot() +
+ "/Templates/Windows";
+
+ std::string sourceFile = this->ConvertPath(manifestFile, false);
+ this->ConvertToWindowsSlash(sourceFile);
+ this->WriteString("<AppxManifest Include=\"", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(sourceFile) << "\">\n";
+ this->WriteString("<SubType>Designer</SubType>\n", 3);
+ this->WriteString("</AppxManifest>\n", 2);
+ this->AddedFiles.push_back(sourceFile);
+
+ std::string smallLogo = this->DefaultArtifactDir + "/SmallLogo.png";
+ cmSystemTools::CopyAFile(templateFolder + "/SmallLogo.png",
+ smallLogo, false);
+ this->ConvertToWindowsSlash(smallLogo);
+ this->WriteString("<Image Include=\"", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(smallLogo) << "\" />\n";
+ this->AddedFiles.push_back(smallLogo);
+
+ std::string smallLogo44 = this->DefaultArtifactDir + "/SmallLogo44x44.png";
+ cmSystemTools::CopyAFile(templateFolder + "/SmallLogo44x44.png",
+ smallLogo44, false);
+ this->ConvertToWindowsSlash(smallLogo44);
+ this->WriteString("<Image Include=\"", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(smallLogo44) << "\" />\n";
+ this->AddedFiles.push_back(smallLogo44);
+
+ std::string logo = this->DefaultArtifactDir + "/Logo.png";
+ cmSystemTools::CopyAFile(templateFolder + "/Logo.png",
+ logo, false);
+ this->ConvertToWindowsSlash(logo);
+ this->WriteString("<Image Include=\"", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(logo) << "\" />\n";
+ this->AddedFiles.push_back(logo);
+
+ std::string storeLogo = this->DefaultArtifactDir + "/StoreLogo.png";
+ cmSystemTools::CopyAFile(templateFolder + "/StoreLogo.png",
+ storeLogo, false);
+ this->ConvertToWindowsSlash(storeLogo);
+ this->WriteString("<Image Include=\"", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(storeLogo) << "\" />\n";
+ this->AddedFiles.push_back(storeLogo);
+
+ std::string splashScreen = this->DefaultArtifactDir + "/SplashScreen.png";
+ cmSystemTools::CopyAFile(templateFolder + "/SplashScreen.png",
+ splashScreen, false);
+ this->ConvertToWindowsSlash(splashScreen);
+ this->WriteString("<Image Include=\"", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(splashScreen) << "\" />\n";
+ this->AddedFiles.push_back(splashScreen);
+
+ // This file has already been added to the build so don't copy it
+ std::string keyFile = this->DefaultArtifactDir + "/Windows_TemporaryKey.pfx";
+ this->ConvertToWindowsSlash(keyFile);
+ this->WriteString("<None Include=\"", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(keyFile) << "\" />\n";
+}
+
+bool cmVisualStudio10TargetGenerator::ForceOld(const std::string& source) const
+{
+ HANDLE h = CreateFileW(
+ cmSystemTools::ConvertToWindowsExtendedPath(source).c_str(),
+ FILE_WRITE_ATTRIBUTES,
+ FILE_SHARE_WRITE, 0, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS, 0);
+ if (!h)
+ {
+ return false;
+ }
+
+ FILETIME const ftime_20010101 = { 3365781504u, 29389701u };
+ if (!SetFileTime(h, &ftime_20010101, &ftime_20010101, &ftime_20010101))
+ {
+ CloseHandle(h);
+ return false;
+ }
+
+ CloseHandle(h);
+ return true;
}
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 9a480a87f..044e0ddee 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -13,7 +13,6 @@
#define cmVisualStudioTargetGenerator_h
#include "cmStandardIncludes.h"
-class cmTarget;
class cmMakefile;
class cmGeneratorTarget;
class cmGeneratedFileStream;
@@ -23,19 +22,20 @@ class cmCustomCommand;
class cmLocalVisualStudio7Generator;
class cmComputeLinkInformation;
class cmVisualStudioGeneratorOptions;
+struct cmIDEFlagTable;
#include "cmSourceGroup.h"
class cmVisualStudio10TargetGenerator
{
public:
- cmVisualStudio10TargetGenerator(cmTarget* target,
+ cmVisualStudio10TargetGenerator(cmGeneratorTarget* target,
cmGlobalVisualStudio10Generator* gg);
~cmVisualStudio10TargetGenerator();
void Generate();
// used by cmVisualStudioGeneratorOptions
void WritePlatformConfigTag(
const char* tag,
- const char* config,
+ const std::string& config,
int indentLevel,
const char* attribute = 0,
const char* end = 0,
@@ -45,7 +45,7 @@ public:
private:
struct ToolSource
{
- cmSourceFile* SourceFile;
+ cmSourceFile const* SourceFile;
bool RelativePath;
};
struct ToolSources: public std::vector<ToolSource> {};
@@ -55,64 +55,116 @@ private:
void WriteString(const char* line, int indentLevel);
void WriteProjectConfigurations();
void WriteProjectConfigurationValues();
- void WriteSource(const char* tool, cmSourceFile* sf, const char* end = 0);
- void WriteSources(const char* tool, std::vector<cmSourceFile*> const&);
+ void WriteMSToolConfigurationValues(std::string const& config);
+ void WriteHeaderSource(cmSourceFile const* sf);
+ void WriteExtraSource(cmSourceFile const* sf);
+ void WriteNsightTegraConfigurationValues(std::string const& config);
+ void WriteSource(std::string const& tool, cmSourceFile const* sf,
+ const char* end = 0);
+ void WriteSources(std::string const& tool,
+ std::vector<cmSourceFile const*> const&);
void WriteAllSources();
void WriteDotNetReferences();
void WriteEmbeddedResourceGroup();
void WriteWinRTReferences();
+ void WriteWinRTPackageCertificateKeyFile();
+ void WriteXamlFilesGroup();
void WritePathAndIncrementalLinkOptions();
void WriteItemDefinitionGroups();
+ void VerifyNecessaryFiles();
+ void WriteMissingFiles();
+ void WriteMissingFilesWP80();
+ void WriteMissingFilesWP81();
+ void WriteMissingFilesWS80();
+ void WriteMissingFilesWS81();
+ void WriteMissingFilesWS10_0();
+ void WritePlatformExtensions();
+ void WriteSinglePlatformExtension(std::string const& extension,
+ std::string const& version);
+ void WriteSDKReferences();
+ void WriteSingleSDKReference(std::string const& extension,
+ std::string const& version);
+ void WriteCommonMissingFiles(const std::string& manifestFile);
+ void WriteTargetSpecificReferences();
bool ComputeClOptions();
bool ComputeClOptions(std::string const& configName);
void WriteClOptions(std::string const& config,
std::vector<std::string> const & includes);
+ bool ComputeRcOptions();
+ bool ComputeRcOptions(std::string const& config);
void WriteRCOptions(std::string const& config,
std::vector<std::string> const & includes);
+ bool ComputeMasmOptions();
+ bool ComputeMasmOptions(std::string const& config);
+ void WriteMasmOptions(std::string const& config,
+ std::vector<std::string> const& includes);
bool ComputeLinkOptions();
bool ComputeLinkOptions(std::string const& config);
void WriteLinkOptions(std::string const& config);
void WriteMidlOptions(std::string const& config,
std::vector<std::string> const & includes);
- void OutputIncludes(std::vector<std::string> const & includes);
+ void WriteAntBuildOptions(std::string const& config);
void OutputLinkIncremental(std::string const& configName);
- void WriteCustomRule(cmSourceFile* source,
+ void WriteCustomRule(cmSourceFile const* source,
cmCustomCommand const & command);
void WriteCustomCommands();
- void WriteCustomCommand(cmSourceFile* sf);
+ void WriteCustomCommand(cmSourceFile const* sf);
void WriteGroups();
void WriteProjectReferences();
- bool OutputSourceSpecificFlags(cmSourceFile* source);
- void AddLibraries(cmComputeLinkInformation& cli, std::string& libstring);
+ void WriteApplicationTypeSettings();
+ bool OutputSourceSpecificFlags(cmSourceFile const* source);
+ void AddLibraries(cmComputeLinkInformation& cli,
+ std::vector<std::string>& libVec);
void WriteLibOptions(std::string const& config);
+ void WriteManifestOptions(std::string const& config);
void WriteEvents(std::string const& configName);
- void WriteEvent(const char* name, std::vector<cmCustomCommand> & commands,
+ void WriteEvent(const char* name,
+ std::vector<cmCustomCommand> const& commands,
std::string const& configName);
void WriteGroupSources(const char* name, ToolSources const& sources,
std::vector<cmSourceGroup>& );
void AddMissingSourceGroups(std::set<cmSourceGroup*>& groupsUsed,
const std::vector<cmSourceGroup>& allGroups);
bool IsResxHeader(const std::string& headerFile);
+ bool IsXamlHeader(const std::string& headerFile);
+ bool IsXamlSource(const std::string& headerFile);
+
+ cmIDEFlagTable const* GetClFlagTable() const;
+ cmIDEFlagTable const* GetRcFlagTable() const;
+ cmIDEFlagTable const* GetLibFlagTable() const;
+ cmIDEFlagTable const* GetLinkFlagTable() const;
+ cmIDEFlagTable const* GetMasmFlagTable() const;
+
+ bool ForceOld(const std::string& source) const;
private:
typedef cmVisualStudioGeneratorOptions Options;
- typedef std::map<cmStdString, Options*> OptionsMap;
+ typedef std::map<std::string, Options*> OptionsMap;
OptionsMap ClOptions;
+ OptionsMap RcOptions;
+ OptionsMap MasmOptions;
OptionsMap LinkOptions;
std::string PathToVcxproj;
- cmTarget* Target;
+ std::vector<std::string> Configurations;
cmGeneratorTarget* GeneratorTarget;
cmMakefile* Makefile;
std::string Platform;
std::string GUID;
std::string Name;
+ bool MSTools;
+ bool NsightTegra;
+ int NsightTegraVersion[4];
+ bool TargetCompileAsWinRT;
cmGlobalVisualStudio10Generator* GlobalGenerator;
cmGeneratedFileStream* BuildFileStream;
cmLocalVisualStudio7Generator* LocalGenerator;
- std::set<cmSourceFile*> SourcesVisited;
+ std::set<cmSourceFile const*> SourcesVisited;
+ bool IsMissingFiles;
+ std::vector<std::string> AddedFiles;
+ std::string DefaultArtifactDir;
- typedef std::map<cmStdString, ToolSources> ToolSourceMap;
+ typedef std::map<std::string, ToolSources> ToolSourceMap;
ToolSourceMap Tools;
};
diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx
index 6aca787f5..bd4eb6986 100644
--- a/Source/cmVisualStudioGeneratorOptions.cxx
+++ b/Source/cmVisualStudioGeneratorOptions.cxx
@@ -1,11 +1,11 @@
#include "cmVisualStudioGeneratorOptions.h"
+#include "cmOutputConverter.h"
#include "cmSystemTools.h"
-#include <cmsys/System.h>
#include "cmVisualStudio10TargetGenerator.h"
-inline std::string cmVisualStudio10GeneratorOptionsEscapeForXML(const char* s)
+static
+std::string cmVisualStudio10GeneratorOptionsEscapeForXML(std::string ret)
{
- std::string ret = s;
cmSystemTools::ReplaceString(ret, ";", "%3B");
cmSystemTools::ReplaceString(ret, "&", "&amp;");
cmSystemTools::ReplaceString(ret, "<", "&lt;");
@@ -13,9 +13,9 @@ inline std::string cmVisualStudio10GeneratorOptionsEscapeForXML(const char* s)
return ret;
}
-inline std::string cmVisualStudioGeneratorOptionsEscapeForXML(const char* s)
+static
+std::string cmVisualStudioGeneratorOptionsEscapeForXML(std::string ret)
{
- std::string ret = s;
cmSystemTools::ReplaceString(ret, "&", "&amp;");
cmSystemTools::ReplaceString(ret, "\"", "&quot;");
cmSystemTools::ReplaceString(ret, "<", "&lt;");
@@ -28,6 +28,26 @@ inline std::string cmVisualStudioGeneratorOptionsEscapeForXML(const char* s)
cmVisualStudioGeneratorOptions
::cmVisualStudioGeneratorOptions(cmLocalVisualStudioGenerator* lg,
Tool tool,
+ cmVisualStudio10TargetGenerator* g):
+ cmIDEOptions(),
+ LocalGenerator(lg), Version(lg->GetVersion()), CurrentTool(tool),
+ TargetGenerator(g)
+{
+ // Preprocessor definitions are not allowed for linker tools.
+ this->AllowDefine = (tool != Linker);
+
+ // Slash options are allowed for VS.
+ this->AllowSlash = true;
+
+ this->FortranRuntimeDebug = false;
+ this->FortranRuntimeDLL = false;
+ this->FortranRuntimeMT = false;
+}
+
+//----------------------------------------------------------------------------
+cmVisualStudioGeneratorOptions
+::cmVisualStudioGeneratorOptions(cmLocalVisualStudioGenerator* lg,
+ Tool tool,
cmVS7FlagTable const* table,
cmVS7FlagTable const* extraTable,
cmVisualStudio10TargetGenerator* g):
@@ -36,9 +56,8 @@ cmVisualStudioGeneratorOptions
TargetGenerator(g)
{
// Store the given flag tables.
- cmIDEFlagTable const** ft = this->FlagTable;
- if(table) { *ft++ = table; }
- if(extraTable) { *ft++ = extraTable; }
+ this->AddTable(table);
+ this->AddTable(extraTable);
// Preprocessor definitions are not allowed for linker tools.
this->AllowDefine = (tool != Linker);
@@ -52,6 +71,22 @@ cmVisualStudioGeneratorOptions
}
//----------------------------------------------------------------------------
+void cmVisualStudioGeneratorOptions::AddTable(cmVS7FlagTable const* table)
+{
+ if(table)
+ {
+ for(int i=0; i < FlagTableCount; ++i)
+ {
+ if (!this->FlagTable[i])
+ {
+ this->FlagTable[i] = table;
+ break;
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
void cmVisualStudioGeneratorOptions::FixExceptionHandlingDefault()
{
// Exception handling is on by default because the platform file has
@@ -61,13 +96,14 @@ void cmVisualStudioGeneratorOptions::FixExceptionHandlingDefault()
// remove the flag we need to override the IDE default of on.
switch (this->Version)
{
- case cmLocalVisualStudioGenerator::VS7:
- case cmLocalVisualStudioGenerator::VS71:
+ case cmGlobalVisualStudioGenerator::VS7:
+ case cmGlobalVisualStudioGenerator::VS71:
this->FlagMap["ExceptionHandling"] = "FALSE";
break;
- case cmLocalVisualStudioGenerator::VS10:
- case cmLocalVisualStudioGenerator::VS11:
- case cmLocalVisualStudioGenerator::VS12:
+ case cmGlobalVisualStudioGenerator::VS10:
+ case cmGlobalVisualStudioGenerator::VS11:
+ case cmGlobalVisualStudioGenerator::VS12:
+ case cmGlobalVisualStudioGenerator::VS14:
// by default VS puts <ExceptionHandling></ExceptionHandling> empty
// for a project, to make our projects look the same put a new line
// and space over for the closing </ExceptionHandling> as the default
@@ -96,7 +132,7 @@ void cmVisualStudioGeneratorOptions::SetVerboseMakefile(bool verbose)
this->FlagMap.find("SuppressStartupBanner") == this->FlagMap.end())
{
this->FlagMap["SuppressStartupBanner"] =
- this->Version < cmLocalVisualStudioGenerator::VS10 ? "FALSE" : "";
+ this->Version < cmGlobalVisualStudioGenerator::VS10 ? "FALSE" : "";
}
}
@@ -106,6 +142,12 @@ bool cmVisualStudioGeneratorOptions::IsDebug() const
}
//----------------------------------------------------------------------------
+bool cmVisualStudioGeneratorOptions::IsWinRt() const
+{
+ return this->FlagMap.find("CompileAsWinRT") != this->FlagMap.end();
+}
+
+//----------------------------------------------------------------------------
bool cmVisualStudioGeneratorOptions::UsingUnicode() const
{
// Look for the a _UNICODE definition.
@@ -204,10 +246,10 @@ void cmVisualStudioGeneratorOptions::StoreUnknownFlag(const char* flag)
// This option is not known. Store it in the output flags.
this->FlagString += " ";
this->FlagString +=
- cmSystemTools::EscapeWindowsShellArgument(
+ cmOutputConverter::EscapeWindowsShellArgument(
flag,
- cmsysSystem_Shell_Flag_AllowMakeVariables |
- cmsysSystem_Shell_Flag_VSIDE);
+ cmOutputConverter::Shell_Flag_AllowMakeVariables |
+ cmOutputConverter::Shell_Flag_VSIDE);
}
//----------------------------------------------------------------------------
@@ -222,17 +264,17 @@ cmVisualStudioGeneratorOptions
::OutputPreprocessorDefinitions(std::ostream& fout,
const char* prefix,
const char* suffix,
- const char* lang)
+ const std::string& lang)
{
if(this->Defines.empty())
{
return;
}
- if(this->Version >= cmLocalVisualStudioGenerator::VS10)
+ if(this->Version >= cmGlobalVisualStudioGenerator::VS10)
{
// if there are configuration specific flags, then
// use the configuration specific tag for PreprocessorDefinitions
- if(this->Configuration.size())
+ if(!this->Configuration.empty())
{
fout << prefix;
this->TargetGenerator->WritePlatformConfigTag(
@@ -256,7 +298,7 @@ cmVisualStudioGeneratorOptions
{
// Escape the definition for the compiler.
std::string define;
- if(this->Version < cmLocalVisualStudioGenerator::VS10)
+ if(this->Version < cmGlobalVisualStudioGenerator::VS10)
{
define =
this->LocalGenerator->EscapeForShell(di->c_str(), true);
@@ -266,24 +308,24 @@ cmVisualStudioGeneratorOptions
define = *di;
}
// Escape this flag for the IDE.
- if(this->Version >= cmLocalVisualStudioGenerator::VS10)
+ if(this->Version >= cmGlobalVisualStudioGenerator::VS10)
{
- define = cmVisualStudio10GeneratorOptionsEscapeForXML(define.c_str());
+ define = cmVisualStudio10GeneratorOptionsEscapeForXML(define);
- if(0 == strcmp(lang, "RC"))
+ if(lang == "RC")
{
cmSystemTools::ReplaceString(define, "\"", "\\\"");
}
}
else
{
- define = cmVisualStudioGeneratorOptionsEscapeForXML(define.c_str());
+ define = cmVisualStudioGeneratorOptionsEscapeForXML(define);
}
// Store the flag in the project file.
fout << sep << define;
sep = ";";
}
- if(this->Version >= cmLocalVisualStudioGenerator::VS10)
+ if(this->Version >= cmGlobalVisualStudioGenerator::VS10)
{
fout << ";%(PreprocessorDefinitions)</PreprocessorDefinitions>" << suffix;
}
@@ -298,13 +340,13 @@ void
cmVisualStudioGeneratorOptions
::OutputFlagMap(std::ostream& fout, const char* indent)
{
- if(this->Version >= cmLocalVisualStudioGenerator::VS10)
+ if(this->Version >= cmGlobalVisualStudioGenerator::VS10)
{
- for(std::map<cmStdString, cmStdString>::iterator m = this->FlagMap.begin();
+ for(std::map<std::string, FlagValue>::iterator m = this->FlagMap.begin();
m != this->FlagMap.end(); ++m)
{
fout << indent;
- if(this->Configuration.size())
+ if(!this->Configuration.empty())
{
this->TargetGenerator->WritePlatformConfigTag(
m->first.c_str(),
@@ -316,20 +358,30 @@ cmVisualStudioGeneratorOptions
{
fout << "<" << m->first << ">";
}
- fout << m->second;
- if (m->first == "AdditionalIncludeDirectories")
+ const char* sep = "";
+ for(std::vector<std::string>::iterator i = m->second.begin();
+ i != m->second.end(); ++i)
{
- fout << ";%(AdditionalIncludeDirectories)";
+ fout << sep << cmVisualStudio10GeneratorOptionsEscapeForXML(*i);
+ sep = ";";
}
fout << "</" << m->first << ">\n";
}
}
else
{
- for(std::map<cmStdString, cmStdString>::iterator m = this->FlagMap.begin();
+ for(std::map<std::string, FlagValue>::iterator m = this->FlagMap.begin();
m != this->FlagMap.end(); ++m)
{
- fout << indent << m->first << "=\"" << m->second << "\"\n";
+ fout << indent << m->first << "=\"";
+ const char* sep = "";
+ for(std::vector<std::string>::iterator i = m->second.begin();
+ i != m->second.end(); ++i)
+ {
+ fout << sep << cmVisualStudioGeneratorOptionsEscapeForXML(*i);
+ sep = ";";
+ }
+ fout << "\"\n";
}
}
}
@@ -343,10 +395,10 @@ cmVisualStudioGeneratorOptions
{
if(!this->FlagString.empty())
{
- if(this->Version >= cmLocalVisualStudioGenerator::VS10)
+ if(this->Version >= cmGlobalVisualStudioGenerator::VS10)
{
fout << prefix;
- if(this->Configuration.size())
+ if(!this->Configuration.empty())
{
this->TargetGenerator->WritePlatformConfigTag(
"AdditionalOptions",
@@ -358,14 +410,13 @@ cmVisualStudioGeneratorOptions
{
fout << "<AdditionalOptions>";
}
- fout << this->FlagString.c_str()
+ fout << cmVisualStudio10GeneratorOptionsEscapeForXML(this->FlagString)
<< " %(AdditionalOptions)</AdditionalOptions>\n";
}
else
{
fout << prefix << "AdditionalOptions=\"";
- fout <<
- cmVisualStudioGeneratorOptionsEscapeForXML(this->FlagString.c_str());
+ fout << cmVisualStudioGeneratorOptionsEscapeForXML(this->FlagString);
fout << "\"" << suffix;
}
}
diff --git a/Source/cmVisualStudioGeneratorOptions.h b/Source/cmVisualStudioGeneratorOptions.h
index 90f76672d..0179134b5 100644
--- a/Source/cmVisualStudioGeneratorOptions.h
+++ b/Source/cmVisualStudioGeneratorOptions.h
@@ -27,6 +27,8 @@ public:
enum Tool
{
Compiler,
+ ResourceCompiler,
+ MasmCompiler,
Linker,
FortranCompiler
};
@@ -36,6 +38,13 @@ public:
cmVS7FlagTable const* extraTable = 0,
cmVisualStudio10TargetGenerator* g = 0);
+ cmVisualStudioGeneratorOptions(cmLocalVisualStudioGenerator* lg,
+ Tool tool,
+ cmVisualStudio10TargetGenerator* g = 0);
+
+ // Add a table of flags.
+ void AddTable(cmVS7FlagTable const* table);
+
// Store options from command line flags.
void Parse(const char* flags);
void ParseFinish();
@@ -51,11 +60,12 @@ public:
bool UsingSBCS() const;
bool IsDebug() const;
+ bool IsWinRt() const;
// Write options to output.
void OutputPreprocessorDefinitions(std::ostream& fout,
const char* prefix,
const char* suffix,
- const char* lang);
+ const std::string& lang);
void OutputFlagMap(std::ostream& fout, const char* indent);
void OutputAdditionalOptions(std::ostream& fout,
const char* prefix,
@@ -63,7 +73,7 @@ public:
void SetConfiguration(const char* config);
private:
cmLocalVisualStudioGenerator* LocalGenerator;
- cmLocalVisualStudioGenerator::VSVersion Version;
+ cmGlobalVisualStudioGenerator::VSVersion Version;
std::string Configuration;
Tool CurrentTool;
diff --git a/Source/cmVisualStudioSlnParser.cxx b/Source/cmVisualStudioSlnParser.cxx
index bae59740a..d182a75d5 100644
--- a/Source/cmVisualStudioSlnParser.cxx
+++ b/Source/cmVisualStudioSlnParser.cxx
@@ -13,6 +13,7 @@
#include "cmSystemTools.h"
#include "cmVisualStudioSlnData.h"
+#include <cmsys/FStream.hxx>
#include <cassert>
#include <stack>
@@ -472,7 +473,7 @@ bool cmVisualStudioSlnParser::ParseFile(const std::string& file,
this->LastResult.SetError(ResultErrorUnsupportedDataGroup, 0);
return false;
}
- std::ifstream f(file.c_str());
+ cmsys::ifstream f(file.c_str());
if (!f)
{
this->LastResult.SetError(ResultErrorOpeningInput, 0);
diff --git a/Source/cmVisualStudioWCEPlatformParser.cxx b/Source/cmVisualStudioWCEPlatformParser.cxx
index 219a5eb49..ca226fb50 100644
--- a/Source/cmVisualStudioWCEPlatformParser.cxx
+++ b/Source/cmVisualStudioWCEPlatformParser.cxx
@@ -62,7 +62,7 @@ const char* cmVisualStudioWCEPlatformParser::GetArchitectureFamily() const
return 0;
}
-void cmVisualStudioWCEPlatformParser::StartElement(const char* name,
+void cmVisualStudioWCEPlatformParser::StartElement(const std::string& name,
const char** attributes)
{
if(this->FoundRequiredName)
@@ -72,7 +72,7 @@ void cmVisualStudioWCEPlatformParser::StartElement(const char* name,
this->CharacterData = "";
- if(strcmp(name, "PlatformData") == 0)
+ if(name == "PlatformData")
{
this->PlatformName = "";
this->OSMajorVersion = "";
@@ -80,7 +80,7 @@ void cmVisualStudioWCEPlatformParser::StartElement(const char* name,
this->Macros.clear();
}
- if(strcmp(name, "Macro") == 0)
+ if(name == "Macro")
{
std::string macroName;
std::string macroValue;
@@ -102,7 +102,7 @@ void cmVisualStudioWCEPlatformParser::StartElement(const char* name,
this->Macros[macroName] = macroValue;
}
}
- else if(strcmp(name, "Directories") == 0)
+ else if(name == "Directories")
{
for(const char** attr = attributes; *attr; attr += 2)
{
@@ -122,11 +122,11 @@ void cmVisualStudioWCEPlatformParser::StartElement(const char* name,
}
}
-void cmVisualStudioWCEPlatformParser::EndElement(const char* name)
+void cmVisualStudioWCEPlatformParser::EndElement(const std::string& name)
{
if(!this->RequiredName)
{
- if(strcmp(name, "PlatformName") == 0)
+ if(name == "PlatformName")
{
this->AvailablePlatforms.push_back(this->CharacterData);
}
@@ -138,19 +138,19 @@ void cmVisualStudioWCEPlatformParser::EndElement(const char* name)
return;
}
- if(strcmp(name, "PlatformName") == 0)
+ if(name == "PlatformName")
{
this->PlatformName = this->CharacterData;
}
- else if(strcmp(name, "OSMajorVersion") == 0)
+ else if(name == "OSMajorVersion")
{
this->OSMajorVersion = this->CharacterData;
}
- else if(strcmp(name, "OSMinorVersion") == 0)
+ else if(name == "OSMinorVersion")
{
this->OSMinorVersion = this->CharacterData;
}
- else if(strcmp(name, "Platform") == 0)
+ else if(name == "Platform")
{
if(this->PlatformName == this->RequiredName)
{
diff --git a/Source/cmVisualStudioWCEPlatformParser.h b/Source/cmVisualStudioWCEPlatformParser.h
index 466e1dd43..042df0142 100644
--- a/Source/cmVisualStudioWCEPlatformParser.h
+++ b/Source/cmVisualStudioWCEPlatformParser.h
@@ -41,8 +41,8 @@ public:
return this->AvailablePlatforms; }
protected:
- virtual void StartElement(const char* name, const char** attributes);
- void EndElement(const char* name);
+ virtual void StartElement(const std::string& name, const char** attributes);
+ void EndElement(const std::string& name);
void CharacterDataHandler(const char* data, int length);
private:
diff --git a/Source/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx
index 7d2eeadd6..4b7afd87a 100644
--- a/Source/cmWhileCommand.cxx
+++ b/Source/cmWhileCommand.cxx
@@ -10,7 +10,18 @@
See the License for more information.
============================================================================*/
#include "cmWhileCommand.h"
-#include "cmIfCommand.h"
+#include "cmConditionEvaluator.h"
+
+cmWhileFunctionBlocker::cmWhileFunctionBlocker(cmMakefile* mf):
+ Makefile(mf), Depth(0)
+{
+ this->Makefile->PushLoopBlock();
+}
+
+cmWhileFunctionBlocker::~cmWhileFunctionBlocker()
+{
+ this->Makefile->PopLoopBlock();
+}
bool cmWhileFunctionBlocker::
IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
@@ -34,16 +45,31 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
std::string errorString;
- std::vector<std::string> expandedArguments;
+ std::vector<cmExpandedCommandArgument> expandedArguments;
mf.ExpandArguments(this->Args, expandedArguments);
cmake::MessageType messageType;
- bool isTrue =
- cmIfCommand::IsTrue(expandedArguments,errorString,
- &mf, messageType);
+
+ cmListFileContext execContext = this->GetStartingContext();
+
+ cmCommandContext commandContext;
+ commandContext.Line = execContext.Line;
+ commandContext.Name = execContext.Name;
+
+ cmListFileContext conditionContext =
+ cmConditionEvaluator::GetConditionContext(
+ &mf, commandContext,
+ this->GetStartingContext().FilePath);
+
+ cmConditionEvaluator conditionEvaluator(
+ mf, conditionContext,
+ mf.GetBacktrace(commandContext));
+
+ bool isTrue = conditionEvaluator.IsTrue(
+ expandedArguments, errorString, messageType);
while (isTrue)
{
- if (errorString.size())
+ if (!errorString.empty())
{
std::string err = "had incorrect arguments: ";
unsigned int i;
@@ -79,6 +105,10 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
{
return true;
}
+ if (status.GetContinueInvoked())
+ {
+ break;
+ }
if(cmSystemTools::GetFatalErrorOccured() )
{
return true;
@@ -86,9 +116,8 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
}
expandedArguments.clear();
mf.ExpandArguments(this->Args, expandedArguments);
- isTrue =
- cmIfCommand::IsTrue(expandedArguments,errorString,
- &mf, messageType);
+ isTrue = conditionEvaluator.IsTrue(
+ expandedArguments, errorString, messageType);
}
return true;
}
@@ -113,7 +142,7 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile& )
{
// if the endwhile has arguments, then make sure
// they match the arguments of the matching while
- if (lff.Arguments.size() == 0 ||
+ if (lff.Arguments.empty() ||
lff.Arguments == this->Args)
{
return true;
@@ -133,7 +162,7 @@ bool cmWhileCommand
}
// create a function blocker
- cmWhileFunctionBlocker *f = new cmWhileFunctionBlocker();
+ cmWhileFunctionBlocker *f = new cmWhileFunctionBlocker(this->Makefile);
f->Args = args;
this->Makefile->AddFunctionBlocker(f);
diff --git a/Source/cmWhileCommand.h b/Source/cmWhileCommand.h
index 1bdf27af3..85a0bd327 100644
--- a/Source/cmWhileCommand.h
+++ b/Source/cmWhileCommand.h
@@ -19,8 +19,8 @@
class cmWhileFunctionBlocker : public cmFunctionBlocker
{
public:
- cmWhileFunctionBlocker() {this->Depth=0;}
- virtual ~cmWhileFunctionBlocker() {}
+ cmWhileFunctionBlocker(cmMakefile* mf);
+ ~cmWhileFunctionBlocker();
virtual bool IsFunctionBlocked(const cmListFileFunction& lff,
cmMakefile &mf,
cmExecutionStatus &);
@@ -29,6 +29,7 @@ public:
std::vector<cmListFileArgument> Args;
std::vector<cmListFileFunction> Functions;
private:
+ cmMakefile* Makefile;
int Depth;
};
@@ -66,33 +67,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "while";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Evaluate a group of commands while a condition is true";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " while(condition)\n"
- " COMMAND1(ARGS ...)\n"
- " COMMAND2(ARGS ...)\n"
- " ...\n"
- " endwhile(condition)\n"
- "All commands between while and the matching endwhile are recorded "
- "without being invoked. Once the endwhile is evaluated, the "
- "recorded list of commands is invoked as long as the condition "
- "is true. The condition is evaluated using the same logic as the "
- "if command.";
- }
+ virtual std::string GetName() const { return "while";}
cmTypeMacro(cmWhileCommand, cmCommand);
};
diff --git a/Source/cmWin32ProcessExecution.cxx b/Source/cmWin32ProcessExecution.cxx
deleted file mode 100644
index 1bdeffbed..000000000
--- a/Source/cmWin32ProcessExecution.cxx
+++ /dev/null
@@ -1,884 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#include "cmWin32ProcessExecution.h"
-
-#include "cmSystemTools.h"
-
-#include <malloc.h>
-#include <io.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <windows.h>
-
-#if defined(__BORLANDC__)
-# define STRICMP stricmp
-# define TO_INTPTR(x) ((long)(x))
-#endif // Borland
-#if defined(_MSC_VER) // Visual studio
-# if ( _MSC_VER >= 1300 )
-# include <stddef.h>
-# define TO_INTPTR(x) ((intptr_t)(x))
-# else // Visual Studio 6
-# define TO_INTPTR(x) ((long)(x))
-# endif // Visual studio .NET
-# define STRICMP _stricmp
-#endif // Visual Studio
-#if defined(__MINGW32__)
-# include <stdint.h>
-# define TO_INTPTR(x) ((intptr_t)(x))
-# define STRICMP _stricmp
-#endif // MinGW
-
-#define POPEN_1 1
-#define POPEN_2 2
-#define POPEN_3 3
-#define POPEN_4 4
-
-#define cmMAX(x,y) (((x)<(y))?(y):(x))
-
-void DisplayErrorMessage()
-{
- LPVOID lpMsgBuf;
- FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- GetLastError(),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
- (LPTSTR) &lpMsgBuf,
- 0,
- NULL
- );
- // Process any inserts in lpMsgBuf.
- // ...
- // Display the string.
- MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
- // Free the buffer.
- LocalFree( lpMsgBuf );
-}
-
-// Code from a Borland web site with the following explaination :
-/* In this article, I will explain how to spawn a console application
- * and redirect its standard input/output using anonymous pipes. An
- * anonymous pipe is a pipe that goes only in one direction (read
- * pipe, write pipe, etc.). Maybe you are asking, "why would I ever
- * need to do this sort of thing?" One example would be a Windows
- * telnet server, where you spawn a shell and listen on a port and
- * send and receive data between the shell and the socket
- * client. (Windows does not really have a built-in remote
- * shell). First, we should talk about pipes. A pipe in Windows is
- * simply a method of communication, often between process. The SDK
- * defines a pipe as "a communication conduit with two ends;
- a process
- * with a handle to one end can communicate with a process having a
- * handle to the other end." In our case, we are using "anonymous"
- * pipes, one-way pipes that "transfer data between a parent process
- * and a child process or between two child processes of the same
- * parent process." It's easiest to imagine a pipe as its namesake. An
- * actual pipe running between processes that can carry data. We are
- * using anonymous pipes because the console app we are spawning is a
- * child process. We use the CreatePipe function which will create an
- * anonymous pipe and return a read handle and a write handle. We will
- * create two pipes, on for stdin and one for stdout. We will then
- * monitor the read end of the stdout pipe to check for display on our
- * child process. Every time there is something availabe for reading,
- * we will display it in our app. Consequently, we check for input in
- * our app and send it off to the write end of the stdin pipe. */
-
-inline bool IsWinNT()
-//check if we're running NT
-{
- OSVERSIONINFO osv;
- osv.dwOSVersionInfoSize = sizeof(osv);
- GetVersionEx(&osv);
- return (osv.dwPlatformId == VER_PLATFORM_WIN32_NT);
-}
-
-//---------------------------------------------------------------------------
-bool cmWin32ProcessExecution::BorlandRunCommand(
- const char* command, const char* dir,
- std::string& output, int& retVal, bool verbose, int /* timeout */,
- bool hideWindows)
-{
- //verbose = true;
- //std::cerr << std::endl
- // << "WindowsRunCommand(" << command << ")" << std::endl
- // << std::flush;
- const int BUFFER_SIZE = 4096;
- char buf[BUFFER_SIZE];
-
-//i/o buffer
- STARTUPINFO si;
- SECURITY_ATTRIBUTES sa;
- SECURITY_DESCRIPTOR sd;
-
-//security information for pipes
- PROCESS_INFORMATION pi;
- HANDLE newstdin,newstdout,read_stdout,write_stdin;
-
-//pipe handles
- if (IsWinNT())
-//initialize security descriptor (Windows NT)
- {
- InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
- SetSecurityDescriptorDacl(&sd, true, NULL, false);
- sa.lpSecurityDescriptor = &sd;
-
- }
- else sa.lpSecurityDescriptor = NULL;
- sa.nLength = sizeof(SECURITY_ATTRIBUTES);
- sa.bInheritHandle = true;
-
-//allow inheritable handles
- if (!CreatePipe(&newstdin,&write_stdin,&sa,0))
-//create stdin pipe
- {
- return false;
- }
- if (!CreatePipe(&read_stdout,&newstdout,&sa,0))
-//create stdout pipe
- {
- CloseHandle(newstdin);
- CloseHandle(write_stdin);
- return false;
-
- }
- GetStartupInfo(&si);
-
-//set startupinfo for the spawned process
- /* The dwFlags member tells CreateProcess how to make the
- * process. STARTF_USESTDHANDLES validates the hStd*
- * members. STARTF_USESHOWWINDOW validates the wShowWindow
- * member. */
-
- si.cb = sizeof(STARTUPINFO);
- si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
- si.hStdOutput = newstdout;
- si.hStdError = newstdout;
- si.wShowWindow = SW_SHOWDEFAULT;
- if(hideWindows)
- {
- si.wShowWindow = SW_HIDE;
- }
-
-//set the new handles for the child process si.hStdInput = newstdin;
- char* commandAndArgs = strcpy(new char[strlen(command)+1], command);
- if (!CreateProcess(NULL,commandAndArgs,NULL,NULL,TRUE,
- 0, // CREATE_NEW_CONSOLE,
- NULL,dir,&si,&pi))
- {
- std::cerr << "CreateProcess failed " << commandAndArgs << std::endl;
- CloseHandle(newstdin);
- CloseHandle(newstdout);
- CloseHandle(read_stdout);
- CloseHandle(write_stdin);
- delete [] commandAndArgs;
- return false;
-
- }
- delete [] commandAndArgs;
- unsigned long exit=0;
-
-//process exit code unsigned
- unsigned long bread;
-
-//bytes read unsigned
- unsigned long avail;
-
-//bytes available
- memset(buf, 0, sizeof(buf));
- for(;;)
-//main program loop
- {
- Sleep(10);
-//check to see if there is any data to read from stdout
- //std::cout << "Peek for data..." << std::endl;
- PeekNamedPipe(read_stdout,buf,1023,&bread,&avail,NULL);
- if (bread != 0)
- {
- memset(buf, 0, sizeof(buf));
- if (avail > 1023)
- {
- while (bread >= 1023)
- {
- //std::cout << "Read data..." << std::endl;
- ReadFile(read_stdout,buf,1023,&bread,NULL);
-
- //read the stdout pipe
- memset(buf, 0, sizeof(buf));
- output += buf;
- if (verbose)
- {
- cmSystemTools::Stdout(buf);
- }
- }
- }
- else
- {
- ReadFile(read_stdout,buf,1023,&bread,NULL);
- output += buf;
- if(verbose)
- {
- cmSystemTools::Stdout(buf);
- }
-
- }
-
- }
-
- //std::cout << "Check for process..." << std::endl;
- GetExitCodeProcess(pi.hProcess,&exit);
-
-//while the process is running
- if (exit != STILL_ACTIVE) break;
-
- }
- WaitForSingleObject(pi.hProcess, INFINITE);
- GetExitCodeProcess(pi.hProcess,&exit);
- CloseHandle(pi.hThread);
- CloseHandle(pi.hProcess);
- CloseHandle(newstdin);
-
-//clean stuff up
- CloseHandle(newstdout);
- CloseHandle(read_stdout);
- CloseHandle(write_stdin);
- retVal = exit;
- return true;
-
-}
-
-bool cmWin32ProcessExecution::StartProcess(
- const char* cmd, const char* path, bool verbose)
-{
- this->Initialize();
- this->Verbose = verbose;
- return this->PrivateOpen(cmd, path, _O_RDONLY | _O_TEXT, POPEN_3);
-}
-
-bool cmWin32ProcessExecution::Wait(int timeout)
-{
- return this->PrivateClose(timeout);
-}
-
-static BOOL RealPopenCreateProcess(const char *cmdstring,
- const char *path,
- const char *szConsoleSpawn,
- HANDLE hStdin,
- HANDLE hStdout,
- HANDLE hStderr,
- HANDLE *hProcess,
- bool hideWindows,
- std::string& output)
-{
- PROCESS_INFORMATION piProcInfo;
- STARTUPINFO siStartInfo;
- char *s1=0,*s2=0;
- const char *s3 = " /c ";
- int i = GetEnvironmentVariable("COMSPEC",NULL,0);
- if (i)
- {
- char *comshell;
-
- s1 = (char *)malloc(i);
- int x = GetEnvironmentVariable("COMSPEC", s1, i);
- if (!x)
- {
- free(s1);
- return x;
- }
-
- /* Explicitly check if we are using COMMAND.COM. If we are
- * then use the w9xpopen hack.
- */
- comshell = s1 + x;
- while (comshell >= s1 && *comshell != '\\')
- --comshell;
- ++comshell;
-
- if (GetVersion() < 0x80000000 &&
- STRICMP(comshell, "command.com") != 0)
- {
- /* NT/2000 and not using command.com. */
- x = i + (int)strlen(s3) + (int)strlen(cmdstring) + 1;
- s2 = (char *)malloc(x);
- ZeroMemory(s2, x);
- //sprintf(s2, "%s%s%s", s1, s3, cmdstring);
- sprintf(s2, "%s", cmdstring);
- }
- else
- {
- /*
- * Oh gag, we're on Win9x or using COMMAND.COM. Use
- * the workaround listed in KB: Q150956
- */
- char modulepath[_MAX_PATH];
- struct stat statinfo;
- GetModuleFileName(NULL, modulepath, sizeof(modulepath));
- for (i = x = 0; modulepath[i]; i++)
- if (modulepath[i] == '\\')
- x = i+1;
- modulepath[x] = '\0';
- /* Create the full-name to w9xpopen, so we can test it exists */
- strncat(modulepath,
- szConsoleSpawn,
- (sizeof(modulepath)/sizeof(modulepath[0]))
- -strlen(modulepath));
- if (stat(modulepath, &statinfo) != 0)
- {
- /* Eeek - file-not-found - possibly an embedding
- situation - see if we can locate it in sys.prefix
- */
- strncpy(modulepath,
- ".",
- sizeof(modulepath)/sizeof(modulepath[0]));
- if (modulepath[strlen(modulepath)-1] != '\\')
- strcat(modulepath, "\\");
- strncat(modulepath,
- szConsoleSpawn,
- (sizeof(modulepath)/sizeof(modulepath[0]))
- -strlen(modulepath));
- /* No where else to look - raise an easily identifiable
- error, rather than leaving Windows to report
- "file not found" - as the user is probably blissfully
- unaware this shim EXE is used, and it will confuse them.
- (well, it confused me for a while ;-)
- */
- if (stat(modulepath, &statinfo) != 0)
- {
- std::cout
- << "Can not locate '" << modulepath
- << "' which is needed "
- "for popen to work with your shell "
- "or platform." << std::endl;
- free(s1);
- free(s2);
- return FALSE;
- }
- }
- x = i + (int)strlen(s3) + (int)strlen(cmdstring) + 1 +
- (int)strlen(modulepath) +
- (int)strlen(szConsoleSpawn) + 1;
- if(s2)
- {
- free(s2);
- }
- s2 = (char *)malloc(x);
- ZeroMemory(s2, x);
- sprintf(
- s2,
- "%s %s%s%s",
- modulepath,
- s1,
- s3,
- cmdstring);
- sprintf(
- s2,
- "%s %s",
- modulepath,
- cmdstring);
- }
- }
-
- /* Could be an else here to try cmd.exe / command.com in the path
- Now we'll just error out.. */
- else
- {
- std::cout << "Cannot locate a COMSPEC environment variable to "
- << "use as the shell" << std::endl;
- free(s2);
- free(s1);
- return FALSE;
- }
-
- ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
- siStartInfo.cb = sizeof(STARTUPINFO);
- siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
- siStartInfo.hStdInput = hStdin;
- siStartInfo.hStdOutput = hStdout;
- siStartInfo.hStdError = hStderr;
- siStartInfo.wShowWindow = SW_SHOWDEFAULT;
- if(hideWindows)
- {
- siStartInfo.wShowWindow = SW_HIDE;
- }
-
- //std::cout << "Create process: " << s2 << std::endl;
- if (CreateProcess(NULL,
- s2,
- NULL,
- NULL,
- TRUE,
- 0, //CREATE_NEW_CONSOLE,
- NULL,
- path,
- &siStartInfo,
- &piProcInfo) )
- {
- /* Close the handles now so anyone waiting is woken. */
- CloseHandle(piProcInfo.hThread);
- /* Return process handle */
- *hProcess = piProcInfo.hProcess;
- //std::cout << "Process created..." << std::endl;
- free(s2);
- free(s1);
- return TRUE;
- }
-
- output += "CreateProcessError: ";
- {
- /* Format the error message. */
- char message[1024];
- DWORD original = GetLastError();
- DWORD length = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS, 0, original,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- message, 1023, 0);
- if(length < 1)
- {
- /* FormatMessage failed. Use a default message. */
- _snprintf(message, 1023,
- "Process execution failed with error 0x%X. "
- "FormatMessage failed with error 0x%X",
- original, GetLastError());
- }
- output += message;
- }
- output += "\n";
- output += "for command: ";
- output += s2;
- if(path)
- {
- output += "\nin dir: ";
- output += path;
- }
- output += "\n";
- free(s2);
- free(s1);
- return FALSE;
-}
-
-/* The following code is based off of KB: Q190351 */
-
-bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring,
- const char* path,
- int mode,
- int n)
-{
- HANDLE hProcess;
-
- SECURITY_ATTRIBUTES saAttr;
- BOOL fSuccess;
- int fd1, fd2, fd3;
- this->hChildStdinRd = 0;
- this->hChildStdinWr = 0;
- this->hChildStdoutRd = 0;
- this->hChildStdoutWr = 0;
- this->hChildStderrRd = 0;
- this->hChildStderrWr = 0;
- this->hChildStdinWrDup = 0;
- this->hChildStdoutRdDup = 0;
- this->hChildStderrRdDup = 0;
-
- saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
- saAttr.bInheritHandle = TRUE;
- saAttr.lpSecurityDescriptor = NULL;
-
- fd1 = 0;
- fd2 = 0;
- fd3 = 0;
-
- if (!CreatePipe(&this->hChildStdinRd, &this->hChildStdinWr, &saAttr, 0))
- {
- this->Output += "CreatePipeError\n";
- return false;
- }
-
- /* Create new output read handle and the input write handle. Set
- * the inheritance properties to FALSE. Otherwise, the child inherits
- * these handles; resulting in non-closeable handles to the pipes
- * being created. */
- fSuccess = DuplicateHandle(GetCurrentProcess(), this->hChildStdinWr,
- GetCurrentProcess(), &this->hChildStdinWrDup, 0,
- FALSE,
- DUPLICATE_SAME_ACCESS);
- if (!fSuccess)
- {
- this->Output += "DuplicateHandleError\n";
- return false;
- }
-
-
- /* Close the inheritable version of ChildStdin
- that we're using. */
- CloseHandle(hChildStdinWr);
-
- if (!CreatePipe(&this->hChildStdoutRd, &this->hChildStdoutWr, &saAttr, 0))
- {
- this->Output += "CreatePipeError\n";
- return false;
- }
-
- fSuccess = DuplicateHandle(GetCurrentProcess(), this->hChildStdoutRd,
- GetCurrentProcess(), &this->hChildStdoutRdDup, 0,
- FALSE, DUPLICATE_SAME_ACCESS);
- if (!fSuccess)
- {
- this->Output += "DuplicateHandleError\n";
- return false;
- }
-
- /* Close the inheritable version of ChildStdout
- that we're using. */
- CloseHandle(hChildStdoutRd);
-
- if (n != POPEN_4)
- {
- if (!CreatePipe(&this->hChildStderrRd, &this->hChildStderrWr, &saAttr, 0))
- {
- this->Output += "CreatePipeError\n";
- return false;
- }
- fSuccess = DuplicateHandle(GetCurrentProcess(),
- this->hChildStderrRd,
- GetCurrentProcess(),
- &this->hChildStderrRdDup, 0,
- FALSE, DUPLICATE_SAME_ACCESS);
- if (!fSuccess)
- {
- this->Output += "DuplicateHandleError\n";
- return false;
- }
- /* Close the inheritable version of ChildStdErr that we're using. */
- CloseHandle(hChildStderrRd);
-
- }
-
- switch (n)
- {
- case POPEN_1:
- switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY))
- {
- case _O_WRONLY | _O_TEXT:
- /* Case for writing to child Stdin in text mode. */
- fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdinWrDup), mode);
- /* We don't care about these pipes anymore,
- so close them. */
- break;
-
- case _O_RDONLY | _O_TEXT:
- /* Case for reading from child Stdout in text mode. */
- fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdoutRdDup), mode);
- /* We don't care about these pipes anymore,
- so close them. */
- break;
-
- case _O_RDONLY | _O_BINARY:
- /* Case for readinig from child Stdout in
- binary mode. */
- fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdoutRdDup), mode);
- /* We don't care about these pipes anymore,
- so close them. */
- break;
-
- case _O_WRONLY | _O_BINARY:
- /* Case for writing to child Stdin in binary mode. */
- fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdinWrDup), mode);
- /* We don't care about these pipes anymore,
- so close them. */
- break;
- }
- break;
-
- case POPEN_2:
- case POPEN_4:
- //if ( 1 )
- {
- fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdinWrDup), mode);
- fd2 = _open_osfhandle(TO_INTPTR(this->hChildStdoutRdDup), mode);
- break;
- }
-
- case POPEN_3:
- //if ( 1)
- {
- fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdinWrDup), mode);
- fd2 = _open_osfhandle(TO_INTPTR(this->hChildStdoutRdDup), mode);
- fd3 = _open_osfhandle(TO_INTPTR(this->hChildStderrRdDup), mode);
- break;
- }
- }
-
- if (n == POPEN_4)
- {
- if (!RealPopenCreateProcess(cmdstring,
- path,
- this->ConsoleSpawn.c_str(),
- this->hChildStdinRd,
- this->hChildStdoutWr,
- this->hChildStdoutWr,
- &hProcess, this->HideWindows,
- this->Output))
- {
- if(fd1 >= 0)
- {
- close(fd1);
- }
- if(fd2 >= 0)
- {
- close(fd2);
- }
- if(fd3 >= 0)
- {
- close(fd3);
- }
- return 0;
- }
- }
- else
- {
- if (!RealPopenCreateProcess(cmdstring,
- path,
- this->ConsoleSpawn.c_str(),
- this->hChildStdinRd,
- this->hChildStdoutWr,
- this->hChildStderrWr,
- &hProcess, this->HideWindows,
- this->Output))
- {
- if(fd1 >= 0)
- {
- close(fd1);
- }
- if(fd2 >= 0)
- {
- close(fd2);
- }
- if(fd3 >= 0)
- {
- close(fd3);
- }
- return 0;
- }
- }
-
- /* Child is launched. Close the parents copy of those pipe
- * handles that only the child should have open. You need to
- * make sure that no handles to the write end of the output pipe
- * are maintained in this process or else the pipe will not close
- * when the child process exits and the ReadFile will hang. */
- this->ProcessHandle = hProcess;
- if ( fd1 >= 0 )
- {
- this->pStdIn = fd1;
- }
- if ( fd2 >= 0 )
- {
- this->pStdOut = fd2;
- }
- if ( fd3 >= 0 )
- {
- this->pStdErr = fd3;
- }
-
- return true;
-}
-
-bool cmWin32ProcessExecution::CloseHandles()
-{
- if(this->pStdErr != -1 )
- {
- // this will close this as well: this->hChildStderrRdDup
- _close(this->pStdErr);
- this->pStdErr = -1;
- this->hChildStderrRdDup = 0;
- }
- if(this->pStdIn != -1 )
- {
- // this will close this as well: this->hChildStdinWrDup
- _close(this->pStdIn);
- this->pStdIn = -1;
- this->hChildStdinWrDup = 0;
- }
- if(this->pStdOut != -1 )
- {
- // this will close this as well: this->hChildStdoutRdDup
- _close(this->pStdOut);
- this->pStdOut = -1;
- this->hChildStdoutRdDup = 0;
- }
-
- bool ret = true;
- if (this->hChildStdinRd && !CloseHandle(this->hChildStdinRd))
- {
- ret = false;
- }
- this->hChildStdinRd = 0;
- // now close these two
- if (this->hChildStdoutWr && !CloseHandle(this->hChildStdoutWr))
- {
- ret = false;
- }
- this->hChildStdoutWr = 0;
- if (this->hChildStderrWr && !CloseHandle(this->hChildStderrWr))
- {
- ret = false;
- }
- this->hChildStderrWr = 0;
- return ret;
-}
-cmWin32ProcessExecution::~cmWin32ProcessExecution()
-{
- this->CloseHandles();
-}
-
-bool cmWin32ProcessExecution::PrivateClose(int /* timeout */)
-{
- HANDLE hProcess = this->ProcessHandle;
-
- int result = -1;
- DWORD exit_code;
-
- std::string output = "";
- bool done = false;
- while(!done)
- {
- Sleep(10);
- bool have_some = false;
- struct _stat fsout;
- struct _stat fserr;
- int rout = _fstat(this->pStdOut, &fsout);
- int rerr = _fstat(this->pStdErr, &fserr);
- if ( rout && rerr )
- {
- break;
- }
- if (fserr.st_size > 0)
- {
- char buffer[1024];
- int len = read(this->pStdErr, buffer, 1023);
- buffer[len] = 0;
- if ( this->Verbose )
- {
- cmSystemTools::Stdout(buffer);
- }
- output += buffer;
- have_some = true;
- }
- if (fsout.st_size > 0)
- {
- char buffer[1024];
- int len = read(this->pStdOut, buffer, 1023);
- buffer[len] = 0;
- if ( this->Verbose )
- {
- cmSystemTools::Stdout(buffer);
- }
- output += buffer;
- have_some = true;
- }
- unsigned long exitCode;
- if ( ! have_some )
- {
- GetExitCodeProcess(hProcess,&exitCode);
- if (exitCode != STILL_ACTIVE)
- {
- break;
- }
- }
- }
-
-
- if (WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
- GetExitCodeProcess(hProcess, &exit_code))
- {
- result = exit_code;
- }
- else
- {
- /* Indicate failure - this will cause the file object
- * to raise an I/O error and translate the last Win32
- * error code from errno. We do have a problem with
- * last errors that overlap the normal errno table,
- * but that's a consistent problem with the file object.
- */
- if (result != EOF)
- {
- /* If the error wasn't from the fclose(), then
- * set errno for the file object error handling.
- */
- errno = GetLastError();
- }
- result = -1;
- }
-
- /* Free up the native handle at this point */
- CloseHandle(hProcess);
- this->ExitValue = result;
- this->Output += output;
- bool ret = this->CloseHandles();
- if ( result < 0 || !ret)
- {
- return false;
- }
- return true;
-}
-
-int cmWin32ProcessExecution::Windows9xHack(const char* command)
-{
- BOOL bRet;
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
- DWORD exit_code=0;
-
- if (!command)
- {
- cmSystemTools::Error("Windows9xHack: Command not specified");
- return 1;
- }
-
- /* Make child process use this app's standard files. */
- ZeroMemory(&si, sizeof si);
- si.cb = sizeof si;
- si.dwFlags = STARTF_USESTDHANDLES;
- si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
- si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
- si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
-
-
- char * app = 0;
- char* cmd = new char[ strlen(command) + 1 ];
- strcpy(cmd, command);
-
- bRet = CreateProcess(
- app, cmd,
- 0, 0,
- TRUE, 0,
- 0, 0,
- &si, &pi
- );
- delete [] cmd;
-
- if (bRet)
- {
- if (WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_FAILED)
- {
- GetExitCodeProcess(pi.hProcess, &exit_code);
- }
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
- return exit_code;
- }
-
- return 1;
-}
diff --git a/Source/cmWin32ProcessExecution.h b/Source/cmWin32ProcessExecution.h
deleted file mode 100644
index 2127ebd2e..000000000
--- a/Source/cmWin32ProcessExecution.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef cmWin32ProcessExecution_h
-#define cmWin32ProcessExecution_h
-
-#include "cmStandardIncludes.h"
-#include "windows.h"
-
-class cmMakefile;
-
-/** \class cmWin32ProcessExecution
- * \brief A process executor for windows
- *
- * cmWin32ProcessExecution is a class that provides a "clean" way of
- * executing processes on Windows. It is modified code from Python 2.1
- * distribution.
- *
- * Portable 'popen' replacement for Win32.
- *
- * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks and 2.0
- * integration by Fredrik Lundh <fredrik@pythonware.com> Return code
- * handling by David Bolen <db3l@fitlinxx.com>.
- *
- * Modified for CMake.
- *
- * For more information, please check Microsoft Knowledge Base
- * Articles Q190351 and Q150956.
- */
-class cmWin32ProcessExecution
-{
-public:
- cmWin32ProcessExecution()
- {
- this->HideWindows = false;
- this->SetConsoleSpawn("w9xpopen.exe");
- this->Initialize();
- }
- ~cmWin32ProcessExecution();
- ///! If true windows will be created hidden.
- void SetHideWindows(bool v) { this->HideWindows = v; }
-
- /**
- * Initialize the process execution datastructure. Do not call while
- * running the process.
- */
- void Initialize()
- {
- this->ProcessHandle = 0;
- this->ExitValue = -1;
- // Comment this out. Maybe we will need it in the future.
- // file IO access to the process might be cool.
- //this->StdIn = 0;
- //this->StdOut = 0;
- //this->StdErr = 0;
- this->pStdIn = -1;
- this->pStdOut = -1;
- this->pStdErr = -1;
- }
-
- /**
- * Start the process in the directory path. Make sure that the
- * executable is either in the path or specify the full path. The
- * argument verbose specifies whether or not to display output while
- * it is being generated.
- */
- bool StartProcess(const char*, const char* path, bool verbose);
-
- /**
- * Wait for the process to finish. If timeout is specified, it will
- * break the process after timeout expires. (Timeout code is not yet
- * implemented.
- */
- bool Wait(int timeout);
-
- /**
- * Get the output of the process (mixed stdout and stderr) as
- * std::string.
- */
- const std::string GetOutput() const { return this->Output; }
-
- /**
- * Get the return value of the process. If the process is still
- * running, the return value is -1.
- */
- int GetExitValue() const { return this->ExitValue; }
-
- /**
- * On Windows 9x there is a bug in the process execution code which
- * may result in blocking. That is why this workaround is
- * used. Specify the console spawn, which should run the
- * Windows9xHack code.
- */
- void SetConsoleSpawn(const char* prog) { this->ConsoleSpawn = prog; }
- static int Windows9xHack(const char* command);
-
- /** Code from a Borland web site with the following explaination :
- * In this article, I will explain how to spawn a console
- * application and redirect its standard input/output using
- * anonymous pipes. An anonymous pipe is a pipe that goes only in
- * one direction (read pipe, write pipe, etc.). Maybe you are
- * asking, "why would I ever need to do this sort of thing?" One
- * example would be a Windows telnet server, where you spawn a shell
- * and listen on a port and send and receive data between the shell
- * and the socket client. (Windows does not really have a built-in
- * remote shell). First, we should talk about pipes. A pipe in
- * Windows is simply a method of communication, often between
- * process. The SDK defines a pipe as "a communication conduit with
- * two ends; a process with a handle to one end can communicate with
- * a process having a handle to the other end." In our case, we are
- * using "anonymous" pipes, one-way pipes that "transfer data
- * between a parent process and a child process or between two child
- * processes of the same parent process." It's easiest to imagine a
- * pipe as its namesake. An actual pipe running between processes
- * that can carry data. We are using anonymous pipes because the
- * console app we are spawning is a child process. We use the
- * CreatePipe function which will create an anonymous pipe and
- * return a read handle and a write handle. We will create two
- * pipes, on for stdin and one for stdout. We will then monitor the
- * read end of the stdout pipe to check for display on our child
- * process. Every time there is something availabe for reading, we
- * will display it in our app. Consequently, we check for input in
- * our app and send it off to the write end of the stdin pipe.
- */
- static bool BorlandRunCommand(const char* command,
- const char* dir,
- std::string& output, int& retVal,
- bool verbose,
- int timeout, bool hideWindows);
-
-private:
- bool CloseHandles();
- bool PrivateOpen(const char*, const char*, int, int);
- bool PrivateClose(int timeout);
-
- HANDLE ProcessHandle;
- HANDLE hChildStdinRd;
- HANDLE hChildStdinWr;
- HANDLE hChildStdoutRd;
- HANDLE hChildStdoutWr;
- HANDLE hChildStderrRd;
- HANDLE hChildStderrWr;
- HANDLE hChildStdinWrDup;
- HANDLE hChildStdoutRdDup;
- HANDLE hChildStderrRdDup;
-
-
- int pStdIn;
- int pStdOut;
- int pStdErr;
-
- int ExitValue;
-
- std::string Output;
- std::string ConsoleSpawn;
- bool Verbose;
- bool HideWindows;
-};
-
-
-#endif
diff --git a/Source/cmWriteFileCommand.cxx b/Source/cmWriteFileCommand.cxx
index 3642c6fba..cc9f22003 100644
--- a/Source/cmWriteFileCommand.cxx
+++ b/Source/cmWriteFileCommand.cxx
@@ -10,6 +10,7 @@
See the License for more information.
============================================================================*/
#include "cmWriteFileCommand.h"
+#include <cmsys/FStream.hxx>
#include <sys/types.h>
#include <sys/stat.h>
@@ -46,7 +47,7 @@ bool cmWriteFileCommand
{
std::string e = "attempted to write a file: " + fileName
+ " into a source directory.";
- this->SetError(e.c_str());
+ this->SetError(e);
cmSystemTools::SetFatalErrorOccured();
return false;
}
@@ -62,8 +63,6 @@ bool cmWriteFileCommand
cmSystemTools::SetPermissions(fileName.c_str(),
#if defined( _MSC_VER ) || defined( __MINGW32__ )
mode | S_IWRITE
-#elif defined( __BORLANDC__ )
- mode | S_IWUSR
#else
mode | S_IWUSR | S_IWGRP
#endif
@@ -71,14 +70,14 @@ bool cmWriteFileCommand
}
// If GetPermissions fails, pretend like it is ok. File open will fail if
// the file is not writable
- std::ofstream file(fileName.c_str(),
+ cmsys::ofstream file(fileName.c_str(),
overwrite?std::ios::out : std::ios::app);
if ( !file )
{
std::string error = "Internal CMake error when trying to open file: ";
error += fileName.c_str();
error += " for writing.";
- this->SetError(error.c_str());
+ this->SetError(error);
return false;
}
file << message << std::endl;
diff --git a/Source/cmWriteFileCommand.h b/Source/cmWriteFileCommand.h
index 771ef5a1b..89dc9ff6c 100644
--- a/Source/cmWriteFileCommand.h
+++ b/Source/cmWriteFileCommand.h
@@ -44,39 +44,7 @@ public:
/**
* The name of the command as specified in CMakeList.txt.
*/
- virtual const char* GetName() const { return "write_file";}
-
- /**
- * Succinct documentation.
- */
- virtual const char* GetTerseDocumentation() const
- {
- return "Deprecated. Use the file(WRITE ) command instead.";
- }
-
- /**
- * More documentation.
- */
- virtual const char* GetFullDocumentation() const
- {
- return
- " write_file(filename \"message to write\"... [APPEND])\n"
- "The first argument is the file name, the rest of the arguments are "
- "messages to write. If the argument APPEND is specified, then "
- "the message will be appended.\n"
- "NOTE 1: file(WRITE ... and file(APPEND ... do exactly the same as "
- "this one but add some more functionality.\n"
- "NOTE 2: When using write_file the produced file cannot be used as an "
- "input to CMake (CONFIGURE_FILE, source file ...) because it will "
- "lead to an infinite loop. Use configure_file if you want to generate "
- "input files to CMake.";
- }
-
- /** This command is kept for compatibility with older CMake versions. */
- virtual bool IsDiscouraged() const
- {
- return true;
- }
+ virtual std::string GetName() const { return "write_file";}
cmTypeMacro(cmWriteFileCommand, cmCommand);
};
diff --git a/Source/cmXCode21Object.cxx b/Source/cmXCode21Object.cxx
index 855e1ad2f..3973540bf 100644
--- a/Source/cmXCode21Object.cxx
+++ b/Source/cmXCode21Object.cxx
@@ -22,7 +22,7 @@ cmXCode21Object::cmXCode21Object(PBXType ptype, Type type)
//----------------------------------------------------------------------------
void cmXCode21Object::PrintComment(std::ostream& out)
{
- if(this->Comment.size() == 0)
+ if(this->Comment.empty())
{
cmXCodeObject* n = this->GetObject("name");
if(n)
@@ -31,7 +31,11 @@ void cmXCode21Object::PrintComment(std::ostream& out)
cmSystemTools::ReplaceString(this->Comment, "\"", "");
}
}
- out << "/* ";
+ if(this->Comment.empty())
+ {
+ return;
+ }
+ out << " /* ";
out << this->Comment;
out << " */";
}
diff --git a/Source/cmXCodeObject.cxx b/Source/cmXCodeObject.cxx
index 6abf6bf00..5bc34c136 100644
--- a/Source/cmXCodeObject.cxx
+++ b/Source/cmXCodeObject.cxx
@@ -81,7 +81,7 @@ void cmXCodeObject::Indent(int level, std::ostream& out)
{
while(level)
{
- out << " ";
+ out << "\t";
level--;
}
}
@@ -91,24 +91,21 @@ void cmXCodeObject::Print(std::ostream& out)
{
std::string separator = "\n";
int indentFactor = 1;
+ cmXCodeObject::Indent(2*indentFactor, out);
if(this->Version > 15
&& (this->IsA == PBXFileReference || this->IsA == PBXBuildFile))
{
separator = " ";
indentFactor = 0;
}
- cmXCodeObject::Indent(2*indentFactor, out);
- out << this->Id << " ";
- if(!(this->IsA == PBXGroup && this->Comment.size() == 0))
- {
- this->PrintComment(out);
- }
+ out << this->Id;
+ this->PrintComment(out);
out << " = {";
if(separator == "\n")
{
out << separator;
}
- std::map<cmStdString, cmXCodeObject*>::iterator i;
+ std::map<std::string, cmXCodeObject*>::iterator i;
cmXCodeObject::Indent(3*indentFactor, out);
out << "isa = " << PBXTypeNames[this->IsA] << ";" << separator;
for(i = this->ObjectAttributes.begin();
@@ -129,7 +126,7 @@ void cmXCodeObject::Print(std::ostream& out)
for(unsigned int k = 0; k < i->second->List.size(); k++)
{
cmXCodeObject::Indent(4*indentFactor, out);
- out << i->second->List[k]->Id << " ";
+ out << i->second->List[k]->Id;
i->second->List[k]->PrintComment(out);
out << "," << separator;
}
@@ -138,8 +135,12 @@ void cmXCodeObject::Print(std::ostream& out)
}
else if(object->TypeValue == ATTRIBUTE_GROUP)
{
- std::map<cmStdString, cmXCodeObject*>::iterator j;
- out << i->first << " = {" << separator;
+ std::map<std::string, cmXCodeObject*>::iterator j;
+ out << i->first << " = {";
+ if(separator == "\n")
+ {
+ out << separator;
+ }
for(j = object->ObjectAttributes.begin(); j !=
object->ObjectAttributes.end(); ++j)
{
@@ -188,7 +189,6 @@ void cmXCodeObject::Print(std::ostream& out)
out << " = " << object->Object->Id;
if(object->Object->HasComment() && i->first != "remoteGlobalIDString")
{
- out << " ";
object->Object->PrintComment(out);
}
out << ";" << separator;
@@ -236,13 +236,18 @@ void cmXCodeObject::CopyAttributes(cmXCodeObject* copy)
}
//----------------------------------------------------------------------------
-void cmXCodeObject::PrintString(std::ostream& os,cmStdString String)
+void cmXCodeObject::PrintString(std::ostream& os,std::string String)
{
// The string needs to be quoted if it contains any characters
// considered special by the Xcode project file parser.
bool needQuote =
(String.empty() ||
- String.find_first_of(" <>.+-=@$[],") != String.npos);
+ String.find("//") != String.npos ||
+ String.find_first_not_of(
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789"
+ "$_./") != String.npos);
const char* quote = needQuote? "\"" : "";
// Print the string, quoted and escaped as necessary.
@@ -250,9 +255,9 @@ void cmXCodeObject::PrintString(std::ostream& os,cmStdString String)
for(std::string::const_iterator i = String.begin();
i != String.end(); ++i)
{
- if(*i == '"')
+ if(*i == '"' || *i == '\\')
{
- // Escape double-quotes.
+ // Escape double-quotes and backslashes.
os << '\\';
}
os << *i;
@@ -266,7 +271,7 @@ void cmXCodeObject::PrintString(std::ostream& os) const
}
//----------------------------------------------------------------------------
-void cmXCodeObject::SetString(const char* s)
+void cmXCodeObject::SetString(const std::string& s)
{
this->String = s;
}
diff --git a/Source/cmXCodeObject.h b/Source/cmXCodeObject.h
index b89f78cf3..bd0f43f57 100644
--- a/Source/cmXCodeObject.h
+++ b/Source/cmXCodeObject.h
@@ -13,7 +13,7 @@
#define cmXCodeObject_h
#include "cmStandardIncludes.h"
-class cmTarget;
+class cmGeneratorTarget;
class cmXCodeObject
{
@@ -30,20 +30,20 @@ public:
PBXCopyFilesBuildPhase,
None
};
- class StringVec: public std::vector<cmStdString> {};
+ class StringVec: public std::vector<std::string> {};
static const char* PBXTypeNames[];
virtual ~cmXCodeObject();
cmXCodeObject(PBXType ptype, Type type);
Type GetType() { return this->TypeValue;}
PBXType GetIsA() { return this->IsA;}
- void SetString(const char* s);
- const char* GetString()
+ void SetString(const std::string& s);
+ const std::string& GetString()
{
- return this->String.c_str();
+ return this->String;
}
- void AddAttribute(const char* name, cmXCodeObject* value)
+ void AddAttribute(const std::string& name, cmXCodeObject* value)
{
this->ObjectAttributes[name] = value;
}
@@ -75,28 +75,28 @@ public:
}
static void Indent(int level, std::ostream& out);
void Print(std::ostream& out);
- virtual void PrintComment(std::ostream&) {};
+ virtual void PrintComment(std::ostream&) {}
static void PrintList(std::vector<cmXCodeObject*> const&,
std::ostream& out);
- const char* GetId()
+ const std::string& GetId()
{
- return this->Id.c_str();
+ return this->Id;
}
- void SetId(const char* id)
+ void SetId(const std::string& id)
{
this->Id = id;
}
- cmTarget* GetTarget()
+ cmGeneratorTarget* GetTarget()
{
return this->Target;
}
- void SetTarget(cmTarget* t)
+ void SetTarget(cmGeneratorTarget* t)
{
this->Target = t;
}
- const char* GetComment() {return this->Comment.c_str();}
- bool HasComment() { return (this->Comment.size() != 0);}
+ const std::string& GetComment() {return this->Comment;}
+ bool HasComment() { return (!this->Comment.empty());}
cmXCodeObject* GetObject(const char* name)
{
if(this->ObjectAttributes.count(name))
@@ -105,7 +105,7 @@ public:
}
return 0;
}
- // serach the attribute list for an object of the specified type
+ // search the attribute list for an object of the specified type
cmXCodeObject* GetObject(cmXCodeObject::PBXType t)
{
for(std::vector<cmXCodeObject*>::iterator i = this->List.begin();
@@ -122,49 +122,41 @@ public:
void CopyAttributes(cmXCodeObject* );
- void AddDependLibrary(const char* configName,
- const char* l)
+ void AddDependLibrary(const std::string& configName,
+ const std::string& l)
{
- if(!configName)
- {
- configName = "";
- }
this->DependLibraries[configName].push_back(l);
}
- std::map<cmStdString, StringVec> const& GetDependLibraries()
+ std::map<std::string, StringVec> const& GetDependLibraries()
{
return this->DependLibraries;
}
- void AddDependTarget(const char* configName,
- const char* tName)
+ void AddDependTarget(const std::string& configName,
+ const std::string& tName)
{
- if(!configName)
- {
- configName = "";
- }
this->DependTargets[configName].push_back(tName);
}
- std::map<cmStdString, StringVec> const& GetDependTargets()
+ std::map<std::string, StringVec> const& GetDependTargets()
{
return this->DependTargets;
}
std::vector<cmXCodeObject*> const& GetObjectList() { return this->List;}
- void SetComment(const char* c) { this->Comment = c;}
- static void PrintString(std::ostream& os,cmStdString String);
+ void SetComment(const std::string& c) { this->Comment = c;}
+ static void PrintString(std::ostream& os,std::string String);
protected:
void PrintString(std::ostream& os) const;
- cmTarget* Target;
+ cmGeneratorTarget* Target;
Type TypeValue;
- cmStdString Id;
+ std::string Id;
PBXType IsA;
int Version;
- cmStdString Comment;
- cmStdString String;
+ std::string Comment;
+ std::string String;
cmXCodeObject* Object;
std::vector<cmXCodeObject*> List;
- std::map<cmStdString, StringVec> DependLibraries;
- std::map<cmStdString, StringVec> DependTargets;
- std::map<cmStdString, cmXCodeObject*> ObjectAttributes;
+ std::map<std::string, StringVec> DependLibraries;
+ std::map<std::string, StringVec> DependTargets;
+ std::map<std::string, cmXCodeObject*> ObjectAttributes;
};
#endif
diff --git a/Source/cmXMLParser.cxx b/Source/cmXMLParser.cxx
index 882fc172e..1d3e0e937 100644
--- a/Source/cmXMLParser.cxx
+++ b/Source/cmXMLParser.cxx
@@ -10,6 +10,7 @@
See the License for more information.
============================================================================*/
#include "cmXMLParser.h"
+#include <cmsys/FStream.hxx>
#include <cm_expat.h>
#include <ctype.h>
@@ -19,6 +20,8 @@ cmXMLParser::cmXMLParser()
{
this->Parser = 0;
this->ParseError = 0;
+ this->ReportCallback = 0;
+ this->ReportCallbackData = 0;
}
//----------------------------------------------------------------------------
@@ -45,13 +48,13 @@ int cmXMLParser::ParseFile(const char* file)
return 0;
}
- std::ifstream ifs(file);
+ cmsys::ifstream ifs(file);
if ( !ifs )
{
return 0;
}
- cmOStringStream str;
+ std::ostringstream str;
str << ifs.rdbuf();
return this->Parse(str.str().c_str());
}
@@ -151,14 +154,14 @@ int cmXMLParser::ParsingComplete()
}
//----------------------------------------------------------------------------
-void cmXMLParser::StartElement(const char * name,
+void cmXMLParser::StartElement(const std::string& name,
const char ** /*atts*/)
{
std::cout << "Start element: " << name << std::endl;
}
//----------------------------------------------------------------------------
-void cmXMLParser::EndElement(const char * name)
+void cmXMLParser::EndElement(const std::string& name)
{
std::cout << "End element: " << name << std::endl;
}
@@ -232,6 +235,13 @@ void cmXMLParser::ReportXmlParseError()
//----------------------------------------------------------------------------
void cmXMLParser::ReportError(int line, int, const char* msg)
{
- std::cerr << "Error parsing XML in stream at line "
- << line << ": " << msg << std::endl;
+ if(this->ReportCallback)
+ {
+ this->ReportCallback(line, msg, this->ReportCallbackData);
+ }
+ else
+ {
+ std::cerr << "Error parsing XML in stream at line "
+ << line << ": " << msg << std::endl;
+ }
}
diff --git a/Source/cmXMLParser.h b/Source/cmXMLParser.h
index d916075e5..e72da66b3 100644
--- a/Source/cmXMLParser.h
+++ b/Source/cmXMLParser.h
@@ -50,11 +50,18 @@ public:
virtual int ParseChunk(const char* inputString,
std::string::size_type length);
virtual int CleanupParser();
-
+ typedef void (*ReportFunction)(int, const char*, void*);
+ void SetErrorCallback(ReportFunction f, void* d)
+ {
+ this->ReportCallback = f;
+ this->ReportCallbackData = d;
+ }
protected:
//! This variable is true if there was a parse error while parsing in
//chunks.
int ParseError;
+ ReportFunction ReportCallback;
+ void* ReportCallbackData;
//1 Expat parser structure. Exists only during call to Parse().
void* Parser;
@@ -74,11 +81,11 @@ protected:
* element. atts = Null-terminated array of attribute name/value pairs.
* Even indices are attribute names, and odd indices are values.
*/
- virtual void StartElement(const char* name, const char** atts);
+ virtual void StartElement(const std::string& name, const char** atts);
//! Called at the end of an element in the XML source opened when
//StartElement was called.
- virtual void EndElement(const char* name);
+ virtual void EndElement(const std::string& name);
//! Called when there is character data to handle.
virtual void CharacterDataHandler(const char* data, int length);
diff --git a/Source/cmXMLSafe.cxx b/Source/cmXMLSafe.cxx
index 72fdc3466..4ad05ca31 100644
--- a/Source/cmXMLSafe.cxx
+++ b/Source/cmXMLSafe.cxx
@@ -13,8 +13,8 @@
#include "cm_utf8.h"
-#include <cmsys/ios/iostream>
-#include <cmsys/ios/sstream>
+#include <iostream>
+#include <sstream>
#include <string.h>
#include <stdio.h>
@@ -28,7 +28,7 @@ cmXMLSafe::cmXMLSafe(const char* s):
}
//----------------------------------------------------------------------------
-cmXMLSafe::cmXMLSafe(cmsys_stl::string const& s):
+cmXMLSafe::cmXMLSafe(std::string const& s):
Data(s.c_str()),
Size(static_cast<unsigned long>(s.length())),
DoQuotes(true)
@@ -43,15 +43,15 @@ cmXMLSafe& cmXMLSafe::Quotes(bool b)
}
//----------------------------------------------------------------------------
-cmsys_stl::string cmXMLSafe::str()
+std::string cmXMLSafe::str()
{
- cmsys_ios::ostringstream ss;
+ std::ostringstream ss;
ss << *this;
return ss.str();
}
//----------------------------------------------------------------------------
-cmsys_ios::ostream& operator<<(cmsys_ios::ostream& os, cmXMLSafe const& self)
+std::ostream& operator<<(std::ostream& os, cmXMLSafe const& self)
{
char const* first = self.Data;
char const* last = self.Data + self.Size;
diff --git a/Source/cmXMLSafe.h b/Source/cmXMLSafe.h
index cba9f390d..ead2e014c 100644
--- a/Source/cmXMLSafe.h
+++ b/Source/cmXMLSafe.h
@@ -12,8 +12,9 @@
#ifndef cmXMLSafe_h
#define cmXMLSafe_h
-#include <cmsys/stl/string>
-#include <cmsys/ios/iosfwd>
+#include <cmsys/Configure.hxx>
+#include <string>
+#include <iosfwd>
/** \class cmXMLSafe
* \brief Write strings to XML with proper escapes
@@ -24,7 +25,7 @@ public:
/** Construct with the data to be written. This assumes the data
will exist for the duration of this object's life. */
cmXMLSafe(const char* s);
- cmXMLSafe(cmsys_stl::string const& s);
+ cmXMLSafe(std::string const& s);
/** Specify whether to escape quotes too. This is needed when
writing the content of an attribute value. By default quotes
@@ -32,13 +33,12 @@ public:
cmXMLSafe& Quotes(bool b = true);
/** Get the escaped data as a string. */
- cmsys_stl::string str();
+ std::string str();
private:
char const* Data;
unsigned long Size;
bool DoQuotes;
- friend cmsys_ios::ostream& operator<<(cmsys_ios::ostream&,
- cmXMLSafe const&);
+ friend std::ostream& operator<<(std::ostream&, cmXMLSafe const&);
};
#endif
diff --git a/Source/cmXMLWriter.cxx b/Source/cmXMLWriter.cxx
new file mode 100644
index 000000000..f9b3b491c
--- /dev/null
+++ b/Source/cmXMLWriter.cxx
@@ -0,0 +1,134 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Daniel Pfeifer <daniel@pfeifer-mail.de>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmXMLWriter.h"
+#include "cmXMLSafe.h"
+
+#include <cassert>
+#include <fstream>
+
+cmXMLWriter::cmXMLWriter(std::ostream& output, std::size_t level)
+: Output(output)
+, Level(level)
+, ElementOpen(false)
+, BreakAttrib(false)
+, IsContent(false)
+{
+}
+
+cmXMLWriter::~cmXMLWriter()
+{
+ assert(this->Elements.empty());
+}
+
+void cmXMLWriter::StartDocument(const char* encoding)
+{
+ this->Output << "<?xml version=\"1.0\" encoding=\"" << encoding << "\"?>";
+}
+
+void cmXMLWriter::EndDocument()
+{
+ assert(this->Elements.empty());
+ this->Output << '\n';
+}
+
+void cmXMLWriter::StartElement(std::string const& name)
+{
+ this->CloseStartElement();
+ this->ConditionalLineBreak(!this->IsContent, this->Elements.size());
+ this->Output << '<' << name;
+ this->Elements.push(name);
+ this->ElementOpen = true;
+ this->BreakAttrib = false;
+}
+
+void cmXMLWriter::EndElement()
+{
+ assert(!this->Elements.empty());
+ if (this->ElementOpen)
+ {
+ this->Output << "/>";
+ }
+ else
+ {
+ this->ConditionalLineBreak(!this->IsContent, this->Elements.size() - 1);
+ this->IsContent = false;
+ this->Output << "</" << this->Elements.top() << '>';
+ }
+ this->Elements.pop();
+ this->ElementOpen = false;
+}
+
+void cmXMLWriter::BreakAttributes()
+{
+ this->BreakAttrib = true;
+}
+
+void cmXMLWriter::Comment(const char* comment)
+{
+ this->CloseStartElement();
+ this->ConditionalLineBreak(!this->IsContent, this->Elements.size());
+ this->Output << "<!-- " << comment << " -->";
+}
+
+void cmXMLWriter::CData(std::string const& data)
+{
+ this->PreContent();
+ this->Output << "<![CDATA[" << data << "]]>";
+}
+
+void cmXMLWriter::ProcessingInstruction(const char* target, const char* data)
+{
+ this->CloseStartElement();
+ this->ConditionalLineBreak(!this->IsContent, this->Elements.size());
+ this->Output << "<?" << target << ' ' << data << "?>";
+}
+
+void cmXMLWriter::FragmentFile(const char* fname)
+{
+ this->CloseStartElement();
+ std::ifstream fin(fname, std::ios::in | std::ios::binary);
+ this->Output << fin.rdbuf();
+}
+
+void cmXMLWriter::ConditionalLineBreak(bool condition, std::size_t indent)
+{
+ if (condition)
+ {
+ this->Output << '\n' << std::string(indent + this->Level, '\t');
+ }
+}
+
+void cmXMLWriter::PreAttribute()
+{
+ assert(this->ElementOpen);
+ this->ConditionalLineBreak(this->BreakAttrib, this->Elements.size());
+ if (!this->BreakAttrib)
+ {
+ this->Output << ' ';
+ }
+}
+
+void cmXMLWriter::PreContent()
+{
+ this->CloseStartElement();
+ this->IsContent = true;
+}
+
+void cmXMLWriter::CloseStartElement()
+{
+ if (this->ElementOpen)
+ {
+ this->ConditionalLineBreak(this->BreakAttrib, this->Elements.size());
+ this->Output << '>';
+ this->ElementOpen = false;
+ }
+}
diff --git a/Source/cmXMLWriter.h b/Source/cmXMLWriter.h
new file mode 100644
index 000000000..c38c0deb7
--- /dev/null
+++ b/Source/cmXMLWriter.h
@@ -0,0 +1,120 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Daniel Pfeifer <daniel@pfeifer-mail.de>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmXMLWiter_h
+#define cmXMLWiter_h
+
+#include "cmStandardIncludes.h"
+#include "cmXMLSafe.h"
+
+#include <ostream>
+#include <stack>
+#include <string>
+#include <vector>
+
+class cmXMLWriter
+{
+public:
+ cmXMLWriter(std::ostream& output, std::size_t level = 0);
+ ~cmXMLWriter();
+
+ void StartDocument(const char* encoding = "UTF-8");
+ void EndDocument();
+
+ void StartElement(std::string const& name);
+ void EndElement();
+
+ void BreakAttributes();
+
+ template <typename T>
+ void Attribute(const char* name, T const& value)
+ {
+ this->PreAttribute();
+ this->Output << name << "=\"" << SafeAttribute(value) << '"';
+ }
+
+ template <typename T>
+ void Element(std::string const& name, T const& value)
+ {
+ this->StartElement(name);
+ this->Content(value);
+ this->EndElement();
+ }
+
+ template <typename T>
+ void Content(T const& content)
+ {
+ this->PreContent();
+ this->Output << SafeContent(content);
+ }
+
+ void Comment(const char* comment);
+
+ void CData(std::string const& data);
+
+ void ProcessingInstruction(const char* target, const char* data);
+
+ void FragmentFile(const char* fname);
+
+private:
+ cmXMLWriter(const cmXMLWriter&);
+ cmXMLWriter& operator=(const cmXMLWriter&);
+
+ void ConditionalLineBreak(bool condition, std::size_t indent);
+
+ void PreAttribute();
+ void PreContent();
+
+ void CloseStartElement();
+
+private:
+ static cmXMLSafe SafeAttribute(const char* value)
+ {
+ return cmXMLSafe(value);
+ }
+
+ static cmXMLSafe SafeAttribute(std::string const& value)
+ {
+ return cmXMLSafe(value);
+ }
+
+ template <typename T>
+ static T SafeAttribute(T value)
+ {
+ return value;
+ }
+
+ static cmXMLSafe SafeContent(const char* value)
+ {
+ return cmXMLSafe(value).Quotes(false);
+ }
+
+ static cmXMLSafe SafeContent(std::string const& value)
+ {
+ return cmXMLSafe(value).Quotes(false);
+ }
+
+ template <typename T>
+ static T SafeContent(T value)
+ {
+ return value;
+ }
+
+private:
+ std::ostream& Output;
+ std::stack<std::string, std::vector<std::string> > Elements;
+ std::size_t Level;
+ bool ElementOpen;
+ bool BreakAttrib;
+ bool IsContent;
+};
+
+#endif
diff --git a/Source/cm_get_date.c b/Source/cm_get_date.c
new file mode 100644
index 000000000..2e0d4bdd8
--- /dev/null
+++ b/Source/cm_get_date.c
@@ -0,0 +1,16 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cm_get_date.h"
+
+#define __archive_get_date cm_get_date
+
+#include "../Utilities/cmlibarchive/libarchive/archive_getdate.c"
diff --git a/Source/cm_get_date.h b/Source/cm_get_date.h
new file mode 100644
index 000000000..d5f6d3e0a
--- /dev/null
+++ b/Source/cm_get_date.h
@@ -0,0 +1,28 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cm_get_date_h
+#define cm_get_date_h
+
+#include <time.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Parse a date/time string. Treat relative times with respect to 'now'. */
+time_t cm_get_date(time_t now, const char *str);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif
diff --git a/Source/cm_sha2.c b/Source/cm_sha2.c
index 24de2b294..649c39aaf 100644
--- a/Source/cm_sha2.c
+++ b/Source/cm_sha2.c
@@ -87,25 +87,21 @@
* made).
*/
#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
-/* CMake modification: use byte order from cmIML. */
-# include "cmIML/ABI.h"
+/* CMake modification: use byte order from KWIML. */
# undef BYTE_ORDER
# undef BIG_ENDIAN
# undef LITTLE_ENDIAN
-# define BYTE_ORDER cmIML_ABI_ENDIAN_ID
-# define BIG_ENDIAN cmIML_ABI_ENDIAN_ID_BIG
-# define LITTLE_ENDIAN cmIML_ABI_ENDIAN_ID_LITTLE
+# define BYTE_ORDER KWIML_ABI_ENDIAN_ID
+# define BIG_ENDIAN KWIML_ABI_ENDIAN_ID_BIG
+# define LITTLE_ENDIAN KWIML_ABI_ENDIAN_ID_LITTLE
#endif
/* CMake modification: use types computed in header. */
typedef cm_sha2_uint8_t sha_byte; /* Exactly 1 byte */
typedef cm_sha2_uint32_t sha_word32; /* Exactly 4 bytes */
typedef cm_sha2_uint64_t sha_word64; /* Exactly 8 bytes */
-#define SHA_UINT32_C(x) cmIML_INT_UINT32_C(x)
-#define SHA_UINT64_C(x) cmIML_INT_UINT64_C(x)
-#if defined(__BORLANDC__)
-# pragma warn -8004 /* variable assigned value that is never used */
-#endif
+#define SHA_UINT32_C(x) KWIML_INT_UINT32_C(x)
+#define SHA_UINT64_C(x) KWIML_INT_UINT64_C(x)
#if defined(__clang__)
# pragma clang diagnostic ignored "-Wcast-align"
#endif
@@ -666,7 +662,7 @@ void SHA1_Update(SHA_CTX* context, const sha_byte *data, size_t len) {
context->s1.bitcount += freespace << 3;
len -= freespace;
data += freespace;
- SHA1_Internal_Transform(context, (sha_word32*)context->s1.buffer);
+ SHA1_Internal_Transform(context, (const sha_word32*)context->s1.buffer);
} else {
/* The buffer is not yet full */
MEMCPY_BCOPY(&context->s1.buffer[usedspace], data, len);
@@ -678,7 +674,7 @@ void SHA1_Update(SHA_CTX* context, const sha_byte *data, size_t len) {
}
while (len >= 64) {
/* Process as many complete blocks as we can */
- SHA1_Internal_Transform(context, (sha_word32*)data);
+ SHA1_Internal_Transform(context, (const sha_word32*)data);
context->s1.bitcount += 512;
len -= 64;
data += 64;
@@ -727,7 +723,7 @@ void SHA1_Final(sha_byte digest[], SHA_CTX* context) {
MEMSET_BZERO(&context->s1.buffer[usedspace], 64 - usedspace);
}
/* Do second-to-last transform: */
- SHA1_Internal_Transform(context, (sha_word32*)context->s1.buffer);
+ SHA1_Internal_Transform(context, (const sha_word32*)context->s1.buffer);
/* And set-up for the last transform: */
MEMSET_BZERO(context->s1.buffer, 56);
@@ -744,7 +740,7 @@ void SHA1_Final(sha_byte digest[], SHA_CTX* context) {
sizeof(sha_word64));
/* Final transform: */
- SHA1_Internal_Transform(context, (sha_word32*)context->s1.buffer);
+ SHA1_Internal_Transform(context, (const sha_word32*)context->s1.buffer);
/* Save the hash data for output: */
#if BYTE_ORDER == LITTLE_ENDIAN
@@ -1007,7 +1003,7 @@ void SHA256_Update(SHA_CTX* context, const sha_byte *data, size_t len) {
context->s256.bitcount += freespace << 3;
len -= freespace;
data += freespace;
- SHA256_Internal_Transform(context, (sha_word32*)context->s256.buffer);
+ SHA256_Internal_Transform(context, (const sha_word32*)context->s256.buffer);
} else {
/* The buffer is not yet full */
MEMCPY_BCOPY(&context->s256.buffer[usedspace], data, len);
@@ -1019,7 +1015,7 @@ void SHA256_Update(SHA_CTX* context, const sha_byte *data, size_t len) {
}
while (len >= 64) {
/* Process as many complete blocks as we can */
- SHA256_Internal_Transform(context, (sha_word32*)data);
+ SHA256_Internal_Transform(context, (const sha_word32*)data);
context->s256.bitcount += 512;
len -= 64;
data += 64;
@@ -1053,7 +1049,7 @@ void SHA256_Internal_Last(SHA_CTX* context) {
MEMSET_BZERO(&context->s256.buffer[usedspace], 64 - usedspace);
}
/* Do second-to-last transform: */
- SHA256_Internal_Transform(context, (sha_word32*)context->s256.buffer);
+ SHA256_Internal_Transform(context, (const sha_word32*)context->s256.buffer);
/* And set-up for the last transform: */
MEMSET_BZERO(context->s256.buffer, 56);
@@ -1072,7 +1068,7 @@ void SHA256_Internal_Last(SHA_CTX* context) {
sizeof(sha_word64));
/* Final transform: */
- SHA256_Internal_Transform(context, (sha_word32*)context->s256.buffer);
+ SHA256_Internal_Transform(context, (const sha_word32*)context->s256.buffer);
}
void SHA256_Final(sha_byte digest[], SHA_CTX* context) {
@@ -1415,7 +1411,7 @@ void SHA512_Update(SHA_CTX* context, const sha_byte *data, size_t len) {
ADDINC128(context->s512.bitcount, freespace << 3);
len -= freespace;
data += freespace;
- SHA512_Internal_Transform(context, (sha_word64*)context->s512.buffer);
+ SHA512_Internal_Transform(context, (const sha_word64*)context->s512.buffer);
} else {
/* The buffer is not yet full */
MEMCPY_BCOPY(&context->s512.buffer[usedspace], data, len);
@@ -1427,7 +1423,7 @@ void SHA512_Update(SHA_CTX* context, const sha_byte *data, size_t len) {
}
while (len >= 128) {
/* Process as many complete blocks as we can */
- SHA512_Internal_Transform(context, (sha_word64*)data);
+ SHA512_Internal_Transform(context, (const sha_word64*)data);
ADDINC128(context->s512.bitcount, 1024);
len -= 128;
data += 128;
@@ -1462,7 +1458,7 @@ void SHA512_Internal_Last(SHA_CTX* context) {
MEMSET_BZERO(&context->s512.buffer[usedspace], 128 - usedspace);
}
/* Do second-to-last transform: */
- SHA512_Internal_Transform(context, (sha_word64*)context->s512.buffer);
+ SHA512_Internal_Transform(context, (const sha_word64*)context->s512.buffer);
/* And set-up for the last transform: */
MEMSET_BZERO(context->s512.buffer, 112);
@@ -1483,7 +1479,7 @@ void SHA512_Internal_Last(SHA_CTX* context) {
sizeof(sha_word64));
/* Final transform: */
- SHA512_Internal_Transform(context, (sha_word64*)context->s512.buffer);
+ SHA512_Internal_Transform(context, (const sha_word64*)context->s512.buffer);
}
void SHA512_Final(sha_byte digest[], SHA_CTX* context) {
diff --git a/Source/cm_sha2.h b/Source/cm_sha2.h
index 71395f06b..f1510318c 100644
--- a/Source/cm_sha2.h
+++ b/Source/cm_sha2.h
@@ -38,11 +38,11 @@
#include "cm_sha2_mangle.h"
-/* CMake modification: use integer types from cmIML. */
-#include "cmIML/INT.h"
-typedef cmIML_INT_uint8_t cm_sha2_uint8_t;
-typedef cmIML_INT_uint32_t cm_sha2_uint32_t;
-typedef cmIML_INT_uint64_t cm_sha2_uint64_t;
+/* CMake modification: use integer types from KWIML. */
+#include <cm_kwiml.h>
+typedef KWIML_INT_uint8_t cm_sha2_uint8_t;
+typedef KWIML_INT_uint32_t cm_sha2_uint32_t;
+typedef KWIML_INT_uint64_t cm_sha2_uint64_t;
#ifdef __cplusplus
extern "C" {
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 14ddc1b01..8f6b9524a 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -10,34 +10,27 @@
See the License for more information.
============================================================================*/
#include "cmake.h"
-#include "cmDocumentVariables.h"
-#include "time.h"
-#include "cmCacheManager.h"
#include "cmMakefile.h"
#include "cmLocalGenerator.h"
#include "cmExternalMakefileProjectGenerator.h"
#include "cmCommands.h"
#include "cmCommand.h"
#include "cmFileTimeComparison.h"
-#include "cmGeneratedFileStream.h"
-#include "cmQtAutomoc.h"
#include "cmSourceFile.h"
-#include "cmVersion.h"
#include "cmTest.h"
-#include "cmDocumentationFormatterText.h"
+#include "cmDocumentationFormatter.h"
+#include "cmAlgorithms.h"
+#include "cmState.h"
#if defined(CMAKE_BUILD_WITH_CMAKE)
# include "cmGraphVizWriter.h"
-# include "cmDependsFortran.h" // For -E cmake_copy_f90_mod callback.
# include "cmVariableWatch.h"
-# include <cmsys/Terminal.h>
-# include <cmsys/CommandLineArguments.hxx>
+# include <cmsys/SystemInformation.hxx>
#endif
-#include <cmsys/Directory.hxx>
-#include <cmsys/Process.h>
#include <cmsys/Glob.hxx>
#include <cmsys/RegularExpression.hxx>
+#include <cmsys/FStream.hxx>
// only build kdevelop generator on non-windows platforms
// when not bootstrapping cmake
@@ -66,30 +59,31 @@
# include "cmGlobalVisualStudio10Generator.h"
# include "cmGlobalVisualStudio11Generator.h"
# include "cmGlobalVisualStudio12Generator.h"
+# include "cmGlobalVisualStudio14Generator.h"
# include "cmGlobalBorlandMakefileGenerator.h"
# include "cmGlobalNMakeMakefileGenerator.h"
# include "cmGlobalJOMMakefileGenerator.h"
-# include "cmGlobalWatcomWMakeGenerator.h"
+# include "cmGlobalGhsMultiGenerator.h"
# define CMAKE_HAVE_VS_GENERATORS
# endif
# include "cmGlobalMSYSMakefileGenerator.h"
# include "cmGlobalMinGWMakefileGenerator.h"
-# include "cmWin32ProcessExecution.h"
#else
#endif
+#if defined(CMAKE_USE_WMAKE)
+# include "cmGlobalWatcomWMakeGenerator.h"
+#endif
#include "cmGlobalUnixMakefileGenerator3.h"
-#include "cmGlobalNinjaGenerator.h"
-
-
-#if defined(CMAKE_HAVE_VS_GENERATORS)
-#include "cmCallVisualStudioMacro.h"
-#include "cmVisualStudioWCEPlatformParser.h"
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+# include "cmGlobalNinjaGenerator.h"
#endif
+#include "cmExtraCodeLiteGenerator.h"
#if !defined(CMAKE_BOOT_MINGW)
# include "cmExtraCodeBlocksGenerator.h"
#endif
#include "cmExtraSublimeTextGenerator.h"
+#include "cmExtraKateGenerator.h"
#ifdef CMAKE_USE_KDEVELOP
# include "cmGlobalKdevelopGenerator.h"
@@ -113,33 +107,11 @@
#include <sys/stat.h> // struct stat
+#include <list>
+
static bool cmakeCheckStampFile(const char* stampName);
static bool cmakeCheckStampList(const char* stampName);
-void cmNeedBackwardsCompatibility(const std::string& variable,
- int access_type, void*, const char*, const cmMakefile*)
-{
-#ifdef CMAKE_BUILD_WITH_CMAKE
- if (access_type == cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS)
- {
- std::string message = "An attempt was made to access a variable: ";
- message += variable;
- message +=
- " that has not been defined. Some variables were always defined "
- "by CMake in versions prior to 1.6. To fix this you might need to set "
- "the cache value of CMAKE_BACKWARDS_COMPATIBILITY to 1.4 or less. If "
- "you are writing a CMakeLists file, (or have already set "
- "CMAKE_BACKWARDS_COMPATIBILITY to 1.4 or less) then you probably need "
- "to include a CMake module to test for the feature this variable "
- "defines.";
- cmSystemTools::Error(message.c_str());
- }
-#else
- (void)variable;
- (void)access_type;
-#endif
-}
-
void cmWarnUnusedCliWarning(const std::string& variable,
int, void* ctx, const char*, const cmMakefile*)
{
@@ -150,19 +122,18 @@ void cmWarnUnusedCliWarning(const std::string& variable,
cmake::cmake()
{
this->Trace = false;
+ this->TraceExpand = false;
this->WarnUninitialized = false;
this->WarnUnused = false;
this->WarnUnusedCli = true;
this->CheckSystemVars = false;
- this->SuppressDevWarnings = false;
- this->DoSuppressDevWarnings = false;
this->DebugOutput = false;
this->DebugTryCompile = false;
this->ClearBuildSystem = false;
this->FileComparison = new cmFileTimeComparison;
- this->Policies = new cmPolicies();
- this->InitializeProperties();
+ this->State = new cmState;
+ this->CurrentSnapshot = this->State->CreateBaseSnapshot();
#ifdef __APPLE__
struct rlimit rlp;
@@ -177,8 +148,6 @@ cmake::cmake()
#endif
this->Verbose = false;
- this->InTryCompile = false;
- this->CacheManager = new cmCacheManager(this);
this->GlobalGenerator = 0;
this->ProgressCallback = 0;
this->ProgressCallbackClientData = 0;
@@ -186,12 +155,6 @@ cmake::cmake()
#ifdef CMAKE_BUILD_WITH_CMAKE
this->VariableWatch = new cmVariableWatch;
- this->VariableWatch->AddWatch("CMAKE_WORDS_BIGENDIAN",
- cmNeedBackwardsCompatibility);
- this->VariableWatch->AddWatch("CMAKE_SIZEOF_INT",
- cmNeedBackwardsCompatibility);
- this->VariableWatch->AddWatch("CMAKE_X_LIBS",
- cmNeedBackwardsCompatibility);
#endif
this->AddDefaultGenerators();
@@ -200,161 +163,52 @@ cmake::cmake()
// Make sure we can capture the build tool output.
cmSystemTools::EnableVSConsoleOutput();
+
+ // Set up a list of source and header extensions
+ // these are used to find files when the extension
+ // is not given
+ // The "c" extension MUST precede the "C" extension.
+ this->SourceFileExtensions.push_back( "c" );
+ this->SourceFileExtensions.push_back( "C" );
+
+ this->SourceFileExtensions.push_back( "c++" );
+ this->SourceFileExtensions.push_back( "cc" );
+ this->SourceFileExtensions.push_back( "cpp" );
+ this->SourceFileExtensions.push_back( "cxx" );
+ this->SourceFileExtensions.push_back( "m" );
+ this->SourceFileExtensions.push_back( "M" );
+ this->SourceFileExtensions.push_back( "mm" );
+
+ this->HeaderFileExtensions.push_back( "h" );
+ this->HeaderFileExtensions.push_back( "hh" );
+ this->HeaderFileExtensions.push_back( "h++" );
+ this->HeaderFileExtensions.push_back( "hm" );
+ this->HeaderFileExtensions.push_back( "hpp" );
+ this->HeaderFileExtensions.push_back( "hxx" );
+ this->HeaderFileExtensions.push_back( "in" );
+ this->HeaderFileExtensions.push_back( "txx" );
}
cmake::~cmake()
{
- delete this->CacheManager;
- delete this->Policies;
+ delete this->State;
if (this->GlobalGenerator)
{
delete this->GlobalGenerator;
this->GlobalGenerator = 0;
}
- for(RegisteredCommandsMap::iterator j = this->Commands.begin();
- j != this->Commands.end(); ++j)
- {
- delete (*j).second;
- }
- for(RegisteredGeneratorsVector::iterator j = this->Generators.begin();
- j != this->Generators.end(); ++j)
- {
- delete *j;
- }
+ cmDeleteAll(this->Generators);
#ifdef CMAKE_BUILD_WITH_CMAKE
delete this->VariableWatch;
#endif
delete this->FileComparison;
}
-void cmake::InitializeProperties()
-{
- this->Properties.clear();
- this->Properties.SetCMakeInstance(this);
- this->AccessedProperties.clear();
- this->PropertyDefinitions.clear();
-
- // initialize properties
- cmCacheManager::DefineProperties(this);
- cmSourceFile::DefineProperties(this);
- cmTarget::DefineProperties(this);
- cmMakefile::DefineProperties(this);
- cmTest::DefineProperties(this);
- cmake::DefineProperties(this);
-}
-
void cmake::CleanupCommandsAndMacros()
{
- this->InitializeProperties();
- std::vector<cmCommand*> commands;
- for(RegisteredCommandsMap::iterator j = this->Commands.begin();
- j != this->Commands.end(); ++j)
- {
- if ( !j->second->IsA("cmMacroHelperCommand") &&
- !j->second->IsA("cmFunctionHelperCommand"))
- {
- commands.push_back(j->second);
- }
- else
- {
- delete j->second;
- }
- }
- this->Commands.erase(this->Commands.begin(), this->Commands.end());
- std::vector<cmCommand*>::iterator it;
- for ( it = commands.begin(); it != commands.end();
- ++ it )
- {
- this->Commands[cmSystemTools::LowerCase((*it)->GetName())] = *it;
- }
-}
-
-bool cmake::CommandExists(const char* name) const
-{
- std::string sName = cmSystemTools::LowerCase(name);
- return (this->Commands.find(sName) != this->Commands.end());
-}
-
-cmCommand *cmake::GetCommand(const char *name)
-{
- cmCommand* rm = 0;
- std::string sName = cmSystemTools::LowerCase(name);
- RegisteredCommandsMap::iterator pos = this->Commands.find(sName);
- if (pos != this->Commands.end())
- {
- rm = (*pos).second;
- }
- return rm;
-}
-
-void cmake::RenameCommand(const char*oldName, const char* newName)
-{
- // if the command already exists, free the old one
- std::string sOldName = cmSystemTools::LowerCase(oldName);
- std::string sNewName = cmSystemTools::LowerCase(newName);
- RegisteredCommandsMap::iterator pos = this->Commands.find(sOldName);
- if ( pos == this->Commands.end() )
- {
- return;
- }
- cmCommand* cmd = pos->second;
-
- pos = this->Commands.find(sNewName);
- if (pos != this->Commands.end())
- {
- delete pos->second;
- this->Commands.erase(pos);
- }
- this->Commands.insert(RegisteredCommandsMap::value_type(sNewName, cmd));
- pos = this->Commands.find(sOldName);
- this->Commands.erase(pos);
-}
-
-void cmake::RemoveCommand(const char* name)
-{
- std::string sName = cmSystemTools::LowerCase(name);
- RegisteredCommandsMap::iterator pos = this->Commands.find(sName);
- if ( pos != this->Commands.end() )
- {
- delete pos->second;
- this->Commands.erase(pos);
- }
-}
-
-void cmake::AddCommand(cmCommand* wg)
-{
- std::string name = cmSystemTools::LowerCase(wg->GetName());
- // if the command already exists, free the old one
- RegisteredCommandsMap::iterator pos = this->Commands.find(name);
- if (pos != this->Commands.end())
- {
- delete pos->second;
- this->Commands.erase(pos);
- }
- this->Commands.insert( RegisteredCommandsMap::value_type(name, wg));
-}
-
-
-void cmake::RemoveUnscriptableCommands()
-{
- std::vector<std::string> unscriptableCommands;
- cmake::RegisteredCommandsMap* commands = this->GetCommands();
- for (cmake::RegisteredCommandsMap::const_iterator pos = commands->begin();
- pos != commands->end();
- ++pos)
- {
- if (!pos->second->IsScriptable())
- {
- unscriptableCommands.push_back(pos->first);
- }
- }
-
- for(std::vector<std::string>::const_iterator it=unscriptableCommands.begin();
- it != unscriptableCommands.end();
- ++it)
- {
- this->RemoveCommand(it->c_str());
- }
+ this->CurrentSnapshot = this->State->Reset();
+ this->State->RemoveUserDefinedCommands();
+ this->CurrentSnapshot.SetDefaultDefinitions();
}
// Parse the args
@@ -367,7 +221,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
if(arg.find("-D",0) == 0)
{
std::string entry = arg.substr(2);
- if(entry.size() == 0)
+ if(entry.empty())
{
++i;
if(i < args.size())
@@ -381,24 +235,32 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
}
}
std::string var, value;
- cmCacheManager::CacheEntryType type = cmCacheManager::UNINITIALIZED;
- if(cmCacheManager::ParseEntry(entry.c_str(), var, value, type))
+ cmState::CacheEntryType type = cmState::UNINITIALIZED;
+ if(cmState::ParseCacheEntry(entry, var, value, type))
{
// The value is transformed if it is a filepath for example, so
// we can't compare whether the value is already in the cache until
// after we call AddCacheEntry.
- const char *cachedValue =
- this->CacheManager->GetCacheValue(var.c_str());
+ bool haveValue = false;
+ std::string cachedValue;
+ if(this->WarnUnusedCli)
+ {
+ if(const char *v = this->State->GetInitializedCacheValue(var))
+ {
+ haveValue = true;
+ cachedValue = v;
+ }
+ }
- this->CacheManager->AddCacheEntry(var.c_str(), value.c_str(),
+ this->AddCacheEntry(var, value.c_str(),
"No help, variable specified on the command line.", type);
+
if(this->WarnUnusedCli)
{
- if (!cachedValue
- || strcmp(this->CacheManager->GetCacheValue(var.c_str()),
- cachedValue) != 0)
+ if (!haveValue ||
+ cachedValue != this->State->GetInitializedCacheValue(var))
{
- this->WatchUnusedCli(var.c_str());
+ this->WatchUnusedCli(var);
}
}
}
@@ -410,20 +272,74 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
return false;
}
}
- else if(arg.find("-Wno-dev",0) == 0)
- {
- this->SuppressDevWarnings = true;
- this->DoSuppressDevWarnings = true;
- }
- else if(arg.find("-Wdev",0) == 0)
+ else if(cmHasLiteralPrefix(arg, "-W"))
{
- this->SuppressDevWarnings = false;
- this->DoSuppressDevWarnings = true;
+ std::string entry = arg.substr(2);
+ if (entry.empty())
+ {
+ ++i;
+ if (i < args.size())
+ {
+ entry = args[i];
+ }
+ else
+ {
+ cmSystemTools::Error("-W must be followed with [no-]<name>.");
+ return false;
+ }
+ }
+
+ std::string name;
+ bool foundNo = false;
+ bool foundError = false;
+ unsigned int nameStartPosition = 0;
+
+ if (entry.find("no-", nameStartPosition) == 0)
+ {
+ foundNo = true;
+ nameStartPosition += 3;
+ }
+
+ if (entry.find("error=", nameStartPosition) == 0)
+ {
+ foundError = true;
+ nameStartPosition += 6;
+ }
+
+ name = entry.substr(nameStartPosition);
+ if (name.empty())
+ {
+ cmSystemTools::Error("No warning name provided.");
+ return false;
+ }
+
+ if (!foundNo && !foundError)
+ {
+ // -W<name>
+ this->DiagLevels[name] = std::max(this->DiagLevels[name],
+ DIAG_WARN);
+ }
+ else if (foundNo && !foundError)
+ {
+ // -Wno<name>
+ this->DiagLevels[name] = DIAG_IGNORE;
+ }
+ else if (!foundNo && foundError)
+ {
+ // -Werror=<name>
+ this->DiagLevels[name] = DIAG_ERROR;
+ }
+ else
+ {
+ // -Wno-error=<name>
+ this->DiagLevels[name] = std::min(this->DiagLevels[name],
+ DIAG_WARN);
+ }
}
else if(arg.find("-U",0) == 0)
{
std::string entryPattern = arg.substr(2);
- if(entryPattern.size() == 0)
+ if(entryPattern.empty())
{
++i;
if(i < args.size())
@@ -437,20 +353,19 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
}
}
cmsys::RegularExpression regex(
- cmsys::Glob::PatternToRegex(entryPattern.c_str(), true, true).c_str());
+ cmsys::Glob::PatternToRegex(entryPattern, true, true).c_str());
//go through all cache entries and collect the vars which will be removed
std::vector<std::string> entriesToDelete;
- cmCacheManager::CacheIterator it =
- this->CacheManager->GetCacheIterator();
- for ( it.Begin(); !it.IsAtEnd(); it.Next() )
+ std::vector<std::string> cacheKeys = this->State->GetCacheEntryKeys();
+ for (std::vector<std::string>::const_iterator it = cacheKeys.begin();
+ it != cacheKeys.end(); ++it)
{
- cmCacheManager::CacheEntryType t = it.GetType();
- if(t != cmCacheManager::STATIC)
+ cmState::CacheEntryType t = this->State->GetCacheEntryType(*it);
+ if(t != cmState::STATIC)
{
- std::string entryName = it.GetName();
- if (regex.find(entryName.c_str()))
+ if (regex.find(it->c_str()))
{
- entriesToDelete.push_back(entryName);
+ entriesToDelete.push_back(*it);
}
}
}
@@ -461,13 +376,13 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
currentEntry != entriesToDelete.end();
++currentEntry)
{
- this->CacheManager->RemoveCacheEntry(currentEntry->c_str());
+ this->State->RemoveCacheEntry(*currentEntry);
}
}
else if(arg.find("-C",0) == 0)
{
std::string path = arg.substr(2);
- if ( path.size() == 0 )
+ if (path.empty())
{
++i;
if(i < args.size())
@@ -480,7 +395,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
return false;
}
}
- std::cerr << "loading initial cache file " << path.c_str() << "\n";
+ std::cout << "loading initial cache file " << path << "\n";
this->ReadListFile(args, path.c_str());
}
else if(arg.find("-P",0) == 0)
@@ -492,7 +407,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
return false;
}
std::string path = args[i];
- if ( path.size() == 0 )
+ if (path.empty())
{
cmSystemTools::Error("No cmake script provided.");
return false;
@@ -523,35 +438,39 @@ void cmake::ReadListFile(const std::vector<std::string>& args,
// if a generator was not specified use a generic one
if (!gg)
{
- gg = new cmGlobalGenerator;
- gg->SetCMakeInstance(this);
+ gg = new cmGlobalGenerator(this);
created = true;
}
// read in the list file to fill the cache
if(path)
{
- cmsys::auto_ptr<cmLocalGenerator> lg(gg->CreateLocalGenerator());
- lg->GetMakefile()->SetHomeOutputDirectory
- (cmSystemTools::GetCurrentWorkingDirectory().c_str());
- lg->GetMakefile()->SetStartOutputDirectory
- (cmSystemTools::GetCurrentWorkingDirectory().c_str());
- lg->GetMakefile()->SetHomeDirectory
- (cmSystemTools::GetCurrentWorkingDirectory().c_str());
- lg->GetMakefile()->SetStartDirectory
- (cmSystemTools::GetCurrentWorkingDirectory().c_str());
+ this->CurrentSnapshot = this->State->Reset();
+ std::string homeDir = this->GetHomeDirectory();
+ std::string homeOutputDir = this->GetHomeOutputDirectory();
+ this->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory());
+ this->SetHomeOutputDirectory(cmSystemTools::GetCurrentWorkingDirectory());
+ cmState::Snapshot snapshot = this->GetCurrentSnapshot();
+ snapshot.GetDirectory().SetCurrentBinary
+ (cmSystemTools::GetCurrentWorkingDirectory());
+ snapshot.GetDirectory().SetCurrentSource
+ (cmSystemTools::GetCurrentWorkingDirectory());
+ snapshot.SetDefaultDefinitions();
+ cmsys::auto_ptr<cmMakefile> mf(new cmMakefile(gg, snapshot));
if (this->GetWorkingMode() != NORMAL_MODE)
{
std::string file(cmSystemTools::CollapseFullPath(path));
cmSystemTools::ConvertToUnixSlashes(file);
- lg->GetMakefile()->SetScriptModeFile(file.c_str());
+ mf->SetScriptModeFile(file.c_str());
- lg->GetMakefile()->SetArgcArgv(args);
+ mf->SetArgcArgv(args);
}
- if (!lg->GetMakefile()->ReadListFile(0, path))
+ if (!mf->ReadListFile(path))
{
cmSystemTools::Error("Error processing file: ", path);
}
+ this->SetHomeDirectory(homeDir);
+ this->SetHomeOutputDirectory(homeOutputDir);
}
// free generic one if generated
@@ -564,27 +483,29 @@ void cmake::ReadListFile(const std::vector<std::string>& args,
bool cmake::FindPackage(const std::vector<std::string>& args)
{
+ this->SetHomeDirectory
+ (cmSystemTools::GetCurrentWorkingDirectory());
+ this->SetHomeOutputDirectory
+ (cmSystemTools::GetCurrentWorkingDirectory());
+
// if a generator was not yet created, temporarily create one
- cmGlobalGenerator *gg = new cmGlobalGenerator;
- gg->SetCMakeInstance(this);
+ cmGlobalGenerator *gg = new cmGlobalGenerator(this);
this->SetGlobalGenerator(gg);
+ cmState::Snapshot snapshot = this->GetCurrentSnapshot();
+ snapshot.GetDirectory().SetCurrentBinary
+ (cmSystemTools::GetCurrentWorkingDirectory());
+ snapshot.GetDirectory().SetCurrentSource
+ (cmSystemTools::GetCurrentWorkingDirectory());
// read in the list file to fill the cache
- cmsys::auto_ptr<cmLocalGenerator> lg(gg->CreateLocalGenerator());
- cmMakefile* mf = lg->GetMakefile();
- mf->SetHomeOutputDirectory
- (cmSystemTools::GetCurrentWorkingDirectory().c_str());
- mf->SetStartOutputDirectory
- (cmSystemTools::GetCurrentWorkingDirectory().c_str());
- mf->SetHomeDirectory
- (cmSystemTools::GetCurrentWorkingDirectory().c_str());
- mf->SetStartDirectory
- (cmSystemTools::GetCurrentWorkingDirectory().c_str());
+ snapshot.SetDefaultDefinitions();
+ cmMakefile* mf = new cmMakefile(gg, snapshot);
+ gg->AddMakefile(mf);
mf->SetArgcArgv(args);
std::string systemFile = mf->GetModulesFile("CMakeFindPackageMode.cmake");
- mf->ReadListFile(0, systemFile.c_str());
+ mf->ReadListFile(systemFile.c_str());
std::string language = mf->GetSafeDefinition("LANGUAGE");
std::string mode = mf->GetSafeDefinition("MODE");
@@ -612,8 +533,9 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
std::vector<std::string> includeDirs;
cmSystemTools::ExpandListArgument(includes, includeDirs);
- std::string includeFlags = lg->GetIncludeFlags(includeDirs, 0,
- language.c_str(), false);
+ gg->CreateGenerationObjects();
+ cmLocalGenerator* lg = gg->LocalGenerators[0];
+ std::string includeFlags = lg->GetIncludeFlags(includeDirs, 0, language);
std::string definitions = mf->GetSafeDefinition("PACKAGE_DEFINITIONS");
printf("%s %s\n", includeFlags.c_str(), definitions.c_str());
@@ -632,8 +554,8 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
libIt != libList.end();
++libIt)
{
- mf->AddLinkLibraryForTarget(targetName, libIt->c_str(),
- cmTarget::GENERAL);
+ mf->AddLinkLibraryForTarget(targetName, *libIt,
+ GENERAL_LibraryType);
}
@@ -642,9 +564,11 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
std::string linkPath;
std::string flags;
std::string linkFlags;
- cmGeneratorTarget gtgt(tgt);
+ gg->CreateGenerationObjects();
+ cmGeneratorTarget *gtgt = gg->FindGeneratorTarget(tgt->GetName());
+ cmLocalGenerator* lg = gtgt->GetLocalGenerator();
lg->GetTargetFlags(linkLibs, frameworkPath, linkPath, flags, linkFlags,
- &gtgt);
+ gtgt, false);
linkLibs = frameworkPath + linkPath + linkLibs;
printf("%s\n", linkLibs.c_str() );
@@ -673,6 +597,7 @@ void cmake::SetArgs(const std::vector<std::string>& args,
{
bool directoriesSet = directoriesSetBefore;
bool haveToolset = false;
+ bool havePlatform = false;
for(unsigned int i=1; i < args.size(); ++i)
{
std::string arg = args[i];
@@ -680,9 +605,9 @@ void cmake::SetArgs(const std::vector<std::string>& args,
{
directoriesSet = true;
std::string path = arg.substr(2);
- path = cmSystemTools::CollapseFullPath(path.c_str());
+ path = cmSystemTools::CollapseFullPath(path);
cmSystemTools::ConvertToUnixSlashes(path);
- this->SetHomeDirectory(path.c_str());
+ this->SetHomeDirectory(path);
}
else if(arg.find("-S",0) == 0)
{
@@ -696,11 +621,11 @@ void cmake::SetArgs(const std::vector<std::string>& args,
{
directoriesSet = true;
std::string path = arg.substr(2);
- path = cmSystemTools::CollapseFullPath(path.c_str());
+ path = cmSystemTools::CollapseFullPath(path);
cmSystemTools::ConvertToUnixSlashes(path);
- this->SetHomeOutputDirectory(path.c_str());
+ this->SetHomeOutputDirectory(path);
}
- else if((i < args.size()-1) && (arg.find("--check-build-system",0) == 0))
+ else if((i < args.size()-2) && (arg.find("--check-build-system",0) == 0))
{
this->CheckBuildSystemArgument = args[++i];
this->ClearBuildSystem = (atoi(args[++i].c_str()) > 0);
@@ -745,18 +670,14 @@ void cmake::SetArgs(const std::vector<std::string>& args,
// skip for now
i++;
}
- else if(arg.find("-Wno-dev",0) == 0)
- {
- // skip for now
- }
- else if(arg.find("-Wdev",0) == 0)
+ else if(arg.find("-W",0) == 0)
{
// skip for now
}
else if(arg.find("--graphviz=",0) == 0)
{
std::string path = arg.substr(strlen("--graphviz="));
- path = cmSystemTools::CollapseFullPath(path.c_str());
+ path = cmSystemTools::CollapseFullPath(path);
cmSystemTools::ConvertToUnixSlashes(path);
this->GraphVizFile = path;
if ( this->GraphVizFile.empty() )
@@ -774,10 +695,17 @@ void cmake::SetArgs(const std::vector<std::string>& args,
std::cout << "Running with debug output on.\n";
this->SetDebugOutputOn(true);
}
+ else if(arg.find("--trace-expand",0) == 0)
+ {
+ std::cout << "Running with expanded trace output on.\n";
+ this->SetTrace(true);
+ this->SetTraceExpand(true);
+ }
else if(arg.find("--trace",0) == 0)
{
std::cout << "Running with trace output on.\n";
this->SetTrace(true);
+ this->SetTraceExpand(false);
}
else if(arg.find("--warn-uninitialized",0) == 0)
{
@@ -801,10 +729,31 @@ void cmake::SetArgs(const std::vector<std::string>& args,
"uninitialized variables.\n";
this->SetCheckSystemVars(true);
}
+ else if(arg.find("-A",0) == 0)
+ {
+ std::string value = arg.substr(2);
+ if(value.empty())
+ {
+ ++i;
+ if(i >= args.size())
+ {
+ cmSystemTools::Error("No platform specified for -A");
+ return;
+ }
+ value = args[i];
+ }
+ if(havePlatform)
+ {
+ cmSystemTools::Error("Multiple -A options not allowed");
+ return;
+ }
+ this->GeneratorPlatform = value;
+ havePlatform = true;
+ }
else if(arg.find("-T",0) == 0)
{
std::string value = arg.substr(2);
- if(value.size() == 0)
+ if(value.empty())
{
++i;
if(i >= args.size())
@@ -825,22 +774,24 @@ void cmake::SetArgs(const std::vector<std::string>& args,
else if(arg.find("-G",0) == 0)
{
std::string value = arg.substr(2);
- if(value.size() == 0)
+ if(value.empty())
{
++i;
if(i >= args.size())
{
cmSystemTools::Error("No generator specified for -G");
+ this->PrintGeneratorList();
return;
}
value = args[i];
}
cmGlobalGenerator* gen =
- this->CreateGlobalGenerator(value.c_str());
+ this->CreateGlobalGenerator(value);
if(!gen)
{
cmSystemTools::Error("Could not create named generator ",
value.c_str());
+ this->PrintGeneratorList();
}
else
{
@@ -857,17 +808,10 @@ void cmake::SetArgs(const std::vector<std::string>& args,
if(!directoriesSet)
{
this->SetHomeOutputDirectory
- (cmSystemTools::GetCurrentWorkingDirectory().c_str());
- this->SetStartOutputDirectory
- (cmSystemTools::GetCurrentWorkingDirectory().c_str());
+ (cmSystemTools::GetCurrentWorkingDirectory());
this->SetHomeDirectory
- (cmSystemTools::GetCurrentWorkingDirectory().c_str());
- this->SetStartDirectory
- (cmSystemTools::GetCurrentWorkingDirectory().c_str());
+ (cmSystemTools::GetCurrentWorkingDirectory());
}
-
- this->SetStartDirectory(this->GetHomeDirectory());
- this->SetStartOutputDirectory(this->GetHomeOutputDirectory());
}
//----------------------------------------------------------------------------
@@ -899,15 +843,15 @@ void cmake::SetDirectoriesFromFile(const char* arg)
{
argIsFile = true;
std::string fullPath = cmSystemTools::CollapseFullPath(arg);
- std::string name = cmSystemTools::GetFilenameName(fullPath.c_str());
+ std::string name = cmSystemTools::GetFilenameName(fullPath);
name = cmSystemTools::LowerCase(name);
if(name == "cmakecache.txt")
{
- cachePath = cmSystemTools::GetFilenamePath(fullPath.c_str());
+ cachePath = cmSystemTools::GetFilenamePath(fullPath);
}
else if(name == "cmakelists.txt")
{
- listPath = cmSystemTools::GetFilenamePath(fullPath.c_str());
+ listPath = cmSystemTools::GetFilenamePath(fullPath);
}
}
else
@@ -915,12 +859,12 @@ void cmake::SetDirectoriesFromFile(const char* arg)
// Specified file or directory does not exist. Try to set things
// up to produce a meaningful error message.
std::string fullPath = cmSystemTools::CollapseFullPath(arg);
- std::string name = cmSystemTools::GetFilenameName(fullPath.c_str());
+ std::string name = cmSystemTools::GetFilenameName(fullPath);
name = cmSystemTools::LowerCase(name);
if(name == "cmakecache.txt" || name == "cmakelists.txt")
{
argIsFile = true;
- listPath = cmSystemTools::GetFilenamePath(fullPath.c_str());
+ listPath = cmSystemTools::GetFilenamePath(fullPath);
}
else
{
@@ -929,41 +873,38 @@ void cmake::SetDirectoriesFromFile(const char* arg)
}
// If there is a CMakeCache.txt file, use its settings.
- if(cachePath.length() > 0)
+ if(!cachePath.empty())
{
- cmCacheManager* cachem = this->GetCacheManager();
- cmCacheManager::CacheIterator it = cachem->NewIterator();
- if(cachem->LoadCache(cachePath.c_str()) &&
- it.Find("CMAKE_HOME_DIRECTORY"))
+ if(this->LoadCache(cachePath))
{
- this->SetHomeOutputDirectory(cachePath.c_str());
- this->SetStartOutputDirectory(cachePath.c_str());
- this->SetHomeDirectory(it.GetValue());
- this->SetStartDirectory(it.GetValue());
- return;
+ const char* existingValue =
+ this->State->GetCacheEntryValue("CMAKE_HOME_DIRECTORY");
+ if (existingValue)
+ {
+ this->SetHomeOutputDirectory(cachePath);
+ this->SetHomeDirectory(existingValue);
+ return;
+ }
}
}
// If there is a CMakeLists.txt file, use it as the source tree.
- if(listPath.length() > 0)
+ if(!listPath.empty())
{
- this->SetHomeDirectory(listPath.c_str());
- this->SetStartDirectory(listPath.c_str());
+ this->SetHomeDirectory(listPath);
if(argIsFile)
{
// Source CMakeLists.txt file given. It was probably dropped
// onto the executable in a GUI. Default to an in-source build.
- this->SetHomeOutputDirectory(listPath.c_str());
- this->SetStartOutputDirectory(listPath.c_str());
+ this->SetHomeOutputDirectory(listPath);
}
else
{
// Source directory given on command line. Use current working
// directory as build tree.
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
- this->SetHomeOutputDirectory(cwd.c_str());
- this->SetStartOutputDirectory(cwd.c_str());
+ this->SetHomeOutputDirectory(cwd);
}
return;
}
@@ -973,897 +914,44 @@ void cmake::SetDirectoriesFromFile(const char* arg)
// current working directory as the build tree.
std::string full = cmSystemTools::CollapseFullPath(arg);
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
- this->SetHomeDirectory(full.c_str());
- this->SetStartDirectory(full.c_str());
- this->SetHomeOutputDirectory(cwd.c_str());
- this->SetStartOutputDirectory(cwd.c_str());
+ this->SetHomeDirectory(full);
+ this->SetHomeOutputDirectory(cwd);
}
// at the end of this CMAKE_ROOT and CMAKE_COMMAND should be added to the
// cache
int cmake::AddCMakePaths()
{
- // Find the cmake executable
- std::string cMakeSelf = cmSystemTools::GetExecutableDirectory();
- cMakeSelf = cmSystemTools::GetRealPath(cMakeSelf.c_str());
- cMakeSelf += "/cmake";
- cMakeSelf += cmSystemTools::GetExecutableExtension();
-#ifdef __APPLE__
- // on the apple this might be the gui bundle
- if(!cmSystemTools::FileExists(cMakeSelf.c_str()))
- {
- cMakeSelf = cmSystemTools::GetExecutableDirectory();
- cMakeSelf = cmSystemTools::GetRealPath(cMakeSelf.c_str());
- cMakeSelf += "../../../..";
- cMakeSelf = cmSystemTools::GetRealPath(cMakeSelf.c_str());
- cMakeSelf = cmSystemTools::CollapseFullPath(cMakeSelf.c_str());
- cMakeSelf += "/cmake";
- std::cerr << cMakeSelf.c_str() << "\n";
- }
-#endif
- if(!cmSystemTools::FileExists(cMakeSelf.c_str()))
- {
- cmSystemTools::Error("CMake executable cannot be found at ",
- cMakeSelf.c_str());
- return 0;
- }
// Save the value in the cache
- this->CacheManager->AddCacheEntry
- ("CMAKE_COMMAND",cMakeSelf.c_str(), "Path to CMake executable.",
- cmCacheManager::INTERNAL);
- // if the edit command is not yet in the cache,
- // or if CMakeEditCommand has been set on this object,
- // then set the CMAKE_EDIT_COMMAND in the cache
- // This will mean that the last gui to edit the cache
- // will be the one that make edit_cache uses.
- if(!this->GetCacheDefinition("CMAKE_EDIT_COMMAND")
- || !this->CMakeEditCommand.empty())
- {
- // Find and save the command to edit the cache
- std::string editCacheCommand;
- if(!this->CMakeEditCommand.empty())
- {
- editCacheCommand = cmSystemTools::GetFilenamePath(cMakeSelf)
- + std::string("/")
- + this->CMakeEditCommand
- + cmSystemTools::GetFilenameExtension(cMakeSelf);
- }
- if( !cmSystemTools::FileExists(editCacheCommand.c_str()))
- {
- editCacheCommand = cmSystemTools::GetFilenamePath(cMakeSelf) +
- "/ccmake" + cmSystemTools::GetFilenameExtension(cMakeSelf);
- }
- if( !cmSystemTools::FileExists(editCacheCommand.c_str()))
- {
- editCacheCommand = cmSystemTools::GetFilenamePath(cMakeSelf) +
- "/cmake-gui" + cmSystemTools::GetFilenameExtension(cMakeSelf);
- }
- if(cmSystemTools::FileExists(editCacheCommand.c_str()))
- {
- this->CacheManager->AddCacheEntry
- ("CMAKE_EDIT_COMMAND", editCacheCommand.c_str(),
- "Path to cache edit program executable.", cmCacheManager::INTERNAL);
- }
- }
- std::string ctestCommand = cmSystemTools::GetFilenamePath(cMakeSelf) +
- "/ctest" + cmSystemTools::GetFilenameExtension(cMakeSelf);
- if(cmSystemTools::FileExists(ctestCommand.c_str()))
- {
- this->CacheManager->AddCacheEntry
- ("CMAKE_CTEST_COMMAND", ctestCommand.c_str(),
- "Path to ctest program executable.", cmCacheManager::INTERNAL);
- }
- std::string cpackCommand = cmSystemTools::GetFilenamePath(cMakeSelf) +
- "/cpack" + cmSystemTools::GetFilenameExtension(cMakeSelf);
- if(cmSystemTools::FileExists(cpackCommand.c_str()))
- {
- this->CacheManager->AddCacheEntry
- ("CMAKE_CPACK_COMMAND", cpackCommand.c_str(),
- "Path to cpack program executable.", cmCacheManager::INTERNAL);
- }
-
- // do CMAKE_ROOT, look for the environment variable first
- std::string cMakeRoot;
- std::string modules;
- if (getenv("CMAKE_ROOT"))
- {
- cMakeRoot = getenv("CMAKE_ROOT");
- modules = cMakeRoot + "/Modules/CMake.cmake";
- }
- if(!cmSystemTools::FileExists(modules.c_str()))
- {
- // next try exe/..
- cMakeRoot = cmSystemTools::GetRealPath(cMakeSelf.c_str());
- cMakeRoot = cmSystemTools::GetProgramPath(cMakeRoot.c_str());
- std::string::size_type slashPos = cMakeRoot.rfind("/");
- if(slashPos != std::string::npos)
- {
- cMakeRoot = cMakeRoot.substr(0, slashPos);
- }
- // is there no Modules directory there?
- modules = cMakeRoot + "/Modules/CMake.cmake";
- }
-
- if (!cmSystemTools::FileExists(modules.c_str()))
- {
- // try exe/../share/cmake
- cMakeRoot += CMAKE_DATA_DIR;
- modules = cMakeRoot + "/Modules/CMake.cmake";
- }
-#ifdef CMAKE_ROOT_DIR
- if (!cmSystemTools::FileExists(modules.c_str()))
- {
- // try compiled in root directory
- cMakeRoot = CMAKE_ROOT_DIR;
- modules = cMakeRoot + "/Modules/CMake.cmake";
- }
+ this->AddCacheEntry
+ ("CMAKE_COMMAND", cmSystemTools::GetCMakeCommand().c_str(),
+ "Path to CMake executable.", cmState::INTERNAL);
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ this->AddCacheEntry
+ ("CMAKE_CTEST_COMMAND", cmSystemTools::GetCTestCommand().c_str(),
+ "Path to ctest program executable.", cmState::INTERNAL);
+ this->AddCacheEntry
+ ("CMAKE_CPACK_COMMAND", cmSystemTools::GetCPackCommand().c_str(),
+ "Path to cpack program executable.", cmState::INTERNAL);
#endif
- if (!cmSystemTools::FileExists(modules.c_str()))
- {
- // try
- cMakeRoot = cmSystemTools::GetProgramPath(cMakeSelf.c_str());
- cMakeRoot += CMAKE_DATA_DIR;
- modules = cMakeRoot + "/Modules/CMake.cmake";
- }
- if(!cmSystemTools::FileExists(modules.c_str()))
- {
- // next try exe
- cMakeRoot = cmSystemTools::GetProgramPath(cMakeSelf.c_str());
- // is there no Modules directory there?
- modules = cMakeRoot + "/Modules/CMake.cmake";
- }
- if (!cmSystemTools::FileExists(modules.c_str()))
+ if(!cmSystemTools::FileExists(
+ (cmSystemTools::GetCMakeRoot()+"/Modules/CMake.cmake").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());
+ cmSystemTools::GetCMakeRoot().c_str());
return 0;
}
- this->CacheManager->AddCacheEntry
- ("CMAKE_ROOT", cMakeRoot.c_str(),
- "Path to CMake installation.", cmCacheManager::INTERNAL);
-
-#ifdef _WIN32
- std::string comspec = "cmw9xcom.exe";
- cmSystemTools::SetWindows9xComspecSubstitute(comspec.c_str());
-#endif
- return 1;
-}
-
-
-
-void CMakeCommandUsage(const char* program)
-{
- cmOStringStream errorStream;
-
-#ifdef CMAKE_BUILD_WITH_CMAKE
- errorStream
- << "cmake version " << cmVersion::GetCMakeVersion() << "\n";
-#else
- errorStream
- << "cmake bootstrap\n";
-#endif
- // If you add new commands, change here,
- // and in cmakemain.cxx in the options table
- errorStream
- << "Usage: " << program << " -E [command] [arguments ...]\n"
- << "Available commands: \n"
- << " chdir dir cmd [args]... - run command in a given directory\n"
- << " compare_files file1 file2 - check if file1 is same as file2\n"
- << " copy file destination - copy file to destination (either file "
- "or directory)\n"
- << " copy_directory source destination - copy directory 'source' "
- "content to directory 'destination'\n"
- << " copy_if_different in-file out-file - copy file if input has "
- "changed\n"
- << " echo [string]... - displays arguments as text\n"
- << " echo_append [string]... - displays arguments as text but no new "
- "line\n"
- << " environment - display the current environment\n"
- << " make_directory dir - create a directory\n"
- << " md5sum file1 [...] - compute md5sum of files\n"
- << " remove [-f] file1 file2 ... - remove the file(s), use -f to force "
- "it\n"
- << " remove_directory dir - remove a directory and its contents\n"
- << " rename oldname newname - rename a file or directory "
- "(on one volume)\n"
- << " tar [cxt][vfz][cvfj] file.tar [file/dir1 file/dir2 ...]\n"
- << " - create or extract a tar or zip archive\n"
- << " time command [args] ... - run command and return elapsed time\n"
- << " touch file - touch a file.\n"
- << " touch_nocreate file - touch a file but do not create it.\n"
-#if defined(_WIN32) && !defined(__CYGWIN__)
- << "Available on Windows only:\n"
- << " comspec - on windows 9x use this for RunCommand\n"
- << " delete_regv key - delete registry value\n"
- << " env_vs8_wince sdkname - displays a batch file which sets the "
- "environment for the provided Windows CE SDK installed in VS2005\n"
- << " env_vs9_wince sdkname - displays a batch file which sets the "
- "environment for the provided Windows CE SDK installed in VS2008\n"
- << " write_regv key value - write registry value\n"
-#else
- << "Available on UNIX only:\n"
- << " create_symlink old new - create a symbolic link new -> old\n"
-#endif
- ;
-
- cmSystemTools::Error(errorStream.str().c_str());
-}
-
-int cmake::ExecuteCMakeCommand(std::vector<std::string>& args)
-{
- // IF YOU ADD A NEW COMMAND, DOCUMENT IT ABOVE and in cmakemain.cxx
- if (args.size() > 1)
- {
- // Copy file
- if (args[1] == "copy" && args.size() == 4)
- {
- if(!cmSystemTools::cmCopyFile(args[2].c_str(), args[3].c_str()))
- {
- std::cerr << "Error copying file \"" << args[2].c_str()
- << "\" to \"" << args[3].c_str() << "\".\n";
- return 1;
- }
- return 0;
- }
-
- // Copy file if different.
- if (args[1] == "copy_if_different" && args.size() == 4)
- {
- if(!cmSystemTools::CopyFileIfDifferent(args[2].c_str(),
- args[3].c_str()))
- {
- std::cerr << "Error copying file (if different) from \""
- << args[2].c_str() << "\" to \"" << args[3].c_str()
- << "\".\n";
- return 1;
- }
- return 0;
- }
-
- // Copy directory content
- if (args[1] == "copy_directory" && args.size() == 4)
- {
- if(!cmSystemTools::CopyADirectory(args[2].c_str(), args[3].c_str()))
- {
- std::cerr << "Error copying directory from \""
- << args[2].c_str() << "\" to \"" << args[3].c_str()
- << "\".\n";
- return 1;
- }
- return 0;
- }
-
- // Rename a file or directory
- if (args[1] == "rename" && args.size() == 4)
- {
- if(!cmSystemTools::RenameFile(args[2].c_str(), args[3].c_str()))
- {
- std::string e = cmSystemTools::GetLastSystemError();
- std::cerr << "Error renaming from \""
- << args[2].c_str() << "\" to \"" << args[3].c_str()
- << "\": " << e << "\n";
- return 1;
- }
- return 0;
- }
-
- // Compare files
- if (args[1] == "compare_files" && args.size() == 4)
- {
- if(cmSystemTools::FilesDiffer(args[2].c_str(), args[3].c_str()))
- {
- std::cerr << "Files \""
- << args[2].c_str() << "\" to \"" << args[3].c_str()
- << "\" are different.\n";
- return 1;
- }
- return 0;
- }
-
- // Echo string
- else if (args[1] == "echo" )
- {
- unsigned int cc;
- const char* space = "";
- for ( cc = 2; cc < args.size(); cc ++ )
- {
- std::cout << space << args[cc];
- space = " ";
- }
- std::cout << std::endl;
- return 0;
- }
-
- // Echo string no new line
- else if (args[1] == "echo_append" )
- {
- unsigned int cc;
- const char* space = "";
- for ( cc = 2; cc < args.size(); cc ++ )
- {
- std::cout << space << args[cc];
- space = " ";
- }
- return 0;
- }
-
-#if defined(CMAKE_BUILD_WITH_CMAKE)
- // Command to create a symbolic link. Fails on platforms not
- // supporting them.
- else if (args[1] == "environment" )
- {
- std::vector<std::string> env = cmSystemTools::GetEnvironmentVariables();
- std::vector<std::string>::iterator it;
- for ( it = env.begin(); it != env.end(); ++ it )
- {
- std::cout << it->c_str() << std::endl;
- }
- return 0;
- }
-#endif
-
- else if (args[1] == "make_directory" && args.size() == 3)
- {
- if(!cmSystemTools::MakeDirectory(args[2].c_str()))
- {
- std::cerr << "Error making directory \"" << args[2].c_str()
- << "\".\n";
- return 1;
- }
- return 0;
- }
-
- else if (args[1] == "remove_directory" && args.size() == 3)
- {
- if(cmSystemTools::FileIsDirectory(args[2].c_str()) &&
- !cmSystemTools::RemoveADirectory(args[2].c_str()))
- {
- std::cerr << "Error removing directory \"" << args[2].c_str()
- << "\".\n";
- return 1;
- }
- return 0;
- }
-
- // Remove file
- else if (args[1] == "remove" && args.size() > 2)
- {
- bool force = false;
- for (std::string::size_type cc = 2; cc < args.size(); cc ++)
- {
- if(args[cc] == "\\-f" || args[cc] == "-f")
- {
- force = true;
- }
- else
- {
- // Complain if the file could not be removed, still exists,
- // and the -f option was not given.
- if(!cmSystemTools::RemoveFile(args[cc].c_str()) && !force &&
- cmSystemTools::FileExists(args[cc].c_str()))
- {
- return 1;
- }
- }
- }
- return 0;
- }
- // Touch file
- else if (args[1] == "touch" && args.size() > 2)
- {
- for (std::string::size_type cc = 2; cc < args.size(); cc ++)
- {
- // Complain if the file could not be removed, still exists,
- // and the -f option was not given.
- if(!cmSystemTools::Touch(args[cc].c_str(), true))
- {
- return 1;
- }
- }
- return 0;
- }
- // Touch file
- else if (args[1] == "touch_nocreate" && args.size() > 2)
- {
- for (std::string::size_type cc = 2; cc < args.size(); cc ++)
- {
- // Complain if the file could not be removed, still exists,
- // and the -f option was not given.
- if(!cmSystemTools::Touch(args[cc].c_str(), false))
- {
- return 1;
- }
- }
- return 0;
- }
-
- // Clock command
- else if (args[1] == "time" && args.size() > 2)
- {
- std::string command = args[2];
- for (std::string::size_type cc = 3; cc < args.size(); cc ++)
- {
- command += " ";
- command += args[cc];
- }
-
- clock_t clock_start, clock_finish;
- time_t time_start, time_finish;
-
- time(&time_start);
- clock_start = clock();
- int ret =0;
- cmSystemTools::RunSingleCommand(command.c_str(), 0, &ret);
-
- clock_finish = clock();
- time(&time_finish);
-
- double clocks_per_sec = static_cast<double>(CLOCKS_PER_SEC);
- std::cout << "Elapsed time: "
- << static_cast<long>(time_finish - time_start) << " s. (time)"
- << ", "
- << static_cast<double>(clock_finish - clock_start) / clocks_per_sec
- << " s. (clock)"
- << "\n";
- return ret;
- }
- // Command to calculate the md5sum of a file
- else if (args[1] == "md5sum" && args.size() >= 3)
- {
- char md5out[32];
- int retval = 0;
- for (std::string::size_type cc = 2; cc < args.size(); cc ++)
- {
- const char *filename = args[cc].c_str();
- // Cannot compute md5sum of a directory
- if(cmSystemTools::FileIsDirectory(filename))
- {
- std::cerr << "Error: " << filename << " is a directory" << std::endl;
- retval++;
- }
- else if(!cmSystemTools::ComputeFileMD5(filename, md5out))
- {
- // To mimic md5sum behavior in a shell:
- std::cerr << filename << ": No such file or directory" << std::endl;
- retval++;
- }
- else
- {
- std::cout << std::string(md5out,32) << " " << filename << std::endl;
- }
- }
- return retval;
- }
-
- // Command to change directory and run a program.
- else if (args[1] == "chdir" && args.size() >= 4)
- {
- std::string directory = args[2];
- if(!cmSystemTools::FileExists(directory.c_str()))
- {
- cmSystemTools::Error("Directory does not exist for chdir command: ",
- args[2].c_str());
- return 1;
- }
-
- std::string command = "\"";
- command += args[3];
- command += "\"";
- for (std::string::size_type cc = 4; cc < args.size(); cc ++)
- {
- command += " \"";
- command += args[cc];
- command += "\"";
- }
- int retval = 0;
- int timeout = 0;
- if ( cmSystemTools::RunSingleCommand(command.c_str(), 0, &retval,
- directory.c_str(), cmSystemTools::OUTPUT_NORMAL, timeout) )
- {
- return retval;
- }
-
- return 1;
- }
-
- // Command to start progress for a build
- else if (args[1] == "cmake_progress_start" && args.size() == 4)
- {
- // basically remove the directory
- std::string dirName = args[2];
- dirName += "/Progress";
- cmSystemTools::RemoveADirectory(dirName.c_str());
-
- // is the last argument a filename that exists?
- FILE *countFile = fopen(args[3].c_str(),"r");
- int count;
- if (countFile)
- {
- if (1!=fscanf(countFile,"%i",&count))
- {
- cmSystemTools::Message("Could not read from count file.");
- }
- fclose(countFile);
- }
- else
- {
- count = atoi(args[3].c_str());
- }
- if (count)
- {
- cmSystemTools::MakeDirectory(dirName.c_str());
- // write the count into the directory
- std::string fName = dirName;
- fName += "/count.txt";
- FILE *progFile = fopen(fName.c_str(),"w");
- if (progFile)
- {
- fprintf(progFile,"%i\n",count);
- fclose(progFile);
- }
- }
- return 0;
- }
-
- // Command to report progress for a build
- else if (args[1] == "cmake_progress_report" && args.size() >= 3)
- {
- std::string dirName = args[2];
- dirName += "/Progress";
- std::string fName;
- FILE *progFile;
-
- // read the count
- fName = dirName;
- fName += "/count.txt";
- progFile = fopen(fName.c_str(),"r");
- int count = 0;
- if (!progFile)
- {
- return 0;
- }
- else
- {
- if (1!=fscanf(progFile,"%i",&count))
- {
- cmSystemTools::Message("Could not read from progress file.");
- }
- fclose(progFile);
- }
- unsigned int i;
- for (i = 3; i < args.size(); ++i)
- {
- fName = dirName;
- fName += "/";
- fName += args[i];
- progFile = fopen(fName.c_str(),"w");
- if (progFile)
- {
- fprintf(progFile,"empty");
- fclose(progFile);
- }
- }
- int fileNum = static_cast<int>
- (cmsys::Directory::GetNumberOfFilesInDirectory(dirName.c_str()));
- if (count > 0)
- {
- // print the progress
- fprintf(stdout,"[%3i%%] ",((fileNum-3)*100)/count);
- }
- return 0;
- }
-
- // Command to create a symbolic link. Fails on platforms not
- // supporting them.
- else if (args[1] == "create_symlink" && args.size() == 4)
- {
- const char* destinationFileName = args[3].c_str();
- if ( cmSystemTools::FileExists(destinationFileName) )
- {
- if ( cmSystemTools::FileIsSymlink(destinationFileName) )
- {
- if ( !cmSystemTools::RemoveFile(destinationFileName) ||
- cmSystemTools::FileExists(destinationFileName) )
- {
- return 0;
- }
- }
- else
- {
- return 0;
- }
- }
- return cmSystemTools::CreateSymlink(args[2].c_str(),
- args[3].c_str())? 0:1;
- }
-
- // Internal CMake shared library support.
- else if (args[1] == "cmake_symlink_library" && args.size() == 5)
- {
- return cmake::SymlinkLibrary(args);
- }
- // Internal CMake versioned executable support.
- else if (args[1] == "cmake_symlink_executable" && args.size() == 4)
- {
- return cmake::SymlinkExecutable(args);
- }
-
-#if defined(CMAKE_HAVE_VS_GENERATORS)
- // Internal CMake support for calling Visual Studio macros.
- else if (args[1] == "cmake_call_visual_studio_macro" && args.size() >= 4)
- {
- // args[2] = full path to .sln file or "ALL"
- // args[3] = name of Visual Studio macro to call
- // args[4..args.size()-1] = [optional] args for Visual Studio macro
-
- std::string macroArgs;
-
- if (args.size() > 4)
- {
- macroArgs = args[4];
-
- for (size_t i = 5; i < args.size(); ++i)
- {
- macroArgs += " ";
- macroArgs += args[i];
- }
- }
-
- return cmCallVisualStudioMacro::CallMacro(args[2], args[3],
- macroArgs, true);
- }
-#endif
-
- // Internal CMake dependency scanning support.
- else if (args[1] == "cmake_depends" && args.size() >= 6)
- {
- // Use the make system's VERBOSE environment variable to enable
- // verbose output. This can be skipped by also setting CMAKE_NO_VERBOSE
- // (which is set by the Eclipse and KDevelop generators).
- bool verbose = ((cmSystemTools::GetEnv("VERBOSE") != 0)
- && (cmSystemTools::GetEnv("CMAKE_NO_VERBOSE") == 0));
-
- // Create a cmake object instance to process dependencies.
- cmake cm;
- std::string gen;
- std::string homeDir;
- std::string startDir;
- std::string homeOutDir;
- std::string startOutDir;
- std::string depInfo;
- bool color = false;
- if(args.size() >= 8)
- {
- // Full signature:
- //
- // -E cmake_depends <generator>
- // <home-src-dir> <start-src-dir>
- // <home-out-dir> <start-out-dir>
- // <dep-info> [--color=$(COLOR)]
- //
- // All paths are provided.
- gen = args[2];
- homeDir = args[3];
- startDir = args[4];
- homeOutDir = args[5];
- startOutDir = args[6];
- depInfo = args[7];
- if(args.size() >= 9 &&
- args[8].length() >= 8 &&
- args[8].substr(0, 8) == "--color=")
- {
- // Enable or disable color based on the switch value.
- color = (args[8].size() == 8 ||
- cmSystemTools::IsOn(args[8].substr(8).c_str()));
- }
- }
- else
- {
- // Support older signature for existing makefiles:
- //
- // -E cmake_depends <generator>
- // <home-out-dir> <start-out-dir>
- // <dep-info>
- //
- // Just pretend the source directories are the same as the
- // binary directories so at least scanning will work.
- gen = args[2];
- homeDir = args[3];
- startDir = args[4];
- homeOutDir = args[3];
- startOutDir = args[3];
- depInfo = args[5];
- }
-
- // Create a local generator configured for the directory in
- // which dependencies will be scanned.
- homeDir = cmSystemTools::CollapseFullPath(homeDir.c_str());
- startDir = cmSystemTools::CollapseFullPath(startDir.c_str());
- homeOutDir = cmSystemTools::CollapseFullPath(homeOutDir.c_str());
- startOutDir = cmSystemTools::CollapseFullPath(startOutDir.c_str());
- cm.SetHomeDirectory(homeDir.c_str());
- cm.SetStartDirectory(startDir.c_str());
- cm.SetHomeOutputDirectory(homeOutDir.c_str());
- cm.SetStartOutputDirectory(startOutDir.c_str());
- if(cmGlobalGenerator* ggd = cm.CreateGlobalGenerator(gen.c_str()))
- {
- cm.SetGlobalGenerator(ggd);
- cmsys::auto_ptr<cmLocalGenerator> lgd(ggd->CreateLocalGenerator());
- lgd->GetMakefile()->SetStartDirectory(startDir.c_str());
- lgd->GetMakefile()->SetStartOutputDirectory(startOutDir.c_str());
- lgd->GetMakefile()->MakeStartDirectoriesCurrent();
-
- // Actually scan dependencies.
- return lgd->UpdateDependencies(depInfo.c_str(),
- verbose, color)? 0 : 2;
- }
- return 1;
- }
-
- // Internal CMake link script support.
- else if (args[1] == "cmake_link_script" && args.size() >= 3)
- {
- return cmake::ExecuteLinkScript(args);
- }
-
- // Internal CMake unimplemented feature notification.
- else if (args[1] == "cmake_unimplemented_variable")
- {
- std::cerr << "Feature not implemented for this platform.";
- if(args.size() == 3)
- {
- std::cerr << " Variable " << args[2] << " is not set.";
- }
- std::cerr << std::endl;
- return 1;
- }
- else if (args[1] == "vs_link_exe")
- {
- return cmake::VisualStudioLink(args, 1);
- }
- else if (args[1] == "vs_link_dll")
- {
- return cmake::VisualStudioLink(args, 2);
- }
-#ifdef CMAKE_BUILD_WITH_CMAKE
- // Internal CMake color makefile support.
- else if (args[1] == "cmake_echo_color")
- {
- return cmake::ExecuteEchoColor(args);
- }
- else if (args[1] == "cmake_automoc" && args.size() >= 4)
- {
- cmQtAutomoc automoc;
- const char *config = args[3].empty() ? 0 : args[3].c_str();
- bool automocSuccess = automoc.Run(args[2].c_str(), config);
- return automocSuccess ? 0 : 1;
- }
-#endif
-
- // Tar files
- else if (args[1] == "tar" && args.size() > 3)
- {
- std::string flags = args[2];
- std::string outFile = args[3];
- std::vector<cmStdString> files;
- for (std::string::size_type cc = 4; cc < args.size(); cc ++)
- {
- files.push_back(args[cc]);
- }
- bool gzip = false;
- bool bzip2 = false;
- bool verbose = false;
- if ( flags.find_first_of('j') != flags.npos )
- {
- bzip2 = true;
- }
- if ( flags.find_first_of('z') != flags.npos )
- {
- gzip = true;
- }
- if ( flags.find_first_of('v') != flags.npos )
- {
- verbose = true;
- }
-
- if ( flags.find_first_of('t') != flags.npos )
- {
- if ( !cmSystemTools::ListTar(outFile.c_str(), gzip, verbose) )
- {
- cmSystemTools::Error("Problem creating tar: ", outFile.c_str());
- return 1;
- }
- }
- else if ( flags.find_first_of('c') != flags.npos )
- {
- if ( !cmSystemTools::CreateTar(
- outFile.c_str(), files, gzip, bzip2, verbose) )
- {
- cmSystemTools::Error("Problem creating tar: ", outFile.c_str());
- return 1;
- }
- }
- else if ( flags.find_first_of('x') != flags.npos )
- {
- if ( !cmSystemTools::ExtractTar(
- outFile.c_str(), gzip, verbose) )
- {
- cmSystemTools::Error("Problem extracting tar: ", outFile.c_str());
- return 1;
- }
-#ifdef WIN32
- // OK, on windows 7 after we untar some files,
- // sometimes we can not rename the directory after
- // the untar is done. This breaks the external project
- // untar and rename code. So, by default we will wait
- // 1/10th of a second after the untar. If CMAKE_UNTAR_DELAY
- // is set in the env, its value will be used instead of 100.
- int delay = 100;
- const char* delayVar = cmSystemTools::GetEnv("CMAKE_UNTAR_DELAY");
- if(delayVar)
- {
- delay = atoi(delayVar);
- }
- if(delay)
- {
- cmSystemTools::Delay(delay);
- }
-#endif
- }
- return 0;
- }
-
-#if defined(CMAKE_BUILD_WITH_CMAKE)
- // Internal CMake Fortran module support.
- else if (args[1] == "cmake_copy_f90_mod" && args.size() >= 4)
- {
- return cmDependsFortran::CopyModule(args)? 0 : 1;
- }
-#endif
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- // Write registry value
- else if (args[1] == "write_regv" && args.size() > 3)
- {
- return cmSystemTools::WriteRegistryValue(args[2].c_str(),
- args[3].c_str()) ? 0 : 1;
- }
-
- // Delete registry value
- else if (args[1] == "delete_regv" && args.size() > 2)
- {
- return cmSystemTools::DeleteRegistryValue(args[2].c_str()) ? 0 : 1;
- }
- // Remove file
- else if (args[1] == "comspec" && args.size() > 2)
- {
- unsigned int cc;
- std::string command = args[2];
- for ( cc = 3; cc < args.size(); cc ++ )
- {
- command += " " + args[cc];
- }
- return cmWin32ProcessExecution::Windows9xHack(command.c_str());
- }
- else if (args[1] == "env_vs8_wince" && args.size() == 3)
- {
- return cmake::WindowsCEEnvironment("8.0", args[2]);
- }
- else if (args[1] == "env_vs9_wince" && args.size() == 3)
- {
- return cmake::WindowsCEEnvironment("9.0", args[2]);
- }
-#endif
- }
+ this->AddCacheEntry
+ ("CMAKE_ROOT", cmSystemTools::GetCMakeRoot().c_str(),
+ "Path to CMake installation.", cmState::INTERNAL);
- ::CMakeCommandUsage(args[0].c_str());
return 1;
}
-void cmake::AddExtraGenerator(const char* name,
+void cmake::AddExtraGenerator(const std::string& name,
CreateExtraGeneratorFunctionType newFunction)
{
cmExternalMakefileProjectGenerator* extraGenerator = newFunction();
@@ -1876,8 +964,8 @@ void cmake::AddExtraGenerator(const char* name,
++it )
{
std::string fullName = cmExternalMakefileProjectGenerator::
- CreateFullGeneratorName(it->c_str(), name);
- this->ExtraGenerators[fullName.c_str()] = newFunction;
+ CreateFullGeneratorName(*it, name);
+ this->ExtraGenerators[fullName] = newFunction;
}
delete extraGenerator;
}
@@ -1891,8 +979,12 @@ void cmake::AddDefaultExtraGenerators()
this->AddExtraGenerator(cmExtraCodeBlocksGenerator::GetActualName(),
&cmExtraCodeBlocksGenerator::New);
+ this->AddExtraGenerator(cmExtraCodeLiteGenerator::GetActualName(),
+ &cmExtraCodeLiteGenerator::New);
this->AddExtraGenerator(cmExtraSublimeTextGenerator::GetActualName(),
&cmExtraSublimeTextGenerator::New);
+ this->AddExtraGenerator(cmExtraKateGenerator::GetActualName(),
+ &cmExtraKateGenerator::New);
#ifdef CMAKE_USE_ECLIPSE
this->AddExtraGenerator(cmExtraEclipseCDT4Generator::GetActualName(),
@@ -1913,24 +1005,39 @@ void cmake::AddDefaultExtraGenerators()
//----------------------------------------------------------------------------
-void cmake::GetRegisteredGenerators(std::vector<std::string>& names)
+void cmake::GetRegisteredGenerators(std::vector<GeneratorInfo>& generators)
{
- for(RegisteredGeneratorsVector::const_iterator i = this->Generators.begin();
- i != this->Generators.end(); ++i)
+ for (RegisteredGeneratorsVector::const_iterator
+ i = this->Generators.begin(), e = this->Generators.end();
+ i != e; ++i)
{
+ std::vector<std::string> names;
(*i)->GetGenerators(names);
+
+ for (size_t j = 0; j < names.size(); ++j)
+ {
+ GeneratorInfo info;
+ info.supportsToolset = (*i)->SupportsToolset();
+ info.name = names[j];
+ generators.push_back(info);
+ }
}
- for(RegisteredExtraGeneratorsMap::const_iterator
- i = this->ExtraGenerators.begin();
- i != this->ExtraGenerators.end(); ++i)
+
+ for (RegisteredExtraGeneratorsMap::const_iterator
+ i = this->ExtraGenerators.begin(), e = this->ExtraGenerators.end();
+ i != e; ++i)
{
- names.push_back(i->first);
+ GeneratorInfo info;
+ info.name = i->first;
+ info.supportsToolset = false;
+ generators.push_back(info);
}
}
-cmGlobalGenerator* cmake::CreateGlobalGenerator(const char* name)
+cmGlobalGenerator* cmake::CreateGlobalGenerator(const std::string& gname)
{
cmExternalMakefileProjectGenerator* extraGenerator = 0;
+ std::string name = gname;
RegisteredExtraGeneratorsMap::const_iterator extraGenIt =
this->ExtraGenerators.find(name);
if (extraGenIt != this->ExtraGenerators.end())
@@ -1943,7 +1050,7 @@ cmGlobalGenerator* cmake::CreateGlobalGenerator(const char* name)
for (RegisteredGeneratorsVector::const_iterator i =
this->Generators.begin(); i != this->Generators.end(); ++i)
{
- generator = (*i)->CreateGlobalGenerator(name);
+ generator = (*i)->CreateGlobalGenerator(name, this);
if (generator)
{
break;
@@ -1952,7 +1059,6 @@ cmGlobalGenerator* cmake::CreateGlobalGenerator(const char* name)
if (generator)
{
- generator->SetCMakeInstance(this);
generator->SetExternalMakefileProjectGenerator(extraGenerator);
}
else
@@ -1963,16 +1069,32 @@ cmGlobalGenerator* cmake::CreateGlobalGenerator(const char* name)
return generator;
}
-void cmake::SetHomeDirectory(const char* dir)
+void cmake::SetHomeDirectory(const std::string& dir)
+{
+ this->State->SetSourceDirectory(dir);
+ if (this->CurrentSnapshot.IsValid())
+ {
+ this->CurrentSnapshot.SetDefinition("CMAKE_SOURCE_DIR", dir);
+ }
+}
+
+const char* cmake::GetHomeDirectory() const
+{
+ return this->State->GetSourceDirectory();
+}
+
+void cmake::SetHomeOutputDirectory(const std::string& dir)
{
- this->cmHomeDirectory = dir;
- cmSystemTools::ConvertToUnixSlashes(this->cmHomeDirectory);
+ this->State->SetBinaryDirectory(dir);
+ if (this->CurrentSnapshot.IsValid())
+ {
+ this->CurrentSnapshot.SetDefinition("CMAKE_BINARY_DIR", dir);
+ }
}
-void cmake::SetHomeOutputDirectory(const char* lib)
+const char* cmake::GetHomeOutputDirectory() const
{
- this->HomeOutputDirectory = lib;
- cmSystemTools::ConvertToUnixSlashes(this->HomeOutputDirectory);
+ return this->State->GetBinaryDirectory();
}
void cmake::SetGlobalGenerator(cmGlobalGenerator *gg)
@@ -1989,17 +1111,17 @@ void cmake::SetGlobalGenerator(cmGlobalGenerator *gg)
// restore the original environment variables CXX and CC
// Restore CC
std::string env = "CC=";
- if(this->CCEnvironment.size())
+ if(!this->CCEnvironment.empty())
{
env += this->CCEnvironment;
}
- cmSystemTools::PutEnv(env.c_str());
+ cmSystemTools::PutEnv(env);
env = "CXX=";
- if(this->CXXEnvironment.size())
+ if(!this->CXXEnvironment.empty())
{
env += this->CXXEnvironment;
}
- cmSystemTools::PutEnv(env.c_str());
+ cmSystemTools::PutEnv(env);
}
// set the new
@@ -2029,18 +1151,16 @@ void cmake::SetGlobalGenerator(cmGlobalGenerator *gg)
{
this->CCEnvironment = "";
}
- // set the cmake instance just to be sure
- gg->SetCMakeInstance(this);
}
int cmake::DoPreConfigureChecks()
{
- // Make sure the Start directory contains a CMakeLists.txt file.
+ // Make sure the Source directory contains a CMakeLists.txt file.
std::string srcList = this->GetHomeDirectory();
srcList += "/CMakeLists.txt";
if(!cmSystemTools::FileExists(srcList.c_str()))
{
- cmOStringStream err;
+ std::ostringstream err;
if(cmSystemTools::FileIsDirectory(this->GetHomeDirectory()))
{
err << "The source directory \"" << this->GetHomeDirectory()
@@ -2063,14 +1183,14 @@ int cmake::DoPreConfigureChecks()
}
// do a sanity check on some values
- if(this->CacheManager->GetCacheValue("CMAKE_HOME_DIRECTORY"))
+ if(this->State->GetInitializedCacheValue("CMAKE_HOME_DIRECTORY"))
{
std::string cacheStart =
- this->CacheManager->GetCacheValue("CMAKE_HOME_DIRECTORY");
+ this->State->GetInitializedCacheValue("CMAKE_HOME_DIRECTORY");
cacheStart += "/CMakeLists.txt";
std::string currentStart = this->GetHomeDirectory();
currentStart += "/CMakeLists.txt";
- if(!cmSystemTools::SameFile(cacheStart.c_str(), currentStart.c_str()))
+ if(!cmSystemTools::SameFile(cacheStart, currentStart))
{
std::string message = "The source \"";
message += currentStart;
@@ -2093,22 +1213,22 @@ struct SaveCacheEntry
std::string key;
std::string value;
std::string help;
- cmCacheManager::CacheEntryType type;
+ cmState::CacheEntryType type;
};
-int cmake::HandleDeleteCacheVariables(const char* var)
+int cmake::HandleDeleteCacheVariables(const std::string& var)
{
std::vector<std::string> argsSplit;
cmSystemTools::ExpandListArgument(std::string(var), argsSplit, true);
// erase the property to avoid infinite recursion
- this->SetProperty("__CMAKE_DELETE_CACHE_CHANGE_VARS_", "");
- if(this->GetIsInTryCompile())
+ this->State
+ ->SetGlobalProperty("__CMAKE_DELETE_CACHE_CHANGE_VARS_", "");
+ if(this->State->GetIsInTryCompile())
{
return 0;
}
- cmCacheManager::CacheIterator ci = this->CacheManager->NewIterator();
std::vector<SaveCacheEntry> saved;
- cmOStringStream warning;
+ std::ostringstream warning;
warning
<< "You have changed variables that require your cache to be deleted.\n"
<< "Configure will be re-run and you may have to reset some variables.\n"
@@ -2122,23 +1242,29 @@ int cmake::HandleDeleteCacheVariables(const char* var)
i++;
save.value = *i;
warning << *i << "\n";
- if(ci.Find(save.key.c_str()))
+ const char* existingValue =
+ this->State->GetCacheEntryValue(save.key);
+ if(existingValue)
{
- save.type = ci.GetType();
- save.help = ci.GetProperty("HELPSTRING");
+ save.type = this->State->GetCacheEntryType(save.key);
+ if(const char* help =
+ this->State->GetCacheEntryProperty(save.key, "HELPSTRING"))
+ {
+ save.help = help;
+ }
}
saved.push_back(save);
}
// remove the cache
- this->CacheManager->DeleteCache(this->GetStartOutputDirectory());
+ this->DeleteCache(this->GetHomeOutputDirectory());
// load the empty cache
this->LoadCache();
// restore the changed compilers
for(std::vector<SaveCacheEntry>::iterator i = saved.begin();
i != saved.end(); ++i)
{
- this->AddCacheEntry(i->key.c_str(), i->value.c_str(),
+ this->AddCacheEntry(i->key, i->value.c_str(),
i->help.c_str(), i->type);
}
cmSystemTools::Message(warning.str().c_str());
@@ -2153,28 +1279,83 @@ int cmake::HandleDeleteCacheVariables(const char* var)
int cmake::Configure()
{
- if(this->DoSuppressDevWarnings)
+ DiagLevel diagLevel;
+
+ if (this->DiagLevels.count("deprecated") == 1)
{
- if(this->SuppressDevWarnings)
+
+ diagLevel = this->DiagLevels["deprecated"];
+ if (diagLevel == DIAG_IGNORE)
{
- this->CacheManager->
- AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS", "TRUE",
- "Suppress Warnings that are meant for"
- " the author of the CMakeLists.txt files.",
- cmCacheManager::INTERNAL);
+ this->SetSuppressDeprecatedWarnings(true);
+ this->SetDeprecatedWarningsAsErrors(false);
}
- else
+ else if (diagLevel == DIAG_WARN)
{
- this->CacheManager->
- AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS", "FALSE",
- "Suppress Warnings that are meant for"
- " the author of the CMakeLists.txt files.",
- cmCacheManager::INTERNAL);
+ this->SetSuppressDeprecatedWarnings(false);
+ this->SetDeprecatedWarningsAsErrors(false);
+ }
+ else if (diagLevel == DIAG_ERROR)
+ {
+ this->SetSuppressDeprecatedWarnings(false);
+ this->SetDeprecatedWarningsAsErrors(true);
}
}
+
+ if (this->DiagLevels.count("dev") == 1)
+ {
+ bool setDeprecatedVariables = false;
+
+ const char* cachedWarnDeprecated =
+ this->State->GetCacheEntryValue("CMAKE_WARN_DEPRECATED");
+ const char* cachedErrorDeprecated =
+ this->State->GetCacheEntryValue("CMAKE_ERROR_DEPRECATED");
+
+ // don't overwrite deprecated warning setting from a previous invocation
+ if (!cachedWarnDeprecated && !cachedErrorDeprecated)
+ {
+ setDeprecatedVariables = true;
+ }
+
+ diagLevel = this->DiagLevels["dev"];
+ if (diagLevel == DIAG_IGNORE)
+ {
+ this->SetSuppressDevWarnings(true);
+ this->SetDevWarningsAsErrors(false);
+
+ if (setDeprecatedVariables)
+ {
+ this->SetSuppressDeprecatedWarnings(true);
+ this->SetDeprecatedWarningsAsErrors(false);
+ }
+ }
+ else if (diagLevel == DIAG_WARN)
+ {
+ this->SetSuppressDevWarnings(false);
+ this->SetDevWarningsAsErrors(false);
+
+ if (setDeprecatedVariables)
+ {
+ this->SetSuppressDeprecatedWarnings(false);
+ this->SetDeprecatedWarningsAsErrors(false);
+ }
+ }
+ else if (diagLevel == DIAG_ERROR)
+ {
+ this->SetSuppressDevWarnings(false);
+ this->SetDevWarningsAsErrors(true);
+
+ if (setDeprecatedVariables)
+ {
+ this->SetSuppressDeprecatedWarnings(false);
+ this->SetDeprecatedWarningsAsErrors(true);
+ }
+ }
+ }
+
int ret = this->ActualConfigure();
- const char* delCacheVars =
- this->GetProperty("__CMAKE_DELETE_CACHE_CHANGE_VARS_");
+ const char* delCacheVars = this->State
+ ->GetGlobalProperty("__CMAKE_DELETE_CACHE_CHANGE_VARS_");
if(delCacheVars && delCacheVars[0] != 0)
{
return this->HandleDeleteCacheVariables(delCacheVars);
@@ -2200,26 +1381,27 @@ int cmake::ActualConfigure()
}
if ( !res )
{
- this->CacheManager->AddCacheEntry
+ this->AddCacheEntry
("CMAKE_HOME_DIRECTORY",
this->GetHomeDirectory(),
- "Start directory with the top level CMakeLists.txt file for this "
+ "Source directory with the top level CMakeLists.txt file for this "
"project",
- cmCacheManager::INTERNAL);
+ cmState::INTERNAL);
}
// no generator specified on the command line
if(!this->GlobalGenerator)
{
const char* genName =
- this->CacheManager->GetCacheValue("CMAKE_GENERATOR");
+ this->State->GetInitializedCacheValue("CMAKE_GENERATOR");
const char* extraGenName =
- this->CacheManager->GetCacheValue("CMAKE_EXTRA_GENERATOR");
+ this->State->GetInitializedCacheValue("CMAKE_EXTRA_GENERATOR");
if(genName)
{
std::string fullName = cmExternalMakefileProjectGenerator::
- CreateFullGeneratorName(genName, extraGenName);
- this->GlobalGenerator = this->CreateGlobalGenerator(fullName.c_str());
+ CreateFullGeneratorName(genName,
+ extraGenName ? extraGenName : "");
+ this->GlobalGenerator = this->CreateGlobalGenerator(fullName);
}
if(this->GlobalGenerator)
{
@@ -2231,9 +1413,7 @@ int cmake::ActualConfigure()
}
else
{
-#if defined(__BORLANDC__) && defined(_WIN32)
- this->SetGlobalGenerator(new cmGlobalBorlandMakefileGenerator);
-#elif defined(_WIN32) && !defined(__CYGWIN__) && !defined(CMAKE_BOOT_MINGW)
+#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(CMAKE_BOOT_MINGW)
std::string installedCompiler;
// Try to find the newest VS installed on the computer and
// use that as a default if -G is not specified
@@ -2254,9 +1434,10 @@ int cmake::ActualConfigure()
{"7.1", "Visual Studio 7 .NET 2003"},
{"8.0", "Visual Studio 8 2005"},
{"9.0", "Visual Studio 9 2008"},
- {"10.0", "Visual Studio 10"},
- {"11.0", "Visual Studio 11"},
- {"12.0", "Visual Studio 12"},
+ {"10.0", "Visual Studio 10 2010"},
+ {"11.0", "Visual Studio 11 2012"},
+ {"12.0", "Visual Studio 12 2013"},
+ {"14.0", "Visual Studio 14 2015"},
{0, 0}};
for(int i=0; version[i].MSVersion != 0; i++)
{
@@ -2277,12 +1458,12 @@ int cmake::ActualConfigure()
= this->CreateGlobalGenerator(installedCompiler.c_str());
if(!gen)
{
- gen = new cmGlobalNMakeMakefileGenerator;
+ gen = new cmGlobalNMakeMakefileGenerator(this);
}
this->SetGlobalGenerator(gen);
std::cout << "-- Building for: " << gen->GetName() << "\n";
#else
- this->SetGlobalGenerator(new cmGlobalUnixMakefileGenerator3);
+ this->SetGlobalGenerator(new cmGlobalUnixMakefileGenerator3(this));
#endif
}
if(!this->GlobalGenerator)
@@ -2292,36 +1473,65 @@ int cmake::ActualConfigure()
}
}
- const char* genName = this->CacheManager->GetCacheValue("CMAKE_GENERATOR");
+ const char* genName = this->State
+ ->GetInitializedCacheValue("CMAKE_GENERATOR");
if(genName)
{
- if(strcmp(this->GlobalGenerator->GetName(), genName) != 0)
+ if(!this->GlobalGenerator->MatchesGeneratorName(genName))
{
std::string message = "Error: generator : ";
message += this->GlobalGenerator->GetName();
message += "\nDoes not match the generator used previously: ";
message += genName;
message +=
- "\nEither remove the CMakeCache.txt file or choose a different"
- " binary directory.";
+ "\nEither remove the CMakeCache.txt file and CMakeFiles "
+ "directory or choose a different binary directory.";
cmSystemTools::Error(message.c_str());
return -2;
}
}
- if(!this->CacheManager->GetCacheValue("CMAKE_GENERATOR"))
+ if(!this->State->GetInitializedCacheValue("CMAKE_GENERATOR"))
{
- this->CacheManager->AddCacheEntry("CMAKE_GENERATOR",
- this->GlobalGenerator->GetName(),
+ this->AddCacheEntry("CMAKE_GENERATOR",
+ this->GlobalGenerator->GetName().c_str(),
"Name of generator.",
- cmCacheManager::INTERNAL);
- this->CacheManager->AddCacheEntry("CMAKE_EXTRA_GENERATOR",
- this->GlobalGenerator->GetExtraGeneratorName(),
- "Name of external makefile project generator.",
- cmCacheManager::INTERNAL);
+ cmState::INTERNAL);
+ this->AddCacheEntry("CMAKE_EXTRA_GENERATOR",
+ this->GlobalGenerator->GetExtraGeneratorName().c_str(),
+ "Name of external makefile project generator.",
+ cmState::INTERNAL);
+ }
+
+ if(const char* platformName =
+ this->State->GetInitializedCacheValue("CMAKE_GENERATOR_PLATFORM"))
+ {
+ if(this->GeneratorPlatform.empty())
+ {
+ this->GeneratorPlatform = platformName;
+ }
+ else if(this->GeneratorPlatform != platformName)
+ {
+ std::string message = "Error: generator platform: ";
+ message += this->GeneratorPlatform;
+ message += "\nDoes not match the platform used previously: ";
+ message += platformName;
+ message +=
+ "\nEither remove the CMakeCache.txt file and CMakeFiles "
+ "directory or choose a different binary directory.";
+ cmSystemTools::Error(message.c_str());
+ return -2;
+ }
+ }
+ else
+ {
+ this->AddCacheEntry("CMAKE_GENERATOR_PLATFORM",
+ this->GeneratorPlatform.c_str(),
+ "Name of generator platform.",
+ cmState::INTERNAL);
}
if(const char* tsName =
- this->CacheManager->GetCacheValue("CMAKE_GENERATOR_TOOLSET"))
+ this->State->GetInitializedCacheValue("CMAKE_GENERATOR_TOOLSET"))
{
if(this->GeneratorToolset.empty())
{
@@ -2334,36 +1544,27 @@ int cmake::ActualConfigure()
message += "\nDoes not match the toolset used previously: ";
message += tsName;
message +=
- "\nEither remove the CMakeCache.txt file or choose a different"
- " binary directory.";
+ "\nEither remove the CMakeCache.txt file and CMakeFiles "
+ "directory or choose a different binary directory.";
cmSystemTools::Error(message.c_str());
return -2;
}
}
else
{
- this->CacheManager->AddCacheEntry("CMAKE_GENERATOR_TOOLSET",
+ this->AddCacheEntry("CMAKE_GENERATOR_TOOLSET",
this->GeneratorToolset.c_str(),
"Name of generator toolset.",
- cmCacheManager::INTERNAL);
- }
- if(!this->GeneratorToolset.empty() &&
- !this->GlobalGenerator->SetGeneratorToolset(this->GeneratorToolset))
- {
- return -2;
+ cmState::INTERNAL);
}
// reset any system configuration information, except for when we are
// InTryCompile. With TryCompile the system info is taken from the parent's
// info to save time
- if (!this->InTryCompile)
+ if (!this->State->GetIsInTryCompile())
{
this->GlobalGenerator->ClearEnabledLanguages();
- }
- // Truncate log files
- if (!this->InTryCompile)
- {
this->TruncateOutputLog("CMakeOutput.log");
this->TruncateOutputLog("CMakeError.log");
}
@@ -2380,51 +1581,29 @@ int cmake::ActualConfigure()
// project requires compatibility with CMake 2.4. We detect this
// here by looking for the old CMAKE_BACKWARDS_COMPATIBILITY
// variable created when CMP0001 is not set to NEW.
- if(this->GetCacheManager()->GetCacheValue("CMAKE_BACKWARDS_COMPATIBILITY"))
+ if(this->State
+ ->GetInitializedCacheValue("CMAKE_BACKWARDS_COMPATIBILITY"))
{
- if(!this->CacheManager->GetCacheValue("LIBRARY_OUTPUT_PATH"))
+ if(!this->State->GetInitializedCacheValue("LIBRARY_OUTPUT_PATH"))
{
- this->CacheManager->AddCacheEntry
+ this->AddCacheEntry
("LIBRARY_OUTPUT_PATH", "",
"Single output directory for building all libraries.",
- cmCacheManager::PATH);
+ cmState::PATH);
}
- if(!this->CacheManager->GetCacheValue("EXECUTABLE_OUTPUT_PATH"))
+ if(!this->State
+ ->GetInitializedCacheValue("EXECUTABLE_OUTPUT_PATH"))
{
- this->CacheManager->AddCacheEntry
+ this->AddCacheEntry
("EXECUTABLE_OUTPUT_PATH", "",
"Single output directory for building all executables.",
- cmCacheManager::PATH);
+ cmState::PATH);
}
}
- if(!this->CacheManager->GetCacheValue("CMAKE_USE_RELATIVE_PATHS"))
- {
- this->CacheManager->AddCacheEntry
- ("CMAKE_USE_RELATIVE_PATHS", "OFF",
- "If true, cmake will use relative paths in makefiles and projects.",
- cmCacheManager::BOOL);
- cmCacheManager::CacheIterator it =
- this->CacheManager->GetCacheIterator("CMAKE_USE_RELATIVE_PATHS");
- if ( !it.PropertyExists("ADVANCED") )
- {
- it.SetProperty("ADVANCED", "1");
- }
- }
-
- if(cmSystemTools::GetFatalErrorOccured() &&
- (!this->CacheManager->GetCacheValue("CMAKE_MAKE_PROGRAM") ||
- cmSystemTools::IsOff(this->CacheManager->
- GetCacheValue("CMAKE_MAKE_PROGRAM"))))
- {
- // We must have a bad generator selection. Wipe the cache entry so the
- // user can select another.
- this->CacheManager->RemoveCacheEntry("CMAKE_GENERATOR");
- this->CacheManager->RemoveCacheEntry("CMAKE_EXTRA_GENERATOR");
- }
- cmMakefile* mf=this->GlobalGenerator->GetLocalGenerators()[0]->GetMakefile();
+ cmMakefile* mf=this->GlobalGenerator->GetMakefiles()[0];
if (mf->IsOn("CTEST_USE_LAUNCHERS")
- && !this->GetProperty("RULE_LAUNCH_COMPILE", cmProperty::GLOBAL))
+ && !this->State->GetGlobalProperty("RULE_LAUNCH_COMPILE"))
{
cmSystemTools::Error("CTEST_USE_LAUNCHERS is enabled, but the "
"RULE_LAUNCH_COMPILE global property is not defined.\n"
@@ -2435,12 +1614,7 @@ int cmake::ActualConfigure()
// only save the cache if there were no fatal errors
if ( this->GetWorkingMode() == NORMAL_MODE )
{
- this->CacheManager->SaveCache(this->GetHomeOutputDirectory());
- }
- if ( !this->GraphVizFile.empty() )
- {
- std::cout << "Generate graphviz: " << this->GraphVizFile << std::endl;
- this->GenerateGraphViz(this->GraphVizFile.c_str());
+ this->SaveCache(this->GetHomeOutputDirectory());
}
if(cmSystemTools::GetErrorOccuredFlag())
{
@@ -2453,7 +1627,7 @@ void cmake::PreLoadCMakeFiles()
{
std::vector<std::string> args;
std::string pre_load = this->GetHomeDirectory();
- if ( pre_load.size() > 0 )
+ if (!pre_load.empty())
{
pre_load += "/PreLoad.cmake";
if ( cmSystemTools::FileExists(pre_load.c_str()) )
@@ -2462,7 +1636,7 @@ void cmake::PreLoadCMakeFiles()
}
}
pre_load = this->GetHomeOutputDirectory();
- if ( pre_load.size() > 0 )
+ if (!pre_load.empty())
{
pre_load += "/PreLoad.cmake";
if ( cmSystemTools::FileExists(pre_load.c_str()) )
@@ -2496,9 +1670,6 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
return 0;
}
- // set the cmake command
- this->CMakeCommand = args[0];
-
if ( this->GetWorkingMode() == NORMAL_MODE )
{
// load the cache
@@ -2512,6 +1683,7 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
{
this->AddCMakePaths();
}
+
// Add any cache args
if ( !this->SetCacheArgs(args) )
{
@@ -2556,12 +1728,6 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
return 0;
}
- // If we are doing global generate, we better set start and start
- // output directory to the root of the project.
- std::string oldstartdir = this->GetStartDirectory();
- std::string oldstartoutputdir = this->GetStartOutputDirectory();
- this->SetStartDirectory(this->GetHomeDirectory());
- this->SetStartOutputDirectory(this->GetHomeOutputDirectory());
int ret = this->Configure();
if (ret || this->GetWorkingMode() != NORMAL_MODE)
{
@@ -2587,13 +1753,6 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
std::string message = "Build files have been written to: ";
message += this->GetHomeOutputDirectory();
this->UpdateProgress(message.c_str(), -1);
- if(ret)
- {
- return ret;
- }
- this->SetStartDirectory(oldstartdir.c_str());
- this->SetStartOutputDirectory(oldstartoutputdir.c_str());
-
return ret;
}
@@ -2603,7 +1762,16 @@ int cmake::Generate()
{
return -1;
}
+ if (!this->GlobalGenerator->Compute())
+ {
+ return -1;
+ }
this->GlobalGenerator->Generate();
+ if ( !this->GraphVizFile.empty() )
+ {
+ std::cout << "Generate graphviz: " << this->GraphVizFile << std::endl;
+ this->GenerateGraphViz(this->GraphVizFile.c_str());
+ }
if(this->WarnUnusedCli)
{
this->RunCheckForUnusedVariables();
@@ -2612,45 +1780,41 @@ int cmake::Generate()
{
return -1;
}
- if (this->GetProperty("REPORT_UNDEFINED_PROPERTIES"))
- {
- this->ReportUndefinedPropertyAccesses
- (this->GetProperty("REPORT_UNDEFINED_PROPERTIES"));
- }
// Save the cache again after a successful Generate so that any internal
// variables created during Generate are saved. (Specifically target GUIDs
// for the Visual Studio and Xcode generators.)
if ( this->GetWorkingMode() == NORMAL_MODE )
{
- this->CacheManager->SaveCache(this->GetHomeOutputDirectory());
+ this->SaveCache(this->GetHomeOutputDirectory());
}
return 0;
}
-void cmake::AddCacheEntry(const char* key, const char* value,
+void cmake::AddCacheEntry(const std::string& key, const char* value,
const char* helpString,
int type)
{
- this->CacheManager->AddCacheEntry(key, value,
+ this->State->AddCacheEntry(key, value,
helpString,
- cmCacheManager::CacheEntryType(type));
+ cmState::CacheEntryType(type));
+ this->UnwatchUnusedCli(key);
}
-const char* cmake::GetCacheDefinition(const char* name) const
+const char* cmake::GetCacheDefinition(const std::string& name) const
{
- return this->CacheManager->GetCacheValue(name);
+ return this->State->GetInitializedCacheValue(name);
}
void cmake::AddDefaultCommands()
{
- std::list<cmCommand*> commands;
+ std::vector<cmCommand*> commands;
GetBootstrapCommands1(commands);
GetBootstrapCommands2(commands);
GetPredefinedCommands(commands);
- for(std::list<cmCommand*>::iterator i = commands.begin();
+ for(std::vector<cmCommand*>::iterator i = commands.begin();
i != commands.end(); ++i)
{
- this->AddCommand(*i);
+ this->State->AddCommand(*i);
}
}
@@ -2659,21 +1823,23 @@ void cmake::AddDefaultGenerators()
#if defined(_WIN32) && !defined(__CYGWIN__)
# if !defined(CMAKE_BOOT_MINGW)
this->Generators.push_back(
- cmGlobalVisualStudio6Generator::NewFactory());
+ cmGlobalVisualStudio14Generator::NewFactory());
this->Generators.push_back(
- cmGlobalVisualStudio7Generator::NewFactory());
+ cmGlobalVisualStudio12Generator::NewFactory());
+ this->Generators.push_back(
+ cmGlobalVisualStudio11Generator::NewFactory());
this->Generators.push_back(
cmGlobalVisualStudio10Generator::NewFactory());
this->Generators.push_back(
- cmGlobalVisualStudio11Generator::NewFactory());
+ cmGlobalVisualStudio9Generator::NewFactory());
this->Generators.push_back(
- cmGlobalVisualStudio12Generator::NewFactory());
+ cmGlobalVisualStudio8Generator::NewFactory());
this->Generators.push_back(
cmGlobalVisualStudio71Generator::NewFactory());
this->Generators.push_back(
- cmGlobalVisualStudio8Generator::NewFactory());
+ cmGlobalVisualStudio7Generator::NewFactory());
this->Generators.push_back(
- cmGlobalVisualStudio9Generator::NewFactory());
+ cmGlobalVisualStudio6Generator::NewFactory());
this->Generators.push_back(
cmGlobalBorlandMakefileGenerator::NewFactory());
this->Generators.push_back(
@@ -2681,7 +1847,7 @@ void cmake::AddDefaultGenerators()
this->Generators.push_back(
cmGlobalJOMMakefileGenerator::NewFactory());
this->Generators.push_back(
- cmGlobalWatcomWMakeGenerator::NewFactory());
+ cmGlobalGhsMultiGenerator::NewFactory());
# endif
this->Generators.push_back(
cmGlobalMSYSMakefileGenerator::NewFactory());
@@ -2690,18 +1856,32 @@ void cmake::AddDefaultGenerators()
#endif
this->Generators.push_back(
cmGlobalUnixMakefileGenerator3::NewFactory());
+#if defined(CMAKE_BUILD_WITH_CMAKE)
this->Generators.push_back(
cmGlobalNinjaGenerator::NewFactory());
+#endif
+#if defined(CMAKE_USE_WMAKE)
+ this->Generators.push_back(
+ cmGlobalWatcomWMakeGenerator::NewFactory());
+#endif
#ifdef CMAKE_USE_XCODE
this->Generators.push_back(
cmGlobalXCodeGenerator::NewFactory());
#endif
}
+bool cmake::ParseCacheEntry(const std::string& entry,
+ std::string& var,
+ std::string& value,
+ cmState::CacheEntryType& type)
+{
+ return cmState::ParseCacheEntry(entry, var, value, type);
+}
+
int cmake::LoadCache()
{
// could we not read the cache
- if (!this->CacheManager->LoadCache(this->GetHomeOutputDirectory()))
+ if (!this->LoadCache(this->GetHomeOutputDirectory()))
{
// if it does exist, but isn't readable then warn the user
std::string cacheFile = this->GetHomeOutputDirectory();
@@ -2716,14 +1896,6 @@ int cmake::LoadCache()
}
}
- if (this->CMakeCommand.size() < 2)
- {
- cmSystemTools::Error(
- "cmake command was not specified prior to loading the cache in "
- "cmake.cxx");
- return -1;
- }
-
// setup CMAKE_ROOT and CMAKE_COMMAND
if(!this->AddCMakePaths())
{
@@ -2732,60 +1904,72 @@ int cmake::LoadCache()
return 0;
}
-void cmake::SetProgressCallback(ProgressCallbackType f, void *cd)
+bool cmake::LoadCache(const std::string& path)
{
- this->ProgressCallback = f;
- this->ProgressCallbackClientData = cd;
+ std::set<std::string> emptySet;
+ return this->LoadCache(path, true, emptySet, emptySet);
}
-void cmake::UpdateProgress(const char *msg, float prog)
+bool cmake::LoadCache(const std::string& path, bool internal,
+ std::set<std::string>& excludes,
+ std::set<std::string>& includes)
{
- if(this->ProgressCallback && !this->InTryCompile)
+ bool result = this->State->LoadCache(path, internal, excludes, includes);
+ static const char* entries[] = {"CMAKE_CACHE_MAJOR_VERSION",
+ "CMAKE_CACHE_MINOR_VERSION"};
+ for (const char* const* nameIt = cmArrayBegin(entries);
+ nameIt != cmArrayEnd(entries); ++nameIt)
{
- (*this->ProgressCallback)(msg, prog, this->ProgressCallbackClientData);
- return;
+ this->UnwatchUnusedCli(*nameIt);
}
+ return result;
}
-void cmake::GetCommandDocumentation(std::vector<cmDocumentationEntry>& v,
- bool withCurrentCommands,
- bool withCompatCommands) const
+bool cmake::SaveCache(const std::string& path)
{
- for(RegisteredCommandsMap::const_iterator j = this->Commands.begin();
- j != this->Commands.end(); ++j)
+ bool result = this->State->SaveCache(path);
+ static const char* entries[] = {"CMAKE_CACHE_MAJOR_VERSION",
+ "CMAKE_CACHE_MINOR_VERSION",
+ "CMAKE_CACHE_PATCH_VERSION",
+ "CMAKE_CACHEFILE_DIR"};
+ for (const char* const* nameIt = cmArrayBegin(entries);
+ nameIt != cmArrayEnd(entries); ++nameIt)
{
- if ((( withCompatCommands == false) && ( (*j).second->IsDiscouraged()))
- || ((withCurrentCommands == false) && (!(*j).second->IsDiscouraged()))
- || (!((*j).second->ShouldAppearInDocumentation()))
- )
- {
- continue;
- }
-
- cmDocumentationEntry e((*j).second->GetName(),
- (*j).second->GetTerseDocumentation(),
- (*j).second->GetFullDocumentation());
- v.push_back(e);
+ this->UnwatchUnusedCli(*nameIt);
}
+ return result;
}
-void cmake::GetPolicyDocumentation(std::vector<cmDocumentationEntry>& v)
+bool cmake::DeleteCache(const std::string& path)
{
- this->Policies->GetDocumentation(v);
+ return this->State->DeleteCache(path);
}
-void cmake::GetPropertiesDocumentation(std::map<std::string,
- cmDocumentationSection *>& v)
+void cmake::SetProgressCallback(ProgressCallbackType f, void *cd)
{
- // loop over the properties and put them into the doc structure
- std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::iterator i;
- i = this->PropertyDefinitions.begin();
- for (;i != this->PropertyDefinitions.end(); ++i)
+ this->ProgressCallback = f;
+ this->ProgressCallbackClientData = cd;
+}
+
+void cmake::UpdateProgress(const char *msg, float prog)
+{
+ if(this->ProgressCallback && !this->State->GetIsInTryCompile())
{
- i->second.GetPropertiesDocumentation(v);
+ (*this->ProgressCallback)(msg, prog, this->ProgressCallbackClientData);
+ return;
}
}
+bool cmake::GetIsInTryCompile() const
+{
+ return this->State->GetIsInTryCompile();
+}
+
+void cmake::SetIsInTryCompile(bool b)
+{
+ this->State->SetIsInTryCompile(b);
+}
+
void cmake::GetGeneratorDocumentation(std::vector<cmDocumentationEntry>& v)
{
for(RegisteredGeneratorsVector::const_iterator i =
@@ -2800,22 +1984,35 @@ void cmake::GetGeneratorDocumentation(std::vector<cmDocumentationEntry>& v)
{
cmDocumentationEntry e;
cmExternalMakefileProjectGenerator* generator = (i->second)();
- generator->GetDocumentation(e, i->first.c_str());
+ generator->GetDocumentation(e, i->first);
e.Name = i->first;
delete generator;
v.push_back(e);
}
}
+void cmake::PrintGeneratorList()
+{
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ cmDocumentation doc;
+ std::vector<cmDocumentationEntry> generators;
+ this->GetGeneratorDocumentation(generators);
+ doc.AppendSection("Generators",generators);
+ std::cerr << "\n";
+ doc.PrintDocumentation(cmDocumentation::ListGenerators, std::cerr);
+#endif
+}
+
void cmake::UpdateConversionPathTable()
{
// Update the path conversion table with any specified file:
const char* tablepath =
- this->CacheManager->GetCacheValue("CMAKE_PATH_TRANSLATION_FILE");
+ this->State
+ ->GetInitializedCacheValue("CMAKE_PATH_TRANSLATION_FILE");
if(tablepath)
{
- std::ifstream table( tablepath );
+ cmsys::ifstream table( tablepath );
if(!table)
{
cmSystemTools::Error("CMAKE_PATH_TRANSLATION_FILE set to ", tablepath,
@@ -2829,7 +2026,7 @@ void cmake::UpdateConversionPathTable()
{
// two entries per line
table >> a; table >> b;
- cmSystemTools::AddTranslationPath( a.c_str(), b.c_str());
+ cmSystemTools::AddTranslationPath( a, b);
}
}
}
@@ -2850,11 +2047,11 @@ int cmake::CheckBuildSystem()
// determine whether CMake should rerun.
// If no file is provided for the check, we have to rerun.
- if(this->CheckBuildSystemArgument.size() == 0)
+ if(this->CheckBuildSystemArgument.empty())
{
if(verbose)
{
- cmOStringStream msg;
+ std::ostringstream msg;
msg << "Re-run cmake no build system arguments\n";
cmSystemTools::Stdout(msg.str().c_str());
}
@@ -2866,9 +2063,9 @@ int cmake::CheckBuildSystem()
{
if(verbose)
{
- cmOStringStream msg;
+ std::ostringstream msg;
msg << "Re-run cmake missing file: "
- << this->CheckBuildSystemArgument.c_str() << "\n";
+ << this->CheckBuildSystemArgument << "\n";
cmSystemTools::Stdout(msg.str().c_str());
}
return 1;
@@ -2877,18 +2074,19 @@ int cmake::CheckBuildSystem()
// Read the rerun check file and use it to decide whether to do the
// global generate.
cmake cm;
- cmGlobalGenerator gg;
- gg.SetCMakeInstance(&cm);
- cmsys::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator());
- cmMakefile* mf = lg->GetMakefile();
- if(!mf->ReadListFile(0, this->CheckBuildSystemArgument.c_str()) ||
+ cm.SetHomeDirectory("");
+ cm.SetHomeOutputDirectory("");
+ cm.GetCurrentSnapshot().SetDefaultDefinitions();
+ cmGlobalGenerator gg(&cm);
+ cmsys::auto_ptr<cmMakefile> mf(new cmMakefile(&gg, cm.GetCurrentSnapshot()));
+ if(!mf->ReadListFile(this->CheckBuildSystemArgument.c_str()) ||
cmSystemTools::GetErrorOccuredFlag())
{
if(verbose)
{
- cmOStringStream msg;
+ std::ostringstream msg;
msg << "Re-run cmake error reading : "
- << this->CheckBuildSystemArgument.c_str() << "\n";
+ << this->CheckBuildSystemArgument << "\n";
cmSystemTools::Stdout(msg.str().c_str());
}
// There was an error reading the file. Just rerun.
@@ -2909,8 +2107,12 @@ int cmake::CheckBuildSystem()
ggd(this->CreateGlobalGenerator(genName));
if(ggd.get())
{
- cmsys::auto_ptr<cmLocalGenerator> lgd(ggd->CreateLocalGenerator());
- lgd->ClearDependencies(mf, verbose);
+ cm.GetCurrentSnapshot().SetDefaultDefinitions();
+ cmsys::auto_ptr<cmMakefile> mfd(new cmMakefile(ggd.get(),
+ cm.GetCurrentSnapshot()));
+ cmsys::auto_ptr<cmLocalGenerator> lgd(
+ ggd->CreateLocalGenerator(mfd.get()));
+ lgd->ClearDependencies(mfd.get(), verbose);
}
}
@@ -2924,11 +2126,11 @@ int cmake::CheckBuildSystem()
pi != products.end(); ++pi)
{
if(!(cmSystemTools::FileExists(pi->c_str()) ||
- cmSystemTools::FileIsSymlink(pi->c_str())))
+ cmSystemTools::FileIsSymlink(*pi)))
{
if(verbose)
{
- cmOStringStream msg;
+ std::ostringstream msg;
msg << "Re-run cmake, missing byproduct: " << *pi << "\n";
cmSystemTools::Stdout(msg.str().c_str());
}
@@ -2951,7 +2153,7 @@ int cmake::CheckBuildSystem()
// Not enough information was provided to do the test. Just rerun.
if(verbose)
{
- cmOStringStream msg;
+ std::ostringstream msg;
msg << "Re-run cmake no CMAKE_MAKEFILE_DEPENDS "
"or CMAKE_MAKEFILE_OUTPUTS :\n";
cmSystemTools::Stdout(msg.str().c_str());
@@ -2977,7 +2179,7 @@ int cmake::CheckBuildSystem()
{
if(verbose)
{
- cmOStringStream msg;
+ std::ostringstream msg;
msg << "Re-run cmake: build system dependency is missing\n";
cmSystemTools::Stdout(msg.str().c_str());
}
@@ -3003,7 +2205,7 @@ int cmake::CheckBuildSystem()
{
if(verbose)
{
- cmOStringStream msg;
+ std::ostringstream msg;
msg << "Re-run cmake: build system output is missing\n";
cmSystemTools::Stdout(msg.str().c_str());
}
@@ -3021,9 +2223,9 @@ int cmake::CheckBuildSystem()
{
if(verbose)
{
- cmOStringStream msg;
- msg << "Re-run cmake file: " << out_oldest.c_str()
- << " older than: " << dep_newest.c_str() << "\n";
+ std::ostringstream msg;
+ msg << "Re-run cmake file: " << out_oldest
+ << " older than: " << dep_newest << "\n";
cmSystemTools::Stdout(msg.str().c_str());
}
return 1;
@@ -3045,9 +2247,9 @@ void cmake::TruncateOutputLog(const char* fname)
{
return;
}
- if ( !this->CacheManager->GetCacheValue("CMAKE_CACHEFILE_DIR") )
+ if (!this->State->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR"))
{
- cmSystemTools::RemoveFile(fullPath.c_str());
+ cmSystemTools::RemoveFile(fullPath);
return;
}
off_t fsize = st.st_size;
@@ -3068,82 +2270,6 @@ inline std::string removeQuotes(const std::string& s)
return s;
}
-std::string cmake::FindCMakeProgram(const char* name) const
-{
- std::string path;
- if ((name) && (*name))
- {
- const cmMakefile* mf
- = this->GetGlobalGenerator()->GetLocalGenerators()[0]->GetMakefile();
-#ifdef CMAKE_BUILD_WITH_CMAKE
- path = mf->GetRequiredDefinition("CMAKE_COMMAND");
- path = removeQuotes(path);
- path = cmSystemTools::GetFilenamePath(path.c_str());
- path += "/";
- path += name;
- path += cmSystemTools::GetExecutableExtension();
- if(!cmSystemTools::FileExists(path.c_str()))
- {
- path = mf->GetRequiredDefinition("CMAKE_COMMAND");
- path = cmSystemTools::GetFilenamePath(path.c_str());
- path += "/Debug/";
- path += name;
- path += cmSystemTools::GetExecutableExtension();
- }
- if(!cmSystemTools::FileExists(path.c_str()))
- {
- path = mf->GetRequiredDefinition("CMAKE_COMMAND");
- path = cmSystemTools::GetFilenamePath(path.c_str());
- path += "/Release/";
- path += name;
- path += cmSystemTools::GetExecutableExtension();
- }
-#else
- // Only for bootstrap
- path += mf->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH");
- path += "/";
- path += name;
- path += cmSystemTools::GetExecutableExtension();
-#endif
- }
- return path;
-}
-
-const char* cmake::GetCTestCommand()
-{
- if ( this->CTestCommand.empty() )
- {
- this->CTestCommand = this->FindCMakeProgram("ctest");
- }
- if ( this->CTestCommand.empty() )
- {
- cmSystemTools::Error("Cannot find the CTest executable");
- this->CTestCommand = "CTEST-COMMAND-NOT-FOUND";
- }
- return this->CTestCommand.c_str();
-}
-
-const char* cmake::GetCPackCommand()
-{
- if ( this->CPackCommand.empty() )
- {
- this->CPackCommand = this->FindCMakeProgram("cpack");
- }
- if ( this->CPackCommand.empty() )
- {
- cmSystemTools::Error("Cannot find the CPack executable");
- this->CPackCommand = "CPACK-COMMAND-NOT-FOUND";
- }
- return this->CPackCommand.c_str();
-}
-
-
-const char* cmake::GetCMakeCommand()
-{
- return this->CMakeCommand.c_str();
-}
-
-
void cmake::MarkCliAsUsed(const std::string& variable)
{
this->UsedCliVariables[variable] = true;
@@ -3169,717 +2295,60 @@ void cmake::GenerateGraphViz(const char* fileName) const
#endif
}
-
-//----------------------------------------------------------------------------
-int cmake::SymlinkLibrary(std::vector<std::string>& args)
+void cmake::SetProperty(const std::string& prop, const char* value)
{
- int result = 0;
- std::string realName = args[2];
- std::string soName = args[3];
- std::string name = args[4];
- if(soName != realName)
- {
- if(!cmake::SymlinkInternal(realName, soName))
- {
- cmSystemTools::ReportLastSystemError("cmake_symlink_library");
- result = 1;
- }
- }
- if(name != soName)
- {
- if(!cmake::SymlinkInternal(soName, name))
- {
- cmSystemTools::ReportLastSystemError("cmake_symlink_library");
- result = 1;
- }
- }
- return result;
+ this->State->SetGlobalProperty(prop, value);
}
-//----------------------------------------------------------------------------
-int cmake::SymlinkExecutable(std::vector<std::string>& args)
+void cmake::AppendProperty(const std::string& prop,
+ const char* value, bool asString)
{
- int result = 0;
- std::string realName = args[2];
- std::string name = args[3];
- if(name != realName)
- {
- if(!cmake::SymlinkInternal(realName, name))
- {
- cmSystemTools::ReportLastSystemError("cmake_symlink_executable");
- result = 1;
- }
- }
- return result;
+ this->State->AppendGlobalProperty(prop, value, asString);
}
-//----------------------------------------------------------------------------
-bool cmake::SymlinkInternal(std::string const& file, std::string const& link)
+const char *cmake::GetProperty(const std::string& prop)
{
- if(cmSystemTools::FileExists(link.c_str()) ||
- cmSystemTools::FileIsSymlink(link.c_str()))
- {
- cmSystemTools::RemoveFile(link.c_str());
- }
-#if defined(_WIN32) && !defined(__CYGWIN__)
- return cmSystemTools::CopyFileAlways(file.c_str(), link.c_str());
-#else
- std::string linktext = cmSystemTools::GetFilenameName(file);
- return cmSystemTools::CreateSymlink(linktext.c_str(), link.c_str());
-#endif
+ return this->State->GetGlobalProperty(prop);
}
-//----------------------------------------------------------------------------
-#ifdef CMAKE_BUILD_WITH_CMAKE
-int cmake::ExecuteEchoColor(std::vector<std::string>& args)
+bool cmake::GetPropertyAsBool(const std::string& prop)
{
- // The arguments are
- // argv[0] == <cmake-executable>
- // argv[1] == cmake_echo_color
-
- bool enabled = true;
- int color = cmsysTerminal_Color_Normal;
- bool newline = true;
- for(unsigned int i=2; i < args.size(); ++i)
- {
- if(args[i].find("--switch=") == 0)
- {
- // Enable or disable color based on the switch value.
- std::string value = args[i].substr(9);
- if(!value.empty())
- {
- if(cmSystemTools::IsOn(value.c_str()))
- {
- enabled = true;
- }
- else
- {
- enabled = false;
- }
- }
- }
- else if(args[i] == "--normal")
- {
- color = cmsysTerminal_Color_Normal;
- }
- else if(args[i] == "--black")
- {
- color = cmsysTerminal_Color_ForegroundBlack;
- }
- else if(args[i] == "--red")
- {
- color = cmsysTerminal_Color_ForegroundRed;
- }
- else if(args[i] == "--green")
- {
- color = cmsysTerminal_Color_ForegroundGreen;
- }
- else if(args[i] == "--yellow")
- {
- color = cmsysTerminal_Color_ForegroundYellow;
- }
- else if(args[i] == "--blue")
- {
- color = cmsysTerminal_Color_ForegroundBlue;
- }
- else if(args[i] == "--magenta")
- {
- color = cmsysTerminal_Color_ForegroundMagenta;
- }
- else if(args[i] == "--cyan")
- {
- color = cmsysTerminal_Color_ForegroundCyan;
- }
- else if(args[i] == "--white")
- {
- color = cmsysTerminal_Color_ForegroundWhite;
- }
- else if(args[i] == "--bold")
- {
- color |= cmsysTerminal_Color_ForegroundBold;
- }
- else if(args[i] == "--no-newline")
- {
- newline = false;
- }
- else if(args[i] == "--newline")
- {
- newline = true;
- }
- else
- {
- // Color is enabled. Print with the current color.
- cmSystemTools::MakefileColorEcho(color, args[i].c_str(),
- newline, enabled);
- }
- }
-
- return 0;
+ return this->State->GetGlobalPropertyAsBool(prop);
}
-#else
-int cmake::ExecuteEchoColor(std::vector<std::string>&)
-{
- return 1;
-}
-#endif
-//----------------------------------------------------------------------------
-int cmake::ExecuteLinkScript(std::vector<std::string>& args)
+cmInstalledFile *cmake::GetOrCreateInstalledFile(
+ cmMakefile* mf, const std::string& name)
{
- // The arguments are
- // argv[0] == <cmake-executable>
- // argv[1] == cmake_link_script
- // argv[2] == <link-script-name>
- // argv[3] == --verbose=?
- bool verbose = false;
- if(args.size() >= 4)
- {
- if(args[3].find("--verbose=") == 0)
- {
- if(!cmSystemTools::IsOff(args[3].substr(10).c_str()))
- {
- verbose = true;
- }
- }
- }
+ std::map<std::string, cmInstalledFile>::iterator i =
+ this->InstalledFiles.find(name);
- // Allocate a process instance.
- cmsysProcess* cp = cmsysProcess_New();
- if(!cp)
+ if(i != this->InstalledFiles.end())
{
- std::cerr << "Error allocating process instance in link script."
- << std::endl;
- return 1;
+ cmInstalledFile &file = i->second;
+ return &file;
}
-
- // Children should share stdout and stderr with this process.
- cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDOUT, 1);
- cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDERR, 1);
-
- // Run the command lines verbatim.
- cmsysProcess_SetOption(cp, cmsysProcess_Option_Verbatim, 1);
-
- // Read command lines from the script.
- std::ifstream fin(args[2].c_str());
- if(!fin)
- {
- std::cerr << "Error opening link script \""
- << args[2] << "\"" << std::endl;
- return 1;
- }
-
- // Run one command at a time.
- std::string command;
- int result = 0;
- while(result == 0 && cmSystemTools::GetLineFromStream(fin, command))
- {
- // Skip empty command lines.
- if(command.find_first_not_of(" \t") == command.npos)
- {
- continue;
- }
-
- // Setup this command line.
- const char* cmd[2] = {command.c_str(), 0};
- cmsysProcess_SetCommand(cp, cmd);
-
- // Report the command if verbose output is enabled.
- if(verbose)
- {
- std::cout << command << std::endl;
- }
-
- // Run the command and wait for it to exit.
- cmsysProcess_Execute(cp);
- cmsysProcess_WaitForExit(cp, 0);
-
- // Report failure if any.
- switch(cmsysProcess_GetState(cp))
- {
- case cmsysProcess_State_Exited:
- {
- int value = cmsysProcess_GetExitValue(cp);
- if(value != 0)
- {
- result = value;
- }
- }
- break;
- case cmsysProcess_State_Exception:
- std::cerr << "Error running link command: "
- << cmsysProcess_GetExceptionString(cp) << std::endl;
- result = 1;
- break;
- case cmsysProcess_State_Error:
- std::cerr << "Error running link command: "
- << cmsysProcess_GetErrorString(cp) << std::endl;
- result = 2;
- break;
- default:
- break;
- };
- }
-
- // Free the process instance.
- cmsysProcess_Delete(cp);
-
- // Return the final resulting return value.
- return result;
-}
-
-void cmake::DefineProperties(cmake *cm)
-{
- cm->DefineProperty
- ("REPORT_UNDEFINED_PROPERTIES", cmProperty::GLOBAL,
- "If set, report any undefined properties to this file.",
- "If this property is set to a filename then when CMake runs "
- "it will report any properties or variables that were accessed "
- "but not defined into the filename specified in this property."
- );
-
- cm->DefineProperty
- ("TARGET_SUPPORTS_SHARED_LIBS", cmProperty::GLOBAL,
- "Does the target platform support shared libraries.",
- "TARGET_SUPPORTS_SHARED_LIBS is a boolean specifying whether the target "
- "platform supports shared libraries. Basically all current general "
- "general purpose OS do so, the exception are usually embedded systems "
- "with no or special OSs.");
-
- cm->DefineProperty
- ("TARGET_ARCHIVES_MAY_BE_SHARED_LIBS", cmProperty::GLOBAL,
- "Set if shared libraries may be named like archives.",
- "On AIX shared libraries may be named \"lib<name>.a\". "
- "This property is set to true on such platforms.");
-
- cm->DefineProperty
- ("FIND_LIBRARY_USE_LIB64_PATHS", cmProperty::GLOBAL,
- "Whether FIND_LIBRARY should automatically search lib64 directories.",
- "FIND_LIBRARY_USE_LIB64_PATHS is a boolean specifying whether the "
- "FIND_LIBRARY command should automatically search the lib64 variant of "
- "directories called lib in the search path when building 64-bit "
- "binaries.");
- cm->DefineProperty
- ("FIND_LIBRARY_USE_OPENBSD_VERSIONING", cmProperty::GLOBAL,
- "Whether FIND_LIBRARY should find OpenBSD-style shared libraries.",
- "This property is a boolean specifying whether the FIND_LIBRARY "
- "command should find shared libraries with OpenBSD-style versioned "
- "extension: \".so.<major>.<minor>\". "
- "The property is set to true on OpenBSD and false on other platforms.");
- cm->DefineProperty
- ("ENABLED_FEATURES", cmProperty::GLOBAL,
- "List of features which are enabled during the CMake run.",
- "List of features which are enabled during the CMake run. By default "
- "it contains the names of all packages which were found. This is "
- "determined using the <NAME>_FOUND variables. Packages which are "
- "searched QUIET are not listed. A project can add its own features to "
- "this list. "
- "This property is used by the macros in FeatureSummary.cmake.");
- cm->DefineProperty
- ("DISABLED_FEATURES", cmProperty::GLOBAL,
- "List of features which are disabled during the CMake run.",
- "List of features which are disabled during the CMake run. By default "
- "it contains the names of all packages which were not found. This is "
- "determined using the <NAME>_FOUND variables. Packages which are "
- "searched QUIET are not listed. A project can add its own features to "
- "this list. "
- "This property is used by the macros in FeatureSummary.cmake.");
- cm->DefineProperty
- ("PACKAGES_FOUND", cmProperty::GLOBAL,
- "List of packages which were found during the CMake run.",
- "List of packages which were found during the CMake run. Whether a "
- "package has been found is determined using the <NAME>_FOUND variables.");
- cm->DefineProperty
- ("PACKAGES_NOT_FOUND", cmProperty::GLOBAL,
- "List of packages which were not found during the CMake run.",
- "List of packages which were not found during the CMake run. Whether a "
- "package has been found is determined using the <NAME>_FOUND variables.");
-
- cm->DefineProperty(
- "__CMAKE_DELETE_CACHE_CHANGE_VARS_", cmProperty::GLOBAL,
- "Internal property",
- "Used to detect compiler changes, Do not set.");
-
- cm->DefineProperty(
- "DEBUG_CONFIGURATIONS", cmProperty::GLOBAL,
- "Specify which configurations are for debugging.",
- "The value must be a semi-colon separated list of configuration names. "
- "Currently this property is used only by the target_link_libraries "
- "command (see its documentation for details). "
- "Additional uses may be defined in the future. "
- "\n"
- "This property must be set at the top level of the project and before "
- "the first target_link_libraries command invocation. "
- "If any entry in the list does not match a valid configuration for "
- "the project the behavior is undefined.");
-
- cm->DefineProperty(
- "GLOBAL_DEPENDS_DEBUG_MODE", cmProperty::GLOBAL,
- "Enable global target dependency graph debug mode.",
- "CMake automatically analyzes the global inter-target dependency graph "
- "at the beginning of native build system generation. "
- "This property causes it to display details of its analysis to stderr.");
-
- cm->DefineProperty(
- "GLOBAL_DEPENDS_NO_CYCLES", cmProperty::GLOBAL,
- "Disallow global target dependency graph cycles.",
- "CMake automatically analyzes the global inter-target dependency graph "
- "at the beginning of native build system generation. "
- "It reports an error if the dependency graph contains a cycle that "
- "does not consist of all STATIC library targets. "
- "This property tells CMake to disallow all cycles completely, even "
- "among static libraries.");
-
- cm->DefineProperty(
- "ALLOW_DUPLICATE_CUSTOM_TARGETS", cmProperty::GLOBAL,
- "Allow duplicate custom targets to be created.",
- "Normally CMake requires that all targets built in a project have "
- "globally unique logical names (see policy CMP0002). "
- "This is necessary to generate meaningful project file names in "
- "Xcode and VS IDE generators. "
- "It also allows the target names to be referenced unambiguously.\n"
- "Makefile generators are capable of supporting duplicate custom target "
- "names. "
- "For projects that care only about Makefile generators and do "
- "not wish to support Xcode or VS IDE generators, one may set this "
- "property to true to allow duplicate custom targets. "
- "The property allows multiple add_custom_target command calls in "
- "different directories to specify the same target name. "
- "However, setting this property will cause non-Makefile generators "
- "to produce an error and refuse to generate the project."
- );
-
- cm->DefineProperty
- ("IN_TRY_COMPILE", cmProperty::GLOBAL,
- "Read-only property that is true during a try-compile configuration.",
- "True when building a project inside a TRY_COMPILE or TRY_RUN command.");
- cm->DefineProperty
- ("ENABLED_LANGUAGES", cmProperty::GLOBAL,
- "Read-only property that contains the list of currently "
- "enabled languages",
- "Set to list of currently enabled languages.");
-
- cm->DefineProperty
- ("RULE_LAUNCH_COMPILE", cmProperty::GLOBAL,
- "Specify a launcher for compile rules.",
- "Makefile generators prefix compiler commands with the given "
- "launcher command line. "
- "This is intended to allow launchers to intercept build problems "
- "with high granularity. "
- "Non-Makefile generators currently ignore this property.");
- cm->DefineProperty
- ("RULE_LAUNCH_LINK", cmProperty::GLOBAL,
- "Specify a launcher for link rules.",
- "Makefile generators prefix link and archive commands with the given "
- "launcher command line. "
- "This is intended to allow launchers to intercept build problems "
- "with high granularity. "
- "Non-Makefile generators currently ignore this property.");
- cm->DefineProperty
- ("RULE_LAUNCH_CUSTOM", cmProperty::GLOBAL,
- "Specify a launcher for custom rules.",
- "Makefile generators prefix custom commands with the given "
- "launcher command line. "
- "This is intended to allow launchers to intercept build problems "
- "with high granularity. "
- "Non-Makefile generators currently ignore this property.");
-
- cm->DefineProperty
- ("RULE_MESSAGES", cmProperty::GLOBAL,
- "Specify whether to report a message for each make rule.",
- "This property specifies whether Makefile generators should add a "
- "progress message describing what each build rule does. "
- "If the property is not set the default is ON. "
- "Set the property to OFF to disable granular messages and report only "
- "as each target completes. "
- "This is intended to allow scripted builds to avoid the build time "
- "cost of detailed reports. "
- "If a CMAKE_RULE_MESSAGES cache entry exists its value initializes "
- "the value of this property. "
- "Non-Makefile generators currently ignore this property.");
-
- cm->DefineProperty
- ("USE_FOLDERS", cmProperty::GLOBAL,
- "Use the FOLDER target property to organize targets into folders.",
- "If not set, CMake treats this property as OFF by default. "
- "CMake generators that are capable of organizing into a "
- "hierarchy of folders use the values of the FOLDER target "
- "property to name those folders. See also the documentation "
- "for the FOLDER target property.");
-
- cm->DefineProperty
- ("AUTOMOC_TARGETS_FOLDER", cmProperty::GLOBAL,
- "Name of FOLDER for *_automoc targets that are added automatically by "
- "CMake for targets for which AUTOMOC is enabled.",
- "If not set, CMake uses the FOLDER property of the parent target as a "
- "default value for this property. See also the documentation for the "
- "FOLDER target property and the AUTOMOC target property.");
-
- cm->DefineProperty
- ("PREDEFINED_TARGETS_FOLDER", cmProperty::GLOBAL,
- "Name of FOLDER for targets that are added automatically by CMake.",
- "If not set, CMake uses \"CMakePredefinedTargets\" as a default "
- "value for this property. Targets such as INSTALL, PACKAGE and "
- "RUN_TESTS will be organized into this FOLDER. See also the "
- "documentation for the FOLDER target property.");
-
- // ================================================================
- // define variables as well
- // ================================================================
- cmDocumentVariables::DefineVariables(cm);
-}
-
-
-void cmake::DefineProperty(const char *name, cmProperty::ScopeType scope,
- const char *ShortDescription,
- const char *FullDescription,
- bool chained, const char *docSection)
-{
- this->PropertyDefinitions[scope].DefineProperty(name,scope,ShortDescription,
- FullDescription,
- docSection,
- chained);
-}
-
-bool cmake::GetIsPropertyDefined(const char *name,
- cmProperty::ScopeType scope)
-{
- return this->PropertyDefinitions[scope].find(name) !=
- this->PropertyDefinitions[scope].end();
-}
-
-cmPropertyDefinition *cmake
-::GetPropertyDefinition(const char *name,
- cmProperty::ScopeType scope)
-{
- if (this->IsPropertyDefined(name,scope))
- {
- return &(this->PropertyDefinitions[scope][name]);
- }
- return 0;
-}
-
-void cmake::RecordPropertyAccess(const char *name,
- cmProperty::ScopeType scope)
-{
- this->AccessedProperties.insert
- (std::pair<cmStdString,cmProperty::ScopeType>(name,scope));
-}
-
-void cmake::ReportUndefinedPropertyAccesses(const char *filename)
-{
- if(!this->GlobalGenerator)
- { return; }
- FILE *progFile = fopen(filename,"w");
- if(!progFile)
- { return; }
-
- // what are the enabled languages?
- std::vector<std::string> enLangs;
- this->GlobalGenerator->GetEnabledLanguages(enLangs);
-
- // Common configuration names.
- // TODO: Compute current configuration(s).
- std::vector<std::string> enConfigs;
- enConfigs.push_back("");
- enConfigs.push_back("DEBUG");
- enConfigs.push_back("RELEASE");
- enConfigs.push_back("MINSIZEREL");
- enConfigs.push_back("RELWITHDEBINFO");
-
- // take all the defined properties and add definitions for all the enabled
- // languages
- std::set<std::pair<cmStdString,cmProperty::ScopeType> > aliasedProperties;
- std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::iterator i;
- i = this->PropertyDefinitions.begin();
- for (;i != this->PropertyDefinitions.end(); ++i)
- {
- cmPropertyDefinitionMap::iterator j;
- for (j = i->second.begin(); j != i->second.end(); ++j)
- {
- // TODO: What if both <LANG> and <CONFIG> appear?
- if (j->first.find("<CONFIG>") != std::string::npos)
- {
- std::vector<std::string>::const_iterator k;
- for (k = enConfigs.begin(); k != enConfigs.end(); ++k)
- {
- std::string tmp = j->first;
- cmSystemTools::ReplaceString(tmp, "<CONFIG>", k->c_str());
- // add alias
- aliasedProperties.insert
- (std::pair<cmStdString,cmProperty::ScopeType>(tmp,i->first));
- }
- }
- if (j->first.find("<LANG>") != std::string::npos)
- {
- std::vector<std::string>::const_iterator k;
- for (k = enLangs.begin(); k != enLangs.end(); ++k)
- {
- std::string tmp = j->first;
- cmSystemTools::ReplaceString(tmp, "<LANG>", k->c_str());
- // add alias
- aliasedProperties.insert
- (std::pair<cmStdString,cmProperty::ScopeType>(tmp,i->first));
- }
- }
- }
- }
-
- std::set<std::pair<cmStdString,cmProperty::ScopeType> >::const_iterator ap;
- ap = this->AccessedProperties.begin();
- for (;ap != this->AccessedProperties.end(); ++ap)
- {
- if (!this->IsPropertyDefined(ap->first.c_str(),ap->second) &&
- aliasedProperties.find(std::pair<cmStdString,cmProperty::ScopeType>
- (ap->first,ap->second)) ==
- aliasedProperties.end())
- {
- const char *scopeStr = "";
- switch (ap->second)
- {
- case cmProperty::TARGET:
- scopeStr = "TARGET";
- break;
- case cmProperty::SOURCE_FILE:
- scopeStr = "SOURCE_FILE";
- break;
- case cmProperty::DIRECTORY:
- scopeStr = "DIRECTORY";
- break;
- case cmProperty::TEST:
- scopeStr = "TEST";
- break;
- case cmProperty::VARIABLE:
- scopeStr = "VARIABLE";
- break;
- case cmProperty::CACHED_VARIABLE:
- scopeStr = "CACHED_VARIABLE";
- break;
- default:
- scopeStr = "unknown";
- break;
- }
- fprintf(progFile, "%s with scope %s\n", ap->first.c_str(), scopeStr);
- }
- }
- fclose(progFile);
-}
-
-bool cmake::IsPropertyDefined(const char *name, cmProperty::ScopeType scope)
-{
- return this->PropertyDefinitions[scope].IsPropertyDefined(name);
-}
-
-bool cmake::IsPropertyChained(const char *name, cmProperty::ScopeType scope)
-{
- return this->PropertyDefinitions[scope].IsPropertyChained(name);
-}
-
-void cmake::SetProperty(const char* prop, const char* value)
-{
- if (!prop)
- {
- return;
- }
-
- // Special hook to invalidate cached value.
- if(strcmp(prop, "DEBUG_CONFIGURATIONS") == 0)
+ else
{
- this->DebugConfigs.clear();
+ cmInstalledFile &file = this->InstalledFiles[name];
+ file.SetName(mf, name);
+ return &file;
}
-
- this->Properties.SetProperty(prop, value, cmProperty::GLOBAL);
}
-void cmake::AppendProperty(const char* prop, const char* value, bool asString)
+cmInstalledFile const* cmake::GetInstalledFile(const std::string& name) const
{
- if (!prop)
- {
- return;
- }
+ std::map<std::string, cmInstalledFile>::const_iterator i =
+ this->InstalledFiles.find(name);
- // Special hook to invalidate cached value.
- if(strcmp(prop, "DEBUG_CONFIGURATIONS") == 0)
+ if(i != this->InstalledFiles.end())
{
- this->DebugConfigs.clear();
+ cmInstalledFile const& file = i->second;
+ return &file;
}
-
- this->Properties.AppendProperty(prop, value, cmProperty::GLOBAL, asString);
-}
-
-const char *cmake::GetProperty(const char* prop)
-{
- return this->GetProperty(prop, cmProperty::GLOBAL);
-}
-
-const char *cmake::GetProperty(const char* prop, cmProperty::ScopeType scope)
-{
- if(!prop)
+ else
{
return 0;
}
- bool chain = false;
-
- // watch for special properties
- std::string propname = prop;
- std::string output = "";
- if ( propname == "CACHE_VARIABLES" )
- {
- cmCacheManager::CacheIterator cit =
- this->GetCacheManager()->GetCacheIterator();
- for ( cit.Begin(); !cit.IsAtEnd(); cit.Next() )
- {
- if ( output.size() )
- {
- output += ";";
- }
- output += cit.GetName();
- }
- this->SetProperty("CACHE_VARIABLES", output.c_str());
- }
- else if ( propname == "COMMANDS" )
- {
- cmake::RegisteredCommandsMap::iterator cmds
- = this->GetCommands()->begin();
- for (unsigned int cc=0 ; cmds != this->GetCommands()->end(); ++ cmds )
- {
- if ( cc > 0 )
- {
- output += ";";
- }
- output += cmds->first.c_str();
- cc++;
- }
- this->SetProperty("COMMANDS",output.c_str());
- }
- else if ( propname == "IN_TRY_COMPILE" )
- {
- this->SetProperty("IN_TRY_COMPILE",
- this->GetIsInTryCompile()? "1":"0");
- }
- else if ( propname == "ENABLED_LANGUAGES" )
- {
- std::string lang;
- if(this->GlobalGenerator)
- {
- std::vector<std::string> enLangs;
- this->GlobalGenerator->GetEnabledLanguages(enLangs);
- const char* sep = "";
- for(std::vector<std::string>::iterator i = enLangs.begin();
- i != enLangs.end(); ++i)
- {
- lang += sep;
- sep = ";";
- lang += *i;
- }
- }
- this->SetProperty("ENABLED_LANGUAGES", lang.c_str());
- }
- return this->Properties.GetPropertyValue(prop, scope, chain);
-}
-
-bool cmake::GetPropertyAsBool(const char* prop)
-{
- return cmSystemTools::IsOn(this->GetProperty(prop));
}
int cmake::GetSystemInformation(std::vector<std::string>& args)
@@ -3888,7 +2357,7 @@ int cmake::GetSystemInformation(std::vector<std::string>& args)
std::string resultFile;
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
std::string destPath = cwd + "/__cmake_systeminformation";
- cmSystemTools::RemoveADirectory(destPath.c_str());
+ cmSystemTools::RemoveADirectory(destPath);
if (!cmSystemTools::MakeDirectory(destPath.c_str()))
{
std::cerr << "Error: --system-information must be run from a "
@@ -3908,22 +2377,24 @@ int cmake::GetSystemInformation(std::vector<std::string>& args)
else if(arg.find("-G",0) == 0)
{
std::string value = arg.substr(2);
- if(value.size() == 0)
+ if(value.empty())
{
++i;
if(i >= args.size())
{
cmSystemTools::Error("No generator specified for -G");
+ this->PrintGeneratorList();
return -1;
}
value = args[i];
}
cmGlobalGenerator* gen =
- this->CreateGlobalGenerator(value.c_str());
+ this->CreateGlobalGenerator(value);
if(!gen)
{
cmSystemTools::Error("Could not create named generator ",
value.c_str());
+ this->PrintGeneratorList();
}
else
{
@@ -3947,7 +2418,7 @@ int cmake::GetSystemInformation(std::vector<std::string>& args)
// we have to find the module directory, so we can copy the files
this->AddCMakePaths();
std::string modulesPath =
- this->CacheManager->GetCacheValue("CMAKE_ROOT");
+ this->State->GetInitializedCacheValue("CMAKE_ROOT");
modulesPath += "/Modules";
std::string inFile = modulesPath;
inFile += "/SystemInformation.cmake";
@@ -3957,20 +2428,20 @@ int cmake::GetSystemInformation(std::vector<std::string>& args)
// Copy file
if(!cmSystemTools::cmCopyFile(inFile.c_str(), outFile.c_str()))
{
- std::cerr << "Error copying file \"" << inFile.c_str()
- << "\" to \"" << outFile.c_str() << "\".\n";
+ std::cerr << "Error copying file \"" << inFile
+ << "\" to \"" << outFile << "\".\n";
return 1;
}
// do we write to a file or to stdout?
- if (resultFile.size() == 0)
+ if (resultFile.empty())
{
resultFile = cwd;
resultFile += "/__cmake_systeminformation/results.txt";
}
// now run cmake on the CMakeLists file
- cmSystemTools::ChangeDirectory(destPath.c_str());
+ cmSystemTools::ChangeDirectory(destPath);
std::vector<std::string> args2;
args2.push_back(args[0]);
args2.push_back(destPath);
@@ -3986,12 +2457,12 @@ int cmake::GetSystemInformation(std::vector<std::string>& args)
}
// change back to the original directory
- cmSystemTools::ChangeDirectory(cwd.c_str());
+ cmSystemTools::ChangeDirectory(cwd);
// echo results to stdout if needed
if (writeToStdout)
{
- FILE* fin = fopen(resultFile.c_str(), "r");
+ FILE* fin = cmsys::SystemTools::Fopen(resultFile, "r");
if(fin)
{
const int bufferSize = 4096;
@@ -4010,7 +2481,7 @@ int cmake::GetSystemInformation(std::vector<std::string>& args)
}
// clean up the directory
- cmSystemTools::RemoveADirectory(destPath.c_str());
+ cmSystemTools::RemoveADirectory(destPath);
return 0;
}
@@ -4025,9 +2496,9 @@ static bool cmakeCheckStampFile(const char* stampName)
std::string stampDepends = stampName;
stampDepends += ".depend";
#if defined(_WIN32) || defined(__CYGWIN__)
- std::ifstream fin(stampDepends.c_str(), std::ios::in | std::ios::binary);
+ cmsys::ifstream fin(stampDepends.c_str(), std::ios::in | std::ios::binary);
#else
- std::ifstream fin(stampDepends.c_str(), std::ios::in);
+ cmsys::ifstream fin(stampDepends.c_str(), std::ios::in);
#endif
if(!fin)
{
@@ -4044,7 +2515,7 @@ static bool cmakeCheckStampFile(const char* stampName)
while(cmSystemTools::GetLineFromStream(fin, dep))
{
int result;
- if(dep.length() >= 1 && dep[0] != '#' &&
+ if(!dep.empty() && dep[0] != '#' &&
(!ftc.FileTimeCompare(stampDepends.c_str(), dep.c_str(), &result)
|| result < 0))
{
@@ -4061,14 +2532,14 @@ static bool cmakeCheckStampFile(const char* stampName)
// The build system is up to date. The stamp file has been removed
// by the VS IDE due to a "rebuild" request. Restore it atomically.
- cmOStringStream stampTempStream;
+ std::ostringstream stampTempStream;
stampTempStream << stampName << ".tmp" << cmSystemTools::RandomSeed();
std::string stampTempString = stampTempStream.str();
const char* stampTemp = stampTempString.c_str();
{
// TODO: Teach cmGeneratedFileStream to use a random temp file (with
// multiple tries in unlikely case of conflict) and use that here.
- std::ofstream stamp(stampTemp);
+ cmsys::ofstream stamp(stampTemp);
stamp << "# CMake generation timestamp file for this directory.\n";
}
if(cmSystemTools::RenameFile(stampTemp, stampName))
@@ -4098,7 +2569,7 @@ static bool cmakeCheckStampList(const char* stampList)
<< "is missing.\n";
return false;
}
- std::ifstream fin(stampList);
+ cmsys::ifstream fin(stampList);
if(!fin)
{
std::cout << "CMake is re-running because generate.stamp.list "
@@ -4118,467 +2589,265 @@ static bool cmakeCheckStampList(const char* stampList)
return true;
}
-//----------------------------------------------------------------------------
-int cmake::WindowsCEEnvironment(const char* version, const std::string& name)
+cmake::MessageType cmake::ConvertMessageType(cmake::MessageType t)
{
-#if defined(CMAKE_HAVE_VS_GENERATORS)
- cmVisualStudioWCEPlatformParser parser(name.c_str());
- parser.ParseVersion(version);
- if (parser.Found())
- {
- std::cout << "@echo off" << std::endl;
- std::cout << "echo Environment Selection: " << name << std::endl;
- std::cout << "set PATH=" << parser.GetPathDirectories() << std::endl;
- std::cout << "set INCLUDE=" << parser.GetIncludeDirectories() <<std::endl;
- std::cout << "set LIB=" << parser.GetLibraryDirectories() <<std::endl;
- return 0;
- }
-#else
- (void)version;
-#endif
-
- std::cerr << "Could not find " << name;
- return -1;
-}
+ bool warningsAsErrors;
-// For visual studio 2005 and newer manifest files need to be embedded into
-// exe and dll's. This code does that in such a way that incremental linking
-// still works.
-int cmake::VisualStudioLink(std::vector<std::string>& args, int type)
-{
- if(args.size() < 2)
+ if (t == cmake::AUTHOR_WARNING || t == cmake::AUTHOR_ERROR)
{
- return -1;
- }
- bool verbose = false;
- if(cmSystemTools::GetEnv("VERBOSE"))
- {
- verbose = true;
- }
- std::vector<std::string> expandedArgs;
- for(std::vector<std::string>::iterator i = args.begin();
- i != args.end(); ++i)
- {
- // check for nmake temporary files
- if((*i)[0] == '@' && i->find("@CMakeFiles") != 0 )
+ warningsAsErrors = this->GetDevWarningsAsErrors();
+ if (warningsAsErrors && t == cmake::AUTHOR_WARNING)
{
- std::ifstream fin(i->substr(1).c_str());
- std::string line;
- while(cmSystemTools::GetLineFromStream(fin,
- line))
- {
- cmSystemTools::ParseWindowsCommandLine(line.c_str(), expandedArgs);
- }
+ t = cmake::AUTHOR_ERROR;
}
- else
+ else if (!warningsAsErrors && t == cmake::AUTHOR_ERROR)
{
- expandedArgs.push_back(*i);
+ t = cmake::AUTHOR_WARNING;
}
}
- bool hasIncremental = false;
- bool hasManifest = true;
- for(std::vector<std::string>::iterator i = expandedArgs.begin();
- i != expandedArgs.end(); ++i)
+ else if (t == cmake::DEPRECATION_WARNING || t == cmake::DEPRECATION_ERROR)
{
- if(cmSystemTools::Strucmp(i->c_str(), "/INCREMENTAL:YES") == 0)
- {
- hasIncremental = true;
- }
- if(cmSystemTools::Strucmp(i->c_str(), "/INCREMENTAL") == 0)
+ warningsAsErrors = this->GetDeprecatedWarningsAsErrors();
+ if (warningsAsErrors && t == cmake::DEPRECATION_WARNING)
{
- hasIncremental = true;
+ t = cmake::DEPRECATION_ERROR;
}
- if(cmSystemTools::Strucmp(i->c_str(), "/MANIFEST:NO") == 0)
+ else if (!warningsAsErrors && t == cmake::DEPRECATION_ERROR)
{
- hasManifest = false;
+ t = cmake::DEPRECATION_WARNING;
}
}
- if(hasIncremental && hasManifest)
+
+ return t;
+}
+
+bool cmake::IsMessageTypeVisible(cmake::MessageType t)
+{
+ bool isVisible = true;
+
+ if(t == cmake::DEPRECATION_ERROR)
{
- if(verbose)
+ if(!this->GetDeprecatedWarningsAsErrors())
{
- std::cout << "Visual Studio Incremental Link with embedded manifests\n";
+ isVisible = false;
}
- return cmake::VisualStudioLinkIncremental(expandedArgs, type, verbose);
}
- if(verbose)
+ else if (t == cmake::DEPRECATION_WARNING)
{
- if(!hasIncremental)
- {
- std::cout << "Visual Studio Non-Incremental Link\n";
- }
- else
+ if (this->GetSuppressDeprecatedWarnings())
{
- std::cout << "Visual Studio Incremental Link without manifests\n";
+ isVisible = false;
}
}
- return cmake::VisualStudioLinkNonIncremental(expandedArgs,
- type, hasManifest, verbose);
-}
-
-int cmake::ParseVisualStudioLinkCommand(std::vector<std::string>& args,
- std::vector<cmStdString>& command,
- std::string& targetName)
-{
- std::vector<std::string>::iterator i = args.begin();
- i++; // skip -E
- i++; // skip vs_link_dll or vs_link_exe
- command.push_back(*i);
- i++; // move past link command
- for(; i != args.end(); ++i)
- {
- command.push_back(*i);
- if(i->find("/Fe") == 0)
- {
- targetName = i->substr(3);
- }
- if(i->find("/out:") == 0)
+ else if (t == cmake::AUTHOR_ERROR)
+ {
+ if (!this->GetDevWarningsAsErrors())
{
- targetName = i->substr(5);
+ isVisible = false;
}
}
- if(targetName.size() == 0 || command.size() == 0)
- {
- return -1;
- }
- return 0;
-}
-
-bool cmake::RunCommand(const char* comment,
- std::vector<cmStdString>& command,
- bool verbose,
- int* retCodeOut)
-{
- if(verbose)
+ else if (t == cmake::AUTHOR_WARNING)
{
- std::cout << comment << ":\n";
- for(std::vector<cmStdString>::iterator i = command.begin();
- i != command.end(); ++i)
+ if (this->GetSuppressDevWarnings())
{
- std::cout << i->c_str() << " ";
+ isVisible = false;
}
- std::cout << "\n";
}
- std::string output;
- int retCode =0;
- // use rc command to create .res file
- cmSystemTools::RunSingleCommand(command,
- &output,
- &retCode, 0, cmSystemTools::OUTPUT_NONE);
- // always print the output of the command, unless
- // it is the dumb rc command banner, but if the command
- // returned an error code then print the output anyway as
- // the banner may be mixed with some other important information.
- if(output.find("Resource Compiler Version") == output.npos
- || retCode !=0)
- {
- std::cout << output;
- }
- // if retCodeOut is requested then always return true
- // and set the retCodeOut to retCode
- if(retCodeOut)
- {
- *retCodeOut = retCode;
- return true;
- }
- if(retCode != 0)
- {
- std::cout << comment << " failed. with " << retCode << "\n";
- }
- return retCode == 0;
+
+ return isVisible;
}
-int cmake::VisualStudioLinkIncremental(std::vector<std::string>& args,
- int type, bool verbose)
+bool cmake::PrintMessagePreamble(cmake::MessageType t, std::ostream& msg)
{
- // This follows the steps listed here:
- // http://blogs.msdn.com/zakramer/archive/2006/05/22/603558.aspx
-
- // 1. Compiler compiles the application and generates the *.obj files.
- // 2. An empty manifest file is generated if this is a clean build and if
- // not the previous one is reused.
- // 3. The resource compiler (rc.exe) compiles the *.manifest file to a
- // *.res file.
- // 4. Linker generates the binary (EXE or DLL) with the /incremental
- // switch and embeds the dummy manifest file. The linker also generates
- // the real manifest file based on the binaries that your binary depends
- // on.
- // 5. The manifest tool (mt.exe) is then used to generate the final
- // manifest.
-
- // If the final manifest is changed, then 6 and 7 are run, if not
- // they are skipped, and it is done.
-
- // 6. The resource compiler is invoked one more time.
- // 7. Finally, the Linker does another incremental link, but since the
- // only thing that has changed is the *.res file that contains the
- // manifest it is a short link.
- std::vector<cmStdString> linkCommand;
- std::string targetName;
- if(cmake::ParseVisualStudioLinkCommand(args, linkCommand, targetName) == -1)
- {
- return -1;
- }
- std::string manifestArg = "/MANIFESTFILE:";
- std::vector<cmStdString> rcCommand;
- rcCommand.push_back(cmSystemTools::FindProgram("rc.exe"));
- std::vector<cmStdString> mtCommand;
- mtCommand.push_back(cmSystemTools::FindProgram("mt.exe"));
- std::string tempManifest;
- tempManifest = targetName;
- tempManifest += ".intermediate.manifest";
- std::string resourceInputFile = targetName;
- resourceInputFile += ".resource.txt";
- if(verbose)
+ // Construct the message header.
+ if(t == cmake::FATAL_ERROR)
{
- std::cout << "Create " << resourceInputFile.c_str() << "\n";
+ msg << "CMake Error";
}
- // Create input file for rc command
- std::ofstream fout(resourceInputFile.c_str());
- if(!fout)
+ else if(t == cmake::INTERNAL_ERROR)
{
- return -1;
+ msg << "CMake Internal Error (please report a bug)";
}
- std::string manifestFile = targetName;
- manifestFile += ".embed.manifest";
- std::string fullPath= cmSystemTools::CollapseFullPath(manifestFile.c_str());
- fout << type << " /* CREATEPROCESS_MANIFEST_RESOURCE_ID "
- "*/ 24 /* RT_MANIFEST */ " << "\"" << fullPath.c_str() << "\"";
- fout.close();
- manifestArg += tempManifest;
- // add the manifest arg to the linkCommand
- linkCommand.push_back("/MANIFEST");
- linkCommand.push_back(manifestArg);
- // if manifestFile is not yet created, create an
- // empty one
- if(!cmSystemTools::FileExists(manifestFile.c_str()))
- {
- if(verbose)
- {
- std::cout << "Create empty: " << manifestFile.c_str() << "\n";
- }
- std::ofstream foutTmp(manifestFile.c_str());
- }
- std::string resourceFile = manifestFile;
- resourceFile += ".res";
- // add the resource file to the end of the link command
- linkCommand.push_back(resourceFile);
- std::string outputOpt = "/fo";
- outputOpt += resourceFile;
- rcCommand.push_back(outputOpt);
- rcCommand.push_back(resourceInputFile);
- // Run rc command to create resource
- if(!cmake::RunCommand("RC Pass 1", rcCommand, verbose))
+ else if(t == cmake::LOG)
{
- return -1;
+ msg << "CMake Debug Log";
}
- // Now run the link command to link and create manifest
- if(!cmake::RunCommand("LINK Pass 1", linkCommand, verbose))
+ else if(t == cmake::DEPRECATION_ERROR)
{
- return -1;
+ msg << "CMake Deprecation Error";
}
- // create mt command
- std::string outArg("/out:");
- outArg+= manifestFile;
- mtCommand.push_back("/nologo");
- mtCommand.push_back(outArg);
- mtCommand.push_back("/notify_update");
- mtCommand.push_back("/manifest");
- mtCommand.push_back(tempManifest);
- // now run mt.exe to create the final manifest file
- int mtRet =0;
- cmake::RunCommand("MT", mtCommand, verbose, &mtRet);
- // if mt returns 0, then the manifest was not changed and
- // we do not need to do another link step
- if(mtRet == 0)
+ else if (t == cmake::DEPRECATION_WARNING)
{
- return 0;
+ msg << "CMake Deprecation Warning";
}
- // check for magic mt return value if mt returns the magic number
- // 1090650113 then it means that it updated the manifest file and we need
- // to do the final link. If mt has any value other than 0 or 1090650113
- // then there was some problem with the command itself and there was an
- // error so return the error code back out of cmake so make can report it.
- if(mtRet != 1090650113)
+ else if (t == cmake::AUTHOR_WARNING)
{
- return mtRet;
+ msg << "CMake Warning (dev)";
}
- // update the resource file with the new manifest from the mt command.
- if(!cmake::RunCommand("RC Pass 2", rcCommand, verbose))
+ else if (t == cmake::AUTHOR_ERROR)
{
- return -1;
+ msg << "CMake Error (dev)";
}
- // Run the final incremental link that will put the new manifest resource
- // into the file incrementally.
- if(!cmake::RunCommand("FINAL LINK", linkCommand, verbose))
+ else
{
- return -1;
+ msg << "CMake Warning";
}
- return 0;
+ return true;
}
-int cmake::VisualStudioLinkNonIncremental(std::vector<std::string>& args,
- int type,
- bool hasManifest,
- bool verbose)
+void printMessageText(std::ostream& msg, std::string const& text)
{
- std::vector<cmStdString> linkCommand;
- std::string targetName;
- if(cmake::ParseVisualStudioLinkCommand(args, linkCommand, targetName) == -1)
- {
- return -1;
- }
- // Run the link command as given
- if (hasManifest)
- {
- linkCommand.push_back("/MANIFEST");
- }
- if(!cmake::RunCommand("LINK", linkCommand, verbose))
+ msg << ":\n";
+ cmDocumentationFormatter formatter;
+ formatter.SetIndent(" ");
+ formatter.PrintFormatted(msg, text.c_str());
+}
+
+void displayMessage(cmake::MessageType t, std::ostringstream& msg)
+{
+
+ // Add a note about warning suppression.
+ if(t == cmake::AUTHOR_WARNING)
{
- return -1;
+ msg <<
+ "This warning is for project developers. Use -Wno-dev to suppress it.";
}
- if(!hasManifest)
+ else if (t == cmake::AUTHOR_ERROR)
{
- return 0;
+ msg <<
+ "This error is for project developers. Use -Wno-error=dev to suppress "
+ "it.";
}
- std::vector<cmStdString> mtCommand;
- mtCommand.push_back(cmSystemTools::FindProgram("mt.exe"));
- mtCommand.push_back("/nologo");
- mtCommand.push_back("/manifest");
- std::string manifestFile = targetName;
- manifestFile += ".manifest";
- mtCommand.push_back(manifestFile);
- std::string outresource = "/outputresource:";
- outresource += targetName;
- outresource += ";#";
- if(type == 1)
+
+ // Add a terminating blank line.
+ msg << "\n";
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ // Add a C++ stack trace to internal errors.
+ if(t == cmake::INTERNAL_ERROR)
{
- outresource += "1";
+ std::string stack = cmsys::SystemInformation::GetProgramStack(0,0);
+ if(!stack.empty())
+ {
+ if(cmHasLiteralPrefix(stack, "WARNING:"))
+ {
+ stack = "Note:" + stack.substr(8);
+ }
+ msg << stack << "\n";
+ }
}
- else if(type == 2)
+#endif
+
+ // Output the message.
+ if(t == cmake::FATAL_ERROR
+ || t == cmake::INTERNAL_ERROR
+ || t == cmake::DEPRECATION_ERROR
+ || t == cmake::AUTHOR_ERROR)
{
- outresource += "2";
+ cmSystemTools::SetErrorOccured();
+ cmSystemTools::Message(msg.str().c_str(), "Error");
}
- mtCommand.push_back(outresource);
- // Now use the mt tool to embed the manifest into the exe or dll
- if(!cmake::RunCommand("MT", mtCommand, verbose))
+ else
{
- return -1;
+ cmSystemTools::Message(msg.str().c_str(), "Warning");
}
- return 0;
}
//----------------------------------------------------------------------------
void cmake::IssueMessage(cmake::MessageType t, std::string const& text,
- cmListFileBacktrace const& backtrace)
+ cmListFileBacktrace const& bt,
+ bool force)
{
- cmOStringStream msg;
- bool isError = false;
- // Construct the message header.
- if(t == cmake::FATAL_ERROR)
- {
- isError = true;
- msg << "CMake Error";
- }
- else if(t == cmake::INTERNAL_ERROR)
+ cmListFileBacktrace backtrace = bt;
+
+ if (!force)
{
- isError = true;
- msg << "CMake Internal Error (please report a bug)";
+ // override the message type, if needed, for warnings and errors
+ cmake::MessageType override = this->ConvertMessageType(t);
+ if (override != t)
+ {
+ t = override;
+ force = true;
+ }
}
- else if(t == cmake::LOG)
+
+ if (!force && !this->IsMessageTypeVisible(t))
{
- msg << "CMake Debug Log";
+ return;
}
- else
+
+ std::ostringstream msg;
+ if (!this->PrintMessagePreamble(t, msg))
{
- msg << "CMake Warning";
- if(t == cmake::AUTHOR_WARNING)
- {
- // Allow suppression of these warnings.
- cmCacheManager::CacheIterator it = this->CacheManager
- ->GetCacheIterator("CMAKE_SUPPRESS_DEVELOPER_WARNINGS");
- if(!it.IsAtEnd() && it.GetValueAsBool())
- {
- return;
- }
- msg << " (dev)";
- }
+ return;
}
// Add the immediate context.
- cmListFileBacktrace::const_iterator i = backtrace.begin();
- if(i != backtrace.end())
- {
- cmListFileContext const& lfc = *i;
- msg << (lfc.Line? " at ": " in ") << lfc;
- ++i;
- }
+ backtrace.PrintTitle(msg);
- // Add the message text.
- {
- msg << ":\n";
- cmDocumentationFormatterText formatter;
- formatter.SetIndent(" ");
- formatter.PrintFormatted(msg, text.c_str());
- }
+ printMessageText(msg, text);
// Add the rest of the context.
- if(i != backtrace.end())
+ backtrace.PrintCallStack(msg);
+
+ displayMessage(t, msg);
+}
+
+//----------------------------------------------------------------------------
+void cmake::IssueMessage(cmake::MessageType t, std::string const& text,
+ cmListFileContext const& lfc,
+ bool force)
+{
+ if (!force)
{
- msg << "Call Stack (most recent call first):\n";
- while(i != backtrace.end())
+ // override the message type, if needed, for warnings and errors
+ cmake::MessageType override = this->ConvertMessageType(t);
+ if (override != t)
{
- cmListFileContext const& lfc = *i;
- msg << " " << lfc << "\n";
- ++i;
+ t = override;
+ force = true;
}
}
- // Add a note about warning suppression.
- if(t == cmake::AUTHOR_WARNING)
+ if (!force && !this->IsMessageTypeVisible(t))
{
- msg <<
- "This warning is for project developers. Use -Wno-dev to suppress it.";
+ return;
}
- // Add a terminating blank line.
- msg << "\n";
-
- // Output the message.
- if(isError)
+ std::ostringstream msg;
+ if (!this->PrintMessagePreamble(t, msg))
{
- cmSystemTools::SetErrorOccured();
- cmSystemTools::Message(msg.str().c_str(), "Error");
- }
- else
- {
- cmSystemTools::Message(msg.str().c_str(), "Warning");
+ return;
}
+
+ // Add the immediate context.
+ msg << (lfc.Line ? " at " : " in ") << lfc;
+
+ printMessageText(msg, text);
+
+ displayMessage(t, msg);
}
//----------------------------------------------------------------------------
-std::vector<std::string> const& cmake::GetDebugConfigs()
+std::vector<std::string> cmake::GetDebugConfigs()
{
- // Compute on-demand.
- if(this->DebugConfigs.empty())
+ std::vector<std::string> configs;
+ if(const char* config_list =
+ this->State->GetGlobalProperty("DEBUG_CONFIGURATIONS"))
{
- if(const char* config_list = this->GetProperty("DEBUG_CONFIGURATIONS"))
- {
- // Expand the specified list and convert to upper-case.
- cmSystemTools::ExpandListArgument(config_list, this->DebugConfigs);
- for(std::vector<std::string>::iterator i = this->DebugConfigs.begin();
- i != this->DebugConfigs.end(); ++i)
- {
- *i = cmSystemTools::UpperCase(*i);
- }
- }
- // If no configurations were specified, use a default list.
- if(this->DebugConfigs.empty())
- {
- this->DebugConfigs.push_back("DEBUG");
- }
+ // Expand the specified list and convert to upper-case.
+ cmSystemTools::ExpandListArgument(config_list, configs);
+ std::transform(configs.begin(),
+ configs.end(),
+ configs.begin(),
+ cmSystemTools::UpperCase);
}
- return this->DebugConfigs;
+ // If no configurations were specified, use a default list.
+ if(configs.empty())
+ {
+ configs.push_back("DEBUG");
+ }
+ return configs;
}
@@ -4586,54 +2855,84 @@ int cmake::Build(const std::string& dir,
const std::string& target,
const std::string& config,
const std::vector<std::string>& nativeOptions,
- bool clean,
- cmSystemTools::OutputOption outputflag)
+ bool clean)
{
- if(!cmSystemTools::FileIsDirectory(dir.c_str()))
+
+ this->SetHomeDirectory("");
+ this->SetHomeOutputDirectory("");
+ if(!cmSystemTools::FileIsDirectory(dir))
{
std::cerr << "Error: " << dir << " is not a directory\n";
return 1;
}
std::string cachePath = dir;
cmSystemTools::ConvertToUnixSlashes(cachePath);
- cmCacheManager* cachem = this->GetCacheManager();
- cmCacheManager::CacheIterator it = cachem->NewIterator();
- if(!cachem->LoadCache(cachePath.c_str()))
+ std::string cacheFile = cachePath;
+ cacheFile += "/CMakeCache.txt";
+ if(!cmSystemTools::FileExists(cacheFile.c_str()))
+ {
+ // search in parent directories for cache
+ std::string cmakeFiles = cachePath;
+ cmakeFiles += "/CMakeFiles";
+ if(cmSystemTools::FileExists(cmakeFiles.c_str()))
+ {
+ std::string cachePathFound =
+ cmSystemTools::FileExistsInParentDirectories(
+ "CMakeCache.txt", cachePath.c_str(), "/");
+ if(!cachePathFound.empty())
+ {
+ cachePath = cmSystemTools::GetFilenamePath(cachePathFound);
+ }
+ }
+ }
+
+ if(!this->LoadCache(cachePath))
{
std::cerr << "Error: could not load cache\n";
return 1;
}
- if(!it.Find("CMAKE_GENERATOR"))
+ const char* cachedGenerator =
+ this->State->GetCacheEntryValue("CMAKE_GENERATOR");
+ if(!cachedGenerator)
{
- std::cerr << "Error: could find generator in Cache\n";
+ std::cerr << "Error: could not find CMAKE_GENERATOR in Cache\n";
return 1;
}
cmsys::auto_ptr<cmGlobalGenerator> gen(
- this->CreateGlobalGenerator(it.GetValue()));
+ this->CreateGlobalGenerator(cachedGenerator));
+ if(!gen.get())
+ {
+ std::cerr << "Error: could create CMAKE_GENERATOR \""
+ << cachedGenerator << "\"\n";
+ return 1;
+ }
std::string output;
std::string projName;
- std::string makeProgram;
- if(!it.Find("CMAKE_PROJECT_NAME"))
+ const char* cachedProjectName =
+ this->State->GetCacheEntryValue("CMAKE_PROJECT_NAME");
+ if(!cachedProjectName)
{
std::cerr << "Error: could not find CMAKE_PROJECT_NAME in Cache\n";
return 1;
}
- projName = it.GetValue();
- if(!it.Find("CMAKE_MAKE_PROGRAM"))
+ projName = cachedProjectName;
+ bool verbose = false;
+ const char* cachedVerbose =
+ this->State->GetCacheEntryValue("CMAKE_VERBOSE_MAKEFILE");
+ if(cachedVerbose)
{
- std::cerr << "Error: could not find CMAKE_MAKE_PROGRAM in Cache\n";
- return 1;
+ verbose = cmSystemTools::IsOn(cachedVerbose);
}
- makeProgram = it.GetValue();
- return gen->Build(0, dir.c_str(),
- projName.c_str(), target.c_str(),
- &output,
- makeProgram.c_str(),
- config.c_str(), clean, false, 0, outputflag,
- 0, nativeOptions);
+ return gen->Build("", dir,
+ projName, target,
+ output,
+ "",
+ config, clean, false, verbose, 0,
+ cmSystemTools::OUTPUT_PASSTHROUGH,
+ nativeOptions);
}
-void cmake::WatchUnusedCli(const char* var)
+void cmake::WatchUnusedCli(const std::string& var)
{
#ifdef CMAKE_BUILD_WITH_CMAKE
this->VariableWatch->AddWatch(var, cmWarnUnusedCliWarning, this);
@@ -4644,7 +2943,7 @@ void cmake::WatchUnusedCli(const char* var)
#endif
}
-void cmake::UnwatchUnusedCli(const char* var)
+void cmake::UnwatchUnusedCli(const std::string& var)
{
#ifdef CMAKE_BUILD_WITH_CMAKE
this->VariableWatch->RemoveWatch(var, cmWarnUnusedCliWarning);
@@ -4656,9 +2955,9 @@ void cmake::RunCheckForUnusedVariables()
{
#ifdef CMAKE_BUILD_WITH_CMAKE
bool haveUnused = false;
- cmOStringStream msg;
+ std::ostringstream msg;
msg << "Manually-specified variables were not used by the project:";
- for(std::map<cmStdString, bool>::const_iterator
+ for(std::map<std::string, bool>::const_iterator
it = this->UsedCliVariables.begin();
it != this->UsedCliVariables.end(); ++it)
{
@@ -4670,7 +2969,157 @@ void cmake::RunCheckForUnusedVariables()
}
if(haveUnused)
{
- this->IssueMessage(cmake::WARNING, msg.str(), cmListFileBacktrace());
+ this->IssueMessage(cmake::WARNING, msg.str());
}
#endif
}
+
+bool cmake::GetSuppressDevWarnings(cmMakefile const* mf)
+{
+ /*
+ * The suppression CMake variable may be set in the CMake configuration file
+ * itself, so we have to check what its set to in the makefile if we can.
+ */
+ if (mf)
+ {
+ return mf->IsOn("CMAKE_SUPPRESS_DEVELOPER_WARNINGS");
+ }
+ else
+ {
+ const char* cacheEntryValue = this->State->GetCacheEntryValue(
+ "CMAKE_SUPPRESS_DEVELOPER_WARNINGS");
+ return cmSystemTools::IsOn(cacheEntryValue);
+ }
+}
+
+void cmake::SetSuppressDevWarnings(bool b)
+{
+ std::string value;
+
+ // equivalent to -Wno-dev
+ if (b)
+ {
+ value = "TRUE";
+ }
+ // equivalent to -Wdev
+ else
+ {
+ value = "FALSE";
+ }
+
+ this->AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS", value.c_str(),
+ "Suppress Warnings that are meant for"
+ " the author of the CMakeLists.txt files.",
+ cmState::INTERNAL);
+}
+
+bool cmake::GetSuppressDeprecatedWarnings(cmMakefile const* mf)
+{
+ /*
+ * The suppression CMake variable may be set in the CMake configuration file
+ * itself, so we have to check what its set to in the makefile if we can.
+ */
+ if (mf)
+ {
+ return (mf->IsSet("CMAKE_WARN_DEPRECATED") &&
+ !mf->IsOn("CMAKE_WARN_DEPRECATED"));
+ }
+ else
+ {
+ const char* cacheEntryValue = this->State->GetCacheEntryValue(
+ "CMAKE_WARN_DEPRECATED");
+ return cacheEntryValue && cmSystemTools::IsOff(cacheEntryValue);
+ }
+}
+
+void cmake::SetSuppressDeprecatedWarnings(bool b)
+{
+ std::string value;
+
+ // equivalent to -Wno-deprecated
+ if (b)
+ {
+ value = "FALSE";
+ }
+ // equivalent to -Wdeprecated
+ else
+ {
+ value = "TRUE";
+ }
+
+ this->AddCacheEntry("CMAKE_WARN_DEPRECATED", value.c_str(),
+ "Whether to issue warnings for deprecated "
+ "functionality.",
+ cmState::INTERNAL);
+}
+
+bool cmake::GetDevWarningsAsErrors(cmMakefile const* mf)
+{
+ if (mf)
+ {
+ return (mf->IsSet("CMAKE_SUPPRESS_DEVELOPER_ERRORS") &&
+ !mf->IsOn("CMAKE_SUPPRESS_DEVELOPER_ERRORS"));
+ }
+ else
+ {
+ const char* cacheEntryValue = this->State->GetCacheEntryValue(
+ "CMAKE_SUPPRESS_DEVELOPER_ERRORS");
+ return cacheEntryValue && cmSystemTools::IsOff(cacheEntryValue);
+ }
+}
+
+void cmake::SetDevWarningsAsErrors(bool b)
+{
+ std::string value;
+
+ // equivalent to -Werror=dev
+ if (b)
+ {
+ value = "FALSE";
+ }
+ // equivalent to -Wno-error=dev
+ else
+ {
+ value = "TRUE";
+ }
+
+ this->AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_ERRORS", value.c_str(),
+ "Suppress errors that are meant for"
+ " the author of the CMakeLists.txt files.",
+ cmState::INTERNAL);
+}
+
+bool cmake::GetDeprecatedWarningsAsErrors(cmMakefile const* mf)
+{
+ if (mf)
+ {
+ return mf->IsOn("CMAKE_ERROR_DEPRECATED");
+ }
+ else
+ {
+ const char* cacheEntryValue = this->State->GetCacheEntryValue(
+ "CMAKE_ERROR_DEPRECATED");
+ return cmSystemTools::IsOn(cacheEntryValue);
+ }
+}
+
+void cmake::SetDeprecatedWarningsAsErrors(bool b)
+{
+ std::string value;
+
+ // equivalent to -Werror=deprecated
+ if (b)
+ {
+ value = "TRUE";
+ }
+ // equivalent to -Wno-error=deprecated
+ else
+ {
+ value = "FALSE";
+ }
+
+ this->AddCacheEntry("CMAKE_ERROR_DEPRECATED", value.c_str(),
+ "Whether to issue deprecation errors for macros"
+ " and functions.",
+ cmState::INTERNAL);
+}
diff --git a/Source/cmake.h b/Source/cmake.h
index a50c1ed02..84967056a 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -13,22 +13,20 @@
#ifndef cmake_h
#define cmake_h
+#include "cmListFileCache.h"
#include "cmSystemTools.h"
-#include "cmPropertyDefinitionMap.h"
-#include "cmPropertyMap.h"
+#include "cmInstalledFile.h"
+#include "cmCacheManager.h"
+#include "cmState.h"
class cmGlobalGeneratorFactory;
class cmGlobalGenerator;
class cmLocalGenerator;
-class cmCacheManager;
class cmMakefile;
-class cmCommand;
class cmVariableWatch;
class cmFileTimeComparison;
class cmExternalMakefileProjectGenerator;
class cmDocumentationSection;
-class cmPolicies;
-class cmListFileBacktrace;
class cmTarget;
class cmGeneratedFileStream;
@@ -41,7 +39,7 @@ class cmGeneratedFileStream;
* The basic process for a GUI is as follows:
*
* -# Create a cmake instance
- * -# Set the Home & Start directories, generator, and cmake command. this
+ * -# Set the Home directories, generator, and cmake command. this
* can be done using the Set methods or by using SetArgs and passing in
* command line arguments.
* -# Load the cache by calling LoadCache (duh)
@@ -52,7 +50,7 @@ class cmGeneratedFileStream;
* -# Let the user change values and go back to step 5
* -# call Generate
- * If your GUI allows the user to change the start & home directories then
+ * If your GUI allows the user to change the home directories then
* you must at a minimum redo steps 2 through 7.
*/
@@ -61,13 +59,22 @@ class cmake
public:
enum MessageType
{ AUTHOR_WARNING,
+ AUTHOR_ERROR,
FATAL_ERROR,
INTERNAL_ERROR,
MESSAGE,
WARNING,
- LOG
+ LOG,
+ DEPRECATION_ERROR,
+ DEPRECATION_WARNING
};
+ enum DiagLevel
+ {
+ DIAG_IGNORE,
+ DIAG_WARN,
+ DIAG_ERROR
+ };
/** \brief Describes the working modes of cmake */
enum WorkingMode
@@ -89,63 +96,34 @@ class cmake
*/
FIND_PACKAGE_MODE
};
- typedef std::map<cmStdString, cmCommand*> RegisteredCommandsMap;
+
+ struct GeneratorInfo
+ {
+ std::string name;
+ bool supportsToolset;
+ };
+
+ typedef std::map<std::string, cmInstalledFile> InstalledFilesMap;
/// Default constructor
cmake();
/// Destructor
~cmake();
- static const char *GetCMakeFilesDirectory() {return "/CMakeFiles";};
+ static const char *GetCMakeFilesDirectory() {return "/CMakeFiles";}
static const char *GetCMakeFilesDirectoryPostSlash() {
- return "CMakeFiles/";};
+ return "CMakeFiles/";}
//@{
/**
* Set/Get the home directory (or output directory) in the project. The
* home directory is the top directory of the project. It is the
- * path-to-source cmake was run with. Remember that CMake processes
- * CMakeLists files by recursing up the tree starting at the StartDirectory
- * and going up until it reaches the HomeDirectory.
- */
- void SetHomeDirectory(const char* dir);
- const char* GetHomeDirectory() const
- {
- return this->cmHomeDirectory.c_str();
- }
- void SetHomeOutputDirectory(const char* lib);
- const char* GetHomeOutputDirectory() const
- {
- return this->HomeOutputDirectory.c_str();
- }
- //@}
-
- //@{
- /**
- * Set/Get the start directory (or output directory). The start directory
- * is the directory of the CMakeLists.txt file that started the current
- * round of processing. Remember that CMake processes CMakeLists files by
- * recursing up the tree starting at the StartDirectory and going up until
- * it reaches the HomeDirectory.
+ * path-to-source cmake was run with.
*/
- void SetStartDirectory(const char* dir)
- {
- this->cmStartDirectory = dir;
- cmSystemTools::ConvertToUnixSlashes(this->cmStartDirectory);
- }
- const char* GetStartDirectory() const
- {
- return this->cmStartDirectory.c_str();
- }
- void SetStartOutputDirectory(const char* lib)
- {
- this->StartOutputDirectory = lib;
- cmSystemTools::ConvertToUnixSlashes(this->StartOutputDirectory);
- }
- const char* GetStartOutputDirectory() const
- {
- return this->StartOutputDirectory.c_str();
- }
+ void SetHomeDirectory(const std::string& dir);
+ const char* GetHomeDirectory() const;
+ void SetHomeOutputDirectory(const std::string& dir);
+ const char* GetHomeOutputDirectory() const;
//@}
/**
@@ -169,11 +147,23 @@ class cmake
int Configure();
int ActualConfigure();
+ ///! Break up a line like VAR:type="value" into var, type and value
+ static bool ParseCacheEntry(const std::string& entry,
+ std::string& var,
+ std::string& value,
+ cmState::CacheEntryType& type);
+
int LoadCache();
+ bool LoadCache(const std::string& path);
+ bool LoadCache(const std::string& path, bool internal,
+ std::set<std::string>& excludes,
+ std::set<std::string>& includes);
+ bool SaveCache(const std::string& path);
+ bool DeleteCache(const std::string& path);
void PreLoadCMakeFiles();
///! Create a GlobalGenerator
- cmGlobalGenerator* CreateGlobalGenerator(const char* name);
+ cmGlobalGenerator* CreateGlobalGenerator(const std::string& name);
///! Return the global generator assigned to this instance of cmake
cmGlobalGenerator* GetGlobalGenerator() { return this->GlobalGenerator; }
@@ -185,7 +175,15 @@ class cmake
void SetGlobalGenerator(cmGlobalGenerator *);
///! Get the names of the current registered generators
- void GetRegisteredGenerators(std::vector<std::string>& names);
+ void GetRegisteredGenerators(std::vector<GeneratorInfo>& generators);
+
+ ///! Set the name of the selected generator-specific platform.
+ void SetGeneratorPlatform(std::string const& ts)
+ { this->GeneratorPlatform = ts; }
+
+ ///! Get the name of the selected generator-specific platform.
+ std::string const& GetGeneratorPlatform() const
+ { return this->GeneratorPlatform; }
///! Set the name of the selected generator-specific toolset.
void SetGeneratorToolset(std::string const& ts)
@@ -198,56 +196,32 @@ class cmake
///! get the cmCachemManager used by this invocation of cmake
cmCacheManager *GetCacheManager() { return this->CacheManager; }
- ///! set the cmake command this instance of cmake should use
- void SetCMakeCommand(const char* cmd) { this->CMakeCommand = cmd; }
+ const std::vector<std::string>& GetSourceExtensions() const
+ {return this->SourceFileExtensions;}
+ const std::vector<std::string>& GetHeaderExtensions() const
+ {return this->HeaderFileExtensions;}
/**
* Given a variable name, return its value (as a string).
*/
- const char* GetCacheDefinition(const char*) const;
+ const char* GetCacheDefinition(const std::string&) const;
///! Add an entry into the cache
- void AddCacheEntry(const char* key, const char* value,
+ void AddCacheEntry(const std::string& key, const char* value,
const char* helpString,
int type);
- /**
- * Execute commands during the build process. Supports options such
- * as echo, remove file etc.
- */
- static int ExecuteCMakeCommand(std::vector<std::string>&);
/**
* Get the system information and write it to the file specified
*/
int GetSystemInformation(std::vector<std::string>&);
- /**
- * Add a command to this cmake instance
- */
- void AddCommand(cmCommand* );
- void RenameCommand(const char* oldName, const char* newName);
- void RemoveCommand(const char* name);
- void RemoveUnscriptableCommands();
-
- /**
- * Get a command by its name
- */
- cmCommand *GetCommand(const char *name);
-
- /** Get list of all commands */
- RegisteredCommandsMap* GetCommands() { return &this->Commands; }
-
- /** Check if a command exists. */
- bool CommandExists(const char* name) const;
-
///! Parse command line arguments
void SetArgs(const std::vector<std::string>&,
bool directoriesSetBefore = false);
///! Is this cmake running as a result of a TRY_COMPILE command
- bool GetIsInTryCompile() { return this->InTryCompile; }
-
- ///! Is this cmake running as a result of a TRY_COMPILE command
- void SetIsInTryCompile(bool i) { this->InTryCompile = i; }
+ bool GetIsInTryCompile() const;
+ void SetIsInTryCompile(bool b);
///! Parse command line arguments that might set cache values
bool SetCacheArgs(const std::vector<std::string>&);
@@ -266,36 +240,26 @@ class cmake
///! this is called by generators to update the progress
void UpdateProgress(const char *msg, float prog);
- ///! get the cmake policies instance
- cmPolicies *GetPolicies() {return this->Policies;} ;
-
///! Get the variable watch object
cmVariableWatch* GetVariableWatch() { return this->VariableWatch; }
- /** Get the documentation entries for the supported commands.
- * If withCurrentCommands is true, the documentation for the
- * recommended set of commands is included.
- * If withCompatCommands is true, the documentation for discouraged
- * (compatibility) commands is included.
- * You probably don't want to set both to false.
- */
- void GetCommandDocumentation(std::vector<cmDocumentationEntry>& entries,
- bool withCurrentCommands = true,
- bool withCompatCommands = true) const;
- void GetPropertiesDocumentation(std::map<std::string,
- cmDocumentationSection *>&);
void GetGeneratorDocumentation(std::vector<cmDocumentationEntry>&);
- void GetPolicyDocumentation(std::vector<cmDocumentationEntry>& entries);
///! Set/Get a property of this target file
- void SetProperty(const char *prop, const char *value);
- void AppendProperty(const char *prop, const char *value,bool asString=false);
- const char *GetProperty(const char *prop);
- const char *GetProperty(const char *prop, cmProperty::ScopeType scope);
- bool GetPropertyAsBool(const char *prop);
+ void SetProperty(const std::string& prop, const char *value);
+ void AppendProperty(const std::string& prop,
+ const char *value,bool asString=false);
+ const char *GetProperty(const std::string& prop);
+ bool GetPropertyAsBool(const std::string& prop);
+
+ ///! Get or create an cmInstalledFile instance and return a pointer to it
+ cmInstalledFile *GetOrCreateInstalledFile(
+ cmMakefile* mf, const std::string& name);
+
+ cmInstalledFile const* GetInstalledFile(const std::string& name) const;
- // Get the properties
- cmPropertyMap &GetProperties() { return this->Properties; };
+ InstalledFilesMap const& GetInstalledFiles() const
+ { return this->InstalledFiles; }
///! Do all the checks before running configure
int DoPreConfigureChecks();
@@ -317,13 +281,6 @@ class cmake
*/
cmFileTimeComparison* GetFileComparison() { return this->FileComparison; }
- /**
- * Get the path to ctest
- */
- const char* GetCTestCommand();
- const char* GetCPackCommand();
- const char* GetCMakeCommand();
-
// Do we want debug output during the cmake run.
bool GetDebugOutput() { return this->DebugOutput; }
void SetDebugOutputOn(bool b) { this->DebugOutput = b;}
@@ -331,6 +288,8 @@ class cmake
// Do we want trace output during the cmake run.
bool GetTrace() { return this->Trace;}
void SetTrace(bool b) { this->Trace = b;}
+ bool GetTraceExpand() { return this->TraceExpand;}
+ void SetTraceExpand(bool b) { this->TraceExpand = b;}
bool GetWarnUninitialized() { return this->WarnUninitialized;}
void SetWarnUninitialized(bool b) { this->WarnUninitialized = b;}
bool GetWarnUnused() { return this->WarnUnused;}
@@ -342,90 +301,105 @@ class cmake
void MarkCliAsUsed(const std::string& variable);
- // Define a property
- void DefineProperty(const char *name, cmProperty::ScopeType scope,
- const char *ShortDescription,
- const char *FullDescription,
- bool chain = false,
- const char *variableGroup = 0);
-
- bool GetIsPropertyDefined(const char *name, cmProperty::ScopeType scope);
-
- // get property definition
- cmPropertyDefinition *GetPropertyDefinition
- (const char *name, cmProperty::ScopeType scope);
-
- // Is a property defined?
- bool IsPropertyDefined(const char *name, cmProperty::ScopeType scope);
- bool IsPropertyChained(const char *name, cmProperty::ScopeType scope);
-
/** Get the list of configurations (in upper case) considered to be
debugging configurations.*/
- std::vector<std::string> const& GetDebugConfigs();
+ std::vector<std::string> GetDebugConfigs();
- // record accesses of properties and variables
- void RecordPropertyAccess(const char *name, cmProperty::ScopeType scope);
- void ReportUndefinedPropertyAccesses(const char *filename);
+ void SetCMakeEditCommand(std::string const& s)
+ { this->CMakeEditCommand = s; }
+ std::string const& GetCMakeEditCommand() const
+ { return this->CMakeEditCommand; }
+
+ /*
+ * Get the state of the suppression of developer (author) warnings.
+ * Returns false, by default, if developer warnings should be shown, true
+ * otherwise.
+ */
+ bool GetSuppressDevWarnings(cmMakefile const* mf = NULL);
+ /*
+ * Set the state of the suppression of developer (author) warnings.
+ */
+ void SetSuppressDevWarnings(bool v);
- // Define the properties
- static void DefineProperties(cmake *cm);
+ /*
+ * Get the state of the suppression of deprecated warnings.
+ * Returns false, by default, if deprecated warnings should be shown, true
+ * otherwise.
+ */
+ bool GetSuppressDeprecatedWarnings(cmMakefile const* mf = NULL);
+ /*
+ * Set the state of the suppression of deprecated warnings.
+ */
+ void SetSuppressDeprecatedWarnings(bool v);
- void SetCMakeEditCommand(const char* s)
- {
- this->CMakeEditCommand = s;
- }
- void SetSuppressDevWarnings(bool v)
- {
- this->SuppressDevWarnings = v;
- this->DoSuppressDevWarnings = true;
- }
+ /*
+ * Get the state of treating developer (author) warnings as errors.
+ * Returns false, by default, if warnings should not be treated as errors,
+ * true otherwise.
+ */
+ bool GetDevWarningsAsErrors(cmMakefile const* mf = NULL);
+ /**
+ * Set the state of treating developer (author) warnings as errors.
+ */
+ void SetDevWarningsAsErrors(bool v);
+
+ /*
+ * Get the state of treating deprecated warnings as errors.
+ * Returns false, by default, if warnings should not be treated as errors,
+ * true otherwise.
+ */
+ bool GetDeprecatedWarningsAsErrors(cmMakefile const* mf = NULL);
+ /**
+ * Set the state of treating developer (author) warnings as errors.
+ */
+ void SetDeprecatedWarningsAsErrors(bool v);
/** Display a message to the user. */
void IssueMessage(cmake::MessageType t, std::string const& text,
- cmListFileBacktrace const& backtrace);
+ cmListFileBacktrace const& backtrace = cmListFileBacktrace(),
+ bool force = false);
+ void IssueMessage(cmake::MessageType t, std::string const& text,
+ cmListFileContext const& lfc,
+ bool force = false);
+
///! run the --build option
int Build(const std::string& dir,
const std::string& target,
const std::string& config,
const std::vector<std::string>& nativeOptions,
- bool clean,
- cmSystemTools::OutputOption outputflag);
+ bool clean);
+
+ void UnwatchUnusedCli(const std::string& var);
+ void WatchUnusedCli(const std::string& var);
+
+ cmState* GetState() const { return this->State; }
+ void SetCurrentSnapshot(cmState::Snapshot snapshot)
+ { this->CurrentSnapshot = snapshot; }
+ cmState::Snapshot GetCurrentSnapshot() const
+ { return this->CurrentSnapshot; }
- void UnwatchUnusedCli(const char* var);
- void WatchUnusedCli(const char* var);
protected:
void RunCheckForUnusedVariables();
void InitializeProperties();
- int HandleDeleteCacheVariables(const char* var);
- cmPropertyMap Properties;
- std::set<std::pair<cmStdString,cmProperty::ScopeType> > AccessedProperties;
-
- std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>
- PropertyDefinitions;
+ int HandleDeleteCacheVariables(const std::string& var);
typedef
cmExternalMakefileProjectGenerator* (*CreateExtraGeneratorFunctionType)();
- typedef std::map<cmStdString,
+ typedef std::map<std::string,
CreateExtraGeneratorFunctionType> RegisteredExtraGeneratorsMap;
typedef std::vector<cmGlobalGeneratorFactory*> RegisteredGeneratorsVector;
- RegisteredCommandsMap Commands;
RegisteredGeneratorsVector Generators;
RegisteredExtraGeneratorsMap ExtraGenerators;
void AddDefaultCommands();
void AddDefaultGenerators();
void AddDefaultExtraGenerators();
- void AddExtraGenerator(const char* name,
+ void AddExtraGenerator(const std::string& name,
CreateExtraGeneratorFunctionType newFunction);
- cmPolicies *Policies;
cmGlobalGenerator *GlobalGenerator;
cmCacheManager *CacheManager;
- std::string cmHomeDirectory;
- std::string HomeOutputDirectory;
- std::string cmStartDirectory;
- std::string StartOutputDirectory;
- bool SuppressDevWarnings;
- bool DoSuppressDevWarnings;
+ std::map<std::string, DiagLevel> DiagLevels;
+ std::string GeneratorPlatform;
std::string GeneratorToolset;
///! read in a cmake list file to initialize the cache
@@ -450,33 +424,8 @@ protected:
void GenerateGraphViz(const char* fileName) const;
- static int SymlinkLibrary(std::vector<std::string>& args);
- static int SymlinkExecutable(std::vector<std::string>& args);
- static bool SymlinkInternal(std::string const& file,
- std::string const& link);
- static int ExecuteEchoColor(std::vector<std::string>& args);
- static int ExecuteLinkScript(std::vector<std::string>& args);
- static int WindowsCEEnvironment(const char* version,
- const std::string& name);
- static int VisualStudioLink(std::vector<std::string>& args, int type);
- static int VisualStudioLinkIncremental(std::vector<std::string>& args,
- int type,
- bool verbose);
- static int VisualStudioLinkNonIncremental(std::vector<std::string>& args,
- int type,
- bool hasManifest,
- bool verbose);
- static int ParseVisualStudioLinkCommand(std::vector<std::string>& args,
- std::vector<cmStdString>& command,
- std::string& targetName);
- static bool RunCommand(const char* comment,
- std::vector<cmStdString>& command,
- bool verbose,
- int* retCodeOut = 0);
cmVariableWatch* VariableWatch;
- ///! Find the full path to one of the cmake programs like ctest, cpack, etc.
- std::string FindCMakeProgram(const char* name) const;
private:
cmake(const cmake&); // Not implemented.
void operator=(const cmake&); // Not implemented.
@@ -487,77 +436,131 @@ private:
WorkingMode CurrentWorkingMode;
bool DebugOutput;
bool Trace;
+ bool TraceExpand;
bool WarnUninitialized;
bool WarnUnused;
bool WarnUnusedCli;
bool CheckSystemVars;
- std::map<cmStdString, bool> UsedCliVariables;
+ std::map<std::string, bool> UsedCliVariables;
std::string CMakeEditCommand;
- std::string CMakeCommand;
std::string CXXEnvironment;
std::string CCEnvironment;
std::string CheckBuildSystemArgument;
std::string CheckStampFile;
std::string CheckStampList;
std::string VSSolutionFile;
- std::string CTestCommand;
- std::string CPackCommand;
+ std::vector<std::string> SourceFileExtensions;
+ std::vector<std::string> HeaderFileExtensions;
bool ClearBuildSystem;
bool DebugTryCompile;
cmFileTimeComparison* FileComparison;
std::string GraphVizFile;
- std::vector<std::string> DebugConfigs;
+ InstalledFilesMap InstalledFiles;
+
+ cmState* State;
+ cmState::Snapshot CurrentSnapshot;
void UpdateConversionPathTable();
+
+ // Print a list of valid generators to stderr.
+ void PrintGeneratorList();
+
+ /**
+ * Convert a message type between a warning and an error, based on the state
+ * of the error output CMake variables, in the cache.
+ */
+ cmake::MessageType ConvertMessageType(cmake::MessageType t);
+
+ /*
+ * Check if messages of this type should be output, based on the state of the
+ * warning and error output CMake variables, in the cache.
+ */
+ bool IsMessageTypeVisible(cmake::MessageType t);
+
+ bool PrintMessagePreamble(cmake::MessageType t, std::ostream& msg);
};
#define CMAKE_STANDARD_OPTIONS_TABLE \
- {"-C <initial-cache>", "Pre-load a script to populate the cache.", \
- "When cmake is first run in an empty build tree, it creates a " \
- "CMakeCache.txt file and populates it with customizable settings " \
- "for the project. This option may be used to specify a file from " \
- "which to load cache entries before the first pass through " \
- "the project's cmake listfiles. The loaded entries take priority " \
- "over the project's default values. The given file should be a CMake " \
- "script containing SET commands that use the CACHE option, " \
- "not a cache-format file."}, \
- {"-D <var>:<type>=<value>", "Create a cmake cache entry.", \
- "When cmake is first run in an empty build tree, it creates a " \
- "CMakeCache.txt file and populates it with customizable settings " \
- "for the project. This option may be used to specify a setting " \
- "that takes priority over the project's default value. The option " \
- "may be repeated for as many cache entries as desired."}, \
- {"-U <globbing_expr>", "Remove matching entries from CMake cache.", \
- "This option may be used to remove one or more variables from the " \
- "CMakeCache.txt file, globbing expressions using * and ? are supported. "\
- "The option may be repeated for as many cache entries as desired.\n" \
- "Use with care, you can make your CMakeCache.txt non-working."}, \
- {"-G <generator-name>", "Specify a build system generator.", \
- "CMake may support multiple native build systems on certain platforms. " \
- "A generator is responsible for generating a particular build " \
- "system. Possible generator names are specified in the Generators " \
- "section."},\
- {"-T <toolset-name>", "Specify toolset name if supported by generator.", \
- "Some CMake generators support a toolset name to be given to the " \
- "native build system to choose a compiler. " \
- "This is supported only on specific generators:\n" \
- " Visual Studio >= 10\n" \
- " Xcode >= 3.0\n" \
- "See native build system documentation for allowed toolset names."}, \
- {"-Wno-dev", "Suppress developer warnings.",\
- "Suppress warnings that are meant for the author"\
- " of the CMakeLists.txt files."},\
- {"-Wdev", "Enable developer warnings.",\
- "Enable warnings that are meant for the author"\
- " of the CMakeLists.txt files."}
-
-
-#define CMAKE_STANDARD_INTRODUCTION \
- {0, \
- "CMake is a cross-platform build system generator. Projects " \
- "specify their build process with platform-independent CMake listfiles " \
- "included in each directory of a source tree with the name " \
- "CMakeLists.txt. " \
- "Users build a project by using CMake to generate a build system " \
- "for a native tool on their platform.", 0}
+ {"-C <initial-cache>", "Pre-load a script to populate the cache."}, \
+ {"-D <var>[:<type>]=<value>", "Create a cmake cache entry."}, \
+ {"-U <globbing_expr>", "Remove matching entries from CMake cache."}, \
+ {"-G <generator-name>", "Specify a build system generator."},\
+ {"-T <toolset-name>", "Specify toolset name if supported by generator."}, \
+ {"-A <platform-name>", "Specify platform name if supported by generator."}, \
+ {"-Wdev", "Enable developer warnings."},\
+ {"-Wno-dev", "Suppress developer warnings."},\
+ {"-Werror=dev", "Make developer warnings errors."},\
+ {"-Wno-error=dev", "Make developer warnings not errors."},\
+ {"-Wdeprecated", "Enable deprecation warnings."},\
+ {"-Wno-deprecated", "Suppress deprecation warnings."},\
+ {"-Werror=deprecated", "Make deprecated macro and function warnings " \
+ "errors."},\
+ {"-Wno-error=deprecated", "Make deprecated macro and function warnings " \
+ "not errors."}
+
+#define FOR_EACH_C_FEATURE(F) \
+ F(c_function_prototypes) \
+ F(c_restrict) \
+ F(c_static_assert) \
+ F(c_variadic_macros)
+
+#define FOR_EACH_CXX_FEATURE(F) \
+ F(cxx_aggregate_default_initializers) \
+ F(cxx_alias_templates) \
+ F(cxx_alignas) \
+ F(cxx_alignof) \
+ F(cxx_attributes) \
+ F(cxx_attribute_deprecated) \
+ F(cxx_auto_type) \
+ F(cxx_binary_literals) \
+ F(cxx_constexpr) \
+ F(cxx_contextual_conversions) \
+ F(cxx_decltype) \
+ F(cxx_decltype_auto) \
+ F(cxx_decltype_incomplete_return_types) \
+ F(cxx_default_function_template_args) \
+ F(cxx_defaulted_functions) \
+ F(cxx_defaulted_move_initializers) \
+ F(cxx_delegating_constructors) \
+ F(cxx_deleted_functions) \
+ F(cxx_digit_separators) \
+ F(cxx_enum_forward_declarations) \
+ F(cxx_explicit_conversions) \
+ F(cxx_extended_friend_declarations) \
+ F(cxx_extern_templates) \
+ F(cxx_final) \
+ F(cxx_func_identifier) \
+ F(cxx_generalized_initializers) \
+ F(cxx_generic_lambdas) \
+ F(cxx_inheriting_constructors) \
+ F(cxx_inline_namespaces) \
+ F(cxx_lambdas) \
+ F(cxx_lambda_init_captures) \
+ F(cxx_local_type_template_args) \
+ F(cxx_long_long_type) \
+ F(cxx_noexcept) \
+ F(cxx_nonstatic_member_init) \
+ F(cxx_nullptr) \
+ F(cxx_override) \
+ F(cxx_range_for) \
+ F(cxx_raw_string_literals) \
+ F(cxx_reference_qualified_functions) \
+ F(cxx_relaxed_constexpr) \
+ F(cxx_return_type_deduction) \
+ F(cxx_right_angle_brackets) \
+ F(cxx_rvalue_references) \
+ F(cxx_sizeof_member) \
+ F(cxx_static_assert) \
+ F(cxx_strong_enums) \
+ F(cxx_template_template_parameters) \
+ F(cxx_thread_local) \
+ F(cxx_trailing_return_types) \
+ F(cxx_unicode_literals) \
+ F(cxx_uniform_initialization) \
+ F(cxx_unrestricted_unions) \
+ F(cxx_user_literals) \
+ F(cxx_variable_templates) \
+ F(cxx_variadic_macros) \
+ F(cxx_variadic_templates)
+
#endif
diff --git a/Source/cmake.version.manifest b/Source/cmake.version.manifest
new file mode 100644
index 000000000..e7010c972
--- /dev/null
+++ b/Source/cmake.version.manifest
@@ -0,0 +1,18 @@
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1"
+ manifestVersion="1.0"
+ xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
+ <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+ <application>
+ <!-- Windows Vista -->
+ <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
+ <!-- Windows 7 -->
+ <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+ <!-- Windows 8 -->
+ <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
+ <!-- Windows 8.1 -->
+ <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
+ <!-- Windows 10 -->
+ <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
+ </application>
+ </compatibility>
+</assembly>
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index 68d833964..a06b26fc6 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -17,43 +17,44 @@
#endif
#include "cmake.h"
-#include "cmCacheManager.h"
+#include "cmcmd.h"
+#include "cmState.h"
#include "cmListFileCache.h"
-#include "cmakewizard.h"
#include "cmSourceFile.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#include "cmAlgorithms.h"
+#include <cmsys/Encoding.hxx>
#ifdef CMAKE_BUILD_WITH_CMAKE
//----------------------------------------------------------------------------
-static const char * cmDocumentationName[][3] =
+static const char * cmDocumentationName[][2] =
{
{0,
- " cmake - Cross-Platform Makefile Generator.", 0},
- {0,0,0}
+ " cmake - Cross-Platform Makefile Generator."},
+ {0,0}
};
//----------------------------------------------------------------------------
-static const char * cmDocumentationUsage[][3] =
+static const char * cmDocumentationUsage[][2] =
{
{0,
" cmake [options] <path-to-source>\n"
- " cmake [options] <path-to-existing-build>", 0},
- {0,0,0}
+ " cmake [options] <path-to-existing-build>"},
+ {0,
+ "Specify a source directory to (re-)generate a build system for "
+ "it in the current working directory. Specify an existing build "
+ "directory to re-generate its build system."},
+ {0,0}
};
//----------------------------------------------------------------------------
-static const char * cmDocumentationDescription[][3] =
+static const char * cmDocumentationUsageNote[][2] =
{
{0,
- "The \"cmake\" executable is the CMake command-line interface. It may "
- "be used to configure projects in scripts. Project configuration "
- "settings "
- "may be specified on the command line with the -D option. The -i option "
- "will cause cmake to interactively prompt for such settings.", 0},
- CMAKE_STANDARD_INTRODUCTION,
- {0,0,0}
+ "Run 'cmake --help' for more information."},
+ {0,0}
};
#define CMAKE_BUILD_OPTIONS \
@@ -62,209 +63,48 @@ static const char * cmDocumentationDescription[][3] =
" --config <cfg> = For multi-configuration tools, choose <cfg>.\n" \
" --clean-first = Build target 'clean' first, then build.\n" \
" (To clean only, use --target 'clean'.)\n" \
- " --use-stderr = Don't merge stdout/stderr output and pass the\n" \
- " original stdout/stderr handles to the native\n" \
- " tool so it can use the capabilities of the\n" \
- " calling terminal (e.g. colored output).\n" \
+ " --use-stderr = Ignored. Behavior is default in CMake >= 3.0.\n" \
" -- = Pass remaining options to the native tool.\n"
//----------------------------------------------------------------------------
-static const char * cmDocumentationOptions[][3] =
+static const char * cmDocumentationOptions[][2] =
{
CMAKE_STANDARD_OPTIONS_TABLE,
- {"-E", "CMake command mode.",
- "For true platform independence, CMake provides a list of commands "
- "that can be used on all systems. Run with -E help for the usage "
- "information. Commands available are: chdir, compare_files, copy, "
- "copy_directory, copy_if_different, echo, echo_append, environment, "
- "make_directory, md5sum, remove, remove_directory, rename, tar, time, "
- "touch, touch_nocreate. In addition, some platform specific commands "
- "are available. "
- "On Windows: comspec, delete_regv, write_regv. "
- "On UNIX: create_symlink."},
- {"-i", "Run in wizard mode.",
- "Wizard mode runs cmake interactively without a GUI. The user is "
- "prompted to answer questions about the project configuration. "
- "The answers are used to set cmake cache values."},
- {"-L[A][H]", "List non-advanced cached variables.",
- "List cache variables will run CMake and list all the variables from the "
- "CMake cache that are not marked as INTERNAL or ADVANCED. This will "
- "effectively display current CMake settings, which can then be changed "
- "with -D option. Changing some of the variables may result in more "
- "variables being created. If A is specified, then it will display also "
- "advanced variables. If H is specified, it will also display help for "
- "each variable."},
- {"--build <dir>", "Build a CMake-generated project binary tree.",
- "This abstracts a native build tool's command-line interface with the "
- "following options:\n"
- CMAKE_BUILD_OPTIONS
- "Run cmake --build with no options for quick help."},
- {"-N", "View mode only.",
- "Only load the cache. Do not actually run configure and generate steps."},
- {"-P <file>", "Process script mode.",
- "Process the given cmake file as a script written in the CMake language. "
- "No configure or generate step is performed and the cache is not"
- " modified. If variables are defined using -D, this must be done "
- "before the -P argument."},
- {"--find-package", "Run in pkg-config like mode.",
- "Search a package using find_package() and print the resulting flags "
- "to stdout. This can be used to use cmake instead of pkg-config to find "
- "installed libraries in plain Makefile-based projects or in "
- "autoconf-based projects (via share/aclocal/cmake.m4)."},
+ {"-E", "CMake command mode."},
+ {"-L[A][H]", "List non-advanced cached variables."},
+ {"--build <dir>", "Build a CMake-generated project binary tree."},
+ {"-N", "View mode only."},
+ {"-P <file>", "Process script mode."},
+ {"--find-package", "Run in pkg-config like mode."},
{"--graphviz=[file]", "Generate graphviz of dependencies, see "
- "CMakeGraphVizOptions.cmake for more.",
- "Generate a graphviz input file that will contain all the library and "
- "executable dependencies in the project. See the documentation for "
- "CMakeGraphVizOptions.cmake for more details. "},
- {"--system-information [file]", "Dump information about this system.",
- "Dump a wide range of information about the current system. If run "
- "from the top of a binary tree for a CMake project it will dump "
- "additional information such as the cache, log files etc."},
+ "CMakeGraphVizOptions.cmake for more."},
+ {"--system-information [file]", "Dump information about this system."},
{"--debug-trycompile", "Do not delete the try_compile build tree. Only "
- "useful on one try_compile at a time.",
- "Do not delete the files and directories created for try_compile calls. "
- "This is useful in debugging failed try_compiles. It may however "
- "change the results of the try-compiles as old junk from a previous "
- "try-compile may cause a different test to either pass or fail "
- "incorrectly. This option is best used for one try-compile at a time, "
- "and only when debugging." },
- {"--debug-output", "Put cmake in a debug mode.",
- "Print extra stuff during the cmake run like stack traces with "
- "message(send_error ) calls."},
- {"--trace", "Put cmake in trace mode.",
- "Print a trace of all calls made and from where with "
- "message(send_error ) calls."},
- {"--warn-uninitialized", "Warn about uninitialized values.",
- "Print a warning when an uninitialized variable is used."},
- {"--warn-unused-vars", "Warn about unused variables.",
- "Find variables that are declared or set, but not used."},
- {"--no-warn-unused-cli", "Don't warn about command line options.",
- "Don't find variables that are declared on the command line, but not "
- "used."},
+ "useful on one try_compile at a time."},
+ {"--debug-output", "Put cmake in a debug mode."},
+ {"--trace", "Put cmake in trace mode."},
+ {"--trace-expand", "Put cmake in trace mode with variable expansion."},
+ {"--warn-uninitialized", "Warn about uninitialized values."},
+ {"--warn-unused-vars", "Warn about unused variables."},
+ {"--no-warn-unused-cli", "Don't warn about command line options."},
{"--check-system-vars", "Find problems with variable usage in system "
- "files.", "Normally, unused and uninitialized variables are searched for "
- "only in CMAKE_SOURCE_DIR and CMAKE_BINARY_DIR. This flag tells CMake to "
- "warn about other files as well."},
- {"--help-command cmd [file]", "Print help for a single command and exit.",
- "Full documentation specific to the given command is displayed. "
- "If a file is specified, the documentation is written into and the output "
- "format is determined depending on the filename suffix. Supported are man "
- "page, HTML, DocBook and plain text."},
- {"--help-command-list [file]", "List available listfile commands and exit.",
- "The list contains all commands for which help may be obtained by using "
- "the --help-command argument followed by a command name. "
- "If a file is specified, the documentation is written into and the output "
- "format is determined depending on the filename suffix. Supported are man "
- "page, HTML, DocBook and plain text."},
- {"--help-commands [file]", "Print help for all commands and exit.",
- "Full documentation specific for all current commands is displayed."
- "If a file is specified, the documentation is written into and the output "
- "format is determined depending on the filename suffix. Supported are man "
- "page, HTML, DocBook and plain text."},
- {"--help-compatcommands [file]", "Print help for compatibility commands. ",
- "Full documentation specific for all compatibility commands is displayed."
- "If a file is specified, the documentation is written into and the output "
- "format is determined depending on the filename suffix. Supported are man "
- "page, HTML, DocBook and plain text."},
- {"--help-module module [file]", "Print help for a single module and exit.",
- "Full documentation specific to the given module is displayed."
- "If a file is specified, the documentation is written into and the output "
- "format is determined depending on the filename suffix. Supported are man "
- "page, HTML, DocBook and plain text."},
- {"--help-module-list [file]", "List available modules and exit.",
- "The list contains all modules for which help may be obtained by using "
- "the --help-module argument followed by a module name. "
- "If a file is specified, the documentation is written into and the output "
- "format is determined depending on the filename suffix. Supported are man "
- "page, HTML, DocBook and plain text."},
- {"--help-modules [file]", "Print help for all modules and exit.",
- "Full documentation for all modules is displayed. "
- "If a file is specified, the documentation is written into and the output "
- "format is determined depending on the filename suffix. Supported are man "
- "page, HTML, DocBook and plain text."},
- {"--help-custom-modules [file]" , "Print help for all custom modules and "
- "exit.",
- "Full documentation for all custom modules is displayed. "
- "If a file is specified, the documentation is written into and the output "
- "format is determined depending on the filename suffix. Supported are man "
- "page, HTML, DocBook and plain text."},
- {"--help-policy cmp [file]",
- "Print help for a single policy and exit.",
- "Full documentation specific to the given policy is displayed."
- "If a file is specified, the documentation is written into and the output "
- "format is determined depending on the filename suffix. Supported are man "
- "page, HTML, DocBook and plain text."},
- {"--help-policies [file]", "Print help for all policies and exit.",
- "Full documentation for all policies is displayed."
- "If a file is specified, the documentation is written into and the output "
- "format is determined depending on the filename suffix. Supported are man "
- "page, HTML, DocBook and plain text."},
- {"--help-property prop [file]",
- "Print help for a single property and exit.",
- "Full documentation specific to the given property is displayed."
- "If a file is specified, the documentation is written into and the output "
- "format is determined depending on the filename suffix. Supported are man "
- "page, HTML, DocBook and plain text."},
- {"--help-property-list [file]", "List available properties and exit.",
- "The list contains all properties for which help may be obtained by using "
- "the --help-property argument followed by a property name. If a file is "
- "specified, the help is written into it."
- "If a file is specified, the documentation is written into and the output "
- "format is determined depending on the filename suffix. Supported are man "
- "page, HTML, DocBook and plain text."},
- {"--help-properties [file]", "Print help for all properties and exit.",
- "Full documentation for all properties is displayed."
- "If a file is specified, the documentation is written into and the output "
- "format is determined depending on the filename suffix. Supported are man "
- "page, HTML, DocBook and plain text."},
- {"--help-variable var [file]",
- "Print help for a single variable and exit.",
- "Full documentation specific to the given variable is displayed."
- "If a file is specified, the documentation is written into and the output "
- "format is determined depending on the filename suffix. Supported are man "
- "page, HTML, DocBook and plain text."},
- {"--help-variable-list [file]", "List documented variables and exit.",
- "The list contains all variables for which help may be obtained by using "
- "the --help-variable argument followed by a variable name. If a file is "
- "specified, the help is written into it."
- "If a file is specified, the documentation is written into and the output "
- "format is determined depending on the filename suffix. Supported are man "
- "page, HTML, DocBook and plain text."},
- {"--help-variables [file]", "Print help for all variables and exit.",
- "Full documentation for all variables is displayed."
- "If a file is specified, the documentation is written into and the output "
- "format is determined depending on the filename suffix. Supported are man "
- "page, HTML, DocBook and plain text."},
- {0,0,0}
+ "files."},
+ {0,0}
};
-//----------------------------------------------------------------------------
-static const char * cmDocumentationSeeAlso[][3] =
-{
- {0, "ccmake", 0},
- {0, "cpack", 0},
- {0, "ctest", 0},
- {0, "cmakecommands", 0},
- {0, "cmakecompat", 0},
- {0, "cmakemodules", 0},
- {0, "cmakeprops", 0},
- {0, "cmakevars", 0},
- {0, 0, 0}
-};
+#endif
-//----------------------------------------------------------------------------
-static const char * cmDocumentationNOTE[][3] =
+static int do_command(int ac, char const* const* av)
{
- {0,
- "CMake no longer configures a project when run with no arguments. "
- "In order to configure the project in the current directory, run\n"
- " cmake .", 0},
- {0,0,0}
-};
-#endif
+ std::vector<std::string> args;
+ args.reserve(ac - 1);
+ args.push_back(av[0]);
+ args.insert(args.end(), av + 2, av + ac);
+ return cmcmd::ExecuteCMakeCommand(args);
+}
-int do_cmake(int ac, char** av);
-static int do_build(int ac, char** av);
+int do_cmake(int ac, char const* const* av);
+static int do_build(int ac, char const* const* av);
static cmMakefile* cmakemainGetMakefile(void *clientdata)
{
@@ -274,12 +114,7 @@ static cmMakefile* cmakemainGetMakefile(void *clientdata)
cmGlobalGenerator* gg=cm->GetGlobalGenerator();
if (gg)
{
- cmLocalGenerator* lg=gg->GetCurrentLocalGenerator();
- if (lg)
- {
- cmMakefile* mf = lg->GetMakefile();
- return mf;
- }
+ return gg->GetCurrentMakefile();
}
}
return 0;
@@ -291,7 +126,7 @@ static std::string cmakemainGetStack(void *clientdata)
cmMakefile* mf=cmakemainGetMakefile(clientdata);
if (mf)
{
- msg = mf->GetListFileStack();
+ msg = mf->FormatListFileStack();
if (!msg.empty())
{
msg = "\n Called from: " + msg;
@@ -301,8 +136,8 @@ static std::string cmakemainGetStack(void *clientdata)
return msg;
}
-static void cmakemainErrorCallback(const char* m, const char*, bool&,
- void *clientdata)
+static void cmakemainMessageCallback(const char* m, const char*, bool&,
+ void *clientdata)
{
std::cerr << m << cmakemainGetStack(clientdata) << std::endl << std::flush;
}
@@ -315,12 +150,12 @@ static void cmakemainProgressCallback(const char *m, float prog,
if ((mf) && (strstr(m, "Configuring")==m) && (prog<0))
{
dir = " ";
- dir += mf->GetCurrentDirectory();
+ dir += mf->GetCurrentSourceDirectory();
}
else if ((mf) && (strstr(m, "Generating")==m))
{
dir = " ";
- dir += mf->GetCurrentOutputDirectory();
+ dir += mf->GetCurrentBinaryDirectory();
}
if ((prog < 0) || (!dir.empty()))
@@ -332,13 +167,25 @@ static void cmakemainProgressCallback(const char *m, float prog,
}
-int main(int ac, char** av)
+int main(int ac, char const* const* av)
{
+ cmsys::Encoding::CommandLineArguments args =
+ cmsys::Encoding::CommandLineArguments::Main(ac, av);
+ ac = args.argc();
+ av = args.argv();
+
cmSystemTools::EnableMSVCDebugHook();
- cmSystemTools::FindExecutableDirectory(av[0]);
- if(ac > 1 && strcmp(av[1], "--build") == 0)
+ cmSystemTools::FindCMakeResources(av[0]);
+ if(ac > 1)
{
- return do_build(ac, av);
+ if(strcmp(av[1], "--build") == 0)
+ {
+ return do_build(ac, av);
+ }
+ else if(strcmp(av[1], "-E") == 0)
+ {
+ return do_command(ac, av);
+ }
}
int ret = do_cmake(ac, av);
#ifdef CMAKE_BUILD_WITH_CMAKE
@@ -347,9 +194,9 @@ int main(int ac, char** av)
return ret;
}
-int do_cmake(int ac, char** av)
+int do_cmake(int ac, char const* const* av)
{
- if ( cmSystemTools::GetCurrentWorkingDirectory().size() == 0 )
+ if (cmSystemTools::GetCurrentWorkingDirectory().empty())
{
std::cerr << "Current working directory cannot be established."
<< std::endl;
@@ -359,72 +206,34 @@ int do_cmake(int ac, char** av)
#ifdef CMAKE_BUILD_WITH_CMAKE
cmDocumentation doc;
doc.addCMakeStandardDocSections();
- if(doc.CheckOptions(ac, av, "-E"))
+ if(doc.CheckOptions(ac, av))
{
// Construct and print requested documentation.
cmake hcm;
+ hcm.SetHomeDirectory("");
+ hcm.SetHomeOutputDirectory("");
hcm.AddCMakePaths();
- doc.SetCMakeRoot(hcm.GetCacheDefinition("CMAKE_ROOT"));
// the command line args are processed here so that you can do
// -DCMAKE_MODULE_PATH=/some/path and have this value accessible here
- std::vector<std::string> args;
- for(int i =0; i < ac; ++i)
- {
- args.push_back(av[i]);
- }
+ std::vector<std::string> args(av, av + ac);
hcm.SetCacheArgs(args);
- const char* modulePath = hcm.GetCacheDefinition("CMAKE_MODULE_PATH");
- if (modulePath)
- {
- doc.SetCMakeModulePath(modulePath);
- }
- std::vector<cmDocumentationEntry> commands;
- std::vector<cmDocumentationEntry> policies;
- std::vector<cmDocumentationEntry> compatCommands;
std::vector<cmDocumentationEntry> generators;
- std::map<std::string,cmDocumentationSection *> propDocs;
- hcm.GetPolicyDocumentation(policies);
- hcm.GetCommandDocumentation(commands, true, false);
- hcm.GetCommandDocumentation(compatCommands, false, true);
- hcm.GetPropertiesDocumentation(propDocs);
hcm.GetGeneratorDocumentation(generators);
doc.SetName("cmake");
doc.SetSection("Name",cmDocumentationName);
doc.SetSection("Usage",cmDocumentationUsage);
- doc.SetSection("Description",cmDocumentationDescription);
- doc.AppendSection("Generators",generators);
- doc.PrependSection("Options",cmDocumentationOptions);
- doc.SetSection("Commands",commands);
- doc.SetSection("Policies",policies);
- doc.AppendSection("Compatibility Commands",compatCommands);
- doc.SetSections(propDocs);
-
- cmDocumentationEntry e;
- e.Brief =
- "variables defined by cmake, that give information about the project, "
- "and cmake";
- doc.PrependSection("Variables that Provide Information",e);
-
- doc.SetSeeAlsoList(cmDocumentationSeeAlso);
- int result = doc.PrintRequestedDocumentation(std::cout)? 0:1;
-
- // If we were run with no arguments, but a CMakeLists.txt file
- // exists, the user may have been trying to use the old behavior
- // of cmake to build a project in-source. Print a message
- // explaining the change to standard error and return an error
- // condition in case the program is running from a script.
- if((ac == 1) && cmSystemTools::FileExists("CMakeLists.txt"))
+ if ( ac == 1 )
{
- doc.ClearSections();
- doc.SetSection("NOTE", cmDocumentationNOTE);
- doc.Print(cmDocumentation::UsageForm, 0, std::cerr);
- return 1;
+ doc.AppendSection("Usage",cmDocumentationUsageNote);
}
- return result;
+ doc.AppendSection("Generators",generators);
+ doc.PrependSection("Options",cmDocumentationOptions);
+
+ return doc.PrintRequestedDocumentation(std::cout)? 0:1;
}
#else
if ( ac == 1 )
@@ -436,9 +245,7 @@ int do_cmake(int ac, char** av)
}
#endif
- bool wiz = false;
bool sysinfo = false;
- bool command = false;
bool list_cached = false;
bool list_all_cached = false;
bool list_help = false;
@@ -447,43 +254,41 @@ int do_cmake(int ac, char** av)
std::vector<std::string> args;
for(int i =0; i < ac; ++i)
{
- if(!command && strcmp(av[i], "-i") == 0)
+ if(strcmp(av[i], "-i") == 0)
{
- wiz = true;
+ std::cerr <<
+ "The \"cmake -i\" wizard mode is no longer supported.\n"
+ "Use the -D option to set cache values on the command line.\n"
+ "Use cmake-gui or ccmake for an interactive dialog.\n";
+ return 1;
}
- else if(!command && strcmp(av[i], "--system-information") == 0)
+ else if(strcmp(av[i], "--system-information") == 0)
{
sysinfo = true;
}
- // if command has already been set, then
- // do not eat the -E
- else if (!command && strcmp(av[i], "-E") == 0)
- {
- command = true;
- }
- else if (!command && strcmp(av[i], "-N") == 0)
+ else if (strcmp(av[i], "-N") == 0)
{
view_only = true;
}
- else if (!command && strcmp(av[i], "-L") == 0)
+ else if (strcmp(av[i], "-L") == 0)
{
list_cached = true;
}
- else if (!command && strcmp(av[i], "-LA") == 0)
+ else if (strcmp(av[i], "-LA") == 0)
{
list_all_cached = true;
}
- else if (!command && strcmp(av[i], "-LH") == 0)
+ else if (strcmp(av[i], "-LH") == 0)
{
list_cached = true;
list_help = true;
}
- else if (!command && strcmp(av[i], "-LAH") == 0)
+ else if (strcmp(av[i], "-LAH") == 0)
{
list_all_cached = true;
list_help = true;
}
- else if (!command && strncmp(av[i], "-P", strlen("-P")) == 0)
+ else if (cmHasLiteralPrefix(av[i], "-P"))
{
if ( i == ac -1 )
{
@@ -497,8 +302,7 @@ int do_cmake(int ac, char** av)
args.push_back(av[i]);
}
}
- else if (!command && strncmp(av[i], "--find-package",
- strlen("--find-package")) == 0)
+ else if (cmHasLiteralPrefix(av[i], "--find-package"))
{
workingMode = cmake::FIND_PACKAGE_MODE;
args.push_back(av[i]);
@@ -508,49 +312,47 @@ int do_cmake(int ac, char** av)
args.push_back(av[i]);
}
}
- if(command)
- {
- int ret = cmake::ExecuteCMakeCommand(args);
- return ret;
- }
- if (wiz)
- {
- cmakewizard wizard;
- return wizard.RunWizard(args);
- }
if (sysinfo)
{
cmake cm;
+ cm.SetHomeDirectory("");
+ cm.SetHomeOutputDirectory("");
int ret = cm.GetSystemInformation(args);
return ret;
}
cmake cm;
- cmSystemTools::SetErrorCallback(cmakemainErrorCallback, (void *)&cm);
+ cm.SetHomeDirectory("");
+ cm.SetHomeOutputDirectory("");
+ cmSystemTools::SetMessageCallback(cmakemainMessageCallback, (void *)&cm);
cm.SetProgressCallback(cmakemainProgressCallback, (void *)&cm);
cm.SetWorkingMode(workingMode);
int res = cm.Run(args, view_only);
if ( list_cached || list_all_cached )
{
- cmCacheManager::CacheIterator it =
- cm.GetCacheManager()->GetCacheIterator();
std::cout << "-- Cache values" << std::endl;
- for ( it.Begin(); !it.IsAtEnd(); it.Next() )
+ std::vector<std::string> keys = cm.GetState()->GetCacheEntryKeys();
+ for (std::vector<std::string>::const_iterator it = keys.begin();
+ it != keys.end(); ++it)
{
- cmCacheManager::CacheEntryType t = it.GetType();
- if ( t != cmCacheManager::INTERNAL && t != cmCacheManager::STATIC &&
- t != cmCacheManager::UNINITIALIZED )
+ cmState::CacheEntryType t = cm.GetState()->GetCacheEntryType(*it);
+ if (t != cmState::INTERNAL && t != cmState::STATIC &&
+ t != cmState::UNINITIALIZED)
{
- bool advanced = it.PropertyExists("ADVANCED");
- if ( list_all_cached || !advanced)
+ const char* advancedProp =
+ cm.GetState()->GetCacheEntryProperty(*it, "ADVANCED");
+ if ( list_all_cached || !advancedProp)
{
if ( list_help )
{
- std::cout << "// " << it.GetProperty("HELPSTRING") << std::endl;
+ std::cout << "// "
+ << cm.GetState()->GetCacheEntryProperty(*it,
+ "HELPSTRING") << std::endl;
}
- std::cout << it.GetName() << ":" <<
- cmCacheManager::TypeToString(it.GetType())
- << "=" << it.GetValue() << std::endl;
+ std::cout << *it << ":" <<
+ cmState::CacheEntryTypeToString(t)
+ << "=" << cm.GetState()->GetCacheEntryValue(*it)
+ << std::endl;
if ( list_help )
{
std::cout << std::endl;
@@ -573,7 +375,7 @@ int do_cmake(int ac, char** av)
}
//----------------------------------------------------------------------------
-static int do_build(int ac, char** av)
+static int do_build(int ac, char const* const* av)
{
#ifndef CMAKE_BUILD_WITH_CMAKE
std::cerr << "This cmake does not support --build\n";
@@ -584,7 +386,6 @@ static int do_build(int ac, char** av)
std::string dir;
std::vector<std::string> nativeOptions;
bool clean = false;
- cmSystemTools::OutputOption outputflag = cmSystemTools::OUTPUT_MERGE;
enum Doing { DoingNone, DoingDir, DoingTarget, DoingConfig, DoingNative};
Doing doing = DoingDir;
@@ -609,7 +410,7 @@ static int do_build(int ac, char** av)
}
else if(strcmp(av[i], "--use-stderr") == 0)
{
- outputflag = cmSystemTools::OUTPUT_PASSTHROUGH;
+ /* tolerate legacy option */
}
else if(strcmp(av[i], "--") == 0)
{
@@ -620,7 +421,7 @@ static int do_build(int ac, char** av)
switch (doing)
{
case DoingDir:
- dir = av[i];
+ dir = cmSystemTools::CollapseFullPath(av[i]);
doing = DoingNone;
break;
case DoingTarget:
@@ -656,6 +457,6 @@ static int do_build(int ac, char** av)
}
cmake cm;
- return cm.Build(dir, target, config, nativeOptions, clean, outputflag);
+ return cm.Build(dir, target, config, nativeOptions, clean);
#endif
}
diff --git a/Source/cmaketest.h.in b/Source/cmaketest.h.in
deleted file mode 100644
index aada52dba..000000000
--- a/Source/cmaketest.h.in
+++ /dev/null
@@ -1,16 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#define CMAKE_BINARY_DIR "${CMake_BINARY_DIR}"
-#define EXECUTABLE_OUTPUT_PATH "${EXECUTABLE_OUTPUT_PATH}"
-#define MAKEPROGRAM "${MAKEPROGRAM}"
-#define CMAKE_GENERATOR "${CMAKE_GENERATOR}"
-#define DART_MAKECOMMAND "${MAKECOMMAND}"
diff --git a/Source/cmakewizard.cxx b/Source/cmakewizard.cxx
deleted file mode 100644
index bac403a89..000000000
--- a/Source/cmakewizard.cxx
+++ /dev/null
@@ -1,155 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#include "cmakewizard.h"
-#include "cmake.h"
-#include "cmCacheManager.h"
-
-cmakewizard::cmakewizard()
-{
- this->ShowAdvanced = false;
-}
-
-
-void cmakewizard::AskUser(const char* key,
- cmCacheManager::CacheIterator& iter)
-{
- printf("Variable Name: %s\n", key);
- const char* helpstring = iter.GetProperty("HELPSTRING");
- printf("Description: %s\n", (helpstring?helpstring:"(none)"));
- printf("Current Value: %s\n", iter.GetValue());
- printf("New Value (Enter to keep current value): ");
- char buffer[4096];
- if(!fgets(buffer, static_cast<int>(sizeof(buffer) - 1), stdin))
- {
- buffer[0] = 0;
- }
-
- if(strlen(buffer) > 0)
- {
- std::string sbuffer = buffer;
- std::string::size_type pos = sbuffer.find_last_not_of(" \n\r\t");
- std::string value = "";
- if ( pos != std::string::npos )
- {
- value = sbuffer.substr(0, pos+1);
- }
-
- if ( value.size() > 0 )
- {
- if(iter.GetType() == cmCacheManager::PATH ||
- iter.GetType() == cmCacheManager::FILEPATH)
- {
- cmSystemTools::ConvertToUnixSlashes(value);
- }
- if(iter.GetType() == cmCacheManager::BOOL)
- {
- if(!cmSystemTools::IsOn(value.c_str()))
- {
- value = "OFF";
- }
- }
- iter.SetValue(value.c_str());
- }
- }
- printf("\n");
-}
-
-bool cmakewizard::AskAdvanced()
-{
- printf("Would you like to see advanced options? [No]:");
- char buffer[4096];
- if(!fgets(buffer, static_cast<int>(sizeof(buffer) - 1), stdin))
- {
- buffer[0] = 0;
- }
- else if(buffer[0] == 'y' || buffer[0] == 'Y')
- {
- return true;
- }
- return false;
-}
-
-
-void cmakewizard::ShowMessage(const char* m)
-{
- printf("%s\n", m);
-}
-
-
-
-int cmakewizard::RunWizard(std::vector<std::string> const& args)
-{
- this->ShowAdvanced = this->AskAdvanced();
- cmSystemTools::DisableRunCommandOutput();
- cmake make;
- make.SetArgs(args);
- make.SetCMakeCommand(args[0].c_str());
- make.LoadCache();
- make.SetCacheArgs(args);
- std::map<cmStdString, cmStdString> askedCache;
- bool asked = false;
- // continue asking questions until no new questions are asked
- do
- {
- asked = false;
- // run cmake
- this->ShowMessage(
- "Please wait while cmake processes CMakeLists.txt files....\n");
-
- make.Configure();
- this->ShowMessage("\n");
- // load the cache from disk
- cmCacheManager *cachem = make.GetCacheManager();
- cachem->LoadCache(make.GetHomeOutputDirectory());
- cmCacheManager::CacheIterator i = cachem->NewIterator();
- // iterate over all entries in the cache
- for(;!i.IsAtEnd(); i.Next())
- {
- std::string key = i.GetName();
- if( i.GetType() == cmCacheManager::INTERNAL ||
- i.GetType() == cmCacheManager::STATIC ||
- i.GetType() == cmCacheManager::UNINITIALIZED )
- {
- continue;
- }
- if(askedCache.count(key))
- {
- std::string& e = askedCache.find(key)->second;
- if(e != i.GetValue())
- {
- if(this->ShowAdvanced || !i.GetPropertyAsBool("ADVANCED"))
- {
- this->AskUser(key.c_str(), i);
- asked = true;
- }
- }
- }
- else
- {
- if(this->ShowAdvanced || !i.GetPropertyAsBool("ADVANCED"))
- {
- this->AskUser(key.c_str(), i);
- asked = true;
- }
- }
- askedCache[key] = i.GetValue();
- }
- cachem->SaveCache(make.GetHomeOutputDirectory());
- }
- while(asked);
- if(make.Generate() == 0)
- {
- this->ShowMessage("CMake complete, run make to build project.\n");
- return 0;
- }
- return 1;
-}
diff --git a/Source/cmakewizard.h b/Source/cmakewizard.h
deleted file mode 100644
index 0c8dba93c..000000000
--- a/Source/cmakewizard.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-
-
-#include "cmMakefile.h"
-
-class cmakewizard
-{
-public:
- cmakewizard();
- virtual ~cmakewizard() {}
- /**
- * Prompt the user to see if they want to see advanced entries.
- */
- virtual bool AskAdvanced();
-
- /**
- * Prompt the User for a new value for key, the answer is put in entry.
- */
- virtual void AskUser(const char* key, cmCacheManager::CacheIterator& iter);
- ///! Show a message to wait for cmake to run.
- virtual void ShowMessage(const char*);
-
- /**
- * Run cmake in wizard mode. This will coninue to ask the user questions
- * until there are no more entries in the cache.
- */
- int RunWizard(std::vector<std::string>const& args);
-
-private:
- bool ShowAdvanced;
-};
-
diff --git a/Source/cmcldeps.cxx b/Source/cmcldeps.cxx
index 85715574f..f3c6059b1 100644
--- a/Source/cmcldeps.cxx
+++ b/Source/cmcldeps.cxx
@@ -23,6 +23,7 @@
#include <windows.h>
#include <sstream>
#include <cmSystemTools.h>
+#include <cmsys/Encoding.hxx>
// We don't want any wildcard expansion.
// See http://msdn.microsoft.com/en-us/library/zay8tzh6(v=vs.85).aspx
@@ -100,7 +101,7 @@ static std::string getArg(std::string& cmdline) {
return ret;
}
-static void parseCommandLine(LPTSTR wincmdline,
+static void parseCommandLine(LPWSTR wincmdline,
std::string& lang,
std::string& srcfile,
std::string& dfile,
@@ -109,7 +110,7 @@ static void parseCommandLine(LPTSTR wincmdline,
std::string& clpath,
std::string& binpath,
std::string& rest) {
- std::string cmdline(wincmdline);
+ std::string cmdline = cmsys::Encoding::ToNarrow(wincmdline);
/* self */ getArg(cmdline);
lang = getArg(cmdline);
srcfile = getArg(cmdline);
@@ -138,7 +139,7 @@ static void outputDepFile(const std::string& dfile, const std::string& objfile,
std::sort(incs.begin(), incs.end());
incs.erase(std::unique(incs.begin(), incs.end()), incs.end());
- FILE* out = fopen(dfile.c_str(), "wb");
+ FILE* out = cmsys::SystemTools::Fopen(dfile.c_str(), "wb");
// FIXME should this be fatal or not? delete obj? delete d?
if (!out)
@@ -197,7 +198,7 @@ static int process( const std::string& srcfilename,
std::vector<std::string> args;
cmSystemTools::ParseWindowsCommandLine(cmd.c_str(), args);
// convert to correct vector type for RunSingleCommand
- std::vector<cmStdString> command;
+ std::vector<std::string> command;
for(std::vector<std::string>::iterator i = args.begin();
i != args.end(); ++i)
{
@@ -205,8 +206,9 @@ static int process( const std::string& srcfilename,
}
// run the command
int exit_code = 0;
- bool run = cmSystemTools::RunSingleCommand(command, &output, &exit_code,
- dir.c_str(), cmSystemTools::OUTPUT_NONE);
+ bool run = cmSystemTools::RunSingleCommand(command, &output, &output,
+ &exit_code, dir.c_str(),
+ cmSystemTools::OUTPUT_NONE);
// process the include directives and output everything else
std::stringstream ss(output);
@@ -247,7 +249,7 @@ int main() {
// the same command line verbatim.
std::string lang, srcfile, dfile, objfile, prefix, cl, binpath, rest;
- parseCommandLine(GetCommandLine(), lang, srcfile, dfile, objfile,
+ parseCommandLine(GetCommandLineW(), lang, srcfile, dfile, objfile,
prefix, cl, binpath, rest);
// needed to suppress filename output of msvc tools
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
new file mode 100644
index 000000000..e9d77b250
--- /dev/null
+++ b/Source/cmcmd.cxx
@@ -0,0 +1,1782 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmcmd.h"
+#include "cmMakefile.h"
+#include "cmLocalGenerator.h"
+#include "cmGlobalGenerator.h"
+#include "cmQtAutoGenerators.h"
+#include "cmVersion.h"
+#include "cmAlgorithms.h"
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+# include "cmDependsFortran.h" // For -E cmake_copy_f90_mod callback.
+#endif
+
+#include <cmsys/Directory.hxx>
+#include <cmsys/Process.h>
+#include <cmsys/FStream.hxx>
+#include <cmsys/Terminal.h>
+
+#if defined(CMAKE_HAVE_VS_GENERATORS)
+#include "cmCallVisualStudioMacro.h"
+#include "cmVisualStudioWCEPlatformParser.h"
+#endif
+
+#include <time.h>
+
+#include <stdlib.h> // required for atoi
+#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
+#include "bindexplib.h"
+#endif
+
+void CMakeCommandUsage(const char* program)
+{
+ std::ostringstream errorStream;
+
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ errorStream
+ << "cmake version " << cmVersion::GetCMakeVersion() << "\n";
+#else
+ errorStream
+ << "cmake bootstrap\n";
+#endif
+ // If you add new commands, change here,
+ // and in cmakemain.cxx in the options table
+ errorStream
+ << "Usage: " << program << " -E <command> [arguments...]\n"
+ << "Available commands: \n"
+ << " chdir dir cmd [args...] - run command in a given directory\n"
+ << " compare_files file1 file2 - check if file1 is same as file2\n"
+ << " copy <file>... destination - copy files to destination "
+ "(either file or directory)\n"
+ << " copy_directory <dir>... destination - copy content of <dir>... "
+ "directories to 'destination' directory\n"
+ << " copy_if_different <file>... destination - copy files if it has "
+ "changed\n"
+ << " echo [<string>...] - displays arguments as text\n"
+ << " echo_append [<string>...] - displays arguments as text but no new "
+ "line\n"
+ << " env [--unset=NAME]... [NAME=VALUE]... COMMAND [ARG]...\n"
+ << " - run command in a modified environment\n"
+ << " environment - display the current environment\n"
+ << " make_directory <dir>... - create parent and <dir> directories\n"
+ << " md5sum <file>... - compute md5sum of files\n"
+ << " remove [-f] <file>... - remove the file(s), use -f to force "
+ "it\n"
+ << " remove_directory dir - remove a directory and its contents\n"
+ << " rename oldname newname - rename a file or directory "
+ "(on one volume)\n"
+ << " tar [cxt][vf][zjJ] file.tar [file/dir1 file/dir2 ...]\n"
+ << " - create or extract a tar or zip archive\n"
+ << " sleep <number>... - sleep for given number of seconds\n"
+ << " time command [args...] - run command and return elapsed time\n"
+ << " touch file - touch a file.\n"
+ << " touch_nocreate file - touch a file but do not create it.\n"
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ << "Available on Windows only:\n"
+ << " delete_regv key - delete registry value\n"
+ << " env_vs8_wince sdkname - displays a batch file which sets the "
+ "environment for the provided Windows CE SDK installed in VS2005\n"
+ << " env_vs9_wince sdkname - displays a batch file which sets the "
+ "environment for the provided Windows CE SDK installed in VS2008\n"
+ << " write_regv key value - write registry value\n"
+#else
+ << "Available on UNIX only:\n"
+ << " create_symlink old new - create a symbolic link new -> old\n"
+#endif
+ ;
+
+ cmSystemTools::Error(errorStream.str().c_str());
+}
+
+static bool cmTarFilesFrom(std::string const& file,
+ std::vector<std::string>& files)
+{
+ if (cmSystemTools::FileIsDirectory(file))
+ {
+ std::ostringstream e;
+ e << "-E tar --files-from= file '" << file << "' is a directory";
+ cmSystemTools::Error(e.str().c_str());
+ return false;
+ }
+ cmsys::ifstream fin(file.c_str());
+ if (!fin)
+ {
+ std::ostringstream e;
+ e << "-E tar --files-from= file '" << file << "' not found";
+ cmSystemTools::Error(e.str().c_str());
+ return false;
+ }
+ std::string line;
+ while (cmSystemTools::GetLineFromStream(fin, line))
+ {
+ if (line.empty())
+ {
+ continue;
+ }
+ if (cmHasLiteralPrefix(line, "--add-file="))
+ {
+ files.push_back(line.substr(11));
+ }
+ else if (cmHasLiteralPrefix(line, "-"))
+ {
+ std::ostringstream e;
+ e << "-E tar --files-from='" << file << "' file invalid line:\n"
+ << line << "\n";
+ cmSystemTools::Error(e.str().c_str());
+ return false;
+ }
+ else
+ {
+ files.push_back(line);
+ }
+ }
+ return true;
+}
+
+int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
+{
+ // IF YOU ADD A NEW COMMAND, DOCUMENT IT ABOVE and in cmakemain.cxx
+ if (args.size() > 1)
+ {
+ // Copy file
+ if (args[1] == "copy" && args.size() > 3)
+ {
+ // If multiple source files specified,
+ // then destination must be directory
+ if ((args.size() > 4) &&
+ (!cmSystemTools::FileIsDirectory(args[args.size() - 1])))
+ {
+ std::cerr << "Error: Target (for copy command) \""
+ << args[args.size() - 1]
+ << "\" is not a directory.\n";
+ return 1;
+ }
+ // If error occurs we want to continue copying next files.
+ bool return_value = 0;
+ for (std::string::size_type cc = 2; cc < args.size() - 1; cc ++)
+ {
+ if(!cmSystemTools::cmCopyFile(args[cc].c_str(),
+ args[args.size() - 1].c_str()))
+ {
+ std::cerr << "Error copying file \"" << args[cc]
+ << "\" to \"" << args[args.size() - 1] << "\".\n";
+ return_value = 1;
+ }
+ }
+ return return_value;
+ }
+
+ // Copy file if different.
+ if (args[1] == "copy_if_different" && args.size() > 3)
+ {
+ // If multiple source files specified,
+ // then destination must be directory
+ if ((args.size() > 4) &&
+ (!cmSystemTools::FileIsDirectory(args[args.size() - 1])))
+ {
+ std::cerr << "Error: Target (for copy_if_different command) \""
+ << args[args.size() - 1]
+ << "\" is not a directory.\n";
+ return 1;
+ }
+ // If error occurs we want to continue copying next files.
+ bool return_value = 0;
+ for (std::string::size_type cc = 2; cc < args.size() - 1; cc ++)
+ {
+ if(!cmSystemTools::CopyFileIfDifferent(args[cc].c_str(),
+ args[args.size() - 1].c_str()))
+ {
+ std::cerr << "Error copying file (if different) from \""
+ << args[cc] << "\" to \"" << args[args.size() - 1]
+ << "\".\n";
+ return_value = 1;
+ }
+ }
+ return return_value;
+ }
+
+ // Copy directory content
+ if (args[1] == "copy_directory" && args.size() > 3)
+ {
+ // If error occurs we want to continue copying next files.
+ bool return_value = 0;
+ for (std::string::size_type cc = 2; cc < args.size() - 1; cc ++)
+ {
+ if(!cmSystemTools::CopyADirectory(args[cc].c_str(),
+ args[args.size() - 1].c_str()))
+ {
+ std::cerr << "Error copying directory from \""
+ << args[cc] << "\" to \"" << args[args.size() - 1]
+ << "\".\n";
+ return_value = 1;
+ }
+ }
+ return return_value;
+ }
+
+ // Rename a file or directory
+ if (args[1] == "rename" && args.size() == 4)
+ {
+ if(!cmSystemTools::RenameFile(args[2].c_str(), args[3].c_str()))
+ {
+ std::string e = cmSystemTools::GetLastSystemError();
+ std::cerr << "Error renaming from \""
+ << args[2] << "\" to \"" << args[3]
+ << "\": " << e << "\n";
+ return 1;
+ }
+ return 0;
+ }
+
+ // Compare files
+ if (args[1] == "compare_files" && args.size() == 4)
+ {
+ if(cmSystemTools::FilesDiffer(args[2], args[3]))
+ {
+ std::cerr << "Files \""
+ << args[2] << "\" to \"" << args[3]
+ << "\" are different.\n";
+ return 1;
+ }
+ return 0;
+ }
+
+#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
+ else if(args[1] == "__create_def")
+ {
+ if(args.size() < 4)
+ {
+ std::cerr <<
+ "__create_def Usage: -E __create_def outfile.def objlistfile\n";
+ return 1;
+ }
+ FILE* fout = cmsys::SystemTools::Fopen(args[2].c_str(), "w+");
+ if(!fout)
+ {
+ std::cerr << "could not open output .def file: " << args[2].c_str()
+ << "\n";
+ return 1;
+ }
+ cmsys::ifstream fin(args[3].c_str(),
+ std::ios::in | std::ios::binary);
+ if(!fin)
+ {
+ std::cerr << "could not open object list file: " << args[3].c_str()
+ << "\n";
+ return 1;
+ }
+ std::string objfile;
+ bindexplib deffile;
+ while(cmSystemTools::GetLineFromStream(fin, objfile))
+ {
+ if( !deffile.AddObjectFile(objfile.c_str()))
+ {
+ return 1;
+ }
+ }
+ deffile.WriteFile(fout);
+ fclose(fout);
+ return 0;
+ }
+#endif
+ // run include what you use command and then run the compile
+ // command. This is an internal undocumented option and should
+ // only be used by CMake itself when running iwyu.
+ else if (args[1] == "__run_iwyu")
+ {
+ if (args.size() < 3)
+ {
+ std::cerr << "__run_iwyu Usage: -E __run_iwyu [--iwyu=/path/iwyu]"
+ " -- compile command\n";
+ return 1;
+ }
+ bool doing_options = true;
+ std::vector<std::string> orig_cmd;
+ std::string iwyu;
+ for (std::string::size_type cc = 2; cc < args.size(); cc ++)
+ {
+ std::string const& arg = args[cc];
+ if (arg == "--")
+ {
+ doing_options = false;
+ }
+ else if (doing_options && cmHasLiteralPrefix(arg, "--iwyu="))
+ {
+ iwyu = arg.substr(7);
+ }
+ else if (doing_options)
+ {
+ std::cerr << "__run_iwyu given unknown argument: " << arg << "\n";
+ return 1;
+ }
+ else
+ {
+ orig_cmd.push_back(arg);
+ }
+ }
+ if (iwyu.empty())
+ {
+ std::cerr << "__run_iwyu missing --iwyu=\n";
+ return 1;
+ }
+ if (orig_cmd.empty())
+ {
+ std::cerr << "__run_iwyu missing compile command after --\n";
+ return 1;
+ }
+
+ // Construct the iwyu command line by taking what was given
+ // and adding all the arguments we give to the compiler.
+ std::vector<std::string> iwyu_cmd;
+ cmSystemTools::ExpandListArgument(iwyu, iwyu_cmd, true);
+ iwyu_cmd.insert(iwyu_cmd.end(), orig_cmd.begin()+1, orig_cmd.end());
+
+ // Run the iwyu command line. Capture its stderr and hide its stdout.
+ int ret = 0;
+ std::string stdErr;
+ if(!cmSystemTools::RunSingleCommand(iwyu_cmd, 0, &stdErr, &ret,
+ 0, cmSystemTools::OUTPUT_NONE))
+ {
+ std::cerr << "Error running '" << iwyu_cmd[0] << "': "
+ << stdErr << "\n";
+ return 1;
+ }
+
+ // Warn if iwyu reported anything.
+ if(stdErr.find("should remove these lines:") != stdErr.npos
+ || stdErr.find("should add these lines:") != stdErr.npos)
+ {
+ std::cerr << "Warning: include-what-you-use reported diagnostics:\n"
+ << stdErr << "\n";
+ }
+
+ // Now run the real compiler command and return its result value.
+ if(!cmSystemTools::RunSingleCommand(orig_cmd, 0, 0, &ret, 0,
+ cmSystemTools::OUTPUT_PASSTHROUGH))
+ {
+ std::cerr << "Error running '" << orig_cmd[0] << "'\n";
+ return 1;
+ }
+ return ret;
+ }
+
+ // Echo string
+ else if (args[1] == "echo" )
+ {
+ std::cout << cmJoin(cmMakeRange(args).advance(2), " ") << std::endl;
+ return 0;
+ }
+
+ // Echo string no new line
+ else if (args[1] == "echo_append" )
+ {
+ std::cout << cmJoin(cmMakeRange(args).advance(2), " ");
+ return 0;
+ }
+
+ else if (args[1] == "env" )
+ {
+ std::vector<std::string>::const_iterator ai = args.begin() + 2;
+ std::vector<std::string>::const_iterator ae = args.end();
+ for(; ai != ae; ++ai)
+ {
+ std::string const& a = *ai;
+ if(cmHasLiteralPrefix(a, "--unset="))
+ {
+ // Unset environment variable.
+ cmSystemTools::UnPutEnv(a.c_str() + 8);
+ }
+ else if(!a.empty() && a[0] == '-')
+ {
+ // Environment variable and command names cannot start in '-',
+ // so this must be an unknown option.
+ std::cerr << "cmake -E env: unknown option '" << a << "'"
+ << std::endl;
+ return 1;
+ }
+ else if(a.find("=") != a.npos)
+ {
+ // Set environment variable.
+ cmSystemTools::PutEnv(a);
+ }
+ else
+ {
+ // This is the beginning of the command.
+ break;
+ }
+ }
+
+ if(ai == ae)
+ {
+ std::cerr << "cmake -E env: no command given" << std::endl;
+ return 1;
+ }
+
+ // Execute command from remaining arguments.
+ std::vector<std::string> cmd(ai, ae);
+ int retval;
+ if(cmSystemTools::RunSingleCommand(
+ cmd, 0, 0, &retval, NULL, cmSystemTools::OUTPUT_PASSTHROUGH))
+ {
+ return retval;
+ }
+ return 1;
+ }
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ else if (args[1] == "environment" )
+ {
+ std::vector<std::string> env = cmSystemTools::GetEnvironmentVariables();
+ std::vector<std::string>::iterator it;
+ for ( it = env.begin(); it != env.end(); ++ it )
+ {
+ std::cout << *it << std::endl;
+ }
+ return 0;
+ }
+#endif
+
+ else if (args[1] == "make_directory" && args.size() > 2)
+ {
+ // If error occurs we want to continue copying next files.
+ bool return_value = 0;
+ for (std::string::size_type cc = 2; cc < args.size(); cc ++)
+ {
+ if(!cmSystemTools::MakeDirectory(args[cc].c_str()))
+ {
+ std::cerr << "Error creating directory \""
+ << args[cc] << "\".\n";
+ return_value = 1;
+ }
+ }
+ return return_value;
+ }
+
+ else if (args[1] == "remove_directory" && args.size() == 3)
+ {
+ if(cmSystemTools::FileIsDirectory(args[2]) &&
+ !cmSystemTools::RemoveADirectory(args[2]))
+ {
+ std::cerr << "Error removing directory \"" << args[2]
+ << "\".\n";
+ return 1;
+ }
+ return 0;
+ }
+
+ // Remove file
+ else if (args[1] == "remove" && args.size() > 2)
+ {
+ bool force = false;
+ for (std::string::size_type cc = 2; cc < args.size(); cc ++)
+ {
+ if(args[cc] == "\\-f" || args[cc] == "-f")
+ {
+ force = true;
+ }
+ else
+ {
+ // Complain if the file could not be removed, still exists,
+ // and the -f option was not given.
+ if(!cmSystemTools::RemoveFile(args[cc]) && !force &&
+ cmSystemTools::FileExists(args[cc].c_str()))
+ {
+ return 1;
+ }
+ }
+ }
+ return 0;
+ }
+ // Touch file
+ else if (args[1] == "touch" && args.size() > 2)
+ {
+ for (std::string::size_type cc = 2; cc < args.size(); cc ++)
+ {
+ if(!cmSystemTools::Touch(args[cc], true))
+ {
+ return 1;
+ }
+ }
+ return 0;
+ }
+ // Touch file
+ else if (args[1] == "touch_nocreate" && args.size() > 2)
+ {
+ for (std::string::size_type cc = 2; cc < args.size(); cc ++)
+ {
+ // Complain if the file could not be removed, still exists,
+ // and the -f option was not given.
+ if(!cmSystemTools::Touch(args[cc], false))
+ {
+ return 1;
+ }
+ }
+ return 0;
+ }
+
+ // Sleep command
+ else if (args[1] == "sleep" && args.size() > 2)
+ {
+ double total = 0;
+ for(size_t i = 2; i < args.size(); ++i)
+ {
+ double num = 0.0;
+ char unit;
+ char extra;
+ int n = sscanf(args[i].c_str(), "%lg%c%c", &num, &unit, &extra);
+ if((n == 1 || (n == 2 && unit == 's')) && num >= 0)
+ {
+ total += num;
+ }
+ else
+ {
+ std::cerr << "Unknown sleep time format \"" << args[i] << "\".\n";
+ return 1;
+ }
+ }
+ if(total > 0)
+ {
+ cmSystemTools::Delay(static_cast<unsigned int>(total*1000));
+ }
+ return 0;
+ }
+
+ // Clock command
+ else if (args[1] == "time" && args.size() > 2)
+ {
+ std::vector<std::string> command(args.begin()+2, args.end());
+
+ clock_t clock_start, clock_finish;
+ time_t time_start, time_finish;
+
+ time(&time_start);
+ clock_start = clock();
+ int ret =0;
+ cmSystemTools::RunSingleCommand(command, 0, 0, &ret);
+
+ clock_finish = clock();
+ time(&time_finish);
+
+ double clocks_per_sec = static_cast<double>(CLOCKS_PER_SEC);
+ std::cout << "Elapsed time: "
+ << static_cast<long>(time_finish - time_start) << " s. (time)"
+ << ", "
+ << static_cast<double>(clock_finish - clock_start) / clocks_per_sec
+ << " s. (clock)"
+ << "\n";
+ return ret;
+ }
+ // Command to calculate the md5sum of a file
+ else if (args[1] == "md5sum" && args.size() >= 3)
+ {
+ char md5out[32];
+ int retval = 0;
+ for (std::string::size_type cc = 2; cc < args.size(); cc ++)
+ {
+ const char *filename = args[cc].c_str();
+ // Cannot compute md5sum of a directory
+ if(cmSystemTools::FileIsDirectory(filename))
+ {
+ std::cerr << "Error: " << filename << " is a directory" << std::endl;
+ retval++;
+ }
+ else if(!cmSystemTools::ComputeFileMD5(filename, md5out))
+ {
+ // To mimic md5sum behavior in a shell:
+ std::cerr << filename << ": No such file or directory" << std::endl;
+ retval++;
+ }
+ else
+ {
+ std::cout << std::string(md5out,32) << " " << filename << std::endl;
+ }
+ }
+ return retval;
+ }
+
+ // Command to change directory and run a program.
+ else if (args[1] == "chdir" && args.size() >= 4)
+ {
+ std::string directory = args[2];
+ if(!cmSystemTools::FileExists(directory.c_str()))
+ {
+ cmSystemTools::Error("Directory does not exist for chdir command: ",
+ args[2].c_str());
+ return 1;
+ }
+
+ std::string command =
+ cmWrap('"', cmMakeRange(args).advance(3), '"', " ");
+ int retval = 0;
+ int timeout = 0;
+ if ( cmSystemTools::RunSingleCommand(command.c_str(), 0, 0, &retval,
+ directory.c_str(), cmSystemTools::OUTPUT_PASSTHROUGH, timeout) )
+ {
+ return retval;
+ }
+
+ return 1;
+ }
+
+ // Command to start progress for a build
+ else if (args[1] == "cmake_progress_start" && args.size() == 4)
+ {
+ // basically remove the directory
+ std::string dirName = args[2];
+ dirName += "/Progress";
+ cmSystemTools::RemoveADirectory(dirName);
+
+ // is the last argument a filename that exists?
+ FILE *countFile = cmsys::SystemTools::Fopen(args[3],"r");
+ int count;
+ if (countFile)
+ {
+ if (1!=fscanf(countFile,"%i",&count))
+ {
+ cmSystemTools::Message("Could not read from count file.");
+ }
+ fclose(countFile);
+ }
+ else
+ {
+ count = atoi(args[3].c_str());
+ }
+ if (count)
+ {
+ cmSystemTools::MakeDirectory(dirName.c_str());
+ // write the count into the directory
+ std::string fName = dirName;
+ fName += "/count.txt";
+ FILE *progFile = cmsys::SystemTools::Fopen(fName,"w");
+ if (progFile)
+ {
+ fprintf(progFile,"%i\n",count);
+ fclose(progFile);
+ }
+ }
+ return 0;
+ }
+
+ // Command to report progress for a build
+ else if (args[1] == "cmake_progress_report" && args.size() >= 3)
+ {
+ // This has been superseded by cmake_echo_color --progress-*
+ // options. We leave it here to avoid errors if somehow this
+ // is invoked by an existing makefile without regenerating.
+ return 0;
+ }
+
+ // Command to create a symbolic link. Fails on platforms not
+ // supporting them.
+ else if (args[1] == "create_symlink" && args.size() == 4)
+ {
+ const char* destinationFileName = args[3].c_str();
+ if((cmSystemTools::FileExists(destinationFileName) ||
+ cmSystemTools::FileIsSymlink(destinationFileName)) &&
+ !cmSystemTools::RemoveFile(destinationFileName))
+ {
+ std::string emsg = cmSystemTools::GetLastSystemError();
+ std::cerr <<
+ "failed to create symbolic link '" << destinationFileName <<
+ "' because existing path cannot be removed: " << emsg << "\n";
+ return 1;
+ }
+ if(!cmSystemTools::CreateSymlink(args[2], args[3]))
+ {
+ std::string emsg = cmSystemTools::GetLastSystemError();
+ std::cerr <<
+ "failed to create symbolic link '" << destinationFileName <<
+ "': " << emsg << "\n";
+ return 1;
+ }
+ return 0;
+ }
+
+ // Internal CMake shared library support.
+ else if (args[1] == "cmake_symlink_library" && args.size() == 5)
+ {
+ return cmcmd::SymlinkLibrary(args);
+ }
+ // Internal CMake versioned executable support.
+ else if (args[1] == "cmake_symlink_executable" && args.size() == 4)
+ {
+ return cmcmd::SymlinkExecutable(args);
+ }
+
+#if defined(CMAKE_HAVE_VS_GENERATORS)
+ // Internal CMake support for calling Visual Studio macros.
+ else if (args[1] == "cmake_call_visual_studio_macro" && args.size() >= 4)
+ {
+ // args[2] = full path to .sln file or "ALL"
+ // args[3] = name of Visual Studio macro to call
+ // args[4..args.size()-1] = [optional] args for Visual Studio macro
+
+ std::string macroArgs;
+
+ if (args.size() > 4)
+ {
+ macroArgs = args[4];
+
+ for (size_t i = 5; i < args.size(); ++i)
+ {
+ macroArgs += " ";
+ macroArgs += args[i];
+ }
+ }
+
+ return cmCallVisualStudioMacro::CallMacro(args[2], args[3],
+ macroArgs, true);
+ }
+#endif
+
+ // Internal CMake dependency scanning support.
+ else if (args[1] == "cmake_depends" && args.size() >= 6)
+ {
+ // Use the make system's VERBOSE environment variable to enable
+ // verbose output. This can be skipped by also setting CMAKE_NO_VERBOSE
+ // (which is set by the Eclipse and KDevelop generators).
+ bool verbose = ((cmSystemTools::GetEnv("VERBOSE") != 0)
+ && (cmSystemTools::GetEnv("CMAKE_NO_VERBOSE") == 0));
+
+ // Create a cmake object instance to process dependencies.
+ cmake cm;
+ std::string gen;
+ std::string homeDir;
+ std::string startDir;
+ std::string homeOutDir;
+ std::string startOutDir;
+ std::string depInfo;
+ bool color = false;
+ if(args.size() >= 8)
+ {
+ // Full signature:
+ //
+ // -E cmake_depends <generator>
+ // <home-src-dir> <start-src-dir>
+ // <home-out-dir> <start-out-dir>
+ // <dep-info> [--color=$(COLOR)]
+ //
+ // All paths are provided.
+ gen = args[2];
+ homeDir = args[3];
+ startDir = args[4];
+ homeOutDir = args[5];
+ startOutDir = args[6];
+ depInfo = args[7];
+ if(args.size() >= 9 &&
+ args[8].length() >= 8 &&
+ args[8].substr(0, 8) == "--color=")
+ {
+ // Enable or disable color based on the switch value.
+ color = (args[8].size() == 8 ||
+ cmSystemTools::IsOn(args[8].substr(8).c_str()));
+ }
+ }
+ else
+ {
+ // Support older signature for existing makefiles:
+ //
+ // -E cmake_depends <generator>
+ // <home-out-dir> <start-out-dir>
+ // <dep-info>
+ //
+ // Just pretend the source directories are the same as the
+ // binary directories so at least scanning will work.
+ gen = args[2];
+ homeDir = args[3];
+ startDir = args[4];
+ homeOutDir = args[3];
+ startOutDir = args[3];
+ depInfo = args[5];
+ }
+
+ // Create a local generator configured for the directory in
+ // which dependencies will be scanned.
+ homeDir = cmSystemTools::CollapseFullPath(homeDir);
+ startDir = cmSystemTools::CollapseFullPath(startDir);
+ homeOutDir = cmSystemTools::CollapseFullPath(homeOutDir);
+ startOutDir = cmSystemTools::CollapseFullPath(startOutDir);
+ cm.SetHomeDirectory(homeDir);
+ cm.SetHomeOutputDirectory(homeOutDir);
+ cm.GetCurrentSnapshot().SetDefaultDefinitions();
+ if(cmGlobalGenerator* ggd = cm.CreateGlobalGenerator(gen))
+ {
+ cm.SetGlobalGenerator(ggd);
+ cmState::Snapshot snapshot = cm.GetCurrentSnapshot();
+ snapshot.GetDirectory().SetCurrentBinary(startOutDir);
+ snapshot.GetDirectory().SetCurrentSource(startDir);
+ cmsys::auto_ptr<cmMakefile> mf(new cmMakefile(ggd, snapshot));
+ cmsys::auto_ptr<cmLocalGenerator> lgd(
+ ggd->CreateLocalGenerator(mf.get()));
+
+ // Actually scan dependencies.
+ return lgd->UpdateDependencies(depInfo.c_str(),
+ verbose, color)? 0 : 2;
+ }
+ return 1;
+ }
+
+ // Internal CMake link script support.
+ else if (args[1] == "cmake_link_script" && args.size() >= 3)
+ {
+ return cmcmd::ExecuteLinkScript(args);
+ }
+
+ // Internal CMake unimplemented feature notification.
+ else if (args[1] == "cmake_unimplemented_variable")
+ {
+ std::cerr << "Feature not implemented for this platform.";
+ if(args.size() == 3)
+ {
+ std::cerr << " Variable " << args[2] << " is not set.";
+ }
+ std::cerr << std::endl;
+ return 1;
+ }
+ else if (args[1] == "vs_link_exe")
+ {
+ return cmcmd::VisualStudioLink(args, 1);
+ }
+ else if (args[1] == "vs_link_dll")
+ {
+ return cmcmd::VisualStudioLink(args, 2);
+ }
+ // Internal CMake color makefile support.
+ else if (args[1] == "cmake_echo_color")
+ {
+ return cmcmd::ExecuteEchoColor(args);
+ }
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ else if (args[1] == "cmake_autogen" && args.size() >= 4)
+ {
+ cmQtAutoGenerators autogen;
+ std::string const& config = args[3];
+ bool autogenSuccess = autogen.Run(args[2], config);
+ return autogenSuccess ? 0 : 1;
+ }
+#endif
+
+ // Tar files
+ else if (args[1] == "tar" && args.size() > 3)
+ {
+ const char* knownFormats[] =
+ {
+ "7zip",
+ "gnutar",
+ "pax",
+ "paxr",
+ "zip"
+ };
+
+ std::string flags = args[2];
+ std::string outFile = args[3];
+ std::vector<std::string> files;
+ std::string mtime;
+ std::string format;
+ bool doing_options = true;
+ for (std::string::size_type cc = 4; cc < args.size(); cc ++)
+ {
+ std::string const& arg = args[cc];
+ if (doing_options && cmHasLiteralPrefix(arg, "--"))
+ {
+ if (arg == "--")
+ {
+ doing_options = false;
+ }
+ else if (cmHasLiteralPrefix(arg, "--mtime="))
+ {
+ mtime = arg.substr(8);
+ }
+ else if (cmHasLiteralPrefix(arg, "--files-from="))
+ {
+ std::string const& files_from = arg.substr(13);
+ if (!cmTarFilesFrom(files_from, files))
+ {
+ return 1;
+ }
+ }
+ else if (cmHasLiteralPrefix(arg, "--format="))
+ {
+ format = arg.substr(9);
+ bool isKnown = std::find(cmArrayBegin(knownFormats),
+ cmArrayEnd(knownFormats), format) != cmArrayEnd(knownFormats);
+
+ if(!isKnown)
+ {
+ cmSystemTools::Error("Unknown -E tar --format= argument: ",
+ format.c_str());
+ return 1;
+ }
+ }
+ else
+ {
+ cmSystemTools::Error("Unknown option to -E tar: ", arg.c_str());
+ return 1;
+ }
+ }
+ else
+ {
+ files.push_back(arg);
+ }
+ }
+ cmSystemTools::cmTarCompression compress =
+ cmSystemTools::TarCompressNone;
+ bool verbose = false;
+ int nCompress = 0;
+ if ( flags.find_first_of('j') != flags.npos )
+ {
+ compress = cmSystemTools::TarCompressBZip2;
+ ++nCompress;
+ }
+ if ( flags.find_first_of('J') != flags.npos )
+ {
+ compress = cmSystemTools::TarCompressXZ;
+ ++nCompress;
+ }
+ if ( flags.find_first_of('z') != flags.npos )
+ {
+ compress = cmSystemTools::TarCompressGZip;
+ ++nCompress;
+ }
+ if ( (format == "7zip" || format == "zip") && nCompress > 0 )
+ {
+ cmSystemTools::Error("Can not use compression flags with format: ",
+ format.c_str());
+ return 1;
+ }
+ else if ( nCompress > 1 )
+ {
+ cmSystemTools::Error("Can only compress a tar file one way; "
+ "at most one flag of z, j, or J may be used");
+ return 1;
+ }
+ if ( flags.find_first_of('v') != flags.npos )
+ {
+ verbose = true;
+ }
+
+ if ( flags.find_first_of('t') != flags.npos )
+ {
+ if ( !cmSystemTools::ListTar(outFile.c_str(), verbose) )
+ {
+ cmSystemTools::Error("Problem listing tar: ", outFile.c_str());
+ return 1;
+ }
+ }
+ else if ( flags.find_first_of('c') != flags.npos )
+ {
+ if ( !cmSystemTools::CreateTar(
+ outFile.c_str(), files, compress, verbose, mtime, format) )
+ {
+ cmSystemTools::Error("Problem creating tar: ", outFile.c_str());
+ return 1;
+ }
+ }
+ else if ( flags.find_first_of('x') != flags.npos )
+ {
+ if ( !cmSystemTools::ExtractTar(
+ outFile.c_str(), verbose) )
+ {
+ cmSystemTools::Error("Problem extracting tar: ", outFile.c_str());
+ return 1;
+ }
+#ifdef WIN32
+ // OK, on windows 7 after we untar some files,
+ // sometimes we can not rename the directory after
+ // the untar is done. This breaks the external project
+ // untar and rename code. So, by default we will wait
+ // 1/10th of a second after the untar. If CMAKE_UNTAR_DELAY
+ // is set in the env, its value will be used instead of 100.
+ int delay = 100;
+ const char* delayVar = cmSystemTools::GetEnv("CMAKE_UNTAR_DELAY");
+ if(delayVar)
+ {
+ delay = atoi(delayVar);
+ }
+ if(delay)
+ {
+ cmSystemTools::Delay(delay);
+ }
+#endif
+ }
+ return 0;
+ }
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ // Internal CMake Fortran module support.
+ else if (args[1] == "cmake_copy_f90_mod" && args.size() >= 4)
+ {
+ return cmDependsFortran::CopyModule(args)? 0 : 1;
+ }
+#endif
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ // Write registry value
+ else if (args[1] == "write_regv" && args.size() > 3)
+ {
+ return cmSystemTools::WriteRegistryValue(args[2].c_str(),
+ args[3].c_str()) ? 0 : 1;
+ }
+
+ // Delete registry value
+ else if (args[1] == "delete_regv" && args.size() > 2)
+ {
+ return cmSystemTools::DeleteRegistryValue(args[2].c_str()) ? 0 : 1;
+ }
+ // Remove file
+ else if (args[1] == "comspec" && args.size() > 2)
+ {
+ std::cerr << "Win9x helper \"cmake -E comspec\" no longer supported\n";
+ return 1;
+ }
+ else if (args[1] == "env_vs8_wince" && args.size() == 3)
+ {
+ return cmcmd::WindowsCEEnvironment("8.0", args[2]);
+ }
+ else if (args[1] == "env_vs9_wince" && args.size() == 3)
+ {
+ return cmcmd::WindowsCEEnvironment("9.0", args[2]);
+ }
+#endif
+ }
+
+ ::CMakeCommandUsage(args[0].c_str());
+ return 1;
+}
+
+//----------------------------------------------------------------------------
+int cmcmd::SymlinkLibrary(std::vector<std::string>& args)
+{
+ int result = 0;
+ std::string realName = args[2];
+ std::string soName = args[3];
+ std::string name = args[4];
+ if(soName != realName)
+ {
+ if(!cmcmd::SymlinkInternal(realName, soName))
+ {
+ cmSystemTools::ReportLastSystemError("cmake_symlink_library");
+ result = 1;
+ }
+ }
+ if(name != soName)
+ {
+ if(!cmcmd::SymlinkInternal(soName, name))
+ {
+ cmSystemTools::ReportLastSystemError("cmake_symlink_library");
+ result = 1;
+ }
+ }
+ return result;
+}
+
+//----------------------------------------------------------------------------
+int cmcmd::SymlinkExecutable(std::vector<std::string>& args)
+{
+ int result = 0;
+ std::string realName = args[2];
+ std::string name = args[3];
+ if(name != realName)
+ {
+ if(!cmcmd::SymlinkInternal(realName, name))
+ {
+ cmSystemTools::ReportLastSystemError("cmake_symlink_executable");
+ result = 1;
+ }
+ }
+ return result;
+}
+
+//----------------------------------------------------------------------------
+bool cmcmd::SymlinkInternal(std::string const& file, std::string const& link)
+{
+ if(cmSystemTools::FileExists(link.c_str()) ||
+ cmSystemTools::FileIsSymlink(link))
+ {
+ cmSystemTools::RemoveFile(link);
+ }
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ return cmSystemTools::CopyFileAlways(file.c_str(), link.c_str());
+#else
+ std::string linktext = cmSystemTools::GetFilenameName(file);
+ return cmSystemTools::CreateSymlink(linktext, link);
+#endif
+}
+
+//----------------------------------------------------------------------------
+static void cmcmdProgressReport(std::string const& dir,
+ std::string const& num)
+{
+ std::string dirName = dir;
+ dirName += "/Progress";
+ std::string fName;
+ FILE *progFile;
+
+ // read the count
+ fName = dirName;
+ fName += "/count.txt";
+ progFile = cmsys::SystemTools::Fopen(fName,"r");
+ int count = 0;
+ if (!progFile)
+ {
+ return;
+ }
+ else
+ {
+ if (1!=fscanf(progFile,"%i",&count))
+ {
+ cmSystemTools::Message("Could not read from progress file.");
+ }
+ fclose(progFile);
+ }
+ const char* last = num.c_str();
+ for(const char* c = last;; ++c)
+ {
+ if (*c == ',' || *c == '\0')
+ {
+ if (c != last)
+ {
+ fName = dirName;
+ fName += "/";
+ fName.append(last, c-last);
+ progFile = cmsys::SystemTools::Fopen(fName,"w");
+ if (progFile)
+ {
+ fprintf(progFile,"empty");
+ fclose(progFile);
+ }
+ }
+ if(*c == '\0')
+ {
+ break;
+ }
+ last = c + 1;
+ }
+ }
+ int fileNum = static_cast<int>
+ (cmsys::Directory::GetNumberOfFilesInDirectory(dirName));
+ if (count > 0)
+ {
+ // print the progress
+ fprintf(stdout,"[%3i%%] ",((fileNum-3)*100)/count);
+ }
+}
+
+//----------------------------------------------------------------------------
+int cmcmd::ExecuteEchoColor(std::vector<std::string>& args)
+{
+ // The arguments are
+ // argv[0] == <cmake-executable>
+ // argv[1] == cmake_echo_color
+
+ bool enabled = true;
+ int color = cmsysTerminal_Color_Normal;
+ bool newline = true;
+ std::string progressDir;
+ for(unsigned int i=2; i < args.size(); ++i)
+ {
+ if(args[i].find("--switch=") == 0)
+ {
+ // Enable or disable color based on the switch value.
+ std::string value = args[i].substr(9);
+ if(!value.empty())
+ {
+ if(cmSystemTools::IsOn(value.c_str()))
+ {
+ enabled = true;
+ }
+ else
+ {
+ enabled = false;
+ }
+ }
+ }
+ else if(cmHasLiteralPrefix(args[i], "--progress-dir="))
+ {
+ progressDir = args[i].substr(15);
+ }
+ else if(cmHasLiteralPrefix(args[i], "--progress-num="))
+ {
+ if (!progressDir.empty())
+ {
+ std::string const& progressNum = args[i].substr(15);
+ cmcmdProgressReport(progressDir, progressNum);
+ }
+ }
+ else if(args[i] == "--normal")
+ {
+ color = cmsysTerminal_Color_Normal;
+ }
+ else if(args[i] == "--black")
+ {
+ color = cmsysTerminal_Color_ForegroundBlack;
+ }
+ else if(args[i] == "--red")
+ {
+ color = cmsysTerminal_Color_ForegroundRed;
+ }
+ else if(args[i] == "--green")
+ {
+ color = cmsysTerminal_Color_ForegroundGreen;
+ }
+ else if(args[i] == "--yellow")
+ {
+ color = cmsysTerminal_Color_ForegroundYellow;
+ }
+ else if(args[i] == "--blue")
+ {
+ color = cmsysTerminal_Color_ForegroundBlue;
+ }
+ else if(args[i] == "--magenta")
+ {
+ color = cmsysTerminal_Color_ForegroundMagenta;
+ }
+ else if(args[i] == "--cyan")
+ {
+ color = cmsysTerminal_Color_ForegroundCyan;
+ }
+ else if(args[i] == "--white")
+ {
+ color = cmsysTerminal_Color_ForegroundWhite;
+ }
+ else if(args[i] == "--bold")
+ {
+ color |= cmsysTerminal_Color_ForegroundBold;
+ }
+ else if(args[i] == "--no-newline")
+ {
+ newline = false;
+ }
+ else if(args[i] == "--newline")
+ {
+ newline = true;
+ }
+ else
+ {
+ // Color is enabled. Print with the current color.
+ cmSystemTools::MakefileColorEcho(color, args[i].c_str(),
+ newline, enabled);
+ }
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+int cmcmd::ExecuteLinkScript(std::vector<std::string>& args)
+{
+ // The arguments are
+ // argv[0] == <cmake-executable>
+ // argv[1] == cmake_link_script
+ // argv[2] == <link-script-name>
+ // argv[3] == --verbose=?
+ bool verbose = false;
+ if(args.size() >= 4)
+ {
+ if(args[3].find("--verbose=") == 0)
+ {
+ if(!cmSystemTools::IsOff(args[3].substr(10).c_str()))
+ {
+ verbose = true;
+ }
+ }
+ }
+
+ // Allocate a process instance.
+ cmsysProcess* cp = cmsysProcess_New();
+ if(!cp)
+ {
+ std::cerr << "Error allocating process instance in link script."
+ << std::endl;
+ return 1;
+ }
+
+ // Children should share stdout and stderr with this process.
+ cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDOUT, 1);
+ cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDERR, 1);
+
+ // Run the command lines verbatim.
+ cmsysProcess_SetOption(cp, cmsysProcess_Option_Verbatim, 1);
+
+ // Read command lines from the script.
+ cmsys::ifstream fin(args[2].c_str());
+ if(!fin)
+ {
+ std::cerr << "Error opening link script \""
+ << args[2] << "\"" << std::endl;
+ return 1;
+ }
+
+ // Run one command at a time.
+ std::string command;
+ int result = 0;
+ while(result == 0 && cmSystemTools::GetLineFromStream(fin, command))
+ {
+ // Skip empty command lines.
+ if(command.find_first_not_of(" \t") == command.npos)
+ {
+ continue;
+ }
+
+ // Setup this command line.
+ const char* cmd[2] = {command.c_str(), 0};
+ cmsysProcess_SetCommand(cp, cmd);
+
+ // Report the command if verbose output is enabled.
+ if(verbose)
+ {
+ std::cout << command << std::endl;
+ }
+
+ // Run the command and wait for it to exit.
+ cmsysProcess_Execute(cp);
+ cmsysProcess_WaitForExit(cp, 0);
+
+ // Report failure if any.
+ switch(cmsysProcess_GetState(cp))
+ {
+ case cmsysProcess_State_Exited:
+ {
+ int value = cmsysProcess_GetExitValue(cp);
+ if(value != 0)
+ {
+ result = value;
+ }
+ }
+ break;
+ case cmsysProcess_State_Exception:
+ std::cerr << "Error running link command: "
+ << cmsysProcess_GetExceptionString(cp) << std::endl;
+ result = 1;
+ break;
+ case cmsysProcess_State_Error:
+ std::cerr << "Error running link command: "
+ << cmsysProcess_GetErrorString(cp) << std::endl;
+ result = 2;
+ break;
+ default:
+ break;
+ };
+ }
+
+ // Free the process instance.
+ cmsysProcess_Delete(cp);
+
+ // Return the final resulting return value.
+ return result;
+}
+
+//----------------------------------------------------------------------------
+int cmcmd::WindowsCEEnvironment(const char* version, const std::string& name)
+{
+#if defined(CMAKE_HAVE_VS_GENERATORS)
+ cmVisualStudioWCEPlatformParser parser(name.c_str());
+ parser.ParseVersion(version);
+ if (parser.Found())
+ {
+ std::cout << "@echo off" << std::endl;
+ std::cout << "echo Environment Selection: " << name << std::endl;
+ std::cout << "set PATH=" << parser.GetPathDirectories() << std::endl;
+ std::cout << "set INCLUDE=" << parser.GetIncludeDirectories() <<std::endl;
+ std::cout << "set LIB=" << parser.GetLibraryDirectories() <<std::endl;
+ return 0;
+ }
+#else
+ (void)version;
+#endif
+
+ std::cerr << "Could not find " << name;
+ return -1;
+}
+
+class cmVSLink
+{
+ int Type;
+ bool Verbose;
+ bool Incremental;
+ bool LinkGeneratesManifest;
+ std::vector<std::string> LinkCommand;
+ std::vector<std::string> UserManifests;
+ std::string LinkerManifestFile;
+ std::string ManifestFile;
+ std::string ManifestFileRC;
+ std::string ManifestFileRes;
+ std::string TargetFile;
+public:
+ cmVSLink(int type, bool verbose)
+ : Type(type)
+ , Verbose(verbose)
+ , Incremental(false)
+ , LinkGeneratesManifest(true)
+ {}
+ bool Parse(std::vector<std::string>::const_iterator argBeg,
+ std::vector<std::string>::const_iterator argEnd);
+ int Link();
+private:
+ int LinkIncremental();
+ int LinkNonIncremental();
+ int RunMT(std::string const& out, bool notify);
+};
+
+// For visual studio 2005 and newer manifest files need to be embedded into
+// exe and dll's. This code does that in such a way that incremental linking
+// still works.
+int cmcmd::VisualStudioLink(std::vector<std::string>& args, int type)
+{
+ if(args.size() < 2)
+ {
+ return -1;
+ }
+ bool verbose = cmSystemTools::GetEnv("VERBOSE")? true:false;
+ std::vector<std::string> expandedArgs;
+ for(std::vector<std::string>::iterator i = args.begin();
+ i != args.end(); ++i)
+ {
+ // check for nmake temporary files
+ if((*i)[0] == '@' && i->find("@CMakeFiles") != 0 )
+ {
+ cmsys::ifstream fin(i->substr(1).c_str());
+ std::string line;
+ while(cmSystemTools::GetLineFromStream(fin,
+ line))
+ {
+ cmSystemTools::ParseWindowsCommandLine(line.c_str(), expandedArgs);
+ }
+ }
+ else
+ {
+ expandedArgs.push_back(*i);
+ }
+ }
+
+ cmVSLink vsLink(type, verbose);
+ if (!vsLink.Parse(expandedArgs.begin()+2, expandedArgs.end()))
+ {
+ return -1;
+ }
+ return vsLink.Link();
+}
+
+static bool RunCommand(const char* comment,
+ std::vector<std::string>& command,
+ bool verbose,
+ int* retCodeOut = 0)
+{
+ if(verbose)
+ {
+ std::cout << comment << ":\n";
+ std::cout << cmJoin(command, " ") << "\n";
+ }
+ std::string output;
+ int retCode =0;
+ // use rc command to create .res file
+ bool res = cmSystemTools::RunSingleCommand(command,
+ &output, &output,
+ &retCode, 0,
+ cmSystemTools::OUTPUT_NONE);
+ // always print the output of the command, unless
+ // it is the dumb rc command banner, but if the command
+ // returned an error code then print the output anyway as
+ // the banner may be mixed with some other important information.
+ if(output.find("Resource Compiler Version") == output.npos
+ || !res || retCode)
+ {
+ std::cout << output;
+ }
+ if (!res)
+ {
+ std::cout << comment << " failed to run." << std::endl;
+ return false;
+ }
+ // if retCodeOut is requested then always return true
+ // and set the retCodeOut to retCode
+ if(retCodeOut)
+ {
+ *retCodeOut = retCode;
+ return true;
+ }
+ if(retCode != 0)
+ {
+ std::cout << comment << " failed. with " << retCode << "\n";
+ }
+ return retCode == 0;
+}
+
+bool cmVSLink::Parse(std::vector<std::string>::const_iterator argBeg,
+ std::vector<std::string>::const_iterator argEnd)
+{
+ // Parse our own arguments.
+ std::string intDir;
+ std::vector<std::string>::const_iterator arg = argBeg;
+ while (arg != argEnd && cmHasLiteralPrefix(*arg, "-"))
+ {
+ if (*arg == "--")
+ {
+ ++arg;
+ break;
+ }
+ else if (*arg == "--manifests")
+ {
+ for (++arg; arg != argEnd && !cmHasLiteralPrefix(*arg, "-"); ++arg)
+ {
+ this->UserManifests.push_back(*arg);
+ }
+ }
+ else if (cmHasLiteralPrefix(*arg, "--intdir="))
+ {
+ intDir = arg->substr(9);
+ ++arg;
+ }
+ else
+ {
+ std::cerr << "unknown argument '" << *arg << "'\n";
+ return false;
+ }
+ }
+ if (intDir.empty())
+ {
+ return false;
+ }
+
+ // The rest of the arguments form the link command.
+ if (arg == argEnd)
+ {
+ return false;
+ }
+ this->LinkCommand.insert(this->LinkCommand.begin(), arg, argEnd);
+
+ // Parse the link command to extract information we need.
+ for (; arg != argEnd; ++arg)
+ {
+ if (cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL:YES") == 0)
+ {
+ this->Incremental = true;
+ }
+ else if (cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL") == 0)
+ {
+ this->Incremental = true;
+ }
+ else if (cmSystemTools::Strucmp(arg->c_str(), "/MANIFEST:NO") == 0)
+ {
+ this->LinkGeneratesManifest = false;
+ }
+ else if (cmHasLiteralPrefix(*arg, "/Fe"))
+ {
+ this->TargetFile = arg->substr(3);
+ }
+ else if (cmHasLiteralPrefix(*arg, "/out:"))
+ {
+ this->TargetFile = arg->substr(5);
+ }
+ }
+
+ if (this->TargetFile.empty())
+ {
+ return false;
+ }
+
+ this->ManifestFile = intDir + "/embed.manifest";
+ this->LinkerManifestFile = intDir + "/intermediate.manifest";
+
+ if (this->Incremental)
+ {
+ // We will compile a resource containing the manifest and
+ // pass it to the link command.
+ this->ManifestFileRC = intDir + "/manifest.rc";
+ this->ManifestFileRes = intDir + "/manifest.res";
+ }
+ else if (this->UserManifests.empty())
+ {
+ // Prior to support for user-specified manifests CMake placed the
+ // linker-generated manifest next to the binary (as if it were not to be
+ // embedded) when not linking incrementally. Preserve this behavior.
+ this->ManifestFile = this->TargetFile + ".manifest";
+ this->LinkerManifestFile = this->ManifestFile;
+ }
+
+ if (this->LinkGeneratesManifest)
+ {
+ this->LinkCommand.push_back("/MANIFEST");
+ this->LinkCommand.push_back("/MANIFESTFILE:" + this->LinkerManifestFile);
+ }
+
+ return true;
+}
+
+int cmVSLink::Link()
+{
+ if (this->Incremental &&
+ (this->LinkGeneratesManifest || !this->UserManifests.empty()))
+ {
+ if (this->Verbose)
+ {
+ std::cout << "Visual Studio Incremental Link with embedded manifests\n";
+ }
+ return LinkIncremental();
+ }
+ if (this->Verbose)
+ {
+ if (!this->Incremental)
+ {
+ std::cout << "Visual Studio Non-Incremental Link\n";
+ }
+ else
+ {
+ std::cout << "Visual Studio Incremental Link without manifests\n";
+ }
+ }
+ return LinkNonIncremental();
+}
+
+int cmVSLink::LinkIncremental()
+{
+ // This follows the steps listed here:
+ // http://blogs.msdn.com/zakramer/archive/2006/05/22/603558.aspx
+
+ // 1. Compiler compiles the application and generates the *.obj files.
+ // 2. An empty manifest file is generated if this is a clean build and if
+ // not the previous one is reused.
+ // 3. The resource compiler (rc.exe) compiles the *.manifest file to a
+ // *.res file.
+ // 4. Linker generates the binary (EXE or DLL) with the /incremental
+ // switch and embeds the dummy manifest file. The linker also generates
+ // the real manifest file based on the binaries that your binary depends
+ // on.
+ // 5. The manifest tool (mt.exe) is then used to generate the final
+ // manifest.
+
+ // If the final manifest is changed, then 6 and 7 are run, if not
+ // they are skipped, and it is done.
+
+ // 6. The resource compiler is invoked one more time.
+ // 7. Finally, the Linker does another incremental link, but since the
+ // only thing that has changed is the *.res file that contains the
+ // manifest it is a short link.
+
+ // Create a resource file referencing the manifest.
+ std::string absManifestFile =
+ cmSystemTools::CollapseFullPath(this->ManifestFile);
+ if (this->Verbose)
+ {
+ std::cout << "Create " << this->ManifestFileRC << "\n";
+ }
+ {
+ cmsys::ofstream fout(this->ManifestFileRC.c_str());
+ if (!fout)
+ {
+ return -1;
+ }
+ fout << this->Type << " /* CREATEPROCESS_MANIFEST_RESOURCE_ID */ "
+ "24 /* RT_MANIFEST */ \"" << absManifestFile << "\"";
+ }
+
+ // If we have not previously generated a manifest file,
+ // generate an empty one so the resource compiler succeeds.
+ if (!cmSystemTools::FileExists(this->ManifestFile))
+ {
+ if (this->Verbose)
+ {
+ std::cout << "Create empty: " << this->ManifestFile << "\n";
+ }
+ cmsys::ofstream foutTmp(this->ManifestFile.c_str());
+ }
+
+ // Compile the resource file.
+ std::vector<std::string> rcCommand;
+ rcCommand.push_back(cmSystemTools::FindProgram("rc.exe"));
+ rcCommand.push_back("/fo" + this->ManifestFileRes);
+ rcCommand.push_back(this->ManifestFileRC);
+ if (!RunCommand("RC Pass 1", rcCommand, this->Verbose))
+ {
+ return -1;
+ }
+
+ // Tell the linker to use our manifest compiled into a resource.
+ this->LinkCommand.push_back(this->ManifestFileRes);
+
+ // Run the link command (possibly generates intermediate manifest).
+ if (!RunCommand("LINK Pass 1", this->LinkCommand, this->Verbose))
+ {
+ return -1;
+ }
+
+ // Run the manifest tool to create the final manifest.
+ int mtRet = this->RunMT("/out:" + this->ManifestFile, true);
+
+ // If mt returns 1090650113 (or 187 on a posix host) then it updated the
+ // manifest file so we need to embed it again. Otherwise we are done.
+ if (mtRet != 1090650113 && mtRet != 187)
+ {
+ return mtRet;
+ }
+
+ // Compile the resource file again.
+ if (!RunCommand("RC Pass 2", rcCommand, this->Verbose))
+ {
+ return -1;
+ }
+
+ // Link incrementally again to use the updated resource.
+ if (!RunCommand("FINAL LINK", this->LinkCommand, this->Verbose))
+ {
+ return -1;
+ }
+ return 0;
+}
+
+int cmVSLink::LinkNonIncremental()
+{
+ // Run the link command (possibly generates intermediate manifest).
+ if (!RunCommand("LINK", this->LinkCommand, this->Verbose))
+ {
+ return -1;
+ }
+
+ // If we have no manifest files we are done.
+ if (!this->LinkGeneratesManifest && this->UserManifests.empty())
+ {
+ return 0;
+ }
+
+ // Run the manifest tool to embed the final manifest in the binary.
+ std::string mtOut =
+ "/outputresource:" + this->TargetFile + (this->Type == 1? ";#1" : ";#2");
+ return this->RunMT(mtOut, false);
+}
+
+int cmVSLink::RunMT(std::string const& out, bool notify)
+{
+ std::vector<std::string> mtCommand;
+ mtCommand.push_back(cmSystemTools::FindProgram("mt.exe"));
+ mtCommand.push_back("/nologo");
+ mtCommand.push_back("/manifest");
+ if (this->LinkGeneratesManifest)
+ {
+ mtCommand.push_back(this->LinkerManifestFile);
+ }
+ mtCommand.insert(mtCommand.end(),
+ this->UserManifests.begin(), this->UserManifests.end());
+ mtCommand.push_back(out);
+ if (notify)
+ {
+ // Add an undocumented option that enables a special return
+ // code to notify us when the manifest is modified.
+ mtCommand.push_back("/notify_update");
+ }
+ int mtRet = 0;
+ if (!RunCommand("MT", mtCommand, this->Verbose, &mtRet))
+ {
+ return -1;
+ }
+ return mtRet;
+}
diff --git a/Source/cmcmd.h b/Source/cmcmd.h
new file mode 100644
index 000000000..64b240623
--- /dev/null
+++ b/Source/cmcmd.h
@@ -0,0 +1,40 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmcmd_h
+#define cmcmd_h
+
+#include "cmStandardIncludes.h"
+
+class cmcmd
+{
+public:
+
+ /**
+ * Execute commands during the build process. Supports options such
+ * as echo, remove file etc.
+ */
+ static int ExecuteCMakeCommand(std::vector<std::string>&);
+protected:
+
+ static int SymlinkLibrary(std::vector<std::string>& args);
+ static int SymlinkExecutable(std::vector<std::string>& args);
+ static bool SymlinkInternal(std::string const& file,
+ std::string const& link);
+ static int ExecuteEchoColor(std::vector<std::string>& args);
+ static int ExecuteLinkScript(std::vector<std::string>& args);
+ static int WindowsCEEnvironment(const char* version,
+ const std::string& name);
+ static int VisualStudioLink(std::vector<std::string>& args, int type);
+};
+
+#endif
diff --git a/Source/cmparseMSBuildXML.py b/Source/cmparseMSBuildXML.py
index d1b61ef6a..056a0db0f 100755
--- a/Source/cmparseMSBuildXML.py
+++ b/Source/cmparseMSBuildXML.py
@@ -12,6 +12,9 @@
# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/v120/1033/cl.xml"
# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/v120/1033/lib.xml"
# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/v120/1033/link.xml"
+# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/V140/1033/cl.xml"
+# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/V140/1033/lib.xml"
+# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/V140/1033/link.xml"
#
# BoolProperty <Name>true|false</Name>
# simple example:
diff --git a/Source/cmw9xcom.cxx b/Source/cmw9xcom.cxx
deleted file mode 100644
index ab238d539..000000000
--- a/Source/cmw9xcom.cxx
+++ /dev/null
@@ -1,45 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#include "cmSystemTools.h"
-#include "cmWin32ProcessExecution.h"
-
-// this is a test driver program for cmake.
-int main (int argc, char *argv[])
-{
- cmSystemTools::EnableMSVCDebugHook();
- if ( argc <= 1 )
- {
- std::cerr << "Usage: " << argv[0] << " executable" << std::endl;
- return 1;
- }
- std::string arg = argv[1];
- if ( (arg.find_first_of(" ") != arg.npos) &&
- (arg.find_first_of("\"") == arg.npos) )
- {
- arg = "\"" + arg + "\"";
- }
- std::string command = arg;
- int cc;
- for ( cc = 2; cc < argc; cc ++ )
- {
- std::string nextArg = argv[cc];
- if ( (nextArg.find_first_of(" ") != nextArg.npos) &&
- (nextArg.find_first_of("\"") == nextArg.npos) )
- {
- nextArg = "\"" + nextArg + "\"";
- }
- command += " ";
- command += nextArg;
- }
-
- return cmWin32ProcessExecution::Windows9xHack(command.c_str());
-}
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
index e767a1612..7fa6aed8e 100644
--- a/Source/ctest.cxx
+++ b/Source/ctest.cxx
@@ -18,256 +18,119 @@
#include "CTest/cmCTestScriptHandler.h"
#include "CTest/cmCTestLaunch.h"
+#include "cmsys/Encoding.hxx"
//----------------------------------------------------------------------------
-static const char * cmDocumentationName[][3] =
+static const char * cmDocumentationName[][2] =
{
{0,
- " ctest - Testing driver provided by CMake.", 0},
- {0,0,0}
+ " ctest - Testing driver provided by CMake."},
+ {0,0}
};
//----------------------------------------------------------------------------
-static const char * cmDocumentationUsage[][3] =
+static const char * cmDocumentationUsage[][2] =
{
{0,
- " ctest [options]", 0},
- {0,0,0}
+ " ctest [options]"},
+ {0,0}
};
//----------------------------------------------------------------------------
-static const char * cmDocumentationDescription[][3] =
-{
- {0,
- "The \"ctest\" executable is the CMake test driver program. "
- "CMake-generated build trees created for projects that use "
- "the ENABLE_TESTING and ADD_TEST commands have testing support. "
- "This program will run the tests and report results.", 0},
- {0,0,0}
-};
-
//----------------------------------------------------------------------------
-static const char * cmDocumentationOptions[][3] =
+static const char * cmDocumentationOptions[][2] =
{
- {"-C <cfg>, --build-config <cfg>", "Choose configuration to test.",
- "Some CMake-generated build trees can have multiple build configurations "
- "in the same tree. This option can be used to specify which one should "
- "be tested. Example configurations are \"Debug\" and \"Release\"."},
- {"-V,--verbose", "Enable verbose output from tests.",
- "Test output is normally suppressed and only summary information is "
- "displayed. This option will show all test output."},
- {"-VV,--extra-verbose", "Enable more verbose output from tests.",
- "Test output is normally suppressed and only summary information is "
- "displayed. This option will show even more test output."},
- {"--debug", "Displaying more verbose internals of CTest.",
- "This feature will result in a large number of output that is mostly "
- "useful for debugging dashboard problems."},
+ {"-C <cfg>, --build-config <cfg>", "Choose configuration to test."},
+ {"-V,--verbose", "Enable verbose output from tests."},
+ {"-VV,--extra-verbose", "Enable more verbose output from tests."},
+ {"--debug", "Displaying more verbose internals of CTest."},
{"--output-on-failure", "Output anything outputted by the test program "
- "if the test should fail. This option can also be enabled by setting "
- "the environment variable CTEST_OUTPUT_ON_FAILURE"},
- {"-F", "Enable failover.", "This option allows ctest to resume a test "
- "set execution that was previously interrupted. If no interruption "
- "occurred, the -F option will have no effect."},
- {"-j <jobs>, --parallel <jobs>", "Run the tests in parallel using the"
- "given number of jobs.",
- "This option tells ctest to run the tests in parallel using given "
- "number of jobs. This option can also be set by setting "
- "the environment variable CTEST_PARALLEL_LEVEL."},
- {"-Q,--quiet", "Make ctest quiet.",
- "This option will suppress all the output. The output log file will "
- "still be generated if the --output-log is specified. Options such "
- "as --verbose, --extra-verbose, and --debug are ignored if --quiet is "
- "specified."},
- {"-O <file>, --output-log <file>", "Output to log file",
- "This option tells ctest to write all its output to a log file."},
- {"-N,--show-only", "Disable actual execution of tests.",
- "This option tells ctest to list the tests that would be run but not "
- "actually run them. Useful in conjunction with the -R and -E options."},
+ "if the test should fail."},
+ {"--test-output-size-passed <size>", "Limit the output for passed tests "
+ "to <size> bytes"},
+ {"--test-output-size-failed <size>", "Limit the output for failed tests "
+ "to <size> bytes"},
+ {"-F", "Enable failover."},
+ {"-j <jobs>, --parallel <jobs>", "Run the tests in parallel using the "
+ "given number of jobs."},
+ {"-Q,--quiet", "Make ctest quiet."},
+ {"-O <file>, --output-log <file>", "Output to log file"},
+ {"-N,--show-only", "Disable actual execution of tests."},
{"-L <regex>, --label-regex <regex>", "Run tests with labels matching "
- "regular expression.",
- "This option tells ctest to run only the tests whose labels match the "
- "given regular expression."},
+ "regular expression."},
{"-R <regex>, --tests-regex <regex>", "Run tests matching regular "
- "expression.",
- "This option tells ctest to run only the tests whose names match the "
- "given regular expression."},
+ "expression."},
{"-E <regex>, --exclude-regex <regex>", "Exclude tests matching regular "
- "expression.",
- "This option tells ctest to NOT run the tests whose names match the "
- "given regular expression."},
+ "expression."},
{"-LE <regex>, --label-exclude <regex>", "Exclude tests with labels "
- "matching regular expression.",
- "This option tells ctest to NOT run the tests whose labels match the "
- "given regular expression."},
- {"-D <dashboard>, --dashboard <dashboard>", "Execute dashboard test",
- "This option tells ctest to act as a Dart client and perform "
- "a dashboard test. All tests are <Mode><Test>, where Mode can be "
- "Experimental, Nightly, and Continuous, and Test can be Start, Update, "
- "Configure, Build, Test, Coverage, and Submit."},
- {"-D <var>:<type>=<value>", "Define a variable for script mode",
- "Pass in variable values on the command line. Use in "
- "conjunction with -S to pass variable values to a dashboard script. "
- "Parsing -D arguments as variable values is only attempted if "
- "the value following -D does not match any of the known dashboard "
- "types."},
- {"-M <model>, --test-model <model>", "Sets the model for a dashboard",
- "This option tells ctest to act as a Dart client "
- "where the TestModel can be Experimental, "
- "Nightly, and Continuous. Combining -M and -T is similar to -D"},
+ "matching regular expression."},
+ {"-D <dashboard>, --dashboard <dashboard>", "Execute dashboard test"},
+ {"-D <var>:<type>=<value>", "Define a variable for script mode"},
+ {"-M <model>, --test-model <model>", "Sets the model for a dashboard"},
{"-T <action>, --test-action <action>", "Sets the dashboard action to "
- "perform",
- "This option tells ctest to act as a Dart client "
- "and perform some action such as start, build, test etc. "
- "Combining -M and -T is similar to -D"},
- {"--track <track>", "Specify the track to submit dashboard to",
- "Submit dashboard to specified track instead of default one. By "
- "default, the dashboard is submitted to Nightly, Experimental, or "
- "Continuous track, but by specifying this option, the track can be "
- "arbitrary."},
+ "perform"},
+ {"--track <track>", "Specify the track to submit dashboard to"},
{"-S <script>, --script <script>", "Execute a dashboard for a "
- "configuration",
- "This option tells ctest to load in a configuration script which sets "
- "a number of parameters such as the binary and source directories. Then "
- "ctest will do what is required to create and run a dashboard. This "
- "option basically sets up a dashboard and then runs ctest -D with the "
- "appropriate options."},
+ "configuration"},
{"-SP <script>, --script-new-process <script>", "Execute a dashboard for a "
- "configuration",
- "This option does the same operations as -S but it will do them in a "
- "separate process. This is primarily useful in cases where the script "
- "may modify the environment and you do not want the modified environment "
- "to impact other -S scripts."},
- {"-A <file>, --add-notes <file>", "Add a notes file with submission",
- "This option tells ctest to include a notes file when submitting "
- "dashboard. "},
+ "configuration"},
+ {"-A <file>, --add-notes <file>", "Add a notes file with submission"},
{"-I [Start,End,Stride,test#,test#|Test file], --tests-information",
- "Run a specific number of tests by number.",
- "This option causes ctest to run tests starting at number Start, ending "
- "at number End, and incrementing by Stride. Any additional numbers after "
- "Stride are considered individual test numbers. Start, End,or stride "
- "can be empty. Optionally a file can be given that contains the same "
- "syntax as the command line."},
- {"-U, --union", "Take the Union of -I and -R",
- "When both -R and -I are specified by default the intersection of "
- "tests are run. By specifying -U the union of tests is run instead."},
- {"--max-width <width>", "Set the max width for a test name to output",
- "Set the maximum width for each test name to show in the output. This "
- "allows the user to widen the output to avoid clipping the test name which "
- "can be very annoying."},
- {"--interactive-debug-mode [0|1]", "Set the interactive mode to 0 or 1.",
- "This option causes ctest to run tests in either an interactive mode or "
- "a non-interactive mode. On Windows this means that in non-interactive "
- "mode, all system debug pop up windows are blocked. In dashboard mode "
- "(Experimental, Nightly, Continuous), the default is non-interactive. "
- "When just running tests not for a dashboard the default is to allow "
- "popups and interactive "
- "debugging."},
- {"--no-label-summary", "Disable timing summary information for labels.",
- "This option tells ctest not to print summary information for each label "
- "associated with the tests run. If there are no labels on the "
- "tests, nothing extra is printed."},
- {"--build-and-test", "Configure, build and run a test.",
- "This option tells ctest to configure (i.e. run cmake on), build, and or "
- "execute a test. The configure and test steps are optional. The arguments "
- "to this command line are the source and binary directories. By default "
- "this will run CMake on the Source/Bin directories specified unless "
- "--build-nocmake is specified. Both --build-makeprogram and "
- "--build-generator MUST be provided to use --build-and-test. If "
- "--test-command is specified then that will be run after the build is "
- "complete. Other options that affect this mode are --build-target "
- "--build-nocmake, --build-run-dir, "
- "--build-two-config, --build-exe-dir, --build-project,"
- "--build-noclean, --build-options"},
- {"--build-target", "Specify a specific target to build.",
- "This option goes with the --build-and-test option, if left out the all "
- "target is built." },
- {"--build-nocmake", "Run the build without running cmake first.",
- "Skip the cmake step." },
- {"--build-run-dir", "Specify directory to run programs from.",
- "Directory where programs will be after it has been compiled." },
- {"--build-two-config", "Run CMake twice", "" },
- {"--build-exe-dir", "Specify the directory for the executable.", "" },
- {"--build-generator", "Specify the generator to use.", "" },
- {"--build-generator-toolset", "Specify the generator-specific toolset.",""},
- {"--build-project", "Specify the name of the project to build.", "" },
- {"--build-makeprogram", "Specify the make program to use.", "" },
- {"--build-noclean", "Skip the make clean step.", "" },
+ "Run a specific number of tests by number."},
+ {"-U, --union", "Take the Union of -I and -R"},
+ {"--rerun-failed", "Run only the tests that failed previously"},
+ {"--repeat-until-fail <n>", "Require each test to run <n> "
+ "times without failing in order to pass"},
+ {"--max-width <width>", "Set the max width for a test name to output"},
+ {"--interactive-debug-mode [0|1]", "Set the interactive mode to 0 or 1."},
+ {"--no-label-summary", "Disable timing summary information for labels."},
+ {"--build-and-test", "Configure, build and run a test."},
+ {"--build-target", "Specify a specific target to build."},
+ {"--build-nocmake", "Run the build without running cmake first."},
+ {"--build-run-dir", "Specify directory to run programs from."},
+ {"--build-two-config", "Run CMake twice"},
+ {"--build-exe-dir", "Specify the directory for the executable."},
+ {"--build-generator", "Specify the generator to use."},
+ {"--build-generator-platform", "Specify the generator-specific platform."},
+ {"--build-generator-toolset", "Specify the generator-specific toolset."},
+ {"--build-project", "Specify the name of the project to build."},
+ {"--build-makeprogram", "Specify the make program to use."},
+ {"--build-noclean", "Skip the make clean step."},
{"--build-config-sample",
- "A sample executable to use to determine the configuration",
- "A sample executable to use to determine the configuration that "
- "should be used. e.g. Debug/Release/etc" },
- {"--build-options", "Add extra options to the build step.",
- "This option must be the last option with the exception of --test-command"
- },
+ "A sample executable to use to determine the configuration"},
+ {"--build-options", "Add extra options to the build step."},
- {"--test-command", "The test to run with the --build-and-test option.", ""
- },
- {"--test-timeout", "The time limit in seconds, internal use only.", ""
- },
- {"--tomorrow-tag", "Nightly or experimental starts with next day tag.",
- "This is useful if the build will not finish in one day." },
+ {"--test-command", "The test to run with the --build-and-test option."},
+ {"--test-timeout", "The time limit in seconds, internal use only."},
+ {"--test-load", "CPU load threshold for starting new parallel tests."},
+ {"--tomorrow-tag", "Nightly or experimental starts with next day tag."},
{"--ctest-config", "The configuration file used to initialize CTest state "
- "when submitting dashboards.",
- "This option tells CTest to use different initialization file instead of "
- "CTestConfiguration.tcl. This way multiple initialization files can be "
- "used for example to submit to multiple dashboards." },
- {"--overwrite", "Overwrite CTest configuration option.",
- "By default ctest uses configuration options from configuration file. "
- "This option will overwrite the configuration option." },
- {"--extra-submit <file>[;<file>]", "Submit extra files to the dashboard.",
- "This option will submit extra files to the dashboard." },
- {"--force-new-ctest-process", "Run child CTest instances as new processes",
- "By default CTest will run child CTest instances within the same process. "
- "If this behavior is not desired, this argument will enforce new "
- "processes for child CTest processes." },
- {"--schedule-random", "Use a random order for scheduling tests",
- "This option will run the tests in a random order. It is commonly used to "
- "detect implicit dependencies in a test suite." },
- {"--submit-index", "Submit individual dashboard tests with specific index",
- "This option allows performing the same CTest action (such as test) "
- "multiple times and submit all stages to the same dashboard (Dart2 "
- "required). Each execution requires different index." },
- {"--timeout <seconds>", "Set a global timeout on all tests.",
- "This option will set a global timeout on all tests that do not already "
- "have a timeout set on them."},
- {"--stop-time <time>", "Set a time at which all tests should stop running.",
- "Set a real time of day at which all tests should timeout. Example: "
- "7:00:00 -0400. Any time format understood by the curl date parser is "
- "accepted. Local time is assumed if no timezone is specified."},
- {"--http1.0", "Submit using HTTP 1.0.",
- "This option will force CTest to use HTTP 1.0 to submit files to the "
- "dashboard, instead of HTTP 1.1."},
- {"--no-compress-output", "Do not compress test output when submitting.",
- "This flag will turn off automatic compression of test output. Use this "
- "to maintain compatibility with an older version of CDash which doesn't "
- "support compressed test output."},
- {"--print-labels", "Print all available test labels.",
- "This option will not run any tests, it will simply print the list of "
- "all labels associated with the test set."},
- {"--help-command <cmd> [<file>]", "Show help for a single command and exit.",
- "Prints the help for the command to stdout or to the specified file." },
- {"--help-command-list [<file>]", "List available commands and exit.",
- "Prints the list of all available listfile commands to stdout or the "
- "specified file." },
- {"--help-commands [<file>]", "Print help for all commands and exit.",
- "Prints the help for all commands to stdout or to the specified file." },
- {0,0,0}
-};
-
-//----------------------------------------------------------------------------
-static const char * cmDocumentationSeeAlso[][3] =
-{
- {0, "cmake", 0},
- {0, "ccmake", 0},
- {0, 0, 0}
+ "when submitting dashboards."},
+ {"--overwrite", "Overwrite CTest configuration option."},
+ {"--extra-submit <file>[;<file>]", "Submit extra files to the dashboard."},
+ {"--force-new-ctest-process", "Run child CTest instances as new processes"},
+ {"--schedule-random", "Use a random order for scheduling tests"},
+ {"--submit-index", "Submit individual dashboard tests with specific index"},
+ {"--timeout <seconds>", "Set a global timeout on all tests."},
+ {"--stop-time <time>",
+ "Set a time at which all tests should stop running."},
+ {"--http1.0", "Submit using HTTP 1.0."},
+ {"--no-compress-output", "Do not compress test output when submitting."},
+ {"--print-labels", "Print all available test labels."},
+ {0,0}
};
// this is a test driver program for cmCTest.
-int main (int argc, char *argv[])
+int main (int argc, char const* const* argv)
{
+ cmsys::Encoding::CommandLineArguments encoding_args =
+ cmsys::Encoding::CommandLineArguments::Main(argc, argv);
+ argc = encoding_args.argc();
+ argv = encoding_args.argv();
+
cmSystemTools::DoNotInheritStdPipes();
cmSystemTools::EnableMSVCDebugHook();
- cmSystemTools::FindExecutableDirectory(argv[0]);
+ cmSystemTools::FindCMakeResources(argv[0]);
// Dispatch 'ctest --launch' mode directly.
if(argc >= 2 && strcmp(argv[1], "--launch") == 0)
@@ -277,7 +140,7 @@ int main (int argc, char *argv[])
cmCTest inst;
- if ( cmSystemTools::GetCurrentWorkingDirectory().size() == 0 )
+ if (cmSystemTools::GetCurrentWorkingDirectory().empty())
{
cmCTestLog(&inst, ERROR_MESSAGE,
"Current working directory cannot be established." << std::endl);
@@ -301,21 +164,21 @@ int main (int argc, char *argv[])
doc.addCTestStandardDocSections();
if(doc.CheckOptions(argc, argv))
{
+ cmake hcm;
+ hcm.SetHomeDirectory("");
+ hcm.SetHomeOutputDirectory("");
+ hcm.AddCMakePaths();
+
// Construct and print requested documentation.
- std::vector<cmDocumentationEntry> commands;
cmCTestScriptHandler* ch =
static_cast<cmCTestScriptHandler*>(inst.GetHandler("script"));
ch->CreateCMake();
- ch->GetCommandDocumentation(commands);
doc.SetShowGenerators(false);
doc.SetName("ctest");
doc.SetSection("Name",cmDocumentationName);
doc.SetSection("Usage",cmDocumentationUsage);
- doc.SetSection("Description",cmDocumentationDescription);
doc.PrependSection("Options",cmDocumentationOptions);
- doc.SetSection("Commands",commands);
- doc.SetSeeAlsoList(cmDocumentationSeeAlso);
#ifdef cout
# undef cout
#endif
@@ -324,10 +187,6 @@ int main (int argc, char *argv[])
}
}
-#ifdef _WIN32
- std::string comspec = "cmw9xcom.exe";
- cmSystemTools::SetWindows9xComspecSubstitute(comspec.c_str());
-#endif
// copy the args to a vector
std::vector<std::string> args;
for(int i =0; i < argc; ++i)
diff --git a/Source/kwsys/.gitattributes b/Source/kwsys/.gitattributes
new file mode 100644
index 000000000..a9c4e7739
--- /dev/null
+++ b/Source/kwsys/.gitattributes
@@ -0,0 +1,12 @@
+.git* export-ignore
+
+/CONTRIBUTING.rst conflict-marker-size=78
+
+*.c whitespace=tab-in-indent,no-lf-at-eof
+*.h whitespace=tab-in-indent,no-lf-at-eof
+*.h.in whitespace=tab-in-indent,no-lf-at-eof
+*.cxx whitespace=tab-in-indent,no-lf-at-eof
+*.hxx whitespace=tab-in-indent,no-lf-at-eof
+*.hxx.in whitespace=tab-in-indent,no-lf-at-eof
+*.txt whitespace=tab-in-indent,no-lf-at-eof
+*.cmake whitespace=tab-in-indent,no-lf-at-eof
diff --git a/Source/kwsys/Base64.c b/Source/kwsys/Base64.c
index d07bdd01b..4b8ede2fb 100644
--- a/Source/kwsys/Base64.c
+++ b/Source/kwsys/Base64.c
@@ -115,10 +115,10 @@ void kwsysBase64_Encode1(const unsigned char *src, unsigned char *dest)
actually knowing how much data to expect (if the input is not a multiple of
3 bytes then the extra padding needed to complete the encode 4 bytes will
stop the decoding anyway). */
-unsigned long kwsysBase64_Encode(const unsigned char *input,
- unsigned long length,
- unsigned char *output,
- int mark_end)
+size_t kwsysBase64_Encode(const unsigned char *input,
+ size_t length,
+ unsigned char *output,
+ int mark_end)
{
const unsigned char *ptr = input;
const unsigned char *end = input + length;
@@ -157,7 +157,7 @@ unsigned long kwsysBase64_Encode(const unsigned char *input,
optr += 4;
}
- return (unsigned long)(optr - output);
+ return (size_t)(optr - output);
}
/*--------------------------------------------------------------------------*/
@@ -207,10 +207,10 @@ int kwsysBase64_Decode3(const unsigned char *src, unsigned char *dest)
'length' parameter is ignored. This enables the caller to decode a stream
without actually knowing how much decoded data to expect (of course, the
buffer must be large enough). */
-unsigned long kwsysBase64_Decode(const unsigned char *input,
- unsigned long length,
- unsigned char *output,
- unsigned long max_input_length)
+size_t kwsysBase64_Decode(const unsigned char *input,
+ size_t length,
+ unsigned char *output,
+ size_t max_input_length)
{
const unsigned char *ptr = input;
unsigned char *optr = output;
@@ -226,7 +226,7 @@ unsigned long kwsysBase64_Decode(const unsigned char *input,
optr += len;
if(len < 3)
{
- return (unsigned long)(optr - output);
+ return (size_t)(optr - output);
}
ptr += 4;
}
@@ -240,7 +240,7 @@ unsigned long kwsysBase64_Decode(const unsigned char *input,
optr += len;
if(len < 3)
{
- return (unsigned long)(optr - output);
+ return (size_t)(optr - output);
}
ptr += 4;
}
@@ -275,5 +275,5 @@ unsigned long kwsysBase64_Decode(const unsigned char *input,
}
}
- return (unsigned long)(optr - output);
+ return (size_t)(optr - output);
}
diff --git a/Source/kwsys/Base64.h.in b/Source/kwsys/Base64.h.in
index 346800768..36ed3cce2 100644
--- a/Source/kwsys/Base64.h.in
+++ b/Source/kwsys/Base64.h.in
@@ -14,6 +14,8 @@
#include <@KWSYS_NAMESPACE@/Configure.h>
+#include <stddef.h> /* size_t */
+
/* Redefine all public interface symbol names to be in the proper
namespace. These macros are used internally to kwsys only, and are
not visible to user code. Use kwsysHeaderDump.pl to reproduce
@@ -68,10 +70,10 @@ kwsysEXPORT void kwsysBase64_Encode1(const unsigned char *src,
* the extra padding needed to complete the encode 4 bytes will stop
* the decoding anyway).
*/
-kwsysEXPORT unsigned long kwsysBase64_Encode(const unsigned char *input,
- unsigned long length,
- unsigned char *output,
- int mark_end);
+kwsysEXPORT size_t kwsysBase64_Encode(const unsigned char *input,
+ size_t length,
+ unsigned char *output,
+ int mark_end);
/**
* Decode 4 bytes into a 3 byte string. Returns the number of bytes
@@ -92,10 +94,10 @@ kwsysEXPORT int kwsysBase64_Decode3(const unsigned char *src,
* much decoded data to expect (of course, the buffer must be large
* enough).
*/
-kwsysEXPORT unsigned long kwsysBase64_Decode(const unsigned char *input,
- unsigned long length,
- unsigned char *output,
- unsigned long max_input_length);
+kwsysEXPORT size_t kwsysBase64_Decode(const unsigned char *input,
+ size_t length,
+ unsigned char *output,
+ size_t max_input_length);
#if defined(__cplusplus)
} /* extern "C" */
diff --git a/Source/kwsys/CMakeEmptyInputFile.in b/Source/kwsys/CMakeEmptyInputFile.in
deleted file mode 100644
index 40b7ea245..000000000
--- a/Source/kwsys/CMakeEmptyInputFile.in
+++ /dev/null
@@ -1 +0,0 @@
-@CMAKE_EMPTY_INPUT_FILE_CONTENT@
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index 0f2783689..8b1539416 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -35,15 +35,6 @@
# 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 are as follows:
#
# KWSYS_INSTALL_BIN_DIR = The installation target directories into
@@ -85,6 +76,13 @@
# written.
CMAKE_MINIMUM_REQUIRED(VERSION 2.6.3 FATAL_ERROR)
+IF(POLICY CMP0025)
+ CMAKE_POLICY(SET CMP0025 NEW)
+ENDIF()
+IF(POLICY CMP0056)
+ CMAKE_POLICY(SET CMP0056 NEW)
+ENDIF()
+SET(CMAKE_LEGACY_CYGWIN_WIN32 0)
#-----------------------------------------------------------------------------
# If a namespace is not specified, use "kwsys" and enable testing.
@@ -93,7 +91,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6.3 FATAL_ERROR)
IF(NOT KWSYS_NAMESPACE)
SET(KWSYS_NAMESPACE "kwsys")
SET(KWSYS_STANDALONE 1)
-ENDIF(NOT KWSYS_NAMESPACE)
+ENDIF()
#-----------------------------------------------------------------------------
# The project name is that of the specified namespace.
@@ -112,6 +110,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
SET(KWSYS_USE_Base64 1)
SET(KWSYS_USE_Directory 1)
SET(KWSYS_USE_DynamicLoader 1)
+ SET(KWSYS_USE_Encoding 1)
SET(KWSYS_USE_Glob 1)
SET(KWSYS_USE_MD5 1)
SET(KWSYS_USE_Process 1)
@@ -119,36 +118,54 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
SET(KWSYS_USE_System 1)
SET(KWSYS_USE_SystemTools 1)
SET(KWSYS_USE_CommandLineArguments 1)
- SET(KWSYS_USE_FundamentalType 1)
SET(KWSYS_USE_Terminal 1)
SET(KWSYS_USE_IOStream 1)
+ SET(KWSYS_USE_FStream 1)
SET(KWSYS_USE_String 1)
SET(KWSYS_USE_SystemInformation 1)
- SET(KWSYS_USE_CPU 1)
-ENDIF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
+ENDIF()
# Enforce component dependencies.
IF(KWSYS_USE_SystemTools)
SET(KWSYS_USE_Directory 1)
-ENDIF(KWSYS_USE_SystemTools)
+ SET(KWSYS_USE_FStream 1)
+ SET(KWSYS_USE_Encoding 1)
+ENDIF()
IF(KWSYS_USE_Glob)
SET(KWSYS_USE_Directory 1)
SET(KWSYS_USE_SystemTools 1)
SET(KWSYS_USE_RegularExpression 1)
-ENDIF(KWSYS_USE_Glob)
+ SET(KWSYS_USE_FStream 1)
+ SET(KWSYS_USE_Encoding 1)
+ENDIF()
IF(KWSYS_USE_Process)
SET(KWSYS_USE_System 1)
-ENDIF(KWSYS_USE_Process)
+ SET(KWSYS_USE_Encoding 1)
+ENDIF()
IF(KWSYS_USE_SystemInformation)
SET(KWSYS_USE_Process 1)
-ENDIF(KWSYS_USE_SystemInformation)
+ENDIF()
+IF(KWSYS_USE_System)
+ SET(KWSYS_USE_Encoding 1)
+ENDIF()
+IF(KWSYS_USE_Directory)
+ SET(KWSYS_USE_Encoding 1)
+ENDIF()
+IF(KWSYS_USE_FStream)
+ SET(KWSYS_USE_Encoding 1)
+ENDIF()
# Setup the large file support default.
IF(KWSYS_LFS_DISABLE)
SET(KWSYS_LFS_REQUESTED 0)
-ELSE(KWSYS_LFS_DISABLE)
+ELSE()
SET(KWSYS_LFS_REQUESTED 1)
-ENDIF(KWSYS_LFS_DISABLE)
+ENDIF()
+
+# Specify default 8 bit encoding for Windows
+IF(NOT KWSYS_ENCODING_DEFAULT_CODEPAGE)
+ SET(KWSYS_ENCODING_DEFAULT_CODEPAGE CP_ACP)
+ENDIF()
# Enable testing if building standalone.
IF(KWSYS_STANDALONE)
@@ -156,8 +173,8 @@ IF(KWSYS_STANDALONE)
MARK_AS_ADVANCED(BUILD_TESTING DART_ROOT TCL_TCLSH)
IF(BUILD_TESTING)
ENABLE_TESTING()
- ENDIF(BUILD_TESTING)
-ENDIF(KWSYS_STANDALONE)
+ ENDIF()
+ENDIF()
# Include helper macros.
INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/kwsysPlatformTests.cmake)
@@ -173,15 +190,15 @@ INCLUDE_REGULAR_EXPRESSION("^.*$")
IF(NOT KWSYS_INSTALL_INCLUDE_DIR)
STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_INCLUDE_DIR
"${KWSYS_HEADER_INSTALL_DIR}")
-ENDIF(NOT KWSYS_INSTALL_INCLUDE_DIR)
+ENDIF()
IF(NOT KWSYS_INSTALL_LIB_DIR)
STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_LIB_DIR
"${KWSYS_LIBRARY_INSTALL_DIR}")
-ENDIF(NOT KWSYS_INSTALL_LIB_DIR)
+ENDIF()
IF(NOT KWSYS_INSTALL_BIN_DIR)
STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_BIN_DIR
"${KWSYS_LIBRARY_INSTALL_DIR}")
-ENDIF(NOT KWSYS_INSTALL_BIN_DIR)
+ENDIF()
# Setup header install rules.
SET(KWSYS_INSTALL_INCLUDE_OPTIONS)
@@ -189,7 +206,7 @@ IF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT)
SET(KWSYS_INSTALL_INCLUDE_OPTIONS ${KWSYS_INSTALL_INCLUDE_OPTIONS}
COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT}
)
-ENDIF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT)
+ENDIF()
# Setup library install rules.
SET(KWSYS_INSTALL_LIBRARY_RULE)
@@ -206,7 +223,7 @@ IF(KWSYS_INSTALL_LIB_DIR)
SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME}
)
- ENDIF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
+ ENDIF()
# Install the archive to the lib directory.
SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
@@ -217,8 +234,8 @@ IF(KWSYS_INSTALL_LIB_DIR)
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)
+ ENDIF()
+ENDIF()
IF(KWSYS_INSTALL_BIN_DIR)
# Install the runtime library to the bin directory.
SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
@@ -229,8 +246,8 @@ IF(KWSYS_INSTALL_BIN_DIR)
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)
+ ENDIF()
+ENDIF()
# Do not support old KWSYS_*a_INSTALL_DIR variable names.
SET(KWSYS_HEADER_INSTALL_DIR)
@@ -241,8 +258,8 @@ STRING(COMPARE EQUAL "${PROJECT_SOURCE_DIR}" "${PROJECT_BINARY_DIR}"
KWSYS_IN_SOURCE_BUILD)
IF(NOT KWSYS_IN_SOURCE_BUILD)
CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/kwsysPrivate.h
- ${PROJECT_BINARY_DIR}/kwsysPrivate.h COPY_ONLY IMMEDIATE)
-ENDIF(NOT KWSYS_IN_SOURCE_BUILD)
+ ${PROJECT_BINARY_DIR}/kwsysPrivate.h COPYONLY IMMEDIATE)
+ENDIF()
# Select plugin module file name convention.
IF(NOT KWSYS_DynamicLoader_PREFIX)
@@ -256,7 +273,7 @@ ENDIF()
# We require ANSI support from the C compiler. Add any needed flags.
IF(CMAKE_ANSI_CFLAGS)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_ANSI_CFLAGS}")
-ENDIF(CMAKE_ANSI_CFLAGS)
+ENDIF()
#-----------------------------------------------------------------------------
# Adjust compiler flags for some platforms.
@@ -268,15 +285,31 @@ IF(NOT CMAKE_COMPILER_IS_GNUCXX)
KWSYS_CXX_FLAGS_HAVE_NO_IMPLICIT_INCLUDE "${CMAKE_CXX_FLAGS}")
IF(NOT KWSYS_CXX_FLAGS_HAVE_IMPLICIT_LOCAL)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -timplicit_local")
- ENDIF(NOT KWSYS_CXX_FLAGS_HAVE_IMPLICIT_LOCAL)
+ ENDIF()
IF(NOT KWSYS_CXX_FLAGS_HAVE_NO_IMPLICIT_INCLUDE)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -no_implicit_include")
- ENDIF(NOT KWSYS_CXX_FLAGS_HAVE_NO_IMPLICIT_INCLUDE)
- ENDIF(CMAKE_SYSTEM MATCHES "OSF1-V.*")
+ ENDIF()
+ ENDIF()
IF(CMAKE_SYSTEM MATCHES "HP-UX")
SET(KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS "+p")
- ENDIF(CMAKE_SYSTEM MATCHES "HP-UX")
-ENDIF(NOT CMAKE_COMPILER_IS_GNUCXX)
+ IF(CMAKE_CXX_COMPILER_ID MATCHES "HP")
+ # it is known that version 3.85 fails and 6.25 works without these flags
+ IF(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4)
+ # use new C++ library and improved template support
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -AA +hpxstd98")
+ ENDIF()
+ ENDIF()
+ ENDIF()
+ENDIF()
+IF(KWSYS_STANDALONE)
+ IF(CMAKE_CXX_COMPILER_ID STREQUAL SunPro)
+ IF(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.13)
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++03")
+ ELSE()
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -library=stlport4")
+ ENDIF()
+ ENDIF()
+ENDIF()
#-----------------------------------------------------------------------------
# Configure Large File Support.
@@ -296,121 +329,17 @@ IF(KWSYS_LFS_REQUESTED)
IF(KWSYS_LFS_WORKS)
SET(KWSYS_LFS_AVAILABLE 1)
- ENDIF(KWSYS_LFS_WORKS)
-ELSE(KWSYS_LFS_REQUESTED)
+ ENDIF()
+ELSE()
# Large File Support is not requested.
SET(KWSYS_LFS_REQUESTED 0)
-ENDIF(KWSYS_LFS_REQUESTED)
+ENDIF()
#-----------------------------------------------------------------------------
# Configure the standard library header wrappers based on compiler's
# capabilities and parent project's request. Enforce 0/1 as only
# possible values for configuration into Configure.hxx.
-KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAVE_STD
- "Checking whether STL classes are in std namespace" DIRECT)
-
-IF(KWSYS_IOS_FORCE_OLD)
- SET(KWSYS_IOS_USE_ANSI 0)
-ELSE(KWSYS_IOS_FORCE_OLD)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_USE_ANSI
- "Checking whether ANSI stream headers are available" DIRECT)
-ENDIF(KWSYS_IOS_FORCE_OLD)
-
-IF(KWSYS_IOS_USE_ANSI)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAVE_STD
- "Checking whether ANSI streams are in std namespace" DIRECT)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_USE_SSTREAM
- "Checking whether ANSI string stream is available" DIRECT)
-ELSE(KWSYS_IOS_USE_ANSI)
- SET(KWSYS_IOS_HAVE_STD 0)
- SET(KWSYS_IOS_USE_SSTREAM 0)
-ENDIF(KWSYS_IOS_USE_ANSI)
-
-IF(KWSYS_IOS_USE_SSTREAM)
- SET(KWSYS_IOS_USE_STRSTREAM_H 0)
- SET(KWSYS_IOS_USE_STRSTREA_H 0)
-ELSE(KWSYS_IOS_USE_SSTREAM)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_USE_STRSTREAM_H
- "Checking whether strstream.h is available" DIRECT)
- IF(KWSYS_IOS_USE_STRSTREAM_H)
- SET(KWSYS_IOS_USE_STRSTREA_H 0)
- ELSE(KWSYS_IOS_USE_STRSTREAM_H)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_USE_STRSTREA_H
- "Checking whether strstrea.h is available" DIRECT)
- ENDIF(KWSYS_IOS_USE_STRSTREAM_H)
-ENDIF(KWSYS_IOS_USE_SSTREAM)
-
-KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_CSTDDEF
- "Checking whether header cstddef is available" DIRECT)
-
-SET(KWSYS_PLATFORM_CXX_TEST_DEFINES
- -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD})
-KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_STRING_HAVE_NEQ_CHAR
- "Checking whether stl string has operator!= for char*" DIRECT)
-KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ITERATOR_TRAITS
- "Checking whether stl has iterator_traits" DIRECT)
-IF(KWSYS_STL_HAS_ITERATOR_TRAITS)
- SET(KWSYS_STL_HAS_ITERATOR_CATEGORY 0)
- SET(KWSYS_STL_HAS___ITERATOR_CATEGORY 0)
-ELSE(KWSYS_STL_HAS_ITERATOR_TRAITS)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ITERATOR_CATEGORY
- "Checking whether stl has old iterator_category" DIRECT)
- IF(KWSYS_STL_HAS_ITERATOR_CATEGORY)
- SET(KWSYS_STL_HAS___ITERATOR_CATEGORY 0)
- ELSE(KWSYS_STL_HAS_ITERATOR_CATEGORY)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS___ITERATOR_CATEGORY
- "Checking whether stl has internal __iterator_category" DIRECT)
- ENDIF(KWSYS_STL_HAS_ITERATOR_CATEGORY)
-ENDIF(KWSYS_STL_HAS_ITERATOR_TRAITS)
-KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ALLOCATOR_TEMPLATE
- "Checking whether stl has standard template allocator" DIRECT)
-IF(KWSYS_STL_HAS_ALLOCATOR_TEMPLATE)
- SET(KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE 0)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ALLOCATOR_REBIND
- "Checking for rebind member of stl allocator" DIRECT)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT
- "Checking for non-standard argument to stl allocator<>::max_size" DIRECT)
-ELSE(KWSYS_STL_HAS_ALLOCATOR_TEMPLATE)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE
- "Checking whether stl has old non-template allocator" DIRECT)
- SET(KWSYS_STL_HAS_ALLOCATOR_REBIND 0)
- SET(KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT 0)
-ENDIF(KWSYS_STL_HAS_ALLOCATOR_TEMPLATE)
-KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ALLOCATOR_OBJECTS
- "Checking whether stl containers support allocator objects." DIRECT)
-IF(KWSYS_IOS_USE_ANSI AND NOT WATCOM)
- # ANSI streams always have string operators.
- SET(KWSYS_STL_STRING_HAVE_OSTREAM 1)
- SET(KWSYS_STL_STRING_HAVE_ISTREAM 1)
-ELSE(KWSYS_IOS_USE_ANSI AND NOT WATCOM)
- # There may not be string operators for old streams.
- KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_STRING_HAVE_OSTREAM
- "Checking whether stl string has ostream operator<<" DIRECT)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_STRING_HAVE_ISTREAM
- "Checking whether stl string has istream operator>>" DIRECT)
-ENDIF(KWSYS_IOS_USE_ANSI AND NOT WATCOM)
-SET(KWSYS_PLATFORM_CXX_TEST_DEFINES
- -DKWSYS_IOS_USE_ANSI=${KWSYS_IOS_USE_ANSI}
- -DKWSYS_IOS_HAVE_STD=${KWSYS_IOS_HAVE_STD})
-KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAVE_BINARY
- "Checking whether ios has binary openmode" DIRECT)
-SET(KWSYS_PLATFORM_CXX_TEST_DEFINES)
-
-KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_NULL_TEMPLATE_ARGS
- "Checking whether \"<>\" is needed for template friends" INVERT)
-KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_MEMBER_TEMPLATES
- "Checking for member template support" DIRECT)
-KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_FULL_SPECIALIZATION
- "Checking for standard template specialization syntax" DIRECT)
-KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP
- "Checking whether argument dependent lookup is supported" DIRECT)
-
-IF(UNIX)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_STAT_HAS_ST_MTIM
- "Checking whether struct stat has st_mtim member" DIRECT)
-ENDIF(UNIX)
-
# Check existence and uniqueness of long long and __int64.
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_LONG_LONG
"Checking whether C++ compiler has 'long long'" DIRECT)
@@ -444,73 +373,14 @@ IF(KWSYS_CXX_HAS___INT64)
ENDIF()
ENDIF()
-IF(KWSYS_USE_FundamentalType)
+IF(KWSYS_USE_Encoding)
# Look for type size helper macros.
- KWSYS_PLATFORM_INFO_TEST(C KWSYS_C_TYPE_MACROS
- "Checking for C type size macros")
- SET(macro_regex ".*INFO:macro\\[([^]]*)\\].*")
- FOREACH(info ${KWSYS_C_TYPE_MACROS})
- IF("${info}" MATCHES "${macro_regex}")
- STRING(REGEX REPLACE "${macro_regex}" "\\1" macro "${info}")
- SET(KWSYS_C_HAS_MACRO_${macro} 1)
- ENDIF()
- ENDFOREACH()
-
- # Determine type sizes at preprocessing time if possible, and
- # otherwise fall back to a try-compile.
- SET(KWSYS_C_TYPE_NAME_CHAR "char")
- SET(KWSYS_C_TYPE_NAME_SHORT "short")
- SET(KWSYS_C_TYPE_NAME_INT "int")
- SET(KWSYS_C_TYPE_NAME_LONG "long")
- SET(KWSYS_C_TYPE_NAME_LONG_LONG "long long")
- SET(KWSYS_C_TYPE_NAME___INT64 "__int64")
- FOREACH(type CHAR SHORT INT LONG LONG_LONG __INT64)
- IF(KWSYS_C_HAS_MACRO___SIZEOF_${type}__)
- # Use __SIZEOF_${type}__ macro.
- SET(KWSYS_SIZEOF_${type} TRUE)
- SET(KWSYS_C_CODE_SIZEOF_${type} "#define ${KWSYS_NAMESPACE}_SIZEOF_${type} __SIZEOF_${type}__")
- ELSEIF(KWSYS_C_HAS_MACRO___${type}_MAX__)
- # Use __${type}_MAX__ macro.
- SET(KWSYS_SIZEOF_${type} TRUE)
- SET(KWSYS_C_CODE_SIZEOF_${type} "#if __${type}_MAX__ == 0x7f
-# define ${KWSYS_NAMESPACE}_SIZEOF_${type} 1
-#elif __${type}_MAX__ == 0x7fff
-# define ${KWSYS_NAMESPACE}_SIZEOF_${type} 2
-#elif __${type}_MAX__ == 0x7fffffff
-# define ${KWSYS_NAMESPACE}_SIZEOF_${type} 4
-#elif __${type}_MAX__>>32 == 0x7fffffff
-# define ${KWSYS_NAMESPACE}_SIZEOF_${type} 8
-#else
-# error \"Cannot determine sizeof(${KWSYS_C_TYPE_NAME_${type}}).\"
-#endif")
- ELSE()
- # Configure a hard-coded type size.
- CHECK_TYPE_SIZE("${KWSYS_C_TYPE_NAME_${type}}" KWSYS_SIZEOF_${type})
- IF(NOT KWSYS_SIZEOF_${type})
- SET(KWSYS_SIZEOF_${type} 0)
- ENDIF()
- SET(KWSYS_C_CODE_SIZEOF_${type}
- "#define ${KWSYS_NAMESPACE}_SIZEOF_${type} ${KWSYS_SIZEOF_${type}}")
- ENDIF()
- ENDFOREACH()
-
- IF(KWSYS_USE___INT64)
- KWSYS_PLATFORM_CXX_TEST(KWSYS_CAN_CONVERT_UI64_TO_DOUBLE
- "Checking whether unsigned __int64 can convert to double" DIRECT)
- ELSE(KWSYS_USE___INT64)
- SET(KWSYS_CAN_CONVERT_UI64_TO_DOUBLE 1)
- ENDIF(KWSYS_USE___INT64)
-
- # Check signedness of "char" type.
- KWSYS_PLATFORM_CXX_TEST_RUN(KWSYS_CHAR_IS_SIGNED
- "Checking whether char is signed" DIRECT)
-ENDIF(KWSYS_USE_FundamentalType)
+ KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_WSTRING
+ "Checking whether wstring is available" DIRECT)
+ENDIF()
IF(KWSYS_USE_IOStream)
# Determine whether iostreams support long long.
- SET(KWSYS_PLATFORM_CXX_TEST_DEFINES
- -DKWSYS_IOS_USE_ANSI=${KWSYS_IOS_USE_ANSI}
- -DKWSYS_IOS_HAVE_STD=${KWSYS_IOS_HAVE_STD})
IF(KWSYS_CXX_HAS_LONG_LONG)
KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_ISTREAM_LONG_LONG
"Checking if istream supports long long" DIRECT)
@@ -529,27 +399,26 @@ IF(KWSYS_USE_IOStream)
SET(KWSYS_IOS_HAS_ISTREAM___INT64 0)
SET(KWSYS_IOS_HAS_OSTREAM___INT64 0)
ENDIF()
- SET(KWSYS_PLATFORM_CXX_TEST_DEFINES)
-ENDIF(KWSYS_USE_IOStream)
+ENDIF()
IF(KWSYS_NAMESPACE MATCHES "^kwsys$")
SET(KWSYS_NAME_IS_KWSYS 1)
-ELSE(KWSYS_NAMESPACE MATCHES "^kwsys$")
+ELSE()
SET(KWSYS_NAME_IS_KWSYS 0)
-ENDIF(KWSYS_NAMESPACE MATCHES "^kwsys$")
+ENDIF()
# Choose default shared/static build if not specified.
IF(KWSYS_BUILD_SHARED MATCHES "^KWSYS_BUILD_SHARED$")
SET(KWSYS_BUILD_SHARED ${BUILD_SHARED_LIBS})
-ENDIF(KWSYS_BUILD_SHARED MATCHES "^KWSYS_BUILD_SHARED$")
+ENDIF()
IF(KWSYS_BUILD_SHARED)
SET(KWSYS_BUILD_SHARED 1)
SET(KWSYS_LIBRARY_TYPE SHARED)
-ELSE(KWSYS_BUILD_SHARED)
+ELSE()
SET(KWSYS_BUILD_SHARED 0)
SET(KWSYS_LIBRARY_TYPE STATIC)
-ENDIF(KWSYS_BUILD_SHARED)
+ENDIF()
#-----------------------------------------------------------------------------
# Configure some implementation details.
@@ -573,12 +442,18 @@ IF(KWSYS_USE_SystemTools)
"Checking whether CXX compiler has utimes" DIRECT)
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_UTIMENSAT
"Checking whether CXX compiler has utimensat" DIRECT)
+ KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_STAT_HAS_ST_MTIM
+ "Checking whether CXX compiler struct stat has st_mtim member" DIRECT)
+ KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_STAT_HAS_ST_MTIMESPEC
+ "Checking whether CXX compiler struct stat has st_mtimespec member" DIRECT)
SET_PROPERTY(SOURCE SystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS
KWSYS_CXX_HAS_SETENV=${KWSYS_CXX_HAS_SETENV}
KWSYS_CXX_HAS_UNSETENV=${KWSYS_CXX_HAS_UNSETENV}
KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H=${KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H}
KWSYS_CXX_HAS_UTIMES=${KWSYS_CXX_HAS_UTIMES}
KWSYS_CXX_HAS_UTIMENSAT=${KWSYS_CXX_HAS_UTIMENSAT}
+ KWSYS_CXX_STAT_HAS_ST_MTIM=${KWSYS_CXX_STAT_HAS_ST_MTIM}
+ KWSYS_CXX_STAT_HAS_ST_MTIMESPEC=${KWSYS_CXX_STAT_HAS_ST_MTIMESPEC}
)
ENDIF()
@@ -655,6 +530,7 @@ IF(KWSYS_USE_SystemInformation)
# usually it's in libc but on FreeBSD
# it's in libexecinfo
FIND_LIBRARY(EXECINFO_LIB "execinfo")
+ MARK_AS_ADVANCED(EXECINFO_LIB)
IF (NOT EXECINFO_LIB)
SET(EXECINFO_LIB "")
ENDIF()
@@ -745,13 +621,22 @@ IF(KWSYS_USE_SystemInformation)
SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_BUILD_SHARED=1)
ENDIF()
+
+ IF(UNIX AND NOT CYGWIN)
+ KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_GETLOADAVG
+ "Checking whether CXX compiler has getloadavg" DIRECT)
+ IF(KWSYS_CXX_HAS_GETLOADAVG)
+ SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ COMPILE_DEFINITIONS KWSYS_CXX_HAS_GETLOADAVG=1)
+ ENDIF()
+ ENDIF()
ENDIF()
#-----------------------------------------------------------------------------
# Choose a directory for the generated headers.
IF(NOT KWSYS_HEADER_ROOT)
SET(KWSYS_HEADER_ROOT "${PROJECT_BINARY_DIR}")
-ENDIF(NOT KWSYS_HEADER_ROOT)
+ENDIF()
SET(KWSYS_HEADER_DIR "${KWSYS_HEADER_ROOT}/${KWSYS_NAMESPACE}")
INCLUDE_DIRECTORIES(${KWSYS_HEADER_ROOT})
@@ -763,91 +648,13 @@ IF(KWSYS_INSTALL_DOC_DIR)
SET(KWSYS_INSTALL_LICENSE_OPTIONS ${KWSYS_INSTALL_LICENSE_OPTIONS}
COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME}
)
- ENDIF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
+ ENDIF()
# Install the license under the documentation directory.
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/Copyright.txt
DESTINATION ${KWSYS_INSTALL_DOC_DIR}/${KWSYS_NAMESPACE}
${KWSYS_INSTALL_LICENSE_OPTIONS})
-ENDIF(KWSYS_INSTALL_DOC_DIR)
-
-#-----------------------------------------------------------------------------
-# Create STL header wrappers to block warnings in the STL headers and
-# give standard names by which they may be included.
-SET(KWSYS_STL_HEADER_EXTRA_string 1)
-FOREACH(header
- algorithm
- deque
- exception
- functional
- iterator
- list
- map
- memory
- new
- numeric
- queue
- set
- stack
- stdexcept
- string
- utility
- vector
- )
- # Configure the header wrapper.
- SET(KWSYS_STL_HEADER "${header}")
- IF(KWSYS_STL_HEADER_EXTRA_${header})
- SET(KWSYS_STL_HEADER_EXTRA
- "#define ${KWSYS_NAMESPACE}_stl_${header}_including_hxx\n# include <${KWSYS_NAMESPACE}/stl/${header}.hxx>\n#undef ${KWSYS_NAMESPACE}_stl_${header}_including_hxx\n")
- 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
- ${KWSYS_INSTALL_INCLUDE_OPTIONS})
- ENDIF(KWSYS_INSTALL_INCLUDE_DIR)
- ELSE(KWSYS_STL_HEADER_EXTRA_${header})
- SET(KWSYS_STL_HEADER_EXTRA "")
- ENDIF(KWSYS_STL_HEADER_EXTRA_${header})
- CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/kwsys_stl.hxx.in
- ${KWSYS_HEADER_DIR}/stl/${header}
- @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
- ${KWSYS_INSTALL_INCLUDE_OPTIONS})
- ENDIF(KWSYS_INSTALL_INCLUDE_DIR)
-ENDFOREACH(header)
-
-# Provide cstddef header.
-CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/kwsys_cstddef.hxx.in
- ${KWSYS_HEADER_DIR}/cstddef
- @ONLY IMMEDIATE)
-IF(KWSYS_INSTALL_INCLUDE_DIR)
- INSTALL(FILES ${KWSYS_HEADER_DIR}/cstddef
- DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}
- ${KWSYS_INSTALL_INCLUDE_OPTIONS})
-ENDIF(KWSYS_INSTALL_INCLUDE_DIR)
-
-#-----------------------------------------------------------------------------
-# Create streams header wrappers to give standard names by which they
-# may be included.
-FOREACH(header iostream fstream sstream iosfwd)
- # Configure the header wrapper.
- CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/kwsys_ios_${header}.h.in
- ${KWSYS_HEADER_DIR}/ios/${header}
- @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
- ${KWSYS_INSTALL_INCLUDE_OPTIONS})
- ENDIF(KWSYS_INSTALL_INCLUDE_DIR)
-ENDFOREACH(header)
+ENDIF()
#-----------------------------------------------------------------------------
# Build a list of classes and headers we need to implement the
@@ -861,8 +668,8 @@ SET(KWSYS_HXX_FILES Configure String
# Add selected C++ classes.
SET(cppclasses
- Directory DynamicLoader Glob RegularExpression SystemTools
- CommandLineArguments IOStream SystemInformation
+ Directory DynamicLoader Encoding Glob RegularExpression SystemTools
+ CommandLineArguments IOStream FStream SystemInformation
)
FOREACH(cpp ${cppclasses})
IF(KWSYS_USE_${cpp})
@@ -872,13 +679,13 @@ FOREACH(cpp ${cppclasses})
# Load component-specific CMake code.
IF(EXISTS ${PROJECT_SOURCE_DIR}/kwsys${cpp}.cmake)
INCLUDE(${PROJECT_SOURCE_DIR}/kwsys${cpp}.cmake)
- ENDIF(EXISTS ${PROJECT_SOURCE_DIR}/kwsys${cpp}.cmake)
- ENDIF(KWSYS_USE_${cpp})
-ENDFOREACH(cpp)
+ ENDIF()
+ ENDIF()
+ENDFOREACH()
# Add selected C components.
FOREACH(c
- Process Base64 FundamentalType MD5 Terminal System String CPU
+ Process Base64 Encoding MD5 Terminal System String
)
IF(KWSYS_USE_${c})
# Use the corresponding header file.
@@ -887,9 +694,9 @@ FOREACH(c
# Load component-specific CMake code.
IF(EXISTS ${PROJECT_SOURCE_DIR}/kwsys${c}.cmake)
INCLUDE(${PROJECT_SOURCE_DIR}/kwsys${c}.cmake)
- ENDIF(EXISTS ${PROJECT_SOURCE_DIR}/kwsys${c}.cmake)
- ENDIF(KWSYS_USE_${c})
-ENDFOREACH(c)
+ ENDIF()
+ ENDIF()
+ENDFOREACH()
#-----------------------------------------------------------------------------
# Build a list of sources for the library based on components that are
@@ -902,23 +709,31 @@ IF(KWSYS_USE_Process)
IF(NOT UNIX)
# Use the Windows implementation.
SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessWin32.c)
- ELSE(NOT UNIX)
+ ELSE()
# Use the UNIX implementation.
SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessUNIX.c)
- ENDIF(NOT UNIX)
-ENDIF(KWSYS_USE_Process)
+ ENDIF()
+ENDIF()
# Add selected C sources.
-FOREACH(c Base64 MD5 Terminal System String)
+FOREACH(c Base64 Encoding MD5 Terminal System String)
IF(KWSYS_USE_${c})
- SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ${c}.c)
- ENDIF(KWSYS_USE_${c})
-ENDFOREACH(c)
+ IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}C.c)
+ LIST(APPEND KWSYS_C_SRCS ${c}C.c)
+ ELSE()
+ LIST(APPEND KWSYS_C_SRCS ${c}.c)
+ ENDIF()
+ ENDIF()
+ENDFOREACH()
# Configure headers of C++ classes and construct the list of sources.
FOREACH(c ${KWSYS_CLASSES})
# Add this source to the list of source files for the library.
- SET(KWSYS_CXX_SRCS ${KWSYS_CXX_SRCS} ${c}.cxx)
+ IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}CXX.cxx)
+ LIST(APPEND KWSYS_CXX_SRCS ${c}CXX.cxx)
+ ELSEIF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}.cxx)
+ LIST(APPEND KWSYS_CXX_SRCS ${c}.cxx)
+ ENDIF()
# Configure the header for this class.
CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/${c}.hxx.in ${KWSYS_HEADER_DIR}/${c}.hxx
@@ -930,8 +745,8 @@ FOREACH(c ${KWSYS_CLASSES})
INSTALL(FILES ${KWSYS_HEADER_DIR}/${c}.hxx
DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}
${KWSYS_INSTALL_INCLUDE_OPTIONS})
- ENDIF(KWSYS_INSTALL_INCLUDE_DIR)
-ENDFOREACH(c)
+ ENDIF()
+ENDFOREACH()
# Configure C headers.
FOREACH(h ${KWSYS_H_FILES})
@@ -945,8 +760,8 @@ FOREACH(h ${KWSYS_H_FILES})
INSTALL(FILES ${KWSYS_HEADER_DIR}/${h}.h
DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}
${KWSYS_INSTALL_INCLUDE_OPTIONS})
- ENDIF(KWSYS_INSTALL_INCLUDE_DIR)
-ENDFOREACH(h)
+ ENDIF()
+ENDFOREACH()
# Configure other C++ headers.
FOREACH(h ${KWSYS_HXX_FILES})
@@ -960,8 +775,8 @@ FOREACH(h ${KWSYS_HXX_FILES})
INSTALL(FILES ${KWSYS_HEADER_DIR}/${h}.hxx
DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}
${KWSYS_INSTALL_INCLUDE_OPTIONS})
- ENDIF(KWSYS_INSTALL_INCLUDE_DIR)
-ENDFOREACH(h)
+ ENDIF()
+ENDFOREACH()
#-----------------------------------------------------------------------------
# Add the library with the configured name and list of sources.
@@ -972,8 +787,8 @@ IF(KWSYS_C_SRCS OR KWSYS_CXX_SRCS)
IF(KWSYS_USE_DynamicLoader)
IF(UNIX)
TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE} ${CMAKE_DL_LIBS})
- ENDIF(UNIX)
- ENDIF(KWSYS_USE_DynamicLoader)
+ ENDIF()
+ ENDIF()
IF(KWSYS_USE_SystemInformation)
IF(WIN32)
@@ -998,13 +813,13 @@ IF(KWSYS_C_SRCS OR KWSYS_CXX_SRCS)
SET_TARGET_PROPERTIES(${KWSYS_NAMESPACE} PROPERTIES
${KWSYS_PROPERTIES_CXX}
)
- ENDIF(KWSYS_PROPERTIES_CXX)
+ ENDIF()
# 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)
-ENDIF(KWSYS_C_SRCS OR KWSYS_CXX_SRCS)
+ ENDIF()
+ENDIF()
# Add a C-only library if requested.
IF(KWSYS_ENABLE_C AND KWSYS_C_SRCS)
@@ -1013,23 +828,23 @@ IF(KWSYS_ENABLE_C AND KWSYS_C_SRCS)
# Apply user-defined target properties to the library.
IF(KWSYS_PROPERTIES_C)
- SET_TARGET_PROPERTIES(${KWSYS_NAMESPACE} PROPERTIES
+ SET_TARGET_PROPERTIES(${KWSYS_NAMESPACE}_c PROPERTIES
${KWSYS_PROPERTIES_C}
)
- ENDIF(KWSYS_PROPERTIES_C)
+ ENDIF()
# 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)
-ENDIF(KWSYS_ENABLE_C AND KWSYS_C_SRCS)
+ ENDIF()
+ENDIF()
# For building kwsys itself, we use a macro defined on the command
# line to configure the namespace in the C and C++ source files.
ADD_DEFINITIONS("-DKWSYS_NAMESPACE=${KWSYS_NAMESPACE}")
# Disable deprecation warnings for standard C functions.
-IF(MSVC OR (WIN32 AND "${CMAKE_C_COMPILER_ID}" MATCHES "^(Intel)$"))
+IF(MSVC OR (WIN32 AND CMAKE_C_COMPILER_ID STREQUAL "Intel"))
ADD_DEFINITIONS(
-D_CRT_NONSTDC_NO_DEPRECATE
-D_CRT_SECURE_NO_DEPRECATE
@@ -1038,11 +853,22 @@ IF(MSVC OR (WIN32 AND "${CMAKE_C_COMPILER_ID}" MATCHES "^(Intel)$"))
)
ENDIF()
+IF(WIN32)
+ # Help enforce the use of wide Windows apis.
+ ADD_DEFINITIONS(-DUNICODE -D_UNICODE)
+ENDIF()
+
IF(KWSYS_USE_String)
# Activate code in "String.c". See the comment in the source.
SET_SOURCE_FILES_PROPERTIES(String.c PROPERTIES
COMPILE_FLAGS "-DKWSYS_STRING_C")
-ENDIF(KWSYS_USE_String)
+ENDIF()
+
+IF(KWSYS_USE_Encoding)
+ # Set default 8 bit encoding in "EndcodingC.c".
+ SET_PROPERTY(SOURCE EncodingC.c APPEND PROPERTY COMPILE_DEFINITIONS
+ KWSYS_ENCODING_DEFAULT_CODEPAGE=${KWSYS_ENCODING_DEFAULT_CODEPAGE})
+ENDIF()
#-----------------------------------------------------------------------------
# Setup testing if not being built as part of another project.
@@ -1052,7 +878,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
SET(EXEC_DIR "${CMAKE_CURRENT_BINARY_DIR}")
IF(EXECUTABLE_OUTPUT_PATH)
SET(EXEC_DIR "${EXECUTABLE_OUTPUT_PATH}")
- ENDIF(EXECUTABLE_OUTPUT_PATH)
+ ENDIF()
# C tests
SET(KWSYS_C_TESTS
@@ -1072,7 +898,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
FOREACH(test ${KWSYS_C_TESTS})
ADD_TEST(kwsys.${test} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsC ${test} ${KWSYS_TEST_ARGS_${test}})
SET_PROPERTY(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST})
- ENDFOREACH(test)
+ ENDFOREACH()
# C++ tests
IF(NOT WATCOM)
@@ -1080,23 +906,33 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
testAutoPtr
testHashSTL
)
- ENDIF(NOT WATCOM)
+ ENDIF()
SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
testIOS
testSystemTools
testCommandLineArguments
testCommandLineArguments1
)
+ IF(KWSYS_STL_HAS_WSTRING)
+ SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
+ testEncoding
+ )
+ ENDIF()
+ IF(KWSYS_USE_FStream)
+ SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
+ testFStream
+ )
+ ENDIF()
IF(KWSYS_USE_SystemInformation)
SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testSystemInformation)
- ENDIF(KWSYS_USE_SystemInformation)
+ ENDIF()
IF(KWSYS_USE_DynamicLoader)
SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testDynamicLoader)
# If kwsys contains the DynamicLoader, need extra library
ADD_LIBRARY(${KWSYS_NAMESPACE}TestDynload MODULE testDynload.c)
SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestDynload PROPERTY LABELS ${KWSYS_LABELS_LIB})
ADD_DEPENDENCIES(${KWSYS_NAMESPACE}TestDynload ${KWSYS_NAMESPACE})
- ENDIF(KWSYS_USE_DynamicLoader)
+ ENDIF()
CREATE_TEST_SOURCELIST(
KWSYS_CXX_TEST_SRCS ${KWSYS_NAMESPACE}TestsCxx.cxx
${KWSYS_CXX_TESTS}
@@ -1104,10 +940,9 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestsCxx ${KWSYS_CXX_TEST_SRCS})
SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY LABELS ${KWSYS_LABELS_EXE})
TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE}TestsCxx ${KWSYS_NAMESPACE})
- SET(TEST_SYSTEMTOOLS_BIN_FILE
- "${CMAKE_CURRENT_SOURCE_DIR}/testSystemTools.bin")
- SET(TEST_SYSTEMTOOLS_SRC_FILE
- "${CMAKE_CURRENT_SOURCE_DIR}/testSystemTools.cxx")
+
+ SET(TEST_SYSTEMTOOLS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+ SET(TEST_SYSTEMTOOLS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
CONFIGURE_FILE(
${PROJECT_SOURCE_DIR}/testSystemTools.h.in
${PROJECT_BINARY_DIR}/testSystemTools.h)
@@ -1117,7 +952,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/ExtraTest.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/ExtraTest.cmake")
SET_DIRECTORY_PROPERTIES(PROPERTIES TEST_INCLUDE_FILE "${CMAKE_CURRENT_BINARY_DIR}/ExtraTest.cmake")
- ENDIF(CTEST_TEST_KWSYS)
+ ENDIF()
SET(KWSYS_TEST_ARGS_testCommandLineArguments
--another-bool-variable
@@ -1150,7 +985,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
FOREACH(test ${KWSYS_CXX_TESTS})
ADD_TEST(kwsys.${test} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsCxx ${test} ${KWSYS_TEST_ARGS_${test}})
SET_PROPERTY(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST})
- ENDFOREACH(test)
+ ENDFOREACH()
# Process tests.
ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestProcess testProcess.c)
@@ -1158,16 +993,19 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE}TestProcess ${KWSYS_NAMESPACE}_c)
IF(NOT CYGWIN)
SET(KWSYS_TEST_PROCESS_7 7)
- ENDIF(NOT CYGWIN)
- FOREACH(n 1 2 3 4 5 6 ${KWSYS_TEST_PROCESS_7})
+ ENDIF()
+ FOREACH(n 1 2 3 4 5 6 ${KWSYS_TEST_PROCESS_7} 9 10)
ADD_TEST(kwsys.testProcess-${n} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestProcess ${n})
SET_PROPERTY(TEST kwsys.testProcess-${n} PROPERTY LABELS ${KWSYS_LABELS_TEST})
SET_TESTS_PROPERTIES(kwsys.testProcess-${n} PROPERTIES TIMEOUT 120)
- ENDFOREACH(n)
+ ENDFOREACH()
# Some Apple compilers produce bad optimizations in this source.
- IF(APPLE AND "${CMAKE_C_COMPILER_ID}" MATCHES "^(GNU|LLVM)$")
+ IF(APPLE AND CMAKE_C_COMPILER_ID MATCHES "^(GNU|LLVM)$")
SET_SOURCE_FILES_PROPERTIES(testProcess.c PROPERTIES COMPILE_FLAGS -O0)
+ ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "XL")
+ # Tell IBM XL not to warn about our test infinite loop
+ SET_PROPERTY(SOURCE testProcess.c PROPERTY COMPILE_FLAGS -qsuppress=1500-010)
ENDIF()
# Test SharedForward
@@ -1189,10 +1027,14 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
MESSAGE(STATUS "GET_TEST_PROPERTY returned: ${wfv}")
ENDIF()
+ # Set up ctest custom configuration file.
+ CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/CTestCustom.cmake.in
+ ${PROJECT_BINARY_DIR}/CTestCustom.cmake @ONLY)
+
# Suppress known consistent failures on buggy systems.
IF(KWSYS_TEST_BOGUS_FAILURES)
SET_TESTS_PROPERTIES(${KWSYS_TEST_BOGUS_FAILURES} PROPERTIES WILL_FAIL ON)
ENDIF()
- ENDIF(BUILD_TESTING)
-ENDIF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
+ ENDIF()
+ENDIF()
diff --git a/Source/kwsys/CONTRIBUTING.rst b/Source/kwsys/CONTRIBUTING.rst
new file mode 100644
index 000000000..960eea471
--- /dev/null
+++ b/Source/kwsys/CONTRIBUTING.rst
@@ -0,0 +1,35 @@
+Contributing to KWSys
+*********************
+
+Overview
+========
+
+KWSys is kept in its own Git repository and shared by several projects
+via copies in their source trees. Changes to KWSys should not be made
+directly in a host project, except perhaps in maintenance branches.
+
+Please visit
+
+ http://public.kitware.com/Wiki/KWSys/Git
+
+to contribute changes directly to KWSys upstream. Once changes are
+reviewed, tested, and integrated there then the copies of KWSys within
+dependent projects can be updated to get the changes.
+
+Issues
+======
+
+KWSys has no independent issue tracker. After encountering an issue
+(bug) please try to submit a patch using the above instructions.
+Otherwise please report the issue to the tracker for the project that
+hosts the copy of KWSys in which the problem was found.
+
+License
+=======
+
+We do not require any formal copyright assignment or contributor license
+agreement. Any contributions intentionally sent upstream are presumed
+to be offered under terms of the OSI-approved BSD 3-clause License.
+See `Copyright.txt`_ for details.
+
+.. _`Copyright.txt`: Copyright.txt
diff --git a/Source/kwsys/CPU.h.in b/Source/kwsys/CPU.h.in
deleted file mode 100644
index 2e1a584b1..000000000
--- a/Source/kwsys/CPU.h.in
+++ /dev/null
@@ -1,125 +0,0 @@
-/*============================================================================
- KWSys - Kitware System Library
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef @KWSYS_NAMESPACE@_CPU_h
-#define @KWSYS_NAMESPACE@_CPU_h
-
-#include <@KWSYS_NAMESPACE@/Configure.h>
-
-/* Identify possible endian cases. The macro
- @KWSYS_NAMESPACE@_CPU_ENDIAN_ID will be defined to one of these, or
- 0 if unknown. */
-#define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_BIG 4321
-#define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_LITTLE 1234
-
-/* Apple always defines one of these. */
-#if defined(__LITTLE_ENDIAN__)
-# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_LITTLE
-#elif defined(__BIG_ENDIAN__)
-# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_BIG
-
-/* Alpha */
-#elif defined(__alpha) || defined(__alpha__) || defined(_M_ALPHA)
-# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_LITTLE
-
-/* Arm */
-#elif defined(__arm__)
-# if !defined(__ARMEB__)
-# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_LITTLE
-# else
-# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_BIG
-# endif
-
-/* Intel x86 */
-#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
-# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_LITTLE
-#elif defined(_X86_) || defined(__THW_INTEL__) || defined(__I86__)
-# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_LITTLE
-#elif defined(__MWERKS__) && defined(__INTEL__)
-# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_LITTLE
-
-/* Intel x86-64 */
-#elif defined(__x86_64) || defined(__x86_64__) || defined(_M_X64)
-# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_LITTLE
-#elif defined(__amd64) || defined(__amd64__)
-# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_LITTLE
-
-/* Intel Architecture-64 (Itanium) */
-#elif defined(__ia64) || defined(__ia64__)
-# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_LITTLE
-#elif defined(_IA64) || defined(__IA64__) || defined(_M_IA64)
-# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_LITTLE
-
-/* PowerPC */
-#elif defined(__powerpc) || defined(__powerpc__)
-# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_BIG
-#elif defined(__ppc) || defined(__ppc__) || defined(__POWERPC__)
-# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_BIG
-
-/* SPARC */
-#elif defined(__sparc) || defined(__sparc__)
-# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_BIG
-
-/* HP/PA RISC */
-#elif defined(__hppa) || defined(__hppa__)
-# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_BIG
-
-/* Motorola 68k */
-#elif defined(__m68k__) || defined(M68000)
-# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_BIG
-
-/* MIPS */
-#elif defined(__mips) || defined(__mips__) || defined(__MIPS__)
-# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_BIG
-
-/* RS/6000 */
-#elif defined(__THW_RS600) || defined(_IBMR2) || defined(_POWER)
-# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_BIG
-#elif defined(_ARCH_PWR) || defined(_ARCH_PWR2)
-# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_BIG
-
-/* System/370 */
-#elif defined(__370__) || defined(__THW_370__)
-# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_BIG
-
-/* System/390 */
-#elif defined(__s390__) || defined(__s390x__)
-# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_BIG
-
-/* z/Architecture */
-#elif defined(__SYSC_ZARCH__)
-# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_BIG
-
-/* Aarch64 */
-#elif defined(__aarch64__)
-# if !defined(__AARCH64EB__)
-# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_LITTLE
-# else
-# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_BIG
-# endif
-
-/* Unknown CPU */
-#else
-# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID 0
-# if !defined(@KWSYS_NAMESPACE@_CPU_UNKNOWN_OKAY)
-# error "The target CPU architecture is not known."
-# endif
-#endif
-
-/* If building a C or C++ file in kwsys itself, give the source file
- access to the macros without a configured namespace. */
-#if defined(KWSYS_NAMESPACE)
-# define KWSYS_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID
-# define KWSYS_CPU_ENDIAN_ID_BIG @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_BIG
-# define KWSYS_CPU_ENDIAN_ID_LITTLE @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_LITTLE
-#endif
-
-#endif
diff --git a/Source/kwsys/CTestCustom.cmake.in b/Source/kwsys/CTestCustom.cmake.in
new file mode 100644
index 000000000..760221b12
--- /dev/null
+++ b/Source/kwsys/CTestCustom.cmake.in
@@ -0,0 +1,14 @@
+# kwsys.testProcess-10 involves sending SIGINT to a child process, which then
+# exits abnormally via a call to _exit(). (On Windows, a call to ExitProcess).
+# Naturally, this results in plenty of memory being "leaked" by this child
+# process - the memory check results are not meaningful in this case.
+#
+# kwsys.testProcess-9 also tests sending SIGINT to a child process. However,
+# normal operation of that test involves the child process timing out, and the
+# host process kills (SIGKILL) it as a result. Since it was SIGKILL'ed, the
+# resulting memory leaks are not logged by valgrind anyway. Therefore, we
+# don't have to exclude it.
+
+list(APPEND CTEST_CUSTOM_MEMCHECK_IGNORE
+ kwsys.testProcess-10
+ )
diff --git a/Source/kwsys/CommandLineArguments.cxx b/Source/kwsys/CommandLineArguments.cxx
index ece88ae89..36368368b 100644
--- a/Source/kwsys/CommandLineArguments.cxx
+++ b/Source/kwsys/CommandLineArguments.cxx
@@ -15,22 +15,19 @@
#include KWSYS_HEADER(Configure.hxx)
#include KWSYS_HEADER(String.hxx)
-#include KWSYS_HEADER(stl/vector)
-#include KWSYS_HEADER(stl/map)
-#include KWSYS_HEADER(stl/set)
-#include KWSYS_HEADER(ios/sstream)
-#include KWSYS_HEADER(ios/iostream)
-
// Work-around CMake dependency scanning limitation. This must
// duplicate the above list of headers.
#if 0
# include "CommandLineArguments.hxx.in"
# include "Configure.hxx.in"
-# include "kwsys_stl.hxx.in"
-# include "kwsys_ios_sstream.h.in"
-# include "kwsys_ios_iostream.h.in"
#endif
+#include <vector>
+#include <map>
+#include <set>
+#include <sstream>
+#include <iostream>
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -45,7 +42,7 @@
#if 0
# define CommandLineArguments_DEBUG(x) \
- kwsys_ios::cout << __LINE__ << " CLA: " << x << kwsys_ios::endl
+ std::cout << __LINE__ << " CLA: " << x << std::endl
#else
# define CommandLineArguments_DEBUG(x)
#endif
@@ -67,11 +64,11 @@ struct CommandLineArgumentsCallbackStructure
};
class CommandLineArgumentsVectorOfStrings :
- public kwsys_stl::vector<kwsys::String> {};
+ public std::vector<kwsys::String> {};
class CommandLineArgumentsSetOfStrings :
- public kwsys_stl::set<kwsys::String> {};
+ public std::set<kwsys::String> {};
class CommandLineArgumentsMapOfStrucs :
- public kwsys_stl::map<kwsys::String,
+ public std::map<kwsys::String,
CommandLineArgumentsCallbackStructure> {};
class CommandLineArgumentsInternal
@@ -152,8 +149,8 @@ void CommandLineArguments::ProcessArgument(const char* arg)
//----------------------------------------------------------------------------
bool CommandLineArguments::GetMatchedArguments(
- kwsys_stl::vector<kwsys_stl::string>* matches,
- const kwsys_stl::string& arg)
+ std::vector<std::string>* matches,
+ const std::string& arg)
{
matches->clear();
CommandLineArguments::Internal::CallbacksMap::iterator it;
@@ -178,21 +175,21 @@ bool CommandLineArguments::GetMatchedArguments(
matches->push_back(parg);
}
}
- return matches->size() > 0;
+ return !matches->empty();
}
//----------------------------------------------------------------------------
int CommandLineArguments::Parse()
{
- kwsys_stl::vector<kwsys_stl::string>::size_type cc;
- kwsys_stl::vector<kwsys_stl::string> matches;
+ std::vector<std::string>::size_type cc;
+ std::vector<std::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];
+ const std::string& arg = this->Internals->Argv[cc];
CommandLineArguments_DEBUG("Process argument: " << arg);
this->Internals->LastArgument = cc;
if ( this->GetMatchedArguments(&matches, arg) )
@@ -214,7 +211,7 @@ int CommandLineArguments::Parse()
// additional value
CommandLineArgumentsCallbackStructure *cs
= &this->Internals->Callbacks[matches[maxidx]];
- const kwsys_stl::string& sarg = matches[maxidx];
+ const std::string& sarg = matches[maxidx];
if ( cs->Argument != sarg )
{
abort();
@@ -235,7 +232,7 @@ int CommandLineArguments::Parse()
return 0;
}
CommandLineArguments_DEBUG("This is a space argument: " << arg
- << " value: " << this->Internals->Argv[cc+1].c_str());
+ << " value: " << this->Internals->Argv[cc+1]);
// Value is the next argument
if ( !this->PopulateVariable(cs, this->Internals->Argv[cc+1].c_str()) )
{
@@ -244,7 +241,7 @@ int CommandLineArguments::Parse()
cc ++;
break;
case EQUAL_ARGUMENT:
- if ( arg.size() == sarg.size() || *(arg.c_str() + sarg.size()) != '=' )
+ if ( arg.size() == sarg.size() || arg.at(sarg.size()) != '=' )
{
this->Internals->LastArgument --;
return 0;
@@ -267,7 +264,7 @@ int CommandLineArguments::Parse()
CommandLineArguments_DEBUG("This is a multi argument: " << arg);
for (cc++; cc < this->Internals->Argv.size(); ++ cc )
{
- const kwsys_stl::string& marg = this->Internals->Argv[cc];
+ const std::string& marg = this->Internals->Argv[cc];
CommandLineArguments_DEBUG(" check multi argument value: " << marg);
if ( this->GetMatchedArguments(&matches, marg) )
{
@@ -288,7 +285,7 @@ int CommandLineArguments::Parse()
}
break;
default:
- kwsys_ios::cerr << "Got unknown argument type: \"" << cs->ArgumentType << "\"" << kwsys_ios::endl;
+ std::cerr << "Got unknown argument type: \"" << cs->ArgumentType << "\"" << std::endl;
this->Internals->LastArgument --;
return 0;
}
@@ -309,11 +306,11 @@ int CommandLineArguments::Parse()
else if ( this->StoreUnusedArgumentsFlag )
{
CommandLineArguments_DEBUG("Store unused argument " << arg);
- this->Internals->UnusedArguments.push_back(arg.c_str());
+ this->Internals->UnusedArguments.push_back(arg);
}
else
{
- kwsys_ios::cerr << "Got unknown argument: \"" << arg.c_str() << "\"" << kwsys_ios::endl;
+ std::cerr << "Got unknown argument: \"" << arg << "\"" << std::endl;
this->Internals->LastArgument --;
return 0;
}
@@ -430,13 +427,13 @@ CommandLineArgumentsAddArgumentMacro(BOOL, bool)
CommandLineArgumentsAddArgumentMacro(INT, int)
CommandLineArgumentsAddArgumentMacro(DOUBLE, double)
CommandLineArgumentsAddArgumentMacro(STRING, char*)
-CommandLineArgumentsAddArgumentMacro(STL_STRING, kwsys_stl::string)
+CommandLineArgumentsAddArgumentMacro(STL_STRING, std::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>)
+CommandLineArgumentsAddArgumentMacro(VECTOR_BOOL, std::vector<bool>)
+CommandLineArgumentsAddArgumentMacro(VECTOR_INT, std::vector<int>)
+CommandLineArgumentsAddArgumentMacro(VECTOR_DOUBLE, std::vector<double>)
+CommandLineArgumentsAddArgumentMacro(VECTOR_STRING, std::vector<char*>)
+CommandLineArgumentsAddArgumentMacro(VECTOR_STL_STRING, std::vector<std::string>)
//----------------------------------------------------------------------------
#define CommandLineArgumentsAddBooleanArgumentMacro(type, ctype) \
@@ -451,7 +448,7 @@ CommandLineArgumentsAddBooleanArgumentMacro(BOOL, bool)
CommandLineArgumentsAddBooleanArgumentMacro(INT, int)
CommandLineArgumentsAddBooleanArgumentMacro(DOUBLE, double)
CommandLineArgumentsAddBooleanArgumentMacro(STRING, char*)
-CommandLineArgumentsAddBooleanArgumentMacro(STL_STRING, kwsys_stl::string)
+CommandLineArgumentsAddBooleanArgumentMacro(STL_STRING, std::string)
//----------------------------------------------------------------------------
void CommandLineArguments::SetClientData(void* client_data)
@@ -518,12 +515,12 @@ unsigned int CommandLineArguments::GetLastArgument()
//----------------------------------------------------------------------------
void CommandLineArguments::GenerateHelp()
{
- kwsys_ios::ostringstream str;
+ std::ostringstream str;
// Collapse all arguments into the map of vectors of all arguments that do
// the same thing.
CommandLineArguments::Internal::CallbacksMap::iterator it;
- typedef kwsys_stl::map<CommandLineArguments::Internal::String,
+ typedef std::map<CommandLineArguments::Internal::String,
CommandLineArguments::Internal::SetOfStrings > MapArgs;
MapArgs mp;
MapArgs::iterator mpit, smpit;
@@ -604,7 +601,7 @@ void CommandLineArguments::GenerateHelp()
CommandLineArguments::Internal::SetOfStrings::iterator sit;
for ( sit = mpit->second.begin(); sit != mpit->second.end(); sit++ )
{
- str << kwsys_ios::endl;
+ str << std::endl;
char argument[100];
sprintf(argument, "%s", sit->c_str());
switch ( this->Internals->Callbacks[*sit].ArgumentType )
@@ -658,8 +655,8 @@ void CommandLineArguments::GenerateHelp()
skip = cc;
}
}
- str.write(ptr, static_cast<kwsys_ios::streamsize>(skip));
- str << kwsys_ios::endl;
+ str.write(ptr, static_cast<std::streamsize>(skip));
+ str << std::endl;
ptr += skip;
len -= skip;
cnt ++;
@@ -680,7 +677,7 @@ void CommandLineArguments::GenerateHelp()
//----------------------------------------------------------------------------
void CommandLineArguments::PopulateVariable(
- bool* variable, const kwsys_stl::string& value)
+ bool* variable, const std::string& value)
{
if ( value == "1" || value == "ON" || value == "on" || value == "On" ||
value == "TRUE" || value == "true" || value == "True" ||
@@ -696,7 +693,7 @@ void CommandLineArguments::PopulateVariable(
//----------------------------------------------------------------------------
void CommandLineArguments::PopulateVariable(
- int* variable, const kwsys_stl::string& value)
+ int* variable, const std::string& value)
{
char* res = 0;
*variable = static_cast<int>(strtol(value.c_str(), &res, 10));
@@ -708,7 +705,7 @@ void CommandLineArguments::PopulateVariable(
//----------------------------------------------------------------------------
void CommandLineArguments::PopulateVariable(
- double* variable, const kwsys_stl::string& value)
+ double* variable, const std::string& value)
{
char* res = 0;
*variable = strtod(value.c_str(), &res);
@@ -720,7 +717,7 @@ void CommandLineArguments::PopulateVariable(
//----------------------------------------------------------------------------
void CommandLineArguments::PopulateVariable(
- char** variable, const kwsys_stl::string& value)
+ char** variable, const std::string& value)
{
if ( *variable )
{
@@ -733,14 +730,14 @@ void CommandLineArguments::PopulateVariable(
//----------------------------------------------------------------------------
void CommandLineArguments::PopulateVariable(
- kwsys_stl::string* variable, const kwsys_stl::string& value)
+ std::string* variable, const std::string& value)
{
*variable = value;
}
//----------------------------------------------------------------------------
void CommandLineArguments::PopulateVariable(
- kwsys_stl::vector<bool>* variable, const kwsys_stl::string& value)
+ std::vector<bool>* variable, const std::string& value)
{
bool val = false;
if ( value == "1" || value == "ON" || value == "on" || value == "On" ||
@@ -754,7 +751,7 @@ void CommandLineArguments::PopulateVariable(
//----------------------------------------------------------------------------
void CommandLineArguments::PopulateVariable(
- kwsys_stl::vector<int>* variable, const kwsys_stl::string& value)
+ std::vector<int>* variable, const std::string& value)
{
char* res = 0;
variable->push_back(static_cast<int>(strtol(value.c_str(), &res, 10)));
@@ -766,7 +763,7 @@ void CommandLineArguments::PopulateVariable(
//----------------------------------------------------------------------------
void CommandLineArguments::PopulateVariable(
- kwsys_stl::vector<double>* variable, const kwsys_stl::string& value)
+ std::vector<double>* variable, const std::string& value)
{
char* res = 0;
variable->push_back(strtod(value.c_str(), &res));
@@ -778,7 +775,7 @@ void CommandLineArguments::PopulateVariable(
//----------------------------------------------------------------------------
void CommandLineArguments::PopulateVariable(
- kwsys_stl::vector<char*>* variable, const kwsys_stl::string& value)
+ std::vector<char*>* variable, const std::string& value)
{
char* var = new char[ value.size() + 1 ];
strcpy(var, value.c_str());
@@ -787,8 +784,8 @@ void CommandLineArguments::PopulateVariable(
//----------------------------------------------------------------------------
void CommandLineArguments::PopulateVariable(
- kwsys_stl::vector<kwsys_stl::string>* variable,
- const kwsys_stl::string& value)
+ std::vector<std::string>* variable,
+ const std::string& value)
{
variable->push_back(value);
}
@@ -809,7 +806,7 @@ bool CommandLineArguments::PopulateVariable(CommandLineArgumentsCallbackStructur
CommandLineArguments_DEBUG("Set argument: " << cs->Argument << " to " << value);
if ( cs->Variable )
{
- kwsys_stl::string var = "1";
+ std::string var = "1";
if ( value )
{
var = value;
@@ -826,28 +823,28 @@ bool CommandLineArguments::PopulateVariable(CommandLineArgumentsCallbackStructur
this->PopulateVariable(static_cast<char**>(cs->Variable), var);
break;
case CommandLineArguments::STL_STRING_TYPE:
- this->PopulateVariable(static_cast<kwsys_stl::string*>(cs->Variable), var);
+ this->PopulateVariable(static_cast<std::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);
+ this->PopulateVariable(static_cast<std::vector<bool>*>(cs->Variable), var);
break;
case CommandLineArguments::VECTOR_INT_TYPE:
- this->PopulateVariable(static_cast<kwsys_stl::vector<int>*>(cs->Variable), var);
+ this->PopulateVariable(static_cast<std::vector<int>*>(cs->Variable), var);
break;
case CommandLineArguments::VECTOR_DOUBLE_TYPE:
- this->PopulateVariable(static_cast<kwsys_stl::vector<double>*>(cs->Variable), var);
+ this->PopulateVariable(static_cast<std::vector<double>*>(cs->Variable), var);
break;
case CommandLineArguments::VECTOR_STRING_TYPE:
- this->PopulateVariable(static_cast<kwsys_stl::vector<char*>*>(cs->Variable), var);
+ this->PopulateVariable(static_cast<std::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);
+ this->PopulateVariable(static_cast<std::vector<std::string>*>(cs->Variable), var);
break;
default:
- kwsys_ios::cerr << "Got unknown variable type: \"" << cs->VariableType << "\"" << kwsys_ios::endl;
+ std::cerr << "Got unknown variable type: \"" << cs->VariableType << "\"" << std::endl;
this->Internals->LastArgument --;
return 0;
}
diff --git a/Source/kwsys/CommandLineArguments.hxx.in b/Source/kwsys/CommandLineArguments.hxx.in
index cbf6ee393..e4f6d0265 100644
--- a/Source/kwsys/CommandLineArguments.hxx.in
+++ b/Source/kwsys/CommandLineArguments.hxx.in
@@ -15,13 +15,8 @@
#include <@KWSYS_NAMESPACE@/Configure.h>
#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
-# define kwsys_stl @KWSYS_NAMESPACE@_stl
-#endif
+#include <string>
+#include <vector>
namespace @KWSYS_NAMESPACE@
{
@@ -64,7 +59,7 @@ struct CommandLineArgumentsCallbackStructure;
* "This is help string for --something");
* if ( !arg.Parse() )
* {
- * kwsys_ios::cerr << "Problem parsing arguments" << kwsys_ios::endl;
+ * std::cerr << "Problem parsing arguments" << std::endl;
* res = 1;
* }
*
@@ -155,7 +150,7 @@ public:
void AddArgument(const char* argument, ArgumentTypeEnum type,
char** variable, const char* help);
void AddArgument(const char* argument, ArgumentTypeEnum type,
- kwsys_stl::string* variable, const char* help);
+ std::string* variable, const char* help);
/**
* Add handler for argument which is going to set the variable to the
@@ -163,15 +158,15 @@ public:
* appropriate type. This will handle the multi argument values.
*/
void AddArgument(const char* argument, ArgumentTypeEnum type,
- kwsys_stl::vector<bool>* variable, const char* help);
+ std::vector<bool>* variable, const char* help);
void AddArgument(const char* argument, ArgumentTypeEnum type,
- kwsys_stl::vector<int>* variable, const char* help);
+ std::vector<int>* variable, const char* help);
void AddArgument(const char* argument, ArgumentTypeEnum type,
- kwsys_stl::vector<double>* variable, const char* help);
+ std::vector<double>* variable, const char* help);
void AddArgument(const char* argument, ArgumentTypeEnum type,
- kwsys_stl::vector<char*>* variable, const char* help);
+ std::vector<char*>* variable, const char* help);
void AddArgument(const char* argument, ArgumentTypeEnum type,
- kwsys_stl::vector<kwsys_stl::string>* variable, const char* help);
+ std::vector<std::string>* variable, const char* help);
/**
* Add handler for boolean argument. The argument does not take any option
@@ -187,7 +182,7 @@ public:
void AddBooleanArgument(const char* argument,
char** variable, const char* help);
void AddBooleanArgument(const char* argument,
- kwsys_stl::string* variable, const char* help);
+ std::string* variable, const char* help);
/**
* Set the callbacks for error handling.
@@ -243,28 +238,28 @@ 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);
+ bool GetMatchedArguments(std::vector<std::string>* matches,
+ const std::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);
+ void PopulateVariable(bool* variable, const std::string& value);
+ void PopulateVariable(int* variable, const std::string& value);
+ void PopulateVariable(double* variable, const std::string& value);
+ void PopulateVariable(char** variable, const std::string& value);
+ void PopulateVariable(std::string* variable, const std::string& value);
+ void PopulateVariable(std::vector<bool>* variable, const std::string& value);
+ void PopulateVariable(std::vector<int>* variable, const std::string& value);
+ void PopulateVariable(std::vector<double>* variable, const std::string& value);
+ void PopulateVariable(std::vector<char*>* variable, const std::string& value);
+ void PopulateVariable(std::vector<std::string>* variable, const std::string& value);
typedef CommandLineArgumentsInternal Internal;
Internal* Internals;
- kwsys_stl::string Help;
+ std::string Help;
unsigned int LineLength;
@@ -273,11 +268,6 @@ protected:
} // namespace @KWSYS_NAMESPACE@
-/* Undefine temporary macro. */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
-# undef kwsys_stl
-#endif
-
#endif
diff --git a/Source/kwsys/Configure.h.in b/Source/kwsys/Configure.h.in
index 70cf8442b..cd2d96519 100644
--- a/Source/kwsys/Configure.h.in
+++ b/Source/kwsys/Configure.h.in
@@ -115,6 +115,11 @@
# pragma warning (disable: 4710) /* function not inlined */
# pragma warning (disable: 4786) /* identifier truncated in debug info */
# endif
+# if defined(__BORLANDC__) && !defined(__cplusplus)
+ /* Code has no effect; raised by winnt.h in C (not C++) when ignoring an
+ unused parameter using "(param)" syntax (i.e. no cast to void). */
+# pragma warn -8019
+# endif
#endif
/* MSVC 6.0 in release mode will warn about code it produces with its
diff --git a/Source/kwsys/Configure.hxx.in b/Source/kwsys/Configure.hxx.in
index 716b84f09..ff8e49dba 100644
--- a/Source/kwsys/Configure.hxx.in
+++ b/Source/kwsys/Configure.hxx.in
@@ -15,161 +15,17 @@
/* Include C configuration. */
#include <@KWSYS_NAMESPACE@/Configure.h>
-/* Whether ANSI C++ stream headers are to be used. */
-#define @KWSYS_NAMESPACE@_IOS_USE_ANSI @KWSYS_IOS_USE_ANSI@
-
-/* Whether ANSI C++ streams are in std namespace. */
-#define @KWSYS_NAMESPACE@_IOS_HAVE_STD @KWSYS_IOS_HAVE_STD@
-
-/* Whether ANSI C++ <sstream> header is to be used. */
-#define @KWSYS_NAMESPACE@_IOS_USE_SSTREAM @KWSYS_IOS_USE_SSTREAM@
-
-/* Whether old C++ <strstream.h> header is to be used. */
-#define @KWSYS_NAMESPACE@_IOS_USE_STRSTREAM_H @KWSYS_IOS_USE_STRSTREAM_H@
-
-/* Whether old C++ <strstrea.h> header is to be used. */
-#define @KWSYS_NAMESPACE@_IOS_USE_STRSTREA_H @KWSYS_IOS_USE_STRSTREA_H@
-
-/* Whether C++ streams support the ios::binary openmode. */
-#define @KWSYS_NAMESPACE@_IOS_HAVE_BINARY @KWSYS_IOS_HAVE_BINARY@
-
-/* Whether STL is in std namespace. */
-#define @KWSYS_NAMESPACE@_STL_HAVE_STD @KWSYS_STL_HAVE_STD@
-
-/* Whether the STL string has operator<< for ostream. */
-#define @KWSYS_NAMESPACE@_STL_STRING_HAVE_OSTREAM @KWSYS_STL_STRING_HAVE_OSTREAM@
-
-/* Whether the STL string has operator>> for istream. */
-#define @KWSYS_NAMESPACE@_STL_STRING_HAVE_ISTREAM @KWSYS_STL_STRING_HAVE_ISTREAM@
-
-/* Whether the STL string has operator!= for char*. */
-#define @KWSYS_NAMESPACE@_STL_STRING_HAVE_NEQ_CHAR @KWSYS_STL_STRING_HAVE_NEQ_CHAR@
-
-/* Define the stl namespace macro. */
-#if @KWSYS_NAMESPACE@_STL_HAVE_STD
-# define @KWSYS_NAMESPACE@_stl std
-#else
-# define @KWSYS_NAMESPACE@_stl
-#endif
-
-/* Define the ios namespace macro. */
-#if @KWSYS_NAMESPACE@_IOS_HAVE_STD
-# define @KWSYS_NAMESPACE@_ios_namespace std
-#else
-# define @KWSYS_NAMESPACE@_ios_namespace
-#endif
-#if @KWSYS_NAMESPACE@_IOS_USE_SSTREAM
-# define @KWSYS_NAMESPACE@_ios @KWSYS_NAMESPACE@_ios_namespace
-#else
-# define @KWSYS_NAMESPACE@_ios @KWSYS_NAMESPACE@_ios
-#endif
-
-/* Define the ios::binary openmode macro. */
-#if @KWSYS_NAMESPACE@_IOS_HAVE_BINARY
-# define @KWSYS_NAMESPACE@_ios_binary @KWSYS_NAMESPACE@_ios::ios::binary
-#else
-# define @KWSYS_NAMESPACE@_ios_binary 0
-#endif
-
-/* Whether the cstddef header is available. */
-#define @KWSYS_NAMESPACE@_CXX_HAS_CSTDDEF @KWSYS_CXX_HAS_CSTDDEF@
-
-/* Whether the compiler supports null template arguments. */
-#define @KWSYS_NAMESPACE@_CXX_HAS_NULL_TEMPLATE_ARGS @KWSYS_CXX_HAS_NULL_TEMPLATE_ARGS@
-
-/* Define the null template arguments macro. */
-#if @KWSYS_NAMESPACE@_CXX_HAS_NULL_TEMPLATE_ARGS
-# define @KWSYS_NAMESPACE@_CXX_NULL_TEMPLATE_ARGS <>
-#else
-# define @KWSYS_NAMESPACE@_CXX_NULL_TEMPLATE_ARGS
-#endif
-
-/* Whether the compiler supports member templates. */
-#define @KWSYS_NAMESPACE@_CXX_HAS_MEMBER_TEMPLATES @KWSYS_CXX_HAS_MEMBER_TEMPLATES@
-
-/* Whether the compiler supports argument dependent lookup. */
-#define @KWSYS_NAMESPACE@_CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP @KWSYS_CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP@
-
-/* Whether the compiler supports standard full specialization syntax. */
-#define @KWSYS_NAMESPACE@_CXX_HAS_FULL_SPECIALIZATION @KWSYS_CXX_HAS_FULL_SPECIALIZATION@
-
-/* Define the specialization definition macro. */
-#if @KWSYS_NAMESPACE@_CXX_HAS_FULL_SPECIALIZATION
-# define @KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION template <>
-#else
-# define @KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
-#endif
-
-/* Define typename keyword macro for use in declarations. */
-#if defined(_MSC_VER) && _MSC_VER < 1300
-# define @KWSYS_NAMESPACE@_CXX_DECL_TYPENAME
-#else
-# define @KWSYS_NAMESPACE@_CXX_DECL_TYPENAME typename
-#endif
-
-/* Whether the stl has iterator_traits. */
-#define @KWSYS_NAMESPACE@_STL_HAS_ITERATOR_TRAITS @KWSYS_STL_HAS_ITERATOR_TRAITS@
-
-/* Whether the stl has iterator_category. */
-#define @KWSYS_NAMESPACE@_STL_HAS_ITERATOR_CATEGORY @KWSYS_STL_HAS_ITERATOR_CATEGORY@
-
-/* Whether the stl has __iterator_category. */
-#define @KWSYS_NAMESPACE@_STL_HAS___ITERATOR_CATEGORY @KWSYS_STL_HAS___ITERATOR_CATEGORY@
-
-/* Whether the stl allocator is the standard template. */
-#define @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_TEMPLATE @KWSYS_STL_HAS_ALLOCATOR_TEMPLATE@
-
-/* Whether the stl allocator is not a template. */
-#define @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_NONTEMPLATE @KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE@
-
-/* Whether the stl allocator has rebind. */
-#define @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_REBIND @KWSYS_STL_HAS_ALLOCATOR_REBIND@
-
-/* Whether the stl allocator has a size argument for max_size. */
-#define @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT @KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT@
-
-/* Whether the stl containers support allocator objects. */
-#define @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_OBJECTS @KWSYS_STL_HAS_ALLOCATOR_OBJECTS@
-
-/* Whether struct stat has the st_mtim member for high resolution times. */
-#define @KWSYS_NAMESPACE@_STAT_HAS_ST_MTIM @KWSYS_STAT_HAS_ST_MTIM@
+/* Whether wstring is available. */
+#define @KWSYS_NAMESPACE@_STL_HAS_WSTRING @KWSYS_STL_HAS_WSTRING@
/* If building a C++ file in kwsys itself, give the source file
access to the macros without a configured namespace. */
#if defined(KWSYS_NAMESPACE)
# if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
-# define kwsys_stl @KWSYS_NAMESPACE@_stl
-# define kwsys_ios @KWSYS_NAMESPACE@_ios
# define kwsys @KWSYS_NAMESPACE@
-# define kwsys_ios_binary @KWSYS_NAMESPACE@_ios_binary
# endif
# define KWSYS_NAME_IS_KWSYS @KWSYS_NAMESPACE@_NAME_IS_KWSYS
-# define KWSYS_STL_HAVE_STD @KWSYS_NAMESPACE@_STL_HAVE_STD
-# define KWSYS_IOS_HAVE_STD @KWSYS_NAMESPACE@_IOS_HAVE_STD
-# define KWSYS_IOS_USE_ANSI @KWSYS_NAMESPACE@_IOS_USE_ANSI
-# define KWSYS_IOS_USE_SSTREAM @KWSYS_NAMESPACE@_IOS_USE_SSTREAM
-# define KWSYS_IOS_USE_STRSTREAM_H @KWSYS_NAMESPACE@_IOS_USE_STRSTREAM_H
-# define KWSYS_IOS_USE_STRSTREA_H @KWSYS_NAMESPACE@_IOS_USE_STRSTREA_H
-# define KWSYS_IOS_HAVE_BINARY @KWSYS_NAMESPACE@_IOS_HAVE_BINARY
-# define KWSYS_STAT_HAS_ST_MTIM @KWSYS_NAMESPACE@_STAT_HAS_ST_MTIM
-# define KWSYS_CXX_HAS_CSTDDEF @KWSYS_NAMESPACE@_CXX_HAS_CSTDDEF
-# define KWSYS_STL_STRING_HAVE_OSTREAM @KWSYS_NAMESPACE@_STL_STRING_HAVE_OSTREAM
-# define KWSYS_STL_STRING_HAVE_ISTREAM @KWSYS_NAMESPACE@_STL_STRING_HAVE_ISTREAM
-# define KWSYS_STL_STRING_HAVE_NEQ_CHAR @KWSYS_NAMESPACE@_STL_STRING_HAVE_NEQ_CHAR
-# define KWSYS_CXX_NULL_TEMPLATE_ARGS @KWSYS_NAMESPACE@_CXX_NULL_TEMPLATE_ARGS
-# define KWSYS_CXX_HAS_MEMBER_TEMPLATES @KWSYS_NAMESPACE@_CXX_HAS_MEMBER_TEMPLATES
-# define KWSYS_CXX_HAS_FULL_SPECIALIZATION @KWSYS_NAMESPACE@_CXX_HAS_FULL_SPECIALIZATION
-# define KWSYS_CXX_DEFINE_SPECIALIZATION @KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
-# define KWSYS_CXX_DECL_TYPENAME @KWSYS_NAMESPACE@_CXX_DECL_TYPENAME
-# define KWSYS_STL_HAS_ALLOCATOR_REBIND @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_REBIND
-# define KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT
-# define KWSYS_CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP @KWSYS_NAMESPACE@_CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP
-# define KWSYS_STL_HAS_ITERATOR_TRAITS @KWSYS_NAMESPACE@_STL_HAS_ITERATOR_TRAITS
-# define KWSYS_STL_HAS_ITERATOR_CATEGORY @KWSYS_NAMESPACE@_STL_HAS_ITERATOR_CATEGORY
-# define KWSYS_STL_HAS___ITERATOR_CATEGORY @KWSYS_NAMESPACE@_STL_HAS___ITERATOR_CATEGORY
-# define KWSYS_STL_HAS_ALLOCATOR_TEMPLATE @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_TEMPLATE
-# define KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_NONTEMPLATE
-# define KWSYS_STL_HAS_ALLOCATOR_OBJECTS @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_OBJECTS
+# define KWSYS_STL_HAS_WSTRING @KWSYS_NAMESPACE@_STL_HAS_WSTRING
#endif
#endif
diff --git a/Source/kwsys/Directory.cxx b/Source/kwsys/Directory.cxx
index b88474781..c549792d2 100644
--- a/Source/kwsys/Directory.cxx
+++ b/Source/kwsys/Directory.cxx
@@ -14,19 +14,19 @@
#include KWSYS_HEADER(Configure.hxx)
-#include KWSYS_HEADER(stl/string)
-#include KWSYS_HEADER(stl/vector)
+#include KWSYS_HEADER(Encoding.hxx)
// Work-around CMake dependency scanning limitation. This must
// duplicate the above list of headers.
#if 0
# include "Directory.hxx.in"
# include "Configure.hxx.in"
-# include "kwsys_stl.hxx.in"
-# include "kwsys_stl_string.hxx.in"
-# include "kwsys_stl_vector.hxx.in"
+# include "Encoding.hxx.in"
#endif
+#include <string>
+#include <vector>
+
namespace KWSYS_NAMESPACE
{
@@ -35,10 +35,10 @@ class DirectoryInternals
{
public:
// Array of Files
- kwsys_stl::vector<kwsys_stl::string> Files;
+ std::vector<std::string> Files;
// Path to Open'ed directory
- kwsys_stl::string Path;
+ std::string Path;
};
//----------------------------------------------------------------------------
@@ -100,7 +100,7 @@ void Directory::Clear()
namespace KWSYS_NAMESPACE
{
-bool Directory::Load(const char* name)
+bool Directory::Load(const std::string& name)
{
this->Clear();
#if _MSC_VER < 1300
@@ -109,21 +109,30 @@ bool Directory::Load(const char* name)
intptr_t srchHandle;
#endif
char* buf;
- size_t n = strlen(name);
- if ( name[n - 1] == '/' )
+ size_t n = name.size();
+ if ( *name.rbegin() == '/' || *name.rbegin() == '\\' )
{
buf = new char[n + 1 + 1];
- sprintf(buf, "%s*", name);
+ sprintf(buf, "%s*", name.c_str());
}
else
{
+ // Make sure the slashes in the wildcard suffix are consistent with the
+ // rest of the path
buf = new char[n + 2 + 1];
- sprintf(buf, "%s/*", name);
+ if ( name.find('\\') != name.npos )
+ {
+ sprintf(buf, "%s\\*", name.c_str());
+ }
+ else
+ {
+ sprintf(buf, "%s/*", name.c_str());
+ }
}
- struct _finddata_t data; // data of current file
+ struct _wfinddata_t data; // data of current file
// Now put them into the file array
- srchHandle = _findfirst(buf, &data);
+ srchHandle = _wfindfirst((wchar_t*)Encoding::ToWide(buf).c_str(), &data);
delete [] buf;
if ( srchHandle == -1 )
@@ -134,14 +143,14 @@ bool Directory::Load(const char* name)
// Loop through names
do
{
- this->Internal->Files.push_back(data.name);
+ this->Internal->Files.push_back(Encoding::ToNarrow(data.name));
}
- while ( _findnext(srchHandle, &data) != -1 );
+ while ( _wfindnext(srchHandle, &data) != -1 );
this->Internal->Path = name;
return _findclose(srchHandle) != -1;
}
-unsigned long Directory::GetNumberOfFilesInDirectory(const char* name)
+unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
{
#if _MSC_VER < 1300
long srchHandle;
@@ -149,21 +158,21 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const char* name)
intptr_t srchHandle;
#endif
char* buf;
- size_t n = strlen(name);
- if ( name[n - 1] == '/' )
+ size_t n = name.size();
+ if ( *name.rbegin() == '/' )
{
buf = new char[n + 1 + 1];
- sprintf(buf, "%s*", name);
+ sprintf(buf, "%s*", name.c_str());
}
else
{
buf = new char[n + 2 + 1];
- sprintf(buf, "%s/*", name);
+ sprintf(buf, "%s/*", name.c_str());
}
- struct _finddata_t data; // data of current file
+ struct _wfinddata_t data; // data of current file
// Now put them into the file array
- srchHandle = _findfirst(buf, &data);
+ srchHandle = _wfindfirst((wchar_t*)Encoding::ToWide(buf).c_str(), &data);
delete [] buf;
if ( srchHandle == -1 )
@@ -177,7 +186,7 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const char* name)
{
count++;
}
- while ( _findnext(srchHandle, &data) != -1 );
+ while ( _wfindnext(srchHandle, &data) != -1 );
_findclose(srchHandle);
return count;
}
@@ -191,34 +200,35 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const char* name)
#include <sys/types.h>
#include <dirent.h>
-/* There is a problem with the Portland compiler, large file
-support and glibc/Linux system headers:
-http://www.pgroup.com/userforum/viewtopic.php?
-p=1992&sid=f16167f51964f1a68fe5041b8eb213b6
-*/
-#if defined(__PGI) && defined(__USE_FILE_OFFSET64)
-# define dirent dirent64
+// PGI with glibc has trouble with dirent and large file support:
+// http://www.pgroup.com/userforum/viewtopic.php?
+// p=1992&sid=f16167f51964f1a68fe5041b8eb213b6
+// Work around the problem by mapping dirent the same way as readdir.
+#if defined(__PGI) && defined(__GLIBC__)
+# define kwsys_dirent_readdir dirent
+# define kwsys_dirent_readdir64 dirent64
+# define kwsys_dirent kwsys_dirent_lookup(readdir)
+# define kwsys_dirent_lookup(x) kwsys_dirent_lookup_delay(x)
+# define kwsys_dirent_lookup_delay(x) kwsys_dirent_##x
+#else
+# define kwsys_dirent dirent
#endif
namespace KWSYS_NAMESPACE
{
-bool Directory::Load(const char* name)
+bool Directory::Load(const std::string& name)
{
this->Clear();
- if (!name)
- {
- return 0;
- }
- DIR* dir = opendir(name);
+ DIR* dir = opendir(name.c_str());
if (!dir)
{
return 0;
}
- for (dirent* d = readdir(dir); d; d = readdir(dir) )
+ for (kwsys_dirent* d = readdir(dir); d; d = readdir(dir) )
{
this->Internal->Files.push_back(d->d_name);
}
@@ -227,9 +237,9 @@ bool Directory::Load(const char* name)
return 1;
}
-unsigned long Directory::GetNumberOfFilesInDirectory(const char* name)
+unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
{
- DIR* dir = opendir(name);
+ DIR* dir = opendir(name.c_str());
if (!dir)
{
@@ -237,7 +247,7 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const char* name)
}
unsigned long count = 0;
- for (dirent* d = readdir(dir); d; d = readdir(dir) )
+ for (kwsys_dirent* d = readdir(dir); d; d = readdir(dir) )
{
count++;
}
diff --git a/Source/kwsys/Directory.hxx.in b/Source/kwsys/Directory.hxx.in
index 05217c46d..e68f33773 100644
--- a/Source/kwsys/Directory.hxx.in
+++ b/Source/kwsys/Directory.hxx.in
@@ -13,6 +13,7 @@
#define @KWSYS_NAMESPACE@_Directory_hxx
#include <@KWSYS_NAMESPACE@/Configure.h>
+#include <string>
namespace @KWSYS_NAMESPACE@
{
@@ -38,7 +39,7 @@ public:
* in that directory. 0 is returned if the directory can not be
* opened, 1 if it is opened.
*/
- bool Load(const char*);
+ bool Load(const std::string&);
/**
* Return the number of files in the current directory.
@@ -49,7 +50,7 @@ public:
* Return the number of files in the specified directory.
* A higher performance static method.
*/
- static unsigned long GetNumberOfFilesInDirectory(const char*);
+ static unsigned long GetNumberOfFilesInDirectory(const std::string&);
/**
* Return the file at the given index, the indexing is 0 based
diff --git a/Source/kwsys/DynamicLoader.cxx b/Source/kwsys/DynamicLoader.cxx
index fd83752c0..1941d965a 100644
--- a/Source/kwsys/DynamicLoader.cxx
+++ b/Source/kwsys/DynamicLoader.cxx
@@ -40,20 +40,24 @@ namespace KWSYS_NAMESPACE
{
//----------------------------------------------------------------------------
-DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
+DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const std::string& libname )
{
- return shl_load(libname, BIND_DEFERRED | DYNAMIC_PATH, 0L);
+ return shl_load(libname.c_str(), BIND_DEFERRED | DYNAMIC_PATH, 0L);
}
//----------------------------------------------------------------------------
int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
{
+ if (!lib)
+ {
+ return 0;
+ }
return !shl_unload(lib);
}
//----------------------------------------------------------------------------
DynamicLoader::SymbolPointer
-DynamicLoader::GetSymbolAddress(DynamicLoader::LibraryHandle lib, const char* sym)
+DynamicLoader::GetSymbolAddress(DynamicLoader::LibraryHandle lib, const std::string& sym)
{
void* addr;
int status;
@@ -62,7 +66,7 @@ DynamicLoader::GetSymbolAddress(DynamicLoader::LibraryHandle lib, const char* sy
* TYPE_DATA Look for a symbol in the data segment (for example, variables).
* TYPE_UNDEFINED Look for any symbol.
*/
- status = shl_findsym (&lib, sym, TYPE_UNDEFINED, &addr);
+ status = shl_findsym (&lib, sym.c_str(), TYPE_UNDEFINED, &addr);
void* result = (status < 0) ? (void*)0 : addr;
// Hack to cast pointer-to-data to pointer-to-function.
@@ -111,18 +115,18 @@ namespace KWSYS_NAMESPACE
{
//----------------------------------------------------------------------------
-DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
+DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const std::string& libname )
{
NSObjectFileImageReturnCode rc;
NSObjectFileImage image = 0;
- rc = NSCreateObjectFileImageFromFile(libname, &image);
+ rc = NSCreateObjectFileImageFromFile(libname.c_str(), &image);
// rc == NSObjectFileImageInappropriateFile when trying to load a dylib file
if( rc != NSObjectFileImageSuccess )
{
return 0;
}
- NSModule handle = NSLinkModule(image, libname,
+ NSModule handle = NSLinkModule(image, libname.c_str(),
NSLINKMODULE_OPTION_BINDNOW|NSLINKMODULE_OPTION_RETURN_ON_ERROR);
NSDestroyObjectFileImage(image);
return handle;
@@ -142,14 +146,14 @@ int DynamicLoader::CloseLibrary( DynamicLoader::LibraryHandle lib)
//----------------------------------------------------------------------------
DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
- DynamicLoader::LibraryHandle lib, const char* sym)
+ DynamicLoader::LibraryHandle lib, const std::string& sym)
{
void *result=0;
// Need to prepend symbols with '_' on Apple-gcc compilers
- size_t len = strlen(sym);
+ size_t len = sym.size();
char *rsym = new char[len + 1 + 1];
strcpy(rsym, "_");
- strcat(rsym+1, sym);
+ strcat(rsym+1, sym.c_str());
NSSymbol symbol = NSLookupSymbolInModule(lib, rsym);
if(symbol)
@@ -183,16 +187,15 @@ namespace KWSYS_NAMESPACE
{
//----------------------------------------------------------------------------
-DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname)
+DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const std::string& libname)
{
DynamicLoader::LibraryHandle lh;
-#ifdef UNICODE
- wchar_t libn[MB_CUR_MAX];
- mbstowcs(libn, libname, MB_CUR_MAX);
- lh = LoadLibrary(libn);
-#else
- lh = LoadLibrary(libname);
-#endif
+ int length = MultiByteToWideChar(CP_UTF8, 0, libname.c_str(), -1, NULL, 0);
+ wchar_t* wchars = new wchar_t[length+1];
+ wchars[0] = '\0';
+ MultiByteToWideChar(CP_UTF8, 0, libname.c_str(), -1, wchars, length);
+ lh = LoadLibraryW(wchars);
+ delete [] wchars;
return lh;
}
@@ -204,7 +207,7 @@ int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
//----------------------------------------------------------------------------
DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
- DynamicLoader::LibraryHandle lib, const char* sym)
+ DynamicLoader::LibraryHandle lib, const std::string& sym)
{
// TODO: The calling convention affects the name of the symbol. We
// should have a tool to help get the symbol with the desired
@@ -231,20 +234,14 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
void *result;
#if defined(__BORLANDC__) || defined(__WATCOMC__)
// Need to prepend symbols with '_'
- size_t len = strlen(sym);
+ size_t len = sym.size();
char *rsym = new char[len + 1 + 1];
strcpy(rsym, "_");
- strcat(rsym, sym);
+ strcat(rsym, sym.c_str());
#else
- const char *rsym = sym;
+ const char *rsym = sym.c_str();
#endif
-#ifdef UNICODE
- wchar_t wsym[MB_CUR_MAX];
- mbstowcs(wsym, rsym, MB_CUR_MAX);
- result = GetProcAddress(lib, wsym);
-#else
result = (void*)GetProcAddress(lib, rsym);
-#endif
#if defined(__BORLANDC__) || defined(__WATCOMC__)
delete[] rsym;
#endif
@@ -305,11 +302,11 @@ namespace KWSYS_NAMESPACE
static image_id last_dynamic_err = B_OK;
//----------------------------------------------------------------------------
-DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
+DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const std::string& libname )
{
// image_id's are integers, errors are negative. Add one just in case we
// get a valid image_id of zero (is that even possible?).
- image_id rc = load_add_on(libname);
+ image_id rc = load_add_on(libname.c_str());
if (rc < 0)
{
last_dynamic_err = rc;
@@ -343,7 +340,7 @@ int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
//----------------------------------------------------------------------------
DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
- DynamicLoader::LibraryHandle lib, const char* sym)
+ DynamicLoader::LibraryHandle lib, const std::string& sym)
{
// Hack to cast pointer-to-data to pointer-to-function.
union
@@ -363,7 +360,7 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
// !!! FIXME: BeOS can do function-only lookups...does this ever
// !!! FIXME: actually _want_ a data symbol lookup, or was this union
// !!! FIXME: a leftover of dlsym()? (s/ANY/TEXT for functions only).
- status_t rc = get_image_symbol(lib-1,sym,B_SYMBOL_TYPE_ANY,&result.pvoid);
+ status_t rc = get_image_symbol(lib-1,sym.c_str(),B_SYMBOL_TYPE_ANY,&result.pvoid);
if (rc != B_OK)
{
last_dynamic_err = rc;
@@ -396,7 +393,7 @@ namespace KWSYS_NAMESPACE
{
//----------------------------------------------------------------------------
-DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
+DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const std::string& libname )
{
return 0;
}
@@ -414,7 +411,7 @@ int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
//----------------------------------------------------------------------------
DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
- DynamicLoader::LibraryHandle lib, const char* sym)
+ DynamicLoader::LibraryHandle lib, const std::string& sym)
{
return 0;
}
@@ -440,12 +437,12 @@ namespace KWSYS_NAMESPACE
{
//----------------------------------------------------------------------------
-DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
+DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const std::string& libname )
{
- char *name = (char *)calloc(1, strlen(libname) + 1);
+ char *name = (char *)calloc(1, libname.size() + 1);
dld_init(program_invocation_name);
- strncpy(name, libname, strlen(libname));
- dld_link(libname);
+ strncpy(name, libname.c_str(), libname.size());
+ dld_link(libname.c_str());
return (void *)name;
}
@@ -459,7 +456,7 @@ int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
//----------------------------------------------------------------------------
DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
- DynamicLoader::LibraryHandle lib, const char* sym)
+ DynamicLoader::LibraryHandle lib, const std::string& sym)
{
// Hack to cast pointer-to-data to pointer-to-function.
union
@@ -467,7 +464,7 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
void* pvoid;
DynamicLoader::SymbolPointer psym;
} result;
- result.pvoid = dld_get_symbol(sym);
+ result.pvoid = dld_get_symbol(sym.c_str());
return result.psym;
}
@@ -492,9 +489,9 @@ namespace KWSYS_NAMESPACE
{
//----------------------------------------------------------------------------
-DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
+DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const std::string& libname )
{
- return dlopen(libname, RTLD_LAZY);
+ return dlopen(libname.c_str(), RTLD_LAZY);
}
//----------------------------------------------------------------------------
@@ -511,7 +508,7 @@ int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
//----------------------------------------------------------------------------
DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
- DynamicLoader::LibraryHandle lib, const char* sym)
+ DynamicLoader::LibraryHandle lib, const std::string& sym)
{
// Hack to cast pointer-to-data to pointer-to-function.
union
@@ -519,7 +516,7 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
void* pvoid;
DynamicLoader::SymbolPointer psym;
} result;
- result.pvoid = dlsym(lib, sym);
+ result.pvoid = dlsym(lib, sym.c_str());
return result.psym;
}
diff --git a/Source/kwsys/DynamicLoader.hxx.in b/Source/kwsys/DynamicLoader.hxx.in
index 64468ecd3..1e4a91265 100644
--- a/Source/kwsys/DynamicLoader.hxx.in
+++ b/Source/kwsys/DynamicLoader.hxx.in
@@ -12,7 +12,8 @@
#ifndef @KWSYS_NAMESPACE@_DynamicLoader_hxx
#define @KWSYS_NAMESPACE@_DynamicLoader_hxx
-#include <@KWSYS_NAMESPACE@/Configure.h>
+#include <@KWSYS_NAMESPACE@/Configure.hxx>
+#include <string>
#if defined(__hpux)
#include <dl.h>
@@ -77,14 +78,14 @@ public:
/** Load a dynamic library into the current process.
* The returned LibraryHandle can be used to access the symbols in the
* library. */
- static LibraryHandle OpenLibrary(const char*);
+ static LibraryHandle OpenLibrary(const std::string&);
/** Attempt to detach a dynamic library from the
* process. A value of true is returned if it is sucessful. */
static int CloseLibrary(LibraryHandle);
/** Find the address of the symbol in the given library. */
- static SymbolPointer GetSymbolAddress(LibraryHandle, const char*);
+ static SymbolPointer GetSymbolAddress(LibraryHandle, const std::string&);
/** Return the default module prefix for the current platform. */
static const char* LibPrefix() { return "@KWSYS_DynamicLoader_PREFIX@"; }
diff --git a/Source/kwsys/Encoding.h.in b/Source/kwsys/Encoding.h.in
new file mode 100644
index 000000000..591c5a898
--- /dev/null
+++ b/Source/kwsys/Encoding.h.in
@@ -0,0 +1,79 @@
+/*============================================================================
+ KWSys - Kitware System Library
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef @KWSYS_NAMESPACE@_Encoding_h
+#define @KWSYS_NAMESPACE@_Encoding_h
+
+#include <@KWSYS_NAMESPACE@/Configure.h>
+#include <wchar.h>
+
+/* Redefine all public interface symbol names to be in the proper
+ namespace. These macros are used internally to kwsys only, and are
+ not visible to user code. Use kwsysHeaderDump.pl to reproduce
+ these macros after making changes to the interface. */
+#if !defined(KWSYS_NAMESPACE)
+# define kwsys_ns(x) @KWSYS_NAMESPACE@##x
+# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
+#endif
+#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
+# define kwsysEncoding kwsys_ns(Encoding)
+# define kwsysEncoding_mbstowcs kwsys_ns(Encoding_mbstowcs)
+# define kwsysEncoding_DupToWide kwsys_ns(Encoding_DupToWide)
+# define kwsysEncoding_wcstombs kwsys_ns(Encoding_wcstombs)
+# define kwsysEncoding_DupToNarrow kwsys_ns(Encoding_DupToNarrow)
+#endif
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+
+/* Convert a narrow string to a wide string.
+ On Windows, UTF-8 is assumed, and on other platforms,
+ the current locale is assumed.
+ */
+kwsysEXPORT size_t kwsysEncoding_mbstowcs(wchar_t* dest, const char* src, size_t n);
+
+/* Convert a narrow string to a wide string.
+ This can return NULL if the conversion fails. */
+kwsysEXPORT wchar_t* kwsysEncoding_DupToWide(const char* src);
+
+
+/* Convert a wide string to a narrow string.
+ On Windows, UTF-8 is assumed, and on other platforms,
+ the current locale is assumed. */
+kwsysEXPORT size_t kwsysEncoding_wcstombs(char* dest, const wchar_t* src, size_t n);
+
+/* Convert a wide string to a narrow string.
+ This can return NULL if the conversion fails. */
+kwsysEXPORT char* kwsysEncoding_DupToNarrow(const wchar_t* str);
+
+
+#if defined(__cplusplus)
+} /* extern "C" */
+#endif
+
+/* If we are building a kwsys .c or .cxx file, let it use these macros.
+ Otherwise, undefine them to keep the namespace clean. */
+#if !defined(KWSYS_NAMESPACE)
+# undef kwsys_ns
+# undef kwsysEXPORT
+# if !defined(KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
+# undef kwsysEncoding
+# undef kwsysEncoding_mbstowcs
+# undef kwsysEncoding_DupToWide
+# undef kwsysEncoding_wcstombs
+# undef kwsysEncoding_DupToNarrow
+# endif
+#endif
+
+#endif
diff --git a/Source/kwsys/Encoding.hxx.in b/Source/kwsys/Encoding.hxx.in
new file mode 100644
index 000000000..87b1c2150
--- /dev/null
+++ b/Source/kwsys/Encoding.hxx.in
@@ -0,0 +1,77 @@
+/*============================================================================
+ KWSys - Kitware System Library
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef @KWSYS_NAMESPACE@_Encoding_hxx
+#define @KWSYS_NAMESPACE@_Encoding_hxx
+
+#include <@KWSYS_NAMESPACE@/Configure.hxx>
+#include <string>
+#include <vector>
+
+namespace @KWSYS_NAMESPACE@
+{
+class @KWSYS_NAMESPACE@_EXPORT Encoding
+{
+public:
+
+ // Container class for argc/argv.
+ class CommandLineArguments
+ {
+ public:
+ // On Windows, get the program command line arguments
+ // in this Encoding module's 8 bit encoding.
+ // On other platforms the given argc/argv is used, and
+ // to be consistent, should be the argc/argv from main().
+ static CommandLineArguments Main(int argc, char const* const* argv);
+
+ // Construct CommandLineArguments with the given
+ // argc/argv. It is assumed that the string is already
+ // in the encoding used by this module.
+ CommandLineArguments(int argc, char const* const* argv);
+
+ // Construct CommandLineArguments with the given
+ // argc and wide argv. This is useful if wmain() is used.
+ CommandLineArguments(int argc, wchar_t const* const* argv);
+ ~CommandLineArguments();
+ CommandLineArguments(const CommandLineArguments&);
+ CommandLineArguments& operator=(const CommandLineArguments&);
+
+ int argc() const;
+ char const* const* argv() const;
+
+ protected:
+ std::vector<char*> argv_;
+ };
+
+ /**
+ * Convert between char and wchar_t
+ */
+
+#if @KWSYS_NAMESPACE@_STL_HAS_WSTRING
+
+ // Convert a narrow string to a wide string.
+ // On Windows, UTF-8 is assumed, and on other platforms,
+ // the current locale is assumed.
+ static std::wstring ToWide(const std::string& str);
+ static std::wstring ToWide(const char* str);
+
+ // Convert a wide string to a narrow string.
+ // On Windows, UTF-8 is assumed, and on other platforms,
+ // the current locale is assumed.
+ static std::string ToNarrow(const std::wstring& str);
+ static std::string ToNarrow(const wchar_t* str);
+
+#endif // @KWSYS_NAMESPACE@_STL_HAS_WSTRING
+
+}; // class Encoding
+} // namespace @KWSYS_NAMESPACE@
+
+#endif
diff --git a/Source/kwsys/EncodingC.c b/Source/kwsys/EncodingC.c
new file mode 100644
index 000000000..32b9bffa7
--- /dev/null
+++ b/Source/kwsys/EncodingC.c
@@ -0,0 +1,85 @@
+/*============================================================================
+ KWSys - Kitware System Library
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "kwsysPrivate.h"
+#include KWSYS_HEADER(Encoding.h)
+
+/* Work-around CMake dependency scanning limitation. This must
+ duplicate the above list of headers. */
+#if 0
+# include "Encoding.h.in"
+#endif
+
+#include <stdlib.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+size_t kwsysEncoding_mbstowcs(wchar_t* dest, const char* str, size_t n)
+{
+ if(str == 0)
+ {
+ return (size_t)-1;
+ }
+#ifdef _WIN32
+ return MultiByteToWideChar(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0,
+ str, -1, dest, (int)n) - 1;
+#else
+ return mbstowcs(dest, str, n);
+#endif
+}
+
+wchar_t* kwsysEncoding_DupToWide(const char* str)
+{
+ wchar_t* ret = NULL;
+ size_t length = kwsysEncoding_mbstowcs(NULL, str, 0) + 1;
+ if(length > 0)
+ {
+ ret = (wchar_t*)malloc((length)*sizeof(wchar_t));
+ if(ret)
+ {
+ ret[0] = 0;
+ kwsysEncoding_mbstowcs(ret, str, length);
+ }
+ }
+ return ret;
+}
+
+size_t kwsysEncoding_wcstombs(char* dest, const wchar_t* str, size_t n)
+{
+ if(str == 0)
+ {
+ return (size_t)-1;
+ }
+#ifdef _WIN32
+ return WideCharToMultiByte(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str, -1,
+ dest, (int)n, NULL, NULL) - 1;
+#else
+ return wcstombs(dest, str, n);
+#endif
+}
+
+char* kwsysEncoding_DupToNarrow(const wchar_t* str)
+{
+ char* ret = NULL;
+ size_t length = kwsysEncoding_wcstombs(0, str, 0) + 1;
+ if(length > 0)
+ {
+ ret = (char*)malloc(length);
+ if(ret)
+ {
+ ret[0] = 0;
+ kwsysEncoding_wcstombs(ret, str, length);
+ }
+ }
+ return ret;
+}
diff --git a/Source/kwsys/EncodingCXX.cxx b/Source/kwsys/EncodingCXX.cxx
new file mode 100644
index 000000000..597d4bd19
--- /dev/null
+++ b/Source/kwsys/EncodingCXX.cxx
@@ -0,0 +1,185 @@
+/*============================================================================
+ KWSys - Kitware System Library
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifdef __osf__
+# define _OSF_SOURCE
+# define _POSIX_C_SOURCE 199506L
+# define _XOPEN_SOURCE_EXTENDED
+#endif
+
+#include "kwsysPrivate.h"
+#include KWSYS_HEADER(Encoding.hxx)
+#include KWSYS_HEADER(Encoding.h)
+
+// Work-around CMake dependency scanning limitation. This must
+// duplicate the above list of headers.
+#if 0
+# include "Encoding.hxx.in"
+# include "Encoding.h.in"
+#endif
+
+#include <vector>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef _MSC_VER
+# pragma warning (disable: 4786)
+#endif
+
+// Windows API.
+#if defined(_WIN32)
+# include <windows.h>
+# include <shellapi.h>
+#endif
+
+namespace KWSYS_NAMESPACE
+{
+
+Encoding::CommandLineArguments
+Encoding::CommandLineArguments::Main(int argc, char const* const* argv)
+{
+#ifdef _WIN32
+ (void) argc;
+ (void) argv;
+
+ int ac;
+ LPWSTR* w_av = CommandLineToArgvW(GetCommandLineW(), &ac);
+
+ std::vector<std::string> av1(ac);
+ std::vector<char const*> av2(ac);
+ for(int i=0; i<ac; i++)
+ {
+ av1[i] = ToNarrow(w_av[i]);
+ av2[i] = av1[i].c_str();
+ }
+ LocalFree(w_av);
+ return CommandLineArguments(ac, &av2[0]);
+#else
+ return CommandLineArguments(argc, argv);
+#endif
+}
+
+Encoding::CommandLineArguments::CommandLineArguments(int ac,
+ char const* const* av)
+{
+ this->argv_.resize(ac+1);
+ for(int i=0; i<ac; i++)
+ {
+ this->argv_[i] = strdup(av[i]);
+ }
+ this->argv_[ac] = 0;
+}
+
+Encoding::CommandLineArguments::CommandLineArguments(int ac,
+ wchar_t const* const* av)
+{
+ this->argv_.resize(ac+1);
+ for(int i=0; i<ac; i++)
+ {
+ this->argv_[i] = kwsysEncoding_DupToNarrow(av[i]);
+ }
+ this->argv_[ac] = 0;
+}
+
+Encoding::CommandLineArguments::~CommandLineArguments()
+{
+ for(size_t i=0; i<this->argv_.size(); i++)
+ {
+ free(argv_[i]);
+ }
+}
+
+Encoding::CommandLineArguments::
+ CommandLineArguments(const CommandLineArguments& other)
+{
+ this->argv_.resize(other.argv_.size());
+ for(size_t i=0; i<this->argv_.size(); i++)
+ {
+ this->argv_[i] = other.argv_[i] ? strdup(other.argv_[i]) : 0;
+ }
+}
+
+Encoding::CommandLineArguments&
+Encoding::CommandLineArguments::operator=(const CommandLineArguments& other)
+{
+ if(this != &other)
+ {
+ size_t i;
+ for(i=0; i<this->argv_.size(); i++)
+ {
+ free(this->argv_[i]);
+ }
+
+ this->argv_.resize(other.argv_.size());
+ for(i=0; i<this->argv_.size(); i++)
+ {
+ this->argv_[i] = other.argv_[i] ? strdup(other.argv_[i]) : 0;
+ }
+ }
+
+ return *this;
+}
+
+int Encoding::CommandLineArguments::argc() const
+{
+ return static_cast<int>(this->argv_.size() - 1);
+}
+
+char const* const* Encoding::CommandLineArguments::argv() const
+{
+ return &this->argv_[0];
+}
+
+#if KWSYS_STL_HAS_WSTRING
+
+std::wstring Encoding::ToWide(const std::string& str)
+{
+ return ToWide(str.c_str());
+}
+
+std::string Encoding::ToNarrow(const std::wstring& str)
+{
+ return ToNarrow(str.c_str());
+}
+
+std::wstring Encoding::ToWide(const char* cstr)
+{
+ std::wstring wstr;
+ size_t length = kwsysEncoding_mbstowcs(0, cstr, 0) + 1;
+ if(length > 0)
+ {
+ std::vector<wchar_t> wchars(length);
+ if(kwsysEncoding_mbstowcs(&wchars[0], cstr, length) > 0)
+ {
+ wstr = &wchars[0];
+ }
+ }
+ return wstr;
+}
+
+std::string Encoding::ToNarrow(const wchar_t* wcstr)
+{
+ std::string str;
+ size_t length = kwsysEncoding_wcstombs(0, wcstr, 0) + 1;
+ if(length > 0)
+ {
+ std::vector<char> chars(length);
+ if(kwsysEncoding_wcstombs(&chars[0], wcstr, length) > 0)
+ {
+ str = &chars[0];
+ }
+ }
+ return str;
+}
+#endif // KWSYS_STL_HAS_WSTRING
+
+} // namespace KWSYS_NAMESPACE
diff --git a/Source/kwsys/FStream.cxx b/Source/kwsys/FStream.cxx
new file mode 100644
index 000000000..5a30997d6
--- /dev/null
+++ b/Source/kwsys/FStream.cxx
@@ -0,0 +1,78 @@
+/*============================================================================
+ KWSys - Kitware System Library
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "kwsysPrivate.h"
+#include KWSYS_HEADER(FStream.hxx)
+
+// Work-around CMake dependency scanning limitation. This must
+// duplicate the above list of headers.
+#if 0
+# include "FStream.hxx.in"
+#endif
+
+namespace KWSYS_NAMESPACE
+{
+namespace FStream
+{
+
+BOM ReadBOM(std::istream& in)
+{
+ if(!in.good())
+ {
+ return BOM_None;
+ }
+ unsigned long orig = in.tellg();
+ unsigned char bom[4];
+ in.read(reinterpret_cast<char*>(bom), 2);
+ if(!in.good())
+ {
+ in.clear();
+ in.seekg(orig);
+ return BOM_None;
+ }
+ if(bom[0] == 0xEF && bom[1] == 0xBB)
+ {
+ in.read(reinterpret_cast<char*>(bom+2), 1);
+ if(in.good() && bom[2] == 0xBF)
+ {
+ return BOM_UTF8;
+ }
+ }
+ else if(bom[0] == 0xFE && bom[1] == 0xFF)
+ {
+ return BOM_UTF16BE;
+ }
+ else if(bom[0] == 0x00 && bom[1] == 0x00)
+ {
+ in.read(reinterpret_cast<char*>(bom+2), 2);
+ if(in.good() && bom[2] == 0xFE && bom[3] == 0xFF)
+ {
+ return BOM_UTF32BE;
+ }
+ }
+ else if(bom[0] == 0xFF && bom[1] == 0xFE)
+ {
+ unsigned long p = in.tellg();
+ in.read(reinterpret_cast<char*>(bom+2), 2);
+ if(in.good() && bom[2] == 0x00 && bom[3] == 0x00)
+ {
+ return BOM_UTF32LE;
+ }
+ in.seekg(p);
+ return BOM_UTF16LE;
+ }
+ in.clear();
+ in.seekg(orig);
+ return BOM_None;
+}
+
+} // FStream namespace
+} //KWSYS_NAMESPACE
diff --git a/Source/kwsys/FStream.hxx.in b/Source/kwsys/FStream.hxx.in
new file mode 100644
index 000000000..681e4d870
--- /dev/null
+++ b/Source/kwsys/FStream.hxx.in
@@ -0,0 +1,194 @@
+/*============================================================================
+ KWSys - Kitware System Library
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef @KWSYS_NAMESPACE@_FStream_hxx
+#define @KWSYS_NAMESPACE@_FStream_hxx
+
+#include <@KWSYS_NAMESPACE@/Encoding.hxx>
+#include <fstream>
+
+namespace @KWSYS_NAMESPACE@
+{
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+# if defined(_NOEXCEPT)
+# define @KWSYS_NAMESPACE@_FStream_NOEXCEPT _NOEXCEPT
+# else
+# define @KWSYS_NAMESPACE@_FStream_NOEXCEPT
+# endif
+ template<typename CharType,typename Traits>
+ class basic_filebuf : public std::basic_filebuf<CharType,Traits>
+ {
+ public:
+ typedef std::basic_filebuf<CharType,Traits> my_base_type;
+ basic_filebuf *open(char const *s,std::ios_base::openmode mode)
+ {
+ return static_cast<basic_filebuf*>(
+ my_base_type::open(Encoding::ToWide(s).c_str(), mode)
+ );
+ }
+ };
+
+ template<typename CharType,typename Traits = std::char_traits<CharType> >
+ class basic_ifstream : public std::basic_istream<CharType,Traits>
+ {
+ public:
+ typedef basic_filebuf<CharType,Traits> internal_buffer_type;
+ typedef std::basic_istream<CharType,Traits> internal_stream_type;
+
+ basic_ifstream() : internal_stream_type(new internal_buffer_type())
+ {
+ buf_ = static_cast<internal_buffer_type *>(internal_stream_type::rdbuf());
+ }
+ explicit basic_ifstream(char const *file_name,
+ std::ios_base::openmode mode = std::ios_base::in)
+ : internal_stream_type(new internal_buffer_type())
+ {
+ buf_ = static_cast<internal_buffer_type *>(internal_stream_type::rdbuf());
+ open(file_name,mode);
+ }
+ void open(char const *file_name,std::ios_base::openmode mode = std::ios_base::in)
+ {
+ if(!buf_->open(file_name,mode | std::ios_base::in))
+ {
+ this->setstate(std::ios_base::failbit);
+ }
+ else
+ {
+ this->clear();
+ }
+ }
+ bool is_open()
+ {
+ return buf_->is_open();
+ }
+ bool is_open() const
+ {
+ return buf_->is_open();
+ }
+ void close()
+ {
+ if(!buf_->close())
+ {
+ this->setstate(std::ios_base::failbit);
+ }
+ else
+ {
+ this->clear();
+ }
+ }
+
+ internal_buffer_type *rdbuf() const
+ {
+ return buf_;
+ }
+
+ ~basic_ifstream() @KWSYS_NAMESPACE@_FStream_NOEXCEPT
+ {
+ buf_->close();
+ delete buf_;
+ }
+
+ private:
+ internal_buffer_type* buf_;
+};
+
+template<typename CharType,typename Traits = std::char_traits<CharType> >
+class basic_ofstream : public std::basic_ostream<CharType,Traits>
+{
+ public:
+ typedef basic_filebuf<CharType,Traits> internal_buffer_type;
+ typedef std::basic_ostream<CharType,Traits> internal_stream_type;
+
+ basic_ofstream() : internal_stream_type(new internal_buffer_type())
+ {
+ buf_ = static_cast<internal_buffer_type *>(internal_stream_type::rdbuf());
+ }
+ explicit basic_ofstream(char const *file_name,std::ios_base::openmode mode = std::ios_base::out) :
+ internal_stream_type(new internal_buffer_type())
+ {
+ buf_ = static_cast<internal_buffer_type *>(internal_stream_type::rdbuf());
+ open(file_name,mode);
+ }
+ void open(char const *file_name,std::ios_base::openmode mode = std::ios_base::out)
+ {
+ if(!buf_->open(file_name,mode | std::ios_base::out))
+ {
+ this->setstate(std::ios_base::failbit);
+ }
+ else
+ {
+ this->clear();
+ }
+ }
+ bool is_open()
+ {
+ return buf_->is_open();
+ }
+ bool is_open() const
+ {
+ return buf_->is_open();
+ }
+ void close()
+ {
+ if(!buf_->close())
+ {
+ this->setstate(std::ios_base::failbit);
+ }
+ else
+ {
+ this->clear();
+ }
+ }
+
+ internal_buffer_type *rdbuf() const
+ {
+ return buf_.get();
+ }
+ ~basic_ofstream() @KWSYS_NAMESPACE@_FStream_NOEXCEPT
+ {
+ buf_->close();
+ delete buf_;
+ }
+
+ private:
+ internal_buffer_type* buf_;
+};
+
+ typedef basic_ifstream<char> ifstream;
+ typedef basic_ofstream<char> ofstream;
+
+# undef @KWSYS_NAMESPACE@_FStream_NOEXCEPT
+#else
+ using std::ofstream;
+ using std::ifstream;
+#endif
+
+ namespace FStream
+ {
+ enum BOM
+ {
+ BOM_None,
+ BOM_UTF8,
+ BOM_UTF16BE,
+ BOM_UTF16LE,
+ BOM_UTF32BE,
+ BOM_UTF32LE
+ };
+
+ // Read a BOM, if one exists.
+ // If a BOM exists, the stream is advanced to after the BOM.
+ // This function requires a seekable stream (but not a relative
+ // seekable stream).
+ BOM ReadBOM(std::istream& in);
+ }
+}
+
+#endif
diff --git a/Source/kwsys/FundamentalType.h.in b/Source/kwsys/FundamentalType.h.in
deleted file mode 100644
index ff200633a..000000000
--- a/Source/kwsys/FundamentalType.h.in
+++ /dev/null
@@ -1,146 +0,0 @@
-/*============================================================================
- KWSys - Kitware System Library
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef @KWSYS_NAMESPACE@_FundamentalType_h
-#define @KWSYS_NAMESPACE@_FundamentalType_h
-
-#include <@KWSYS_NAMESPACE@/Configure.h>
-
-/* Redefine all public interface symbol names to be in the proper
- namespace. These macros are used internally to kwsys only, and are
- not visible to user code. Use kwsysHeaderDump.pl to reproduce
- these macros after making changes to the interface. */
-#if !defined(KWSYS_NAMESPACE)
-# define kwsys_ns(x) @KWSYS_NAMESPACE@##x
-# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
-#endif
-
-#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
-# define kwsysFundamentalType kwsys_ns(FundamentalType)
-# define kwsysFundamentalType_Int8 kwsys_ns(FundamentalType_Int8)
-# define kwsysFundamentalType_UInt8 kwsys_ns(FundamentalType_UInt8)
-# define kwsysFundamentalType_Int16 kwsys_ns(FundamentalType_Int16)
-# define kwsysFundamentalType_UInt16 kwsys_ns(FundamentalType_UInt16)
-# define kwsysFundamentalType_Int32 kwsys_ns(FundamentalType_Int32)
-# define kwsysFundamentalType_UInt32 kwsys_ns(FundamentalType_UInt32)
-# define kwsysFundamentalType_Int64 kwsys_ns(FundamentalType_Int64)
-# define kwsysFundamentalType_UInt64 kwsys_ns(FundamentalType_UInt64)
-#endif
-
-/* The size of fundamental types. Types that do not exist have size 0. */
-@KWSYS_C_CODE_SIZEOF_CHAR@
-@KWSYS_C_CODE_SIZEOF_SHORT@
-@KWSYS_C_CODE_SIZEOF_INT@
-@KWSYS_C_CODE_SIZEOF_LONG@
-@KWSYS_C_CODE_SIZEOF_LONG_LONG@
-@KWSYS_C_CODE_SIZEOF___INT64@
-
-/* Whether types "long long" and "__int64" are enabled. If a type is
- enabled then it is a unique fundamental type. */
-#define @KWSYS_NAMESPACE@_USE_LONG_LONG @KWSYS_USE_LONG_LONG@
-#define @KWSYS_NAMESPACE@_USE___INT64 @KWSYS_USE___INT64@
-
-/* Whether type "char" is signed (it may be signed or unsigned). */
-#define @KWSYS_NAMESPACE@_CHAR_IS_SIGNED @KWSYS_CHAR_IS_SIGNED@
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-/* Select an 8-bit integer type. */
-#if @KWSYS_NAMESPACE@_SIZEOF_CHAR == 1
-typedef signed char kwsysFundamentalType_Int8;
-typedef unsigned char kwsysFundamentalType_UInt8;
-#else
-# error "No native data type can represent an 8-bit integer."
-#endif
-
-/* Select a 16-bit integer type. */
-#if @KWSYS_NAMESPACE@_SIZEOF_SHORT == 2
-typedef short kwsysFundamentalType_Int16;
-typedef unsigned short kwsysFundamentalType_UInt16;
-#elif @KWSYS_NAMESPACE@_SIZEOF_INT == 2
-typedef int kwsysFundamentalType_Int16;
-typedef unsigned int kwsysFundamentalType_UInt16;
-#else
-# error "No native data type can represent a 16-bit integer."
-#endif
-
-/* Select a 32-bit integer type. */
-#if @KWSYS_NAMESPACE@_SIZEOF_INT == 4
-typedef int kwsysFundamentalType_Int32;
-typedef unsigned int kwsysFundamentalType_UInt32;
-#elif @KWSYS_NAMESPACE@_SIZEOF_LONG == 4
-typedef long kwsysFundamentalType_Int32;
-typedef unsigned long kwsysFundamentalType_UInt32;
-#else
-# error "No native data type can represent a 32-bit integer."
-#endif
-
-/* Select a 64-bit integer type. */
-#if @KWSYS_NAMESPACE@_SIZEOF_LONG == 8
-typedef signed long kwsysFundamentalType_Int64;
-typedef unsigned long kwsysFundamentalType_UInt64;
-/* Whether UInt64 can be converted to double. */
-# define @KWSYS_NAMESPACE@_CAN_CONVERT_UI64_TO_DOUBLE 1
-#elif @KWSYS_NAMESPACE@_USE_LONG_LONG && @KWSYS_NAMESPACE@_SIZEOF_LONG_LONG == 8
-typedef signed long long kwsysFundamentalType_Int64;
-typedef unsigned long long kwsysFundamentalType_UInt64;
-/* Whether UInt64 can be converted to double. */
-# define @KWSYS_NAMESPACE@_CAN_CONVERT_UI64_TO_DOUBLE 1
-#elif @KWSYS_NAMESPACE@_USE___INT64 && @KWSYS_NAMESPACE@_SIZEOF___INT64 == 8
-typedef signed __int64 kwsysFundamentalType_Int64;
-typedef unsigned __int64 kwsysFundamentalType_UInt64;
-/* Whether UInt64 can be converted to double. */
-# define @KWSYS_NAMESPACE@_CAN_CONVERT_UI64_TO_DOUBLE @KWSYS_CAN_CONVERT_UI64_TO_DOUBLE@
-#else
-# error "No native data type can represent a 64-bit integer."
-#endif
-
-#if defined(__cplusplus)
-} /* extern "C" */
-#endif
-
-/* If we are building a kwsys .c or .cxx file, let it use these macros.
- Otherwise, undefine them to keep the namespace clean. */
-#if !defined(KWSYS_NAMESPACE)
-# undef kwsys_ns
-# undef kwsysEXPORT
-# if !defined(KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
-# undef kwsysFundamentalType
-# undef kwsysFundamentalType_Int8
-# undef kwsysFundamentalType_UInt8
-# undef kwsysFundamentalType_Int16
-# undef kwsysFundamentalType_UInt16
-# undef kwsysFundamentalType_Int32
-# undef kwsysFundamentalType_UInt32
-# undef kwsysFundamentalType_Int64
-# undef kwsysFundamentalType_UInt64
-# endif
-#endif
-
-/* If building a C or C++ file in kwsys itself, give the source file
- access to the configured macros without a configured namespace. */
-#if defined(KWSYS_NAMESPACE)
-# define KWSYS_SIZEOF_CHAR @KWSYS_NAMESPACE@_SIZEOF_CHAR
-# define KWSYS_SIZEOF_SHORT @KWSYS_NAMESPACE@_SIZEOF_SHORT
-# define KWSYS_SIZEOF_INT @KWSYS_NAMESPACE@_SIZEOF_INT
-# define KWSYS_SIZEOF_LONG @KWSYS_NAMESPACE@_SIZEOF_LONG
-# define KWSYS_SIZEOF_LONG_LONG @KWSYS_NAMESPACE@_SIZEOF_LONG_LONG
-# define KWSYS_SIZEOF___INT64 @KWSYS_NAMESPACE@_SIZEOF___INT64
-# define KWSYS_USE_LONG_LONG @KWSYS_NAMESPACE@_USE_LONG_LONG
-# define KWSYS_USE___INT64 @KWSYS_NAMESPACE@_USE___INT64
-# define KWSYS_CHAR_IS_SIGNED @KWSYS_NAMESPACE@_CHAR_IS_SIGNED
-# define KWSYS_CAN_CONVERT_UI64_TO_DOUBLE @KWSYS_NAMESPACE@_CAN_CONVERT_UI64_TO_DOUBLE
-#endif
-
-#endif
diff --git a/Source/kwsys/Glob.cxx b/Source/kwsys/Glob.cxx
index 46a7e4f44..9d6345951 100644
--- a/Source/kwsys/Glob.cxx
+++ b/Source/kwsys/Glob.cxx
@@ -17,8 +17,6 @@
#include KWSYS_HEADER(RegularExpression.hxx)
#include KWSYS_HEADER(SystemTools.hxx)
#include KWSYS_HEADER(Directory.hxx)
-#include KWSYS_HEADER(stl/string)
-#include KWSYS_HEADER(stl/vector)
// Work-around CMake dependency scanning limitation. This must
// duplicate the above list of headers.
@@ -28,10 +26,12 @@
# include "Configure.hxx.in"
# include "RegularExpression.hxx.in"
# include "SystemTools.hxx.in"
-# include "kwsys_stl.hxx.in"
-# include "kwsys_stl_string.hxx.in"
#endif
+#include <string>
+#include <vector>
+#include <algorithm>
+
#include <ctype.h>
#include <stdio.h>
#include <string.h>
@@ -51,8 +51,8 @@ namespace KWSYS_NAMESPACE
class GlobInternals
{
public:
- kwsys_stl::vector<kwsys_stl::string> Files;
- kwsys_stl::vector<kwsys::RegularExpression> Expressions;
+ std::vector<std::string> Files;
+ std::vector<kwsys::RegularExpression> Expressions;
};
//----------------------------------------------------------------------------
@@ -66,6 +66,10 @@ Glob::Glob()
// RecurseThroughSymlinks is true by default for backwards compatibility,
// not because it's a good idea...
this->FollowedSymlinkCount = 0;
+
+ // Keep separate variables for directory listing for back compatibility
+ this->ListDirs = true;
+ this->RecurseListDirs = false;
}
//----------------------------------------------------------------------------
@@ -75,21 +79,21 @@ Glob::~Glob()
}
//----------------------------------------------------------------------------
-kwsys_stl::vector<kwsys_stl::string>& Glob::GetFiles()
+std::vector<std::string>& Glob::GetFiles()
{
return this->Internals->Files;
}
//----------------------------------------------------------------------------
-kwsys_stl::string Glob::PatternToRegex(const kwsys_stl::string& pattern,
+std::string Glob::PatternToRegex(const std::string& pattern,
bool require_whole_string,
bool preserve_case)
{
// Incrementally build the regular expression from the pattern.
- kwsys_stl::string regex = require_whole_string? "^" : "";
- kwsys_stl::string::const_iterator pattern_first = pattern.begin();
- kwsys_stl::string::const_iterator pattern_last = pattern.end();
- for(kwsys_stl::string::const_iterator i = pattern_first;
+ std::string regex = require_whole_string? "^" : "";
+ std::string::const_iterator pattern_first = pattern.begin();
+ std::string::const_iterator pattern_last = pattern.end();
+ for(std::string::const_iterator i = pattern_first;
i != pattern_last; ++i)
{
int c = *i;
@@ -113,8 +117,8 @@ kwsys_stl::string Glob::PatternToRegex(const kwsys_stl::string& pattern,
{
// Parse out the bracket expression. It begins just after the
// opening character.
- kwsys_stl::string::const_iterator bracket_first = i+1;
- kwsys_stl::string::const_iterator bracket_last = bracket_first;
+ std::string::const_iterator bracket_first = i+1;
+ std::string::const_iterator bracket_last = bracket_first;
// The first character may be complementation '!' or '^'.
if(bracket_last != pattern_last &&
@@ -146,7 +150,7 @@ kwsys_stl::string Glob::PatternToRegex(const kwsys_stl::string& pattern,
else
{
// Convert the bracket string to its regex equivalent.
- kwsys_stl::string::const_iterator k = bracket_first;
+ std::string::const_iterator k = bracket_first;
// Open the regex block.
regex += "[";
@@ -214,23 +218,21 @@ kwsys_stl::string Glob::PatternToRegex(const kwsys_stl::string& pattern,
}
//----------------------------------------------------------------------------
-void Glob::RecurseDirectory(kwsys_stl::string::size_type start,
- const kwsys_stl::string& dir)
+bool Glob::RecurseDirectory(std::string::size_type start,
+ const std::string& dir, GlobMessages* messages)
{
kwsys::Directory d;
- if ( !d.Load(dir.c_str()) )
+ if ( !d.Load(dir) )
{
- return;
+ return true;
}
unsigned long cc;
- kwsys_stl::string fullname;
- kwsys_stl::string realname;
- kwsys_stl::string fname;
+ std::string realname;
+ std::string fname;
for ( cc = 0; cc < d.GetNumberOfFiles(); cc ++ )
{
fname = d.GetFile(cc);
- if ( strcmp(fname.c_str(), ".") == 0 ||
- strcmp(fname.c_str(), "..") == 0 )
+ if ( fname == "." || fname == ".." )
{
continue;
}
@@ -249,47 +251,98 @@ void Glob::RecurseDirectory(kwsys_stl::string::size_type start,
fname = kwsys::SystemTools::LowerCase(fname);
#endif
- if ( start == 0 )
- {
- fullname = dir + fname;
- }
- else
- {
- fullname = dir + "/" + fname;
- }
-
- bool isDir = kwsys::SystemTools::FileIsDirectory(realname.c_str());
- bool isSymLink = kwsys::SystemTools::FileIsSymlink(realname.c_str());
+ bool isDir = kwsys::SystemTools::FileIsDirectory(realname);
+ bool isSymLink = kwsys::SystemTools::FileIsSymlink(realname);
if ( isDir && (!isSymLink || this->RecurseThroughSymlinks) )
{
if (isSymLink)
{
++this->FollowedSymlinkCount;
+ std::string realPathErrorMessage;
+ std::string canonicalPath(SystemTools::GetRealPath(dir,
+ &realPathErrorMessage));
+
+ if(!realPathErrorMessage.empty())
+ {
+ if(messages)
+ {
+ messages->push_back(Message(
+ Glob::error, "Canonical path generation from path '"
+ + dir + "' failed! Reason: '" + realPathErrorMessage + "'"));
+ }
+ return false;
+ }
+
+ if(std::find(this->VisitedSymlinks.begin(),
+ this->VisitedSymlinks.end(),
+ canonicalPath) == this->VisitedSymlinks.end())
+ {
+ if(this->RecurseListDirs)
+ {
+ // symlinks are treated as directories
+ this->AddFile(this->Internals->Files, realname);
+ }
+
+ this->VisitedSymlinks.push_back(canonicalPath);
+ if(!this->RecurseDirectory(start+1, realname, messages))
+ {
+ this->VisitedSymlinks.pop_back();
+
+ return false;
+ }
+ this->VisitedSymlinks.pop_back();
+ }
+ // else we have already visited this symlink - prevent cyclic recursion
+ else if(messages)
+ {
+ std::string message;
+ for(std::vector<std::string>::const_iterator
+ pathIt = std::find(this->VisitedSymlinks.begin(),
+ this->VisitedSymlinks.end(),
+ canonicalPath);
+ pathIt != this->VisitedSymlinks.end(); ++pathIt)
+ {
+ message += *pathIt + "\n";
+ }
+ message += canonicalPath + "/" + fname;
+ messages->push_back(Message(Glob::cyclicRecursion, message));
+ }
+ }
+ else
+ {
+ if(this->RecurseListDirs)
+ {
+ this->AddFile(this->Internals->Files, realname);
+ }
+ if(!this->RecurseDirectory(start+1, realname, messages))
+ {
+ return false;
+ }
}
- this->RecurseDirectory(start+1, realname);
}
else
{
- if ( (this->Internals->Expressions.size() > 0) &&
- this->Internals->Expressions[
- this->Internals->Expressions.size()-1].find(fname.c_str()) )
+ if ( !this->Internals->Expressions.empty() &&
+ this->Internals->Expressions.rbegin()->find(fname) )
{
- this->AddFile(this->Internals->Files, realname.c_str());
+ this->AddFile(this->Internals->Files, realname);
}
}
}
+
+ return true;
}
//----------------------------------------------------------------------------
-void Glob::ProcessDirectory(kwsys_stl::string::size_type start,
- const kwsys_stl::string& dir)
+void Glob::ProcessDirectory(std::string::size_type start,
+ const std::string& dir, GlobMessages* messages)
{
- //kwsys_ios::cout << "ProcessDirectory: " << dir << kwsys_ios::endl;
+ //std::cout << "ProcessDirectory: " << dir << std::endl;
bool last = ( start == this->Internals->Expressions.size()-1 );
if ( last && this->Recurse )
{
- this->RecurseDirectory(start, dir);
+ this->RecurseDirectory(start, dir, messages);
return;
}
@@ -299,19 +352,17 @@ void Glob::ProcessDirectory(kwsys_stl::string::size_type start,
}
kwsys::Directory d;
- if ( !d.Load(dir.c_str()) )
+ if ( !d.Load(dir) )
{
return;
}
unsigned long cc;
- kwsys_stl::string fullname;
- kwsys_stl::string realname;
- kwsys_stl::string fname;
+ std::string realname;
+ std::string fname;
for ( cc = 0; cc < d.GetNumberOfFiles(); cc ++ )
{
fname = d.GetFile(cc);
- if ( strcmp(fname.c_str(), ".") == 0 ||
- strcmp(fname.c_str(), "..") == 0 )
+ if ( fname == "." || fname == ".." )
{
continue;
}
@@ -330,59 +381,51 @@ void Glob::ProcessDirectory(kwsys_stl::string::size_type start,
fname = kwsys::SystemTools::LowerCase(fname);
#endif
- if ( start == 0 )
- {
- fullname = dir + fname;
- }
- else
- {
- fullname = dir + "/" + fname;
- }
-
- //kwsys_ios::cout << "Look at file: " << fname << kwsys_ios::endl;
- //kwsys_ios::cout << "Match: "
- // << this->Internals->TextExpressions[start].c_str() << kwsys_ios::endl;
- //kwsys_ios::cout << "Full name: " << fullname << kwsys_ios::endl;
+ //std::cout << "Look at file: " << fname << std::endl;
+ //std::cout << "Match: "
+ // << this->Internals->TextExpressions[start].c_str() << std::endl;
+ //std::cout << "Real name: " << realname << std::endl;
- if ( !last &&
- !kwsys::SystemTools::FileIsDirectory(realname.c_str()) )
+ if( (!last && !kwsys::SystemTools::FileIsDirectory(realname))
+ || (!this->ListDirs && last &&
+ kwsys::SystemTools::FileIsDirectory(realname)) )
{
continue;
}
- if ( this->Internals->Expressions[start].find(fname.c_str()) )
+ if ( this->Internals->Expressions[start].find(fname) )
{
if ( last )
{
- this->AddFile(this->Internals->Files, realname.c_str());
+ this->AddFile(this->Internals->Files, realname);
}
else
{
- this->ProcessDirectory(start+1, realname + "/");
+ this->ProcessDirectory(start+1, realname, messages);
}
}
}
}
//----------------------------------------------------------------------------
-bool Glob::FindFiles(const kwsys_stl::string& inexpr)
+bool Glob::FindFiles(const std::string& inexpr, GlobMessages* messages)
{
- kwsys_stl::string cexpr;
- kwsys_stl::string::size_type cc;
- kwsys_stl::string expr = inexpr;
+ std::string cexpr;
+ std::string::size_type cc;
+ std::string expr = inexpr;
this->Internals->Expressions.clear();
this->Internals->Files.clear();
- if ( !kwsys::SystemTools::FileIsFullPath(expr.c_str()) )
+ if ( !kwsys::SystemTools::FileIsFullPath(expr) )
{
expr = kwsys::SystemTools::GetCurrentWorkingDirectory();
expr += "/" + inexpr;
}
- kwsys_stl::string fexpr = expr;
+ std::string fexpr = expr;
- kwsys_stl::string::size_type skip = 0;
- kwsys_stl::string::size_type last_slash = 0;
+ std::string::size_type skip = 0;
+ std::string::size_type last_slash = 0;
for ( cc = 0; cc < expr.size(); cc ++ )
{
if ( cc > 0 && expr[cc] == '/' && expr[cc-1] != '\\' )
@@ -398,8 +441,8 @@ bool Glob::FindFiles(const kwsys_stl::string& inexpr)
}
if ( last_slash > 0 )
{
- //kwsys_ios::cout << "I can skip: " << fexpr.substr(0, last_slash)
- // << kwsys_ios::endl;
+ //std::cout << "I can skip: " << fexpr.substr(0, last_slash)
+ // << std::endl;
skip = last_slash;
}
if ( skip == 0 )
@@ -442,9 +485,9 @@ bool Glob::FindFiles(const kwsys_stl::string& inexpr)
int ch = expr[cc];
if ( ch == '/' )
{
- if ( cexpr.size() > 0 )
+ if ( !cexpr.empty() )
{
- this->AddExpression(cexpr.c_str());
+ this->AddExpression(cexpr);
}
cexpr = "";
}
@@ -453,29 +496,29 @@ bool Glob::FindFiles(const kwsys_stl::string& inexpr)
cexpr.append(1, static_cast<char>(ch));
}
}
- if ( cexpr.size() > 0 )
+ if ( !cexpr.empty() )
{
- this->AddExpression(cexpr.c_str());
+ this->AddExpression(cexpr);
}
// Handle network paths
if ( skip > 0 )
{
- this->ProcessDirectory(0, fexpr.substr(0, skip) + "/");
+ this->ProcessDirectory(0, fexpr.substr(0, skip) + "/", messages);
}
else
{
- this->ProcessDirectory(0, "/");
+ this->ProcessDirectory(0, "/", messages);
}
return true;
}
//----------------------------------------------------------------------------
-void Glob::AddExpression(const char* expr)
+void Glob::AddExpression(const std::string& expr)
{
this->Internals->Expressions.push_back(
kwsys::RegularExpression(
- this->PatternToRegex(expr).c_str()));
+ this->PatternToRegex(expr)));
}
//----------------------------------------------------------------------------
@@ -500,11 +543,11 @@ const char* Glob::GetRelative()
}
//----------------------------------------------------------------------------
-void Glob::AddFile(kwsys_stl::vector<kwsys_stl::string>& files, const char* file)
+void Glob::AddFile(std::vector<std::string>& files, const std::string& file)
{
if ( !this->Relative.empty() )
{
- files.push_back(kwsys::SystemTools::RelativePath(this->Relative.c_str(), file));
+ files.push_back(kwsys::SystemTools::RelativePath(this->Relative, file));
}
else
{
diff --git a/Source/kwsys/Glob.hxx.in b/Source/kwsys/Glob.hxx.in
index 88c343ce0..ffee9ca80 100644
--- a/Source/kwsys/Glob.hxx.in
+++ b/Source/kwsys/Glob.hxx.in
@@ -15,13 +15,8 @@
#include <@KWSYS_NAMESPACE@/Configure.h>
#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
-# define kwsys_stl @KWSYS_NAMESPACE@_stl
-#endif
+#include <string>
+#include <vector>
namespace @KWSYS_NAMESPACE@
{
@@ -40,14 +35,45 @@ class GlobInternals;
class @KWSYS_NAMESPACE@_EXPORT Glob
{
public:
+ enum MessageType
+ {
+ error,
+ cyclicRecursion
+ };
+
+ struct Message
+ {
+ MessageType type;
+ std::string content;
+
+ Message(MessageType t, const std::string& c) :
+ type(t),
+ content(c)
+ {}
+ Message(const Message& msg) :
+ type(msg.type),
+ content(msg.content)
+ {}
+ Message& operator=(Message const& msg)
+ {
+ this->type = msg.type;
+ this->content = msg.content;
+ return *this;
+ }
+ };
+
+ typedef std::vector<Message> GlobMessages;
+ typedef std::vector<Message>::iterator GlobMessagesIterator;
+public:
Glob();
~Glob();
//! Find all files that match the pattern.
- bool FindFiles(const kwsys_stl::string& inexpr);
+ bool FindFiles(const std::string& inexpr,
+ GlobMessages* messages = 0);
//! Return the list of files that matched.
- kwsys_stl::vector<kwsys_stl::string>& GetFiles();
+ std::vector<std::string>& GetFiles();
//! Set recurse to true to match subdirectories.
void RecurseOn() { this->SetRecurse(true); }
@@ -76,31 +102,45 @@ public:
string. This is on by default because patterns always match
whole strings, but may be disabled to support concatenating
expressions more easily (regex1|regex2|etc). */
- static kwsys_stl::string PatternToRegex(const kwsys_stl::string& pattern,
+ static std::string PatternToRegex(const std::string& pattern,
bool require_whole_string = true,
bool preserve_case = false);
+ /** Getters and setters for enabling and disabling directory
+ listing in recursive and non recursive globbing mode.
+ If listing is enabled in recursive mode it also lists
+ directory symbolic links even if follow symlinks is enabled. */
+ void SetListDirs(bool list) { this->ListDirs=list; }
+ bool GetListDirs() const { return this->ListDirs; }
+ void SetRecurseListDirs(bool list) { this->RecurseListDirs=list; }
+ bool GetRecurseListDirs() const { return this->RecurseListDirs; }
+
protected:
//! Process directory
- void ProcessDirectory(kwsys_stl::string::size_type start,
- const kwsys_stl::string& dir);
+ void ProcessDirectory(std::string::size_type start,
+ const std::string& dir,
+ GlobMessages* messages);
//! Process last directory, but only when recurse flags is on. That is
// effectively like saying: /path/to/file/**/file
- void RecurseDirectory(kwsys_stl::string::size_type start,
- const kwsys_stl::string& dir);
+ bool RecurseDirectory(std::string::size_type start,
+ const std::string& dir,
+ GlobMessages* messages);
//! Add regular expression
- void AddExpression(const char* expr);
+ void AddExpression(const std::string& expr);
//! Add a file to the list
- void AddFile(kwsys_stl::vector<kwsys_stl::string>& files, const char* file);
+ void AddFile(std::vector<std::string>& files, const std::string& file);
GlobInternals* Internals;
bool Recurse;
- kwsys_stl::string Relative;
+ std::string Relative;
bool RecurseThroughSymlinks;
unsigned int FollowedSymlinkCount;
+ std::vector<std::string> VisitedSymlinks;
+ bool ListDirs;
+ bool RecurseListDirs;
private:
Glob(const Glob&); // Not implemented.
@@ -109,9 +149,4 @@ private:
} // namespace @KWSYS_NAMESPACE@
-/* Undefine temporary macro. */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
-# undef kwsys_stl
-#endif
-
#endif
diff --git a/Source/kwsys/IOStream.cxx b/Source/kwsys/IOStream.cxx
index a31f8c846..81c6a73a6 100644
--- a/Source/kwsys/IOStream.cxx
+++ b/Source/kwsys/IOStream.cxx
@@ -12,25 +12,14 @@
#include "kwsysPrivate.h"
#include KWSYS_HEADER(Configure.hxx)
-// Configure the implementation for the current streams library.
-#if !KWSYS_IOS_USE_ANSI
-# define ios_base ios
-# if defined(__HP_aCC)
-# define protected public
-# include <iostream.h> // Hack access to some private stream methods.
-# undef protected
-# endif
-#endif
-
// Include the streams library.
-#include KWSYS_HEADER(ios/iostream)
+#include <iostream>
#include KWSYS_HEADER(IOStream.hxx)
// Work-around CMake dependency scanning limitation. This must
// duplicate the above list of headers.
#if 0
# include "Configure.hxx.in"
-# include "kwsys_ios_iostream.hxx.in"
# include "IOStream.hxx.in"
#endif
@@ -50,7 +39,7 @@ namespace KWSYS_NAMESPACE
{
// Scan an input stream for an integer value.
-static int IOStreamScanStream(kwsys_ios::istream& is, char* buffer)
+static int IOStreamScanStream(std::istream& is, char* buffer)
{
// Prepare to write to buffer.
char* out = buffer;
@@ -64,10 +53,10 @@ static int IOStreamScanStream(kwsys_ios::istream& is, char* buffer)
// detect it from the input. A leading 0x means hex, and a leading
// 0 alone means octal.
int base = 0;
- int flags = is.flags() & kwsys_ios::ios_base::basefield;
- if(flags == kwsys_ios::ios_base::oct) { base = 8; }
- else if(flags == kwsys_ios::ios_base::dec) { base = 10; }
- else if(flags == kwsys_ios::ios_base::hex) { base = 16; }
+ int flags = is.flags() & std::ios_base::basefield;
+ if(flags == std::ios_base::oct) { base = 8; }
+ else if(flags == std::ios_base::dec) { base = 10; }
+ else if(flags == std::ios_base::hex) { base = 16; }
bool foundDigit = false;
bool foundNonZero = false;
if(is.peek() == '0')
@@ -134,24 +123,17 @@ static int IOStreamScanStream(kwsys_ios::istream& is, char* buffer)
// Read an integer value from an input stream.
template <class T>
-kwsys_ios::istream&
-IOStreamScanTemplate(kwsys_ios::istream& is, T& value, char type)
+std::istream&
+IOStreamScanTemplate(std::istream& is, T& value, char type)
{
- int state = kwsys_ios::ios_base::goodbit;
+ int state = std::ios_base::goodbit;
// Skip leading whitespace.
-# if KWSYS_IOS_USE_ANSI
- kwsys_ios::istream::sentry okay(is);
-# else
- is.eatwhite();
- kwsys_ios::istream& okay = is;
-# endif
+ std::istream::sentry okay(is);
if(okay)
{
-# if KWSYS_IOS_USE_ANSI
try {
-# endif
// Copy the string to a buffer and construct the format string.
char buffer[KWSYS_IOS_INT64_MAX_DIG];
# if defined(_MSC_VER)
@@ -174,52 +156,40 @@ IOStreamScanTemplate(kwsys_ios::istream& is, T& value, char type)
int success = (sscanf(buffer, format, &result) == 1)?1:0;
// Set flags for resulting state.
- if(is.peek() == EOF) { state |= kwsys_ios::ios_base::eofbit; }
- if(!success) { state |= kwsys_ios::ios_base::failbit; }
+ if(is.peek() == EOF) { state |= std::ios_base::eofbit; }
+ if(!success) { state |= std::ios_base::failbit; }
else { value = result; }
-# if KWSYS_IOS_USE_ANSI
- } catch(...) { state |= kwsys_ios::ios_base::badbit; }
-# endif
+ } catch(...) { state |= std::ios_base::badbit; }
}
-# if KWSYS_IOS_USE_ANSI
- is.setstate(kwsys_ios::ios_base::iostate(state));
-# else
- is.clear(state);
-# endif
+ is.setstate(std::ios_base::iostate(state));
return is;
}
// Print an integer value to an output stream.
template <class T>
-kwsys_ios::ostream&
-IOStreamPrintTemplate(kwsys_ios::ostream& os, T value, char type)
+std::ostream&
+IOStreamPrintTemplate(std::ostream& os, T value, char type)
{
-# if KWSYS_IOS_USE_ANSI
- kwsys_ios::ostream::sentry okay(os);
-# else
- kwsys_ios::ostream& okay = os;
-# endif
+ std::ostream::sentry okay(os);
if(okay)
{
-# if KWSYS_IOS_USE_ANSI
try {
-# endif
// Construct the format string.
char format[8];
char* f = format;
*f++ = '%';
- if(os.flags() & kwsys_ios::ios_base::showpos) { *f++ = '+'; }
- if(os.flags() & kwsys_ios::ios_base::showbase) { *f++ = '#'; }
+ if(os.flags() & std::ios_base::showpos) { *f++ = '+'; }
+ if(os.flags() & std::ios_base::showbase) { *f++ = '#'; }
# if defined(_MSC_VER)
*f++ = 'I'; *f++ = '6'; *f++ = '4';
# else
*f++ = 'l'; *f++ = 'l';
# endif
- long bflags = os.flags() & kwsys_ios::ios_base::basefield;
- if(bflags == kwsys_ios::ios_base::oct) { *f++ = 'o'; }
- else if(bflags != kwsys_ios::ios_base::hex) { *f++ = type; }
- else if(os.flags() & kwsys_ios::ios_base::uppercase) { *f++ = 'X'; }
+ long bflags = os.flags() & std::ios_base::basefield;
+ if(bflags == std::ios_base::oct) { *f++ = 'o'; }
+ else if(bflags != std::ios_base::hex) { *f++ = type; }
+ else if(os.flags() & std::ios_base::uppercase) { *f++ = 'X'; }
else { *f++ = 'x'; }
*f = '\0';
@@ -228,22 +198,20 @@ IOStreamPrintTemplate(kwsys_ios::ostream& os, T value, char type)
char buffer[2*KWSYS_IOS_INT64_MAX_DIG];
sprintf(buffer, format, value);
os << buffer;
-# if KWSYS_IOS_USE_ANSI
- } catch(...) { os.clear(os.rdstate() | kwsys_ios::ios_base::badbit); }
-# endif
+ } catch(...) { os.clear(os.rdstate() | std::ios_base::badbit); }
}
return os;
}
# if !KWSYS_IOS_HAS_ISTREAM_LONG_LONG
// Implement input stream operator for IOStreamSLL.
-kwsys_ios::istream& IOStreamScan(kwsys_ios::istream& is, IOStreamSLL& value)
+std::istream& IOStreamScan(std::istream& is, IOStreamSLL& value)
{
return IOStreamScanTemplate(is, value, 'd');
}
// Implement input stream operator for IOStreamULL.
-kwsys_ios::istream& IOStreamScan(kwsys_ios::istream& is, IOStreamULL& value)
+std::istream& IOStreamScan(std::istream& is, IOStreamULL& value)
{
return IOStreamScanTemplate(is, value, 'u');
}
@@ -251,13 +219,13 @@ kwsys_ios::istream& IOStreamScan(kwsys_ios::istream& is, IOStreamULL& value)
# if !KWSYS_IOS_HAS_OSTREAM_LONG_LONG
// Implement output stream operator for IOStreamSLL.
-kwsys_ios::ostream& IOStreamPrint(kwsys_ios::ostream& os, IOStreamSLL value)
+std::ostream& IOStreamPrint(std::ostream& os, IOStreamSLL value)
{
return IOStreamPrintTemplate(os, value, 'd');
}
// Implement output stream operator for IOStreamULL.
-kwsys_ios::ostream& IOStreamPrint(kwsys_ios::ostream& os, IOStreamULL value)
+std::ostream& IOStreamPrint(std::ostream& os, IOStreamULL value)
{
return IOStreamPrintTemplate(os, value, 'u');
}
diff --git a/Source/kwsys/IOStream.hxx.in b/Source/kwsys/IOStream.hxx.in
index 2eeedf2ff..c10190954 100644
--- a/Source/kwsys/IOStream.hxx.in
+++ b/Source/kwsys/IOStream.hxx.in
@@ -12,12 +12,11 @@
#ifndef @KWSYS_NAMESPACE@_IOStream_hxx
#define @KWSYS_NAMESPACE@_IOStream_hxx
-#include <@KWSYS_NAMESPACE@/ios/iosfwd>
+#include <iosfwd>
/* Define these macros temporarily to keep the code readable. */
#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
-# define kwsys_ios @KWSYS_NAMESPACE@_ios
#endif
/* Whether istream supports long long. */
@@ -56,10 +55,8 @@
/* Input stream operator implementation functions. */
namespace @KWSYS_NAMESPACE@
{
-kwsysEXPORT kwsys_ios::istream& IOStreamScan(kwsys_ios::istream&,
- IOStreamSLL&);
-kwsysEXPORT kwsys_ios::istream& IOStreamScan(kwsys_ios::istream&,
- IOStreamULL&);
+kwsysEXPORT std::istream& IOStreamScan(std::istream&, IOStreamSLL&);
+kwsysEXPORT std::istream& IOStreamScan(std::istream&, IOStreamULL&);
}
/* Provide input stream operator for long long. */
@@ -67,8 +64,8 @@ kwsysEXPORT kwsys_ios::istream& IOStreamScan(kwsys_ios::istream&,
!defined(KWSYS_IOS_ISTREAM_LONG_LONG_DEFINED)
# define KWSYS_IOS_ISTREAM_LONG_LONG_DEFINED
# define @KWSYS_NAMESPACE@_IOS_ISTREAM_LONG_LONG_DEFINED
-inline kwsys_ios::istream&
-operator>>(kwsys_ios::istream& is, @KWSYS_NAMESPACE@::IOStreamSLL& value)
+inline std::istream&
+operator>>(std::istream& is, @KWSYS_NAMESPACE@::IOStreamSLL& value)
{
return @KWSYS_NAMESPACE@::IOStreamScan(is, value);
}
@@ -79,8 +76,8 @@ operator>>(kwsys_ios::istream& is, @KWSYS_NAMESPACE@::IOStreamSLL& value)
!defined(KWSYS_IOS_ISTREAM_UNSIGNED_LONG_LONG_DEFINED)
# define KWSYS_IOS_ISTREAM_UNSIGNED_LONG_LONG_DEFINED
# define @KWSYS_NAMESPACE@_IOS_ISTREAM_UNSIGNED_LONG_LONG_DEFINED
-inline kwsys_ios::istream&
-operator>>(kwsys_ios::istream& is, @KWSYS_NAMESPACE@::IOStreamULL& value)
+inline std::istream&
+operator>>(std::istream& is, @KWSYS_NAMESPACE@::IOStreamULL& value)
{
return @KWSYS_NAMESPACE@::IOStreamScan(is, value);
}
@@ -92,10 +89,8 @@ operator>>(kwsys_ios::istream& is, @KWSYS_NAMESPACE@::IOStreamULL& value)
/* Output stream operator implementation functions. */
namespace @KWSYS_NAMESPACE@
{
-kwsysEXPORT kwsys_ios::ostream& IOStreamPrint(kwsys_ios::ostream&,
- IOStreamSLL);
-kwsysEXPORT kwsys_ios::ostream& IOStreamPrint(kwsys_ios::ostream&,
- IOStreamULL);
+kwsysEXPORT std::ostream& IOStreamPrint(std::ostream&, IOStreamSLL);
+kwsysEXPORT std::ostream& IOStreamPrint(std::ostream&, IOStreamULL);
}
/* Provide output stream operator for long long. */
@@ -103,8 +98,8 @@ kwsysEXPORT kwsys_ios::ostream& IOStreamPrint(kwsys_ios::ostream&,
!defined(KWSYS_IOS_OSTREAM_LONG_LONG_DEFINED)
# define KWSYS_IOS_OSTREAM_LONG_LONG_DEFINED
# define @KWSYS_NAMESPACE@_IOS_OSTREAM_LONG_LONG_DEFINED
-inline kwsys_ios::ostream&
-operator<<(kwsys_ios::ostream& os, @KWSYS_NAMESPACE@::IOStreamSLL value)
+inline std::ostream&
+operator<<(std::ostream& os, @KWSYS_NAMESPACE@::IOStreamSLL value)
{
return @KWSYS_NAMESPACE@::IOStreamPrint(os, value);
}
@@ -115,8 +110,8 @@ operator<<(kwsys_ios::ostream& os, @KWSYS_NAMESPACE@::IOStreamSLL value)
!defined(KWSYS_IOS_OSTREAM_UNSIGNED_LONG_LONG_DEFINED)
# define KWSYS_IOS_OSTREAM_UNSIGNED_LONG_LONG_DEFINED
# define @KWSYS_NAMESPACE@_IOS_OSTREAM_UNSIGNED_LONG_LONG_DEFINED
-inline kwsys_ios::ostream&
-operator<<(kwsys_ios::ostream& os, @KWSYS_NAMESPACE@::IOStreamULL value)
+inline std::ostream&
+operator<<(std::ostream& os, @KWSYS_NAMESPACE@::IOStreamULL value)
{
return @KWSYS_NAMESPACE@::IOStreamPrint(os, value);
}
@@ -127,7 +122,6 @@ operator<<(kwsys_ios::ostream& os, @KWSYS_NAMESPACE@::IOStreamULL value)
/* Undefine temporary macros. */
#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
# undef kwsysEXPORT
-# undef kwsys_ios
#endif
/* If building a C++ file in kwsys itself, give the source file
diff --git a/Source/kwsys/MD5.c b/Source/kwsys/MD5.c
index 56776a324..b9d25a8d7 100644
--- a/Source/kwsys/MD5.c
+++ b/Source/kwsys/MD5.c
@@ -29,7 +29,7 @@
it in a single source file instead of a separate header and
implementation file. */
-#if defined(__clang__)
+#if defined(__clang__) && !defined(__INTEL_COMPILER)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wcast-align"
#endif
@@ -433,7 +433,7 @@ static void md5_finish(md5_state_t *pms, md5_byte_t digest[16])
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
}
-#if defined(__clang__)
+#if defined(__clang__) && !defined(__INTEL_COMPILER)
# pragma clang diagnostic pop
#endif
@@ -478,11 +478,16 @@ void kwsysMD5_Initialize(kwsysMD5* md5)
/*--------------------------------------------------------------------------*/
void kwsysMD5_Append(kwsysMD5* md5, unsigned char const* data, int length)
{
+ size_t dlen;
if(length < 0)
{
- length = (int)strlen((char const*)data);
+ dlen = strlen((char const*)data);
}
- md5_append(&md5->md5_state, (md5_byte_t const*)data, (size_t)length);
+ else
+ {
+ dlen = (size_t)length;
+ }
+ md5_append(&md5->md5_state, (md5_byte_t const*)data, dlen);
}
/*--------------------------------------------------------------------------*/
diff --git a/Source/kwsys/Process.h.in b/Source/kwsys/Process.h.in
index c5995eac1..c5ebc97f4 100644
--- a/Source/kwsys/Process.h.in
+++ b/Source/kwsys/Process.h.in
@@ -23,57 +23,60 @@
# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
#endif
#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
-# define kwsysProcess kwsys_ns(Process)
-# define kwsysProcess_s kwsys_ns(Process_s)
-# define kwsysProcess_New kwsys_ns(Process_New)
-# define kwsysProcess_Delete kwsys_ns(Process_Delete)
-# define kwsysProcess_SetCommand kwsys_ns(Process_SetCommand)
-# define kwsysProcess_AddCommand kwsys_ns(Process_AddCommand)
-# define kwsysProcess_SetTimeout kwsys_ns(Process_SetTimeout)
-# define kwsysProcess_SetWorkingDirectory kwsys_ns(Process_SetWorkingDirectory)
-# define kwsysProcess_SetPipeFile kwsys_ns(Process_SetPipeFile)
-# define kwsysProcess_SetPipeNative kwsys_ns(Process_SetPipeNative)
-# define kwsysProcess_SetPipeShared kwsys_ns(Process_SetPipeShared)
-# define kwsysProcess_Option_Detach kwsys_ns(Process_Option_Detach)
-# define kwsysProcess_Option_HideWindow kwsys_ns(Process_Option_HideWindow)
-# define kwsysProcess_Option_Verbatim kwsys_ns(Process_Option_Verbatim)
-# define kwsysProcess_GetOption kwsys_ns(Process_GetOption)
-# define kwsysProcess_SetOption kwsys_ns(Process_SetOption)
-# define kwsysProcess_Option_e kwsys_ns(Process_Option_e)
-# define kwsysProcess_State_Starting kwsys_ns(Process_State_Starting)
-# define kwsysProcess_State_Error kwsys_ns(Process_State_Error)
-# define kwsysProcess_State_Exception kwsys_ns(Process_State_Exception)
-# define kwsysProcess_State_Executing kwsys_ns(Process_State_Executing)
-# define kwsysProcess_State_Exited kwsys_ns(Process_State_Exited)
-# define kwsysProcess_State_Expired kwsys_ns(Process_State_Expired)
-# define kwsysProcess_State_Killed kwsys_ns(Process_State_Killed)
-# define kwsysProcess_State_Disowned kwsys_ns(Process_State_Disowned)
-# define kwsysProcess_GetState kwsys_ns(Process_GetState)
-# define kwsysProcess_State_e kwsys_ns(Process_State_e)
-# define kwsysProcess_Exception_None kwsys_ns(Process_Exception_None)
-# define kwsysProcess_Exception_Fault kwsys_ns(Process_Exception_Fault)
-# define kwsysProcess_Exception_Illegal kwsys_ns(Process_Exception_Illegal)
-# define kwsysProcess_Exception_Interrupt kwsys_ns(Process_Exception_Interrupt)
-# define kwsysProcess_Exception_Numerical kwsys_ns(Process_Exception_Numerical)
-# define kwsysProcess_Exception_Other kwsys_ns(Process_Exception_Other)
-# define kwsysProcess_GetExitException kwsys_ns(Process_GetExitException)
-# define kwsysProcess_Exception_e kwsys_ns(Process_Exception_e)
-# define kwsysProcess_GetExitCode kwsys_ns(Process_GetExitCode)
-# define kwsysProcess_GetExitValue kwsys_ns(Process_GetExitValue)
-# define kwsysProcess_GetErrorString kwsys_ns(Process_GetErrorString)
-# define kwsysProcess_GetExceptionString kwsys_ns(Process_GetExceptionString)
-# define kwsysProcess_Execute kwsys_ns(Process_Execute)
-# define kwsysProcess_Disown kwsys_ns(Process_Disown)
-# define kwsysProcess_WaitForData kwsys_ns(Process_WaitForData)
-# define kwsysProcess_Pipes_e kwsys_ns(Process_Pipes_e)
-# define kwsysProcess_Pipe_None kwsys_ns(Process_Pipe_None)
-# define kwsysProcess_Pipe_STDIN kwsys_ns(Process_Pipe_STDIN)
-# define kwsysProcess_Pipe_STDOUT kwsys_ns(Process_Pipe_STDOUT)
-# define kwsysProcess_Pipe_STDERR kwsys_ns(Process_Pipe_STDERR)
-# define kwsysProcess_Pipe_Timeout kwsys_ns(Process_Pipe_Timeout)
-# define kwsysProcess_Pipe_Handle kwsys_ns(Process_Pipe_Handle)
-# define kwsysProcess_WaitForExit kwsys_ns(Process_WaitForExit)
-# define kwsysProcess_Kill kwsys_ns(Process_Kill)
+# define kwsysProcess kwsys_ns(Process)
+# define kwsysProcess_s kwsys_ns(Process_s)
+# define kwsysProcess_New kwsys_ns(Process_New)
+# define kwsysProcess_Delete kwsys_ns(Process_Delete)
+# define kwsysProcess_SetCommand kwsys_ns(Process_SetCommand)
+# define kwsysProcess_AddCommand kwsys_ns(Process_AddCommand)
+# define kwsysProcess_SetTimeout kwsys_ns(Process_SetTimeout)
+# define kwsysProcess_SetWorkingDirectory kwsys_ns(Process_SetWorkingDirectory)
+# define kwsysProcess_SetPipeFile kwsys_ns(Process_SetPipeFile)
+# define kwsysProcess_SetPipeNative kwsys_ns(Process_SetPipeNative)
+# define kwsysProcess_SetPipeShared kwsys_ns(Process_SetPipeShared)
+# define kwsysProcess_Option_Detach kwsys_ns(Process_Option_Detach)
+# define kwsysProcess_Option_HideWindow kwsys_ns(Process_Option_HideWindow)
+# define kwsysProcess_Option_MergeOutput kwsys_ns(Process_Option_MergeOutput)
+# define kwsysProcess_Option_Verbatim kwsys_ns(Process_Option_Verbatim)
+# define kwsysProcess_Option_CreateProcessGroup kwsys_ns(Process_Option_CreateProcessGroup)
+# define kwsysProcess_GetOption kwsys_ns(Process_GetOption)
+# define kwsysProcess_SetOption kwsys_ns(Process_SetOption)
+# define kwsysProcess_Option_e kwsys_ns(Process_Option_e)
+# define kwsysProcess_State_Starting kwsys_ns(Process_State_Starting)
+# define kwsysProcess_State_Error kwsys_ns(Process_State_Error)
+# define kwsysProcess_State_Exception kwsys_ns(Process_State_Exception)
+# define kwsysProcess_State_Executing kwsys_ns(Process_State_Executing)
+# define kwsysProcess_State_Exited kwsys_ns(Process_State_Exited)
+# define kwsysProcess_State_Expired kwsys_ns(Process_State_Expired)
+# define kwsysProcess_State_Killed kwsys_ns(Process_State_Killed)
+# define kwsysProcess_State_Disowned kwsys_ns(Process_State_Disowned)
+# define kwsysProcess_GetState kwsys_ns(Process_GetState)
+# define kwsysProcess_State_e kwsys_ns(Process_State_e)
+# define kwsysProcess_Exception_None kwsys_ns(Process_Exception_None)
+# define kwsysProcess_Exception_Fault kwsys_ns(Process_Exception_Fault)
+# define kwsysProcess_Exception_Illegal kwsys_ns(Process_Exception_Illegal)
+# define kwsysProcess_Exception_Interrupt kwsys_ns(Process_Exception_Interrupt)
+# define kwsysProcess_Exception_Numerical kwsys_ns(Process_Exception_Numerical)
+# define kwsysProcess_Exception_Other kwsys_ns(Process_Exception_Other)
+# define kwsysProcess_GetExitException kwsys_ns(Process_GetExitException)
+# define kwsysProcess_Exception_e kwsys_ns(Process_Exception_e)
+# define kwsysProcess_GetExitCode kwsys_ns(Process_GetExitCode)
+# define kwsysProcess_GetExitValue kwsys_ns(Process_GetExitValue)
+# define kwsysProcess_GetErrorString kwsys_ns(Process_GetErrorString)
+# define kwsysProcess_GetExceptionString kwsys_ns(Process_GetExceptionString)
+# define kwsysProcess_Execute kwsys_ns(Process_Execute)
+# define kwsysProcess_Disown kwsys_ns(Process_Disown)
+# define kwsysProcess_WaitForData kwsys_ns(Process_WaitForData)
+# define kwsysProcess_Pipes_e kwsys_ns(Process_Pipes_e)
+# define kwsysProcess_Pipe_None kwsys_ns(Process_Pipe_None)
+# define kwsysProcess_Pipe_STDIN kwsys_ns(Process_Pipe_STDIN)
+# define kwsysProcess_Pipe_STDOUT kwsys_ns(Process_Pipe_STDOUT)
+# define kwsysProcess_Pipe_STDERR kwsys_ns(Process_Pipe_STDERR)
+# define kwsysProcess_Pipe_Timeout kwsys_ns(Process_Pipe_Timeout)
+# define kwsysProcess_Pipe_Handle kwsys_ns(Process_Pipe_Handle)
+# define kwsysProcess_WaitForExit kwsys_ns(Process_WaitForExit)
+# define kwsysProcess_Interrupt kwsys_ns(Process_Interrupt)
+# define kwsysProcess_Kill kwsys_ns(Process_Kill)
#endif
#if defined(__cplusplus)
@@ -186,12 +189,27 @@ kwsysEXPORT void kwsysProcess_SetPipeNative(kwsysProcess* cp, int pipe,
* 0 = No (default)
* 1 = Yes
*
+ * kwsysProcess_Option_MergeOutput = Whether to merge stdout/stderr.
+ * No content will be returned as stderr.
+ * Any actual stderr will be on stdout.
+ * 0 = No (default)
+ * 1 = Yes
+ *
* kwsysProcess_Option_Verbatim = Whether SetCommand and AddCommand
* should treat the first argument
* as a verbatim command line
* and ignore the rest of the arguments.
* 0 = No (default)
* 1 = Yes
+ *
+ * kwsysProcess_Option_CreateProcessGroup = Whether to place the process in a
+ * new process group. This is
+ * useful if you want to send Ctrl+C
+ * to the process. On UNIX, also
+ * places the process in a new
+ * session.
+ * 0 = No (default)
+ * 1 = Yes
*/
kwsysEXPORT int kwsysProcess_GetOption(kwsysProcess* cp, int optionId);
kwsysEXPORT void kwsysProcess_SetOption(kwsysProcess* cp, int optionId,
@@ -200,7 +218,9 @@ enum kwsysProcess_Option_e
{
kwsysProcess_Option_HideWindow,
kwsysProcess_Option_Detach,
- kwsysProcess_Option_Verbatim
+ kwsysProcess_Option_MergeOutput,
+ kwsysProcess_Option_Verbatim,
+ kwsysProcess_Option_CreateProcessGroup
};
/**
@@ -355,6 +375,17 @@ enum kwsysProcess_Pipes_e
kwsysEXPORT int kwsysProcess_WaitForExit(kwsysProcess* cp, double* timeout);
/**
+ * Interrupt the process group for the child process that is currently
+ * running by sending it the appropriate operating-system specific signal.
+ * The caller should call WaitForExit after this returns to wait for the
+ * child to terminate.
+ *
+ * WARNING: If you didn't specify kwsysProcess_Option_CreateProcessGroup,
+ * you will interrupt your own process group.
+ */
+kwsysEXPORT void kwsysProcess_Interrupt(kwsysProcess* cp);
+
+/**
* Forcefully terminate the child process that is currently running.
* The caller should call WaitForExit after this returns to wait for
* the child to terminate.
@@ -384,7 +415,9 @@ kwsysEXPORT void kwsysProcess_Kill(kwsysProcess* cp);
# undef kwsysProcess_SetPipeShared
# undef kwsysProcess_Option_Detach
# undef kwsysProcess_Option_HideWindow
+# undef kwsysProcess_Option_MergeOutput
# undef kwsysProcess_Option_Verbatim
+# undef kwsysProcess_Option_CreateProcessGroup
# undef kwsysProcess_GetOption
# undef kwsysProcess_SetOption
# undef kwsysProcess_Option_e
@@ -421,6 +454,7 @@ kwsysEXPORT void kwsysProcess_Kill(kwsysProcess* cp);
# undef kwsysProcess_Pipe_Timeout
# undef kwsysProcess_Pipe_Handle
# undef kwsysProcess_WaitForExit
+# undef kwsysProcess_Interrupt
# undef kwsysProcess_Kill
# endif
#endif
diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c
index b9af2f1f5..07c644b8e 100644
--- a/Source/kwsys/ProcessUNIX.c
+++ b/Source/kwsys/ProcessUNIX.c
@@ -68,6 +68,7 @@ do.
#include <signal.h> /* sigaction */
#include <dirent.h> /* DIR, dirent */
#include <ctype.h> /* isspace */
+#include <assert.h> /* assert */
#if defined(__VMS)
# define KWSYSPE_VMS_NONBLOCK , O_NONBLOCK
@@ -87,7 +88,7 @@ typedef ssize_t kwsysProcess_ssize_t;
typedef int kwsysProcess_ssize_t;
#endif
-#if defined(__BEOS__) && !defined(__ZETA__)
+#if defined(__BEOS__) && !defined(__ZETA__)
/* BeOS 5 doesn't have usleep(), but it has snooze(), which is identical. */
# include <be/kernel/OS.h>
static inline void kwsysProcess_usleep(unsigned int msec)
@@ -150,13 +151,14 @@ typedef struct kwsysProcessCreateInformation_s
} kwsysProcessCreateInformation;
/*--------------------------------------------------------------------------*/
+static void kwsysProcessVolatileFree(volatile void* p);
static int kwsysProcessInitialize(kwsysProcess* cp);
static void kwsysProcessCleanup(kwsysProcess* cp, int error);
static void kwsysProcessCleanupDescriptor(int* pfd);
static void kwsysProcessClosePipes(kwsysProcess* cp);
static int kwsysProcessSetNonBlocking(int fd);
static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
- kwsysProcessCreateInformation* si, int* readEnd);
+ kwsysProcessCreateInformation* si);
static void kwsysProcessDestroy(kwsysProcess* cp);
static int kwsysProcessSetupOutputPipeFile(int* p, const char* name);
static int kwsysProcessSetupOutputPipeNative(int* p, int des[2]);
@@ -196,20 +198,26 @@ struct kwsysProcess_s
{
/* The command lines to execute. */
char*** Commands;
- int NumberOfCommands;
+ volatile int NumberOfCommands;
/* Descriptors for the read ends of the child's output pipes and
the signal pipe. */
int PipeReadEnds[KWSYSPE_PIPE_COUNT];
+ /* Descriptors for the child's ends of the pipes.
+ Used temporarily during process creation. */
+ int PipeChildStd[3];
+
/* Write descriptor for child termination signal pipe. */
int SignalPipe;
/* Buffer for pipe data. */
char PipeBuffer[KWSYSPE_PIPE_BUFFER_SIZE];
- /* Process IDs returned by the calls to fork. */
- pid_t* ForkPIDs;
+ /* Process IDs returned by the calls to fork. Everything is volatile
+ because the signal handler accesses them. You must be very careful
+ when reaping PIDs or modifying this array to avoid race conditions. */
+ volatile pid_t* volatile ForkPIDs;
/* Flag for whether the children were terminated by a faild select. */
int SelectError;
@@ -229,6 +237,12 @@ struct kwsysProcess_s
/* Whether to treat command lines as verbatim. */
int Verbatim;
+ /* Whether to merge stdout/stderr of the child. */
+ int MergeOutput;
+
+ /* Whether to create the process in a new process group. */
+ volatile sig_atomic_t CreateProcessGroup;
+
/* Time at which the child started. Negative for no timeout. */
kwsysProcessTime StartTime;
@@ -249,8 +263,9 @@ struct kwsysProcess_s
/* The number of children still executing. */
int CommandsLeft;
- /* The current status of the child process. */
- int State;
+ /* The current status of the child process. Must be atomic because
+ the signal handler checks this to avoid a race. */
+ volatile sig_atomic_t State;
/* The exceptional behavior that terminated the child process, if
* any. */
@@ -263,7 +278,7 @@ struct kwsysProcess_s
int ExitValue;
/* Whether the process was killed. */
- int Killed;
+ volatile sig_atomic_t Killed;
/* Buffer for error message in case of failure. */
char ErrorMessage[KWSYSPE_PIPE_BUFFER_SIZE+1];
@@ -450,6 +465,7 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
}
for(i=0; i < n; ++i)
{
+ assert(command[i]); /* Quiet Clang scan-build. */
newCommands[cp->NumberOfCommands][i] = strdup(command[i]);
if(!newCommands[cp->NumberOfCommands][i])
{
@@ -545,7 +561,7 @@ int kwsysProcess_SetPipeFile(kwsysProcess* cp, int prPipe, const char* file)
}
if(file)
{
- *pfile = malloc(strlen(file)+1);
+ *pfile = (char*)malloc(strlen(file)+1);
if(!*pfile)
{
return 0;
@@ -638,7 +654,10 @@ int kwsysProcess_GetOption(kwsysProcess* cp, int optionId)
switch(optionId)
{
case kwsysProcess_Option_Detach: return cp->OptionDetach;
+ case kwsysProcess_Option_MergeOutput: return cp->MergeOutput;
case kwsysProcess_Option_Verbatim: return cp->Verbatim;
+ case kwsysProcess_Option_CreateProcessGroup:
+ return cp->CreateProcessGroup;
default: return 0;
}
}
@@ -654,7 +673,10 @@ void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, int value)
switch(optionId)
{
case kwsysProcess_Option_Detach: cp->OptionDetach = value; break;
+ case kwsysProcess_Option_MergeOutput: cp->MergeOutput = value; break;
case kwsysProcess_Option_Verbatim: cp->Verbatim = value; break;
+ case kwsysProcess_Option_CreateProcessGroup:
+ cp->CreateProcessGroup = value; break;
default: break;
}
}
@@ -715,7 +737,6 @@ const char* kwsysProcess_GetExceptionString(kwsysProcess* cp)
void kwsysProcess_Execute(kwsysProcess* cp)
{
int i;
- kwsysProcessCreateInformation si = {-1, -1, -1, {-1, -1}};
/* Do not execute a second copy simultaneously. */
if(!cp || cp->State == kwsysProcess_State_Executing)
@@ -783,7 +804,50 @@ void kwsysProcess_Execute(kwsysProcess* cp)
}
}
- /* Setup the stderr pipe to be shared by all processes. */
+ /* Setup the stdin pipe for the first process. */
+ if(cp->PipeFileSTDIN)
+ {
+ /* Open a file for the child's stdin to read. */
+ cp->PipeChildStd[0] = open(cp->PipeFileSTDIN, O_RDONLY);
+ if(cp->PipeChildStd[0] < 0)
+ {
+ kwsysProcessCleanup(cp, 1);
+ return;
+ }
+
+ /* Set close-on-exec flag on the pipe's end. */
+ if(fcntl(cp->PipeChildStd[0], F_SETFD, FD_CLOEXEC) < 0)
+ {
+ kwsysProcessCleanup(cp, 1);
+ return;
+ }
+ }
+ else if(cp->PipeSharedSTDIN)
+ {
+ cp->PipeChildStd[0] = 0;
+ }
+ else if(cp->PipeNativeSTDIN[0] >= 0)
+ {
+ cp->PipeChildStd[0] = cp->PipeNativeSTDIN[0];
+
+ /* Set close-on-exec flag on the pipe's ends. The read end will
+ be dup2-ed into the stdin descriptor after the fork but before
+ the exec. */
+ if((fcntl(cp->PipeNativeSTDIN[0], F_SETFD, FD_CLOEXEC) < 0) ||
+ (fcntl(cp->PipeNativeSTDIN[1], F_SETFD, FD_CLOEXEC) < 0))
+ {
+ kwsysProcessCleanup(cp, 1);
+ return;
+ }
+ }
+ else
+ {
+ cp->PipeChildStd[0] = -1;
+ }
+
+ /* Create the output pipe for the last process.
+ We always create this so the pipe can be passed to select even if
+ it will report closed immediately. */
{
/* Create the pipe. */
int p[2];
@@ -794,15 +858,14 @@ void kwsysProcess_Execute(kwsysProcess* cp)
}
/* Store the pipe. */
- cp->PipeReadEnds[KWSYSPE_PIPE_STDERR] = p[0];
- si.StdErr = p[1];
+ cp->PipeReadEnds[KWSYSPE_PIPE_STDOUT] = p[0];
+ cp->PipeChildStd[1] = p[1];
/* Set close-on-exec flag on the pipe's ends. */
if((fcntl(p[0], F_SETFD, FD_CLOEXEC) < 0) ||
(fcntl(p[1], F_SETFD, FD_CLOEXEC) < 0))
{
kwsysProcessCleanup(cp, 1);
- kwsysProcessCleanupDescriptor(&si.StdErr);
return;
}
@@ -811,41 +874,93 @@ void kwsysProcess_Execute(kwsysProcess* cp)
if(!kwsysProcessSetNonBlocking(p[0]))
{
kwsysProcessCleanup(cp, 1);
- kwsysProcessCleanupDescriptor(&si.StdErr);
return;
}
}
- /* Replace the stderr pipe with a file if requested. In this case
- the select call will report that stderr is closed immediately. */
- if(cp->PipeFileSTDERR)
+ if (cp->PipeFileSTDOUT)
{
- if(!kwsysProcessSetupOutputPipeFile(&si.StdErr, cp->PipeFileSTDERR))
+ /* Use a file for stdout. */
+ if(!kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[1],
+ cp->PipeFileSTDOUT))
{
kwsysProcessCleanup(cp, 1);
- kwsysProcessCleanupDescriptor(&si.StdErr);
return;
}
}
+ else if (cp->PipeSharedSTDOUT)
+ {
+ /* Use the parent stdout. */
+ kwsysProcessCleanupDescriptor(&cp->PipeChildStd[1]);
+ cp->PipeChildStd[1] = 1;
+ }
+ else if (cp->PipeNativeSTDOUT[1] >= 0)
+ {
+ /* Use the given descriptor for stdout. */
+ if(!kwsysProcessSetupOutputPipeNative(&cp->PipeChildStd[1],
+ cp->PipeNativeSTDOUT))
+ {
+ kwsysProcessCleanup(cp, 1);
+ return;
+ }
+ }
+
+ /* Create stderr pipe to be shared by all processes in the pipeline.
+ We always create this so the pipe can be passed to select even if
+ it will report closed immediately. */
+ {
+ /* Create the pipe. */
+ int p[2];
+ if(pipe(p KWSYSPE_VMS_NONBLOCK) < 0)
+ {
+ kwsysProcessCleanup(cp, 1);
+ return;
+ }
- /* Replace the stderr pipe with the parent's if requested. In this
- case the select call will report that stderr is closed
- immediately. */
- if(cp->PipeSharedSTDERR)
+ /* Store the pipe. */
+ cp->PipeReadEnds[KWSYSPE_PIPE_STDERR] = p[0];
+ cp->PipeChildStd[2] = p[1];
+
+ /* Set close-on-exec flag on the pipe's ends. */
+ if((fcntl(p[0], F_SETFD, FD_CLOEXEC) < 0) ||
+ (fcntl(p[1], F_SETFD, FD_CLOEXEC) < 0))
+ {
+ kwsysProcessCleanup(cp, 1);
+ return;
+ }
+
+ /* Set to non-blocking in case select lies, or for the polling
+ implementation. */
+ if(!kwsysProcessSetNonBlocking(p[0]))
{
- kwsysProcessCleanupDescriptor(&si.StdErr);
- si.StdErr = 2;
+ kwsysProcessCleanup(cp, 1);
+ return;
}
+ }
- /* Replace the stderr pipe with the native pipe provided if any. In
- this case the select call will report that stderr is closed
- immediately. */
- if(cp->PipeNativeSTDERR[1] >= 0)
+ if (cp->PipeFileSTDERR)
{
- if(!kwsysProcessSetupOutputPipeNative(&si.StdErr, cp->PipeNativeSTDERR))
+ /* Use a file for stderr. */
+ if(!kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[2],
+ cp->PipeFileSTDERR))
+ {
+ kwsysProcessCleanup(cp, 1);
+ return;
+ }
+ }
+ else if (cp->PipeSharedSTDERR)
+ {
+ /* Use the parent stderr. */
+ kwsysProcessCleanupDescriptor(&cp->PipeChildStd[2]);
+ cp->PipeChildStd[2] = 2;
+ }
+ else if (cp->PipeNativeSTDERR[1] >= 0)
+ {
+ /* Use the given handle for stderr. */
+ if(!kwsysProcessSetupOutputPipeNative(&cp->PipeChildStd[2],
+ cp->PipeNativeSTDERR))
{
kwsysProcessCleanup(cp, 1);
- kwsysProcessCleanupDescriptor(&si.StdErr);
return;
}
}
@@ -857,54 +972,85 @@ void kwsysProcess_Execute(kwsysProcess* cp)
/* Create the pipeline of processes. */
{
- int readEnd = -1;
- int failed = 0;
+ kwsysProcessCreateInformation si = {-1, -1, -1, {-1, -1}};
+ int nextStdIn = cp->PipeChildStd[0];
for(i=0; i < cp->NumberOfCommands; ++i)
{
- if(!kwsysProcessCreate(cp, i, &si, &readEnd))
- {
- failed = 1;
- }
-
- /* Set the output pipe of the last process to be non-blocking in
- case select lies, or for the polling implementation. */
- if(i == (cp->NumberOfCommands-1) && !kwsysProcessSetNonBlocking(readEnd))
+ /* Setup the process's pipes. */
+ si.StdIn = nextStdIn;
+ if (i == cp->NumberOfCommands-1)
{
- failed = 1;
+ nextStdIn = -1;
+ si.StdOut = cp->PipeChildStd[1];
}
-
- if(failed)
+ else
{
- kwsysProcessCleanup(cp, 1);
-
- /* Release resources that may have been allocated for this
- process before an error occurred. */
- kwsysProcessCleanupDescriptor(&readEnd);
- if(si.StdIn != 0)
+ /* Create a pipe to sit between the children. */
+ int p[2] = {-1,-1};
+ if(pipe(p KWSYSPE_VMS_NONBLOCK) < 0)
{
- kwsysProcessCleanupDescriptor(&si.StdIn);
- }
- if(si.StdOut != 1)
- {
- kwsysProcessCleanupDescriptor(&si.StdOut);
+ if (nextStdIn != cp->PipeChildStd[0])
+ {
+ kwsysProcessCleanupDescriptor(&nextStdIn);
+ }
+ kwsysProcessCleanup(cp, 1);
+ return;
}
- if(si.StdErr != 2)
+
+ /* Set close-on-exec flag on the pipe's ends. */
+ if((fcntl(p[0], F_SETFD, FD_CLOEXEC) < 0) ||
+ (fcntl(p[1], F_SETFD, FD_CLOEXEC) < 0))
{
- kwsysProcessCleanupDescriptor(&si.StdErr);
+ close(p[0]);
+ close(p[1]);
+ if (nextStdIn != cp->PipeChildStd[0])
+ {
+ kwsysProcessCleanupDescriptor(&nextStdIn);
+ }
+ kwsysProcessCleanup(cp, 1);
+ return;
}
+ nextStdIn = p[0];
+ si.StdOut = p[1];
+ }
+ si.StdErr = cp->MergeOutput? cp->PipeChildStd[1] : cp->PipeChildStd[2];
+
+ {
+ int res = kwsysProcessCreate(cp, i, &si);
+
+ /* Close our copies of pipes used between children. */
+ if (si.StdIn != cp->PipeChildStd[0])
+ {
+ kwsysProcessCleanupDescriptor(&si.StdIn);
+ }
+ if (si.StdOut != cp->PipeChildStd[1])
+ {
+ kwsysProcessCleanupDescriptor(&si.StdOut);
+ }
+ if (si.StdErr != cp->PipeChildStd[2] && !cp->MergeOutput)
+ {
+ kwsysProcessCleanupDescriptor(&si.StdErr);
+ }
+
+ if(!res)
+ {
kwsysProcessCleanupDescriptor(&si.ErrorPipe[0]);
kwsysProcessCleanupDescriptor(&si.ErrorPipe[1]);
+ if (nextStdIn != cp->PipeChildStd[0])
+ {
+ kwsysProcessCleanupDescriptor(&nextStdIn);
+ }
+ kwsysProcessCleanup(cp, 1);
return;
}
}
- /* Save a handle to the output pipe for the last process. */
- cp->PipeReadEnds[KWSYSPE_PIPE_STDOUT] = readEnd;
+ }
}
- /* The parent process does not need the output pipe write ends. */
- if(si.StdErr != 2)
+ /* The parent process does not need the child's pipe ends. */
+ for (i=0; i < 3; ++i)
{
- kwsysProcessCleanupDescriptor(&si.StdErr);
+ kwsysProcessCleanupDescriptor(&cp->PipeChildStd[i]);
}
/* Restore the working directory. */
@@ -1355,6 +1501,45 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
}
/*--------------------------------------------------------------------------*/
+void kwsysProcess_Interrupt(kwsysProcess* cp)
+{
+ int i;
+ /* Make sure we are executing a process. */
+ if(!cp || cp->State != kwsysProcess_State_Executing || cp->TimeoutExpired ||
+ cp->Killed)
+ {
+ return;
+ }
+
+ /* Interrupt the children. */
+ if (cp->CreateProcessGroup)
+ {
+ if(cp->ForkPIDs)
+ {
+ for(i=0; i < cp->NumberOfCommands; ++i)
+ {
+ /* Make sure the PID is still valid. */
+ if(cp->ForkPIDs[i])
+ {
+ /* The user created a process group for this process. The group ID
+ is the process ID for the original process in the group. */
+ kill(-cp->ForkPIDs[i], SIGINT);
+ }
+ }
+ }
+ }
+ else
+ {
+ /* No process group was created. Kill our own process group.
+ NOTE: While one could argue that we could call kill(cp->ForkPIDs[i],
+ SIGINT) as a way to still interrupt the process even though it's not in
+ a special group, this is not an option on Windows. Therefore, we kill
+ the current process group for consistency with Windows. */
+ kill(0, SIGINT);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
void kwsysProcess_Kill(kwsysProcess* cp)
{
int i;
@@ -1404,14 +1589,36 @@ void kwsysProcess_Kill(kwsysProcess* cp)
}
/*--------------------------------------------------------------------------*/
+/* Call the free() function with a pointer to volatile without causing
+ compiler warnings. */
+static void kwsysProcessVolatileFree(volatile void* p)
+{
+ /* clang has made it impossible to free memory that points to volatile
+ without first using special pragmas to disable a warning... */
+#if defined(__clang__) && !defined(__INTEL_COMPILER)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wcast-qual"
+#endif
+ free((void*)p); /* The cast will silence most compilers, but not clang. */
+#if defined(__clang__) && !defined(__INTEL_COMPILER)
+# pragma clang diagnostic pop
+#endif
+}
+
+/*--------------------------------------------------------------------------*/
/* Initialize a process control structure for kwsysProcess_Execute. */
static int kwsysProcessInitialize(kwsysProcess* cp)
{
int i;
+ volatile pid_t* oldForkPIDs;
for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
{
cp->PipeReadEnds[i] = -1;
}
+ for(i=0; i < 3; ++i)
+ {
+ cp->PipeChildStd[i] = -1;
+ }
cp->SignalPipe = -1;
cp->SelectError = 0;
cp->StartTime.tv_sec = -1;
@@ -1432,16 +1639,21 @@ static int kwsysProcessInitialize(kwsysProcess* cp)
cp->ErrorMessage[0] = 0;
strcpy(cp->ExitExceptionString, "No exception");
- if(cp->ForkPIDs)
+ oldForkPIDs = cp->ForkPIDs;
+ cp->ForkPIDs = (volatile pid_t*)malloc(
+ sizeof(volatile pid_t)*(size_t)(cp->NumberOfCommands));
+ if(oldForkPIDs)
{
- free(cp->ForkPIDs);
+ kwsysProcessVolatileFree(oldForkPIDs);
}
- cp->ForkPIDs = (pid_t*)malloc(sizeof(pid_t)*(size_t)(cp->NumberOfCommands));
if(!cp->ForkPIDs)
{
return 0;
}
- memset(cp->ForkPIDs, 0, sizeof(pid_t)*(size_t)(cp->NumberOfCommands));
+ for(i=0; i < cp->NumberOfCommands; ++i)
+ {
+ cp->ForkPIDs[i] = 0; /* can't use memset due to volatile */
+ }
if(cp->CommandExitCodes)
{
@@ -1466,7 +1678,7 @@ static int kwsysProcessInitialize(kwsysProcess* cp)
cp->RealWorkingDirectoryLength = 4096;
#endif
cp->RealWorkingDirectory =
- malloc((size_t)(cp->RealWorkingDirectoryLength));
+ (char*)malloc((size_t)(cp->RealWorkingDirectoryLength));
if(!cp->RealWorkingDirectory)
{
return 0;
@@ -1532,7 +1744,7 @@ static void kwsysProcessCleanup(kwsysProcess* cp, int error)
/* Free memory. */
if(cp->ForkPIDs)
{
- free(cp->ForkPIDs);
+ kwsysProcessVolatileFree(cp->ForkPIDs);
cp->ForkPIDs = 0;
}
if(cp->RealWorkingDirectory)
@@ -1546,13 +1758,17 @@ static void kwsysProcessCleanup(kwsysProcess* cp, int error)
{
kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]);
}
+ for(i=0; i < 3; ++i)
+ {
+ kwsysProcessCleanupDescriptor(&cp->PipeChildStd[i]);
+ }
}
/*--------------------------------------------------------------------------*/
/* Close the given file descriptor if it is open. Reset its value to -1. */
static void kwsysProcessCleanupDescriptor(int* pfd)
{
- if(pfd && *pfd >= 0)
+ if(pfd && *pfd > 2)
{
/* Keep trying to close until it is not interrupted by a
* signal. */
@@ -1613,109 +1829,51 @@ int decc$set_child_standard_streams(int fd1, int fd2, int fd3);
/*--------------------------------------------------------------------------*/
static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
- kwsysProcessCreateInformation* si, int* readEnd)
+ kwsysProcessCreateInformation* si)
{
- /* Setup the process's stdin. */
- if(prIndex > 0)
- {
- si->StdIn = *readEnd;
- *readEnd = 0;
- }
- else if(cp->PipeFileSTDIN)
- {
- /* Open a file for the child's stdin to read. */
- si->StdIn = open(cp->PipeFileSTDIN, O_RDONLY);
- if(si->StdIn < 0)
- {
- return 0;
- }
+ sigset_t mask, old_mask;
+ int pgidPipe[2];
+ char tmp;
+ ssize_t readRes;
- /* Set close-on-exec flag on the pipe's end. */
- if(fcntl(si->StdIn, F_SETFD, FD_CLOEXEC) < 0)
- {
- return 0;
- }
- }
- else if(cp->PipeSharedSTDIN)
- {
- si->StdIn = 0;
- }
- else if(cp->PipeNativeSTDIN[0] >= 0)
- {
- si->StdIn = cp->PipeNativeSTDIN[0];
-
- /* Set close-on-exec flag on the pipe's ends. The read end will
- be dup2-ed into the stdin descriptor after the fork but before
- the exec. */
- if((fcntl(cp->PipeNativeSTDIN[0], F_SETFD, FD_CLOEXEC) < 0) ||
- (fcntl(cp->PipeNativeSTDIN[1], F_SETFD, FD_CLOEXEC) < 0))
- {
- return 0;
- }
- }
- else
- {
- si->StdIn = -1;
- }
-
- /* Setup the process's stdout. */
- {
- /* Create the pipe. */
- int p[2];
- if(pipe(p KWSYSPE_VMS_NONBLOCK) < 0)
+ /* Create the error reporting pipe. */
+ if(pipe(si->ErrorPipe) < 0)
{
return 0;
}
- *readEnd = p[0];
- si->StdOut = p[1];
- /* Set close-on-exec flag on the pipe's ends. */
- if((fcntl(p[0], F_SETFD, FD_CLOEXEC) < 0) ||
- (fcntl(p[1], F_SETFD, FD_CLOEXEC) < 0))
+ /* Create a pipe for detecting that the child process has created a process
+ group and session. */
+ if(pipe(pgidPipe) < 0)
{
+ kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
+ kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
return 0;
}
- }
- /* Replace the stdout pipe with a file if requested. In this case
- the select call will report that stdout is closed immediately. */
- if(prIndex == cp->NumberOfCommands-1 && cp->PipeFileSTDOUT)
- {
- if(!kwsysProcessSetupOutputPipeFile(&si->StdOut, cp->PipeFileSTDOUT))
- {
- return 0;
- }
- }
-
- /* Replace the stdout pipe with the parent's if requested. In this
- case the select call will report that stderr is closed
- immediately. */
- if(prIndex == cp->NumberOfCommands-1 && cp->PipeSharedSTDOUT)
- {
- kwsysProcessCleanupDescriptor(&si->StdOut);
- si->StdOut = 1;
- }
-
- /* Replace the stdout pipe with the native pipe provided if any. In
- this case the select call will report that stdout is closed
- immediately. */
- if(prIndex == cp->NumberOfCommands-1 && cp->PipeNativeSTDOUT[1] >= 0)
- {
- if(!kwsysProcessSetupOutputPipeNative(&si->StdOut, cp->PipeNativeSTDOUT))
- {
- return 0;
- }
- }
-
- /* Create the error reporting pipe. */
- if(pipe(si->ErrorPipe) < 0)
+ /* Set close-on-exec flag on the pipe's write end. */
+ if(fcntl(si->ErrorPipe[1], F_SETFD, FD_CLOEXEC) < 0 ||
+ fcntl(pgidPipe[1], F_SETFD, FD_CLOEXEC) < 0)
{
+ kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
+ kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
+ kwsysProcessCleanupDescriptor(&pgidPipe[0]);
+ kwsysProcessCleanupDescriptor(&pgidPipe[1]);
return 0;
}
- /* Set close-on-exec flag on the error pipe's write end. */
- if(fcntl(si->ErrorPipe[1], F_SETFD, FD_CLOEXEC) < 0)
+ /* Block SIGINT / SIGTERM while we start. The purpose is so that our signal
+ handler doesn't get called from the child process after the fork and
+ before the exec, and subsequently start kill()'ing PIDs from ForkPIDs. */
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGINT);
+ sigaddset(&mask, SIGTERM);
+ if(sigprocmask(SIG_BLOCK, &mask, &old_mask) < 0)
{
+ kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
+ kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
+ kwsysProcessCleanupDescriptor(&pgidPipe[0]);
+ kwsysProcessCleanupDescriptor(&pgidPipe[1]);
return 0;
}
@@ -1723,13 +1881,19 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
#if defined(__VMS)
/* VMS needs vfork and execvp to be in the same function because
they use setjmp/longjmp to run the child startup code in the
- parent! TODO: OptionDetach. */
+ parent! TODO: OptionDetach. Also
+ TODO: CreateProcessGroup. */
cp->ForkPIDs[prIndex] = vfork();
#else
cp->ForkPIDs[prIndex] = kwsysProcessFork(cp, si);
#endif
if(cp->ForkPIDs[prIndex] < 0)
{
+ sigprocmask(SIG_SETMASK, &old_mask, 0);
+ kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
+ kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
+ kwsysProcessCleanupDescriptor(&pgidPipe[0]);
+ kwsysProcessCleanupDescriptor(&pgidPipe[1]);
return 0;
}
@@ -1739,8 +1903,10 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
/* Specify standard pipes for child process. */
decc$set_child_standard_streams(si->StdIn, si->StdOut, si->StdErr);
#else
- /* Close the read end of the error reporting pipe. */
+ /* Close the read end of the error reporting / process group
+ setup pipe. */
close(si->ErrorPipe[0]);
+ close(pgidPipe[0]);
/* Setup the stdin, stdout, and stderr pipes. */
if(si->StdIn > 0)
@@ -1768,11 +1934,25 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
/* Restore all default signal handlers. */
kwsysProcessRestoreDefaultSignalHandlers();
+
+ /* Now that we have restored default signal handling and created the
+ process group, restore mask. */
+ sigprocmask(SIG_SETMASK, &old_mask, 0);
+
+ /* Create new process group. We use setsid instead of setpgid to avoid
+ the child getting hung up on signals like SIGTTOU. (In the real world,
+ this has been observed where "git svn" ends up calling the "resize"
+ program which opens /dev/tty. */
+ if(cp->CreateProcessGroup && setsid() < 0)
+ {
+ kwsysProcessChildErrorExit(si->ErrorPipe[1]);
+ }
#endif
/* Execute the real process. If successful, this does not return. */
execvp(cp->Commands[prIndex][0], cp->Commands[prIndex]);
/* TODO: What does VMS do if the child fails to start? */
+ /* TODO: On VMS, how do we put the process in a new group? */
/* Failure. Report error to parent and terminate. */
kwsysProcessChildErrorExit(si->ErrorPipe[1]);
@@ -1783,12 +1963,34 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
decc$set_child_standard_streams(0, 1, 2);
#endif
+ /* We are done with the error reporting pipe and process group setup pipe
+ write end. */
+ kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
+ kwsysProcessCleanupDescriptor(&pgidPipe[1]);
+
+ /* Make sure the child is in the process group before we proceed. This
+ avoids race conditions with calls to the kill function that we make for
+ signalling process groups. */
+ while((readRes = read(pgidPipe[0], &tmp, 1)) > 0);
+ if(readRes < 0)
+ {
+ sigprocmask(SIG_SETMASK, &old_mask, 0);
+ kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
+ kwsysProcessCleanupDescriptor(&pgidPipe[0]);
+ return 0;
+ }
+ kwsysProcessCleanupDescriptor(&pgidPipe[0]);
+
+ /* Unmask signals. */
+ if(sigprocmask(SIG_SETMASK, &old_mask, 0) < 0)
+ {
+ kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
+ return 0;
+ }
+
/* A child has been created. */
++cp->CommandsLeft;
- /* We are done with the error reporting pipe write end. */
- kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
-
/* Block until the child's exec call succeeds and closes the error
pipe or writes data to the pipe to report an error. */
{
@@ -1817,19 +2019,6 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
}
}
- /* Successfully created this child process. */
- if(prIndex > 0 || si->StdIn > 0)
- {
- /* The parent process does not need the input pipe read end. */
- kwsysProcessCleanupDescriptor(&si->StdIn);
- }
-
- /* The parent process does not need the output pipe write ends. */
- if(si->StdOut != 1)
- {
- kwsysProcessCleanupDescriptor(&si->StdOut);
- }
-
return 1;
}
@@ -1839,6 +2028,17 @@ static void kwsysProcessDestroy(kwsysProcess* cp)
/* A child process has terminated. Reap it if it is one handled by
this object. */
int i;
+ /* Temporarily disable signals that access ForkPIDs. We don't want them to
+ read a reaped PID, and writes to ForkPIDs are not atomic. */
+ sigset_t mask, old_mask;
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGINT);
+ sigaddset(&mask, SIGTERM);
+ if(sigprocmask(SIG_BLOCK, &mask, &old_mask) < 0)
+ {
+ return;
+ }
+
for(i=0; i < cp->NumberOfCommands; ++i)
{
if(cp->ForkPIDs[i])
@@ -1872,6 +2072,9 @@ static void kwsysProcessDestroy(kwsysProcess* cp)
}
}
}
+
+ /* Re-enable signals. */
+ sigprocmask(SIG_SETMASK, &old_mask, 0);
}
/*--------------------------------------------------------------------------*/
@@ -1900,7 +2103,7 @@ static int kwsysProcessSetupOutputPipeFile(int* p, const char* name)
/* Assign the replacement descriptor. */
*p = fout;
- return 1;
+ return 1;
}
/*--------------------------------------------------------------------------*/
@@ -2038,7 +2241,7 @@ static kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, kwsysProcessTi
kwsysProcessTime out;
out.tv_sec = in1.tv_sec + in2.tv_sec;
out.tv_usec = in1.tv_usec + in2.tv_usec;
- if(out.tv_usec > 1000000)
+ if(out.tv_usec >= 1000000)
{
out.tv_usec -= 1000000;
out.tv_sec += 1;
@@ -2413,6 +2616,12 @@ static void kwsysProcessKill(pid_t process_id)
/* Suspend the process to be sure it will not create more children. */
kill(process_id, SIGSTOP);
+#if defined(__CYGWIN__)
+ /* Some Cygwin versions seem to need help here. Give up our time slice
+ so that the child can process SIGSTOP before we send SIGKILL. */
+ usleep(1);
+#endif
+
/* Kill all children if we can find them. */
#if defined(__linux__) || defined(__CYGWIN__)
/* First try using the /proc filesystem. */
@@ -2449,6 +2658,7 @@ static void kwsysProcessKill(pid_t process_id)
if(f)
{
size_t nread = fread(buffer, 1, KWSYSPE_PIPE_BUFFER_SIZE, f);
+ fclose(f);
buffer[nread] = '\0';
if(nread > 0)
{
@@ -2463,7 +2673,6 @@ static void kwsysProcessKill(pid_t process_id)
}
}
}
- fclose(f);
}
}
}
@@ -2538,19 +2747,23 @@ typedef struct kwsysProcessInstances_s
} kwsysProcessInstances;
static kwsysProcessInstances kwsysProcesses;
-/* The old SIGCHLD handler. */
+/* The old SIGCHLD / SIGINT / SIGTERM handlers. */
static struct sigaction kwsysProcessesOldSigChldAction;
+static struct sigaction kwsysProcessesOldSigIntAction;
+static struct sigaction kwsysProcessesOldSigTermAction;
/*--------------------------------------------------------------------------*/
static void kwsysProcessesUpdate(kwsysProcessInstances* newProcesses)
{
- /* Block SIGCHLD while we update the set of pipes to check.
+ /* Block signals while we update the set of pipes to check.
TODO: sigprocmask is undefined for threaded apps. See
pthread_sigmask. */
sigset_t newset;
sigset_t oldset;
sigemptyset(&newset);
sigaddset(&newset, SIGCHLD);
+ sigaddset(&newset, SIGINT);
+ sigaddset(&newset, SIGTERM);
sigprocmask(SIG_BLOCK, &newset, &oldset);
/* Store the new set in that seen by the signal handler. */
@@ -2642,21 +2855,36 @@ static int kwsysProcessesAdd(kwsysProcess* cp)
{
/* Install our handler for SIGCHLD. Repeat call until it is not
interrupted. */
- struct sigaction newSigChldAction;
- memset(&newSigChldAction, 0, sizeof(struct sigaction));
+ struct sigaction newSigAction;
+ memset(&newSigAction, 0, sizeof(struct sigaction));
#if KWSYSPE_USE_SIGINFO
- newSigChldAction.sa_sigaction = kwsysProcessesSignalHandler;
- newSigChldAction.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
+ newSigAction.sa_sigaction = kwsysProcessesSignalHandler;
+ newSigAction.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
# ifdef SA_RESTART
- newSigChldAction.sa_flags |= SA_RESTART;
+ newSigAction.sa_flags |= SA_RESTART;
# endif
#else
- newSigChldAction.sa_handler = kwsysProcessesSignalHandler;
- newSigChldAction.sa_flags = SA_NOCLDSTOP;
+ newSigAction.sa_handler = kwsysProcessesSignalHandler;
+ newSigAction.sa_flags = SA_NOCLDSTOP;
#endif
- while((sigaction(SIGCHLD, &newSigChldAction,
+ sigemptyset(&newSigAction.sa_mask);
+ while((sigaction(SIGCHLD, &newSigAction,
&kwsysProcessesOldSigChldAction) < 0) &&
(errno == EINTR));
+
+ /* Install our handler for SIGINT / SIGTERM. Repeat call until
+ it is not interrupted. */
+ sigemptyset(&newSigAction.sa_mask);
+ sigaddset(&newSigAction.sa_mask, SIGTERM);
+ while((sigaction(SIGINT, &newSigAction,
+ &kwsysProcessesOldSigIntAction) < 0) &&
+ (errno == EINTR));
+
+ sigemptyset(&newSigAction.sa_mask);
+ sigaddset(&newSigAction.sa_mask, SIGINT);
+ while((sigaction(SIGTERM, &newSigAction,
+ &kwsysProcessesOldSigIntAction) < 0) &&
+ (errno == EINTR));
}
}
@@ -2690,10 +2918,14 @@ static void kwsysProcessesRemove(kwsysProcess* cp)
/* If this was the last process, disable the signal handler. */
if(newProcesses.Count == 0)
{
- /* Restore the SIGCHLD handler. Repeat call until it is not
+ /* Restore the signal handlers. Repeat call until it is not
interrupted. */
while((sigaction(SIGCHLD, &kwsysProcessesOldSigChldAction, 0) < 0) &&
(errno == EINTR));
+ while((sigaction(SIGINT, &kwsysProcessesOldSigIntAction, 0) < 0) &&
+ (errno == EINTR));
+ while((sigaction(SIGTERM, &kwsysProcessesOldSigTermAction, 0) < 0) &&
+ (errno == EINTR));
/* Free the table of process pointers since it is now empty.
This is safe because the signal handler has been removed. */
@@ -2719,39 +2951,108 @@ static void kwsysProcessesSignalHandler(int signum
#endif
)
{
- (void)signum;
+ int i, j, procStatus, old_errno = errno;
#if KWSYSPE_USE_SIGINFO
(void)info;
(void)ucontext;
#endif
/* Signal all process objects that a child has terminated. */
- {
- int i;
- for(i=0; i < kwsysProcesses.Count; ++i)
+ switch(signum)
{
- /* Set the pipe in a signalled state. */
- char buf = 1;
- kwsysProcess* cp = kwsysProcesses.Processes[i];
- kwsysProcess_ssize_t status=
- read(cp->PipeReadEnds[KWSYSPE_PIPE_SIGNAL], &buf, 1);
- (void)status;
- status=write(cp->SignalPipe, &buf, 1);
- (void)status;
+ case SIGCHLD:
+ for(i=0; i < kwsysProcesses.Count; ++i)
+ {
+ /* Set the pipe in a signalled state. */
+ char buf = 1;
+ kwsysProcess* cp = kwsysProcesses.Processes[i];
+ kwsysProcess_ssize_t pipeStatus=
+ read(cp->PipeReadEnds[KWSYSPE_PIPE_SIGNAL], &buf, 1);
+ (void)pipeStatus;
+ pipeStatus=write(cp->SignalPipe, &buf, 1);
+ (void)pipeStatus;
+ }
+ break;
+ case SIGINT:
+ case SIGTERM:
+ /* Signal child processes that are running in new process groups. */
+ for(i=0; i < kwsysProcesses.Count; ++i)
+ {
+ kwsysProcess* cp = kwsysProcesses.Processes[i];
+ /* Check Killed to avoid data race condition when killing.
+ Check State to avoid data race condition in kwsysProcessCleanup
+ when there is an error (it leaves a reaped PID). */
+ if(cp->CreateProcessGroup && !cp->Killed &&
+ cp->State != kwsysProcess_State_Error && cp->ForkPIDs)
+ {
+ for(j=0; j < cp->NumberOfCommands; ++j)
+ {
+ /* Make sure the PID is still valid. */
+ if(cp->ForkPIDs[j])
+ {
+ /* The user created a process group for this process. The group ID
+ is the process ID for the original process in the group. */
+ kill(-cp->ForkPIDs[j], SIGINT);
+ }
+ }
+ }
+ }
+
+ /* Wait for all processes to terminate. */
+ while(wait(&procStatus) >= 0 || errno != ECHILD)
+ {
+ }
+
+ /* Terminate the process, which is now in an inconsistent state
+ because we reaped all the PIDs that it may have been reaping
+ or may have reaped in the future. Reraise the signal so that
+ the proper exit code is returned. */
+ {
+ /* Install default signal handler. */
+ struct sigaction defSigAction;
+ sigset_t unblockSet;
+ memset(&defSigAction, 0, sizeof(defSigAction));
+ defSigAction.sa_handler = SIG_DFL;
+ sigemptyset(&defSigAction.sa_mask);
+ while((sigaction(signum, &defSigAction, 0) < 0) &&
+ (errno == EINTR));
+ /* Unmask the signal. */
+ sigemptyset(&unblockSet);
+ sigaddset(&unblockSet, signum);
+ sigprocmask(SIG_UNBLOCK, &unblockSet, 0);
+ /* Raise the signal again. */
+ raise(signum);
+ /* We shouldn't get here... but if we do... */
+ _exit(1);
+ }
+ /* break omitted to silence unreachable code clang compiler warning. */
}
- }
#if !KWSYSPE_USE_SIGINFO
- /* Re-Install our handler for SIGCHLD. Repeat call until it is not
- interrupted. */
+ /* Re-Install our handler. Repeat call until it is not interrupted. */
{
- struct sigaction newSigChldAction;
- memset(&newSigChldAction, 0, sizeof(struct sigaction));
+ struct sigaction newSigAction;
+ struct sigaction &oldSigAction;
+ memset(&newSigAction, 0, sizeof(struct sigaction));
newSigChldAction.sa_handler = kwsysProcessesSignalHandler;
newSigChldAction.sa_flags = SA_NOCLDSTOP;
- while((sigaction(SIGCHLD, &newSigChldAction,
- &kwsysProcessesOldSigChldAction) < 0) &&
+ sigemptyset(&newSigAction.sa_mask);
+ switch(signum)
+ {
+ case SIGCHLD: oldSigAction = &kwsysProcessesOldSigChldAction; break;
+ case SIGINT:
+ sigaddset(&newSigAction.sa_mask, SIGTERM);
+ oldSigAction = &kwsysProcessesOldSigIntAction; break;
+ case SIGTERM:
+ sigaddset(&newSigAction.sa_mask, SIGINT);
+ oldSigAction = &kwsysProcessesOldSigTermAction; break;
+ default: return 0;
+ }
+ while((sigaction(signum, &newSigAction,
+ oldSigAction) < 0) &&
(errno == EINTR));
}
#endif
+
+ errno = old_errno;
}
diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c
index c836f9b08..1f8749fbe 100644
--- a/Source/kwsys/ProcessWin32.c
+++ b/Source/kwsys/ProcessWin32.c
@@ -11,13 +11,13 @@
============================================================================*/
#include "kwsysPrivate.h"
#include KWSYS_HEADER(Process.h)
-#include KWSYS_HEADER(System.h)
+#include KWSYS_HEADER(Encoding.h)
/* Work-around CMake dependency scanning limitation. This must
duplicate the above list of headers. */
#if 0
# include "Process.h.in"
-# include "System.h.in"
+# include "Encoding_c.h.in"
#endif
/*
@@ -34,6 +34,9 @@ a UNIX-style select system call.
#pragma warning (push, 1)
#endif
#include <windows.h> /* Windows API */
+#if defined(_MSC_VER) && _MSC_VER >= 1800
+# define KWSYS_WINDOWS_DEPRECATED_GetVersionEx
+#endif
#include <string.h> /* strlen, strdup */
#include <stdio.h> /* sprintf */
#include <io.h> /* _unlink */
@@ -88,9 +91,15 @@ typedef LARGE_INTEGER kwsysProcessTime;
typedef struct kwsysProcessCreateInformation_s
{
/* Windows child startup control data. */
- STARTUPINFO StartupInfo;
+ STARTUPINFOW StartupInfo;
+
+ /* Original handles before making inherited duplicates. */
+ HANDLE hStdInput;
+ HANDLE hStdOutput;
+ HANDLE hStdError;
} kwsysProcessCreateInformation;
+
/*--------------------------------------------------------------------------*/
typedef struct kwsysProcessPipeData_s kwsysProcessPipeData;
static DWORD WINAPI kwsysProcessPipeThreadRead(LPVOID ptd);
@@ -100,23 +109,16 @@ static DWORD WINAPI kwsysProcessPipeThreadWake(LPVOID ptd);
static void kwsysProcessPipeThreadWakePipe(kwsysProcess* cp,
kwsysProcessPipeData* td);
static int kwsysProcessInitialize(kwsysProcess* cp);
-static int kwsysProcessCreate(kwsysProcess* cp, int index,
- kwsysProcessCreateInformation* si,
- PHANDLE readEnd);
+static DWORD kwsysProcessCreate(kwsysProcess* cp, int index,
+ kwsysProcessCreateInformation* si);
static void kwsysProcessDestroy(kwsysProcess* cp, int event);
-static int kwsysProcessSetupOutputPipeFile(PHANDLE handle, const char* name);
-static int kwsysProcessSetupSharedPipe(DWORD nStdHandle, PHANDLE handle);
-static int kwsysProcessSetupPipeNative(PHANDLE handle, HANDLE p[2],
- int isWrite);
+static DWORD kwsysProcessSetupOutputPipeFile(PHANDLE handle,
+ const char* name);
+static void kwsysProcessSetupSharedPipe(DWORD nStdHandle, PHANDLE handle);
+static void kwsysProcessSetupPipeNative(HANDLE native, PHANDLE handle);
static void kwsysProcessCleanupHandle(PHANDLE h);
-static void kwsysProcessCleanupHandleSafe(PHANDLE h, DWORD nStdHandle);
-static void kwsysProcessCleanup(kwsysProcess* cp, int error);
+static void kwsysProcessCleanup(kwsysProcess* cp, DWORD error);
static void kwsysProcessCleanErrorMessage(kwsysProcess* cp);
-static int kwsysProcessComputeCommandLength(kwsysProcess* cp,
- char const* const* command);
-static void kwsysProcessComputeCommandLine(kwsysProcess* cp,
- char const* const* command,
- char* cmd);
static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
kwsysProcessTime* timeoutTime);
static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime,
@@ -132,6 +134,13 @@ static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProc
static void kwsysProcessSetExitException(kwsysProcess* cp, int code);
static void kwsysProcessKillTree(int pid);
static void kwsysProcessDisablePipeThreads(kwsysProcess* cp);
+static int kwsysProcessesInitialize(void);
+static int kwsysTryEnterCreateProcessSection(void);
+static void kwsysLeaveCreateProcessSection(void);
+static int kwsysProcessesAdd(HANDLE hProcess, DWORD dwProcessId,
+ int newProcessGroup);
+static void kwsysProcessesRemove(HANDLE hProcess);
+static BOOL WINAPI kwsysCtrlHandler(DWORD dwCtrlType);
/*--------------------------------------------------------------------------*/
/* A structure containing synchronization data for each thread. */
@@ -197,14 +206,14 @@ struct kwsysProcess_s
int State;
/* The command lines to execute. */
- char** Commands;
+ wchar_t** Commands;
int NumberOfCommands;
/* The exit code of each command. */
DWORD* CommandExitCodes;
/* The working directory for the child process. */
- char* WorkingDirectory;
+ wchar_t* WorkingDirectory;
/* Whether to create the child as a detached process. */
int OptionDetach;
@@ -218,6 +227,12 @@ struct kwsysProcess_s
/* Whether to treat command lines as verbatim. */
int Verbatim;
+ /* Whether to merge stdout/stderr of the child. */
+ int MergeOutput;
+
+ /* Whether to create the process in a new process group. */
+ int CreateProcessGroup;
+
/* Mutex to protect the shared index used by threads to report data. */
HANDLE SharedIndexMutex;
@@ -299,7 +314,11 @@ struct kwsysProcess_s
/* Real working directory of our own process. */
DWORD RealWorkingDirectoryLength;
- char* RealWorkingDirectory;
+ wchar_t* RealWorkingDirectory;
+
+ /* Own handles for the child's ends of the pipes in the parent process.
+ Used temporarily during process creation. */
+ HANDLE PipeChildStd[3];
};
/*--------------------------------------------------------------------------*/
@@ -313,6 +332,16 @@ kwsysProcess* kwsysProcess_New(void)
/* Windows version number data. */
OSVERSIONINFO osv;
+ /* Initialize list of processes before we get any farther. It's especially
+ important that the console Ctrl handler be added BEFORE starting the
+ first process. This prevents the risk of an orphaned process being
+ started by the main thread while the default Ctrl handler is in
+ progress. */
+ if(!kwsysProcessesInitialize())
+ {
+ return 0;
+ }
+
/* Allocate a process control structure. */
cp = (kwsysProcess*)malloc(sizeof(kwsysProcess));
if(!cp)
@@ -332,7 +361,18 @@ kwsysProcess* kwsysProcess_New(void)
windows. */
ZeroMemory(&osv, sizeof(osv));
osv.dwOSVersionInfoSize = sizeof(osv);
+#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
+# pragma warning (push)
+# ifdef __INTEL_COMPILER
+# pragma warning (disable:1478)
+# else
+# pragma warning (disable:4996)
+# endif
+#endif
GetVersionEx(&osv);
+#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
+# pragma warning (pop)
+#endif
if(osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
{
/* Win9x no longer supported. */
@@ -429,6 +469,10 @@ kwsysProcess* kwsysProcess_New(void)
return 0;
}
}
+ for(i=0; i < 3; ++i)
+ {
+ cp->PipeChildStd[i] = INVALID_HANDLE_VALUE;
+ }
return cp;
}
@@ -546,7 +590,7 @@ int kwsysProcess_SetCommand(kwsysProcess* cp, char const* const* command)
int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
{
int newNumberOfCommands;
- char** newCommands;
+ wchar_t** newCommands;
/* Make sure we have a command to add. */
if(!cp || !command || !*command)
@@ -554,9 +598,10 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
return 0;
}
+
/* Allocate a new array for command pointers. */
newNumberOfCommands = cp->NumberOfCommands + 1;
- if(!(newCommands = (char**)malloc(sizeof(char*) * newNumberOfCommands)))
+ if(!(newCommands = (wchar_t**)malloc(sizeof(wchar_t*) * newNumberOfCommands)))
{
/* Out of memory. */
return 0;
@@ -571,33 +616,69 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
}
}
- /* We need to construct a single string representing the command
- and its arguments. We will surround each argument containing
- spaces with double-quotes. Inside a double-quoted argument, we
- need to escape double-quotes and all backslashes before them.
- We also need to escape backslashes at the end of an argument
- because they come before the closing double-quote for the
- argument. */
- {
- /* First determine the length of the final string. */
- int length = kwsysProcessComputeCommandLength(cp, command);
-
- /* Allocate enough space for the command. We do not need an extra
- byte for the terminating null because we allocated a space for
- the first argument that we will not use. */
- newCommands[cp->NumberOfCommands] = (char*)malloc(length);
- if(!newCommands[cp->NumberOfCommands])
+ if (cp->Verbatim)
{
- /* Out of memory. */
+ /* Copy the verbatim command line into the buffer. */
+ newCommands[cp->NumberOfCommands] = kwsysEncoding_DupToWide(*command);
+ }
+ else
+ {
+ /* Encode the arguments so CommandLineToArgvW can decode
+ them from the command line string in the child. */
+ char buffer[32768]; /* CreateProcess max command-line length. */
+ char* end = buffer + sizeof(buffer);
+ char* out = buffer;
+ char const* const* a;
+ for (a = command; *a; ++a)
+ {
+ int quote = !**a; /* Quote the empty string. */
+ int slashes = 0;
+ char const* c;
+ if (a != command && out != end) { *out++ = ' '; }
+ for (c = *a; !quote && *c; ++c)
+ { quote = (*c == ' ' || *c == '\t'); }
+ if (quote && out != end) { *out++ = '"'; }
+ for (c = *a; *c; ++c)
+ {
+ if (*c == '\\')
+ {
+ ++slashes;
+ }
+ else
+ {
+ if (*c == '"')
+ {
+ // Add n+1 backslashes to total 2n+1 before internal '"'.
+ while(slashes-- >= 0 && out != end) { *out++ = '\\'; }
+ }
+ slashes = 0;
+ }
+ if (out != end) { *out++ = *c; }
+ }
+ if (quote)
+ {
+ // Add n backslashes to total 2n before ending '"'.
+ while (slashes-- > 0 && out != end) { *out++ = '\\'; }
+ if (out != end) { *out++ = '"'; }
+ }
+ }
+ if(out != end)
+ {
+ *out = '\0';
+ newCommands[cp->NumberOfCommands] = kwsysEncoding_DupToWide(buffer);
+ }
+ else
+ {
+ newCommands[cp->NumberOfCommands] = 0;
+ }
+ }
+ if (!newCommands[cp->NumberOfCommands])
+ {
+ /* Out of memory or command line too long. */
free(newCommands);
return 0;
}
- /* Construct the command line in the allocated buffer. */
- kwsysProcessComputeCommandLine(cp, command,
- newCommands[cp->NumberOfCommands]);
- }
-
/* Save the new array of commands. */
free(cp->Commands);
cp->Commands = newCommands;
@@ -633,22 +714,26 @@ int kwsysProcess_SetWorkingDirectory(kwsysProcess* cp, const char* dir)
}
if(dir && dir[0])
{
+ wchar_t* wdir = kwsysEncoding_DupToWide(dir);
/* We must convert the working directory to a full path. */
- DWORD length = GetFullPathName(dir, 0, 0, 0);
+ DWORD length = GetFullPathNameW(wdir, 0, 0, 0);
if(length > 0)
{
- cp->WorkingDirectory = (char*)malloc(length);
- if(!cp->WorkingDirectory)
+ wchar_t* work_dir = malloc(length*sizeof(wchar_t));
+ if(!work_dir)
{
+ free(wdir);
return 0;
}
- if(!GetFullPathName(dir, length, cp->WorkingDirectory, 0))
+ if(!GetFullPathNameW(wdir, length, work_dir, 0))
{
- free(cp->WorkingDirectory);
- cp->WorkingDirectory = 0;
+ free(work_dir);
+ free(wdir);
return 0;
}
+ cp->WorkingDirectory = work_dir;
}
+ free(wdir);
}
return 1;
}
@@ -770,7 +855,10 @@ int kwsysProcess_GetOption(kwsysProcess* cp, int optionId)
{
case kwsysProcess_Option_Detach: return cp->OptionDetach;
case kwsysProcess_Option_HideWindow: return cp->HideWindow;
+ case kwsysProcess_Option_MergeOutput: return cp->MergeOutput;
case kwsysProcess_Option_Verbatim: return cp->Verbatim;
+ case kwsysProcess_Option_CreateProcessGroup:
+ return cp->CreateProcessGroup;
default: return 0;
}
}
@@ -787,7 +875,10 @@ void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, int value)
{
case kwsysProcess_Option_Detach: cp->OptionDetach = value; break;
case kwsysProcess_Option_HideWindow: cp->HideWindow = value; break;
+ case kwsysProcess_Option_MergeOutput: cp->MergeOutput = value; break;
case kwsysProcess_Option_Verbatim: cp->Verbatim = value; break;
+ case kwsysProcess_Option_CreateProcessGroup:
+ cp->CreateProcessGroup = value; break;
default: break;
}
}
@@ -849,9 +940,6 @@ void kwsysProcess_Execute(kwsysProcess* cp)
{
int i;
- /* Child startup control data. */
- kwsysProcessCreateInformation si;
-
/* Do not execute a second time. */
if(!cp || cp->State == kwsysProcess_State_Executing)
{
@@ -879,131 +967,230 @@ void kwsysProcess_Execute(kwsysProcess* cp)
to make pipe file paths evaluate correctly. */
if(cp->WorkingDirectory)
{
- if(!GetCurrentDirectory(cp->RealWorkingDirectoryLength,
+ if(!GetCurrentDirectoryW(cp->RealWorkingDirectoryLength,
cp->RealWorkingDirectory))
{
- kwsysProcessCleanup(cp, 1);
+ kwsysProcessCleanup(cp, GetLastError());
return;
}
- SetCurrentDirectory(cp->WorkingDirectory);
+ SetCurrentDirectoryW(cp->WorkingDirectory);
}
- /* Initialize startup info data. */
- ZeroMemory(&si, sizeof(si));
- si.StartupInfo.cb = sizeof(si.StartupInfo);
-
- /* Decide whether a child window should be shown. */
- si.StartupInfo.dwFlags |= STARTF_USESHOWWINDOW;
- si.StartupInfo.wShowWindow =
- (unsigned short)(cp->HideWindow?SW_HIDE:SW_SHOWDEFAULT);
-
- /* Connect the child's output pipes to the threads. */
- si.StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
- /* Create stderr pipe to be shared by all processes in the pipeline.
- Neither end is directly inherited. */
- if(!CreatePipe(&cp->Pipe[KWSYSPE_PIPE_STDERR].Read,
- &cp->Pipe[KWSYSPE_PIPE_STDERR].Write, 0, 0))
+ /* Setup the stdin pipe for the first process. */
+ if(cp->PipeFileSTDIN)
{
- kwsysProcessCleanup(cp, 1);
- return;
+ /* Create a handle to read a file for stdin. */
+ wchar_t* wstdin = kwsysEncoding_DupToWide(cp->PipeFileSTDIN);
+ DWORD error;
+ cp->PipeChildStd[0] =
+ CreateFileW(wstdin, GENERIC_READ|GENERIC_WRITE,
+ FILE_SHARE_READ|FILE_SHARE_WRITE,
+ 0, OPEN_EXISTING, 0, 0);
+ error = GetLastError(); /* Check now in case free changes this. */
+ free(wstdin);
+ if(cp->PipeChildStd[0] == INVALID_HANDLE_VALUE)
+ {
+ kwsysProcessCleanup(cp, error);
+ return;
+ }
+ }
+ else if(cp->PipeSharedSTDIN)
+ {
+ /* Share this process's stdin with the child. */
+ kwsysProcessSetupSharedPipe(STD_INPUT_HANDLE, &cp->PipeChildStd[0]);
+ }
+ else if(cp->PipeNativeSTDIN[0])
+ {
+ /* Use the provided native pipe. */
+ kwsysProcessSetupPipeNative(cp->PipeNativeSTDIN[0], &cp->PipeChildStd[0]);
+ }
+ else
+ {
+ /* Explicitly give the child no stdin. */
+ cp->PipeChildStd[0] = INVALID_HANDLE_VALUE;
}
- /* Create an inherited duplicate of the write end, but do not
- close the non-inherited version. We need to keep it open
- to use in waking up the pipe threads. */
- if(!DuplicateHandle(GetCurrentProcess(), cp->Pipe[KWSYSPE_PIPE_STDERR].Write,
- GetCurrentProcess(), &si.StartupInfo.hStdError,
- 0, TRUE, DUPLICATE_SAME_ACCESS))
+ /* Create the output pipe for the last process.
+ We always create this so the pipe thread can run even if we
+ do not end up giving the write end to the child below. */
+ if(!CreatePipe(&cp->Pipe[KWSYSPE_PIPE_STDOUT].Read,
+ &cp->Pipe[KWSYSPE_PIPE_STDOUT].Write, 0, 0))
{
- kwsysProcessCleanup(cp, 1);
- kwsysProcessCleanupHandle(&si.StartupInfo.hStdError);
+ kwsysProcessCleanup(cp, GetLastError());
return;
}
- /* Replace the stderr pipe with a file if requested. In this case
- the pipe thread will still run but never report data. */
- if(cp->PipeFileSTDERR)
+ if(cp->PipeFileSTDOUT)
{
- if(!kwsysProcessSetupOutputPipeFile(&si.StartupInfo.hStdError,
- cp->PipeFileSTDERR))
+ /* Use a file for stdout. */
+ DWORD error = kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[1],
+ cp->PipeFileSTDOUT);
+ if(error)
{
- kwsysProcessCleanup(cp, 1);
- kwsysProcessCleanupHandle(&si.StartupInfo.hStdError);
+ kwsysProcessCleanup(cp, error);
return;
}
}
-
- /* Replace the stderr pipe with the parent process's if requested.
- In this case the pipe thread will still run but never report
- data. */
- if(cp->PipeSharedSTDERR)
+ else if(cp->PipeSharedSTDOUT)
+ {
+ /* Use the parent stdout. */
+ kwsysProcessSetupSharedPipe(STD_OUTPUT_HANDLE, &cp->PipeChildStd[1]);
+ }
+ else if(cp->PipeNativeSTDOUT[1])
{
- if(!kwsysProcessSetupSharedPipe(STD_ERROR_HANDLE,
- &si.StartupInfo.hStdError))
+ /* Use the given handle for stdout. */
+ kwsysProcessSetupPipeNative(cp->PipeNativeSTDOUT[1], &cp->PipeChildStd[1]);
+ }
+ else
+ {
+ /* Use our pipe for stdout. Duplicate the handle since our waker
+ thread will use the original. Do not make it inherited yet. */
+ if(!DuplicateHandle(GetCurrentProcess(),
+ cp->Pipe[KWSYSPE_PIPE_STDOUT].Write,
+ GetCurrentProcess(), &cp->PipeChildStd[1],
+ 0, FALSE, DUPLICATE_SAME_ACCESS))
{
- kwsysProcessCleanup(cp, 1);
- kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdError,
- STD_ERROR_HANDLE);
+ kwsysProcessCleanup(cp, GetLastError());
return;
}
}
- /* Replace the stderr pipe with the native pipe provided if any. In
- this case the pipe thread will still run but never report
- data. */
- if(cp->PipeNativeSTDERR[1])
+ /* Create stderr pipe to be shared by all processes in the pipeline.
+ We always create this so the pipe thread can run even if we do not
+ end up giving the write end to the child below. */
+ if(!CreatePipe(&cp->Pipe[KWSYSPE_PIPE_STDERR].Read,
+ &cp->Pipe[KWSYSPE_PIPE_STDERR].Write, 0, 0))
{
- if(!kwsysProcessSetupPipeNative(&si.StartupInfo.hStdError,
- cp->PipeNativeSTDERR, 1))
+ kwsysProcessCleanup(cp, GetLastError());
+ return;
+ }
+
+ if(cp->PipeFileSTDERR)
+ {
+ /* Use a file for stderr. */
+ DWORD error = kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[2],
+ cp->PipeFileSTDERR);
+ if(error)
{
- kwsysProcessCleanup(cp, 1);
- kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdError,
- STD_ERROR_HANDLE);
+ kwsysProcessCleanup(cp, error);
+ return;
+ }
+ }
+ else if(cp->PipeSharedSTDERR)
+ {
+ /* Use the parent stderr. */
+ kwsysProcessSetupSharedPipe(STD_ERROR_HANDLE, &cp->PipeChildStd[2]);
+ }
+ else if(cp->PipeNativeSTDERR[1])
+ {
+ /* Use the given handle for stderr. */
+ kwsysProcessSetupPipeNative(cp->PipeNativeSTDERR[1], &cp->PipeChildStd[2]);
+ }
+ else
+ {
+ /* Use our pipe for stderr. Duplicate the handle since our waker
+ thread will use the original. Do not make it inherited yet. */
+ if(!DuplicateHandle(GetCurrentProcess(),
+ cp->Pipe[KWSYSPE_PIPE_STDERR].Write,
+ GetCurrentProcess(), &cp->PipeChildStd[2],
+ 0, FALSE, DUPLICATE_SAME_ACCESS))
+ {
+ kwsysProcessCleanup(cp, GetLastError());
return;
}
}
/* Create the pipeline of processes. */
{
- HANDLE readEnd = 0;
+ /* Child startup control data. */
+ kwsysProcessCreateInformation si;
+ HANDLE nextStdInput = cp->PipeChildStd[0];
+
+ /* Initialize startup info data. */
+ ZeroMemory(&si, sizeof(si));
+ si.StartupInfo.cb = sizeof(si.StartupInfo);
+
+ /* Decide whether a child window should be shown. */
+ si.StartupInfo.dwFlags |= STARTF_USESHOWWINDOW;
+ si.StartupInfo.wShowWindow =
+ (unsigned short)(cp->HideWindow?SW_HIDE:SW_SHOWDEFAULT);
+
+ /* Connect the child's output pipes to the threads. */
+ si.StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
+
for(i=0; i < cp->NumberOfCommands; ++i)
{
- if(kwsysProcessCreate(cp, i, &si, &readEnd))
+ /* Setup the process's pipes. */
+ si.hStdInput = nextStdInput;
+ if (i == cp->NumberOfCommands-1)
+ {
+ /* The last child gets the overall stdout. */
+ nextStdInput = INVALID_HANDLE_VALUE;
+ si.hStdOutput = cp->PipeChildStd[1];
+ }
+ else
+ {
+ /* Create a pipe to sit between the children. */
+ HANDLE p[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE};
+ if (!CreatePipe(&p[0], &p[1], 0, 0))
+ {
+ DWORD error = GetLastError();
+ if (nextStdInput != cp->PipeChildStd[0])
+ {
+ kwsysProcessCleanupHandle(&nextStdInput);
+ }
+ kwsysProcessCleanup(cp, error);
+ return;
+ }
+ nextStdInput = p[0];
+ si.hStdOutput = p[1];
+ }
+ si.hStdError = cp->MergeOutput? cp->PipeChildStd[1] : cp->PipeChildStd[2];
+
+ {
+ DWORD error = kwsysProcessCreate(cp, i, &si);
+
+ /* Close our copies of pipes used between children. */
+ if (si.hStdInput != cp->PipeChildStd[0])
+ {
+ kwsysProcessCleanupHandle(&si.hStdInput);
+ }
+ if (si.hStdOutput != cp->PipeChildStd[1])
+ {
+ kwsysProcessCleanupHandle(&si.hStdOutput);
+ }
+ if (si.hStdError != cp->PipeChildStd[2] && !cp->MergeOutput)
+ {
+ kwsysProcessCleanupHandle(&si.hStdError);
+ }
+ if (!error)
{
cp->ProcessEvents[i+1] = cp->ProcessInformation[i].hProcess;
}
else
{
- kwsysProcessCleanup(cp, 1);
-
- /* Release resources that may have been allocated for this
- process before an error occurred. */
- kwsysProcessCleanupHandle(&readEnd);
- kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdInput,
- STD_INPUT_HANDLE);
- kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdOutput,
- STD_OUTPUT_HANDLE);
- kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdError,
- STD_ERROR_HANDLE);
+ if (nextStdInput != cp->PipeChildStd[0])
+ {
+ kwsysProcessCleanupHandle(&nextStdInput);
+ }
+ kwsysProcessCleanup(cp, error);
return;
}
}
-
- /* Save a handle to the output pipe for the last process. */
- cp->Pipe[KWSYSPE_PIPE_STDOUT].Read = readEnd;
+ }
}
- /* Close the inherited handles to the stderr pipe shared by all
- processes in the pipeline. The stdout and stdin pipes are not
- shared among all children and are therefore closed by
- kwsysProcessCreate after each child is created. */
- kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdError, STD_ERROR_HANDLE);
+ /* The parent process does not need the child's pipe ends. */
+ for (i=0; i < 3; ++i)
+ {
+ kwsysProcessCleanupHandle(&cp->PipeChildStd[i]);
+ }
/* Restore the working directory. */
if(cp->RealWorkingDirectory)
{
- SetCurrentDirectory(cp->RealWorkingDirectory);
+ SetCurrentDirectoryW(cp->RealWorkingDirectory);
free(cp->RealWorkingDirectory);
cp->RealWorkingDirectory = 0;
}
@@ -1303,6 +1490,52 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
}
/*--------------------------------------------------------------------------*/
+void kwsysProcess_Interrupt(kwsysProcess* cp)
+{
+ int i;
+ /* Make sure we are executing a process. */
+ if(!cp || cp->State != kwsysProcess_State_Executing || cp->TimeoutExpired ||
+ cp->Killed)
+ {
+ KWSYSPE_DEBUG((stderr, "interrupt: child not executing\n"));
+ return;
+ }
+
+ /* Skip actually interrupting the child if it has already terminated. */
+ if(cp->Terminated)
+ {
+ KWSYSPE_DEBUG((stderr, "interrupt: child already terminated\n"));
+ return;
+ }
+
+ /* Interrupt the children. */
+ if (cp->CreateProcessGroup)
+ {
+ if(cp->ProcessInformation)
+ {
+ for(i=0; i < cp->NumberOfCommands; ++i)
+ {
+ /* Make sure the process handle isn't closed (e.g. from disowning). */
+ if(cp->ProcessInformation[i].hProcess)
+ {
+ /* The user created a process group for this process. The group ID
+ is the process ID for the original process in the group. Note
+ that we have to use Ctrl+Break: Ctrl+C is not allowed for process
+ groups. */
+ GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,
+ cp->ProcessInformation[i].dwProcessId);
+ }
+ }
+ }
+ }
+ else
+ {
+ /* No process group was created. Kill our own process group... */
+ GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
void kwsysProcess_Kill(kwsysProcess* cp)
{
int i;
@@ -1330,7 +1563,8 @@ void kwsysProcess_Kill(kwsysProcess* cp)
for(i=0; i < cp->NumberOfCommands; ++i)
{
kwsysProcessKillTree(cp->ProcessInformation[i].dwProcessId);
- // close the handle if we kill it
+ /* Remove from global list of processes and close handles. */
+ kwsysProcessesRemove(cp->ProcessInformation[i].hProcess);
kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread);
kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hProcess);
}
@@ -1507,170 +1741,139 @@ int kwsysProcessInitialize(kwsysProcess* cp)
/* Allocate space to save the real working directory of this process. */
if(cp->WorkingDirectory)
{
- cp->RealWorkingDirectoryLength = GetCurrentDirectory(0, 0);
+ cp->RealWorkingDirectoryLength = GetCurrentDirectoryW(0, 0);
if(cp->RealWorkingDirectoryLength > 0)
{
- cp->RealWorkingDirectory = (char*)malloc(cp->RealWorkingDirectoryLength);
+ cp->RealWorkingDirectory = malloc(cp->RealWorkingDirectoryLength * sizeof(wchar_t));
if(!cp->RealWorkingDirectory)
{
return 0;
}
}
}
+ {
+ int i;
+ for (i=0; i < 3; ++i)
+ {
+ cp->PipeChildStd[i] = INVALID_HANDLE_VALUE;
+ }
+ }
return 1;
}
/*--------------------------------------------------------------------------*/
-int kwsysProcessCreate(kwsysProcess* cp, int index,
- kwsysProcessCreateInformation* si,
- PHANDLE readEnd)
+static DWORD kwsysProcessCreateChildHandle(PHANDLE out, HANDLE in, int isStdIn)
{
- /* Setup the process's stdin. */
- if(*readEnd)
- {
- /* Create an inherited duplicate of the read end from the output
- pipe of the previous process. This also closes the
- non-inherited version. */
- if(!DuplicateHandle(GetCurrentProcess(), *readEnd,
- GetCurrentProcess(), readEnd,
- 0, TRUE, (DUPLICATE_CLOSE_SOURCE |
- DUPLICATE_SAME_ACCESS)))
- {
- return 0;
- }
- si->StartupInfo.hStdInput = *readEnd;
+ DWORD flags;
- /* This function is done with this handle. */
- *readEnd = 0;
- }
- else if(cp->PipeFileSTDIN)
+ /* Check whether the handle is valid for this process. */
+ if (in != INVALID_HANDLE_VALUE && GetHandleInformation(in, &flags))
{
- /* Create a handle to read a file for stdin. */
- 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)
+ /* Use the handle as-is if it is already inherited. */
+ if (flags & HANDLE_FLAG_INHERIT)
{
- return 0;
+ *out = in;
+ return ERROR_SUCCESS;
}
- /* Create an inherited duplicate of the handle. This also closes
- the non-inherited version. */
- if(!DuplicateHandle(GetCurrentProcess(), fin,
- GetCurrentProcess(), &fin,
- 0, TRUE, (DUPLICATE_CLOSE_SOURCE |
- DUPLICATE_SAME_ACCESS)))
- {
- return 0;
- }
- si->StartupInfo.hStdInput = fin;
- }
- else if(cp->PipeSharedSTDIN)
- {
- /* Share this process's stdin with the child. */
- if(!kwsysProcessSetupSharedPipe(STD_INPUT_HANDLE,
- &si->StartupInfo.hStdInput))
+
+ /* Create an inherited copy of this handle. */
+ if (DuplicateHandle(GetCurrentProcess(), in, GetCurrentProcess(), out,
+ 0, TRUE, DUPLICATE_SAME_ACCESS))
{
- return 0;
+ return ERROR_SUCCESS;
}
- }
- else if(cp->PipeNativeSTDIN[0])
- {
- /* Use the provided native pipe. */
- if(!kwsysProcessSetupPipeNative(&si->StartupInfo.hStdInput,
- cp->PipeNativeSTDIN, 0))
+ else
{
- return 0;
+ return GetLastError();
}
}
else
{
- /* Explicitly give the child no stdin. */
- si->StartupInfo.hStdInput = INVALID_HANDLE_VALUE;
+ /* The given handle is not valid for this process. Some child
+ processes may break if they do not have a valid standard handle,
+ so open NUL to give to the child. */
+ SECURITY_ATTRIBUTES sa;
+ ZeroMemory(&sa, sizeof(sa));
+ sa.nLength = (DWORD)sizeof(sa);
+ sa.bInheritHandle = 1;
+ *out = CreateFileW(L"NUL",
+ (isStdIn ? GENERIC_READ :
+ (GENERIC_WRITE | FILE_READ_ATTRIBUTES)),
+ FILE_SHARE_READ|FILE_SHARE_WRITE,
+ &sa, OPEN_EXISTING, 0, 0);
+ return (*out != INVALID_HANDLE_VALUE) ? ERROR_SUCCESS : GetLastError();
}
+}
- /* Setup the process's stdout. */
- {
- DWORD maybeClose = DUPLICATE_CLOSE_SOURCE;
- HANDLE writeEnd;
+/*--------------------------------------------------------------------------*/
+DWORD kwsysProcessCreate(kwsysProcess* cp, int index,
+ kwsysProcessCreateInformation* si)
+{
+ DWORD creationFlags;
+ DWORD error = ERROR_SUCCESS;
- /* Create the output pipe for this process. Neither end is directly
- inherited. */
- if(!CreatePipe(readEnd, &writeEnd, 0, 0))
+ /* Check if we are currently exiting. */
+ if (!kwsysTryEnterCreateProcessSection())
{
- return 0;
+ /* The Ctrl handler is currently working on exiting our process. Rather
+ than return an error code, which could cause incorrect conclusions to be
+ reached by the caller, we simply hang. (For example, a CMake try_run
+ configure step might cause the project to configure wrong.) */
+ Sleep(INFINITE);
}
- /* Create an inherited duplicate of the write end. Close the
- non-inherited version unless this is the last process. Save the
- non-inherited write end of the last process. */
- if(index == cp->NumberOfCommands-1)
- {
- cp->Pipe[KWSYSPE_PIPE_STDOUT].Write = writeEnd;
- maybeClose = 0;
- }
- if(!DuplicateHandle(GetCurrentProcess(), writeEnd,
- GetCurrentProcess(), &writeEnd,
- 0, TRUE, (maybeClose | DUPLICATE_SAME_ACCESS)))
+ /* Create the child in a suspended state so we can wait until all
+ children have been created before running any one. */
+ creationFlags = CREATE_SUSPENDED;
+ if (cp->CreateProcessGroup)
{
- return 0;
+ creationFlags |= CREATE_NEW_PROCESS_GROUP;
}
- si->StartupInfo.hStdOutput = writeEnd;
- }
- /* Replace the stdout pipe with a file if requested. In this case
- the pipe thread will still run but never report data. */
- if(index == cp->NumberOfCommands-1 && cp->PipeFileSTDOUT)
+ /* Create inherited copies of the handles. */
+ (error = kwsysProcessCreateChildHandle(&si->StartupInfo.hStdInput,
+ si->hStdInput, 1)) ||
+ (error = kwsysProcessCreateChildHandle(&si->StartupInfo.hStdOutput,
+ si->hStdOutput, 0)) ||
+ (error = kwsysProcessCreateChildHandle(&si->StartupInfo.hStdError,
+ si->hStdError, 0)) ||
+ /* Create the process. */
+ (!CreateProcessW(0, cp->Commands[index], 0, 0, TRUE, creationFlags, 0,
+ 0, &si->StartupInfo, &cp->ProcessInformation[index]) &&
+ (error = GetLastError()));
+
+ /* Close the inherited copies of the handles. */
+ if (si->StartupInfo.hStdInput != si->hStdInput)
{
- if(!kwsysProcessSetupOutputPipeFile(&si->StartupInfo.hStdOutput,
- cp->PipeFileSTDOUT))
- {
- return 0;
- }
+ kwsysProcessCleanupHandle(&si->StartupInfo.hStdInput);
}
-
- /* Replace the stdout pipe of the last child with the parent
- process's if requested. In this case the pipe thread will still
- run but never report data. */
- if(index == cp->NumberOfCommands-1 && cp->PipeSharedSTDOUT)
+ if (si->StartupInfo.hStdOutput != si->hStdOutput)
{
- if(!kwsysProcessSetupSharedPipe(STD_OUTPUT_HANDLE,
- &si->StartupInfo.hStdOutput))
- {
- return 0;
- }
+ kwsysProcessCleanupHandle(&si->StartupInfo.hStdOutput);
}
-
- /* Replace the stdout pipe with the native pipe provided if any. In
- this case the pipe thread will still run but never report
- data. */
- if(index == cp->NumberOfCommands-1 && cp->PipeNativeSTDOUT[1])
+ if (si->StartupInfo.hStdError != si->hStdError)
{
- if(!kwsysProcessSetupPipeNative(&si->StartupInfo.hStdOutput,
- cp->PipeNativeSTDOUT, 1))
- {
- return 0;
- }
+ kwsysProcessCleanupHandle(&si->StartupInfo.hStdError);
}
- /* Create the child in a suspended state so we can wait until all
- children have been created before running any one. */
- if(!CreateProcess(0, cp->Commands[index], 0, 0, TRUE, CREATE_SUSPENDED, 0,
- 0, &si->StartupInfo, &cp->ProcessInformation[index]))
+ /* Add the process to the global list of processes. */
+ if (!error &&
+ !kwsysProcessesAdd(cp->ProcessInformation[index].hProcess,
+ cp->ProcessInformation[index].dwProcessId, cp->CreateProcessGroup))
{
- return 0;
+ /* This failed for some reason. Kill the suspended process. */
+ TerminateProcess(cp->ProcessInformation[index].hProcess, 1);
+ /* And clean up... */
+ kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hProcess);
+ kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hThread);
+ strcpy(cp->ErrorMessage, "kwsysProcessesAdd function failed");
+ error = ERROR_NOT_ENOUGH_MEMORY; /* Most likely reason. */
}
- /* Successfully created this child process. Close the current
- process's copies of the inherited stdout and stdin handles. The
- stderr handle is shared among all children and is closed by
- kwsysProcess_Execute after all children have been created. */
- kwsysProcessCleanupHandleSafe(&si->StartupInfo.hStdInput,
- STD_INPUT_HANDLE);
- kwsysProcessCleanupHandleSafe(&si->StartupInfo.hStdOutput,
- STD_OUTPUT_HANDLE);
-
- return 1;
+ /* If the console Ctrl handler is waiting for us, this will release it... */
+ kwsysLeaveCreateProcessSection();
+ return error;
}
/*--------------------------------------------------------------------------*/
@@ -1692,6 +1895,9 @@ void kwsysProcessDestroy(kwsysProcess* cp, int event)
GetExitCodeProcess(cp->ProcessInformation[index].hProcess,
&cp->CommandExitCodes[index]);
+ /* Remove from global list of processes. */
+ kwsysProcessesRemove(cp->ProcessInformation[index].hProcess);
+
/* Close the process handle for the terminated process. */
kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hProcess);
@@ -1726,122 +1932,51 @@ void kwsysProcessDestroy(kwsysProcess* cp, int event)
}
/*--------------------------------------------------------------------------*/
-int kwsysProcessSetupOutputPipeFile(PHANDLE phandle, const char* name)
+DWORD kwsysProcessSetupOutputPipeFile(PHANDLE phandle, const char* name)
{
HANDLE fout;
+ wchar_t* wname;
+ DWORD error;
if(!name)
{
- return 1;
+ return ERROR_INVALID_PARAMETER;
}
- /* Close the existing inherited handle. */
+ /* Close the existing handle. */
kwsysProcessCleanupHandle(phandle);
/* Create a handle to write a file for the pipe. */
- fout = CreateFile(name, GENERIC_WRITE, FILE_SHARE_READ, 0,
+ wname = kwsysEncoding_DupToWide(name);
+ fout = CreateFileW(wname, GENERIC_WRITE, FILE_SHARE_READ, 0,
CREATE_ALWAYS, 0, 0);
+ error = GetLastError();
+ free(wname);
if(fout == INVALID_HANDLE_VALUE)
{
- return 0;
- }
-
- /* Create an inherited duplicate of the handle. This also closes
- the non-inherited version. */
- if(!DuplicateHandle(GetCurrentProcess(), fout,
- GetCurrentProcess(), &fout,
- 0, TRUE, (DUPLICATE_CLOSE_SOURCE |
- DUPLICATE_SAME_ACCESS)))
- {
- return 0;
+ return error;
}
/* Assign the replacement handle. */
*phandle = fout;
- return 1;
+ return ERROR_SUCCESS;
}
/*--------------------------------------------------------------------------*/
-int kwsysProcessSetupSharedPipe(DWORD nStdHandle, PHANDLE handle)
+void kwsysProcessSetupSharedPipe(DWORD nStdHandle, PHANDLE handle)
{
- /* Check whether the handle to be shared is already inherited. */
- DWORD flags;
- int inherited = 0;
- if(GetHandleInformation(GetStdHandle(nStdHandle), &flags) &&
- (flags & HANDLE_FLAG_INHERIT))
- {
- inherited = 1;
- }
-
- /* Cleanup the previous handle. */
+ /* Close the existing handle. */
kwsysProcessCleanupHandle(handle);
-
- /* If the standard handle is not inherited then duplicate it to
- create an inherited copy. Do not close the original handle when
- duplicating! */
- if(inherited)
- {
- *handle = GetStdHandle(nStdHandle);
- return 1;
- }
- else if(DuplicateHandle(GetCurrentProcess(), GetStdHandle(nStdHandle),
- GetCurrentProcess(), handle,
- 0, TRUE, DUPLICATE_SAME_ACCESS))
- {
- return 1;
- }
- else
- {
- /* The given standard handle is not valid for this process. Some
- child processes may break if they do not have a valid standard
- pipe, so give the child an empty pipe. For the stdin pipe we
- want to close the write end and give the read end to the child.
- For stdout and stderr we want to close the read end and give
- the write end to the child. */
- int child_end = (nStdHandle == STD_INPUT_HANDLE)? 0:1;
- int parent_end = (nStdHandle == STD_INPUT_HANDLE)? 1:0;
- HANDLE emptyPipe[2];
- if(!CreatePipe(&emptyPipe[0], &emptyPipe[1], 0, 0))
- {
- return 0;
- }
-
- /* Close the non-inherited end so the pipe will be broken
- immediately. */
- CloseHandle(emptyPipe[parent_end]);
-
- /* Create an inherited duplicate of the handle. This also
- closes the non-inherited version. */
- if(!DuplicateHandle(GetCurrentProcess(), emptyPipe[child_end],
- GetCurrentProcess(), &emptyPipe[child_end],
- 0, TRUE, (DUPLICATE_CLOSE_SOURCE |
- DUPLICATE_SAME_ACCESS)))
- {
- return 0;
- }
-
- /* Give the inherited handle to the child. */
- *handle = emptyPipe[child_end];
- return 1;
- }
+ /* Store the new standard handle. */
+ *handle = GetStdHandle(nStdHandle);
}
/*--------------------------------------------------------------------------*/
-int kwsysProcessSetupPipeNative(PHANDLE handle, HANDLE p[2], int isWrite)
+void kwsysProcessSetupPipeNative(HANDLE native, PHANDLE handle)
{
- /* Close the existing inherited handle. */
+ /* Close the existing handle. */
kwsysProcessCleanupHandle(handle);
-
- /* Create an inherited duplicate of the handle. This also closes
- the non-inherited version. */
- if(!DuplicateHandle(GetCurrentProcess(), p[isWrite? 1:0],
- GetCurrentProcess(), handle,
- 0, TRUE, (DUPLICATE_CLOSE_SOURCE |
- DUPLICATE_SAME_ACCESS)))
- {
- return 0;
- }
-
- return 1;
+ /* Store the new given handle. */
+ *handle = native;
}
/*--------------------------------------------------------------------------*/
@@ -1849,30 +1984,20 @@ int kwsysProcessSetupPipeNative(PHANDLE handle, HANDLE p[2], int isWrite)
/* Close the given handle if it is open. Reset its value to 0. */
void kwsysProcessCleanupHandle(PHANDLE h)
{
- if(h && *h)
- {
- CloseHandle(*h);
- *h = 0;
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-/* Close the given handle if it is open and not a standard handle.
- Reset its value to 0. */
-void kwsysProcessCleanupHandleSafe(PHANDLE h, DWORD nStdHandle)
-{
- if(h && *h && (*h != GetStdHandle(nStdHandle)))
+ if(h && *h && *h != INVALID_HANDLE_VALUE &&
+ *h != GetStdHandle(STD_INPUT_HANDLE) &&
+ *h != GetStdHandle(STD_OUTPUT_HANDLE) &&
+ *h != GetStdHandle(STD_ERROR_HANDLE))
{
CloseHandle(*h);
- *h = 0;
+ *h = INVALID_HANDLE_VALUE;
}
}
/*--------------------------------------------------------------------------*/
/* Close all handles created by kwsysProcess_Execute. */
-void kwsysProcessCleanup(kwsysProcess* cp, int error)
+void kwsysProcessCleanup(kwsysProcess* cp, DWORD error)
{
int i;
/* If this is an error case, report the error. */
@@ -1882,18 +2007,27 @@ void kwsysProcessCleanup(kwsysProcess* cp, int error)
if(cp->ErrorMessage[0] == 0)
{
/* Format the error message. */
- DWORD original = GetLastError();
- DWORD length = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS, 0, original,
+ wchar_t err_msg[KWSYSPE_PIPE_BUFFER_SIZE];
+ DWORD length = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS, 0, error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- cp->ErrorMessage, KWSYSPE_PIPE_BUFFER_SIZE, 0);
+ err_msg, KWSYSPE_PIPE_BUFFER_SIZE, 0);
if(length < 1)
{
/* FormatMessage failed. Use a default message. */
_snprintf(cp->ErrorMessage, KWSYSPE_PIPE_BUFFER_SIZE,
"Process execution failed with error 0x%X. "
"FormatMessage failed with error 0x%X",
- original, GetLastError());
+ error, GetLastError());
+ }
+ if(!WideCharToMultiByte(CP_UTF8, 0, err_msg, -1, cp->ErrorMessage,
+ KWSYSPE_PIPE_BUFFER_SIZE, NULL, NULL))
+ {
+ /* WideCharToMultiByte failed. Use a default message. */
+ _snprintf(cp->ErrorMessage, KWSYSPE_PIPE_BUFFER_SIZE,
+ "Process execution failed with error 0x%X. "
+ "WideCharToMultiByte failed with error 0x%X",
+ error, GetLastError());
}
}
@@ -1916,6 +2050,8 @@ void kwsysProcessCleanup(kwsysProcess* cp, int error)
}
for(i=0; i < cp->NumberOfCommands; ++i)
{
+ /* Remove from global list of processes and close handles. */
+ kwsysProcessesRemove(cp->ProcessInformation[i].hProcess);
kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread);
kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hProcess);
}
@@ -1924,7 +2060,7 @@ void kwsysProcessCleanup(kwsysProcess* cp, int error)
/* Restore the working directory. */
if(cp->RealWorkingDirectory)
{
- SetCurrentDirectory(cp->RealWorkingDirectory);
+ SetCurrentDirectoryW(cp->RealWorkingDirectory);
}
}
@@ -1952,6 +2088,10 @@ void kwsysProcessCleanup(kwsysProcess* cp, int error)
kwsysProcessCleanupHandle(&cp->Pipe[i].Read);
cp->Pipe[i].Closed = 0;
}
+ for(i=0; i < 3; ++i)
+ {
+ kwsysProcessCleanupHandle(&cp->PipeChildStd[i]);
+ }
}
/*--------------------------------------------------------------------------*/
@@ -1976,66 +2116,6 @@ void kwsysProcessCleanErrorMessage(kwsysProcess* cp)
}
/*--------------------------------------------------------------------------*/
-int kwsysProcessComputeCommandLength(kwsysProcess* cp,
- char const* const* command)
-{
- int length = 0;
- if(cp->Verbatim)
- {
- /* Treat the first argument as a verbatim command line. Use its
- length directly and add space for the null-terminator. */
- length = (int)strlen(*command)+1;
- }
- else
- {
- /* Compute the length of the command line when it is converted to
- a single string. Space for the null-terminator is allocated by
- the whitespace character allocated for the first argument that
- will not be used. */
- char const* const* arg;
- for(arg = command; *arg; ++arg)
- {
- /* Add the length of this argument. It already includes room
- for a separating space or terminating null. */
- length += kwsysSystem_Shell_GetArgumentSizeForWindows(*arg, 0);
- }
- }
-
- return length;
-}
-
-/*--------------------------------------------------------------------------*/
-void kwsysProcessComputeCommandLine(kwsysProcess* cp,
- char const* const* command,
- char* cmd)
-{
- if(cp->Verbatim)
- {
- /* Copy the verbatim command line into the buffer. */
- strcpy(cmd, *command);
- }
- else
- {
- /* Construct the command line in the allocated buffer. */
- char const* const* arg;
- for(arg = command; *arg; ++arg)
- {
- /* Add the separating space if this is not the first argument. */
- if(arg != command)
- {
- *cmd++ = ' ';
- }
-
- /* Add the current argument. */
- cmd = kwsysSystem_Shell_GetArgumentForWindows(*arg, cmd, 0);
- }
-
- /* Add the terminating null character to the command line. */
- *cmd = 0;
- }
-}
-
-/*--------------------------------------------------------------------------*/
/* Get the time at which either the process or user timeout will
expire. Returns 1 if the user timeout is first, and 0 otherwise. */
int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
@@ -2222,7 +2302,7 @@ static void kwsysProcessSetExitException(kwsysProcess* cp, int code)
case STATUS_NO_MEMORY:
default:
cp->ExitException = kwsysProcess_Exception_Other;
- sprintf(cp->ExitExceptionString, "Exit code 0x%x\n", code);
+ _snprintf(cp->ExitExceptionString, KWSYSPE_PIPE_BUFFER_SIZE, "Exit code 0x%x\n", code);
break;
}
}
@@ -2350,7 +2430,18 @@ static kwsysProcess_List* kwsysProcess_List_New(void)
/* Select an implementation. */
ZeroMemory(&osv, sizeof(osv));
osv.dwOSVersionInfoSize = sizeof(osv);
+#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
+# pragma warning (push)
+# ifdef __INTEL_COMPILER
+# pragma warning (disable:1478)
+# else
+# pragma warning (disable:4996)
+# endif
+#endif
GetVersionEx(&osv);
+#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
+# pragma warning (pop)
+#endif
self->NT4 = (osv.dwPlatformId == VER_PLATFORM_WIN32_NT &&
osv.dwMajorVersion < 5)? 1:0;
@@ -2430,7 +2521,7 @@ static int kwsysProcess_List__New_NT4(kwsysProcess_List* self)
loaded in this program. This does not actually increment the
reference count to the module so we do not need to close the
handle. */
- HMODULE hNT = GetModuleHandle("ntdll.dll");
+ HMODULE hNT = GetModuleHandleW(L"ntdll.dll");
if(hNT)
{
/* Get pointers to the needed API functions. */
@@ -2534,7 +2625,7 @@ static int kwsysProcess_List__New_Snapshot(kwsysProcess_List* self)
loaded in this program. This does not actually increment the
reference count to the module so we do not need to close the
handle. */
- HMODULE hKernel = GetModuleHandle("kernel32.dll");
+ HMODULE hKernel = GetModuleHandleW(L"kernel32.dll");
if(hKernel)
{
self->P_CreateToolhelp32Snapshot =
@@ -2697,3 +2788,230 @@ static void kwsysProcessDisablePipeThreads(kwsysProcess* cp)
ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0);
}
}
+
+/*--------------------------------------------------------------------------*/
+/* Global set of executing processes for use by the Ctrl handler.
+ This global instance will be zero-initialized by the compiler.
+
+ Note that the console Ctrl handler runs on a background thread and so
+ everything it does must be thread safe. Here, we track the hProcess
+ HANDLEs directly instead of kwsysProcess instances, so that we don't have
+ to make kwsysProcess thread safe. */
+typedef struct kwsysProcessInstance_s
+{
+ HANDLE hProcess;
+ DWORD dwProcessId;
+ int NewProcessGroup; /* Whether the process was created in a new group. */
+} kwsysProcessInstance;
+
+typedef struct kwsysProcessInstances_s
+{
+ /* Whether we have initialized key fields below, like critical sections. */
+ int Initialized;
+
+ /* Ctrl handler runs on a different thread, so we must sync access. */
+ CRITICAL_SECTION Lock;
+
+ int Exiting;
+ size_t Count;
+ size_t Size;
+ kwsysProcessInstance* Processes;
+} kwsysProcessInstances;
+static kwsysProcessInstances kwsysProcesses;
+
+/*--------------------------------------------------------------------------*/
+/* Initialize critial section and set up console Ctrl handler. You MUST call
+ this before using any other kwsysProcesses* functions below. */
+static int kwsysProcessesInitialize(void)
+{
+ /* Initialize everything if not done already. */
+ if(!kwsysProcesses.Initialized)
+ {
+ InitializeCriticalSection(&kwsysProcesses.Lock);
+
+ /* Set up console ctrl handler. */
+ if(!SetConsoleCtrlHandler(kwsysCtrlHandler, TRUE))
+ {
+ return 0;
+ }
+
+ kwsysProcesses.Initialized = 1;
+ }
+ return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+/* The Ctrl handler waits on the global list of processes. To prevent an
+ orphaned process, do not create a new process if the Ctrl handler is
+ already running. Do so by using this function to check if it is ok to
+ create a process. */
+static int kwsysTryEnterCreateProcessSection(void)
+{
+ /* Enter main critical section; this means creating a process and the Ctrl
+ handler are mutually exclusive. */
+ EnterCriticalSection(&kwsysProcesses.Lock);
+ /* Indicate to the caller if they can create a process. */
+ if(kwsysProcesses.Exiting)
+ {
+ LeaveCriticalSection(&kwsysProcesses.Lock);
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+/* Matching function on successful kwsysTryEnterCreateProcessSection return.
+ Make sure you called kwsysProcessesAdd if applicable before calling this.*/
+static void kwsysLeaveCreateProcessSection(void)
+{
+ LeaveCriticalSection(&kwsysProcesses.Lock);
+}
+
+/*--------------------------------------------------------------------------*/
+/* Add new process to global process list. The Ctrl handler will wait for
+ the process to exit before it returns. Do not close the process handle
+ until after calling kwsysProcessesRemove. The newProcessGroup parameter
+ must be set if the process was created with CREATE_NEW_PROCESS_GROUP. */
+static int kwsysProcessesAdd(HANDLE hProcess, DWORD dwProcessid,
+ int newProcessGroup)
+{
+ if(!kwsysProcessesInitialize() || !hProcess ||
+ hProcess == INVALID_HANDLE_VALUE)
+ {
+ return 0;
+ }
+
+ /* Enter the critical section. */
+ EnterCriticalSection(&kwsysProcesses.Lock);
+
+ /* Make sure there is enough space for the new process handle. */
+ if(kwsysProcesses.Count == kwsysProcesses.Size)
+ {
+ size_t newSize;
+ kwsysProcessInstance *newArray;
+ /* Start with enough space for a small number of process handles
+ and double the size each time more is needed. */
+ newSize = kwsysProcesses.Size? kwsysProcesses.Size*2 : 4;
+
+ /* Try allocating the new block of memory. */
+ if(newArray = (kwsysProcessInstance*)malloc(
+ newSize*sizeof(kwsysProcessInstance)))
+ {
+ /* Copy the old process handles to the new memory. */
+ if(kwsysProcesses.Count > 0)
+ {
+ memcpy(newArray, kwsysProcesses.Processes,
+ kwsysProcesses.Count * sizeof(kwsysProcessInstance));
+ }
+ }
+ else
+ {
+ /* Failed to allocate memory for the new process handle set. */
+ LeaveCriticalSection(&kwsysProcesses.Lock);
+ return 0;
+ }
+
+ /* Free original array. */
+ free(kwsysProcesses.Processes);
+
+ /* Update original structure with new allocation. */
+ kwsysProcesses.Size = newSize;
+ kwsysProcesses.Processes = newArray;
+ }
+
+ /* Append the new process information to the set. */
+ kwsysProcesses.Processes[kwsysProcesses.Count].hProcess = hProcess;
+ kwsysProcesses.Processes[kwsysProcesses.Count].dwProcessId = dwProcessid;
+ kwsysProcesses.Processes[kwsysProcesses.Count++].NewProcessGroup =
+ newProcessGroup;
+
+ /* Leave critical section and return success. */
+ LeaveCriticalSection(&kwsysProcesses.Lock);
+
+ return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+/* Removes process to global process list. */
+static void kwsysProcessesRemove(HANDLE hProcess)
+{
+ size_t i;
+
+ if (!hProcess || hProcess == INVALID_HANDLE_VALUE)
+ {
+ return;
+ }
+
+ EnterCriticalSection(&kwsysProcesses.Lock);
+
+ /* Find the given process in the set. */
+ for(i=0; i < kwsysProcesses.Count; ++i)
+ {
+ if(kwsysProcesses.Processes[i].hProcess == hProcess)
+ {
+ break;
+ }
+ }
+ if(i < kwsysProcesses.Count)
+ {
+ /* Found it! Remove the process from the set. */
+ --kwsysProcesses.Count;
+ for(; i < kwsysProcesses.Count; ++i)
+ {
+ kwsysProcesses.Processes[i] = kwsysProcesses.Processes[i+1];
+ }
+
+ /* If this was the last process, free the array. */
+ if(kwsysProcesses.Count == 0)
+ {
+ kwsysProcesses.Size = 0;
+ free(kwsysProcesses.Processes);
+ kwsysProcesses.Processes = 0;
+ }
+ }
+
+ LeaveCriticalSection(&kwsysProcesses.Lock);
+}
+
+/*--------------------------------------------------------------------------*/
+static BOOL WINAPI kwsysCtrlHandler(DWORD dwCtrlType)
+{
+ size_t i;
+ (void)dwCtrlType;
+ /* Enter critical section. */
+ EnterCriticalSection(&kwsysProcesses.Lock);
+
+ /* Set flag indicating that we are exiting. */
+ kwsysProcesses.Exiting = 1;
+
+ /* If some of our processes were created in a new process group, we must
+ manually interrupt them. They won't otherwise receive a Ctrl+C/Break. */
+ for(i=0; i < kwsysProcesses.Count; ++i)
+ {
+ if(kwsysProcesses.Processes[i].NewProcessGroup)
+ {
+ DWORD groupId = kwsysProcesses.Processes[i].dwProcessId;
+ if(groupId)
+ {
+ GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, groupId);
+ }
+ }
+ }
+
+ /* Wait for each child process to exit. This is the key step that prevents
+ us from leaving several orphaned children processes running in the
+ background when the user presses Ctrl+C. */
+ for(i=0; i < kwsysProcesses.Count; ++i)
+ {
+ WaitForSingleObject(kwsysProcesses.Processes[i].hProcess, INFINITE);
+ }
+
+ /* Leave critical section. */
+ LeaveCriticalSection(&kwsysProcesses.Lock);
+
+ /* Continue on to default Ctrl handler (which calls ExitProcess). */
+ return FALSE;
+}
diff --git a/Source/kwsys/README.txt b/Source/kwsys/README.txt
index ba03f8dde..b8191f784 100644
--- a/Source/kwsys/README.txt
+++ b/Source/kwsys/README.txt
@@ -8,3 +8,5 @@ details.
You are probably reading this file in the source tree of a surrounding
project. In that case, see "../README.kwsys" for details of using
KWSys in your project.
+
+See CONTRIBUTING.rst for instructions to contribute KWSys changes.
diff --git a/Source/kwsys/RegularExpression.cxx b/Source/kwsys/RegularExpression.cxx
index c8297873f..598e7cae5 100644
--- a/Source/kwsys/RegularExpression.cxx
+++ b/Source/kwsys/RegularExpression.cxx
@@ -882,13 +882,6 @@ void regdump ();
static char* regprop ();
#endif
-bool RegularExpression::find (kwsys_stl::string const& s)
-{
- return find(s.c_str());
-}
-
-
-
// find -- Matches the regular expression to the given string.
// Returns true if found, and sets start and end indexes accordingly.
diff --git a/Source/kwsys/RegularExpression.hxx.in b/Source/kwsys/RegularExpression.hxx.in
index 62e9cad23..d0235d8f6 100644
--- a/Source/kwsys/RegularExpression.hxx.in
+++ b/Source/kwsys/RegularExpression.hxx.in
@@ -33,12 +33,7 @@
#include <@KWSYS_NAMESPACE@/Configure.h>
#include <@KWSYS_NAMESPACE@/Configure.hxx>
-#include <@KWSYS_NAMESPACE@/stl/string>
-
-/* Define this macro temporarily to keep the code readable. */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
-# define kwsys_stl @KWSYS_NAMESPACE@_stl
-#endif
+#include <string>
/* Disable useless Borland warnings. KWSys tries not to force things
on its includers, but there is no choice here. */
@@ -198,13 +193,18 @@ public:
* Instantiate RegularExpression with compiled char*.
*/
inline RegularExpression (char const*);
-
+
/**
* Instantiate RegularExpression as a copy of another regular expression.
*/
RegularExpression (RegularExpression const&);
/**
+ * Instantiate RegularExpression with compiled string.
+ */
+ inline RegularExpression (std::string const&);
+
+ /**
* Destructor.
*/
inline ~RegularExpression();
@@ -216,6 +216,12 @@ public:
bool compile (char const*);
/**
+ * Compile a regular expression into internal code
+ * for later pattern matching.
+ */
+ inline bool compile (std::string const&);
+
+ /**
* Matches the regular expression to the given string.
* Returns true if found, and sets start and end indexes accordingly.
*/
@@ -225,17 +231,17 @@ public:
* Matches the regular expression to the given std string.
* Returns true if found, and sets start and end indexes accordingly.
*/
- bool find (kwsys_stl::string const&);
+ inline bool find (std::string const&);
/**
* Index to start of first find.
*/
- inline kwsys_stl::string::size_type start() const;
+ inline std::string::size_type start() const;
/**
* Index to end of first find.
*/
- inline kwsys_stl::string::size_type end() const;
+ inline std::string::size_type end() const;
/**
* Copy the given regular expression.
@@ -274,9 +280,9 @@ public:
* Destructor.
*/
// awf added
- kwsys_stl::string::size_type start(int n) const;
- kwsys_stl::string::size_type end(int n) const;
- kwsys_stl::string match(int n) const;
+ std::string::size_type start(int n) const;
+ std::string::size_type end(int n) const;
+ std::string match(int n) const;
enum { NSUBEXP = 10 };
private:
@@ -285,7 +291,7 @@ private:
char regstart; // Internal use only
char reganch; // Internal use only
const char* regmust; // Internal use only
- kwsys_stl::string::size_type regmlen; // Internal use only
+ std::string::size_type regmlen; // Internal use only
char* program;
int progsize;
const char* searchstring;
@@ -313,6 +319,16 @@ inline RegularExpression::RegularExpression (const char* s)
}
/**
+ * Creates a regular expression from string s, and
+ * compiles s.
+ */
+inline RegularExpression::RegularExpression (const std::string& s)
+{
+ this->program = 0;
+ this->compile(s);
+}
+
+/**
* Destroys and frees space allocated for the regular expression.
*/
inline RegularExpression::~RegularExpression ()
@@ -323,11 +339,29 @@ inline RegularExpression::~RegularExpression ()
}
/**
+ * Compile a regular expression into internal code
+ * for later pattern matching.
+ */
+inline bool RegularExpression::compile (std::string const& s)
+{
+ return this->compile(s.c_str());
+}
+
+/**
+ * Matches the regular expression to the given std string.
+ * Returns true if found, and sets start and end indexes accordingly.
+ */
+inline bool RegularExpression::find (std::string const& s)
+{
+ return this->find(s.c_str());
+}
+
+/**
* Set the start position for the regular expression.
*/
-inline kwsys_stl::string::size_type RegularExpression::start () const
+inline std::string::size_type RegularExpression::start () const
{
- return static_cast<kwsys_stl::string::size_type>(
+ return static_cast<std::string::size_type>(
this->startp[0] - searchstring);
}
@@ -335,9 +369,9 @@ inline kwsys_stl::string::size_type RegularExpression::start () const
/**
* Returns the start/end index of the last item found.
*/
-inline kwsys_stl::string::size_type RegularExpression::end () const
+inline std::string::size_type RegularExpression::end () const
{
- return static_cast<kwsys_stl::string::size_type>(
+ return static_cast<std::string::size_type>(
this->endp[0] - searchstring);
}
@@ -371,9 +405,9 @@ inline void RegularExpression::set_invalid ()
/**
* Return start index of nth submatch. start(0) is the start of the full match.
*/
-inline kwsys_stl::string::size_type RegularExpression::start(int n) const
+inline std::string::size_type RegularExpression::start(int n) const
{
- return static_cast<kwsys_stl::string::size_type>(
+ return static_cast<std::string::size_type>(
this->startp[n] - searchstring);
}
@@ -381,34 +415,29 @@ inline kwsys_stl::string::size_type RegularExpression::start(int n) const
/**
* Return end index of nth submatch. end(0) is the end of the full match.
*/
-inline kwsys_stl::string::size_type RegularExpression::end(int n) const
+inline std::string::size_type RegularExpression::end(int n) const
{
- return static_cast<kwsys_stl::string::size_type>(
+ return static_cast<std::string::size_type>(
this->endp[n] - searchstring);
}
/**
* Return nth submatch as a string.
*/
-inline kwsys_stl::string RegularExpression::match(int n) const
+inline std::string RegularExpression::match(int n) const
{
if (this->startp[n]==0)
{
- return kwsys_stl::string("");
+ return std::string("");
}
else
{
- return kwsys_stl::string(this->startp[n],
- static_cast<kwsys_stl::string::size_type>(
+ return std::string(this->startp[n],
+ static_cast<std::string::size_type>(
this->endp[n] - this->startp[n]));
}
}
} // namespace @KWSYS_NAMESPACE@
-/* Undefine temporary macro. */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
-# undef kwsys_stl
-#endif
-
#endif
diff --git a/Source/kwsys/SharedForward.h.in b/Source/kwsys/SharedForward.h.in
index 8bbc74ac2..f80ef8470 100644
--- a/Source/kwsys/SharedForward.h.in
+++ b/Source/kwsys/SharedForward.h.in
@@ -65,6 +65,21 @@
See the comments below for specific explanations of each macro.
*/
+/* Disable -Wcast-qual warnings since they are too hard to fix in a
+ cross-platform way. */
+#if defined(__clang__) && defined(__has_warning)
+# if __has_warning("-Wcast-qual")
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wcast-qual"
+# endif
+#endif
+
+#if defined(__BORLANDC__) && !defined(__cplusplus)
+ /* Code has no effect; raised by winnt.h in C (not C++) when ignoring an
+ unused parameter using "(param)" syntax (i.e. no cast to void). */
+# pragma warn -8019
+#endif
+
/*--------------------------------------------------------------------------*/
/* Full path to the directory in which this executable is built. Do
@@ -415,7 +430,7 @@ static int kwsys_shared_forward_realpath(const char* in_path, char* out_path)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
/* Implementation for Windows. */
- DWORD n = GetFullPathName(in_path, KWSYS_SHARED_FORWARD_MAXPATH,
+ DWORD n = GetFullPathNameA(in_path, KWSYS_SHARED_FORWARD_MAXPATH,
out_path, 0);
return n > 0 && n <= KWSYS_SHARED_FORWARD_MAXPATH;
#else
@@ -429,9 +444,9 @@ static int kwsys_shared_forward_samepath(const char* file1, const char* file2)
{
#if defined(_WIN32)
int result = 0;
- HANDLE h1 = CreateFile(file1, GENERIC_READ, FILE_SHARE_READ, NULL,
+ HANDLE h1 = CreateFileA(file1, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
- HANDLE h2 = CreateFile(file2, GENERIC_READ, FILE_SHARE_READ, NULL,
+ HANDLE h2 = CreateFileA(file2, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if(h1 != INVALID_HANDLE_VALUE && h2 != INVALID_HANDLE_VALUE)
{
@@ -462,7 +477,7 @@ static void kwsys_shared_forward_strerror(char* message)
#if defined(_WIN32) && !defined(__CYGWIN__)
/* Implementation for Windows. */
DWORD original = GetLastError();
- DWORD length = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
+ DWORD length = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, 0, original,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
message, KWSYS_SHARED_FORWARD_MAXPATH, 0);
@@ -512,7 +527,7 @@ static void kwsys_shared_forward_execvp(const char* cmd,
/* Invoke the child process. */
#if defined(_MSC_VER)
_execvp(cmd, argv);
-#elif defined(__MINGW32__)
+#elif defined(__MINGW32__) && !defined(__MINGW64__)
execvp(cmd, argv);
#else
execvp(cmd, (char* const*)argv);
@@ -813,7 +828,7 @@ static void kwsys_shared_forward_print_failure(char const* const* argv)
}
/* Static storage space to store the updated environment variable. */
-static char kwsys_shared_forward_ldpath[KWSYS_SHARED_FORWARD_MAXPATH*16] = KWSYS_SHARED_FORWARD_LDPATH "=";
+static char kwsys_shared_forward_ldpath[65535] = KWSYS_SHARED_FORWARD_LDPATH "=";
/*--------------------------------------------------------------------------*/
/* Main driver function to be called from main. */
@@ -917,6 +932,13 @@ static int @KWSYS_NAMESPACE@_shared_forward_to_real(int argc, char** argv_in)
return 1;
}
+/* Restore warning stack. */
+#if defined(__clang__) && defined(__has_warning)
+# if __has_warning("-Wcast-qual")
+# pragma clang diagnostic pop
+# endif
+#endif
+
#else
# error "@KWSYS_NAMESPACE@/SharedForward.h should be included only once."
#endif
diff --git a/Source/kwsys/String.hxx.in b/Source/kwsys/String.hxx.in
index 4386c9eb7..2e9aedb86 100644
--- a/Source/kwsys/String.hxx.in
+++ b/Source/kwsys/String.hxx.in
@@ -12,7 +12,7 @@
#ifndef @KWSYS_NAMESPACE@_String_hxx
#define @KWSYS_NAMESPACE@_String_hxx
-#include <@KWSYS_NAMESPACE@/stl/string>
+#include <string>
namespace @KWSYS_NAMESPACE@
{
@@ -25,10 +25,10 @@ namespace @KWSYS_NAMESPACE@
* simply a subclass of this type with the same interface so that the
* name is shorter in debugging symbols and error messages.
*/
-class String: public @KWSYS_NAMESPACE@_stl::string
+class String: public std::string
{
/** The original string type. */
- typedef @KWSYS_NAMESPACE@_stl::string stl_string;
+ typedef std::string stl_string;
public:
@@ -55,8 +55,8 @@ public:
#if defined(__WATCOMC__)
inline bool operator<(String const& l, String const& r)
{
- return (static_cast<@KWSYS_NAMESPACE@_stl::string const&>(l) <
- static_cast<@KWSYS_NAMESPACE@_stl::string const&>(r));
+ return (static_cast<std::string const&>(l) <
+ static_cast<std::string const&>(r));
}
#endif
diff --git a/Source/kwsys/System.c b/Source/kwsys/System.c
index 5d178bfa2..ccc7e8164 100644
--- a/Source/kwsys/System.c
+++ b/Source/kwsys/System.c
@@ -20,8 +20,8 @@
#include <stddef.h> /* ptrdiff_t */
#include <stdlib.h> /* malloc, free */
-#include <string.h> /* strlen */
-#include <ctype.h> /* isalpha */
+#include <string.h> /* memcpy */
+#include <ctype.h> /* isspace */
#include <stdio.h>
@@ -31,561 +31,6 @@ typedef ptrdiff_t kwsysSystem_ptrdiff_t;
typedef int kwsysSystem_ptrdiff_t;
#endif
-/*
-
-Notes:
-
-Make variable replacements open a can of worms. Sometimes they should
-be quoted and sometimes not. Sometimes their replacement values are
-already quoted.
-
-VS variables cause problems. In order to pass the referenced value
-with spaces the reference must be quoted. If the variable value ends
-in a backslash then it will escape the ending quote! In order to make
-the ending backslash appear we need this:
-
- "$(InputDir)\"
-
-However if there is not a trailing backslash then this will put a
-quote in the value so we need:
-
- "$(InputDir)"
-
-Make variable references are platform specific so we should probably
-just NOT quote them and let the listfile author deal with it.
-
-*/
-
-/*
-TODO: For windows echo:
-
-To display a pipe (|) or redirection character (< or >) when using the
-echo command, use a caret character immediately before the pipe or
-redirection character (for example, ^>, ^<, or ^| ). If you need to
-use the caret character itself (^), use two in a row (^^).
-*/
-
-/*--------------------------------------------------------------------------*/
-static int kwsysSystem_Shell__CharIsWhitespace(char c)
-{
- return ((c == ' ') || (c == '\t'));
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysSystem_Shell__CharNeedsQuotesOnUnix(char c)
-{
- return ((c == '\'') || (c == '`') || (c == ';') || (c == '#') ||
- (c == '&') || (c == '$') || (c == '(') || (c == ')') ||
- (c == '~') || (c == '<') || (c == '>') || (c == '|') ||
- (c == '*') || (c == '^') || (c == '\\'));
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysSystem_Shell__CharNeedsQuotesOnWindows(char c)
-{
- return ((c == '\'') || (c == '#') || (c == '&') ||
- (c == '<') || (c == '>') || (c == '|') || (c == '^'));
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysSystem_Shell__CharNeedsQuotes(char c, int isUnix, int flags)
-{
- /* On Windows the built-in command shell echo never needs quotes. */
- if(!isUnix && (flags & kwsysSystem_Shell_Flag_EchoWindows))
- {
- return 0;
- }
-
- /* On all platforms quotes are needed to preserve whitespace. */
- if(kwsysSystem_Shell__CharIsWhitespace(c))
- {
- return 1;
- }
-
- if(isUnix)
- {
- /* On UNIX several special characters need quotes to preserve them. */
- if(kwsysSystem_Shell__CharNeedsQuotesOnUnix(c))
- {
- return 1;
- }
- }
- else
- {
- /* On Windows several special characters need quotes to preserve them. */
- if(kwsysSystem_Shell__CharNeedsQuotesOnWindows(c))
- {
- return 1;
- }
- }
- return 0;
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysSystem_Shell__CharIsMakeVariableName(char c)
-{
- return c && (c == '_' || isalpha(((int)c)));
-}
-
-/*--------------------------------------------------------------------------*/
-static const char* kwsysSystem_Shell__SkipMakeVariables(const char* c)
-{
- while(*c == '$' && *(c+1) == '(')
- {
- const char* skip = c+2;
- while(kwsysSystem_Shell__CharIsMakeVariableName(*skip))
- {
- ++skip;
- }
- if(*skip == ')')
- {
- c = skip+1;
- }
- else
- {
- break;
- }
- }
- return c;
-}
-
-/*
-Allowing make variable replacements opens a can of worms. Sometimes
-they should be quoted and sometimes not. Sometimes their replacement
-values are already quoted or contain escapes.
-
-Some Visual Studio variables cause problems. In order to pass the
-referenced value with spaces the reference must be quoted. If the
-variable value ends in a backslash then it will escape the ending
-quote! In order to make the ending backslash appear we need this:
-
- "$(InputDir)\"
-
-However if there is not a trailing backslash then this will put a
-quote in the value so we need:
-
- "$(InputDir)"
-
-This macro decides whether we quote an argument just because it
-contains a make variable reference. This should be replaced with a
-flag later when we understand applications of this better.
-*/
-#define KWSYS_SYSTEM_SHELL_QUOTE_MAKE_VARIABLES 0
-
-/*--------------------------------------------------------------------------*/
-static int kwsysSystem_Shell__ArgumentNeedsQuotes(const char* in, int isUnix,
- int flags)
-{
- /* The empty string needs quotes. */
- if(!*in)
- {
- return 1;
- }
-
- /* Scan the string for characters that require quoting. */
- {
- const char* c;
- for(c=in; *c; ++c)
- {
- /* Look for $(MAKEVAR) syntax if requested. */
- if(flags & kwsysSystem_Shell_Flag_AllowMakeVariables)
- {
-#if KWSYS_SYSTEM_SHELL_QUOTE_MAKE_VARIABLES
- const char* skip = kwsysSystem_Shell__SkipMakeVariables(c);
- if(skip != c)
- {
- /* We need to quote make variable references to preserve the
- string with contents substituted in its place. */
- return 1;
- }
-#else
- /* Skip over the make variable references if any are present. */
- c = kwsysSystem_Shell__SkipMakeVariables(c);
-
- /* Stop if we have reached the end of the string. */
- if(!*c)
- {
- break;
- }
-#endif
- }
-
- /* Check whether this character needs quotes. */
- if(kwsysSystem_Shell__CharNeedsQuotes(*c, isUnix, flags))
- {
- return 1;
- }
- }
- }
-
- /* On Windows some single character arguments need quotes. */
- if(!isUnix && *in && !*(in+1))
- {
- char c = *in;
- if((c == '?') || (c == '&') || (c == '^') || (c == '|') || (c == '#'))
- {
- return 1;
- }
- }
-
- return 0;
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysSystem_Shell__GetArgumentSize(const char* in,
- int isUnix, int flags)
-{
- /* Start with the length of the original argument, plus one for
- either a terminating null or a separating space. */
- int size = (int)strlen(in) + 1;
-
- /* String iterator. */
- const char* c;
-
- /* Keep track of how many backslashes have been encountered in a row. */
- int windows_backslashes = 0;
-
- /* Scan the string for characters that require escaping or quoting. */
- for(c=in; *c; ++c)
- {
- /* Look for $(MAKEVAR) syntax if requested. */
- if(flags & kwsysSystem_Shell_Flag_AllowMakeVariables)
- {
- /* Skip over the make variable references if any are present. */
- c = kwsysSystem_Shell__SkipMakeVariables(c);
-
- /* Stop if we have reached the end of the string. */
- if(!*c)
- {
- break;
- }
- }
-
- /* Check whether this character needs escaping for the shell. */
- if(isUnix)
- {
- /* On Unix a few special characters need escaping even inside a
- quoted argument. */
- if(*c == '\\' || *c == '"' || *c == '`' || *c == '$')
- {
- /* This character needs a backslash to escape it. */
- ++size;
- }
- }
- else if(flags & kwsysSystem_Shell_Flag_EchoWindows)
- {
- /* On Windows the built-in command shell echo never needs escaping. */
- }
- else
- {
- /* On Windows only backslashes and double-quotes need escaping. */
- if(*c == '\\')
- {
- /* Found a backslash. It may need to be escaped later. */
- ++windows_backslashes;
- }
- else if(*c == '"')
- {
- /* Found a double-quote. We need to escape it and all
- immediately preceding backslashes. */
- size += windows_backslashes + 1;
- windows_backslashes = 0;
- }
- else
- {
- /* Found another character. This eliminates the possibility
- that any immediately preceding backslashes will be
- escaped. */
- windows_backslashes = 0;
- }
- }
-
- /* Check whether this character needs escaping for a make tool. */
- if(*c == '$')
- {
- if(flags & kwsysSystem_Shell_Flag_Make)
- {
- /* In Makefiles a dollar is written $$ so we need one extra
- character. */
- ++size;
- }
- else if(flags & kwsysSystem_Shell_Flag_VSIDE)
- {
- /* In a VS IDE a dollar is written "$" so we need two extra
- characters. */
- size += 2;
- }
- }
- else if(*c == '#')
- {
- if((flags & kwsysSystem_Shell_Flag_Make) &&
- (flags & kwsysSystem_Shell_Flag_WatcomWMake))
- {
- /* In Watcom WMake makefiles a pound is written $# so we need
- one extra character. */
- ++size;
- }
- }
- else if(*c == '%')
- {
- if((flags & kwsysSystem_Shell_Flag_VSIDE) ||
- ((flags & kwsysSystem_Shell_Flag_Make) &&
- ((flags & kwsysSystem_Shell_Flag_MinGWMake) ||
- (flags & kwsysSystem_Shell_Flag_NMake))))
- {
- /* In the VS IDE, NMake, or MinGW make a percent is written %%
- so we need one extra characters. */
- size += 1;
- }
- }
- else if(*c == ';')
- {
- if(flags & kwsysSystem_Shell_Flag_VSIDE)
- {
- /* In a VS IDE a semicolon is written ";" so we need two extra
- characters. */
- size += 2;
- }
- }
- }
-
- /* Check whether the argument needs surrounding quotes. */
- if(kwsysSystem_Shell__ArgumentNeedsQuotes(in, isUnix, flags))
- {
- /* Surrounding quotes are needed. Allocate space for them. */
- size += 2;
-
- /* We must escape all ending backslashes when quoting on windows. */
- size += windows_backslashes;
- }
-
- return size;
-}
-
-/*--------------------------------------------------------------------------*/
-static char* kwsysSystem_Shell__GetArgument(const char* in, char* out,
- int isUnix, int flags)
-{
- /* String iterator. */
- const char* c;
-
- /* Keep track of how many backslashes have been encountered in a row. */
- int windows_backslashes = 0;
-
- /* Whether the argument must be quoted. */
- int needQuotes = kwsysSystem_Shell__ArgumentNeedsQuotes(in, isUnix, flags);
- if(needQuotes)
- {
- /* Add the opening quote for this argument. */
- *out++ = '"';
- }
-
- /* Scan the string for characters that require escaping or quoting. */
- for(c=in; *c; ++c)
- {
- /* Look for $(MAKEVAR) syntax if requested. */
- if(flags & kwsysSystem_Shell_Flag_AllowMakeVariables)
- {
- const char* skip = kwsysSystem_Shell__SkipMakeVariables(c);
- if(skip != c)
- {
- /* Copy to the end of the make variable references. */
- while(c != skip)
- {
- *out++ = *c++;
- }
-
- /* The make variable reference eliminates any escaping needed
- for preceding backslashes. */
- windows_backslashes = 0;
-
- /* Stop if we have reached the end of the string. */
- if(!*c)
- {
- break;
- }
- }
- }
-
- /* Check whether this character needs escaping for the shell. */
- if(isUnix)
- {
- /* On Unix a few special characters need escaping even inside a
- quoted argument. */
- if(*c == '\\' || *c == '"' || *c == '`' || *c == '$')
- {
- /* This character needs a backslash to escape it. */
- *out++ = '\\';
- }
- }
- else if(flags & kwsysSystem_Shell_Flag_EchoWindows)
- {
- /* On Windows the built-in command shell echo never needs escaping. */
- }
- else
- {
- /* On Windows only backslashes and double-quotes need escaping. */
- if(*c == '\\')
- {
- /* Found a backslash. It may need to be escaped later. */
- ++windows_backslashes;
- }
- else if(*c == '"')
- {
- /* Found a double-quote. Escape all immediately preceding
- backslashes. */
- while(windows_backslashes > 0)
- {
- --windows_backslashes;
- *out++ = '\\';
- }
-
- /* Add the backslash to escape the double-quote. */
- *out++ = '\\';
- }
- else
- {
- /* We encountered a normal character. This eliminates any
- escaping needed for preceding backslashes. */
- windows_backslashes = 0;
- }
- }
-
- /* Check whether this character needs escaping for a make tool. */
- if(*c == '$')
- {
- if(flags & kwsysSystem_Shell_Flag_Make)
- {
- /* In Makefiles a dollar is written $$. The make tool will
- replace it with just $ before passing it to the shell. */
- *out++ = '$';
- *out++ = '$';
- }
- else if(flags & kwsysSystem_Shell_Flag_VSIDE)
- {
- /* In a VS IDE a dollar is written "$". If this is written in
- an un-quoted argument it starts a quoted segment, inserts
- the $ and ends the segment. If it is written in a quoted
- argument it ends quoting, inserts the $ and restarts
- quoting. Either way the $ is isolated from surrounding
- text to avoid looking like a variable reference. */
- *out++ = '"';
- *out++ = '$';
- *out++ = '"';
- }
- else
- {
- /* Otherwise a dollar is written just $. */
- *out++ = '$';
- }
- }
- else if(*c == '#')
- {
- if((flags & kwsysSystem_Shell_Flag_Make) &&
- (flags & kwsysSystem_Shell_Flag_WatcomWMake))
- {
- /* In Watcom WMake makefiles a pound is written $#. The make
- tool will replace it with just # before passing it to the
- shell. */
- *out++ = '$';
- *out++ = '#';
- }
- else
- {
- /* Otherwise a pound is written just #. */
- *out++ = '#';
- }
- }
- else if(*c == '%')
- {
- if((flags & kwsysSystem_Shell_Flag_VSIDE) ||
- ((flags & kwsysSystem_Shell_Flag_Make) &&
- ((flags & kwsysSystem_Shell_Flag_MinGWMake) ||
- (flags & kwsysSystem_Shell_Flag_NMake))))
- {
- /* In the VS IDE, NMake, or MinGW make a percent is written %%. */
- *out++ = '%';
- *out++ = '%';
- }
- else
- {
- /* Otherwise a percent is written just %. */
- *out++ = '%';
- }
- }
- else if(*c == ';')
- {
- if(flags & kwsysSystem_Shell_Flag_VSIDE)
- {
- /* In a VS IDE a semicolon is written ";". If this is written
- in an un-quoted argument it starts a quoted segment,
- inserts the ; and ends the segment. If it is written in a
- quoted argument it ends quoting, inserts the ; and restarts
- quoting. Either way the ; is isolated. */
- *out++ = '"';
- *out++ = ';';
- *out++ = '"';
- }
- else
- {
- /* Otherwise a semicolon is written just ;. */
- *out++ = ';';
- }
- }
- else
- {
- /* Store this character. */
- *out++ = *c;
- }
- }
-
- if(needQuotes)
- {
- /* Add enough backslashes to escape any trailing ones. */
- while(windows_backslashes > 0)
- {
- --windows_backslashes;
- *out++ = '\\';
- }
-
- /* Add the closing quote for this argument. */
- *out++ = '"';
- }
-
- /* Store a terminating null without incrementing. */
- *out = 0;
-
- return out;
-}
-
-/*--------------------------------------------------------------------------*/
-char* kwsysSystem_Shell_GetArgumentForWindows(const char* in,
- char* out,
- int flags)
-{
- return kwsysSystem_Shell__GetArgument(in, out, 0, flags);
-}
-
-/*--------------------------------------------------------------------------*/
-char* kwsysSystem_Shell_GetArgumentForUnix(const char* in,
- char* out,
- int flags)
-{
- return kwsysSystem_Shell__GetArgument(in, out, 1, flags);
-}
-
-/*--------------------------------------------------------------------------*/
-int kwsysSystem_Shell_GetArgumentSizeForWindows(const char* in, int flags)
-{
- return kwsysSystem_Shell__GetArgumentSize(in, 0, flags);
-}
-
-/*--------------------------------------------------------------------------*/
-int kwsysSystem_Shell_GetArgumentSizeForUnix(const char* in, int flags)
-{
- return kwsysSystem_Shell__GetArgumentSize(in, 1, flags);
-}
-
/*--------------------------------------------------------------------------*/
static int kwsysSystem__AppendByte(char* local,
char** begin, char** end,
diff --git a/Source/kwsys/System.h.in b/Source/kwsys/System.h.in
index 549db900c..3f3d3f4b0 100644
--- a/Source/kwsys/System.h.in
+++ b/Source/kwsys/System.h.in
@@ -24,27 +24,6 @@
#endif
#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
# define kwsysSystem_Parse_CommandForUnix kwsys_ns(System_Parse_CommandForUnix)
-# define kwsysSystem_Shell_GetArgumentForWindows kwsys_ns(System_Shell_GetArgumentForWindows)
-# define kwsysSystem_Shell_GetArgumentForUnix kwsys_ns(System_Shell_GetArgumentForUnix)
-# define kwsysSystem_Shell_GetArgumentSizeForWindows kwsys_ns(System_Shell_GetArgumentSizeForWindows)
-# define kwsysSystem_Shell_GetArgumentSizeForUnix kwsys_ns(System_Shell_GetArgumentSizeForUnix)
-# define kwsysSystem_Shell_Flag_e kwsys_ns(System_Shell_Flag_e)
-# define kwsysSystem_Shell_Flag_Make kwsys_ns(System_Shell_Flag_Make)
-# define kwsysSystem_Shell_Flag_VSIDE kwsys_ns(System_Shell_Flag_VSIDE)
-# define kwsysSystem_Shell_Flag_EchoWindows kwsys_ns(System_Shell_Flag_EchoWindows)
-# define kwsysSystem_Shell_Flag_WatcomWMake kwsys_ns(System_Shell_Flag_WatcomWMake)
-# define kwsysSystem_Shell_Flag_MinGWMake kwsys_ns(System_Shell_Flag_MinGWMake)
-# define kwsysSystem_Shell_Flag_NMake kwsys_ns(System_Shell_Flag_NMake)
-# define kwsysSystem_Shell_Flag_AllowMakeVariables kwsys_ns(System_Shell_Flag_AllowMakeVariables)
-#endif
-
-#ifdef __VMS
-#define @KWSYS_NAMESPACE@System_Shell_GetArgumentForUnix \
- @KWSYS_NAMESPACE@System_Shell_UnixGA
-#define @KWSYS_NAMESPACE@System_Shell_GetArgumentSizeForUnix \
- @KWSYS_NAMESPACE@System_Shell_UnixGAS
-#define @KWSYS_NAMESPACE@System_Shell_GetArgumentForWindows \
- @KWSYS_NAMESPACE@System_Shell_WindowsGA
#endif
#if defined(__cplusplus)
@@ -53,66 +32,6 @@ extern "C"
#endif
/**
- * Transform the given command line argument for use in a Windows or
- * Unix shell. Returns a pointer to the end of the command line
- * argument in the provided output buffer. Flags may be passed to
- * modify the generated quoting and escape sequences to work under
- * alternative environments.
- */
-kwsysEXPORT char* kwsysSystem_Shell_GetArgumentForWindows(const char* in,
- char* out,
- int flags);
-kwsysEXPORT char* kwsysSystem_Shell_GetArgumentForUnix(const char* in,
- char* out,
- int flags);
-
-/**
- * Compute the size of the buffer required to store the output from
- * kwsysSystem_Shell_GetArgumentForWindows or
- * kwsysSystem_Shell_GetArgumentForUnix. The flags passed must be
- * identical between the two calls.
- */
-kwsysEXPORT int kwsysSystem_Shell_GetArgumentSizeForWindows(const char* in,
- int flags);
-kwsysEXPORT int kwsysSystem_Shell_GetArgumentSizeForUnix(const char* in,
- int flags);
-
-/**
- * Flags to pass to kwsysSystem_Shell_GetArgumentForWindows or
- * kwsysSystem_Shell_GetArgumentForUnix. These modify the generated
- * quoting and escape sequences to work under alternative
- * environments.
- */
-enum kwsysSystem_Shell_Flag_e
-{
- /** The target shell is in a makefile. */
- kwsysSystem_Shell_Flag_Make = (1<<0),
-
- /** The target shell is in a VS project file. Do not use with
- Shell_Flag_Make. */
- kwsysSystem_Shell_Flag_VSIDE = (1<<1),
-
- /** In a windows shell the argument is being passed to "echo". */
- kwsysSystem_Shell_Flag_EchoWindows = (1<<2),
-
- /** The target shell is in a Watcom WMake makefile. */
- kwsysSystem_Shell_Flag_WatcomWMake = (1<<3),
-
- /** The target shell is in a MinGW Make makefile. */
- kwsysSystem_Shell_Flag_MinGWMake = (1<<4),
-
- /** The target shell is in a NMake makefile. */
- kwsysSystem_Shell_Flag_NMake = (1<<6),
-
- /** Make variable reference syntax $(MAKEVAR) should not be escaped
- to allow a build tool to replace it. Replacement values
- containing spaces, quotes, backslashes, or other
- non-alphanumeric characters that have significance to some makes
- or shells produce undefined behavior. */
- kwsysSystem_Shell_Flag_AllowMakeVariables = (1<<5)
-};
-
-/**
* Parse a unix-style command line string into separate arguments.
*
* On success, returns a pointer to an array of pointers to individual
@@ -144,18 +63,6 @@ kwsysEXPORT char** kwsysSystem_Parse_CommandForUnix(const char* command,
# undef kwsysEXPORT
# if !defined(KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
# undef kwsysSystem_Parse_CommandForUnix
-# undef kwsysSystem_Shell_GetArgumentForWindows
-# undef kwsysSystem_Shell_GetArgumentForUnix
-# undef kwsysSystem_Shell_GetArgumentSizeForWindows
-# undef kwsysSystem_Shell_GetArgumentSizeForUnix
-# undef kwsysSystem_Shell_Flag_e
-# undef kwsysSystem_Shell_Flag_Make
-# undef kwsysSystem_Shell_Flag_VSIDE
-# undef kwsysSystem_Shell_Flag_EchoWindows
-# undef kwsysSystem_Shell_Flag_WatcomWMake
-# undef kwsysSystem_Shell_Flag_MinGWMake
-# undef kwsysSystem_Shell_Flag_NMake
-# undef kwsysSystem_Shell_Flag_AllowMakeVariables
# endif
#endif
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index beefd7d73..cddcc8dcb 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -35,14 +35,8 @@
// http://msdn.microsoft.com/en-us/library/ms683219(VS.85).aspx
#include "kwsysPrivate.h"
-#include KWSYS_HEADER(stl/string)
-#include KWSYS_HEADER(stl/vector)
-#include KWSYS_HEADER(ios/iosfwd)
#include KWSYS_HEADER(SystemInformation.hxx)
#include KWSYS_HEADER(Process.h)
-#include KWSYS_HEADER(ios/iostream)
-#include KWSYS_HEADER(ios/sstream)
-#include KWSYS_HEADER(ios/fstream)
// Work-around CMake dependency scanning limitation. This must
// duplicate the above list of headers.
@@ -50,16 +44,19 @@
# include "SystemInformation.hxx.in"
# include "Process.h.in"
# include "Configure.hxx.in"
-# include "kwsys_stl.hxx.in"
-# include "kwsys_stl_vector.in"
-# include "kwsys_stl_iosfwd.in"
-# include "kwsys_ios_sstream.h.in"
-# include "kwsys_ios_iostream.h.in"
-# include "kwsys_ios_fstream.h.in"
#endif
+#include <iostream>
+#include <sstream>
+#include <fstream>
+#include <string>
+#include <vector>
+
#if defined(_WIN32)
# include <windows.h>
+# if defined(_MSC_VER) && _MSC_VER >= 1800
+# define KWSYS_WINDOWS_DEPRECATED_GetVersionEx
+# endif
# include <errno.h>
# if defined(KWSYS_SYS_HAS_PSAPI)
# include <psapi.h>
@@ -78,6 +75,11 @@ typedef int siginfo_t;
# include <errno.h> // extern int errno;
#endif
+#if defined (__CYGWIN__) && !defined(_WIN32)
+# include <windows.h>
+# undef _WIN32
+#endif
+
#ifdef __FreeBSD__
# include <sys/sysctl.h>
# include <fenv.h>
@@ -117,16 +119,8 @@ typedef int siginfo_t;
# include <ifaddrs.h>
# define KWSYS_SYSTEMINFORMATION_IMPLEMENT_FQDN
# endif
-# if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0 >= 1050
-# if defined(KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE)
-# include <execinfo.h>
-# if defined(KWSYS_SYSTEMINFORMATION_HAS_CPP_DEMANGLE)
-# include <cxxabi.h>
-# endif
-# if defined(KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP)
-# include <dlfcn.h>
-# endif
-# endif
+# if !(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0 >= 1050)
+# undef KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE
# endif
#endif
@@ -141,15 +135,6 @@ typedef int siginfo_t;
# define KWSYS_SYSTEMINFORMATION_IMPLEMENT_FQDN
# endif
# endif
-# if defined(KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE)
-# include <execinfo.h>
-# if defined(KWSYS_SYSTEMINFORMATION_HAS_CPP_DEMANGLE)
-# include <cxxabi.h>
-# endif
-# if defined(KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP)
-# include <dlfcn.h>
-# endif
-# endif
# if defined(KWSYS_CXX_HAS_RLIMIT64)
typedef struct rlimit64 ResourceLimitType;
# define GetResourceLimit getrlimit64
@@ -169,6 +154,19 @@ typedef struct rlimit ResourceLimitType;
# include <OS.h>
#endif
+#if defined(KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE)
+# include <execinfo.h>
+# if defined(KWSYS_SYSTEMINFORMATION_HAS_CPP_DEMANGLE)
+# include <cxxabi.h>
+# endif
+# if defined(KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP)
+# include <dlfcn.h>
+# endif
+#else
+# undef KWSYS_SYSTEMINFORMATION_HAS_CPP_DEMANGLE
+# undef KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP
+#endif
+
#include <memory.h>
#include <stdlib.h>
#include <stdio.h>
@@ -244,7 +242,7 @@ static bool call_cpuid(int select, int result[4])
_asm {
#ifdef CPUID_AWARE_COMPILER
; we must push/pop the registers <<CPUID>> writes to, as the
- ; optimiser doesn't know about <<CPUID>>, and so doesn't expect
+ ; optimiser does not know about <<CPUID>>, and so does not expect
; these registers to change.
push eax
push ebx
@@ -321,11 +319,11 @@ public:
const char * GetVendorString();
const char * GetVendorID();
- kwsys_stl::string GetTypeID();
- kwsys_stl::string GetFamilyID();
- kwsys_stl::string GetModelID();
- kwsys_stl::string GetModelName();
- kwsys_stl::string GetSteppingCode();
+ std::string GetTypeID();
+ std::string GetFamilyID();
+ std::string GetModelID();
+ std::string GetModelName();
+ std::string GetSteppingCode();
const char * GetExtendedProcessorName();
const char * GetProcessorSerialNumber();
int GetProcessorCacheSize();
@@ -337,7 +335,7 @@ public:
const char * GetOSName();
const char * GetHostname();
- int GetFullyQualifiedDomainName(kwsys_stl::string &fqdn);
+ int GetFullyQualifiedDomainName(std::string &fqdn);
const char * GetOSRelease();
const char * GetOSVersion();
const char * GetOSPlatform();
@@ -367,13 +365,15 @@ public:
const char *procLimitEnvVarName);
LongLong GetProcMemoryUsed();
+ double GetLoadAverage();
+
// enable/disable stack trace signal handler.
static
void SetStackTraceOnError(int enable);
// get current stack
static
- kwsys_stl::string GetProgramStack(int firstFrame, int wholePath);
+ std::string GetProgramStack(int firstFrame, int wholePath);
/** Run the different checks */
void RunCPUCheck();
@@ -389,10 +389,10 @@ public:
int Revision;
int ExtendedFamily;
int ExtendedModel;
- kwsys_stl::string ProcessorName;
- kwsys_stl::string Vendor;
- kwsys_stl::string SerialNumber;
- kwsys_stl::string ModelName;
+ std::string ProcessorName;
+ std::string Vendor;
+ std::string SerialNumber;
+ std::string ModelName;
} ID;
typedef struct tagCPUPowerManagement
@@ -444,7 +444,7 @@ public:
};
protected:
- // Functions.
+ // For windows
bool RetrieveCPUFeatures();
bool RetrieveCPUIdentity();
bool RetrieveCPUCacheDetails();
@@ -458,6 +458,7 @@ protected:
bool RetrieveClassicalCPUIdentity();
bool RetrieveExtendedCPUIdentity();
+ // Processor information
Manufacturer ChipManufacturer;
CPUFeatures Features;
ID ChipID;
@@ -465,15 +466,15 @@ protected:
unsigned int NumberOfLogicalCPU;
unsigned int NumberOfPhysicalCPU;
- int CPUCount();
+ int CPUCount(); // For windows
unsigned char LogicalCPUPerPhysicalCPU();
- unsigned char GetAPICId();
+ unsigned char GetAPICId(); // For windows
bool IsHyperThreadingSupported();
- static LongLong GetCyclesDifference(DELAY_FUNC, unsigned int);
+ static LongLong GetCyclesDifference(DELAY_FUNC, unsigned int); // For windows
// For Linux and Cygwin, /proc/cpuinfo formats are slightly different
bool RetreiveInformationFromCpuInfoFile();
- kwsys_stl::string ExtractValueFromCpuInfoFile(kwsys_stl::string buffer,
+ std::string ExtractValueFromCpuInfoFile(std::string buffer,
const char* word, size_t init=0);
bool QueryLinuxMemory();
@@ -482,20 +483,20 @@ protected:
static void Delay (unsigned int);
static void DelayOverhead (unsigned int);
- void FindManufacturer(const kwsys_stl::string &family = "");
+ void FindManufacturer(const std::string &family = "");
// For Mac
bool ParseSysCtl();
- int CallSwVers(const char *arg, kwsys_stl::string &ver);
- void TrimNewline(kwsys_stl::string&);
- kwsys_stl::string ExtractValueFromSysCtl(const char* word);
- kwsys_stl::string SysCtlBuffer;
+ int CallSwVers(const char *arg, std::string &ver);
+ void TrimNewline(std::string&);
+ std::string ExtractValueFromSysCtl(const char* word);
+ std::string SysCtlBuffer;
// For Solaris
bool QuerySolarisMemory();
bool QuerySolarisProcessor();
- kwsys_stl::string ParseValueFromKStat(const char* arguments);
- kwsys_stl::string RunProcess(kwsys_stl::vector<const char*> args);
+ std::string ParseValueFromKStat(const char* arguments);
+ std::string RunProcess(std::vector<const char*> args);
//For Haiku OS
bool QueryHaikuInfo();
@@ -533,11 +534,11 @@ protected:
// Operating System information
bool QueryOSInformation();
- kwsys_stl::string OSName;
- kwsys_stl::string Hostname;
- kwsys_stl::string OSRelease;
- kwsys_stl::string OSVersion;
- kwsys_stl::string OSPlatform;
+ std::string OSName;
+ std::string Hostname;
+ std::string OSRelease;
+ std::string OSVersion;
+ std::string OSPlatform;
};
@@ -561,27 +562,27 @@ const char * SystemInformation::GetVendorID()
return this->Implementation->GetVendorID();
}
-kwsys_stl::string SystemInformation::GetTypeID()
+std::string SystemInformation::GetTypeID()
{
return this->Implementation->GetTypeID();
}
-kwsys_stl::string SystemInformation::GetFamilyID()
+std::string SystemInformation::GetFamilyID()
{
return this->Implementation->GetFamilyID();
}
-kwsys_stl::string SystemInformation::GetModelID()
+std::string SystemInformation::GetModelID()
{
return this->Implementation->GetModelID();
}
-kwsys_stl::string SystemInformation::GetModelName()
+std::string SystemInformation::GetModelName()
{
return this->Implementation->GetModelName();
}
-kwsys_stl::string SystemInformation::GetSteppingCode()
+std::string SystemInformation::GetSteppingCode()
{
return this->Implementation->GetSteppingCode();
}
@@ -626,9 +627,9 @@ bool SystemInformation::DoesCPUSupportFeature(long int i)
return this->Implementation->DoesCPUSupportFeature(i);
}
-kwsys_stl::string SystemInformation::GetCPUDescription()
+std::string SystemInformation::GetCPUDescription()
{
- kwsys_ios::ostringstream oss;
+ std::ostringstream oss;
oss
<< this->GetNumberOfPhysicalCPU()
<< " core ";
@@ -647,9 +648,9 @@ kwsys_stl::string SystemInformation::GetCPUDescription()
}
// remove extra spaces
- kwsys_stl::string tmp=oss.str();
+ std::string tmp=oss.str();
size_t pos;
- while( (pos=tmp.find(" "))!=kwsys_stl::string::npos)
+ while( (pos=tmp.find(" "))!=std::string::npos)
{
tmp.replace(pos,2," ");
}
@@ -667,9 +668,9 @@ const char * SystemInformation::GetHostname()
return this->Implementation->GetHostname();
}
-kwsys_stl::string SystemInformation::GetFullyQualifiedDomainName()
+std::string SystemInformation::GetFullyQualifiedDomainName()
{
- kwsys_stl::string fqdn;
+ std::string fqdn;
this->Implementation->GetFullyQualifiedDomainName(fqdn);
return fqdn;
}
@@ -716,9 +717,9 @@ int SystemInformation::GetOSIsApple()
#endif
}
-kwsys_stl::string SystemInformation::GetOSDescription()
+std::string SystemInformation::GetOSDescription()
{
- kwsys_ios::ostringstream oss;
+ std::ostringstream oss;
oss
<< this->GetOSName()
<< " "
@@ -770,11 +771,11 @@ size_t SystemInformation::GetAvailablePhysicalMemory()
return this->Implementation->GetAvailablePhysicalMemory();
}
-kwsys_stl::string SystemInformation::GetMemoryDescription(
+std::string SystemInformation::GetMemoryDescription(
const char *hostLimitEnvVarName,
const char *procLimitEnvVarName)
{
- kwsys_ios::ostringstream oss;
+ std::ostringstream oss;
oss
<< "Host Total: "
<< iostreamLongLong(this->GetHostMemoryTotal())
@@ -820,6 +821,11 @@ SystemInformation::LongLong SystemInformation::GetProcMemoryUsed()
return this->Implementation->GetProcMemoryUsed();
}
+double SystemInformation::GetLoadAverage()
+{
+ return this->Implementation->GetLoadAverage();
+}
+
SystemInformation::LongLong SystemInformation::GetProcessId()
{
return this->Implementation->GetProcessId();
@@ -830,7 +836,7 @@ void SystemInformation::SetStackTraceOnError(int enable)
SystemInformationImplementation::SetStackTraceOnError(enable);
}
-kwsys_stl::string SystemInformation::GetProgramStack(int firstFrame, int wholePath)
+std::string SystemInformation::GetProgramStack(int firstFrame, int wholePath)
{
return SystemInformationImplementation::GetProgramStack(firstFrame, wholePath);
}
@@ -914,7 +920,7 @@ namespace {
#if defined(__linux) || defined(__APPLE__)
int LoadLines(
FILE *file,
- kwsys_stl::vector<kwsys_stl::string> &lines)
+ std::vector<std::string> &lines)
{
// Load each line in the given file into a the vector.
int nRead=0;
@@ -951,7 +957,7 @@ int LoadLines(
// *****************************************************************************
int LoadLines(
const char *fileName,
- kwsys_stl::vector<kwsys_stl::string> &lines)
+ std::vector<std::string> &lines)
{
FILE *file=fopen(fileName,"r");
if (file==0)
@@ -967,18 +973,18 @@ int LoadLines(
// ****************************************************************************
template<typename T>
int NameValue(
- kwsys_stl::vector<kwsys_stl::string> &lines,
- kwsys_stl::string name, T &value)
+ std::vector<std::string> &lines,
+ std::string name, T &value)
{
size_t nLines=lines.size();
for (size_t i=0; i<nLines; ++i)
{
size_t at=lines[i].find(name);
- if (at==kwsys_stl::string::npos)
+ if (at==std::string::npos)
{
continue;
}
- kwsys_ios::istringstream is(lines[i].substr(at+name.size()));
+ std::istringstream is(lines[i].substr(at+name.size()));
is >> value;
return 0;
}
@@ -994,7 +1000,7 @@ int GetFieldsFromFile(
const char **fieldNames,
T *values)
{
- kwsys_stl::vector<kwsys_stl::string> fields;
+ std::vector<std::string> fields;
if (!LoadLines(fileName,fields))
{
return -1;
@@ -1044,7 +1050,7 @@ int GetFieldsFromCommand(
{
return -1;
}
- kwsys_stl::vector<kwsys_stl::string> fields;
+ std::vector<std::string> fields;
int nl=LoadLines(file,fields);
pclose(file);
if (nl==0)
@@ -1073,10 +1079,10 @@ void StacktraceSignalHandler(
void * /*sigContext*/)
{
#if defined(__linux) || defined(__APPLE__)
- kwsys_ios::ostringstream oss;
+ std::ostringstream oss;
oss
- << kwsys_ios::endl
- << "=========================================================" << kwsys_ios::endl
+ << std::endl
+ << "=========================================================" << std::endl
<< "Process id " << getpid() << " ";
switch (sigNo)
{
@@ -1234,6 +1240,7 @@ void StacktraceSignalHandler(
case ILL_ILLTRP:
oss << "illegal trap";
+ break;
case ILL_PRVOPC:
oss << "privileged opcode";
@@ -1268,11 +1275,11 @@ void StacktraceSignalHandler(
break;
}
oss
- << kwsys_ios::endl
- << "Program Stack:" << kwsys_ios::endl
+ << std::endl
+ << "Program Stack:" << std::endl
<< SystemInformationImplementation::GetProgramStack(2,0)
- << "=========================================================" << kwsys_ios::endl;
- kwsys_ios::cerr << oss.str() << kwsys_ios::endl;
+ << "=========================================================" << std::endl;
+ std::cerr << oss.str() << std::endl;
// restore the previously registered handlers
// and abort
@@ -1317,7 +1324,7 @@ public:
void SetBinary(const char *binary)
{ this->Binary=safes(binary); }
- kwsys_stl::string GetBinary() const;
+ std::string GetBinary() const;
// Description:
// Set the name of the function that the symbol is found in.
@@ -1325,7 +1332,7 @@ public:
void SetFunction(const char *function)
{ this->Function=this->Demangle(function); }
- kwsys_stl::string GetFunction() const
+ std::string GetFunction() const
{ return this->Function; }
// Description:
@@ -1334,7 +1341,7 @@ public:
void SetSourceFile(const char *sourcefile)
{ this->SourceFile=safes(sourcefile); }
- kwsys_stl::string GetSourceFile() const
+ std::string GetSourceFile() const
{ return this->GetFileName(this->SourceFile); }
// Description:
@@ -1352,31 +1359,31 @@ private:
void *GetRealAddress() const
{ return (void*)((char*)this->Address-(char*)this->BinaryBaseAddress); }
- kwsys_stl::string GetFileName(const kwsys_stl::string &path) const;
- kwsys_stl::string Demangle(const char *symbol) const;
+ std::string GetFileName(const std::string &path) const;
+ std::string Demangle(const char *symbol) const;
private:
- kwsys_stl::string Binary;
+ std::string Binary;
void *BinaryBaseAddress;
void *Address;
- kwsys_stl::string SourceFile;
- kwsys_stl::string Function;
+ std::string SourceFile;
+ std::string Function;
long LineNumber;
int ReportPath;
};
// --------------------------------------------------------------------------
-kwsys_ios::ostream &operator<<(
- kwsys_ios::ostream &os,
+std::ostream &operator<<(
+ std::ostream &os,
const SymbolProperties &sp)
{
#if defined(KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP)
os
- << kwsys_ios::hex << sp.GetAddress() << " : "
+ << std::hex << sp.GetAddress() << " : "
<< sp.GetFunction()
<< " [(" << sp.GetBinary() << ") "
<< sp.GetSourceFile() << ":"
- << kwsys_ios::dec << sp.GetLineNumber() << "]";
+ << std::dec << sp.GetLineNumber() << "]";
#elif defined(KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE)
void *addr = sp.GetAddress();
char **syminfo = backtrace_symbols(&addr,1);
@@ -1409,28 +1416,28 @@ SymbolProperties::SymbolProperties()
}
// --------------------------------------------------------------------------
-kwsys_stl::string SymbolProperties::GetFileName(const kwsys_stl::string &path) const
+std::string SymbolProperties::GetFileName(const std::string &path) const
{
- kwsys_stl::string file(path);
+ std::string file(path);
if (!this->ReportPath)
{
size_t at = file.rfind("/");
- if (at!=kwsys_stl::string::npos)
+ if (at!=std::string::npos)
{
- file = file.substr(at+1,kwsys_stl::string::npos);
+ file = file.substr(at+1,std::string::npos);
}
}
return file;
}
// --------------------------------------------------------------------------
-kwsys_stl::string SymbolProperties::GetBinary() const
+std::string SymbolProperties::GetBinary() const
{
// only linux has proc fs
#if defined(__linux__)
if (this->Binary=="/proc/self/exe")
{
- kwsys_stl::string binary;
+ std::string binary;
char buf[1024]={'\0'};
ssize_t ll=0;
if ((ll=readlink("/proc/self/exe",buf,1024))>0)
@@ -1449,9 +1456,9 @@ kwsys_stl::string SymbolProperties::GetBinary() const
}
// --------------------------------------------------------------------------
-kwsys_stl::string SymbolProperties::Demangle(const char *symbol) const
+std::string SymbolProperties::Demangle(const char *symbol) const
{
- kwsys_stl::string result = safes(symbol);
+ std::string result = safes(symbol);
#if defined(KWSYS_SYSTEMINFORMATION_HAS_CPP_DEMANGLE)
int status = 0;
size_t bufferLen = 1024;
@@ -1489,6 +1496,60 @@ void SymbolProperties::Initialize(void *address)
}
#endif // don't define this class if we're not using it
+// --------------------------------------------------------------------------
+#if defined(_WIN32) || defined(__CYGWIN__)
+# define KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes
+#endif
+#if defined(_MSC_VER) && _MSC_VER < 1310
+# undef KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes
+#endif
+#if defined(KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes)
+double calculateCPULoad(unsigned __int64 idleTicks,
+ unsigned __int64 totalTicks)
+{
+ static double previousLoad = -0.0;
+ static unsigned __int64 previousIdleTicks = 0;
+ static unsigned __int64 previousTotalTicks = 0;
+
+ unsigned __int64 const idleTicksSinceLastTime =
+ idleTicks - previousIdleTicks;
+ unsigned __int64 const totalTicksSinceLastTime =
+ totalTicks - previousTotalTicks;
+
+ double load;
+ if (previousTotalTicks == 0 || totalTicksSinceLastTime == 0)
+ {
+ // No new information. Use previous result.
+ load = previousLoad;
+ }
+ else
+ {
+ // Calculate load since last time.
+ load = 1.0 - double(idleTicksSinceLastTime) / totalTicksSinceLastTime;
+
+ // Smooth if possible.
+ if (previousLoad > 0)
+ {
+ load = 0.25 * load + 0.75 * previousLoad;
+ }
+ }
+
+ previousLoad = load;
+ previousIdleTicks = idleTicks;
+ previousTotalTicks = totalTicks;
+
+ return load;
+}
+
+unsigned __int64 fileTimeToUInt64(FILETIME const& ft)
+{
+ LARGE_INTEGER out;
+ out.HighPart = ft.dwHighDateTime;
+ out.LowPart = ft.dwLowDateTime;
+ return out.QuadPart;
+}
+#endif
+
} // anonymous namespace
@@ -1662,7 +1723,7 @@ const char* SystemInformationImplementation::GetHostname()
/** Get the FQDN */
int SystemInformationImplementation::GetFullyQualifiedDomainName(
- kwsys_stl::string &fqdn)
+ std::string &fqdn)
{
// in the event of absolute failure return localhost.
fqdn="localhost";
@@ -1734,12 +1795,12 @@ int SystemInformationImplementation::GetFullyQualifiedDomainName(
{
char host[NI_MAXHOST]={'\0'};
- socklen_t addrlen
+ const size_t addrlen
= (fam==AF_INET?sizeof(struct sockaddr_in):sizeof(struct sockaddr_in6));
ierr=getnameinfo(
ifa->ifa_addr,
- addrlen,
+ static_cast<socklen_t>(addrlen),
host,
NI_MAXHOST,
NULL,
@@ -1753,8 +1814,8 @@ int SystemInformationImplementation::GetFullyQualifiedDomainName(
continue;
}
- kwsys_stl::string candidate=host;
- if ((candidate.find(base)!=kwsys_stl::string::npos) && baseSize<candidate.size())
+ std::string candidate=host;
+ if ((candidate.find(base)!=std::string::npos) && baseSize<candidate.size())
{
// success, stop now.
ierr=0;
@@ -1823,45 +1884,46 @@ const char * SystemInformationImplementation::GetVendorID()
return "Motorola";
case HP:
return "Hewlett-Packard";
+ case UnknownManufacturer:
default:
return "Unknown Manufacturer";
}
}
/** Return the type ID of the CPU */
-kwsys_stl::string SystemInformationImplementation::GetTypeID()
+std::string SystemInformationImplementation::GetTypeID()
{
- kwsys_ios::ostringstream str;
+ std::ostringstream str;
str << this->ChipID.Type;
return str.str();
}
/** Return the family of the CPU present */
-kwsys_stl::string SystemInformationImplementation::GetFamilyID()
+std::string SystemInformationImplementation::GetFamilyID()
{
- kwsys_ios::ostringstream str;
+ std::ostringstream str;
str << this->ChipID.Family;
return str.str();
}
// Return the model of CPU present */
-kwsys_stl::string SystemInformationImplementation::GetModelID()
+std::string SystemInformationImplementation::GetModelID()
{
- kwsys_ios::ostringstream str;
+ std::ostringstream str;
str << this->ChipID.Model;
return str.str();
}
// Return the model name of CPU present */
-kwsys_stl::string SystemInformationImplementation::GetModelName()
+std::string SystemInformationImplementation::GetModelName()
{
return this->ChipID.ModelName;
}
/** Return the stepping code of the CPU present. */
-kwsys_stl::string SystemInformationImplementation::GetSteppingCode()
+std::string SystemInformationImplementation::GetSteppingCode()
{
- kwsys_ios::ostringstream str;
+ std::ostringstream str;
str << this->ChipID.Revision;
return str.str();
}
@@ -2112,7 +2174,7 @@ bool SystemInformationImplementation::RetrieveCPUFeatures()
/** Find the manufacturer given the vendor id */
-void SystemInformationImplementation::FindManufacturer(const kwsys_stl::string& family)
+void SystemInformationImplementation::FindManufacturer(const std::string& family)
{
if (this->ChipID.Vendor == "GenuineIntel") this->ChipManufacturer = Intel; // Intel Corp.
else if (this->ChipID.Vendor == "UMC UMC UMC ") this->ChipManufacturer = UMC; // United Microelectronics Corp.
@@ -2445,8 +2507,8 @@ bool SystemInformationImplementation::RetrieveCPUClockSpeed()
if (!retrieved)
{
HKEY hKey = NULL;
- LONG err = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0,
+ LONG err = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0,
KEY_READ, &hKey);
if (ERROR_SUCCESS == err)
@@ -2455,7 +2517,7 @@ bool SystemInformationImplementation::RetrieveCPUClockSpeed()
DWORD data = 0;
DWORD dwSize = sizeof(DWORD);
- err = RegQueryValueEx(hKey, "~MHz", 0,
+ err = RegQueryValueExW(hKey, L"~MHz", 0,
&dwType, (LPBYTE) &data, &dwSize);
if (ERROR_SUCCESS == err)
@@ -2731,11 +2793,11 @@ bool SystemInformationImplementation::RetrieveCPUPowerManagement()
#if USE_CPUID
// Used only in USE_CPUID implementation below.
-static void SystemInformationStripLeadingSpace(kwsys_stl::string& str)
+static void SystemInformationStripLeadingSpace(std::string& str)
{
// Because some manufacturers have leading white space - we have to post-process the name.
- kwsys_stl::string::size_type pos = str.find_first_not_of(" ");
- if(pos != kwsys_stl::string::npos)
+ std::string::size_type pos = str.find_first_not_of(" ");
+ if(pos != std::string::npos)
{
str = str.substr(pos);
}
@@ -3064,6 +3126,12 @@ bool SystemInformationImplementation::RetrieveClassicalCPUIdentity()
case NSC:
this->ChipID.ProcessorName = "Cx486SLC \\ DLC \\ Cx486S A-Step";
break;
+
+ case Sun:
+ case IBM:
+ case Motorola:
+ case HP:
+ case UnknownManufacturer:
default:
this->ChipID.ProcessorName = "Unknown family"; // We cannot identify the processor.
return false;
@@ -3074,7 +3142,7 @@ bool SystemInformationImplementation::RetrieveClassicalCPUIdentity()
/** Extract a value from the CPUInfo file */
-kwsys_stl::string SystemInformationImplementation::ExtractValueFromCpuInfoFile(kwsys_stl::string buffer,const char* word,size_t init)
+std::string SystemInformationImplementation::ExtractValueFromCpuInfoFile(std::string buffer,const char* word,size_t init)
{
size_t pos = buffer.find(word,init);
if(pos != buffer.npos)
@@ -3106,12 +3174,12 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
{
this->NumberOfLogicalCPU = 0;
this->NumberOfPhysicalCPU = 0;
- kwsys_stl::string buffer;
+ std::string buffer;
FILE *fd = fopen("/proc/cpuinfo", "r" );
if ( !fd )
{
- kwsys_ios::cout << "Problem opening /proc/cpuinfo" << kwsys_ios::endl;
+ std::cout << "Problem opening /proc/cpuinfo" << std::endl;
return false;
}
@@ -3135,7 +3203,7 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
#ifdef __linux
// Find the largest physical id.
int maxId = -1;
- kwsys_stl::string idc =
+ std::string idc =
this->ExtractValueFromCpuInfoFile(buffer,"physical id");
while(this->CurrentPositionInFile != buffer.npos)
{
@@ -3150,16 +3218,25 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
// Physical ids returned by Linux don't distinguish cores.
// We want to record the total number of cores in this->NumberOfPhysicalCPU
// (checking only the first proc)
- kwsys_stl::string cores =
+ std::string cores =
this->ExtractValueFromCpuInfoFile(buffer,"cpu cores");
int numberOfCoresPerCPU=atoi(cores.c_str());
- this->NumberOfPhysicalCPU=static_cast<unsigned int>(
- numberOfCoresPerCPU*(maxId+1));
+ if (maxId > 0)
+ {
+ this->NumberOfPhysicalCPU=static_cast<unsigned int>(
+ numberOfCoresPerCPU*(maxId+1));
+ }
+ else
+ {
+ // Linux Sparc: get cpu count
+ this->NumberOfPhysicalCPU=
+ atoi(this->ExtractValueFromCpuInfoFile(buffer,"ncpus active").c_str());
+ }
#else // __CYGWIN__
// does not have "physical id" entries, neither "cpu cores"
// this has to be fixed for hyper-threading.
- kwsys_stl::string cpucount =
+ std::string cpucount =
this->ExtractValueFromCpuInfoFile(buffer,"cpu count");
this->NumberOfPhysicalCPU=
this->NumberOfLogicalCPU = atoi(cpucount.c_str());
@@ -3175,11 +3252,23 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
this->NumberOfLogicalCPU/this->NumberOfPhysicalCPU;
// CPU speed (checking only the first processor)
- kwsys_stl::string CPUSpeed = this->ExtractValueFromCpuInfoFile(buffer,"cpu MHz");
- this->CPUSpeedInMHz = static_cast<float>(atof(CPUSpeed.c_str()));
+ std::string CPUSpeed = this->ExtractValueFromCpuInfoFile(buffer,"cpu MHz");
+ if(!CPUSpeed.empty())
+ {
+ this->CPUSpeedInMHz = static_cast<float>(atof(CPUSpeed.c_str()));
+ }
+#ifdef __linux
+ else
+ {
+ // Linux Sparc: CPU speed is in Hz and encoded in hexadecimal
+ CPUSpeed = this->ExtractValueFromCpuInfoFile(buffer,"Cpu0ClkTck");
+ this->CPUSpeedInMHz = static_cast<float>(
+ strtoull(CPUSpeed.c_str(),0,16))/1000000.0f;
+ }
+#endif
// Chip family
- kwsys_stl::string familyStr =
+ std::string familyStr =
this->ExtractValueFromCpuInfoFile(buffer,"cpu family");
if(familyStr.empty())
{
@@ -3209,7 +3298,7 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
{
// Some platforms (e.g. PA-RISC) tell us their CPU name here.
// Note: x86 does not.
- kwsys_stl::string cpuname = this->ExtractValueFromCpuInfoFile(buffer,"cpu");
+ std::string cpuname = this->ExtractValueFromCpuInfoFile(buffer,"cpu");
if(!cpuname.empty())
{
this->ChipID.ProcessorName = cpuname;
@@ -3217,7 +3306,7 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
}
// Chip revision
- kwsys_stl::string cpurev = this->ExtractValueFromCpuInfoFile(buffer,"stepping");
+ std::string cpurev = this->ExtractValueFromCpuInfoFile(buffer,"stepping");
if(cpurev.empty())
{
cpurev = this->ExtractValueFromCpuInfoFile(buffer,"CPU revision");
@@ -3230,7 +3319,7 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
// L1 Cache size
// Different architectures may show different names for the caches.
// Sum up everything we find.
- kwsys_stl::vector<const char*> cachename;
+ std::vector<const char*> cachename;
cachename.clear();
cachename.push_back("cache size"); // e.g. x86
@@ -3240,7 +3329,7 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
this->Features.L1CacheSize = 0;
for (size_t index = 0; index < cachename.size(); index ++)
{
- kwsys_stl::string cacheSize = this->ExtractValueFromCpuInfoFile(buffer,cachename[index]);
+ std::string cacheSize = this->ExtractValueFromCpuInfoFile(buffer,cachename[index]);
if (!cacheSize.empty())
{
pos = cacheSize.find(" KB");
@@ -3253,48 +3342,48 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
}
// processor feature flags (probably x86 specific)
- kwsys_stl::string cpuflags = this->ExtractValueFromCpuInfoFile(buffer,"flags");
+ std::string cpuflags = this->ExtractValueFromCpuInfoFile(buffer,"flags");
if(!cpurev.empty())
{
// now we can match every flags as space + flag + space
cpuflags = " " + cpuflags + " ";
- if ((cpuflags.find(" fpu ")!=kwsys_stl::string::npos))
+ if ((cpuflags.find(" fpu ")!=std::string::npos))
{
this->Features.HasFPU = true;
}
- if ((cpuflags.find(" tsc ")!=kwsys_stl::string::npos))
+ if ((cpuflags.find(" tsc ")!=std::string::npos))
{
this->Features.HasTSC = true;
}
- if ((cpuflags.find(" mmx ")!=kwsys_stl::string::npos))
+ if ((cpuflags.find(" mmx ")!=std::string::npos))
{
this->Features.HasMMX = true;
}
- if ((cpuflags.find(" sse ")!=kwsys_stl::string::npos))
+ if ((cpuflags.find(" sse ")!=std::string::npos))
{
this->Features.HasSSE = true;
}
- if ((cpuflags.find(" sse2 ")!=kwsys_stl::string::npos))
+ if ((cpuflags.find(" sse2 ")!=std::string::npos))
{
this->Features.HasSSE2 = true;
}
- if ((cpuflags.find(" apic ")!=kwsys_stl::string::npos))
+ if ((cpuflags.find(" apic ")!=std::string::npos))
{
this->Features.HasAPIC = true;
}
- if ((cpuflags.find(" cmov ")!=kwsys_stl::string::npos))
+ if ((cpuflags.find(" cmov ")!=std::string::npos))
{
this->Features.HasCMOV = true;
}
- if ((cpuflags.find(" mtrr ")!=kwsys_stl::string::npos))
+ if ((cpuflags.find(" mtrr ")!=std::string::npos))
{
this->Features.HasMTRR = true;
}
- if ((cpuflags.find(" acpi ")!=kwsys_stl::string::npos))
+ if ((cpuflags.find(" acpi ")!=std::string::npos))
{
this->Features.HasACPI = true;
}
- if ((cpuflags.find(" 3dnow ")!=kwsys_stl::string::npos))
+ if ((cpuflags.find(" 3dnow ")!=std::string::npos))
{
this->Features.ExtendedFeatures.Has3DNow = true;
}
@@ -3550,7 +3639,7 @@ SystemInformationImplementation::GetProcMemoryUsed()
#elif defined(__APPLE__)
SystemInformation::LongLong memUsed=0;
pid_t pid=getpid();
- kwsys_ios::ostringstream oss;
+ std::ostringstream oss;
oss << "ps -o rss= -p " << pid;
FILE *file=popen(oss.str().c_str(),"r");
if (file==0)
@@ -3575,7 +3664,7 @@ SystemInformationImplementation::GetProcMemoryUsed()
{
return -2;
}
- kwsys_ios::istringstream iss(oss.str());
+ std::istringstream iss(oss.str());
iss >> memUsed;
return memUsed;
#else
@@ -3583,6 +3672,38 @@ SystemInformationImplementation::GetProcMemoryUsed()
#endif
}
+double SystemInformationImplementation::GetLoadAverage()
+{
+#if defined(KWSYS_CXX_HAS_GETLOADAVG)
+ double loadavg[3] = { 0.0, 0.0, 0.0 };
+ if (getloadavg(loadavg, 3) > 0)
+ {
+ return loadavg[0];
+ }
+ return -0.0;
+#elif defined(KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes)
+ // Old windows.h headers do not provide GetSystemTimes.
+ typedef BOOL (WINAPI *GetSystemTimesType)(LPFILETIME, LPFILETIME,
+ LPFILETIME);
+ static GetSystemTimesType pGetSystemTimes =
+ (GetSystemTimesType)GetProcAddress(GetModuleHandleW(L"kernel32"),
+ "GetSystemTimes");
+ FILETIME idleTime, kernelTime, userTime;
+ if (pGetSystemTimes && pGetSystemTimes(&idleTime, &kernelTime, &userTime))
+ {
+ unsigned __int64 const idleTicks =
+ fileTimeToUInt64(idleTime);
+ unsigned __int64 const totalTicks =
+ fileTimeToUInt64(kernelTime) + fileTimeToUInt64(userTime);
+ return calculateCPULoad(idleTicks, totalTicks) * GetNumberOfPhysicalCPU();
+ }
+ return -0.0;
+#else
+ // Not implemented on this platform.
+ return -0.0;
+#endif
+}
+
/**
Get the process id of the running process.
*/
@@ -3602,11 +3723,11 @@ SystemInformationImplementation::GetProcessId()
return current program stack in a string
demangle cxx symbols if possible.
*/
-kwsys_stl::string SystemInformationImplementation::GetProgramStack(
+std::string SystemInformationImplementation::GetProgramStack(
int firstFrame,
int wholePath)
{
- kwsys_stl::string programStack = ""
+ std::string programStack = ""
#if !defined(KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE)
"WARNING: The stack could not be examined "
"because backtrace is not supported.\n"
@@ -3625,7 +3746,7 @@ kwsys_stl::string SystemInformationImplementation::GetProgramStack(
#endif
;
- kwsys_ios::ostringstream oss;
+ std::ostringstream oss;
#if defined(KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE)
void *stackSymbols[256];
int nFrames=backtrace(stackSymbols,256);
@@ -3634,7 +3755,7 @@ kwsys_stl::string SystemInformationImplementation::GetProgramStack(
SymbolProperties symProps;
symProps.SetReportPath(wholePath);
symProps.Initialize(stackSymbols[i]);
- oss << symProps << kwsys_ios::endl;
+ oss << symProps << std::endl;
}
#else
(void)firstFrame;
@@ -3679,7 +3800,10 @@ void SystemInformationImplementation::SetStackTraceOnError(int enable)
// install ours
struct sigaction sa;
sa.sa_sigaction=(SigAction)StacktraceSignalHandler;
- sa.sa_flags=SA_SIGINFO|SA_RESTART|SA_RESETHAND;
+ sa.sa_flags=SA_SIGINFO|SA_RESETHAND;
+# ifdef SA_RESTART
+ sa.sa_flags|=SA_RESTART;
+# endif
sigemptyset(&sa.sa_mask);
sigaction(SIGABRT,&sa,0);
@@ -3730,9 +3854,9 @@ bool SystemInformationImplementation::QueryWindowsMemory()
}
# define MEM_VAL(value) ull##value
# endif
- tv = ms.MEM_VAL(TotalVirtual);
+ tv = ms.MEM_VAL(TotalPageFile);
tp = ms.MEM_VAL(TotalPhys);
- av = ms.MEM_VAL(AvailVirtual);
+ av = ms.MEM_VAL(AvailPageFile);
ap = ms.MEM_VAL(AvailPhys);
this->TotalVirtualMemory = tv>>10>>10;
this->TotalPhysicalMemory = tp>>10>>10;
@@ -3762,11 +3886,11 @@ bool SystemInformationImplementation::QueryLinuxMemory()
int errorFlag = uname(&unameInfo);
if( errorFlag!=0 )
{
- kwsys_ios::cout << "Problem calling uname(): " << strerror(errno) << kwsys_ios::endl;
+ std::cout << "Problem calling uname(): " << strerror(errno) << std::endl;
return false;
}
- if( unameInfo.release!=0 && strlen(unameInfo.release)>=3 )
+ if( strlen(unameInfo.release)>=3 )
{
// release looks like "2.6.3-15mdk-i686-up-4GB"
char majorChar=unameInfo.release[0];
@@ -3786,7 +3910,7 @@ bool SystemInformationImplementation::QueryLinuxMemory()
FILE *fd = fopen("/proc/meminfo", "r" );
if ( !fd )
{
- kwsys_ios::cout << "Problem opening /proc/meminfo" << kwsys_ios::endl;
+ std::cout << "Problem opening /proc/meminfo" << std::endl;
return false;
}
@@ -3824,7 +3948,7 @@ bool SystemInformationImplementation::QueryLinuxMemory()
}
else
{
- kwsys_ios::cout << "Problem parsing /proc/meminfo" << kwsys_ios::endl;
+ std::cout << "Problem parsing /proc/meminfo" << std::endl;
fclose(fd);
return false;
}
@@ -3836,7 +3960,8 @@ bool SystemInformationImplementation::QueryLinuxMemory()
unsigned long temp;
unsigned long cachedMem;
unsigned long buffersMem;
- char *r=fgets(buffer, sizeof(buffer), fd); // Skip "total: used:..."
+ // Skip "total: used:..."
+ char *r=fgets(buffer, static_cast<int>(sizeof(buffer)), fd);
int status=0;
if(r==buffer)
{
@@ -3856,7 +3981,7 @@ bool SystemInformationImplementation::QueryLinuxMemory()
}
else
{
- kwsys_ios::cout << "Problem parsing /proc/meminfo" << kwsys_ios::endl;
+ std::cout << "Problem parsing /proc/meminfo" << std::endl;
fclose(fd);
return false;
}
@@ -3889,7 +4014,7 @@ bool SystemInformationImplementation::QueryCygwinMemory()
bool SystemInformationImplementation::QueryAIXMemory()
{
-#if defined(_AIX)
+#if defined(_AIX) && defined(_SC_AIX_REALMEM)
long c = sysconf(_SC_AIX_REALMEM);
if (c <= 0)
{
@@ -4333,8 +4458,8 @@ bool SystemInformationImplementation::ParseSysCtl()
::memset(retBuf, 0, 128);
len = 32;
err = sysctlbyname("hw.machine", &retBuf, &len, NULL, 0);
- kwsys_stl::string machineBuf(retBuf);
- if (machineBuf.find_first_of("Power") != kwsys_stl::string::npos)
+ std::string machineBuf(retBuf);
+ if (machineBuf.find_first_of("Power") != std::string::npos)
{
this->ChipID.Vendor = "IBM";
len = sizeof(this->ChipID.Family);
@@ -4396,41 +4521,41 @@ bool SystemInformationImplementation::ParseSysCtl()
{
// now we can match every flags as space + flag + space
buf[len + 1] = ' ';
- kwsys_stl::string cpuflags(buf, len + 2);
+ std::string cpuflags(buf, len + 2);
- if ((cpuflags.find(" FPU ")!=kwsys_stl::string::npos))
+ if ((cpuflags.find(" FPU ")!=std::string::npos))
{
this->Features.HasFPU = true;
}
- if ((cpuflags.find(" TSC ")!=kwsys_stl::string::npos))
+ if ((cpuflags.find(" TSC ")!=std::string::npos))
{
this->Features.HasTSC = true;
}
- if ((cpuflags.find(" MMX ")!=kwsys_stl::string::npos))
+ if ((cpuflags.find(" MMX ")!=std::string::npos))
{
this->Features.HasMMX = true;
}
- if ((cpuflags.find(" SSE ")!=kwsys_stl::string::npos))
+ if ((cpuflags.find(" SSE ")!=std::string::npos))
{
this->Features.HasSSE = true;
}
- if ((cpuflags.find(" SSE2 ")!=kwsys_stl::string::npos))
+ if ((cpuflags.find(" SSE2 ")!=std::string::npos))
{
this->Features.HasSSE2 = true;
}
- if ((cpuflags.find(" APIC ")!=kwsys_stl::string::npos))
+ if ((cpuflags.find(" APIC ")!=std::string::npos))
{
this->Features.HasAPIC = true;
}
- if ((cpuflags.find(" CMOV ")!=kwsys_stl::string::npos))
+ if ((cpuflags.find(" CMOV ")!=std::string::npos))
{
this->Features.HasCMOV = true;
}
- if ((cpuflags.find(" MTRR ")!=kwsys_stl::string::npos))
+ if ((cpuflags.find(" MTRR ")!=std::string::npos))
{
this->Features.HasMTRR = true;
}
- if ((cpuflags.find(" ACPI ")!=kwsys_stl::string::npos))
+ if ((cpuflags.find(" ACPI ")!=std::string::npos))
{
this->Features.HasACPI = true;
}
@@ -4464,7 +4589,7 @@ bool SystemInformationImplementation::ParseSysCtl()
/** Extract a value from sysctl command */
-kwsys_stl::string SystemInformationImplementation::ExtractValueFromSysCtl(const char* word)
+std::string SystemInformationImplementation::ExtractValueFromSysCtl(const char* word)
{
size_t pos = this->SysCtlBuffer.find(word);
if(pos != this->SysCtlBuffer.npos)
@@ -4481,9 +4606,9 @@ kwsys_stl::string SystemInformationImplementation::ExtractValueFromSysCtl(const
/** Run a given process */
-kwsys_stl::string SystemInformationImplementation::RunProcess(kwsys_stl::vector<const char*> args)
+std::string SystemInformationImplementation::RunProcess(std::vector<const char*> args)
{
- kwsys_stl::string buffer = "";
+ std::string buffer = "";
// Run the application
kwsysProcess* gp = kwsysProcess_New();
@@ -4513,12 +4638,12 @@ kwsys_stl::string SystemInformationImplementation::RunProcess(kwsys_stl::vector<
} break;
case kwsysProcess_State_Error:
{
- kwsys_ios::cerr << "Error: Could not run " << args[0] << ":\n";
- kwsys_ios::cerr << kwsysProcess_GetErrorString(gp) << "\n";
+ std::cerr << "Error: Could not run " << args[0] << ":\n";
+ std::cerr << kwsysProcess_GetErrorString(gp) << "\n";
} break;
case kwsysProcess_State_Exception:
{
- kwsys_ios::cerr << "Error: " << args[0]
+ std::cerr << "Error: " << args[0]
<< " terminated with an exception: "
<< kwsysProcess_GetExceptionString(gp) << "\n";
} break;
@@ -4528,27 +4653,27 @@ kwsys_stl::string SystemInformationImplementation::RunProcess(kwsys_stl::vector<
case kwsysProcess_State_Killed:
{
// Should not get here.
- kwsys_ios::cerr << "Unexpected ending state after running " << args[0]
- << kwsys_ios::endl;
+ std::cerr << "Unexpected ending state after running " << args[0]
+ << std::endl;
} break;
}
kwsysProcess_Delete(gp);
if(result)
{
- kwsys_ios::cerr << "Error " << args[0] << " returned :" << result << "\n";
+ std::cerr << "Error " << args[0] << " returned :" << result << "\n";
}
return buffer;
}
-kwsys_stl::string SystemInformationImplementation::ParseValueFromKStat(const char* arguments)
+std::string SystemInformationImplementation::ParseValueFromKStat(const char* arguments)
{
- kwsys_stl::vector<const char*> args;
+ std::vector<const char*> args;
args.clear();
args.push_back("kstat");
args.push_back("-p");
- kwsys_stl::string command = arguments;
+ std::string command = arguments;
size_t start = command.npos;
size_t pos = command.find(' ',0);
while(pos!=command.npos)
@@ -4570,7 +4695,7 @@ kwsys_stl::string SystemInformationImplementation::ParseValueFromKStat(const cha
if(!inQuotes)
{
- kwsys_stl::string arg = command.substr(start+1,pos-start-1);
+ std::string arg = command.substr(start+1,pos-start-1);
// Remove the quotes if any
size_t quotes = arg.find('"');
@@ -4584,14 +4709,14 @@ kwsys_stl::string SystemInformationImplementation::ParseValueFromKStat(const cha
}
pos = command.find(' ',pos+1);
}
- kwsys_stl::string lastArg = command.substr(start+1,command.size()-start-1);
+ std::string lastArg = command.substr(start+1,command.size()-start-1);
args.push_back(lastArg.c_str());
args.push_back(0);
- kwsys_stl::string buffer = this->RunProcess(args);
+ std::string buffer = this->RunProcess(args);
- kwsys_stl::string value = "";
+ std::string value = "";
for(size_t i=buffer.size()-1;i>0;i--)
{
if(buffer[i] == ' ' || buffer[i] == '\t')
@@ -4600,7 +4725,7 @@ kwsys_stl::string SystemInformationImplementation::ParseValueFromKStat(const cha
}
if(buffer[i] != '\n' && buffer[i] != '\r')
{
- kwsys_stl::string val = value;
+ std::string val = value;
value = buffer[i];
value += val;
}
@@ -4667,11 +4792,28 @@ bool SystemInformationImplementation::QueryHaikuInfo()
{
#if defined(__HAIKU__)
+ // CPU count
system_info info;
get_system_info(&info);
-
this->NumberOfPhysicalCPU = info.cpu_count;
- this->CPUSpeedInMHz = info.cpu_clock_speed / 1000000.0F;
+
+ // CPU speed
+ uint32 topologyNodeCount = 0;
+ cpu_topology_node_info* topology = 0;
+ get_cpu_topology_info(0, &topologyNodeCount);
+ if (topologyNodeCount != 0)
+ topology = new cpu_topology_node_info[topologyNodeCount];
+ get_cpu_topology_info(topology, &topologyNodeCount);
+
+ for (uint32 i = 0; i < topologyNodeCount; i++) {
+ if (topology[i].type == B_TOPOLOGY_CORE) {
+ this->CPUSpeedInMHz = topology[i].data.core.default_frequency /
+ 1000000.0f;
+ break;
+ }
+ }
+
+ delete[] topology;
// Physical Memory
this->TotalPhysicalMemory = (info.max_pages * B_PAGE_SIZE) / (1024 * 1024) ;
@@ -4737,8 +4879,8 @@ bool SystemInformationImplementation::QueryHaikuInfo()
bool SystemInformationImplementation::QueryQNXMemory()
{
#if defined(__QNX__)
- kwsys_stl::string buffer;
- kwsys_stl::vector<const char*> args;
+ std::string buffer;
+ std::vector<const char*> args;
args.clear();
args.push_back("showmem");
@@ -4795,8 +4937,8 @@ bool SystemInformationImplementation::QueryQNXProcessor()
#if defined(__QNX__)
// the output on my QNX 6.4.1 looks like this:
// Processor1: 686 Pentium II Stepping 3 2175MHz FPU
- kwsys_stl::string buffer;
- kwsys_stl::vector<const char*> args;
+ std::string buffer;
+ std::vector<const char*> args;
args.clear();
args.push_back("pidin");
@@ -4975,16 +5117,26 @@ bool SystemInformationImplementation::QueryHPUXProcessor()
case CPU_PA_RISC1_0:
this->ChipID.Vendor = "Hewlett-Packard";
this->ChipID.Family = 0x100;
+ break;
case CPU_PA_RISC1_1:
this->ChipID.Vendor = "Hewlett-Packard";
this->ChipID.Family = 0x110;
+ break;
case CPU_PA_RISC2_0:
this->ChipID.Vendor = "Hewlett-Packard";
this->ChipID.Family = 0x200;
+ break;
+# if defined(CPU_HP_INTEL_EM_1_0) || defined(CPU_IA64_ARCHREV_0)
+# ifdef CPU_HP_INTEL_EM_1_0
+ case CPU_HP_INTEL_EM_1_0:
+# endif
+# ifdef CPU_IA64_ARCHREV_0
case CPU_IA64_ARCHREV_0:
+# endif
this->ChipID.Vendor = "GenuineIntel";
this->Features.HasIA64 = true;
break;
+# endif
default:
return false;
}
@@ -5007,23 +5159,34 @@ bool SystemInformationImplementation::QueryOSInformation()
this->OSName = "Windows";
- OSVERSIONINFOEX osvi;
+ OSVERSIONINFOEXW osvi;
BOOL bIsWindows64Bit;
BOOL bOsVersionInfoEx;
char operatingSystem[256];
// Try calling GetVersionEx using the OSVERSIONINFOEX structure.
- ZeroMemory (&osvi, sizeof (OSVERSIONINFOEX));
- osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
- bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi);
+ ZeroMemory (&osvi, sizeof (OSVERSIONINFOEXW));
+ osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEXW);
+#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
+# pragma warning (push)
+# ifdef __INTEL_COMPILER
+# pragma warning (disable:1478)
+# else
+# pragma warning (disable:4996)
+# endif
+#endif
+ bOsVersionInfoEx = GetVersionExW ((OSVERSIONINFOW*)&osvi);
if (!bOsVersionInfoEx)
{
- osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
- if (!GetVersionEx ((OSVERSIONINFO *) &osvi))
+ osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOW);
+ if (!GetVersionExW((OSVERSIONINFOW*)&osvi))
{
return false;
}
}
+#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
+# pragma warning (pop)
+#endif
switch (osvi.dwPlatformId)
{
@@ -5098,26 +5261,26 @@ bool SystemInformationImplementation::QueryOSInformation()
}
}
- sprintf (operatingSystem, "%s (Build %ld)", osvi.szCSDVersion, osvi.dwBuildNumber & 0xFFFF);
+ sprintf (operatingSystem, "%ls (Build %ld)", osvi.szCSDVersion, osvi.dwBuildNumber & 0xFFFF);
this->OSVersion = operatingSystem;
}
else
#endif // VER_NT_WORKSTATION
{
HKEY hKey;
- char szProductType[80];
+ wchar_t szProductType[80];
DWORD dwBufLen;
// Query the registry to retrieve information.
- RegOpenKeyEx (HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\ProductOptions", 0, KEY_QUERY_VALUE, &hKey);
- RegQueryValueEx (hKey, "ProductType", NULL, NULL, (LPBYTE) szProductType, &dwBufLen);
+ RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions", 0, KEY_QUERY_VALUE, &hKey);
+ RegQueryValueExW(hKey, L"ProductType", NULL, NULL, (LPBYTE) szProductType, &dwBufLen);
RegCloseKey (hKey);
- if (lstrcmpi ("WINNT", szProductType) == 0)
+ if (lstrcmpiW(L"WINNT", szProductType) == 0)
{
this->OSRelease += " Professional";
}
- if (lstrcmpi ("LANMANNT", szProductType) == 0)
+ if (lstrcmpiW(L"LANMANNT", szProductType) == 0)
{
// Decide between Windows 2000 Advanced Server and Windows .NET Enterprise Server.
if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
@@ -5129,7 +5292,7 @@ bool SystemInformationImplementation::QueryOSInformation()
this->OSRelease += " Server";
}
}
- if (lstrcmpi ("SERVERNT", szProductType) == 0)
+ if (lstrcmpiW(L"SERVERNT", szProductType) == 0)
{
// Decide between Windows 2000 Advanced Server and Windows .NET Enterprise Server.
if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
@@ -5147,7 +5310,7 @@ bool SystemInformationImplementation::QueryOSInformation()
if (osvi.dwMajorVersion <= 4)
{
// NB: NT 4.0 and earlier.
- sprintf (operatingSystem, "version %ld.%ld %s (Build %ld)",
+ sprintf (operatingSystem, "version %ld.%ld %ls (Build %ld)",
osvi.dwMajorVersion,
osvi.dwMinorVersion,
osvi.szCSDVersion,
@@ -5162,7 +5325,7 @@ bool SystemInformationImplementation::QueryOSInformation()
LPFNPROC DLLProc;
// Load the Kernel32 DLL.
- hKernelDLL = LoadLibrary ("kernel32");
+ hKernelDLL = LoadLibraryW(L"kernel32");
if (hKernelDLL != NULL) {
// Only XP and .NET Server support IsWOW64Process so... Load dynamically!
DLLProc = (LPFNPROC) GetProcAddress (hKernelDLL, "IsWow64Process");
@@ -5178,7 +5341,7 @@ bool SystemInformationImplementation::QueryOSInformation()
else
{
// Windows 2000 and everything else.
- sprintf (operatingSystem,"%s (Build %ld)", osvi.szCSDVersion, osvi.dwBuildNumber & 0xFFFF);
+ sprintf (operatingSystem,"%ls (Build %ld)", osvi.szCSDVersion, osvi.dwBuildNumber & 0xFFFF);
this->OSVersion = operatingSystem;
}
break;
@@ -5271,10 +5434,10 @@ bool SystemInformationImplementation::QueryOSInformation()
int SystemInformationImplementation::CallSwVers(
const char *arg,
- kwsys_stl::string &ver)
+ std::string &ver)
{
#ifdef __APPLE__
- kwsys_stl::vector<const char*> args;
+ std::vector<const char*> args;
args.push_back("sw_vers");
args.push_back(arg);
args.push_back(0);
@@ -5288,18 +5451,18 @@ int SystemInformationImplementation::CallSwVers(
return 0;
}
-void SystemInformationImplementation::TrimNewline(kwsys_stl::string& output)
+void SystemInformationImplementation::TrimNewline(std::string& output)
{
// remove \r
- kwsys_stl::string::size_type pos=0;
- while((pos = output.find("\r", pos)) != kwsys_stl::string::npos)
+ std::string::size_type pos=0;
+ while((pos = output.find("\r", pos)) != std::string::npos)
{
output.erase(pos);
}
// remove \n
pos = 0;
- while((pos = output.find("\n", pos)) != kwsys_stl::string::npos)
+ while((pos = output.find("\n", pos)) != std::string::npos)
{
output.erase(pos);
}
diff --git a/Source/kwsys/SystemInformation.hxx.in b/Source/kwsys/SystemInformation.hxx.in
index a9fd05def..7c453887e 100644
--- a/Source/kwsys/SystemInformation.hxx.in
+++ b/Source/kwsys/SystemInformation.hxx.in
@@ -12,14 +12,9 @@
#ifndef @KWSYS_NAMESPACE@_SystemInformation_h
#define @KWSYS_NAMESPACE@_SystemInformation_h
-
-/* Define these macros temporarily to keep the code readable. */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
-# define kwsys_stl @KWSYS_NAMESPACE@_stl
-# define kwsys_ios @KWSYS_NAMESPACE@_ios
-#endif
-#include <@KWSYS_NAMESPACE@/stl/string>
+#include <@KWSYS_NAMESPACE@/Configure.hxx>
#include <stddef.h> /* size_t */
+#include <string>
namespace @KWSYS_NAMESPACE@
{
@@ -45,11 +40,11 @@ public:
const char * GetVendorString();
const char * GetVendorID();
- kwsys_stl::string GetTypeID();
- kwsys_stl::string GetFamilyID();
- kwsys_stl::string GetModelID();
- kwsys_stl::string GetModelName();
- kwsys_stl::string GetSteppingCode();
+ std::string GetTypeID();
+ std::string GetFamilyID();
+ std::string GetModelID();
+ std::string GetModelName();
+ std::string GetSteppingCode();
const char * GetExtendedProcessorName();
const char * GetProcessorSerialNumber();
int GetProcessorCacheSize();
@@ -61,10 +56,10 @@ public:
// returns an informative general description of the cpu
// on this system.
- kwsys_stl::string GetCPUDescription();
+ std::string GetCPUDescription();
const char * GetHostname();
- kwsys_stl::string GetFullyQualifiedDomainName();
+ std::string GetFullyQualifiedDomainName();
const char * GetOSName();
const char * GetOSRelease();
@@ -77,7 +72,7 @@ public:
// returns an informative general description of the os
// on this system.
- kwsys_stl::string GetOSDescription();
+ std::string GetOSDescription();
bool Is64Bits();
@@ -98,7 +93,7 @@ public:
// returns an informative general description if the installed and
// available ram on this system. See the GetHostMmeoryTotal, and
// Get{Host,Proc}MemoryAvailable methods for more information.
- kwsys_stl::string GetMemoryDescription(
+ std::string GetMemoryDescription(
const char *hostLimitEnvVarName=NULL,
const char *procLimitEnvVarName=NULL);
@@ -130,6 +125,10 @@ public:
// Get system RAM used by this process id in units of KiB.
LongLong GetProcMemoryUsed();
+ // Return the load average of the machine or -0.0 if it cannot
+ // be determined.
+ double GetLoadAverage();
+
// enable/disable stack trace signal handler. In order to
// produce an informative stack trace the application should
// be dynamically linked and compiled with debug symbols.
@@ -140,7 +139,7 @@ public:
// order to produce an informative stack trace the application
// should be dynamically linked and compiled with debug symbols.
static
- kwsys_stl::string GetProgramStack(int firstFrame, int wholePath);
+ std::string GetProgramStack(int firstFrame, int wholePath);
/** Run the different checks */
void RunCPUCheck();
@@ -150,10 +149,4 @@ public:
} // namespace @KWSYS_NAMESPACE@
-/* Undefine temporary macros. */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
-# undef kwsys_stl
-# undef kwsys_ios
-#endif
-
#endif
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index e9a1fd37d..e3428f878 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -16,25 +16,33 @@
# define _XOPEN_SOURCE_EXTENDED
#endif
+#if defined(_WIN32) && (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__MINGW32__))
+# define KWSYS_WINDOWS_DIRS
+#else
+# if defined(__SUNPRO_CC)
+# include <fcntl.h>
+# endif
+#endif
+
#include "kwsysPrivate.h"
#include KWSYS_HEADER(RegularExpression.hxx)
#include KWSYS_HEADER(SystemTools.hxx)
#include KWSYS_HEADER(Directory.hxx)
+#include KWSYS_HEADER(FStream.hxx)
+#include KWSYS_HEADER(Encoding.hxx)
-#include KWSYS_HEADER(ios/iostream)
-#include KWSYS_HEADER(ios/fstream)
-#include KWSYS_HEADER(ios/sstream)
-
-#include KWSYS_HEADER(stl/set)
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <set>
// Work-around CMake dependency scanning limitation. This must
// duplicate the above list of headers.
#if 0
# include "SystemTools.hxx.in"
# include "Directory.hxx.in"
-# include "kwsys_ios_iostream.h.in"
-# include "kwsys_ios_fstream.h.in"
-# include "kwsys_ios_sstream.h.in"
+# include "FStream.hxx.in"
+# include "Encoding.hxx.in"
#endif
#ifdef _MSC_VER
@@ -56,6 +64,10 @@
#include <sys/stat.h>
#include <time.h>
+#ifdef _MSC_VER
+# define umask _umask // Note this is still umask on Borland
+#endif
+
// support for realpath call
#ifndef _WIN32
#include <sys/time.h>
@@ -75,6 +87,12 @@
// Windows API.
#if defined(_WIN32)
# include <windows.h>
+# ifndef INVALID_FILE_ATTRIBUTES
+# define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
+# endif
+# if defined(_MSC_VER) && _MSC_VER >= 1800
+# define KWSYS_WINDOWS_DEPRECATED_GetVersionEx
+# endif
#elif defined (__CYGWIN__)
# include <windows.h>
# undef _WIN32
@@ -85,7 +103,7 @@ extern char **environ;
#endif
#ifdef __CYGWIN__
-extern "C" void cygwin_conv_to_win32_path(const char *path, char *win32_path);
+# include <sys/cygwin.h>
#endif
// getpwnam doesn't exist on Windows and Cray Xt3/Catamount
@@ -152,11 +170,6 @@ public:
#define _chdir chdir
#endif
-#if defined(__HAIKU__)
-#include <os/kernel/OS.h>
-#include <os/storage/Path.h>
-#endif
-
#if defined(__BEOS__) && !defined(__ZETA__)
#include <be/kernel/OS.h>
#include <be/storage/Path.h>
@@ -185,45 +198,98 @@ static inline char *realpath(const char *path, char *resolved_path)
}
#endif
-#if defined(_WIN32) && (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__MINGW32__))
-inline int Mkdir(const char* dir)
+#ifdef _WIN32
+static time_t windows_filetime_to_posix_time(const FILETIME& ft)
{
- return _mkdir(dir);
+ LARGE_INTEGER date;
+ date.HighPart = ft.dwHighDateTime;
+ date.LowPart = ft.dwLowDateTime;
+
+ // removes the diff between 1970 and 1601
+ date.QuadPart -= ((LONGLONG)(369 * 365 + 89) * 24 * 3600 * 10000000);
+
+ // converts back from 100-nanoseconds to seconds
+ return date.QuadPart / 10000000;
}
-inline int Rmdir(const char* dir)
+#endif
+
+#ifdef KWSYS_WINDOWS_DIRS
+#include <wctype.h>
+
+inline int Mkdir(const std::string& dir)
+{
+ return _wmkdir(
+ KWSYS_NAMESPACE::SystemTools::ConvertToWindowsExtendedPath(dir).c_str());
+}
+inline int Rmdir(const std::string& dir)
{
- return _rmdir(dir);
+ return _wrmdir(
+ KWSYS_NAMESPACE::SystemTools::ConvertToWindowsExtendedPath(dir).c_str());
}
inline const char* Getcwd(char* buf, unsigned int len)
{
- if(const char* ret = _getcwd(buf, len))
+ std::vector<wchar_t> w_buf(len);
+ if(_wgetcwd(&w_buf[0], len))
{
// make sure the drive letter is capital
- if(strlen(buf) > 1 && buf[1] == ':')
+ if(wcslen(&w_buf[0]) > 1 && w_buf[1] == L':')
{
- buf[0] = toupper(buf[0]);
+ w_buf[0] = towupper(w_buf[0]);
}
- return ret;
+ std::string tmp = KWSYS_NAMESPACE::Encoding::ToNarrow(&w_buf[0]);
+ strcpy(buf, tmp.c_str());
+ return buf;
}
return 0;
}
-inline int Chdir(const char* dir)
+inline int Chdir(const std::string& dir)
{
#if defined(__BORLANDC__)
- return chdir(dir);
+ return chdir(dir.c_str());
#else
- return _chdir(dir);
+ return _wchdir(KWSYS_NAMESPACE::Encoding::ToWide(dir).c_str());
#endif
}
-inline void Realpath(const char *path, kwsys_stl::string & resolved_path)
+inline void Realpath(const std::string& path,
+ std::string& resolved_path,
+ std::string* errorMessage = 0)
{
- char *ptemp;
- char fullpath[MAX_PATH];
- if( GetFullPathName(path, sizeof(fullpath), fullpath, &ptemp) )
+ std::wstring tmp = KWSYS_NAMESPACE::Encoding::ToWide(path);
+ wchar_t *ptemp;
+ wchar_t fullpath[MAX_PATH];
+ DWORD bufferLen = GetFullPathNameW(tmp.c_str(),
+ sizeof(fullpath) / sizeof(fullpath[0]),
+ fullpath, &ptemp);
+ if( bufferLen < sizeof(fullpath)/sizeof(fullpath[0]) )
{
- resolved_path = fullpath;
+ resolved_path = KWSYS_NAMESPACE::Encoding::ToNarrow(fullpath);
KWSYS_NAMESPACE::SystemTools::ConvertToUnixSlashes(resolved_path);
}
+ else if(errorMessage)
+ {
+ if(bufferLen)
+ {
+ *errorMessage = "Destination path buffer size too small.";
+ }
+ else if(unsigned int errorId = GetLastError())
+ {
+ LPSTR message = NULL;
+ DWORD size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER
+ | FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, errorId,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPSTR)&message, 0, NULL);
+ *errorMessage = std::string(message, size);
+ LocalFree(message);
+ }
+ else
+ {
+ *errorMessage = "Unknown error.";
+ }
+
+ resolved_path = "";
+ }
else
{
resolved_path = path;
@@ -233,32 +299,48 @@ inline void Realpath(const char *path, kwsys_stl::string & resolved_path)
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
-inline int Mkdir(const char* dir)
+inline int Mkdir(const std::string& dir)
{
- return mkdir(dir, 00777);
+ return mkdir(dir.c_str(), 00777);
}
-inline int Rmdir(const char* dir)
+inline int Rmdir(const std::string& dir)
{
- return rmdir(dir);
+ return rmdir(dir.c_str());
}
inline const char* Getcwd(char* buf, unsigned int len)
{
return getcwd(buf, len);
}
-inline int Chdir(const char* dir)
+inline int Chdir(const std::string& dir)
{
- return chdir(dir);
+ return chdir(dir.c_str());
}
-inline void Realpath(const char *path, kwsys_stl::string & resolved_path)
+inline void Realpath(const std::string& path,
+ std::string& resolved_path,
+ std::string* errorMessage = 0)
{
char resolved_name[KWSYS_SYSTEMTOOLS_MAXPATH];
- char *ret = realpath(path, resolved_name);
+ errno = 0;
+ char *ret = realpath(path.c_str(), resolved_name);
if(ret)
{
resolved_path = ret;
}
+ else if(errorMessage)
+ {
+ if(errno)
+ {
+ *errorMessage = strerror(errno);
+ }
+ else
+ {
+ *errorMessage = "Unknown error.";
+ }
+
+ resolved_path = "";
+ }
else
{
// if path resolution fails, return what was passed in
@@ -299,17 +381,38 @@ double SystemTools::GetTime(void)
}
class SystemToolsTranslationMap :
- public kwsys_stl::map<kwsys_stl::string,kwsys_stl::string>
+ public std::map<std::string,std::string>
+{
+};
+
+#ifdef _WIN32
+struct SystemToolsPathCaseCmp
{
+ bool operator()(std::string const& l, std::string const& r) const
+ {
+# ifdef _MSC_VER
+ return _stricmp(l.c_str(), r.c_str()) < 0;
+# elif defined(__GNUC__)
+ return strcasecmp(l.c_str(), r.c_str()) < 0;
+# else
+ return SystemTools::Strucmp(l.c_str(), r.c_str()) < 0;
+# endif
+ }
};
+class SystemToolsPathCaseMap:
+ public std::map<std::string, std::string,
+ SystemToolsPathCaseCmp> {};
+#endif
+
// adds the elements of the env variable path to the arg passed in
-void SystemTools::GetPath(kwsys_stl::vector<kwsys_stl::string>& path, const char* env)
+void SystemTools::GetPath(std::vector<std::string>& path, const char* env)
{
+ size_t const old_size = path.size();
#if defined(_WIN32) && !defined(__CYGWIN__)
- const char* pathSep = ";";
+ const char pathSep = ';';
#else
- const char* pathSep = ":";
+ const char pathSep = ':';
#endif
if(!env)
{
@@ -321,19 +424,19 @@ void SystemTools::GetPath(kwsys_stl::vector<kwsys_stl::string>& path, const char
return;
}
- kwsys_stl::string pathEnv = cpathEnv;
+ std::string pathEnv = cpathEnv;
// A hack to make the below algorithm work.
- if(!pathEnv.empty() && pathEnv[pathEnv.length()-1] != pathSep[0])
+ if(!pathEnv.empty() && *pathEnv.rbegin() != pathSep)
{
pathEnv += pathSep;
}
- kwsys_stl::string::size_type start =0;
+ std::string::size_type start =0;
bool done = false;
while(!done)
{
- kwsys_stl::string::size_type endpos = pathEnv.find(pathSep, start);
- if(endpos != kwsys_stl::string::npos)
+ std::string::size_type endpos = pathEnv.find(pathSep, start);
+ if(endpos != std::string::npos)
{
path.push_back(pathEnv.substr(start, endpos-start));
start = endpos+1;
@@ -343,7 +446,7 @@ void SystemTools::GetPath(kwsys_stl::vector<kwsys_stl::string>& path, const char
done = true;
}
}
- for(kwsys_stl::vector<kwsys_stl::string>::iterator i = path.begin();
+ for(std::vector<std::string>::iterator i = path.begin() + old_size;
i != path.end(); ++i)
{
SystemTools::ConvertToUnixSlashes(*i);
@@ -355,7 +458,12 @@ const char* SystemTools::GetEnv(const char* key)
return getenv(key);
}
-bool SystemTools::GetEnv(const char* key, kwsys_stl::string& result)
+const char* SystemTools::GetEnv(const std::string& key)
+{
+ return SystemTools::GetEnv(key.c_str());
+}
+
+bool SystemTools::GetEnv(const char* key, std::string& result)
{
const char* v = getenv(key);
if(v)
@@ -369,6 +477,11 @@ bool SystemTools::GetEnv(const char* key, kwsys_stl::string& result)
}
}
+bool SystemTools::GetEnv(const std::string& key, std::string& result)
+{
+ return SystemTools::GetEnv(key.c_str(), result);
+}
+
//----------------------------------------------------------------------------
#if defined(__CYGWIN__) || defined(__GLIBC__)
@@ -380,27 +493,28 @@ bool SystemTools::GetEnv(const char* key, kwsys_stl::string& result)
#if KWSYS_CXX_HAS_UNSETENV
/* unsetenv("A") removes A from the environment.
On older platforms it returns void instead of int. */
-static int kwsysUnPutEnv(const char* env)
+static int kwsysUnPutEnv(const std::string& env)
{
- if(const char* eq = strchr(env, '='))
+ size_t pos = env.find('=');
+ if(pos != env.npos)
{
- std::string name(env, eq-env);
+ std::string name = env.substr(0, pos);
unsetenv(name.c_str());
}
else
{
- unsetenv(env);
+ unsetenv(env.c_str());
}
return 0;
}
#elif defined(KWSYS_PUTENV_EMPTY) || defined(KWSYS_PUTENV_NAME)
/* putenv("A=") or putenv("A") removes A from the environment. */
-static int kwsysUnPutEnv(const char* env)
+static int kwsysUnPutEnv(const std::string& env)
{
int err = 0;
- const char* eq = strchr(env, '=');
- size_t const len = eq? (size_t)(eq-env) : strlen(env);
+ size_t pos = env.find('=');
+ size_t const len = pos == env.npos ? env.size() : pos;
# ifdef KWSYS_PUTENV_EMPTY
size_t const sz = len + 2;
# else
@@ -412,7 +526,7 @@ static int kwsysUnPutEnv(const char* env)
{
return -1;
}
- strncpy(buf, env, len);
+ strncpy(buf, env.c_str(), len);
# ifdef KWSYS_PUTENV_EMPTY
buf[len] = '=';
buf[len+1] = 0;
@@ -441,17 +555,17 @@ static int kwsysUnPutEnv(const char* env)
#else
/* Manipulate the "environ" global directly. */
-static int kwsysUnPutEnv(const char* env)
+static int kwsysUnPutEnv(const std::string& env)
{
- const char* eq = strchr(env, '=');
- size_t const len = eq? (size_t)(eq-env) : strlen(env);
+ size_t pos = env.find('=');
+ size_t const len = pos == env.npos ? env.size() : pos;
int in = 0;
int out = 0;
while(environ[in])
{
if(strlen(environ[in]) > len &&
environ[in][len] == '=' &&
- strncmp(env, environ[in], len) == 0)
+ strncmp(env.c_str(), environ[in], len) == 0)
{
++in;
}
@@ -474,12 +588,13 @@ static int kwsysUnPutEnv(const char* env)
/* setenv("A", "B", 1) will set A=B in the environment and makes its
own copies of the strings. */
-bool SystemTools::PutEnv(const char* env)
+bool SystemTools::PutEnv(const std::string& env)
{
- if(const char* eq = strchr(env, '='))
+ size_t pos = env.find('=');
+ if(pos != env.npos)
{
- std::string name(env, eq-env);
- return setenv(name.c_str(), eq+1, 1) == 0;
+ std::string name = env.substr(0, pos);
+ return setenv(name.c_str(), env.c_str() + pos + 1, 1) == 0;
}
else
{
@@ -487,7 +602,7 @@ bool SystemTools::PutEnv(const char* env)
}
}
-bool SystemTools::UnPutEnv(const char* env)
+bool SystemTools::UnPutEnv(const std::string& env)
{
return kwsysUnPutEnv(env) == 0;
}
@@ -525,7 +640,7 @@ struct kwsysEnvCompare
}
};
-class kwsysEnv: public kwsys_stl::set<const char*, kwsysEnvCompare>
+class kwsysEnv: public std::set<const char*, kwsysEnvCompare>
{
class Free
{
@@ -535,7 +650,7 @@ class kwsysEnv: public kwsys_stl::set<const char*, kwsysEnvCompare>
~Free() { free(const_cast<char*>(this->Env)); }
};
public:
- typedef kwsys_stl::set<const char*, kwsysEnvCompare> derived;
+ typedef std::set<const char*, kwsysEnvCompare> derived;
~kwsysEnv()
{
for(derived::iterator i = this->begin(); i != this->end(); ++i)
@@ -573,14 +688,14 @@ public:
static kwsysEnv kwsysEnvInstance;
-bool SystemTools::PutEnv(const char* env)
+bool SystemTools::PutEnv(const std::string& env)
{
- return kwsysEnvInstance.Put(env);
+ return kwsysEnvInstance.Put(env.c_str());
}
-bool SystemTools::UnPutEnv(const char* env)
+bool SystemTools::UnPutEnv(const std::string& env)
{
- return kwsysEnvInstance.UnPut(env);
+ return kwsysEnvInstance.UnPut(env.c_str());
}
#endif
@@ -596,6 +711,15 @@ const char* SystemTools::GetExecutableExtension()
#endif
}
+FILE* SystemTools::Fopen(const std::string& file, const char* mode)
+{
+#ifdef _WIN32
+ return _wfopen(SystemTools::ConvertToWindowsExtendedPath(file).c_str(),
+ Encoding::ToWide(mode).c_str());
+#else
+ return fopen(file.c_str(), mode);
+#endif
+}
bool SystemTools::MakeDirectory(const char* path)
{
@@ -603,27 +727,32 @@ bool SystemTools::MakeDirectory(const char* path)
{
return false;
}
+ return SystemTools::MakeDirectory(std::string(path));
+}
+
+bool SystemTools::MakeDirectory(const std::string& path)
+{
if(SystemTools::FileExists(path))
{
return SystemTools::FileIsDirectory(path);
}
- kwsys_stl::string dir = path;
- if(dir.size() == 0)
+ if(path.empty())
{
return false;
}
+ std::string dir = path;
SystemTools::ConvertToUnixSlashes(dir);
- kwsys_stl::string::size_type pos = 0;
- kwsys_stl::string topdir;
- while((pos = dir.find('/', pos)) != kwsys_stl::string::npos)
+ std::string::size_type pos = 0;
+ std::string topdir;
+ while((pos = dir.find('/', pos)) != std::string::npos)
{
topdir = dir.substr(0, pos);
- Mkdir(topdir.c_str());
+ Mkdir(topdir);
pos++;
}
topdir = dir;
- if(Mkdir(topdir.c_str()) != 0)
+ if(Mkdir(topdir) != 0)
{
// There is a bug in the Borland Run time library which makes MKDIR
// return EACCES when it should return EEXISTS
@@ -644,9 +773,36 @@ bool SystemTools::MakeDirectory(const char* path)
// replace replace with with as many times as it shows up in source.
// write the result into source.
-void SystemTools::ReplaceString(kwsys_stl::string& source,
- const char* replace,
- const char* with)
+void SystemTools::ReplaceString(std::string& source,
+ const std::string& replace,
+ const std::string& with)
+{
+ // do while hangs if replaceSize is 0
+ if (replace.empty())
+ {
+ return;
+ }
+
+ SystemTools::ReplaceString(source, replace.c_str(), replace.size(), with);
+}
+
+void SystemTools::ReplaceString(std::string& source,
+ const char* replace,
+ const char* with)
+{
+ // do while hangs if replaceSize is 0
+ if (!*replace)
+ {
+ return;
+ }
+
+ SystemTools::ReplaceString(source, replace, strlen(replace), with ? with : "");
+}
+
+void SystemTools::ReplaceString(std::string& source,
+ const char* replace,
+ size_t replaceSize,
+ const std::string& with)
{
const char *src = source.c_str();
char *searchPos = const_cast<char *>(strstr(src,replace));
@@ -658,12 +814,6 @@ void SystemTools::ReplaceString(kwsys_stl::string& source,
}
// perform replacements until done
- size_t replaceSize = strlen(replace);
- // do while hangs if replaceSize is 0
- if(replaceSize == 0)
- {
- return;
- }
char *orig = strdup(src);
char *currentPos = orig;
searchPos = searchPos - src + orig;
@@ -695,21 +845,21 @@ void SystemTools::ReplaceString(kwsys_stl::string& source,
#endif
#if defined(_WIN32) && !defined(__CYGWIN__)
-static bool SystemToolsParseRegistryKey(const char* key,
+static bool SystemToolsParseRegistryKey(const std::string& key,
HKEY& primaryKey,
- kwsys_stl::string& second,
- kwsys_stl::string& valuename)
+ std::string& second,
+ std::string& valuename)
{
- kwsys_stl::string primary = key;
+ std::string primary = key;
- size_t start = primary.find("\\");
- if (start == kwsys_stl::string::npos)
+ size_t start = primary.find('\\');
+ if (start == std::string::npos)
{
return false;
}
- size_t valuenamepos = primary.find(";");
- if (valuenamepos != kwsys_stl::string::npos)
+ size_t valuenamepos = primary.find(';');
+ if (valuenamepos != std::string::npos)
{
valuename = primary.substr(valuenamepos+1);
}
@@ -745,7 +895,7 @@ static DWORD SystemToolsMakeRegistryMode(DWORD mode,
SystemTools::KeyWOW64 view)
{
// only add the modes when on a system that supports Wow64.
- static FARPROC wow64p = GetProcAddress(GetModuleHandle("kernel32"),
+ static FARPROC wow64p = GetProcAddress(GetModuleHandleW(L"kernel32"),
"IsWow64Process");
if(wow64p == NULL)
{
@@ -766,21 +916,21 @@ static DWORD SystemToolsMakeRegistryMode(DWORD mode,
#if defined(_WIN32) && !defined(__CYGWIN__)
bool
-SystemTools::GetRegistrySubKeys(const char *key,
- kwsys_stl::vector<kwsys_stl::string>& subkeys,
+SystemTools::GetRegistrySubKeys(const std::string& key,
+ std::vector<std::string>& subkeys,
KeyWOW64 view)
{
HKEY primaryKey = HKEY_CURRENT_USER;
- kwsys_stl::string second;
- kwsys_stl::string valuename;
+ std::string second;
+ std::string valuename;
if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename))
{
return false;
}
HKEY hKey;
- if(RegOpenKeyEx(primaryKey,
- second.c_str(),
+ if(RegOpenKeyExW(primaryKey,
+ Encoding::ToWide(second).c_str(),
0,
SystemToolsMakeRegistryMode(KEY_READ, view),
&hKey) != ERROR_SUCCESS)
@@ -789,13 +939,13 @@ SystemTools::GetRegistrySubKeys(const char *key,
}
else
{
- char name[1024];
+ wchar_t name[1024];
DWORD dwNameSize = sizeof(name)/sizeof(name[0]);
DWORD i = 0;
- while (RegEnumKey(hKey, i, name, dwNameSize) == ERROR_SUCCESS)
+ while (RegEnumKeyW(hKey, i, name, dwNameSize) == ERROR_SUCCESS)
{
- subkeys.push_back(name);
+ subkeys.push_back(Encoding::ToNarrow(name));
++i;
}
@@ -805,8 +955,8 @@ SystemTools::GetRegistrySubKeys(const char *key,
return true;
}
#else
-bool SystemTools::GetRegistrySubKeys(const char *,
- kwsys_stl::vector<kwsys_stl::string>&,
+bool SystemTools::GetRegistrySubKeys(const std::string&,
+ std::vector<std::string>&,
KeyWOW64)
{
return false;
@@ -821,21 +971,21 @@ bool SystemTools::GetRegistrySubKeys(const char *,
// => will return the data of the "Root" value of the key
#if defined(_WIN32) && !defined(__CYGWIN__)
-bool SystemTools::ReadRegistryValue(const char *key, kwsys_stl::string &value,
+bool SystemTools::ReadRegistryValue(const std::string& key, std::string &value,
KeyWOW64 view)
{
bool valueset = false;
HKEY primaryKey = HKEY_CURRENT_USER;
- kwsys_stl::string second;
- kwsys_stl::string valuename;
+ std::string second;
+ std::string valuename;
if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename))
{
return false;
}
HKEY hKey;
- if(RegOpenKeyEx(primaryKey,
- second.c_str(),
+ if(RegOpenKeyExW(primaryKey,
+ Encoding::ToWide(second).c_str(),
0,
SystemToolsMakeRegistryMode(KEY_READ, view),
&hKey) != ERROR_SUCCESS)
@@ -846,9 +996,9 @@ bool SystemTools::ReadRegistryValue(const char *key, kwsys_stl::string &value,
{
DWORD dwType, dwSize;
dwSize = 1023;
- char data[1024];
- if(RegQueryValueEx(hKey,
- (LPTSTR)valuename.c_str(),
+ wchar_t data[1024];
+ if(RegQueryValueExW(hKey,
+ Encoding::ToWide(valuename).c_str(),
NULL,
&dwType,
(BYTE *)data,
@@ -856,16 +1006,17 @@ bool SystemTools::ReadRegistryValue(const char *key, kwsys_stl::string &value,
{
if (dwType == REG_SZ)
{
- value = data;
+ value = Encoding::ToNarrow(data);
valueset = true;
}
else if (dwType == REG_EXPAND_SZ)
{
- char expanded[1024];
+ wchar_t expanded[1024];
DWORD dwExpandedSize = sizeof(expanded)/sizeof(expanded[0]);
- if(ExpandEnvironmentStrings(data, expanded, dwExpandedSize))
+ if(ExpandEnvironmentStringsW(data, expanded,
+ dwExpandedSize))
{
- value = expanded;
+ value = Encoding::ToNarrow(expanded);
valueset = true;
}
}
@@ -877,7 +1028,7 @@ bool SystemTools::ReadRegistryValue(const char *key, kwsys_stl::string &value,
return valueset;
}
#else
-bool SystemTools::ReadRegistryValue(const char *, kwsys_stl::string &,
+bool SystemTools::ReadRegistryValue(const std::string&, std::string &,
KeyWOW64)
{
return false;
@@ -893,12 +1044,13 @@ bool SystemTools::ReadRegistryValue(const char *, kwsys_stl::string &,
// => will set the data of the "Root" value of the key
#if defined(_WIN32) && !defined(__CYGWIN__)
-bool SystemTools::WriteRegistryValue(const char *key, const char *value,
+bool SystemTools::WriteRegistryValue(const std::string& key,
+ const std::string& value,
KeyWOW64 view)
{
HKEY primaryKey = HKEY_CURRENT_USER;
- kwsys_stl::string second;
- kwsys_stl::string valuename;
+ std::string second;
+ std::string valuename;
if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename))
{
return false;
@@ -906,9 +1058,9 @@ bool SystemTools::WriteRegistryValue(const char *key, const char *value,
HKEY hKey;
DWORD dwDummy;
- char lpClass[] = "";
- if(RegCreateKeyEx(primaryKey,
- second.c_str(),
+ wchar_t lpClass[] = L"";
+ if(RegCreateKeyExW(primaryKey,
+ Encoding::ToWide(second).c_str(),
0,
lpClass,
REG_OPTION_NON_VOLATILE,
@@ -920,19 +1072,20 @@ bool SystemTools::WriteRegistryValue(const char *key, const char *value,
return false;
}
- if(RegSetValueEx(hKey,
- (LPTSTR)valuename.c_str(),
+ std::wstring wvalue = Encoding::ToWide(value);
+ if(RegSetValueExW(hKey,
+ Encoding::ToWide(valuename).c_str(),
0,
REG_SZ,
- (CONST BYTE *)value,
- (DWORD)(strlen(value) + 1)) == ERROR_SUCCESS)
+ (CONST BYTE *)wvalue.c_str(),
+ (DWORD)(sizeof(wchar_t) * (wvalue.size() + 1))) == ERROR_SUCCESS)
{
return true;
}
return false;
}
#else
-bool SystemTools::WriteRegistryValue(const char *, const char *, KeyWOW64)
+bool SystemTools::WriteRegistryValue(const std::string&, const std::string&, KeyWOW64)
{
return false;
}
@@ -946,19 +1099,19 @@ bool SystemTools::WriteRegistryValue(const char *, const char *, KeyWOW64)
// => will delete the data of the "Root" value of the key
#if defined(_WIN32) && !defined(__CYGWIN__)
-bool SystemTools::DeleteRegistryValue(const char *key, KeyWOW64 view)
+bool SystemTools::DeleteRegistryValue(const std::string& key, KeyWOW64 view)
{
HKEY primaryKey = HKEY_CURRENT_USER;
- kwsys_stl::string second;
- kwsys_stl::string valuename;
+ std::string second;
+ std::string valuename;
if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename))
{
return false;
}
HKEY hKey;
- if(RegOpenKeyEx(primaryKey,
- second.c_str(),
+ if(RegOpenKeyExW(primaryKey,
+ Encoding::ToWide(second).c_str(),
0,
SystemToolsMakeRegistryMode(KEY_WRITE, view),
&hKey) != ERROR_SUCCESS)
@@ -977,18 +1130,18 @@ bool SystemTools::DeleteRegistryValue(const char *key, KeyWOW64 view)
return false;
}
#else
-bool SystemTools::DeleteRegistryValue(const char *, KeyWOW64)
+bool SystemTools::DeleteRegistryValue(const std::string&, KeyWOW64)
{
return false;
}
#endif
-bool SystemTools::SameFile(const char* file1, const char* file2)
+bool SystemTools::SameFile(const std::string& file1, const std::string& file2)
{
#ifdef _WIN32
HANDLE hFile1, hFile2;
- hFile1 = CreateFile( file1,
+ hFile1 = CreateFileW( Encoding::ToWide(file1).c_str(),
GENERIC_READ,
FILE_SHARE_READ ,
NULL,
@@ -996,7 +1149,7 @@ bool SystemTools::SameFile(const char* file1, const char* file2)
FILE_FLAG_BACKUP_SEMANTICS,
NULL
);
- hFile2 = CreateFile( file2,
+ hFile2 = CreateFileW( Encoding::ToWide(file2).c_str(),
GENERIC_READ,
FILE_SHARE_READ,
NULL,
@@ -1028,7 +1181,7 @@ bool SystemTools::SameFile(const char* file1, const char* file2)
fiBuf1.nFileIndexLow == fiBuf2.nFileIndexLow);
#else
struct stat fileStat1, fileStat2;
- if (stat(file1, &fileStat1) == 0 && stat(file2, &fileStat2) == 0)
+ if (stat(file1.c_str(), &fileStat1) == 0 && stat(file2.c_str(), &fileStat2) == 0)
{
// see if the files are the same file
// check the device inode and size
@@ -1045,39 +1198,52 @@ bool SystemTools::SameFile(const char* file1, const char* file2)
}
//----------------------------------------------------------------------------
-#if defined(_WIN32) || defined(__CYGWIN__)
-static bool WindowsFileExists(const char* filename)
+bool SystemTools::FileExists(const char* filename)
{
- WIN32_FILE_ATTRIBUTE_DATA fd;
- return GetFileAttributesExA(filename, GetFileExInfoStandard, &fd) != 0;
+ if(!filename)
+ {
+ return false;
+ }
+ return SystemTools::FileExists(std::string(filename));
}
-#endif
//----------------------------------------------------------------------------
-bool SystemTools::FileExists(const char* filename)
+bool SystemTools::FileExists(const std::string& filename)
{
- if(!(filename && *filename))
+ if(filename.empty())
{
return false;
}
#if defined(__CYGWIN__)
// Convert filename to native windows path if possible.
char winpath[MAX_PATH];
- if(SystemTools::PathCygwinToWin32(filename, winpath))
+ if(SystemTools::PathCygwinToWin32(filename.c_str(), winpath))
{
- return WindowsFileExists(winpath);
+ return (GetFileAttributesA(winpath) != INVALID_FILE_ATTRIBUTES);
}
- return access(filename, R_OK) == 0;
+ return access(filename.c_str(), R_OK) == 0;
#elif defined(_WIN32)
- return WindowsFileExists(filename);
+ return (GetFileAttributesW(
+ SystemTools::ConvertToWindowsExtendedPath(filename).c_str())
+ != INVALID_FILE_ATTRIBUTES);
#else
- return access(filename, R_OK) == 0;
+ return access(filename.c_str(), R_OK) == 0;
#endif
}
//----------------------------------------------------------------------------
bool SystemTools::FileExists(const char* filename, bool isFile)
{
+ if(!filename)
+ {
+ return false;
+ }
+ return SystemTools::FileExists(std::string(filename), isFile);
+}
+
+//----------------------------------------------------------------------------
+bool SystemTools::FileExists(const std::string& filename, bool isFile)
+{
if(SystemTools::FileExists(filename))
{
// If isFile is set return not FileIsDirectory,
@@ -1088,6 +1254,43 @@ bool SystemTools::FileExists(const char* filename, bool isFile)
}
//----------------------------------------------------------------------------
+bool SystemTools::TestFileAccess(const char* filename,
+ TestFilePermissions permissions)
+{
+ if(!filename)
+ {
+ return false;
+ }
+ return SystemTools::TestFileAccess(std::string(filename),
+ permissions);
+}
+
+//----------------------------------------------------------------------------
+bool SystemTools::TestFileAccess(const std::string& filename,
+ TestFilePermissions permissions)
+{
+ if(filename.empty())
+ {
+ return false;
+ }
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ // If execute set, change to read permission (all files on Windows
+ // are executable if they are readable). The CRT will always fail
+ // if you pass an execute bit.
+ if(permissions & TEST_FILE_EXECUTE)
+ {
+ permissions &= ~TEST_FILE_EXECUTE;
+ permissions |= TEST_FILE_READ;
+ }
+ return _waccess(
+ SystemTools::ConvertToWindowsExtendedPath(filename).c_str(),
+ permissions) == 0;
+#else
+ return access(filename.c_str(), permissions) == 0;
+#endif
+}
+
+//----------------------------------------------------------------------------
#ifdef __CYGWIN__
bool SystemTools::PathCygwinToWin32(const char *path, char *win32_path)
{
@@ -1100,7 +1303,10 @@ bool SystemTools::PathCygwinToWin32(const char *path, char *win32_path)
}
else
{
- cygwin_conv_to_win32_path(path, win32_path);
+ if(cygwin_conv_path(CCP_POSIX_TO_WIN_A, path, win32_path, MAX_PATH) != 0)
+ {
+ win32_path[0] = 0;
+ }
SystemToolsTranslationMap::value_type entry(path, win32_path);
SystemTools::Cyg2Win32Map->insert(entry);
}
@@ -1108,22 +1314,31 @@ bool SystemTools::PathCygwinToWin32(const char *path, char *win32_path)
}
#endif
-bool SystemTools::Touch(const char* filename, bool create)
+bool SystemTools::Touch(const std::string& filename, bool create)
{
- if(create && !SystemTools::FileExists(filename))
+ if (!SystemTools::FileExists(filename))
{
- FILE* file = fopen(filename, "a+b");
- if(file)
+ if(create)
+ {
+ FILE* file = Fopen(filename, "a+b");
+ if(file)
+ {
+ fclose(file);
+ return true;
+ }
+ return false;
+ }
+ else
{
- fclose(file);
return true;
}
- return false;
}
#if defined(_WIN32) && !defined(__CYGWIN__)
- HANDLE h = CreateFile(filename, FILE_WRITE_ATTRIBUTES,
- FILE_SHARE_WRITE, 0, OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS, 0);
+ HANDLE h = CreateFileW(
+ SystemTools::ConvertToWindowsExtendedPath(filename).c_str(),
+ FILE_WRITE_ATTRIBUTES,
+ FILE_SHARE_WRITE, 0, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS, 0);
if(!h)
{
return false;
@@ -1138,35 +1353,38 @@ bool SystemTools::Touch(const char* filename, bool create)
CloseHandle(h);
#elif KWSYS_CXX_HAS_UTIMENSAT
struct timespec times[2] = {{0,UTIME_OMIT},{0,UTIME_NOW}};
- if(utimensat(AT_FDCWD, filename, times, 0) < 0)
+ if(utimensat(AT_FDCWD, filename.c_str(), times, 0) < 0)
{
return false;
}
#else
struct stat st;
- if(stat(filename, &st) < 0)
+ if(stat(filename.c_str(), &st) < 0)
{
return false;
}
struct timeval mtime;
gettimeofday(&mtime, 0);
# if KWSYS_CXX_HAS_UTIMES
- struct timeval times[2] =
- {
-# if KWSYS_STAT_HAS_ST_MTIM
- {st.st_atim.tv_sec, st.st_atim.tv_nsec/1000}, /* tv_sec, tv_usec */
+ struct timeval atime;
+# if KWSYS_CXX_STAT_HAS_ST_MTIM
+ atime.tv_sec = st.st_atim.tv_sec;
+ atime.tv_usec = st.st_atim.tv_nsec/1000;
+# elif KWSYS_CXX_STAT_HAS_ST_MTIMESPEC
+ atime.tv_sec = st.st_atimespec.tv_sec;
+ atime.tv_usec = st.st_atimespec.tv_nsec/1000;
# else
- {st.st_atime, 0},
+ atime.tv_sec = st.st_atime;
+ atime.tv_usec = 0;
# endif
- mtime
- };
- if(utimes(filename, times) < 0)
+ struct timeval times[2] = { atime, mtime };
+ if(utimes(filename.c_str(), times) < 0)
{
return false;
}
# else
struct utimbuf times = {st.st_atime, mtime.tv_sec};
- if(utime(filename, &times) < 0)
+ if(utime(filename.c_str(), &times) < 0)
{
return false;
}
@@ -1175,7 +1393,8 @@ bool SystemTools::Touch(const char* filename, bool create)
return true;
}
-bool SystemTools::FileTimeCompare(const char* f1, const char* f2,
+bool SystemTools::FileTimeCompare(const std::string& f1,
+ const std::string& f2,
int* result)
{
// Default to same time.
@@ -1183,16 +1402,16 @@ bool SystemTools::FileTimeCompare(const char* f1, const char* f2,
#if !defined(_WIN32) || defined(__CYGWIN__)
// POSIX version. Use stat function to get file modification time.
struct stat s1;
- if(stat(f1, &s1) != 0)
+ if(stat(f1.c_str(), &s1) != 0)
{
return false;
}
struct stat s2;
- if(stat(f2, &s2) != 0)
+ if(stat(f2.c_str(), &s2) != 0)
{
return false;
}
-# if KWSYS_STAT_HAS_ST_MTIM
+# if KWSYS_CXX_STAT_HAS_ST_MTIM
// Compare using nanosecond resolution.
if(s1.st_mtim.tv_sec < s2.st_mtim.tv_sec)
{
@@ -1210,6 +1429,24 @@ bool SystemTools::FileTimeCompare(const char* f1, const char* f2,
{
*result = 1;
}
+# elif KWSYS_CXX_STAT_HAS_ST_MTIMESPEC
+ // Compare using nanosecond resolution.
+ if(s1.st_mtimespec.tv_sec < s2.st_mtimespec.tv_sec)
+ {
+ *result = -1;
+ }
+ else if(s1.st_mtimespec.tv_sec > s2.st_mtimespec.tv_sec)
+ {
+ *result = 1;
+ }
+ else if(s1.st_mtimespec.tv_nsec < s2.st_mtimespec.tv_nsec)
+ {
+ *result = -1;
+ }
+ else if(s1.st_mtimespec.tv_nsec > s2.st_mtimespec.tv_nsec)
+ {
+ *result = 1;
+ }
# else
// Compare using 1 second resolution.
if(s1.st_mtime < s2.st_mtime)
@@ -1225,11 +1462,15 @@ bool SystemTools::FileTimeCompare(const char* f1, const char* f2,
// Windows version. Get the modification time from extended file attributes.
WIN32_FILE_ATTRIBUTE_DATA f1d;
WIN32_FILE_ATTRIBUTE_DATA f2d;
- if(!GetFileAttributesEx(f1, GetFileExInfoStandard, &f1d))
+ if(!GetFileAttributesExW(
+ SystemTools::ConvertToWindowsExtendedPath(f1).c_str(),
+ GetFileExInfoStandard, &f1d))
{
return false;
}
- if(!GetFileAttributesEx(f2, GetFileExInfoStandard, &f2d))
+ if(!GetFileAttributesExW(
+ SystemTools::ConvertToWindowsExtendedPath(f2).c_str(),
+ GetFileExInfoStandard, &f2d))
{
return false;
}
@@ -1243,26 +1484,26 @@ bool SystemTools::FileTimeCompare(const char* f1, const char* f2,
// Return a capitalized string (i.e the first letter is uppercased, all other
// are lowercased)
-kwsys_stl::string SystemTools::Capitalized(const kwsys_stl::string& s)
+std::string SystemTools::Capitalized(const std::string& s)
{
- kwsys_stl::string n;
- if(s.size() == 0)
+ std::string n;
+ if(s.empty())
{
return n;
}
n.resize(s.size());
- n[0] = static_cast<kwsys_stl::string::value_type>(toupper(s[0]));
+ n[0] = static_cast<std::string::value_type>(toupper(s[0]));
for (size_t i = 1; i < s.size(); i++)
{
- n[i] = static_cast<kwsys_stl::string::value_type>(tolower(s[i]));
+ n[i] = static_cast<std::string::value_type>(tolower(s[i]));
}
return n;
}
// Return capitalized words
-kwsys_stl::string SystemTools::CapitalizedWords(const kwsys_stl::string& s)
+std::string SystemTools::CapitalizedWords(const std::string& s)
{
- kwsys_stl::string n(s);
+ std::string n(s);
for (size_t i = 0; i < s.size(); i++)
{
#if defined(_MSC_VER) && defined (_MT) && defined (_DEBUG)
@@ -1274,16 +1515,16 @@ kwsys_stl::string SystemTools::CapitalizedWords(const kwsys_stl::string& s)
if (isalpha(s[i]) && (i == 0 || isspace(s[i - 1])))
#endif
{
- n[i] = static_cast<kwsys_stl::string::value_type>(toupper(s[i]));
+ n[i] = static_cast<std::string::value_type>(toupper(s[i]));
}
}
return n;
}
// Return uncapitalized words
-kwsys_stl::string SystemTools::UnCapitalizedWords(const kwsys_stl::string& s)
+std::string SystemTools::UnCapitalizedWords(const std::string& s)
{
- kwsys_stl::string n(s);
+ std::string n(s);
for (size_t i = 0; i < s.size(); i++)
{
#if defined(_MSC_VER) && defined (_MT) && defined (_DEBUG)
@@ -1295,18 +1536,18 @@ kwsys_stl::string SystemTools::UnCapitalizedWords(const kwsys_stl::string& s)
if (isalpha(s[i]) && (i == 0 || isspace(s[i - 1])))
#endif
{
- n[i] = static_cast<kwsys_stl::string::value_type>(tolower(s[i]));
+ n[i] = static_cast<std::string::value_type>(tolower(s[i]));
}
}
return n;
}
// only works for words with at least two letters
-kwsys_stl::string SystemTools::AddSpaceBetweenCapitalizedWords(
- const kwsys_stl::string& s)
+std::string SystemTools::AddSpaceBetweenCapitalizedWords(
+ const std::string& s)
{
- kwsys_stl::string n;
- if (s.size())
+ std::string n;
+ if (!s.empty())
{
n.reserve(s.size());
n += s[0];
@@ -1372,25 +1613,25 @@ char* SystemTools::AppendStrings(
}
// Return a lower case string
-kwsys_stl::string SystemTools::LowerCase(const kwsys_stl::string& s)
+std::string SystemTools::LowerCase(const std::string& s)
{
- kwsys_stl::string n;
+ std::string n;
n.resize(s.size());
for (size_t i = 0; i < s.size(); i++)
{
- n[i] = static_cast<kwsys_stl::string::value_type>(tolower(s[i]));
+ n[i] = static_cast<std::string::value_type>(tolower(s[i]));
}
return n;
}
// Return a lower case string
-kwsys_stl::string SystemTools::UpperCase(const kwsys_stl::string& s)
+std::string SystemTools::UpperCase(const std::string& s)
{
- kwsys_stl::string n;
+ std::string n;
n.resize(s.size());
for (size_t i = 0; i < s.size(); i++)
{
- n[i] = static_cast<kwsys_stl::string::value_type>(toupper(s[i]));
+ n[i] = static_cast<std::string::value_type>(toupper(s[i]));
}
return n;
}
@@ -1495,6 +1736,17 @@ bool SystemTools::StringStartsWith(const char* str1, const char* str2)
return len1 >= len2 && !strncmp(str1, str2, len2) ? true : false;
}
+// Returns if string starts with another string
+bool SystemTools::StringStartsWith(const std::string& str1, const char* str2)
+{
+ if (!str2)
+ {
+ return false;
+ }
+ size_t len1 = str1.size(), len2 = strlen(str2);
+ return len1 >= len2 && !strncmp(str1.c_str(), str2, len2) ? true : false;
+}
+
// Returns if string ends with another string
bool SystemTools::StringEndsWith(const char* str1, const char* str2)
{
@@ -1506,6 +1758,17 @@ bool SystemTools::StringEndsWith(const char* str1, const char* str2)
return len1 >= len2 && !strncmp(str1 + (len1 - len2), str2, len2) ? true : false;
}
+// Returns if string ends with another string
+bool SystemTools::StringEndsWith(const std::string& str1, const char* str2)
+{
+ if (!str2)
+ {
+ return false;
+ }
+ size_t len1 = str1.size(), len2 = strlen(str2);
+ return len1 >= len2 && !strncmp(str1.c_str() + (len1 - len2), str2, len2) ? true : false;
+}
+
// Returns a pointer to the last occurence of str2 in str1
const char* SystemTools::FindLastString(const char* str1, const char* str2)
{
@@ -1542,7 +1805,7 @@ char* SystemTools::DuplicateString(const char* str)
}
// Return a cropped string
-kwsys_stl::string SystemTools::CropString(const kwsys_stl::string& s,
+std::string SystemTools::CropString(const std::string& s,
size_t max_len)
{
if (!s.size() || max_len == 0 || max_len >= s.size())
@@ -1550,13 +1813,13 @@ kwsys_stl::string SystemTools::CropString(const kwsys_stl::string& s,
return s;
}
- kwsys_stl::string n;
+ std::string n;
n.reserve(max_len);
size_t middle = max_len / 2;
n += s.substr(0, middle);
- n += s.substr(s.size() - (max_len - middle), kwsys_stl::string::npos);
+ n += s.substr(s.size() - (max_len - middle), std::string::npos);
if (max_len > 2)
{
@@ -1575,10 +1838,10 @@ kwsys_stl::string SystemTools::CropString(const kwsys_stl::string& s,
}
//----------------------------------------------------------------------------
-kwsys_stl::vector<kwsys::String> SystemTools::SplitString(const char* p, char sep, bool isPath)
+std::vector<kwsys::String> SystemTools::SplitString(const std::string& p, char sep, bool isPath)
{
- kwsys_stl::string path = p;
- kwsys_stl::vector<kwsys::String> paths;
+ std::string path = p;
+ std::vector<kwsys::String> paths;
if(path.empty())
{
return paths;
@@ -1588,9 +1851,9 @@ kwsys_stl::vector<kwsys::String> SystemTools::SplitString(const char* p, char se
path.erase(path.begin());
paths.push_back("/");
}
- kwsys_stl::string::size_type pos1 = 0;
- kwsys_stl::string::size_type pos2 = path.find(sep, pos1+1);
- while(pos2 != kwsys_stl::string::npos)
+ std::string::size_type pos1 = 0;
+ std::string::size_type pos2 = path.find(sep, pos1+1);
+ while(pos2 != std::string::npos)
{
paths.push_back(path.substr(pos1, pos2-pos1));
pos1 = pos2+1;
@@ -1670,12 +1933,12 @@ int SystemTools::EstimateFormatLength(const char *format, va_list ap)
return static_cast<int>(length);
}
-kwsys_stl::string SystemTools::EscapeChars(
+std::string SystemTools::EscapeChars(
const char *str,
const char *chars_to_escape,
char escape_char)
{
- kwsys_stl::string n;
+ std::string n;
if (str)
{
if (!chars_to_escape || !*chars_to_escape)
@@ -1706,17 +1969,17 @@ kwsys_stl::string SystemTools::EscapeChars(
}
#ifdef __VMS
-static void ConvertVMSToUnix(kwsys_stl::string& path)
+static void ConvertVMSToUnix(std::string& path)
{
- kwsys_stl::string::size_type rootEnd = path.find(":[");
- kwsys_stl::string::size_type pathEnd = path.find("]");
+ std::string::size_type rootEnd = path.find(":[");
+ std::string::size_type pathEnd = path.find("]");
if(rootEnd != path.npos)
{
- kwsys_stl::string root = path.substr(0, rootEnd);
- kwsys_stl::string pathPart = path.substr(rootEnd+2, pathEnd - rootEnd-2);
+ std::string root = path.substr(0, rootEnd);
+ std::string pathPart = path.substr(rootEnd+2, pathEnd - rootEnd-2);
const char* pathCString = pathPart.c_str();
const char* pos0 = pathCString;
- for (kwsys_stl::string::size_type pos = 0; *pos0; ++ pos )
+ for (std::string::size_type pos = 0; *pos0; ++ pos )
{
if ( *pos0 == '.' )
{
@@ -1730,7 +1993,7 @@ static void ConvertVMSToUnix(kwsys_stl::string& path)
#endif
// convert windows slashes to unix slashes
-void SystemTools::ConvertToUnixSlashes(kwsys_stl::string& path)
+void SystemTools::ConvertToUnixSlashes(std::string& path)
{
const char* pathCString = path.c_str();
bool hasDoubleSlash = false;
@@ -1739,7 +2002,7 @@ void SystemTools::ConvertToUnixSlashes(kwsys_stl::string& path)
#else
const char* pos0 = pathCString;
const char* pos1 = pathCString+1;
- for (kwsys_stl::string::size_type pos = 0; *pos0; ++ pos )
+ for (std::string::size_type pos = 0; *pos0; ++ pos )
{
// make sure we don't convert an escaped space to a unix slash
if ( *pos0 == '\\' && *pos1 != ' ' )
@@ -1787,8 +2050,8 @@ void SystemTools::ConvertToUnixSlashes(kwsys_stl::string& path)
#ifdef HAVE_GETPWNAM
else if(pathCString[0] == '~')
{
- kwsys_stl::string::size_type idx = path.find_first_of("/\0");
- kwsys_stl::string user = path.substr(1, idx-1);
+ std::string::size_type idx = path.find_first_of("/\0");
+ std::string user = path.substr(1, idx-1);
passwd* pw = getpwnam(user.c_str());
if(pw)
{
@@ -1799,32 +2062,98 @@ void SystemTools::ConvertToUnixSlashes(kwsys_stl::string& path)
// remove trailing slash if the path is more than
// a single /
pathCString = path.c_str();
- if(path.size() > 1 && *(pathCString+(path.size()-1)) == '/')
+ size_t size = path.size();
+ if(size > 1 && *path.rbegin() == '/')
{
// if it is c:/ then do not remove the trailing slash
- if(!((path.size() == 3 && pathCString[1] == ':')))
+ if(!((size == 3 && pathCString[1] == ':')))
{
- path = path.substr(0, path.size()-1);
+ path.resize(size - 1);
}
}
}
}
+#ifdef _WIN32
+// Convert local paths to UNC style paths
+std::wstring
+SystemTools::ConvertToWindowsExtendedPath(const std::string &source)
+{
+ std::wstring wsource = Encoding::ToWide(source);
+
+ // Resolve any relative paths
+ DWORD wfull_len;
+
+ /* The +3 is a workaround for a bug in some versions of GetFullPathNameW that
+ * won't return a large enough buffer size if the input is too small */
+ wfull_len = GetFullPathNameW(wsource.c_str(), 0, NULL, NULL) + 3;
+ std::vector<wchar_t> wfull(wfull_len);
+ GetFullPathNameW(wsource.c_str(), wfull_len, &wfull[0], NULL);
+
+ /* This should get the correct size without any extra padding from the
+ * previous size workaround. */
+ wfull_len = static_cast<DWORD>(wcslen(&wfull[0]));
+
+ if(wfull_len >= 2 && isalpha(wfull[0]) && wfull[1] == L':')
+ { /* C:\Foo\bar\FooBar.txt */
+ return L"\\\\?\\" + std::wstring(&wfull[0]);
+ }
+ else if(wfull_len >= 2 && wfull[0] == L'\\' && wfull[1] == L'\\')
+ { /* Starts with \\ */
+ if(wfull_len >= 4 && wfull[2] == L'?' && wfull[3] == L'\\')
+ { /* Starts with \\?\ */
+ if(wfull_len >= 8 && wfull[4] == L'U' && wfull[5] == L'N' &&
+ wfull[6] == L'C' && wfull[7] == L'\\')
+ { /* \\?\UNC\Foo\bar\FooBar.txt */
+ return std::wstring(&wfull[0]);
+ }
+ else if(wfull_len >= 6 && isalpha(wfull[4]) && wfull[5] == L':')
+ { /* \\?\C:\Foo\bar\FooBar.txt */
+ return std::wstring(&wfull[0]);
+ }
+ else if(wfull_len >= 5)
+ { /* \\?\Foo\bar\FooBar.txt */
+ return L"\\\\?\\UNC\\" + std::wstring(&wfull[4]);
+ }
+ }
+ else if(wfull_len >= 4 && wfull[2] == L'.' && wfull[3] == L'\\')
+ { /* Starts with \\.\ a device name */
+ if(wfull_len >= 6 && isalpha(wfull[4]) && wfull[5] == L':')
+ { /* \\.\C:\Foo\bar\FooBar.txt */
+ return L"\\\\?\\" + std::wstring(&wfull[4]);
+ }
+ else if(wfull_len >= 5)
+ { /* \\.\Foo\bar\ Device name is left unchanged */
+ return std::wstring(&wfull[0]);
+ }
+ }
+ else if(wfull_len >= 3)
+ { /* \\Foo\bar\FooBar.txt */
+ return L"\\\\?\\UNC\\" + std::wstring(&wfull[2]);
+ }
+ }
+
+ // If this case has been reached, then the path is invalid. Leave it
+ // unchanged
+ return Encoding::ToWide(source);
+}
+#endif
+
// change // to /, and escape any spaces in the path
-kwsys_stl::string SystemTools::ConvertToUnixOutputPath(const char* path)
+std::string SystemTools::ConvertToUnixOutputPath(const std::string& path)
{
- kwsys_stl::string ret = path;
+ std::string ret = path;
// remove // except at the beginning might be a cygwin drive
- kwsys_stl::string::size_type pos=1;
- while((pos = ret.find("//", pos)) != kwsys_stl::string::npos)
+ std::string::size_type pos=1;
+ while((pos = ret.find("//", pos)) != std::string::npos)
{
ret.erase(pos, 1);
}
// escape spaces and () in the path
- if(ret.find_first_of(" ") != kwsys_stl::string::npos)
+ if(ret.find_first_of(" ") != std::string::npos)
{
- kwsys_stl::string result = "";
+ std::string result = "";
char lastch = 1;
for(const char* ch = ret.c_str(); *ch != '\0'; ++ch)
{
@@ -1841,7 +2170,7 @@ kwsys_stl::string SystemTools::ConvertToUnixOutputPath(const char* path)
return ret;
}
-kwsys_stl::string SystemTools::ConvertToOutputPath(const char* path)
+std::string SystemTools::ConvertToOutputPath(const std::string& path)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
return SystemTools::ConvertToWindowsOutputPath(path);
@@ -1851,17 +2180,16 @@ kwsys_stl::string SystemTools::ConvertToOutputPath(const char* path)
}
// remove double slashes not at the start
-kwsys_stl::string SystemTools::ConvertToWindowsOutputPath(const char* path)
+std::string SystemTools::ConvertToWindowsOutputPath(const std::string& path)
{
- kwsys_stl::string ret;
+ std::string ret;
// make it big enough for all of path and double quotes
- ret.reserve(strlen(path)+3);
+ ret.reserve(path.size()+3);
// put path into the string
- ret.assign(path);
ret = path;
- kwsys_stl::string::size_type pos = 0;
+ std::string::size_type pos = 0;
// first convert all of the slashes
- while((pos = ret.find('/', pos)) != kwsys_stl::string::npos)
+ while((pos = ret.find('/', pos)) != std::string::npos)
{
ret[pos] = '\\';
pos++;
@@ -1883,35 +2211,35 @@ kwsys_stl::string SystemTools::ConvertToWindowsOutputPath(const char* path)
return ret;
}
}
- while((pos = ret.find("\\\\", pos)) != kwsys_stl::string::npos)
+ while((pos = ret.find("\\\\", pos)) != std::string::npos)
{
ret.erase(pos, 1);
}
// now double quote the path if it has spaces in it
// and is not already double quoted
- if(ret.find(' ') != kwsys_stl::string::npos
+ if(ret.find(' ') != std::string::npos
&& ret[0] != '\"')
{
- ret.insert(static_cast<kwsys_stl::string::size_type>(0),
- static_cast<kwsys_stl::string::size_type>(1), '\"');
+ ret.insert(static_cast<std::string::size_type>(0),
+ static_cast<std::string::size_type>(1), '\"');
ret.append(1, '\"');
}
return ret;
}
-bool SystemTools::CopyFileIfDifferent(const char* source,
- const char* destination)
+bool SystemTools::CopyFileIfDifferent(const std::string& source,
+ const std::string& destination)
{
// special check for a destination that is a directory
// FilesDiffer does not handle file to directory compare
if(SystemTools::FileIsDirectory(destination))
{
- kwsys_stl::string new_destination = destination;
+ std::string new_destination = destination;
SystemTools::ConvertToUnixSlashes(new_destination);
new_destination += '/';
- kwsys_stl::string source_name = source;
+ std::string source_name = source;
new_destination += SystemTools::GetFilenameName(source_name);
- if(SystemTools::FilesDiffer(source, new_destination.c_str()))
+ if(SystemTools::FilesDiffer(source, new_destination))
{
return SystemTools::CopyFileAlways(source, destination);
}
@@ -1934,17 +2262,52 @@ bool SystemTools::CopyFileIfDifferent(const char* source,
#define KWSYS_ST_BUFFER 4096
-bool SystemTools::FilesDiffer(const char* source,
- const char* destination)
+bool SystemTools::FilesDiffer(const std::string& source,
+ const std::string& destination)
{
+
+#if defined(_WIN32)
+ WIN32_FILE_ATTRIBUTE_DATA statSource;
+ if (GetFileAttributesExW(
+ SystemTools::ConvertToWindowsExtendedPath(source).c_str(),
+ GetFileExInfoStandard,
+ &statSource) == 0)
+ {
+ return true;
+ }
+
+ WIN32_FILE_ATTRIBUTE_DATA statDestination;
+ if (GetFileAttributesExW(
+ SystemTools::ConvertToWindowsExtendedPath(destination).c_str(),
+ GetFileExInfoStandard,
+ &statDestination) == 0)
+ {
+ return true;
+ }
+
+ if(statSource.nFileSizeHigh != statDestination.nFileSizeHigh ||
+ statSource.nFileSizeLow != statDestination.nFileSizeLow)
+ {
+ return true;
+ }
+
+ if(statSource.nFileSizeHigh == 0 && statSource.nFileSizeLow == 0)
+ {
+ return false;
+ }
+ off_t nleft = ((__int64)statSource.nFileSizeHigh << 32) +
+ statSource.nFileSizeLow;
+
+#else
+
struct stat statSource;
- if (stat(source, &statSource) != 0)
+ if (stat(source.c_str(), &statSource) != 0)
{
return true;
}
struct stat statDestination;
- if (stat(destination, &statDestination) != 0)
+ if (stat(destination.c_str(), &statDestination) != 0)
{
return true;
}
@@ -1958,15 +2321,19 @@ bool SystemTools::FilesDiffer(const char* source,
{
return false;
}
+ off_t nleft = statSource.st_size;
+#endif
-#if defined(_WIN32) || defined(__CYGWIN__)
- kwsys_ios::ifstream finSource(source, (kwsys_ios::ios::binary |
- kwsys_ios::ios::in));
- kwsys_ios::ifstream finDestination(destination, (kwsys_ios::ios::binary |
- kwsys_ios::ios::in));
+#if defined(_WIN32)
+ kwsys::ifstream finSource(source.c_str(),
+ (std::ios::binary |
+ std::ios::in));
+ kwsys::ifstream finDestination(destination.c_str(),
+ (std::ios::binary |
+ std::ios::in));
#else
- kwsys_ios::ifstream finSource(source);
- kwsys_ios::ifstream finDestination(destination);
+ kwsys::ifstream finSource(source.c_str());
+ kwsys::ifstream finDestination(destination.c_str());
#endif
if(!finSource || !finDestination)
{
@@ -1976,17 +2343,16 @@ bool SystemTools::FilesDiffer(const char* source,
// Compare the files a block at a time.
char source_buf[KWSYS_ST_BUFFER];
char dest_buf[KWSYS_ST_BUFFER];
- off_t nleft = statSource.st_size;
while(nleft > 0)
{
// Read a block from each file.
- kwsys_ios::streamsize nnext = (nleft > KWSYS_ST_BUFFER)? KWSYS_ST_BUFFER : static_cast<kwsys_ios::streamsize>(nleft);
+ std::streamsize nnext = (nleft > KWSYS_ST_BUFFER)? KWSYS_ST_BUFFER : static_cast<std::streamsize>(nleft);
finSource.read(source_buf, nnext);
finDestination.read(dest_buf, nnext);
// If either failed to read assume they are different.
- if(static_cast<kwsys_ios::streamsize>(finSource.gcount()) != nnext ||
- static_cast<kwsys_ios::streamsize>(finDestination.gcount()) != nnext)
+ if(static_cast<std::streamsize>(finSource.gcount()) != nnext ||
+ static_cast<std::streamsize>(finDestination.gcount()) != nnext)
{
return true;
}
@@ -2012,7 +2378,7 @@ bool SystemTools::FilesDiffer(const char* source,
/**
* Copy a file named by "source" to the file named by "destination".
*/
-bool SystemTools::CopyFileAlways(const char* source, const char* destination)
+bool SystemTools::CopyFileAlways(const std::string& source, const std::string& destination)
{
// If files are the same do not copy
if ( SystemTools::SameFile(source, destination) )
@@ -2021,91 +2387,105 @@ bool SystemTools::CopyFileAlways(const char* source, const char* destination)
}
mode_t perm = 0;
bool perms = SystemTools::GetPermissions(source, perm);
+ std::string real_destination = destination;
- const int bufferSize = 4096;
- char buffer[bufferSize];
-
- // If destination is a directory, try to create a file with the same
- // name as the source in that directory.
-
- kwsys_stl::string new_destination;
- if(SystemTools::FileExists(destination) &&
- SystemTools::FileIsDirectory(destination))
+ if(SystemTools::FileIsDirectory(source))
{
- new_destination = destination;
- SystemTools::ConvertToUnixSlashes(new_destination);
- new_destination += '/';
- kwsys_stl::string source_name = source;
- new_destination += SystemTools::GetFilenameName(source_name);
- destination = new_destination.c_str();
+ SystemTools::MakeDirectory(destination);
}
+ else
+ {
+ const int bufferSize = 4096;
+ char buffer[bufferSize];
- // Create destination directory
+ // If destination is a directory, try to create a file with the same
+ // name as the source in that directory.
- kwsys_stl::string destination_dir = destination;
- destination_dir = SystemTools::GetFilenamePath(destination_dir);
- SystemTools::MakeDirectory(destination_dir.c_str());
+ std::string destination_dir;
+ if(SystemTools::FileIsDirectory(destination))
+ {
+ destination_dir = real_destination;
+ SystemTools::ConvertToUnixSlashes(real_destination);
+ real_destination += '/';
+ std::string source_name = source;
+ real_destination += SystemTools::GetFilenameName(source_name);
+ }
+ else
+ {
+ destination_dir = SystemTools::GetFilenamePath(destination);
+ }
- // Open files
+ // Create destination directory
-#if defined(_WIN32) || defined(__CYGWIN__)
- kwsys_ios::ifstream fin(source,
- kwsys_ios::ios::binary | kwsys_ios::ios::in);
+ SystemTools::MakeDirectory(destination_dir);
+
+ // Open files
+#if defined(_WIN32)
+ kwsys::ifstream fin(Encoding::ToNarrow(
+ SystemTools::ConvertToWindowsExtendedPath(source)).c_str(),
+ std::ios::in | std::ios::binary);
#else
- kwsys_ios::ifstream fin(source);
+ kwsys::ifstream fin(source.c_str(),
+ std::ios::in | std::ios::binary);
#endif
- if(!fin)
- {
- return false;
- }
+ if(!fin)
+ {
+ return false;
+ }
- // try and remove the destination file so that read only destination files
- // can be written to.
- // If the remove fails continue so that files in read only directories
- // that do not allow file removal can be modified.
- SystemTools::RemoveFile(destination);
+ // try and remove the destination file so that read only destination files
+ // can be written to.
+ // If the remove fails continue so that files in read only directories
+ // that do not allow file removal can be modified.
+ SystemTools::RemoveFile(real_destination);
-#if defined(_WIN32) || defined(__CYGWIN__)
- kwsys_ios::ofstream fout(destination,
- kwsys_ios::ios::binary | kwsys_ios::ios::out | kwsys_ios::ios::trunc);
+#if defined(_WIN32)
+ kwsys::ofstream fout(Encoding::ToNarrow(
+ SystemTools::ConvertToWindowsExtendedPath(real_destination)).c_str(),
+ std::ios::out | std::ios::trunc | std::ios::binary);
#else
- kwsys_ios::ofstream fout(destination,
- kwsys_ios::ios::out | kwsys_ios::ios::trunc);
+ kwsys::ofstream fout(real_destination.c_str(),
+ std::ios::out | std::ios::trunc | std::ios::binary);
#endif
- if(!fout)
- {
- return false;
- }
+ if(!fout)
+ {
+ return false;
+ }
- // This copy loop is very sensitive on certain platforms with
- // slightly broken stream libraries (like HPUX). Normally, it is
- // incorrect to not check the error condition on the fin.read()
- // before using the data, but the fin.gcount() will be zero if an
- // error occurred. Therefore, the loop should be safe everywhere.
- while(fin)
- {
- fin.read(buffer, bufferSize);
- if(fin.gcount())
+ // This copy loop is very sensitive on certain platforms with
+ // slightly broken stream libraries (like HPUX). Normally, it is
+ // incorrect to not check the error condition on the fin.read()
+ // before using the data, but the fin.gcount() will be zero if an
+ // error occurred. Therefore, the loop should be safe everywhere.
+ while(fin)
{
- fout.write(buffer, fin.gcount());
+ fin.read(buffer, bufferSize);
+ if(fin.gcount())
+ {
+ fout.write(buffer, fin.gcount());
+ }
+ else
+ {
+ break;
+ }
}
- }
- // Make sure the operating system has finished writing the file
- // before closing it. This will ensure the file is finished before
- // the check below.
- fout.flush();
+ // Make sure the operating system has finished writing the file
+ // before closing it. This will ensure the file is finished before
+ // the check below.
+ fout.flush();
- fin.close();
- fout.close();
+ fin.close();
+ fout.close();
- if(!fout)
- {
- return false;
+ if(!fout)
+ {
+ return false;
+ }
}
if ( perms )
{
- if ( !SystemTools::SetPermissions(destination, perm) )
+ if ( !SystemTools::SetPermissions(real_destination, perm) )
{
return false;
}
@@ -2114,7 +2494,7 @@ bool SystemTools::CopyFileAlways(const char* source, const char* destination)
}
//----------------------------------------------------------------------------
-bool SystemTools::CopyAFile(const char* source, const char* destination,
+bool SystemTools::CopyAFile(const std::string& source, const std::string& destination,
bool always)
{
if(always)
@@ -2131,11 +2511,16 @@ bool SystemTools::CopyAFile(const char* source, const char* destination,
* Copy a directory content from "source" directory to the directory named by
* "destination".
*/
-bool SystemTools::CopyADirectory(const char* source, const char* destination,
+bool SystemTools::CopyADirectory(const std::string& source, const std::string& destination,
bool always)
{
Directory dir;
+#ifdef _WIN32
+ dir.Load(Encoding::ToNarrow(
+ SystemTools::ConvertToWindowsExtendedPath(source)));
+#else
dir.Load(source);
+#endif
size_t fileNum;
if ( !SystemTools::MakeDirectory(destination) )
{
@@ -2146,16 +2531,16 @@ bool SystemTools::CopyADirectory(const char* source, const char* destination,
if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)),".") &&
strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)),".."))
{
- kwsys_stl::string fullPath = source;
+ std::string fullPath = source;
fullPath += "/";
fullPath += dir.GetFile(static_cast<unsigned long>(fileNum));
- if(SystemTools::FileIsDirectory(fullPath.c_str()))
+ if(SystemTools::FileIsDirectory(fullPath))
{
- kwsys_stl::string fullDestPath = destination;
+ std::string fullDestPath = destination;
fullDestPath += "/";
fullDestPath += dir.GetFile(static_cast<unsigned long>(fileNum));
- if (!SystemTools::CopyADirectory(fullPath.c_str(),
- fullDestPath.c_str(),
+ if (!SystemTools::CopyADirectory(fullPath,
+ fullDestPath,
always))
{
return false;
@@ -2163,7 +2548,7 @@ bool SystemTools::CopyADirectory(const char* source, const char* destination,
}
else
{
- if(!SystemTools::CopyAFile(fullPath.c_str(), destination, always))
+ if(!SystemTools::CopyAFile(fullPath, destination, always))
{
return false;
}
@@ -2176,17 +2561,30 @@ bool SystemTools::CopyADirectory(const char* source, const char* destination,
// return size of file; also returns zero if no file exists
-unsigned long SystemTools::FileLength(const char* filename)
+unsigned long SystemTools::FileLength(const std::string& filename)
{
- struct stat fs;
- if (stat(filename, &fs) != 0)
+ unsigned long length = 0;
+#ifdef _WIN32
+ WIN32_FILE_ATTRIBUTE_DATA fs;
+ if (GetFileAttributesExW(
+ SystemTools::ConvertToWindowsExtendedPath(filename).c_str(),
+ GetFileExInfoStandard, &fs) != 0)
{
- return 0;
+ /* To support the full 64-bit file size, use fs.nFileSizeHigh
+ * and fs.nFileSizeLow to construct the 64 bit size
+
+ length = ((__int64)fs.nFileSizeHigh << 32) + fs.nFileSizeLow;
+ */
+ length = static_cast<unsigned long>(fs.nFileSizeLow);
}
- else
+#else
+ struct stat fs;
+ if (stat(filename.c_str(), &fs) == 0)
{
- return static_cast<unsigned long>(fs.st_size);
+ length = static_cast<unsigned long>(fs.st_size);
}
+#endif
+ return length;
}
int SystemTools::Strucmp(const char *s1, const char *s2)
@@ -2203,31 +2601,49 @@ int SystemTools::Strucmp(const char *s1, const char *s2)
}
// return file's modified time
-long int SystemTools::ModifiedTime(const char* filename)
+long int SystemTools::ModifiedTime(const std::string& filename)
{
- struct stat fs;
- if (stat(filename, &fs) != 0)
+ long int mt = 0;
+#ifdef _WIN32
+ WIN32_FILE_ATTRIBUTE_DATA fs;
+ if (GetFileAttributesExW(
+ SystemTools::ConvertToWindowsExtendedPath(filename).c_str(),
+ GetFileExInfoStandard,
+ &fs) != 0)
{
- return 0;
+ mt = windows_filetime_to_posix_time(fs.ftLastWriteTime);
}
- else
+#else
+ struct stat fs;
+ if (stat(filename.c_str(), &fs) == 0)
{
- return static_cast<long int>(fs.st_mtime);
+ mt = static_cast<long int>(fs.st_mtime);
}
+#endif
+ return mt;
}
// return file's creation time
-long int SystemTools::CreationTime(const char* filename)
+long int SystemTools::CreationTime(const std::string& filename)
{
- struct stat fs;
- if (stat(filename, &fs) != 0)
+ long int ct = 0;
+#ifdef _WIN32
+ WIN32_FILE_ATTRIBUTE_DATA fs;
+ if (GetFileAttributesExW(
+ SystemTools::ConvertToWindowsExtendedPath(filename).c_str(),
+ GetFileExInfoStandard,
+ &fs) != 0)
{
- return 0;
+ ct = windows_filetime_to_posix_time(fs.ftCreationTime);
}
- else
+#else
+ struct stat fs;
+ if (stat(filename.c_str(), &fs) == 0)
{
- return fs.st_ctime >= 0 ? static_cast<long int>(fs.st_ctime) : 0;
+ ct = fs.st_ctime >= 0 ? static_cast<long int>(fs.st_ctime) : 0;
}
+#endif
+ return ct;
}
bool SystemTools::ConvertDateMacroString(const char *str, time_t *tmt)
@@ -2332,34 +2748,55 @@ bool SystemTools::ConvertTimeStampMacroString(const char *str, time_t *tmt)
return true;
}
-kwsys_stl::string SystemTools::GetLastSystemError()
+std::string SystemTools::GetLastSystemError()
{
int e = errno;
return strerror(e);
}
-bool SystemTools::RemoveFile(const char* source)
+bool SystemTools::RemoveFile(const std::string& source)
{
#ifdef _WIN32
+ std::wstring const& ws =
+ SystemTools::ConvertToWindowsExtendedPath(source);
+ if (DeleteFileW(ws.c_str()))
+ {
+ return true;
+ }
+ DWORD err = GetLastError();
+ if (err == ERROR_FILE_NOT_FOUND ||
+ err == ERROR_PATH_NOT_FOUND)
+ {
+ return true;
+ }
+ if (err != ERROR_ACCESS_DENIED)
+ {
+ return false;
+ }
+ /* The file may be read-only. Try adding write permission. */
mode_t mode;
- if ( !SystemTools::GetPermissions(source, mode) )
+ if (!SystemTools::GetPermissions(source, mode) ||
+ !SystemTools::SetPermissions(source, S_IWRITE))
{
+ SetLastError(err);
return false;
}
- /* Win32 unlink is stupid --- it fails if the file is read-only */
- SystemTools::SetPermissions(source, S_IWRITE);
-#endif
- bool res = unlink(source) != 0 ? false : true;
-#ifdef _WIN32
- if ( !res )
+ if (DeleteFileW(ws.c_str()) ||
+ GetLastError() == ERROR_FILE_NOT_FOUND ||
+ GetLastError() == ERROR_PATH_NOT_FOUND)
{
- SystemTools::SetPermissions(source, mode);
+ return true;
}
+ /* Try to restore the original permissions. */
+ SystemTools::SetPermissions(source, mode);
+ SetLastError(err);
+ return false;
+#else
+ return unlink(source.c_str()) == 0 || errno == ENOENT;
#endif
- return res;
}
-bool SystemTools::RemoveADirectory(const char* source)
+bool SystemTools::RemoveADirectory(const std::string& source)
{
// Add write permission to the directory so we can modify its
// content to remove files and directories from it.
@@ -2375,27 +2812,32 @@ bool SystemTools::RemoveADirectory(const char* source)
}
Directory dir;
+#ifdef _WIN32
+ dir.Load(Encoding::ToNarrow(
+ SystemTools::ConvertToWindowsExtendedPath(source)));
+#else
dir.Load(source);
+#endif
size_t fileNum;
for (fileNum = 0; fileNum < dir.GetNumberOfFiles(); ++fileNum)
{
if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)),".") &&
strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)),".."))
{
- kwsys_stl::string fullPath = source;
+ std::string fullPath = source;
fullPath += "/";
fullPath += dir.GetFile(static_cast<unsigned long>(fileNum));
- if(SystemTools::FileIsDirectory(fullPath.c_str()) &&
- !SystemTools::FileIsSymlink(fullPath.c_str()))
+ if(SystemTools::FileIsDirectory(fullPath) &&
+ !SystemTools::FileIsSymlink(fullPath))
{
- if (!SystemTools::RemoveADirectory(fullPath.c_str()))
+ if (!SystemTools::RemoveADirectory(fullPath))
{
return false;
}
}
else
{
- if(!SystemTools::RemoveFile(fullPath.c_str()))
+ if(!SystemTools::RemoveFile(fullPath))
{
return false;
}
@@ -2418,13 +2860,13 @@ size_t SystemTools::GetMaximumFilePathLength()
* the system search path. Returns the full path to the file if it is
* found. Otherwise, the empty string is returned.
*/
-kwsys_stl::string SystemTools
-::FindName(const char* name,
- const kwsys_stl::vector<kwsys_stl::string>& userPaths,
+std::string SystemTools
+::FindName(const std::string& name,
+ const std::vector<std::string>& userPaths,
bool no_system_path)
{
// Add the system search path to our path first
- kwsys_stl::vector<kwsys_stl::string> path;
+ std::vector<std::string> path;
if (!no_system_path)
{
SystemTools::GetPath(path, "CMAKE_FILE_PATH");
@@ -2432,7 +2874,7 @@ kwsys_stl::string SystemTools
}
// now add the additional paths
{
- for(kwsys_stl::vector<kwsys_stl::string>::const_iterator i = userPaths.begin();
+ for(std::vector<std::string>::const_iterator i = userPaths.begin();
i != userPaths.end(); ++i)
{
path.push_back(*i);
@@ -2440,24 +2882,24 @@ kwsys_stl::string SystemTools
}
// Add a trailing slash to all paths to aid the search process.
{
- for(kwsys_stl::vector<kwsys_stl::string>::iterator i = path.begin();
+ for(std::vector<std::string>::iterator i = path.begin();
i != path.end(); ++i)
{
- kwsys_stl::string& p = *i;
- if(p.empty() || p[p.size()-1] != '/')
+ std::string& p = *i;
+ if(p.empty() || *p.rbegin() != '/')
{
p += "/";
}
}
}
// now look for the file
- kwsys_stl::string tryPath;
- for(kwsys_stl::vector<kwsys_stl::string>::const_iterator p = path.begin();
+ std::string tryPath;
+ for(std::vector<std::string>::const_iterator p = path.begin();
p != path.end(); ++p)
{
tryPath = *p;
tryPath += name;
- if(SystemTools::FileExists(tryPath.c_str()))
+ if(SystemTools::FileExists(tryPath))
{
return tryPath;
}
@@ -2471,15 +2913,15 @@ kwsys_stl::string SystemTools
* the system search path. Returns the full path to the file if it is
* found. Otherwise, the empty string is returned.
*/
-kwsys_stl::string SystemTools
-::FindFile(const char* name,
- const kwsys_stl::vector<kwsys_stl::string>& userPaths,
+std::string SystemTools
+::FindFile(const std::string& name,
+ const std::vector<std::string>& userPaths,
bool no_system_path)
{
- kwsys_stl::string tryPath = SystemTools::FindName(name, userPaths, no_system_path);
- if(tryPath != "" && !SystemTools::FileIsDirectory(tryPath.c_str()))
+ std::string tryPath = SystemTools::FindName(name, userPaths, no_system_path);
+ if(!tryPath.empty() && !SystemTools::FileIsDirectory(tryPath))
{
- return SystemTools::CollapseFullPath(tryPath.c_str());
+ return SystemTools::CollapseFullPath(tryPath);
}
// Couldn't find the file.
return "";
@@ -2490,15 +2932,15 @@ kwsys_stl::string SystemTools
* the system search path. Returns the full path to the directory if it is
* found. Otherwise, the empty string is returned.
*/
-kwsys_stl::string SystemTools
-::FindDirectory(const char* name,
- const kwsys_stl::vector<kwsys_stl::string>& userPaths,
+std::string SystemTools
+::FindDirectory(const std::string& name,
+ const std::vector<std::string>& userPaths,
bool no_system_path)
{
- kwsys_stl::string tryPath = SystemTools::FindName(name, userPaths, no_system_path);
- if(tryPath != "" && SystemTools::FileIsDirectory(tryPath.c_str()))
+ std::string tryPath = SystemTools::FindName(name, userPaths, no_system_path);
+ if(!tryPath.empty() && SystemTools::FileIsDirectory(tryPath))
{
- return SystemTools::CollapseFullPath(tryPath.c_str());
+ return SystemTools::CollapseFullPath(tryPath);
}
// Couldn't find the file.
return "";
@@ -2509,58 +2951,56 @@ kwsys_stl::string SystemTools
* the system search path. Returns the full path to the executable if it is
* found. Otherwise, the empty string is returned.
*/
-kwsys_stl::string SystemTools::FindProgram(
+std::string SystemTools::FindProgram(
const char* nameIn,
- const kwsys_stl::vector<kwsys_stl::string>& userPaths,
+ const std::vector<std::string>& userPaths,
bool no_system_path)
{
if(!nameIn || !*nameIn)
{
return "";
}
- kwsys_stl::string name = nameIn;
- kwsys_stl::vector<kwsys_stl::string> extensions;
+ return SystemTools::FindProgram(std::string(nameIn), userPaths, no_system_path);
+}
+
+std::string SystemTools::FindProgram(
+ const std::string& name,
+ const std::vector<std::string>& userPaths,
+ bool no_system_path)
+{
+ std::string tryPath;
+
#if defined (_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
- bool hasExtension = false;
+ std::vector<std::string> extensions;
// check to see if the name already has a .xxx at
// the end of it
- if(name.size() > 3 && name[name.size()-4] == '.')
- {
- hasExtension = true;
- }
// on windows try .com then .exe
- if(!hasExtension)
+ if(name.size() <= 3 || name[name.size()-4] != '.')
{
extensions.push_back(".com");
extensions.push_back(".exe");
- }
-#endif
- kwsys_stl::string tryPath;
- // first try with extensions if the os supports them
- if(extensions.size())
- {
- for(kwsys_stl::vector<kwsys_stl::string>::iterator i =
+ // first try with extensions if the os supports them
+ for(std::vector<std::string>::iterator i =
extensions.begin(); i != extensions.end(); ++i)
{
tryPath = name;
tryPath += *i;
- if(SystemTools::FileExists(tryPath.c_str()) &&
- !SystemTools::FileIsDirectory(tryPath.c_str()))
+ if(SystemTools::FileExists(tryPath, true))
{
- return SystemTools::CollapseFullPath(tryPath.c_str());
+ return SystemTools::CollapseFullPath(tryPath);
}
}
}
+#endif
+
// now try just the name
- tryPath = name;
- if(SystemTools::FileExists(tryPath.c_str()) &&
- !SystemTools::FileIsDirectory(tryPath.c_str()))
+ if(SystemTools::FileExists(name, true))
{
- return SystemTools::CollapseFullPath(tryPath.c_str());
+ return SystemTools::CollapseFullPath(name);
}
// now construct the path
- kwsys_stl::vector<kwsys_stl::string> path;
+ std::vector<std::string> path;
// Add the system search path to our path.
if (!no_system_path)
{
@@ -2568,7 +3008,7 @@ kwsys_stl::string SystemTools::FindProgram(
}
// now add the additional paths
{
- for(kwsys_stl::vector<kwsys_stl::string>::const_iterator i =
+ for(std::vector<std::string>::const_iterator i =
userPaths.begin(); i != userPaths.end(); ++i)
{
path.push_back(*i);
@@ -2576,63 +3016,60 @@ kwsys_stl::string SystemTools::FindProgram(
}
// Add a trailing slash to all paths to aid the search process.
{
- for(kwsys_stl::vector<kwsys_stl::string>::iterator i = path.begin();
+ for(std::vector<std::string>::iterator i = path.begin();
i != path.end(); ++i)
{
- kwsys_stl::string& p = *i;
- if(p.empty() || p[p.size()-1] != '/')
+ std::string& p = *i;
+ if(p.empty() || *p.rbegin() != '/')
{
p += "/";
}
}
}
// Try each path
- for(kwsys_stl::vector<kwsys_stl::string>::iterator p = path.begin();
+ for(std::vector<std::string>::iterator p = path.begin();
p != path.end(); ++p)
{
#ifdef _WIN32
// Remove double quotes from the path on windows
SystemTools::ReplaceString(*p, "\"", "");
#endif
+#if defined (_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
// first try with extensions
- if(extensions.size())
+ for(std::vector<std::string>::iterator ext
+ = extensions.begin(); ext != extensions.end(); ++ext)
{
- for(kwsys_stl::vector<kwsys_stl::string>::iterator ext
- = extensions.begin(); ext != extensions.end(); ++ext)
+ tryPath = *p;
+ tryPath += name;
+ tryPath += *ext;
+ if(SystemTools::FileExists(tryPath, true))
{
- tryPath = *p;
- tryPath += name;
- tryPath += *ext;
- if(SystemTools::FileExists(tryPath.c_str()) &&
- !SystemTools::FileIsDirectory(tryPath.c_str()))
- {
- return SystemTools::CollapseFullPath(tryPath.c_str());
- }
+ return SystemTools::CollapseFullPath(tryPath);
}
}
+#endif
// now try it without them
tryPath = *p;
tryPath += name;
- if(SystemTools::FileExists(tryPath.c_str()) &&
- !SystemTools::FileIsDirectory(tryPath.c_str()))
+ if(SystemTools::FileExists(tryPath, true))
{
- return SystemTools::CollapseFullPath(tryPath.c_str());
+ return SystemTools::CollapseFullPath(tryPath);
}
}
// Couldn't find the program.
return "";
}
-kwsys_stl::string SystemTools::FindProgram(
- const kwsys_stl::vector<kwsys_stl::string>& names,
- const kwsys_stl::vector<kwsys_stl::string>& path,
+std::string SystemTools::FindProgram(
+ const std::vector<std::string>& names,
+ const std::vector<std::string>& path,
bool noSystemPath)
{
- for(kwsys_stl::vector<kwsys_stl::string>::const_iterator it = names.begin();
+ for(std::vector<std::string>::const_iterator it = names.begin();
it != names.end() ; ++it)
{
// Try to find the program.
- kwsys_stl::string result = SystemTools::FindProgram(it->c_str(),
+ std::string result = SystemTools::FindProgram(*it,
path,
noSystemPath);
if ( !result.empty() )
@@ -2648,23 +3085,22 @@ kwsys_stl::string SystemTools::FindProgram(
* the system search path. Returns the full path to the library if it is
* found. Otherwise, the empty string is returned.
*/
-kwsys_stl::string SystemTools
-::FindLibrary(const char* name,
- const kwsys_stl::vector<kwsys_stl::string>& userPaths)
+std::string SystemTools
+::FindLibrary(const std::string& name,
+ const std::vector<std::string>& userPaths)
{
// See if the executable exists as written.
- if(SystemTools::FileExists(name) &&
- !SystemTools::FileIsDirectory(name))
+ if(SystemTools::FileExists(name, true))
{
return SystemTools::CollapseFullPath(name);
}
// Add the system search path to our path.
- kwsys_stl::vector<kwsys_stl::string> path;
+ std::vector<std::string> path;
SystemTools::GetPath(path);
// now add the additional paths
{
- for(kwsys_stl::vector<kwsys_stl::string>::const_iterator i = userPaths.begin();
+ for(std::vector<std::string>::const_iterator i = userPaths.begin();
i != userPaths.end(); ++i)
{
path.push_back(*i);
@@ -2672,84 +3108,77 @@ kwsys_stl::string SystemTools
}
// Add a trailing slash to all paths to aid the search process.
{
- for(kwsys_stl::vector<kwsys_stl::string>::iterator i = path.begin();
+ for(std::vector<std::string>::iterator i = path.begin();
i != path.end(); ++i)
{
- kwsys_stl::string& p = *i;
- if(p.empty() || p[p.size()-1] != '/')
+ std::string& p = *i;
+ if(p.empty() || *p.rbegin() != '/')
{
p += "/";
}
}
}
- kwsys_stl::string tryPath;
- for(kwsys_stl::vector<kwsys_stl::string>::const_iterator p = path.begin();
+ std::string tryPath;
+ for(std::vector<std::string>::const_iterator p = path.begin();
p != path.end(); ++p)
{
#if defined(__APPLE__)
tryPath = *p;
tryPath += name;
tryPath += ".framework";
- if(SystemTools::FileExists(tryPath.c_str())
- && SystemTools::FileIsDirectory(tryPath.c_str()))
+ if(SystemTools::FileIsDirectory(tryPath))
{
- return SystemTools::CollapseFullPath(tryPath.c_str());
+ return SystemTools::CollapseFullPath(tryPath);
}
#endif
#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__)
tryPath = *p;
tryPath += name;
tryPath += ".lib";
- if(SystemTools::FileExists(tryPath.c_str())
- && !SystemTools::FileIsDirectory(tryPath.c_str()))
+ if(SystemTools::FileExists(tryPath, true))
{
- return SystemTools::CollapseFullPath(tryPath.c_str());
+ return SystemTools::CollapseFullPath(tryPath);
}
#else
tryPath = *p;
tryPath += "lib";
tryPath += name;
tryPath += ".so";
- if(SystemTools::FileExists(tryPath.c_str())
- && !SystemTools::FileIsDirectory(tryPath.c_str()))
+ if(SystemTools::FileExists(tryPath, true))
{
- return SystemTools::CollapseFullPath(tryPath.c_str());
+ return SystemTools::CollapseFullPath(tryPath);
}
tryPath = *p;
tryPath += "lib";
tryPath += name;
tryPath += ".a";
- if(SystemTools::FileExists(tryPath.c_str())
- && !SystemTools::FileIsDirectory(tryPath.c_str()))
+ if(SystemTools::FileExists(tryPath, true))
{
- return SystemTools::CollapseFullPath(tryPath.c_str());
+ return SystemTools::CollapseFullPath(tryPath);
}
tryPath = *p;
tryPath += "lib";
tryPath += name;
tryPath += ".sl";
- if(SystemTools::FileExists(tryPath.c_str())
- && !SystemTools::FileIsDirectory(tryPath.c_str()))
+ if(SystemTools::FileExists(tryPath, true))
{
- return SystemTools::CollapseFullPath(tryPath.c_str());
+ return SystemTools::CollapseFullPath(tryPath);
}
tryPath = *p;
tryPath += "lib";
tryPath += name;
tryPath += ".dylib";
- if(SystemTools::FileExists(tryPath.c_str())
- && !SystemTools::FileIsDirectory(tryPath.c_str()))
+ if(SystemTools::FileExists(tryPath, true))
{
- return SystemTools::CollapseFullPath(tryPath.c_str());
+ return SystemTools::CollapseFullPath(tryPath);
}
tryPath = *p;
tryPath += "lib";
tryPath += name;
tryPath += ".dll";
- if(SystemTools::FileExists(tryPath.c_str())
- && !SystemTools::FileIsDirectory(tryPath.c_str()))
+ if(SystemTools::FileExists(tryPath, true))
{
- return SystemTools::CollapseFullPath(tryPath.c_str());
+ return SystemTools::CollapseFullPath(tryPath);
}
#endif
}
@@ -2758,32 +3187,34 @@ kwsys_stl::string SystemTools
return "";
}
-kwsys_stl::string SystemTools::GetRealPath(const char* path)
+std::string SystemTools::GetRealPath(const std::string& path,
+ std::string* errorMessage)
{
- kwsys_stl::string ret;
- Realpath(path, ret);
+ std::string ret;
+ Realpath(path, ret, errorMessage);
return ret;
}
-bool SystemTools::FileIsDirectory(const char* name)
+bool SystemTools::FileIsDirectory(const std::string& inName)
{
- size_t length = strlen(name);
- if (length == 0)
+ if (inName.empty())
{
return false;
}
+ size_t length = inName.size();
+ const char* name = inName.c_str();
// Remove any trailing slash from the name except in a root component.
char local_buffer[KWSYS_SYSTEMTOOLS_MAXPATH];
std::string string_buffer;
size_t last = length-1;
if(last > 0 && (name[last] == '/' || name[last] == '\\')
- && strcmp(name, "/") !=0 && name[last-1] != ':')
+ && strcmp(name, "/") != 0 && name[last-1] != ':')
{
- if(last < sizeof(local_buffer))
+ if (last < sizeof(local_buffer))
{
memcpy(local_buffer, name, last);
- local_buffer[last] = 0;
+ local_buffer[last] = '\0';
name = local_buffer;
}
else
@@ -2794,12 +3225,16 @@ bool SystemTools::FileIsDirectory(const char* name)
}
// Now check the file node type.
+#if defined( _WIN32 )
+ DWORD attr = GetFileAttributesW(
+ SystemTools::ConvertToWindowsExtendedPath(name).c_str());
+ if (attr != INVALID_FILE_ATTRIBUTES)
+ {
+ return (attr & FILE_ATTRIBUTE_DIRECTORY) != 0;
+#else
struct stat fs;
if(stat(name, &fs) == 0)
{
-#if defined( _WIN32 ) && !defined(__CYGWIN__)
- return ((fs.st_mode & _S_IFDIR) != 0);
-#else
return S_ISDIR(fs.st_mode);
#endif
}
@@ -2809,14 +3244,22 @@ bool SystemTools::FileIsDirectory(const char* name)
}
}
-bool SystemTools::FileIsSymlink(const char* name)
+bool SystemTools::FileIsSymlink(const std::string& name)
{
#if defined( _WIN32 )
- (void)name;
- return false;
+ DWORD attr = GetFileAttributesW(
+ SystemTools::ConvertToWindowsExtendedPath(name).c_str());
+ if (attr != INVALID_FILE_ATTRIBUTES)
+ {
+ return (attr & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
+ }
+ else
+ {
+ return false;
+ }
#else
struct stat fs;
- if(lstat(name, &fs) == 0)
+ if(lstat(name.c_str(), &fs) == 0)
{
return S_ISLNK(fs.st_mode);
}
@@ -2828,29 +3271,29 @@ bool SystemTools::FileIsSymlink(const char* name)
}
#if defined(_WIN32) && !defined(__CYGWIN__)
-bool SystemTools::CreateSymlink(const char*, const char*)
+bool SystemTools::CreateSymlink(const std::string&, const std::string&)
{
return false;
}
#else
-bool SystemTools::CreateSymlink(const char* origName, const char* newName)
+bool SystemTools::CreateSymlink(const std::string& origName, const std::string& newName)
{
- return symlink(origName, newName) >= 0;
+ return symlink(origName.c_str(), newName.c_str()) >= 0;
}
#endif
#if defined(_WIN32) && !defined(__CYGWIN__)
-bool SystemTools::ReadSymlink(const char*, kwsys_stl::string&)
+bool SystemTools::ReadSymlink(const std::string&, std::string&)
{
return false;
}
#else
-bool SystemTools::ReadSymlink(const char* newName,
- kwsys_stl::string& origName)
+bool SystemTools::ReadSymlink(const std::string& newName,
+ std::string& origName)
{
char buf[KWSYS_SYSTEMTOOLS_MAXPATH+1];
int count =
- static_cast<int>(readlink(newName, buf, KWSYS_SYSTEMTOOLS_MAXPATH));
+ static_cast<int>(readlink(newName.c_str(), buf, KWSYS_SYSTEMTOOLS_MAXPATH));
if(count >= 0)
{
// Add null-terminator.
@@ -2865,47 +3308,47 @@ bool SystemTools::ReadSymlink(const char* newName,
}
#endif
-int SystemTools::ChangeDirectory(const char *dir)
+int SystemTools::ChangeDirectory(const std::string& dir)
{
return Chdir(dir);
}
-kwsys_stl::string SystemTools::GetCurrentWorkingDirectory(bool collapse)
+std::string SystemTools::GetCurrentWorkingDirectory(bool collapse)
{
char buf[2048];
const char* cwd = Getcwd(buf, 2048);
- kwsys_stl::string path;
+ std::string path;
if ( cwd )
{
path = cwd;
}
if(collapse)
{
- return SystemTools::CollapseFullPath(path.c_str());
+ return SystemTools::CollapseFullPath(path);
}
return path;
}
-kwsys_stl::string SystemTools::GetProgramPath(const char* in_name)
+std::string SystemTools::GetProgramPath(const std::string& in_name)
{
- kwsys_stl::string dir, file;
+ std::string dir, file;
SystemTools::SplitProgramPath(in_name, dir, file);
return dir;
}
-bool SystemTools::SplitProgramPath(const char* in_name,
- kwsys_stl::string& dir,
- kwsys_stl::string& file,
+bool SystemTools::SplitProgramPath(const std::string& in_name,
+ std::string& dir,
+ std::string& file,
bool)
{
dir = in_name;
file = "";
SystemTools::ConvertToUnixSlashes(dir);
- if(!SystemTools::FileIsDirectory(dir.c_str()))
+ if(!SystemTools::FileIsDirectory(dir))
{
- kwsys_stl::string::size_type slashPos = dir.rfind("/");
- if(slashPos != kwsys_stl::string::npos)
+ std::string::size_type slashPos = dir.rfind("/");
+ if(slashPos != std::string::npos)
{
file = dir.substr(slashPos+1);
dir = dir.substr(0, slashPos);
@@ -2916,9 +3359,9 @@ bool SystemTools::SplitProgramPath(const char* in_name,
dir = "";
}
}
- if(!(dir == "") && !SystemTools::FileIsDirectory(dir.c_str()))
+ if(!(dir.empty()) && !SystemTools::FileIsDirectory(dir))
{
- kwsys_stl::string oldDir = in_name;
+ std::string oldDir = in_name;
SystemTools::ConvertToUnixSlashes(oldDir);
dir = in_name;
return false;
@@ -2927,22 +3370,22 @@ bool SystemTools::SplitProgramPath(const char* in_name,
}
bool SystemTools::FindProgramPath(const char* argv0,
- kwsys_stl::string& pathOut,
- kwsys_stl::string& errorMsg,
+ std::string& pathOut,
+ std::string& errorMsg,
const char* exeName,
const char* buildDir,
const char* installPrefix )
{
- kwsys_stl::vector<kwsys_stl::string> failures;
- kwsys_stl::string self = argv0 ? argv0 : "";
+ std::vector<std::string> failures;
+ std::string self = argv0 ? argv0 : "";
failures.push_back(self);
SystemTools::ConvertToUnixSlashes(self);
- self = SystemTools::FindProgram(self.c_str());
- if(!SystemTools::FileExists(self.c_str()))
+ self = SystemTools::FindProgram(self);
+ if(!SystemTools::FileExists(self))
{
if(buildDir)
{
- kwsys_stl::string intdir = ".";
+ std::string intdir = ".";
#ifdef CMAKE_INTDIR
intdir = CMAKE_INTDIR;
#endif
@@ -2956,7 +3399,7 @@ bool SystemTools::FindProgramPath(const char* argv0,
}
if(installPrefix)
{
- if(!SystemTools::FileExists(self.c_str()))
+ if(!SystemTools::FileExists(self))
{
failures.push_back(self);
self = installPrefix;
@@ -2964,10 +3407,10 @@ bool SystemTools::FindProgramPath(const char* argv0,
self += exeName;
}
}
- if(!SystemTools::FileExists(self.c_str()))
+ if(!SystemTools::FileExists(self))
{
failures.push_back(self);
- kwsys_ios::ostringstream msg;
+ std::ostringstream msg;
msg << "Can not find the command line program ";
if (exeName)
{
@@ -2979,10 +3422,10 @@ bool SystemTools::FindProgramPath(const char* argv0,
msg << " argv[0] = \"" << argv0 << "\"\n";
}
msg << " Attempted paths:\n";
- kwsys_stl::vector<kwsys_stl::string>::iterator i;
+ std::vector<std::string>::iterator i;
for(i=failures.begin(); i != failures.end(); ++i)
{
- msg << " \"" << i->c_str() << "\"\n";
+ msg << " \"" << *i << "\"\n";
}
errorMsg = msg.str();
return false;
@@ -2992,33 +3435,33 @@ bool SystemTools::FindProgramPath(const char* argv0,
}
-kwsys_stl::string SystemTools::CollapseFullPath(const char* in_relative)
+std::string SystemTools::CollapseFullPath(const std::string& in_relative)
{
return SystemTools::CollapseFullPath(in_relative, 0);
}
-void SystemTools::AddTranslationPath(const char * a, const char * b)
+void SystemTools::AddTranslationPath(const std::string& a, const std::string& b)
{
- kwsys_stl::string path_a = a;
- kwsys_stl::string path_b = b;
+ std::string path_a = a;
+ std::string path_b = b;
SystemTools::ConvertToUnixSlashes(path_a);
SystemTools::ConvertToUnixSlashes(path_b);
// First check this is a directory path, since we don't want the table to
// grow too fat
- if( SystemTools::FileIsDirectory( path_a.c_str() ) )
+ if( SystemTools::FileIsDirectory( path_a ) )
{
// Make sure the path is a full path and does not contain no '..'
// Ken--the following code is incorrect. .. can be in a valid path
// for example /home/martink/MyHubba...Hubba/Src
- if( SystemTools::FileIsFullPath(path_b.c_str()) && path_b.find("..")
- == kwsys_stl::string::npos )
+ if( SystemTools::FileIsFullPath(path_b) && path_b.find("..")
+ == std::string::npos )
{
// Before inserting make sure path ends with '/'
- if(path_a.size() && path_a[path_a.size() -1] != '/')
+ if(!path_a.empty() && *path_a.rbegin() != '/')
{
path_a += '/';
}
- if(path_b.size() && path_b[path_b.size() -1] != '/')
+ if(!path_b.empty() && *path_b.rbegin() != '/')
{
path_b += '/';
}
@@ -3031,14 +3474,14 @@ void SystemTools::AddTranslationPath(const char * a, const char * b)
}
}
-void SystemTools::AddKeepPath(const char* dir)
+void SystemTools::AddKeepPath(const std::string& dir)
{
- kwsys_stl::string cdir;
+ std::string cdir;
Realpath(SystemTools::CollapseFullPath(dir).c_str(), cdir);
- SystemTools::AddTranslationPath(cdir.c_str(), dir);
+ SystemTools::AddTranslationPath(cdir, dir);
}
-void SystemTools::CheckTranslationPath(kwsys_stl::string & path)
+void SystemTools::CheckTranslationPath(std::string & path)
{
// Do not translate paths that are too short to have meaningful
// translations.
@@ -3054,7 +3497,7 @@ void SystemTools::CheckTranslationPath(kwsys_stl::string & path)
// In case a file was specified we still have to go through this:
// Now convert any path found in the table back to the one desired:
- kwsys_stl::map<kwsys_stl::string,kwsys_stl::string>::const_iterator it;
+ std::map<std::string,std::string>::const_iterator it;
for(it = SystemTools::TranslationMap->begin();
it != SystemTools::TranslationMap->end();
++it )
@@ -3072,41 +3515,43 @@ void SystemTools::CheckTranslationPath(kwsys_stl::string & path)
static void
SystemToolsAppendComponents(
- kwsys_stl::vector<kwsys_stl::string>& out_components,
- kwsys_stl::vector<kwsys_stl::string>::const_iterator first,
- kwsys_stl::vector<kwsys_stl::string>::const_iterator last)
+ std::vector<std::string>& out_components,
+ std::vector<std::string>::const_iterator first,
+ std::vector<std::string>::const_iterator last)
{
- for(kwsys_stl::vector<kwsys_stl::string>::const_iterator i = first;
+ static const std::string up = "..";
+ static const std::string cur = ".";
+ for(std::vector<std::string>::const_iterator i = first;
i != last; ++i)
{
- if(*i == "..")
+ if(*i == up)
{
if(out_components.size() > 1)
{
- out_components.erase(out_components.end()-1, out_components.end());
+ out_components.resize(out_components.size()-1);
}
}
- else if(!(*i == ".") && !(*i == ""))
+ else if(!i->empty() && *i != cur)
{
out_components.push_back(*i);
}
}
}
-kwsys_stl::string SystemTools::CollapseFullPath(const char* in_path,
+std::string SystemTools::CollapseFullPath(const std::string& in_path,
const char* in_base)
{
// Collect the output path components.
- kwsys_stl::vector<kwsys_stl::string> out_components;
+ std::vector<std::string> out_components;
// Split the input path components.
- kwsys_stl::vector<kwsys_stl::string> path_components;
+ std::vector<std::string> path_components;
SystemTools::SplitPath(in_path, path_components);
// If the input path is relative, start with a base path.
if(path_components[0].length() == 0)
{
- kwsys_stl::vector<kwsys_stl::string> base_components;
+ std::vector<std::string> base_components;
if(in_base)
{
// Use the given base path.
@@ -3139,7 +3584,62 @@ kwsys_stl::string SystemTools::CollapseFullPath(const char* in_path,
path_components.end());
// Transform the path back to a string.
- kwsys_stl::string newPath = SystemTools::JoinPath(out_components);
+ std::string newPath = SystemTools::JoinPath(out_components);
+
+ // Update the translation table with this potentially new path. I am not
+ // sure why this line is here, it seems really questionable, but yet I
+ // would put good money that if I remove it something will break, basically
+ // from what I can see it created a mapping from the collapsed path, to be
+ // replaced by the input path, which almost completely does the opposite of
+ // this function, the only thing preventing this from happening a lot is
+ // that if the in_path has a .. in it, then it is not added to the
+ // translation table. So for most calls this either does nothing due to the
+ // .. or it adds a translation between identical paths as nothing was
+ // collapsed, so I am going to try to comment it out, and see what hits the
+ // fan, hopefully quickly.
+ // Commented out line below:
+ //SystemTools::AddTranslationPath(newPath, in_path);
+
+ SystemTools::CheckTranslationPath(newPath);
+#ifdef _WIN32
+ newPath = SystemTools::GetActualCaseForPath(newPath);
+ SystemTools::ConvertToUnixSlashes(newPath);
+#endif
+ // Return the reconstructed path.
+ return newPath;
+}
+
+std::string SystemTools::CollapseFullPath(const std::string& in_path,
+ const std::string& in_base)
+{
+ // Collect the output path components.
+ std::vector<std::string> out_components;
+
+ // Split the input path components.
+ std::vector<std::string> path_components;
+ SystemTools::SplitPath(in_path, path_components);
+
+ // If the input path is relative, start with a base path.
+ if(path_components[0].length() == 0)
+ {
+ std::vector<std::string> base_components;
+ // Use the given base path.
+ SystemTools::SplitPath(in_base, base_components);
+
+ // Append base path components to the output path.
+ out_components.push_back(base_components[0]);
+ SystemToolsAppendComponents(out_components,
+ base_components.begin()+1,
+ base_components.end());
+ }
+
+ // Append input path components to the output path.
+ SystemToolsAppendComponents(out_components,
+ path_components.begin(),
+ path_components.end());
+
+ // Transform the path back to a string.
+ std::string newPath = SystemTools::JoinPath(out_components);
// Update the translation table with this potentially new path. I am not
// sure why this line is here, it seems really questionable, but yet I
@@ -3153,11 +3653,11 @@ kwsys_stl::string SystemTools::CollapseFullPath(const char* in_path,
// collapsed, so I am going to try to comment it out, and see what hits the
// fan, hopefully quickly.
// Commented out line below:
- //SystemTools::AddTranslationPath(newPath.c_str(), in_path);
+ //SystemTools::AddTranslationPath(newPath, in_path);
SystemTools::CheckTranslationPath(newPath);
#ifdef _WIN32
- newPath = SystemTools::GetActualCaseForPath(newPath.c_str());
+ newPath = SystemTools::GetActualCaseForPath(newPath);
SystemTools::ConvertToUnixSlashes(newPath);
#endif
// Return the reconstructed path.
@@ -3165,7 +3665,7 @@ kwsys_stl::string SystemTools::CollapseFullPath(const char* in_path,
}
// compute the relative path from here to there
-kwsys_stl::string SystemTools::RelativePath(const char* local, const char* remote)
+std::string SystemTools::RelativePath(const std::string& local, const std::string& remote)
{
if(!SystemTools::FileIsFullPath(local))
{
@@ -3176,11 +3676,14 @@ kwsys_stl::string SystemTools::RelativePath(const char* local, const char* remot
return "";
}
+ std::string l = SystemTools::CollapseFullPath(local);
+ std::string r = SystemTools::CollapseFullPath(remote);
+
// split up both paths into arrays of strings using / as a separator
- kwsys_stl::vector<kwsys::String> localSplit = SystemTools::SplitString(local, '/', true);
- kwsys_stl::vector<kwsys::String> remoteSplit = SystemTools::SplitString(remote, '/', true);
- kwsys_stl::vector<kwsys::String> commonPath; // store shared parts of path in this array
- kwsys_stl::vector<kwsys::String> finalPath; // store the final relative path here
+ std::vector<kwsys::String> localSplit = SystemTools::SplitString(l, '/', true);
+ std::vector<kwsys::String> remoteSplit = SystemTools::SplitString(r, '/', true);
+ std::vector<kwsys::String> commonPath; // store shared parts of path in this array
+ std::vector<kwsys::String> finalPath; // store the final relative path here
// count up how many matching directory names there are from the start
unsigned int sameCount = 0;
while(
@@ -3218,28 +3721,28 @@ kwsys_stl::string SystemTools::RelativePath(const char* local, const char* remot
// path into the remote dir
for(unsigned int i = 0; i < localSplit.size(); ++i)
{
- if(localSplit[i].size())
+ if(!localSplit[i].empty())
{
finalPath.push_back("../");
}
}
// for each entry that is not common in the remote path add it
// to the final path.
- for(kwsys_stl::vector<String>::iterator vit = remoteSplit.begin();
+ for(std::vector<String>::iterator vit = remoteSplit.begin();
vit != remoteSplit.end(); ++vit)
{
- if(vit->size())
+ if(!vit->empty())
{
finalPath.push_back(*vit);
}
}
- kwsys_stl::string relativePath; // result string
+ std::string relativePath; // result string
// now turn the array of directories into a unix path by puttint /
// between each entry that does not already have one
- for(kwsys_stl::vector<String>::iterator vit1 = finalPath.begin();
+ for(std::vector<String>::iterator vit1 = finalPath.begin();
vit1 != finalPath.end(); ++vit1)
{
- if(relativePath.size() && relativePath[relativePath.size()-1] != '/')
+ if(!relativePath.empty() && *relativePath.rbegin() != '/')
{
relativePath += "/";
}
@@ -3249,11 +3752,11 @@ kwsys_stl::string SystemTools::RelativePath(const char* local, const char* remot
}
#ifdef _WIN32
-static int GetCasePathName(const kwsys_stl::string & pathIn,
- kwsys_stl::string & casePath)
+static int GetCasePathName(const std::string & pathIn,
+ std::string & casePath)
{
- kwsys_stl::vector<kwsys_stl::string> path_components;
- SystemTools::SplitPath(pathIn.c_str(), path_components);
+ std::vector<std::string> path_components;
+ SystemTools::SplitPath(pathIn, path_components);
if(path_components[0].empty()) // First component always exists.
{
// Relative paths cannot be converted.
@@ -3262,8 +3765,13 @@ static int GetCasePathName(const kwsys_stl::string & pathIn,
}
// Start with root component.
- kwsys_stl::vector<kwsys_stl::string>::size_type idx = 0;
+ std::vector<std::string>::size_type idx = 0;
casePath = path_components[idx++];
+ // make sure drive letter is always upper case
+ if(casePath.size() > 1 && casePath[1] == ':')
+ {
+ casePath[0] = toupper(casePath[0]);
+ }
const char* sep = "";
// If network path, fill casePath with server/share so FindFirstFile
@@ -3281,14 +3789,25 @@ static int GetCasePathName(const kwsys_stl::string & pathIn,
{
casePath += sep;
sep = "/";
- kwsys_stl::string test_str = casePath;
+ std::string test_str = casePath;
test_str += path_components[idx];
- WIN32_FIND_DATA findData;
- HANDLE hFind = ::FindFirstFile(test_str.c_str(), &findData);
+ // If path component contains wildcards, we skip matching
+ // because these filenames are not allowed on windows,
+ // and we do not want to match a different file.
+ if(path_components[idx].find('*') != std::string::npos ||
+ path_components[idx].find('?') != std::string::npos)
+ {
+ casePath = "";
+ return 0;
+ }
+
+ WIN32_FIND_DATAW findData;
+ HANDLE hFind = ::FindFirstFileW(Encoding::ToWide(test_str).c_str(),
+ &findData);
if (INVALID_HANDLE_VALUE != hFind)
{
- casePath += findData.cFileName;
+ casePath += Encoding::ToNarrow(findData.cFileName);
::FindClose(hFind);
}
else
@@ -3303,42 +3822,36 @@ static int GetCasePathName(const kwsys_stl::string & pathIn,
//----------------------------------------------------------------------------
-kwsys_stl::string SystemTools::GetActualCaseForPath(const char* p)
+std::string SystemTools::GetActualCaseForPath(const std::string& p)
{
#ifndef _WIN32
return p;
#else
- kwsys_stl::string casePath = p;
- // make sure drive letter is always upper case
- if(casePath.size() > 1 && casePath[1] == ':')
- {
- casePath[0] = toupper(casePath[0]);
- }
-
// Check to see if actual case has already been called
- // for this path, and the result is stored in the LongPathMap
- SystemToolsTranslationMap::iterator i =
- SystemTools::LongPathMap->find(casePath);
- if(i != SystemTools::LongPathMap->end())
+ // for this path, and the result is stored in the PathCaseMap
+ SystemToolsPathCaseMap::iterator i =
+ SystemTools::PathCaseMap->find(p);
+ if(i != SystemTools::PathCaseMap->end())
{
return i->second;
}
+ std::string casePath;
int len = GetCasePathName(p, casePath);
if(len == 0 || len > MAX_PATH+1)
{
return p;
}
- (*SystemTools::LongPathMap)[p] = casePath;
+ (*SystemTools::PathCaseMap)[p] = casePath;
return casePath;
#endif
}
//----------------------------------------------------------------------------
-const char* SystemTools::SplitPathRootComponent(const char* p,
- kwsys_stl::string* root)
+const char* SystemTools::SplitPathRootComponent(const std::string& p,
+ std::string* root)
{
// Identify the root component.
- const char* c = p;
+ const char* c = p.c_str();
if((c[0] == '/' && c[1] == '/') || (c[0] == '\\' && c[1] == '\\'))
{
// Network path.
@@ -3420,22 +3933,22 @@ const char* SystemTools::SplitPathRootComponent(const char* p,
}
//----------------------------------------------------------------------------
-void SystemTools::SplitPath(const char* p,
- kwsys_stl::vector<kwsys_stl::string>& components,
+void SystemTools::SplitPath(const std::string& p,
+ std::vector<std::string>& components,
bool expand_home_dir)
{
- const char* c = p;
+ const char* c;
components.clear();
// Identify the root component.
{
- kwsys_stl::string root;
- c = SystemTools::SplitPathRootComponent(c, &root);
+ std::string root;
+ c = SystemTools::SplitPathRootComponent(p, &root);
// Expand home directory references if requested.
if(expand_home_dir && !root.empty() && root[0] == '~')
{
- kwsys_stl::string homedir;
+ std::string homedir;
root = root.substr(0, root.size()-1);
if(root.size() == 1)
{
@@ -3460,12 +3973,12 @@ void SystemTools::SplitPath(const char* p,
}
}
#endif
- if(!homedir.empty() && (homedir[homedir.size()-1] == '/' ||
- homedir[homedir.size()-1] == '\\'))
+ if(!homedir.empty() && (*homedir.rbegin() == '/' ||
+ *homedir.rbegin() == '\\'))
{
- homedir = homedir.substr(0, homedir.size()-1);
+ homedir.resize(homedir.size() - 1);
}
- SystemTools::SplitPath(homedir.c_str(), components);
+ SystemTools::SplitPath(homedir, components);
}
else
{
@@ -3481,9 +3994,7 @@ void SystemTools::SplitPath(const char* p,
if(*last == '/' || *last == '\\')
{
// End of a component. Save it.
- components.push_back(
- kwsys_stl::string(first,static_cast<kwsys_stl::string::size_type>(
- last-first)));
+ components.push_back(std::string(first, last));
first = last+1;
}
}
@@ -3491,27 +4002,32 @@ void SystemTools::SplitPath(const char* p,
// Save the last component unless there were no components.
if(last != c)
{
- components.push_back(
- kwsys_stl::string(first,static_cast<kwsys_stl::string::size_type>(
- last-first)));
+ components.push_back(std::string(first, last));
}
}
//----------------------------------------------------------------------------
-kwsys_stl::string
-SystemTools::JoinPath(const kwsys_stl::vector<kwsys_stl::string>& components)
+std::string
+SystemTools::JoinPath(const std::vector<std::string>& components)
{
return SystemTools::JoinPath(components.begin(), components.end());
}
//----------------------------------------------------------------------------
-kwsys_stl::string
+std::string
SystemTools
-::JoinPath(kwsys_stl::vector<kwsys_stl::string>::const_iterator first,
- kwsys_stl::vector<kwsys_stl::string>::const_iterator last)
+::JoinPath(std::vector<std::string>::const_iterator first,
+ std::vector<std::string>::const_iterator last)
{
// Construct result in a single string.
- kwsys_stl::string result;
+ std::string result;
+ size_t len = 0;
+ std::vector<std::string>::const_iterator i;
+ for(i = first; i != last; ++i)
+ {
+ len += 1 + i->size();
+ }
+ result.reserve(len);
// The first two components do not add a slash.
if(first != last)
@@ -3535,30 +4051,30 @@ SystemTools
}
//----------------------------------------------------------------------------
-bool SystemTools::ComparePath(const char* c1, const char* c2)
+bool SystemTools::ComparePath(const std::string& c1, const std::string& c2)
{
#if defined(_WIN32) || defined(__APPLE__)
# ifdef _MSC_VER
- return _stricmp(c1, c2) == 0;
+ return _stricmp(c1.c_str(), c2.c_str()) == 0;
# elif defined(__APPLE__) || defined(__GNUC__)
- return strcasecmp(c1, c2) == 0;
+ return strcasecmp(c1.c_str(), c2.c_str()) == 0;
#else
- return SystemTools::Strucmp(c1, c2) == 0;
+ return SystemTools::Strucmp(c1.c_str(), c2.c_str()) == 0;
# endif
#else
- return strcmp(c1, c2) == 0;
+ return c1 == c2;
#endif
}
//----------------------------------------------------------------------------
-bool SystemTools::Split(const char* str, kwsys_stl::vector<kwsys_stl::string>& lines, char separator)
+bool SystemTools::Split(const std::string& str, std::vector<std::string>& lines, char separator)
{
- kwsys_stl::string data(str);
- kwsys_stl::string::size_type lpos = 0;
+ std::string data(str);
+ std::string::size_type lpos = 0;
while(lpos < data.length())
{
- kwsys_stl::string::size_type rpos = data.find_first_of(separator, lpos);
- if(rpos == kwsys_stl::string::npos)
+ std::string::size_type rpos = data.find_first_of(separator, lpos);
+ if(rpos == std::string::npos)
{
// Line ends at end of string without a newline.
lines.push_back(data.substr(lpos));
@@ -3575,14 +4091,14 @@ bool SystemTools::Split(const char* str, kwsys_stl::vector<kwsys_stl::string>& l
}
//----------------------------------------------------------------------------
-bool SystemTools::Split(const char* str, kwsys_stl::vector<kwsys_stl::string>& lines)
+bool SystemTools::Split(const std::string& str, std::vector<std::string>& lines)
{
- kwsys_stl::string data(str);
- kwsys_stl::string::size_type lpos = 0;
+ std::string data(str);
+ std::string::size_type lpos = 0;
while(lpos < data.length())
{
- kwsys_stl::string::size_type rpos = data.find_first_of("\n", lpos);
- if(rpos == kwsys_stl::string::npos)
+ std::string::size_type rpos = data.find_first_of("\n", lpos);
+ if(rpos == std::string::npos)
{
// Line ends at end of string without a newline.
lines.push_back(data.substr(lpos));
@@ -3607,20 +4123,20 @@ bool SystemTools::Split(const char* str, kwsys_stl::vector<kwsys_stl::string>& l
* Return path of a full filename (no trailing slashes).
* Warning: returned path is converted to Unix slashes format.
*/
-kwsys_stl::string SystemTools::GetFilenamePath(const kwsys_stl::string& filename)
+std::string SystemTools::GetFilenamePath(const std::string& filename)
{
- kwsys_stl::string fn = filename;
+ std::string fn = filename;
SystemTools::ConvertToUnixSlashes(fn);
- kwsys_stl::string::size_type slash_pos = fn.rfind("/");
- if(slash_pos != kwsys_stl::string::npos)
+ std::string::size_type slash_pos = fn.rfind("/");
+ if(slash_pos != std::string::npos)
{
- kwsys_stl::string ret = fn.substr(0, slash_pos);
+ std::string ret = fn.substr(0, slash_pos);
if(ret.size() == 2 && ret[1] == ':')
{
return ret + '/';
}
- if(ret.size() == 0)
+ if(ret.empty())
{
return "/";
}
@@ -3636,14 +4152,14 @@ kwsys_stl::string SystemTools::GetFilenamePath(const kwsys_stl::string& filename
/**
* Return file name of a full filename (i.e. file name without path).
*/
-kwsys_stl::string SystemTools::GetFilenameName(const kwsys_stl::string& filename)
+std::string SystemTools::GetFilenameName(const std::string& filename)
{
#if defined(_WIN32)
- kwsys_stl::string::size_type slash_pos = filename.find_last_of("/\\");
+ std::string::size_type slash_pos = filename.find_last_of("/\\");
#else
- kwsys_stl::string::size_type slash_pos = filename.find_last_of("/");
+ std::string::size_type slash_pos = filename.rfind('/');
#endif
- if(slash_pos != kwsys_stl::string::npos)
+ if(slash_pos != std::string::npos)
{
return filename.substr(slash_pos + 1);
}
@@ -3658,11 +4174,11 @@ kwsys_stl::string SystemTools::GetFilenameName(const kwsys_stl::string& filename
* Return file extension of a full filename (dot included).
* Warning: this is the longest extension (for example: .tar.gz)
*/
-kwsys_stl::string SystemTools::GetFilenameExtension(const kwsys_stl::string& filename)
+std::string SystemTools::GetFilenameExtension(const std::string& filename)
{
- kwsys_stl::string name = SystemTools::GetFilenameName(filename);
- kwsys_stl::string::size_type dot_pos = name.find(".");
- if(dot_pos != kwsys_stl::string::npos)
+ std::string name = SystemTools::GetFilenameName(filename);
+ std::string::size_type dot_pos = name.find('.');
+ if(dot_pos != std::string::npos)
{
return name.substr(dot_pos);
}
@@ -3676,11 +4192,11 @@ kwsys_stl::string SystemTools::GetFilenameExtension(const kwsys_stl::string& fil
* Return file extension of a full filename (dot included).
* Warning: this is the shortest extension (for example: .gz of .tar.gz)
*/
-kwsys_stl::string SystemTools::GetFilenameLastExtension(const kwsys_stl::string& filename)
+std::string SystemTools::GetFilenameLastExtension(const std::string& filename)
{
- kwsys_stl::string name = SystemTools::GetFilenameName(filename);
- kwsys_stl::string::size_type dot_pos = name.rfind(".");
- if(dot_pos != kwsys_stl::string::npos)
+ std::string name = SystemTools::GetFilenameName(filename);
+ std::string::size_type dot_pos = name.rfind('.');
+ if(dot_pos != std::string::npos)
{
return name.substr(dot_pos);
}
@@ -3694,11 +4210,11 @@ kwsys_stl::string SystemTools::GetFilenameLastExtension(const kwsys_stl::string&
* Return file name without extension of a full filename (i.e. without path).
* Warning: it considers the longest extension (for example: .tar.gz)
*/
-kwsys_stl::string SystemTools::GetFilenameWithoutExtension(const kwsys_stl::string& filename)
+std::string SystemTools::GetFilenameWithoutExtension(const std::string& filename)
{
- kwsys_stl::string name = SystemTools::GetFilenameName(filename);
- kwsys_stl::string::size_type dot_pos = name.find(".");
- if(dot_pos != kwsys_stl::string::npos)
+ std::string name = SystemTools::GetFilenameName(filename);
+ std::string::size_type dot_pos = name.find('.');
+ if(dot_pos != std::string::npos)
{
return name.substr(0, dot_pos);
}
@@ -3714,12 +4230,12 @@ kwsys_stl::string SystemTools::GetFilenameWithoutExtension(const kwsys_stl::stri
* Warning: it considers the last extension (for example: removes .gz
* from .tar.gz)
*/
-kwsys_stl::string
-SystemTools::GetFilenameWithoutLastExtension(const kwsys_stl::string& filename)
+std::string
+SystemTools::GetFilenameWithoutLastExtension(const std::string& filename)
{
- kwsys_stl::string name = SystemTools::GetFilenameName(filename);
- kwsys_stl::string::size_type dot_pos = name.rfind(".");
- if(dot_pos != kwsys_stl::string::npos)
+ std::string name = SystemTools::GetFilenameName(filename);
+ std::string::size_type dot_pos = name.rfind('.');
+ if(dot_pos != std::string::npos)
{
return name.substr(0, dot_pos);
}
@@ -3738,8 +4254,7 @@ bool SystemTools::FileHasSignature(const char *filename,
return false;
}
- FILE *fp;
- fp = fopen(filename, "rb");
+ FILE *fp = Fopen(filename, "rb");
if (!fp)
{
return false;
@@ -3772,8 +4287,12 @@ SystemTools::DetectFileType(const char *filename,
return SystemTools::FileTypeUnknown;
}
- FILE *fp;
- fp = fopen(filename, "rb");
+ if (SystemTools::FileIsDirectory(filename))
+ {
+ return SystemTools::FileTypeUnknown;
+ }
+
+ FILE *fp = Fopen(filename, "rb");
if (!fp)
{
return SystemTools::FileTypeUnknown;
@@ -3786,6 +4305,7 @@ SystemTools::DetectFileType(const char *filename,
fclose(fp);
if (read_length == 0)
{
+ delete [] buffer;
return SystemTools::FileTypeUnknown;
}
@@ -3824,7 +4344,7 @@ SystemTools::DetectFileType(const char *filename,
bool SystemTools::LocateFileInDir(const char *filename,
const char *dir,
- kwsys_stl::string& filename_found,
+ std::string& filename_found,
int try_filename_dirs)
{
if (!filename || !dir)
@@ -3834,12 +4354,12 @@ bool SystemTools::LocateFileInDir(const char *filename,
// Get the basename of 'filename'
- kwsys_stl::string filename_base = SystemTools::GetFilenameName(filename);
+ std::string filename_base = SystemTools::GetFilenameName(filename);
// Check if 'dir' is really a directory
// If win32 and matches something like C:, accept it as a dir
- kwsys_stl::string real_dir;
+ std::string real_dir;
if (!SystemTools::FileIsDirectory(dir))
{
#if defined( _WIN32 )
@@ -3857,20 +4377,20 @@ bool SystemTools::LocateFileInDir(const char *filename,
// Try to find the file in 'dir'
bool res = false;
- if (filename_base.size() && dir)
+ if (!filename_base.empty() && dir)
{
size_t dir_len = strlen(dir);
int need_slash =
(dir_len && dir[dir_len - 1] != '/' && dir[dir_len - 1] != '\\');
- kwsys_stl::string temp = dir;
+ std::string temp = dir;
if (need_slash)
{
temp += "/";
}
temp += filename_base;
- if (SystemTools::FileExists(temp.c_str()))
+ if (SystemTools::FileExists(temp))
{
res = true;
filename_found = temp;
@@ -3883,18 +4403,18 @@ bool SystemTools::LocateFileInDir(const char *filename,
else if (try_filename_dirs)
{
- kwsys_stl::string filename_dir(filename);
- kwsys_stl::string filename_dir_base;
- kwsys_stl::string filename_dir_bases;
+ std::string filename_dir(filename);
+ std::string filename_dir_base;
+ std::string filename_dir_bases;
do
{
filename_dir = SystemTools::GetFilenamePath(filename_dir);
filename_dir_base = SystemTools::GetFilenameName(filename_dir);
#if defined( _WIN32 )
- if (!filename_dir_base.size() ||
- filename_dir_base[filename_dir_base.size() - 1] == ':')
+ if (filename_dir_base.empty() ||
+ *filename_dir_base.rbegin() == ':')
#else
- if (!filename_dir_base.size())
+ if (filename_dir_base.empty())
#endif
{
break;
@@ -3912,39 +4432,48 @@ bool SystemTools::LocateFileInDir(const char *filename,
res = SystemTools::LocateFileInDir(
filename_base.c_str(), temp.c_str(), filename_found, 0);
- } while (!res && filename_dir_base.size());
+ } while (!res && !filename_dir_base.empty());
}
}
return res;
}
+bool SystemTools::FileIsFullPath(const std::string& in_name)
+{
+ return SystemTools::FileIsFullPath(in_name.c_str(), in_name.size());
+}
+
bool SystemTools::FileIsFullPath(const char* in_name)
{
- kwsys_stl::string name = in_name;
+ return SystemTools::FileIsFullPath(in_name, in_name[0] ? (in_name[1] ? 2 : 1) : 0);
+}
+
+bool SystemTools::FileIsFullPath(const char* in_name, size_t len)
+{
#if defined(_WIN32) || defined(__CYGWIN__)
// On Windows, the name must be at least two characters long.
- if(name.length() < 2)
+ if(len < 2)
{
return false;
}
- if(name[1] == ':')
+ if(in_name[1] == ':')
{
return true;
}
- if(name[0] == '\\')
+ if(in_name[0] == '\\')
{
return true;
}
#else
// On UNIX, the name must be at least one character long.
- if(name.length() < 1)
+ if(len < 1)
{
return false;
}
#endif
#if !defined(_WIN32)
- if(name[0] == '~')
+ if(in_name[0] == '~')
{
return true;
}
@@ -3952,46 +4481,37 @@ bool SystemTools::FileIsFullPath(const char* in_name)
// On UNIX, the name must begin in a '/'.
// On Windows, if the name begins in a '/', then it is a full
// network path.
- if(name[0] == '/')
+ if(in_name[0] == '/')
{
return true;
}
return false;
}
-bool SystemTools::GetShortPath(const char* path, kwsys_stl::string& shortPath)
+bool SystemTools::GetShortPath(const std::string& path, std::string& shortPath)
{
-#if defined(WIN32) && !defined(__CYGWIN__)
- const int size = int(strlen(path)) +1; // size of return
- char *buffer = new char[size]; // create a buffer
- char *tempPath = new char[size]; // create a buffer
- int ret;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ std::string tempPath = path; // create a buffer
// if the path passed in has quotes around it, first remove the quotes
- if (path[0] == '"' && path[strlen(path)-1] == '"')
+ if (!path.empty() && path[0] == '"' && *path.rbegin() == '"')
{
- strcpy(tempPath,path+1);
- tempPath[strlen(tempPath)-1] = '\0';
- }
- else
- {
- strcpy(tempPath,path);
+ tempPath = path.substr(1, path.length()-2);
}
- buffer[0] = 0;
- ret = GetShortPathName(tempPath, buffer, size);
+ std::wstring wtempPath = Encoding::ToWide(tempPath);
+ DWORD ret = GetShortPathNameW(wtempPath.c_str(), NULL, 0);
+ std::vector<wchar_t> buffer(ret);
+ ret = GetShortPathNameW(wtempPath.c_str(),
+ &buffer[0], static_cast<DWORD>(buffer.size()));
- if(buffer[0] == 0 || ret > size)
+ if (ret == 0)
{
- delete [] buffer;
- delete [] tempPath;
return false;
}
else
{
- shortPath = buffer;
- delete [] buffer;
- delete [] tempPath;
+ shortPath = Encoding::ToNarrow(&buffer[0]);
return true;
}
#else
@@ -4000,8 +4520,8 @@ bool SystemTools::GetShortPath(const char* path, kwsys_stl::string& shortPath)
#endif
}
-void SystemTools::SplitProgramFromArgs(const char* path,
- kwsys_stl::string& program, kwsys_stl::string& args)
+void SystemTools::SplitProgramFromArgs(const std::string& path,
+ std::string& program, std::string& args)
{
// see if this is a full path to a program
// if so then set program to path and args to nothing
@@ -4013,9 +4533,9 @@ void SystemTools::SplitProgramFromArgs(const char* path,
}
// Try to find the program in the path, note the program
// may have spaces in its name so we have to look for it
- kwsys_stl::vector<kwsys_stl::string> e;
- kwsys_stl::string findProg = SystemTools::FindProgram(path, e);
- if(findProg.size())
+ std::vector<std::string> e;
+ std::string findProg = SystemTools::FindProgram(path, e);
+ if(!findProg.empty())
{
program = findProg;
args = "";
@@ -4024,17 +4544,17 @@ void SystemTools::SplitProgramFromArgs(const char* path,
// Now try and peel off space separated chunks from the end of the string
// so the largest path possible is found allowing for spaces in the path
- kwsys_stl::string dir = path;
- kwsys_stl::string::size_type spacePos = dir.rfind(' ');
- while(spacePos != kwsys_stl::string::npos)
+ std::string dir = path;
+ std::string::size_type spacePos = dir.rfind(' ');
+ while(spacePos != std::string::npos)
{
- kwsys_stl::string tryProg = dir.substr(0, spacePos);
+ std::string tryProg = dir.substr(0, spacePos);
// See if the file exists
- if(SystemTools::FileExists(tryProg.c_str()))
+ if(SystemTools::FileExists(tryProg))
{
program = tryProg;
// remove trailing spaces from program
- kwsys_stl::string::size_type pos = program.size()-1;
+ std::string::size_type pos = program.size()-1;
while(program[pos] == ' ')
{
program.erase(pos);
@@ -4044,12 +4564,12 @@ void SystemTools::SplitProgramFromArgs(const char* path,
return;
}
// Now try and find the program in the path
- findProg = SystemTools::FindProgram(tryProg.c_str(), e);
- if(findProg.size())
+ findProg = SystemTools::FindProgram(tryProg, e);
+ if(!findProg.empty())
{
program = findProg;
// remove trailing spaces from program
- kwsys_stl::string::size_type pos = program.size()-1;
+ std::string::size_type pos = program.size()-1;
while(program[pos] == ' ')
{
program.erase(pos);
@@ -4067,29 +4587,29 @@ void SystemTools::SplitProgramFromArgs(const char* path,
args = "";
}
-kwsys_stl::string SystemTools::GetCurrentDateTime(const char* format)
+std::string SystemTools::GetCurrentDateTime(const char* format)
{
char buf[1024];
time_t t;
time(&t);
strftime(buf, sizeof(buf), format, localtime(&t));
- return kwsys_stl::string(buf);
+ return std::string(buf);
}
-kwsys_stl::string SystemTools::MakeCidentifier(const char* s)
+std::string SystemTools::MakeCidentifier(const std::string& s)
{
- kwsys_stl::string str(s);
+ std::string str(s);
if (str.find_first_of("0123456789") == 0)
{
str = "_" + str;
}
- kwsys_stl::string permited_chars("_"
+ std::string permited_chars("_"
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789");
- kwsys_stl::string::size_type pos = 0;
- while ((pos = str.find_first_not_of(permited_chars, pos)) != kwsys_stl::string::npos)
+ std::string::size_type pos = 0;
+ while ((pos = str.find_first_not_of(permited_chars, pos)) != std::string::npos)
{
str[pos] = '_';
}
@@ -4099,8 +4619,8 @@ kwsys_stl::string SystemTools::MakeCidentifier(const char* s)
// Due to a buggy stream library on the HP and another on Mac OS X, we
// need this very carefully written version of getline. Returns true
// if any data were read before the end-of-file was reached.
-bool SystemTools::GetLineFromStream(kwsys_ios::istream& is,
- kwsys_stl::string& line,
+bool SystemTools::GetLineFromStream(std::istream& is,
+ std::string& line,
bool* has_newline /* = 0 */,
long sizeLimit /* = -1 */)
{
@@ -4131,7 +4651,7 @@ bool SystemTools::GetLineFromStream(kwsys_ios::istream& is,
// been reached. Clear the fail bit just before reading.
while(!haveNewline &&
leftToRead != 0 &&
- (is.clear(is.rdstate() & ~kwsys_ios::ios::failbit),
+ (is.clear(is.rdstate() & ~std::ios::failbit),
is.getline(buffer, bufferSize), is.gcount() > 0))
{
// We have read at least one byte.
@@ -4216,27 +4736,90 @@ bool SystemTools::GetPermissions(const char* file, mode_t& mode)
{
return false;
}
+ return SystemTools::GetPermissions(std::string(file), mode);
+}
+bool SystemTools::GetPermissions(const std::string& file, mode_t& mode)
+{
+#if defined(_WIN32)
+ DWORD attr = GetFileAttributesW(
+ SystemTools::ConvertToWindowsExtendedPath(file).c_str());
+ if(attr == INVALID_FILE_ATTRIBUTES)
+ {
+ return false;
+ }
+ if((attr & FILE_ATTRIBUTE_READONLY) != 0)
+ {
+ mode = (_S_IREAD | (_S_IREAD >> 3) | (_S_IREAD >> 6));
+ }
+ else
+ {
+ mode = (_S_IWRITE | (_S_IWRITE >> 3) | (_S_IWRITE >> 6)) |
+ (_S_IREAD | (_S_IREAD >> 3) | (_S_IREAD >> 6));
+ }
+ if((attr & FILE_ATTRIBUTE_DIRECTORY) != 0)
+ {
+ mode |= S_IFDIR | (_S_IEXEC | (_S_IEXEC >> 3) | (_S_IEXEC >> 6));
+ }
+ else
+ {
+ mode |= S_IFREG;
+ }
+ size_t dotPos = file.rfind('.');
+ const char* ext = dotPos == file.npos ? 0 : (file.c_str() + dotPos);
+ if(ext && (Strucmp(ext, ".exe") == 0 ||
+ Strucmp(ext, ".com") == 0 ||
+ Strucmp(ext, ".cmd") == 0 ||
+ Strucmp(ext, ".bat") == 0))
+ {
+ mode |= (_S_IEXEC | (_S_IEXEC >> 3) | (_S_IEXEC >> 6));
+ }
+#else
struct stat st;
- if ( stat(file, &st) < 0 )
+ if ( stat(file.c_str(), &st) < 0 )
{
return false;
}
mode = st.st_mode;
+#endif
return true;
}
-bool SystemTools::SetPermissions(const char* file, mode_t mode)
+bool SystemTools::SetPermissions(const char* file,
+ mode_t mode,
+ bool honor_umask)
{
if ( !file )
{
return false;
}
- if ( !SystemTools::FileExists(file) )
+ return SystemTools::SetPermissions(
+ std::string(file), mode, honor_umask);
+}
+
+bool SystemTools::SetPermissions(const std::string& file,
+ mode_t mode,
+ bool honor_umask)
+{
+ // TEMPORARY / TODO: After FileExists calls lstat() instead of
+ // access(), change this call to FileExists instead of
+ // TestFileAccess so that we don't follow symlinks.
+ if ( !SystemTools::TestFileAccess(file, TEST_FILE_OK) )
{
return false;
}
- if ( chmod(file, mode) < 0 )
+ if (honor_umask)
+ {
+ mode_t currentMask = umask(0);
+ umask(currentMask);
+ mode &= ~currentMask;
+ }
+#ifdef _WIN32
+ if ( _wchmod(SystemTools::ConvertToWindowsExtendedPath(file).c_str(),
+ mode) < 0 )
+#else
+ if ( chmod(file.c_str(), mode) < 0 )
+#endif
{
return false;
}
@@ -4244,25 +4827,25 @@ bool SystemTools::SetPermissions(const char* file, mode_t mode)
return true;
}
-kwsys_stl::string SystemTools::GetParentDirectory(const char* fileOrDir)
+std::string SystemTools::GetParentDirectory(const std::string& fileOrDir)
{
return SystemTools::GetFilenamePath(fileOrDir);
}
-bool SystemTools::IsSubDirectory(const char* cSubdir, const char* cDir)
+bool SystemTools::IsSubDirectory(const std::string& cSubdir, const std::string& cDir)
{
- if(!*cDir)
+ if(cDir.empty())
{
return false;
}
- kwsys_stl::string subdir = cSubdir;
- kwsys_stl::string dir = cDir;
+ std::string subdir = cSubdir;
+ std::string dir = cDir;
SystemTools::ConvertToUnixSlashes(subdir);
SystemTools::ConvertToUnixSlashes(dir);
if(subdir.size() > dir.size() && subdir[dir.size()] == '/')
{
std::string s = subdir.substr(0, dir.size());
- return SystemTools::ComparePath(s.c_str(), dir.c_str());
+ return SystemTools::ComparePath(s, dir);
}
return false;
}
@@ -4291,146 +4874,93 @@ void SystemTools::Delay(unsigned int msec)
#endif
}
-void SystemTools::ConvertWindowsCommandLineToUnixArguments(
- const char *cmd_line, int *argc, char ***argv)
+std::string SystemTools::GetOperatingSystemNameAndVersion()
{
- if (!cmd_line || !argc || !argv)
- {
- return;
- }
+ std::string res;
- // A space delimites an argument except when it is inside a quote
+#ifdef _WIN32
+ char buffer[256];
- (*argc) = 1;
+ OSVERSIONINFOEXA osvi;
+ BOOL bOsVersionInfoEx;
- size_t cmd_line_len = strlen(cmd_line);
+ ZeroMemory(&osvi, sizeof(osvi));
+ osvi.dwOSVersionInfoSize = sizeof(osvi);
- size_t i;
- for (i = 0; i < cmd_line_len; i++)
+#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
+# pragma warning (push)
+# ifdef __INTEL_COMPILER
+# pragma warning (disable:1478)
+# else
+# pragma warning (disable:4996)
+# endif
+#endif
+ bOsVersionInfoEx = GetVersionExA((OSVERSIONINFOA *)&osvi);
+ if (!bOsVersionInfoEx)
{
- while (isspace(cmd_line[i]) && i < cmd_line_len)
- {
- i++;
- }
- if (i < cmd_line_len)
- {
- if (cmd_line[i] == '\"')
+ return 0;
+ }
+#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
+# pragma warning (pop)
+#endif
+
+ switch (osvi.dwPlatformId)
+ {
+ // Test for the Windows NT product family.
+
+ case VER_PLATFORM_WIN32_NT:
+
+ // Test for the specific product family.
+ if (osvi.dwMajorVersion == 10 && osvi.dwMinorVersion == 0)
{
- i++;
- while (cmd_line[i] != '\"' && i < cmd_line_len)
+ if (osvi.wProductType == VER_NT_WORKSTATION)
+ {
+ res += "Microsoft Windows 10";
+ }
+ else
{
- i++;
+ res += "Microsoft Windows Server 2016 family";
}
- (*argc)++;
}
- else
+
+ if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 3)
{
- while (!isspace(cmd_line[i]) && i < cmd_line_len)
+ if (osvi.wProductType == VER_NT_WORKSTATION)
{
- i++;
+ res += "Microsoft Windows 8.1";
+ }
+ else
+ {
+ res += "Microsoft Windows Server 2012 R2 family";
}
- (*argc)++;
}
- }
- }
-
- (*argv) = new char* [(*argc) + 1];
- (*argv)[(*argc)] = NULL;
-
- // Set the first arg to be the exec name
-
- (*argv)[0] = new char [1024];
-#ifdef _WIN32
- ::GetModuleFileName(0, (*argv)[0], 1024);
-#else
- (*argv)[0][0] = '\0';
-#endif
-
- // Allocate the others
-
- int j;
- for (j = 1; j < (*argc); j++)
- {
- (*argv)[j] = new char [cmd_line_len + 10];
- }
-
- // Grab the args
-
- size_t pos;
- int argc_idx = 1;
- for (i = 0; i < cmd_line_len; i++)
- {
- while (isspace(cmd_line[i]) && i < cmd_line_len)
- {
- i++;
- }
- if (i < cmd_line_len)
- {
- if (cmd_line[i] == '\"')
+ if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 2)
{
- i++;
- pos = i;
- while (cmd_line[i] != '\"' && i < cmd_line_len)
+ if (osvi.wProductType == VER_NT_WORKSTATION)
+ {
+ res += "Microsoft Windows 8";
+ }
+ else
{
- i++;
+ res += "Microsoft Windows Server 2012 family";
}
- memcpy((*argv)[argc_idx], &cmd_line[pos], i - pos);
- (*argv)[argc_idx][i - pos] = '\0';
- argc_idx++;
}
- else
+
+ if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 1)
{
- pos = i;
- while (!isspace(cmd_line[i]) && i < cmd_line_len)
+ if (osvi.wProductType == VER_NT_WORKSTATION)
+ {
+ res += "Microsoft Windows 7";
+ }
+ else
{
- i++;
+ res += "Microsoft Windows Server 2008 R2 family";
}
- memcpy((*argv)[argc_idx], &cmd_line[pos], i - pos);
- (*argv)[argc_idx][i - pos] = '\0';
- argc_idx++;
}
- }
- }
- }
-
-kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion()
-{
- kwsys_stl::string res;
-
-#ifdef _WIN32
- char buffer[256];
-
- OSVERSIONINFOEX osvi;
- BOOL bOsVersionInfoEx;
-
- // Try calling GetVersionEx using the OSVERSIONINFOEX structure.
- // If that fails, try using the OSVERSIONINFO structure.
-
- ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
- osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
-
- bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *)&osvi);
- if (!bOsVersionInfoEx)
- {
- osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- if (!GetVersionEx((OSVERSIONINFO *)&osvi))
- {
- return 0;
- }
- }
-
- switch (osvi.dwPlatformId)
- {
- // Test for the Windows NT product family.
-
- case VER_PLATFORM_WIN32_NT:
-
- // Test for the specific product family.
if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0)
{
-#if (_MSC_VER >= 1300)
if (osvi.wProductType == VER_NT_WORKSTATION)
{
res += "Microsoft Windows Vista";
@@ -4439,9 +4969,6 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion()
{
res += "Microsoft Windows Server 2008 family";
}
-#else
- res += "Microsoft Windows Vista or Windows Server 2008";
-#endif
}
if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
@@ -4470,7 +4997,6 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion()
{
// Test for the workstation type.
-#if (_MSC_VER >= 1300)
if (osvi.wProductType == VER_NT_WORKSTATION)
{
if (osvi.dwMajorVersion == 4)
@@ -4542,7 +5068,6 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion()
}
}
}
-#endif // Visual Studio 7 and up
}
// Test for specific product on Windows NT 4.0 SP5 and earlier
@@ -4551,21 +5076,21 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion()
{
HKEY hKey;
#define BUFSIZE 80
- char szProductType[BUFSIZE];
+ wchar_t szProductType[BUFSIZE];
DWORD dwBufLen=BUFSIZE;
LONG lRet;
- lRet = RegOpenKeyEx(
+ lRet = RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
- "SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
+ L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
0, KEY_QUERY_VALUE, &hKey);
if (lRet != ERROR_SUCCESS)
{
return 0;
}
- lRet = RegQueryValueEx(hKey, "ProductType", NULL, NULL,
- (LPBYTE) szProductType, &dwBufLen);
+ lRet = RegQueryValueExW(hKey, L"ProductType", NULL, NULL,
+ (LPBYTE) szProductType, &dwBufLen);
if ((lRet != ERROR_SUCCESS) || (dwBufLen > BUFSIZE))
{
@@ -4574,15 +5099,15 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion()
RegCloseKey(hKey);
- if (lstrcmpi("WINNT", szProductType) == 0)
+ if (lstrcmpiW(L"WINNT", szProductType) == 0)
{
res += " Workstation";
}
- if (lstrcmpi("LANMANNT", szProductType) == 0)
+ if (lstrcmpiW(L"LANMANNT", szProductType) == 0)
{
res += " Server";
}
- if (lstrcmpi("SERVERNT", szProductType) == 0)
+ if (lstrcmpiW(L"SERVERNT", szProductType) == 0)
{
res += " Advanced Server";
}
@@ -4598,16 +5123,16 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion()
// Display service pack (if any) and build number.
if (osvi.dwMajorVersion == 4 &&
- lstrcmpi(osvi.szCSDVersion, "Service Pack 6") == 0)
+ lstrcmpiA(osvi.szCSDVersion, "Service Pack 6") == 0)
{
HKEY hKey;
LONG lRet;
// Test for SP6 versus SP6a.
- lRet = RegOpenKeyEx(
+ lRet = RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
- "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009",
+ L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009",
0, KEY_QUERY_VALUE, &hKey);
if (lRet == ERROR_SUCCESS)
@@ -4680,9 +5205,9 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion()
}
// ----------------------------------------------------------------------
-bool SystemTools::ParseURLProtocol( const kwsys_stl::string& URL,
- kwsys_stl::string& protocol,
- kwsys_stl::string& dataglom )
+bool SystemTools::ParseURLProtocol( const std::string& URL,
+ std::string& protocol,
+ std::string& dataglom )
{
// match 0 entire url
// match 1 protocol
@@ -4698,13 +5223,13 @@ bool SystemTools::ParseURLProtocol( const kwsys_stl::string& URL,
}
// ----------------------------------------------------------------------
-bool SystemTools::ParseURL( const kwsys_stl::string& URL,
- kwsys_stl::string& protocol,
- kwsys_stl::string& username,
- kwsys_stl::string& password,
- kwsys_stl::string& hostname,
- kwsys_stl::string& dataport,
- kwsys_stl::string& database )
+bool SystemTools::ParseURL( const std::string& URL,
+ std::string& protocol,
+ std::string& username,
+ std::string& password,
+ std::string& hostname,
+ std::string& dataport,
+ std::string& database )
{
kwsys::RegularExpression urlRe( VTK_URL_REGEX );
if ( ! urlRe.find( URL ) ) return false;
@@ -4735,7 +5260,9 @@ bool SystemTools::ParseURL( const kwsys_stl::string& URL,
// necessary.
static unsigned int SystemToolsManagerCount;
SystemToolsTranslationMap *SystemTools::TranslationMap;
-SystemToolsTranslationMap *SystemTools::LongPathMap;
+#ifdef _WIN32
+SystemToolsPathCaseMap *SystemTools::PathCaseMap;
+#endif
#ifdef __CYGWIN__
SystemToolsTranslationMap *SystemTools::Cyg2Win32Map;
#endif
@@ -4783,7 +5310,9 @@ void SystemTools::ClassInitialize()
#endif
// Allocate the translation map first.
SystemTools::TranslationMap = new SystemToolsTranslationMap;
- SystemTools::LongPathMap = new SystemToolsTranslationMap;
+#ifdef _WIN32
+ SystemTools::PathCaseMap = new SystemToolsPathCaseMap;
+#endif
#ifdef __CYGWIN__
SystemTools::Cyg2Win32Map = new SystemToolsTranslationMap;
#endif
@@ -4805,13 +5334,13 @@ void SystemTools::ClassInitialize()
// The current working directory may be a logical path. Find
// the shortest logical path that still produces the correct
// physical path.
- kwsys_stl::string cwd_changed;
- kwsys_stl::string pwd_changed;
+ std::string cwd_changed;
+ std::string pwd_changed;
// Test progressively shorter logical-to-physical mappings.
- kwsys_stl::string pwd_str = pwd;
- kwsys_stl::string cwd_str = cwd;
- kwsys_stl::string pwd_path;
+ std::string pwd_str = pwd;
+ std::string cwd_str = cwd;
+ std::string pwd_path;
Realpath(pwd, pwd_path);
while(cwd_str == pwd_path && cwd_str != pwd_str)
{
@@ -4821,16 +5350,16 @@ void SystemTools::ClassInitialize()
// Strip off one directory level and see if the logical
// mapping still works.
- pwd_str = SystemTools::GetFilenamePath(pwd_str.c_str());
- cwd_str = SystemTools::GetFilenamePath(cwd_str.c_str());
+ pwd_str = SystemTools::GetFilenamePath(pwd_str);
+ cwd_str = SystemTools::GetFilenamePath(cwd_str);
Realpath(pwd_str.c_str(), pwd_path);
}
// Add the translation to keep the logical path name.
if(!cwd_changed.empty() && !pwd_changed.empty())
{
- SystemTools::AddTranslationPath(cwd_changed.c_str(),
- pwd_changed.c_str());
+ SystemTools::AddTranslationPath(cwd_changed,
+ pwd_changed);
}
}
}
@@ -4840,7 +5369,9 @@ void SystemTools::ClassInitialize()
void SystemTools::ClassFinalize()
{
delete SystemTools::TranslationMap;
- delete SystemTools::LongPathMap;
+#ifdef _WIN32
+ delete SystemTools::PathCaseMap;
+#endif
#ifdef __CYGWIN__
delete SystemTools::Cyg2Win32Map;
#endif
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in
index d6dae3986..bba5a5cd3 100644
--- a/Source/kwsys/SystemTools.hxx.in
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -12,19 +12,25 @@
#ifndef @KWSYS_NAMESPACE@_SystemTools_hxx
#define @KWSYS_NAMESPACE@_SystemTools_hxx
-#include <@KWSYS_NAMESPACE@/ios/iosfwd>
-#include <@KWSYS_NAMESPACE@/stl/string>
-#include <@KWSYS_NAMESPACE@/stl/vector>
-#include <@KWSYS_NAMESPACE@/stl/map>
+#include <@KWSYS_NAMESPACE@/Configure.hxx>
+
+#include <iosfwd>
+#include <string>
+#include <vector>
+#include <map>
-#include <@KWSYS_NAMESPACE@/Configure.h>
#include <@KWSYS_NAMESPACE@/String.hxx>
#include <sys/types.h>
+#if !defined(_WIN32) || defined(__CYGWIN__)
+# include <unistd.h> // For access permissions for use with access()
+#endif
// Required for va_list
#include <stdarg.h>
-#if @KWSYS_NAMESPACE@_STL_HAVE_STD && !defined(va_list)
+// Required for FILE*
+#include <stdio.h>
+#if !defined(va_list)
// Some compilers move va_list into the std namespace and there is no way to
// tell that this has been done. Playing with things being included before or
// after stdarg.h does not solve things because we do not have control over
@@ -42,20 +48,12 @@ namespace @KWSYS_NAMESPACE@
}
#endif // va_list
-#if defined( _MSC_VER )
-typedef unsigned short mode_t;
-#endif
-
-/* Define these macros temporarily to keep the code readable. */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
-# define kwsys_stl @KWSYS_NAMESPACE@_stl
-# define kwsys_ios @KWSYS_NAMESPACE@_ios
-#endif
-
namespace @KWSYS_NAMESPACE@
{
class SystemToolsTranslationMap;
+class SystemToolsPathCaseMap;
+
/** \class SystemToolsManager
* \brief Use to make sure SystemTools is initialized before it is used
* and is the last static object destroyed
@@ -68,10 +66,28 @@ public:
};
// This instance will show up in any translation unit that uses
-// SystemTools. It will make sure SystemTools is initialized
+// SystemTools. It will make sure SystemTools is initialized
// before it is used and is the last static object destroyed.
static SystemToolsManager SystemToolsManagerInstance;
+// Flags for use with TestFileAccess. Use a typedef in case any operating
+// system in the future needs a special type. These are flags that may be
+// combined using the | operator.
+typedef int TestFilePermissions;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ // On Windows (VC and Borland), no system header defines these constants...
+ static const TestFilePermissions TEST_FILE_OK = 0;
+ static const TestFilePermissions TEST_FILE_READ = 4;
+ static const TestFilePermissions TEST_FILE_WRITE = 2;
+ static const TestFilePermissions TEST_FILE_EXECUTE = 1;
+#else
+ // Standard POSIX constants
+ static const TestFilePermissions TEST_FILE_OK = F_OK;
+ static const TestFilePermissions TEST_FILE_READ = R_OK;
+ static const TestFilePermissions TEST_FILE_WRITE = W_OK;
+ static const TestFilePermissions TEST_FILE_EXECUTE = X_OK;
+#endif
+
/** \class SystemTools
* \brief A collection of useful platform-independent system functions.
*/
@@ -91,9 +107,9 @@ public:
* then an underscore is prepended. Note that this can produce
* identifiers that the standard reserves (_[A-Z].* and __.*).
*/
- static kwsys_stl::string MakeCidentifier(const char* s);
+ static std::string MakeCidentifier(const std::string& s);
- static kwsys_stl::string MakeCindentifier(const char* s)
+ static std::string MakeCindentifier(const std::string& s)
{
return MakeCidentifier(s);
}
@@ -101,43 +117,46 @@ public:
/**
* Replace replace all occurences of the string in the source string.
*/
- static void ReplaceString(kwsys_stl::string& source,
+ static void ReplaceString(std::string& source,
const char* replace,
const char* with);
+ static void ReplaceString(std::string& source,
+ const std::string& replace,
+ const std::string& with);
/**
* Return a capitalized string (i.e the first letter is uppercased,
* all other are lowercased).
*/
- static kwsys_stl::string Capitalized(const kwsys_stl::string&);
-
+ static std::string Capitalized(const std::string&);
+
/**
* Return a 'capitalized words' string (i.e the first letter of each word
* is uppercased all other are left untouched though).
*/
- static kwsys_stl::string CapitalizedWords(const kwsys_stl::string&);
-
+ static std::string CapitalizedWords(const std::string&);
+
/**
* Return a 'uncapitalized words' string (i.e the first letter of each word
* is lowercased all other are left untouched though).
*/
- static kwsys_stl::string UnCapitalizedWords(const kwsys_stl::string&);
-
+ static std::string UnCapitalizedWords(const std::string&);
+
/**
* Return a lower case string
*/
- static kwsys_stl::string LowerCase(const kwsys_stl::string&);
-
+ static std::string LowerCase(const std::string&);
+
/**
* Return a lower case string
*/
- static kwsys_stl::string UpperCase(const kwsys_stl::string&);
-
+ static std::string UpperCase(const std::string&);
+
/**
* Count char in string
*/
static size_t CountChar(const char* str, char c);
-
+
/**
* Remove some characters from a string.
* Return a pointer to the new resulting string (allocated with 'new')
@@ -149,50 +168,52 @@ public:
* Return a pointer to the new resulting string (allocated with 'new')
*/
static char* RemoveCharsButUpperHex(const char* str);
-
+
/**
* Replace some characters by another character in a string (in-place)
* Return a pointer to string
*/
static char* ReplaceChars(char* str, const char *toreplace,char replacement);
-
+
/**
* Returns true if str1 starts (respectively ends) with str2
*/
static bool StringStartsWith(const char* str1, const char* str2);
+ static bool StringStartsWith(const std::string& str1, const char* str2);
static bool StringEndsWith(const char* str1, const char* str2);
+ static bool StringEndsWith(const std::string& str1, const char* str2);
/**
* Returns a pointer to the last occurence of str2 in str1
*/
static const char* FindLastString(const char* str1, const char* str2);
-
+
/**
* Make a duplicate of the string similar to the strdup C function
* but use new to create the 'new' string, so one can use
* 'delete' to remove it. Returns 0 if the input is empty.
*/
static char* DuplicateString(const char* str);
-
+
/**
* Return the string cropped to a given length by removing chars in the
* center of the string and replacing them with an ellipsis (...)
*/
- static kwsys_stl::string CropString(const kwsys_stl::string&,size_t max_len);
-
+ static std::string CropString(const std::string&,size_t max_len);
+
/** split a path by separator into an array of strings, default is /.
If isPath is true then the string is treated like a path and if
s starts with a / then the first element of the returned array will
be /, so /foo/bar will be [/, foo, bar]
- */
- static kwsys_stl::vector<String> SplitString(const char* s, char separator = '/',
+ */
+ static std::vector<String> SplitString(const std::string& s, char separator = '/',
bool isPath = false);
/**
* Perform a case-independent string comparison
*/
static int Strucmp(const char *s1, const char *s2);
- /**
+ /**
* Convert a string in __DATE__ or __TIMESTAMP__ format into a time_t.
* Return false on error, true on success
*/
@@ -203,16 +224,16 @@ public:
* Split a string on its newlines into multiple lines
* Return false only if the last line stored had no newline
*/
- static bool Split(const char* s, kwsys_stl::vector<kwsys_stl::string>& l);
- static bool Split(const char* s, kwsys_stl::vector<kwsys_stl::string>& l, char separator);
-
- /**
+ static bool Split(const std::string& s, std::vector<std::string>& l);
+ static bool Split(const std::string& s, std::vector<std::string>& l, char separator);
+
+ /**
* Return string with space added between capitalized words
* (i.e. EatMyShorts becomes Eat My Shorts )
- * (note that IEatShorts becomes IEat Shorts)
+ * (note that IEatShorts becomes IEat Shorts)
*/
- static kwsys_stl::string AddSpaceBetweenCapitalizedWords(
- const kwsys_stl::string&);
+ static std::string AddSpaceBetweenCapitalizedWords(
+ const std::string&);
/**
* Append two or more strings and produce new one.
@@ -239,7 +260,7 @@ public:
/**
* Escape specific characters in 'str'.
*/
- static kwsys_stl::string EscapeChars(
+ static std::string EscapeChars(
const char *str, const char *chars_to_escape, char escape_char = '\\');
/** -----------------------------------------------------------------
@@ -250,19 +271,30 @@ public:
/**
* Replace Windows file system slashes with Unix-style slashes.
*/
- static void ConvertToUnixSlashes(kwsys_stl::string& path);
-
+ static void ConvertToUnixSlashes(std::string& path);
+
+#ifdef _WIN32
+ /**
+ * Convert the path to an extended length path to avoid MAX_PATH length
+ * limitations on Windows. If the input is a local path the result will be
+ * prefixed with \\?\; if the input is instead a network path, the result
+ * will be prefixed with \\?\UNC\. All output will also be converted to
+ * absolute paths with Windows-style backslashes.
+ **/
+ static std::wstring ConvertToWindowsExtendedPath(const std::string&);
+#endif
+
/**
* For windows this calls ConvertToWindowsOutputPath and for unix
* it calls ConvertToUnixOutputPath
*/
- static kwsys_stl::string ConvertToOutputPath(const char*);
+ static std::string ConvertToOutputPath(const std::string&);
/**
* Convert the path to a string that can be used in a unix makefile.
* double slashes are removed, and spaces are escaped.
*/
- static kwsys_stl::string ConvertToUnixOutputPath(const char*);
+ static std::string ConvertToUnixOutputPath(const std::string&);
/**
* Convert the path to string that can be used in a windows project or
@@ -270,16 +302,35 @@ public:
* the string, the slashes are converted to windows style backslashes, and
* if there are spaces in the string it is double quoted.
*/
- static kwsys_stl::string ConvertToWindowsOutputPath(const char*);
+ static std::string ConvertToWindowsOutputPath(const std::string&);
/**
* Return true if a file exists in the current directory.
- * If isFile = true, then make sure the file is a file and
+ * If isFile = true, then make sure the file is a file and
* not a directory. If isFile = false, then return true
- * if it is a file or a directory.
+ * if it is a file or a directory. Note that the file will
+ * also be checked for read access. (Currently, this check
+ * for read access is only done on POSIX systems.)
*/
static bool FileExists(const char* filename, bool isFile);
+ static bool FileExists(const std::string& filename, bool isFile);
static bool FileExists(const char* filename);
+ static bool FileExists(const std::string& filename);
+
+ /**
+ * Test if a file exists and can be accessed with the requested
+ * permissions. Symbolic links are followed. Returns true if
+ * the access test was successful.
+ *
+ * On POSIX systems (including Cygwin), this maps to the access
+ * function. On Windows systems, all existing files are
+ * considered readable, and writable files are considered to
+ * have the read-only file attribute cleared.
+ */
+ static bool TestFileAccess(const char* filename,
+ TestFilePermissions permissions);
+ static bool TestFileAccess(const std::string& filename,
+ TestFilePermissions permissions);
/**
* Converts Cygwin path to Win32 path. Uses dictionary container for
@@ -293,20 +344,21 @@ public:
/**
* Return file length
*/
- static unsigned long FileLength(const char *filename);
+ static unsigned long FileLength(const std::string& filename);
/**
Change the modification time or create a file
*/
- static bool Touch(const char* filename, bool create);
-
+ static bool Touch(const std::string& filename, bool create);
+
/**
* Compare file modification times.
* Return true for successful comparison and false for error.
* When true is returned, result has -1, 0, +1 for
* f1 older, same, or newer than f2.
*/
- static bool FileTimeCompare(const char* f1, const char* f2,
+ static bool FileTimeCompare(const std::string& f1,
+ const std::string& f2,
int* result);
/**
@@ -321,17 +373,17 @@ public:
* does not exist path is returned unchanged. This does nothing
* on unix but return path.
*/
- static kwsys_stl::string GetActualCaseForPath(const char* path);
+ static std::string GetActualCaseForPath(const std::string& path);
/**
* Given the path to a program executable, get the directory part of
* the path with the file stripped off. If there is no directory
* part, the empty string is returned.
*/
- static kwsys_stl::string GetProgramPath(const char*);
- static bool SplitProgramPath(const char* in_name,
- kwsys_stl::string& dir,
- kwsys_stl::string& file,
+ static std::string GetProgramPath(const std::string&);
+ static bool SplitProgramPath(const std::string& in_name,
+ std::string& dir,
+ std::string& file,
bool errorReport = true);
/**
@@ -341,14 +393,14 @@ public:
* to the running executable. If argv0 is not a full path,
* then this will try to find the full path. If the path is not
* found false is returned, if found true is returned. An error
- * message of the attempted paths is stored in errorMsg.
+ * message of the attempted paths is stored in errorMsg.
* exeName is the name of the executable.
* buildDir is a possibly null path to the build directory.
* installPrefix is a possibly null pointer to the install directory.
*/
static bool FindProgramPath(const char* argv0,
- kwsys_stl::string& pathOut,
- kwsys_stl::string& errorMsg,
+ std::string& pathOut,
+ std::string& errorMsg,
const char* exeName = 0,
const char* buildDir = 0,
const char* installPrefix = 0);
@@ -359,16 +411,21 @@ public:
* (which defaults to the current working directory). The full path
* is returned.
*/
- static kwsys_stl::string CollapseFullPath(const char* in_relative);
- static kwsys_stl::string CollapseFullPath(const char* in_relative,
+ static std::string CollapseFullPath(const std::string& in_relative);
+ static std::string CollapseFullPath(const std::string& in_relative,
const char* in_base);
+ static std::string CollapseFullPath(const std::string& in_relative,
+ const std::string& in_base);
- /**
+ /**
* Get the real path for a given path, removing all symlinks. In
* the event of an error (non-existent path, permissions issue,
- * etc.) the original path is returned.
+ * etc.) the original path is returned if errorMessage pointer is
+ * NULL. Otherwise empty string is returned and errorMessage
+ * contains error description.
*/
- static kwsys_stl::string GetRealPath(const char* path);
+ static std::string GetRealPath(const std::string& path,
+ std::string* errorMessage = 0);
/**
* Split a path name into its root component and the rest of the
@@ -385,8 +442,8 @@ public:
* returned. The root component is stored in the "root" string if
* given.
*/
- static const char* SplitPathRootComponent(const char* p,
- kwsys_stl::string* root=0);
+ static const char* SplitPathRootComponent(const std::string& p,
+ std::string* root=0);
/**
* Split a path name into its basic components. The first component
@@ -398,77 +455,78 @@ public:
* automatically expanded if expand_home_dir is true and this
* platform supports them.
*/
- static void SplitPath(const char* p,
- kwsys_stl::vector<kwsys_stl::string>& components,
+ static void SplitPath(const std::string& p,
+ std::vector<std::string>& components,
bool expand_home_dir = true);
/**
* Join components of a path name into a single string. See
* SplitPath for the format of the components.
*/
- static kwsys_stl::string JoinPath(
- const kwsys_stl::vector<kwsys_stl::string>& components);
- static kwsys_stl::string JoinPath(
- kwsys_stl::vector<kwsys_stl::string>::const_iterator first,
- kwsys_stl::vector<kwsys_stl::string>::const_iterator last);
+ static std::string JoinPath(
+ const std::vector<std::string>& components);
+ static std::string JoinPath(
+ std::vector<std::string>::const_iterator first,
+ std::vector<std::string>::const_iterator last);
/**
* Compare a path or components of a path.
*/
- static bool ComparePath(const char* c1, const char* c2);
+ static bool ComparePath(const std::string& c1, const std::string& c2);
/**
* Return path of a full filename (no trailing slashes)
*/
- static kwsys_stl::string GetFilenamePath(const kwsys_stl::string&);
+ static std::string GetFilenamePath(const std::string&);
/**
* Return file name of a full filename (i.e. file name without path)
*/
- static kwsys_stl::string GetFilenameName(const kwsys_stl::string&);
+ static std::string GetFilenameName(const std::string&);
/**
* Split a program from its arguments and handle spaces in the paths
*/
static void SplitProgramFromArgs(
- const char* path,
- kwsys_stl::string& program, kwsys_stl::string& args);
+ const std::string& path,
+ std::string& program, std::string& args);
/**
* Return longest file extension of a full filename (dot included)
*/
- static kwsys_stl::string GetFilenameExtension(const kwsys_stl::string&);
+ static std::string GetFilenameExtension(const std::string&);
/**
* Return shortest file extension of a full filename (dot included)
*/
- static kwsys_stl::string GetFilenameLastExtension(
- const kwsys_stl::string& filename);
-
+ static std::string GetFilenameLastExtension(
+ const std::string& filename);
+
/**
* Return file name without extension of a full filename
*/
- static kwsys_stl::string GetFilenameWithoutExtension(
- const kwsys_stl::string&);
-
+ static std::string GetFilenameWithoutExtension(
+ const std::string&);
+
/**
* Return file name without its last (shortest) extension
*/
- static kwsys_stl::string GetFilenameWithoutLastExtension(
- const kwsys_stl::string&);
-
+ static std::string GetFilenameWithoutLastExtension(
+ const std::string&);
+
/**
* Return whether the path represents a full path (not relative)
*/
+ static bool FileIsFullPath(const std::string&);
static bool FileIsFullPath(const char*);
-
+
/**
* For windows return the short path for the given path,
* Unix just a pass through
*/
- static bool GetShortPath(const char* path, kwsys_stl::string& result);
-
+ static bool GetShortPath(const std::string& path, std::string& result);
+
/**
* Read line from file. Make sure to get everything. Due to a buggy stream
* library on the HP and another on Mac OS X, we need this very carefully
@@ -476,20 +534,20 @@ public:
* end-of-file was reached. If the has_newline argument is specified, it will
* be true when the line read had a newline character.
*/
- static bool GetLineFromStream(kwsys_ios::istream& istr,
- kwsys_stl::string& line,
+ static bool GetLineFromStream(std::istream& istr,
+ std::string& line,
bool* has_newline=0,
long sizeLimit=-1);
/**
* Get the parent directory of the directory or file
*/
- static kwsys_stl::string GetParentDirectory(const char* fileOrDir);
+ static std::string GetParentDirectory(const std::string& fileOrDir);
/**
* Check if the given file or directory is in subdirectory of dir
*/
- static bool IsSubDirectory(const char* fileOrDir, const char* dir);
+ static bool IsSubDirectory(const std::string& fileOrDir, const std::string& dir);
/** -----------------------------------------------------------------
* File Manipulation Routines
@@ -497,40 +555,46 @@ public:
*/
/**
+ * Open a file considering unicode.
+ */
+ static FILE* Fopen(const std::string& file, const char* mode);
+
+ /**
* Make a new directory if it is not there. This function
* can make a full path even if none of the directories existed
- * prior to calling this function.
+ * prior to calling this function.
*/
static bool MakeDirectory(const char* path);
+ static bool MakeDirectory(const std::string& path);
/**
* Copy the source file to the destination file only
* if the two files differ.
*/
- static bool CopyFileIfDifferent(const char* source,
- const char* destination);
+ static bool CopyFileIfDifferent(const std::string& source,
+ const std::string& destination);
/**
* Compare the contents of two files. Return true if different
*/
- static bool FilesDiffer(const char* source, const char* destination);
+ static bool FilesDiffer(const std::string& source, const std::string& destination);
/**
* Return true if the two files are the same file
*/
- static bool SameFile(const char* file1, const char* file2);
+ static bool SameFile(const std::string& file1, const std::string& file2);
/**
* Copy a file.
*/
- static bool CopyFileAlways(const char* source, const char* destination);
+ static bool CopyFileAlways(const std::string& source, const std::string& destination);
/**
* Copy a file. If the "always" argument is true the file is always
* copied. If it is false, the file is copied only if it is new or
* has changed.
*/
- static bool CopyAFile(const char* source, const char* destination,
+ static bool CopyAFile(const std::string& source, const std::string& destination,
bool always = true);
/**
@@ -539,18 +603,18 @@ public:
* always copied. If it is false, only files that have changed or
* are new are copied.
*/
- static bool CopyADirectory(const char* source, const char* destination,
+ static bool CopyADirectory(const std::string& source, const std::string& destination,
bool always = true);
-
+
/**
* Remove a file
*/
- static bool RemoveFile(const char* source);
-
+ static bool RemoveFile(const std::string& source);
+
/**
* Remove a directory
*/
- static bool RemoveADirectory(const char* source);
+ static bool RemoveADirectory(const std::string& source);
/**
* Get the maximum full file path length
@@ -560,52 +624,57 @@ public:
/**
* Find a file in the system PATH, with optional extra paths
*/
- static kwsys_stl::string FindFile(
- const char* name,
- const kwsys_stl::vector<kwsys_stl::string>& path =
- kwsys_stl::vector<kwsys_stl::string>(),
+ static std::string FindFile(
+ const std::string& name,
+ const std::vector<std::string>& path =
+ std::vector<std::string>(),
bool no_system_path = false);
/**
* Find a directory in the system PATH, with optional extra paths
*/
- static kwsys_stl::string FindDirectory(
- const char* name,
- const kwsys_stl::vector<kwsys_stl::string>& path =
- kwsys_stl::vector<kwsys_stl::string>(),
+ static std::string FindDirectory(
+ const std::string& name,
+ const std::vector<std::string>& path =
+ std::vector<std::string>(),
bool no_system_path = false);
/**
* Find an executable in the system PATH, with optional extra paths
*/
- static kwsys_stl::string FindProgram(
+ static std::string FindProgram(
const char* name,
- const kwsys_stl::vector<kwsys_stl::string>& path =
- kwsys_stl::vector<kwsys_stl::string>(),
+ const std::vector<std::string>& path =
+ std::vector<std::string>(),
+ bool no_system_path = false);
+ static std::string FindProgram(
+ const std::string& name,
+ const std::vector<std::string>& path =
+ std::vector<std::string>(),
bool no_system_path = false);
- static kwsys_stl::string FindProgram(
- const kwsys_stl::vector<kwsys_stl::string>& names,
- const kwsys_stl::vector<kwsys_stl::string>& path =
- kwsys_stl::vector<kwsys_stl::string>(),
+ static std::string FindProgram(
+ const std::vector<std::string>& names,
+ const std::vector<std::string>& path =
+ std::vector<std::string>(),
bool no_system_path = false);
/**
* Find a library in the system PATH, with optional extra paths
*/
- static kwsys_stl::string FindLibrary(
- const char* name,
- const kwsys_stl::vector<kwsys_stl::string>& path);
-
+ static std::string FindLibrary(
+ const std::string& name,
+ const std::vector<std::string>& path);
+
/**
* Return true if the file is a directory
*/
- static bool FileIsDirectory(const char* name);
-
+ static bool FileIsDirectory(const std::string& name);
+
/**
* Return true if the file is a symlink
*/
- static bool FileIsSymlink(const char* name);
-
+ static bool FileIsSymlink(const std::string& name);
+
/**
* Return true if the file has a given signature (first set of bytes)
*/
@@ -621,28 +690,28 @@ public:
* The algorithm is simplistic, and should probably check for usual file
* extensions, 'magic' signature, unicode, etc.
*/
- enum FileTypeEnum
- {
+ enum FileTypeEnum
+ {
FileTypeUnknown,
FileTypeBinary,
FileTypeText
};
static SystemTools::FileTypeEnum DetectFileType(
- const char* filename,
- unsigned long length = 256,
+ const char* filename,
+ unsigned long length = 256,
double percent_bin = 0.05);
/**
* Create a symbolic link if the platform supports it. Returns whether
- * creation succeded.
+ * creation succeeded.
*/
- static bool CreateSymlink(const char* origName, const char* newName);
+ static bool CreateSymlink(const std::string& origName, const std::string& newName);
/**
* Read the contents of a symbolic link. Returns whether reading
- * succeded.
+ * succeeded.
*/
- static bool ReadSymlink(const char* newName, kwsys_stl::string& origName);
+ static bool ReadSymlink(const std::string& newName, std::string& origName);
/**
* Try to locate the file 'filename' in the directory 'dir'.
@@ -654,41 +723,55 @@ public:
* 'filename_found' is assigned the fully qualified name/path of the file
* if it is found (not touched otherwise).
* If 'try_filename_dirs' is true, try to find the file using the
- * components of its path, i.e. if we are looking for c:/foo/bar/bill.txt,
+ * components of its path, i.e. if we are looking for c:/foo/bar/bill.txt,
* first look for bill.txt in 'dir', then in 'dir'/bar, then in 'dir'/foo/bar
* etc.
* Return true if the file was found, false otherwise.
*/
- static bool LocateFileInDir(const char *filename,
- const char *dir,
- kwsys_stl::string& filename_found,
+ static bool LocateFileInDir(const char *filename,
+ const char *dir,
+ std::string& filename_found,
int try_filename_dirs = 0);
- /** compute the relative path from local to remote. local must
- be a directory. remote can be a file or a directory.
+ /** compute the relative path from local to remote. local must
+ be a directory. remote can be a file or a directory.
Both remote and local must be full paths. Basically, if
you are in directory local and you want to access the file in remote
what is the relative path to do that. For example:
/a/b/c/d to /a/b/c1/d1 -> ../../c1/d1
from /usr/src to /usr/src/test/blah/foo.cpp -> test/blah/foo.cpp
*/
- static kwsys_stl::string RelativePath(const char* local, const char* remote);
+ static std::string RelativePath(const std::string& local, const std::string& remote);
/**
* Return file's modified time
*/
- static long int ModifiedTime(const char* filename);
+ static long int ModifiedTime(const std::string& filename);
/**
* Return file's creation time (Win32: works only for NTFS, not FAT)
*/
- static long int CreationTime(const char* filename);
+ static long int CreationTime(const std::string& filename);
/**
- * Get and set permissions of the file.
+ * Visual C++ does not define mode_t (note that Borland does, however).
+ */
+ #if defined( _MSC_VER )
+ typedef unsigned short mode_t;
+ #endif
+
+ /**
+ * Get and set permissions of the file. If honor_umask is set, the umask
+ * is queried and applied to the given permissions. Returns false if
+ * failure.
+ *
+ * WARNING: A non-thread-safe method is currently used to get the umask
+ * if a honor_umask parameter is set to true.
*/
static bool GetPermissions(const char* file, mode_t& mode);
- static bool SetPermissions(const char* file, mode_t mode);
+ static bool GetPermissions(const std::string& file, mode_t& mode);
+ static bool SetPermissions(const char* file, mode_t mode, bool honor_umask = false);
+ static bool SetPermissions(const std::string& file, mode_t mode, bool honor_umask = false);
/** -----------------------------------------------------------------
* Time Manipulation Routines
@@ -701,7 +784,7 @@ public:
/**
* Get current date/time
*/
- static kwsys_stl::string GetCurrentDateTime(const char* format);
+ static std::string GetCurrentDateTime(const char* format);
/** -----------------------------------------------------------------
* Registry Manipulation Routines
@@ -718,26 +801,26 @@ public:
/**
* Get a list of subkeys.
*/
- static bool GetRegistrySubKeys(const char *key,
- kwsys_stl::vector<kwsys_stl::string>& subkeys,
+ static bool GetRegistrySubKeys(const std::string& key,
+ std::vector<std::string>& subkeys,
KeyWOW64 view = KeyWOW64_Default);
/**
* Read a registry value
*/
- static bool ReadRegistryValue(const char *key, kwsys_stl::string &value,
+ static bool ReadRegistryValue(const std::string& key, std::string &value,
KeyWOW64 view = KeyWOW64_Default);
/**
* Write a registry value
*/
- static bool WriteRegistryValue(const char *key, const char *value,
+ static bool WriteRegistryValue(const std::string& key, const std::string& value,
KeyWOW64 view = KeyWOW64_Default);
/**
* Delete a registry value
*/
- static bool DeleteRegistryValue(const char *key,
+ static bool DeleteRegistryValue(const std::string& key,
KeyWOW64 view = KeyWOW64_Default);
/** -----------------------------------------------------------------
@@ -750,37 +833,39 @@ public:
* string vector passed in. If env is set then the value
* of env will be used instead of PATH.
*/
- static void GetPath(kwsys_stl::vector<kwsys_stl::string>& path,
+ static void GetPath(std::vector<std::string>& path,
const char* env=0);
/**
* Read an environment variable
*/
static const char* GetEnv(const char* key);
- static bool GetEnv(const char* key, kwsys_stl::string& result);
+ static const char* GetEnv(const std::string& key);
+ static bool GetEnv(const char* key, std::string& result);
+ static bool GetEnv(const std::string& key, std::string& result);
/** Put a string into the environment
of the form var=value */
- static bool PutEnv(const char* env);
+ static bool PutEnv(const std::string& env);
/** Remove a string from the environment.
Input is of the form "var" or "var=value" (value is ignored). */
- static bool UnPutEnv(const char* env);
+ static bool UnPutEnv(const std::string& env);
/**
* Get current working directory CWD
*/
- static kwsys_stl::string GetCurrentWorkingDirectory(bool collapse =true);
+ static std::string GetCurrentWorkingDirectory(bool collapse =true);
/**
* Change directory to the directory specified
*/
- static int ChangeDirectory(const char* dir);
+ static int ChangeDirectory(const std::string& dir);
/**
* Get the result of strerror(errno)
*/
- static kwsys_stl::string GetLastSystemError();
+ static std::string GetLastSystemError();
/**
* When building DEBUG with MSVC, this enables a hook that prevents
@@ -799,18 +884,18 @@ public:
/**
* Add an entry in the path translation table.
*/
- static void AddTranslationPath(const char * dir, const char * refdir);
+ static void AddTranslationPath(const std::string& dir, const std::string& refdir);
/**
* If dir is different after CollapseFullPath is called,
* Then insert it into the path translation table
*/
- static void AddKeepPath(const char* dir);
+ static void AddKeepPath(const std::string& dir);
/**
* Update path by going through the Path Translation table;
*/
- static void CheckTranslationPath(kwsys_stl::string & path);
+ static void CheckTranslationPath(std::string & path);
/**
* Delay the execution for a specified amount of time specified
@@ -822,16 +907,7 @@ public:
* Get the operating system name and version
* This is implemented for Win32 only for the moment
*/
- static kwsys_stl::string GetOperatingSystemNameAndVersion();
-
- /**
- * Convert windows-style arguments given as a command-line string
- * into more traditional argc/argv arguments.
- * Note that argv[0] will be assigned the executable name using
- * the GetModuleFileName() function.
- */
- static void ConvertWindowsCommandLineToUnixArguments(
- const char *cmd_line, int *argc, char ***argv);
+ static std::string GetOperatingSystemNameAndVersion();
/** -----------------------------------------------------------------
* URL Manipulation Routines
@@ -844,9 +920,9 @@ public:
* and fill protocol as appropriate.
* Return false if the URL does not have the required form, true otherwise.
*/
- static bool ParseURLProtocol( const kwsys_stl::string& URL,
- kwsys_stl::string& protocol,
- kwsys_stl::string& dataglom );
+ static bool ParseURLProtocol( const std::string& URL,
+ std::string& protocol,
+ std::string& dataglom );
/**
* Parse a string (a URL without protocol prefix) with the form:
@@ -855,13 +931,13 @@ public:
* when values are found.
* Return true if the string matches the format; false otherwise.
*/
- static bool ParseURL( const kwsys_stl::string& URL,
- kwsys_stl::string& protocol,
- kwsys_stl::string& username,
- kwsys_stl::string& password,
- kwsys_stl::string& hostname,
- kwsys_stl::string& dataport,
- kwsys_stl::string& datapath );
+ static bool ParseURL( const std::string& URL,
+ std::string& protocol,
+ std::string& username,
+ std::string& password,
+ std::string& hostname,
+ std::string& dataport,
+ std::string& datapath );
private:
/**
@@ -883,13 +959,26 @@ private:
}
/**
+ * Actual implementation of ReplaceString.
+ */
+ static void ReplaceString(std::string& source,
+ const char* replace,
+ size_t replaceSize,
+ const std::string& with);
+
+ /**
+ * Actual implementation of FileIsFullPath.
+ */
+ static bool FileIsFullPath(const char*, size_t);
+
+ /**
* Find a filename (file or directory) in the system PATH, with
* optional extra paths.
*/
- static kwsys_stl::string FindName(
- const char* name,
- const kwsys_stl::vector<kwsys_stl::string>& path =
- kwsys_stl::vector<kwsys_stl::string>(),
+ static std::string FindName(
+ const std::string& name,
+ const std::vector<std::string>& path =
+ std::vector<std::string>(),
bool no_system_path = false);
@@ -898,7 +987,9 @@ private:
* Each time 'dir' will be found it will be replace by 'refdir'
*/
static SystemToolsTranslationMap *TranslationMap;
- static SystemToolsTranslationMap *LongPathMap;
+#ifdef _WIN32
+ static SystemToolsPathCaseMap *PathCaseMap;
+#endif
#ifdef __CYGWIN__
static SystemToolsTranslationMap *Cyg2Win32Map;
#endif
@@ -907,10 +998,4 @@ private:
} // namespace @KWSYS_NAMESPACE@
-/* Undefine temporary macros. */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
-# undef kwsys_stl
-# undef kwsys_ios
-#endif
-
#endif
diff --git a/Source/kwsys/Terminal.c b/Source/kwsys/Terminal.c
index 25832c2b1..a8abb6cc6 100644
--- a/Source/kwsys/Terminal.c
+++ b/Source/kwsys/Terminal.c
@@ -104,11 +104,11 @@ void kwsysTerminal_cfprintf(int color, FILE* stream, const char* format, ...)
}
/*--------------------------------------------------------------------------*/
-/* Detect cases when a stream is definately not interactive. */
+/* Detect cases when a stream is definitely not interactive. */
#if !defined(KWSYS_TERMINAL_ISATTY_WORKS)
static int kwsysTerminalStreamIsNotInteractive(FILE* stream)
{
- /* The given stream is definately not interactive if it is a regular
+ /* The given stream is definitely not interactive if it is a regular
file. */
struct stat stream_stat;
if(fstat(fileno(stream), &stream_stat) == 0)
@@ -155,6 +155,7 @@ static const char* kwsysTerminalVT100Names[] =
"mach-color",
"mlterm",
"putty",
+ "putty-256color",
"rxvt",
"rxvt-256color",
"rxvt-cygwin",
@@ -174,6 +175,7 @@ static const char* kwsysTerminalVT100Names[] =
"xterm-88color",
"xterm-color",
"xterm-debian",
+ "xterm-termite",
0
};
@@ -182,14 +184,25 @@ static const char* kwsysTerminalVT100Names[] =
static int kwsysTerminalStreamIsVT100(FILE* stream, int default_vt100,
int default_tty)
{
+ /* Force color according to http://bixense.com/clicolors/ convention. */
+ {
+ const char* clicolor_force = getenv("CLICOLOR_FORCE");
+ if (clicolor_force && *clicolor_force && strcmp(clicolor_force, "0") != 0)
+ {
+ return 1;
+ }
+ }
+
/* 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)
@@ -211,7 +224,7 @@ static int kwsysTerminalStreamIsVT100(FILE* stream, int default_vt100,
(void)default_tty;
return isatty(fileno(stream))? 1:0;
#else
- /* Check for cases in which the stream is definately not a tty. */
+ /* Check for cases in which the stream is definitely not a tty. */
if(kwsysTerminalStreamIsNotInteractive(stream))
{
return 0;
diff --git a/Source/kwsys/hash_fun.hxx.in b/Source/kwsys/hash_fun.hxx.in
index 6f787ddc5..4872b51c7 100644
--- a/Source/kwsys/hash_fun.hxx.in
+++ b/Source/kwsys/hash_fun.hxx.in
@@ -38,8 +38,8 @@
#define @KWSYS_NAMESPACE@_hash_fun_hxx
#include <@KWSYS_NAMESPACE@/Configure.hxx>
-#include <@KWSYS_NAMESPACE@/cstddef> // size_t
-#include <@KWSYS_NAMESPACE@/stl/string> // string
+#include <stddef.h> // size_t
+#include <string>
namespace @KWSYS_NAMESPACE@
{
@@ -55,90 +55,90 @@ inline size_t _stl_hash_string(const char* __s)
return size_t(__h);
}
-@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
struct hash<char*> {
size_t operator()(const char* __s) const { return _stl_hash_string(__s); }
};
-@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
struct hash<const char*> {
size_t operator()(const char* __s) const { return _stl_hash_string(__s); }
};
-@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
- struct hash<@KWSYS_NAMESPACE@_stl::string> {
- size_t operator()(const @KWSYS_NAMESPACE@_stl::string & __s) const { return _stl_hash_string(__s.c_str()); }
+template <>
+ struct hash<std::string> {
+ size_t operator()(const std::string & __s) const { return _stl_hash_string(__s.c_str()); }
};
#if !defined(__BORLANDC__)
-@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
- struct hash<const @KWSYS_NAMESPACE@_stl::string> {
- size_t operator()(const @KWSYS_NAMESPACE@_stl::string & __s) const { return _stl_hash_string(__s.c_str()); }
+template <>
+ struct hash<const std::string> {
+ size_t operator()(const std::string & __s) const { return _stl_hash_string(__s.c_str()); }
};
#endif
-@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
struct hash<char> {
size_t operator()(char __x) const { return __x; }
};
-@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
struct hash<unsigned char> {
size_t operator()(unsigned char __x) const { return __x; }
};
-@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
struct hash<signed char> {
size_t operator()(unsigned char __x) const { return __x; }
};
-@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
struct hash<short> {
size_t operator()(short __x) const { return __x; }
};
-@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
struct hash<unsigned short> {
size_t operator()(unsigned short __x) const { return __x; }
};
-@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
struct hash<int> {
size_t operator()(int __x) const { return __x; }
};
-@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
struct hash<unsigned int> {
size_t operator()(unsigned int __x) const { return __x; }
};
-@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
struct hash<long> {
size_t operator()(long __x) const { return __x; }
};
-@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
struct hash<unsigned long> {
size_t operator()(unsigned long __x) const { return __x; }
};
// use long long or __int64
#if @KWSYS_USE_LONG_LONG@
-@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
struct hash<long long> {
size_t operator()(long long __x) const { return __x; }
};
-@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
struct hash<unsigned long long> {
size_t operator()(unsigned long long __x) const { return __x; }
};
#elif @KWSYS_USE___INT64@
-@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
struct hash<__int64> {
size_t operator()(__int64 __x) const { return __x; }
};
-@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+template <>
struct hash<unsigned __int64> {
size_t operator()(unsigned __int64 __x) const { return __x; }
};
diff --git a/Source/kwsys/hash_map.hxx.in b/Source/kwsys/hash_map.hxx.in
index 6d4379d8e..60c708607 100644
--- a/Source/kwsys/hash_map.hxx.in
+++ b/Source/kwsys/hash_map.hxx.in
@@ -39,7 +39,7 @@
#include <@KWSYS_NAMESPACE@/hashtable.hxx>
#include <@KWSYS_NAMESPACE@/hash_fun.hxx>
-#include <@KWSYS_NAMESPACE@/stl/functional> // equal_to
+#include <functional> // equal_to
#if defined(_MSC_VER)
# pragma warning (push)
@@ -58,9 +58,9 @@ namespace @KWSYS_NAMESPACE@
// select1st is an extension: it is not part of the standard.
template <class T1, class T2>
struct hash_select1st:
- public @KWSYS_NAMESPACE@_stl::unary_function<@KWSYS_NAMESPACE@_stl::pair<T1, T2>, T1>
+ public std::unary_function<std::pair<T1, T2>, T1>
{
- const T1& operator()(const @KWSYS_NAMESPACE@_stl::pair<T1, T2>& __x) const
+ const T1& operator()(const std::pair<T1, T2>& __x) const
{ return __x.first; }
};
@@ -68,8 +68,8 @@ struct hash_select1st:
template <class _Key, class _Tp,
class _HashFcn = hash<_Key>,
- class _EqualKey = @KWSYS_NAMESPACE@_stl::equal_to<_Key>,
- class _Alloc = @KWSYS_NAMESPACE@_HASH_DEFAULT_ALLOCATOR(char) >
+ class _EqualKey = std::equal_to<_Key>,
+ class _Alloc = std::allocator<char> >
class hash_map;
template <class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc>
@@ -81,7 +81,7 @@ template <class _Key, class _Tp, class _HashFcn, class _EqualKey,
class hash_map
{
private:
- typedef hashtable<@KWSYS_NAMESPACE@_stl::pair<const _Key,_Tp>,_Key,_HashFcn,
+ typedef hashtable<std::pair<const _Key,_Tp>,_Key,_HashFcn,
hash_select1st<const _Key,_Tp>,_EqualKey,_Alloc> _Ht;
_Ht _M_ht;
@@ -119,7 +119,6 @@ public:
const allocator_type& __a = allocator_type())
: _M_ht(__n, __hf, __eql, __a) {}
-#if @KWSYS_NAMESPACE@_CXX_HAS_MEMBER_TEMPLATES
template <class _InputIterator>
hash_map(_InputIterator __f, _InputIterator __l)
: _M_ht(100, hasher(), key_equal(), allocator_type())
@@ -140,48 +139,14 @@ public:
: _M_ht(__n, __hf, __eql, __a)
{ _M_ht.insert_unique(__f, __l); }
-#else
- hash_map(const value_type* __f, const value_type* __l)
- : _M_ht(100, hasher(), key_equal(), allocator_type())
- { _M_ht.insert_unique(__f, __l); }
- hash_map(const value_type* __f, const value_type* __l, size_type __n)
- : _M_ht(__n, hasher(), key_equal(), allocator_type())
- { _M_ht.insert_unique(__f, __l); }
- hash_map(const value_type* __f, const value_type* __l, size_type __n,
- const hasher& __hf)
- : _M_ht(__n, __hf, key_equal(), allocator_type())
- { _M_ht.insert_unique(__f, __l); }
- hash_map(const value_type* __f, const value_type* __l, size_type __n,
- const hasher& __hf, const key_equal& __eql,
- const allocator_type& __a = allocator_type())
- : _M_ht(__n, __hf, __eql, __a)
- { _M_ht.insert_unique(__f, __l); }
-
- hash_map(const_iterator __f, const_iterator __l)
- : _M_ht(100, hasher(), key_equal(), allocator_type())
- { _M_ht.insert_unique(__f, __l); }
- hash_map(const_iterator __f, const_iterator __l, size_type __n)
- : _M_ht(__n, hasher(), key_equal(), allocator_type())
- { _M_ht.insert_unique(__f, __l); }
- hash_map(const_iterator __f, const_iterator __l, size_type __n,
- const hasher& __hf)
- : _M_ht(__n, __hf, key_equal(), allocator_type())
- { _M_ht.insert_unique(__f, __l); }
- hash_map(const_iterator __f, const_iterator __l, size_type __n,
- const hasher& __hf, const key_equal& __eql,
- const allocator_type& __a = allocator_type())
- : _M_ht(__n, __hf, __eql, __a)
- { _M_ht.insert_unique(__f, __l); }
-#endif
-
public:
size_type size() const { return _M_ht.size(); }
size_type max_size() const { return _M_ht.max_size(); }
bool empty() const { return _M_ht.empty(); }
void swap(hash_map& __hs) { _M_ht.swap(__hs._M_ht); }
- friend bool operator==@KWSYS_NAMESPACE@_CXX_NULL_TEMPLATE_ARGS(const hash_map&,
- const hash_map&);
+ friend bool operator==<>(const hash_map&,
+ const hash_map&);
iterator begin() { return _M_ht.begin(); }
iterator end() { return _M_ht.end(); }
@@ -189,20 +154,12 @@ public:
const_iterator end() const { return _M_ht.end(); }
public:
- @KWSYS_NAMESPACE@_stl::pair<iterator,bool> insert(const value_type& __obj)
+ std::pair<iterator,bool> insert(const value_type& __obj)
{ return _M_ht.insert_unique(__obj); }
-#if @KWSYS_NAMESPACE@_CXX_HAS_MEMBER_TEMPLATES
template <class _InputIterator>
void insert(_InputIterator __f, _InputIterator __l)
{ _M_ht.insert_unique(__f,__l); }
-#else
- void insert(const value_type* __f, const value_type* __l) {
- _M_ht.insert_unique(__f,__l);
- }
- void insert(const_iterator __f, const_iterator __l)
- { _M_ht.insert_unique(__f, __l); }
-#endif
- @KWSYS_NAMESPACE@_stl::pair<iterator,bool> insert_noresize(const value_type& __obj)
+ std::pair<iterator,bool> insert_noresize(const value_type& __obj)
{ return _M_ht.insert_unique_noresize(__obj); }
iterator find(const key_type& __key) { return _M_ht.find(__key); }
@@ -215,9 +172,9 @@ public:
size_type count(const key_type& __key) const { return _M_ht.count(__key); }
- @KWSYS_NAMESPACE@_stl::pair<iterator, iterator> equal_range(const key_type& __key)
+ std::pair<iterator, iterator> equal_range(const key_type& __key)
{ return _M_ht.equal_range(__key); }
- @KWSYS_NAMESPACE@_stl::pair<const_iterator, const_iterator>
+ std::pair<const_iterator, const_iterator>
equal_range(const key_type& __key) const
{ return _M_ht.equal_range(__key); }
@@ -260,8 +217,8 @@ swap(hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1,
template <class _Key, class _Tp,
class _HashFcn = hash<_Key>,
- class _EqualKey = @KWSYS_NAMESPACE@_stl::equal_to<_Key>,
- class _Alloc = @KWSYS_NAMESPACE@_HASH_DEFAULT_ALLOCATOR(char) >
+ class _EqualKey = std::equal_to<_Key>,
+ class _Alloc = std::allocator<char> >
class hash_multimap;
template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
@@ -274,7 +231,7 @@ template <class _Key, class _Tp, class _HashFcn, class _EqualKey,
class hash_multimap
{
private:
- typedef hashtable<@KWSYS_NAMESPACE@_stl::pair<const _Key, _Tp>, _Key, _HashFcn,
+ typedef hashtable<std::pair<const _Key, _Tp>, _Key, _HashFcn,
hash_select1st<const _Key, _Tp>, _EqualKey, _Alloc>
_Ht;
_Ht _M_ht;
@@ -313,7 +270,6 @@ public:
const allocator_type& __a = allocator_type())
: _M_ht(__n, __hf, __eql, __a) {}
-#if @KWSYS_NAMESPACE@_CXX_HAS_MEMBER_TEMPLATES
template <class _InputIterator>
hash_multimap(_InputIterator __f, _InputIterator __l)
: _M_ht(100, hasher(), key_equal(), allocator_type())
@@ -334,48 +290,14 @@ public:
: _M_ht(__n, __hf, __eql, __a)
{ _M_ht.insert_equal(__f, __l); }
-#else
- hash_multimap(const value_type* __f, const value_type* __l)
- : _M_ht(100, hasher(), key_equal(), allocator_type())
- { _M_ht.insert_equal(__f, __l); }
- hash_multimap(const value_type* __f, const value_type* __l, size_type __n)
- : _M_ht(__n, hasher(), key_equal(), allocator_type())
- { _M_ht.insert_equal(__f, __l); }
- hash_multimap(const value_type* __f, const value_type* __l, size_type __n,
- const hasher& __hf)
- : _M_ht(__n, __hf, key_equal(), allocator_type())
- { _M_ht.insert_equal(__f, __l); }
- hash_multimap(const value_type* __f, const value_type* __l, size_type __n,
- const hasher& __hf, const key_equal& __eql,
- const allocator_type& __a = allocator_type())
- : _M_ht(__n, __hf, __eql, __a)
- { _M_ht.insert_equal(__f, __l); }
-
- hash_multimap(const_iterator __f, const_iterator __l)
- : _M_ht(100, hasher(), key_equal(), allocator_type())
- { _M_ht.insert_equal(__f, __l); }
- hash_multimap(const_iterator __f, const_iterator __l, size_type __n)
- : _M_ht(__n, hasher(), key_equal(), allocator_type())
- { _M_ht.insert_equal(__f, __l); }
- hash_multimap(const_iterator __f, const_iterator __l, size_type __n,
- const hasher& __hf)
- : _M_ht(__n, __hf, key_equal(), allocator_type())
- { _M_ht.insert_equal(__f, __l); }
- hash_multimap(const_iterator __f, const_iterator __l, size_type __n,
- const hasher& __hf, const key_equal& __eql,
- const allocator_type& __a = allocator_type())
- : _M_ht(__n, __hf, __eql, __a)
- { _M_ht.insert_equal(__f, __l); }
-#endif
-
public:
size_type size() const { return _M_ht.size(); }
size_type max_size() const { return _M_ht.max_size(); }
bool empty() const { return _M_ht.empty(); }
void swap(hash_multimap& __hs) { _M_ht.swap(__hs._M_ht); }
- friend bool operator==@KWSYS_NAMESPACE@_CXX_NULL_TEMPLATE_ARGS(const hash_multimap&,
- const hash_multimap&);
+ friend bool operator==<>(const hash_multimap&,
+ const hash_multimap&);
iterator begin() { return _M_ht.begin(); }
iterator end() { return _M_ht.end(); }
@@ -385,17 +307,9 @@ public:
public:
iterator insert(const value_type& __obj)
{ return _M_ht.insert_equal(__obj); }
-#if @KWSYS_NAMESPACE@_CXX_HAS_MEMBER_TEMPLATES
template <class _InputIterator>
void insert(_InputIterator __f, _InputIterator __l)
{ _M_ht.insert_equal(__f,__l); }
-#else
- void insert(const value_type* __f, const value_type* __l) {
- _M_ht.insert_equal(__f,__l);
- }
- void insert(const_iterator __f, const_iterator __l)
- { _M_ht.insert_equal(__f, __l); }
-#endif
iterator insert_noresize(const value_type& __obj)
{ return _M_ht.insert_equal_noresize(__obj); }
@@ -405,9 +319,9 @@ public:
size_type count(const key_type& __key) const { return _M_ht.count(__key); }
- @KWSYS_NAMESPACE@_stl::pair<iterator, iterator> equal_range(const key_type& __key)
+ std::pair<iterator, iterator> equal_range(const key_type& __key)
{ return _M_ht.equal_range(__key); }
- @KWSYS_NAMESPACE@_stl::pair<const_iterator, const_iterator>
+ std::pair<const_iterator, const_iterator>
equal_range(const key_type& __key) const
{ return _M_ht.equal_range(__key); }
diff --git a/Source/kwsys/hash_set.hxx.in b/Source/kwsys/hash_set.hxx.in
index 5ee01a594..c314979f9 100644
--- a/Source/kwsys/hash_set.hxx.in
+++ b/Source/kwsys/hash_set.hxx.in
@@ -39,7 +39,7 @@
#include <@KWSYS_NAMESPACE@/hashtable.hxx>
#include <@KWSYS_NAMESPACE@/hash_fun.hxx>
-#include <@KWSYS_NAMESPACE@/stl/functional> // equal_to
+#include <functional> // equal_to
#if defined(_MSC_VER)
# pragma warning (push)
@@ -57,7 +57,7 @@ namespace @KWSYS_NAMESPACE@
// identity is an extension: it is not part of the standard.
template <class _Tp>
-struct _Identity : public @KWSYS_NAMESPACE@_stl::unary_function<_Tp,_Tp>
+struct _Identity : public std::unary_function<_Tp,_Tp>
{
const _Tp& operator()(const _Tp& __x) const { return __x; }
};
@@ -66,8 +66,8 @@ struct _Identity : public @KWSYS_NAMESPACE@_stl::unary_function<_Tp,_Tp>
template <class _Value,
class _HashFcn = hash<_Value>,
- class _EqualKey = @KWSYS_NAMESPACE@_stl::equal_to<_Value>,
- class _Alloc = @KWSYS_NAMESPACE@_HASH_DEFAULT_ALLOCATOR(char) >
+ class _EqualKey = std::equal_to<_Value>,
+ class _Alloc = std::allocator<char> >
class hash_set;
template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
@@ -116,7 +116,6 @@ public:
const allocator_type& __a = allocator_type())
: _M_ht(__n, __hf, __eql, __a) {}
-#if @KWSYS_NAMESPACE@_CXX_HAS_MEMBER_TEMPLATES
template <class _InputIterator>
hash_set(_InputIterator __f, _InputIterator __l)
: _M_ht(100, hasher(), key_equal(), allocator_type())
@@ -136,40 +135,6 @@ public:
const allocator_type& __a = allocator_type())
: _M_ht(__n, __hf, __eql, __a)
{ _M_ht.insert_unique(__f, __l); }
-#else
-
- hash_set(const value_type* __f, const value_type* __l)
- : _M_ht(100, hasher(), key_equal(), allocator_type())
- { _M_ht.insert_unique(__f, __l); }
- hash_set(const value_type* __f, const value_type* __l, size_type __n)
- : _M_ht(__n, hasher(), key_equal(), allocator_type())
- { _M_ht.insert_unique(__f, __l); }
- hash_set(const value_type* __f, const value_type* __l, size_type __n,
- const hasher& __hf)
- : _M_ht(__n, __hf, key_equal(), allocator_type())
- { _M_ht.insert_unique(__f, __l); }
- hash_set(const value_type* __f, const value_type* __l, size_type __n,
- const hasher& __hf, const key_equal& __eql,
- const allocator_type& __a = allocator_type())
- : _M_ht(__n, __hf, __eql, __a)
- { _M_ht.insert_unique(__f, __l); }
-
- hash_set(const_iterator __f, const_iterator __l)
- : _M_ht(100, hasher(), key_equal(), allocator_type())
- { _M_ht.insert_unique(__f, __l); }
- hash_set(const_iterator __f, const_iterator __l, size_type __n)
- : _M_ht(__n, hasher(), key_equal(), allocator_type())
- { _M_ht.insert_unique(__f, __l); }
- hash_set(const_iterator __f, const_iterator __l, size_type __n,
- const hasher& __hf)
- : _M_ht(__n, __hf, key_equal(), allocator_type())
- { _M_ht.insert_unique(__f, __l); }
- hash_set(const_iterator __f, const_iterator __l, size_type __n,
- const hasher& __hf, const key_equal& __eql,
- const allocator_type& __a = allocator_type())
- : _M_ht(__n, __hf, __eql, __a)
- { _M_ht.insert_unique(__f, __l); }
-#endif
public:
size_type size() const { return _M_ht.size(); }
@@ -177,43 +142,35 @@ public:
bool empty() const { return _M_ht.empty(); }
void swap(hash_set& __hs) { _M_ht.swap(__hs._M_ht); }
- friend bool operator==@KWSYS_NAMESPACE@_CXX_NULL_TEMPLATE_ARGS(const hash_set&,
- const hash_set&);
+ friend bool operator==<>(const hash_set&,
+ const hash_set&);
iterator begin() const { return _M_ht.begin(); }
iterator end() const { return _M_ht.end(); }
public:
- @KWSYS_NAMESPACE@_stl::pair<iterator, bool> insert(const value_type& __obj)
+ std::pair<iterator, bool> insert(const value_type& __obj)
{
typedef typename _Ht::iterator _Ht_iterator;
- @KWSYS_NAMESPACE@_stl::pair<_Ht_iterator, bool> __p = _M_ht.insert_unique(__obj);
- return @KWSYS_NAMESPACE@_stl::pair<iterator,bool>(__p.first, __p.second);
+ std::pair<_Ht_iterator, bool> __p = _M_ht.insert_unique(__obj);
+ return std::pair<iterator,bool>(__p.first, __p.second);
}
-#if @KWSYS_NAMESPACE@_CXX_HAS_MEMBER_TEMPLATES
template <class _InputIterator>
void insert(_InputIterator __f, _InputIterator __l)
{ _M_ht.insert_unique(__f,__l); }
-#else
- void insert(const value_type* __f, const value_type* __l) {
- _M_ht.insert_unique(__f,__l);
- }
- void insert(const_iterator __f, const_iterator __l)
- {_M_ht.insert_unique(__f, __l); }
-#endif
- @KWSYS_NAMESPACE@_stl::pair<iterator, bool> insert_noresize(const value_type& __obj)
+ std::pair<iterator, bool> insert_noresize(const value_type& __obj)
{
typedef typename _Ht::iterator _Ht_iterator;
- @KWSYS_NAMESPACE@_stl::pair<_Ht_iterator, bool> __p =
+ std::pair<_Ht_iterator, bool> __p =
_M_ht.insert_unique_noresize(__obj);
- return @KWSYS_NAMESPACE@_stl::pair<iterator, bool>(__p.first, __p.second);
+ return std::pair<iterator, bool>(__p.first, __p.second);
}
iterator find(const key_type& __key) const { return _M_ht.find(__key); }
size_type count(const key_type& __key) const { return _M_ht.count(__key); }
- @KWSYS_NAMESPACE@_stl::pair<iterator, iterator> equal_range(const key_type& __key) const
+ std::pair<iterator, iterator> equal_range(const key_type& __key) const
{ return _M_ht.equal_range(__key); }
size_type erase(const key_type& __key) {return _M_ht.erase(__key); }
@@ -254,8 +211,8 @@ swap(hash_set<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1,
template <class _Value,
class _HashFcn = hash<_Value>,
- class _EqualKey = @KWSYS_NAMESPACE@_stl::equal_to<_Value>,
- class _Alloc = @KWSYS_NAMESPACE@_HASH_DEFAULT_ALLOCATOR(char) >
+ class _EqualKey = std::equal_to<_Value>,
+ class _Alloc = std::allocator<char> >
class hash_multiset;
template <class _Val, class _HashFcn, class _EqualKey, class _Alloc>
@@ -305,7 +262,6 @@ public:
const allocator_type& __a = allocator_type())
: _M_ht(__n, __hf, __eql, __a) {}
-#if @KWSYS_NAMESPACE@_CXX_HAS_MEMBER_TEMPLATES
template <class _InputIterator>
hash_multiset(_InputIterator __f, _InputIterator __l)
: _M_ht(100, hasher(), key_equal(), allocator_type())
@@ -325,40 +281,6 @@ public:
const allocator_type& __a = allocator_type())
: _M_ht(__n, __hf, __eql, __a)
{ _M_ht.insert_equal(__f, __l); }
-#else
-
- hash_multiset(const value_type* __f, const value_type* __l)
- : _M_ht(100, hasher(), key_equal(), allocator_type())
- { _M_ht.insert_equal(__f, __l); }
- hash_multiset(const value_type* __f, const value_type* __l, size_type __n)
- : _M_ht(__n, hasher(), key_equal(), allocator_type())
- { _M_ht.insert_equal(__f, __l); }
- hash_multiset(const value_type* __f, const value_type* __l, size_type __n,
- const hasher& __hf)
- : _M_ht(__n, __hf, key_equal(), allocator_type())
- { _M_ht.insert_equal(__f, __l); }
- hash_multiset(const value_type* __f, const value_type* __l, size_type __n,
- const hasher& __hf, const key_equal& __eql,
- const allocator_type& __a = allocator_type())
- : _M_ht(__n, __hf, __eql, __a)
- { _M_ht.insert_equal(__f, __l); }
-
- hash_multiset(const_iterator __f, const_iterator __l)
- : _M_ht(100, hasher(), key_equal(), allocator_type())
- { _M_ht.insert_equal(__f, __l); }
- hash_multiset(const_iterator __f, const_iterator __l, size_type __n)
- : _M_ht(__n, hasher(), key_equal(), allocator_type())
- { _M_ht.insert_equal(__f, __l); }
- hash_multiset(const_iterator __f, const_iterator __l, size_type __n,
- const hasher& __hf)
- : _M_ht(__n, __hf, key_equal(), allocator_type())
- { _M_ht.insert_equal(__f, __l); }
- hash_multiset(const_iterator __f, const_iterator __l, size_type __n,
- const hasher& __hf, const key_equal& __eql,
- const allocator_type& __a = allocator_type())
- : _M_ht(__n, __hf, __eql, __a)
- { _M_ht.insert_equal(__f, __l); }
-#endif
public:
size_type size() const { return _M_ht.size(); }
@@ -366,8 +288,8 @@ public:
bool empty() const { return _M_ht.empty(); }
void swap(hash_multiset& hs) { _M_ht.swap(hs._M_ht); }
- friend bool operator==@KWSYS_NAMESPACE@_CXX_NULL_TEMPLATE_ARGS(const hash_multiset&,
- const hash_multiset&);
+ friend bool operator==<>(const hash_multiset&,
+ const hash_multiset&);
iterator begin() const { return _M_ht.begin(); }
iterator end() const { return _M_ht.end(); }
@@ -375,17 +297,9 @@ public:
public:
iterator insert(const value_type& __obj)
{ return _M_ht.insert_equal(__obj); }
-#if @KWSYS_NAMESPACE@_CXX_HAS_MEMBER_TEMPLATES
template <class _InputIterator>
void insert(_InputIterator __f, _InputIterator __l)
{ _M_ht.insert_equal(__f,__l); }
-#else
- void insert(const value_type* __f, const value_type* __l) {
- _M_ht.insert_equal(__f,__l);
- }
- void insert(const_iterator __f, const_iterator __l)
- { _M_ht.insert_equal(__f, __l); }
-#endif
iterator insert_noresize(const value_type& __obj)
{ return _M_ht.insert_equal_noresize(__obj); }
@@ -393,7 +307,7 @@ public:
size_type count(const key_type& __key) const { return _M_ht.count(__key); }
- @KWSYS_NAMESPACE@_stl::pair<iterator, iterator> equal_range(const key_type& __key) const
+ std::pair<iterator, iterator> equal_range(const key_type& __key) const
{ return _M_ht.equal_range(__key); }
size_type erase(const key_type& __key) {return _M_ht.erase(__key); }
diff --git a/Source/kwsys/hashtable.hxx.in b/Source/kwsys/hashtable.hxx.in
index 651de82bf..9a2022657 100644
--- a/Source/kwsys/hashtable.hxx.in
+++ b/Source/kwsys/hashtable.hxx.in
@@ -44,13 +44,13 @@
#include <@KWSYS_NAMESPACE@/Configure.hxx>
-#include <@KWSYS_NAMESPACE@/cstddef> // size_t
-#include <@KWSYS_NAMESPACE@/stl/algorithm> // lower_bound
-#include <@KWSYS_NAMESPACE@/stl/functional> // unary_function
-#include <@KWSYS_NAMESPACE@/stl/iterator> // iterator_traits
-#include <@KWSYS_NAMESPACE@/stl/memory> // allocator
-#include <@KWSYS_NAMESPACE@/stl/utility> // pair
-#include <@KWSYS_NAMESPACE@/stl/vector> // vector
+#include <stddef.h> // size_t
+#include <algorithm> // lower_bound
+#include <functional> // unary_function
+#include <iterator> // iterator_traits
+#include <memory> // allocator
+#include <utility> // pair
+#include <vector> // vector
#if defined(_MSC_VER)
# pragma warning (push)
@@ -73,248 +73,22 @@
# endif
#endif
-#if @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_TEMPLATE
-# define @KWSYS_NAMESPACE@_HASH_DEFAULT_ALLOCATOR(T) @KWSYS_NAMESPACE@_stl::allocator< T >
-#elif @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_NONTEMPLATE
-# define @KWSYS_NAMESPACE@_HASH_DEFAULT_ALLOCATOR(T) @KWSYS_NAMESPACE@_stl::allocator
-#else
-# define @KWSYS_NAMESPACE@_HASH_DEFAULT_ALLOCATOR(T) @KWSYS_NAMESPACE@_stl::alloc
-#endif
-
-#if @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_OBJECTS
-# define @KWSYS_NAMESPACE@_HASH_BUCKETS_INIT(__a) _M_buckets(__a)
-# define @KWSYS_NAMESPACE@_HASH_BUCKETS_GET_ALLOCATOR(__b) , __b.get_allocator()
-#else
-# define @KWSYS_NAMESPACE@_HASH_BUCKETS_INIT(__a) _M_buckets()
-# define @KWSYS_NAMESPACE@_HASH_BUCKETS_GET_ALLOCATOR(__b)
-#endif
-
namespace @KWSYS_NAMESPACE@
{
-//----------------------------------------------------------------------------
-// Define an allocator adaptor for platforms that do not provide an
-// allocator with the rebind member.
-#if !@KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_REBIND
-
-// Utility functions to convert item counts.
-inline size_t hash_sizeof(void*) { return sizeof(char); }
-inline size_t hash_sizeof(const void*) { return sizeof(char); }
-template <class TPtr> inline size_t hash_sizeof(TPtr p)
-{
- static_cast<void>(p);
- return sizeof(*p);
-}
-template <class POut, class PIn, class TSize>
-inline TSize hash_allocator_n(POut out, PIn in, TSize n)
-{
- return n*(hash_sizeof(out)/hash_sizeof(in) +
- (hash_sizeof(out)%hash_sizeof(in)>0));
-}
-
-// Define an allocation method to use the native allocator with
-// the proper signature. The following signatures of the allocate
-// method are used on various STL implementations:
-// pointer allocate(size_type, const void* hint)
-// pointer allocate(size_type)
-// static pointer allocate(size_type, const void* hint)
-// static pointer allocate(size_type)
-// Where pointer might be a real type or void*.
-// This set of overloads decodes the signature for a particular STL.
-// The extra three int/long arguments will favor certain signatures
-// over others in the case that multiple are present to avoid
-// ambiguity errors.
-template <class TAlloc, class PIn, class TSize, class THint, class POut>
-inline void hash_allocate(TAlloc* a, PIn (TAlloc::*allocate)(TSize, THint),
- TSize n_out, const void* hint, POut& out,
- int, int, int)
-{
- TSize n_in = hash_allocator_n(POut(), PIn(), n_out);
- void* vout = (a->*allocate)(n_in, const_cast<THint>(hint));
- out = static_cast<POut>(vout);
-}
-
-template <class TAlloc, class PIn, class TSize, class POut>
-inline void hash_allocate(TAlloc* a, PIn (TAlloc::*allocate)(TSize),
- TSize n_out, const void*, POut& out,
- int, int, long)
-{
- TSize n_in = hash_allocator_n(POut(), PIn(), n_out);
- void* vout = (a->*allocate)(n_in);
- out = static_cast<POut>(vout);
-}
-
-template <class PIn, class TSize, class THint, class POut>
-inline void hash_allocate(void*, PIn (*allocate)(TSize, THint),
- TSize n_out, const void* hint, POut& out,
- int, long, long)
-{
- TSize n_in = hash_allocator_n(POut(), PIn(), n_out);
- void* vout = allocate(n_in, const_cast<THint>(hint));
- out = static_cast<POut>(vout);
-}
-
-template <class PIn, class TSize, class POut>
-inline void hash_allocate(void*, PIn (*allocate)(TSize),
- TSize n_out, const void*, POut& out,
- long, long, long)
-{
- TSize n_in = hash_allocator_n(POut(), PIn(), n_out);
- void* vout = allocate(n_in);
- out = static_cast<POut>(vout);
-}
-
-// Define a deallocation method to use the native allocator with
-// the proper signature. The following signatures of the deallocate
-// method are used on various STL implementations:
-// void deallocate(pointer, size_type)
-// void deallocate(pointer)
-// static void deallocate(pointer, size_type)
-// static void deallocate(pointer)
-// Where pointer might be a real type or void*.
-// This set of overloads decodes the signature for a particular STL.
-// The extra three int/long arguments will favor certain signatures
-// over others in the case that multiple are present to avoid
-// ambiguity errors.
-template <class TAlloc, class PIn, class TSize, class PInReal, class POut>
-inline void hash_deallocate(TAlloc* a, void (TAlloc::*deallocate)(PIn, TSize),
- PInReal, POut p, TSize n_out, int, int, int)
-{
- TSize n_in = hash_allocator_n(POut(), PInReal(), n_out);
- void* vout = p;
- (a->*deallocate)(static_cast<PIn>(vout), n_in);
-}
-
-template <class TAlloc, class PIn, class TSize, class PInReal, class POut>
-inline void hash_deallocate(TAlloc* a, void (TAlloc::*deallocate)(PIn),
- PInReal, POut p, TSize, int, int, long)
-{
- void* vout = p;
- (a->*deallocate)(static_cast<PIn>(vout));
-}
-
-template <class PIn, class TSize, class PInReal, class POut>
-inline void hash_deallocate(void*, void (*deallocate)(PIn, TSize),
- PInReal, POut p, TSize n_out, int, long, long)
-{
- TSize n_in = hash_allocator_n(POut(), PInReal(), n_out);
- void* vout = p;
- deallocate(static_cast<PIn>(vout), n_in);
-}
-
-template <class PIn, class TSize, class PInReal, class POut>
-inline void hash_deallocate(void*, void (*deallocate)(PIn),
- PInReal, POut p, TSize, long, long, long)
-{
- void* vout = p;
- deallocate(static_cast<PIn>(vout));
-}
-
-// Use the same four overloads as hash_allocate to decode the type
-// really used for allocation. This is passed as PInReal to the
-// deallocate functions so that hash_allocator_n has the proper size.
-template <class TAlloc, class PIn, class TSize, class THint>
-inline PIn hash_allocate_type(PIn (TAlloc::*)(TSize, THint),
- int, int, int) { return 0; }
-template <class TAlloc, class PIn, class TSize>
-inline PIn hash_allocate_type(PIn (TAlloc::*)(TSize),
- int, int, long) { return 0; }
-template <class PIn, class TSize, class THint>
-inline PIn hash_allocate_type(PIn (*)(TSize, THint),
- int, long, long) { return 0; }
-template <class PIn, class TSize>
-inline PIn hash_allocate_type(PIn (*)(TSize),
- long, long, long) { return 0; }
-
-// Define the comparison operators in terms of a base type to avoid
-// needing templated versions.
-class hash_allocator_base {};
-inline bool operator==(const hash_allocator_base&,
- const hash_allocator_base&) throw() { return true; }
-inline bool operator!=(const hash_allocator_base&,
- const hash_allocator_base&) throw() { return false; }
-
-// Define the allocator template.
-template <class T, class Alloc>
-class hash_allocator: public hash_allocator_base
-{
-private:
- // Store the real allocator privately.
- typedef Alloc alloc_type;
- alloc_type alloc_;
-
-public:
- // Standard allocator interface.
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef T* pointer;
- typedef const T* const_pointer;
- typedef T& reference;
- typedef const T& const_reference;
- typedef T value_type;
-
- hash_allocator() throw(): alloc_() {}
- hash_allocator(const hash_allocator_base&) throw() : alloc_() {}
- hash_allocator(const hash_allocator& a) throw() : alloc_(a.alloc_) {}
- hash_allocator(const alloc_type& a) throw() : alloc_(a) {}
- ~hash_allocator() throw() {}
-# if @KWSYS_NAMESPACE@_CXX_HAS_MEMBER_TEMPLATES
- template <class U>
- struct rebind { typedef hash_allocator<U, alloc_type> other; };
-# endif
- pointer address(reference x) const { return &x; }
- const_pointer address(const_reference x) const { return &x; }
- typedef void* void_pointer;
- typedef const void* const_void_pointer;
- pointer allocate(size_type n=1, const_void_pointer hint = 0)
- {
- if(n)
- {
- pointer p;
- hash_allocate(&alloc_, &alloc_type::allocate, n, hint, p, 1, 1, 1);
- return p;
- }
- else
- {
- return 0;
- }
- }
- void deallocate(pointer p, size_type n=1)
- {
- if(n)
- {
- hash_deallocate(&alloc_, &alloc_type::deallocate,
- hash_allocate_type(&alloc_type::allocate, 1, 1, 1),
- p, n, 1, 1, 1);
- }
- }
-#if @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT
- size_type max_size(size_type s) const throw()
- {
- return alloc_.max_size(s);
- }
-#else
- size_type max_size() const throw()
- {
- size_type n = alloc_.max_size() / sizeof(value_type);
- return n>0? n:1;
- }
-#endif
- void construct(pointer p, const value_type& val) { new (p) value_type(val); }
- void destroy(pointer p) { (void)p; p->~value_type(); }
-};
-#endif
-
template <class _Val>
struct _Hashtable_node
{
_Hashtable_node* _M_next;
_Val _M_val;
+ void public_method_to_quiet_warning_about_all_methods_private();
+private:
+ void operator=(_Hashtable_node<_Val> const&); // poison node assignment
};
template <class _Val, class _Key, class _HashFcn,
class _ExtractKey, class _EqualKey,
- class _Alloc = @KWSYS_NAMESPACE@_HASH_DEFAULT_ALLOCATOR(char) >
+ class _Alloc = std::allocator<char> >
class hashtable;
template <class _Val, class _Key, class _HashFcn,
@@ -338,7 +112,7 @@ struct _Hashtable_iterator {
const_iterator;
typedef _Hashtable_node<_Val> _Node;
- typedef @KWSYS_NAMESPACE@_stl::forward_iterator_tag iterator_category;
+ typedef std::forward_iterator_tag iterator_category;
typedef _Val value_type;
typedef ptrdiff_t difference_type;
typedef size_t size_type;
@@ -375,7 +149,7 @@ struct _Hashtable_const_iterator {
const_iterator;
typedef _Hashtable_node<_Val> _Node;
- typedef @KWSYS_NAMESPACE@_stl::forward_iterator_tag iterator_category;
+ typedef std::forward_iterator_tag iterator_category;
typedef _Val value_type;
typedef ptrdiff_t difference_type;
typedef size_t size_type;
@@ -420,11 +194,11 @@ static const unsigned long _stl_prime_list[_stl_num_primes] =
return &_stl_prime_list[0]; }
-inline size_t _stl_next_prime(size_t __n)
+static inline size_t _stl_next_prime(size_t __n)
{
const unsigned long* __first = get_stl_prime_list();
const unsigned long* __last = get_stl_prime_list() + (int)_stl_num_primes;
- const unsigned long* pos = @KWSYS_NAMESPACE@_stl::lower_bound(__first, __last, __n);
+ const unsigned long* pos = std::lower_bound(__first, __last, __n);
return pos == __last ? *(__last - 1) : *pos;
}
@@ -467,27 +241,13 @@ public:
private:
typedef _Hashtable_node<_Val> _Node;
-#if @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_REBIND
public:
typedef typename _Alloc::template rebind<_Val>::other allocator_type;
allocator_type get_allocator() const { return _M_node_allocator; }
private:
typedef typename _Alloc::template rebind<_Node>::other _M_node_allocator_type;
typedef typename _Alloc::template rebind<_Node*>::other _M_node_ptr_allocator_type;
- typedef @KWSYS_NAMESPACE@_stl::vector<_Node*,_M_node_ptr_allocator_type> _M_buckets_type;
-#else
-public:
- typedef hash_allocator<_Val, _Alloc> allocator_type;
- allocator_type get_allocator() const { return allocator_type(); }
-private:
- typedef hash_allocator<_Node, _Alloc> _M_node_allocator_type;
-# if @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_OBJECTS
- typedef hash_allocator<_Node*, _Alloc> _M_node_ptr_allocator_type;
-# else
- typedef _Alloc _M_node_ptr_allocator_type;
-# endif
- typedef @KWSYS_NAMESPACE@_stl::vector<_Node*,_M_node_ptr_allocator_type> _M_buckets_type;
-#endif
+ typedef std::vector<_Node*,_M_node_ptr_allocator_type> _M_buckets_type;
private:
_M_node_allocator_type _M_node_allocator;
@@ -522,7 +282,7 @@ public:
_M_hash(__hf),
_M_equals(__eql),
_M_get_key(__ext),
- @KWSYS_NAMESPACE@_HASH_BUCKETS_INIT(__a),
+ _M_buckets(__a),
_M_num_elements(0)
{
_M_initialize_buckets(__n);
@@ -536,7 +296,7 @@ public:
_M_hash(__hf),
_M_equals(__eql),
_M_get_key(_ExtractKey()),
- @KWSYS_NAMESPACE@_HASH_BUCKETS_INIT(__a),
+ _M_buckets(__a),
_M_num_elements(0)
{
_M_initialize_buckets(__n);
@@ -547,7 +307,7 @@ public:
_M_hash(__ht._M_hash),
_M_equals(__ht._M_equals),
_M_get_key(__ht._M_get_key),
- @KWSYS_NAMESPACE@_HASH_BUCKETS_INIT(__ht.get_allocator()),
+ _M_buckets(__ht.get_allocator()),
_M_num_elements(0)
{
_M_copy_from(__ht);
@@ -573,11 +333,11 @@ public:
void swap(hashtable& __ht)
{
- @KWSYS_NAMESPACE@_stl::swap(_M_hash, __ht._M_hash);
- @KWSYS_NAMESPACE@_stl::swap(_M_equals, __ht._M_equals);
- @KWSYS_NAMESPACE@_stl::swap(_M_get_key, __ht._M_get_key);
+ std::swap(_M_hash, __ht._M_hash);
+ std::swap(_M_equals, __ht._M_equals);
+ std::swap(_M_get_key, __ht._M_get_key);
_M_buckets.swap(__ht._M_buckets);
- @KWSYS_NAMESPACE@_stl::swap(_M_num_elements, __ht._M_num_elements);
+ std::swap(_M_num_elements, __ht._M_num_elements);
}
iterator begin()
@@ -600,8 +360,8 @@ public:
const_iterator end() const { return const_iterator(0, this); }
- friend bool operator==@KWSYS_NAMESPACE@_CXX_NULL_TEMPLATE_ARGS(const hashtable&,
- const hashtable&);
+ friend bool operator==<>(const hashtable&,
+ const hashtable&);
public:
@@ -618,7 +378,7 @@ public:
return __result;
}
- @KWSYS_NAMESPACE@_stl::pair<iterator, bool> insert_unique(const value_type& __obj)
+ std::pair<iterator, bool> insert_unique(const value_type& __obj)
{
resize(_M_num_elements + 1);
return insert_unique_noresize(__obj);
@@ -630,38 +390,26 @@ public:
return insert_equal_noresize(__obj);
}
- @KWSYS_NAMESPACE@_stl::pair<iterator, bool> insert_unique_noresize(const value_type& __obj);
+ std::pair<iterator, bool> insert_unique_noresize(const value_type& __obj);
iterator insert_equal_noresize(const value_type& __obj);
-#if @KWSYS_NAMESPACE@_STL_HAS_ITERATOR_TRAITS
-# define @KWSYS_NAMESPACE@_HASH_ITERATOR_CATEGORY(T,I) \
- typename @KWSYS_NAMESPACE@_stl::iterator_traits< T >::iterator_category()
-#elif @KWSYS_NAMESPACE@_STL_HAS_ITERATOR_CATEGORY
-# define @KWSYS_NAMESPACE@_HASH_ITERATOR_CATEGORY(T,I) \
- @KWSYS_NAMESPACE@_stl::iterator_category( I )
-#elif @KWSYS_NAMESPACE@_STL_HAS___ITERATOR_CATEGORY
-# define @KWSYS_NAMESPACE@_HASH_ITERATOR_CATEGORY(T,I) \
- @KWSYS_NAMESPACE@_stl::__iterator_category( I )
-#endif
-
-#if @KWSYS_NAMESPACE@_CXX_HAS_MEMBER_TEMPLATES && defined(@KWSYS_NAMESPACE@_HASH_ITERATOR_CATEGORY)
template <class _InputIterator>
void insert_unique(_InputIterator __f, _InputIterator __l)
{
insert_unique(__f, __l,
- @KWSYS_NAMESPACE@_HASH_ITERATOR_CATEGORY(_InputIterator, __f));
+ typename std::iterator_traits<_InputIterator>::iterator_category());
}
template <class _InputIterator>
void insert_equal(_InputIterator __f, _InputIterator __l)
{
insert_equal(__f, __l,
- @KWSYS_NAMESPACE@_HASH_ITERATOR_CATEGORY(_InputIterator, __f));
+ typename std::iterator_traits<_InputIterator>::iterator_category());
}
template <class _InputIterator>
void insert_unique(_InputIterator __f, _InputIterator __l,
- @KWSYS_NAMESPACE@_stl::input_iterator_tag)
+ std::input_iterator_tag)
{
for ( ; __f != __l; ++__f)
insert_unique(*__f);
@@ -669,7 +417,7 @@ public:
template <class _InputIterator>
void insert_equal(_InputIterator __f, _InputIterator __l,
- @KWSYS_NAMESPACE@_stl::input_iterator_tag)
+ std::input_iterator_tag)
{
for ( ; __f != __l; ++__f)
insert_equal(*__f);
@@ -677,10 +425,10 @@ public:
template <class _ForwardIterator>
void insert_unique(_ForwardIterator __f, _ForwardIterator __l,
- @KWSYS_NAMESPACE@_stl::forward_iterator_tag)
+ std::forward_iterator_tag)
{
size_type __n = 0;
- @KWSYS_NAMESPACE@_stl::distance(__f, __l, __n);
+ std::distance(__f, __l, __n);
resize(_M_num_elements + __n);
for ( ; __n > 0; --__n, ++__f)
insert_unique_noresize(*__f);
@@ -688,50 +436,14 @@ public:
template <class _ForwardIterator>
void insert_equal(_ForwardIterator __f, _ForwardIterator __l,
- @KWSYS_NAMESPACE@_stl::forward_iterator_tag)
- {
- size_type __n = 0;
- @KWSYS_NAMESPACE@_stl::distance(__f, __l, __n);
- resize(_M_num_elements + __n);
- for ( ; __n > 0; --__n, ++__f)
- insert_equal_noresize(*__f);
- }
-
-#else
- void insert_unique(const value_type* __f, const value_type* __l)
- {
- size_type __n = __l - __f;
- resize(_M_num_elements + __n);
- for ( ; __n > 0; --__n, ++__f)
- insert_unique_noresize(*__f);
- }
-
- void insert_equal(const value_type* __f, const value_type* __l)
- {
- size_type __n = __l - __f;
- resize(_M_num_elements + __n);
- for ( ; __n > 0; --__n, ++__f)
- insert_equal_noresize(*__f);
- }
-
- void insert_unique(const_iterator __f, const_iterator __l)
+ std::forward_iterator_tag)
{
size_type __n = 0;
- @KWSYS_NAMESPACE@_stl::distance(__f, __l, __n);
- resize(_M_num_elements + __n);
- for ( ; __n > 0; --__n, ++__f)
- insert_unique_noresize(*__f);
- }
-
- void insert_equal(const_iterator __f, const_iterator __l)
- {
- size_type __n = 0;
- @KWSYS_NAMESPACE@_stl::distance(__f, __l, __n);
+ std::distance(__f, __l, __n);
resize(_M_num_elements + __n);
for ( ; __n > 0; --__n, ++__f)
insert_equal_noresize(*__f);
}
-#endif
reference find_or_insert(const value_type& __obj);
@@ -768,10 +480,10 @@ public:
return __result;
}
- @KWSYS_NAMESPACE@_stl::pair<iterator, iterator>
+ std::pair<iterator, iterator>
equal_range(const key_type& __key);
- @KWSYS_NAMESPACE@_stl::pair<const_iterator, const_iterator>
+ std::pair<const_iterator, const_iterator>
equal_range(const key_type& __key) const;
size_type erase(const key_type& __key);
@@ -933,7 +645,7 @@ inline void swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1,
}
template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-@KWSYS_NAMESPACE@_stl::pair<@KWSYS_NAMESPACE@_CXX_DECL_TYPENAME hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator, bool>
+std::pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator, bool>
hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
::insert_unique_noresize(const value_type& __obj)
{
@@ -942,13 +654,13 @@ hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
- return @KWSYS_NAMESPACE@_stl::pair<iterator, bool>(iterator(__cur, this), false);
+ return std::pair<iterator, bool>(iterator(__cur, this), false);
_Node* __tmp = _M_new_node(__obj);
__tmp->_M_next = __first;
_M_buckets[__n] = __tmp;
++_M_num_elements;
- return @KWSYS_NAMESPACE@_stl::pair<iterator, bool>(iterator(__tmp, this), true);
+ return std::pair<iterator, bool>(iterator(__tmp, this), true);
}
template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
@@ -996,11 +708,11 @@ hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::find_or_insert(const value_type& __obj)
}
template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-@KWSYS_NAMESPACE@_stl::pair<@KWSYS_NAMESPACE@_CXX_DECL_TYPENAME hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator,
- @KWSYS_NAMESPACE@_CXX_DECL_TYPENAME hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator>
+std::pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator,
+ typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator>
hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::equal_range(const key_type& __key)
{
- typedef @KWSYS_NAMESPACE@_stl::pair<iterator, iterator> _Pii;
+ typedef std::pair<iterator, iterator> _Pii;
const size_type __n = _M_bkt_num_key(__key);
for (_Node* __first = _M_buckets[__n]; __first; __first = __first->_M_next)
@@ -1018,12 +730,12 @@ hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::equal_range(const key_type& __key)
}
template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-@KWSYS_NAMESPACE@_stl::pair<@KWSYS_NAMESPACE@_CXX_DECL_TYPENAME hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator,
- @KWSYS_NAMESPACE@_CXX_DECL_TYPENAME hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator>
+std::pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator,
+ typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator>
hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
::equal_range(const key_type& __key) const
{
- typedef @KWSYS_NAMESPACE@_stl::pair<const_iterator, const_iterator> _Pii;
+ typedef std::pair<const_iterator, const_iterator> _Pii;
const size_type __n = _M_bkt_num_key(__key);
for (const _Node* __first = _M_buckets[__n] ;
@@ -1161,8 +873,8 @@ void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
const size_type __n = _M_next_size(__num_elements_hint);
if (__n > __old_n) {
_M_buckets_type __tmp(
- __n, (_Node*)(0)
- @KWSYS_NAMESPACE@_HASH_BUCKETS_GET_ALLOCATOR(_M_buckets));
+ __n, (_Node*)(0),
+ _M_buckets.get_allocator());
try {
for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) {
_Node* __first = _M_buckets[__bucket];
@@ -1271,14 +983,6 @@ void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
} // namespace @KWSYS_NAMESPACE@
-// Normally the comparison operators should be found in the @KWSYS_NAMESPACE@
-// namespace by argument dependent lookup. For compilers that do not
-// support it we must bring them into the global namespace now.
-#if !@KWSYS_NAMESPACE@_CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP
-using @KWSYS_NAMESPACE@::operator==;
-using @KWSYS_NAMESPACE@::operator!=;
-#endif
-
// Undo warning suppression.
#if defined(__clang__) && defined(__has_warning)
# if __has_warning("-Wdeprecated")
diff --git a/Source/kwsys/kwsysPlatformTests.cmake b/Source/kwsys/kwsysPlatformTests.cmake
index f9ee254f0..0da0f635f 100644
--- a/Source/kwsys/kwsysPlatformTests.cmake
+++ b/Source/kwsys/kwsysPlatformTests.cmake
@@ -13,7 +13,7 @@ SET(KWSYS_PLATFORM_TEST_FILE_C kwsysPlatformTestsC.c)
SET(KWSYS_PLATFORM_TEST_FILE_CXX kwsysPlatformTestsCXX.cxx)
MACRO(KWSYS_PLATFORM_TEST lang var description invert)
- IF("${var}_COMPILED" MATCHES "^${var}_COMPILED$")
+ IF(NOT DEFINED ${var}_COMPILED)
MESSAGE(STATUS "${description}")
TRY_COMPILE(${var}_COMPILED
${CMAKE_CURRENT_BINARY_DIR}
@@ -25,42 +25,42 @@ MACRO(KWSYS_PLATFORM_TEST lang var description invert)
FILE(APPEND
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"${description} compiled with the following output:\n${OUTPUT}\n\n")
- ELSE(${var}_COMPILED)
+ ELSE()
FILE(APPEND
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"${description} failed to compile with the following output:\n${OUTPUT}\n\n")
- ENDIF(${var}_COMPILED)
+ ENDIF()
IF(${invert} MATCHES INVERT)
IF(${var}_COMPILED)
MESSAGE(STATUS "${description} - no")
- ELSE(${var}_COMPILED)
+ ELSE()
MESSAGE(STATUS "${description} - yes")
- ENDIF(${var}_COMPILED)
- ELSE(${invert} MATCHES INVERT)
+ ENDIF()
+ ELSE()
IF(${var}_COMPILED)
MESSAGE(STATUS "${description} - yes")
- ELSE(${var}_COMPILED)
+ ELSE()
MESSAGE(STATUS "${description} - no")
- ENDIF(${var}_COMPILED)
- ENDIF(${invert} MATCHES INVERT)
- ENDIF("${var}_COMPILED" MATCHES "^${var}_COMPILED$")
+ ENDIF()
+ ENDIF()
+ ENDIF()
IF(${invert} MATCHES INVERT)
IF(${var}_COMPILED)
SET(${var} 0)
- ELSE(${var}_COMPILED)
+ ELSE()
SET(${var} 1)
- ENDIF(${var}_COMPILED)
- ELSE(${invert} MATCHES INVERT)
+ ENDIF()
+ ELSE()
IF(${var}_COMPILED)
SET(${var} 1)
- ELSE(${var}_COMPILED)
+ ELSE()
SET(${var} 0)
- ENDIF(${var}_COMPILED)
- ENDIF(${invert} MATCHES INVERT)
-ENDMACRO(KWSYS_PLATFORM_TEST)
+ ENDIF()
+ ENDIF()
+ENDMACRO()
MACRO(KWSYS_PLATFORM_TEST_RUN lang var description invert)
- IF("${var}" MATCHES "^${var}$")
+ IF(NOT DEFINED ${var})
MESSAGE(STATUS "${description}")
TRY_RUN(${var} ${var}_COMPILED
${CMAKE_CURRENT_BINARY_DIR}
@@ -74,63 +74,63 @@ MACRO(KWSYS_PLATFORM_TEST_RUN lang var description invert)
FILE(APPEND
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"${description} compiled but failed to run with the following output:\n${OUTPUT}\n\n")
- ELSE(${var})
+ ELSE()
FILE(APPEND
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"${description} compiled and ran with the following output:\n${OUTPUT}\n\n")
- ENDIF(${var})
- ELSE(${var}_COMPILED)
+ ENDIF()
+ ELSE()
FILE(APPEND
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"${description} failed to compile with the following output:\n${OUTPUT}\n\n")
SET(${var} -1 CACHE INTERNAL "${description} failed to compile.")
- ENDIF(${var}_COMPILED)
+ ENDIF()
IF(${invert} MATCHES INVERT)
IF(${var}_COMPILED)
IF(${var})
MESSAGE(STATUS "${description} - yes")
- ELSE(${var})
+ ELSE()
MESSAGE(STATUS "${description} - no")
- ENDIF(${var})
- ELSE(${var}_COMPILED)
+ ENDIF()
+ ELSE()
MESSAGE(STATUS "${description} - failed to compile")
- ENDIF(${var}_COMPILED)
- ELSE(${invert} MATCHES INVERT)
+ ENDIF()
+ ELSE()
IF(${var}_COMPILED)
IF(${var})
MESSAGE(STATUS "${description} - no")
- ELSE(${var})
+ ELSE()
MESSAGE(STATUS "${description} - yes")
- ENDIF(${var})
- ELSE(${var}_COMPILED)
+ ENDIF()
+ ELSE()
MESSAGE(STATUS "${description} - failed to compile")
- ENDIF(${var}_COMPILED)
- ENDIF(${invert} MATCHES INVERT)
- ENDIF("${var}" MATCHES "^${var}$")
+ ENDIF()
+ ENDIF()
+ ENDIF()
IF(${invert} MATCHES INVERT)
IF(${var}_COMPILED)
IF(${var})
SET(${var} 1)
- ELSE(${var})
+ ELSE()
SET(${var} 0)
- ENDIF(${var})
- ELSE(${var}_COMPILED)
+ ENDIF()
+ ELSE()
SET(${var} 1)
- ENDIF(${var}_COMPILED)
- ELSE(${invert} MATCHES INVERT)
+ ENDIF()
+ ELSE()
IF(${var}_COMPILED)
IF(${var})
SET(${var} 0)
- ELSE(${var})
+ ELSE()
SET(${var} 1)
- ENDIF(${var})
- ELSE(${var}_COMPILED)
+ ENDIF()
+ ELSE()
SET(${var} 0)
- ENDIF(${var}_COMPILED)
- ENDIF(${invert} MATCHES INVERT)
-ENDMACRO(KWSYS_PLATFORM_TEST_RUN)
+ ENDIF()
+ ENDIF()
+ENDMACRO()
MACRO(KWSYS_PLATFORM_C_TEST var description invert)
SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_C_TEST_DEFINES})
@@ -138,7 +138,7 @@ MACRO(KWSYS_PLATFORM_C_TEST var description invert)
KWSYS_PLATFORM_TEST(C "${var}" "${description}" "${invert}")
SET(KWSYS_PLATFORM_TEST_DEFINES)
SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
-ENDMACRO(KWSYS_PLATFORM_C_TEST)
+ENDMACRO()
MACRO(KWSYS_PLATFORM_C_TEST_RUN var description invert)
SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_C_TEST_DEFINES})
@@ -146,7 +146,7 @@ MACRO(KWSYS_PLATFORM_C_TEST_RUN var description invert)
KWSYS_PLATFORM_TEST_RUN(C "${var}" "${description}" "${invert}")
SET(KWSYS_PLATFORM_TEST_DEFINES)
SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
-ENDMACRO(KWSYS_PLATFORM_C_TEST_RUN)
+ENDMACRO()
MACRO(KWSYS_PLATFORM_CXX_TEST var description invert)
SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_CXX_TEST_DEFINES})
@@ -156,7 +156,7 @@ MACRO(KWSYS_PLATFORM_CXX_TEST var description invert)
SET(KWSYS_PLATFORM_TEST_DEFINES)
SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
SET(KWSYS_PLATFORM_TEST_LINK_LIBRARIES)
-ENDMACRO(KWSYS_PLATFORM_CXX_TEST)
+ENDMACRO()
MACRO(KWSYS_PLATFORM_CXX_TEST_RUN var description invert)
SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_CXX_TEST_DEFINES})
@@ -164,7 +164,7 @@ MACRO(KWSYS_PLATFORM_CXX_TEST_RUN var description invert)
KWSYS_PLATFORM_TEST_RUN(CXX "${var}" "${description}" "${invert}")
SET(KWSYS_PLATFORM_TEST_DEFINES)
SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
-ENDMACRO(KWSYS_PLATFORM_CXX_TEST_RUN)
+ENDMACRO()
#-----------------------------------------------------------------------------
# KWSYS_PLATFORM_INFO_TEST(lang var description)
diff --git a/Source/kwsys/kwsysPlatformTestsCXX.cxx b/Source/kwsys/kwsysPlatformTestsCXX.cxx
index be7a09ee2..fc87f9135 100644
--- a/Source/kwsys/kwsysPlatformTestsCXX.cxx
+++ b/Source/kwsys/kwsysPlatformTestsCXX.cxx
@@ -9,110 +9,11 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-// Setup for tests that use result of stl namespace test.
-#if defined(KWSYS_STL_HAVE_STD)
-# if KWSYS_STL_HAVE_STD
-# define kwsys_stl std
-# else
-# define kwsys_stl
-# endif
-#endif
-
-// Setup for tests that use iostreams.
-#if defined(KWSYS_IOS_USE_ANSI) && defined(KWSYS_IOS_HAVE_STD)
-# if defined(_MSC_VER)
-# pragma warning (push,1)
-# endif
-# if KWSYS_IOS_USE_ANSI
-# include <iostream>
-# else
-# include <iostream.h>
-# endif
-# if defined(_MSC_VER)
-# pragma warning (pop)
-# endif
-# if KWSYS_IOS_HAVE_STD
-# define kwsys_ios std
-# else
-# define kwsys_ios
-# endif
-#endif
-
-#ifdef TEST_KWSYS_STL_HAVE_STD
-#include <list>
-void f(std ::list<int>*) {}
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_IOS_USE_ANSI
-#include <iosfwd>
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_IOS_HAVE_STD
-#include <iosfwd>
-void f(std ::ostream*) {}
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_IOS_USE_SSTREAM
-#include <sstream>
-#if defined(__GNUC__) && __GNUC__ == 2 && __GNUC_MINOR__ == 96
-# error "GCC 2.96 stringstream is buggy"
-#endif
-int main()
-{
- std ::ostringstream ostr;
- ostr << "hello";
- if(ostr.str().size() == 5)
- {
- return 0;
- }
- return -1;
-}
-#endif
-
-#ifdef TEST_KWSYS_IOS_USE_STRSTREAM_H
-#include <strstream.h>
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_IOS_USE_STRSTREA_H
-#include <strstrea.h>
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_STL_STRING_HAVE_OSTREAM
-# include <iostream.h>
-# include <string>
-void f(ostream& os, const kwsys_stl::string& s) { os << s; }
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_STL_STRING_HAVE_ISTREAM
-# include <iostream.h>
-# include <string>
-void f(istream& is, kwsys_stl::string& s) { is >> s; }
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_STL_STRING_HAVE_NEQ_CHAR
-# include <string>
-bool f(const kwsys_stl::string& s) { return s != ""; }
-int main() { return 0; }
-#endif
-
#ifdef TEST_KWSYS_CXX_HAS_CSTDIO
#include <cstdio>
int main() { return 0; }
#endif
-#ifdef TEST_KWSYS_CXX_HAS_CSTDDEF
-#include <cstddef>
-void f(size_t) {}
-int main() { return 0; }
-#endif
-
#ifdef TEST_KWSYS_CXX_HAS_LONG_LONG
long long f(long long n) { return n; }
int main()
@@ -131,159 +32,28 @@ int main()
}
#endif
-#ifdef TEST_KWSYS_CXX_HAS_NULL_TEMPLATE_ARGS
-template <class T> class A;
-template <class T> int f(A<T>&);
-template <class T> class A
-{
-public:
- // "friend int f<>(A<T>&)" would conform
- friend int f(A<T>&);
-private:
- int x;
-};
-
-template <class T> int f(A<T>& a) { return a.x = 0; }
-template int f(A<int>&);
-
-int main()
-{
- A<int> a;
- return f(a);
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_MEMBER_TEMPLATES
-template <class U>
-class A
-{
-public:
- U u;
- A(): u(0) {}
- template <class V> V m(V* p) { return *p = u; }
-};
-
-int main()
-{
- A<short> a;
- int s = 1;
- return a.m(&s);
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_FULL_SPECIALIZATION
-template <class T> struct A {};
-template <> struct A<int*>
-{
- static int f() { return 0; }
-};
-int main() { return A<int*>::f(); }
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP
-namespace N
-{
- class A {};
- int f(A*) { return 0; }
-}
-void f(void*);
-int main()
-{
- N::A* a = 0;
- return f(a);
-}
-#endif
-
-#ifdef TEST_KWSYS_STL_HAS_ITERATOR_TRAITS
-#include <iterator>
-#include <list>
-void f(kwsys_stl::iterator_traits<kwsys_stl::list<int>::iterator>::iterator_category const&) {}
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_STL_HAS_ITERATOR_CATEGORY
-#include <iterator>
-#include <list>
-void f(kwsys_stl::list<int>::iterator x) { kwsys_stl::iterator_category(x); }
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_STL_HAS___ITERATOR_CATEGORY
-#include <iterator>
-#include <list>
-void f(kwsys_stl::list<int>::iterator x) { kwsys_stl::__iterator_category(x); }
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_STL_HAS_ALLOCATOR_TEMPLATE
-#include <memory>
-template <class Alloc>
-void f(const Alloc&)
-{
- typedef typename Alloc::size_type alloc_size_type;
-}
-int main()
-{
- f(kwsys_stl::allocator<char>());
- return 0;
-}
-#endif
-
-#ifdef TEST_KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE
-#include <memory>
-void f(kwsys_stl::allocator::size_type const&) {}
-int main() { return 0; }
-#endif
-
-#ifdef TEST_KWSYS_STL_HAS_ALLOCATOR_REBIND
-#include <memory>
-template <class T, class Alloc>
-void f(const T&, const Alloc&)
-{
- typedef typename Alloc::template rebind<T>::other alloc_type;
-}
-int main()
-{
- f(0, kwsys_stl::allocator<char>());
- return 0;
-}
-#endif
-
-#ifdef TEST_KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT
-#include <memory>
-void f(kwsys_stl::allocator<char> const& a)
-{
- a.max_size(sizeof(int));
-}
-int main()
-{
- f(kwsys_stl::allocator<char>());
- return 0;
-}
-#endif
-
-#ifdef TEST_KWSYS_STL_HAS_ALLOCATOR_OBJECTS
-#include <vector>
-void f(kwsys_stl::vector<int> const& v1)
-{
- kwsys_stl::vector<int>(1, 1, v1.get_allocator());
-}
+#ifdef TEST_KWSYS_CXX_STAT_HAS_ST_MTIM
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
int main()
{
- f(kwsys_stl::vector<int>());
+ struct stat stat1;
+ (void)stat1.st_mtim.tv_sec;
+ (void)stat1.st_mtim.tv_nsec;
return 0;
}
#endif
-#ifdef TEST_KWSYS_STAT_HAS_ST_MTIM
+#ifdef TEST_KWSYS_CXX_STAT_HAS_ST_MTIMESPEC
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main()
{
struct stat stat1;
- (void)stat1.st_mtim.tv_sec;
- (void)stat1.st_mtim.tv_nsec;
+ (void)stat1.st_mtimespec.tv_sec;
+ (void)stat1.st_mtimespec.tv_nsec;
return 0;
}
#endif
@@ -308,86 +78,55 @@ int main()
}
#endif
-#ifdef TEST_KWSYS_CAN_CONVERT_UI64_TO_DOUBLE
-void function(double& l, unsigned __int64 const& r)
-{
- l = static_cast<double>(r);
-}
-
-int main()
-{
- double tTo = 0.0;
- unsigned __int64 tFrom = 0;
- function(tTo, tFrom);
- return 0;
-}
-#endif
-
-#ifdef TEST_KWSYS_IOS_HAVE_BINARY
-int test_binary(int, ...)
-{
- return 0;
-}
-int main()
-{
- return test_binary(1, kwsys_ios::ios::binary);
-}
-#endif
-
#ifdef TEST_KWSYS_IOS_HAS_ISTREAM_LONG_LONG
-int test_istream(kwsys_ios::istream& is, long long& x)
+# include <iostream>
+int test_istream(std::istream& is, long long& x)
{
return (is >> x)? 1:0;
}
int main()
{
long long x = 0;
- return test_istream(kwsys_ios::cin, x);
+ return test_istream(std::cin, x);
}
#endif
#ifdef TEST_KWSYS_IOS_HAS_OSTREAM_LONG_LONG
-int test_ostream(kwsys_ios::ostream& os, long long x)
+# include <iostream>
+int test_ostream(std::ostream& os, long long x)
{
return (os << x)? 1:0;
}
int main()
{
long long x = 0;
- return test_ostream(kwsys_ios::cout, x);
+ return test_ostream(std::cout, x);
}
#endif
#ifdef TEST_KWSYS_IOS_HAS_ISTREAM___INT64
-int test_istream(kwsys_ios::istream& is, __int64& x)
+# include <iostream>
+int test_istream(std::istream& is, __int64& x)
{
return (is >> x)? 1:0;
}
int main()
{
__int64 x = 0;
- return test_istream(kwsys_ios::cin, x);
+ return test_istream(std::cin, x);
}
#endif
#ifdef TEST_KWSYS_IOS_HAS_OSTREAM___INT64
-int test_ostream(kwsys_ios::ostream& os, __int64 x)
+# include <iostream>
+int test_ostream(std::ostream& os, __int64 x)
{
return (os << x)? 1:0;
}
int main()
{
__int64 x = 0;
- return test_ostream(kwsys_ios::cout, x);
-}
-#endif
-
-#ifdef TEST_KWSYS_CHAR_IS_SIGNED
-/* Return 0 for char signed and 1 for char unsigned. */
-int main()
-{
- unsigned char uc = 255;
- return (*reinterpret_cast<char*>(&uc) < 0)?0:1;
+ return test_ostream(std::cout, x);
}
#endif
@@ -452,6 +191,19 @@ int main()
}
#endif
+#ifdef TEST_KWSYS_CXX_HAS_GETLOADAVG
+// Match feature definitions from SystemInformation.cxx
+#if (defined(__GNUC__) || defined(__PGI)) && !defined(_GNU_SOURCE)
+# define _GNU_SOURCE
+#endif
+#include <stdlib.h>
+int main()
+{
+ double loadavg[3] = { 0.0, 0.0, 0.0 };
+ return getloadavg(loadavg, 3);
+}
+#endif
+
#ifdef TEST_KWSYS_CXX_HAS_RLIMIT64
# if defined(KWSYS_HAS_LFS)
# define _LARGEFILE_SOURCE
@@ -548,6 +300,10 @@ int main()
#if (defined(__GNUC__) || defined(__PGI)) && !defined(_GNU_SOURCE)
# define _GNU_SOURCE
#endif
+#if defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5130 \
+ && __linux && __SUNPRO_CC_COMPAT == 'G'
+# include <iostream>
+#endif
#include <cxxabi.h>
int main()
{
@@ -561,93 +317,6 @@ int main()
}
#endif
-#ifdef TEST_KWSYS_CXX_TYPE_INFO
-/* Collect fundamental type information and save it to a CMake script. */
-
-/* Include limits.h to get macros indicating long long and __int64.
- Note that certain compilers need special macros to define these
- macros in limits.h. */
-#if defined(_MSC_VER) && !defined(_MSC_EXTENSIONS)
-# define _MSC_EXTENSIONS
-#endif
-#if defined(__GNUC__) && __GNUC__ < 3
-# define _GNU_SOURCE
-#endif
-#include <limits.h>
-
-#include <stdio.h>
-#include <string.h>
-
-/* Due to shell differences and limitations of ADD_DEFINITIONS the
- KWSYS_CXX_TYPE_INFO_FILE macro will sometimes have double quotes
- and sometimes not. This macro will make sure the value is treated
- as a double-quoted string. */
-#define TO_STRING(x) TO_STRING0(x)
-#define TO_STRING0(x) TO_STRING1(x)
-#define TO_STRING1(x) #x
-
-void f() {}
-
-int main()
-{
- /* Construct the output file name. Some preprocessors will add an
- extra level of double quotes, so strip them. */
- char fbuf[] = TO_STRING(KWSYS_CXX_TYPE_INFO_FILE);
- char* fname = fbuf;
- if(fname[0] == '"')
- {
- ++fname;
- int len = static_cast<int>(strlen(fname));
- if(len > 0 && fname[len-1] == '"')
- {
- fname[len-1] = 0;
- }
- }
-
- /* Try to open the output file. */
- if(FILE* fout = fopen(fname, "w"))
- {
- /* Set the size of standard types. */
- fprintf(fout, "SET(KWSYS_SIZEOF_CHAR %d)\n", static_cast<int>(sizeof(char)));
- fprintf(fout, "SET(KWSYS_SIZEOF_SHORT %d)\n", static_cast<int>(sizeof(short)));
- fprintf(fout, "SET(KWSYS_SIZEOF_INT %d)\n", static_cast<int>(sizeof(int)));
- fprintf(fout, "SET(KWSYS_SIZEOF_LONG %d)\n", static_cast<int>(sizeof(long)));
-
- /* Set the size of some non-standard but common types. */
- /* Check for a limits.h macro for long long to see if the type exists. */
-#if defined(LLONG_MAX) || defined(LONG_LONG_MAX) || defined(LONGLONG_MAX)
- fprintf(fout, "SET(KWSYS_SIZEOF_LONG_LONG %d)\n", static_cast<int>(sizeof(long long)));
-#else
- fprintf(fout, "SET(KWSYS_SIZEOF_LONG_LONG 0) # No long long available.\n");
-#endif
- /* Check for a limits.h macro for __int64 to see if the type exists. */
-#if defined(_I64_MIN)
- fprintf(fout, "SET(KWSYS_SIZEOF___INT64 %d)\n", static_cast<int>(sizeof(__int64)));
-#else
- fprintf(fout, "SET(KWSYS_SIZEOF___INT64 0) # No __int64 available.\n");
-#endif
-
- /* Set the size of some pointer types. */
- fprintf(fout, "SET(KWSYS_SIZEOF_PDATA %d)\n", static_cast<int>(sizeof(void*)));
- fprintf(fout, "SET(KWSYS_SIZEOF_PFUNC %d)\n", static_cast<int>(sizeof(&f)));
-
- /* Set whether the native type "char" is signed or unsigned. */
- unsigned char uc = 255;
- fprintf(fout, "SET(KWSYS_CHAR_IS_SIGNED %d)\n",
- (*reinterpret_cast<char*>(&uc) < 0)?1:0);
-
- fclose(fout);
- return 0;
- }
- else
- {
- fprintf(stderr, "Failed to write fundamental type info to \"%s\".\n",
- fname);
- return 1;
- }
-}
-#endif
-
#ifdef TEST_KWSYS_CXX_HAS_BORLAND_ASM
int main()
{
@@ -674,3 +343,9 @@ int main()
return a;
}
#endif
+
+#ifdef TEST_KWSYS_STL_HAS_WSTRING
+#include <string>
+void f(std ::wstring*) {}
+int main() { return 0; }
+#endif
diff --git a/Source/kwsys/kwsys_cstddef.hxx.in b/Source/kwsys/kwsys_cstddef.hxx.in
deleted file mode 100644
index 925c03084..000000000
--- a/Source/kwsys/kwsys_cstddef.hxx.in
+++ /dev/null
@@ -1,35 +0,0 @@
-/*============================================================================
- KWSys - Kitware System Library
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef @KWSYS_NAMESPACE@_cstddef
-#define @KWSYS_NAMESPACE@_cstddef
-
-#include <@KWSYS_NAMESPACE@/Configure.hxx>
-
-/* Avoid warnings in MSVC standard headers. */
-#ifdef _MSC_VER
-# pragma warning (push, 1)
-# pragma warning (disable: 4702)
-# pragma warning (disable: 4786)
-#endif
-
-/* Include the real header. */
-#if @KWSYS_NAMESPACE@_CXX_HAS_CSTDDEF
-# include <cstddef>
-#else
-# include <stddef.h>
-#endif
-
-#ifdef _MSC_VER
-# pragma warning(pop)
-#endif
-
-#endif
diff --git a/Source/kwsys/kwsys_ios_fstream.h.in b/Source/kwsys/kwsys_ios_fstream.h.in
deleted file mode 100644
index 4b1a8cfcc..000000000
--- a/Source/kwsys/kwsys_ios_fstream.h.in
+++ /dev/null
@@ -1,46 +0,0 @@
-/*============================================================================
- KWSys - Kitware System Library
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef @KWSYS_NAMESPACE@_ios_fstream
-#define @KWSYS_NAMESPACE@_ios_fstream
-
-#include <@KWSYS_NAMESPACE@/Configure.hxx>
-
-#ifdef _MSC_VER
-# pragma warning (push, 1)
-# pragma warning (disable: 4702)
-# pragma warning (disable: 4995) /* Old streams are deprecated. */
-#endif
-
-#if @KWSYS_NAMESPACE@_IOS_USE_ANSI
-# include <fstream>
-#else
-# include <fstream.h>
-#endif
-
-#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::ofstream;
- using @KWSYS_NAMESPACE@_ios_namespace::ifstream;
- using @KWSYS_NAMESPACE@_ios_namespace::ios;
- using @KWSYS_NAMESPACE@_ios_namespace::endl;
- using @KWSYS_NAMESPACE@_ios_namespace::flush;
-}
-#endif
-
-#ifdef _MSC_VER
-# pragma warning(pop)
-#endif
-
-#endif
diff --git a/Source/kwsys/kwsys_ios_iosfwd.h.in b/Source/kwsys/kwsys_ios_iosfwd.h.in
deleted file mode 100644
index f4fafebc2..000000000
--- a/Source/kwsys/kwsys_ios_iosfwd.h.in
+++ /dev/null
@@ -1,49 +0,0 @@
-/*============================================================================
- KWSys - Kitware System Library
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef @KWSYS_NAMESPACE@_ios_iosfwd
-#define @KWSYS_NAMESPACE@_ios_iosfwd
-
-#include <@KWSYS_NAMESPACE@/Configure.hxx>
-
-#ifdef _MSC_VER
-#pragma warning (push, 1)
-#pragma warning (disable: 4702)
-#endif
-
-#if @KWSYS_NAMESPACE@_IOS_USE_ANSI
-# include <iosfwd>
-#else
-class fstream;
-class ifstream;
-class ios;
-class istream;
-class ofstream;
-class ostream;
-#endif
-
-#if !@KWSYS_NAMESPACE@_IOS_USE_SSTREAM
-namespace @KWSYS_NAMESPACE@_ios
-{
- using @KWSYS_NAMESPACE@_ios_namespace::fstream;
- using @KWSYS_NAMESPACE@_ios_namespace::ifstream;
- using @KWSYS_NAMESPACE@_ios_namespace::ios;
- using @KWSYS_NAMESPACE@_ios_namespace::istream;
- using @KWSYS_NAMESPACE@_ios_namespace::ofstream;
- using @KWSYS_NAMESPACE@_ios_namespace::ostream;
-}
-#endif
-
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-#endif
diff --git a/Source/kwsys/kwsys_ios_iostream.h.in b/Source/kwsys/kwsys_ios_iostream.h.in
deleted file mode 100644
index 43fc4d579..000000000
--- a/Source/kwsys/kwsys_ios_iostream.h.in
+++ /dev/null
@@ -1,99 +0,0 @@
-/*============================================================================
- KWSys - Kitware System Library
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef @KWSYS_NAMESPACE@_ios_iostream
-#define @KWSYS_NAMESPACE@_ios_iostream
-
-#include <@KWSYS_NAMESPACE@/Configure.hxx>
-
-#ifdef _MSC_VER
-# pragma warning (push, 1)
-# pragma warning (disable: 4702)
-# pragma warning (disable: 4995) /* Old streams are deprecated. */
-#endif
-
-#if @KWSYS_NAMESPACE@_IOS_USE_ANSI
-# include <iostream>
-#else
-# 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
-{
- typedef int streamsize;
- typedef int streamoff;
- using @KWSYS_NAMESPACE@_ios_namespace::ostream;
- using @KWSYS_NAMESPACE@_ios_namespace::istream;
- using @KWSYS_NAMESPACE@_ios_namespace::ios;
- 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
-
-#ifdef _MSC_VER
-# pragma warning(pop)
-#endif
-
-#endif
diff --git a/Source/kwsys/kwsys_ios_sstream.h.in b/Source/kwsys/kwsys_ios_sstream.h.in
deleted file mode 100644
index 29d250c7a..000000000
--- a/Source/kwsys/kwsys_ios_sstream.h.in
+++ /dev/null
@@ -1,199 +0,0 @@
-/*============================================================================
- KWSys - Kitware System Library
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef @KWSYS_NAMESPACE@_ios_sstream
-#define @KWSYS_NAMESPACE@_ios_sstream
-
-#include <@KWSYS_NAMESPACE@/Configure.hxx>
-
-/* Define this macro temporarily to keep the code readable. */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
-# define kwsys_stl @KWSYS_NAMESPACE@_stl
-#endif
-
-#if @KWSYS_NAMESPACE@_IOS_USE_SSTREAM
-# ifdef _MSC_VER
-# pragma warning (push, 1)
-# pragma warning (disable: 4702)
-# endif
-# include <sstream>
-# ifdef _MSC_VER
-# pragma warning(pop)
-# endif
-#else
-# ifdef _MSC_VER
-# pragma warning (push, 1)
-# pragma warning (disable: 4702)
-# pragma warning (disable: 4995) /* Old streams are deprecated. */
-# endif
-# if @KWSYS_NAMESPACE@_IOS_USE_ANSI
-# include <strstream>
-# elif @KWSYS_NAMESPACE@_IOS_USE_STRSTREAM_H
-# include <strstream.h>
-# elif @KWSYS_NAMESPACE@_IOS_USE_STRSTREA_H
-# include <strstrea.h>
-# endif
-# if @KWSYS_NAMESPACE@_IOS_USE_ANSI
-# include <new> // Need placement operator new.
-# else
-# include <new.h> // Need placement operator new.
-# endif
-# ifdef _MSC_VER
-# pragma warning(pop)
-# endif
-
-// Only have old std strstream classes. Wrap them to look like new
-// ostringstream and istringstream classes.
-
-# include <@KWSYS_NAMESPACE@/stl/string>
-
-namespace @KWSYS_NAMESPACE@_ios
-{
-using @KWSYS_NAMESPACE@_ios_namespace::streambuf;
-using @KWSYS_NAMESPACE@_ios_namespace::ostream;
-using @KWSYS_NAMESPACE@_ios_namespace::istream;
-using @KWSYS_NAMESPACE@_ios_namespace::strstream;
-using @KWSYS_NAMESPACE@_ios_namespace::istrstream;
-using @KWSYS_NAMESPACE@_ios_namespace::ostrstream;
-using @KWSYS_NAMESPACE@_ios_namespace::ios;
-using @KWSYS_NAMESPACE@_ios_namespace::endl;
-using @KWSYS_NAMESPACE@_ios_namespace::ends;
-using @KWSYS_NAMESPACE@_ios_namespace::flush;
-
-class stringstream_cleanup
-{
-public:
- stringstream_cleanup(strstream& str): m_StrStream(str) {}
- ~stringstream_cleanup() { m_StrStream.rdbuf()->freeze(0); }
- static void IgnoreUnusedVariable(const stringstream_cleanup&) {}
-protected:
- strstream& m_StrStream;
-private:
- void operator=(stringstream_cleanup const&);
-};
-
-class stringstream: public strstream
-{
-public:
- typedef strstream Superclass;
- stringstream() {}
- stringstream(const kwsys_stl::string& s) { *this << s.c_str(); }
- kwsys_stl::string str()
- {
- stringstream_cleanup cleanup(*this);
- stringstream_cleanup::IgnoreUnusedVariable(cleanup);
-// Visual Studio 6 has a strstream::pcount, but this is not rdbuf()->pcount()
-#if (@KWSYS_NAMESPACE@_IOS_USE_STRSTREA_H) && defined(_MSC_VER) && (_MSC_VER == 1200)
- int count = this->pcount();
-#elif defined(__WATCOMC__)
- int count = this->rdbuf()->out_waiting();
-#else
- int count = this->rdbuf()->pcount();
-#endif
- const char* ptr = this->Superclass::str();
- return kwsys_stl::string(ptr?ptr:"", count);
- }
- void str(const kwsys_stl::string& s)
- {
- this->~stringstream();
- new (this) stringstream(s);
- }
-private:
- stringstream(const stringstream&);
- void operator=(const stringstream&);
-};
-
-class ostringstream_cleanup
-{
-public:
- ostringstream_cleanup(ostrstream& ostr): m_OStrStream(ostr) {}
- ~ostringstream_cleanup() { m_OStrStream.rdbuf()->freeze(0); }
- static void IgnoreUnusedVariable(const ostringstream_cleanup&) {}
-protected:
- ostrstream& m_OStrStream;
-private:
- void operator=(ostringstream_cleanup const&);
-};
-
-class ostringstream: public ostrstream
-{
-public:
- typedef ostrstream Superclass;
- ostringstream() {}
- ostringstream(const kwsys_stl::string& s) { *this << s.c_str(); }
- kwsys_stl::string str()
- {
- ostringstream_cleanup cleanup(*this);
- ostringstream_cleanup::IgnoreUnusedVariable(cleanup);
- int count = this->pcount();
- const char* ptr = this->Superclass::str();
- return kwsys_stl::string(ptr?ptr:"", count);
- }
- void str(const kwsys_stl::string& s)
- {
- this->~ostringstream();
- new (this) ostringstream(s);
- }
-private:
- ostringstream(const ostringstream&);
- void operator=(const ostringstream&);
-};
-
-#if defined(_MSC_VER)
-# pragma warning (push)
-# pragma warning (disable: 4097) /* typedef-name used as synonym for class */
-#endif
-#if defined(__WATCOMC__)
-// W728: class modifiers for 'A' conflict with class modifiers for 'B'
-# pragma warning 728 10
-#endif
-
-class istringstream: private kwsys_stl::string, public istrstream
-{
-public:
- typedef kwsys_stl::string StdString;
- typedef istrstream IStrStream;
- istringstream(): StdString(),
- IStrStream(const_cast<char*>(StdString::c_str())) {}
- istringstream(const kwsys_stl::string& s):
- StdString(s), IStrStream(const_cast<char*>(StdString::c_str())) {}
- kwsys_stl::string str() const { return *this; }
- void str(const kwsys_stl::string& s)
- {
- this->~istringstream();
- new (this) istringstream(s);
- }
- void clear(int flags)
- {
- this->IStrStream::clear(flags);
- }
-private:
- istringstream(const istringstream&);
- void operator=(const istringstream&);
-};
-
-#if defined(__WATCOMC__)
-# pragma warning 728 9
-#endif
-#if defined(_MSC_VER)
-# pragma warning (pop)
-#endif
-
-} // namespace @KWSYS_NAMESPACE@_ios
-
-#endif
-
-/* Undefine temporary macro. */
-#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
-# undef kwsys_stl
-#endif
-
-#endif
diff --git a/Source/kwsys/kwsys_stl.hxx.in b/Source/kwsys/kwsys_stl.hxx.in
deleted file mode 100644
index 610e6d471..000000000
--- a/Source/kwsys/kwsys_stl.hxx.in
+++ /dev/null
@@ -1,49 +0,0 @@
-/*============================================================================
- KWSys - Kitware System Library
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef @KWSYS_NAMESPACE@_stl_@KWSYS_STL_HEADER@
-#define @KWSYS_NAMESPACE@_stl_@KWSYS_STL_HEADER@
-
-#include <@KWSYS_NAMESPACE@/Configure.hxx>
-
-/* Avoid warnings in MSVC standard headers. */
-#ifdef _MSC_VER
-# pragma warning (push, 1)
-# pragma warning (disable: 4702)
-# pragma warning (disable: 4786)
-#endif
-
-/* The HP standard library defines the functor "times" instead of
- "multiplies" as specified by C++98 20.3.2 for backward
- compatibility with earlier specifications. Defining this macro
- fixes this behavior. The name "times" also conflicts with the
- function declared in sys/times.h on that platform, so we must do
- this as a work-around anyway. */
-#if defined(__HP_aCC) && !defined(__HPACC_USING_MULTIPLIES_IN_FUNCTIONAL)
-# define __HPACC_USING_MULTIPLIES_IN_FUNCTIONAL
-# define @KWSYS_NAMESPACE@_DEFINED___HPACC_USING_MULTIPLIES_IN_FUNCTIONAL
-#endif
-
-/* Include the real header. */
-#include <@KWSYS_STL_HEADER@>
-
-/* Cleanup. */
-#if defined(@KWSYS_NAMESPACE@_DEFINED___HPACC_USING_MULTIPLIES_IN_FUNCTIONAL)
-# undef @KWSYS_NAMESPACE@_DEFINED___HPACC_USING_MULTIPLIES_IN_FUNCTIONAL
-# undef __HPACC_USING_MULTIPLIES_IN_FUNCTIONAL
-#endif
-
-#ifdef _MSC_VER
-# pragma warning(pop)
-#endif
-
-@KWSYS_STL_HEADER_EXTRA@
-#endif
diff --git a/Source/kwsys/kwsys_stl_string.hxx.in b/Source/kwsys/kwsys_stl_string.hxx.in
deleted file mode 100644
index cd312cb8e..000000000
--- a/Source/kwsys/kwsys_stl_string.hxx.in
+++ /dev/null
@@ -1,123 +0,0 @@
-/*============================================================================
- KWSys - Kitware System Library
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-
-// This header is extra code for <@KWSYS_NAMESPACE@/stl/string>.
-#if !defined(@KWSYS_NAMESPACE@_stl_string_including_hxx)
-# error "The header <@KWSYS_NAMESPACE@/stl/string.hxx> may be included only by <@KWSYS_NAMESPACE@/stl/string>."
-#endif
-
-// Provide the istream operator for the stl string if it is not
-// provided by the system or another copy of kwsys. Allow user code
-// to block this definition by defining the macro
-// @KWSYS_NAMESPACE@_STL_STRING_NO_ISTREAM
-// to avoid conflicts with other libraries. User code can test for
-// this definition by checking the macro
-// @KWSYS_NAMESPACE@_STL_STRING_ISTREAM_DEFINED
-#if !@KWSYS_NAMESPACE@_STL_STRING_HAVE_ISTREAM && !defined(@KWSYS_NAMESPACE@_STL_STRING_NO_ISTREAM) && !defined(KWSYS_STL_STRING_ISTREAM_DEFINED)
-# define KWSYS_STL_STRING_ISTREAM_DEFINED
-# define @KWSYS_NAMESPACE@_STL_STRING_ISTREAM_DEFINED
-# include <ctype.h> // isspace
-# include <@KWSYS_NAMESPACE@/ios/iostream>
-# if defined(__WATCOMC__)
-namespace @KWSYS_NAMESPACE@
-{
-struct ios_istream_hack: public kwsys_ios::istream
-{ void eatwhite() { this->@KWSYS_NAMESPACE@_ios::istream::eatwhite(); } };
-}
-# endif
-inline @KWSYS_NAMESPACE@_ios::istream&
-operator>>(@KWSYS_NAMESPACE@_ios::istream& is,
- @KWSYS_NAMESPACE@_stl::string& s)
-{
- // Keep track of the resulting state.
- int state = @KWSYS_NAMESPACE@_ios::ios::goodbit;
-
- // Save the width setting and set it back to zero.
- size_t n = static_cast<size_t>(is.width(0));
-
- // Clear any old contents of the output string.
- s.erase();
-
- // Skip leading whitespace.
-#if defined(__WATCOMC__)
- static_cast<@KWSYS_NAMESPACE@::ios_istream_hack&>(is).eatwhite();
-#else
- is.eatwhite();
-#endif
- @KWSYS_NAMESPACE@_ios::istream& okay = is;
-
- if(okay)
- {
- // Select a maximum possible length.
- if(n == 0 || n >= s.max_size())
- {
- n = s.max_size();
- }
-
- // Read until a space is found or the maximum length is reached.
- bool success = false;
- for(int c = is.peek(); (--n > 0 && c != EOF && !isspace(c)); c = is.peek())
- {
- s += static_cast<char>(c);
- success = true;
- is.ignore();
- }
-
- // Set flags for resulting state.
- if(is.peek() == EOF) { state |= @KWSYS_NAMESPACE@_ios::ios::eofbit; }
- if(!success) { state |= @KWSYS_NAMESPACE@_ios::ios::failbit; }
- }
-
- // Set the final result state.
- is.clear(state);
- return is;
-}
-#endif
-
-// Provide the ostream operator for the stl string if it is not
-// provided by the system or another copy of kwsys. Allow user code
-// to block this definition by defining the macro
-// @KWSYS_NAMESPACE@_STL_STRING_NO_OSTREAM
-// to avoid conflicts with other libraries. User code can test for
-// this definition by checking the macro
-// @KWSYS_NAMESPACE@_STL_STRING_OSTREAM_DEFINED
-#if !@KWSYS_NAMESPACE@_STL_STRING_HAVE_OSTREAM && !defined(@KWSYS_NAMESPACE@_STL_STRING_NO_OSTREAM) && !defined(KWSYS_STL_STRING_OSTREAM_DEFINED)
-# define KWSYS_STL_STRING_OSTREAM_DEFINED
-# define @KWSYS_NAMESPACE@_STL_STRING_OSTREAM_DEFINED
-# include <@KWSYS_NAMESPACE@/ios/iostream>
-inline @KWSYS_NAMESPACE@_ios::ostream&
-operator<<(@KWSYS_NAMESPACE@_ios::ostream& os,
- @KWSYS_NAMESPACE@_stl::string const& s)
-{
- return os << s.c_str();
-}
-#endif
-
-// Provide the operator!= for the stl string and char* if it is not
-// provided by the system or another copy of kwsys. Allow user code
-// to block this definition by defining the macro
-// @KWSYS_NAMESPACE@_STL_STRING_NO_NEQ_CHAR
-// to avoid conflicts with other libraries. User code can test for
-// this definition by checking the macro
-// @KWSYS_NAMESPACE@_STL_STRING_NEQ_CHAR_DEFINED
-#if !@KWSYS_NAMESPACE@_STL_STRING_HAVE_NEQ_CHAR && !defined(@KWSYS_NAMESPACE@_STL_STRING_NO_NEQ_CHAR) && !defined(KWSYS_STL_STRING_NEQ_CHAR_DEFINED)
-# define KWSYS_STL_STRING_NEQ_CHAR_DEFINED
-# define @KWSYS_NAMESPACE@_STL_STRING_NEQ_CHAR_DEFINED
-inline bool operator!=(@KWSYS_NAMESPACE@_stl::string const& s, const char* c)
-{
- return !(s == c);
-}
-inline bool operator!=(const char* c, @KWSYS_NAMESPACE@_stl::string const& s)
-{
- return !(s == c);
-}
-#endif
diff --git a/Source/kwsys/testCommandLineArguments.cxx b/Source/kwsys/testCommandLineArguments.cxx
index 72e65447b..525522dca 100644
--- a/Source/kwsys/testCommandLineArguments.cxx
+++ b/Source/kwsys/testCommandLineArguments.cxx
@@ -11,16 +11,16 @@
============================================================================*/
#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
+#include <iostream>
+#include <vector>
+
#include <stddef.h> /* size_t */
#include <string.h> /* strcmp */
@@ -28,10 +28,10 @@ static void* random_ptr = reinterpret_cast<void*>(0x123);
static int argument(const char* arg, const char* value, void* call_data)
{
- kwsys_ios::cout << "Got argument: \"" << arg << "\" value: \"" << (value?value:"(null)") << "\"" << kwsys_ios::endl;
+ std::cout << "Got argument: \"" << arg << "\" value: \"" << (value?value:"(null)") << "\"" << std::endl;
if ( call_data != random_ptr )
{
- kwsys_ios::cerr << "Problem processing call_data" << kwsys_ios::endl;
+ std::cerr << "Problem processing call_data" << std::endl;
return 0;
}
return 1;
@@ -39,10 +39,10 @@ static int argument(const char* arg, const char* value, void* call_data)
static int unknown_argument(const char* argument, void* call_data)
{
- kwsys_ios::cout << "Got unknown argument: \"" << argument << "\"" << kwsys_ios::endl;
+ std::cout << "Got unknown argument: \"" << argument << "\"" << std::endl;
if ( call_data != random_ptr )
{
- kwsys_ios::cerr << "Problem processing call_data" << kwsys_ios::endl;
+ std::cerr << "Problem processing call_data" << std::endl;
return 0;
}
return 1;
@@ -53,8 +53,8 @@ static bool CompareTwoItemsOnList(int i1, int i2) { return i1 == i2; }
static bool CompareTwoItemsOnList(double i1, double i2) { return i1 == i2; }
static bool CompareTwoItemsOnList(const char* i1,
const char* i2) { return strcmp(i1, i2) == 0; }
-static bool CompareTwoItemsOnList(const kwsys_stl::string& i1,
- const kwsys_stl::string& i2) { return i1 == i2; }
+static bool CompareTwoItemsOnList(const std::string& i1,
+ const std::string& i2) { return i1 == i2; }
int testCommandLineArguments(int argc, char* argv[])
{
@@ -74,26 +74,26 @@ int testCommandLineArguments(int argc, char* argv[])
int some_int_variable = 10;
double some_double_variable = 10.10;
char* some_string_variable = 0;
- kwsys_stl::string some_stl_string_variable = "";
+ std::string some_stl_string_variable = "";
bool some_bool_variable = false;
bool some_bool_variable1 = false;
bool bool_arg1 = false;
int bool_arg2 = 0;
- kwsys_stl::vector<int> numbers_argument;
+ std::vector<int> numbers_argument;
int valid_numbers[] = { 5, 1, 8, 3, 7, 1, 3, 9, 7, 1 };
- kwsys_stl::vector<double> doubles_argument;
+ std::vector<double> doubles_argument;
double valid_doubles[] = { 12.5, 1.31, 22 };
- kwsys_stl::vector<bool> bools_argument;
+ std::vector<bool> bools_argument;
bool valid_bools[] = { true, true, false };
- kwsys_stl::vector<char*> strings_argument;
+ std::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" };
+ std::vector<std::string> stl_strings_argument;
+ std::string valid_stl_strings[] = { "ken", "brad", "bill", "andy" };
typedef kwsys::CommandLineArguments argT;
@@ -122,47 +122,47 @@ int testCommandLineArguments(int argc, char* argv[])
if ( !arg.Parse() )
{
- kwsys_ios::cerr << "Problem parsing arguments" << kwsys_ios::endl;
+ std::cerr << "Problem parsing arguments" << std::endl;
res = 1;
}
- kwsys_ios::cout << "Help: " << arg.GetHelp() << kwsys_ios::endl;
+ std::cout << "Help: " << arg.GetHelp() << std::endl;
- 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;
+ std::cout << "Some int variable was set to: " << some_int_variable << std::endl;
+ std::cout << "Some double variable was set to: " << some_double_variable << std::endl;
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;
+ std::cout << "Some string variable was set to: " << some_string_variable << std::endl;
delete [] some_string_variable;
}
else
{
- kwsys_ios::cerr << "Problem setting string variable" << kwsys_ios::endl;
+ std::cerr << "Problem setting string variable" << std::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; \
+ std::cerr << "Problem setting " #list1 ". Size is: " << list1.size() \
+ << " should be: " << lsize << std::endl; \
res = 1; \
} \
else \
{ \
- kwsys_ios::cout << #list1 " argument set:"; \
+ std::cout << #list1 " argument set:"; \
for ( cc =0; cc < lsize; ++ cc ) \
{ \
- kwsys_ios::cout << " " << list1[cc]; \
+ std::cout << " " << list1[cc]; \
if ( !CompareTwoItemsOnList(list1[cc], list_valid[cc]) ) \
{ \
- kwsys_ios::cerr << "Problem setting " #list1 ". Value of " \
+ std::cerr << "Problem setting " #list1 ". Value of " \
<< cc << " is: [" << list1[cc] << "] <> [" \
- << list_valid[cc] << "]" << kwsys_ios::endl; \
+ << list_valid[cc] << "]" << std::endl; \
res = 1; \
break; \
} \
} \
- kwsys_ios::cout << kwsys_ios::endl; \
+ std::cout << std::endl; \
}
CompareTwoLists(numbers_argument, valid_numbers, 10);
@@ -171,12 +171,12 @@ int testCommandLineArguments(int argc, char* argv[])
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;
+ std::cout << "Some STL String variable was set to: " << some_stl_string_variable << std::endl;
+ std::cout << "Some bool variable was set to: " << some_bool_variable << std::endl;
+ std::cout << "Some bool variable was set to: " << some_bool_variable1 << std::endl;
+ std::cout << "bool_arg1 variable was set to: " << bool_arg1 << std::endl;
+ std::cout << "bool_arg2 variable was set to: " << bool_arg2 << std::endl;
+ std::cout << std::endl;
for ( cc = 0; cc < strings_argument.size(); ++ cc )
{
diff --git a/Source/kwsys/testCommandLineArguments1.cxx b/Source/kwsys/testCommandLineArguments1.cxx
index 0860c2abc..6eb465d81 100644
--- a/Source/kwsys/testCommandLineArguments1.cxx
+++ b/Source/kwsys/testCommandLineArguments1.cxx
@@ -11,16 +11,17 @@
============================================================================*/
#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
+#include <iostream>
+#include <vector>
+
+#include <assert.h> /* assert */
#include <string.h> /* strcmp */
int testCommandLineArguments1(int argc, char* argv[])
@@ -30,7 +31,7 @@ int testCommandLineArguments1(int argc, char* argv[])
int n = 0;
char* m = 0;
- kwsys_stl::string p;
+ std::string p;
int res = 0;
typedef kwsys::CommandLineArguments argT;
@@ -42,27 +43,27 @@ int testCommandLineArguments1(int argc, char* argv[])
if ( !arg.Parse() )
{
- kwsys_ios::cerr << "Problem parsing arguments" << kwsys_ios::endl;
+ std::cerr << "Problem parsing arguments" << std::endl;
res = 1;
}
if ( n != 24 )
{
- kwsys_ios::cout << "Problem setting N. Value of N: " << n << kwsys_ios::endl;
+ std::cout << "Problem setting N. Value of N: " << n << std::endl;
res = 1;
}
if ( !m || strcmp(m, "test value") != 0 )
{
- kwsys_ios::cout << "Problem setting M. Value of M: " << m << kwsys_ios::endl;
+ std::cout << "Problem setting M. Value of M: " << m << std::endl;
res = 1;
}
if ( p != "1" )
{
- kwsys_ios::cout << "Problem setting P. Value of P: " << p.c_str() << kwsys_ios::endl;
+ std::cout << "Problem setting P. Value of P: " << p << std::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;
+ std::cout << "Value of N: " << n << std::endl;
+ std::cout << "Value of M: " << m << std::endl;
+ std::cout << "Value of P: " << p << std::endl;
if ( m )
{
delete [] m;
@@ -78,24 +79,25 @@ int testCommandLineArguments1(int argc, char* argv[])
};
if ( newArgc != 9 )
{
- kwsys_ios::cerr << "Bad number of unused arguments: " << newArgc << kwsys_ios::endl;
+ std::cerr << "Bad number of unused arguments: " << newArgc << std::endl;
res = 1;
}
for ( cc = 0; cc < newArgc; ++ cc )
{
- kwsys_ios::cout << "Unused argument[" << cc << "] = [" << newArgv[cc] << "]"
- << kwsys_ios::endl;
+ assert(newArgv[cc]); /* Quiet Clang scan-build. */
+ std::cout << "Unused argument[" << cc << "] = [" << newArgv[cc] << "]"
+ << std::endl;
if ( cc >= 9 )
{
- kwsys_ios::cerr << "Too many unused arguments: " << cc << kwsys_ios::endl;
+ std::cerr << "Too many unused arguments: " << cc << std::endl;
res = 1;
}
else if ( valid_unused_args[cc] &&
strcmp(valid_unused_args[cc], newArgv[cc]) != 0 )
{
- kwsys_ios::cerr << "Bad unused argument [" << cc << "] \""
+ std::cerr << "Bad unused argument [" << cc << "] \""
<< newArgv[cc] << "\" should be: \"" << valid_unused_args[cc] << "\""
- << kwsys_ios::endl;
+ << std::endl;
res = 1;
}
}
diff --git a/Source/kwsys/testDynamicLoader.cxx b/Source/kwsys/testDynamicLoader.cxx
index dd6d60390..695a134d2 100644
--- a/Source/kwsys/testDynamicLoader.cxx
+++ b/Source/kwsys/testDynamicLoader.cxx
@@ -12,33 +12,28 @@
#include "kwsysPrivate.h"
#include KWSYS_HEADER(DynamicLoader.hxx)
-#include KWSYS_HEADER(ios/iostream)
-#include KWSYS_HEADER(stl/string)
-#if defined(__BEOS__)
+#if defined(__BEOS__) || defined(__HAIKU__)
#include <be/kernel/OS.h> /* disable_debugger() API. */
#endif
-#if defined(__HAIKU__)
-#include <os/kernel/OS.h> /* disable_debugger() API. */
-#endif
-
// Work-around CMake dependency scanning limitation. This must
// duplicate the above list of headers.
#if 0
# include "DynamicLoader.hxx.in"
-# include "kwsys_ios_iostream.h.in"
-# include "kwsys_stl_string.hxx.in"
#endif
+#include <string>
+#include <iostream>
+
// Include with <> instead of "" to avoid getting any in-source copy
// left on disk.
#include <testSystemTools.h>
-static kwsys_stl::string GetLibName(const char* lname)
+static std::string GetLibName(const char* lname)
{
// Construct proper name of lib
- kwsys_stl::string slname;
+ std::string slname;
slname = EXECUTABLE_OUTPUT_PATH;
#ifdef CMAKE_INTDIR
slname += "/";
@@ -60,30 +55,30 @@ static kwsys_stl::string GetLibName(const char* lname)
*/
int TestDynamicLoader(const char* libname, const char* symbol, int r1, int r2, int r3)
{
- kwsys_ios::cerr << "Testing: " << libname << kwsys_ios::endl;
+ std::cerr << "Testing: " << libname << std::endl;
kwsys::DynamicLoader::LibraryHandle l
= kwsys::DynamicLoader::OpenLibrary(libname);
// If result is incompatible with expectation just fails (xor):
if( (r1 && !l) || (!r1 && l) )
{
- kwsys_ios::cerr
- << kwsys::DynamicLoader::LastError() << kwsys_ios::endl;
+ std::cerr
+ << kwsys::DynamicLoader::LastError() << std::endl;
return 1;
}
kwsys::DynamicLoader::SymbolPointer f
= kwsys::DynamicLoader::GetSymbolAddress(l, symbol);
if( (r2 && !f) || (!r2 && f) )
{
- kwsys_ios::cerr
- << kwsys::DynamicLoader::LastError() << kwsys_ios::endl;
+ std::cerr
+ << kwsys::DynamicLoader::LastError() << std::endl;
return 1;
}
#ifndef __APPLE__
int s = kwsys::DynamicLoader::CloseLibrary(l);
if( (r3 && !s) || (!r3 && s) )
{
- kwsys_ios::cerr
- << kwsys::DynamicLoader::LastError() << kwsys_ios::endl;
+ std::cerr
+ << kwsys::DynamicLoader::LastError() << std::endl;
return 1;
}
#else
@@ -112,7 +107,7 @@ int testDynamicLoader(int argc, char *argv[])
// Make sure that inexistent lib is giving correct result
res += TestDynamicLoader("azerty_", "foo_bar",0,0,0);
// Make sure that random binary file cannot be assimilated as dylib
- res += TestDynamicLoader(TEST_SYSTEMTOOLS_BIN_FILE, "wp",0,0,0);
+ res += TestDynamicLoader(TEST_SYSTEMTOOLS_SOURCE_DIR "/testSystemTools.bin", "wp",0,0,0);
#endif
#ifdef __linux__
@@ -122,7 +117,7 @@ int testDynamicLoader(int argc, char *argv[])
res += TestDynamicLoader("libdl.so", "TestDynamicLoader",1,0,1);
#endif
// Now try on the generated library
- kwsys_stl::string libname = GetLibName(KWSYS_NAMESPACE_STRING "TestDynload");
+ std::string libname = GetLibName(KWSYS_NAMESPACE_STRING "TestDynload");
res += TestDynamicLoader(libname.c_str(), "dummy",1,0,1);
res += TestDynamicLoader(libname.c_str(), "TestDynamicLoaderSymbolPointer",1,1,1);
res += TestDynamicLoader(libname.c_str(), "_TestDynamicLoaderSymbolPointer",1,0,1);
diff --git a/Source/kwsys/testEncoding.cxx b/Source/kwsys/testEncoding.cxx
new file mode 100644
index 000000000..842b17dd5
--- /dev/null
+++ b/Source/kwsys/testEncoding.cxx
@@ -0,0 +1,198 @@
+/*============================================================================
+ KWSys - Kitware System Library
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "kwsysPrivate.h"
+
+#if defined(_MSC_VER)
+# pragma warning (disable:4786)
+#endif
+
+#include KWSYS_HEADER(Encoding.hxx)
+#include KWSYS_HEADER(Encoding.h)
+
+#include <iostream>
+#include <locale.h>
+#include <string.h>
+#include <stdlib.h>
+
+// Work-around CMake dependency scanning limitation. This must
+// duplicate the above list of headers.
+#if 0
+# include "Encoding.hxx.in"
+# include "Encoding.h.in"
+#endif
+
+//----------------------------------------------------------------------------
+static const unsigned char helloWorldStrings[][32] =
+{
+ // English
+ {'H','e','l','l','o',' ','W','o','r','l','d',0},
+ // Japanese
+ {0xE3, 0x81, 0x93, 0xE3, 0x82, 0x93, 0xE3, 0x81, 0xAB, 0xE3,
+ 0x81, 0xA1, 0xE3, 0x81, 0xAF, 0xE4, 0xB8, 0x96, 0xE7, 0x95,
+ 0x8C, 0},
+ // Arabic
+ {0xD9, 0x85, 0xD8, 0xB1, 0xD8, 0xAD, 0xD8, 0xA8, 0xD8, 0xA7,
+ 0x20, 0xD8, 0xA7, 0xD9, 0x84, 0xD8, 0xB9, 0xD8, 0xA7, 0xD9,
+ 0x84, 0xD9, 0x85, 0},
+ // Yiddish
+ {0xD7, 0x94, 0xD7, 0xA2, 0xD7, 0x9C, 0xD7, 0x90, 0x20, 0xD7,
+ 0x95, 0xD7, 0x95, 0xD7, 0xA2, 0xD7, 0x9C, 0xD7, 0x98, 0},
+ // Russian
+ {0xD0, 0xBF, 0xD1, 0x80, 0xD0, 0xB8, 0xD0, 0xB2, 0xD0, 0xB5,
+ 0xD1, 0x82, 0x20, 0xD0, 0xBC, 0xD0, 0xB8, 0xD1, 0x80, 0},
+ // Latin
+ {0x4D, 0x75, 0x6E, 0x64, 0x75, 0x73, 0x20, 0x73, 0x61, 0x6C,
+ 0x76, 0x65, 0},
+ // Swahili
+ {0x68, 0x75, 0x6A, 0x61, 0x6D, 0x62, 0x6F, 0x20, 0x44, 0x75,
+ 0x6E, 0x69, 0x61, 0},
+ // Icelandic
+ {0x48, 0x61, 0x6C, 0x6C, 0xC3, 0xB3, 0x20, 0x68, 0x65, 0x69,
+ 0x6D, 0x75, 0x72, 0},
+ {0}
+};
+
+//----------------------------------------------------------------------------
+static int testHelloWorldEncoding()
+{
+ int ret = 0;
+ for(int i=0; helloWorldStrings[i][0] != 0; i++)
+ {
+ std::string str = reinterpret_cast<const char*>(helloWorldStrings[i]);
+ std::cout << str << std::endl;
+ std::wstring wstr = kwsys::Encoding::ToWide(str);
+ std::string str2 = kwsys::Encoding::ToNarrow(wstr);
+ wchar_t* c_wstr = kwsysEncoding_DupToWide(str.c_str());
+ char* c_str2 = kwsysEncoding_DupToNarrow(c_wstr);
+ if(!wstr.empty() && (str != str2 || strcmp(c_str2, str.c_str())))
+ {
+ std::cout << "converted string was different: " << str2 << std::endl;
+ std::cout << "converted string was different: " << c_str2 << std::endl;
+ ret++;
+ }
+ free(c_wstr);
+ free(c_str2);
+ }
+ return ret;
+}
+
+static int testRobustEncoding()
+{
+ // test that the conversion functions handle invalid
+ // unicode correctly/gracefully
+
+ int ret = 0;
+ char cstr[] = {(char)-1, 0};
+ // this conversion could fail
+ std::wstring wstr = kwsys::Encoding::ToWide(cstr);
+
+ wstr = kwsys::Encoding::ToWide(NULL);
+ if(wstr != L"")
+ {
+ const wchar_t* wcstr = wstr.c_str();
+ std::cout << "ToWide(NULL) returned";
+ for(size_t i=0; i<wstr.size(); i++)
+ {
+ std::cout << " " << std::hex << (int)wcstr[i];
+ }
+ std::cout << std::endl;
+ ret++;
+ }
+ wstr = kwsys::Encoding::ToWide("");
+ if(wstr != L"")
+ {
+ const wchar_t* wcstr = wstr.c_str();
+ std::cout << "ToWide(\"\") returned";
+ for(size_t i=0; i<wstr.size(); i++)
+ {
+ std::cout << " " << std::hex << (int)wcstr[i];
+ }
+ std::cout << std::endl;
+ ret++;
+ }
+
+#ifdef WIN32
+ // 16 bit wchar_t - we make an invalid surrogate pair
+ wchar_t cwstr[] = {0xD801, 0xDA00, 0};
+ // this conversion could fail
+ std::string win_str = kwsys::Encoding::ToNarrow(cwstr);
+#endif
+
+ std::string str = kwsys::Encoding::ToNarrow(NULL);
+ if(str != "")
+ {
+ std::cout << "ToNarrow(NULL) returned " << str << std::endl;
+ ret++;
+ }
+
+ str = kwsys::Encoding::ToNarrow(L"");
+ if(wstr != L"")
+ {
+ std::cout << "ToNarrow(\"\") returned " << str << std::endl;
+ ret++;
+ }
+
+ return ret;
+}
+
+static int testCommandLineArguments()
+{
+ int status = 0;
+
+ char const* argv[2] = {
+ "./app.exe",
+ (char const*)helloWorldStrings[1]
+ };
+
+ kwsys::Encoding::CommandLineArguments args(2, argv);
+ kwsys::Encoding::CommandLineArguments arg2 =
+ kwsys::Encoding::CommandLineArguments(args);
+
+ char const* const* u8_argv = args.argv();
+ for(int i=0; i<args.argc(); i++)
+ {
+ char const* u8_arg = u8_argv[i];
+ if(strcmp(argv[i], u8_arg) != 0)
+ {
+ std::cout << "argv[" << i << "] " << argv[i] << " != "
+ << u8_arg << std::endl;
+ status++;
+ }
+ }
+
+ kwsys::Encoding::CommandLineArguments args3 =
+ kwsys::Encoding::CommandLineArguments::Main(2, argv);
+
+ return status;
+}
+
+//----------------------------------------------------------------------------
+int testEncoding(int, char*[])
+{
+ const char* loc = setlocale(LC_ALL, "");
+ if(loc)
+ {
+ std::cout << "Locale: " << loc << std::endl;
+ }
+ else
+ {
+ std::cout << "Locale: None" << std::endl;
+ }
+
+ int ret = 0;
+
+ ret |= testHelloWorldEncoding();
+ ret |= testRobustEncoding();
+ ret |= testCommandLineArguments();
+
+ return ret;
+}
diff --git a/Source/kwsys/testFStream.cxx b/Source/kwsys/testFStream.cxx
new file mode 100644
index 000000000..5e537258f
--- /dev/null
+++ b/Source/kwsys/testFStream.cxx
@@ -0,0 +1,138 @@
+/*============================================================================
+ KWSys - Kitware System Library
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "kwsysPrivate.h"
+
+#if defined(_MSC_VER)
+# pragma warning (disable:4786)
+#endif
+
+#include KWSYS_HEADER(FStream.hxx)
+#include <string.h>
+#ifdef __BORLANDC__
+# include <mem.h> /* memcmp */
+#endif
+
+// Work-around CMake dependency scanning limitation. This must
+// duplicate the above list of headers.
+#if 0
+# include "FStream.hxx.in"
+#endif
+
+#include <iostream>
+
+//----------------------------------------------------------------------------
+static int testNoFile()
+{
+ kwsys::ifstream in_file("NoSuchFile.txt");
+ if(in_file)
+ {
+ return 1;
+ }
+
+ return 0;
+}
+
+static const int num_test_files = 7;
+static const int max_test_file_size = 45;
+
+static kwsys::FStream::BOM expected_bom[num_test_files] =
+{
+ kwsys::FStream::BOM_None,
+ kwsys::FStream::BOM_None,
+ kwsys::FStream::BOM_UTF8,
+ kwsys::FStream::BOM_UTF16LE,
+ kwsys::FStream::BOM_UTF16BE,
+ kwsys::FStream::BOM_UTF32LE,
+ kwsys::FStream::BOM_UTF32BE
+};
+
+static unsigned char expected_bom_data[num_test_files][5] =
+{
+ {0},
+ {0},
+ {3, 0xEF, 0xBB, 0xBF},
+ {2, 0xFF, 0xFE},
+ {2, 0xFE, 0xFF},
+ {4, 0xFF, 0xFE, 0x00, 0x00},
+ {4, 0x00, 0x00, 0xFE, 0xFF},
+};
+
+static unsigned char file_data[num_test_files][max_test_file_size] =
+{
+ {1, 'H'},
+ {11, 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'},
+ {11, 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'},
+ {22, 0x48, 0x00, 0x65, 0x00, 0x6C, 0x00, 0x6C, 0x00, 0x6F, 0x00, 0x20, 0x00,
+ 0x57, 0x00, 0x6F, 0x00, 0x72, 0x00, 0x6C, 0x00, 0x64, 0x00},
+ {22, 0x00, 0x48, 0x00, 0x65, 0x00, 0x6C, 0x00, 0x6C, 0x00, 0x6F, 0x00, 0x20,
+ 0x00, 0x57, 0x00, 0x6F, 0x00, 0x72, 0x00, 0x6C, 0x00, 0x64},
+ {44, 0x48, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00,
+ 0x6C, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+ 0x57, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00,
+ 0x6C, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00},
+ {44, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x6C,
+ 0x00, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x72,
+ 0x00, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x64},
+};
+
+//----------------------------------------------------------------------------
+static int testBOM()
+{
+ // test various encodings in binary mode
+ for(int i=0; i<num_test_files; i++)
+ {
+ {
+ kwsys::ofstream out("bom.txt", kwsys::ofstream::binary);
+ out.write(reinterpret_cast<const char*>(expected_bom_data[i]+1),
+ *expected_bom_data[i]);
+ out.write(reinterpret_cast<const char*>(file_data[i]+1),
+ file_data[i][0]);
+ }
+
+ kwsys::ifstream in("bom.txt", kwsys::ofstream::binary);
+ kwsys::FStream::BOM bom = kwsys::FStream::ReadBOM(in);
+ if(bom != expected_bom[i])
+ {
+ std::cout << "Unexpected BOM " << i << std::endl;
+ return 1;
+ }
+ char data[max_test_file_size];
+ in.read(data, file_data[i][0]);
+ if(!in.good())
+ {
+ std::cout << "Unable to read data " << i << std::endl;
+ return 1;
+ }
+
+ if(memcmp(data, file_data[i]+1, file_data[i][0]) != 0)
+ {
+ std::cout << "Incorrect read data " << i << std::endl;
+ return 1;
+ }
+
+ }
+
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+int testFStream(int, char*[])
+{
+ int ret = 0;
+
+ ret |= testNoFile();
+ ret |= testBOM();
+
+ return ret;
+}
diff --git a/Source/kwsys/testHashSTL.cxx b/Source/kwsys/testHashSTL.cxx
index b861a5b32..ab1f83e78 100644
--- a/Source/kwsys/testHashSTL.cxx
+++ b/Source/kwsys/testHashSTL.cxx
@@ -12,7 +12,6 @@
#include "kwsysPrivate.h"
#include KWSYS_HEADER(hash_map.hxx)
#include KWSYS_HEADER(hash_set.hxx)
-#include KWSYS_HEADER(ios/iostream)
// Work-around CMake dependency scanning limitation. This must
// duplicate the above list of headers.
@@ -20,9 +19,10 @@
# include "hash_map.hxx.in"
# include "hash_set.hxx.in"
# include "hashtable.hxx.in"
-# include "kwsys_ios_iostream.h.in"
#endif
+#include <iostream>
+
#if defined(_MSC_VER)
# pragma warning (disable:4786)
#endif
@@ -34,7 +34,7 @@
template class kwsys::hash_map<const char*, int>;
template class kwsys::hash_set<int>;
-bool test_hash_map()
+static bool test_hash_map()
{
typedef kwsys::hash_map<const char*, int> mtype;
mtype m;
@@ -44,14 +44,14 @@ bool test_hash_map()
int sum = 0;
for(mtype::iterator mi = m.begin(); mi != m.end(); ++mi)
{
- kwsys_ios::cout << "Found entry [" << mi->first << "," << mi->second << "]"
- << kwsys_ios::endl;
+ std::cout << "Found entry [" << mi->first << "," << mi->second << "]"
+ << std::endl;
sum += mi->second;
}
return sum == 3;
}
-bool test_hash_set()
+static bool test_hash_set()
{
typedef kwsys::hash_set<int> stype;
stype s;
@@ -60,7 +60,7 @@ bool test_hash_set()
int sum = 0;
for(stype::iterator si = s.begin(); si != s.end(); ++si)
{
- kwsys_ios::cout << "Found entry [" << *si << "]" << kwsys_ios::endl;
+ std::cout << "Found entry [" << *si << "]" << std::endl;
sum += *si;
}
return sum == 3;
diff --git a/Source/kwsys/testIOS.cxx b/Source/kwsys/testIOS.cxx
index f0c7f1a7b..396a09d47 100644
--- a/Source/kwsys/testIOS.cxx
+++ b/Source/kwsys/testIOS.cxx
@@ -10,158 +10,149 @@
See the License for more information.
============================================================================*/
#include "kwsysPrivate.h"
-#include KWSYS_HEADER(stl/vector)
-#include KWSYS_HEADER(ios/sstream)
-#include KWSYS_HEADER(ios/fstream)
-#include KWSYS_HEADER(ios/iostream)
-
-// Work-around CMake dependency scanning limitation. This must
-// duplicate the above list of headers.
-#if 0
-# include "kwsys_stl_string.hxx.in"
-# include "kwsys_stl_vector.h.in"
-# include "kwsys_ios_sstream.h.in"
-# include "kwsys_ios_fstream.h.in"
-# include "kwsys_ios_iostream.h.in"
-#endif
+#include KWSYS_HEADER(Configure.hxx)
+#include <sstream>
+#include <fstream>
+#include <iostream>
+#include <vector>
#include <string.h> /* strlen */
int testIOS(int, char*[])
{
- kwsys_ios::ostringstream ostr;
+ std::ostringstream ostr;
const char hello[] = "hello";
ostr << hello;
if(ostr.str() != hello)
{
- kwsys_ios::cerr << "failed to write hello to ostr" << kwsys_ios::endl;
+ std::cerr << "failed to write hello to ostr" << std::endl;
return 1;
}
const char world[] = "world";
- kwsys_ios::ostringstream ostr2;
+ std::ostringstream ostr2;
ostr2.write( hello, strlen(hello) ); /* I could do sizeof */
ostr2.put( '\0' );
ostr2.write( world, strlen(world) );
if(ostr2.str().size() != strlen(hello) + 1 + strlen(world) )
{
- kwsys_ios::cerr << "failed to write hello to ostr2" << kwsys_ios::endl;
+ std::cerr << "failed to write hello to ostr2" << std::endl;
return 1;
}
static const unsigned char array[] = { 0xff,0x4f,0xff,0x51,0x00,0x29,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x07,0x01,0x01,0xff,0x52,0x00,0x0c,0x00,0x00,0x00,0x01,0x00,0x05,0x04,0x04,0x00,0x01,0xff,0x5c,0x00,0x13,0x40,0x40,0x48,0x48,0x50,0x48,0x48,0x50,0x48,0x48,0x50,0x48,0x48,0x50,0x48,0x48,0x50,0xff,0x64,0x00,0x2c,0x00,0x00,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x62,0x79,0x20,0x49,0x54,0x4b,0x2f,0x47,0x44,0x43,0x4d,0x2f,0x4f,0x70,0x65,0x6e,0x4a,0x50,0x45,0x47,0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x31,0x2e,0x30,0xff,0x90,0x00,0x0a,0x00,0x00,0x00,0x00,0x06,0x2c,0x00,0x01,0xff,0x93,0xcf,0xb0,0x18,0x08,0x7f,0xc6,0x99,0xbf,0xff,0xc0,0xf8,0xc1,0xc1,0xf3,0x05,0x81,0xf2,0x83,0x0a,0xa5,0xff,0x10,0x90,0xbf,0x2f,0xff,0x04,0xa8,0x7f,0xc0,0xf8,0xc4,0xc1,0xf3,0x09,0x81,0xf3,0x0c,0x19,0x34 };
const size_t narray = sizeof(array); // 180
- kwsys_ios::stringstream strstr;
+ std::stringstream strstr;
strstr.write( (char*)array, narray );
//strstr.seekp( narray / 2 ); // set position of put pointer in mid string
if(strstr.str().size() != narray )
{
- kwsys_ios::cerr << "failed to write array to strstr" << kwsys_ios::endl;
+ std::cerr << "failed to write array to strstr" << std::endl;
return 1;
}
- kwsys_ios::istringstream istr(" 10 20 str ");
- kwsys_stl::string s;
+ std::istringstream istr(" 10 20 str ");
+ std::string s;
int x;
if(istr >> x)
{
if(x != 10)
{
- kwsys_ios::cerr << "x != 10" << kwsys_ios::endl;
+ std::cerr << "x != 10" << std::endl;
return 1;
}
}
else
{
- kwsys_ios::cerr << "Failed to read 10 from istr" << kwsys_ios::endl;
+ std::cerr << "Failed to read 10 from istr" << std::endl;
return 1;
}
if(istr >> x)
{
if(x != 20)
{
- kwsys_ios::cerr << "x != 20" << kwsys_ios::endl;
+ std::cerr << "x != 20" << std::endl;
return 1;
}
}
else
{
- kwsys_ios::cerr << "Failed to read 20 from istr" << kwsys_ios::endl;
+ std::cerr << "Failed to read 20 from istr" << std::endl;
return 1;
}
if(istr >> s)
{
if(s != "str")
{
- kwsys_ios::cerr << "s != \"str\"" << kwsys_ios::endl;
+ std::cerr << "s != \"str\"" << std::endl;
return 1;
}
}
else
{
- kwsys_ios::cerr << "Failed to read str from istr" << kwsys_ios::endl;
+ std::cerr << "Failed to read str from istr" << std::endl;
return 1;
}
if(istr >> s)
{
- kwsys_ios::cerr << "Able to read past end of stream" << kwsys_ios::endl;
+ std::cerr << "Able to read past end of stream" << std::endl;
return 1;
}
else
{
// Clear the failure.
- istr.clear(istr.rdstate() & ~kwsys_ios::ios::eofbit);
- istr.clear(istr.rdstate() & ~kwsys_ios::ios::failbit);
+ istr.clear(istr.rdstate() & ~std::ios::eofbit);
+ istr.clear(istr.rdstate() & ~std::ios::failbit);
}
istr.str("30");
if(istr >> x)
{
if(x != 30)
{
- kwsys_ios::cerr << "x != 30" << kwsys_ios::endl;
+ std::cerr << "x != 30" << std::endl;
return 1;
}
}
else
{
- kwsys_ios::cerr << "Failed to read 30 from istr" << kwsys_ios::endl;
+ std::cerr << "Failed to read 30 from istr" << std::endl;
return 1;
}
- kwsys_ios::stringstream sstr;
+ std::stringstream sstr;
sstr << "40 str2";
if(sstr >> x)
{
if(x != 40)
{
- kwsys_ios::cerr << "x != 40" << kwsys_ios::endl;
+ std::cerr << "x != 40" << std::endl;
return 1;
}
}
else
{
- kwsys_ios::cerr << "Failed to read 40 from sstr" << kwsys_ios::endl;
+ std::cerr << "Failed to read 40 from sstr" << std::endl;
return 1;
}
if(sstr >> s)
{
if(s != "str2")
{
- kwsys_ios::cerr << "s != \"str2\"" << kwsys_ios::endl;
+ std::cerr << "s != \"str2\"" << std::endl;
return 1;
}
}
else
{
- kwsys_ios::cerr << "Failed to read str2 from sstr" << kwsys_ios::endl;
+ std::cerr << "Failed to read str2 from sstr" << std::endl;
return 1;
}
// Just try to compile this.
if(x == 12345)
{
- kwsys_ios::ifstream fin("/does_not_exist",
- kwsys_ios::ios::in | kwsys_ios_binary);
+ std::ifstream fin("/does_not_exist",
+ std::ios::in | std::ios::binary);
}
- kwsys_ios::cout << "IOS tests passed" << kwsys_ios::endl;
+ std::cout << "IOS tests passed" << std::endl;
return 0;
}
diff --git a/Source/kwsys/testProcess.c b/Source/kwsys/testProcess.c
index 6d5eb71fd..8fd3382e9 100644
--- a/Source/kwsys/testProcess.c
+++ b/Source/kwsys/testProcess.c
@@ -11,13 +11,17 @@
============================================================================*/
#include "kwsysPrivate.h"
#include KWSYS_HEADER(Process.h)
+#include KWSYS_HEADER(Encoding.h)
/* Work-around CMake dependency scanning limitation. This must
duplicate the above list of headers. */
#if 0
# include "Process.h.in"
+# include "Encoding.h.in"
#endif
+#include <assert.h>
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -26,29 +30,61 @@
# include <windows.h>
#else
# include <unistd.h>
+# include <signal.h>
#endif
#if defined(__BORLANDC__)
# pragma warn -8060 /* possibly incorrect assignment */
#endif
+/* Platform-specific sleep functions. */
+
#if defined(__BEOS__) && !defined(__ZETA__)
/* BeOS 5 doesn't have usleep(), but it has snooze(), which is identical. */
# include <be/kernel/OS.h>
-static inline void testProcess_usleep(unsigned int msec)
+static inline void testProcess_usleep(unsigned int usec)
+{
+ snooze(usec);
+}
+#elif defined(_WIN32)
+/* Windows can only sleep in millisecond intervals. */
+static void testProcess_usleep(unsigned int usec)
{
- snooze(msec);
+ Sleep(usec / 1000);
}
#else
# define testProcess_usleep usleep
#endif
+#if defined(_WIN32)
+static void testProcess_sleep(unsigned int sec)
+{
+ Sleep(sec*1000);
+}
+#else
+static void testProcess_sleep(unsigned int sec)
+{
+ sleep(sec);
+}
+#endif
+
int runChild(const char* cmd[], int state, int exception, int value,
int share, int output, int delay, double timeout, int poll,
- int repeat, int disown);
+ int repeat, int disown, int createNewGroup,
+ unsigned int interruptDelay);
static int test1(int argc, const char* argv[])
{
+ /* This is a very basic functional test of kwsysProcess. It is repeated
+ numerous times to verify that there are no resource leaks in kwsysProcess
+ that eventually lead to an error. Many versions of OS X will fail after
+ 256 leaked file handles, so 257 iterations seems to be a good test. On
+ the other hand, too many iterations will cause the test to time out -
+ especially if the test is instrumented with e.g. valgrind.
+
+ If you have problems with this test timing out on your system, or want to
+ run more than 257 iterations, you can change the number of iterations by
+ setting the KWSYS_TEST_PROCESS_1_COUNT environment variable. */
(void)argc; (void)argv;
fprintf(stdout, "Output on stdout from test returning 0.\n");
fprintf(stderr, "Output on stderr from test returning 0.\n");
@@ -70,11 +106,7 @@ static int test3(int argc, const char* argv[])
fprintf(stderr, "Output before sleep on stderr from timeout test.\n");
fflush(stdout);
fflush(stderr);
-#if defined(_WIN32)
- Sleep(15000);
-#else
- sleep(15);
-#endif
+ testProcess_sleep(15);
fprintf(stdout, "Output after sleep on stdout from timeout test.\n");
fprintf(stderr, "Output after sleep on stderr from timeout test.\n");
return 0;
@@ -99,9 +131,10 @@ static int test4(int argc, const char* argv[])
#endif
(void)argc; (void)argv;
fprintf(stdout, "Output before crash on stdout from crash test.\n");
- fprintf(stderr, "Output before crash on stderr from crash test.\n");
+ fprintf(stderr, "Output before crash on stderr from crash test.\n");
fflush(stdout);
fflush(stderr);
+ assert(invalidAddress); /* Quiet Clang scan-build. */
/* Provoke deliberate crash by writing to the invalid address. */
*invalidAddress = 0;
fprintf(stdout, "Output after crash on stdout from crash test.\n");
@@ -123,7 +156,7 @@ static int test5(int argc, const char* argv[])
fflush(stdout);
fflush(stderr);
r = runChild(cmd, kwsysProcess_State_Exception,
- kwsysProcess_Exception_Fault, 1, 1, 1, 0, 15, 0, 1, 0);
+ kwsysProcess_Exception_Fault, 1, 1, 1, 0, 15, 0, 1, 0, 0, 0);
fprintf(stdout, "Output on stdout after recursive test.\n");
fprintf(stderr, "Output on stderr after recursive test.\n");
fflush(stdout);
@@ -164,11 +197,7 @@ static int test7(int argc, const char* argv[])
fflush(stdout);
fflush(stderr);
/* Sleep for 1 second. */
-#if defined(_WIN32)
- Sleep(1000);
-#else
- sleep(1);
-#endif
+ testProcess_sleep(1);
fprintf(stdout, "Output on stdout after sleep.\n");
fprintf(stderr, "Output on stderr after sleep.\n");
fflush(stdout);
@@ -192,7 +221,7 @@ static int test8(int argc, const char* argv[])
fflush(stdout);
fflush(stderr);
r = runChild(cmd, kwsysProcess_State_Disowned, kwsysProcess_Exception_None,
- 1, 1, 1, 0, 10, 0, 1, 1);
+ 1, 1, 1, 0, 10, 0, 1, 1, 0, 0);
fprintf(stdout, "Output on stdout after grandchild test.\n");
fprintf(stderr, "Output on stderr after grandchild test.\n");
fflush(stdout);
@@ -213,18 +242,137 @@ static int test8_grandchild(int argc, const char* argv[])
implemented. */
fclose(stdout);
fclose(stderr);
+ testProcess_sleep(15);
+ return 0;
+}
+
+static int test9(int argc, const char* argv[])
+{
+ /* Test Ctrl+C behavior: the root test program will send a Ctrl+C to this
+ process. Here, we start a child process that sleeps for a long time
+ while ignoring signals. The test is successful if this process waits
+ for the child to return before exiting from the Ctrl+C handler.
+
+ WARNING: This test will falsely pass if the share parameter of runChild
+ was set to 0 when invoking the test9 process. */
+ int r;
+ const char* cmd[4];
+ (void)argc;
+ cmd[0] = argv[0];
+ cmd[1] = "run";
+ cmd[2] = "109";
+ cmd[3] = 0;
+ fprintf(stdout, "Output on stdout before grandchild test.\n");
+ fprintf(stderr, "Output on stderr before grandchild test.\n");
+ fflush(stdout);
+ fflush(stderr);
+ r = runChild(cmd, kwsysProcess_State_Exited,
+ kwsysProcess_Exception_None,
+ 0, 1, 1, 0, 30, 0, 1, 0, 0, 0);
+ /* This sleep will avoid a race condition between this function exiting
+ normally and our Ctrl+C handler exiting abnormally after the process
+ exits. */
+ testProcess_sleep(1);
+ fprintf(stdout, "Output on stdout after grandchild test.\n");
+ fprintf(stderr, "Output on stderr after grandchild test.\n");
+ fflush(stdout);
+ fflush(stderr);
+ return r;
+}
+
#if defined(_WIN32)
- Sleep(15000);
+static BOOL WINAPI test9_grandchild_handler(DWORD dwCtrlType)
+{
+ /* Ignore all Ctrl+C/Break signals. We must use an actual handler function
+ instead of using SetConsoleCtrlHandler(NULL, TRUE) so that we can also
+ ignore Ctrl+Break in addition to Ctrl+C. */
+ (void)dwCtrlType;
+ return TRUE;
+}
+#endif
+
+static int test9_grandchild(int argc, const char* argv[])
+{
+ /* The grandchild just sleeps for a few seconds while ignoring signals. */
+ (void)argc; (void)argv;
+#if defined(_WIN32)
+ if(!SetConsoleCtrlHandler(test9_grandchild_handler, TRUE))
+ {
+ return 1;
+ }
#else
- sleep(15);
+ struct sigaction sa;
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = SIG_IGN;
+ sigemptyset(&sa.sa_mask);
+ if(sigaction(SIGINT, &sa, 0) < 0)
+ {
+ return 1;
+ }
#endif
+ fprintf(stdout, "Output on stdout from grandchild before sleep.\n");
+ fprintf(stderr, "Output on stderr from grandchild before sleep.\n");
+ fflush(stdout);
+ fflush(stderr);
+ /* Sleep for 9 seconds. */
+ testProcess_sleep(9);
+ fprintf(stdout, "Output on stdout from grandchild after sleep.\n");
+ fprintf(stderr, "Output on stderr from grandchild after sleep.\n");
+ fflush(stdout);
+ fflush(stderr);
+ return 0;
+}
+
+static int test10(int argc, const char* argv[])
+{
+ /* Test Ctrl+C behavior: the root test program will send a Ctrl+C to this
+ process. Here, we start a child process that sleeps for a long time and
+ processes signals normally. However, this grandchild is created in a new
+ process group - ensuring that Ctrl+C we receive is sent to our process
+ groups. We make sure it exits anyway. */
+ int r;
+ const char* cmd[4];
+ (void)argc;
+ cmd[0] = argv[0];
+ cmd[1] = "run";
+ cmd[2] = "110";
+ cmd[3] = 0;
+ fprintf(stdout, "Output on stdout before grandchild test.\n");
+ fprintf(stderr, "Output on stderr before grandchild test.\n");
+ fflush(stdout);
+ fflush(stderr);
+ r = runChild(cmd, kwsysProcess_State_Exception,
+ kwsysProcess_Exception_Interrupt,
+ 0, 1, 1, 0, 30, 0, 1, 0, 1, 0);
+ fprintf(stdout, "Output on stdout after grandchild test.\n");
+ fprintf(stderr, "Output on stderr after grandchild test.\n");
+ fflush(stdout);
+ fflush(stderr);
+ return r;
+}
+
+static int test10_grandchild(int argc, const char* argv[])
+{
+ /* The grandchild just sleeps for a few seconds and handles signals. */
+ (void)argc; (void)argv;
+ fprintf(stdout, "Output on stdout from grandchild before sleep.\n");
+ fprintf(stderr, "Output on stderr from grandchild before sleep.\n");
+ fflush(stdout);
+ fflush(stderr);
+ /* Sleep for 6 seconds. */
+ testProcess_sleep(6);
+ fprintf(stdout, "Output on stdout from grandchild after sleep.\n");
+ fprintf(stderr, "Output on stderr from grandchild after sleep.\n");
+ fflush(stdout);
+ fflush(stderr);
return 0;
}
static int runChild2(kwsysProcess* kp,
const char* cmd[], int state, int exception, int value,
int share, int output, int delay, double timeout,
- int poll, int disown)
+ int poll, int disown, int createNewGroup,
+ unsigned int interruptDelay)
{
int result = 0;
char* data = 0;
@@ -245,6 +393,10 @@ static int runChild2(kwsysProcess* kp,
{
kwsysProcess_SetOption(kp, kwsysProcess_Option_Detach, 1);
}
+ if(createNewGroup)
+ {
+ kwsysProcess_SetOption(kp, kwsysProcess_Option_CreateProcessGroup, 1);
+ }
kwsysProcess_Execute(kp);
if(poll)
@@ -252,6 +404,12 @@ static int runChild2(kwsysProcess* kp,
pUserTimeout = &userTimeout;
}
+ if(interruptDelay)
+ {
+ testProcess_sleep(interruptDelay);
+ kwsysProcess_Interrupt(kp);
+ }
+
if(!share && !disown)
{
int p;
@@ -282,17 +440,13 @@ static int runChild2(kwsysProcess* kp,
if(poll)
{
/* Delay to avoid busy loop during polling. */
-#if defined(_WIN32)
- Sleep(100);
-#else
testProcess_usleep(100000);
-#endif
}
if(delay)
{
/* Purposely sleeping only on Win32 to let pipe fill up. */
#if defined(_WIN32)
- Sleep(100);
+ testProcess_usleep(100000);
#endif
}
}
@@ -333,7 +487,7 @@ static int runChild2(kwsysProcess* kp,
printf("Error in administrating child process: [%s]\n",
kwsysProcess_GetErrorString(kp)); break;
};
-
+
if(result)
{
if(exception != kwsysProcess_GetExitException(kp))
@@ -349,7 +503,7 @@ static int runChild2(kwsysProcess* kp,
value, kwsysProcess_GetExitValue(kp));
}
}
-
+
if(kwsysProcess_GetState(kp) != state)
{
fprintf(stderr, "Mismatch in state. "
@@ -370,9 +524,37 @@ static int runChild2(kwsysProcess* kp,
return result;
}
+/**
+ * Runs a child process and blocks until it returns. Arguments as follows:
+ *
+ * cmd = Command line to run.
+ * state = Expected return value of kwsysProcess_GetState after exit.
+ * exception = Expected return value of kwsysProcess_GetExitException.
+ * value = Expected return value of kwsysProcess_GetExitValue.
+ * share = Whether to share stdout/stderr child pipes with our pipes
+ * by way of kwsysProcess_SetPipeShared. If false, new pipes
+ * are created.
+ * output = If !share && !disown, whether to write the child's stdout
+ * and stderr output to our stdout.
+ * delay = If !share && !disown, adds an additional short delay to
+ * the pipe loop to allow the pipes to fill up; Windows only.
+ * timeout = Non-zero to sets a timeout in seconds via
+ * kwsysProcess_SetTimeout.
+ * poll = If !share && !disown, we count the number of 0.1 second
+ * intervals where the child pipes had no new data. We fail
+ * if not in the bounds of MINPOLL/MAXPOLL.
+ * repeat = Number of times to run the process.
+ * disown = If set, the process is disowned.
+ * createNewGroup = If set, the process is created in a new process group.
+ * interruptDelay = If non-zero, number of seconds to delay before
+ * interrupting the process. Note that this delay will occur
+ * BEFORE any reading/polling of pipes occurs and before any
+ * detachment occurs.
+ */
int runChild(const char* cmd[], int state, int exception, int value,
int share, int output, int delay, double timeout,
- int poll, int repeat, int disown)
+ int poll, int repeat, int disown, int createNewGroup,
+ unsigned int interruptDelay)
{
int result = 1;
kwsysProcess* kp = kwsysProcess_New();
@@ -384,7 +566,12 @@ int runChild(const char* cmd[], int state, int exception, int value,
while(repeat-- > 0)
{
result = runChild2(kp, cmd, state, exception, value, share,
- output, delay, timeout, poll, disown);
+ output, delay, timeout, poll, disown, createNewGroup,
+ interruptDelay);
+ if(result)
+ {
+ break;
+ }
}
kwsysProcess_Delete(kp);
return result;
@@ -393,6 +580,19 @@ int runChild(const char* cmd[], int state, int exception, int value,
int main(int argc, const char* argv[])
{
int n = 0;
+
+#ifdef _WIN32
+ int i;
+ char new_args[10][_MAX_PATH];
+ LPWSTR* w_av = CommandLineToArgvW(GetCommandLineW(), &argc);
+ for(i=0; i<argc; i++)
+ {
+ kwsysEncoding_wcstombs(new_args[i], w_av[i], _MAX_PATH);
+ argv[i] = new_args[i];
+ }
+ LocalFree(w_av);
+#endif
+
#if 0
{
HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
@@ -418,7 +618,7 @@ int main(int argc, const char* argv[])
n = atoi(argv[2]);
}
/* Check arguments. */
- if(((n >= 1 && n <= 8) || n == 108) && argc == 3)
+ if(((n >= 1 && n <= 10) || n == 108 || n == 109 || n == 110) && argc == 3)
{
/* This is the child process for a requested test number. */
switch (n)
@@ -431,15 +631,19 @@ int main(int argc, const char* argv[])
case 6: test6(argc, argv); return 0;
case 7: return test7(argc, argv);
case 8: return test8(argc, argv);
+ case 9: return test9(argc, argv);
+ case 10: return test10(argc, argv);
case 108: return test8_grandchild(argc, argv);
+ case 109: return test9_grandchild(argc, argv);
+ case 110: return test10_grandchild(argc, argv);
}
fprintf(stderr, "Invalid test number %d.\n", n);
return 1;
}
- else if(n >= 1 && n <= 8)
+ else if(n >= 1 && n <= 10)
{
/* This is the parent process for a requested test number. */
- int states[8] =
+ int states[10] =
{
kwsysProcess_State_Exited,
kwsysProcess_State_Exited,
@@ -448,9 +652,11 @@ int main(int argc, const char* argv[])
kwsysProcess_State_Exited,
kwsysProcess_State_Expired,
kwsysProcess_State_Exited,
- kwsysProcess_State_Exited
+ kwsysProcess_State_Exited,
+ kwsysProcess_State_Expired, /* Ctrl+C handler test */
+ kwsysProcess_State_Exception /* Process group test */
};
- int exceptions[8] =
+ int exceptions[10] =
{
kwsysProcess_Exception_None,
kwsysProcess_Exception_None,
@@ -459,18 +665,34 @@ int main(int argc, const char* argv[])
kwsysProcess_Exception_None,
kwsysProcess_Exception_None,
kwsysProcess_Exception_None,
- kwsysProcess_Exception_None
+ kwsysProcess_Exception_None,
+ kwsysProcess_Exception_None,
+ kwsysProcess_Exception_Interrupt
};
- int values[8] = {0, 123, 1, 1, 0, 0, 0, 0};
- int outputs[8] = {1, 1, 1, 1, 1, 0, 1, 1};
- int delays[8] = {0, 0, 0, 0, 0, 1, 0, 0};
- double timeouts[8] = {10, 10, 10, 30, 30, 10, -1, 10};
- int polls[8] = {0, 0, 0, 0, 0, 0, 1, 0};
- int repeat[8] = {2, 1, 1, 1, 1, 1, 1, 1};
+ int values[10] = {0, 123, 1, 1, 0, 0, 0, 0, 1, 1};
+ int shares[10] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1};
+ int outputs[10] = {1, 1, 1, 1, 1, 0, 1, 1, 1, 1};
+ int delays[10] = {0, 0, 0, 0, 0, 1, 0, 0, 0, 0};
+ double timeouts[10] = {10, 10, 10, 30, 30, 10, -1, 10, 6, 4};
+ int polls[10] = {0, 0, 0, 0, 0, 0, 1, 0, 0, 0};
+ int repeat[10] = {257, 1, 1, 1, 1, 1, 1, 1, 1, 1};
+ int createNewGroups[10] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1};
+ unsigned int interruptDelays[10] = {0, 0, 0, 0, 0, 0, 0, 0, 3, 2};
int r;
const char* cmd[4];
#ifdef _WIN32
char* argv0 = 0;
+#endif
+ char* test1IterationsStr = getenv("KWSYS_TEST_PROCESS_1_COUNT");
+ if(test1IterationsStr)
+ {
+ long int test1Iterations = strtol(test1IterationsStr, 0, 10);
+ if(test1Iterations > 10 && test1Iterations != LONG_MAX)
+ {
+ repeat[0] = (int)test1Iterations;
+ }
+ }
+#ifdef _WIN32
if(n == 0 && (argv0 = strdup(argv[0])))
{
/* Try converting to forward slashes to see if it works. */
@@ -498,9 +720,10 @@ int main(int argc, const char* argv[])
fprintf(stderr, "Output on stderr before test %d.\n", n);
fflush(stdout);
fflush(stderr);
- r = runChild(cmd, states[n-1], exceptions[n-1], values[n-1], 0,
+ r = runChild(cmd, states[n-1], exceptions[n-1], values[n-1], shares[n-1],
outputs[n-1], delays[n-1], timeouts[n-1],
- polls[n-1], repeat[n-1], 0);
+ polls[n-1], repeat[n-1], 0, createNewGroups[n-1],
+ interruptDelays[n-1]);
fprintf(stdout, "Output on stdout after test %d.\n", n);
fprintf(stderr, "Output on stderr after test %d.\n", n);
fflush(stdout);
@@ -519,7 +742,8 @@ int main(int argc, const char* argv[])
int exception = kwsysProcess_Exception_None;
int value = 0;
double timeout = 0;
- int r = runChild(cmd, state, exception, value, 0, 1, 0, timeout, 0, 1, 0);
+ int r = runChild(cmd, state, exception, value, 0, 1, 0, timeout,
+ 0, 1, 0, 0, 0);
return r;
}
else
diff --git a/Source/kwsys/testSystemInformation.cxx b/Source/kwsys/testSystemInformation.cxx
index 53d51ac40..c96751ab4 100644
--- a/Source/kwsys/testSystemInformation.cxx
+++ b/Source/kwsys/testSystemInformation.cxx
@@ -11,15 +11,15 @@
============================================================================*/
#include "kwsysPrivate.h"
#include KWSYS_HEADER(SystemInformation.hxx)
-#include KWSYS_HEADER(ios/iostream)
// Work-around CMake dependency scanning limitation. This must
// duplicate the above list of headers.
#if 0
# include "SystemInformation.hxx.in"
-# include "kwsys_ios_iostream.h.in"
#endif
+#include <iostream>
+
#if defined(KWSYS_USE_LONG_LONG)
# if defined(KWSYS_IOS_HAS_OSTREAM_LONG_LONG)
# define iostreamLongLong(x) (x)
@@ -36,18 +36,18 @@
# error "No Long Long"
#endif
-#define printMethod(info, m) kwsys_ios::cout << #m << ": " \
+#define printMethod(info, m) std::cout << #m << ": " \
<< info.m() << "\n"
-#define printMethod2(info, m, unit) kwsys_ios::cout << #m << ": " \
+#define printMethod2(info, m, unit) std::cout << #m << ": " \
<< info.m() << " " << unit << "\n"
-#define printMethod3(info, m, unit) kwsys_ios::cout << #m << ": " \
+#define printMethod3(info, m, unit) std::cout << #m << ": " \
<< iostreamLongLong(info.m) << " " << unit << "\n"
int testSystemInformation(int, char*[])
{
- kwsys_ios::cout << "CTEST_FULL_OUTPUT\n"; // avoid truncation
+ std::cout << "CTEST_FULL_OUTPUT\n"; // avoid truncation
kwsys::SystemInformation info;
info.RunCPUCheck();
@@ -87,21 +87,22 @@ int testSystemInformation(int, char*[])
printMethod3(info, GetProcMemoryAvailable("KWSHL","KWSPL"), "KiB");
printMethod3(info, GetHostMemoryUsed(), "KiB");
printMethod3(info, GetProcMemoryUsed(), "KiB");
+ printMethod(info, GetLoadAverage);
for (long int i = 0; i <= 31; i++)
{
if (info.DoesCPUSupportFeature(static_cast<long int>(1) << i))
{
- kwsys_ios::cout << "CPU feature " << i << "\n";
+ std::cout << "CPU feature " << i << "\n";
}
}
/* test stack trace
*/
- kwsys_ios::cout
- << "Program Stack:" << kwsys_ios::endl
- << kwsys::SystemInformation::GetProgramStack(0,0) << kwsys_ios::endl
- << kwsys_ios::endl;
+ std::cout
+ << "Program Stack:" << std::endl
+ << kwsys::SystemInformation::GetProgramStack(0,0) << std::endl
+ << std::endl;
/* test segv handler
info.SetStackTraceOnError(1);
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
index 1690fd51a..4d97688fc 100644
--- a/Source/kwsys/testSystemTools.cxx
+++ b/Source/kwsys/testSystemTools.cxx
@@ -16,20 +16,31 @@
#endif
#include KWSYS_HEADER(SystemTools.hxx)
-#include KWSYS_HEADER(ios/iostream)
// Work-around CMake dependency scanning limitation. This must
// duplicate the above list of headers.
#if 0
# include "SystemTools.hxx.in"
-# include "kwsys_ios_iostream.h.in"
#endif
// Include with <> instead of "" to avoid getting any in-source copy
// left on disk.
#include <testSystemTools.h>
+#include <iostream>
+#include <sstream>
#include <string.h> /* strcmp */
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# include <io.h> /* _umask (MSVC) / umask (Borland) */
+# ifdef _MSC_VER
+# define umask _umask // Note this is still umask on Borland
+# endif
+#endif
+#include <sys/stat.h> /* umask (POSIX), _S_I* constants (Windows) */
+// Visual C++ does not define mode_t (note that Borland does, however).
+#if defined( _MSC_VER )
+typedef unsigned short mode_t;
+#endif
//----------------------------------------------------------------------------
static const char* toUnixPaths[][2] =
@@ -52,17 +63,17 @@ static const char* toUnixPaths[][2] =
{0, 0}
};
-static bool CheckConvertToUnixSlashes(kwsys_stl::string input,
- kwsys_stl::string output)
+static bool CheckConvertToUnixSlashes(std::string input,
+ std::string output)
{
- kwsys_stl::string result = input;
+ std::string result = input;
kwsys::SystemTools::ConvertToUnixSlashes(result);
if ( result != output )
{
- kwsys_ios::cerr
- << "Problem with ConvertToUnixSlashes - input: " << input.c_str()
- << " output: " << result.c_str() << " expected: " << output.c_str()
- << kwsys_ios::endl;
+ std::cerr
+ << "Problem with ConvertToUnixSlashes - input: " << input
+ << " output: " << result << " expected: " << output
+ << std::endl;
return false;
}
return true;
@@ -76,19 +87,19 @@ static const char* checkEscapeChars[][4] =
{0, 0, 0, 0}
};
-static bool CheckEscapeChars(kwsys_stl::string input,
+static bool CheckEscapeChars(std::string input,
const char *chars_to_escape,
char escape_char,
- kwsys_stl::string output)
+ std::string output)
{
- kwsys_stl::string result = kwsys::SystemTools::EscapeChars(
+ std::string result = kwsys::SystemTools::EscapeChars(
input.c_str(), chars_to_escape, escape_char);
if (result != output)
{
- kwsys_ios::cerr
- << "Problem with CheckEscapeChars - input: " << input.c_str()
- << " output: " << result.c_str() << " expected: " << output.c_str()
- << kwsys_ios::endl;
+ std::cerr
+ << "Problem with CheckEscapeChars - input: " << input
+ << " output: " << result << " expected: " << output
+ << std::endl;
return false;
}
return true;
@@ -98,33 +109,442 @@ static bool CheckEscapeChars(kwsys_stl::string input,
static bool CheckFileOperations()
{
bool res = true;
+ const std::string testNonExistingFile(TEST_SYSTEMTOOLS_SOURCE_DIR
+ "/testSystemToolsNonExistingFile");
+ const std::string testDotFile(TEST_SYSTEMTOOLS_SOURCE_DIR
+ "/.");
+ const std::string testBinFile(TEST_SYSTEMTOOLS_SOURCE_DIR
+ "/testSystemTools.bin");
+ const std::string testTxtFile(TEST_SYSTEMTOOLS_SOURCE_DIR
+ "/testSystemTools.cxx");
+ const std::string testNewDir(TEST_SYSTEMTOOLS_BINARY_DIR
+ "/testSystemToolsNewDir");
+ const std::string testNewFile(testNewDir + "/testNewFile.txt");
+
+ if (kwsys::SystemTools::DetectFileType(testNonExistingFile.c_str()) !=
+ kwsys::SystemTools::FileTypeUnknown)
+ {
+ std::cerr
+ << "Problem with DetectFileType - failed to detect type of: "
+ << testNonExistingFile << std::endl;
+ res = false;
+ }
- if (kwsys::SystemTools::DetectFileType(TEST_SYSTEMTOOLS_BIN_FILE) !=
+ if (kwsys::SystemTools::DetectFileType(testDotFile.c_str()) !=
+ kwsys::SystemTools::FileTypeUnknown)
+ {
+ std::cerr
+ << "Problem with DetectFileType - failed to detect type of: "
+ << testDotFile << std::endl;
+ res = false;
+ }
+
+ if (kwsys::SystemTools::DetectFileType(testBinFile.c_str()) !=
kwsys::SystemTools::FileTypeBinary)
{
- kwsys_ios::cerr
+ std::cerr
<< "Problem with DetectFileType - failed to detect type of: "
- << TEST_SYSTEMTOOLS_BIN_FILE << kwsys_ios::endl;
+ << testBinFile << std::endl;
res = false;
}
- if (kwsys::SystemTools::DetectFileType(TEST_SYSTEMTOOLS_SRC_FILE) !=
+ if (kwsys::SystemTools::DetectFileType(testTxtFile.c_str()) !=
kwsys::SystemTools::FileTypeText)
{
- kwsys_ios::cerr
+ std::cerr
<< "Problem with DetectFileType - failed to detect type of: "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ << testTxtFile << std::endl;
res = false;
}
-
- if (kwsys::SystemTools::FileLength(TEST_SYSTEMTOOLS_BIN_FILE) != 766)
+
+ if (kwsys::SystemTools::FileLength(testBinFile) != 766)
{
- kwsys_ios::cerr
+ std::cerr
<< "Problem with FileLength - incorrect length for: "
- << TEST_SYSTEMTOOLS_BIN_FILE << kwsys_ios::endl;
- res = false;
+ << testBinFile << std::endl;
+ res = false;
+ }
+
+ if (!kwsys::SystemTools::MakeDirectory(testNewDir))
+ {
+ std::cerr
+ << "Problem with MakeDirectory for: "
+ << testNewDir << std::endl;
+ res = false;
+ }
+ // calling it again should just return true
+ if (!kwsys::SystemTools::MakeDirectory(testNewDir))
+ {
+ std::cerr
+ << "Problem with second call to MakeDirectory for: "
+ << testNewDir << std::endl;
+ res = false;
+ }
+ // calling with 0 pointer should return false
+ if (kwsys::SystemTools::MakeDirectory(0))
+ {
+ std::cerr
+ << "Problem with MakeDirectory(0)"
+ << std::endl;
+ res = false;
+ }
+ // calling with an empty string should return false
+ if (kwsys::SystemTools::MakeDirectory(std::string()))
+ {
+ std::cerr
+ << "Problem with MakeDirectory(std::string())"
+ << std::endl;
+ res = false;
+ }
+ // check existence
+ if (!kwsys::SystemTools::FileExists(testNewDir.c_str(), false))
+ {
+ std::cerr
+ << "Problem with FileExists as C string and not file for: "
+ << testNewDir << std::endl;
+ res = false;
+ }
+ // remove it
+ if (!kwsys::SystemTools::RemoveADirectory(testNewDir))
+ {
+ std::cerr
+ << "Problem with RemoveADirectory for: "
+ << testNewDir << std::endl;
+ res = false;
+ }
+ // check existence
+ if (kwsys::SystemTools::FileExists(testNewDir.c_str(), false))
+ {
+ std::cerr
+ << "After RemoveADirectory: "
+ << "Problem with FileExists as C string and not file for: "
+ << testNewDir << std::endl;
+ res = false;
+ }
+ // create it using the char* version
+ if (!kwsys::SystemTools::MakeDirectory(testNewDir.c_str()))
+ {
+ std::cerr
+ << "Problem with second call to MakeDirectory as C string for: "
+ << testNewDir << std::endl;
+ res = false;
+ }
+
+ if (!kwsys::SystemTools::Touch(testNewFile.c_str(), true))
+ {
+ std::cerr
+ << "Problem with Touch for: "
+ << testNewFile << std::endl;
+ res = false;
+ }
+ // calling MakeDirectory with something that is no file should fail
+ if (kwsys::SystemTools::MakeDirectory(testNewFile))
+ {
+ std::cerr
+ << "Problem with to MakeDirectory for: "
+ << testNewFile << std::endl;
+ res = false;
+ }
+
+ // calling with 0 pointer should return false
+ if (kwsys::SystemTools::FileExists(0))
+ {
+ std::cerr
+ << "Problem with FileExists(0)"
+ << std::endl;
+ res = false;
+ }
+ if (kwsys::SystemTools::FileExists(0, true))
+ {
+ std::cerr
+ << "Problem with FileExists(0) as file"
+ << std::endl;
+ res = false;
+ }
+ // calling with an empty string should return false
+ if (kwsys::SystemTools::FileExists(std::string()))
+ {
+ std::cerr
+ << "Problem with FileExists(std::string())"
+ << std::endl;
+ res = false;
+ }
+ // FileExists(x, true) should return false on a directory
+ if (kwsys::SystemTools::FileExists(testNewDir, true))
+ {
+ std::cerr
+ << "Problem with FileExists as file for: "
+ << testNewDir << std::endl;
+ res = false;
+ }
+ if (kwsys::SystemTools::FileExists(testNewDir.c_str(), true))
+ {
+ std::cerr
+ << "Problem with FileExists as C string and file for: "
+ << testNewDir << std::endl;
+ res = false;
+ }
+ // FileExists(x, false) should return true even on a directory
+ if (!kwsys::SystemTools::FileExists(testNewDir, false))
+ {
+ std::cerr
+ << "Problem with FileExists as not file for: "
+ << testNewDir << std::endl;
+ res = false;
+ }
+ if (!kwsys::SystemTools::FileExists(testNewDir.c_str(), false))
+ {
+ std::cerr
+ << "Problem with FileExists as C string and not file for: "
+ << testNewDir << std::endl;
+ res = false;
+ }
+ // should work, was created as new file before
+ if (!kwsys::SystemTools::FileExists(testNewFile))
+ {
+ std::cerr
+ << "Problem with FileExists for: "
+ << testNewDir << std::endl;
+ res = false;
+ }
+ if (!kwsys::SystemTools::FileExists(testNewFile.c_str()))
+ {
+ std::cerr
+ << "Problem with FileExists as C string for: "
+ << testNewDir << std::endl;
+ res = false;
+ }
+ if (!kwsys::SystemTools::FileExists(testNewFile, true))
+ {
+ std::cerr
+ << "Problem with FileExists as file for: "
+ << testNewDir << std::endl;
+ res = false;
+ }
+ if (!kwsys::SystemTools::FileExists(testNewFile.c_str(), true))
+ {
+ std::cerr
+ << "Problem with FileExists as C string and file for: "
+ << testNewDir << std::endl;
+ res = false;
+ }
+
+ // Reset umask
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ // NOTE: Windows doesn't support toggling _S_IREAD.
+ mode_t fullMask = _S_IWRITE;
+#else
+ // On a normal POSIX platform, we can toggle all permissions.
+ mode_t fullMask = S_IRWXU | S_IRWXG | S_IRWXO;
+#endif
+ mode_t orig_umask = umask(fullMask);
+
+ // Test file permissions without umask
+ mode_t origPerm, thisPerm;
+ if (!kwsys::SystemTools::GetPermissions(testNewFile, origPerm))
+ {
+ std::cerr
+ << "Problem with GetPermissions (1) for: "
+ << testNewFile << std::endl;
+ res = false;
+ }
+
+ if (!kwsys::SystemTools::SetPermissions(testNewFile, 0))
+ {
+ std::cerr
+ << "Problem with SetPermissions (1) for: "
+ << testNewFile << std::endl;
+ res = false;
+ }
+
+ if (!kwsys::SystemTools::GetPermissions(testNewFile, thisPerm))
+ {
+ std::cerr
+ << "Problem with GetPermissions (2) for: "
+ << testNewFile << std::endl;
+ res = false;
+ }
+
+ if ((thisPerm & fullMask) != 0)
+ {
+ std::cerr
+ << "SetPermissions failed to set permissions (1) for: "
+ << testNewFile << ": actual = " << thisPerm << "; expected = "
+ << 0 << std::endl;
+ res = false;
+ }
+
+ // While we're at it, check proper TestFileAccess functionality.
+ if (kwsys::SystemTools::TestFileAccess(testNewFile,
+ kwsys::TEST_FILE_WRITE))
+ {
+ std::cerr
+ << "TestFileAccess incorrectly indicated that this is a writable file:"
+ << testNewFile << std::endl;
+ res = false;
+ }
+
+ if (!kwsys::SystemTools::TestFileAccess(testNewFile,
+ kwsys::TEST_FILE_OK))
+ {
+ std::cerr
+ << "TestFileAccess incorrectly indicated that this file does not exist:"
+ << testNewFile << std::endl;
+ res = false;
+ }
+
+ // Test restoring/setting full permissions.
+ if (!kwsys::SystemTools::SetPermissions(testNewFile, fullMask))
+ {
+ std::cerr
+ << "Problem with SetPermissions (2) for: "
+ << testNewFile << std::endl;
+ res = false;
+ }
+
+ if (!kwsys::SystemTools::GetPermissions(testNewFile, thisPerm))
+ {
+ std::cerr
+ << "Problem with GetPermissions (3) for: "
+ << testNewFile << std::endl;
+ res = false;
+ }
+
+ if ((thisPerm & fullMask) != fullMask)
+ {
+ std::cerr
+ << "SetPermissions failed to set permissions (2) for: "
+ << testNewFile << ": actual = " << thisPerm << "; expected = "
+ << fullMask << std::endl;
+ res = false;
+ }
+
+ // Test setting file permissions while honoring umask
+ if (!kwsys::SystemTools::SetPermissions(testNewFile, fullMask, true))
+ {
+ std::cerr
+ << "Problem with SetPermissions (3) for: "
+ << testNewFile << std::endl;
+ res = false;
+ }
+
+ if (!kwsys::SystemTools::GetPermissions(testNewFile, thisPerm))
+ {
+ std::cerr
+ << "Problem with GetPermissions (4) for: "
+ << testNewFile << std::endl;
+ res = false;
+ }
+
+ if ((thisPerm & fullMask) != 0)
+ {
+ std::cerr
+ << "SetPermissions failed to honor umask for: "
+ << testNewFile << ": actual = " << thisPerm << "; expected = "
+ << 0 << std::endl;
+ res = false;
+ }
+
+ // Restore umask
+ umask(orig_umask);
+
+ // Restore file permissions
+ if (!kwsys::SystemTools::SetPermissions(testNewFile, origPerm))
+ {
+ std::cerr
+ << "Problem with SetPermissions (4) for: "
+ << testNewFile << std::endl;
+ res = false;
+ }
+
+ // Remove the test file
+ if (!kwsys::SystemTools::RemoveFile(testNewFile))
+ {
+ std::cerr
+ << "Problem with RemoveFile: "
+ << testNewFile << std::endl;
+ res = false;
+ }
+
+ std::string const testFileMissing(testNewDir + "/testMissingFile.txt");
+ if (!kwsys::SystemTools::RemoveFile(testFileMissing))
+ {
+ std::string const& msg = kwsys::SystemTools::GetLastSystemError();
+ std::cerr <<
+ "RemoveFile(\"" << testFileMissing << "\") failed: " << msg << "\n";
+ res = false;
+ }
+
+ std::string const testFileMissingDir(testNewDir + "/missing/file.txt");
+ if (!kwsys::SystemTools::RemoveFile(testFileMissingDir))
+ {
+ std::string const& msg = kwsys::SystemTools::GetLastSystemError();
+ std::cerr <<
+ "RemoveFile(\"" << testFileMissingDir << "\") failed: " << msg << "\n";
+ res = false;
+ }
+
+ kwsys::SystemTools::Touch(testNewFile.c_str(), true);
+ if (!kwsys::SystemTools::RemoveADirectory(testNewDir))
+ {
+ std::cerr
+ << "Problem with RemoveADirectory for: "
+ << testNewDir << std::endl;
+ res = false;
}
+#ifdef KWSYS_TEST_SYSTEMTOOLS_LONG_PATHS
+ // Perform the same file and directory creation and deletion tests but
+ // with paths > 256 characters in length.
+
+ const std::string testNewLongDir(
+ TEST_SYSTEMTOOLS_BINARY_DIR "/"
+ "012345678901234567890123456789012345678901234567890123456789"
+ "012345678901234567890123456789012345678901234567890123456789"
+ "012345678901234567890123456789012345678901234567890123456789"
+ "012345678901234567890123456789012345678901234567890123456789"
+ "01234567890123");
+ const std::string testNewLongFile(testNewLongDir + "/"
+ "012345678901234567890123456789012345678901234567890123456789"
+ "012345678901234567890123456789012345678901234567890123456789"
+ "012345678901234567890123456789012345678901234567890123456789"
+ "012345678901234567890123456789012345678901234567890123456789"
+ "0123456789.txt");
+
+ if (!kwsys::SystemTools::MakeDirectory(testNewLongDir))
+ {
+ std::cerr
+ << "Problem with MakeDirectory for: "
+ << testNewLongDir << std::endl;
+ res = false;
+ }
+
+ if (!kwsys::SystemTools::Touch(testNewLongFile.c_str(), true))
+ {
+ std::cerr
+ << "Problem with Touch for: "
+ << testNewLongFile << std::endl;
+ res = false;
+ }
+
+ if (!kwsys::SystemTools::RemoveFile(testNewLongFile))
+ {
+ std::cerr
+ << "Problem with RemoveFile: "
+ << testNewLongFile << std::endl;
+ res = false;
+ }
+
+ kwsys::SystemTools::Touch(testNewLongFile.c_str(), true);
+ if (!kwsys::SystemTools::RemoveADirectory(testNewLongDir))
+ {
+ std::cerr
+ << "Problem with RemoveADirectory for: "
+ << testNewLongDir << std::endl;
+ res = false;
+ }
+#endif
+
return res;
}
@@ -133,84 +553,84 @@ static bool CheckStringOperations()
{
bool res = true;
- kwsys_stl::string test = "mary had a little lamb.";
+ std::string test = "mary had a little lamb.";
if (kwsys::SystemTools::CapitalizedWords(test) != "Mary Had A Little Lamb.")
{
- kwsys_ios::cerr
+ std::cerr
<< "Problem with CapitalizedWords "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
- res = false;
+ << '"' << test << '"' << std::endl;
+ res = false;
}
test = "Mary Had A Little Lamb.";
- if (kwsys::SystemTools::UnCapitalizedWords(test) !=
+ if (kwsys::SystemTools::UnCapitalizedWords(test) !=
"mary had a little lamb.")
{
- kwsys_ios::cerr
+ std::cerr
<< "Problem with UnCapitalizedWords "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
- res = false;
+ << '"' << test << '"' << std::endl;
+ res = false;
}
test = "MaryHadTheLittleLamb.";
- if (kwsys::SystemTools::AddSpaceBetweenCapitalizedWords(test) !=
+ if (kwsys::SystemTools::AddSpaceBetweenCapitalizedWords(test) !=
"Mary Had The Little Lamb.")
{
- kwsys_ios::cerr
+ std::cerr
<< "Problem with AddSpaceBetweenCapitalizedWords "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
- res = false;
+ << '"' << test << '"' << std::endl;
+ res = false;
}
- char * cres =
+ char * cres =
kwsys::SystemTools::AppendStrings("Mary Had A"," Little Lamb.");
if (strcmp(cres,"Mary Had A Little Lamb."))
{
- kwsys_ios::cerr
+ std::cerr
<< "Problem with AppendStrings "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
- res = false;
+ << "\"Mary Had A\" \" Little Lamb.\"" << std::endl;
+ res = false;
}
delete [] cres;
- cres =
+ cres =
kwsys::SystemTools::AppendStrings("Mary Had"," A ","Little Lamb.");
if (strcmp(cres,"Mary Had A Little Lamb."))
{
- kwsys_ios::cerr
+ std::cerr
<< "Problem with AppendStrings "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
- res = false;
+ << "\"Mary Had\" \" A \" \"Little Lamb.\"" << std::endl;
+ res = false;
}
delete [] cres;
if (kwsys::SystemTools::CountChar("Mary Had A Little Lamb.",'a') != 3)
{
- kwsys_ios::cerr
+ std::cerr
<< "Problem with CountChar "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
- res = false;
+ << "\"Mary Had A Little Lamb.\"" << std::endl;
+ res = false;
}
- cres =
+ cres =
kwsys::SystemTools::RemoveChars("Mary Had A Little Lamb.","aeiou");
if (strcmp(cres,"Mry Hd A Lttl Lmb."))
{
- kwsys_ios::cerr
+ std::cerr
<< "Problem with RemoveChars "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
- res = false;
+ << "\"Mary Had A Little Lamb.\"" << std::endl;
+ res = false;
}
delete [] cres;
- cres =
+ cres =
kwsys::SystemTools::RemoveCharsButUpperHex("Mary Had A Little Lamb.");
if (strcmp(cres,"A"))
{
- kwsys_ios::cerr
+ std::cerr
<< "Problem with RemoveCharsButUpperHex "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
- res = false;
+ << "\"Mary Had A Little Lamb.\"" << std::endl;
+ res = false;
}
delete [] cres;
@@ -219,130 +639,221 @@ static bool CheckStringOperations()
kwsys::SystemTools::ReplaceChars(cres2,"aeiou",'X');
if (strcmp(cres2,"MXry HXd A LXttlX LXmb."))
{
- kwsys_ios::cerr
+ std::cerr
<< "Problem with ReplaceChars "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
- res = false;
+ << "\"Mary Had A Little Lamb.\"" << std::endl;
+ res = false;
}
delete [] cres2;
if (!kwsys::SystemTools::StringStartsWith("Mary Had A Little Lamb.",
"Mary "))
{
- kwsys_ios::cerr
+ std::cerr
<< "Problem with StringStartsWith "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
- res = false;
+ << "\"Mary Had A Little Lamb.\"" << std::endl;
+ res = false;
}
if (!kwsys::SystemTools::StringEndsWith("Mary Had A Little Lamb.",
" Lamb."))
{
- kwsys_ios::cerr
+ std::cerr
<< "Problem with StringEndsWith "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
- res = false;
+ << "\"Mary Had A Little Lamb.\"" << std::endl;
+ res = false;
}
cres = kwsys::SystemTools::DuplicateString("Mary Had A Little Lamb.");
if (strcmp(cres,"Mary Had A Little Lamb."))
{
- kwsys_ios::cerr
+ std::cerr
<< "Problem with DuplicateString "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
- res = false;
+ << "\"Mary Had A Little Lamb.\"" << std::endl;
+ res = false;
}
delete [] cres;
test = "Mary Had A Little Lamb.";
- if (kwsys::SystemTools::CropString(test,13) !=
+ if (kwsys::SystemTools::CropString(test,13) !=
"Mary ...Lamb.")
{
- kwsys_ios::cerr
+ std::cerr
<< "Problem with CropString "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
- res = false;
+ << "\"Mary Had A Little Lamb.\"" << std::endl;
+ res = false;
}
- kwsys_stl::vector<kwsys_stl::string> lines;
+ std::vector<std::string> lines;
kwsys::SystemTools::Split("Mary Had A Little Lamb.",lines,' ');
if (lines[0] != "Mary" || lines[1] != "Had" ||
lines[2] != "A" || lines[3] != "Little" || lines[4] != "Lamb.")
{
- kwsys_ios::cerr
+ std::cerr
<< "Problem with Split "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
- res = false;
+ << "\"Mary Had A Little Lamb.\"" << std::endl;
+ res = false;
+ }
+
+#ifdef _WIN32
+ if (kwsys::SystemTools::ConvertToWindowsExtendedPath
+ ("L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") !=
+ L"\\\\?\\L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo")
+ {
+ std::cerr
+ << "Problem with ConvertToWindowsExtendedPath "
+ << "\"L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\""
+ << std::endl;
+ res = false;
+ }
+
+ if (kwsys::SystemTools::ConvertToWindowsExtendedPath
+ ("L:/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
+ L"\\\\?\\L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo")
+ {
+ std::cerr
+ << "Problem with ConvertToWindowsExtendedPath "
+ << "\"L:/Local Mojo/Hex Power Pack/Iffy Voodoo\""
+ << std::endl;
+ res = false;
+ }
+
+ if (kwsys::SystemTools::ConvertToWindowsExtendedPath
+ ("\\\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") !=
+ L"\\\\?\\UNC\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo")
+ {
+ std::cerr
+ << "Problem with ConvertToWindowsExtendedPath "
+ << "\"\\\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\""
+ << std::endl;
+ res = false;
+ }
+
+ if (kwsys::SystemTools::ConvertToWindowsExtendedPath
+ ("//Foo/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
+ L"\\\\?\\UNC\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo")
+ {
+ std::cerr
+ << "Problem with ConvertToWindowsExtendedPath "
+ << "\"//Foo/Local Mojo/Hex Power Pack/Iffy Voodoo\""
+ << std::endl;
+ res = false;
+ }
+
+ if (kwsys::SystemTools::ConvertToWindowsExtendedPath("//") !=
+ L"//")
+ {
+ std::cerr
+ << "Problem with ConvertToWindowsExtendedPath "
+ << "\"//\""
+ << std::endl;
+ res = false;
+ }
+
+ if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\") !=
+ L"\\\\.\\")
+ {
+ std::cerr
+ << "Problem with ConvertToWindowsExtendedPath "
+ << "\"\\\\.\\\""
+ << std::endl;
+ res = false;
}
+ if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\X") !=
+ L"\\\\.\\X")
+ {
+ std::cerr
+ << "Problem with ConvertToWindowsExtendedPath "
+ << "\"\\\\.\\X\""
+ << std::endl;
+ res = false;
+ }
+
+ if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\X:") !=
+ L"\\\\?\\X:")
+ {
+ std::cerr
+ << "Problem with ConvertToWindowsExtendedPath "
+ << "\"\\\\.\\X:\""
+ << std::endl;
+ res = false;
+ }
+
+ if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\X:\\") !=
+ L"\\\\?\\X:\\")
+ {
+ std::cerr
+ << "Problem with ConvertToWindowsExtendedPath "
+ << "\"\\\\.\\X:\\\""
+ << std::endl;
+ res = false;
+ }
+
+ if (kwsys::SystemTools::ConvertToWindowsExtendedPath("NUL") !=
+ L"\\\\.\\NUL")
+ {
+ std::cerr
+ << "Problem with ConvertToWindowsExtendedPath "
+ << "\"NUL\""
+ << std::endl;
+ res = false;
+ }
+
+#endif
+
if (kwsys::SystemTools::ConvertToWindowsOutputPath
- ("L://Local Mojo/Hex Power Pack/Iffy Voodoo") !=
+ ("L://Local Mojo/Hex Power Pack/Iffy Voodoo") !=
"\"L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\"")
{
- kwsys_ios::cerr
+ std::cerr
<< "Problem with ConvertToWindowsOutputPath "
- << kwsys_ios::endl;
- res = false;
+ << "\"L://Local Mojo/Hex Power Pack/Iffy Voodoo\""
+ << std::endl;
+ res = false;
}
-
+
if (kwsys::SystemTools::ConvertToWindowsOutputPath
- ("//grayson/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
+ ("//grayson/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
"\"\\\\grayson\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\"")
{
- kwsys_ios::cerr
+ std::cerr
<< "Problem with ConvertToWindowsOutputPath "
- << kwsys_ios::endl;
- res = false;
+ << "\"//grayson/Local Mojo/Hex Power Pack/Iffy Voodoo\""
+ << std::endl;
+ res = false;
}
if (kwsys::SystemTools::ConvertToUnixOutputPath
- ("//Local Mojo/Hex Power Pack/Iffy Voodoo") !=
+ ("//Local Mojo/Hex Power Pack/Iffy Voodoo") !=
"//Local\\ Mojo/Hex\\ Power\\ Pack/Iffy\\ Voodoo")
{
- kwsys_ios::cerr
+ std::cerr
<< "Problem with ConvertToUnixOutputPath "
- << kwsys_ios::endl;
- res = false;
- }
-
- int targc;
- char **targv;
- kwsys::SystemTools::ConvertWindowsCommandLineToUnixArguments
- ("\"Local Mojo\\Voodoo.asp\" -CastHex \"D:\\My Secret Mojo\\Voodoo.mp3\"", &targc, &targv);
- if (targc != 4 || strcmp(targv[1],"Local Mojo\\Voodoo.asp") ||
- strcmp(targv[2],"-CastHex") ||
- strcmp(targv[3],"D:\\My Secret Mojo\\Voodoo.mp3"))
- {
- kwsys_ios::cerr
- << "Problem with ConvertWindowsCommandLineToUnixArguments"
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
- res = false;
- }
- for (;targc >=0; --targc)
- {
- delete [] targv[targc];
+ << "\"//Local Mojo/Hex Power Pack/Iffy Voodoo\""
+ << std::endl;
+ res = false;
}
- delete [] targv;
return res;
}
//----------------------------------------------------------------------------
-static bool CheckPutEnv(const char* env, const char* name, const char* value)
+static bool CheckPutEnv(const std::string& env, const char* name, const char* value)
{
if(!kwsys::SystemTools::PutEnv(env))
{
- kwsys_ios::cerr << "PutEnv(\"" << env
- << "\") failed!" << kwsys_ios::endl;
+ std::cerr << "PutEnv(\"" << env
+ << "\") failed!" << std::endl;
return false;
}
const char* v = kwsys::SystemTools::GetEnv(name);
v = v? v : "(null)";
if(strcmp(v, value) != 0)
{
- kwsys_ios::cerr << "GetEnv(\"" << name << "\") returned \""
- << v << "\", not \"" << value << "\"!" << kwsys_ios::endl;
+ std::cerr << "GetEnv(\"" << name << "\") returned \""
+ << v << "\", not \"" << value << "\"!" << std::endl;
return false;
}
return true;
@@ -352,14 +863,14 @@ static bool CheckUnPutEnv(const char* env, const char* name)
{
if(!kwsys::SystemTools::UnPutEnv(env))
{
- kwsys_ios::cerr << "UnPutEnv(\"" << env << "\") failed!"
- << kwsys_ios::endl;
+ std::cerr << "UnPutEnv(\"" << env << "\") failed!"
+ << std::endl;
return false;
}
if(const char* v = kwsys::SystemTools::GetEnv(name))
{
- kwsys_ios::cerr << "GetEnv(\"" << name << "\") returned \""
- << v << "\", not (null)!" << kwsys_ios::endl;
+ std::cerr << "GetEnv(\"" << name << "\") returned \""
+ << v << "\", not (null)!" << std::endl;
return false;
}
return true;
@@ -379,6 +890,153 @@ static bool CheckEnvironmentOperations()
return res;
}
+
+static bool CheckRelativePath(
+ const std::string& local,
+ const std::string& remote,
+ const std::string& expected)
+{
+ std::string result = kwsys::SystemTools::RelativePath(local, remote);
+ if(expected != result)
+ {
+ std::cerr << "RelativePath(" << local << ", " << remote
+ << ") yielded " << result << " instead of " << expected << std::endl;
+ return false;
+ }
+ return true;
+}
+
+static bool CheckRelativePaths()
+{
+ bool res = true;
+ res &= CheckRelativePath("/usr/share", "/bin/bash", "../../bin/bash");
+ res &= CheckRelativePath("/usr/./share/", "/bin/bash", "../../bin/bash");
+ res &= CheckRelativePath("/usr//share/", "/bin/bash", "../../bin/bash");
+ res &= CheckRelativePath("/usr/share/../bin/", "/bin/bash", "../../bin/bash");
+ res &= CheckRelativePath("/usr/share", "/usr/share//bin", "bin");
+ return res;
+}
+
+static bool CheckCollapsePath(
+ const std::string& path,
+ const std::string& expected)
+{
+ std::string result = kwsys::SystemTools::CollapseFullPath(path);
+ if(expected != result)
+ {
+ std::cerr << "CollapseFullPath(" << path
+ << ") yielded " << result << " instead of " << expected << std::endl;
+ return false;
+ }
+ return true;
+}
+
+static bool CheckCollapsePath()
+{
+ bool res = true;
+ res &= CheckCollapsePath("/usr/share/*", "/usr/share/*");
+ res &= CheckCollapsePath("C:/Windows/*", "C:/Windows/*");
+ return res;
+}
+
+static std::string StringVectorToString(const std::vector<std::string>& vec)
+{
+ std::stringstream ss;
+ ss << "vector(";
+ for (std::vector<std::string>::const_iterator i = vec.begin();
+ i != vec.end(); ++i)
+ {
+ if (i != vec.begin())
+ {
+ ss << ", ";
+ }
+ ss << *i;
+ }
+ ss << ")";
+ return ss.str();
+}
+
+static bool CheckGetPath()
+{
+ const char* envName = "S";
+#ifdef _WIN32
+ const char* envValue = "C:\\Somewhere\\something;D:\\Temp";
+#else
+ const char* envValue = "/Somewhere/something:/tmp";
+#endif
+ const char* registryPath = "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MyApp; MyKey]";
+
+ std::vector<std::string> originalPathes;
+ originalPathes.push_back(registryPath);
+
+ std::vector<std::string> expectedPathes;
+ expectedPathes.push_back(registryPath);
+#ifdef _WIN32
+ expectedPathes.push_back("C:/Somewhere/something");
+ expectedPathes.push_back("D:/Temp");
+#else
+ expectedPathes.push_back("/Somewhere/something");
+ expectedPathes.push_back("/tmp");
+#endif
+
+ bool res = true;
+ res &= CheckPutEnv(std::string(envName) + "=" + envValue, envName, envValue);
+
+ std::vector<std::string> pathes = originalPathes;
+ kwsys::SystemTools::GetPath(pathes, envName);
+
+ if (pathes != expectedPathes)
+ {
+ std::cerr <<
+ "GetPath(" << StringVectorToString(originalPathes) <<
+ ", " << envName << ") yielded " << StringVectorToString(pathes) <<
+ " instead of " << StringVectorToString(expectedPathes) <<
+ std::endl;
+ res = false;
+ }
+
+ res &= CheckUnPutEnv(envName, envName);
+ return res;
+}
+
+static bool CheckFind()
+{
+ bool res = true;
+ const std::string testFindFileName("testFindFile.txt");
+ const std::string testFindFile(TEST_SYSTEMTOOLS_BINARY_DIR "/"
+ + testFindFileName);
+
+ if (!kwsys::SystemTools::Touch(testFindFile.c_str(), true))
+ {
+ std::cerr
+ << "Problem with Touch for: "
+ << testFindFile << std::endl;
+ // abort here as the existence of the file only makes the test meaningful
+ return false;
+ }
+
+ std::vector<std::string> searchPaths;
+ searchPaths.push_back(TEST_SYSTEMTOOLS_BINARY_DIR);
+ if (kwsys::SystemTools::FindFile(testFindFileName,
+ searchPaths, true).empty())
+ {
+ std::cerr
+ << "Problem with FindFile without system paths for: "
+ << testFindFileName << std::endl;
+ res = false;
+ }
+ if (kwsys::SystemTools::FindFile(testFindFileName,
+ searchPaths, false).empty())
+ {
+ std::cerr
+ << "Problem with FindFile with system paths for: "
+ << testFindFileName << std::endl;
+ res = false;
+ }
+
+ return res;
+}
+
//----------------------------------------------------------------------------
int testSystemTools(int, char*[])
{
@@ -391,7 +1049,7 @@ int testSystemTools(int, char*[])
}
// Special check for ~
- kwsys_stl::string output;
+ std::string output;
if(kwsys::SystemTools::GetEnv("HOME", output))
{
output += "/foo bar/lala";
@@ -400,7 +1058,7 @@ int testSystemTools(int, char*[])
for (cc = 0; checkEscapeChars[cc][0]; cc ++ )
{
- res &= CheckEscapeChars(checkEscapeChars[cc][0], checkEscapeChars[cc][1],
+ res &= CheckEscapeChars(checkEscapeChars[cc][0], checkEscapeChars[cc][1],
*checkEscapeChars[cc][2], checkEscapeChars[cc][3]);
}
@@ -410,5 +1068,13 @@ int testSystemTools(int, char*[])
res &= CheckEnvironmentOperations();
+ res &= CheckRelativePaths();
+
+ res &= CheckCollapsePath();
+
+ res &= CheckGetPath();
+
+ res &= CheckFind();
+
return res ? 0 : 1;
}
diff --git a/Source/kwsys/testSystemTools.h.in b/Source/kwsys/testSystemTools.h.in
index 4b94bb6af..66f0f7257 100644
--- a/Source/kwsys/testSystemTools.h.in
+++ b/Source/kwsys/testSystemTools.h.in
@@ -14,7 +14,8 @@
#define EXECUTABLE_OUTPUT_PATH "@CMAKE_CURRENT_BINARY_DIR@"
-#define TEST_SYSTEMTOOLS_BIN_FILE "@TEST_SYSTEMTOOLS_BIN_FILE@"
-#define TEST_SYSTEMTOOLS_SRC_FILE "@TEST_SYSTEMTOOLS_SRC_FILE@"
+#define TEST_SYSTEMTOOLS_SOURCE_DIR "@TEST_SYSTEMTOOLS_SOURCE_DIR@"
+#define TEST_SYSTEMTOOLS_BINARY_DIR "@TEST_SYSTEMTOOLS_BINARY_DIR@"
+#cmakedefine KWSYS_TEST_SYSTEMTOOLS_LONG_PATHS
#endif
diff --git a/Templates/CPack.GenericDescription.txt b/Templates/CPack.GenericDescription.txt
index 9ca1802ad..712ee145f 100644
--- a/Templates/CPack.GenericDescription.txt
+++ b/Templates/CPack.GenericDescription.txt
@@ -1,5 +1,5 @@
DESCRIPTION
===========
-This is an installer created using CPack (http://www.cmake.org). No additional installation instructions provided.
+This is an installer created using CPack (https://cmake.org). No additional installation instructions provided.
diff --git a/Templates/CPack.GenericLicense.txt b/Templates/CPack.GenericLicense.txt
index c211bb370..09c621841 100644
--- a/Templates/CPack.GenericLicense.txt
+++ b/Templates/CPack.GenericLicense.txt
@@ -1,5 +1,5 @@
LICENSE
=======
-This is an installer created using CPack (http://www.cmake.org). No license provided.
+This is an installer created using CPack (https://cmake.org). No license provided.
diff --git a/Templates/CPackConfig.cmake.in b/Templates/CPackConfig.cmake.in
index 79b8d93ae..c00ea2a05 100644
--- a/Templates/CPackConfig.cmake.in
+++ b/Templates/CPackConfig.cmake.in
@@ -10,3 +10,11 @@
# usually begin with CPACK_<GENNAME>_xxxx.
@_CPACK_OTHER_VARIABLES_@
+
+if(NOT CPACK_PROPERTIES_FILE)
+ set(CPACK_PROPERTIES_FILE "@CMAKE_BINARY_DIR@/CPackProperties.cmake")
+endif()
+
+if(EXISTS ${CPACK_PROPERTIES_FILE})
+ include(${CPACK_PROPERTIES_FILE})
+endif()
diff --git a/Templates/TestDriver.cxx.in b/Templates/TestDriver.cxx.in
index f4510bb55..ffa69995b 100644
--- a/Templates/TestDriver.cxx.in
+++ b/Templates/TestDriver.cxx.in
@@ -3,6 +3,10 @@
#include <string.h>
#include <stdlib.h>
+#if defined(_MSC_VER)
+# pragma warning(disable:4996) /* deprecation */
+#endif
+
@CMAKE_TESTDRIVER_EXTRA_INCLUDES@
@@ -18,7 +22,7 @@ typedef struct
MainFuncPointer func;
} functionMapEntry;
-functionMapEntry cmakeGeneratedFunctionMapEntries[] = {
+static functionMapEntry cmakeGeneratedFunctionMapEntries[] = {
@CMAKE_FUNCTION_TABLE_ENTIRES@
{0,0}
};
@@ -26,7 +30,7 @@ functionMapEntry cmakeGeneratedFunctionMapEntries[] = {
/* Allocate and create a lowercased copy of string
(note that it has to be free'd manually) */
-char* lowercase(const char *string)
+static char* lowercase(const char *string)
{
char *new_string, *p;
@@ -58,7 +62,7 @@ char* lowercase(const char *string)
int main(int ac, char *av[])
{
- int i, NumTests, testNum, partial_match;
+ int i, NumTests, testNum = 0, partial_match;
char *arg, *test_name;
int count;
int testToRun = -1;
@@ -81,7 +85,6 @@ int main(int ac, char *av[])
}
printf("To run a test, enter the test number: ");
fflush(stdout);
- testNum = 0;
if( scanf("%d", &testNum) != 1 )
{
printf("Couldn't parse that input as a number\n");
@@ -137,6 +140,13 @@ int main(int ac, char *av[])
{
int result;
@CMAKE_TESTDRIVER_BEFORE_TESTMAIN@
+ if (testToRun < 0 || testToRun >= NumTests)
+ {
+ printf(
+ "testToRun was modified by TestDriver code to an invalid value: %3d.\n",
+ testNum);
+ return -1;
+ }
result = (*cmakeGeneratedFunctionMapEntries[testToRun].func)(ac, av);
@CMAKE_TESTDRIVER_AFTER_TESTMAIN@
return result;
diff --git a/Templates/Windows/ApplicationIcon.png b/Templates/Windows/ApplicationIcon.png
new file mode 100644
index 000000000..7d95d4e08
--- /dev/null
+++ b/Templates/Windows/ApplicationIcon.png
Binary files differ
diff --git a/Templates/Windows/Logo.png b/Templates/Windows/Logo.png
new file mode 100644
index 000000000..e26771cb3
--- /dev/null
+++ b/Templates/Windows/Logo.png
Binary files differ
diff --git a/Templates/Windows/SmallLogo.png b/Templates/Windows/SmallLogo.png
new file mode 100644
index 000000000..1eb0d9d52
--- /dev/null
+++ b/Templates/Windows/SmallLogo.png
Binary files differ
diff --git a/Templates/Windows/SmallLogo44x44.png b/Templates/Windows/SmallLogo44x44.png
new file mode 100644
index 000000000..28810b7c0
--- /dev/null
+++ b/Templates/Windows/SmallLogo44x44.png
Binary files differ
diff --git a/Templates/Windows/SplashScreen.png b/Templates/Windows/SplashScreen.png
new file mode 100644
index 000000000..c951e031b
--- /dev/null
+++ b/Templates/Windows/SplashScreen.png
Binary files differ
diff --git a/Templates/Windows/StoreLogo.png b/Templates/Windows/StoreLogo.png
new file mode 100644
index 000000000..dcb672712
--- /dev/null
+++ b/Templates/Windows/StoreLogo.png
Binary files differ
diff --git a/Templates/Windows/Windows_TemporaryKey.pfx b/Templates/Windows/Windows_TemporaryKey.pfx
new file mode 100644
index 000000000..1cad9993d
--- /dev/null
+++ b/Templates/Windows/Windows_TemporaryKey.pfx
Binary files differ
diff --git a/Tests/AliasTarget/CMakeLists.txt b/Tests/AliasTarget/CMakeLists.txt
index a5eb0f6de..e1d89666e 100644
--- a/Tests/AliasTarget/CMakeLists.txt
+++ b/Tests/AliasTarget/CMakeLists.txt
@@ -1,7 +1,15 @@
-
cmake_minimum_required(VERSION 2.8.11)
project(AliasTarget)
+set(CMAKE_CXX_STANDARD 98)
+
+# Those versions of the HP compiler that need a flag to get proper C++98
+# template support also need a flag to use the newer C++ library.
+if (CMAKE_CXX_COMPILER_ID STREQUAL HP AND
+ CMAKE_CXX98_STANDARD_COMPILE_OPTION STREQUAL "+hpxstd98")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -AA")
+endif ()
+
add_library(foo SHARED empty.cpp)
add_library(PREFIX::Foo ALIAS foo)
add_library(Another::Alias ALIAS foo)
@@ -29,7 +37,9 @@ target_include_directories(bat PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
add_executable(targetgenerator targetgenerator.cpp)
add_executable(Generator::Target ALIAS targetgenerator)
-add_custom_target(usealias Generator::Target)
+add_subdirectory(subdir)
+
+add_custom_target(usealias Generator::Target $<TARGET_FILE:Sub::tgt>)
add_dependencies(bat usealias)
if (NOT TARGET Another::Alias)
@@ -45,3 +55,28 @@ get_property(_alt2 TARGET PREFIX::Foo PROPERTY ALIASED_TARGET)
if (NOT ${_alt2} STREQUAL foo)
message(SEND_ERROR "ALIASED_TARGET is not foo.")
endif()
+
+add_library(iface INTERFACE)
+add_library(Alias::Iface ALIAS iface)
+
+get_target_property(_notAlias1 foo ALIASED_TARGET)
+if (NOT DEFINED _notAlias1)
+ message(SEND_ERROR "_notAlias1 is not defined")
+endif()
+if (_notAlias1)
+ message(SEND_ERROR "_notAlias1 is defined, but foo is not an ALIAS")
+endif()
+if (NOT _notAlias1 STREQUAL _notAlias1-NOTFOUND)
+ message(SEND_ERROR "_notAlias1 not defined to a -NOTFOUND variant")
+endif()
+
+get_property(_notAlias2 TARGET foo PROPERTY ALIASED_TARGET)
+if (NOT DEFINED _notAlias2)
+ message(SEND_ERROR "_notAlias2 is not defined")
+endif()
+if (_notAlias2)
+ message(SEND_ERROR "_notAlias2 is defined, but foo is not an ALIAS")
+endif()
+if (NOT _notAlias2 STREQUAL _notAlias2-NOTFOUND)
+ message(SEND_ERROR "_notAlias2 not defined to a -NOTFOUND variant")
+endif()
diff --git a/Tests/AliasTarget/subdir/CMakeLists.txt b/Tests/AliasTarget/subdir/CMakeLists.txt
new file mode 100644
index 000000000..8c84aea3c
--- /dev/null
+++ b/Tests/AliasTarget/subdir/CMakeLists.txt
@@ -0,0 +1,3 @@
+
+add_library(tgt STATIC empty.cpp)
+add_library(Sub::tgt ALIAS tgt)
diff --git a/Tests/AliasTarget/subdir/empty.cpp b/Tests/AliasTarget/subdir/empty.cpp
new file mode 100644
index 000000000..b19427ad0
--- /dev/null
+++ b/Tests/AliasTarget/subdir/empty.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int main(void)
+{
+ return 0;
+}
diff --git a/Tests/Assembler/CMakeLists.txt b/Tests/Assembler/CMakeLists.txt
index bb4bcccbe..fb17ebb60 100644
--- a/Tests/Assembler/CMakeLists.txt
+++ b/Tests/Assembler/CMakeLists.txt
@@ -9,12 +9,15 @@ set(SRCS)
# and also generate assembler files from C:
if("${CMAKE_GENERATOR}" MATCHES "Makefile|Xcode" AND
NOT CMAKE_OSX_ARCHITECTURES)
- if(("${CMAKE_C_COMPILER_ID}" MATCHES "^(GNU|Clang|HP|SunPro|XL)$") OR ("${CMAKE_C_COMPILER_ID}" STREQUAL "Intel" AND UNIX))
+ if((CMAKE_C_COMPILER_ID MATCHES "^(GNU|Clang|AppleClang|HP|SunPro|XL)$") OR (CMAKE_C_COMPILER_ID STREQUAL "Intel" AND UNIX))
set(C_FLAGS "${CMAKE_C_FLAGS}")
separate_arguments(C_FLAGS)
if(CMAKE_OSX_SYSROOT AND CMAKE_C_SYSROOT_FLAG AND NOT ";${C_FLAGS};" MATCHES ";${CMAKE_C_SYSROOT_FLAG};")
list(APPEND C_FLAGS ${CMAKE_C_SYSROOT_FLAG} ${CMAKE_OSX_SYSROOT})
endif()
+ # Clang on OS X, and perhaps other compilers, do not support -g
+ # for both generating and assembling, so drop it from generating.
+ list(REMOVE_ITEM C_FLAGS -g)
set(SRCS main.s)
add_custom_command(
OUTPUT main.s
diff --git a/Tests/BootstrapTest.cmake b/Tests/BootstrapTest.cmake
new file mode 100644
index 000000000..9c9fe09ac
--- /dev/null
+++ b/Tests/BootstrapTest.cmake
@@ -0,0 +1,10 @@
+file(MAKE_DIRECTORY "${bin_dir}")
+message(STATUS "running bootstrap: ${bootstrap}")
+execute_process(
+ COMMAND ${bootstrap}
+ WORKING_DIRECTORY "${bin_dir}"
+ RESULT_VARIABLE result
+ )
+if(result)
+ message(FATAL_ERROR "bootstrap failed: ${result}")
+endif()
diff --git a/Tests/BuildDepends/CMakeLists.txt b/Tests/BuildDepends/CMakeLists.txt
index 06871543f..36987de7b 100644
--- a/Tests/BuildDepends/CMakeLists.txt
+++ b/Tests/BuildDepends/CMakeLists.txt
@@ -13,7 +13,7 @@ project(BuildDepends)
set(CMAKE_SUPPRESS_REGENERATION 1)
# Xcode needs some help with the fancy dependencies in this test.
-if("${CMAKE_GENERATOR}" MATCHES "Xcode")
+if(XCODE AND XCODE_VERSION VERSION_LESS 5)
set(HELP_XCODE 1)
endif()
function(help_xcode_depends)
@@ -28,17 +28,13 @@ function(help_xcode_depends)
endif()
endfunction()
-if("${CMAKE_GENERATOR}" MATCHES "Ninja")
- set(HELP_NINJA 1) # TODO Why is this needed?
-endif()
-
# The Intel compiler causes the MSVC linker to crash during
# incremental linking, so avoid the /INCREMENTAL:YES flag.
if(WIN32 AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Intel")
set(_cmake_options "-DCMAKE_EXE_LINKER_FLAGS=")
endif()
-if("${CMAKE_GENERATOR}" MATCHES "Make")
+if("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
set(TEST_LINK_DEPENDS ${BuildDepends_BINARY_DIR}/Project/linkdep.txt)
file(WRITE ${TEST_LINK_DEPENDS} "1")
endif()
@@ -46,6 +42,11 @@ list(APPEND _cmake_options "-DTEST_LINK_DEPENDS=${TEST_LINK_DEPENDS}")
list(APPEND _cmake_options "-DCMAKE_FORCE_DEPFILES=1")
+if(NOT CMAKE_GENERATOR MATCHES "Visual Studio ([^6789]|[6789][0-9])")
+ set(TEST_MULTI3 1)
+ list(APPEND _cmake_options "-DTEST_MULTI3=1")
+endif()
+
file(MAKE_DIRECTORY ${BuildDepends_BINARY_DIR}/Project)
message("Creating Project/foo.cxx")
write_file(${BuildDepends_BINARY_DIR}/Project/foo.cxx
@@ -68,6 +69,14 @@ file(WRITE ${BuildDepends_BINARY_DIR}/Project/link_depends_no_shared_exe.h
"#define link_depends_no_shared_exe_value 0\n")
set(link_depends_no_shared_check_txt ${BuildDepends_BINARY_DIR}/Project/link_depends_no_shared_check.txt)
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/object_depends.txt "0\n")
+set(object_depends_check_txt ${BuildDepends_BINARY_DIR}/Project/object_depends_check.txt)
+
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/external.in "external original\n")
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/multi1-in.txt "multi1-in original\n")
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/multi2-stamp.txt "multi2-stamp original\n")
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/multi3-stamp.txt "multi3-stamp original\n")
+
help_xcode_depends()
message("Building project first time")
@@ -166,9 +175,62 @@ else()
"Targets link_depends_no_shared_lib and link_depends_no_shared_exe not both built.")
endif()
+if(EXISTS ${BuildDepends_BINARY_DIR}/Project/external.out)
+ file(STRINGS ${BuildDepends_BINARY_DIR}/Project/external.out external_out)
+ if("${external_out}" STREQUAL "external original")
+ message(STATUS "external.out contains '${external_out}'")
+ else()
+ message(SEND_ERROR "Project did not initially build properly: "
+ "external.out contains '${external_out}'")
+ endif()
+else()
+ message(SEND_ERROR "Project did not initially build properly: "
+ "external.out is missing")
+endif()
+
+if(EXISTS ${BuildDepends_BINARY_DIR}/Project/multi1-out2-copy.txt)
+ file(STRINGS ${BuildDepends_BINARY_DIR}/Project/multi1-out2-copy.txt multi1_out)
+ if("${multi1_out}" STREQUAL "multi1-in original")
+ message(STATUS "multi1-out2-copy.txt contains '${multi1_out}'")
+ else()
+ message(SEND_ERROR "Project did not initially build properly: "
+ "multi1-out2-copy.txt contains '${multi1_out}'")
+ endif()
+else()
+ message(SEND_ERROR "Project did not initially build properly: "
+ "multi1-out2-copy.txt is missing")
+endif()
+
+if(EXISTS ${BuildDepends_BINARY_DIR}/Project/multi2-real.txt)
+ if(${BuildDepends_BINARY_DIR}/Project/multi2-real.txt
+ IS_NEWER_THAN ${BuildDepends_BINARY_DIR}/Project/multi2-stamp.txt)
+ message(STATUS "multi2-real.txt is newer than multi2-stamp.txt")
+ else()
+ message(SEND_ERROR "Project did not initially build properly: "
+ "multi2-real.txt is not newer than multi2-stamp.txt")
+ endif()
+else()
+ message(SEND_ERROR "Project did not initially build properly: "
+ "multi2-real.txt is missing")
+endif()
+
+if(TEST_MULTI3)
+ if(EXISTS ${BuildDepends_BINARY_DIR}/Project/multi3-real.txt)
+ if(${BuildDepends_BINARY_DIR}/Project/multi3-real.txt
+ IS_NEWER_THAN ${BuildDepends_BINARY_DIR}/Project/multi3-stamp.txt)
+ message(STATUS "multi3-real.txt is newer than multi3-stamp.txt")
+ else()
+ message(SEND_ERROR "Project did not initially build properly: "
+ "multi3-real.txt is not newer than multi3-stamp.txt")
+ endif()
+ else()
+ message(SEND_ERROR "Project did not initially build properly: "
+ "multi3-real.txt is missing")
+ endif()
+endif()
+
message("Waiting 3 seconds...")
-# any additional argument will cause ${bar} to wait forever
-execute_process(COMMAND ${bar} -infinite TIMEOUT 3 OUTPUT_VARIABLE out)
+execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 3)
message("Modifying Project/foo.cxx")
write_file(${BuildDepends_BINARY_DIR}/Project/foo.cxx
@@ -187,10 +249,17 @@ file(WRITE ${BuildDepends_BINARY_DIR}/Project/zot_macro_tgt.hxx
file(WRITE ${BuildDepends_BINARY_DIR}/Project/link_depends_no_shared_lib.h
"#define link_depends_no_shared_lib_value 0\n")
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/object_depends.txt "1\n")
+
if(TEST_LINK_DEPENDS)
file(WRITE ${TEST_LINK_DEPENDS} "2")
endif()
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/external.in "external changed\n")
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/multi1-in.txt "multi1-in changed\n")
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/multi2-stamp.txt "multi2-stamp changed\n")
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/multi3-stamp.txt "multi3-stamp changed\n")
+
help_xcode_depends()
message("Building project second time")
@@ -202,7 +271,7 @@ try_compile(RESULT
OUTPUT_VARIABLE OUTPUT)
# Xcode is in serious need of help here
-if(HELP_XCODE OR HELP_NINJA)
+if(HELP_XCODE)
try_compile(RESULT
${BuildDepends_BINARY_DIR}/Project
${BuildDepends_SOURCE_DIR}/Project
@@ -294,3 +363,71 @@ else()
message(SEND_ERROR "Project did not rebuild properly. "
"Targets link_depends_no_shared_lib and link_depends_no_shared_exe not both built.")
endif()
+
+if(EXISTS "${object_depends_check_txt}")
+ file(STRINGS "${object_depends_check_txt}" object_depends_check LIMIT_COUNT 1)
+ if("${object_depends_check}" STREQUAL "1")
+ message(STATUS "object_depends exe is newer than object_depends.txt as expected.")
+ elseif(CMAKE_GENERATOR MATCHES "Visual Studio|Xcode")
+ message(STATUS "Known limitation: OBJECT_DEPENDS does not work on ${CMAKE_GENERATOR}")
+ else()
+ message(SEND_ERROR "Project did not rebuild properly: object_depends exe is not newer than object_depends.txt.")
+ endif()
+else()
+ message(SEND_ERROR "Project did not rebuild properly. "
+ "object_depends exe and object_depends.txt are not both present.")
+endif()
+
+if(EXISTS ${BuildDepends_BINARY_DIR}/Project/external.out)
+ file(STRINGS ${BuildDepends_BINARY_DIR}/Project/external.out external_out)
+ if("${external_out}" STREQUAL "external changed")
+ message(STATUS "external.out contains '${external_out}'")
+ else()
+ message(SEND_ERROR "Project did not rebuild properly: "
+ "external.out contains '${external_out}'")
+ endif()
+else()
+ message(SEND_ERROR "Project did not rebuild properly: "
+ "external.out is missing")
+endif()
+
+if(EXISTS ${BuildDepends_BINARY_DIR}/Project/multi1-out2-copy.txt)
+ file(STRINGS ${BuildDepends_BINARY_DIR}/Project/multi1-out2-copy.txt multi1_out)
+ if("${multi1_out}" STREQUAL "multi1-in changed")
+ message(STATUS "multi1-out2-copy.txt contains '${multi1_out}'")
+ else()
+ message(SEND_ERROR "Project did not rebuild properly: "
+ "multi1-out2-copy.txt contains '${multi1_out}'")
+ endif()
+else()
+ message(SEND_ERROR "Project did not rebuild properly: "
+ "multi1-out2-copy.txt is missing")
+endif()
+
+if(EXISTS ${BuildDepends_BINARY_DIR}/Project/multi2-real.txt)
+ if(${BuildDepends_BINARY_DIR}/Project/multi2-real.txt
+ IS_NEWER_THAN ${BuildDepends_BINARY_DIR}/Project/multi2-stamp.txt)
+ message(STATUS "multi2-real.txt is newer than multi2-stamp.txt")
+ else()
+ message(SEND_ERROR "Project did not rebuild properly: "
+ "multi2-real.txt is not newer than multi2-stamp.txt")
+ endif()
+else()
+ message(SEND_ERROR "Project did not rebuild properly: "
+ "multi2-real.txt is missing")
+endif()
+
+if(TEST_MULTI3)
+ if(EXISTS ${BuildDepends_BINARY_DIR}/Project/multi3-real.txt)
+ if(${BuildDepends_BINARY_DIR}/Project/multi3-real.txt
+ IS_NEWER_THAN ${BuildDepends_BINARY_DIR}/Project/multi3-stamp.txt)
+ message(STATUS "multi3-real.txt is newer than multi3-stamp.txt")
+ else()
+ message(SEND_ERROR "Project did not rebuild properly: "
+ "multi3-real.txt is not newer than multi3-stamp.txt")
+ endif()
+ else()
+ message(SEND_ERROR "Project did not rebuild properly: "
+ "multi3-real.txt is missing")
+ endif()
+endif()
diff --git a/Tests/BuildDepends/Project/CMakeLists.txt b/Tests/BuildDepends/Project/CMakeLists.txt
index 8806ecdf1..3aa57fc9e 100644
--- a/Tests/BuildDepends/Project/CMakeLists.txt
+++ b/Tests/BuildDepends/Project/CMakeLists.txt
@@ -139,3 +139,58 @@ add_custom_target(header_tgt DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/dir/header.h)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_executable(ninjadep ninjadep.cpp)
add_dependencies(ninjadep header_tgt)
+
+include(ExternalProject)
+ExternalProject_Add(ExternalBuild
+ SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/External
+ BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/External
+ STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/External/Stamp
+ BUILD_ALWAYS 1
+ CMAKE_ARGS
+ -Dexternal_in=${CMAKE_CURRENT_BINARY_DIR}/external.in
+ -Dexternal_out=${CMAKE_CURRENT_BINARY_DIR}/external.out
+ INSTALL_COMMAND ""
+ )
+
+add_custom_command(
+ OUTPUT multi1-out1.txt multi1-out2.txt
+ COMMAND ${CMAKE_COMMAND} -E copy multi1-in.txt multi1-out1.txt
+ COMMAND ${CMAKE_COMMAND} -E copy multi1-in.txt multi1-out2.txt
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/multi1-in.txt
+ )
+add_custom_command(
+ OUTPUT multi1-out2-copy.txt
+ COMMAND ${CMAKE_COMMAND} -E copy multi1-out2.txt multi1-out2-copy.txt
+ DEPENDS multi1-out2.txt
+ )
+add_custom_target(multi1 ALL DEPENDS multi1-out2-copy.txt)
+
+# Test having the first output never created.
+add_custom_command(
+ OUTPUT multi2-dummy.txt multi2-real.txt
+ COMMAND ${CMAKE_COMMAND} -E touch multi2-real.txt
+ )
+set_property(SOURCE multi2-real.txt multi2-dummy.txt PROPERTY SYMBOLIC 1)
+add_custom_target(multi2 ALL DEPENDS multi2-real.txt)
+
+if(TEST_MULTI3)
+ # Test having the second output never created. Does not work with msbuild.
+ add_custom_command(
+ OUTPUT multi3-real.txt multi3-dummy.txt
+ COMMAND ${CMAKE_COMMAND} -E touch multi3-real.txt
+ )
+ set_property(SOURCE multi3-real.txt multi3-dummy.txt PROPERTY SYMBOLIC 1)
+ add_custom_target(multi3 ALL DEPENDS multi3-real.txt)
+endif()
+
+add_executable(object_depends object_depends.cxx)
+set_property(SOURCE object_depends.cxx PROPERTY OBJECT_DEPENDS
+ ${CMAKE_CURRENT_BINARY_DIR}/object_depends.txt)
+add_custom_target(object_depends_check ALL
+ COMMAND ${CMAKE_COMMAND}
+ -Dexe=$<TARGET_FILE:object_depends>
+ -Dout=${CMAKE_CURRENT_BINARY_DIR}/object_depends_check.txt
+ -Dtxt=${CMAKE_CURRENT_BINARY_DIR}/object_depends.txt
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/object_depends_check.cmake
+ )
+add_dependencies(object_depends_check object_depends)
diff --git a/Tests/BuildDepends/Project/External/CMakeLists.txt b/Tests/BuildDepends/Project/External/CMakeLists.txt
new file mode 100644
index 000000000..c6015b651
--- /dev/null
+++ b/Tests/BuildDepends/Project/External/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.0)
+project(BuildDependsExternal NONE)
+if(NOT DEFINED external_in)
+ message(FATAL_ERROR "Define external_in")
+endif()
+if(NOT DEFINED external_out)
+ message(FATAL_ERROR "Define external_out")
+endif()
+add_custom_command(
+ OUTPUT ${external_out}
+ COMMAND ${CMAKE_COMMAND} -E copy ${external_in} ${external_out}
+ DEPENDS ${external_in}
+ )
+add_custom_target(drive ALL DEPENDS ${external_out})
diff --git a/Tests/BuildDepends/Project/bar.cxx b/Tests/BuildDepends/Project/bar.cxx
index 25d8bd21b..dadf93d6b 100644
--- a/Tests/BuildDepends/Project/bar.cxx
+++ b/Tests/BuildDepends/Project/bar.cxx
@@ -15,11 +15,5 @@ int main(int argc, char** argv)
/* Print out the string that should have been regenerated. */
printf("%s\n", regen_string);
fflush(stdout);
- // if any argument is used, wait forever
- if (argc>1)
- {
- // wait that we get killed...
- for(;;);
- }
return 0;
}
diff --git a/Tests/BuildDepends/Project/object_depends.cxx b/Tests/BuildDepends/Project/object_depends.cxx
new file mode 100644
index 000000000..76e819701
--- /dev/null
+++ b/Tests/BuildDepends/Project/object_depends.cxx
@@ -0,0 +1 @@
+int main() { return 0; }
diff --git a/Tests/BuildDepends/Project/object_depends_check.cmake b/Tests/BuildDepends/Project/object_depends_check.cmake
new file mode 100644
index 000000000..e00989288
--- /dev/null
+++ b/Tests/BuildDepends/Project/object_depends_check.cmake
@@ -0,0 +1,7 @@
+if(NOT EXISTS "${txt}" OR NOT EXISTS "${exe}")
+ file(REMOVE "${out}")
+elseif("${exe}" IS_NEWER_THAN "${txt}")
+ file(WRITE "${out}" "1\n")
+else()
+ file(WRITE "${out}" "0\n")
+endif()
diff --git a/Tests/BundleTest/BundleLib.cxx b/Tests/BundleTest/BundleLib.cxx
index b68ee25dd..37bc178d6 100644
--- a/Tests/BundleTest/BundleLib.cxx
+++ b/Tests/BundleTest/BundleLib.cxx
@@ -58,7 +58,7 @@ int foo(char *exec)
int res1 = findBundleFile(exec, "Resources/randomResourceFile.plist");
int res2 = findBundleFile(exec, "MacOS/SomeRandomFile.txt");
- int res3 = findBundleFile(exec, "MacOS/ChangeLog.txt");
+ int res3 = findBundleFile(exec, "MacOS/README.rst");
if ( !res1 ||
!res2 ||
!res3 )
diff --git a/Tests/BundleTest/BundleSubDir/CMakeLists.txt b/Tests/BundleTest/BundleSubDir/CMakeLists.txt
index 1921ce095..43c366a09 100644
--- a/Tests/BundleTest/BundleSubDir/CMakeLists.txt
+++ b/Tests/BundleTest/BundleSubDir/CMakeLists.txt
@@ -12,7 +12,7 @@ set_source_files_properties(
set_source_files_properties(
"${BundleTest_SOURCE_DIR}/SomeRandomFile.txt"
- "${BundleTest_SOURCE_DIR}/../../ChangeLog.txt"
+ "${BundleTest_SOURCE_DIR}/../../README.rst"
PROPERTIES
MACOSX_PACKAGE_LOCATION MacOS
)
@@ -21,7 +21,7 @@ add_executable(SecondBundle
MACOSX_BUNDLE
"${BundleTest_SOURCE_DIR}/BundleTest.cxx"
"${BundleTest_SOURCE_DIR}/SomeRandomFile.txt"
- "${BundleTest_SOURCE_DIR}/../../ChangeLog.txt"
+ "${BundleTest_SOURCE_DIR}/../../README.rst"
"${CMAKE_CURRENT_BINARY_DIR}/randomResourceFile.plist"
)
target_link_libraries(SecondBundle BundleTestLib)
diff --git a/Tests/BundleTest/CMakeLists.txt b/Tests/BundleTest/CMakeLists.txt
index de69d7555..853da3538 100644
--- a/Tests/BundleTest/CMakeLists.txt
+++ b/Tests/BundleTest/CMakeLists.txt
@@ -17,7 +17,7 @@ set_source_files_properties(
set_source_files_properties(
SomeRandomFile.txt
- "${BundleTest_SOURCE_DIR}/../../ChangeLog.txt"
+ "${BundleTest_SOURCE_DIR}/../../README.rst"
PROPERTIES
MACOSX_PACKAGE_LOCATION MacOS
)
@@ -38,7 +38,7 @@ add_executable(BundleTest
MACOSX_BUNDLE
BundleTest.cxx
SomeRandomFile.txt
- "${BundleTest_SOURCE_DIR}/../../ChangeLog.txt"
+ "${BundleTest_SOURCE_DIR}/../../README.rst"
"${CMAKE_CURRENT_BINARY_DIR}/randomResourceFile.plist"
)
target_link_libraries(BundleTest BundleTestLib)
diff --git a/Tests/BundleUtilities/CMakeLists.txt b/Tests/BundleUtilities/CMakeLists.txt
index 5cc7071b4..69ef53505 100644
--- a/Tests/BundleUtilities/CMakeLists.txt
+++ b/Tests/BundleUtilities/CMakeLists.txt
@@ -25,13 +25,11 @@ set_target_properties(shared shared2 framework PROPERTIES
# testbundleutils1 will load this at runtime
add_library(module1 MODULE module.cpp module.h)
set_target_properties(module1 PROPERTIES PREFIX "")
-get_target_property(module_loc module1 LOCATION)
target_link_libraries(module1 shared2)
# a bundle application
add_executable(testbundleutils1 MACOSX_BUNDLE testbundleutils1.cpp)
target_link_libraries(testbundleutils1 shared framework ${CMAKE_DL_LIBS})
-get_target_property(loc testbundleutils1 LOCATION)
set_target_properties(testbundleutils1 module1 PROPERTIES
INSTALL_RPATH "${CMAKE_CURRENT_BINARY_DIR}/testdir1"
@@ -40,8 +38,8 @@ set_target_properties(testbundleutils1 module1 PROPERTIES
# add custom target to install and test the app
add_custom_target(testbundleutils1_test ALL
COMMAND ${CMAKE_COMMAND}
- "-DINPUT=${loc}"
- "-DMODULE=${module_loc}"
+ "-DINPUT=$<TARGET_FILE:testbundleutils1>"
+ "-DMODULE=$<TARGET_FILE:module1>"
"-DINPUTDIR=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}"
"-DOUTPUTDIR=${CMAKE_CURRENT_BINARY_DIR}/testdir1"
-P "${CMAKE_CURRENT_SOURCE_DIR}/bundleutils.cmake"
@@ -58,13 +56,11 @@ add_dependencies(testbundleutils1_test testbundleutils1)
# testbundleutils2 will load this at runtime
add_library(module2 MODULE module.cpp module.h)
set_target_properties(module2 PROPERTIES PREFIX "")
-get_target_property(module_loc module2 LOCATION)
target_link_libraries(module2 shared2)
# a non-bundle application
add_executable(testbundleutils2 testbundleutils2.cpp)
target_link_libraries(testbundleutils2 shared framework ${CMAKE_DL_LIBS})
-get_target_property(loc testbundleutils2 LOCATION)
set_target_properties(testbundleutils2 module2 PROPERTIES
INSTALL_RPATH "${CMAKE_CURRENT_BINARY_DIR}/testdir2"
@@ -73,8 +69,8 @@ set_target_properties(testbundleutils2 module2 PROPERTIES
# add custom target to install and test the app
add_custom_target(testbundleutils2_test ALL
COMMAND ${CMAKE_COMMAND}
- "-DINPUT=${loc}"
- "-DMODULE=${module_loc}"
+ "-DINPUT=$<TARGET_FILE:testbundleutils2>"
+ "-DMODULE=$<TARGET_FILE:module2>"
"-DINPUTDIR=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}"
"-DOUTPUTDIR=${CMAKE_CURRENT_BINARY_DIR}/testdir2"
-P "${CMAKE_CURRENT_SOURCE_DIR}/bundleutils.cmake"
@@ -106,22 +102,21 @@ if(APPLE AND NOT CMAKE_SYSTEM_VERSION VERSION_LESS 9.0)
# testbundleutils1 will load this at runtime
add_library(module3 MODULE module.cpp module.h)
set_target_properties(module3 PROPERTIES PREFIX "" LINK_FLAGS "-Wl,-rpath,@loader_path/")
- get_target_property(module_loc module3 LOCATION)
target_link_libraries(module3 shared2-3)
# a non-bundle application
add_executable(testbundleutils3 testbundleutils3.cpp)
target_link_libraries(testbundleutils3 shared-3 framework-3 ${CMAKE_DL_LIBS})
- get_target_property(loc testbundleutils3 LOCATION)
set_target_properties(testbundleutils3 module3 PROPERTIES
- LINK_FLAGS "-Wl,-rpath,@loader_path/")
+ LINK_FLAGS "-Wl,-rpath,@loader_path/"
+ BUILD_WITH_INSTALL_RPATH 1)
# add custom target to install and test the app
add_custom_target(testbundleutils3_test ALL
COMMAND ${CMAKE_COMMAND}
- "-DINPUT=${loc}"
- "-DMODULE=${module_loc}"
+ "-DINPUT=$<TARGET_FILE:testbundleutils3>"
+ "-DMODULE=$<TARGET_FILE:module3>"
"-DINPUTDIR=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}"
"-DOUTPUTDIR=${CMAKE_CURRENT_BINARY_DIR}/testdir3"
-P "${CMAKE_CURRENT_SOURCE_DIR}/bundleutils.cmake"
diff --git a/Tests/CFBundleTest/CMakeLists.txt b/Tests/CFBundleTest/CMakeLists.txt
index bf9771c8b..5cda527d8 100644
--- a/Tests/CFBundleTest/CMakeLists.txt
+++ b/Tests/CFBundleTest/CMakeLists.txt
@@ -30,8 +30,14 @@ if(NOT RC_COMPILER)
message(FATAL_ERROR "could not find Rez to build resources from .r file...")
endif()
+set(sysroot)
+if(CMAKE_OSX_SYSROOT)
+ set(sysroot -isysroot ${CMAKE_OSX_SYSROOT})
+endif()
+
execute_process(COMMAND
- ${RC_COMPILER} ${RCFILES} -useDF -o ${CMAKE_CURRENT_BINARY_DIR}/Localized.rsrc
+ ${RC_COMPILER} ${sysroot} ${RCFILES} -useDF
+ -o ${CMAKE_CURRENT_BINARY_DIR}/Localized.rsrc
)
set_source_files_properties(
diff --git a/Tests/CFBundleTest/VerifyResult.cmake b/Tests/CFBundleTest/VerifyResult.cmake
index e62290052..e637bb142 100644
--- a/Tests/CFBundleTest/VerifyResult.cmake
+++ b/Tests/CFBundleTest/VerifyResult.cmake
@@ -14,13 +14,10 @@ message(STATUS "CTEST_CONFIGURATION_TYPE='${CTEST_CONFIGURATION_TYPE}'")
message(STATUS "dir='${dir}'")
message(STATUS "gen='${gen}'")
-if(gen MATCHES "Make" OR
- "${CTEST_CONFIGURATION_TYPE}" STREQUAL "" OR
- "${CTEST_CONFIGURATION_TYPE}" STREQUAL "." OR
- "${CTEST_CONFIGURATION_TYPE}" STREQUAL "NoConfig")
- set(expected_filename "${dir}/CFBundleTest.plugin/Contents/MacOS/CFBundleTest")
-else()
+if(gen STREQUAL "Xcode")
set(expected_filename "${dir}/${CTEST_CONFIGURATION_TYPE}/CFBundleTest.plugin/Contents/MacOS/CFBundleTest")
+else()
+ set(expected_filename "${dir}/CFBundleTest.plugin/Contents/MacOS/CFBundleTest")
endif()
if(NOT EXISTS "${expected_filename}")
diff --git a/Tests/CMakeBuildTest.cmake.in b/Tests/CMakeBuildTest.cmake.in
index 0f7074b2f..71bcb183e 100644
--- a/Tests/CMakeBuildTest.cmake.in
+++ b/Tests/CMakeBuildTest.cmake.in
@@ -11,8 +11,9 @@ file(REMOVE "@CMAKE_BUILD_TEST_SOURCE_DIR@/CMakeCache.txt")
message("running: ${CMAKE_COMMAND}")
execute_process(COMMAND "${CMAKE_COMMAND}"
"@CMAKE_BUILD_TEST_SOURCE_DIR@"
- "-G@CMAKE_TEST_GENERATOR@"
- -T "@CMAKE_TEST_GENERATOR_TOOLSET@"
+ "-G@CMAKE_GENERATOR@"
+ -A "@CMAKE_GENERATOR_PLATFORM@"
+ -T "@CMAKE_GENERATOR_TOOLSET@"
WORKING_DIRECTORY "@CMAKE_BUILD_TEST_BINARY_DIR@"
RESULT_VARIABLE RESULT)
if(RESULT)
diff --git a/Tests/CMakeCommands/add_compile_options/CMakeLists.txt b/Tests/CMakeCommands/add_compile_options/CMakeLists.txt
index 1652cf665..995b32c28 100644
--- a/Tests/CMakeCommands/add_compile_options/CMakeLists.txt
+++ b/Tests/CMakeCommands/add_compile_options/CMakeLists.txt
@@ -12,3 +12,10 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
"DO_GNU_TESTS"
)
endif()
+
+add_compile_options(-rtti)
+add_library(imp UNKNOWN IMPORTED)
+get_target_property(_res imp COMPILE_OPTIONS)
+if (_res)
+ message(SEND_ERROR "add_compile_options populated the COMPILE_OPTIONS target property")
+endif()
diff --git a/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt b/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt
index 900dbd028..f96283d55 100644
--- a/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt
@@ -25,3 +25,25 @@ target_compile_definitions(consumer
target_compile_definitions(consumer
PRIVATE
)
+
+if (CMAKE_GENERATOR MATCHES "Makefiles" OR CMAKE_GENERATOR MATCHES "Ninja")
+ target_sources(consumer PRIVATE
+ "${CMAKE_CURRENT_SOURCE_DIR}/consumer.c"
+ )
+ target_compile_definitions(consumer
+ PRIVATE
+ CONSUMER_LANG_$<COMPILE_LANGUAGE>
+ LANG_IS_CXX=$<COMPILE_LANGUAGE:CXX>
+ LANG_IS_C=$<COMPILE_LANGUAGE:C>
+ )
+ target_compile_definitions(consumer
+ PRIVATE -DTEST_LANG_DEFINES
+ )
+endif()
+
+add_definitions(-DSOME_DEF)
+add_library(imp UNKNOWN IMPORTED)
+get_target_property(_res imp COMPILE_DEFINITIONS)
+if (_res)
+ message(SEND_ERROR "add_definitions populated the COMPILE_DEFINITIONS target property")
+endif()
diff --git a/Tests/CMakeCommands/target_compile_definitions/consumer.c b/Tests/CMakeCommands/target_compile_definitions/consumer.c
new file mode 100644
index 000000000..5796d9652
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_definitions/consumer.c
@@ -0,0 +1,23 @@
+
+#ifdef TEST_LANG_DEFINES
+ #ifdef CONSUMER_LANG_CXX
+ #error Unexpected CONSUMER_LANG_CXX
+ #endif
+
+ #ifndef CONSUMER_LANG_C
+ #error Expected CONSUMER_LANG_C
+ #endif
+
+ #if !LANG_IS_C
+ #error Expected LANG_IS_C
+ #endif
+
+ #if LANG_IS_CXX
+ #error Unexpected LANG_IS_CXX
+ #endif
+#endif
+
+void consumer_c()
+{
+
+}
diff --git a/Tests/CMakeCommands/target_compile_definitions/consumer.cpp b/Tests/CMakeCommands/target_compile_definitions/consumer.cpp
index a39111416..778f57e55 100644
--- a/Tests/CMakeCommands/target_compile_definitions/consumer.cpp
+++ b/Tests/CMakeCommands/target_compile_definitions/consumer.cpp
@@ -15,4 +15,22 @@
#error Expected DASH_D_DEFINE
#endif
+#ifdef TEST_LANG_DEFINES
+ #ifndef CONSUMER_LANG_CXX
+ #error Expected CONSUMER_LANG_CXX
+ #endif
+
+ #ifdef CONSUMER_LANG_C
+ #error Unexpected CONSUMER_LANG_C
+ #endif
+
+ #if !LANG_IS_CXX
+ #error Expected LANG_IS_CXX
+ #endif
+
+ #if LANG_IS_C
+ #error Unexpected LANG_IS_C
+ #endif
+#endif
+
int main() { return 0; }
diff --git a/Tests/CMakeCommands/target_compile_features/CMakeLists.txt b/Tests/CMakeCommands/target_compile_features/CMakeLists.txt
new file mode 100644
index 000000000..9b35f2713
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/CMakeLists.txt
@@ -0,0 +1,45 @@
+cmake_minimum_required(VERSION 3.0)
+project(target_compile_features)
+
+if (NOT CMAKE_CXX_COMPILE_FEATURES AND NOT CMAKE_C_COMPILE_FEATURES)
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test_dummy.cpp"
+ "int main(int,char**) { return 0; }\n"
+ )
+ add_executable(target_compile_features "${CMAKE_CURRENT_BINARY_DIR}/test_dummy.cpp")
+ return()
+endif()
+
+set(CMAKE_VERBOSE_MAKEFILE ON)
+
+if (CMAKE_C_COMPILE_FEATURES)
+ add_executable(target_compile_features main.c)
+ target_compile_features(target_compile_features
+ PRIVATE c_restrict
+ )
+
+ add_library(lib_restrict lib_restrict.c)
+ target_compile_features(lib_restrict
+ PUBLIC c_restrict
+ )
+
+ add_executable(restrict_user restrict_user.c)
+ target_link_libraries(restrict_user lib_restrict)
+endif()
+
+if (CMAKE_CXX_COMPILE_FEATURES)
+ if (CMAKE_C_COMPILE_FEATURES)
+ set(target_suffix _cxx)
+ endif()
+ add_executable(target_compile_features${target_suffix} main.cpp)
+ target_compile_features(target_compile_features${target_suffix}
+ PRIVATE cxx_auto_type
+ )
+
+ add_library(lib_auto_type lib_auto_type.cpp)
+ target_compile_features(lib_auto_type
+ PUBLIC cxx_auto_type
+ )
+
+ add_executable(lib_user lib_user.cpp)
+ target_link_libraries(lib_user lib_auto_type)
+endif()
diff --git a/Tests/CMakeCommands/target_compile_features/dummy.cpp b/Tests/CMakeCommands/target_compile_features/dummy.cpp
new file mode 100644
index 000000000..341aaafa0
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/dummy.cpp
@@ -0,0 +1,5 @@
+
+int main(int, char **)
+{
+ return 0;
+}
diff --git a/Tests/CMakeCommands/target_compile_features/lib_auto_type.cpp b/Tests/CMakeCommands/target_compile_features/lib_auto_type.cpp
new file mode 100644
index 000000000..71b22150d
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/lib_auto_type.cpp
@@ -0,0 +1,6 @@
+
+int getAutoTypeImpl()
+{
+ auto i = 0;
+ return i;
+}
diff --git a/Tests/CMakeCommands/target_compile_features/lib_auto_type.h b/Tests/CMakeCommands/target_compile_features/lib_auto_type.h
new file mode 100644
index 000000000..c825b10c3
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/lib_auto_type.h
@@ -0,0 +1,8 @@
+
+int getAutoTypeImpl();
+
+int getAutoType()
+{
+ auto i = getAutoTypeImpl();
+ return i;
+}
diff --git a/Tests/CMakeCommands/target_compile_features/lib_restrict.c b/Tests/CMakeCommands/target_compile_features/lib_restrict.c
new file mode 100644
index 000000000..049c1b008
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/lib_restrict.c
@@ -0,0 +1,9 @@
+
+#include "lib_restrict.h"
+
+int foo(int * restrict a, int * restrict b)
+{
+ (void)a;
+ (void)b;
+ return 0;
+}
diff --git a/Tests/CMakeCommands/target_compile_features/lib_restrict.h b/Tests/CMakeCommands/target_compile_features/lib_restrict.h
new file mode 100644
index 000000000..eca22be10
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/lib_restrict.h
@@ -0,0 +1,7 @@
+
+#ifndef LIB_RESTRICT_H
+#define LIB_RESTRICT_H
+
+int foo(int * restrict a, int * restrict b);
+
+#endif
diff --git a/Tests/CMakeCommands/target_compile_features/lib_user.cpp b/Tests/CMakeCommands/target_compile_features/lib_user.cpp
new file mode 100644
index 000000000..976068a0b
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/lib_user.cpp
@@ -0,0 +1,7 @@
+
+#include "lib_auto_type.h"
+
+int main(int argc, char **argv)
+{
+ return getAutoType();
+}
diff --git a/Tests/CMakeCommands/target_compile_features/main.c b/Tests/CMakeCommands/target_compile_features/main.c
new file mode 100644
index 000000000..831c5eb27
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/main.c
@@ -0,0 +1,12 @@
+
+int foo(int * restrict a, int * restrict b)
+{
+ (void)a;
+ (void)b;
+ return 0;
+}
+
+int main()
+{
+ return 0;
+}
diff --git a/Tests/CMakeCommands/target_compile_features/main.cpp b/Tests/CMakeCommands/target_compile_features/main.cpp
new file mode 100644
index 000000000..fe29b04ad
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/main.cpp
@@ -0,0 +1,6 @@
+
+int main(int, char **)
+{
+ auto i = 0;
+ return i;
+}
diff --git a/Tests/CMakeCommands/target_compile_features/restrict_user.c b/Tests/CMakeCommands/target_compile_features/restrict_user.c
new file mode 100644
index 000000000..d47b847b4
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/restrict_user.c
@@ -0,0 +1,14 @@
+
+#include "lib_restrict.h"
+
+int bar(int * restrict a, int * restrict b)
+{
+ (void)a;
+ (void)b;
+ return foo(a, b);
+}
+
+int main()
+{
+ return 0;
+}
diff --git a/Tests/CMakeCommands/target_compile_options/CMakeLists.txt b/Tests/CMakeCommands/target_compile_options/CMakeLists.txt
index 1d0463927..35dd276ba 100644
--- a/Tests/CMakeCommands/target_compile_options/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_compile_options/CMakeLists.txt
@@ -23,6 +23,21 @@ add_executable(consumer
"${CMAKE_CURRENT_SOURCE_DIR}/consumer.cpp"
)
+if (NOT CMAKE_GENERATOR MATCHES "Visual Studio")
+ target_sources(consumer PRIVATE
+ "${CMAKE_CURRENT_SOURCE_DIR}/consumer.c"
+ )
+ target_compile_options(consumer
+ PRIVATE
+ -DCONSUMER_LANG_$<COMPILE_LANGUAGE>
+ -DLANG_IS_CXX=$<COMPILE_LANGUAGE:CXX>
+ -DLANG_IS_C=$<COMPILE_LANGUAGE:C>
+ )
+ target_compile_definitions(consumer
+ PRIVATE -DTEST_LANG_DEFINES
+ )
+endif()
+
target_compile_options(consumer
PRIVATE $<$<CXX_COMPILER_ID:GNU>:$<TARGET_PROPERTY:target_compile_options,INTERFACE_COMPILE_OPTIONS>>
)
diff --git a/Tests/CMakeCommands/target_compile_options/consumer.c b/Tests/CMakeCommands/target_compile_options/consumer.c
new file mode 100644
index 000000000..5796d9652
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_options/consumer.c
@@ -0,0 +1,23 @@
+
+#ifdef TEST_LANG_DEFINES
+ #ifdef CONSUMER_LANG_CXX
+ #error Unexpected CONSUMER_LANG_CXX
+ #endif
+
+ #ifndef CONSUMER_LANG_C
+ #error Expected CONSUMER_LANG_C
+ #endif
+
+ #if !LANG_IS_C
+ #error Expected LANG_IS_C
+ #endif
+
+ #if LANG_IS_CXX
+ #error Unexpected LANG_IS_CXX
+ #endif
+#endif
+
+void consumer_c()
+{
+
+}
diff --git a/Tests/CMakeCommands/target_compile_options/consumer.cpp b/Tests/CMakeCommands/target_compile_options/consumer.cpp
index 12996065b..c5882a54b 100644
--- a/Tests/CMakeCommands/target_compile_options/consumer.cpp
+++ b/Tests/CMakeCommands/target_compile_options/consumer.cpp
@@ -15,4 +15,22 @@
#endif
+#ifdef TEST_LANG_DEFINES
+ #ifndef CONSUMER_LANG_CXX
+ #error Expected CONSUMER_LANG_CXX
+ #endif
+
+ #ifdef CONSUMER_LANG_C
+ #error Unexpected CONSUMER_LANG_C
+ #endif
+
+ #if !LANG_IS_CXX
+ #error Expected LANG_IS_CXX
+ #endif
+
+ #if LANG_IS_C
+ #error Unexpected LANG_IS_C
+ #endif
+#endif
+
int main() { return 0; }
diff --git a/Tests/CMakeCommands/target_include_directories/CMakeLists.txt b/Tests/CMakeCommands/target_include_directories/CMakeLists.txt
index 21b8e1530..d57556aad 100644
--- a/Tests/CMakeCommands/target_include_directories/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_include_directories/CMakeLists.txt
@@ -42,10 +42,25 @@ add_executable(consumer
"${CMAKE_CURRENT_SOURCE_DIR}/consumer.cpp"
)
+if (CMAKE_GENERATOR MATCHES "Makefiles" OR CMAKE_GENERATOR MATCHES "Ninja")
+ target_sources(consumer PRIVATE
+ "${CMAKE_CURRENT_SOURCE_DIR}/consumer.c"
+ )
+ target_include_directories(consumer
+ PRIVATE
+ $<$<COMPILE_LANGUAGE:CXX>:${CMAKE_CURRENT_SOURCE_DIR}/cxx_only>
+ $<$<COMPILE_LANGUAGE:C>:${CMAKE_CURRENT_SOURCE_DIR}/c_only>
+ )
+ target_compile_definitions(consumer
+ PRIVATE -DTEST_LANG_DEFINES
+ )
+endif()
+
target_include_directories(consumer
PRIVATE
$<TARGET_PROPERTY:target_include_directories,INTERFACE_INCLUDE_DIRECTORIES>
- relative_dir
+ relative_dir
+ relative_dir/$<TARGET_PROPERTY:NAME>
)
# Test no items
@@ -61,3 +76,10 @@ target_include_directories(consumer
target_include_directories(consumer
SYSTEM PRIVATE
)
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+add_library(imp UNKNOWN IMPORTED)
+get_target_property(_res imp INCLUDE_DIRECTORIES)
+if (_res)
+ message(SEND_ERROR "include_directories populated the INCLUDE_DIRECTORIES target property")
+endif()
diff --git a/Tests/CMakeCommands/target_include_directories/c_only/c_only.h b/Tests/CMakeCommands/target_include_directories/c_only/c_only.h
new file mode 100644
index 000000000..29f68ee33
--- /dev/null
+++ b/Tests/CMakeCommands/target_include_directories/c_only/c_only.h
@@ -0,0 +1,2 @@
+
+#define C_ONLY_DEFINE
diff --git a/Tests/CMakeCommands/target_include_directories/consumer.c b/Tests/CMakeCommands/target_include_directories/consumer.c
new file mode 100644
index 000000000..8821f5bc7
--- /dev/null
+++ b/Tests/CMakeCommands/target_include_directories/consumer.c
@@ -0,0 +1,10 @@
+
+#ifdef TEST_LANG_DEFINES
+ #include "c_only.h"
+
+ #ifndef C_ONLY_DEFINE
+ #error Expected C_ONLY_DEFINE
+ #endif
+#endif
+
+int consumer_c() { return 0; }
diff --git a/Tests/CMakeCommands/target_include_directories/consumer.cpp b/Tests/CMakeCommands/target_include_directories/consumer.cpp
index 82b800a40..649510ce0 100644
--- a/Tests/CMakeCommands/target_include_directories/consumer.cpp
+++ b/Tests/CMakeCommands/target_include_directories/consumer.cpp
@@ -3,6 +3,10 @@
#include "publicinclude.h"
#include "interfaceinclude.h"
#include "relative_dir.h"
+#include "consumer.h"
+#ifdef TEST_LANG_DEFINES
+ #include "cxx_only.h"
+#endif
#ifdef PRIVATEINCLUDE_DEFINE
#error Unexpected PRIVATEINCLUDE_DEFINE
@@ -24,4 +28,14 @@
#error Expected RELATIVE_DIR_DEFINE
#endif
+#ifndef CONSUMER_DEFINE
+#error Expected CONSUMER_DEFINE
+#endif
+
+#ifdef TEST_LANG_DEFINES
+ #ifndef CXX_ONLY_DEFINE
+ #error Expected CXX_ONLY_DEFINE
+ #endif
+#endif
+
int main() { return 0; }
diff --git a/Tests/CMakeCommands/target_include_directories/cxx_only/cxx_only.h b/Tests/CMakeCommands/target_include_directories/cxx_only/cxx_only.h
new file mode 100644
index 000000000..67289a4fb
--- /dev/null
+++ b/Tests/CMakeCommands/target_include_directories/cxx_only/cxx_only.h
@@ -0,0 +1,2 @@
+
+#define CXX_ONLY_DEFINE
diff --git a/Tests/CMakeCommands/target_include_directories/relative_dir/consumer/consumer.h b/Tests/CMakeCommands/target_include_directories/relative_dir/consumer/consumer.h
new file mode 100644
index 000000000..b91537369
--- /dev/null
+++ b/Tests/CMakeCommands/target_include_directories/relative_dir/consumer/consumer.h
@@ -0,0 +1,2 @@
+
+#define CONSUMER_DEFINE
diff --git a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
index 06019e691..e11f980df 100644
--- a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
@@ -32,7 +32,7 @@ generate_export_header(depA)
add_library(depB SHARED depB.cpp)
generate_export_header(depB)
-target_link_libraries(depB LINK_PRIVATE depA)
+target_link_libraries(depB LINK_PRIVATE depA LINK_PRIVATE depA)
add_library(libgenex SHARED libgenex.cpp)
generate_export_header(libgenex)
@@ -44,11 +44,11 @@ set_property(TARGET depB APPEND PROPERTY
add_library(depC SHARED depC.cpp)
generate_export_header(depC)
-target_link_libraries(depC LINK_PUBLIC depA)
+target_link_libraries(depC LINK_PUBLIC depA LINK_PUBLIC depA)
assert_property(depA LINK_INTERFACE_LIBRARIES "")
assert_property(depB LINK_INTERFACE_LIBRARIES "")
-assert_property(depC LINK_INTERFACE_LIBRARIES "depA")
+assert_property(depC LINK_INTERFACE_LIBRARIES "depA;depA")
add_executable(targetA targetA.cpp)
diff --git a/Tests/CMakeCommands/target_link_libraries/cmp0022/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/cmp0022/CMakeLists.txt
index 818b8c99c..741c73e77 100644
--- a/Tests/CMakeCommands/target_link_libraries/cmp0022/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_link_libraries/cmp0022/CMakeLists.txt
@@ -22,8 +22,18 @@ generate_export_header(staticlib1)
add_library(staticlib2 STATIC staticlib2.cpp)
generate_export_header(staticlib2)
target_link_libraries(staticlib1 LINK_PUBLIC staticlib2)
+
+# Try adding a private link item to be propagated out of a static lib.
+set(private_link "")
if (CMAKE_CXX_COMPILER_ID MATCHES GNU OR CMAKE_CXX_COMPILER_ID MATCHES Clang)
- target_link_libraries(staticlib1 LINK_PRIVATE "-Wl,-v")
+ if (CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+ set(private_link "-Wl,-V")
+ else()
+ set(private_link "-Wl,-v")
+ endif()
+endif()
+if(private_link)
+ target_link_libraries(staticlib1 LINK_PRIVATE "${private_link}")
endif()
add_executable(staticlib_exe staticlib_exe.cpp)
diff --git a/Tests/CMakeCopyright.cmake b/Tests/CMakeCopyright.cmake
new file mode 100644
index 000000000..a7201e97d
--- /dev/null
+++ b/Tests/CMakeCopyright.cmake
@@ -0,0 +1,22 @@
+if(CMAKE_VERSION MATCHES "\\.(20[0-9][0-9])[0-9][0-9][0-9][0-9](-|$)")
+ set(version_year "${CMAKE_MATCH_1}")
+ set(copyright_line_regex "^Copyright 2000-(20[0-9][0-9]) Kitware")
+ file(STRINGS "${CMAKE_CURRENT_LIST_DIR}/../Copyright.txt" copyright_line
+ LIMIT_COUNT 1 REGEX "${copyright_line_regex}")
+ if(copyright_line MATCHES "${copyright_line_regex}")
+ set(copyright_year "${CMAKE_MATCH_1}")
+ if(copyright_year LESS version_year)
+ message(FATAL_ERROR "Copyright.txt contains\n"
+ " ${copyright_line}\n"
+ "but the current version year is ${version_year}.")
+ else()
+ message(STATUS "PASSED: Copyright.txt contains\n"
+ " ${copyright_line}\n"
+ "and the current version year is ${version_year}.")
+ endif()
+ else()
+ message(FATAL_ERROR "Copyright.txt has no Copyright line of expected format!")
+ endif()
+else()
+ message(STATUS "SKIPPED: CMAKE_VERSION does not know the year: ${CMAKE_VERSION}")
+endif()
diff --git a/Tests/CMakeInstall.cmake b/Tests/CMakeInstall.cmake
index 5f814d91b..fda8c54b3 100644
--- a/Tests/CMakeInstall.cmake
+++ b/Tests/CMakeInstall.cmake
@@ -17,29 +17,15 @@ if(CMake_TEST_INSTALL)
if(CMAKE_CONFIGURATION_TYPES)
# There are multiple configurations. Make sure the tested
# configuration is the one that is installed.
- set(CMake_TEST_INSTALL_CONFIG -C "\${CTEST_CONFIGURATION_TYPE}")
+ set(CMake_TEST_INSTALL_CONFIG --config $<CONFIGURATION>)
else()
set(CMake_TEST_INSTALL_CONFIG)
endif()
- # The CTest of the CMake used to build this CMake.
- if(CMAKE_CTEST_COMMAND)
- set(CMake_TEST_INSTALL_CTest ${CMAKE_CTEST_COMMAND})
- else()
- set(CMake_TEST_INSTALL_CTest ${CMake_BIN_DIR}/ctest)
- endif()
-
# Add a test to install CMake through the build system install target.
- add_test(CMake.Install
- ${CMake_TEST_INSTALL_CTest}
- ${CMake_TEST_INSTALL_CONFIG}
- --build-and-test ${CMake_SOURCE_DIR} ${CMake_BINARY_DIR}
- --build-generator ${CMAKE_GENERATOR} # Not CMAKE_TEST_GENERATOR
- --build-project CMake
- --build-makeprogram ${CMAKE_MAKE_PROGRAM} # Not CMAKE_TEST_MAKEPROGRAM
- --build-nocmake
- --build-noclean
- --build-target install)
+ add_test(NAME CMake.Install
+ COMMAND cmake --build . --target install ${CMake_TEST_INSTALL_CONFIG}
+ )
# Avoid running this test simultaneously with other tests:
set_tests_properties(CMake.Install PROPERTIES RUN_SERIAL ON)
diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt
index a831e3015..7ef3c037a 100644
--- a/Tests/CMakeLib/CMakeLists.txt
+++ b/Tests/CMakeLib/CMakeLists.txt
@@ -6,13 +6,16 @@ include_directories(
set(CMakeLib_TESTS
testGeneratedFileStream
+ testRST
testSystemTools
testUTF8
testXMLParser
testXMLSafe
)
-if(WIN32 AND NOT UNIX) # Just if(WIN32) when CMake >= 2.8.4 is required
+set(testRST_ARGS ${CMAKE_CURRENT_SOURCE_DIR})
+
+if(WIN32)
list(APPEND CMakeLib_TESTS
testVisualStudioSlnParser
)
@@ -38,10 +41,12 @@ if(CMAKE_OSX_ARCHITECTURES AND XCODE
endif()
foreach(test ${CMakeLib_TESTS})
- add_test(CMakeLib.${test} CMakeLibTests ${test})
+ add_test(CMakeLib.${test} CMakeLibTests ${test} ${${test}_ARGS})
endforeach()
if(TEST_CompileCommandOutput)
add_executable(runcompilecommands run_compile_commands.cxx)
target_link_libraries(runcompilecommands CMakeLib)
endif()
+
+add_subdirectory(PseudoMemcheck)
diff --git a/Tests/CMakeLib/PseudoMemcheck/CMakeLists.txt b/Tests/CMakeLib/PseudoMemcheck/CMakeLists.txt
new file mode 100644
index 000000000..c53befcb8
--- /dev/null
+++ b/Tests/CMakeLib/PseudoMemcheck/CMakeLists.txt
@@ -0,0 +1,41 @@
+foreach (_retval 0 1)
+ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/memtester.cxx.in" "${CMAKE_CURRENT_BINARY_DIR}/ret${_retval}.cxx" @ONLY)
+endforeach ()
+
+include_directories(${CMake_SOURCE_DIR}/Source ${CMake_BINARY_DIR}/Source)
+
+# create binaries that we will use as a pseudo memory checker
+add_executable(pseudo_valgrind "${CMAKE_CURRENT_BINARY_DIR}/ret0.cxx")
+set_target_properties(pseudo_valgrind PROPERTIES OUTPUT_NAME valgrind)
+target_link_libraries(pseudo_valgrind CMakeLib)
+
+add_executable(pseudo_purify "${CMAKE_CURRENT_BINARY_DIR}/ret0.cxx")
+set_target_properties(pseudo_purify PROPERTIES OUTPUT_NAME purify)
+target_link_libraries(pseudo_purify CMakeLib)
+add_executable(pseudo_BC "${CMAKE_CURRENT_BINARY_DIR}/ret0.cxx")
+set_target_properties(pseudo_BC PROPERTIES OUTPUT_NAME BC)
+target_link_libraries(pseudo_BC CMakeLib)
+
+# binary to be used as pre- and post-memcheck command that fails
+add_executable(memcheck_fail "${CMAKE_CURRENT_BINARY_DIR}/ret1.cxx")
+target_link_libraries(memcheck_fail CMakeLib)
+
+# Binaries that are used as memchecker that do not write the expected
+# output file. Need to be in their own subdirectory as they have the
+# same filenames.
+add_subdirectory(NoLog)
+
+# Xcode 2.x forgets to create the output directory before linking
+# the individual architectures.
+if(CMAKE_OSX_ARCHITECTURES AND XCODE AND NOT "${XCODE_VERSION}" MATCHES "^[^12]")
+ foreach(t
+ memcheck_fail
+ pseudo_BC
+ pseudo_purify
+ pseudo_valgrind
+ )
+ add_custom_command(TARGET ${t}
+ PRE_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CFG_INTDIR}"
+ )
+ endforeach()
+endif()
diff --git a/Tests/CMakeLib/PseudoMemcheck/NoLog/CMakeLists.txt b/Tests/CMakeLib/PseudoMemcheck/NoLog/CMakeLists.txt
new file mode 100644
index 000000000..3a45bfecc
--- /dev/null
+++ b/Tests/CMakeLib/PseudoMemcheck/NoLog/CMakeLists.txt
@@ -0,0 +1,22 @@
+# A dummy checker implementation that does not write the requested output file
+# so it triggers an error for every checker.
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/ret0.c.in" "int main(){return 0;}\n")
+
+configure_file(
+ "${CMAKE_CURRENT_BINARY_DIR}/ret0.c.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/ret0.c"
+ )
+
+foreach(_pseudo IN ITEMS valgrind purify BC)
+ add_executable(pseudonl_${_pseudo} "${CMAKE_CURRENT_BINARY_DIR}/ret0.c")
+ set_target_properties(pseudonl_${_pseudo} PROPERTIES OUTPUT_NAME ${_pseudo})
+
+ # Xcode 2.x forgets to create the output directory before linking
+ # the individual architectures.
+ if(CMAKE_OSX_ARCHITECTURES AND XCODE AND NOT "${XCODE_VERSION}" MATCHES "^[^12]")
+ add_custom_command(TARGET pseudonl_${_pseudo}
+ PRE_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CFG_INTDIR}"
+ )
+ endif()
+endforeach()
diff --git a/Tests/CMakeLib/PseudoMemcheck/memtester.cxx.in b/Tests/CMakeLib/PseudoMemcheck/memtester.cxx.in
new file mode 100644
index 000000000..c018e0862
--- /dev/null
+++ b/Tests/CMakeLib/PseudoMemcheck/memtester.cxx.in
@@ -0,0 +1,58 @@
+#include <cmSystemTools.h>
+#include <cmsys/Encoding.hxx>
+#include <string>
+
+#define RETVAL @_retval@
+
+int
+main(int ac, char **av)
+{
+ cmsys::Encoding::CommandLineArguments args =
+ cmsys::Encoding::CommandLineArguments::Main(ac, av);
+ int argc = args.argc();
+ const char* const* argv = args.argv();
+
+ std::string exename = argv[0];
+ std::string logarg;
+ bool nextarg = false;
+
+ if (exename.find("valgrind") != exename.npos)
+ logarg = "--log-file=";
+ else if (exename.find("purify") != exename.npos)
+#ifdef _WIN32
+ logarg = "/SAVETEXTDATA=";
+#else
+ logarg = "-log-file=";
+#endif
+ else if (exename.find("BC") != exename.npos)
+ {
+ nextarg = true;
+ logarg = "/X";
+ }
+
+ if (!logarg.empty()) {
+ std::string logfile;
+ for (int i = 1; i < argc; i++) {
+ std::string arg = argv[i];
+ if (arg.find(logarg) == 0)
+ {
+ if (nextarg)
+ {
+ if (i == argc - 1)
+ return 1; // invalid command line
+ logfile = argv[i + 1];
+ }
+ else
+ {
+ logfile = arg.substr(logarg.length());
+ }
+ // keep searching, it may be overridden later to provoke an error
+ }
+ }
+
+ if (!logfile.empty())
+ cmSystemTools::Touch(logfile.c_str(), true);
+ }
+
+ return RETVAL;
+}
diff --git a/Tests/CMakeLib/run_compile_commands.cxx b/Tests/CMakeLib/run_compile_commands.cxx
index dc1ce24f7..26ab223dc 100644
--- a/Tests/CMakeLib/run_compile_commands.cxx
+++ b/Tests/CMakeLib/run_compile_commands.cxx
@@ -2,14 +2,14 @@
class CompileCommandParser {
public:
- class CommandType: public std::map<cmStdString, cmStdString>
+ class CommandType: public std::map<std::string, std::string>
{
public:
- cmStdString const& at(cmStdString const& k) const
+ std::string const& at(std::string const& k) const
{
const_iterator i = this->find(k);
if(i != this->end()) { return i->second; }
- static cmStdString emptyString;
+ static std::string emptyString;
return emptyString;
}
};
@@ -127,10 +127,10 @@ int main ()
it = parser.GetTranslationUnits().begin(),
end = parser.GetTranslationUnits().end(); it != end; ++it)
{
- std::vector<cmStdString> command;
+ std::vector<std::string> command;
cmSystemTools::ParseUnixCommandLine(it->at("command").c_str(), command);
if (!cmSystemTools::RunSingleCommand(
- command, 0, 0, it->at("directory").c_str()))
+ command, 0, 0, 0, it->at("directory").c_str()))
{
std::cout << "ERROR: Failed to run command \""
<< command[0] << "\"" << std::endl;
diff --git a/Tests/CMakeLib/testRST.cxx b/Tests/CMakeLib/testRST.cxx
new file mode 100644
index 000000000..37cb3faab
--- /dev/null
+++ b/Tests/CMakeLib/testRST.cxx
@@ -0,0 +1,101 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2013 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmRST.h"
+
+#include "cmSystemTools.h"
+
+void reportLine(std::ostream& os, bool ret, std::string line, bool eol)
+{
+ if(ret)
+ {
+ os << "\"" << line << "\" (" << (eol?"with EOL":"without EOL") << ")";
+ }
+ else
+ {
+ os << "EOF";
+ }
+}
+
+int testRST(int argc, char* argv[])
+{
+ if(argc != 2)
+ {
+ std::cerr << "Usage: testRST <dir>" << std::endl;
+ return 1;
+ }
+ std::string dir = argv[1];
+ if(dir.empty())
+ {
+ dir = ".";
+ }
+ std::string a_name = "testRST.actual";
+ std::string e_name = dir + "/testRST.expect";
+
+ // Process the test RST file.
+ {
+ std::string fname = dir + "/testRST.rst";
+ std::ofstream fout(a_name.c_str());
+ if(!fout)
+ {
+ std::cerr << "Could not open output " << a_name << std::endl;
+ return 1;
+ }
+
+ cmRST r(fout, dir);
+ if(!r.ProcessFile(fname))
+ {
+ std::cerr << "Could not open input " << fname << std::endl;
+ return 1;
+ }
+ }
+
+ // Compare expected and actual outputs.
+ std::ifstream e_fin(e_name.c_str());
+ std::ifstream a_fin(a_name.c_str());
+ if(!e_fin)
+ {
+ std::cerr << "Could not open input " << e_name << std::endl;
+ return 1;
+ }
+ if(!a_fin)
+ {
+ std::cerr << "Could not open input " << a_name << std::endl;
+ return 1;
+ }
+ int lineno = 0;
+ bool e_ret;
+ bool a_ret;
+ do
+ {
+ std::string e_line;
+ std::string a_line;
+ bool e_eol;
+ bool a_eol;
+ e_ret = cmSystemTools::GetLineFromStream(e_fin, e_line, &e_eol);
+ a_ret = cmSystemTools::GetLineFromStream(a_fin, a_line, &a_eol);
+ ++lineno;
+ if(e_ret != a_ret || e_line != a_line || e_eol != a_eol)
+ {
+ a_fin.seekg(0, std::ios::beg);
+ std::cerr << "Actual output does not match that expected on line "
+ << lineno << "." << std::endl << "Expected ";
+ reportLine(std::cerr, e_ret, e_line, e_eol);
+ std::cerr << " but got ";
+ reportLine(std::cerr, a_ret, a_line, a_eol);
+ std::cerr << "." << std::endl
+ << "Actual output:" << std::endl
+ << a_fin.rdbuf();
+ return 1;
+ }
+ } while(e_ret && a_ret);
+ return 0;
+}
diff --git a/Tests/CMakeLib/testRST.expect b/Tests/CMakeLib/testRST.expect
new file mode 100644
index 000000000..fa436cb91
--- /dev/null
+++ b/Tests/CMakeLib/testRST.expect
@@ -0,0 +1,92 @@
+title_text
+----------
+
+Command ``some_cmd()`` explicit cmake domain.
+Command ``some_cmd()`` without target.
+Command ``some_cmd`` with target.
+Command ``some_cmd_<cmd>()`` placeholder without target.
+Command ``some_cmd_<cmd>`` placholder with target.
+Command ``some_cmd()`` with parens.
+Command ``some_cmd(SUB)`` with subcommand.
+Command ``some_cmd(SUB)`` with subcommand and target.
+Command ``some_cmd (SUB)`` with space and subcommand and target.
+Command ``some command`` with space and target.
+Variable ``some variable`` space and target.
+Variable ``<PLACEHOLDER>_VARIABLE`` with leading placeholder.
+Variable ``VARIABLE_<PLACEHOLDER>`` with trailing placeholder.
+Variable ``<PLACEHOLDER>_VARIABLE`` with leading placeholder and target.
+Variable ``VARIABLE_<PLACEHOLDER>`` with trailing placeholder and target.
+Generator ``Some Generator`` with space.
+
+First TOC entry.
+
+|not replaced|
+Second TOC entry.
+
+CMake Module Content
+
+More CMake Module Content
+
+Bracket Comment Content
+
+[
+Bracket Comment Content
+]
+
+.. cmake:command:: some_cmd
+
+ Command some_cmd description.
+
+.. command:: other_cmd
+
+ Command other_cmd description.
+
+.. cmake:variable:: some_var
+
+ Variable some_var description.
+
+.. variable:: other_var
+
+ Variable other_var description.
+
+ Parsed-literal included without directive.
+ Common Indentation Removed
+ # replaced in parsed literal
+
+ # Sample CMake code block
+ if(condition)
+ message(indented)
+ endif()
+ # |not replaced in literal|
+
+A literal block starts after a line consisting of two colons
+
+::
+
+ Literal block.
+ Common Indentation Removed
+ # |not replaced in literal|
+
+or after a paragraph ending in two colons::
+
+ Literal block.
+ Common Indentation Removed
+ # |not replaced in literal|
+
+but not after a line ending in two colons::
+in the middle of a paragraph.
+
+.. productionlist::
+ grammar: `production`
+ production: "content rendered"
+
+.. note::
+ Notes are called out.
+
+substituted text with multiple lines becomes one line
+
+End of first include.
+
+Cross-include substitution text with ``some_cmd()`` reference.
+
+End of second include.
diff --git a/Tests/CMakeLib/testRST.rst b/Tests/CMakeLib/testRST.rst
new file mode 100644
index 000000000..54952dd9f
--- /dev/null
+++ b/Tests/CMakeLib/testRST.rst
@@ -0,0 +1,99 @@
+.. index::
+ single: directive ignored
+
+title_text
+----------
+
+.. comment ignored
+..
+ comment ignored
+
+Command :cmake:command:`some_cmd` explicit cmake domain.
+Command :command:`some_cmd` without target.
+Command :command:`some_cmd <some_cmd>` with target.
+Command :command:`some_cmd_<cmd>` placeholder without target.
+Command :command:`some_cmd_<cmd> <some_cmd>` placholder with target.
+Command :command:`some_cmd()` with parens.
+Command :command:`some_cmd(SUB)` with subcommand.
+Command :command:`some_cmd(SUB) <some_cmd>` with subcommand and target.
+Command :command:`some_cmd (SUB) <some_cmd>` with space and subcommand and target.
+Command :command:`some command <some_cmd>` with space and target.
+Variable :variable:`some variable <some_var>` space and target.
+Variable :variable:`<PLACEHOLDER>_VARIABLE` with leading placeholder.
+Variable :variable:`VARIABLE_<PLACEHOLDER>` with trailing placeholder.
+Variable :variable:`<PLACEHOLDER>_VARIABLE <target>` with leading placeholder and target.
+Variable :variable:`VARIABLE_<PLACEHOLDER> <target>` with trailing placeholder and target.
+Generator :generator:`Some Generator` with space.
+
+.. |not replaced| replace:: not replaced through toctree
+.. |not replaced in literal| replace:: replaced in parsed literal
+
+.. toctree::
+ :maxdepth: 2
+
+ testRSTtoc1
+ /testRSTtoc2
+
+.. cmake-module:: testRSTmod.cmake
+
+.. cmake:command:: some_cmd
+
+ Command some_cmd description.
+
+.. command:: other_cmd
+
+ Command other_cmd description.
+
+.. cmake:variable:: some_var
+
+ Variable some_var description.
+
+.. variable:: other_var
+
+ Variable other_var description.
+
+.. parsed-literal::
+
+ Parsed-literal included without directive.
+ Common Indentation Removed
+ # |not replaced in literal|
+
+.. code-block:: cmake
+
+ # Sample CMake code block
+ if(condition)
+ message(indented)
+ endif()
+ # |not replaced in literal|
+
+A literal block starts after a line consisting of two colons
+
+::
+
+ Literal block.
+ Common Indentation Removed
+ # |not replaced in literal|
+
+or after a paragraph ending in two colons::
+
+ Literal block.
+ Common Indentation Removed
+ # |not replaced in literal|
+
+but not after a line ending in two colons::
+in the middle of a paragraph.
+
+.. productionlist::
+ grammar: `production`
+ production: "content rendered"
+
+.. note::
+ Notes are called out.
+
+.. |substitution| replace::
+ |nested substitution|
+ with multiple lines becomes one line
+.. |nested substitution| replace:: substituted text
+
+.. include:: testRSTinclude1.rst
+.. include:: /testRSTinclude2.rst
diff --git a/Tests/CMakeLib/testRSTinclude1.rst b/Tests/CMakeLib/testRSTinclude1.rst
new file mode 100644
index 000000000..91d394e3a
--- /dev/null
+++ b/Tests/CMakeLib/testRSTinclude1.rst
@@ -0,0 +1,6 @@
+|substitution|
+
+.. |cross-include substitution| replace:: Cross-include substitution text
+ with :command:`some_cmd` reference.
+
+End of first include.
diff --git a/Tests/CMakeLib/testRSTinclude2.rst b/Tests/CMakeLib/testRSTinclude2.rst
new file mode 100644
index 000000000..f2d619c4f
--- /dev/null
+++ b/Tests/CMakeLib/testRSTinclude2.rst
@@ -0,0 +1,3 @@
+|cross-include substitution|
+
+End of second include.
diff --git a/Tests/CMakeLib/testRSTmod.cmake b/Tests/CMakeLib/testRSTmod.cmake
new file mode 100644
index 000000000..8b807a605
--- /dev/null
+++ b/Tests/CMakeLib/testRSTmod.cmake
@@ -0,0 +1,11 @@
+#.rst:
+# CMake Module Content
+#.rst:
+# More CMake Module Content
+#[[.rst:
+Bracket Comment Content
+# not part of content]] # not part of content
+#[=[.rst:
+[
+Bracket Comment Content
+]]=] # not part of content
diff --git a/Tests/CMakeLib/testRSTtoc1.rst b/Tests/CMakeLib/testRSTtoc1.rst
new file mode 100644
index 000000000..fa7806ede
--- /dev/null
+++ b/Tests/CMakeLib/testRSTtoc1.rst
@@ -0,0 +1,2 @@
+.. |not replaced| replace:: not replaced across toctree
+First TOC entry.
diff --git a/Tests/CMakeLib/testRSTtoc2.rst b/Tests/CMakeLib/testRSTtoc2.rst
new file mode 100644
index 000000000..9fd2fcb19
--- /dev/null
+++ b/Tests/CMakeLib/testRSTtoc2.rst
@@ -0,0 +1,2 @@
+|not replaced|
+Second TOC entry.
diff --git a/Tests/CMakeLib/testVisualStudioSlnParser.cxx b/Tests/CMakeLib/testVisualStudioSlnParser.cxx
index 5b62f239f..5007ab872 100644
--- a/Tests/CMakeLib/testVisualStudioSlnParser.cxx
+++ b/Tests/CMakeLib/testVisualStudioSlnParser.cxx
@@ -3,7 +3,7 @@
#include "cmVisualStudioSlnData.h"
#include "cmVisualStudioSlnParser.h"
-#include <cmsys/ios/iostream>
+#include <iostream>
//----------------------------------------------------------------------------
static bool parsedRight(cmVisualStudioSlnParser& parser,
@@ -27,10 +27,10 @@ static bool parsedRight(cmVisualStudioSlnParser& parser,
return true;
}
}
- cmsys_ios::cerr << "cmVisualStudioSlnParser mis-parsed " << file
- << "." SLN_EXTENSION << "; expected result " << expected
- << ", got " << parser.GetParseResult()
- << cmsys_ios::endl;
+ std::cerr << "cmVisualStudioSlnParser mis-parsed " << file
+ << "." SLN_EXTENSION << "; expected result " << expected
+ << ", got " << parser.GetParseResult()
+ << std::endl;
return false;
}
@@ -42,8 +42,8 @@ int testVisualStudioSlnParser(int, char*[])
// Test clean parser
if (parser.GetParseResult() != cmVisualStudioSlnParser::ResultOK)
{
- cmsys_ios::cerr << "cmVisualStudioSlnParser initialisation failed"
- << cmsys_ios::endl;
+ std::cerr << "cmVisualStudioSlnParser initialisation failed"
+ << std::endl;
return 1;
}
@@ -73,38 +73,38 @@ int testVisualStudioSlnParser(int, char*[])
const size_t expectedProjectCount = sizeof(names) / sizeof(*names);
if (projects.size() != expectedProjectCount)
{
- cmsys_ios::cerr << "cmVisualStudioSlnParser returned bad number of "
- << "projects (" << projects.size() << " instead of "
- << expectedProjectCount << ')'
- << cmsys_ios::endl;
+ std::cerr << "cmVisualStudioSlnParser returned bad number of "
+ << "projects (" << projects.size() << " instead of "
+ << expectedProjectCount << ')'
+ << std::endl;
return 1;
}
for (size_t idx = 0; idx < expectedProjectCount; ++idx)
{
if (projects[idx].GetName() != names[idx])
{
- cmsys_ios::cerr << "cmVisualStudioSlnParser returned bad project #"
- << idx << "; expected \"" << names[idx] << "\", got \""
- << projects[idx].GetName() << '"'
- << cmsys_ios::endl;
+ std::cerr << "cmVisualStudioSlnParser returned bad project #"
+ << idx << "; expected \"" << names[idx] << "\", got \""
+ << projects[idx].GetName() << '"'
+ << std::endl;
return 1;
}
}
if (projects[0].GetRelativePath() != "Utilities\\3rdParty")
{
- cmsys_ios::cerr << "cmVisualStudioSlnParser returned bad relative path of "
- << "project 3rdParty; expected \"Utilities\\3rdParty\", "
- << "got \"" << projects[0].GetRelativePath() << '"'
- << cmsys_ios::endl;
+ std::cerr << "cmVisualStudioSlnParser returned bad relative path of "
+ << "project 3rdParty; expected \"Utilities\\3rdParty\", "
+ << "got \"" << projects[0].GetRelativePath() << '"'
+ << std::endl;
return 1;
}
if (projects[2].GetGUID() != "{59BCCCCD-3AD1-4491-B8F4-C5793AC007E2}")
{
- cmsys_ios::cerr << "cmVisualStudioSlnParser returned bad relative path of "
- << "project CMakeLib; expected "
- << "\"{59BCCCCD-3AD1-4491-B8F4-C5793AC007E2}\", "
- << "got \"" << projects[2].GetGUID() << '"'
- << cmsys_ios::endl;
+ std::cerr << "cmVisualStudioSlnParser returned bad relative path of "
+ << "project CMakeLib; expected "
+ << "\"{59BCCCCD-3AD1-4491-B8F4-C5793AC007E2}\", "
+ << "got \"" << projects[2].GetGUID() << '"'
+ << std::endl;
return 1;
}
}
@@ -119,9 +119,9 @@ int testVisualStudioSlnParser(int, char*[])
}
if (!parser.GetParseHadBOM())
{
- cmsys_ios::cerr << "cmVisualStudioSlnParser didn't find BOM in bom."
- << SLN_EXTENSION
- << cmsys_ios::endl;
+ std::cerr << "cmVisualStudioSlnParser didn't find BOM in bom."
+ << SLN_EXTENSION
+ << std::endl;
return 1;
}
@@ -131,9 +131,9 @@ int testVisualStudioSlnParser(int, char*[])
}
if (parser.GetParseHadBOM())
{
- cmsys_ios::cerr << "cmVisualStudioSlnParser found BOM in nobom."
- << SLN_EXTENSION
- << cmsys_ios::endl;
+ std::cerr << "cmVisualStudioSlnParser found BOM in nobom."
+ << SLN_EXTENSION
+ << std::endl;
return 1;
}
}
diff --git a/Tests/CMakeLib/testXMLParser.cxx b/Tests/CMakeLib/testXMLParser.cxx
index 54ed5dc90..b5219e245 100644
--- a/Tests/CMakeLib/testXMLParser.cxx
+++ b/Tests/CMakeLib/testXMLParser.cxx
@@ -2,7 +2,7 @@
#include "cmXMLParser.h"
-#include <cmsys/ios/iostream>
+#include <iostream>
int testXMLParser(int, char*[])
{
@@ -10,7 +10,7 @@ int testXMLParser(int, char*[])
cmXMLParser parser;
if(!parser.ParseFile(SOURCE_DIR "/testXMLParser.xml"))
{
- cmsys_ios::cerr << "cmXMLParser failed!" << cmsys_ios::endl;
+ std::cerr << "cmXMLParser failed!" << std::endl;
return 1;
}
return 0;
diff --git a/Tests/CMakeLib/testXMLSafe.cxx b/Tests/CMakeLib/testXMLSafe.cxx
index 60442fab7..9e4960c18 100644
--- a/Tests/CMakeLib/testXMLSafe.cxx
+++ b/Tests/CMakeLib/testXMLSafe.cxx
@@ -34,7 +34,7 @@ int testXMLSafe(int, char*[])
for(test_pair const* p = pairs; p->in; ++p)
{
cmXMLSafe xs(p->in);
- cmOStringStream oss;
+ std::ostringstream oss;
oss << xs;
std::string out = oss.str();
if(out != p->out)
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 9c3ed594f..7bb072156 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -3,20 +3,20 @@
macro(ADD_TEST_MACRO NAME COMMAND)
string(REPLACE "." "/" dir "${NAME}")
string(REGEX REPLACE "[^.]*\\." "" proj "${NAME}")
- add_test(${NAME} ${CMAKE_CTEST_COMMAND}
+ add_test(NAME "${NAME}" COMMAND "${CMAKE_CTEST_COMMAND}"
--build-and-test
"${CMake_SOURCE_DIR}/Tests/${dir}"
"${CMake_BINARY_DIR}/Tests/${dir}"
--build-two-config
${build_generator_args}
--build-project ${proj}
- ${${NAME}_EXTRA_OPTIONS}
+ ${${NAME}_CTEST_OPTIONS}
+ --build-options ${build_options}
+ ${${NAME}_BUILD_OPTIONS}
--test-command ${COMMAND} ${ARGN})
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${dir}")
endmacro()
-include(${CMAKE_CURRENT_SOURCE_DIR}/RegexEscapeString.cmake)
-
include(${CMAKE_CURRENT_SOURCE_DIR}/CheckFortran.cmake)
# Fake a user home directory to avoid polluting the real one.
@@ -43,13 +43,29 @@ configure_file(${CMake_SOURCE_DIR}/Tests/EnforceConfig.cmake.in
# Testing
if(BUILD_TESTING)
- if("${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles" OR ("${CMAKE_TEST_GENERATOR}" MATCHES Ninja AND NOT WIN32))
- set(TEST_CompileCommandOutput 1)
+ set(CMake_TEST_DEVENV "")
+ if(CMAKE_VS_DEVENV_COMMAND)
+ set(CMake_TEST_DEVENV "${CMAKE_VS_DEVENV_COMMAND}")
+ elseif(CMAKE_GENERATOR MATCHES "Visual Studio [7-9] " AND
+ NOT CMAKE_MAKE_PROGRAM MATCHES "[mM][sS][bB][uU][iI][lL][dD]\\.[eE][xX][eE]")
+ set(CMake_TEST_DEVENV "${CMAKE_MAKE_PROGRAM}")
+ endif()
+
+ if(CMAKE_GENERATOR MATCHES "Visual Studio|Xcode")
+ set(CMake_TEST_EXPLICIT_MAKE_PROGRAM "")
+ else()
+ set(CMake_TEST_EXPLICIT_MAKE_PROGRAM "${CMAKE_MAKE_PROGRAM}")
+ endif()
+
+ if(NOT CMake_TEST_EXTERNAL_CMAKE)
+ if("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles" OR ("${CMAKE_GENERATOR}" MATCHES Ninja AND NOT WIN32))
+ set(TEST_CompileCommandOutput 1)
+ endif()
endif()
set(MAKE_IS_GNU )
- if(${CMAKE_TEST_MAKEPROGRAM} MATCHES make)
- execute_process(COMMAND ${CMAKE_TEST_MAKEPROGRAM} no_such_target --version
+ if(CMAKE_MAKE_PROGRAM MATCHES make)
+ execute_process(COMMAND ${CMAKE_MAKE_PROGRAM} no_such_target --version
RESULT_VARIABLE res OUTPUT_VARIABLE out ERROR_VARIABLE out)
if("${res}" STREQUAL "0")
if("${out}" MATCHES "GNU")
@@ -60,31 +76,67 @@ if(BUILD_TESTING)
# some old versions of make simply cannot handle spaces in paths
if (MAKE_IS_GNU OR
- "${CMAKE_TEST_MAKEPROGRAM}" MATCHES "nmake|gmake|wmake" OR
- "${CMAKE_TEST_GENERATOR}" MATCHES "Visual Studio|XCode|Borland")
+ CMAKE_MAKE_PROGRAM MATCHES "nmake|gmake|wmake" OR
+ CMAKE_GENERATOR MATCHES "Visual Studio|Xcode|Borland")
set(MAKE_SUPPORTS_SPACES 1)
else()
set(MAKE_SUPPORTS_SPACES 0)
endif()
set(build_generator_args
- --build-generator ${CMAKE_TEST_GENERATOR}
- --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-generator ${CMAKE_GENERATOR}
)
- if(CMAKE_TEST_GENERATOR_TOOLSET)
+ if(CMAKE_GENERATOR_PLATFORM)
list(APPEND build_generator_args
- --build-generator-toolset ${CMAKE_TEST_GENERATOR_TOOLSET}
+ --build-generator-platform ${CMAKE_GENERATOR_PLATFORM}
)
endif()
+ if(CMAKE_GENERATOR_TOOLSET)
+ list(APPEND build_generator_args
+ --build-generator-toolset ${CMAKE_GENERATOR_TOOLSET}
+ )
+ endif()
+
+ set(build_options)
+ if(CMake_TEST_EXPLICIT_MAKE_PROGRAM)
+ list(APPEND build_options -DCMAKE_MAKE_PROGRAM:FILEPATH=${CMake_TEST_EXPLICIT_MAKE_PROGRAM})
+ endif()
+
+ # Look for rpmbuild to use for tests.
+ # The tool does not work with spaces in the path.
+ if(NOT CMAKE_CURRENT_BINARY_DIR MATCHES " ")
+ find_program(RPMBUILD_EXECUTABLE NAMES rpmbuild)
+ else()
+ set(RPMBUILD_EXECUTABLE "RPMBUILD_EXECUTABLE-NOTFOUND")
+ endif()
+
+ if(RPMBUILD_EXECUTABLE)
+ set(CPACK_BINARY_RPM ON)
+ else()
+ set(CPACK_BINARY_RPM OFF)
+ endif()
+
+ # Look for rpmbuild to use for tests.
+ # The tool does not work with spaces in the path.
+ find_program(DPKG_EXECUTABLE NAMES dpkg)
+
+ if(DPKG_EXECUTABLE)
+ set(CPACK_BINARY_DEB ON)
+ else()
+ set(CPACK_BINARY_DEB OFF)
+ endif()
- add_subdirectory(CMakeLib)
+ #---------------------------------------------------------------------------
+ # Add tests below here.
+
+ if(NOT CMake_TEST_EXTERNAL_CMAKE)
+ add_subdirectory(CMakeLib)
+ endif()
add_subdirectory(CMakeOnly)
add_subdirectory(RunCMake)
add_subdirectory(FindPackageModeMakefileTest)
- add_subdirectory(CTestTestMemcheck)
-
# Collect a list of all test build directories.
set(TEST_BUILD_DIRS)
@@ -136,19 +188,54 @@ if(BUILD_TESTING)
ON)
mark_as_advanced(CTEST_TEST_CPACK)
set(CTEST_TEST_OSX_ARCH 0)
+ set(CMake_TEST_XCODE_VERSION 0)
if(APPLE)
execute_process(
COMMAND sw_vers -productVersion
OUTPUT_VARIABLE OSX_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
- if(OSX_VERSION MATCHES "^10\\.[0123]" OR OSX_VERSION MATCHES "ProductVersion:\t10\\.[0123]")
+ if(OSX_VERSION VERSION_LESS 10.4)
message(STATUS "Forcing CTEST_TEST_CPACK=OFF on OSX < 10.4")
message(STATUS "OSX_VERSION='${OSX_VERSION}'")
set(CTEST_TEST_CPACK OFF)
else()
set(CTEST_TEST_OSX_ARCH 1)
endif()
+ if(XCODE_VERSION)
+ set(CMake_TEST_XCODE_VERSION "${XCODE_VERSION}")
+ else()
+ execute_process(
+ COMMAND xcodebuild -version
+ OUTPUT_VARIABLE _version ERROR_VARIABLE _version
+ )
+ if(_version MATCHES "^Xcode ([0-9]+(\\.[0-9]+)*)")
+ set(CMake_TEST_XCODE_VERSION "${CMAKE_MATCH_1}")
+ endif()
+ endif()
+ if(CMAKE_OSX_SYSROOT)
+ execute_process(
+ COMMAND xcodebuild -sdk ${CMAKE_OSX_SYSROOT} -version ProductName
+ OUTPUT_VARIABLE _stdout
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_VARIABLE _stderr
+ RESULT_VARIABLE _failed
+ )
+ if(NOT _failed)
+ set(CMAKE_OSX_SDKPRODUCT "${_stdout}")
+ endif()
+
+ execute_process(
+ COMMAND xcodebuild -sdk ${CMAKE_OSX_SYSROOT} -version SDKVersion
+ OUTPUT_VARIABLE _stdout
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_VARIABLE _stderr
+ RESULT_VARIABLE _failed
+ )
+ if(NOT _failed)
+ set(CMAKE_OSX_SDKVERSION "${_stdout}")
+ endif()
+ endif()
endif()
# Use 1500 or CTEST_TEST_TIMEOUT for long test timeout value,
@@ -161,15 +248,20 @@ if(BUILD_TESTING)
set(CMAKE_LONG_TEST_TIMEOUT 1500)
endif()
+ add_test(NAME CMake.Copyright
+ COMMAND cmake -P ${CMAKE_CURRENT_SOURCE_DIR}/CMakeCopyright.cmake)
+
# add a bunch of standard build-and-test style tests
ADD_TEST_MACRO(CommandLineTest CommandLineTest)
ADD_TEST_MACRO(FindPackageTest FindPackageTest)
ADD_TEST_MACRO(FindModulesExecuteAll FindModulesExecuteAll)
ADD_TEST_MACRO(StringFileTest StringFileTest)
ADD_TEST_MACRO(TryCompile TryCompile)
- ADD_TEST_MACRO(TarTest TarTest)
ADD_TEST_MACRO(SystemInformation SystemInformation)
ADD_TEST_MACRO(MathTest MathTest)
+ ADD_TEST_MACRO(CompileFeatures CompileFeatures)
+ ADD_TEST_MACRO(CMakeCommands.target_compile_features target_compile_features)
+
# assume no resources building to test
set(TEST_RESOURCES FALSE)
# for windows and cygwin assume we have resources
@@ -177,18 +269,28 @@ if(BUILD_TESTING)
set(TEST_RESOURCES TRUE)
endif()
# for borland and watcom there is no resource support
- if("${CMAKE_TEST_GENERATOR}" MATCHES "WMake" OR
- "${CMAKE_TEST_GENERATOR}" MATCHES "Borland")
+ if(WATCOM OR BORLAND)
set(TEST_RESOURCES FALSE)
endif()
if(TEST_RESOURCES)
ADD_TEST_MACRO(VSResource VSResource)
endif()
+ ADD_TEST_MACRO(MSManifest MSManifest)
ADD_TEST_MACRO(Simple Simple)
ADD_TEST_MACRO(PreOrder PreOrder)
ADD_TEST_MACRO(MissingSourceFile MissingSourceFile)
set_tests_properties(MissingSourceFile PROPERTIES
PASS_REGULAR_EXPRESSION "CMake Error at CMakeLists.txt:3 \\(add_executable\\):[ \r\n]*Cannot find source file:[ \r\n]*DoesNotExist/MissingSourceFile.c")
+ if(CMake_TEST_XCODE_VERSION AND CMAKE_OSX_SDKVERSION AND CMAKE_OSX_SDKPRODUCT)
+ if((NOT CMake_TEST_XCODE_VERSION VERSION_LESS 6.1) AND
+ ((NOT CMAKE_OSX_SDKPRODUCT STREQUAL "Mac OS X") OR
+ (NOT CMAKE_OSX_SDKVERSION VERSION_LESS 10.10)))
+ if(CMAKE_GENERATOR STREQUAL "Xcode")
+ ADD_TEST_MACRO(SwiftMix SwiftMix)
+ ADD_TEST_MACRO(SwiftOnly SwiftOnly)
+ endif()
+ endif()
+ endif()
if(CMAKE_Fortran_COMPILER)
ADD_TEST_MACRO(FortranOnly FortranOnly)
endif()
@@ -220,6 +322,7 @@ if(BUILD_TESTING)
endif()
ADD_TEST_MACRO(COnly COnly)
ADD_TEST_MACRO(CxxOnly CxxOnly)
+ ADD_TEST_MACRO(CxxSubdirC CxxSubdirC)
ADD_TEST_MACRO(IPO COnly/COnly)
ADD_TEST_MACRO(OutDir runtime/OutDir)
ADD_TEST_MACRO(ObjectLibrary UseCshared)
@@ -227,7 +330,9 @@ if(BUILD_TESTING)
ADD_TEST_MACRO(SetLang SetLang)
ADD_TEST_MACRO(EmptyProperty EmptyProperty)
ADD_TEST_MACRO(ExternalOBJ ExternalOBJ)
- ADD_TEST_MACRO(LoadCommand LoadedCommand)
+ if(NOT CMake_TEST_EXTERNAL_CMAKE)
+ ADD_TEST_MACRO(LoadCommand LoadedCommand)
+ endif()
ADD_TEST_MACRO(LinkDirectory bin/LinkDirectory)
ADD_TEST_MACRO(LinkLanguage LinkLanguage)
ADD_TEST_MACRO(LinkLine LinkLine)
@@ -238,6 +343,7 @@ if(BUILD_TESTING)
ADD_TEST_MACRO(Assembler HelloAsm)
ADD_TEST_MACRO(SourceGroups SourceGroups)
ADD_TEST_MACRO(Preprocess Preprocess)
+ set(ExportImport_BUILD_OPTIONS -DCMake_TEST_NESTED_MAKE_PROGRAM:FILEPATH=${CMake_TEST_EXPLICIT_MAKE_PROGRAM})
ADD_TEST_MACRO(ExportImport ExportImport)
ADD_TEST_MACRO(Unset Unset)
ADD_TEST_MACRO(PolicyScope PolicyScope)
@@ -246,12 +352,33 @@ if(BUILD_TESTING)
ADD_TEST_MACRO(CompileOptions CompileOptions)
ADD_TEST_MACRO(CompatibleInterface CompatibleInterface)
ADD_TEST_MACRO(AliasTarget AliasTarget)
+ ADD_TEST_MACRO(StagingPrefix StagingPrefix)
+ ADD_TEST_MACRO(InterfaceLibrary InterfaceLibrary)
+ if (CMAKE_BUILD_TYPE MATCHES "[Dd][Ee][Bb][Uu][Gg]")
+ set(ConfigSources_BUILD_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
+ ADD_TEST_MACRO(ConfigSources ConfigSources)
+ endif()
+ ADD_TEST_MACRO(SourcesProperty SourcesProperty)
+ ADD_TEST_MACRO(SourceFileProperty SourceFileProperty)
+ if(CMAKE_CXX_COMPILER_ID STREQUAL GNU
+ AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7)
+ set(runCxxDialectTest 1)
+ endif()
+ if(CMAKE_CXX_COMPILER_ID STREQUAL Clang
+ AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4)
+ if(NOT APPLE OR POLICY CMP0025)
+ set(runCxxDialectTest 1)
+ endif()
+ endif()
+ if(runCxxDialectTest)
+ ADD_TEST_MACRO(CxxDialect CxxDialect)
+ endif()
set_tests_properties(EmptyLibrary PROPERTIES
PASS_REGULAR_EXPRESSION "CMake Error: CMake can not determine linker language for target: test")
ADD_TEST_MACRO(CrossCompile CrossCompile)
set_tests_properties(CrossCompile PROPERTIES
PASS_REGULAR_EXPRESSION "TRY_RUN.. invoked in cross-compiling mode")
- if("${CMAKE_TEST_GENERATOR}" MATCHES "Make")
+ if("${CMAKE_GENERATOR}" MATCHES "Make")
ADD_TEST_MACRO(Policy0002 Policy0002)
endif()
if(CTEST_TEST_OSX_ARCH)
@@ -263,7 +390,7 @@ if(BUILD_TESTING)
list(APPEND TEST_BUILD_DIRS ${CMake_TEST_INSTALL_PREFIX})
if(NOT QT4_FOUND)
- find_package(Qt4)
+ find_package(Qt4 QUIET)
endif()
if(QT4_FOUND)
@@ -290,7 +417,7 @@ if(BUILD_TESTING)
MINGW OR
CMAKE_SYSTEM_NAME MATCHES "Linux" OR
CMAKE_SYSTEM_NAME MATCHES "Darwin")
- if(NOT "${CMAKE_TEST_GENERATOR}" STREQUAL "Watcom WMake")
+ if(NOT "${CMAKE_GENERATOR}" STREQUAL "Watcom WMake")
add_test(BundleUtilities ${CMAKE_CTEST_COMMAND}
--build-and-test
@@ -298,6 +425,7 @@ if(BUILD_TESTING)
"${CMake_BINARY_DIR}/Tests/BundleUtilities"
${build_generator_args}
--build-project BundleUtilities
+ --build-options ${build_options}
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/BundleUtilities")
@@ -310,7 +438,7 @@ if(BUILD_TESTING)
"${CMake_BINARY_DIR}/Tests/Qt4Deploy"
${build_generator_args}
--build-project Qt4Deploy
- --build-options
+ --build-options ${build_options}
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}
)
@@ -348,12 +476,16 @@ if(BUILD_TESTING)
--build-project ExternalDataTest
--build-noclean
--force-new-ctest-process
- --build-options -DMAKE_SUPPORTS_SPACES=${MAKE_SUPPORTS_SPACES}
+ --build-options ${build_options}
+ -DMAKE_SUPPORTS_SPACES=${MAKE_SUPPORTS_SPACES}
--test-command ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE} -V
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Module/ExternalData")
ADD_TEST_MACRO(Module.GenerateExportHeader GenerateExportHeader)
+ ADD_TEST_MACRO(Module.FindDependency FindDependency)
+
+ ADD_TEST_MACRO(Module.WriteCompilerDetectionHeader WriteCompilerDetectionHeader)
if (APPLE OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
include(CheckCXXCompilerFlag)
@@ -373,6 +505,29 @@ if(BUILD_TESTING)
ADD_TEST_MACRO(PositionIndependentTargets PositionIndependentTargets)
endif()
+ if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") AND
+ (NOT "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS 4.2) AND
+ (CMAKE_SYSTEM_NAME MATCHES "Linux"))
+
+ include(CheckCXXCompilerFlag)
+ check_cxx_compiler_flag(
+ -fvisibility-inlines-hidden run_inlines_hidden_test)
+ endif()
+
+ if(run_inlines_hidden_test)
+ add_test(Visibility ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/Visibility"
+ "${CMake_BINARY_DIR}/Tests/Visibility"
+ ${build_generator_args}
+ --build-project Visibility
+ --build-options ${build_options}
+ )
+ list(APPEND TEST_BUILD_DIRS
+ "${CMake_BINARY_DIR}/Tests/Visibility"
+ )
+ endif()
+
add_test(LinkFlags-prepare
${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE}
--build-and-test
@@ -381,7 +536,8 @@ if(BUILD_TESTING)
${build_generator_args}
--build-project LinkFlags
--build-target LinkFlags
- --build-options -DTEST_CONFIG=\${CTEST_CONFIGURATION_TYPE}
+ --build-options ${build_options}
+ -DTEST_CONFIG=\${CTEST_CONFIGURATION_TYPE}
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/LinkFlags")
@@ -414,7 +570,7 @@ if(BUILD_TESTING)
# build the "Simple" test with the ExtraGenerators, if available
# This doesn't test whether the generated project files work (unfortunately),
# mainly it tests that cmake doesn't crash when generating these project files.
- if(${CMAKE_TEST_GENERATOR} MATCHES "Unix Makefiles" OR ${CMAKE_TEST_GENERATOR} MATCHES "KDevelop")
+ if(${CMAKE_GENERATOR} MATCHES "Unix Makefiles" OR ${CMAKE_GENERATOR} MATCHES "KDevelop")
# check which generators we have
execute_process(COMMAND ${CMAKE_CMAKE_COMMAND} --help
OUTPUT_VARIABLE cmakeOutput ERROR_VARIABLE cmakeOutput)
@@ -426,9 +582,10 @@ if(BUILD_TESTING)
"${CMake_BINARY_DIR}/Tests/Simple_EclipseGenerator"
--build-two-config
--build-generator "Eclipse CDT4 - Unix Makefiles"
- --build-generator-toolset "${CMAKE_TEST_GENERATOR_TOOLSET}"
- --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-generator-platform "${CMAKE_GENERATOR_PLATFORM}"
+ --build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
--build-project Simple
+ --build-options ${build_options}
--test-command Simple)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Simple_EclipseGenerator")
endif ()
@@ -441,9 +598,10 @@ if(BUILD_TESTING)
"${CMake_BINARY_DIR}/Tests/Simple_CodeBlocksGenerator"
--build-two-config
--build-generator "CodeBlocks - Unix Makefiles"
- --build-generator-toolset "${CMAKE_TEST_GENERATOR_TOOLSET}"
- --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-generator-platform "${CMAKE_GENERATOR_PLATFORM}"
+ --build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
--build-project Simple
+ --build-options ${build_options}
--test-command Simple)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Simple_CodeBlocksGenerator")
endif ()
@@ -455,9 +613,10 @@ if(BUILD_TESTING)
"${CMake_BINARY_DIR}/Tests/Simple_KDevelop3Generator"
--build-two-config
--build-generator "KDevelop3 - Unix Makefiles"
- --build-generator-toolset "${CMAKE_TEST_GENERATOR_TOOLSET}"
- --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-generator-platform "${CMAKE_GENERATOR_PLATFORM}"
+ --build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
--build-project Simple
+ --build-options ${build_options}
--test-command Simple)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Simple_KDevelop3Generator")
endif ()
@@ -465,8 +624,8 @@ if(BUILD_TESTING)
endif()
# test for correct sub-project generation
- # not implemented in VS6 or Xcode
- if(NOT MSVC60 AND NOT XCODE AND NOT MSVC70)
+ # not implemented in VS 6, VS 7.0, Xcode, or Ninja
+ if(NOT CMAKE_GENERATOR MATCHES "Visual Studio [67]$|Xcode|Ninja")
# run cmake and configure all of SubProject
# but only build the independent executable car
add_test(SubProject ${CMAKE_CTEST_COMMAND}
@@ -476,40 +635,39 @@ if(BUILD_TESTING)
--build-project SubProject
${build_generator_args}
--build-target car
+ --build-options ${build_options}
--test-command car
)
- if(${CMAKE_TEST_GENERATOR} MATCHES "Ninja")
- # The Ninja generator does not create a recursive build system. Start
- # from the root directory.
- set(SubProject_SUBDIR)
- else()
- set(SubProject_SUBDIR "/foo")
- endif()
-
# For stage 2, do not run cmake again.
# Then build the foo sub project which should build
# the bar library which should be referenced because
# foo links to the static library bar, but bar is not
# directly in the foo sub project
+ if(CMake_TEST_EXPLICIT_MAKE_PROGRAM)
+ set(SubProject-Stage2_BUILD_MAKEPROGRAM
+ --build-makeprogram ${CMake_TEST_EXPLICIT_MAKE_PROGRAM}
+ )
+ endif()
add_test(SubProject-Stage2 ${CMAKE_CTEST_COMMAND}
--build-and-test
- "${CMake_SOURCE_DIR}/Tests/SubProject${SubProject_SUBDIR}"
- "${CMake_BINARY_DIR}/Tests/SubProject${SubProject_SUBDIR}"
- ${build_generator_args}
+ "${CMake_SOURCE_DIR}/Tests/SubProject/foo"
+ "${CMake_BINARY_DIR}/Tests/SubProject/foo"
+ --build-generator ${CMAKE_GENERATOR}
+ --build-generator-platform "${CMAKE_GENERATOR_PLATFORM}"
+ --build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
+ ${SubProject-Stage2_BUILD_MAKEPROGRAM}
--build-nocmake
--build-project foo
--build-target foo
--build-exe-dir "${CMake_BINARY_DIR}/Tests/SubProject/foo"
+ --build-options ${build_options}
--test-command foo
)
set_tests_properties ( SubProject-Stage2 PROPERTIES DEPENDS SubProject)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/SubProject")
endif()
- if (CMAKE_STRICT)
- ADD_TEST_MACRO(DocTest DocTest)
- endif ()
# macro to add a test that will build a nightly release
# of CMake for given platform using the release scripts
macro(ADD_NIGHTLY_BUILD_TEST name script)
@@ -518,7 +676,7 @@ if(BUILD_TESTING)
file(WRITE "${_TEST_DIR}/nightly-cmake.sh"
"cd ${_TEST_DIR}
${CMake_BINARY_DIR}/bin/cmake -DCMAKE_CREATE_VERSION=nightly -P ${CMake_SOURCE_DIR}/Utilities/Release/${script}
-${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/Release/upload_release.cmake
+${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release/upload_release.cmake
")
add_test(${name} /bin/sh ${_TEST_DIR}/nightly-cmake.sh)
if(COMMAND SET_TESTS_PROPERTIES AND COMMAND GET_TEST_PROPERTY)
@@ -527,13 +685,13 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
endmacro()
if(CMAKE_BUILD_NIGHTLY_RELEASES)
ADD_NIGHTLY_BUILD_TEST(CMakeNightlyWindows
- dash2win64_release.cmake)
- ADD_NIGHTLY_BUILD_TEST(CMakeNightlyMac
- dashmacmini2_release.cmake)
- ADD_NIGHTLY_BUILD_TEST(CMakeNightlyMac64
+ dash3win7_release.cmake)
+ ADD_NIGHTLY_BUILD_TEST(CMakeNightlyOSX
dashmacmini5_release.cmake)
- ADD_NIGHTLY_BUILD_TEST(CMakeNightlyLinux
+ ADD_NIGHTLY_BUILD_TEST(CMakeNightlyLinux32
magrathea_release.cmake)
+ ADD_NIGHTLY_BUILD_TEST(CMakeNightlyLinux64
+ linux64_release.cmake)
endif()
# add tests with more complex invocations
@@ -544,7 +702,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--build-two-config
${build_generator_args}
--build-project Framework
- --build-options
+ --build-options ${build_options}
"-DCMAKE_INSTALL_PREFIX:PATH=${CMake_BINARY_DIR}/Tests/Framework/Install"
--test-command bar)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Framework")
@@ -556,6 +714,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--build-two-config
${build_generator_args}
--build-project TargetName
+ --build-options ${build_options}
--test-command ${CMAKE_CMAKE_COMMAND} -E compare_files
${CMake_SOURCE_DIR}/Tests/TargetName/scripts/hello_world
${CMake_BINARY_DIR}/Tests/TargetName/scripts/hello_world)
@@ -569,6 +728,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
${build_generator_args}
--build-project LibName
--build-exe-dir "${CMake_BINARY_DIR}/Tests/LibName/lib"
+ --build-options ${build_options}
--test-command foobar
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/LibName")
@@ -581,6 +741,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
${build_generator_args}
--build-project CustComDepend
--build-exe-dir "${CMake_BINARY_DIR}/Tests/CustComDepend/bin"
+ --build-options ${build_options}
--test-command foo bar.c
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CustComDepend")
@@ -592,18 +753,22 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
${build_generator_args}
--build-project ArgumentExpansion
--build-exe-dir "${CMake_BINARY_DIR}/Tests/ArgumentExpansion/bin"
+ --build-options ${build_options}
)
set_tests_properties(ArgumentExpansion PROPERTIES
FAIL_REGULAR_EXPRESSION "Unexpected: ")
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ArgumentExpansion")
- add_test(GeneratorExpression ${CMAKE_CTEST_COMMAND}
+ add_test(GeneratorExpression
+ ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE}
--build-and-test
"${CMake_SOURCE_DIR}/Tests/GeneratorExpression"
"${CMake_BINARY_DIR}/Tests/GeneratorExpression"
${build_generator_args}
--build-project GeneratorExpression
- --build-options -DCMAKE_BUILD_TYPE=\${CTEST_CONFIGURATION_TYPE}
+ --build-options ${build_options}
+ -DCMAKE_BUILD_TYPE=\${CTEST_CONFIGURATION_TYPE}
+ --test-command ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE} -V
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/GeneratorExpression")
@@ -615,10 +780,13 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
${build_generator_args}
--build-project CustomCommand
--build-exe-dir "${CMake_BINARY_DIR}/Tests/CustomCommand/bin"
+ --build-options ${build_options}
--test-command CustomCommand
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CustomCommand")
+ ADD_TEST_MACRO(CustomCommandByproducts CustomCommandByproducts)
+
ADD_TEST_MACRO(EmptyDepends ${CMAKE_CTEST_COMMAND})
add_test(CustomCommandWorkingDirectory ${CMAKE_CTEST_COMMAND}
@@ -628,6 +796,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--build-two-config
${build_generator_args}
--build-project TestWorkingDir
+ --build-options ${build_options}
--test-command working
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CustomCommandWorkingDirectory")
@@ -639,6 +808,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
# ${build_generator_args}
# --build-project SimpleExclude
# --build-two-config
+ # --build-options ${build_options}
# --test-command t4
#--test-command "${CMAKE_COMMAND}"
#"-DCONFIGURATION=\${CTEST_CONFIGURATION_TYPE}"
@@ -652,6 +822,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
# ${build_generator_args}
# --build-project SameName
# --build-two-config
+# --build-options ${build_options}
# --test-command
# "${CMake_BINARY_DIR}/Tests/SameName/Exe1/mytest2")
@@ -662,6 +833,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
${build_generator_args}
--build-project OutOfSource
--build-two-config
+ --build-options ${build_options}
--test-command
"${CMake_BINARY_DIR}/Tests/OutOfSource/SubDir/OutOfSourceSubdir/simple")
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/OutOfSource")
@@ -674,6 +846,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
"${CMake_BINARY_DIR}/Tests/BuildDepends"
${build_generator_args}
--build-project BuildDepends
+ --build-options ${build_options}
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/BuildDepends")
@@ -686,7 +859,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
${build_generator_args}
--build-project TestSimpleInstall
--build-two-config
- --build-options
+ --build-options ${build_options}
"-DCMAKE_INSTALL_PREFIX:PATH=${SimpleInstallInstallDir}"
"-DCTEST_TEST_CPACK:BOOL=${CTEST_TEST_CPACK}"
--test-command ${SimpleInstallInstallDir}/MyTest/bin/SimpleInstExe)
@@ -698,26 +871,32 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
${build_generator_args}
--build-project TestSimpleInstall
--build-two-config
- --build-options
+ --build-options ${build_options}
"-DCMAKE_INSTALL_PREFIX:PATH=${SimpleInstallInstallDir}"
"-DSTAGE2:BOOL=1"
--test-command ${SimpleInstallInstallDir}/MyTest/bin/SimpleInstExeS2)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/SimpleInstallS2")
+ set(MissingInstallInstallDir
+ "${CMake_BINARY_DIR}/Tests/MissingInstall/InstallDirectory")
+ add_test(MissingInstall ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/MissingInstall"
+ "${CMake_BINARY_DIR}/Tests/MissingInstall"
+ ${build_generator_args}
+ --build-project TestMissingInstall
+ --build-two-config
+ --build-options ${build_options}
+ "-DCMAKE_INSTALL_PREFIX:PATH=${MissingInstallInstallDir}")
+ list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/MissingInstall")
+
# By default, run the CPackComponents test if the CTEST_TEST_CPACK
# option is ON:
#
set(CTEST_RUN_CPackComponents ${CTEST_TEST_CPACK})
set(CTEST_package_X11_TEST ${CTEST_TEST_CPACK})
set(CTEST_RUN_CPackComponentsForAll ${CTEST_TEST_CPACK})
-
- if (CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT CMAKE_CURRENT_BINARY_DIR MATCHES ".* .*")
- find_program(RPMBUILD NAMES rpmbuild)
- endif()
- # Do not try to build RPM
- if (NOT RPMBUILD)
- set(CPACK_BINARY_RPM OFF)
- endif()
+ set(CTEST_RUN_CPackComponentsPrefix ${CTEST_TEST_CPACK})
find_program(NSIS_MAKENSIS_EXECUTABLE NAMES makensis
PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS]
@@ -747,24 +926,31 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
if(WIX_LIGHT_EXECUTABLE)
add_test(CPackWiXGenerator ${CMAKE_CTEST_COMMAND}
+ -C \${CTEST_CONFIGURATION_TYPE}
--build-and-test
"${CMake_SOURCE_DIR}/Tests/CPackWiXGenerator"
"${CMake_BINARY_DIR}/Tests/CPackWiXGenerator"
${build_generator_args}
--build-project CPackWiXGenerator
+ --build-options ${build_options}
--test-command ${CMAKE_CMAKE_COMMAND}
"-DCPackWiXGenerator_BINARY_DIR:PATH=${CMake_BINARY_DIR}/Tests/CPackWiXGenerator"
+ "-Dconfig=\${CTEST_CONFIGURATION_TYPE}"
-P "${CMake_SOURCE_DIR}/Tests/CPackWiXGenerator/RunCPackVerifyResult.cmake")
+
+ set_property(TEST CPackWiXGenerator PROPERTY
+ ATTACHED_FILES_ON_FAIL
+ "${CMake_BINARY_DIR}/Tests/CPackWiXGenerator/_CPack_Packages/win32/WIX/wix.log")
endif()
endif()
if(CTEST_RUN_CPackComponents)
- set(CPackComponents_EXTRA_OPTIONS)
+ set(CPackComponents_BUILD_OPTIONS)
if(APPLE)
- set(CPackComponents_EXTRA_OPTIONS -DCPACK_BINARY_DRAGNDROP:BOOL=ON)
+ set(CPackComponents_BUILD_OPTIONS -DCPACK_BINARY_DRAGNDROP:BOOL=ON)
endif()
if(NSIS_MAKENSIS_EXECUTABLE)
- set(CPackComponents_EXTRA_OPTIONS ${CPackComponents_EXTRA_OPTIONS}
+ set(CPackComponents_BUILD_OPTIONS ${CPackComponents_BUILD_OPTIONS}
-DCPACK_BINARY_NSIS:BOOL=ON)
endif()
@@ -776,10 +962,10 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--build-project CPackComponents
--build-two-config
--build-target package
- --build-options
+ --build-options ${build_options}
-DCPACK_BINARY_DEB:BOOL=${CPACK_BINARY_DEB}
-DCPACK_BINARY_RPM:BOOL=${CPACK_BINARY_RPM}
- ${CPackComponents_EXTRA_OPTIONS}
+ ${CPackComponents_BUILD_OPTIONS}
--graphviz=CPackComponents.dot
--test-command ${CMAKE_CMAKE_COMMAND}
"-DCPackComponents_BINARY_DIR:PATH=${CMake_BINARY_DIR}/Tests/CPackComponents"
@@ -790,34 +976,22 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
if(CTEST_RUN_CPackComponentsForAll)
# Check whether if rpmbuild command is found
# before adding RPM tests
- find_program(RPMBUILD_EXECUTABLE NAMES rpmbuild)
- if(RPMBUILD_EXECUTABLE)
+ if(CPACK_BINARY_RPM)
list(APPEND ACTIVE_CPACK_GENERATORS RPM)
endif()
# Check whether if dpkg command is found
# before adding DEB tests
- find_program(DPKG_EXECUTABLE NAMES dpkg)
- if(DPKG_EXECUTABLE)
+ if(CPACK_BINARY_DEB)
list(APPEND ACTIVE_CPACK_GENERATORS DEB)
endif()
# ACTIVE_CPACK_GENERATORS variable
# now contains the list of 'active generators'
- set(CPackComponentsForAll_EXTRA_OPTIONS)
+ set(CPackComponentsForAll_BUILD_OPTIONS)
# set up list of CPack generators
- list(APPEND GENLST "ZIP")
+ list(APPEND ACTIVE_CPACK_GENERATORS "ZIP")
if(APPLE)
- list(APPEND GENLST "DragNDrop")
- endif()
- if (NOT CMAKE_CURRENT_BINARY_DIR MATCHES ".* .*")
- list(FIND ACTIVE_CPACK_GENERATORS "RPM" RPM_ACTIVE)
- if (NOT ${RPM_ACTIVE} EQUAL -1)
- list(APPEND GENLST "RPM")
- endif()
- endif()
- list(FIND ACTIVE_CPACK_GENERATORS "DEB" DEB_ACTIVE)
- if (NOT ${DEB_ACTIVE} EQUAL -1)
- list(APPEND GENLST "DEB")
+ list(APPEND ACTIVE_CPACK_GENERATORS "DragNDrop")
endif()
# set up list of component packaging ways
@@ -825,20 +999,22 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
list(APPEND CWAYLST "OnePackPerGroup")
list(APPEND CWAYLST "IgnoreGroup")
list(APPEND CWAYLST "AllInOne")
- foreach(CPackGen ${GENLST})
+ foreach(CPackGen IN LISTS ACTIVE_CPACK_GENERATORS)
set(CPackRun_CPackGen "-DCPackGen=${CPackGen}")
foreach(CPackComponentWay ${CWAYLST})
set(CPackRun_CPackComponentWay "-DCPackComponentWay=${CPackComponentWay}")
- add_test(CPackComponentsForAll-${CPackGen}-${CPackComponentWay} ${CMAKE_CTEST_COMMAND}
+ add_test(CPackComponentsForAll-${CPackGen}-${CPackComponentWay}
+ ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE}
--build-and-test
"${CMake_SOURCE_DIR}/Tests/CPackComponentsForAll"
"${CMake_BINARY_DIR}/Tests/CPackComponentsForAll/build${CPackGen}-${CPackComponentWay}"
${build_generator_args}
--build-project CPackComponentsForAll
- --build-options
+ --build-options ${build_options}
+ -DCPACK_GENERATOR:STRING=${CPackGen}
-DCPACK_BINARY_${CPackGen}:BOOL=ON
${CPackRun_CPackComponentWay}
- ${CPackComponentsForAll_EXTRA_OPTIONS}
+ ${CPackComponentsForAll_BUILD_OPTIONS}
--graphviz=CPackComponentsForAll.dot
--test-command ${CMAKE_CMAKE_COMMAND}
"-DCPackComponentsForAll_BINARY_DIR:PATH=${CMake_BINARY_DIR}/Tests/CPackComponentsForAll/build${CPackGen}-${CPackComponentWay}"
@@ -848,6 +1024,47 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CPackComponentsForAll/build${CPackGen}-${CPackComponentWay}")
endforeach()
endforeach()
+
+ # debian specific
+ if(DPKG_EXECUTABLE)
+ unset(CPackRun_CPackDEBConfiguration_ALL_CONFIGS)
+ set(DEB_TEST_NAMES "CPackComponentsDEB")
+ set(DEB_CONFIGURATIONS_TO_TEST "components-lintian-dpkgdeb-checks"
+ "components-description1"
+ "components-description2"
+ "components-source"
+ "components-shlibdeps1"
+ "components-depend1"
+ "components-depend2"
+ "compression")
+ set(CPackGen "DEB")
+ set(CPackRun_CPackGen "-DCPackGen=${CPackGen}")
+
+ foreach(CPackDEBConfiguration IN LISTS DEB_CONFIGURATIONS_TO_TEST)
+ set(CPackRun_CPackDEBConfiguration "-DCPackDEBConfiguration=${CPackDEBConfiguration}")
+ add_test(${DEB_TEST_NAMES}-${CPackDEBConfiguration}
+ ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/${DEB_TEST_NAMES}"
+ "${CMake_BINARY_DIR}/Tests/${DEB_TEST_NAMES}/build${CPackGen}-${CPackDEBConfiguration}"
+ ${build_generator_args}
+ --build-project CPackComponentsDEB
+ --build-options ${build_options}
+ -DCPACK_GENERATOR:STRING=${CPackGen}
+ -DCPACK_BINARY_${CPackGen}:BOOL=ON
+ ${CPackRun_CPackDEBConfiguration}
+ ${CPackRun_CPackDEBConfiguration_ALL_CONFIGS}
+ --graphviz=${DEB_TEST_NAMES}.dot
+ --test-command ${CMAKE_CMAKE_COMMAND}
+ "-D${DEB_TEST_NAMES}_SOURCE_DIR:PATH=${CMake_SOURCE_DIR}/Tests/${DEB_TEST_NAMES}"
+ "-D${DEB_TEST_NAMES}_BINARY_DIR:PATH=${CMake_BINARY_DIR}/Tests/${DEB_TEST_NAMES}/build${CPackGen}-${CPackDEBConfiguration}"
+ "${CPackRun_CPackGen}"
+ "${CPackRun_CPackDEBConfiguration}"
+ -P "${CMake_SOURCE_DIR}/Tests/${DEB_TEST_NAMES}/RunCPackVerifyResult-${CPackDEBConfiguration}.cmake")
+ list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${DEB_TEST_NAMES}/build${CPackGen}-${CPackDEBConfiguration}")
+ endforeach()
+ endif()
+
endif()
# By default, turn this test off (because it takes a long time...)
@@ -872,6 +1089,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
"${CMake_BINARY_DIR}/Tests/CPackTestAllGenerators"
${build_generator_args}
--build-project CPackTestAllGenerators
+ --build-options ${build_options}
--test-command
${CMAKE_CMAKE_COMMAND}
-D dir=${CMake_BINARY_DIR}/Tests/CPackTestAllGenerators
@@ -880,6 +1098,33 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CPackTestAllGenerators")
endif()
+ if(CTEST_RUN_CPackComponentsPrefix)
+ set(CPackComponents_BUILD_OPTIONS)
+ if(APPLE)
+ set(CPackComponents_BUILD_OPTIONS -DCPACK_BINARY_DRAGNDROP:BOOL=ON)
+ endif()
+ if(NOT NSIS_MAKENSIS_EXECUTABLE)
+ set(CPackComponents_BUILD_OPTIONS ${CPackComponents_BUILD_OPTIONS}
+ -DCPACK_BINARY_NSIS:BOOL=OFF)
+ endif()
+
+ add_test(CPackComponentsPrefix ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/CPackComponentsPrefix"
+ "${CMake_BINARY_DIR}/Tests/CPackComponentsPrefix"
+ ${build_generator_args}
+ --build-project CPackComponentsPrefix
+ --build-two-config
+ --build-target package
+ --build-options ${build_options}
+ -DCPACK_BINARY_DEB:BOOL=${CPACK_BINARY_DEB}
+ -DCPACK_BINARY_RPM:BOOL=${CPACK_BINARY_RPM}
+ -DCPACK_BINARY_ZIP:BOOL=ON
+ ${CPackComponents_BUILD_OPTIONS}
+ )
+ list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CPackComponentsPrefix")
+ endif()
+
if(CTEST_package_X11_TEST)
set(X11_build_target_arg --build-target package)
else()
@@ -894,6 +1139,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--build-project UseX11
--build-two-config
${X11_build_target_arg}
+ --build-options ${build_options}
--test-command UseX11)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/X11")
@@ -911,21 +1157,6 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
"${CMake_BINARY_DIR}/Tests/CMakeTestAllGenerators")
endif()
- if(NOT DEFINED CTEST_RUN_CMakeTestBadCommandLines)
- set(CTEST_RUN_CMakeTestBadCommandLines ON)
- endif()
-
- if(CTEST_RUN_CMakeTestBadCommandLines)
- add_test(CMakeTestBadCommandLines ${CMAKE_CMAKE_COMMAND}
- -D dir=${CMake_BINARY_DIR}/Tests/CMakeTestBadCommandLines
- -D gen=${CMAKE_TEST_GENERATOR}
- -D CMake_SOURCE_DIR=${CMake_SOURCE_DIR}
- -P ${CMake_SOURCE_DIR}/Tests/CMakeTestBadCommandLines/RunCMake.cmake
- )
- list(APPEND TEST_BUILD_DIRS
- "${CMake_BINARY_DIR}/Tests/CMakeTestBadCommandLines")
- endif()
-
if(NOT DEFINED CTEST_RUN_CMakeTestMultipleConfigures)
set(CTEST_RUN_CMakeTestMultipleConfigures ON)
endif()
@@ -933,7 +1164,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
if(CTEST_RUN_CMakeTestMultipleConfigures)
add_test(CMakeTestMultipleConfigures ${CMAKE_CMAKE_COMMAND}
-D dir=${CMake_BINARY_DIR}/Tests/CMakeTestMultipleConfigures
- -D gen=${CMAKE_TEST_GENERATOR}
+ -D gen=${CMAKE_GENERATOR}
-D CMake_SOURCE_DIR=${CMake_SOURCE_DIR}
-P ${CMake_SOURCE_DIR}/Tests/CMakeTestMultipleConfigures/RunCMake.cmake
)
@@ -941,15 +1172,18 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
"${CMake_BINARY_DIR}/Tests/CMakeTestMultipleConfigures")
endif()
- add_test(LoadedCommandOneConfig ${CMAKE_CTEST_COMMAND}
- --build-and-test
- "${CMake_SOURCE_DIR}/Tests/LoadCommandOneConfig"
- "${CMake_BINARY_DIR}/Tests/LoadCommandOneConfig"
- ${build_generator_args}
- --build-project LoadCommand
- --test-command LoadedCommand
- )
- list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/LoadCommandOneConfig")
+ if(NOT CMake_TEST_EXTERNAL_CMAKE)
+ add_test(LoadedCommandOneConfig ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/LoadCommandOneConfig"
+ "${CMake_BINARY_DIR}/Tests/LoadCommandOneConfig"
+ ${build_generator_args}
+ --build-project LoadCommand
+ --build-options ${build_options}
+ --test-command LoadedCommand
+ )
+ list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/LoadCommandOneConfig")
+ endif()
add_test(complex ${CMAKE_CTEST_COMMAND}
--build-and-test
@@ -960,7 +1194,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
${build_generator_args}
--build-project Complex
--build-exe-dir "${CMake_BINARY_DIR}/Tests/Complex/bin"
- --build-options
+ --build-options ${build_options}
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
--test-command complex
)
@@ -973,24 +1207,13 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
${build_generator_args}
--build-project Complex
--build-exe-dir "${CMake_BINARY_DIR}/Tests/ComplexOneConfig/bin"
- --build-options
+ --build-options ${build_options}
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
--test-command complex)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ComplexOneConfig")
# because of the registry write these tests depend on each other
set_tests_properties ( complex PROPERTIES DEPENDS complexOneConfig)
- add_test(Example ${CMAKE_CTEST_COMMAND}
- --build-and-test
- "${CMake_SOURCE_DIR}/Example"
- "${CMake_BINARY_DIR}/Example"
- ${build_generator_args}
- --build-project HELLO
- --build-exe-dir "${CMake_BINARY_DIR}/Example/Demo"
- --test-command helloDemo
- )
- list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Example")
-
add_test(Environment ${CMAKE_CTEST_COMMAND}
--build-and-test
"${CMake_SOURCE_DIR}/Tests/Environment"
@@ -999,6 +1222,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--build-project EnvironmentProj
--build-exe-dir "${CMake_BINARY_DIR}/Tests/Environment"
--force-new-ctest-process
+ --build-options ${build_options}
--test-command ${CMAKE_CTEST_COMMAND} -V
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Environment")
@@ -1009,38 +1233,85 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
"${CMake_BINARY_DIR}/Tests/QtAutomocNoQt"
${build_generator_args}
--build-project QtAutomocNoQt
- --build-options -DCMAKE_BUILD_TYPE=\${CTEST_CONFIGURATION_TYPE}
+ --build-options ${build_options}
+ -DCMAKE_BUILD_TYPE=\${CTEST_CONFIGURATION_TYPE}
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/QtAutomocNoQt")
+ # On Windows there is no RPATH, so while Qt might be available for building,
+ # the required dlls may not be in the PATH, so we can't run the executables
+ # on that platform.
+ if(WIN32)
+ set(run_autogen_test ${CMAKE_CTEST_COMMAND} -V)
+ set(run_autouic_test ${CMAKE_CTEST_COMMAND} -V)
+ else()
+ set(run_autogen_test QtAutogen)
+ set(run_autouic_test QtAutoUicInterface)
+ endif()
+ if(NOT CMAKE_CONFIGURATION_TYPES)
+ set(QtAutogen_BUILD_OPTIONS -DCMAKE_BUILD_TYPE=$<CONFIGURATION>)
+ endif()
+
find_package(Qt5Widgets QUIET NO_MODULE)
if(Qt5Widgets_FOUND)
- add_test(Qt5Automoc ${CMAKE_CTEST_COMMAND}
+ add_test(NAME Qt5Autogen COMMAND ${CMAKE_CTEST_COMMAND}
--build-and-test
- "${CMake_SOURCE_DIR}/Tests/QtAutomoc"
- "${CMake_BINARY_DIR}/Tests/Qt5Automoc"
+ "${CMake_SOURCE_DIR}/Tests/QtAutogen"
+ "${CMake_BINARY_DIR}/Tests/Qt5Autogen"
${build_generator_args}
- --build-project QtAutomoc
- --build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt5Automoc"
+ --build-project QtAutogen
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt5Autogen"
--force-new-ctest-process
- --build-options -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} -DQT_TEST_VERSION=5
- --test-command ${CMAKE_CTEST_COMMAND} -V
+ --build-options ${build_options}
+ -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} -DQT_TEST_VERSION=5
+ ${QtAutogen_BUILD_OPTIONS}
+ --test-command ${run_autogen_test}
)
- list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt5Automoc")
+ list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt5Autogen")
+
+ add_test(Qt5AutoUicInterface ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/QtAutoUicInterface"
+ "${CMake_BINARY_DIR}/Tests/Qt5AutoUicInterface"
+ ${build_generator_args}
+ --build-project QtAutoUicInterface
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt5AutoUicInterface"
+ --force-new-ctest-process
+ --build-options ${build_options}
+ -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} -DQT_TEST_VERSION=5
+ --test-command ${run_autouic_test}
+ )
+ list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt5AutoUicInterface")
endif()
if(QT4_WORKS AND QT_QTGUI_FOUND)
- add_test(Qt4Automoc ${CMAKE_CTEST_COMMAND}
+ add_test(NAME Qt4Autogen COMMAND ${CMAKE_CTEST_COMMAND}
--build-and-test
- "${CMake_SOURCE_DIR}/Tests/QtAutomoc"
- "${CMake_BINARY_DIR}/Tests/Qt4Automoc"
+ "${CMake_SOURCE_DIR}/Tests/QtAutogen"
+ "${CMake_BINARY_DIR}/Tests/Qt4Autogen"
${build_generator_args}
- --build-project QtAutomoc
- --build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt4Automoc"
+ --build-project QtAutogen
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt4Autogen"
--force-new-ctest-process
- --build-options -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} -DQT_TEST_VERSION=4
- --test-command ${CMAKE_CTEST_COMMAND} -V
+ --build-options ${build_options}
+ -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} -DQT_TEST_VERSION=4
+ ${QtAutogen_BUILD_OPTIONS}
+ --test-command ${run_autogen_test}
+ )
+ list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4Autogen")
+
+ add_test(Qt4AutoUicInterface ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/QtAutoUicInterface"
+ "${CMake_BINARY_DIR}/Tests/Qt4AutoUicInterface"
+ ${build_generator_args}
+ --build-project QtAutoUicInterface
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt4AutoUicInterface"
+ --force-new-ctest-process
+ --build-options ${build_options}
+ -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} -DQT_TEST_VERSION=4
+ --test-command ${run_autouic_test}
)
- list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4Automoc")
+ list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4AutoUicInterface")
add_test(Qt4Targets ${CMAKE_CTEST_COMMAND}
--build-and-test
@@ -1050,7 +1321,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--build-project Qt4Targets
--build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt4Targets"
--force-new-ctest-process
- --build-options -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}
+ --build-options ${build_options}
+ -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}
--test-command ${CMAKE_CTEST_COMMAND} -V
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4Targets")
@@ -1064,12 +1336,74 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--build-project Qt4And5Automoc
--build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt4And5Automoc"
--force-new-ctest-process
+ --build-options ${build_options}
--test-command ${CMAKE_CTEST_COMMAND} -V
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4And5Automoc")
+ add_test(Qt4And5AutomocReverse ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/Qt4And5Automoc"
+ "${CMake_BINARY_DIR}/Tests/Qt4And5AutomocReverse"
+ ${build_generator_args}
+ --build-project Qt4And5Automoc
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt4And5AutomocReverse"
+ --force-new-ctest-process
+ --build-options ${build_options} -DQT_REVERSE_FIND_ORDER=1
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+ list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4And5AutomocReverse")
endif()
endif()
+ if(CMake_TEST_FindBoost)
+ add_subdirectory(FindBoost)
+ endif()
+
+ if(CMake_TEST_FindGSL)
+ add_subdirectory(FindGSL)
+ endif()
+
+ if(CMake_TEST_FindGTest)
+ add_subdirectory(FindGTest)
+ endif()
+
+ if(CMake_TEST_FindJsonCpp)
+ add_subdirectory(FindJsonCpp)
+ endif()
+
+ if(CMake_TEST_FindOpenSSL)
+ add_subdirectory(FindOpenSSL)
+ endif()
+
+ if(CMake_TEST_FindPNG)
+ add_subdirectory(FindPNG)
+ endif()
+
+ if(CMake_TEST_FindTIFF)
+ add_subdirectory(FindTIFF)
+ endif()
+
+ if(CMake_TEST_FindXalanC)
+ add_subdirectory(FindXalanC)
+ endif()
+
+ if(CMake_TEST_FindXercesC)
+ add_subdirectory(FindXercesC)
+ endif()
+
+ add_subdirectory(FindThreads)
+
+ # Matlab module
+ if(CMake_TEST_FindMatlab)
+ ADD_TEST_MACRO(FindMatlab.basic_checks ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>)
+ ADD_TEST_MACRO(FindMatlab.versions_checks ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>)
+ endif()
+
+ find_package(GTK2 QUIET)
+ if(GTK2_FOUND)
+ add_subdirectory(FindGTK2)
+ endif()
+
add_test(ExternalProject ${CMAKE_CTEST_COMMAND}
--build-and-test
"${CMake_SOURCE_DIR}/Tests/ExternalProject"
@@ -1078,12 +1412,40 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--build-project ExternalProjectTest
--build-exe-dir "${CMake_BINARY_DIR}/Tests/ExternalProject"
--force-new-ctest-process
+ --build-options ${build_options}
--test-command ${CMAKE_CTEST_COMMAND} -V
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProject")
set_tests_properties(ExternalProject PROPERTIES
TIMEOUT ${CMAKE_LONG_TEST_TIMEOUT})
+ add_test(NAME ExternalProjectSubdir
+ COMMAND ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/ExternalProjectSubdir"
+ "${CMake_BINARY_DIR}/Tests/ExternalProjectSubdir"
+ ${build_generator_args}
+ --build-project ExternalProjectSubdir
+ --force-new-ctest-process
+ --build-options ${build_options}
+ )
+ list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProjectSubdir")
+
+ add_test(ExternalProjectLocal ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/ExternalProjectLocal"
+ "${CMake_BINARY_DIR}/Tests/ExternalProjectLocal"
+ ${build_generator_args}
+ --build-project ExternalProjectLocalTest
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/ExternalProjectLocal"
+ --force-new-ctest-process
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+ list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProjectLocal")
+ set_tests_properties(ExternalProjectLocal PROPERTIES
+ TIMEOUT ${CMAKE_LONG_TEST_TIMEOUT})
+
add_test(ExternalProjectUpdateSetup ${CMAKE_CTEST_COMMAND}
--build-and-test
"${CMake_SOURCE_DIR}/Tests/ExternalProjectUpdate"
@@ -1092,6 +1454,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--build-project ExternalProjectUpdateTest
--build-exe-dir "${CMake_BINARY_DIR}/Tests/ExternalProjectUpdate"
--force-new-ctest-process
+ --build-options ${build_options}
--test-command ${CMAKE_CTEST_COMMAND} -V
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProjectUpdate")
@@ -1102,9 +1465,9 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
COMMAND ${CMAKE_CMAKE_COMMAND}
-DExternalProjectUpdate_SOURCE_DIR:PATH=${CMake_SOURCE_DIR}/Tests/ExternalProjectUpdate
-DExternalProjectUpdate_BINARY_DIR:PATH=${CMake_BINARY_DIR}/Tests/ExternalProjectUpdate
- -DCMAKE_TEST_GENERATOR=${CMAKE_TEST_GENERATOR}
- -DCMAKE_TEST_GENERATOR_TOOLSET=${CMAKE_TEST_GENERATOR_TOOLSET}
- -DCMAKE_TEST_MAKEPROGRAM=${CMAKE_TEST_MAKEPROGRAM}
+ -DCMAKE_GENERATOR=${CMAKE_GENERATOR}
+ -DCMAKE_GENERATOR_PLATFORM=${CMAKE_GENERATOR_PLATFORM}
+ -DCMAKE_GENERATOR_TOOLSET=${CMAKE_GENERATOR_TOOLSET}
-DCMAKE_CTEST_COMMAND=${CMAKE_CTEST_COMMAND}
-P ${CMake_SOURCE_DIR}/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake
)
@@ -1123,6 +1486,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--build-two-config
${build_generator_args}
--build-project Tutorial
+ --build-options ${build_options}
--test-command Tutorial 25.0)
endforeach()
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Tutorial")
@@ -1133,6 +1497,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
"${CMake_BINARY_DIR}/Tests/Testing"
${build_generator_args}
--build-project Testing
+ --build-options ${build_options}
--test-command ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE}
)
set_tests_properties(testing PROPERTIES PASS_REGULAR_EXPRESSION "Passed")
@@ -1145,6 +1510,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
${build_generator_args}
--build-project Wrapping
--build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin"
+ --build-options ${build_options}
--test-command wrapping
)
add_test(qtwrapping ${CMAKE_CTEST_COMMAND}
@@ -1154,6 +1520,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
${build_generator_args}
--build-project Wrapping
--build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin"
+ --build-options ${build_options}
--test-command qtwrapping
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Wrapping")
@@ -1165,6 +1532,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
${build_generator_args}
--build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin"
--build-project TestDriverTest
+ --build-options ${build_options}
--test-command TestDriverTest test1
)
@@ -1175,6 +1543,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
${build_generator_args}
--build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin"
--build-project TestDriverTest
+ --build-options ${build_options}
--test-command TestDriverTest test2
)
@@ -1185,6 +1554,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
${build_generator_args}
--build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin"
--build-project TestDriverTest
+ --build-options ${build_options}
--test-command TestDriverTest subdir/test3
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/TestDriver")
@@ -1196,11 +1566,12 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--build-exe-dir "${CMake_BINARY_DIR}/Tests/Dependency/Exec"
${build_generator_args}
--build-project Dependency
+ --build-options ${build_options}
--test-command exec
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Dependency")
- if("${CMAKE_SYSTEM_NAME}" MATCHES syllable)
+ if(CMAKE_SYSTEM_NAME MATCHES syllable)
# RPATH isn't supported under Syllable, so the tests don't
# find their libraries. In order to fix that LIBRARY_OUTPUT_DIR
@@ -1225,7 +1596,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--build-exe-dir "${CMake_BINARY_DIR}/Tests/Jump/WithLibOut/Executable"
--build-project Jump
${build_generator_args}
- --build-options
+ --build-options ${build_options}
-DLIBRARY_OUTPUT_PATH:PATH=${CMake_BINARY_DIR}/Tests/Jump/WithLibOut/Lib
--test-command jumpExecutable
)
@@ -1238,6 +1609,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--build-run-dir "${CMake_BINARY_DIR}/Tests/Jump/NoLibOut/Executable"
--build-project Jump
${build_generator_args}
+ --build-options ${build_options}
--test-command jumpExecutable
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Jump")
@@ -1249,6 +1621,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
${build_generator_args}
--build-project Plugin
--build-two-config
+ --build-options ${build_options}
--test-command bin/example)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Plugin")
@@ -1264,15 +1637,24 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
"${CMake_BINARY_DIR}/Tests/MacRuntimePath"
${build_generator_args}
--build-project MacRuntimePath
+ --build-options ${build_options}
+ -DCMake_TEST_NESTED_MAKE_PROGRAM:FILEPATH=${CMake_TEST_EXPLICIT_MAKE_PROGRAM}
)
endif()
+ if(CMake_TEST_XCODE_VERSION AND NOT CMake_TEST_XCODE_VERSION VERSION_LESS 5
+ AND OSX_VERSION MATCHES "^([0-9]+\\.[0-9]+)")
+ set(XCTest_BUILD_OPTIONS -DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_MATCH_1})
+ ADD_TEST_MACRO(XCTest ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> -V)
+ endif()
+
add_test(linkorder1 ${CMAKE_CTEST_COMMAND}
--build-and-test
"${CMake_SOURCE_DIR}/Tests/LinkLineOrder"
"${CMake_BINARY_DIR}/Tests/LinkLineOrder"
${build_generator_args}
--build-project LinkLineOrder
+ --build-options ${build_options}
--test-command Exec1
)
@@ -1282,6 +1664,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
"${CMake_BINARY_DIR}/Tests/LinkLineOrder"
${build_generator_args}
--build-project LinkLineOrder
+ --build-options ${build_options}
--test-command Exec2
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/LinkLineOrder")
@@ -1293,7 +1676,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
set_tests_properties ( SimpleInstall-Stage2 PROPERTIES DEPENDS SimpleInstall)
# Test static linking on toolchains known to support it.
- if("${CMAKE_C_COMPILER_ID}" MATCHES "^(GNU)$"
+ if(CMAKE_C_COMPILER_ID STREQUAL "GNU"
AND NOT APPLE AND NOT WIN32 AND NOT CYGWIN
AND EXISTS "/usr/lib/libm.a")
add_test(LinkStatic ${CMAKE_CTEST_COMMAND}
@@ -1302,24 +1685,13 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
"${CMake_BINARY_DIR}/Tests/LinkStatic"
${build_generator_args}
--build-project LinkStatic
- --build-options -DMATH_LIBRARY:FILEPATH=/usr/lib/libm.a
+ --build-options ${build_options}
+ -DMATH_LIBRARY:FILEPATH=/usr/lib/libm.a
--test-command LinkStatic
)
endif()
- if(NOT CMAKE_TEST_DIFFERENT_GENERATOR)
- add_test(kwsys ${CMAKE_CTEST_COMMAND}
- --build-and-test
- "${CMake_SOURCE_DIR}/Source/kwsys"
- "${CMake_BINARY_DIR}/Tests/kwsys"
- ${build_generator_args}
- --build-project kwsys
- --test-command kwsysTestsCxx testIOS
- )
- list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/kwsys")
- endif()
-
- if(MAKE_SUPPORTS_SPACES)
+ if(MAKE_SUPPORTS_SPACES AND NOT CMAKE_GENERATOR STREQUAL "Xcode")
add_test(SubDirSpaces ${CMAKE_CTEST_COMMAND}
--build-and-test
"${CMake_SOURCE_DIR}/Tests/SubDirSpaces"
@@ -1328,6 +1700,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
"${CMake_BINARY_DIR}/Tests/SubDirSpaces/Executable Sources"
${build_generator_args}
--build-project SUBDIR
+ --build-options ${build_options}
--test-command test
"${CMake_BINARY_DIR}/Tests/SubDirSpaces/ShouldBeHere"
"${CMake_BINARY_DIR}/Tests/SubDirSpaces/testfromsubdir.obj"
@@ -1343,6 +1716,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--build-exe-dir "${CMake_BINARY_DIR}/Tests/SubDir/Executable"
${build_generator_args}
--build-project SUBDIR
+ --build-options ${build_options}
--test-command test
"${CMake_BINARY_DIR}/Tests/SubDir/ShouldBeHere"
"${CMake_BINARY_DIR}/Tests/SubDir/testfromsubdir.obj"
@@ -1355,6 +1729,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--build-exe-dir "${CMake_BINARY_DIR}/Tests/SubDir/Executable"
${build_generator_args}
--build-project SUBDIR
+ --build-options ${build_options}
--test-command test
"${CMake_BINARY_DIR}/Tests/SubDir/ShouldBeHere"
"${CMake_BINARY_DIR}/Tests/SubDir/testfromsubdir.o"
@@ -1362,19 +1737,19 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
endif ()
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/SubDir")
- if(CMAKE_TEST_MSVC)
+ if(MSVC)
ADD_TEST_MACRO(ForceInclude foo)
ADD_TEST_MACRO(PDBDirectoryAndName myexe)
ADD_TEST_MACRO(PrecompiledHeader foo)
endif()
- if(CMAKE_TEST_MSVC OR
- "${CMAKE_TEST_GENERATOR}" MATCHES "(MSYS|MinGW) Makefiles")
+ if(MSVC OR
+ "${CMAKE_GENERATOR}" MATCHES "(MSYS|MinGW) Makefiles")
ADD_TEST_MACRO(ModuleDefinition example_exe)
endif()
ADD_TEST_MACRO(CheckCompilerRelatedVariables CheckCompilerRelatedVariables)
- if("${CMAKE_TEST_GENERATOR}" MATCHES "Makefile")
+ if("${CMAKE_GENERATOR}" MATCHES "Makefile")
add_test(MakeClean ${CMAKE_CTEST_COMMAND}
--build-and-test
"${CMake_SOURCE_DIR}/Tests/MakeClean"
@@ -1382,6 +1757,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
${build_generator_args}
--build-project MakeClean
--build-exe-dir "${CMake_BINARY_DIR}/MakeClean"
+ --build-options ${build_options}
--test-command check_clean
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/MakeClean")
@@ -1395,10 +1771,10 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
# Look for evidence that this is a VCExpress build. If so, avoid
# the MFC test by default.
- string(TOLOWER "${CMAKE_TEST_MAKEPROGRAM}" mkprog)
+ string(TOLOWER "${CMAKE_MAKE_PROGRAM}" mkprog)
if(mkprog MATCHES "vcexpress")
message(STATUS
- "CMAKE_TEST_MAKEPROGRAM indicates vcexpress, avoiding MFC test")
+ "CMAKE_MAKE_PROGRAM indicates vcexpress, avoiding MFC test")
set(CTEST_RUN_MFC OFF)
endif()
@@ -1419,7 +1795,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
# For the Watcom WMake generator, avoid the MFC test by default.
if(CTEST_RUN_MFC)
- if("${CMAKE_TEST_GENERATOR}" MATCHES "WMake")
+ if("${CMAKE_GENERATOR}" MATCHES "WMake")
message(STATUS
"using the Watcom WMake generator, avoiding MFC test")
set(CTEST_RUN_MFC OFF)
@@ -1486,18 +1862,27 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--build-two-config
${build_generator_args}
--build-project mfc_driver
+ --build-options ${build_options}
--test-command ${CMAKE_CTEST_COMMAND}
-C \${CTEST_CONFIGURATION_TYPE} -VV)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/MFC")
endif()
- if(${CMAKE_TEST_GENERATOR} MATCHES "Visual Studio")
+ if(MSVC AND NOT MSVC_VERSION LESS 1310
+ AND NOT CMAKE_GENERATOR MATCHES "Visual Studio [67]( |$)"
+ AND (NOT CMAKE_GENERATOR MATCHES "Visual Studio [89]( |$)"
+ OR CMAKE_SIZEOF_VOID_P EQUAL 4)
+ )
+ ADD_TEST_MACRO(VSMASM VSMASM)
+ endif()
+
+ if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
if(NOT MSVC60)
ADD_TEST_MACRO(SBCS SBCS)
endif()
- if(NOT "${CMAKE_TEST_GENERATOR}" MATCHES "Visual Studio [6789]( |$)"
- AND NOT CMAKE_TEST_GENERATOR_TOOLSET)
+ if(NOT "${CMAKE_GENERATOR}" MATCHES "Visual Studio [6789]( |$)"
+ AND NOT CMAKE_GENERATOR_TOOLSET)
ADD_TEST_MACRO(VSWindowsFormsResx VSWindowsFormsResx)
endif()
@@ -1508,6 +1893,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--build-two-config
${build_generator_args}
--build-project VSExternalInclude
+ --build-options ${build_options}
--test-command VSExternalInclude)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSExternalInclude")
@@ -1518,10 +1904,11 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--build-two-config
${build_generator_args}
--build-project VSMidl
+ --build-options ${build_options}
--test-command VSMidl)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSMidl")
- if(NOT MSVC60 AND NOT CMAKE_TEST_MAKEPROGRAM MATCHES "[mM][sS][bB][uU][iI][lL][dD]\\.[eE][xX][eE]")
+ if(CMake_TEST_DEVENV)
# The test (and tested property) works with .sln files, so it's skipped when:
# * Using VS6, which doesn't use .sln files
# * cmake --build is set up to use MSBuild, since the MSBuild invocation does not use the .sln file
@@ -1533,8 +1920,12 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
"${CMake_BINARY_DIR}/Tests/VSExcludeFromDefaultBuild"
--build-config ${config}
--build-two-config
- ${build_generator_args}
+ --build-generator ${CMAKE_GENERATOR}
+ --build-makeprogram ${CMake_TEST_DEVENV}
+ --build-generator-platform "${CMAKE_GENERATOR_PLATFORM}"
+ --build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
--build-project VSExcludeFromDefaultBuild
+ --build-target install
--test-command ${CMAKE_COMMAND}
-D "activeConfig=${config}"
-D "allConfigs=${CMAKE_CONFIGURATION_TYPES}"
@@ -1549,32 +1940,184 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSExcludeFromDefaultBuild")
endif()
- if(CMAKE_TEST_GENERATOR MATCHES "Visual Studio ([0-5]|[6-9][0-9])")
- if(CMAKE_TEST_MAKEPROGRAM MATCHES "[mM][sS][bB][uU][iI][lL][dD]\\.[eE][xX][eE]")
- set(MSBUILD_EXECUTABLE "${CMAKE_TEST_MAKEPROGRAM}")
- else()
- if(CMAKE_TEST_GENERATOR MATCHES "Visual Studio (12)")
- set(_msbuild_hints "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\${CMAKE_MATCH_1}.0;MSBuildToolsPath]")
- else()
- set(_FDIR "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VC7;FrameworkDir32]")
- set(_FVER "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VC7;FrameworkVer32]")
- set(_msbuild_hints ${_FDIR}/${_FVER})
+ if(CMAKE_GENERATOR MATCHES "Visual Studio ([0-5]|[6-9][0-9])")
+ # This is Visual Studio 10 or above, so the default build tool is MSBuild.
+ add_test(NAME VSProjectInSubdir COMMAND ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/VSProjectInSubdir"
+ "${CMake_BINARY_DIR}/Tests/VSProjectInSubdir"
+ --build-two-config
+ --build-generator ${CMAKE_GENERATOR}
+ --build-generator-platform "${CMAKE_GENERATOR_PLATFORM}"
+ --build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
+ --build-project VSProjectInSubdir
+ --build-target test)
+ list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSProjectInSubdir")
+ endif()
+ endif()
+
+ if(WIN32)
+ # Macro to search for available Windows CE SDKs in the windows Registry
+ macro(select_wince_sdk selected_reg selected_sdk)
+ if(CMAKE_HOST_WIN32)
+ execute_process(COMMAND reg QUERY "HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows CE Tools\\SDKs"
+ OUTPUT_VARIABLE sdk_reg
+ ERROR_VARIABLE my_err)
+ string(REGEX REPLACE "HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Wow6432Node\\\\Microsoft\\\\Windows CE Tools\\\\SDKs\\\\" ";" sdk_list "${sdk_reg}")
+ list(LENGTH sdk_list sdk_list_len)
+ if (${sdk_list_len} GREATER 1)
+ list(GET sdk_list 1 _sdk) # The first entry is always empty due to the regex replace above
+ string(STRIP ${_sdk} _sdk) # Make sure there is no newline in the SDK name
endif()
- find_program(MSBUILD_EXECUTABLE NAMES msbuild HINTS ${_msbuild_hints})
+ # Build a key to be used by get_filename_component that is pointing to the SDK directory
+ set(_reg "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows CE Tools\\SDKs\\${_sdk}]")
+
+ # Set return values
+ set(${selected_reg} ${_reg})
+ set(${selected_sdk} ${_sdk})
+ endif(CMAKE_HOST_WIN32)
+ endmacro(select_wince_sdk)
+
+ set(reg_vs10 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0;InstallDir]")
+ set(reg_vs11 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\11.0;InstallDir]")
+ set(reg_vs12 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\12.0;InstallDir]")
+ set(reg_vs14 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots;KitsRoot10]")
+ set(reg_ws80 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v8.0;InstallationFolder]")
+ set(reg_ws81 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v8.1;InstallationFolder]")
+ set(reg_ws10_0 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\14.0\\Setup\\Build Tools for Windows 10;srcPath]")
+ set(reg_wp80 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\WindowsPhone\\v8.0;InstallationFolder]")
+ set(reg_wp81 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\WindowsPhone\\v8.1;InstallationFolder]")
+ select_wince_sdk(reg_wince wince_sdk)
+ set(reg_tegra "[HKEY_LOCAL_MACHINE\\SOFTWARE\\NVIDIA Corporation\\Nsight Tegra;sdkRoot]")
+ foreach(reg vs10 vs11 vs12 vs14 ws80 ws81 ws10_0 wp80 wp81 wince tegra)
+ get_filename_component(r "${reg_${reg}}" ABSOLUTE)
+ if(IS_DIRECTORY "${r}")
+ set(${reg} 1)
+ else()
+ set(${reg} 0)
endif()
- if(MSBUILD_EXECUTABLE)
- add_test(NAME VSProjectInSubdir COMMAND ${CMAKE_CTEST_COMMAND}
+ endforeach()
+ endif()
+
+ get_filename_component(ntver "[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion;CurrentVersion]" NAME)
+ if(WIN32 AND ntver VERSION_GREATER 6.1) # Windows >= 8.0
+ macro(add_test_VSWinStorePhone name generator systemName systemVersion)
+ add_test(NAME VSWinStorePhone.${name} COMMAND ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/VSWinStorePhone"
+ "${CMake_BINARY_DIR}/Tests/VSWinStorePhone/${name}"
+ --build-generator "${generator}"
+ --build-project VSWinStorePhone
+ --build-config $<CONFIGURATION>
+ --build-options -DCMAKE_SYSTEM_NAME=${systemName}
+ -DCMAKE_SYSTEM_VERSION=${systemVersion}
+ )
+ list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSWinStorePhone/${name}")
+ endmacro()
+
+ if(vs11 AND ws80)
+ add_test_VSWinStorePhone(vs11-store80-X86 "Visual Studio 11 2012" WindowsStore 8.0)
+ add_test_VSWinStorePhone(vs11-store80-ARM "Visual Studio 11 2012 ARM" WindowsStore 8.0)
+ add_test_VSWinStorePhone(vs11-store80-X64 "Visual Studio 11 2012 Win64" WindowsStore 8.0)
+ endif()
+ if(vs12 AND ws81)
+ add_test_VSWinStorePhone(vs12-store81-X86 "Visual Studio 12 2013" WindowsStore 8.1)
+ add_test_VSWinStorePhone(vs12-store81-ARM "Visual Studio 12 2013 ARM" WindowsStore 8.1)
+ add_test_VSWinStorePhone(vs12-store81-X64 "Visual Studio 12 2013 Win64" WindowsStore 8.1)
+
+ add_test(NAME VSXaml COMMAND ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/VSXaml"
+ "${CMake_BINARY_DIR}/Tests/VSXaml"
+ --build-generator "Visual Studio 12 2013"
+ --build-project VSXaml
+ --build-config $<CONFIGURATION>
+ --build-options -DCMAKE_SYSTEM_NAME=WindowsStore
+ -DCMAKE_SYSTEM_VERSION=8.1
+ )
+ endif()
+ if(vs14 AND ws10_0)
+ add_test_VSWinStorePhone(vs14-store10_0-X86 "Visual Studio 14 2015" WindowsStore 10.0)
+ add_test_VSWinStorePhone(vs14-store10_0-ARM "Visual Studio 14 2015 ARM" WindowsStore 10.0)
+ add_test_VSWinStorePhone(vs14-store10_0-X64 "Visual Studio 14 2015 Win64" WindowsStore 10.0)
+ endif()
+ if(vs11 AND wp80)
+ add_test_VSWinStorePhone(vs11-phone80-X86 "Visual Studio 11 2012" WindowsPhone 8.0)
+ add_test_VSWinStorePhone(vs11-phone80-ARM "Visual Studio 11 2012 ARM" WindowsPhone 8.0)
+ endif()
+ if(vs12 AND wp81)
+ add_test_VSWinStorePhone(vs12-phone81-X86 "Visual Studio 12 2013" WindowsPhone 8.1)
+ add_test_VSWinStorePhone(vs12-phone81-ARM "Visual Studio 12 2013 ARM" WindowsPhone 8.1)
+ endif()
+ endif()
+
+ if(WIN32 AND wince)
+ macro(add_test_VSWinCE name generator systemName systemVersion generatorPlatform)
+ # TODO: Fix the tutorial to make it work in cross compile
+ # currently the MakeTable is build for target and can not be used on the host
+ # This happens in part 5 so we build only part 1-4 of the tutorial
+ foreach(STP RANGE 1 4)
+ add_test(NAME "TutorialStep${STP}.${name}" COMMAND ${CMAKE_CTEST_COMMAND}
--build-and-test
- "${CMake_SOURCE_DIR}/Tests/VSProjectInSubdir"
- "${CMake_BINARY_DIR}/Tests/VSProjectInSubdir"
- --build-two-config
- --build-generator ${CMAKE_TEST_GENERATOR}
- --build-generator-toolset "${CMAKE_TEST_GENERATOR_TOOLSET}"
- --build-makeprogram "${MSBUILD_EXECUTABLE}"
- --build-project VSProjectInSubdir
- --build-target test)
- list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSProjectInSubdir")
- endif()
+ "${CMake_SOURCE_DIR}/Tests/Tutorial/Step${STP}"
+ "${CMake_BINARY_DIR}/Tests/Tutorial/Step${STP}_${name}"
+ --build-generator "${generator}"
+ --build-project Tutorial
+ --build-config $<CONFIGURATION>
+ --build-options -DCMAKE_SYSTEM_NAME=${systemName}
+ -DCMAKE_SYSTEM_VERSION=${systemVersion}
+ -DCMAKE_GENERATOR_PLATFORM=${generatorPlatform})
+ list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Tutorial/Step${STP}_${name}")
+ endforeach()
+ endmacro()
+
+ if(vs11)
+ add_test_VSWinCE(vs11-ce80-ARM "Visual Studio 11 2012" WindowsCE 8.0 ${wince_sdk})
+ endif()
+
+ if(vs12)
+ add_test_VSWinCE(vs12-ce80-ARM "Visual Studio 12 2013" WindowsCE 8.0 ${wince_sdk})
+ endif()
+ endif()
+
+ if (CMake_TEST_GreenHillsMULTI)
+ macro(add_test_GhsMulti name primaryTarget bspName)
+ add_test(NAME GhsMulti.${name} COMMAND ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/GhsMulti"
+ "${CMake_BINARY_DIR}/Tests/GhsMulti/${name}"
+ --build-generator "Green Hills MULTI"
+ --build-project ReturnNum
+ --build-config $<CONFIGURATION>
+ --build-options -DGHS_PRIMARY_TARGET=${primaryTarget}
+ -DGHS_BSP_NAME=${bspName}
+ )
+ endmacro ()
+ add_test_GhsMulti("arm_integrity_simarm" "arm_integrity.tgt" "simarm")
+ add_test_GhsMulti("arm64_integrity_simarm" "arm64_integrity.tgt" "simarm")
+ endif ()
+
+ if(tegra AND NOT "${CMake_SOURCE_DIR};${CMake_BINARY_DIR}" MATCHES " ")
+ macro(add_test_VSNsightTegra name generator)
+ add_test(NAME VSNsightTegra.${name} COMMAND ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/VSNsightTegra"
+ "${CMake_BINARY_DIR}/Tests/VSNsightTegra/${name}"
+ --build-generator "${generator}"
+ --build-project VSNsightTegra
+ --build-config $<CONFIGURATION>
+ --build-options -DCMAKE_SYSTEM_NAME=Android
+ )
+ list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSNsightTegra/${name}")
+ endmacro()
+ if(vs10)
+ add_test_VSNsightTegra(vs10 "Visual Studio 10 2010")
+ endif()
+ if(vs11)
+ add_test_VSNsightTegra(vs11 "Visual Studio 11 2012")
+ endif()
+ if(vs12)
+ add_test_VSNsightTegra(vs12 "Visual Studio 12 2013")
endif()
endif()
@@ -1591,23 +2134,26 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--build-project BundleTest
--build-target install
# --build-target package
- --build-options "-DCMAKE_INSTALL_PREFIX:PATH=${BundleTestInstallDir}"
+ --build-options ${build_options}
+ "-DCMAKE_INSTALL_PREFIX:PATH=${BundleTestInstallDir}"
"-DCMake_SOURCE_DIR:PATH=${CMake_SOURCE_DIR}"
--test-command
${BundleTestInstallDir}/Applications/SecondBundleExe.app/Contents/MacOS/SecondBundleExe)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/BundleTest")
- add_test(CFBundleTest ${CMAKE_CTEST_COMMAND}
+ add_test(NAME CFBundleTest COMMAND ${CMAKE_CTEST_COMMAND}
--build-and-test
"${CMake_SOURCE_DIR}/Tests/CFBundleTest"
"${CMake_BINARY_DIR}/Tests/CFBundleTest"
--build-two-config
${build_generator_args}
--build-project CFBundleTest
+ --build-config $<CONFIGURATION>
+ --build-options ${build_options}
--test-command
- ${CMAKE_CMAKE_COMMAND} -DCTEST_CONFIGURATION_TYPE=\${CTEST_CONFIGURATION_TYPE}
+ ${CMAKE_CMAKE_COMMAND} -DCTEST_CONFIGURATION_TYPE=$<CONFIGURATION>
-Ddir=${CMake_BINARY_DIR}/Tests/CFBundleTest
- -Dgen=${CMAKE_TEST_GENERATOR}
+ -Dgen=${CMAKE_GENERATOR}
-P ${CMake_SOURCE_DIR}/Tests/CFBundleTest/VerifyResult.cmake)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CFBundleTest")
@@ -1624,7 +2170,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
${build_generator_args}
--build-project BundleGeneratorTest
--build-target package
- --build-options "-DCMAKE_INSTALL_PREFIX:PATH=${CMake_BINARY_DIR}/Tests/BundleGeneratorTest/InstallDirectory"
+ --build-options ${build_options}
+ "-DCMAKE_INSTALL_PREFIX:PATH=${CMake_BINARY_DIR}/Tests/BundleGeneratorTest/InstallDirectory"
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/BundleGeneratorTest")
endif()
@@ -1636,7 +2183,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
${build_generator_args}
--build-noclean
--build-project WarnUnusedUnusedViaSet
- --build-options "--warn-unused-vars")
+ --build-options ${build_options}
+ "--warn-unused-vars")
set_tests_properties(WarnUnusedUnusedViaSet PROPERTIES
PASS_REGULAR_EXPRESSION "unused variable \\(changing definition\\) 'UNUSED_VARIABLE'")
set_tests_properties(WarnUnusedUnusedViaSet PROPERTIES
@@ -1650,14 +2198,15 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
${build_generator_args}
--build-noclean
--build-project WarnUnusedUnusedViaUnset
- --build-options "--warn-unused-vars")
+ --build-options ${build_options}
+ "--warn-unused-vars")
set_tests_properties(WarnUnusedUnusedViaUnset PROPERTIES
- PASS_REGULAR_EXPRESSION "CMake Warning .*VariableUnusedViaUnset.CMakeLists.txt:7 \\(set\\):")
+ PASS_REGULAR_EXPRESSION "CMake Warning \\(dev\\) at CMakeLists.txt:7 \\(set\\):")
set_tests_properties(WarnUnusedUnusedViaUnset PROPERTIES
- FAIL_REGULAR_EXPRESSION "CMake Warning .*VariableUnusedViaUnset.CMakeLists.txt:5 \\(set\\):")
+ FAIL_REGULAR_EXPRESSION "CMakeLists.txt:5 \\(set\\):")
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/WarnUnusedUnusedViaUnset")
- if("${CMAKE_TEST_GENERATOR}" MATCHES "Makefile" AND NOT WIN32)
+ if("${CMAKE_GENERATOR}" MATCHES "Makefile" AND NOT WIN32)
# Ninja does not support ADDITIONAL_MAKE_CLEAN_FILES and therefore fails
# this test. (See #13371)
# Apparently Visual Studio does not support it either. As the MakeClean
@@ -1669,7 +2218,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
"${CMake_BINARY_DIR}/Tests/WarnUnusedCliUnused"
${build_generator_args}
--build-project WarnUnusedCliUnused
- --build-options "-DUNUSED_CLI_VARIABLE=Unused")
+ --build-options ${build_options}
+ "-DUNUSED_CLI_VARIABLE=Unused")
set_tests_properties(WarnUnusedCliUnused PROPERTIES
PASS_REGULAR_EXPRESSION "CMake Warning:.*Manually-specified variables were not used by the project:.* UNUSED_CLI_VARIABLE")
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/WarnUnusedCliUnused")
@@ -1682,7 +2232,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
${build_generator_args}
--build-noclean
--build-project WarnUnusedCliUsed
- --build-options "-DUSED_VARIABLE=Usage proven")
+ --build-options ${build_options}
+ "-DUSED_VARIABLE=Usage proven")
set_tests_properties(WarnUnusedCliUsed PROPERTIES
PASS_REGULAR_EXPRESSION "Usage proven")
set_tests_properties(WarnUnusedCliUsed PROPERTIES
@@ -1696,12 +2247,14 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
${build_generator_args}
--build-noclean
--build-project WarnUninitialized
- --build-options "--warn-uninitialized")
+ --build-options ${build_options}
+ "--warn-uninitialized")
set_tests_properties(WarnUninitialized PROPERTIES
PASS_REGULAR_EXPRESSION "uninitialized variable 'USED_VARIABLE'")
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/WarnUninitialized")
- add_test(TestsWorkingDirectory ${CMAKE_CTEST_COMMAND}
+ add_test(TestsWorkingDirectory
+ ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE}
--build-and-test
"${CMake_SOURCE_DIR}/Tests/TestsWorkingDirectory"
"${CMake_BINARY_DIR}/Tests/TestsWorkingDirectory"
@@ -1709,6 +2262,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--build-project TestsWorkingDirectoryProj
--build-exe-dir "${CMake_BINARY_DIR}/Tests/TestsWorkingDirectory"
--force-new-ctest-process
+ --build-options ${build_options}
--test-command ${CMAKE_CTEST_COMMAND} -V -C \${CTEST_CONFIGURATION_TYPE}
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/TestsWorkingDirectory")
@@ -1725,17 +2279,21 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
# )
# A test for ctest_build() with targets in subdirectories
- if(CMAKE_TEST_GENERATOR_TOOLSET)
- set(CMAKE_TEST_GENERATOR_TOOLSET_SELECTION "-T;${CMAKE_TEST_GENERATOR_TOOLSET};")
- else()
- set(CMAKE_TEST_GENERATOR_TOOLSET_SELECTION)
+ set(ctest_configure_options)
+ if(CMAKE_GENERATOR_PLATFORM)
+ list(APPEND ctest_configure_options -A ${CMAKE_GENERATOR_PLATFORM})
+ endif()
+ if(CMAKE_GENERATOR_TOOLSET)
+ list(APPEND ctest_configure_options -T ${CMAKE_GENERATOR_TOOLSET})
+ endif()
+ if(CMake_TEST_EXPLICIT_MAKE_PROGRAM)
+ list(APPEND ctest_configure_options -DCMAKE_MAKE_PROGRAM:FILEPATH=${CMake_TEST_EXPLICIT_MAKE_PROGRAM})
endif()
configure_file("${CMake_SOURCE_DIR}/Tests/CTestBuildCommandProjectInSubdir/CTestBuildCommandProjectInSubdir.cmake.in"
"${CMake_BINARY_DIR}/Tests/CTestBuildCommandProjectInSubdir/CTestBuildCommandProjectInSubdir.cmake" @ONLY)
- unset(CMAKE_TEST_GENERATOR_TOOLSET_SELECTION)
+ unset(ctest_configure_options)
add_test(CTest.BuildCommand.ProjectInSubdir
- ${CMAKE_CTEST_COMMAND} -S "${CMake_BINARY_DIR}/Tests/CTestBuildCommandProjectInSubdir/CTestBuildCommandProjectInSubdir.cmake"
- -DCMAKE_MAKE_PROGRAM:FILEPATH=${CMAKE_TEST_MAKEPROGRAM})
+ ${CMAKE_CTEST_COMMAND} -S "${CMake_BINARY_DIR}/Tests/CTestBuildCommandProjectInSubdir/CTestBuildCommandProjectInSubdir.cmake")
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CTestBuildCommandProjectInSubdir/Nested")
set(CTEST_TEST_UPDATE 1)
@@ -1856,6 +2414,26 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${CTestUpdateHG_DIR}")
endif()
+
+ # Test CTest Update with P4
+ find_program(P4_EXECUTABLE NAMES p4)
+ find_program(P4D_EXECUTABLE NAMES p4d)
+ mark_as_advanced(P4_EXECUTABLE P4D_EXECUTABLE)
+ set(CTEST_TEST_UPDATE_P4 0)
+ if(P4_EXECUTABLE AND P4D_EXECUTABLE)
+ if(NOT "${P4_EXECUTABLE};${P4D_EXECUTABLE}" MATCHES "cygwin" OR UNIX)
+ set(CTEST_TEST_UPDATE_P4 1)
+ endif()
+ endif()
+ if(CTEST_TEST_UPDATE_P4)
+ set(CTestUpdateP4_DIR "CTest UpdateP4")
+ configure_file("${CMake_SOURCE_DIR}/Tests/CTestUpdateP4.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestUpdateP4.cmake" @ONLY)
+ add_test(CTest.UpdateP4 ${CMAKE_CMAKE_COMMAND}
+ -P "${CMake_BINARY_DIR}/Tests/CTestUpdateP4.cmake"
+ )
+ list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${CTestUpdateP4_DIR}")
+ endif()
endif()
configure_file(
@@ -1893,35 +2471,29 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
PASS_REGULAR_EXPRESSION "Upload\\.xml")
configure_file(
- "${CMake_SOURCE_DIR}/Tests/CTestTestConfigFileInBuildDir/test1.cmake.in"
- "${CMake_BINARY_DIR}/Tests/CTestTestConfigFileInBuildDir1/test1.cmake"
+ "${CMake_SOURCE_DIR}/Tests/CTestCoverageCollectGCOV/test.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestCoverageCollectGCOV/test.cmake"
@ONLY ESCAPE_QUOTES)
- add_test(CTestTestConfigFileInBuildDir1 ${CMAKE_CTEST_COMMAND}
- -S "${CMake_BINARY_DIR}/Tests/CTestTestConfigFileInBuildDir1/test1.cmake" -V
- --output-log "${CMake_BINARY_DIR}/Tests/CTestTestConfigFileInBuildDir1/testOut1.log"
+ add_test(CTestCoverageCollectGCOV ${CMAKE_CTEST_COMMAND}
+ -C \${CTEST_CONFIGURATION_TYPE}
+ -S "${CMake_BINARY_DIR}/Tests/CTestCoverageCollectGCOV/test.cmake" -VV
+ --output-log "${CMake_BINARY_DIR}/Tests/CTestCoverageCollectGCOV/testOut.log"
)
- REGEX_ESCAPE_STRING(CTEST_TEST_ESCAPED_SOURCE_DIR "${CMake_SOURCE_DIR}")
- set_tests_properties(CTestTestConfigFileInBuildDir1 PROPERTIES DEPENDS CTestTestNoBuild
+ set_tests_properties(CTestCoverageCollectGCOV PROPERTIES
PASS_REGULAR_EXPRESSION
- "Reading ctest configuration file: ${CTEST_TEST_ESCAPED_SOURCE_DIR}.Tests.CTestTestConfigFileInBuildDir.CTestConfig.cmake")
+ "PASSED with correct output.*Testing/CoverageInfo/main.cpp.gcov")
+ set_property(TEST CTestCoverageCollectGCOV PROPERTY ENVIRONMENT CTEST_PARALLEL_LEVEL=)
configure_file(
- "${CMake_SOURCE_DIR}/Tests/CTestTestConfigFileInBuildDir/test2.cmake.in"
- "${CMake_BINARY_DIR}/Tests/CTestTestConfigFileInBuildDir2/test2.cmake"
+ "${CMake_SOURCE_DIR}/Tests/CTestTestEmptyBinaryDirectory/test.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestEmptyBinaryDirectory/test.cmake"
@ONLY ESCAPE_QUOTES)
- configure_file(
- "${CMake_SOURCE_DIR}/Tests/CTestTestConfigFileInBuildDir/CTestConfig.cmake"
- "${CMake_BINARY_DIR}/Tests/CTestTestConfigFileInBuildDir2/CTestConfig.cmake"
- @ONLY ESCAPE_QUOTES COPYONLY)
- add_test(CTestTestConfigFileInBuildDir2 ${CMAKE_CTEST_COMMAND}
- -S "${CMake_BINARY_DIR}/Tests/CTestTestConfigFileInBuildDir2/test2.cmake" -V
- --output-log "${CMake_BINARY_DIR}/Tests/CTestTestConfigFileInBuildDir2/testOut2.log"
+ add_test(CTestTestEmptyBinaryDirectory ${CMAKE_CTEST_COMMAND}
+ -S "${CMake_BINARY_DIR}/Tests/CTestTestEmptyBinaryDirectory/test.cmake" -V
+ --output-log "${CMake_BINARY_DIR}/Tests/CTestTestEmptyBinaryDirectory/testOut.log"
)
- REGEX_ESCAPE_STRING(CTEST_TEST_ESCAPED_BINARY_DIR "${CMake_BINARY_DIR}")
- set_tests_properties(CTestTestConfigFileInBuildDir2 PROPERTIES DEPENDS CTestTestNoBuild
- REQUIRED_FILES ${CMake_BINARY_DIR}/Tests/CTestTestConfigFileInBuildDir2/CTestConfig.cmake
- PASS_REGULAR_EXPRESSION
- "Reading ctest configuration file: ${CTEST_TEST_ESCAPED_BINARY_DIR}.Tests.CTestTestConfigFileInBuildDir2.CTestConfig.cmake")
+ set_tests_properties(CTestTestEmptyBinaryDirectory PROPERTIES
+ PASS_REGULAR_EXPRESSION "TEST_SUCCESS")
# test coverage for mumps
# create a MumpsCoverage dir in the binary tree under Testing to
@@ -1932,6 +2504,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
configure_file(
"${CMake_SOURCE_DIR}/Tests/MumpsCoverage/gtm_coverage.mcov.in"
"${CMake_BINARY_DIR}/Testing/MumpsCoverage/gtm_coverage.mcov")
+ file(REMOVE_RECURSE "${CMake_BINARY_DIR}/Testing/MumpsCoverage/VistA-FOIA")
file(COPY "${CMake_SOURCE_DIR}/Tests/MumpsCoverage/VistA-FOIA"
DESTINATION "${CMake_BINARY_DIR}/Testing/MumpsCoverage")
add_test(NAME CTestGTMCoverage
@@ -1940,7 +2513,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
$<TARGET_FILE:ctest> -T Coverage --debug)
set_tests_properties(CTestGTMCoverage PROPERTIES
PASS_REGULAR_EXPRESSION
- "Process file.*XINDEX.m.*Total LOC:.*127.*Percentage Coverage: 85.83.*"
+ "Process file.*ZZCOVTST.m.*Total LOC:.*30.*Percentage Coverage: 80.00*"
ENVIRONMENT COVFILE=)
configure_file(
@@ -1949,6 +2522,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
configure_file(
"${CMake_SOURCE_DIR}/Tests/MumpsCoverage/cache_coverage.cmcov.in"
"${CMake_BINARY_DIR}/Testing/MumpsCacheCoverage/cache_coverage.cmcov")
+ file(REMOVE_RECURSE "${CMake_BINARY_DIR}/Testing/MumpsCacheCoverage/VistA-FOIA")
file(COPY "${CMake_SOURCE_DIR}/Tests/MumpsCoverage/VistA-FOIA"
DESTINATION "${CMake_BINARY_DIR}/Testing/MumpsCacheCoverage")
add_test(NAME CTestCacheCoverage
@@ -1957,14 +2531,102 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
$<TARGET_FILE:ctest> -T Coverage --debug)
set_tests_properties(CTestCacheCoverage PROPERTIES
PASS_REGULAR_EXPRESSION
- "Process file.*XINDEX.m.*Total LOC:.*125.*Percentage Coverage: 85.60.*"
+ "Process file.*ZZCOVTST.m.*Total LOC:.*29.*Percentage Coverage: 86.21.*"
ENVIRONMENT COVFILE=)
- # Use macro, not function so that build can still be driven by CMake 2.4.
- # After 2.6 is required, this could be a function without the extra 'set'
- # calls.
- #
- macro(add_config_tests cfg)
- set(cfg "${cfg}")
+
+ # Adding a test case for Python Coverage
+ configure_file(
+ "${CMake_SOURCE_DIR}/Tests/PythonCoverage/coverage.xml.in"
+ "${CMake_BINARY_DIR}/Testing/PythonCoverage/coverage.xml")
+ configure_file(
+ "${CMake_SOURCE_DIR}/Tests/PythonCoverage/DartConfiguration.tcl.in"
+ "${CMake_BINARY_DIR}/Testing/PythonCoverage/DartConfiguration.tcl")
+ file(COPY "${CMake_SOURCE_DIR}/Tests/PythonCoverage/coveragetest"
+ DESTINATION "${CMake_BINARY_DIR}/Testing/PythonCoverage")
+ add_test(NAME CTestPythonCoverage
+ COMMAND cmake -E chdir
+ ${CMake_BINARY_DIR}/Testing/PythonCoverage
+ $<TARGET_FILE:ctest> -T Coverage --debug)
+ set_tests_properties(CTestPythonCoverage PROPERTIES
+ PASS_REGULAR_EXPRESSION
+ "Process file.*foo.py.*Total LOC:.*13.*Percentage Coverage: 84.62.*"
+ ENVIRONMENT COVFILE=)
+
+ # Adding a test case for non-python Cobertura Coverage
+ configure_file(
+ "${CMake_SOURCE_DIR}/Tests/CoberturaCoverage/DartConfiguration.tcl.in"
+ "${CMake_BINARY_DIR}/Testing/CoberturaCoverage/DartConfiguration.tcl")
+ configure_file(
+ "${CMake_SOURCE_DIR}/Tests/CoberturaCoverage/coverage.xml.in"
+ "${CMake_BINARY_DIR}/Testing/CoberturaCoverage/coverage.xml")
+ file(COPY "${CMake_SOURCE_DIR}/Tests/CoberturaCoverage/src"
+ DESTINATION "${CMake_BINARY_DIR}/Testing/CoberturaCoverage")
+ add_test(NAME CTestCoberturaCoverage
+ COMMAND cmake -E chdir
+ ${CMake_BINARY_DIR}/Testing/CoberturaCoverage
+ $<TARGET_FILE:ctest> -T Coverage --debug)
+ set_tests_properties(CTestCoberturaCoverage PROPERTIES
+ PASS_REGULAR_EXPRESSION
+ "Process file.*CoverageTest.java.*Total LOC:.*18.*Percentage Coverage: 72.22.*"
+ ENVIRONMENT COBERTURADIR=${CMake_BINARY_DIR}/Testing/CoberturaCoverage
+ ENVIRONMENT COVFILE=)
+
+
+ # Adding a test case for JaCoCo Coverage
+ configure_file(
+ "${CMake_SOURCE_DIR}/Tests/JacocoCoverage/DartConfiguration.tcl.in"
+ "${CMake_BINARY_DIR}/Testing/JacocoCoverage/DartConfiguration.tcl")
+ file(COPY "${CMake_SOURCE_DIR}/Tests/JacocoCoverage/Coverage"
+ DESTINATION "${CMake_BINARY_DIR}/Testing/JacocoCoverage")
+ configure_file("${CMake_BINARY_DIR}/Testing/JacocoCoverage/Coverage/target/site/jacoco.xml.in"
+ "${CMake_BINARY_DIR}/Testing/JacocoCoverage/Coverage/target/site/jacoco.xml")
+ add_test(NAME CTestJacocoCoverage
+ COMMAND cmake -E chdir
+ ${CMake_BINARY_DIR}/Testing/JacocoCoverage
+ $<TARGET_FILE:ctest> -T Coverage --debug)
+ set_tests_properties(CTestJacocoCoverage PROPERTIES
+ PASS_REGULAR_EXPRESSION
+ "Process file.*CoverageTest.java.*Total LOC:.*17.*Percentage Coverage: 76.47*"
+ ENVIRONMENT COVFILE=)
+
+ # Adding a test case for Javascript Coverage
+ configure_file(
+ "${CMake_SOURCE_DIR}/Tests/JavascriptCoverage/DartConfiguration.tcl.in"
+ "${CMake_BINARY_DIR}/Testing/JavascriptCoverage/DartConfiguration.tcl")
+ configure_file(
+ "${CMake_SOURCE_DIR}/Tests/JavascriptCoverage/output.json.in"
+ "${CMake_BINARY_DIR}/Testing/JavascriptCoverage/output.json")
+ file(COPY "${CMake_SOURCE_DIR}/Tests/JavascriptCoverage/"
+ DESTINATION "${CMake_BINARY_DIR}/Testing/JavascriptCoverage"
+ FILES_MATCHING PATTERN "*.js")
+ add_test(NAME CTestJavascriptCoverage
+ COMMAND cmake -E chdir
+ ${CMake_BINARY_DIR}/Testing/JavascriptCoverage
+ $<TARGET_FILE:ctest> -T Coverage --debug)
+ set_tests_properties(CTestJavascriptCoverage PROPERTIES
+ PASS_REGULAR_EXPRESSION
+ "Process file.*test3.js.*Total LOC:.*49.*Percentage Coverage: 79.59*"
+ ENVIRONMENT COVFILE=)
+
+ # test coverage for Delphi-code-Coverage
+ configure_file(
+ "${CMake_SOURCE_DIR}/Tests/DelphiCoverage/DartConfiguration.tcl.in"
+ "${CMake_BINARY_DIR}/Testing/DelphiCoverage/DartConfiguration.tcl")
+ file(COPY "${CMake_SOURCE_DIR}/Tests/DelphiCoverage/src"
+ DESTINATION "${CMake_BINARY_DIR}/Testing/DelphiCoverage")
+ configure_file(
+ "${CMake_SOURCE_DIR}/Tests/DelphiCoverage/UTCovTest(UTCovTest.pas).html.in"
+ "${CMake_BINARY_DIR}/Testing/DelphiCoverage/UTCovTest(UTCovTest.pas).html")
+ add_test(NAME CTestDelphiCoverage
+ COMMAND cmake -E chdir
+ ${CMake_BINARY_DIR}/Testing/DelphiCoverage
+ $<TARGET_FILE:ctest> -T Coverage --debug)
+ set_tests_properties(CTestDelphiCoverage PROPERTIES
+ PASS_REGULAR_EXPRESSION
+ "Process file.*UTCovTest.pas.*Total LOC:.*20.*Percentage Coverage: 95.*"
+ ENVIRONMENT COVFILE=)
+
+ function(add_config_tests cfg)
set(base "${CMake_BINARY_DIR}/Tests/CTestConfig")
# Test -S script with a -C config arg to ctest:
@@ -1988,7 +2650,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
add_test(CTestConfig.Dashboard.${cfg} ${CMAKE_CMAKE_COMMAND}
-P "${base}/${cfg}-dashboard.cmake" -VV
)
- endmacro()
+ endfunction()
add_config_tests(Debug)
add_config_tests(MinSizeRel)
@@ -2008,6 +2670,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--output-log "${CMake_BINARY_DIR}/Tests/CTestConfig/ScriptWithArgs.log"
)
+ ADD_TEST_MACRO(CMakeCommands.add_compile_options add_compile_options)
ADD_TEST_MACRO(CMakeCommands.target_link_libraries target_link_libraries)
ADD_TEST_MACRO(CMakeCommands.target_include_directories target_include_directories)
ADD_TEST_MACRO(CMakeCommands.target_compile_definitions target_compile_definitions)
@@ -2022,7 +2685,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--output-log "${CMake_BINARY_DIR}/Tests/CTestTestCrash/testOutput.log"
)
# with watcom the SEGFAULT is not found, it just fails
- if(CMAKE_TEST_GENERATOR MATCHES "Watcom WMake")
+ if(CMAKE_GENERATOR MATCHES "Watcom WMake")
set_tests_properties(CTestTestCrash PROPERTIES
PASS_REGULAR_EXPRESSION "Failed")
else()
@@ -2048,6 +2711,18 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
PASS_REGULAR_EXPRESSION "${CTestTestBadExe_REGEX}")
configure_file(
+ "${CMake_SOURCE_DIR}/Tests/CTestTestBadGenerator/test.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestBadGenerator/test.cmake"
+ @ONLY ESCAPE_QUOTES)
+ add_test(CTestTestBadGenerator ${CMAKE_CTEST_COMMAND}
+ -C "\${CTestTest_CONFIG}"
+ -S "${CMake_BINARY_DIR}/Tests/CTestTestBadGenerator/test.cmake" -V
+ --output-log "${CMake_BINARY_DIR}/Tests/CTestTestBadGenerator/testOutput.log"
+ )
+ set_property(TEST CTestTestBadGenerator PROPERTY
+ PASS_REGULAR_EXPRESSION "could not create generator named \"Bad Generator\"")
+
+ configure_file(
"${CMake_SOURCE_DIR}/Tests/CTestTestParallel/test.cmake.in"
"${CMake_BINARY_DIR}/Tests/CTestTestParallel/test.cmake"
@ONLY ESCAPE_QUOTES)
@@ -2056,8 +2731,45 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--output-log "${CMake_BINARY_DIR}/Tests/CTestTestParallel/testOutput.log"
)
+ configure_file("${CMake_SOURCE_DIR}/Tests/CTestTestVerboseOutput/test.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestVerboseOutput/test.cmake" @ONLY ESCAPE_QUOTES)
+ add_test(CTestTestVerboseOutput ${CMAKE_CTEST_COMMAND}
+ -S "${CMake_BINARY_DIR}/Tests/CTestTestVerboseOutput/test.cmake" -VV
+ --output-log "${CMake_BINARY_DIR}/Tests/CTestTestVerboseOutput/testOutput.log"
+ -C "\${CTestTest_CONFIG}"
+ )
+ set_property(TEST CTestTestVerboseOutput PROPERTY PASS_REGULAR_EXPRESSION
+ "Environment variables:.*foo=bar.*this=that"
+ )
+
+ configure_file(
+ "${CMake_SOURCE_DIR}/Tests/CTestTestSkipReturnCode/test.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestSkipReturnCode/test.cmake"
+ @ONLY ESCAPE_QUOTES)
+ add_test(CTestTestSkipReturnCode ${CMAKE_CTEST_COMMAND}
+ -S "${CMake_BINARY_DIR}/Tests/CTestTestSkipReturnCode/test.cmake" -V
+ --output-log "${CMake_BINARY_DIR}/Tests/CTestTestSkipReturnCode/testOutput.log"
+ -C \${CTEST_CONFIGURATION_TYPE}
+ )
+ set_tests_properties(CTestTestSkipReturnCode PROPERTIES
+ PASS_REGULAR_EXPRESSION "CMakeV1 \\.* +Passed.*CMakeV2 \\.+\\*+Skipped")
+ set_property(TEST CTestTestSkipReturnCode PROPERTY ENVIRONMENT CTEST_PARALLEL_LEVEL=)
+
+ ADD_TEST_MACRO(CTestTestSerialInDepends ${CMAKE_CTEST_COMMAND} -j 4
+ --output-on-failure -C "\${CTestTest_CONFIG}")
+
+ ADD_TEST_MACRO(CTestTestMissingDependsExe ${CMAKE_CTEST_COMMAND}
+ --output-on-failure -C "\${CTestTest_CONFIG}")
+ set_tests_properties(CTestTestMissingDependsExe PROPERTIES
+ PASS_REGULAR_EXPRESSION "\\*\\*\\*Not Run"
+ )
+
+ ADD_TEST_MACRO(CTestTestSerialOrder ${CMAKE_CTEST_COMMAND}
+ --output-on-failure -C "\${CTestTest_CONFIG}")
+ set_property(TEST CTestTestSerialOrder PROPERTY ENVIRONMENT CTEST_PARALLEL_LEVEL=)
+
if(NOT BORLAND)
- set(CTestLimitDashJ_EXTRA_OPTIONS --force-new-ctest-process)
+ set(CTestLimitDashJ_CTEST_OPTIONS --force-new-ctest-process)
add_test_macro(CTestLimitDashJ ${CMAKE_CTEST_COMMAND} -j 4
--output-on-failure -C "\${CTestTest_CONFIG}")
endif()
@@ -2068,6 +2780,17 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
"All Labels:.* Label1.* Label2")
configure_file(
+ "${CMake_SOURCE_DIR}/Tests/CTestTestLabelRegExp/test.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestLabelRegExp/test.cmake"
+ @ONLY ESCAPE_QUOTES)
+ add_test(NAME CTestTestLabelRegExp
+ COMMAND ${CMAKE_CMAKE_COMMAND}
+ -DSOURCE_DIR=${CMAKE_SOURCE_DIR}/Tests/CTestTestLabelRegExp
+ -P ${CMAKE_BINARY_DIR}/Tests/CTestTestLabelRegExp/test.cmake
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/Tests/CTestTestLabelRegExp
+ )
+
+ configure_file(
"${CMake_SOURCE_DIR}/Tests/CTestTestResourceLock/test.cmake.in"
"${CMake_BINARY_DIR}/Tests/CTestTestResourceLock/test.cmake"
@ONLY ESCAPE_QUOTES)
@@ -2137,7 +2860,14 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--output-log "${CMake_BINARY_DIR}/Tests/CTestTestTimeout/testOutput.log"
)
set_tests_properties(CTestTestTimeout PROPERTIES
- PASS_REGULAR_EXPRESSION "TestTimeout *\\.+ *\\*\\*\\*Timeout.*CheckChild *\\.+ *Passed")
+ PASS_REGULAR_EXPRESSION "TestTimeout *\\.+ *\\*\\*\\*Timeout.*TestSleep *\\.+ *Passed.*timeout correctly killed child")
+
+ add_test(
+ NAME CTestTestRerunFailed
+ COMMAND ${CMAKE_CTEST_COMMAND} --rerun-failed)
+ set_tests_properties(CTestTestRerunFailed PROPERTIES
+ PASS_REGULAR_EXPRESSION "1/1 Test #1: TestTimeout" DEPENDS CTestTestTimeout
+ WORKING_DIRECTORY ${CMake_BINARY_DIR}/Tests/CTestTestTimeout)
configure_file(
"${CMake_SOURCE_DIR}/Tests/CTestTestZeroTimeout/test.cmake.in"
@@ -2198,57 +2928,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--output-log "${CMake_BINARY_DIR}/Tests/CTestTestFdSetSize/testOutput.log"
)
- # Use macro, not function so that build can still be driven by CMake 2.4.
- # After 2.6 is required, this could be a function without the extra 'set'
- # calls.
- #
- macro(add_failed_submit_test name source build in out log regex)
- # Have variables named source, build and drop_method because the
- # configure_file call expects those variables to be defined.
- #
- set(source "${source}")
- set(build "${build}")
- configure_file("${in}" "${out}" @ONLY)
- add_test(${name} ${CMAKE_CTEST_COMMAND} -S "${out}" -V --output-log "${log}")
- set_tests_properties(${name} PROPERTIES PASS_REGULAR_EXPRESSION "${regex}")
- endmacro()
-
- set(regex "(Problems when submitting via S*CP")
- set(regex "${regex}|Error message was: ")
- set(regex "${regex}([Cc]ould *n.t resolve host")
- set(regex "${regex}|[Cc]ould *n.t connect to host")
- set(regex "${regex}|Empty reply from server")
- set(regex "${regex}|The requested URL returned error")
- set(regex "${regex}|libcurl was built with SSL disabled. https: not supported)")
- set(regex "${regex}|Submission method .xmlrpc. not compiled into CTest")
- set(regex "${regex}|Submission problem")
- set(regex "${regex}|Submission successful)")
-
- set(ctest_coverage_labels_args "")
-
- foreach(drop_method cp ftp http https scp xmlrpc)
- # Cycle through these values each time through the loop:
- if(ctest_coverage_labels_args STREQUAL "")
- set(ctest_coverage_labels_args "LABELS Everything")
- elseif(ctest_coverage_labels_args STREQUAL "LABELS Everything")
- set(ctest_coverage_labels_args "LABELS 0ArgTest")
- else()
- set(ctest_coverage_labels_args "")
- endif()
-
- add_failed_submit_test(CTestTestFailedSubmit-${drop_method}
- "${CMake_SOURCE_DIR}/Tests/CTestTest/SmallAndFast"
- "${CMake_BINARY_DIR}/Tests/CTestTestFailedSubmits/${drop_method}"
- "${CMake_SOURCE_DIR}/Tests/CTestTestFailedSubmits/test.cmake.in"
- "${CMake_BINARY_DIR}/Tests/CTestTestFailedSubmits/test-${drop_method}.cmake"
- "${CMake_BINARY_DIR}/Tests/CTestTestFailedSubmits/test-${drop_method}.log"
- "${regex}"
- )
- endforeach()
-
-
if (CMAKE_TESTS_CDASH_SERVER)
- set(regex "^([^:]+)://([^/]+)(/.*)$")
+ set(regex "^([^:]+)://([^/]+)(.*)$")
if ("${CMAKE_TESTS_CDASH_SERVER}" MATCHES "${regex}")
set(protocol "${CMAKE_MATCH_1}")
@@ -2256,8 +2937,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
set(path "${CMAKE_MATCH_3}")
else ()
set(protocol "http")
- set(server "www.cdash.org")
- set(path "/CDash")
+ set(server "open.cdash.org")
+ set(path "")
message("warning: CMAKE_TESTS_CDASH_SERVER does not match expected regex...")
message(" ...using default url='${protocol}://${server}${path}' for CTestTest[23]")
endif ()
@@ -2279,6 +2960,17 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--output-log "${CMake_BINARY_DIR}/Tests/CTestTest2/testOutput.log"
)
+ if("${CMAKE_GENERATOR}" MATCHES "Makefiles" OR "${CMAKE_GENERATOR}" MATCHES "Ninja")
+ configure_file("${CMake_SOURCE_DIR}/Tests/CTestTestLaunchers/test.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestLaunchers/test.cmake" @ONLY ESCAPE_QUOTES)
+ add_test(CTestTestLaunchers ${CMAKE_CTEST_COMMAND}
+ -S "${CMake_BINARY_DIR}/Tests/CTestTestLaunchers/test.cmake" -V
+ --output-log "${CMake_BINARY_DIR}/Tests/CTestTestLaunchers/testOutput.log"
+ )
+ set_tests_properties(CTestTestLaunchers PROPERTIES
+ PASS_REGULAR_EXPRESSION "CTEST_TEST_LAUNCHER_SUCCESS")
+ endif()
+
configure_file("${CMake_SOURCE_DIR}/Tests/CTestTestChecksum/test.cmake.in"
"${CMake_BINARY_DIR}/Tests/CTestTestChecksum/test.cmake" @ONLY
ESCAPE_QUOTES)
@@ -2305,7 +2997,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
endif ()
endif ()
- if("${CMAKE_TEST_GENERATOR}" MATCHES Xcode)
+ if("${CMAKE_GENERATOR}" MATCHES Xcode)
set(CMAKE_SKIP_BOOTSTRAP_TEST 1)
endif()
if(EXISTS "${CMake_BINARY_DIR}/CMakeLists.txt")
@@ -2323,16 +3015,12 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
endif()
endif()
if(bootstrap)
- add_test(BootstrapTest ${CMAKE_CTEST_COMMAND}
- --build-and-test
- ${CMake_SOURCE_DIR}
- ${CMake_BINARY_DIR}/Tests/BootstrapTest
- --build-nocmake
- --build-noclean
- --build-makeprogram ${bootstrap}
- --build-generator "${CMAKE_TEST_GENERATOR}"
- --test-command
- ${CMake_BINARY_DIR}/Tests/BootstrapTest/Bootstrap.cmk/cmake)
+ add_test(NAME BootstrapTest
+ COMMAND ${CMAKE_CMAKE_COMMAND}
+ -D "bootstrap=${bootstrap}"
+ -D "bin_dir=${CMake_BINARY_DIR}/Tests/BootstrapTest"
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/BootstrapTest.cmake
+ )
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/BootstrapTest")
# Make this test run early during parallel execution
set_tests_properties(BootstrapTest PROPERTIES COST 5000)
@@ -2353,6 +3041,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
${build_generator_args}
--build-project testf
--build-two-config
+ --build-options ${build_options}
+ -DCMake_TEST_NESTED_MAKE_PROGRAM:FILEPATH=${CMake_TEST_EXPLICIT_MAKE_PROGRAM}
--test-command testf)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Fortran")
@@ -2371,6 +3061,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
${build_generator_args}
--build-project FortranC
--build-two-config
+ --build-options ${build_options}
--test-command CMakeFiles/FortranCInterface/FortranCInterface)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/FortranC")
endif()
@@ -2378,7 +3069,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
find_package(Java COMPONENTS Development QUIET)
if(Java_JAVA_EXECUTABLE AND Java_JAVAC_EXECUTABLE AND Java_JAR_EXECUTABLE AND NOT MINGW
- AND NOT "${CMAKE_TEST_GENERATOR}" MATCHES "Xcode")
+ AND NOT "${CMAKE_GENERATOR}" MATCHES "Xcode")
get_filename_component(JNIPATH ${JAVA_COMPILE} PATH)
find_file(JNI_H jni.h
"${JNIPATH}/../include"
@@ -2386,22 +3077,61 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
if(JNI_H AND EXISTS "${JNI_H}") # in case jni.h is a broken symlink
file(READ "${JNI_H}" JNI_FILE)
if("${JNI_FILE}" MATCHES "JDK1_2")
- add_test(Java ${CMAKE_CTEST_COMMAND}
+ add_test(Java.Jar ${CMAKE_CTEST_COMMAND}
--build-and-test
"${CMake_SOURCE_DIR}/Tests/Java"
- "${CMake_BINARY_DIR}/Tests/Java"
+ "${CMake_BINARY_DIR}/Tests/JavaJar"
${build_generator_args}
--build-project hello
+ --build-target hello
--build-two-config
- --build-run-dir "${CMake_BINARY_DIR}/Tests/Java/"
+ --build-run-dir "${CMake_BINARY_DIR}/Tests/JavaJar/"
+ --build-options ${build_options}
--test-command ${JAVA_RUNTIME} -classpath hello.jar HelloWorld)
- list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Java")
+ list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/JavaJar")
+ add_test(Java.JarSourceList ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/Java"
+ "${CMake_BINARY_DIR}/Tests/JavaJarSourceList"
+ ${build_generator_args}
+ --build-project hello
+ --build-target hello2
+ --build-two-config
+ --build-run-dir "${CMake_BINARY_DIR}/Tests/JavaJarSourceList/"
+ --build-options ${build_options}
+ --test-command ${JAVA_RUNTIME} -classpath hello2.jar HelloWorld)
+ list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/JavaJarSourceList")
+
+ # For next test, java tool must have same architecture as toolchain
+ math(EXPR _object_mode "${CMAKE_SIZEOF_VOID_P} * 8")
+ execute_process(
+ COMMAND "${Java_JAVA_EXECUTABLE}" -d${_object_mode} -version
+ OUTPUT_QUIET ERROR_QUIET RESULT_VARIABLE _result
+ )
+ if(_result EQUAL 0)
+ if(CMAKE_CONFIGURATION_TYPES)
+ set (JAVAH_LIBRARY_PATH ${CMake_BINARY_DIR}/Tests/JavaJavah/$<CONFIGURATION>)
+ else()
+ set (JAVAH_LIBRARY_PATH ${CMake_BINARY_DIR}/Tests/JavaJavah)
+ endif()
+ add_test(NAME Java.Javah COMMAND ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/JavaJavah"
+ "${CMake_BINARY_DIR}/Tests/JavaJavah"
+ ${build_generator_args}
+ --build-project helloJavah
+ --build-two-config
+ --build-run-dir "${CMake_BINARY_DIR}/Tests/JavaJavah/"
+ --build-options ${build_options}
+ --test-command ${JAVA_RUNTIME} -Djava.library.path=${JAVAH_LIBRARY_PATH} -classpath hello3.jar HelloWorld2)
+ list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/JavaJavah")
+ endif()
endif()
endif()
endif()
# add some cross compiler tests, for now only with makefile based generators
- if(CMAKE_TEST_GENERATOR MATCHES "Makefiles" OR CMAKE_TEST_GENERATOR MATCHES "KDevelop")
+ if(CMAKE_GENERATOR MATCHES "Makefiles" OR CMAKE_GENERATOR MATCHES "KDevelop")
# if sdcc is found, build the SimpleCOnly project with sdcc
find_program(SDCC_EXECUTABLE sdcc)
@@ -2413,7 +3143,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
"${CMake_BINARY_DIR}/Tests/SimpleCOnly_sdcc"
${build_generator_args}
--build-project SimpleC
- --build-options
+ --build-options ${build_options}
"-DCMAKE_SYSTEM_NAME=Generic"
"-DCMAKE_C_COMPILER=${SDCC_EXECUTABLE}")
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/SimpleCOnly_sdcc")
@@ -2431,7 +3161,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
"${CMake_BINARY_DIR}/Tests/Simple_Mingw_Linux2Win"
${build_generator_args}
--build-project Simple
- --build-options
+ --build-options ${build_options}
"-DCMAKE_SYSTEM_NAME=Windows"
"-DCMAKE_C_COMPILER=${MINGW_CC_LINUX2WIN_EXECUTABLE}"
"-DCMAKE_CXX_COMPILER=${MINGW_CXX_LINUX2WIN_EXECUTABLE}"
@@ -2441,19 +3171,6 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
endif()
endif()
- if(UNIX)
- string(COMPARE EQUAL "${CMAKE_INSTALL_PREFIX}" "${CMake_BINARY_DIR}/Tests/TestShellInstall/Prefix"
- PREFIX_IS_FOR_TEST)
- if(PREFIX_IS_FOR_TEST)
- configure_file(
- ${CMake_SOURCE_DIR}/Tests/TestInstall.sh.in
- ${CMake_BINARY_DIR}/Tests/TestShellInstall/TestInstall.sh
- @ONLY IMMEDIATE
- )
- add_test(ShellInstall /bin/sh ${CMake_BINARY_DIR}/Tests/TestShellInstall/TestShellInstall.sh)
- endif()
- endif()
-
if(CMAKE_TEST_PROJECT_CSE_DIR)
set(script "${CMAKE_TEST_PROJECT_CSE_DIR}/BuildProjectCSE.cmake")
if(NOT EXISTS "${script}")
@@ -2493,11 +3210,10 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
)
endif()
- add_test(CMakeWizardTest ${CMAKE_CMAKE_COMMAND}
- -D build_dir:STRING=${CMAKE_CURRENT_BINARY_DIR}/CMakeWizardTest
- -D source_dir:STRING=${CMAKE_CURRENT_SOURCE_DIR}/Tutorial/Step3
- -D CMAKE_CTEST_COMMAND:STRING=${CMAKE_CTEST_COMMAND}
- -P ${CMAKE_CURRENT_SOURCE_DIR}/CMakeWizardTest.cmake)
+ add_test(NAME CMakeWizardTest COMMAND cmake -i)
+ set_property(TEST CMakeWizardTest PROPERTY PASS_REGULAR_EXPRESSION
+ "The \"cmake -i\" wizard mode is no longer supported.")
+
# If the cache variable CMAKE_CONTRACT_PROJECTS is set
# then the dashboard will run a contract with CMake test of that
# name. For example CMAKE_CONTRACT_PROJECTS = vtk542 would run
@@ -2526,8 +3242,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
endforeach()
if(TEST_CompileCommandOutput)
- set(CompileCommandOutput_EXTRA_OPTIONS
- --build-options -DMAKE_SUPPORTS_SPACES=${MAKE_SUPPORTS_SPACES})
+ set(CompileCommandOutput_BUILD_OPTIONS
+ -DMAKE_SUPPORTS_SPACES=${MAKE_SUPPORTS_SPACES})
ADD_TEST_MACRO(CompileCommandOutput
"${CMake_BINARY_DIR}/Tests/CMakeLib/runcompilecommands")
endif()
@@ -2539,6 +3255,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--build-two-config
${build_generator_args}
--build-project IncludeDirectories
+ --build-options ${build_options}
--test-command IncludeDirectories)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/IncludeDirectories")
@@ -2549,6 +3266,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--build-two-config
${build_generator_args}
--build-project InterfaceLinkLibraries
+ --build-options ${build_options}
--test-command InterfaceLinkLibraries)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/InterfaceLinkLibraries")
@@ -2566,5 +3284,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
WORKING_DIRECTORY ${CMake_BINARY_DIR}/Utilities/KWStyle)
endif()
- add_subdirectory(CMakeTests)
+ if(NOT CMake_TEST_EXTERNAL_CMAKE)
+ add_subdirectory(CMakeTests)
+ endif()
endif()
diff --git a/Tests/CMakeOnly/AllFindModules/CMakeLists.txt b/Tests/CMakeOnly/AllFindModules/CMakeLists.txt
index 739593cc9..bdc25639c 100644
--- a/Tests/CMakeOnly/AllFindModules/CMakeLists.txt
+++ b/Tests/CMakeOnly/AllFindModules/CMakeLists.txt
@@ -8,11 +8,14 @@ endif ()
# Avoid ctest truncation of output
message(STATUS "CTEST_FULL_OUTPUT")
+set(ORIGINAL_MODULE_PATH "${CMAKE_MODULE_PATH}")
+
file(GLOB FIND_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../Modules/Find*.cmake" )
macro(do_find MODULE_NAME)
message(STATUS " Checking Find${MODULE_NAME}")
find_package(${MODULE_NAME})
+ set(CMAKE_MODULE_PATH "${ORIGINAL_MODULE_PATH}")
endmacro()
# It is only possible to use either Qt3 or Qt4 in one project.
@@ -22,11 +25,18 @@ endmacro()
set(DESIRED_QT_VERSION 4)
set(NO_QT4_MODULES "Qt3" "KDE3")
+# ignore everything that has it's own test in Tests/Module/
+file(GLOB OWN_TEST_MODULES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/../../Module/" "${CMAKE_CURRENT_SOURCE_DIR}/../../Module/Find*")
+foreach(FIND_MODULE IN LISTS OWN_TEST_MODULES)
+ string(REGEX REPLACE "^Find" "" _MOD_NAME "${FIND_MODULE}")
+ list(APPEND NO_FIND_MODULES "${_MOD_NAME}")
+endforeach()
+
# These modules are named Find*.cmake, but are nothing that works in
# find_package().
-set(NO_FIND_MODULES "PackageHandleStandardArgs" "PackageMessage")
+list(APPEND NO_FIND_MODULES "PackageHandleStandardArgs" "PackageMessage")
-foreach(FIND_MODULE ${FIND_MODULES})
+foreach(FIND_MODULE IN LISTS FIND_MODULES)
string(REGEX REPLACE ".*/Find(.*)\\.cmake$" "\\1" MODULE_NAME "${FIND_MODULE}")
list(FIND NO_QT4_MODULES ${MODULE_NAME} NO_QT4_INDEX)
@@ -76,8 +86,8 @@ foreach(VTEST ALSA ARMADILLO BZIP2 CUPS CURL EXPAT FREETYPE GETTEXT GIT HG
check_version_string(${VTEST} ${VTEST}_VERSION_STRING)
endforeach()
-foreach(VTEST BISON Boost CUDA DOXYGEN FLEX GIF GTK2 LibArchive OPENSCENEGRAPH
- RUBY SWIG)
+foreach(VTEST BISON Boost CUDA DOXYGEN FLEX GIF GTK2
+ HDF5 LibArchive OPENSCENEGRAPH RUBY SWIG)
check_version_string(${VTEST} ${VTEST}_VERSION)
endforeach()
diff --git a/Tests/CMakeOnly/CMakeLists.txt b/Tests/CMakeOnly/CMakeLists.txt
index be7ddbc21..7586de6b2 100644
--- a/Tests/CMakeOnly/CMakeLists.txt
+++ b/Tests/CMakeOnly/CMakeLists.txt
@@ -19,6 +19,8 @@ add_CMakeOnly_test(CheckCXXCompilerFlag)
add_CMakeOnly_test(CheckLanguage)
+add_CMakeOnly_test(CheckStructHasMember)
+
add_CMakeOnly_test(CompilerIdC)
add_CMakeOnly_test(CompilerIdCXX)
if(CMAKE_Fortran_COMPILER)
diff --git a/Tests/CMakeOnly/CheckCXXCompilerFlag/CMakeLists.txt b/Tests/CMakeOnly/CheckCXXCompilerFlag/CMakeLists.txt
index e205330b0..9be69f128 100644
--- a/Tests/CMakeOnly/CheckCXXCompilerFlag/CMakeLists.txt
+++ b/Tests/CMakeOnly/CheckCXXCompilerFlag/CMakeLists.txt
@@ -56,3 +56,10 @@ if(CMAKE_COMPILER_IS_GNUCXX)
else()
message("Unhandled Platform")
endif()
+
+if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
+ check_cxx_compiler_flag("-x c++" HAVE_X_CXX)
+ if(NOT HAVE_X_CXX)
+ message(FATAL_ERROR "${CMAKE_CXX_COMPILER_ID} compiler flag '-x c++' check failed")
+ endif()
+endif()
diff --git a/Tests/CMakeOnly/CheckStructHasMember/CMakeLists.txt b/Tests/CMakeOnly/CheckStructHasMember/CMakeLists.txt
new file mode 100644
index 000000000..f06d5c34d
--- /dev/null
+++ b/Tests/CMakeOnly/CheckStructHasMember/CMakeLists.txt
@@ -0,0 +1,93 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(CheckStructHasMember)
+
+set(CMAKE_REQUIRED_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}")
+
+include(CheckStructHasMember)
+
+foreach(_config_type Release RelWithDebInfo MinSizeRel Debug)
+ set(CMAKE_TRY_COMPILE_CONFIGURATION ${_config_type})
+ unset(CSHM_RESULT_S1_${_config_type} CACHE)
+ unset(CSHM_RESULT_S2_${_config_type} CACHE)
+ unset(CSHM_RESULT_S3_${_config_type} CACHE)
+ message(STATUS "Testing configuration ${_config_type}")
+
+ check_struct_has_member("struct non_existent_struct" "foo" "cm_cshm.h" CSHM_RESULT_S1_${_config_type})
+ check_struct_has_member("struct struct_with_member" "non_existent_member" "cm_cshm.h" CSHM_RESULT_S2_${_config_type})
+ check_struct_has_member("struct struct_with_member" "member" "cm_cshm.h" CSHM_RESULT_S3_${_config_type})
+
+ if(CSHM_RESULT_S1_${_config_type} OR CSHM_RESULT_S2_${_config_type})
+ message(SEND_ERROR "CheckStructHasMember reported a nonexistent member as existing in configuration ${_config_type}")
+ endif()
+
+ if(NOT CSHM_RESULT_S3_${_config_type})
+ message(SEND_ERROR "CheckStructHasMember did not report an existent member as existing in configuration ${_config_type}")
+ endif()
+endforeach()
+
+foreach(_config_type Release RelWithDebInfo MinSizeRel Debug)
+ set(CMAKE_TRY_COMPILE_CONFIGURATION ${_config_type})
+ unset(CSHM_RESULT_S1_${_config_type}_C CACHE)
+ unset(CSHM_RESULT_S2_${_config_type}_C CACHE)
+ unset(CSHM_RESULT_S3_${_config_type}_C CACHE)
+ message(STATUS "Testing configuration ${_config_type}")
+
+ check_struct_has_member("struct non_existent_struct" "foo" "cm_cshm.h" CSHM_RESULT_S1_${_config_type}_C LANGUAGE C)
+ check_struct_has_member("struct struct_with_member" "non_existent_member" "cm_cshm.h" CSHM_RESULT_S2_${_config_type}_C LANGUAGE C)
+ check_struct_has_member("struct struct_with_member" "member" "cm_cshm.h" CSHM_RESULT_S3_${_config_type}_C LANGUAGE C)
+
+ if(CSHM_RESULT_S1_${_config_type}_C OR CSHM_RESULT_S2_${_config_type}_C)
+ message(SEND_ERROR "CheckStructHasMember reported a nonexistent member as existing in configuration ${_config_type}")
+ endif()
+
+ if(NOT CSHM_RESULT_S3_${_config_type}_C)
+ message(SEND_ERROR "CheckStructHasMember did not report an existent member as existing in configuration ${_config_type}")
+ endif()
+endforeach()
+
+foreach(_config_type Release RelWithDebInfo MinSizeRel Debug)
+ set(CMAKE_TRY_COMPILE_CONFIGURATION ${_config_type})
+ unset(CSHM_RESULT_S1_${_config_type}_CXX CACHE)
+ unset(CSHM_RESULT_S2_${_config_type}_CXX CACHE)
+ unset(CSHM_RESULT_S3_${_config_type}_CXX CACHE)
+ unset(CSHM_RESULT_C1_${_config_type}_CXX CACHE)
+ unset(CSHM_RESULT_C2_${_config_type}_CXX CACHE)
+ unset(CSHM_RESULT_C3_${_config_type}_CXX CACHE)
+
+ message(STATUS "Testing configuration ${_config_type}")
+
+ check_struct_has_member("non_existent_struct" "foo" "cm_cshm.h" CSHM_RESULT_S1_${_config_type}_CXX LANGUAGE CXX)
+ check_struct_has_member("struct_with_non_existent_members" "non_existent_member" "cm_cshm.h" CSHM_RESULT_S2_${_config_type}_CXX LANGUAGE CXX)
+ check_struct_has_member("struct struct_with_member" "member" "cm_cshm.h" CSHM_RESULT_S3_${_config_type}_CXX LANGUAGE CXX)
+ check_struct_has_member("ns::non_existent_class" "foo" "cm_cshm.hxx" CSHM_RESULT_C1_${_config_type}_CXX LANGUAGE CXX)
+ check_struct_has_member("ns::class_with_non_existent_members" "foo" "cm_cshm.hxx" CSHM_RESULT_C2_${_config_type}_CXX LANGUAGE CXX)
+ check_struct_has_member("ns::class_with_member" "foo" "cm_cshm.hxx" CSHM_RESULT_C3_${_config_type}_CXX LANGUAGE CXX)
+
+ if(CSHM_RESULT_S1_${_config_type}_CXX OR CSHM_RESULT_S2_${_config_type}_CXX OR CSHM_RESULT_C1_${_config_type}_CXX OR CSHM_RESULT_C2_${_config_type}_CXX)
+ message(SEND_ERROR "CheckStructHasMember reported a nonexistent member as existing in configuration ${_config_type}")
+ endif()
+
+ if(NOT CSHM_RESULT_S3_${_config_type}_CXX OR NOT CSHM_RESULT_C3_${_config_type}_CXX)
+ message(SEND_ERROR "CheckStructHasMember did not report an existent member as existing in configuration ${_config_type}")
+ endif()
+endforeach()
+
+
+set(CMAKE_TRY_COMPILE_CONFIGURATION ${CMAKE_BUILD_TYPE})
+
+if (CMAKE_COMPILER_IS_GNUCC)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
+ unset(CSHM_RESULT_O3 CACHE)
+ unset(CSHM_RESULT_O3_C CACHE)
+ unset(CSHM_RESULT_O3_CXX CACHE)
+ message(STATUS "Testing with optimization -O3")
+
+ check_struct_has_member("class_with_non_existent_members" foo "cm_cshm.h" CSHM_RESULT_O3)
+ check_struct_has_member("class_with_non_existent_members" foo "cm_cshm.h" CSHM_RESULT_O3_C LANGUAGE C)
+ check_struct_has_member("class_with_non_existent_members" foo "cm_cshm.h" CSHM_RESULT_O3_CXX LANGUAGE CXX)
+
+ if (CSE_RESULT_O3 OR CSHM_RESULT_O3_C OR CSHM_RESULT_O3_CXX)
+ message(SEND_ERROR "CheckSymbolExists reported a nonexistent symbol as existing with optimization -O3")
+ endif ()
+endif ()
diff --git a/Tests/CMakeOnly/CheckStructHasMember/cm_cshm.h b/Tests/CMakeOnly/CheckStructHasMember/cm_cshm.h
new file mode 100644
index 000000000..82bb0498c
--- /dev/null
+++ b/Tests/CMakeOnly/CheckStructHasMember/cm_cshm.h
@@ -0,0 +1,9 @@
+#ifndef _CSHM_DUMMY_H
+#define _CSHM_DUMMY_H
+
+struct non_existent_struct;
+struct struct_with_member{
+ int member;
+};
+
+#endif
diff --git a/Tests/CMakeOnly/CheckStructHasMember/cm_cshm.hxx b/Tests/CMakeOnly/CheckStructHasMember/cm_cshm.hxx
new file mode 100644
index 000000000..458a99b46
--- /dev/null
+++ b/Tests/CMakeOnly/CheckStructHasMember/cm_cshm.hxx
@@ -0,0 +1,16 @@
+#ifndef _CSHM_DUMMY_HXX
+#define _CSHM_DUMMY_HXX
+
+namespace ns {
+
+class non_existent_class;
+class class_with_non_existent_members {
+};
+class class_with_member {
+public:
+ int foo;
+};
+
+}
+
+#endif
diff --git a/Tests/CMakeOnly/CompilerIdC/CMakeLists.txt b/Tests/CMakeOnly/CompilerIdC/CMakeLists.txt
index 848ffdd36..6fea73eb8 100644
--- a/Tests/CMakeOnly/CompilerIdC/CMakeLists.txt
+++ b/Tests/CMakeOnly/CompilerIdC/CMakeLists.txt
@@ -12,3 +12,10 @@ foreach(v
message(SEND_ERROR "${v} not set!")
endif()
endforeach()
+
+# Version numbers may only contain numbers and periods.
+if(NOT CMAKE_C_COMPILER_VERSION MATCHES
+ "^([0-9]+)(\\.([0-9]+))?(\\.([0-9]+))?(\\.([0-9]+))?$"
+ )
+ message(SEND_ERROR "Compiler version is not numeric!")
+endif()
diff --git a/Tests/CMakeOnly/CompilerIdCXX/CMakeLists.txt b/Tests/CMakeOnly/CompilerIdCXX/CMakeLists.txt
index 94ac31e4c..05e6bb222 100644
--- a/Tests/CMakeOnly/CompilerIdCXX/CMakeLists.txt
+++ b/Tests/CMakeOnly/CompilerIdCXX/CMakeLists.txt
@@ -12,3 +12,10 @@ foreach(v
message(SEND_ERROR "${v} not set!")
endif()
endforeach()
+
+# Version numbers may only contain numbers and periods.
+if(NOT CMAKE_CXX_COMPILER_VERSION MATCHES
+ "^([0-9]+)(\\.([0-9]+))?(\\.([0-9]+))?(\\.([0-9]+))?$"
+ )
+ message(SEND_ERROR "Compiler version is not numeric!")
+endif()
diff --git a/Tests/CMakeOnly/CompilerIdFortran/CMakeLists.txt b/Tests/CMakeOnly/CompilerIdFortran/CMakeLists.txt
index 3a2bdebd6..067fb8cd3 100644
--- a/Tests/CMakeOnly/CompilerIdFortran/CMakeLists.txt
+++ b/Tests/CMakeOnly/CompilerIdFortran/CMakeLists.txt
@@ -4,6 +4,7 @@ project(CompilerIdFortran Fortran)
foreach(v
CMAKE_Fortran_COMPILER
CMAKE_Fortran_COMPILER_ID
+ CMAKE_Fortran_COMPILER_VERSION
)
if(${v})
message(STATUS "${v}=[${${v}}]")
@@ -11,12 +12,10 @@ foreach(v
message(SEND_ERROR "${v} not set!")
endif()
endforeach()
-foreach(v
- CMAKE_Fortran_COMPILER_VERSION
+
+# Version numbers may only contain numbers and periods.
+if(NOT CMAKE_Fortran_COMPILER_VERSION MATCHES
+ "^([0-9]+)(\\.([0-9]+))?(\\.([0-9]+))?(\\.([0-9]+))?$"
)
- if(${v})
- message(STATUS "${v}=[${${v}}]")
- else()
- message(WARNING "${v} not set!")
- endif()
-endforeach()
+ message(SEND_ERROR "Compiler version is not numeric!")
+endif()
diff --git a/Tests/CMakeOnly/MajorVersionSelection/CMakeLists.txt b/Tests/CMakeOnly/MajorVersionSelection/CMakeLists.txt
index 74f54514e..2511064a2 100644
--- a/Tests/CMakeOnly/MajorVersionSelection/CMakeLists.txt
+++ b/Tests/CMakeOnly/MajorVersionSelection/CMakeLists.txt
@@ -20,13 +20,13 @@ endif ()
string(TOUPPER "${MAJOR_TEST_MODULE}" MODULE_UPPER)
-if ( ( ${MAJOR_TEST_MODULE}_FOUND OR ${MODULE_UPPER}_FOUND ) AND "${VERSION_VAR}")
+if ( ( ${MAJOR_TEST_MODULE}_FOUND OR ${MODULE_UPPER}_FOUND ) AND ${VERSION_VAR})
message(STATUS "${VERSION_VAR} is '${${VERSION_VAR}}'")
- if ("${VERSION_VAR}" VERSION_LESS MAJOR_TEST_VERSION)
+ if (${VERSION_VAR} VERSION_LESS MAJOR_TEST_VERSION)
message(SEND_ERROR "Found version ${${VERSION_VAR}} is less than requested major version ${MAJOR_TEST_VERSION}")
endif ()
math(EXPR V_PLUS_ONE "${MAJOR_TEST_VERSION} + 1")
- if ("${VERSION_VAR}" VERSION_GREATER V_PLUS_ONE)
+ if (${VERSION_VAR} VERSION_GREATER V_PLUS_ONE)
message(SEND_ERROR "Found version ${${VERSION_VAR}} is greater than requested major version ${MAJOR_TEST_VERSION}")
endif ()
endif ()
diff --git a/Tests/CMakeOnly/Test.cmake.in b/Tests/CMakeOnly/Test.cmake.in
index a266415f7..0ae8af158 100644
--- a/Tests/CMakeOnly/Test.cmake.in
+++ b/Tests/CMakeOnly/Test.cmake.in
@@ -2,14 +2,21 @@ if (NOT TEST_SOURCE)
set(TEST_SOURCE "${TEST}")
endif ()
+set(make_program "@CMake_TEST_EXPLICIT_MAKE_PROGRAM@")
+if(make_program)
+ set(maybe_make_program "-DCMAKE_MAKE_PROGRAM=${make_program}")
+endif()
+
set(source_dir "@CMAKE_CURRENT_SOURCE_DIR@/${TEST_SOURCE}")
set(binary_dir "@CMAKE_CURRENT_BINARY_DIR@/${TEST}-build")
file(REMOVE_RECURSE "${binary_dir}")
file(MAKE_DIRECTORY "${binary_dir}")
execute_process(
COMMAND ${CMAKE_COMMAND} ${CMAKE_ARGS}
- "${source_dir}" -G "@CMAKE_TEST_GENERATOR@"
- -T "@CMAKE_TEST_GENERATOR_TOOLSET@"
+ "${source_dir}" -G "@CMAKE_GENERATOR@"
+ -A "@CMAKE_GENERATOR_PLATFORM@"
+ -T "@CMAKE_GENERATOR_TOOLSET@"
+ ${maybe_make_program}
WORKING_DIRECTORY "${binary_dir}"
RESULT_VARIABLE result
)
diff --git a/Tests/CMakeTestBadCommandLines/RunCMake.cmake b/Tests/CMakeTestBadCommandLines/RunCMake.cmake
deleted file mode 100644
index 08549cc5e..000000000
--- a/Tests/CMakeTestBadCommandLines/RunCMake.cmake
+++ /dev/null
@@ -1,79 +0,0 @@
-if(NOT DEFINED CMake_SOURCE_DIR)
- message(FATAL_ERROR "CMake_SOURCE_DIR not defined")
-endif()
-
-if(NOT DEFINED dir)
- message(FATAL_ERROR "dir not defined")
-endif()
-
-if(NOT DEFINED gen)
- message(FATAL_ERROR "gen not defined")
-endif()
-
-message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)")
-
-# First setup a source tree to run CMake on.
-#
-execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory
- ${CMake_SOURCE_DIR}/Tests/CTestTest/SmallAndFast
- ${dir}/Source
-)
-
-execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory
- ${dir}/Build
- )
-
-function(RunCMakeWithArgs)
- message(STATUS "info: running cmake with ARGN='${ARGN}'")
-
- execute_process(COMMAND ${CMAKE_COMMAND} ${ARGN}
- RESULT_VARIABLE result
- OUTPUT_VARIABLE stdout
- ERROR_VARIABLE stderr
- WORKING_DIRECTORY ${dir}/Build
- )
-
- message(STATUS "result='${result}'")
- message(STATUS "stdout='${stdout}'")
- message(STATUS "stderr='${stderr}'")
- message(STATUS "")
-endfunction()
-
-# Run cmake once with no errors to get a good build tree:
-#
-RunCMakeWithArgs(-G ${gen} ../Source)
-
-# Run cmake with args that produce some sort of problem to cover the error
-# cases in cmake.cxx...
-#
-# (These are not good examples of cmake command lines. Do not copy and
-# paste them elsewhere and expect them to work... See the cmake
-# documentation or other real examples of usage instead.)
-#
-RunCMakeWithArgs()
-RunCMakeWithArgs(-C)
-RunCMakeWithArgs(-C nosuchcachefile.txt)
-RunCMakeWithArgs(--check-stamp-file nostampfile)
-RunCMakeWithArgs(--check-stamp-list nostamplist)
-RunCMakeWithArgs(nosuchsubdir/CMakeCache.txt)
-RunCMakeWithArgs(nosuchsubdir/CMakeLists.txt)
-RunCMakeWithArgs(-D)
-RunCMakeWithArgs(--debug-output .)
-RunCMakeWithArgs(--debug-trycompile .)
-RunCMakeWithArgs(-E)
-RunCMakeWithArgs(-E create_symlink)
-RunCMakeWithArgs(-E echo_append)
-RunCMakeWithArgs(-E rename)
-RunCMakeWithArgs(-E touch_nocreate)
-RunCMakeWithArgs(-G)
-RunCMakeWithArgs(--graphviz= ../Source)
-RunCMakeWithArgs(--graphviz=g.dot .)
-RunCMakeWithArgs(-P)
-RunCMakeWithArgs(-P nosuchscriptfile.cmake)
-RunCMakeWithArgs(--trace .)
-RunCMakeWithArgs(-U)
-RunCMakeWithArgs(-U nosuchvariable .)
-RunCMakeWithArgs(-V)
-RunCMakeWithArgs(-V .)
-RunCMakeWithArgs(-Wno-dev .)
-RunCMakeWithArgs(-Wdev .)
diff --git a/Tests/CMakeTests/CMakeLists.txt b/Tests/CMakeTests/CMakeLists.txt
index 344b77255..d5524c3ca 100644
--- a/Tests/CMakeTests/CMakeLists.txt
+++ b/Tests/CMakeTests/CMakeLists.txt
@@ -3,7 +3,7 @@ set(CMAKE_EXECUTABLE "${CMake_BIN_DIR}/cmake")
macro(AddCMakeTest TestName PreArgs)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${TestName}Test.cmake.in"
- "${CMAKE_CURRENT_BINARY_DIR}/${TestName}Test.cmake" @ONLY IMMEDIATE)
+ "${CMAKE_CURRENT_BINARY_DIR}/${TestName}Test.cmake" @ONLY)
add_test(NAME CMake.${TestName}
COMMAND ${CMAKE_EXECUTABLE} ${PreArgs}
-P "${CMAKE_CURRENT_BINARY_DIR}/${TestName}Test.cmake" ${ARGN})
@@ -19,7 +19,6 @@ AddCMakeTest(GetFilenameComponentRealpath "")
AddCMakeTest(Version "")
AddCMakeTest(Message "")
AddCMakeTest(File "")
-AddCMakeTest(ConfigureFile "")
AddCMakeTest(SeparateArguments "")
AddCMakeTest(ImplicitLinkInfo "")
AddCMakeTest(ModuleNotices "")
@@ -38,6 +37,10 @@ AddCMakeTest(FileDownload "")
set_property(TEST CMake.FileDownload PROPERTY
PASS_REGULAR_EXPRESSION "file already exists with expected MD5 sum"
)
+AddCMakeTest(FileDownloadBadHash "")
+set_property(TEST CMake.FileDownloadBadHash PROPERTY
+ WILL_FAIL TRUE
+ )
AddCMakeTest(FileUpload "")
@@ -55,6 +58,15 @@ set(GetPrerequisites_PreArgs
)
AddCMakeTest(GetPrerequisites "${GetPrerequisites_PreArgs}")
+if(GIT_EXECUTABLE)
+ set(PolicyCheck_PreArgs
+ "-DCMake_BINARY_DIR:PATH=${CMake_BINARY_DIR}"
+ "-DCMake_SOURCE_DIR:PATH=${CMake_SOURCE_DIR}"
+ "-DGIT_EXECUTABLE:STRING=${GIT_EXECUTABLE}"
+ )
+ AddCMakeTest(PolicyCheck "${PolicyCheck_PreArgs}")
+endif()
+
# Run CheckSourceTree as the very last test in the CMake/CTest/CPack test
# suite. It detects if any changes have been made to the CMake source tree
# by any previous configure, build or test steps.
diff --git a/Tests/CMakeTests/CheckCMakeTest.cmake b/Tests/CMakeTests/CheckCMakeTest.cmake
index 7be7b30f0..1565394bc 100644
--- a/Tests/CMakeTests/CheckCMakeTest.cmake
+++ b/Tests/CMakeTests/CheckCMakeTest.cmake
@@ -9,8 +9,8 @@ function(check_cmake_test_single prefix test testfile)
ERROR_VARIABLE stderr
RESULT_VARIABLE result
)
- string(REGEX REPLACE "\n" "\n out> " out " out> ${stdout}")
- string(REGEX REPLACE "\n" "\n err> " err " err> ${stderr}")
+ string(REPLACE "\n" "\n out> " out " out> ${stdout}")
+ string(REPLACE "\n" "\n err> " err " err> ${stderr}")
if(NOT "${result}" STREQUAL "${${test}-RESULT}")
message(FATAL_ERROR
"Test ${test} result is [${result}], not [${${test}-RESULT}].\n"
diff --git a/Tests/CMakeTests/CheckSourceTreeTest.cmake.in b/Tests/CMakeTests/CheckSourceTreeTest.cmake.in
index 59b28904d..8145db7cb 100644
--- a/Tests/CMakeTests/CheckSourceTreeTest.cmake.in
+++ b/Tests/CMakeTests/CheckSourceTreeTest.cmake.in
@@ -16,8 +16,13 @@ string(REPLACE "\\" "\\\\" HOME "${HOME}")
# (i.e. - is it an "in source" build?)
#
set(in_source_build 0)
+set(build_under_source 0)
-if(CMake_SOURCE_DIR STREQUAL "${CMake_BINARY_DIR}")
+string(FIND "${CMake_BINARY_DIR}" "${CMake_SOURCE_DIR}/" pos)
+if(pos EQUAL 0)
+ message("build dir is *inside* source dir")
+ set(build_under_source 1)
+elseif(CMake_SOURCE_DIR STREQUAL "${CMake_BINARY_DIR}")
message("build dir *is* source dir")
set(in_source_build 1)
else()
@@ -39,8 +44,13 @@ message("bin_len='${bin_len}'")
message("substr_len='${substr_len}'")
message("bin_dir='${bin_dir}'")
message("in_source_build='${in_source_build}'")
+message("build_under_source='${build_under_source}'")
message("")
+if(build_under_source)
+ message(STATUS "Skipping rest of test because build tree is under source tree")
+ return()
+endif()
# If this does not appear to be a git checkout, just pass the test here
# and now. (Do not let the test fail if it is run in a tree *exported* from a
@@ -268,12 +278,12 @@ if(NOT ov STREQUAL "")
if(consider)
if(is_git_checkout)
- if(line MATCHES "^#[ \t]*modified:")
+ if(line MATCHES "^#?[ \t]*modified:")
message(" locally modified file detected...")
set(modifications 1)
endif()
- if(line MATCHES "^# Untracked")
+ if(line MATCHES "^(# )?Untracked")
message(" locally non-added file/directory detected...")
set(nonadditions 1)
endif()
diff --git a/Tests/CMakeTests/ConfigureFile-DirOutput.cmake b/Tests/CMakeTests/ConfigureFile-DirOutput.cmake
deleted file mode 100644
index d682a2d85..000000000
--- a/Tests/CMakeTests/ConfigureFile-DirOutput.cmake
+++ /dev/null
@@ -1,5 +0,0 @@
-file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/ConfigureFile-DirOutput.txt "DirOutput test file\n")
-file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/ConfigureFile-DirOutput)
-configure_file(ConfigureFile-DirOutput.txt ConfigureFile-DirOutput)
-file(READ ${CMAKE_CURRENT_BINARY_DIR}/ConfigureFile-DirOutput/ConfigureFile-DirOutput.txt out)
-message("${out}")
diff --git a/Tests/CMakeTests/ConfigureFile-NewLineStyle-COPYONLY.cmake b/Tests/CMakeTests/ConfigureFile-NewLineStyle-COPYONLY.cmake
deleted file mode 100644
index 3b09eb0c3..000000000
--- a/Tests/CMakeTests/ConfigureFile-NewLineStyle-COPYONLY.cmake
+++ /dev/null
@@ -1,3 +0,0 @@
-set(file_name ${CMAKE_CURRENT_SOURCE_DIR}/ConfigureFile-NewLineStyle.txt)
-file(WRITE ${file_name} "Data\n")
-configure_file(${file_name} ${file_name}.out COPYONLY NEWLINE_STYLE DOS)
diff --git a/Tests/CMakeTests/ConfigureFile-NewLineStyle-NoArg.cmake b/Tests/CMakeTests/ConfigureFile-NewLineStyle-NoArg.cmake
deleted file mode 100644
index 133a67a8a..000000000
--- a/Tests/CMakeTests/ConfigureFile-NewLineStyle-NoArg.cmake
+++ /dev/null
@@ -1,3 +0,0 @@
-set(file_name ${CMAKE_CURRENT_SOURCE_DIR}/ConfigureFile-NewLineStyle.txt)
-file(WRITE ${file_name} "Data\n")
-configure_file(${file_name} ${file_name}.out NEWLINE_STYLE)
diff --git a/Tests/CMakeTests/ConfigureFile-NewLineStyle-ValidArg.cmake b/Tests/CMakeTests/ConfigureFile-NewLineStyle-ValidArg.cmake
deleted file mode 100644
index b7e619ca2..000000000
--- a/Tests/CMakeTests/ConfigureFile-NewLineStyle-ValidArg.cmake
+++ /dev/null
@@ -1,17 +0,0 @@
-set(file_name ${CMAKE_CURRENT_SOURCE_DIR}/ConfigureFile-NewLineStyle.txt)
-
-function(test_eol style in out)
- file(WRITE ${file_name} "${in}")
- configure_file(${file_name} ${file_name}.out NEWLINE_STYLE ${style})
- file(READ ${file_name}.out new HEX)
- if(NOT "${new}" STREQUAL "${out}")
- message(FATAL_ERROR "No ${style} line endings")
- endif()
-endfunction()
-
-test_eol(DOS "a\n" "610d0a")
-test_eol(WIN32 "b\n" "620d0a")
-test_eol(CRLF "c\n" "630d0a")
-
-test_eol(UNIX "d\n" "640a")
-test_eol(LF "e\n" "650a")
diff --git a/Tests/CMakeTests/ConfigureFile-NewLineStyle-WrongArg.cmake b/Tests/CMakeTests/ConfigureFile-NewLineStyle-WrongArg.cmake
deleted file mode 100644
index e8887c127..000000000
--- a/Tests/CMakeTests/ConfigureFile-NewLineStyle-WrongArg.cmake
+++ /dev/null
@@ -1,3 +0,0 @@
-set(file_name ${CMAKE_CURRENT_SOURCE_DIR}/ConfigureFile-NewLineStyle.txt)
-file(WRITE ${file_name} "Data\n")
-configure_file(${file_name} ${file_name}.out NEWLINE_STYLE FOO)
diff --git a/Tests/CMakeTests/ConfigureFile-Relative.cmake b/Tests/CMakeTests/ConfigureFile-Relative.cmake
deleted file mode 100644
index 532580a21..000000000
--- a/Tests/CMakeTests/ConfigureFile-Relative.cmake
+++ /dev/null
@@ -1,4 +0,0 @@
-file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/ConfigureFile-Relative-In.txt "Relative test file\n")
-configure_file(ConfigureFile-Relative-In.txt ConfigureFile-Relative-Out.txt)
-file(READ ${CMAKE_CURRENT_BINARY_DIR}/ConfigureFile-Relative-Out.txt out)
-message("${out}")
diff --git a/Tests/CMakeTests/ConfigureFileTest.cmake.in b/Tests/CMakeTests/ConfigureFileTest.cmake.in
deleted file mode 100644
index 6cc61d90c..000000000
--- a/Tests/CMakeTests/ConfigureFileTest.cmake.in
+++ /dev/null
@@ -1,28 +0,0 @@
-set(DirInput-RESULT 1)
-set(DirInput-STDERR "is a directory")
-set(DirOutput-RESULT 0)
-set(DirOutput-STDERR "DirOutput test file")
-set(Relative-RESULT 0)
-set(Relative-STDERR "Relative test file")
-set(BadArg-RESULT 1)
-set(BadArg-STDERR "called with incorrect number of arguments")
-set(NewLineStyle-NoArg-RESULT 1)
-set(NewLineStyle-NoArg-STDERR "NEWLINE_STYLE must set a style:")
-set(NewLineStyle-WrongArg-RESULT 1)
-set(NewLineStyle-WrongArg-STDERR "NEWLINE_STYLE sets an unknown style")
-set(NewLineStyle-ValidArg-RESULT 0)
-set(NewLineStyle-ValidArg-STDERR )
-set(NewLineStyle-COPYONLY-RESULT 1)
-set(NewLineStyle-COPYONLY-STDERR "COPYONLY could not be used in combination")
-
-include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake")
-check_cmake_test(ConfigureFile
- DirInput
- DirOutput
- Relative
- BadArg
- NewLineStyle-NoArg
- NewLineStyle-WrongArg
- NewLineStyle-ValidArg
- NewLineStyle-COPYONLY
- )
diff --git a/Tests/CMakeTests/ELFTest.cmake.in b/Tests/CMakeTests/ELFTest.cmake.in
index 0271abb1f..463577889 100644
--- a/Tests/CMakeTests/ELFTest.cmake.in
+++ b/Tests/CMakeTests/ELFTest.cmake.in
@@ -11,7 +11,7 @@ set(out "@CMAKE_CURRENT_BINARY_DIR@/ELF-Out")
file(REMOVE_RECURSE "${out}")
file(MAKE_DIRECTORY "${out}")
foreach(f ${names})
- file(COPY ${in}/${f} DESTINATION ${out})
+ file(COPY ${in}/${f} DESTINATION ${out} NO_SOURCE_PERMISSIONS)
list(APPEND files "${out}/${f}")
endforeach()
diff --git a/Tests/CMakeTests/ExecuteScriptTests.cmake b/Tests/CMakeTests/ExecuteScriptTests.cmake
index c71585a02..bceac335f 100644
--- a/Tests/CMakeTests/ExecuteScriptTests.cmake
+++ b/Tests/CMakeTests/ExecuteScriptTests.cmake
@@ -52,9 +52,9 @@ function(execute_all_script_tests scriptname result)
foreach(line ${script})
if(line MATCHES "${regex}")
+ set(testname "${CMAKE_MATCH_2}")
+ set(expected_result "${CMAKE_MATCH_3}")
math(EXPR count "${count} + 1")
- string(REGEX REPLACE "${regex}" "\\2" testname "${line}")
- string(REGEX REPLACE "${regex}" "\\3" expected_result "${line}")
execute_one_script_test(${scriptname} ${testname} ${expected_result})
endif()
endforeach()
diff --git a/Tests/CMakeTests/FileDownloadBadHashTest.cmake.in b/Tests/CMakeTests/FileDownloadBadHashTest.cmake.in
new file mode 100644
index 000000000..4a47c0695
--- /dev/null
+++ b/Tests/CMakeTests/FileDownloadBadHashTest.cmake.in
@@ -0,0 +1,10 @@
+set(url "file://@CMAKE_CURRENT_SOURCE_DIR@/FileDownloadInput.png")
+set(dir "@CMAKE_CURRENT_BINARY_DIR@/downloads")
+
+file(DOWNLOAD
+ ${url}
+ ${dir}/file3.png
+ TIMEOUT 2
+ STATUS status
+ EXPECTED_HASH SHA1=5555555555555555555555555555555555555555
+ )
diff --git a/Tests/CMakeTests/FileDownloadTest.cmake.in b/Tests/CMakeTests/FileDownloadTest.cmake.in
index 91086c6d7..83ade2ba7 100644
--- a/Tests/CMakeTests/FileDownloadTest.cmake.in
+++ b/Tests/CMakeTests/FileDownloadTest.cmake.in
@@ -94,3 +94,16 @@ file(DOWNLOAD
EXPECTED_MD5 d16778650db435bda3a8c3435c3ff5d1
)
message(STATUS "${status}")
+
+message(STATUS "FileDownload:11")
+file(DOWNLOAD
+ badhostname.png
+ ${dir}/file11.png
+ TIMEOUT 2
+ STATUS status
+ )
+message(STATUS "${status}")
+list(GET status 0 status_code)
+if(NOT ${status_code} EQUAL 6)
+ message(SEND_ERROR "error: expected status code 6 for bad host name, got: ${status_code}")
+endif()
diff --git a/Tests/CMakeTests/GetPropertyTest.cmake.in b/Tests/CMakeTests/GetPropertyTest.cmake.in
index a858418f1..1ad895657 100644
--- a/Tests/CMakeTests/GetPropertyTest.cmake.in
+++ b/Tests/CMakeTests/GetPropertyTest.cmake.in
@@ -1,5 +1,3 @@
-include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake")
-
get_property(FOO_BRIEF GLOBAL PROPERTY FOO BRIEF_DOCS)
get_property(FOO_FULL GLOBAL PROPERTY FOO FULL_DOCS)
@@ -11,113 +9,8 @@ if (NOT FOO_FULL STREQUAL "NOTFOUND")
message(SEND_ERROR "property FOO has FULL_DOCS set to '${FOO_FULL}'")
endif ()
-get_property(test_brief GLOBAL PROPERTY ENABLED_FEATURES BRIEF_DOCS)
-get_property(test_full GLOBAL PROPERTY ENABLED_FEATURES FULL_DOCS)
-
-if(test_brief STREQUAL "NOTFOUND")
- message(SEND_ERROR "property ENABLED_FEATURES has no BRIEF_DOCS")
-endif()
-
-if(test_full STREQUAL "NOTFOUND")
- message(SEND_ERROR "property ENABLED_FEATURES has no FULL_DOCS")
-endif()
-
set(test_var alpha)
get_property(result VARIABLE PROPERTY test_var)
if(NOT result STREQUAL "alpha")
message(SEND_ERROR "bad value of VARIABLE PROPERTY test_var: got '${result}' instead of 'alpha'")
endif()
-
-include("@CMAKE_CURRENT_SOURCE_DIR@/../RegexEscapeString.cmake")
-REGEX_ESCAPE_STRING(CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@")
-
-set(Missing-Argument-RESULT 1)
-set(Missing-Argument-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Missing-Argument.cmake:1 \\(get_property\\):.*get_property called with incorrect number of arguments.*")
-
-check_cmake_test(GetProperty
- Missing-Argument
-)
-
-set(Bad-Scope-RESULT 1)
-set(Bad-Scope-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Bad-Scope.cmake:1 \\(get_property\\):.*get_property given invalid scope FOO\\..*")
-
-check_cmake_test(GetProperty
- Bad-Scope
-)
-
-set(Bad-Argument-RESULT 1)
-set(Bad-Argument-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Bad-Argument.cmake:1 \\(get_property\\):.*get_property given invalid argument \"FOO\"\\..*")
-
-check_cmake_test(GetProperty
- Bad-Argument
-)
-
-set(No-Property-RESULT 1)
-set(No-Property-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-No-Property.cmake:1 \\(get_property\\):.*get_property not given a PROPERTY <name> argument\\..*")
-
-check_cmake_test(GetProperty
- No-Property
-)
-
-set(Global-Name-RESULT 1)
-set(Global-Name-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Global-Name.cmake:1 \\(get_property\\):.*get_property given name for GLOBAL scope\\..*")
-
-check_cmake_test(GetProperty
- Global-Name
-)
-
-set(Bad-Directory-RESULT 1)
-set(Bad-Directory-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Bad-Directory.cmake:1 \\(get_property\\):.*get_property DIRECTORY scope provided but requested directory was not.*found\\..*")
-
-check_cmake_test(GetProperty
- Bad-Directory
-)
-
-set(No-Target-RESULT 1)
-set(No-Target-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-No-Target.cmake:1 \\(get_property\\):.*get_property not given name for TARGET scope\\..*")
-
-check_cmake_test(GetProperty
- No-Target
-)
-
-set(Bad-Target-RESULT 1)
-set(Bad-Target-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Bad-Target.cmake:1 \\(get_property\\):.*get_property could not find TARGET FOO\\..*")
-
-check_cmake_test(GetProperty
- Bad-Target
-)
-
-set(No-Source-RESULT 1)
-set(No-Source-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-No-Source.cmake:1 \\(get_property\\):.*get_property not given name for SOURCE scope\\..*")
-
-check_cmake_test(GetProperty
- No-Source
-)
-
-set(No-Test-RESULT 1)
-set(No-Test-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-No-Test.cmake:1 \\(get_property\\):.*get_property not given name for TEST scope\\..*")
-
-check_cmake_test(GetProperty
- No-Test
-)
-
-set(Bad-Test-RESULT 1)
-set(Bad-Test-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Bad-Test.cmake:1 \\(get_property\\):.*get_property given TEST name that does not exist: FOO.*")
-
-check_cmake_test(GetProperty
- Bad-Test
-)
-
-set(Variable-Name-RESULT 1)
-set(Variable-Name-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Variable-Name.cmake:1 \\(get_property\\):.*get_property given name for VARIABLE scope\\..*")
-
-check_cmake_test(GetProperty
- Variable-Name
-)
-
-set(No-Cache-RESULT 1)
-set(No-Cache-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-No-Cache.cmake:1 \\(get_property\\):.*get_property not given name for CACHE scope\\..*")
-
-check_cmake_test(GetProperty
- No-Cache
-)
diff --git a/Tests/CMakeTests/IfTest.cmake.in b/Tests/CMakeTests/IfTest.cmake.in
index 74b8e32b5..e5211b4fa 100644
--- a/Tests/CMakeTests/IfTest.cmake.in
+++ b/Tests/CMakeTests/IfTest.cmake.in
@@ -7,9 +7,6 @@ foreach(_arg "" 0 1 2 ${TRUE_NAMES} ${FALSE_NAMES})
set(VAR_${_arg} "${_arg}")
endforeach()
-include("@CMAKE_CURRENT_SOURCE_DIR@/../RegexEscapeString.cmake")
-REGEX_ESCAPE_STRING(CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@")
-
macro(test_vars _old)
# Variables set to false or not set.
foreach(_var "" 0 ${FALSE_NAMES} UNDEFINED)
@@ -159,11 +156,3 @@ foreach(_bad 2x -2x)
endforeach()
test_vars("")
-
-set(Invalid-Argument-RESULT 1)
-set(Invalid-Argument-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?If-Invalid-Argument.cmake:1 \\(if\\):.*Unknown arguments specified.*")
-
-include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake")
-check_cmake_test(If
- Invalid-Argument
-)
diff --git a/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in b/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in
index 055b183d6..da614e996 100644
--- a/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in
+++ b/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in
@@ -105,6 +105,13 @@ set(linux64_test2_libs "c;/opt/sun/sunstudio12/prod/lib/amd64/libc_supp.a")
set(linux64_test2_dirs "/opt/sun/sunstudio12/prod/lib/amd64;/lib64;/usr/lib64")
list(APPEND platforms linux64_test2)
+# -specs=redhat-hardened-ld
+set(linux64_test3_text "COLLECT_GCC_OPTIONS='-specs=/usr/lib/rpm/redhat/redhat-hardened-ld' '-v' '-O2' '-g' '-pipe' '-Wall' '-Werror=format-security' '-fexceptions' '-fstack-protector-strong' '--param' 'ssp-buffer-size=4' '-grecord-gcc-switches' '-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1' '-m64' '-mtune=generic' '-I' '/usr/lib64/gfortran/modules' '-o' 'a.out' '-rdynamic' '-shared-libgcc' '-march=x86-64' '-pie'
+ /usr/libexec/gcc/x86_64-redhat-linux/5.1.1/collect2 -plugin /usr/libexec/gcc/x86_64-redhat-linux/5.1.1/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-redhat-linux/5.1.1/lto-wrapper -plugin-opt=-fresolution=/tmp/ccNzxFD8.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lquadmath -plugin-opt=-pass-through=-lm -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -export-dynamic -dynamic-linker /lib64/ld-linux-x86-64.so.2 -z now -pie -o a.out /usr/lib/gcc/x86_64-redhat-linux/5.1.1/../../../../lib64/Scrt1.o /usr/lib/gcc/x86_64-redhat-linux/5.1.1/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/5.1.1/crtbeginS.o -L/usr/lib/gcc/x86_64-redhat-linux/5.1.1 -L/usr/lib/gcc/x86_64-redhat-linux/5.1.1/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/5.1.1/../../.. -z relro dummy.o -lgfortran -lm -lgcc_s -lgcc -lquadmath -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-redhat-linux/5.1.1/crtendS.o /usr/lib/gcc/x86_64-redhat-linux/5.1.1/../../../../lib64/crtn.o")
+set(linux64_test3_libs "gfortran;m;quadmath;m;c")
+set(linux64_test3_dirs "/usr/lib/gcc/x86_64-redhat-linux/5.1.1;/usr/lib64;/lib64;/usr/lib")
+list(APPEND platforms linux64_test3)
+
#-----------------------------------------------------------------------------
# Mac
diff --git a/Tests/CMakeTests/List-Get-CMP0007-Warn.cmake b/Tests/CMakeTests/List-Get-CMP0007-Warn.cmake
deleted file mode 100644
index 0a9264fdc..000000000
--- a/Tests/CMakeTests/List-Get-CMP0007-Warn.cmake
+++ /dev/null
@@ -1,6 +0,0 @@
-set(thelist "" NEW OLD)
-
-list(GET thelist 1 thevalue)
-if (NOT thevalue STREQUAL "OLD")
- message(SEND_ERROR "returned element '${thevalue}', but expected 'OLD'")
-endif()
diff --git a/Tests/CMakeTests/ListTest.cmake.in b/Tests/CMakeTests/ListTest.cmake.in
index 77c34a9c4..76f5e4f6a 100644
--- a/Tests/CMakeTests/ListTest.cmake.in
+++ b/Tests/CMakeTests/ListTest.cmake.in
@@ -1,8 +1,5 @@
include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake")
-include("@CMAKE_CURRENT_SOURCE_DIR@/../RegexEscapeString.cmake")
-REGEX_ESCAPE_STRING(CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@")
-
macro(TEST command expected)
if("x${result}" STREQUAL "x${expected}")
#message("TEST \"${command}\" success: \"${result}\" expected: \"${expected}\"")
@@ -103,9 +100,6 @@ TEST("REVERSE empty result" "")
list(SORT result)
TEST("SORT empty result" "")
-set(No-Arguments-RESULT 1)
-set(No-Arguments-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-No-Arguments.cmake:1 \\(list\\):.*list must be called with at least two arguments.*")
-
# these trigger top-level condition
foreach(cmd IN ITEMS Append Find Get Insert Length Reverse Remove_At Remove_Duplicates Remove_Item Sort)
set(${cmd}-No-Arguments-RESULT 1)
@@ -132,53 +126,6 @@ foreach(cmd IN ITEMS Find Get Insert Length Remove_At Remove_Item)
check_cmake_test_single(List "${cmd}-List-Only" "${_test_file_name}")
endforeach()
-set(Length-Too-Many-Arguments-RESULT 1)
-set(Length-Too-Many-Arguments-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-Length-Too-Many-Arguments.cmake:1 \\(list\\):.*list sub-command LENGTH requires two arguments.*")
-
-set(Reverse-Too-Many-Arguments-RESULT 1)
-set(Reverse-Too-Many-Arguments-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-Reverse-Too-Many-Arguments.cmake:1 \\(list\\):.*list sub-command REVERSE only takes one argument.*")
-
-set(Remove_Duplicates-Too-Many-Arguments-RESULT 1)
-set(Remove_Duplicates-Too-Many-Arguments-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-Remove_Duplicates-Too-Many-Arguments.cmake:1 \\(list\\):.*list sub-command REMOVE_DUPLICATES only takes one argument.*")
-
-set(Sort-Too-Many-Arguments-RESULT 1)
-set(Sort-Too-Many-Arguments-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-Sort-Too-Many-Arguments.cmake:1 \\(list\\):.*list sub-command SORT only takes one argument.*")
-
-set(Invalid-Subcommand-RESULT 1)
-set(Invalid-Subcommand-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-Invalid-Subcommand.cmake:1 \\(list\\):.*list does not recognize sub-command NO_SUCH_SUBCOMMAND.*")
-
-foreach(cmd Get Insert Remove_At)
- set(${cmd}-Invalid-Index-RESULT 1)
- set(${cmd}-Invalid-Index-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-${cmd}-Invalid-Index.cmake:2 \\(list\\):.*list index: 3 out of range \\(-3, 2\\).*")
-endforeach()
-
-foreach(cmd Remove_Item Reverse Remove_Duplicates Sort Remove_At)
- string(TOUPPER ${cmd} Cmd)
- set(${cmd}-Nonexistent-List-RESULT 1)
- set(${cmd}-Nonexistent-List-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-${cmd}-Nonexistent-List.cmake:2 \\(list\\):.*sub-command ${Cmd} requires list to be present.*")
-endforeach()
-
-set(Get-CMP0007-Warn-RESULT 0)
-set(Get-CMP0007-Warn-STDERR ".*CMake Warning \\(dev\\) at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-Get-CMP0007-Warn.cmake:3 \\(list\\):.*Policy CMP0007 is not set:.*")
-
-check_cmake_test(List
- No-Arguments
- Length-Too-Many-Arguments
- Reverse-Too-Many-Arguments
- Remove_Duplicates-Too-Many-Arguments
- Sort-Too-Many-Arguments
- Invalid-Subcommand
- Get-Invalid-Index
- Insert-Invalid-Index
- Remove_Item-Nonexistent-List
- Reverse-Nonexistent-List
- Remove_Duplicates-Nonexistent-List
- Sort-Nonexistent-List
- Remove_At-Nonexistent-List
- Remove_At-Invalid-Index
- Get-CMP0007-Warn
-)
-
set(thelist "" NEW OLD)
foreach (_pol ${thelist})
diff --git a/Tests/CMakeTests/PolicyCheckTest.cmake.in b/Tests/CMakeTests/PolicyCheckTest.cmake.in
new file mode 100644
index 000000000..416dc0a75
--- /dev/null
+++ b/Tests/CMakeTests/PolicyCheckTest.cmake.in
@@ -0,0 +1,154 @@
+# Check the CMake source tree for suspicious policy introdcutions...
+#
+message("=============================================================================")
+message("CTEST_FULL_OUTPUT (Avoid ctest truncation of output)")
+message("")
+message("CMake_BINARY_DIR='${CMake_BINARY_DIR}'")
+message("CMake_SOURCE_DIR='${CMake_SOURCE_DIR}'")
+message("GIT_EXECUTABLE='${GIT_EXECUTABLE}'")
+message("")
+
+
+# If this does not appear to be a git checkout, just pass the test here
+# and now. (Do not let the test fail if it is run in a tree *exported* from a
+# repository or unpacked from a .zip file source installer...)
+#
+set(is_git_checkout 0)
+if(EXISTS "${CMake_SOURCE_DIR}/.git")
+ set(is_git_checkout 1)
+endif()
+
+message("is_git_checkout='${is_git_checkout}'")
+message("")
+
+if(NOT is_git_checkout)
+ message("source tree is not a git checkout... test passes by early return...")
+ return()
+endif()
+
+# If no GIT_EXECUTABLE, see if we can figure out which git was used
+# for the ctest_update step on this dashboard...
+#
+if(is_git_checkout AND NOT GIT_EXECUTABLE)
+ set(ctest_ini_file "")
+ set(exe "")
+
+ # Use the old name:
+ if(EXISTS "${CMake_BINARY_DIR}/DartConfiguration.tcl")
+ set(ctest_ini_file "${CMake_BINARY_DIR}/DartConfiguration.tcl")
+ endif()
+
+ # But if it exists, prefer the new name:
+ if(EXISTS "${CMake_BINARY_DIR}/CTestConfiguration.ini")
+ set(ctest_ini_file "${CMake_BINARY_DIR}/CTestConfiguration.ini")
+ endif()
+
+ # If there is a ctest ini file, read the update command or git command
+ # from it:
+ #
+ if(ctest_ini_file)
+ file(STRINGS "${ctest_ini_file}" line REGEX "^GITCommand: (.*)$")
+ string(REGEX REPLACE "^GITCommand: (.*)$" "\\1" line "${line}")
+ if("${line}" MATCHES "^\"")
+ string(REGEX REPLACE "^\"([^\"]+)\" *.*$" "\\1" line "${line}")
+ else()
+ string(REGEX REPLACE "^([^ ]+) *.*$" "\\1" line "${line}")
+ endif()
+ set(exe "${line}")
+ if("${exe}" STREQUAL "GITCOMMAND-NOTFOUND")
+ set(exe "")
+ endif()
+ if(exe)
+ message("info: GIT_EXECUTABLE set by 'GITCommand:' from '${ctest_ini_file}'")
+ endif()
+
+ if(NOT exe)
+ file(STRINGS "${ctest_ini_file}" line REGEX "^UpdateCommand: (.*)$")
+ string(REGEX REPLACE "^UpdateCommand: (.*)$" "\\1" line "${line}")
+ if("${line}" MATCHES "^\"")
+ string(REGEX REPLACE "^\"([^\"]+)\" *.*$" "\\1" line "${line}")
+ else()
+ string(REGEX REPLACE "^([^ ]+) *.*$" "\\1" line "${line}")
+ endif()
+ set(exe "${line}")
+ if("${exe}" STREQUAL "GITCOMMAND-NOTFOUND")
+ set(exe "")
+ endif()
+ if(exe)
+ message("info: GIT_EXECUTABLE set by 'UpdateCommand:' from '${ctest_ini_file}'")
+ endif()
+ endif()
+ else()
+ message("info: no DartConfiguration.tcl or CTestConfiguration.ini file...")
+ endif()
+
+ # If we have still not grokked the exe, look in the Update.xml file to see
+ # if we can parse it from there...
+ #
+ if(NOT exe)
+ file(GLOB_RECURSE update_xml_file "${CMake_BINARY_DIR}/Testing/Update.xml")
+ if(update_xml_file)
+ file(STRINGS "${update_xml_file}" line
+ REGEX "^.*<UpdateCommand>(.*)</UpdateCommand>$" LIMIT_COUNT 1)
+ string(REPLACE "&quot\;" "\"" line "${line}")
+ string(REGEX REPLACE "^.*<UpdateCommand>(.*)</UpdateCommand>$" "\\1" line "${line}")
+ if("${line}" MATCHES "^\"")
+ string(REGEX REPLACE "^\"([^\"]+)\" *.*$" "\\1" line "${line}")
+ else()
+ string(REGEX REPLACE "^([^ ]+) *.*$" "\\1" line "${line}")
+ endif()
+ if(line)
+ set(exe "${line}")
+ endif()
+ if(exe)
+ message("info: GIT_EXECUTABLE set by '<UpdateCommand>' from '${update_xml_file}'")
+ endif()
+ else()
+ message("info: no Update.xml file...")
+ endif()
+ endif()
+
+ if(exe)
+ set(GIT_EXECUTABLE "${exe}")
+ message("GIT_EXECUTABLE='${GIT_EXECUTABLE}'")
+ message("")
+
+ if(NOT EXISTS "${GIT_EXECUTABLE}")
+ message(FATAL_ERROR "GIT_EXECUTABLE does not exist...")
+ endif()
+ else()
+ message(FATAL_ERROR "could not determine GIT_EXECUTABLE...")
+ endif()
+endif()
+
+
+if(is_git_checkout AND GIT_EXECUTABLE)
+ # Check with "git grep" if there are any unacceptable cmPolicies additions
+ #
+ message("=============================================================================")
+ message("This is a git checkout, using git grep to verify no unacceptable policies")
+ message("are being introduced....")
+ message("")
+
+ execute_process(COMMAND ${GIT_EXECUTABLE} grep -En "[0-9][0-9][0-9][0-9][0-9].*cmPolicies"
+ WORKING_DIRECTORY ${CMake_SOURCE_DIR}
+ OUTPUT_VARIABLE grep_output
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ message("=== output of 'git grep -En \"[0-9][0-9][0-9][0-9][0-9].*cmPolicies\"' ===")
+ message("${grep_output}")
+ message("=== end output ===")
+ message("")
+
+ if(NOT "${grep_output}" STREQUAL "")
+ message(FATAL_ERROR "git grep output is non-empty...
+New CMake policies must be introduced in a non-date-based version number.
+Send email to the cmake-developers list to figure out what the target
+version number for this policy should be...")
+ endif()
+endif()
+
+
+# Still here? Good then...
+#
+message("test passes")
+message("")
diff --git a/Tests/CMakeTests/StringTest.cmake.in b/Tests/CMakeTests/StringTest.cmake.in
index a9fe428e3..92e70c3ac 100644
--- a/Tests/CMakeTests/StringTest.cmake.in
+++ b/Tests/CMakeTests/StringTest.cmake.in
@@ -63,7 +63,7 @@ check_cmake_test(String
# Execute each test listed in StringTestScript.cmake:
#
set(scriptname "@CMAKE_CURRENT_SOURCE_DIR@/StringTestScript.cmake")
-set(number_of_tests_expected 69)
+set(number_of_tests_expected 70)
include("@CMAKE_CURRENT_SOURCE_DIR@/ExecuteScriptTests.cmake")
execute_all_script_tests(${scriptname} number_of_tests_executed)
@@ -75,6 +75,6 @@ message(STATUS "scriptname='${scriptname}'")
message(STATUS "number_of_tests_executed='${number_of_tests_executed}'")
message(STATUS "number_of_tests_expected='${number_of_tests_expected}'")
-if(number_of_tests_executed LESS number_of_tests_expected)
+if(NOT number_of_tests_executed EQUAL number_of_tests_expected)
message(FATAL_ERROR "error: some test cases were skipped")
endif()
diff --git a/Tests/CMakeTests/StringTestScript.cmake b/Tests/CMakeTests/StringTestScript.cmake
index a562e71d3..44d56531f 100644
--- a/Tests/CMakeTests/StringTestScript.cmake
+++ b/Tests/CMakeTests/StringTestScript.cmake
@@ -122,14 +122,17 @@ elseif(testname STREQUAL substring_not_enough_args) # fail
elseif(testname STREQUAL substring_begin_too_large) # fail
string(SUBSTRING "abcdefg" 25 100 v)
-elseif(testname STREQUAL substring_end_too_large) # fail
+elseif(testname STREQUAL substring_end_larger_than_strlen) # pass
string(SUBSTRING "abcdefg" 1 100 v)
elseif(testname STREQUAL substring_begin_less_than_zero) # fail
- string(SUBSTRING "abcdefg" -2 4 v)
+ string(SUBSTRING "abcdefg" -1 4 v)
-elseif(testname STREQUAL substring_end_less_than_begin) # fail
- string(SUBSTRING "abcdefg" 6 3 v)
+elseif(testname STREQUAL substring_end_less_than_zero) # pass
+ string(SUBSTRING "abcdefg" 0 -1 v)
+
+elseif(testname STREQUAL substring_end_less_than_begin) # pass
+ string(SUBSTRING "abcdefg" 6 0 v)
elseif(testname STREQUAL length_not_enough_args) # fail
string(LENGTH)
diff --git a/Tests/CMakeTests/VersionTest.cmake.in b/Tests/CMakeTests/VersionTest.cmake.in
index 9e31cb431..4e946abe8 100644
--- a/Tests/CMakeTests/VersionTest.cmake.in
+++ b/Tests/CMakeTests/VersionTest.cmake.in
@@ -8,9 +8,85 @@ else()
message("CMAKE_VERSION=[${CMAKE_VERSION}] is not less than [${min_ver}]")
endif()
-set(v 1.2.3.4.5.6.7)
-if("${v}.8" VERSION_LESS "${v}.9")
- message(STATUS "${v}.8 is less than ${v}.9")
-else()
- message(FATAL_ERROR "${v}.8 is not less than ${v}.9?")
-endif()
+set(EQUALV "1 1")
+list(APPEND EQUALV "1.0 1")
+list(APPEND EQUALV "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 1")
+list(APPEND EQUALV "1.2.3.4.5.6.7 1.2.3.4.5.6.7")
+list(APPEND EQUALV "1.2.3.4.5.6.7.8.9 1.2.3.4.5.6.7.8.9")
+
+foreach(v IN LISTS EQUALV)
+ string(REGEX MATCH "(.*) (.*)" _dummy "${v}")
+ # modify any of the operands to see the negative check also works
+ if("${CMAKE_MATCH_1}.2" VERSION_EQUAL CMAKE_MATCH_2)
+ message(FATAL_ERROR "${CMAKE_MATCH_1}.2 is equal ${CMAKE_MATCH_2}?")
+ else()
+ message(STATUS "${CMAKE_MATCH_1}.2 is not equal ${CMAKE_MATCH_2}")
+ endif()
+
+ if(CMAKE_MATCH_1 VERSION_EQUAL "${CMAKE_MATCH_2}.2")
+ message(FATAL_ERROR "${CMAKE_MATCH_1} is equal ${CMAKE_MATCH_2}.2?")
+ else()
+ message(STATUS "${CMAKE_MATCH_1} is not equal ${CMAKE_MATCH_2}.2")
+ endif()
+endforeach()
+
+# test the negative outcomes first, due to the implementation the positive
+# allow some additional strings to pass that would not fail for the negative
+# tests
+
+list(APPEND EQUALV "1a 1")
+list(APPEND EQUALV "1.1a 1.1")
+list(APPEND EQUALV "1.0a 1")
+list(APPEND EQUALV "1a 1.0")
+
+foreach(v IN LISTS EQUALV)
+ # check equal versions
+ string(REGEX MATCH "(.*) (.*)" _dummy "${v}")
+ if(CMAKE_MATCH_1 VERSION_EQUAL CMAKE_MATCH_2)
+ message(STATUS "${CMAKE_MATCH_1} is equal ${CMAKE_MATCH_2}")
+ else()
+ message(FATAL_ERROR "${CMAKE_MATCH_1} is not equal ${CMAKE_MATCH_2}?")
+ endif()
+
+ # still equal, but inverted order of operands
+ string(REGEX MATCH "(.*) (.*)" _dummy "${v}")
+ if(CMAKE_MATCH_2 VERSION_EQUAL CMAKE_MATCH_1)
+ message(STATUS "${CMAKE_MATCH_2} is equal ${CMAKE_MATCH_1}")
+ else()
+ message(FATAL_ERROR "${CMAKE_MATCH_2} is not equal ${CMAKE_MATCH_1}?")
+ endif()
+endforeach()
+
+set(LESSV "1.2.3.4.5.6.7.8 1.2.3.4.5.6.7.9")
+list(APPEND LESSV "1.2.3.4.5.6.7 1.2.3.4.5.6.7.9")
+list(APPEND LESSV "1 1.0.0.1")
+foreach(v IN LISTS LESSV)
+ string(REGEX MATCH "(.*) (.*)" _dummy "${v}")
+ # check less
+ if(CMAKE_MATCH_1 VERSION_LESS CMAKE_MATCH_2)
+ message(STATUS "${CMAKE_MATCH_1} is less than ${CMAKE_MATCH_2}")
+ else()
+ message(FATAL_ERROR "${CMAKE_MATCH_1} is not less than ${CMAKE_MATCH_2}?")
+ endif()
+
+ # check greater
+ if(CMAKE_MATCH_2 VERSION_GREATER CMAKE_MATCH_1)
+ message(STATUS "${CMAKE_MATCH_2} is greater than ${CMAKE_MATCH_1}")
+ else()
+ message(FATAL_ERROR "${CMAKE_MATCH_2} is not greater than ${CMAKE_MATCH_1}?")
+ endif()
+
+ # check less negative case
+ if(NOT CMAKE_MATCH_2 VERSION_LESS CMAKE_MATCH_1)
+ message(STATUS "${CMAKE_MATCH_2} is not less than ${CMAKE_MATCH_1}")
+ else()
+ message(FATAL_ERROR "${CMAKE_MATCH_2} is less than ${CMAKE_MATCH_1}?")
+ endif()
+
+ # check greater negative case
+ if(NOT CMAKE_MATCH_1 VERSION_GREATER CMAKE_MATCH_2)
+ message(STATUS "${CMAKE_MATCH_1} is not greater than ${CMAKE_MATCH_2}")
+ else()
+ message(FATAL_ERROR "${CMAKE_MATCH_1} is greater than ${CMAKE_MATCH_2}?")
+ endif()
+endforeach()
diff --git a/Tests/CMakeTests/WhileTest.cmake.in b/Tests/CMakeTests/WhileTest.cmake.in
index d4cf7d7dc..cc22978ce 100644
--- a/Tests/CMakeTests/WhileTest.cmake.in
+++ b/Tests/CMakeTests/WhileTest.cmake.in
@@ -1,9 +1,6 @@
set(NUMBERS "")
set(COUNT 0)
-include("@CMAKE_CURRENT_SOURCE_DIR@/../RegexEscapeString.cmake")
-REGEX_ESCAPE_STRING(CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@")
-
while(COUNT LESS 200)
set(NUMBERS "${NUMBERS} ${COUNT}")
set(COUNT "2${COUNT}")
@@ -18,40 +15,3 @@ endwhile()
if(NOT NUMBERS STREQUAL " 0 3 30 20 3 30")
message(SEND_ERROR "while loop nesting error, result: '${NUMBERS}'")
endif()
-
-
-set(Missing-Argument-RESULT 1)
-set(Missing-Argument-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Missing-Argument.cmake:1 \\(while\\):.*while called with incorrect number of arguments.*")
-
-include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake")
-check_cmake_test(While
- Missing-Argument
-)
-
-set(Missing-Endwhile-RESULT 1)
-set(Missing-Endwhile-STDERR ".*CMake Error in (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Missing-Endwhile.cmake:.*A logical block opening on the line.*(${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Missing-Endwhile.cmake:1 \\(while\\).*is not closed\\..*")
-
-check_cmake_test(While
- Missing-Endwhile
-)
-
-set(Endwhile-Mismatch-RESULT 0)
-set(Endwhile-Mismatch-STDERR ".*CMake Warning \\(dev\\) in (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Endwhile-Mismatch.cmake:.*A logical block opening on the line.*(${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Endwhile-Mismatch.cmake:1 \\(while\\).*with mis-matching arguments\\..*")
-
-check_cmake_test(While
- Endwhile-Mismatch
-)
-
-set(Endwhile-Alone-RESULT 1)
-set(Endwhile-Alone-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Endwhile-Alone.cmake:1 \\(endwhile\\):.*An ENDWHILE command was found outside of a proper WHILE ENDWHILE.*structure\\.\n.*$")
-
-check_cmake_test(While
- Endwhile-Alone
-)
-
-set(Endwhile-Alone-Args-RESULT 1)
-set(Endwhile-Alone-Args-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Endwhile-Alone-Args.cmake:1 \\(endwhile\\):.*An ENDWHILE command was found outside of a proper WHILE ENDWHILE.*structure\\. Or its arguments did not.*$")
-
-check_cmake_test(While
- Endwhile-Alone-Args
-)
diff --git a/Tests/CMakeWizardTest.cmake b/Tests/CMakeWizardTest.cmake
deleted file mode 100644
index bcae8afeb..000000000
--- a/Tests/CMakeWizardTest.cmake
+++ /dev/null
@@ -1,52 +0,0 @@
-message("CTEST_FULL_OUTPUT (Avoid ctest truncation of output)")
-
-message(STATUS "build_dir='${build_dir}'")
-
-message(STATUS "source_dir='${source_dir}'")
-
-
-execute_process(COMMAND ${CMAKE_COMMAND} -E
- remove_directory ${build_dir}
- TIMEOUT 5)
-
-execute_process(COMMAND ${CMAKE_COMMAND} -E
- make_directory ${build_dir}
- TIMEOUT 5)
-
-execute_process(COMMAND ${CMAKE_COMMAND} -E
- copy_directory ${source_dir} ${build_dir}/src
- TIMEOUT 5)
-
-execute_process(COMMAND ${CMAKE_COMMAND} -E
- make_directory ${build_dir}/build
- TIMEOUT 5)
-
-# This is enough to answer 32 questions with "the default answer is ok"...
-#
-file(WRITE ${build_dir}/input.txt
- "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n")
-
-
-message(STATUS "running wizard mode (cmake -i)...")
-
-execute_process(COMMAND ${CMAKE_COMMAND} -i ../src
- INPUT_FILE ${build_dir}/input.txt
- WORKING_DIRECTORY ${build_dir}/build
- TIMEOUT 5
- )
-
-
-message(STATUS "building...")
-
-execute_process(COMMAND ${CMAKE_COMMAND} --build .
- WORKING_DIRECTORY ${build_dir}/build
- TIMEOUT 5
- )
-
-
-message(STATUS "testing...")
-
-execute_process(COMMAND ${CMAKE_CTEST_COMMAND}
- WORKING_DIRECTORY ${build_dir}/build
- TIMEOUT 5
- )
diff --git a/Tests/CPackComponents/CMakeLists.txt b/Tests/CPackComponents/CMakeLists.txt
index 1cb86696a..3c8ae3524 100644
--- a/Tests/CPackComponents/CMakeLists.txt
+++ b/Tests/CPackComponents/CMakeLists.txt
@@ -72,7 +72,7 @@ set(CPACK_PACKAGE_INSTALL_DIRECTORY "CPack Component Example")
set(CPACK_NSIS_MENU_LINKS
"ftp://ftpserver" "Test Ftp Link"
"ftps://ftpsserver" "Test Ftps Link"
- "http://www.cmake.org" "CMake Web Site"
+ "https://cmake.org" "CMake Web Site"
"https://github.com/" "Test Https Link"
"mailto:kitware@kitware.com" "Test MailTo Link"
"news://newsserver" "Test News Link"
diff --git a/Tests/CPackComponentsDEB/CMakeLists.txt b/Tests/CPackComponentsDEB/CMakeLists.txt
new file mode 100644
index 000000000..093b23fdd
--- /dev/null
+++ b/Tests/CPackComponentsDEB/CMakeLists.txt
@@ -0,0 +1,135 @@
+# CPack Example: User-selectable Installation Components
+#
+# In this example, we have a simple library (mylib) with an example
+# application (mylibapp). We create a binary installer (a CPack Generator)
+# which supports CPack components.
+
+cmake_minimum_required(VERSION 2.8.3.20101130 FATAL_ERROR)
+project(CPackComponentsDEB)
+
+# Use GNUInstallDirs in order to enforce lib64 if needed
+include(GNUInstallDirs)
+
+# Create the mylib library
+add_library(mylib mylib.cpp)
+
+# Create the mylibapp application
+add_executable(mylibapp mylibapp.cpp)
+target_link_libraries(mylibapp mylib)
+
+# Duplicate of mylibapp application
+# which won't be put in any component (?mistake?)
+add_executable(mylibapp2 mylibapp.cpp)
+target_link_libraries(mylibapp2 mylib)
+
+# Create installation targets. Note that we put each kind of file
+# into a different component via COMPONENT. These components will
+# be used to create the installation components.
+install(TARGETS mylib
+ ARCHIVE
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ COMPONENT libraries)
+
+install(TARGETS mylibapp
+ RUNTIME
+ DESTINATION bin
+ COMPONENT applications)
+
+install(FILES mylib.h
+ DESTINATION include
+ COMPONENT headers)
+
+# CPack boilerplate for this project
+set(CPACK_PACKAGE_NAME "MyLib")
+set(CPACK_PACKAGE_CONTACT "None")
+set(CPACK_PACKAGE_VENDOR "CMake.org")
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "MyLib - CPack Component Installation Example")
+set(CPACK_PACKAGE_VERSION "1.0.2")
+set(CPACK_PACKAGE_VERSION_MAJOR "1")
+set(CPACK_PACKAGE_VERSION_MINOR "0")
+set(CPACK_PACKAGE_VERSION_PATCH "2")
+set(CPACK_PACKAGE_INSTALL_DIRECTORY "CPack Component Example")
+set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/license.txt)
+
+# Tell CPack all of the components to install. The "ALL"
+# refers to the fact that this is the set of components that
+# will be included when CPack is instructed to put everything
+# into the binary installer (the default behavior).
+set(CPACK_COMPONENTS_ALL applications libraries headers)
+
+# Set the displayed names for each of the components to install.
+# These will be displayed in the list of components inside the installer.
+set(CPACK_COMPONENT_APPLICATIONS_DISPLAY_NAME "MyLib Application")
+set(CPACK_COMPONENT_LIBRARIES_DISPLAY_NAME "Libraries")
+set(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ Headers")
+
+# Provide descriptions for each of the components to install.
+# When the user hovers the mouse over the name of a component,
+# the description will be shown in the "Description" box in the
+# installer. If no descriptions are provided, the "Description"
+# box will be removed.
+set(CPACK_COMPONENT_APPLICATIONS_DESCRIPTION
+ "An extremely useful application that makes use of MyLib")
+set(CPACK_COMPONENT_LIBRARIES_DESCRIPTION
+ "Static libraries used to build programs with MyLib")
+set(CPACK_COMPONENT_HEADERS_DESCRIPTION
+ "C/C++ header files for use with MyLib")
+
+# It doesn't make sense to install the headers without the libraries
+# (because you could never use the headers!), so make the headers component
+# depend on the libraries component.
+set(CPACK_COMPONENT_HEADERS_DEPENDS libraries)
+
+# creates preinst/prerm scripts with specific permissions. Those permissions
+# (especially executable) should be in the final archive
+find_program(CHMOD_PROG chmod)
+if(CHMOD_PROG)
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/preinst "echo default_preinst")
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/prerm "echo default_prerm")
+
+ # Those should have 755 permission normally. We mess it up to see if
+ # CPACK_DEBIAN_APPLICATIONS_PACKAGE_CONTROL_STRICT_PERMISSION is able to fix
+ # it.
+ execute_process(COMMAND ${CHMOD_PROG} 640 ${CMAKE_CURRENT_BINARY_DIR}/preinst)
+ execute_process(COMMAND ${CHMOD_PROG} 640 ${CMAKE_CURRENT_BINARY_DIR}/prerm)
+
+ set(CPACK_DEBIAN_APPLICATIONS_PACKAGE_CONTROL_EXTRA
+ "${CMAKE_CURRENT_BINARY_DIR}/preinst;${CMAKE_CURRENT_BINARY_DIR}/prerm")
+
+ set(CPACK_DEBIAN_APPLICATIONS_PACKAGE_CONTROL_STRICT_PERMISSION TRUE)
+endif()
+
+# creates a symbolic link and a directory. Those should not be hashed.
+# warning: relocation of the symlink is not supported (symlinks with relative
+# paths)
+execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink mylibapp symtest)
+install(FILES ${CPackComponentsDEB_BINARY_DIR}/symtest
+ DESTINATION bin
+ COMPONENT applications)
+
+if(EXISTS "./dirtest")
+ execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory ./dirtest)
+endif()
+# NOTE: directory left empty on purpose
+execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ./dirtest)
+# NOTE: we should not add the trailing "/" to dirtest
+install(DIRECTORY ${CPackComponentsDEB_BINARY_DIR}/dirtest
+ DESTINATION bin/
+ COMPONENT applications)
+
+# We may use the CPack specific config file in order
+# to tailor CPack behavior on a CPack generator specific way
+# (Behavior would be different for RPM or TGZ or DEB ...)
+if (NOT DEFINED CPackDEBConfiguration)
+ message(FATAL_ERROR "CPackDEBConfiguration should be defined")
+endif()
+
+# Setup project specific CPack-time CPack Config file.
+configure_file(${CPackComponentsDEB_SOURCE_DIR}/MyLibCPackConfig-${CPackDEBConfiguration}.cmake.in
+ ${CPackComponentsDEB_BINARY_DIR}/MyLibCPackConfig-${CPackDEBConfiguration}.cmake
+ @ONLY)
+set(CPACK_PROJECT_CONFIG_FILE ${CPackComponentsDEB_BINARY_DIR}/MyLibCPackConfig-${CPackDEBConfiguration}.cmake)
+
+
+# Include CPack to introduce the appropriate targets
+include(CPack)
diff --git a/Tests/CPackComponentsDEB/MyLibCPackConfig-components-depend1.cmake.in b/Tests/CPackComponentsDEB/MyLibCPackConfig-components-depend1.cmake.in
new file mode 100644
index 000000000..d207bcc12
--- /dev/null
+++ b/Tests/CPackComponentsDEB/MyLibCPackConfig-components-depend1.cmake.in
@@ -0,0 +1,20 @@
+#
+# Activate component packaging
+#
+
+if(CPACK_GENERATOR MATCHES "DEB")
+ set(CPACK_DEB_COMPONENT_INSTALL "ON")
+endif()
+
+#
+# Choose grouping way
+#
+#set(CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE)
+#set(CPACK_COMPONENTS_GROUPING)
+set(CPACK_COMPONENTS_IGNORE_GROUPS 1)
+#set(CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE 1)
+
+# setting dependencies
+set(CPACK_DEBIAN_PACKAGE_DEPENDS "depend-default")
+set(CPACK_DEBIAN_APPLICATIONS_PACKAGE_DEPENDS "depend-application")
+set(CPACK_DEBIAN_HEADERS_PACKAGE_DEPENDS "depend-headers")
diff --git a/Tests/CPackComponentsDEB/MyLibCPackConfig-components-depend2.cmake.in b/Tests/CPackComponentsDEB/MyLibCPackConfig-components-depend2.cmake.in
new file mode 100644
index 000000000..803720a3c
--- /dev/null
+++ b/Tests/CPackComponentsDEB/MyLibCPackConfig-components-depend2.cmake.in
@@ -0,0 +1,29 @@
+#
+# Activate component packaging
+#
+
+if(CPACK_GENERATOR MATCHES "DEB")
+ set(CPACK_DEB_COMPONENT_INSTALL "ON")
+endif()
+
+#
+# Choose grouping way
+#
+#set(CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE)
+#set(CPACK_COMPONENTS_GROUPING)
+set(CPACK_COMPONENTS_IGNORE_GROUPS 1)
+#set(CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE 1)
+
+# setting dependencies
+set(CPACK_DEBIAN_PACKAGE_DEPENDS "depend-default")
+set(CPACK_DEBIAN_HEADERS_PACKAGE_DEPENDS "depend-headers")
+
+# this time we set shlibdeps to on
+set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
+set(CPACK_DEBIAN_HEADERS_PACKAGE_SHLIBDEPS OFF)
+set(CPACK_DEBIAN_LIBRARIES_PACKAGE_SHLIBDEPS OFF)
+
+# we also set the dependencies of APPLICATION component to empty, and let
+# shlibdeps do the job for this component. Otherwise the default will
+# override
+set(CPACK_DEBIAN_APPLICATIONS_PACKAGE_DEPENDS "")
diff --git a/Tests/CPackComponentsDEB/MyLibCPackConfig-components-description1.cmake.in b/Tests/CPackComponentsDEB/MyLibCPackConfig-components-description1.cmake.in
new file mode 100644
index 000000000..74d816cf6
--- /dev/null
+++ b/Tests/CPackComponentsDEB/MyLibCPackConfig-components-description1.cmake.in
@@ -0,0 +1,22 @@
+#
+# Activate component packaging
+#
+
+if(CPACK_GENERATOR MATCHES "DEB")
+ set(CPACK_DEB_COMPONENT_INSTALL "ON")
+endif()
+
+#
+# Choose grouping way
+#
+#set(CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE)
+#set(CPACK_COMPONENTS_GROUPING)
+set(CPACK_COMPONENTS_IGNORE_GROUPS 1)
+#set(CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE 1)
+
+# overriding previous descriptions
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "main description")
+set(CPACK_COMPONENT_APPLICATIONS_DESCRIPTION "applications_description")
+set(CPACK_COMPONENT_HEADERS_DESCRIPTION "headers_description")
+# libraries does not have any description and should inherit from CPACK_PACKAGE_DESCRIPTION_SUMMARY
+unset(CPACK_COMPONENT_LIBRARIES_DESCRIPTION)
diff --git a/Tests/CPackComponentsDEB/MyLibCPackConfig-components-description2.cmake.in b/Tests/CPackComponentsDEB/MyLibCPackConfig-components-description2.cmake.in
new file mode 100644
index 000000000..cda79bc02
--- /dev/null
+++ b/Tests/CPackComponentsDEB/MyLibCPackConfig-components-description2.cmake.in
@@ -0,0 +1,26 @@
+#
+# Activate component packaging
+#
+
+if(CPACK_GENERATOR MATCHES "DEB")
+ set(CPACK_DEB_COMPONENT_INSTALL "ON")
+endif()
+
+#
+# Choose grouping way
+#
+#set(CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE)
+#set(CPACK_COMPONENTS_GROUPING)
+set(CPACK_COMPONENTS_IGNORE_GROUPS 1)
+#set(CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE 1)
+
+# overriding previous descriptions
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "main description 2")
+
+# Components do not have any description
+unset(CPACK_COMPONENT_APPLICATIONS_DESCRIPTION)
+unset(CPACK_COMPONENT_HEADERS_DESCRIPTION)
+unset(CPACK_COMPONENT_LIBRARIES_DESCRIPTION)
+
+
+set(CPACK_COMPONENT_LIBRARIES_DESCRIPTION "library description")
diff --git a/Tests/CPackComponentsDEB/MyLibCPackConfig-components-lintian-dpkgdeb-checks.cmake.in b/Tests/CPackComponentsDEB/MyLibCPackConfig-components-lintian-dpkgdeb-checks.cmake.in
new file mode 100644
index 000000000..e0a9e9d1c
--- /dev/null
+++ b/Tests/CPackComponentsDEB/MyLibCPackConfig-components-lintian-dpkgdeb-checks.cmake.in
@@ -0,0 +1,15 @@
+#
+# Activate component packaging
+#
+
+if(CPACK_GENERATOR MATCHES "DEB")
+ set(CPACK_DEB_COMPONENT_INSTALL "ON")
+endif()
+
+#
+# Choose grouping way
+#
+#set(CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE)
+#set(CPACK_COMPONENTS_GROUPING)
+set(CPACK_COMPONENTS_IGNORE_GROUPS 1)
+#set(CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE 1)
diff --git a/Tests/CPackComponentsDEB/MyLibCPackConfig-components-shlibdeps1.cmake.in b/Tests/CPackComponentsDEB/MyLibCPackConfig-components-shlibdeps1.cmake.in
new file mode 100644
index 000000000..cfe6df529
--- /dev/null
+++ b/Tests/CPackComponentsDEB/MyLibCPackConfig-components-shlibdeps1.cmake.in
@@ -0,0 +1,24 @@
+#
+# Activate component packaging
+#
+
+if(CPACK_GENERATOR MATCHES "DEB")
+ set(CPACK_DEB_COMPONENT_INSTALL "ON")
+endif()
+
+#
+# Choose grouping way
+#
+#set(CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE)
+#set(CPACK_COMPONENTS_GROUPING)
+set(CPACK_COMPONENTS_IGNORE_GROUPS 1)
+#set(CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE 1)
+
+# we set shlibdeps to on
+set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
+# except for the component "headers" that do not contain any binary.
+# the packaging will just fail if this does not work
+set(CPACK_DEBIAN_HEADERS_PACKAGE_SHLIBDEPS OFF)
+
+# Also libraries contains only a static library.
+set(CPACK_DEBIAN_LIBRARIES_PACKAGE_SHLIBDEPS OFF)
diff --git a/Tests/CPackComponentsDEB/MyLibCPackConfig-components-source.cmake.in b/Tests/CPackComponentsDEB/MyLibCPackConfig-components-source.cmake.in
new file mode 100644
index 000000000..352f10b99
--- /dev/null
+++ b/Tests/CPackComponentsDEB/MyLibCPackConfig-components-source.cmake.in
@@ -0,0 +1,33 @@
+#
+# Activate component packaging
+#
+
+if(CPACK_GENERATOR MATCHES "DEB")
+ set(CPACK_DEB_COMPONENT_INSTALL "ON")
+endif()
+
+#
+# Choose grouping way
+#
+set(CPACK_COMPONENTS_IGNORE_GROUPS 1)
+
+# setting dependencies
+set(CPACK_DEBIAN_PACKAGE_DEPENDS "depend-default")
+set(CPACK_DEBIAN_HEADERS_PACKAGE_DEPENDS "depend-headers")
+
+# this time we set shlibdeps to on
+set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
+set(CPACK_DEBIAN_HEADERS_PACKAGE_SHLIBDEPS OFF)
+set(CPACK_DEBIAN_LIBRARIES_PACKAGE_SHLIBDEPS OFF)
+
+# we also set the dependencies of APPLICATION component to empty, and let
+# shlibdeps do the job for this component. Otherwise the default will
+# override
+set(CPACK_DEBIAN_APPLICATIONS_PACKAGE_DEPENDS "")
+
+# this sets the generated packages source to the desired one, in case
+# several packages are generated from a unique source (the case with
+# multicomponents packaging).
+
+set(CPACK_DEBIAN_PACKAGE_SOURCE "test-source")
+set(CPACK_DEBIAN_APPLICATIONS_PACKAGE_SOURCE "test-other-source")
diff --git a/Tests/CPackComponentsDEB/MyLibCPackConfig-compression.cmake.in b/Tests/CPackComponentsDEB/MyLibCPackConfig-compression.cmake.in
new file mode 100644
index 000000000..ff1883453
--- /dev/null
+++ b/Tests/CPackComponentsDEB/MyLibCPackConfig-compression.cmake.in
@@ -0,0 +1,11 @@
+#
+# Test that setting the compression produces valid
+# packages (compression does not leak to the DEBIAN/ files that use gzip)
+#
+
+if(CPACK_GENERATOR MATCHES "DEB")
+ set(CPACK_DEB_COMPONENT_INSTALL "OFF")
+endif()
+
+set(CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE)
+set(CPACK_DEBIAN_COMPRESSION_TYPE xz)
diff --git a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-depend1.cmake b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-depend1.cmake
new file mode 100644
index 000000000..26ab19ed3
--- /dev/null
+++ b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-depend1.cmake
@@ -0,0 +1,85 @@
+if(NOT CPackComponentsDEB_SOURCE_DIR)
+ message(FATAL_ERROR "CPackComponentsDEB_SOURCE_DIR not set")
+endif()
+
+include(${CPackComponentsDEB_SOURCE_DIR}/RunCPackVerifyResult.cmake)
+
+
+# expected results
+set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/MyLib-*.deb")
+set(expected_count 3)
+
+
+set(actual_output)
+run_cpack(actual_output
+ CPack_output
+ CPack_error
+ EXPECTED_FILE_MASK "${expected_file_mask}"
+ CONFIG_ARGS ${config_args}
+ CONFIG_VERBOSE ${config_verbose})
+
+
+if(NOT actual_output)
+ message(STATUS "expected_count='${expected_count}'")
+ message(STATUS "expected_file_mask='${expected_file_mask}'")
+ message(STATUS "actual_output_files='${actual_output}'")
+ message(FATAL_ERROR "error: expected_files do not exist: CPackComponentsDEB test fails. (CPack_output=${CPack_output}, CPack_error=${CPack_error}")
+endif()
+
+list(LENGTH actual_output actual_count)
+if(NOT actual_count EQUAL expected_count)
+ message(STATUS "actual_count='${actual_count}'")
+ message(FATAL_ERROR "error: expected_count=${expected_count} does not match actual_count=${actual_count}: CPackComponents test fails. (CPack_output=${CPack_output}, CPack_error=${CPack_error})")
+endif()
+
+
+# dpkg-deb checks for the dependencies of the packages
+find_program(DPKGDEB_EXECUTABLE dpkg-deb)
+if(DPKGDEB_EXECUTABLE)
+ set(dpkgdeb_output_errors_all "")
+ foreach(_f IN LISTS actual_output)
+
+ # extracts the metadata from the package
+ run_dpkgdeb(dpkg_output
+ FILENAME "${_f}"
+ )
+
+ dpkgdeb_return_specific_metaentry(dpkg_package_name
+ DPKGDEB_OUTPUT "${dpkg_output}"
+ METAENTRY "Package:")
+
+ dpkgdeb_return_specific_metaentry(dpkg_depends
+ DPKGDEB_OUTPUT "${dpkg_output}"
+ METAENTRY "Depends:")
+
+ message(STATUS "package='${dpkg_package_name}', dependencies='${dpkg_depends}'")
+
+ if("${dpkg_package_name}" STREQUAL "mylib-applications")
+ if(NOT "${dpkg_depends}" STREQUAL "depend-application")
+ set(dpkgdeb_output_errors_all ${dpkgdeb_output_errors_all}
+ "dpkg-deb: ${_f}: Incorrect dependencies for package ${dpkg_package_name}: '${dpkg_depends}' != 'depend-application'\n")
+ endif()
+ elseif("${dpkg_package_name}" STREQUAL "mylib-headers")
+ if(NOT "${dpkg_depends}" STREQUAL "depend-headers")
+ set(dpkgdeb_output_errors_all ${dpkgdeb_output_errors_all}
+ "dpkg-deb: ${_f}: Incorrect dependencies for package ${dpkg_package_name}: '${dpkg_depends}' != 'depend-headers'\n")
+ endif()
+ elseif("${dpkg_package_name}" STREQUAL "mylib-libraries")
+ if(NOT "${dpkg_depends}" STREQUAL "depend-default")
+ set(dpkgdeb_output_errors_all ${dpkgdeb_output_errors_all}
+ "dpkg-deb: ${_f}: Incorrect dependencies for package ${dpkg_package_name}: '${dpkg_depends}' != 'depend-default'\n")
+ endif()
+ else()
+ set(dpkgdeb_output_errors_all ${dpkgdeb_output_errors_all}
+ "dpkg-deb: ${_f}: component name not found: ${dpkg_package_name}\n")
+ endif()
+
+ endforeach()
+
+
+ if(NOT "${dpkgdeb_output_errors_all}" STREQUAL "")
+ message(FATAL_ERROR "dpkg-deb checks failed:\n${dpkgdeb_output_errors_all}")
+ endif()
+else()
+ message("dpkg-deb executable not found - skipping dpkg-deb test")
+endif()
diff --git a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-depend2.cmake b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-depend2.cmake
new file mode 100644
index 000000000..79e5df21f
--- /dev/null
+++ b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-depend2.cmake
@@ -0,0 +1,97 @@
+if(NOT CPackComponentsDEB_SOURCE_DIR)
+ message(FATAL_ERROR "CPackComponentsDEB_SOURCE_DIR not set")
+endif()
+
+include(${CPackComponentsDEB_SOURCE_DIR}/RunCPackVerifyResult.cmake)
+
+
+# expected results
+set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/MyLib-*.deb")
+set(expected_count 3)
+
+set(config_verbose -V)
+set(actual_output)
+run_cpack(actual_output
+ CPack_output
+ CPack_error
+ EXPECTED_FILE_MASK "${expected_file_mask}"
+ CONFIG_ARGS ${config_args}
+ CONFIG_VERBOSE ${config_verbose})
+
+
+if(NOT actual_output)
+ message(STATUS "expected_count='${expected_count}'")
+ message(STATUS "expected_file_mask='${expected_file_mask}'")
+ message(STATUS "actual_output_files='${actual_output}'")
+ message(FATAL_ERROR "error: expected_files do not exist: CPackComponentsDEB test fails. (CPack_output=${CPack_output}, CPack_error=${CPack_error}")
+endif()
+
+list(LENGTH actual_output actual_count)
+if(NOT actual_count EQUAL expected_count)
+ message(STATUS "actual_count='${actual_count}'")
+ message(FATAL_ERROR "error: expected_count=${expected_count} does not match actual_count=${actual_count}: CPackComponents test fails. (CPack_output=${CPack_output}, CPack_error=${CPack_error})")
+endif()
+
+
+# dpkg-deb checks for the summary of the packages
+find_program(DPKGDEB_EXECUTABLE dpkg-deb)
+if(DPKGDEB_EXECUTABLE)
+ set(dpkgdeb_output_errors_all "")
+ foreach(_f IN LISTS actual_output)
+
+ # extracts the metadata from the package
+ run_dpkgdeb(dpkg_output
+ FILENAME "${_f}"
+ )
+
+ dpkgdeb_return_specific_metaentry(dpkg_package_name
+ DPKGDEB_OUTPUT "${dpkg_output}"
+ METAENTRY "Package:")
+
+ dpkgdeb_return_specific_metaentry(dpkg_depends
+ DPKGDEB_OUTPUT "${dpkg_output}"
+ METAENTRY "Depends:")
+
+ message(STATUS "package='${dpkg_package_name}', dependencies='${dpkg_depends}'")
+
+ if("${dpkg_package_name}" STREQUAL "mylib-applications")
+ find_program(DPKG_SHLIBDEP_EXECUTABLE dpkg-shlibdeps)
+ if(DPKG_SHLIBDEP_EXECUTABLE)
+ string(FIND "${dpkg_depends}" "lib" index_libwhatever)
+ if(NOT index_libwhatever GREATER "-1")
+ set(dpkgdeb_output_errors_all "${dpkgdeb_output_errors_all}"
+ "dpkg-deb: ${_f}: Incorrect dependencies for package ${dpkg_package_name}: '${dpkg_depends}' does not contain any 'lib'\n")
+ endif()
+ else()
+ message("dpkg-shlibdeps executable not found - skipping dpkg-shlibdeps test")
+ endif()
+
+ # should not contain the default
+ string(FIND "${dpkg_depends}" "depend-default" index_default)
+ if(index_default GREATER "0")
+ set(dpkgdeb_output_errors_all "${dpkgdeb_output_errors_all}"
+ "dpkg-deb: ${_f}: Incorrect dependencies for package ${dpkg_package_name}: '${dpkg_depends}' does contains 'depend-default'\n")
+ endif()
+ elseif("${dpkg_package_name}" STREQUAL "mylib-headers")
+ if(NOT "${dpkg_depends}" STREQUAL "depend-headers")
+ set(dpkgdeb_output_errors_all "${dpkgdeb_output_errors_all}"
+ "dpkg-deb: ${_f}: Incorrect dependencies for package ${dpkg_package_name}: '${dpkg_depends}' != 'depend-headers'\n")
+ endif()
+ elseif("${dpkg_package_name}" STREQUAL "mylib-libraries")
+ if(NOT "${dpkg_depends}" STREQUAL "depend-default")
+ set(dpkgdeb_output_errors_all "${dpkgdeb_output_errors_all}"
+ "dpkg-deb: ${_f}: Incorrect dependencies for package ${dpkg_package_name}: '${dpkg_depends}' != 'depend-default'\n")
+ endif()
+ else()
+ set(dpkgdeb_output_errors_all "${dpkgdeb_output_errors_all}"
+ "dpkg-deb: ${_f}: component name not found: ${dpkg_package_name}\n")
+ endif()
+
+ endforeach()
+
+ if(NOT "${dpkgdeb_output_errors_all}" STREQUAL "")
+ message(FATAL_ERROR "dpkg-deb checks failed:\n${dpkgdeb_output_errors_all}")
+ endif()
+else()
+ message("dpkg-deb executable not found - skipping dpkg-deb test")
+endif()
diff --git a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-description1.cmake b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-description1.cmake
new file mode 100644
index 000000000..6335029e6
--- /dev/null
+++ b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-description1.cmake
@@ -0,0 +1,85 @@
+if(NOT CPackComponentsDEB_SOURCE_DIR)
+ message(FATAL_ERROR "CPackComponentsDEB_SOURCE_DIR not set")
+endif()
+
+include(${CPackComponentsDEB_SOURCE_DIR}/RunCPackVerifyResult.cmake)
+
+
+# expected results
+set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/MyLib-*.deb")
+set(expected_count 3)
+
+
+set(actual_output)
+run_cpack(actual_output
+ CPack_output
+ CPack_error
+ EXPECTED_FILE_MASK "${expected_file_mask}"
+ CONFIG_ARGS ${config_args}
+ CONFIG_VERBOSE ${config_verbose})
+
+
+if(NOT actual_output)
+ message(STATUS "expected_count='${expected_count}'")
+ message(STATUS "expected_file_mask='${expected_file_mask}'")
+ message(STATUS "actual_output_files='${actual_output}'")
+ message(FATAL_ERROR "error: expected_files do not exist: CPackComponentsDEB test fails. (CPack_output=${CPack_output}, CPack_error=${CPack_error}")
+endif()
+
+list(LENGTH actual_output actual_count)
+if(NOT actual_count EQUAL expected_count)
+ message(STATUS "actual_count='${actual_count}'")
+ message(FATAL_ERROR "error: expected_count=${expected_count} does not match actual_count=${actual_count}: CPackComponents test fails. (CPack_output=${CPack_output}, CPack_error=${CPack_error})")
+endif()
+
+
+# dpkg-deb checks for the summary of the packages
+find_program(DPKGDEB_EXECUTABLE dpkg-deb)
+if(DPKGDEB_EXECUTABLE)
+ set(dpkgdeb_output_errors_all "")
+ foreach(_f IN LISTS actual_output)
+
+ # extracts the metadata from the package
+ run_dpkgdeb(dpkg_output
+ FILENAME ${_f}
+ )
+
+ dpkgdeb_return_specific_metaentry(dpkg_package_name
+ DPKGDEB_OUTPUT "${dpkg_output}"
+ METAENTRY "Package:")
+
+ dpkgdeb_return_specific_metaentry(dpkg_description
+ DPKGDEB_OUTPUT "${dpkg_output}"
+ METAENTRY "Description:")
+
+ message(STATUS "package='${dpkg_package_name}', description='${dpkg_description}'")
+
+ if("${dpkg_package_name}" STREQUAL "mylib-applications")
+ if(NOT "${dpkg_description}" STREQUAL "applications_description")
+ set(dpkgdeb_output_errors_all ${dpkgdeb_output_errors_all}
+ "dpkg-deb: ${_f}: Incorrect description for package ${dpkg_package_name}: ${dpkg_description} != applications_description")
+ endif()
+ elseif("${dpkg_package_name}" STREQUAL "mylib-headers")
+ if(NOT "${dpkg_description}" STREQUAL "headers_description")
+ set(dpkgdeb_output_errors_all ${dpkgdeb_output_errors_all}
+ "dpkg-deb: ${_f}: Incorrect description for package ${dpkg_package_name}: ${dpkg_description} != headers_description")
+ endif()
+ elseif("${dpkg_package_name}" STREQUAL "mylib-libraries")
+ if(NOT "${dpkg_description}" STREQUAL "main description")
+ set(dpkgdeb_output_errors_all ${dpkgdeb_output_errors_all}
+ "dpkg-deb: ${_f}: Incorrect description for package ${dpkg_package_name}: ${dpkg_description} != 'main description'")
+ endif()
+ else()
+ set(dpkgdeb_output_errors_all ${dpkgdeb_output_errors_all}
+ "dpkg-deb: ${_f}: component name not found: ${dpkg_package_name}\n")
+ endif()
+
+ endforeach()
+
+
+ if(NOT "${dpkgdeb_output_errors_all}" STREQUAL "")
+ message(FATAL_ERROR "dpkg-deb checks failed:\n${dpkgdeb_output_errors_all}")
+ endif()
+else()
+ message("dpkg-deb executable not found - skipping dpkg-deb test")
+endif()
diff --git a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-description2.cmake b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-description2.cmake
new file mode 100644
index 000000000..3d0929649
--- /dev/null
+++ b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-description2.cmake
@@ -0,0 +1,85 @@
+if(NOT CPackComponentsDEB_SOURCE_DIR)
+ message(FATAL_ERROR "CPackComponentsDEB_SOURCE_DIR not set")
+endif()
+
+include(${CPackComponentsDEB_SOURCE_DIR}/RunCPackVerifyResult.cmake)
+
+
+
+# expected results
+set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/MyLib-*.deb")
+set(expected_count 3)
+
+
+set(actual_output)
+run_cpack(actual_output
+ CPack_output
+ CPack_error
+ EXPECTED_FILE_MASK "${expected_file_mask}"
+ CONFIG_ARGS ${config_args}
+ CONFIG_VERBOSE ${config_verbose})
+
+if(NOT actual_output)
+ message(STATUS "expected_count='${expected_count}'")
+ message(STATUS "expected_file_mask='${expected_file_mask}'")
+ message(STATUS "actual_output_files='${actual_output}'")
+ message(FATAL_ERROR "error: expected_files do not exist: CPackComponentsDEB test fails. (CPack_output=${CPack_output}, CPack_error=${CPack_error}")
+endif()
+
+list(LENGTH actual_output actual_count)
+message(STATUS "actual_count='${actual_count}'")
+if(NOT actual_count EQUAL expected_count)
+ message(FATAL_ERROR "error: expected_count=${expected_count} does not match actual_count=${actual_count}: CPackComponents test fails. (CPack_output=${CPack_output}, CPack_error=${CPack_error})")
+endif()
+
+
+# dpkg-deb checks for the summary of the packages
+find_program(DPKGDEB_EXECUTABLE dpkg-deb)
+if(DPKGDEB_EXECUTABLE)
+ set(dpkgdeb_output_errors_all "")
+ foreach(_f IN LISTS actual_output)
+
+ # extracts the metadata from the package
+ run_dpkgdeb(dpkg_output
+ FILENAME ${_f}
+ )
+
+ dpkgdeb_return_specific_metaentry(dpkg_package_name
+ DPKGDEB_OUTPUT "${dpkg_output}"
+ METAENTRY "Package:")
+
+ dpkgdeb_return_specific_metaentry(dpkg_description
+ DPKGDEB_OUTPUT "${dpkg_output}"
+ METAENTRY "Description:")
+
+ message(STATUS "package='${dpkg_package_name}', description='${dpkg_description}'")
+
+ if("${dpkg_package_name}" STREQUAL "mylib-applications")
+ if(NOT "${dpkg_description}" STREQUAL "main description 2")
+ set(dpkgdeb_output_errors_all ${dpkgdeb_output_errors_all}
+ "dpkg-deb: ${_f}: Incorrect description for package ${dpkg_package_name}: ${dpkg_description} != applications_description")
+ endif()
+ elseif("${dpkg_package_name}" STREQUAL "mylib-headers")
+ if(NOT "${dpkg_description}" STREQUAL "main description 2")
+ set(dpkgdeb_output_errors_all ${dpkgdeb_output_errors_all}
+ "dpkg-deb: ${_f}: Incorrect description for package ${dpkg_package_name}: ${dpkg_description} != headers_description")
+ endif()
+ elseif("${dpkg_package_name}" STREQUAL "mylib-libraries")
+ if(NOT "${dpkg_description}" STREQUAL "library description")
+ set(dpkgdeb_output_errors_all ${dpkgdeb_output_errors_all}
+ "dpkg-deb: ${_f}: Incorrect description for package ${dpkg_package_name}: ${dpkg_description} != 'main description'")
+ endif()
+ else()
+ set(dpkgdeb_output_errors_all ${dpkgdeb_output_errors_all}
+ "dpkg-deb: ${_f}: component name not found: ${dpkg_package_name}\n")
+ endif()
+
+ endforeach()
+
+
+ if(NOT "${dpkgdeb_output_errors_all}" STREQUAL "")
+ message(FATAL_ERROR "dpkg-deb checks failed:\n${dpkgdeb_output_errors_all}")
+ endif()
+else()
+ message("dpkg-deb executable not found - skipping dpkg-deb test")
+endif()
diff --git a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-lintian-dpkgdeb-checks.cmake b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-lintian-dpkgdeb-checks.cmake
new file mode 100644
index 000000000..ff22f8f9f
--- /dev/null
+++ b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-lintian-dpkgdeb-checks.cmake
@@ -0,0 +1,78 @@
+if(NOT CPackComponentsDEB_SOURCE_DIR)
+ message(FATAL_ERROR "CPackComponentsDEB_SOURCE_DIR not set")
+endif()
+
+include(${CPackComponentsDEB_SOURCE_DIR}/RunCPackVerifyResult.cmake)
+
+# TODO: currently debian doens't produce lower cased names
+set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/MyLib-*.deb")
+set(expected_count 3)
+
+
+set(actual_output)
+run_cpack(actual_output
+ CPack_output
+ CPack_error
+ EXPECTED_FILE_MASK "${expected_file_mask}"
+ CONFIG_ARGS "${config_args}"
+ CONFIG_VERBOSE "${config_verbose}")
+
+if(NOT actual_output)
+ message(STATUS "expected_count='${expected_count}'")
+ message(STATUS "expected_file_mask='${expected_file_mask}'")
+ message(STATUS "actual_output_files='${actual_output}'")
+ message(FATAL_ERROR "error: expected_files do not exist: CPackComponentsDEB test fails. (CPack_output=${CPack_output}, CPack_error=${CPack_error}")
+endif()
+
+list(LENGTH actual_output actual_count)
+if(NOT actual_count EQUAL expected_count)
+ message(STATUS "actual_count='${actual_count}'")
+ message(FATAL_ERROR "error: expected_count=${expected_count} does not match actual_count=${actual_count}: CPackComponents test fails. (CPack_output=${CPack_output}, CPack_error=${CPack_error})")
+endif()
+
+
+# lintian checks
+find_program(LINTIAN_EXECUTABLE lintian)
+if(LINTIAN_EXECUTABLE)
+ set(lintian_output_errors_all "")
+ foreach(_f IN LISTS actual_output)
+ set(STRINGS_TO_AVOID "E:([^\r\n]*)control-file-has-bad-permissions" "E:([^\r\n]*)md5sums-lists-nonexistent-file")
+ lintian_check_specific_errors(lintian_output_errors
+ FILENAME "${_f}"
+ ERROR_REGEX_STRINGS "${STRINGS_TO_AVOID}")
+
+ set(lintian_output_errors_all "${lintian_output_errors_all}${lintian_output_errors}")
+ endforeach()
+
+ if(NOT "${lintian_output_errors_all}" STREQUAL "")
+ message(FATAL_ERROR "Lintian checks failed:\n${lintian_output_errors_all}")
+ endif()
+else()
+ message("lintian executable not found - skipping lintian test")
+endif()
+
+# dpkg-deb checks
+find_program(DPKGDEB_EXECUTABLE dpkg-deb)
+if(DPKGDEB_EXECUTABLE)
+ set(dpkgdeb_output_errors_all "")
+ foreach(_f IN LISTS actual_output)
+ run_dpkgdeb(dpkg_output
+ FILENAME "${_f}"
+ )
+
+ dpkgdeb_return_specific_metaentry(dpkgentry
+ DPKGDEB_OUTPUT "${dpkg_output}"
+ METAENTRY "Maintainer:")
+
+ if(NOT "${dpkgentry}" STREQUAL "None")
+ set(dpkgdeb_output_errors_all "${dpkgdeb_output_errors_all}"
+ "dpkg-deb: ${_f}: Incorrect value for Maintainer: ${dpkgentry} != None\n")
+ endif()
+ endforeach()
+
+ if(NOT "${dpkgdeb_output_errors_all}" STREQUAL "")
+ message(FATAL_ERROR "dpkg-deb checks failed:\n${dpkgdeb_output_errors_all}")
+ endif()
+else()
+ message("dpkg-deb executable not found - skipping dpkg-deb test")
+endif()
diff --git a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-shlibdeps1.cmake b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-shlibdeps1.cmake
new file mode 100644
index 000000000..79d8f0de2
--- /dev/null
+++ b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-shlibdeps1.cmake
@@ -0,0 +1,75 @@
+if(NOT CPackComponentsDEB_SOURCE_DIR)
+ message(FATAL_ERROR "CPackComponentsDEB_SOURCE_DIR not set")
+endif()
+
+include(${CPackComponentsDEB_SOURCE_DIR}/RunCPackVerifyResult.cmake)
+
+
+
+# requirements
+
+# debian now produces lower case names
+set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/MyLib-*.deb")
+set(expected_count 3)
+
+
+set(actual_output)
+run_cpack(actual_output
+ CPack_output
+ CPack_error
+ EXPECTED_FILE_MASK "${expected_file_mask}"
+ CONFIG_ARGS ${config_args}
+ CONFIG_VERBOSE ${config_verbose})
+
+message(STATUS "expected_count='${expected_count}'")
+message(STATUS "expected_file_mask='${expected_file_mask}'")
+message(STATUS "actual_output_files='${actual_output}'")
+
+if(NOT actual_output)
+ message(FATAL_ERROR "error: expected_files do not exist: CPackComponentsDEB test fails. (CPack_output=${CPack_output}, CPack_error=${CPack_error}")
+endif()
+
+list(LENGTH actual_output actual_count)
+message(STATUS "actual_count='${actual_count}'")
+if(NOT actual_count EQUAL expected_count)
+ message(FATAL_ERROR "error: expected_count=${expected_count} does not match actual_count=${actual_count}: CPackComponents test fails. (CPack_output=${CPack_output}, CPack_error=${CPack_error})")
+endif()
+
+
+# dpkg-deb checks for the summary of the packages
+find_program(DPKGDEB_EXECUTABLE dpkg-deb)
+if(DPKGDEB_EXECUTABLE)
+ set(dpkgdeb_output_errors_all)
+ foreach(_f IN LISTS actual_output)
+
+ # extracts the metadata from the package
+ run_dpkgdeb(dpkg_output
+ FILENAME ${_f}
+ )
+
+ dpkgdeb_return_specific_metaentry(dpkg_package_name
+ DPKGDEB_OUTPUT "${dpkg_output}"
+ METAENTRY "Package:")
+
+ message(STATUS "package='${dpkg_package_name}'")
+
+ if("${dpkg_package_name}" STREQUAL "mylib-applications")
+ # pass
+ elseif("${dpkg_package_name}" STREQUAL "mylib-headers")
+ # pass
+ elseif("${dpkg_package_name}" STREQUAL "mylib-libraries")
+ # pass
+ else()
+ set(dpkgdeb_output_errors_all ${dpkgdeb_output_errors_all}
+ "dpkg-deb: ${_f}: component name not found: ${dpkg_package_name}\n")
+ endif()
+
+ endforeach()
+
+
+ if(NOT "${dpkgdeb_output_errors_all}" STREQUAL "")
+ message(FATAL_ERROR "dpkg-deb checks failed:\n${dpkgdeb_output_errors_all}")
+ endif()
+else()
+ message("dpkg-deb executable not found - skipping dpkg-deb test")
+endif()
diff --git a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-source.cmake b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-source.cmake
new file mode 100644
index 000000000..51fa3ad81
--- /dev/null
+++ b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-source.cmake
@@ -0,0 +1,75 @@
+if(NOT CPackComponentsDEB_SOURCE_DIR)
+ message(FATAL_ERROR "CPackComponentsDEB_SOURCE_DIR not set")
+endif()
+
+include(${CPackComponentsDEB_SOURCE_DIR}/RunCPackVerifyResult.cmake)
+
+
+# expected results
+set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/MyLib-*.deb")
+set(expected_count 3)
+
+set(config_verbose -V)
+set(actual_output)
+run_cpack(actual_output
+ CPack_output
+ CPack_error
+ EXPECTED_FILE_MASK "${expected_file_mask}"
+ CONFIG_ARGS ${config_args}
+ CONFIG_VERBOSE ${config_verbose})
+
+
+if(NOT actual_output)
+ message(STATUS "expected_count='${expected_count}'")
+ message(STATUS "expected_file_mask='${expected_file_mask}'")
+ message(STATUS "actual_output_files='${actual_output}'")
+ message(FATAL_ERROR "error: expected_files do not exist: CPackComponentsDEB test fails. (CPack_output=${CPack_output}, CPack_error=${CPack_error}")
+endif()
+
+list(LENGTH actual_output actual_count)
+if(NOT actual_count EQUAL expected_count)
+ message(STATUS "actual_count='${actual_count}'")
+ message(FATAL_ERROR "error: expected_count=${expected_count} does not match actual_count=${actual_count}: CPackComponents test fails. (CPack_output=${CPack_output}, CPack_error=${CPack_error})")
+endif()
+
+
+# dpkg-deb checks for the summary of the packages
+find_program(DPKGDEB_EXECUTABLE dpkg-deb)
+if(DPKGDEB_EXECUTABLE)
+ set(dpkgdeb_output_errors_all "")
+ foreach(_f IN LISTS actual_output)
+
+ # extracts the metadata from the package
+ run_dpkgdeb(dpkg_output
+ FILENAME "${_f}"
+ )
+
+ dpkgdeb_return_specific_metaentry(dpkg_package_name
+ DPKGDEB_OUTPUT "${dpkg_output}"
+ METAENTRY "Package:")
+
+ dpkgdeb_return_specific_metaentry(dpkg_package_source
+ DPKGDEB_OUTPUT "${dpkg_output}"
+ METAENTRY "Source:")
+
+ message(STATUS "package='${_f}', source='${dpkg_package_source}'")
+
+ if(NOT ("${dpkg_package_name}" STREQUAL "mylib-applications"))
+ if(NOT ("${dpkg_package_source}" STREQUAL "test-source"))
+ set(dpkgdeb_output_errors_all "${dpkgdeb_output_errors_all}"
+ "dpkg-deb: ${_f}: Incorrect source for package '${dpkg_package_name}': '${dpkg_package_source}' instead of 'test-source'\n")
+ endif()
+ else()
+ if(NOT ("${dpkg_package_source}" STREQUAL "test-other-source"))
+ set(dpkgdeb_output_errors_all "${dpkgdeb_output_errors_all}"
+ "dpkg-deb: ${_f}: Incorrect source for package '${dpkg_package_name}': '${dpkg_package_source}' instead of 'test-other-source'\n")
+ endif()
+ endif()
+ endforeach()
+
+ if(NOT "${dpkgdeb_output_errors_all}" STREQUAL "")
+ message(FATAL_ERROR "dpkg-deb checks failed:\n${dpkgdeb_output_errors_all}")
+ endif()
+else()
+ message("dpkg-deb executable not found - skipping dpkg-deb test")
+endif()
diff --git a/Tests/CPackComponentsDEB/RunCPackVerifyResult-compression.cmake b/Tests/CPackComponentsDEB/RunCPackVerifyResult-compression.cmake
new file mode 100644
index 000000000..2175adae9
--- /dev/null
+++ b/Tests/CPackComponentsDEB/RunCPackVerifyResult-compression.cmake
@@ -0,0 +1,54 @@
+if(NOT CPackComponentsDEB_SOURCE_DIR)
+ message(FATAL_ERROR "CPackComponentsDEB_SOURCE_DIR not set")
+endif()
+
+include(${CPackComponentsDEB_SOURCE_DIR}/RunCPackVerifyResult.cmake)
+
+# TODO: currently debian doens't produce lower cased names
+set(expected_file_mask "${CPackComponentsDEB_BINARY_DIR}/MyLib-*.deb")
+set(expected_count 1)
+
+set(actual_output)
+run_cpack(actual_output
+ CPack_output
+ CPack_error
+ EXPECTED_FILE_MASK "${expected_file_mask}"
+ CONFIG_ARGS "${config_args}"
+ CONFIG_VERBOSE "${config_verbose}")
+
+if(NOT actual_output)
+ message(STATUS "expected_count='${expected_count}'")
+ message(STATUS "expected_file_mask='${expected_file_mask}'")
+ message(STATUS "actual_output_files='${actual_output}'")
+ message(FATAL_ERROR "error: expected_files do not exist: CPackComponentsDEB test fails. (CPack_output=${CPack_output}, CPack_error=${CPack_error}")
+endif()
+
+list(LENGTH actual_output actual_count)
+if(NOT actual_count EQUAL expected_count)
+ message(STATUS "actual_count='${actual_count}'")
+ message(FATAL_ERROR "error: expected_count=${expected_count} does not match actual_count=${actual_count}: CPackComponents test fails. (CPack_output=${CPack_output}, CPack_error=${CPack_error})")
+endif()
+
+
+# dpkg-deb checks
+find_program(DPKGDEB_EXECUTABLE dpkg-deb)
+if(DPKGDEB_EXECUTABLE)
+ set(dpkgdeb_output_errors_all "")
+ foreach(_f IN LISTS actual_output)
+ run_dpkgdeb(dpkg_output
+ FILENAME "${_f}"
+ )
+
+ # message(FATAL_ERROR "output = '${dpkg_output}'")
+ if("${dpkg_output}" STREQUAL "")
+ set(dpkgdeb_output_errors_all "${dpkgdeb_output_errors_all}"
+ "dpkg-deb: ${_f}: empty content returned by dpkg-deb")
+ endif()
+ endforeach()
+
+ if(NOT "${dpkgdeb_output_errors_all}" STREQUAL "")
+ message(FATAL_ERROR "dpkg-deb checks failed:\n${dpkgdeb_output_errors_all}")
+ endif()
+else()
+ message("dpkg-deb executable not found - skipping dpkg-deb test")
+endif()
diff --git a/Tests/CPackComponentsDEB/RunCPackVerifyResult.cmake b/Tests/CPackComponentsDEB/RunCPackVerifyResult.cmake
new file mode 100644
index 000000000..b4e567c9e
--- /dev/null
+++ b/Tests/CPackComponentsDEB/RunCPackVerifyResult.cmake
@@ -0,0 +1,203 @@
+# prevent older policies from interfearing with this script
+cmake_policy(PUSH)
+cmake_policy(VERSION ${CMAKE_VERSION})
+
+
+include(CMakeParseArguments)
+
+message(STATUS "=============================================================================")
+message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)")
+message(STATUS "")
+
+if(NOT CPackComponentsDEB_BINARY_DIR)
+ message(FATAL_ERROR "CPackComponentsDEB_BINARY_DIR not set")
+endif()
+
+if(NOT CPackGen)
+ message(FATAL_ERROR "CPackGen not set")
+endif()
+
+message("CMAKE_CPACK_COMMAND = ${CMAKE_CPACK_COMMAND}")
+if(NOT CMAKE_CPACK_COMMAND)
+ message(FATAL_ERROR "CMAKE_CPACK_COMMAND not set")
+endif()
+
+if(NOT CPackDEBConfiguration)
+ message(FATAL_ERROR "CPackDEBConfiguration not set")
+endif()
+
+# run cpack with some options and returns the list of files generated
+# -output_expected_file: list of files that match the pattern
+function(run_cpack output_expected_file CPack_output_parent CPack_error_parent)
+ set(options )
+ set(oneValueArgs "EXPECTED_FILE_MASK" "CONFIG_VERBOSE")
+ set(multiValueArgs "CONFIG_ARGS")
+ cmake_parse_arguments(run_cpack_deb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
+
+
+ # clean-up previously CPack generated files
+ if(${run_cpack_deb_EXPECTED_FILE_MASK})
+ file(GLOB expected_file "${${run_cpack_deb_EXPECTED_FILE_MASK}}")
+ if (expected_file)
+ file(REMOVE "${expected_file}")
+ endif()
+ endif()
+
+ message("config_args = ${run_cpack_deb_CONFIG_ARGS}")
+ message("config_verbose = ${run_cpack_deb_CONFIG_VERBOSE}")
+ execute_process(COMMAND ${CMAKE_CPACK_COMMAND} ${run_cpack_deb_CONFIG_VERBOSE} -G ${CPackGen} ${run_cpack_deb_CONFIG_ARGS}
+ RESULT_VARIABLE CPack_result
+ OUTPUT_VARIABLE CPack_output
+ ERROR_VARIABLE CPack_error
+ WORKING_DIRECTORY ${CPackComponentsDEB_BINARY_DIR})
+
+ set(${CPack_output_parent} ${CPack_output} PARENT_SCOPE)
+ set(${CPack_error_parent} ${CPack_error} PARENT_SCOPE)
+
+ if (CPack_result)
+ message(FATAL_ERROR "error: CPack execution went wrong!, CPack_output=${CPack_output}, CPack_error=${CPack_error}")
+ else ()
+ message(STATUS "CPack_output=${CPack_output}")
+ message(STATUS "CPack_error=${CPack_error}")
+ endif()
+
+
+ if(run_cpack_deb_EXPECTED_FILE_MASK)
+ file(GLOB _output_expected_file "${run_cpack_deb_EXPECTED_FILE_MASK}")
+ set(${output_expected_file} "${_output_expected_file}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+
+
+# This function runs lintian on a .deb and returns its output
+function(run_lintian lintian_output)
+ set(${lintian_output} "" PARENT_SCOPE)
+
+ find_program(LINTIAN_EXECUTABLE lintian)
+ if(LINTIAN_EXECUTABLE)
+ set(options "")
+ set(oneValueArgs "FILENAME")
+ set(multiValueArgs "")
+ cmake_parse_arguments(run_lintian_deb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
+
+
+ if(NOT run_lintian_deb_FILENAME)
+ message(FATAL_ERROR "error: run_lintian needs FILENAME to be set")
+ endif()
+
+ # run dpkg-deb
+ execute_process(COMMAND ${LINTIAN_EXECUTABLE} ${run_lintian_deb_FILENAME}
+ WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}"
+ OUTPUT_VARIABLE LINTIAN_OUTPUT
+ RESULT_VARIABLE LINTIAN_RESULT
+ ERROR_VARIABLE LINTIAN_ERROR
+ OUTPUT_STRIP_TRAILING_WHITESPACE )
+
+ set(${lintian_output} "${LINTIAN_OUTPUT}" PARENT_SCOPE)
+ else()
+ message(FATAL_ERROR "run_lintian called without lintian executable being present")
+ endif()
+endfunction()
+
+
+# Higher level lintian check that parse the output for errors and required strings
+function(lintian_check_specific_errors output_errors)
+ set(${output_errors} "" PARENT_SCOPE)
+ set(ERROR_ACC)
+
+ set(options "")
+ set(oneValueArgs "FILENAME")
+ set(multiValueArgs "ERROR_REGEX_STRINGS")
+ cmake_parse_arguments(lintian_check_specific_errors_deb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
+
+ set(lintian_output)
+ run_lintian(lintian_output FILENAME ${lintian_check_specific_errors_deb_FILENAME})
+
+ message(STATUS "Lintian output is ''${lintian_output}'")
+
+ # regex to avoid
+ foreach(_s IN LISTS lintian_check_specific_errors_deb_ERROR_REGEX_STRINGS)
+
+ if("${_s}" STREQUAL "")
+ continue()
+ endif()
+
+ string(REGEX MATCHALL "${_s}" "_TMP_CHECK_ERROR" "${lintian_output}")
+
+ if(NOT "${_TMP_CHECK_ERROR}" STREQUAL "")
+ set(ERROR_ACC "${ERROR_ACC}\nlintian: ${_f}: output contains an undesirable regex:\n\t${_TMP_CHECK_ERROR}")
+ endif()
+ endforeach()
+
+ set(${output_errors} "${ERROR_ACC}" PARENT_SCOPE)
+endfunction()
+
+
+
+
+# This function runs dpkg-deb on a .deb and returns its output
+# the default behaviour it to run "--info" on the specified Debian package
+# ACTION is one of the option accepted by dpkg-deb
+function(run_dpkgdeb dpkg_deb_output)
+ set(${dpkg_deb_output} "" PARENT_SCOPE)
+
+ find_program(DPKGDEB_EXECUTABLE dpkg-deb)
+ if(DPKGDEB_EXECUTABLE)
+
+ set(options "")
+ set(oneValueArgs "FILENAME" "ACTION")
+ set(multiValueArgs "")
+ cmake_parse_arguments(run_dpkgdeb_deb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
+
+
+ if(NOT run_dpkgdeb_deb_FILENAME)
+ message(FATAL_ERROR "error: run_dpkgdeb needs FILENAME to be set")
+ endif()
+
+ if(NOT run_dpkgdeb_deb_ACTION)
+ set(run_dpkgdeb_deb_ACTION "--info")
+ endif()
+
+ # run dpkg-deb
+ execute_process(COMMAND ${DPKGDEB_EXECUTABLE} ${run_dpkgdeb_deb_ACTION} ${run_dpkgdeb_deb_FILENAME}
+ WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}"
+ OUTPUT_VARIABLE DPKGDEB_OUTPUT
+ RESULT_VARIABLE DPKGDEB_RESULT
+ ERROR_VARIABLE DPKGDEB_ERROR
+ OUTPUT_STRIP_TRAILING_WHITESPACE )
+
+ if(NOT ("${DPKGDEB_RESULT}" EQUAL "0"))
+ message(FATAL_ERROR "Error '${DPKGDEB_RESULT}' returned by dpkg-deb: '${DPKGDEB_ERROR}'")
+ endif()
+
+ set(${dpkg_deb_output} "${DPKGDEB_OUTPUT}" PARENT_SCOPE)
+ else()
+ message(FATAL_ERROR "run_dpkgdeb called without dpkg-deb executable being present")
+ endif()
+endfunction()
+
+
+# returns a particular line of the metadata of the .deb, for checking
+# a previous call to run_dpkgdeb should provide the DPKGDEB_OUTPUT entry.
+function(dpkgdeb_return_specific_metaentry output)
+ set(${output} "" PARENT_SCOPE)
+
+ set(options "")
+ set(oneValueArgs "DPKGDEB_OUTPUT" "METAENTRY")
+ set(multiValueArgs "")
+ cmake_parse_arguments(dpkgdeb_return_specific_metaentry_deb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
+
+ if(NOT dpkgdeb_return_specific_metaentry_deb_METAENTRY)
+ message(FATAL_ERROR "error: dpkgdeb_return_specific_metaentry needs METAENTRY to be set")
+ endif()
+
+ string(REGEX MATCH "${dpkgdeb_return_specific_metaentry_deb_METAENTRY}([^\r\n]*)" _TMP_STR "${dpkgdeb_return_specific_metaentry_deb_DPKGDEB_OUTPUT}")
+ #message("################ _TMP_STR = ${CMAKE_MATCH_1} ##################")
+ if(NOT "${CMAKE_MATCH_1}" STREQUAL "")
+ string(STRIP "${CMAKE_MATCH_1}" _TMP_STR)
+ set(${output} "${_TMP_STR}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+cmake_policy(POP)
diff --git a/Tests/CPackComponentsDEB/license.txt b/Tests/CPackComponentsDEB/license.txt
new file mode 100644
index 000000000..d829d93a2
--- /dev/null
+++ b/Tests/CPackComponentsDEB/license.txt
@@ -0,0 +1,3 @@
+LICENSE
+-------
+This is an installer created using CPack (https://cmake.org). No license provided.
diff --git a/Tests/CPackComponentsDEB/mylib.cpp b/Tests/CPackComponentsDEB/mylib.cpp
new file mode 100644
index 000000000..8ddac198c
--- /dev/null
+++ b/Tests/CPackComponentsDEB/mylib.cpp
@@ -0,0 +1,7 @@
+#include "mylib.h"
+#include "stdio.h"
+
+void mylib_function()
+{
+ printf("This is mylib");
+}
diff --git a/Tests/CPackComponentsDEB/mylib.h b/Tests/CPackComponentsDEB/mylib.h
new file mode 100644
index 000000000..5d0a822db
--- /dev/null
+++ b/Tests/CPackComponentsDEB/mylib.h
@@ -0,0 +1 @@
+void mylib_function();
diff --git a/Tests/CPackComponentsDEB/mylibapp.cpp b/Tests/CPackComponentsDEB/mylibapp.cpp
new file mode 100644
index 000000000..a438ac77f
--- /dev/null
+++ b/Tests/CPackComponentsDEB/mylibapp.cpp
@@ -0,0 +1,6 @@
+#include "mylib.h"
+
+int main()
+{
+ mylib_function();
+}
diff --git a/Tests/CPackComponentsForAll/CMakeLists.txt b/Tests/CPackComponentsForAll/CMakeLists.txt
index 8162f0c2a..823f6db4d 100644
--- a/Tests/CPackComponentsForAll/CMakeLists.txt
+++ b/Tests/CPackComponentsForAll/CMakeLists.txt
@@ -43,12 +43,57 @@ install(TARGETS mylibapp
# CPACK_MONOLITHIC_INSTALL=1 is set (at cmake time).
install(TARGETS mylibapp2
RUNTIME
- DESTINATION bin)
+ DESTINATION bin/@in@_@path@@with\\@and\\@/\@in_path\@) # test @ char in path
install(FILES mylib.h
DESTINATION include
COMPONENT headers)
+if("${CPACK_GENERATOR}" MATCHES "RPM")
+ ############## test man pages
+ install(FILES mylib
+ DESTINATION share/man/mylib/man3/mylib.1)
+ install(FILES mylib
+ DESTINATION share/man/mylib/man3/mylib.1 RENAME mylib2)
+
+ ############## test symlinks
+ # Package symbolic links
+ install(DIRECTORY DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/depth_two/depth_three COMPONENT libraries)
+ install(DIRECTORY DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_two/depth_two/different_relocatable/bar COMPONENT libraries)
+ install(DIRECTORY DESTINATION other_relocatable/depth_two COMPONENT libraries)
+ install(DIRECTORY DESTINATION non_relocatable/depth_two COMPONENT libraries)
+ # test symbolic links to same dir
+ execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink depth_three symlink_samedir_path)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_samedir_path DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/depth_two COMPONENT libraries)
+ # test symbolic links to same dir with current dir ./ prefix
+ execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ./depth_three symlink_samedir_path_current_dir)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_samedir_path_current_dir DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/depth_two COMPONENT libraries)
+ # test symbolic links to same dir with longer relative path
+ execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ../../../${CMAKE_INSTALL_LIBDIR}/.././${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/./depth_two/depth_three symlink_samedir_path_longer)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_samedir_path_longer DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/depth_two COMPONENT libraries)
+ # test symbolic links to sub dir
+ execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ../../${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/depth_two/depth_three symlink_subdir_path)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_subdir_path DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one COMPONENT libraries)
+ # test symbolic links to parent dir
+ execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink .././../../../${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/./depth_two symlink_parentdir_path)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_parentdir_path DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/depth_two/depth_three COMPONENT libraries)
+ # test symbolic link to another relocatable path
+ execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink .././.././../other_relocatable/./depth_two symlink_other_relocatable_path)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_other_relocatable_path DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_two/depth_two COMPONENT libraries)
+ # test symbolic link to non relocatable path
+ execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink .././../../non_relocatable/./depth_two symlink_to_non_relocatable_path)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_to_non_relocatable_path DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_two/depth_two COMPONENT libraries)
+ # test symbolic link from non relocatable path
+ execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink .././../${CMAKE_INSTALL_LIBDIR}/inside_relocatable_two/depth_two symlink_from_non_relocatable_path)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_from_non_relocatable_path DESTINATION non_relocatable/depth_two COMPONENT libraries)
+ # test symbolic link relocatable path to its relocatable subpath
+ execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ../../inside_relocatable_two/depth_two/different_relocatable/bar symlink_relocatable_subpath)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_relocatable_subpath DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/depth_two COMPONENT libraries)
+ # test symbolic link to location outside package
+ execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ./outside_package symlink_outside_package)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_outside_package DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/depth_two COMPONENT libraries)
+endif()
+
# CPack boilerplate for this project
set(CPACK_PACKAGE_NAME "MyLib")
set(CPACK_PACKAGE_CONTACT "None")
@@ -59,6 +104,7 @@ set(CPACK_PACKAGE_VERSION_MAJOR "1")
set(CPACK_PACKAGE_VERSION_MINOR "0")
set(CPACK_PACKAGE_VERSION_PATCH "2")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "CPack Component Example")
+set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/license.txt)
# Tell CPack all of the components to install. The "ALL"
# refers to the fact that this is the set of components that
@@ -109,6 +155,13 @@ set(CPACK_COMPONENT_LIBRARIES_INSTALL_TYPES Developer Full)
set(CPACK_COMPONENT_HEADERS_INSTALL_TYPES Developer Full)
set(CPACK_COMPONENT_APPLICATIONS_INSTALL_TYPES Full)
+# set CPACK_RPM_RELOCATION_PATHS here as GNUInstallDirs script
+# can not be used in CPack scripts due to CMAKE_SIZEOF_VOID_P
+# variable not being set
+set(CPACK_RPM_RELOCATION_PATHS "${CMAKE_INSTALL_INCLUDEDIR}"
+ "${CMAKE_INSTALL_LIBDIR}" "${CMAKE_INSTALL_BINDIR}" "other_relocatable"
+ "${CMAKE_INSTALL_LIBDIR}/inside_relocatable_two/depth_two/different_relocatable")
+
# We may use the CPack specific config file in order
# to tailor CPack behavior on a CPack generator specific way
# (Behavior would be different for RPM or TGZ or DEB ...)
@@ -120,4 +173,4 @@ if (NOT ("${CPackComponentWay}" STREQUAL "default"))
set(CPACK_PROJECT_CONFIG_FILE ${CPackComponentsForAll_BINARY_DIR}/MyLibCPackConfig-${CPackComponentWay}.cmake)
endif ()
# Include CPack to introduce the appropriate targets
-include(CPack) \ No newline at end of file
+include(CPack)
diff --git a/Tests/CPackComponentsForAll/MyLibCPackConfig-IgnoreGroup.cmake.in b/Tests/CPackComponentsForAll/MyLibCPackConfig-IgnoreGroup.cmake.in
index 450c2047e..ac9b55222 100644
--- a/Tests/CPackComponentsForAll/MyLibCPackConfig-IgnoreGroup.cmake.in
+++ b/Tests/CPackComponentsForAll/MyLibCPackConfig-IgnoreGroup.cmake.in
@@ -6,8 +6,32 @@ if(CPACK_GENERATOR MATCHES "ZIP")
endif()
if(CPACK_GENERATOR MATCHES "RPM")
- set(CPACK_RPM_COMPONENT_INSTALL "ON")
- set(CPACK_RPM_applications_PACKAGE_REQUIRES "mylib-libraries")
+ set(CPACK_RPM_COMPONENT_INSTALL "ON")
+
+ # test that /usr and /usr/foo get omitted in relocatable
+ # rpms as shortest relocation path is treated as base of
+ # package (/usr/foo/bar is relocatable and must exist)
+ set(CPACK_PACKAGING_INSTALL_PREFIX "/usr/foo/bar")
+
+ # test requires
+ set(CPACK_RPM_applications_PACKAGE_REQUIRES "mylib-libraries")
+
+ # test a "noarch" rpm
+ set(CPACK_RPM_headers_PACKAGE_ARCHITECTURE "noarch")
+
+ # test cross-built rpm
+ set(CPACK_RPM_applications_PACKAGE_ARCHITECTURE "armv7hf")
+
+ # test package summary override - headers rpm is generated in the middle
+ set(CPACK_RPM_PACKAGE_SUMMARY "default summary")
+ set(CPACK_RPM_headers_PACKAGE_SUMMARY "headers summary")
+
+ # test package description override - headers rpm is generated in the middle
+ set(CPACK_RPM_headers_PACKAGE_DESCRIPTION "headers description")
+
+ # test package do not use CPACK_PACKAGING_INSTALL_PREFIX
+ # as relocation path
+ set(CPACK_RPM_NO_libraries_INSTALL_PREFIX_RELOCATION true)
endif()
if(CPACK_GENERATOR MATCHES "DEB")
@@ -20,4 +44,4 @@ endif()
#set(CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE)
#set(CPACK_COMPONENTS_GROUPING)
set(CPACK_COMPONENTS_IGNORE_GROUPS 1)
-#set(CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE 1) \ No newline at end of file
+#set(CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE 1)
diff --git a/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake b/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake
index 0b6d07d97..d94a477be 100644
--- a/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake
+++ b/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake
@@ -1,3 +1,7 @@
+# prevent older policies from interfearing with this script
+cmake_policy(PUSH)
+cmake_policy(VERSION ${CMAKE_VERSION})
+
message(STATUS "=============================================================================")
message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)")
message(STATUS "")
@@ -123,3 +127,237 @@ if(expected_file_mask)
message(FATAL_ERROR "error: expected_count=${expected_count} does not match actual_count=${actual_count}: CPackComponents test fails. (CPack_output=${CPack_output}, CPack_error=${CPack_error})")
endif()
endif()
+
+# Validate content
+if(CPackGen MATCHES "RPM")
+ find_program(RPM_EXECUTABLE rpm)
+ if(NOT RPM_EXECUTABLE)
+ message(FATAL_ERROR "error: missing rpm executable required by the test")
+ endif()
+
+ set(CPACK_RPM_PACKAGE_SUMMARY "default summary")
+ set(CPACK_RPM_headers_PACKAGE_SUMMARY "headers summary")
+ set(CPACK_RPM_headers_PACKAGE_DESCRIPTION "headers description")
+ set(CPACK_COMPONENT_APPLICATIONS_DESCRIPTION
+ "An extremely useful application that makes use of MyLib")
+ set(CPACK_COMPONENT_LIBRARIES_DESCRIPTION
+ "Static libraries used to build programs with MyLib")
+ set(LIB_SUFFIX "6?4?")
+
+ # test package info
+ if(${CPackComponentWay} STREQUAL "IgnoreGroup")
+ # set gnu install prefixes to what they are set during rpm creation
+ # CMAKE_SIZEOF_VOID_P is not set here but lib is prefix of lib64 so
+ # relocation path test won't fail on OSes with lib64 library location
+ include(GNUInstallDirs)
+ set(CPACK_PACKAGING_INSTALL_PREFIX "/usr/foo/bar")
+
+ foreach(check_file ${expected_file})
+ string(REGEX MATCH ".*libraries.*" check_file_libraries_match ${check_file})
+ string(REGEX MATCH ".*headers.*" check_file_headers_match ${check_file})
+ string(REGEX MATCH ".*applications.*" check_file_applications_match ${check_file})
+ string(REGEX MATCH ".*Unspecified.*" check_file_Unspecified_match ${check_file})
+
+ execute_process(COMMAND ${RPM_EXECUTABLE} -pqi ${check_file}
+ OUTPUT_VARIABLE check_file_content
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ execute_process(COMMAND ${RPM_EXECUTABLE} -pqa ${check_file}
+ RESULT_VARIABLE check_package_architecture_result
+ OUTPUT_VARIABLE check_package_architecture
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ execute_process(COMMAND ${RPM_EXECUTABLE} -pql ${check_file}
+ OUTPUT_VARIABLE check_package_content
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ set(whitespaces "[\\t\\n\\r ]*")
+
+ if(check_file_libraries_match)
+ set(check_file_match_expected_summary ".*${CPACK_RPM_PACKAGE_SUMMARY}.*")
+ set(check_file_match_expected_description ".*${CPACK_COMPONENT_LIBRARIES_DESCRIPTION}.*")
+ set(check_file_match_expected_relocation_path "Relocations${whitespaces}:${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}${LIB_SUFFIX}${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/other_relocatable${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}${LIB_SUFFIX}/inside_relocatable_two/depth_two/different_relocatable")
+ set(check_file_match_expected_architecture "") # we don't explicitly set this value so it is different on each platform - ignore it
+ set(spec_regex "*libraries*")
+ set(check_content_list "^/usr/foo/bar/lib${LIB_SUFFIX}
+/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one
+/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two
+/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/depth_three
+/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/depth_three/symlink_parentdir_path
+/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/symlink_outside_package
+/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/symlink_relocatable_subpath
+/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/symlink_samedir_path
+/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/symlink_samedir_path_current_dir
+/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/symlink_samedir_path_longer
+/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/symlink_subdir_path
+/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_two
+/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_two/depth_two
+/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_two/depth_two/different_relocatable
+/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_two/depth_two/different_relocatable/bar
+/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_two/depth_two/symlink_other_relocatable_path
+/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_two/depth_two/symlink_to_non_relocatable_path
+/usr/foo/bar/lib${LIB_SUFFIX}/libmylib.a
+/usr/foo/bar/non_relocatable
+/usr/foo/bar/non_relocatable/depth_two
+/usr/foo/bar/non_relocatable/depth_two/symlink_from_non_relocatable_path
+/usr/foo/bar/other_relocatable
+/usr/foo/bar/other_relocatable/depth_two$")
+ elseif(check_file_headers_match)
+ set(check_file_match_expected_summary ".*${CPACK_RPM_headers_PACKAGE_SUMMARY}.*")
+ set(check_file_match_expected_description ".*${CPACK_RPM_headers_PACKAGE_DESCRIPTION}.*")
+ set(check_file_match_expected_relocation_path "Relocations${whitespaces}:${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}")
+ set(check_file_match_expected_architecture "noarch")
+ set(spec_regex "*headers*")
+ set(check_content_list "^/usr/foo/bar\n/usr/foo/bar/include\n/usr/foo/bar/include/mylib.h$")
+ elseif(check_file_applications_match)
+ set(check_file_match_expected_summary ".*${CPACK_RPM_PACKAGE_SUMMARY}.*")
+ set(check_file_match_expected_description ".*${CPACK_COMPONENT_APPLICATIONS_DESCRIPTION}.*")
+ set(check_file_match_expected_relocation_path "Relocations${whitespaces}:${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}")
+ set(check_file_match_expected_architecture "armv7hf")
+ set(spec_regex "*applications*")
+ set(check_content_list "^/usr/foo/bar
+/usr/foo/bar/bin
+/usr/foo/bar/bin/mylibapp$")
+ elseif(check_file_Unspecified_match)
+ set(check_file_match_expected_summary ".*${CPACK_RPM_PACKAGE_SUMMARY}.*")
+ set(check_file_match_expected_description ".*DESCRIPTION.*")
+ set(check_file_match_expected_relocation_path "Relocations${whitespaces}:${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}")
+ set(check_file_match_expected_architecture "") # we don't explicitly set this value so it is different on each platform - ignore it
+ set(spec_regex "*Unspecified*")
+ set(check_content_list "^/usr/foo/bar
+/usr/foo/bar/bin
+/usr/foo/bar/bin/@in@_@path@@with
+/usr/foo/bar/bin/@in@_@path@@with/@and
+/usr/foo/bar/bin/@in@_@path@@with/@and/@
+/usr/foo/bar/bin/@in@_@path@@with/@and/@/@in_path@
+/usr/foo/bar/bin/@in@_@path@@with/@and/@/@in_path@/mylibapp2
+/usr/foo/bar/share
+/usr/foo/bar/share/man
+/usr/foo/bar/share/man/mylib
+/usr/foo/bar/share/man/mylib/man3
+/usr/foo/bar/share/man/mylib/man3/mylib.1
+/usr/foo/bar/share/man/mylib/man3/mylib.1/mylib
+/usr/foo/bar/share/man/mylib/man3/mylib.1/mylib2$")
+ else()
+ message(FATAL_ERROR "error: unexpected rpm package '${check_file}'")
+ endif()
+
+ #######################
+ # test package info
+ #######################
+ string(REGEX MATCH ${check_file_match_expected_summary} check_file_match_summary ${check_file_content})
+
+ if(NOT check_file_match_summary)
+ message(FATAL_ERROR "error: '${check_file}' rpm package summary does not match expected value - regex '${check_file_match_expected_summary}'; RPM output: '${check_file_content}'")
+ endif()
+
+ string(REGEX MATCH ${check_file_match_expected_description} check_file_match_description ${check_file_content})
+
+ if(NOT check_file_match_description)
+ message(FATAL_ERROR "error: '${check_file}' rpm package description does not match expected value - regex '${check_file_match_expected_description}'; RPM output: '${check_file_content}'")
+ endif()
+
+ string(REGEX MATCH ${check_file_match_expected_relocation_path} check_file_match_relocation_path ${check_file_content})
+
+ if(NOT check_file_match_relocation_path)
+ file(GLOB_RECURSE spec_file "${CPackComponentsForAll_BINARY_DIR}/${spec_regex}.spec")
+
+ if(spec_file)
+ file(READ ${spec_file} spec_file_content)
+ endif()
+
+ message(FATAL_ERROR "error: '${check_file}' rpm package relocation path does not match expected value - regex '${check_file_match_expected_relocation_path}'; RPM output: '${check_file_content}'; generated spec file: '${spec_file_content}'")
+ endif()
+
+ #######################
+ # test package architecture
+ #######################
+ string(REGEX MATCH "Architecture${whitespaces}:" check_info_contains_arch ${check_file_content})
+ if(check_info_contains_arch) # test for rpm versions that contain architecture in package info (e.g. 4.11.x)
+ string(REGEX MATCH "Architecture${whitespaces}:${whitespaces}${check_file_match_expected_architecture}" check_file_match_architecture ${check_file_content})
+ if(NOT check_file_match_architecture)
+ message(FATAL_ERROR "error: '${check_file}' Architecture does not match expected value - '${check_file_match_expected_architecture}'; RPM output: '${check_file_content}'; generated spec file: '${spec_file_content}'")
+ endif()
+ elseif(NOT check_package_architecture_result) # test result only on platforms that support -pqa rpm query
+ # test for rpm versions that do not contain architecture in package info (e.g. 4.8.x)
+ string(REGEX MATCH ".*${check_file_match_expected_architecture}" check_file_match_architecture "${check_package_architecture}")
+ if(NOT check_file_match_architecture)
+ message(FATAL_ERROR "error: '${check_file}' Architecture does not match expected value - '${check_file_match_expected_architecture}'; RPM output: '${check_package_architecture}'; generated spec file: '${spec_file_content}'")
+ endif()
+ # else rpm version too old (e.g. 4.4.x) - skip test
+ endif()
+
+ #######################
+ # test package content
+ #######################
+ string(REGEX MATCH "${check_content_list}" expected_content_list "${check_package_content}")
+
+ if(NOT expected_content_list)
+ file(GLOB_RECURSE spec_file "${CPackComponentsForAll_BINARY_DIR}/${spec_regex}.spec")
+
+ if(spec_file)
+ file(READ ${spec_file} spec_file_content)
+ endif()
+
+ message(FATAL_ERROR "error: '${check_file}' rpm package content does not match expected value - regex '${check_content_list}'; RPM output: '${check_package_content}'; generated spec file: '${spec_file_content}'")
+ endif()
+ endforeach()
+
+ #######################
+ # verify generated symbolic links
+ #######################
+ file(GLOB_RECURSE symlink_files RELATIVE "${CPackComponentsForAll_BINARY_DIR}" "${CPackComponentsForAll_BINARY_DIR}/*/symlink_*")
+
+ foreach(check_symlink IN LISTS symlink_files)
+ get_filename_component(symlink_name "${check_symlink}" NAME)
+ execute_process(COMMAND ls -la "${check_symlink}"
+ WORKING_DIRECTORY "${CPackComponentsForAll_BINARY_DIR}"
+ OUTPUT_VARIABLE SYMLINK_POINT_
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ if("${symlink_name}" STREQUAL "symlink_samedir_path"
+ OR "${symlink_name}" STREQUAL "symlink_samedir_path_current_dir"
+ OR "${symlink_name}" STREQUAL "symlink_samedir_path_longer")
+ string(REGEX MATCH "^.*${whitespaces}->${whitespaces}depth_three$" check_symlink "${SYMLINK_POINT_}")
+ elseif("${symlink_name}" STREQUAL "symlink_subdir_path")
+ string(REGEX MATCH "^.*${whitespaces}->${whitespaces}depth_two/depth_three$" check_symlink "${SYMLINK_POINT_}")
+ elseif("${symlink_name}" STREQUAL "symlink_parentdir_path")
+ string(REGEX MATCH "^.*${whitespaces}->${whitespaces}../$" check_symlink "${SYMLINK_POINT_}")
+ elseif("${symlink_name}" STREQUAL "symlink_to_non_relocatable_path")
+ string(REGEX MATCH "^.*${whitespaces}->${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/non_relocatable/depth_two$" check_symlink "${SYMLINK_POINT_}")
+ elseif("${symlink_name}" STREQUAL "symlink_outside_package")
+ string(REGEX MATCH "^.*${whitespaces}->${whitespaces}outside_package$" check_symlink "${SYMLINK_POINT_}")
+ elseif("${symlink_name}" STREQUAL "symlink_other_relocatable_path"
+ OR "${symlink_name}" STREQUAL "symlink_from_non_relocatable_path"
+ OR "${symlink_name}" STREQUAL "symlink_relocatable_subpath")
+ # these links were not canged - post install script only - ignore them
+ else()
+ message(FATAL_ERROR "error: unexpected rpm symbolic link '${check_symlink}'")
+ endif()
+
+ if(NOT check_symlink)
+ message(FATAL_ERROR "symlink points to unexpected location '${SYMLINK_POINT_}'")
+ endif()
+ endforeach()
+
+ # verify post install symlink relocation script
+ file(GLOB_RECURSE spec_file "${CPackComponentsForAll_BINARY_DIR}/*libraries*.spec")
+ file(READ ${spec_file} spec_file_content)
+ file(READ "${CMAKE_CURRENT_LIST_DIR}/symlink_postinstall_expected.txt" symlink_postinstall_expected)
+ # prepare regex
+ string(STRIP "${symlink_postinstall_expected}" symlink_postinstall_expected)
+ string(REPLACE "[" "\\[" symlink_postinstall_expected "${symlink_postinstall_expected}")
+ string(REPLACE "$" "\\$" symlink_postinstall_expected "${symlink_postinstall_expected}")
+ string(REPLACE "lib" "lib${LIB_SUFFIX}" symlink_postinstall_expected "${symlink_postinstall_expected}")
+ # compare
+ string(REGEX MATCH ".*${symlink_postinstall_expected}.*" symlink_postinstall_expected_matches "${spec_file_content}")
+ if(NOT symlink_postinstall_expected_matches)
+ message(FATAL_ERROR "error: unexpected rpm symbolic link postinstall script! generated spec file: '${spec_file_content}'")
+ endif()
+ endif()
+endif()
+
+cmake_policy(POP)
diff --git a/Tests/CPackComponentsForAll/license.txt b/Tests/CPackComponentsForAll/license.txt
new file mode 100644
index 000000000..d829d93a2
--- /dev/null
+++ b/Tests/CPackComponentsForAll/license.txt
@@ -0,0 +1,3 @@
+LICENSE
+-------
+This is an installer created using CPack (https://cmake.org). No license provided.
diff --git a/Tests/CPackComponentsForAll/mylib b/Tests/CPackComponentsForAll/mylib
new file mode 100644
index 000000000..e3bd05c4e
--- /dev/null
+++ b/Tests/CPackComponentsForAll/mylib
@@ -0,0 +1,17 @@
+.\" Manpage for mylib.
+.\" Contact bugs@mylib_author.net.in to correct errors or typos.
+.TH mylib 3 "01 May 2015" "1.0" "mylib.so man page"
+.SH NAME
+mylib \- cpack testing lib
+.SH SYNOPSIS
+mylib.so
+.SH DESCRIPTION
+mylib.so test man page.
+.SH OPTIONS
+Lib does not take any options.
+.SH SEE ALSO
+mylib(3)
+.SH BUGS
+No known bugs.
+.SH AUTHOR
+Someone (author@lib_author.net.in)
diff --git a/Tests/CPackComponentsForAll/symlink_postinstall_expected.txt b/Tests/CPackComponentsForAll/symlink_postinstall_expected.txt
new file mode 100644
index 000000000..ba46792ee
--- /dev/null
+++ b/Tests/CPackComponentsForAll/symlink_postinstall_expected.txt
@@ -0,0 +1,57 @@
+if [ "$RPM_INSTALL_PREFIX0" != "/usr/foo/bar/lib" ]; then
+ if [ "$RPM_INSTALL_PREFIX1" != "/usr/foo/bar/other_relocatable" ]; then
+ if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_1" ]; then
+ ln -s "$RPM_INSTALL_PREFIX1/depth_two" "$RPM_INSTALL_PREFIX0/inside_relocatable_two/depth_two/symlink_other_relocatable_path"
+ CPACK_RPM_RELOCATED_SYMLINK_1=true
+ fi
+ fi
+ if [ "$RPM_INSTALL_PREFIX2" != "/usr/foo/bar/lib/inside_relocatable_two/depth_two/different_relocatable" ]; then
+ if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_0" ]; then
+ ln -s "$RPM_INSTALL_PREFIX2/bar" "$RPM_INSTALL_PREFIX0/inside_relocatable_one/depth_two/symlink_relocatable_subpath"
+ CPACK_RPM_RELOCATED_SYMLINK_0=true
+ fi
+ fi
+ if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_0" ]; then
+ ln -s "$RPM_INSTALL_PREFIX0/inside_relocatable_two/depth_two/different_relocatable/bar" "$RPM_INSTALL_PREFIX0/inside_relocatable_one/depth_two/symlink_relocatable_subpath"
+ CPACK_RPM_RELOCATED_SYMLINK_0=true
+ fi
+ if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_0" ]; then
+ ln -s "/usr/foo/bar/lib/inside_relocatable_two/depth_two/different_relocatable/bar" "$RPM_INSTALL_PREFIX0/inside_relocatable_one/depth_two/symlink_relocatable_subpath"
+ CPACK_RPM_RELOCATED_SYMLINK_0=true
+ fi
+ if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_1" ]; then
+ ln -s "/usr/foo/bar/other_relocatable/depth_two" "$RPM_INSTALL_PREFIX0/inside_relocatable_two/depth_two/symlink_other_relocatable_path"
+ CPACK_RPM_RELOCATED_SYMLINK_1=true
+ fi
+fi
+if [ "$RPM_INSTALL_PREFIX1" != "/usr/foo/bar/other_relocatable" ]; then
+ if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_1" ]; then
+ ln -s "$RPM_INSTALL_PREFIX1/depth_two" "/usr/foo/bar/lib/inside_relocatable_two/depth_two/symlink_other_relocatable_path"
+ CPACK_RPM_RELOCATED_SYMLINK_1=true
+ fi
+fi
+if [ "$RPM_INSTALL_PREFIX2" != "/usr/foo/bar/lib/inside_relocatable_two/depth_two/different_relocatable" ]; then
+ if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_0" ]; then
+ ln -s "$RPM_INSTALL_PREFIX2/bar" "/usr/foo/bar/lib/inside_relocatable_one/depth_two/symlink_relocatable_subpath"
+ CPACK_RPM_RELOCATED_SYMLINK_0=true
+ fi
+fi
+if [ "$RPM_INSTALL_PREFIX0" != "/usr/foo/bar/lib" ]; then
+ if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_0" ]; then
+ ln -s "$RPM_INSTALL_PREFIX0/inside_relocatable_two/depth_two/different_relocatable/bar" "/usr/foo/bar/lib/inside_relocatable_one/depth_two/symlink_relocatable_subpath"
+ CPACK_RPM_RELOCATED_SYMLINK_0=true
+ fi
+ if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_2" ]; then
+ ln -s "$RPM_INSTALL_PREFIX0/inside_relocatable_two/depth_two" "/usr/foo/bar/non_relocatable/depth_two/symlink_from_non_relocatable_path"
+ CPACK_RPM_RELOCATED_SYMLINK_2=true
+ fi
+fi
+if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_0" ]; then
+ ln -s "/usr/foo/bar/lib/inside_relocatable_two/depth_two/different_relocatable/bar" "/usr/foo/bar/lib/inside_relocatable_one/depth_two/symlink_relocatable_subpath"
+fi
+if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_1" ]; then
+ ln -s "/usr/foo/bar/other_relocatable/depth_two" "/usr/foo/bar/lib/inside_relocatable_two/depth_two/symlink_other_relocatable_path"
+fi
+if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_2" ]; then
+ ln -s "/usr/foo/bar/lib/inside_relocatable_two/depth_two" "/usr/foo/bar/non_relocatable/depth_two/symlink_from_non_relocatable_path"
+fi
diff --git a/Tests/CPackComponentsPrefix/CMakeLists.txt b/Tests/CPackComponentsPrefix/CMakeLists.txt
new file mode 100644
index 000000000..581d3b378
--- /dev/null
+++ b/Tests/CPackComponentsPrefix/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.2)
+project(CPackComponentsPrefix NONE)
+
+install(FILES file-runtime.txt
+ DESTINATION bin COMPONENT Runtime)
+install(FILES file-development.txt
+ DESTINATION lib COMPONENT Development)
+
+set(CPACK_PACKAGE_CONTACT "None") # mandatory for DEB generator
+set(CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY 1)
+set(CPACK_COMPONENTS_ALL Development)
+set(CPACK_ARCHIVE_COMPONENT_INSTALL 1)
+set(CPACK_PACKAGING_INSTALL_PREFIX "/opt/My-1.0")
+include(CPack)
diff --git a/Tests/CPackComponentsPrefix/file-development.txt b/Tests/CPackComponentsPrefix/file-development.txt
new file mode 100644
index 000000000..df22d2f51
--- /dev/null
+++ b/Tests/CPackComponentsPrefix/file-development.txt
@@ -0,0 +1 @@
+This file is installed with the Development component.
diff --git a/Tests/CPackComponentsPrefix/file-runtime.txt b/Tests/CPackComponentsPrefix/file-runtime.txt
new file mode 100644
index 000000000..135c13d3e
--- /dev/null
+++ b/Tests/CPackComponentsPrefix/file-runtime.txt
@@ -0,0 +1 @@
+This file is installed with the Runtime component.
diff --git a/Tests/CPackWiXGenerator/CMakeLists.txt b/Tests/CPackWiXGenerator/CMakeLists.txt
index 475e60d09..73eaf4fe9 100644
--- a/Tests/CPackWiXGenerator/CMakeLists.txt
+++ b/Tests/CPackWiXGenerator/CMakeLists.txt
@@ -4,19 +4,31 @@ project(CPackWiXGenerator)
add_library(mylib mylib.cpp)
-add_executable(mylibapp mylibapp.cpp)
-target_link_libraries(mylibapp mylib)
+add_executable(my-libapp mylibapp.cpp)
+target_link_libraries(my-libapp mylib)
+
+add_executable(my-other-app myotherapp.cpp)
+
+file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/empty)
+install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/empty
+ DESTINATION extras
+ COMPONENT extras)
install(TARGETS mylib
ARCHIVE
DESTINATION lib
COMPONENT libraries)
-install(TARGETS mylibapp
+install(TARGETS my-libapp
RUNTIME
DESTINATION bin
COMPONENT applications)
+install(TARGETS my-other-app
+ RUNTIME
+ DESTINATION bin
+ COMPONENT applications2)
+
install(FILES mylib.h "file with spaces.h"
DESTINATION include
COMPONENT headers)
@@ -36,7 +48,23 @@ set(CPACK_PACKAGE_INSTALL_DIRECTORY "CPack Component Example")
set(CPACK_WIX_UPGRADE_GUID "BF20CE5E-7F7C-401D-8F7C-AB45E8D170E6")
set(CPACK_WIX_UNINSTALL "1")
-set(CPACK_PACKAGE_EXECUTABLES "mylibapp; CPack Wix Test")
+
+set(CPACK_PACKAGE_EXECUTABLES
+ "my-libapp" "CPack WiX Test"
+ "my-other-app" "Second CPack WiX Test"
+)
+
+set(CPACK_CREATE_DESKTOP_LINKS
+ "my-libapp"
+ "my-other-app"
+)
+
+set(CPACK_WIX_PATCH_FILE "${CMAKE_CURRENT_SOURCE_DIR}/patch.xml")
+
+set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/license.txt")
+
+set(CPACK_WIX_PROPERTY_ARPCOMMENTS "My Custom ARPCOMMENTS")
+set(CPACK_WIX_PROPERTY_ARPHELPLINK "https://cmake.org")
include(CPack)
@@ -49,12 +77,25 @@ cpack_add_component_group(Development
EXPANDED
DESCRIPTION "All of the tools you'll ever need to develop software")
+cpack_add_component(extras
+ DISPLAY_NAME "Extras"
+ DESCRIPTION "Extras"
+ GROUP Runtime
+ INSTALL_TYPES Full)
+
cpack_add_component(applications
+ REQUIRED
DISPLAY_NAME "MyLib Application"
DESCRIPTION "An extremely useful application that makes use of MyLib"
GROUP Runtime
INSTALL_TYPES Full)
+cpack_add_component(applications2
+ DISPLAY_NAME "MyLib Extra Application"
+ DESCRIPTION "Another extremely useful application that makes use of MyLib"
+ GROUP Runtime
+ INSTALL_TYPES Full)
+
cpack_add_component(documentation
DISPLAY_NAME "MyLib Documentation"
DESCRIPTION "The extensive suite of MyLib Application documentation files"
diff --git a/Tests/CPackWiXGenerator/RunCPackVerifyResult.cmake b/Tests/CPackWiXGenerator/RunCPackVerifyResult.cmake
index 30e33cf22..ca9fd9049 100644
--- a/Tests/CPackWiXGenerator/RunCPackVerifyResult.cmake
+++ b/Tests/CPackWiXGenerator/RunCPackVerifyResult.cmake
@@ -10,7 +10,12 @@ message(STATUS "CMAKE_COMMAND: ${CMAKE_COMMAND}")
message(STATUS "CMAKE_CPACK_COMMAND: ${CMAKE_CPACK_COMMAND}")
message(STATUS "CPackWiXGenerator_BINARY_DIR: ${CPackWiXGenerator_BINARY_DIR}")
+if(config)
+ set(_C_config -C ${config})
+endif()
+
execute_process(COMMAND "${CMAKE_CPACK_COMMAND}"
+ ${_C_config}
RESULT_VARIABLE CPack_result
OUTPUT_VARIABLE CPack_output
ERROR_VARIABLE CPack_error
diff --git a/Tests/CPackWiXGenerator/license.txt b/Tests/CPackWiXGenerator/license.txt
new file mode 100644
index 000000000..79427833d
--- /dev/null
+++ b/Tests/CPackWiXGenerator/license.txt
@@ -0,0 +1,9 @@
+hello world
+merhaba dünya
+ãƒãƒ­ãƒ¼ãƒ¯ãƒ¼ãƒ«ãƒ‰
+привет мир
+مرحبا العالم
+你好世界
+
+4-Byte sequences:
+ Perch (Fish) 𩶘 Elevator 𨋢!
diff --git a/Tests/CPackWiXGenerator/myotherapp.cpp b/Tests/CPackWiXGenerator/myotherapp.cpp
new file mode 100644
index 000000000..c272dabae
--- /dev/null
+++ b/Tests/CPackWiXGenerator/myotherapp.cpp
@@ -0,0 +1 @@
+int main() {} \ No newline at end of file
diff --git a/Tests/CPackWiXGenerator/patch.xml b/Tests/CPackWiXGenerator/patch.xml
new file mode 100644
index 000000000..13c392d3c
--- /dev/null
+++ b/Tests/CPackWiXGenerator/patch.xml
@@ -0,0 +1,7 @@
+<CPackWiXPatch>
+ <CPackWiXFragment Id="CM_CP_applications.bin.my_libapp.exe">
+ <Environment Id="MyEnvironment" Action="set"
+ Name="CPackWiXGeneratorTest"
+ Value="CPackWiXGeneratorTest"/>
+ </CPackWiXFragment>
+</CPackWiXPatch>
diff --git a/Tests/CTestBuildCommandProjectInSubdir/CTestBuildCommandProjectInSubdir.cmake.in b/Tests/CTestBuildCommandProjectInSubdir/CTestBuildCommandProjectInSubdir.cmake.in
index ea48c780f..670a8745f 100644
--- a/Tests/CTestBuildCommandProjectInSubdir/CTestBuildCommandProjectInSubdir.cmake.in
+++ b/Tests/CTestBuildCommandProjectInSubdir/CTestBuildCommandProjectInSubdir.cmake.in
@@ -2,11 +2,11 @@ cmake_minimum_required(VERSION 2.8.10)
set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/VSProjectInSubdir")
set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestBuildCommandProjectInSubdir/Nested")
-set(CTEST_CMAKE_GENERATOR "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
set(CTEST_PROJECT_NAME "VSProjectInSubdir")
set(CTEST_BUILD_CONFIGURATION "@CTestTest_CONFIG@")
ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY})
ctest_start(Experimental)
-ctest_configure(OPTIONS "@CMAKE_TEST_GENERATOR_TOOLSET_SELECTION@-DCMAKE_MAKE_PROGRAM:FILEPATH=@CMAKE_TEST_MAKEPROGRAM@")
+ctest_configure(OPTIONS "@ctest_configure_options@")
ctest_build(TARGET test)
diff --git a/Tests/CTestConfig/dashboard.cmake.in b/Tests/CTestConfig/dashboard.cmake.in
index 0bba6d62d..143fe717a 100644
--- a/Tests/CTestConfig/dashboard.cmake.in
+++ b/Tests/CTestConfig/dashboard.cmake.in
@@ -18,8 +18,9 @@ endif()
message("cmake initial configure")
execute_process(COMMAND ${CMAKE_COMMAND}
${arg}
- -G "@CMAKE_TEST_GENERATOR@"
- -T "@CMAKE_TEST_GENERATOR_TOOLSET@"
+ -G "@CMAKE_GENERATOR@"
+ -A "@CMAKE_GENERATOR_PLATFORM@"
+ -T "@CMAKE_GENERATOR_TOOLSET@"
${CTEST_SOURCE_DIRECTORY}
WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY}
RESULT_VARIABLE rv)
diff --git a/Tests/CTestConfig/script.cmake.in b/Tests/CTestConfig/script.cmake.in
index 83267a4d1..b6ccedb57 100644
--- a/Tests/CTestConfig/script.cmake.in
+++ b/Tests/CTestConfig/script.cmake.in
@@ -1,5 +1,6 @@
-set(CTEST_CMAKE_GENERATOR "@CMAKE_TEST_GENERATOR@")
-set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_TEST_GENERATOR_TOOLSET@")
+set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@")
set(CTEST_PROJECT_NAME "CTestConfig")
set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestConfig")
set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestConfig/@cfg@-script")
diff --git a/Tests/CTestCoverageCollectGCOV/TestProject/3rdparty/foo.cpp b/Tests/CTestCoverageCollectGCOV/TestProject/3rdparty/foo.cpp
new file mode 100644
index 000000000..85e6cd8c3
--- /dev/null
+++ b/Tests/CTestCoverageCollectGCOV/TestProject/3rdparty/foo.cpp
@@ -0,0 +1 @@
+void foo() {}
diff --git a/Tests/CTestCoverageCollectGCOV/TestProject/CMakeLists.txt b/Tests/CTestCoverageCollectGCOV/TestProject/CMakeLists.txt
new file mode 100644
index 000000000..ce6fac435
--- /dev/null
+++ b/Tests/CTestCoverageCollectGCOV/TestProject/CMakeLists.txt
@@ -0,0 +1,41 @@
+cmake_minimum_required(VERSION 3.2)
+
+project(TestProject CXX)
+
+include(CTest)
+
+set(SOURCES
+ main.cpp
+ 3rdparty/foo.cpp
+ extra/extra.cpp
+)
+
+add_executable(myexecutable ${SOURCES})
+
+set_property(SOURCE main.cpp APPEND PROPERTY LABELS SourceLabel)
+set_property(TARGET myexecutable APPEND PROPERTY LABELS TargetLabel)
+
+set(MYEXECUTABLE_INFO_FILE "${CMAKE_CURRENT_BINARY_DIR}/myexecutable_info.cmake")
+
+file(WRITE "${MYEXECUTABLE_INFO_FILE}" "
+ set(TARGET myexecutable)
+ set(SOURCE_DIR \"${CMAKE_CURRENT_SOURCE_DIR}\")
+ set(SOURCES \"${SOURCES}\")
+")
+
+add_custom_command(TARGET myexecutable
+ POST_BUILD
+ COMMAND ${CMAKE_COMMAND}
+ "-DINFO_FILE=${MYEXECUTABLE_INFO_FILE}"
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/fake_compile_time_gcno.cmake"
+ VERBATIM
+)
+
+add_test(NAME mytest
+ COMMAND ${CMAKE_COMMAND}
+ "-DMYEXECUTABLE=$<TARGET_FILE:myexecutable>"
+ "-DTARGETDIR=${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/myexecutable.dir"
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/fake_run_time_gcda.cmake"
+)
+
+set_property(TEST mytest APPEND PROPERTY LABELS TestLabel)
diff --git a/Tests/CTestCoverageCollectGCOV/TestProject/extra/extra.cpp b/Tests/CTestCoverageCollectGCOV/TestProject/extra/extra.cpp
new file mode 100644
index 000000000..c3a2c129d
--- /dev/null
+++ b/Tests/CTestCoverageCollectGCOV/TestProject/extra/extra.cpp
@@ -0,0 +1 @@
+void extra() {}
diff --git a/Tests/CTestCoverageCollectGCOV/TestProject/fake_compile_time_gcno.cmake b/Tests/CTestCoverageCollectGCOV/TestProject/fake_compile_time_gcno.cmake
new file mode 100644
index 000000000..881460b3c
--- /dev/null
+++ b/Tests/CTestCoverageCollectGCOV/TestProject/fake_compile_time_gcno.cmake
@@ -0,0 +1,7 @@
+include("${INFO_FILE}")
+
+foreach(source ${SOURCES})
+ file(WRITE "CMakeFiles/${TARGET}.dir/${source}.gcno"
+ "${SOURCE_DIR}/${source}"
+ )
+endforeach()
diff --git a/Tests/CTestCoverageCollectGCOV/TestProject/fake_run_time_gcda.cmake b/Tests/CTestCoverageCollectGCOV/TestProject/fake_run_time_gcda.cmake
new file mode 100644
index 000000000..26ce2bd76
--- /dev/null
+++ b/Tests/CTestCoverageCollectGCOV/TestProject/fake_run_time_gcda.cmake
@@ -0,0 +1,12 @@
+execute_process(COMMAND ${MYEXECUTABLE} RESULT_VARIABLE RESULT)
+
+if(NOT RESULT_VARIABLE STREQUAL "0")
+ message("Test failure")
+endif()
+
+file(GLOB_RECURSE gcno_files "${TARGETDIR}/*.gcno")
+
+foreach(gcno_file ${gcno_files})
+ string(REPLACE ".gcno" ".gcda" gcda_file "${gcno_file}")
+ configure_file(${gcno_file} ${gcda_file} COPYONLY)
+endforeach()
diff --git a/Tests/CTestCoverageCollectGCOV/TestProject/main.cpp b/Tests/CTestCoverageCollectGCOV/TestProject/main.cpp
new file mode 100644
index 000000000..237c8ce18
--- /dev/null
+++ b/Tests/CTestCoverageCollectGCOV/TestProject/main.cpp
@@ -0,0 +1 @@
+int main() {}
diff --git a/Tests/CTestCoverageCollectGCOV/fakegcov.cmake b/Tests/CTestCoverageCollectGCOV/fakegcov.cmake
new file mode 100644
index 000000000..b0c3a9b9f
--- /dev/null
+++ b/Tests/CTestCoverageCollectGCOV/fakegcov.cmake
@@ -0,0 +1,14 @@
+foreach(I RANGE 0 ${CMAKE_ARGC})
+ if("${CMAKE_ARGV${I}}" MATCHES ".*\\.gcda")
+ set(gcda_file "${CMAKE_ARGV${I}}")
+ endif()
+endforeach()
+
+get_filename_component(gcda_name ${gcda_file} NAME)
+string(REPLACE ".gcda" ".gcov" gcov_name "${gcda_name}")
+
+file(STRINGS "${gcda_file}" source_file LIMIT_COUNT 1 ENCODING UTF-8)
+
+file(WRITE "${CMAKE_SOURCE_DIR}/${gcov_name}"
+ " -: 0:Source:${source_file}"
+)
diff --git a/Tests/CTestCoverageCollectGCOV/test.cmake.in b/Tests/CTestCoverageCollectGCOV/test.cmake.in
new file mode 100644
index 000000000..b2e6d6dfe
--- /dev/null
+++ b/Tests/CTestCoverageCollectGCOV/test.cmake.in
@@ -0,0 +1,50 @@
+cmake_minimum_required(VERSION 2.8.12)
+set(CTEST_PROJECT_NAME "TestProject")
+set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestCoverageCollectGCOV/TestProject")
+set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestCoverageCollectGCOV/TestProject")
+set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
+
+ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY})
+
+ctest_start(Experimental)
+ctest_configure()
+ctest_build()
+ctest_test()
+
+list(APPEND CTEST_CUSTOM_COVERAGE_EXCLUDE
+ "/foo/something"
+ "/3rdparty/"
+ "/bar/somethingelse"
+)
+
+include(CTestCoverageCollectGCOV)
+set(tar_file ${CTEST_BINARY_DIRECTORY}/gcov.tar)
+ctest_coverage_collect_gcov(
+ TARBALL "${tar_file}"
+ SOURCE "${CTEST_SOURCE_DIRECTORY}"
+ BUILD "${CTEST_BINARY_DIRECTORY}"
+ GCOV_COMMAND "${CMAKE_COMMAND}"
+ GCOV_OPTIONS -P "@CMake_SOURCE_DIR@/Tests/CTestCoverageCollectGCOV/fakegcov.cmake")
+
+execute_process(COMMAND
+ ${CMAKE_COMMAND} -E tar tf ${tar_file}
+ OUTPUT_VARIABLE out
+ WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+
+string(REPLACE "\n" ";" out "${out}")
+list(SORT out)
+
+set(expected_out
+ CMakeFiles/myexecutable.dir/Labels.json
+ Testing/CoverageInfo/data.json
+ Testing/CoverageInfo/extra.cpp.gcov
+ Testing/CoverageInfo/main.cpp.gcov
+)
+
+if("${out}" STREQUAL "${expected_out}")
+ message("PASSED with correct output: ${out}")
+else()
+ message(FATAL_ERROR "FAILED: expected:\n${expected_out}\nGot:\n${out}")
+endif()
diff --git a/Tests/CTestTest/test.cmake.in b/Tests/CTestTest/test.cmake.in
index 214bff8d7..bb6346b8a 100644
--- a/Tests/CTestTest/test.cmake.in
+++ b/Tests/CTestTest/test.cmake.in
@@ -6,7 +6,7 @@
# this is the cvs module name that should be checked out
set (CTEST_MODULE_NAME SmallAndFast)
-# these are the the name of the source and binary directory on disk.
+# these are the name of the source and binary directory on disk.
# They will be appended to DASHBOARD_ROOT
set (CTEST_SOURCE_NAME SmallAndFast)
set (CTEST_BINARY_NAME SmallAndFastBuild)
@@ -41,6 +41,7 @@ set (CTEST_INITIAL_CACHE "
SITE:STRING=@SITE@
BUILDNAME:STRING=SmallAndFast-@BUILDNAME@
CMAKE_GENERATOR:INTERNAL=@CMAKE_GENERATOR@
+CMAKE_GENERATOR_PLATFORM:INTERNAL=@CMAKE_GENERATOR_PLATFORM@
CMAKE_GENERATOR_TOOLSET:INTERNAL=@CMAKE_GENERATOR_TOOLSET@
CMAKE_CXX_FLAGS:STRING=@CMAKE_CXX_FLAGS@
CMAKE_C_FLAGS:STRING=@CMAKE_C_FLAGS@
diff --git a/Tests/CTestTest2/test.cmake.in b/Tests/CTestTest2/test.cmake.in
index 26a77a7e6..825b957d7 100644
--- a/Tests/CTestTest2/test.cmake.in
+++ b/Tests/CTestTest2/test.cmake.in
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.1)
+cmake_minimum_required(VERSION 2.4)
# Settings:
set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Source/kwsys")
set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTest2/kwsysBin")
set(CTEST_CVS_COMMAND "@CVSCOMMAND@")
set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@")
set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@")
set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
set(CTEST_MEMORYCHECK_COMMAND "@MEMORYCHECK_COMMAND@")
@@ -38,14 +39,19 @@ CMAKE_CXX_COMPILER_ARG1:STRING=@CMAKE_CXX_COMPILER_ARG1@
CTEST_TEST_KWSYS:BOOL=ON
")
+set(test_exclude
+ kwsys.testProcess-10
+ )
+
CTEST_START(Experimental)
#CTEST_UPDATE(SOURCE "${CTEST_SOURCE_DIRECTORY}" RETURN_VALUE res)
CTEST_CONFIGURE(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
+CTEST_READ_CUSTOM_FILES(${CTEST_BINARY_DIRECTORY})
CTEST_BUILD(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
-CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res START 1 END 5 STRIDE 2)
-CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res START 7 STRIDE 2 SUBMIT_INDEX 1)
-CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res START 2 END 4 STRIDE 2 SUBMIT_INDEX 2)
-CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res START 6 STRIDE 2 SUBMIT_INDEX 3)
+CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res EXCLUDE ${test_exclude} START 1 END 5 STRIDE 2)
+CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res EXCLUDE ${test_exclude} START 7 STRIDE 2 SUBMIT_INDEX 1)
+CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res EXCLUDE ${test_exclude} START 2 END 4 STRIDE 2 SUBMIT_INDEX 2)
+CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res EXCLUDE ${test_exclude} START 6 STRIDE 2 SUBMIT_INDEX 3)
CTEST_MEMCHECK(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res STRIDE 1.5)
CTEST_COVERAGE(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
diff --git a/Tests/CTestTestBadExe/CTestConfig.cmake b/Tests/CTestTestBadExe/CTestConfig.cmake
index 1d46ea3e7..c7286e2c5 100644
--- a/Tests/CTestTestBadExe/CTestConfig.cmake
+++ b/Tests/CTestTestBadExe/CTestConfig.cmake
@@ -2,6 +2,6 @@ set (CTEST_PROJECT_NAME "CTestTestBadExe")
set (CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
set (CTEST_DART_SERVER_VERSION "2")
set(CTEST_DROP_METHOD "http")
-set(CTEST_DROP_SITE "www.cdash.org")
-set(CTEST_DROP_LOCATION "/CDash/submit.php?project=PublicDashboard")
+set(CTEST_DROP_SITE "open.cdash.org")
+set(CTEST_DROP_LOCATION "/submit.php?project=PublicDashboard")
set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Tests/CTestTestBadExe/test.cmake.in b/Tests/CTestTestBadExe/test.cmake.in
index 03ebd0416..43a85725b 100644
--- a/Tests/CTestTestBadExe/test.cmake.in
+++ b/Tests/CTestTestBadExe/test.cmake.in
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.1)
+cmake_minimum_required(VERSION 2.4)
# Settings:
set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
@@ -8,8 +8,9 @@ set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-BadExe")
set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestBadExe")
set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestBadExe")
set(CTEST_CVS_COMMAND "@CVSCOMMAND@")
-set(CTEST_CMAKE_GENERATOR "@CMAKE_TEST_GENERATOR@")
-set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_TEST_GENERATOR_TOOLSET@")
+set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@")
set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
diff --git a/Tests/CTestTestBadGenerator/CMakeLists.txt b/Tests/CTestTestBadGenerator/CMakeLists.txt
new file mode 100644
index 000000000..d46d9bf4f
--- /dev/null
+++ b/Tests/CTestTestBadGenerator/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.0)
+project(CTestTestDepends NONE)
+include(CTest)
diff --git a/Tests/CTestTestBadGenerator/CTestConfig.cmake b/Tests/CTestTestBadGenerator/CTestConfig.cmake
new file mode 100644
index 000000000..1e61bf441
--- /dev/null
+++ b/Tests/CTestTestBadGenerator/CTestConfig.cmake
@@ -0,0 +1,7 @@
+set (CTEST_PROJECT_NAME "CTestTestBadGenerator")
+set (CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
+set (CTEST_DART_SERVER_VERSION "2")
+set(CTEST_DROP_METHOD "http")
+set(CTEST_DROP_SITE "open.cdash.org")
+set(CTEST_DROP_LOCATION "/submit.php?project=PublicDashboard")
+set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Tests/CTestTestBadGenerator/test.cmake.in b/Tests/CTestTestBadGenerator/test.cmake.in
new file mode 100644
index 000000000..ae6d0b578
--- /dev/null
+++ b/Tests/CTestTestBadGenerator/test.cmake.in
@@ -0,0 +1,21 @@
+cmake_minimum_required(VERSION 3.0)
+
+# Settings:
+set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
+set(CTEST_SITE "@SITE@")
+set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-Depends")
+
+set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestBadGenerator")
+set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestBadGenerator")
+set(CTEST_CVS_COMMAND "@CVSCOMMAND@")
+set(CTEST_CMAKE_GENERATOR "Bad Generator")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "")
+set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
+set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
+set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
+
+CTEST_START(Experimental)
+CTEST_CONFIGURE(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
+CTEST_BUILD(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
+CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
diff --git a/Tests/CTestTestChecksum/test.cmake.in b/Tests/CTestTestChecksum/test.cmake.in
index efc53fbed..32d62bb34 100644
--- a/Tests/CTestTestChecksum/test.cmake.in
+++ b/Tests/CTestTestChecksum/test.cmake.in
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.1)
+cmake_minimum_required(VERSION 2.4)
# Settings:
set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
@@ -8,8 +8,9 @@ set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-Checksum")
set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestParallel")
set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestParallel")
set(CTEST_CVS_COMMAND "@CVSCOMMAND@")
-set(CTEST_CMAKE_GENERATOR "@CMAKE_TEST_GENERATOR@")
-set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_TEST_GENERATOR_TOOLSET@")
+set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@")
set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
diff --git a/Tests/CTestTestConfigFileInBuildDir/CMakeLists.txt b/Tests/CTestTestConfigFileInBuildDir/CMakeLists.txt
deleted file mode 100644
index 3c53e6623..000000000
--- a/Tests/CTestTestConfigFileInBuildDir/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-cmake_minimum_required(VERSION 2.8)
-project(CTestTestConfigFileInBuildDir)
-include(CTest)
diff --git a/Tests/CTestTestConfigFileInBuildDir/CTestConfig.cmake b/Tests/CTestTestConfigFileInBuildDir/CTestConfig.cmake
deleted file mode 100644
index d2c28f98c..000000000
--- a/Tests/CTestTestConfigFileInBuildDir/CTestConfig.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-set(CTEST_PROJECT_NAME "CTestTestConfigFileInBuildDir")
-set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC")
-set(CTEST_DART_SERVER_VERSION "2")
-set(CTEST_DROP_METHOD "http")
-set(CTEST_DROP_SITE "www.cdash.org")
-set(CTEST_DROP_LOCATION "/CDash/submit.php?project=PublicDashboard")
-set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Tests/CTestTestConfigFileInBuildDir/test1.cmake.in b/Tests/CTestTestConfigFileInBuildDir/test1.cmake.in
deleted file mode 100644
index 42225d305..000000000
--- a/Tests/CTestTestConfigFileInBuildDir/test1.cmake.in
+++ /dev/null
@@ -1,18 +0,0 @@
-cmake_minimum_required(VERSION 2.8)
-
-# Settings:
-set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
-set(CTEST_SITE "@SITE@")
-set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-ConfigFileInBuildDir1")
-
-set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestConfigFileInBuildDir")
-set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestConfigFileInBuildDir1")
-set(CTEST_CVS_COMMAND "@CVSCOMMAND@")
-set(CTEST_CMAKE_GENERATOR "@CMAKE_TEST_GENERATOR@")
-set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_TEST_GENERATOR_TOOLSET@")
-set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
-set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
-set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
-
-CTEST_START(Experimental)
-CTEST_CONFIGURE(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
diff --git a/Tests/CTestTestConfigFileInBuildDir/test2.cmake.in b/Tests/CTestTestConfigFileInBuildDir/test2.cmake.in
deleted file mode 100644
index 010fe1caa..000000000
--- a/Tests/CTestTestConfigFileInBuildDir/test2.cmake.in
+++ /dev/null
@@ -1,18 +0,0 @@
-cmake_minimum_required(VERSION 2.8)
-
-# Settings:
-set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
-set(CTEST_SITE "@SITE@")
-set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-ConfigFileInBuildDir2")
-
-set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestConfigFileInBuildDir")
-set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestConfigFileInBuildDir2")
-set(CTEST_CVS_COMMAND "@CVSCOMMAND@")
-set(CTEST_CMAKE_GENERATOR "@CMAKE_TEST_GENERATOR@")
-set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_TEST_GENERATOR_TOOLSET@")
-set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
-set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
-set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
-
-CTEST_START(Experimental)
-CTEST_CONFIGURE(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
diff --git a/Tests/CTestTestCostSerial/CTestConfig.cmake b/Tests/CTestTestCostSerial/CTestConfig.cmake
index 05c20eb4b..3ab99ac5e 100644
--- a/Tests/CTestTestCostSerial/CTestConfig.cmake
+++ b/Tests/CTestTestCostSerial/CTestConfig.cmake
@@ -2,6 +2,6 @@ set(CTEST_PROJECT_NAME "CTestTestCostSerial")
set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
set(CTEST_DART_SERVER_VERSION "2")
set(CTEST_DROP_METHOD "http")
-set(CTEST_DROP_SITE "www.cdash.org")
-set(CTEST_DROP_LOCATION "/CDash/submit.php?project=PublicDashboard")
+set(CTEST_DROP_SITE "open.cdash.org")
+set(CTEST_DROP_LOCATION "/submit.php?project=PublicDashboard")
set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Tests/CTestTestCostSerial/test.cmake.in b/Tests/CTestTestCostSerial/test.cmake.in
index bfb3d9a03..9b32a468b 100644
--- a/Tests/CTestTestCostSerial/test.cmake.in
+++ b/Tests/CTestTestCostSerial/test.cmake.in
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.1)
+cmake_minimum_required(VERSION 2.4)
# Settings:
set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
@@ -8,8 +8,9 @@ set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-CostSerial")
set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestCostSerial")
set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestCostSerial")
set(CTEST_CVS_COMMAND "@CVSCOMMAND@")
-set(CTEST_CMAKE_GENERATOR "@CMAKE_TEST_GENERATOR@")
-set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_TEST_GENERATOR_TOOLSET@")
+set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@")
set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
diff --git a/Tests/CTestTestCrash/CTestConfig.cmake b/Tests/CTestTestCrash/CTestConfig.cmake
index e1c5b1b6f..5c2ca0ea9 100644
--- a/Tests/CTestTestCrash/CTestConfig.cmake
+++ b/Tests/CTestTestCrash/CTestConfig.cmake
@@ -2,6 +2,6 @@ set (CTEST_PROJECT_NAME "CTestTestCrash")
set (CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
set (CTEST_DART_SERVER_VERSION "2")
set(CTEST_DROP_METHOD "http")
-set(CTEST_DROP_SITE "www.cdash.org")
-set(CTEST_DROP_LOCATION "/CDash/submit.php?project=PublicDashboard")
+set(CTEST_DROP_SITE "open.cdash.org")
+set(CTEST_DROP_LOCATION "/submit.php?project=PublicDashboard")
set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Tests/CTestTestCrash/test.cmake.in b/Tests/CTestTestCrash/test.cmake.in
index 492966c4a..3641cb01f 100644
--- a/Tests/CTestTestCrash/test.cmake.in
+++ b/Tests/CTestTestCrash/test.cmake.in
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.1)
+cmake_minimum_required(VERSION 2.4)
# Settings:
set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
@@ -8,8 +8,9 @@ set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-Crash")
set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestCrash")
set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestCrash")
set(CTEST_CVS_COMMAND "@CVSCOMMAND@")
-set(CTEST_CMAKE_GENERATOR "@CMAKE_TEST_GENERATOR@")
-set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_TEST_GENERATOR_TOOLSET@")
+set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@")
set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
diff --git a/Tests/CTestTestCycle/CTestConfig.cmake b/Tests/CTestTestCycle/CTestConfig.cmake
index 43e99863a..8aeb09b70 100644
--- a/Tests/CTestTestCycle/CTestConfig.cmake
+++ b/Tests/CTestTestCycle/CTestConfig.cmake
@@ -2,6 +2,6 @@ set (CTEST_PROJECT_NAME "CTestTestCycle")
set (CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
set (CTEST_DART_SERVER_VERSION "2")
set(CTEST_DROP_METHOD "http")
-set(CTEST_DROP_SITE "www.cdash.org")
-set(CTEST_DROP_LOCATION "/CDash/submit.php?project=PublicDashboard")
+set(CTEST_DROP_SITE "open.cdash.org")
+set(CTEST_DROP_LOCATION "/submit.php?project=PublicDashboard")
set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Tests/CTestTestCycle/test.cmake.in b/Tests/CTestTestCycle/test.cmake.in
index e9c9a4ee8..4a63dd612 100644
--- a/Tests/CTestTestCycle/test.cmake.in
+++ b/Tests/CTestTestCycle/test.cmake.in
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.1)
+cmake_minimum_required(VERSION 2.4)
# Settings:
set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
@@ -8,8 +8,9 @@ set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-Cycle")
set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestCycle")
set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestCycle")
set(CTEST_CVS_COMMAND "@CVSCOMMAND@")
-set(CTEST_CMAKE_GENERATOR "@CMAKE_TEST_GENERATOR@")
-set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_TEST_GENERATOR_TOOLSET@")
+set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@")
set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
diff --git a/Tests/CTestTestDepends/CTestConfig.cmake b/Tests/CTestTestDepends/CTestConfig.cmake
index e3af7dd8d..7af9200e2 100644
--- a/Tests/CTestTestDepends/CTestConfig.cmake
+++ b/Tests/CTestTestDepends/CTestConfig.cmake
@@ -2,6 +2,6 @@ set (CTEST_PROJECT_NAME "CTestTestDepends")
set (CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
set (CTEST_DART_SERVER_VERSION "2")
set(CTEST_DROP_METHOD "http")
-set(CTEST_DROP_SITE "www.cdash.org")
-set(CTEST_DROP_LOCATION "/CDash/submit.php?project=PublicDashboard")
+set(CTEST_DROP_SITE "open.cdash.org")
+set(CTEST_DROP_LOCATION "/submit.php?project=PublicDashboard")
set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Tests/CTestTestDepends/test.cmake.in b/Tests/CTestTestDepends/test.cmake.in
index 002958b41..74fddb3d3 100644
--- a/Tests/CTestTestDepends/test.cmake.in
+++ b/Tests/CTestTestDepends/test.cmake.in
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.1)
+cmake_minimum_required(VERSION 2.4)
# Settings:
set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
@@ -8,8 +8,9 @@ set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-Depends")
set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestDepends")
set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestDepends")
set(CTEST_CVS_COMMAND "@CVSCOMMAND@")
-set(CTEST_CMAKE_GENERATOR "@CMAKE_TEST_GENERATOR@")
-set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_TEST_GENERATOR_TOOLSET@")
+set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@")
set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
diff --git a/Tests/CTestTestEmptyBinaryDirectory/test.cmake.in b/Tests/CTestTestEmptyBinaryDirectory/test.cmake.in
new file mode 100644
index 000000000..8eb808f7d
--- /dev/null
+++ b/Tests/CTestTestEmptyBinaryDirectory/test.cmake.in
@@ -0,0 +1,66 @@
+cmake_minimum_required(VERSION 2.8.12)
+
+set(CTEST_RUN_CURRENT_SCRIPT 0)
+
+set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestEmptyBinaryDirectory")
+set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestEmptyBinaryDirectory")
+
+# make sure ctest does not remove directories without a CMakeCache.txt in it
+set(EMPTY_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/empty_binary_dir")
+file(MAKE_DIRECTORY "${EMPTY_BINARY_DIR}")
+
+if(NOT EXISTS "${EMPTY_BINARY_DIR}"
+ OR EXISTS "${EMPTY_BINARY_DIR}/CMakeCache.txt")
+ message(FATAL_ERROR "empty_binary_dir precondition failed")
+endif()
+
+ctest_empty_binary_directory("${EMPTY_BINARY_DIR}")
+
+if(NOT EXISTS "${EMPTY_BINARY_DIR}")
+ message(FATAL_ERROR "empty_binary_dir should not have been removed")
+endif()
+
+# make sure ctest does remove directories with a CMakeCache.txt
+set(VALID_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/valid_binary_dir")
+file(MAKE_DIRECTORY "${VALID_BINARY_DIR}")
+file(WRITE "${VALID_BINARY_DIR}/CMakeCache.txt")
+
+if(NOT EXISTS "${VALID_BINARY_DIR}"
+ OR NOT EXISTS "${VALID_BINARY_DIR}/CMakeCache.txt")
+ message(FATAL_ERROR "valid_binary_dir precondition failed")
+endif()
+
+ctest_empty_binary_directory("${VALID_BINARY_DIR}")
+
+if(EXISTS "${VALID_BINARY_DIR}")
+ message(FATAL_ERROR "valid_binary_dir should have been removed")
+endif()
+
+# make sure ctest removes build directories recursively
+set(DEEP_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/deep_binary_dir")
+file(MAKE_DIRECTORY "${DEEP_BINARY_DIR}")
+file(WRITE "${DEEP_BINARY_DIR}/CMakeCache.txt")
+
+foreach(SUBDIR A Z A/A A/Z Z/A Z/Z)
+ set(FULL_SUBDIR "${DEEP_BINARY_DIR}/${SUBDIR}")
+ file(MAKE_DIRECTORY "${FULL_SUBDIR}")
+
+ foreach(SUBFILE A.cpp Z.bat)
+ set(FULL_SUBFILE "${FULL_SUBDIR}/${SUBFILE}")
+ file(WRITE "${FULL_SUBFILE}" "I am '${FULL_SUBFILE}'")
+ endforeach()
+endforeach()
+
+if(NOT EXISTS "${DEEP_BINARY_DIR}"
+ OR NOT EXISTS "${DEEP_BINARY_DIR}/CMakeCache.txt"
+ OR NOT EXISTS "${DEEP_BINARY_DIR}/Z/A/Z.bat")
+ message(FATAL_ERROR "deep_binary_dir precondition failed")
+endif()
+
+ctest_empty_binary_directory("${DEEP_BINARY_DIR}")
+
+if(EXISTS "${DEEP_BINARY_DIR}")
+ message(FATAL_ERROR "deep_binary_dir should have been removed")
+endif()
+
+message("TEST_SUCCESS")
diff --git a/Tests/CTestTestFailedSubmits/test.cmake.in b/Tests/CTestTestFailedSubmits/test.cmake.in
deleted file mode 100644
index 36a09cf61..000000000
--- a/Tests/CTestTestFailedSubmits/test.cmake.in
+++ /dev/null
@@ -1,48 +0,0 @@
-cmake_minimum_required(VERSION 2.8)
-
-# CTestConfig.cmake settings:
-set(CTEST_PROJECT_NAME "SmallAndFast")
-
-# Intentionally leave out other upload-related CTestConfig.cmake settings
-# so that the ctest_submit call below fails with an error message...
-#
-set(CTEST_DROP_METHOD "@drop_method@")
-
-# Settings:
-set(CTEST_USE_LAUNCHERS 1)
-
-# Emit these compiler warnings:
-set(ENV{CXXFLAGS} "$ENV{CXXFLAGS} -Wall")
-
-set(CTEST_SITE "@SITE@")
-set(CTEST_BUILD_NAME "CTestTestLaunchers-@drop_method@")
-
-set(CTEST_SOURCE_DIRECTORY "@source@")
-set(CTEST_BINARY_DIRECTORY "@build@")
-set(CTEST_CVS_COMMAND "@CVSCOMMAND@")
-set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
-set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@")
-set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
-set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
-set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
-
-CTEST_EMPTY_BINARY_DIRECTORY(${CTEST_BINARY_DIRECTORY})
-
-CTEST_START(Experimental)
-
-# explicitly do not use CTEST_UPDATE - avoid network activity
-
-CTEST_CONFIGURE(BUILD "${CTEST_BINARY_DIRECTORY}"
- OPTIONS "-DCTEST_USE_LAUNCHERS:BOOL=${CTEST_USE_LAUNCHERS};-DSAF_INTENTIONAL_COMPILE_ERROR:BOOL=ON;-DSAF_INTENTIONAL_COMPILE_WARNING:BOOL=ON"
- RETURN_VALUE res)
-CTEST_BUILD(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
-CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
-CTEST_COVERAGE(BUILD "${CTEST_BINARY_DIRECTORY}" @ctest_coverage_labels_args@ RETURN_VALUE res)
-
-# ok to call ctest_submit - still avoids network activity because there is
-# not a valid drop location given above...
-CTEST_SUBMIT(RETURN_VALUE res)
-
-# Add coverage for the new APPEND arg to ctest_start:
-#
-CTEST_START(Experimental APPEND)
diff --git a/Tests/CTestTestFailure/CTestConfig.cmake b/Tests/CTestTestFailure/CTestConfig.cmake
index fd8d97acf..07e1be00c 100644
--- a/Tests/CTestTestFailure/CTestConfig.cmake
+++ b/Tests/CTestTestFailure/CTestConfig.cmake
@@ -2,6 +2,6 @@ set (CTEST_PROJECT_NAME "CTestTestFailure")
set (CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
set (CTEST_DART_SERVER_VERSION "2")
set(CTEST_DROP_METHOD "http")
-set(CTEST_DROP_SITE "www.cdash.org")
-set(CTEST_DROP_LOCATION "/CDash/submit.php?project=PublicDashboard")
+set(CTEST_DROP_SITE "open.cdash.org")
+set(CTEST_DROP_LOCATION "/submit.php?project=PublicDashboard")
set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Tests/CTestTestFailure/testNoBuild.cmake.in b/Tests/CTestTestFailure/testNoBuild.cmake.in
index 3c4d219f5..86333af4a 100644
--- a/Tests/CTestTestFailure/testNoBuild.cmake.in
+++ b/Tests/CTestTestFailure/testNoBuild.cmake.in
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.1)
+cmake_minimum_required(VERSION 2.4)
# Settings:
set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
@@ -8,8 +8,9 @@ set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-NoBuild")
set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestFailure")
set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestFailure")
set(CTEST_CVS_COMMAND "@CVSCOMMAND@")
-set(CTEST_CMAKE_GENERATOR "@CMAKE_TEST_GENERATOR@")
-set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_TEST_GENERATOR_TOOLSET@")
+set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@")
set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
diff --git a/Tests/CTestTestFailure/testNoExe.cmake.in b/Tests/CTestTestFailure/testNoExe.cmake.in
index a133e2a13..8875cee36 100644
--- a/Tests/CTestTestFailure/testNoExe.cmake.in
+++ b/Tests/CTestTestFailure/testNoExe.cmake.in
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.1)
+cmake_minimum_required(VERSION 2.4)
# Settings:
set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
@@ -8,8 +8,9 @@ set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-NoExe")
set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestFailure")
set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestFailure")
set(CTEST_CVS_COMMAND "@CVSCOMMAND@")
-set(CTEST_CMAKE_GENERATOR "@CMAKE_TEST_GENERATOR@")
-set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_TEST_GENERATOR_TOOLSET@")
+set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@")
set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
diff --git a/Tests/CTestTestFdSetSize/test.cmake.in b/Tests/CTestTestFdSetSize/test.cmake.in
index c24f50590..bfe445925 100644
--- a/Tests/CTestTestFdSetSize/test.cmake.in
+++ b/Tests/CTestTestFdSetSize/test.cmake.in
@@ -8,8 +8,9 @@ set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-FdSetSize")
set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestFdSetSize")
set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestFdSetSize")
set(CTEST_CVS_COMMAND "@CVSCOMMAND@")
-set(CTEST_CMAKE_GENERATOR "@CMAKE_TEST_GENERATOR@")
-set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_TEST_GENERATOR_TOOLSET@")
+set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@")
set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
diff --git a/Tests/CTestTestLabelRegExp/CTestTestfile.cmake.in b/Tests/CTestTestLabelRegExp/CTestTestfile.cmake.in
new file mode 100644
index 000000000..657f38286
--- /dev/null
+++ b/Tests/CTestTestLabelRegExp/CTestTestfile.cmake.in
@@ -0,0 +1,8 @@
+add_test(test1 ${CMAKE_COMMAND} -E echo test1)
+set_tests_properties(test1 PROPERTIES LABELS "foo")
+
+add_test(test2 ${CMAKE_COMMAND} -E echo test2)
+set_tests_properties(test2 PROPERTIES LABELS "bar")
+
+add_test(test3 ${CMAKE_COMMAND} -E echo test3)
+set_tests_properties(test3 PROPERTIES LABELS "foo;bar")
diff --git a/Tests/CTestTestLabelRegExp/test.cmake.in b/Tests/CTestTestLabelRegExp/test.cmake.in
new file mode 100644
index 000000000..5c0c9d7ff
--- /dev/null
+++ b/Tests/CTestTestLabelRegExp/test.cmake.in
@@ -0,0 +1,37 @@
+configure_file(${SOURCE_DIR}/CTestTestfile.cmake.in CTestTestfile.cmake)
+
+function(get_test_list TEST_LIST)
+ set(QUERY_COMMAND ${CMAKE_CTEST_COMMAND} -N ${ARGN})
+
+ execute_process(COMMAND ${QUERY_COMMAND}
+ RESULT_VARIABLE RESULT
+ OUTPUT_VARIABLE OUTPUT
+ ERROR_VARIABLE ERROR)
+
+ if(NOT ${RESULT} STREQUAL "0")
+ message(FATAL_ERROR "command [${QUERY_COMMAND}] failed: RESULT[${RESULT}] OUTPUT[${OUTPUT}] ERROR[${ERROR}]")
+ endif()
+
+ set(${TEST_LIST} "${OUTPUT}" PARENT_SCOPE)
+endfunction()
+
+function(expect_test_list EXPECTED_OUTPUT)
+ get_test_list(TEST_LIST ${ARGN})
+
+ if(NOT "${TEST_LIST}" MATCHES "${EXPECTED_OUTPUT}")
+ message(FATAL_ERROR "actual output [${TEST_LIST}] does not match expected output [${EXPECTED_OUTPUT}] for given arguments [${ARGN}]")
+ endif()
+endfunction()
+
+expect_test_list("test1.*test3.*Total Tests: 2" --label-regex foo)
+expect_test_list("test2.*test3.*Total Tests: 2" --label-regex bar)
+expect_test_list("test1.*test2.*test3.*Total Tests: 3" --label-regex foo|bar)
+expect_test_list("Total Tests: 0" --label-regex baz)
+
+expect_test_list("test2.*Total Tests: 1" --label-exclude foo)
+expect_test_list("test1.*Total Tests: 1" --label-exclude bar)
+expect_test_list("Total Tests: 0" --label-exclude foo|bar)
+expect_test_list("test1.*test2.*test3.*Total Tests: 3" --label-exclude baz)
+
+expect_test_list("test1.*Total Tests: 1" --label-regex foo --label-exclude bar)
+expect_test_list("test2.*Total Tests: 1" --label-regex bar --label-exclude foo)
diff --git a/Tests/CTestTestLaunchers/launcher_test_project/CMakeLists.txt b/Tests/CTestTestLaunchers/launcher_test_project/CMakeLists.txt
new file mode 100644
index 000000000..06c57253d
--- /dev/null
+++ b/Tests/CTestTestLaunchers/launcher_test_project/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12)
+
+project(launcher_test_project)
+
+include(CTest)
+
+add_custom_command(
+ OUTPUT test1.txt
+ COMMAND ${CMAKE_COMMAND}
+ ARGS -DTESTID=1 -P "${CMAKE_CURRENT_SOURCE_DIR}/command.cmake"
+)
+
+add_custom_command(
+ OUTPUT test2.txt
+ COMMAND ${CMAKE_COMMAND}
+ ARGS -DTESTID=2 -P "${CMAKE_CURRENT_SOURCE_DIR}/command.cmake"
+)
+
+add_custom_target(mytarget ALL DEPENDS test1.txt test2.txt)
diff --git a/Tests/CTestTestLaunchers/launcher_test_project/CTestConfig.cmake b/Tests/CTestTestLaunchers/launcher_test_project/CTestConfig.cmake
new file mode 100644
index 000000000..669b0fb68
--- /dev/null
+++ b/Tests/CTestTestLaunchers/launcher_test_project/CTestConfig.cmake
@@ -0,0 +1,8 @@
+set(CTEST_USE_LAUNCHERS 1)
+set(CTEST_PROJECT_NAME "CTestTestLaunchers")
+set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
+set(CTEST_DART_SERVER_VERSION "2")
+set(CTEST_DROP_METHOD "http")
+set(CTEST_DROP_SITE "open.cdash.org")
+set(CTEST_DROP_LOCATION "/submit.php?project=PublicDashboard")
+set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Tests/CTestTestLaunchers/launcher_test_project/command.cmake b/Tests/CTestTestLaunchers/launcher_test_project/command.cmake
new file mode 100644
index 000000000..7f31af950
--- /dev/null
+++ b/Tests/CTestTestLaunchers/launcher_test_project/command.cmake
@@ -0,0 +1,5 @@
+if("${TESTID}" STREQUAL "1")
+ message("success")
+elseif("${TESTID}" STREQUAL "2")
+ message(FATAL_ERROR "failure")
+endif()
diff --git a/Tests/CTestTestLaunchers/test.cmake.in b/Tests/CTestTestLaunchers/test.cmake.in
new file mode 100644
index 000000000..03a118a40
--- /dev/null
+++ b/Tests/CTestTestLaunchers/test.cmake.in
@@ -0,0 +1,40 @@
+cmake_minimum_required(VERSION 2.8.12)
+
+# Settings:
+set(CTEST_DASHBOARD_SOURCE "@CMake_SOURCE_DIR@/Tests/CTestTestLaunchers")
+set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTestLaunchers")
+set(CTEST_SITE "@SITE@")
+set(CTEST_BUILD_NAME "Launchers-@BUILDNAME@-CTestTestLaunchers")
+
+set(CTEST_SOURCE_DIRECTORY "${CTEST_DASHBOARD_SOURCE}/launcher_test_project")
+set(CTEST_BINARY_DIRECTORY "${CTEST_DASHBOARD_ROOT}/launcher_test_project-bin")
+set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@")
+set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
+set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
+
+ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY})
+
+file(WRITE "${CTEST_BINARY_DIRECTORY}/CMakeCache.txt" "
+CMAKE_CXX_FLAGS:STRING=@CMAKE_CXX_FLAGS@
+CMAKE_C_FLAGS:STRING=@CMAKE_C_FLAGS@
+CMAKE_C_COMPILER:STRING=@CMAKE_C_COMPILER@
+CMAKE_CXX_COMPILER:STRING=@CMAKE_CXX_COMPILER@
+CMAKE_C_COMPILER_ARG1:STRING=@CMAKE_C_COMPILER_ARG1@
+CMAKE_CXX_COMPILER_ARG1:STRING=@CMAKE_CXX_COMPILER_ARG1@
+")
+
+set(TEST_SUCCESS FALSE)
+
+ctest_start(Experimental)
+ctest_configure(OPTIONS "-DCTEST_USE_LAUNCHERS=1")
+ctest_build(NUMBER_ERRORS error_count)
+
+if("${error_count}" STREQUAL "1")
+ set(TEST_SUCCESS TRUE)
+endif()
+
+if(TEST_SUCCESS)
+ message("CTEST_TEST_LAUNCHER_SUCCESS")
+endif()
diff --git a/Tests/CTestTestMemcheck/CMakeLists.txt b/Tests/CTestTestMemcheck/CMakeLists.txt
deleted file mode 100644
index 86d73854b..000000000
--- a/Tests/CTestTestMemcheck/CMakeLists.txt
+++ /dev/null
@@ -1,173 +0,0 @@
-REGEX_ESCAPE_STRING(CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
-
-foreach (_retval 0 1)
- configure_file("${CMAKE_CURRENT_SOURCE_DIR}/memtester.cxx.in" "${CMAKE_CURRENT_BINARY_DIR}/ret${_retval}.cxx" @ONLY)
-endforeach ()
-
-include_directories(${CMake_SOURCE_DIR}/Source ${CMake_BINARY_DIR}/Source)
-
-# create binaries that we will use as a pseudo memory checker
-add_executable(pseudo_valgrind "${CMAKE_CURRENT_BINARY_DIR}/ret0.cxx")
-set_target_properties(pseudo_valgrind PROPERTIES OUTPUT_NAME valgrind)
-target_link_libraries(pseudo_valgrind CMakeLib)
-
-# Xcode 2.x forgets to create the output directory before linking
-# the individual architectures.
-if(CMAKE_OSX_ARCHITECTURES AND XCODE AND NOT "${XCODE_VERSION}" MATCHES "^[^12]")
- add_custom_command(TARGET pseudo_valgrind
- PRE_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CFG_INTDIR}"
- )
-endif()
-
-add_executable(pseudo_purify "${CMAKE_CURRENT_BINARY_DIR}/ret0.cxx")
-set_target_properties(pseudo_purify PROPERTIES OUTPUT_NAME purify)
-target_link_libraries(pseudo_purify CMakeLib)
-add_executable(pseudo_BC "${CMAKE_CURRENT_BINARY_DIR}/ret0.cxx")
-set_target_properties(pseudo_BC PROPERTIES OUTPUT_NAME BC)
-target_link_libraries(pseudo_BC CMakeLib)
-
-# binary to be used as pre- and post-memcheck command that fails
-add_executable(memcheck_fail "${CMAKE_CURRENT_BINARY_DIR}/ret1.cxx")
-target_link_libraries(memcheck_fail CMakeLib)
-
-# Binaries that are used as memchecker that do not write the expected
-# output file. Need to be in their own subdirectory as they have the
-# same filenames.
-add_subdirectory(NoLogDummyChecker)
-
-if (APPLE)
- # filter out additional messages by Guard Malloc integrated in Xcode
- set(GUARD_MALLOC_MSG "(ctest\([0-9]+\) malloc: [^\n]*\n)*")
- set(NORMAL_CTEST_OUTPUT "\n1/1 MemCheck #1: RunCMake \\.+ Passed +[0-9]+\\.[0-9]+ sec\n${GUARD_MALLOC_MSG}\n${GUARD_MALLOC_MSG}100% tests passed, 0 tests failed out of 1\n.*\n-- Processing memory checking output: \n${GUARD_MALLOC_MSG}Memory checking results:\n${GUARD_MALLOC_MSG}")
-else ()
- set(NORMAL_CTEST_OUTPUT "\n1/1 MemCheck #1: RunCMake \\.+ Passed +[0-9]+\\.[0-9]+ sec\n\n100% tests passed, 0 tests failed out of 1\n.*\n-- Processing memory checking output: \nMemory checking results:\n")
-endif ()
-set(BULLSEYE_MSG "(BullseyeCoverage[^\n]*\n)?")
-
-function(gen_mc_test_internal NAME CHECKER)
- set(SUBTEST_NAME "${NAME}")
- set(CHECKER_COMMAND "${CHECKER}")
- foreach(_file IN ITEMS CMakeLists.txt CTestConfig.cmake test.cmake)
- configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${_file}.in"
- "${CMAKE_CURRENT_BINARY_DIR}/${NAME}/${_file}" @ONLY)
- endforeach()
- add_test(NAME CTestTestMemcheck${NAME}
- COMMAND ${CMAKE_CTEST_COMMAND}
- -C $<CONFIGURATION>
- -S "${CMAKE_CURRENT_BINARY_DIR}/${NAME}/test.cmake" -V
- --output-log "${CMAKE_CURRENT_BINARY_DIR}/${NAME}/testOutput.log"
- ${ARGN}
- )
-endfunction(gen_mc_test_internal)
-
-function(gen_mc_test NAME CHECKER)
- gen_mc_test_internal(${NAME} "${CHECKER}"
- -D PSEUDO_BC=$<TARGET_FILE:pseudo_BC>
- -D PSEUDO_PURIFY=$<TARGET_FILE:pseudo_purify>
- -D PSEUDO_VALGRIND=$<TARGET_FILE:pseudo_valgrind>
- -D ERROR_COMMAND=$<TARGET_FILE:memcheck_fail>
- ${ARGN}
- )
-endfunction(gen_mc_test)
-
-function(gen_mcnl_test NAME CHECKER)
- gen_mc_test_internal(${NAME} ${CHECKER}
- -D PSEUDO_BC=$<TARGET_FILE:pseudonl_BC>
- -D PSEUDO_PURIFY=$<TARGET_FILE:pseudonl_purify>
- -D PSEUDO_VALGRIND=$<TARGET_FILE:pseudonl_valgrind>
- ${ARGN}
- )
- set_tests_properties(CTestTestMemcheck${NAME}
- PROPERTIES
- PASS_REGULAR_EXPRESSION "\nCannot find memory tester output file: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/${NAME}/Testing/Temporary/MemoryChecker.1.log\n(.*\n)?Error in read script: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/${NAME}/test.cmake\n")
-endfunction(gen_mcnl_test)
-
-unset(CTEST_EXTRA_CONFIG)
-unset(CTEST_EXTRA_CODE)
-unset(CMAKELISTS_EXTRA_CODE)
-
-gen_mc_test(DummyPurify "\${PSEUDO_PURIFY}")
-gen_mc_test(DummyValgrind "\${PSEUDO_VALGRIND}")
-gen_mc_test(DummyBC "\${PSEUDO_BC}")
-gen_mcnl_test(DummyPurifyNoLogfile "\${PSEUDO_PURIFY}")
-gen_mcnl_test(DummyValgrindNoLogfile "\${PSEUDO_VALGRIND}")
-gen_mcnl_test(DummyBCNoLogfile "\${PSEUDO_BC}")
-
-set(CTEST_EXTRA_CODE "string(REPLACE \" \" \"\\\\ \" PRE_POST_COMMAND \"\${CTEST_MEMORYCHECK_COMMAND}\")
-
-set(CTEST_CUSTOM_PRE_MEMCHECK \"\${PRE_POST_COMMAND} pre command\")
-set(CTEST_CUSTOM_POST_MEMCHECK \"\${PRE_POST_COMMAND} post command \")
-")
-gen_mc_test(DummyValgrindPrePost "\${PSEUDO_VALGRIND}")
-
-set(CTEST_EXTRA_CODE "set(CTEST_CUSTOM_POST_MEMCHECK \"\${ERROR_COMMAND}\")")
-gen_mc_test(DummyValgrindFailPost "\${PSEUDO_VALGRIND}")
-
-set(CTEST_EXTRA_CODE "set(CTEST_CUSTOM_PRE_MEMCHECK \"\${ERROR_COMMAND}\")")
-gen_mc_test(DummyValgrindFailPre "\${PSEUDO_VALGRIND}")
-
-unset(CTEST_EXTRA_CODE)
-set(CTEST_EXTRA_CONFIG "set(CTEST_CUSTOM_MEMCHECK_IGNORE RunCMakeAgain)\n")
-set(CMAKELISTS_EXTRA_CODE "add_test(NAME RunCMakeAgain COMMAND \"\${CMAKE_COMMAND}\" --version)")
-gen_mc_test(DummyValgrindIgnoreMemcheck "\${PSEUDO_VALGRIND}")
-
-unset(CTEST_EXTRA_CONFIG)
-gen_mc_test(DummyValgrindTwoTargets "\${PSEUDO_VALGRIND}" "-VV")
-
-set(CTEST_EXTRA_CONFIG "set(CTEST_MEMORYCHECK_SUPPRESSIONS_FILE \"\${CMAKE_CURRENT_BINARY_DIR}/does-not-exist\")")
-unset(CMAKELISTS_EXTRA_CODE)
-gen_mc_test(DummyValgrindInvalidSupFile "\${PSEUDO_VALGRIND}")
-
-# CTest will add the logfile option before any custom options. Set the logfile
-# again, this time to an empty string. This will cause the logfile to be
-# missing, which will be the prove for us that the custom option is indeed used.
-set(CTEST_EXTRA_CONFIG "set(CTEST_MEMORYCHECK_COMMAND_OPTIONS \"--log-file=\")")
-gen_mc_test(DummyValgrindCustomOptions "\${PSEUDO_VALGRIND}")
-
-unset(CTEST_EXTRA_CONFIG)
-gen_mc_test(NotExist "\${CTEST_BINARY_DIRECTORY}/no-memcheck-exe")
-
-gen_mc_test(Unknown "${CMAKE_COMMAND}")
-
-string(REPLACE "\\" "\\\\" CMAKE_COMMAND_ESCAPED "${CMAKE_COMMAND}")
-string(REPLACE "(" "\\(" CMAKE_COMMAND_ESCAPED "${CMAKE_COMMAND_ESCAPED}")
-string(REPLACE ")" "\\)" CMAKE_COMMAND_ESCAPED "${CMAKE_COMMAND_ESCAPED}")
-string(REPLACE "+" "\\+" CMAKE_COMMAND_ESCAPED "${CMAKE_COMMAND_ESCAPED}")
-
-set_tests_properties(CTestTestMemcheckUnknown PROPERTIES
- PASS_REGULAR_EXPRESSION "Do not understand memory checker: ${CMAKE_COMMAND_ESCAPED}\n(.*\n)?Error in read script: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/Unknown/test.cmake\n")
-
-set_tests_properties(CTestTestMemcheckNotExist PROPERTIES
- PASS_REGULAR_EXPRESSION "Memory checker \\(MemoryCheckCommand\\) not set, or cannot find the specified program.")
-
-# It is a valid result if valgrind does not output any files (can e.g. happen
-# if you have not compiled in debug mode), so these tests will not fail.
-set_tests_properties(CTestTestMemcheckDummyValgrind
- CTestTestMemcheckDummyValgrindPrePost
- CTestTestMemcheckDummyPurify
- PROPERTIES
- PASS_REGULAR_EXPRESSION "${NORMAL_CTEST_OUTPUT}${BULLSEYE_MSG}$")
-
-foreach (_pp Pre Post)
- string(TOLOWER ${_pp} _pp_lower)
- set_tests_properties(CTestTestMemcheckDummyValgrindFail${_pp}
- PROPERTIES
- PASS_REGULAR_EXPRESSION "\nProblem running command: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}[^\n]*fail[^\n]*\n(.*\n)?Problem executing ${_pp_lower}-memcheck command\\(s\\\).\n(.*\n)?Error in read script: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindFail${_pp}/test.cmake\n")
-endforeach ()
-
-set_tests_properties(CTestTestMemcheckDummyValgrindIgnoreMemcheck
- PROPERTIES
- PASS_REGULAR_EXPRESSION "\n2/2 Test #2: RunCMakeAgain .*${NORMAL_CTEST_OUTPUT}${BULLSEYE_MSG}$")
-
-set_tests_properties(CTestTestMemcheckDummyBC PROPERTIES
- PASS_REGULAR_EXPRESSION "\n1/1 MemCheck #1: RunCMake \\.+ Passed +[0-9]+.[0-9]+ sec\n\n100% tests passed, 0 tests failed out of 1\n(.*\n)?Error parsing XML in stream at line 1: no element found\n")
-
-set_tests_properties(CTestTestMemcheckDummyValgrindInvalidSupFile PROPERTIES
- PASS_REGULAR_EXPRESSION "\nCannot find memory checker suppression file: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/does-not-exist\n")
-
-set_tests_properties(CTestTestMemcheckDummyValgrindCustomOptions PROPERTIES
- PASS_REGULAR_EXPRESSION "\nCannot find memory tester output file: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindCustomOptions/Testing/Temporary/MemoryChecker.1.log\n(.*\n)?Error in read script: ${CMAKE_CURRENT_BINARY_DIR}/DummyValgrindCustomOptions/test.cmake\n")
-
-set_tests_properties(CTestTestMemcheckDummyValgrindTwoTargets PROPERTIES
- PASS_REGULAR_EXPRESSION
- "\nMemory check project ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindTwoTargets\n.*\n *Start 1: RunCMake\n(.*\n)?Memory check command: .* \"--log-file=${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindTwoTargets/Testing/Temporary/MemoryChecker.1.log\" \"-q\".*\n *Start 2: RunCMakeAgain\n(.*\n)?Memory check command: .* \"--log-file=${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindTwoTargets/Testing/Temporary/MemoryChecker.2.log\" \"-q\".*\n")
diff --git a/Tests/CTestTestMemcheck/CMakeLists.txt.in b/Tests/CTestTestMemcheck/CMakeLists.txt.in
deleted file mode 100644
index e28e56a9a..000000000
--- a/Tests/CTestTestMemcheck/CMakeLists.txt.in
+++ /dev/null
@@ -1,7 +0,0 @@
-cmake_minimum_required(VERSION 2.8.9)
-project(CTestTestMemcheck@SUBTEST_NAME@)
-include(CTest)
-
-add_test(NAME RunCMake COMMAND "${CMAKE_COMMAND}" --version)
-
-@CMAKELISTS_EXTRA_CODE@
diff --git a/Tests/CTestTestMemcheck/CTestConfig.cmake.in b/Tests/CTestTestMemcheck/CTestConfig.cmake.in
deleted file mode 100644
index 6cf37828f..000000000
--- a/Tests/CTestTestMemcheck/CTestConfig.cmake.in
+++ /dev/null
@@ -1,9 +0,0 @@
-set (CTEST_PROJECT_NAME "CTestTestMemcheck@SUBTEST_NAME@")
-set (CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
-set (CTEST_DART_SERVER_VERSION "2")
-set(CTEST_DROP_METHOD "http")
-set(CTEST_DROP_SITE "www.cdash.org")
-set(CTEST_DROP_LOCATION "/CDash/submit.php?project=PublicDashboard")
-set(CTEST_DROP_SITE_CDASH TRUE)
-
-@CTEST_EXTRA_CONFIG@
diff --git a/Tests/CTestTestMemcheck/NoLogDummyChecker/CMakeLists.txt b/Tests/CTestTestMemcheck/NoLogDummyChecker/CMakeLists.txt
deleted file mode 100644
index c5aa2cdbd..000000000
--- a/Tests/CTestTestMemcheck/NoLogDummyChecker/CMakeLists.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-# A dummy checker implementation that does not write the requested output file
-# so it triggers an error for every checker.
-
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/ret0.c" "int main(){return 0;}\n")
-
-foreach(_pseudo IN ITEMS valgrind purify BC)
- add_executable(pseudonl_${_pseudo} "${CMAKE_CURRENT_BINARY_DIR}/ret0.c")
- set_target_properties(pseudonl_${_pseudo} PROPERTIES OUTPUT_NAME ${_pseudo})
-endforeach()
-
-# Xcode 2.x forgets to create the output directory before linking
-# the individual architectures.
-if(CMAKE_OSX_ARCHITECTURES AND XCODE AND NOT "${XCODE_VERSION}" MATCHES "^[^12]")
- add_custom_command(TARGET pseudonl_valgrind
- PRE_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CFG_INTDIR}"
- )
-endif()
diff --git a/Tests/CTestTestMemcheck/memtester.cxx.in b/Tests/CTestTestMemcheck/memtester.cxx.in
deleted file mode 100644
index 55a34e34f..000000000
--- a/Tests/CTestTestMemcheck/memtester.cxx.in
+++ /dev/null
@@ -1,52 +0,0 @@
-#include <cmSystemTools.h>
-#include <string>
-
-#define RETVAL @_retval@
-
-int
-main(int argc, char **argv)
-{
- std::string exename = argv[0];
- std::string logarg;
- bool nextarg = false;
-
- if (exename.find("valgrind") != exename.npos)
- logarg = "--log-file=";
- else if (exename.find("purify") != exename.npos)
-#ifdef _WIN32
- logarg = "/SAVETEXTDATA=";
-#else
- logarg = "-log-file=";
-#endif
- else if (exename.find("BC") != exename.npos)
- {
- nextarg = true;
- logarg = "/X";
- }
-
- if (!logarg.empty()) {
- std::string logfile;
- for (int i = 1; i < argc; i++) {
- std::string arg = argv[i];
- if (arg.find(logarg) == 0)
- {
- if (nextarg)
- {
- if (i == argc - 1)
- return 1; // invalid command line
- logfile = argv[i + 1];
- }
- else
- {
- logfile = arg.substr(logarg.length());
- }
- // keep searching, it may be overridden later to provoke an error
- }
- }
-
- if (!logfile.empty())
- cmSystemTools::Touch(logfile.c_str(), true);
- }
-
- return RETVAL;
-}
diff --git a/Tests/CTestTestMemcheck/test.cmake.in b/Tests/CTestTestMemcheck/test.cmake.in
deleted file mode 100644
index 6c388c52c..000000000
--- a/Tests/CTestTestMemcheck/test.cmake.in
+++ /dev/null
@@ -1,24 +0,0 @@
-cmake_minimum_required(VERSION 2.8.9)
-
-# Settings:
-set(CTEST_DASHBOARD_ROOT "@CMAKE_CURRENT_BINARY_DIR@")
-set(CTEST_SITE "@SITE@")
-set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-Memcheck@SUBTEST_NAME@")
-
-set(CTEST_SOURCE_DIRECTORY "@CMAKE_CURRENT_BINARY_DIR@/@SUBTEST_NAME@")
-set(CTEST_BINARY_DIRECTORY "@CMAKE_CURRENT_BINARY_DIR@/@SUBTEST_NAME@")
-set(CTEST_CVS_COMMAND "@CVSCOMMAND@")
-set(CTEST_CMAKE_GENERATOR "@CMAKE_TEST_GENERATOR@")
-set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_TEST_GENERATOR_TOOLSET@")
-set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
-set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
-set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
-
-set(CTEST_MEMORYCHECK_COMMAND "@CHECKER_COMMAND@")
-
-@CTEST_EXTRA_CODE@
-
-CTEST_START(Experimental)
-CTEST_CONFIGURE(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
-CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
-CTEST_MEMCHECK(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
diff --git a/Tests/CTestTestMissingDependsExe/CMakeLists.txt b/Tests/CTestTestMissingDependsExe/CMakeLists.txt
new file mode 100644
index 000000000..9826da661
--- /dev/null
+++ b/Tests/CTestTestMissingDependsExe/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 2.8.12)
+
+project(CTestTestMissingDependsExe)
+
+enable_testing()
+
+add_test(test1 ${CMAKE_COMMAND} -E echo test)
+add_test(test2 non-existent-command)
+
+set_tests_properties(test1 PROPERTIES DEPENDS test2)
diff --git a/Tests/CTestTestParallel/CTestConfig.cmake b/Tests/CTestTestParallel/CTestConfig.cmake
index c3c503881..fc5b6668e 100644
--- a/Tests/CTestTestParallel/CTestConfig.cmake
+++ b/Tests/CTestTestParallel/CTestConfig.cmake
@@ -2,6 +2,6 @@ set(CTEST_PROJECT_NAME "CTestTestParallel")
set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
set(CTEST_DART_SERVER_VERSION "2")
set(CTEST_DROP_METHOD "http")
-set(CTEST_DROP_SITE "www.cdash.org")
-set(CTEST_DROP_LOCATION "/CDash/submit.php?project=PublicDashboard")
+set(CTEST_DROP_SITE "open.cdash.org")
+set(CTEST_DROP_LOCATION "/submit.php?project=PublicDashboard")
set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Tests/CTestTestParallel/test.cmake.in b/Tests/CTestTestParallel/test.cmake.in
index a0d9fb3a1..045a4ca06 100644
--- a/Tests/CTestTestParallel/test.cmake.in
+++ b/Tests/CTestTestParallel/test.cmake.in
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.1)
+cmake_minimum_required(VERSION 2.4)
# Settings:
set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
@@ -8,8 +8,9 @@ set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-Parallel")
set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestParallel")
set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestParallel")
set(CTEST_CVS_COMMAND "@CVSCOMMAND@")
-set(CTEST_CMAKE_GENERATOR "@CMAKE_TEST_GENERATOR@")
-set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_TEST_GENERATOR_TOOLSET@")
+set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@")
set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
diff --git a/Tests/CTestTestResourceLock/CTestConfig.cmake b/Tests/CTestTestResourceLock/CTestConfig.cmake
index 5fb560b87..c1187778d 100644
--- a/Tests/CTestTestResourceLock/CTestConfig.cmake
+++ b/Tests/CTestTestResourceLock/CTestConfig.cmake
@@ -2,6 +2,6 @@ set(CTEST_PROJECT_NAME "CTestTestResourceLock")
set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
set(CTEST_DART_SERVER_VERSION "2")
set(CTEST_DROP_METHOD "http")
-set(CTEST_DROP_SITE "www.cdash.org")
-set(CTEST_DROP_LOCATION "/CDash/submit.php?project=PublicDashboard")
+set(CTEST_DROP_SITE "open.cdash.org")
+set(CTEST_DROP_LOCATION "/submit.php?project=PublicDashboard")
set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Tests/CTestTestResourceLock/test.cmake.in b/Tests/CTestTestResourceLock/test.cmake.in
index 1e7e34480..67dde1803 100644
--- a/Tests/CTestTestResourceLock/test.cmake.in
+++ b/Tests/CTestTestResourceLock/test.cmake.in
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.1)
+cmake_minimum_required(VERSION 2.4)
# Settings:
set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
@@ -8,8 +8,9 @@ set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-ResourceLock")
set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestResourceLock")
set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestResourceLock")
set(CTEST_CVS_COMMAND "@CVSCOMMAND@")
-set(CTEST_CMAKE_GENERATOR "@CMAKE_TEST_GENERATOR@")
-set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_TEST_GENERATOR_TOOLSET@")
+set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@")
set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
diff --git a/Tests/CTestTestScheduler/CTestConfig.cmake b/Tests/CTestTestScheduler/CTestConfig.cmake
index 7da8f6f53..797387bdd 100644
--- a/Tests/CTestTestScheduler/CTestConfig.cmake
+++ b/Tests/CTestTestScheduler/CTestConfig.cmake
@@ -2,6 +2,6 @@ set(CTEST_PROJECT_NAME "CTestTestScheduler")
set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
set(CTEST_DART_SERVER_VERSION "2")
set(CTEST_DROP_METHOD "http")
-set(CTEST_DROP_SITE "www.cdash.org")
-set(CTEST_DROP_LOCATION "/CDash/submit.php?project=PublicDashboard")
+set(CTEST_DROP_SITE "open.cdash.org")
+set(CTEST_DROP_LOCATION "/submit.php?project=PublicDashboard")
set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Tests/CTestTestScheduler/test.cmake.in b/Tests/CTestTestScheduler/test.cmake.in
index 8ad6137eb..f8c8ab747 100644
--- a/Tests/CTestTestScheduler/test.cmake.in
+++ b/Tests/CTestTestScheduler/test.cmake.in
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.1)
+cmake_minimum_required(VERSION 2.4)
# Settings:
set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
@@ -8,8 +8,9 @@ set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-Scheduler")
set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestScheduler")
set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestScheduler")
set(CTEST_CVS_COMMAND "@CVSCOMMAND@")
-set(CTEST_CMAKE_GENERATOR "@CMAKE_TEST_GENERATOR@")
-set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_TEST_GENERATOR_TOOLSET@")
+set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@")
set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
diff --git a/Tests/CTestTestSerialInDepends/CMakeLists.txt b/Tests/CTestTestSerialInDepends/CMakeLists.txt
new file mode 100644
index 000000000..90e50f982
--- /dev/null
+++ b/Tests/CTestTestSerialInDepends/CMakeLists.txt
@@ -0,0 +1,23 @@
+cmake_minimum_required(VERSION 2.8.12)
+
+project(CTestTestSerialInDepends)
+
+enable_testing()
+
+function(my_add_test NAME COST)
+ add_test(NAME ${NAME}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${CMAKE_CTEST_COMMAND} -DTEST_NAME=${NAME}
+ -S ${CMAKE_CURRENT_SOURCE_DIR}/test.ctest)
+ set_tests_properties(${NAME} PROPERTIES COST ${COST})
+endfunction()
+
+my_add_test(i_like_company 1000)
+my_add_test(i_like_company_too 0)
+
+my_add_test(i_have_dependencies 1000)
+set_tests_properties(i_have_dependencies PROPERTIES
+ DEPENDS "i_want_to_be_alone")
+
+my_add_test(i_want_to_be_alone 100)
+set_tests_properties(i_want_to_be_alone PROPERTIES RUN_SERIAL 1)
diff --git a/Tests/CTestTestSerialInDepends/test.ctest b/Tests/CTestTestSerialInDepends/test.ctest
new file mode 100644
index 000000000..28ee09436
--- /dev/null
+++ b/Tests/CTestTestSerialInDepends/test.ctest
@@ -0,0 +1,16 @@
+set(CTEST_RUN_CURRENT_SCRIPT 0)
+
+set(LOCK_FILE "${TEST_NAME}.lock")
+
+if("${TEST_NAME}" STREQUAL "i_want_to_be_alone")
+ file(GLOB LOCK_FILES *.lock)
+ if(LOCK_FILES)
+ message(FATAL_ERROR "found lock files of other tests even though this test should be running by itself: ${LOCK_FILES}")
+ endif()
+endif()
+
+file(WRITE "${LOCK_FILE}")
+ctest_sleep(3)
+file(REMOVE "${LOCK_FILE}")
+
+return()
diff --git a/Tests/CTestTestSerialOrder/CMakeLists.txt b/Tests/CTestTestSerialOrder/CMakeLists.txt
new file mode 100644
index 000000000..69c11fcde
--- /dev/null
+++ b/Tests/CTestTestSerialOrder/CMakeLists.txt
@@ -0,0 +1,40 @@
+cmake_minimum_required(VERSION 2.8.12)
+
+project(CTestTestSerialOrder)
+
+set(TEST_OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/test_output.txt")
+
+enable_testing()
+
+function(add_serial_order_test TEST_NAME)
+ add_test(NAME ${TEST_NAME}
+ COMMAND ${CMAKE_COMMAND}
+ "-DTEST_OUTPUT_FILE=${TEST_OUTPUT_FILE}"
+ "-DTEST_NAME=${TEST_NAME}"
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/test.cmake"
+ )
+
+ if(ARGC GREATER 1)
+ set_tests_properties(${TEST_NAME} PROPERTIES ${ARGN})
+ endif()
+endfunction()
+
+add_serial_order_test(initialization COST 1000)
+add_serial_order_test(test1)
+add_serial_order_test(test2)
+add_serial_order_test(test3)
+add_serial_order_test(test4 DEPENDS test5)
+
+add_serial_order_test(test5)
+set_tests_properties(test5 PROPERTIES DEPENDS "test6;test7b;test7a")
+
+add_serial_order_test(test6 COST -2)
+add_serial_order_test(test7a COST -1)
+add_serial_order_test(test7b COST -1)
+add_serial_order_test(test8 COST 10)
+add_serial_order_test(test9 COST 20)
+add_serial_order_test(test10 COST 0)
+add_serial_order_test(test11)
+add_serial_order_test(test12 COST 0)
+
+add_serial_order_test(verification COST -1000)
diff --git a/Tests/CTestTestSerialOrder/test.cmake b/Tests/CTestTestSerialOrder/test.cmake
new file mode 100644
index 000000000..8479cae95
--- /dev/null
+++ b/Tests/CTestTestSerialOrder/test.cmake
@@ -0,0 +1,31 @@
+list(APPEND EXPECTED_OUTPUT
+ initialization
+ test9
+ test8
+ test1
+ test2
+ test3
+ test6
+ test7a
+ test7b
+ test5
+ test4
+ test10
+ test11
+ test12
+)
+
+
+if("${TEST_NAME}" STREQUAL "initialization")
+ file(WRITE ${TEST_OUTPUT_FILE} "${TEST_NAME}")
+
+elseif("${TEST_NAME}" STREQUAL "verification")
+ file(READ ${TEST_OUTPUT_FILE} ACTUAL_OUTPUT)
+ if(NOT "${ACTUAL_OUTPUT}" STREQUAL "${EXPECTED_OUTPUT}")
+ message(FATAL_ERROR "Actual test order [${ACTUAL_OUTPUT}] differs from expected test order [${EXPECTED_OUTPUT}]")
+ endif()
+
+else()
+ file(APPEND ${TEST_OUTPUT_FILE} ";${TEST_NAME}")
+
+endif()
diff --git a/Tests/CTestTestSkipReturnCode/CMakeLists.txt b/Tests/CTestTestSkipReturnCode/CMakeLists.txt
new file mode 100644
index 000000000..26c4178fd
--- /dev/null
+++ b/Tests/CTestTestSkipReturnCode/CMakeLists.txt
@@ -0,0 +1,8 @@
+cmake_minimum_required(VERSION 2.8.12)
+project(CTestTestSkipReturnCode)
+include(CTest)
+
+add_test (NAME CMakeV1 COMMAND ${CMAKE_COMMAND} "--version")
+add_test (NAME CMakeV2 COMMAND ${CMAKE_COMMAND} "--version")
+
+set_tests_properties(CMakeV2 PROPERTIES SKIP_RETURN_CODE 0)
diff --git a/Tests/CTestTestSkipReturnCode/CTestConfig.cmake b/Tests/CTestTestSkipReturnCode/CTestConfig.cmake
new file mode 100644
index 000000000..da0c76b73
--- /dev/null
+++ b/Tests/CTestTestSkipReturnCode/CTestConfig.cmake
@@ -0,0 +1,7 @@
+set (CTEST_PROJECT_NAME "CTestTestSkipReturnCode")
+set (CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
+set (CTEST_DART_SERVER_VERSION "2")
+set(CTEST_DROP_METHOD "http")
+set(CTEST_DROP_SITE "open.cdash.org")
+set(CTEST_DROP_LOCATION "/submit.php?project=PublicDashboard")
+set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Tests/CTestTestSkipReturnCode/test.cmake.in b/Tests/CTestTestSkipReturnCode/test.cmake.in
new file mode 100644
index 000000000..112b0cd0f
--- /dev/null
+++ b/Tests/CTestTestSkipReturnCode/test.cmake.in
@@ -0,0 +1,23 @@
+cmake_minimum_required(VERSION 2.4)
+
+# Settings:
+set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
+set(CTEST_SITE "@SITE@")
+set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-SkipReturnCode")
+
+set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestSkipReturnCode")
+set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestSkipReturnCode")
+set(CTEST_CVS_COMMAND "@CVSCOMMAND@")
+set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@")
+set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
+set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
+set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
+
+#CTEST_EMPTY_BINARY_DIRECTORY(${CTEST_BINARY_DIRECTORY})
+
+CTEST_START(Experimental)
+CTEST_CONFIGURE(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
+CTEST_BUILD(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
+CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
diff --git a/Tests/CTestTestStopTime/CTestConfig.cmake b/Tests/CTestTestStopTime/CTestConfig.cmake
index 129db4dea..412283e69 100644
--- a/Tests/CTestTestStopTime/CTestConfig.cmake
+++ b/Tests/CTestTestStopTime/CTestConfig.cmake
@@ -2,6 +2,6 @@ set (CTEST_PROJECT_NAME "CTestTestStopTime")
set (CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
set (CTEST_DART_SERVER_VERSION "2")
set(CTEST_DROP_METHOD "http")
-set(CTEST_DROP_SITE "www.cdash.org")
-set(CTEST_DROP_LOCATION "/CDash/submit.php?project=PublicDashboard")
+set(CTEST_DROP_SITE "open.cdash.org")
+set(CTEST_DROP_LOCATION "/submit.php?project=PublicDashboard")
set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Tests/CTestTestStopTime/GetDate.cmake b/Tests/CTestTestStopTime/GetDate.cmake
index 60f1e0c74..edc65192c 100644
--- a/Tests/CTestTestStopTime/GetDate.cmake
+++ b/Tests/CTestTestStopTime/GetDate.cmake
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.2)
+cmake_minimum_required(VERSION 2.8.11)
macro(GET_DATE)
#
@@ -13,10 +13,7 @@ macro(GET_DATE)
# ${GD_PREFIX}PREFIX (if '${GD_PREFIX}' is not 'GD_'...!)
# ${GD_PREFIX}VERBOSE
#
- # ${GD_PREFIX}CMD
- # ${GD_PREFIX}ARGS
# ${GD_PREFIX}OV
- # ${GD_PREFIX}RV
#
# ${GD_PREFIX}REGEX
# ${GD_PREFIX}YEAR
@@ -25,8 +22,6 @@ macro(GET_DATE)
# ${GD_PREFIX}HOUR
# ${GD_PREFIX}MINUTE
# ${GD_PREFIX}SECOND
- # ${GD_PREFIX}FRACTIONAL_SECOND
- # ${GD_PREFIX}DAY_OF_WEEK
#
# Caller can then use these variables to construct names based on
# date and time stamps...
@@ -51,31 +46,10 @@ macro(GET_DATE)
# Retrieve the current date and time in the format:
#
- # Thu 01/12/2006 8:55:12.01
- # dow mm/dd/YYYY HH:MM:SS.ssssss
+ # 01/12/2006 08:55:12
+ # mm/dd/YYYY HH:MM:SS
#
- # Use "echo %DATE% %TIME%" on Windows.
- # Otherwise, try "date" as implemented on most Unix flavors.
- #
- if(WIN32)
- #
- # Use "cmd" shell with %DATE% and %TIME% support...
- # May need adjustment in different locales or for custom date/time formats
- # set in the Windows Control Panel.
- #
- set(${GD_PREFIX}CMD "cmd")
- set(${GD_PREFIX}ARGS "/c echo %DATE% %TIME%")
- else()
- #
- # Match the format returned by default in US English Windows:
- #
- set(${GD_PREFIX}CMD "date")
- set(${GD_PREFIX}ARGS "\"+%a %m/%d/%Y %H:%M:%S.00\"")
- endif()
-
- exec_program("${${GD_PREFIX}CMD}" "." ARGS "${${GD_PREFIX}ARGS}"
- OUTPUT_VARIABLE ${GD_PREFIX}OV RETURN_VALUE ${GD_PREFIX}RV
- )
+ string(TIMESTAMP "${GD_PREFIX}OV" "%m/%d/%Y %H:%M:%S")
if(${GD_PREFIX}VERBOSE)
message(STATUS "")
@@ -87,114 +61,39 @@ macro(GET_DATE)
endif()
message(STATUS "${GD_PREFIX}VERBOSE='${${GD_PREFIX}VERBOSE}'")
message(STATUS "")
- message(STATUS "${GD_PREFIX}CMD='${${GD_PREFIX}CMD}'")
- message(STATUS "${GD_PREFIX}ARGS='${${GD_PREFIX}ARGS}'")
message(STATUS "${GD_PREFIX}OV='${${GD_PREFIX}OV}'")
- message(STATUS "${GD_PREFIX}RV='${${GD_PREFIX}RV}'")
message(STATUS "")
endif()
- if("${${GD_PREFIX}RV}" STREQUAL "0")
- #
- # Extract eight individual components by matching a regex with paren groupings.
- # Use the replace functionality and \\1 thru \\8 to extract components.
- #
- set(${GD_PREFIX}REGEX "([^ ]+) +([^/]+)/([^/]+)/([^ ]+) +([^:]+):([^:]+):([^\\.]+)\\.(.*)")
-
- string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\1" ${GD_PREFIX}DAY_OF_WEEK "${${GD_PREFIX}OV}")
- string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\2" ${GD_PREFIX}MONTH "${${GD_PREFIX}OV}")
- string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\3" ${GD_PREFIX}DAY "${${GD_PREFIX}OV}")
- string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\4" ${GD_PREFIX}YEAR "${${GD_PREFIX}OV}")
- string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\5" ${GD_PREFIX}HOUR "${${GD_PREFIX}OV}")
- string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\6" ${GD_PREFIX}MINUTE "${${GD_PREFIX}OV}")
- string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\7" ${GD_PREFIX}SECOND "${${GD_PREFIX}OV}")
- string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\8" ${GD_PREFIX}FRACTIONAL_SECOND "${${GD_PREFIX}OV}")
-
- #
- # Verify that extracted components don't have anything obviously
- # wrong with them... Emit warnings if something looks suspicious...
- #
-
- # Expecting a four digit year:
- #
- if(NOT "${${GD_PREFIX}YEAR}" MATCHES "^[0-9][0-9][0-9][0-9]$")
- message(STATUS "WARNING: Extracted ${GD_PREFIX}YEAR='${${GD_PREFIX}YEAR}' is not a four digit number...")
- endif()
-
- # Expecting month to be <= 12:
- #
- if(${${GD_PREFIX}MONTH} GREATER 12)
- message(STATUS "WARNING: Extracted ${GD_PREFIX}MONTH='${${GD_PREFIX}MONTH}' is greater than 12!")
- endif()
-
- # Expecting day to be <= 31:
- #
- if(${${GD_PREFIX}DAY} GREATER 31)
- message(STATUS "WARNING: Extracted ${GD_PREFIX}DAY='${${GD_PREFIX}DAY}' is greater than 31!")
- endif()
-
- # Expecting hour to be <= 23:
- #
- if(${${GD_PREFIX}HOUR} GREATER 23)
- message(STATUS "WARNING: Extracted ${GD_PREFIX}HOUR='${${GD_PREFIX}HOUR}' is greater than 23!")
- endif()
-
- # Expecting minute to be <= 59:
- #
- if(${${GD_PREFIX}MINUTE} GREATER 59)
- message(STATUS "WARNING: Extracted ${GD_PREFIX}MINUTE='${${GD_PREFIX}MINUTE}' is greater than 59!")
- endif()
-
- # Expecting second to be <= 59:
- #
- if(${${GD_PREFIX}SECOND} GREATER 59)
- message(STATUS "WARNING: Extracted ${GD_PREFIX}SECOND='${${GD_PREFIX}SECOND}' is greater than 59!")
- endif()
+ #
+ # Extract six individual components by matching a regex with paren groupings.
+ # Use the replace functionality and \\1 thru \\6 to extract components.
+ #
+ set(${GD_PREFIX}REGEX "([^/]+)/([^/]+)/([^ ]+) +([^:]+):([^:]+):([^\\.]+)")
- # If individual components are single digit,
- # prepend a leading zero:
- #
- if("${${GD_PREFIX}YEAR}" MATCHES "^[0-9]$")
- set(${GD_PREFIX}YEAR "0${${GD_PREFIX}YEAR}")
- endif()
- if("${${GD_PREFIX}MONTH}" MATCHES "^[0-9]$")
- set(${GD_PREFIX}MONTH "0${${GD_PREFIX}MONTH}")
- endif()
- if("${${GD_PREFIX}DAY}" MATCHES "^[0-9]$")
- set(${GD_PREFIX}DAY "0${${GD_PREFIX}DAY}")
- endif()
- if("${${GD_PREFIX}HOUR}" MATCHES "^[0-9]$")
- set(${GD_PREFIX}HOUR "0${${GD_PREFIX}HOUR}")
- endif()
- if("${${GD_PREFIX}MINUTE}" MATCHES "^[0-9]$")
- set(${GD_PREFIX}MINUTE "0${${GD_PREFIX}MINUTE}")
- endif()
- if("${${GD_PREFIX}SECOND}" MATCHES "^[0-9]$")
- set(${GD_PREFIX}SECOND "0${${GD_PREFIX}SECOND}")
- endif()
+ string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\1" ${GD_PREFIX}MONTH "${${GD_PREFIX}OV}")
+ string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\2" ${GD_PREFIX}DAY "${${GD_PREFIX}OV}")
+ string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\3" ${GD_PREFIX}YEAR "${${GD_PREFIX}OV}")
+ string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\4" ${GD_PREFIX}HOUR "${${GD_PREFIX}OV}")
+ string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\5" ${GD_PREFIX}MINUTE "${${GD_PREFIX}OV}")
+ string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\6" ${GD_PREFIX}SECOND "${${GD_PREFIX}OV}")
- if(${GD_PREFIX}VERBOSE)
- message(STATUS "${GD_PREFIX}REGEX='${${GD_PREFIX}REGEX}'")
- message(STATUS "${GD_PREFIX}YEAR='${${GD_PREFIX}YEAR}'")
- message(STATUS "${GD_PREFIX}MONTH='${${GD_PREFIX}MONTH}'")
- message(STATUS "${GD_PREFIX}DAY='${${GD_PREFIX}DAY}'")
- message(STATUS "${GD_PREFIX}HOUR='${${GD_PREFIX}HOUR}'")
- message(STATUS "${GD_PREFIX}MINUTE='${${GD_PREFIX}MINUTE}'")
- message(STATUS "${GD_PREFIX}SECOND='${${GD_PREFIX}SECOND}'")
- message(STATUS "${GD_PREFIX}FRACTIONAL_SECOND='${${GD_PREFIX}FRACTIONAL_SECOND}'")
- message(STATUS "${GD_PREFIX}DAY_OF_WEEK='${${GD_PREFIX}DAY_OF_WEEK}'")
- message(STATUS "")
- message(STATUS "Counters that change...")
- message(STATUS "")
- message(STATUS "...very very quickly : ${${GD_PREFIX}YEAR}${${GD_PREFIX}MONTH}${${GD_PREFIX}DAY}${${GD_PREFIX}HOUR}${${GD_PREFIX}MINUTE}${${GD_PREFIX}SECOND}${${GD_PREFIX}FRACTIONAL_SECOND}")
- message(STATUS " every second : ${${GD_PREFIX}YEAR}${${GD_PREFIX}MONTH}${${GD_PREFIX}DAY}${${GD_PREFIX}HOUR}${${GD_PREFIX}MINUTE}${${GD_PREFIX}SECOND}")
- message(STATUS " daily : ${${GD_PREFIX}YEAR}${${GD_PREFIX}MONTH}${${GD_PREFIX}DAY}")
- message(STATUS " monthly : ${${GD_PREFIX}YEAR}${${GD_PREFIX}MONTH}")
- message(STATUS " annually : ${${GD_PREFIX}YEAR}")
- message(STATUS "")
- endif()
- else()
- message(SEND_ERROR "ERROR: macro(GET_DATE) failed. ${GD_PREFIX}CMD='${${GD_PREFIX}CMD}' ${GD_PREFIX}ARGS='${${GD_PREFIX}ARGS}' ${GD_PREFIX}OV='${${GD_PREFIX}OV}' ${GD_PREFIX}RV='${${GD_PREFIX}RV}'")
+ if(${GD_PREFIX}VERBOSE)
+ message(STATUS "${GD_PREFIX}REGEX='${${GD_PREFIX}REGEX}'")
+ message(STATUS "${GD_PREFIX}YEAR='${${GD_PREFIX}YEAR}'")
+ message(STATUS "${GD_PREFIX}MONTH='${${GD_PREFIX}MONTH}'")
+ message(STATUS "${GD_PREFIX}DAY='${${GD_PREFIX}DAY}'")
+ message(STATUS "${GD_PREFIX}HOUR='${${GD_PREFIX}HOUR}'")
+ message(STATUS "${GD_PREFIX}MINUTE='${${GD_PREFIX}MINUTE}'")
+ message(STATUS "${GD_PREFIX}SECOND='${${GD_PREFIX}SECOND}'")
+ message(STATUS "")
+ message(STATUS "Counters that change...")
+ message(STATUS "")
+ message(STATUS " every second : ${${GD_PREFIX}YEAR}${${GD_PREFIX}MONTH}${${GD_PREFIX}DAY}${${GD_PREFIX}HOUR}${${GD_PREFIX}MINUTE}${${GD_PREFIX}SECOND}")
+ message(STATUS " daily : ${${GD_PREFIX}YEAR}${${GD_PREFIX}MONTH}${${GD_PREFIX}DAY}")
+ message(STATUS " monthly : ${${GD_PREFIX}YEAR}${${GD_PREFIX}MONTH}")
+ message(STATUS " annually : ${${GD_PREFIX}YEAR}")
+ message(STATUS "")
endif()
if(${GD_PREFIX}VERBOSE)
diff --git a/Tests/CTestTestStopTime/test.cmake.in b/Tests/CTestTestStopTime/test.cmake.in
index 6804789cc..d3a9a4a92 100644
--- a/Tests/CTestTestStopTime/test.cmake.in
+++ b/Tests/CTestTestStopTime/test.cmake.in
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.1)
+cmake_minimum_required(VERSION 2.4)
# Settings:
set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
@@ -8,8 +8,9 @@ set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-StopTime")
set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestStopTime")
set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestStopTime")
set(CTEST_CVS_COMMAND "@CVSCOMMAND@")
-set(CTEST_CMAKE_GENERATOR "@CMAKE_TEST_GENERATOR@")
-set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_TEST_GENERATOR_TOOLSET@")
+set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@")
set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
diff --git a/Tests/CTestTestSubdir/CTestConfig.cmake b/Tests/CTestTestSubdir/CTestConfig.cmake
index 4b848aa26..47ebb925c 100644
--- a/Tests/CTestTestSubdir/CTestConfig.cmake
+++ b/Tests/CTestTestSubdir/CTestConfig.cmake
@@ -2,6 +2,6 @@ set(CTEST_PROJECT_NAME "CTestTestSubdir")
set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
set(CTEST_DART_SERVER_VERSION "2")
set(CTEST_DROP_METHOD "http")
-set(CTEST_DROP_SITE "www.cdash.org")
-set(CTEST_DROP_LOCATION "/CDash/submit.php?project=PublicDashboard")
+set(CTEST_DROP_SITE "open.cdash.org")
+set(CTEST_DROP_LOCATION "/submit.php?project=PublicDashboard")
set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Tests/CTestTestSubdir/test.cmake.in b/Tests/CTestTestSubdir/test.cmake.in
index 526d453dd..8b3957b4e 100644
--- a/Tests/CTestTestSubdir/test.cmake.in
+++ b/Tests/CTestTestSubdir/test.cmake.in
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.1)
+cmake_minimum_required(VERSION 2.4)
# Settings:
set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
@@ -8,8 +8,9 @@ set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-Subdir")
set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestSubdir")
set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestSubdir")
set(CTEST_CVS_COMMAND "@CVSCOMMAND@")
-set(CTEST_CMAKE_GENERATOR "@CMAKE_TEST_GENERATOR@")
-set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_TEST_GENERATOR_TOOLSET@")
+set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@")
set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
diff --git a/Tests/CTestTestTimeout/CMakeLists.txt b/Tests/CTestTestTimeout/CMakeLists.txt
index 476d0a5e0..c6cbc4709 100644
--- a/Tests/CTestTestTimeout/CMakeLists.txt
+++ b/Tests/CTestTestTimeout/CMakeLists.txt
@@ -3,26 +3,19 @@ project(CTestTestTimeout)
include(CTest)
if(NOT TIMEOUT)
- if(CYGWIN)
- set(TIMEOUT 4) # Cygwin CMake sometimes takes > 1 second to load!
- else()
- set(TIMEOUT 1)
- endif()
+ # Give the process time to load and start running.
+ set(TIMEOUT 4)
endif()
add_definitions(-DTIMEOUT=${TIMEOUT})
-add_executable (Timeout timeout.c)
+add_executable (Sleep sleep.c)
add_test(NAME TestTimeout
- COMMAND ${CMAKE_COMMAND} -D Timeout=$<TARGET_FILE:Timeout>
+ COMMAND ${CMAKE_COMMAND} -D Sleep=$<TARGET_FILE:Sleep>
-D Log=${CMAKE_CURRENT_BINARY_DIR}/timeout.log
-P ${CMAKE_CURRENT_SOURCE_DIR}/timeout.cmake
)
set_tests_properties(TestTimeout PROPERTIES TIMEOUT ${TIMEOUT})
-add_test(NAME CheckChild
- COMMAND ${CMAKE_COMMAND} -D Timeout=$<TARGET_FILE:Timeout>
- -D Log=${CMAKE_CURRENT_BINARY_DIR}/timeout.log
- -P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake
- )
-set_tests_properties(CheckChild PROPERTIES DEPENDS TestTimeout)
+add_test(NAME TestSleep COMMAND Sleep)
+set_tests_properties(TestSleep PROPERTIES DEPENDS TestTimeout)
diff --git a/Tests/CTestTestTimeout/CTestConfig.cmake b/Tests/CTestTestTimeout/CTestConfig.cmake
index 76d62ad27..13114f1ca 100644
--- a/Tests/CTestTestTimeout/CTestConfig.cmake
+++ b/Tests/CTestTestTimeout/CTestConfig.cmake
@@ -2,6 +2,6 @@ set(CTEST_PROJECT_NAME "CTestTestTimeout")
set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
set(CTEST_DART_SERVER_VERSION "2")
set(CTEST_DROP_METHOD "http")
-set(CTEST_DROP_SITE "www.cdash.org")
-set(CTEST_DROP_LOCATION "/CDash/submit.php?project=PublicDashboard")
+set(CTEST_DROP_SITE "open.cdash.org")
+set(CTEST_DROP_LOCATION "/submit.php?project=PublicDashboard")
set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Tests/CTestTestTimeout/check.cmake b/Tests/CTestTestTimeout/check.cmake
deleted file mode 100644
index b16f2aab9..000000000
--- a/Tests/CTestTestTimeout/check.cmake
+++ /dev/null
@@ -1,9 +0,0 @@
-# Block just as long as timeout.cmake would if it were not killed.
-execute_process(COMMAND ${Timeout})
-
-# Verify that the log is empty, which indicates that the grandchild
-# was killed before it finished sleeping.
-file(READ "${Log}" LOG)
-if(NOT "${LOG}" STREQUAL "")
- message(FATAL_ERROR "${LOG}")
-endif()
diff --git a/Tests/CTestTestTimeout/sleep.c b/Tests/CTestTestTimeout/sleep.c
new file mode 100644
index 000000000..33ce30772
--- /dev/null
+++ b/Tests/CTestTestTimeout/sleep.c
@@ -0,0 +1,21 @@
+#if defined(_WIN32)
+# include <windows.h>
+#else
+# include <unistd.h>
+#endif
+
+#include <stdio.h>
+
+int main(void)
+{
+ fprintf(stderr, "before sleep\n");
+ fflush(stderr); /* should not be needed, but just in case */
+#if defined(_WIN32)
+ Sleep((TIMEOUT+4)*1000);
+#else
+ sleep((TIMEOUT+4));
+#endif
+ fprintf(stderr, "after sleep\n");
+ fflush(stderr); /* should not be needed, but just in case */
+ return 0;
+}
diff --git a/Tests/CTestTestTimeout/test.cmake.in b/Tests/CTestTestTimeout/test.cmake.in
index 40241ffd6..4b5157ef0 100644
--- a/Tests/CTestTestTimeout/test.cmake.in
+++ b/Tests/CTestTestTimeout/test.cmake.in
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.1)
+cmake_minimum_required(VERSION 2.4)
# Settings:
set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
@@ -8,8 +8,9 @@ set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-Timeout")
set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestTimeout")
set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestTimeout")
set(CTEST_CVS_COMMAND "@CVSCOMMAND@")
-set(CTEST_CMAKE_GENERATOR "@CMAKE_TEST_GENERATOR@")
-set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_TEST_GENERATOR_TOOLSET@")
+set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@")
set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
@@ -24,3 +25,16 @@ CTEST_START(Experimental)
CTEST_CONFIGURE(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
CTEST_BUILD(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
+
+set(log ${CTEST_BINARY_DIRECTORY}/timeout.log)
+if(EXISTS "${log}")
+ # Verify that the timeout test did not finish sleeping.
+ file(STRINGS "${log}" after_sleep REGEX "after sleep")
+ if(after_sleep)
+ message(FATAL_ERROR "Log indicates timeout did not kill child.")
+ else()
+ message(STATUS "Log indicates timeout correctly killed child.")
+ endif()
+else()
+ message(FATAL_ERROR "Log does not exist:\n ${log}")
+endif()
diff --git a/Tests/CTestTestTimeout/timeout.c b/Tests/CTestTestTimeout/timeout.c
deleted file mode 100644
index 370ab22ed..000000000
--- a/Tests/CTestTestTimeout/timeout.c
+++ /dev/null
@@ -1,18 +0,0 @@
-#if defined(_WIN32)
-# include <windows.h>
-#else
-# include <unistd.h>
-#endif
-
-#include <stdio.h>
-
-int main(void)
-{
-#if defined(_WIN32)
- Sleep((TIMEOUT+4)*1000);
-#else
- sleep((TIMEOUT+4));
-#endif
- printf("timeout process finished sleeping!\n");
- return -1;
-}
diff --git a/Tests/CTestTestTimeout/timeout.cmake b/Tests/CTestTestTimeout/timeout.cmake
index 198cc9713..0989b65df 100644
--- a/Tests/CTestTestTimeout/timeout.cmake
+++ b/Tests/CTestTestTimeout/timeout.cmake
@@ -3,4 +3,4 @@ file(REMOVE ${Log})
# Run a child that sleeps longer than the timout of this test.
# Log its output so check.cmake can verify it dies.
-execute_process(COMMAND ${Timeout} OUTPUT_FILE ${Log})
+execute_process(COMMAND ${Sleep} ERROR_FILE ${Log})
diff --git a/Tests/CTestTestUpload/CTestConfig.cmake b/Tests/CTestTestUpload/CTestConfig.cmake
index 89c5b9474..a54708838 100644
--- a/Tests/CTestTestUpload/CTestConfig.cmake
+++ b/Tests/CTestTestUpload/CTestConfig.cmake
@@ -2,6 +2,6 @@ set (CTEST_PROJECT_NAME "CTestTestUpload")
set (CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
set (CTEST_DART_SERVER_VERSION "2")
set (CTEST_DROP_METHOD "http")
-set (CTEST_DROP_SITE "www.cdash.org")
-set (CTEST_DROP_LOCATION "/CDash/submit.php?project=PublicDashboard")
+set (CTEST_DROP_SITE "open.cdash.org")
+set (CTEST_DROP_LOCATION "/submit.php?project=PublicDashboard")
set (CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Tests/CTestTestUpload/test.cmake.in b/Tests/CTestTestUpload/test.cmake.in
index 19abc89f1..701439d37 100644
--- a/Tests/CTestTestUpload/test.cmake.in
+++ b/Tests/CTestTestUpload/test.cmake.in
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.1)
+cmake_minimum_required(VERSION 2.4)
# Settings:
set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
@@ -7,8 +7,9 @@ set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-Upload")
set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestUpload")
set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestUpload")
-set(CTEST_CMAKE_GENERATOR "@CMAKE_TEST_GENERATOR@")
-set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_TEST_GENERATOR_TOOLSET@")
+set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@")
set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
CTEST_START(Experimental)
diff --git a/Tests/CTestTestVerboseOutput/CMakeLists.txt b/Tests/CTestTestVerboseOutput/CMakeLists.txt
new file mode 100644
index 000000000..4cdd29c68
--- /dev/null
+++ b/Tests/CTestTestVerboseOutput/CMakeLists.txt
@@ -0,0 +1,11 @@
+cmake_minimum_required (VERSION 2.6)
+project(CTestTestVerboseOutput)
+include(CTest)
+
+add_executable(nop nop.c)
+
+add_test(NAME TestWithProperties COMMAND nop)
+set_property(TEST TestWithProperties PROPERTY ENVIRONMENT
+ "foo=bar"
+ "this=that"
+)
diff --git a/Tests/CTestTestVerboseOutput/CTestConfig.cmake b/Tests/CTestTestVerboseOutput/CTestConfig.cmake
new file mode 100644
index 000000000..4f96c79a9
--- /dev/null
+++ b/Tests/CTestTestVerboseOutput/CTestConfig.cmake
@@ -0,0 +1,7 @@
+set(CTEST_PROJECT_NAME "CTestTestVerboseOutput")
+set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
+set(CTEST_DART_SERVER_VERSION "2")
+set(CTEST_DROP_METHOD "http")
+set(CTEST_DROP_SITE "open.cdash.org")
+set(CTEST_DROP_LOCATION "/submit.php?project=PublicDashboard")
+set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Tests/CTestTestVerboseOutput/nop.c b/Tests/CTestTestVerboseOutput/nop.c
new file mode 100644
index 000000000..f8b643afb
--- /dev/null
+++ b/Tests/CTestTestVerboseOutput/nop.c
@@ -0,0 +1,4 @@
+int main()
+{
+ return 0;
+}
diff --git a/Tests/CTestTestVerboseOutput/test.cmake.in b/Tests/CTestTestVerboseOutput/test.cmake.in
new file mode 100644
index 000000000..7f4954841
--- /dev/null
+++ b/Tests/CTestTestVerboseOutput/test.cmake.in
@@ -0,0 +1,20 @@
+cmake_minimum_required(VERSION 2.4)
+
+# Settings:
+set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
+set(CTEST_SITE "@SITE@")
+set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-VerboseOutput")
+
+set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestVerboseOutput")
+set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestVerboseOutput")
+set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@")
+set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
+set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
+set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
+
+CTEST_START(Experimental)
+CTEST_CONFIGURE(BUILD "${CTEST_BINARY_DIRECTORY}")
+CTEST_BUILD(BUILD "${CTEST_BINARY_DIRECTORY}")
+CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}")
diff --git a/Tests/CTestTestZeroTimeout/CTestConfig.cmake b/Tests/CTestTestZeroTimeout/CTestConfig.cmake
index f8e06093d..60948647f 100644
--- a/Tests/CTestTestZeroTimeout/CTestConfig.cmake
+++ b/Tests/CTestTestZeroTimeout/CTestConfig.cmake
@@ -2,6 +2,6 @@ set(CTEST_PROJECT_NAME "CTestTestZeroTimeout")
set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
set(CTEST_DART_SERVER_VERSION "2")
set(CTEST_DROP_METHOD "http")
-set(CTEST_DROP_SITE "www.cdash.org")
-set(CTEST_DROP_LOCATION "/CDash/submit.php?project=PublicDashboard")
+set(CTEST_DROP_SITE "open.cdash.org")
+set(CTEST_DROP_LOCATION "/submit.php?project=PublicDashboard")
set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Tests/CTestTestZeroTimeout/test.cmake.in b/Tests/CTestTestZeroTimeout/test.cmake.in
index 745e5bc34..b829fefe2 100644
--- a/Tests/CTestTestZeroTimeout/test.cmake.in
+++ b/Tests/CTestTestZeroTimeout/test.cmake.in
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.1)
+cmake_minimum_required(VERSION 2.4)
# Settings:
set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
@@ -8,8 +8,9 @@ set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-ZeroTimeout")
set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestZeroTimeout")
set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestZeroTimeout")
set(CTEST_CVS_COMMAND "@CVSCOMMAND@")
-set(CTEST_CMAKE_GENERATOR "@CMAKE_TEST_GENERATOR@")
-set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_TEST_GENERATOR_TOOLSET@")
+set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@")
set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
diff --git a/Tests/CTestUpdateCVS.cmake.in b/Tests/CTestUpdateCVS.cmake.in
index 1699c3f1f..277b3a603 100644
--- a/Tests/CTestUpdateCVS.cmake.in
+++ b/Tests/CTestUpdateCVS.cmake.in
@@ -170,3 +170,22 @@ set(CTEST_CHECKOUT_COMMAND
# Run the dashboard script with CTest.
run_dashboard_script(dash-binary)
+
+#-----------------------------------------------------------------------------
+# Test ctest_update(RETURN_VALUE) on failure
+message("Running CTest Dashboard Script (fail to update)...")
+
+set(ctest_update_check [[
+if(NOT ret LESS 0)
+ message(FATAL_ERROR "ctest_update incorrectly succeeded with ${ret}")
+endif()
+]])
+create_dashboard_script(dash-binary-fail
+ "set(CTEST_CVS_COMMAND \"update-command-does-not-exist\")
+")
+unset(ctest_update_check)
+
+# Run the dashboard script with CTest.
+set(FAIL_UPDATE 1)
+run_dashboard_script(dash-binary-fail)
+unset(FAIL_UPDATE)
diff --git a/Tests/CTestUpdateCommon.cmake b/Tests/CTestUpdateCommon.cmake
index aaf88a8d1..458e42743 100644
--- a/Tests/CTestUpdateCommon.cmake
+++ b/Tests/CTestUpdateCommon.cmake
@@ -9,10 +9,13 @@ function(run_child)
ERROR_STRIP_TRAILING_WHITESPACE
)
if(FAILED)
- string(REGEX REPLACE "\n" "\n " OUTPUT "${OUTPUT}")
+ string(REPLACE "\n" "\n " OUTPUT "${OUTPUT}")
message(FATAL_ERROR "Child failed (${FAILED}), output is\n ${OUTPUT}\n"
"Command = [${ARGN}]\n")
endif()
+
+ # Pass output back up to the parent scope for possible further inspection.
+ set(OUTPUT "${OUTPUT}" PARENT_SCOPE)
endfunction()
#-----------------------------------------------------------------------------
@@ -37,15 +40,26 @@ function(check_updates build)
REGEX "<(${types}|FullName)>"
LIMIT_INPUT ${max_update_xml_size}
)
+
string(REGEX REPLACE
"[ \t]*<(${types})>[ \t]*;[ \t]*<FullName>([^<]*)</FullName>"
"\\1{\\2}" UPDATE_XML_ENTRIES "${UPDATE_XML_ENTRIES}")
+ # If specified, remove the given prefix from the files in Update.xml.
+ # Some VCS systems, like Perforce, return absolute locations
+ if(DEFINED REPOSITORY_FILE_PREFIX)
+ string(REPLACE
+ "${REPOSITORY_FILE_PREFIX}" ""
+ UPDATE_XML_ENTRIES "${UPDATE_XML_ENTRIES}")
+ endif()
+
# Compare expected and actual entries
set(EXTRA "${UPDATE_XML_ENTRIES}")
list(REMOVE_ITEM EXTRA ${ARGN} ${UPDATE_EXTRA} ${UPDATE_MAYBE})
set(MISSING "${ARGN}" ${UPDATE_EXTRA})
- list(REMOVE_ITEM MISSING ${UPDATE_XML_ENTRIES})
+ if(NOT "" STREQUAL "${UPDATE_XML_ENTRIES}")
+ list(REMOVE_ITEM MISSING ${UPDATE_XML_ENTRIES})
+ endif()
if(NOT UPDATE_NOT_GLOBAL)
set(rev_elements Revision PriorRevision ${UPDATE_GLOBAL_ELEMENTS})
@@ -97,7 +111,7 @@ function(check_updates build)
${TOP}/${build}/Testing/Temporary/LastUpdate*.log)
if(UPDATE_LOG_FILE)
file(READ ${UPDATE_LOG_FILE} UPDATE_LOG LIMIT ${max_update_xml_size})
- string(REGEX REPLACE "\n" "\n " UPDATE_LOG "${UPDATE_LOG}")
+ string(REPLACE "\n" "\n " UPDATE_LOG "${UPDATE_LOG}")
set(MSG "${MSG}Update log:\n ${UPDATE_LOG}")
else()
set(MSG "${MSG}No update log found!")
@@ -168,6 +182,14 @@ endfunction()
#-----------------------------------------------------------------------------
# Function to write the dashboard test script.
function(create_dashboard_script bin_dir custom_text)
+ if (NOT ctest_update_check)
+ set(ctest_update_check [[
+if(ret LESS 0)
+ message(FATAL_ERROR "ctest_update failed with ${ret}")
+endif()
+]])
+ endif()
+
# Write the dashboard script.
file(WRITE ${TOP}/${bin_dir}.cmake
"# CTest Dashboard Script
@@ -179,8 +201,8 @@ set(CTEST_BINARY_DIRECTORY \${CTEST_DASHBOARD_ROOT}/${bin_dir})
${custom_text}
# Start a dashboard and run the update step
ctest_start(Experimental)
-ctest_update(SOURCE \${CTEST_SOURCE_DIRECTORY})
-")
+ctest_update(SOURCE \${CTEST_SOURCE_DIRECTORY} RETURN_VALUE ret ${ctest_update_args})
+${ctest_update_check}")
endfunction()
#-----------------------------------------------------------------------------
@@ -208,6 +230,54 @@ function(run_dashboard_command_line bin_dir)
endfunction()
#-----------------------------------------------------------------------------
+# Function to find the Update.xml file and make sure
+# it only has the Revision in it and no updates
+function(check_no_update bin_dir)
+ set(PATTERN ${TOP}/${bin_dir}/Testing/*/Update.xml)
+ file(GLOB UPDATE_XML_FILE RELATIVE ${TOP} ${PATTERN})
+ string(REGEX REPLACE "//Update.xml$" "/Update.xml"
+ UPDATE_XML_FILE "${UPDATE_XML_FILE}")
+ message(" found ${UPDATE_XML_FILE}")
+ set(rev_regex "Revision|PriorRevision")
+ file(STRINGS ${TOP}/${UPDATE_XML_FILE} UPDATE_XML_REVISIONS
+ REGEX "^\t<(${rev_regex})>[^<\n]+</(${rev_regex})>$"
+ )
+ set(found_revisons FALSE)
+ foreach(r IN LISTS UPDATE_XML_REVISIONS)
+ if("${r}" MATCHES "PriorRevision")
+ message(FATAL_ERROR "Found PriorRevision in no update test")
+ endif()
+ if("${r}" MATCHES "<Revision>")
+ set(found_revisons TRUE)
+ endif()
+ endforeach()
+ if(found_revisons)
+ message(" found <Revision> in no update test")
+ else()
+ message(FATAL_ERROR " missing <Revision> in no update test")
+ endif()
+endfunction()
+
+#-----------------------------------------------------------------------------
+# Function to find the Update.xml file and make sure
+# it only has the UpdateReturnStatus failure message and no updates.
+function(check_fail_update bin_dir)
+ set(PATTERN ${TOP}/${bin_dir}/Testing/*/Update.xml)
+ file(GLOB UPDATE_XML_FILE RELATIVE ${TOP} ${PATTERN})
+ string(REGEX REPLACE "//Update.xml$" "/Update.xml"
+ UPDATE_XML_FILE "${UPDATE_XML_FILE}")
+ message(" found ${UPDATE_XML_FILE}")
+ file(STRINGS ${TOP}/${UPDATE_XML_FILE} UPDATE_XML_STATUS
+ REGEX "^\t<UpdateReturnStatus>[^<\n]+"
+ )
+ if(UPDATE_XML_STATUS MATCHES "Update command failed")
+ message(" correctly found 'Update command failed'")
+ else()
+ message(FATAL_ERROR " missing 'Update command failed'")
+ endif()
+endfunction()
+
+#-----------------------------------------------------------------------------
# Function to run the dashboard through a script
function(run_dashboard_script bin_dir)
run_child(
@@ -216,14 +286,23 @@ function(run_dashboard_script bin_dir)
)
# Verify the updates reported by CTest.
- list(APPEND UPDATE_MAYBE Updated{subdir})
- check_updates(${bin_dir}
- Updated{foo.txt}
- Updated{bar.txt}
- Updated{zot.txt}
- Updated{subdir/foo.txt}
- Updated{subdir/bar.txt}
- )
+ list(APPEND UPDATE_MAYBE Updated{subdir} Updated{CTestConfig.cmake})
+ if(NO_UPDATE)
+ check_no_update(${bin_dir})
+ elseif(FAIL_UPDATE)
+ check_fail_update(${bin_dir})
+ else()
+ check_updates(${bin_dir}
+ Updated{foo.txt}
+ Updated{bar.txt}
+ Updated{zot.txt}
+ Updated{subdir/foo.txt}
+ Updated{subdir/bar.txt}
+ )
+ endif()
+
+ # Pass console output up to the parent, in case they'd like to inspect it.
+ set(OUTPUT "${OUTPUT}" PARENT_SCOPE)
endfunction()
#-----------------------------------------------------------------------------
diff --git a/Tests/CTestUpdateGIT.cmake.in b/Tests/CTestUpdateGIT.cmake.in
index f6939de9a..46230cca3 100644
--- a/Tests/CTestUpdateGIT.cmake.in
+++ b/Tests/CTestUpdateGIT.cmake.in
@@ -41,7 +41,6 @@ run_child(
COMMAND ${GIT} --bare init
)
file(REMOVE_RECURSE ${TOP}/repo.git/hooks)
-set(REPO file://${TOP}/repo.git)
# Create submodule repository.
message("Creating submodule...")
@@ -51,17 +50,13 @@ run_child(
COMMAND ${GIT} --bare init
)
file(REMOVE_RECURSE ${TOP}/module.git/hooks)
-set(MOD_REPO file://${TOP}/module.git)
-create_content(module)
-run_child(WORKING_DIRECTORY ${TOP}/module
- COMMAND ${GIT} init
+run_child(WORKING_DIRECTORY ${TOP}
+ COMMAND ${GIT} clone module.git module
)
file(REMOVE_RECURSE ${TOP}/module/.git/hooks)
file(APPEND ${TOP}/module/.git/config "
-[remote \"origin\"]
-\turl = ${MOD_REPO}
-\tfetch = +refs/heads/*:refs/remotes/origin/*
${AUTHOR_CONFIG}")
+create_content(module)
run_child(WORKING_DIRECTORY ${TOP}/module
COMMAND ${GIT} add .
)
@@ -75,20 +70,17 @@ run_child(WORKING_DIRECTORY ${TOP}/module
#-----------------------------------------------------------------------------
# Import initial content into the repository.
message("Importing content...")
-create_content(import)
-file(WRITE ${TOP}/import/HEAD "HEAD\n")
-file(WRITE ${TOP}/import/master "master\n")
# Import the content into the repository.
-run_child(WORKING_DIRECTORY ${TOP}/import
- COMMAND ${GIT} init
+run_child(WORKING_DIRECTORY ${TOP}
+ COMMAND ${GIT} clone repo.git import
)
file(REMOVE_RECURSE ${TOP}/import/.git/hooks)
file(APPEND ${TOP}/import/.git/config "
-[remote \"origin\"]
-\turl = ${REPO}
-\tfetch = +refs/heads/*:refs/remotes/origin/*
${AUTHOR_CONFIG}")
+create_content(import)
+file(WRITE ${TOP}/import/HEAD "HEAD\n")
+file(WRITE ${TOP}/import/master "master\n")
run_child(WORKING_DIRECTORY ${TOP}/import
COMMAND ${GIT} add .
)
@@ -96,7 +88,7 @@ run_child(WORKING_DIRECTORY ${TOP}/import
COMMAND ${GIT} config core.safecrlf false
)
run_child(WORKING_DIRECTORY ${TOP}/import
- COMMAND ${GIT} submodule add ${MOD_REPO} module
+ COMMAND ${GIT} submodule add ../module.git module
)
run_child(WORKING_DIRECTORY ${TOP}/import
COMMAND ${GIT} commit -m "Initial content"
@@ -123,7 +115,7 @@ run_child(WORKING_DIRECTORY ${TOP}/module
message("Checking out revision 1...")
run_child(
WORKING_DIRECTORY ${TOP}
- COMMAND ${GIT} clone ${REPO} user-source
+ COMMAND ${GIT} clone repo.git user-source
)
file(REMOVE_RECURSE ${TOP}/user-source/.git/hooks)
file(APPEND ${TOP}/user-source/.git/config "${AUTHOR_CONFIG}")
@@ -278,7 +270,7 @@ set(CTEST_GIT_COMMAND \"${GIT}\")
set(CTEST_GIT_UPDATE_OPTIONS)
execute_process(
WORKING_DIRECTORY \"${TOP}\"
- COMMAND \"${GIT}\" clone \"${REPO}\" dash-source
+ COMMAND \"${GIT}\" clone repo.git dash-source
)
# Test .git file.
@@ -317,3 +309,64 @@ set(CTEST_GIT_UPDATE_CUSTOM \${CTEST_GIT_COMMAND} pull origin master)
# Run the dashboard script with CTest.
run_dashboard_script(dash-binary-custom)
+
+
+rewind_source(dash-source)
+
+#-----------------------------------------------------------------------------
+# Test no update with a dashboard script.
+message("Running CTest Dashboard Script (No update)...")
+
+create_dashboard_script(dash-binary-no-update
+ "# git command configuration
+set(CTEST_GIT_COMMAND \"${GIT}\")
+set(CTEST_UPDATE_VERSION_ONLY TRUE)
+")
+
+# Run the dashboard script with CTest.
+set(NO_UPDATE 1)
+run_dashboard_script(dash-binary-no-update)
+unset(NO_UPDATE)
+
+rewind_source(dash-source)
+
+#-----------------------------------------------------------------------------
+# Test ctest_update(QUIET)
+message("Running CTest Dashboard Script (update quietly)...")
+
+set(ctest_update_args QUIET)
+create_dashboard_script(dash-binary-quiet
+ "# git command configuration
+set(CTEST_GIT_COMMAND \"${GIT}\")
+set(CTEST_GIT_UPDATE_OPTIONS)
+set(CTEST_GIT_UPDATE_CUSTOM \${CTEST_GIT_COMMAND} pull origin master)
+")
+unset(ctest_update_args)
+
+# Run the dashboard script with CTest.
+run_dashboard_script(dash-binary-quiet)
+
+# Make sure the output seems quiet.
+if("${OUTPUT}" MATCHES "Updating the repository")
+ message(FATAL_ERROR "Found 'Updating the repository' in quiet output")
+endif()
+
+#-----------------------------------------------------------------------------
+# Test ctest_update(RETURN_VALUE) on failure
+message("Running CTest Dashboard Script (fail to update)...")
+
+set(ctest_update_check [[
+
+if(NOT ret LESS 0)
+ message(FATAL_ERROR "ctest_update incorrectly succeeded with ${ret}")
+endif()
+]])
+create_dashboard_script(dash-binary-fail
+ "set(CTEST_GIT_COMMAND \"update-command-does-not-exist\")
+")
+unset(ctest_update_check)
+
+# Run the dashboard script with CTest.
+set(FAIL_UPDATE 1)
+run_dashboard_script(dash-binary-fail)
+unset(FAIL_UPDATE)
diff --git a/Tests/CTestUpdateHG.cmake.in b/Tests/CTestUpdateHG.cmake.in
index c5440f954..c76bf9192 100644
--- a/Tests/CTestUpdateHG.cmake.in
+++ b/Tests/CTestUpdateHG.cmake.in
@@ -164,3 +164,22 @@ execute_process(
# Run the dashboard script with CTest.
run_dashboard_script(dash-binary)
+
+#-----------------------------------------------------------------------------
+# Test ctest_update(RETURN_VALUE) on failure
+message("Running CTest Dashboard Script (fail to update)...")
+
+set(ctest_update_check [[
+if(NOT ret LESS 0)
+ message(FATAL_ERROR "ctest_update incorrectly succeeded with ${ret}")
+endif()
+]])
+create_dashboard_script(dash-binary-fail
+ "set(CTEST_HG_COMMAND \"update-command-does-not-exist\")
+")
+unset(ctest_update_check)
+
+# Run the dashboard script with CTest.
+set(FAIL_UPDATE 1)
+run_dashboard_script(dash-binary-fail)
+unset(FAIL_UPDATE)
diff --git a/Tests/CTestUpdateP4.cmake.in b/Tests/CTestUpdateP4.cmake.in
new file mode 100644
index 000000000..f0420c42f
--- /dev/null
+++ b/Tests/CTestUpdateP4.cmake.in
@@ -0,0 +1,261 @@
+# This script drives creation of a perforce repository and checks
+# that CTest can update from it.
+
+#-----------------------------------------------------------------------------
+# Test in a directory next to this script.
+get_filename_component(TOP "${CMAKE_CURRENT_LIST_FILE}" PATH)
+set(P4_TOP "${TOP}")
+set(TOP "${TOP}/@CTestUpdateP4_DIR@")
+
+# Include code common to all update tests.
+set(REPOSITORY_FILE_PREFIX "//ctest/")
+include("@CMAKE_CURRENT_SOURCE_DIR@/CTestUpdateCommon.cmake")
+
+#-----------------------------------------------------------------------------
+# Perforce server options
+set(P4_HOST localhost)
+set(P4_PORT 1888)
+
+#-----------------------------------------------------------------------------
+# Report p4 tools in use and set its defaults
+message("Using P4 tools:")
+set(P4 "@P4_EXECUTABLE@")
+set(P4D "@P4D_EXECUTABLE@")
+message(" p4 = ${P4}")
+message(" p4d = ${P4D}")
+
+set(P4_CLIENT -c ctest_p4)
+set(P4_OPTIONS -H ${P4_HOST} -p ${P4_PORT})
+set(P4CMD ${P4} ${P4_OPTIONS})
+
+#-----------------------------------------------------------------------------
+# Start the Perforce server
+if(UNIX)
+ set(P4_ROOT ${P4_TOP}/perforce)
+
+ message("Starting p4d on '${P4_ROOT}' listening on port ${P4_PORT}...")
+
+ # Stop a previous instance of Perforce running
+ execute_process(
+ WORKING_DIRECTORY ${TOP}
+ COMMAND ${P4CMD} admin stop
+ OUTPUT_QUIET
+ ERROR_QUIET
+ )
+
+ # Make sure we don't have a perforce directory from a previous run
+ file(REMOVE_RECURSE ${P4_ROOT})
+ file(MAKE_DIRECTORY ${P4_ROOT})
+
+ set(P4_SERVER "nohup '${P4D}' -d -r '${P4_ROOT}'")
+ set(P4_SERVER "${P4_SERVER} -L '${P4_ROOT}/p4.log'")
+ set(P4_SERVER "${P4_SERVER} -J '${P4_ROOT}/journal'")
+ set(P4_SERVER "${P4_SERVER} -p ${P4_PORT} >/dev/null 2>&1 &")
+
+ message("Server command line: ${P4_SERVER}")
+
+ execute_process(
+ COMMAND sh -c "
+${P4_SERVER}
+for i in 1 2 3 4 5 6 7 8 9 10; do
+ echo 'Waiting for server to start...'
+ sleep 1
+ if '${P4}' -H ${P4_HOST} -p ${P4_PORT} help >/dev/null 2>&1; then
+ echo 'Server started.'
+ exit
+ fi
+done
+echo 'Gave up waiting for server to start.'
+"
+ )
+endif()
+
+#-----------------------------------------------------------------------------
+# Initialize the testing directory.
+message("Creating test directory...")
+init_testing()
+
+#-----------------------------------------------------------------------------
+# Create the repository.
+message("Creating depot...")
+file(WRITE ${TOP}/depot.spec "Depot: ctest\n")
+file(APPEND ${TOP}/depot.spec "Type: local\n")
+file(APPEND ${TOP}/depot.spec "Map: ctest/...\n")
+run_child(
+ WORKING_DIRECTORY ${TOP}
+ COMMAND ${P4CMD} depot -i
+ INPUT_FILE ${TOP}/depot.spec
+)
+
+#-----------------------------------------------------------------------------
+# Import initial content into the repository.
+message("Importing content...")
+create_content(user-source)
+
+message("Creating client spec...")
+file(WRITE ${TOP}/client.spec "Client: ctest_p4\n")
+file(APPEND ${TOP}/client.spec "Root: ${TOP}/user-source\n")
+file(APPEND ${TOP}/client.spec "View: //ctest/... //ctest_p4/...\n")
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${P4CMD} client -i
+ INPUT_FILE ${TOP}/client.spec
+)
+
+# After creating the depot and the client view, all P4 commands need to
+# have the client spec passed to them
+list(APPEND P4CMD ${P4_CLIENT})
+
+message("Adding files to repository")
+file(GLOB_RECURSE files ${TOP}/user-source/*)
+foreach(filename ${files})
+ run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${P4CMD} add ${filename}
+ )
+endforeach()
+
+message("Submitting changes to repository")
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${P4CMD} submit -d "CTEST: Initial content"
+)
+message("Tagging the repository")
+file(WRITE ${TOP}/label.spec "Label: r1\n")
+file(APPEND ${TOP}/label.spec "View: //ctest/...\n")
+
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${P4CMD} label -i
+ INPUT_FILE ${TOP}/label.spec
+)
+
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${P4CMD} labelsync -l r1
+)
+
+#-----------------------------------------------------------------------------
+# Make changes in the working tree.
+message("Changing content...")
+update_content(user-source files_added files_removed dirs_added)
+foreach(filename ${files_added})
+ message("add: ${filename}")
+ run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${P4CMD} add ${TOP}/user-source/${filename}
+ )
+endforeach()
+foreach(filename ${files_removed})
+ run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${P4CMD} delete ${TOP}/user-source/${filename}
+ )
+endforeach()
+
+#-----------------------------------------------------------------------------
+# Commit the changes to the repository.
+message("Committing revision 2...")
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${P4CMD} submit -d "CTEST: Changed content"
+)
+
+#-----------------------------------------------------------------------------
+# Make changes in the working tree.
+message("Changing content again...")
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${P4CMD} edit //ctest/...
+)
+
+change_content(user-source)
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${P4CMD} revert -a //ctest/...
+)
+
+#-----------------------------------------------------------------------------
+# Commit the changes to the repository.
+message("Committing revision 3...")
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${P4CMD} submit -d "CTEST: Changed content again"
+)
+
+#-----------------------------------------------------------------------------
+# Go back to before the changes so we can test updating.
+message("Backing up to revision 1...")
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${P4CMD} sync @r1
+ )
+
+# Create a modified file.
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${P4CMD} sync @r1
+ )
+
+# We should p4 open any files that modify_content creates
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${P4CMD} open ${TOP}/user-source/CTestConfig.cmake
+)
+modify_content(user-source)
+
+#-----------------------------------------------------------------------------
+# Test updating the user work directory with the command-line interface.
+message("Running CTest Dashboard Command Line...")
+
+# Create the user build tree.
+create_build_tree(user-source user-binary)
+file(APPEND ${TOP}/user-binary/CTestConfiguration.ini
+ "# P4 command configuration
+UpdateCommand: ${P4}
+P4Client: ctest_p4
+P4Options: -H ${P4_HOST} -p ${P4_PORT}
+")
+
+# Run the dashboard command line interface.
+run_dashboard_command_line(user-binary)
+
+# Revert the modified files
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${P4CMD} revert ${TOP}/user-source/CTestConfig.cmake
+)
+
+#-----------------------------------------------------------------------------
+# Test initial checkout and update with a dashboard script.
+# Create a new client so we can check out files on a different directory
+message("Running CTest Dashboard Script...")
+
+message("Creating client spec...")
+file(WRITE ${TOP}/client2.spec "Client: ctest2_p4\n")
+file(APPEND ${TOP}/client2.spec "Root: ${TOP}/dash-source\n")
+file(APPEND ${TOP}/client2.spec "View: //ctest/... //ctest2_p4/...\n")
+run_child(
+ COMMAND ${P4CMD} client -i
+ INPUT_FILE ${TOP}/client2.spec
+)
+
+file(MAKE_DIRECTORY ${TOP}/dash-source)
+
+create_dashboard_script(dash-binary
+ "# P4 command configuration
+set(CTEST_P4_CLIENT \"ctest2_p4\")
+set(CTEST_P4_OPTIONS \"-H ${P4_HOST} -p ${P4_PORT}\")
+set(CTEST_UPDATE_COMMAND \"${P4}\")
+")
+
+# Run the dashboard script with CTest.
+run_dashboard_script(dash-binary)
+
+#-----------------------------------------------------------------------------
+# Clean up
+message("Shutting down p4d")
+run_child(
+ WORKING_DIRECTORY ${TOP}
+ COMMAND ${P4CMD} admin stop
+) \ No newline at end of file
diff --git a/Tests/CTestUpdateSVN.cmake.in b/Tests/CTestUpdateSVN.cmake.in
index b5728fd67..b757a441d 100644
--- a/Tests/CTestUpdateSVN.cmake.in
+++ b/Tests/CTestUpdateSVN.cmake.in
@@ -147,3 +147,22 @@ set(CTEST_CHECKOUT_COMMAND
# Run the dashboard script with CTest.
run_dashboard_script(dash-binary)
+
+#-----------------------------------------------------------------------------
+# Test ctest_update(RETURN_VALUE) on failure
+message("Running CTest Dashboard Script (fail to update)...")
+
+set(ctest_update_check [[
+if(NOT ret LESS 0)
+ message(FATAL_ERROR "ctest_update incorrectly succeeded with ${ret}")
+endif()
+]])
+create_dashboard_script(dash-binary-fail
+ "set(CTEST_SVN_COMMAND \"update-command-does-not-exist\")
+")
+unset(ctest_update_check)
+
+# Run the dashboard script with CTest.
+set(FAIL_UPDATE 1)
+run_dashboard_script(dash-binary-fail)
+unset(FAIL_UPDATE)
diff --git a/Tests/CheckCompilerRelatedVariables/CMakeLists.txt b/Tests/CheckCompilerRelatedVariables/CMakeLists.txt
index 69cfdb8e3..87b7f1acd 100644
--- a/Tests/CheckCompilerRelatedVariables/CMakeLists.txt
+++ b/Tests/CheckCompilerRelatedVariables/CMakeLists.txt
@@ -40,6 +40,9 @@ endif()
if(DEFINED MSVC12)
math(EXPR msvc_total "${msvc_total} + 1")
endif()
+if(DEFINED MSVC14)
+ math(EXPR msvc_total "${msvc_total} + 1")
+endif()
echo_var(MSVC)
echo_var(MSVC60)
@@ -50,6 +53,7 @@ echo_var(MSVC90)
echo_var(MSVC10)
echo_var(MSVC11)
echo_var(MSVC12)
+echo_var(MSVC14)
echo_var(MSVC_IDE)
if(MSVC)
diff --git a/Tests/CoberturaCoverage/DartConfiguration.tcl.in b/Tests/CoberturaCoverage/DartConfiguration.tcl.in
new file mode 100644
index 000000000..954f59a8a
--- /dev/null
+++ b/Tests/CoberturaCoverage/DartConfiguration.tcl.in
@@ -0,0 +1,8 @@
+# This file is configured by CMake automatically as DartConfiguration.tcl
+# If you choose not to use CMake, this file may be hand configured, by
+# filling in the required variables.
+
+
+# Configuration directories and files
+SourceDirectory: ${CMake_SOURCE_DIR}/Testing/CoberturaCoverage
+BuildDirectory: ${CMake_BINARY_DIR}/Testing/CoberturaCoverage
diff --git a/Tests/CoberturaCoverage/coverage.xml.in b/Tests/CoberturaCoverage/coverage.xml.in
new file mode 100644
index 000000000..b3f6691d0
--- /dev/null
+++ b/Tests/CoberturaCoverage/coverage.xml.in
@@ -0,0 +1,112 @@
+<?xml version="1.0"?>
+<!DOCTYPE coverage SYSTEM "http://cobertura.sourceforge.net/xml/coverage-04.dtd">
+
+<coverage line-rate="0.7222222222222222" branch-rate="0.875" lines-covered="13" lines-valid="18" branches-covered="7" branches-valid="8" complexity="0.0" version="1.9.4.1" timestamp="1401890139281">
+ <sources>
+ <source>${CMake_BINARY_DIR}/Testing/CoberturaCoverage/src/main/java/</source>
+ </sources>
+ <packages>
+ <package name="org.cmake.Coverage" line-rate="0.7222222222222222" branch-rate="0.875" complexity="0.0">
+ <classes>
+ <class name="org.cmake.Coverage.CoverageTest" filename="org/cmake/CoverageTest.java" line-rate="0.7222222222222222" branch-rate="0.875" complexity="0.0">
+ <methods>
+ <method name="&lt;clinit&gt;" signature="()V" line-rate="1.0" branch-rate="1.0">
+ <lines>
+ <line number="10" hits="2" branch="false"/>
+ <line number="11" hits="2" branch="false"/>
+ </lines>
+ </method>
+ <method name="&lt;init&gt;" signature="()V" line-rate="0.0" branch-rate="1.0">
+ <lines>
+ <line number="8" hits="0" branch="false"/>
+ <line number="12" hits="0" branch="false"/>
+ </lines>
+ </method>
+ <method name="equalsVarOne" signature="(Ljava/lang/String;)Ljava/lang/Boolean;" line-rate="0.6666666666666666" branch-rate="0.5">
+ <lines>
+ <line number="16" hits="2" branch="true" condition-coverage="50% (1/2)">
+ <conditions>
+ <condition number="0" type="jump" coverage="50%"/>
+ </conditions>
+ </line>
+ <line number="17" hits="2" branch="false"/>
+ <line number="20" hits="0" branch="false"/>
+ </lines>
+ </method>
+ <method name="equalsVarTwo" signature="(Ljava/lang/String;)Z" line-rate="1.0" branch-rate="1.0">
+ <lines>
+ <line number="26" hits="4" branch="true" condition-coverage="100% (2/2)">
+ <conditions>
+ <condition number="0" type="jump" coverage="100%"/>
+ </conditions>
+ </line>
+ <line number="27" hits="2" branch="false"/>
+ <line number="30" hits="2" branch="false"/>
+ </lines>
+ </method>
+ <method name="timesIntOne" signature="(Ljava/lang/Integer;)Ljava/lang/Integer;" line-rate="0.0" branch-rate="1.0">
+ <lines>
+ <line number="35" hits="0" branch="false"/>
+ <line number="36" hits="0" branch="false"/>
+ </lines>
+ </method>
+ <method name="whileLoop" signature="(Ljava/lang/Integer;)Z" line-rate="1.0" branch-rate="1.0">
+ <lines>
+ <line number="41" hits="2" branch="false"/>
+ <line number="42" hits="10" branch="true" condition-coverage="100% (2/2)">
+ <conditions>
+ <condition number="0" type="jump" coverage="100%"/>
+ </conditions>
+ </line>
+ <line number="43" hits="8" branch="false"/>
+ <line number="45" hits="2" branch="true" condition-coverage="100% (2/2)">
+ <conditions>
+ <condition number="0" type="jump" coverage="100%"/>
+ </conditions>
+ </line>
+ <line number="46" hits="1" branch="false"/>
+ <line number="49" hits="1" branch="false"/>
+ </lines>
+ </method>
+ </methods>
+ <lines>
+ <line number="8" hits="0" branch="false"/>
+ <line number="10" hits="2" branch="false"/>
+ <line number="11" hits="2" branch="false"/>
+ <line number="12" hits="0" branch="false"/>
+ <line number="16" hits="2" branch="true" condition-coverage="50% (1/2)">
+ <conditions>
+ <condition number="0" type="jump" coverage="50%"/>
+ </conditions>
+ </line>
+ <line number="17" hits="2" branch="false"/>
+ <line number="20" hits="0" branch="false"/>
+ <line number="26" hits="4" branch="true" condition-coverage="100% (2/2)">
+ <conditions>
+ <condition number="0" type="jump" coverage="100%"/>
+ </conditions>
+ </line>
+ <line number="27" hits="2" branch="false"/>
+ <line number="30" hits="2" branch="false"/>
+ <line number="35" hits="0" branch="false"/>
+ <line number="36" hits="0" branch="false"/>
+ <line number="41" hits="2" branch="false"/>
+ <line number="42" hits="10" branch="true" condition-coverage="100% (2/2)">
+ <conditions>
+ <condition number="0" type="jump" coverage="100%"/>
+ </conditions>
+ </line>
+ <line number="43" hits="8" branch="false"/>
+ <line number="45" hits="2" branch="true" condition-coverage="100% (2/2)">
+ <conditions>
+ <condition number="0" type="jump" coverage="100%"/>
+ </conditions>
+ </line>
+ <line number="46" hits="1" branch="false"/>
+ <line number="49" hits="1" branch="false"/>
+ </lines>
+ </class>
+ </classes>
+ </package>
+ </packages>
+</coverage>
diff --git a/Tests/CoberturaCoverage/src/main/java/org/cmake/CoverageTest.java b/Tests/CoberturaCoverage/src/main/java/org/cmake/CoverageTest.java
new file mode 100644
index 000000000..4fb43c608
--- /dev/null
+++ b/Tests/CoberturaCoverage/src/main/java/org/cmake/CoverageTest.java
@@ -0,0 +1,52 @@
+package org.cmake.Coverage;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.List;
+import java.awt.*;
+
+public class CoverageTest {
+
+ public static String VarOne = "test1";
+ public static String VarTwo = "test2";
+ private Integer IntOne = 4;
+
+ public static Boolean equalsVarOne(String inString) {
+
+ if(VarOne.equals(inString)){
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ public static boolean equalsVarTwo(String inString){
+
+ if(VarTwo.equals(inString)){
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ private Integer timesIntOne(Integer inVal){
+
+ return inVal * IntOne;
+ }
+
+ public static boolean whileLoop(Integer StopInt){
+
+ Integer i = 0;
+ while(i < StopInt){
+ i=i+1;
+ }
+ if (i.equals(5)){
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+}
diff --git a/Tests/CompatibleInterface/CMakeLists.txt b/Tests/CompatibleInterface/CMakeLists.txt
index ae1d2fa43..668a97b14 100644
--- a/Tests/CompatibleInterface/CMakeLists.txt
+++ b/Tests/CompatibleInterface/CMakeLists.txt
@@ -1,12 +1,12 @@
-cmake_minimum_required(VERSION 2.8)
+cmake_minimum_required(VERSION 3.0)
project(CompatibleInterface)
include(GenerateExportHeader)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
-add_library(iface1 empty.cpp)
+add_library(iface1 INTERFACE)
set_property(TARGET iface1 APPEND PROPERTY
COMPATIBLE_INTERFACE_BOOL
BOOL_PROP1
@@ -20,19 +20,59 @@ set_property(TARGET iface1 APPEND PROPERTY
STRING_PROP2
STRING_PROP3
)
+set_property(TARGET iface1 APPEND PROPERTY
+ COMPATIBLE_INTERFACE_NUMBER_MIN
+ NUMBER_MIN_PROP1
+ NUMBER_MIN_PROP2
+ NUMBER_MIN_PROP3
+ NUMBER_MIN_PROP4
+)
+set_property(TARGET iface1 APPEND PROPERTY
+ COMPATIBLE_INTERFACE_NUMBER_MAX
+ NUMBER_MAX_PROP1
+ NUMBER_MAX_PROP2
+)
+
+set(CMAKE_DEBUG_TARGET_PROPERTIES
+ BOOL_PROP1 BOOL_PROP2 BOOL_PROP3 BOOL_PROP4
+ STRING_PROP1 STRING_PROP2 STRING_PROP3
+ NUMBER_MIN_PROP1 NUMBER_MIN_PROP2 NUMBER_MIN_PROP3 NUMBER_MIN_PROP4
+ NUMBER_MAX_PROP1 NUMBER_MAX_PROP2
+)
set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP1 ON)
set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP2 ON)
set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP1 prop1)
set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP2 prop2)
+set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP1 100)
+set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP2 200)
+set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP3 0x10)
+set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP4 0x10)
+set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MAX_PROP1 100)
+set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MAX_PROP2 200)
add_executable(CompatibleInterface main.cpp)
target_link_libraries(CompatibleInterface iface1)
+add_library(foo STATIC foo.cpp)
+add_library(bar SHARED bar.cpp)
+set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SOMEPROP)
+set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP ON)
+# Use LINK_ONLY to suppress usage requirements and allow the check to pass.
+set_property(TARGET bar PROPERTY INTERFACE_LINK_LIBRARIES $<LINK_ONLY:foo>)
+set_property(TARGET CompatibleInterface PROPERTY SOMEPROP OFF)
+target_link_libraries(CompatibleInterface bar)
+
set_property(TARGET CompatibleInterface PROPERTY BOOL_PROP2 ON)
set_property(TARGET CompatibleInterface PROPERTY BOOL_PROP3 ON)
set_property(TARGET CompatibleInterface PROPERTY STRING_PROP2 prop2)
set_property(TARGET CompatibleInterface PROPERTY STRING_PROP3 prop3)
+set_property(TARGET CompatibleInterface PROPERTY NUMBER_MIN_PROP1 50)
+set_property(TARGET CompatibleInterface PROPERTY NUMBER_MIN_PROP2 250)
+set_property(TARGET CompatibleInterface PROPERTY NUMBER_MIN_PROP3 0xa)
+set_property(TARGET CompatibleInterface PROPERTY NUMBER_MIN_PROP4 0x1A)
+set_property(TARGET CompatibleInterface PROPERTY NUMBER_MAX_PROP1 50)
+set_property(TARGET CompatibleInterface PROPERTY NUMBER_MAX_PROP2 250)
target_compile_definitions(CompatibleInterface
PRIVATE
@@ -42,6 +82,12 @@ target_compile_definitions(CompatibleInterface
$<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP1>,prop1>:STRING_PROP1>
$<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP2>,prop2>:STRING_PROP2>
$<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP3>,prop3>:STRING_PROP3>
+ $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP1>,50>:NUMBER_MIN_PROP1=50>
+ $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP2>,200>:NUMBER_MIN_PROP2=200>
+ $<$<EQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP3>,0xA>:NUMBER_MIN_PROP3=0xA>
+ $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP4>,0x10>:NUMBER_MIN_PROP4=0x10>
+ $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MAX_PROP1>,100>:NUMBER_MAX_PROP1=100>
+ $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MAX_PROP2>,250>:NUMBER_MAX_PROP2=250>
)
diff --git a/Tests/CompatibleInterface/bar.cpp b/Tests/CompatibleInterface/bar.cpp
new file mode 100644
index 000000000..2e0990093
--- /dev/null
+++ b/Tests/CompatibleInterface/bar.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int bar()
+{
+ return 0;
+}
diff --git a/Tests/CompatibleInterface/foo.cpp b/Tests/CompatibleInterface/foo.cpp
new file mode 100644
index 000000000..e05eb7e69
--- /dev/null
+++ b/Tests/CompatibleInterface/foo.cpp
@@ -0,0 +1,4 @@
+int foo()
+{
+ return 0;
+}
diff --git a/Tests/CompatibleInterface/main.cpp b/Tests/CompatibleInterface/main.cpp
index f5e6e3891..d20b64b2b 100644
--- a/Tests/CompatibleInterface/main.cpp
+++ b/Tests/CompatibleInterface/main.cpp
@@ -23,10 +23,31 @@
#error Expected STRING_PROP3
#endif
+template<bool test>
+struct CMakeStaticAssert;
+
+template<>
+struct CMakeStaticAssert<true> {};
+
+enum {
+ NumericMaxTest1 = sizeof(CMakeStaticAssert<NUMBER_MAX_PROP1 == 100>),
+ NumericMaxTest2 = sizeof(CMakeStaticAssert<NUMBER_MAX_PROP2 == 250>),
+ NumericMinTest1 = sizeof(CMakeStaticAssert<NUMBER_MIN_PROP1 == 50>),
+ NumericMinTest2 = sizeof(CMakeStaticAssert<NUMBER_MIN_PROP2 == 200>),
+ NumericMinTest3 = sizeof(CMakeStaticAssert<NUMBER_MIN_PROP3 == 0xA>),
+ NumericMinTest4 = sizeof(CMakeStaticAssert<NUMBER_MIN_PROP4 == 0x10>)
+};
+
#include "iface2.h"
+int foo();
+#ifdef _WIN32
+__declspec(dllimport)
+#endif
+int bar();
+
int main(int argc, char **argv)
{
Iface2 if2;
- return if2.foo();
+ return if2.foo() + foo() + bar();
}
diff --git a/Tests/CompileDefinitions/CMakeLists.txt b/Tests/CompileDefinitions/CMakeLists.txt
index 930d22058..13d1b011f 100644
--- a/Tests/CompileDefinitions/CMakeLists.txt
+++ b/Tests/CompileDefinitions/CMakeLists.txt
@@ -1,6 +1,4 @@
-
cmake_minimum_required(VERSION 2.8)
-
project(CompileDefinitions)
if ("${CMAKE_GENERATOR}" STREQUAL "Visual Studio 6")
@@ -19,8 +17,8 @@ set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS
"BUILD_CONFIG_NAME=\"$<CONFIGURATION>\""
)
-add_subdirectory(add_definitions_command)
+add_subdirectory(add_def_cmd)
add_subdirectory(target_prop)
-add_subdirectory(add_definitions_command_with_target_prop)
+add_subdirectory(add_def_cmd_tprop)
add_executable(CompileDefinitions runtest.c)
diff --git a/Tests/CompileDefinitions/add_def_cmd/CMakeLists.txt b/Tests/CompileDefinitions/add_def_cmd/CMakeLists.txt
new file mode 100644
index 000000000..2bce60229
--- /dev/null
+++ b/Tests/CompileDefinitions/add_def_cmd/CMakeLists.txt
@@ -0,0 +1,12 @@
+add_definitions(-DCMAKE_IS_FUN -DCMAKE_IS=Fun -DCMAKE_IS_="Fun")
+if (NOT NO_SPACES_IN_DEFINE_VALUES)
+ add_definitions(-DCMAKE_IS_REALLY="Very Fun")
+endif()
+add_definitions(-DCMAKE_IS_="Fun")
+if (NOT NO_SPACES_IN_DEFINE_VALUES)
+ add_definitions(-DCMAKE_IS_REALLY="Very Fun")
+endif()
+add_definitions(-DCMAKE_IS_FUN -DCMAKE_IS=Fun)
+add_definitions(-DBUILD_IS_DEBUG=$<CONFIG:Debug> -DBUILD_IS_NOT_DEBUG=$<NOT:$<CONFIG:Debug>>)
+
+add_executable(add_def_cmd_exe ../compiletest.cpp)
diff --git a/Tests/CompileDefinitions/add_def_cmd_tprop/CMakeLists.txt b/Tests/CompileDefinitions/add_def_cmd_tprop/CMakeLists.txt
new file mode 100644
index 000000000..4ef8a0937
--- /dev/null
+++ b/Tests/CompileDefinitions/add_def_cmd_tprop/CMakeLists.txt
@@ -0,0 +1,16 @@
+add_definitions(-DCMAKE_IS_FUN -DCMAKE_IS=Fun)
+
+add_executable(add_def_cmd_tprop_exe ../compiletest.cpp)
+
+set_target_properties(add_def_cmd_tprop_exe PROPERTIES COMPILE_DEFINITIONS CMAKE_IS_="Fun")
+
+if (NOT NO_SPACES_IN_DEFINE_VALUES)
+ set_property(TARGET add_def_cmd_tprop_exe APPEND PROPERTY COMPILE_DEFINITIONS CMAKE_IS_REALLY="Very Fun")
+endif()
+
+add_definitions(-DCMAKE_IS_FUN)
+
+set_property(TARGET add_def_cmd_tprop_exe APPEND PROPERTY COMPILE_DEFINITIONS CMAKE_IS=Fun CMAKE_IS_="Fun")
+
+add_definitions(-DBUILD_IS_DEBUG=$<CONFIG:Debug>)
+set_property(TARGET add_def_cmd_tprop_exe APPEND PROPERTY COMPILE_DEFINITIONS BUILD_IS_NOT_DEBUG=$<NOT:$<CONFIG:Debug>>)
diff --git a/Tests/CompileDefinitions/add_definitions_command/CMakeLists.txt b/Tests/CompileDefinitions/add_definitions_command/CMakeLists.txt
deleted file mode 100644
index 23e013425..000000000
--- a/Tests/CompileDefinitions/add_definitions_command/CMakeLists.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-
-project(add_definitions_command)
-
-add_definitions(-DCMAKE_IS_FUN -DCMAKE_IS=Fun -DCMAKE_IS_="Fun")
-if (NOT NO_SPACES_IN_DEFINE_VALUES)
- add_definitions(-DCMAKE_IS_REALLY="Very Fun")
-endif()
-add_definitions(-DCMAKE_IS_="Fun")
-if (NOT NO_SPACES_IN_DEFINE_VALUES)
- add_definitions(-DCMAKE_IS_REALLY="Very Fun")
-endif()
-add_definitions(-DCMAKE_IS_FUN -DCMAKE_IS=Fun)
-add_definitions(-DBUILD_IS_DEBUG=$<CONFIG:Debug> -DBUILD_IS_NOT_DEBUG=$<NOT:$<CONFIG:Debug>>)
-
-add_executable(add_definitions_command_executable ../compiletest.cpp)
diff --git a/Tests/CompileDefinitions/add_definitions_command_with_target_prop/CMakeLists.txt b/Tests/CompileDefinitions/add_definitions_command_with_target_prop/CMakeLists.txt
deleted file mode 100644
index 55108db7a..000000000
--- a/Tests/CompileDefinitions/add_definitions_command_with_target_prop/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-project(add_definitions_command_with_target_prop)
-
-add_definitions(-DCMAKE_IS_FUN -DCMAKE_IS=Fun)
-
-add_executable(add_definitions_command_with_target_prop_executable ../compiletest.cpp)
-
-set_target_properties(add_definitions_command_with_target_prop_executable PROPERTIES COMPILE_DEFINITIONS CMAKE_IS_="Fun")
-
-if (NOT NO_SPACES_IN_DEFINE_VALUES)
- set_property(TARGET add_definitions_command_with_target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS CMAKE_IS_REALLY="Very Fun")
-endif()
-
-add_definitions(-DCMAKE_IS_FUN)
-
-set_property(TARGET add_definitions_command_with_target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS CMAKE_IS=Fun CMAKE_IS_="Fun")
-
-add_definitions(-DBUILD_IS_DEBUG=$<CONFIG:Debug>)
-set_property(TARGET add_definitions_command_with_target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS BUILD_IS_NOT_DEBUG=$<NOT:$<CONFIG:Debug>>)
diff --git a/Tests/CompileDefinitions/compiletest.c b/Tests/CompileDefinitions/compiletest.c
index d7883af77..8871750af 100644
--- a/Tests/CompileDefinitions/compiletest.c
+++ b/Tests/CompileDefinitions/compiletest.c
@@ -13,6 +13,10 @@
#error Unexpected LINK_LANGUAGE_IS_CXX
#endif
+#ifdef DEBUG_MODE
+#error Unexpected DEBUG_MODE
+#endif
+
int main(void)
{
return 0;
diff --git a/Tests/CompileDefinitions/target_prop/CMakeLists.txt b/Tests/CompileDefinitions/target_prop/CMakeLists.txt
index a0d3f4e96..311975ce5 100644
--- a/Tests/CompileDefinitions/target_prop/CMakeLists.txt
+++ b/Tests/CompileDefinitions/target_prop/CMakeLists.txt
@@ -35,6 +35,9 @@ set_property(TARGET target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS
add_executable(target_prop_c_executable ../compiletest.c)
+cmake_policy(SET CMP0043 NEW)
+set_property(TARGET target_prop_c_executable APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG DEBUG_MODE)
+
set_property(TARGET target_prop_c_executable APPEND PROPERTY COMPILE_DEFINITIONS
"$<$<STREQUAL:$<TARGET_PROPERTY:LINKER_LANGUAGE>,CXX>:LINK_CXX_DEFINE>"
"$<$<STREQUAL:$<TARGET_PROPERTY:LINKER_LANGUAGE>,C>:LINK_C_DEFINE>"
@@ -50,3 +53,8 @@ set_property(TARGET target_prop_mixed_executable APPEND PROPERTY COMPILE_DEFINIT
"LINK_LANGUAGE_IS_$<TARGET_PROPERTY:LINKER_LANGUAGE>"
"C_EXECUTABLE_LINK_LANGUAGE_IS_$<TARGET_PROPERTY:target_prop_c_executable,LINKER_LANGUAGE>"
)
+
+add_library(tgt STATIC IMPORTED)
+set_property(TARGET tgt APPEND PROPERTY COMPILE_DEFINITIONS TGT_DEF TGT_TYPE_$<TARGET_PROPERTY:TYPE>)
+add_executable(usetgt usetgt.c)
+target_compile_definitions(usetgt PRIVATE $<TARGET_PROPERTY:tgt,COMPILE_DEFINITIONS>)
diff --git a/Tests/CompileDefinitions/target_prop/usetgt.c b/Tests/CompileDefinitions/target_prop/usetgt.c
new file mode 100644
index 000000000..6672a3e8f
--- /dev/null
+++ b/Tests/CompileDefinitions/target_prop/usetgt.c
@@ -0,0 +1,10 @@
+#ifndef TGT_DEF
+# error TGT_DEF incorrectly not defined
+#endif
+#ifndef TGT_TYPE_STATIC_LIBRARY
+# error TGT_TYPE_STATIC_LIBRARY incorrectly not defined
+#endif
+#ifdef TGT_TYPE_EXECUTABLE
+# error TGT_TYPE_EXECUTABLE incorrectly defined
+#endif
+int main(void) { return 0; }
diff --git a/Tests/CompileFeatures/CMakeLists.txt b/Tests/CompileFeatures/CMakeLists.txt
new file mode 100644
index 000000000..a32138d71
--- /dev/null
+++ b/Tests/CompileFeatures/CMakeLists.txt
@@ -0,0 +1,337 @@
+
+cmake_minimum_required(VERSION 3.1)
+
+project(CompileFeatures)
+
+if (NOT CMAKE_C_COMPILE_FEATURES AND NOT CMAKE_CXX_COMPILE_FEATURES)
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp"
+ "int main(int,char**) { return 0; }\n"
+ )
+ add_executable(CompileFeatures "${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp")
+ return()
+endif()
+
+macro(run_test feature lang)
+ if (";${CMAKE_${lang}_COMPILE_FEATURES};" MATCHES ${feature})
+ add_library(test_${feature} OBJECT ${feature})
+ set_property(TARGET test_${feature}
+ PROPERTY COMPILE_FEATURES "${feature}"
+ )
+ else()
+ list(APPEND ${lang}_non_features ${feature})
+ endif()
+endmacro()
+
+get_property(c_features GLOBAL PROPERTY CMAKE_C_KNOWN_FEATURES)
+foreach(feature ${c_features})
+ run_test(${feature} C)
+endforeach()
+get_property(cxx_features GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES)
+foreach(feature ${cxx_features})
+ run_test(${feature} CXX)
+endforeach()
+
+if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang"
+ AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.1)
+ # AppleClang prior to 5.1 does not set any preprocessor define to distinguish
+ # c++1y from c++11, so CMake does not support c++1y features before AppleClang 5.1.
+ list(REMOVE_ITEM CXX_non_features
+ cxx_attribute_deprecated
+ cxx_binary_literals
+ )
+endif()
+
+if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang"
+ AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.2)
+ # AppleClang prior to 4.1 reports false for __has_feature(cxx_local_type_template_args)
+ # and __has_feature(cxx_unrestricted_unions) but it happens to pass these tests.
+ list(REMOVE_ITEM CXX_non_features
+ cxx_local_type_template_args
+ cxx_unrestricted_unions
+ )
+endif()
+
+if (CMAKE_CXX_COMPILER_ID STREQUAL SunPro)
+ list(REMOVE_ITEM CXX_non_features
+ cxx_attribute_deprecated
+ cxx_contextual_conversions
+ cxx_extended_friend_declarations
+ cxx_long_long_type
+ cxx_sizeof_member
+ cxx_variadic_macros
+ )
+endif()
+
+if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
+ AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.5)
+ # The cxx_raw_string_literals feature happens to work in some distributions
+ # of GNU 4.4, but it is first documented as available with GNU 4.5.
+ list(REMOVE_ITEM CXX_non_features
+ cxx_raw_string_literals
+ )
+endif()
+if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
+ AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6)
+ # The cxx_constexpr feature happens to work (for *this* testcase) with
+ # GNU 4.5, but it is first documented as available with GNU 4.6.
+ list(REMOVE_ITEM CXX_non_features
+ cxx_constexpr
+ )
+endif()
+if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
+ AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
+ # The cxx_alignof feature happens to work (for *this* testcase) with
+ # GNU 4.7, but it is first documented as available with GNU 4.8.
+ list(REMOVE_ITEM CXX_non_features
+ cxx_alignof
+ )
+endif()
+if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
+ AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)
+ # GNU prior to 4.9 does not set any preprocessor define to distinguish
+ # c++1y from c++11, so CMake does not support c++1y features before GNU 4.9.
+ list(REMOVE_ITEM CXX_non_features
+ # GNU 4.8 knows cxx_attributes, but doesn't know [[deprecated]]
+ # and warns that it is unknown and ignored.
+ cxx_attribute_deprecated
+ cxx_binary_literals
+ cxx_lambda_init_captures
+ cxx_return_type_deduction
+ )
+endif()
+
+if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
+ if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18.0)
+ list(REMOVE_ITEM CXX_non_features
+ # The cxx_contextual_conversions feature happens to work
+ # (for *this* testcase) with VS 2010 and VS 2012, but
+ # they do not document support until VS 2013.
+ cxx_contextual_conversions
+ )
+ elseif (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.0)
+ list(REMOVE_ITEM CXX_non_features
+ # The cxx_deleted_functions and cxx_nonstatic_member_init
+ # features happen to work (for *this* testcase) with VS 2013,
+ # but they do not document support until VS 2015.
+ cxx_deleted_functions
+ cxx_nonstatic_member_init
+ )
+ endif()
+endif()
+
+set(C_ext c)
+set(C_standard_flag 11)
+set(CXX_ext cpp)
+set(CXX_standard_flag 14)
+foreach(lang CXX C)
+ if (CMAKE_${lang}_COMPILE_FEATURES)
+ foreach(feature ${${lang}_non_features})
+ message("Testing feature : ${feature}")
+ try_compile(${feature}_works
+ "${CMAKE_CURRENT_BINARY_DIR}/${feature}_test"
+ "${CMAKE_CURRENT_SOURCE_DIR}/feature_test.${${lang}_ext}"
+ COMPILE_DEFINITIONS "-DTEST=${feature}.${${lang}_ext}"
+ CMAKE_FLAGS "-DCMAKE_${lang}_STANDARD=${${lang}_standard_flag}"
+ "-DINCLUDE_DIRECTORIES=${CMAKE_CURRENT_SOURCE_DIR}"
+ OUTPUT_VARIABLE OUTPUT
+ )
+ if (${feature}_works)
+ message(SEND_ERROR
+ "Feature ${feature} expected not to work for ${lang} ${CMAKE_${lang}_COMPILER_ID}-${CMAKE_${lang}_COMPILER_VERSION}.
+ Update the supported features or blacklist it.\n${OUTPUT}")
+ else()
+ message("Testing feature : ${feature} -- Fails, as expected.")
+ endif()
+ endforeach()
+ endif()
+endforeach()
+
+if (CMAKE_C_COMPILE_FEATURES)
+ if (CMAKE_C_STANDARD_DEFAULT)
+ string(FIND "${CMAKE_C_FLAGS}" "-std=" std_flag_idx)
+ if (std_flag_idx EQUAL -1)
+ add_executable(default_dialect_C default_dialect.c)
+ target_compile_definitions(default_dialect_C PRIVATE
+ DEFAULT_C11=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},11>
+ DEFAULT_C99=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},99>
+ DEFAULT_C90=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},90>
+ )
+ endif()
+ endif()
+
+ add_executable(CompileFeaturesGenex_C genex_test.c)
+ set_property(TARGET CompileFeaturesGenex_C PROPERTY C_STANDARD 11)
+
+ if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
+ if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.6)
+ list(APPEND expected_defs
+ EXPECT_C_STATIC_ASSERT=1
+ )
+ else()
+ list(APPEND expected_defs
+ EXPECT_C_STATIC_ASSERT=0
+ )
+ endif()
+ elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang"
+ OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
+ list(APPEND expected_defs
+ EXPECT_C_STATIC_ASSERT=1
+ )
+ endif()
+
+ list(APPEND expected_defs
+ EXPECT_C_FUNCTION_PROTOTYPES=1
+ EXPECT_C_RESTRICT=1
+ )
+
+ target_compile_definitions(CompileFeaturesGenex_C PRIVATE
+ HAVE_C_FUNCTION_PROTOTYPES=$<COMPILE_FEATURES:c_function_prototypes>
+ HAVE_C_RESTRICT=$<COMPILE_FEATURES:c_restrict>
+ HAVE_C_STATIC_ASSERT=$<COMPILE_FEATURES:c_static_assert>
+ ${expected_defs}
+ )
+endif()
+
+if (CMAKE_CXX_COMPILE_FEATURES)
+ if (CMAKE_CXX_STANDARD_DEFAULT)
+ string(FIND "${CMAKE_CXX_FLAGS}" "-std=" std_flag_idx)
+ if (std_flag_idx EQUAL -1)
+ add_executable(default_dialect default_dialect.cpp)
+ target_compile_definitions(default_dialect PRIVATE
+ DEFAULT_CXX14=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},14>
+ DEFAULT_CXX11=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},11>
+ DEFAULT_CXX98=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},98>
+ )
+ endif()
+ endif()
+
+ add_executable(CompileFeatures main.cpp)
+ set_property(TARGET CompileFeatures
+ PROPERTY COMPILE_FEATURES "cxx_auto_type"
+ )
+ set_property(TARGET CompileFeatures
+ PROPERTY CXX_STANDARD_REQUIRED TRUE
+ )
+
+ add_executable(GenexCompileFeatures main.cpp)
+ set_property(TARGET GenexCompileFeatures
+ PROPERTY COMPILE_FEATURES "$<1:cxx_auto_type>;$<0:not_a_feature>"
+ )
+
+ add_library(iface INTERFACE)
+ set_property(TARGET iface
+ PROPERTY INTERFACE_COMPILE_FEATURES "cxx_auto_type"
+ )
+ add_executable(IfaceCompileFeatures main.cpp)
+ target_link_libraries(IfaceCompileFeatures iface)
+
+ if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
+ add_definitions(
+ -DEXPECT_OVERRIDE_CONTROL=1
+ -DEXPECT_INHERITING_CONSTRUCTORS=1
+ -DEXPECT_FINAL=1
+ -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1
+ )
+ elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7)
+ add_definitions(
+ -DEXPECT_OVERRIDE_CONTROL=1
+ -DEXPECT_INHERITING_CONSTRUCTORS=0
+ -DEXPECT_FINAL=1
+ -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
+ )
+ else()
+ add_definitions(
+ -DEXPECT_OVERRIDE_CONTROL=0
+ -DEXPECT_INHERITING_CONSTRUCTORS=0
+ -DEXPECT_FINAL=0
+ -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
+ )
+ endif()
+ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+ add_definitions(
+ -DEXPECT_OVERRIDE_CONTROL=1
+ -DEXPECT_INHERITING_CONSTRUCTORS=1
+ -DEXPECT_FINAL=1
+ -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1
+ )
+ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
+ if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
+ add_definitions(
+ -DEXPECT_OVERRIDE_CONTROL=1
+ -DEXPECT_INHERITING_CONSTRUCTORS=1
+ -DEXPECT_FINAL=1
+ -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1
+ )
+ else()
+ add_definitions(
+ -DEXPECT_OVERRIDE_CONTROL=1
+ -DEXPECT_INHERITING_CONSTRUCTORS=0
+ -DEXPECT_FINAL=1
+ -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
+ )
+ endif()
+ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
+ if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.0)
+ add_definitions(
+ -DEXPECT_OVERRIDE_CONTROL=1
+ -DEXPECT_INHERITING_CONSTRUCTORS=1
+ -DEXPECT_FINAL=1
+ -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1
+ )
+ elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 17.0)
+ add_definitions(
+ -DEXPECT_OVERRIDE_CONTROL=1
+ -DEXPECT_INHERITING_CONSTRUCTORS=0
+ -DEXPECT_FINAL=1
+ -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
+ )
+ else()
+ add_definitions(
+ -DEXPECT_OVERRIDE_CONTROL=0
+ -DEXPECT_INHERITING_CONSTRUCTORS=0
+ -DEXPECT_FINAL=0
+ -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
+ )
+ endif()
+ elseif (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro")
+ add_definitions(
+ -DEXPECT_OVERRIDE_CONTROL=1
+ -DEXPECT_INHERITING_CONSTRUCTORS=1
+ -DEXPECT_FINAL=1
+ -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1
+ )
+ endif()
+
+ add_executable(CompileFeaturesGenex genex_test.cpp)
+ set_property(TARGET CompileFeaturesGenex PROPERTY CXX_STANDARD 11)
+ target_compile_definitions(CompileFeaturesGenex PRIVATE
+ HAVE_OVERRIDE_CONTROL=$<COMPILE_FEATURES:cxx_final,cxx_override>
+ HAVE_AUTO_TYPE=$<COMPILE_FEATURES:cxx_auto_type>
+ HAVE_INHERITING_CONSTRUCTORS=$<COMPILE_FEATURES:cxx_inheriting_constructors>
+ HAVE_FINAL=$<COMPILE_FEATURES:cxx_final>
+ HAVE_INHERITING_CONSTRUCTORS_AND_FINAL=$<COMPILE_FEATURES:cxx_inheriting_constructors,cxx_final>
+ )
+
+ add_executable(CompileFeaturesGenex2 genex_test.cpp)
+ target_compile_features(CompileFeaturesGenex2 PRIVATE cxx_static_assert)
+ target_compile_definitions(CompileFeaturesGenex2 PRIVATE
+ HAVE_OVERRIDE_CONTROL=$<COMPILE_FEATURES:cxx_final,cxx_override>
+ HAVE_AUTO_TYPE=$<COMPILE_FEATURES:cxx_auto_type>
+ HAVE_INHERITING_CONSTRUCTORS=$<COMPILE_FEATURES:cxx_inheriting_constructors>
+ HAVE_FINAL=$<COMPILE_FEATURES:cxx_final>
+ HAVE_INHERITING_CONSTRUCTORS_AND_FINAL=$<COMPILE_FEATURES:cxx_inheriting_constructors,cxx_final>
+ )
+
+ add_library(static_assert_iface INTERFACE)
+ target_compile_features(static_assert_iface INTERFACE cxx_static_assert)
+ add_executable(CompileFeaturesGenex3 genex_test.cpp)
+ target_link_libraries(CompileFeaturesGenex3 PRIVATE static_assert_iface)
+ target_compile_definitions(CompileFeaturesGenex3 PRIVATE
+ HAVE_OVERRIDE_CONTROL=$<COMPILE_FEATURES:cxx_final,cxx_override>
+ HAVE_AUTO_TYPE=$<COMPILE_FEATURES:cxx_auto_type>
+ HAVE_INHERITING_CONSTRUCTORS=$<COMPILE_FEATURES:cxx_inheriting_constructors>
+ HAVE_FINAL=$<COMPILE_FEATURES:cxx_final>
+ HAVE_INHERITING_CONSTRUCTORS_AND_FINAL=$<COMPILE_FEATURES:cxx_inheriting_constructors,cxx_final>
+ )
+endif()
diff --git a/Tests/CompileFeatures/c_function_prototypes.c b/Tests/CompileFeatures/c_function_prototypes.c
new file mode 100644
index 000000000..ab3c94887
--- /dev/null
+++ b/Tests/CompileFeatures/c_function_prototypes.c
@@ -0,0 +1,9 @@
+
+int someFunc(int a, int b);
+
+int someFunc(int a, int b)
+{
+ (void)a;
+ (void)b;
+ return 0;
+}
diff --git a/Tests/CompileFeatures/c_restrict.c b/Tests/CompileFeatures/c_restrict.c
new file mode 100644
index 000000000..7bc756658
--- /dev/null
+++ b/Tests/CompileFeatures/c_restrict.c
@@ -0,0 +1,7 @@
+
+int f (int * restrict a, int * restrict b)
+{
+ (void)a;
+ (void)b;
+ return 0;
+}
diff --git a/Tests/CompileFeatures/c_static_assert.c b/Tests/CompileFeatures/c_static_assert.c
new file mode 100644
index 000000000..afab50418
--- /dev/null
+++ b/Tests/CompileFeatures/c_static_assert.c
@@ -0,0 +1,2 @@
+
+_Static_assert(1, "Static assert test");
diff --git a/Tests/CompileFeatures/c_variadic_macros.c b/Tests/CompileFeatures/c_variadic_macros.c
new file mode 100644
index 000000000..4da111e62
--- /dev/null
+++ b/Tests/CompileFeatures/c_variadic_macros.c
@@ -0,0 +1,15 @@
+
+int someFunc(int i1, char c, int i2)
+{
+ (void)i1;
+ (void)c;
+ (void)i2;
+ return 0;
+}
+
+#define FUNC_WRAPPER(...) someFunc(__VA_ARGS__)
+
+void otherFunc()
+{
+ FUNC_WRAPPER(42, 'a', 7);
+}
diff --git a/Tests/CompileFeatures/cxx_aggregate_default_initializers.cpp b/Tests/CompileFeatures/cxx_aggregate_default_initializers.cpp
new file mode 100644
index 000000000..63a3713cf
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_aggregate_default_initializers.cpp
@@ -0,0 +1,9 @@
+
+struct X { int i, j, k = 42; };
+
+int someFunc()
+{
+ X a[] = { 1, 2, 3, 4, 5, 6 };
+ X b[2] = { { 1, 2, 3 }, { 4, 5, 6 } };
+ return a[0].k == b[0].k && a[1].k == b[1].k ? 0 : 1;
+}
diff --git a/Tests/CompileFeatures/cxx_alias_templates.cpp b/Tests/CompileFeatures/cxx_alias_templates.cpp
new file mode 100644
index 000000000..a47e27ded
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_alias_templates.cpp
@@ -0,0 +1,11 @@
+
+template <typename T1, typename T2>
+struct A
+{
+ typedef T1 MyT1;
+ using MyT2 = T2;
+};
+
+using B = A<int, char>;
+template<typename T>
+using C = A<int, T>;
diff --git a/Tests/CompileFeatures/cxx_alignas.cpp b/Tests/CompileFeatures/cxx_alignas.cpp
new file mode 100644
index 000000000..35b7c8294
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_alignas.cpp
@@ -0,0 +1,4 @@
+
+struct S1 {
+ alignas(8) int n;
+};
diff --git a/Tests/CompileFeatures/cxx_alignof.cpp b/Tests/CompileFeatures/cxx_alignof.cpp
new file mode 100644
index 000000000..63b14fec9
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_alignof.cpp
@@ -0,0 +1,5 @@
+
+int someFunc()
+{
+ return alignof(int);
+}
diff --git a/Tests/CompileFeatures/cxx_attribute_deprecated.cpp b/Tests/CompileFeatures/cxx_attribute_deprecated.cpp
new file mode 100644
index 000000000..b6f307d9e
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_attribute_deprecated.cpp
@@ -0,0 +1,11 @@
+
+[[deprecated]]
+int foo()
+{
+ return 0;
+}
+
+int someFunc()
+{
+ return foo();
+}
diff --git a/Tests/CompileFeatures/cxx_attributes.cpp b/Tests/CompileFeatures/cxx_attributes.cpp
new file mode 100644
index 000000000..a3c89eaba
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_attributes.cpp
@@ -0,0 +1,2 @@
+
+void unusedFunc [[noreturn]] () { throw 1; }
diff --git a/Tests/CompileFeatures/cxx_auto_type.cpp b/Tests/CompileFeatures/cxx_auto_type.cpp
new file mode 100644
index 000000000..1f36a7966
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_auto_type.cpp
@@ -0,0 +1,12 @@
+
+double foo_ = 3.14;
+
+double& foo()
+{
+ return foo_;
+}
+
+void someFunc()
+{
+ auto& x = foo();
+}
diff --git a/Tests/CompileFeatures/cxx_binary_literals.cpp b/Tests/CompileFeatures/cxx_binary_literals.cpp
new file mode 100644
index 000000000..14a9e7523
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_binary_literals.cpp
@@ -0,0 +1,6 @@
+
+int someFunc()
+{
+ int i = 0b101;
+ return i - 5;
+}
diff --git a/Tests/CompileFeatures/cxx_constexpr.cpp b/Tests/CompileFeatures/cxx_constexpr.cpp
new file mode 100644
index 000000000..570c10fb9
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_constexpr.cpp
@@ -0,0 +1,5 @@
+
+constexpr int getNum()
+{
+ return 42;
+}
diff --git a/Tests/CompileFeatures/cxx_contextual_conversions.cpp b/Tests/CompileFeatures/cxx_contextual_conversions.cpp
new file mode 100644
index 000000000..34386246d
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_contextual_conversions.cpp
@@ -0,0 +1,33 @@
+
+#define assert(E) if(!(E)) return 1;
+
+template<class T>
+class zero_init
+{
+public:
+ zero_init( )
+ : val( static_cast<T>(0) ) { }
+ zero_init( T val ) : val( val )
+ { }
+ operator T & ( ) { return val; }
+ operator T ( ) const { return val; }
+private:
+ T val;
+};
+
+int someFunc()
+{
+ zero_init<int*> p; assert( p == 0 );
+ p = new int(7);
+ assert( *p == 7 );
+ delete p;
+
+ zero_init<int> i; assert( i == 0 );
+ i = 7;
+ assert( i == 7 );
+ switch( i ) { }
+
+ int *vp = new int[i];
+
+ return 0;
+}
diff --git a/Tests/CompileFeatures/cxx_decltype.cpp b/Tests/CompileFeatures/cxx_decltype.cpp
new file mode 100644
index 000000000..24ec51e84
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_decltype.cpp
@@ -0,0 +1,7 @@
+
+int someFunc()
+{
+ int i = 0;
+ decltype(i) other = 0;
+ return other;
+}
diff --git a/Tests/CompileFeatures/cxx_decltype_auto.cpp b/Tests/CompileFeatures/cxx_decltype_auto.cpp
new file mode 100644
index 000000000..900bb6d79
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_decltype_auto.cpp
@@ -0,0 +1,6 @@
+
+int someFunc(int argc, char**)
+{
+ decltype(auto) i = argc;
+ return 0;
+}
diff --git a/Tests/CompileFeatures/cxx_decltype_incomplete_return_types.cpp b/Tests/CompileFeatures/cxx_decltype_incomplete_return_types.cpp
new file mode 100644
index 000000000..109d0384c
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_decltype_incomplete_return_types.cpp
@@ -0,0 +1,14 @@
+
+template<class T>
+struct A
+{
+ ~A() = delete;
+};
+
+template<class T> auto h() -> A<T>;
+template<class T> auto i(T) -> T;
+template<class T> auto f(T) -> decltype(i(h<T>()));
+template<class T> auto f(T) -> void;
+auto g() -> void {
+ f(42);
+}
diff --git a/Tests/CompileFeatures/cxx_default_function_template_args.cpp b/Tests/CompileFeatures/cxx_default_function_template_args.cpp
new file mode 100644
index 000000000..3d14c52ca
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_default_function_template_args.cpp
@@ -0,0 +1,12 @@
+
+template<typename T = int>
+int someFunc()
+{
+ T t = 0;
+ return t;
+}
+
+void otherFunc()
+{
+ someFunc();
+}
diff --git a/Tests/CompileFeatures/cxx_defaulted_functions.cpp b/Tests/CompileFeatures/cxx_defaulted_functions.cpp
new file mode 100644
index 000000000..b679a9269
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_defaulted_functions.cpp
@@ -0,0 +1,9 @@
+
+struct A {
+ A() = default;
+};
+
+void someFunc()
+{
+ A a;
+}
diff --git a/Tests/CompileFeatures/cxx_defaulted_move_initializers.cpp b/Tests/CompileFeatures/cxx_defaulted_move_initializers.cpp
new file mode 100644
index 000000000..14f987147
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_defaulted_move_initializers.cpp
@@ -0,0 +1,7 @@
+
+struct A
+{
+ A() = default;
+ A& operator=(A&&) = default;
+ A(A&&) = default;
+};
diff --git a/Tests/CompileFeatures/cxx_delegating_constructors.cpp b/Tests/CompileFeatures/cxx_delegating_constructors.cpp
new file mode 100644
index 000000000..4b41615b9
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_delegating_constructors.cpp
@@ -0,0 +1,15 @@
+
+class Foo
+{
+public:
+ Foo(int i);
+
+ Foo(double d)
+ : Foo(static_cast<int>(d))
+ {
+
+ }
+
+private:
+ int m_i;
+};
diff --git a/Tests/CompileFeatures/cxx_deleted_functions.cpp b/Tests/CompileFeatures/cxx_deleted_functions.cpp
new file mode 100644
index 000000000..4ecb1e9d5
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_deleted_functions.cpp
@@ -0,0 +1,6 @@
+
+struct A
+{
+ A(const A&) = delete;
+ A& operator=(const A&) = delete;
+};
diff --git a/Tests/CompileFeatures/cxx_digit_separators.cpp b/Tests/CompileFeatures/cxx_digit_separators.cpp
new file mode 100644
index 000000000..abcd1c8fa
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_digit_separators.cpp
@@ -0,0 +1,6 @@
+
+int someFunc()
+{
+ int one_thousand = 1'000;
+ return one_thousand - 1000;
+}
diff --git a/Tests/CompileFeatures/cxx_enum_forward_declarations.cpp b/Tests/CompileFeatures/cxx_enum_forward_declarations.cpp
new file mode 100644
index 000000000..a7e144537
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_enum_forward_declarations.cpp
@@ -0,0 +1,8 @@
+
+enum SomeEnum : short;
+
+void someFunc()
+{
+ SomeEnum value;
+ int i = value;
+}
diff --git a/Tests/CompileFeatures/cxx_explicit_conversions.cpp b/Tests/CompileFeatures/cxx_explicit_conversions.cpp
new file mode 100644
index 000000000..0decdcd43
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_explicit_conversions.cpp
@@ -0,0 +1,10 @@
+
+class A
+{
+ int m_i;
+public:
+ explicit operator bool()
+ {
+ return m_i != 0;
+ }
+};
diff --git a/Tests/CompileFeatures/cxx_extended_friend_declarations.cpp b/Tests/CompileFeatures/cxx_extended_friend_declarations.cpp
new file mode 100644
index 000000000..631c699a9
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_extended_friend_declarations.cpp
@@ -0,0 +1,25 @@
+
+template <typename T>
+struct B
+{
+ B() : m_i(42) {}
+private:
+ int m_i;
+ friend T;
+};
+
+struct A
+{
+ template<typename T>
+ int getBValue(B<T> b)
+ {
+ return b.m_i;
+ }
+};
+
+void someFunc()
+{
+ A a;
+ B<A> b;
+ a.getBValue(b);
+}
diff --git a/Tests/CompileFeatures/cxx_extern_templates.cpp b/Tests/CompileFeatures/cxx_extern_templates.cpp
new file mode 100644
index 000000000..9fa4aa4cc
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_extern_templates.cpp
@@ -0,0 +1,12 @@
+
+template<typename T>
+void someFunc()
+{
+}
+
+extern template void someFunc<int>();
+
+void otherFunc()
+{
+ someFunc<int>();
+}
diff --git a/Tests/CompileFeatures/cxx_final.cpp b/Tests/CompileFeatures/cxx_final.cpp
new file mode 100644
index 000000000..598cb943f
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_final.cpp
@@ -0,0 +1,2 @@
+
+struct A final {};
diff --git a/Tests/CompileFeatures/cxx_func_identifier.cpp b/Tests/CompileFeatures/cxx_func_identifier.cpp
new file mode 100644
index 000000000..0c3595cee
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_func_identifier.cpp
@@ -0,0 +1,6 @@
+
+void someFunc()
+{
+ bool b = sizeof(__func__);
+ (void)b;
+}
diff --git a/Tests/CompileFeatures/cxx_generalized_initializers.cpp b/Tests/CompileFeatures/cxx_generalized_initializers.cpp
new file mode 100644
index 000000000..ad05f1204
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_generalized_initializers.cpp
@@ -0,0 +1,28 @@
+#if defined(_MSC_VER) && _MSC_VER == 1800 && _MSC_FULL_VER < 180030723
+# error "VS 2013 safely supports this only with Update 3 or greater"
+#endif
+
+// Dummy implementation. Test only the compiler feature.
+namespace std {
+ typedef decltype(sizeof(int)) size_t;
+ template <class _E>
+ class initializer_list
+ {
+ const _E* __begin_;
+ size_t __size_;
+ public:
+ template <typename T1, typename T2>
+ initializer_list(T1, T2) {}
+ };
+}
+
+template <typename T>
+struct A
+{
+ A(std::initializer_list<T>) {}
+};
+
+void someFunc()
+{
+ A<int> as = { 1, 2, 3, 4 };
+}
diff --git a/Tests/CompileFeatures/cxx_generic_lambdas.cpp b/Tests/CompileFeatures/cxx_generic_lambdas.cpp
new file mode 100644
index 000000000..ae1b78edd
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_generic_lambdas.cpp
@@ -0,0 +1,6 @@
+
+int someFunc()
+{
+ auto identity = [](auto a) { return a; };
+ return identity(0);
+}
diff --git a/Tests/CompileFeatures/cxx_inheriting_constructors.cpp b/Tests/CompileFeatures/cxx_inheriting_constructors.cpp
new file mode 100644
index 000000000..cfce88022
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_inheriting_constructors.cpp
@@ -0,0 +1,18 @@
+
+struct A
+{
+ int m_i;
+
+ A(int i) : m_i(i) {}
+};
+
+struct B : public A
+{
+ using A::A;
+};
+
+void someFunc()
+{
+ int i = 0;
+ B b(i);
+}
diff --git a/Tests/CompileFeatures/cxx_inline_namespaces.cpp b/Tests/CompileFeatures/cxx_inline_namespaces.cpp
new file mode 100644
index 000000000..59fa9c8f5
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_inline_namespaces.cpp
@@ -0,0 +1,26 @@
+namespace Lib
+{
+inline namespace Lib_1
+{
+ template <typename T> class A;
+}
+
+template <typename T> void g(T);
+}
+
+struct MyClass {
+
+};
+namespace Lib
+{
+template<>
+class A<MyClass> {
+
+};
+}
+
+void someFunc()
+{
+ Lib::A<MyClass> a;
+ g(a); // ok, Lib is an associated namespace of A
+}
diff --git a/Tests/CompileFeatures/cxx_lambda_init_captures.cpp b/Tests/CompileFeatures/cxx_lambda_init_captures.cpp
new file mode 100644
index 000000000..7e337faf4
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_lambda_init_captures.cpp
@@ -0,0 +1,6 @@
+
+int someFunc()
+{
+ int a = 0;
+ return [b = static_cast<int&&>(a)]() { return b; }();
+}
diff --git a/Tests/CompileFeatures/cxx_lambdas.cpp b/Tests/CompileFeatures/cxx_lambdas.cpp
new file mode 100644
index 000000000..eecaa23a3
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_lambdas.cpp
@@ -0,0 +1,5 @@
+
+void someFunc()
+{
+ [](){}();
+}
diff --git a/Tests/CompileFeatures/cxx_local_type_template_args.cpp b/Tests/CompileFeatures/cxx_local_type_template_args.cpp
new file mode 100644
index 000000000..802ea7a0a
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_local_type_template_args.cpp
@@ -0,0 +1,21 @@
+
+template <typename T>
+class X { };
+template <typename T>
+void f(T t) { }
+struct {} unnamed_obj;
+void f() {
+ struct A { };
+ enum { e1 };
+ typedef struct {} B;
+ B b;
+ X<A> x1;
+ X<A*> x2;
+ X<B> x3;
+ f(e1);
+ f(unnamed_obj);
+ f(b);
+ (void)x1;
+ (void)x2;
+ (void)x3;
+}
diff --git a/Tests/CompileFeatures/cxx_long_long_type.cpp b/Tests/CompileFeatures/cxx_long_long_type.cpp
new file mode 100644
index 000000000..670324c4a
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_long_long_type.cpp
@@ -0,0 +1,5 @@
+
+void someFunc()
+{
+ long long ll = 9223372036854775807LL;
+}
diff --git a/Tests/CompileFeatures/cxx_noexcept.cpp b/Tests/CompileFeatures/cxx_noexcept.cpp
new file mode 100644
index 000000000..a3c05b86a
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_noexcept.cpp
@@ -0,0 +1,5 @@
+
+void someFunc() noexcept
+{
+
+}
diff --git a/Tests/CompileFeatures/cxx_nonstatic_member_init.cpp b/Tests/CompileFeatures/cxx_nonstatic_member_init.cpp
new file mode 100644
index 000000000..6b7fa7098
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_nonstatic_member_init.cpp
@@ -0,0 +1,4 @@
+class A
+{
+ int m_i = 42;
+};
diff --git a/Tests/CompileFeatures/cxx_nullptr.cpp b/Tests/CompileFeatures/cxx_nullptr.cpp
new file mode 100644
index 000000000..96307dfc6
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_nullptr.cpp
@@ -0,0 +1,10 @@
+
+void someFunc(int*)
+{
+
+}
+
+void otherFunc()
+{
+ someFunc(nullptr);
+}
diff --git a/Tests/CompileFeatures/cxx_override.cpp b/Tests/CompileFeatures/cxx_override.cpp
new file mode 100644
index 000000000..55bec1389
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_override.cpp
@@ -0,0 +1,7 @@
+
+struct A {
+ virtual void doNothing() {}
+};
+struct B : A {
+ void doNothing() override {}
+};
diff --git a/Tests/CompileFeatures/cxx_range_for.cpp b/Tests/CompileFeatures/cxx_range_for.cpp
new file mode 100644
index 000000000..892109e90
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_range_for.cpp
@@ -0,0 +1,10 @@
+
+void someFunc()
+{
+ int accumulated = 0;
+ int numbers[] = { 1, 2, 5 };
+ for (int i : numbers)
+ {
+ accumulated += i;
+ }
+}
diff --git a/Tests/CompileFeatures/cxx_raw_string_literals.cpp b/Tests/CompileFeatures/cxx_raw_string_literals.cpp
new file mode 100644
index 000000000..ea4d2312c
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_raw_string_literals.cpp
@@ -0,0 +1,7 @@
+
+void someFunc()
+{
+const char p[] = R"(a\
+b
+c)";
+}
diff --git a/Tests/CompileFeatures/cxx_reference_qualified_functions.cpp b/Tests/CompileFeatures/cxx_reference_qualified_functions.cpp
new file mode 100644
index 000000000..83a2361a4
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_reference_qualified_functions.cpp
@@ -0,0 +1,11 @@
+
+struct test{
+ void f() & { }
+ void f() && { }
+};
+
+void someFunc(){
+ test t;
+ t.f(); // lvalue
+ test().f(); // rvalue
+}
diff --git a/Tests/CompileFeatures/cxx_relaxed_constexpr.cpp b/Tests/CompileFeatures/cxx_relaxed_constexpr.cpp
new file mode 100644
index 000000000..bce82e32a
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_relaxed_constexpr.cpp
@@ -0,0 +1,23 @@
+
+struct X {
+ constexpr X() : n(5) {
+ n *= 2;
+ }
+ int n;
+};
+
+constexpr int g(const int (&is)[4]) {
+ X x;
+ int r = x.n;
+ for (int i = 0; i < 5; ++i)
+ r += i;
+ for (auto& i : is)
+ r += i;
+ return r;
+}
+
+int someFunc()
+{
+ constexpr int k3 = g({ 4, 5, 6, 7 });
+ return k3 - 42;
+}
diff --git a/Tests/CompileFeatures/cxx_return_type_deduction.cpp b/Tests/CompileFeatures/cxx_return_type_deduction.cpp
new file mode 100644
index 000000000..009e91927
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_return_type_deduction.cpp
@@ -0,0 +1,10 @@
+
+auto sum(int a, int b)
+{
+ return a+b;
+}
+
+int someFunc()
+{
+ return sum(3, -3);
+}
diff --git a/Tests/CompileFeatures/cxx_right_angle_brackets.cpp b/Tests/CompileFeatures/cxx_right_angle_brackets.cpp
new file mode 100644
index 000000000..2713fd8d0
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_right_angle_brackets.cpp
@@ -0,0 +1,12 @@
+
+template<typename T>
+struct A
+{
+ typedef T Result;
+};
+
+void someFunc()
+{
+ A<A<int>> object;
+ (void)object;
+}
diff --git a/Tests/CompileFeatures/cxx_rvalue_references.cpp b/Tests/CompileFeatures/cxx_rvalue_references.cpp
new file mode 100644
index 000000000..787026a21
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_rvalue_references.cpp
@@ -0,0 +1,5 @@
+
+void someFunc(int&&)
+{
+
+}
diff --git a/Tests/CompileFeatures/cxx_sizeof_member.cpp b/Tests/CompileFeatures/cxx_sizeof_member.cpp
new file mode 100644
index 000000000..ae143d26f
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_sizeof_member.cpp
@@ -0,0 +1,10 @@
+
+struct A
+{
+ int m_i;
+};
+
+int someFunc()
+{
+ return sizeof(A::m_i) > 0 ? 1 : 2;
+}
diff --git a/Tests/CompileFeatures/cxx_static_assert.cpp b/Tests/CompileFeatures/cxx_static_assert.cpp
new file mode 100644
index 000000000..6aa8678f6
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_static_assert.cpp
@@ -0,0 +1,2 @@
+
+static_assert(true, "static_assert test");
diff --git a/Tests/CompileFeatures/cxx_strong_enums.cpp b/Tests/CompileFeatures/cxx_strong_enums.cpp
new file mode 100644
index 000000000..626245666
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_strong_enums.cpp
@@ -0,0 +1,7 @@
+
+enum class Colors
+{
+ RedColor,
+ GreenColor,
+ BlueColor
+};
diff --git a/Tests/CompileFeatures/cxx_template_template_parameters.cpp b/Tests/CompileFeatures/cxx_template_template_parameters.cpp
new file mode 100644
index 000000000..0fdd18d92
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_template_template_parameters.cpp
@@ -0,0 +1,18 @@
+
+template<template <typename> class T, typename U>
+void someFunc(T<U>)
+{
+
+}
+
+template<typename T>
+struct A
+{
+
+};
+
+void otherFunc()
+{
+ A<int> a;
+ someFunc(a);
+}
diff --git a/Tests/CompileFeatures/cxx_thread_local.cpp b/Tests/CompileFeatures/cxx_thread_local.cpp
new file mode 100644
index 000000000..1fb27e241
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_thread_local.cpp
@@ -0,0 +1,2 @@
+
+thread_local unsigned int rage = 1;
diff --git a/Tests/CompileFeatures/cxx_trailing_return_types.cpp b/Tests/CompileFeatures/cxx_trailing_return_types.cpp
new file mode 100644
index 000000000..01a76cbff
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_trailing_return_types.cpp
@@ -0,0 +1,5 @@
+
+auto someFunc() -> int
+{
+ return 42;
+}
diff --git a/Tests/CompileFeatures/cxx_unicode_literals.cpp b/Tests/CompileFeatures/cxx_unicode_literals.cpp
new file mode 100644
index 000000000..a7b7df0cd
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_unicode_literals.cpp
@@ -0,0 +1,3 @@
+
+const char16_t lit_16[] = u"\u00DA";
+const char32_t lit_32[] = U"\u00DA";
diff --git a/Tests/CompileFeatures/cxx_uniform_initialization.cpp b/Tests/CompileFeatures/cxx_uniform_initialization.cpp
new file mode 100644
index 000000000..82c76e20c
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_uniform_initialization.cpp
@@ -0,0 +1,9 @@
+struct A {};
+struct B {
+ B(A) {}
+};
+
+void Func()
+{
+ B b{A{}};
+}
diff --git a/Tests/CompileFeatures/cxx_unrestricted_unions.cpp b/Tests/CompileFeatures/cxx_unrestricted_unions.cpp
new file mode 100644
index 000000000..698fd61f9
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_unrestricted_unions.cpp
@@ -0,0 +1,11 @@
+
+struct point {
+ point() {}
+ point(int x, int y) : x_(x), y_(y) {}
+ int x_, y_;
+};
+union u {
+ point p_;
+ int i_;
+ const char* s_;
+};
diff --git a/Tests/CompileFeatures/cxx_user_literals.cpp b/Tests/CompileFeatures/cxx_user_literals.cpp
new file mode 100644
index 000000000..9e5a5889e
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_user_literals.cpp
@@ -0,0 +1,7 @@
+
+long double operator "" _meters(long double);
+
+void someFunc()
+{
+ long double i = 1.2_meters;
+}
diff --git a/Tests/CompileFeatures/cxx_variable_templates.cpp b/Tests/CompileFeatures/cxx_variable_templates.cpp
new file mode 100644
index 000000000..5d4bdbc35
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_variable_templates.cpp
@@ -0,0 +1,10 @@
+
+template<typename T>
+constexpr T pi = T(3.1415926535897932385);
+
+int someFunc()
+{
+ auto pi_int = pi<int>;
+ auto pi_float = pi<float>;
+ return pi_int - 3;
+}
diff --git a/Tests/CompileFeatures/cxx_variadic_macros.cpp b/Tests/CompileFeatures/cxx_variadic_macros.cpp
new file mode 100644
index 000000000..4d007a536
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_variadic_macros.cpp
@@ -0,0 +1,12 @@
+
+int someFunc(int, char, int)
+{
+ return 0;
+}
+
+#define FUNC_WRAPPER(...) someFunc(__VA_ARGS__)
+
+void otherFunc()
+{
+ FUNC_WRAPPER(42, 'a', 7);
+}
diff --git a/Tests/CompileFeatures/cxx_variadic_templates.cpp b/Tests/CompileFeatures/cxx_variadic_templates.cpp
new file mode 100644
index 000000000..e1f641b81
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_variadic_templates.cpp
@@ -0,0 +1,74 @@
+#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) < 407)
+#define OLD_GNU
+#endif
+
+#ifdef OLD_GNU
+template<int... Is>
+struct Interface;
+#endif
+
+template<int I, int... Is>
+struct Interface
+#ifdef OLD_GNU
+ <I, Is...>
+#endif
+{
+ static int accumulate()
+ {
+ return I + Interface<Is...>::accumulate();
+ }
+};
+
+template<int I>
+struct Interface<I>
+{
+ static int accumulate()
+ {
+ return I;
+ }
+};
+
+// Note: split this into a separate test if a
+// cxx_variadic_template_template_parameters feature is added.
+
+template<typename T>
+struct eval {
+ enum {
+ Matched = 0
+ };
+};
+
+template<template<typename...> class T, typename... U>
+struct eval<T<U...> > {
+ enum {
+ Matched = 1
+ };
+};
+
+template<typename...>
+struct A {
+
+};
+template<typename T>
+struct B {
+
+};
+template<typename T, typename U>
+struct C {
+
+};
+template<typename T, typename U, typename...>
+struct D {
+
+};
+
+// Note: This test assumes that a compiler supporting this feature
+// supports static_assert. Add a workaround if that does not hold.
+static_assert(eval<A<> >::Matched, "A Matches");
+static_assert(eval<A<int> >::Matched, "A Matches");
+static_assert(eval<A<int, char> >::Matched, "A Matches");
+static_assert(eval<B<int> >::Matched, "B Matches");
+static_assert(eval<C<int, char> >::Matched, "C Matches");
+static_assert(eval<D<int, char> >::Matched, "D Matches");
+static_assert(eval<D<int, char, bool> >::Matched, "D Matches");
+static_assert(eval<D<int, char, bool, double> >::Matched, "D Matches");
diff --git a/Tests/CompileFeatures/default_dialect.c b/Tests/CompileFeatures/default_dialect.c
new file mode 100644
index 000000000..1b39deca6
--- /dev/null
+++ b/Tests/CompileFeatures/default_dialect.c
@@ -0,0 +1,22 @@
+
+#if DEFAULT_C11
+# if __STDC_VERSION__ != 201112L
+# error Unexpected value for __STDC_VERSION__.
+# endif
+#elif DEFAULT_C99
+# if __STDC_VERSION__ != 199901L
+# error Unexpected value for __STDC_VERSION__.
+# endif
+#else
+# if !DEFAULT_C90
+# error Buildsystem error
+# endif
+# if defined(__STDC_VERSION__)
+# error Unexpected __STDC_VERSION__ definition
+# endif
+#endif
+
+int main()
+{
+ return 0;
+}
diff --git a/Tests/CompileFeatures/default_dialect.cpp b/Tests/CompileFeatures/default_dialect.cpp
new file mode 100644
index 000000000..a2ca268a4
--- /dev/null
+++ b/Tests/CompileFeatures/default_dialect.cpp
@@ -0,0 +1,25 @@
+
+template<long l>
+struct Outputter;
+
+#if DEFAULT_CXX14
+# if __cplusplus != 201402L
+Outputter<__cplusplus> o;
+# endif
+#elif DEFAULT_CXX11
+# if __cplusplus != 201103L
+Outputter<__cplusplus> o;
+# endif
+#else
+# if !DEFAULT_CXX98
+# error Buildsystem error
+# endif
+# if __cplusplus != 199711L && __cplusplus != 1 && !defined(__GXX_EXPERIMENTAL_CXX0X__)
+Outputter<__cplusplus> o;
+# endif
+#endif
+
+int main()
+{
+ return 0;
+}
diff --git a/Tests/CompileFeatures/feature_test.c b/Tests/CompileFeatures/feature_test.c
new file mode 100644
index 000000000..4147f1fbd
--- /dev/null
+++ b/Tests/CompileFeatures/feature_test.c
@@ -0,0 +1,10 @@
+
+#define STRINGIFY_IMPL(X) #X
+#define STRINGIFY(X) STRINGIFY_IMPL(X)
+
+#include STRINGIFY(TEST)
+
+int main(void)
+{
+ return 0;
+}
diff --git a/Tests/CompileFeatures/feature_test.cpp b/Tests/CompileFeatures/feature_test.cpp
new file mode 100644
index 000000000..4406c16e2
--- /dev/null
+++ b/Tests/CompileFeatures/feature_test.cpp
@@ -0,0 +1,10 @@
+
+#define STRINGIFY_IMPL(X) #X
+#define STRINGIFY(X) STRINGIFY_IMPL(X)
+
+#include STRINGIFY(TEST)
+
+int main()
+{
+ return 0;
+}
diff --git a/Tests/CompileFeatures/genex_test.c b/Tests/CompileFeatures/genex_test.c
new file mode 100644
index 000000000..b1215bd21
--- /dev/null
+++ b/Tests/CompileFeatures/genex_test.c
@@ -0,0 +1,38 @@
+#ifndef EXPECT_C_STATIC_ASSERT
+# error EXPECT_C_STATIC_ASSERT not defined
+#endif
+#ifndef EXPECT_C_FUNCTION_PROTOTYPES
+# error EXPECT_C_FUNCTION_PROTOTYPES not defined
+#endif
+#ifndef EXPECT_C_RESTRICT
+# error EXPECT_C_RESTRICT not defined
+#endif
+
+#if !EXPECT_C_STATIC_ASSERT
+#if EXPECT_C_STATIC_ASSERT
+#error "Expect c_static_assert feature"
+#endif
+#else
+#if !EXPECT_C_STATIC_ASSERT
+#error "Expect no c_static_assert feature"
+#endif
+#endif
+
+#if !EXPECT_C_FUNCTION_PROTOTYPES
+# error Expect c_function_prototypes support
+#endif
+
+#if !EXPECT_C_RESTRICT
+# if EXPECT_C_RESTRICT
+# error Expect c_restrict support
+# endif
+#else
+# if !EXPECT_C_RESTRICT
+# error Expect no c_restrict support
+# endif
+#endif
+
+int main()
+{
+
+}
diff --git a/Tests/CompileFeatures/genex_test.cpp b/Tests/CompileFeatures/genex_test.cpp
new file mode 100644
index 000000000..2161bca49
--- /dev/null
+++ b/Tests/CompileFeatures/genex_test.cpp
@@ -0,0 +1,72 @@
+#ifndef EXPECT_FINAL
+# error EXPECT_FINAL not defined
+#endif
+#ifndef EXPECT_INHERITING_CONSTRUCTORS
+# error EXPECT_INHERITING_CONSTRUCTORS not defined
+#endif
+#ifndef EXPECT_INHERITING_CONSTRUCTORS_AND_FINAL
+# error EXPECT_INHERITING_CONSTRUCTORS_AND_FINAL not defined
+#endif
+#ifndef EXPECT_OVERRIDE_CONTROL
+# error EXPECT_OVERRIDE_CONTROL not defined
+#endif
+
+#if !HAVE_OVERRIDE_CONTROL
+#if EXPECT_OVERRIDE_CONTROL
+#error "Expect override control feature"
+#endif
+#else
+#if !EXPECT_OVERRIDE_CONTROL
+#error "Expect no override control feature"
+#endif
+
+struct A
+{
+ virtual int getA() { return 7; }
+};
+
+struct B final : A
+{
+ int getA() override { return 42; }
+};
+
+#endif
+
+#if !HAVE_AUTO_TYPE
+# error Expect cxx_auto_type support
+#endif
+
+#if !HAVE_INHERITING_CONSTRUCTORS
+# if EXPECT_INHERITING_CONSTRUCTORS
+# error Expect cxx_inheriting_constructors support
+# endif
+#else
+# if !EXPECT_INHERITING_CONSTRUCTORS
+# error Expect no cxx_inheriting_constructors support
+# endif
+#endif
+
+#if !HAVE_FINAL
+# if EXPECT_FINAL
+# error Expect cxx_final support
+# endif
+#else
+# if !EXPECT_FINAL
+# error Expect no cxx_final support
+# endif
+#endif
+
+#if !HAVE_INHERITING_CONSTRUCTORS_AND_FINAL
+# if EXPECT_INHERITING_CONSTRUCTORS_AND_FINAL
+# error Expect cxx_inheriting_constructors and cxx_final support
+# endif
+#else
+# if !EXPECT_INHERITING_CONSTRUCTORS_AND_FINAL
+# error Expect no combined cxx_inheriting_constructors and cxx_final support
+# endif
+#endif
+
+int main()
+{
+
+}
diff --git a/Tests/CompileFeatures/main.cpp b/Tests/CompileFeatures/main.cpp
new file mode 100644
index 000000000..3a8e0fcea
--- /dev/null
+++ b/Tests/CompileFeatures/main.cpp
@@ -0,0 +1,6 @@
+
+int main(int,char**)
+{
+ auto value = 0;
+ return value;
+}
diff --git a/Tests/CompileOptions/CMakeLists.txt b/Tests/CompileOptions/CMakeLists.txt
index 9b6c9c2a0..692e0de0c 100644
--- a/Tests/CompileOptions/CMakeLists.txt
+++ b/Tests/CompileOptions/CMakeLists.txt
@@ -22,6 +22,12 @@ set_property(TARGET CompileOptions PROPERTY COMPILE_OPTIONS
${cxx_tests}
)
+if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|Borland|Embarcadero")
+ set_property(TARGET CompileOptions APPEND PROPERTY COMPILE_OPTIONS
+ "-DTEST_OCTOTHORPE=\"#\""
+ )
+endif()
+
target_link_libraries(CompileOptions testlib)
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
diff --git a/Tests/CompileOptions/main.cpp b/Tests/CompileOptions/main.cpp
index 42f4cca11..f3c135593 100644
--- a/Tests/CompileOptions/main.cpp
+++ b/Tests/CompileOptions/main.cpp
@@ -17,6 +17,9 @@
int main()
{
return (strcmp(NEEDS_ESCAPE, "E$CAPE") == 0
+#ifdef TEST_OCTOTHORPE
+ && strcmp(TEST_OCTOTHORPE, "#") == 0
+#endif
&& strcmp(EXPECTED_C_COMPILER_VERSION, TEST_C_COMPILER_VERSION) == 0
&& strcmp(EXPECTED_CXX_COMPILER_VERSION, TEST_CXX_COMPILER_VERSION) == 0
&& TEST_C_COMPILER_VERSION_EQUALITY == 1
diff --git a/Tests/Complex/CMakeLists.txt b/Tests/Complex/CMakeLists.txt
index 50dccbe57..9251ff37d 100644
--- a/Tests/Complex/CMakeLists.txt
+++ b/Tests/Complex/CMakeLists.txt
@@ -1,9 +1,16 @@
#
# A more complex test case
#
-set(CMAKE_BACKWARDS_COMPATIBILITY 1.4)
+cmake_minimum_required(VERSION 2.4)
project (Complex)
+# Test that renaming a built-in works when configured multiple times.
+message("message")
+function(message)
+ _message(${ARGN})
+endfunction()
+message("message")
+
# Try setting a new policy. The IF test is for coverage.
if(POLICY CMP0003)
cmake_policy(SET CMP0003 NEW)
@@ -14,6 +21,21 @@ if(POLICY CMP0003)
endif()
endif()
+# It is not recommended to set a policy to OLD, but this test
+# covers the OLD behavior of some policies.
+foreach(p
+ CMP0029
+ CMP0032
+ CMP0033
+ CMP0034
+ CMP0043
+ CMP0050
+ )
+ if(POLICY ${p})
+ cmake_policy(SET ${p} OLD)
+ endif()
+endforeach()
+
# Test building without per-rule echo lines in Makefiles.
set_property(GLOBAL PROPERTY RULE_MESSAGES OFF)
@@ -36,7 +58,7 @@ ASSERT(Complex_BINARY_DIR "The PROJECT command is broken")
#
macro(TEST_ARGC value1 value2)
add_definitions(${value1} ${value2})
- if (${ARGC} MATCHES 4)
+ if (${ARGC} EQUAL 4)
add_definitions(${ARGV2} ${ARGV3})
endif ()
endmacro()
@@ -70,7 +92,7 @@ if(NOT 2.4 EQUAL 2.4)
message(FATAL_ERROR "Failed: NOT 2.4 EQUAL 2.4")
endif()
-if(CMAKE_SYSTEM MATCHES "OSF1-V.*")
+if(CMAKE_SYSTEM MATCHES "OSF1-V")
if(NOT CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -timplicit_local -no_implicit_include ")
endif()
@@ -83,6 +105,14 @@ set_property(DIRECTORY
PROPERTY COMPILE_DEFINITIONS_RELEASE
CMAKE_IS_FUN_IN_RELEASE_MODE
)
+set_property(DIRECTORY
+ PROPERTY COMPILE_DEFINITIONS_RELWITHDEBINFO
+ CMAKE_IS_FUN_IN_RELEASE_MODE
+ )
+set_property(DIRECTORY
+ PROPERTY COMPILE_DEFINITIONS_MINSIZEREL
+ CMAKE_IS_FUN_IN_RELEASE_MODE
+ )
set(TEST_SEP "a b c")
separate_arguments(TEST_SEP)
@@ -198,14 +228,14 @@ make_directory("${Complex_BINARY_DIR}/make_dir")
configure_file(
${Complex_SOURCE_DIR}/Library/dummy
${Complex_BINARY_DIR}/Library/dummylib.lib
- COPYONLY IMMEDIATE)
+ COPYONLY)
foreach (ext ${CMAKE_SHLIB_SUFFIX};.so;.a;.sl
${CMAKE_SHARED_LIBRARY_SUFFIX}.2
${CMAKE_STATIC_LIBRARY_SUFFIX}.2)
configure_file(
${Complex_SOURCE_DIR}/Library/dummy
${Complex_BINARY_DIR}/Library/libdummylib${ext}
- COPYONLY IMMEDIATE)
+ COPYONLY)
endforeach ()
find_library(FIND_DUMMY_LIB
@@ -281,7 +311,7 @@ if (WIN32)
configure_file(
${Complex_SOURCE_DIR}/Library/dummy
"${dir}/${file}"
- COPYONLY IMMEDIATE)
+ COPYONLY)
exec_program(${CMAKE_COMMAND} ARGS "-E write_regv \"${hkey}\" \"${dir}\"")
find_path(REGISTRY_TEST_PATH
${file}
@@ -392,6 +422,21 @@ if(NOT RESULT STREQUAL "a[b]c[d]e")
"string(REGEX REPLACE ... ) test failed (\"${RESULT}\" v. \"a[b]c[d]e\")")
endif()
+#
+# This tests needs Ansi C++98
+#
+set(CMAKE_CXX_STANDARD 98)
+#
+# GNU extensions are needed for stricmp() on Windows.
+#
+set(CMAKE_CXX_EXTENSIONS TRUE)
+
+# Those versions of the HP compiler that need a flag to get proper C++98
+# template support also need a flag to use the newer C++ library.
+if (CMAKE_CXX_COMPILER_ID STREQUAL HP AND
+ CMAKE_CXX98_STANDARD_COMPILE_OPTION STREQUAL "+hpxstd98")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -AA")
+endif ()
#
# Create the libs and the main exe
diff --git a/Tests/Complex/Executable/CMakeLists.txt b/Tests/Complex/Executable/CMakeLists.txt
index 2613f2762..a1f8e68a7 100644
--- a/Tests/Complex/Executable/CMakeLists.txt
+++ b/Tests/Complex/Executable/CMakeLists.txt
@@ -1,4 +1,3 @@
-cmake_minimum_required(VERSION 1.3)
#
# Create exe.
#
@@ -22,7 +21,7 @@ if(TARGET NotATarget)
message(FATAL_ERROR "if(TARGET NotATarget) returned true!")
endif()
- # Use LINK_LIBRARIES instead of TARGET_LINK_LIBRARIES to
+# Use LINK_LIBRARIES instead of TARGET_LINK_LIBRARIES to
set(COMPLEX_LIBS CMakeTestLibrary;CMakeTestLibraryShared;CMakeTestCLibraryShared)
link_libraries(${COMPLEX_LIBS})
@@ -90,18 +89,22 @@ remove_definitions(-DCOMPLEX_DEFINED)
# Test pre-build/pre-link/post-build rules for an executable.
add_custom_command(TARGET complex PRE_BUILD
COMMAND ${CREATE_FILE_EXE}
- ARGS "${Complex_BINARY_DIR}/Executable/prebuild.txt")
+ ARGS "Executable/prebuild.txt"
+ WORKING_DIRECTORY "${Complex_BINARY_DIR}")
add_custom_command(TARGET complex PRE_LINK
COMMAND ${CREATE_FILE_EXE}
- ARGS "${Complex_BINARY_DIR}/Executable/prelink.txt")
+ ARGS "Executable/prelink.txt"
+ WORKING_DIRECTORY "${Complex_BINARY_DIR}")
add_custom_command(TARGET complex POST_BUILD
COMMAND ${CREATE_FILE_EXE}
- ARGS "${Complex_BINARY_DIR}/Executable/postbuild.txt")
+ ARGS "Executable/postbuild.txt"
+ WORKING_DIRECTORY "${Complex_BINARY_DIR}")
add_custom_command(TARGET complex POST_BUILD
COMMAND ${CMAKE_COMMAND}
ARGS -E copy
- "${Complex_BINARY_DIR}/Executable/postbuild.txt"
- "${Complex_BINARY_DIR}/Executable/postbuild2.txt")
+ "Executable/postbuild.txt"
+ "Executable/postbuild2.txt"
+ WORKING_DIRECTORY "${Complex_BINARY_DIR}")
set_source_files_properties(complex
COMPILE_FLAGS
diff --git a/Tests/Complex/Executable/complex.cxx b/Tests/Complex/Executable/complex.cxx
index e904f2897..ec222a5ac 100644
--- a/Tests/Complex/Executable/complex.cxx
+++ b/Tests/Complex/Executable/complex.cxx
@@ -716,14 +716,14 @@ int main()
// the file was removed the last time 'complex' was run, and it is
// only created during a build.
- TestAndRemoveFile(BINARY_DIR "/Library/prebuild.txt");
- TestAndRemoveFile(BINARY_DIR "/Library/prelink.txt");
- TestAndRemoveFile(BINARY_DIR "/Library/postbuild.txt");
- TestAndRemoveFile(BINARY_DIR "/Library/postbuild2.txt");
- TestAndRemoveFile(BINARY_DIR "/Executable/prebuild.txt");
- TestAndRemoveFile(BINARY_DIR "/Executable/prelink.txt");
- TestAndRemoveFile(BINARY_DIR "/Executable/postbuild.txt");
- TestAndRemoveFile(BINARY_DIR "/Executable/postbuild2.txt");
+ TestAndRemoveFile("Library/prebuild.txt");
+ TestAndRemoveFile("Library/prelink.txt");
+ TestAndRemoveFile("Library/postbuild.txt");
+ TestAndRemoveFile("Library/postbuild2.txt");
+ TestAndRemoveFile("Executable/prebuild.txt");
+ TestAndRemoveFile("Executable/prelink.txt");
+ TestAndRemoveFile("Executable/postbuild.txt");
+ TestAndRemoveFile("Executable/postbuild2.txt");
// ----------------------------------------------------------------------
// A custom target has been created (see Library/).
@@ -733,12 +733,12 @@ int main()
// the file was removed the last time 'complex' was run, and it is
// only created during a build.
- TestAndRemoveFile(BINARY_DIR "/Library/custom_target1.txt");
+ TestAndRemoveFile("Library/custom_target1.txt");
// ----------------------------------------------------------------------
// A directory has been created.
- TestDir(BINARY_DIR "/make_dir");
+ TestDir("make_dir");
// ----------------------------------------------------------------------
// Test OUTPUT_REQUIRED_FILES
@@ -749,7 +749,7 @@ int main()
// the file was removed the last time 'complex' was run, and it is
// only created during a build.
- TestAndRemoveFile(BINARY_DIR "/Executable/Temp/complex-required.txt");
+ TestAndRemoveFile("Executable/Temp/complex-required.txt");
// ----------------------------------------------------------------------
// Test FIND_LIBRARY
@@ -838,13 +838,13 @@ int main()
#endif
#endif // defined(_WIN32) && !defined(__CYGWIN__)
- if(strcmp(CMAKE_MINIMUM_REQUIRED_VERSION, "1.3") == 0)
+ if(strcmp(CMAKE_MINIMUM_REQUIRED_VERSION, "2.4") == 0)
{
- cmPassed("CMAKE_MINIMUM_REQUIRED_VERSION is set to 1.3");
+ cmPassed("CMAKE_MINIMUM_REQUIRED_VERSION is set to 2.4");
}
else
{
- cmFailed("CMAKE_MINIMUM_REQUIRED_VERSION is not set to the expected 1.3");
+ cmFailed("CMAKE_MINIMUM_REQUIRED_VERSION is not set to the expected 2.4");
}
// ----------------------------------------------------------------------
diff --git a/Tests/Complex/Library/CMakeLists.txt b/Tests/Complex/Library/CMakeLists.txt
index 5c430523e..f00cbd611 100644
--- a/Tests/Complex/Library/CMakeLists.txt
+++ b/Tests/Complex/Library/CMakeLists.txt
@@ -51,7 +51,7 @@ define_property(
FULL_DOCS "A simple etst proerty that means nothign and is used for nothing"
)
set_target_properties(CMakeTestCLibraryShared PROPERTIES FOO BAR)
-if(NOT BEOS AND NOT WIN32) # No libm on BeOS.
+if(NOT BEOS AND NOT WIN32 AND NOT HAIKU) # No libm on BeOS.
set_target_properties(CMakeTestCLibraryShared PROPERTIES LINK_FLAGS "-lm")
endif()
get_target_property(FOO_BAR_VAR CMakeTestCLibraryShared FOO)
diff --git a/Tests/ComplexOneConfig/CMakeLists.txt b/Tests/ComplexOneConfig/CMakeLists.txt
index cbb42860d..3b73e709a 100644
--- a/Tests/ComplexOneConfig/CMakeLists.txt
+++ b/Tests/ComplexOneConfig/CMakeLists.txt
@@ -1,7 +1,7 @@
#
# A more complex test case
#
-set(CMAKE_BACKWARDS_COMPATIBILITY 1.4)
+cmake_minimum_required(VERSION 2.4)
project (Complex)
# Try setting a new policy. The IF test is for coverage.
@@ -14,6 +14,21 @@ if(POLICY CMP0003)
endif()
endif()
+# It is not recommended to set a policy to OLD, but this test
+# covers the OLD behavior of some policies.
+foreach(p
+ CMP0029
+ CMP0032
+ CMP0033
+ CMP0034
+ CMP0043
+ CMP0050
+ )
+ if(POLICY ${p})
+ cmake_policy(SET ${p} OLD)
+ endif()
+endforeach()
+
# Test building without per-rule echo lines in Makefiles.
set_property(GLOBAL PROPERTY RULE_MESSAGES OFF)
@@ -36,7 +51,7 @@ ASSERT(Complex_BINARY_DIR "The PROJECT command is broken")
#
macro(TEST_ARGC value1 value2)
add_definitions(${value1} ${value2})
- if (${ARGC} MATCHES 4)
+ if (${ARGC} EQUAL 4)
add_definitions(${ARGV2} ${ARGV3})
endif ()
endmacro()
@@ -70,7 +85,7 @@ if(NOT 2.4 EQUAL 2.4)
message(FATAL_ERROR "Failed: NOT 2.4 EQUAL 2.4")
endif()
-if(CMAKE_SYSTEM MATCHES "OSF1-V.*")
+if(CMAKE_SYSTEM MATCHES "OSF1-V")
if(NOT CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -timplicit_local -no_implicit_include ")
endif()
@@ -83,6 +98,14 @@ set_property(DIRECTORY
PROPERTY COMPILE_DEFINITIONS_RELEASE
CMAKE_IS_FUN_IN_RELEASE_MODE
)
+set_property(DIRECTORY
+ PROPERTY COMPILE_DEFINITIONS_RELWITHDEBINFO
+ CMAKE_IS_FUN_IN_RELEASE_MODE
+ )
+set_property(DIRECTORY
+ PROPERTY COMPILE_DEFINITIONS_MINSIZEREL
+ CMAKE_IS_FUN_IN_RELEASE_MODE
+ )
set(TEST_SEP "a b c")
separate_arguments(TEST_SEP)
@@ -198,12 +221,12 @@ make_directory("${Complex_BINARY_DIR}/make_dir")
configure_file(
${Complex_SOURCE_DIR}/Library/dummy
${Complex_BINARY_DIR}/Library/dummylib.lib
- COPYONLY IMMEDIATE)
+ COPYONLY)
foreach (ext ${CMAKE_SHLIB_SUFFIX};.so;.a;.sl)
configure_file(
${Complex_SOURCE_DIR}/Library/dummy
${Complex_BINARY_DIR}/Library/libdummylib${ext}
- COPYONLY IMMEDIATE)
+ COPYONLY)
endforeach ()
find_library(FIND_DUMMY_LIB
@@ -251,7 +274,7 @@ if (WIN32)
configure_file(
${Complex_SOURCE_DIR}/Library/dummy
"${dir}/${file}"
- COPYONLY IMMEDIATE)
+ COPYONLY)
exec_program(${CMAKE_COMMAND} ARGS "-E write_regv \"${hkey}\" \"${dir}\"")
find_path(REGISTRY_TEST_PATH
${file}
@@ -362,6 +385,21 @@ if(NOT RESULT STREQUAL "a[b]c[d]e")
"string(REGEX REPLACE ... ) test failed (\"${RESULT}\" v. \"a[b]c[d]e\")")
endif()
+#
+# This tests needs Ansi C++98
+#
+set(CMAKE_CXX_STANDARD 98)
+#
+# GNU extensions are needed for stricmp() on Windows.
+#
+set(CMAKE_CXX_EXTENSIONS TRUE)
+
+# Those versions of the HP compiler that need a flag to get proper C++98
+# template support also need a flag to use the newer C++ library.
+if (CMAKE_CXX_COMPILER_ID STREQUAL HP AND
+ CMAKE_CXX98_STANDARD_COMPILE_OPTION STREQUAL "+hpxstd98")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -AA")
+endif ()
#
# Create the libs and the main exe
diff --git a/Tests/ComplexOneConfig/Executable/CMakeLists.txt b/Tests/ComplexOneConfig/Executable/CMakeLists.txt
index 432dbf890..b2307b21f 100644
--- a/Tests/ComplexOneConfig/Executable/CMakeLists.txt
+++ b/Tests/ComplexOneConfig/Executable/CMakeLists.txt
@@ -1,4 +1,3 @@
-cmake_minimum_required(VERSION 1.3)
#
# Create exe.
#
@@ -22,7 +21,7 @@ if(TARGET NotATarget)
message(FATAL_ERROR "if(TARGET NotATarget) returned true!")
endif()
- # Use LINK_LIBRARIES instead of TARGET_LINK_LIBRARIES to
+# Use LINK_LIBRARIES instead of TARGET_LINK_LIBRARIES to
set(COMPLEX_LIBS CMakeTestLibrary;CMakeTestLibraryShared;CMakeTestCLibraryShared)
link_libraries(${COMPLEX_LIBS})
@@ -90,18 +89,22 @@ remove_definitions(-DCOMPLEX_DEFINED)
# Test pre-build/pre-link/post-build rules for an executable.
add_custom_command(TARGET complex PRE_BUILD
COMMAND ${CREATE_FILE_EXE}
- ARGS "${Complex_BINARY_DIR}/Executable/prebuild.txt")
+ ARGS "Executable/prebuild.txt"
+ WORKING_DIRECTORY "${Complex_BINARY_DIR}")
add_custom_command(TARGET complex PRE_BUILD
COMMAND ${CREATE_FILE_EXE}
- ARGS "${Complex_BINARY_DIR}/Executable/prelink.txt")
+ ARGS "Executable/prelink.txt"
+ WORKING_DIRECTORY "${Complex_BINARY_DIR}")
add_custom_command(TARGET complex POST_BUILD
COMMAND ${CREATE_FILE_EXE}
- ARGS "${Complex_BINARY_DIR}/Executable/postbuild.txt")
+ ARGS "Executable/postbuild.txt"
+ WORKING_DIRECTORY "${Complex_BINARY_DIR}")
add_custom_command(TARGET complex POST_BUILD
COMMAND ${CMAKE_COMMAND}
ARGS -E copy
- "${Complex_BINARY_DIR}/Executable/postbuild.txt"
- "${Complex_BINARY_DIR}/Executable/postbuild2.txt")
+ "Executable/postbuild.txt"
+ "Executable/postbuild2.txt"
+ WORKING_DIRECTORY "${Complex_BINARY_DIR}")
set_source_files_properties(complex
COMPILE_FLAGS
diff --git a/Tests/ComplexOneConfig/Executable/complex.cxx b/Tests/ComplexOneConfig/Executable/complex.cxx
index e904f2897..ec222a5ac 100644
--- a/Tests/ComplexOneConfig/Executable/complex.cxx
+++ b/Tests/ComplexOneConfig/Executable/complex.cxx
@@ -716,14 +716,14 @@ int main()
// the file was removed the last time 'complex' was run, and it is
// only created during a build.
- TestAndRemoveFile(BINARY_DIR "/Library/prebuild.txt");
- TestAndRemoveFile(BINARY_DIR "/Library/prelink.txt");
- TestAndRemoveFile(BINARY_DIR "/Library/postbuild.txt");
- TestAndRemoveFile(BINARY_DIR "/Library/postbuild2.txt");
- TestAndRemoveFile(BINARY_DIR "/Executable/prebuild.txt");
- TestAndRemoveFile(BINARY_DIR "/Executable/prelink.txt");
- TestAndRemoveFile(BINARY_DIR "/Executable/postbuild.txt");
- TestAndRemoveFile(BINARY_DIR "/Executable/postbuild2.txt");
+ TestAndRemoveFile("Library/prebuild.txt");
+ TestAndRemoveFile("Library/prelink.txt");
+ TestAndRemoveFile("Library/postbuild.txt");
+ TestAndRemoveFile("Library/postbuild2.txt");
+ TestAndRemoveFile("Executable/prebuild.txt");
+ TestAndRemoveFile("Executable/prelink.txt");
+ TestAndRemoveFile("Executable/postbuild.txt");
+ TestAndRemoveFile("Executable/postbuild2.txt");
// ----------------------------------------------------------------------
// A custom target has been created (see Library/).
@@ -733,12 +733,12 @@ int main()
// the file was removed the last time 'complex' was run, and it is
// only created during a build.
- TestAndRemoveFile(BINARY_DIR "/Library/custom_target1.txt");
+ TestAndRemoveFile("Library/custom_target1.txt");
// ----------------------------------------------------------------------
// A directory has been created.
- TestDir(BINARY_DIR "/make_dir");
+ TestDir("make_dir");
// ----------------------------------------------------------------------
// Test OUTPUT_REQUIRED_FILES
@@ -749,7 +749,7 @@ int main()
// the file was removed the last time 'complex' was run, and it is
// only created during a build.
- TestAndRemoveFile(BINARY_DIR "/Executable/Temp/complex-required.txt");
+ TestAndRemoveFile("Executable/Temp/complex-required.txt");
// ----------------------------------------------------------------------
// Test FIND_LIBRARY
@@ -838,13 +838,13 @@ int main()
#endif
#endif // defined(_WIN32) && !defined(__CYGWIN__)
- if(strcmp(CMAKE_MINIMUM_REQUIRED_VERSION, "1.3") == 0)
+ if(strcmp(CMAKE_MINIMUM_REQUIRED_VERSION, "2.4") == 0)
{
- cmPassed("CMAKE_MINIMUM_REQUIRED_VERSION is set to 1.3");
+ cmPassed("CMAKE_MINIMUM_REQUIRED_VERSION is set to 2.4");
}
else
{
- cmFailed("CMAKE_MINIMUM_REQUIRED_VERSION is not set to the expected 1.3");
+ cmFailed("CMAKE_MINIMUM_REQUIRED_VERSION is not set to the expected 2.4");
}
// ----------------------------------------------------------------------
diff --git a/Tests/ComplexOneConfig/Library/CMakeLists.txt b/Tests/ComplexOneConfig/Library/CMakeLists.txt
index 5c430523e..f00cbd611 100644
--- a/Tests/ComplexOneConfig/Library/CMakeLists.txt
+++ b/Tests/ComplexOneConfig/Library/CMakeLists.txt
@@ -51,7 +51,7 @@ define_property(
FULL_DOCS "A simple etst proerty that means nothign and is used for nothing"
)
set_target_properties(CMakeTestCLibraryShared PROPERTIES FOO BAR)
-if(NOT BEOS AND NOT WIN32) # No libm on BeOS.
+if(NOT BEOS AND NOT WIN32 AND NOT HAIKU) # No libm on BeOS.
set_target_properties(CMakeTestCLibraryShared PROPERTIES LINK_FLAGS "-lm")
endif()
get_target_property(FOO_BAR_VAR CMakeTestCLibraryShared FOO)
diff --git a/Tests/ConfigSources/CMakeLists.txt b/Tests/ConfigSources/CMakeLists.txt
new file mode 100644
index 000000000..748aad887
--- /dev/null
+++ b/Tests/ConfigSources/CMakeLists.txt
@@ -0,0 +1,17 @@
+
+cmake_minimum_required(VERSION 3.0)
+
+project(ConfigSources)
+
+add_library(iface INTERFACE)
+set_property(TARGET iface PROPERTY INTERFACE_SOURCES
+ "${CMAKE_CURRENT_SOURCE_DIR}/iface_src.cpp"
+ "$<$<CONFIG:Debug>:${CMAKE_CURRENT_SOURCE_DIR}/iface_debug_src.cpp>"
+ "$<$<CONFIG:Release>:${CMAKE_CURRENT_SOURCE_DIR}/does_not_exist.cpp>"
+)
+
+add_executable(ConfigSources
+ $<$<CONFIG:Debug>:main.cpp>
+ $<$<CONFIG:Release>:does_not_exist.cpp>
+)
+target_link_libraries(ConfigSources iface)
diff --git a/Tests/ConfigSources/iface_debug.h b/Tests/ConfigSources/iface_debug.h
new file mode 100644
index 000000000..a23d7374b
--- /dev/null
+++ b/Tests/ConfigSources/iface_debug.h
@@ -0,0 +1,4 @@
+
+int iface_src();
+
+int iface_debug();
diff --git a/Tests/ConfigSources/iface_debug_src.cpp b/Tests/ConfigSources/iface_debug_src.cpp
new file mode 100644
index 000000000..63b22fcd1
--- /dev/null
+++ b/Tests/ConfigSources/iface_debug_src.cpp
@@ -0,0 +1,7 @@
+
+#include "iface_debug.h"
+
+int iface_debug()
+{
+ return 0;
+}
diff --git a/Tests/ConfigSources/iface_src.cpp b/Tests/ConfigSources/iface_src.cpp
new file mode 100644
index 000000000..c3a0c8f1e
--- /dev/null
+++ b/Tests/ConfigSources/iface_src.cpp
@@ -0,0 +1,5 @@
+
+int iface_src()
+{
+ return 0;
+}
diff --git a/Tests/ConfigSources/main.cpp b/Tests/ConfigSources/main.cpp
new file mode 100644
index 000000000..71af72f70
--- /dev/null
+++ b/Tests/ConfigSources/main.cpp
@@ -0,0 +1,7 @@
+
+#include "iface_debug.h"
+
+int main(int argc, char** argv)
+{
+ return iface_src() + iface_debug();
+}
diff --git a/Tests/Contracts/Trilinos-10-6/CMakeLists.txt b/Tests/Contracts/Trilinos-10-6/CMakeLists.txt
deleted file mode 100644
index 79ed669a2..000000000
--- a/Tests/Contracts/Trilinos-10-6/CMakeLists.txt
+++ /dev/null
@@ -1,103 +0,0 @@
-cmake_minimum_required(VERSION 2.8)
-project(Trilinos-10-6)
-
-include(ExternalProject)
-
-include("${CMAKE_CURRENT_SOURCE_DIR}/LocalOverrides.cmake" OPTIONAL)
-include("${CMAKE_CURRENT_BINARY_DIR}/LocalOverrides.cmake" OPTIONAL)
-
-if(NOT DEFINED HOME)
- if(DEFINED ENV{CTEST_REAL_HOME})
- set(HOME "$ENV{CTEST_REAL_HOME}")
- else()
- set(HOME "$ENV{HOME}")
- endif()
-
- if(NOT HOME AND WIN32)
- # Try for USERPROFILE as HOME equivalent:
- string(REPLACE "\\" "/" HOME "$ENV{USERPROFILE}")
-
- # But just use root of SystemDrive if USERPROFILE contains any spaces:
- # (Default on XP and earlier...)
- if(HOME MATCHES " ")
- string(REPLACE "\\" "/" HOME "$ENV{SystemDrive}")
- endif()
- endif()
-endif()
-message(STATUS "HOME='${HOME}'")
-
-if(NOT DEFINED url)
- set(url "http://www.cmake.org/files/contracts/trilinos-10.6.1.tar.gz")
-endif()
-message(STATUS "url='${url}'")
-
-if(NOT DEFINED md5)
- set(md5 "690230465dd21a76e3c6636fd07bd2f0")
-endif()
-message(STATUS "md5='${md5}'")
-
-string(SUBSTRING "${md5}" 0 8 shorttag)
-set(shorttag "m${shorttag}")
-
-set(download_dir "${HOME}/.cmake/Downloads")
-
-set(base_dir "${HOME}/.cmake/Contracts/${PROJECT_NAME}/${shorttag}")
-set(binary_dir "${base_dir}/build")
-set(script_dir "${base_dir}")
-set(source_dir "${base_dir}/src")
-
-if(NOT DEFINED BUILDNAME)
- set(BUILDNAME "CMakeContract-${shorttag}")
-endif()
-message(STATUS "BUILDNAME='${BUILDNAME}'")
-
-if(NOT DEFINED SITE)
- site_name(SITE)
-endif()
-message(STATUS "SITE='${SITE}'")
-
-configure_file(
- "${CMAKE_CURRENT_SOURCE_DIR}/Dashboard.cmake.in"
- "${script_dir}/Dashboard.cmake"
- @ONLY)
-
-configure_file(
- "${CMAKE_CURRENT_SOURCE_DIR}/ValidateBuild.cmake.in"
- "${CMAKE_CURRENT_BINARY_DIR}/ValidateBuild.cmake"
- @ONLY)
-
-# Source dir for this project exists outside the CMake build tree because it
-# is absolutely huge. Source dir is therefore cached under a '.cmake/Contracts'
-# dir in your HOME directory. Downloads are cached under '.cmake/Downloads'
-#
-if(EXISTS "${source_dir}/cmake/ctest/TrilinosCTestDriverCore.cmake")
- # If it exists already, download is a complete no-op:
- ExternalProject_Add(download-${PROJECT_NAME}
- DOWNLOAD_COMMAND ""
- CONFIGURE_COMMAND ""
- BUILD_COMMAND ""
- INSTALL_COMMAND ""
- )
-else()
- # If it does not yet exist, download pulls the tarball from the web (or
- # no-ops if it already exists with the given md5 sum):
- #
- ExternalProject_Add(download-${PROJECT_NAME}
- DOWNLOAD_DIR "${download_dir}"
- URL "${url}"
- URL_MD5 "${md5}"
- SOURCE_DIR "${source_dir}"
- PATCH_COMMAND ${CMAKE_COMMAND} -Dsource_dir=${source_dir} -P "${CMAKE_CURRENT_SOURCE_DIR}/Patch.cmake"
- CONFIGURE_COMMAND ""
- BUILD_COMMAND ""
- INSTALL_COMMAND ""
- )
-endif()
-
-ExternalProject_Add(build-${PROJECT_NAME}
- DOWNLOAD_COMMAND ""
- CONFIGURE_COMMAND ""
- BUILD_COMMAND ${CMAKE_COMMAND} -P "${script_dir}/Dashboard.cmake"
- INSTALL_COMMAND ""
- DEPENDS download-${PROJECT_NAME}
- )
diff --git a/Tests/Contracts/Trilinos-10-6/Dashboard.cmake.in b/Tests/Contracts/Trilinos-10-6/Dashboard.cmake.in
deleted file mode 100644
index cc2950232..000000000
--- a/Tests/Contracts/Trilinos-10-6/Dashboard.cmake.in
+++ /dev/null
@@ -1,63 +0,0 @@
-# This "cmake -P" script may be configured to drive a dashboard on any machine.
-#
-set(CTEST_BINARY_DIRECTORY "@binary_dir@")
-set(CTEST_BUILD_NAME "@BUILDNAME@")
-set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
-set(CTEST_SITE "@SITE@")
-set(CTEST_SOURCE_DIRECTORY "@source_dir@")
-
-# Set the environment:
-#
-set(ENV{CTEST_BUILD_NAME} "${CTEST_BUILD_NAME}")
-set(ENV{CTEST_CMAKE_GENERATOR} "${CTEST_CMAKE_GENERATOR}")
-set(ENV{CTEST_SITE} "${CTEST_SITE}")
-
-# Allow override of the environment on a per-client basis:
-#
-set(ENV_SCRIPT "$ENV{CMAKE_CONTRACT_Trilinos_10_6_ENV_SCRIPT}")
-if(ENV_SCRIPT AND EXISTS "${ENV_SCRIPT}")
- include("${ENV_SCRIPT}")
-endif()
-
-# Empty build dir to start with:
-#
-message("Cleaning binary dir '${CTEST_BINARY_DIRECTORY}'")
-file(REMOVE_RECURSE "${CTEST_BINARY_DIRECTORY}")
-
-# Generate 'do-configure' script:
-#
-file(WRITE "${CTEST_BINARY_DIRECTORY}/do-configure" "
-\"${CMAKE_COMMAND}\" -G \"${CTEST_CMAKE_GENERATOR}\" \"${CTEST_SOURCE_DIRECTORY}\"
-")
-
-# Make the 'do-configure' script executable and execute it:
-#
-if(WIN32)
- configure_file(
- "${CTEST_BINARY_DIRECTORY}/do-configure"
- "${CTEST_BINARY_DIRECTORY}/do-configure.cmd"
- COPYONLY)
- execute_process(COMMAND "${CTEST_BINARY_DIRECTORY}/do-configure.cmd"
- WORKING_DIRECTORY "${CTEST_BINARY_DIRECTORY}")
-else()
- execute_process(COMMAND chmod +x "${CTEST_BINARY_DIRECTORY}/do-configure")
- execute_process(COMMAND "${CTEST_BINARY_DIRECTORY}/do-configure"
- WORKING_DIRECTORY "${CTEST_BINARY_DIRECTORY}")
-endif()
-
-# Run an experimental Trilinos dashboard:
-#
-execute_process(COMMAND
- "${CMAKE_CTEST_COMMAND}"
- -S "${CTEST_SOURCE_DIRECTORY}/cmake/ctest/experimental_build_test.cmake"
- -VV
- WORKING_DIRECTORY "${CTEST_BINARY_DIRECTORY}"
- RESULT_VARIABLE rv
- )
-
-if(NOT "${rv}" STREQUAL "0")
- message("error(s) (or warnings or test failures) running Trilinos dashboard
-script experimental_build_test.cmake...
-ctest returned rv='${rv}'
-")
-endif()
diff --git a/Tests/Contracts/Trilinos-10-6/RunTest.cmake b/Tests/Contracts/Trilinos-10-6/RunTest.cmake
deleted file mode 100644
index 30124d8e9..000000000
--- a/Tests/Contracts/Trilinos-10-6/RunTest.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-# ValidateBuild.cmake is configured into this location when the test is built:
-set(dir "${CMAKE_CURRENT_BINARY_DIR}/Contracts/${project}")
-
-set(exe "${CMAKE_COMMAND}")
-set(args -P "${dir}/ValidateBuild.cmake")
-
-set(Trilinos-10-6_RUN_TEST ${exe} ${args})
diff --git a/Tests/Contracts/Trilinos-10-6/ValidateBuild.cmake.in b/Tests/Contracts/Trilinos-10-6/ValidateBuild.cmake.in
deleted file mode 100644
index 04bbf214e..000000000
--- a/Tests/Contracts/Trilinos-10-6/ValidateBuild.cmake.in
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# This code validates that the Trilinos build was "successful enough" (since it
-# is difficult to detect this from the caller of the experimental_build_test
-# dashboard script...)
-#
-set(binary_dir "@binary_dir@")
-message("binary_dir='${binary_dir}'")
-
-
-# Count *.exe files:
-#
-file(GLOB_RECURSE exes "${binary_dir}/*.exe")
-message(STATUS "exes='${exes}'")
-list(LENGTH exes len)
-if(len LESS 47)
- message(FATAL_ERROR "len='${len}' is less than minimum expected='47' (count of executables)")
-endif()
-message(STATUS "Found len='${len}' *.exe files")
-
-
-# Try to find the Teuchos unit tests executable:
-#
-file(GLOB_RECURSE exe "${binary_dir}/Teuchos_UnitTest_UnitTests.exe")
-list(LENGTH exe len)
-if(NOT len EQUAL 1)
- message(FATAL_ERROR "len='${len}' is not the expected='1' (count of Teuchos_UnitTest_UnitTests.exe)")
-endif()
-message(STATUS "Found exe='${exe}'")
-
-
-# Try to run it:
-execute_process(COMMAND ${exe} RESULT_VARIABLE rv)
-if(NOT "${rv}" STREQUAL "0")
- message(FATAL_ERROR "rv='${rv}' is not the expected='0' (result of running Teuchos_UnitTest_UnitTests.exe)")
-endif()
-message(STATUS "Ran exe='${exe}' rv='${rv}'")
-
-
-message(STATUS "All Trilinos build validation tests pass.")
diff --git a/Tests/Contracts/Trilinos/CMakeLists.txt b/Tests/Contracts/Trilinos/CMakeLists.txt
new file mode 100644
index 000000000..8d74ca574
--- /dev/null
+++ b/Tests/Contracts/Trilinos/CMakeLists.txt
@@ -0,0 +1,103 @@
+cmake_minimum_required(VERSION 2.8)
+project(Trilinos)
+
+include(ExternalProject)
+
+include("${CMAKE_CURRENT_SOURCE_DIR}/LocalOverrides.cmake" OPTIONAL)
+include("${CMAKE_CURRENT_BINARY_DIR}/LocalOverrides.cmake" OPTIONAL)
+
+if(NOT DEFINED HOME)
+ if(DEFINED ENV{CTEST_REAL_HOME})
+ set(HOME "$ENV{CTEST_REAL_HOME}")
+ else()
+ set(HOME "$ENV{HOME}")
+ endif()
+
+ if(NOT HOME AND WIN32)
+ # Try for USERPROFILE as HOME equivalent:
+ string(REPLACE "\\" "/" HOME "$ENV{USERPROFILE}")
+
+ # But just use root of SystemDrive if USERPROFILE contains any spaces:
+ # (Default on XP and earlier...)
+ if(HOME MATCHES " ")
+ string(REPLACE "\\" "/" HOME "$ENV{SystemDrive}")
+ endif()
+ endif()
+endif()
+message(STATUS "HOME='${HOME}'")
+
+if(NOT DEFINED url)
+ set(url "https://cmake.org/files/contracts/trilinos-11.4.1.tar.gz")
+endif()
+message(STATUS "url='${url}'")
+
+if(NOT DEFINED md5)
+ set(md5 "28b6a3c7c0fb317b3a237997293faa8b")
+endif()
+message(STATUS "md5='${md5}'")
+
+string(SUBSTRING "${md5}" 0 8 shorttag)
+set(shorttag "m${shorttag}")
+
+set(download_dir "${HOME}/.cmake/Downloads")
+
+set(base_dir "${HOME}/.cmake/Contracts/${PROJECT_NAME}/${shorttag}")
+set(binary_dir "${base_dir}/build")
+set(script_dir "${base_dir}")
+set(source_dir "${base_dir}/src")
+
+if(NOT DEFINED BUILDNAME)
+ set(BUILDNAME "CMakeContract-${shorttag}")
+endif()
+message(STATUS "BUILDNAME='${BUILDNAME}'")
+
+if(NOT DEFINED SITE)
+ site_name(SITE)
+endif()
+message(STATUS "SITE='${SITE}'")
+
+configure_file(
+ "${CMAKE_CURRENT_SOURCE_DIR}/Dashboard.cmake.in"
+ "${script_dir}/Dashboard.cmake"
+ @ONLY)
+
+configure_file(
+ "${CMAKE_CURRENT_SOURCE_DIR}/ValidateBuild.cmake.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/ValidateBuild.cmake"
+ @ONLY)
+
+# Source dir for this project exists outside the CMake build tree because it
+# is absolutely huge. Source dir is therefore cached under a '.cmake/Contracts'
+# dir in your HOME directory. Downloads are cached under '.cmake/Downloads'
+#
+if(EXISTS "${source_dir}/cmake/ctest/TrilinosCTestDriverCore.cmake")
+ # If it exists already, download is a complete no-op:
+ ExternalProject_Add(download-${PROJECT_NAME}
+ DOWNLOAD_COMMAND ""
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ )
+else()
+ # If it does not yet exist, download pulls the tarball from the web (or
+ # no-ops if it already exists with the given md5 sum):
+ #
+ ExternalProject_Add(download-${PROJECT_NAME}
+ DOWNLOAD_DIR "${download_dir}"
+ URL "${url}"
+ URL_MD5 "${md5}"
+ SOURCE_DIR "${source_dir}"
+ PATCH_COMMAND ${CMAKE_COMMAND} -Dsource_dir=${source_dir} -P "${CMAKE_CURRENT_SOURCE_DIR}/Patch.cmake"
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ )
+endif()
+
+ExternalProject_Add(build-${PROJECT_NAME}
+ DOWNLOAD_COMMAND ""
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ${CMAKE_COMMAND} -P "${script_dir}/Dashboard.cmake"
+ INSTALL_COMMAND ""
+ DEPENDS download-${PROJECT_NAME}
+ )
diff --git a/Tests/Contracts/Trilinos/Dashboard.cmake.in b/Tests/Contracts/Trilinos/Dashboard.cmake.in
new file mode 100644
index 000000000..93d4f61ac
--- /dev/null
+++ b/Tests/Contracts/Trilinos/Dashboard.cmake.in
@@ -0,0 +1,63 @@
+# This "cmake -P" script may be configured to drive a dashboard on any machine.
+#
+set(CTEST_BINARY_DIRECTORY "@binary_dir@")
+set(CTEST_BUILD_NAME "@BUILDNAME@")
+set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
+set(CTEST_SITE "@SITE@")
+set(CTEST_SOURCE_DIRECTORY "@source_dir@")
+
+# Set the environment:
+#
+set(ENV{CTEST_BUILD_NAME} "${CTEST_BUILD_NAME}")
+set(ENV{CTEST_CMAKE_GENERATOR} "${CTEST_CMAKE_GENERATOR}")
+set(ENV{CTEST_SITE} "${CTEST_SITE}")
+
+# Allow override of the environment on a per-client basis:
+#
+set(ENV_SCRIPT "$ENV{CMAKE_CONTRACT_Trilinos_ENV_SCRIPT}")
+if(ENV_SCRIPT AND EXISTS "${ENV_SCRIPT}")
+ include("${ENV_SCRIPT}")
+endif()
+
+# Empty build dir to start with:
+#
+message("Cleaning binary dir '${CTEST_BINARY_DIRECTORY}'")
+file(REMOVE_RECURSE "${CTEST_BINARY_DIRECTORY}")
+
+# Generate 'do-configure' script:
+#
+file(WRITE "${CTEST_BINARY_DIRECTORY}/do-configure" "
+\"${CMAKE_COMMAND}\" -G \"${CTEST_CMAKE_GENERATOR}\" \"${CTEST_SOURCE_DIRECTORY}\"
+")
+
+# Make the 'do-configure' script executable and execute it:
+#
+if(WIN32)
+ configure_file(
+ "${CTEST_BINARY_DIRECTORY}/do-configure"
+ "${CTEST_BINARY_DIRECTORY}/do-configure.cmd"
+ COPYONLY)
+ execute_process(COMMAND "${CTEST_BINARY_DIRECTORY}/do-configure.cmd"
+ WORKING_DIRECTORY "${CTEST_BINARY_DIRECTORY}")
+else()
+ execute_process(COMMAND chmod +x "${CTEST_BINARY_DIRECTORY}/do-configure")
+ execute_process(COMMAND "${CTEST_BINARY_DIRECTORY}/do-configure"
+ WORKING_DIRECTORY "${CTEST_BINARY_DIRECTORY}")
+endif()
+
+# Run an experimental Trilinos dashboard:
+#
+execute_process(COMMAND
+ "${CMAKE_CTEST_COMMAND}"
+ -S "${CTEST_SOURCE_DIRECTORY}/cmake/tribits/ctest/experimental_build_test.cmake"
+ -VV
+ WORKING_DIRECTORY "${CTEST_BINARY_DIRECTORY}"
+ RESULT_VARIABLE rv
+ )
+
+if(NOT "${rv}" STREQUAL "0")
+ message("error(s) (or warnings or test failures) running Trilinos dashboard
+script experimental_build_test.cmake...
+ctest returned rv='${rv}'
+")
+endif()
diff --git a/Tests/Contracts/Trilinos-10-6/EnvScript.cmake b/Tests/Contracts/Trilinos/EnvScript.cmake
index dacb704f7..dacb704f7 100644
--- a/Tests/Contracts/Trilinos-10-6/EnvScript.cmake
+++ b/Tests/Contracts/Trilinos/EnvScript.cmake
diff --git a/Tests/Contracts/Trilinos-10-6/Patch.cmake b/Tests/Contracts/Trilinos/Patch.cmake
index 6c619ac4f..6c619ac4f 100644
--- a/Tests/Contracts/Trilinos-10-6/Patch.cmake
+++ b/Tests/Contracts/Trilinos/Patch.cmake
diff --git a/Tests/Contracts/Trilinos/RunTest.cmake b/Tests/Contracts/Trilinos/RunTest.cmake
new file mode 100644
index 000000000..d661a4c1f
--- /dev/null
+++ b/Tests/Contracts/Trilinos/RunTest.cmake
@@ -0,0 +1,7 @@
+# ValidateBuild.cmake is configured into this location when the test is built:
+set(dir "${CMAKE_CURRENT_BINARY_DIR}/Contracts/${project}")
+
+set(exe "${CMAKE_COMMAND}")
+set(args -P "${dir}/ValidateBuild.cmake")
+
+set(Trilinos_RUN_TEST ${exe} ${args})
diff --git a/Tests/Contracts/Trilinos/ValidateBuild.cmake.in b/Tests/Contracts/Trilinos/ValidateBuild.cmake.in
new file mode 100644
index 000000000..fa38ada54
--- /dev/null
+++ b/Tests/Contracts/Trilinos/ValidateBuild.cmake.in
@@ -0,0 +1,39 @@
+#
+# This code validates that the Trilinos build was "successful enough" (since it
+# is difficult to detect this from the caller of the experimental_build_test
+# dashboard script...)
+#
+set(binary_dir "@binary_dir@")
+message("binary_dir='${binary_dir}'")
+
+
+# Count *.exe files:
+#
+file(GLOB_RECURSE exes "${binary_dir}/*.exe")
+message(STATUS "exes='${exes}'")
+list(LENGTH exes len)
+if(len LESS 47)
+ message(FATAL_ERROR "len='${len}' is less than minimum expected='47' (count of executables)")
+endif()
+message(STATUS "Found len='${len}' *.exe files")
+
+
+# Try to find the Teuchos unit tests executable:
+#
+file(GLOB_RECURSE exe "${binary_dir}/TeuchosCore_UnitTest_UnitTests.exe")
+list(LENGTH exe len)
+if(NOT len EQUAL 1)
+ message(FATAL_ERROR "len='${len}' is not the expected='1' (count of TeuchosCore_UnitTest_UnitTests.exe)")
+endif()
+message(STATUS "Found exe='${exe}'")
+
+
+# Try to run it:
+execute_process(COMMAND ${exe} RESULT_VARIABLE rv)
+if(NOT "${rv}" STREQUAL "0")
+ message(FATAL_ERROR "rv='${rv}' is not the expected='0' (result of running TeuchosCore_UnitTest_UnitTests.exe)")
+endif()
+message(STATUS "Ran exe='${exe}' rv='${rv}'")
+
+
+message(STATUS "All Trilinos build validation tests pass.")
diff --git a/Tests/Contracts/VTK/CMakeLists.txt b/Tests/Contracts/VTK/CMakeLists.txt
new file mode 100644
index 000000000..ef19325a4
--- /dev/null
+++ b/Tests/Contracts/VTK/CMakeLists.txt
@@ -0,0 +1,47 @@
+# The VTK external project for CMake
+# ---------------------------------------------------------------------------
+cmake_minimum_required(VERSION 2.8)
+project(VTK)
+include(ExternalProject)
+
+# find "HOME". VTK will be downloaded & built within a subdirectory.
+if(NOT DEFINED HOME)
+ if(DEFINED ENV{CTEST_REAL_HOME})
+ set(HOME "$ENV{CTEST_REAL_HOME}")
+ else()
+ set(HOME "$ENV{HOME}")
+ endif()
+
+ if(NOT HOME AND WIN32)
+ # Try for USERPROFILE as HOME equivalent:
+ string(REPLACE "\\" "/" HOME "$ENV{USERPROFILE}")
+
+ # But just use root of SystemDrive if USERPROFILE contains any spaces:
+ # (Default on XP and earlier...)
+ if(HOME MATCHES " ")
+ string(REPLACE "\\" "/" HOME "$ENV{SystemDrive}")
+ endif()
+ endif()
+endif()
+
+set(base_dir "${HOME}/.cmake/Contracts/VTK")
+
+if(NOT DEFINED SITE)
+ site_name(SITE)
+endif()
+
+# configure our dashboard script
+configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/Dashboard.cmake.in
+ ${base_dir}/Dashboard.cmake
+ @ONLY)
+
+# build & test VTK's release branch
+ExternalProject_Add(${PROJECT_NAME}
+ GIT_REPOSITORY "git://vtk.org/VTK.git"
+ GIT_TAG "release"
+ PREFIX ${base_dir}
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ${CMAKE_CTEST_COMMAND} -S "${base_dir}/Dashboard.cmake"
+ INSTALL_COMMAND ""
+)
diff --git a/Tests/Contracts/VTK/Dashboard.cmake.in b/Tests/Contracts/VTK/Dashboard.cmake.in
new file mode 100644
index 000000000..c3d10f4bf
--- /dev/null
+++ b/Tests/Contracts/VTK/Dashboard.cmake.in
@@ -0,0 +1,37 @@
+# This submission's role is to test leading edge of cmake development
+# against VTK release
+#
+# Maintainer: Zack Galbreath <zack.galbreath@kitware.com>
+#
+# This file was generated as part of the CMake/VTK Contracts test.
+# See <CMake-src>/Tests/Contracts/VTK/ for more information
+
+set(CTEST_SITE "@SITE@")
+set(CTEST_BUILD_NAME "Contracts.VTK")
+set(CTEST_DASHBOARD_ROOT "@base_dir@")
+set(CTEST_SOURCE_DIRECTORY "${CTEST_DASHBOARD_ROOT}/src/VTK")
+set(CTEST_BINARY_DIRECTORY "${CTEST_DASHBOARD_ROOT}/VTK-build")
+
+set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
+set(CTEST_CONFIGURATION_TYPE Debug)
+set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
+
+# Assume a Linux build, with a make that supports -j9. Modify this script if
+# assumption is ever invalid.
+#
+set(CTEST_BUILD_COMMAND "@CMAKE_MAKE_PROGRAM@ -j9 -i")
+
+ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY})
+
+file(WRITE "${CTEST_BINARY_DIRECTORY}/CMakeCache.txt" "
+ BUILD_EXAMPLES:BOOL=ON
+ BUILD_TESTING:BOOL=ON
+ VTK_WRAP_PYTHON:BOOL=ON
+ ExternalData_OBJECT_STORES:FILEPATH=@base_dir@/ExternalData
+")
+
+ctest_start(Nightly)
+ctest_configure(BUILD "${CTEST_BINARY_DIRECTORY}")
+ctest_build(BUILD "${CTEST_BINARY_DIRECTORY}")
+ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" INCLUDE "PythonSmoke")
+ctest_submit(BUILD "${CTEST_BINARY_DIRECTORY}")
diff --git a/Tests/Contracts/VTK/RunTest.cmake b/Tests/Contracts/VTK/RunTest.cmake
new file mode 100644
index 000000000..65285cf77
--- /dev/null
+++ b/Tests/Contracts/VTK/RunTest.cmake
@@ -0,0 +1,3 @@
+set(exe "$ENV{HOME}/.cmake/Contracts/VTK/VTK-build/bin/vtkCommonCoreCxxTests")
+set(args otherArrays)
+set(VTK_RUN_TEST ${exe} ${args})
diff --git a/Tests/Contracts/vtk542/CMakeLists.txt b/Tests/Contracts/vtk542/CMakeLists.txt
deleted file mode 100644
index cfb8b1600..000000000
--- a/Tests/Contracts/vtk542/CMakeLists.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-# The VTK external project for CMake
-# ---------------------------------------------------------------------------
-cmake_minimum_required(VERSION 2.8)
-project(vtk542)
-include(ExternalProject)
-
-
-set(vtk_source "${CMAKE_CURRENT_BINARY_DIR}/VTK-source")
-set(vtk_binary "${CMAKE_CURRENT_BINARY_DIR}/VTK-build")
-
-ExternalProject_Add(VTK
- DOWNLOAD_DIR ${CMAKE_CURRENT_BINARY_DIR}
- URL "http://www.vtk.org/files/release/5.4/vtk-5.4.2.tar.gz"
- URL_MD5 c2c797091d4b2128d9a1bd32c4b78227
- SOURCE_DIR ${vtk_source}
- BINARY_DIR ${vtk_binary}
- CMAKE_GENERATOR "${CMAKE_GENERATOR}"
- CMAKE_ARGS
- -DBUILD_EXAMPLES:BOOL=ON
- -DBUILD_TESTING:BOOL=ON
- INSTALL_COMMAND ""
- )
-# make it so that each build will run make in the VTK build tree
-ExternalProject_Add_Step(VTK forcebuild
- COMMAND ${CMAKE_COMMAND}
- -E remove ${CMAKE_CURRENT_BUILD_DIR}/VTK-prefix/src/VTK-stamp/VTK-build
- DEPENDEES configure
- DEPENDERS build
- ALWAYS 1
- )
diff --git a/Tests/Contracts/vtk542/RunTest.cmake b/Tests/Contracts/vtk542/RunTest.cmake
deleted file mode 100644
index b4bd5b087..000000000
--- a/Tests/Contracts/vtk542/RunTest.cmake
+++ /dev/null
@@ -1 +0,0 @@
-set(vtk542_RUN_TEST VTK-build/bin/CommonCxxTests otherArrays)
diff --git a/Tests/CustomCommand/CMakeLists.txt b/Tests/CustomCommand/CMakeLists.txt
index 30daa7dea..268069d72 100644
--- a/Tests/CustomCommand/CMakeLists.txt
+++ b/Tests/CustomCommand/CMakeLists.txt
@@ -29,9 +29,6 @@ set (EXECUTABLE_OUTPUT_PATH
# add the executable that will generate the file
add_executable(generator generator.cxx)
-get_target_property(generator_PATH generator LOCATION)
-message("Location ${generator_PATH}")
-
################################################################
#
# Test using a wrapper to wrap a header file
@@ -120,6 +117,7 @@ add_custom_command(
COMMAND ${CMAKE_COMMAND} -E echo " Copying doc1pre.txt to doc2post.txt."
COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/doc1pre.txt
${PROJECT_BINARY_DIR}/doc2post.txt
+ BYPRODUCTS ${PROJECT_BINARY_DIR}/doc2post.txt
COMMENT "Running TDocument post-build commands"
)
@@ -156,6 +154,19 @@ add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/foo.c
${PROJECT_BINARY_DIR}/foo.c
)
+# Test using OBJECT_DEPENDS to bring in a custom command.
+# Use a path that can be simplified to make sure paths
+# are consistently normalized.
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/subdir/../subdir/subdir.h
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_CURRENT_SOURCE_DIR}/subdir.h.in
+ ${CMAKE_CURRENT_BINARY_DIR}/subdir/subdir.h
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/subdir.h.in
+ )
+set_property(SOURCE ${PROJECT_BINARY_DIR}/foo.c PROPERTY
+ OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/subdir/../subdir/subdir.h)
+
# Add custom command to generate not_included.h, which is a header
# file that is not included by any source in this project. This will
# test whether all custom command outputs explicitly listed as sources
@@ -166,13 +177,6 @@ add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/not_included.h
${PROJECT_BINARY_DIR}/not_included.h
)
-# Tell the executable where to find not_included.h.
-configure_file(
- ${PROJECT_SOURCE_DIR}/config.h.in
- ${PROJECT_BINARY_DIR}/config.h
- @ONLY IMMEDIATE
- )
-
# add the executable
add_executable(CustomCommand
${PROJECT_BINARY_DIR}/foo.h
@@ -188,8 +192,8 @@ add_executable(CustomCommand
# here to test adding the generation rule after referencing the
# generated source in a target.
add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/generated.c
- DEPENDS generator
- COMMAND ${generator_PATH}
+ DEPENDS $<1:generator> $<0:does_not_exist>
+ COMMAND generator
ARGS ${PROJECT_BINARY_DIR}/generated.c
)
@@ -224,8 +228,11 @@ add_subdirectory(GeneratorInExtraDir)
add_executable(tcat tcat.cxx)
+# Test that list expansion from a generator expression works.
+set_property(TARGET tcat PROPERTY DEPSLIST tcat gen_redirect_in.c)
+
add_custom_command(OUTPUT gen_redirect.c
- DEPENDS tcat gen_redirect_in.c
+ DEPENDS $<TARGET_PROPERTY:tcat,DEPSLIST>
COMMAND tcat < ${CMAKE_CURRENT_SOURCE_DIR}/gen_redirect_in.c > gen_redirect.c
COMMAND ${CMAKE_COMMAND} -E echo "#endif" >> gen_redirect.c
VERBATIM
@@ -367,15 +374,15 @@ endif()
foreach(arg ${CHECK_ARGS} "")
set(ARG "${arg}")
- string(REGEX REPLACE "\\\\" "\\\\\\\\" ARG "${ARG}")
- string(REGEX REPLACE "\"" "\\\\\"" ARG "${ARG}")
+ string(REPLACE "\\" "\\\\" ARG "${ARG}")
+ string(REPLACE "\"" "\\\"" ARG "${ARG}")
set(EXPECTED_ARGUMENTS
"${EXPECTED_ARGUMENTS} \"${ARG}\",
")
endforeach()
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/check_command_line.c.in
${CMAKE_CURRENT_BINARY_DIR}/check_command_line.c
- @ONLY IMMEDIATE)
+ @ONLY)
add_executable(check_command_line
${CMAKE_CURRENT_BINARY_DIR}/check_command_line.c)
set(output_name "check_command_line")
@@ -449,3 +456,60 @@ set_property(SOURCE perconfig.out PROPERTY SYMBOLIC 1)
add_custom_target(perconfig_target ALL
COMMAND ${CMAKE_COMMAND} -E echo "perconfig=$<TARGET_FILE:perconfig>" "config=$<CONFIGURATION>"
DEPENDS perconfig.out)
+
+# Test SOURCES in add_custom_target() with COMPILE_DEFINITIONS
+# which previously caused a crash in the makefile generators.
+add_custom_target(source_in_custom_target SOURCES source_in_custom_target.cpp)
+set_property(SOURCE source_in_custom_target
+ PROPERTY COMPILE_DEFINITIONS "TEST"
+)
+
+set(gen_path "${CMAKE_CURRENT_BINARY_DIR}//./foo")
+set(gen_file "${gen_path}/foo.cxx")
+
+add_custom_command(
+ OUTPUT "${gen_file}"
+ # Make sure the output directory exists before trying to write to it.
+ COMMAND ${CMAKE_COMMAND} -E make_directory "${gen_path}"
+ COMMAND ${CMAKE_COMMAND} -E touch "${gen_file}"
+)
+
+add_library(NormOutput "${gen_file}")
+
+set(gen_path "${gen_path}/bar")
+set(gen_file "${gen_path}/bar.cxx")
+
+add_custom_command(
+ OUTPUT "${gen_path}"
+ COMMAND ${CMAKE_COMMAND} -E make_directory "${gen_path}"
+)
+
+add_custom_command(
+ OUTPUT "${gen_file}"
+ DEPENDS "${gen_path}"
+ COMMAND ${CMAKE_COMMAND} -E touch "${gen_file}")
+
+add_library(NormDepends "${gen_file}")
+
+# Test that USES_TERMINAL is parsed correctly.
+# It seems much more difficult to test that USES_TERMINAL actually gives
+# the subprocess console access, as test output is piped through CTest,
+# and CTest itself might not be connected to the console.
+
+set(gen_file "${gen_path}/bar2.cxx")
+
+add_custom_command(
+ OUTPUT "${gen_file}"
+ DEPENDS "${gen_path}"
+ COMMAND ${CMAKE_COMMAND} -E touch "${gen_file}"
+ VERBATIM
+ USES_TERMINAL
+)
+
+add_library(UseConsole "${gen_file}")
+
+add_custom_target(UseConsoleTarget ALL
+ COMMAND ${CMAKE_COMMAND} -E echo "Custom console target."
+ VERBATIM
+ USES_TERMINAL
+)
diff --git a/Tests/CustomCommand/config.h.in b/Tests/CustomCommand/config.h.in
deleted file mode 100644
index 86c97bd95..000000000
--- a/Tests/CustomCommand/config.h.in
+++ /dev/null
@@ -1 +0,0 @@
-#define PROJECT_BINARY_DIR "@PROJECT_BINARY_DIR@"
diff --git a/Tests/CustomCommand/foo.in b/Tests/CustomCommand/foo.in
index 0c5021caa..15d2d2cd8 100644
--- a/Tests/CustomCommand/foo.in
+++ b/Tests/CustomCommand/foo.in
@@ -1,17 +1,21 @@
#include "doc1.h"
#include "foo.h"
-#include "config.h"
#include <stdio.h>
int generated();
int wrapped();
+#include "subdir/subdir.h"
+#ifndef SUBDIR_DEF
+# error SUBDIR_DEF not defined
+#endif
+
int main ()
{
if (generated()*wrapped()*doc() == 3*5*7)
{
- FILE* fin = fopen(PROJECT_BINARY_DIR "/not_included.h", "r");
+ FILE* fin = fopen("not_included.h", "r");
if(fin)
{
fclose(fin);
diff --git a/Tests/CustomCommand/source_in_custom_target.cpp b/Tests/CustomCommand/source_in_custom_target.cpp
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/CustomCommand/source_in_custom_target.cpp
diff --git a/Tests/CustomCommand/subdir.h.in b/Tests/CustomCommand/subdir.h.in
new file mode 100644
index 000000000..1e507504c
--- /dev/null
+++ b/Tests/CustomCommand/subdir.h.in
@@ -0,0 +1 @@
+#define SUBDIR_DEF
diff --git a/Tests/CustomCommandByproducts/CMakeLists.txt b/Tests/CustomCommandByproducts/CMakeLists.txt
new file mode 100644
index 000000000..3289e8f9f
--- /dev/null
+++ b/Tests/CustomCommandByproducts/CMakeLists.txt
@@ -0,0 +1,148 @@
+cmake_minimum_required(VERSION 3.1)
+project(CustomCommandByproducts C)
+
+# Generate a byproduct in a rule that runs in the target consuming it.
+add_custom_command(
+ OUTPUT timestamp1.txt
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ ${CMAKE_CURRENT_SOURCE_DIR}/byproduct1.c.in byproduct1.c
+ BYPRODUCTS byproduct1.c
+ COMMAND ${CMAKE_COMMAND} -E touch timestamp1.txt
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/byproduct1.c.in
+ )
+
+# Generate a byproduct in a rule that runs in a dependency of the consumer.
+add_custom_command(
+ OUTPUT timestamp2.txt
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ ${CMAKE_CURRENT_SOURCE_DIR}/byproduct2.c.in byproduct2.c
+ BYPRODUCTS byproduct2.c
+ COMMAND ${CMAKE_COMMAND} -E touch timestamp2.txt
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/byproduct2.c.in
+ )
+add_custom_target(Producer2 DEPENDS timestamp2.txt)
+
+# Generate a byproduct in a custom target.
+add_custom_target(Producer3_4
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ ${CMAKE_CURRENT_SOURCE_DIR}/byproduct3.c.in byproduct3.c
+ BYPRODUCTS byproduct3.c
+ )
+
+# Generate a byproduct in a custom target POST_BUILD command.
+add_custom_command(
+ TARGET Producer3_4 POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ ${CMAKE_CURRENT_SOURCE_DIR}/byproduct4.c.in byproduct4.c
+ BYPRODUCTS byproduct4.c
+ )
+
+add_executable(ProducerExe ProducerExe.c)
+
+# Generate a byproduct in an executable POST_BUILD command.
+add_custom_command(
+ TARGET ProducerExe POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ ${CMAKE_CURRENT_SOURCE_DIR}/byproduct5.c.in byproduct5.c
+ BYPRODUCTS byproduct5.c
+ )
+
+# Generate a byproduct in an executable PRE_LINK command.
+add_custom_command(
+ TARGET ProducerExe PRE_LINK
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ ${CMAKE_CURRENT_SOURCE_DIR}/byproduct6.c.in byproduct6.c
+ BYPRODUCTS byproduct6.c
+ )
+
+# Generate a byproduct in an executable PRE_BUILD command.
+add_custom_command(
+ TARGET ProducerExe PRE_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ ${CMAKE_CURRENT_SOURCE_DIR}/byproduct7.c.in byproduct7.c
+ BYPRODUCTS byproduct7.c
+ )
+
+# Generate a byproduct in a custom command that consumes other byproducts.
+add_custom_command(OUTPUT timestamp8.txt
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ ${CMAKE_CURRENT_SOURCE_DIR}/byproduct8.c.in byproduct8.c
+ COMMAND ${CMAKE_COMMAND} -E touch timestamp8.txt
+ BYPRODUCTS byproduct8.c
+ DEPENDS
+ ${CMAKE_CURRENT_BINARY_DIR}/byproduct2.c
+ ${CMAKE_CURRENT_BINARY_DIR}/byproduct3.c
+ ${CMAKE_CURRENT_BINARY_DIR}/byproduct4.c
+ ${CMAKE_CURRENT_BINARY_DIR}/byproduct5.c
+ ${CMAKE_CURRENT_BINARY_DIR}/byproduct6.c
+ ${CMAKE_CURRENT_BINARY_DIR}/byproduct7.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/byproduct8.c.in
+ )
+
+# Generate the library file of an imported target as a byproduct
+# of an external project.
+if(CMAKE_CONFIGURATION_TYPES)
+ set(cfg /${CMAKE_CFG_INTDIR})
+else()
+ set(cfg)
+endif()
+set(ExternalLibrary_LIBRARY
+ ${CMAKE_CURRENT_BINARY_DIR}/External-build${cfg}/${CMAKE_STATIC_LIBRARY_PREFIX}ExternalLibrary${CMAKE_STATIC_LIBRARY_SUFFIX}
+ )
+include(ExternalProject)
+ExternalProject_Add(ExternalTarget
+ SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/External"
+ BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/External-build"
+ PREFIX "${CMAKE_CURRENT_BINARY_DIR}/External-build/root"
+ DOWNLOAD_COMMAND ""
+ INSTALL_COMMAND ""
+ BUILD_BYPRODUCTS "${ExternalLibrary_LIBRARY}"
+ )
+add_library(ExternalLibrary STATIC IMPORTED)
+set_property(TARGET ExternalLibrary PROPERTY IMPORTED_LOCATION ${ExternalLibrary_LIBRARY})
+add_dependencies(ExternalLibrary ExternalTarget)
+
+# Generate the library file of an imported target as a byproduct
+# of an external project. The byproduct uses <BINARY_DIR> that is substituted
+# by the real binary path
+if(CMAKE_CONFIGURATION_TYPES)
+ set(cfg /${CMAKE_CFG_INTDIR})
+else()
+ set(cfg)
+endif()
+include(ExternalProject)
+ExternalProject_Add(ExtTargetSubst
+ SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/External"
+ DOWNLOAD_COMMAND ""
+ INSTALL_COMMAND ""
+ BUILD_BYPRODUCTS "<BINARY_DIR>${cfg}/${CMAKE_STATIC_LIBRARY_PREFIX}ExternalLibrary${CMAKE_STATIC_LIBRARY_SUFFIX}"
+ )
+ExternalProject_Get_Property(ExtTargetSubst binary_dir)
+add_library(ExternalLibraryWithSubstitution STATIC IMPORTED)
+set_property(TARGET ExternalLibraryWithSubstitution PROPERTY IMPORTED_LOCATION
+ ${binary_dir}${cfg}/${CMAKE_STATIC_LIBRARY_PREFIX}ExternalLibrary${CMAKE_STATIC_LIBRARY_SUFFIX})
+add_dependencies(ExternalLibraryWithSubstitution ExtTargetSubst)
+
+# Add an executable consuming all the byproducts.
+add_executable(CustomCommandByproducts
+ CustomCommandByproducts.c
+ byproduct1.c timestamp1.txt
+ byproduct2.c
+ byproduct3.c
+ byproduct4.c
+ byproduct5.c
+ byproduct6.c
+ byproduct7.c
+ byproduct8.c timestamp8.txt
+ )
+add_dependencies(CustomCommandByproducts Producer2)
+add_dependencies(CustomCommandByproducts Producer3_4)
+add_dependencies(CustomCommandByproducts ProducerExe)
+target_link_libraries(CustomCommandByproducts ExternalLibrary)
+
+if(CMAKE_GENERATOR STREQUAL "Ninja")
+ add_custom_target(CheckNinja ALL
+ COMMENT "Checking build.ninja"
+ COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/ninja-check.cmake
+ )
+endif()
diff --git a/Tests/CustomCommandByproducts/CustomCommandByproducts.c b/Tests/CustomCommandByproducts/CustomCommandByproducts.c
new file mode 100644
index 000000000..1916427b7
--- /dev/null
+++ b/Tests/CustomCommandByproducts/CustomCommandByproducts.c
@@ -0,0 +1,23 @@
+extern int byproduct1(void);
+extern int byproduct2(void);
+extern int byproduct3(void);
+extern int byproduct4(void);
+extern int byproduct5(void);
+extern int byproduct6(void);
+extern int byproduct7(void);
+extern int byproduct8(void);
+extern int ExternalLibrary(void);
+int main(void)
+{
+ return (
+ byproduct1() +
+ byproduct2() +
+ byproduct3() +
+ byproduct4() +
+ byproduct5() +
+ byproduct6() +
+ byproduct7() +
+ byproduct8() +
+ ExternalLibrary() +
+ 0);
+}
diff --git a/Tests/CustomCommandByproducts/External/CMakeLists.txt b/Tests/CustomCommandByproducts/External/CMakeLists.txt
new file mode 100644
index 000000000..feaa12ea4
--- /dev/null
+++ b/Tests/CustomCommandByproducts/External/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.1)
+project(External C)
+
+add_library(ExternalLibrary STATIC ExternalLibrary.c)
diff --git a/Tests/CustomCommandByproducts/External/ExternalLibrary.c b/Tests/CustomCommandByproducts/External/ExternalLibrary.c
new file mode 100644
index 000000000..a1dacf0c1
--- /dev/null
+++ b/Tests/CustomCommandByproducts/External/ExternalLibrary.c
@@ -0,0 +1 @@
+int ExternalLibrary(void) { return 0; }
diff --git a/Tests/CustomCommandByproducts/ProducerExe.c b/Tests/CustomCommandByproducts/ProducerExe.c
new file mode 100644
index 000000000..78f2de106
--- /dev/null
+++ b/Tests/CustomCommandByproducts/ProducerExe.c
@@ -0,0 +1 @@
+int main(void) { return 0; }
diff --git a/Tests/CustomCommandByproducts/byproduct1.c.in b/Tests/CustomCommandByproducts/byproduct1.c.in
new file mode 100644
index 000000000..5c3cc2471
--- /dev/null
+++ b/Tests/CustomCommandByproducts/byproduct1.c.in
@@ -0,0 +1 @@
+int byproduct1(void) { return 0; }
diff --git a/Tests/CustomCommandByproducts/byproduct2.c.in b/Tests/CustomCommandByproducts/byproduct2.c.in
new file mode 100644
index 000000000..eeb69efef
--- /dev/null
+++ b/Tests/CustomCommandByproducts/byproduct2.c.in
@@ -0,0 +1 @@
+int byproduct2(void) { return 0; }
diff --git a/Tests/CustomCommandByproducts/byproduct3.c.in b/Tests/CustomCommandByproducts/byproduct3.c.in
new file mode 100644
index 000000000..7d1531079
--- /dev/null
+++ b/Tests/CustomCommandByproducts/byproduct3.c.in
@@ -0,0 +1 @@
+int byproduct3(void) { return 0; }
diff --git a/Tests/CustomCommandByproducts/byproduct4.c.in b/Tests/CustomCommandByproducts/byproduct4.c.in
new file mode 100644
index 000000000..8b243ddfd
--- /dev/null
+++ b/Tests/CustomCommandByproducts/byproduct4.c.in
@@ -0,0 +1 @@
+int byproduct4(void) { return 0; }
diff --git a/Tests/CustomCommandByproducts/byproduct5.c.in b/Tests/CustomCommandByproducts/byproduct5.c.in
new file mode 100644
index 000000000..47f599039
--- /dev/null
+++ b/Tests/CustomCommandByproducts/byproduct5.c.in
@@ -0,0 +1 @@
+int byproduct5(void) { return 0; }
diff --git a/Tests/CustomCommandByproducts/byproduct6.c.in b/Tests/CustomCommandByproducts/byproduct6.c.in
new file mode 100644
index 000000000..d70c14f90
--- /dev/null
+++ b/Tests/CustomCommandByproducts/byproduct6.c.in
@@ -0,0 +1 @@
+int byproduct6(void) { return 0; }
diff --git a/Tests/CustomCommandByproducts/byproduct7.c.in b/Tests/CustomCommandByproducts/byproduct7.c.in
new file mode 100644
index 000000000..0be5006c1
--- /dev/null
+++ b/Tests/CustomCommandByproducts/byproduct7.c.in
@@ -0,0 +1 @@
+int byproduct7(void) { return 0; }
diff --git a/Tests/CustomCommandByproducts/byproduct8.c.in b/Tests/CustomCommandByproducts/byproduct8.c.in
new file mode 100644
index 000000000..abefd62c6
--- /dev/null
+++ b/Tests/CustomCommandByproducts/byproduct8.c.in
@@ -0,0 +1 @@
+int byproduct8(void) { return 0; }
diff --git a/Tests/CustomCommandByproducts/ninja-check.cmake b/Tests/CustomCommandByproducts/ninja-check.cmake
new file mode 100644
index 000000000..2fc3cc217
--- /dev/null
+++ b/Tests/CustomCommandByproducts/ninja-check.cmake
@@ -0,0 +1,20 @@
+file(READ build.ninja build_ninja)
+if("${build_ninja}" MATCHES [====[
+# Unknown Build Time Dependencies.
+# Tell Ninja that they may appear as side effects of build rules
+# otherwise ordered by order-only dependencies.
+
+((build [^:]*: phony [^\n]*
+)*)# ========]====])
+ set(phony "${CMAKE_MATCH_1}")
+ if(NOT phony)
+ message(STATUS "build.ninja correctly does not have extra phony rules")
+ else()
+ string(REGEX REPLACE "\n+$" "" phony "${phony}")
+ string(REGEX REPLACE "\n" "\n " phony " ${phony}")
+ message(FATAL_ERROR "build.ninja incorrectly has extra phony rules:\n"
+ "${phony}")
+ endif()
+else()
+ message(FATAL_ERROR "build.ninja is incorrectly missing expected block")
+endif()
diff --git a/Tests/CxxDialect/CMakeLists.txt b/Tests/CxxDialect/CMakeLists.txt
new file mode 100644
index 000000000..8c903398c
--- /dev/null
+++ b/Tests/CxxDialect/CMakeLists.txt
@@ -0,0 +1,28 @@
+cmake_minimum_required(VERSION 2.8.12)
+cmake_policy(SET CMP0025 NEW)
+project(CxxDialect)
+
+add_executable(use_typeof use_typeof.cxx)
+set_property(TARGET use_typeof PROPERTY CXX_STANDARD 98)
+
+add_executable(use_constexpr use_constexpr.cxx)
+set_property(TARGET use_constexpr PROPERTY CXX_STANDARD 11)
+
+add_executable(CxxDialect use_constexpr_and_typeof.cxx)
+set_property(TARGET CxxDialect PROPERTY CXX_STANDARD 11)
+
+try_compile(typeof_no_extensions_works
+ "${CMAKE_CURRENT_BINARY_DIR}/use_typeof_test"
+ "${CMAKE_CURRENT_SOURCE_DIR}/use_typeof.cxx"
+ COMPILE_DEFINITIONS
+ CMAKE_FLAGS
+ "-DCMAKE_CXX_STANDARD=98"
+ "-DCMAKE_CXX_EXTENSIONS=FALSE"
+ OUTPUT_VARIABLE OUTPUT
+)
+
+if (typeof_no_extensions_works)
+ message("Use of typeof extension with extensions disabled works, but is expected to fail: ${OUTPUT}")
+else()
+ message("Use of typeof extension with extensions disabled fails, as expected")
+endif()
diff --git a/Tests/CxxDialect/use_constexpr.cxx b/Tests/CxxDialect/use_constexpr.cxx
new file mode 100644
index 000000000..30ccc4cac
--- /dev/null
+++ b/Tests/CxxDialect/use_constexpr.cxx
@@ -0,0 +1,10 @@
+
+constexpr int foo()
+{
+ return 0;
+}
+
+int main(int argc, char**)
+{
+ return foo();
+}
diff --git a/Tests/CxxDialect/use_constexpr_and_typeof.cxx b/Tests/CxxDialect/use_constexpr_and_typeof.cxx
new file mode 100644
index 000000000..af217b67e
--- /dev/null
+++ b/Tests/CxxDialect/use_constexpr_and_typeof.cxx
@@ -0,0 +1,11 @@
+
+constexpr int foo()
+{
+ return 0;
+}
+
+int main(int argc, char**)
+{
+ typeof(argc) ret = foo();
+ return ret;
+}
diff --git a/Tests/CxxDialect/use_typeof.cxx b/Tests/CxxDialect/use_typeof.cxx
new file mode 100644
index 000000000..dabb61f4f
--- /dev/null
+++ b/Tests/CxxDialect/use_typeof.cxx
@@ -0,0 +1,6 @@
+
+int main(int argc, char**)
+{
+ typeof(argc) ret = 0;
+ return ret;
+}
diff --git a/Tests/CxxSubdirC/CMakeLists.txt b/Tests/CxxSubdirC/CMakeLists.txt
new file mode 100644
index 000000000..52474f8dc
--- /dev/null
+++ b/Tests/CxxSubdirC/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.0)
+project(CxxSubdirC CXX)
+add_subdirectory(Cdir)
+add_executable(CxxSubdirC main.cxx $<TARGET_OBJECTS:Cobj>)
diff --git a/Tests/CxxSubdirC/Cdir/CMakeLists.txt b/Tests/CxxSubdirC/Cdir/CMakeLists.txt
new file mode 100644
index 000000000..08a87579b
--- /dev/null
+++ b/Tests/CxxSubdirC/Cdir/CMakeLists.txt
@@ -0,0 +1,2 @@
+enable_language(C)
+add_library(Cobj OBJECT Cobj.c)
diff --git a/Tests/CxxSubdirC/Cdir/Cobj.c b/Tests/CxxSubdirC/Cdir/Cobj.c
new file mode 100644
index 000000000..75a00458b
--- /dev/null
+++ b/Tests/CxxSubdirC/Cdir/Cobj.c
@@ -0,0 +1 @@
+int Cobj(void) { return 0; }
diff --git a/Tests/CxxSubdirC/main.cxx b/Tests/CxxSubdirC/main.cxx
new file mode 100644
index 000000000..049220f11
--- /dev/null
+++ b/Tests/CxxSubdirC/main.cxx
@@ -0,0 +1,2 @@
+extern "C" int Cobj(void);
+int main() { return Cobj(); }
diff --git a/Tests/DelphiCoverage/DartConfiguration.tcl.in b/Tests/DelphiCoverage/DartConfiguration.tcl.in
new file mode 100644
index 000000000..4edcea6ee
--- /dev/null
+++ b/Tests/DelphiCoverage/DartConfiguration.tcl.in
@@ -0,0 +1,8 @@
+# This file is configured by CMake automatically as DartConfiguration.tcl
+# If you choose not to use CMake, this file may be hand configured, by
+# filling in the required variables.
+
+
+# Configuration directories and files
+SourceDirectory: ${CMake_BINARY_DIR}/Testing/DelphiCoverage
+BuildDirectory: ${CMake_BINARY_DIR}/Testing/DelphiCoverage
diff --git a/Tests/DelphiCoverage/UTCovTest(UTCovTest.pas).html.in b/Tests/DelphiCoverage/UTCovTest(UTCovTest.pas).html.in
new file mode 100644
index 000000000..9caaea369
--- /dev/null
+++ b/Tests/DelphiCoverage/UTCovTest(UTCovTest.pas).html.in
@@ -0,0 +1,117 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+ <title>Delphi CodeCoverage Coverage Report</title>
+<style type="text/css">
+table {border-spacing:0; border-collapse:collapse;}
+table, td, th {border: 1px solid black;}
+td, th {background: white; margin: 0; padding: 2px 0.5em 2px 0.5em}
+td {border-width: 0 1px 0 0;}
+th {border-width: 1px 1px 1px 0;}
+p, h1, h2, h3, th {font-family: verdana,arial,sans-serif; font-size: 10pt;}
+td {font-family: courier,monospace; font-size: 10pt;}
+th {background: #CCCCCC;}
+table.o tr td:nth-child(1) {font-weight: bold;}
+table.o tr td:nth-child(2) {text-align: right;}
+table.o tr td {border-width: 1px;}
+table.s {width: 100%;}
+table.s tr td {padding: 0 0.25em 0 0.25em;}
+table.s tr td:first-child {text-align: right; font-weight: bold;}
+table.s tr.notcovered td {background: #DDDDFF;}
+table.s tr.nocodegen td {background: #FFFFEE;}
+table.s tr.covered td {background: #CCFFCC;}
+table.s tr.covered td:first-child {color: green;}
+table.s {border-width: 1px 0 1px 1px;}
+table.sum tr td {border-width: 1px;}
+table.sum tr th {text-align:right;}
+table.sum tr th:first-child {text-align:center;}
+table.sum tr td {text-align:right;}
+table.sum tr td:first-child {text-align:left;}
+</style>
+</head>
+<body>
+<p>Coverage report for <strong>UTCovTest (C:\Users\joe.snyder\Work\OSEHRA\VistA\Packages\Order Entry Results Reporting\CPRS\Testing\Tests\UTCovTest.pas)</strong>.</p>
+<p> Generated at 10/3/2014 12:24:11 PM by <a href="http://code.google.com/p/delphi-code-coverage/" title="Code Coverage for Delphi 5+">DelphiCodeCoverage</a> - an open source tool for Delphi Code Coverage.</p>
+<p> Statistics for C:\Users\joe.snyder\Work\OSEHRA\VistA\Packages\Order Entry Results Reporting\CPRS\Testing\Tests\UTCovTest.pas </p>
+<table class="o"><tr><td>Number of lines covered</td><td>19</td></tr><tr><td>Number of lines with code gen</td><td>19</td></tr><tr><td>Line coverage</td><td>100%</td></tr></table>
+<br /><br />
+<table class="s">
+<tr class="nocodegen"><td>1</td><td><pre style="display:inline;">//---------------------------------------------------------------------------</pre></td></tr>
+<tr class="nocodegen"><td>2</td><td><pre style="display:inline;">// Copyright 2012 The Open Source Electronic Health Record Agent</pre></td></tr>
+<tr class="nocodegen"><td>3</td><td><pre style="display:inline;">//</pre></td></tr>
+<tr class="nocodegen"><td>4</td><td><pre style="display:inline;">// Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</pre></td></tr>
+<tr class="nocodegen"><td>5</td><td><pre style="display:inline;">// you may not use this file except in compliance with the License.</pre></td></tr>
+<tr class="nocodegen"><td>6</td><td><pre style="display:inline;">// You may obtain a copy of the License at</pre></td></tr>
+<tr class="nocodegen"><td>7</td><td><pre style="display:inline;">//</pre></td></tr>
+<tr class="nocodegen"><td>8</td><td><pre style="display:inline;">// &nbsp; &nbsp; http://www.apache.org/licenses/LICENSE-2.0</pre></td></tr>
+<tr class="nocodegen"><td>9</td><td><pre style="display:inline;">//</pre></td></tr>
+<tr class="nocodegen"><td>10</td><td><pre style="display:inline;">// Unless required by applicable law or agreed to in writing, software</pre></td></tr>
+<tr class="nocodegen"><td>11</td><td><pre style="display:inline;">// distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</pre></td></tr>
+<tr class="nocodegen"><td>12</td><td><pre style="display:inline;">// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</pre></td></tr>
+<tr class="nocodegen"><td>13</td><td><pre style="display:inline;">// See the License for the specific language governing permissions and</pre></td></tr>
+<tr class="nocodegen"><td>14</td><td><pre style="display:inline;">// limitations under the License.</pre></td></tr>
+<tr class="nocodegen"><td>15</td><td><pre style="display:inline;">//---------------------------------------------------------------------------</pre></td></tr>
+<tr class="nocodegen"><td>16</td><td><pre style="display:inline;">unit UTCovTest;</pre></td></tr>
+<tr class="nocodegen"><td>17</td><td><pre style="display:inline;">interface</pre></td></tr>
+<tr class="nocodegen"><td>18</td><td><pre style="display:inline;">uses UnitTest, TestFrameWork,SysUtils,Windows;</pre></td></tr>
+<tr class="nocodegen"><td>19</td><td><pre style="display:inline;"></pre></td></tr>
+<tr class="nocodegen"><td>20</td><td><pre style="display:inline;">implementation</pre></td></tr>
+<tr class="nocodegen"><td>21</td><td><pre style="display:inline;">type</pre></td></tr>
+<tr class="nocodegen"><td>22</td><td><pre style="display:inline;">UTCovTestTests=class(TTestCase)</pre></td></tr>
+<tr class="nocodegen"><td>23</td><td><pre style="display:inline;"> &nbsp;public</pre></td></tr>
+<tr class="nocodegen"><td>24</td><td><pre style="display:inline;"> &nbsp;procedure SetUp; override;</pre></td></tr>
+<tr class="nocodegen"><td>25</td><td><pre style="display:inline;"> &nbsp;procedure TearDown; override;</pre></td></tr>
+<tr class="nocodegen"><td>26</td><td><pre style="display:inline;"></pre></td></tr>
+<tr class="nocodegen"><td>27</td><td><pre style="display:inline;"> &nbsp;published</pre></td></tr>
+<tr class="nocodegen"><td>28</td><td><pre style="display:inline;"> &nbsp; &nbsp;procedure TestCov1;</pre></td></tr>
+<tr class="nocodegen"><td>29</td><td><pre style="display:inline;"> &nbsp; &nbsp;procedure TestCov2;</pre></td></tr>
+<tr class="nocodegen"><td>30</td><td><pre style="display:inline;"> &nbsp; &nbsp;procedure TestCov3;</pre></td></tr>
+<tr class="nocodegen"><td>31</td><td><pre style="display:inline;"> &nbsp;end;</pre></td></tr>
+<tr class="nocodegen"><td>32</td><td><pre style="display:inline;"></pre></td></tr>
+<tr class="nocodegen"><td>33</td><td><pre style="display:inline;">procedure NotRun;</pre></td></tr>
+<tr class="nocodegen"><td>34</td><td><pre style="display:inline;">begin</pre></td></tr>
+<tr class="nocodegen"><td>35</td><td><pre style="display:inline;"> &nbsp; &nbsp;WriteLn(&apos;This line will never run&apos;);</pre></td></tr>
+<tr class="nocodegen"><td>36</td><td><pre style="display:inline;">end;</pre></td></tr>
+<tr class="nocodegen"><td>37</td><td><pre style="display:inline;">procedure UTCovTestTests.SetUp;</pre></td></tr>
+<tr class="nocodegen"><td>38</td><td><pre style="display:inline;">begin</pre></td></tr>
+<tr class="covered"><td>39</td><td><pre style="display:inline;">end;</pre></td></tr>
+<tr class="nocodegen"><td>40</td><td><pre style="display:inline;"></pre></td></tr>
+<tr class="nocodegen"><td>41</td><td><pre style="display:inline;">procedure UTCovTestTests.TearDown;</pre></td></tr>
+<tr class="nocodegen"><td>42</td><td><pre style="display:inline;">begin</pre></td></tr>
+<tr class="covered"><td>43</td><td><pre style="display:inline;">end;</pre></td></tr>
+<tr class="nocodegen"><td>44</td><td><pre style="display:inline;"></pre></td></tr>
+<tr class="nocodegen"><td>45</td><td><pre style="display:inline;">procedure UTCovTestTests.TestCov1;</pre></td></tr>
+<tr class="covered"><td>46</td><td><pre style="display:inline;">begin</pre></td></tr>
+<tr class="nocodegen"><td>47</td><td><pre style="display:inline;"> &nbsp;{</pre></td></tr>
+<tr class="nocodegen"><td>48</td><td><pre style="display:inline;"> &nbsp;Block comment lines</pre></td></tr>
+<tr class="nocodegen"><td>49</td><td><pre style="display:inline;"> &nbsp;}</pre></td></tr>
+<tr class="covered"><td>50</td><td><pre style="display:inline;"> &nbsp;CheckEquals(1,2-1);</pre></td></tr>
+<tr class="covered"><td>51</td><td><pre style="display:inline;">end;</pre></td></tr>
+<tr class="nocodegen"><td>52</td><td><pre style="display:inline;"></pre></td></tr>
+<tr class="nocodegen"><td>53</td><td><pre style="display:inline;">procedure UTCovTestTests.TestCov2;</pre></td></tr>
+<tr class="nocodegen"><td>54</td><td><pre style="display:inline;">var</pre></td></tr>
+<tr class="nocodegen"><td>55</td><td><pre style="display:inline;"> &nbsp;i:DWORD;</pre></td></tr>
+<tr class="covered"><td>56</td><td><pre style="display:inline;">begin</pre></td></tr>
+<tr class="covered"><td>57</td><td><pre style="display:inline;"> &nbsp;for i := 0 to 1 do</pre></td></tr>
+<tr class="covered"><td>58</td><td><pre style="display:inline;"> &nbsp; &nbsp;WriteLn( IntToStr(i));</pre></td></tr>
+<tr class="nocodegen"><td>59</td><td><pre style="display:inline;"> &nbsp;// Comment</pre></td></tr>
+<tr class="covered"><td>60</td><td><pre style="display:inline;"> &nbsp;CheckEquals(i,2);</pre></td></tr>
+<tr class="covered"><td>61</td><td><pre style="display:inline;">end;</pre></td></tr>
+<tr class="nocodegen"><td>62</td><td><pre style="display:inline;"></pre></td></tr>
+<tr class="nocodegen"><td>63</td><td><pre style="display:inline;">procedure UTCovTestTests.TestCov3;</pre></td></tr>
+<tr class="nocodegen"><td>64</td><td><pre style="display:inline;">var</pre></td></tr>
+<tr class="nocodegen"><td>65</td><td><pre style="display:inline;"> i : DWORD;</pre></td></tr>
+<tr class="covered"><td>66</td><td><pre style="display:inline;">begin</pre></td></tr>
+<tr class="covered"><td>67</td><td><pre style="display:inline;"> &nbsp;i := 0;</pre></td></tr>
+<tr class="covered"><td>68</td><td><pre style="display:inline;"> &nbsp;while i &lt; 5 do</pre></td></tr>
+<tr class="covered"><td>69</td><td><pre style="display:inline;"> &nbsp; i := i+1;</pre></td></tr>
+<tr class="covered"><td>70</td><td><pre style="display:inline;"> &nbsp;CheckEquals(i,5);</pre></td></tr>
+<tr class="covered"><td>71</td><td><pre style="display:inline;">end;</pre></td></tr>
+<tr class="nocodegen"><td>72</td><td><pre style="display:inline;"></pre></td></tr>
+<tr class="covered"><td>73</td><td><pre style="display:inline;">begin</pre></td></tr>
+<tr class="covered"><td>74</td><td><pre style="display:inline;"> &nbsp;UnitTest.addSuite(UTCovTestTests.Suite);</pre></td></tr>
+<tr class="covered"><td>75</td><td><pre style="display:inline;">end.</pre></td></tr>
+</table>
+</body>
+</html>
diff --git a/Tests/DelphiCoverage/src/UTCovTest.pas b/Tests/DelphiCoverage/src/UTCovTest.pas
new file mode 100644
index 000000000..66db3c065
--- /dev/null
+++ b/Tests/DelphiCoverage/src/UTCovTest.pas
@@ -0,0 +1,75 @@
+//---------------------------------------------------------------------------
+// Copyright 2012 The Open Source Electronic Health Record Agent
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//---------------------------------------------------------------------------
+unit UTCovTest;
+interface
+uses UnitTest, TestFrameWork,SysUtils,Windows;
+
+implementation
+type
+UTCovTestTests=class(TTestCase)
+ public
+ procedure SetUp; override;
+ procedure TearDown; override;
+
+ published
+ procedure TestCov1;
+ procedure TestCov2;
+ procedure TestCov3;
+ end;
+
+procedure NotRun;
+begin
+ WriteLn('This line will never run');
+end;
+procedure UTCovTestTests.SetUp;
+begin
+end;
+
+procedure UTCovTestTests.TearDown;
+begin
+end;
+
+procedure UTCovTestTests.TestCov1;
+begin
+ {
+ Block comment lines
+ }
+ CheckEquals(1,2-1);
+end;
+
+procedure UTCovTestTests.TestCov2;
+var
+ i:DWORD;
+begin
+ for i := 0 to 1 do
+ WriteLn( IntToStr(i));
+ // Comment
+ CheckEquals(i,2);
+end;
+
+procedure UTCovTestTests.TestCov3;
+var
+ i : DWORD;
+begin
+ i := 0;
+ while i < 5 do
+ i := i+1;
+ CheckEquals(i,5);
+end;
+
+begin
+ UnitTest.addSuite(UTCovTestTests.Suite);
+end. \ No newline at end of file
diff --git a/Tests/Dependency/CMakeLists.txt b/Tests/Dependency/CMakeLists.txt
index ef4204803..ebc2d1066 100644
--- a/Tests/Dependency/CMakeLists.txt
+++ b/Tests/Dependency/CMakeLists.txt
@@ -51,3 +51,4 @@ add_subdirectory(Case1)
add_subdirectory(Case2)
add_subdirectory(Case3)
add_subdirectory(Case4)
+add_subdirectory(Case5)
diff --git a/Tests/Dependency/Case5/CMakeLists.txt b/Tests/Dependency/Case5/CMakeLists.txt
new file mode 100644
index 000000000..e954b02ea
--- /dev/null
+++ b/Tests/Dependency/Case5/CMakeLists.txt
@@ -0,0 +1,8 @@
+project(CASE5 C)
+
+add_library(case5Foo SHARED foo.c)
+add_library(case5Bar STATIC bar.c)
+target_link_libraries(case5Bar case5Foo)
+
+add_executable(case5 main.c)
+target_link_libraries(case5 case5Foo case5Bar)
diff --git a/Tests/Dependency/Case5/bar.c b/Tests/Dependency/Case5/bar.c
new file mode 100644
index 000000000..4cb1b1bd1
--- /dev/null
+++ b/Tests/Dependency/Case5/bar.c
@@ -0,0 +1,12 @@
+#ifdef _WIN32
+__declspec(dllimport)
+#endif
+void foo(void);
+
+#include <stdio.h>
+
+void bar(void)
+{
+ foo();
+ printf("bar()\n");
+}
diff --git a/Tests/Dependency/Case5/foo.c b/Tests/Dependency/Case5/foo.c
new file mode 100644
index 000000000..794833dce
--- /dev/null
+++ b/Tests/Dependency/Case5/foo.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+void foo(void)
+{
+ printf("foo()\n");
+}
diff --git a/Tests/Dependency/Case5/main.c b/Tests/Dependency/Case5/main.c
new file mode 100644
index 000000000..ae3dc9570
--- /dev/null
+++ b/Tests/Dependency/Case5/main.c
@@ -0,0 +1,7 @@
+void bar(void);
+
+int main(int argc, char *argv[])
+{
+ bar();
+ return 0;
+}
diff --git a/Tests/DocTest/CMakeLists.txt b/Tests/DocTest/CMakeLists.txt
deleted file mode 100644
index 837328e81..000000000
--- a/Tests/DocTest/CMakeLists.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-cmake_minimum_required (VERSION 2.6)
-project (DocTest)
-
-add_executable (DocTest DocTest.cxx)
-
-set_property(GLOBAL PROPERTY REPORT_UNDEFINED_PROPERTIES
- "${CMAKE_CURRENT_BINARY_DIR}/UndefinedProperties.txt")
diff --git a/Tests/DocTest/DocTest.cxx b/Tests/DocTest/DocTest.cxx
deleted file mode 100644
index a8a62ab6c..000000000
--- a/Tests/DocTest/DocTest.cxx
+++ /dev/null
@@ -1,33 +0,0 @@
-#include <fstream>
-#include <iostream>
-#include <stdio.h>
-
-int main ()
-{
- int result = 0;
-
- // parse the dart test file
- std::ifstream fin("UndefinedProperties.txt");
- if(!fin)
- {
- fprintf(stderr,"failed to find undefined properties file");
- return 1;
- }
-
- char buffer[1024];
- while ( fin )
- {
- buffer[0] = 0;
- fin.getline(buffer, 1023);
- buffer[1023] = 0;
- std::string line = buffer;
- if(line.size() && line.find("with scope VARIABLE") == std::string::npos)
- {
- fprintf(stderr, "%s\n", line.c_str());
- result = 1;
- }
- }
- fin.close();
-
- return result;
-}
diff --git a/Tests/ExportImport/CMakeLists.txt b/Tests/ExportImport/CMakeLists.txt
index b8368fc98..eaad3d46c 100644
--- a/Tests/ExportImport/CMakeLists.txt
+++ b/Tests/ExportImport/CMakeLists.txt
@@ -1,5 +1,8 @@
cmake_minimum_required (VERSION 2.7.20090711)
project(ExportImport C CXX)
+if(NOT DEFINED CMake_TEST_NESTED_MAKE_PROGRAM AND NOT CMAKE_GENERATOR MATCHES "Visual Studio")
+ set(CMake_TEST_NESTED_MAKE_PROGRAM "${CMAKE_MAKE_PROGRAM}")
+endif()
# Wipe out the install tree to make sure the exporter works.
add_custom_command(
@@ -41,8 +44,8 @@ add_custom_command(
--build-project Export
--build-target install
--build-generator ${CMAKE_GENERATOR}
+ --build-generator-platform "${CMAKE_GENERATOR_PLATFORM}"
--build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
- --build-makeprogram ${CMAKE_MAKE_PROGRAM}
--build-options -C${ExportImport_BINARY_DIR}/InitialCache.cmake
VERBATIM
)
@@ -63,8 +66,8 @@ add_custom_command(
--build-noclean
--build-project Import
--build-generator ${CMAKE_GENERATOR}
+ --build-generator-platform "${CMAKE_GENERATOR_PLATFORM}"
--build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
- --build-makeprogram ${CMAKE_MAKE_PROGRAM}
--build-options -C${ExportImport_BINARY_DIR}/InitialCache.cmake
VERBATIM
)
diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt
index 72ae78f57..c2ecb0b1c 100644
--- a/Tests/ExportImport/Export/CMakeLists.txt
+++ b/Tests/ExportImport/Export/CMakeLists.txt
@@ -23,6 +23,22 @@ add_library(testLib1 STATIC testLib1.c)
add_library(testLib2 STATIC testLib2.c)
target_link_libraries(testLib2 testLib1)
+# Test install(FILES) with generator expressions referencing testLib1.
+add_custom_command(TARGET testLib1 POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:testLib1>
+ $<TARGET_FILE:testLib1>.genex
+ )
+install(FILES $<TARGET_FILE:testLib1>.genex
+ DESTINATION $<1:lib>$<0:/wrong>
+ )
+set_property(TARGET testLib1 PROPERTY MY_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/testLib1file1.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/testLib1file2.txt
+ )
+install(FILES $<TARGET_PROPERTY:testLib1,MY_FILES>
+ DESTINATION $<1:doc>$<0:/wrong>
+ )
+
# Test library with empty link interface. Link it to an implementation
# dependency that itself links to dependencies publicly.
add_library(testLib3ImpDep SHARED testLib3ImpDep.c)
@@ -52,6 +68,17 @@ add_library(testLib5 SHARED testLib5.c)
add_library(testLib6 STATIC testLib6.cxx testLib6c.c)
+add_library(testLibPerConfigDest STATIC testLibPerConfigDest.c)
+install(TARGETS testLibPerConfigDest EXPORT exp
+ DESTINATION lib/$<$<BOOL:$<CONFIG>>:$<CONFIG>>$<$<NOT:$<BOOL:$<CONFIG>>>:NoConfig>
+ )
+
+# Test OUTPUT_NAME properties with generator expressions
+add_library(testLib7 STATIC testLib7.c)
+set_property(TARGET testLib7 PROPERTY OUTPUT_NAME_DEBUG testLib7D-$<CONFIG>)
+set_property(TARGET testLib7 PROPERTY OUTPUT_NAME_RELEASE testLib7R-$<CONFIG>)
+set_property(TARGET testLib7 PROPERTY OUTPUT_NAME testLib7-$<CONFIG>)
+
# Work-around: Visual Studio 6 does not support per-target object files.
set(VS6)
if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 6")
@@ -78,6 +105,19 @@ target_link_libraries(testLib4
add_executable(testExe3 testExe3.c)
set_property(TARGET testExe3 PROPERTY MACOSX_BUNDLE 1)
+# Test <ARCHIVE|LIBRARY|RUNTIME>_OUTPUT_DIRECTORY[_<CONFIG>] properties with generator expressions
+add_executable(testExe4 testExe4.c)
+target_link_libraries(testExe4 testExe1lib)
+set_property(TARGET testLib7 PROPERTY ARCHIVE_OUTPUT_DIRECTORY_DEBUG testLib7D-$<CONFIG>)
+set_property(TARGET testLib7 PROPERTY ARCHIVE_OUTPUT_DIRECTORY_RELEASE testLib7R-$<CONFIG>)
+set_property(TARGET testLib7 PROPERTY ARCHIVE_OUTPUT_DIRECTORY testLib7-$<CONFIG>)
+set_property(TARGET testLib5 PROPERTY LIBRARY_OUTPUT_DIRECTORY_DEBUG testLib5D-$<CONFIG>)
+set_property(TARGET testLib5 PROPERTY LIBRARY_OUTPUT_DIRECTORY_RELEASE testLib5R-$<CONFIG>)
+set_property(TARGET testLib5 PROPERTY LIBRARY_OUTPUT_DIRECTORY testLib5-$<CONFIG>)
+set_property(TARGET testExe4 PROPERTY RUNTIME_OUTPUT_DIRECTORY_DEBUG testExe4D-$<CONFIG>)
+set_property(TARGET testExe4 PROPERTY RUNTIME_OUTPUT_DIRECTORY_RELEASE testExe4R-$<CONFIG>)
+set_property(TARGET testExe4 PROPERTY RUNTIME_OUTPUT_DIRECTORY testExe4-$<CONFIG>)
+
# Test cyclic dependencies.
add_library(testLibCycleA STATIC
testLibCycleA1.c testLibCycleA2.c testLibCycleA3.c)
@@ -87,13 +127,21 @@ target_link_libraries(testLibCycleA testLibCycleB)
target_link_libraries(testLibCycleB testLibCycleA)
set_property(TARGET testLibCycleA PROPERTY LINK_INTERFACE_MULTIPLICITY 3)
+add_library(testLibNoSONAME SHARED testLibNoSONAME.c)
+set_property(TARGET testLibNoSONAME PROPERTY NO_SONAME 1)
+
+cmake_policy(PUSH)
+cmake_policy(SET CMP0022 NEW)
# Test exporting dependent libraries into different exports
add_library(testLibRequired testLibRequired.c)
add_library(testLibDepends testLibDepends.c)
target_link_libraries(testLibDepends LINK_PUBLIC testLibRequired)
+add_library(testStaticLibRequiredPrivate testStaticLibRequiredPrivate.c)
+target_link_libraries(testLibDepends PRIVATE testStaticLibRequiredPrivate)
+cmake_policy(POP)
macro(add_include_lib _libName)
- file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_libName}.c" "// no content\n")
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_libName}.c" "/* no content */\n")
add_library(${_libName} "${CMAKE_CURRENT_BINARY_DIR}/${_libName}.c")
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${_libName}")
set_property(TARGET ${_libName} APPEND PROPERTY
@@ -101,7 +149,7 @@ macro(add_include_lib _libName)
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/${_libName}>"
)
if (NOT "${ARGV1}" STREQUAL "NO_HEADER")
- file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_libName}/${_libName}.h" "// no content\n")
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_libName}/${_libName}.h" "/* no content */\n")
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/${_libName}/${_libName}.h"
DESTINATION include/${_libName}
@@ -139,7 +187,7 @@ install(FILES
)
add_include_lib(testLibIncludeRequired6)
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/testLibIncludeRequired7/testLibIncludeRequired7.h" "// No content\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/testLibIncludeRequired7/testLibIncludeRequired7.h" "/* No content */\n")
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/testLibIncludeRequired7/testLibIncludeRequired7.h"
DESTINATION include/testLibIncludeRequired7
@@ -227,6 +275,7 @@ install(FILES
DESTINATION include/testSharedLibRequiredUser
)
+cmake_policy(PUSH)
cmake_policy(SET CMP0022 NEW)
add_library(testSharedLibRequiredUser2 SHARED testSharedLibRequiredUser2.cpp)
generate_export_header(testSharedLibRequiredUser2)
@@ -240,7 +289,7 @@ install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/testsharedlibrequireduser2_export.h"
DESTINATION include/testSharedLibRequiredUser2
)
-cmake_policy(SET CMP0022 OLD)
+cmake_policy(POP)
add_library(testSharedLibDepends SHARED testSharedLibDepends.cpp)
set_property(TARGET testSharedLibDepends APPEND PROPERTY
@@ -268,6 +317,8 @@ target_link_libraries(testSharedLibDepends LINK_PUBLIC renamed_on_export)
target_link_libraries(testSharedLibDepends LINK_INTERFACE_LIBRARIES
$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:$<TARGET_NAME:testSharedLibRequired>>)
+cmake_policy(PUSH)
+cmake_policy(SET CMP0022 OLD)
add_library(cmp0022OLD SHARED cmp0022_vs6_1.cpp)
generate_export_header(cmp0022OLD BASE_NAME cmp0022)
target_include_directories(cmp0022OLD PUBLIC
@@ -281,7 +332,7 @@ target_include_directories(cmp0022NEW PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR};${CMAKE_CURRENT_SOURCE_DIR}>"
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/cmp0022>"
)
-cmake_policy(SET CMP0022 OLD)
+cmake_policy(POP)
install(FILES
"${CMAKE_CURRENT_SOURCE_DIR}/cmp0022.h"
"${CMAKE_CURRENT_BINARY_DIR}/cmp0022_export.h"
@@ -298,12 +349,38 @@ set_property(TARGET cmp0022OLD APPEND PROPERTY LINK_INTERFACE_LIBRARIES testLib3
add_library(noIncludesInterface empty.cpp)
+add_library(systemlib SHARED systemlib.cpp)
+install(FILES systemlib.h DESTINATION include/systemlib)
+target_include_directories(systemlib
+ INTERFACE
+ $<INSTALL_INTERFACE:include/systemlib>
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
+)
+
install(TARGETS testLibRequired
EXPORT RequiredExp DESTINATION lib
INCLUDES DESTINATION
installIncludesTest
$<INSTALL_PREFIX>/installIncludesTest2
- )
+ installIncludesTest3/$<TARGET_PROPERTY:NAME>
+ $<TARGET_PROPERTY:NAME>/installIncludesTest4
+ $<INSTALL_INTERFACE:installIncludesTest5$<0:>>
+ $<INSTALL_INTERFACE:$<0:>installIncludesTest6>
+ $<INSTALL_INTERFACE:$<INSTALL_PREFIX>/installIncludesTest7>
+)
+
+target_include_directories(testLibRequired INTERFACE
+ # These can't be in the above install(INCLUDES DESTINATION call because
+ # that is only for installed interfaces. These directories are prefixes
+ # in the build dir, which is an error for the installed interface.
+ # We add them here so that we don't have to add conditions in the Import
+ # component of the test.
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest5$<0:>>
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/$<0:>installIncludesTest6>
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest7>
+ $<INSTALL_INTERFACE:installIncludesTest8/$<0:>>
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest8$<0:>>
+)
install(TARGETS
testLibIncludeRequired1
testLibIncludeRequired2
@@ -319,13 +396,29 @@ install(TARGETS
INCLUDES DESTINATION
$<INSTALL_PREFIX>/include/$<TARGET_PROPERTY:NAME>
)
+install(TARGETS
+ testStaticLibRequiredPrivate
+ EXPORT RequiredExp DESTINATION lib
+)
install(EXPORT RequiredExp NAMESPACE Req:: FILE testLibRequiredTargets.cmake DESTINATION lib/cmake/testLibRequired)
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest")
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest/installIncludesTest.h" "// No content\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest/installIncludesTest.h" "/* No content */\n")
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest2")
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest2/installIncludesTest2.h" "// No content\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest2/installIncludesTest2.h" "/* No content */\n")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest3/testLibRequired")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest3/testLibRequired/installIncludesTest3.h" "/* No content */\n")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/testLibRequired/installIncludesTest4")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/testLibRequired/installIncludesTest4/installIncludesTest4.h" "/* No content */\n")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest5")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest5/installIncludesTest5.h" "/* No content */\n")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest6")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest6/installIncludesTest6.h" "/* No content */\n")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest7")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest7/installIncludesTest7.h" "/* No content */\n")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest8")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest8/installIncludesTest8.h" "/* No content */\n")
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest/installIncludesTest.h"
DESTINATION installIncludesTest
@@ -334,6 +427,30 @@ install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest2/installIncludesTest2.h"
DESTINATION installIncludesTest2
)
+install(FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest3/testLibRequired/installIncludesTest3.h"
+ DESTINATION installIncludesTest3/testLibRequired
+)
+install(FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/testLibRequired/installIncludesTest4/installIncludesTest4.h"
+ DESTINATION testLibRequired/installIncludesTest4
+)
+install(FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest5/installIncludesTest5.h"
+ DESTINATION installIncludesTest5
+)
+install(FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest6/installIncludesTest6.h"
+ DESTINATION installIncludesTest6
+)
+install(FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest7/installIncludesTest7.h"
+ DESTINATION installIncludesTest7
+)
+install(FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest8/installIncludesTest8.h"
+ DESTINATION installIncludesTest8
+)
install(TARGETS testLibDepends testSharedLibDepends EXPORT DependsExp DESTINATION lib )
install(EXPORT DependsExp FILE testLibDependsTargets.cmake DESTINATION lib/cmake/testLibDepends)
@@ -361,15 +478,17 @@ install(FILES
# Install and export from install tree.
install(
TARGETS
- testExe1 testLib1 testLib2 testExe2 testLib3 testLib4 testExe3
+ testExe1 testLib1 testLib2 testExe2 testLib3 testLib4 testExe3 testExe4
testExe2lib testLib4lib testLib4libdbg testLib4libopt
- testLib6
+ testLib6 testLib7
testLibCycleA testLibCycleB
+ testLibNoSONAME
cmp0022NEW cmp0022OLD
+ systemlib
EXPORT exp
- RUNTIME DESTINATION bin
- LIBRARY DESTINATION lib NAMELINK_SKIP
- ARCHIVE DESTINATION lib
+ RUNTIME DESTINATION $<1:bin>
+ LIBRARY DESTINATION $<1:lib> NAMELINK_SKIP
+ ARCHIVE DESTINATION $<1:lib>
FRAMEWORK DESTINATION Frameworks
BUNDLE DESTINATION Applications
)
@@ -417,12 +536,32 @@ export(TARGETS testExe1 testLib1 testLib2 testLib3
testSharedLibRequired testSharedLibRequiredUser testSharedLibRequiredUser2
testSharedLibDepends renamed_on_export
cmp0022NEW cmp0022OLD
+ systemlib
NAMESPACE bld_
FILE ExportBuildTree.cmake
)
-export(TARGETS testExe2 testLib4 testLib5 testLib6 testExe3 testExe2lib
+export(TARGETS testExe2 testLib4 testLib5 testLib6 testLib7 testExe3 testExe4 testExe2lib
testLib4lib testLib4libdbg testLib4libopt
testLibCycleA testLibCycleB
+ testLibNoSONAME
+ testLibPerConfigDest
NAMESPACE bld_
APPEND FILE ExportBuildTree.cmake
)
+
+add_subdirectory(Interface)
+
+#-----------------------------------------------------------------------------
+# Install export with absolute destination but relative pieces.
+add_library(testLibAbs1 STATIC testLibAbs1.c)
+target_include_directories(testLibAbs1 INTERFACE
+ "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/abs/1a;include/abs/1b>"
+ )
+install(
+ TARGETS testLibAbs1
+ EXPORT expAbs
+ ARCHIVE DESTINATION lib
+ INCLUDES DESTINATION include/abs
+ )
+install(DIRECTORY $<1:include/abs>$<0:/wrong> DESTINATION $<1:include>$<0:/wrong>)
+install(EXPORT expAbs NAMESPACE expAbs_ DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/expAbs)
diff --git a/Tests/ExportImport/Export/Interface/CMakeLists.txt b/Tests/ExportImport/Export/Interface/CMakeLists.txt
new file mode 100644
index 000000000..fd55c423c
--- /dev/null
+++ b/Tests/ExportImport/Export/Interface/CMakeLists.txt
@@ -0,0 +1,72 @@
+
+add_library(headeronly INTERFACE)
+set_property(TARGET headeronly PROPERTY INTERFACE_INCLUDE_DIRECTORIES
+ "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/headeronly>"
+ "$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include/headeronly>"
+)
+set_property(TARGET headeronly PROPERTY INTERFACE_COMPILE_DEFINITIONS "HEADERONLY_DEFINE")
+
+include(GenerateExportHeader)
+add_library(sharedlib SHARED sharedlib.cpp)
+generate_export_header(sharedlib)
+set_property(TARGET sharedlib PROPERTY INCLUDE_DIRECTORIES
+ "${CMAKE_CURRENT_SOURCE_DIR}/sharedlib"
+ "${CMAKE_CURRENT_BINARY_DIR}"
+)
+set_property(TARGET sharedlib PROPERTY INTERFACE_INCLUDE_DIRECTORIES
+ "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/sharedlib;${CMAKE_CURRENT_BINARY_DIR}>"
+ "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/sharedlib>"
+)
+
+set_property(TARGET sharedlib PROPERTY INTERFACE_COMPILE_DEFINITIONS "SHAREDLIB_DEFINE")
+
+add_library(sharediface INTERFACE)
+target_link_libraries(sharediface INTERFACE sharedlib)
+
+add_library(use_auto_type INTERFACE)
+target_compile_features(use_auto_type INTERFACE cxx_auto_type)
+
+add_library(use_c_restrict INTERFACE)
+target_compile_features(use_c_restrict INTERFACE c_restrict)
+
+add_library(source_target INTERFACE)
+target_sources(source_target INTERFACE
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/source_target.cpp>
+ $<INSTALL_INTERFACE:$<INSTALL_PREFIX>/src/source_target_for_install.cpp>
+)
+install(FILES
+ source_target_for_install.cpp
+ DESTINATION src
+)
+
+add_library(cmakeonly INTERFACE)
+set_property(TARGET cmakeonly PROPERTY INTERFACE_COMPILE_DEFINITIONS [[DEF="\"\$\B"]])
+
+install(TARGETS headeronly sharediface use_auto_type use_c_restrict source_target
+ cmakeonly
+ EXPORT expInterface
+)
+install(TARGETS sharedlib
+ EXPORT expInterface
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION lib NAMELINK_SKIP
+ ARCHIVE DESTINATION lib
+ FRAMEWORK DESTINATION Frameworks
+ BUNDLE DESTINATION Applications
+)
+install(FILES
+ headeronly/headeronly.h
+ DESTINATION include/headeronly
+)
+install(FILES
+ sharedlib/sharedlib.h
+ "${CMAKE_CURRENT_BINARY_DIR}/sharedlib_export.h"
+ DESTINATION include/sharedlib
+)
+
+install(EXPORT expInterface NAMESPACE exp:: DESTINATION lib/exp)
+
+export(EXPORT expInterface
+ NAMESPACE bld::
+ FILE ../ExportInterfaceBuildTree.cmake
+)
diff --git a/Tests/ExportImport/Export/Interface/headeronly/headeronly.h b/Tests/ExportImport/Export/Interface/headeronly/headeronly.h
new file mode 100644
index 000000000..3673c2187
--- /dev/null
+++ b/Tests/ExportImport/Export/Interface/headeronly/headeronly.h
@@ -0,0 +1,7 @@
+
+enum { one };
+
+struct HeaderOnly
+{
+ int foo() const { return 0; }
+};
diff --git a/Tests/ExportImport/Export/Interface/sharedlib.cpp b/Tests/ExportImport/Export/Interface/sharedlib.cpp
new file mode 100644
index 000000000..88ca7130f
--- /dev/null
+++ b/Tests/ExportImport/Export/Interface/sharedlib.cpp
@@ -0,0 +1,7 @@
+
+#include "sharedlib.h"
+
+int SharedLibObject::foo() const
+{
+ return 0;
+}
diff --git a/Tests/ExportImport/Export/Interface/sharedlib/sharedlib.h b/Tests/ExportImport/Export/Interface/sharedlib/sharedlib.h
new file mode 100644
index 000000000..aad9ef3f4
--- /dev/null
+++ b/Tests/ExportImport/Export/Interface/sharedlib/sharedlib.h
@@ -0,0 +1,7 @@
+
+#include "sharedlib_export.h"
+
+struct SHAREDLIB_EXPORT SharedLibObject
+{
+ int foo() const;
+};
diff --git a/Tests/ExportImport/Export/Interface/source_target.cpp b/Tests/ExportImport/Export/Interface/source_target.cpp
new file mode 100644
index 000000000..037191cf6
--- /dev/null
+++ b/Tests/ExportImport/Export/Interface/source_target.cpp
@@ -0,0 +1,13 @@
+
+#ifndef USE_FROM_BUILD_DIR
+#error Expected define USE_FROM_BUILD_DIR
+#endif
+
+#ifdef USE_FROM_INSTALL_DIR
+#error Unexpected define USE_FROM_INSTALL_DIR
+#endif
+
+int source_symbol()
+{
+ return 42;
+}
diff --git a/Tests/ExportImport/Export/Interface/source_target_for_install.cpp b/Tests/ExportImport/Export/Interface/source_target_for_install.cpp
new file mode 100644
index 000000000..64514edb2
--- /dev/null
+++ b/Tests/ExportImport/Export/Interface/source_target_for_install.cpp
@@ -0,0 +1,13 @@
+
+#ifdef USE_FROM_BUILD_DIR
+#error Unexpected define USE_FROM_BUILD_DIR
+#endif
+
+#ifndef USE_FROM_INSTALL_DIR
+#error Expected define USE_FROM_INSTALL_DIR
+#endif
+
+int source_symbol()
+{
+ return 42;
+}
diff --git a/Tests/ExportImport/Export/include/abs/1a/testLibAbs1a.h b/Tests/ExportImport/Export/include/abs/1a/testLibAbs1a.h
new file mode 100644
index 000000000..44212274a
--- /dev/null
+++ b/Tests/ExportImport/Export/include/abs/1a/testLibAbs1a.h
@@ -0,0 +1 @@
+#define testLibAbs1a
diff --git a/Tests/ExportImport/Export/include/abs/1b/testLibAbs1b.h b/Tests/ExportImport/Export/include/abs/1b/testLibAbs1b.h
new file mode 100644
index 000000000..00a2a299f
--- /dev/null
+++ b/Tests/ExportImport/Export/include/abs/1b/testLibAbs1b.h
@@ -0,0 +1 @@
+#define testLibAbs1b
diff --git a/Tests/ExportImport/Export/include/abs/testLibAbs1.h b/Tests/ExportImport/Export/include/abs/testLibAbs1.h
new file mode 100644
index 000000000..19d80a5e5
--- /dev/null
+++ b/Tests/ExportImport/Export/include/abs/testLibAbs1.h
@@ -0,0 +1 @@
+extern int testLibAbs1(void);
diff --git a/Tests/ExportImport/Export/systemlib.cpp b/Tests/ExportImport/Export/systemlib.cpp
new file mode 100644
index 000000000..ec45148f7
--- /dev/null
+++ b/Tests/ExportImport/Export/systemlib.cpp
@@ -0,0 +1,7 @@
+
+#include "systemlib.h"
+
+SystemStruct::SystemStruct()
+{
+
+}
diff --git a/Tests/ExportImport/Export/systemlib.h b/Tests/ExportImport/Export/systemlib.h
new file mode 100644
index 000000000..f7900c098
--- /dev/null
+++ b/Tests/ExportImport/Export/systemlib.h
@@ -0,0 +1,22 @@
+
+#ifndef SYSTEMLIB_H
+#define SYSTEMLIB_H
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+# define systemlib_EXPORT __declspec(dllexport)
+#else
+# define systemlib_EXPORT
+#endif
+
+struct systemlib_EXPORT SystemStruct
+{
+ SystemStruct();
+
+ void someMethod()
+ {
+ int unused;
+ // unused warning not issued when this header is used as a system header.
+ }
+};
+
+#endif
diff --git a/Tests/ExportImport/Export/testExe4.c b/Tests/ExportImport/Export/testExe4.c
new file mode 100644
index 000000000..731057edc
--- /dev/null
+++ b/Tests/ExportImport/Export/testExe4.c
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+int main(int argc, const char* argv[])
+{
+ if(argc < 2)
+ {
+ fprintf(stderr, "Must specify output file.\n");
+ return 1;
+ }
+ {
+ FILE* f = fopen(argv[1], "w");
+ if(f)
+ {
+ fprintf(f, "int generated_by_testExe4() { return 0; }\n");
+ fclose(f);
+ }
+ else
+ {
+ fprintf(stderr, "Error writing to %s\n", argv[1]);
+ return 1;
+ }
+ }
+ return 0;
+}
diff --git a/Tests/ExportImport/Export/testLib1file1.txt b/Tests/ExportImport/Export/testLib1file1.txt
new file mode 100644
index 000000000..73601df59
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib1file1.txt
@@ -0,0 +1 @@
+testLib1file1
diff --git a/Tests/ExportImport/Export/testLib1file2.txt b/Tests/ExportImport/Export/testLib1file2.txt
new file mode 100644
index 000000000..4874ed109
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib1file2.txt
@@ -0,0 +1 @@
+testLib1file2
diff --git a/Tests/ExportImport/Export/testLib7.c b/Tests/ExportImport/Export/testLib7.c
new file mode 100644
index 000000000..7acae9eb1
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib7.c
@@ -0,0 +1 @@
+int testLib7(void) { return 0; }
diff --git a/Tests/ExportImport/Export/testLibAbs1.c b/Tests/ExportImport/Export/testLibAbs1.c
new file mode 100644
index 000000000..34aec7573
--- /dev/null
+++ b/Tests/ExportImport/Export/testLibAbs1.c
@@ -0,0 +1 @@
+int testLibAbs1(void) { return 0; }
diff --git a/Tests/ExportImport/Export/testLibDepends.c b/Tests/ExportImport/Export/testLibDepends.c
index fb5a002e0..3c7774eed 100644
--- a/Tests/ExportImport/Export/testLibDepends.c
+++ b/Tests/ExportImport/Export/testLibDepends.c
@@ -16,5 +16,10 @@
#endif
extern int testLibRequired(void);
+extern int testStaticLibRequiredPrivate(void);
-int testLibDepends(void) { return testLibRequired(); }
+int testLibDepends(void) {
+ return testLibRequired()
+ + testStaticLibRequiredPrivate()
+ ;
+}
diff --git a/Tests/ExportImport/Export/testLibNoSONAME.c b/Tests/ExportImport/Export/testLibNoSONAME.c
new file mode 100644
index 000000000..2193e1f53
--- /dev/null
+++ b/Tests/ExportImport/Export/testLibNoSONAME.c
@@ -0,0 +1,7 @@
+#if defined(_WIN32) || defined(__CYGWIN__)
+# define testLibNoSONAME_EXPORT __declspec(dllexport)
+#else
+# define testLibNoSONAME_EXPORT
+#endif
+
+testLibNoSONAME_EXPORT int testLibNoSONAME(void) { return 0; }
diff --git a/Tests/ExportImport/Export/testLibPerConfigDest.c b/Tests/ExportImport/Export/testLibPerConfigDest.c
new file mode 100644
index 000000000..c7113fc15
--- /dev/null
+++ b/Tests/ExportImport/Export/testLibPerConfigDest.c
@@ -0,0 +1 @@
+int testLibPerConfigDest(void) { return 0; }
diff --git a/Tests/ExportImport/Export/testStaticLibRequiredPrivate.c b/Tests/ExportImport/Export/testStaticLibRequiredPrivate.c
new file mode 100644
index 000000000..28a2675ff
--- /dev/null
+++ b/Tests/ExportImport/Export/testStaticLibRequiredPrivate.c
@@ -0,0 +1 @@
+int testStaticLibRequiredPrivate(void) { return 0; }
diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt
index 2627354ac..5ce962861 100644
--- a/Tests/ExportImport/Import/A/CMakeLists.txt
+++ b/Tests/ExportImport/Import/A/CMakeLists.txt
@@ -19,11 +19,17 @@ add_custom_command(
COMMAND exp_testExe3 ${Import_BINARY_DIR}/exp_generated3.c
DEPENDS exp_testExe3
)
+add_custom_command(
+ OUTPUT ${Import_BINARY_DIR}/exp_generated4.c
+ COMMAND exp_testExe4 ${Import_BINARY_DIR}/exp_generated4.c
+ DEPENDS exp_testExe4
+ )
add_executable(imp_testExe1
imp_testExe1.c
${Import_BINARY_DIR}/exp_generated.c
${Import_BINARY_DIR}/exp_generated3.c
+ ${Import_BINARY_DIR}/exp_generated4.c
)
# Try linking to a library imported from the install tree.
@@ -33,7 +39,9 @@ target_link_libraries(imp_testExe1
exp_testLib4
exp_testLib5
exp_testLib6
+ exp_testLib7
exp_testLibCycleA
+ exp_testLibPerConfigDest
)
# Try building a plugin to an executable imported from the install tree.
@@ -51,11 +59,17 @@ add_custom_command(
COMMAND bld_testExe3 ${Import_BINARY_DIR}/bld_generated3.c
DEPENDS bld_testExe3
)
+add_custom_command(
+ OUTPUT ${Import_BINARY_DIR}/bld_generated4.c
+ COMMAND bld_testExe4 ${Import_BINARY_DIR}/bld_generated4.c
+ DEPENDS bld_testExe4
+ )
add_executable(imp_testExe1b
imp_testExe1.c
${Import_BINARY_DIR}/bld_generated.c
${Import_BINARY_DIR}/bld_generated3.c
+ ${Import_BINARY_DIR}/bld_generated4.c
)
# Try linking to a library imported from the build tree.
@@ -65,9 +79,61 @@ target_link_libraries(imp_testExe1b
bld_testLib4
bld_testLib5
bld_testLib6
+ bld_testLib7
bld_testLibCycleA
+ bld_testLibPerConfigDest
)
+add_custom_target(check_testLib1_genex ALL
+ COMMAND ${CMAKE_COMMAND} -DtestLib1=$<TARGET_FILE:exp_testLib1>
+ -Dprefix=${CMAKE_INSTALL_PREFIX}
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/check_testLib1_genex.cmake
+ )
+
+if(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG AND
+ "${CMAKE_C_CREATE_SHARED_MODULE}" MATCHES "SONAME_FLAG")
+ foreach(ns exp bld)
+ get_property(configs TARGET ${ns}_testLib5 PROPERTY IMPORTED_CONFIGURATIONS)
+ foreach(c ${configs})
+ string(TOUPPER "${c}" CONFIG)
+ get_property(soname TARGET ${ns}_testLib5 PROPERTY IMPORTED_NO_SONAME_${CONFIG})
+ if(soname)
+ message(SEND_ERROR "${ns}_testLib5 has IMPORTED_NO_SONAME_${CONFIG} but should:\n ${soname}")
+ else()
+ message(STATUS "${ns}_testLib5 does not have IMPORTED_NO_SONAME_${CONFIG} as expected")
+ endif()
+ endforeach()
+
+ get_property(configs TARGET ${ns}_testLibNoSONAME PROPERTY IMPORTED_CONFIGURATIONS)
+ foreach(c ${configs})
+ string(TOUPPER "${c}" CONFIG)
+ get_property(soname TARGET ${ns}_testLibNoSONAME PROPERTY IMPORTED_NO_SONAME_${CONFIG})
+ if(soname)
+ message(STATUS "${ns}_testLibNoSONAME has IMPORTED_NO_SONAME_${CONFIG} as expected")
+ else()
+ message(SEND_ERROR "${ns}_testLibNoSONAME does not have IMPORTED_NO_SONAME_${CONFIG} but should")
+ endif()
+ endforeach()
+
+ # Parse the binary to check for SONAME if possible.
+ if("${CMAKE_EXECUTABLE_FORMAT}" MATCHES "ELF")
+ find_program(READELF_EXE readelf)
+ if(READELF_EXE)
+ add_custom_target(check_${ns}_testLib5_soname ALL COMMAND
+ ${CMAKE_COMMAND} -Dreadelf=${READELF_EXE}
+ -Dlib=$<TARGET_FILE:${ns}_testLib5>
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/check_lib_soname.cmake
+ )
+ add_custom_target(check_${ns}_testLibNoSONAME_soname ALL COMMAND
+ ${CMAKE_COMMAND} -Dreadelf=${READELF_EXE}
+ -Dlib=$<TARGET_FILE:${ns}_testLibNoSONAME>
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/check_lib_nosoname.cmake
+ )
+ endif()
+ endif()
+ endforeach()
+endif()
+
add_executable(cmp0022OLD_test cmp0022OLD_test_vs6_1.cpp)
target_link_libraries(cmp0022OLD_test bld_cmp0022OLD)
add_executable(cmp0022NEW_test cmp0022NEW_test_vs6_1.cpp)
@@ -90,6 +156,16 @@ foreach(c DEBUG RELWITHDEBINFO)
endforeach()
#-----------------------------------------------------------------------------
+include(${CMAKE_INSTALL_PREFIX}/lib/expAbs/expAbs.cmake)
+
+add_executable(imp_testExeAbs1
+ imp_testExeAbs1.c
+ )
+target_link_libraries(imp_testExeAbs1
+ expAbs_testLibAbs1
+ )
+
+#-----------------------------------------------------------------------------
# Create a custom target to generate a header for the libraries below.
# Drive the header generation through an indirect chain of imported
# target dependencies.
@@ -237,6 +313,7 @@ add_subdirectory(excludedFromAll)
add_executable(iface_test_bld iface_test.cpp)
target_link_libraries(iface_test_bld bld_testSharedLibDepends)
+set_property(TARGET iface_test_bld PROPERTY NO_SYSTEM_FROM_IMPORTED 1)
set_property(TARGET bld_testSharedLibRequired APPEND PROPERTY
LINK_INTERFACE_LIBRARIES
@@ -265,3 +342,80 @@ foreach(_config ${_configs})
)
endforeach()
unset(_configs)
+
+if (((CMAKE_C_COMPILER_ID STREQUAL GNU AND CMAKE_C_COMPILER_VERSION VERSION_GREATER 4.4)
+ OR CMAKE_C_COMPILER_ID STREQUAL Clang)
+ AND (CMAKE_GENERATOR STREQUAL "Unix Makefiles" OR CMAKE_GENERATOR STREQUAL "Ninja"))
+ include(CheckCXXCompilerFlag)
+ check_cxx_compiler_flag(-Wunused-variable run_sys_includes_test)
+ if(run_sys_includes_test)
+ # The Bullseye wrapper appears to break the -isystem effect.
+ execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version OUTPUT_VARIABLE out ERROR_VARIABLE out)
+ if("x${out}" MATCHES "Bullseye")
+ set(run_sys_includes_test 0)
+ endif()
+ endif()
+ if (run_sys_includes_test)
+ add_executable(test_system_exp test_system.cpp)
+ target_link_libraries(test_system_exp exp_systemlib)
+ target_compile_options(test_system_exp PRIVATE -Wunused-variable -Werror=unused-variable)
+
+ unset(EXP_ERROR_VARIABLE CACHE)
+ try_compile(EXP_ERROR_VARIABLE
+ "${CMAKE_CURRENT_SOURCE_DIR}/test_system"
+ "${CMAKE_CURRENT_SOURCE_DIR}/test_system.cpp"
+ COMPILE_DEFINITIONS "-Wunused-variable -Werror=unused-variable"
+ LINK_LIBRARIES exp_systemlib
+ OUTPUT_VARIABLE OUTPUT
+ )
+ if(NOT EXP_ERROR_VARIABLE)
+ message(SEND_ERROR "EXP_ERROR_VARIABLE try_compile failed, but it was expected to succeed ${OUTPUT}.")
+ endif()
+
+ if(NOT CMAKE_CROSSCOMPILING)
+ unset(EXP_RUN_VAR CACHE)
+ unset(EXP_COMPILE_VAR CACHE)
+ try_run(EXP_RUN_VAR EXP_COMPILE_VAR
+ "${CMAKE_CURRENT_SOURCE_DIR}/test_system"
+ "${CMAKE_CURRENT_SOURCE_DIR}/test_system.cpp"
+ COMPILE_DEFINITIONS "-Wunused-variable -Werror=unused-variable"
+ LINK_LIBRARIES exp_systemlib
+ OUTPUT_VARIABLE OUTPUT
+ )
+ if(NOT EXP_COMPILE_VAR)
+ message(SEND_ERROR "try_run compile failed, but it was expected to succeed ${OUTPUT}.")
+ endif()
+ endif()
+
+ add_executable(test_system_bld test_system.cpp)
+ target_link_libraries(test_system_bld bld_systemlib)
+ target_compile_options(test_system_bld PRIVATE -Wunused-variable -Werror=unused-variable)
+
+ unset(BLD_ERROR_VARIABLE CACHE)
+ try_compile(BLD_ERROR_VARIABLE
+ "${CMAKE_CURRENT_SOURCE_DIR}/test_system"
+ "${CMAKE_CURRENT_SOURCE_DIR}/test_system.cpp"
+ COMPILE_DEFINITIONS "-Wunused-variable -Werror=unused-variable"
+ LINK_LIBRARIES bld_systemlib
+ OUTPUT_VARIABLE OUTPUT
+ )
+ if(NOT BLD_ERROR_VARIABLE)
+ message(SEND_ERROR "BLD_ERROR_VARIABLE try_compile failed, but it was expected to succeed.")
+ endif()
+
+ if(NOT CMAKE_CROSSCOMPILING)
+ unset(BLD_RUN_VAR CACHE)
+ unset(BLD_COMPILE_VAR CACHE)
+ try_run(BLD_RUN_VAR BLD_COMPILE_VAR
+ "${CMAKE_CURRENT_SOURCE_DIR}/test_system"
+ "${CMAKE_CURRENT_SOURCE_DIR}/test_system.cpp"
+ COMPILE_DEFINITIONS "-Wunused-variable -Werror=unused-variable"
+ LINK_LIBRARIES bld_systemlib
+ OUTPUT_VARIABLE OUTPUT
+ )
+ if(NOT BLD_COMPILE_VAR)
+ message(SEND_ERROR "try_run compile failed, but it was expected to succeed ${OUTPUT}.")
+ endif()
+ endif()
+ endif()
+endif()
diff --git a/Tests/ExportImport/Import/A/check_lib_nosoname.cmake b/Tests/ExportImport/Import/A/check_lib_nosoname.cmake
new file mode 100644
index 000000000..613391e82
--- /dev/null
+++ b/Tests/ExportImport/Import/A/check_lib_nosoname.cmake
@@ -0,0 +1,7 @@
+execute_process(COMMAND ${readelf} -d ${lib} OUTPUT_FILE ${lib}.readelf.txt)
+file(STRINGS ${lib}.readelf.txt soname REGEX "SONAME")
+if(soname)
+ message(FATAL_ERROR "${lib} has soname but should not:\n ${soname}")
+else()
+ message(STATUS "${lib} has no soname as expected:\n ${soname}")
+endif()
diff --git a/Tests/ExportImport/Import/A/check_lib_soname.cmake b/Tests/ExportImport/Import/A/check_lib_soname.cmake
new file mode 100644
index 000000000..a3c4b54be
--- /dev/null
+++ b/Tests/ExportImport/Import/A/check_lib_soname.cmake
@@ -0,0 +1,7 @@
+execute_process(COMMAND ${readelf} -d ${lib} OUTPUT_FILE ${lib}.readelf.txt)
+file(STRINGS ${lib}.readelf.txt soname REGEX "SONAME")
+if(soname)
+ message(STATUS "${lib} has soname as expected:\n ${soname}")
+else()
+ message(FATAL_ERROR "${lib} has no soname but should:\n ${soname}")
+endif()
diff --git a/Tests/ExportImport/Import/A/check_testLib1_genex.cmake b/Tests/ExportImport/Import/A/check_testLib1_genex.cmake
new file mode 100644
index 000000000..7c0265248
--- /dev/null
+++ b/Tests/ExportImport/Import/A/check_testLib1_genex.cmake
@@ -0,0 +1,11 @@
+foreach(f
+ "${testLib1}.genex"
+ "${prefix}/doc/testLib1file1.txt"
+ "${prefix}/doc/testLib1file2.txt"
+ )
+ if(EXISTS "${f}")
+ message(STATUS "'${f}' exists!")
+ else()
+ message(FATAL_ERROR "Missing file:\n ${f}")
+ endif()
+endforeach()
diff --git a/Tests/ExportImport/Import/A/deps_iface.c b/Tests/ExportImport/Import/A/deps_iface.c
index 48a4c44d6..953d0ad85 100644
--- a/Tests/ExportImport/Import/A/deps_iface.c
+++ b/Tests/ExportImport/Import/A/deps_iface.c
@@ -6,6 +6,12 @@
#include "installIncludesTest.h"
#include "installIncludesTest2.h"
+#include "installIncludesTest3.h"
+#include "installIncludesTest4.h"
+#include "installIncludesTest5.h"
+#include "installIncludesTest6.h"
+#include "installIncludesTest7.h"
+#include "installIncludesTest8.h"
#ifndef testLibRequired_IFACE_DEFINE
#error Expected testLibRequired_IFACE_DEFINE
diff --git a/Tests/ExportImport/Import/A/imp_testExe1.c b/Tests/ExportImport/Import/A/imp_testExe1.c
index 451998ab7..0a74309a3 100644
--- a/Tests/ExportImport/Import/A/imp_testExe1.c
+++ b/Tests/ExportImport/Import/A/imp_testExe1.c
@@ -1,12 +1,15 @@
extern int generated_by_testExe1();
extern int generated_by_testExe3();
+extern int generated_by_testExe4();
extern int testLib2();
extern int testLib3();
extern int testLib4();
extern int testLib4lib();
extern int testLib5();
extern int testLib6();
+extern int testLib7();
extern int testLibCycleA1();
+extern int testLibPerConfigDest();
/* Switch a symbol between debug and optimized builds to make sure the
proper library is found from the testLib4 link interface. */
@@ -20,6 +23,7 @@ extern testLib4libcfg(void);
int main()
{
return (testLib2() + generated_by_testExe1() + testLib3() + testLib4()
- + testLib5() + testLib6() + testLibCycleA1()
- + generated_by_testExe3() + testLib4lib() + testLib4libcfg());
+ + testLib5() + testLib6() + testLib7() + testLibCycleA1()
+ + testLibPerConfigDest()
+ + generated_by_testExe3() + generated_by_testExe4() + testLib4lib() + testLib4libcfg());
}
diff --git a/Tests/ExportImport/Import/A/imp_testExeAbs1.c b/Tests/ExportImport/Import/A/imp_testExeAbs1.c
new file mode 100644
index 000000000..069c3f076
--- /dev/null
+++ b/Tests/ExportImport/Import/A/imp_testExeAbs1.c
@@ -0,0 +1,15 @@
+#include "testLibAbs1.h"
+#include "testLibAbs1a.h"
+#include "testLibAbs1b.h"
+#ifndef testLibAbs1a
+# error "testLibAbs1a not defined"
+#endif
+#ifndef testLibAbs1b
+# error "testLibAbs1b not defined"
+#endif
+int main()
+{
+ return 0
+ + testLibAbs1()
+ ;
+}
diff --git a/Tests/ExportImport/Import/A/test_system.cpp b/Tests/ExportImport/Import/A/test_system.cpp
new file mode 100644
index 000000000..aae358333
--- /dev/null
+++ b/Tests/ExportImport/Import/A/test_system.cpp
@@ -0,0 +1,9 @@
+
+#include "systemlib.h"
+
+int main()
+{
+ SystemStruct s;
+ (void)s;
+ return 0;
+}
diff --git a/Tests/ExportImport/Import/CMakeLists.txt b/Tests/ExportImport/Import/CMakeLists.txt
index 9c2d5977c..189f7a2bc 100644
--- a/Tests/ExportImport/Import/CMakeLists.txt
+++ b/Tests/ExportImport/Import/CMakeLists.txt
@@ -1,4 +1,5 @@
cmake_minimum_required (VERSION 2.7.20090711)
+cmake_policy(SET CMP0025 NEW)
project(Import C CXX)
# Import everything in a subdirectory.
@@ -19,3 +20,6 @@ add_executable(imp_testTransExe1b imp_testTransExe1.c)
target_link_libraries(imp_testTransExe1b imp_lib1b)
add_subdirectory(try_compile)
+
+# Test package INTERFACE controls
+add_subdirectory(Interface)
diff --git a/Tests/ExportImport/Import/Interface/CMakeLists.txt b/Tests/ExportImport/Import/Interface/CMakeLists.txt
new file mode 100644
index 000000000..c850508e5
--- /dev/null
+++ b/Tests/ExportImport/Import/Interface/CMakeLists.txt
@@ -0,0 +1,112 @@
+
+# Import targets from the exported build tree.
+include(${Import_BINARY_DIR}/../Export/ExportInterfaceBuildTree.cmake)
+
+# Import targets from the exported install tree.
+include(${CMAKE_INSTALL_PREFIX}/lib/exp/expInterface.cmake)
+
+add_library(define_iface INTERFACE)
+set_property(TARGET define_iface PROPERTY
+ INTERFACE_COMPILE_DEFINITIONS DEFINE_IFACE_DEFINE)
+
+add_executable(headeronlytest_bld headeronlytest.cpp)
+target_link_libraries(headeronlytest_bld bld::headeronly)
+
+set_property(TARGET bld::sharediface APPEND PROPERTY INTERFACE_LINK_LIBRARIES define_iface)
+
+add_executable(interfacetest_bld interfacetest.cpp)
+target_link_libraries(interfacetest_bld bld::sharediface)
+
+include(CheckCSourceCompiles)
+include(CheckCXXSourceCompiles)
+
+macro(do_try_compile prefix)
+
+ set(CMAKE_REQUIRED_LIBRARIES ${prefix}::headeronly)
+ check_cxx_source_compiles(
+ "
+ #include \"headeronly.h\"
+
+ #ifndef HEADERONLY_DEFINE
+ #error Expected HEADERONLY_DEFINE
+ #endif
+
+ int main(int,char**)
+ {
+ HeaderOnly ho;
+ return ho.foo();
+ }
+ " ${prefix}IFACE_TRY_COMPILE)
+
+ if(NOT ${prefix}IFACE_TRY_COMPILE)
+ message(SEND_ERROR "${prefix} try_compile with IMPORTED INTERFACE target failed!\n\n${OUTPUT}")
+ endif()
+
+ if (";${CMAKE_C_COMPILE_FEATURES};" MATCHES ";c_restrict;")
+ set(CMAKE_REQUIRED_LIBRARIES ${prefix}::use_c_restrict)
+ check_c_source_compiles(
+ "
+ int foo(int * restrict a, int * restrict b)
+ {
+ (void)a;
+ (void)b;
+ return 0;
+ }
+ int main()
+ {
+ return 0;
+ }
+ " ${prefix}IMPORTED_IFACE_C_RESTRICT)
+
+ if(NOT ${prefix}IMPORTED_IFACE_C_RESTRICT)
+ message(SEND_ERROR "${prefix} try_compile with IMPORTED INTERFACE target failed!\n\n${OUTPUT}")
+ endif()
+ endif()
+ if (";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";cxx_auto_type;")
+ set(CMAKE_REQUIRED_LIBRARIES ${prefix}::use_auto_type)
+ check_cxx_source_compiles(
+ "
+ int main(int,char**)
+ {
+ auto value = 0;
+ return value;
+ }
+ " ${prefix}IMPORTED_IFACE_AUTO_TYPE)
+
+ if(NOT ${prefix}IMPORTED_IFACE_AUTO_TYPE)
+ message(SEND_ERROR "${prefix} try_compile with IMPORTED INTERFACE target failed!\n\n${OUTPUT}")
+ endif()
+ endif()
+
+endmacro()
+
+do_try_compile(bld)
+
+add_executable(source_target_test_bld source_target_test.cpp)
+target_link_libraries(source_target_test_bld bld::source_target)
+target_compile_definitions(source_target_test_bld PRIVATE USE_FROM_BUILD_DIR)
+
+add_executable(source_target_test_exp source_target_test.cpp)
+target_link_libraries(source_target_test_exp exp::source_target)
+target_compile_definitions(source_target_test_exp PRIVATE USE_FROM_INSTALL_DIR)
+
+add_executable(headeronlytest_exp headeronlytest.cpp)
+target_link_libraries(headeronlytest_exp exp::headeronly)
+
+set_property(TARGET exp::sharediface APPEND PROPERTY INTERFACE_LINK_LIBRARIES define_iface)
+
+add_executable(interfacetest_exp interfacetest.cpp)
+target_link_libraries(interfacetest_exp exp::sharediface)
+
+do_try_compile(exp)
+
+foreach(ns exp bld)
+ get_property(defs TARGET ${ns}::cmakeonly PROPERTY INTERFACE_COMPILE_DEFINITIONS)
+ if(NOT defs STREQUAL [[DEF="\"\$\B"]])
+ message(SEND_ERROR
+ "${ns}::cmakeonly property INTERFACE_COMPILE_DEFINITIONS is:\n"
+ " ${defs}\n"
+ "not\n"
+ " " [[DEF="\"\$\B"]] "\n")
+ endif()
+endforeach()
diff --git a/Tests/ExportImport/Import/Interface/headeronlytest.cpp b/Tests/ExportImport/Import/Interface/headeronlytest.cpp
new file mode 100644
index 000000000..20674a725
--- /dev/null
+++ b/Tests/ExportImport/Import/Interface/headeronlytest.cpp
@@ -0,0 +1,17 @@
+
+#include "headeronly.h"
+
+#ifndef HEADERONLY_DEFINE
+#error Expected HEADERONLY_DEFINE
+#endif
+
+#ifdef SHAREDLIB_DEFINE
+#error Unexpected SHAREDLIB_DEFINE
+#endif
+
+
+int main(int,char**)
+{
+ HeaderOnly ho;
+ return ho.foo();
+}
diff --git a/Tests/ExportImport/Import/Interface/interfacetest.cpp b/Tests/ExportImport/Import/Interface/interfacetest.cpp
new file mode 100644
index 000000000..786458d19
--- /dev/null
+++ b/Tests/ExportImport/Import/Interface/interfacetest.cpp
@@ -0,0 +1,20 @@
+
+#include "sharedlib.h"
+
+#ifndef SHAREDLIB_DEFINE
+#error Expected SHAREDLIB_DEFINE
+#endif
+
+#ifdef HEADERONLY_DEFINE
+#error Unexpected HEADERONLY_DEFINE
+#endif
+
+#ifndef DEFINE_IFACE_DEFINE
+#error Expected DEFINE_IFACE_DEFINE
+#endif
+
+int main(int,char**)
+{
+ SharedLibObject slo;
+ return slo.foo();
+}
diff --git a/Tests/ExportImport/Import/Interface/source_target_test.cpp b/Tests/ExportImport/Import/Interface/source_target_test.cpp
new file mode 100644
index 000000000..0e8ec5f87
--- /dev/null
+++ b/Tests/ExportImport/Import/Interface/source_target_test.cpp
@@ -0,0 +1,7 @@
+
+extern int source_symbol();
+
+int main()
+{
+ return source_symbol() - 42;
+}
diff --git a/Tests/ExportImport/InitialCache.cmake.in b/Tests/ExportImport/InitialCache.cmake.in
index 98d355f8f..f600d90e7 100644
--- a/Tests/ExportImport/InitialCache.cmake.in
+++ b/Tests/ExportImport/InitialCache.cmake.in
@@ -1,3 +1,4 @@
+set(CMAKE_MAKE_PROGRAM "@CMake_TEST_NESTED_MAKE_PROGRAM@" CACHE FILEPATH "Make Program")
set(CMAKE_C_COMPILER "@CMAKE_C_COMPILER@" CACHE STRING "C Compiler")
set(CMAKE_C_FLAGS "@CMAKE_C_FLAGS@" CACHE STRING "C Flags")
set(CMAKE_C_FLAGS_DEBUG "@CMAKE_C_FLAGS_DEBUG@" CACHE STRING "C Flags")
diff --git a/Tests/ExternalProject/CMakeLists.txt b/Tests/ExternalProject/CMakeLists.txt
index 602ff0f65..b5041c7f8 100644
--- a/Tests/ExternalProject/CMakeLists.txt
+++ b/Tests/ExternalProject/CMakeLists.txt
@@ -3,6 +3,8 @@ project(ExternalProjectTest NONE)
include(ExternalProject)
+# Test ExternalProject, especially with checkouts from VCS
+
find_package(CVS)
find_package(Subversion)
find_package(Git)
@@ -23,33 +25,6 @@ set(binary_base "${base}/Build")
set_property(DIRECTORY PROPERTY EP_BASE ${base})
set_property(DIRECTORY PROPERTY EP_STEP_TARGETS configure build test)
-if(NOT DEFINED can_build_tutorial_step5)
- set(can_build_tutorial_step5 1)
-
- # Tutorial Step5 cannot build correctly using Visual Studio 6
- # on Windows 98 if the path of its build tree exceeds 72
- # characters in length... So don't attempt to build it
- # in a long path on Win98:
- #
- if(CMAKE_SYSTEM STREQUAL "Windows-4.10")
- string(LENGTH "${binary_base}/TutorialStep5-Local" n)
- if(n GREATER 72)
- set(can_build_tutorial_step5 0)
- endif()
- endif()
-
- # The ExternalProject builds of Tutorial Step5 cannot be built
- # correctly 2nd and later times in an in-source build...
- # (because the CMakeCache.txt from the real in-source build of
- # the Tests/Tutorial/Step5 directory gets copied when we do
- # the "source directory copy" step... but it still refers to
- # its original path which yields a configure error.) So:
- #
- if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
- set(can_build_tutorial_step5 0)
- endif()
-endif()
-
add_custom_target(NonExternalProjectTarget
COMMAND ${CMAKE_COMMAND} -E echo NonExternalProjectTarget)
@@ -98,6 +73,7 @@ ExternalProject_Add(${proj}
CVS_TAG ""
DEPENDS "MinimalNoOpProject" NonExternalProjectTarget
DOWNLOAD_COMMAND ""
+ DOWNLOAD_NO_PROGRESS 1
INSTALL_COMMAND ""
PATCH_COMMAND ""
STEP_TARGETS install update
@@ -115,142 +91,6 @@ ExternalProject_Add(${proj}
set_property(TARGET ${proj} PROPERTY FOLDER "")
-# Local DIR:
-#
-if(can_build_tutorial_step5)
- set(proj TutorialStep5-Local)
- ExternalProject_Add(${proj}
- URL "${CMAKE_CURRENT_SOURCE_DIR}/../Tutorial/Step5"
- CMAKE_CACHE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
- CMAKE_ARGS -G ${CMAKE_GENERATOR} <SOURCE_DIR>
- TEST_BEFORE_INSTALL 1
- LOG_INSTALL 1
- )
- set_property(TARGET ${proj} PROPERTY FOLDER "Local")
- ExternalProject_Get_Property(${proj} install_dir)
- set(TutorialStep5_install_dir ${install_dir})
-
- set(proj TutorialStep5-Local-TestAfterInstall)
- ExternalProject_Add(${proj}
- URL "${CMAKE_CURRENT_SOURCE_DIR}/../Tutorial/Step5"
- CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -G ${CMAKE_GENERATOR} <SOURCE_DIR>
- TEST_AFTER_INSTALL 1
- LOG_TEST 1
- )
- set_property(TARGET ${proj} PROPERTY FOLDER "Local")
-endif()
-
-
-# Local TAR:
-#
-set(proj TutorialStep1-LocalTAR)
-ExternalProject_Add(${proj}
- URL "${CMAKE_CURRENT_SOURCE_DIR}/Step1.tar"
- URL_MD5 a87c5b47c0201c09ddfe1d5738fdb1e3
- LIST_SEPARATOR ::
- PATCH_COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/Step1Patch.cmake
- CMAKE_GENERATOR "${CMAKE_GENERATOR}"
- CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
- -DTEST_LIST:STRING=A::B::C
- INSTALL_COMMAND ""
- LOG_CONFIGURE 1
-)
-set_property(TARGET ${proj} PROPERTY FOLDER "Local/TAR")
-
-set(proj TutorialStep1-LocalNoDirTAR)
-ExternalProject_Add(${proj}
- URL "${CMAKE_CURRENT_SOURCE_DIR}/Step1NoDir.tar"
- URL_MD5 d09e3d370c5c908fa035c30939ee438e
- LIST_SEPARATOR @@
- CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -G ${CMAKE_GENERATOR} <SOURCE_DIR>
- -DTEST_LIST:STRING=1@@2@@3
- INSTALL_COMMAND ""
-)
-set_property(TARGET ${proj} PROPERTY FOLDER "Local/TAR")
-ExternalProject_Add_Step(${proj} mypatch
- COMMAND ${CMAKE_COMMAND} -E echo "This is a custom external project step."
- COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/Step1Patch.cmake
- WORKING_DIRECTORY <SOURCE_DIR>
- DEPENDEES download
- DEPENDERS configure
- )
-
-
-# Local TGZ:
-#
-set(proj TutorialStep1-LocalTGZ)
-ExternalProject_Add(${proj}
- URL "${CMAKE_CURRENT_SOURCE_DIR}/Step1.tgz"
- URL_MD5 38c648e817339c356f6be00eeed79bd0
- CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -G ${CMAKE_GENERATOR} <SOURCE_DIR>
- INSTALL_COMMAND ""
- LOG_BUILD 1
-)
-set_property(TARGET ${proj} PROPERTY FOLDER "Local/TGZ")
-
-set(proj TutorialStep1-LocalNoDirTGZ)
-ExternalProject_Add(${proj}
- URL "${CMAKE_CURRENT_SOURCE_DIR}/Step1NoDir.tgz"
- URL_HASH SHA256=496229e2a5ed620a37c385ad9406004a18026beab8b55dd2c4565d4b7f1d5383
- CMAKE_GENERATOR "${CMAKE_GENERATOR}"
- CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
- INSTALL_COMMAND ""
-)
-set_property(TARGET ${proj} PROPERTY FOLDER "Local/TGZ")
-
-
-# Local BZ2:
-#
-# (The bz2 tests are here just to verify that the bz2 decompression is executed
-# during a test suite run... The configure and build commands are set to
-# nothing to make the test quicker. To make this more complete, I should add
-# a diff between this and the TGZ source tree since that one does build...)
-#
-set(proj TutorialStep1-LocalBZ2)
-ExternalProject_Add(${proj}
- URL "${CMAKE_CURRENT_SOURCE_DIR}/Step1.tar.bz2"
- CONFIGURE_COMMAND ""
- BUILD_COMMAND ""
- INSTALL_COMMAND ""
-)
-set_property(TARGET ${proj} PROPERTY FOLDER "Local/BZ2")
-
-set(proj TutorialStep1-LocalNoDirBZ2)
-ExternalProject_Add(${proj}
- URL "${CMAKE_CURRENT_SOURCE_DIR}/Step1NoDir.tar.bz2"
- CONFIGURE_COMMAND ""
- BUILD_COMMAND ""
- INSTALL_COMMAND ""
-)
-set_property(TARGET ${proj} PROPERTY FOLDER "Local/BZ2")
-
-
-# Local ZIP:
-#
-# (The zip tests are here just to verify that the zip decompression is executed
-# during a test suite run... The configure and build commands are set to
-# nothing to make the test quicker. To make this more complete, I should add
-# a diff between this and the TGZ source tree since that one does build...)
-#
-set(proj TutorialStep1-LocalZIP)
-ExternalProject_Add(${proj}
- URL "${CMAKE_CURRENT_SOURCE_DIR}/Step1.zip"
- CONFIGURE_COMMAND ""
- BUILD_COMMAND ""
- INSTALL_COMMAND ""
-)
-set_property(TARGET ${proj} PROPERTY FOLDER "Local/ZIP")
-
-set(proj TutorialStep1-LocalNoDirZIP)
-ExternalProject_Add(${proj}
- URL "${CMAKE_CURRENT_SOURCE_DIR}/Step1NoDir.zip"
- CONFIGURE_COMMAND ""
- BUILD_COMMAND ""
- INSTALL_COMMAND ""
-)
-set_property(TARGET ${proj} PROPERTY FOLDER "Local/ZIP")
-
-
# CVS-based tests:
#
set(do_cvs_tests 0)
@@ -336,10 +176,6 @@ if(do_cvs_tests)
INSTALL_COMMAND ""
DEPENDS "SetupLocalCVSRepository"
DEPENDS "EmptyNoOpProject"
- DEPENDS "TutorialStep1-LocalTAR"
- DEPENDS "TutorialStep1-LocalNoDirTAR"
- DEPENDS "TutorialStep1-LocalTGZ"
- DEPENDS "TutorialStep1-LocalNoDirTGZ"
DEPENDS "TutorialStep1-CVS-20090626"
DEPENDS "TutorialStep1-CVS-testtag1"
)
@@ -512,6 +348,82 @@ if(do_git_tests)
LOG_UPDATE 1
)
set_property(TARGET ${proj} PROPERTY FOLDER "GIT")
+
+ # git by explicit branch/tag with empty submodule list
+ #
+ set(proj TutorialStep1-GIT-bytag-withsubmodules)
+ ExternalProject_Add(${proj}
+ GIT_REPOSITORY "${local_git_repo}"
+ GIT_TAG "origin/master"
+ GIT_SUBMODULES ""
+ UPDATE_COMMAND ""
+ CMAKE_GENERATOR "${CMAKE_GENERATOR}"
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+ INSTALL_COMMAND ""
+ DEPENDS "SetupLocalGITRepository"
+ )
+ set_property(TARGET ${proj} PROPERTY FOLDER "GIT")
+
+ # Unzip/untar the git repository in our source folder so that other
+ # projects below may use it to test git args of ExternalProject_Add
+ #
+ set(proj SetupLocalGITRepositoryWithSubmodules)
+ ExternalProject_Add(${proj}
+ SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/LocalRepositories/GIT-with-submodules
+ URL ${CMAKE_CURRENT_SOURCE_DIR}/gitrepo-sub.tgz
+ BUILD_COMMAND ""
+ CONFIGURE_COMMAND "${GIT_EXECUTABLE}" --version
+ INSTALL_COMMAND ""
+ )
+ set_property(TARGET ${proj}
+ PROPERTY FOLDER "SetupRepos/Local/Deeply/Nested/For/Testing")
+
+ set(local_git_repo "../../LocalRepositories/GIT-with-submodules")
+
+ set(proj TS1-GIT-no-GIT_SUBMODULES)
+ ExternalProject_Add(${proj}
+ GIT_REPOSITORY "${local_git_repo}"
+ CMAKE_GENERATOR "${CMAKE_GENERATOR}"
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+ -DWITH_m1:BOOL=ON
+ -DWITH_m2:BOOL=ON
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ DEPENDS "SetupLocalGITRepository"
+ "SetupLocalGITRepositoryWithSubmodules"
+ )
+ set_property(TARGET ${proj} PROPERTY FOLDER "GIT")
+
+ set(proj TS1-GIT-empty-GIT_SUBMODULES)
+ ExternalProject_Add(${proj}
+ GIT_REPOSITORY "${local_git_repo}"
+ GIT_SUBMODULES ""
+ CMAKE_GENERATOR "${CMAKE_GENERATOR}"
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+ -DWITH_m1:BOOL=ON
+ -DWITH_m2:BOOL=ON
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ DEPENDS "SetupLocalGITRepository"
+ "SetupLocalGITRepositoryWithSubmodules"
+ )
+ set_property(TARGET ${proj} PROPERTY FOLDER "GIT")
+
+ set(proj TS1-GIT-some-GIT_SUBMODULES)
+ ExternalProject_Add(${proj}
+ GIT_REPOSITORY "${local_git_repo}"
+ GIT_SUBMODULES "m/m1"
+ CMAKE_GENERATOR "${CMAKE_GENERATOR}"
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+ -DWITH_m1:BOOL=ON
+ -DWITH_m2:BOOL=OFF
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ DEPENDS "SetupLocalGITRepository"
+ "SetupLocalGITRepositoryWithSubmodules"
+ )
+ set_property(TARGET ${proj} PROPERTY FOLDER "GIT")
+
endif()
set(do_hg_tests 0)
@@ -520,6 +432,13 @@ if(HG_EXECUTABLE)
set(do_hg_tests 1)
endif()
+if(do_hg_tests AND NOT UNIX)
+ if("${HG_EXECUTABLE}" MATCHES "cygwin")
+ message(STATUS "No ExternalProject hg tests with cygwin hg outside cygwin!")
+ set(do_hg_tests 0)
+ endif()
+endif()
+
if(do_hg_tests)
set(local_hg_repo "../../LocalRepositories/HG")
@@ -595,29 +514,6 @@ enable_testing()
#
# BuildTree tests:
#
-if(can_build_tutorial_step5)
- add_test(TutorialStep5-Local-BuildTreeTest
- "${binary_base}/TutorialStep5-Local/Tutorial" 42)
- set_property(TEST TutorialStep5-Local-BuildTreeTest
- APPEND PROPERTY LABELS Step5 BuildTree)
-endif()
-
-add_test(TutorialStep1-LocalTAR-BuildTreeTest
- "${binary_base}/TutorialStep1-LocalTAR/EP-Tutorial" 36)
-set_property(TEST TutorialStep1-LocalTAR-BuildTreeTest
- APPEND PROPERTY LABELS TAR)
-
-add_test(TutorialStep1-LocalNoDirTAR-BuildTreeTest
- "${binary_base}/TutorialStep1-LocalNoDirTAR/EP-Tutorial" 25)
-
-add_test(TutorialStep1-LocalTGZ-BuildTreeTest
- "${binary_base}/TutorialStep1-LocalTGZ/Tutorial" 16)
-set_property(TEST TutorialStep1-LocalTGZ-BuildTreeTest
- APPEND PROPERTY LABELS TGZ)
-
-add_test(TutorialStep1-LocalNoDirTGZ-BuildTreeTest
- "${binary_base}/TutorialStep1-LocalNoDirTGZ/Tutorial" 9)
-
if(do_cvs_tests)
add_test(TutorialStep1-CVS-20090626-BuildTreeTest
"${binary_base}/TutorialStep1-CVS-20090626/Tutorial" 4)
@@ -652,18 +548,42 @@ if(do_git_tests)
endif()
-# InstallTree tests:
-#
-if(can_build_tutorial_step5)
- add_test(TutorialStep5-InstallTreeTest
- "${TutorialStep5_install_dir}/bin/Tutorial" 49)
- set_property(TEST TutorialStep5-InstallTreeTest
- APPEND PROPERTY LABELS Step5 InstallTree)
-endif()
-
-
-message(STATUS "can_build_tutorial_step5='${can_build_tutorial_step5}'")
message(STATUS "do_cvs_tests='${do_cvs_tests}'")
message(STATUS "do_svn_tests='${do_svn_tests}'")
message(STATUS "do_git_tests='${do_git_tests}' GIT_EXECUTABLE='${GIT_EXECUTABLE}'")
message(STATUS "do_hg_tests='${do_hg_tests}' HG_EXECUTABLE='${HG_EXECUTABLE}'")
+
+
+# Test if log works when the first arguments of *_COMMAND is "COMMAND".
+set(proj ExternalProject-no-log)
+set(download_cmd "")
+set(patch_cmd "")
+set(update_cmd "")
+set(configure_cmd "")
+set(build_cmd "")
+set(install_cmd "")
+
+ExternalProject_Add(${proj}
+ DOWNLOAD_COMMAND "${download_cmd}" COMMAND "${CMAKE_COMMAND}" -E echo "download"
+ PATCH_COMMAND "${patch_cmd}" COMMAND "${CMAKE_COMMAND}" -E echo "patch"
+ UPDATE_COMMAND "${update_cmd}" COMMAND "${CMAKE_COMMAND}" -E echo "update"
+ CONFIGURE_COMMAND "${configure_cmd}" COMMAND "${CMAKE_COMMAND}" -E echo "configure"
+ BUILD_COMMAND "${build_cmd}" COMMAND "${CMAKE_COMMAND}" -E echo "build"
+ INSTALL_COMMAND "${install_cmd}" COMMAND "${CMAKE_COMMAND}" -E echo "install"
+ )
+
+set(proj ExternalProject-log)
+ExternalProject_Add(${proj}
+ DOWNLOAD_COMMAND "${download_cmd}" COMMAND "${CMAKE_COMMAND}" -E echo "download"
+ PATCH_COMMAND "${patch_cmd}" COMMAND "${CMAKE_COMMAND}" -E echo "patch"
+ UPDATE_COMMAND "${update_cmd}" COMMAND "${CMAKE_COMMAND}" -E echo "update"
+ CONFIGURE_COMMAND "${configure_cmd}" COMMAND "${CMAKE_COMMAND}" -E echo "configure"
+ BUILD_COMMAND "${build_cmd}" COMMAND "${CMAKE_COMMAND}" -E echo "build"
+ INSTALL_COMMAND "${install_cmd}" COMMAND "${CMAKE_COMMAND}" -E echo "install"
+ LOG_DOWNLOAD 1
+ LOG_PATCH 1
+ LOG_UPDATE 1
+ LOG_CONFIGURE 1
+ LOG_BUILD 1
+ LOG_INSTALL 1
+ )
diff --git a/Tests/ExternalProject/Example/CMakeLists.txt b/Tests/ExternalProject/Example/CMakeLists.txt
index 69ebaaf51..4c128957e 100644
--- a/Tests/ExternalProject/Example/CMakeLists.txt
+++ b/Tests/ExternalProject/Example/CMakeLists.txt
@@ -5,7 +5,7 @@ include(ExternalProject)
ExternalProject_Add(
cmake281
- URL http://www.cmake.org/files/v2.8/cmake-2.8.1.tar.gz
+ URL https://cmake.org/files/v2.8/cmake-2.8.1.tar.gz
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
BUILD_COMMAND ""
)
diff --git a/Tests/ExternalProject/TryCheckout.cmake b/Tests/ExternalProject/TryCheckout.cmake
deleted file mode 100644
index 6a396c339..000000000
--- a/Tests/ExternalProject/TryCheckout.cmake
+++ /dev/null
@@ -1,54 +0,0 @@
-find_package(CVS)
-find_package(Subversion)
-
-
-function(try_cvs_checkout repository module dir result_var)
- # Assume cvs checkouts will not work:
- set(${result_var} 0 PARENT_SCOPE)
-
- if(CVS_EXECUTABLE)
- message(STATUS "try_cvs_checkout")
-
- # Ensure directory exists so we can call cvs in it:
- file(MAKE_DIRECTORY "${dir}")
-
- # Try to do the cvs checkout command:
- execute_process(COMMAND ${CVS_EXECUTABLE} -d ${repository} co ${module}
- WORKING_DIRECTORY ${dir}
- TIMEOUT 30
- RESULT_VARIABLE rv)
-
- # If it worked, cvs checkouts will work:
- if(rv EQUAL 0)
- set(${result_var} 1 PARENT_SCOPE)
- endif()
-
- message(STATUS "try_cvs_checkout -- done")
- endif()
-endfunction()
-
-
-function(try_svn_checkout repository dir result_var)
- # Assume svn checkouts will not work:
- set(${result_var} 0 PARENT_SCOPE)
-
- if(Subversion_SVN_EXECUTABLE)
- message(STATUS "try_svn_checkout")
-
- # Ensure directory exists so we can call svn in it:
- file(MAKE_DIRECTORY "${dir}")
-
- # Try to do the svn checkout command:
- execute_process(COMMAND ${Subversion_SVN_EXECUTABLE} co ${repository} ${dir}
- WORKING_DIRECTORY ${dir}
- TIMEOUT 30
- RESULT_VARIABLE rv)
-
- # If it worked, svn checkouts will work:
- if(rv EQUAL 0)
- set(${result_var} 1 PARENT_SCOPE)
- endif()
-
- message(STATUS "try_svn_checkout -- done")
- endif()
-endfunction()
diff --git a/Tests/ExternalProject/gitrepo-sub.tgz b/Tests/ExternalProject/gitrepo-sub.tgz
new file mode 100644
index 000000000..c0b536017
--- /dev/null
+++ b/Tests/ExternalProject/gitrepo-sub.tgz
Binary files differ
diff --git a/Tests/ExternalProjectLocal/CMakeLists.txt b/Tests/ExternalProjectLocal/CMakeLists.txt
new file mode 100644
index 000000000..e1a67dbe2
--- /dev/null
+++ b/Tests/ExternalProjectLocal/CMakeLists.txt
@@ -0,0 +1,255 @@
+cmake_minimum_required(VERSION 2.8)
+project(ExternalProjectLocalTest NONE)
+
+include(ExternalProject)
+
+# Test ExternalProject with local projects
+
+option(ExternalProjectTest_USE_FOLDERS "Enable folder grouping in IDEs." ON)
+if(ExternalProjectTest_USE_FOLDERS)
+ set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+else()
+ set_property(GLOBAL PROPERTY USE_FOLDERS OFF)
+endif()
+
+set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER
+ "CMakePredefinedTargets-in-ExternalProjectTest")
+
+set(base "${CMAKE_BINARY_DIR}/Ext")
+set(binary_base "${base}/Build")
+set_property(DIRECTORY PROPERTY EP_BASE ${base})
+set_property(DIRECTORY PROPERTY EP_STEP_TARGETS configure build test)
+
+if(NOT DEFINED can_build_tutorial_step5)
+ set(can_build_tutorial_step5 1)
+
+ # Tutorial Step5 cannot build correctly using Visual Studio 6
+ # on Windows 98 if the path of its build tree exceeds 72
+ # characters in length... So don't attempt to build it
+ # in a long path on Win98:
+ #
+ if(CMAKE_SYSTEM STREQUAL "Windows-4.10")
+ string(LENGTH "${binary_base}/TutorialStep5-Local" n)
+ if(n GREATER 72)
+ set(can_build_tutorial_step5 0)
+ endif()
+ endif()
+
+ # The ExternalProject builds of Tutorial Step5 cannot be built
+ # correctly 2nd and later times in an in-source build...
+ # (because the CMakeCache.txt from the real in-source build of
+ # the Tests/Tutorial/Step5 directory gets copied when we do
+ # the "source directory copy" step... but it still refers to
+ # its original path which yields a configure error.) So:
+ #
+ if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
+ set(can_build_tutorial_step5 0)
+ endif()
+endif()
+
+# Local DIR:
+#
+if(can_build_tutorial_step5)
+ set(proj TutorialStep5-Local)
+ ExternalProject_Add(${proj}
+ URL "${CMAKE_CURRENT_SOURCE_DIR}/../Tutorial/Step5"
+ CMAKE_CACHE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+ CMAKE_ARGS -G ${CMAKE_GENERATOR} <SOURCE_DIR>
+ TEST_BEFORE_INSTALL 1
+ LOG_INSTALL 1
+ )
+ set_property(TARGET ${proj} PROPERTY FOLDER "Local")
+ ExternalProject_Get_Property(${proj} install_dir)
+ set(TutorialStep5_install_dir ${install_dir})
+
+ set(proj TutorialStep5-Local-TestAfterInstall)
+ ExternalProject_Add(${proj}
+ URL "${CMAKE_CURRENT_SOURCE_DIR}/../Tutorial/Step5"
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -G ${CMAKE_GENERATOR} <SOURCE_DIR>
+ CMAKE_CACHE_DEFAULT_ARGS -DUSE_MYMATH:BOOL=OFF
+ TEST_AFTER_INSTALL 1
+ LOG_TEST 1
+ )
+ set_property(TARGET ${proj} PROPERTY FOLDER "Local")
+
+ set(proj TutorialStep5-Local-TestExcludeFromMainBefore)
+ ExternalProject_Add(${proj}
+ URL "${CMAKE_CURRENT_SOURCE_DIR}/../Tutorial/Step5"
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -G ${CMAKE_GENERATOR} <SOURCE_DIR>
+ CMAKE_CACHE_DEFAULT_ARGS -DUSE_MYMATH:BOOL=OFF
+ TEST_BEFORE_INSTALL 1
+ TEST_EXCLUDE_FROM_MAIN 1
+ STEP_TARGETS test
+ LOG_TEST 1
+ )
+ set_property(TARGET ${proj} PROPERTY FOLDER "Local")
+
+ set(proj TutorialStep5-Local-TestExcludeFromMainAfter)
+ ExternalProject_Add(${proj}
+ URL "${CMAKE_CURRENT_SOURCE_DIR}/../Tutorial/Step5"
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -G ${CMAKE_GENERATOR} <SOURCE_DIR>
+ CMAKE_CACHE_DEFAULT_ARGS -DUSE_MYMATH:BOOL=OFF
+ TEST_AFTER_INSTALL 1
+ TEST_EXCLUDE_FROM_MAIN 1
+ STEP_TARGETS test
+ LOG_TEST 1
+ )
+ set_property(TARGET ${proj} PROPERTY FOLDER "Local")
+
+endif()
+
+
+# Local TAR:
+#
+set(proj TutorialStep1-LocalTAR)
+ExternalProject_Add(${proj}
+ URL "${CMAKE_CURRENT_SOURCE_DIR}/Step1.tar"
+ URL_MD5 a87c5b47c0201c09ddfe1d5738fdb1e3
+ LIST_SEPARATOR ::
+ PATCH_COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/Step1Patch.cmake
+ CMAKE_GENERATOR "${CMAKE_GENERATOR}"
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+ -DTEST_LIST:STRING=A::B::C
+ INSTALL_COMMAND ""
+ LOG_CONFIGURE 1
+)
+set_property(TARGET ${proj} PROPERTY FOLDER "Local/TAR")
+
+set(proj TutorialStep1-LocalNoDirTAR)
+ExternalProject_Add(${proj}
+ URL "${CMAKE_CURRENT_SOURCE_DIR}/Step1NoDir.tar"
+ URL_MD5 d09e3d370c5c908fa035c30939ee438e
+ LIST_SEPARATOR @@
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -G ${CMAKE_GENERATOR} <SOURCE_DIR>
+ -DTEST_LIST:STRING=1@@2@@3
+ INSTALL_COMMAND ""
+)
+set_property(TARGET ${proj} PROPERTY FOLDER "Local/TAR")
+ExternalProject_Add_Step(${proj} mypatch
+ COMMAND ${CMAKE_COMMAND} -E echo "This is a custom external project step."
+ COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/Step1Patch.cmake
+ WORKING_DIRECTORY <SOURCE_DIR>
+ DEPENDEES download
+ DEPENDERS configure
+ )
+
+
+# Local TGZ:
+#
+set(proj TutorialStep1-LocalTGZ)
+ExternalProject_Add(${proj}
+ URL "${CMAKE_CURRENT_SOURCE_DIR}/Step1.tgz"
+ URL_MD5 38c648e817339c356f6be00eeed79bd0
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -G ${CMAKE_GENERATOR} <SOURCE_DIR>
+ INSTALL_COMMAND ""
+ LOG_BUILD 1
+)
+set_property(TARGET ${proj} PROPERTY FOLDER "Local/TGZ")
+
+set(proj TutorialStep1-LocalNoDirTGZ)
+ExternalProject_Add(${proj}
+ URL "${CMAKE_CURRENT_SOURCE_DIR}/Step1NoDir.tgz"
+ URL_HASH SHA256=496229e2a5ed620a37c385ad9406004a18026beab8b55dd2c4565d4b7f1d5383
+ CMAKE_GENERATOR "${CMAKE_GENERATOR}"
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+ INSTALL_COMMAND ""
+)
+set_property(TARGET ${proj} PROPERTY FOLDER "Local/TGZ")
+
+
+# Local BZ2:
+#
+# (The bz2 tests are here just to verify that the bz2 decompression is executed
+# during a test suite run... The configure and build commands are set to
+# nothing to make the test quicker. To make this more complete, I should add
+# a diff between this and the TGZ source tree since that one does build...)
+#
+set(proj TutorialStep1-LocalBZ2)
+ExternalProject_Add(${proj}
+ URL "${CMAKE_CURRENT_SOURCE_DIR}/Step1.tar.bz2"
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+)
+set_property(TARGET ${proj} PROPERTY FOLDER "Local/BZ2")
+
+set(proj TutorialStep1-LocalNoDirBZ2)
+ExternalProject_Add(${proj}
+ URL "${CMAKE_CURRENT_SOURCE_DIR}/Step1NoDir.tar.bz2"
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+)
+set_property(TARGET ${proj} PROPERTY FOLDER "Local/BZ2")
+
+
+# Local ZIP:
+#
+# (The zip tests are here just to verify that the zip decompression is executed
+# during a test suite run... The configure and build commands are set to
+# nothing to make the test quicker. To make this more complete, I should add
+# a diff between this and the TGZ source tree since that one does build...)
+#
+set(proj TutorialStep1-LocalZIP)
+ExternalProject_Add(${proj}
+ URL "${CMAKE_CURRENT_SOURCE_DIR}/Step1.zip"
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+)
+set_property(TARGET ${proj} PROPERTY FOLDER "Local/ZIP")
+
+set(proj TutorialStep1-LocalNoDirZIP)
+ExternalProject_Add(${proj}
+ URL "${CMAKE_CURRENT_SOURCE_DIR}/Step1NoDir.zip"
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+)
+set_property(TARGET ${proj} PROPERTY FOLDER "Local/ZIP")
+
+
+# Test the testable built/installed products:
+#
+enable_testing()
+
+
+# Do at least a smoke test of a built executable from each
+# project's build directory...
+#
+# BuildTree tests:
+#
+if(can_build_tutorial_step5)
+ add_test(TutorialStep5-Local-BuildTreeTest
+ "${binary_base}/TutorialStep5-Local/Tutorial" 42)
+ set_property(TEST TutorialStep5-Local-BuildTreeTest
+ APPEND PROPERTY LABELS Step5 BuildTree)
+endif()
+
+add_test(TutorialStep1-LocalTAR-BuildTreeTest
+ "${binary_base}/TutorialStep1-LocalTAR/EP-Tutorial" 36)
+set_property(TEST TutorialStep1-LocalTAR-BuildTreeTest
+ APPEND PROPERTY LABELS TAR)
+
+add_test(TutorialStep1-LocalNoDirTAR-BuildTreeTest
+ "${binary_base}/TutorialStep1-LocalNoDirTAR/EP-Tutorial" 25)
+
+add_test(TutorialStep1-LocalTGZ-BuildTreeTest
+ "${binary_base}/TutorialStep1-LocalTGZ/Tutorial" 16)
+set_property(TEST TutorialStep1-LocalTGZ-BuildTreeTest
+ APPEND PROPERTY LABELS TGZ)
+
+add_test(TutorialStep1-LocalNoDirTGZ-BuildTreeTest
+ "${binary_base}/TutorialStep1-LocalNoDirTGZ/Tutorial" 9)
+
+# InstallTree tests:
+#
+if(can_build_tutorial_step5)
+ add_test(TutorialStep5-InstallTreeTest
+ "${TutorialStep5_install_dir}/bin/Tutorial" 49)
+ set_property(TEST TutorialStep5-InstallTreeTest
+ APPEND PROPERTY LABELS Step5 InstallTree)
+endif()
+
+
+message(STATUS "can_build_tutorial_step5='${can_build_tutorial_step5}'")
diff --git a/Tests/ExternalProject/Step1.tar b/Tests/ExternalProjectLocal/Step1.tar
index 3711f07fb..3711f07fb 100644
--- a/Tests/ExternalProject/Step1.tar
+++ b/Tests/ExternalProjectLocal/Step1.tar
Binary files differ
diff --git a/Tests/ExternalProject/Step1.tar.bz2 b/Tests/ExternalProjectLocal/Step1.tar.bz2
index 49b5f23a6..49b5f23a6 100644
--- a/Tests/ExternalProject/Step1.tar.bz2
+++ b/Tests/ExternalProjectLocal/Step1.tar.bz2
Binary files differ
diff --git a/Tests/ExternalProject/Step1.tgz b/Tests/ExternalProjectLocal/Step1.tgz
index d9b4cd259..d9b4cd259 100644
--- a/Tests/ExternalProject/Step1.tgz
+++ b/Tests/ExternalProjectLocal/Step1.tgz
Binary files differ
diff --git a/Tests/ExternalProject/Step1.zip b/Tests/ExternalProjectLocal/Step1.zip
index 49dac24ed..49dac24ed 100644
--- a/Tests/ExternalProject/Step1.zip
+++ b/Tests/ExternalProjectLocal/Step1.zip
Binary files differ
diff --git a/Tests/ExternalProject/Step1NoDir.tar b/Tests/ExternalProjectLocal/Step1NoDir.tar
index 03664b856..03664b856 100644
--- a/Tests/ExternalProject/Step1NoDir.tar
+++ b/Tests/ExternalProjectLocal/Step1NoDir.tar
Binary files differ
diff --git a/Tests/ExternalProject/Step1NoDir.tar.bz2 b/Tests/ExternalProjectLocal/Step1NoDir.tar.bz2
index 92eb480d6..92eb480d6 100644
--- a/Tests/ExternalProject/Step1NoDir.tar.bz2
+++ b/Tests/ExternalProjectLocal/Step1NoDir.tar.bz2
Binary files differ
diff --git a/Tests/ExternalProject/Step1NoDir.tgz b/Tests/ExternalProjectLocal/Step1NoDir.tgz
index 71a2d8142..71a2d8142 100644
--- a/Tests/ExternalProject/Step1NoDir.tgz
+++ b/Tests/ExternalProjectLocal/Step1NoDir.tgz
Binary files differ
diff --git a/Tests/ExternalProject/Step1NoDir.zip b/Tests/ExternalProjectLocal/Step1NoDir.zip
index b42d31879..b42d31879 100644
--- a/Tests/ExternalProject/Step1NoDir.zip
+++ b/Tests/ExternalProjectLocal/Step1NoDir.zip
Binary files differ
diff --git a/Tests/ExternalProject/Step1Patch.cmake b/Tests/ExternalProjectLocal/Step1Patch.cmake
index 35e09d948..35e09d948 100644
--- a/Tests/ExternalProject/Step1Patch.cmake
+++ b/Tests/ExternalProjectLocal/Step1Patch.cmake
diff --git a/Tests/ExternalProjectSubdir/CMakeLists.txt b/Tests/ExternalProjectSubdir/CMakeLists.txt
new file mode 100644
index 000000000..e65087a8c
--- /dev/null
+++ b/Tests/ExternalProjectSubdir/CMakeLists.txt
@@ -0,0 +1,29 @@
+cmake_minimum_required(VERSION 3.2)
+project(ExternalProjectSubdir NONE)
+include(ExternalProject)
+
+# Remove the custom target output to be sure it runs in an
+# incremental test. Skip this on VS 6 because it sometimes
+# re-runs CMake after the custom command runs.
+if(NOT CMAKE_GENERATOR STREQUAL "Visual Studio 6")
+ file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/PreSubdir1.txt)
+endif()
+
+add_custom_target(PreSubdir1
+ COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/PreSubdir1.txt
+ )
+add_library(PreSubdir1Interface INTERFACE)
+add_dependencies(PreSubdir1Interface PreSubdir1)
+
+ExternalProject_Add(Subdir1
+ SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Subdir1
+ BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/Subdir1
+
+ CMAKE_ARGS -DNORMAL_VAR=NORMAL_VALUE -DGENEX_VAR=$<1:GENEX_VALUE>
+ LOG_CONFIGURE 1
+
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+
+ DEPENDS PreSubdir1Interface
+ )
diff --git a/Tests/ExternalProjectSubdir/Subdir1/CMakeLists.txt b/Tests/ExternalProjectSubdir/Subdir1/CMakeLists.txt
new file mode 100644
index 000000000..2303c3e88
--- /dev/null
+++ b/Tests/ExternalProjectSubdir/Subdir1/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.2)
+project(Subdir1 NONE)
+
+if(NOT "${NORMAL_VAR}" STREQUAL "NORMAL_VALUE")
+ message(SEND_ERROR "NORMAL_VAR != 'NORMAL_VALUE'")
+endif()
+
+if(NOT "${GENEX_VAR}" STREQUAL "GENEX_VALUE")
+ message(SEND_ERROR "GENEX_VAR != 'GENEX_VALUE'")
+endif()
+
+if(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/../PreSubdir1.txt")
+ message(SEND_ERROR "../PreSubdir1.txt not provided!")
+endif()
diff --git a/Tests/ExternalProjectUpdate/CMakeLists.txt b/Tests/ExternalProjectUpdate/CMakeLists.txt
index c33e90b51..fbb338869 100644
--- a/Tests/ExternalProjectUpdate/CMakeLists.txt
+++ b/Tests/ExternalProjectUpdate/CMakeLists.txt
@@ -19,6 +19,7 @@ set(base "${CMAKE_BINARY_DIR}/CMakeExternals")
set(binary_base "${base}/Build")
set_property(DIRECTORY PROPERTY EP_BASE ${base})
set_property(DIRECTORY PROPERTY EP_STEP_TARGETS configure build test)
+set_property(DIRECTORY PROPERTY EP_INDEPENDENT_STEP_TARGETS update)
set(do_git_tests 0)
@@ -68,8 +69,20 @@ if(do_git_tests)
CMAKE_GENERATOR "${CMAKE_GENERATOR}"
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
INSTALL_COMMAND ""
- DEPENDS "SetupLocalGITRepository"
)
+ ExternalProject_Add_StepDependencies(${proj} download SetupLocalGITRepository)
+ set_property(TARGET ${proj} PROPERTY FOLDER "GIT")
+
+ set(proj TutorialStep2-GIT)
+ ExternalProject_Add(${proj}
+ GIT_REPOSITORY "${local_git_repo}"
+ GIT_TAG ${TEST_GIT_TAG}
+ CMAKE_GENERATOR "${CMAKE_GENERATOR}"
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+ INSTALL_COMMAND ""
+ UPDATE_DISCONNECTED 1
+ )
+ ExternalProject_Add_StepDependencies(${proj} download SetupLocalGITRepository)
set_property(TARGET ${proj} PROPERTY FOLDER "GIT")
endif()
diff --git a/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake b/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake
index b6f848aa8..7065f36c1 100644
--- a/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake
+++ b/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake
@@ -12,7 +12,8 @@ macro(check_a_tag desired_tag resulting_sha fetch_expected)
# Configure
execute_process(COMMAND ${CMAKE_COMMAND}
- -G ${CMAKE_TEST_GENERATOR} -T "${CMAKE_TEST_GENERATOR_TOOLSET}"
+ -G ${CMAKE_GENERATOR} -T "${CMAKE_GENERATOR_TOOLSET}"
+ -A "${CMAKE_GENERATOR_PLATFORM}"
-DTEST_GIT_TAG:STRING=${desired_tag}
${ExternalProjectUpdate_SOURCE_DIR}
WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR}
@@ -58,6 +59,102 @@ was expected."
if( EXISTS ${FETCH_HEAD_file} AND NOT ${fetch_expected})
message( FATAL_ERROR "Fetch DID occur when it was not expected.")
endif()
+
+ message( STATUS "Checking ExternalProjectUpdate to tag: ${desired_tag} (disconnected)" )
+
+ # Remove the FETCH_HEAD file, so we can check if it gets replaced with a 'git
+ # fetch'.
+ set( FETCH_HEAD_file ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep2-GIT/.git/FETCH_HEAD )
+ file( REMOVE ${FETCH_HEAD_file} )
+
+ # Check initial SHA
+ execute_process(COMMAND ${GIT_EXECUTABLE}
+ rev-list --max-count=1 HEAD
+ WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep2-GIT
+ RESULT_VARIABLE error_code
+ OUTPUT_VARIABLE initial_sha
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+
+ # Configure
+ execute_process(COMMAND ${CMAKE_COMMAND}
+ -G ${CMAKE_GENERATOR} -T "${CMAKE_GENERATOR_TOOLSET}"
+ -A "${CMAKE_GENERATOR_PLATFORM}"
+ -DTEST_GIT_TAG:STRING=${desired_tag}
+ ${ExternalProjectUpdate_SOURCE_DIR}
+ WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR}
+ RESULT_VARIABLE error_code
+ )
+ if(error_code)
+ message(FATAL_ERROR "Could not configure the project.")
+ endif()
+
+ # Build
+ execute_process(COMMAND ${CMAKE_COMMAND}
+ --build ${ExternalProjectUpdate_BINARY_DIR}
+ RESULT_VARIABLE error_code
+ )
+ if(error_code)
+ message(FATAL_ERROR "Could not build the project.")
+ endif()
+
+ if( EXISTS ${FETCH_HEAD_file} )
+ message( FATAL_ERROR "Fetch occured when it was not expected.")
+ endif()
+
+ # Check the resulting SHA
+ execute_process(COMMAND ${GIT_EXECUTABLE}
+ rev-list --max-count=1 HEAD
+ WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep2-GIT
+ RESULT_VARIABLE error_code
+ OUTPUT_VARIABLE tag_sha
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ if(error_code)
+ message(FATAL_ERROR "Could not check the sha.")
+ endif()
+
+ if(NOT (${tag_sha} STREQUAL ${initial_sha}))
+ message(FATAL_ERROR "Update occurred when it was not expected.")
+ endif()
+
+ # Update
+ execute_process(COMMAND ${CMAKE_COMMAND}
+ --build ${ExternalProjectUpdate_BINARY_DIR}
+ --target TutorialStep2-GIT-update
+ RESULT_VARIABLE error_code
+ )
+ if(error_code)
+ message(FATAL_ERROR "Could not build the project.")
+ endif()
+
+ # Check the resulting SHA
+ execute_process(COMMAND ${GIT_EXECUTABLE}
+ rev-list --max-count=1 HEAD
+ WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep2-GIT
+ RESULT_VARIABLE error_code
+ OUTPUT_VARIABLE tag_sha
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ if(error_code)
+ message(FATAL_ERROR "Could not check the sha.")
+ endif()
+
+ if(NOT (${tag_sha} STREQUAL ${resulting_sha}))
+ message(FATAL_ERROR "UPDATE_COMMAND produced
+ ${tag_sha}
+when
+ ${resulting_sha}
+was expected."
+ )
+ endif()
+
+ if( NOT EXISTS ${FETCH_HEAD_file} AND ${fetch_expected})
+ message( FATAL_ERROR "Fetch did NOT occur when it was expected.")
+ endif()
+ if( EXISTS ${FETCH_HEAD_file} AND NOT ${fetch_expected})
+ message( FATAL_ERROR "Fetch DID occur when it was not expected.")
+ endif()
endmacro()
find_package(Git)
diff --git a/Tests/FindBoost/CMakeLists.txt b/Tests/FindBoost/CMakeLists.txt
new file mode 100644
index 000000000..259ee266f
--- /dev/null
+++ b/Tests/FindBoost/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_test(NAME FindBoost.Test COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindBoost/Test"
+ "${CMake_BINARY_DIR}/Tests/FindBoost/Test"
+ ${build_generator_args}
+ --build-project TestFindBoost
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
diff --git a/Tests/FindBoost/Test/CMakeLists.txt b/Tests/FindBoost/Test/CMakeLists.txt
new file mode 100644
index 000000000..ce50fc775
--- /dev/null
+++ b/Tests/FindBoost/Test/CMakeLists.txt
@@ -0,0 +1,18 @@
+cmake_minimum_required(VERSION 3.1)
+project(TestFindBoost CXX)
+include(CTest)
+
+find_package(Boost REQUIRED COMPONENTS filesystem thread)
+
+add_executable(test_boost_tgt main.cxx)
+target_link_libraries(test_boost_tgt
+ Boost::dynamic_linking
+ Boost::disable_autolinking
+ Boost::filesystem
+ Boost::thread)
+add_test(NAME test_boost_tgt COMMAND test_boost_tgt)
+
+add_executable(test_boost_var main.cxx)
+target_include_directories(test_boost_var PRIVATE ${Boost_INCLUDE_DIRS})
+target_link_libraries(test_boost_var PRIVATE ${Boost_FILESYSTEM_LIBRARIES} ${Boost_SYSTEM_LIBRARIES} ${Boost_THREAD_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
+add_test(NAME test_boost_var COMMAND test_boost_var)
diff --git a/Tests/FindBoost/Test/main.cxx b/Tests/FindBoost/Test/main.cxx
new file mode 100644
index 000000000..0f44f30b0
--- /dev/null
+++ b/Tests/FindBoost/Test/main.cxx
@@ -0,0 +1,26 @@
+#include <boost/filesystem.hpp>
+#include <boost/thread.hpp>
+
+namespace
+{
+
+ boost::mutex m1;
+ boost::recursive_mutex m2;
+
+ void
+ threadmain()
+ {
+ boost::lock_guard<boost::mutex> lock1(m1);
+ boost::lock_guard<boost::recursive_mutex> lock2(m2);
+
+ boost::filesystem::path p(boost::filesystem::current_path());
+ }
+
+}
+
+int main() {
+ boost::thread foo(threadmain);
+ foo.join();
+
+ return 0;
+}
diff --git a/Tests/FindGSL/CMakeLists.txt b/Tests/FindGSL/CMakeLists.txt
new file mode 100644
index 000000000..45a347102
--- /dev/null
+++ b/Tests/FindGSL/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_test(NAME FindGSL.rng COMMAND ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGSL/rng"
+ "${CMake_BINARY_DIR}/Tests/FindGSL/rng"
+ ${build_generator_args}
+ --build-project FindGSL_rng
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
diff --git a/Tests/FindGSL/rng/CMakeLists.txt b/Tests/FindGSL/rng/CMakeLists.txt
new file mode 100644
index 000000000..b15d6acab
--- /dev/null
+++ b/Tests/FindGSL/rng/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.0)
+project(FindGSL_rng CXX)
+include(CTest)
+
+find_package(GSL REQUIRED)
+
+add_executable(tstgslrng_tgt main.cc)
+target_link_libraries(tstgslrng_tgt GSL::gsl)
+add_test(NAME tstgslrng_tgt COMMAND tstgslrng_tgt)
+
+add_executable(tstgslrng_var main.cc)
+target_link_libraries(tstgslrng_var ${GSL_LIBRARIES})
+target_include_directories(tstgslrng_var PRIVATE ${GSL_INCLUDE_DIRS})
+add_test(NAME tstgslrng_var COMMAND tstgslrng_var)
diff --git a/Tests/FindGSL/rng/main.cc b/Tests/FindGSL/rng/main.cc
new file mode 100644
index 000000000..72543be77
--- /dev/null
+++ b/Tests/FindGSL/rng/main.cc
@@ -0,0 +1,24 @@
+#include <math.h>
+#include "gsl/gsl_rng.h"
+
+int main()
+{
+ // return code
+ int retval = 1;
+
+ // create a generator
+ gsl_rng *generator;
+ generator = gsl_rng_alloc(gsl_rng_mt19937);
+
+ // Read a value.
+ double const Result = gsl_rng_uniform(generator);
+
+ // Check value
+ double const expectedResult( 0.999741748906672 );
+ if( fabs( expectedResult - Result ) < 1.0e-6 )
+ retval = 0;
+
+ // free allocated memory
+ gsl_rng_free(generator);
+ return retval;
+}
diff --git a/Tests/FindGTK2/CMakeLists.txt b/Tests/FindGTK2/CMakeLists.txt
new file mode 100644
index 000000000..0105faeaa
--- /dev/null
+++ b/Tests/FindGTK2/CMakeLists.txt
@@ -0,0 +1,320 @@
+find_package(GTK2 COMPONENTS gtk glade gtkmm glademm QUIET)
+
+
+# Test GTK2 components
+if(GTK2_GTK_FOUND)
+ add_test(GTK2Components.gtk ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGTK2/gtk"
+ "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Components/gtk"
+ ${build_generator_args}
+ --build-target gtk-all-libs
+ --build-project gtk
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Components/gtk"
+ --force-new-ctest-process
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+endif()
+
+if(GTK2_GTKMM_FOUND)
+ add_test(GTK2Components.gtkmm ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGTK2/gtkmm"
+ "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Components/gtkmm"
+ ${build_generator_args}
+ --build-target gtkmm-all-libs
+ --build-project gtkmm
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Components/gtkmm"
+ --force-new-ctest-process
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+endif()
+
+
+# Test GTK2 targets
+if(TARGET GTK2::glib)
+ add_test(GTK2Targets.glib ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGTK2/glib"
+ "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/glib"
+ ${build_generator_args}
+ --build-project glib
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/glib"
+ --force-new-ctest-process
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+endif()
+
+if(TARGET GTK2::gobject)
+ add_test(GTK2Targets.gobject ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGTK2/gobject"
+ "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gobject"
+ ${build_generator_args}
+ --build-project gobject
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gobject"
+ --force-new-ctest-process
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+endif()
+
+if(TARGET GTK2::gio)
+ add_test(GTK2Targets.gio ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGTK2/gio"
+ "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gio"
+ ${build_generator_args}
+ --build-project gio
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gio"
+ --force-new-ctest-process
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+endif()
+
+if(TARGET GTK2::gmodule)
+ add_test(GTK2Targets.gmodule ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGTK2/gmodule"
+ "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gmodule"
+ ${build_generator_args}
+ --build-project gmodule
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gmodule"
+ --force-new-ctest-process
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+endif()
+
+if(TARGET GTK2::gthread)
+ add_test(GTK2Targets.gthread ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGTK2/gthread"
+ "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gthread"
+ ${build_generator_args}
+ --build-project gthread
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gthread"
+ --force-new-ctest-process
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+endif()
+
+if(TARGET GTK2::atk)
+ add_test(GTK2Targets.atk ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGTK2/atk"
+ "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/atk"
+ ${build_generator_args}
+ --build-project atk
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/atk"
+ --force-new-ctest-process
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+endif()
+
+if(TARGET GTK2::gdk_pixbuf)
+ add_test(GTK2Targets.gdk_pixbuf ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGTK2/gdk_pixbuf"
+ "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gdk_pixbuf"
+ ${build_generator_args}
+ --build-project gdk_pixbuf
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gdk_pixbuf"
+ --force-new-ctest-process
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+endif()
+
+if(TARGET GTK2::cairo)
+ add_test(GTK2Targets.cairo ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGTK2/cairo"
+ "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/cairo"
+ ${build_generator_args}
+ --build-project cairo
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/cairo"
+ --force-new-ctest-process
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+endif()
+
+if(TARGET GTK2::pango)
+ add_test(GTK2Targets.pango ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGTK2/pango"
+ "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/pango"
+ ${build_generator_args}
+ --build-project pango
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/pango"
+ --force-new-ctest-process
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+endif()
+
+if(TARGET GTK2::pangocairo)
+ add_test(GTK2Targets.pangocairo ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGTK2/pangocairo"
+ "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/pangocairo"
+ ${build_generator_args}
+ --build-project pangocairo
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/pangocairo"
+ --force-new-ctest-process
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+endif()
+
+if(TARGET GTK2::pangoxft)
+ add_test(GTK2Targets.pangoxft ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGTK2/pangoxft"
+ "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/pangoxft"
+ ${build_generator_args}
+ --build-project pangoxft
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/pangoxft"
+ --force-new-ctest-process
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+endif()
+
+if(TARGET GTK2::pangoft2)
+ add_test(GTK2Targets.pangoft2 ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGTK2/pangoft2"
+ "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/pangoft2"
+ ${build_generator_args}
+ --build-project pangoft2
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/pangoft2"
+ --force-new-ctest-process
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+endif()
+
+if(TARGET GTK2::gdk)
+ add_test(GTK2Targets.gdk ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGTK2/gdk"
+ "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gdk"
+ ${build_generator_args}
+ --build-project gdk
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gdk"
+ --force-new-ctest-process
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+endif()
+
+if(TARGET GTK2::gtk)
+ add_test(GTK2Targets.gtk ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGTK2/gtk"
+ "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gtk"
+ ${build_generator_args}
+ --build-project gtk
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gtk"
+ --force-new-ctest-process
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+endif()
+
+if(TARGET GTK2::sigc++)
+ add_test(GTK2Targets.sigc++ ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGTK2/sigc++"
+ "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/sigc++"
+ ${build_generator_args}
+ --build-project sigc++
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/sigc++"
+ --force-new-ctest-process
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+endif()
+
+if(TARGET GTK2::glibmm)
+ add_test(GTK2Targets.glibmm ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGTK2/glibmm"
+ "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/glibmm"
+ ${build_generator_args}
+ --build-project glibmm
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/glibmm"
+ --force-new-ctest-process
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+endif()
+
+if(TARGET GTK2::giomm)
+ add_test(GTK2Targets.giomm ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGTK2/giomm"
+ "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/giomm"
+ ${build_generator_args}
+ --build-project giomm
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/giomm"
+ --force-new-ctest-process
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+endif()
+
+if(TARGET GTK2::atkmm)
+ add_test(GTK2Targets.atkmm ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGTK2/atkmm"
+ "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/atkmm"
+ ${build_generator_args}
+ --build-project atkmm
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/atkmm"
+ --force-new-ctest-process
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+endif()
+
+if(TARGET GTK2::cairomm)
+ add_test(GTK2Targets.cairomm ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGTK2/cairomm"
+ "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/cairomm"
+ ${build_generator_args}
+ --build-project cairomm
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/cairomm"
+ --force-new-ctest-process
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+endif()
+
+if(TARGET GTK2::pangomm)
+ add_test(GTK2Targets.pangomm ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGTK2/pangomm"
+ "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/pangomm"
+ ${build_generator_args}
+ --build-project pangomm
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/pangomm"
+ --force-new-ctest-process
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+endif()
+
+if(TARGET GTK2::gdkmm)
+ add_test(GTK2Targets.gdkmm ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGTK2/gdkmm"
+ "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/GTK2Targets/gdkmm"
+ ${build_generator_args}
+ --build-project gdkmm
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/GTK2Targets/gdkmm"
+ --force-new-ctest-process
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+endif()
+
+if(TARGET GTK2::gtkmm)
+ add_test(GTK2Targets.gtkmm ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGTK2/gtkmm"
+ "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gtkmm"
+ ${build_generator_args}
+ --build-target gtkmm-target
+ --build-project gtkmm
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/FindGTK2/GTK2Targets/gtkmm"
+ --force-new-ctest-process
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+endif()
diff --git a/Tests/FindGTK2/atk/CMakeLists.txt b/Tests/FindGTK2/atk/CMakeLists.txt
new file mode 100644
index 000000000..be37957ed
--- /dev/null
+++ b/Tests/FindGTK2/atk/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(atk C)
+
+find_package(GTK2 COMPONENTS gtk REQUIRED)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_executable(atk WIN32 main.c)
+target_link_libraries(atk GTK2::atk)
diff --git a/Tests/FindGTK2/atk/main.c b/Tests/FindGTK2/atk/main.c
new file mode 100644
index 000000000..e25030ebd
--- /dev/null
+++ b/Tests/FindGTK2/atk/main.c
@@ -0,0 +1,7 @@
+#include <atk/atk.h>
+
+int main(int argc, char *argv[])
+{
+ const gchar *name = atk_get_toolkit_name();
+ return 0;
+}
diff --git a/Tests/FindGTK2/atkmm/CMakeLists.txt b/Tests/FindGTK2/atkmm/CMakeLists.txt
new file mode 100644
index 000000000..e8320b533
--- /dev/null
+++ b/Tests/FindGTK2/atkmm/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(atkmm CXX)
+
+find_package(GTK2 COMPONENTS gtk gtkmm REQUIRED)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_executable(atkmm WIN32 main.cpp)
+target_link_libraries(atkmm GTK2::atkmm)
diff --git a/Tests/FindGTK2/atkmm/main.cpp b/Tests/FindGTK2/atkmm/main.cpp
new file mode 100644
index 000000000..f455c7a96
--- /dev/null
+++ b/Tests/FindGTK2/atkmm/main.cpp
@@ -0,0 +1,8 @@
+#include <atkmm.h>
+#include <atkmm/init.h>
+
+int main(int argc, char *argv[])
+{
+ Atk::init();
+ return 0;
+}
diff --git a/Tests/FindGTK2/cairo/CMakeLists.txt b/Tests/FindGTK2/cairo/CMakeLists.txt
new file mode 100644
index 000000000..97a736944
--- /dev/null
+++ b/Tests/FindGTK2/cairo/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(cairo C)
+
+find_package(GTK2 COMPONENTS gtk REQUIRED)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_executable(cairo WIN32 main.c)
+target_link_libraries(cairo GTK2::cairo)
diff --git a/Tests/FindGTK2/cairo/main.c b/Tests/FindGTK2/cairo/main.c
new file mode 100644
index 000000000..1b6100117
--- /dev/null
+++ b/Tests/FindGTK2/cairo/main.c
@@ -0,0 +1,52 @@
+/* Taken from http://cairographics.org/samples/ */
+
+
+#include <cairo.h>
+#include <math.h>
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+ char *filename;
+ if (argc != 2)
+ {
+ fprintf (stderr, "Usage: %s OUTPUT_FILENAME\n", argv[0]);
+ return 1;
+ }
+ filename = argv[1];
+ double xc = 128.0;
+ double yc = 128.0;
+ double radius = 100.0;
+ double angle1 = 45.0 * (M_PI/180.0); /* angles are specified */
+ double angle2 = 180.0 * (M_PI/180.0); /* in radians */
+
+ cairo_surface_t *im = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, xc * 2, yc * 2);
+ cairo_t *cr = cairo_create(im);
+
+
+ cairo_set_line_width (cr, 10.0);
+ cairo_arc (cr, xc, yc, radius, angle1, angle2);
+ cairo_stroke (cr);
+
+ /* draw helping lines */
+ cairo_set_source_rgba (cr, 1, 0.2, 0.2, 0.6);
+ cairo_set_line_width (cr, 6.0);
+
+ cairo_arc (cr, xc, yc, 10.0, 0, 2*M_PI);
+ cairo_fill (cr);
+
+ cairo_arc (cr, xc, yc, radius, angle1, angle1);
+ cairo_line_to (cr, xc, yc);
+ cairo_arc (cr, xc, yc, radius, angle2, angle2);
+ cairo_line_to (cr, xc, yc);
+ cairo_stroke (cr);
+
+ cairo_status_t status = cairo_surface_write_to_png (im, filename);
+ cairo_surface_destroy (im);
+ if (status != CAIRO_STATUS_SUCCESS) {
+ fprintf(stderr, "Could not save png to '%s'\n", filename);
+ }
+
+ cairo_destroy(cr);
+ return 0;
+}
diff --git a/Tests/FindGTK2/cairomm/CMakeLists.txt b/Tests/FindGTK2/cairomm/CMakeLists.txt
new file mode 100644
index 000000000..47a156e2c
--- /dev/null
+++ b/Tests/FindGTK2/cairomm/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(cairomm CXX)
+
+find_package(GTK2 COMPONENTS gtk gtkmm REQUIRED)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_executable(cairomm WIN32 main.cpp)
+target_link_libraries(cairomm GTK2::cairomm)
diff --git a/Tests/FindGTK2/cairomm/main.cpp b/Tests/FindGTK2/cairomm/main.cpp
new file mode 100644
index 000000000..ea8f1065c
--- /dev/null
+++ b/Tests/FindGTK2/cairomm/main.cpp
@@ -0,0 +1,62 @@
+// Taken from http://cgit.freedesktop.org/cairomm/plain/examples/surfaces/image-surface.cc
+
+
+/* M_PI is defined in math.h in the case of Microsoft Visual C++, Solaris,
+ * et. al.
+ */
+#if defined(_MSC_VER)
+#define _USE_MATH_DEFINES
+#endif
+
+#include <string>
+#include <iostream>
+#include <cairommconfig.h>
+#include <cairomm/context.h>
+#include <cairomm/surface.h>
+
+#include <cmath>
+
+int main()
+{
+ Cairo::RefPtr<Cairo::ImageSurface> surface =
+ Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, 600, 400);
+
+ Cairo::RefPtr<Cairo::Context> cr = Cairo::Context::create(surface);
+
+ cr->save(); // save the state of the context
+ cr->set_source_rgb(0.86, 0.85, 0.47);
+ cr->paint(); // fill image with the color
+ cr->restore(); // color is back to black now
+
+ cr->save();
+ // draw a border around the image
+ cr->set_line_width(20.0); // make the line wider
+ cr->rectangle(0.0, 0.0, surface->get_width(), surface->get_height());
+ cr->stroke();
+
+ cr->set_source_rgba(0.0, 0.0, 0.0, 0.7);
+ // draw a circle in the center of the image
+ cr->arc(surface->get_width() / 2.0, surface->get_height() / 2.0,
+ surface->get_height() / 4.0, 0.0, 2.0 * M_PI);
+ cr->stroke();
+
+ // draw a diagonal line
+ cr->move_to(surface->get_width() / 4.0, surface->get_height() / 4.0);
+ cr->line_to(surface->get_width() * 3.0 / 4.0, surface->get_height() * 3.0 / 4.0);
+ cr->stroke();
+ cr->restore();
+
+#ifdef CAIRO_HAS_PNG_FUNCTIONS
+
+ std::string filename = "image.png";
+ surface->write_to_png(filename);
+
+ std::cout << "Wrote png file \"" << filename << "\"" << std::endl;
+
+#else
+
+ std::cout << "You must compile cairo with PNG support for this example to work."
+ << std::endl;
+
+#endif
+}
diff --git a/Tests/FindGTK2/gdk/CMakeLists.txt b/Tests/FindGTK2/gdk/CMakeLists.txt
new file mode 100644
index 000000000..f4852368c
--- /dev/null
+++ b/Tests/FindGTK2/gdk/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(gdk C)
+
+find_package(GTK2 COMPONENTS gtk REQUIRED)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_executable(gdk WIN32 main.c)
+target_link_libraries(gdk GTK2::gdk)
diff --git a/Tests/FindGTK2/gdk/main.c b/Tests/FindGTK2/gdk/main.c
new file mode 100644
index 000000000..ac1bd4b59
--- /dev/null
+++ b/Tests/FindGTK2/gdk/main.c
@@ -0,0 +1,7 @@
+#include <gdk/gdk.h>
+
+int main(int argc, char *argv[])
+{
+ gdk_init(argc, argv);
+ return 0;
+}
diff --git a/Tests/FindGTK2/gdk_pixbuf/CMakeLists.txt b/Tests/FindGTK2/gdk_pixbuf/CMakeLists.txt
new file mode 100644
index 000000000..004e82e8a
--- /dev/null
+++ b/Tests/FindGTK2/gdk_pixbuf/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(gdk_pixbuf C)
+
+find_package(GTK2 COMPONENTS gtk REQUIRED)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_executable(gdk_pixbuf WIN32 main.c)
+target_link_libraries(gdk_pixbuf GTK2::gdk_pixbuf)
diff --git a/Tests/FindGTK2/gdk_pixbuf/main.c b/Tests/FindGTK2/gdk_pixbuf/main.c
new file mode 100644
index 000000000..e42b83e86
--- /dev/null
+++ b/Tests/FindGTK2/gdk_pixbuf/main.c
@@ -0,0 +1,10 @@
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+int main(int argc, char *argv[])
+{
+ const char *version = gdk_pixbuf_version;
+ const guint major = gdk_pixbuf_major_version;
+ const guint minor = gdk_pixbuf_minor_version;
+ const guint micro = gdk_pixbuf_micro_version;
+ return 0;
+}
diff --git a/Tests/FindGTK2/gdkmm/CMakeLists.txt b/Tests/FindGTK2/gdkmm/CMakeLists.txt
new file mode 100644
index 000000000..a54fc4f13
--- /dev/null
+++ b/Tests/FindGTK2/gdkmm/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(gdkmm CXX)
+
+find_package(GTK2 COMPONENTS gtk gtkmm REQUIRED)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_executable(gdkmm WIN32 main.cpp)
+target_link_libraries(gdkmm GTK2::gdkmm)
diff --git a/Tests/FindGTK2/gdkmm/main.cpp b/Tests/FindGTK2/gdkmm/main.cpp
new file mode 100644
index 000000000..935bcc42c
--- /dev/null
+++ b/Tests/FindGTK2/gdkmm/main.cpp
@@ -0,0 +1,7 @@
+#include <gdkmm.h>
+
+int main(int argc, char *argv[])
+{
+ Gdk::Color red = Gdk::Color("red");
+ return 0;
+}
diff --git a/Tests/FindGTK2/gio/CMakeLists.txt b/Tests/FindGTK2/gio/CMakeLists.txt
new file mode 100644
index 000000000..db9cdd00a
--- /dev/null
+++ b/Tests/FindGTK2/gio/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(gio C)
+
+find_package(GTK2 COMPONENTS gtk REQUIRED)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_executable(gio WIN32 main.c)
+target_link_libraries(gio GTK2::gio)
diff --git a/Tests/FindGTK2/gio/main.c b/Tests/FindGTK2/gio/main.c
new file mode 100644
index 000000000..13f4304a2
--- /dev/null
+++ b/Tests/FindGTK2/gio/main.c
@@ -0,0 +1,8 @@
+#include <gio/gio.h>
+
+int main(int argc, char *argv[])
+{
+ GFile *file = g_file_new_for_path("path");
+ g_object_unref(file);
+ return 0;
+}
diff --git a/Tests/FindGTK2/giomm/CMakeLists.txt b/Tests/FindGTK2/giomm/CMakeLists.txt
new file mode 100644
index 000000000..46cfef50a
--- /dev/null
+++ b/Tests/FindGTK2/giomm/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(giomm CXX)
+
+find_package(GTK2 COMPONENTS gtk gtkmm REQUIRED)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_executable(giomm WIN32 main.cpp)
+target_link_libraries(giomm GTK2::giomm)
diff --git a/Tests/FindGTK2/giomm/main.cpp b/Tests/FindGTK2/giomm/main.cpp
new file mode 100644
index 000000000..8303ba9ec
--- /dev/null
+++ b/Tests/FindGTK2/giomm/main.cpp
@@ -0,0 +1,7 @@
+#include <giomm.h>
+
+int main(int argc, char *argv[])
+{
+ Glib::RefPtr<Gio::File> f = Gio::File::create_for_path("path");
+ return 0;
+}
diff --git a/Tests/FindGTK2/glib/CMakeLists.txt b/Tests/FindGTK2/glib/CMakeLists.txt
new file mode 100644
index 000000000..1aa73ff16
--- /dev/null
+++ b/Tests/FindGTK2/glib/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(glib C)
+
+find_package(GTK2 COMPONENTS gtk REQUIRED)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_executable(glib WIN32 main.c)
+target_link_libraries(glib GTK2::glib)
diff --git a/Tests/FindGTK2/glib/main.c b/Tests/FindGTK2/glib/main.c
new file mode 100644
index 000000000..80d0554e4
--- /dev/null
+++ b/Tests/FindGTK2/glib/main.c
@@ -0,0 +1,11 @@
+#include <glib.h>
+
+int main(int argc, char *argv[])
+{
+ if (!g_file_test("file", G_FILE_TEST_EXISTS)) {
+ g_print("File not found. \n");
+ } else {
+ g_print("File found. \n");
+ }
+ return 0;
+}
diff --git a/Tests/FindGTK2/glibmm/CMakeLists.txt b/Tests/FindGTK2/glibmm/CMakeLists.txt
new file mode 100644
index 000000000..af8ddcf27
--- /dev/null
+++ b/Tests/FindGTK2/glibmm/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(glibmm CXX)
+
+find_package(GTK2 COMPONENTS gtk gtkmm REQUIRED)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_executable(glibmm WIN32 main.cpp)
+target_link_libraries(glibmm GTK2::glibmm)
diff --git a/Tests/FindGTK2/glibmm/main.cpp b/Tests/FindGTK2/glibmm/main.cpp
new file mode 100644
index 000000000..0e8cdae7d
--- /dev/null
+++ b/Tests/FindGTK2/glibmm/main.cpp
@@ -0,0 +1,7 @@
+#include <glibmm/init.h>
+
+int main(int, char**)
+{
+ Glib::init();
+ return 0;
+}
diff --git a/Tests/FindGTK2/gmodule/CMakeLists.txt b/Tests/FindGTK2/gmodule/CMakeLists.txt
new file mode 100644
index 000000000..9717da8d5
--- /dev/null
+++ b/Tests/FindGTK2/gmodule/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(gmodule C)
+
+find_package(GTK2 COMPONENTS gtk REQUIRED)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_executable(gmodule WIN32 main.c)
+target_link_libraries(gmodule GTK2::gmodule)
diff --git a/Tests/FindGTK2/gmodule/main.c b/Tests/FindGTK2/gmodule/main.c
new file mode 100644
index 000000000..5c85a6f98
--- /dev/null
+++ b/Tests/FindGTK2/gmodule/main.c
@@ -0,0 +1,7 @@
+#include <gmodule.h>
+
+int main(int argc, char *argv[])
+{
+ gboolean b = g_module_supported();
+ return 0;
+}
diff --git a/Tests/FindGTK2/gobject/CMakeLists.txt b/Tests/FindGTK2/gobject/CMakeLists.txt
new file mode 100644
index 000000000..c51fd4dee
--- /dev/null
+++ b/Tests/FindGTK2/gobject/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(gobject C)
+
+find_package(GTK2 COMPONENTS gtk REQUIRED)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_executable(gobject WIN32 main.c)
+target_link_libraries(gobject GTK2::gobject)
diff --git a/Tests/FindGTK2/gobject/main.c b/Tests/FindGTK2/gobject/main.c
new file mode 100644
index 000000000..d3e13f9e5
--- /dev/null
+++ b/Tests/FindGTK2/gobject/main.c
@@ -0,0 +1,72 @@
+/* Taken from https://developer.gnome.org/gobject/stable/chapter-gobject.html */
+
+
+#include <glib-object.h>
+
+
+#define MAMAN_TYPE_BAR (maman_bar_get_type ())
+#define MAMAN_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_TYPE_BAR, MamanBar))
+#define MAMAN_IS_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_TYPE_BAR))
+#define MAMAN_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MAMAN_TYPE_BAR, MamanBarClass))
+#define MAMAN_IS_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MAMAN_TYPE_BAR))
+#define MAMAN_BAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MAMAN_TYPE_BAR, MamanBarClass))
+
+typedef struct _MamanBar MamanBar;
+typedef struct _MamanBarClass MamanBarClass;
+
+struct _MamanBar
+{
+ GObject parent_instance;
+
+ /* instance members */
+};
+
+struct _MamanBarClass
+{
+ GObjectClass parent_class;
+
+ /* class members */
+};
+
+/* will create maman_bar_get_type and set maman_bar_parent_class */
+G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT);
+
+static GObject *
+maman_bar_constructor (GType gtype,
+ guint n_properties,
+ GObjectConstructParam *properties)
+{
+ GObject *obj;
+
+ {
+ /* Always chain up to the parent constructor */
+ obj = G_OBJECT_CLASS (maman_bar_parent_class)->constructor (gtype, n_properties, properties);
+ }
+
+ /* update the object state depending on constructor properties */
+
+ return obj;
+}
+
+static void
+maman_bar_class_init (MamanBarClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->constructor = maman_bar_constructor;
+}
+
+static void
+maman_bar_init (MamanBar *self)
+{
+ /* initialize the object */
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
+ g_object_unref(bar);
+ return 0;
+}
diff --git a/Tests/FindGTK2/gthread/CMakeLists.txt b/Tests/FindGTK2/gthread/CMakeLists.txt
new file mode 100644
index 000000000..a90294d0a
--- /dev/null
+++ b/Tests/FindGTK2/gthread/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(gthread C)
+
+find_package(GTK2 COMPONENTS gtk REQUIRED)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_executable(gthread WIN32 main.c)
+target_link_libraries(gthread GTK2::gthread)
diff --git a/Tests/FindGTK2/gthread/main.c b/Tests/FindGTK2/gthread/main.c
new file mode 100644
index 000000000..ce68cbd6b
--- /dev/null
+++ b/Tests/FindGTK2/gthread/main.c
@@ -0,0 +1,7 @@
+#include <glib.h>
+
+int main(int argc, char *argv[])
+{
+ g_thread_init(NULL);
+ return 0;
+}
diff --git a/Tests/FindGTK2/gtk/CMakeLists.txt b/Tests/FindGTK2/gtk/CMakeLists.txt
new file mode 100644
index 000000000..11603aec9
--- /dev/null
+++ b/Tests/FindGTK2/gtk/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(gtk C)
+
+find_package(GTK2 COMPONENTS gtk REQUIRED)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_executable(gtk WIN32 main.c)
+target_link_libraries(gtk GTK2::gtk)
+
+add_executable(gtk-all-libs WIN32 main.c)
+target_link_libraries(gtk-all-libs ${GTK2_LIBRARIES})
+target_include_directories(gtk-all-libs PRIVATE ${GTK2_INCLUDE_DIRS})
diff --git a/Tests/FindGTK2/gtk/main.c b/Tests/FindGTK2/gtk/main.c
new file mode 100644
index 000000000..309c32896
--- /dev/null
+++ b/Tests/FindGTK2/gtk/main.c
@@ -0,0 +1,15 @@
+#include <gtk/gtk.h>
+
+int main(int argc, char *argv[])
+{
+ GtkWidget *window;
+
+ gtk_init (&argc, &argv);
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_widget_show (window);
+
+ gtk_main ();
+
+ return 0;
+}
diff --git a/Tests/FindGTK2/gtkmm/CMakeLists.txt b/Tests/FindGTK2/gtkmm/CMakeLists.txt
new file mode 100644
index 000000000..32aafe2c1
--- /dev/null
+++ b/Tests/FindGTK2/gtkmm/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(gtkmm CXX)
+
+find_package(GTK2 COMPONENTS gtk gtkmm REQUIRED)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_executable(gtkmm-target WIN32 main.cpp helloworld.cpp helloworld.h)
+target_link_libraries(gtkmm-target GTK2::gtkmm)
+
+add_executable(gtkmm-all-libs WIN32 main.cpp helloworld.cpp helloworld.h)
+target_link_libraries(gtkmm-all-libs ${GTK2_LIBRARIES})
+target_include_directories(gtkmm-all-libs PRIVATE ${GTK2_INCLUDE_DIRS})
diff --git a/Tests/FindGTK2/gtkmm/helloworld.cpp b/Tests/FindGTK2/gtkmm/helloworld.cpp
new file mode 100644
index 000000000..535f44a5d
--- /dev/null
+++ b/Tests/FindGTK2/gtkmm/helloworld.cpp
@@ -0,0 +1,29 @@
+#include "helloworld.h"
+#include <iostream>
+
+HelloWorld::HelloWorld()
+ : m_button("Hello World") // creates a new button with label "Hello World".
+{
+ // Sets the border width of the window.
+ set_border_width(10);
+
+ // When the button receives the "clicked" signal, it will call the
+ // on_button_clicked() method defined below.
+ m_button.signal_clicked().connect(sigc::mem_fun(*this,
+ &HelloWorld::on_button_clicked));
+
+ // This packs the button into the Window (a container).
+ add(m_button);
+
+ // The final step is to display this newly created widget...
+ m_button.show();
+}
+
+HelloWorld::~HelloWorld()
+{
+}
+
+void HelloWorld::on_button_clicked()
+{
+ std::cout << "Hello World" << std::endl;
+}
diff --git a/Tests/FindGTK2/gtkmm/helloworld.h b/Tests/FindGTK2/gtkmm/helloworld.h
new file mode 100644
index 000000000..ab9a076b7
--- /dev/null
+++ b/Tests/FindGTK2/gtkmm/helloworld.h
@@ -0,0 +1,20 @@
+#ifndef GTKMM_EXAMPLE_HELLOWORLD_H
+#define GTKMM_EXAMPLE_HELLOWORLD_H
+
+#include <gtkmm.h>
+
+class HelloWorld : public Gtk::Window
+{
+public:
+ HelloWorld();
+ virtual ~HelloWorld();
+
+protected:
+ //Signal handlers:
+ void on_button_clicked();
+
+ //Member widgets:
+ Gtk::Button m_button;
+};
+
+#endif // GTKMM_EXAMPLE_HELLOWORLD_H
diff --git a/Tests/FindGTK2/gtkmm/main.cpp b/Tests/FindGTK2/gtkmm/main.cpp
new file mode 100644
index 000000000..5ff64d113
--- /dev/null
+++ b/Tests/FindGTK2/gtkmm/main.cpp
@@ -0,0 +1,13 @@
+#include <gtkmm.h>
+#include "helloworld.h"
+
+int main(int argc, char *argv[])
+{
+ Gtk::Main kit(argc, argv);
+
+ HelloWorld helloworld;
+ //Shows the window and returns when it is closed.
+ Gtk::Main::run(helloworld);
+
+ return 0;
+}
diff --git a/Tests/FindGTK2/pango/CMakeLists.txt b/Tests/FindGTK2/pango/CMakeLists.txt
new file mode 100644
index 000000000..af382a4c7
--- /dev/null
+++ b/Tests/FindGTK2/pango/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(pango C)
+
+find_package(GTK2 COMPONENTS gtk REQUIRED)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_executable(pango WIN32 main.c)
+target_link_libraries(pango GTK2::pango)
diff --git a/Tests/FindGTK2/pango/main.c b/Tests/FindGTK2/pango/main.c
new file mode 100644
index 000000000..ef87ce447
--- /dev/null
+++ b/Tests/FindGTK2/pango/main.c
@@ -0,0 +1,7 @@
+#include <pango/pango.h>
+
+int main(int argc, char *argv[])
+{
+ gboolean ret = pango_color_parse(NULL, "#ffffff");
+ return 0;
+}
diff --git a/Tests/FindGTK2/pangocairo/CMakeLists.txt b/Tests/FindGTK2/pangocairo/CMakeLists.txt
new file mode 100644
index 000000000..8f61379b3
--- /dev/null
+++ b/Tests/FindGTK2/pangocairo/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(pangocairo C)
+
+find_package(GTK2 COMPONENTS gtk REQUIRED)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_executable(pangocairo WIN32 main.c)
+target_link_libraries(pangocairo GTK2::pangocairo m)
diff --git a/Tests/FindGTK2/pangocairo/main.c b/Tests/FindGTK2/pangocairo/main.c
new file mode 100644
index 000000000..78268d6f0
--- /dev/null
+++ b/Tests/FindGTK2/pangocairo/main.c
@@ -0,0 +1,72 @@
+/* Taken from https://developer.gnome.org/pango/stable/pango-Cairo-Rendering.html */
+
+
+#include <math.h>
+#include <pango/pangocairo.h>
+static void
+draw_text (cairo_t *cr)
+{
+#define RADIUS 150
+#define N_WORDS 10
+#define FONT "Sans Bold 27"
+ PangoLayout *layout;
+ PangoFontDescription *desc;
+ int i;
+ /* Center coordinates on the middle of the region we are drawing
+ */
+ cairo_translate (cr, RADIUS, RADIUS);
+ /* Create a PangoLayout, set the font and text */
+ layout = pango_cairo_create_layout (cr);
+ pango_layout_set_text (layout, "Text", -1);
+ desc = pango_font_description_from_string (FONT);
+ pango_layout_set_font_description (layout, desc);
+ pango_font_description_free (desc);
+ /* Draw the layout N_WORDS times in a circle */
+ for (i = 0; i < N_WORDS; i++)
+ {
+ int width, height;
+ double angle = (360. * i) / N_WORDS;
+ double red;
+ cairo_save (cr);
+ /* Gradient from red at angle == 60 to blue at angle == 240 */
+ red = (1 + cos ((angle - 60) * G_PI / 180.)) / 2;
+ cairo_set_source_rgb (cr, red, 0, 1.0 - red);
+ cairo_rotate (cr, angle * G_PI / 180.);
+ /* Inform Pango to re-layout the text with the new transformation */
+ pango_cairo_update_layout (cr, layout);
+ pango_layout_get_size (layout, &width, &height);
+ cairo_move_to (cr, - ((double)width / PANGO_SCALE) / 2, - RADIUS);
+ pango_cairo_show_layout (cr, layout);
+ cairo_restore (cr);
+ }
+ /* free the layout object */
+ g_object_unref (layout);
+}
+int main (int argc, char **argv)
+{
+ cairo_t *cr;
+ char *filename;
+ cairo_status_t status;
+ cairo_surface_t *surface;
+ if (argc != 2)
+ {
+ g_printerr ("Usage: cairosimple OUTPUT_FILENAME\n");
+ return 1;
+ }
+ filename = argv[1];
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ 2 * RADIUS, 2 * RADIUS);
+ cr = cairo_create (surface);
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
+ cairo_paint (cr);
+ draw_text (cr);
+ cairo_destroy (cr);
+ status = cairo_surface_write_to_png (surface, filename);
+ cairo_surface_destroy (surface);
+ if (status != CAIRO_STATUS_SUCCESS)
+ {
+ g_printerr ("Could not save png to '%s'\n", filename);
+ return 1;
+ }
+ return 0;
+}
diff --git a/Tests/FindGTK2/pangoft2/CMakeLists.txt b/Tests/FindGTK2/pangoft2/CMakeLists.txt
new file mode 100644
index 000000000..0f84c7fdf
--- /dev/null
+++ b/Tests/FindGTK2/pangoft2/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(pangoft2 C)
+
+find_package(GTK2 COMPONENTS gtk REQUIRED)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_executable(pangoft2 WIN32 main.c)
+target_link_libraries(pangoft2 GTK2::pangoft2)
diff --git a/Tests/FindGTK2/pangoft2/main.c b/Tests/FindGTK2/pangoft2/main.c
new file mode 100644
index 000000000..cf3459ecf
--- /dev/null
+++ b/Tests/FindGTK2/pangoft2/main.c
@@ -0,0 +1,8 @@
+#include <pango/pangoft2.h>
+
+int main(int argc, char *argv[])
+{
+ PangoFontMap* pfm = pango_ft2_font_map_new();
+ g_object_unref(pfm);
+ return 0;
+}
diff --git a/Tests/FindGTK2/pangomm/CMakeLists.txt b/Tests/FindGTK2/pangomm/CMakeLists.txt
new file mode 100644
index 000000000..3650c5080
--- /dev/null
+++ b/Tests/FindGTK2/pangomm/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(pangomm CXX)
+
+find_package(GTK2 COMPONENTS gtk gtkmm REQUIRED)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_executable(pangomm WIN32 main.cpp)
+target_link_libraries(pangomm GTK2::pangomm)
diff --git a/Tests/FindGTK2/pangomm/main.cpp b/Tests/FindGTK2/pangomm/main.cpp
new file mode 100644
index 000000000..32ec914e7
--- /dev/null
+++ b/Tests/FindGTK2/pangomm/main.cpp
@@ -0,0 +1,8 @@
+#include <pangomm.h>
+#include <pangomm/init.h>
+
+int main(int argc, char *argv[])
+{
+ Pango::init();
+ return 0;
+}
diff --git a/Tests/FindGTK2/pangoxft/CMakeLists.txt b/Tests/FindGTK2/pangoxft/CMakeLists.txt
new file mode 100644
index 000000000..0db16b153
--- /dev/null
+++ b/Tests/FindGTK2/pangoxft/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(pangoxft C)
+
+find_package(GTK2 COMPONENTS gtk REQUIRED)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_executable(pangoxft WIN32 main.c)
+target_link_libraries(pangoxft GTK2::pangoxft)
diff --git a/Tests/FindGTK2/pangoxft/main.c b/Tests/FindGTK2/pangoxft/main.c
new file mode 100644
index 000000000..cb04f6185
--- /dev/null
+++ b/Tests/FindGTK2/pangoxft/main.c
@@ -0,0 +1,7 @@
+#include <pango/pangoxft.h>
+
+int main(int argc, char *argv[])
+{
+ pango_xft_get_context(NULL, 0);
+ return 0;
+}
diff --git a/Tests/FindGTK2/sigc++/CMakeLists.txt b/Tests/FindGTK2/sigc++/CMakeLists.txt
new file mode 100644
index 000000000..f830b81b7
--- /dev/null
+++ b/Tests/FindGTK2/sigc++/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(sigc++ CXX)
+
+find_package(GTK2 COMPONENTS gtk gtkmm REQUIRED)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_executable(sigc++ WIN32 main.cpp)
+target_link_libraries(sigc++ GTK2::sigc++)
diff --git a/Tests/FindGTK2/sigc++/main.cpp b/Tests/FindGTK2/sigc++/main.cpp
new file mode 100644
index 000000000..78428e76b
--- /dev/null
+++ b/Tests/FindGTK2/sigc++/main.cpp
@@ -0,0 +1,30 @@
+// Taken from https://developer.gnome.org/libsigc++-tutorial/stable/ch02.html
+
+
+#include <sigc++/sigc++.h>
+#include <iostream>
+
+class AlienDetector
+{
+public:
+ AlienDetector() {}
+
+ void run() {}
+
+ sigc::signal<void> signal_detected;
+};
+
+void warn_people()
+{
+ std::cout << "There are aliens in the carpark!" << std::endl;
+}
+
+int main()
+{
+ AlienDetector mydetector;
+ mydetector.signal_detected.connect( sigc::ptr_fun(warn_people) );
+
+ mydetector.run();
+
+ return 0;
+}
diff --git a/Tests/FindGTest/CMakeLists.txt b/Tests/FindGTest/CMakeLists.txt
new file mode 100644
index 000000000..cbc92b144
--- /dev/null
+++ b/Tests/FindGTest/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_test(NAME FindGTest.Test COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGTest/Test"
+ "${CMake_BINARY_DIR}/Tests/FindGTest/Test"
+ ${build_generator_args}
+ --build-project TestFindGTest
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
diff --git a/Tests/FindGTest/Test/CMakeLists.txt b/Tests/FindGTest/Test/CMakeLists.txt
new file mode 100644
index 000000000..99368ac71
--- /dev/null
+++ b/Tests/FindGTest/Test/CMakeLists.txt
@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 3.1)
+project(TestFindGTest CXX)
+include(CTest)
+
+# CMake does not actually provide FindGTest publicly.
+set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../../Source/Modules)
+
+find_package(GTest REQUIRED)
+
+add_executable(test_gtest_tgt main.cxx)
+target_link_libraries(test_gtest_tgt GTest::Main)
+add_test(NAME test_gtest_tgt COMMAND test_gtest_tgt)
+
+add_executable(test_gtest_var main.cxx)
+target_include_directories(test_gtest_var PRIVATE ${GTEST_INCLUDE_DIRS})
+target_link_libraries(test_gtest_var PRIVATE ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
+add_test(NAME test_gtest_var COMMAND test_gtest_var)
diff --git a/Tests/FindGTest/Test/main.cxx b/Tests/FindGTest/Test/main.cxx
new file mode 100644
index 000000000..0572a5ddc
--- /dev/null
+++ b/Tests/FindGTest/Test/main.cxx
@@ -0,0 +1,6 @@
+#include <gtest/gtest.h>
+
+TEST(FindCMake, LinksAndRuns)
+{
+ ASSERT_TRUE(true);
+}
diff --git a/Tests/FindJsonCpp/CMakeLists.txt b/Tests/FindJsonCpp/CMakeLists.txt
new file mode 100644
index 000000000..9a1fa385e
--- /dev/null
+++ b/Tests/FindJsonCpp/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_test(NAME FindJsonCpp.Test COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindJsonCpp/Test"
+ "${CMake_BINARY_DIR}/Tests/FindJsonCpp/Test"
+ ${build_generator_args}
+ --build-project TestFindJsonCpp
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
diff --git a/Tests/FindJsonCpp/Test/CMakeLists.txt b/Tests/FindJsonCpp/Test/CMakeLists.txt
new file mode 100644
index 000000000..d1dc647b3
--- /dev/null
+++ b/Tests/FindJsonCpp/Test/CMakeLists.txt
@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 3.1)
+project(TestFindJsonCpp CXX)
+include(CTest)
+
+# CMake does not actually provide FindJsonCpp publicly.
+set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../../Source/Modules)
+
+find_package(JsonCpp REQUIRED)
+
+add_executable(test_jsoncpp_tgt main.cxx)
+target_link_libraries(test_jsoncpp_tgt JsonCpp::JsonCpp)
+add_test(NAME test_jsoncpp_tgt COMMAND test_jsoncpp_tgt)
+
+add_executable(test_jsoncpp_var main.cxx)
+target_include_directories(test_jsoncpp_var PRIVATE ${JsonCpp_INCLUDE_DIRS})
+target_link_libraries(test_jsoncpp_var PRIVATE ${JsonCpp_LIBRARIES})
+add_test(NAME test_jsoncpp_var COMMAND test_jsoncpp_var)
diff --git a/Tests/FindJsonCpp/Test/main.cxx b/Tests/FindJsonCpp/Test/main.cxx
new file mode 100644
index 000000000..0fefe32a1
--- /dev/null
+++ b/Tests/FindJsonCpp/Test/main.cxx
@@ -0,0 +1,8 @@
+#include <json/json.h>
+
+int main()
+{
+ int zero = 0;
+ Json::Value value(zero);
+ return value.asInt();
+}
diff --git a/Tests/FindMatlab/basic_checks/CMakeLists.txt b/Tests/FindMatlab/basic_checks/CMakeLists.txt
new file mode 100644
index 000000000..bf5442767
--- /dev/null
+++ b/Tests/FindMatlab/basic_checks/CMakeLists.txt
@@ -0,0 +1,57 @@
+
+cmake_minimum_required (VERSION 2.8.12)
+enable_testing()
+project(basic_checks)
+
+set(MATLAB_FIND_DEBUG TRUE)
+
+# the success of the following command is dependent on the current configuration:
+# - on 32bits builds (cmake is building with 32 bits), it looks for 32 bits Matlab
+# - on 64bits builds (cmake is building with 64 bits), it looks for 64 bits Matlab
+find_package(Matlab REQUIRED COMPONENTS MX_LIBRARY MAIN_PROGRAM)
+
+
+
+matlab_add_mex(
+ # target name
+ NAME cmake_matlab_test_wrapper1
+ # output name
+ OUTPUT_NAME cmake_matlab_mex1
+ SRC ${CMAKE_CURRENT_SOURCE_DIR}/../matlab_wrapper1.cpp
+ DOCUMENTATION ${CMAKE_CURRENT_SOURCE_DIR}/../help_text1.m.txt
+ )
+
+
+matlab_add_unit_test(
+ NAME ${PROJECT_NAME}_matlabtest-1
+ TIMEOUT 90
+ UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_matlab_unit_tests1.m
+ ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper1>
+ )
+
+matlab_add_unit_test(
+ NAME ${PROJECT_NAME}_matlabtest-2
+ TIMEOUT 15
+ UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_matlab_unit_tests_timeout.m
+ ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper1>
+ )
+set_tests_properties(${PROJECT_NAME}_matlabtest-2 PROPERTIES WILL_FAIL TRUE)
+
+
+# testing the test without the unittest framework of Matlab
+matlab_add_unit_test(
+ NAME ${PROJECT_NAME}_matlabtest-3
+ TIMEOUT 30
+ NO_UNITTEST_FRAMEWORK
+ UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_matlab_unit_tests2.m
+ ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper1>
+ )
+
+matlab_add_unit_test(
+ NAME ${PROJECT_NAME}_matlabtest-4
+ TIMEOUT 30
+ NO_UNITTEST_FRAMEWORK
+ UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_matlab_unit_tests3.m
+ ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper1>
+ )
+set_tests_properties(${PROJECT_NAME}_matlabtest-4 PROPERTIES WILL_FAIL TRUE)
diff --git a/Tests/FindMatlab/cmake_matlab_unit_tests1.m b/Tests/FindMatlab/cmake_matlab_unit_tests1.m
new file mode 100644
index 000000000..2371c3a64
--- /dev/null
+++ b/Tests/FindMatlab/cmake_matlab_unit_tests1.m
@@ -0,0 +1,33 @@
+
+classdef cmake_matlab_unit_tests1 < matlab.unittest.TestCase
+ % some simple unit test for CMake Matlab wrapper
+ properties
+ end
+
+ methods (Test)
+ function testDummyCall(testCase)
+ % very simple call test
+ cmake_matlab_mex1(rand(3,3));
+ end
+
+ function testDummyCall2(testCase)
+ % very simple call test 2
+ ret = cmake_matlab_mex1(rand(3,3));
+ testCase.verifyEqual(size(ret), size(rand(3,3)));
+
+ testCase.verifyEqual(size(cmake_matlab_mex1(rand(4,3))), [4,3] );
+ end
+
+ function testFailTest(testCase)
+ testCase.verifyError(@() cmake_matlab_mex1(10), 'cmake_matlab:configuration');
+ testCase.verifyError(@() cmake_matlab_mex1([10]), 'cmake_matlab:configuration');
+ end
+
+ function testHelpContent(testCase)
+ % testing the help feature
+ testCase.verifySubstring(evalc('help cmake_matlab_mex1'), 'Dummy matlab extension in cmake');
+ end
+
+
+ end
+end
diff --git a/Tests/FindMatlab/cmake_matlab_unit_tests2.m b/Tests/FindMatlab/cmake_matlab_unit_tests2.m
new file mode 100644
index 000000000..7a8a342de
--- /dev/null
+++ b/Tests/FindMatlab/cmake_matlab_unit_tests2.m
@@ -0,0 +1,6 @@
+
+ret = cmake_matlab_mex1(rand(3,3));
+
+if(size(ret) ~= size(rand(3,3)))
+ error('Dimension mismatch!');
+end
diff --git a/Tests/FindMatlab/cmake_matlab_unit_tests3.m b/Tests/FindMatlab/cmake_matlab_unit_tests3.m
new file mode 100644
index 000000000..2639325be
--- /dev/null
+++ b/Tests/FindMatlab/cmake_matlab_unit_tests3.m
@@ -0,0 +1,5 @@
+
+cmake_matlab_mex1(10);
+
+% should not reach this point
+exit(0);
diff --git a/Tests/FindMatlab/cmake_matlab_unit_tests_timeout.m b/Tests/FindMatlab/cmake_matlab_unit_tests_timeout.m
new file mode 100644
index 000000000..11d5e9ebe
--- /dev/null
+++ b/Tests/FindMatlab/cmake_matlab_unit_tests_timeout.m
@@ -0,0 +1,16 @@
+
+classdef cmake_matlab_unit_tests_timeout < matlab.unittest.TestCase
+ % timeout tests
+
+ properties
+ end
+
+ methods (Test)
+ function testCallHangsShouldBeTimedOut(testCase)
+ cmake_matlab_mex1(rand(3,3));
+ disp('Will now wait.');
+ disp('Testing the cmake Matlab package timeout - do not kill');
+ pause(20); % supposed to be killed after 15s
+ end
+ end
+end
diff --git a/Tests/FindMatlab/help_text1.m.txt b/Tests/FindMatlab/help_text1.m.txt
new file mode 100644
index 000000000..a924355d7
--- /dev/null
+++ b/Tests/FindMatlab/help_text1.m.txt
@@ -0,0 +1,2 @@
+% Dummy matlab extension in cmake
+function ret = cmake_matlab_mex1(X)
diff --git a/Tests/FindMatlab/matlab_wrapper1.cpp b/Tests/FindMatlab/matlab_wrapper1.cpp
new file mode 100644
index 000000000..4149bb954
--- /dev/null
+++ b/Tests/FindMatlab/matlab_wrapper1.cpp
@@ -0,0 +1,26 @@
+
+// simple workaround to some compiler specific problems
+// see http://stackoverflow.com/questions/22367516/mex-compile-error-unknown-type-name-char16-t/23281916#23281916
+#include <algorithm>
+
+#include "mex.h"
+
+// this test should return a matrix of 10 x 10 and should check some of the arguments
+
+void mexFunction(const int nlhs, mxArray *plhs[], const int nrhs, const mxArray *prhs[])
+{
+ if(nrhs != 1)
+ {
+ mexErrMsgTxt("Incorrect arguments");
+ }
+
+ size_t dim1 = mxGetM(prhs[0]);
+ size_t dim2 = mxGetN(prhs[0]);
+
+ if(dim1 == 1 || dim2 == 1)
+ {
+ mexErrMsgIdAndTxt("cmake_matlab:configuration", "Incorrect arguments");
+ }
+
+ plhs[0] = mxCreateNumericMatrix(dim1, dim2, mxGetClassID(prhs[0]), mxREAL);
+}
diff --git a/Tests/FindMatlab/versions_checks/CMakeLists.txt b/Tests/FindMatlab/versions_checks/CMakeLists.txt
new file mode 100644
index 000000000..5d20685c2
--- /dev/null
+++ b/Tests/FindMatlab/versions_checks/CMakeLists.txt
@@ -0,0 +1,52 @@
+
+cmake_minimum_required (VERSION 2.8.12)
+enable_testing()
+project(versions_checks)
+
+set(MATLAB_FIND_DEBUG TRUE)
+set(MATLAB_ADDITIONAL_VERSIONS
+ "dummy=14.9")
+
+# the success of the following command is dependent on the current configuration
+# in this case, we are only interested in the version macros
+find_package(Matlab)
+
+
+
+if(NOT COMMAND matlab_get_version_from_release_name)
+ message(FATAL_ERROR "The macro matlab_get_version_from_release_name should be defined")
+endif()
+
+if(NOT COMMAND matlab_get_release_name_from_version)
+ message(FATAL_ERROR "The macro matlab_get_release_name_from_version should be defined")
+endif()
+
+
+# matlab_get_release_name_from_version
+matlab_get_release_name_from_version("7.13" release_name)
+if(NOT release_name STREQUAL "R2011b")
+ message(FATAL_ERROR "version 7.13 does not give release R2011b : '${release_name}' != R2011b")
+endif()
+
+matlab_get_release_name_from_version("14.9" release_name)
+if(NOT release_name STREQUAL "dummy")
+ message(FATAL_ERROR "version 14.9 does not give release dummy : '${release_name}' != dummy")
+endif()
+
+matlab_get_release_name_from_version("14.10" release_name)
+if(NOT release_name STREQUAL "")
+ message(FATAL_ERROR "version 14.10 does not give empty release: '${release_name}' != ''")
+endif()
+
+
+# matlab_get_version_from_release_name
+matlab_get_version_from_release_name("R2011a" version)
+if(NOT version STREQUAL "7.12")
+ message(FATAL_ERROR "Release R2011a does not give version 7.12 : '${version}' != 7.12")
+endif()
+
+matlab_get_version_from_release_name("dummy" version)
+#message(FATAL_ERROR "versionversion = ${version}")
+if(NOT version STREQUAL "14.9")
+ message(FATAL_ERROR "Release dummy does not give version 14.9 : '${version}' != 14.9")
+endif()
diff --git a/Tests/FindOpenSSL/CMakeLists.txt b/Tests/FindOpenSSL/CMakeLists.txt
new file mode 100644
index 000000000..66b3fb299
--- /dev/null
+++ b/Tests/FindOpenSSL/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_test(NAME FindOpenSSL.rand COMMAND ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindOpenSSL/rand"
+ "${CMake_BINARY_DIR}/Tests/FindOpenSSL/rand"
+ ${build_generator_args}
+ --build-project FindOpenSSL_rand
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
diff --git a/Tests/FindOpenSSL/rand/CMakeLists.txt b/Tests/FindOpenSSL/rand/CMakeLists.txt
new file mode 100644
index 000000000..520d5d203
--- /dev/null
+++ b/Tests/FindOpenSSL/rand/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.0)
+project(FindOpenSSL_rand CXX)
+include(CTest)
+
+find_package(OpenSSL REQUIRED)
+
+add_executable(tstopensslrand_tgt main.cc)
+target_link_libraries(tstopensslrand_tgt OpenSSL::SSL)
+add_test(NAME tstopensslrand_tgt COMMAND tstopensslrand_tgt)
+
+add_executable(tstopensslrand_var main.cc)
+target_link_libraries(tstopensslrand_var ${OPENSSL_LIBRARIES})
+target_include_directories(tstopensslrand_var PRIVATE ${OPENSSL_INCLUDE_DIR})
+add_test(NAME tstopensslrand_var COMMAND tstopensslrand_var)
diff --git a/Tests/FindOpenSSL/rand/main.cc b/Tests/FindOpenSSL/rand/main.cc
new file mode 100644
index 000000000..a5d1ac097
--- /dev/null
+++ b/Tests/FindOpenSSL/rand/main.cc
@@ -0,0 +1,22 @@
+#include <openssl/rand.h>
+
+int main()
+{
+ // return value
+ int retval = 1;
+
+ // bytes buffer
+ unsigned char buf[1024];
+
+ // random bytes
+ int rezval = RAND_bytes(buf, sizeof(buf)); /* 1 succes, 0 otherwise */
+
+ // check result
+ if(rezval == 1)
+ {
+ retval = 0;
+ }
+
+ // return code
+ return retval;
+}
diff --git a/Tests/FindPNG/CMakeLists.txt b/Tests/FindPNG/CMakeLists.txt
new file mode 100644
index 000000000..c665b67b2
--- /dev/null
+++ b/Tests/FindPNG/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_test(NAME FindPNG.Test COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPNG/Test"
+ "${CMake_BINARY_DIR}/Tests/FindPNG/Test"
+ ${build_generator_args}
+ --build-project TestFindPNG
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
diff --git a/Tests/FindPNG/Test/CMakeLists.txt b/Tests/FindPNG/Test/CMakeLists.txt
new file mode 100644
index 000000000..ad50011c7
--- /dev/null
+++ b/Tests/FindPNG/Test/CMakeLists.txt
@@ -0,0 +1,16 @@
+cmake_minimum_required(VERSION 3.4)
+project(TestFindPNG C)
+include(CTest)
+
+find_package(PNG REQUIRED)
+
+add_definitions(-DCMAKE_EXPECTED_PNG_VERSION="${PNG_VERSION_STRING}")
+
+add_executable(test_tgt main.c)
+target_link_libraries(test_tgt PNG::PNG)
+add_test(NAME test_tgt COMMAND test_tgt)
+
+add_executable(test_var main.c)
+target_include_directories(test_var PRIVATE ${PNG_INCLUDE_DIRS})
+target_link_libraries(test_var PRIVATE ${PNG_LIBRARIES})
+add_test(NAME test_var COMMAND test_var)
diff --git a/Tests/FindPNG/Test/main.c b/Tests/FindPNG/Test/main.c
new file mode 100644
index 000000000..27e14786b
--- /dev/null
+++ b/Tests/FindPNG/Test/main.c
@@ -0,0 +1,20 @@
+#include <assert.h>
+#include <string.h>
+#include <png.h>
+
+int main()
+{
+ png_uint_32 png_version;
+ char png_version_string[16];
+
+ png_version = png_access_version_number ();
+
+ snprintf (png_version_string, 16, "%i.%i.%i",
+ png_version / 10000,
+ (png_version % 10000) / 100,
+ png_version % 100);
+
+ assert (strcmp(png_version_string, CMAKE_EXPECTED_PNG_VERSION) == 0);
+
+ return 0;
+}
diff --git a/Tests/FindPackageModeMakefileTest/CMakeLists.txt b/Tests/FindPackageModeMakefileTest/CMakeLists.txt
index 3674f0efe..8e21c32b6 100644
--- a/Tests/FindPackageModeMakefileTest/CMakeLists.txt
+++ b/Tests/FindPackageModeMakefileTest/CMakeLists.txt
@@ -10,7 +10,7 @@ if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Makefile")
ERROR_QUIET
TIMEOUT 10)
string(TOUPPER "${makeVersionOutput}" MAKE_VERSION_OUTPUT)
- if("${MAKE_VERSION_OUTPUT}" MATCHES ".*GNU MAKE.*")
+ if("${MAKE_VERSION_OUTPUT}" MATCHES "GNU MAKE")
# build a library which we can search during the test
add_library(foo STATIC foo.cpp)
@@ -19,8 +19,16 @@ if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Makefile")
configure_file(FindFoo.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/FindFoo.cmake @ONLY)
# now set up the test:
- get_target_property(cmakeExecutable cmake LOCATION)
-
+ if (NOT CMAKE_VERSION VERSION_LESS 2.8.12)
+ file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/cmakeExecutable.mk"
+ CONTENT "CMAKE = \"$<TARGET_FILE:cmake>\"\n"
+ )
+ else()
+ get_target_property(cmakeLocation cmake LOCATION)
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cmakeExecutable.mk"
+ "CMAKE = \"${cmakeLocation}\"\n"
+ )
+ endif()
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Makefile.in ${CMAKE_CURRENT_BINARY_DIR}/ConfMakefile @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/main.cpp ${CMAKE_CURRENT_BINARY_DIR}/main.cpp COPYONLY)
diff --git a/Tests/FindPackageModeMakefileTest/Makefile.in b/Tests/FindPackageModeMakefileTest/Makefile.in
index f647901e7..8e7ff72aa 100644
--- a/Tests/FindPackageModeMakefileTest/Makefile.in
+++ b/Tests/FindPackageModeMakefileTest/Makefile.in
@@ -1,18 +1,21 @@
-CMAKE = "@cmakeExecutable@"
+
+include cmakeExecutable.mk
+
CMAKE_CURRENT_BINARY_DIR = "@CMAKE_CURRENT_BINARY_DIR@"
CMAKE_CXX_COMPILER = "@CMAKE_CXX_COMPILER@"
CMAKE_CXX_COMPILER_ID = "@CMAKE_CXX_COMPILER_ID@"
+CMAKE_CXX_FLAGS = @CMAKE_CXX_FLAGS@
CMAKE_FOO = $(CMAKE) --find-package -DCMAKE_MODULE_PATH=$(CMAKE_CURRENT_BINARY_DIR) -DNAME=Foo -DLANGUAGE=CXX -DCOMPILER_ID=$(CMAKE_CXX_COMPILER_ID)
tmp = tmp.txt
-all: clean pngtest
+all: pngtest
-main.o: main.cpp
+main.o: clean main.cpp
@$(CMAKE_FOO) -DMODE=COMPILE >$(tmp)
@foo="`cat $(tmp)`"; \
- printf '"%s" %s %s -c main.cpp\n' $(CMAKE_CXX_COMPILER) "$(CXXFLAGS)" "$$foo" >$(tmp)
+ printf '"%s" %s %s -c main.cpp\n' $(CMAKE_CXX_COMPILER) "$(CMAKE_CXX_FLAGS)" "$$foo" >$(tmp)
@cat $(tmp)
@sh $(tmp)
@rm -f $(tmp)
@@ -20,7 +23,7 @@ main.o: main.cpp
pngtest: main.o
@$(CMAKE_FOO) -DMODE=LINK >$(tmp)
@foo="`cat $(tmp)`"; \
- printf '"%s" %s %s -o pngtest main.o %s\n' $(CMAKE_CXX_COMPILER) "$(CXXFLAGS)" "$(LDFLAGS)" "$$foo" >$(tmp)
+ printf '"%s" %s %s -o pngtest main.o %s\n' $(CMAKE_CXX_COMPILER) "$(CMAKE_CXX_FLAGS)" "$(LDFLAGS)" "$$foo" >$(tmp)
@cat $(tmp)
@sh $(tmp)
@rm -f $(tmp)
diff --git a/Tests/FindPackageTest/CMakeLists.txt b/Tests/FindPackageTest/CMakeLists.txt
index a77713f27..fadd0feef 100644
--- a/Tests/FindPackageTest/CMakeLists.txt
+++ b/Tests/FindPackageTest/CMakeLists.txt
@@ -1,6 +1,9 @@
cmake_minimum_required (VERSION 2.6)
project(FindPackageTest)
+# Protect tests from running inside the default install prefix.
+set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/NotDefaultPrefix")
+
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
# Look for a package which uses FindPackageHandleStandardArgs.cmake with the
@@ -45,12 +48,18 @@ endif()
find_package(SomePackage)
if(NOT SomePackage_FOUND)
- message(SEND_ERROR "SomePackage with FOUND_VAR SomePackage_FOUND not found !")
+ message(SEND_ERROR "SomePackage not found !")
+endif()
+if(NOT SOMEPACKAGE_FOUND)
+ message(SEND_ERROR "SomePackage compatibility name SOMEPACKAGE_FOUND not set!")
endif()
find_package(UpperCasePackage)
+if(NOT UpperCasePackage_FOUND)
+ message(SEND_ERROR "UpperCasePackage not found!")
+endif()
if(NOT UPPERCASEPACKAGE_FOUND)
- message(SEND_ERROR "UpperCasePackage with FOUND_VAR UPPERCASEPACKAGE_FOUND not found !")
+ message(SEND_ERROR "SomePackage compatibility name SOMEPACKAGE_FOUND not set!")
endif()
#-----------------------------------------------------------------------------
@@ -320,23 +329,61 @@ endif()
#-----------------------------------------------------------------------------
# Test export(PACKAGE) with find_package.
+
+# Choose a unique version.
+string(REGEX REPLACE "-.*$" "" version ${CMAKE_VERSION})
+string(RANDOM LENGTH 4 ALPHABET "0123456789" v)
+set(version "${version}.${v}")
+
message(STATUS "Preparing export(PACKAGE) test project")
try_compile(EXPORTER_COMPILED
- ${FindPackageTest_BINARY_DIR}/Exporter
+ ${FindPackageTest_BINARY_DIR}/Exporter-build
${FindPackageTest_SOURCE_DIR}/Exporter
CMakeTestExportPackage dummy
+ CMAKE_FLAGS "-UCMAKE_EXPORT_NO_PACKAGE_REGISTRY"
+ -Dversion=${version}
OUTPUT_VARIABLE output)
message(STATUS "Searching for export(PACKAGE) test project")
set(CMakeTestExportPackage_DIR "" CACHE FILEPATH
"Wipe out find results for testing." FORCE)
-string(REGEX REPLACE "-.*$" "" version ${CMAKE_VERSION})
find_package(CMakeTestExportPackage 1.${version} EXACT REQUIRED)
+message(STATUS "Searching for export(PACKAGE) test project with CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY=TRUE")
+set(CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY TRUE)
+set(CMakeTestExportPackage_DIR "" CACHE FILEPATH
+ "Wipe out find results for testing." FORCE)
+find_package(CMakeTestExportPackage 1.${version} EXACT QUIET)
+if(CMakeTestExportPackage_FOUND)
+ message(SEND_ERROR "CMakeTestExportPackage should not be FOUND!")
+endif()
+unset(CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY)
+
+message(STATUS "Remove export(PACKAGE) test project")
+file(REMOVE_RECURSE ${FindPackageTest_BINARY_DIR}/Exporter-build)
+set(CMakeTestExportPackage_DIR "" CACHE FILEPATH
+ "Wipe out find results for testing." FORCE)
+find_package(CMakeTestExportPackage QUIET) # Should clean the user package cache
+#
+message(STATUS "Preparing export(PACKAGE) test project with CMAKE_EXPORT_NO_PACKAGE_REGISTRY=TRUE")
+try_compile(EXPORTER_COMPILED
+ ${FindPackageTest_BINARY_DIR}/Exporter-build
+ ${FindPackageTest_SOURCE_DIR}/Exporter
+ CMakeTestExportPackage dummy
+ CMAKE_FLAGS "-DCMAKE_EXPORT_NO_PACKAGE_REGISTRY:BOOL=TRUE"
+ -Dversion=${version}
+ OUTPUT_VARIABLE output)
+message(STATUS "Searching for export(PACKAGE) test project")
+find_package(CMakeTestExportPackage 1.${version} EXACT QUIET)
+if(CMakeTestExportPackage_FOUND)
+ message(SEND_ERROR "CMakeTestExportPackage should not be FOUND!")
+endif()
+
#-----------------------------------------------------------------------------
# Test configure_package_config_file().
include(CMakePackageConfigHelpers)
+# Generate a config file ready to be installed.
set(INCLUDE_INSTALL_DIR include )
set(SHARE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share/" )
set(CURRENT_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}" )
@@ -370,6 +417,43 @@ if(Relocatable_FOUND)
message(SEND_ERROR "Relocatable_FOUND set to TRUE !")
endif()
+# Generate a config file for the build tree.
+set(INCLUDE_INSTALL_DIR include )
+set(SHARE_INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/share/" )
+set(CURRENT_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}" )
+
+configure_package_config_file(RelocatableConfig.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/RelocatableConfig.cmake"
+ INSTALL_DESTINATION "${CMAKE_CURRENT_BINARY_DIR}"
+ PATH_VARS INCLUDE_INSTALL_DIR SHARE_INSTALL_DIR CURRENT_BUILD_DIR
+ INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}"
+ )
+
+set(Relocatable_FIND_COMPONENTS AComp BComp CComp)
+set(Relocatable_FIND_REQUIRED_BComp 1)
+include("${CMAKE_CURRENT_BINARY_DIR}/RelocatableConfig.cmake")
+
+if(NOT "${RELOC_INCLUDE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/include")
+ message(SEND_ERROR "RELOC_INCLUDE_DIR set by configure_package_config_file() is set to \"${RELOC_INCLUDE_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}/include\")")
+endif()
+
+if(NOT "${RELOC_SHARE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/share/")
+ message(SEND_ERROR "RELOC_SHARE_DIR set by configure_package_config_file() is set to \"${RELOC_SHARE_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}/share/\")")
+endif()
+
+if(NOT "${RELOC_BUILD_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
+ message(SEND_ERROR "RELOC_BUILD_DIR set by configure_package_config_file() is set to \"${RELOC_BUILD_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}\")")
+endif()
+
+if(NOT DEFINED Relocatable_FOUND)
+ message(SEND_ERROR "Relocatable_FOUND not defined !")
+endif()
+
+if(Relocatable_FOUND)
+ message(SEND_ERROR "Relocatable_FOUND set to TRUE !")
+endif()
+
+
+
#-----------------------------------------------------------------------------
# Test write_basic_config_version_file().
diff --git a/Tests/FindPackageTest/Exporter/CMakeTestExportPackageConfigVersion.cmake.in b/Tests/FindPackageTest/Exporter/CMakeTestExportPackageConfigVersion.cmake.in
index 42bd84ea8..6eac6e672 100644
--- a/Tests/FindPackageTest/Exporter/CMakeTestExportPackageConfigVersion.cmake.in
+++ b/Tests/FindPackageTest/Exporter/CMakeTestExportPackageConfigVersion.cmake.in
@@ -1,5 +1,5 @@
# Test config file.
-set(PACKAGE_VERSION "1.@CMAKE_VERSION@")
+set(PACKAGE_VERSION "1.@version@")
if("${PACKAGE_FIND_VERSION}" VERSION_EQUAL "${PACKAGE_VERSION}")
set(PACKAGE_VERSION_COMPATIBLE 1)
set(PACKAGE_VERSION_EXACT 1)
diff --git a/Tests/FindPackageTest/FindLotsOfComponents.cmake b/Tests/FindPackageTest/FindLotsOfComponents.cmake
index 9076d86ed..5d959c594 100644
--- a/Tests/FindPackageTest/FindLotsOfComponents.cmake
+++ b/Tests/FindPackageTest/FindLotsOfComponents.cmake
@@ -4,7 +4,7 @@ set(LotsOfComponents_AComp_FOUND TRUE)
set(LotsOfComponents_BComp_FOUND FALSE)
set(LotsOfComponents_CComp_FOUND TRUE)
-include(FindPackageHandleStandardArgs)
+include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
find_package_handle_standard_args(LotsOfComponents REQUIRED_VARS LOC_FOO
HANDLE_COMPONENTS)
diff --git a/Tests/FindPackageTest/FindSomePackage.cmake b/Tests/FindPackageTest/FindSomePackage.cmake
index 83d1d0e4d..746c08776 100644
--- a/Tests/FindPackageTest/FindSomePackage.cmake
+++ b/Tests/FindPackageTest/FindSomePackage.cmake
@@ -1,6 +1,5 @@
set(SOP_FOO TRUE)
-include(FindPackageHandleStandardArgs)
+include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
-find_package_handle_standard_args(SomePackage REQUIRED_VARS SOP_FOO
- FOUND_VAR SomePackage_FOUND )
+find_package_handle_standard_args(SomePackage REQUIRED_VARS SOP_FOO)
diff --git a/Tests/FindPackageTest/FindUpperCasePackage.cmake b/Tests/FindPackageTest/FindUpperCasePackage.cmake
index 66c2fea5b..5e349da5d 100644
--- a/Tests/FindPackageTest/FindUpperCasePackage.cmake
+++ b/Tests/FindPackageTest/FindUpperCasePackage.cmake
@@ -1,6 +1,5 @@
set(UCP_FOO TRUE)
-include(FindPackageHandleStandardArgs)
+include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
-find_package_handle_standard_args(UpperCasePackage REQUIRED_VARS UCP_FOO
- FOUND_VAR UPPERCASEPACKAGE_FOUND )
+find_package_handle_standard_args(UpperCasePackage REQUIRED_VARS UCP_FOO)
diff --git a/Tests/FindTIFF/CMakeLists.txt b/Tests/FindTIFF/CMakeLists.txt
new file mode 100644
index 000000000..c4e0c6a7f
--- /dev/null
+++ b/Tests/FindTIFF/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_test(NAME FindTIFF.Test COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindTIFF/Test"
+ "${CMake_BINARY_DIR}/Tests/FindTIFF/Test"
+ ${build_generator_args}
+ --build-project TestFindTIFF
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
diff --git a/Tests/FindTIFF/Test/CMakeLists.txt b/Tests/FindTIFF/Test/CMakeLists.txt
new file mode 100644
index 000000000..f17cda77f
--- /dev/null
+++ b/Tests/FindTIFF/Test/CMakeLists.txt
@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 3.1)
+project(TestFindTIFF C)
+include(CTest)
+
+# CMake does not actually provide FindTIFF publicly.
+set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../../Source/Modules)
+
+find_package(TIFF REQUIRED)
+
+add_executable(test_xercesc_tgt main.c)
+target_link_libraries(test_xercesc_tgt TIFF::TIFF)
+add_test(NAME test_xercesc_tgt COMMAND test_xercesc_tgt)
+
+add_executable(test_xercesc_var main.c)
+target_include_directories(test_xercesc_var PRIVATE ${TIFF_INCLUDE_DIRS})
+target_link_libraries(test_xercesc_var PRIVATE ${TIFF_LIBRARIES})
+add_test(NAME test_xercesc_var COMMAND test_xercesc_var)
diff --git a/Tests/FindTIFF/Test/main.c b/Tests/FindTIFF/Test/main.c
new file mode 100644
index 000000000..fc4f33757
--- /dev/null
+++ b/Tests/FindTIFF/Test/main.c
@@ -0,0 +1,12 @@
+#include <assert.h>
+#include <tiffio.h>
+
+int main()
+{
+ /* Without any TIFF file to open, test that the call fails as
+ expected. This tests that linking worked. */
+ TIFF *tiff = TIFFOpen("invalid.tiff", "r");
+ assert(!tiff);
+
+ return 0;
+}
diff --git a/Tests/FindThreads/C-only/CMakeLists.txt b/Tests/FindThreads/C-only/CMakeLists.txt
new file mode 100644
index 000000000..ab4ca0ddd
--- /dev/null
+++ b/Tests/FindThreads/C-only/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
+project(FindThreads_C-only C)
+
+set(CMAKE_THREAD_PREFER_PTHREAD On)
+find_package(Threads REQUIRED)
+
+if (NOT WIN32)
+ add_executable(thr ${CMAKE_CURRENT_SOURCE_DIR}/../../../Modules/CheckForPthreads.c)
+ target_link_libraries(thr Threads::Threads)
+endif ()
diff --git a/Tests/FindThreads/CMakeLists.txt b/Tests/FindThreads/CMakeLists.txt
new file mode 100644
index 000000000..aa9499bd8
--- /dev/null
+++ b/Tests/FindThreads/CMakeLists.txt
@@ -0,0 +1,11 @@
+foreach (_lang IN ITEMS C CXX)
+ add_test(NAME FindThreads.${_lang}-only COMMAND ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindThreads/${_lang}-only"
+ "${CMake_BINARY_DIR}/Tests/FindThreads/${_lang}-only"
+ ${build_generator_args}
+ --build-project FindThreads_${_lang}-only
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+endforeach ()
diff --git a/Tests/FindThreads/CXX-only/CMakeLists.txt b/Tests/FindThreads/CXX-only/CMakeLists.txt
new file mode 100644
index 000000000..999312322
--- /dev/null
+++ b/Tests/FindThreads/CXX-only/CMakeLists.txt
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
+project(FindThreads_CXX-only CXX)
+
+set(CMAKE_THREAD_PREFER_PTHREAD On)
+find_package(Threads REQUIRED)
+
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../../../Modules/CheckForPthreads.c
+ ${CMAKE_CURRENT_BINARY_DIR}/CheckForPthreads.cxx)
+
+if (NOT WIN32)
+ add_executable(thr ${CMAKE_CURRENT_BINARY_DIR}/CheckForPthreads.cxx)
+ target_link_libraries(thr Threads::Threads)
+endif ()
diff --git a/Tests/FindXalanC/CMakeLists.txt b/Tests/FindXalanC/CMakeLists.txt
new file mode 100644
index 000000000..787292936
--- /dev/null
+++ b/Tests/FindXalanC/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_test(NAME FindXalanC.Test COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindXalanC/Test"
+ "${CMake_BINARY_DIR}/Tests/FindXalanC/Test"
+ ${build_generator_args}
+ --build-project TestFindXalanC
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
diff --git a/Tests/FindXalanC/Test/CMakeLists.txt b/Tests/FindXalanC/Test/CMakeLists.txt
new file mode 100644
index 000000000..b445e0e10
--- /dev/null
+++ b/Tests/FindXalanC/Test/CMakeLists.txt
@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 3.1)
+project(TestFindXalanC CXX)
+include(CTest)
+
+# CMake does not actually provide FindXalanC publicly.
+set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../../Source/Modules)
+
+find_package(XalanC REQUIRED)
+
+add_executable(test_xalanc_tgt main.cxx)
+target_link_libraries(test_xalanc_tgt XalanC::XalanC)
+add_test(NAME test_xalanc_tgt COMMAND test_xalanc_tgt)
+
+add_executable(test_xalanc_var main.cxx)
+target_include_directories(test_xalanc_var PRIVATE ${XalanC_INCLUDE_DIRS})
+target_link_libraries(test_xalanc_var PRIVATE ${XalanC_LIBRARIES})
+add_test(NAME test_xalanc_var COMMAND test_xalanc_var)
diff --git a/Tests/FindXalanC/Test/main.cxx b/Tests/FindXalanC/Test/main.cxx
new file mode 100644
index 000000000..3b4a2df8e
--- /dev/null
+++ b/Tests/FindXalanC/Test/main.cxx
@@ -0,0 +1,10 @@
+#include <xercesc/util/PlatformUtils.hpp>
+#include <xalanc/XalanTransformer/XalanTransformer.hpp>
+
+int main()
+{
+ xercesc::XMLPlatformUtils::Initialize();
+ xalanc::XalanTransformer::initialize();
+ xalanc::XalanTransformer::terminate();
+ xercesc::XMLPlatformUtils::Terminate();
+}
diff --git a/Tests/FindXercesC/CMakeLists.txt b/Tests/FindXercesC/CMakeLists.txt
new file mode 100644
index 000000000..633f613e8
--- /dev/null
+++ b/Tests/FindXercesC/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_test(NAME FindXercesC.Test COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindXercesC/Test"
+ "${CMake_BINARY_DIR}/Tests/FindXercesC/Test"
+ ${build_generator_args}
+ --build-project TestFindXercesC
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
diff --git a/Tests/FindXercesC/Test/CMakeLists.txt b/Tests/FindXercesC/Test/CMakeLists.txt
new file mode 100644
index 000000000..8e7767cfd
--- /dev/null
+++ b/Tests/FindXercesC/Test/CMakeLists.txt
@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 3.1)
+project(TestFindXercesC CXX)
+include(CTest)
+
+# CMake does not actually provide FindXercesC publicly.
+set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../../Source/Modules)
+
+find_package(XercesC REQUIRED)
+
+add_executable(test_xercesc_tgt main.cxx)
+target_link_libraries(test_xercesc_tgt XercesC::XercesC)
+add_test(NAME test_xercesc_tgt COMMAND test_xercesc_tgt)
+
+add_executable(test_xercesc_var main.cxx)
+target_include_directories(test_xercesc_var PRIVATE ${XercesC_INCLUDE_DIRS})
+target_link_libraries(test_xercesc_var PRIVATE ${XercesC_LIBRARIES})
+add_test(NAME test_xercesc_var COMMAND test_xercesc_var)
diff --git a/Tests/FindXercesC/Test/main.cxx b/Tests/FindXercesC/Test/main.cxx
new file mode 100644
index 000000000..1794fa638
--- /dev/null
+++ b/Tests/FindXercesC/Test/main.cxx
@@ -0,0 +1,7 @@
+#include <xercesc/util/PlatformUtils.hpp>
+
+int main()
+{
+ xercesc::XMLPlatformUtils::Initialize();
+ xercesc::XMLPlatformUtils::Terminate();
+}
diff --git a/Tests/ForceInclude/CMakeLists.txt b/Tests/ForceInclude/CMakeLists.txt
index 5c02ebbd0..e2310543d 100644
--- a/Tests/ForceInclude/CMakeLists.txt
+++ b/Tests/ForceInclude/CMakeLists.txt
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.8.3.20110103)
project(ForceInclude C)
# Make sure the proper compiler is in use.
-if(NOT MSVC AND NOT "${CMAKE_C_COMPILER_ID}" MATCHES "^(Intel)$")
+if(NOT MSVC AND NOT CMAKE_C_COMPILER_ID STREQUAL "Intel")
message(FATAL_ERROR "The ForceInclude test works only with MSVC or Intel")
endif()
diff --git a/Tests/Fortran/CMakeLists.txt b/Tests/Fortran/CMakeLists.txt
index cda5fed3f..ecf38a605 100644
--- a/Tests/Fortran/CMakeLists.txt
+++ b/Tests/Fortran/CMakeLists.txt
@@ -1,5 +1,9 @@
-cmake_minimum_required (VERSION 2.6)
+cmake_minimum_required (VERSION 3.0)
project(testf C CXX Fortran)
+if(NOT DEFINED CMake_TEST_NESTED_MAKE_PROGRAM AND NOT CMAKE_GENERATOR MATCHES "Visual Studio")
+ set(CMake_TEST_NESTED_MAKE_PROGRAM "${CMAKE_MAKE_PROGRAM}")
+endif()
+
message("CTEST_FULL_OUTPUT ")
set(CMAKE_VERBOSE_MAKEFILE 1)
message("ENV_FLAGS = $ENV{FFLAGS}")
@@ -9,11 +13,11 @@ message("CMAKE_Fortran_COMPILER = ${CMAKE_Fortran_COMPILER}")
message("CMAKE_Fortran_FLAGS = ${CMAKE_Fortran_FLAGS}")
set(_SHARED SHARED)
-if("${CMAKE_Fortran_COMPILER_ID}" MATCHES "^(XL|VisualAge)$")
+if(CMAKE_Fortran_COMPILER_ID MATCHES "^(XL|VisualAge)$")
# We do not implement SHARED Fortran libs on AIX yet!
# Workaround: Set LINKER_LANGUAGE to C, which uses 'xlc' and Fortran implicits.
set(_SHARED STATIC)
-elseif("${CMAKE_Fortran_COMPILER_ID}" STREQUAL "GNU")
+elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
# g77 2.96 does not support shared libs on Itanium because g2c is not -fPIC
execute_process(COMMAND ${CMAKE_Fortran_COMPILER} --version
OUTPUT_VARIABLE output ERROR_VARIABLE output)
@@ -25,10 +29,10 @@ endif()
# Pick a module .def file with the properly mangled symbol name.
set(world_def "")
if(WIN32 AND NOT CYGWIN)
- if("${CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU")
+ if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
set(world_def world_gnu.def)
- elseif("${CMAKE_Fortran_COMPILER_ID}" MATCHES "Intel" OR
- "${CMAKE_GENERATOR}" MATCHES "Visual Studio") # Intel plugin
+ elseif(CMAKE_Fortran_COMPILER_ID MATCHES "Intel" OR
+ CMAKE_GENERATOR MATCHES "Visual Studio") # Intel plugin
set(world_def world_icl.def)
endif()
endif()
@@ -115,7 +119,7 @@ endfunction()
# call the test_fortran_c_interface_module function
if("${CMAKE_Fortran_COMPILER_ID}:${CMAKE_C_COMPILER_ID}" MATCHES
"(Intel:MSVC|Absoft:GNU)"
- OR ("${CMAKE_Fortran_COMPILER_ID}" MATCHES "${CMAKE_C_COMPILER_ID}" ))
+ OR (CMAKE_Fortran_COMPILER_ID MATCHES CMAKE_C_COMPILER_ID ))
test_fortran_c_interface_module()
else()
message("Fortran does not match c compiler")
@@ -124,7 +128,7 @@ else()
# hack to make g77 work after CL has been enabled
# as a languge, cmake needs language specific versions
# of these variables....
- if(WIN32 AND "${CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU")
+ if(WIN32 AND CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
set(CMAKE_CREATE_CONSOLE_EXE )
set(CMAKE_LIBRARY_PATH_FLAG "-L")
set(CMAKE_LINK_LIBRARY_FLAG "-l")
@@ -133,8 +137,8 @@ else()
# gnu and sunpro do not use the same flags here...
# however if LDFLAGS is used to set -m64 it causes odd stuf
# with the fortran build
- if( ("${CMAKE_C_COMPILER_ID}" MATCHES "GNU")
- AND ("${CMAKE_Fortran_COMPILER_ID}" MATCHES "SunPro"))
+ if( (CMAKE_C_COMPILER_ID MATCHES "GNU")
+ AND (CMAKE_Fortran_COMPILER_ID MATCHES "SunPro"))
set(CMAKE_EXE_LINKER_FLAGS "")
set(CMAKE_Fortran_FLAGS "")
endif()
@@ -164,7 +168,7 @@ if(CMAKE_Fortran_COMPILER_SUPPORTS_F90)
add_definitions(-DFOO -DBAR=1)
include_directories(${testf_SOURCE_DIR}/include)
- add_executable(test_preprocess test_preprocess.F90)
+ add_executable(test_preprocess test_preprocess.F90 test_preprocess_module.F90)
set(TEST_MODULE_DEPENDS 1)
endif()
@@ -197,14 +201,15 @@ if(TEST_MODULE_DEPENDS)
--build-two-config
--build-project ExtFort
--build-generator ${CMAKE_GENERATOR}
+ --build-generator-platform "${CMAKE_GENERATOR_PLATFORM}"
--build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
- --build-makeprogram ${CMAKE_MAKE_PROGRAM}
--build-options -DCMAKE_Fortran_COMPILER:STRING=${CMAKE_Fortran_COMPILER}
-DCMAKE_Fortran_FLAGS:STRING=${CMAKE_Fortran_FLAGS}
-DCMAKE_Fortran_FLAGS_DEBUG:STRING=${CMAKE_Fortran_FLAGS_DEBUG}
-DCMAKE_Fortran_FLAGS_RELEASE:STRING=${CMAKE_Fortran_FLAGS_RELEASE}
-DCMAKE_Fortran_FLAGS_MINSIZEREL:STRING=${CMAKE_Fortran_FLAGS_MINSIZEREL}
-DCMAKE_Fortran_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_Fortran_FLAGS_RELWITHDEBINFO}
+ -DCMAKE_MAKE_PROGRAM:FILEPATH=${CMake_TEST_NESTED_MAKE_PROGRAM}
${External_BUILD_TYPE}
VERBATIM
)
@@ -218,5 +223,6 @@ if(TEST_MODULE_DEPENDS)
endif()
add_subdirectory(Library)
+ add_subdirectory(Subdir)
add_subdirectory(Executable)
endif()
diff --git a/Tests/Fortran/Executable/CMakeLists.txt b/Tests/Fortran/Executable/CMakeLists.txt
index 55f21ad46..de08d8605 100644
--- a/Tests/Fortran/Executable/CMakeLists.txt
+++ b/Tests/Fortran/Executable/CMakeLists.txt
@@ -3,6 +3,6 @@ include_directories(${External_BINARY_DIR})
link_directories(${External_BINARY_DIR})
add_executable(subdir_exe2 main.f90)
-target_link_libraries(subdir_exe2 subdir_mods)
+target_link_libraries(subdir_exe2 subdir_mods subdir_mods2)
add_dependencies(subdir_exe2 ExternalTarget)
target_link_libraries(subdir_exe2 myext)
diff --git a/Tests/Fortran/Executable/main.f90 b/Tests/Fortran/Executable/main.f90
index f21156cda..640259c12 100644
--- a/Tests/Fortran/Executable/main.f90
+++ b/Tests/Fortran/Executable/main.f90
@@ -1,6 +1,7 @@
PROGRAM MAINF90
USE libraryModuleA
USE libraryModuleB
+ USE subdirModuleA
USE externalMod
CALL printExtModGreeting
END PROGRAM MAINF90
diff --git a/Tests/Fortran/Subdir/CMakeLists.txt b/Tests/Fortran/Subdir/CMakeLists.txt
new file mode 100644
index 000000000..52683e587
--- /dev/null
+++ b/Tests/Fortran/Subdir/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_library(subdir_mods2 subdir.f90)
+target_include_directories(subdir_mods2 INTERFACE ${CMAKE_CURRENT_BINARY_DIR})
diff --git a/Tests/Fortran/Subdir/subdir.f90 b/Tests/Fortran/Subdir/subdir.f90
new file mode 100644
index 000000000..68955f6b5
--- /dev/null
+++ b/Tests/Fortran/Subdir/subdir.f90
@@ -0,0 +1,2 @@
+MODULE subdirModuleA
+END MODULE
diff --git a/Tests/Fortran/test_preprocess.F90 b/Tests/Fortran/test_preprocess.F90
index e4f1fbe76..3a09976c5 100644
--- a/Tests/Fortran/test_preprocess.F90
+++ b/Tests/Fortran/test_preprocess.F90
@@ -46,6 +46,8 @@ PROGRAM PPTEST
#endif
! 0 ; <empty>
+USE PPAvailable
+
#include "test_preprocess.h"
END PROGRAM
diff --git a/Tests/Fortran/test_preprocess_module.F90 b/Tests/Fortran/test_preprocess_module.F90
new file mode 100644
index 000000000..5849b62b4
--- /dev/null
+++ b/Tests/Fortran/test_preprocess_module.F90
@@ -0,0 +1,5 @@
+#ifdef FOO
+MODULE PPAvailable
+! no conent
+END MODULE
+#endif
diff --git a/Tests/FortranC/CMakeLists.txt b/Tests/FortranC/CMakeLists.txt
index f33558397..79c670d6f 100644
--- a/Tests/FortranC/CMakeLists.txt
+++ b/Tests/FortranC/CMakeLists.txt
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.8)
project(FortranC C Fortran)
# Skip this test for compilers not known to be compatible.
-if(NOT ("${CMAKE_C_COMPILER_ID}" STREQUAL "${CMAKE_Fortran_COMPILER_ID}" OR
+if(NOT (CMAKE_C_COMPILER_ID STREQUAL CMAKE_Fortran_COMPILER_ID OR
"${CMAKE_C_COMPILER_ID}-${CMAKE_Fortran_COMPILER_ID}" MATCHES "^(MSVC-Intel)$"))
message(STATUS "${CMAKE_C_COMPILER_ID} C and ${CMAKE_Fortran_COMPILER_ID} Fortran not known to be compatible!")
return()
diff --git a/Tests/FortranC/Flags.cmake.in b/Tests/FortranC/Flags.cmake.in
index 34363093b..cf361a539 100644
--- a/Tests/FortranC/Flags.cmake.in
+++ b/Tests/FortranC/Flags.cmake.in
@@ -12,10 +12,17 @@ configure_file("${src}/test_opt.sh.in" "${bld}/fc.sh" @ONLY)
set(ID)
set(COMMAND)
+set(make_program "@CMake_TEST_EXPLICIT_MAKE_PROGRAM@")
+if(make_program)
+ set(maybe_make_program "-DCMAKE_MAKE_PROGRAM=${make_program}")
+endif()
+
execute_process(
WORKING_DIRECTORY "${bld}"
- COMMAND ${CMAKE_COMMAND} "${src}" -G "@CMAKE_TEST_GENERATOR@"
- -T "@CMAKE_TEST_GENERATOR_TOOLSET@"
+ COMMAND ${CMAKE_COMMAND} "${src}" -G "@CMAKE_GENERATOR@"
+ -A "@CMAKE_GENERATOR_PLATFORM@"
+ -T "@CMAKE_GENERATOR_TOOLSET@"
+ ${maybe_make_program}
"-DFortranC_TEST_FLAGS=1"
"-DCMAKE_C_COMPILER=${bld}/cc.sh"
"-DCMAKE_C_FLAGS:STRING=@CMAKE_C_FLAGS@"
diff --git a/Tests/FortranOnly/CMakeLists.txt b/Tests/FortranOnly/CMakeLists.txt
index d57a8b295..9bf03033a 100644
--- a/Tests/FortranOnly/CMakeLists.txt
+++ b/Tests/FortranOnly/CMakeLists.txt
@@ -8,13 +8,14 @@ set_property(TARGET FortranOnlylib PROPERTY Fortran_FORMAT FIXED)
set_property(SOURCE world.f PROPERTY Fortran_FORMAT FREE)
# create an executable that calls hello and world
-add_executable(FortranOnly testf.f)
-target_link_libraries(FortranOnly FortranOnlylib)
+add_executable(FortranOnly1 testf.f)
+set_property(TARGET FortranOnly1 PROPERTY OUTPUT_NAME FortranOnly)
+target_link_libraries(FortranOnly1 FortranOnlylib)
-# create a custom command that runs FortranOnly and puts
+# create a custom command that runs FortranOnly1 and puts
# the output into the file testfhello.txt
add_custom_command(OUTPUT ${FortranOnly_BINARY_DIR}/testfhello.txt
- COMMAND ${FortranOnly_BINARY_DIR}/${CMAKE_CFG_INTDIR}/FortranOnly
+ COMMAND FortranOnly1
> testfhello.txt)
# create a second executable FortranOnly2 that has
# testfhello.txt has an source file so that it will
@@ -27,15 +28,15 @@ add_custom_target(checktestf2 ALL
COMMAND ${CMAKE_COMMAND}
-P ${FortranOnly_SOURCE_DIR}/checktestf2.cmake)
-# create a custom target that runs FortranOnly exectuable and creates
+# create a custom target that runs FortranOnly1 exectuable and creates
# a file out.txt that should have hello world in it.
add_custom_target(sayhello ALL
- COMMAND ${FortranOnly_BINARY_DIR}/${CMAKE_CFG_INTDIR}/FortranOnly > out.txt
+ COMMAND FortranOnly1 > out.txt
)
# make sure stuff is built in the right order
add_dependencies(checktestf2 FortranOnly2)
-add_dependencies(sayhello FortranOnly)
-add_dependencies(FortranOnly2 FortranOnly)
+add_dependencies(sayhello FortranOnly1)
+add_dependencies(FortranOnly2 FortranOnly1)
# add a custom target that checkes that out.txt has the correct
# content
@@ -43,3 +44,58 @@ add_custom_target(checksayhello ALL
COMMAND ${CMAKE_COMMAND} -P ${FortranOnly_SOURCE_DIR}/checksayhello.cmake
)
add_dependencies(checksayhello sayhello)
+
+# Exclude this test on IBM XL for now because the check strangely
+# fails with 'ld: 0706-029 Use a number with the -H flag'.
+if(NOT CMAKE_Fortran_COMPILER_ID STREQUAL XL)
+ set(err_log ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log)
+ file(REMOVE "${err_log}")
+ include(CheckFortranSourceCompiles)
+ unset(HAVE_PRINT CACHE)
+ CHECK_Fortran_SOURCE_COMPILES([[
+ PROGRAM TEST_HAVE_PRINT
+ PRINT *, 'Hello'
+ END
+]] HAVE_PRINT)
+ if(NOT HAVE_PRINT)
+ if(EXISTS "${err_log}")
+ file(READ "${err_log}" err)
+ endif()
+ string(REPLACE "\n" "\n " err " ${err}")
+ message(SEND_ERROR "CHECK_Fortran_SOURCE_COMPILES for HAVE_PRINT failed:\n"
+ "${err}")
+ endif()
+
+ unset(Fortran_BOGUS_FLAG CACHE)
+ include(CheckFortranCompilerFlag)
+ CHECK_Fortran_COMPILER_FLAG(-_this_is_not_a_flag_ Fortran_BOGUS_FLAG)
+ if (Fortran_BOGUS_FLAG)
+ message (SEND_ERROR "CHECK_Fortran_COMPILER_FLAG() succeeded, but should have failed")
+ endif ()
+endif()
+
+# Test generation of preprocessed sources.
+if("${CMAKE_GENERATOR}" MATCHES "Makefile" AND CMAKE_MAKE_PROGRAM)
+ if(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE)
+ # Skip running this part of the test on certain platforms
+ # until they are fixed.
+ set(MAYBE_ALL ALL)
+ list(LENGTH CMAKE_OSX_ARCHITECTURES ARCH_COUNT)
+ if(ARCH_COUNT GREATER 1)
+ # OSX does not support preprocessing more than one architecture.
+ set(MAYBE_ALL)
+ endif()
+
+ add_executable(preprocess preprocess.F)
+
+ # Custom target to try preprocessing invocation.
+ add_custom_target(test_preprocess ${MAYBE_ALL}
+ COMMAND ${CMAKE_COMMAND} -E remove CMakeFiles/preprocess.dir/preprocess.F.i
+ COMMAND ${CMAKE_MAKE_PROGRAM} preprocess.i
+ COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/test_preprocess.cmake
+ # Remove bogus file some compilers leave behind.
+ COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_SOURCE_DIR}/preprocess.s
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ )
+ endif()
+endif()
diff --git a/Tests/FortranOnly/preprocess.F b/Tests/FortranOnly/preprocess.F
new file mode 100644
index 000000000..f7df4572c
--- /dev/null
+++ b/Tests/FortranOnly/preprocess.F
@@ -0,0 +1,5 @@
+ PROGRAM PREPRO
+#ifndef TEST_PREPROCESSOR
+ PRINT *, 'Hello'
+#endif
+ END
diff --git a/Tests/FortranOnly/test_preprocess.cmake b/Tests/FortranOnly/test_preprocess.cmake
new file mode 100644
index 000000000..29ebdace6
--- /dev/null
+++ b/Tests/FortranOnly/test_preprocess.cmake
@@ -0,0 +1,7 @@
+set(TEST_FILE CMakeFiles/preprocess.dir/preprocess.F.i)
+file(READ ${TEST_FILE} CONTENTS)
+if("${CONTENTS}" MATCHES "PRINT *")
+ message(STATUS "${TEST_FILE} created successfully!")
+else()
+ message(FATAL_ERROR "${TEST_FILE} creation failed!")
+endif()
diff --git a/Tests/FunctionTest/CMakeLists.txt b/Tests/FunctionTest/CMakeLists.txt
index d1fada495..68da972c6 100644
--- a/Tests/FunctionTest/CMakeLists.txt
+++ b/Tests/FunctionTest/CMakeLists.txt
@@ -92,7 +92,7 @@ endfunction()
STRANGE_FUNCTION(var)
set(second_var "second_var")
-if("${var}" STREQUAL "strange_function" AND "${second_var}" STREQUAL "second_var")
+if("x${var}" STREQUAL "xstrange_function" AND "x${second_var}" STREQUAL "xsecond_var")
PASS("Case Test" "(${var} ${second_var})")
else()
FAILED("Case test" "(${var} ${second_var})")
diff --git a/Tests/GeneratorExpression/CMP0044/CMakeLists.txt b/Tests/GeneratorExpression/CMP0044/CMakeLists.txt
new file mode 100644
index 000000000..309a8cc1e
--- /dev/null
+++ b/Tests/GeneratorExpression/CMP0044/CMakeLists.txt
@@ -0,0 +1,19 @@
+
+string(TOLOWER ${CMAKE_C_COMPILER_ID} lc_test)
+if (lc_test STREQUAL CMAKE_C_COMPILER_ID)
+ string(TOUPPER ${CMAKE_C_COMPILER_ID} lc_test)
+ if (lc_test STREQUAL CMAKE_C_COMPILER_ID)
+ message(SEND_ERROR "Try harder.")
+ endif()
+endif()
+
+if (CMP0044_TYPE)
+ cmake_policy(SET CMP0044 ${CMP0044_TYPE})
+endif()
+
+add_library(cmp0044-check-${CMP0044_TYPE} cmp0044-check.cpp)
+target_compile_definitions(cmp0044-check-${CMP0044_TYPE}
+ PRIVATE
+ Result=$<C_COMPILER_ID:${lc_test}>
+ Type_Is_${CMP0044_TYPE}
+)
diff --git a/Tests/GeneratorExpression/CMP0044/cmp0044-check.cpp b/Tests/GeneratorExpression/CMP0044/cmp0044-check.cpp
new file mode 100644
index 000000000..2356bc488
--- /dev/null
+++ b/Tests/GeneratorExpression/CMP0044/cmp0044-check.cpp
@@ -0,0 +1,26 @@
+
+#ifdef Type_Is_
+# if !Result
+# error Result should be 1 in WARN mode
+# endif
+#endif
+
+#ifdef Type_Is_NEW
+# if Result
+# error Result should be 0 in NEW mode
+# endif
+#endif
+
+#ifdef Type_Is_OLD
+# if !Result
+# error Result should be 1 in OLD mode
+# endif
+#endif
+
+#if !defined(Type_Is_) && !defined(Type_Is_OLD) && !defined(Type_Is_NEW)
+#error No expected definition present
+#endif
+
+void foo(void)
+{
+}
diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt
index 4d8d7ed25..27f33a2a6 100644
--- a/Tests/GeneratorExpression/CMakeLists.txt
+++ b/Tests/GeneratorExpression/CMakeLists.txt
@@ -1,5 +1,7 @@
cmake_minimum_required (VERSION 2.8.8)
-project(GeneratorExpression CXX)
+project(GeneratorExpression)
+
+include(CTest)
# This test is split into multiple parts as needed to avoid NMake command
# length limits.
@@ -11,6 +13,7 @@ add_custom_target(check-part1 ALL
-Dtest_1=$<1:content>
-Dtest_1_with_comma=$<1:-Wl,--no-undefined>
-Dconfig=$<CONFIGURATION>
+ -Dshort_config=$<CONFIG>
-Dtest_and_0=$<AND:0>
-Dtest_and_0_0=$<AND:0,0>
-Dtest_and_0_1=$<AND:0,1>
@@ -63,7 +66,7 @@ add_custom_target(check-part1 ALL
-Dtest_colons_4=$<1:C:\\CMake>
-Dtest_colons_5=$<1:C:/CMake>
-P ${CMAKE_CURRENT_SOURCE_DIR}/check-part1.cmake
- COMMAND ${CMAKE_COMMAND} -E echo "check done (part 1 of 3)"
+ COMMAND ${CMAKE_COMMAND} -E echo "check done (part 1 of 4)"
VERBATIM
)
@@ -134,7 +137,7 @@ add_custom_target(check-part2 ALL
-Dtest_arbitrary_content_comma_9=$<1:a,,b,,>
-Dtest_arbitrary_content_comma_10=$<1:,,a,,b,,>
-P ${CMAKE_CURRENT_SOURCE_DIR}/check-part2.cmake
- COMMAND ${CMAKE_COMMAND} -E echo "check done (part 2 of 3)"
+ COMMAND ${CMAKE_COMMAND} -E echo "check done (part 2 of 4)"
VERBATIM
)
@@ -163,7 +166,7 @@ add_library(imported4 SHARED IMPORTED)
set_property(TARGET imported4 APPEND PROPERTY
INCLUDE_DIRECTORIES $<TARGET_PROPERTY:imported3,INTERFACE_INCLUDE_DIRECTORIES>)
-add_executable(someexe empty.cpp)
+add_executable(someexe $<1:empty.cpp> $<0:does_not_exist>)
add_executable(Alias::SomeExe ALIAS someexe)
add_library(Alias::SomeLib ALIAS empty1)
@@ -186,7 +189,92 @@ add_custom_target(check-part3 ALL
-Dtest_alias_target_name=$<STREQUAL:$<TARGET_PROPERTY:Alias::SomeLib,NAME>,$<TARGET_PROPERTY:empty1,NAME>>
-Dtest_early_termination_1=$<$<1:>:
-Dtest_early_termination_2=$<$<1:>:,
+ -Dsystem_name=${CMAKE_HOST_SYSTEM_NAME}
+ -Dtest_platform_id=$<PLATFORM_ID>
+ -Dtest_platform_id_Linux=$<PLATFORM_ID:Linux>
+ -Dtest_platform_id_Windows=$<PLATFORM_ID:Windows>
+ -Dtest_platform_id_Darwin=$<PLATFORM_ID:Darwin>
+ -Dlower_case=$<LOWER_CASE:Mi,XeD>
+ -Dupper_case=$<UPPER_CASE:MiX,eD>
+ -Dmake_c_identifier=$<MAKE_C_IDENTIFIER:4f,oo:+bar-$>
+ -Dequal1=$<EQUAL:1,2>
+ -Dequal2=$<EQUAL:1,1>
+ -Dequal3=$<EQUAL:0x1,1>
+ -Dequal4=$<EQUAL:0X1,2>
+ -Dequal5=$<EQUAL:0xA,0xa>
+ -Dequal6=$<EQUAL:0xA,10>
+ -Dequal7=$<EQUAL:0xA,012>
+ -Dequal8=$<EQUAL:10,012>
+ -Dequal9=$<EQUAL:10,010>
+ -Dequal10=$<EQUAL:10,0b1010>
+ -Dequal11=$<EQUAL:-10,-0xa>
+ -Dequal12=$<EQUAL:10,+0xa>
+ -Dequal13=$<EQUAL:+10,+0Xa>
+ -Dequal14=$<EQUAL:+10,0xa>
+ -Dequal15=$<EQUAL:-10,-0Xa>
+ -Dequal16=$<EQUAL:-10,-0b1010>
+ -Dequal17=$<EQUAL:-10,+0b1010>
+ -Dequal18=$<EQUAL:10,+0B1010>
+ -Dequal19=$<EQUAL:10,-0B1010>
+ -Dequal20=$<EQUAL:10,0B1010>
+ -Dequal21=$<EQUAL:10,+012>
+ -Dequal22=$<EQUAL:10,-012>
+ -Dequal23=$<EQUAL:-10,-012>
-P ${CMAKE_CURRENT_SOURCE_DIR}/check-part3.cmake
- COMMAND ${CMAKE_COMMAND} -E echo "check done (part 3 of 3)"
+ COMMAND ${CMAKE_COMMAND} -E echo "check done (part 3 of 4)"
+ VERBATIM
+ )
+
+if(WIN32)
+ set(test_shell_path c:/shell/path)
+else()
+ set(test_shell_path /shell/path)
+endif()
+set(path_prefix BYPASS_FURTHER_CONVERSION)
+
+add_custom_target(check-part4 ALL
+ COMMAND ${CMAKE_COMMAND}
+ # Prefix path to bypass its further conversion when being processed by
+ # CMake as command-line argument
+ -Dtest_shell_path=${path_prefix}$<SHELL_PATH:${test_shell_path}>
+ -Dpath_prefix=${path_prefix}
+ -DWIN32=${WIN32}
+ -DCMAKE_GENERATOR=${CMAKE_GENERATOR}
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/check-part4.cmake
+ COMMAND ${CMAKE_COMMAND} -E echo "check done (part 4 of 4)"
VERBATIM
)
+
+#-----------------------------------------------------------------------------
+# Cover test properties with generator expressions.
+add_executable(echo echo.c)
+add_executable(pwd pwd.c)
+
+add_test(NAME echo-configuration COMMAND echo $<CONFIGURATION>)
+set_property(TEST echo-configuration PROPERTY
+ PASS_REGULAR_EXPRESSION "^$<CONFIGURATION>\n$")
+
+add_test(NAME echo-target-file COMMAND echo $<TARGET_FILE:echo>)
+set_property(TEST echo-target-file PROPERTY
+ PASS_REGULAR_EXPRESSION "/echo${CMAKE_EXECUTABLE_SUFFIX}\n$")
+set_property(TEST echo-target-file PROPERTY
+ REQUIRED_FILES "$<TARGET_FILE:echo>")
+
+add_test(NAME working-dir-arg
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/WorkingDirectory/$<CONFIGURATION>"
+ COMMAND pwd)
+set_property(TEST working-dir-arg PROPERTY
+ PASS_REGULAR_EXPRESSION "WorkingDirectory/$<CONFIGURATION>\n$")
+foreach(c ${CMAKE_CONFIGURATION_TYPES} ${CMAKE_BUILD_TYPE})
+ file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/WorkingDirectory/${c}")
+endforeach()
+
+add_test(echo-old-style echo "\$<CONFIGURATION>")
+set_property(TEST echo-old-style PROPERTY
+ PASS_REGULAR_EXPRESSION "^\\$<CONFIGURATION>\n$")
+
+add_subdirectory(CMP0044 ${CMAKE_BINARY_DIR}/CMP0044-WARN)
+set(CMP0044_TYPE NEW)
+add_subdirectory(CMP0044 ${CMAKE_BINARY_DIR}/CMP0044-NEW)
+set(CMP0044_TYPE OLD)
+add_subdirectory(CMP0044 ${CMAKE_BINARY_DIR}/CMP0044-OLD)
diff --git a/Tests/GeneratorExpression/check-common.cmake b/Tests/GeneratorExpression/check-common.cmake
index 8ffebd740..faf5d4f16 100644
--- a/Tests/GeneratorExpression/check-common.cmake
+++ b/Tests/GeneratorExpression/check-common.cmake
@@ -1,5 +1,5 @@
-macro(check var val)
+function(check var val)
if(NOT "${${var}}" STREQUAL "${val}")
message(SEND_ERROR "${var} is \"${${var}}\", not \"${val}\"")
endif()
-endmacro()
+endfunction()
diff --git a/Tests/GeneratorExpression/check-part1.cmake b/Tests/GeneratorExpression/check-part1.cmake
index 9bef15904..60b193f58 100644
--- a/Tests/GeneratorExpression/check-part1.cmake
+++ b/Tests/GeneratorExpression/check-part1.cmake
@@ -2,6 +2,7 @@
include(${CMAKE_CURRENT_LIST_DIR}/check-common.cmake)
message(STATUS "config=[${config}]")
+check(config "${short_config}")
check(test_0 "")
check(test_0_with_comma "")
check(test_1 "content")
@@ -54,5 +55,5 @@ check(test_semicolon ";")
check(test_colons_1 ":")
check(test_colons_2 "::")
check(test_colons_3 "Qt5::Core")
-check(test_colons_4 "C:\\\\CMake")
+check(test_colons_4 [[C:\CMake]])
check(test_colons_5 "C:/CMake")
diff --git a/Tests/GeneratorExpression/check-part3.cmake b/Tests/GeneratorExpression/check-part3.cmake
index 74a596c3a..70ccfe167 100644
--- a/Tests/GeneratorExpression/check-part3.cmake
+++ b/Tests/GeneratorExpression/check-part3.cmake
@@ -26,3 +26,37 @@ check(test_alias_file_lib "1")
check(test_alias_target_name "1")
check(test_early_termination_1 "$<:")
check(test_early_termination_2 "$<:,")
+check(test_platform_id "${system_name}")
+foreach(system Linux Windows Darwin)
+ if(system_name STREQUAL system)
+ check(test_platform_id_${system} 1)
+ else()
+ check(test_platform_id_${system} 0)
+ endif()
+endforeach()
+check(lower_case "mi,xed")
+check(upper_case "MIX,ED")
+check(make_c_identifier "_4f_oo__bar__")
+check(equal1 "0")
+check(equal2 "1")
+check(equal3 "1")
+check(equal4 "0")
+check(equal5 "1")
+check(equal6 "1")
+check(equal7 "1")
+check(equal8 "1")
+check(equal9 "0")
+check(equal10 "1")
+check(equal11 "1")
+check(equal12 "1")
+check(equal13 "1")
+check(equal14 "1")
+check(equal15 "1")
+check(equal16 "1")
+check(equal17 "0")
+check(equal18 "1")
+check(equal19 "0")
+check(equal20 "1")
+check(equal21 "1")
+check(equal22 "0")
+check(equal23 "1")
diff --git a/Tests/GeneratorExpression/check-part4.cmake b/Tests/GeneratorExpression/check-part4.cmake
new file mode 100644
index 000000000..9e516d52c
--- /dev/null
+++ b/Tests/GeneratorExpression/check-part4.cmake
@@ -0,0 +1,15 @@
+include(${CMAKE_CURRENT_LIST_DIR}/check-common.cmake)
+
+string(REPLACE ${path_prefix} "" test_shell_path ${test_shell_path})
+
+if(WIN32)
+ if(CMAKE_GENERATOR STREQUAL "MSYS Makefiles")
+ check(test_shell_path [[/c/shell/path]])
+ elseif(CMAKE_GENERATOR STREQUAL "Unix Makefiles")
+ check(test_shell_path [[c:/shell/path]])
+ else()
+ check(test_shell_path [[c:\shell\path]])
+ endif()
+else()
+ check(test_shell_path [[/shell/path]])
+endif()
diff --git a/Tests/GeneratorExpression/echo.c b/Tests/GeneratorExpression/echo.c
new file mode 100644
index 000000000..06b0844b3
--- /dev/null
+++ b/Tests/GeneratorExpression/echo.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char* argv[])
+{
+ printf("%s\n", argv[1]);
+ return EXIT_SUCCESS;
+}
diff --git a/Tests/GeneratorExpression/pwd.c b/Tests/GeneratorExpression/pwd.c
new file mode 100644
index 000000000..054b1af68
--- /dev/null
+++ b/Tests/GeneratorExpression/pwd.c
@@ -0,0 +1,34 @@
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef _WIN32
+#include <direct.h>
+#define getcurdir _getcwd
+#else
+#include <unistd.h>
+#define getcurdir getcwd
+#endif
+
+int main(int argc, char* argv[])
+{
+#define BUFSZ 20000
+ char buf[BUFSZ + 1];
+#ifdef _WIN32
+ char *pos;
+#endif
+ getcurdir(buf, BUFSZ);
+#ifdef _WIN32
+ pos = buf;
+ while (*pos)
+ {
+ if (*pos == '\\')
+ {
+ *pos = '/';
+ }
+ ++pos;
+ }
+#endif
+ printf("%s\n", buf);
+ return EXIT_SUCCESS;
+}
diff --git a/Tests/GhsMulti/CMakeLists.txt b/Tests/GhsMulti/CMakeLists.txt
new file mode 100644
index 000000000..6e15ba9a7
--- /dev/null
+++ b/Tests/GhsMulti/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.1)
+project(ReturnNum)
+
+add_subdirectory(ReturnNum)
diff --git a/Tests/GhsMulti/ReturnNum/App/CMakeLists.txt b/Tests/GhsMulti/ReturnNum/App/CMakeLists.txt
new file mode 100644
index 000000000..2adbd4e3d
--- /dev/null
+++ b/Tests/GhsMulti/ReturnNum/App/CMakeLists.txt
@@ -0,0 +1,4 @@
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../Lib)
+add_executable(App Main.c)
+target_link_libraries(App Lib)
+target_compile_options(App PUBLIC "-non_shared")
diff --git a/Tests/GhsMulti/ReturnNum/App/Main.c b/Tests/GhsMulti/ReturnNum/App/Main.c
new file mode 100644
index 000000000..1133834d8
--- /dev/null
+++ b/Tests/GhsMulti/ReturnNum/App/Main.c
@@ -0,0 +1,8 @@
+#include "HelperFun.h"
+
+int main(int argc, const char* argv[])
+{
+ int out;
+ out = giveNum();
+ return out;
+}
diff --git a/Tests/GhsMulti/ReturnNum/CMakeLists.txt b/Tests/GhsMulti/ReturnNum/CMakeLists.txt
new file mode 100644
index 000000000..7bcc5f96a
--- /dev/null
+++ b/Tests/GhsMulti/ReturnNum/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_subdirectory(App)
+add_subdirectory(Int)
+add_subdirectory(Lib)
diff --git a/Tests/GhsMulti/ReturnNum/Int/AppDD.int b/Tests/GhsMulti/ReturnNum/Int/AppDD.int
new file mode 100644
index 000000000..9e22b5e25
--- /dev/null
+++ b/Tests/GhsMulti/ReturnNum/Int/AppDD.int
@@ -0,0 +1,12 @@
+# Input File for the Integrate utility for use with the INTEGRITY real-time
+# operating system by Green Hills Software.
+# Before editing this file, refer to the Integrate Reference Manual.
+
+Kernel
+ Filename DynamicDownload
+EndKernel
+
+AddressSpace App
+ Filename "App/App.as"
+ Language C
+EndAddressSpace
diff --git a/Tests/GhsMulti/ReturnNum/Int/CMakeLists.txt b/Tests/GhsMulti/ReturnNum/Int/CMakeLists.txt
new file mode 100644
index 000000000..44c5de1c5
--- /dev/null
+++ b/Tests/GhsMulti/ReturnNum/Int/CMakeLists.txt
@@ -0,0 +1 @@
+add_executable(AppDD AppDD.int Default.bsp)
diff --git a/Tests/GhsMulti/ReturnNum/Int/Default.bsp b/Tests/GhsMulti/ReturnNum/Int/Default.bsp
new file mode 100644
index 000000000..224ec2906
--- /dev/null
+++ b/Tests/GhsMulti/ReturnNum/Int/Default.bsp
@@ -0,0 +1,35 @@
+# Target description File for the Integrate utility for use with the
+# INTEGRITY real-time operating system by Green Hills Software.
+# Before editing this file, refer to your Integrate documentation.
+# default.bsp is appropriate for INTEGRITY applications which are
+# fully linked with the kernel (for RAM or ROM) or dynamically downloaded.
+#
+# MinimumAddress must match the value of .ramend in the linker directives
+# file used for the KernelSpace program - see default.ld for more info.
+# The MaximumAddress used here allows memory mappings to be specified
+# for up to the 16 MB mark in RAM. Intex will not permit programs
+# that require more memory for its mappings. If the board has less
+# memory, this number can be reduced by the user.
+
+Target
+ MinimumAddress .ramend
+ MaximumAddress .ramlimit
+ Clock StandardTick
+ EndClock
+ Clock HighResTimer
+ EndClock
+ IODevice "SerialDev0"
+ InitialKernelObjects 200
+ DefaultStartIt false
+ DefaultMaxPriority 255
+ DefaultPriority 127
+ DefaultWeight 1
+ DefaultMaxWeight 255
+ DefaultHeapSize 0x10000
+ LastVirtualAddress 0x3fffffff
+ PageSize 0x1000
+ ArchitectedPageSize 0x1000
+ ArchitectedPageSize 0x10000
+ ArchitectedPageSize 0x100000
+ DefaultMemoryRegionSize 0x20000
+EndTarget
diff --git a/Tests/GhsMulti/ReturnNum/Lib/CMakeLists.txt b/Tests/GhsMulti/ReturnNum/Lib/CMakeLists.txt
new file mode 100644
index 000000000..9c822da56
--- /dev/null
+++ b/Tests/GhsMulti/ReturnNum/Lib/CMakeLists.txt
@@ -0,0 +1 @@
+add_library(Lib HelperFun.c HelperFun.h) \ No newline at end of file
diff --git a/Tests/GhsMulti/ReturnNum/Lib/HelperFun.c b/Tests/GhsMulti/ReturnNum/Lib/HelperFun.c
new file mode 100644
index 000000000..d7515d7da
--- /dev/null
+++ b/Tests/GhsMulti/ReturnNum/Lib/HelperFun.c
@@ -0,0 +1,4 @@
+int giveNum(void)
+{
+ return 1;
+}
diff --git a/Tests/GhsMulti/ReturnNum/Lib/HelperFun.h b/Tests/GhsMulti/ReturnNum/Lib/HelperFun.h
new file mode 100644
index 000000000..00971b04f
--- /dev/null
+++ b/Tests/GhsMulti/ReturnNum/Lib/HelperFun.h
@@ -0,0 +1 @@
+int giveNum(void);
diff --git a/Tests/IncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/CMakeLists.txt
index 35ad8dc90..9ee195714 100644
--- a/Tests/IncludeDirectories/CMakeLists.txt
+++ b/Tests/IncludeDirectories/CMakeLists.txt
@@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 2.6)
project(IncludeDirectories)
if (((CMAKE_C_COMPILER_ID STREQUAL GNU AND CMAKE_C_COMPILER_VERSION VERSION_GREATER 4.4)
- OR CMAKE_C_COMPILER_ID STREQUAL Clang)
+ OR CMAKE_C_COMPILER_ID STREQUAL Clang OR CMAKE_C_COMPILER_ID STREQUAL AppleClang)
AND (CMAKE_GENERATOR STREQUAL "Unix Makefiles" OR CMAKE_GENERATOR STREQUAL "Ninja"))
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag(-Wunused-variable run_sys_includes_test)
diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt
index aec6ff981..dcee85eb4 100644
--- a/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt
+++ b/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt
@@ -14,6 +14,54 @@ target_include_directories(upstream SYSTEM PUBLIC
$<TARGET_PROPERTY:systemlib,INTERFACE_INCLUDE_DIRECTORIES>
)
+add_library(config_specific INTERFACE)
+set(testConfig ${CMAKE_BUILD_TYPE})
+target_include_directories(config_specific SYSTEM INTERFACE
+ "$<$<CONFIG:${testConfig}>:${CMAKE_CURRENT_SOURCE_DIR}/config_specific>"
+)
+
add_library(consumer consumer.cpp)
-target_link_libraries(consumer upstream)
+target_link_libraries(consumer upstream config_specific)
target_compile_options(consumer PRIVATE -Werror=unused-variable)
+
+add_library(iface IMPORTED INTERFACE)
+set_property(TARGET iface PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/systemlib_header_only")
+
+add_library(imported_consumer imported_consumer.cpp)
+target_link_libraries(imported_consumer iface)
+target_compile_options(imported_consumer PRIVATE -Werror=unused-variable)
+
+add_library(imported_consumer2 imported_consumer.cpp)
+target_link_libraries(imported_consumer2 imported_consumer)
+target_compile_options(imported_consumer2 PRIVATE -Werror=unused-variable)
+
+# add a target which has a relative system include
+add_library(somelib imported_consumer.cpp)
+target_include_directories(somelib SYSTEM PUBLIC "systemlib_header_only")
+target_compile_options(somelib PRIVATE -Werror=unused-variable)
+
+# add a target which consumes a relative system include
+add_library(otherlib upstream.cpp)
+target_link_libraries(otherlib PUBLIC somelib)
+target_compile_options(somelib PRIVATE -Werror=unused-variable)
+
+macro(do_try_compile error_option)
+ set(TC_ARGS
+ IFACE_TRY_COMPILE_${error_option}
+ "${CMAKE_CURRENT_BINARY_DIR}/try_compile_iface" "${CMAKE_CURRENT_SOURCE_DIR}/imported_consumer.cpp"
+ LINK_LIBRARIES iface
+ )
+ if (${error_option} STREQUAL WITH_ERROR)
+ list(APPEND TC_ARGS COMPILE_DEFINITIONS -Werror=unused-variable)
+ endif()
+ try_compile(${TC_ARGS})
+endmacro()
+
+do_try_compile(NO_ERROR)
+if (NOT IFACE_TRY_COMPILE_NO_ERROR)
+ message(SEND_ERROR "try_compile failed with imported target.")
+endif()
+do_try_compile(WITH_ERROR)
+if (NOT IFACE_TRY_COMPILE_WITH_ERROR)
+ message(SEND_ERROR "try_compile failed with imported target with error option.")
+endif()
diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/config_specific/config_iface.h b/Tests/IncludeDirectories/SystemIncludeDirectories/config_specific/config_iface.h
new file mode 100644
index 000000000..05d3604eb
--- /dev/null
+++ b/Tests/IncludeDirectories/SystemIncludeDirectories/config_specific/config_iface.h
@@ -0,0 +1,14 @@
+
+#ifndef CONFIG_IFACE_H
+#define CONFIG_IFACE_H
+
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int configUnusedFunc()
+{
+ int unused;
+ return 0;
+}
+
+#endif
diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/consumer.cpp b/Tests/IncludeDirectories/SystemIncludeDirectories/consumer.cpp
index 197dae86d..be18ebf52 100644
--- a/Tests/IncludeDirectories/SystemIncludeDirectories/consumer.cpp
+++ b/Tests/IncludeDirectories/SystemIncludeDirectories/consumer.cpp
@@ -1,6 +1,8 @@
#include "upstream.h"
+#include "config_iface.h"
+
int consumer()
{
return upstream();
diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/imported_consumer.cpp b/Tests/IncludeDirectories/SystemIncludeDirectories/imported_consumer.cpp
new file mode 100644
index 000000000..1dbe819e1
--- /dev/null
+++ b/Tests/IncludeDirectories/SystemIncludeDirectories/imported_consumer.cpp
@@ -0,0 +1,7 @@
+
+#include "systemlib.h"
+
+int main()
+{
+ return systemlib();
+}
diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/systemlib_header_only/systemlib.h b/Tests/IncludeDirectories/SystemIncludeDirectories/systemlib_header_only/systemlib.h
new file mode 100644
index 000000000..93622c433
--- /dev/null
+++ b/Tests/IncludeDirectories/SystemIncludeDirectories/systemlib_header_only/systemlib.h
@@ -0,0 +1,16 @@
+
+#ifndef SYSTEMLIB_H
+#define SYSTEMLIB_H
+
+int systemlib()
+{
+ return 0;
+}
+
+int unusedFunc()
+{
+ int unused;
+ return systemlib();
+}
+
+#endif
diff --git a/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt
index 8e2bd0a0d..5b99ea7b3 100644
--- a/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt
+++ b/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt
@@ -5,7 +5,7 @@ project(TargetIncludeDirectories)
macro(create_header _name)
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${_name}")
- file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_name}/${_name}.h" "//${_name}.h\n")
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_name}/${_name}.h" "/* ${_name}.h */\n")
endmacro()
create_header(bar)
@@ -88,7 +88,7 @@ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/bad/common.h" "#error Should not be incl
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/good")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/good/common.h" "#include \"othergood.h\"\n")
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/othergood")
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/othergood/othergood.h" "// No error\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/othergood/othergood.h" "/* No error */\n")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/libothergood.cpp" "// No content \n")
add_library(libothergood "${CMAKE_CURRENT_BINARY_DIR}/libothergood.cpp")
@@ -149,7 +149,7 @@ target_include_directories(lib5
)
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/prefix_foo/prefix_bar/prefix_bat")
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/prefix_foo/prefix_bar/prefix_bat/prefix_foo_bar_bat.h" "// prefix_foo_bar_bat.h\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/prefix_foo/prefix_bar/prefix_bat/prefix_foo_bar_bat.h" "/* prefix_foo_bar_bat.h */\n")
target_include_directories(TargetIncludeDirectories PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/prefix_$<JOIN:foo;bar;bat,/prefix_>")
diff --git a/Tests/InterfaceLibrary/CMakeLists.txt b/Tests/InterfaceLibrary/CMakeLists.txt
new file mode 100644
index 000000000..ee81419fd
--- /dev/null
+++ b/Tests/InterfaceLibrary/CMakeLists.txt
@@ -0,0 +1,61 @@
+
+cmake_minimum_required(VERSION 2.8)
+
+project(InterfaceLibrary)
+
+add_library(iface_nodepends INTERFACE)
+target_compile_definitions(iface_nodepends INTERFACE IFACE_DEFINE)
+
+add_subdirectory(headerdir)
+
+# Add an interface target in a subdirectory that uses an imported interface.
+add_subdirectory(ifacedir)
+
+# Poison an imported interface with the same name as that in the subdir
+# to ensure that the transitive lookup occurs in the subdir.
+add_library(imp::iface INTERFACE IMPORTED)
+set_property(TARGET imp::iface APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SOMEPROP)
+set_property(TARGET imp::iface PROPERTY INTERFACE_SOMEPROP OFF)
+set_property(TARGET imp::iface PROPERTY INTERFACE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/does_not_exist.cpp)
+
+add_library(objlib OBJECT obj.cpp)
+add_library(iface_objlib INTERFACE)
+target_sources(iface_objlib INTERFACE $<TARGET_OBJECTS:objlib>)
+
+add_library(intermediate INTERFACE)
+target_link_libraries(intermediate INTERFACE iface_objlib)
+
+add_executable(InterfaceLibrary definetestexe.cpp)
+target_link_libraries(InterfaceLibrary iface_nodepends headeriface subiface intermediate)
+
+add_subdirectory(libsdir)
+
+add_executable(sharedlibtestexe sharedlibtestexe.cpp)
+target_link_libraries(sharedlibtestexe shared_iface imported::iface)
+
+add_library(broken EXCLUDE_FROM_ALL broken.cpp)
+
+add_library(iface_broken INTERFACE)
+# This is not a dependency, so broken will not be built (and the error in
+# it will not be hit)
+target_link_libraries(iface_broken INTERFACE broken)
+
+add_library(iface_whitelist INTERFACE)
+# The target property CUSTOM will never be evaluated on the INTERFACE library.
+target_link_libraries(iface_whitelist INTERFACE $<$<BOOL:$<TARGET_PROPERTY:CUSTOM>>:irrelevant>)
+
+add_executable(exec_whitelist dummy.cpp)
+target_link_libraries(exec_whitelist iface_whitelist)
+
+add_library(iface_imported INTERFACE IMPORTED)
+set_property(TARGET iface_imported PROPERTY
+ INTERFACE_COMPILE_DEFINITIONS
+ $<$<CONFIG:SPECIAL>:SPECIAL_MODE>
+ $<$<CONFIG:Debug>:DEBUG_MODE>
+)
+set_property(TARGET iface_imported PROPERTY
+ MAP_IMPORTED_CONFIG_DEBUG SPECIAL
+)
+
+add_executable(map_config map_config.cpp)
+target_link_libraries(map_config iface_imported)
diff --git a/Tests/InterfaceLibrary/broken.cpp b/Tests/InterfaceLibrary/broken.cpp
new file mode 100644
index 000000000..1fd10416b
--- /dev/null
+++ b/Tests/InterfaceLibrary/broken.cpp
@@ -0,0 +1,2 @@
+
+#error Broken
diff --git a/Tests/InterfaceLibrary/definetestexe.cpp b/Tests/InterfaceLibrary/definetestexe.cpp
new file mode 100644
index 000000000..904407646
--- /dev/null
+++ b/Tests/InterfaceLibrary/definetestexe.cpp
@@ -0,0 +1,24 @@
+
+#ifndef IFACE_DEFINE
+#error Expected IFACE_DEFINE
+#endif
+
+#include "iface_header.h"
+
+#ifndef IFACE_HEADER_SRCDIR
+#error Expected IFACE_HEADER_SRCDIR
+#endif
+
+#include "iface_header_builddir.h"
+
+#ifndef IFACE_HEADER_BUILDDIR
+#error Expected IFACE_HEADER_BUILDDIR
+#endif
+
+extern int obj();
+extern int sub();
+
+int main(int,char**)
+{
+ return obj() + sub();
+}
diff --git a/Tests/InterfaceLibrary/dummy.cpp b/Tests/InterfaceLibrary/dummy.cpp
new file mode 100644
index 000000000..341aaafa0
--- /dev/null
+++ b/Tests/InterfaceLibrary/dummy.cpp
@@ -0,0 +1,5 @@
+
+int main(int, char **)
+{
+ return 0;
+}
diff --git a/Tests/InterfaceLibrary/headerdir/CMakeLists.txt b/Tests/InterfaceLibrary/headerdir/CMakeLists.txt
new file mode 100644
index 000000000..826a9ed9c
--- /dev/null
+++ b/Tests/InterfaceLibrary/headerdir/CMakeLists.txt
@@ -0,0 +1,13 @@
+
+set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)
+
+add_library(headeriface INTERFACE)
+
+add_custom_target(headeriface_gen
+ COMMENT "Generating iface_header_builddir.h"
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ ${CMAKE_CURRENT_SOURCE_DIR}/iface_header_builddir.h.in
+ ${CMAKE_CURRENT_BINARY_DIR}/iface_header_builddir.h
+ VERBATIM
+ )
+add_dependencies(headeriface headeriface_gen)
diff --git a/Tests/InterfaceLibrary/headerdir/iface_header.h b/Tests/InterfaceLibrary/headerdir/iface_header.h
new file mode 100644
index 000000000..82dd15749
--- /dev/null
+++ b/Tests/InterfaceLibrary/headerdir/iface_header.h
@@ -0,0 +1 @@
+#define IFACE_HEADER_SRCDIR
diff --git a/Tests/InterfaceLibrary/headerdir/iface_header_builddir.h.in b/Tests/InterfaceLibrary/headerdir/iface_header_builddir.h.in
new file mode 100644
index 000000000..42dd6dfd9
--- /dev/null
+++ b/Tests/InterfaceLibrary/headerdir/iface_header_builddir.h.in
@@ -0,0 +1 @@
+#define IFACE_HEADER_BUILDDIR
diff --git a/Tests/InterfaceLibrary/ifacedir/CMakeLists.txt b/Tests/InterfaceLibrary/ifacedir/CMakeLists.txt
new file mode 100644
index 000000000..228715e75
--- /dev/null
+++ b/Tests/InterfaceLibrary/ifacedir/CMakeLists.txt
@@ -0,0 +1,8 @@
+add_library(imp::iface INTERFACE IMPORTED)
+set_property(TARGET imp::iface APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SOMEPROP)
+set_property(TARGET imp::iface PROPERTY INTERFACE_SOMEPROP ON)
+set_property(TARGET imp::iface PROPERTY INTERFACE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/sub.cpp)
+
+add_library(subiface INTERFACE)
+target_link_libraries(subiface INTERFACE imp::iface)
+set_property(TARGET subiface PROPERTY INTERFACE_SOMEPROP ON)
diff --git a/Tests/InterfaceLibrary/ifacedir/sub.cpp b/Tests/InterfaceLibrary/ifacedir/sub.cpp
new file mode 100644
index 000000000..165a66adb
--- /dev/null
+++ b/Tests/InterfaceLibrary/ifacedir/sub.cpp
@@ -0,0 +1 @@
+int sub() { return 0; }
diff --git a/Tests/InterfaceLibrary/libsdir/CMakeLists.txt b/Tests/InterfaceLibrary/libsdir/CMakeLists.txt
new file mode 100644
index 000000000..4e529dfb1
--- /dev/null
+++ b/Tests/InterfaceLibrary/libsdir/CMakeLists.txt
@@ -0,0 +1,28 @@
+
+include(GenerateExportHeader)
+
+add_library(sharedlib SHARED sharedlib.cpp)
+generate_export_header(sharedlib)
+
+add_library(shareddependlib SHARED shareddependlib.cpp)
+generate_export_header(shareddependlib)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)
+
+target_link_libraries(sharedlib PUBLIC shareddependlib)
+
+target_include_directories(shareddependlib
+ PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/shareddependlib")
+target_compile_definitions(shareddependlib
+ INTERFACE $<1:SHAREDDEPENDLIB_DEFINE>)
+
+target_include_directories(sharedlib
+ PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/sharedlib")
+target_compile_definitions(shareddependlib
+ INTERFACE $<1:SHAREDLIB_DEFINE>)
+
+add_library(shared_iface INTERFACE)
+target_link_libraries(shared_iface INTERFACE sharedlib)
+
+add_library(imported::iface INTERFACE IMPORTED GLOBAL)
diff --git a/Tests/InterfaceLibrary/libsdir/shareddependlib.cpp b/Tests/InterfaceLibrary/libsdir/shareddependlib.cpp
new file mode 100644
index 000000000..378ba8165
--- /dev/null
+++ b/Tests/InterfaceLibrary/libsdir/shareddependlib.cpp
@@ -0,0 +1,7 @@
+
+#include "shareddependlib.h"
+
+int SharedDependLibObject::foo() const
+{
+ return 0;
+}
diff --git a/Tests/InterfaceLibrary/libsdir/shareddependlib/shareddependlib.h b/Tests/InterfaceLibrary/libsdir/shareddependlib/shareddependlib.h
new file mode 100644
index 000000000..ad9b484b7
--- /dev/null
+++ b/Tests/InterfaceLibrary/libsdir/shareddependlib/shareddependlib.h
@@ -0,0 +1,12 @@
+
+#ifndef SHAREDDEPENDLIB_H
+#define SHAREDDEPENDLIB_H
+
+#include "shareddependlib_export.h"
+
+struct SHAREDDEPENDLIB_EXPORT SharedDependLibObject
+{
+ int foo() const;
+};
+
+#endif
diff --git a/Tests/InterfaceLibrary/libsdir/sharedlib.cpp b/Tests/InterfaceLibrary/libsdir/sharedlib.cpp
new file mode 100644
index 000000000..c49ce905b
--- /dev/null
+++ b/Tests/InterfaceLibrary/libsdir/sharedlib.cpp
@@ -0,0 +1,12 @@
+
+#include "sharedlib.h"
+
+SharedDependLibObject SharedLibObject::object() const
+{
+ SharedDependLibObject sdlo;
+ return sdlo;
+}
+int SharedLibObject::foo() const
+{
+ return 0;
+}
diff --git a/Tests/InterfaceLibrary/libsdir/sharedlib/sharedlib.h b/Tests/InterfaceLibrary/libsdir/sharedlib/sharedlib.h
new file mode 100644
index 000000000..5b3c7db73
--- /dev/null
+++ b/Tests/InterfaceLibrary/libsdir/sharedlib/sharedlib.h
@@ -0,0 +1,15 @@
+
+#ifndef SHAREDLIB_H
+#define SHAREDLIB_H
+
+#include "sharedlib_export.h"
+
+#include "shareddependlib.h"
+
+struct SHAREDLIB_EXPORT SharedLibObject
+{
+ SharedDependLibObject object() const;
+ int foo() const;
+};
+
+#endif
diff --git a/Tests/InterfaceLibrary/map_config.cpp b/Tests/InterfaceLibrary/map_config.cpp
new file mode 100644
index 000000000..81bb66605
--- /dev/null
+++ b/Tests/InterfaceLibrary/map_config.cpp
@@ -0,0 +1,15 @@
+
+#ifdef DEBUG_MODE
+#ifndef SPECIAL_MODE
+#error Special configuration should be mapped to debug configuration.
+#endif
+#else
+#ifdef SPECIAL_MODE
+#error Special configuration should not be enabled if not debug configuration
+#endif
+#endif
+
+int main(int,char**)
+{
+ return 0;
+}
diff --git a/Tests/InterfaceLibrary/obj.cpp b/Tests/InterfaceLibrary/obj.cpp
new file mode 100644
index 000000000..ee6f5fef2
--- /dev/null
+++ b/Tests/InterfaceLibrary/obj.cpp
@@ -0,0 +1 @@
+int obj() { return 0; }
diff --git a/Tests/InterfaceLibrary/sharedlibtestexe.cpp b/Tests/InterfaceLibrary/sharedlibtestexe.cpp
new file mode 100644
index 000000000..c677f7067
--- /dev/null
+++ b/Tests/InterfaceLibrary/sharedlibtestexe.cpp
@@ -0,0 +1,19 @@
+
+#ifndef SHAREDLIB_DEFINE
+#error Expected SHAREDLIB_DEFINE
+#endif
+
+#ifndef SHAREDDEPENDLIB_DEFINE
+#error Expected SHAREDDEPENDLIB_DEFINE
+#endif
+
+#include "sharedlib.h"
+#include "shareddependlib.h"
+
+int main(int,char**)
+{
+ SharedLibObject sl;
+ SharedDependLibObject sdl = sl.object();
+
+ return sdl.foo() + sl.foo();
+}
diff --git a/Tests/InterfaceLinkLibraries/CMakeLists.txt b/Tests/InterfaceLinkLibraries/CMakeLists.txt
index bd0cf748e..9e14c4400 100644
--- a/Tests/InterfaceLinkLibraries/CMakeLists.txt
+++ b/Tests/InterfaceLinkLibraries/CMakeLists.txt
@@ -9,6 +9,9 @@ target_compile_definitions(foo_shared INTERFACE FOO_LIBRARY)
add_library(bar_shared SHARED bar_vs6_1.cpp)
target_compile_definitions(bar_shared INTERFACE BAR_LIBRARY)
set_property(TARGET bar_shared APPEND PROPERTY INTERFACE_LINK_LIBRARIES foo_shared)
+add_library(zot_shared SHARED zot_vs6_1.cpp)
+target_compile_definitions(zot_shared INTERFACE ZOT_LIBRARY)
+set_property(TARGET bar_shared APPEND PROPERTY INTERFACE_LINK_LIBRARIES $<LINK_ONLY:zot_shared>)
add_executable(shared_test main_vs6_1.cpp)
set_property(TARGET shared_test APPEND PROPERTY LINK_LIBRARIES bar_shared)
@@ -18,6 +21,9 @@ target_compile_definitions(foo_static INTERFACE FOO_LIBRARY)
add_library(bar_static STATIC bar_vs6_2.cpp)
target_compile_definitions(bar_static INTERFACE BAR_LIBRARY)
set_property(TARGET bar_static APPEND PROPERTY INTERFACE_LINK_LIBRARIES foo_static)
+add_library(zot_static STATIC zot_vs6_2.cpp)
+target_compile_definitions(zot_static INTERFACE ZOT_LIBRARY)
+set_property(TARGET bar_static APPEND PROPERTY INTERFACE_LINK_LIBRARIES $<LINK_ONLY:zot_static>)
add_executable(static_test main_vs6_2.cpp)
set_property(TARGET static_test APPEND PROPERTY LINK_LIBRARIES bar_static)
@@ -31,6 +37,9 @@ target_compile_definitions(bar_shared_private INTERFACE BAR_LIBRARY)
target_compile_definitions(bar_shared_private PRIVATE BAR_USE_BANG)
set_property(TARGET bar_shared_private APPEND PROPERTY LINK_LIBRARIES bang_shared_private)
set_property(TARGET bar_shared_private APPEND PROPERTY INTERFACE_LINK_LIBRARIES foo_shared_private)
+add_library(zot_shared_private SHARED zot_vs6_3.cpp)
+target_compile_definitions(zot_shared_private INTERFACE ZOT_LIBRARY)
+set_property(TARGET bar_shared_private APPEND PROPERTY INTERFACE_LINK_LIBRARIES $<LINK_ONLY:zot_shared_private>)
add_executable(shared_private_test main_vs6_3.cpp)
set_property(TARGET shared_private_test APPEND PROPERTY LINK_LIBRARIES bar_shared_private)
@@ -44,6 +53,9 @@ target_compile_definitions(bar_static_private INTERFACE BAR_LIBRARY)
target_compile_definitions(bar_static_private PRIVATE BAR_USE_BANG)
set_property(TARGET bar_static_private APPEND PROPERTY LINK_LIBRARIES bang_static_private)
set_property(TARGET bar_static_private APPEND PROPERTY INTERFACE_LINK_LIBRARIES $<LINK_ONLY:bang_static_private> foo_static_private)
+add_library(zot_static_private STATIC zot_vs6_4.cpp)
+target_compile_definitions(zot_static_private INTERFACE ZOT_LIBRARY)
+set_property(TARGET bar_static_private APPEND PROPERTY INTERFACE_LINK_LIBRARIES $<LINK_ONLY:zot_static_private>)
add_executable(InterfaceLinkLibraries main_vs6_4.cpp)
set_property(TARGET InterfaceLinkLibraries APPEND PROPERTY LINK_LIBRARIES bar_static_private)
diff --git a/Tests/InterfaceLinkLibraries/main.cpp b/Tests/InterfaceLinkLibraries/main.cpp
index a54076a75..6e1295a10 100644
--- a/Tests/InterfaceLinkLibraries/main.cpp
+++ b/Tests/InterfaceLinkLibraries/main.cpp
@@ -11,9 +11,13 @@
#error Unexpected BANG_LIBRARY
#endif
-#include "bar.h"
+#ifdef ZOT_LIBRARY
+#error Unexpected ZOT_LIBRARY
+#endif
+
+#include "zot.h"
int main(void)
{
- return foo() + bar();
+ return foo() + bar() + zot();
}
diff --git a/Tests/InterfaceLinkLibraries/zot.cpp b/Tests/InterfaceLinkLibraries/zot.cpp
new file mode 100644
index 000000000..69462b063
--- /dev/null
+++ b/Tests/InterfaceLinkLibraries/zot.cpp
@@ -0,0 +1,6 @@
+#include "zot.h"
+
+int zot()
+{
+ return 0;
+}
diff --git a/Tests/InterfaceLinkLibraries/zot.h b/Tests/InterfaceLinkLibraries/zot.h
new file mode 100644
index 000000000..5e4fb1eba
--- /dev/null
+++ b/Tests/InterfaceLinkLibraries/zot.h
@@ -0,0 +1,7 @@
+
+#include "bar.h"
+
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int zot();
diff --git a/Tests/InterfaceLinkLibraries/zot_vs6_1.cpp b/Tests/InterfaceLinkLibraries/zot_vs6_1.cpp
new file mode 100644
index 000000000..c588c5fe9
--- /dev/null
+++ b/Tests/InterfaceLinkLibraries/zot_vs6_1.cpp
@@ -0,0 +1 @@
+#include "zot.cpp"
diff --git a/Tests/InterfaceLinkLibraries/zot_vs6_2.cpp b/Tests/InterfaceLinkLibraries/zot_vs6_2.cpp
new file mode 100644
index 000000000..c588c5fe9
--- /dev/null
+++ b/Tests/InterfaceLinkLibraries/zot_vs6_2.cpp
@@ -0,0 +1 @@
+#include "zot.cpp"
diff --git a/Tests/InterfaceLinkLibraries/zot_vs6_3.cpp b/Tests/InterfaceLinkLibraries/zot_vs6_3.cpp
new file mode 100644
index 000000000..c588c5fe9
--- /dev/null
+++ b/Tests/InterfaceLinkLibraries/zot_vs6_3.cpp
@@ -0,0 +1 @@
+#include "zot.cpp"
diff --git a/Tests/InterfaceLinkLibraries/zot_vs6_4.cpp b/Tests/InterfaceLinkLibraries/zot_vs6_4.cpp
new file mode 100644
index 000000000..c588c5fe9
--- /dev/null
+++ b/Tests/InterfaceLinkLibraries/zot_vs6_4.cpp
@@ -0,0 +1 @@
+#include "zot.cpp"
diff --git a/Tests/JacocoCoverage/Coverage/src/main/java/org/cmake/CoverageTest.java b/Tests/JacocoCoverage/Coverage/src/main/java/org/cmake/CoverageTest.java
new file mode 100644
index 000000000..4fb43c608
--- /dev/null
+++ b/Tests/JacocoCoverage/Coverage/src/main/java/org/cmake/CoverageTest.java
@@ -0,0 +1,52 @@
+package org.cmake.Coverage;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.List;
+import java.awt.*;
+
+public class CoverageTest {
+
+ public static String VarOne = "test1";
+ public static String VarTwo = "test2";
+ private Integer IntOne = 4;
+
+ public static Boolean equalsVarOne(String inString) {
+
+ if(VarOne.equals(inString)){
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ public static boolean equalsVarTwo(String inString){
+
+ if(VarTwo.equals(inString)){
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ private Integer timesIntOne(Integer inVal){
+
+ return inVal * IntOne;
+ }
+
+ public static boolean whileLoop(Integer StopInt){
+
+ Integer i = 0;
+ while(i < StopInt){
+ i=i+1;
+ }
+ if (i.equals(5)){
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+}
diff --git a/Tests/JacocoCoverage/Coverage/target/site/jacoco.xml.in b/Tests/JacocoCoverage/Coverage/target/site/jacoco.xml.in
new file mode 100644
index 000000000..49c3e8740
--- /dev/null
+++ b/Tests/JacocoCoverage/Coverage/target/site/jacoco.xml.in
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?><!DOCTYPE report PUBLIC "-//JACOCO//DTD Report 1.0//EN" "report.dtd"><report name="Coverage"><sessioninfo id="vagrant-ubuntu-precise-32-f1c264e9" start="1402427058670" dump="1402427059269"/><package name="org/cmake"><class name="org/cmake/Coverage/CoverageTest"><method name="&lt;init&gt;" desc="()V" line="8"><counter type="INSTRUCTION" missed="7" covered="0"/><counter type="LINE" missed="2" covered="0"/><counter type="COMPLEXITY" missed="1" covered="0"/><counter type="METHOD" missed="1" covered="0"/></method><method name="equalsVarOne" desc="(Ljava/lang/String;)Ljava/lang/Boolean;" line="16"><counter type="INSTRUCTION" missed="3" covered="7"/><counter type="BRANCH" missed="1" covered="1"/><counter type="LINE" missed="1" covered="2"/><counter type="COMPLEXITY" missed="1" covered="1"/><counter type="METHOD" missed="0" covered="1"/></method><method name="equalsVarTwo" desc="(Ljava/lang/String;)Z" line="26"><counter type="INSTRUCTION" missed="0" covered="8"/><counter type="BRANCH" missed="0" covered="2"/><counter type="LINE" missed="0" covered="3"/><counter type="COMPLEXITY" missed="0" covered="2"/><counter type="METHOD" missed="0" covered="1"/></method><method name="timesIntOne" desc="(Ljava/lang/Integer;)Ljava/lang/Integer;" line="36"><counter type="INSTRUCTION" missed="8" covered="0"/><counter type="LINE" missed="1" covered="0"/><counter type="COMPLEXITY" missed="1" covered="0"/><counter type="METHOD" missed="1" covered="0"/></method><method name="whileLoop" desc="(Ljava/lang/Integer;)Z" line="41"><counter type="INSTRUCTION" missed="0" covered="24"/><counter type="BRANCH" missed="0" covered="4"/><counter type="LINE" missed="0" covered="6"/><counter type="COMPLEXITY" missed="0" covered="3"/><counter type="METHOD" missed="0" covered="1"/></method><method name="&lt;clinit&gt;" desc="()V" line="10"><counter type="INSTRUCTION" missed="0" covered="5"/><counter type="LINE" missed="0" covered="2"/><counter type="COMPLEXITY" missed="0" covered="1"/><counter type="METHOD" missed="0" covered="1"/></method><counter type="INSTRUCTION" missed="18" covered="44"/><counter type="BRANCH" missed="1" covered="7"/><counter type="LINE" missed="4" covered="13"/><counter type="COMPLEXITY" missed="3" covered="7"/><counter type="METHOD" missed="2" covered="4"/><counter type="CLASS" missed="0" covered="1"/></class><sourcefile name="CoverageTest.java"><line nr="8" mi="2" ci="0" mb="0" cb="0"/><line nr="10" mi="0" ci="2" mb="0" cb="0"/><line nr="11" mi="0" ci="3" mb="0" cb="0"/><line nr="12" mi="5" ci="0" mb="0" cb="0"/><line nr="16" mi="0" ci="4" mb="1" cb="1"/><line nr="17" mi="0" ci="3" mb="0" cb="0"/><line nr="20" mi="3" ci="0" mb="0" cb="0"/><line nr="26" mi="0" ci="4" mb="0" cb="2"/><line nr="27" mi="0" ci="2" mb="0" cb="0"/><line nr="30" mi="0" ci="2" mb="0" cb="0"/><line nr="36" mi="8" ci="0" mb="0" cb="0"/><line nr="41" mi="0" ci="3" mb="0" cb="0"/><line nr="42" mi="0" ci="5" mb="0" cb="2"/><line nr="43" mi="0" ci="7" mb="0" cb="0"/><line nr="45" mi="0" ci="5" mb="0" cb="2"/><line nr="46" mi="0" ci="2" mb="0" cb="0"/><line nr="49" mi="0" ci="2" mb="0" cb="0"/><counter type="INSTRUCTION" missed="18" covered="44"/><counter type="BRANCH" missed="1" covered="7"/><counter type="LINE" missed="4" covered="13"/><counter type="COMPLEXITY" missed="3" covered="7"/><counter type="METHOD" missed="2" covered="4"/><counter type="CLASS" missed="0" covered="1"/></sourcefile><counter type="INSTRUCTION" missed="18" covered="44"/><counter type="BRANCH" missed="1" covered="7"/><counter type="LINE" missed="4" covered="13"/><counter type="COMPLEXITY" missed="3" covered="7"/><counter type="METHOD" missed="2" covered="4"/><counter type="CLASS" missed="0" covered="1"/></package><counter type="INSTRUCTION" missed="18" covered="44"/><counter type="BRANCH" missed="1" covered="7"/><counter type="LINE" missed="4" covered="13"/><counter type="COMPLEXITY" missed="3" covered="7"/><counter type="METHOD" missed="2" covered="4"/><counter type="CLASS" missed="0" covered="1"/></report>
diff --git a/Tests/JacocoCoverage/DartConfiguration.tcl.in b/Tests/JacocoCoverage/DartConfiguration.tcl.in
new file mode 100644
index 000000000..cc10e9c76
--- /dev/null
+++ b/Tests/JacocoCoverage/DartConfiguration.tcl.in
@@ -0,0 +1,8 @@
+# This file is configured by CMake automatically as DartConfiguration.tcl
+# If you choose not to use CMake, this file may be hand configured, by
+# filling in the required variables.
+
+
+# Configuration directories and files
+SourceDirectory: ${CMake_BINARY_DIR}/Testing/JacocoCoverage
+BuildDirectory: ${CMake_BINARY_DIR}/Testing/JacocoCoverage
diff --git a/Tests/Java/CMakeLists.txt b/Tests/Java/CMakeLists.txt
index 6a69a2464..e1bcf3c20 100644
--- a/Tests/Java/CMakeLists.txt
+++ b/Tests/Java/CMakeLists.txt
@@ -7,3 +7,7 @@ find_package(Java COMPONENTS Development)
include (UseJava)
add_jar(hello A.java HelloWorld.java)
+
+# use listing file to specify sources
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/java_fileslist "A.java\nHelloWorld.java\n")
+add_jar(hello2 @${CMAKE_CURRENT_BINARY_DIR}/java_fileslist)
diff --git a/Tests/JavaJavah/B.cpp b/Tests/JavaJavah/B.cpp
new file mode 100644
index 000000000..266675703
--- /dev/null
+++ b/Tests/JavaJavah/B.cpp
@@ -0,0 +1,10 @@
+
+#include <jni.h>
+#include <stdio.h>
+
+#include "B.h"
+
+JNIEXPORT void JNICALL Java_B_printName(JNIEnv *, jobject)
+{
+ printf("B\n");
+}
diff --git a/Tests/JavaJavah/B.java b/Tests/JavaJavah/B.java
new file mode 100644
index 000000000..d731f396c
--- /dev/null
+++ b/Tests/JavaJavah/B.java
@@ -0,0 +1,19 @@
+class B
+{
+ public B()
+ {
+ }
+
+ public native void printName();
+
+ static {
+ try {
+
+ System.loadLibrary("B");
+
+ } catch (UnsatisfiedLinkError e) {
+ System.err.println("Native code library failed to load.\n" + e);
+ System.exit(1);
+ }
+ }
+}
diff --git a/Tests/JavaJavah/C.cpp b/Tests/JavaJavah/C.cpp
new file mode 100644
index 000000000..ec75f4213
--- /dev/null
+++ b/Tests/JavaJavah/C.cpp
@@ -0,0 +1,10 @@
+
+#include <jni.h>
+#include <stdio.h>
+
+#include "C.h"
+
+JNIEXPORT void JNICALL Java_C_printName(JNIEnv *, jobject)
+{
+ printf("C\n");
+}
diff --git a/Tests/JavaJavah/C.java b/Tests/JavaJavah/C.java
new file mode 100644
index 000000000..54b1be205
--- /dev/null
+++ b/Tests/JavaJavah/C.java
@@ -0,0 +1,19 @@
+class C
+{
+ public C()
+ {
+ }
+
+ public native void printName();
+
+ static {
+ try {
+
+ System.loadLibrary("B");
+
+ } catch (UnsatisfiedLinkError e) {
+ System.err.println("Native code library failed to load.\n" + e);
+ System.exit(1);
+ }
+ }
+}
diff --git a/Tests/JavaJavah/CMakeLists.txt b/Tests/JavaJavah/CMakeLists.txt
new file mode 100644
index 000000000..071bf20d6
--- /dev/null
+++ b/Tests/JavaJavah/CMakeLists.txt
@@ -0,0 +1,23 @@
+project(helloJavah Java CXX)
+
+cmake_minimum_required (VERSION 2.6)
+set(CMAKE_VERBOSE_MAKEFILE 1)
+
+find_package(Java COMPONENTS Development)
+include (UseJava)
+
+# JNI support
+find_package(JNI)
+
+add_jar(B1 B.java)
+add_jar(C1 C.java)
+create_javah(TARGET B_javah CLASSES B C CLASSPATH B1 C1)
+
+add_jar(hello3 HelloWorld2.java)
+
+add_library(B SHARED B.cpp C.cpp)
+add_dependencies(B B_javah)
+
+target_include_directories(B PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
+ ${JAVA_INCLUDE_PATH}
+ ${JAVA_INCLUDE_PATH2})
diff --git a/Tests/JavaJavah/HelloWorld2.java b/Tests/JavaJavah/HelloWorld2.java
new file mode 100644
index 000000000..5ff710f95
--- /dev/null
+++ b/Tests/JavaJavah/HelloWorld2.java
@@ -0,0 +1,15 @@
+class HelloWorld2
+{
+ public static void main(String args[])
+ {
+ B b;
+ b = new B();
+ b.printName();
+
+ C c;
+ c = new C();
+ c.printName();
+
+ System.out.println("Hello World!");
+ }
+}
diff --git a/Tests/JavascriptCoverage/DartConfiguration.tcl.in b/Tests/JavascriptCoverage/DartConfiguration.tcl.in
new file mode 100644
index 000000000..f94d98869
--- /dev/null
+++ b/Tests/JavascriptCoverage/DartConfiguration.tcl.in
@@ -0,0 +1,8 @@
+# This file is configured by CMake automatically as DartConfiguration.tcl
+# If you choose not to use CMake, this file may be hand configured, by
+# filling in the required variables.
+
+
+# Configuration directories and files
+SourceDirectory: ${CMake_BINARY_DIR}/Testing/JavascriptCoverage
+BuildDirectory: ${CMake_BINARY_DIR}/Testing/JavascriptCoverage
diff --git a/Tests/JavascriptCoverage/output.json.in b/Tests/JavascriptCoverage/output.json.in
new file mode 100644
index 000000000..717cffe62
--- /dev/null
+++ b/Tests/JavascriptCoverage/output.json.in
@@ -0,0 +1,448 @@
+{
+ "instrumentation": "node-jscoverage",
+ "sloc": 29,
+ "hits": 28,
+ "misses": 1,
+ "coverage": 96.55172413793103,
+ "files": [
+ {
+ "filename": "${CMake_BINARY_DIR}/Testing/JavascriptCoverage/test.js",
+ "coverage": 96.55172413793103,
+ "hits": 28,
+ "misses": 1,
+ "sloc": 29,
+ "source": {
+ "1": {
+ "source": "var assert = require(\"assert\")",
+ "coverage": 1
+ },
+ "2": {
+ "source": "var test = {",
+ "coverage": 1
+ },
+ "3": {
+ "source": " version: \"1.0.0\"",
+ "coverage": ""
+ },
+ "4": {
+ "source": "}",
+ "coverage": ""
+ },
+ "5": {
+ "source": "function covTest(p1,p2) {",
+ "coverage": 1
+ },
+ "6": {
+ "source": " if (p1 > 3) {",
+ "coverage": 2
+ },
+ "7": {
+ "source": " return 1;",
+ "coverage": 1
+ },
+ "8": {
+ "source": " }",
+ "coverage": ""
+ },
+ "9": {
+ "source": " else {",
+ "coverage": ""
+ },
+ "10": {
+ "source": " return p1 + p2;",
+ "coverage": 1
+ },
+ "11": {
+ "source": " }",
+ "coverage": ""
+ },
+ "12": {
+ "source": "}",
+ "coverage": ""
+ },
+ "13": {
+ "source": "",
+ "coverage": ""
+ },
+ "14": {
+ "source": "function covTest2(p1,p2) {",
+ "coverage": 1
+ },
+ "15": {
+ "source": " return 0;",
+ "coverage": 0
+ },
+ "16": {
+ "source": "}",
+ "coverage": ""
+ },
+ "17": {
+ "source": "",
+ "coverage": ""
+ },
+ "18": {
+ "source": "function covTest3(p1) {",
+ "coverage": 1
+ },
+ "19": {
+ "source": " for(i=0;i < p1;i++){",
+ "coverage": 1
+ },
+ "20": {
+ "source": " }",
+ "coverage": ""
+ },
+ "21": {
+ "source": " return i;",
+ "coverage": 1
+ },
+ "22": {
+ "source": "}",
+ "coverage": ""
+ },
+ "23": {
+ "source": "function covTest4(p1) {",
+ "coverage": 1
+ },
+ "24": {
+ "source": " i=0;",
+ "coverage": 1
+ },
+ "25": {
+ "source": " while(i < p1){",
+ "coverage": 1
+ },
+ "26": {
+ "source": " i++;",
+ "coverage": 5
+ },
+ "27": {
+ "source": " }",
+ "coverage": ""
+ },
+ "28": {
+ "source": " return i;",
+ "coverage": 1
+ },
+ "29": {
+ "source": "}",
+ "coverage": ""
+ },
+ "30": {
+ "source": "",
+ "coverage": ""
+ },
+ "31": {
+ "source": "describe('Array', function(){",
+ "coverage": 1
+ },
+ "32": {
+ "source": " describe('CovTest', function(){",
+ "coverage": 1
+ },
+ "33": {
+ "source": " it('should return when the value is not present', function(){",
+ "coverage": 1
+ },
+ "34": {
+ "source": " assert.equal(4,covTest(2,2));",
+ "coverage": 1
+ },
+ "35": {
+ "source": " })",
+ "coverage": ""
+ },
+ "36": {
+ "source": " })",
+ "coverage": ""
+ },
+ "37": {
+ "source": " ",
+ "coverage": ""
+ },
+ "38": {
+ "source": " describe('CovTest>3', function(){",
+ "coverage": 1
+ },
+ "39": {
+ "source": " it('should return when the value is not present', function(){",
+ "coverage": 1
+ },
+ "40": {
+ "source": " assert.equal(1,covTest(4,2));",
+ "coverage": 1
+ },
+ "41": {
+ "source": " })",
+ "coverage": ""
+ },
+ "42": {
+ "source": " })",
+ "coverage": ""
+ },
+ "43": {
+ "source": " describe('covTest4', function(){",
+ "coverage": 1
+ },
+ "44": {
+ "source": " it('should return when the value is not present', function(){",
+ "coverage": 1
+ },
+ "45": {
+ "source": " assert.equal(5,covTest4(5));",
+ "coverage": 1
+ },
+ "46": {
+ "source": " })",
+ "coverage": ""
+ },
+ "47": {
+ "source": " })",
+ "coverage": ""
+ },
+ "48": {
+ "source": " describe('covTest3', function(){",
+ "coverage": 1
+ },
+ "49": {
+ "source": " it('should return when the value is not present', function(){",
+ "coverage": 1
+ },
+ "50": {
+ "source": " assert.equal(5,covTest3(5));",
+ "coverage": 1
+ },
+ "51": {
+ "source": " })",
+ "coverage": ""
+ },
+ "52": {
+ "source": " })",
+ "coverage": ""
+ },
+ "53": {
+ "source": "})",
+ "coverage": ""
+ },
+ "54": {
+ "source": "",
+ "coverage": ""
+ }
+ }
+ "filename": "${CMake_BINARY_DIR}/Testing/JavascriptCoverage/test3.js",
+ "coverage": 55.00000000000001,
+ "hits": 11,
+ "misses": 9,
+ "sloc": 20,
+ "source": {
+ "1": {
+ "source": "var assert = require(\"assert\")",
+ "coverage": 1
+ },
+ "2": {
+ "source": "var test = {",
+ "coverage": 1
+ },
+ "3": {
+ "source": " version: \"1.0.0\"",
+ "coverage": ""
+ },
+ "4": {
+ "source": "}",
+ "coverage": ""
+ },
+ "5": {
+ "source": "function covTest(p1,p2) {",
+ "coverage": 1
+ },
+ "6": {
+ "source": " if (p1 > 3) {",
+ "coverage": 0
+ },
+ "7": {
+ "source": " return 1;",
+ "coverage": 0
+ },
+ "8": {
+ "source": " }",
+ "coverage": ""
+ },
+ "9": {
+ "source": " else {",
+ "coverage": ""
+ },
+ "10": {
+ "source": " return p1 + p2;",
+ "coverage": 0
+ },
+ "11": {
+ "source": " }",
+ "coverage": ""
+ },
+ "12": {
+ "source": "}",
+ "coverage": ""
+ },
+ "13": {
+ "source": "",
+ "coverage": ""
+ },
+ "14": {
+ "source": "function covTest2(p1,p2) {",
+ "coverage": 1
+ },
+ "15": {
+ "source": " return 0;",
+ "coverage": 1
+ },
+ "16": {
+ "source": "}",
+ "coverage": ""
+ },
+ "17": {
+ "source": "",
+ "coverage": ""
+ },
+ "18": {
+ "source": "function covTest3(p1) {",
+ "coverage": 1
+ },
+ "19": {
+ "source": " for(i=0;i < p1;i++){",
+ "coverage": 0
+ },
+ "20": {
+ "source": " }",
+ "coverage": ""
+ },
+ "21": {
+ "source": " return i;",
+ "coverage": 0
+ },
+ "22": {
+ "source": "}",
+ "coverage": ""
+ },
+ "23": {
+ "source": "function covTest4(p1) {",
+ "coverage": 1
+ },
+ "24": {
+ "source": " i=0;",
+ "coverage": 0
+ },
+ "25": {
+ "source": " while(i < p1){",
+ "coverage": 0
+ },
+ "26": {
+ "source": " i++;",
+ "coverage": 0
+ },
+ "27": {
+ "source": " }",
+ "coverage": ""
+ },
+ "28": {
+ "source": " return i;",
+ "coverage": 0
+ },
+ "29": {
+ "source": "}",
+ "coverage": ""
+ },
+ "30": {
+ "source": "",
+ "coverage": ""
+ },
+ "31": {
+ "source": "describe('Array', function(){",
+ "coverage": 1
+ },
+ "32": {
+ "source": " describe('CovTest2', function(){",
+ "coverage": 1
+ },
+ "33": {
+ "source": " it('should return when the value is not present', function(){",
+ "coverage": 1
+ },
+ "34": {
+ "source": " assert.equal(0,covTest2(2,2));",
+ "coverage": 1
+ },
+ "35": {
+ "source": " })",
+ "coverage": ""
+ },
+ "36": {
+ "source": " })",
+ "coverage": ""
+ },
+ "37": {
+ "source": "})",
+ "coverage": ""
+ },
+ "38": {
+ "source": "",
+ "coverage": ""
+ }
+ }
+ }
+ ],
+ "stats": {
+ "suites": 5,
+ "tests": 4,
+ "passes": 4,
+ "pending": 0,
+ "failures": 0,
+ "start": "2014-10-23T17:56:02.339Z",
+ "end": "2014-10-23T17:56:02.344Z",
+ "duration": 5
+ },
+ "tests": [
+ {
+ "title": "should return when the value is not present",
+ "fullTitle": "Array CovTest should return when the value is not present",
+ "duration": 0
+ },
+ {
+ "title": "should return when the value is not present",
+ "fullTitle": "Array CovTest>3 should return when the value is not present",
+ "duration": 0
+ },
+ {
+ "title": "should return when the value is not present",
+ "fullTitle": "Array covTest4 should return when the value is not present",
+ "duration": 0
+ },
+ {
+ "title": "should return when the value is not present",
+ "fullTitle": "Array covTest3 should return when the value is not present",
+ "duration": 0
+ }
+ ],
+ "failures": [],
+ "passes": [
+ {
+ "title": "should return when the value is not present",
+ "fullTitle": "Array CovTest should return when the value is not present",
+ "duration": 0
+ },
+ {
+ "title": "should return when the value is not present",
+ "fullTitle": "Array CovTest>3 should return when the value is not present",
+ "duration": 0
+ },
+ {
+ "title": "should return when the value is not present",
+ "fullTitle": "Array covTest4 should return when the value is not present",
+ "duration": 0
+ },
+ {
+ "title": "should return when the value is not present",
+ "fullTitle": "Array covTest3 should return when the value is not present",
+ "duration": 0
+ }
+ ]
+} \ No newline at end of file
diff --git a/Tests/JavascriptCoverage/test.js b/Tests/JavascriptCoverage/test.js
new file mode 100644
index 000000000..273e921c9
--- /dev/null
+++ b/Tests/JavascriptCoverage/test.js
@@ -0,0 +1,53 @@
+var assert = require("assert")
+var test = {
+ version: "1.0.0"
+}
+function covTest(p1,p2) {
+ if (p1 > 3) {
+ return 1;
+ }
+ else {
+ return p1 + p2;
+ }
+}
+
+function covTest2(p1,p2) {
+ return 0;
+}
+
+function covTest3(p1) {
+ for(i=0;i < p1;i++){
+ }
+ return i;
+}
+function covTest4(p1) {
+ i=0;
+ while(i < p1){
+ i++;
+ }
+ return i;
+}
+
+describe('Array', function(){
+ describe('CovTest', function(){
+ it('should return when the value is not present', function(){
+ assert.equal(4,covTest(2,2));
+ })
+ })
+
+ describe('CovTest>3', function(){
+ it('should return when the value is not present', function(){
+ assert.equal(1,covTest(4,2));
+ })
+ })
+ describe('covTest4', function(){
+ it('should return when the value is not present', function(){
+ assert.equal(5,covTest4(5));
+ })
+ })
+ describe('covTest3', function(){
+ it('should return when the value is not present', function(){
+ assert.equal(5,covTest3(5));
+ })
+ })
+})
diff --git a/Tests/JavascriptCoverage/test3.js b/Tests/JavascriptCoverage/test3.js
new file mode 100644
index 000000000..a1e31bc18
--- /dev/null
+++ b/Tests/JavascriptCoverage/test3.js
@@ -0,0 +1,37 @@
+var assert = require("assert")
+var test = {
+ version: "1.0.0"
+}
+function covTest(p1,p2) {
+ if (p1 > 3) {
+ return 1;
+ }
+ else {
+ return p1 + p2;
+ }
+}
+
+function covTest2(p1,p2) {
+ return 0;
+}
+
+function covTest3(p1) {
+ for(i=0;i < p1;i++){
+ }
+ return i;
+}
+function covTest4(p1) {
+ i=0;
+ while(i < p1){
+ i++;
+ }
+ return i;
+}
+
+describe('Array', function(){
+ describe('CovTest2', function(){
+ it('should return when the value is not present', function(){
+ assert.equal(0,covTest2(2,2));
+ })
+ })
+})
diff --git a/Tests/LinkDirectory/CMakeLists.txt b/Tests/LinkDirectory/CMakeLists.txt
index 7356b27d2..c60de84e9 100644
--- a/Tests/LinkDirectory/CMakeLists.txt
+++ b/Tests/LinkDirectory/CMakeLists.txt
@@ -11,13 +11,11 @@ endif()
add_library(mylibA STATIC mylibA.c)
set_property(TARGET mylibA PROPERTY
ARCHIVE_OUTPUT_DIRECTORY "${LinkDirectory_BINARY_DIR}/External/lib")
-get_property(mylibA TARGET mylibA PROPERTY LOCATION)
# Build a library into our build tree relative to the subproject build tree.
add_library(mylibB STATIC mylibB.c)
set_property(TARGET mylibB PROPERTY
ARCHIVE_OUTPUT_DIRECTORY "${LinkDirectory_BINARY_DIR}/lib")
-get_property(mylibB TARGET mylibB PROPERTY LOCATION)
# Create a custom target to drive the subproject build.
include(ExternalProject)
@@ -38,7 +36,7 @@ ExternalProject_Add_Step(ExternalTarget cleanup
COMMAND ${CMAKE_COMMAND} -E remove_directory ${LinkDirectory_BINARY_DIR}/bin
DEPENDEES download
DEPENDERS configure
- DEPENDS ${mylibA} ${mylibB}
+ DEPENDS mylibA mylibB
"${LinkDirectory_BINARY_DIR}/External/CMakeLists.txt"
"${LinkDirectory_BINARY_DIR}/External/myexe.c"
)
diff --git a/Tests/LinkStatic/CMakeLists.txt b/Tests/LinkStatic/CMakeLists.txt
index 2062c4345..200d4e51c 100644
--- a/Tests/LinkStatic/CMakeLists.txt
+++ b/Tests/LinkStatic/CMakeLists.txt
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 2.8.4.20110303 FATAL_ERROR)
project(LinkStatic C)
-if(NOT "${CMAKE_C_COMPILER_ID}" MATCHES "^(GNU)$")
+if(NOT CMAKE_C_COMPILER_ID STREQUAL "GNU")
message(FATAL_ERROR "This test works only with the GNU compiler!")
endif()
diff --git a/Tests/LoadCommand/CMakeLists.txt b/Tests/LoadCommand/CMakeLists.txt
index c9337987a..03a3b4942 100644
--- a/Tests/LoadCommand/CMakeLists.txt
+++ b/Tests/LoadCommand/CMakeLists.txt
@@ -8,10 +8,6 @@ include (${CMAKE_ROOT}/Modules/CheckTypeSize.cmake)
CHECK_TYPE_SIZE(char SIZEOF_CHAR)
CHECK_TYPE_SIZE(short SIZEOF_SHORT)
-include (CheckFunctionExists)
-CHECK_FUNCTION_EXISTS(printf HAVE_PRINTF)
-CHECK_FUNCTION_EXISTS(vsblabla HAVE_VSBLABLA)
-
configure_file(${LoadCommand_SOURCE_DIR}/LoadedCommand.h.in
${LoadCommand_BINARY_DIR}/LoadedCommand.h)
diff --git a/Tests/LoadCommand/LoadedCommand.cxx.in b/Tests/LoadCommand/LoadedCommand.cxx.in
index c58bcf153..72ec014f1 100644
--- a/Tests/LoadCommand/LoadedCommand.cxx.in
+++ b/Tests/LoadCommand/LoadedCommand.cxx.in
@@ -9,15 +9,6 @@ int testSizeOf(int s1, int s2)
int main ()
{
int ret = 0;
-#ifdef HAVE_VSBLABLA
- printf("Should not be able to find vsblabla\n");
- ret = 1;
-#endif
-
-#if !defined( HAVE_PRINTF )
- printf("Should be able to find printf\n");
- ret= 1;
-#endif
#if !defined( ADDED_DEFINITION )
printf("Should have ADDED_DEFINITION defined\n");
diff --git a/Tests/LoadCommand/LoadedCommand.h.in b/Tests/LoadCommand/LoadedCommand.h.in
index 7516a66e5..733c414a3 100644
--- a/Tests/LoadCommand/LoadedCommand.h.in
+++ b/Tests/LoadCommand/LoadedCommand.h.in
@@ -1,7 +1,3 @@
/* Check for size of types */
#cmakedefine SIZEOF_CHAR ${SIZEOF_CHAR}
#cmakedefine SIZEOF_SHORT ${SIZEOF_SHORT}
-
-/* Check for functions */
-#cmakedefine HAVE_PRINTF
-#cmakedefine HAVE_VSBLABLA
diff --git a/Tests/LoadCommandOneConfig/CMakeLists.txt b/Tests/LoadCommandOneConfig/CMakeLists.txt
index a75ad5aa5..6affd343f 100644
--- a/Tests/LoadCommandOneConfig/CMakeLists.txt
+++ b/Tests/LoadCommandOneConfig/CMakeLists.txt
@@ -8,10 +8,6 @@ include (${CMAKE_ROOT}/Modules/CheckTypeSize.cmake)
CHECK_TYPE_SIZE(char SIZEOF_CHAR)
CHECK_TYPE_SIZE(short SIZEOF_SHORT)
-include (CheckFunctionExists)
-CHECK_FUNCTION_EXISTS(printf HAVE_PRINTF)
-CHECK_FUNCTION_EXISTS(vsblabla HAVE_VSBLABLA)
-
include (${CMAKE_ROOT}/Modules/CheckIncludeFile.cmake)
CHECK_INCLUDE_FILE("sys/prctl.h" HAVE_SYS_PRCTL_H)
diff --git a/Tests/LoadCommandOneConfig/LoadedCommand.cxx.in b/Tests/LoadCommandOneConfig/LoadedCommand.cxx.in
index c58bcf153..72ec014f1 100644
--- a/Tests/LoadCommandOneConfig/LoadedCommand.cxx.in
+++ b/Tests/LoadCommandOneConfig/LoadedCommand.cxx.in
@@ -9,15 +9,6 @@ int testSizeOf(int s1, int s2)
int main ()
{
int ret = 0;
-#ifdef HAVE_VSBLABLA
- printf("Should not be able to find vsblabla\n");
- ret = 1;
-#endif
-
-#if !defined( HAVE_PRINTF )
- printf("Should be able to find printf\n");
- ret= 1;
-#endif
#if !defined( ADDED_DEFINITION )
printf("Should have ADDED_DEFINITION defined\n");
diff --git a/Tests/LoadCommandOneConfig/LoadedCommand.h.in b/Tests/LoadCommandOneConfig/LoadedCommand.h.in
index 7a0a15d4d..d748d063e 100644
--- a/Tests/LoadCommandOneConfig/LoadedCommand.h.in
+++ b/Tests/LoadCommandOneConfig/LoadedCommand.h.in
@@ -2,10 +2,6 @@
#cmakedefine SIZEOF_CHAR ${SIZEOF_CHAR}
#cmakedefine SIZEOF_SHORT ${SIZEOF_SHORT}
-/* Check for functions */
-#cmakedefine HAVE_PRINTF
-#cmakedefine HAVE_VSBLABLA
-
/* Check for headers */
#cmakedefine HAVE_SYS_PRCTL_H
diff --git a/Tests/MSManifest/CMakeLists.txt b/Tests/MSManifest/CMakeLists.txt
new file mode 100644
index 000000000..300cfa6bb
--- /dev/null
+++ b/Tests/MSManifest/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.3)
+project(MSManifest C)
+
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+add_subdirectory(Subdir)
diff --git a/Tests/MSManifest/Subdir/CMakeLists.txt b/Tests/MSManifest/Subdir/CMakeLists.txt
new file mode 100644
index 000000000..11272bb9f
--- /dev/null
+++ b/Tests/MSManifest/Subdir/CMakeLists.txt
@@ -0,0 +1,11 @@
+configure_file(test.manifest.in test.manifest)
+add_executable(MSManifest main.c ${CMAKE_CURRENT_BINARY_DIR}/test.manifest)
+
+if(MSVC AND NOT MSVC_VERSION LESS 1400)
+ add_custom_command(TARGET MSManifest POST_BUILD VERBATIM
+ COMMAND ${CMAKE_COMMAND} -Dexe=$<TARGET_FILE:MSManifest>
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake
+ )
+ add_executable(MSManifestNone main.c)
+ set_property(TARGET MSManifestNone PROPERTY LINK_FLAGS "/MANIFEST:NO")
+endif()
diff --git a/Tests/MSManifest/Subdir/check.cmake b/Tests/MSManifest/Subdir/check.cmake
new file mode 100644
index 000000000..b7b68410b
--- /dev/null
+++ b/Tests/MSManifest/Subdir/check.cmake
@@ -0,0 +1,6 @@
+file(STRINGS "${exe}" content REGEX "name=\"Kitware.CMake.MSManifestTest\"")
+if(content)
+ message(STATUS "Expected manifest content found:\n ${content}")
+else()
+ message(FATAL_ERROR "Expected manifest content not found in\n ${exe}")
+endif()
diff --git a/Tests/MSManifest/Subdir/main.c b/Tests/MSManifest/Subdir/main.c
new file mode 100644
index 000000000..78f2de106
--- /dev/null
+++ b/Tests/MSManifest/Subdir/main.c
@@ -0,0 +1 @@
+int main(void) { return 0; }
diff --git a/Tests/MSManifest/Subdir/test.manifest.in b/Tests/MSManifest/Subdir/test.manifest.in
new file mode 100644
index 000000000..540961ac5
--- /dev/null
+++ b/Tests/MSManifest/Subdir/test.manifest.in
@@ -0,0 +1,4 @@
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity type="win32" version="1.0.0.0"
+ name="Kitware.CMake.MSManifestTest"/>
+</assembly>
diff --git a/Tests/MacRuntimePath/A/CMakeLists.txt b/Tests/MacRuntimePath/A/CMakeLists.txt
index 5fc54f406..ade0a3cfb 100644
--- a/Tests/MacRuntimePath/A/CMakeLists.txt
+++ b/Tests/MacRuntimePath/A/CMakeLists.txt
@@ -10,13 +10,15 @@ add_library(shared2 SHARED shared.cpp shared.h)
set_target_properties(shared2 PROPERTIES
BUILD_WITH_INSTALL_RPATH 1 INSTALL_NAME_DIR "@rpath")
+cmake_policy(SET CMP0042 NEW)
+
# a framework library
add_library(framework SHARED framework.cpp framework.h)
-set_target_properties(framework PROPERTIES MACOSX_RPATH 1 FRAMEWORK 1)
+set_target_properties(framework PROPERTIES FRAMEWORK 1)
# another framework
add_library(framework2 SHARED framework2.cpp framework2.h)
-set_target_properties(framework2 PROPERTIES MACOSX_RPATH 1 FRAMEWORK 1)
+set_target_properties(framework2 PROPERTIES FRAMEWORK 1)
# executable to test a shared library dependency with install rpaths
add_executable(test1 test1.cpp)
diff --git a/Tests/MacRuntimePath/CMakeLists.txt b/Tests/MacRuntimePath/CMakeLists.txt
index 5e5b6c421..3e9ab8a55 100644
--- a/Tests/MacRuntimePath/CMakeLists.txt
+++ b/Tests/MacRuntimePath/CMakeLists.txt
@@ -1,6 +1,8 @@
cmake_minimum_required (VERSION 2.8)
project(MacRuntimePath)
-
+if(NOT DEFINED CMake_TEST_NESTED_MAKE_PROGRAM AND NOT CMAKE_GENERATOR MATCHES "Visual Studio")
+ set(CMake_TEST_NESTED_MAKE_PROGRAM "${CMAKE_MAKE_PROGRAM}")
+endif()
# Wipe out the install tree to make sure the exporter works.
add_custom_command(
@@ -37,8 +39,8 @@ add_custom_command(
--build-project MacRuntimePath_A
--build-target install
--build-generator ${CMAKE_GENERATOR}
+ --build-generator-platform "${CMAKE_GENERATOR_PLATFORM}"
--build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
- --build-makeprogram ${CMAKE_MAKE_PROGRAM}
--build-options -C${MacRuntimePath_BINARY_DIR}/InitialCache.cmake
VERBATIM
)
@@ -59,8 +61,8 @@ add_custom_command(
--build-noclean
--build-project MacRuntimePath_B
--build-generator ${CMAKE_GENERATOR}
+ --build-generator-platform "${CMAKE_GENERATOR_PLATFORM}"
--build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
- --build-makeprogram ${CMAKE_MAKE_PROGRAM}
--build-options -C${MacRuntimePath_BINARY_DIR}/InitialCache.cmake
VERBATIM
)
diff --git a/Tests/MacRuntimePath/InitialCache.cmake.in b/Tests/MacRuntimePath/InitialCache.cmake.in
index be15eb30b..a9f6a3c0d 100644
--- a/Tests/MacRuntimePath/InitialCache.cmake.in
+++ b/Tests/MacRuntimePath/InitialCache.cmake.in
@@ -1,3 +1,4 @@
+set(CMAKE_MAKE_PROGRAM "@CMake_TEST_NESTED_MAKE_PROGRAM@" CACHE FILEPATH "Make Program")
set(CMAKE_C_COMPILER "@CMAKE_C_COMPILER@" CACHE STRING "C Compiler")
set(CMAKE_C_FLAGS "@CMAKE_C_FLAGS@" CACHE STRING "C Flags")
set(CMAKE_C_FLAGS_DEBUG "@CMAKE_C_FLAGS_DEBUG@" CACHE STRING "C Flags")
diff --git a/Tests/MacroTest/CMakeLists.txt b/Tests/MacroTest/CMakeLists.txt
index 02bb31f20..6c6dfb625 100644
--- a/Tests/MacroTest/CMakeLists.txt
+++ b/Tests/MacroTest/CMakeLists.txt
@@ -36,7 +36,7 @@ macro(strange_macro m)
endmacro()
STRANGE_MACRO(var)
set(second_var "second_var")
-if("${var}" STREQUAL "strange_macro" AND "${second_var}" STREQUAL "second_var")
+if("x${var}" STREQUAL "xstrange_macro" AND "x${second_var}" STREQUAL "xsecond_var")
PASS("Case Test" "(${var} ${second_var})")
else()
FAILED("Case test" "(${var} ${second_var})")
diff --git a/Tests/MakeClean/CMakeLists.txt b/Tests/MakeClean/CMakeLists.txt
index 13348a28b..8ac624a63 100644
--- a/Tests/MakeClean/CMakeLists.txt
+++ b/Tests/MakeClean/CMakeLists.txt
@@ -37,21 +37,14 @@ foreach(f ${TOCLEAN_FILES})
set(CHECK_FILES "${CHECK_FILES} \"${f}\",\n")
endforeach()
configure_file(${MakeClean_SOURCE_DIR}/check_clean.c.in
- ${MakeClean_BINARY_DIR}/check_clean.c @ONLY IMMEDIATE)
+ ${MakeClean_BINARY_DIR}/check_clean.c @ONLY)
add_executable(check_clean ${MakeClean_BINARY_DIR}/check_clean.c)
# After the executable builds, clean the files.
add_custom_command(
TARGET check_clean
POST_BUILD
- COMMAND ${CMAKE_CTEST_COMMAND}
- ARGS --build-and-test
- ${MakeClean_SOURCE_DIR}/ToClean
- ${MakeClean_BINARY_DIR}/ToClean
- --build-generator ${CMAKE_GENERATOR}
- --build-project ToClean
- --build-makeprogram ${CMAKE_MAKE_PROGRAM}
- --build-noclean
- --build-target clean
+ COMMAND ${CMAKE_COMMAND} --build ${MakeClean_BINARY_DIR}/ToClean
+ --target clean
COMMENT "Clean the ToClean Project"
)
diff --git a/Tests/MakeClean/ToClean/CMakeLists.txt b/Tests/MakeClean/ToClean/CMakeLists.txt
index 28569dd1d..d0e24cefe 100644
--- a/Tests/MakeClean/ToClean/CMakeLists.txt
+++ b/Tests/MakeClean/ToClean/CMakeLists.txt
@@ -5,7 +5,6 @@ project(ToClean)
add_executable(toclean toclean.cxx)
# List some build-time-generated files.
-get_target_property(TOCLEAN_FILES toclean LOCATION)
set(TOCLEAN_FILES ${TOCLEAN_FILES}
"${ToClean_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/toclean.dir/toclean.cxx${CMAKE_CXX_OUTPUT_EXTENSION}")
@@ -26,6 +25,18 @@ add_custom_command(OUTPUT ${ToClean_BINARY_DIR}/generated.txt
add_custom_target(generate ALL DEPENDS ${ToClean_BINARY_DIR}/generated.txt)
set(TOCLEAN_FILES ${TOCLEAN_FILES} "${ToClean_BINARY_DIR}/generated.txt")
+# Create a custom command whose output should be cleaned, but whose name
+# is not known until generate-time
+set(copied_exe "$<TARGET_FILE_DIR:toclean>/toclean_copy${CMAKE_EXECUTABLE_SUFFIX}")
+add_custom_command(TARGET toclean POST_BUILD
+ COMMAND ${CMAKE_COMMAND}
+ ARGS -E copy $<TARGET_FILE:toclean>
+ ${copied_exe}
+ )
+set_property(DIRECTORY APPEND PROPERTY
+ ADDITIONAL_MAKE_CLEAN_FILES ${copied_exe})
+list(APPEND TOCLEAN_FILES "${ToClean_BINARY_DIR}/toclean_copy${CMAKE_EXECUTABLE_SUFFIX}")
+
# Configure a file listing these build-time-generated files.
configure_file(${ToClean_SOURCE_DIR}/ToCleanFiles.cmake.in
- ${ToClean_BINARY_DIR}/ToCleanFiles.cmake @ONLY IMMEDIATE)
+ ${ToClean_BINARY_DIR}/ToCleanFiles.cmake @ONLY)
diff --git a/Tests/MissingInstall/CMakeLists.txt b/Tests/MissingInstall/CMakeLists.txt
new file mode 100644
index 000000000..91624f710
--- /dev/null
+++ b/Tests/MissingInstall/CMakeLists.txt
@@ -0,0 +1,25 @@
+cmake_minimum_required (VERSION 2.8.12)
+project(TestMissingInstall)
+
+set(CMAKE_SKIP_INSTALL_RULES ON)
+
+# Skip the dependency that causes a build when installing. This
+# avoids infinite loops when the post-build rule below installs.
+set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY 1)
+set(CMAKE_SKIP_PACKAGE_ALL_DEPENDENCY 1)
+
+if(CMAKE_CONFIGURATION_TYPES)
+ set(MULTI_CONFIG ON)
+else()
+ set(MULTI_CONFIG OFF)
+endif()
+
+add_executable(mybin mybin.cpp)
+install(TARGETS mybin RUNTIME DESTINATION bin)
+
+add_custom_command(TARGET mybin
+ POST_BUILD
+ COMMAND ${CMAKE_COMMAND} "-DMULTI_CONFIG=${MULTI_CONFIG}"
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/ExpectInstallFail.cmake
+ COMMENT "Install Project"
+)
diff --git a/Tests/MissingInstall/ExpectInstallFail.cmake b/Tests/MissingInstall/ExpectInstallFail.cmake
new file mode 100644
index 000000000..3d677bf72
--- /dev/null
+++ b/Tests/MissingInstall/ExpectInstallFail.cmake
@@ -0,0 +1,18 @@
+if(MULTI_CONFIG)
+ set(SI_CONFIG --config $<CONFIGURATION>)
+else()
+ set(SI_CONFIG)
+endif()
+
+execute_process(
+ COMMAND ${CMAKE_COMMAND}
+ --build .
+ --target install ${SI_CONFIG}
+ RESULT_VARIABLE RESULT
+ OUTPUT_VARIABLE OUTPUT
+ ERROR_VARIABLE ERROR
+)
+
+if(RESULT EQUAL 0)
+ message(FATAL_ERROR "install should have failed")
+endif()
diff --git a/Tests/MissingInstall/mybin.cpp b/Tests/MissingInstall/mybin.cpp
new file mode 100644
index 000000000..237c8ce18
--- /dev/null
+++ b/Tests/MissingInstall/mybin.cpp
@@ -0,0 +1 @@
+int main() {}
diff --git a/Tests/Module/CheckTypeSize/CMakeLists.txt b/Tests/Module/CheckTypeSize/CMakeLists.txt
index abe617a16..16989fe23 100644
--- a/Tests/Module/CheckTypeSize/CMakeLists.txt
+++ b/Tests/Module/CheckTypeSize/CMakeLists.txt
@@ -1,6 +1,7 @@
cmake_minimum_required(VERSION 2.8.1 FATAL_ERROR)
-project(CheckTypeSize C)
+project(CheckTypeSize)
+# Check C types
include(CheckTypeSize)
check_type_size("void*" SIZEOF_DATA_PTR)
check_type_size(char SIZEOF_CHAR)
@@ -18,7 +19,19 @@ check_type_size("((struct somestruct*)0)->someint" SIZEOF_STRUCTMEMBER_INT)
check_type_size("((struct somestruct*)0)->someptr" SIZEOF_STRUCTMEMBER_PTR)
check_type_size("((struct somestruct*)0)->somechar" SIZEOF_STRUCTMEMBER_CHAR)
+# Check CXX types
+check_type_size(bool SIZEOF_BOOL LANGUAGE CXX)
+
+set(CMAKE_EXTRA_INCLUDE_FILES someclass.hxx)
+check_type_size("((ns::someclass*)0)->someint" SIZEOF_NS_CLASSMEMBER_INT LANGUAGE CXX)
+check_type_size("((ns::someclass*)0)->someptr" SIZEOF_NS_CLASSMEMBER_PTR LANGUAGE CXX)
+check_type_size("((ns::someclass*)0)->somechar" SIZEOF_NS_CLASSMEMBER_CHAR LANGUAGE CXX)
+check_type_size("((ns::someclass*)0)->somebool" SIZEOF_NS_CLASSMEMBER_BOOL LANGUAGE CXX)
+
configure_file(config.h.in config.h)
+configure_file(config.hxx.in config.hxx)
+
include_directories("${CheckTypeSize_BINARY_DIR}")
add_executable(CheckTypeSize CheckTypeSize.c)
+add_executable(CheckTypeSizeCXX CheckTypeSize.cxx)
diff --git a/Tests/Module/CheckTypeSize/CheckTypeSize.cxx b/Tests/Module/CheckTypeSize/CheckTypeSize.cxx
new file mode 100644
index 000000000..b5692cdbf
--- /dev/null
+++ b/Tests/Module/CheckTypeSize/CheckTypeSize.cxx
@@ -0,0 +1,172 @@
+#include "config.h"
+#include "config.hxx"
+#include "someclass.hxx"
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_STDDEF_H
+# include <stddef.h>
+#endif
+
+#include <stdio.h>
+
+#define CHECK(t,m) do { \
+ if(sizeof(t) != m) \
+ { \
+ printf(#m ": expected %d, got %d (line %d)\n", \
+ (int)sizeof(t), (int)m, __LINE__); \
+ result = 1; \
+ } \
+ } while(0)
+
+#define NODEF(m) do { \
+ printf(#m": not defined (line %d)\n", __LINE__); \
+ result = 1; \
+ } while(0)
+
+int main()
+{
+ int result = 0;
+ ns::someclass y;
+
+ /* void* */
+#if !defined(HAVE_SIZEOF_DATA_PTR)
+ NODEF(HAVE_SIZEOF_DATA_PTR);
+#endif
+#if defined(SIZEOF_DATA_PTR)
+ CHECK(void*, SIZEOF_DATA_PTR);
+#else
+ NODEF(SIZEOF_DATA_PTR);
+#endif
+
+ /* char */
+#if !defined(HAVE_SIZEOF_CHAR)
+ NODEF(HAVE_SIZEOF_CHAR);
+#endif
+#if defined(SIZEOF_CHAR)
+ CHECK(char, SIZEOF_CHAR);
+#else
+ NODEF(SIZEOF_CHAR);
+#endif
+
+ /* short */
+#if !defined(HAVE_SIZEOF_SHORT)
+ NODEF(HAVE_SIZEOF_SHORT);
+#endif
+#if defined(SIZEOF_SHORT)
+ CHECK(short, SIZEOF_SHORT);
+#else
+ NODEF(SIZEOF_SHORT);
+#endif
+
+ /* int */
+#if !defined(HAVE_SIZEOF_INT)
+ NODEF(HAVE_SIZEOF_INT);
+#endif
+#if defined(SIZEOF_INT)
+ CHECK(int, SIZEOF_INT);
+#else
+ NODEF(SIZEOF_INT);
+#endif
+
+ /* long */
+#if !defined(HAVE_SIZEOF_LONG)
+ NODEF(HAVE_SIZEOF_LONG);
+#endif
+#if defined(SIZEOF_LONG)
+ CHECK(long, SIZEOF_LONG);
+#else
+ NODEF(SIZEOF_LONG);
+#endif
+
+ /* long long */
+#if defined(SIZEOF_LONG_LONG)
+ CHECK(long long, SIZEOF_LONG_LONG);
+# if !defined(HAVE_SIZEOF_LONG_LONG)
+ NODEF(HAVE_SIZEOF_LONG_LONG);
+# endif
+#endif
+
+ /* __int64 */
+#if defined(SIZEOF___INT64)
+ CHECK(__int64, SIZEOF___INT64);
+# if !defined(HAVE_SIZEOF___INT64)
+ NODEF(HAVE_SIZEOF___INT64);
+# endif
+#elif defined(HAVE_SIZEOF___INT64)
+ NODEF(SIZEOF___INT64);
+#endif
+
+ /* size_t */
+#if !defined(HAVE_SIZEOF_SIZE_T)
+ NODEF(HAVE_SIZEOF_SIZE_T);
+#endif
+#if defined(SIZEOF_SIZE_T)
+ CHECK(size_t, SIZEOF_SIZE_T);
+#else
+ NODEF(SIZEOF_SIZE_T);
+#endif
+
+ /* ssize_t */
+#if defined(SIZEOF_SSIZE_T)
+ CHECK(ssize_t, SIZEOF_SSIZE_T);
+# if !defined(HAVE_SIZEOF_SSIZE_T)
+ NODEF(HAVE_SIZEOF_SSIZE_T);
+# endif
+#elif defined(HAVE_SIZEOF_SSIZE_T)
+ NODEF(SIZEOF_SSIZE_T);
+#endif
+
+ /* ns::someclass::someint */
+#if defined(SIZEOF_NS_CLASSMEMBER_INT)
+ CHECK(y.someint, SIZEOF_NS_CLASSMEMBER_INT);
+ CHECK(y.someint, SIZEOF_INT);
+# if !defined(HAVE_SIZEOF_NS_CLASSMEMBER_INT)
+ NODEF(HAVE_SIZEOF_STRUCTMEMBER_INT);
+# endif
+#elif defined(HAVE_SIZEOF_STRUCTMEMBER_INT)
+ NODEF(SIZEOF_STRUCTMEMBER_INT);
+#endif
+
+ /* ns::someclass::someptr */
+#if defined(SIZEOF_NS_CLASSMEMBER_PTR)
+ CHECK(y.someptr, SIZEOF_NS_CLASSMEMBER_PTR);
+ CHECK(y.someptr, SIZEOF_DATA_PTR);
+# if !defined(HAVE_SIZEOF_NS_CLASSMEMBER_PTR)
+ NODEF(HAVE_SIZEOF_NS_CLASSMEMBER_PTR);
+# endif
+#elif defined(HAVE_SIZEOF_NS_CLASSMEMBER_PTR)
+ NODEF(SIZEOF_NS_CLASSMEMBER_PTR);
+#endif
+
+ /* ns::someclass::somechar */
+#if defined(SIZEOF_NS_CLASSMEMBER_CHAR)
+ CHECK(y.somechar, SIZEOF_NS_CLASSMEMBER_CHAR);
+ CHECK(y.somechar, SIZEOF_CHAR);
+# if !defined(HAVE_SIZEOF_NS_CLASSMEMBER_CHAR)
+ NODEF(HAVE_SIZEOF_NS_CLASSMEMBER_CHAR);
+# endif
+#elif defined(HAVE_SIZEOF_NS_CLASSMEMBER_CHAR)
+ NODEF(SIZEOF_NS_CLASSMEMBER_CHAR);
+#endif
+
+ /* ns::someclass::somebool */
+#if defined(SIZEOF_NS_CLASSMEMBER_BOOL)
+ CHECK(y.somechar, SIZEOF_NS_CLASSMEMBER_BOOL);
+ CHECK(y.somechar, SIZEOF_BOOL);
+# if !defined(HAVE_SIZEOF_NS_CLASSMEMBER_BOOL)
+ NODEF(HAVE_SIZEOF_NS_CLASSMEMBER_BOOL);
+# endif
+#elif defined(HAVE_SIZEOF_NS_CLASSMEMBER_BOOL)
+ NODEF(SIZEOF_NS_CLASSMEMBER_BOOL);
+#endif
+
+ /* to avoid possible warnings about unused or write-only variable */
+ y.someint = result;
+
+ return y.someint;
+}
diff --git a/Tests/Module/CheckTypeSize/config.hxx.in b/Tests/Module/CheckTypeSize/config.hxx.in
new file mode 100644
index 000000000..8c66ade6c
--- /dev/null
+++ b/Tests/Module/CheckTypeSize/config.hxx.in
@@ -0,0 +1,23 @@
+#cmakedefine HAVE_SYS_TYPES_H
+#cmakedefine HAVE_STDINT_H
+#cmakedefine HAVE_STDDEF_H
+
+/* bool */
+#cmakedefine HAVE_SIZEOF_BOOL
+@SIZEOF_BOOL_CODE@
+
+/* struct ns::somestruct::someint */
+#cmakedefine HAVE_SIZEOF_NS_STRUCTMEMBER_INT
+@SIZEOF_NS_STRUCTMEMBER_INT_CODE@
+
+/* struct ns::somestruct::someptr */
+#cmakedefine HAVE_SIZEOF_NS_STRUCTMEMBER_PTR
+@SIZEOF_NS_STRUCTMEMBER_PTR_CODE@
+
+/* struct ns::somestruct::somechar */
+#cmakedefine HAVE_SIZEOF_NS_STRUCTMEMBER_CHAR
+@SIZEOF_NS_STRUCTMEMBER_CHAR_CODE@
+
+/* struct ns::somestruct::somebool */
+#cmakedefine HAVE_SIZEOF_NS_STRUCTMEMBER_BOOL
+@SIZEOF_NS_STRUCTMEMBER_BOOL_CODE@
diff --git a/Tests/Module/CheckTypeSize/someclass.hxx b/Tests/Module/CheckTypeSize/someclass.hxx
new file mode 100644
index 000000000..76c07ecdb
--- /dev/null
+++ b/Tests/Module/CheckTypeSize/someclass.hxx
@@ -0,0 +1,14 @@
+#ifndef _CMAKE_SOMECLASS_HXX
+#define _CMAKE_SOMECLASS_HXX
+
+namespace ns {
+class someclass {
+public:
+ int someint;
+ void *someptr;
+ char somechar;
+ bool somebool;
+};
+}
+
+#endif
diff --git a/Tests/Module/ExternalData/Alt/MyAlgoMap1-md5/dded55e43cd6529ee35d24113dfc87a3 b/Tests/Module/ExternalData/Alt/MyAlgoMap1-md5/dded55e43cd6529ee35d24113dfc87a3
new file mode 100644
index 000000000..fa0cb1ad1
--- /dev/null
+++ b/Tests/Module/ExternalData/Alt/MyAlgoMap1-md5/dded55e43cd6529ee35d24113dfc87a3
@@ -0,0 +1 @@
+DataAlgoMap \ No newline at end of file
diff --git a/Tests/Module/ExternalData/Alt/SHA1/85158f0c1996837976e858c42a9a7634bfe91b93 b/Tests/Module/ExternalData/Alt/SHA1/85158f0c1996837976e858c42a9a7634bfe91b93
new file mode 100644
index 000000000..fa0cb1ad1
--- /dev/null
+++ b/Tests/Module/ExternalData/Alt/SHA1/85158f0c1996837976e858c42a9a7634bfe91b93
@@ -0,0 +1 @@
+DataAlgoMap \ No newline at end of file
diff --git a/Tests/Module/ExternalData/CMakeLists.txt b/Tests/Module/ExternalData/CMakeLists.txt
index 8312dcacd..f07ab7197 100644
--- a/Tests/Module/ExternalData/CMakeLists.txt
+++ b/Tests/Module/ExternalData/CMakeLists.txt
@@ -10,7 +10,11 @@ if(NOT "${CMAKE_CURRENT_SOURCE_DIR}" MATCHES "^/")
endif()
set(ExternalData_URL_TEMPLATES
"file://${slash}${CMAKE_CURRENT_SOURCE_DIR}/%(algo)/%(hash)"
+ "file://${slash}${CMAKE_CURRENT_SOURCE_DIR}/Alt/%(algo:MyAlgoMap1)/%(hash)"
+ "ExternalDataCustomScript://MyScript1/%(algo)/%(hash)"
)
+set(ExternalData_URL_ALGO_MD5_MyAlgoMap1 MyAlgoMap1-md5)
+set(ExternalData_CUSTOM_SCRIPT_MyScript1 "${CMAKE_CURRENT_SOURCE_DIR}/MyScript1.cmake")
set(ExternalData_BINARY_ROOT "${CMAKE_CURRENT_BINARY_DIR}/ExternalData")
file(REMOVE_RECURSE ${ExternalData_BINARY_ROOT}) # clean test
@@ -23,6 +27,11 @@ ExternalData_Add_Test(Data1
COMMAND ${CMAKE_COMMAND}
-D Data=DATA{Data.dat}
${Data1CheckSpaces}
+ -D DataScript=DATA{DataScript.dat}
+ -D DataAlgoMapA=DATA{DataAlgoMapA.dat}
+ -D DataAlgoMapB=DATA{DataAlgoMapB.dat}
+ -D DataMissing=DATA{DataMissing.dat}
+ -D DataMissingWithAssociated=DATA{DataMissing.dat,Data.dat}
-D SeriesA=DATA{SeriesA.dat,:}
-D SeriesB=DATA{SeriesB.dat,:}
-D SeriesC=DATA{SeriesC.dat,:}
@@ -35,6 +44,7 @@ ExternalData_Add_Test(Data1
-D Paired=DATA{PairedA.dat,PairedB.dat}
-D Meta=DATA{MetaTop.dat,REGEX:Meta[ABC].dat}
-D Directory=DATA{Directory/,A.dat,REGEX:[BC].dat}
+ -D DirRecurse=DATA{DirRecurse/,RECURSE:,A.dat,REGEX:[BC].dat}
-D "Semicolons=DATA{Data.dat}\\;DATA{Data.dat}"
-P ${CMAKE_CURRENT_SOURCE_DIR}/Data1Check.cmake
)
@@ -42,3 +52,5 @@ ExternalData_Add_Target(Data1)
add_subdirectory(Data2)
add_subdirectory(Data3)
+add_subdirectory(Data4)
+add_subdirectory(DataNoSymlinks)
diff --git a/Tests/Module/ExternalData/Data1Check.cmake b/Tests/Module/ExternalData/Data1Check.cmake
index 57702453e..f60c2094d 100644
--- a/Tests/Module/ExternalData/Data1Check.cmake
+++ b/Tests/Module/ExternalData/Data1Check.cmake
@@ -8,6 +8,40 @@ if(DEFINED DataSpace)
message(SEND_ERROR "Input file:\n ${DataSpace}\ndoes not have expected content, but [[${lines}]]")
endif()
endif()
+file(STRINGS "${DataScript}" lines LIMIT_INPUT 1024)
+if(NOT "x${lines}" STREQUAL "xDataScript")
+ message(SEND_ERROR "Input file:\n ${DataScript}\ndoes not have expected content, but [[${lines}]]")
+endif()
+file(STRINGS "${DataAlgoMapA}" lines LIMIT_INPUT 1024)
+if(NOT "x${lines}" STREQUAL "xDataAlgoMap")
+ message(SEND_ERROR "Input file:\n ${DataAlgoMapA}\ndoes not have expected content, but [[${lines}]]")
+endif()
+file(STRINGS "${DataAlgoMapB}" lines LIMIT_INPUT 1024)
+if(NOT "x${lines}" STREQUAL "xDataAlgoMap")
+ message(SEND_ERROR "Input file:\n ${DataAlgoMapB}\ndoes not have expected content, but [[${lines}]]")
+endif()
+if(DataMissing)
+ if(EXISTS "${DataMissing}")
+ message(SEND_ERROR
+ "Input file:\n"
+ " ${DataMissing}\n"
+ "exists but should not."
+ )
+ endif()
+else()
+ message(SEND_ERROR "DataMissing is not set!")
+endif()
+if(DataMissingWithAssociated)
+ if(EXISTS "${DataMissingWithAssociated}")
+ message(SEND_ERROR
+ "Input file:\n"
+ " ${DataMissingWithAssociated}\n"
+ "exists but should not."
+ )
+ endif()
+else()
+ message(SEND_ERROR "DataMissingWithAssociated is not set!")
+endif()
set(SeriesAn1 "1\\.dat")
set(SeriesBn1 "_1\\.dat")
set(SeriesCn1 "\\.1\\.dat")
@@ -56,6 +90,12 @@ foreach(n A B C)
message(SEND_ERROR "Input file:\n ${file}\ndoes not exist!")
endif()
endforeach()
+foreach(n A Sub1/A Sub2/Dir/A B Sub1/B Sub2/Dir/B C Sub1/C Sub2/Dir/C)
+ set(file "${DirRecurse}/${n}.dat")
+ if(NOT EXISTS "${file}")
+ message(SEND_ERROR "Input file:\n ${file}\ndoes not exist!")
+ endif()
+endforeach()
list(LENGTH Semicolons len)
if("${len}" EQUAL 2)
foreach(file ${Semicolons})
diff --git a/Tests/Module/ExternalData/Data4/CMakeLists.txt b/Tests/Module/ExternalData/Data4/CMakeLists.txt
new file mode 100644
index 000000000..ac977fb6d
--- /dev/null
+++ b/Tests/Module/ExternalData/Data4/CMakeLists.txt
@@ -0,0 +1,15 @@
+set(Store0 ${CMAKE_BINARY_DIR}/ExternalData/Other)
+set(Store1 ${CMAKE_BINARY_DIR}/ExternalData/Objects)
+set(ExternalData_OBJECT_STORES ${Store0} ${Store1})
+unset(ExternalData_URL_TEMPLATES) # All objects already in stores!
+ExternalData_Add_Test(Data4
+ NAME Data4Check
+ COMMAND ${CMAKE_COMMAND}
+ -D Data=DATA{Data.dat}
+ -D Other=DATA{Other.dat}
+ -D Store0=${Store0}
+ -D Store1=${Store1}
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/Data4Check.cmake
+ )
+ExternalData_Add_Target(Data4)
+add_dependencies(Data4 Data3)
diff --git a/Tests/Module/ExternalData/Data4/Data.dat.md5 b/Tests/Module/ExternalData/Data4/Data.dat.md5
new file mode 100644
index 000000000..70e39bd5d
--- /dev/null
+++ b/Tests/Module/ExternalData/Data4/Data.dat.md5
@@ -0,0 +1 @@
+8c018830e3efa5caf3c7415028335a57
diff --git a/Tests/Module/ExternalData/Data4/Data4Check.cmake b/Tests/Module/ExternalData/Data4/Data4Check.cmake
new file mode 100644
index 000000000..e614cc4e3
--- /dev/null
+++ b/Tests/Module/ExternalData/Data4/Data4Check.cmake
@@ -0,0 +1,26 @@
+if(NOT EXISTS "${Data}")
+ message(SEND_ERROR "Input file:\n ${Data}\ndoes not exist!")
+endif()
+if(NOT EXISTS "${Other}")
+ message(SEND_ERROR "Input file:\n ${Other}\ndoes not exist!")
+endif()
+# Verify that the 'Data' object was found in the second store location left
+# from Data1 target downloads and that the 'Other' object was found in the
+# first store location left from Data3 target downloads. Neither object
+# should exist in the opposite store.
+foreach(should_exist
+ "${Store0}/MD5/aaad162b85f60d1eb57ca71a23e8efd7"
+ "${Store1}/MD5/8c018830e3efa5caf3c7415028335a57"
+ )
+ if(NOT EXISTS ${should_exist})
+ message(SEND_ERROR "Store file:\n ${should_exist}\nshould exist!")
+ endif()
+endforeach()
+foreach(should_not_exist
+ "${Store0}/MD5/8c018830e3efa5caf3c7415028335a57"
+ "${Store1}/MD5/aaad162b85f60d1eb57ca71a23e8efd7"
+ )
+ if(EXISTS ${should_not_exist})
+ message(SEND_ERROR "Store file:\n ${should_not_exist}\nshould not exist!")
+ endif()
+endforeach()
diff --git a/Tests/Module/ExternalData/Data4/Other.dat.md5 b/Tests/Module/ExternalData/Data4/Other.dat.md5
new file mode 100644
index 000000000..5312faac0
--- /dev/null
+++ b/Tests/Module/ExternalData/Data4/Other.dat.md5
@@ -0,0 +1 @@
+aaad162b85f60d1eb57ca71a23e8efd7
diff --git a/Tests/Module/ExternalData/DataAlgoMapA.dat.md5 b/Tests/Module/ExternalData/DataAlgoMapA.dat.md5
new file mode 100644
index 000000000..7281481ba
--- /dev/null
+++ b/Tests/Module/ExternalData/DataAlgoMapA.dat.md5
@@ -0,0 +1 @@
+dded55e43cd6529ee35d24113dfc87a3
diff --git a/Tests/Module/ExternalData/DataAlgoMapB.dat.sha1 b/Tests/Module/ExternalData/DataAlgoMapB.dat.sha1
new file mode 100644
index 000000000..4fd7c06fd
--- /dev/null
+++ b/Tests/Module/ExternalData/DataAlgoMapB.dat.sha1
@@ -0,0 +1 @@
+85158f0c1996837976e858c42a9a7634bfe91b93
diff --git a/Tests/Module/ExternalData/DataNoSymlinks/CMakeLists.txt b/Tests/Module/ExternalData/DataNoSymlinks/CMakeLists.txt
new file mode 100644
index 000000000..d3df7fcf9
--- /dev/null
+++ b/Tests/Module/ExternalData/DataNoSymlinks/CMakeLists.txt
@@ -0,0 +1,8 @@
+set(ExternalData_NO_SYMLINKS 1)
+ExternalData_Add_Test(DataNoSymlinks
+ NAME DataNoSymlinksCheck
+ COMMAND ${CMAKE_COMMAND}
+ -D Data=DATA{Data.dat}
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/DataNoSymlinksCheck.cmake
+ )
+ExternalData_Add_Target(DataNoSymlinks)
diff --git a/Tests/Module/ExternalData/DataNoSymlinks/Data.dat.md5 b/Tests/Module/ExternalData/DataNoSymlinks/Data.dat.md5
new file mode 100644
index 000000000..70e39bd5d
--- /dev/null
+++ b/Tests/Module/ExternalData/DataNoSymlinks/Data.dat.md5
@@ -0,0 +1 @@
+8c018830e3efa5caf3c7415028335a57
diff --git a/Tests/Module/ExternalData/DataNoSymlinks/DataNoSymlinksCheck.cmake b/Tests/Module/ExternalData/DataNoSymlinks/DataNoSymlinksCheck.cmake
new file mode 100644
index 000000000..2be3571ff
--- /dev/null
+++ b/Tests/Module/ExternalData/DataNoSymlinks/DataNoSymlinksCheck.cmake
@@ -0,0 +1,6 @@
+if(NOT EXISTS "${Data}")
+ message(SEND_ERROR "Input file:\n ${Data}\ndoes not exist!")
+endif()
+if(IS_SYMLINK "${Data}")
+ message(SEND_ERROR "Input file:\n ${Data}\nis a symlink but should not be!")
+endif()
diff --git a/Tests/Module/ExternalData/DataScript.dat.md5 b/Tests/Module/ExternalData/DataScript.dat.md5
new file mode 100644
index 000000000..74b461607
--- /dev/null
+++ b/Tests/Module/ExternalData/DataScript.dat.md5
@@ -0,0 +1 @@
+fd95c03719e8626c0d10a818f9996dc5
diff --git a/Tests/Module/ExternalData/DirRecurse/A.dat.md5 b/Tests/Module/ExternalData/DirRecurse/A.dat.md5
new file mode 100644
index 000000000..4a78fc783
--- /dev/null
+++ b/Tests/Module/ExternalData/DirRecurse/A.dat.md5
@@ -0,0 +1 @@
+9d980b06c2f0fec3d4872d68175b9822
diff --git a/Tests/Module/ExternalData/DirRecurse/B.dat.md5 b/Tests/Module/ExternalData/DirRecurse/B.dat.md5
new file mode 100644
index 000000000..4557a216a
--- /dev/null
+++ b/Tests/Module/ExternalData/DirRecurse/B.dat.md5
@@ -0,0 +1 @@
+8f4add4581551facf27237e6577fd662
diff --git a/Tests/Module/ExternalData/DirRecurse/C.dat.md5 b/Tests/Module/ExternalData/DirRecurse/C.dat.md5
new file mode 100644
index 000000000..a7f23dd7f
--- /dev/null
+++ b/Tests/Module/ExternalData/DirRecurse/C.dat.md5
@@ -0,0 +1 @@
+c1030719c95f3435d8abc39c0d442946
diff --git a/Tests/Module/ExternalData/DirRecurse/Sub1/A.dat.md5 b/Tests/Module/ExternalData/DirRecurse/Sub1/A.dat.md5
new file mode 100644
index 000000000..4a78fc783
--- /dev/null
+++ b/Tests/Module/ExternalData/DirRecurse/Sub1/A.dat.md5
@@ -0,0 +1 @@
+9d980b06c2f0fec3d4872d68175b9822
diff --git a/Tests/Module/ExternalData/DirRecurse/Sub1/B.dat.md5 b/Tests/Module/ExternalData/DirRecurse/Sub1/B.dat.md5
new file mode 100644
index 000000000..4557a216a
--- /dev/null
+++ b/Tests/Module/ExternalData/DirRecurse/Sub1/B.dat.md5
@@ -0,0 +1 @@
+8f4add4581551facf27237e6577fd662
diff --git a/Tests/Module/ExternalData/DirRecurse/Sub1/C.dat.md5 b/Tests/Module/ExternalData/DirRecurse/Sub1/C.dat.md5
new file mode 100644
index 000000000..a7f23dd7f
--- /dev/null
+++ b/Tests/Module/ExternalData/DirRecurse/Sub1/C.dat.md5
@@ -0,0 +1 @@
+c1030719c95f3435d8abc39c0d442946
diff --git a/Tests/Module/ExternalData/DirRecurse/Sub2/Dir/A.dat.md5 b/Tests/Module/ExternalData/DirRecurse/Sub2/Dir/A.dat.md5
new file mode 100644
index 000000000..4a78fc783
--- /dev/null
+++ b/Tests/Module/ExternalData/DirRecurse/Sub2/Dir/A.dat.md5
@@ -0,0 +1 @@
+9d980b06c2f0fec3d4872d68175b9822
diff --git a/Tests/Module/ExternalData/DirRecurse/Sub2/Dir/B.dat.md5 b/Tests/Module/ExternalData/DirRecurse/Sub2/Dir/B.dat.md5
new file mode 100644
index 000000000..4557a216a
--- /dev/null
+++ b/Tests/Module/ExternalData/DirRecurse/Sub2/Dir/B.dat.md5
@@ -0,0 +1 @@
+8f4add4581551facf27237e6577fd662
diff --git a/Tests/Module/ExternalData/DirRecurse/Sub2/Dir/C.dat.md5 b/Tests/Module/ExternalData/DirRecurse/Sub2/Dir/C.dat.md5
new file mode 100644
index 000000000..a7f23dd7f
--- /dev/null
+++ b/Tests/Module/ExternalData/DirRecurse/Sub2/Dir/C.dat.md5
@@ -0,0 +1 @@
+c1030719c95f3435d8abc39c0d442946
diff --git a/Tests/Module/ExternalData/MyScript1.cmake b/Tests/Module/ExternalData/MyScript1.cmake
new file mode 100644
index 000000000..242c64d9f
--- /dev/null
+++ b/Tests/Module/ExternalData/MyScript1.cmake
@@ -0,0 +1,5 @@
+if(ExternalData_CUSTOM_LOCATION STREQUAL "MD5/fd95c03719e8626c0d10a818f9996dc5")
+ file(WRITE "${ExternalData_CUSTOM_FILE}" "DataScript")
+else()
+ set(ExternalData_CUSTOM_ERROR "no ${ExternalData_CUSTOM_LOCATION} known")
+endif()
diff --git a/Tests/Module/FindDependency/CMakeLists.txt b/Tests/Module/FindDependency/CMakeLists.txt
new file mode 100644
index 000000000..dcb998a4b
--- /dev/null
+++ b/Tests/Module/FindDependency/CMakeLists.txt
@@ -0,0 +1,11 @@
+
+cmake_minimum_required(VERSION 3.0)
+project(FindDependency)
+
+set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/packages")
+
+find_package(Pack1 REQUIRED)
+find_package(Pack4 4.3 EXACT REQUIRED)
+
+add_executable(FindDependency main.cpp)
+target_link_libraries(FindDependency Pack1::Lib Pack4::Lib)
diff --git a/Tests/Module/FindDependency/main.cpp b/Tests/Module/FindDependency/main.cpp
new file mode 100644
index 000000000..50c5958ca
--- /dev/null
+++ b/Tests/Module/FindDependency/main.cpp
@@ -0,0 +1,29 @@
+
+#ifndef HAVE_PACK1
+#error Expected HAVE_PACK1
+#endif
+
+#ifndef HAVE_PACK2
+#error Expected HAVE_PACK2
+#endif
+
+#ifndef HAVE_PACK3
+#error Expected HAVE_PACK3
+#endif
+
+#ifndef HAVE_PACK4
+#error Expected HAVE_PACK4
+#endif
+
+#ifndef HAVE_PACK5
+#error Expected HAVE_PACK5
+#endif
+
+#ifndef HAVE_PACK6
+#error Expected HAVE_PACK6
+#endif
+
+int main(int argc, char** argv)
+{
+ return 0;
+}
diff --git a/Tests/Module/FindDependency/packages/Pack1/Pack1Config.cmake b/Tests/Module/FindDependency/packages/Pack1/Pack1Config.cmake
new file mode 100644
index 000000000..ff533c2a0
--- /dev/null
+++ b/Tests/Module/FindDependency/packages/Pack1/Pack1Config.cmake
@@ -0,0 +1,9 @@
+
+include(CMakeFindDependencyMacro)
+
+find_dependency(Pack2 2.3)
+find_dependency(Pack3)
+
+add_library(Pack1::Lib INTERFACE IMPORTED)
+set_property(TARGET Pack1::Lib PROPERTY INTERFACE_COMPILE_DEFINITIONS HAVE_PACK1)
+set_property(TARGET Pack1::Lib PROPERTY INTERFACE_LINK_LIBRARIES Pack2::Lib Pack3::Lib)
diff --git a/Tests/Module/FindDependency/packages/Pack1/Pack1ConfigVersion.cmake b/Tests/Module/FindDependency/packages/Pack1/Pack1ConfigVersion.cmake
new file mode 100644
index 000000000..dfb7b6c84
--- /dev/null
+++ b/Tests/Module/FindDependency/packages/Pack1/Pack1ConfigVersion.cmake
@@ -0,0 +1,11 @@
+
+set(PACKAGE_VERSION "1.3")
+
+if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
+ set(PACKAGE_VERSION_COMPATIBLE FALSE)
+else()
+ set(PACKAGE_VERSION_COMPATIBLE TRUE)
+ if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
+ set(PACKAGE_VERSION_EXACT TRUE)
+ endif()
+endif()
diff --git a/Tests/Module/FindDependency/packages/Pack2/Pack2Config.cmake b/Tests/Module/FindDependency/packages/Pack2/Pack2Config.cmake
new file mode 100644
index 000000000..672288ec8
--- /dev/null
+++ b/Tests/Module/FindDependency/packages/Pack2/Pack2Config.cmake
@@ -0,0 +1,5 @@
+
+set(PACK2_VAR ON)
+
+add_library(Pack2::Lib INTERFACE IMPORTED)
+set_property(TARGET Pack2::Lib PROPERTY INTERFACE_COMPILE_DEFINITIONS HAVE_PACK2)
diff --git a/Tests/Module/FindDependency/packages/Pack2/Pack2ConfigVersion.cmake b/Tests/Module/FindDependency/packages/Pack2/Pack2ConfigVersion.cmake
new file mode 100644
index 000000000..42f58c05b
--- /dev/null
+++ b/Tests/Module/FindDependency/packages/Pack2/Pack2ConfigVersion.cmake
@@ -0,0 +1,11 @@
+
+set(PACKAGE_VERSION "2.4")
+
+if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
+ set(PACKAGE_VERSION_COMPATIBLE FALSE)
+else()
+ set(PACKAGE_VERSION_COMPATIBLE TRUE)
+ if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
+ set(PACKAGE_VERSION_EXACT TRUE)
+ endif()
+endif()
diff --git a/Tests/Module/FindDependency/packages/Pack3/Pack3Config.cmake b/Tests/Module/FindDependency/packages/Pack3/Pack3Config.cmake
new file mode 100644
index 000000000..25c32f326
--- /dev/null
+++ b/Tests/Module/FindDependency/packages/Pack3/Pack3Config.cmake
@@ -0,0 +1,5 @@
+
+set(PACK3_VAR ON)
+
+add_library(Pack3::Lib INTERFACE IMPORTED)
+set_property(TARGET Pack3::Lib PROPERTY INTERFACE_COMPILE_DEFINITIONS HAVE_PACK3)
diff --git a/Tests/Module/FindDependency/packages/Pack3/Pack3ConfigVersion.cmake b/Tests/Module/FindDependency/packages/Pack3/Pack3ConfigVersion.cmake
new file mode 100644
index 000000000..870f7478d
--- /dev/null
+++ b/Tests/Module/FindDependency/packages/Pack3/Pack3ConfigVersion.cmake
@@ -0,0 +1,11 @@
+
+set(PACKAGE_VERSION "1.4")
+
+if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
+ set(PACKAGE_VERSION_COMPATIBLE FALSE)
+else()
+ set(PACKAGE_VERSION_COMPATIBLE TRUE)
+ if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
+ set(PACKAGE_VERSION_EXACT TRUE)
+ endif()
+endif()
diff --git a/Tests/Module/FindDependency/packages/Pack4/Pack4Config.cmake b/Tests/Module/FindDependency/packages/Pack4/Pack4Config.cmake
new file mode 100644
index 000000000..62fddb1c5
--- /dev/null
+++ b/Tests/Module/FindDependency/packages/Pack4/Pack4Config.cmake
@@ -0,0 +1,9 @@
+
+include(CMakeFindDependencyMacro)
+
+find_dependency(Pack5 3.1) # Actual version is 3.3. EXACT not propagated.
+find_dependency(Pack6 5.5 EXACT)
+
+add_library(Pack4::Lib INTERFACE IMPORTED)
+set_property(TARGET Pack4::Lib PROPERTY INTERFACE_COMPILE_DEFINITIONS HAVE_PACK4)
+set_property(TARGET Pack4::Lib PROPERTY INTERFACE_LINK_LIBRARIES Pack5::Lib Pack6::Lib)
diff --git a/Tests/Module/FindDependency/packages/Pack4/Pack4ConfigVersion.cmake b/Tests/Module/FindDependency/packages/Pack4/Pack4ConfigVersion.cmake
new file mode 100644
index 000000000..ae982b0ff
--- /dev/null
+++ b/Tests/Module/FindDependency/packages/Pack4/Pack4ConfigVersion.cmake
@@ -0,0 +1,11 @@
+
+set(PACKAGE_VERSION "4.3")
+
+if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
+ set(PACKAGE_VERSION_COMPATIBLE FALSE)
+else()
+ set(PACKAGE_VERSION_COMPATIBLE TRUE)
+ if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
+ set(PACKAGE_VERSION_EXACT TRUE)
+ endif()
+endif()
diff --git a/Tests/Module/FindDependency/packages/Pack5/Pack5Config.cmake b/Tests/Module/FindDependency/packages/Pack5/Pack5Config.cmake
new file mode 100644
index 000000000..1edda9aa8
--- /dev/null
+++ b/Tests/Module/FindDependency/packages/Pack5/Pack5Config.cmake
@@ -0,0 +1,3 @@
+
+add_library(Pack5::Lib INTERFACE IMPORTED)
+set_property(TARGET Pack5::Lib PROPERTY INTERFACE_COMPILE_DEFINITIONS HAVE_PACK5)
diff --git a/Tests/Module/FindDependency/packages/Pack5/Pack5ConfigVersion.cmake b/Tests/Module/FindDependency/packages/Pack5/Pack5ConfigVersion.cmake
new file mode 100644
index 000000000..e944f9668
--- /dev/null
+++ b/Tests/Module/FindDependency/packages/Pack5/Pack5ConfigVersion.cmake
@@ -0,0 +1,11 @@
+
+set(PACKAGE_VERSION "3.3")
+
+if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
+ set(PACKAGE_VERSION_COMPATIBLE FALSE)
+else()
+ set(PACKAGE_VERSION_COMPATIBLE TRUE)
+ if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
+ set(PACKAGE_VERSION_EXACT TRUE)
+ endif()
+endif()
diff --git a/Tests/Module/FindDependency/packages/Pack6/Pack6Config.cmake b/Tests/Module/FindDependency/packages/Pack6/Pack6Config.cmake
new file mode 100644
index 000000000..d6c85fb37
--- /dev/null
+++ b/Tests/Module/FindDependency/packages/Pack6/Pack6Config.cmake
@@ -0,0 +1,3 @@
+
+add_library(Pack6::Lib INTERFACE IMPORTED)
+set_property(TARGET Pack6::Lib PROPERTY INTERFACE_COMPILE_DEFINITIONS HAVE_PACK6)
diff --git a/Tests/Module/FindDependency/packages/Pack6/Pack6ConfigVersion.cmake b/Tests/Module/FindDependency/packages/Pack6/Pack6ConfigVersion.cmake
new file mode 100644
index 000000000..0dd00d22e
--- /dev/null
+++ b/Tests/Module/FindDependency/packages/Pack6/Pack6ConfigVersion.cmake
@@ -0,0 +1,11 @@
+
+set(PACKAGE_VERSION "5.5")
+
+if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
+ set(PACKAGE_VERSION_COMPATIBLE FALSE)
+else()
+ set(PACKAGE_VERSION_COMPATIBLE TRUE)
+ if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
+ set(PACKAGE_VERSION_EXACT TRUE)
+ endif()
+endif()
diff --git a/Tests/Module/GenerateExportHeader/CMakeLists.txt b/Tests/Module/GenerateExportHeader/CMakeLists.txt
index 09f188191..8cd25a4ff 100644
--- a/Tests/Module/GenerateExportHeader/CMakeLists.txt
+++ b/Tests/Module/GenerateExportHeader/CMakeLists.txt
@@ -55,93 +55,18 @@ else()
endif()
endif()
-set(DEPS
- libshared
- libstatic
- lib_shared_and_static
-)
-
-foreach(DEP ${DEPS})
- try_compile(Result ${CMAKE_CURRENT_BINARY_DIR}/${DEP}_build
- ${CMAKE_CURRENT_SOURCE_DIR}/${DEP}
- ${DEP}
- OUTPUT_VARIABLE Out
- )
- if (NOT Result)
- message("OUTPUT: ${Out}")
- endif()
-endforeach()
-
-# The _do_build macro is called from a child scope, where
-# the current source and binary dir are different. Save them here
-# for use in the macro.
-set(TEST_TOP_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
-set(TEST_TOP_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
-
-
-# We seem to get race conditions is writing this stuff to the same file at least on MinGW
-# So to write to separate source and build directories, we use a count to differentiate.
-set (COUNT 0)
-macro(_do_build Include Library LibrarySource Source)
-
- math(EXPR COUNT "${COUNT} + 1" )
-
- file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test${COUNT}/src.cpp" "#include \"${Include}\"\n"
- "int main() { ${Source}; }\n"
- )
-
- if ("${Library}" STREQUAL "static_variant")
- set(CONDITIONAL_STATIC_DEFINE "add_definitions(-DLIBSHARED_AND_STATIC_STATIC_DEFINE)\n")
- endif()
-
- file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test${COUNT}/CMakeLists.txt"
- "cmake_minimum_required(VERSION 2.8)\n"
-
- "project(compiletest)\n"
-
- "set(CMAKE_INCLUDE_CURRENT_DIR ON)\n"
-
- "set(CMAKE_RUNTIME_OUTPUT_DIRECTORY \"\${CMAKE_CURRENT_BINARY_DIR}\")\n"
-
- "include(GenerateExportHeader)\n"
-
- "add_compiler_export_flags()\n"
-
- "if(NOT \"${ERROR_FLAG}\" STREQUAL \"\")\n"
- " add_definitions(${ERROR_FLAG})\n"
- "endif()\n"
-
- "include(\"${TEST_TOP_BINARY_DIR}/${LibrarySource}_build/Targets.cmake\")\n"
-
- "include_directories(\"${TEST_TOP_SOURCE_DIR}/${LibrarySource}\"\n"
- " \"${TEST_TOP_BINARY_DIR}/${LibrarySource}_build\")\n"
-
- "${CONDITIONAL_STATIC_DEFINE}"
-
- "add_executable(compiletest src.cpp)\n"
- "target_link_libraries(compiletest ${Library})\n"
- )
-
- try_compile(Result ${CMAKE_CURRENT_BINARY_DIR}/fail${COUNT}
- ${CMAKE_CURRENT_BINARY_DIR}/test${COUNT}
- compiletest
- OUTPUT_VARIABLE Out
- )
-endmacro()
+include(GenerateExportHeader)
-macro(build_fail Include Library LibrarySource Source Message)
- _do_build(${Include} ${Library} ${LibrarySource} "${Source}")
- test_fail(Result ${Message})
-endmacro()
+set(CMAKE_CXX_STANDARD 98)
-macro(build_pass Include Library LibrarySource Source Message)
- _do_build(${Include} ${Library} ${LibrarySource} "${Source}")
- test_pass(Result ${Message})
-endmacro()
+# Those versions of the HP compiler that need a flag to get proper C++98
+# template support also need a flag to use the newer C++ library.
+if (CMAKE_CXX_COMPILER_ID STREQUAL HP AND
+ CMAKE_CXX98_STANDARD_COMPILE_OPTION STREQUAL "+hpxstd98")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -AA")
+endif ()
-include(GenerateExportHeader)
-
-add_subdirectory(visibility_preset)
+add_subdirectory(lib_shared_and_static)
add_compiler_export_flags()
@@ -159,23 +84,17 @@ macro(macro_add_test_library name)
${${name}_BINARY_DIR} # For the export header.
)
list(APPEND link_libraries ${name})
- add_subdirectory(${name}test)
endmacro()
macro_add_test_library(libshared)
macro_add_test_library(libstatic)
-add_subdirectory(lib_shared_and_static)
-add_subdirectory(lib_shared_and_statictest)
-add_subdirectory(override_symbol)
add_subdirectory(nodeprecated)
-add_subdirectory(prefix)
if(NOT BORLAND)
add_subdirectory(c_identifier)
endif()
if (CMAKE_COMPILER_IS_GNUCXX OR (${CMAKE_CXX_COMPILER_ID} MATCHES Clang))
- # We deliberately call deprecated methods, and test for that elsewhere.
# No need to clutter the test output with warnings.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations")
endif()
@@ -187,3 +106,24 @@ endif()
add_executable(GenerateExportHeader exportheader_test.cpp)
target_link_libraries(GenerateExportHeader ${link_libraries})
+if (WIN32 OR CYGWIN)
+ if(MSVC AND COMPILER_HAS_DEPRECATED)
+ set(_platform Win32)
+ elseif((MINGW OR CYGWIN) AND COMPILER_HAS_DEPRECATED)
+ set(_platform MinGW)
+ else()
+ set(_platform WinEmpty)
+ endif()
+elseif(COMPILER_HAS_HIDDEN_VISIBILITY AND USE_COMPILER_HIDDEN_VISIBILITY)
+ set(_platform UNIX)
+elseif(COMPILER_HAS_DEPRECATED)
+ set(_platform UNIX_DeprecatedOnly)
+else()
+ set(_platform Empty)
+endif()
+message("#### Testing reference: ${_platform}")
+target_compile_definitions(GenerateExportHeader
+ PRIVATE
+ "SRC_DIR=${CMAKE_CURRENT_SOURCE_DIR}/reference/${_platform}"
+ "BIN_DIR=${CMAKE_CURRENT_BINARY_DIR}"
+)
diff --git a/Tests/Module/GenerateExportHeader/exportheader_test.cpp b/Tests/Module/GenerateExportHeader/exportheader_test.cpp
index 55c3c1ad6..4f45f3786 100644
--- a/Tests/Module/GenerateExportHeader/exportheader_test.cpp
+++ b/Tests/Module/GenerateExportHeader/exportheader_test.cpp
@@ -11,6 +11,64 @@
#define DOES_NOT_BUILD(function) function
#endif
+#include <fstream>
+#include <iostream>
+#include <stdlib.h>
+#include <string>
+
+void compare(const char* refName, const char* testName)
+{
+ std::ifstream ref;
+ ref.open(refName);
+ if (!ref.is_open())
+ {
+ std::cout << "Could not open \"" << refName << "\"." << std::endl;
+ exit(1);
+ }
+ std::ifstream test;
+ test.open(testName);
+ if (!test.is_open())
+ {
+ std::cout << "Could not open \"" << testName << "\"." << std::endl;
+ exit(1);
+ }
+
+ while (!ref.eof() && !test.eof())
+ {
+ std::string refLine;
+ std::string testLine;
+ std::getline(ref, refLine);
+ std::getline(test, testLine);
+ // Some very old Borland runtimes (C++ Builder 5 WITHOUT Update 1) add a
+ // trailing null to the string that we need to strip before testing for a
+ // trailing space.
+ if (refLine.size() && refLine[refLine.size()-1] == 0)
+ {
+ refLine = refLine.substr(0, refLine.size() - 1);
+ }
+ if (testLine.size() && testLine[testLine.size()-1] == 0)
+ {
+ testLine = testLine.substr(0, testLine.size() - 1);
+ }
+ // The reference files never have trailing spaces:
+ if (testLine.size() && testLine[testLine.size()-1] == ' ')
+ {
+ testLine = testLine.substr(0, testLine.size() - 1);
+ }
+ if (refLine != testLine)
+ {
+ std::cout << "Ref and test are not the same:\n Ref: \""
+ << refLine << "\"\n Test: \"" << testLine << "\"\n";
+ exit(1);
+ }
+ }
+ if (!ref.eof() || !test.eof())
+ {
+ std::cout << "Ref and test have differing numbers of lines.";
+ exit(1);
+ }
+}
+
int main()
{
{
@@ -78,5 +136,13 @@ int main()
libstatic_not_exported();
libstatic_excluded();
+#define STRINGIFY_IMPL(A) #A
+#define STRINGIFY(A) STRINGIFY_IMPL(A)
+
+ compare(STRINGIFY(SRC_DIR) "/libshared_export.h",
+ STRINGIFY(BIN_DIR) "/libshared/libshared_export.h");
+ compare(STRINGIFY(SRC_DIR) "/libstatic_export.h",
+ STRINGIFY(BIN_DIR) "/libstatic/libstatic_export.h");
+
return 0;
}
diff --git a/Tests/Module/GenerateExportHeader/lib_shared_and_static/CMakeLists.txt b/Tests/Module/GenerateExportHeader/lib_shared_and_static/CMakeLists.txt
index be0387fd5..c1be12556 100644
--- a/Tests/Module/GenerateExportHeader/lib_shared_and_static/CMakeLists.txt
+++ b/Tests/Module/GenerateExportHeader/lib_shared_and_static/CMakeLists.txt
@@ -5,7 +5,15 @@ project(lib_shared_and_static)
include(GenerateExportHeader)
-add_compiler_export_flags()
+set(CMAKE_CXX_VISIBILITY_PRESET hidden)
+set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
+
+if (CMAKE_CXX_FLAGS MATCHES "-fvisibility=hidden")
+ message(SEND_ERROR "Do not use add_compiler_export_flags before adding this directory")
+endif()
+if (CMAKE_CXX_FLAGS MATCHES "-fvisibility-inlines-hidden")
+ message(SEND_ERROR "Do not use add_compiler_export_flags before adding this directory")
+endif()
set(CMAKE_INCLUDE_CURRENT_DIR ON)
@@ -14,9 +22,13 @@ set(lib_SRCS
)
add_library(shared_variant SHARED ${lib_SRCS})
+set_target_properties(shared_variant PROPERTIES DEFINE_SYMBOL SHARED_VARIANT_MAKEDLL)
add_library(static_variant ${lib_SRCS})
-generate_export_header(shared_variant BASE_NAME libshared_and_static)
+generate_export_header(shared_variant
+ BASE_NAME libshared_and_static
+ PREFIX_NAME MYPREFIX_
+)
set_target_properties(static_variant PROPERTIES COMPILE_FLAGS -DLIBSHARED_AND_STATIC_STATIC_DEFINE)
diff --git a/Tests/Module/GenerateExportHeader/lib_shared_and_static/libshared_and_static.h b/Tests/Module/GenerateExportHeader/lib_shared_and_static/libshared_and_static.h
index 049bfe9c4..5ad77f4a9 100644
--- a/Tests/Module/GenerateExportHeader/lib_shared_and_static/libshared_and_static.h
+++ b/Tests/Module/GenerateExportHeader/lib_shared_and_static/libshared_and_static.h
@@ -4,51 +4,51 @@
#include "libshared_and_static_export.h"
-class LIBSHARED_AND_STATIC_EXPORT LibsharedAndStatic {
+class MYPREFIX_LIBSHARED_AND_STATIC_EXPORT LibsharedAndStatic {
public:
int libshared_and_static() const;
int libshared_and_static_exported() const;
- int LIBSHARED_AND_STATIC_DEPRECATED libshared_and_static_deprecated() const;
+ int MYPREFIX_LIBSHARED_AND_STATIC_DEPRECATED libshared_and_static_deprecated() const;
int libshared_and_static_not_exported() const;
- int LIBSHARED_AND_STATIC_NO_EXPORT libshared_and_static_excluded() const;
+ int MYPREFIX_LIBSHARED_AND_STATIC_NO_EXPORT libshared_and_static_excluded() const;
};
class LibsharedAndStaticNotExported {
public:
int libshared_and_static() const;
- int LIBSHARED_AND_STATIC_EXPORT libshared_and_static_exported() const;
+ int MYPREFIX_LIBSHARED_AND_STATIC_EXPORT libshared_and_static_exported() const;
- int LIBSHARED_AND_STATIC_DEPRECATED libshared_and_static_deprecated() const;
+ int MYPREFIX_LIBSHARED_AND_STATIC_DEPRECATED libshared_and_static_deprecated() const;
int libshared_and_static_not_exported() const;
- int LIBSHARED_AND_STATIC_NO_EXPORT libshared_and_static_excluded() const;
+ int MYPREFIX_LIBSHARED_AND_STATIC_NO_EXPORT libshared_and_static_excluded() const;
};
-class LIBSHARED_AND_STATIC_NO_EXPORT LibsharedAndStaticExcluded {
+class MYPREFIX_LIBSHARED_AND_STATIC_NO_EXPORT LibsharedAndStaticExcluded {
public:
int libshared_and_static() const;
- int LIBSHARED_AND_STATIC_EXPORT libshared_and_static_exported() const;
+ int MYPREFIX_LIBSHARED_AND_STATIC_EXPORT libshared_and_static_exported() const;
- int LIBSHARED_AND_STATIC_DEPRECATED libshared_and_static_deprecated() const;
+ int MYPREFIX_LIBSHARED_AND_STATIC_DEPRECATED libshared_and_static_deprecated() const;
int libshared_and_static_not_exported() const;
- int LIBSHARED_AND_STATIC_NO_EXPORT libshared_and_static_excluded() const;
+ int MYPREFIX_LIBSHARED_AND_STATIC_NO_EXPORT libshared_and_static_excluded() const;
};
-LIBSHARED_AND_STATIC_EXPORT int libshared_and_static_exported();
+MYPREFIX_LIBSHARED_AND_STATIC_EXPORT int libshared_and_static_exported();
-LIBSHARED_AND_STATIC_DEPRECATED_EXPORT int libshared_and_static_deprecated();
+MYPREFIX_LIBSHARED_AND_STATIC_DEPRECATED_EXPORT int libshared_and_static_deprecated();
int libshared_and_static_not_exported();
-int LIBSHARED_AND_STATIC_NO_EXPORT libshared_and_static_excluded();
+int MYPREFIX_LIBSHARED_AND_STATIC_NO_EXPORT libshared_and_static_excluded();
#endif
diff --git a/Tests/Module/GenerateExportHeader/lib_shared_and_statictest/CMakeLists.txt b/Tests/Module/GenerateExportHeader/lib_shared_and_statictest/CMakeLists.txt
deleted file mode 100644
index 207534d6e..000000000
--- a/Tests/Module/GenerateExportHeader/lib_shared_and_statictest/CMakeLists.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-
-macro(shared_variant_build_pass Source Message)
- build_pass("libshared_and_static.h" "shared_variant" "lib_shared_and_static" "${Source}" ${Message})
-endmacro()
-
-macro(shared_variant_build_fail Source Message)
- build_fail("libshared_and_static.h" "shared_variant" "lib_shared_and_static" "${Source}" ${Message})
-endmacro()
-
-macro(static_variant_build_pass Source Message)
- build_pass("libshared_and_static.h" "static_variant" "lib_shared_and_static" "${Source}" ${Message})
-endmacro()
-
-macro(static_variant_build_fail Source Message)
- build_fail("libshared_and_static.h" "static_variant" "lib_shared_and_static" "${Source}" ${Message})
-endmacro()
-
-static_variant_build_pass("return libshared_and_static_exported();" "Failed to build static variant")
-shared_variant_build_pass("return libshared_and_static_exported();" "Failed to build shared variant")
-# if (COMPILER_HAS_DEPRECATED)
-# shared_variant_build_fail("return libshared_and_static_deprecated();" "Built shared deprecated variant")
-# static_variant_build_fail("return libshared_and_static_deprecated();" "Built static deprecated variant")
-# else()
-# shared_variant_build_pass("return libshared_and_static_deprecated();" "Built shared deprecated variant")
-# static_variant_build_pass("return libshared_and_static_deprecated();" "Built static deprecated variant")
-# endif()
-static_variant_build_pass("return libshared_and_static_not_exported();" "Failed to build static not exported variant")
-
-if (WIN32 OR COMPILER_HAS_HIDDEN_VISIBILITY)
- shared_variant_build_fail("return libshared_and_static_not_exported();" "Built shared not exported variant")
-else()
- shared_variant_build_pass("return libshared_and_static_not_exported();" "Built shared not exported variant")
-endif()
diff --git a/Tests/Module/GenerateExportHeader/libsharedtest/CMakeLists.txt b/Tests/Module/GenerateExportHeader/libsharedtest/CMakeLists.txt
deleted file mode 100644
index 2a97d8f83..000000000
--- a/Tests/Module/GenerateExportHeader/libsharedtest/CMakeLists.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-
-macro(shared_build_pass Source Message)
- build_pass("libshared.h" "libshared" "libshared" "${Source}" ${Message})
-endmacro()
-
-macro(shared_build_fail Source Message)
- build_fail("libshared.h" "libshared" "libshared" "${Source}" ${Message})
-endmacro()
-
-shared_build_pass("Libshared l; return l.libshared_exported();" "Failed to build exported")
-shared_build_pass("return libshared_exported();" "Failed to build exported function.")
-
-# if (COMPILER_HAS_DEPRECATED)
-# shared_build_fail("Libshared l; return l.libshared_deprecated();" "Built use of deprecated class method. This should not be possible.")
-# else()
-# shared_build_pass("Libshared l; return l.libshared_deprecated();" "Built use of deprecated class method. This should not be possible.")
-# endif()
-if (COMPILER_HAS_HIDDEN_VISIBILITY)
- shared_build_fail("Libshared l; return l.libshared_excluded();" "Built use of excluded class method. This should not be possible.")
-else()
- # There is no MSVC equivalent to hiding symbols.
- shared_build_pass("Libshared l; return l.libshared_excluded();" "Built use of excluded class method. This is possible on MSVC.")
-endif()
-
-if (WIN32 OR COMPILER_HAS_HIDDEN_VISIBILITY)
- shared_build_fail("LibsharedNotExported l; return l.libshared();" "Built use of not-exported class method. This should not be possible.")
- shared_build_fail("LibsharedNotExported l; return l.libshared_not_exported();" "Built use of not-exported class method. This should not be possible.")
- shared_build_fail("LibsharedNotExported l; return l.libshared_excluded();" "Built use of not-exported class method. This should not be possible.")
- shared_build_fail("LibsharedExcluded l; return l.libshared();" "Built use of excluded class method. This should not be possible.")
- shared_build_fail("LibsharedExcluded l; return l.libshared_not_exported();" "Built use of excluded class method. This should not be possible.")
- shared_build_fail("LibsharedExcluded l; return l.libshared_excluded();" "Built use of excluded class method. This should not be possible.")
-
- shared_build_fail("return libshared_excluded();" "Built use of excluded function. This should not be possible.")
- shared_build_fail("return libshared_not_exported();" "Built use of not-exported function. This should not be possible.")
-else()
- shared_build_pass("LibsharedNotExported l; return l.libshared();" "Built use of not-exported class method.")
- shared_build_pass("LibsharedNotExported l; return l.libshared_not_exported();" "Built use of not-exported class method.")
- shared_build_pass("LibsharedNotExported l; return l.libshared_excluded();" "Built use of not-exported class method.")
- shared_build_pass("LibsharedExcluded l; return l.libshared();" "Built use of excluded class method.")
- shared_build_pass("LibsharedExcluded l; return l.libshared_not_exported();" "Built use of excluded class method.")
- shared_build_pass("LibsharedExcluded l; return l.libshared_excluded();" "Built use of excluded class method.")
-
- shared_build_pass("return libshared_excluded();" "Built use of excluded function.")
- shared_build_pass("return libshared_not_exported();" "Built use of not-exported function.")
-endif()
diff --git a/Tests/Module/GenerateExportHeader/libstatictest/CMakeLists.txt b/Tests/Module/GenerateExportHeader/libstatictest/CMakeLists.txt
deleted file mode 100644
index eb6bb874c..000000000
--- a/Tests/Module/GenerateExportHeader/libstatictest/CMakeLists.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-
-macro(static_build_pass Source Message)
- build_pass("libstatic.h" "libstatic" "libstatic" "${Source}" ${Message})
-endmacro()
-
-macro(static_build_fail Source Message)
- build_fail("libstatic.h" "libstatic" "libstatic" "${Source}" ${Message})
-endmacro()
-
-static_build_pass("Libstatic l; return l.libstatic_exported();" "Failed to build exported.")
-
-# if (COMPILER_HAS_DEPRECATED)
-# static_build_fail("Libstatic l; return l.libstatic_deprecated();" "Built use of deprecated class method. This should not be possible.")
-# static_build_fail("libstatic_deprecated();" "Built use of deprecated function. This should not be possible.")
-# else()
-# static_build_pass("Libstatic l; return l.libstatic_deprecated();" "Built use of deprecated class method. This should not be possible.")
-# static_build_pass("libstatic_deprecated();" "Built use of deprecated function. This should not be possible.")
-# endif()
diff --git a/Tests/Module/GenerateExportHeader/override_symbol/CMakeLists.txt b/Tests/Module/GenerateExportHeader/override_symbol/CMakeLists.txt
deleted file mode 100644
index aeeef20ee..000000000
--- a/Tests/Module/GenerateExportHeader/override_symbol/CMakeLists.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-project(override_symbol)
-
-add_library(somelib SHARED someclass.cpp)
-
-set_target_properties(somelib PROPERTIES DEFINE_SYMBOL SOMELIB_MAKEDLL)
-
-generate_export_header(somelib)
-
-add_executable(consumer main.cpp)
-
-target_link_libraries(consumer somelib)
diff --git a/Tests/Module/GenerateExportHeader/override_symbol/main.cpp b/Tests/Module/GenerateExportHeader/override_symbol/main.cpp
deleted file mode 100644
index eec46d3f2..000000000
--- a/Tests/Module/GenerateExportHeader/override_symbol/main.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-
-#include "someclass.h"
-
-int main(int, char**)
-{
- SomeClass sc;
- sc.someMethod();
- return 0;
-}
diff --git a/Tests/Module/GenerateExportHeader/override_symbol/someclass.cpp b/Tests/Module/GenerateExportHeader/override_symbol/someclass.cpp
deleted file mode 100644
index 427ec297c..000000000
--- a/Tests/Module/GenerateExportHeader/override_symbol/someclass.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-
-#include "someclass.h"
-
-void SomeClass::someMethod() const
-{
-
-}
diff --git a/Tests/Module/GenerateExportHeader/override_symbol/someclass.h b/Tests/Module/GenerateExportHeader/override_symbol/someclass.h
deleted file mode 100644
index ae5e84454..000000000
--- a/Tests/Module/GenerateExportHeader/override_symbol/someclass.h
+++ /dev/null
@@ -1,8 +0,0 @@
-
-#include "somelib_export.h"
-
-class SOMELIB_EXPORT SomeClass
-{
-public:
- void someMethod() const;
-};
diff --git a/Tests/Module/GenerateExportHeader/prefix/CMakeLists.txt b/Tests/Module/GenerateExportHeader/prefix/CMakeLists.txt
deleted file mode 100644
index bd64df283..000000000
--- a/Tests/Module/GenerateExportHeader/prefix/CMakeLists.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-project(use_prefix)
-
-set(use_prefix_lib_SRCS
- useprefixclass.cpp
-)
-
-add_library(use_prefix_lib SHARED useprefixclass.cpp)
-
-generate_export_header(use_prefix_lib
- PREFIX_NAME MYPREFIX_
-)
-
-add_executable(use_prefix main.cpp)
-
-target_link_libraries(use_prefix use_prefix_lib) \ No newline at end of file
diff --git a/Tests/Module/GenerateExportHeader/prefix/main.cpp b/Tests/Module/GenerateExportHeader/prefix/main.cpp
deleted file mode 100644
index 507f6fd15..000000000
--- a/Tests/Module/GenerateExportHeader/prefix/main.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-
-#include "useprefixclass.h"
-
-int main(int argc, char **argv)
-{
- UsePrefixClass upc;
- return upc.someMethod();
-}
diff --git a/Tests/Module/GenerateExportHeader/prefix/useprefixclass.cpp b/Tests/Module/GenerateExportHeader/prefix/useprefixclass.cpp
deleted file mode 100644
index 1fd2cb2b4..000000000
--- a/Tests/Module/GenerateExportHeader/prefix/useprefixclass.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-
-#include "useprefixclass.h"
-
-int UsePrefixClass::someMethod() const
-{
- return 0;
-}
diff --git a/Tests/Module/GenerateExportHeader/prefix/useprefixclass.h b/Tests/Module/GenerateExportHeader/prefix/useprefixclass.h
deleted file mode 100644
index f5e31b507..000000000
--- a/Tests/Module/GenerateExportHeader/prefix/useprefixclass.h
+++ /dev/null
@@ -1,13 +0,0 @@
-
-#ifndef USEPREFIXCLASS_H
-#define USEPREFIXCLASS_H
-
-#include "use_prefix_lib_export.h"
-
-class MYPREFIX_USE_PREFIX_LIB_EXPORT UsePrefixClass
-{
-public:
- int someMethod() const;
-};
-
-#endif
diff --git a/Tests/Module/GenerateExportHeader/reference/Empty/libshared_export.h b/Tests/Module/GenerateExportHeader/reference/Empty/libshared_export.h
new file mode 100644
index 000000000..b6749b257
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/reference/Empty/libshared_export.h
@@ -0,0 +1,41 @@
+
+#ifndef LIBSHARED_EXPORT_H
+#define LIBSHARED_EXPORT_H
+
+#ifdef LIBSHARED_STATIC_DEFINE
+# define LIBSHARED_EXPORT
+# define LIBSHARED_NO_EXPORT
+#else
+# ifndef LIBSHARED_EXPORT
+# ifdef libshared_EXPORTS
+ /* We are building this library */
+# define LIBSHARED_EXPORT
+# else
+ /* We are using this library */
+# define LIBSHARED_EXPORT
+# endif
+# endif
+
+# ifndef LIBSHARED_NO_EXPORT
+# define LIBSHARED_NO_EXPORT
+# endif
+#endif
+
+#ifndef LIBSHARED_DEPRECATED
+# define LIBSHARED_DEPRECATED
+#endif
+
+#ifndef LIBSHARED_DEPRECATED_EXPORT
+# define LIBSHARED_DEPRECATED_EXPORT LIBSHARED_EXPORT LIBSHARED_DEPRECATED
+#endif
+
+#ifndef LIBSHARED_DEPRECATED_NO_EXPORT
+# define LIBSHARED_DEPRECATED_NO_EXPORT LIBSHARED_NO_EXPORT LIBSHARED_DEPRECATED
+#endif
+
+#define DEFINE_NO_DEPRECATED 0
+#if DEFINE_NO_DEPRECATED
+# define LIBSHARED_NO_DEPRECATED
+#endif
+
+#endif
diff --git a/Tests/Module/GenerateExportHeader/reference/Empty/libstatic_export.h b/Tests/Module/GenerateExportHeader/reference/Empty/libstatic_export.h
new file mode 100644
index 000000000..e8000e251
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/reference/Empty/libstatic_export.h
@@ -0,0 +1,41 @@
+
+#ifndef LIBSTATIC_EXPORT_H
+#define LIBSTATIC_EXPORT_H
+
+#ifdef LIBSTATIC_STATIC_DEFINE
+# define LIBSTATIC_EXPORT
+# define LIBSTATIC_NO_EXPORT
+#else
+# ifndef LIBSTATIC_EXPORT
+# ifdef libstatic_EXPORTS
+ /* We are building this library */
+# define LIBSTATIC_EXPORT
+# else
+ /* We are using this library */
+# define LIBSTATIC_EXPORT
+# endif
+# endif
+
+# ifndef LIBSTATIC_NO_EXPORT
+# define LIBSTATIC_NO_EXPORT
+# endif
+#endif
+
+#ifndef LIBSTATIC_DEPRECATED
+# define LIBSTATIC_DEPRECATED
+#endif
+
+#ifndef LIBSTATIC_DEPRECATED_EXPORT
+# define LIBSTATIC_DEPRECATED_EXPORT LIBSTATIC_EXPORT LIBSTATIC_DEPRECATED
+#endif
+
+#ifndef LIBSTATIC_DEPRECATED_NO_EXPORT
+# define LIBSTATIC_DEPRECATED_NO_EXPORT LIBSTATIC_NO_EXPORT LIBSTATIC_DEPRECATED
+#endif
+
+#define DEFINE_NO_DEPRECATED 0
+#if DEFINE_NO_DEPRECATED
+# define LIBSTATIC_NO_DEPRECATED
+#endif
+
+#endif
diff --git a/Tests/Module/GenerateExportHeader/reference/MinGW/libshared_export.h b/Tests/Module/GenerateExportHeader/reference/MinGW/libshared_export.h
new file mode 100644
index 000000000..d37663102
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/reference/MinGW/libshared_export.h
@@ -0,0 +1,41 @@
+
+#ifndef LIBSHARED_EXPORT_H
+#define LIBSHARED_EXPORT_H
+
+#ifdef LIBSHARED_STATIC_DEFINE
+# define LIBSHARED_EXPORT
+# define LIBSHARED_NO_EXPORT
+#else
+# ifndef LIBSHARED_EXPORT
+# ifdef libshared_EXPORTS
+ /* We are building this library */
+# define LIBSHARED_EXPORT __declspec(dllexport)
+# else
+ /* We are using this library */
+# define LIBSHARED_EXPORT __declspec(dllimport)
+# endif
+# endif
+
+# ifndef LIBSHARED_NO_EXPORT
+# define LIBSHARED_NO_EXPORT
+# endif
+#endif
+
+#ifndef LIBSHARED_DEPRECATED
+# define LIBSHARED_DEPRECATED __attribute__ ((__deprecated__))
+#endif
+
+#ifndef LIBSHARED_DEPRECATED_EXPORT
+# define LIBSHARED_DEPRECATED_EXPORT LIBSHARED_EXPORT LIBSHARED_DEPRECATED
+#endif
+
+#ifndef LIBSHARED_DEPRECATED_NO_EXPORT
+# define LIBSHARED_DEPRECATED_NO_EXPORT LIBSHARED_NO_EXPORT LIBSHARED_DEPRECATED
+#endif
+
+#define DEFINE_NO_DEPRECATED 0
+#if DEFINE_NO_DEPRECATED
+# define LIBSHARED_NO_DEPRECATED
+#endif
+
+#endif
diff --git a/Tests/Module/GenerateExportHeader/reference/MinGW/libstatic_export.h b/Tests/Module/GenerateExportHeader/reference/MinGW/libstatic_export.h
new file mode 100644
index 000000000..fd021e9d0
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/reference/MinGW/libstatic_export.h
@@ -0,0 +1,41 @@
+
+#ifndef LIBSTATIC_EXPORT_H
+#define LIBSTATIC_EXPORT_H
+
+#ifdef LIBSTATIC_STATIC_DEFINE
+# define LIBSTATIC_EXPORT
+# define LIBSTATIC_NO_EXPORT
+#else
+# ifndef LIBSTATIC_EXPORT
+# ifdef libstatic_EXPORTS
+ /* We are building this library */
+# define LIBSTATIC_EXPORT
+# else
+ /* We are using this library */
+# define LIBSTATIC_EXPORT
+# endif
+# endif
+
+# ifndef LIBSTATIC_NO_EXPORT
+# define LIBSTATIC_NO_EXPORT
+# endif
+#endif
+
+#ifndef LIBSTATIC_DEPRECATED
+# define LIBSTATIC_DEPRECATED __attribute__ ((__deprecated__))
+#endif
+
+#ifndef LIBSTATIC_DEPRECATED_EXPORT
+# define LIBSTATIC_DEPRECATED_EXPORT LIBSTATIC_EXPORT LIBSTATIC_DEPRECATED
+#endif
+
+#ifndef LIBSTATIC_DEPRECATED_NO_EXPORT
+# define LIBSTATIC_DEPRECATED_NO_EXPORT LIBSTATIC_NO_EXPORT LIBSTATIC_DEPRECATED
+#endif
+
+#define DEFINE_NO_DEPRECATED 0
+#if DEFINE_NO_DEPRECATED
+# define LIBSTATIC_NO_DEPRECATED
+#endif
+
+#endif
diff --git a/Tests/Module/GenerateExportHeader/reference/UNIX/libshared_export.h b/Tests/Module/GenerateExportHeader/reference/UNIX/libshared_export.h
new file mode 100644
index 000000000..7d8087f60
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/reference/UNIX/libshared_export.h
@@ -0,0 +1,41 @@
+
+#ifndef LIBSHARED_EXPORT_H
+#define LIBSHARED_EXPORT_H
+
+#ifdef LIBSHARED_STATIC_DEFINE
+# define LIBSHARED_EXPORT
+# define LIBSHARED_NO_EXPORT
+#else
+# ifndef LIBSHARED_EXPORT
+# ifdef libshared_EXPORTS
+ /* We are building this library */
+# define LIBSHARED_EXPORT __attribute__((visibility("default")))
+# else
+ /* We are using this library */
+# define LIBSHARED_EXPORT __attribute__((visibility("default")))
+# endif
+# endif
+
+# ifndef LIBSHARED_NO_EXPORT
+# define LIBSHARED_NO_EXPORT __attribute__((visibility("hidden")))
+# endif
+#endif
+
+#ifndef LIBSHARED_DEPRECATED
+# define LIBSHARED_DEPRECATED __attribute__ ((__deprecated__))
+#endif
+
+#ifndef LIBSHARED_DEPRECATED_EXPORT
+# define LIBSHARED_DEPRECATED_EXPORT LIBSHARED_EXPORT LIBSHARED_DEPRECATED
+#endif
+
+#ifndef LIBSHARED_DEPRECATED_NO_EXPORT
+# define LIBSHARED_DEPRECATED_NO_EXPORT LIBSHARED_NO_EXPORT LIBSHARED_DEPRECATED
+#endif
+
+#define DEFINE_NO_DEPRECATED 0
+#if DEFINE_NO_DEPRECATED
+# define LIBSHARED_NO_DEPRECATED
+#endif
+
+#endif
diff --git a/Tests/Module/GenerateExportHeader/reference/UNIX/libstatic_export.h b/Tests/Module/GenerateExportHeader/reference/UNIX/libstatic_export.h
new file mode 100644
index 000000000..fd021e9d0
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/reference/UNIX/libstatic_export.h
@@ -0,0 +1,41 @@
+
+#ifndef LIBSTATIC_EXPORT_H
+#define LIBSTATIC_EXPORT_H
+
+#ifdef LIBSTATIC_STATIC_DEFINE
+# define LIBSTATIC_EXPORT
+# define LIBSTATIC_NO_EXPORT
+#else
+# ifndef LIBSTATIC_EXPORT
+# ifdef libstatic_EXPORTS
+ /* We are building this library */
+# define LIBSTATIC_EXPORT
+# else
+ /* We are using this library */
+# define LIBSTATIC_EXPORT
+# endif
+# endif
+
+# ifndef LIBSTATIC_NO_EXPORT
+# define LIBSTATIC_NO_EXPORT
+# endif
+#endif
+
+#ifndef LIBSTATIC_DEPRECATED
+# define LIBSTATIC_DEPRECATED __attribute__ ((__deprecated__))
+#endif
+
+#ifndef LIBSTATIC_DEPRECATED_EXPORT
+# define LIBSTATIC_DEPRECATED_EXPORT LIBSTATIC_EXPORT LIBSTATIC_DEPRECATED
+#endif
+
+#ifndef LIBSTATIC_DEPRECATED_NO_EXPORT
+# define LIBSTATIC_DEPRECATED_NO_EXPORT LIBSTATIC_NO_EXPORT LIBSTATIC_DEPRECATED
+#endif
+
+#define DEFINE_NO_DEPRECATED 0
+#if DEFINE_NO_DEPRECATED
+# define LIBSTATIC_NO_DEPRECATED
+#endif
+
+#endif
diff --git a/Tests/Module/GenerateExportHeader/reference/UNIX_DeprecatedOnly/libshared_export.h b/Tests/Module/GenerateExportHeader/reference/UNIX_DeprecatedOnly/libshared_export.h
new file mode 100644
index 000000000..5681f5842
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/reference/UNIX_DeprecatedOnly/libshared_export.h
@@ -0,0 +1,41 @@
+
+#ifndef LIBSHARED_EXPORT_H
+#define LIBSHARED_EXPORT_H
+
+#ifdef LIBSHARED_STATIC_DEFINE
+# define LIBSHARED_EXPORT
+# define LIBSHARED_NO_EXPORT
+#else
+# ifndef LIBSHARED_EXPORT
+# ifdef libshared_EXPORTS
+ /* We are building this library */
+# define LIBSHARED_EXPORT
+# else
+ /* We are using this library */
+# define LIBSHARED_EXPORT
+# endif
+# endif
+
+# ifndef LIBSHARED_NO_EXPORT
+# define LIBSHARED_NO_EXPORT
+# endif
+#endif
+
+#ifndef LIBSHARED_DEPRECATED
+# define LIBSHARED_DEPRECATED __attribute__ ((__deprecated__))
+#endif
+
+#ifndef LIBSHARED_DEPRECATED_EXPORT
+# define LIBSHARED_DEPRECATED_EXPORT LIBSHARED_EXPORT LIBSHARED_DEPRECATED
+#endif
+
+#ifndef LIBSHARED_DEPRECATED_NO_EXPORT
+# define LIBSHARED_DEPRECATED_NO_EXPORT LIBSHARED_NO_EXPORT LIBSHARED_DEPRECATED
+#endif
+
+#define DEFINE_NO_DEPRECATED 0
+#if DEFINE_NO_DEPRECATED
+# define LIBSHARED_NO_DEPRECATED
+#endif
+
+#endif
diff --git a/Tests/Module/GenerateExportHeader/reference/UNIX_DeprecatedOnly/libstatic_export.h b/Tests/Module/GenerateExportHeader/reference/UNIX_DeprecatedOnly/libstatic_export.h
new file mode 100644
index 000000000..fd021e9d0
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/reference/UNIX_DeprecatedOnly/libstatic_export.h
@@ -0,0 +1,41 @@
+
+#ifndef LIBSTATIC_EXPORT_H
+#define LIBSTATIC_EXPORT_H
+
+#ifdef LIBSTATIC_STATIC_DEFINE
+# define LIBSTATIC_EXPORT
+# define LIBSTATIC_NO_EXPORT
+#else
+# ifndef LIBSTATIC_EXPORT
+# ifdef libstatic_EXPORTS
+ /* We are building this library */
+# define LIBSTATIC_EXPORT
+# else
+ /* We are using this library */
+# define LIBSTATIC_EXPORT
+# endif
+# endif
+
+# ifndef LIBSTATIC_NO_EXPORT
+# define LIBSTATIC_NO_EXPORT
+# endif
+#endif
+
+#ifndef LIBSTATIC_DEPRECATED
+# define LIBSTATIC_DEPRECATED __attribute__ ((__deprecated__))
+#endif
+
+#ifndef LIBSTATIC_DEPRECATED_EXPORT
+# define LIBSTATIC_DEPRECATED_EXPORT LIBSTATIC_EXPORT LIBSTATIC_DEPRECATED
+#endif
+
+#ifndef LIBSTATIC_DEPRECATED_NO_EXPORT
+# define LIBSTATIC_DEPRECATED_NO_EXPORT LIBSTATIC_NO_EXPORT LIBSTATIC_DEPRECATED
+#endif
+
+#define DEFINE_NO_DEPRECATED 0
+#if DEFINE_NO_DEPRECATED
+# define LIBSTATIC_NO_DEPRECATED
+#endif
+
+#endif
diff --git a/Tests/Module/GenerateExportHeader/reference/Win32/libshared_export.h b/Tests/Module/GenerateExportHeader/reference/Win32/libshared_export.h
new file mode 100644
index 000000000..976c92ef8
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/reference/Win32/libshared_export.h
@@ -0,0 +1,41 @@
+
+#ifndef LIBSHARED_EXPORT_H
+#define LIBSHARED_EXPORT_H
+
+#ifdef LIBSHARED_STATIC_DEFINE
+# define LIBSHARED_EXPORT
+# define LIBSHARED_NO_EXPORT
+#else
+# ifndef LIBSHARED_EXPORT
+# ifdef libshared_EXPORTS
+ /* We are building this library */
+# define LIBSHARED_EXPORT __declspec(dllexport)
+# else
+ /* We are using this library */
+# define LIBSHARED_EXPORT __declspec(dllimport)
+# endif
+# endif
+
+# ifndef LIBSHARED_NO_EXPORT
+# define LIBSHARED_NO_EXPORT
+# endif
+#endif
+
+#ifndef LIBSHARED_DEPRECATED
+# define LIBSHARED_DEPRECATED __declspec(deprecated)
+#endif
+
+#ifndef LIBSHARED_DEPRECATED_EXPORT
+# define LIBSHARED_DEPRECATED_EXPORT LIBSHARED_EXPORT LIBSHARED_DEPRECATED
+#endif
+
+#ifndef LIBSHARED_DEPRECATED_NO_EXPORT
+# define LIBSHARED_DEPRECATED_NO_EXPORT LIBSHARED_NO_EXPORT LIBSHARED_DEPRECATED
+#endif
+
+#define DEFINE_NO_DEPRECATED 0
+#if DEFINE_NO_DEPRECATED
+# define LIBSHARED_NO_DEPRECATED
+#endif
+
+#endif
diff --git a/Tests/Module/GenerateExportHeader/reference/Win32/libstatic_export.h b/Tests/Module/GenerateExportHeader/reference/Win32/libstatic_export.h
new file mode 100644
index 000000000..db4df61b4
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/reference/Win32/libstatic_export.h
@@ -0,0 +1,41 @@
+
+#ifndef LIBSTATIC_EXPORT_H
+#define LIBSTATIC_EXPORT_H
+
+#ifdef LIBSTATIC_STATIC_DEFINE
+# define LIBSTATIC_EXPORT
+# define LIBSTATIC_NO_EXPORT
+#else
+# ifndef LIBSTATIC_EXPORT
+# ifdef libstatic_EXPORTS
+ /* We are building this library */
+# define LIBSTATIC_EXPORT
+# else
+ /* We are using this library */
+# define LIBSTATIC_EXPORT
+# endif
+# endif
+
+# ifndef LIBSTATIC_NO_EXPORT
+# define LIBSTATIC_NO_EXPORT
+# endif
+#endif
+
+#ifndef LIBSTATIC_DEPRECATED
+# define LIBSTATIC_DEPRECATED __declspec(deprecated)
+#endif
+
+#ifndef LIBSTATIC_DEPRECATED_EXPORT
+# define LIBSTATIC_DEPRECATED_EXPORT LIBSTATIC_EXPORT LIBSTATIC_DEPRECATED
+#endif
+
+#ifndef LIBSTATIC_DEPRECATED_NO_EXPORT
+# define LIBSTATIC_DEPRECATED_NO_EXPORT LIBSTATIC_NO_EXPORT LIBSTATIC_DEPRECATED
+#endif
+
+#define DEFINE_NO_DEPRECATED 0
+#if DEFINE_NO_DEPRECATED
+# define LIBSTATIC_NO_DEPRECATED
+#endif
+
+#endif
diff --git a/Tests/Module/GenerateExportHeader/reference/WinEmpty/libshared_export.h b/Tests/Module/GenerateExportHeader/reference/WinEmpty/libshared_export.h
new file mode 100644
index 000000000..2dc41d414
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/reference/WinEmpty/libshared_export.h
@@ -0,0 +1,41 @@
+
+#ifndef LIBSHARED_EXPORT_H
+#define LIBSHARED_EXPORT_H
+
+#ifdef LIBSHARED_STATIC_DEFINE
+# define LIBSHARED_EXPORT
+# define LIBSHARED_NO_EXPORT
+#else
+# ifndef LIBSHARED_EXPORT
+# ifdef libshared_EXPORTS
+ /* We are building this library */
+# define LIBSHARED_EXPORT __declspec(dllexport)
+# else
+ /* We are using this library */
+# define LIBSHARED_EXPORT __declspec(dllimport)
+# endif
+# endif
+
+# ifndef LIBSHARED_NO_EXPORT
+# define LIBSHARED_NO_EXPORT
+# endif
+#endif
+
+#ifndef LIBSHARED_DEPRECATED
+# define LIBSHARED_DEPRECATED
+#endif
+
+#ifndef LIBSHARED_DEPRECATED_EXPORT
+# define LIBSHARED_DEPRECATED_EXPORT LIBSHARED_EXPORT LIBSHARED_DEPRECATED
+#endif
+
+#ifndef LIBSHARED_DEPRECATED_NO_EXPORT
+# define LIBSHARED_DEPRECATED_NO_EXPORT LIBSHARED_NO_EXPORT LIBSHARED_DEPRECATED
+#endif
+
+#define DEFINE_NO_DEPRECATED 0
+#if DEFINE_NO_DEPRECATED
+# define LIBSHARED_NO_DEPRECATED
+#endif
+
+#endif
diff --git a/Tests/Module/GenerateExportHeader/reference/WinEmpty/libstatic_export.h b/Tests/Module/GenerateExportHeader/reference/WinEmpty/libstatic_export.h
new file mode 100644
index 000000000..e8000e251
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/reference/WinEmpty/libstatic_export.h
@@ -0,0 +1,41 @@
+
+#ifndef LIBSTATIC_EXPORT_H
+#define LIBSTATIC_EXPORT_H
+
+#ifdef LIBSTATIC_STATIC_DEFINE
+# define LIBSTATIC_EXPORT
+# define LIBSTATIC_NO_EXPORT
+#else
+# ifndef LIBSTATIC_EXPORT
+# ifdef libstatic_EXPORTS
+ /* We are building this library */
+# define LIBSTATIC_EXPORT
+# else
+ /* We are using this library */
+# define LIBSTATIC_EXPORT
+# endif
+# endif
+
+# ifndef LIBSTATIC_NO_EXPORT
+# define LIBSTATIC_NO_EXPORT
+# endif
+#endif
+
+#ifndef LIBSTATIC_DEPRECATED
+# define LIBSTATIC_DEPRECATED
+#endif
+
+#ifndef LIBSTATIC_DEPRECATED_EXPORT
+# define LIBSTATIC_DEPRECATED_EXPORT LIBSTATIC_EXPORT LIBSTATIC_DEPRECATED
+#endif
+
+#ifndef LIBSTATIC_DEPRECATED_NO_EXPORT
+# define LIBSTATIC_DEPRECATED_NO_EXPORT LIBSTATIC_NO_EXPORT LIBSTATIC_DEPRECATED
+#endif
+
+#define DEFINE_NO_DEPRECATED 0
+#if DEFINE_NO_DEPRECATED
+# define LIBSTATIC_NO_DEPRECATED
+#endif
+
+#endif
diff --git a/Tests/Module/GenerateExportHeader/visibility_preset/CMakeLists.txt b/Tests/Module/GenerateExportHeader/visibility_preset/CMakeLists.txt
deleted file mode 100644
index 2571d2224..000000000
--- a/Tests/Module/GenerateExportHeader/visibility_preset/CMakeLists.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-
-set(CMAKE_CXX_VISIBILITY_PRESET hidden)
-set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
-
-if (CMAKE_CXX_FLAGS MATCHES "-fvisibility=hidden")
- message(SEND_ERROR "Do not use add_compiler_export_flags before adding this directory")
-endif()
-if (CMAKE_CXX_FLAGS MATCHES "-fvisibility-inlines-hidden")
- message(SEND_ERROR "Do not use add_compiler_export_flags before adding this directory")
-endif()
-
-add_library(visibility_preset SHARED visibility_preset.cpp)
-generate_export_header(visibility_preset)
-
-add_executable(visibility_preset_exe main.cpp)
-
-target_link_libraries(visibility_preset_exe visibility_preset)
diff --git a/Tests/Module/GenerateExportHeader/visibility_preset/main.cpp b/Tests/Module/GenerateExportHeader/visibility_preset/main.cpp
deleted file mode 100644
index 89c397784..000000000
--- a/Tests/Module/GenerateExportHeader/visibility_preset/main.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-
-#include "visibility_preset.h"
-
-int main()
-{
- VisibilityPreset vp;
- vp.someMethod();
- return 0;
-}
diff --git a/Tests/Module/GenerateExportHeader/visibility_preset/visibility_preset.cpp b/Tests/Module/GenerateExportHeader/visibility_preset/visibility_preset.cpp
deleted file mode 100644
index c97dec6e2..000000000
--- a/Tests/Module/GenerateExportHeader/visibility_preset/visibility_preset.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-
-#include "visibility_preset.h"
-
-void VisibilityPreset::someMethod()
-{
-
-}
diff --git a/Tests/Module/GenerateExportHeader/visibility_preset/visibility_preset.h b/Tests/Module/GenerateExportHeader/visibility_preset/visibility_preset.h
deleted file mode 100644
index 8becbe189..000000000
--- a/Tests/Module/GenerateExportHeader/visibility_preset/visibility_preset.h
+++ /dev/null
@@ -1,13 +0,0 @@
-
-#ifndef VISIBILITY_PRESET_H
-#define VISIBILITY_PRESET_H
-
-#include "visibility_preset_export.h"
-
-class VISIBILITY_PRESET_EXPORT VisibilityPreset
-{
-public:
- void someMethod();
-};
-
-#endif
diff --git a/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt b/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt
new file mode 100644
index 000000000..c53828074
--- /dev/null
+++ b/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt
@@ -0,0 +1,154 @@
+cmake_minimum_required(VERSION 3.1.0)
+project(WriteCompilerDetectionHeader)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+include(WriteCompilerDetectionHeader)
+
+get_property(cxx_known_features GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES)
+get_property(c_known_features GLOBAL PROPERTY CMAKE_C_KNOWN_FEATURES)
+
+write_compiler_detection_header(
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/test_compiler_detection.h"
+ PREFIX TEST
+ COMPILERS GNU Clang AppleClang MSVC SunPro
+ VERSION 3.1
+ PROLOG "// something"
+ EPILOG "// more"
+ FEATURES
+ ${cxx_known_features} ${c_known_features}
+)
+
+if (NOT CMAKE_CXX_COMPILE_FEATURES AND NOT CMAKE_C_COMPILE_FEATURES)
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp"
+ "int main(int,char**) { return 0; }\n"
+ )
+ add_executable(WriteCompilerDetectionHeader "${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp")
+
+ if(UNIX OR NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ include(CheckCXXSourceCompiles)
+ check_cxx_source_compiles("#include \"${CMAKE_CURRENT_BINARY_DIR}/test_compiler_detection.h\"\nint main() { return 0; }\n"
+ file_include_works
+ )
+ if (file_include_works)
+ message(SEND_ERROR "Inclusion of ${CMAKE_CURRENT_BINARY_DIR}/test_compiler_detection.h was expected to cause an error, but did not.")
+ endif()
+ endif()
+ return()
+endif()
+
+string(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" COMPILER_VERSION_MAJOR "${CMAKE_CXX_COMPILER_VERSION}")
+string(REGEX REPLACE "^[0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" COMPILER_VERSION_MINOR "${CMAKE_CXX_COMPILER_VERSION}")
+string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" COMPILER_VERSION_PATCH "${CMAKE_CXX_COMPILER_VERSION}")
+
+macro(set_defines target true_defs false_defs)
+ set(defines)
+ foreach(def ${true_defs})
+ list(APPEND defines ${def}=1)
+ endforeach()
+ foreach(def ${false_defs})
+ list(APPEND defines ${def}=0)
+ endforeach()
+ target_compile_definitions(${target}
+ PRIVATE
+ ${defines}
+ EXPECTED_COMPILER_VERSION_MAJOR=${COMPILER_VERSION_MAJOR}
+ EXPECTED_COMPILER_VERSION_MINOR=${COMPILER_VERSION_MINOR}
+ EXPECTED_COMPILER_VERSION_PATCH=${COMPILER_VERSION_PATCH}
+ )
+endmacro()
+
+if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
+ OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang"
+ OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang"
+ OR CMAKE_CXX_COMPILER_ID STREQUAL "SunPro")
+ # False for C++98 mode.
+ list(APPEND false_defs EXPECTED_COMPILER_CXX_DELEGATING_CONSTRUCTORS)
+ list(APPEND false_defs EXPECTED_COMPILER_CXX_VARIADIC_TEMPLATES)
+endif()
+
+# for msvc the compiler version determines which c++11 features are available.
+if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
+ if(";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";cxx_delegating_constructors;")
+ list(APPEND true_defs EXPECTED_COMPILER_CXX_DELEGATING_CONSTRUCTORS)
+ list(APPEND true_defs EXPECTED_COMPILER_CXX_VARIADIC_TEMPLATES)
+ else()
+ list(APPEND false_defs EXPECTED_COMPILER_CXX_DELEGATING_CONSTRUCTORS)
+ list(APPEND false_defs EXPECTED_COMPILER_CXX_VARIADIC_TEMPLATES)
+ endif()
+endif()
+
+if (CMAKE_C_COMPILER_ID STREQUAL "GNU"
+ OR CMAKE_C_COMPILER_ID STREQUAL "Clang"
+ OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
+ add_executable(C_undefined c_undefined.c)
+ set_property(TARGET C_undefined PROPERTY C_STANDARD 90)
+ target_compile_options(C_undefined PRIVATE -Werror=undef)
+
+ add_executable(WriteCompilerDetectionHeader_C main.c)
+ set_property(TARGET WriteCompilerDetectionHeader_C PROPERTY C_STANDARD 90)
+ set_defines(WriteCompilerDetectionHeader_C "EXPECTED_COMPILER_C_FUNCTION_PROTOTYPES" "EXPECTED_COMPILER_C_RESTRICT")
+
+ add_executable(WriteCompilerDetectionHeader_C_multi main_multi.c)
+ set_property(TARGET WriteCompilerDetectionHeader_C_multi PROPERTY C_STANDARD 90)
+ set_defines(WriteCompilerDetectionHeader_C_multi "EXPECTED_COMPILER_C_FUNCTION_PROTOTYPES" "EXPECTED_COMPILER_C_RESTRICT")
+ target_include_directories(WriteCompilerDetectionHeader_C_multi PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/compiler_multi_files)
+endif()
+
+add_executable(WriteCompilerDetectionHeader main.cpp)
+set_property(TARGET WriteCompilerDetectionHeader PROPERTY CXX_STANDARD 98)
+set_defines(WriteCompilerDetectionHeader "${true_defs}" "${false_defs}")
+
+write_compiler_detection_header(
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/compiler_multi_files/multi_file_compiler_detection.h"
+ PREFIX MULTI
+ OUTPUT_FILES_VAR multi_files
+ OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/compiler_multi_files/compiler_support"
+ COMPILERS GNU Clang AppleClang MSVC SunPro
+ VERSION 3.1
+ FEATURES
+ ${cxx_known_features} ${c_known_features}
+)
+
+add_executable(multi_files multi_files.cpp)
+set_property(TARGET multi_files PROPERTY CXX_STANDARD 98)
+target_include_directories(multi_files PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/compiler_multi_files)
+set_defines(multi_files "${true_defs}" "${false_defs}")
+
+if(MSVC)
+ return() # MSVC has only one mode.
+endif()
+
+# Since GNU 4.7
+if (";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";cxx_delegating_constructors;")
+ list(APPEND true_defs EXPECTED_COMPILER_CXX_DELEGATING_CONSTRUCTORS)
+ list(REMOVE_ITEM false_defs EXPECTED_COMPILER_CXX_DELEGATING_CONSTRUCTORS)
+endif()
+
+# Since GNU 4.4
+if (";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";cxx_variadic_templates;")
+ list(APPEND true_defs EXPECTED_COMPILER_CXX_VARIADIC_TEMPLATES)
+ list(REMOVE_ITEM false_defs EXPECTED_COMPILER_CXX_VARIADIC_TEMPLATES)
+endif()
+
+add_executable(WriteCompilerDetectionHeader_11 main.cpp)
+set_property(TARGET WriteCompilerDetectionHeader_11 PROPERTY CXX_STANDARD 11)
+set_defines(WriteCompilerDetectionHeader_11 "${true_defs}" "${false_defs}")
+
+add_executable(multi_files_11 multi_files.cpp)
+set_property(TARGET multi_files_11 PROPERTY CXX_STANDARD 11)
+target_include_directories(multi_files_11 PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/compiler_multi_files)
+set_defines(multi_files_11 "${true_defs}" "${false_defs}")
+
+if (CMAKE_C_COMPILER_ID STREQUAL "GNU"
+ OR CMAKE_C_COMPILER_ID STREQUAL "Clang"
+ OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
+ add_executable(WriteCompilerDetectionHeader_C11 main.c)
+ set_property(TARGET WriteCompilerDetectionHeader_C11 PROPERTY C_STANDARD 11)
+ set_defines(WriteCompilerDetectionHeader_C11 "EXPECTED_COMPILER_C_FUNCTION_PROTOTYPES;EXPECTED_COMPILER_C_RESTRICT" "")
+
+ add_executable(WriteCompilerDetectionHeader_C11_multi main_multi.c)
+ set_property(TARGET WriteCompilerDetectionHeader_C11_multi PROPERTY C_STANDARD 11)
+ set_defines(WriteCompilerDetectionHeader_C11_multi "EXPECTED_COMPILER_C_FUNCTION_PROTOTYPES;EXPECTED_COMPILER_C_RESTRICT" "")
+ target_include_directories(WriteCompilerDetectionHeader_C11_multi PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/compiler_multi_files)
+endif()
diff --git a/Tests/Module/WriteCompilerDetectionHeader/c_undefined.c b/Tests/Module/WriteCompilerDetectionHeader/c_undefined.c
new file mode 100644
index 000000000..487e66dd0
--- /dev/null
+++ b/Tests/Module/WriteCompilerDetectionHeader/c_undefined.c
@@ -0,0 +1,7 @@
+
+#include "test_compiler_detection.h"
+
+int main()
+{
+ return 0;
+}
diff --git a/Tests/Module/WriteCompilerDetectionHeader/compile_tests.h b/Tests/Module/WriteCompilerDetectionHeader/compile_tests.h
new file mode 100644
index 000000000..8b547d846
--- /dev/null
+++ b/Tests/Module/WriteCompilerDetectionHeader/compile_tests.h
@@ -0,0 +1,25 @@
+
+#define JOIN_IMPL(A, B) A ## B
+#define JOIN(A, B) JOIN_IMPL(A, B)
+
+#define CHECK(FEATURE) (JOIN(PREFIX, JOIN(_COMPILER_, FEATURE)) == JOIN(EXPECTED_COMPILER_, FEATURE))
+
+#if !CHECK(CXX_DELEGATING_CONSTRUCTORS)
+#error cxx_delegating_constructors expected availability did not match.
+#endif
+
+#if !CHECK(CXX_VARIADIC_TEMPLATES)
+#error cxx_variadic_templates expected availability did not match.
+#endif
+
+#if !CHECK(VERSION_MAJOR)
+#error Compiler major version did not match.
+#endif
+
+#if !CHECK(VERSION_MINOR)
+#error Compiler minor version did not match.
+#endif
+
+#if !CHECK(VERSION_PATCH)
+#error Compiler patch version did not match.
+#endif
diff --git a/Tests/Module/WriteCompilerDetectionHeader/main.c b/Tests/Module/WriteCompilerDetectionHeader/main.c
new file mode 100644
index 000000000..9023b0f53
--- /dev/null
+++ b/Tests/Module/WriteCompilerDetectionHeader/main.c
@@ -0,0 +1,29 @@
+
+#include "test_compiler_detection.h"
+
+#if !defined(TEST_COMPILER_C_FUNCTION_PROTOTYPES) || !TEST_COMPILER_C_FUNCTION_PROTOTYPES
+# error Expected TEST_COMPILER_C_FUNCTION_PROTOTYPES
+#endif
+
+#if !EXPECTED_COMPILER_C_FUNCTION_PROTOTYPES
+# error Expected EXPECTED_COMPILER_C_FUNCTION_PROTOTYPES
+#endif
+
+#if !defined(TEST_COMPILER_C_RESTRICT) || !TEST_COMPILER_C_RESTRICT
+# if EXPECTED_COMPILER_C_RESTRICT
+# error Expected TEST_COMPILER_C_RESTRICT
+# endif
+#else
+# if !EXPECTED_COMPILER_C_RESTRICT
+# error Expect no TEST_COMPILER_C_RESTRICT
+# endif
+#endif
+
+#ifdef TEST_COMPILER_CXX_STATIC_ASSERT
+#error Expect no CXX features defined
+#endif
+
+int main()
+{
+ return 0;
+}
diff --git a/Tests/Module/WriteCompilerDetectionHeader/main.cpp b/Tests/Module/WriteCompilerDetectionHeader/main.cpp
new file mode 100644
index 000000000..192094c1b
--- /dev/null
+++ b/Tests/Module/WriteCompilerDetectionHeader/main.cpp
@@ -0,0 +1,14 @@
+
+#include "test_compiler_detection.h"
+
+#define PREFIX TEST
+#include "compile_tests.h"
+
+#ifdef TEST_COMPILER_C_STATIC_ASSERT
+#error Expect no C features defined
+#endif
+
+int main()
+{
+ return 0;
+}
diff --git a/Tests/Module/WriteCompilerDetectionHeader/main_multi.c b/Tests/Module/WriteCompilerDetectionHeader/main_multi.c
new file mode 100644
index 000000000..6f4573f77
--- /dev/null
+++ b/Tests/Module/WriteCompilerDetectionHeader/main_multi.c
@@ -0,0 +1,29 @@
+
+#include "multi_file_compiler_detection.h"
+
+#if !defined(MULTI_COMPILER_C_FUNCTION_PROTOTYPES) || !MULTI_COMPILER_C_FUNCTION_PROTOTYPES
+# error Expected MULTI_COMPILER_C_FUNCTION_PROTOTYPES
+#endif
+
+#if !EXPECTED_COMPILER_C_FUNCTION_PROTOTYPES
+# error Expected EXPECTED_COMPILER_C_FUNCTION_PROTOTYPES
+#endif
+
+#if !defined(MULTI_COMPILER_C_RESTRICT) || !MULTI_COMPILER_C_RESTRICT
+# if EXPECTED_COMPILER_C_RESTRICT
+# error Expected MULTI_COMPILER_C_RESTRICT
+# endif
+#else
+# if !EXPECTED_COMPILER_C_RESTRICT
+# error Expect no MULTI_COMPILER_C_RESTRICT
+# endif
+#endif
+
+#ifdef MULTI_COMPILER_CXX_STATIC_ASSERT
+#error Expect no CXX features defined
+#endif
+
+int main()
+{
+ return 0;
+}
diff --git a/Tests/Module/WriteCompilerDetectionHeader/multi_files.cpp b/Tests/Module/WriteCompilerDetectionHeader/multi_files.cpp
new file mode 100644
index 000000000..1635091cb
--- /dev/null
+++ b/Tests/Module/WriteCompilerDetectionHeader/multi_files.cpp
@@ -0,0 +1,14 @@
+
+#include "multi_file_compiler_detection.h"
+
+#define PREFIX MULTI
+#include "compile_tests.h"
+
+#ifdef MULTI_COMPILER_C_STATIC_ASSERT
+#error Expect no C features defined
+#endif
+
+int main()
+{
+ return 0;
+}
diff --git a/Tests/ModuleDefinition/CMakeLists.txt b/Tests/ModuleDefinition/CMakeLists.txt
index a30f64363..bfbb343bc 100644
--- a/Tests/ModuleDefinition/CMakeLists.txt
+++ b/Tests/ModuleDefinition/CMakeLists.txt
@@ -13,7 +13,7 @@ add_custom_command(OUTPUT example_dll_gen.def
add_library(example_dll_gen SHARED example_dll_gen.c example_dll_gen.def)
# Test /DEF:<file> flag recognition for VS.
-if(MSVC OR "${CMAKE_C_COMPILER_ID}" MATCHES "^(Intel)$")
+if(MSVC OR CMAKE_C_COMPILER_ID STREQUAL "Intel")
add_library(example_dll_2 SHARED example_dll_2.c)
set_property(TARGET example_dll_2 PROPERTY LINK_FLAGS
/DEF:"${ModuleDefinition_SOURCE_DIR}/example_dll_2.def")
diff --git a/Tests/MumpsCoverage/Accounts_ReceivableTest.cmcov b/Tests/MumpsCoverage/Accounts_ReceivableTest.cmcov
deleted file mode 100644
index c3b3342ab..000000000
--- a/Tests/MumpsCoverage/Accounts_ReceivableTest.cmcov
+++ /dev/null
@@ -1,304 +0,0 @@
-Routine,Line,RtnLine,Code
-DDIOL,1,0,"DDIOL ;SFISC/MKO-THE LOADER ;1:53 PM 12 Sep 1995"
-,2,0," ;;22.0;VA FileMan;;Mar 30, 1999"
-,3,0," ;Per VHA Directive 10-93-142, this routine should not be modified."
-,4,0," ;"
-,5,0,"EN(A,G,FMT) ;Write the text contained in local array A or global array G"
-,6,0," ;If one string passed, use format FMT"
-,7,0," N %,Y,DINAKED"
-,8,0," S DINAKED=$$LGR^%ZOSV"
-,9,0," ;"
-,10,0," S:'$D(A) A="""""
-,11,0," I $G(A)="""",$D(A)<9,$G(FMT)="""",$G(G)'?1""^""1A.7AN,$G(G)'?1""^""1A.7AN1""("".E1"")"" Q"
-,12,0," ;"
-,13,0," G:$D(DDS) SM"
-,14,0," G:$D(DIQUIET) LD"
-,15,0," ;"
-,16,0," N F,I,S"
-,17,0," I $D(A)=1,$G(G)="""" D"
-,18,0," . S F=$S($G(FMT)]"""":FMT,1:""!"")"
-,19,0," . W @F,A"
-,20,0," ;"
-,21,0," E I $D(A)>9 S I=0 F S I=$O(A(I)) Q:I'=+$P(I,""E"") D"
-,22,0," . S F=$G(A(I,""F""),""!"") S:F="""" F=""?0"""
-,23,0," . W @F,$G(A(I))"
-,24,0," ;"
-,25,0," E S I=0 F S I=$O(@G@(I)) Q:I'=+$P(I,""E"") D"
-,26,0," . S S=$G(@G@(I,0),$G(@G@(I)))"
-,27,0," . S F=$G(@G@(I,""F""),""!"") S:F="""" F=""?0"""
-,28,0," . W @F,S"
-,29,0," ;"
-,30,0," I DINAKED]"""" S DINAKED=$S(DINAKED["""""""""""":$O(@DINAKED),1:$D(@DINAKED))"
-,31,0," Q"
-,32,0," ;"
-,33,0,"LD ;Load text into ^TMP"
-,34,0," N I,N,T"
-,35,0," S T=$S($G(DDIOLFLG)[""H"":""DIHELP"",1:""DIMSG"")"
-,36,0," S N=$O(^TMP(T,$J,"" ""),-1)"
-,37,0," ;"
-,38,0," I $D(A)=1,$G(G)="""" D"
-,39,0," . D LD1(A,$S($G(FMT)]"""":FMT,1:""!""))"
-,40,0," ;"
-,41,0," E I $D(A)>9 S I=0 F S I=$O(A(I)) Q:I'=+$P(I,""E"") D"
-,42,0," . D LD1($G(A(I)),$G(A(I,""F""),""!""))"
-,43,0," ;"
-,44,0," E S I=0 F S I=$O(@G@(I)) Q:I'=+$P(I,""E"") D"
-,45,0," . D LD1($G(@G@(I),$G(@G@(I,0))),$G(@G@(I,""F""),""!""))"
-,46,0," ;"
-,47,0," K:'N @T S:N @T=N"
-,48,0," I DINAKED]"""" S DINAKED=$S(DINAKED["""""""""""":$O(@DINAKED),1:$D(@DINAKED))"
-,49,0," Q"
-,50,0," ;"
-,51,0,"LD1(S,F) ;Load string S, with format F"
-,52,0," ;In: N and T"
-,53,0," N C,J,L"
-,54,0," S:S[$C(7) S=$TR(S,$C(7),"""")"
-,55,0," F J=1:1:$L(F,""!"")-1 S N=N+1,^TMP(T,$J,N)="""""
-,56,0," S:'N N=1"
-,57,0," S:F[""?"" @(""C=""_$P(F,""?"",2))"
-,58,0," S L=$G(^TMP(T,$J,N))"
-,59,0," S ^TMP(T,$J,N)=L_$J("""",$G(C)-$L(L))_S"
-,60,0," Q"
-,61,0," ;"
-,62,0,"SM ;Print text in ScreenMan's Command Area"
-,63,0," I $D(DDSID),$D(DTOUT)!$D(DUOUT) G SMQ"
-,64,0," N DDIOL"
-,65,0," S DDIOL=1"
-,66,0," ;"
-,67,0," I $D(A)=1&($G(G)="""")!($D(A)>9) D"
-,68,0," . D MSG^DDSMSG(.A,"""",$G(FMT))"
-,69,0," E I $D(@G@(+$O(@G@(0)),0))#2 D"
-,70,0," . D WP^DDSMSG(G)"
-,71,0," E D HLP^DDSMSG(G)"
-,72,0," ;"
-,73,0,"SMQ I DINAKED]"""" S DINAKED=$S(DINAKED["""""""""""":$O(@DINAKED),1:$D(@DINAKED))"
-,74,0," Q"
-Totals for DDIOL,,0,
-XINDEX,1,0,"XINDEX ;ISC/REL,GFT,GRK,RWF - INDEX & CROSS-REFERENCE ;08/04/08 13:19"
-,2,1," ;;7.3;TOOLKIT;**20,27,48,61,66,68,110,121,128**;Apr 25, 1995;Build 1"
-,3,0," ; Per VHA Directive 2004-038, this routine should not be modified."
-,4,1," G ^XINDX6"
-,5,107216,"SEP F I=1:1 S CH=$E(LIN,I) D QUOTE:CH=Q Q:"" ""[CH"
-,6,107216," S ARG=$E(LIN,1,I-1) S:CH="" "" I=I+1 S LIN=$E(LIN,I,999) Q"
-,7,36371,"QUOTE F I=I+1:1 S CH=$E(LIN,I) Q:CH=""""!(CH=Q)"
-,8,36371," Q:CH]"""" S ERR=6 G ^XINDX1"
-,9,0,"ALIVE ;enter here from taskman"
-,10,1," D SETUP^XINDX7 ;Get ready to process"
-,11,468,"A2 S RTN=$O(^UTILITY($J,RTN)) G ^XINDX5:RTN="""""
-,12,467," S INDLC=(RTN?1""|""1.4L.NP) D LOAD:'INDLC"
-,13,467," I $D(ZTQUEUED),$$S^%ZTLOAD S RTN=""~"",IND(""QUIT"")=1,ZTSTOP=1 G A2"
-,14,467," I 'INDDS,INDLC W !!?10,""Data Dictionaries"",! S INDDS=1"
-,15,467," D BEG"
-,16,467," G A2"
-,17,0," ;"
-,18,467,"LOAD S X=RTN,XCNP=0,DIF=""^UTILITY(""_$J_"",1,RTN,0,"" X ^%ZOSF(""TEST"") Q:'$T X ^%ZOSF(""LOAD"") S ^UTILITY($J,1,RTN,0,0)=XCNP-1"
-,19,467," I $D(^UTILITY($J,1,RTN,0,0)) S ^UTILITY($J,1,RTN,""RSUM"")=""B""_$$SUMB^XPDRSUM($NA(^UTILITY($J,1,RTN,0)))"
-,20,467," Q"
-,21,0,"BEG ;"
-,22,467," S %=INDLC*5 W:$X+10+%>IOM ! W RTN,$J("""",10+%-$L(RTN))"
-,23,467," S (IND(""DO""),IND(""SZT""),IND(""SZC""),LABO)=0,LC=$G(^UTILITY($J,1,RTN,0,0))"
-,24,467," I LC="""" W !,"">>>Routine '"",RTN,""' not found <<<"",! Q"
-,25,467," S TXT="""",LAB=$P(^UTILITY($J,1,RTN,0,1,0),"" "") I RTN'=$P(LAB,""("") D E^XINDX1(17)"
-,26,467," I 'INDLC,LAB[""("" D E^XINDX1(55) S LAB=$P(LAB,""("")"
-,27,0," ;if M routine(not compiled template or DD) and has more than 2 lines, check lines 1 & 2"
-,28,467," I 'INDLC,LC>2 D"
-,29,467," . N LABO S LABO=1"
-,30,467," . S LIN=$G(^UTILITY($J,1,RTN,0,1,0)),TXT=1"
-,31,0," . ;check 1st line (site/dev - ) patch 128"
-,32,467," . I $P(LIN,"";"",2,4)'?.E1""/"".E.1""-"".E D E^XINDX1(62)"
-,33,467," . S LIN=$G(^UTILITY($J,1,RTN,0,2,0)),TXT=2"
-,34,0," . ;check 2nd line (;;nn.nn[TV]nn;package;.anything)"
-,35,467," . I $P(LIN,"";"",3,99)'?1.2N1"".""1.2N.1(1""T"",1""V"").2N1"";""1A.AP1"";"".E D E^XINDX1(44) ;patch 121"
-,36,467," . I $L(INP(11)) X INP(11) ;Version number check"
-,37,467," . I $L(INP(12)) X INP(12) ;Patch number check"
-,38,467,"B5 F TXT=1:1:LC S LIN=^UTILITY($J,1,RTN,0,TXT,0),LN=$L(LIN),IND(""SZT"")=IND(""SZT"")+LN+2 D LN,ST ;Process Line"
-,39,467," S LAB="""",LABO=0,TXT=0,^UTILITY($J,1,RTN,0)=IND(""SZT"")_""^""_LC_""^""_IND(""SZC"")"
-,40,467," I IND(""SZT"")>INP(""MAX""),'INDLC S ERR=35,ERR(1)=IND(""SZT"") D ^XINDX1"
-,41,467," I IND(""SZT"")-IND(""SZC"")>INP(""CMAX""),'INDLC S ERR=58,ERR(1)=IND(""SZT"")-IND(""SZC"") D ^XINDX1"
-,42,467," D POSTRTN"
-,43,467," Q"
-,44,0," ;Proccess one line, LN = Length, LIN = Line."
-,45,44620,"LN K V S (ARG,GRB,IND(""COM""),IND(""DOL""),IND(""F""))="""",X=$P(LIN,"" "")"
-,46,44620," I '$L(X) S LABO=LABO+1 G CD"
-,47,5073," S (IND(""COM""),LAB)=$P(X,""(""),ARG=$P($P(X,""("",2),"")""),LABO=0,IND(""PP"")=X?1.8E1""("".E1"")"""
-,48,5073," D:$L(ARG) NE^XINDX3 ;Process formal parameters as New list."
-,49,5073," I 'INDLC,'$$VT^XINDX2(LAB) D E^XINDX1($S(LAB=$$CASE^XINDX52(LAB):37,1:55)) ;Check for bad labels"
-,50,5073," I $D(^UTILITY($J,1,RTN,""T"",LAB)) D E^XINDX1(15) G CD ;DUP label"
-,51,5073," S ^UTILITY($J,1,RTN,""T"",LAB)="""""
-,52,44620,"CD I LN>245 D:'(LN=246&($E(RTN,1,3)=""|dd"")) E^XINDX1(19) ;patch 119"
-,53,44620," D:LIN'?1.ANP E^XINDX1(18)"
-,54,44620," S LIN=$P(LIN,"" "",2,999),IND(""LCC"")=1"
-,55,44620," I LIN="""" D E^XINDX1(42) Q ;Blank line ;p110"
-,56,44620," S I=0 ;Watch the scope of I, counts dots"
-,57,44620," I "" .""[$E(LIN) D S X=$L($E(LIN,1,I),""."")-1,LIN=$E(LIN,I,999)"
-,58,10770," . F I=1:1:245 Q:"". ""'[$E(LIN,I)"
-,59,10770," . Q"
-,60,0," ;check dots against Do level IND(""DO""), IND(""DOL"")=dot level"
-,61,44620," D:'I&$G(IND(""DO1"")) E^XINDX1(51) S IND(""DO1"")=0 S:'I IND(""DO"")=0"
-,62,44620," I I D:X>IND(""DO"") E^XINDX1(51) S (IND(""DO""),IND(""DOL""))=X"
-,63,0," ;Count Comment lines, skip ;; lines"
-,64,44620," I $E(LIN)="";"",$E(LIN,2)'="";"" S IND(""SZC"")=IND(""SZC"")+$L(LIN) ;p110"
-,65,0," ;Process commands on line."
-,66,116081,"EE I LIN="""" D ^XINDX2 Q"
-,67,71461," S COM=$E(LIN),GK="""",ARG="""""
-,68,71461," I COM="";"" S LIN="""" G EE ;p110"
-,69,54870," I COM="" "" S ERR=$S(LIN?1."" "":13,1:0),LIN=$S(ERR:"""",1:$E(LIN,2,999)) D:ERR ^XINDX1 G EE"
-,70,53608," D SEP"
-,71,53608," S CM=$P(ARG,"":"",1),POST=$P(ARG,"":"",2,999),IND(""COM"")=IND(""COM"")_$C(9)_COM,ERR=48"
-,72,53608," D:ARG["":""&(POST']"""") ^XINDX1 S:POST]"""" GRB=GRB_$C(9)_POST,IND(""COM"")=IND(""COM"")_"":"""
-,73,0," ;SAC now allows lowercase commands"
-,74,53608," I CM?.E1L.E S CM=$$CASE^XINDX52(CM),COM=$E(CM) ;I IND(""LCC"") S IND(""LCC"")=0 D E^XINDX1(47)"
-,75,53608," I CM="""" D E^XINDX1(21) G EE ;Missing command"
-,76,53608," S CX=$G(IND(""CMD"",CM)) I CX="""" D G:CX="""" EE"
-,77,0," . I $E(CM)=""Z"" S CX=""^Z"" Q ;Proccess Z commands"
-,78,0," . D E^XINDX1(1) S LIN="""" Q"
-,79,53608," S CX=$P(CX,""^"",2,9)"
-,80,53608," D SEP I '$L(LIN),CH="" "" D E^XINDX1(13) ;trailing space"
-,81,53608," I ARG="""",""CGJMORSUWX""[COM S ERR=49 G ^XINDX1"
-,82,53608," I CX>0 D E^XINDX1(CX) S CX="""""
-,83,53608," D:$L(CX) @CX S:ARG'="""" GRB=GRB_$C(9)_ARG G EE"
-,84,0,"B S ERR=25 G ^XINDX1"
-,85,0,"C S ERR=29 G ^XINDX1"
-,86,0,"D G DG1^XINDX4"
-,87,0,"E Q:ARG="""" S ERR=7 G ^XINDX1"
-,88,1559,"F G:ARG]"""" FR^XINDX4 S IND(""F"")=1 Q"
-,89,1932,"G G DG^XINDX4"
-,90,11,"H Q:ARG'="""" S ERR=32 G ^XINDX1"
-,91,0,"J S ERR=36,ARG="""" G ^XINDX1"
-,92,2218,"K S ERR=$S(ARG?1""("".E:22,ARG?."" "":23,1:0) D:ERR ^XINDX1"
-,93,2218," G KL^XINDX3"
-,94,259,"L G LO^XINDX4"
-,95,30,"M G S^XINDX3"
-,96,1721,"N G NE^XINDX3"
-,97,0,"O S ERR=34 D ^XINDX1,O^XINDX3 Q"
-,98,7762,"Q Q:ARG="""" G Q^XINDX4"
-,99,85,"R S RDTIME=0 G RD^XINDX3"
-,100,17549,"S G S^XINDX3"
-,101,0,"TR Q ;What to process. p110"
-,102,72,"U S ARG=$P(ARG,"":"") Q"
-,103,0,"V S ARG="""",ERR=20 G ^XINDX1"
-,104,4584,"W G WR^XINDX4"
-,105,220,"X G XE^XINDX4"
-,106,0,"Z S ERR=2 D ^XINDX1 G ZC^XINDX4"
-,107,0," ;"
-,108,0," ;Save off items from line."
-,109,44620,"ST S R=LAB_$S(LABO:""+""_LABO,1:"""")"
-,110,0," ;Local variable, Global, Marked Items, Naked global, Internal ref, eXternal ref., Tag ref."
-,111,44620," S LOC="""" F S LOC=$O(V(LOC)),S="""" Q:LOC="""" F S S=$O(V(LOC,S)) Q:S="""" D SET"
-,112,44620," S ^UTILITY($J,1,RTN,""COM"",TXT)=IND(""COM"")"
-,113,44620," Q"
-,114,0," ;"
-,115,85079,"SET I V(LOC,S)]"""" F %=""!"",""~"" I V(LOC,S)[%,$G(^UTILITY($J,1,RTN,LOC,S))'[% S ^(S)=$G(^(S))_%"
-,116,85079," S %=0"
-,117,86891,"SE2 S ARG=$G(^UTILITY($J,1,RTN,LOC,S,%)) I $L(ARG)>230 S %=%+1 G SE2"
-,118,85079," S ^UTILITY($J,1,RTN,LOC,S,%)=ARG_R_V(LOC,S)_"","""
-,119,85079," Q"
-,120,0," ;"
-,121,0,"POSTRTN ;Do more overall checking"
-,122,467," N V,E,T,T1,T2"
-,123,467," S T="""" ;Check for missing Labels"
-,124,467," F S T=$O(^UTILITY($J,1,RTN,""I"",T)),T2=T Q:T="""" S T1=$G(^(T,0)) D"
-,125,2091," . Q:$E(T2,1,2)=""@("""
-,126,2044," . S:$E(T2,1,2)=""$$"" T2=$E(T2,3,99)"
-,127,2044," . I T2]"""",'$D(^UTILITY($J,1,RTN,""T"",$P(T2,""+"",1))) D"
-,128,0," . . F I=1:1:$L(T1,"","")-1 S LAB=$P(T1,"","",I),LABO=+$P(LAB,""+"",2),LAB=$P(LAB,""+""),E=14,E(1)=T D E^XINDX1(.E)"
-,129,0," . . Q"
-,130,2044," . Q"
-,131,467," S LAB="""",LABO=0 ;Check for valid label names"
-,132,467," I 'INDLC F S LAB=$O(^UTILITY($J,1,RTN,""T"",LAB)) Q:LAB="""" D"
-,133,5073," . I '$$VA^XINDX2(LAB) D E^XINDX1(55) Q"
-,134,5073," . D:'$$VT^XINDX2(LAB) E^XINDX1(37)"
-,135,5073," . Q"
-,136,467," S LAB="""",LABO=0 ;Check for valid variable names."
-,137,467," F S LAB=$O(^UTILITY($J,1,RTN,""L"",LAB)) Q:LAB="""" D"
-,138,15909," . D VLNF^XINDX3($P(LAB,""(""))"
-,139,15909," . Q"
-,140,467," Q"
-,141,0," ;"
-,142,0,"QUICK ;Quick, Just get a routine an print the results"
-,143,0," D QUICK^XINDX6()"
-,144,0," Q"
-Totals for XINDEX,,2446443,
-XINDX1,1,0,"XINDX1 ;ISC/REL,GRK,RWF - ERROR ROUTINE ;08/05/08 13:59"
-,2,2," ;;7.3;TOOLKIT;**20,61,66,68,110,121,128**;Apr 25, 1995;Build 1"
-,3,0," ; Per VHA Directive 2004-038, this routine should not be modified."
-,4,2," G A"
-,5,0,"E(ERR) ;"
-,6,75,"A N %,%1 ;TXT is the line of the error."
-,7,75," S ERTX=LAB_$S(LABO:""+""_LABO,1:"""")_$C(9),%1=$T(ERROR+ERR),ERTX=ERTX_$S(ERR:$P(%1,"";"",4,9),1:ERR) ;p110"
-,8,75," I ERTX[""|"" F %=1:1 S ERTX=$P(ERTX,""|"")_$S($D(ERR(%)):ERR(%),1:""??"")_$P(ERTX,""|"",%+1,99) Q:ERTX'[""|"""
-,9,75,"B I $P(%1,"";"",3)]"""" D Q:%1]"""" ;Don't flag kernel doing kernel."
-,10,0," . S %1=$P(%1,"";"",3)"
-,11,0," . F Q:RTN[$P(%1,"","") S %1=$P(%1,"","",2,99) ;quit if RTN[%1 or null."
-,12,0," . Q"
-,13,75," I ERR=17,$E(RTN)'=""%"",$E(LAB)=""%"" Q ;Don't flag %RTN w/o %."
-,14,0," ;Global is Error Line,tab,error tag,tab,error text"
-,15,75," S %=$G(^UTILITY($J,1,RTN,""E"",0))+1,^(0)=%,^(%)=TXT_$C(9)_ERTX"
-,16,75," Q"
-,17,0," ;"
-,18,0," ;F = Fatal, S = Standard, W = Warning, I = Info"
-,19,0,"ERROR ;"
-,20,0,"1 ;;;F - UNDEFINED COMMAND (rest of line not checked)."
-,21,0,"2 ;;;F - Non-standard (Undefined) 'Z' command."
-,22,0,"3 ;;XTRMON;F - Undefined Function."
-,23,0,"4 ;;;F - Undefined Special Variable."
-,24,0,"5 ;;;F - Unmatched Parenthesis."
-,25,0,"6 ;;;F - Unmatched Quotation Marks."
-,26,0,"7 ;;;F - ELSE Command followed by only one space."
-,27,0,"8 ;;;F - FOR Command did not contain '='."
-,28,0,"9 ;;;I - QUIT Command followed by only one space."
-,29,0,"10 ;;;F - Unrecognized argument in SET command."
-,30,0,"11 ;;;W - Invalid local variable name."
-,31,0,"12 ;;;W - Invalid global variable name."
-,32,0,"13 ;;;W - Blank(s) at end of line."
-,33,0,"14 ;;;F - Call to missing label '|' in this routine."
-,34,0,"15 ;;;W - Duplicate label. (M57)"
-,35,0,"16 ;;;F - Error in pattern code."
-,36,0,"17 ;;;W - First line label NOT routine name."
-,37,0,"18 ;;;W - Line contains a CONTROL (non-graphic) character."
-,38,0,"19 ;;;S - Line is longer than 245 bytes."
-,39,0,"20 ;;;S - View command used."
-,40,0,"21 ;;;F - General Syntax Error."
-,41,0,"22 ;;;S - Exclusive Kill."
-,42,0,"23 ;;;S - Unargumented Kill."
-,43,0,"24 ;;;S - Kill of an unsubscripted global."
-,44,0,"25 ;;;S - Break command used."
-,45,0,"26 ;;;S - Exclusive or Unargumented NEW command."
-,46,0,"27 ;;;S - $View function used."
-,47,0,"28 ;;ZOSV,ZIS,ZT;S - Non-standard $Z special variable used."
-,48,0,"29 ;;ZIS,ZTM;S - 'Close' command should be invoked through 'D ^%ZISC'."
-,49,0,"30 ;;;S - LABEL+OFFSET syntax."
-,50,0,"31 ;;ZOSV,ZIS,ZT;S - Non-standard $Z function used."
-,51,0,"32 ;;;S - 'HALT' command should be invoked through 'G ^XUSCLEAN'."
-,52,0,"33 ;;;S - Read command doesn't have a timeout."
-,53,0,"34 ;;ZIS;S - 'OPEN' command should be invoked through ^%ZIS."
-,54,0,"35 ;;;S - Routine exceeds SACC maximum size of 20000 (|)."
-,55,0,"36 ;;ZTM;S - Should use 'TASKMAN' instead of 'JOB' command."
-,56,0,"37 ;;;F - Label is not valid."
-,57,0,"38 ;;;F - Call to this |"
-,58,0,"39 ;;ZIS,XUS,XUP;S - Kill of a protected variable (|)."
-,59,0,"40 ;;;S - Space where a command should be."
-,60,0,"41 ;;;I - Star or pound READ used."
-,61,0,"42 ;;;W - Null line (no commands or comment)."
-,62,0,"43 ;;;F - Invalid or wrong number of arguments to a function."
-,63,0,"44 ;;;S - 2nd line of routine violates the SAC."
-,64,0,"45 ;;ZT,ZIS,XUTM,XTER;S - Set to a '%' global."
-,65,0,"46 ;;;F - Quoted string not followed by a separator."
-,66,0,"47 ;;;S - Lowercase command(s) used in line."
-,67,0,"48 ;;;F - Missing argument to a command post-conditional."
-,68,0,"49 ;;;F - Command missing an argument."
-,69,0,"50 ;;ZTM;S - Extended reference."
-,70,0,"51 ;;;F - Block structure mismatch."
-,71,0,"52 ;;;F - Reference to routine '^|'. That isn't in this UCI."
-,72,0,"53 ;;;F - Bad Number."
-,73,0,"54 ;;XG;S - Access to SSVN's restricted to Kernel."
-,74,0,"55 ;;;S - Violates VA programming standards."
-,75,0,"56 ;;;S - Patch number '|' missing from second line."
-,76,0,"57 ;;;S - Lower/Mixed case Variable name used."
-,77,0,"58 ;;;S - Routine code exceeds SACC maximum size of 15000 (|)."
-,78,0,"59 ;;;F - Bad WRITE syntax."
-,79,0,"60 ;;;S - Lock missing Timeout."
-,80,0,"61 ;;;S - Non-Incremental Lock."
-,81,0,"62 ;;;S - First line of routine violates the SAC."
-,82,0,"63 ;;;F - GO or DO mismatch from block structure (M45)."
-Totals for XINDX1,,529,
diff --git a/Tests/MumpsCoverage/Accounts_ReceivableTest.mcov b/Tests/MumpsCoverage/Accounts_ReceivableTest.mcov
deleted file mode 100644
index 3c585f556..000000000
--- a/Tests/MumpsCoverage/Accounts_ReceivableTest.mcov
+++ /dev/null
@@ -1,1445 +0,0 @@
-%GO Global Output Utility
-GT.M 17-APR-2012 17:18:27 ZWR
-^ZZCOVERAGE("%RSEL","SRC")="1:0:0:0"
-^ZZCOVERAGE("%RSEL","SRC",1)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","SRC",2)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","SRC",3)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","SRC",4)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","SRC",5)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","SRC",6)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","SRC",7)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","init")="1:0:0:0"
-^ZZCOVERAGE("%RSEL","init",1)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","init",3)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","init",4)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","init",5)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","init",6)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","init",7)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","init",8)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","init",8,"FOR_LOOP",1)=1
-^ZZCOVERAGE("%RSEL","init",9)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","init",10)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","init",11)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","init",12)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","init",13)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","init",14)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","init",15)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","init",16)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","init",17)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","init",17,"FOR_LOOP",1)=2
-^ZZCOVERAGE("%RSEL","init",18)="2:0:0:0"
-^ZZCOVERAGE("%RSEL","init",19)="2:0:0:0"
-^ZZCOVERAGE("%RSEL","init",20)="2:0:0:0"
-^ZZCOVERAGE("%RSEL","init",40)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","main")="1:32001:84004:116005"
-^ZZCOVERAGE("%RSEL","main",1)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","main",2)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","main",3)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","main",3,"FOR_LOOP",1)=468
-^ZZCOVERAGE("%RSEL","main",4)="468:0:24003:24003"
-^ZZCOVERAGE("%RSEL","main",5)="468:0:0:0"
-^ZZCOVERAGE("%RSEL","main",6)="468:32001:48001:80002"
-^ZZCOVERAGE("%RSEL","main",7)="467:0:12000:12000"
-^ZZCOVERAGE("%RSEL","main",8)="467:0:0:0"
-^ZZCOVERAGE("%RSEL","main",9)="467:0:0:0"
-^ZZCOVERAGE("%RSEL","main",10)="467:0:0:0"
-^ZZCOVERAGE("%RSEL","main",11)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","main",12)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","main",13)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","main",14)="1:0:0:0"
-^ZZCOVERAGE("%RSEL","next")="1403:12001:20002:32003"
-^ZZCOVERAGE("%RSEL","next",0)="1403:0:0:0"
-^ZZCOVERAGE("%RSEL","next",1)="1403:12001:20002:32003"
-^ZZCOVERAGE("%RSEL","next",1,"FOR_LOOP",1)=1403
-^ZZCOVERAGE("%RSEL","next",2)="1403:0:0:0"
-^ZZCOVERAGE("%RSEL","save")="467:0:4001:4001"
-^ZZCOVERAGE("%RSEL","save",1)="467:0:0:0"
-^ZZCOVERAGE("%RSEL","save",5)="467:0:0:0"
-^ZZCOVERAGE("%RSEL","save",6)="467:0:0:0"
-^ZZCOVERAGE("%RSEL","save",7)="467:0:0:0"
-^ZZCOVERAGE("%RSEL","save",8)="467:0:4001:4001"
-^ZZCOVERAGE("%RSEL","save",9)="467:0:0:0"
-^ZZCOVERAGE("%RSEL","search")="934:0:16001:16001"
-^ZZCOVERAGE("%RSEL","search",0)="934:0:4000:4000"
-^ZZCOVERAGE("%RSEL","search",1)="934:0:0:0"
-^ZZCOVERAGE("%RSEL","search",2)="934:0:4001:4001"
-^ZZCOVERAGE("%RSEL","search",2,"FOR_LOOP",1)=1868
-^ZZCOVERAGE("%RSEL","search",3)="934:0:8000:8000"
-^ZZCOVERAGE("%RSEL","search",4)="934:0:0:0"
-^ZZCOVERAGE("%RSEL","search",5)="934:0:0:0"
-^ZZCOVERAGE("%RSEL","start")="468:0:4001:4001"
-^ZZCOVERAGE("%RSEL","start",0)="468:0:0:0"
-^ZZCOVERAGE("%RSEL","start",1)="468:0:0:0"
-^ZZCOVERAGE("%RSEL","start",2)="468:0:0:0"
-^ZZCOVERAGE("%RSEL","start",2,"FOR_LOOP",1)=936
-^ZZCOVERAGE("%RSEL","start",3)="468:0:0:0"
-^ZZCOVERAGE("%RSEL","work")="467:20002:24001:44003"
-^ZZCOVERAGE("%RSEL","work",1)="467:0:0:0"
-^ZZCOVERAGE("%RSEL","work",2)="467:0:0:0"
-^ZZCOVERAGE("%RSEL","work",3)="467:0:4000:4000"
-^ZZCOVERAGE("%RSEL","work",4)="467:0:0:0"
-^ZZCOVERAGE("%RSEL","work",6)="467:4000:12000:16000"
-^ZZCOVERAGE("%RSEL","work",6,"FOR_LOOP",1)=3421
-^ZZCOVERAGE("%RSEL","work",7)="467:0:0:0"
-^ZZCOVERAGE("%RSEL","work",8)="467:4001:0:4001"
-^ZZCOVERAGE("%RSEL","work",9)="467:0:0:0"
-^ZZCOVERAGE("%RSEL","work",10)="467:0:0:0"
-^ZZCOVERAGE("%RSEL","work",11)="467:0:0:0"
-^ZZCOVERAGE("%RSEL","work",12)="467:4000:0:4000"
-^ZZCOVERAGE("%RSEL","work",13)="467:0:4000:4000"
-^ZZCOVERAGE("%RSEL","work",14)="467:0:0:0"
-^ZZCOVERAGE("%RSEL","work",15)="467:4001:4001:8002"
-^ZZCOVERAGE("%RSEL","work",15,"FOR_LOOP",1)=934
-^ZZCOVERAGE("%RSEL","work",16)="467:0:0:0"
-^ZZCOVERAGE("%ZIS","%ZIS")="2:0:0:0"
-^ZZCOVERAGE("%ZIS","%ZIS",3)="2:0:0:0"
-^ZZCOVERAGE("%ZIS","%ZIS",4)="2:0:0:0"
-^ZZCOVERAGE("%ZIS","A",0)="2:0:0:0"
-^ZZCOVERAGE("%ZIS","A",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS","CLEAN")="3:0:0:0"
-^ZZCOVERAGE("%ZIS","CLEAN",1)="3:0:0:0"
-^ZZCOVERAGE("%ZIS","CLEAN",2)="3:0:0:0"
-^ZZCOVERAGE("%ZIS","CLEAN",3)="3:0:0:0"
-^ZZCOVERAGE("%ZIS","CLEAN",4)="3:0:0:0"
-^ZZCOVERAGE("%ZIS","GETHOME")="2:0:0:0"
-^ZZCOVERAGE("%ZIS","GETHOME",0)="2:0:0:0"
-^ZZCOVERAGE("%ZIS","GETHOME",1)="1:0:0:0"
-^ZZCOVERAGE("%ZIS","GETHOME",3)="1:0:0:0"
-^ZZCOVERAGE("%ZIS","GETHOME",4)="1:0:0:0"
-^ZZCOVERAGE("%ZIS","GETHOME",5)="1:0:0:0"
-^ZZCOVERAGE("%ZIS","GETHOME",6)="1:0:0:0"
-^ZZCOVERAGE("%ZIS","GETHOME",7)="1:0:0:0"
-^ZZCOVERAGE("%ZIS","HOME")="1:0:0:0"
-^ZZCOVERAGE("%ZIS","HOME",1)="1:0:0:0"
-^ZZCOVERAGE("%ZIS","HOME",2)="1:0:0:0"
-^ZZCOVERAGE("%ZIS","INIT",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS","INIT",3)="2:0:0:0"
-^ZZCOVERAGE("%ZIS","INIT",4)="2:0:0:0"
-^ZZCOVERAGE("%ZIS","INIT",5)="2:0:0:0"
-^ZZCOVERAGE("%ZIS","INIT",6)="2:0:0:0"
-^ZZCOVERAGE("%ZIS","INIT",8)="2:0:0:0"
-^ZZCOVERAGE("%ZIS","INIT",10)="2:0:0:0"
-^ZZCOVERAGE("%ZIS","INIT",11)="2:0:0:0"
-^ZZCOVERAGE("%ZIS","INIT",12)="2:0:0:0"
-^ZZCOVERAGE("%ZIS","INIT",13)="2:0:0:0"
-^ZZCOVERAGE("%ZIS","INIT",15)="2:0:0:0"
-^ZZCOVERAGE("%ZIS","K2",0)="2:0:0:0"
-^ZZCOVERAGE("%ZIS","K2",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS","K2",2)="2:0:0:0"
-^ZZCOVERAGE("%ZIS","K2",4)="2:0:0:0"
-^ZZCOVERAGE("%ZIS","VIRTUAL")="2:0:0:0"
-^ZZCOVERAGE("%ZIS","VIRTUAL",4)="2:0:0:0"
-^ZZCOVERAGE("%ZIS","VIRTUAL",4,"FOR_LOOP",1)=6
-^ZZCOVERAGE("%ZIS","VIRTUAL",5)="2:0:0:0"
-^ZZCOVERAGE("%ZIS","VIRTUAL",7)="2:0:0:0"
-^ZZCOVERAGE("%ZIS","VTLKUP")="4:0:0:0"
-^ZZCOVERAGE("%ZIS","VTLKUP",0)="4:0:0:0"
-^ZZCOVERAGE("%ZIS","VTLKUP",0,"FOR_LOOP",1)=8
-^ZZCOVERAGE("%ZIS","VTLKUP",1)="4:0:0:0"
-^ZZCOVERAGE("%ZIS1","EX2",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","EX2",2)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","EXIT",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","EXIT",3)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","EXIT",5)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","EXIT",6)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","EXIT",7)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","EXIT",8)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","EXIT",9)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","G",0)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","IOP")="1:0:0:0"
-^ZZCOVERAGE("%ZIS1","IOP",1)="1:0:0:0"
-^ZZCOVERAGE("%ZIS1","K2")="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","K2",1)="4:0:0:0"
-^ZZCOVERAGE("%ZIS1","K2",2)="4:0:0:0"
-^ZZCOVERAGE("%ZIS1","K2",3)="4:0:0:0"
-^ZZCOVERAGE("%ZIS1","K2",4)="4:0:0:0"
-^ZZCOVERAGE("%ZIS1","KIL",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","KIL",2)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","KIL",3)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","L1",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","L1",2)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","L1",3)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","L1",4)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","L1",5)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","L1",6)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","L1",7)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","L1",8)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","L1",9)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","L1",10)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","L1",11)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","L1",12)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","LKUP")="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","LKUP",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","LKUP",2)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","LKUP",3)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","MAIN",2)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","R")="1:0:0:0"
-^ZZCOVERAGE("%ZIS1","R",0)="1:0:0:0"
-^ZZCOVERAGE("%ZIS1","R",1)="1:0:0:0"
-^ZZCOVERAGE("%ZIS1","R",2)="1:0:0:0"
-^ZZCOVERAGE("%ZIS1","RD",0)="1:0:0:0"
-^ZZCOVERAGE("%ZIS1","RD",1)="1:0:0:0"
-^ZZCOVERAGE("%ZIS1","RD",2)="1:0:0:0"
-^ZZCOVERAGE("%ZIS1","RD",3)="1:0:0:0"
-^ZZCOVERAGE("%ZIS1","RD",4)="1:0:0:0"
-^ZZCOVERAGE("%ZIS1","RD",5)="1:0:0:0"
-^ZZCOVERAGE("%ZIS1","SBR")="1:0:0:0"
-^ZZCOVERAGE("%ZIS1","SBR",1)="1:0:0:0"
-^ZZCOVERAGE("%ZIS1","SBR",2)="1:0:0:0"
-^ZZCOVERAGE("%ZIS1","SBR",3)="1:0:0:0"
-^ZZCOVERAGE("%ZIS1","SETQ")="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","SETQ",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","SETQ",2)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","SETQ",3)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","SETQ",4)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","SETQ",5)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","SETVAR",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","SETVAR",2)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","SETVAR",5)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","SETVAR",7)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","SETVAR",8)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","SETVAR",9)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","SETVAR",10)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","SETVAR",11)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","SETVAR",12)="2:0:0:0"
-^ZZCOVERAGE("%ZIS1","SETVAR",13)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","CHECK",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","CHECK",2)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","CHECK",3)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","CHECK",4)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","CHECK",5)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","CHECK",6)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","IOPAR")="4:0:0:0"
-^ZZCOVERAGE("%ZIS2","IOPAR",0)="4:0:0:0"
-^ZZCOVERAGE("%ZIS2","IOPAR",1)="4:0:0:0"
-^ZZCOVERAGE("%ZIS2","L2")="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","L2",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","OCPU",0)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","OOS",0)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","OOS",2)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","OTHCPU")="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","OTHCPU",0)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","OTHCPU",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","OTHCPU",2)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","OTHCPU",2,"FOR_LOOP",1)=4
-^ZZCOVERAGE("%ZIS2","OTHCPU",3)="4:0:0:0"
-^ZZCOVERAGE("%ZIS2","OTHCPU",4)="4:0:0:0"
-^ZZCOVERAGE("%ZIS2","OTHCPU",5)="4:0:0:0"
-^ZZCOVERAGE("%ZIS2","OTHCPU",15)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","PTIME",0)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","QUECHK")="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","QUECHK",0)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","QUECHK",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","QUECHK",3)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","QUECHK",4)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","QUECHK",9)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","QUECHK",13)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","SLAVE",0)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","T2",0)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","T2",2)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","TMPVAR",0)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","TMPVAR",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","TMPVAR",2)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","TMPVAR",4)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","TMPVAR",10)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","TMPVAR",11)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","TMPVAR",12)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","TMPVAR",15)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","TMPVAR",16)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","TMPVAR",18)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","VTRM",0)="2:0:0:0"
-^ZZCOVERAGE("%ZIS2","VTRM",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","%ZIS3",4)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","%ZIS3",5)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","%ZIS3",6)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","%ZIS3",8)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","%ZIS3",9)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","%ZIS3",11)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","ALTP",0)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","ASKMAR",0)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","ASKMAR",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","MARGN")="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","MARGN",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","MARGN",2)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","MARGN",3)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","MARGN",4)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","Q",2)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","Q",3)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","Q",4)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","SETPAR")="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","SETPAR",0)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","SETPAR",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","ST")="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","ST",0)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","ST",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","ST",2)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","ST",3)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","STP",0)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","STP",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","STP",2)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","STP",3)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","TRM",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","TRM",2)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","TRM",3)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","TRM",4)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","TRM",5)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","W")="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","W",0)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","W",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS3","W",2)="1:0:0:0"
-^ZZCOVERAGE("%ZIS3","W",3)="1:0:0:0"
-^ZZCOVERAGE("%ZIS4","O")="2:0:0:0"
-^ZZCOVERAGE("%ZIS4","O",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS4","O",2)="2:0:0:0"
-^ZZCOVERAGE("%ZIS4","O1")="2:0:0:0"
-^ZZCOVERAGE("%ZIS4","O1",0)="2:0:0:0"
-^ZZCOVERAGE("%ZIS4","O1",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS4","O1",2)="2:0:0:0"
-^ZZCOVERAGE("%ZIS4","O1",3)="2:0:0:0"
-^ZZCOVERAGE("%ZIS4","OPAR",0)="2:0:0:0"
-^ZZCOVERAGE("%ZIS4","OPAR",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS4","OPAR",2)="2:0:0:0"
-^ZZCOVERAGE("%ZIS4","OPAR",3)="2:0:0:0"
-^ZZCOVERAGE("%ZIS4","OPAR",4)="2:0:0:0"
-^ZZCOVERAGE("%ZIS4","OPAR",5)="2:0:0:0"
-^ZZCOVERAGE("%ZIS4","OPAR",9)="2:0:0:0"
-^ZZCOVERAGE("%ZIS4","OPAR",10)="2:0:0:0"
-^ZZCOVERAGE("%ZIS4","OPAR",12)="2:0:0:0"
-^ZZCOVERAGE("%ZIS6","ANSBAK",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS6","ANSBAK",2)="2:0:0:0"
-^ZZCOVERAGE("%ZIS6","ANSBAK",3)="2:0:0:0"
-^ZZCOVERAGE("%ZIS6","OXECUTE",1)="2:0:0:0"
-^ZZCOVERAGE("%ZIS6","QUIT",0)="2:0:0:0"
-^ZZCOVERAGE("%ZIS6","QUIT",1)="2:0:0:0"
-^ZZCOVERAGE("%ZISC","C0")="1:0:0:0"
-^ZZCOVERAGE("%ZISC","C0",1)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","C0",3)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","C0",5)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","C0",6)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","C0",8)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","C0",9)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","C0",10)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","C0",13)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","C0",16)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","C0",17)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","C0",21)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","C0",26)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","C0",27)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","C0",29)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","C0",32)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","C0",33)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","C0",34)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","C0",37)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","C0",41)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","C0",43)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","CIOS")="1:0:0:0"
-^ZZCOVERAGE("%ZISC","CIOS",0)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","CIOS",1)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","CIOS",2)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","CIOS",3)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","CIOS",4)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","CIOS",5)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","CIOS",6)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","CIOS",7)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","CIOS",8)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","CLOSPP")="1:0:0:0"
-^ZZCOVERAGE("%ZISC","CLOSPP",0)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","CLOSPP",1)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","CLOSPP",2)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","END",0)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","END",2)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","END",4)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","FF")="1:0:0:0"
-^ZZCOVERAGE("%ZISC","FF",0)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","FF",1)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","FF",2)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","RM")="1:0:0:0"
-^ZZCOVERAGE("%ZISC","RM",0)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","RM",1)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","S1",0)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","S1",1)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","SETIO",2)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","SETIO",4)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","SETIO",5)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","SETIO",6)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","SETIO",7)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","SETIO",8)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","SETIO",9)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","SETIO",10)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","SETIO",12)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","SUBTYPE")="1:0:0:0"
-^ZZCOVERAGE("%ZISC","SUBTYPE",1)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","SUBTYPE",2)="1:0:0:0"
-^ZZCOVERAGE("%ZISC","SUBTYPE",3)="1:0:0:0"
-^ZZCOVERAGE("%ZISUTL","LINEPORT")="1:0:0:0"
-^ZZCOVERAGE("%ZISUTL","LINEPORT",0)="1:0:0:0"
-^ZZCOVERAGE("%ZISUTL","LINEPORT",2)="1:0:0:0"
-^ZZCOVERAGE("%ZISUTL","LINEPORT",3)="1:0:0:0"
-^ZZCOVERAGE("%ZISUTL","LINEPORT",4)="1:0:0:0"
-^ZZCOVERAGE("%ZISUTL","LINEPORT",5)="1:0:0:0"
-^ZZCOVERAGE("%ZISUTL","LINEPORT",6)="1:0:0:0"
-^ZZCOVERAGE("%ZISUTL","LNPRTIEN")="3:0:0:0"
-^ZZCOVERAGE("%ZISUTL","LNPRTIEN",0)="3:0:0:0"
-^ZZCOVERAGE("%ZISUTL","LNPRTIEN",1)="3:0:0:0"
-^ZZCOVERAGE("%ZISUTL","LNPRTNAM")="3:0:0:0"
-^ZZCOVERAGE("%ZISUTL","LNPRTNAM",0)="3:0:0:0"
-^ZZCOVERAGE("%ZISUTL","LNPRTNAM",1)="3:0:0:0"
-^ZZCOVERAGE("%ZISUTL","LNPRTNAM",2)="3:0:0:0"
-^ZZCOVERAGE("%ZISUTL","LNPRTNAM",3)="3:0:0:0"
-^ZZCOVERAGE("%ZISUTL","LNPRTNAM",5)="3:0:0:0"
-^ZZCOVERAGE("%ZISUTL","LNPRTNAM",6)="3:0:0:0"
-^ZZCOVERAGE("%ZISUTL","LNPRTSUB")="2:0:0:0"
-^ZZCOVERAGE("%ZISUTL","LNPRTSUB",0)="2:0:0:0"
-^ZZCOVERAGE("%ZISUTL","LNPRTSUB",1)="2:0:0:0"
-^ZZCOVERAGE("%ZISUTL","LNPRTSUB",2)="2:0:0:0"
-^ZZCOVERAGE("%ZISUTL","LNPRTSUB",3)="2:0:0:0"
-^ZZCOVERAGE("%ZISUTL","SYMBOL")="2:0:0:0"
-^ZZCOVERAGE("%ZISUTL","SYMBOL",0)="2:0:0:0"
-^ZZCOVERAGE("%ZISUTL","SYMBOL",1)="2:0:0:0"
-^ZZCOVERAGE("%ZISUTL","SYMBOL",3)="2:0:0:0"
-^ZZCOVERAGE("%ZISUTL","SYMBOL",4)="2:0:0:0"
-^ZZCOVERAGE("%ZISUTL","SYMBOL",5)="2:0:0:0"
-^ZZCOVERAGE("%ZISUTL","SYMBOL",5,"FOR_LOOP",1)=40
-^ZZCOVERAGE("%ZISUTL","SYMBOL",6)="40:0:0:0"
-^ZZCOVERAGE("%ZISUTL","SYMBOL",10)="2:0:0:0"
-^ZZCOVERAGE("%ZOSV","GETENV")="2:0:0:0"
-^ZZCOVERAGE("%ZOSV","GETENV",1)="2:0:0:0"
-^ZZCOVERAGE("%ZOSV","GETENV",2)="2:0:0:0"
-^ZZCOVERAGE("%ZOSV","GETENV",3)="2:0:0:0"
-^ZZCOVERAGE("%ZOSV","LGR")="2:0:0:0"
-^ZZCOVERAGE("%ZOSV","LGR",0)="2:0:0:0"
-^ZZCOVERAGE("%ZOSV","LGR",1)="2:0:0:0"
-^ZZCOVERAGE("%ZOSV","PRI")="1:0:0:0"
-^ZZCOVERAGE("%ZOSV","PRI",0)="1:0:0:0"
-^ZZCOVERAGE("%ZOSV","PRI",3)="1:0:0:0"
-^ZZCOVERAGE("%ZOSV","RETURN")="2:0:4000:4000"
-^ZZCOVERAGE("%ZOSV","RETURN",0)="2:0:0:0"
-^ZZCOVERAGE("%ZOSV","RETURN",2)="2:0:0:0"
-^ZZCOVERAGE("%ZOSV","RETURN",3)="2:0:0:0"
-^ZZCOVERAGE("%ZOSV","RETURN",4)="2:0:4000:4000"
-^ZZCOVERAGE("%ZOSV","RETURN",5)="2:0:0:0"
-^ZZCOVERAGE("%ZOSV","RETURN",7)="2:0:0:0"
-^ZZCOVERAGE("%ZOSV","TEMP")="2:0:0:0"
-^ZZCOVERAGE("%ZOSV","TEMP",0)="2:0:0:0"
-^ZZCOVERAGE("%ZOSV","TEMP",2)="2:0:0:0"
-^ZZCOVERAGE("%ZOSV2","LOAD")="467:1000060:340019:1340079"
-^ZZCOVERAGE("%ZOSV2","LOAD",0)="467:0:0:0"
-^ZZCOVERAGE("%ZOSV2","LOAD",1)="467:0:8001:8001"
-^ZZCOVERAGE("%ZOSV2","LOAD",2)="467:1000060:320018:1320078"
-^ZZCOVERAGE("%ZOSV2","LOAD",2,"FOR_LOOP",1)=45087
-^ZZCOVERAGE("%ZOSV2","LOAD",3)="467:0:12000:12000"
-^ZZCOVERAGE("DIALOG","EZBLD")="2:0:4000:4000"
-^ZZCOVERAGE("DIALOG","EZBLD",0)="2:0:0:0"
-^ZZCOVERAGE("DIALOG","EZBLD",2)="2:0:0:0"
-^ZZCOVERAGE("DIALOG","EZBLD",3)="2:0:0:0"
-^ZZCOVERAGE("DIALOG","EZBLD",4)="2:0:0:0"
-^ZZCOVERAGE("DIALOG","EZBLD",5)="2:0:0:0"
-^ZZCOVERAGE("DIALOG","EZBLD",6)="2:0:0:0"
-^ZZCOVERAGE("DIALOG","EZBLD",7)="2:0:0:0"
-^ZZCOVERAGE("DIALOG","EZBLD",8)="2:0:0:0"
-^ZZCOVERAGE("DIALOG","EZBLD",9)="2:0:0:0"
-^ZZCOVERAGE("DIALOG","PARAM")="2:0:0:0"
-^ZZCOVERAGE("DIALOG","PARAM",0)="4:0:0:0"
-^ZZCOVERAGE("DIALOG","PARAM",1)="2:0:0:0"
-^ZZCOVERAGE("DIALOG","PARAM",2)="2:0:0:0"
-^ZZCOVERAGE("DIALOG","PARAM",3)="2:0:0:0"
-^ZZCOVERAGE("DIALOG","Q1",0)="2:0:0:0"
-^ZZCOVERAGE("DIALOG","Q2")="2:0:0:0"
-^ZZCOVERAGE("DIALOG","Q2",0)="2:0:0:0"
-^ZZCOVERAGE("DIALOG","QEZ",0)="2:0:4000:4000"
-^ZZCOVERAGE("DIALOG","QEZ",1)="2:0:0:0"
-^ZZCOVERAGE("DIALOG","QP",0)="2:0:0:0"
-^ZZCOVERAGE("DIC","A1",0)="2:0:0:0"
-^ZZCOVERAGE("DIC","ASK",0)="2:0:0:0"
-^ZZCOVERAGE("DIC","ASK",1)="2:0:0:0"
-^ZZCOVERAGE("DIC","ASK",2)="2:0:0:0"
-^ZZCOVERAGE("DIC","ASK",3)="2:0:0:0"
-^ZZCOVERAGE("DIC","ASK",4)="2:0:0:0"
-^ZZCOVERAGE("DIC","DIC")="2:0:0:0"
-^ZZCOVERAGE("DIC","DIC",3)="2:0:0:0"
-^ZZCOVERAGE("DIC","DIC",4)="2:0:0:0"
-^ZZCOVERAGE("DIC","DIC",5)="2:0:0:0"
-^ZZCOVERAGE("DIC","DIC",6)="2:0:0:0"
-^ZZCOVERAGE("DIC","EN",0)="2:0:0:0"
-^ZZCOVERAGE("DIC","EN",1)="2:0:0:0"
-^ZZCOVERAGE("DIC","EN",2)="2:0:0:0"
-^ZZCOVERAGE("DIC","EN",3)="2:0:0:0"
-^ZZCOVERAGE("DIC","EN",4)="2:0:0:0"
-^ZZCOVERAGE("DIC","EN",5)="2:0:0:0"
-^ZZCOVERAGE("DIC","EN",6)="2:0:0:0"
-^ZZCOVERAGE("DIC","EN",7)="2:0:0:0"
-^ZZCOVERAGE("DIC","EN",8)="2:0:0:0"
-^ZZCOVERAGE("DIC","EN",9)="2:0:0:0"
-^ZZCOVERAGE("DIC","RTN",0)="2:0:0:0"
-^ZZCOVERAGE("DIC","RTN",3)="2:0:0:0"
-^ZZCOVERAGE("DIC","RTN",6)="2:0:0:0"
-^ZZCOVERAGE("DIC","X",1)="2:0:0:0"
-^ZZCOVERAGE("DIC","X",4)="2:0:0:0"
-^ZZCOVERAGE("DIC","X",5)="2:0:0:0"
-^ZZCOVERAGE("DIC","X",6)="2:0:0:0"
-^ZZCOVERAGE("DIC0","GETFILE")="2:0:0:0"
-^ZZCOVERAGE("DIC0","GETFILE",0)="2:0:0:0"
-^ZZCOVERAGE("DIC0","GETFILE",1)="2:0:0:0"
-^ZZCOVERAGE("DIC0","GETFILE",2)="2:0:0:0"
-^ZZCOVERAGE("DIC0","GETFILE",3)="2:0:0:0"
-^ZZCOVERAGE("DIC0","GETFILE",4)="2:0:0:0"
-^ZZCOVERAGE("DIC0","GETFILE",7)="2:0:0:0"
-^ZZCOVERAGE("DIC0","GETFILE",8)="2:0:0:0"
-^ZZCOVERAGE("DIC0","GETFILE",11)="2:0:0:0"
-^ZZCOVERAGE("DIC0","GETFILE",12)="2:0:0:0"
-^ZZCOVERAGE("DIC0","GETFILE",13)="2:0:0:0"
-^ZZCOVERAGE("DIC0","GETFILE",14)="2:0:0:0"
-^ZZCOVERAGE("DIC0","GETFILE",15)="2:0:0:0"
-^ZZCOVERAGE("DIC0","GETFILE",16)="2:0:0:0"
-^ZZCOVERAGE("DIC0","INIT")="2:0:0:0"
-^ZZCOVERAGE("DIC0","INIT",1)="2:0:0:0"
-^ZZCOVERAGE("DIC0","INIT",2)="2:0:0:0"
-^ZZCOVERAGE("DIC0","INIT",3)="2:0:0:0"
-^ZZCOVERAGE("DIC0","INIT",4)="2:0:0:0"
-^ZZCOVERAGE("DIC0","INIT",5)="2:0:0:0"
-^ZZCOVERAGE("DIC0","INIT",6)="2:0:0:0"
-^ZZCOVERAGE("DIC0","INIT",7)="2:0:0:0"
-^ZZCOVERAGE("DIC0","INIT",8)="2:0:0:0"
-^ZZCOVERAGE("DIC0","SETIEN")="2:0:0:0"
-^ZZCOVERAGE("DIC0","SETIEN",0)="2:0:0:0"
-^ZZCOVERAGE("DIC0","SETIEN",1)="2:0:0:0"
-^ZZCOVERAGE("DIC0","SETIEN",2)="2:0:0:0"
-^ZZCOVERAGE("DIC0","SETIEN",3)="2:0:0:0"
-^ZZCOVERAGE("DIC0","SETIEN",4)="2:0:0:0"
-^ZZCOVERAGE("DIC0","SETIEN",5)="2:0:0:0"
-^ZZCOVERAGE("DIC0","SETIEN",5,"FOR_LOOP",1)=2
-^ZZCOVERAGE("DIC0","SETIEN",6)="2:0:0:0"
-^ZZCOVERAGE("DIC0","SETIEN",7)="2:0:0:0"
-^ZZCOVERAGE("DIC1","B",0)="2:0:0:0"
-^ZZCOVERAGE("DIC1","DIC1")="2:0:0:0"
-^ZZCOVERAGE("DIC1","DIC1",3)="2:0:0:0"
-^ZZCOVERAGE("DIC1","DIC1",4)="2:0:0:0"
-^ZZCOVERAGE("DIC1","DIC1",5)="2:0:0:0"
-^ZZCOVERAGE("DIC1","DO")="4:0:0:0"
-^ZZCOVERAGE("DIC1","DO",1)="4:0:0:0"
-^ZZCOVERAGE("DIC1","DO",2)="2:0:0:0"
-^ZZCOVERAGE("DIC1","DO2",0)="2:0:0:0"
-^ZZCOVERAGE("DIC1","DO2",1)="2:0:0:0"
-^ZZCOVERAGE("DIC1","DO2",2)="2:0:0:0"
-^ZZCOVERAGE("DIC1","DO2",3)="2:0:0:0"
-^ZZCOVERAGE("DIC1","GETFA")="4:0:0:0"
-^ZZCOVERAGE("DIC1","GETFA",0)="4:0:0:0"
-^ZZCOVERAGE("DIC1","GETFA",2)="4:0:0:0"
-^ZZCOVERAGE("DIC1","P",1)="2:0:0:0"
-^ZZCOVERAGE("DIC1","P",2)="2:0:0:0"
-^ZZCOVERAGE("DIC1","PROMPT",1)="2:0:0:0"
-^ZZCOVERAGE("DIC1","PROMPT",2)="2:0:0:0"
-^ZZCOVERAGE("DIC1","W",0)="2:0:0:0"
-^ZZCOVERAGE("DIC1","W",0,"FOR_LOOP",1)=4
-^ZZCOVERAGE("DIC1","W",1)="3:0:0:0"
-^ZZCOVERAGE("DIC1","W",2)="3:0:0:0"
-^ZZCOVERAGE("DIC1","W",3)="2:0:0:0"
-^ZZCOVERAGE("DIC1","W",4)="2:0:0:0"
-^ZZCOVERAGE("DIC1","W",5)="2:0:0:0"
-^ZZCOVERAGE("DIC1","W",6)="2:0:0:0"
-^ZZCOVERAGE("DIC1","WOV")="1:0:0:0"
-^ZZCOVERAGE("DIC1","WOV",0)="1:0:0:0"
-^ZZCOVERAGE("DIC1","WOV",1)="1:0:0:0"
-^ZZCOVERAGE("DIC11","GETPRMT")="2:0:0:0"
-^ZZCOVERAGE("DIC11","GETPRMT",0)="2:0:0:0"
-^ZZCOVERAGE("DIC11","GETPRMT",1)="2:0:0:0"
-^ZZCOVERAGE("DIC11","GETPRMT",2)="2:0:0:0"
-^ZZCOVERAGE("DIC11","GETPRMT",3)="2:0:0:0"
-^ZZCOVERAGE("DIC11","GETPRMT",3,"FOR_LOOP",1)=2
-^ZZCOVERAGE("DIC11","GETPRMT",4)="2:0:0:0"
-^ZZCOVERAGE("DIC11","GETPRMT",8)="2:0:0:0"
-^ZZCOVERAGE("DIC11","GETPRMT",9)="2:0:0:0"
-^ZZCOVERAGE("DIC11","GETPRMT",10)="2:0:0:0"
-^ZZCOVERAGE("DIC11","GETPRMT",11)="2:0:0:0"
-^ZZCOVERAGE("DIC11","GETPRMT",12)="2:0:0:0"
-^ZZCOVERAGE("DIC11","GETPRMT",13)="2:0:0:0"
-^ZZCOVERAGE("DIC11","GETPRMT",14)="2:0:0:0"
-^ZZCOVERAGE("DIC11","GETPRMT",15)="2:0:0:0"
-^ZZCOVERAGE("DIC11","GETPRMT",16)="2:0:0:0"
-^ZZCOVERAGE("DIC11","GETPRMT",17)="2:0:0:0"
-^ZZCOVERAGE("DIC11","GETPRMT",18)="2:0:0:0"
-^ZZCOVERAGE("DIC11","GETPRMT",19)="2:0:0:0"
-^ZZCOVERAGE("DIC11","PR1",0)="2:0:0:0"
-^ZZCOVERAGE("DIC11","PR1",1)="2:0:0:0"
-^ZZCOVERAGE("DIC11","PR1",2)="2:0:0:0"
-^ZZCOVERAGE("DIC11","PR1",3)="2:0:0:0"
-^ZZCOVERAGE("DIC11","PR1",4)="2:0:0:0"
-^ZZCOVERAGE("DIC11","PR1",6)="2:0:0:0"
-^ZZCOVERAGE("DIC11","PR1",8)="2:0:0:0"
-^ZZCOVERAGE("DIC11","PR1",9)="2:0:0:0"
-^ZZCOVERAGE("DIC11","PR1",11)="2:0:0:0"
-^ZZCOVERAGE("DIC11","PR1",12)="2:0:0:0"
-^ZZCOVERAGE("DIC11","PR1",13)="2:0:0:0"
-^ZZCOVERAGE("DIC11","PR1",14)="2:0:0:0"
-^ZZCOVERAGE("DIC11","PR1",15)="2:0:0:0"
-^ZZCOVERAGE("DIC11","PR1",16)="2:0:0:0"
-^ZZCOVERAGE("DIC11","PROMPT")="2:0:0:0"
-^ZZCOVERAGE("DIC11","PROMPT",0)="2:0:0:0"
-^ZZCOVERAGE("DIC11","PROMPT",1)="2:0:0:0"
-^ZZCOVERAGE("DIC11","PROMPT",1,"FOR_LOOP",1)=2
-^ZZCOVERAGE("DIC11","PROMPT",2)="2:0:0:0"
-^ZZCOVERAGE("DIC11","PROMPT",3)="2:0:0:0"
-^ZZCOVERAGE("DIC11","PROMPT",5)="2:0:0:0"
-^ZZCOVERAGE("DIC2","PGM")="4:0:0:0"
-^ZZCOVERAGE("DIC2","PGM",0)="4:0:0:0"
-^ZZCOVERAGE("DIC2","PGM",1)="4:0:0:0"
-^ZZCOVERAGE("DIC2","PGM",2)="4:0:0:0"
-^ZZCOVERAGE("DIC2","Q")="2:0:0:0"
-^ZZCOVERAGE("DIC2","Q",0)="2:0:0:0"
-^ZZCOVERAGE("DIC2","Q",1)="2:0:0:0"
-^ZZCOVERAGE("DIC2","Q",2)="2:0:0:0"
-^ZZCOVERAGE("DICL","DINDEX")="2:0:0:0"
-^ZZCOVERAGE("DICL","DINDEX",0)="2:0:0:0"
-^ZZCOVERAGE("DICL","DINDEX",1)="2:0:0:0"
-^ZZCOVERAGE("DICL","DINDEX",2)="2:0:0:0"
-^ZZCOVERAGE("DICL","DINDEX",5)="2:0:0:0"
-^ZZCOVERAGE("DICL","DINDEX",6)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","I1",2)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","I1",3)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","I1",4)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","I1",5)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","INDEX")="2:0:0:0"
-^ZZCOVERAGE("DICUIX","INDEX",0)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X1",2)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X1",8)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X1",9)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",2)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",3)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",4)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",5)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",8)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",11)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",12)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",13)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",14)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",15)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",15,"FOR_LOOP",1)=2
-^ZZCOVERAGE("DICUIX","X2",16)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",17)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",18)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",19)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",20)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",21)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",22)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",23)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",24)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",25)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",26)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",27)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",28)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",29)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",30)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",31)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",32)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","X2",33)="2:0:0:0"
-^ZZCOVERAGE("DICUIX","XREF")="2:0:0:0"
-^ZZCOVERAGE("DICUIX","XREF",0)="2:0:0:0"
-^ZZCOVERAGE("DICUIX1","G1",2)="2:0:0:0"
-^ZZCOVERAGE("DICUIX1","G1",3)="2:0:0:0"
-^ZZCOVERAGE("DICUIX1","G1",4)="2:0:0:0"
-^ZZCOVERAGE("DICUIX1","G2",2)="2:0:0:0"
-^ZZCOVERAGE("DICUIX1","G2",3)="2:0:0:0"
-^ZZCOVERAGE("DICUIX1","G3",2)="2:0:0:0"
-^ZZCOVERAGE("DICUIX1","G30",1)="2:0:0:0"
-^ZZCOVERAGE("DICUIX1","G4",2)="2:0:0:0"
-^ZZCOVERAGE("DICUIX1","G4",3)="2:0:0:0"
-^ZZCOVERAGE("DICUIX1","G4",4)="2:0:0:0"
-^ZZCOVERAGE("DICUIX1","G4",5)="2:0:0:0"
-^ZZCOVERAGE("DICUIX1","G4",6)="2:0:0:0"
-^ZZCOVERAGE("DICUIX1","G4",7)="2:0:0:0"
-^ZZCOVERAGE("DICUIX1","G5",2)="2:0:0:0"
-^ZZCOVERAGE("DICUIX1","G5",3)="2:0:0:0"
-^ZZCOVERAGE("DICUIX1","G5",7)="2:0:0:0"
-^ZZCOVERAGE("DICUIX1","GET")="2:0:0:0"
-^ZZCOVERAGE("DICUIX1","GET",0)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C1",0)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C1",1)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C2",0)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C2",1)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C3",0)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C3",1)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C3",2)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C3",5)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C4",0)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C4",1)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C4",2)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C4",3)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C4",4)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C4",5)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C4",6)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C4",7)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C4",8)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C4",9)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C4",10)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C4",11)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C4",12)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C4",17)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C4",18)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C4",23)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C4",24)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C5",0)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C5",1)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C6",0)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C6",18)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C6",19)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C6",20)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C7",0)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","C7",7)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","COMMON1")="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","COMMON1",1)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","COMMON1",2)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","COMMON1",3)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","COMMON1",4)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","COMMON1",5)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","COMMON1",6)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","COMMON1",7)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","COMMON2")="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","COMMON2",1)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","COMMON2",2)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","COMMON2",3)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","COMMON2",4)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","COMMON2",5)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","COMMON2",6)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","COMMON2",7)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","COMMON2",8)="2:0:0:0"
-^ZZCOVERAGE("DICUIX2","COMMON2",9)="2:0:0:0"
-^ZZCOVERAGE("DIEFU","IENX",1)="2:0:0:0"
-^ZZCOVERAGE("DIEFU","IENX",2)="2:0:0:0"
-^ZZCOVERAGE("DIEFU","IENX",3)="2:0:0:0"
-^ZZCOVERAGE("DIEFU","IENX",3,"FOR_LOOP",1)=4
-^ZZCOVERAGE("DIEFU","IENX",4)="2:0:0:0"
-^ZZCOVERAGE("DIEFU","IENX",5)="2:0:0:0"
-^ZZCOVERAGE("DILF","CREF")="4:0:0:0"
-^ZZCOVERAGE("DILF","CREF",0)="4:0:0:0"
-^ZZCOVERAGE("DILF","IENS")="2:0:0:0"
-^ZZCOVERAGE("DILF","IENS",0)="2:0:0:0"
-^ZZCOVERAGE("DILF","IENS",1)="2:0:0:0"
-^ZZCOVERAGE("DILF","OREF")="2:0:0:0"
-^ZZCOVERAGE("DILF","OREF",0)="2:0:0:0"
-^ZZCOVERAGE("DILIBF","FNO")="2:0:0:0"
-^ZZCOVERAGE("DILIBF","FNO",0)="2:0:0:0"
-^ZZCOVERAGE("DILIBF","FNO",1)="2:0:0:0"
-^ZZCOVERAGE("DILIBF","FNO",2)="2:0:0:0"
-^ZZCOVERAGE("DIQGU","ENCREF",0)="4:0:0:0"
-^ZZCOVERAGE("DIQGU","ENOREF",0)="2:0:0:0"
-^ZZCOVERAGE("DIQGU","OR2")="2:0:0:0"
-^ZZCOVERAGE("DIQGU","OR2",0)="2:0:0:0"
-^ZZCOVERAGE("XINDEX","A2",0)="468:0:4000:4000"
-^ZZCOVERAGE("XINDEX","A2",1)="467:0:0:0"
-^ZZCOVERAGE("XINDEX","A2",2)="467:0:0:0"
-^ZZCOVERAGE("XINDEX","A2",3)="467:4000:0:4000"
-^ZZCOVERAGE("XINDEX","A2",4)="467:0:4000:4000"
-^ZZCOVERAGE("XINDEX","A2",5)="467:0:0:0"
-^ZZCOVERAGE("XINDEX","ALIVE",1)="1:0:0:0"
-^ZZCOVERAGE("XINDEX","B5",0)="467:188012:220012:408024"
-^ZZCOVERAGE("XINDEX","B5",0,"FOR_LOOP",1)=44620
-^ZZCOVERAGE("XINDEX","B5",1)="467:20000:8000:28000"
-^ZZCOVERAGE("XINDEX","B5",2)="467:4000:0:4000"
-^ZZCOVERAGE("XINDEX","B5",3)="467:0:0:0"
-^ZZCOVERAGE("XINDEX","B5",4)="467:4000:0:4000"
-^ZZCOVERAGE("XINDEX","B5",5)="467:0:0:0"
-^ZZCOVERAGE("XINDEX","BEG")="467:2460149:2872194:5332343"
-^ZZCOVERAGE("XINDEX","BEG",1)="467:8000:0:8000"
-^ZZCOVERAGE("XINDEX","BEG",2)="467:4000:0:4000"
-^ZZCOVERAGE("XINDEX","BEG",3)="467:0:4000:4000"
-^ZZCOVERAGE("XINDEX","BEG",4)="467:0:4000:4000"
-^ZZCOVERAGE("XINDEX","BEG",5)="467:4001:0:4001"
-^ZZCOVERAGE("XINDEX","BEG",7)="467:0:0:0"
-^ZZCOVERAGE("XINDEX","BEG",8)="467:0:0:0"
-^ZZCOVERAGE("XINDEX","BEG",9)="467:0:0:0"
-^ZZCOVERAGE("XINDEX","BEG",11)="467:4000:0:4000"
-^ZZCOVERAGE("XINDEX","BEG",12)="467:0:4000:4000"
-^ZZCOVERAGE("XINDEX","BEG",14)="467:0:0:0"
-^ZZCOVERAGE("XINDEX","BEG",15)="467:0:0:0"
-^ZZCOVERAGE("XINDEX","BEG",16)="467:0:0:0"
-^ZZCOVERAGE("XINDEX","CD",0)="44620:32001:36002:68003"
-^ZZCOVERAGE("XINDEX","CD",1)="44620:40002:60004:100006"
-^ZZCOVERAGE("XINDEX","CD",2)="44620:40001:60002:100003"
-^ZZCOVERAGE("XINDEX","CD",3)="44620:36002:44004:80006"
-^ZZCOVERAGE("XINDEX","CD",4)="44620:28000:40002:68002"
-^ZZCOVERAGE("XINDEX","CD",5)="44620:28002:52001:80003"
-^ZZCOVERAGE("XINDEX","CD",6)="10770:28003:20000:48003"
-^ZZCOVERAGE("XINDEX","CD",6,"FOR_LOOP",1)=57531
-^ZZCOVERAGE("XINDEX","CD",7)="10770:24004:16000:40004"
-^ZZCOVERAGE("XINDEX","CD",9)="44620:60005:40004:100009"
-^ZZCOVERAGE("XINDEX","CD",10)="44620:44003:48005:92008"
-^ZZCOVERAGE("XINDEX","CD",12)="44620:52004:44002:96006"
-^ZZCOVERAGE("XINDEX","EE",0)="116081:148007:200014:348021"
-^ZZCOVERAGE("XINDEX","EE",1)="71461:44004:44002:88006"
-^ZZCOVERAGE("XINDEX","EE",2)="71461:100007:80003:180010"
-^ZZCOVERAGE("XINDEX","EE",3)="54870:44001:48001:92002"
-^ZZCOVERAGE("XINDEX","EE",4)="53608:88008:100009:188017"
-^ZZCOVERAGE("XINDEX","EE",5)="53608:72006:68004:140010"
-^ZZCOVERAGE("XINDEX","EE",6)="53608:76005:72004:148009"
-^ZZCOVERAGE("XINDEX","EE",8)="53608:60003:64005:124008"
-^ZZCOVERAGE("XINDEX","EE",9)="53608:48003:72003:120006"
-^ZZCOVERAGE("XINDEX","EE",10)="53608:52002:96008:148010"
-^ZZCOVERAGE("XINDEX","EE",13)="53608:52003:44001:96004"
-^ZZCOVERAGE("XINDEX","EE",14)="53608:96007:112006:208013"
-^ZZCOVERAGE("XINDEX","EE",15)="53608:24001:52004:76005"
-^ZZCOVERAGE("XINDEX","EE",16)="53608:52005:88007:140012"
-^ZZCOVERAGE("XINDEX","EE",17)="53608:128008:208017:336025"
-^ZZCOVERAGE("XINDEX","F")="1559:4000:4001:8001"
-^ZZCOVERAGE("XINDEX","F",0)="1559:4000:0:4000"
-^ZZCOVERAGE("XINDEX","G")="1932:56003:96009:152012"
-^ZZCOVERAGE("XINDEX","G",0)="1932:4000:8002:12002"
-^ZZCOVERAGE("XINDEX","H")="11:0:0:0"
-^ZZCOVERAGE("XINDEX","H",0)="11:0:0:0"
-^ZZCOVERAGE("XINDEX","K")="2218:40001:24002:64003"
-^ZZCOVERAGE("XINDEX","K",0)="2218:4000:4000:8000"
-^ZZCOVERAGE("XINDEX","K",1)="2218:0:4001:4001"
-^ZZCOVERAGE("XINDEX","L")="259:4001:4000:8001"
-^ZZCOVERAGE("XINDEX","L",0)="259:0:0:0"
-^ZZCOVERAGE("XINDEX","LN",0)="44620:68005:104005:172010"
-^ZZCOVERAGE("XINDEX","LN",1)="44620:40001:64004:104005"
-^ZZCOVERAGE("XINDEX","LN",2)="5073:12000:4001:16001"
-^ZZCOVERAGE("XINDEX","LN",3)="5073:4000:8000:12000"
-^ZZCOVERAGE("XINDEX","LN",4)="5073:20001:0:20001"
-^ZZCOVERAGE("XINDEX","LN",5)="5073:20003:12002:32005"
-^ZZCOVERAGE("XINDEX","LN",6)="5073:12002:16000:28002"
-^ZZCOVERAGE("XINDEX","LOAD")="467:88003:196019:284022"
-^ZZCOVERAGE("XINDEX","LOAD",0)="467:88003:196019:284022"
-^ZZCOVERAGE("XINDEX","LOAD",1)="467:0:0:0"
-^ZZCOVERAGE("XINDEX","LOAD",2)="467:0:0:0"
-^ZZCOVERAGE("XINDEX","M")="30:4000:0:4000"
-^ZZCOVERAGE("XINDEX","M",0)="30:0:0:0"
-^ZZCOVERAGE("XINDEX","N")="1721:88005:80004:168009"
-^ZZCOVERAGE("XINDEX","N",0)="1721:4000:0:4000"
-^ZZCOVERAGE("XINDEX","POSTRTN")="467:108009:96003:204012"
-^ZZCOVERAGE("XINDEX","POSTRTN",1)="467:0:0:0"
-^ZZCOVERAGE("XINDEX","POSTRTN",2)="467:0:0:0"
-^ZZCOVERAGE("XINDEX","POSTRTN",3)="467:12000:8000:20000"
-^ZZCOVERAGE("XINDEX","POSTRTN",3,"FOR_LOOP",1)=2558
-^ZZCOVERAGE("XINDEX","POSTRTN",4)="2091:0:0:0"
-^ZZCOVERAGE("XINDEX","POSTRTN",5)="2044:4000:0:4000"
-^ZZCOVERAGE("XINDEX","POSTRTN",6)="2044:4000:0:4000"
-^ZZCOVERAGE("XINDEX","POSTRTN",9)="2044:0:0:0"
-^ZZCOVERAGE("XINDEX","POSTRTN",10)="467:0:4000:4000"
-^ZZCOVERAGE("XINDEX","POSTRTN",11)="467:12002:16001:28003"
-^ZZCOVERAGE("XINDEX","POSTRTN",11,"FOR_LOOP",1)=5540
-^ZZCOVERAGE("XINDEX","POSTRTN",12)="5073:0:4000:4000"
-^ZZCOVERAGE("XINDEX","POSTRTN",13)="5073:8000:4000:12000"
-^ZZCOVERAGE("XINDEX","POSTRTN",14)="5073:0:0:0"
-^ZZCOVERAGE("XINDEX","POSTRTN",15)="467:0:0:0"
-^ZZCOVERAGE("XINDEX","POSTRTN",16)="467:28001:20001:48002"
-^ZZCOVERAGE("XINDEX","POSTRTN",16,"FOR_LOOP",1)=16376
-^ZZCOVERAGE("XINDEX","POSTRTN",17)="15909:40006:40001:80007"
-^ZZCOVERAGE("XINDEX","POSTRTN",18)="15909:0:0:0"
-^ZZCOVERAGE("XINDEX","POSTRTN",19)="467:0:0:0"
-^ZZCOVERAGE("XINDEX","Q")="7762:12000:20001:32001"
-^ZZCOVERAGE("XINDEX","Q",0)="7762:4000:16001:20001"
-^ZZCOVERAGE("XINDEX","QUOTE")="36371:188012:232009:420021"
-^ZZCOVERAGE("XINDEX","QUOTE",0)="36371:156010:192008:348018"
-^ZZCOVERAGE("XINDEX","QUOTE",0,"FOR_LOOP",1)=323268
-^ZZCOVERAGE("XINDEX","QUOTE",1)="36371:20002:20001:40003"
-^ZZCOVERAGE("XINDEX","R")="85:0:8001:8001"
-^ZZCOVERAGE("XINDEX","R",0)="85:0:0:0"
-^ZZCOVERAGE("XINDEX","S")="17549:716055:988057:1704112"
-^ZZCOVERAGE("XINDEX","S",0)="17549:28003:28003:56006"
-^ZZCOVERAGE("XINDEX","SE2",0)="86891:176010:272017:448027"
-^ZZCOVERAGE("XINDEX","SE2",1)="85079:264015:376016:640031"
-^ZZCOVERAGE("XINDEX","SE2",2)="85079:72005:112010:184015"
-^ZZCOVERAGE("XINDEX","SEP")="107216:736054:648038:1384092"
-^ZZCOVERAGE("XINDEX","SEP",0)="107216:580045:440030:1020075"
-^ZZCOVERAGE("XINDEX","SEP",0,"FOR_LOOP",1)=1019212
-^ZZCOVERAGE("XINDEX","SEP",1)="107216:120007:144005:264012"
-^ZZCOVERAGE("XINDEX","SET")="85079:772044:1124063:1896107"
-^ZZCOVERAGE("XINDEX","SET",0)="85079:176007:168008:344015"
-^ZZCOVERAGE("XINDEX","SET",0,"FOR_LOOP",1)=74812
-^ZZCOVERAGE("XINDEX","SET",1)="85079:64005:144010:208015"
-^ZZCOVERAGE("XINDEX","ST",0)="44620:68001:56004:124005"
-^ZZCOVERAGE("XINDEX","ST",2)="44620:260012:376038:636050"
-^ZZCOVERAGE("XINDEX","ST",2,"FOR_LOOP",1)=85813
-^ZZCOVERAGE("XINDEX","ST",2,"FOR_LOOP",2)=126272
-^ZZCOVERAGE("XINDEX","ST",3)="44620:224014:184014:408028"
-^ZZCOVERAGE("XINDEX","ST",4)="44620:0:0:0"
-^ZZCOVERAGE("XINDEX","U")="72:0:0:0"
-^ZZCOVERAGE("XINDEX","U",0)="72:0:0:0"
-^ZZCOVERAGE("XINDEX","W")="4584:156009:200014:356023"
-^ZZCOVERAGE("XINDEX","W",0)="4584:0:16001:16001"
-^ZZCOVERAGE("XINDEX","X")="220:0:0:0"
-^ZZCOVERAGE("XINDEX","X",0)="220:0:0:0"
-^ZZCOVERAGE("XINDEX","XINDEX")="1:32002:36000:68002"
-^ZZCOVERAGE("XINDEX","XINDEX",3)="1:0:0:0"
-^ZZCOVERAGE("XINDX1","A",0)="75:0:4000:4000"
-^ZZCOVERAGE("XINDX1","A",1)="75:0:0:0"
-^ZZCOVERAGE("XINDX1","A",2)="75:0:0:0"
-^ZZCOVERAGE("XINDX1","B",0)="75:0:0:0"
-^ZZCOVERAGE("XINDX1","B",4)="75:0:0:0"
-^ZZCOVERAGE("XINDX1","B",6)="75:0:0:0"
-^ZZCOVERAGE("XINDX1","B",7)="75:0:0:0"
-^ZZCOVERAGE("XINDX1","E")="73:0:4000:4000"
-^ZZCOVERAGE("XINDX1","E",0)="73:0:0:0"
-^ZZCOVERAGE("XINDX1","XINDX1")="2:0:0:0"
-^ZZCOVERAGE("XINDX1","XINDX1",3)="2:0:0:0"
-^ZZCOVERAGE("XINDX10","ASK")="1:0:0:0"
-^ZZCOVERAGE("XINDX10","ASK",1)="1:0:0:0"
-^ZZCOVERAGE("XINDX10","ASK",2)="1:0:0:0"
-^ZZCOVERAGE("XINDX10","ASK",3)="1:0:0:0"
-^ZZCOVERAGE("XINDX10","ASK",8)="1:0:0:0"
-^ZZCOVERAGE("XINDX2","%")="44620:132010:232014:364024"
-^ZZCOVERAGE("XINDX2","%",0)="44620:96008:92005:188013"
-^ZZCOVERAGE("XINDX2","%",0,"FOR_LOOP",1)=62810
-^ZZCOVERAGE("XINDX2","%",1)="44620:16001:68003:84004"
-^ZZCOVERAGE("XINDX2","ARG")="329774:1516089:2124136:3640225"
-^ZZCOVERAGE("XINDX2","ARG",1)="330498:328020:360021:688041"
-^ZZCOVERAGE("XINDX2","ARG",2)="262221:228015:296022:524037"
-^ZZCOVERAGE("XINDX2","ARG",3)="226556:260020:468034:728054"
-^ZZCOVERAGE("XINDX2","ARG",4)="126854:104004:160011:264015"
-^ZZCOVERAGE("XINDX2","ARG",5)="117750:136007:148011:284018"
-^ZZCOVERAGE("XINDX2","ARG",6)="88629:60001:96003:156004"
-^ZZCOVERAGE("XINDX2","ARG",7)="88424:80005:100006:180011"
-^ZZCOVERAGE("XINDX2","ARG",8)="86550:72002:108007:180009"
-^ZZCOVERAGE("XINDX2","ARGG")="18715:288018:352019:640037"
-^ZZCOVERAGE("XINDX2","ARGG",0)="18715:76007:84005:160012"
-^ZZCOVERAGE("XINDX2","ARGG",0,"FOR_LOOP",1)=49672
-^ZZCOVERAGE("XINDX2","ARGS")="44410:464031:676031:1140062"
-^ZZCOVERAGE("XINDX2","ARGS",1)="63125:620038:844037:1464075"
-^ZZCOVERAGE("XINDX2","ARGS",1,"FOR_LOOP",1)=291597
-^ZZCOVERAGE("XINDX2","ARGS",2)="63125:24001:60004:84005"
-^ZZCOVERAGE("XINDX2","DN")="44410:208011:284017:492028"
-^ZZCOVERAGE("XINDX2","DN",0)="44410:44003:108008:152011"
-^ZZCOVERAGE("XINDX2","DN",1)="44410:152008:144006:296014"
-^ZZCOVERAGE("XINDX2","EXT",1)="1970:4000:8001:12001"
-^ZZCOVERAGE("XINDX2","EXT",2)="1970:0:0:0"
-^ZZCOVERAGE("XINDX2","EXT",3)="1970:8001:12001:20002"
-^ZZCOVERAGE("XINDX2","EXT",4)="1970:0:4000:4000"
-^ZZCOVERAGE("XINDX2","FLUSH")="94:0:0:0"
-^ZZCOVERAGE("XINDX2","FLUSH",0)="94:0:0:0"
-^ZZCOVERAGE("XINDX2","FLUSH",1)="94:0:0:0"
-^ZZCOVERAGE("XINDX2","FLUSH",1,"FOR_LOOP",1)=415
-^ZZCOVERAGE("XINDX2","FLUSH",2)="94:0:0:0"
-^ZZCOVERAGE("XINDX2","FNC")="12:0:0:0"
-^ZZCOVERAGE("XINDX2","FNC",0)="12:0:0:0"
-^ZZCOVERAGE("XINDX2","FNC",1)="12:0:0:0"
-^ZZCOVERAGE("XINDX2","FNC",2)="12:0:0:0"
-^ZZCOVERAGE("XINDX2","FNC",3)="12:0:0:0"
-^ZZCOVERAGE("XINDX2","FNC",4)="12:0:0:0"
-^ZZCOVERAGE("XINDX2","FUN")="29121:340019:424027:764046"
-^ZZCOVERAGE("XINDX2","FUN",0)="29121:36004:40002:76006"
-^ZZCOVERAGE("XINDX2","FUN",1)="23452:48002:72003:120005"
-^ZZCOVERAGE("XINDX2","FUN",2)="23452:20000:44003:64003"
-^ZZCOVERAGE("XINDX2","FUN",3)="23393:96004:56005:152009"
-^ZZCOVERAGE("XINDX2","FUN",3,"FOR_LOOP",1)=147754
-^ZZCOVERAGE("XINDX2","FUN",4)="23393:48003:56005:104008"
-^ZZCOVERAGE("XINDX2","FUN",5)="23393:60004:92005:152009"
-^ZZCOVERAGE("XINDX2","GLO",0)="9104:28002:28001:56003"
-^ZZCOVERAGE("XINDX2","GLO",1)="9104:12001:20001:32002"
-^ZZCOVERAGE("XINDX2","GLO",2)="9104:16000:28001:44001"
-^ZZCOVERAGE("XINDX2","GLO",3)="9104:36002:80004:116006"
-^ZZCOVERAGE("XINDX2","GLO",4)="9104:8000:4000:12000"
-^ZZCOVERAGE("XINDX2","INC")="322910:416022:652029:1068051"
-^ZZCOVERAGE("XINDX2","INC",0)="365505:320019:472020:792039"
-^ZZCOVERAGE("XINDX2","INC2")="42595:104006:148008:252014"
-^ZZCOVERAGE("XINDX2","INC2",0)="42595:48001:40003:88004"
-^ZZCOVERAGE("XINDX2","LOC")="99702:576031:736052:1312083"
-^ZZCOVERAGE("XINDX2","LOC",0)="99702:144010:156013:300023"
-^ZZCOVERAGE("XINDX2","LOC",1)="99702:124004:148011:272015"
-^ZZCOVERAGE("XINDX2","LOC",2)="99702:212011:272014:484025"
-^ZZCOVERAGE("XINDX2","LOC",3)="99702:52005:96006:148011"
-^ZZCOVERAGE("XINDX2","NAK",0)="996:0:0:0"
-^ZZCOVERAGE("XINDX2","NAK",1)="996:0:0:0"
-^ZZCOVERAGE("XINDX2","PAT")="205:4000:0:4000"
-^ZZCOVERAGE("XINDX2","PAT",0)="205:0:0:0"
-^ZZCOVERAGE("XINDX2","PAT",1)="205:4000:0:4000"
-^ZZCOVERAGE("XINDX2","PAT",1,"FOR_LOOP",1)=457
-^ZZCOVERAGE("XINDX2","PAT",2)="205:0:0:0"
-^ZZCOVERAGE("XINDX2","PATCODE")="457:4000:4000:8000"
-^ZZCOVERAGE("XINDX2","PATCODE",0)="457:0:4000:4000"
-^ZZCOVERAGE("XINDX2","PATCODE",1)="358:4000:0:4000"
-^ZZCOVERAGE("XINDX2","PATCODE",1,"FOR_LOOP",1)=791
-^ZZCOVERAGE("XINDX2","PATCODE",2)="358:0:0:0"
-^ZZCOVERAGE("XINDX2","PATCODE",3)="358:0:0:0"
-^ZZCOVERAGE("XINDX2","PATCODE",4)="358:0:0:0"
-^ZZCOVERAGE("XINDX2","PATQ")="99:4000:4000:8000"
-^ZZCOVERAGE("XINDX2","PATQ",0)="99:0:4000:4000"
-^ZZCOVERAGE("XINDX2","PATQ",0,"FOR_LOOP",1)=247
-^ZZCOVERAGE("XINDX2","PATQ",1)="99:4000:0:4000"
-^ZZCOVERAGE("XINDX2","PATQ",2)="99:0:0:0"
-^ZZCOVERAGE("XINDX2","PEEK")="112687:168013:248022:416035"
-^ZZCOVERAGE("XINDX2","PEEK",0)="112687:120009:164010:284019"
-^ZZCOVERAGE("XINDX2","PEEKDN")="17373:56002:40000:96002"
-^ZZCOVERAGE("XINDX2","PEEKDN",0)="17373:48002:32000:80002"
-^ZZCOVERAGE("XINDX2","REPCNT")="457:0:0:0"
-^ZZCOVERAGE("XINDX2","REPCNT",0)="457:0:0:0"
-^ZZCOVERAGE("XINDX2","REPCNT",0,"FOR_LOOP",1)=1004
-^ZZCOVERAGE("XINDX2","REPCNT",1)="457:0:0:0"
-^ZZCOVERAGE("XINDX2","REPCNT",2)="457:0:0:0"
-^ZZCOVERAGE("XINDX2","SPV",1)="3699:0:8001:8001"
-^ZZCOVERAGE("XINDX2","SPV",2)="3699:0:0:0"
-^ZZCOVERAGE("XINDX2","ST")="110835:464030:648049:1112079"
-^ZZCOVERAGE("XINDX2","ST",0)="110835:192009:248021:440030"
-^ZZCOVERAGE("XINDX2","ST",1)="110835:100008:156011:256019"
-^ZZCOVERAGE("XINDX2","ST",2)="110835:76005:116005:192010"
-^ZZCOVERAGE("XINDX2","TEXT",0)="59:0:0:0"
-^ZZCOVERAGE("XINDX2","TEXT",1)="59:0:0:0"
-^ZZCOVERAGE("XINDX2","TEXT",2)="59:0:0:0"
-^ZZCOVERAGE("XINDX2","TEXT",3)="59:0:0:0"
-^ZZCOVERAGE("XINDX2","UP")="44410:116012:180012:296024"
-^ZZCOVERAGE("XINDX2","UP",1)="44410:112012:116006:228018"
-^ZZCOVERAGE("XINDX2","VA")="5073:16001:20000:36001"
-^ZZCOVERAGE("XINDX2","VA",0)="5073:4000:12000:16000"
-^ZZCOVERAGE("XINDX2","VA",1)="5073:8000:4000:12000"
-^ZZCOVERAGE("XINDX2","VT")="10205:4001:24002:28003"
-^ZZCOVERAGE("XINDX2","VT",0)="10205:0:8000:8000"
-^ZZCOVERAGE("XINDX2","VT",1)="10205:0:4000:4000"
-^ZZCOVERAGE("XINDX3","A",0)="8136:36001:12001:48002"
-^ZZCOVERAGE("XINDX3","ASM")="312:12001:0:12001"
-^ZZCOVERAGE("XINDX3","ASM",0)="312:0:0:0"
-^ZZCOVERAGE("XINDX3","ASM",1)="312:8001:0:8001"
-^ZZCOVERAGE("XINDX3","ASM",1,"FOR_LOOP",1)=2110
-^ZZCOVERAGE("XINDX3","ASM",2)="312:0:0:0"
-^ZZCOVERAGE("XINDX3","DN")="498:4000:4000:8000"
-^ZZCOVERAGE("XINDX3","DN",0)="498:0:4000:4000"
-^ZZCOVERAGE("XINDX3","DN",1)="498:4000:0:4000"
-^ZZCOVERAGE("XINDX3","FL")="63250:152007:260014:412021"
-^ZZCOVERAGE("XINDX3","FL",1)="63250:72000:144009:216009"
-^ZZCOVERAGE("XINDX3","FL",2)="63250:64006:80004:144010"
-^ZZCOVERAGE("XINDX3","INC")="145482:224018:308026:532044"
-^ZZCOVERAGE("XINDX3","INC",0)="145482:188015:196015:384030"
-^ZZCOVERAGE("XINDX3","KL",1)="2218:0:4000:4000"
-^ZZCOVERAGE("XINDX3","KL1")="28:0:0:0"
-^ZZCOVERAGE("XINDX3","KL1",0)="28:0:0:0"
-^ZZCOVERAGE("XINDX3","KL2")="724:4000:28000:32000"
-^ZZCOVERAGE("XINDX3","KL2",0)="724:0:0:0"
-^ZZCOVERAGE("XINDX3","KL2",1)="724:0:4000:4000"
-^ZZCOVERAGE("XINDX3","KL2",2)="724:0:0:0"
-^ZZCOVERAGE("XINDX3","KL3")="3320:12002:36002:48004"
-^ZZCOVERAGE("XINDX3","KL3",0)="3320:4000:8000:12000"
-^ZZCOVERAGE("XINDX3","KL3",1)="3320:4001:4000:8001"
-^ZZCOVERAGE("XINDX3","KL5",0)="3320:0:20002:20002"
-^ZZCOVERAGE("XINDX3","MULT")="498:8001:4000:12001"
-^ZZCOVERAGE("XINDX3","MULT",0)="498:4001:0:4001"
-^ZZCOVERAGE("XINDX3","MULT",1)="498:4000:4000:8000"
-^ZZCOVERAGE("XINDX3","MULT",1,"FOR_LOOP",1)=2401
-^ZZCOVERAGE("XINDX3","MULT",2)="498:0:0:0"
-^ZZCOVERAGE("XINDX3","N2",0)="23604:68004:36003:104007"
-^ZZCOVERAGE("XINDX3","N2",3)="11802:16002:4000:20002"
-^ZZCOVERAGE("XINDX3","N2",4)="187:0:0:0"
-^ZZCOVERAGE("XINDX3","N2",5)="187:0:0:0"
-^ZZCOVERAGE("XINDX3","N2",6)="11628:12001:20002:32003"
-^ZZCOVERAGE("XINDX3","N2",7)="11628:12000:8000:20000"
-^ZZCOVERAGE("XINDX3","NE")="779:32002:16001:48003"
-^ZZCOVERAGE("XINDX3","NE",1)="2500:4000:4000:8000"
-^ZZCOVERAGE("XINDX3","NE",2)="2500:4000:20000:24000"
-^ZZCOVERAGE("XINDX3","PEEK")="498:0:0:0"
-^ZZCOVERAGE("XINDX3","PEEK",0)="498:0:0:0"
-^ZZCOVERAGE("XINDX3","PEEKDN")="39:0:0:0"
-^ZZCOVERAGE("XINDX3","PEEKDN",0)="39:0:0:0"
-^ZZCOVERAGE("XINDX3","RD",0)="85:0:0:0"
-^ZZCOVERAGE("XINDX3","RD1",0)="278:0:4001:4001"
-^ZZCOVERAGE("XINDX3","RD1",3)="193:0:4000:4000"
-^ZZCOVERAGE("XINDX3","RD1",4)="85:0:0:0"
-^ZZCOVERAGE("XINDX3","RD1",5)="85:0:0:0"
-^ZZCOVERAGE("XINDX3","RD2")="85:0:4000:4000"
-^ZZCOVERAGE("XINDX3","RD2",0)="255:0:0:0"
-^ZZCOVERAGE("XINDX3","RD2",1)="170:0:0:0"
-^ZZCOVERAGE("XINDX3","RD2",2)="170:0:4000:4000"
-^ZZCOVERAGE("XINDX3","RD2",3)="85:0:0:0"
-^ZZCOVERAGE("XINDX3","RD3")="108:0:0:0"
-^ZZCOVERAGE("XINDX3","RD3",0)="161:0:0:0"
-^ZZCOVERAGE("XINDX3","RD3",1)="37:0:0:0"
-^ZZCOVERAGE("XINDX3","RD3",2)="37:0:0:0"
-^ZZCOVERAGE("XINDX3","S",1)="17579:48005:56003:104008"
-^ZZCOVERAGE("XINDX3","S2",0)="110559:164008:220011:384019"
-^ZZCOVERAGE("XINDX3","S2",1)="92980:64007:96005:160012"
-^ZZCOVERAGE("XINDX3","S2",2)="92980:52004:100005:152009"
-^ZZCOVERAGE("XINDX3","S2",3)="87238:60005:68003:128008"
-^ZZCOVERAGE("XINDX3","S2",4)="63916:68007:68004:136011"
-^ZZCOVERAGE("XINDX3","S2",5)="846:0:0:0"
-^ZZCOVERAGE("XINDX3","S2",6)="846:0:4000:4000"
-^ZZCOVERAGE("XINDX3","S2",10)="63916:56004:60003:116007"
-^ZZCOVERAGE("XINDX3","S2",11)="62481:40002:60003:100005"
-^ZZCOVERAGE("XINDX3","S2",12)="62313:56003:56005:112008"
-^ZZCOVERAGE("XINDX3","S2",13)="61815:76007:152010:228017"
-^ZZCOVERAGE("XINDX3","UP")="498:8000:4000:12000"
-^ZZCOVERAGE("XINDX3","UP",1)="498:8000:4000:12000"
-^ZZCOVERAGE("XINDX3","VLN",1)="15909:32002:16001:48003"
-^ZZCOVERAGE("XINDX3","VLN",2)="15909:44002:28003:72005"
-^ZZCOVERAGE("XINDX3","VLNF")="15909:120006:60005:180011"
-^ZZCOVERAGE("XINDX3","VLNF",0)="15909:32002:12001:44003"
-^ZZCOVERAGE("XINDX4","CNG")="2186:0:24001:24001"
-^ZZCOVERAGE("XINDX4","CNG",0)="2186:0:0:0"
-^ZZCOVERAGE("XINDX4","CNG",2)="2186:0:8001:8001"
-^ZZCOVERAGE("XINDX4","CNG",2,"FOR_LOOP",1)=2202
-^ZZCOVERAGE("XINDX4","CNG",3)="2186:0:12000:12000"
-^ZZCOVERAGE("XINDX4","DG",0)="8937:20003:16000:36003"
-^ZZCOVERAGE("XINDX4","DG",1)="8937:12000:16001:28001"
-^ZZCOVERAGE("XINDX4","DG",2)="8937:8001:20002:28003"
-^ZZCOVERAGE("XINDX4","DG",3)="8937:16000:12000:28000"
-^ZZCOVERAGE("XINDX4","DG",4)="8937:4000:12001:16001"
-^ZZCOVERAGE("XINDX4","DG",5)="8937:0:12002:12002"
-^ZZCOVERAGE("XINDX4","DG",6)="8937:12001:12000:24001"
-^ZZCOVERAGE("XINDX4","DG",7)="8937:12000:20003:32003"
-^ZZCOVERAGE("XINDX4","DG",8)="8937:24001:4001:28002"
-^ZZCOVERAGE("XINDX4","DG",9)="8937:4000:12001:16001"
-^ZZCOVERAGE("XINDX4","DG",10)="8937:16001:28001:44002"
-^ZZCOVERAGE("XINDX4","DG",11)="8937:8000:12000:20000"
-^ZZCOVERAGE("XINDX4","DG",12)="8937:4000:16002:20002"
-^ZZCOVERAGE("XINDX4","DG",13)="8937:8000:12002:20002"
-^ZZCOVERAGE("XINDX4","DG",14)="8937:0:4000:4000"
-^ZZCOVERAGE("XINDX4","DG",15)="8937:36002:32002:68004"
-^ZZCOVERAGE("XINDX4","DG",16)="8937:8001:4001:12002"
-^ZZCOVERAGE("XINDX4","DG",17)="8387:12002:4000:16002"
-^ZZCOVERAGE("XINDX4","DG1")="8449:168011:180013:348024"
-^ZZCOVERAGE("XINDX4","DG1",0)="8449:12001:16001:28002"
-^ZZCOVERAGE("XINDX4","FR",0)="525:0:4001:4001"
-^ZZCOVERAGE("XINDX4","FR",1)="525:0:0:0"
-^ZZCOVERAGE("XINDX4","FR",2)="525:0:0:0"
-^ZZCOVERAGE("XINDX4","INSIDE")="2202:4001:32001:36002"
-^ZZCOVERAGE("XINDX4","INSIDE",0)="2202:0:16000:16000"
-^ZZCOVERAGE("XINDX4","INSIDE",1)="2202:0:4000:4000"
-^ZZCOVERAGE("XINDX4","INSIDE",2)="2202:4001:4000:8001"
-^ZZCOVERAGE("XINDX4","LO",1)="259:0:0:0"
-^ZZCOVERAGE("XINDX4","LO",2)="259:0:0:0"
-^ZZCOVERAGE("XINDX4","LO",3)="259:0:0:0"
-^ZZCOVERAGE("XINDX4","LO",4)="259:0:4000:4000"
-^ZZCOVERAGE("XINDX4","LO",4,"FOR_LOOP",1)=260
-^ZZCOVERAGE("XINDX4","LO",5)="260:0:0:0"
-^ZZCOVERAGE("XINDX4","LO",6)="260:0:0:0"
-^ZZCOVERAGE("XINDX4","LO",7)="260:0:0:0"
-^ZZCOVERAGE("XINDX4","LO",8)="89:0:0:0"
-^ZZCOVERAGE("XINDX4","LO",9)="89:0:0:0"
-^ZZCOVERAGE("XINDX4","LO",10)="89:4001:0:4001"
-^ZZCOVERAGE("XINDX4","LO",12)="259:0:0:0"
-^ZZCOVERAGE("XINDX4","LO",13)="259:0:0:0"
-^ZZCOVERAGE("XINDX4","LOOP")="14735:44003:108008:152011"
-^ZZCOVERAGE("XINDX4","LOOP",0)="14735:28002:72005:100007"
-^ZZCOVERAGE("XINDX4","LOOP",0,"FOR_LOOP",1)=68121
-^ZZCOVERAGE("XINDX4","LOOP",1)="14735:4000:32003:36003"
-^ZZCOVERAGE("XINDX4","PAREN")="2638:24000:36004:60004"
-^ZZCOVERAGE("XINDX4","PAREN",0)="2638:4000:8000:12000"
-^ZZCOVERAGE("XINDX4","PAREN",1)="2638:20000:16001:36001"
-^ZZCOVERAGE("XINDX4","PAREN",1,"FOR_LOOP",1)=50171
-^ZZCOVERAGE("XINDX4","PAREN",2)="2638:0:8002:8002"
-^ZZCOVERAGE("XINDX4","PAREN",3)="2638:0:0:0"
-^ZZCOVERAGE("XINDX4","PRUNE")="2186:8001:16001:24002"
-^ZZCOVERAGE("XINDX4","PRUNE",0)="2186:8001:4000:12001"
-^ZZCOVERAGE("XINDX4","PRUNE",1)="2186:0:8001:8001"
-^ZZCOVERAGE("XINDX4","PRUNE",1,"FOR_LOOP",1)=2186
-^ZZCOVERAGE("XINDX4","PRUNE",2)="2186:0:4000:4000"
-^ZZCOVERAGE("XINDX4","PRUNE",2,"FOR_LOOP",1)=2187
-^ZZCOVERAGE("XINDX4","PRUNE",3)="2186:0:0:0"
-^ZZCOVERAGE("XINDX4","Q",1)="747:8000:0:8000"
-^ZZCOVERAGE("XINDX4","Q",2)="747:0:0:0"
-^ZZCOVERAGE("XINDX4","QUOTE")="2402:28002:28000:56002"
-^ZZCOVERAGE("XINDX4","QUOTE",0)="2402:20002:20000:40002"
-^ZZCOVERAGE("XINDX4","QUOTE",0,"FOR_LOOP",1)=23674
-^ZZCOVERAGE("XINDX4","QUOTE",1)="2402:0:0:0"
-^ZZCOVERAGE("XINDX4","QUOTE",2)="2402:8000:4000:12000"
-^ZZCOVERAGE("XINDX4","ST")="8937:24000:16002:40002"
-^ZZCOVERAGE("XINDX4","ST",0)="8937:12000:8000:20000"
-^ZZCOVERAGE("XINDX4","ST",1)="8937:8000:8002:16002"
-^ZZCOVERAGE("XINDX4","WR",0)="4584:12001:12000:24001"
-^ZZCOVERAGE("XINDX4","WR",1)="4584:0:8000:8000"
-^ZZCOVERAGE("XINDX4","WR",2)="4584:72004:56006:128010"
-^ZZCOVERAGE("XINDX4","WR",2,"FOR_LOOP",1)=27607
-^ZZCOVERAGE("XINDX4","WR",3)="23023:8002:32003:40005"
-^ZZCOVERAGE("XINDX4","WR",4)="20835:12000:32001:44001"
-^ZZCOVERAGE("XINDX4","WR",5)="20835:24002:8001:32003"
-^ZZCOVERAGE("XINDX4","WR",6)="20835:24000:36002:60002"
-^ZZCOVERAGE("XINDX4","WR",7)="20835:0:0:0"
-^ZZCOVERAGE("XINDX4","WR",8)="4584:4000:0:4000"
-^ZZCOVERAGE("XINDX4","XE",0)="220:0:0:0"
-^ZZCOVERAGE("XINDX4","XE",1)="220:0:0:0"
-^ZZCOVERAGE("XINDX5","A",0)="468:0:4000:4000"
-^ZZCOVERAGE("XINDX5","A",1)="467:28002:24000:52002"
-^ZZCOVERAGE("XINDX5","A",1,"FOR_LOOP",1)=4011
-^ZZCOVERAGE("XINDX5","A",2)="467:0:0:0"
-^ZZCOVERAGE("XINDX5","AA")="3544:48004:68006:116010"
-^ZZCOVERAGE("XINDX5","AA",0)="3544:8002:16003:24005"
-^ZZCOVERAGE("XINDX5","AA",1)="1902:0:4000:4000"
-^ZZCOVERAGE("XINDX5","AA",2)="1902:4001:0:4001"
-^ZZCOVERAGE("XINDX5","AA",3)="1902:12001:4001:16002"
-^ZZCOVERAGE("XINDX5","AA",4)="1902:12000:32002:44002"
-^ZZCOVERAGE("XINDX5","AA",5)="1902:0:0:0"
-^ZZCOVERAGE("XINDX5","AA",6)="1209:0:0:0"
-^ZZCOVERAGE("XINDX5","AA",7)="1209:8000:4000:12000"
-^ZZCOVERAGE("XINDX5","AA",8)="1209:0:0:0"
-^ZZCOVERAGE("XINDX5","AA",9)="1642:0:4000:4000"
-^ZZCOVERAGE("XINDX5","AA",10)="1594:0:0:0"
-^ZZCOVERAGE("XINDX5","AA",11)="1594:4000:4000:8000"
-^ZZCOVERAGE("XINDX5","AA",12)="1642:0:0:0"
-^ZZCOVERAGE("XINDX5","B",0)="1:0:0:0"
-^ZZCOVERAGE("XINDX5","CLEAN",1)="1:0:0:0"
-^ZZCOVERAGE("XINDX5","CLEAN",2)="1:0:0:0"
-^ZZCOVERAGE("XINDX5","CLEAN",3)="1:0:0:0"
-^ZZCOVERAGE("XINDX5","END",0)="1:0:0:0"
-^ZZCOVERAGE("XINDX5","END",1)="1:0:0:0"
-^ZZCOVERAGE("XINDX5","END",2)="1:0:0:0"
-^ZZCOVERAGE("XINDX5","END",3)="1:0:0:0"
-^ZZCOVERAGE("XINDX5","VTAG")="4320:12000:16001:28001"
-^ZZCOVERAGE("XINDX5","VTAG",0)="4320:12000:8001:20001"
-^ZZCOVERAGE("XINDX5","VTAG",1)="4320:0:4000:4000"
-^ZZCOVERAGE("XINDX5","XINDX5",3)="1:0:0:0"
-^ZZCOVERAGE("XINDX5","XINDX5",4)="1:0:0:0"
-^ZZCOVERAGE("XINDX5","XINDX5",5)="1:0:0:0"
-^ZZCOVERAGE("XINDX5","XINDX5",7)="1:0:0:0"
-^ZZCOVERAGE("XINDX51","B")="1:0:4001:4001"
-^ZZCOVERAGE("XINDX51","B",0)="1:0:0:0"
-^ZZCOVERAGE("XINDX51","B",1)="1:0:0:0"
-^ZZCOVERAGE("XINDX51","B",3)="1:0:4001:4001"
-^ZZCOVERAGE("XINDX51","B",3,"FOR_LOOP",1)=468
-^ZZCOVERAGE("XINDX51","B",4)="1:0:0:0"
-^ZZCOVERAGE("XINDX51","B",6)="1:0:0:0"
-^ZZCOVERAGE("XINDX51","BHDR")="60:0:4000:4000"
-^ZZCOVERAGE("XINDX51","BHDR",0)="60:0:4000:4000"
-^ZZCOVERAGE("XINDX51","BHDR",1)="60:0:0:0"
-^ZZCOVERAGE("XINDX51","END",0)="1:0:0:0"
-^ZZCOVERAGE("XINDX51","HD")="60:0:0:0"
-^ZZCOVERAGE("XINDX51","HD",0)="60:0:0:0"
-^ZZCOVERAGE("XINDX51","HD",1)="60:0:0:0"
-^ZZCOVERAGE("XINDX51","HD1")="1:0:0:0"
-^ZZCOVERAGE("XINDX51","HD1",0)="1:0:0:0"
-^ZZCOVERAGE("XINDX51","HD1",1)="1:0:0:0"
-^ZZCOVERAGE("XINDX51","HD2")="60:4000:0:4000"
-^ZZCOVERAGE("XINDX51","HD2",0)="60:4000:0:4000"
-^ZZCOVERAGE("XINDX51","HD2",1)="60:0:0:0"
-^ZZCOVERAGE("XINDX51","WAIT")="1:0:0:0"
-^ZZCOVERAGE("XINDX51","WAIT",0)="1:0:0:0"
-^ZZCOVERAGE("XINDX51","WAIT",1)="1:0:0:0"
-^ZZCOVERAGE("XINDX51","WAIT",2)="1:0:0:0"
-^ZZCOVERAGE("XINDX51","WERR")="60:0:0:0"
-^ZZCOVERAGE("XINDX51","WERR",0)="60:0:0:0"
-^ZZCOVERAGE("XINDX51","WERR",1)="60:0:0:0"
-^ZZCOVERAGE("XINDX51","WERR",2)="60:0:0:0"
-^ZZCOVERAGE("XINDX51","WERR",2,"FOR_LOOP",1)=135
-^ZZCOVERAGE("XINDX51","WERR",3)="75:0:0:0"
-^ZZCOVERAGE("XINDX51","WERR",4)="75:0:0:0"
-^ZZCOVERAGE("XINDX51","WERR",5)="75:0:0:0"
-^ZZCOVERAGE("XINDX51","WERR",6)="75:0:0:0"
-^ZZCOVERAGE("XINDX51","WERR",7)="60:0:0:0"
-^ZZCOVERAGE("XINDX51","WORL")="70:0:0:0"
-^ZZCOVERAGE("XINDX51","WORL",0)="70:0:0:0"
-^ZZCOVERAGE("XINDX51","WORL",1)="70:0:0:0"
-^ZZCOVERAGE("XINDX51","WORL",2)="70:0:0:0"
-^ZZCOVERAGE("XINDX51","WORL",3)="70:0:0:0"
-^ZZCOVERAGE("XINDX51","WORL",3,"FOR_LOOP",1)=76
-^ZZCOVERAGE("XINDX51","WORL",4)="70:0:0:0"
-^ZZCOVERAGE("XINDX52","CASE")="2:0:0:0"
-^ZZCOVERAGE("XINDX52","CASE",0)="2:0:0:0"
-^ZZCOVERAGE("XINDX52","CASE",1)="2:0:0:0"
-^ZZCOVERAGE("XINDX6","ANS")="2:0:0:0"
-^ZZCOVERAGE("XINDX6","ANS",0)="2:0:0:0"
-^ZZCOVERAGE("XINDX6","ANS",1)="2:0:0:0"
-^ZZCOVERAGE("XINDX6","ANS",1,"FOR_LOOP",1)=2
-^ZZCOVERAGE("XINDX6","ANS",2)="2:0:0:0"
-^ZZCOVERAGE("XINDX6","ASKRTN")="1:4000:0:4000"
-^ZZCOVERAGE("XINDX6","ASKRTN",1)="1:0:0:0"
-^ZZCOVERAGE("XINDX6","ASKRTN",1,"FOR_LOOP",1)=468
-^ZZCOVERAGE("XINDX6","ASKRTN",2)="1:4000:0:4000"
-^ZZCOVERAGE("XINDX6","ASKRTN",2,"FOR_LOOP",1)=468
-^ZZCOVERAGE("XINDX6","ASKRTN",3)="1:0:0:0"
-^ZZCOVERAGE("XINDX6","DEVICE",0)="1:0:0:0"
-^ZZCOVERAGE("XINDX6","DEVICE",2)="1:0:0:0"
-^ZZCOVERAGE("XINDX6","DEVICE",3)="1:0:0:0"
-^ZZCOVERAGE("XINDX6","L7",0)="1:0:0:0"
-^ZZCOVERAGE("XINDX6","L7",1)="1:0:0:0"
-^ZZCOVERAGE("XINDX6","NY")="1:0:0:0"
-^ZZCOVERAGE("XINDX6","NY",0)="1:0:0:0"
-^ZZCOVERAGE("XINDX6","PARAM")="1:0:0:0"
-^ZZCOVERAGE("XINDX6","PARAM",1)="1:0:0:0"
-^ZZCOVERAGE("XINDX6","PARAM",2)="1:0:0:0"
-^ZZCOVERAGE("XINDX6","PARAM",2,"FOR_LOOP",1)=10
-^ZZCOVERAGE("XINDX6","PARAM",3)="1:0:0:0"
-^ZZCOVERAGE("XINDX6","PARAM",4)="1:0:0:0"
-^ZZCOVERAGE("XINDX6","PARAM",5)="1:0:0:0"
-^ZZCOVERAGE("XINDX6","PARAM",6)="1:0:0:0"
-^ZZCOVERAGE("XINDX6","PARAM",7)="1:0:0:0"
-^ZZCOVERAGE("XINDX6","RD")="2:0:0:0"
-^ZZCOVERAGE("XINDX6","RD",0)="2:0:0:0"
-^ZZCOVERAGE("XINDX6","XINDX6",5)="1:0:0:0"
-^ZZCOVERAGE("XINDX6","XINDX6",6)="1:0:0:0"
-^ZZCOVERAGE("XINDX6","XINDX6",7)="1:0:0:0"
-^ZZCOVERAGE("XINDX6","XINDX6",8)="1:0:0:0"
-^ZZCOVERAGE("XINDX6","XINDX6",9)="1:0:0:0"
-^ZZCOVERAGE("XINDX6","XINDX6",10)="1:0:0:0"
-^ZZCOVERAGE("XINDX6","XINDX6",11)="1:0:0:0"
-^ZZCOVERAGE("XINDX6","XINDX6",12)="1:0:0:0"
-^ZZCOVERAGE("XINDX6","XINDX6",13)="1:0:0:0"
-^ZZCOVERAGE("XINDX6","YN")="1:0:0:0"
-^ZZCOVERAGE("XINDX6","YN",0)="1:0:0:0"
-^ZZCOVERAGE("XINDX7","BUILD")="1:0:0:0"
-^ZZCOVERAGE("XINDX7","BUILD",0)="1:0:0:0"
-^ZZCOVERAGE("XINDX7","BUILD",1)="1:0:0:0"
-^ZZCOVERAGE("XINDX7","BUILD",1,"FOR_LOOP",1)=10
-^ZZCOVERAGE("XINDX7","BUILD",2)="9:0:0:0"
-^ZZCOVERAGE("XINDX7","BUILD",3)="6:0:0:0"
-^ZZCOVERAGE("XINDX7","BUILD",3,"FOR_LOOP",1)=85
-^ZZCOVERAGE("XINDX7","BUILD",4)="79:0:0:0"
-^ZZCOVERAGE("XINDX7","BUILD",5)="79:0:0:0"
-^ZZCOVERAGE("XINDX7","BUILD",6)="6:0:0:0"
-^ZZCOVERAGE("XINDX7","BUILD",7)="1:0:0:0"
-^ZZCOVERAGE("XINDX7","HDR")="2:0:0:0"
-^ZZCOVERAGE("XINDX7","HDR",0)="2:0:0:0"
-^ZZCOVERAGE("XINDX7","HDR",1)="2:0:0:0"
-^ZZCOVERAGE("XINDX7","HDR",2)="1:0:0:0"
-^ZZCOVERAGE("XINDX7","HDR",3)="1:0:0:0"
-^ZZCOVERAGE("XINDX7","HDR",4)="1:0:0:0"
-^ZZCOVERAGE("XINDX7","HDR",5)="1:0:0:0"
-^ZZCOVERAGE("XINDX7","HDR",6)="2:0:0:0"
-^ZZCOVERAGE("XINDX7","HDR",7)="2:0:0:0"
-^ZZCOVERAGE("XINDX7","SETUP")="1:0:0:0"
-^ZZCOVERAGE("XINDX7","SETUP",1)="1:0:0:0"
-^ZZCOVERAGE("XINDX7","SETUP",2)="1:0:0:0"
-^ZZCOVERAGE("XINDX7","SETUP",3)="1:0:0:0"
-^ZZCOVERAGE("XINDX7","SETUP",4)="1:0:0:0"
-^ZZCOVERAGE("XINDX7","SETUP",6)="1:0:0:0"
-^ZZCOVERAGE("XINDX7","SETUP",7)="1:0:0:0"
-^ZZCOVERAGE("XINDX7","SETUP",7,"FOR_LOOP",1)=468
-^ZZCOVERAGE("XINDX7","SETUP",8)="1:0:0:0"
-^ZZCOVERAGE("XINDX7","SETUP",9)="1:0:0:0"
-^ZZCOVERAGE("XINDX7","SETUP",10)="1:0:0:0"
-^ZZCOVERAGE("XINDX9","ADD")="406841:436032:684041:1120073"
-^ZZCOVERAGE("XINDX9","ADD",0)="598820:552042:692040:1244082"
-^ZZCOVERAGE("XINDX9","AR")="197699:748039:1052073:1800112"
-^ZZCOVERAGE("XINDX9","AR",0)="197699:708036:936061:1644097"
-^ZZCOVERAGE("XINDX9","CASE")="23461:28003:92005:120008"
-^ZZCOVERAGE("XINDX9","CASE",0)="23461:12002:48003:60005"
-^ZZCOVERAGE("XINDX9","CASE",1)="23461:12001:28000:40001"
-^ZZCOVERAGE("XINDX9","DN")="45002:204010:248016:452026"
-^ZZCOVERAGE("XINDX9","DN",0)="45002:176008:196011:372019"
-^ZZCOVERAGE("XINDX9","DN",1)="45002:16001:24003:40004"
-^ZZCOVERAGE("XINDX9","EXT",1)="1970:4000:12001:16001"
-^ZZCOVERAGE("XINDX9","FNC")="29146:96005:104009:200014"
-^ZZCOVERAGE("XINDX9","FNC",0)="29146:28001:20003:48004"
-^ZZCOVERAGE("XINDX9","FNC",1)="29146:44002:72005:116007"
-^ZZCOVERAGE("XINDX9","FNC",2)="12:0:0:0"
-^ZZCOVERAGE("XINDX9","FNC",3)="12:0:0:0"
-^ZZCOVERAGE("XINDX9","FUNC")="29134:284015:400024:684039"
-^ZZCOVERAGE("XINDX9","FUNC",1)="29134:112005:120007:232012"
-^ZZCOVERAGE("XINDX9","FUNC",2)="23461:48003:72004:120007"
-^ZZCOVERAGE("XINDX9","FUNC",3)="23461:20000:32001:52001"
-^ZZCOVERAGE("XINDX9","FX",0)="23461:68004:116009:184013"
-^ZZCOVERAGE("XINDX9","GVAR")="29134:96004:180015:276019"
-^ZZCOVERAGE("XINDX9","GVAR",0)="29134:28000:44003:72003"
-^ZZCOVERAGE("XINDX9","GVAR",1)="29134:32001:72005:104006"
-^ZZCOVERAGE("XINDX9","GVAR",2)="29134:16000:24002:40002"
-^ZZCOVERAGE("XINDX9","INC")="29134:64003:64007:128010"
-^ZZCOVERAGE("XINDX9","INC",0)="29134:20001:12001:32002"
-^ZZCOVERAGE("XINDX9","INC",1)="29134:32002:40004:72006"
-^ZZCOVERAGE("XINDX9","NEW")="287703:532032:660032:1192064"
-^ZZCOVERAGE("XINDX9","NEW",0)="287703:200012:244014:444026"
-^ZZCOVERAGE("XINDX9","NEW",1)="287703:220014:248008:468022"
-^ZZCOVERAGE("XINDX9","NUM")="45379:292023:340026:632049"
-^ZZCOVERAGE("XINDX9","NUM",0)="45379:92006:84006:176012"
-^ZZCOVERAGE("XINDX9","NUM",0,"FOR_LOOP",1)=71145
-^ZZCOVERAGE("XINDX9","NUM",1)="45379:40005:48002:88007"
-^ZZCOVERAGE("XINDX9","NUM",2)="45379:40004:56005:96009"
-^ZZCOVERAGE("XINDX9","NUM",3)="45379:76003:88008:164011"
-^ZZCOVERAGE("XINDX9","NUM",4)="45379:24003:40003:64006"
-^ZZCOVERAGE("XINDX9","PA2",0)="518346:544028:668032:1212060"
-^ZZCOVERAGE("XINDX9","PA2",1)="472665:532043:620035:1152078"
-^ZZCOVERAGE("XINDX9","PA2",2)="317803:264019:292021:556040"
-^ZZCOVERAGE("XINDX9","PA2",3)="317803:200013:324018:524031"
-^ZZCOVERAGE("XINDX9","PA2",4)="307072:348020:492025:840045"
-^ZZCOVERAGE("XINDX9","PA2",5)="197397:160015:296011:456026"
-^ZZCOVERAGE("XINDX9","PA2",6)="152018:120016:132005:252021"
-^ZZCOVERAGE("XINDX9","PA2",7)="152018:116009:112008:228017"
-^ZZCOVERAGE("XINDX9","PA2",8)="151813:96008:168010:264018"
-^ZZCOVERAGE("XINDX9","PA2",9)="151813:100008:172009:272017"
-^ZZCOVERAGE("XINDX9","PA2",10)="151813:220008:324022:544030"
-^ZZCOVERAGE("XINDX9","PA2",11)="151813:168011:152010:320021"
-^ZZCOVERAGE("XINDX9","PA2",12)="151813:128009:148012:276021"
-^ZZCOVERAGE("XINDX9","PA2",13)="151813:136005:104009:240014"
-^ZZCOVERAGE("XINDX9","PARSE")="45681:3356226:4340257:7696483"
-^ZZCOVERAGE("XINDX9","PARSE",0)="45681:104007:108007:212014"
-^ZZCOVERAGE("XINDX9","PAT")="205:0:0:0"
-^ZZCOVERAGE("XINDX9","PAT",0)="205:0:0:0"
-^ZZCOVERAGE("XINDX9","PAT",1)="205:0:0:0"
-^ZZCOVERAGE("XINDX9","PAT",1,"FOR_LOOP",1)=1185
-^ZZCOVERAGE("XINDX9","PAT",2)="205:0:0:0"
-^ZZCOVERAGE("XINDX9","PAT",3)="205:0:0:0"
-^ZZCOVERAGE("XINDX9","PAT",4)="205:0:0:0"
-^ZZCOVERAGE("XINDX9","PATC")="28:0:0:0"
-^ZZCOVERAGE("XINDX9","PATC",0)="28:0:0:0"
-^ZZCOVERAGE("XINDX9","PATQ")="99:0:8000:8000"
-^ZZCOVERAGE("XINDX9","PATQ",0)="99:0:0:0"
-^ZZCOVERAGE("XINDX9","PATQ",0,"FOR_LOOP",1)=247
-^ZZCOVERAGE("XINDX9","PATQ",1)="99:0:0:0"
-^ZZCOVERAGE("XINDX9","PATQ",2)="99:0:8000:8000"
-^ZZCOVERAGE("XINDX9","PATU")="15:0:0:0"
-^ZZCOVERAGE("XINDX9","PATU",0)="15:0:0:0"
-^ZZCOVERAGE("XINDX9","PEND",0)="45681:68001:140014:208015"
-^ZZCOVERAGE("XINDX9","PEND",1)="45681:36004:52005:88009"
-^ZZCOVERAGE("XINDX9","QUOTE")="35724:244013:304019:548032"
-^ZZCOVERAGE("XINDX9","QUOTE",0)="36272:172010:140009:312019"
-^ZZCOVERAGE("XINDX9","QUOTE",0,"FOR_LOOP",1)=323021
-^ZZCOVERAGE("XINDX9","QUOTE",1)="36272:28001:72004:100005"
-^ZZCOVERAGE("XINDX9","QUOTE",2)="35724:28001:24003:52004"
-^ZZCOVERAGE("XINDX9","QUOTE",3)="35724:16001:52002:68003"
-^ZZCOVERAGE("XINDX9","SPV",0)="3703:4000:12000:16000"
-^ZZCOVERAGE("XINDX9","SPV",1)="3703:8001:4000:12001"
-^ZZCOVERAGE("XINDX9","SPV",2)="3703:8001:4000:12001"
-^ZZCOVERAGE("XINDX9","SPV",3)="3703:4000:8001:12001"
-^ZZCOVERAGE("XINDX9","STR")="287703:560037:724043:1284080"
-^ZZCOVERAGE("XINDX9","STR",0)="287703:300018:312020:612038"
-^ZZCOVERAGE("XINDX9","SUM")="213322:612034:916052:1528086"
-^ZZCOVERAGE("XINDX9","SUM",0)="213322:160009:208011:368020"
-^ZZCOVERAGE("XINDX9","SUM",1)="213322:212007:280018:492025"
-^ZZCOVERAGE("XINDX9","SUM",2)="213322:136012:268012:404024"
-^ZZCOVERAGE("XINDX9","UP")="45002:396026:440029:836055"
-^ZZCOVERAGE("XINDX9","UP",0)="45002:24003:44001:68004"
-^ZZCOVERAGE("XINDX9","UP",1)="45002:180008:192016:372024"
-^ZZCOVERAGE("XINDX9","UP",2)="45002:136010:128005:264015"
-^ZZCOVERAGE("XINDX9","UP",3)="45002:40003:52003:92006"
-^ZZCOVERAGE("XINDX9","VAR")="138809:828044:1004072:1832116"
-^ZZCOVERAGE("XINDX9","VAR",0)="138809:376018:336017:712035"
-^ZZCOVERAGE("XINDX9","VAR",0,"FOR_LOOP",1)=462128
-^ZZCOVERAGE("XINDX9","VAR",1)="138809:292018:376034:668052"
-^ZZCOVERAGE("XINDX9","VAR",2)="138809:116003:144008:260011"
-^ZZCOVERAGE("XINDX9","XINDX9")="45681:296016:320021:616037"
-^ZZCOVERAGE("XINDX9","XINDX9",3)="45681:52003:128006:180009"
-^ZZCOVERAGE("XINDX9","XINDX9",4)="45681:164006:112008:276014"
-^ZZCOVERAGE("XINDX9","XINDX9",4,"FOR_LOOP",1)=128269
-^ZZCOVERAGE("XINDX9","XINDX9",5)="45681:48004:52005:100009"
-^ZZCOVERAGE("XLFDT","DT")="1:0:0:0"
-^ZZCOVERAGE("XLFDT","DT",0)="1:0:0:0"
-^ZZCOVERAGE("XLFDT","DT",1)="1:0:0:0"
-^ZZCOVERAGE("XLFDT","HR")="3:0:0:0"
-^ZZCOVERAGE("XLFDT","HR",0)="3:0:0:0"
-^ZZCOVERAGE("XLFDT","HR",1)="3:0:0:0"
-^ZZCOVERAGE("XLFDT","HTE")="1:0:0:0"
-^ZZCOVERAGE("XLFDT","HTE",0)="1:0:0:0"
-^ZZCOVERAGE("XLFDT","HTE",1)="1:0:0:0"
-^ZZCOVERAGE("XLFDT","HTE",2)="1:0:0:0"
-^ZZCOVERAGE("XLFDT","HTE",3)="1:0:0:0"
-^ZZCOVERAGE("XLFDT","HTFM")="2:0:0:0"
-^ZZCOVERAGE("XLFDT","HTFM",0)="2:0:0:0"
-^ZZCOVERAGE("XLFDT","HTFM",1)="2:0:0:0"
-^ZZCOVERAGE("XLFDT","HTFM",2)="2:0:0:0"
-^ZZCOVERAGE("XLFDT","HTFM",3)="2:0:0:0"
-^ZZCOVERAGE("XLFDT","HTFM",4)="2:0:0:0"
-^ZZCOVERAGE("XLFDT","HTFM",5)="2:0:0:0"
-^ZZCOVERAGE("XLFDT","T2",0)="1:0:0:0"
-^ZZCOVERAGE("XLFDT","T2",1)="1:0:0:0"
-^ZZCOVERAGE("XLFDT","YMD")="2:0:0:0"
-^ZZCOVERAGE("XLFDT","YMD",1)="2:0:0:0"
-^ZZCOVERAGE("XLFDT","YMD",2)="2:0:0:0"
-^ZZCOVERAGE("XLFDT","YMD",3)="2:0:0:0"
-^ZZCOVERAGE("XLFDT","YMD",4)="2:0:0:0"
-^ZZCOVERAGE("XLFDT","YMD",5)="2:0:0:0"
-^ZZCOVERAGE("XLFDT1","F1",1)="1:0:0:0"
-^ZZCOVERAGE("XLFDT1","FMT")="1:0:0:0"
-^ZZCOVERAGE("XLFDT1","FMT",1)="1:0:0:0"
-^ZZCOVERAGE("XLFDT1","FMT",2)="1:0:0:0"
-^ZZCOVERAGE("XLFDT1","M")="1:0:0:0"
-^ZZCOVERAGE("XLFDT1","M",0)="1:0:0:0"
-^ZZCOVERAGE("XLFDT1","TM",1)="1:0:0:0"
-^ZZCOVERAGE("XLFDT1","TM",2)="1:0:0:0"
-^ZZCOVERAGE("XLFDT1","TM",3)="1:0:0:0"
-^ZZCOVERAGE("XLFDT1","TM",7)="1:0:0:0"
-^ZZCOVERAGE("XPDRSUM","SUMB")="467:1808124:180014:1988138"
-^ZZCOVERAGE("XPDRSUM","SUMB",0)="467:8000:0:8000"
-^ZZCOVERAGE("XPDRSUM","SUMB",2)="467:0:0:0"
-^ZZCOVERAGE("XPDRSUM","SUMB",3)="467:1796124:180014:1976138"
-^ZZCOVERAGE("XPDRSUM","SUMB",3,"FOR_LOOP",1)=44620
-^ZZCOVERAGE("XPDRSUM","SUMB",3,"FOR_LOOP",2)=1566704
-^ZZCOVERAGE("XPDRSUM","SUMB",4)="467:0:0:0"
-^ZZCOVERAGE("XTRUTL1","BUILD")="1:0:0:0"
-^ZZCOVERAGE("XTRUTL1","BUILD",0)="1:0:0:0"
-^ZZCOVERAGE("XTRUTL1","BUILD",1)="1:0:0:0"
-^ZZCOVERAGE("XTRUTL1","BUILD",2)="1:0:0:0"
-^ZZCOVERAGE("XTRUTL1","BUILD",3)="1:0:0:0"
-
-
diff --git a/Tests/MumpsCoverage/VistA-FOIA/Packages/Toolkit/Routines/XINDEX.m b/Tests/MumpsCoverage/VistA-FOIA/Packages/Toolkit/Routines/XINDEX.m
deleted file mode 100644
index b04522151..000000000
--- a/Tests/MumpsCoverage/VistA-FOIA/Packages/Toolkit/Routines/XINDEX.m
+++ /dev/null
@@ -1,144 +0,0 @@
-XINDEX ;ISC/REL,GFT,GRK,RWF - INDEX & CROSS-REFERENCE ;08/04/08 13:19
- ;;7.3;TOOLKIT;**20,27,48,61,66,68,110,121,128**;Apr 25, 1995;Build 1
- ; Per VHA Directive 2004-038, this routine should not be modified.
- G ^XINDX6
-SEP F I=1:1 S CH=$E(LIN,I) D QUOTE:CH=Q Q:" "[CH
- S ARG=$E(LIN,1,I-1) S:CH=" " I=I+1 S LIN=$E(LIN,I,999) Q
-QUOTE F I=I+1:1 S CH=$E(LIN,I) Q:CH=""!(CH=Q)
- Q:CH]"" S ERR=6 G ^XINDX1
-ALIVE ;enter here from taskman
- D SETUP^XINDX7 ;Get ready to process
-A2 S RTN=$O(^UTILITY($J,RTN)) G ^XINDX5:RTN=""
- S INDLC=(RTN?1"|"1.4L.NP) D LOAD:'INDLC
- I $D(ZTQUEUED),$$S^%ZTLOAD S RTN="~",IND("QUIT")=1,ZTSTOP=1 G A2
- I 'INDDS,INDLC W !!?10,"Data Dictionaries",! S INDDS=1
- D BEG
- G A2
- ;
-LOAD S X=RTN,XCNP=0,DIF="^UTILITY("_$J_",1,RTN,0," X ^%ZOSF("TEST") Q:'$T X ^%ZOSF("LOAD") S ^UTILITY($J,1,RTN,0,0)=XCNP-1
- I $D(^UTILITY($J,1,RTN,0,0)) S ^UTILITY($J,1,RTN,"RSUM")="B"_$$SUMB^XPDRSUM($NA(^UTILITY($J,1,RTN,0)))
- Q
-BEG ;
- S %=INDLC*5 W:$X+10+%>IOM ! W RTN,$J("",10+%-$L(RTN))
- S (IND("DO"),IND("SZT"),IND("SZC"),LABO)=0,LC=$G(^UTILITY($J,1,RTN,0,0))
- I LC="" W !,">>>Routine '",RTN,"' not found <<<",! Q
- S TXT="",LAB=$P(^UTILITY($J,1,RTN,0,1,0)," ") I RTN'=$P(LAB,"(") D E^XINDX1(17)
- I 'INDLC,LAB["(" D E^XINDX1(55) S LAB=$P(LAB,"(")
- ;if M routine(not compiled template or DD) and has more than 2 lines, check lines 1 & 2
- I 'INDLC,LC>2 D
- . N LABO S LABO=1
- . S LIN=$G(^UTILITY($J,1,RTN,0,1,0)),TXT=1
- . ;check 1st line (site/dev - ) patch 128
- . I $P(LIN,";",2,4)'?.E1"/".E.1"-".E D E^XINDX1(62)
- . S LIN=$G(^UTILITY($J,1,RTN,0,2,0)),TXT=2
- . ;check 2nd line (;;nn.nn[TV]nn;package;.anything)
- . I $P(LIN,";",3,99)'?1.2N1"."1.2N.1(1"T",1"V").2N1";"1A.AP1";".E D E^XINDX1(44) ;patch 121
- . I $L(INP(11)) X INP(11) ;Version number check
- . I $L(INP(12)) X INP(12) ;Patch number check
-B5 F TXT=1:1:LC S LIN=^UTILITY($J,1,RTN,0,TXT,0),LN=$L(LIN),IND("SZT")=IND("SZT")+LN+2 D LN,ST ;Process Line
- S LAB="",LABO=0,TXT=0,^UTILITY($J,1,RTN,0)=IND("SZT")_"^"_LC_"^"_IND("SZC")
- I IND("SZT")>INP("MAX"),'INDLC S ERR=35,ERR(1)=IND("SZT") D ^XINDX1
- I IND("SZT")-IND("SZC")>INP("CMAX"),'INDLC S ERR=58,ERR(1)=IND("SZT")-IND("SZC") D ^XINDX1
- D POSTRTN
- Q
- ;Proccess one line, LN = Length, LIN = Line.
-LN K V S (ARG,GRB,IND("COM"),IND("DOL"),IND("F"))="",X=$P(LIN," ")
- I '$L(X) S LABO=LABO+1 G CD
- S (IND("COM"),LAB)=$P(X,"("),ARG=$P($P(X,"(",2),")"),LABO=0,IND("PP")=X?1.8E1"(".E1")"
- D:$L(ARG) NE^XINDX3 ;Process formal parameters as New list.
- I 'INDLC,'$$VT^XINDX2(LAB) D E^XINDX1($S(LAB=$$CASE^XINDX52(LAB):37,1:55)) ;Check for bad labels
- I $D(^UTILITY($J,1,RTN,"T",LAB)) D E^XINDX1(15) G CD ;DUP label
- S ^UTILITY($J,1,RTN,"T",LAB)=""
-CD I LN>245 D:'(LN=246&($E(RTN,1,3)="|dd")) E^XINDX1(19) ;patch 119
- D:LIN'?1.ANP E^XINDX1(18)
- S LIN=$P(LIN," ",2,999),IND("LCC")=1
- I LIN="" D E^XINDX1(42) Q ;Blank line ;p110
- S I=0 ;Watch the scope of I, counts dots
- I " ."[$E(LIN) D S X=$L($E(LIN,1,I),".")-1,LIN=$E(LIN,I,999)
- . F I=1:1:245 Q:". "'[$E(LIN,I)
- . Q
- ;check dots against Do level IND("DO"), IND("DOL")=dot level
- D:'I&$G(IND("DO1")) E^XINDX1(51) S IND("DO1")=0 S:'I IND("DO")=0
- I I D:X>IND("DO") E^XINDX1(51) S (IND("DO"),IND("DOL"))=X
- ;Count Comment lines, skip ;; lines
- I $E(LIN)=";",$E(LIN,2)'=";" S IND("SZC")=IND("SZC")+$L(LIN) ;p110
- ;Process commands on line.
-EE I LIN="" D ^XINDX2 Q
- S COM=$E(LIN),GK="",ARG=""
- I COM=";" S LIN="" G EE ;p110
- I COM=" " S ERR=$S(LIN?1." ":13,1:0),LIN=$S(ERR:"",1:$E(LIN,2,999)) D:ERR ^XINDX1 G EE
- D SEP
- S CM=$P(ARG,":",1),POST=$P(ARG,":",2,999),IND("COM")=IND("COM")_$C(9)_COM,ERR=48
- D:ARG[":"&(POST']"") ^XINDX1 S:POST]"" GRB=GRB_$C(9)_POST,IND("COM")=IND("COM")_":"
- ;SAC now allows lowercase commands
- I CM?.E1L.E S CM=$$CASE^XINDX52(CM),COM=$E(CM) ;I IND("LCC") S IND("LCC")=0 D E^XINDX1(47)
- I CM="" D E^XINDX1(21) G EE ;Missing command
- S CX=$G(IND("CMD",CM)) I CX="" D G:CX="" EE
- . I $E(CM)="Z" S CX="^Z" Q ;Proccess Z commands
- . D E^XINDX1(1) S LIN="" Q
- S CX=$P(CX,"^",2,9)
- D SEP I '$L(LIN),CH=" " D E^XINDX1(13) ;trailing space
- I ARG="","CGJMORSUWX"[COM S ERR=49 G ^XINDX1
- I CX>0 D E^XINDX1(CX) S CX=""
- D:$L(CX) @CX S:ARG'="" GRB=GRB_$C(9)_ARG G EE
-B S ERR=25 G ^XINDX1
-C S ERR=29 G ^XINDX1
-D G DG1^XINDX4
-E Q:ARG="" S ERR=7 G ^XINDX1
-F G:ARG]"" FR^XINDX4 S IND("F")=1 Q
-G G DG^XINDX4
-H Q:ARG'="" S ERR=32 G ^XINDX1
-J S ERR=36,ARG="" G ^XINDX1
-K S ERR=$S(ARG?1"(".E:22,ARG?." ":23,1:0) D:ERR ^XINDX1
- G KL^XINDX3
-L G LO^XINDX4
-M G S^XINDX3
-N G NE^XINDX3
-O S ERR=34 D ^XINDX1,O^XINDX3 Q
-Q Q:ARG="" G Q^XINDX4
-R S RDTIME=0 G RD^XINDX3
-S G S^XINDX3
-TR Q ;What to process. p110
-U S ARG=$P(ARG,":") Q
-V S ARG="",ERR=20 G ^XINDX1
-W G WR^XINDX4
-X G XE^XINDX4
-Z S ERR=2 D ^XINDX1 G ZC^XINDX4
- ;
- ;Save off items from line.
-ST S R=LAB_$S(LABO:"+"_LABO,1:"")
- ;Local variable, Global, Marked Items, Naked global, Internal ref, eXternal ref., Tag ref.
- S LOC="" F S LOC=$O(V(LOC)),S="" Q:LOC="" F S S=$O(V(LOC,S)) Q:S="" D SET
- S ^UTILITY($J,1,RTN,"COM",TXT)=IND("COM")
- Q
- ;
-SET I V(LOC,S)]"" F %="!","~" I V(LOC,S)[%,$G(^UTILITY($J,1,RTN,LOC,S))'[% S ^(S)=$G(^(S))_%
- S %=0
-SE2 S ARG=$G(^UTILITY($J,1,RTN,LOC,S,%)) I $L(ARG)>230 S %=%+1 G SE2
- S ^UTILITY($J,1,RTN,LOC,S,%)=ARG_R_V(LOC,S)_","
- Q
- ;
-POSTRTN ;Do more overall checking
- N V,E,T,T1,T2
- S T="" ;Check for missing Labels
- F S T=$O(^UTILITY($J,1,RTN,"I",T)),T2=T Q:T="" S T1=$G(^(T,0)) D
- . Q:$E(T2,1,2)="@("
- . S:$E(T2,1,2)="$$" T2=$E(T2,3,99)
- . I T2]"",'$D(^UTILITY($J,1,RTN,"T",$P(T2,"+",1))) D
- . . F I=1:1:$L(T1,",")-1 S LAB=$P(T1,",",I),LABO=+$P(LAB,"+",2),LAB=$P(LAB,"+"),E=14,E(1)=T D E^XINDX1(.E)
- . . Q
- . Q
- S LAB="",LABO=0 ;Check for valid label names
- I 'INDLC F S LAB=$O(^UTILITY($J,1,RTN,"T",LAB)) Q:LAB="" D
- . I '$$VA^XINDX2(LAB) D E^XINDX1(55) Q
- . D:'$$VT^XINDX2(LAB) E^XINDX1(37)
- . Q
- S LAB="",LABO=0 ;Check for valid variable names.
- F S LAB=$O(^UTILITY($J,1,RTN,"L",LAB)) Q:LAB="" D
- . D VLNF^XINDX3($P(LAB,"("))
- . Q
- Q
- ;
-QUICK ;Quick, Just get a routine an print the results
- D QUICK^XINDX6()
- Q
diff --git a/Tests/MumpsCoverage/VistA-FOIA/Packages/Uncategorized/ZZCOVTST.m b/Tests/MumpsCoverage/VistA-FOIA/Packages/Uncategorized/ZZCOVTST.m
new file mode 100644
index 000000000..ee7068240
--- /dev/null
+++ b/Tests/MumpsCoverage/VistA-FOIA/Packages/Uncategorized/ZZCOVTST.m
@@ -0,0 +1,43 @@
+ZZCOVTST;OSEHRA/JPS -- Test routine for Coverage Parsing;4/28/2014
+ ; (tab) This is series of comments
+ ; (tab) it should all be not executable
+ ; (spaces) one of these sets might be a problem
+ ; (spaces) we will have to see.
+EN ; This entry point shouldn't be found without fixing
+ N D
+ S D=1 ;An executable line
+ D T1^ZZCOVTST
+ I '$$T5 W "RETURNED FROM t5",!
+ Q
+ ; This line not executable
+ D T6^ZZCOVTST
+ ;
+T1 ; This line should always be found
+ N D
+ S D=2
+ W !,D,!,"This is the second entry point",!
+ D T2^ZZCOVTST(D)
+ Q
+ ;
+T2(EQ) ; This is debatable and only called with ENT^ROU notation
+ N D
+ S D=3
+ W !,D,!,EQ,"This is the third entry point",!
+ D T3^ZZCOVTST
+ Q
+ ;
+T3 N D S D=4 W D,!,"Fourth Entry point",! Q
+ ;
+T4 N D S D=5 W "Shouldn't be executed"
+ W "Lots to not do"
+ Q
+T5(EQ) ;this entry point is called with a $$ notation
+ W "THIS IS THE $$ NOTATION!",!
+ Q 0
+T6 ; An entry point to show comments inside of "DO" blocks
+ D
+ . W "This is executable code",!
+ . ;This is a comment inside the do block, not executable
+ . S ZZBLAH="blah"
+ W "Ending T6",!
+ ;
diff --git a/Tests/MumpsCoverage/ZZCOVTST.cmcov b/Tests/MumpsCoverage/ZZCOVTST.cmcov
new file mode 100644
index 000000000..7a5df6105
--- /dev/null
+++ b/Tests/MumpsCoverage/ZZCOVTST.cmcov
@@ -0,0 +1,45 @@
+Routine,Line,RtnLine,Code
+ZZCOVTST,1,1,"ZZCOVTST;OSEHRA/JPS -- Test routine for Coverage Parsing;4/28/2014"
+,2,0," ; (tab) This is series of comments"
+,3,0," ; (tab) it should all be not executable"
+,4,0," ; (spaces) one of these sets might be a problem"
+,5,0," ; (spaces) we will have to see."
+,6,0,"EN ; This entry point shouldn't be found without fixing"
+,7,1," N D"
+,8,1," S D=1 ;An executable line"
+,9,1," D T1^ZZCOVTST"
+,10,1," I '$$T5 W ""RETURNED FROM t5"",!"
+,11,1," D T6^ZZCOVTST"
+,12,1," Q"
+,13,0," ; This line not executable"
+,14,0," ;"
+,15,0,"T1 ; This line should always be found"
+,16,1," N D"
+,17,1," S D=2"
+,18,1," W !,D,!,""This is the second entry point"",!"
+,19,1," D T2^ZZCOVTST(D)"
+,20,1," Q"
+,21,0," ;"
+,22,0,"T2(EQ) ; This is debatable and only called with ENT^ROU notation"
+,23,1," N D"
+,24,1," S D=3"
+,25,1," W !,D,!,EQ,""This is the third entry point"",!"
+,26,1," D T3^ZZCOVTST"
+,27,1," Q"
+,28,0," ;"
+,29,1,"T3 N D S D=4 W D,!,""Fourth Entry point"",! Q"
+,30,0," ;"
+,31,0,"T4 N D S D=5 W ""Shouldn't be executed"""
+,32,0," W ""Lots to not do"""
+,33,0," Q"
+,34,1,"T5(EQ) ;this entry point is called with a $$ notation"
+,35,1," W ""THIS IS THE $$ NOTATION!"",!"
+,36,1," Q 0"
+,37,0,"T6 ; An entry point to show comments inside of ""DO"" blocks"
+,38,1," D"
+,39,1," . W ""This is executable code"",!"
+,40,0," . ; This is a comment inside the do block, not executable"
+,41,1," . S ZZBLAH=""blah"""
+,42,1," W ""Ending T6"",!"
+,43,0," ;"
+Totals for ZZCOVTST,,25, \ No newline at end of file
diff --git a/Tests/MumpsCoverage/ZZCOVTST.mcov b/Tests/MumpsCoverage/ZZCOVTST.mcov
new file mode 100644
index 000000000..b2608d952
--- /dev/null
+++ b/Tests/MumpsCoverage/ZZCOVTST.mcov
@@ -0,0 +1,38 @@
+%GO Global Output Utility
+GT.M 15-AUG-2014 10:14:32 ZWR
+^ZZCOVERAGE("*CHILDREN")="212000:68000:280000"
+^ZZCOVERAGE("*RUN")="56000:136000:192000"
+^ZZCOVERAGE("ZZCOVTST","EN")="1:4000:4000:8000:8627798"
+^ZZCOVERAGE("ZZCOVTST","EN",1)="1:0:0:0:27"
+^ZZCOVERAGE("ZZCOVTST","EN",2)="1:0:0:0:23"
+^ZZCOVERAGE("ZZCOVTST","EN",3)="1:0:0:0:70"
+^ZZCOVERAGE("ZZCOVTST","EN",4)="1:0:0:0:74"
+^ZZCOVERAGE("ZZCOVTST","EN",5)="1:0:0:0:66"
+^ZZCOVERAGE("ZZCOVTST","EN",6)="1:0:0:0:40"
+^ZZCOVERAGE("ZZCOVTST","T1")="1:0:0:0:208"
+^ZZCOVERAGE("ZZCOVTST","T1",1)="1:0:0:0:23"
+^ZZCOVERAGE("ZZCOVTST","T1",2)="1:0:0:0:24"
+^ZZCOVERAGE("ZZCOVTST","T1",3)="1:0:0:0:26"
+^ZZCOVERAGE("ZZCOVTST","T1",4)="1:0:0:0:73"
+^ZZCOVERAGE("ZZCOVTST","T1",5)="1:0:0:0:40"
+^ZZCOVERAGE("ZZCOVTST","T2")="1:0:0:0:1783"
+^ZZCOVERAGE("ZZCOVTST","T2",0)="1:0:0:0:25"
+^ZZCOVERAGE("ZZCOVTST","T2",1)="1:0:0:0:524"
+^ZZCOVERAGE("ZZCOVTST","T2",2)="1:0:0:0:40"
+^ZZCOVERAGE("ZZCOVTST","T2",3)="1:0:0:0:95"
+^ZZCOVERAGE("ZZCOVTST","T2",4)="1:0:0:0:607"
+^ZZCOVERAGE("ZZCOVTST","T2",5)="1:0:0:0:470"
+^ZZCOVERAGE("ZZCOVTST","T3")="1:0:0:0:254"
+^ZZCOVERAGE("ZZCOVTST","T3",0)="1:0:0:0:76"
+^ZZCOVERAGE("ZZCOVTST","T5")="1:0:0:0:153"
+^ZZCOVERAGE("ZZCOVTST","T5",0)="1:0:0:0:40"
+^ZZCOVERAGE("ZZCOVTST","T5",1)="1:0:0:0:41"
+^ZZCOVERAGE("ZZCOVTST","T5",2)="1:0:0:0:41"
+^ZZCOVERAGE("ZZCOVTST","T6")="1:0:0:0:227"
+^ZZCOVERAGE("ZZCOVTST","T6",1)="1:0:0:0:41"
+^ZZCOVERAGE("ZZCOVTST","T6",2)="1:0:0:0:42"
+^ZZCOVERAGE("ZZCOVTST","T6",4)="1:0:0:0:41"
+^ZZCOVERAGE("ZZCOVTST","T6",5)="1:0:0:0:34"
+^ZZCOVERAGE("ZZCOVTST","T6",6)="1:0:0:0:38"
+
+
diff --git a/Tests/ObjectLibrary/A/CMakeLists.txt b/Tests/ObjectLibrary/A/CMakeLists.txt
index 55778eabf..c24c5ed92 100644
--- a/Tests/ObjectLibrary/A/CMakeLists.txt
+++ b/Tests/ObjectLibrary/A/CMakeLists.txt
@@ -1,18 +1,26 @@
project(ObjectLibraryA C)
# Add -fPIC so objects can be used in shared libraries.
-# TODO: Need property for this.
-if(CMAKE_SHARED_LIBRARY_C_FLAGS AND NOT WATCOM)
- set(CMAKE_C_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS} ${CMAKE_C_FLAGS}")
-endif()
+set(CMAKE_POSITION_INDEPENDENT_CODE ON)
add_definitions(-DA_DEF)
add_custom_command(
OUTPUT a1.c
- DEPENDS a1.c.in
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/a1.c.in
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/a1.c.in
${CMAKE_CURRENT_BINARY_DIR}/a1.c
)
-add_library(A OBJECT a1.c a2.c)
+# Remove the custom command output to be sure it runs in an
+# incremental test. Skip this on VS 6 because it sometimes
+# re-runs CMake after the custom command runs.
+if(NOT CMAKE_GENERATOR STREQUAL "Visual Studio 6")
+ file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/a.cmake)
+endif()
+add_custom_command(
+ OUTPUT a.cmake
+ COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/a.cmake
+ )
+
+add_library(A OBJECT a1.c a2.c a.cmake)
target_include_directories(A PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/Tests/ObjectLibrary/B/CMakeLists.txt b/Tests/ObjectLibrary/B/CMakeLists.txt
index a567f960b..215808449 100644
--- a/Tests/ObjectLibrary/B/CMakeLists.txt
+++ b/Tests/ObjectLibrary/B/CMakeLists.txt
@@ -5,10 +5,7 @@ if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 6")
endif()
# Add -fPIC so objects can be used in shared libraries.
-# TODO: Need property for this.
-if(CMAKE_SHARED_LIBRARY_C_FLAGS AND NOT WATCOM)
- set(CMAKE_C_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS} ${CMAKE_C_FLAGS}")
-endif()
+set(CMAKE_POSITION_INDEPENDENT_CODE ON)
add_library(B OBJECT b1.c b2.c)
target_include_directories(B PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/Tests/ObjectLibrary/CMakeLists.txt b/Tests/ObjectLibrary/CMakeLists.txt
index 13a07b44a..e9f553e2b 100644
--- a/Tests/ObjectLibrary/CMakeLists.txt
+++ b/Tests/ObjectLibrary/CMakeLists.txt
@@ -12,6 +12,7 @@ add_library(Cshared SHARED c.c $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:Bexport>)
add_executable(UseCshared main.c)
set_property(TARGET UseCshared PROPERTY COMPILE_DEFINITIONS SHARED_C)
target_link_libraries(UseCshared Cshared)
+add_custom_command(TARGET UseCshared POST_BUILD COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/A/a.cmake)
add_executable(UseCinternal main.c c.c $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>)
@@ -58,3 +59,11 @@ target_compile_definitions(ABmain PUBLIC $<TARGET_PROPERTY:B,INTERFACE_COMPILE_D
add_executable(UseABinternal ${dummy}
$<TARGET_OBJECTS:ABmain> $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>
)
+
+# Test target-level dependencies of executable without sources.
+file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/UseABinternalDep.cmake)
+add_custom_target(UseABinternalDep COMMAND ${CMAKE_COMMAND} -E touch UseABinternalDep.cmake)
+add_custom_command(TARGET UseABinternal POST_BUILD COMMAND ${CMAKE_COMMAND} -P UseABinternalDep.cmake)
+add_dependencies(UseABinternal UseABinternalDep)
+
+add_subdirectory(ExportLanguages)
diff --git a/Tests/ObjectLibrary/ExportLanguages/CMakeLists.txt b/Tests/ObjectLibrary/ExportLanguages/CMakeLists.txt
new file mode 100644
index 000000000..22c92a7f3
--- /dev/null
+++ b/Tests/ObjectLibrary/ExportLanguages/CMakeLists.txt
@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 2.8)
+project(ExportLanguages CXX)
+add_library(ExportLanguagesA OBJECT a.cxx)
+add_library(ExportLanguagesB STATIC a.c $<TARGET_OBJECTS:ExportLanguagesA>)
+
+# Verify that object library languages are propagated.
+export(TARGETS ExportLanguagesB NAMESPACE Exp FILE BExport.cmake)
+include(ExternalProject)
+ExternalProject_Add(ExportLanguagesTest
+ SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ExportLanguagesTest"
+ BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ExportLanguagesTest"
+ DOWNLOAD_COMMAND ""
+ INSTALL_COMMAND ""
+)
+add_dependencies(ExportLanguagesTest ExportLanguagesA ExportLanguagesB)
diff --git a/Tests/ObjectLibrary/ExportLanguages/ExportLanguagesTest/CMakeLists.txt b/Tests/ObjectLibrary/ExportLanguages/ExportLanguagesTest/CMakeLists.txt
new file mode 100644
index 000000000..fc8dd2b78
--- /dev/null
+++ b/Tests/ObjectLibrary/ExportLanguages/ExportLanguagesTest/CMakeLists.txt
@@ -0,0 +1,14 @@
+
+cmake_minimum_required(VERSION 2.8)
+
+project(ExportLanguagesTest)
+
+include(${CMAKE_CURRENT_BINARY_DIR}/../BExport.cmake)
+get_property(configs TARGET ExpExportLanguagesB PROPERTY IMPORTED_CONFIGURATIONS)
+foreach(c ${configs})
+ get_property(langs TARGET ExpExportLanguagesB PROPERTY IMPORTED_LINK_INTERFACE_LANGUAGES_${c})
+ list(FIND langs CXX pos)
+ if(${pos} LESS 0)
+ message(FATAL_ERROR "Target export does not list object library languages.")
+ endif()
+endforeach()
diff --git a/Tests/ObjectLibrary/ExportLanguages/a.c b/Tests/ObjectLibrary/ExportLanguages/a.c
new file mode 100644
index 000000000..af20d3ff6
--- /dev/null
+++ b/Tests/ObjectLibrary/ExportLanguages/a.c
@@ -0,0 +1 @@
+int a(void) { return 0; }
diff --git a/Tests/RunCMake/ObjectLibrary/a.cxx b/Tests/ObjectLibrary/ExportLanguages/a.cxx
index ae9c87c49..ae9c87c49 100644
--- a/Tests/RunCMake/ObjectLibrary/a.cxx
+++ b/Tests/ObjectLibrary/ExportLanguages/a.cxx
diff --git a/Tests/OutDir/OutDir.cmake b/Tests/OutDir/OutDir.cmake
index e1e6b7f93..a1f13e7cb 100644
--- a/Tests/OutDir/OutDir.cmake
+++ b/Tests/OutDir/OutDir.cmake
@@ -16,13 +16,17 @@ find_program(CONLY_EXE
PATHS ${top}/runtime
NO_DEFAULT_PATH)
+file(RELATIVE_PATH TESTC1_LIB_FILE "${top}" "${TESTC1_LIB}")
+file(RELATIVE_PATH TESTC2_LIB_FILE "${top}" "${TESTC2_LIB}")
+file(RELATIVE_PATH CONLY_EXE_FILE "${top}" "${CONLY_EXE}")
+
file(WRITE ${top}/OutDir.h "/* Generated by ${CMAKE_CURRENT_LIST_FILE} */
#ifndef OutDir_h
#define OutDir_h
-#define TESTC1_LIB \"${TESTC1_LIB}\"
-#define TESTC2_LIB \"${TESTC2_LIB}\"
-#define CONLY_EXE \"${CONLY_EXE}\"
+#define TESTC1_LIB \"${TESTC1_LIB_FILE}\"
+#define TESTC2_LIB \"${TESTC2_LIB_FILE}\"
+#define CONLY_EXE \"${CONLY_EXE_FILE}\"
#endif
")
diff --git a/Tests/OutOfBinary/CMakeLists.txt b/Tests/OutOfBinary/CMakeLists.txt
index e32754143..f50536e70 100644
--- a/Tests/OutOfBinary/CMakeLists.txt
+++ b/Tests/OutOfBinary/CMakeLists.txt
@@ -1,2 +1,4 @@
add_library(outlib outlib.c)
+add_executable(outexe outexe.c)
+target_link_libraries(outexe subdir)
diff --git a/Tests/OutOfBinary/outexe.c b/Tests/OutOfBinary/outexe.c
new file mode 100644
index 000000000..6f1404358
--- /dev/null
+++ b/Tests/OutOfBinary/outexe.c
@@ -0,0 +1,2 @@
+extern int subdir(void);
+int main(void) { return subdir(); }
diff --git a/Tests/OutOfSource/SubDir/CMakeLists.txt b/Tests/OutOfSource/SubDir/CMakeLists.txt
index c5df36e1b..e18dbb96c 100644
--- a/Tests/OutOfSource/SubDir/CMakeLists.txt
+++ b/Tests/OutOfSource/SubDir/CMakeLists.txt
@@ -6,3 +6,5 @@ add_subdirectory(${OutOfSource_SOURCE_DIR}/../OutOfBinary
# subdir to a sibling dir
add_subdirectory(${OutOfSource_SOURCE_DIR}/${KEN}OutOfSourceSubdir OutOfSourceSubdir )
+
+add_library(subdir subdir.c)
diff --git a/Tests/OutOfSource/SubDir/subdir.c b/Tests/OutOfSource/SubDir/subdir.c
new file mode 100644
index 000000000..0d0d8279e
--- /dev/null
+++ b/Tests/OutOfSource/SubDir/subdir.c
@@ -0,0 +1 @@
+int subdir(void) { return 0; }
diff --git a/Tests/PDBDirectoryAndName/CMakeLists.txt b/Tests/PDBDirectoryAndName/CMakeLists.txt
index 28e46b1f5..180f9fea2 100644
--- a/Tests/PDBDirectoryAndName/CMakeLists.txt
+++ b/Tests/PDBDirectoryAndName/CMakeLists.txt
@@ -2,10 +2,17 @@ cmake_minimum_required(VERSION 2.8)
project(PDBDirectoryAndName C)
# Make sure the proper compiler is in use.
-if(NOT MSVC AND NOT "${CMAKE_C_COMPILER_ID}" MATCHES "^(Intel)$")
+if(NOT MSVC AND NOT CMAKE_C_COMPILER_ID STREQUAL "Intel")
message(FATAL_ERROR "The PDBDirectoryAndName test works only with MSVC or Intel")
endif()
+# Intel 11.1 does not support /Fd but Intel 14.0 does.
+# TODO: Did a version in between these add it?
+if(CMAKE_C_COMPILER_ID STREQUAL Intel AND
+ CMAKE_C_COMPILER_VERSION VERSION_LESS 14.0)
+ set(NO_COMPILE_PDB 1)
+endif()
+
set(my_targets "")
add_library(mylibA SHARED mylibA.c)
@@ -17,12 +24,12 @@ list(APPEND my_targets mylibA)
add_library(mylibB STATIC mylibB.c)
set_target_properties(mylibB PROPERTIES
- PDB_NAME "mylibB_Special"
- PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/mylibB_PDB"
+ COMPILE_PDB_NAME "mylibB_Special"
+ COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/mylibB_PDB"
)
-# TODO: The only .pdb available for a static library is that generated
-# by the compiler /Fd option which is not the same as the linker /pdb.
-# list(APPEND my_targets mylibB)
+if(NOT NO_COMPILE_PDB)
+ list(APPEND my_targets mylibB)
+endif()
add_library(mylibC SHARED mylibC.c)
set_target_properties(mylibC PROPERTIES
@@ -32,10 +39,11 @@ list(APPEND my_targets mylibC)
add_library(mylibD STATIC mylibD.c)
set_target_properties(mylibD PROPERTIES
- PDB_NAME "mylibD_Special"
+ COMPILE_PDB_NAME "mylibD_Special"
)
-# TODO: See comment for mylibB.
-# list(APPEND my_targets mylibD)
+if(NOT NO_COMPILE_PDB)
+ list(APPEND my_targets mylibD)
+endif()
add_executable(myexe myexe.c)
set_target_properties(myexe PROPERTIES
@@ -66,6 +74,12 @@ set(pdbs "")
foreach(t ${my_targets})
get_property(pdb_name TARGET ${t} PROPERTY PDB_NAME)
get_property(pdb_dir TARGET ${t} PROPERTY PDB_OUTPUT_DIRECTORY)
+ if(NOT pdb_name)
+ get_property(pdb_name TARGET ${t} PROPERTY COMPILE_PDB_NAME)
+ endif()
+ if(NOT pdb_dir)
+ get_property(pdb_dir TARGET ${t} PROPERTY COMPILE_PDB_OUTPUT_DIRECTORY)
+ endif()
if(NOT pdb_dir)
set(pdb_dir ${CMAKE_CURRENT_BINARY_DIR})
endif()
diff --git a/Tests/PerConfig/perconfig.cmake b/Tests/PerConfig/perconfig.cmake
index 6a710ca4b..5286307a0 100644
--- a/Tests/PerConfig/perconfig.cmake
+++ b/Tests/PerConfig/perconfig.cmake
@@ -29,8 +29,8 @@ endif()
# Verify that the implementation files are named correctly.
foreach(lib pcStatic pcShared)
- file(STRINGS "${${lib}_file}" info LIMIT_COUNT 1 REGEX "INFO:[^[]*\\[")
- if(NOT "${info}" MATCHES ".*INFO:symbol\\[${lib}\\].*")
+ file(STRINGS "${${lib}_file}" info LIMIT_COUNT 1 REGEX "INFO:[A-Za-z0-9_]+\\[[^]]*\\]")
+ if(NOT "${info}" MATCHES "INFO:symbol\\[${lib}\\]")
message(SEND_ERROR "No INFO:symbol[${lib}] found in:\n ${${lib}_file}")
endif()
endforeach()
diff --git a/Tests/Plugin/CMakeLists.txt b/Tests/Plugin/CMakeLists.txt
index d1b8334a9..2b7bac1bc 100644
--- a/Tests/Plugin/CMakeLists.txt
+++ b/Tests/Plugin/CMakeLists.txt
@@ -24,6 +24,16 @@ include_directories(
${Plugin_SOURCE_DIR}/include
)
+# We need proper C++98 support from the compiler
+set(CMAKE_CXX_STANDARD 98)
+
+# Those versions of the HP compiler that need a flag to get proper C++98
+# template support also need a flag to use the newer C++ library.
+if (CMAKE_CXX_COMPILER_ID STREQUAL HP AND
+ CMAKE_CXX98_STANDARD_COMPILE_OPTION STREQUAL "+hpxstd98")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -AA")
+endif ()
+
# Create an executable that exports an API for use by plugins.
add_executable(example_exe src/example_exe.cxx)
set_target_properties(example_exe PROPERTIES
@@ -42,45 +52,18 @@ target_link_libraries(example_mod_1 example_exe)
if(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG AND
"${CMAKE_C_CREATE_SHARED_MODULE}" MATCHES "SONAME_FLAG")
- # Add a second plugin that should not have any soname.
- add_library(example_mod_2 MODULE src/example_mod_1.c)
- target_link_libraries(example_mod_2 example_exe)
- set_property(TARGET example_mod_2 PROPERTY NO_SONAME 1)
-
# Verify that targets export with proper IMPORTED SONAME properties.
- export(TARGETS example_mod_1 example_mod_2 NAMESPACE exp_
+ export(TARGETS example_mod_1 NAMESPACE exp_
FILE ${CMAKE_CURRENT_BINARY_DIR}/mods.cmake)
- include(${CMAKE_CURRENT_BINARY_DIR}/mods.cmake)
- get_property(configs TARGET exp_example_mod_1 PROPERTY IMPORTED_CONFIGURATIONS)
- foreach(c ${configs})
- string(TOUPPER "${c}" CONFIG)
- get_property(soname1 TARGET exp_example_mod_1 PROPERTY IMPORTED_SONAME_${CONFIG})
- get_property(soname2 TARGET exp_example_mod_2 PROPERTY IMPORTED_NO_SONAME_${CONFIG})
- if(soname1)
- message(STATUS "exp_example_mod_1 has IMPORTED_SONAME_${CONFIG} as expected: ${soname1}")
- else()
- message(SEND_ERROR "exp_example_mod_1 does not have IMPORTED_SONAME_${CONFIG} but should")
- endif()
- if(soname2)
- message(STATUS "exp_example_mod_2 has IMPORTED_NO_SONAME_${CONFIG} as expected: ${soname2}")
- else()
- message(SEND_ERROR "exp_example_mod_2 does not have IMPORTED_NO_SONAME_${CONFIG} but should")
- endif()
- endforeach()
- # Parse the binary to check for SONAME if possible.
- if("${CMAKE_EXECUTABLE_FORMAT}" MATCHES "ELF")
- find_program(READELF_EXE readelf)
- if(READELF_EXE)
- add_custom_target(check_mod_soname ALL COMMAND
- ${CMAKE_COMMAND} -Dreadelf=${READELF_EXE}
- -Dmod1=$<TARGET_FILE:example_mod_1>
- -Dmod2=$<TARGET_FILE:example_mod_2>
- -P ${CMAKE_CURRENT_SOURCE_DIR}/check_mod_soname.cmake
- )
- add_dependencies(check_mod_soname example_mod_1 example_mod_2)
- endif()
- endif()
+ include(ExternalProject)
+ ExternalProject_Add(PluginTest
+ SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/PluginTest"
+ BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/PluginTest"
+ DOWNLOAD_COMMAND ""
+ INSTALL_COMMAND ""
+ )
+ add_dependencies(PluginTest example_mod_1)
endif()
# TODO:
diff --git a/Tests/Plugin/PluginTest/CMakeLists.txt b/Tests/Plugin/PluginTest/CMakeLists.txt
new file mode 100644
index 000000000..5626dbcf7
--- /dev/null
+++ b/Tests/Plugin/PluginTest/CMakeLists.txt
@@ -0,0 +1,27 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(PluginTest)
+
+include(${CMAKE_CURRENT_BINARY_DIR}/../mods.cmake)
+get_property(configs TARGET exp_example_mod_1 PROPERTY IMPORTED_CONFIGURATIONS)
+foreach(c ${configs})
+ string(TOUPPER "${c}" CONFIG)
+ get_property(soname TARGET exp_example_mod_1 PROPERTY IMPORTED_NO_SONAME_${CONFIG})
+ if(soname)
+ message(STATUS "exp_example_mod_1 has IMPORTED_NO_SONAME_${CONFIG} as expected: ${soname}")
+ else()
+ message(SEND_ERROR "exp_example_mod_1 does not have IMPORTED_NO_SONAME_${CONFIG} but should")
+ endif()
+endforeach()
+
+# Parse the binary to check for SONAME if possible.
+if("${CMAKE_EXECUTABLE_FORMAT}" MATCHES "ELF")
+ find_program(READELF_EXE readelf)
+ if(READELF_EXE)
+ add_custom_target(check_mod_soname ALL COMMAND
+ ${CMAKE_COMMAND} -Dreadelf=${READELF_EXE}
+ -Dmod=$<TARGET_FILE:exp_example_mod_1>
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/../check_mod_soname.cmake
+ )
+ endif()
+endif()
diff --git a/Tests/Plugin/check_mod_soname.cmake b/Tests/Plugin/check_mod_soname.cmake
index 3737b450d..eeededa6a 100644
--- a/Tests/Plugin/check_mod_soname.cmake
+++ b/Tests/Plugin/check_mod_soname.cmake
@@ -1,14 +1,7 @@
-execute_process(COMMAND ${readelf} -d ${mod1} OUTPUT_FILE ${mod1}.readelf.txt)
-execute_process(COMMAND ${readelf} -d ${mod2} OUTPUT_FILE ${mod2}.readelf.txt)
-file(STRINGS ${mod1}.readelf.txt soname1 REGEX "\\(SONAME\\)")
-file(STRINGS ${mod2}.readelf.txt soname2 REGEX "\\(SONAME\\)")
-if(soname1)
- message(STATUS "${mod1} has soname as expected: ${soname1}")
+execute_process(COMMAND ${readelf} -d ${mod} OUTPUT_FILE ${mod}.readelf.txt)
+file(STRINGS ${mod}.readelf.txt soname REGEX "SONAME")
+if(soname)
+ message(FATAL_ERROR "${mod} has soname but should not:\n ${soname}")
else()
- message(FATAL_ERROR "${mod1} has no soname but should:\n ${soname1}")
-endif()
-if(soname2)
- message(FATAL_ERROR "${mod2} has soname but should not:\n ${soname2}")
-else()
- message(STATUS "${mod2} has no soname as expected")
+ message(STATUS "${mod} has no soname as expected")
endif()
diff --git a/Tests/Plugin/src/example_exe.cxx b/Tests/Plugin/src/example_exe.cxx
index 309302e58..12d92041a 100644
--- a/Tests/Plugin/src/example_exe.cxx
+++ b/Tests/Plugin/src/example_exe.cxx
@@ -3,15 +3,15 @@
#include <example_exe.h>
#include <kwsys/DynamicLoader.hxx>
-#include <kwsys/ios/iostream>
-#include <kwsys/stl/string>
+#include <iostream>
+#include <string>
#include <stdio.h>
// Implement the ABI used by plugins.
extern "C" int example_exe_function()
{
- kwsys_ios::cout << "hello" << kwsys_ios::endl;
+ std::cout << "hello" << std::endl;
return 123;
}
@@ -23,7 +23,7 @@ extern "C" int example_exe_function()
int main()
{
- kwsys_stl::string libName = EXAMPLE_EXE_PLUGIN_DIR CONFIG_DIR "/";
+ std::string libName = EXAMPLE_EXE_PLUGIN_DIR CONFIG_DIR "/";
libName += kwsys::DynamicLoader::LibPrefix();
libName += "example_mod_1";
libName += kwsys::DynamicLoader::LibExtension();
@@ -31,17 +31,17 @@ int main()
kwsys::DynamicLoader::OpenLibrary(libName.c_str());
if(!handle)
{
- kwsys_ios::cerr << "Could not open plugin \""
- << libName << "\"!" << kwsys_ios::endl;
+ std::cerr << "Could not open plugin \""
+ << libName.c_str() << "\"!" << std::endl;
return 1;
}
kwsys::DynamicLoader::SymbolPointer sym =
kwsys::DynamicLoader::GetSymbolAddress(handle, "example_mod_1_function");
if(!sym)
{
- kwsys_ios::cerr
+ std::cerr
<< "Could not get plugin symbol \"example_mod_1_function\"!"
- << kwsys_ios::endl;
+ << std::endl;
return 1;
}
#ifdef __WATCOMC__
@@ -51,8 +51,8 @@ int main()
#endif
if(f(456) != (123+456))
{
- kwsys_ios::cerr << "Incorrect return value from plugin!"
- << kwsys_ios::endl;
+ std::cerr << "Incorrect return value from plugin!"
+ << std::endl;
return 1;
}
kwsys::DynamicLoader::CloseLibrary(handle);
diff --git a/Tests/PositionIndependentTargets/CMakeLists.txt b/Tests/PositionIndependentTargets/CMakeLists.txt
index eec893d32..e79f3b74b 100644
--- a/Tests/PositionIndependentTargets/CMakeLists.txt
+++ b/Tests/PositionIndependentTargets/CMakeLists.txt
@@ -9,5 +9,6 @@ include_directories("${CMAKE_CURRENT_SOURCE_DIR}") # For pic_test.h
add_subdirectory(global)
add_subdirectory(targets)
+add_subdirectory(interface)
add_executable(PositionIndependentTargets main.cpp)
diff --git a/Tests/PositionIndependentTargets/interface/CMakeLists.txt b/Tests/PositionIndependentTargets/interface/CMakeLists.txt
new file mode 100644
index 000000000..65f3b767e
--- /dev/null
+++ b/Tests/PositionIndependentTargets/interface/CMakeLists.txt
@@ -0,0 +1,27 @@
+
+add_library(piciface INTERFACE)
+set_property(TARGET piciface PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON)
+
+add_executable(test_empty_iface "${CMAKE_CURRENT_SOURCE_DIR}/../pic_main.cpp")
+target_link_libraries(test_empty_iface piciface)
+
+add_library(sharedlib SHARED "${CMAKE_CURRENT_SOURCE_DIR}/../pic_lib.cpp")
+target_link_libraries(sharedlib piciface)
+set_property(TARGET sharedlib PROPERTY DEFINE_SYMBOL PIC_TEST_BUILD_DLL)
+
+add_executable(test_iface_via_shared "${CMAKE_CURRENT_SOURCE_DIR}/../pic_main.cpp")
+target_link_libraries(test_iface_via_shared sharedlib)
+
+add_library(sharedlibpic SHARED "${CMAKE_CURRENT_SOURCE_DIR}/../pic_lib.cpp")
+set_property(TARGET sharedlibpic PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON)
+set_property(TARGET sharedlibpic PROPERTY DEFINE_SYMBOL PIC_TEST_BUILD_DLL)
+
+add_library(shared_iface INTERFACE)
+target_link_libraries(shared_iface INTERFACE sharedlibpic)
+
+add_executable(test_shared_via_iface "${CMAKE_CURRENT_SOURCE_DIR}/../pic_main.cpp")
+target_link_libraries(test_shared_via_iface shared_iface)
+
+add_executable(test_shared_via_iface_non_conflict "${CMAKE_CURRENT_SOURCE_DIR}/../pic_main.cpp")
+set_property(TARGET test_shared_via_iface_non_conflict PROPERTY POSITION_INDEPENDENT_CODE ON)
+target_link_libraries(test_shared_via_iface_non_conflict shared_iface)
diff --git a/Tests/PrecompiledHeader/CMakeLists.txt b/Tests/PrecompiledHeader/CMakeLists.txt
index 6958131bf..98bdd88c5 100644
--- a/Tests/PrecompiledHeader/CMakeLists.txt
+++ b/Tests/PrecompiledHeader/CMakeLists.txt
@@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 2.6)
project(PrecompiledHeader C)
# Make sure the proper compiler is in use.
-if(NOT MSVC AND NOT "${CMAKE_C_COMPILER_ID}" MATCHES "^(Intel)$")
+if(NOT MSVC AND NOT CMAKE_C_COMPILER_ID STREQUAL "Intel")
message(FATAL_ERROR "The PrecompiledHeader test works only with MSVC or Intel")
endif()
diff --git a/Tests/Preprocess/CMakeLists.txt b/Tests/Preprocess/CMakeLists.txt
index d44cb9c82..15e2aca7c 100644
--- a/Tests/Preprocess/CMakeLists.txt
+++ b/Tests/Preprocess/CMakeLists.txt
@@ -34,15 +34,6 @@ endif()
if("${CMAKE_GENERATOR}" MATCHES "Visual Studio")
set(PP_VS 1)
endif()
-if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 10")
- set(PP_VS100 1)
-endif()
-if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 11")
- set(PP_VS110 1)
-endif()
-if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 12")
- set(PP_VS120 1)
-endif()
# Some tests below check the PP_* variables set above. They are meant
# to test the case that the build tool is at fault. Other tests below
@@ -123,7 +114,7 @@ endif()
set(EXPR_OP1 "/")
if((NOT MSVC OR PP_NMAKE) AND
- NOT "${CMAKE_C_COMPILER_ID}" MATCHES "^(Intel)$")
+ NOT CMAKE_C_COMPILER_ID STREQUAL "Intel")
# MSVC cl, Intel icl: %
# When the cl compiler is invoked from the command line then % must
# be written %% (to distinguish from %ENV% syntax). However cl does
@@ -143,6 +134,15 @@ if((NOT MSVC OR PP_NMAKE) AND
set(EXPR_OP1 "%")
endif()
+# XL: )(
+# The XL compiler cannot pass unbalanced parens correctly to a tool
+# it launches internally.
+if(CMAKE_C_COMPILER_ID STREQUAL "XL")
+ set(STRING_EXTRA "${STRING_EXTRA}()")
+else()
+ set(STRING_EXTRA "${STRING_EXTRA})(")
+endif()
+
# General: \"
# Make tools do not reliably accept \\\" syntax:
# - MinGW and MSYS make tools crash with \\\"
@@ -150,7 +150,10 @@ endif()
# or $(BACKSLASH)\" where BACKSLASH is a variable set to \\
# - VS IDE gets confused about the bounds of the definition value \\\"
# - NMake is okay with just \\\"
-if(PP_NMAKE OR PP_UMAKE)
+# - The XL compiler does not re-escape \\\" when launching an
+# internal tool to do preprocessing .
+if((PP_NMAKE OR PP_UMAKE) AND
+ NOT CMAKE_C_COMPILER_ID STREQUAL "XL")
set(STRING_EXTRA "${STRING_EXTRA}\\\"")
endif()
@@ -169,7 +172,7 @@ endif()
# support it and it is not an operator it is not worthwhile.
# Compose the final test string.
-set(STRING_VALUE "hello`~!@$*)(_+-=}{][:'.?/${STRING_EXTRA}world")
+set(STRING_VALUE "hello`~!@$*_+-=}{][:'.?/${STRING_EXTRA}world")
#-----------------------------------------------------------------------------
# Function-style macro command-line support:
diff --git a/Tests/Properties/CMakeLists.txt b/Tests/Properties/CMakeLists.txt
index 285d5965e..11fca45b0 100644
--- a/Tests/Properties/CMakeLists.txt
+++ b/Tests/Properties/CMakeLists.txt
@@ -143,3 +143,5 @@ set_property(CACHE SOME_ENTRY PROPERTY VALUE "${expect_VALUE}")
set_property(CACHE SOME_ENTRY PROPERTY ADVANCED "${expect_ADVANCED}")
set_property(CACHE SOME_ENTRY PROPERTY STRINGS "${expect_STRINGS}")
check_cache_props()
+
+add_subdirectory(SubDir2)
diff --git a/Tests/Properties/SubDir2/CMakeLists.txt b/Tests/Properties/SubDir2/CMakeLists.txt
new file mode 100644
index 000000000..377dc830e
--- /dev/null
+++ b/Tests/Properties/SubDir2/CMakeLists.txt
@@ -0,0 +1,5 @@
+
+set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/../subdirtest.cxx"
+ PROPERTIES COMPILE_DEFINITIONS SUBDIR_TEST)
+
+add_executable(subdirtest "${CMAKE_CURRENT_SOURCE_DIR}/../subdirtest.cxx")
diff --git a/Tests/Properties/subdirtest.cxx b/Tests/Properties/subdirtest.cxx
new file mode 100644
index 000000000..02d8f3d3f
--- /dev/null
+++ b/Tests/Properties/subdirtest.cxx
@@ -0,0 +1,9 @@
+
+#ifndef SUBDIR_TEST
+#error Expected SUBDIR_TEST
+#endif
+
+int main(int, char**)
+{
+ return 0;
+}
diff --git a/Tests/PythonCoverage/DartConfiguration.tcl.in b/Tests/PythonCoverage/DartConfiguration.tcl.in
new file mode 100644
index 000000000..e29cffe4f
--- /dev/null
+++ b/Tests/PythonCoverage/DartConfiguration.tcl.in
@@ -0,0 +1,8 @@
+# This file is configured by CMake automatically as DartConfiguration.tcl
+# If you choose not to use CMake, this file may be hand configured, by
+# filling in the required variables.
+
+
+# Configuration directories and files
+SourceDirectory: ${CMake_BINARY_DIR}/Testing/PythonCoverage/coveragetest
+BuildDirectory: ${CMake_BINARY_DIR}/Testing/PythonCoverage
diff --git a/Tests/PythonCoverage/coverage.xml.in b/Tests/PythonCoverage/coverage.xml.in
new file mode 100644
index 000000000..fcc1b1c67
--- /dev/null
+++ b/Tests/PythonCoverage/coverage.xml.in
@@ -0,0 +1,35 @@
+<?xml version="1.0" ?>
+<!DOCTYPE coverage
+ SYSTEM 'http://cobertura.sourceforge.net/xml/coverage-03.dtd'>
+<coverage branch-rate="0" line-rate="0.8462" timestamp="1380469411433" version="3.6">
+ <!-- Generated by coverage.py: http://nedbatchelder.com/code/coverage -->
+ <packages>
+ <package branch-rate="0" complexity="0" line-rate="0.8462" name="">
+ <classes>
+ <class branch-rate="0" complexity="0" filename="foo.py" line-rate="0.6667" name="foo">
+ <methods/>
+ <lines>
+ <line hits="1" number="2"/>
+ <line hits="1" number="3"/>
+ <line hits="1" number="4"/>
+ <line hits="1" number="6"/>
+ <line hits="0" number="7"/>
+ <line hits="0" number="8"/>
+ </lines>
+ </class>
+ <class branch-rate="0" complexity="0" filename="test_foo.py" line-rate="1" name="test_foo">
+ <methods/>
+ <lines>
+ <line hits="1" number="2"/>
+ <line hits="1" number="3"/>
+ <line hits="1" number="5"/>
+ <line hits="1" number="7"/>
+ <line hits="1" number="8"/>
+ <line hits="1" number="10"/>
+ <line hits="1" number="11"/>
+ </lines>
+ </class>
+ </classes>
+ </package>
+ </packages>
+</coverage>
diff --git a/Tests/PythonCoverage/coveragetest/foo.py b/Tests/PythonCoverage/coveragetest/foo.py
new file mode 100644
index 000000000..97b5a41e9
--- /dev/null
+++ b/Tests/PythonCoverage/coveragetest/foo.py
@@ -0,0 +1,8 @@
+
+def foo():
+ x = 3 + 3
+ return x
+
+def bar():
+ y = 2 + 2
+ return y
diff --git a/Tests/PythonCoverage/coveragetest/test_foo.py b/Tests/PythonCoverage/coveragetest/test_foo.py
new file mode 100644
index 000000000..51a69d89e
--- /dev/null
+++ b/Tests/PythonCoverage/coveragetest/test_foo.py
@@ -0,0 +1,11 @@
+
+import foo
+import unittest
+
+class TestFoo(unittest.TestCase):
+
+ def testFoo(self):
+ self.assertEquals(foo.foo(), 6, 'foo() == 6')
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Tests/Qt4And5Automoc/CMakeLists.txt b/Tests/Qt4And5Automoc/CMakeLists.txt
index 0cc80fe73..ad74961d9 100644
--- a/Tests/Qt4And5Automoc/CMakeLists.txt
+++ b/Tests/Qt4And5Automoc/CMakeLists.txt
@@ -1,13 +1,29 @@
+cmake_minimum_required(VERSION 2.8.12)
project(Qt4And5Automoc)
-find_package(Qt4 REQUIRED)
-find_package(Qt5Core REQUIRED)
+if (QT_REVERSE_FIND_ORDER)
+ find_package(Qt5Core REQUIRED)
+ find_package(Qt4 REQUIRED)
+else()
+ find_package(Qt4 REQUIRED)
+ find_package(Qt5Core REQUIRED)
+endif()
set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
-add_executable(qt4_exe main_qt4.cpp)
+macro(generate_main_file VERSION)
+ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/main.cpp.in" "${CMAKE_CURRENT_BINARY_DIR}/main_qt${VERSION}.cpp" COPYONLY)
+ file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/main_qt${VERSION}.cpp"
+ "#include \"main_qt${VERSION}.moc\"\n"
+ )
+endmacro()
+
+generate_main_file(4)
+generate_main_file(5)
+
+add_executable(qt4_exe "${CMAKE_CURRENT_BINARY_DIR}/main_qt4.cpp")
target_link_libraries(qt4_exe Qt4::QtCore)
-add_executable(qt5_exe main_qt5.cpp)
+add_executable(qt5_exe "${CMAKE_CURRENT_BINARY_DIR}/main_qt5.cpp")
target_link_libraries(qt5_exe Qt5::Core)
diff --git a/Tests/Qt4And5Automoc/main.cpp b/Tests/Qt4And5Automoc/main.cpp.in
index 00fd64153..00fd64153 100644
--- a/Tests/Qt4And5Automoc/main.cpp
+++ b/Tests/Qt4And5Automoc/main.cpp.in
diff --git a/Tests/Qt4And5Automoc/main_qt4.cpp b/Tests/Qt4And5Automoc/main_qt4.cpp
deleted file mode 100644
index a84ce897f..000000000
--- a/Tests/Qt4And5Automoc/main_qt4.cpp
+++ /dev/null
@@ -1,4 +0,0 @@
-
-#include "main.cpp"
-
-#include "main_qt4.moc"
diff --git a/Tests/Qt4And5Automoc/main_qt5.cpp b/Tests/Qt4And5Automoc/main_qt5.cpp
deleted file mode 100644
index 287b26137..000000000
--- a/Tests/Qt4And5Automoc/main_qt5.cpp
+++ /dev/null
@@ -1,4 +0,0 @@
-
-#include "main.cpp"
-
-#include "main_qt5.moc"
diff --git a/Tests/Qt4Targets/CMakeLists.txt b/Tests/Qt4Targets/CMakeLists.txt
index af9fc3fe7..ae0a02bb6 100644
--- a/Tests/Qt4Targets/CMakeLists.txt
+++ b/Tests/Qt4Targets/CMakeLists.txt
@@ -36,3 +36,45 @@ add_executable(Qt4WrapMacroTest WIN32 main_wrap_test.cpp ${moc_file})
set_property(TARGET Qt4WrapMacroTest PROPERTY AUTOMOC OFF)
target_include_directories(Qt4WrapMacroTest PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/interface")
target_link_libraries(Qt4WrapMacroTest Qt4::QtGui)
+
+macro(test_incremental def)
+ set(timeformat "%Y%j%H%M%S")
+ try_compile(RESULT
+ "${CMAKE_CURRENT_BINARY_DIR}/IncrementalMocBuild_${def}"
+ "${CMAKE_CURRENT_SOURCE_DIR}/IncrementalMoc"
+ IncrementalMoc
+ CMAKE_FLAGS -D${def}=0 "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}"
+ OUTPUT_VARIABLE output
+ )
+ file(TIMESTAMP "${CMAKE_CURRENT_BINARY_DIR}/IncrementalMocBuild_${def}/moc_foo.cpp" tsvar_before "${timeformat}")
+ if (NOT tsvar_before)
+ message(SEND_ERROR
+ "Unable to read timestamp from moc file from first build with -D${def}!\n"
+ "try_compile output:\n${output}"
+ )
+ endif()
+
+ execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 2) # Ensure that the timestamp will change.
+
+ try_compile(RESULT
+ "${CMAKE_CURRENT_BINARY_DIR}/IncrementalMocBuild_${def}"
+ "${CMAKE_CURRENT_SOURCE_DIR}/IncrementalMoc"
+ IncrementalMoc
+ CMAKE_FLAGS -D${def}=1 "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}"
+ OUTPUT_VARIABLE output
+ )
+ file(TIMESTAMP "${CMAKE_CURRENT_BINARY_DIR}/IncrementalMocBuild_${def}/moc_foo.cpp" tsvar_after "${timeformat}")
+ if (NOT tsvar_after)
+ message(SEND_ERROR
+ "Unable to read timestamp from moc file from second build!\n"
+ "try_compile output:\n${output}"
+ )
+ endif()
+
+ if (NOT tsvar_after GREATER tsvar_before)
+ message(SEND_ERROR "Rebuild did not re-create moc file with -D${def}. Before: ${tsvar_before}. After: ${tsvar_after}")
+ endif()
+endmacro()
+
+test_incremental(ADD_TARGET_DEF)
+test_incremental(ADD_DIR_DEF)
diff --git a/Tests/Qt4Targets/IncrementalMoc/CMakeLists.txt b/Tests/Qt4Targets/IncrementalMoc/CMakeLists.txt
new file mode 100644
index 000000000..65e2b64bf
--- /dev/null
+++ b/Tests/Qt4Targets/IncrementalMoc/CMakeLists.txt
@@ -0,0 +1,21 @@
+
+cmake_minimum_required(VERSION 2.8.12)
+project(IncrementalMoc)
+
+find_package(Qt4 REQUIRED)
+
+if (ADD_TARGET_DEF)
+ set(target_args TARGET testlib)
+endif()
+
+if (ADD_DIR_DEF)
+ add_definitions(-DNEW_DEF)
+endif()
+
+qt4_generate_moc(foo.h moc_foo.cpp ${target_args})
+
+add_library(testlib foo.cpp moc_foo.cpp)
+target_link_libraries(testlib Qt4::QtCore)
+if (ADD_TARGET_DEF)
+ target_compile_definitions(testlib PRIVATE NEW_DEF)
+endif()
diff --git a/Tests/Qt4Targets/IncrementalMoc/foo.cpp b/Tests/Qt4Targets/IncrementalMoc/foo.cpp
new file mode 100644
index 000000000..e924f7e26
--- /dev/null
+++ b/Tests/Qt4Targets/IncrementalMoc/foo.cpp
@@ -0,0 +1,8 @@
+
+#include "foo.h"
+
+Foo::Foo()
+ : QObject(0)
+{
+
+}
diff --git a/Tests/Qt4Targets/IncrementalMoc/foo.h b/Tests/Qt4Targets/IncrementalMoc/foo.h
new file mode 100644
index 000000000..38d899f0a
--- /dev/null
+++ b/Tests/Qt4Targets/IncrementalMoc/foo.h
@@ -0,0 +1,9 @@
+
+#include <QObject>
+
+class Foo : QObject
+{
+ Q_OBJECT
+public:
+ Foo();
+};
diff --git a/Tests/QtAutoUicInterface/CMakeLists.txt b/Tests/QtAutoUicInterface/CMakeLists.txt
new file mode 100644
index 000000000..555f01689
--- /dev/null
+++ b/Tests/QtAutoUicInterface/CMakeLists.txt
@@ -0,0 +1,70 @@
+
+cmake_minimum_required(VERSION 2.8.12)
+
+project(QtAutoUicInterface)
+
+if (QT_TEST_VERSION STREQUAL 4)
+ find_package(Qt4 REQUIRED)
+
+ include(UseQt4)
+
+ set(QT_CORE_TARGET Qt4::QtCore)
+ set(QT_GUI_TARGET Qt4::QtGui)
+else()
+ if (NOT QT_TEST_VERSION STREQUAL 5)
+ message(SEND_ERROR "Invalid Qt version specified.")
+ endif()
+ find_package(Qt5Widgets REQUIRED)
+
+ set(QT_CORE_TARGET Qt5::Core)
+ set(QT_GUI_TARGET Qt5::Widgets)
+endif()
+
+set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTOUIC ON)
+
+# BEGIN Upstream
+
+set(CMAKE_VERBOSE_MAKEFILE ON)
+
+add_library(KI18n klocalizedstring.cpp)
+target_link_libraries(KI18n ${QT_CORE_TARGET})
+
+set(autouic_options
+ -tr tr2$<$<NOT:$<BOOL:$<TARGET_PROPERTY:NO_KUIT_SEMANTIC>>>:x>i18n
+)
+if (NOT Qt5Widgets_VERSION VERSION_LESS 5.3.0)
+ list(APPEND autouic_options -include klocalizedstring.h)
+endif()
+
+set_property(TARGET KI18n APPEND PROPERTY
+ INTERFACE_AUTOUIC_OPTIONS ${autouic_options}
+)
+
+set(domainProp $<TARGET_PROPERTY:TRANSLATION_DOMAIN>)
+set(nameLower $<LOWER_CASE:$<MAKE_C_IDENTIFIER:$<TARGET_PROPERTY:NAME>>>)
+set(domain_logic
+ $<$<BOOL:${domainProp}>:${domainProp}>$<$<NOT:$<BOOL:${domainProp}>>:${nameLower}>
+)
+set_property(TARGET KI18n APPEND PROPERTY
+ INTERFACE_COMPILE_DEFINITIONS "TRANSLATION_DOMAIN=${domain_logic}"
+)
+
+# END upstream
+
+add_library(LibWidget libwidget.cpp)
+target_link_libraries(LibWidget KI18n ${QT_GUI_TARGET})
+set_property(TARGET LibWidget PROPERTY NO_KUIT_SEMANTIC ON)
+set_property(TARGET LibWidget PROPERTY TRANSLATION_DOMAIN customdomain)
+
+add_library(MyWidget mywidget.cpp)
+target_link_libraries(MyWidget KI18n ${QT_GUI_TARGET})
+
+add_executable(QtAutoUicInterface main.cpp)
+target_compile_definitions(QtAutoUicInterface
+ PRIVATE
+ UI_LIBWIDGET_H="${CMAKE_CURRENT_BINARY_DIR}/ui_libwidget.h"
+ UI_MYWIDGET_H="${CMAKE_CURRENT_BINARY_DIR}/ui_mywidget.h"
+)
diff --git a/Tests/QtAutoUicInterface/klocalizedstring.cpp b/Tests/QtAutoUicInterface/klocalizedstring.cpp
new file mode 100644
index 000000000..f2324bb09
--- /dev/null
+++ b/Tests/QtAutoUicInterface/klocalizedstring.cpp
@@ -0,0 +1,12 @@
+
+#include "klocalizedstring.h"
+
+QString tr2xi18n(const char *text, const char *)
+{
+ return QLatin1String("TranslatedX") + QString::fromLatin1(text);
+}
+
+QString tr2i18n(const char *text, const char *)
+{
+ return QLatin1String("Translated") + QString::fromLatin1(text);
+}
diff --git a/Tests/QtAutoUicInterface/klocalizedstring.h b/Tests/QtAutoUicInterface/klocalizedstring.h
new file mode 100644
index 000000000..559058fa3
--- /dev/null
+++ b/Tests/QtAutoUicInterface/klocalizedstring.h
@@ -0,0 +1,17 @@
+
+#ifndef KLOCALIZEDSTRING_H
+#define KLOCALIZEDSTRING_H
+
+#include <QString>
+
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+QString tr2xi18n(const char *text, const char *comment = 0);
+
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+QString tr2i18n(const char *text, const char *comment = 0);
+
+#endif
diff --git a/Tests/QtAutoUicInterface/libwidget.cpp b/Tests/QtAutoUicInterface/libwidget.cpp
new file mode 100644
index 000000000..8a921b397
--- /dev/null
+++ b/Tests/QtAutoUicInterface/libwidget.cpp
@@ -0,0 +1,9 @@
+
+#include "libwidget.h"
+
+LibWidget::LibWidget(QWidget *parent)
+ : QWidget(parent),
+ ui(new Ui::LibWidget)
+{
+ ui->setupUi(this);
+}
diff --git a/Tests/QtAutoUicInterface/libwidget.h b/Tests/QtAutoUicInterface/libwidget.h
new file mode 100644
index 000000000..8b592ecfc
--- /dev/null
+++ b/Tests/QtAutoUicInterface/libwidget.h
@@ -0,0 +1,24 @@
+
+#ifndef LIBWIDGET_H
+#define LIBWIDGET_H
+
+#include <QWidget>
+#include <memory>
+
+#if QT_VERSION < QT_VERSION_CHECK(5, 3, 0)
+#include <klocalizedstring.h>
+#endif
+
+#include "ui_libwidget.h"
+
+class LibWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit LibWidget(QWidget *parent = 0);
+
+private:
+ const std::auto_ptr<Ui::LibWidget> ui;
+};
+
+#endif
diff --git a/Tests/QtAutoUicInterface/libwidget.ui b/Tests/QtAutoUicInterface/libwidget.ui
new file mode 100644
index 000000000..897371e4a
--- /dev/null
+++ b/Tests/QtAutoUicInterface/libwidget.ui
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>LibWidget</class>
+ <widget class="QWidget" name="LibWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <widget class="QLabel" name="label">
+ <property name="geometry">
+ <rect>
+ <x>180</x>
+ <y>60</y>
+ <width>57</width>
+ <height>15</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>LibLabel</string>
+ </property>
+ </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Tests/QtAutoUicInterface/main.cpp b/Tests/QtAutoUicInterface/main.cpp
new file mode 100644
index 000000000..42d59588e
--- /dev/null
+++ b/Tests/QtAutoUicInterface/main.cpp
@@ -0,0 +1,75 @@
+
+#include <fstream>
+#include <iostream>
+#include <string>
+
+int main(int argc, char **argv)
+{
+ std::ifstream f;
+ f.open(UI_LIBWIDGET_H);
+ if (!f.is_open())
+ {
+ std::cout << "Could not open \"" UI_LIBWIDGET_H "\"." << std::endl;
+ return -1;
+ }
+
+ {
+ bool gotTr2i18n = false;
+
+ while (!f.eof())
+ {
+ std::string output;
+ getline(f, output);
+ if (!gotTr2i18n)
+ {
+ gotTr2i18n = output.find("tr2i18n") != std::string::npos;
+ }
+ if (output.find("tr2xi18n") != std::string::npos)
+ {
+ std::cout << "ui_libwidget,h uses tr2xi18n, though it should not." << std::endl;
+ return -1;
+ }
+ }
+
+ if (!gotTr2i18n)
+ {
+ std::cout << "Did not find tr2i18n in ui_libwidget.h" << std::endl;
+ return -1;
+ }
+ }
+
+ f.close();
+ f.open(UI_MYWIDGET_H);
+ if (!f.is_open())
+ {
+ std::cout << "Could not open \"" UI_MYWIDGET_H "\"." << std::endl;
+ return -1;
+ }
+
+ {
+ bool gotTr2xi18n = false;
+
+ while (!f.eof())
+ {
+ std::string output;
+ getline(f, output);
+ if (!gotTr2xi18n)
+ {
+ gotTr2xi18n = output.find("tr2xi18n") != std::string::npos;
+ }
+ if (output.find("tr2i18n") != std::string::npos)
+ {
+ std::cout << "ui_mywidget,h uses tr2i18n, though it should not." << std::endl;
+ return -1;
+ }
+ }
+ if (!gotTr2xi18n)
+ {
+ std::cout << "Did not find tr2xi18n in ui_mywidget.h" << std::endl;
+ return -1;
+ }
+ }
+ f.close();
+
+ return 0;
+}
diff --git a/Tests/QtAutoUicInterface/mywidget.cpp b/Tests/QtAutoUicInterface/mywidget.cpp
new file mode 100644
index 000000000..b528b1a43
--- /dev/null
+++ b/Tests/QtAutoUicInterface/mywidget.cpp
@@ -0,0 +1,9 @@
+
+#include "mywidget.h"
+
+MyWidget::MyWidget(QWidget *parent)
+ : QWidget(parent),
+ ui(new Ui::MyWidget)
+{
+ ui->setupUi(this);
+}
diff --git a/Tests/QtAutoUicInterface/mywidget.h b/Tests/QtAutoUicInterface/mywidget.h
new file mode 100644
index 000000000..c96fb9828
--- /dev/null
+++ b/Tests/QtAutoUicInterface/mywidget.h
@@ -0,0 +1,24 @@
+
+#ifndef MYWIDGET_H
+#define MYWIDGET_H
+
+#include <QWidget>
+#include <memory>
+
+#if QT_VERSION < QT_VERSION_CHECK(5, 3, 0)
+#include <klocalizedstring.h>
+#endif
+
+#include "ui_mywidget.h"
+
+class MyWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit MyWidget(QWidget *parent = 0);
+
+private:
+ const std::auto_ptr<Ui::MyWidget> ui;
+};
+
+#endif
diff --git a/Tests/QtAutoUicInterface/mywidget.ui b/Tests/QtAutoUicInterface/mywidget.ui
new file mode 100644
index 000000000..b2b9cc592
--- /dev/null
+++ b/Tests/QtAutoUicInterface/mywidget.ui
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MyWidget</class>
+ <widget class="QWidget" name="MyWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <widget class="QPushButton" name="pushButton">
+ <property name="geometry">
+ <rect>
+ <x>110</x>
+ <y>40</y>
+ <width>81</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Special button</string>
+ </property>
+ </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Tests/QtAutomoc/Adir/CMakeLists.txt b/Tests/QtAutogen/Adir/CMakeLists.txt
index a1c36ffce..a1c36ffce 100644
--- a/Tests/QtAutomoc/Adir/CMakeLists.txt
+++ b/Tests/QtAutogen/Adir/CMakeLists.txt
diff --git a/Tests/QtAutomoc/Adir/libA.cpp b/Tests/QtAutogen/Adir/libA.cpp
index 3968c4415..3968c4415 100644
--- a/Tests/QtAutomoc/Adir/libA.cpp
+++ b/Tests/QtAutogen/Adir/libA.cpp
diff --git a/Tests/QtAutomoc/Adir/libA.h b/Tests/QtAutogen/Adir/libA.h
index 03ad1e006..03ad1e006 100644
--- a/Tests/QtAutomoc/Adir/libA.h
+++ b/Tests/QtAutogen/Adir/libA.h
diff --git a/Tests/QtAutomoc/Bdir/CMakeLists.txt b/Tests/QtAutogen/Bdir/CMakeLists.txt
index d9d4aa7fa..d9d4aa7fa 100644
--- a/Tests/QtAutomoc/Bdir/CMakeLists.txt
+++ b/Tests/QtAutogen/Bdir/CMakeLists.txt
diff --git a/Tests/QtAutomoc/Bdir/libB.cpp b/Tests/QtAutogen/Bdir/libB.cpp
index 72f2cfae9..72f2cfae9 100644
--- a/Tests/QtAutomoc/Bdir/libB.cpp
+++ b/Tests/QtAutogen/Bdir/libB.cpp
diff --git a/Tests/QtAutomoc/Bdir/libB.h b/Tests/QtAutogen/Bdir/libB.h
index 510c17f8f..510c17f8f 100644
--- a/Tests/QtAutomoc/Bdir/libB.h
+++ b/Tests/QtAutogen/Bdir/libB.h
diff --git a/Tests/QtAutogen/CMakeLists.txt b/Tests/QtAutogen/CMakeLists.txt
new file mode 100644
index 000000000..d5aca55c7
--- /dev/null
+++ b/Tests/QtAutogen/CMakeLists.txt
@@ -0,0 +1,199 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(QtAutogen)
+
+# Tell find_package(Qt5) where to find Qt.
+if(QT_QMAKE_EXECUTABLE)
+ get_filename_component(Qt_BIN_DIR "${QT_QMAKE_EXECUTABLE}" PATH)
+ get_filename_component(Qt_PREFIX_DIR "${Qt_BIN_DIR}" PATH)
+ set(CMAKE_PREFIX_PATH ${Qt_PREFIX_DIR})
+endif()
+
+if (QT_TEST_VERSION STREQUAL 4)
+ find_package(Qt4 REQUIRED)
+
+ # Include this directory before using the UseQt4 file.
+ add_subdirectory(defines_test)
+
+ include(UseQt4)
+
+ set(QT_QTCORE_TARGET Qt4::QtCore)
+
+ macro(qtx_wrap_cpp)
+ qt4_wrap_cpp(${ARGN})
+ endmacro()
+
+else()
+ if (NOT QT_TEST_VERSION STREQUAL 5)
+ message(SEND_ERROR "Invalid Qt version specified.")
+ endif()
+ find_package(Qt5Widgets REQUIRED)
+
+ set(QT_QTCORE_TARGET Qt5::Core)
+
+ include_directories(${Qt5Widgets_INCLUDE_DIRS})
+ set(QT_LIBRARIES Qt5::Widgets)
+
+ if(Qt5_POSITION_INDEPENDENT_CODE AND CMAKE_CXX_COMPILE_OPTIONS_PIC)
+ add_definitions(${CMAKE_CXX_COMPILE_OPTIONS_PIC})
+ endif()
+
+ macro(qtx_wrap_cpp)
+ qt5_wrap_cpp(${ARGN})
+ endmacro()
+
+endif()
+
+add_executable(rcconly rcconly.cpp second_resource.qrc)
+set_property(TARGET rcconly PROPERTY AUTORCC ON)
+target_link_libraries(rcconly ${QT_QTCORE_TARGET})
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+add_definitions(-DFOO -DSomeDefine="Barx")
+
+# enable relaxed mode so automoc can handle all the special cases:
+set(CMAKE_AUTOMOC_RELAXED_MODE TRUE)
+
+set(CMAKE_AUTOUIC ON)
+set(CMAKE_AUTORCC ON)
+
+# create an executable and two library targets, each requiring automoc:
+add_library(codeeditorLib STATIC codeeditor.cpp)
+
+add_library(privateSlot OBJECT private_slot.cpp)
+
+configure_file(generated_resource.qrc.in generated_resource.qrc @ONLY)
+add_custom_command(
+ OUTPUT generated.txt
+ COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/generated.txt.in" "${CMAKE_CURRENT_BINARY_DIR}/generated.txt"
+ DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/generated.txt.in"
+ )
+
+add_custom_target(generate_moc_input
+ DEPENDS generated.txt
+ COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/myinterface.h.in" "${CMAKE_CURRENT_BINARY_DIR}"
+ COMMAND ${CMAKE_COMMAND} -E rename "${CMAKE_CURRENT_BINARY_DIR}/myinterface.h.in" "${CMAKE_CURRENT_BINARY_DIR}/myinterface.h"
+)
+
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/myotherinterface.h"
+ COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/myotherinterface.h.in" "${CMAKE_CURRENT_BINARY_DIR}/myotherinterface.h"
+ DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/myotherinterface.h.in"
+)
+
+if (NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_GENERATOR STREQUAL Ninja)
+ set(debug_srcs "$<$<CONFIG:Debug>:debug_class.cpp>" $<$<CONFIG:Debug>:debug_resource.qrc>)
+ set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS $<$<CONFIG:Debug>:TEST_DEBUG_CLASS>)
+endif()
+
+# The -no-protection option disables the generation of include guards. Verify
+# that setting the source file property has an effect by using this and
+# issue an error in the preprocessor in calwidget.cpp if the include guard
+# is defined.
+set_source_files_properties(calwidget.ui PROPERTIES AUTOUIC_OPTIONS "-no-protection")
+
+add_executable(QtAutogen main.cpp calwidget.cpp second_widget.cpp foo.cpp blub.cpp bar.cpp abc.cpp
+ multiplewidgets.cpp
+ xyz.cpp yaf.cpp gadget.cpp $<TARGET_OBJECTS:privateSlot>
+ test.qrc second_resource.qrc resourcetester.cpp generated.cpp ${debug_srcs}
+ ${CMAKE_CURRENT_BINARY_DIR}/generated_resource.qrc
+)
+set_property(TARGET QtAutogen APPEND PROPERTY AUTOGEN_TARGET_DEPENDS generate_moc_input "${CMAKE_CURRENT_BINARY_DIR}/myotherinterface.h")
+
+add_executable(targetObjectsTest targetObjectsTest.cpp $<TARGET_OBJECTS:privateSlot>)
+target_link_libraries(targetObjectsTest ${QT_LIBRARIES})
+
+set_target_properties(
+ QtAutogen codeeditorLib privateSlot targetObjectsTest
+ PROPERTIES
+ AUTOMOC TRUE
+)
+
+include(GenerateExportHeader)
+# The order is relevant here. B depends on A, and B headers depend on A
+# headers both subdirectories use CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE and we
+# test that CMAKE_AUTOMOC successfully reads the include directories
+# for the build interface from those targets. There has previously been
+# a bug where caching of the include directories happened before
+# extracting the includes to pass to moc.
+add_subdirectory(Bdir)
+add_subdirectory(Adir)
+add_library(libC SHARED libC.cpp)
+set_target_properties(libC PROPERTIES AUTOMOC TRUE)
+generate_export_header(libC)
+target_link_libraries(libC LINK_PUBLIC libB)
+
+target_link_libraries(QtAutogen codeeditorLib ${QT_LIBRARIES} libC)
+
+# Add not_generated_file.qrc to the source list to get the file-level
+# dependency, but don't generate a c++ file from it. Disable the AUTORCC
+# feature for this target. This tests that qrc files in the sources don't
+# have an effect on generation if AUTORCC is off.
+add_library(empty STATIC empty.cpp not_generated_file.qrc)
+set_target_properties(empty PROPERTIES AUTORCC OFF)
+
+set_target_properties(empty PROPERTIES AUTOMOC TRUE)
+target_link_libraries(empty no_link_language)
+add_library(no_link_language STATIC empty.h)
+set_target_properties(no_link_language PROPERTIES AUTOMOC TRUE)
+
+qtx_wrap_cpp(uicOnlyMoc sub/uiconly.h)
+add_executable(uiconly sub/uiconly.cpp ${uicOnlyMoc})
+target_link_libraries(uiconly ${QT_LIBRARIES})
+
+try_compile(RCC_DEPENDS
+ "${CMAKE_CURRENT_BINARY_DIR}/autorcc_depends"
+ "${CMAKE_CURRENT_SOURCE_DIR}/autorcc_depends"
+ autorcc_depends
+ CMAKE_FLAGS "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}" "-DQT_TEST_VERSION=${QT_TEST_VERSION}"
+ "-DCMAKE_PREFIX_PATH=${Qt_PREFIX_DIR}"
+ OUTPUT_VARIABLE output
+)
+if (NOT RCC_DEPENDS)
+ message(SEND_ERROR "Initial build of autorcc_depends failed. Output: ${output}")
+endif()
+
+file(STRINGS "${CMAKE_CURRENT_BINARY_DIR}/autorcc_depends/info_file.txt" qrc_files)
+
+list(GET qrc_files 0 qrc_file1)
+
+set(timeformat "%Y%j%H%M%S")
+
+file(TIMESTAMP "${qrc_file1}" file1_before "${timeformat}")
+
+execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) # Ensure that the timestamp will change.
+execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${CMAKE_CURRENT_BINARY_DIR}/autorcc_depends/res1/input.txt")
+
+execute_process(COMMAND "${CMAKE_COMMAND}" --build .
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/autorcc_depends"
+)
+
+file(TIMESTAMP "${qrc_file1}" file1_step1 "${timeformat}")
+
+if (NOT file1_step1 GREATER file1_before)
+ message(SEND_ERROR "file1 (${qrc_file1}) should have changed in the first step!")
+endif()
+
+#-----------------------------------------------------------------------------
+try_compile(MOC_RERUN
+ "${CMAKE_CURRENT_BINARY_DIR}/automoc_rerun"
+ "${CMAKE_CURRENT_SOURCE_DIR}/automoc_rerun"
+ automoc_rerun
+ CMAKE_FLAGS "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}" "-DQT_TEST_VERSION=${QT_TEST_VERSION}"
+ "-DCMAKE_PREFIX_PATH=${Qt_PREFIX_DIR}"
+ OUTPUT_VARIABLE output
+)
+if (NOT MOC_RERUN)
+ message(SEND_ERROR "Initial build of automoc_rerun failed. Output: ${output}")
+endif()
+
+configure_file(automoc_rerun/test1.h.in2 automoc_rerun/test1.h COPYONLY)
+
+execute_process(COMMAND "${CMAKE_COMMAND}" --build .
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/automoc_rerun"
+ RESULT_VARIABLE automoc_rerun_result
+ )
+if (automoc_rerun_result)
+ message(SEND_ERROR "Second build of automoc_rerun failed.")
+endif()
diff --git a/Tests/QtAutomoc/abc.cpp b/Tests/QtAutogen/abc.cpp
index 4bbc76905..4bbc76905 100644
--- a/Tests/QtAutomoc/abc.cpp
+++ b/Tests/QtAutogen/abc.cpp
diff --git a/Tests/QtAutomoc/abc.h b/Tests/QtAutogen/abc.h
index d1924b0da..d1924b0da 100644
--- a/Tests/QtAutomoc/abc.h
+++ b/Tests/QtAutogen/abc.h
diff --git a/Tests/QtAutomoc/abc_p.h b/Tests/QtAutogen/abc_p.h
index 952fff315..952fff315 100644
--- a/Tests/QtAutomoc/abc_p.h
+++ b/Tests/QtAutogen/abc_p.h
diff --git a/Tests/QtAutogen/automoc_rerun/CMakeLists.txt b/Tests/QtAutogen/automoc_rerun/CMakeLists.txt
new file mode 100644
index 000000000..17bc332a4
--- /dev/null
+++ b/Tests/QtAutogen/automoc_rerun/CMakeLists.txt
@@ -0,0 +1,27 @@
+cmake_minimum_required(VERSION 3.1)
+project(automoc_rerun CXX)
+
+if (QT_TEST_VERSION STREQUAL 4)
+ find_package(Qt4 REQUIRED)
+ set(QT_CORE_TARGET Qt4::QtCore)
+else()
+ if (NOT QT_TEST_VERSION STREQUAL 5)
+ message(SEND_ERROR "Invalid Qt version specified.")
+ endif()
+
+ find_package(Qt5Core REQUIRED)
+ set(QT_CORE_TARGET Qt5::Core)
+endif()
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTORCC ON)
+
+configure_file(test1.h.in1 test1.h COPYONLY)
+
+add_executable(test1
+ ${CMAKE_CURRENT_BINARY_DIR}/test1.h
+ test1.cpp
+ res1.qrc
+ )
+target_include_directories(test1 PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+target_link_libraries(test1 ${QT_CORE_TARGET})
diff --git a/Tests/QtAutogen/automoc_rerun/input.txt b/Tests/QtAutogen/automoc_rerun/input.txt
new file mode 100644
index 000000000..da627624b
--- /dev/null
+++ b/Tests/QtAutogen/automoc_rerun/input.txt
@@ -0,0 +1 @@
+Res1 input.
diff --git a/Tests/QtAutogen/automoc_rerun/res1.qrc b/Tests/QtAutogen/automoc_rerun/res1.qrc
new file mode 100644
index 000000000..fb804b5ec
--- /dev/null
+++ b/Tests/QtAutogen/automoc_rerun/res1.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file>input.txt</file>
+ </qresource>
+</RCC>
diff --git a/Tests/QtAutogen/automoc_rerun/test1.cpp b/Tests/QtAutogen/automoc_rerun/test1.cpp
new file mode 100644
index 000000000..4316a91cb
--- /dev/null
+++ b/Tests/QtAutogen/automoc_rerun/test1.cpp
@@ -0,0 +1,5 @@
+#include "test1.h"
+int main()
+{
+ return 0;
+}
diff --git a/Tests/QtAutogen/automoc_rerun/test1.h.in1 b/Tests/QtAutogen/automoc_rerun/test1.h.in1
new file mode 100644
index 000000000..fee2c096b
--- /dev/null
+++ b/Tests/QtAutogen/automoc_rerun/test1.h.in1
@@ -0,0 +1,8 @@
+#include <QObject>
+class test1 : public QObject
+{
+ Q_OBJECT
+ public slots:
+ void onTst1() {}
+ void onTst2() {}
+};
diff --git a/Tests/QtAutogen/automoc_rerun/test1.h.in2 b/Tests/QtAutogen/automoc_rerun/test1.h.in2
new file mode 100644
index 000000000..6531d10d5
--- /dev/null
+++ b/Tests/QtAutogen/automoc_rerun/test1.h.in2
@@ -0,0 +1,7 @@
+#include <QObject>
+class test1 : public QObject
+{
+ Q_OBJECT
+ public slots:
+ void onTst1() {}
+};
diff --git a/Tests/QtAutogen/autorcc_depends/CMakeLists.txt b/Tests/QtAutogen/autorcc_depends/CMakeLists.txt
new file mode 100644
index 000000000..fbe71addd
--- /dev/null
+++ b/Tests/QtAutogen/autorcc_depends/CMakeLists.txt
@@ -0,0 +1,27 @@
+cmake_minimum_required(VERSION 3.1)
+project(autorcc_depends)
+
+set(CMAKE_AUTORCC ON)
+
+if (QT_TEST_VERSION STREQUAL 4)
+ find_package(Qt4 REQUIRED)
+ set(QT_CORE_TARGET Qt4::QtCore)
+else()
+ if (NOT QT_TEST_VERSION STREQUAL 5)
+ message(SEND_ERROR "Invalid Qt version specified.")
+ endif()
+
+ find_package(Qt5Core REQUIRED)
+ set(QT_CORE_TARGET Qt5::Core)
+endif()
+
+configure_file(res1.qrc.in res1.qrc @ONLY)
+configure_file(res1/input.txt.in res1/input.txt @ONLY)
+
+add_executable(test_res1
+ test_res1.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/res1.qrc
+)
+target_link_libraries(test_res1 ${QT_CORE_TARGET})
+add_custom_command(TARGET test_res1 POST_BUILD COMMAND
+ ${CMAKE_COMMAND} -E echo "$<TARGET_FILE:test_res1>" > info_file.txt)
diff --git a/Tests/QtAutogen/autorcc_depends/res1.qrc.in b/Tests/QtAutogen/autorcc_depends/res1.qrc.in
new file mode 100644
index 000000000..2a5417bbb
--- /dev/null
+++ b/Tests/QtAutogen/autorcc_depends/res1.qrc.in
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file>res1/input.txt</file>
+ </qresource>
+</RCC>
diff --git a/Tests/QtAutogen/autorcc_depends/res1/input.txt.in b/Tests/QtAutogen/autorcc_depends/res1/input.txt.in
new file mode 100644
index 000000000..da627624b
--- /dev/null
+++ b/Tests/QtAutogen/autorcc_depends/res1/input.txt.in
@@ -0,0 +1 @@
+Res1 input.
diff --git a/Tests/QtAutogen/autorcc_depends/test_res1.cpp b/Tests/QtAutogen/autorcc_depends/test_res1.cpp
new file mode 100644
index 000000000..766b7751b
--- /dev/null
+++ b/Tests/QtAutogen/autorcc_depends/test_res1.cpp
@@ -0,0 +1,5 @@
+
+int main()
+{
+ return 0;
+}
diff --git a/Tests/QtAutomoc/bar.cpp b/Tests/QtAutogen/bar.cpp
index 8be48159d..8be48159d 100644
--- a/Tests/QtAutomoc/bar.cpp
+++ b/Tests/QtAutogen/bar.cpp
diff --git a/Tests/QtAutomoc/blub.cpp b/Tests/QtAutogen/blub.cpp
index bd53972ac..bd53972ac 100644
--- a/Tests/QtAutomoc/blub.cpp
+++ b/Tests/QtAutogen/blub.cpp
diff --git a/Tests/QtAutomoc/blub.h b/Tests/QtAutogen/blub.h
index 1967bc1ea..1967bc1ea 100644
--- a/Tests/QtAutomoc/blub.h
+++ b/Tests/QtAutogen/blub.h
diff --git a/Tests/QtAutogen/calwidget.cpp b/Tests/QtAutogen/calwidget.cpp
new file mode 100644
index 000000000..5f59994b7
--- /dev/null
+++ b/Tests/QtAutogen/calwidget.cpp
@@ -0,0 +1,437 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info@nokia.com)
+ **
+ ** This file is part of the examples of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:BSD$
+ ** You may use this file under the terms of the BSD license as follows:
+ **
+ ** "Redistribution and use in source and binary forms, with or without
+ ** modification, are permitted provided that the following conditions are
+ ** met:
+ ** * Redistributions of source code must retain the above copyright
+ ** notice, this list of conditions and the following disclaimer.
+ ** * Redistributions in binary form must reproduce the above copyright
+ ** notice, this list of conditions and the following disclaimer in
+ ** the documentation and/or other materials provided with the
+ ** distribution.
+ ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+ ** the names of its contributors may be used to endorse or promote
+ ** products derived from this software without specific prior written
+ ** permission.
+ **
+ ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+ #include <QComboBox>
+ #include <QGridLayout>
+ #include <QLabel>
+ #include <QGroupBox>
+ #include <QCheckBox>
+ #include <QDateEdit>
+ #include <QCalendarWidget>
+ #include <QTextCharFormat>
+
+ #include "calwidget.h"
+
+ #include "ui_calwidget.h"
+ #ifdef UI_CALWIDGET_H
+ #error Definition of UI_CALWIDGET_H should be disabled by file option.
+ #endif
+
+ Window::Window()
+ : ui(new Ui::Window)
+ {
+ createPreviewGroupBox();
+ createGeneralOptionsGroupBox();
+ createDatesGroupBox();
+ createTextFormatsGroupBox();
+
+ QGridLayout *layout = new QGridLayout;
+ layout->addWidget(previewGroupBox, 0, 0);
+ layout->addWidget(generalOptionsGroupBox, 0, 1);
+ layout->addWidget(datesGroupBox, 1, 0);
+ layout->addWidget(textFormatsGroupBox, 1, 1);
+ layout->setSizeConstraint(QLayout::SetFixedSize);
+ setLayout(layout);
+
+ previewLayout->setRowMinimumHeight(0, calendar->sizeHint().height());
+ previewLayout->setColumnMinimumWidth(0, calendar->sizeHint().width());
+
+ setWindowTitle(tr("Calendar Widget"));
+ }
+
+ void Window::localeChanged(int index)
+ {
+ calendar->setLocale(localeCombo->itemData(index).toLocale());
+ }
+
+ void Window::firstDayChanged(int index)
+ {
+ calendar->setFirstDayOfWeek(Qt::DayOfWeek(
+ firstDayCombo->itemData(index).toInt()));
+ }
+
+ void Window::selectionModeChanged(int index)
+ {
+ calendar->setSelectionMode(QCalendarWidget::SelectionMode(
+ selectionModeCombo->itemData(index).toInt()));
+ }
+
+ void Window::horizontalHeaderChanged(int index)
+ {
+ calendar->setHorizontalHeaderFormat(QCalendarWidget::HorizontalHeaderFormat(
+ horizontalHeaderCombo->itemData(index).toInt()));
+ }
+
+ void Window::verticalHeaderChanged(int index)
+ {
+ calendar->setVerticalHeaderFormat(QCalendarWidget::VerticalHeaderFormat(
+ verticalHeaderCombo->itemData(index).toInt()));
+ }
+
+ void Window::selectedDateChanged()
+ {
+ currentDateEdit->setDate(calendar->selectedDate());
+ }
+
+ void Window::minimumDateChanged(const QDate &date)
+ {
+ calendar->setMinimumDate(date);
+ maximumDateEdit->setDate(calendar->maximumDate());
+ }
+
+ void Window::maximumDateChanged(const QDate &date)
+ {
+ calendar->setMaximumDate(date);
+ minimumDateEdit->setDate(calendar->minimumDate());
+ }
+
+ void Window::weekdayFormatChanged()
+ {
+ QTextCharFormat format;
+
+ format.setForeground(qvariant_cast<QColor>(
+ weekdayColorCombo->itemData(weekdayColorCombo->currentIndex())));
+ calendar->setWeekdayTextFormat(Qt::Monday, format);
+ calendar->setWeekdayTextFormat(Qt::Tuesday, format);
+ calendar->setWeekdayTextFormat(Qt::Wednesday, format);
+ calendar->setWeekdayTextFormat(Qt::Thursday, format);
+ calendar->setWeekdayTextFormat(Qt::Friday, format);
+ }
+
+ void Window::weekendFormatChanged()
+ {
+ QTextCharFormat format;
+
+ format.setForeground(qvariant_cast<QColor>(
+ weekendColorCombo->itemData(weekendColorCombo->currentIndex())));
+ calendar->setWeekdayTextFormat(Qt::Saturday, format);
+ calendar->setWeekdayTextFormat(Qt::Sunday, format);
+ }
+
+ void Window::reformatHeaders()
+ {
+ QString text = headerTextFormatCombo->currentText();
+ QTextCharFormat format;
+
+ if (text == tr("Bold")) {
+ format.setFontWeight(QFont::Bold);
+ } else if (text == tr("Italic")) {
+ format.setFontItalic(true);
+ } else if (text == tr("Green")) {
+ format.setForeground(Qt::green);
+ }
+ calendar->setHeaderTextFormat(format);
+ }
+
+ void Window::reformatCalendarPage()
+ {
+ if (firstFridayCheckBox->isChecked()) {
+ QDate firstFriday(calendar->yearShown(), calendar->monthShown(), 1);
+ while (firstFriday.dayOfWeek() != Qt::Friday)
+ firstFriday = firstFriday.addDays(1);
+ QTextCharFormat firstFridayFormat;
+ firstFridayFormat.setForeground(Qt::blue);
+ calendar->setDateTextFormat(firstFriday, firstFridayFormat);
+ }
+
+ //May First in Red takes precedence
+ if (mayFirstCheckBox->isChecked()) {
+ const QDate mayFirst(calendar->yearShown(), 5, 1);
+ QTextCharFormat mayFirstFormat;
+ mayFirstFormat.setForeground(Qt::red);
+ calendar->setDateTextFormat(mayFirst, mayFirstFormat);
+ }
+ }
+
+ void Window::createPreviewGroupBox()
+ {
+ previewGroupBox = new QGroupBox(tr("Preview"));
+
+ calendar = new QCalendarWidget;
+ calendar->setMinimumDate(QDate(1900, 1, 1));
+ calendar->setMaximumDate(QDate(3000, 1, 1));
+ calendar->setGridVisible(true);
+
+ connect(calendar, SIGNAL(currentPageChanged(int,int)),
+ this, SLOT(reformatCalendarPage()));
+
+ previewLayout = new QGridLayout;
+ previewLayout->addWidget(calendar, 0, 0, Qt::AlignCenter);
+ previewGroupBox->setLayout(previewLayout);
+ }
+
+ void Window::createGeneralOptionsGroupBox()
+ {
+ generalOptionsGroupBox = new QGroupBox(tr("General Options"));
+
+ localeCombo = new QComboBox;
+ int curLocaleIndex = -1;
+ int index = 0;
+ for (int _lang = QLocale::C; _lang <= QLocale::LastLanguage; ++_lang) {
+ QLocale::Language lang = static_cast<QLocale::Language>(_lang);
+ QList<QLocale::Country> countries = QLocale::countriesForLanguage(lang);
+ for (int i = 0; i < countries.count(); ++i) {
+ QLocale::Country country = countries.at(i);
+ QString label = QLocale::languageToString(lang);
+ label += QLatin1Char('/');
+ label += QLocale::countryToString(country);
+ QLocale locale(lang, country);
+ if (this->locale().language() == lang && this->locale().country() == country)
+ curLocaleIndex = index;
+ localeCombo->addItem(label, locale);
+ ++index;
+ }
+ }
+ if (curLocaleIndex != -1)
+ localeCombo->setCurrentIndex(curLocaleIndex);
+ localeLabel = new QLabel(tr("&Locale"));
+ localeLabel->setBuddy(localeCombo);
+
+ firstDayCombo = new QComboBox;
+ firstDayCombo->addItem(tr("Sunday"), Qt::Sunday);
+ firstDayCombo->addItem(tr("Monday"), Qt::Monday);
+ firstDayCombo->addItem(tr("Tuesday"), Qt::Tuesday);
+ firstDayCombo->addItem(tr("Wednesday"), Qt::Wednesday);
+ firstDayCombo->addItem(tr("Thursday"), Qt::Thursday);
+ firstDayCombo->addItem(tr("Friday"), Qt::Friday);
+ firstDayCombo->addItem(tr("Saturday"), Qt::Saturday);
+
+ firstDayLabel = new QLabel(tr("Wee&k starts on:"));
+ firstDayLabel->setBuddy(firstDayCombo);
+
+ selectionModeCombo = new QComboBox;
+ selectionModeCombo->addItem(tr("Single selection"),
+ QCalendarWidget::SingleSelection);
+ selectionModeCombo->addItem(tr("None"), QCalendarWidget::NoSelection);
+
+ selectionModeLabel = new QLabel(tr("&Selection mode:"));
+ selectionModeLabel->setBuddy(selectionModeCombo);
+
+ gridCheckBox = new QCheckBox(tr("&Grid"));
+ gridCheckBox->setChecked(calendar->isGridVisible());
+
+ navigationCheckBox = new QCheckBox(tr("&Navigation bar"));
+ navigationCheckBox->setChecked(true);
+
+ horizontalHeaderCombo = new QComboBox;
+ horizontalHeaderCombo->addItem(tr("Single letter day names"),
+ QCalendarWidget::SingleLetterDayNames);
+ horizontalHeaderCombo->addItem(tr("Short day names"),
+ QCalendarWidget::ShortDayNames);
+ horizontalHeaderCombo->addItem(tr("None"),
+ QCalendarWidget::NoHorizontalHeader);
+ horizontalHeaderCombo->setCurrentIndex(1);
+
+ horizontalHeaderLabel = new QLabel(tr("&Horizontal header:"));
+ horizontalHeaderLabel->setBuddy(horizontalHeaderCombo);
+
+ verticalHeaderCombo = new QComboBox;
+ verticalHeaderCombo->addItem(tr("ISO week numbers"),
+ QCalendarWidget::ISOWeekNumbers);
+ verticalHeaderCombo->addItem(tr("None"), QCalendarWidget::NoVerticalHeader);
+
+ verticalHeaderLabel = new QLabel(tr("&Vertical header:"));
+ verticalHeaderLabel->setBuddy(verticalHeaderCombo);
+
+ connect(localeCombo, SIGNAL(currentIndexChanged(int)),
+ this, SLOT(localeChanged(int)));
+ connect(firstDayCombo, SIGNAL(currentIndexChanged(int)),
+ this, SLOT(firstDayChanged(int)));
+ connect(selectionModeCombo, SIGNAL(currentIndexChanged(int)),
+ this, SLOT(selectionModeChanged(int)));
+ connect(gridCheckBox, SIGNAL(toggled(bool)),
+ calendar, SLOT(setGridVisible(bool)));
+ connect(navigationCheckBox, SIGNAL(toggled(bool)),
+ calendar, SLOT(setNavigationBarVisible(bool)));
+ connect(horizontalHeaderCombo, SIGNAL(currentIndexChanged(int)),
+ this, SLOT(horizontalHeaderChanged(int)));
+ connect(verticalHeaderCombo, SIGNAL(currentIndexChanged(int)),
+ this, SLOT(verticalHeaderChanged(int)));
+
+ QHBoxLayout *checkBoxLayout = new QHBoxLayout;
+ checkBoxLayout->addWidget(gridCheckBox);
+ checkBoxLayout->addStretch();
+ checkBoxLayout->addWidget(navigationCheckBox);
+
+ QGridLayout *outerLayout = new QGridLayout;
+ outerLayout->addWidget(localeLabel, 0, 0);
+ outerLayout->addWidget(localeCombo, 0, 1);
+ outerLayout->addWidget(firstDayLabel, 1, 0);
+ outerLayout->addWidget(firstDayCombo, 1, 1);
+ outerLayout->addWidget(selectionModeLabel, 2, 0);
+ outerLayout->addWidget(selectionModeCombo, 2, 1);
+ outerLayout->addLayout(checkBoxLayout, 3, 0, 1, 2);
+ outerLayout->addWidget(horizontalHeaderLabel, 4, 0);
+ outerLayout->addWidget(horizontalHeaderCombo, 4, 1);
+ outerLayout->addWidget(verticalHeaderLabel, 5, 0);
+ outerLayout->addWidget(verticalHeaderCombo, 5, 1);
+ generalOptionsGroupBox->setLayout(outerLayout);
+
+ firstDayChanged(firstDayCombo->currentIndex());
+ selectionModeChanged(selectionModeCombo->currentIndex());
+ horizontalHeaderChanged(horizontalHeaderCombo->currentIndex());
+ verticalHeaderChanged(verticalHeaderCombo->currentIndex());
+ }
+
+ void Window::createDatesGroupBox()
+ {
+ datesGroupBox = new QGroupBox(tr("Dates"));
+
+ minimumDateEdit = new QDateEdit;
+ minimumDateEdit->setDisplayFormat("MMM d yyyy");
+ minimumDateEdit->setDateRange(calendar->minimumDate(),
+ calendar->maximumDate());
+ minimumDateEdit->setDate(calendar->minimumDate());
+
+ minimumDateLabel = new QLabel(tr("&Minimum Date:"));
+ minimumDateLabel->setBuddy(minimumDateEdit);
+
+ currentDateEdit = new QDateEdit;
+ currentDateEdit->setDisplayFormat("MMM d yyyy");
+ currentDateEdit->setDate(calendar->selectedDate());
+ currentDateEdit->setDateRange(calendar->minimumDate(),
+ calendar->maximumDate());
+
+ currentDateLabel = new QLabel(tr("&Current Date:"));
+ currentDateLabel->setBuddy(currentDateEdit);
+
+ maximumDateEdit = new QDateEdit;
+ maximumDateEdit->setDisplayFormat("MMM d yyyy");
+ maximumDateEdit->setDateRange(calendar->minimumDate(),
+ calendar->maximumDate());
+ maximumDateEdit->setDate(calendar->maximumDate());
+
+ maximumDateLabel = new QLabel(tr("Ma&ximum Date:"));
+ maximumDateLabel->setBuddy(maximumDateEdit);
+
+ connect(currentDateEdit, SIGNAL(dateChanged(QDate)),
+ calendar, SLOT(setSelectedDate(QDate)));
+ connect(calendar, SIGNAL(selectionChanged()),
+ this, SLOT(selectedDateChanged()));
+ connect(minimumDateEdit, SIGNAL(dateChanged(QDate)),
+ this, SLOT(minimumDateChanged(QDate)));
+ connect(maximumDateEdit, SIGNAL(dateChanged(QDate)),
+ this, SLOT(maximumDateChanged(QDate)));
+
+ QGridLayout *dateBoxLayout = new QGridLayout;
+ dateBoxLayout->addWidget(currentDateLabel, 1, 0);
+ dateBoxLayout->addWidget(currentDateEdit, 1, 1);
+ dateBoxLayout->addWidget(minimumDateLabel, 0, 0);
+ dateBoxLayout->addWidget(minimumDateEdit, 0, 1);
+ dateBoxLayout->addWidget(maximumDateLabel, 2, 0);
+ dateBoxLayout->addWidget(maximumDateEdit, 2, 1);
+ dateBoxLayout->setRowStretch(3, 1);
+
+ datesGroupBox->setLayout(dateBoxLayout);
+ }
+
+ void Window::createTextFormatsGroupBox()
+ {
+ textFormatsGroupBox = new QGroupBox(tr("Text Formats"));
+
+ weekdayColorCombo = createColorComboBox();
+ weekdayColorCombo->setCurrentIndex(
+ weekdayColorCombo->findText(tr("Black")));
+
+ weekdayColorLabel = new QLabel(tr("&Weekday color:"));
+ weekdayColorLabel->setBuddy(weekdayColorCombo);
+
+ weekendColorCombo = createColorComboBox();
+ weekendColorCombo->setCurrentIndex(
+ weekendColorCombo->findText(tr("Red")));
+
+ weekendColorLabel = new QLabel(tr("Week&end color:"));
+ weekendColorLabel->setBuddy(weekendColorCombo);
+
+ headerTextFormatCombo = new QComboBox;
+ headerTextFormatCombo->addItem(tr("Bold"));
+ headerTextFormatCombo->addItem(tr("Italic"));
+ headerTextFormatCombo->addItem(tr("Plain"));
+
+ headerTextFormatLabel = new QLabel(tr("&Header text:"));
+ headerTextFormatLabel->setBuddy(headerTextFormatCombo);
+
+ firstFridayCheckBox = new QCheckBox(tr("&First Friday in blue"));
+
+ mayFirstCheckBox = new QCheckBox(tr("May &1 in red"));
+
+ connect(weekdayColorCombo, SIGNAL(currentIndexChanged(int)),
+ this, SLOT(weekdayFormatChanged()));
+ connect(weekendColorCombo, SIGNAL(currentIndexChanged(int)),
+ this, SLOT(weekendFormatChanged()));
+ connect(headerTextFormatCombo, SIGNAL(currentIndexChanged(QString)),
+ this, SLOT(reformatHeaders()));
+ connect(firstFridayCheckBox, SIGNAL(toggled(bool)),
+ this, SLOT(reformatCalendarPage()));
+ connect(mayFirstCheckBox, SIGNAL(toggled(bool)),
+ this, SLOT(reformatCalendarPage()));
+
+ QHBoxLayout *checkBoxLayout = new QHBoxLayout;
+ checkBoxLayout->addWidget(firstFridayCheckBox);
+ checkBoxLayout->addStretch();
+ checkBoxLayout->addWidget(mayFirstCheckBox);
+
+ QGridLayout *outerLayout = new QGridLayout;
+ outerLayout->addWidget(weekdayColorLabel, 0, 0);
+ outerLayout->addWidget(weekdayColorCombo, 0, 1);
+ outerLayout->addWidget(weekendColorLabel, 1, 0);
+ outerLayout->addWidget(weekendColorCombo, 1, 1);
+ outerLayout->addWidget(headerTextFormatLabel, 2, 0);
+ outerLayout->addWidget(headerTextFormatCombo, 2, 1);
+ outerLayout->addLayout(checkBoxLayout, 3, 0, 1, 2);
+ textFormatsGroupBox->setLayout(outerLayout);
+
+ weekdayFormatChanged();
+ weekendFormatChanged();
+ reformatHeaders();
+ reformatCalendarPage();
+ }
+
+QComboBox *Window::createColorComboBox()
+ {
+ QComboBox *comboBox = new QComboBox;
+ comboBox->addItem(tr("Red"), QColor(Qt::red));
+ comboBox->addItem(tr("Blue"), QColor(Qt::blue));
+ comboBox->addItem(tr("Black"), QColor(Qt::black));
+ comboBox->addItem(tr("Magenta"), QColor(Qt::magenta));
+ return comboBox;
+ }
+
+//#include "moc_calwidget.cpp"
diff --git a/Tests/QtAutogen/calwidget.h b/Tests/QtAutogen/calwidget.h
new file mode 100644
index 000000000..d21a473de
--- /dev/null
+++ b/Tests/QtAutogen/calwidget.h
@@ -0,0 +1,128 @@
+ /****************************************************************************
+ **
+ ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info@nokia.com)
+ **
+ ** This file is part of the examples of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:BSD$
+ ** You may use this file under the terms of the BSD license as follows:
+ **
+ ** "Redistribution and use in source and binary forms, with or without
+ ** modification, are permitted provided that the following conditions are
+ ** met:
+ ** * Redistributions of source code must retain the above copyright
+ ** notice, this list of conditions and the following disclaimer.
+ ** * Redistributions in binary form must reproduce the above copyright
+ ** notice, this list of conditions and the following disclaimer in
+ ** the documentation and/or other materials provided with the
+ ** distribution.
+ ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+ ** the names of its contributors may be used to endorse or promote
+ ** products derived from this software without specific prior written
+ ** permission.
+ **
+ ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+#ifndef WINDOW_H
+#define WINDOW_H
+
+#include <QWidget>
+
+ class QCalendarWidget;
+ class QCheckBox;
+ class QComboBox;
+ class QDate;
+ class QDateEdit;
+ class QGridLayout;
+ class QGroupBox;
+ class QLabel;
+
+ namespace Ui
+ {
+ class Window;
+ }
+
+ class Window : public QWidget
+ {
+ Q_OBJECT
+
+ public:
+ Window();
+
+ private slots:
+ void localeChanged(int index);
+ void firstDayChanged(int index);
+ void selectionModeChanged(int index);
+ void horizontalHeaderChanged(int index);
+ void verticalHeaderChanged(int index);
+ void selectedDateChanged();
+ void minimumDateChanged(const QDate &date);
+ void maximumDateChanged(const QDate &date);
+ void weekdayFormatChanged();
+ void weekendFormatChanged();
+ void reformatHeaders();
+ void reformatCalendarPage();
+
+ private:
+ void createPreviewGroupBox();
+ void createGeneralOptionsGroupBox();
+ void createDatesGroupBox();
+ void createTextFormatsGroupBox();
+ QComboBox *createColorComboBox();
+
+ QGroupBox *previewGroupBox;
+ QGridLayout *previewLayout;
+ QCalendarWidget *calendar;
+
+ QGroupBox *generalOptionsGroupBox;
+ QLabel *localeLabel;
+ QLabel *firstDayLabel;
+ QLabel *selectionModeLabel;
+ QLabel *horizontalHeaderLabel;
+ QLabel *verticalHeaderLabel;
+ QComboBox *localeCombo;
+ QComboBox *firstDayCombo;
+ QComboBox *selectionModeCombo;
+ QCheckBox *gridCheckBox;
+ QCheckBox *navigationCheckBox;
+ QComboBox *horizontalHeaderCombo;
+ QComboBox *verticalHeaderCombo;
+
+ QGroupBox *datesGroupBox;
+ QLabel *currentDateLabel;
+ QLabel *minimumDateLabel;
+ QLabel *maximumDateLabel;
+ QDateEdit *currentDateEdit;
+ QDateEdit *minimumDateEdit;
+ QDateEdit *maximumDateEdit;
+
+ QGroupBox *textFormatsGroupBox;
+ QLabel *weekdayColorLabel;
+ QLabel *weekendColorLabel;
+ QLabel *headerTextFormatLabel;
+ QComboBox *weekdayColorCombo;
+ QComboBox *weekendColorCombo;
+ QComboBox *headerTextFormatCombo;
+
+ QCheckBox *firstFridayCheckBox;
+ QCheckBox *mayFirstCheckBox;
+
+ Ui::Window *ui;
+ };
+
+ #endif
diff --git a/Tests/QtAutogen/calwidget.ui b/Tests/QtAutogen/calwidget.ui
new file mode 100644
index 000000000..1c245cac9
--- /dev/null
+++ b/Tests/QtAutogen/calwidget.ui
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Window</class>
+ <widget class="QWidget" name="Window">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <widget class="QPushButton" name="pushButton">
+ <property name="geometry">
+ <rect>
+ <x>90</x>
+ <y>180</y>
+ <width>94</width>
+ <height>24</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>PushButton</string>
+ </property>
+ </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Tests/QtAutomoc/codeeditor.cpp b/Tests/QtAutogen/codeeditor.cpp
index 01da06276..01da06276 100644
--- a/Tests/QtAutomoc/codeeditor.cpp
+++ b/Tests/QtAutogen/codeeditor.cpp
diff --git a/Tests/QtAutomoc/codeeditor.h b/Tests/QtAutogen/codeeditor.h
index 56e9e7923..56e9e7923 100644
--- a/Tests/QtAutomoc/codeeditor.h
+++ b/Tests/QtAutogen/codeeditor.h
diff --git a/Tests/QtAutogen/debug_class.cpp b/Tests/QtAutogen/debug_class.cpp
new file mode 100644
index 000000000..58e72e46c
--- /dev/null
+++ b/Tests/QtAutogen/debug_class.cpp
@@ -0,0 +1,9 @@
+
+#include "debug_class.h"
+#include "ui_debug_class.h"
+
+DebugClass::DebugClass(QWidget *parent)
+ : QWidget(parent), ui(new Ui::DebugClass)
+{
+ ui->setupUi(this);
+}
diff --git a/Tests/QtAutogen/debug_class.h b/Tests/QtAutogen/debug_class.h
new file mode 100644
index 000000000..71bc1045a
--- /dev/null
+++ b/Tests/QtAutogen/debug_class.h
@@ -0,0 +1,20 @@
+
+#include <QWidget>
+
+namespace Ui
+{
+class DebugClass;
+}
+
+class DebugClass : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit DebugClass(QWidget *parent = 0);
+
+signals:
+ void someSignal();
+
+private:
+ Ui::DebugClass *ui;
+};
diff --git a/Tests/QtAutogen/debug_class.ui b/Tests/QtAutogen/debug_class.ui
new file mode 100644
index 000000000..dc2e1ac18
--- /dev/null
+++ b/Tests/QtAutogen/debug_class.ui
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DebugClass</class>
+ <widget class="QWidget" name="DebugClass">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>DebugClass</string>
+ </property>
+ <widget class="QCheckBox" name="checkBox">
+ <property name="geometry">
+ <rect>
+ <x>50</x>
+ <y>20</y>
+ <width>82</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>CheckBox</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pushButton">
+ <property name="geometry">
+ <rect>
+ <x>40</x>
+ <y>70</y>
+ <width>94</width>
+ <height>24</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>PushButton</string>
+ </property>
+ </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Tests/QtAutogen/debug_resource.qrc b/Tests/QtAutogen/debug_resource.qrc
new file mode 100644
index 000000000..db98b9bc1
--- /dev/null
+++ b/Tests/QtAutogen/debug_resource.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>debug_class.ui</file>
+</qresource>
+</RCC>
diff --git a/Tests/QtAutomoc/defines_test/CMakeLists.txt b/Tests/QtAutogen/defines_test/CMakeLists.txt
index ad4e684cb..ad4e684cb 100644
--- a/Tests/QtAutomoc/defines_test/CMakeLists.txt
+++ b/Tests/QtAutogen/defines_test/CMakeLists.txt
diff --git a/Tests/QtAutomoc/defines_test/defines_test.cpp b/Tests/QtAutogen/defines_test/defines_test.cpp
index 2836d357b..2836d357b 100644
--- a/Tests/QtAutomoc/defines_test/defines_test.cpp
+++ b/Tests/QtAutogen/defines_test/defines_test.cpp
diff --git a/Tests/QtAutomoc/empty.cpp b/Tests/QtAutogen/empty.cpp
index ab32cf6c8..ab32cf6c8 100644
--- a/Tests/QtAutomoc/empty.cpp
+++ b/Tests/QtAutogen/empty.cpp
diff --git a/Tests/QtAutomoc/empty.h b/Tests/QtAutogen/empty.h
index 4566142c1..4566142c1 100644
--- a/Tests/QtAutomoc/empty.h
+++ b/Tests/QtAutogen/empty.h
diff --git a/Tests/QtAutomoc/foo.cpp b/Tests/QtAutogen/foo.cpp
index 699ba094b..699ba094b 100644
--- a/Tests/QtAutomoc/foo.cpp
+++ b/Tests/QtAutogen/foo.cpp
diff --git a/Tests/QtAutomoc/foo.h b/Tests/QtAutogen/foo.h
index f23ec0739..f23ec0739 100644
--- a/Tests/QtAutomoc/foo.h
+++ b/Tests/QtAutogen/foo.h
diff --git a/Tests/QtAutogen/gadget.cpp b/Tests/QtAutogen/gadget.cpp
new file mode 100644
index 000000000..23d95fa4a
--- /dev/null
+++ b/Tests/QtAutogen/gadget.cpp
@@ -0,0 +1,4 @@
+
+#include "gadget.h"
+
+#include "moc_gadget.cpp"
diff --git a/Tests/QtAutogen/gadget.h b/Tests/QtAutogen/gadget.h
new file mode 100644
index 000000000..7c688ee45
--- /dev/null
+++ b/Tests/QtAutogen/gadget.h
@@ -0,0 +1,18 @@
+
+#ifndef GADGET_H
+#define GADGET_H
+
+#include <QObject>
+
+class Gadget
+{
+ Q_GADGET
+ Q_ENUMS(Type)
+public:
+ enum Type {
+ Type0,
+ Type1
+ };
+};
+
+#endif
diff --git a/Tests/QtAutogen/generated.cpp b/Tests/QtAutogen/generated.cpp
new file mode 100644
index 000000000..f53bf5342
--- /dev/null
+++ b/Tests/QtAutogen/generated.cpp
@@ -0,0 +1,10 @@
+
+#include "generated.h"
+
+Generated::Generated(QObject *parent)
+ : QObject(parent)
+{
+
+}
+
+#include "moc_generated.cpp"
diff --git a/Tests/QtAutogen/generated.h b/Tests/QtAutogen/generated.h
new file mode 100644
index 000000000..b6c271115
--- /dev/null
+++ b/Tests/QtAutogen/generated.h
@@ -0,0 +1,18 @@
+
+#ifndef GENERATED_H
+#define GENERATED_H
+
+#include <QObject>
+
+#include "myinterface.h"
+#include "myotherinterface.h"
+
+class Generated : public QObject, MyInterface, MyOtherInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(MyInterface MyOtherInterface)
+public:
+ explicit Generated(QObject *parent = 0);
+};
+
+#endif
diff --git a/Tests/QtAutogen/generated.txt.in b/Tests/QtAutogen/generated.txt.in
new file mode 100644
index 000000000..77507bb8e
--- /dev/null
+++ b/Tests/QtAutogen/generated.txt.in
@@ -0,0 +1 @@
+Some generated text file.
diff --git a/Tests/QtAutogen/generated_resource.qrc.in b/Tests/QtAutogen/generated_resource.qrc.in
new file mode 100644
index 000000000..da5fa6289
--- /dev/null
+++ b/Tests/QtAutogen/generated_resource.qrc.in
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>generated.txt</file>
+</qresource>
+</RCC>
diff --git a/Tests/QtAutomoc/libC.cpp b/Tests/QtAutogen/libC.cpp
index 8d61cb1bf..8d61cb1bf 100644
--- a/Tests/QtAutomoc/libC.cpp
+++ b/Tests/QtAutogen/libC.cpp
diff --git a/Tests/QtAutomoc/libC.h b/Tests/QtAutogen/libC.h
index 4fb4a2cf4..4fb4a2cf4 100644
--- a/Tests/QtAutomoc/libC.h
+++ b/Tests/QtAutogen/libC.h
diff --git a/Tests/QtAutogen/main.cpp b/Tests/QtAutogen/main.cpp
new file mode 100644
index 000000000..eb596650e
--- /dev/null
+++ b/Tests/QtAutogen/main.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info@nokia.com)
+ **
+ ** This file is part of the examples of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:BSD$
+ ** You may use this file under the terms of the BSD license as follows:
+ **
+ ** "Redistribution and use in source and binary forms, with or without
+ ** modification, are permitted provided that the following conditions are
+ ** met:
+ ** * Redistributions of source code must retain the above copyright
+ ** notice, this list of conditions and the following disclaimer.
+ ** * Redistributions in binary form must reproduce the above copyright
+ ** notice, this list of conditions and the following disclaimer in
+ ** the documentation and/or other materials provided with the
+ ** distribution.
+ ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+ ** the names of its contributors may be used to endorse or promote
+ ** products derived from this software without specific prior written
+ ** permission.
+ **
+ ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+#include <QCoreApplication>
+#include <QTimer>
+
+#include "codeeditor.h"
+#include "calwidget.h"
+#include "foo.h"
+#include "blub.h"
+#include "sub/bar.h"
+#include "abc.h"
+#include "xyz.h"
+#include "yaf.h"
+#include "libC.h"
+#include "resourcetester.h"
+#ifdef TEST_DEBUG_CLASS
+#include "debug_class.h"
+#include <iostream>
+#endif
+
+
+int main(int argv, char **args)
+{
+ QCoreApplication app(argv, args);
+
+ Foo foo;
+ foo.doFoo();
+
+ Blub b;
+ b.blubber();
+
+ Bar bar;
+ bar.doBar();
+
+ Abc abc;
+ abc.doAbc();
+
+ Xyz xyz;
+ xyz.doXyz();
+
+ Yaf yaf;
+ yaf.doYaf();
+
+ LibC lc;
+ lc.foo();
+
+ ResourceTester rt;
+
+ QTimer::singleShot(0, &rt, SLOT(doTest()));
+
+#ifdef TEST_DEBUG_CLASS
+ std::cout << DebugClass::staticMetaObject.className() << std::endl;
+#endif
+
+ return app.exec();
+}
diff --git a/Tests/QtAutogen/multiplewidgets.cpp b/Tests/QtAutogen/multiplewidgets.cpp
new file mode 100644
index 000000000..f14387591
--- /dev/null
+++ b/Tests/QtAutogen/multiplewidgets.cpp
@@ -0,0 +1,19 @@
+
+#include "multiplewidgets.h"
+
+#include "ui_widget1.h"
+#include "ui_widget2.h"
+
+Widget1::Widget1(QWidget *parent)
+ : QWidget(parent),
+ ui(new Ui::Widget1)
+{
+ ui->setupUi(this);
+}
+
+Widget2::Widget2(QWidget *parent)
+ : QWidget(parent),
+ ui(new Ui::Widget2)
+{
+ ui->setupUi(this);
+}
diff --git a/Tests/QtAutogen/multiplewidgets.h b/Tests/QtAutogen/multiplewidgets.h
new file mode 100644
index 000000000..6ae6ad125
--- /dev/null
+++ b/Tests/QtAutogen/multiplewidgets.h
@@ -0,0 +1,33 @@
+
+#ifndef MULTIPLEWIDGETS_H
+#define MULTIPLEWIDGETS_H
+
+#include <QWidget>
+
+namespace Ui {
+class Widget1;
+}
+
+class Widget1 : public QWidget
+{
+ Q_OBJECT
+public:
+ Widget1(QWidget *parent = 0);
+private:
+ Ui::Widget1 *ui;
+};
+
+namespace Ui {
+class Widget2;
+}
+
+class Widget2 : public QWidget
+{
+ Q_OBJECT
+public:
+ Widget2(QWidget *parent = 0);
+private:
+ Ui::Widget2 *ui;
+};
+
+#endif
diff --git a/Tests/QtAutogen/myinterface.h.in b/Tests/QtAutogen/myinterface.h.in
new file mode 100644
index 000000000..c6c0ba1b6
--- /dev/null
+++ b/Tests/QtAutogen/myinterface.h.in
@@ -0,0 +1,14 @@
+
+#ifndef MYINTERFACE_H
+#define MYINTERFACE_H
+
+#include <QObject>
+
+class MyInterface
+{
+
+};
+
+Q_DECLARE_INTERFACE(MyInterface, "org.cmake.example.MyInterface")
+
+#endif
diff --git a/Tests/QtAutogen/myotherinterface.h.in b/Tests/QtAutogen/myotherinterface.h.in
new file mode 100644
index 000000000..d21e7af7c
--- /dev/null
+++ b/Tests/QtAutogen/myotherinterface.h.in
@@ -0,0 +1,14 @@
+
+#ifndef MYOTHERINTERFACE_H
+#define MYOTHERINTERFACE_H
+
+#include <QObject>
+
+class MyOtherInterface
+{
+
+};
+
+Q_DECLARE_INTERFACE(MyOtherInterface, "org.cmake.example.MyOtherInterface")
+
+#endif
diff --git a/Tests/QtAutogen/not_generated_file.qrc b/Tests/QtAutogen/not_generated_file.qrc
new file mode 100644
index 000000000..c7698343a
--- /dev/null
+++ b/Tests/QtAutogen/not_generated_file.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>abc.cpp</file>
+</qresource>
+</RCC>
diff --git a/Tests/QtAutomoc/private_slot.cpp b/Tests/QtAutogen/private_slot.cpp
index 1387a70cf..1387a70cf 100644
--- a/Tests/QtAutomoc/private_slot.cpp
+++ b/Tests/QtAutogen/private_slot.cpp
diff --git a/Tests/QtAutomoc/private_slot.h b/Tests/QtAutogen/private_slot.h
index 28e54482a..28e54482a 100644
--- a/Tests/QtAutomoc/private_slot.h
+++ b/Tests/QtAutogen/private_slot.h
diff --git a/Tests/QtAutogen/rcconly.cpp b/Tests/QtAutogen/rcconly.cpp
new file mode 100644
index 000000000..854c4c1bc
--- /dev/null
+++ b/Tests/QtAutogen/rcconly.cpp
@@ -0,0 +1,9 @@
+
+extern int qInitResources_second_resource();
+
+int main(int, char**)
+{
+ // Fails to link if the symbol is not present.
+ qInitResources_second_resource();
+ return 0;
+}
diff --git a/Tests/QtAutogen/resourcetester.cpp b/Tests/QtAutogen/resourcetester.cpp
new file mode 100644
index 000000000..043ec75fc
--- /dev/null
+++ b/Tests/QtAutogen/resourcetester.cpp
@@ -0,0 +1,27 @@
+
+#include "resourcetester.h"
+
+#include <QDebug>
+#include <QApplication>
+#include <QFile>
+#include <QTimer>
+
+ResourceTester::ResourceTester(QObject *parent)
+ : QObject(parent)
+{
+
+}
+
+void ResourceTester::doTest()
+{
+ if (!QFile::exists(":/CMakeLists.txt"))
+ qApp->exit(EXIT_FAILURE);
+ if (!QFile::exists(":/main.cpp"))
+ qApp->exit(EXIT_FAILURE);
+#ifdef TEST_DEBUG_CLASS
+ if (!QFile::exists(":/debug_class.ui"))
+ qApp->exit(EXIT_FAILURE);
+#endif
+
+ QTimer::singleShot(0, qApp, SLOT(quit()));
+}
diff --git a/Tests/QtAutogen/resourcetester.h b/Tests/QtAutogen/resourcetester.h
new file mode 100644
index 000000000..b02cb4ed2
--- /dev/null
+++ b/Tests/QtAutogen/resourcetester.h
@@ -0,0 +1,17 @@
+
+#ifndef RESOURCE_TESTER_H
+#define RESOURCE_TESTER_H
+
+#include <QObject>
+
+class ResourceTester : public QObject
+{
+ Q_OBJECT
+public:
+ explicit ResourceTester(QObject *parent = 0);
+
+private slots:
+ void doTest();
+};
+
+#endif
diff --git a/Tests/QtAutogen/second_resource.qrc b/Tests/QtAutogen/second_resource.qrc
new file mode 100644
index 000000000..27bfb143b
--- /dev/null
+++ b/Tests/QtAutogen/second_resource.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>main.cpp</file>
+</qresource>
+</RCC>
diff --git a/Tests/QtAutogen/second_widget.cpp b/Tests/QtAutogen/second_widget.cpp
new file mode 100644
index 000000000..65ba9627c
--- /dev/null
+++ b/Tests/QtAutogen/second_widget.cpp
@@ -0,0 +1,14 @@
+
+#include "second_widget.h"
+#include "ui_second_widget.h"
+
+SecondWidget::SecondWidget(QWidget *parent)
+ : QWidget(parent), ui(new Ui::SecondWidget)
+{
+ ui->setupUi(this);
+}
+
+SecondWidget::~SecondWidget()
+{
+ delete ui;
+}
diff --git a/Tests/QtAutogen/second_widget.h b/Tests/QtAutogen/second_widget.h
new file mode 100644
index 000000000..fe4d175f7
--- /dev/null
+++ b/Tests/QtAutogen/second_widget.h
@@ -0,0 +1,19 @@
+
+#include <QWidget>
+
+namespace Ui
+{
+class SecondWidget;
+}
+
+class SecondWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit SecondWidget(QWidget *parent = 0);
+
+ ~SecondWidget();
+
+private:
+ Ui::SecondWidget* ui;
+};
diff --git a/Tests/QtAutogen/second_widget.ui b/Tests/QtAutogen/second_widget.ui
new file mode 100644
index 000000000..4effa589c
--- /dev/null
+++ b/Tests/QtAutogen/second_widget.ui
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SecondWidget</class>
+ <widget class="QWidget" name="SecondWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <widget class="QPushButton" name="pushButton">
+ <property name="geometry">
+ <rect>
+ <x>80</x>
+ <y>20</y>
+ <width>94</width>
+ <height>24</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>PushButton</string>
+ </property>
+ </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Tests/QtAutomoc/sub/bar.h b/Tests/QtAutogen/sub/bar.h
index db56b8ed5..db56b8ed5 100644
--- a/Tests/QtAutomoc/sub/bar.h
+++ b/Tests/QtAutogen/sub/bar.h
diff --git a/Tests/QtAutogen/sub/uiconly.cpp b/Tests/QtAutogen/sub/uiconly.cpp
new file mode 100644
index 000000000..cdb33184d
--- /dev/null
+++ b/Tests/QtAutogen/sub/uiconly.cpp
@@ -0,0 +1,13 @@
+
+#include "uiconly.h"
+
+UicOnly::UicOnly(QWidget *parent)
+ : QWidget(parent), ui(new Ui::UicOnly)
+{
+
+}
+
+int main()
+{
+ return 0;
+}
diff --git a/Tests/QtAutogen/sub/uiconly.h b/Tests/QtAutogen/sub/uiconly.h
new file mode 100644
index 000000000..9e21f82e4
--- /dev/null
+++ b/Tests/QtAutogen/sub/uiconly.h
@@ -0,0 +1,20 @@
+
+#ifndef UIC_ONLY_H
+#define UIC_ONLY_H
+
+#include <QWidget>
+#include <memory>
+
+#include "ui_uiconly.h"
+
+class UicOnly : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit UicOnly(QWidget *parent = 0);
+
+private:
+ const std::auto_ptr<Ui::UicOnly> ui;
+};
+
+#endif
diff --git a/Tests/QtAutogen/sub/uiconly.ui b/Tests/QtAutogen/sub/uiconly.ui
new file mode 100644
index 000000000..13fb832eb
--- /dev/null
+++ b/Tests/QtAutogen/sub/uiconly.ui
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>UicOnly</class>
+ <widget class="QWidget" name="UicOnly">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QTreeView" name="treeView"/>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Tests/QtAutogen/targetObjectsTest.cpp b/Tests/QtAutogen/targetObjectsTest.cpp
new file mode 100644
index 000000000..766b7751b
--- /dev/null
+++ b/Tests/QtAutogen/targetObjectsTest.cpp
@@ -0,0 +1,5 @@
+
+int main()
+{
+ return 0;
+}
diff --git a/Tests/QtAutogen/test.qrc b/Tests/QtAutogen/test.qrc
new file mode 100644
index 000000000..c3d4e3cdb
--- /dev/null
+++ b/Tests/QtAutogen/test.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>CMakeLists.txt</file>
+</qresource>
+</RCC>
diff --git a/Tests/QtAutogen/widget1.ui b/Tests/QtAutogen/widget1.ui
new file mode 100644
index 000000000..8fce81a9a
--- /dev/null
+++ b/Tests/QtAutogen/widget1.ui
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Widget1</class>
+ <widget class="QWidget" name="Widget1">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <widget class="QPushButton" name="pushButton">
+ <property name="geometry">
+ <rect>
+ <x>140</x>
+ <y>80</y>
+ <width>80</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>PushButton</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pushButton_2">
+ <property name="geometry">
+ <rect>
+ <x>190</x>
+ <y>170</y>
+ <width>80</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>PushButton</string>
+ </property>
+ </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Tests/QtAutogen/widget2.ui b/Tests/QtAutogen/widget2.ui
new file mode 100644
index 000000000..1f411b9fb
--- /dev/null
+++ b/Tests/QtAutogen/widget2.ui
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Widget2</class>
+ <widget class="QWidget" name="Widget1">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <widget class="QListWidget" name="listWidget">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>20</y>
+ <width>256</width>
+ <height>192</height>
+ </rect>
+ </property>
+ </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Tests/QtAutomoc/xyz.cpp b/Tests/QtAutogen/xyz.cpp
index a3562a337..a3562a337 100644
--- a/Tests/QtAutomoc/xyz.cpp
+++ b/Tests/QtAutogen/xyz.cpp
diff --git a/Tests/QtAutomoc/xyz.h b/Tests/QtAutogen/xyz.h
index 8175d3792..8175d3792 100644
--- a/Tests/QtAutomoc/xyz.h
+++ b/Tests/QtAutogen/xyz.h
diff --git a/Tests/QtAutomoc/yaf.cpp b/Tests/QtAutogen/yaf.cpp
index d278ab422..d278ab422 100644
--- a/Tests/QtAutomoc/yaf.cpp
+++ b/Tests/QtAutogen/yaf.cpp
diff --git a/Tests/QtAutomoc/yaf.h b/Tests/QtAutogen/yaf.h
index 8689f8308..8689f8308 100644
--- a/Tests/QtAutomoc/yaf.h
+++ b/Tests/QtAutogen/yaf.h
diff --git a/Tests/QtAutomoc/yaf_p.h b/Tests/QtAutogen/yaf_p.h
index f0368ade1..f0368ade1 100644
--- a/Tests/QtAutomoc/yaf_p.h
+++ b/Tests/QtAutogen/yaf_p.h
diff --git a/Tests/QtAutomoc/CMakeLists.txt b/Tests/QtAutomoc/CMakeLists.txt
deleted file mode 100644
index 69e52ac5d..000000000
--- a/Tests/QtAutomoc/CMakeLists.txt
+++ /dev/null
@@ -1,68 +0,0 @@
-cmake_minimum_required(VERSION 2.8)
-
-project(QtAutomoc)
-
-if (QT_TEST_VERSION STREQUAL 4)
- find_package(Qt4 REQUIRED)
-
- # Include this directory before using the UseQt4 file.
- add_subdirectory(defines_test)
-
- include(UseQt4)
-
- set(QT_QTCORE_TARGET Qt4::QtCore)
-else()
- if (NOT QT_TEST_VERSION STREQUAL 5)
- message(SEND_ERROR "Invalid Qt version specified.")
- endif()
- find_package(Qt5Widgets REQUIRED)
-
- set(QT_QTCORE_TARGET Qt5::Core)
-
- include_directories(${Qt5Widgets_INCLUDE_DIRS})
- set(QT_LIBRARIES Qt5::Widgets)
-
- if(Qt5_POSITION_INDEPENDENT_CODE)
- set(CMAKE_POSITION_INDEPENDENT_CODE ON)
- endif()
-endif()
-
-
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
-
-add_definitions(-DFOO -DSomeDefine="Barx")
-
-# enable relaxed mode so automoc can handle all the special cases:
-set(CMAKE_AUTOMOC_RELAXED_MODE TRUE)
-
-# create an executable and two library targets, each requiring automoc:
-add_library(codeeditorLib STATIC codeeditor.cpp)
-
-add_library(privateSlot OBJECT private_slot.cpp)
-
-add_executable(foo main.cpp calwidget.cpp foo.cpp blub.cpp bar.cpp abc.cpp
- xyz.cpp yaf.cpp $<TARGET_OBJECTS:privateSlot>)
-
-set_target_properties(foo codeeditorLib privateSlot PROPERTIES AUTOMOC TRUE)
-
-include(GenerateExportHeader)
-# The order is relevant here. B depends on A, and B headers depend on A
-# headers both subdirectories use CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE and we
-# test that CMAKE_AUTOMOC successfully reads the include directories
-# for the build interface from those targets. There has previously been
-# a bug where caching of the include directories happened before
-# extracting the includes to pass to moc.
-add_subdirectory(Bdir)
-add_subdirectory(Adir)
-add_library(libC SHARED libC.cpp)
-set_target_properties(libC PROPERTIES AUTOMOC TRUE)
-generate_export_header(libC)
-target_link_libraries(libC LINK_PUBLIC libB)
-
-target_link_libraries(foo codeeditorLib ${QT_LIBRARIES} libC)
-
-add_library(empty STATIC empty.cpp)
-set_target_properties(empty PROPERTIES AUTOMOC TRUE)
-target_link_libraries(empty no_link_language)
-add_library(no_link_language STATIC empty.h)
-set_target_properties(no_link_language PROPERTIES AUTOMOC TRUE)
diff --git a/Tests/QtAutomoc/calwidget.cpp b/Tests/QtAutomoc/calwidget.cpp
deleted file mode 100644
index cbfa5a8a6..000000000
--- a/Tests/QtAutomoc/calwidget.cpp
+++ /dev/null
@@ -1,431 +0,0 @@
-/****************************************************************************
- **
- ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
- ** All rights reserved.
- ** Contact: Nokia Corporation (qt-info@nokia.com)
- **
- ** This file is part of the examples of the Qt Toolkit.
- **
- ** $QT_BEGIN_LICENSE:BSD$
- ** You may use this file under the terms of the BSD license as follows:
- **
- ** "Redistribution and use in source and binary forms, with or without
- ** modification, are permitted provided that the following conditions are
- ** met:
- ** * Redistributions of source code must retain the above copyright
- ** notice, this list of conditions and the following disclaimer.
- ** * Redistributions in binary form must reproduce the above copyright
- ** notice, this list of conditions and the following disclaimer in
- ** the documentation and/or other materials provided with the
- ** distribution.
- ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
- ** the names of its contributors may be used to endorse or promote
- ** products derived from this software without specific prior written
- ** permission.
- **
- ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
- ** $QT_END_LICENSE$
- **
- ****************************************************************************/
-
- #include <QComboBox>
- #include <QGridLayout>
- #include <QLabel>
- #include <QGroupBox>
- #include <QCheckBox>
- #include <QDateEdit>
- #include <QCalendarWidget>
- #include <QTextCharFormat>
-
- #include "calwidget.h"
-
- Window::Window()
- {
- createPreviewGroupBox();
- createGeneralOptionsGroupBox();
- createDatesGroupBox();
- createTextFormatsGroupBox();
-
- QGridLayout *layout = new QGridLayout;
- layout->addWidget(previewGroupBox, 0, 0);
- layout->addWidget(generalOptionsGroupBox, 0, 1);
- layout->addWidget(datesGroupBox, 1, 0);
- layout->addWidget(textFormatsGroupBox, 1, 1);
- layout->setSizeConstraint(QLayout::SetFixedSize);
- setLayout(layout);
-
- previewLayout->setRowMinimumHeight(0, calendar->sizeHint().height());
- previewLayout->setColumnMinimumWidth(0, calendar->sizeHint().width());
-
- setWindowTitle(tr("Calendar Widget"));
- }
-
- void Window::localeChanged(int index)
- {
- calendar->setLocale(localeCombo->itemData(index).toLocale());
- }
-
- void Window::firstDayChanged(int index)
- {
- calendar->setFirstDayOfWeek(Qt::DayOfWeek(
- firstDayCombo->itemData(index).toInt()));
- }
-
- void Window::selectionModeChanged(int index)
- {
- calendar->setSelectionMode(QCalendarWidget::SelectionMode(
- selectionModeCombo->itemData(index).toInt()));
- }
-
- void Window::horizontalHeaderChanged(int index)
- {
- calendar->setHorizontalHeaderFormat(QCalendarWidget::HorizontalHeaderFormat(
- horizontalHeaderCombo->itemData(index).toInt()));
- }
-
- void Window::verticalHeaderChanged(int index)
- {
- calendar->setVerticalHeaderFormat(QCalendarWidget::VerticalHeaderFormat(
- verticalHeaderCombo->itemData(index).toInt()));
- }
-
- void Window::selectedDateChanged()
- {
- currentDateEdit->setDate(calendar->selectedDate());
- }
-
- void Window::minimumDateChanged(const QDate &date)
- {
- calendar->setMinimumDate(date);
- maximumDateEdit->setDate(calendar->maximumDate());
- }
-
- void Window::maximumDateChanged(const QDate &date)
- {
- calendar->setMaximumDate(date);
- minimumDateEdit->setDate(calendar->minimumDate());
- }
-
- void Window::weekdayFormatChanged()
- {
- QTextCharFormat format;
-
- format.setForeground(qvariant_cast<QColor>(
- weekdayColorCombo->itemData(weekdayColorCombo->currentIndex())));
- calendar->setWeekdayTextFormat(Qt::Monday, format);
- calendar->setWeekdayTextFormat(Qt::Tuesday, format);
- calendar->setWeekdayTextFormat(Qt::Wednesday, format);
- calendar->setWeekdayTextFormat(Qt::Thursday, format);
- calendar->setWeekdayTextFormat(Qt::Friday, format);
- }
-
- void Window::weekendFormatChanged()
- {
- QTextCharFormat format;
-
- format.setForeground(qvariant_cast<QColor>(
- weekendColorCombo->itemData(weekendColorCombo->currentIndex())));
- calendar->setWeekdayTextFormat(Qt::Saturday, format);
- calendar->setWeekdayTextFormat(Qt::Sunday, format);
- }
-
- void Window::reformatHeaders()
- {
- QString text = headerTextFormatCombo->currentText();
- QTextCharFormat format;
-
- if (text == tr("Bold")) {
- format.setFontWeight(QFont::Bold);
- } else if (text == tr("Italic")) {
- format.setFontItalic(true);
- } else if (text == tr("Green")) {
- format.setForeground(Qt::green);
- }
- calendar->setHeaderTextFormat(format);
- }
-
- void Window::reformatCalendarPage()
- {
- if (firstFridayCheckBox->isChecked()) {
- QDate firstFriday(calendar->yearShown(), calendar->monthShown(), 1);
- while (firstFriday.dayOfWeek() != Qt::Friday)
- firstFriday = firstFriday.addDays(1);
- QTextCharFormat firstFridayFormat;
- firstFridayFormat.setForeground(Qt::blue);
- calendar->setDateTextFormat(firstFriday, firstFridayFormat);
- }
-
- //May First in Red takes precedence
- if (mayFirstCheckBox->isChecked()) {
- const QDate mayFirst(calendar->yearShown(), 5, 1);
- QTextCharFormat mayFirstFormat;
- mayFirstFormat.setForeground(Qt::red);
- calendar->setDateTextFormat(mayFirst, mayFirstFormat);
- }
- }
-
- void Window::createPreviewGroupBox()
- {
- previewGroupBox = new QGroupBox(tr("Preview"));
-
- calendar = new QCalendarWidget;
- calendar->setMinimumDate(QDate(1900, 1, 1));
- calendar->setMaximumDate(QDate(3000, 1, 1));
- calendar->setGridVisible(true);
-
- connect(calendar, SIGNAL(currentPageChanged(int,int)),
- this, SLOT(reformatCalendarPage()));
-
- previewLayout = new QGridLayout;
- previewLayout->addWidget(calendar, 0, 0, Qt::AlignCenter);
- previewGroupBox->setLayout(previewLayout);
- }
-
- void Window::createGeneralOptionsGroupBox()
- {
- generalOptionsGroupBox = new QGroupBox(tr("General Options"));
-
- localeCombo = new QComboBox;
- int curLocaleIndex = -1;
- int index = 0;
- for (int _lang = QLocale::C; _lang <= QLocale::LastLanguage; ++_lang) {
- QLocale::Language lang = static_cast<QLocale::Language>(_lang);
- QList<QLocale::Country> countries = QLocale::countriesForLanguage(lang);
- for (int i = 0; i < countries.count(); ++i) {
- QLocale::Country country = countries.at(i);
- QString label = QLocale::languageToString(lang);
- label += QLatin1Char('/');
- label += QLocale::countryToString(country);
- QLocale locale(lang, country);
- if (this->locale().language() == lang && this->locale().country() == country)
- curLocaleIndex = index;
- localeCombo->addItem(label, locale);
- ++index;
- }
- }
- if (curLocaleIndex != -1)
- localeCombo->setCurrentIndex(curLocaleIndex);
- localeLabel = new QLabel(tr("&Locale"));
- localeLabel->setBuddy(localeCombo);
-
- firstDayCombo = new QComboBox;
- firstDayCombo->addItem(tr("Sunday"), Qt::Sunday);
- firstDayCombo->addItem(tr("Monday"), Qt::Monday);
- firstDayCombo->addItem(tr("Tuesday"), Qt::Tuesday);
- firstDayCombo->addItem(tr("Wednesday"), Qt::Wednesday);
- firstDayCombo->addItem(tr("Thursday"), Qt::Thursday);
- firstDayCombo->addItem(tr("Friday"), Qt::Friday);
- firstDayCombo->addItem(tr("Saturday"), Qt::Saturday);
-
- firstDayLabel = new QLabel(tr("Wee&k starts on:"));
- firstDayLabel->setBuddy(firstDayCombo);
-
- selectionModeCombo = new QComboBox;
- selectionModeCombo->addItem(tr("Single selection"),
- QCalendarWidget::SingleSelection);
- selectionModeCombo->addItem(tr("None"), QCalendarWidget::NoSelection);
-
- selectionModeLabel = new QLabel(tr("&Selection mode:"));
- selectionModeLabel->setBuddy(selectionModeCombo);
-
- gridCheckBox = new QCheckBox(tr("&Grid"));
- gridCheckBox->setChecked(calendar->isGridVisible());
-
- navigationCheckBox = new QCheckBox(tr("&Navigation bar"));
- navigationCheckBox->setChecked(true);
-
- horizontalHeaderCombo = new QComboBox;
- horizontalHeaderCombo->addItem(tr("Single letter day names"),
- QCalendarWidget::SingleLetterDayNames);
- horizontalHeaderCombo->addItem(tr("Short day names"),
- QCalendarWidget::ShortDayNames);
- horizontalHeaderCombo->addItem(tr("None"),
- QCalendarWidget::NoHorizontalHeader);
- horizontalHeaderCombo->setCurrentIndex(1);
-
- horizontalHeaderLabel = new QLabel(tr("&Horizontal header:"));
- horizontalHeaderLabel->setBuddy(horizontalHeaderCombo);
-
- verticalHeaderCombo = new QComboBox;
- verticalHeaderCombo->addItem(tr("ISO week numbers"),
- QCalendarWidget::ISOWeekNumbers);
- verticalHeaderCombo->addItem(tr("None"), QCalendarWidget::NoVerticalHeader);
-
- verticalHeaderLabel = new QLabel(tr("&Vertical header:"));
- verticalHeaderLabel->setBuddy(verticalHeaderCombo);
-
- connect(localeCombo, SIGNAL(currentIndexChanged(int)),
- this, SLOT(localeChanged(int)));
- connect(firstDayCombo, SIGNAL(currentIndexChanged(int)),
- this, SLOT(firstDayChanged(int)));
- connect(selectionModeCombo, SIGNAL(currentIndexChanged(int)),
- this, SLOT(selectionModeChanged(int)));
- connect(gridCheckBox, SIGNAL(toggled(bool)),
- calendar, SLOT(setGridVisible(bool)));
- connect(navigationCheckBox, SIGNAL(toggled(bool)),
- calendar, SLOT(setNavigationBarVisible(bool)));
- connect(horizontalHeaderCombo, SIGNAL(currentIndexChanged(int)),
- this, SLOT(horizontalHeaderChanged(int)));
- connect(verticalHeaderCombo, SIGNAL(currentIndexChanged(int)),
- this, SLOT(verticalHeaderChanged(int)));
-
- QHBoxLayout *checkBoxLayout = new QHBoxLayout;
- checkBoxLayout->addWidget(gridCheckBox);
- checkBoxLayout->addStretch();
- checkBoxLayout->addWidget(navigationCheckBox);
-
- QGridLayout *outerLayout = new QGridLayout;
- outerLayout->addWidget(localeLabel, 0, 0);
- outerLayout->addWidget(localeCombo, 0, 1);
- outerLayout->addWidget(firstDayLabel, 1, 0);
- outerLayout->addWidget(firstDayCombo, 1, 1);
- outerLayout->addWidget(selectionModeLabel, 2, 0);
- outerLayout->addWidget(selectionModeCombo, 2, 1);
- outerLayout->addLayout(checkBoxLayout, 3, 0, 1, 2);
- outerLayout->addWidget(horizontalHeaderLabel, 4, 0);
- outerLayout->addWidget(horizontalHeaderCombo, 4, 1);
- outerLayout->addWidget(verticalHeaderLabel, 5, 0);
- outerLayout->addWidget(verticalHeaderCombo, 5, 1);
- generalOptionsGroupBox->setLayout(outerLayout);
-
- firstDayChanged(firstDayCombo->currentIndex());
- selectionModeChanged(selectionModeCombo->currentIndex());
- horizontalHeaderChanged(horizontalHeaderCombo->currentIndex());
- verticalHeaderChanged(verticalHeaderCombo->currentIndex());
- }
-
- void Window::createDatesGroupBox()
- {
- datesGroupBox = new QGroupBox(tr("Dates"));
-
- minimumDateEdit = new QDateEdit;
- minimumDateEdit->setDisplayFormat("MMM d yyyy");
- minimumDateEdit->setDateRange(calendar->minimumDate(),
- calendar->maximumDate());
- minimumDateEdit->setDate(calendar->minimumDate());
-
- minimumDateLabel = new QLabel(tr("&Minimum Date:"));
- minimumDateLabel->setBuddy(minimumDateEdit);
-
- currentDateEdit = new QDateEdit;
- currentDateEdit->setDisplayFormat("MMM d yyyy");
- currentDateEdit->setDate(calendar->selectedDate());
- currentDateEdit->setDateRange(calendar->minimumDate(),
- calendar->maximumDate());
-
- currentDateLabel = new QLabel(tr("&Current Date:"));
- currentDateLabel->setBuddy(currentDateEdit);
-
- maximumDateEdit = new QDateEdit;
- maximumDateEdit->setDisplayFormat("MMM d yyyy");
- maximumDateEdit->setDateRange(calendar->minimumDate(),
- calendar->maximumDate());
- maximumDateEdit->setDate(calendar->maximumDate());
-
- maximumDateLabel = new QLabel(tr("Ma&ximum Date:"));
- maximumDateLabel->setBuddy(maximumDateEdit);
-
- connect(currentDateEdit, SIGNAL(dateChanged(QDate)),
- calendar, SLOT(setSelectedDate(QDate)));
- connect(calendar, SIGNAL(selectionChanged()),
- this, SLOT(selectedDateChanged()));
- connect(minimumDateEdit, SIGNAL(dateChanged(QDate)),
- this, SLOT(minimumDateChanged(QDate)));
- connect(maximumDateEdit, SIGNAL(dateChanged(QDate)),
- this, SLOT(maximumDateChanged(QDate)));
-
- QGridLayout *dateBoxLayout = new QGridLayout;
- dateBoxLayout->addWidget(currentDateLabel, 1, 0);
- dateBoxLayout->addWidget(currentDateEdit, 1, 1);
- dateBoxLayout->addWidget(minimumDateLabel, 0, 0);
- dateBoxLayout->addWidget(minimumDateEdit, 0, 1);
- dateBoxLayout->addWidget(maximumDateLabel, 2, 0);
- dateBoxLayout->addWidget(maximumDateEdit, 2, 1);
- dateBoxLayout->setRowStretch(3, 1);
-
- datesGroupBox->setLayout(dateBoxLayout);
- }
-
- void Window::createTextFormatsGroupBox()
- {
- textFormatsGroupBox = new QGroupBox(tr("Text Formats"));
-
- weekdayColorCombo = createColorComboBox();
- weekdayColorCombo->setCurrentIndex(
- weekdayColorCombo->findText(tr("Black")));
-
- weekdayColorLabel = new QLabel(tr("&Weekday color:"));
- weekdayColorLabel->setBuddy(weekdayColorCombo);
-
- weekendColorCombo = createColorComboBox();
- weekendColorCombo->setCurrentIndex(
- weekendColorCombo->findText(tr("Red")));
-
- weekendColorLabel = new QLabel(tr("Week&end color:"));
- weekendColorLabel->setBuddy(weekendColorCombo);
-
- headerTextFormatCombo = new QComboBox;
- headerTextFormatCombo->addItem(tr("Bold"));
- headerTextFormatCombo->addItem(tr("Italic"));
- headerTextFormatCombo->addItem(tr("Plain"));
-
- headerTextFormatLabel = new QLabel(tr("&Header text:"));
- headerTextFormatLabel->setBuddy(headerTextFormatCombo);
-
- firstFridayCheckBox = new QCheckBox(tr("&First Friday in blue"));
-
- mayFirstCheckBox = new QCheckBox(tr("May &1 in red"));
-
- connect(weekdayColorCombo, SIGNAL(currentIndexChanged(int)),
- this, SLOT(weekdayFormatChanged()));
- connect(weekendColorCombo, SIGNAL(currentIndexChanged(int)),
- this, SLOT(weekendFormatChanged()));
- connect(headerTextFormatCombo, SIGNAL(currentIndexChanged(QString)),
- this, SLOT(reformatHeaders()));
- connect(firstFridayCheckBox, SIGNAL(toggled(bool)),
- this, SLOT(reformatCalendarPage()));
- connect(mayFirstCheckBox, SIGNAL(toggled(bool)),
- this, SLOT(reformatCalendarPage()));
-
- QHBoxLayout *checkBoxLayout = new QHBoxLayout;
- checkBoxLayout->addWidget(firstFridayCheckBox);
- checkBoxLayout->addStretch();
- checkBoxLayout->addWidget(mayFirstCheckBox);
-
- QGridLayout *outerLayout = new QGridLayout;
- outerLayout->addWidget(weekdayColorLabel, 0, 0);
- outerLayout->addWidget(weekdayColorCombo, 0, 1);
- outerLayout->addWidget(weekendColorLabel, 1, 0);
- outerLayout->addWidget(weekendColorCombo, 1, 1);
- outerLayout->addWidget(headerTextFormatLabel, 2, 0);
- outerLayout->addWidget(headerTextFormatCombo, 2, 1);
- outerLayout->addLayout(checkBoxLayout, 3, 0, 1, 2);
- textFormatsGroupBox->setLayout(outerLayout);
-
- weekdayFormatChanged();
- weekendFormatChanged();
- reformatHeaders();
- reformatCalendarPage();
- }
-
-QComboBox *Window::createColorComboBox()
- {
- QComboBox *comboBox = new QComboBox;
- comboBox->addItem(tr("Red"), QColor(Qt::red));
- comboBox->addItem(tr("Blue"), QColor(Qt::blue));
- comboBox->addItem(tr("Black"), QColor(Qt::black));
- comboBox->addItem(tr("Magenta"), QColor(Qt::magenta));
- return comboBox;
- }
-
-//#include "moc_calwidget.cpp"
diff --git a/Tests/QtAutomoc/calwidget.h b/Tests/QtAutomoc/calwidget.h
deleted file mode 100644
index 844738937..000000000
--- a/Tests/QtAutomoc/calwidget.h
+++ /dev/null
@@ -1,121 +0,0 @@
- /****************************************************************************
- **
- ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
- ** All rights reserved.
- ** Contact: Nokia Corporation (qt-info@nokia.com)
- **
- ** This file is part of the examples of the Qt Toolkit.
- **
- ** $QT_BEGIN_LICENSE:BSD$
- ** You may use this file under the terms of the BSD license as follows:
- **
- ** "Redistribution and use in source and binary forms, with or without
- ** modification, are permitted provided that the following conditions are
- ** met:
- ** * Redistributions of source code must retain the above copyright
- ** notice, this list of conditions and the following disclaimer.
- ** * Redistributions in binary form must reproduce the above copyright
- ** notice, this list of conditions and the following disclaimer in
- ** the documentation and/or other materials provided with the
- ** distribution.
- ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
- ** the names of its contributors may be used to endorse or promote
- ** products derived from this software without specific prior written
- ** permission.
- **
- ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
- ** $QT_END_LICENSE$
- **
- ****************************************************************************/
-
-#ifndef WINDOW_H
-#define WINDOW_H
-
-#include <QWidget>
-
- class QCalendarWidget;
- class QCheckBox;
- class QComboBox;
- class QDate;
- class QDateEdit;
- class QGridLayout;
- class QGroupBox;
- class QLabel;
-
- class Window : public QWidget
- {
- Q_OBJECT
-
- public:
- Window();
-
- private slots:
- void localeChanged(int index);
- void firstDayChanged(int index);
- void selectionModeChanged(int index);
- void horizontalHeaderChanged(int index);
- void verticalHeaderChanged(int index);
- void selectedDateChanged();
- void minimumDateChanged(const QDate &date);
- void maximumDateChanged(const QDate &date);
- void weekdayFormatChanged();
- void weekendFormatChanged();
- void reformatHeaders();
- void reformatCalendarPage();
-
- private:
- void createPreviewGroupBox();
- void createGeneralOptionsGroupBox();
- void createDatesGroupBox();
- void createTextFormatsGroupBox();
- QComboBox *createColorComboBox();
-
- QGroupBox *previewGroupBox;
- QGridLayout *previewLayout;
- QCalendarWidget *calendar;
-
- QGroupBox *generalOptionsGroupBox;
- QLabel *localeLabel;
- QLabel *firstDayLabel;
- QLabel *selectionModeLabel;
- QLabel *horizontalHeaderLabel;
- QLabel *verticalHeaderLabel;
- QComboBox *localeCombo;
- QComboBox *firstDayCombo;
- QComboBox *selectionModeCombo;
- QCheckBox *gridCheckBox;
- QCheckBox *navigationCheckBox;
- QComboBox *horizontalHeaderCombo;
- QComboBox *verticalHeaderCombo;
-
- QGroupBox *datesGroupBox;
- QLabel *currentDateLabel;
- QLabel *minimumDateLabel;
- QLabel *maximumDateLabel;
- QDateEdit *currentDateEdit;
- QDateEdit *minimumDateEdit;
- QDateEdit *maximumDateEdit;
-
- QGroupBox *textFormatsGroupBox;
- QLabel *weekdayColorLabel;
- QLabel *weekendColorLabel;
- QLabel *headerTextFormatLabel;
- QComboBox *weekdayColorCombo;
- QComboBox *weekendColorCombo;
- QComboBox *headerTextFormatCombo;
-
- QCheckBox *firstFridayCheckBox;
- QCheckBox *mayFirstCheckBox;
- };
-
- #endif
diff --git a/Tests/QtAutomoc/main.cpp b/Tests/QtAutomoc/main.cpp
deleted file mode 100644
index bd80180bf..000000000
--- a/Tests/QtAutomoc/main.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************************
- **
- ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
- ** All rights reserved.
- ** Contact: Nokia Corporation (qt-info@nokia.com)
- **
- ** This file is part of the examples of the Qt Toolkit.
- **
- ** $QT_BEGIN_LICENSE:BSD$
- ** You may use this file under the terms of the BSD license as follows:
- **
- ** "Redistribution and use in source and binary forms, with or without
- ** modification, are permitted provided that the following conditions are
- ** met:
- ** * Redistributions of source code must retain the above copyright
- ** notice, this list of conditions and the following disclaimer.
- ** * Redistributions in binary form must reproduce the above copyright
- ** notice, this list of conditions and the following disclaimer in
- ** the documentation and/or other materials provided with the
- ** distribution.
- ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
- ** the names of its contributors may be used to endorse or promote
- ** products derived from this software without specific prior written
- ** permission.
- **
- ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
- ** $QT_END_LICENSE$
- **
- ****************************************************************************/
-
-#include <QApplication>
-
-#include "codeeditor.h"
-#include "calwidget.h"
-#include "foo.h"
-#include "blub.h"
-#include "sub/bar.h"
-#include "abc.h"
-#include "xyz.h"
-#include "yaf.h"
-#include "libC.h"
-
-int main(int argv, char **args)
-{
- QApplication app(argv, args);
-
- CodeEditor editor;
- editor.setWindowTitle(QObject::tr("Code Editor Example"));
- editor.show();
-
- Window w;
- w.show();
-
- Foo foo;
- foo.doFoo();
-
- Blub b;
- b.blubber();
-
- Bar bar;
- bar.doBar();
-
- Abc abc;
- abc.doAbc();
-
- Xyz xyz;
- xyz.doXyz();
-
- Yaf yaf;
- yaf.doYaf();
-
- LibC lc;
- lc.foo();
-
- return app.exec();
-}
diff --git a/Tests/RegexEscapeString.cmake b/Tests/RegexEscapeString.cmake
deleted file mode 100644
index 92aed17b1..000000000
--- a/Tests/RegexEscapeString.cmake
+++ /dev/null
@@ -1,4 +0,0 @@
-macro(REGEX_ESCAPE_STRING _OUT _IN)
- # Escape special regex metacharacters with a backslash
- string(REGEX REPLACE "([$^.[|*+?()]|])" "\\\\\\1" ${_OUT} "${_IN}")
-endmacro()
diff --git a/Tests/RunCMake/AutoExportDll/AutoExport.cmake b/Tests/RunCMake/AutoExportDll/AutoExport.cmake
new file mode 100644
index 000000000..3b2b2c5b4
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/AutoExport.cmake
@@ -0,0 +1,7 @@
+project(autoexport)
+set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${autoexport_BINARY_DIR}/bin)
+add_subdirectory(sub)
+add_library(autoexport SHARED hello.cxx world.cxx foo.c)
+add_executable(say say.cxx)
+target_link_libraries(say autoexport autoexport2)
diff --git a/Tests/RunCMake/AutoExportDll/AutoExportBuild-stderr.txt b/Tests/RunCMake/AutoExportDll/AutoExportBuild-stderr.txt
new file mode 100644
index 000000000..d483c2ce1
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/AutoExportBuild-stderr.txt
@@ -0,0 +1 @@
+^.*$
diff --git a/Tests/RunCMake/AutoExportDll/CMakeLists.txt b/Tests/RunCMake/AutoExportDll/CMakeLists.txt
new file mode 100644
index 000000000..18dfd2686
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.2)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake b/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake
new file mode 100644
index 000000000..3784a6a14
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake
@@ -0,0 +1,26 @@
+include(RunCMake)
+set(RunCMake_TEST_NO_CLEAN TRUE)
+set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/AutoExport-build")
+# start by cleaning up because we don't clean up along the way
+file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+# configure the AutoExport test
+run_cmake(AutoExport)
+unset(RunCMake_TEST_OPTIONS)
+# don't run this test on VS 6 as it is not supported
+if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 6|Watcom WMake|Borland Makefiles")
+ return()
+endif()
+# we build debug so the say.exe will be found in Debug/say.exe for
+# Visual Studio generators
+if("${RunCMake_GENERATOR}" MATCHES "Visual Studio|Xcode")
+ set(INTDIR "Debug/")
+endif()
+# build AutoExport
+run_cmake_command(AutoExportBuild ${CMAKE_COMMAND} --build
+ ${RunCMake_TEST_BINARY_DIR} --config Debug --clean-first)
+# run the executable that uses symbols from the dll
+if(WIN32)
+ set(EXE_EXT ".exe")
+endif()
+run_cmake_command(AutoExportRun
+ ${RunCMake_BINARY_DIR}/AutoExport-build/bin/${INTDIR}say${EXE_EXT})
diff --git a/Tests/RunCMake/AutoExportDll/foo.c b/Tests/RunCMake/AutoExportDll/foo.c
new file mode 100644
index 000000000..4b1318b9e
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/foo.c
@@ -0,0 +1,15 @@
+#ifdef _MSC_VER
+#include "windows.h"
+#else
+#define WINAPI
+#endif
+
+int WINAPI foo()
+{
+ return 10;
+}
+
+int bar()
+{
+ return 5;
+}
diff --git a/Tests/RunCMake/AutoExportDll/hello.cxx b/Tests/RunCMake/AutoExportDll/hello.cxx
new file mode 100644
index 000000000..3933fc114
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/hello.cxx
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include "hello.h"
+int Hello::Data = 0;
+void Hello::real()
+{
+ return;
+}
+void hello()
+{
+ printf("hello");
+}
+void Hello::operator delete[](void*) {};
+void Hello::operator delete(void*) {};
diff --git a/Tests/RunCMake/AutoExportDll/hello.h b/Tests/RunCMake/AutoExportDll/hello.h
new file mode 100644
index 000000000..3749b976f
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/hello.h
@@ -0,0 +1,18 @@
+#ifndef _MSC_VER
+#define winexport
+#else
+#ifdef autoexport_EXPORTS
+#define winexport
+#else
+#define winexport __declspec(dllimport)
+#endif
+#endif
+
+class Hello
+{
+public:
+ static winexport int Data;
+ void real();
+ static void operator delete[](void*);
+ static void operator delete(void*);
+};
diff --git a/Tests/RunCMake/AutoExportDll/say.cxx b/Tests/RunCMake/AutoExportDll/say.cxx
new file mode 100644
index 000000000..655b3c21a
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/say.cxx
@@ -0,0 +1,37 @@
+#include <stdio.h>
+#include "hello.h"
+#ifdef _MSC_VER
+#include "windows.h"
+#else
+#define WINAPI
+#endif
+
+extern "C"
+{
+// test __cdecl stuff
+ int WINAPI foo();
+// test regular C
+ int bar();
+}
+
+// test c++ functions
+// forward declare hello and world
+void hello();
+void world();
+
+int main()
+{
+ // test static data (needs declspec to work)
+ Hello::Data = 120;
+ Hello h;
+ h.real();
+ hello();
+ printf(" ");
+ world();
+ printf("\n");
+ foo();
+ printf("\n");
+ bar();
+ printf("\n");
+ return 0;
+}
diff --git a/Tests/RunCMake/AutoExportDll/sub/CMakeLists.txt b/Tests/RunCMake/AutoExportDll/sub/CMakeLists.txt
new file mode 100644
index 000000000..8b70e7dfa
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/sub/CMakeLists.txt
@@ -0,0 +1,5 @@
+add_library(autoexport2 SHARED sub.cxx)
+if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
+ # Try msvc "big" object format.
+ target_compile_options(autoexport2 PRIVATE /bigobj)
+endif()
diff --git a/Tests/RunCMake/AutoExportDll/sub/sub.cxx b/Tests/RunCMake/AutoExportDll/sub/sub.cxx
new file mode 100644
index 000000000..9a3145ec4
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/sub/sub.cxx
@@ -0,0 +1,6 @@
+#include <stdio.h>
+int sub()
+{
+ printf("");
+ return 10;
+}
diff --git a/Tests/RunCMake/AutoExportDll/world.cxx b/Tests/RunCMake/AutoExportDll/world.cxx
new file mode 100644
index 000000000..3a54df315
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/world.cxx
@@ -0,0 +1,6 @@
+#include "stdio.h"
+
+void world()
+{
+ printf("world");
+}
diff --git a/Tests/RunCMake/BuildDepends/C-Exe-Manifest.cmake b/Tests/RunCMake/BuildDepends/C-Exe-Manifest.cmake
new file mode 100644
index 000000000..ef3301216
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/C-Exe-Manifest.cmake
@@ -0,0 +1,19 @@
+enable_language(C)
+
+add_executable(main main.c ${CMAKE_CURRENT_BINARY_DIR}/test.manifest)
+
+if(MSVC AND NOT MSVC_VERSION LESS 1400)
+ set(EXTRA_CHECK [[
+file(STRINGS "$<TARGET_FILE:main>" content REGEX "name=\"Kitware.CMake.C-Exe-Manifest-step[0-9]\"")
+if(NOT "${content}" MATCHES "name=\"Kitware.CMake.C-Exe-Manifest-step${check_step}\"")
+ set(RunCMake_TEST_FAILED "Binary has no manifest with name=\"Kitware.CMake.C-Exe-Manifest-step${check_step}\":\n ${content}")
+endif()
+]])
+endif()
+
+file(GENERATE OUTPUT check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT "
+set(check_pairs
+ \"$<TARGET_FILE:main>|${CMAKE_CURRENT_BINARY_DIR}/test.manifest\"
+ )
+${EXTRA_CHECK}
+")
diff --git a/Tests/RunCMake/BuildDepends/C-Exe-Manifest.step1.cmake b/Tests/RunCMake/BuildDepends/C-Exe-Manifest.step1.cmake
new file mode 100644
index 000000000..c0b939db7
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/C-Exe-Manifest.step1.cmake
@@ -0,0 +1,6 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/test.manifest" [[
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity type="win32" version="1.0.0.0"
+ name="Kitware.CMake.C-Exe-Manifest-step1"/>
+</assembly>
+]])
diff --git a/Tests/RunCMake/BuildDepends/C-Exe-Manifest.step2.cmake b/Tests/RunCMake/BuildDepends/C-Exe-Manifest.step2.cmake
new file mode 100644
index 000000000..a75bf213c
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/C-Exe-Manifest.step2.cmake
@@ -0,0 +1,6 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/test.manifest" [[
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity type="win32" version="1.0.0.0"
+ name="Kitware.CMake.C-Exe-Manifest-step2"/>
+</assembly>
+]])
diff --git a/Tests/RunCMake/BuildDepends/C-Exe.cmake b/Tests/RunCMake/BuildDepends/C-Exe.cmake
new file mode 100644
index 000000000..5057ca91d
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/C-Exe.cmake
@@ -0,0 +1,12 @@
+enable_language(C)
+
+add_executable(main ${CMAKE_CURRENT_BINARY_DIR}/main.c)
+
+file(GENERATE OUTPUT check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT "
+set(check_pairs
+ \"$<TARGET_FILE:main>|${CMAKE_CURRENT_BINARY_DIR}/main.c\"
+ )
+set(check_exes
+ \"$<TARGET_FILE:main>\"
+ )
+")
diff --git a/Tests/RunCMake/BuildDepends/C-Exe.step1.cmake b/Tests/RunCMake/BuildDepends/C-Exe.step1.cmake
new file mode 100644
index 000000000..08e29495a
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/C-Exe.step1.cmake
@@ -0,0 +1,3 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/main.c" [[
+int main(void) { return 1; }
+]])
diff --git a/Tests/RunCMake/BuildDepends/C-Exe.step2.cmake b/Tests/RunCMake/BuildDepends/C-Exe.step2.cmake
new file mode 100644
index 000000000..ee4530cfb
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/C-Exe.step2.cmake
@@ -0,0 +1,3 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/main.c" [[
+int main(void) { return 2; }
+]])
diff --git a/Tests/RunCMake/BuildDepends/CMakeLists.txt b/Tests/RunCMake/BuildDepends/CMakeLists.txt
new file mode 100644
index 000000000..74b3ff8de
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.3)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/BuildDepends/Custom-Always.cmake b/Tests/RunCMake/BuildDepends/Custom-Always.cmake
new file mode 100644
index 000000000..d412708a1
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/Custom-Always.cmake
@@ -0,0 +1,24 @@
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/before-always
+ COMMAND ${CMAKE_COMMAND} -E touch before-always
+ )
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/always
+ COMMAND ${CMAKE_COMMAND} -E touch always-updated
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/before-always
+ )
+set_property(SOURCE always PROPERTY SYMBOLIC 1)
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/after-always
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/always
+ COMMAND ${CMAKE_COMMAND} -E touch after-always
+ )
+
+add_custom_target(drive ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/after-always)
+
+file(GENERATE OUTPUT check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT "
+set(check_pairs
+ \"${CMAKE_CURRENT_BINARY_DIR}/always-updated|${CMAKE_CURRENT_BINARY_DIR}/before-always\"
+ \"${CMAKE_CURRENT_BINARY_DIR}/after-always|${CMAKE_CURRENT_BINARY_DIR}/always-updated\"
+ )
+")
diff --git a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
new file mode 100644
index 000000000..31c72fbe1
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
@@ -0,0 +1,42 @@
+include(RunCMake)
+
+if(RunCMake_GENERATOR STREQUAL "Borland Makefiles")
+ set(fs_delay 3)
+else()
+ set(fs_delay 1.125)
+endif()
+
+function(run_BuildDepends CASE)
+ # Use a single build tree for a few tests without cleaning.
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${CASE}-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ if(RunCMake_GENERATOR MATCHES "Make|Ninja")
+ set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
+ endif()
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ include(${RunCMake_SOURCE_DIR}/${CASE}.step1.cmake OPTIONAL)
+ run_cmake(${CASE})
+ set(RunCMake-check-file check.cmake)
+ set(check_step 1)
+ run_cmake_command(${CASE}-build1 ${CMAKE_COMMAND} --build . --config Debug)
+ if(run_BuildDepends_skip_step_2)
+ return()
+ endif()
+ execute_process(COMMAND ${CMAKE_COMMAND} -E sleep ${fs_delay}) # handle 1s resolution
+ include(${RunCMake_SOURCE_DIR}/${CASE}.step2.cmake OPTIONAL)
+ set(check_step 2)
+ run_cmake_command(${CASE}-build2 ${CMAKE_COMMAND} --build . --config Debug)
+endfunction()
+
+run_BuildDepends(C-Exe)
+if(NOT RunCMake_GENERATOR MATCHES "Visual Studio [67]|Xcode")
+ if(RunCMake_GENERATOR MATCHES "Visual Studio 10")
+ # VS 10 forgets to re-link when a manifest changes
+ set(run_BuildDepends_skip_step_2 1)
+ endif()
+ run_BuildDepends(C-Exe-Manifest)
+ unset(run_BuildDepends_skip_step_2)
+endif()
+
+run_BuildDepends(Custom-Always)
diff --git a/Tests/RunCMake/BuildDepends/check.cmake b/Tests/RunCMake/BuildDepends/check.cmake
new file mode 100644
index 000000000..26a9eb65d
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/check.cmake
@@ -0,0 +1,37 @@
+if(EXISTS ${RunCMake_TEST_BINARY_DIR}/check-debug.cmake)
+ include(${RunCMake_TEST_BINARY_DIR}/check-debug.cmake)
+ if(RunCMake_TEST_FAILED)
+ return()
+ endif()
+ foreach(exe IN LISTS check_exes)
+ execute_process(COMMAND ${exe} RESULT_VARIABLE res)
+ if(NOT res EQUAL ${check_step})
+ set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}
+ '${exe}' returned '${res}' but expected '${check_step}'
+")
+ endif()
+ endforeach()
+ foreach(p IN LISTS check_pairs)
+ if("${p}" MATCHES "^(.*)\\|(.*)$")
+ set(lhs "${CMAKE_MATCH_1}")
+ set(rhs "${CMAKE_MATCH_2}")
+ if(NOT EXISTS "${lhs}")
+ set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}
+ '${lhs}' missing
+")
+ elseif(NOT EXISTS "${rhs}")
+ set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}
+ '${rhs}' missing
+")
+ elseif(NOT "${lhs}" IS_NEWER_THAN "${rhs}")
+ set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}
+ '${lhs}' is not newer than '${rhs}'
+")
+ endif()
+ endif()
+ endforeach()
+else()
+ set(RunCMake_TEST_FAILED "
+ '${RunCMake_TEST_BINARY_DIR}/check-debug.cmake' missing
+")
+endif()
diff --git a/Tests/RunCMake/BuildDepends/main.c b/Tests/RunCMake/BuildDepends/main.c
new file mode 100644
index 000000000..78f2de106
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/main.c
@@ -0,0 +1 @@
+int main(void) { return 0; }
diff --git a/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt b/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt
index 03faef90e..1e4b47d0c 100644
--- a/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt
+++ b/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt
@@ -21,13 +21,13 @@ CMake Warning \(dev\) in CMakeLists.txt:
/usr/include/VAL_INCLUDE;/usr/include/normal
- Evaluated link directory
+ Evaluated link directories
- /usr/lib/\${VAR_LINK_DIRS}
+ /usr/lib/\${VAR_LINK_DIRS};/usr/lib/normal
as
- /usr/lib/VAL_LINK_DIRS
+ /usr/lib/VAL_LINK_DIRS;/usr/lib/normal
Evaluated link library
diff --git a/Tests/RunCMake/CMP0019/CMakeLists.txt b/Tests/RunCMake/CMP0019/CMakeLists.txt
index 12cd3c775..8f85fbf54 100644
--- a/Tests/RunCMake/CMP0019/CMakeLists.txt
+++ b/Tests/RunCMake/CMP0019/CMakeLists.txt
@@ -1,3 +1,3 @@
cmake_minimum_required(VERSION 2.8.4)
project(${RunCMake_TEST} NONE)
-include(${RunCMake_TEST}.cmake)
+include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE)
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared.cmake b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared.cmake
index 57c3ed0d7..2e76ee0df 100644
--- a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared.cmake
+++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared.cmake
@@ -1,5 +1,7 @@
enable_language(CXX)
+cmake_policy(SET CMP0042 NEW)
+
add_library(foo SHARED empty_vs6_1.cpp)
add_library(bar SHARED empty_vs6_2.cpp)
target_link_libraries(bar foo)
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-NEW.cmake b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-NEW.cmake
new file mode 100644
index 000000000..3fee15d8b
--- /dev/null
+++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-NEW.cmake
@@ -0,0 +1,14 @@
+
+project(CMP0022-NOWARN-static-NEW)
+
+cmake_policy(SET CMP0022 NEW)
+
+add_library(foo STATIC empty_vs6_1.cpp)
+add_library(bar STATIC empty_vs6_2.cpp)
+add_library(bat STATIC empty_vs6_3.cpp)
+target_link_libraries(foo bar)
+# The last element here needs to contain a space so that it is a single
+# element which is not a valid target name. As bar is a STATIC library,
+# this tests that the LINK_ONLY generator expression is not used for
+# that element, creating an error.
+target_link_libraries(bar LINK_PRIVATE bat "-lz -lm")
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-link_libraries-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-link_libraries-stderr.txt
deleted file mode 100644
index 10f32932e..000000000
--- a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-link_libraries-stderr.txt
+++ /dev/null
@@ -1 +0,0 @@
-^$
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-stderr.txt
deleted file mode 100644
index 10f32932e..000000000
--- a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-stderr.txt
+++ /dev/null
@@ -1 +0,0 @@
-^$
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static.cmake b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static.cmake
index ad3b8df74..3e4144fcd 100644
--- a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static.cmake
+++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static.cmake
@@ -5,8 +5,4 @@ add_library(foo STATIC empty_vs6_1.cpp)
add_library(bar STATIC empty_vs6_2.cpp)
add_library(bat STATIC empty_vs6_3.cpp)
target_link_libraries(foo bar)
-# The last element here needs to contain a space so that it is a single
-# element which is not a valid target name. As bar is a STATIC library,
-# this tests that the LINK_ONLY generator expression is not used for
-# that element, creating an error.
-target_link_libraries(bar bat "-lz -lm")
+target_link_libraries(bar bat)
diff --git a/Tests/RunCMake/CMP0022/CMP0022-WARN.cmake b/Tests/RunCMake/CMP0022/CMP0022-WARN.cmake
index fe7e858b7..e3552b2f0 100644
--- a/Tests/RunCMake/CMP0022/CMP0022-WARN.cmake
+++ b/Tests/RunCMake/CMP0022/CMP0022-WARN.cmake
@@ -1,6 +1,8 @@
project(CMP0022-WARN)
+cmake_policy(SET CMP0042 NEW)
+
add_library(foo SHARED empty_vs6_1.cpp)
add_library(bar SHARED empty_vs6_2.cpp)
add_library(bat SHARED empty_vs6_3.cpp)
diff --git a/Tests/RunCMake/CMP0022/CMP0022-export-exe-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-export-exe-stderr.txt
deleted file mode 100644
index 10f32932e..000000000
--- a/Tests/RunCMake/CMP0022/CMP0022-export-exe-stderr.txt
+++ /dev/null
@@ -1 +0,0 @@
-^$
diff --git a/Tests/RunCMake/CMP0022/CMP0022-export-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-export-stderr.txt
index ae7627e1e..405dd8dc8 100644
--- a/Tests/RunCMake/CMP0022/CMP0022-export-stderr.txt
+++ b/Tests/RunCMake/CMP0022/CMP0022-export-stderr.txt
@@ -1,4 +1,4 @@
-CMake Error at CMP0022-export.cmake:11 \(export\):
+CMake Error in CMakeLists.txt:
Target "cmp0022NEW" has policy CMP0022 enabled, but also has old-style
LINK_INTERFACE_LIBRARIES properties populated, but it was exported without
the EXPORT_LINK_INTERFACE_LIBRARIES to export the old-style properties
diff --git a/Tests/RunCMake/CMP0022/RunCMakeTest.cmake b/Tests/RunCMake/CMP0022/RunCMakeTest.cmake
index 2781d2094..4c1099607 100644
--- a/Tests/RunCMake/CMP0022/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CMP0022/RunCMakeTest.cmake
@@ -7,6 +7,7 @@ run_cmake(CMP0022-WARN-empty-old)
run_cmake(CMP0022-NOWARN-exe)
run_cmake(CMP0022-NOWARN-shared)
run_cmake(CMP0022-NOWARN-static)
+run_cmake(CMP0022-NOWARN-static-NEW)
run_cmake(CMP0022-NOWARN-static-link_libraries)
run_cmake(CMP0022-export)
run_cmake(CMP0022-export-exe)
diff --git a/Tests/RunCMake/ExternalData/Directory3-result.txt b/Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-NEW-result.txt
index d00491fd7..d00491fd7 100644
--- a/Tests/RunCMake/ExternalData/Directory3-result.txt
+++ b/Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-NEW-result.txt
diff --git a/Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-NEW-stderr.txt b/Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-NEW-stderr.txt
new file mode 100644
index 000000000..05b021746
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-NEW-stderr.txt
@@ -0,0 +1,7 @@
+CMake Error at CMP0026-CONFIG-LOCATION-NEW.cmake:7 \(get_target_property\):
+ The LOCATION property may not be read from target "somelib". Use the
+ target name directly with add_custom_command, or use the generator
+ expression \$<TARGET_FILE>, as appropriate.
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-NEW.cmake b/Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-NEW.cmake
new file mode 100644
index 000000000..1b373e75d
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-NEW.cmake
@@ -0,0 +1,7 @@
+
+enable_language(CXX)
+
+cmake_policy(SET CMP0026 NEW)
+
+add_library(somelib empty.cpp)
+get_target_property(_loc somelib Debug_LOCATION)
diff --git a/Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-OLD-result.txt b/Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-OLD-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-OLD-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-OLD.cmake b/Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-OLD.cmake
new file mode 100644
index 000000000..416682879
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-OLD.cmake
@@ -0,0 +1,7 @@
+
+enable_language(CXX)
+
+cmake_policy(SET CMP0026 OLD)
+
+add_library(somelib empty.cpp)
+get_target_property(_loc somelib Debug_LOCATION)
diff --git a/Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-WARN-result.txt b/Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-WARN-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-WARN-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-WARN-stderr.txt b/Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-WARN-stderr.txt
new file mode 100644
index 000000000..d44dcb48d
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-WARN-stderr.txt
@@ -0,0 +1,12 @@
+CMake Warning \(dev\) at CMP0026-CONFIG-LOCATION-WARN.cmake:5 \(get_target_property\):
+ Policy CMP0026 is not set: Disallow use of the LOCATION target property.
+ Run "cmake --help-policy CMP0026" for policy details. Use the cmake_policy
+ command to set the policy and suppress this warning.
+
+ The LOCATION property should not be read from target "somelib". Use the
+ target name directly with add_custom_command, or use the generator
+ expression \$<TARGET_FILE>, as appropriate.
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-WARN.cmake b/Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-WARN.cmake
new file mode 100644
index 000000000..511056fef
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-WARN.cmake
@@ -0,0 +1,5 @@
+
+enable_language(CXX)
+
+add_library(somelib empty.cpp)
+get_target_property(_loc somelib Debug_LOCATION)
diff --git a/Tests/RunCMake/CMP0026/CMP0026-IMPORTED-result.txt b/Tests/RunCMake/CMP0026/CMP0026-IMPORTED-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/CMP0026-IMPORTED-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0026/CMP0026-IMPORTED.cmake b/Tests/RunCMake/CMP0026/CMP0026-IMPORTED.cmake
new file mode 100644
index 000000000..650c8a5c7
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/CMP0026-IMPORTED.cmake
@@ -0,0 +1,6 @@
+
+enable_language(CXX)
+
+add_library(someimportedlib SHARED IMPORTED)
+
+get_target_property(_loc someimportedlib LOCATION)
diff --git a/Tests/RunCMake/ExternalData/MissingData-result.txt b/Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-NEW-result.txt
index d00491fd7..d00491fd7 100644
--- a/Tests/RunCMake/ExternalData/MissingData-result.txt
+++ b/Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-NEW-result.txt
diff --git a/Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-NEW-stderr.txt b/Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-NEW-stderr.txt
new file mode 100644
index 000000000..fec9dfb4d
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-NEW-stderr.txt
@@ -0,0 +1,7 @@
+CMake Error at CMP0026-LOCATION-CONFIG-NEW.cmake:7 \(get_target_property\):
+ The LOCATION property may not be read from target "somelib". Use the
+ target name directly with add_custom_command, or use the generator
+ expression \$<TARGET_FILE>, as appropriate.
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-NEW.cmake b/Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-NEW.cmake
new file mode 100644
index 000000000..e6aa509af
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-NEW.cmake
@@ -0,0 +1,7 @@
+
+enable_language(CXX)
+
+cmake_policy(SET CMP0026 NEW)
+
+add_library(somelib empty.cpp)
+get_target_property(_loc somelib LOCATION_Debug)
diff --git a/Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-OLD-result.txt b/Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-OLD-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-OLD-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-OLD.cmake b/Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-OLD.cmake
new file mode 100644
index 000000000..482373df2
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-OLD.cmake
@@ -0,0 +1,7 @@
+
+enable_language(CXX)
+
+cmake_policy(SET CMP0026 OLD)
+
+add_library(somelib empty.cpp)
+get_target_property(_loc somelib LOCATION_Debug)
diff --git a/Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-WARN-result.txt b/Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-WARN-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-WARN-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-WARN-stderr.txt b/Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-WARN-stderr.txt
new file mode 100644
index 000000000..cd6f3d095
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-WARN-stderr.txt
@@ -0,0 +1,12 @@
+CMake Warning \(dev\) at CMP0026-LOCATION-CONFIG-WARN.cmake:5 \(get_target_property\):
+ Policy CMP0026 is not set: Disallow use of the LOCATION target property.
+ Run "cmake --help-policy CMP0026" for policy details. Use the cmake_policy
+ command to set the policy and suppress this warning.
+
+ The LOCATION property should not be read from target "somelib". Use the
+ target name directly with add_custom_command, or use the generator
+ expression \$<TARGET_FILE>, as appropriate.
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-WARN.cmake b/Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-WARN.cmake
new file mode 100644
index 000000000..85711c34b
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-WARN.cmake
@@ -0,0 +1,5 @@
+
+enable_language(CXX)
+
+add_library(somelib empty.cpp)
+get_target_property(_loc somelib LOCATION_Debug)
diff --git a/Tests/RunCMake/build_command/BeforeProject-result.txt b/Tests/RunCMake/CMP0026/CMP0026-NEW-result.txt
index d00491fd7..d00491fd7 100644
--- a/Tests/RunCMake/build_command/BeforeProject-result.txt
+++ b/Tests/RunCMake/CMP0026/CMP0026-NEW-result.txt
diff --git a/Tests/RunCMake/CMP0026/CMP0026-NEW-stderr.txt b/Tests/RunCMake/CMP0026/CMP0026-NEW-stderr.txt
new file mode 100644
index 000000000..fa025129f
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/CMP0026-NEW-stderr.txt
@@ -0,0 +1,7 @@
+CMake Error at CMP0026-NEW.cmake:7 \(get_target_property\):
+ The LOCATION property may not be read from target "somelib". Use the
+ target name directly with add_custom_command, or use the generator
+ expression \$<TARGET_FILE>, as appropriate.
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CMP0026/CMP0026-NEW.cmake b/Tests/RunCMake/CMP0026/CMP0026-NEW.cmake
new file mode 100644
index 000000000..1659ffc52
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/CMP0026-NEW.cmake
@@ -0,0 +1,7 @@
+
+enable_language(CXX)
+
+cmake_policy(SET CMP0026 NEW)
+
+add_library(somelib empty.cpp)
+get_target_property(_loc somelib LOCATION)
diff --git a/Tests/RunCMake/CMP0026/CMP0026-WARN-Dir/CMakeLists.txt b/Tests/RunCMake/CMP0026/CMP0026-WARN-Dir/CMakeLists.txt
new file mode 100644
index 000000000..17a7db043
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/CMP0026-WARN-Dir/CMakeLists.txt
@@ -0,0 +1 @@
+add_library(otherlib ../empty.cpp)
diff --git a/Tests/RunCMake/CMP0026/CMP0026-WARN-result.txt b/Tests/RunCMake/CMP0026/CMP0026-WARN-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/CMP0026-WARN-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0026/CMP0026-WARN-stderr.txt b/Tests/RunCMake/CMP0026/CMP0026-WARN-stderr.txt
new file mode 100644
index 000000000..d122c4a2e
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/CMP0026-WARN-stderr.txt
@@ -0,0 +1,25 @@
+CMake Warning \(dev\) at CMP0026-WARN.cmake:5 \(get_target_property\):
+ Policy CMP0026 is not set: Disallow use of the LOCATION target property.
+ Run "cmake --help-policy CMP0026" for policy details. Use the cmake_policy
+ command to set the policy and suppress this warning.
+
+ The LOCATION property should not be read from target "somelib". Use the
+ target name directly with add_custom_command, or use the generator
+ expression \$<TARGET_FILE>, as appropriate.
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
++
+CMake Warning \(dev\) at CMP0026-WARN.cmake:8 \(get_target_property\):
+ Policy CMP0026 is not set: Disallow use of the LOCATION target property.
+ Run "cmake --help-policy CMP0026" for policy details. Use the cmake_policy
+ command to set the policy and suppress this warning.
+
+ The LOCATION property should not be read from target "otherlib". Use the
+ target name directly with add_custom_command, or use the generator
+ expression \$<TARGET_FILE>, as appropriate.
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0026/CMP0026-WARN.cmake b/Tests/RunCMake/CMP0026/CMP0026-WARN.cmake
new file mode 100644
index 000000000..bfc9203af
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/CMP0026-WARN.cmake
@@ -0,0 +1,8 @@
+
+enable_language(CXX)
+
+add_library(somelib empty.cpp)
+get_target_property(_loc somelib LOCATION)
+
+add_subdirectory(CMP0026-WARN-Dir)
+get_target_property(_loc otherlib LOCATION)
diff --git a/Tests/RunCMake/CMP0026/CMakeLists.txt b/Tests/RunCMake/CMP0026/CMakeLists.txt
new file mode 100644
index 000000000..12cd3c775
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS-result.txt b/Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS-stderr.txt b/Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS-stderr.txt
new file mode 100644
index 000000000..0996cb6b4
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS-stderr.txt
@@ -0,0 +1,12 @@
+CMake Warning \(dev\) at LOCATION-and-TARGET_OBJECTS.cmake:[0-9]+ \(get_target_property\):
+ Policy CMP0026 is not set: Disallow use of the LOCATION target property.
+ Run "cmake --help-policy CMP0026" for policy details. Use the cmake_policy
+ command to set the policy and suppress this warning.
+
+ The LOCATION property should not be read from target "bar". Use the target
+ name directly with add_custom_command, or use the generator expression
+ \$<TARGET_FILE>, as appropriate.
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS.cmake b/Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS.cmake
new file mode 100644
index 000000000..3d8eb73d2
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS.cmake
@@ -0,0 +1,6 @@
+
+enable_language(CXX)
+
+add_library(foo OBJECT empty.cpp)
+add_executable(bar $<TARGET_OBJECTS:foo>)
+get_target_property(location bar LOCATION)
diff --git a/Tests/RunCMake/CMP0026/ObjlibNotDefined-result.txt b/Tests/RunCMake/CMP0026/ObjlibNotDefined-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/ObjlibNotDefined-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0026/ObjlibNotDefined-stderr.txt b/Tests/RunCMake/CMP0026/ObjlibNotDefined-stderr.txt
new file mode 100644
index 000000000..87d198d00
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/ObjlibNotDefined-stderr.txt
@@ -0,0 +1,12 @@
+CMake Warning \(dev\) at ObjlibNotDefined.cmake:[0-9]+ \(get_target_property\):
+ Policy CMP0026 is not set: Disallow use of the LOCATION target property.
+ Run "cmake --help-policy CMP0026" for policy details. Use the cmake_policy
+ command to set the policy and suppress this warning.
+
+ The LOCATION property should not be read from target "objlibuser". Use the
+ target name directly with add_custom_command, or use the generator
+ expression \$<TARGET_FILE>, as appropriate.
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0026/ObjlibNotDefined.cmake b/Tests/RunCMake/CMP0026/ObjlibNotDefined.cmake
new file mode 100644
index 000000000..194760cd4
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/ObjlibNotDefined.cmake
@@ -0,0 +1,13 @@
+
+enable_language(CXX)
+
+add_executable(objlibuser
+ empty.cpp
+ $<TARGET_OBJECTS:bar>
+)
+
+get_target_property(_location objlibuser LOCATION)
+
+add_library(bar OBJECT
+ empty.cpp
+)
diff --git a/Tests/RunCMake/CMP0026/RunCMakeTest.cmake b/Tests/RunCMake/CMP0026/RunCMakeTest.cmake
new file mode 100644
index 000000000..633171739
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/RunCMakeTest.cmake
@@ -0,0 +1,14 @@
+include(RunCMake)
+
+run_cmake(CMP0026-WARN)
+run_cmake(CMP0026-NEW)
+run_cmake(CMP0026-IMPORTED)
+run_cmake(CMP0026-CONFIG-LOCATION-NEW)
+run_cmake(CMP0026-CONFIG-LOCATION-OLD)
+run_cmake(CMP0026-CONFIG-LOCATION-WARN)
+run_cmake(CMP0026-LOCATION-CONFIG-NEW)
+run_cmake(CMP0026-LOCATION-CONFIG-OLD)
+run_cmake(CMP0026-LOCATION-CONFIG-WARN)
+run_cmake(ObjlibNotDefined)
+run_cmake(LOCATION-and-TARGET_OBJECTS)
+run_cmake(clear-cached-information)
diff --git a/Tests/RunCMake/CMP0026/clear-cached-information-dir/CMakeLists.txt b/Tests/RunCMake/CMP0026/clear-cached-information-dir/CMakeLists.txt
new file mode 100644
index 000000000..c51e8837f
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/clear-cached-information-dir/CMakeLists.txt
@@ -0,0 +1,2 @@
+
+add_executable(Hello ${CMAKE_CURRENT_BINARY_DIR}/main.c)
diff --git a/Tests/RunCMake/CMP0026/clear-cached-information.cmake b/Tests/RunCMake/CMP0026/clear-cached-information.cmake
new file mode 100644
index 000000000..dd2dd7246
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/clear-cached-information.cmake
@@ -0,0 +1,14 @@
+
+enable_language(C)
+
+cmake_policy(SET CMP0026 OLD)
+
+add_subdirectory(clear-cached-information-dir)
+
+# Critical: this needs to happen in root CMakeLists.txt and not inside
+# the subdir.
+get_target_property(mypath Hello LOCATION)
+# Now we create the file later, so you can see, ultimately no error should
+# happen e.g. during generate phase:
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/clear-cached-information-dir/main.c)
+set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/clear-cached-information-dir/main.c PROPERTIES GENERATED TRUE)
diff --git a/Tests/RunCMake/CMP0026/empty.cpp b/Tests/RunCMake/CMP0026/empty.cpp
new file mode 100644
index 000000000..bfbbddeb9
--- /dev/null
+++ b/Tests/RunCMake/CMP0026/empty.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/include_directories/BinaryDirectoryInInterface-result.txt b/Tests/RunCMake/CMP0027/CMP0027-NEW-result.txt
index d00491fd7..d00491fd7 100644
--- a/Tests/RunCMake/include_directories/BinaryDirectoryInInterface-result.txt
+++ b/Tests/RunCMake/CMP0027/CMP0027-NEW-result.txt
diff --git a/Tests/RunCMake/CMP0027/CMP0027-NEW-stderr.txt b/Tests/RunCMake/CMP0027/CMP0027-NEW-stderr.txt
new file mode 100644
index 000000000..5948ec837
--- /dev/null
+++ b/Tests/RunCMake/CMP0027/CMP0027-NEW-stderr.txt
@@ -0,0 +1,13 @@
+CMake Error in CMakeLists.txt:
+ Imported target "testTarget" includes non-existent path
+
+ "/does/not/exist"
+
+ in its INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:
+
+ \* The path was deleted, renamed, or moved to another location.
+
+ \* An install or uninstall procedure did not complete successfully.
+
+ \* The installation package was faulty and references files it does not
+ provide.
diff --git a/Tests/RunCMake/CMP0027/CMP0027-NEW.cmake b/Tests/RunCMake/CMP0027/CMP0027-NEW.cmake
new file mode 100644
index 000000000..824508549
--- /dev/null
+++ b/Tests/RunCMake/CMP0027/CMP0027-NEW.cmake
@@ -0,0 +1,10 @@
+
+enable_language(CXX)
+
+cmake_policy(SET CMP0027 NEW)
+
+add_library(testTarget UNKNOWN IMPORTED)
+set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "/does/not/exist")
+
+add_library(userTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
+target_link_libraries(userTarget PRIVATE $<1:testTarget>)
diff --git a/Tests/RunCMake/CMP0027/CMP0027-OLD-result.txt b/Tests/RunCMake/CMP0027/CMP0027-OLD-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0027/CMP0027-OLD-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0027/CMP0027-OLD-stderr.txt b/Tests/RunCMake/CMP0027/CMP0027-OLD-stderr.txt
new file mode 100644
index 000000000..4c2b300b4
--- /dev/null
+++ b/Tests/RunCMake/CMP0027/CMP0027-OLD-stderr.txt
@@ -0,0 +1,13 @@
+CMake Warning \(dev\) in CMakeLists.txt:
+ Imported target "testTarget" includes non-existent path
+
+ "/does/not/exist"
+
+ in its INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:
+
+ \* The path was deleted, renamed, or moved to another location.
+
+ \* An install or uninstall procedure did not complete successfully.
+
+ \* The installation package was faulty and references files it does not
+ provide.
diff --git a/Tests/RunCMake/CMP0027/CMP0027-OLD.cmake b/Tests/RunCMake/CMP0027/CMP0027-OLD.cmake
new file mode 100644
index 000000000..404217de7
--- /dev/null
+++ b/Tests/RunCMake/CMP0027/CMP0027-OLD.cmake
@@ -0,0 +1,10 @@
+
+enable_language(CXX)
+
+cmake_policy(SET CMP0027 OLD)
+
+add_library(testTarget UNKNOWN IMPORTED)
+set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "/does/not/exist")
+
+add_library(userTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
+target_link_libraries(userTarget PRIVATE $<1:testTarget>)
diff --git a/Tests/RunCMake/CMP0027/CMP0027-WARN-result.txt b/Tests/RunCMake/CMP0027/CMP0027-WARN-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0027/CMP0027-WARN-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0027/CMP0027-WARN-stderr.txt b/Tests/RunCMake/CMP0027/CMP0027-WARN-stderr.txt
new file mode 100644
index 000000000..9bcec3c44
--- /dev/null
+++ b/Tests/RunCMake/CMP0027/CMP0027-WARN-stderr.txt
@@ -0,0 +1,18 @@
+CMake Warning \(dev\) in CMakeLists.txt:
+ Policy CMP0027 is not set: Conditionally linked imported targets with
+ missing include directories. Run "cmake --help-policy CMP0027" for policy
+ details. Use the cmake_policy command to set the policy and suppress this
+ warning.
+
+ Imported target "testTarget" includes non-existent path
+
+ "/does/not/exist"
+
+ in its INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:
+
+ \* The path was deleted, renamed, or moved to another location.
+
+ \* An install or uninstall procedure did not complete successfully.
+
+ \* The installation package was faulty and references files it does not
+ provide.
diff --git a/Tests/RunCMake/CMP0027/CMP0027-WARN.cmake b/Tests/RunCMake/CMP0027/CMP0027-WARN.cmake
new file mode 100644
index 000000000..8e5f9b518
--- /dev/null
+++ b/Tests/RunCMake/CMP0027/CMP0027-WARN.cmake
@@ -0,0 +1,8 @@
+
+enable_language(CXX)
+
+add_library(testTarget UNKNOWN IMPORTED)
+set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "/does/not/exist")
+
+add_library(userTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
+target_link_libraries(userTarget PRIVATE $<1:testTarget>)
diff --git a/Tests/RunCMake/CMP0027/CMakeLists.txt b/Tests/RunCMake/CMP0027/CMakeLists.txt
new file mode 100644
index 000000000..12cd3c775
--- /dev/null
+++ b/Tests/RunCMake/CMP0027/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0027/RunCMakeTest.cmake b/Tests/RunCMake/CMP0027/RunCMakeTest.cmake
new file mode 100644
index 000000000..1017f01f4
--- /dev/null
+++ b/Tests/RunCMake/CMP0027/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0027-NEW)
+run_cmake(CMP0027-OLD)
+run_cmake(CMP0027-WARN)
diff --git a/Tests/RunCMake/CMP0027/empty.cpp b/Tests/RunCMake/CMP0027/empty.cpp
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/CMP0027/empty.cpp
diff --git a/Tests/RunCMake/include_directories/RelativePathInGenex-result.txt b/Tests/RunCMake/CMP0028/CMP0028-NEW-iface-result.txt
index d00491fd7..d00491fd7 100644
--- a/Tests/RunCMake/include_directories/RelativePathInGenex-result.txt
+++ b/Tests/RunCMake/CMP0028/CMP0028-NEW-iface-result.txt
diff --git a/Tests/RunCMake/CMP0028/CMP0028-NEW-iface-stderr.txt b/Tests/RunCMake/CMP0028/CMP0028-NEW-iface-stderr.txt
new file mode 100644
index 000000000..e2108f46c
--- /dev/null
+++ b/Tests/RunCMake/CMP0028/CMP0028-NEW-iface-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at CMP0028-NEW-iface.cmake:6 \(add_library\):
+ Target "foo" links to target "External::Library" but the target was not
+ found. Perhaps a find_package\(\) call is missing for an IMPORTED target, or
+ an ALIAS target is missing\?
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CMP0028/CMP0028-NEW-iface.cmake b/Tests/RunCMake/CMP0028/CMP0028-NEW-iface.cmake
new file mode 100644
index 000000000..1a7143306
--- /dev/null
+++ b/Tests/RunCMake/CMP0028/CMP0028-NEW-iface.cmake
@@ -0,0 +1,7 @@
+
+cmake_policy(SET CMP0028 NEW)
+
+add_library(iface INTERFACE)
+target_link_libraries(iface INTERFACE External::Library)
+add_library(foo empty.cpp)
+target_link_libraries(foo iface)
diff --git a/Tests/RunCMake/include_directories/RelativePathInInterface-result.txt b/Tests/RunCMake/CMP0028/CMP0028-NEW-result.txt
index d00491fd7..d00491fd7 100644
--- a/Tests/RunCMake/include_directories/RelativePathInInterface-result.txt
+++ b/Tests/RunCMake/CMP0028/CMP0028-NEW-result.txt
diff --git a/Tests/RunCMake/CMP0028/CMP0028-NEW-stderr.txt b/Tests/RunCMake/CMP0028/CMP0028-NEW-stderr.txt
new file mode 100644
index 000000000..711ad0e72
--- /dev/null
+++ b/Tests/RunCMake/CMP0028/CMP0028-NEW-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at CMP0028-NEW.cmake:4 \(add_library\):
+ Target "foo" links to target "External::Library" but the target was not
+ found. Perhaps a find_package\(\) call is missing for an IMPORTED target, or
+ an ALIAS target is missing\?
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CMP0028/CMP0028-NEW.cmake b/Tests/RunCMake/CMP0028/CMP0028-NEW.cmake
new file mode 100644
index 000000000..a0a6ae81c
--- /dev/null
+++ b/Tests/RunCMake/CMP0028/CMP0028-NEW.cmake
@@ -0,0 +1,5 @@
+
+cmake_policy(SET CMP0028 NEW)
+
+add_library(foo empty.cpp)
+target_link_libraries(foo PRIVATE External::Library)
diff --git a/Tests/RunCMake/CMP0028/CMP0028-OLD-iface-result.txt b/Tests/RunCMake/CMP0028/CMP0028-OLD-iface-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0028/CMP0028-OLD-iface-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0028/CMP0028-OLD-iface.cmake b/Tests/RunCMake/CMP0028/CMP0028-OLD-iface.cmake
new file mode 100644
index 000000000..d7bd60e4b
--- /dev/null
+++ b/Tests/RunCMake/CMP0028/CMP0028-OLD-iface.cmake
@@ -0,0 +1,7 @@
+
+cmake_policy(SET CMP0028 OLD)
+
+add_library(iface INTERFACE)
+target_link_libraries(iface INTERFACE External::Library)
+add_library(foo empty.cpp)
+target_link_libraries(foo iface)
diff --git a/Tests/RunCMake/CMP0028/CMP0028-OLD-result.txt b/Tests/RunCMake/CMP0028/CMP0028-OLD-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0028/CMP0028-OLD-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0028/CMP0028-OLD.cmake b/Tests/RunCMake/CMP0028/CMP0028-OLD.cmake
new file mode 100644
index 000000000..d4a870b23
--- /dev/null
+++ b/Tests/RunCMake/CMP0028/CMP0028-OLD.cmake
@@ -0,0 +1,5 @@
+
+cmake_policy(SET CMP0028 OLD)
+
+add_library(foo empty.cpp)
+target_link_libraries(foo PRIVATE External::Library)
diff --git a/Tests/RunCMake/CMP0028/CMP0028-WARN-iface-result.txt b/Tests/RunCMake/CMP0028/CMP0028-WARN-iface-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0028/CMP0028-WARN-iface-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0028/CMP0028-WARN-iface-stderr.txt b/Tests/RunCMake/CMP0028/CMP0028-WARN-iface-stderr.txt
new file mode 100644
index 000000000..0c5c65378
--- /dev/null
+++ b/Tests/RunCMake/CMP0028/CMP0028-WARN-iface-stderr.txt
@@ -0,0 +1,11 @@
+CMake Warning \(dev\) at CMP0028-WARN-iface.cmake:4 \(add_library\):
+ Policy CMP0028 is not set: Double colon in target name means ALIAS or
+ IMPORTED target. Run "cmake --help-policy CMP0028" for policy details.
+ Use the cmake_policy command to set the policy and suppress this warning.
+
+ Target "foo" links to target "External::Library" but the target was not
+ found. Perhaps a find_package\(\) call is missing for an IMPORTED target, or
+ an ALIAS target is missing\?
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0028/CMP0028-WARN-iface.cmake b/Tests/RunCMake/CMP0028/CMP0028-WARN-iface.cmake
new file mode 100644
index 000000000..927002340
--- /dev/null
+++ b/Tests/RunCMake/CMP0028/CMP0028-WARN-iface.cmake
@@ -0,0 +1,5 @@
+
+add_library(iface INTERFACE)
+target_link_libraries(iface INTERFACE External::Library)
+add_library(foo empty.cpp)
+target_link_libraries(foo iface)
diff --git a/Tests/RunCMake/CMP0028/CMP0028-WARN-result.txt b/Tests/RunCMake/CMP0028/CMP0028-WARN-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0028/CMP0028-WARN-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0028/CMP0028-WARN-stderr.txt b/Tests/RunCMake/CMP0028/CMP0028-WARN-stderr.txt
new file mode 100644
index 000000000..41d7560d8
--- /dev/null
+++ b/Tests/RunCMake/CMP0028/CMP0028-WARN-stderr.txt
@@ -0,0 +1,11 @@
+CMake Warning \(dev\) at CMP0028-WARN.cmake:2 \(add_library\):
+ Policy CMP0028 is not set: Double colon in target name means ALIAS or
+ IMPORTED target. Run "cmake --help-policy CMP0028" for policy details.
+ Use the cmake_policy command to set the policy and suppress this warning.
+
+ Target "foo" links to target "External::Library" but the target was not
+ found. Perhaps a find_package\(\) call is missing for an IMPORTED target, or
+ an ALIAS target is missing\?
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0028/CMP0028-WARN.cmake b/Tests/RunCMake/CMP0028/CMP0028-WARN.cmake
new file mode 100644
index 000000000..70a6cc6c4
--- /dev/null
+++ b/Tests/RunCMake/CMP0028/CMP0028-WARN.cmake
@@ -0,0 +1,3 @@
+
+add_library(foo empty.cpp)
+target_link_libraries(foo PRIVATE External::Library)
diff --git a/Tests/RunCMake/CMP0028/CMakeLists.txt b/Tests/RunCMake/CMP0028/CMakeLists.txt
new file mode 100644
index 000000000..144cdb4ee
--- /dev/null
+++ b/Tests/RunCMake/CMP0028/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE) # policy used at end of dir
diff --git a/Tests/RunCMake/CMP0028/RunCMakeTest.cmake b/Tests/RunCMake/CMP0028/RunCMakeTest.cmake
new file mode 100644
index 000000000..0c72ca296
--- /dev/null
+++ b/Tests/RunCMake/CMP0028/RunCMakeTest.cmake
@@ -0,0 +1,8 @@
+include(RunCMake)
+
+run_cmake(CMP0028-NEW)
+run_cmake(CMP0028-OLD)
+run_cmake(CMP0028-WARN)
+run_cmake(CMP0028-NEW-iface)
+run_cmake(CMP0028-OLD-iface)
+run_cmake(CMP0028-WARN-iface)
diff --git a/Tests/RunCMake/CMP0028/empty.cpp b/Tests/RunCMake/CMP0028/empty.cpp
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/CMP0028/empty.cpp
diff --git a/Tests/RunCMake/include_directories/SourceDirectoryInInterface-result.txt b/Tests/RunCMake/CMP0037/CMP0037-NEW-colon-result.txt
index d00491fd7..d00491fd7 100644
--- a/Tests/RunCMake/include_directories/SourceDirectoryInInterface-result.txt
+++ b/Tests/RunCMake/CMP0037/CMP0037-NEW-colon-result.txt
diff --git a/Tests/RunCMake/CMP0037/CMP0037-NEW-colon-stderr.txt b/Tests/RunCMake/CMP0037/CMP0037-NEW-colon-stderr.txt
new file mode 100644
index 000000000..ec2315f18
--- /dev/null
+++ b/Tests/RunCMake/CMP0037/CMP0037-NEW-colon-stderr.txt
@@ -0,0 +1,20 @@
+CMake Error at CMP0037-NEW-colon.cmake:4 \(add_library\):
+ The target name "lib:colon" is reserved or not valid for certain CMake
+ features, such as generator expressions, and may result in undefined
+ behavior.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at CMP0037-NEW-colon.cmake:5 \(add_executable\):
+ The target name "exe:colon" is reserved or not valid for certain CMake
+ features, such as generator expressions, and may result in undefined
+ behavior.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at CMP0037-NEW-colon.cmake:6 \(add_custom_target\):
+ The target name "custom:colon" is reserved or not valid for certain CMake
+ features, such as generator expressions, and may result in undefined
+ behavior.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CMP0037/CMP0037-NEW-colon.cmake b/Tests/RunCMake/CMP0037/CMP0037-NEW-colon.cmake
new file mode 100644
index 000000000..f4c070d7a
--- /dev/null
+++ b/Tests/RunCMake/CMP0037/CMP0037-NEW-colon.cmake
@@ -0,0 +1,6 @@
+
+cmake_policy(SET CMP0037 NEW)
+
+add_library("lib:colon" empty.cpp)
+add_executable("exe:colon" empty.cpp)
+add_custom_target("custom:colon")
diff --git a/Tests/RunCMake/CMP0037/CMP0037-NEW-reserved-result.txt b/Tests/RunCMake/CMP0037/CMP0037-NEW-reserved-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CMP0037/CMP0037-NEW-reserved-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0037/CMP0037-NEW-reserved-stderr.txt b/Tests/RunCMake/CMP0037/CMP0037-NEW-reserved-stderr.txt
new file mode 100644
index 000000000..5789e383a
--- /dev/null
+++ b/Tests/RunCMake/CMP0037/CMP0037-NEW-reserved-stderr.txt
@@ -0,0 +1,18 @@
+CMake Error at CMP0037-NEW-reserved.cmake:4 \(add_library\):
+ The target name "all" is reserved or not valid for certain CMake features,
+ such as generator expressions, and may result in undefined behavior.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at CMP0037-NEW-reserved.cmake:5 \(add_executable\):
+ The target name "clean" is reserved or not valid for certain CMake
+ features, such as generator expressions, and may result in undefined
+ behavior.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at CMP0037-NEW-reserved.cmake:6 \(add_custom_target\):
+ The target name "help" is reserved or not valid for certain CMake features,
+ such as generator expressions, and may result in undefined behavior.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CMP0037/CMP0037-NEW-reserved.cmake b/Tests/RunCMake/CMP0037/CMP0037-NEW-reserved.cmake
new file mode 100644
index 000000000..e9f640469
--- /dev/null
+++ b/Tests/RunCMake/CMP0037/CMP0037-NEW-reserved.cmake
@@ -0,0 +1,6 @@
+
+cmake_policy(SET CMP0037 NEW)
+
+add_library(all empty.cpp)
+add_executable(clean empty.cpp)
+add_custom_target(help)
diff --git a/Tests/RunCMake/CMP0037/CMP0037-NEW-space-result.txt b/Tests/RunCMake/CMP0037/CMP0037-NEW-space-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CMP0037/CMP0037-NEW-space-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0037/CMP0037-NEW-space-stderr.txt b/Tests/RunCMake/CMP0037/CMP0037-NEW-space-stderr.txt
new file mode 100644
index 000000000..e14cec000
--- /dev/null
+++ b/Tests/RunCMake/CMP0037/CMP0037-NEW-space-stderr.txt
@@ -0,0 +1,20 @@
+CMake Error at CMP0037-NEW-space.cmake:4 \(add_library\):
+ The target name "lib with spaces" is reserved or not valid for certain
+ CMake features, such as generator expressions, and may result in undefined
+ behavior.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at CMP0037-NEW-space.cmake:5 \(add_executable\):
+ The target name "exe with spaces" is reserved or not valid for certain
+ CMake features, such as generator expressions, and may result in undefined
+ behavior.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at CMP0037-NEW-space.cmake:6 \(add_custom_target\):
+ The target name "custom with spaces" is reserved or not valid for certain
+ CMake features, such as generator expressions, and may result in undefined
+ behavior.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CMP0037/CMP0037-NEW-space.cmake b/Tests/RunCMake/CMP0037/CMP0037-NEW-space.cmake
new file mode 100644
index 000000000..9227986e9
--- /dev/null
+++ b/Tests/RunCMake/CMP0037/CMP0037-NEW-space.cmake
@@ -0,0 +1,6 @@
+
+cmake_policy(SET CMP0037 NEW)
+
+add_library("lib with spaces" empty.cpp)
+add_executable("exe with spaces" empty.cpp)
+add_custom_target("custom with spaces")
diff --git a/Tests/RunCMake/CMP0037/CMP0037-OLD-reserved-result.txt b/Tests/RunCMake/CMP0037/CMP0037-OLD-reserved-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0037/CMP0037-OLD-reserved-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0037/CMP0037-OLD-reserved.cmake b/Tests/RunCMake/CMP0037/CMP0037-OLD-reserved.cmake
new file mode 100644
index 000000000..870a28672
--- /dev/null
+++ b/Tests/RunCMake/CMP0037/CMP0037-OLD-reserved.cmake
@@ -0,0 +1,6 @@
+
+cmake_policy(SET CMP0037 OLD)
+
+add_library(all empty.cpp)
+add_executable(clean empty.cpp)
+add_custom_target(help)
diff --git a/Tests/RunCMake/CMP0037/CMP0037-OLD-space-result.txt b/Tests/RunCMake/CMP0037/CMP0037-OLD-space-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0037/CMP0037-OLD-space-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0037/CMP0037-OLD-space.cmake b/Tests/RunCMake/CMP0037/CMP0037-OLD-space.cmake
new file mode 100644
index 000000000..46193a1fa
--- /dev/null
+++ b/Tests/RunCMake/CMP0037/CMP0037-OLD-space.cmake
@@ -0,0 +1,6 @@
+
+cmake_policy(SET CMP0037 OLD)
+
+add_library("lib with spaces" empty.cpp)
+add_executable("exe with spaces" empty.cpp)
+add_custom_target("custom with spaces")
diff --git a/Tests/RunCMake/CMP0037/CMP0037-WARN-colon-result.txt b/Tests/RunCMake/CMP0037/CMP0037-WARN-colon-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0037/CMP0037-WARN-colon-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0037/CMP0037-WARN-colon-stderr.txt b/Tests/RunCMake/CMP0037/CMP0037-WARN-colon-stderr.txt
new file mode 100644
index 000000000..d3b0e172f
--- /dev/null
+++ b/Tests/RunCMake/CMP0037/CMP0037-WARN-colon-stderr.txt
@@ -0,0 +1,38 @@
+CMake Warning \(dev\) at CMP0037-WARN-colon.cmake:2 \(add_library\):
+ Policy CMP0037 is not set: Target names should not be reserved and should
+ match a validity pattern. Run "cmake --help-policy CMP0037" for policy
+ details. Use the cmake_policy command to set the policy and suppress this
+ warning.
+
+ The target name "lib:colon" is reserved or not valid for certain CMake
+ features, such as generator expressions, and may result in undefined
+ behavior.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
++
+CMake Warning \(dev\) at CMP0037-WARN-colon.cmake:3 \(add_executable\):
+ Policy CMP0037 is not set: Target names should not be reserved and should
+ match a validity pattern. Run "cmake --help-policy CMP0037" for policy
+ details. Use the cmake_policy command to set the policy and suppress this
+ warning.
+
+ The target name "exe:colon" is reserved or not valid for certain CMake
+ features, such as generator expressions, and may result in undefined
+ behavior.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
++
+CMake Warning \(dev\) at CMP0037-WARN-colon.cmake:4 \(add_custom_target\):
+ Policy CMP0037 is not set: Target names should not be reserved and should
+ match a validity pattern. Run "cmake --help-policy CMP0037" for policy
+ details. Use the cmake_policy command to set the policy and suppress this
+ warning.
+
+ The target name "custom:colon" is reserved or not valid for certain CMake
+ features, such as generator expressions, and may result in undefined
+ behavior.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0037/CMP0037-WARN-colon.cmake b/Tests/RunCMake/CMP0037/CMP0037-WARN-colon.cmake
new file mode 100644
index 000000000..445e3b23e
--- /dev/null
+++ b/Tests/RunCMake/CMP0037/CMP0037-WARN-colon.cmake
@@ -0,0 +1,4 @@
+
+add_library("lib:colon" empty.cpp)
+add_executable("exe:colon" empty.cpp)
+add_custom_target("custom:colon")
diff --git a/Tests/RunCMake/CMP0037/CMP0037-WARN-space-result.txt b/Tests/RunCMake/CMP0037/CMP0037-WARN-space-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0037/CMP0037-WARN-space-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0037/CMP0037-WARN-space-stderr.txt b/Tests/RunCMake/CMP0037/CMP0037-WARN-space-stderr.txt
new file mode 100644
index 000000000..e39477a91
--- /dev/null
+++ b/Tests/RunCMake/CMP0037/CMP0037-WARN-space-stderr.txt
@@ -0,0 +1,37 @@
+CMake Warning \(dev\) at CMP0037-WARN-space.cmake:2 \(add_library\):
+ Policy CMP0037 is not set: Target names should not be reserved and should
+ match a validity pattern. Run "cmake --help-policy CMP0037" for policy
+ details. Use the cmake_policy command to set the policy and suppress this
+ warning.
+
+ The target name "lib with spaces" is reserved or not valid for certain
+ CMake features, such as generator expressions, and may result in undefined
+ behavior.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
++
+CMake Warning \(dev\) at CMP0037-WARN-space.cmake:3 \(add_executable\):
+ Policy CMP0037 is not set: Target names should not be reserved and should
+ match a validity pattern. Run "cmake --help-policy CMP0037" for policy
+ details. Use the cmake_policy command to set the policy and suppress this
+ warning.
+
+ The target name "exe with spaces" is reserved or not valid for certain
+ CMake features, such as generator expressions, and may result in undefined
+ behavior.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
++
+CMake Warning \(dev\) at CMP0037-WARN-space.cmake:4 \(add_custom_target\):
+ Policy CMP0037 is not set: Target names should not be reserved and should
+ match a validity pattern. Run "cmake --help-policy CMP0037" for policy
+ details. Use the cmake_policy command to set the policy and suppress this
+ warning.
+
+ The target name "custom with spaces" is reserved or not valid for certain
+ CMake features, such as generator expressions, and may result in undefined
+ behavior.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CMP0037/CMP0037-WARN-space.cmake b/Tests/RunCMake/CMP0037/CMP0037-WARN-space.cmake
new file mode 100644
index 000000000..e50a64dcf
--- /dev/null
+++ b/Tests/RunCMake/CMP0037/CMP0037-WARN-space.cmake
@@ -0,0 +1,4 @@
+
+add_library("lib with spaces" empty.cpp)
+add_executable("exe with spaces" empty.cpp)
+add_custom_target("custom with spaces")
diff --git a/Tests/RunCMake/CMP0037/CMakeLists.txt b/Tests/RunCMake/CMP0037/CMakeLists.txt
new file mode 100644
index 000000000..f452db177
--- /dev/null
+++ b/Tests/RunCMake/CMP0037/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0037/RunCMakeTest.cmake b/Tests/RunCMake/CMP0037/RunCMakeTest.cmake
new file mode 100644
index 000000000..b7d8d7bb4
--- /dev/null
+++ b/Tests/RunCMake/CMP0037/RunCMakeTest.cmake
@@ -0,0 +1,13 @@
+include(RunCMake)
+
+run_cmake(CMP0037-OLD-space)
+run_cmake(CMP0037-NEW-space)
+run_cmake(CMP0037-WARN-space)
+run_cmake(CMP0037-NEW-colon)
+
+if(NOT (WIN32 AND "${RunCMake_GENERATOR}" MATCHES "Make"))
+ run_cmake(CMP0037-WARN-colon)
+endif()
+
+run_cmake(CMP0037-OLD-reserved)
+run_cmake(CMP0037-NEW-reserved)
diff --git a/Tests/RunCMake/CMP0037/empty.cpp b/Tests/RunCMake/CMP0037/empty.cpp
new file mode 100644
index 000000000..bfbbddeb9
--- /dev/null
+++ b/Tests/RunCMake/CMP0037/empty.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CMP0038/CMP0038-NEW-result.txt b/Tests/RunCMake/CMP0038/CMP0038-NEW-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CMP0038/CMP0038-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0038/CMP0038-NEW-stderr.txt b/Tests/RunCMake/CMP0038/CMP0038-NEW-stderr.txt
new file mode 100644
index 000000000..3d0a428e1
--- /dev/null
+++ b/Tests/RunCMake/CMP0038/CMP0038-NEW-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at CMP0038-NEW.cmake:3 \(add_library\):
+ Target "self_link" links to itself.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CMP0038/CMP0038-NEW.cmake b/Tests/RunCMake/CMP0038/CMP0038-NEW.cmake
new file mode 100644
index 000000000..6296b839a
--- /dev/null
+++ b/Tests/RunCMake/CMP0038/CMP0038-NEW.cmake
@@ -0,0 +1,4 @@
+
+cmake_policy(SET CMP0038 NEW)
+add_library(self_link empty.cpp)
+target_link_libraries(self_link self_link)
diff --git a/Tests/RunCMake/CMP0038/CMP0038-OLD-result.txt b/Tests/RunCMake/CMP0038/CMP0038-OLD-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0038/CMP0038-OLD-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0038/CMP0038-OLD.cmake b/Tests/RunCMake/CMP0038/CMP0038-OLD.cmake
new file mode 100644
index 000000000..37528218c
--- /dev/null
+++ b/Tests/RunCMake/CMP0038/CMP0038-OLD.cmake
@@ -0,0 +1,4 @@
+
+cmake_policy(SET CMP0038 OLD)
+add_library(self_link empty.cpp)
+target_link_libraries(self_link self_link)
diff --git a/Tests/RunCMake/CMP0038/CMP0038-WARN-result.txt b/Tests/RunCMake/CMP0038/CMP0038-WARN-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0038/CMP0038-WARN-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0038/CMP0038-WARN-stderr.txt b/Tests/RunCMake/CMP0038/CMP0038-WARN-stderr.txt
new file mode 100644
index 000000000..64631e7ff
--- /dev/null
+++ b/Tests/RunCMake/CMP0038/CMP0038-WARN-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning \(dev\) at CMP0038-WARN.cmake:2 \(add_library\):
+ Policy CMP0038 is not set: Targets may not link directly to themselves.
+ Run "cmake --help-policy CMP0038" for policy details. Use the cmake_policy
+ command to set the policy and suppress this warning.
+
+ Target "self_link" links to itself.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0038/CMP0038-WARN.cmake b/Tests/RunCMake/CMP0038/CMP0038-WARN.cmake
new file mode 100644
index 000000000..5b92d0951
--- /dev/null
+++ b/Tests/RunCMake/CMP0038/CMP0038-WARN.cmake
@@ -0,0 +1,3 @@
+
+add_library(self_link empty.cpp)
+target_link_libraries(self_link self_link)
diff --git a/Tests/RunCMake/CMP0038/CMakeLists.txt b/Tests/RunCMake/CMP0038/CMakeLists.txt
new file mode 100644
index 000000000..a06591c31
--- /dev/null
+++ b/Tests/RunCMake/CMP0038/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0038/RunCMakeTest.cmake b/Tests/RunCMake/CMP0038/RunCMakeTest.cmake
new file mode 100644
index 000000000..fc3500add
--- /dev/null
+++ b/Tests/RunCMake/CMP0038/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0038-WARN)
+run_cmake(CMP0038-NEW)
+run_cmake(CMP0038-OLD)
diff --git a/Tests/RunCMake/CMP0038/empty.cpp b/Tests/RunCMake/CMP0038/empty.cpp
new file mode 100644
index 000000000..bfbbddeb9
--- /dev/null
+++ b/Tests/RunCMake/CMP0038/empty.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CMP0039/CMP0039-NEW-result.txt b/Tests/RunCMake/CMP0039/CMP0039-NEW-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CMP0039/CMP0039-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0039/CMP0039-NEW-stderr.txt b/Tests/RunCMake/CMP0039/CMP0039-NEW-stderr.txt
new file mode 100644
index 000000000..3d9d22537
--- /dev/null
+++ b/Tests/RunCMake/CMP0039/CMP0039-NEW-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at CMP0039-NEW.cmake:7 \(target_link_libraries\):
+ Utility target "utility" must not be used as the target of a
+ target_link_libraries call.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CMP0039/CMP0039-NEW.cmake b/Tests/RunCMake/CMP0039/CMP0039-NEW.cmake
new file mode 100644
index 000000000..2032d64d4
--- /dev/null
+++ b/Tests/RunCMake/CMP0039/CMP0039-NEW.cmake
@@ -0,0 +1,7 @@
+
+cmake_policy(SET CMP0039 NEW)
+
+add_custom_target(utility
+ COMMAND ${CMAKE_COMMAND} -E echo test
+)
+target_link_libraries(utility m)
diff --git a/Tests/RunCMake/CMP0039/CMP0039-OLD-result.txt b/Tests/RunCMake/CMP0039/CMP0039-OLD-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0039/CMP0039-OLD-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0039/CMP0039-OLD.cmake b/Tests/RunCMake/CMP0039/CMP0039-OLD.cmake
new file mode 100644
index 000000000..9a513f444
--- /dev/null
+++ b/Tests/RunCMake/CMP0039/CMP0039-OLD.cmake
@@ -0,0 +1,7 @@
+
+cmake_policy(SET CMP0039 OLD)
+
+add_custom_target(utility
+ COMMAND ${CMAKE_COMMAND} -E echo test
+)
+target_link_libraries(utility m)
diff --git a/Tests/RunCMake/CMP0039/CMP0039-WARN-result.txt b/Tests/RunCMake/CMP0039/CMP0039-WARN-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0039/CMP0039-WARN-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0039/CMP0039-WARN-stderr.txt b/Tests/RunCMake/CMP0039/CMP0039-WARN-stderr.txt
new file mode 100644
index 000000000..a8e6c70af
--- /dev/null
+++ b/Tests/RunCMake/CMP0039/CMP0039-WARN-stderr.txt
@@ -0,0 +1,10 @@
+CMake Warning \(dev\) at CMP0039-WARN.cmake:5 \(target_link_libraries\):
+ Policy CMP0039 is not set: Utility targets may not have link dependencies.
+ Run "cmake --help-policy CMP0039" for policy details. Use the cmake_policy
+ command to set the policy and suppress this warning.
+
+ Utility target "utility" should not be used as the target of a
+ target_link_libraries call.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0039/CMP0039-WARN.cmake b/Tests/RunCMake/CMP0039/CMP0039-WARN.cmake
new file mode 100644
index 000000000..62499938d
--- /dev/null
+++ b/Tests/RunCMake/CMP0039/CMP0039-WARN.cmake
@@ -0,0 +1,5 @@
+
+add_custom_target(utility
+ COMMAND ${CMAKE_COMMAND} -E echo test
+)
+target_link_libraries(utility m)
diff --git a/Tests/RunCMake/CMP0039/CMakeLists.txt b/Tests/RunCMake/CMP0039/CMakeLists.txt
new file mode 100644
index 000000000..a06591c31
--- /dev/null
+++ b/Tests/RunCMake/CMP0039/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0039/RunCMakeTest.cmake b/Tests/RunCMake/CMP0039/RunCMakeTest.cmake
new file mode 100644
index 000000000..58e8ea91e
--- /dev/null
+++ b/Tests/RunCMake/CMP0039/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0039-WARN)
+run_cmake(CMP0039-NEW)
+run_cmake(CMP0039-OLD)
diff --git a/Tests/RunCMake/CMP0040/CMP0040-NEW-existing-target-result.txt b/Tests/RunCMake/CMP0040/CMP0040-NEW-existing-target-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0040/CMP0040-NEW-existing-target-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0040/CMP0040-NEW-existing-target.cmake b/Tests/RunCMake/CMP0040/CMP0040-NEW-existing-target.cmake
new file mode 100644
index 000000000..f9c8afdf5
--- /dev/null
+++ b/Tests/RunCMake/CMP0040/CMP0040-NEW-existing-target.cmake
@@ -0,0 +1,7 @@
+cmake_policy(SET CMP0040 NEW)
+
+add_library(foobar empty.cpp)
+
+add_custom_command(TARGET foobar PRE_BUILD
+ COMMAND "${CMAKE_COMMAND} -E echo hello world"
+)
diff --git a/Tests/RunCMake/CMP0040/CMP0040-NEW-missing-target-result.txt b/Tests/RunCMake/CMP0040/CMP0040-NEW-missing-target-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CMP0040/CMP0040-NEW-missing-target-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0040/CMP0040-NEW-missing-target-stderr.txt b/Tests/RunCMake/CMP0040/CMP0040-NEW-missing-target-stderr.txt
new file mode 100644
index 000000000..4a1077c7d
--- /dev/null
+++ b/Tests/RunCMake/CMP0040/CMP0040-NEW-missing-target-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at CMP0040-NEW-missing-target.cmake:3 \(add_custom_command\):
+ No TARGET 'foobar' has been created in this directory.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CMP0040/CMP0040-NEW-missing-target.cmake b/Tests/RunCMake/CMP0040/CMP0040-NEW-missing-target.cmake
new file mode 100644
index 000000000..276863d7b
--- /dev/null
+++ b/Tests/RunCMake/CMP0040/CMP0040-NEW-missing-target.cmake
@@ -0,0 +1,5 @@
+cmake_policy(SET CMP0040 NEW)
+
+add_custom_command(TARGET foobar PRE_BUILD
+ COMMAND "${CMAKE_COMMAND} -E hello world"
+)
diff --git a/Tests/RunCMake/CMP0040/CMP0040-OLD-existing-target-result.txt b/Tests/RunCMake/CMP0040/CMP0040-OLD-existing-target-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0040/CMP0040-OLD-existing-target-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0040/CMP0040-OLD-existing-target.cmake b/Tests/RunCMake/CMP0040/CMP0040-OLD-existing-target.cmake
new file mode 100644
index 000000000..d7ec50daa
--- /dev/null
+++ b/Tests/RunCMake/CMP0040/CMP0040-OLD-existing-target.cmake
@@ -0,0 +1,7 @@
+cmake_policy(SET CMP0040 OLD)
+
+add_library(foobar empty.cpp)
+
+add_custom_command(TARGET foobar PRE_BUILD
+ COMMAND "${CMAKE_COMMAND} -E echo hello world"
+)
diff --git a/Tests/RunCMake/CMP0040/CMP0040-OLD-missing-target-result.txt b/Tests/RunCMake/CMP0040/CMP0040-OLD-missing-target-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0040/CMP0040-OLD-missing-target-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0040/CMP0040-OLD-missing-target.cmake b/Tests/RunCMake/CMP0040/CMP0040-OLD-missing-target.cmake
new file mode 100644
index 000000000..ef7a0f731
--- /dev/null
+++ b/Tests/RunCMake/CMP0040/CMP0040-OLD-missing-target.cmake
@@ -0,0 +1,5 @@
+cmake_policy(SET CMP0040 OLD)
+
+add_custom_command(TARGET foobar PRE_BUILD
+ COMMAND "${CMAKE_COMMAND} -E echo hello world"
+)
diff --git a/Tests/RunCMake/CMP0040/CMP0040-WARN-missing-target-result.txt b/Tests/RunCMake/CMP0040/CMP0040-WARN-missing-target-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0040/CMP0040-WARN-missing-target-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0040/CMP0040-WARN-missing-target-stderr.txt b/Tests/RunCMake/CMP0040/CMP0040-WARN-missing-target-stderr.txt
new file mode 100644
index 000000000..e3e3ff468
--- /dev/null
+++ b/Tests/RunCMake/CMP0040/CMP0040-WARN-missing-target-stderr.txt
@@ -0,0 +1,10 @@
+CMake Warning \(dev\) at CMP0040-WARN-missing-target.cmake:2 \(add_custom_command\):
+ Policy CMP0040 is not set: The target in the TARGET signature of
+ add_custom_command\(\) must exist. Run "cmake --help-policy CMP0040" for
+ policy details. Use the cmake_policy command to set the policy and
+ suppress this warning.
++
+ No TARGET 'foobar' has been created in this directory.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0040/CMP0040-WARN-missing-target.cmake b/Tests/RunCMake/CMP0040/CMP0040-WARN-missing-target.cmake
new file mode 100644
index 000000000..2c3e40149
--- /dev/null
+++ b/Tests/RunCMake/CMP0040/CMP0040-WARN-missing-target.cmake
@@ -0,0 +1,4 @@
+
+add_custom_command(TARGET foobar PRE_BUILD
+ COMMAND "${CMAKE_COMMAND} -E hello world"
+)
diff --git a/Tests/RunCMake/CMP0040/CMakeLists.txt b/Tests/RunCMake/CMP0040/CMakeLists.txt
new file mode 100644
index 000000000..a06591c31
--- /dev/null
+++ b/Tests/RunCMake/CMP0040/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0040/RunCMakeTest.cmake b/Tests/RunCMake/CMP0040/RunCMakeTest.cmake
new file mode 100644
index 000000000..13160e3a4
--- /dev/null
+++ b/Tests/RunCMake/CMP0040/RunCMakeTest.cmake
@@ -0,0 +1,8 @@
+include(RunCMake)
+
+run_cmake(CMP0040-OLD-missing-target)
+run_cmake(CMP0040-NEW-missing-target)
+run_cmake(CMP0040-WARN-missing-target)
+
+run_cmake(CMP0040-OLD-existing-target)
+run_cmake(CMP0040-NEW-existing-target)
diff --git a/Tests/RunCMake/CMP0040/empty.cpp b/Tests/RunCMake/CMP0040/empty.cpp
new file mode 100644
index 000000000..bfbbddeb9
--- /dev/null
+++ b/Tests/RunCMake/CMP0040/empty.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CMP0041/CMP0041-NEW-result.txt b/Tests/RunCMake/CMP0041/CMP0041-NEW-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CMP0041/CMP0041-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0041/CMP0041-NEW-stderr.txt b/Tests/RunCMake/CMP0041/CMP0041-NEW-stderr.txt
new file mode 100644
index 000000000..2ec3aef20
--- /dev/null
+++ b/Tests/RunCMake/CMP0041/CMP0041-NEW-stderr.txt
@@ -0,0 +1,20 @@
+CMake Error in CMakeLists.txt:
+ Target "foo" INTERFACE_INCLUDE_DIRECTORIES property contains relative path:
+
+ "include/\$<TARGET_PROPERTY:NAME>"
+
+
+CMake Error in CMakeLists.txt:
+ Target "foo" INTERFACE_INCLUDE_DIRECTORIES property contains path:
+
+ ".*/Tests/RunCMake/CMP0041/include/\$<TARGET_PROPERTY:NAME>"
+
+ which is prefixed in the source directory.
+
+
+CMake Error in CMakeLists.txt:
+ Target "foo" INTERFACE_INCLUDE_DIRECTORIES property contains path:
+
+ ".*/Tests/RunCMake/CMP0041/CMP0041-NEW-build/include/\$<TARGET_PROPERTY:NAME>"
+
+ which is prefixed in the build directory.
diff --git a/Tests/RunCMake/CMP0041/CMP0041-NEW.cmake b/Tests/RunCMake/CMP0041/CMP0041-NEW.cmake
new file mode 100644
index 000000000..605b79a00
--- /dev/null
+++ b/Tests/RunCMake/CMP0041/CMP0041-NEW.cmake
@@ -0,0 +1,12 @@
+
+cmake_policy(SET CMP0041 NEW)
+
+add_library(foo empty.cpp)
+set_property(TARGET foo
+ PROPERTY INTERFACE_INCLUDE_DIRECTORIES
+ include/$<TARGET_PROPERTY:NAME>
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/$<TARGET_PROPERTY:NAME>
+ ${CMAKE_CURRENT_BINARY_DIR}/include/$<TARGET_PROPERTY:NAME>
+)
+install(TARGETS foo EXPORT FooExport DESTINATION lib)
+install(EXPORT FooExport DESTINATION lib/cmake)
diff --git a/Tests/RunCMake/CMP0041/CMP0041-OLD-result.txt b/Tests/RunCMake/CMP0041/CMP0041-OLD-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0041/CMP0041-OLD-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0041/CMP0041-OLD.cmake b/Tests/RunCMake/CMP0041/CMP0041-OLD.cmake
new file mode 100644
index 000000000..16cbced52
--- /dev/null
+++ b/Tests/RunCMake/CMP0041/CMP0041-OLD.cmake
@@ -0,0 +1,12 @@
+
+cmake_policy(SET CMP0041 OLD)
+
+add_library(foo empty.cpp)
+set_property(TARGET foo
+ PROPERTY INTERFACE_INCLUDE_DIRECTORIES
+ include/$<TARGET_PROPERTY:NAME>
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/$<TARGET_PROPERTY:NAME>
+ ${CMAKE_CURRENT_BINARY_DIR}/include/$<TARGET_PROPERTY:NAME>
+)
+install(TARGETS foo EXPORT FooExport DESTINATION lib)
+install(EXPORT FooExport DESTINATION lib/cmake)
diff --git a/Tests/RunCMake/CMP0041/CMP0041-WARN-result.txt b/Tests/RunCMake/CMP0041/CMP0041-WARN-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0041/CMP0041-WARN-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0041/CMP0041-WARN-stderr.txt b/Tests/RunCMake/CMP0041/CMP0041-WARN-stderr.txt
new file mode 100644
index 000000000..a7d303e4d
--- /dev/null
+++ b/Tests/RunCMake/CMP0041/CMP0041-WARN-stderr.txt
@@ -0,0 +1,32 @@
+CMake Warning in CMakeLists.txt:
+ Policy CMP0041 is not set: Error on relative include with generator
+ expression. Run "cmake --help-policy CMP0041" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+
+ Target "foo" INTERFACE_INCLUDE_DIRECTORIES property contains relative path:
+
+ "include/\$<TARGET_PROPERTY:NAME>"
+
+
+CMake Warning in CMakeLists.txt:
+ Policy CMP0041 is not set: Error on relative include with generator
+ expression. Run "cmake --help-policy CMP0041" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+
+ Target "foo" INTERFACE_INCLUDE_DIRECTORIES property contains path:
+
+ ".*/Tests/RunCMake/CMP0041/include/\$<TARGET_PROPERTY:NAME>"
+
+ which is prefixed in the source directory.
+
+
+CMake Warning in CMakeLists.txt:
+ Policy CMP0041 is not set: Error on relative include with generator
+ expression. Run "cmake --help-policy CMP0041" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+
+ Target "foo" INTERFACE_INCLUDE_DIRECTORIES property contains path:
+
+ ".*/Tests/RunCMake/CMP0041/CMP0041-WARN-build/include/\$<TARGET_PROPERTY:NAME>"
+
+ which is prefixed in the build directory.
diff --git a/Tests/RunCMake/CMP0041/CMP0041-WARN.cmake b/Tests/RunCMake/CMP0041/CMP0041-WARN.cmake
new file mode 100644
index 000000000..873cbc708
--- /dev/null
+++ b/Tests/RunCMake/CMP0041/CMP0041-WARN.cmake
@@ -0,0 +1,10 @@
+
+add_library(foo empty.cpp)
+set_property(TARGET foo
+ PROPERTY INTERFACE_INCLUDE_DIRECTORIES
+ include/$<TARGET_PROPERTY:NAME>
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/$<TARGET_PROPERTY:NAME>
+ ${CMAKE_CURRENT_BINARY_DIR}/include/$<TARGET_PROPERTY:NAME>
+)
+install(TARGETS foo EXPORT FooExport DESTINATION lib)
+install(EXPORT FooExport DESTINATION lib/cmake)
diff --git a/Tests/RunCMake/CMP0041/CMP0041-tid-NEW-result.txt b/Tests/RunCMake/CMP0041/CMP0041-tid-NEW-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CMP0041/CMP0041-tid-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0041/CMP0041-tid-NEW-stderr.txt b/Tests/RunCMake/CMP0041/CMP0041-tid-NEW-stderr.txt
new file mode 100644
index 000000000..9b0a21431
--- /dev/null
+++ b/Tests/RunCMake/CMP0041/CMP0041-tid-NEW-stderr.txt
@@ -0,0 +1,22 @@
+CMake Error in CMakeLists.txt:
+ Target "foo" INTERFACE_INCLUDE_DIRECTORIES property contains path:
+
+ ".*/Tests/RunCMake/CMP0041/include/\$<TARGET_PROPERTY:NAME>"
+
+ which is prefixed in the source directory.
+
+
+CMake Error in CMakeLists.txt:
+ Target "foo" INTERFACE_INCLUDE_DIRECTORIES property contains path:
+
+ ".*/Tests/RunCMake/CMP0041/include/\$<TARGET_PROPERTY:NAME>"
+
+ which is prefixed in the source directory.
+
+
+CMake Error in CMakeLists.txt:
+ Target "foo" INTERFACE_INCLUDE_DIRECTORIES property contains path:
+
+ ".*/Tests/RunCMake/CMP0041/CMP0041-tid-NEW-build/include/\$<TARGET_PROPERTY:NAME>"
+
+ which is prefixed in the build directory.
diff --git a/Tests/RunCMake/CMP0041/CMP0041-tid-NEW.cmake b/Tests/RunCMake/CMP0041/CMP0041-tid-NEW.cmake
new file mode 100644
index 000000000..3005108aa
--- /dev/null
+++ b/Tests/RunCMake/CMP0041/CMP0041-tid-NEW.cmake
@@ -0,0 +1,11 @@
+
+cmake_policy(SET CMP0041 NEW)
+
+add_library(foo empty.cpp)
+target_include_directories(foo INTERFACE
+ include/$<TARGET_PROPERTY:NAME>
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/$<TARGET_PROPERTY:NAME>
+ ${CMAKE_CURRENT_BINARY_DIR}/include/$<TARGET_PROPERTY:NAME>
+)
+install(TARGETS foo EXPORT FooExport DESTINATION lib)
+install(EXPORT FooExport DESTINATION lib/cmake)
diff --git a/Tests/RunCMake/CMP0041/CMP0041-tid-OLD-result.txt b/Tests/RunCMake/CMP0041/CMP0041-tid-OLD-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0041/CMP0041-tid-OLD-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0041/CMP0041-tid-OLD.cmake b/Tests/RunCMake/CMP0041/CMP0041-tid-OLD.cmake
new file mode 100644
index 000000000..b5c4e7f85
--- /dev/null
+++ b/Tests/RunCMake/CMP0041/CMP0041-tid-OLD.cmake
@@ -0,0 +1,11 @@
+
+cmake_policy(SET CMP0041 OLD)
+
+add_library(foo empty.cpp)
+target_include_directories(foo INTERFACE
+ include/$<TARGET_PROPERTY:NAME>
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/$<TARGET_PROPERTY:NAME>
+ ${CMAKE_CURRENT_BINARY_DIR}/include/$<TARGET_PROPERTY:NAME>
+)
+install(TARGETS foo EXPORT FooExport DESTINATION lib)
+install(EXPORT FooExport DESTINATION lib/cmake)
diff --git a/Tests/RunCMake/CMP0041/CMP0041-tid-WARN-result.txt b/Tests/RunCMake/CMP0041/CMP0041-tid-WARN-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0041/CMP0041-tid-WARN-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0041/CMP0041-tid-WARN-stderr.txt b/Tests/RunCMake/CMP0041/CMP0041-tid-WARN-stderr.txt
new file mode 100644
index 000000000..aae2c7a17
--- /dev/null
+++ b/Tests/RunCMake/CMP0041/CMP0041-tid-WARN-stderr.txt
@@ -0,0 +1,34 @@
+CMake Warning in CMakeLists.txt:
+ Policy CMP0041 is not set: Error on relative include with generator
+ expression. Run "cmake --help-policy CMP0041" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+
+ Target "foo" INTERFACE_INCLUDE_DIRECTORIES property contains path:
+
+ ".*/Tests/RunCMake/CMP0041/include/\$<TARGET_PROPERTY:NAME>"
+
+ which is prefixed in the source directory.
+
+
+CMake Warning in CMakeLists.txt:
+ Policy CMP0041 is not set: Error on relative include with generator
+ expression. Run "cmake --help-policy CMP0041" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+
+ Target "foo" INTERFACE_INCLUDE_DIRECTORIES property contains path:
+
+ ".*/Tests/RunCMake/CMP0041/include/\$<TARGET_PROPERTY:NAME>"
+
+ which is prefixed in the source directory.
+
+
+CMake Warning in CMakeLists.txt:
+ Policy CMP0041 is not set: Error on relative include with generator
+ expression. Run "cmake --help-policy CMP0041" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+
+ Target "foo" INTERFACE_INCLUDE_DIRECTORIES property contains path:
+
+ ".*/Tests/RunCMake/CMP0041/CMP0041-tid-WARN-build/include/\$<TARGET_PROPERTY:NAME>"
+
+ which is prefixed in the build directory.
diff --git a/Tests/RunCMake/CMP0041/CMP0041-tid-WARN.cmake b/Tests/RunCMake/CMP0041/CMP0041-tid-WARN.cmake
new file mode 100644
index 000000000..ee4c2a621
--- /dev/null
+++ b/Tests/RunCMake/CMP0041/CMP0041-tid-WARN.cmake
@@ -0,0 +1,9 @@
+
+add_library(foo empty.cpp)
+target_include_directories(foo INTERFACE
+ include/$<TARGET_PROPERTY:NAME>
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/$<TARGET_PROPERTY:NAME>
+ ${CMAKE_CURRENT_BINARY_DIR}/include/$<TARGET_PROPERTY:NAME>
+)
+install(TARGETS foo EXPORT FooExport DESTINATION lib)
+install(EXPORT FooExport DESTINATION lib/cmake)
diff --git a/Tests/RunCMake/CMP0041/CMakeLists.txt b/Tests/RunCMake/CMP0041/CMakeLists.txt
new file mode 100644
index 000000000..f452db177
--- /dev/null
+++ b/Tests/RunCMake/CMP0041/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0041/RunCMakeTest.cmake b/Tests/RunCMake/CMP0041/RunCMakeTest.cmake
new file mode 100644
index 000000000..e7f27a1a2
--- /dev/null
+++ b/Tests/RunCMake/CMP0041/RunCMakeTest.cmake
@@ -0,0 +1,11 @@
+include(RunCMake)
+
+# Protect tests from running inside the default install prefix.
+set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/NotDefaultPrefix")
+
+run_cmake(CMP0041-OLD)
+run_cmake(CMP0041-NEW)
+run_cmake(CMP0041-WARN)
+run_cmake(CMP0041-tid-OLD)
+run_cmake(CMP0041-tid-NEW)
+run_cmake(CMP0041-tid-WARN)
diff --git a/Tests/RunCMake/CMP0041/empty.cpp b/Tests/RunCMake/CMP0041/empty.cpp
new file mode 100644
index 000000000..bfbbddeb9
--- /dev/null
+++ b/Tests/RunCMake/CMP0041/empty.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CMP0042/CMP0042-NEW-result.txt b/Tests/RunCMake/CMP0042/CMP0042-NEW-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0042/CMP0042-NEW-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0042/CMP0042-NEW.cmake b/Tests/RunCMake/CMP0042/CMP0042-NEW.cmake
new file mode 100644
index 000000000..778a44431
--- /dev/null
+++ b/Tests/RunCMake/CMP0042/CMP0042-NEW.cmake
@@ -0,0 +1,4 @@
+
+cmake_policy(SET CMP0042 NEW)
+
+add_library(foo SHARED empty.cpp)
diff --git a/Tests/RunCMake/CMP0042/CMP0042-OLD-result.txt b/Tests/RunCMake/CMP0042/CMP0042-OLD-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0042/CMP0042-OLD-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0042/CMP0042-OLD.cmake b/Tests/RunCMake/CMP0042/CMP0042-OLD.cmake
new file mode 100644
index 000000000..1aede967c
--- /dev/null
+++ b/Tests/RunCMake/CMP0042/CMP0042-OLD.cmake
@@ -0,0 +1,4 @@
+
+cmake_policy(SET CMP0042 OLD)
+
+add_library(foo SHARED empty.cpp)
diff --git a/Tests/RunCMake/CMP0042/CMP0042-WARN-result.txt b/Tests/RunCMake/CMP0042/CMP0042-WARN-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0042/CMP0042-WARN-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0042/CMP0042-WARN-stderr.txt b/Tests/RunCMake/CMP0042/CMP0042-WARN-stderr.txt
new file mode 100644
index 000000000..f3574a1a5
--- /dev/null
+++ b/Tests/RunCMake/CMP0042/CMP0042-WARN-stderr.txt
@@ -0,0 +1,10 @@
+CMake Warning \(dev\):
+ Policy CMP0042 is not set: MACOSX_RPATH is enabled by default. Run "cmake
+ --help-policy CMP0042" for policy details. Use the cmake_policy command to
+ set the policy and suppress this warning.
+
+ MACOSX_RPATH is not specified for the following targets:
+
+ foo
+
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0042/CMP0042-WARN.cmake b/Tests/RunCMake/CMP0042/CMP0042-WARN.cmake
new file mode 100644
index 000000000..3fa32b16f
--- /dev/null
+++ b/Tests/RunCMake/CMP0042/CMP0042-WARN.cmake
@@ -0,0 +1,9 @@
+
+add_library(foo SHARED empty.cpp)
+add_library(foo-static STATIC empty.cpp)
+add_library(foo2 SHARED empty.cpp)
+set_target_properties(foo2 PROPERTIES MACOSX_RPATH 1)
+add_library(foo3 SHARED empty.cpp)
+set_target_properties(foo3 PROPERTIES BUILD_WITH_INSTALL_RPATH 1 INSTALL_NAME_DIR "@loader_path")
+add_library(foo4 SHARED empty.cpp)
+set_target_properties(foo4 PROPERTIES BUILD_WITH_INSTALL_RPATH 1 INSTALL_NAME_DIR "@rpath")
diff --git a/Tests/RunCMake/CMP0042/CMakeLists.txt b/Tests/RunCMake/CMP0042/CMakeLists.txt
new file mode 100644
index 000000000..f452db177
--- /dev/null
+++ b/Tests/RunCMake/CMP0042/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0042/RunCMakeTest.cmake b/Tests/RunCMake/CMP0042/RunCMakeTest.cmake
new file mode 100644
index 000000000..3b226d74c
--- /dev/null
+++ b/Tests/RunCMake/CMP0042/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0042-OLD)
+run_cmake(CMP0042-NEW)
+run_cmake(CMP0042-WARN)
diff --git a/Tests/RunCMake/CMP0042/empty.cpp b/Tests/RunCMake/CMP0042/empty.cpp
new file mode 100644
index 000000000..bfbbddeb9
--- /dev/null
+++ b/Tests/RunCMake/CMP0042/empty.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CMP0043/CMP0043-NEW-result.txt b/Tests/RunCMake/CMP0043/CMP0043-NEW-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0043/CMP0043-NEW-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0043/CMP0043-NEW.cmake b/Tests/RunCMake/CMP0043/CMP0043-NEW.cmake
new file mode 100644
index 000000000..857153def
--- /dev/null
+++ b/Tests/RunCMake/CMP0043/CMP0043-NEW.cmake
@@ -0,0 +1,7 @@
+
+cmake_policy(SET CMP0043 NEW)
+
+add_library(foo empty.cpp)
+set_property(TARGET foo
+ PROPERTY COMPILE_DEFINITIONS_DEBUG "DEBUG_MODE"
+)
diff --git a/Tests/RunCMake/CMP0043/CMP0043-OLD-result.txt b/Tests/RunCMake/CMP0043/CMP0043-OLD-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0043/CMP0043-OLD-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0043/CMP0043-OLD.cmake b/Tests/RunCMake/CMP0043/CMP0043-OLD.cmake
new file mode 100644
index 000000000..f379430c5
--- /dev/null
+++ b/Tests/RunCMake/CMP0043/CMP0043-OLD.cmake
@@ -0,0 +1,7 @@
+
+cmake_policy(SET CMP0043 OLD)
+
+add_library(foo empty.cpp)
+set_property(TARGET foo
+ PROPERTY COMPILE_DEFINITIONS_DEBUG "DEBUG_MODE"
+)
diff --git a/Tests/RunCMake/CMP0043/CMP0043-WARN-result.txt b/Tests/RunCMake/CMP0043/CMP0043-WARN-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0043/CMP0043-WARN-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0043/CMP0043-WARN-stderr.txt b/Tests/RunCMake/CMP0043/CMP0043-WARN-stderr.txt
new file mode 100644
index 000000000..4769a63d1
--- /dev/null
+++ b/Tests/RunCMake/CMP0043/CMP0043-WARN-stderr.txt
@@ -0,0 +1,5 @@
+CMake Warning \(dev\) in CMakeLists.txt:
+ Policy CMP0043 is not set: Ignore COMPILE_DEFINITIONS_<Config> properties.
+ Run "cmake --help-policy CMP0043" for policy details. Use the cmake_policy
+ command to set the policy and suppress this warning.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0043/CMP0043-WARN.cmake b/Tests/RunCMake/CMP0043/CMP0043-WARN.cmake
new file mode 100644
index 000000000..161a60d0e
--- /dev/null
+++ b/Tests/RunCMake/CMP0043/CMP0043-WARN.cmake
@@ -0,0 +1,5 @@
+
+add_library(foo empty.cpp)
+set_property(TARGET foo
+ PROPERTY COMPILE_DEFINITIONS_DEBUG "DEBUG_MODE"
+)
diff --git a/Tests/RunCMake/CMP0043/CMakeLists.txt b/Tests/RunCMake/CMP0043/CMakeLists.txt
new file mode 100644
index 000000000..d027f3e0e
--- /dev/null
+++ b/Tests/RunCMake/CMP0043/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE) # policy used at end of dir
+
+if(CMAKE_BUILD_TYPE)
+ # Dummy variable use
+endif()
diff --git a/Tests/RunCMake/CMP0043/RunCMakeTest.cmake b/Tests/RunCMake/CMP0043/RunCMakeTest.cmake
new file mode 100644
index 000000000..7f9572e5a
--- /dev/null
+++ b/Tests/RunCMake/CMP0043/RunCMakeTest.cmake
@@ -0,0 +1,7 @@
+include(RunCMake)
+
+list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
+
+run_cmake(CMP0043-OLD)
+run_cmake(CMP0043-NEW)
+run_cmake(CMP0043-WARN)
diff --git a/Tests/RunCMake/CMP0043/empty.cpp b/Tests/RunCMake/CMP0043/empty.cpp
new file mode 100644
index 000000000..bfbbddeb9
--- /dev/null
+++ b/Tests/RunCMake/CMP0043/empty.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CMP0045/CMP0045-NEW-result.txt b/Tests/RunCMake/CMP0045/CMP0045-NEW-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CMP0045/CMP0045-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0045/CMP0045-NEW-stderr.txt b/Tests/RunCMake/CMP0045/CMP0045-NEW-stderr.txt
new file mode 100644
index 000000000..805a85ed3
--- /dev/null
+++ b/Tests/RunCMake/CMP0045/CMP0045-NEW-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at CMP0045-NEW.cmake:4 \(get_target_property\):
+ get_target_property\(\) called with non-existent target "tgt".
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CMP0045/CMP0045-NEW.cmake b/Tests/RunCMake/CMP0045/CMP0045-NEW.cmake
new file mode 100644
index 000000000..7b2a3cd61
--- /dev/null
+++ b/Tests/RunCMake/CMP0045/CMP0045-NEW.cmake
@@ -0,0 +1,4 @@
+
+cmake_policy(SET CMP0045 NEW)
+
+get_target_property(result tgt TYPE)
diff --git a/Tests/RunCMake/CMP0045/CMP0045-OLD-result.txt b/Tests/RunCMake/CMP0045/CMP0045-OLD-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0045/CMP0045-OLD-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0045/CMP0045-OLD.cmake b/Tests/RunCMake/CMP0045/CMP0045-OLD.cmake
new file mode 100644
index 000000000..90201a325
--- /dev/null
+++ b/Tests/RunCMake/CMP0045/CMP0045-OLD.cmake
@@ -0,0 +1,4 @@
+
+cmake_policy(SET CMP0045 OLD)
+
+get_target_property(result tgt TYPE)
diff --git a/Tests/RunCMake/CMP0045/CMP0045-WARN-result.txt b/Tests/RunCMake/CMP0045/CMP0045-WARN-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0045/CMP0045-WARN-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0045/CMP0045-WARN-stderr.txt b/Tests/RunCMake/CMP0045/CMP0045-WARN-stderr.txt
new file mode 100644
index 000000000..4c532249f
--- /dev/null
+++ b/Tests/RunCMake/CMP0045/CMP0045-WARN-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning \(dev\) at CMP0045-WARN.cmake:2 \(get_target_property\):
+ Policy CMP0045 is not set: Error on non-existent target in
+ get_target_property. Run "cmake --help-policy CMP0045" for policy details.
+ Use the cmake_policy command to set the policy and suppress this warning.
+
+ get_target_property\(\) called with non-existent target "tgt".
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0045/CMP0045-WARN.cmake b/Tests/RunCMake/CMP0045/CMP0045-WARN.cmake
new file mode 100644
index 000000000..86a99a003
--- /dev/null
+++ b/Tests/RunCMake/CMP0045/CMP0045-WARN.cmake
@@ -0,0 +1,2 @@
+
+get_target_property(result tgt TYPE)
diff --git a/Tests/RunCMake/CMP0045/CMakeLists.txt b/Tests/RunCMake/CMP0045/CMakeLists.txt
new file mode 100644
index 000000000..f452db177
--- /dev/null
+++ b/Tests/RunCMake/CMP0045/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0045/RunCMakeTest.cmake b/Tests/RunCMake/CMP0045/RunCMakeTest.cmake
new file mode 100644
index 000000000..7c0e8a215
--- /dev/null
+++ b/Tests/RunCMake/CMP0045/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0045-OLD)
+run_cmake(CMP0045-NEW)
+run_cmake(CMP0045-WARN)
diff --git a/Tests/RunCMake/CMP0045/empty.cpp b/Tests/RunCMake/CMP0045/empty.cpp
new file mode 100644
index 000000000..bfbbddeb9
--- /dev/null
+++ b/Tests/RunCMake/CMP0045/empty.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CMP0046/CMP0046-Duplicate-result.txt b/Tests/RunCMake/CMP0046/CMP0046-Duplicate-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0046/CMP0046-Duplicate-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0046/CMP0046-Duplicate-stderr.txt b/Tests/RunCMake/CMP0046/CMP0046-Duplicate-stderr.txt
new file mode 100644
index 000000000..fb31d6d6e
--- /dev/null
+++ b/Tests/RunCMake/CMP0046/CMP0046-Duplicate-stderr.txt
@@ -0,0 +1,10 @@
+CMake Warning \(dev\) at CMP0046-Duplicate.cmake:5 \(add_dependencies\):
+ Policy CMP0046 is not set: Error on non-existent dependency in
+ add_dependencies. Run "cmake --help-policy CMP0046" for policy details.
+ Use the cmake_policy command to set the policy and suppress this warning.
+
+ The dependency target "ctgt_no_exist" of target "dummy" does not exist.
+Call Stack \(most recent call first\):
+ CMP0046-Duplicate.cmake:8 \(add_dep\)
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0046/CMP0046-Duplicate.cmake b/Tests/RunCMake/CMP0046/CMP0046-Duplicate.cmake
new file mode 100644
index 000000000..26e640b9d
--- /dev/null
+++ b/Tests/RunCMake/CMP0046/CMP0046-Duplicate.cmake
@@ -0,0 +1,9 @@
+
+add_library(dummy empty.cpp)
+
+macro(add_dep)
+ add_dependencies(dummy ctgt_no_exist)
+endmacro()
+
+add_dep()
+add_dep()
diff --git a/Tests/RunCMake/CMP0046/CMP0046-NEW-existing-dependency.cmake b/Tests/RunCMake/CMP0046/CMP0046-NEW-existing-dependency.cmake
new file mode 100644
index 000000000..0be290a8d
--- /dev/null
+++ b/Tests/RunCMake/CMP0046/CMP0046-NEW-existing-dependency.cmake
@@ -0,0 +1,5 @@
+cmake_policy(SET CMP0046 NEW)
+
+add_custom_target(foo)
+add_custom_target(bar)
+add_dependencies(foo bar)
diff --git a/Tests/RunCMake/CMP0046/CMP0046-NEW-missing-dependency-result.txt b/Tests/RunCMake/CMP0046/CMP0046-NEW-missing-dependency-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CMP0046/CMP0046-NEW-missing-dependency-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0046/CMP0046-NEW-missing-dependency-stderr.txt b/Tests/RunCMake/CMP0046/CMP0046-NEW-missing-dependency-stderr.txt
new file mode 100644
index 000000000..381647ff8
--- /dev/null
+++ b/Tests/RunCMake/CMP0046/CMP0046-NEW-missing-dependency-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at CMP0046-NEW-missing-dependency.cmake:4 \(add_dependencies\):
+ The dependency target "bar" of target "foo" does not exist.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CMP0046/CMP0046-NEW-missing-dependency.cmake b/Tests/RunCMake/CMP0046/CMP0046-NEW-missing-dependency.cmake
new file mode 100644
index 000000000..9bb6b90c8
--- /dev/null
+++ b/Tests/RunCMake/CMP0046/CMP0046-NEW-missing-dependency.cmake
@@ -0,0 +1,4 @@
+cmake_policy(SET CMP0046 NEW)
+
+add_custom_target(foo)
+add_dependencies(foo bar)
diff --git a/Tests/RunCMake/CMP0046/CMP0046-OLD-existing-dependency.cmake b/Tests/RunCMake/CMP0046/CMP0046-OLD-existing-dependency.cmake
new file mode 100644
index 000000000..b22ab4fb9
--- /dev/null
+++ b/Tests/RunCMake/CMP0046/CMP0046-OLD-existing-dependency.cmake
@@ -0,0 +1,5 @@
+cmake_policy(SET CMP0046 OLD)
+
+add_custom_target(foo)
+add_custom_target(bar)
+add_dependencies(foo bar)
diff --git a/Tests/RunCMake/CMP0046/CMP0046-OLD-missing-dependency.cmake b/Tests/RunCMake/CMP0046/CMP0046-OLD-missing-dependency.cmake
new file mode 100644
index 000000000..5ee3cb75e
--- /dev/null
+++ b/Tests/RunCMake/CMP0046/CMP0046-OLD-missing-dependency.cmake
@@ -0,0 +1,4 @@
+cmake_policy(SET CMP0046 OLD)
+
+add_custom_target(foo)
+add_dependencies(foo bar)
diff --git a/Tests/RunCMake/CMP0046/CMP0046-WARN-missing-dependency-stderr.txt b/Tests/RunCMake/CMP0046/CMP0046-WARN-missing-dependency-stderr.txt
new file mode 100644
index 000000000..fed36f16e
--- /dev/null
+++ b/Tests/RunCMake/CMP0046/CMP0046-WARN-missing-dependency-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning \(dev\) at CMP0046-WARN-missing-dependency.cmake:2 \(add_dependencies\):
+ Policy CMP0046 is not set: Error on non-existent dependency in
+ add_dependencies. Run "cmake --help-policy CMP0046" for policy details.
+ Use the cmake_policy command to set the policy and suppress this warning.
++
+ The dependency target "bar" of target "foo" does not exist.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0046/CMP0046-WARN-missing-dependency.cmake b/Tests/RunCMake/CMP0046/CMP0046-WARN-missing-dependency.cmake
new file mode 100644
index 000000000..896fa40f6
--- /dev/null
+++ b/Tests/RunCMake/CMP0046/CMP0046-WARN-missing-dependency.cmake
@@ -0,0 +1,2 @@
+add_custom_target(foo)
+add_dependencies(foo bar)
diff --git a/Tests/RunCMake/CMP0046/CMakeLists.txt b/Tests/RunCMake/CMP0046/CMakeLists.txt
new file mode 100644
index 000000000..a06591c31
--- /dev/null
+++ b/Tests/RunCMake/CMP0046/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0046/RunCMakeTest.cmake b/Tests/RunCMake/CMP0046/RunCMakeTest.cmake
new file mode 100644
index 000000000..0a39c7659
--- /dev/null
+++ b/Tests/RunCMake/CMP0046/RunCMakeTest.cmake
@@ -0,0 +1,9 @@
+include(RunCMake)
+
+run_cmake(CMP0046-OLD-missing-dependency)
+run_cmake(CMP0046-NEW-missing-dependency)
+run_cmake(CMP0046-WARN-missing-dependency)
+
+run_cmake(CMP0046-OLD-existing-dependency)
+run_cmake(CMP0046-NEW-existing-dependency)
+run_cmake(CMP0046-Duplicate)
diff --git a/Tests/RunCMake/CMP0046/empty.cpp b/Tests/RunCMake/CMP0046/empty.cpp
new file mode 100644
index 000000000..bfbbddeb9
--- /dev/null
+++ b/Tests/RunCMake/CMP0046/empty.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CMP0049/CMP0049-NEW-result.txt b/Tests/RunCMake/CMP0049/CMP0049-NEW-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CMP0049/CMP0049-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0049/CMP0049-NEW-stderr.txt b/Tests/RunCMake/CMP0049/CMP0049-NEW-stderr.txt
new file mode 100644
index 000000000..ff787e847
--- /dev/null
+++ b/Tests/RunCMake/CMP0049/CMP0049-NEW-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at CMP0049-NEW.cmake:5 \(add_library\):
+ Legacy variable expansion in source file "\${tgt_srcs}" expanded to
+ "empty.cpp" in target "tgt". This behavior will be removed in a future
+ version of CMake.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CMP0049/CMP0049-NEW.cmake b/Tests/RunCMake/CMP0049/CMP0049-NEW.cmake
new file mode 100644
index 000000000..85b5aa854
--- /dev/null
+++ b/Tests/RunCMake/CMP0049/CMP0049-NEW.cmake
@@ -0,0 +1,5 @@
+
+cmake_policy(SET CMP0049 NEW)
+
+set(tgt_srcs empty.cpp)
+add_library(tgt \${tgt_srcs})
diff --git a/Tests/RunCMake/CMP0049/CMP0049-OLD-result.txt b/Tests/RunCMake/CMP0049/CMP0049-OLD-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0049/CMP0049-OLD-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0049/CMP0049-OLD.cmake b/Tests/RunCMake/CMP0049/CMP0049-OLD.cmake
new file mode 100644
index 000000000..ae6fd3bcd
--- /dev/null
+++ b/Tests/RunCMake/CMP0049/CMP0049-OLD.cmake
@@ -0,0 +1,5 @@
+
+cmake_policy(SET CMP0049 OLD)
+
+set(tgt_srcs empty.cpp)
+add_library(tgt \${tgt_srcs})
diff --git a/Tests/RunCMake/CMP0049/CMP0049-WARN-result.txt b/Tests/RunCMake/CMP0049/CMP0049-WARN-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0049/CMP0049-WARN-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0049/CMP0049-WARN-stderr.txt b/Tests/RunCMake/CMP0049/CMP0049-WARN-stderr.txt
new file mode 100644
index 000000000..0cf5ce354
--- /dev/null
+++ b/Tests/RunCMake/CMP0049/CMP0049-WARN-stderr.txt
@@ -0,0 +1,11 @@
+CMake Warning \(dev\) at CMP0049-WARN.cmake:3 \(add_library\):
+ Policy CMP0049 is not set: Do not expand variables in target source
+ entries. Run "cmake --help-policy CMP0049" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+
+ Legacy variable expansion in source file "\${tgt_srcs}" expanded to
+ "empty.cpp" in target "tgt". This behavior will be removed in a future
+ version of CMake.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0049/CMP0049-WARN.cmake b/Tests/RunCMake/CMP0049/CMP0049-WARN.cmake
new file mode 100644
index 000000000..ada082e61
--- /dev/null
+++ b/Tests/RunCMake/CMP0049/CMP0049-WARN.cmake
@@ -0,0 +1,3 @@
+
+set(tgt_srcs empty.cpp)
+add_library(tgt \${tgt_srcs})
diff --git a/Tests/RunCMake/CMP0049/CMakeLists.txt b/Tests/RunCMake/CMP0049/CMakeLists.txt
new file mode 100644
index 000000000..a06591c31
--- /dev/null
+++ b/Tests/RunCMake/CMP0049/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0049/RunCMakeTest.cmake b/Tests/RunCMake/CMP0049/RunCMakeTest.cmake
new file mode 100644
index 000000000..a8aa9d965
--- /dev/null
+++ b/Tests/RunCMake/CMP0049/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0049-OLD)
+run_cmake(CMP0049-NEW)
+run_cmake(CMP0049-WARN)
diff --git a/Tests/RunCMake/CMP0049/empty.cpp b/Tests/RunCMake/CMP0049/empty.cpp
new file mode 100644
index 000000000..bfbbddeb9
--- /dev/null
+++ b/Tests/RunCMake/CMP0049/empty.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CMP0050/CMP0050-NEW-result.txt b/Tests/RunCMake/CMP0050/CMP0050-NEW-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CMP0050/CMP0050-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0050/CMP0050-NEW-stderr.txt b/Tests/RunCMake/CMP0050/CMP0050-NEW-stderr.txt
new file mode 100644
index 000000000..e913b3fa9
--- /dev/null
+++ b/Tests/RunCMake/CMP0050/CMP0050-NEW-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at CMP0050-NEW.cmake:5 \(add_custom_command\):
+ The SOURCE signatures of add_custom_command are no longer supported.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CMP0050/CMP0050-NEW.cmake b/Tests/RunCMake/CMP0050/CMP0050-NEW.cmake
new file mode 100644
index 000000000..cdc65b897
--- /dev/null
+++ b/Tests/RunCMake/CMP0050/CMP0050-NEW.cmake
@@ -0,0 +1,13 @@
+
+cmake_policy(SET CMP0050 NEW)
+
+add_library(empty empty.cpp)
+add_custom_command(
+ TARGET empty
+ SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/input.h.in
+ COMMAND ${CMAKE_COMMAND}
+ ARGS -E copy ${CMAKE_CURRENT_SOURCE_DIR}/input.h.in
+ ${CMAKE_CURRENT_BINARY_DIR}/input.h
+ OUTPUTS ${CMAKE_CURRENT_BINARY_DIR}/input.h
+ DEPENDS ${CMAKE_COMMAND}
+)
diff --git a/Tests/RunCMake/CMP0050/CMP0050-OLD-result.txt b/Tests/RunCMake/CMP0050/CMP0050-OLD-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0050/CMP0050-OLD-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0050/CMP0050-OLD.cmake b/Tests/RunCMake/CMP0050/CMP0050-OLD.cmake
new file mode 100644
index 000000000..efb37e55b
--- /dev/null
+++ b/Tests/RunCMake/CMP0050/CMP0050-OLD.cmake
@@ -0,0 +1,13 @@
+
+cmake_policy(SET CMP0050 OLD)
+
+add_library(empty empty.cpp)
+add_custom_command(
+ TARGET empty
+ SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/input.h.in
+ COMMAND ${CMAKE_COMMAND}
+ ARGS -E copy ${CMAKE_CURRENT_SOURCE_DIR}/input.h.in
+ ${CMAKE_CURRENT_BINARY_DIR}/input.h
+ OUTPUTS ${CMAKE_CURRENT_BINARY_DIR}/input.h
+ DEPENDS ${CMAKE_COMMAND}
+)
diff --git a/Tests/RunCMake/CMP0050/CMP0050-WARN-result.txt b/Tests/RunCMake/CMP0050/CMP0050-WARN-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0050/CMP0050-WARN-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0050/CMP0050-WARN-stderr.txt b/Tests/RunCMake/CMP0050/CMP0050-WARN-stderr.txt
new file mode 100644
index 000000000..c88d59523
--- /dev/null
+++ b/Tests/RunCMake/CMP0050/CMP0050-WARN-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning \(dev\) at CMP0050-WARN.cmake:3 \(add_custom_command\):
+ Policy CMP0050 is not set: Disallow add_custom_command SOURCE signatures.
+ Run "cmake --help-policy CMP0050" for policy details. Use the cmake_policy
+ command to set the policy and suppress this warning.
+
+ The SOURCE signatures of add_custom_command are no longer supported.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0050/CMP0050-WARN.cmake b/Tests/RunCMake/CMP0050/CMP0050-WARN.cmake
new file mode 100644
index 000000000..e57230e5b
--- /dev/null
+++ b/Tests/RunCMake/CMP0050/CMP0050-WARN.cmake
@@ -0,0 +1,11 @@
+
+add_library(empty empty.cpp)
+add_custom_command(
+ TARGET empty
+ SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/input.h.in
+ COMMAND ${CMAKE_COMMAND}
+ ARGS -E copy ${CMAKE_CURRENT_SOURCE_DIR}/input.h.in
+ ${CMAKE_CURRENT_BINARY_DIR}/input.h
+ OUTPUTS ${CMAKE_CURRENT_BINARY_DIR}/input.h
+ DEPENDS ${CMAKE_COMMAND}
+)
diff --git a/Tests/RunCMake/CMP0050/CMakeLists.txt b/Tests/RunCMake/CMP0050/CMakeLists.txt
new file mode 100644
index 000000000..a06591c31
--- /dev/null
+++ b/Tests/RunCMake/CMP0050/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0050/RunCMakeTest.cmake b/Tests/RunCMake/CMP0050/RunCMakeTest.cmake
new file mode 100644
index 000000000..b7de28491
--- /dev/null
+++ b/Tests/RunCMake/CMP0050/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0050-OLD)
+run_cmake(CMP0050-NEW)
+run_cmake(CMP0050-WARN)
diff --git a/Tests/RunCMake/CMP0050/empty.cpp b/Tests/RunCMake/CMP0050/empty.cpp
new file mode 100644
index 000000000..182ea29c9
--- /dev/null
+++ b/Tests/RunCMake/CMP0050/empty.cpp
@@ -0,0 +1,10 @@
+
+#include "input.h"
+
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CMP0050/input.h.in b/Tests/RunCMake/CMP0050/input.h.in
new file mode 100644
index 000000000..d8c5d26a8
--- /dev/null
+++ b/Tests/RunCMake/CMP0050/input.h.in
@@ -0,0 +1,2 @@
+
+#define INPUT
diff --git a/Tests/RunCMake/CMP0051/CMP0051-NEW-result.txt b/Tests/RunCMake/CMP0051/CMP0051-NEW-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0051/CMP0051-NEW-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0051/CMP0051-NEW-stderr.txt b/Tests/RunCMake/CMP0051/CMP0051-NEW-stderr.txt
new file mode 100644
index 000000000..e5578ba98
--- /dev/null
+++ b/Tests/RunCMake/CMP0051/CMP0051-NEW-stderr.txt
@@ -0,0 +1 @@
+^Sources: "empty.cpp;\$<TARGET_OBJECTS:objects>"$
diff --git a/Tests/RunCMake/CMP0051/CMP0051-NEW.cmake b/Tests/RunCMake/CMP0051/CMP0051-NEW.cmake
new file mode 100644
index 000000000..f304bf186
--- /dev/null
+++ b/Tests/RunCMake/CMP0051/CMP0051-NEW.cmake
@@ -0,0 +1,10 @@
+
+cmake_policy(SET CMP0051 NEW)
+
+add_library(objects OBJECT empty.cpp)
+
+add_library(empty empty.cpp $<TARGET_OBJECTS:objects>)
+
+get_target_property(srcs empty SOURCES)
+
+message("Sources: \"${srcs}\"")
diff --git a/Tests/RunCMake/CMP0051/CMP0051-OLD-result.txt b/Tests/RunCMake/CMP0051/CMP0051-OLD-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0051/CMP0051-OLD-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0051/CMP0051-OLD-stderr.txt b/Tests/RunCMake/CMP0051/CMP0051-OLD-stderr.txt
new file mode 100644
index 000000000..cc17f3371
--- /dev/null
+++ b/Tests/RunCMake/CMP0051/CMP0051-OLD-stderr.txt
@@ -0,0 +1 @@
+^Sources: "empty.cpp"$
diff --git a/Tests/RunCMake/CMP0051/CMP0051-OLD.cmake b/Tests/RunCMake/CMP0051/CMP0051-OLD.cmake
new file mode 100644
index 000000000..0243e944c
--- /dev/null
+++ b/Tests/RunCMake/CMP0051/CMP0051-OLD.cmake
@@ -0,0 +1,10 @@
+
+cmake_policy(SET CMP0051 OLD)
+
+add_library(objects OBJECT empty.cpp)
+
+add_library(empty empty.cpp $<TARGET_OBJECTS:objects>)
+
+get_target_property(srcs empty SOURCES)
+
+message("Sources: \"${srcs}\"")
diff --git a/Tests/RunCMake/CMP0051/CMP0051-WARN-Dir/CMakeLists.txt b/Tests/RunCMake/CMP0051/CMP0051-WARN-Dir/CMakeLists.txt
new file mode 100644
index 000000000..77cbad53e
--- /dev/null
+++ b/Tests/RunCMake/CMP0051/CMP0051-WARN-Dir/CMakeLists.txt
@@ -0,0 +1 @@
+add_library(empty2 ../empty.cpp $<TARGET_OBJECTS:objects>)
diff --git a/Tests/RunCMake/CMP0051/CMP0051-WARN-result.txt b/Tests/RunCMake/CMP0051/CMP0051-WARN-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0051/CMP0051-WARN-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0051/CMP0051-WARN-stderr.txt b/Tests/RunCMake/CMP0051/CMP0051-WARN-stderr.txt
new file mode 100644
index 000000000..ae2e46848
--- /dev/null
+++ b/Tests/RunCMake/CMP0051/CMP0051-WARN-stderr.txt
@@ -0,0 +1,31 @@
+CMake Warning \(dev\) at CMP0051-WARN.cmake:6 \(get_target_property\):
+ Policy CMP0051 is not set: List TARGET_OBJECTS in SOURCES target property.
+ Run "cmake --help-policy CMP0051" for policy details. Use the cmake_policy
+ command to set the policy and suppress this warning.
+
+ Target "empty" contains \$<TARGET_OBJECTS> generator expression in its
+ sources list. This content was not previously part of the SOURCES property
+ when that property was read at configure time. Code reading that property
+ needs to be adapted to ignore the generator expression using the
+ string\(GENEX_STRIP\) command.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+Sources: "empty.cpp"
+*
+CMake Warning \(dev\) at CMP0051-WARN.cmake:12 \(get_target_property\):
+ Policy CMP0051 is not set: List TARGET_OBJECTS in SOURCES target property.
+ Run "cmake --help-policy CMP0051" for policy details. Use the cmake_policy
+ command to set the policy and suppress this warning.
+
+ Target "empty2" contains \$<TARGET_OBJECTS> generator expression in its
+ sources list. This content was not previously part of the SOURCES property
+ when that property was read at configure time. Code reading that property
+ needs to be adapted to ignore the generator expression using the
+ string\(GENEX_STRIP\) command.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+Sources: "../empty.cpp"$
diff --git a/Tests/RunCMake/CMP0051/CMP0051-WARN.cmake b/Tests/RunCMake/CMP0051/CMP0051-WARN.cmake
new file mode 100644
index 000000000..744598fcb
--- /dev/null
+++ b/Tests/RunCMake/CMP0051/CMP0051-WARN.cmake
@@ -0,0 +1,14 @@
+
+add_library(objects OBJECT empty.cpp)
+
+add_library(empty empty.cpp $<TARGET_OBJECTS:objects>)
+
+get_target_property(srcs empty SOURCES)
+
+message("Sources: \"${srcs}\"")
+
+add_subdirectory(CMP0051-WARN-Dir)
+
+get_target_property(srcs empty2 SOURCES)
+
+message("Sources: \"${srcs}\"")
diff --git a/Tests/RunCMake/CMP0051/CMakeLists.txt b/Tests/RunCMake/CMP0051/CMakeLists.txt
new file mode 100644
index 000000000..3482e6baf
--- /dev/null
+++ b/Tests/RunCMake/CMP0051/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.0)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0051/RunCMakeTest.cmake b/Tests/RunCMake/CMP0051/RunCMakeTest.cmake
new file mode 100644
index 000000000..621192d9f
--- /dev/null
+++ b/Tests/RunCMake/CMP0051/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0051-OLD)
+run_cmake(CMP0051-NEW)
+run_cmake(CMP0051-WARN)
diff --git a/Tests/RunCMake/CMP0051/empty.cpp b/Tests/RunCMake/CMP0051/empty.cpp
new file mode 100644
index 000000000..bfbbddeb9
--- /dev/null
+++ b/Tests/RunCMake/CMP0051/empty.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CMP0053/CMP0053-NEW-stderr.txt b/Tests/RunCMake/CMP0053/CMP0053-NEW-stderr.txt
new file mode 100644
index 000000000..836b0ffe9
--- /dev/null
+++ b/Tests/RunCMake/CMP0053/CMP0053-NEW-stderr.txt
@@ -0,0 +1,2 @@
+^called
+--><--$
diff --git a/Tests/RunCMake/CMP0053/CMP0053-NEW.cmake b/Tests/RunCMake/CMP0053/CMP0053-NEW.cmake
new file mode 100644
index 000000000..6ffedc63b
--- /dev/null
+++ b/Tests/RunCMake/CMP0053/CMP0053-NEW.cmake
@@ -0,0 +1,8 @@
+cmake_policy(SET CMP0053 NEW)
+
+function (watch_callback)
+ message("called")
+endfunction ()
+
+variable_watch(test watch_callback)
+message("-->${test}<--")
diff --git a/Tests/RunCMake/CMP0053/CMP0053-OLD-stderr.txt b/Tests/RunCMake/CMP0053/CMP0053-OLD-stderr.txt
new file mode 100644
index 000000000..836b0ffe9
--- /dev/null
+++ b/Tests/RunCMake/CMP0053/CMP0053-OLD-stderr.txt
@@ -0,0 +1,2 @@
+^called
+--><--$
diff --git a/Tests/RunCMake/CMP0053/CMP0053-OLD.cmake b/Tests/RunCMake/CMP0053/CMP0053-OLD.cmake
new file mode 100644
index 000000000..41f534746
--- /dev/null
+++ b/Tests/RunCMake/CMP0053/CMP0053-OLD.cmake
@@ -0,0 +1,8 @@
+cmake_policy(SET CMP0053 OLD)
+
+function (watch_callback)
+ message("called")
+endfunction ()
+
+variable_watch(test watch_callback)
+message("-->${test}<--")
diff --git a/Tests/RunCMake/CMP0053/CMP0053-WARN-stderr.txt b/Tests/RunCMake/CMP0053/CMP0053-WARN-stderr.txt
new file mode 100644
index 000000000..836b0ffe9
--- /dev/null
+++ b/Tests/RunCMake/CMP0053/CMP0053-WARN-stderr.txt
@@ -0,0 +1,2 @@
+^called
+--><--$
diff --git a/Tests/RunCMake/CMP0053/CMP0053-WARN.cmake b/Tests/RunCMake/CMP0053/CMP0053-WARN.cmake
new file mode 100644
index 000000000..b010d1319
--- /dev/null
+++ b/Tests/RunCMake/CMP0053/CMP0053-WARN.cmake
@@ -0,0 +1,6 @@
+function (watch_callback)
+ message("called")
+endfunction ()
+
+variable_watch(test watch_callback)
+message("-->${test}<--")
diff --git a/Tests/RunCMake/CMP0053/CMakeLists.txt b/Tests/RunCMake/CMP0053/CMakeLists.txt
new file mode 100644
index 000000000..3482e6baf
--- /dev/null
+++ b/Tests/RunCMake/CMP0053/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.0)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0053/RunCMakeTest.cmake b/Tests/RunCMake/CMP0053/RunCMakeTest.cmake
new file mode 100644
index 000000000..6521ac074
--- /dev/null
+++ b/Tests/RunCMake/CMP0053/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0053-OLD)
+run_cmake(CMP0053-NEW)
+run_cmake(CMP0053-WARN)
diff --git a/Tests/RunCMake/CMP0054/CMP0054-NEW-stderr.txt b/Tests/RunCMake/CMP0054/CMP0054-NEW-stderr.txt
new file mode 100644
index 000000000..f5a8fbe6e
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-NEW-stderr.txt
@@ -0,0 +1 @@
+$^
diff --git a/Tests/RunCMake/CMP0054/CMP0054-NEW.cmake b/Tests/RunCMake/CMP0054/CMP0054-NEW.cmake
new file mode 100644
index 000000000..23a912476
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-NEW.cmake
@@ -0,0 +1,47 @@
+cmake_policy(SET CMP0054 NEW)
+
+set(FOO "BAR")
+set(BAZ "ZZZ")
+set(MYTRUE ON)
+set(MYNUMBER 3)
+set(MYVERSION 3.0)
+
+function(assert_unquoted PREFIX FIRST)
+ string(REPLACE ";" " " ARGN_SP "${ARGN}")
+ if(${PREFIX} ${FIRST} ${ARGN})
+ message(FATAL_ERROR "Assertion failed [${PREFIX} ${FIRST} ${ARGN_SP}]")
+ endif()
+endfunction()
+
+function(assert_quoted PREFIX FIRST)
+ string(REPLACE ";" " " ARGN_SP "${ARGN}")
+ if(${PREFIX} "${FIRST}" ${ARGN})
+ message(FATAL_ERROR "Assertion failed [${PREFIX} \"${FIRST}\" ${ARGN_SP}]")
+ endif()
+endfunction()
+
+function(assert FIRST)
+ assert_unquoted(NOT ${FIRST} ${ARGN})
+ assert_quoted("" ${FIRST} ${ARGN})
+endfunction()
+
+assert(MYTRUE)
+
+assert(FOO MATCHES "^BAR$")
+
+assert(MYNUMBER LESS 4)
+assert(MYNUMBER GREATER 2)
+assert(MYNUMBER EQUAL 3)
+
+assert(FOO STRLESS CCC)
+assert(BAZ STRGREATER CCC)
+assert(FOO STREQUAL BAR)
+
+assert_unquoted(NOT MYVERSION VERSION_LESS 3.1)
+assert_unquoted("" MYVERSION VERSION_LESS 2.9)
+
+assert_quoted(NOT MYVERSION VERSION_LESS 2.9)
+assert_quoted(NOT MYVERSION VERSION_LESS 3.1)
+
+assert(MYVERSION VERSION_GREATER 2.9)
+assert(MYVERSION VERSION_EQUAL 3.0)
diff --git a/Tests/RunCMake/CMP0054/CMP0054-OLD-stderr.txt b/Tests/RunCMake/CMP0054/CMP0054-OLD-stderr.txt
new file mode 100644
index 000000000..f5a8fbe6e
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-OLD-stderr.txt
@@ -0,0 +1 @@
+$^
diff --git a/Tests/RunCMake/CMP0054/CMP0054-OLD.cmake b/Tests/RunCMake/CMP0054/CMP0054-OLD.cmake
new file mode 100644
index 000000000..0c4cede6b
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-OLD.cmake
@@ -0,0 +1,47 @@
+cmake_policy(SET CMP0054 OLD)
+
+set(FOO "BAR")
+set(BAZ "ZZZ")
+set(MYTRUE ON)
+set(MYNUMBER 3)
+set(MYVERSION 3.0)
+
+function(assert_unquoted PREFIX FIRST)
+ string(REPLACE ";" " " ARGN_SP "${ARGN}")
+ if(${PREFIX} ${FIRST} ${ARGN})
+ message(FATAL_ERROR "Assertion failed [${PREFIX} ${FIRST} ${ARGN_SP}]")
+ endif()
+endfunction()
+
+function(assert_quoted PREFIX FIRST)
+ string(REPLACE ";" " " ARGN_SP "${ARGN}")
+ if(${PREFIX} "${FIRST}" ${ARGN})
+ message(FATAL_ERROR "Assertion failed [${PREFIX} \"${FIRST}\" ${ARGN_SP}]")
+ endif()
+endfunction()
+
+function(assert FIRST)
+ assert_unquoted(NOT ${FIRST} ${ARGN})
+ assert_quoted(NOT ${FIRST} ${ARGN})
+endfunction()
+
+assert(MYTRUE)
+
+assert(FOO MATCHES "^BAR$")
+
+assert(MYNUMBER LESS 4)
+assert(MYNUMBER GREATER 2)
+assert(MYNUMBER EQUAL 3)
+
+assert(FOO STRLESS CCC)
+assert(BAZ STRGREATER CCC)
+assert(FOO STREQUAL BAR)
+
+assert_unquoted(NOT MYVERSION VERSION_LESS 3.1)
+assert_unquoted("" MYVERSION VERSION_LESS 2.9)
+
+assert_quoted("" MYVERSION VERSION_LESS 2.9)
+assert_quoted(NOT MYVERSION VERSION_LESS 3.1)
+
+assert(MYVERSION VERSION_GREATER 2.9)
+assert(MYVERSION VERSION_EQUAL 3.0)
diff --git a/Tests/RunCMake/CMP0054/CMP0054-WARN-stderr.txt b/Tests/RunCMake/CMP0054/CMP0054-WARN-stderr.txt
new file mode 100644
index 000000000..3cfa5d2e6
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-WARN-stderr.txt
@@ -0,0 +1,23 @@
+CMake Warning \(dev\) at CMP0054-WARN.cmake:3 \(if\):
+ Policy CMP0054 is not set: Only interpret if\(\) arguments as variables or
+ keywords when unquoted. Run "cmake --help-policy CMP0054" for policy
+ details. Use the cmake_policy command to set the policy and suppress this
+ warning.
+
+ Quoted variables like "FOO" will no longer be dereferenced when the policy
+ is set to NEW. Since the policy is not set the OLD behavior will be used.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
++
+CMake Warning \(dev\) at CMP0054-WARN.cmake:5 \(elseif\):
+ Policy CMP0054 is not set: Only interpret if\(\) arguments as variables or
+ keywords when unquoted. Run "cmake --help-policy CMP0054" for policy
+ details. Use the cmake_policy command to set the policy and suppress this
+ warning.
+
+ Quoted variables like "FOO" will no longer be dereferenced when the policy
+ is set to NEW. Since the policy is not set the OLD behavior will be used.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0054/CMP0054-WARN.cmake b/Tests/RunCMake/CMP0054/CMP0054-WARN.cmake
new file mode 100644
index 000000000..a6089293b
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-WARN.cmake
@@ -0,0 +1,7 @@
+set(FOO "BAR")
+
+if(NOT "FOO" STREQUAL "BAR")
+ message(FATAL_ERROR "The given literals should match")
+elseif("FOO" STREQUAL "BING")
+ message(FATAL_ERROR "The given literals should not match")
+endif()
diff --git a/Tests/RunCMake/CMP0054/CMP0054-duplicate-warnings-stderr.txt b/Tests/RunCMake/CMP0054/CMP0054-duplicate-warnings-stderr.txt
new file mode 100644
index 000000000..485db527d
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-duplicate-warnings-stderr.txt
@@ -0,0 +1,24 @@
+CMake Warning \(dev\) at CMP0054-duplicate-warnings.cmake:4 \(if\):
+ Policy CMP0054 is not set: Only interpret if\(\) arguments as variables or
+ keywords when unquoted. Run "cmake --help-policy CMP0054" for policy
+ details. Use the cmake_policy command to set the policy and suppress this
+ warning.
+
+ Quoted variables like "FOO" will no longer be dereferenced when the policy
+ is set to NEW. Since the policy is not set the OLD behavior will be used.
+Call Stack \(most recent call first\):
+ CMP0054-duplicate-warnings.cmake:8 \(generate_warning\)
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at CMP0054-duplicate-warnings.cmake:11 \(if\):
+ Policy CMP0054 is not set: Only interpret if\(\) arguments as variables or
+ keywords when unquoted. Run "cmake --help-policy CMP0054" for policy
+ details. Use the cmake_policy command to set the policy and suppress this
+ warning.
+
+ Quoted variables like "FOO" will no longer be dereferenced when the policy
+ is set to NEW. Since the policy is not set the OLD behavior will be used.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0054/CMP0054-duplicate-warnings.cmake b/Tests/RunCMake/CMP0054/CMP0054-duplicate-warnings.cmake
new file mode 100644
index 000000000..04fbe14e6
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-duplicate-warnings.cmake
@@ -0,0 +1,12 @@
+set(FOO "BAR")
+
+function(generate_warning)
+ if("FOO" STREQUAL "BAR")
+ endif()
+endfunction()
+
+generate_warning()
+generate_warning()
+
+if("FOO" STREQUAL "BAR")
+endif()
diff --git a/Tests/RunCMake/CMP0054/CMP0054-keywords-NEW-result.txt b/Tests/RunCMake/CMP0054/CMP0054-keywords-NEW-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-keywords-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0054/CMP0054-keywords-NEW-stderr.txt b/Tests/RunCMake/CMP0054/CMP0054-keywords-NEW-stderr.txt
new file mode 100644
index 000000000..f44468449
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-keywords-NEW-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at CMP0054-keywords-NEW.cmake:23 \(if\):
+ if given arguments:
+
+ "NOT" "1"
+
+ Unknown arguments specified
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CMP0054/CMP0054-keywords-NEW.cmake b/Tests/RunCMake/CMP0054/CMP0054-keywords-NEW.cmake
new file mode 100644
index 000000000..b957658b0
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-keywords-NEW.cmake
@@ -0,0 +1,25 @@
+cmake_policy(SET CMP0054 NEW)
+
+function(assert KEYWORD)
+ if("${KEYWORD}" STREQUAL "${KEYWORD}")
+ else()
+ message(FATAL_ERROR
+ "Assertion failed [\"${KEYWORD}\" STREQUAL \"${KEYWORD}\"]")
+ endif()
+endfunction()
+
+assert("NOT")
+assert("COMMAND")
+assert("POLICY")
+assert("TARGET")
+assert("EXISTS")
+assert("IS_DIRECTORY")
+assert("IS_SYMLINK")
+assert("IS_ABSOLUTE")
+assert("DEFINED")
+assert("(")
+assert(")")
+
+if("NOT" 1)
+ message(FATAL_ERROR "[\"NOT\" 1] evaluated true")
+endif()
diff --git a/Tests/RunCMake/CMP0054/CMP0054-keywords-OLD-stderr.txt b/Tests/RunCMake/CMP0054/CMP0054-keywords-OLD-stderr.txt
new file mode 100644
index 000000000..f5a8fbe6e
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-keywords-OLD-stderr.txt
@@ -0,0 +1 @@
+$^
diff --git a/Tests/RunCMake/CMP0054/CMP0054-keywords-OLD.cmake b/Tests/RunCMake/CMP0054/CMP0054-keywords-OLD.cmake
new file mode 100644
index 000000000..a2a7f5183
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-keywords-OLD.cmake
@@ -0,0 +1,9 @@
+cmake_policy(SET CMP0054 OLD)
+
+if(NOT 1)
+ message(FATAL_ERROR "[NOT 1] evaluated true")
+endif()
+
+if("NOT" 1)
+ message(FATAL_ERROR "[\"NOT\" 1] evaluated true")
+endif()
diff --git a/Tests/RunCMake/CMP0054/CMP0054-keywords-WARN-stderr.txt b/Tests/RunCMake/CMP0054/CMP0054-keywords-WARN-stderr.txt
new file mode 100644
index 000000000..5a8c263d7
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-keywords-WARN-stderr.txt
@@ -0,0 +1,25 @@
+CMake Warning \(dev\) at CMP0054-keywords-WARN.cmake:1 \(if\):
+ Policy CMP0054 is not set: Only interpret if\(\) arguments as variables or
+ keywords when unquoted. Run "cmake --help-policy CMP0054" for policy
+ details. Use the cmake_policy command to set the policy and suppress this
+ warning.
+
+ Quoted keywords like "NOT" will no longer be interpreted as keywords when
+ the policy is set to NEW. Since the policy is not set the OLD behavior
+ will be used.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
++
+CMake Warning \(dev\) at CMP0054-keywords-WARN.cmake:3 \(elseif\):
+ Policy CMP0054 is not set: Only interpret if\(\) arguments as variables or
+ keywords when unquoted. Run "cmake --help-policy CMP0054" for policy
+ details. Use the cmake_policy command to set the policy and suppress this
+ warning.
+
+ Quoted keywords like "DEFINED" will no longer be interpreted as keywords
+ when the policy is set to NEW. Since the policy is not set the OLD
+ behavior will be used.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0054/CMP0054-keywords-WARN.cmake b/Tests/RunCMake/CMP0054/CMP0054-keywords-WARN.cmake
new file mode 100644
index 000000000..118ab3d18
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-keywords-WARN.cmake
@@ -0,0 +1,5 @@
+if("NOT" 1)
+ message(FATAL_ERROR "[\"NOT\" 1] evaluated true")
+elseif("DEFINED" NotDefined)
+ message(FATAL_ERROR "[\"DEFINED\" NotDefined] evaluated true")
+endif()
diff --git a/Tests/RunCMake/CMP0054/CMP0054-policy-command-scope-stderr.txt b/Tests/RunCMake/CMP0054/CMP0054-policy-command-scope-stderr.txt
new file mode 100644
index 000000000..f5a8fbe6e
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-policy-command-scope-stderr.txt
@@ -0,0 +1 @@
+$^
diff --git a/Tests/RunCMake/CMP0054/CMP0054-policy-command-scope.cmake b/Tests/RunCMake/CMP0054/CMP0054-policy-command-scope.cmake
new file mode 100644
index 000000000..b6b243caa
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-policy-command-scope.cmake
@@ -0,0 +1,53 @@
+set(FOO BAR)
+
+cmake_policy(SET CMP0054 NEW)
+
+function(function_defined_new_called_old)
+ if(NOT FOO STREQUAL BAR)
+ message(FATAL_ERROR "The variable should match the string")
+ endif()
+
+ if("FOO" STREQUAL BAR)
+ message(FATAL_ERROR "The strings should not match")
+ endif()
+endfunction()
+
+macro(macro_defined_new_called_old)
+ if(NOT FOO STREQUAL BAR)
+ message(FATAL_ERROR "The variable should match the string")
+ endif()
+
+ if("FOO" STREQUAL BAR)
+ message(FATAL_ERROR "The strings should not match")
+ endif()
+endmacro()
+
+cmake_policy(SET CMP0054 OLD)
+
+function_defined_new_called_old()
+macro_defined_new_called_old()
+
+function(function_defined_old_called_new)
+ if(NOT FOO STREQUAL BAR)
+ message(FATAL_ERROR "The variable should match the string")
+ endif()
+
+ if(NOT "FOO" STREQUAL BAR)
+ message(FATAL_ERROR "The quoted variable should match the string")
+ endif()
+endfunction()
+
+macro(macro_defined_old_called_new)
+ if(NOT FOO STREQUAL BAR)
+ message(FATAL_ERROR "The variable should match the string")
+ endif()
+
+ if(NOT "FOO" STREQUAL BAR)
+ message(FATAL_ERROR "The quoted variable should match the string")
+ endif()
+endmacro()
+
+cmake_policy(SET CMP0054 NEW)
+
+function_defined_old_called_new()
+macro_defined_old_called_new()
diff --git a/Tests/RunCMake/CMP0054/CMP0054-policy-foreach-scope-stderr.txt b/Tests/RunCMake/CMP0054/CMP0054-policy-foreach-scope-stderr.txt
new file mode 100644
index 000000000..f5a8fbe6e
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-policy-foreach-scope-stderr.txt
@@ -0,0 +1 @@
+$^
diff --git a/Tests/RunCMake/CMP0054/CMP0054-policy-foreach-scope.cmake b/Tests/RunCMake/CMP0054/CMP0054-policy-foreach-scope.cmake
new file mode 100644
index 000000000..87c968a06
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-policy-foreach-scope.cmake
@@ -0,0 +1,49 @@
+set(FOO BAR)
+
+cmake_policy(SET CMP0054 NEW)
+
+foreach(loop_var arg1 arg2)
+ if(NOT FOO STREQUAL BAR)
+ message(FATAL_ERROR "The variable should match the string")
+ endif()
+
+ if("FOO" STREQUAL BAR)
+ message(FATAL_ERROR "The strings should not match")
+ endif()
+
+ cmake_policy(SET CMP0054 OLD)
+
+ if(NOT FOO STREQUAL BAR)
+ message(FATAL_ERROR "The variable should match the string")
+ endif()
+
+ if(NOT "FOO" STREQUAL BAR)
+ message(FATAL_ERROR "The quoted variable should match the string")
+ endif()
+
+ cmake_policy(SET CMP0054 NEW)
+endforeach()
+
+cmake_policy(SET CMP0054 OLD)
+
+foreach(loop_var arg1 arg2)
+ if(NOT FOO STREQUAL BAR)
+ message(FATAL_ERROR "The variable should match the string")
+ endif()
+
+ if(NOT "FOO" STREQUAL BAR)
+ message(FATAL_ERROR "The quoted variable should match the string")
+ endif()
+
+ cmake_policy(SET CMP0054 NEW)
+
+ if(NOT FOO STREQUAL BAR)
+ message(FATAL_ERROR "The variable should match the string")
+ endif()
+
+ if("FOO" STREQUAL BAR)
+ message(FATAL_ERROR "The strings should not match")
+ endif()
+
+ cmake_policy(SET CMP0054 OLD)
+endforeach()
diff --git a/Tests/RunCMake/CMP0054/CMP0054-policy-nested-if-stderr.txt b/Tests/RunCMake/CMP0054/CMP0054-policy-nested-if-stderr.txt
new file mode 100644
index 000000000..f5a8fbe6e
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-policy-nested-if-stderr.txt
@@ -0,0 +1 @@
+$^
diff --git a/Tests/RunCMake/CMP0054/CMP0054-policy-nested-if.cmake b/Tests/RunCMake/CMP0054/CMP0054-policy-nested-if.cmake
new file mode 100644
index 000000000..dd7434d73
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-policy-nested-if.cmake
@@ -0,0 +1,41 @@
+set(FOO BAR)
+
+cmake_policy(SET CMP0054 NEW)
+
+if("FOO" STREQUAL BAR)
+ message(FATAL_ERROR "The strings should not match")
+
+ if("FOO" STREQUAL BAR)
+ message(FATAL_ERROR "The strings should not match")
+ endif()
+
+ cmake_policy(SET CMP0054 OLD)
+
+ if(NOT "FOO" STREQUAL BAR)
+ message(FATAL_ERROR "The quoted variable should match the string")
+ endif()
+endif()
+
+if("FOO" STREQUAL BAR)
+ message(FATAL_ERROR "The strings should not match")
+endif()
+
+cmake_policy(SET CMP0054 OLD)
+
+if(NOT "FOO" STREQUAL BAR)
+ message(FATAL_ERROR "The quoted variable should match the string")
+
+ if(NOT "FOO" STREQUAL BAR)
+ message(FATAL_ERROR "The quoted variable should match the string")
+ endif()
+
+ cmake_policy(SET CMP0054 NEW)
+
+ if("FOO" STREQUAL BAR)
+ message(FATAL_ERROR "The strings should not match")
+ endif()
+endif()
+
+if(NOT "FOO" STREQUAL BAR)
+ message(FATAL_ERROR "The quoted variable should match the string")
+endif()
diff --git a/Tests/RunCMake/CMP0054/CMP0054-policy-while-scope-stderr.txt b/Tests/RunCMake/CMP0054/CMP0054-policy-while-scope-stderr.txt
new file mode 100644
index 000000000..f5a8fbe6e
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-policy-while-scope-stderr.txt
@@ -0,0 +1 @@
+$^
diff --git a/Tests/RunCMake/CMP0054/CMP0054-policy-while-scope.cmake b/Tests/RunCMake/CMP0054/CMP0054-policy-while-scope.cmake
new file mode 100644
index 000000000..2b22778b5
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMP0054-policy-while-scope.cmake
@@ -0,0 +1,65 @@
+set(FOO BAR)
+
+set(LOOP_VAR "")
+
+cmake_policy(SET CMP0054 NEW)
+
+while(NOT LOOP_VAR STREQUAL "xx")
+ if(NOT FOO STREQUAL BAR)
+ message(FATAL_ERROR "The variable should match the string")
+ endif()
+
+ if("FOO" STREQUAL BAR)
+ message(FATAL_ERROR "The strings should not match")
+ endif()
+
+ cmake_policy(SET CMP0054 OLD)
+
+ if(NOT FOO STREQUAL BAR)
+ message(FATAL_ERROR "The variable should match the string")
+ endif()
+
+ if(NOT "FOO" STREQUAL BAR)
+ message(FATAL_ERROR "The quoted variable should match the string")
+ endif()
+
+ cmake_policy(SET CMP0054 NEW)
+
+ set(LOOP_VAR "${LOOP_VAR}x")
+endwhile()
+
+while("FOO" STREQUAL BAR)
+ message(FATAL_ERROR "The strings should not match")
+endwhile()
+
+set(LOOP_VAR "")
+
+cmake_policy(SET CMP0054 OLD)
+
+while(NOT LOOP_VAR STREQUAL "xx")
+ if(NOT FOO STREQUAL BAR)
+ message(FATAL_ERROR "The variable should match the string")
+ endif()
+
+ if(NOT "FOO" STREQUAL BAR)
+ message(FATAL_ERROR "The quoted variable should match the string")
+ endif()
+
+ cmake_policy(SET CMP0054 NEW)
+
+ if(NOT FOO STREQUAL BAR)
+ message(FATAL_ERROR "The variable should match the string")
+ endif()
+
+ if("FOO" STREQUAL BAR)
+ message(FATAL_ERROR "The strings should not match")
+ endif()
+
+ cmake_policy(SET CMP0054 OLD)
+
+ set(LOOP_VAR "${LOOP_VAR}x")
+endwhile()
+
+if(NOT "FOO" STREQUAL BAR)
+ message(FATAL_ERROR "The quoted variable should match the string")
+endif()
diff --git a/Tests/RunCMake/CMP0054/CMakeLists.txt b/Tests/RunCMake/CMP0054/CMakeLists.txt
new file mode 100644
index 000000000..289710955
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.0)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0054/RunCMakeTest.cmake b/Tests/RunCMake/CMP0054/RunCMakeTest.cmake
new file mode 100644
index 000000000..2f2fb765d
--- /dev/null
+++ b/Tests/RunCMake/CMP0054/RunCMakeTest.cmake
@@ -0,0 +1,13 @@
+include(RunCMake)
+
+run_cmake(CMP0054-OLD)
+run_cmake(CMP0054-NEW)
+run_cmake(CMP0054-WARN)
+run_cmake(CMP0054-keywords-NEW)
+run_cmake(CMP0054-keywords-OLD)
+run_cmake(CMP0054-keywords-WARN)
+run_cmake(CMP0054-duplicate-warnings)
+run_cmake(CMP0054-policy-command-scope)
+run_cmake(CMP0054-policy-foreach-scope)
+run_cmake(CMP0054-policy-while-scope)
+run_cmake(CMP0054-policy-nested-if)
diff --git a/Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope-result.txt b/Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope-stderr.txt b/Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope-stderr.txt
new file mode 100644
index 000000000..27e81405d
--- /dev/null
+++ b/Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at CMP0055-NEW-Out-of-Scope.cmake:4 \(break\):
+ A BREAK command was found outside of a proper FOREACH or WHILE loop scope.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope.cmake b/Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope.cmake
new file mode 100644
index 000000000..53ac214ad
--- /dev/null
+++ b/Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope.cmake
@@ -0,0 +1,4 @@
+
+cmake_policy(SET CMP0055 NEW)
+
+break()
diff --git a/Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments-result.txt b/Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments-stderr.txt b/Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments-stderr.txt
new file mode 100644
index 000000000..32947af2a
--- /dev/null
+++ b/Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at CMP0055-NEW-Reject-Arguments.cmake:5 \(break\):
+ The BREAK command does not accept any arguments.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments.cmake b/Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments.cmake
new file mode 100644
index 000000000..52eaa6aa5
--- /dev/null
+++ b/Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments.cmake
@@ -0,0 +1,6 @@
+
+cmake_policy(SET CMP0055 NEW)
+
+foreach(i RANGE 1 2)
+ break(1)
+endforeach() \ No newline at end of file
diff --git a/Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope-result.txt b/Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope.cmake b/Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope.cmake
new file mode 100644
index 000000000..57195c248
--- /dev/null
+++ b/Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope.cmake
@@ -0,0 +1,4 @@
+
+cmake_policy(SET CMP0055 OLD)
+
+break()
diff --git a/Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments-result.txt b/Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments.cmake b/Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments.cmake
new file mode 100644
index 000000000..d8fdddf10
--- /dev/null
+++ b/Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments.cmake
@@ -0,0 +1,6 @@
+
+cmake_policy(SET CMP0055 OLD)
+
+foreach(i RANGE 1 2)
+ break(1)
+endforeach() \ No newline at end of file
diff --git a/Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope-result.txt b/Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope-stderr.txt b/Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope-stderr.txt
new file mode 100644
index 000000000..ad850ac93
--- /dev/null
+++ b/Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning \(dev\) at CMP0055-WARN-Out-of-Scope.cmake:2 \(break\):
+ Policy CMP0055 is not set: Strict checking for break\(\) command. Run "cmake
+ --help-policy CMP0055" for policy details. Use the cmake_policy command to
+ set the policy and suppress this warning.
+
+ A BREAK command was found outside of a proper FOREACH or WHILE loop scope.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope.cmake b/Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope.cmake
new file mode 100644
index 000000000..373a95a7c
--- /dev/null
+++ b/Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope.cmake
@@ -0,0 +1,2 @@
+
+break()
diff --git a/Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments-result.txt b/Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments-stderr.txt b/Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments-stderr.txt
new file mode 100644
index 000000000..3cc686dc0
--- /dev/null
+++ b/Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning \(dev\) at CMP0055-WARN-Reject-Arguments.cmake:3 \(break\):
+ Policy CMP0055 is not set: Strict checking for break\(\) command. Run "cmake
+ --help-policy CMP0055" for policy details. Use the cmake_policy command to
+ set the policy and suppress this warning.
+
+ The BREAK command does not accept any arguments.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments.cmake b/Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments.cmake
new file mode 100644
index 000000000..ec6b90f8a
--- /dev/null
+++ b/Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments.cmake
@@ -0,0 +1,4 @@
+
+foreach(i RANGE 1 2)
+ break(1)
+endforeach()
diff --git a/Tests/RunCMake/CMP0055/CMakeLists.txt b/Tests/RunCMake/CMP0055/CMakeLists.txt
new file mode 100644
index 000000000..ef2163c29
--- /dev/null
+++ b/Tests/RunCMake/CMP0055/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.1)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0055/RunCMakeTest.cmake b/Tests/RunCMake/CMP0055/RunCMakeTest.cmake
new file mode 100644
index 000000000..efcfcab67
--- /dev/null
+++ b/Tests/RunCMake/CMP0055/RunCMakeTest.cmake
@@ -0,0 +1,9 @@
+include(RunCMake)
+
+run_cmake(CMP0055-OLD-Out-of-Scope)
+run_cmake(CMP0055-NEW-Out-of-Scope)
+run_cmake(CMP0055-WARN-Out-of-Scope)
+
+run_cmake(CMP0055-OLD-Reject-Arguments)
+run_cmake(CMP0055-NEW-Reject-Arguments)
+run_cmake(CMP0055-WARN-Reject-Arguments)
diff --git a/Tests/RunCMake/CMP0057/CMP0057-NEW.cmake b/Tests/RunCMake/CMP0057/CMP0057-NEW.cmake
new file mode 100644
index 000000000..ebd7ba580
--- /dev/null
+++ b/Tests/RunCMake/CMP0057/CMP0057-NEW.cmake
@@ -0,0 +1,31 @@
+cmake_policy(SET CMP0057 NEW)
+
+set(MY_NON_EXISTENT_LIST)
+
+set(MY_EMPTY_LIST "")
+
+set(MY_LIST foo bar)
+
+if(NOT "foo" IN_LIST MY_LIST)
+ message(FATAL_ERROR "expected item 'foo' not found in list MY_LIST")
+endif()
+
+if("baz" IN_LIST MY_LIST)
+ message(FATAL_ERROR "unexpected item 'baz' found in list MY_LIST")
+endif()
+
+if("foo" IN_LIST MY_NON_EXISTENT_LIST)
+ message(FATAL_ERROR
+ "unexpected item 'baz' found in non existent list MY_NON_EXISTENT_LIST")
+endif()
+
+if("foo" IN_LIST MY_EMPTY_LIST)
+ message(FATAL_ERROR
+ "unexpected item 'baz' found in empty list MY_EMPTY_LIST")
+endif()
+
+set(VAR "foo")
+
+if(NOT VAR IN_LIST MY_LIST)
+ message(FATAL_ERROR "expected item VAR not found in list MY_LIST")
+endif()
diff --git a/Tests/RunCMake/CMP0057/CMP0057-OLD-result.txt b/Tests/RunCMake/CMP0057/CMP0057-OLD-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CMP0057/CMP0057-OLD-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0057/CMP0057-OLD-stderr.txt b/Tests/RunCMake/CMP0057/CMP0057-OLD-stderr.txt
new file mode 100644
index 000000000..f3fad8da9
--- /dev/null
+++ b/Tests/RunCMake/CMP0057/CMP0057-OLD-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at CMP0057-OLD.cmake:5 \(if\):
+ if given arguments:
+
+ "foo" "IN_LIST" "MY_LIST"
+
+ Unknown arguments specified
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CMP0057/CMP0057-OLD.cmake b/Tests/RunCMake/CMP0057/CMP0057-OLD.cmake
new file mode 100644
index 000000000..cf9ec890b
--- /dev/null
+++ b/Tests/RunCMake/CMP0057/CMP0057-OLD.cmake
@@ -0,0 +1,7 @@
+cmake_policy(SET CMP0057 OLD)
+
+set(MY_LIST foo bar)
+
+if("foo" IN_LIST MY_LIST)
+ message("foo is in MY_LIST")
+endif()
diff --git a/Tests/RunCMake/CMP0057/CMP0057-WARN-result.txt b/Tests/RunCMake/CMP0057/CMP0057-WARN-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CMP0057/CMP0057-WARN-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0057/CMP0057-WARN-stderr.txt b/Tests/RunCMake/CMP0057/CMP0057-WARN-stderr.txt
new file mode 100644
index 000000000..b1c9b63b4
--- /dev/null
+++ b/Tests/RunCMake/CMP0057/CMP0057-WARN-stderr.txt
@@ -0,0 +1,19 @@
+CMake Warning \(dev\) at CMP0057-WARN.cmake:3 \(if\):
+ Policy CMP0057 is not set: Support new IN_LIST if\(\) operator. Run "cmake
+ --help-policy CMP0057" for policy details. Use the cmake_policy command to
+ set the policy and suppress this warning.
+
+ IN_LIST will be interpreted as an operator when the policy is set to NEW.
+ Since the policy is not set the OLD behavior will be used.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Error at CMP0057-WARN.cmake:3 \(if\):
+ if given arguments:
+
+ "foo" "IN_LIST" "MY_LIST"
+
+ Unknown arguments specified
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CMP0057/CMP0057-WARN.cmake b/Tests/RunCMake/CMP0057/CMP0057-WARN.cmake
new file mode 100644
index 000000000..45f53a52c
--- /dev/null
+++ b/Tests/RunCMake/CMP0057/CMP0057-WARN.cmake
@@ -0,0 +1,5 @@
+set(MY_LIST foo bar)
+
+if("foo" IN_LIST MY_LIST)
+ message("foo is in MY_LIST")
+endif()
diff --git a/Tests/RunCMake/CMP0057/CMakeLists.txt b/Tests/RunCMake/CMP0057/CMakeLists.txt
new file mode 100644
index 000000000..18dfd2686
--- /dev/null
+++ b/Tests/RunCMake/CMP0057/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.2)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0057/RunCMakeTest.cmake b/Tests/RunCMake/CMP0057/RunCMakeTest.cmake
new file mode 100644
index 000000000..719e054a5
--- /dev/null
+++ b/Tests/RunCMake/CMP0057/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0057-OLD)
+run_cmake(CMP0057-WARN)
+run_cmake(CMP0057-NEW)
diff --git a/Tests/RunCMake/CMP0059/CMP0059-NEW-result.txt b/Tests/RunCMake/CMP0059/CMP0059-NEW-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0059/CMP0059-NEW-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0059/CMP0059-NEW-stderr.txt b/Tests/RunCMake/CMP0059/CMP0059-NEW-stderr.txt
new file mode 100644
index 000000000..76992d84b
--- /dev/null
+++ b/Tests/RunCMake/CMP0059/CMP0059-NEW-stderr.txt
@@ -0,0 +1,2 @@
+DEFS:
+CUSTOM CONTENT:CUSTOM_CONTENT
diff --git a/Tests/RunCMake/CMP0059/CMP0059-NEW.cmake b/Tests/RunCMake/CMP0059/CMP0059-NEW.cmake
new file mode 100644
index 000000000..f7b9303cd
--- /dev/null
+++ b/Tests/RunCMake/CMP0059/CMP0059-NEW.cmake
@@ -0,0 +1,17 @@
+
+cmake_policy(SET CMP0059 NEW)
+
+add_definitions(-DSOME_DEF)
+
+get_property(defs DIRECTORY .
+ PROPERTY DEFINITIONS
+)
+message("DEFS:${defs}")
+
+set_property(DIRECTORY .
+ PROPERTY DEFINITIONS CUSTOM_CONTENT
+)
+get_property(content DIRECTORY .
+ PROPERTY DEFINITIONS
+)
+message("CUSTOM CONTENT:${content}")
diff --git a/Tests/RunCMake/CMP0059/CMP0059-OLD-result.txt b/Tests/RunCMake/CMP0059/CMP0059-OLD-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0059/CMP0059-OLD-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0059/CMP0059-OLD-stderr.txt b/Tests/RunCMake/CMP0059/CMP0059-OLD-stderr.txt
new file mode 100644
index 000000000..e35e8c5f1
--- /dev/null
+++ b/Tests/RunCMake/CMP0059/CMP0059-OLD-stderr.txt
@@ -0,0 +1,2 @@
+DEFS: -DSOME_DEF
+CUSTOM CONTENT: -DSOME_DEF
diff --git a/Tests/RunCMake/CMP0059/CMP0059-OLD.cmake b/Tests/RunCMake/CMP0059/CMP0059-OLD.cmake
new file mode 100644
index 000000000..25557744d
--- /dev/null
+++ b/Tests/RunCMake/CMP0059/CMP0059-OLD.cmake
@@ -0,0 +1,17 @@
+
+cmake_policy(SET CMP0059 OLD)
+
+add_definitions(-DSOME_DEF)
+
+get_property(defs DIRECTORY .
+ PROPERTY DEFINITIONS
+)
+message("DEFS:${defs}")
+
+set_property(DIRECTORY .
+ PROPERTY DEFINITIONS CUSTOM_CONTENT
+)
+get_property(content DIRECTORY .
+ PROPERTY DEFINITIONS
+)
+message("CUSTOM CONTENT:${content}")
diff --git a/Tests/RunCMake/CMP0059/CMP0059-WARN-result.txt b/Tests/RunCMake/CMP0059/CMP0059-WARN-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CMP0059/CMP0059-WARN-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0059/CMP0059-WARN-stderr.txt b/Tests/RunCMake/CMP0059/CMP0059-WARN-stderr.txt
new file mode 100644
index 000000000..4e04d15d6
--- /dev/null
+++ b/Tests/RunCMake/CMP0059/CMP0059-WARN-stderr.txt
@@ -0,0 +1,18 @@
+CMake Warning \(dev\) at CMP0059-WARN.cmake:6 \(get_property\):
+ Policy CMP0059 is not set: Do no treat DEFINITIONS as a built-in directory
+ property. Run "cmake --help-policy CMP0059" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+DEFS: -DSOME_DEF
+CMake Warning \(dev\) at CMP0059-WARN.cmake:14 \(get_property\):
+ Policy CMP0059 is not set: Do no treat DEFINITIONS as a built-in directory
+ property. Run "cmake --help-policy CMP0059" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CUSTOM CONTENT: -DSOME_DEF
diff --git a/Tests/RunCMake/CMP0059/CMP0059-WARN.cmake b/Tests/RunCMake/CMP0059/CMP0059-WARN.cmake
new file mode 100644
index 000000000..9d0b49c8e
--- /dev/null
+++ b/Tests/RunCMake/CMP0059/CMP0059-WARN.cmake
@@ -0,0 +1,17 @@
+
+
+
+add_definitions(-DSOME_DEF)
+
+get_property(defs DIRECTORY .
+ PROPERTY DEFINITIONS
+)
+message("DEFS:${defs}")
+
+set_property(DIRECTORY .
+ PROPERTY DEFINITIONS CUSTOM_CONTENT
+)
+get_property(content DIRECTORY .
+ PROPERTY DEFINITIONS
+)
+message("CUSTOM CONTENT:${content}")
diff --git a/Tests/RunCMake/CMP0059/CMakeLists.txt b/Tests/RunCMake/CMP0059/CMakeLists.txt
new file mode 100644
index 000000000..ef2163c29
--- /dev/null
+++ b/Tests/RunCMake/CMP0059/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.1)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0059/RunCMakeTest.cmake b/Tests/RunCMake/CMP0059/RunCMakeTest.cmake
new file mode 100644
index 000000000..9b5757954
--- /dev/null
+++ b/Tests/RunCMake/CMP0059/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0059-OLD)
+run_cmake(CMP0059-NEW)
+run_cmake(CMP0059-WARN)
diff --git a/Tests/RunCMake/CMP0060/CMP0060-Common.cmake b/Tests/RunCMake/CMP0060/CMP0060-Common.cmake
new file mode 100644
index 000000000..e0a56e68c
--- /dev/null
+++ b/Tests/RunCMake/CMP0060/CMP0060-Common.cmake
@@ -0,0 +1,35 @@
+# Always build in a predictable configuration. For multi-config
+# generators we depend on RunCMakeTest.cmake to do this for us.
+if(NOT CMAKE_CONFIGURATION_TYPES)
+ set(CMAKE_BUILD_TYPE Debug)
+endif()
+
+# Convince CMake that it can instruct the linker to search for the
+# library of the proper linkage type, but do not really pass flags.
+set(CMAKE_EXE_LINK_STATIC_C_FLAGS " ")
+set(CMAKE_EXE_LINK_DYNAMIC_C_FLAGS " ")
+
+# Make a link line asking for the linker to search for the library
+# look like a missing object file so we will get predictable content
+# in the error message. This also ensures that cases expected to use
+# the full path can be verified by confirming that they link.
+set(CMAKE_LINK_LIBRARY_FLAG LINKFLAG_)
+set(CMAKE_LINK_LIBRARY_SUFFIX _LINKSUFFIX${CMAKE_C_OUTPUT_EXTENSION})
+
+# Convince CMake that our library is in an implicit linker search directory.
+list(APPEND CMAKE_C_IMPLICIT_LINK_DIRECTORIES ${CMAKE_CURRENT_BINARY_DIR}/lib)
+
+# Create a simple library file. Place it in our library directory.
+add_library(CMP0060 STATIC cmp0060.c)
+set_property(TARGET CMP0060 PROPERTY
+ ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_BINARY_DIR}/lib)
+
+# Add a target to link the library file by full path.
+add_executable(main1 main.c)
+target_link_libraries(main1 $<TARGET_FILE:CMP0060>)
+add_dependencies(main1 CMP0060)
+
+# Add a second target to verify the warning only appears once.
+add_executable(main2 main.c)
+target_link_libraries(main2 $<TARGET_FILE:CMP0060>)
+add_dependencies(main2 CMP0060)
diff --git a/Tests/RunCMake/CMP0060/CMP0060-NEW.cmake b/Tests/RunCMake/CMP0060/CMP0060-NEW.cmake
new file mode 100644
index 000000000..0414e4b4b
--- /dev/null
+++ b/Tests/RunCMake/CMP0060/CMP0060-NEW.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0060 NEW)
+include(CMP0060-Common.cmake)
diff --git a/Tests/RunCMake/CMP0060/CMP0060-OLD-Build-result.txt b/Tests/RunCMake/CMP0060/CMP0060-OLD-Build-result.txt
new file mode 100644
index 000000000..d197c913c
--- /dev/null
+++ b/Tests/RunCMake/CMP0060/CMP0060-OLD-Build-result.txt
@@ -0,0 +1 @@
+[^0]
diff --git a/Tests/RunCMake/CMP0060/CMP0060-OLD-Build-stdout.txt b/Tests/RunCMake/CMP0060/CMP0060-OLD-Build-stdout.txt
new file mode 100644
index 000000000..240764c10
--- /dev/null
+++ b/Tests/RunCMake/CMP0060/CMP0060-OLD-Build-stdout.txt
@@ -0,0 +1 @@
+LINKFLAG_CMP0060_LINKSUFFIX
diff --git a/Tests/RunCMake/CMP0060/CMP0060-OLD.cmake b/Tests/RunCMake/CMP0060/CMP0060-OLD.cmake
new file mode 100644
index 000000000..a9cffefbd
--- /dev/null
+++ b/Tests/RunCMake/CMP0060/CMP0060-OLD.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0060 OLD)
+include(CMP0060-Common.cmake)
diff --git a/Tests/RunCMake/CMP0060/CMP0060-WARN-OFF-Build-result.txt b/Tests/RunCMake/CMP0060/CMP0060-WARN-OFF-Build-result.txt
new file mode 100644
index 000000000..d197c913c
--- /dev/null
+++ b/Tests/RunCMake/CMP0060/CMP0060-WARN-OFF-Build-result.txt
@@ -0,0 +1 @@
+[^0]
diff --git a/Tests/RunCMake/CMP0060/CMP0060-WARN-OFF-Build-stdout.txt b/Tests/RunCMake/CMP0060/CMP0060-WARN-OFF-Build-stdout.txt
new file mode 100644
index 000000000..240764c10
--- /dev/null
+++ b/Tests/RunCMake/CMP0060/CMP0060-WARN-OFF-Build-stdout.txt
@@ -0,0 +1 @@
+LINKFLAG_CMP0060_LINKSUFFIX
diff --git a/Tests/RunCMake/CMP0060/CMP0060-WARN-OFF.cmake b/Tests/RunCMake/CMP0060/CMP0060-WARN-OFF.cmake
new file mode 100644
index 000000000..6b84565a2
--- /dev/null
+++ b/Tests/RunCMake/CMP0060/CMP0060-WARN-OFF.cmake
@@ -0,0 +1 @@
+include(CMP0060-Common.cmake)
diff --git a/Tests/RunCMake/CMP0060/CMP0060-WARN-ON-Build-result.txt b/Tests/RunCMake/CMP0060/CMP0060-WARN-ON-Build-result.txt
new file mode 100644
index 000000000..d197c913c
--- /dev/null
+++ b/Tests/RunCMake/CMP0060/CMP0060-WARN-ON-Build-result.txt
@@ -0,0 +1 @@
+[^0]
diff --git a/Tests/RunCMake/CMP0060/CMP0060-WARN-ON-Build-stdout.txt b/Tests/RunCMake/CMP0060/CMP0060-WARN-ON-Build-stdout.txt
new file mode 100644
index 000000000..240764c10
--- /dev/null
+++ b/Tests/RunCMake/CMP0060/CMP0060-WARN-ON-Build-stdout.txt
@@ -0,0 +1 @@
+LINKFLAG_CMP0060_LINKSUFFIX
diff --git a/Tests/RunCMake/CMP0060/CMP0060-WARN-ON-stderr.txt b/Tests/RunCMake/CMP0060/CMP0060-WARN-ON-stderr.txt
new file mode 100644
index 000000000..f6cc97854
--- /dev/null
+++ b/Tests/RunCMake/CMP0060/CMP0060-WARN-ON-stderr.txt
@@ -0,0 +1,16 @@
+^CMake Warning \(dev\) at CMP0060-Common.cmake:[0-9]+ \(add_executable\):
+ Policy CMP0060 is not set: Link libraries by full path even in implicit
+ directories. Run "cmake --help-policy CMP0060" for policy details. Use
+ the cmake_policy command to set the policy and suppress this warning.
+
+ Some library files are in directories implicitly searched by the linker
+ when invoked for C:
+
+ .*/Tests/RunCMake/CMP0060/CMP0060-WARN-ON-build/lib/(lib)?CMP0060.(a|lib)
+
+ For compatibility with older versions of CMake, the generated link line
+ will ask the linker to search for these by library name.
+Call Stack \(most recent call first\):
+ CMP0060-WARN-ON.cmake:[0-9]+ \(include\)
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/CMP0060/CMP0060-WARN-ON.cmake b/Tests/RunCMake/CMP0060/CMP0060-WARN-ON.cmake
new file mode 100644
index 000000000..a0a7950ef
--- /dev/null
+++ b/Tests/RunCMake/CMP0060/CMP0060-WARN-ON.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_POLICY_WARNING_CMP0060 1)
+include(CMP0060-Common.cmake)
diff --git a/Tests/RunCMake/CMP0060/CMakeLists.txt b/Tests/RunCMake/CMP0060/CMakeLists.txt
new file mode 100644
index 000000000..db6b701c0
--- /dev/null
+++ b/Tests/RunCMake/CMP0060/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.2)
+project(${RunCMake_TEST} C)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0060/RunCMakeTest.cmake b/Tests/RunCMake/CMP0060/RunCMakeTest.cmake
new file mode 100644
index 000000000..445156fa1
--- /dev/null
+++ b/Tests/RunCMake/CMP0060/RunCMakeTest.cmake
@@ -0,0 +1,19 @@
+include(RunCMake)
+
+function(run_cmake_CMP0060 CASE)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CMP0060-${CASE}-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+ run_cmake(CMP0060-${CASE})
+ set(RunCMake_TEST_OUTPUT_MERGE 1)
+ run_cmake_command(CMP0060-${CASE}-Build
+ ${CMAKE_COMMAND} --build . --config Debug
+ )
+endfunction()
+
+run_cmake_CMP0060(OLD)
+run_cmake_CMP0060(WARN-OFF)
+run_cmake_CMP0060(WARN-ON)
+run_cmake_CMP0060(NEW)
diff --git a/Tests/RunCMake/CMP0060/cmp0060.c b/Tests/RunCMake/CMP0060/cmp0060.c
new file mode 100644
index 000000000..a2da227b1
--- /dev/null
+++ b/Tests/RunCMake/CMP0060/cmp0060.c
@@ -0,0 +1,4 @@
+int libCMP0060(void)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CMP0060/main.c b/Tests/RunCMake/CMP0060/main.c
new file mode 100644
index 000000000..91848c2e6
--- /dev/null
+++ b/Tests/RunCMake/CMP0060/main.c
@@ -0,0 +1,5 @@
+extern int libCMP0060(void);
+int main(void)
+{
+ return libCMP0060();
+}
diff --git a/Tests/RunCMake/CMP0064/CMP0064-NEW.cmake b/Tests/RunCMake/CMP0064/CMP0064-NEW.cmake
new file mode 100644
index 000000000..cdf50e9ca
--- /dev/null
+++ b/Tests/RunCMake/CMP0064/CMP0064-NEW.cmake
@@ -0,0 +1,5 @@
+cmake_policy(SET CMP0064 NEW)
+
+if(NOT TEST TestThatDoesNotExist)
+ message(STATUS "if NOT TestThatDoesNotExist is true")
+endif()
diff --git a/Tests/RunCMake/CMP0064/CMP0064-OLD.cmake b/Tests/RunCMake/CMP0064/CMP0064-OLD.cmake
new file mode 100644
index 000000000..bffd3f362
--- /dev/null
+++ b/Tests/RunCMake/CMP0064/CMP0064-OLD.cmake
@@ -0,0 +1,7 @@
+cmake_policy(SET CMP0064 OLD)
+
+if(TEST)
+ message(FATAL_ERROR "TEST was not recognized to be undefined")
+else()
+ message(STATUS "TEST was treated as a variable")
+endif()
diff --git a/Tests/RunCMake/CMP0064/CMP0064-WARN-stderr.txt b/Tests/RunCMake/CMP0064/CMP0064-WARN-stderr.txt
new file mode 100644
index 000000000..71f1ab772
--- /dev/null
+++ b/Tests/RunCMake/CMP0064/CMP0064-WARN-stderr.txt
@@ -0,0 +1,10 @@
+CMake Warning \(dev\) at CMP0064-WARN.cmake:3 \(if\):
+ Policy CMP0064 is not set: Support new TEST if\(\) operator. Run "cmake
+ --help-policy CMP0064" for policy details. Use the cmake_policy command to
+ set the policy and suppress this warning.
+
+ TEST will be interpreted as an operator when the policy is set to NEW.
+ Since the policy is not set the OLD behavior will be used.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0064/CMP0064-WARN.cmake b/Tests/RunCMake/CMP0064/CMP0064-WARN.cmake
new file mode 100644
index 000000000..8f26ec62b
--- /dev/null
+++ b/Tests/RunCMake/CMP0064/CMP0064-WARN.cmake
@@ -0,0 +1,7 @@
+
+
+if(TEST)
+ message(FATAL_ERROR "TEST was not recognized to be undefined")
+else()
+ message(STATUS "TEST was treated as a variable")
+endif()
diff --git a/Tests/RunCMake/CMP0064/CMakeLists.txt b/Tests/RunCMake/CMP0064/CMakeLists.txt
new file mode 100644
index 000000000..74b3ff8de
--- /dev/null
+++ b/Tests/RunCMake/CMP0064/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.3)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0064/RunCMakeTest.cmake b/Tests/RunCMake/CMP0064/RunCMakeTest.cmake
new file mode 100644
index 000000000..26e0a91a7
--- /dev/null
+++ b/Tests/RunCMake/CMP0064/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0064-OLD)
+run_cmake(CMP0064-WARN)
+run_cmake(CMP0064-NEW)
diff --git a/Tests/RunCMake/CMP0065/BuildTargetInSubProject.cmake b/Tests/RunCMake/CMP0065/BuildTargetInSubProject.cmake
new file mode 100644
index 000000000..9339e4667
--- /dev/null
+++ b/Tests/RunCMake/CMP0065/BuildTargetInSubProject.cmake
@@ -0,0 +1,15 @@
+function(BuildTargetInSubProject P T E)
+ try_compile(RESULTVAR
+ ${CMAKE_CURRENT_BINARY_DIR}/subproject
+ ${CMAKE_CURRENT_SOURCE_DIR}/subproject
+ ${P} ${T} OUTPUT_VARIABLE O)
+ if(E AND RESULTVAR)
+ message(STATUS "${P} target ${T} succeeded as expected")
+ elseif(E AND NOT RESULTVAR)
+ message(FATAL_ERROR "${P} target ${T} failed but should have succeeded. Output:${O}")
+ elseif(NOT E AND NOT RESULTVAR)
+ message(STATUS "${P} target ${T} failed as expected")
+ elseif(NOT E AND RESULTVAR)
+ message(FATAL_ERROR "${P} target ${T} succeeded but should have failed. Output:${O}")
+ endif()
+endfunction()
diff --git a/Tests/RunCMake/CMP0065/CMakeLists.txt b/Tests/RunCMake/CMP0065/CMakeLists.txt
new file mode 100644
index 000000000..74b3ff8de
--- /dev/null
+++ b/Tests/RunCMake/CMP0065/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.3)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0065/NEWBad.cmake b/Tests/RunCMake/CMP0065/NEWBad.cmake
new file mode 100644
index 000000000..79d9adb73
--- /dev/null
+++ b/Tests/RunCMake/CMP0065/NEWBad.cmake
@@ -0,0 +1,4 @@
+enable_language(C)
+include(BuildTargetInSubProject.cmake)
+
+BuildTargetInSubProject(TestPolicyCMP0065 FooNEWBad FALSE)
diff --git a/Tests/RunCMake/CMP0065/NEWGood.cmake b/Tests/RunCMake/CMP0065/NEWGood.cmake
new file mode 100644
index 000000000..a5b5d0442
--- /dev/null
+++ b/Tests/RunCMake/CMP0065/NEWGood.cmake
@@ -0,0 +1,4 @@
+enable_language(C)
+include(BuildTargetInSubProject.cmake)
+
+BuildTargetInSubProject(TestPolicyCMP0065 FooNEWGood TRUE)
diff --git a/Tests/RunCMake/CMP0065/OLDBad1.cmake b/Tests/RunCMake/CMP0065/OLDBad1.cmake
new file mode 100644
index 000000000..6d780b4a2
--- /dev/null
+++ b/Tests/RunCMake/CMP0065/OLDBad1.cmake
@@ -0,0 +1,4 @@
+enable_language(C)
+include(BuildTargetInSubProject.cmake)
+
+BuildTargetInSubProject(TestPolicyCMP0065 FooOLDBad1 FALSE)
diff --git a/Tests/RunCMake/CMP0065/OLDBad2.cmake b/Tests/RunCMake/CMP0065/OLDBad2.cmake
new file mode 100644
index 000000000..7196473e1
--- /dev/null
+++ b/Tests/RunCMake/CMP0065/OLDBad2.cmake
@@ -0,0 +1,4 @@
+enable_language(C)
+include(BuildTargetInSubProject.cmake)
+
+BuildTargetInSubProject(TestPolicyCMP0065 FooOLDBad2 FALSE)
diff --git a/Tests/RunCMake/CMP0065/RunCMakeTest.cmake b/Tests/RunCMake/CMP0065/RunCMakeTest.cmake
new file mode 100644
index 000000000..254a4ec02
--- /dev/null
+++ b/Tests/RunCMake/CMP0065/RunCMakeTest.cmake
@@ -0,0 +1,8 @@
+include(RunCMake)
+
+run_cmake(OLDBad1)
+run_cmake(OLDBad2)
+run_cmake(NEWBad)
+run_cmake(NEWGood)
+run_cmake(WARN-OFF)
+run_cmake(WARN-ON)
diff --git a/Tests/RunCMake/CMP0065/WARN-OFF.cmake b/Tests/RunCMake/CMP0065/WARN-OFF.cmake
new file mode 100644
index 000000000..dbc956237
--- /dev/null
+++ b/Tests/RunCMake/CMP0065/WARN-OFF.cmake
@@ -0,0 +1,3 @@
+
+enable_language(C)
+add_executable(main subproject/main.c)
diff --git a/Tests/RunCMake/CMP0065/WARN-ON-stderr.txt b/Tests/RunCMake/CMP0065/WARN-ON-stderr.txt
new file mode 100644
index 000000000..dda4fe5de
--- /dev/null
+++ b/Tests/RunCMake/CMP0065/WARN-ON-stderr.txt
@@ -0,0 +1,10 @@
+CMake Warning \(dev\) in CMakeLists.txt:
+ Policy CMP0065 is not set: Do not add flags to export symbols from
+ executables without the ENABLE_EXPORTS target property. Run "cmake
+ --help-policy CMP0065" for policy details. Use the cmake_policy command to
+ set the policy and suppress this warning.
+
+ For compatibility with older versions of CMake, additional flags may be
+ added to export symbols on all executables regardless of thier
+ ENABLE_EXPORTS property.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0065/WARN-ON.cmake b/Tests/RunCMake/CMP0065/WARN-ON.cmake
new file mode 100644
index 000000000..6ed4a4144
--- /dev/null
+++ b/Tests/RunCMake/CMP0065/WARN-ON.cmake
@@ -0,0 +1,3 @@
+set(CMAKE_POLICY_WARNING_CMP0065 1)
+enable_language(C)
+add_executable(main subproject/main.c)
diff --git a/Tests/RunCMake/CMP0065/subproject/CMakeLists.txt b/Tests/RunCMake/CMP0065/subproject/CMakeLists.txt
new file mode 100644
index 000000000..bed59601c
--- /dev/null
+++ b/Tests/RunCMake/CMP0065/subproject/CMakeLists.txt
@@ -0,0 +1,22 @@
+cmake_minimum_required(VERSION 3.3)
+
+project(TestPolicyCMP0065 C)
+set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS BADFLAGS)
+
+#----------------------------------------------------------------------
+cmake_policy(SET CMP0065 OLD)
+add_executable(FooOLDBad1 main.c)
+
+#----------------------------------------------------------------------
+cmake_policy(SET CMP0065 OLD)
+add_executable(FooOLDBad2 main.c)
+set_target_properties(FooOLDBad2 PROPERTIES ENABLE_EXPORTS ON)
+
+#----------------------------------------------------------------------
+cmake_policy(SET CMP0065 NEW)
+add_executable(FooNEWGood main.c)
+
+#----------------------------------------------------------------------
+cmake_policy(SET CMP0065 NEW)
+add_executable(FooNEWBad main.c)
+set_target_properties(FooNEWBad PROPERTIES ENABLE_EXPORTS ON)
diff --git a/Tests/RunCMake/CMP0065/subproject/main.c b/Tests/RunCMake/CMP0065/subproject/main.c
new file mode 100644
index 000000000..98725db50
--- /dev/null
+++ b/Tests/RunCMake/CMP0065/subproject/main.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ printf("Hello World\n");
+ return 0;
+}
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index e45aba378..0a388c53c 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -1,105 +1,221 @@
-# This directory contains tests that run CMake to configure a project
-# but do not actually build anything. To add a test:
-#
-# 1.) Add a subdirectory named for the test.
-#
-# 2.) Call add_RunCMake_test and pass the test directory name.
-#
-# 3.) Create a RunCMakeTest.cmake script in the directory containing
-# include(RunCMake)
-# run_cmake(SubTest1)
-# ...
-# run_cmake(SubTestN)
-# where SubTest1..SubTestN are sub-test names each corresponding to
-# an independent CMake run and project configuration.
-#
-# 3.) Create a CMakeLists.txt file in the directory containing
-# cmake_minimum_required(...)
-# project(${RunCMake_TEST} NONE) # or languages needed
-# include(${RunCMake_TEST}.cmake)
-# where "${RunCMake_TEST}" is literal. A value for RunCMake_TEST
-# will be passed to CMake by the run_cmake macro when running each
-# sub-test.
-#
-# 4.) Create a <SubTest>.cmake file for each sub-test named above
-# containing the actual test code. Optionally create files
-# containing expected test results:
-# <SubTest>-result.txt = Process result expected if not "0"
-# <SubTest>-stdout.txt = Regex matching expected stdout content
-# <SubTest>-stderr.txt = Regex matching expected stderr content
-# <SubTest>-check.cmake = Custom result check
-# Note that trailing newlines will be stripped from actual and expected test
-# output before matching against the stdout and stderr expressions.
-# The code in <SubTest>-check.cmake may use variables
-# RunCMake_TEST_SOURCE_DIR = Top of test source tree
-# RunCMake_TEST_BINARY_DIR = Top of test binary tree
-# and an failure must store a message in RunCMake_TEST_FAILED.
+# See adjacent README.rst for documentation of this test infrastructure.
macro(add_RunCMake_test test)
- add_test(RunCMake.${test} ${CMAKE_CMAKE_COMMAND}
+ set(TEST_ARGS ${ARGN})
+ if ("${ARGV1}" STREQUAL "TEST_DIR")
+ if ("${ARGV2}" STREQUAL "")
+ message(FATAL_ERROR "Invalid args")
+ endif()
+ set(Test_Dir ${ARGV2})
+ list(REMOVE_AT TEST_ARGS 0)
+ list(REMOVE_AT TEST_ARGS 0)
+ else()
+ set(Test_Dir ${test})
+ endif()
+ add_test(NAME RunCMake.${test} COMMAND ${CMAKE_CMAKE_COMMAND}
-DCMAKE_MODULE_PATH=${CMAKE_CURRENT_SOURCE_DIR}
- -DRunCMake_GENERATOR=${CMAKE_TEST_GENERATOR}
- -DRunCMake_GENERATOR_TOOLSET=${CMAKE_TEST_GENERATOR_TOOLSET}
- -DRunCMake_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}/${test}
+ -DRunCMake_GENERATOR=${CMAKE_GENERATOR}
+ -DRunCMake_GENERATOR_PLATFORM=${CMAKE_GENERATOR_PLATFORM}
+ -DRunCMake_GENERATOR_TOOLSET=${CMAKE_GENERATOR_TOOLSET}
+ -DRunCMake_MAKE_PROGRAM=${CMake_TEST_EXPLICIT_MAKE_PROGRAM}
+ -DRunCMake_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}/${Test_Dir}
-DRunCMake_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}/${test}
${${test}_ARGS}
- -P "${CMAKE_CURRENT_SOURCE_DIR}/${test}/RunCMakeTest.cmake"
+ ${TEST_ARGS}
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/${Test_Dir}/RunCMakeTest.cmake"
)
endmacro()
+function(add_RunCMake_test_group test types)
+ # create directory for common content
+ set(TEST_CONFIG_DIR "${CMAKE_CURRENT_BINARY_DIR}/${test}/conf")
+ file(REMOVE_RECURSE "${TEST_CONFIG_DIR}")
+ file(MAKE_DIRECTORY "${TEST_CONFIG_DIR}")
+
+ foreach(type IN LISTS types)
+ # generate prerequirements config file in cmake as ctest doesn't have as
+ # much system information so it is easier to set programs and environment
+ # values here
+ unset(${test}_${type}_FOUND_PREREQUIREMENTS)
+ include("${CMAKE_CURRENT_SOURCE_DIR}/${test}/${type}/Prerequirements.cmake")
+ get_test_prerequirements("${test}_${type}_FOUND_PREREQUIREMENTS"
+ "${TEST_CONFIG_DIR}/${type}_config.cmake")
+
+ # only add the test if prerequirements are met
+ if(${test}_${type}_FOUND_PREREQUIREMENTS)
+ add_test(NAME RunCMake.${test}_${type} COMMAND ${CMAKE_CMAKE_COMMAND}
+ -DTEST_TYPE=${type}
+ -DCMAKE_MODULE_PATH=${CMAKE_CURRENT_SOURCE_DIR}
+ -DRunCMake_GENERATOR=${CMAKE_GENERATOR}
+ -DRunCMake_GENERATOR_PLATFORM=${CMAKE_GENERATOR_PLATFORM}
+ -DRunCMake_GENERATOR_TOOLSET=${CMAKE_GENERATOR_TOOLSET}
+ -DRunCMake_MAKE_PROGRAM=${CMake_TEST_EXPLICIT_MAKE_PROGRAM}
+ -DRunCMake_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}/${test}
+ -DRunCMake_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}/${type}/${test}
+ -Dconfig_file=${TEST_CONFIG_DIR}/${type}_config.cmake
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/${test}/RunCMakeTest.cmake"
+ )
+ endif()
+ endforeach()
+endfunction()
+
+if(XCODE_VERSION AND "${XCODE_VERSION}" VERSION_LESS 6.1)
+ set(Swift_ARGS -DXCODE_BELOW_6_1=1)
+endif()
+
if(XCODE_VERSION AND "${XCODE_VERSION}" VERSION_LESS 3)
set(GeneratorToolset_ARGS -DXCODE_BELOW_3=1)
endif()
+if(XCODE_VERSION AND "${XCODE_VERSION}" VERSION_LESS 2)
+ set(TargetSources_ARGS -DXCODE_BELOW_2=1)
+ set(File_Generate_ARGS -DXCODE_BELOW_2=1)
+endif()
+
+# Test MSVC for older host CMake versions, and test
+# WIN32/CMAKE_C_COMPILER_ID to fix check on Intel for Windows.
+if(MSVC OR (WIN32 AND CMAKE_C_COMPILER_ID MATCHES "MSVC|Intel"))
+ set(GeneratorExpression_ARGS -DLINKER_SUPPORTS_PDB=1)
+endif()
+
add_RunCMake_test(CMP0019)
add_RunCMake_test(CMP0022)
+add_RunCMake_test(CMP0026)
+add_RunCMake_test(CMP0027)
+add_RunCMake_test(CMP0028)
+add_RunCMake_test(CMP0037)
+add_RunCMake_test(CMP0038)
+add_RunCMake_test(CMP0039)
+add_RunCMake_test(CMP0040)
+add_RunCMake_test(CMP0041)
+if(CMAKE_SYSTEM_NAME MATCHES Darwin AND CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG)
+ add_RunCMake_test(CMP0042)
+endif()
+add_RunCMake_test(CMP0043)
+add_RunCMake_test(CMP0045)
+add_RunCMake_test(CMP0046)
+add_RunCMake_test(CMP0049)
+add_RunCMake_test(CMP0050)
+add_RunCMake_test(CMP0051)
+add_RunCMake_test(CMP0053)
+add_RunCMake_test(CMP0054)
+add_RunCMake_test(CMP0055)
+add_RunCMake_test(CMP0057)
+add_RunCMake_test(CMP0059)
+add_RunCMake_test(CMP0060)
+add_RunCMake_test(CMP0064)
+
+# The test for Policy 65 requires the use of the
+# CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode
+# generators ignore. The policy will have no effect on those generators.
+if(NOT CMAKE_GENERATOR MATCHES "Visual Studio|Xcode")
+ add_RunCMake_test(CMP0065)
+endif()
+if(CMAKE_GENERATOR MATCHES "Make")
+ add_RunCMake_test(Make)
+endif()
+if(CMAKE_GENERATOR STREQUAL "Ninja")
+ add_RunCMake_test(Ninja)
+endif()
add_RunCMake_test(CTest)
-if(UNIX AND "${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles")
+
+if(NOT CMake_TEST_EXTERNAL_CMAKE)
+ add_RunCMake_test(ctest_memcheck
+ -DPSEUDO_BC=$<TARGET_FILE:pseudo_BC>
+ -DPSEUDO_PURIFY=$<TARGET_FILE:pseudo_purify>
+ -DPSEUDO_VALGRIND=$<TARGET_FILE:pseudo_valgrind>
+ -DPSEUDO_BC_NOLOG=$<TARGET_FILE:pseudonl_BC>
+ -DPSEUDO_PURIFY_NOLOG=$<TARGET_FILE:pseudonl_purify>
+ -DPSEUDO_VALGRIND_NOLOG=$<TARGET_FILE:pseudonl_valgrind>
+ -DMEMCHECK_FAIL=$<TARGET_FILE:memcheck_fail>
+ )
+endif()
+
+add_RunCMake_test(BuildDepends)
+if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles|Ninja")
add_RunCMake_test(CompilerChange)
endif()
+add_RunCMake_test(CompilerNotFound)
add_RunCMake_test(Configure)
+add_RunCMake_test(DisallowedCommands)
add_RunCMake_test(ExternalData)
+add_RunCMake_test(FeatureSummary)
add_RunCMake_test(FPHSA)
add_RunCMake_test(GeneratorExpression)
+add_RunCMake_test(GeneratorPlatform)
add_RunCMake_test(GeneratorToolset)
+add_RunCMake_test(GNUInstallDirs)
add_RunCMake_test(TargetPropertyGeneratorExpressions)
add_RunCMake_test(Languages)
+add_RunCMake_test(LinkStatic)
add_RunCMake_test(ObjectLibrary)
+add_RunCMake_test(Swift)
+add_RunCMake_test(TargetObjects)
+add_RunCMake_test(TargetSources)
+add_RunCMake_test(find_dependency)
+add_RunCMake_test(CompileDefinitions)
+add_RunCMake_test(CompileFeatures)
+add_RunCMake_test(PolicyScope)
+add_RunCMake_test(WriteCompilerDetectionHeader)
if(NOT WIN32)
add_RunCMake_test(PositionIndependentCode)
- set(SKIP_VISIBILITY 0)
- if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU" AND "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS 4.2)
- set(SKIP_VISIBILITY 1)
- endif()
-
- if (CMAKE_CXX_COMPILER_ID MATCHES Watcom
- OR CMAKE_SYSTEM_NAME MATCHES IRIX64
- OR CMAKE_CXX_COMPILER_ID MATCHES HP
- OR CMAKE_CXX_COMPILER_ID MATCHES XL
- OR CMAKE_CXX_COMPILER_ID MATCHES SunPro)
- set(SKIP_VISIBILITY 1)
- endif()
-
- if (NOT SKIP_VISIBILITY)
- add_RunCMake_test(VisibilityPreset)
- endif()
+endif()
+if(NOT CMAKE_GENERATOR MATCHES "Visual Studio")
+ add_RunCMake_test(VisibilityPreset)
+endif()
+if (QT4_FOUND)
+ set(CompatibleInterface_ARGS -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE})
endif()
add_RunCMake_test(CompatibleInterface)
add_RunCMake_test(Syntax)
+add_RunCMake_test(add_custom_command)
+add_RunCMake_test(add_custom_target)
add_RunCMake_test(add_dependencies)
+add_RunCMake_test(add_subdirectory)
add_RunCMake_test(build_command)
+add_RunCMake_test(execute_process)
+add_RunCMake_test(export)
+add_RunCMake_test(cmake_minimum_required)
+add_RunCMake_test(cmake_parse_arguments)
+add_RunCMake_test(continue)
+add_RunCMake_test(ctest_build)
+add_RunCMake_test(ctest_configure)
+if(COVERAGE_COMMAND)
+ add_RunCMake_test(ctest_coverage -DCOVERAGE_COMMAND=${COVERAGE_COMMAND})
+endif()
+add_RunCMake_test(ctest_start)
+add_RunCMake_test(ctest_submit)
+add_RunCMake_test(ctest_test)
+add_RunCMake_test(ctest_upload)
+add_RunCMake_test(file)
+add_RunCMake_test(find_file)
+add_RunCMake_test(find_library)
add_RunCMake_test(find_package)
+add_RunCMake_test(find_path)
+add_RunCMake_test(find_program -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME})
add_RunCMake_test(get_filename_component)
+add_RunCMake_test(get_property)
add_RunCMake_test(if)
add_RunCMake_test(include)
add_RunCMake_test(include_directories)
add_RunCMake_test(list)
+add_RunCMake_test(message)
+add_RunCMake_test(project)
+add_RunCMake_test(return)
+add_RunCMake_test(set_property)
+add_RunCMake_test(string)
add_RunCMake_test(try_compile)
+add_RunCMake_test(try_run)
+add_RunCMake_test(set)
add_RunCMake_test(variable_watch)
+add_RunCMake_test(while)
add_RunCMake_test(CMP0004)
add_RunCMake_test(TargetPolicies)
add_RunCMake_test(alias_targets)
+add_RunCMake_test(interface_library)
+add_RunCMake_test(no_install_prefix)
+add_RunCMake_test(configure_file)
find_package(Qt4 QUIET)
find_package(Qt5Core QUIET)
@@ -107,15 +223,81 @@ if (QT4_FOUND AND Qt5Core_FOUND AND NOT Qt5Core_VERSION VERSION_LESS 5.1.0)
add_RunCMake_test(IncompatibleQt)
endif()
if (QT4_FOUND)
- set(ObsoleteQtMacros_ARGS -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE})
- add_RunCMake_test(ObsoleteQtMacros)
+ add_RunCMake_test(ObsoleteQtMacros -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE})
+endif()
+
+find_package(PkgConfig QUIET)
+if(PKG_CONFIG_FOUND)
+ add_RunCMake_test(FindPkgConfig)
endif()
-if("${CMAKE_TEST_GENERATOR}" MATCHES "Visual Studio [^6]")
+if("${CMAKE_GENERATOR}" MATCHES "Visual Studio [^6]")
add_RunCMake_test(include_external_msproject)
add_RunCMake_test(SolutionGlobalSections)
endif()
+if(XCODE_VERSION AND NOT "${XCODE_VERSION}" VERSION_LESS 3)
+ add_RunCMake_test(XcodeProject -DXCODE_VERSION=${XCODE_VERSION})
+endif()
+
+if(NOT XCODE
+ AND CMAKE_C_COMPILER_ID STREQUAL "AppleClang"
+ AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.0)
+ add_RunCMake_test(Framework)
+endif()
+
add_RunCMake_test(File_Generate)
add_RunCMake_test(ExportWithoutLanguage)
add_RunCMake_test(target_link_libraries)
+
+add_RunCMake_test(target_compile_features)
+add_RunCMake_test(CheckModules)
+add_RunCMake_test(CommandLine)
+add_RunCMake_test(CommandLineTar)
+
+add_RunCMake_test(install)
+add_RunCMake_test(CPackConfig)
+add_RunCMake_test(CPackInstallProperties)
+add_RunCMake_test(ExternalProject)
+add_RunCMake_test(CTestCommandLine)
+# Only run this test on unix platforms that support
+# symbolic links
+if(UNIX)
+ add_RunCMake_test(CPackSymlinks)
+endif()
+
+set(IfacePaths_INCLUDE_DIRECTORIES_ARGS -DTEST_PROP=INCLUDE_DIRECTORIES)
+add_RunCMake_test(IfacePaths_INCLUDE_DIRECTORIES TEST_DIR IfacePaths)
+
+set(IfacePaths_SOURCES_ARGS -DTEST_PROP=SOURCES)
+add_RunCMake_test(IfacePaths_SOURCES TEST_DIR IfacePaths)
+
+add_RunCMake_test(COMPILE_LANGUAGE-genex)
+
+# Matlab module related tests
+if(CMake_TEST_FindMatlab)
+ add_RunCMake_test(FindMatlab)
+endif()
+
+add_executable(pseudo_emulator pseudo_emulator.c)
+add_RunCMake_test(CrosscompilingEmulator
+ -DPSEUDO_EMULATOR=$<TARGET_FILE:pseudo_emulator>)
+# Xcode 2.x forgets to create the output directory before linking
+# the individual architectures.
+if(CMAKE_OSX_ARCHITECTURES AND XCODE AND NOT "${XCODE_VERSION}" MATCHES "^[^12]")
+ add_custom_command(
+ TARGET pseudo_emulator
+ PRE_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CFG_INTDIR}"
+ )
+endif()
+
+if("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
+ add_executable(pseudo_iwyu pseudo_iwyu.c)
+ add_RunCMake_test(IncludeWhatYouUse -DPSEUDO_IWYU=$<TARGET_FILE:pseudo_iwyu>)
+ add_RunCMake_test(CompilerLauncher)
+endif()
+
+add_RunCMake_test_group(CPack "DEB;RPM;TGZ")
+# add a test to make sure symbols are exported from a shared library
+# for MSVC compilers CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS property is used
+add_RunCMake_test(AutoExportDll)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CMakeLists.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CMakeLists.txt
new file mode 100644
index 000000000..ef2163c29
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.1)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-result.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-VS.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-VS.txt
new file mode 100644
index 000000000..73b66acc7
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-VS.txt
@@ -0,0 +1,8 @@
+CMake Error at CompileDefinitions.cmake:5 \(target_compile_definitions\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANGUAGE:CXX>
+
+ \$<COMPILE_LANGUAGE:...> may not be used with Visual Studio generators.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-Xcode.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-Xcode.txt
new file mode 100644
index 000000000..a1ed63390
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-Xcode.txt
@@ -0,0 +1,9 @@
+CMake Error at CompileDefinitions.cmake:5 \(target_compile_definitions\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANGUAGE:CXX>
+
+ \$<COMPILE_LANGUAGE:...> may only be used with COMPILE_OPTIONS with the
+ Xcode generator.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions.cmake b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions.cmake
new file mode 100644
index 000000000..7935d881b
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions.cmake
@@ -0,0 +1,5 @@
+
+enable_language(CXX)
+
+add_executable(main main.cpp)
+target_compile_definitions(main PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-DANYTHING>)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions-result.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions-stderr-VS.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions-stderr-VS.txt
new file mode 100644
index 000000000..e9e8e9f1e
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions-stderr-VS.txt
@@ -0,0 +1,8 @@
+CMake Error at CompileOptions.cmake:5 \(target_compile_options\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANGUAGE:CXX>
+
+ \$<COMPILE_LANGUAGE:...> may not be used with Visual Studio generators.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions.cmake b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions.cmake
new file mode 100644
index 000000000..6c92abca9
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions.cmake
@@ -0,0 +1,5 @@
+
+enable_language(CXX)
+
+add_executable(main main.cpp)
+target_compile_options(main PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-DANYTHING>)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-result.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-VS.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-VS.txt
new file mode 100644
index 000000000..ec15068e9
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-VS.txt
@@ -0,0 +1,8 @@
+CMake Error at IncludeDirectories.cmake:5 \(target_include_directories\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANGUAGE:CXX>
+
+ \$<COMPILE_LANGUAGE:...> may not be used with Visual Studio generators.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-Xcode.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-Xcode.txt
new file mode 100644
index 000000000..fdf92b28f
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-Xcode.txt
@@ -0,0 +1,9 @@
+CMake Error at IncludeDirectories.cmake:5 \(target_include_directories\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANGUAGE:CXX>
+
+ \$<COMPILE_LANGUAGE:...> may only be used with COMPILE_OPTIONS with the
+ Xcode generator.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories.cmake b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories.cmake
new file mode 100644
index 000000000..31771f64d
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories.cmake
@@ -0,0 +1,5 @@
+
+enable_language(CXX)
+
+add_executable(main main.cpp)
+target_include_directories(main PRIVATE $<$<COMPILE_LANGUAGE:CXX>:anydir>)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake b/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake
new file mode 100644
index 000000000..5e0a5f512
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake
@@ -0,0 +1,20 @@
+include(RunCMake)
+
+if (RunCMake_GENERATOR MATCHES "Visual Studio")
+ set(RunCMake-stderr-file CompileOptions-stderr-VS.txt)
+ run_cmake(CompileOptions)
+endif()
+if (RunCMake_GENERATOR STREQUAL "Xcode")
+ set(RunCMake-stderr-file CompileDefinitions-stderr-Xcode.txt)
+ run_cmake(CompileDefinitions)
+elseif (RunCMake_GENERATOR MATCHES "Visual Studio")
+ set(RunCMake-stderr-file CompileDefinitions-stderr-VS.txt)
+ run_cmake(CompileDefinitions)
+endif()
+if (RunCMake_GENERATOR STREQUAL "Xcode")
+ set(RunCMake-stderr-file IncludeDirectories-stderr-Xcode.txt)
+ run_cmake(IncludeDirectories)
+elseif (RunCMake_GENERATOR MATCHES "Visual Studio")
+ set(RunCMake-stderr-file IncludeDirectories-stderr-VS.txt)
+ run_cmake(IncludeDirectories)
+endif()
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/main.cpp b/Tests/RunCMake/COMPILE_LANGUAGE-genex/main.cpp
new file mode 100644
index 000000000..31a133726
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/main.cpp
@@ -0,0 +1,5 @@
+
+int main()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CPack/CMakeLists.txt b/Tests/RunCMake/CPack/CMakeLists.txt
new file mode 100644
index 000000000..46f13676b
--- /dev/null
+++ b/Tests/RunCMake/CPack/CMakeLists.txt
@@ -0,0 +1,12 @@
+cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
+
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)
+
+# include test generator specifics
+if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${GENERATOR_TYPE}/${RunCMake_TEST}-specifics.cmake")
+ include("${GENERATOR_TYPE}/${RunCMake_TEST}-specifics.cmake")
+endif()
+
+set(CPACK_GENERATOR "${GENERATOR_TYPE}")
+include(CPack)
diff --git a/Tests/RunCMake/CPack/COMPONENTS_EMPTY_DIR.cmake b/Tests/RunCMake/CPack/COMPONENTS_EMPTY_DIR.cmake
new file mode 100644
index 000000000..7210e7d63
--- /dev/null
+++ b/Tests/RunCMake/CPack/COMPONENTS_EMPTY_DIR.cmake
@@ -0,0 +1,5 @@
+set(CPACK_COMPONENTS_ALL test)
+install(DIRECTORY DESTINATION empty
+ COMPONENT test)
+
+set(CPACK_PACKAGE_NAME "components_empty_dir")
diff --git a/Tests/RunCMake/CPack/CPackTestHelpers.cmake b/Tests/RunCMake/CPack/CPackTestHelpers.cmake
new file mode 100644
index 000000000..aef1086ff
--- /dev/null
+++ b/Tests/RunCMake/CPack/CPackTestHelpers.cmake
@@ -0,0 +1,41 @@
+cmake_policy(SET CMP0057 NEW)
+
+function(run_cpack_test TEST_NAME types build)
+ if(TEST_TYPE IN_LIST types)
+ set(RunCMake_TEST_NO_CLEAN TRUE)
+ set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${TEST_NAME}-build")
+
+ # TODO this should be executed only once per ctest run (not per generator)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+ # execute cmake
+ set(RunCMake_TEST_OPTIONS "-DGENERATOR_TYPE=${TEST_TYPE}")
+ run_cmake(${TEST_NAME})
+
+ # execute optional build step
+ if(build)
+ run_cmake_command(${TEST_NAME}-Build "${CMAKE_COMMAND}" --build "${RunCMake_TEST_BINARY_DIR}")
+ endif()
+
+ # execute cpack
+ execute_process(
+ COMMAND "${CMAKE_CPACK_COMMAND}"
+ WORKING_DIRECTORY "${RunCMake_TEST_BINARY_DIR}"
+ OUTPUT_FILE "${RunCMake_TEST_BINARY_DIR}/test_output.txt"
+ ERROR_FILE "${RunCMake_TEST_BINARY_DIR}/test_error.txt"
+ )
+
+ # verify result
+ run_cmake_command(
+ ${TEST_TYPE}/${TEST_NAME}
+ "${CMAKE_COMMAND}"
+ -DRunCMake_TEST=${TEST_NAME}
+ -DGENERATOR_TYPE=${TEST_TYPE}
+ "-Dsrc_dir=${RunCMake_SOURCE_DIR}"
+ "-Dbin_dir=${RunCMake_TEST_BINARY_DIR}"
+ "-Dconfig_file=${config_file}"
+ -P "${RunCMake_SOURCE_DIR}/VerifyResult.cmake"
+ )
+ endif()
+endfunction()
diff --git a/Tests/RunCMake/CPack/DEB/COMPONENTS_EMPTY_DIR-ExpectedFiles.cmake b/Tests/RunCMake/CPack/DEB/COMPONENTS_EMPTY_DIR-ExpectedFiles.cmake
new file mode 100644
index 000000000..5adca685a
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/COMPONENTS_EMPTY_DIR-ExpectedFiles.cmake
@@ -0,0 +1,5 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_1 "components_empty_dir*.deb")
+set(EXPECTED_FILE_CONTENT_1 "^.*/usr/${whitespaces_}.*/usr/empty/$")
diff --git a/Tests/RunCMake/CPack/DEB/COMPONENTS_EMPTY_DIR-specifics.cmake b/Tests/RunCMake/CPack/DEB/COMPONENTS_EMPTY_DIR-specifics.cmake
new file mode 100644
index 000000000..2720fe921
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/COMPONENTS_EMPTY_DIR-specifics.cmake
@@ -0,0 +1,2 @@
+set(CPACK_PACKAGE_CONTACT "someone")
+set(CPACK_DEB_COMPONENT_INSTALL "ON")
diff --git a/Tests/RunCMake/CPack/DEB/DEB_EXTRA-ExpectedFiles.cmake b/Tests/RunCMake/CPack/DEB/DEB_EXTRA-ExpectedFiles.cmake
new file mode 100644
index 000000000..2ff679ae8
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/DEB_EXTRA-ExpectedFiles.cmake
@@ -0,0 +1,9 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "3")
+set(EXPECTED_FILE_1 "deb_extra-*-foo.deb")
+set(EXPECTED_FILE_CONTENT_1 "^.*/usr/${whitespaces_}.*/usr/foo/${whitespaces_}.*/usr/foo/CMakeLists.txt$")
+set(EXPECTED_FILE_2 "deb_extra-*-bar.deb")
+set(EXPECTED_FILE_CONTENT_2 "^.*/usr/${whitespaces_}.*/usr/bar/${whitespaces_}.*/usr/bar/CMakeLists.txt$")
+set(EXPECTED_FILE_3 "deb_extra-*-bas.deb")
+set(EXPECTED_FILE_CONTENT_3 "^.*/usr/${whitespaces_}.*/usr/bas/${whitespaces_}.*/usr/bas/CMakeLists.txt$")
diff --git a/Tests/RunCMake/CPack/DEB/DEB_EXTRA-VerifyResult.cmake b/Tests/RunCMake/CPack/DEB/DEB_EXTRA-VerifyResult.cmake
new file mode 100644
index 000000000..5f929ff7c
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/DEB_EXTRA-VerifyResult.cmake
@@ -0,0 +1,17 @@
+set(foo_preinst "^echo default_preinst$")
+set(foo_preinst_permissions_regex "-rwxr-xr-x .*")
+set(foo_prerm "^echo default_prerm$")
+set(foo_prerm_permissions_regex "-rwxr-xr-x .*")
+verifyDebControl("${FOUND_FILE_1}" "foo" "preinst;prerm")
+
+set(bar_preinst "^echo bar_preinst$")
+set(bar_prerm_permissions_regex "-rwx------ .*")
+set(bar_prerm "^echo bar_prerm$")
+set(bar_prerm_permissions_regex "-rwx------ .*")
+verifyDebControl("${FOUND_FILE_2}" "bar" "preinst;prerm")
+
+set(bas_preinst "^echo default_preinst$")
+set(bas_prerm_permissions_regex "-rwxr-xr-x .*")
+set(bas_prerm "^echo default_prerm$")
+set(bas_prerm_permissions_regex "-rwxr-xr-x .*")
+verifyDebControl("${FOUND_FILE_3}" "bas" "preinst;prerm")
diff --git a/Tests/RunCMake/CPack/DEB/DEPENDENCIES-ExpectedFiles.cmake b/Tests/RunCMake/CPack/DEB/DEPENDENCIES-ExpectedFiles.cmake
new file mode 100644
index 000000000..c56c670fc
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/DEPENDENCIES-ExpectedFiles.cmake
@@ -0,0 +1,14 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "5")
+set(EXPECTED_FILE_1 "dependencies*-applications.deb")
+set(EXPECTED_FILE_CONTENT_1 "^.*/usr/foo${whitespaces_}.*/usr/foo/test_prog$")
+set(EXPECTED_FILE_2 "dependencies*-applications_auto.deb")
+set(EXPECTED_FILE_CONTENT_2 "^.*/usr/foo_auto${whitespaces_}.*/usr/foo_auto/test_prog$")
+set(EXPECTED_FILE_3 "dependencies*-headers.deb")
+set(EXPECTED_FILE_CONTENT_3 "^.*/usr/bar${whitespaces_}.*/usr/bar/CMakeLists.txt$")
+set(EXPECTED_FILE_4 "dependencies*-libs.deb")
+# dynamic lib extension is .so on Linux and .dylib on Mac so we will use a wildcard .* for it
+set(EXPECTED_FILE_CONTENT_4 "^.*/usr/bas${whitespaces_}.*/usr/bas/libtest_lib\\..*$")
+set(EXPECTED_FILE_5 "dependencies*-libs_auto.deb")
+set(EXPECTED_FILE_CONTENT_5 "^.*/usr/bas_auto${whitespaces_}.*/usr/bas_auto/libtest_lib\\..*$")
diff --git a/Tests/RunCMake/CPack/DEB/DEPENDENCIES-VerifyResult.cmake b/Tests/RunCMake/CPack/DEB/DEPENDENCIES-VerifyResult.cmake
new file mode 100644
index 000000000..ba39f2e36
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/DEPENDENCIES-VerifyResult.cmake
@@ -0,0 +1,34 @@
+function(checkDependencies_ FILE REGEX)
+ set(whitespaces_ "[\t\n\r ]*")
+
+ getPackageInfo("${FILE}" "FILE_INFO_")
+ if(NOT FILE_INFO_ MATCHES "${REGEX}")
+ message(FATAL_ERROR "Unexpected dependencies in '${FILE}'; file info: '${FILE_INFO_}'")
+ endif()
+endfunction()
+
+foreach(dependency_type_ DEPENDS CONFLICTS ENHANCES BREAKS REPLACES RECOMMENDS SUGGESTS)
+ string(TOLOWER "${dependency_type_}" lower_dependency_type_)
+ string(SUBSTRING ${lower_dependency_type_} 1 -1 lower_dependency_type_tail_)
+ string(SUBSTRING ${dependency_type_} 0 1 dependency_type_head_)
+ set(dependency_type_name_ "${dependency_type_head_}${lower_dependency_type_tail_}")
+
+ checkDependencies_("${FOUND_FILE_1}" ".*${dependency_type_name_}${whitespaces_}:${whitespaces_}${lower_dependency_type_}-application, ${lower_dependency_type_}-application-b.*")
+ checkDependencies_("${FOUND_FILE_2}" ".*${dependency_type_name_}${whitespaces_}:${whitespaces_}.*${lower_dependency_type_}-application, ${lower_dependency_type_}-application-b.*")
+ checkDependencies_("${FOUND_FILE_3}" ".*${dependency_type_name_}${whitespaces_}:${whitespaces_}${lower_dependency_type_}-headers.*")
+ checkDependencies_("${FOUND_FILE_4}" ".*${dependency_type_name_}${whitespaces_}:${whitespaces_}${lower_dependency_type_}-default, ${lower_dependency_type_}-default-b.*")
+ checkDependencies_("${FOUND_FILE_5}" ".*${dependency_type_name_}${whitespaces_}:${whitespaces_}${lower_dependency_type_}-default, ${lower_dependency_type_}-default-b.*")
+endforeach()
+
+checkDependencies_("${FOUND_FILE_1}" ".*Provides${whitespaces_}:${whitespaces_}provided-default, provided-default-b")
+checkDependencies_("${FOUND_FILE_2}" ".*Provides${whitespaces_}:${whitespaces_}provided-default, provided-default-b")
+checkDependencies_("${FOUND_FILE_3}" ".*Provides${whitespaces_}:${whitespaces_}provided-default, provided-default-b")
+checkDependencies_("${FOUND_FILE_4}" ".*Provides${whitespaces_}:${whitespaces_}provided-lib.*")
+checkDependencies_("${FOUND_FILE_5}" ".*Provides${whitespaces_}:${whitespaces_}provided-lib_auto.*, provided-lib_auto-b.*")
+
+# PREDEPENDS
+checkDependencies_("${FOUND_FILE_1}" ".*Pre-Depends${whitespaces_}:${whitespaces_}predepends-application, predepends-application-b.*")
+checkDependencies_("${FOUND_FILE_2}" ".*Pre-Depends${whitespaces_}:${whitespaces_}.*predepends-application, predepends-application-b.*")
+checkDependencies_("${FOUND_FILE_3}" ".*Pre-Depends${whitespaces_}:${whitespaces_}predepends-headers.*")
+checkDependencies_("${FOUND_FILE_4}" ".*Pre-Depends${whitespaces_}:${whitespaces_}predepends-default, predepends-default-b.*")
+checkDependencies_("${FOUND_FILE_5}" ".*Pre-Depends${whitespaces_}:${whitespaces_}predepends-default, predepends-default-b.*")
diff --git a/Tests/RunCMake/CPack/DEB/DEPENDENCIES-specifics.cmake b/Tests/RunCMake/CPack/DEB/DEPENDENCIES-specifics.cmake
new file mode 100644
index 000000000..96a9f1442
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/DEPENDENCIES-specifics.cmake
@@ -0,0 +1,21 @@
+set(CPACK_PACKAGE_CONTACT "someone")
+set(CPACK_DEB_COMPONENT_INSTALL "ON")
+
+# false by default
+set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS FALSE)
+# FIXME can not be tested as libraries first have to be part of a package in order
+# to determine their dependencies and we can not be certain if there will be any
+set(CPACK_DEBIAN_APPLICATIONS_AUTO_PACKAGE_SHLIBDEPS TRUE)
+
+foreach(dependency_type_ DEPENDS CONFLICTS PREDEPENDS ENHANCES BREAKS REPLACES RECOMMENDS SUGGESTS)
+ string(TOLOWER "${dependency_type_}" lower_dependency_type_)
+
+ set(CPACK_DEBIAN_PACKAGE_${dependency_type_} "${lower_dependency_type_}-default, ${lower_dependency_type_}-default-b")
+ set(CPACK_DEBIAN_APPLICATIONS_PACKAGE_${dependency_type_} "${lower_dependency_type_}-application, ${lower_dependency_type_}-application-b")
+ set(CPACK_DEBIAN_APPLICATIONS_AUTO_PACKAGE_${dependency_type_} "${lower_dependency_type_}-application, ${lower_dependency_type_}-application-b")
+ set(CPACK_DEBIAN_HEADERS_PACKAGE_${dependency_type_} "${lower_dependency_type_}-headers")
+endforeach()
+
+set(CPACK_DEBIAN_PACKAGE_PROVIDES "provided-default, provided-default-b")
+set(CPACK_DEBIAN_LIBS_PACKAGE_PROVIDES "provided-lib")
+set(CPACK_DEBIAN_LIBS_AUTO_PACKAGE_PROVIDES "provided-lib_auto, provided-lib_auto-b")
diff --git a/Tests/RunCMake/CPack/DEB/EMPTY_DIR-ExpectedFiles.cmake b/Tests/RunCMake/CPack/DEB/EMPTY_DIR-ExpectedFiles.cmake
new file mode 100644
index 000000000..1552a36ad
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/EMPTY_DIR-ExpectedFiles.cmake
@@ -0,0 +1,5 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_1 "empty_dir*.deb")
+set(EXPECTED_FILE_CONTENT_1 "^.*/usr/${whitespaces_}.*/usr/empty/$")
diff --git a/Tests/RunCMake/CPack/DEB/EMPTY_DIR-specifics.cmake b/Tests/RunCMake/CPack/DEB/EMPTY_DIR-specifics.cmake
new file mode 100644
index 000000000..8821ab9be
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/EMPTY_DIR-specifics.cmake
@@ -0,0 +1 @@
+set(CPACK_PACKAGE_CONTACT "someone")
diff --git a/Tests/RunCMake/CPack/DEB/Helpers.cmake b/Tests/RunCMake/CPack/DEB/Helpers.cmake
new file mode 100644
index 000000000..f490130cf
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/Helpers.cmake
@@ -0,0 +1,51 @@
+set(ALL_FILES_GLOB "*.deb")
+
+function(getPackageContent FILE RESULT_VAR)
+ execute_process(COMMAND ${DPKG_EXECUTABLE} -c ${FILE}
+ OUTPUT_VARIABLE package_content_
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ set(${RESULT_VAR} "${package_content_}" PARENT_SCOPE)
+endfunction()
+
+function(verifyDebControl FILE PREFIX VERIFY_FILES)
+ execute_process(COMMAND ${DPKG_EXECUTABLE} --control ${FILE} control_${PREFIX}
+ ERROR_VARIABLE err_)
+
+ if(err_)
+ message(FATAL_ERROR "Debian control verification failed for file: "
+ "'${FILE}'; error output: '${err_}'")
+ endif()
+
+ foreach(FILE_ IN LISTS VERIFY_FILES)
+ file(READ "${CMAKE_CURRENT_BINARY_DIR}/control_${PREFIX}/${FILE_}" content_)
+ if(NOT content_ MATCHES "${${PREFIX}_${FILE_}}")
+ message(FATAL_ERROR "Unexpected content in for '${PREFIX}_${FILE_}'!"
+ " Content: '${content_}'")
+ endif()
+
+ execute_process(COMMAND ls -l "${CMAKE_CURRENT_BINARY_DIR}/control_${PREFIX}/${FILE_}"
+ OUTPUT_VARIABLE package_permissions_
+ ERROR_VARIABLE package_permissions_error_
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ if(NOT package_permissions_error_)
+ if(NOT package_permissions_ MATCHES "${${PREFIX}_${FILE_}_permissions_regex}")
+ message(FATAL_ERROR "Unexpected file permissions for ${PREFIX}_${FILE_}: '${package_permissions_}'!")
+ endif()
+ else()
+ message(FATAL_ERROR "Listing file permissions failed (${package_permissions_error_})!")
+ endif()
+ endforeach()
+endfunction()
+
+function(getPackageInfo FILE RESULT_VAR)
+ execute_process(COMMAND ${DPKG_EXECUTABLE} -I ${FILE}
+ WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}"
+ OUTPUT_VARIABLE package_info_
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ set(${RESULT_VAR} "${package_info_}" PARENT_SCOPE)
+endfunction()
diff --git a/Tests/RunCMake/CPack/DEB/MINIMAL-ExpectedFiles.cmake b/Tests/RunCMake/CPack/DEB/MINIMAL-ExpectedFiles.cmake
new file mode 100644
index 000000000..9e4aa7c1d
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/MINIMAL-ExpectedFiles.cmake
@@ -0,0 +1,5 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_1 "minimal*.deb")
+set(EXPECTED_FILE_CONTENT_1 "^.*/usr/${whitespaces_}.*/usr/foo/${whitespaces_}.*/usr/foo/CMakeLists.txt$")
diff --git a/Tests/RunCMake/CPack/DEB/MINIMAL-specifics.cmake b/Tests/RunCMake/CPack/DEB/MINIMAL-specifics.cmake
new file mode 100644
index 000000000..8821ab9be
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/MINIMAL-specifics.cmake
@@ -0,0 +1 @@
+set(CPACK_PACKAGE_CONTACT "someone")
diff --git a/Tests/RunCMake/CPack/DEB/PER_COMPONENT_FIELDS-ExpectedFiles.cmake b/Tests/RunCMake/CPack/DEB/PER_COMPONENT_FIELDS-ExpectedFiles.cmake
new file mode 100644
index 000000000..1f6c11b9d
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/PER_COMPONENT_FIELDS-ExpectedFiles.cmake
@@ -0,0 +1,9 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "3")
+set(EXPECTED_FILE_1 "per_component*-pkg_1.deb")
+set(EXPECTED_FILE_CONTENT_1 "^.*/usr/foo${whitespaces_}.*/usr/foo/CMakeLists.txt$")
+set(EXPECTED_FILE_2 "per_component*-pkg_2.deb")
+set(EXPECTED_FILE_CONTENT_2 "^.*/usr/foo${whitespaces_}.*/usr/foo/CMakeLists.txt$")
+set(EXPECTED_FILE_3 "per_component*-pkg_3.deb")
+set(EXPECTED_FILE_CONTENT_3 "^.*/usr/foo${whitespaces_}.*/usr/foo/CMakeLists.txt$")
diff --git a/Tests/RunCMake/CPack/DEB/PER_COMPONENT_FIELDS-VerifyResult.cmake b/Tests/RunCMake/CPack/DEB/PER_COMPONENT_FIELDS-VerifyResult.cmake
new file mode 100644
index 000000000..55293be50
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/PER_COMPONENT_FIELDS-VerifyResult.cmake
@@ -0,0 +1,18 @@
+function(checkPackageInfo_ TYPE FILE REGEX)
+ set(whitespaces_ "[\t\n\r ]*")
+
+ getPackageInfo("${FILE}" "FILE_INFO_")
+ if(NOT FILE_INFO_ MATCHES "${REGEX}")
+ message(FATAL_ERROR "Unexpected ${TYPE} in '${FILE}'; file info: '${FILE_INFO_}'")
+ endif()
+endfunction()
+
+# check package name
+checkPackageInfo_("name" "${FOUND_FILE_1}" ".*Package${whitespaces_}:${whitespaces_}per_component-pkg_1")
+checkPackageInfo_("name" "${FOUND_FILE_2}" ".*Package${whitespaces_}:${whitespaces_}second")
+checkPackageInfo_("name" "${FOUND_FILE_3}" ".*Package${whitespaces_}:${whitespaces_}per_component-pkg_3")
+
+# check package group
+checkPackageInfo_("group" "${FOUND_FILE_1}" ".*Section${whitespaces_}:${whitespaces_}default")
+checkPackageInfo_("group" "${FOUND_FILE_2}" ".*Section${whitespaces_}:${whitespaces_}second_group")
+checkPackageInfo_("group" "${FOUND_FILE_3}" ".*Section${whitespaces_}:${whitespaces_}default")
diff --git a/Tests/RunCMake/CPack/DEB/PER_COMPONENT_FIELDS-specifics.cmake b/Tests/RunCMake/CPack/DEB/PER_COMPONENT_FIELDS-specifics.cmake
new file mode 100644
index 000000000..a1da1a3cd
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/PER_COMPONENT_FIELDS-specifics.cmake
@@ -0,0 +1,6 @@
+set(CPACK_PACKAGE_CONTACT "someone")
+set(CPACK_DEB_COMPONENT_INSTALL "ON")
+
+set(CPACK_DEBIAN_PACKAGE_SECTION "default")
+set(CPACK_DEBIAN_PKG_2_PACKAGE_NAME "second")
+set(CPACK_DEBIAN_PKG_2_PACKAGE_SECTION "second_group")
diff --git a/Tests/RunCMake/CPack/DEB/Prerequirements.cmake b/Tests/RunCMake/CPack/DEB/Prerequirements.cmake
new file mode 100644
index 000000000..197b99d5d
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB/Prerequirements.cmake
@@ -0,0 +1,8 @@
+function(get_test_prerequirements found_var config_file)
+ find_program(DPKG_EXECUTABLE dpkg)
+
+ if(DPKG_EXECUTABLE)
+ file(WRITE "${config_file}" "set(DPKG_EXECUTABLE \"${DPKG_EXECUTABLE}\")")
+ set(${found_var} true PARENT_SCOPE)
+ endif()
+endfunction()
diff --git a/Tests/RunCMake/CPack/DEB_EXTRA.cmake b/Tests/RunCMake/CPack/DEB_EXTRA.cmake
new file mode 100644
index 000000000..3c291d521
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEB_EXTRA.cmake
@@ -0,0 +1,38 @@
+install(FILES CMakeLists.txt DESTINATION foo COMPONENT foo)
+install(FILES CMakeLists.txt DESTINATION bar COMPONENT bar)
+install(FILES CMakeLists.txt DESTINATION bas COMPONENT bas)
+
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/tmp/preinst "echo default_preinst")
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/tmp/prerm "echo default_prerm")
+
+foreach(file_ preinst prerm)
+ file(COPY ${CMAKE_CURRENT_BINARY_DIR}/tmp/${file_}
+ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
+ FILE_PERMISSIONS
+ OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE
+ WORLD_READ WORLD_EXECUTE)
+endforeach()
+
+set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
+ "${CMAKE_CURRENT_BINARY_DIR}/preinst;${CMAKE_CURRENT_BINARY_DIR}/prerm;${CMAKE_CURRENT_BINARY_DIR}/conffiles")
+
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/bar_tmp/preinst "echo bar_preinst")
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/bar_tmp/prerm "echo bar_prerm")
+
+foreach(file_ preinst prerm)
+ # not acceptable permissions for lintian but we need to check that
+ # permissions are preserved
+ file(COPY ${CMAKE_CURRENT_BINARY_DIR}/bar_tmp/${file_}
+ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/bar
+ FILE_PERMISSIONS
+ OWNER_READ OWNER_WRITE OWNER_EXECUTE)
+endforeach()
+
+set(CPACK_DEBIAN_BAR_PACKAGE_CONTROL_EXTRA
+ "${CMAKE_CURRENT_BINARY_DIR}/bar/preinst;${CMAKE_CURRENT_BINARY_DIR}/bar/prerm")
+
+set(CPACK_PACKAGE_NAME "deb_extra")
+set(CPACK_PACKAGE_CONTACT "someone")
+
+set(CPACK_DEB_COMPONENT_INSTALL ON)
diff --git a/Tests/RunCMake/CPack/DEPENDENCIES.cmake b/Tests/RunCMake/CPack/DEPENDENCIES.cmake
new file mode 100644
index 000000000..4f6d65fb0
--- /dev/null
+++ b/Tests/RunCMake/CPack/DEPENDENCIES.cmake
@@ -0,0 +1,20 @@
+set(CMAKE_BUILD_WITH_INSTALL_RPATH 1)
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test_lib.hpp"
+ "int test_lib();\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test_lib.cpp"
+ "#include \"test_lib.hpp\"\nint test_lib() {return 0;}\n")
+add_library(test_lib SHARED "${CMAKE_CURRENT_BINARY_DIR}/test_lib.cpp")
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main.cpp"
+ "#include \"test_lib.hpp\"\nint main() {return test_lib();}\n")
+add_executable(test_prog "${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
+target_link_libraries(test_prog test_lib)
+
+install(TARGETS test_prog DESTINATION foo COMPONENT applications)
+install(TARGETS test_prog DESTINATION foo_auto COMPONENT applications_auto)
+install(FILES CMakeLists.txt DESTINATION bar COMPONENT headers)
+install(TARGETS test_lib DESTINATION bas COMPONENT libs)
+install(TARGETS test_lib DESTINATION bas_auto COMPONENT libs_auto)
+
+set(CPACK_PACKAGE_NAME "dependencies")
diff --git a/Tests/RunCMake/CPack/EMPTY_DIR.cmake b/Tests/RunCMake/CPack/EMPTY_DIR.cmake
new file mode 100644
index 000000000..023ba173e
--- /dev/null
+++ b/Tests/RunCMake/CPack/EMPTY_DIR.cmake
@@ -0,0 +1,4 @@
+install(DIRECTORY DESTINATION empty
+ COMPONENT test)
+
+set(CPACK_PACKAGE_NAME "empty_dir")
diff --git a/Tests/RunCMake/CPack/MINIMAL.cmake b/Tests/RunCMake/CPack/MINIMAL.cmake
new file mode 100644
index 000000000..f29ad2a98
--- /dev/null
+++ b/Tests/RunCMake/CPack/MINIMAL.cmake
@@ -0,0 +1,3 @@
+install(FILES CMakeLists.txt DESTINATION foo COMPONENT test)
+
+set(CPACK_PACKAGE_NAME "minimal")
diff --git a/Tests/RunCMake/CPack/PARTIALLY_RELOCATABLE_WARNING.cmake b/Tests/RunCMake/CPack/PARTIALLY_RELOCATABLE_WARNING.cmake
new file mode 100644
index 000000000..31e729bfe
--- /dev/null
+++ b/Tests/RunCMake/CPack/PARTIALLY_RELOCATABLE_WARNING.cmake
@@ -0,0 +1,6 @@
+install(FILES CMakeLists.txt DESTINATION /not_relocatable COMPONENT static)
+
+set(CPACK_PACKAGE_RELOCATABLE TRUE)
+set(CPACK_PACKAGING_INSTALL_PREFIX "/opt")
+
+set(CPACK_RPM_COMPONENT_INSTALL ON)
diff --git a/Tests/RunCMake/CPack/PER_COMPONENT_FIELDS.cmake b/Tests/RunCMake/CPack/PER_COMPONENT_FIELDS.cmake
new file mode 100644
index 000000000..bb42cf4d5
--- /dev/null
+++ b/Tests/RunCMake/CPack/PER_COMPONENT_FIELDS.cmake
@@ -0,0 +1,5 @@
+install(FILES CMakeLists.txt DESTINATION foo COMPONENT pkg_1)
+install(FILES CMakeLists.txt DESTINATION foo COMPONENT pkg_2)
+install(FILES CMakeLists.txt DESTINATION foo COMPONENT pkg_3)
+
+set(CPACK_PACKAGE_NAME "per_component")
diff --git a/Tests/RunCMake/CPack/README.txt b/Tests/RunCMake/CPack/README.txt
new file mode 100644
index 000000000..ea6830448
--- /dev/null
+++ b/Tests/RunCMake/CPack/README.txt
@@ -0,0 +1,99 @@
+RunCMake.CPack is a test module that is intended for testing of package
+generators that can be validated from command line.
+
+-------------
+Adding a test
+-------------
+
+CPack test root directory: 'Tests/RunCMake/CPack'.
+
+All phases are executed separately for each generator that is bound to a test.
+Tests for each generator are subtests of test 'RunCMake.CPack_<generator_name>'.
+
+Each test must also be added to 'RunCMakeTest.cmake' script located in CPack
+test root directory.
+Line that adds a test is:
+run_cpack_test(<test_name> "<generator_name>")
+
+<generator_name> may be one generator e.g. "RPM" or multiple e.g. "RPM;DEB" and
+will be run for all listed generators.
+
+Test consists of
+- CMake execution phase
+- CPack execution phase
+- verification of generated files
+
+CMake execution phase:
+----------------------
+
+To add a new CPack test we first create a <test_name>.cmake script that contains
+CMake commands that should be used as a preparation script for generation of
+different types of packages. This script is placed into CPack test root
+directory even if it will be used for only one of the generators.
+
+If test will be used for multiple generators but some of them require some
+generator specific commands then those commands should be added to a separate
+file that should be located in '<generator_name>/<test_name>-specifics.cmake'
+in CPack test root directory.
+
+CPack execution phase:
+----------------------
+
+Only executes CPack for content that was generated during CMake execution
+phase.
+
+Verification of generated files:
+--------------------------------
+
+Verification of generated files consists of two phases
+- mandatory verification phase
+- optional verification phase
+
+Mandatory verification phase checks that expected files were generated and
+contain expected files.
+Mandatory verification phase also checks that no other unexpected package files
+were generated (this is executed even if EXPECTED_FILES_COUNT contains 0 in
+order to verify that no files were generated).
+CMake script '<generator_name>/<test_name>-ExpectedFiles.cmake' is required by
+this step and must contain
+- EXPECTED_FILES_COUNT variable that contains the number of expected files that
+ will be generated (0 or more)
+- EXPECTED_FILE_<file_number_starting_with_1> that contains globing expression
+ that uniquely defines expected file name (will be used to find expected file)
+ and should be present once for each expected file
+- EXPECTED_FILE_CONTENT_<file_number_starting_with_1> that contains regular
+ expression of files that should be present in generated file and should be
+ present once for each expected file
+
+Optional verification phase is generator specific and is optionaly executed.
+This phase is executed if '<generator_name>/<test_name>-VerifyResult.cmake'
+script exists.
+In case that the script doesn't exist VerifyResult.cmake script automatically
+prints out standard output and standard error from CPack execution phase that
+is compared with '<generator_name>/<test_name>-stdout.txt' regular expression
+and '<generator_name>/<test_name>-stderr.txt' regular expresson respectively.
+
+----------------------
+Adding a new generator
+----------------------
+
+To add a new generator we must
+- add new generator directory (e.g. RPM for RPM generator) to CPack test root
+ directory that contains 'Helpers.cmake' script. In this script a function
+ named 'getPackageContent' must exist. This function should list files that
+ are contained in a package. Function should accept two parameters
+ + FILE variable that will contain path to file for which the content should be
+ listed
+ + RESULT_VAR that will tell the function which variable in parent scope should
+ contain the result (list of files inside package file)
+- add 'Prerequirements.cmake' script to generator directory. In this script a
+ function named 'get_test_prerequirements' must exist. This function should
+ set a variable in parent scope (name of the variable is the first parameter)
+ that tells if prerequirements for test execution are met (certain programs,
+ OS specifics, ...) and create a config file (name of the variable which
+ contains file name and path is provided with the second parameter) that
+ should contain 'set' commands for variables that will later be used in tests
+ (e.g. location of dpkg program for DEB packages)
+- add tests the same way as described above
+- add generator to 'add_RunCMake_test_group' function call that is located in
+ RunCMake CMakeLists.txt file
diff --git a/Tests/RunCMake/CPack/RPM/COMPONENTS_EMPTY_DIR-ExpectedFiles.cmake b/Tests/RunCMake/CPack/RPM/COMPONENTS_EMPTY_DIR-ExpectedFiles.cmake
new file mode 100644
index 000000000..d3962768f
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/COMPONENTS_EMPTY_DIR-ExpectedFiles.cmake
@@ -0,0 +1,5 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_1 "components_empty_dir*.rpm")
+set(EXPECTED_FILE_CONTENT_1 "^/usr/empty$")
diff --git a/Tests/RunCMake/CPack/RPM/COMPONENTS_EMPTY_DIR-stderr.txt b/Tests/RunCMake/CPack/RPM/COMPONENTS_EMPTY_DIR-stderr.txt
new file mode 100644
index 000000000..6ddca1275
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/COMPONENTS_EMPTY_DIR-stderr.txt
@@ -0,0 +1 @@
+^CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/COMPONENTS_EMPTY_DIR-build/_CPack_Packages/.*/RPM/SPECS/components_empty_dir.spec$
diff --git a/Tests/RunCMake/CPack/RPM/DEPENDENCIES-ExpectedFiles.cmake b/Tests/RunCMake/CPack/RPM/DEPENDENCIES-ExpectedFiles.cmake
new file mode 100644
index 000000000..cf85dab76
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/DEPENDENCIES-ExpectedFiles.cmake
@@ -0,0 +1,13 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "5")
+set(EXPECTED_FILE_1 "dependencies*-applications.rpm")
+set(EXPECTED_FILE_CONTENT_1 "^/usr/foo${whitespaces_}/usr/foo/test_prog$")
+set(EXPECTED_FILE_2 "dependencies*-applications_auto.rpm")
+set(EXPECTED_FILE_CONTENT_2 "^/usr/foo_auto${whitespaces_}/usr/foo_auto/test_prog$")
+set(EXPECTED_FILE_3 "dependencies*-headers.rpm")
+set(EXPECTED_FILE_CONTENT_3 "^/usr/bar${whitespaces_}/usr/bar/CMakeLists.txt$")
+set(EXPECTED_FILE_4 "dependencies*-libs.rpm")
+set(EXPECTED_FILE_CONTENT_4 "^/usr/bas${whitespaces_}/usr/bas/libtest_lib.so$")
+set(EXPECTED_FILE_5 "dependencies*-libs_auto.rpm")
+set(EXPECTED_FILE_CONTENT_5 "^/usr/bas_auto${whitespaces_}/usr/bas_auto/libtest_lib.so$")
diff --git a/Tests/RunCMake/CPack/RPM/DEPENDENCIES-VerifyResult.cmake b/Tests/RunCMake/CPack/RPM/DEPENDENCIES-VerifyResult.cmake
new file mode 100644
index 000000000..fec888982
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/DEPENDENCIES-VerifyResult.cmake
@@ -0,0 +1,45 @@
+function(checkDependencies_ FILE TYPE COMPARE_LIST)
+ set(whitespaces_ "[\t\n\r ]*")
+
+ execute_process(COMMAND ${RPM_EXECUTABLE} -qp --${TYPE} ${FILE}
+ WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}"
+ OUTPUT_VARIABLE FILE_DEPENDENCIES_
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ string(REPLACE "\n" ";" FILE_DEPENDENCIES_LIST_ "${FILE_DEPENDENCIES_}")
+
+ foreach(COMPARE_REGEX_ IN LISTS COMPARE_LIST)
+ unset(FOUND_)
+
+ foreach(COMPARE_ IN LISTS FILE_DEPENDENCIES_LIST_)
+ if(COMPARE_ MATCHES "${COMPARE_REGEX_}")
+ set(FOUND_ true)
+ break()
+ endif()
+ endforeach()
+
+ if(NOT FOUND_)
+ message(FATAL_ERROR "Missing dependencies in '${FILE}'; check type: '${TYPE}'; file info: '${FILE_DEPENDENCIES_}'; missing: '${COMPARE_REGEX_}'")
+ endif()
+ endforeach()
+endfunction()
+
+# TODO add tests for what should not be present in lists
+checkDependencies_("${FOUND_FILE_1}" "requires" "depend-application;depend-application-b")
+checkDependencies_("${FOUND_FILE_2}" "requires" "depend-application;depend-application-b;libtest_lib\\.so.*")
+checkDependencies_("${FOUND_FILE_3}" "requires" "depend-headers")
+checkDependencies_("${FOUND_FILE_4}" "requires" "depend-default;depend-default-b")
+checkDependencies_("${FOUND_FILE_5}" "requires" "depend-default;depend-default-b")
+
+checkDependencies_("${FOUND_FILE_1}" "conflicts" "conflict-application;conflict-application-b")
+checkDependencies_("${FOUND_FILE_2}" "conflicts" "conflict-application;conflict-application-b")
+checkDependencies_("${FOUND_FILE_3}" "conflicts" "conflict-headers")
+checkDependencies_("${FOUND_FILE_4}" "conflicts" "conflict-default;conflict-default-b")
+checkDependencies_("${FOUND_FILE_5}" "conflicts" "conflict-default;conflict-default-b")
+
+checkDependencies_("${FOUND_FILE_1}" "provides" "provided-default;provided-default-b")
+checkDependencies_("${FOUND_FILE_2}" "provides" "provided-default;provided-default-b")
+checkDependencies_("${FOUND_FILE_3}" "provides" "provided-default;provided-default-b")
+checkDependencies_("${FOUND_FILE_4}" "provides" "provided-lib")
+checkDependencies_("${FOUND_FILE_5}" "provides" "provided-lib_auto;provided-lib_auto-b")
diff --git a/Tests/RunCMake/CPack/RPM/DEPENDENCIES-specifics.cmake b/Tests/RunCMake/CPack/RPM/DEPENDENCIES-specifics.cmake
new file mode 100644
index 000000000..2cdfece3f
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/DEPENDENCIES-specifics.cmake
@@ -0,0 +1,22 @@
+set(CPACK_RPM_COMPONENT_INSTALL "ON")
+
+# FIXME auto autoprov is not tested at the moment as Ubuntu 15.04 rpmbuild
+# does not use them correctly: https://bugs.launchpad.net/rpm/+bug/1475755
+set(CPACK_RPM_PACKAGE_AUTOREQ "no")
+set(CPACK_RPM_PACKAGE_AUTOPROV "no")
+set(CPACK_RPM_applications_auto_PACKAGE_AUTOREQPROV "yes")
+set(CPACK_RPM_libs_auto_PACKAGE_AUTOREQPROV "yes")
+
+set(CPACK_RPM_PACKAGE_REQUIRES "depend-default, depend-default-b")
+set(CPACK_RPM_applications_PACKAGE_REQUIRES "depend-application, depend-application-b")
+set(CPACK_RPM_applications_auto_PACKAGE_REQUIRES "depend-application, depend-application-b")
+set(CPACK_RPM_headers_PACKAGE_REQUIRES "depend-headers")
+
+set(CPACK_RPM_PACKAGE_CONFLICTS "conflict-default, conflict-default-b")
+set(CPACK_RPM_applications_PACKAGE_CONFLICTS "conflict-application, conflict-application-b")
+set(CPACK_RPM_applications_auto_PACKAGE_CONFLICTS "conflict-application, conflict-application-b")
+set(CPACK_RPM_headers_PACKAGE_CONFLICTS "conflict-headers")
+
+set(CPACK_RPM_PACKAGE_PROVIDES "provided-default, provided-default-b")
+set(CPACK_RPM_libs_PACKAGE_PROVIDES "provided-lib")
+set(CPACK_RPM_libs_auto_PACKAGE_PROVIDES "provided-lib_auto, provided-lib_auto-b")
diff --git a/Tests/RunCMake/CPack/RPM/EMPTY_DIR-ExpectedFiles.cmake b/Tests/RunCMake/CPack/RPM/EMPTY_DIR-ExpectedFiles.cmake
new file mode 100644
index 000000000..0c2977f7b
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/EMPTY_DIR-ExpectedFiles.cmake
@@ -0,0 +1,5 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_1 "empty_dir*.rpm")
+set(EXPECTED_FILE_CONTENT_1 "^/usr/empty$")
diff --git a/Tests/RunCMake/CPack/RPM/EMPTY_DIR-stderr.txt b/Tests/RunCMake/CPack/RPM/EMPTY_DIR-stderr.txt
new file mode 100644
index 000000000..1777aa01d
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/EMPTY_DIR-stderr.txt
@@ -0,0 +1 @@
+^CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/EMPTY_DIR-build/_CPack_Packages/.*/RPM/SPECS/empty_dir.spec$
diff --git a/Tests/RunCMake/CPack/RPM/Helpers.cmake b/Tests/RunCMake/CPack/RPM/Helpers.cmake
new file mode 100644
index 000000000..ba77a4a10
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/Helpers.cmake
@@ -0,0 +1,19 @@
+set(ALL_FILES_GLOB "*.rpm")
+
+function(getPackageContent FILE RESULT_VAR)
+ execute_process(COMMAND ${RPM_EXECUTABLE} -pql ${FILE}
+ OUTPUT_VARIABLE package_content_
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ set(${RESULT_VAR} "${package_content_}" PARENT_SCOPE)
+endfunction()
+
+function(getPackageInfo FILE RESULT_VAR)
+ execute_process(COMMAND ${RPM_EXECUTABLE} -pqi ${FILE}
+ OUTPUT_VARIABLE info_content
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ set(${RESULT_VAR} "${info_content}" PARENT_SCOPE)
+endfunction()
diff --git a/Tests/RunCMake/CPack/RPM/MINIMAL-ExpectedFiles.cmake b/Tests/RunCMake/CPack/RPM/MINIMAL-ExpectedFiles.cmake
new file mode 100644
index 000000000..800b78ee0
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/MINIMAL-ExpectedFiles.cmake
@@ -0,0 +1,5 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_1 "minimal*.rpm")
+set(EXPECTED_FILE_CONTENT_1 "^/usr/foo${whitespaces_}/usr/foo/CMakeLists.txt$")
diff --git a/Tests/RunCMake/CPack/RPM/MINIMAL-stderr.txt b/Tests/RunCMake/CPack/RPM/MINIMAL-stderr.txt
new file mode 100644
index 000000000..7c5fb461c
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/MINIMAL-stderr.txt
@@ -0,0 +1 @@
+^CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/MINIMAL-build/_CPack_Packages/.*/RPM/SPECS/minimal.spec$
diff --git a/Tests/RunCMake/CPack/RPM/PARTIALLY_RELOCATABLE_WARNING-ExpectedFiles.cmake b/Tests/RunCMake/CPack/RPM/PARTIALLY_RELOCATABLE_WARNING-ExpectedFiles.cmake
new file mode 100644
index 000000000..4e01f7b41
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/PARTIALLY_RELOCATABLE_WARNING-ExpectedFiles.cmake
@@ -0,0 +1,5 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_1 "PARTIALLY_RELOCATABLE_WARNING-0.1.1-*.rpm")
+set(EXPECTED_FILE_CONTENT_1 "^/not_relocatable${whitespaces_}/not_relocatable/CMakeLists.txt${whitespaces_}/opt$")
diff --git a/Tests/RunCMake/CPack/RPM/PARTIALLY_RELOCATABLE_WARNING-stderr.txt b/Tests/RunCMake/CPack/RPM/PARTIALLY_RELOCATABLE_WARNING-stderr.txt
new file mode 100644
index 000000000..3b63d5bb4
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/PARTIALLY_RELOCATABLE_WARNING-stderr.txt
@@ -0,0 +1 @@
+CPackRPM:Warning: Path /not_relocatable/CMakeLists.txt is not on one of the.*relocatable paths! Package will be partially relocatable.
diff --git a/Tests/RunCMake/CPack/RPM/PER_COMPONENT_FIELDS-ExpectedFiles.cmake b/Tests/RunCMake/CPack/RPM/PER_COMPONENT_FIELDS-ExpectedFiles.cmake
new file mode 100644
index 000000000..3d28d416e
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/PER_COMPONENT_FIELDS-ExpectedFiles.cmake
@@ -0,0 +1,9 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "3")
+set(EXPECTED_FILE_1 "per_component*-pkg_1.rpm")
+set(EXPECTED_FILE_CONTENT_1 "^/usr/foo${whitespaces_}/usr/foo/CMakeLists.txt$")
+set(EXPECTED_FILE_2 "per_component*-pkg_2.rpm")
+set(EXPECTED_FILE_CONTENT_2 "^/usr/foo${whitespaces_}/usr/foo/CMakeLists.txt$")
+set(EXPECTED_FILE_3 "per_component*-pkg_3.rpm")
+set(EXPECTED_FILE_CONTENT_3 "^/usr/foo${whitespaces_}/usr/foo/CMakeLists.txt$")
diff --git a/Tests/RunCMake/CPack/RPM/PER_COMPONENT_FIELDS-VerifyResult.cmake b/Tests/RunCMake/CPack/RPM/PER_COMPONENT_FIELDS-VerifyResult.cmake
new file mode 100644
index 000000000..d7d4f9de6
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/PER_COMPONENT_FIELDS-VerifyResult.cmake
@@ -0,0 +1,18 @@
+function(checkPackageInfo_ TYPE FILE REGEX)
+ set(whitespaces_ "[\t\n\r ]*")
+
+ getPackageInfo("${FILE}" "FILE_INFO_")
+ if(NOT FILE_INFO_ MATCHES "${REGEX}")
+ message(FATAL_ERROR "Unexpected ${TYPE} in '${FILE}'; file info: '${FILE_INFO_}'")
+ endif()
+endfunction()
+
+# check package name
+checkPackageInfo_("name" "${FOUND_FILE_1}" ".*Name${whitespaces_}:${whitespaces_}per_component-pkg_1")
+checkPackageInfo_("name" "${FOUND_FILE_2}" ".*Name${whitespaces_}:${whitespaces_}second")
+checkPackageInfo_("name" "${FOUND_FILE_3}" ".*Name${whitespaces_}:${whitespaces_}per_component-pkg_3")
+
+# check package group
+checkPackageInfo_("group" "${FOUND_FILE_1}" ".*Group${whitespaces_}:${whitespaces_}default")
+checkPackageInfo_("group" "${FOUND_FILE_2}" ".*Group${whitespaces_}:${whitespaces_}second_group")
+checkPackageInfo_("group" "${FOUND_FILE_3}" ".*Group${whitespaces_}:${whitespaces_}default")
diff --git a/Tests/RunCMake/CPack/RPM/PER_COMPONENT_FIELDS-specifics.cmake b/Tests/RunCMake/CPack/RPM/PER_COMPONENT_FIELDS-specifics.cmake
new file mode 100644
index 000000000..d398168e3
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/PER_COMPONENT_FIELDS-specifics.cmake
@@ -0,0 +1,5 @@
+set(CPACK_RPM_COMPONENT_INSTALL "ON")
+
+set(CPACK_RPM_PACKAGE_GROUP "default")
+set(CPACK_RPM_pkg_2_PACKAGE_NAME "second")
+set(CPACK_RPM_pkg_2_PACKAGE_GROUP "second_group")
diff --git a/Tests/RunCMake/CPack/RPM/Prerequirements.cmake b/Tests/RunCMake/CPack/RPM/Prerequirements.cmake
new file mode 100644
index 000000000..3416205bc
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/Prerequirements.cmake
@@ -0,0 +1,16 @@
+function(get_test_prerequirements found_var config_file)
+ if(CMAKE_CURRENT_BINARY_DIR MATCHES " ")
+ # rpmbuild can't handle spaces in path
+ return()
+ endif()
+
+ find_program(RPM_EXECUTABLE rpm)
+ find_program(RPMBUILD_EXECUTABLE rpmbuild)
+
+ if(RPM_EXECUTABLE AND RPMBUILD_EXECUTABLE)
+ file(WRITE "${config_file}" "set(RPM_EXECUTABLE \"${RPM_EXECUTABLE}\")")
+ file(APPEND "${config_file}"
+ "\nset(RPMBUILD_EXECUTABLE \"${RPMBUILD_EXECUTABLE}\")")
+ set(${found_var} true PARENT_SCOPE)
+ endif()
+endfunction()
diff --git a/Tests/RunCMake/CPack/RunCMakeTest.cmake b/Tests/RunCMake/CPack/RunCMakeTest.cmake
new file mode 100644
index 000000000..fe2b48bb3
--- /dev/null
+++ b/Tests/RunCMake/CPack/RunCMakeTest.cmake
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
+
+include(RunCMake)
+include("${RunCMake_SOURCE_DIR}/CPackTestHelpers.cmake")
+
+# args: TEST_NAME "GENERATORS" RUN_CMAKE_BUILD_STEP
+run_cpack_test(MINIMAL "RPM;DEB;TGZ" false)
+run_cpack_test(PARTIALLY_RELOCATABLE_WARNING "RPM" false)
+run_cpack_test(DEB_EXTRA "DEB" false)
+run_cpack_test(DEPENDENCIES "RPM;DEB" true)
+run_cpack_test(EMPTY_DIR "RPM;DEB;TGZ" true)
+run_cpack_test(COMPONENTS_EMPTY_DIR "RPM;DEB;TGZ" true)
+run_cpack_test(PER_COMPONENT_FIELDS "RPM;DEB" false)
diff --git a/Tests/RunCMake/CPack/TGZ/COMPONENTS_EMPTY_DIR-ExpectedFiles.cmake b/Tests/RunCMake/CPack/TGZ/COMPONENTS_EMPTY_DIR-ExpectedFiles.cmake
new file mode 100644
index 000000000..26e2ab06b
--- /dev/null
+++ b/Tests/RunCMake/CPack/TGZ/COMPONENTS_EMPTY_DIR-ExpectedFiles.cmake
@@ -0,0 +1,3 @@
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_1 "components_empty_dir*.tar.gz")
+set(EXPECTED_FILE_CONTENT_1 "^[^\n]*empty/$")
diff --git a/Tests/RunCMake/CPack/TGZ/COMPONENTS_EMPTY_DIR-specifics.cmake b/Tests/RunCMake/CPack/TGZ/COMPONENTS_EMPTY_DIR-specifics.cmake
new file mode 100644
index 000000000..81a5035a3
--- /dev/null
+++ b/Tests/RunCMake/CPack/TGZ/COMPONENTS_EMPTY_DIR-specifics.cmake
@@ -0,0 +1 @@
+set(CPACK_ARCHIVE_COMPONENT_INSTALL "ON")
diff --git a/Tests/RunCMake/CPack/TGZ/EMPTY_DIR-ExpectedFiles.cmake b/Tests/RunCMake/CPack/TGZ/EMPTY_DIR-ExpectedFiles.cmake
new file mode 100644
index 000000000..a75514a7a
--- /dev/null
+++ b/Tests/RunCMake/CPack/TGZ/EMPTY_DIR-ExpectedFiles.cmake
@@ -0,0 +1,3 @@
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_1 "empty_dir*.tar.gz")
+set(EXPECTED_FILE_CONTENT_1 "^[^\n]*empty_dir-0.1.1-[^\n]*/empty/$")
diff --git a/Tests/RunCMake/CPack/TGZ/Helpers.cmake b/Tests/RunCMake/CPack/TGZ/Helpers.cmake
new file mode 100644
index 000000000..f14d53267
--- /dev/null
+++ b/Tests/RunCMake/CPack/TGZ/Helpers.cmake
@@ -0,0 +1,10 @@
+set(ALL_FILES_GLOB "*.tar.gz")
+
+function(getPackageContent FILE RESULT_VAR)
+ execute_process(COMMAND ${CMAKE_COMMAND} -E tar -ztvf ${FILE}
+ OUTPUT_VARIABLE package_content_
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ set(${RESULT_VAR} "${package_content_}" PARENT_SCOPE)
+endfunction()
diff --git a/Tests/RunCMake/CPack/TGZ/MINIMAL-ExpectedFiles.cmake b/Tests/RunCMake/CPack/TGZ/MINIMAL-ExpectedFiles.cmake
new file mode 100644
index 000000000..5c31f276a
--- /dev/null
+++ b/Tests/RunCMake/CPack/TGZ/MINIMAL-ExpectedFiles.cmake
@@ -0,0 +1,5 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_1 "minimal*.tar.gz")
+set(EXPECTED_FILE_CONTENT_1 "^[^\n]*minimal-0.1.1-[^\n]*/foo/\n[^\n]*minimal-0.1.1-[^\n]*/foo/CMakeLists.txt$")
diff --git a/Tests/RunCMake/CPack/TGZ/Prerequirements.cmake b/Tests/RunCMake/CPack/TGZ/Prerequirements.cmake
new file mode 100644
index 000000000..dbaf682e5
--- /dev/null
+++ b/Tests/RunCMake/CPack/TGZ/Prerequirements.cmake
@@ -0,0 +1,4 @@
+function(get_test_prerequirements found_var config_file)
+ file(WRITE "${config_file}" "")
+ set(${found_var} true PARENT_SCOPE)
+endfunction()
diff --git a/Tests/RunCMake/CPack/VerifyResult.cmake b/Tests/RunCMake/CPack/VerifyResult.cmake
new file mode 100644
index 000000000..6eab5312a
--- /dev/null
+++ b/Tests/RunCMake/CPack/VerifyResult.cmake
@@ -0,0 +1,92 @@
+cmake_minimum_required(VERSION ${CMAKE_VERSION} FATAL_ERROR)
+
+include("${config_file}")
+include("${src_dir}/${GENERATOR_TYPE}/Helpers.cmake")
+
+file(READ "${bin_dir}/test_output.txt" output)
+file(READ "${bin_dir}/test_error.txt" error)
+file(READ "${config_file}" config_file_content)
+
+set(output_error_message
+ "\nCPack output: '${output}'\nCPack error: '${error}';\nconfig file: '${config_file_content}'")
+
+# check that expected generated files exist and contain expected content
+include("${src_dir}/${GENERATOR_TYPE}/${RunCMake_TEST}-ExpectedFiles.cmake")
+
+if(NOT EXPECTED_FILES_COUNT EQUAL 0)
+ foreach(file_no_ RANGE 1 ${EXPECTED_FILES_COUNT})
+ file(GLOB FOUND_FILE_${file_no_} RELATIVE "${bin_dir}" "${EXPECTED_FILE_${file_no_}}")
+ set(foundFiles_ "${foundFiles_};${FOUND_FILE_${file_no_}}")
+ list(LENGTH FOUND_FILE_${file_no_} foundFilesCount_)
+
+ if(foundFilesCount_ EQUAL 1)
+ unset(PACKAGE_CONTENT)
+ getPackageContent("${bin_dir}/${FOUND_FILE_${file_no_}}" "PACKAGE_CONTENT")
+
+ string(REGEX MATCH "${EXPECTED_FILE_CONTENT_${file_no_}}"
+ expected_content_list "${PACKAGE_CONTENT}")
+
+ if(NOT expected_content_list)
+ message(FATAL_ERROR
+ "Unexpected file content for file No. '${file_no_}'!\n"
+ " Content: '${PACKAGE_CONTENT}'\n\n"
+ " Expected: '${EXPECTED_FILE_CONTENT_${file_no_}}'"
+ "${output_error_message}")
+ endif()
+ else()
+ message(FATAL_ERROR
+ "Found more than one file for file No. '${file_no_}'!"
+ " Found files count '${foundFilesCount_}'."
+ " Files: '${FOUND_FILE_${file_no_}}'"
+ "${output_error_message}")
+ endif()
+ endforeach()
+
+ # check that there were no extra files generated
+ foreach(all_files_glob_ IN LISTS ALL_FILES_GLOB)
+ file(GLOB foundAll_ RELATIVE "${bin_dir}" "${all_files_glob_}")
+ set(allFoundFiles_ "${allFoundFiles_};${foundAll_}")
+ endforeach()
+
+ list(LENGTH foundFiles_ foundFilesCount_)
+ list(LENGTH allFoundFiles_ allFoundFilesCount_)
+
+ if(NOT foundFilesCount_ EQUAL allFoundFilesCount_)
+ message(FATAL_ERROR
+ "Found more files than expected! Found files: '${allFoundFiles_}'"
+ "${output_error_message}")
+ endif()
+
+ # sanity check that we didn't accidentally list wrong files with our regular
+ # expressions
+ foreach(expected_ IN LISTS allFoundFiles_)
+ list(FIND foundFiles_ "${expected_}" found_)
+
+ if(found_ EQUAL -1)
+ message(FATAL_ERROR
+ "Expected files don't match found files! Found files:"
+ " '${allFoundFiles_}'"
+ "${output_error_message}")
+ endif()
+ endforeach()
+else()
+ # there should be no generated files present
+ foreach(missing_file_glob_ IN LISTS ALL_FILES_GLOB)
+ file(GLOB checkMissingFiles_ RELATIVE "${bin_dir}" "${missing_file_glob_}")
+
+ if(checkMissingFiles_)
+ message(FATAL_ERROR "Unexpected files found: '${checkMissingFiles_}'"
+ "${output_error_message}")
+ endif()
+ endforeach()
+endif()
+
+# handle additional result verifications
+if(EXISTS "${src_dir}/${GENERATOR_TYPE}/${RunCMake_TEST}-VerifyResult.cmake")
+ include("${src_dir}/${GENERATOR_TYPE}/${RunCMake_TEST}-VerifyResult.cmake")
+else()
+ # by default only print out output and error so that they can be compared by
+ # regex
+ message(STATUS "${output}")
+ message("${error}")
+endif()
diff --git a/Tests/RunCMake/CPackConfig/CMakeLists.txt b/Tests/RunCMake/CPackConfig/CMakeLists.txt
new file mode 100644
index 000000000..9a9e7b443
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/CMakeLists.txt
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 3.3)
+
+project(${RunCMake_TEST})
+include(${RunCMake_TEST}.cmake)
+
+include(CPack)
diff --git a/Tests/RunCMake/CPackConfig/Default-check.cmake b/Tests/RunCMake/CPackConfig/Default-check.cmake
new file mode 100644
index 000000000..b67fe8110
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/Default-check.cmake
@@ -0,0 +1,7 @@
+include(${RunCMake_SOURCE_DIR}/check.cmake)
+
+test_variable(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "Foo\\Bar")
+test_variable(CPACK_NSIS_PACKAGE_NAME "Bar\\Foo")
+
+test_variable(CPACK_SOURCE_IGNORE_FILES
+ "/CVS/;/\\.svn/;/\\.bzr/;/\\.hg/;/\\.git/;\\.swp$;\\.#;/#")
diff --git a/Tests/RunCMake/CPackConfig/Default.cmake b/Tests/RunCMake/CPackConfig/Default.cmake
new file mode 100644
index 000000000..3b3beb30b
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/Default.cmake
@@ -0,0 +1,3 @@
+# two levels of escaping to pass through CPackConfig.cmake
+set(CPACK_PACKAGE_INSTALL_DIRECTORY "Foo\\\\Bar")
+set(CPACK_NSIS_DISPLAY_NAME "Bar\\\\Foo")
diff --git a/Tests/RunCMake/CPackConfig/RunCMakeTest.cmake b/Tests/RunCMake/CPackConfig/RunCMakeTest.cmake
new file mode 100644
index 000000000..16d2cf39f
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/RunCMakeTest.cmake
@@ -0,0 +1,6 @@
+include(RunCMake)
+
+run_cmake(Simple)
+run_cmake(Default)
+run_cmake(Special)
+run_cmake(Verbatim)
diff --git a/Tests/RunCMake/CPackConfig/Simple-check.cmake b/Tests/RunCMake/CPackConfig/Simple-check.cmake
new file mode 100644
index 000000000..6e0cf6fa3
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/Simple-check.cmake
@@ -0,0 +1,3 @@
+include(${RunCMake_SOURCE_DIR}/check.cmake)
+
+test_variable(CPACK_FOO "bar baz;quux")
diff --git a/Tests/RunCMake/CPackConfig/Simple.cmake b/Tests/RunCMake/CPackConfig/Simple.cmake
new file mode 100644
index 000000000..c9f654142
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/Simple.cmake
@@ -0,0 +1 @@
+set(CPACK_FOO "bar baz;quux")
diff --git a/Tests/RunCMake/CPackConfig/Special-check.cmake b/Tests/RunCMake/CPackConfig/Special-check.cmake
new file mode 100644
index 000000000..0624b7908
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/Special-check.cmake
@@ -0,0 +1,5 @@
+include(${RunCMake_SOURCE_DIR}/check.cmake)
+
+test_variable(CPACK_BACKSLASH "\\")
+test_variable(CPACK_QUOTE "a;b;c")
+test_variable(CPACK_DOLLAR "ab")
diff --git a/Tests/RunCMake/CPackConfig/Special.cmake b/Tests/RunCMake/CPackConfig/Special.cmake
new file mode 100644
index 000000000..9442c934c
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/Special.cmake
@@ -0,0 +1,3 @@
+set(CPACK_BACKSLASH "\\\\")
+set(CPACK_QUOTE "a\" b \"c")
+set(CPACK_DOLLAR "a\${NOTHING}b")
diff --git a/Tests/RunCMake/CPackConfig/Verbatim-check.cmake b/Tests/RunCMake/CPackConfig/Verbatim-check.cmake
new file mode 100644
index 000000000..958547dbb
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/Verbatim-check.cmake
@@ -0,0 +1,10 @@
+include(${RunCMake_SOURCE_DIR}/check.cmake)
+
+test_variable(CPACK_BACKSLASH "\\\\")
+test_variable(CPACK_QUOTE "a\" b \"c")
+test_variable(CPACK_DOLLAR "a\${NOTHING}b")
+
+# make sure the default for this is still set correctly with
+# CPACK_VERBATIM_VARIABLES on
+test_variable(CPACK_SOURCE_IGNORE_FILES
+ "/CVS/;/\\.svn/;/\\.bzr/;/\\.hg/;/\\.git/;\\.swp$;\\.#;/#")
diff --git a/Tests/RunCMake/CPackConfig/Verbatim.cmake b/Tests/RunCMake/CPackConfig/Verbatim.cmake
new file mode 100644
index 000000000..4d271c33f
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/Verbatim.cmake
@@ -0,0 +1,5 @@
+set(CPACK_VERBATIM_VARIABLES YES)
+
+set(CPACK_BACKSLASH "\\\\")
+set(CPACK_QUOTE "a\" b \"c")
+set(CPACK_DOLLAR "a\${NOTHING}b")
diff --git a/Tests/RunCMake/CPackConfig/check.cmake b/Tests/RunCMake/CPackConfig/check.cmake
new file mode 100644
index 000000000..ca6229e0d
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/check.cmake
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION ${CMAKE_VERSION} FATAL_ERROR)
+
+function(test_variable NAME EXPECTED_VALUE)
+ if(NOT "${${NAME}}" STREQUAL "${EXPECTED_VALUE}")
+ message(FATAL_ERROR "${NAME}: variable mismatch; expected [${EXPECTED_VALUE}] actual [${${NAME}}]")
+ endif()
+endfunction()
+
+include(${RunCMake_TEST_BINARY_DIR}/CPackConfig.cmake)
+include(${RunCMake_TEST_BINARY_DIR}/CPackSourceConfig.cmake)
diff --git a/Tests/RunCMake/CPackInstallProperties/Append-check.cmake b/Tests/RunCMake/CPackInstallProperties/Append-check.cmake
new file mode 100644
index 000000000..017b30d7d
--- /dev/null
+++ b/Tests/RunCMake/CPackInstallProperties/Append-check.cmake
@@ -0,0 +1,3 @@
+include(${RunCMake_SOURCE_DIR}/check.cmake)
+
+test_property("append.txt" CPACK_TEST_PROP "value1;value2;value3")
diff --git a/Tests/RunCMake/CPackInstallProperties/Append.cmake b/Tests/RunCMake/CPackInstallProperties/Append.cmake
new file mode 100644
index 000000000..cecc45f31
--- /dev/null
+++ b/Tests/RunCMake/CPackInstallProperties/Append.cmake
@@ -0,0 +1,2 @@
+set_property(INSTALL append.txt PROPERTY CPACK_TEST_PROP value1)
+set_property(INSTALL append.txt PROPERTY CPACK_TEST_PROP value2 value3 APPEND)
diff --git a/Tests/RunCMake/CPackInstallProperties/CMakeLists.txt b/Tests/RunCMake/CPackInstallProperties/CMakeLists.txt
new file mode 100644
index 000000000..89ff7c49f
--- /dev/null
+++ b/Tests/RunCMake/CPackInstallProperties/CMakeLists.txt
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 3.0)
+
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)
+
+include(CPack)
diff --git a/Tests/RunCMake/CPackInstallProperties/FilenameGenex-check.cmake b/Tests/RunCMake/CPackInstallProperties/FilenameGenex-check.cmake
new file mode 100644
index 000000000..8c9e967c3
--- /dev/null
+++ b/Tests/RunCMake/CPackInstallProperties/FilenameGenex-check.cmake
@@ -0,0 +1,3 @@
+include(${RunCMake_SOURCE_DIR}/check.cmake)
+
+test_property(${EXPECTED_MYTEST_NAME} CPACK_TEST_PROP2 PROP_VALUE2)
diff --git a/Tests/RunCMake/CPackInstallProperties/FilenameGenex.cmake b/Tests/RunCMake/CPackInstallProperties/FilenameGenex.cmake
new file mode 100644
index 000000000..1a373b928
--- /dev/null
+++ b/Tests/RunCMake/CPackInstallProperties/FilenameGenex.cmake
@@ -0,0 +1,7 @@
+add_executable(mytest test.cpp)
+
+file(GENERATE OUTPUT runtest_info.cmake CONTENT [[
+set(EXPECTED_MYTEST_NAME "$<TARGET_FILE_NAME:mytest>")
+]])
+
+set_property(INSTALL $<TARGET_FILE_NAME:mytest> PROPERTY CPACK_TEST_PROP2 PROP_VALUE2)
diff --git a/Tests/RunCMake/CPackInstallProperties/MultipleValues-check.cmake b/Tests/RunCMake/CPackInstallProperties/MultipleValues-check.cmake
new file mode 100644
index 000000000..91278ba4a
--- /dev/null
+++ b/Tests/RunCMake/CPackInstallProperties/MultipleValues-check.cmake
@@ -0,0 +1,3 @@
+include(${RunCMake_SOURCE_DIR}/check.cmake)
+
+test_property("multiple_values.txt" CPACK_TEST_PROP "value1;value2;value3")
diff --git a/Tests/RunCMake/CPackInstallProperties/MultipleValues.cmake b/Tests/RunCMake/CPackInstallProperties/MultipleValues.cmake
new file mode 100644
index 000000000..26db52acd
--- /dev/null
+++ b/Tests/RunCMake/CPackInstallProperties/MultipleValues.cmake
@@ -0,0 +1 @@
+set_property(INSTALL multiple_values.txt PROPERTY CPACK_TEST_PROP value1 value2 value3)
diff --git a/Tests/RunCMake/CPackInstallProperties/PerConfigValue-check.cmake b/Tests/RunCMake/CPackInstallProperties/PerConfigValue-check.cmake
new file mode 100644
index 000000000..2966d88c9
--- /dev/null
+++ b/Tests/RunCMake/CPackInstallProperties/PerConfigValue-check.cmake
@@ -0,0 +1,13 @@
+include(${RunCMake_SOURCE_DIR}/check.cmake)
+
+file(GLOB INFO_FILES ${RunCMake_TEST_BINARY_DIR}/runtest_info_*.cmake)
+
+if(NOT INFO_FILES)
+ message(FATAL_ERROR "missing expected info files")
+endif()
+
+foreach(INFO_FILE IN LISTS INFO_FILES)
+ include(${INFO_FILE})
+ include(${RunCMake_TEST_BINARY_DIR}/CPackProperties.cmake)
+ test_property("config.cpp" FOO ${EXPECTED_MYTEST_NAME})
+endforeach()
diff --git a/Tests/RunCMake/CPackInstallProperties/PerConfigValue.cmake b/Tests/RunCMake/CPackInstallProperties/PerConfigValue.cmake
new file mode 100644
index 000000000..77fe8ed5d
--- /dev/null
+++ b/Tests/RunCMake/CPackInstallProperties/PerConfigValue.cmake
@@ -0,0 +1,14 @@
+add_executable(mytest test.cpp)
+
+foreach(CONFIG IN LISTS CMAKE_CONFIGURATION_TYPES)
+ string(TOUPPER ${CONFIG} UPPER_CONFIG)
+ set_property(TARGET mytest PROPERTY
+ OUTPUT_NAME_${UPPER_CONFIG} bar_${CONFIG})
+endforeach()
+
+file(GENERATE OUTPUT runtest_info_$<CONFIG>.cmake CONTENT [[
+set(CPACK_BUILD_CONFIG "$<CONFIG>")
+set(EXPECTED_MYTEST_NAME "$<TARGET_FILE_NAME:mytest>")
+]])
+
+set_property(INSTALL config.cpp PROPERTY FOO $<TARGET_FILE_NAME:mytest>)
diff --git a/Tests/RunCMake/CPackInstallProperties/Replace-check.cmake b/Tests/RunCMake/CPackInstallProperties/Replace-check.cmake
new file mode 100644
index 000000000..6e492e72d
--- /dev/null
+++ b/Tests/RunCMake/CPackInstallProperties/Replace-check.cmake
@@ -0,0 +1,3 @@
+include(${RunCMake_SOURCE_DIR}/check.cmake)
+
+test_property("replace.txt" CPACK_TEST_PROP "value2")
diff --git a/Tests/RunCMake/CPackInstallProperties/Replace.cmake b/Tests/RunCMake/CPackInstallProperties/Replace.cmake
new file mode 100644
index 000000000..104d5a41f
--- /dev/null
+++ b/Tests/RunCMake/CPackInstallProperties/Replace.cmake
@@ -0,0 +1,2 @@
+set_property(INSTALL replace.txt PROPERTY CPACK_TEST_PROP value1)
+set_property(INSTALL replace.txt PROPERTY CPACK_TEST_PROP value2)
diff --git a/Tests/RunCMake/CPackInstallProperties/RunCMakeTest.cmake b/Tests/RunCMake/CPackInstallProperties/RunCMakeTest.cmake
new file mode 100644
index 000000000..d244ac5a1
--- /dev/null
+++ b/Tests/RunCMake/CPackInstallProperties/RunCMakeTest.cmake
@@ -0,0 +1,9 @@
+include(RunCMake)
+
+run_cmake(Simple)
+run_cmake(FilenameGenex)
+run_cmake(ValueGenex)
+run_cmake(MultipleValues)
+run_cmake(Append)
+run_cmake(Replace)
+run_cmake(PerConfigValue)
diff --git a/Tests/RunCMake/CPackInstallProperties/Simple-check.cmake b/Tests/RunCMake/CPackInstallProperties/Simple-check.cmake
new file mode 100644
index 000000000..6a7ee2aa4
--- /dev/null
+++ b/Tests/RunCMake/CPackInstallProperties/Simple-check.cmake
@@ -0,0 +1,3 @@
+include(${RunCMake_SOURCE_DIR}/check.cmake)
+
+test_property("foo/test.cpp" CPACK_TEST_PROP PROP_VALUE)
diff --git a/Tests/RunCMake/CPackInstallProperties/Simple.cmake b/Tests/RunCMake/CPackInstallProperties/Simple.cmake
new file mode 100644
index 000000000..2eb87553a
--- /dev/null
+++ b/Tests/RunCMake/CPackInstallProperties/Simple.cmake
@@ -0,0 +1 @@
+set_property(INSTALL foo/test.cpp PROPERTY CPACK_TEST_PROP PROP_VALUE)
diff --git a/Tests/RunCMake/CPackInstallProperties/ValueGenex-check.cmake b/Tests/RunCMake/CPackInstallProperties/ValueGenex-check.cmake
new file mode 100644
index 000000000..cdfbcda22
--- /dev/null
+++ b/Tests/RunCMake/CPackInstallProperties/ValueGenex-check.cmake
@@ -0,0 +1,3 @@
+include(${RunCMake_SOURCE_DIR}/check.cmake)
+
+test_property("bar/test.cpp" CPACK_TEST_PROP ${EXPECTED_MYTEST_NAME})
diff --git a/Tests/RunCMake/CPackInstallProperties/ValueGenex.cmake b/Tests/RunCMake/CPackInstallProperties/ValueGenex.cmake
new file mode 100644
index 000000000..2e1d4656c
--- /dev/null
+++ b/Tests/RunCMake/CPackInstallProperties/ValueGenex.cmake
@@ -0,0 +1,7 @@
+add_executable(mytest test.cpp)
+
+file(GENERATE OUTPUT runtest_info.cmake CONTENT [[
+set(EXPECTED_MYTEST_NAME "$<TARGET_FILE_NAME:mytest>")
+]])
+
+set_property(INSTALL bar/test.cpp PROPERTY CPACK_TEST_PROP $<TARGET_FILE_NAME:mytest>)
diff --git a/Tests/RunCMake/CPackInstallProperties/check.cmake b/Tests/RunCMake/CPackInstallProperties/check.cmake
new file mode 100644
index 000000000..65aa467bd
--- /dev/null
+++ b/Tests/RunCMake/CPackInstallProperties/check.cmake
@@ -0,0 +1,12 @@
+function(test_property FILE NAME EXPECTED_VALUE)
+ get_property(ACTUAL_VALUE INSTALL "${FILE}" PROPERTY "${NAME}")
+
+ if(NOT "${ACTUAL_VALUE}" STREQUAL "${EXPECTED_VALUE}")
+ message(FATAL_ERROR "${NAME}@${FILE}: property mismatch expected [${EXPECTED_VALUE}] actual [${ACTUAL_VALUE}] (Config:${CPACK_BUILD_CONFIG})")
+ endif()
+endfunction()
+
+set(CPACK_BUILD_CONFIG Debug)
+include(${RunCMake_TEST_BINARY_DIR}/CPackProperties.cmake)
+
+include(${RunCMake_TEST_BINARY_DIR}/runtest_info.cmake OPTIONAL)
diff --git a/Tests/RunCMake/CPackInstallProperties/test.cpp b/Tests/RunCMake/CPackInstallProperties/test.cpp
new file mode 100644
index 000000000..237c8ce18
--- /dev/null
+++ b/Tests/RunCMake/CPackInstallProperties/test.cpp
@@ -0,0 +1 @@
+int main() {}
diff --git a/Tests/RunCMake/CPackSymlinks/RunCMakeTest.cmake b/Tests/RunCMake/CPackSymlinks/RunCMakeTest.cmake
new file mode 100644
index 000000000..439d95e61
--- /dev/null
+++ b/Tests/RunCMake/CPackSymlinks/RunCMakeTest.cmake
@@ -0,0 +1,20 @@
+include(RunCMake)
+
+function(run_cpack_symlink_test)
+ set(RunCMake_TEST_NO_CLEAN TRUE)
+ set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/SrcSymlinks-build")
+ set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/SrcSymlinks")
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(REMOVE_RECURSE "${RunCMake_TEST_SOURCE_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_SOURCE_DIR}")
+ run_cmake_command(SrcSymlinksTar
+ ${CMAKE_COMMAND} -E chdir ${RunCMake_TEST_SOURCE_DIR}
+ ${CMAKE_COMMAND} -E tar xvf ${RunCMake_SOURCE_DIR}/testcpacksym.tar
+ )
+ run_cmake(SrcSymlinksCMake)
+ run_cmake_command(SrcSymlinksCPack
+ ${CMAKE_CPACK_COMMAND} --config CPackSourceConfig.cmake
+ )
+endfunction()
+
+run_cpack_symlink_test()
diff --git a/Tests/RunCMake/CPackSymlinks/SrcSymlinksTar-stdout.txt b/Tests/RunCMake/CPackSymlinks/SrcSymlinksTar-stdout.txt
new file mode 100644
index 000000000..24ad12472
--- /dev/null
+++ b/Tests/RunCMake/CPackSymlinks/SrcSymlinksTar-stdout.txt
@@ -0,0 +1,10 @@
+^x CMakeLists.txt
+x cygwin/
+x cygwin/build.sh
+x cygwin/setup.patch
+x include/
+x include/src.h
+x link.h
+x real.h
+x src/
+x src/src.h$
diff --git a/Tests/RunCMake/CPackSymlinks/testcpacksym.tar b/Tests/RunCMake/CPackSymlinks/testcpacksym.tar
new file mode 100644
index 000000000..a44c656e8
--- /dev/null
+++ b/Tests/RunCMake/CPackSymlinks/testcpacksym.tar
Binary files differ
diff --git a/Tests/RunCMake/CTest/BeforeProject-stderr.txt b/Tests/RunCMake/CTest/BeforeProject-stderr.txt
index 354896bc6..d61856ce6 100644
--- a/Tests/RunCMake/CTest/BeforeProject-stderr.txt
+++ b/Tests/RunCMake/CTest/BeforeProject-stderr.txt
@@ -1,6 +1,6 @@
-CMake Error at .*/Modules/CTest.cmake:[0-9]+ \(build_command\):
- build_command\(\) requires CMAKE_MAKE_PROGRAM to be defined. Call project\(\)
- or enable_language\(\) first.
+CMake Error at .*/Modules/CTestTargets.cmake:20 \(message\):
+ Do not include\(CTest\) before calling project\(\).
Call Stack \(most recent call first\):
- BeforeProject.cmake:[0-9]+ \(include\)
- CMakeLists.txt:[0-9]+ \(include\)
+ .*/Modules/CTest.cmake:[0-9]+ \(include\)
+ BeforeProject.cmake:1 \(include\)
+ CMakeLists.txt:5 \(include\)
diff --git a/Tests/RunCMake/CTestCommandLine/BadCTestTestfile-stderr.txt b/Tests/RunCMake/CTestCommandLine/BadCTestTestfile-stderr.txt
new file mode 100644
index 000000000..d95bb337c
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/BadCTestTestfile-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at CTestTestfile.cmake:[0-9]+ \(subdirs\):
+ subdirs called with incorrect number of arguments
++
+No tests were found!!!$
diff --git a/Tests/RunCMake/CTestCommandLine/CMakeLists.txt b/Tests/RunCMake/CTestCommandLine/CMakeLists.txt
new file mode 100644
index 000000000..289710955
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.0)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CTestCommandLine/LabelCount-stdout.txt b/Tests/RunCMake/CTestCommandLine/LabelCount-stdout.txt
new file mode 100644
index 000000000..7fe04eb6a
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/LabelCount-stdout.txt
@@ -0,0 +1,7 @@
+100% tests passed, 0 tests failed out of 4
++
++Label Time Summary:
++'bar' = +[0-9.]+ sec \(3 tests\)
++'foo' = +[0-9.]+ sec \(1 test\)
++
+Total Test time \(real\) = +[0-9.]+ sec
diff --git a/Tests/RunCMake/CTestCommandLine/MergeOutput-stdout.txt b/Tests/RunCMake/CTestCommandLine/MergeOutput-stdout.txt
new file mode 100644
index 000000000..af7cdc570
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/MergeOutput-stdout.txt
@@ -0,0 +1,13 @@
+Test timeout computed to be: [^
+]+
+1: -- Output on stdout
+1: Output on stderr
+1: -- Output on stdout
+1: Output on stderr
+1: -- Output on stdout
+1: Output on stderr
+1: -- Output on stdout
+1: Output on stderr
+1: -- Output on stdout
+1: Output on stderr
+1/1 Test #1: MergeOutput
diff --git a/Tests/RunCMake/CTestCommandLine/MergeOutput.cmake b/Tests/RunCMake/CTestCommandLine/MergeOutput.cmake
new file mode 100644
index 000000000..528ac9014
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/MergeOutput.cmake
@@ -0,0 +1,4 @@
+foreach(i RANGE 1 5)
+ message(STATUS "Output on stdout")
+ message("Output on stderr")
+endforeach()
diff --git a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
new file mode 100644
index 000000000..2bc3693b7
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
@@ -0,0 +1,142 @@
+include(RunCMake)
+set(RunCMake_TEST_TIMEOUT 60)
+
+unset(ENV{CTEST_PARALLEL_LEVEL})
+unset(ENV{CTEST_OUTPUT_ON_FAILURE})
+
+run_cmake_command(repeat-until-fail-bad1
+ ${CMAKE_CTEST_COMMAND} --repeat-until-fail
+ )
+run_cmake_command(repeat-until-fail-bad2
+ ${CMAKE_CTEST_COMMAND} --repeat-until-fail foo
+ )
+run_cmake_command(repeat-until-fail-good
+ ${CMAKE_CTEST_COMMAND} --repeat-until-fail 2
+ )
+
+function(run_repeat_until_fail_tests)
+ # Use a single build tree for a few tests without cleaning.
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/repeat-until-fail-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+ run_cmake(repeat-until-fail-cmake)
+ run_cmake_command(repeat-until-fail-ctest
+ ${CMAKE_CTEST_COMMAND} -C Debug --repeat-until-fail 3
+ )
+endfunction()
+run_repeat_until_fail_tests()
+
+function(run_BadCTestTestfile)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/BadCTestTestfile)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ file(WRITE "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" "
+subdirs()
+")
+
+ run_cmake_command(BadCTestTestfile ${CMAKE_CTEST_COMMAND})
+endfunction()
+run_BadCTestTestfile()
+
+function(run_MergeOutput)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/MergeOutput)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ file(WRITE "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" "
+add_test(MergeOutput \"${CMAKE_COMMAND}\" -P \"${RunCMake_SOURCE_DIR}/MergeOutput.cmake\")
+")
+
+ run_cmake_command(MergeOutput ${CMAKE_CTEST_COMMAND} -V)
+endfunction()
+run_MergeOutput()
+
+function(run_LabelCount)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/LabelCount)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ file(WRITE "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" "
+add_test(test1 \"${CMAKE_COMMAND}\" -E echo \"test1\")
+set_tests_properties(test1 PROPERTIES LABELS 'bar')
+
+add_test(test2 \"${CMAKE_COMMAND}\" -E echo \"test2\")
+set_tests_properties(test2 PROPERTIES LABELS 'bar')
+
+add_test(test3 \"${CMAKE_COMMAND}\" -E echo \"test3\")
+set_tests_properties(test3 PROPERTIES LABELS 'foo')
+
+add_test(test4 \"${CMAKE_COMMAND}\" -E echo \"test4\")
+set_tests_properties(test4 PROPERTIES LABELS 'bar')
+")
+
+ run_cmake_command(LabelCount ${CMAKE_CTEST_COMMAND} -V)
+endfunction()
+
+run_LabelCount()
+
+function(run_SerialFailed)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SerialFailed)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ file(WRITE "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" "
+add_test(NoSuchCommand no_such_command)
+set_tests_properties(NoSuchCommand PROPERTIES RUN_SERIAL ON)
+add_test(Echo \"${CMAKE_COMMAND}\" -E echo \"EchoTest\")
+")
+
+ run_cmake_command(SerialFailed ${CMAKE_CTEST_COMMAND} -V)
+endfunction()
+run_SerialFailed()
+
+function(run_TestLoad name load)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/TestLoad)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ file(WRITE "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" "
+ add_test(TestLoad1 \"${CMAKE_COMMAND}\" -E echo \"test of --test-load\")
+ add_test(TestLoad2 \"${CMAKE_COMMAND}\" -E echo \"test of --test-load\")
+")
+ run_cmake_command(${name} ${CMAKE_CTEST_COMMAND} -j2 --test-load ${load} --test-timeout 5)
+endfunction()
+
+# Tests for the --test-load feature of ctest
+#
+# Spoof a load average value to make these tests more reliable.
+set(ENV{__CTEST_FAKE_LOAD_AVERAGE_FOR_TESTING} 5)
+
+# Verify that new tests are not started when the load average exceeds
+# our threshold.
+run_TestLoad(test-load-fail 2)
+
+# Verify that warning message is displayed but tests still start when
+# an invalid argument is given.
+run_TestLoad(test-load-invalid 'two')
+
+# Verify that new tests are started when the load average falls below
+# our threshold.
+run_TestLoad(test-load-pass 10)
+
+unset(ENV{__CTEST_FAKE_LOAD_AVERAGE_FOR_TESTING})
+
+function(run_TestOutputSize)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/TestOutputSize)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ file(WRITE "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" "
+ add_test(PassingTest \"${CMAKE_COMMAND}\" -E echo PassingTestOutput)
+ add_test(FailingTest \"${CMAKE_COMMAND}\" -E no_such_command)
+")
+ run_cmake_command(TestOutputSize
+ ${CMAKE_CTEST_COMMAND} -M Experimental -T Test
+ --test-output-size-passed 10
+ --test-output-size-failed 12
+ )
+endfunction()
+run_TestOutputSize()
diff --git a/Tests/RunCMake/CTestCommandLine/SerialFailed-result.txt b/Tests/RunCMake/CTestCommandLine/SerialFailed-result.txt
new file mode 100644
index 000000000..45a4fb75d
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/SerialFailed-result.txt
@@ -0,0 +1 @@
+8
diff --git a/Tests/RunCMake/CTestCommandLine/SerialFailed-stderr.txt b/Tests/RunCMake/CTestCommandLine/SerialFailed-stderr.txt
new file mode 100644
index 000000000..cafe56591
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/SerialFailed-stderr.txt
@@ -0,0 +1 @@
+Unable to find executable: no_such_command
diff --git a/Tests/RunCMake/CTestCommandLine/SerialFailed-stdout.txt b/Tests/RunCMake/CTestCommandLine/SerialFailed-stdout.txt
new file mode 100644
index 000000000..d7144f735
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/SerialFailed-stdout.txt
@@ -0,0 +1,10 @@
+Could not find executable no_such_command
+.*
+2/2 Test #2: Echo ............................. Passed +[0-9.]+ sec
++
+50% tests passed, 1 tests failed out of 2
++
+Total Test time \(real\) = +[0-9.]+ sec
++
+The following tests FAILED:
+[ ]+1 - NoSuchCommand \(Not Run\)$
diff --git a/Tests/RunCMake/CTestCommandLine/TestOutputSize-check.cmake b/Tests/RunCMake/CTestCommandLine/TestOutputSize-check.cmake
new file mode 100644
index 000000000..918d242aa
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/TestOutputSize-check.cmake
@@ -0,0 +1,17 @@
+file(GLOB test_xml_file "${RunCMake_TEST_BINARY_DIR}/Testing/*/Test.xml")
+if(test_xml_file)
+ file(READ "${test_xml_file}" test_xml LIMIT 4096)
+ if("${test_xml}" MATCHES [[(<Test Status="passed">.*</Test>).*(<Test Status="failed">.*</Test>)]])
+ set(test_passed "${CMAKE_MATCH_1}")
+ set(test_failed "${CMAKE_MATCH_2}")
+ else()
+ set(RunCMake_TEST_FAILED "Test.xml does not contain a passed then failed test:\n ${test_xml}")
+ endif()
+ if(NOT "${test_passed}" MATCHES [[<Value>PassingTes\.\.\..*10 bytes]])
+ set(RunCMake_TEST_FAILED "Test.xml passed test output not truncated at 10 bytes:\n ${test_passed}")
+ elseif(NOT "${test_failed}" MATCHES [[<Value>CMake Error:\.\.\..*12 bytes]])
+ set(RunCMake_TEST_FAILED "Test.xml failed test output not truncated at 12 bytes:\n ${test_failed}")
+ endif()
+else()
+ set(RunCMake_TEST_FAILED "Test.xml not found")
+endif()
diff --git a/Tests/RunCMake/CTestCommandLine/TestOutputSize-result.txt b/Tests/RunCMake/CTestCommandLine/TestOutputSize-result.txt
new file mode 100644
index 000000000..9c558e357
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/TestOutputSize-result.txt
@@ -0,0 +1 @@
+.
diff --git a/Tests/RunCMake/CTestCommandLine/TestOutputSize-stderr.txt b/Tests/RunCMake/CTestCommandLine/TestOutputSize-stderr.txt
new file mode 100644
index 000000000..ba4235def
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/TestOutputSize-stderr.txt
@@ -0,0 +1 @@
+Errors while running CTest
diff --git a/Tests/RunCMake/CTestCommandLine/init.cmake b/Tests/RunCMake/CTestCommandLine/init.cmake
new file mode 100644
index 000000000..a900f675c
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/init.cmake
@@ -0,0 +1,3 @@
+# This is run by test initialization in repeat-until-fail-cmake.cmake
+# with cmake -P. It creates TEST_OUTPUT_FILE with a 0 in it.
+file(WRITE "${TEST_OUTPUT_FILE}" "0")
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-fail-bad1-result.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-bad1-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-bad1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-fail-bad1-stderr.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-bad1-stderr.txt
new file mode 100644
index 000000000..5ea8816e9
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-bad1-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: '--repeat-until-fail' requires an argument$
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-fail-bad2-result.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-bad2-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-bad2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-fail-bad2-stderr.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-bad2-stderr.txt
new file mode 100644
index 000000000..a79faaef5
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-bad2-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: '--repeat-until-fail' given non-integer value 'foo'$
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-fail-cmake.cmake b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-cmake.cmake
new file mode 100644
index 000000000..465441645
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-cmake.cmake
@@ -0,0 +1,15 @@
+enable_testing()
+
+set(TEST_OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/test_output.txt")
+add_test(NAME initialization
+ COMMAND ${CMAKE_COMMAND}
+ "-DTEST_OUTPUT_FILE=${TEST_OUTPUT_FILE}"
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/init.cmake")
+add_test(NAME test1
+ COMMAND ${CMAKE_COMMAND}
+ "-DTEST_OUTPUT_FILE=${TEST_OUTPUT_FILE}"
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/test1.cmake")
+set_tests_properties(test1 PROPERTIES DEPENDS "initialization")
+
+add_test(hello ${CMAKE_COMMAND} -E echo hello)
+add_test(goodbye ${CMAKE_COMMAND} -E echo goodbye)
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-fail-ctest-result.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-ctest-result.txt
new file mode 100644
index 000000000..45a4fb75d
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-ctest-result.txt
@@ -0,0 +1 @@
+8
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-fail-ctest-stderr.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-ctest-stderr.txt
new file mode 100644
index 000000000..759378390
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-ctest-stderr.txt
@@ -0,0 +1 @@
+^Errors while running CTest$
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-fail-ctest-stdout.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-ctest-stdout.txt
new file mode 100644
index 000000000..6e133cdce
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-ctest-stdout.txt
@@ -0,0 +1,30 @@
+^Test project .*/Tests/RunCMake/CTestCommandLine/repeat-until-fail-build
+ Start 1: initialization
+ Test #1: initialization ................... Passed +[0-9.]+ sec
+ Start 1: initialization
+ Test #1: initialization ................... Passed +[0-9.]+ sec
+ Start 1: initialization
+1/4 Test #1: initialization ................... Passed +[0-9.]+ sec
+ Start 2: test1
+ Test #2: test1 ............................ Passed +[0-9.]+ sec
+ Start 2: test1
+ Test #2: test1 ............................\*\*\*Failed +[0-9.]+ sec
+ Start 3: hello
+ Test #3: hello ............................ Passed +[0-9.]+ sec
+ Start 3: hello
+ Test #3: hello ............................ Passed +[0-9.]+ sec
+ Start 3: hello
+3/4 Test #3: hello ............................ Passed +[0-9.]+ sec
+ Start 4: goodbye
+ Test #4: goodbye .......................... Passed +[0-9.]+ sec
+ Start 4: goodbye
+ Test #4: goodbye .......................... Passed +[0-9.]+ sec
+ Start 4: goodbye
+4/4 Test #4: goodbye .......................... Passed +[0-9.]+ sec
++
+75% tests passed, 1 tests failed out of 4
++
+Total Test time \(real\) = +[0-9.]+ sec
++
+The following tests FAILED:
+[ ]+2 - test1 \(Failed\)$
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-fail-good-stderr.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-good-stderr.txt
new file mode 100644
index 000000000..a7c4b11f7
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-good-stderr.txt
@@ -0,0 +1 @@
+^No tests were found!!!$
diff --git a/Tests/RunCMake/CTestCommandLine/test-load-fail-stderr.txt b/Tests/RunCMake/CTestCommandLine/test-load-fail-stderr.txt
new file mode 100644
index 000000000..eafba1c69
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/test-load-fail-stderr.txt
@@ -0,0 +1 @@
+No tests were found!!!
diff --git a/Tests/RunCMake/CTestCommandLine/test-load-fail-stdout.txt b/Tests/RunCMake/CTestCommandLine/test-load-fail-stdout.txt
new file mode 100644
index 000000000..153da09fb
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/test-load-fail-stdout.txt
@@ -0,0 +1,2 @@
+^Test project .*/Tests/RunCMake/CTestCommandLine/TestLoad
+\*\*\*\*\* WAITING, System Load: 5, Max Allowed Load: 2, Smallest test TestLoad[1-2] requires 1\*\*\*\*\*
diff --git a/Tests/RunCMake/CTestCommandLine/test-load-invalid-stderr.txt b/Tests/RunCMake/CTestCommandLine/test-load-invalid-stderr.txt
new file mode 100644
index 000000000..caab3b9b7
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/test-load-invalid-stderr.txt
@@ -0,0 +1 @@
+Invalid value for 'Test Load' : 'two'
diff --git a/Tests/RunCMake/CTestCommandLine/test-load-invalid-stdout.txt b/Tests/RunCMake/CTestCommandLine/test-load-invalid-stdout.txt
new file mode 100644
index 000000000..7ee3daee1
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/test-load-invalid-stdout.txt
@@ -0,0 +1,7 @@
+^Test project .*/Tests/RunCMake/CTestCommandLine/TestLoad
+ Start 1: TestLoad1
+ Start 2: TestLoad2
+1/2 Test #[1-2]: TestLoad[1-2] ........................ Passed +[0-9.]+ sec
+2/2 Test #[1-2]: TestLoad[1-2] ........................ Passed +[0-9.]+ sec
++
+100% tests passed, 0 tests failed out of 2
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-exe-stderr.txt b/Tests/RunCMake/CTestCommandLine/test-load-pass-stderr.txt
index 10f32932e..10f32932e 100644
--- a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-exe-stderr.txt
+++ b/Tests/RunCMake/CTestCommandLine/test-load-pass-stderr.txt
diff --git a/Tests/RunCMake/CTestCommandLine/test-load-pass-stdout.txt b/Tests/RunCMake/CTestCommandLine/test-load-pass-stdout.txt
new file mode 100644
index 000000000..7ee3daee1
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/test-load-pass-stdout.txt
@@ -0,0 +1,7 @@
+^Test project .*/Tests/RunCMake/CTestCommandLine/TestLoad
+ Start 1: TestLoad1
+ Start 2: TestLoad2
+1/2 Test #[1-2]: TestLoad[1-2] ........................ Passed +[0-9.]+ sec
+2/2 Test #[1-2]: TestLoad[1-2] ........................ Passed +[0-9.]+ sec
++
+100% tests passed, 0 tests failed out of 2
diff --git a/Tests/RunCMake/CTestCommandLine/test1.cmake b/Tests/RunCMake/CTestCommandLine/test1.cmake
new file mode 100644
index 000000000..eeae7a204
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/test1.cmake
@@ -0,0 +1,13 @@
+# This is run by test test1 in repeat-until-fail-cmake.cmake with cmake -P.
+# It reads the file TEST_OUTPUT_FILE and increments the number
+# found in the file by 1. When the number is 2, then the
+# code sends out a cmake error causing the test to fail
+# the second time it is run.
+message("TEST_OUTPUT_FILE = ${TEST_OUTPUT_FILE}")
+file(READ "${TEST_OUTPUT_FILE}" COUNT)
+message("COUNT= ${COUNT}")
+math(EXPR COUNT "${COUNT} + 1")
+file(WRITE "${TEST_OUTPUT_FILE}" "${COUNT}")
+if(${COUNT} EQUAL 2)
+ message(FATAL_ERROR "this test fails on the 2nd run")
+endif()
diff --git a/Tests/RunCMake/CheckModules/CMakeLists.txt b/Tests/RunCMake/CheckModules/CMakeLists.txt
new file mode 100644
index 000000000..9872df2a1
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.11)
+cmake_policy(SET CMP0054 NEW)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CheckModules/CheckStructHasMemberMissingKey-result.txt b/Tests/RunCMake/CheckModules/CheckStructHasMemberMissingKey-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckStructHasMemberMissingKey-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CheckModules/CheckStructHasMemberMissingKey-stderr.txt b/Tests/RunCMake/CheckModules/CheckStructHasMemberMissingKey-stderr.txt
new file mode 100644
index 000000000..1b8603a83
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckStructHasMemberMissingKey-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at .*/Modules/CheckStructHasMember.cmake:[0-9]+. \(message\):
+ Unknown arguments:
+
+ C
+
+Call Stack \(most recent call first\):
+ CheckStructHasMemberMissingKey.cmake:[0-9]+ \(check_struct_has_member\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/CheckModules/CheckStructHasMemberMissingKey.cmake b/Tests/RunCMake/CheckModules/CheckStructHasMemberMissingKey.cmake
new file mode 100644
index 000000000..49f51ceca
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckStructHasMemberMissingKey.cmake
@@ -0,0 +1,2 @@
+include(CheckStructHasMember)
+check_struct_has_member("struct timeval" tv_sec sys/select.h HAVE_TIMEVAL_TV_SEC_K C)
diff --git a/Tests/RunCMake/CheckModules/CheckStructHasMemberMissingLanguage-result.txt b/Tests/RunCMake/CheckModules/CheckStructHasMemberMissingLanguage-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckStructHasMemberMissingLanguage-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CheckModules/CheckStructHasMemberMissingLanguage-stderr.txt b/Tests/RunCMake/CheckModules/CheckStructHasMemberMissingLanguage-stderr.txt
new file mode 100644
index 000000000..8fceab0df
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckStructHasMemberMissingLanguage-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at .*/Modules/CheckStructHasMember.cmake:[0-9]+. \(message\):
+ Unknown arguments:
+
+ LANGUAGE
+
+Call Stack \(most recent call first\):
+ CheckStructHasMemberMissingLanguage.cmake:[0-9]+ \(check_struct_has_member\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/CheckModules/CheckStructHasMemberMissingLanguage.cmake b/Tests/RunCMake/CheckModules/CheckStructHasMemberMissingLanguage.cmake
new file mode 100644
index 000000000..b404d665b
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckStructHasMemberMissingLanguage.cmake
@@ -0,0 +1,2 @@
+include(CheckStructHasMember)
+check_struct_has_member("struct timeval" tv_sec sys/select.h HAVE_TIMEVAL_TV_SEC_K LANGUAGE)
diff --git a/Tests/RunCMake/CheckModules/CheckStructHasMemberOk.cmake b/Tests/RunCMake/CheckModules/CheckStructHasMemberOk.cmake
new file mode 100644
index 000000000..4c064c501
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckStructHasMemberOk.cmake
@@ -0,0 +1,6 @@
+enable_language(C)
+enable_language(CXX)
+include(CheckStructHasMember)
+check_struct_has_member("struct timeval" tv_sec sys/select.h HAVE_TIMEVAL_TV_SEC)
+check_struct_has_member("struct timeval" tv_sec sys/select.h HAVE_TIMEVAL_TV_SEC_C LANGUAGE C)
+check_struct_has_member("struct timeval" tv_sec sys/select.h HAVE_TIMEVAL_TV_SEC_CXX LANGUAGE CXX)
diff --git a/Tests/RunCMake/CheckModules/CheckStructHasMemberTooManyArguments-result.txt b/Tests/RunCMake/CheckModules/CheckStructHasMemberTooManyArguments-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckStructHasMemberTooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CheckModules/CheckStructHasMemberTooManyArguments-stderr.txt b/Tests/RunCMake/CheckModules/CheckStructHasMemberTooManyArguments-stderr.txt
new file mode 100644
index 000000000..459886744
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckStructHasMemberTooManyArguments-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at .*/Modules/CheckStructHasMember.cmake:[0-9]+. \(message\):
+ Unknown arguments:
+
+ LANGUAGE;C;CXX
+
+Call Stack \(most recent call first\):
+ CheckStructHasMemberTooManyArguments.cmake:[0-9]+ \(check_struct_has_member\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/CheckModules/CheckStructHasMemberTooManyArguments.cmake b/Tests/RunCMake/CheckModules/CheckStructHasMemberTooManyArguments.cmake
new file mode 100644
index 000000000..12f81582d
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckStructHasMemberTooManyArguments.cmake
@@ -0,0 +1,2 @@
+include(CheckStructHasMember)
+check_struct_has_member("struct timeval" tv_sec sys/select.h HAVE_TIMEVAL_TV_SEC_K LANGUAGE C CXX)
diff --git a/Tests/RunCMake/CheckModules/CheckStructHasMemberUnknownLanguage-result.txt b/Tests/RunCMake/CheckModules/CheckStructHasMemberUnknownLanguage-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckStructHasMemberUnknownLanguage-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CheckModules/CheckStructHasMemberUnknownLanguage-stderr.txt b/Tests/RunCMake/CheckModules/CheckStructHasMemberUnknownLanguage-stderr.txt
new file mode 100644
index 000000000..ba9e31312
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckStructHasMemberUnknownLanguage-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error at .*/Modules/CheckStructHasMember.cmake:[0-9]+. \(message\):
+ Unknown language:
+
+ FORTRAN
+
+ Supported languages: C, CXX.
+
+Call Stack \(most recent call first\):
+ CheckStructHasMemberUnknownLanguage.cmake:[0-9]+ \(check_struct_has_member\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/CheckModules/CheckStructHasMemberUnknownLanguage.cmake b/Tests/RunCMake/CheckModules/CheckStructHasMemberUnknownLanguage.cmake
new file mode 100644
index 000000000..183058ddc
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckStructHasMemberUnknownLanguage.cmake
@@ -0,0 +1,2 @@
+include(CheckStructHasMember)
+check_struct_has_member("struct timeval" tv_sec sys/select.h HAVE_TIMEVAL_TV_SEC_K LANGUAGE FORTRAN)
diff --git a/Tests/RunCMake/CheckModules/CheckStructHasMemberWrongKey-result.txt b/Tests/RunCMake/CheckModules/CheckStructHasMemberWrongKey-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckStructHasMemberWrongKey-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CheckModules/CheckStructHasMemberWrongKey-stderr.txt b/Tests/RunCMake/CheckModules/CheckStructHasMemberWrongKey-stderr.txt
new file mode 100644
index 000000000..b9fbd38cf
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckStructHasMemberWrongKey-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at .*/Modules/CheckStructHasMember.cmake:[0-9]+. \(message\):
+ Unknown arguments:
+
+ LANGUAG;C
+
+Call Stack \(most recent call first\):
+ CheckStructHasMemberWrongKey.cmake:[0-9]+ \(check_struct_has_member\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/CheckModules/CheckStructHasMemberWrongKey.cmake b/Tests/RunCMake/CheckModules/CheckStructHasMemberWrongKey.cmake
new file mode 100644
index 000000000..900eb0a75
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckStructHasMemberWrongKey.cmake
@@ -0,0 +1,2 @@
+include(CheckStructHasMember)
+check_struct_has_member("struct timeval" tv_sec sys/select.h HAVE_TIMEVAL_TV_SEC_K LANGUAG C)
diff --git a/Tests/RunCMake/CheckModules/CheckTypeSizeMissingLanguage-result.txt b/Tests/RunCMake/CheckModules/CheckTypeSizeMissingLanguage-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckTypeSizeMissingLanguage-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CheckModules/CheckTypeSizeMissingLanguage-stderr.txt b/Tests/RunCMake/CheckModules/CheckTypeSizeMissingLanguage-stderr.txt
new file mode 100644
index 000000000..07ec8e6a4
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckTypeSizeMissingLanguage-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at .*/Modules/CheckTypeSize.cmake:[0-9]+ \(message\):
+ Missing argument:
+
+ LANGUAGE arguments requires a value
+
+Call Stack \(most recent call first\):
+ CheckTypeSizeMissingLanguage.cmake:[0-9]+ \(check_type_size\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/CheckModules/CheckTypeSizeMissingLanguage.cmake b/Tests/RunCMake/CheckModules/CheckTypeSizeMissingLanguage.cmake
new file mode 100644
index 000000000..3fae6c4db
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckTypeSizeMissingLanguage.cmake
@@ -0,0 +1,2 @@
+include(CheckTypeSize)
+check_type_size(int SIZEOF_INT LANGUAGE)
diff --git a/Tests/RunCMake/CheckModules/CheckTypeSizeMixedArgs-result.txt b/Tests/RunCMake/CheckModules/CheckTypeSizeMixedArgs-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckTypeSizeMixedArgs-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CheckModules/CheckTypeSizeMixedArgs-stderr.txt b/Tests/RunCMake/CheckModules/CheckTypeSizeMixedArgs-stderr.txt
new file mode 100644
index 000000000..a2d2fc041
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckTypeSizeMixedArgs-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error at .*/Modules/CheckTypeSize.cmake:[0-9]+. \(message\):
+ Unknown language:
+
+ .
+
+ Supported languages: C, CXX.
+
+Call Stack \(most recent call first\):
+ CheckTypeSizeMixedArgs.cmake:[0-9]+ \(check_type_size\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/CheckModules/CheckTypeSizeMixedArgs.cmake b/Tests/RunCMake/CheckModules/CheckTypeSizeMixedArgs.cmake
new file mode 100644
index 000000000..d2ccc0fad
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckTypeSizeMixedArgs.cmake
@@ -0,0 +1,2 @@
+include(CheckTypeSize)
+check_type_size(int SIZEOF_INT LANGUAGE BUILTIN_TYPES_ONLY)
diff --git a/Tests/RunCMake/CheckModules/CheckTypeSizeOk.cmake b/Tests/RunCMake/CheckModules/CheckTypeSizeOk.cmake
new file mode 100644
index 000000000..45a4978fc
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckTypeSizeOk.cmake
@@ -0,0 +1,12 @@
+enable_language(C)
+enable_language(CXX)
+include(CheckTypeSize)
+check_type_size(int SIZEOF_INT)
+check_type_size(int SIZEOF_INT BUILTIN_TYPES_ONLY)
+check_type_size(int SIZEOF_INT LANGUAGE C)
+check_type_size(int SIZEOF_INT LANGUAGE CXX)
+check_type_size(int SIZEOF_INT BUILTIN_TYPES_ONLY LANGUAGE C)
+
+# Weird but ok... only last value is considered
+check_type_size(int SIZEOF_INT BUILTIN_TYPES_ONLY BUILTIN_TYPES_ONLY)
+check_type_size(int SIZEOF_INT LANGUAGE C LANGUAGE CXX)
diff --git a/Tests/RunCMake/CheckModules/CheckTypeSizeOkNoC.cmake b/Tests/RunCMake/CheckModules/CheckTypeSizeOkNoC.cmake
new file mode 100644
index 000000000..b2dcd7f9b
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckTypeSizeOkNoC.cmake
@@ -0,0 +1,4 @@
+enable_language(CXX)
+include(CheckTypeSize)
+check_type_size(int SIZEOF_INT LANGUAGE CXX)
+check_type_size(int SIZEOF_INT BUILTIN_TYPES_ONLY LANGUAGE CXX)
diff --git a/Tests/RunCMake/CheckModules/CheckTypeSizeUnknownArgument-result.txt b/Tests/RunCMake/CheckModules/CheckTypeSizeUnknownArgument-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckTypeSizeUnknownArgument-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CheckModules/CheckTypeSizeUnknownArgument-stderr.txt b/Tests/RunCMake/CheckModules/CheckTypeSizeUnknownArgument-stderr.txt
new file mode 100644
index 000000000..085488e73
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckTypeSizeUnknownArgument-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at .*/Modules/CheckTypeSize.cmake:[0-9]+. \(message\):
+ Unknown argument:
+
+ LANGUAG
+
+Call Stack \(most recent call first\):
+ CheckTypeSizeUnknownArgument.cmake:[0-9]+ \(check_type_size\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/CheckModules/CheckTypeSizeUnknownArgument.cmake b/Tests/RunCMake/CheckModules/CheckTypeSizeUnknownArgument.cmake
new file mode 100644
index 000000000..6f24ee16c
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckTypeSizeUnknownArgument.cmake
@@ -0,0 +1,2 @@
+include(CheckTypeSize)
+check_type_size(int SIZEOF_INT BUILTIN_TYPES_ONLY LANGUAG CXX)
diff --git a/Tests/RunCMake/CheckModules/CheckTypeSizeUnknownLanguage-result.txt b/Tests/RunCMake/CheckModules/CheckTypeSizeUnknownLanguage-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckTypeSizeUnknownLanguage-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CheckModules/CheckTypeSizeUnknownLanguage-stderr.txt b/Tests/RunCMake/CheckModules/CheckTypeSizeUnknownLanguage-stderr.txt
new file mode 100644
index 000000000..502a7172c
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckTypeSizeUnknownLanguage-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error at .*/Modules/CheckTypeSize.cmake:[0-9]+. \(message\):
+ Unknown language:
+
+ FORTRAN.
+
+ Supported languages: C, CXX.
+
+Call Stack \(most recent call first\):
+ CheckTypeSizeUnknownLanguage.cmake:[0-9]+ \(check_type_size\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/CheckModules/CheckTypeSizeUnknownLanguage.cmake b/Tests/RunCMake/CheckModules/CheckTypeSizeUnknownLanguage.cmake
new file mode 100644
index 000000000..2d5184cd6
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/CheckTypeSizeUnknownLanguage.cmake
@@ -0,0 +1,2 @@
+include(CheckTypeSize)
+check_type_size(int SIZEOF_INT LANGUAGE FORTRAN)
diff --git a/Tests/RunCMake/CheckModules/RunCMakeTest.cmake b/Tests/RunCMake/CheckModules/RunCMakeTest.cmake
new file mode 100644
index 000000000..5b4e57edc
--- /dev/null
+++ b/Tests/RunCMake/CheckModules/RunCMakeTest.cmake
@@ -0,0 +1,16 @@
+include(RunCMake)
+
+run_cmake(CheckStructHasMemberOk)
+run_cmake(CheckStructHasMemberUnknownLanguage)
+run_cmake(CheckStructHasMemberMissingLanguage)
+run_cmake(CheckStructHasMemberMissingKey)
+run_cmake(CheckStructHasMemberTooManyArguments)
+run_cmake(CheckStructHasMemberWrongKey)
+
+run_cmake(CheckTypeSizeOk)
+run_cmake(CheckTypeSizeUnknownLanguage)
+run_cmake(CheckTypeSizeMissingLanguage)
+run_cmake(CheckTypeSizeUnknownArgument)
+run_cmake(CheckTypeSizeMixedArgs)
+
+run_cmake(CheckTypeSizeOkNoC)
diff --git a/Tests/RunCMake/CommandLine/Build-ninja-v-stdout.txt b/Tests/RunCMake/CommandLine/Build-ninja-v-stdout.txt
new file mode 100644
index 000000000..83c62ec99
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Build-ninja-v-stdout.txt
@@ -0,0 +1 @@
+-E echo CustomCommand
diff --git a/Tests/RunCMake/CommandLine/Build.cmake b/Tests/RunCMake/CommandLine/Build.cmake
new file mode 100644
index 000000000..20df108ef
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Build.cmake
@@ -0,0 +1,5 @@
+add_custom_command(
+ OUTPUT output.txt
+ COMMAND ${CMAKE_COMMAND} -E echo CustomCommand > output.txt
+ )
+add_custom_target(CustomTarget ALL DEPENDS output.txt)
diff --git a/Tests/RunCMake/CommandLine/BuildDir.cmake b/Tests/RunCMake/CommandLine/BuildDir.cmake
new file mode 100644
index 000000000..30030a783
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/BuildDir.cmake
@@ -0,0 +1 @@
+add_subdirectory(BuildDir)
diff --git a/Tests/RunCMake/CommandLine/BuildDir/CMakeLists.txt b/Tests/RunCMake/CommandLine/BuildDir/CMakeLists.txt
new file mode 100644
index 000000000..20df108ef
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/BuildDir/CMakeLists.txt
@@ -0,0 +1,5 @@
+add_custom_command(
+ OUTPUT output.txt
+ COMMAND ${CMAKE_COMMAND} -E echo CustomCommand > output.txt
+ )
+add_custom_target(CustomTarget ALL DEPENDS output.txt)
diff --git a/Tests/RunCMake/CommandLine/C-no-arg-result.txt b/Tests/RunCMake/CommandLine/C-no-arg-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/C-no-arg-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/C-no-arg-stderr.txt b/Tests/RunCMake/CommandLine/C-no-arg-stderr.txt
new file mode 100644
index 000000000..0570d8fca
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/C-no-arg-stderr.txt
@@ -0,0 +1,2 @@
+^CMake Error: -C must be followed by a file name.
+CMake Error: Problem processing arguments. Aborting.$
diff --git a/Tests/RunCMake/CommandLine/C-no-file-result.txt b/Tests/RunCMake/CommandLine/C-no-file-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/C-no-file-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/C-no-file-stderr.txt b/Tests/RunCMake/CommandLine/C-no-file-stderr.txt
new file mode 100644
index 000000000..5315f5904
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/C-no-file-stderr.txt
@@ -0,0 +1,3 @@
+^CMake Error: Error processing file: nosuchcachefile.txt
+CMake Error: The source directory ".*/Tests/RunCMake/CommandLine/C-no-file-build/nosuchcachefile.txt" does not exist.
+Specify --help for usage, or press the help button on the CMake GUI.$
diff --git a/Tests/RunCMake/CommandLine/CMakeLists.txt b/Tests/RunCMake/CommandLine/CMakeLists.txt
new file mode 100644
index 000000000..289710955
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.0)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CommandLine/D-no-arg-result.txt b/Tests/RunCMake/CommandLine/D-no-arg-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/D-no-arg-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/D-no-arg-stderr.txt b/Tests/RunCMake/CommandLine/D-no-arg-stderr.txt
new file mode 100644
index 000000000..5e43bcace
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/D-no-arg-stderr.txt
@@ -0,0 +1,2 @@
+^CMake Error: -D must be followed with VAR=VALUE.
+CMake Error: Problem processing arguments. Aborting.$
diff --git a/Tests/RunCMake/CommandLine/D_nested_cache-stderr.txt b/Tests/RunCMake/CommandLine/D_nested_cache-stderr.txt
new file mode 100644
index 000000000..bba64bcbd
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/D_nested_cache-stderr.txt
@@ -0,0 +1 @@
+^-->-DBAR:BOOL=BAZ<--$
diff --git a/Tests/RunCMake/CommandLine/D_nested_cache.cmake b/Tests/RunCMake/CommandLine/D_nested_cache.cmake
new file mode 100644
index 000000000..9b572840e
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/D_nested_cache.cmake
@@ -0,0 +1 @@
+message("-->${FOO}<--")
diff --git a/Tests/RunCMake/CommandLine/D_typed_nested_cache-stderr.txt b/Tests/RunCMake/CommandLine/D_typed_nested_cache-stderr.txt
new file mode 100644
index 000000000..bba64bcbd
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/D_typed_nested_cache-stderr.txt
@@ -0,0 +1 @@
+^-->-DBAR:BOOL=BAZ<--$
diff --git a/Tests/RunCMake/CommandLine/D_typed_nested_cache.cmake b/Tests/RunCMake/CommandLine/D_typed_nested_cache.cmake
new file mode 100644
index 000000000..9b572840e
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/D_typed_nested_cache.cmake
@@ -0,0 +1 @@
+message("-->${FOO}<--")
diff --git a/Tests/RunCMake/CommandLine/DeprecateVS6-WARN-OFF.cmake b/Tests/RunCMake/CommandLine/DeprecateVS6-WARN-OFF.cmake
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/DeprecateVS6-WARN-OFF.cmake
diff --git a/Tests/RunCMake/CommandLine/DeprecateVS6-WARN-ON-stderr.txt b/Tests/RunCMake/CommandLine/DeprecateVS6-WARN-ON-stderr.txt
new file mode 100644
index 000000000..1b6a51052
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/DeprecateVS6-WARN-ON-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Warning:
+ The "Visual Studio 6" generator is deprecated and will be removed in a
+ future version of CMake.
+
+ Add CMAKE_WARN_VS6=OFF to the cache to disable this warning.$
diff --git a/Tests/RunCMake/CommandLine/DeprecateVS6-WARN-ON.cmake b/Tests/RunCMake/CommandLine/DeprecateVS6-WARN-ON.cmake
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/DeprecateVS6-WARN-ON.cmake
diff --git a/Tests/RunCMake/CommandLine/DeprecateVS70-WARN-OFF.cmake b/Tests/RunCMake/CommandLine/DeprecateVS70-WARN-OFF.cmake
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/DeprecateVS70-WARN-OFF.cmake
diff --git a/Tests/RunCMake/CommandLine/DeprecateVS70-WARN-ON-stderr.txt b/Tests/RunCMake/CommandLine/DeprecateVS70-WARN-ON-stderr.txt
new file mode 100644
index 000000000..ea31ef315
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/DeprecateVS70-WARN-ON-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Warning:
+ The "Visual Studio 7" generator is deprecated and will be removed in a
+ future version of CMake.
+
+ Add CMAKE_WARN_VS70=OFF to the cache to disable this warning.$
diff --git a/Tests/RunCMake/CommandLine/DeprecateVS70-WARN-ON.cmake b/Tests/RunCMake/CommandLine/DeprecateVS70-WARN-ON.cmake
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/DeprecateVS70-WARN-ON.cmake
diff --git a/Tests/RunCMake/CommandLine/E-no-arg-result.txt b/Tests/RunCMake/CommandLine/E-no-arg-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E-no-arg-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E-no-arg-stderr.txt b/Tests/RunCMake/CommandLine/E-no-arg-stderr.txt
new file mode 100644
index 000000000..50d9b0332
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E-no-arg-stderr.txt
@@ -0,0 +1,3 @@
+^CMake Error: cmake version .*
+Usage: .* -E <command> \[arguments\.\.\.\]
+Available commands:
diff --git a/Tests/RunCMake/CommandLine/E___run_iwyu-bad-iwyu-result.txt b/Tests/RunCMake/CommandLine/E___run_iwyu-bad-iwyu-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E___run_iwyu-bad-iwyu-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E___run_iwyu-bad-iwyu-stderr.txt b/Tests/RunCMake/CommandLine/E___run_iwyu-bad-iwyu-stderr.txt
new file mode 100644
index 000000000..338f7c4e6
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E___run_iwyu-bad-iwyu-stderr.txt
@@ -0,0 +1,2 @@
+^Error running 'iwyu-does-not-exist': [^
+]+$
diff --git a/Tests/RunCMake/CommandLine/E___run_iwyu-no----result.txt b/Tests/RunCMake/CommandLine/E___run_iwyu-no----result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E___run_iwyu-no----result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E___run_iwyu-no----stderr.txt b/Tests/RunCMake/CommandLine/E___run_iwyu-no----stderr.txt
new file mode 100644
index 000000000..c251adf00
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E___run_iwyu-no----stderr.txt
@@ -0,0 +1 @@
+^__run_iwyu given unknown argument: command-does-not-exist$
diff --git a/Tests/RunCMake/CommandLine/E___run_iwyu-no-cc-result.txt b/Tests/RunCMake/CommandLine/E___run_iwyu-no-cc-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E___run_iwyu-no-cc-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E___run_iwyu-no-cc-stderr.txt b/Tests/RunCMake/CommandLine/E___run_iwyu-no-cc-stderr.txt
new file mode 100644
index 000000000..1998abb22
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E___run_iwyu-no-cc-stderr.txt
@@ -0,0 +1 @@
+^__run_iwyu missing compile command after --$
diff --git a/Tests/RunCMake/CommandLine/E___run_iwyu-no-iwyu-result.txt b/Tests/RunCMake/CommandLine/E___run_iwyu-no-iwyu-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E___run_iwyu-no-iwyu-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E___run_iwyu-no-iwyu-stderr.txt b/Tests/RunCMake/CommandLine/E___run_iwyu-no-iwyu-stderr.txt
new file mode 100644
index 000000000..002409748
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E___run_iwyu-no-iwyu-stderr.txt
@@ -0,0 +1 @@
+^__run_iwyu missing --iwyu=$
diff --git a/Tests/RunCMake/CommandLine/E_copy-one-source-directory-target-is-directory-result.txt b/Tests/RunCMake/CommandLine/E_copy-one-source-directory-target-is-directory-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_copy-one-source-directory-target-is-directory-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CommandLine/E_copy-one-source-directory-target-is-directory-stderr.txt b/Tests/RunCMake/CommandLine/E_copy-one-source-directory-target-is-directory-stderr.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_copy-one-source-directory-target-is-directory-stderr.txt
diff --git a/Tests/RunCMake/CommandLine/E_copy-one-source-file-result.txt b/Tests/RunCMake/CommandLine/E_copy-one-source-file-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_copy-one-source-file-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_copy-one-source-file-stderr.txt b/Tests/RunCMake/CommandLine/E_copy-one-source-file-stderr.txt
new file mode 100644
index 000000000..9a9301d9e
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_copy-one-source-file-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: .*
diff --git a/Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-directory-result.txt b/Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-directory-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-directory-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-directory-stderr.txt b/Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-directory-stderr.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-directory-stderr.txt
diff --git a/Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-file-result.txt b/Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-file-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-file-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-file-stderr.txt b/Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-file-stderr.txt
new file mode 100644
index 000000000..95042168f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-file-stderr.txt
@@ -0,0 +1 @@
+^Error: Target \(for copy command\).* is not a directory.$
diff --git a/Tests/RunCMake/CommandLine/E_copy-two-good-and-one-bad-source-files-target-is-directory-result.txt b/Tests/RunCMake/CommandLine/E_copy-two-good-and-one-bad-source-files-target-is-directory-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_copy-two-good-and-one-bad-source-files-target-is-directory-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_copy-two-good-and-one-bad-source-files-target-is-directory-stderr.txt b/Tests/RunCMake/CommandLine/E_copy-two-good-and-one-bad-source-files-target-is-directory-stderr.txt
new file mode 100644
index 000000000..2d0d98610
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_copy-two-good-and-one-bad-source-files-target-is-directory-stderr.txt
@@ -0,0 +1 @@
+^Error copying file .*not_existing_file.bad\" to .*
diff --git a/Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-directory-result.txt b/Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-directory-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-directory-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-directory-stderr.txt b/Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-directory-stderr.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-directory-stderr.txt
diff --git a/Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-file-result.txt b/Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-file-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-file-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-file-stderr.txt b/Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-file-stderr.txt
new file mode 100644
index 000000000..6ca367767
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-file-stderr.txt
@@ -0,0 +1,3 @@
+^Error copying directory from .* to .*file_for_test.txt\".*
+Error copying directory from .* to .*file_for_test.txt\".*
+Error copying directory from .* to .*file_for_test.txt\".$
diff --git a/Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-not-exist-result.txt b/Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-not-exist-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-not-exist-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-not-exist-stderr.txt b/Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-not-exist-stderr.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-not-exist-stderr.txt
diff --git a/Tests/RunCMake/CommandLine/E_copy_if_different-one-source-directory-target-is-directory-result.txt b/Tests/RunCMake/CommandLine/E_copy_if_different-one-source-directory-target-is-directory-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_copy_if_different-one-source-directory-target-is-directory-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CommandLine/E_copy_if_different-one-source-directory-target-is-directory-stderr.txt b/Tests/RunCMake/CommandLine/E_copy_if_different-one-source-directory-target-is-directory-stderr.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_copy_if_different-one-source-directory-target-is-directory-stderr.txt
diff --git a/Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-directory-result.txt b/Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-directory-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-directory-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-directory-stderr.txt b/Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-directory-stderr.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-directory-stderr.txt
diff --git a/Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-file-result.txt b/Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-file-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-file-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-file-stderr.txt b/Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-file-stderr.txt
new file mode 100644
index 000000000..64b7b1b4c
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-file-stderr.txt
@@ -0,0 +1 @@
+^Error: Target \(for copy_if_different command\).* is not a directory.$
diff --git a/Tests/RunCMake/CommandLine/E_create_symlink-broken-create-check.cmake b/Tests/RunCMake/CommandLine/E_create_symlink-broken-create-check.cmake
new file mode 100644
index 000000000..d7e652de7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_create_symlink-broken-create-check.cmake
@@ -0,0 +1,6 @@
+if(NOT IS_SYMLINK ${RunCMake_TEST_BINARY_DIR}/L)
+ set(RunCMake_TEST_FAILED "Symlink 'L' incorrectly not created!")
+endif()
+if(EXISTS ${RunCMake_TEST_BINARY_DIR}/L)
+ set(RunCMake_TEST_FAILED "Symlink 'L' not broken!")
+endif()
diff --git a/Tests/RunCMake/CommandLine/E_create_symlink-broken-replace-check.cmake b/Tests/RunCMake/CommandLine/E_create_symlink-broken-replace-check.cmake
new file mode 100644
index 000000000..c078ae8fc
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_create_symlink-broken-replace-check.cmake
@@ -0,0 +1,3 @@
+if(NOT IS_DIRECTORY ${RunCMake_TEST_BINARY_DIR}/L)
+ set(RunCMake_TEST_FAILED "Symlink 'L' not replaced correctly!")
+endif()
diff --git a/Tests/RunCMake/CommandLine/E_create_symlink-missing-dir-result.txt b/Tests/RunCMake/CommandLine/E_create_symlink-missing-dir-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_create_symlink-missing-dir-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_create_symlink-missing-dir-stderr.txt b/Tests/RunCMake/CommandLine/E_create_symlink-missing-dir-stderr.txt
new file mode 100644
index 000000000..7a6d84b2c
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_create_symlink-missing-dir-stderr.txt
@@ -0,0 +1 @@
+failed to create symbolic link 'missing-dir/L':
diff --git a/Tests/RunCMake/CommandLine/E_create_symlink-no-arg-result.txt b/Tests/RunCMake/CommandLine/E_create_symlink-no-arg-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_create_symlink-no-arg-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_create_symlink-no-arg-stderr.txt b/Tests/RunCMake/CommandLine/E_create_symlink-no-arg-stderr.txt
new file mode 100644
index 000000000..50d9b0332
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_create_symlink-no-arg-stderr.txt
@@ -0,0 +1,3 @@
+^CMake Error: cmake version .*
+Usage: .* -E <command> \[arguments\.\.\.\]
+Available commands:
diff --git a/Tests/RunCMake/CommandLine/E_create_symlink-no-replace-dir-result.txt b/Tests/RunCMake/CommandLine/E_create_symlink-no-replace-dir-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_create_symlink-no-replace-dir-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_create_symlink-no-replace-dir-stderr.txt b/Tests/RunCMake/CommandLine/E_create_symlink-no-replace-dir-stderr.txt
new file mode 100644
index 000000000..ebed0d67c
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_create_symlink-no-replace-dir-stderr.txt
@@ -0,0 +1 @@
+failed to create symbolic link '\.' because existing path cannot be removed:
diff --git a/Tests/RunCMake/CommandLine/E_env-bad-arg1-result.txt b/Tests/RunCMake/CommandLine/E_env-bad-arg1-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env-bad-arg1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_env-bad-arg1-stderr.txt b/Tests/RunCMake/CommandLine/E_env-bad-arg1-stderr.txt
new file mode 100644
index 000000000..2143ba417
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env-bad-arg1-stderr.txt
@@ -0,0 +1 @@
+^cmake -E env: unknown option '-bad-arg1'$
diff --git a/Tests/RunCMake/CommandLine/E_env-no-command0-result.txt b/Tests/RunCMake/CommandLine/E_env-no-command0-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env-no-command0-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_env-no-command0-stderr.txt b/Tests/RunCMake/CommandLine/E_env-no-command0-stderr.txt
new file mode 100644
index 000000000..d2efa5367
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env-no-command0-stderr.txt
@@ -0,0 +1 @@
+^cmake -E env: no command given$
diff --git a/Tests/RunCMake/CommandLine/E_env-no-command1-result.txt b/Tests/RunCMake/CommandLine/E_env-no-command1-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env-no-command1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_env-no-command1-stderr.txt b/Tests/RunCMake/CommandLine/E_env-no-command1-stderr.txt
new file mode 100644
index 000000000..d2efa5367
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env-no-command1-stderr.txt
@@ -0,0 +1 @@
+^cmake -E env: no command given$
diff --git a/Tests/RunCMake/CommandLine/E_env-set-stdout.txt b/Tests/RunCMake/CommandLine/E_env-set-stdout.txt
new file mode 100644
index 000000000..feff1176e
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env-set-stdout.txt
@@ -0,0 +1 @@
+^-- TEST_ENV is correctly set in environment: 1$
diff --git a/Tests/RunCMake/CommandLine/E_env-set.cmake b/Tests/RunCMake/CommandLine/E_env-set.cmake
new file mode 100644
index 000000000..c2639b663
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env-set.cmake
@@ -0,0 +1,5 @@
+if(DEFINED ENV{TEST_ENV})
+ message(STATUS "TEST_ENV is correctly set in environment: $ENV{TEST_ENV}")
+else()
+ message(FATAL_ERROR "TEST_ENV is incorrectly not set in environment")
+endif()
diff --git a/Tests/RunCMake/CommandLine/E_env-unset-stdout.txt b/Tests/RunCMake/CommandLine/E_env-unset-stdout.txt
new file mode 100644
index 000000000..a1d5c0108
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env-unset-stdout.txt
@@ -0,0 +1 @@
+^-- TEST_ENV is correctly not set in environment$
diff --git a/Tests/RunCMake/CommandLine/E_env-unset.cmake b/Tests/RunCMake/CommandLine/E_env-unset.cmake
new file mode 100644
index 000000000..04976fb40
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env-unset.cmake
@@ -0,0 +1,5 @@
+if(DEFINED ENV{TEST_ENV})
+ message(FATAL_ERROR "TEST_ENV is incorrectly set in environment")
+else()
+ message(STATUS "TEST_ENV is correctly not set in environment")
+endif()
diff --git a/Tests/RunCMake/CommandLine/E_make_directory-directory-with-parent-result.txt b/Tests/RunCMake/CommandLine/E_make_directory-directory-with-parent-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_make_directory-directory-with-parent-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CommandLine/E_make_directory-directory-with-parent-stderr.txt b/Tests/RunCMake/CommandLine/E_make_directory-directory-with-parent-stderr.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_make_directory-directory-with-parent-stderr.txt
diff --git a/Tests/RunCMake/CommandLine/E_make_directory-three-directories-and-file-result.txt b/Tests/RunCMake/CommandLine/E_make_directory-three-directories-and-file-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_make_directory-three-directories-and-file-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_make_directory-three-directories-and-file-stderr.txt b/Tests/RunCMake/CommandLine/E_make_directory-three-directories-and-file-stderr.txt
new file mode 100644
index 000000000..08a9428f4
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_make_directory-three-directories-and-file-stderr.txt
@@ -0,0 +1 @@
+^Error creating directory .*file_for_test.txt\".$
diff --git a/Tests/RunCMake/CommandLine/E_make_directory-three-directories-result.txt b/Tests/RunCMake/CommandLine/E_make_directory-three-directories-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_make_directory-three-directories-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CommandLine/E_make_directory-three-directories-stderr.txt b/Tests/RunCMake/CommandLine/E_make_directory-three-directories-stderr.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_make_directory-three-directories-stderr.txt
diff --git a/Tests/RunCMake/CommandLine/E_rename-no-arg-result.txt b/Tests/RunCMake/CommandLine/E_rename-no-arg-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rename-no-arg-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_rename-no-arg-stderr.txt b/Tests/RunCMake/CommandLine/E_rename-no-arg-stderr.txt
new file mode 100644
index 000000000..50d9b0332
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rename-no-arg-stderr.txt
@@ -0,0 +1,3 @@
+^CMake Error: cmake version .*
+Usage: .* -E <command> \[arguments\.\.\.\]
+Available commands:
diff --git a/Tests/RunCMake/CommandLine/E_sleep-bad-arg1-result.txt b/Tests/RunCMake/CommandLine/E_sleep-bad-arg1-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_sleep-bad-arg1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_sleep-bad-arg1-stderr.txt b/Tests/RunCMake/CommandLine/E_sleep-bad-arg1-stderr.txt
new file mode 100644
index 000000000..45e6ebc3f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_sleep-bad-arg1-stderr.txt
@@ -0,0 +1 @@
+^Unknown sleep time format "x"\.$
diff --git a/Tests/RunCMake/CommandLine/E_sleep-bad-arg2-result.txt b/Tests/RunCMake/CommandLine/E_sleep-bad-arg2-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_sleep-bad-arg2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_sleep-bad-arg2-stderr.txt b/Tests/RunCMake/CommandLine/E_sleep-bad-arg2-stderr.txt
new file mode 100644
index 000000000..399d47fbf
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_sleep-bad-arg2-stderr.txt
@@ -0,0 +1 @@
+^Unknown sleep time format "-1"\.$
diff --git a/Tests/RunCMake/CommandLine/E_sleep-no-args-result.txt b/Tests/RunCMake/CommandLine/E_sleep-no-args-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_sleep-no-args-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_sleep-no-args-stderr.cmake b/Tests/RunCMake/CommandLine/E_sleep-no-args-stderr.cmake
new file mode 100644
index 000000000..977f1efe8
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_sleep-no-args-stderr.cmake
@@ -0,0 +1,2 @@
+Usage: .*/cmake -E \[command\] \[arguments \.\.\.\]
+Available commands:
diff --git a/Tests/RunCMake/CommandLine/E_time-no-arg-result.txt b/Tests/RunCMake/CommandLine/E_time-no-arg-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_time-no-arg-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_time-no-arg-stderr.txt b/Tests/RunCMake/CommandLine/E_time-no-arg-stderr.txt
new file mode 100644
index 000000000..50d9b0332
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_time-no-arg-stderr.txt
@@ -0,0 +1,3 @@
+^CMake Error: cmake version .*
+Usage: .* -E <command> \[arguments\.\.\.\]
+Available commands:
diff --git a/Tests/RunCMake/CommandLine/E_time-stdout.txt b/Tests/RunCMake/CommandLine/E_time-stdout.txt
new file mode 100644
index 000000000..a51446a67
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_time-stdout.txt
@@ -0,0 +1,3 @@
+^hello world
+Elapsed time: [^
+]*$
diff --git a/Tests/RunCMake/CommandLine/E_touch_nocreate-no-arg-result.txt b/Tests/RunCMake/CommandLine/E_touch_nocreate-no-arg-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_touch_nocreate-no-arg-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_touch_nocreate-no-arg-stderr.txt b/Tests/RunCMake/CommandLine/E_touch_nocreate-no-arg-stderr.txt
new file mode 100644
index 000000000..50d9b0332
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_touch_nocreate-no-arg-stderr.txt
@@ -0,0 +1,3 @@
+^CMake Error: cmake version .*
+Usage: .* -E <command> \[arguments\.\.\.\]
+Available commands:
diff --git a/Tests/RunCMake/CommandLine/G_bad-arg-result.txt b/Tests/RunCMake/CommandLine/G_bad-arg-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/G_bad-arg-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/G_bad-arg-stderr.txt b/Tests/RunCMake/CommandLine/G_bad-arg-stderr.txt
new file mode 100644
index 000000000..07f2b5294
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/G_bad-arg-stderr.txt
@@ -0,0 +1,3 @@
+^CMake Error: Could not create named generator NoSuchGenerator
+
+Generators
diff --git a/Tests/RunCMake/CommandLine/G_no-arg-result.txt b/Tests/RunCMake/CommandLine/G_no-arg-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/G_no-arg-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/G_no-arg-stderr.txt b/Tests/RunCMake/CommandLine/G_no-arg-stderr.txt
new file mode 100644
index 000000000..2f491a224
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/G_no-arg-stderr.txt
@@ -0,0 +1,3 @@
+^CMake Error: No generator specified for -G
+
+Generators
diff --git a/Tests/RunCMake/CommandLine/NoArgs-stdout.txt b/Tests/RunCMake/CommandLine/NoArgs-stdout.txt
new file mode 100644
index 000000000..1cd34697b
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/NoArgs-stdout.txt
@@ -0,0 +1,10 @@
+^Usage
+
+ cmake \[options\] <path-to-source>
+ cmake \[options\] <path-to-existing-build>
+
+Specify a source directory to \(re-\)generate a build system for it in the
+current working directory. Specify an existing build directory to
+re-generate its build system.
+
+Run 'cmake --help' for more information.$
diff --git a/Tests/RunCMake/CommandLine/P_directory-result.txt b/Tests/RunCMake/CommandLine/P_directory-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/P_directory-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/P_directory-stderr.txt b/Tests/RunCMake/CommandLine/P_directory-stderr.txt
new file mode 100644
index 000000000..b8319a1fe
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/P_directory-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: Error processing file: .*/Tests/RunCMake/CommandLine$
diff --git a/Tests/RunCMake/CommandLine/P_no-arg-result.txt b/Tests/RunCMake/CommandLine/P_no-arg-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/P_no-arg-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/P_no-arg-stderr.txt b/Tests/RunCMake/CommandLine/P_no-arg-stderr.txt
new file mode 100644
index 000000000..8af3a53ce
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/P_no-arg-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: No script specified for argument -P$
diff --git a/Tests/RunCMake/CommandLine/P_no-file-result.txt b/Tests/RunCMake/CommandLine/P_no-file-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/P_no-file-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/P_no-file-stderr.txt b/Tests/RunCMake/CommandLine/P_no-file-stderr.txt
new file mode 100644
index 000000000..2e1239924
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/P_no-file-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: Error processing file: nosuchscriptfile.cmake$
diff --git a/Tests/RunCMake/CommandLine/P_working-dir.cmake b/Tests/RunCMake/CommandLine/P_working-dir.cmake
new file mode 100644
index 000000000..4ea029382
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/P_working-dir.cmake
@@ -0,0 +1,14 @@
+if(NOT IS_DIRECTORY "${EXPECTED_WORKING_DIR}")
+ message(FATAL_ERROR "EXPECTED_WORKING_DIR is not a directory: ${EXPECTED_WORKING_DIR}")
+endif()
+
+foreach(d CMAKE_BINARY_DIR CMAKE_CURRENT_BINARY_DIR CMAKE_SOURCE_DIR CMAKE_CURRENT_SOURCE_DIR)
+ if(NOT DEFINED ${d})
+ message(FATAL_ERROR "${d} is not defined")
+ endif()
+ if(EXPECTED_WORKING_DIR STREQUAL "${${d}}")
+ message(STATUS "${d} is the expected working directory (${EXPECTED_WORKING_DIR})")
+ else()
+ message(FATAL_ERROR "${d} = \"${${d}}\" is not the expected working directory (${EXPECTED_WORKING_DIR})")
+ endif()
+endforeach()
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
new file mode 100644
index 000000000..e3b73ff25
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -0,0 +1,298 @@
+include(RunCMake)
+
+run_cmake_command(NoArgs ${CMAKE_COMMAND})
+run_cmake_command(C-no-arg ${CMAKE_COMMAND} -C)
+run_cmake_command(C-no-file ${CMAKE_COMMAND} -C nosuchcachefile.txt)
+run_cmake_command(cache-no-file ${CMAKE_COMMAND} nosuchsubdir/CMakeCache.txt)
+run_cmake_command(lists-no-file ${CMAKE_COMMAND} nosuchsubdir/CMakeLists.txt)
+run_cmake_command(D-no-arg ${CMAKE_COMMAND} -D)
+run_cmake_command(U-no-arg ${CMAKE_COMMAND} -U)
+run_cmake_command(E-no-arg ${CMAKE_COMMAND} -E)
+run_cmake_command(E_echo_append ${CMAKE_COMMAND} -E echo_append)
+run_cmake_command(E_rename-no-arg ${CMAKE_COMMAND} -E rename)
+run_cmake_command(E_touch_nocreate-no-arg ${CMAKE_COMMAND} -E touch_nocreate)
+
+run_cmake_command(E_time ${CMAKE_COMMAND} -E time ${CMAKE_COMMAND} -E echo "hello world")
+run_cmake_command(E_time-no-arg ${CMAKE_COMMAND} -E time)
+
+run_cmake_command(E___run_iwyu-no-iwyu ${CMAKE_COMMAND} -E __run_iwyu -- command-does-not-exist)
+run_cmake_command(E___run_iwyu-bad-iwyu ${CMAKE_COMMAND} -E __run_iwyu --iwyu=iwyu-does-not-exist -- command-does-not-exist)
+run_cmake_command(E___run_iwyu-no--- ${CMAKE_COMMAND} -E __run_iwyu --iwyu=iwyu-does-not-exist command-does-not-exist)
+run_cmake_command(E___run_iwyu-no-cc ${CMAKE_COMMAND} -E __run_iwyu --iwyu=iwyu-does-not-exist --)
+
+run_cmake_command(G_no-arg ${CMAKE_COMMAND} -G)
+run_cmake_command(G_bad-arg ${CMAKE_COMMAND} -G NoSuchGenerator)
+run_cmake_command(P_no-arg ${CMAKE_COMMAND} -P)
+run_cmake_command(P_no-file ${CMAKE_COMMAND} -P nosuchscriptfile.cmake)
+
+run_cmake_command(build-no-dir
+ ${CMAKE_COMMAND} --build)
+run_cmake_command(build-no-cache
+ ${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR})
+run_cmake_command(build-no-generator
+ ${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR}/cache-no-generator)
+run_cmake_command(build-bad-dir
+ ${CMAKE_COMMAND} --build dir-does-not-exist)
+run_cmake_command(build-bad-generator
+ ${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR}/cache-bad-generator)
+
+run_cmake_command(cache-bad-entry
+ ${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR}/cache-bad-entry/)
+run_cmake_command(cache-empty-entry
+ ${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR}/cache-empty-entry/)
+
+function(run_BuildDir)
+ # Use a single build tree for a few tests without cleaning.
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/BuildDir-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+ run_cmake(BuildDir)
+ run_cmake_command(BuildDir--build ${CMAKE_COMMAND} -E chdir ..
+ ${CMAKE_COMMAND} --build BuildDir-build --target CustomTarget)
+endfunction()
+run_BuildDir()
+
+if(RunCMake_GENERATOR STREQUAL "Ninja")
+ # Use a single build tree for a few tests without cleaning.
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Build-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+ set(RunCMake_TEST_OPTIONS -DCMAKE_VERBOSE_MAKEFILE=1)
+ run_cmake(Build)
+ unset(RunCMake_TEST_OPTIONS)
+ run_cmake_command(Build-ninja-v ${CMAKE_COMMAND} --build .)
+
+ unset(RunCMake_TEST_BINARY_DIR)
+ unset(RunCMake_TEST_NO_CLEAN)
+endif()
+
+if(RunCMake_GENERATOR STREQUAL "Visual Studio 6")
+ set(RunCMake_WARN_VS6 1)
+ run_cmake(DeprecateVS6-WARN-ON)
+ unset(RunCMake_WARN_VS6)
+ run_cmake(DeprecateVS6-WARN-OFF)
+elseif(RunCMake_GENERATOR STREQUAL "Visual Studio 7")
+ set(RunCMake_WARN_VS70 1)
+ run_cmake(DeprecateVS70-WARN-ON)
+ unset(RunCMake_WARN_VS70)
+ run_cmake(DeprecateVS70-WARN-OFF)
+endif()
+
+if(UNIX)
+ run_cmake_command(E_create_symlink-no-arg
+ ${CMAKE_COMMAND} -E create_symlink
+ )
+ run_cmake_command(E_create_symlink-missing-dir
+ ${CMAKE_COMMAND} -E create_symlink T missing-dir/L
+ )
+
+ # Use a single build tree for a few tests without cleaning.
+ set(RunCMake_TEST_BINARY_DIR
+ ${RunCMake_BINARY_DIR}/E_create_symlink-broken-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ run_cmake_command(E_create_symlink-broken-create
+ ${CMAKE_COMMAND} -E create_symlink T L
+ )
+ run_cmake_command(E_create_symlink-broken-replace
+ ${CMAKE_COMMAND} -E create_symlink . L
+ )
+ unset(RunCMake_TEST_BINARY_DIR)
+ unset(RunCMake_TEST_NO_CLEAN)
+
+ run_cmake_command(E_create_symlink-no-replace-dir
+ ${CMAKE_COMMAND} -E create_symlink T .
+ )
+endif()
+
+set(in ${RunCMake_SOURCE_DIR}/copy_input)
+set(out ${RunCMake_BINARY_DIR}/copy_output)
+file(REMOVE_RECURSE "${out}")
+file(MAKE_DIRECTORY ${out})
+run_cmake_command(E_copy-one-source-file
+ ${CMAKE_COMMAND} -E copy ${out}/f1.txt)
+run_cmake_command(E_copy-one-source-directory-target-is-directory
+ ${CMAKE_COMMAND} -E copy ${in}/f1.txt ${out})
+run_cmake_command(E_copy-three-source-files-target-is-directory
+ ${CMAKE_COMMAND} -E copy ${in}/f1.txt ${in}/f2.txt ${in}/f3.txt ${out})
+run_cmake_command(E_copy-three-source-files-target-is-file
+ ${CMAKE_COMMAND} -E copy ${in}/f1.txt ${in}/f2.txt ${in}/f3.txt ${out}/f1.txt)
+run_cmake_command(E_copy-two-good-and-one-bad-source-files-target-is-directory
+ ${CMAKE_COMMAND} -E copy ${in}/f1.txt ${in}/not_existing_file.bad ${in}/f3.txt ${out})
+run_cmake_command(E_copy_if_different-one-source-directory-target-is-directory
+ ${CMAKE_COMMAND} -E copy_if_different ${in}/f1.txt ${out})
+run_cmake_command(E_copy_if_different-three-source-files-target-is-directory
+ ${CMAKE_COMMAND} -E copy_if_different ${in}/f1.txt ${in}/f2.txt ${in}/f3.txt ${out})
+run_cmake_command(E_copy_if_different-three-source-files-target-is-file
+ ${CMAKE_COMMAND} -E copy_if_different ${in}/f1.txt ${in}/f2.txt ${in}/f3.txt ${out}/f1.txt)
+unset(in)
+unset(out)
+
+set(in ${RunCMake_SOURCE_DIR}/copy_input)
+set(out ${RunCMake_BINARY_DIR}/copy_directory_output)
+set(outfile ${out}/file_for_test.txt)
+file(REMOVE_RECURSE "${out}")
+file(MAKE_DIRECTORY ${out})
+file(WRITE ${outfile} "")
+run_cmake_command(E_copy_directory-three-source-files-target-is-directory
+ ${CMAKE_COMMAND} -E copy_directory ${in}/d1 ${in}/d2 ${in}/d3 ${out})
+run_cmake_command(E_copy_directory-three-source-files-target-is-file
+ ${CMAKE_COMMAND} -E copy_directory ${in}/d1 ${in}/d2 ${in}/d3 ${outfile})
+run_cmake_command(E_copy_directory-three-source-files-target-is-not-exist
+ ${CMAKE_COMMAND} -E copy_directory ${in}/d1 ${in}/d2 ${in}/d3 ${out}/not_existing_directory)
+unset(in)
+unset(out)
+unset(outfile)
+
+set(out ${RunCMake_BINARY_DIR}/make_directory_output)
+set(outfile ${out}/file_for_test.txt)
+file(REMOVE_RECURSE "${out}")
+file(MAKE_DIRECTORY ${out})
+file(WRITE ${outfile} "")
+run_cmake_command(E_make_directory-three-directories
+ ${CMAKE_COMMAND} -E make_directory ${out}/d1 ${out}/d2 ${out}/d2)
+run_cmake_command(E_make_directory-directory-with-parent
+ ${CMAKE_COMMAND} -E make_directory ${out}/parent/child)
+run_cmake_command(E_make_directory-three-directories-and-file
+ ${CMAKE_COMMAND} -E make_directory ${out}/d1 ${out}/d2 ${outfile})
+unset(out)
+unset(outfile)
+
+
+run_cmake_command(E_env-no-command0 ${CMAKE_COMMAND} -E env)
+run_cmake_command(E_env-no-command1 ${CMAKE_COMMAND} -E env TEST_ENV=1)
+run_cmake_command(E_env-bad-arg1 ${CMAKE_COMMAND} -E env -bad-arg1)
+run_cmake_command(E_env-set ${CMAKE_COMMAND} -E env TEST_ENV=1 ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/E_env-set.cmake)
+run_cmake_command(E_env-unset ${CMAKE_COMMAND} -E env TEST_ENV=1 ${CMAKE_COMMAND} -E env --unset=TEST_ENV ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/E_env-unset.cmake)
+
+set(RunCMake_DEFAULT_stderr ".")
+run_cmake_command(E_sleep-no-args ${CMAKE_COMMAND} -E sleep)
+unset(RunCMake_DEFAULT_stderr)
+run_cmake_command(E_sleep-bad-arg1 ${CMAKE_COMMAND} -E sleep x)
+run_cmake_command(E_sleep-bad-arg2 ${CMAKE_COMMAND} -E sleep 1 -1)
+run_cmake_command(E_sleep-one-tenth ${CMAKE_COMMAND} -E sleep 0.1)
+
+run_cmake_command(P_directory ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR})
+run_cmake_command(P_working-dir ${CMAKE_COMMAND} -DEXPECTED_WORKING_DIR=${RunCMake_BINARY_DIR}/P_working-dir-build -P ${RunCMake_SOURCE_DIR}/P_working-dir.cmake)
+
+set(RunCMake_TEST_OPTIONS
+ "-DFOO=-DBAR:BOOL=BAZ")
+run_cmake(D_nested_cache)
+
+set(RunCMake_TEST_OPTIONS
+ "-DFOO:STRING=-DBAR:BOOL=BAZ")
+run_cmake(D_typed_nested_cache)
+
+set(RunCMake_TEST_OPTIONS -Wno-dev)
+run_cmake(Wno-dev)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS -Wdev)
+run_cmake(Wdev)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS -Werror=dev)
+run_cmake(Werror_dev)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS -Wno-error=dev)
+run_cmake(Wno-error_deprecated)
+unset(RunCMake_TEST_OPTIONS)
+
+# -Wdev should not override deprecated options if specified
+set(RunCMake_TEST_OPTIONS -Wdev -Wno-deprecated)
+run_cmake(Wno-deprecated)
+unset(RunCMake_TEST_OPTIONS)
+set(RunCMake_TEST_OPTIONS -Wno-deprecated -Wdev)
+run_cmake(Wno-deprecated)
+unset(RunCMake_TEST_OPTIONS)
+
+# -Wdev should enable deprecated warnings as well
+set(RunCMake_TEST_OPTIONS -Wdev)
+run_cmake(Wdeprecated)
+unset(RunCMake_TEST_OPTIONS)
+
+# -Werror=dev should enable deprecated errors as well
+set(RunCMake_TEST_OPTIONS -Werror=dev)
+run_cmake(Werror_deprecated)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS -Wdeprecated)
+run_cmake(Wdeprecated)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS -Wno-deprecated)
+run_cmake(Wno-deprecated)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS -Werror=deprecated)
+run_cmake(Werror_deprecated)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS -Wno-error=deprecated)
+run_cmake(Wno-error_deprecated)
+unset(RunCMake_TEST_OPTIONS)
+
+# Dev warnings should be on by default
+run_cmake(Wdev)
+
+# Deprecated warnings should be on by default
+run_cmake(Wdeprecated)
+
+# Conflicting -W options should honor the last value
+set(RunCMake_TEST_OPTIONS -Wno-dev -Wdev)
+run_cmake(Wdev)
+unset(RunCMake_TEST_OPTIONS)
+set(RunCMake_TEST_OPTIONS -Wdev -Wno-dev)
+run_cmake(Wno-dev)
+unset(RunCMake_TEST_OPTIONS)
+
+run_cmake_command(W_bad-arg1 ${CMAKE_COMMAND} -W)
+run_cmake_command(W_bad-arg2 ${CMAKE_COMMAND} -Wno-)
+run_cmake_command(W_bad-arg3 ${CMAKE_COMMAND} -Werror=)
+
+set(RunCMake_TEST_OPTIONS --debug-output)
+run_cmake(debug-output)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS --trace)
+run_cmake(trace)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS --trace-expand)
+run_cmake(trace-expand)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS --debug-trycompile)
+run_cmake(debug-trycompile)
+unset(RunCMake_TEST_OPTIONS)
+
+function(run_cmake_depends)
+ set(RunCMake_TEST_SOURCE_DIR "${RunCMake_SOURCE_DIR}/cmake_depends")
+ set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/cmake_depends-build")
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ file(WRITE "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/DepTarget.dir/DependInfo.cmake" "
+set(CMAKE_DEPENDS_LANGUAGES \"C\")
+set(CMAKE_DEPENDS_CHECK_C
+ \"${RunCMake_TEST_SOURCE_DIR}/test.c\"
+ \"${RunCMake_TEST_BINARY_DIR}/CMakeFiles/DepTarget.dir/test.c.o\"
+ )
+")
+ file(WRITE "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/CMakeDirectoryInformation.cmake" "
+set(CMAKE_RELATIVE_PATH_TOP_SOURCE \"${RunCMake_TEST_SOURCE_DIR}\")
+set(CMAKE_RELATIVE_PATH_TOP_BINARY \"${RunCMake_TEST_BINARY_DIR}\")
+")
+ run_cmake_command(cmake_depends ${CMAKE_COMMAND} -E cmake_depends
+ "Unix Makefiles"
+ ${RunCMake_TEST_SOURCE_DIR} ${RunCMake_TEST_SOURCE_DIR}
+ ${RunCMake_TEST_BINARY_DIR} ${RunCMake_TEST_BINARY_DIR}
+ ${RunCMake_TEST_BINARY_DIR}/CMakeFiles/DepTarget.dir/DependInfo.cmake
+ )
+endfunction()
+run_cmake_depends()
diff --git a/Tests/RunCMake/CommandLine/U-no-arg-result.txt b/Tests/RunCMake/CommandLine/U-no-arg-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/U-no-arg-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/U-no-arg-stderr.txt b/Tests/RunCMake/CommandLine/U-no-arg-stderr.txt
new file mode 100644
index 000000000..c34ef947c
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/U-no-arg-stderr.txt
@@ -0,0 +1,2 @@
+^CMake Error: -U must be followed with VAR.
+CMake Error: Problem processing arguments. Aborting.$
diff --git a/Tests/RunCMake/CommandLine/W_bad-arg1-result.txt b/Tests/RunCMake/CommandLine/W_bad-arg1-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/W_bad-arg1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/W_bad-arg1-stderr.txt b/Tests/RunCMake/CommandLine/W_bad-arg1-stderr.txt
new file mode 100644
index 000000000..0c0f61347
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/W_bad-arg1-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error: -W must be followed with \[no-\]<name>.
+CMake Error: Problem processing arguments. Aborting.
diff --git a/Tests/RunCMake/CommandLine/W_bad-arg2-result.txt b/Tests/RunCMake/CommandLine/W_bad-arg2-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/W_bad-arg2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/W_bad-arg2-stderr.txt b/Tests/RunCMake/CommandLine/W_bad-arg2-stderr.txt
new file mode 100644
index 000000000..cc643df95
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/W_bad-arg2-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error: No warning name provided.
+CMake Error: Problem processing arguments. Aborting.
diff --git a/Tests/RunCMake/CommandLine/W_bad-arg3-result.txt b/Tests/RunCMake/CommandLine/W_bad-arg3-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/W_bad-arg3-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/W_bad-arg3-stderr.txt b/Tests/RunCMake/CommandLine/W_bad-arg3-stderr.txt
new file mode 100644
index 000000000..cc643df95
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/W_bad-arg3-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error: No warning name provided.
+CMake Error: Problem processing arguments. Aborting.
diff --git a/Tests/RunCMake/CommandLine/Wdeprecated-stderr.txt b/Tests/RunCMake/CommandLine/Wdeprecated-stderr.txt
new file mode 100644
index 000000000..e9be1dcb3
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Wdeprecated-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Deprecation Warning at Wdeprecated.cmake:1 \(message\):
+ Some deprecated warning
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CommandLine/Wdeprecated.cmake b/Tests/RunCMake/CommandLine/Wdeprecated.cmake
new file mode 100644
index 000000000..3142b42dc
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Wdeprecated.cmake
@@ -0,0 +1 @@
+message(DEPRECATION "Some deprecated warning")
diff --git a/Tests/RunCMake/CommandLine/Wdev-stderr.txt b/Tests/RunCMake/CommandLine/Wdev-stderr.txt
new file mode 100644
index 000000000..88cfb3a30
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Wdev-stderr.txt
@@ -0,0 +1,11 @@
+^CMake Warning \(dev\) at Wdev.cmake:1 \(message\):
+ Some author warning
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at Wdev.cmake:6 \(include\):
+ include\(\) given empty file name \(ignored\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/CommandLine/Wdev.cmake b/Tests/RunCMake/CommandLine/Wdev.cmake
new file mode 100644
index 000000000..756f31eee
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Wdev.cmake
@@ -0,0 +1,6 @@
+message(AUTHOR_WARNING "Some author warning")
+
+# with -Wdev this will also cause an AUTHOR_WARNING message, checks that
+# messages issued outside of the message command, by other CMake commands, also
+# are affected by -Wdev
+include("")
diff --git a/Tests/RunCMake/CommandLine/Werror_deprecated-result.txt b/Tests/RunCMake/CommandLine/Werror_deprecated-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Werror_deprecated-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/Werror_deprecated-stderr.txt b/Tests/RunCMake/CommandLine/Werror_deprecated-stderr.txt
new file mode 100644
index 000000000..6acdc7362
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Werror_deprecated-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Deprecation Error at Werror_deprecated.cmake:1 \(message\):
+ Some deprecated warning
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CommandLine/Werror_deprecated.cmake b/Tests/RunCMake/CommandLine/Werror_deprecated.cmake
new file mode 100644
index 000000000..3142b42dc
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Werror_deprecated.cmake
@@ -0,0 +1 @@
+message(DEPRECATION "Some deprecated warning")
diff --git a/Tests/RunCMake/CommandLine/Werror_dev-result.txt b/Tests/RunCMake/CommandLine/Werror_dev-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Werror_dev-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/Werror_dev-stderr.txt b/Tests/RunCMake/CommandLine/Werror_dev-stderr.txt
new file mode 100644
index 000000000..590ec96d3
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Werror_dev-stderr.txt
@@ -0,0 +1,11 @@
+^CMake Error \(dev\) at Werror_dev.cmake:4 \(include\):
+ include\(\) given empty file name \(ignored\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This error is for project developers. Use -Wno-error=dev to suppress it.
+
+CMake Error \(dev\) at Werror_dev.cmake:7 \(message\):
+ Some author warning
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This error is for project developers. Use -Wno-error=dev to suppress it.$
diff --git a/Tests/RunCMake/CommandLine/Werror_dev.cmake b/Tests/RunCMake/CommandLine/Werror_dev.cmake
new file mode 100644
index 000000000..05f333a57
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Werror_dev.cmake
@@ -0,0 +1,7 @@
+# with -Werror=dev this will also cause an (upgraded) AUTHOR_ERROR message,
+# checks that messages issued outside of the message command, by other CMake
+# commands, also are affected by -Werror=dev
+include("")
+
+# message command sets fatal occurred flag, so run it last
+message(AUTHOR_WARNING "Some author warning")
diff --git a/Tests/RunCMake/CommandLine/Wno-deprecated.cmake b/Tests/RunCMake/CommandLine/Wno-deprecated.cmake
new file mode 100644
index 000000000..3142b42dc
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Wno-deprecated.cmake
@@ -0,0 +1 @@
+message(DEPRECATION "Some deprecated warning")
diff --git a/Tests/RunCMake/CommandLine/Wno-dev.cmake b/Tests/RunCMake/CommandLine/Wno-dev.cmake
new file mode 100644
index 000000000..802b435b0
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Wno-dev.cmake
@@ -0,0 +1,6 @@
+message(AUTHOR_WARNING "Some author warning")
+
+# without -Wno-dev this will also cause an AUTHOR_WARNING message, checks that
+# messages issued outside of the message command, by other CMake commands, also
+# are affected by -Wno-dev
+include("")
diff --git a/Tests/RunCMake/CommandLine/Wno-error_deprecated-stderr.txt b/Tests/RunCMake/CommandLine/Wno-error_deprecated-stderr.txt
new file mode 100644
index 000000000..0ed169861
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Wno-error_deprecated-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Deprecation Warning at Wno-error_deprecated.cmake:2 \(message\):
+ Some deprecated warning
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CommandLine/Wno-error_deprecated.cmake b/Tests/RunCMake/CommandLine/Wno-error_deprecated.cmake
new file mode 100644
index 000000000..676792a8d
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Wno-error_deprecated.cmake
@@ -0,0 +1,2 @@
+# This should still produce a warning when -Wno-error=deprecated is specified
+message(DEPRECATION "Some deprecated warning")
diff --git a/Tests/RunCMake/CommandLine/Wno-error_dev-stderr.txt b/Tests/RunCMake/CommandLine/Wno-error_dev-stderr.txt
new file mode 100644
index 000000000..dd22d5568
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Wno-error_dev-stderr.txt
@@ -0,0 +1,11 @@
+^CMake Warning \(dev\) at Wno-error_dev.cmake:2 \(message\):
+ Some author warning
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at Wno-error_dev.cmake:6 \(include\):
+ include\(\) given empty file name \(ignored\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/CommandLine/Wno-error_dev.cmake b/Tests/RunCMake/CommandLine/Wno-error_dev.cmake
new file mode 100644
index 000000000..b700c1975
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Wno-error_dev.cmake
@@ -0,0 +1,7 @@
+# This should still produce a warning when -Wno-error=dev is specified
+message(AUTHOR_WARNING "Some author warning")
+
+# with -Wno-error=dev this will also cause an AUTHOR_WARNING message, checks
+# that messages issued outside of the message command, by other CMake commands,
+# also are affected by -Wno-error=dev
+include("")
diff --git a/Tests/RunCMake/CommandLine/build-bad-dir-result.txt b/Tests/RunCMake/CommandLine/build-bad-dir-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/build-bad-dir-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/build-bad-dir-stderr.txt b/Tests/RunCMake/CommandLine/build-bad-dir-stderr.txt
new file mode 100644
index 000000000..d3f3d9ce0
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/build-bad-dir-stderr.txt
@@ -0,0 +1,2 @@
+^Error: [^
+]+/Tests/RunCMake/CommandLine/build-bad-dir-build/dir-does-not-exist is not a directory$
diff --git a/Tests/RunCMake/CommandLine/build-bad-generator-result.txt b/Tests/RunCMake/CommandLine/build-bad-generator-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/build-bad-generator-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/build-bad-generator-stderr.txt b/Tests/RunCMake/CommandLine/build-bad-generator-stderr.txt
new file mode 100644
index 000000000..110340749
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/build-bad-generator-stderr.txt
@@ -0,0 +1 @@
+^Error: could create CMAKE_GENERATOR "Bad Generator"$
diff --git a/Tests/RunCMake/CommandLine/build-no-cache-result.txt b/Tests/RunCMake/CommandLine/build-no-cache-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/build-no-cache-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/build-no-cache-stderr.txt b/Tests/RunCMake/CommandLine/build-no-cache-stderr.txt
new file mode 100644
index 000000000..40dd3c097
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/build-no-cache-stderr.txt
@@ -0,0 +1 @@
+^Error: could not load cache$
diff --git a/Tests/RunCMake/CommandLine/build-no-dir-result.txt b/Tests/RunCMake/CommandLine/build-no-dir-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/build-no-dir-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/build-no-dir-stderr.txt b/Tests/RunCMake/CommandLine/build-no-dir-stderr.txt
new file mode 100644
index 000000000..8d518f609
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/build-no-dir-stderr.txt
@@ -0,0 +1 @@
+^Usage: cmake --build <dir> \[options\] \[-- \[native-options\]\]
diff --git a/Tests/RunCMake/CommandLine/build-no-generator-result.txt b/Tests/RunCMake/CommandLine/build-no-generator-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/build-no-generator-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/build-no-generator-stderr.txt b/Tests/RunCMake/CommandLine/build-no-generator-stderr.txt
new file mode 100644
index 000000000..40ad030be
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/build-no-generator-stderr.txt
@@ -0,0 +1 @@
+^Error: could not find CMAKE_GENERATOR in Cache$
diff --git a/Tests/RunCMake/CommandLine/cache-bad-entry-result.txt b/Tests/RunCMake/CommandLine/cache-bad-entry-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/cache-bad-entry-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/cache-bad-entry-stderr.txt b/Tests/RunCMake/CommandLine/cache-bad-entry-stderr.txt
new file mode 100644
index 000000000..150d2ca88
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/cache-bad-entry-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: Parse error in cache file .*/Tests/RunCMake/CommandLine/cache-bad-entry/CMakeCache.txt on line 7. Offending entry: BAD ENTRY.*
diff --git a/Tests/RunCMake/CommandLine/cache-bad-entry/CMakeCache.txt b/Tests/RunCMake/CommandLine/cache-bad-entry/CMakeCache.txt
new file mode 100644
index 000000000..75cd7c2e1
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/cache-bad-entry/CMakeCache.txt
@@ -0,0 +1,10 @@
+# This is a comment
+
+// That was an empty line. This isn't.
+EMPTY_LINE:BOOL=FALSE
+
+// Uhoh! Here it comes
+BAD ENTRY
+
+// This is fine
+GOOD_ENTRY:BOOL=TRUE
diff --git a/Tests/RunCMake/CommandLine/cache-bad-generator/CMakeCache.txt b/Tests/RunCMake/CommandLine/cache-bad-generator/CMakeCache.txt
new file mode 100644
index 000000000..e34af4432
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/cache-bad-generator/CMakeCache.txt
@@ -0,0 +1 @@
+CMAKE_GENERATOR:INTERNAL=Bad Generator
diff --git a/Tests/RunCMake/CommandLine/cache-empty-entry-result.txt b/Tests/RunCMake/CommandLine/cache-empty-entry-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/cache-empty-entry-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/cache-empty-entry-stderr.txt b/Tests/RunCMake/CommandLine/cache-empty-entry-stderr.txt
new file mode 100644
index 000000000..54f44525f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/cache-empty-entry-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: Parse error in cache file .*/Tests/RunCMake/CommandLine/cache-empty-entry/CMakeCache.txt on line 5. Offending entry:.*
diff --git a/Tests/RunCMake/CommandLine/cache-empty-entry/CMakeCache.txt b/Tests/RunCMake/CommandLine/cache-empty-entry/CMakeCache.txt
new file mode 100644
index 000000000..44da1c9c3
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/cache-empty-entry/CMakeCache.txt
@@ -0,0 +1,7 @@
+// This is valid
+VALID:BOOL=TRUE
+
+// This isn't
+
+// One final entry
+FINAL:BOOL=TRUE
diff --git a/Tests/RunCMake/CommandLine/cache-no-file-result.txt b/Tests/RunCMake/CommandLine/cache-no-file-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/cache-no-file-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/cache-no-file-stderr.txt b/Tests/RunCMake/CommandLine/cache-no-file-stderr.txt
new file mode 100644
index 000000000..da3a0c3a8
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/cache-no-file-stderr.txt
@@ -0,0 +1,2 @@
+^CMake Error: The source directory ".*/Tests/RunCMake/CommandLine/cache-no-file-build/nosuchsubdir" does not exist.
+Specify --help for usage, or press the help button on the CMake GUI.$
diff --git a/Tests/RunCMake/CommandLine/cache-no-generator/CMakeCache.txt b/Tests/RunCMake/CommandLine/cache-no-generator/CMakeCache.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/cache-no-generator/CMakeCache.txt
diff --git a/Tests/RunCMake/CommandLine/cmake_depends-check.cmake b/Tests/RunCMake/CommandLine/cmake_depends-check.cmake
new file mode 100644
index 000000000..031478b7b
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/cmake_depends-check.cmake
@@ -0,0 +1,13 @@
+set(depend_make "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/DepTarget.dir/depend.make")
+if(EXISTS "${depend_make}")
+ file(READ "${depend_make}" depend_make_content)
+ string(REGEX REPLACE "\n+$" "" depend_make_content "${depend_make_content}")
+ if(NOT depend_make_content MATCHES "
+CMakeFiles/DepTarget.dir/test.c.o: .*/Tests/RunCMake/CommandLine/cmake_depends/test.c
+CMakeFiles/DepTarget.dir/test.c.o: .*/Tests/RunCMake/CommandLine/cmake_depends/test.h$")
+ string(REPLACE "\n" "\n " depend_make_content " ${depend_make_content}")
+ set(RunCMake_TEST_FAILED "depend.make does not have expected content:\n${depend_make_content}")
+ endif()
+else()
+ set(RunCMake_TEST_FAILED "depend.make missing:\n ${depend_make}")
+endif()
diff --git a/Tests/RunCMake/CommandLine/cmake_depends-stdout.txt b/Tests/RunCMake/CommandLine/cmake_depends-stdout.txt
new file mode 100644
index 000000000..8fe092b4a
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/cmake_depends-stdout.txt
@@ -0,0 +1 @@
+^Scanning dependencies of target DepTarget$
diff --git a/Tests/RunCMake/CommandLine/cmake_depends/test.c b/Tests/RunCMake/CommandLine/cmake_depends/test.c
new file mode 100644
index 000000000..92c056f70
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/cmake_depends/test.c
@@ -0,0 +1,2 @@
+#include "test.h"
+#include "test_UTF-16LE.h"
diff --git a/Tests/RunCMake/CommandLine/cmake_depends/test.h b/Tests/RunCMake/CommandLine/cmake_depends/test.h
new file mode 100644
index 000000000..fd8738811
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/cmake_depends/test.h
@@ -0,0 +1 @@
+void test(void) {}
diff --git a/Tests/RunCMake/CommandLine/cmake_depends/test_UTF-16LE.h b/Tests/RunCMake/CommandLine/cmake_depends/test_UTF-16LE.h
new file mode 100644
index 000000000..bf56ec694
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/cmake_depends/test_UTF-16LE.h
Binary files differ
diff --git a/Tests/RunCMake/CommandLine/copy_input/d1/d1.txt b/Tests/RunCMake/CommandLine/copy_input/d1/d1.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/copy_input/d1/d1.txt
diff --git a/Tests/RunCMake/CommandLine/copy_input/d2/d2.txt b/Tests/RunCMake/CommandLine/copy_input/d2/d2.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/copy_input/d2/d2.txt
diff --git a/Tests/RunCMake/CommandLine/copy_input/d3/d3.txt b/Tests/RunCMake/CommandLine/copy_input/d3/d3.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/copy_input/d3/d3.txt
diff --git a/Tests/RunCMake/CommandLine/copy_input/f1.txt b/Tests/RunCMake/CommandLine/copy_input/f1.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/copy_input/f1.txt
diff --git a/Tests/RunCMake/CommandLine/copy_input/f2.txt b/Tests/RunCMake/CommandLine/copy_input/f2.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/copy_input/f2.txt
diff --git a/Tests/RunCMake/CommandLine/copy_input/f3.txt b/Tests/RunCMake/CommandLine/copy_input/f3.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/copy_input/f3.txt
diff --git a/Tests/RunCMake/CommandLine/debug-output-stdout.txt b/Tests/RunCMake/CommandLine/debug-output-stdout.txt
new file mode 100644
index 000000000..96f2aae7e
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/debug-output-stdout.txt
@@ -0,0 +1 @@
+Running with debug output on.
diff --git a/Tests/RunCMake/CommandLine/debug-output.cmake b/Tests/RunCMake/CommandLine/debug-output.cmake
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/debug-output.cmake
diff --git a/Tests/RunCMake/CommandLine/debug-trycompile.cmake b/Tests/RunCMake/CommandLine/debug-trycompile.cmake
new file mode 100644
index 000000000..a3835a700
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/debug-trycompile.cmake
@@ -0,0 +1,5 @@
+enable_language(C)
+# Look for a source tree left by enable_language internal checks.
+if(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmp/CMakeLists.txt)
+ message(FATAL_ERROR "--debug-trycompile should leave the source behind")
+endif()
diff --git a/Tests/RunCMake/CommandLine/lists-no-file-result.txt b/Tests/RunCMake/CommandLine/lists-no-file-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/lists-no-file-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/lists-no-file-stderr.txt b/Tests/RunCMake/CommandLine/lists-no-file-stderr.txt
new file mode 100644
index 000000000..3465e8972
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/lists-no-file-stderr.txt
@@ -0,0 +1,2 @@
+^CMake Error: The source directory ".*/Tests/RunCMake/CommandLine/lists-no-file-build/nosuchsubdir" does not exist.
+Specify --help for usage, or press the help button on the CMake GUI.$
diff --git a/Tests/RunCMake/CommandLine/trace-expand-stderr.txt b/Tests/RunCMake/CommandLine/trace-expand-stderr.txt
new file mode 100644
index 000000000..4fee9bc96
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/trace-expand-stderr.txt
@@ -0,0 +1,2 @@
+^.*/Tests/RunCMake/CommandLine/CMakeLists.txt\(1\): cmake_minimum_required\(VERSION 3.0 \)
+.*/Tests/RunCMake/CommandLine/CMakeLists.txt\(2\): project\(trace-expand NONE \)
diff --git a/Tests/RunCMake/CommandLine/trace-expand.cmake b/Tests/RunCMake/CommandLine/trace-expand.cmake
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/trace-expand.cmake
diff --git a/Tests/RunCMake/CommandLine/trace-stderr.txt b/Tests/RunCMake/CommandLine/trace-stderr.txt
new file mode 100644
index 000000000..8e8ddfa59
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/trace-stderr.txt
@@ -0,0 +1,2 @@
+^.*/Tests/RunCMake/CommandLine/CMakeLists.txt\(1\): cmake_minimum_required\(VERSION 3.0 \)
+.*/Tests/RunCMake/CommandLine/CMakeLists.txt\(2\): project\(\${RunCMake_TEST} NONE \)
diff --git a/Tests/RunCMake/CommandLine/trace.cmake b/Tests/RunCMake/CommandLine/trace.cmake
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/trace.cmake
diff --git a/Tests/RunCMake/CommandLineTar/7zip-gz-result.txt b/Tests/RunCMake/CommandLineTar/7zip-gz-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/7zip-gz-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLineTar/7zip-gz-stderr.txt b/Tests/RunCMake/CommandLineTar/7zip-gz-stderr.txt
new file mode 100644
index 000000000..2fad3266d
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/7zip-gz-stderr.txt
@@ -0,0 +1 @@
+CMake Error: Can not use compression flags with format: 7zip
diff --git a/Tests/RunCMake/CommandLineTar/7zip.cmake b/Tests/RunCMake/CommandLineTar/7zip.cmake
new file mode 100644
index 000000000..4bc654846
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/7zip.cmake
@@ -0,0 +1,10 @@
+set(OUTPUT_NAME "test.7z")
+
+set(COMPRESSION_FLAGS cvf)
+set(COMPRESSION_OPTIONS --format=7zip)
+
+set(DECOMPRESSION_FLAGS xvf)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("377abcaf271c" LIMIT 6 HEX)
diff --git a/Tests/RunCMake/CommandLineTar/CMakeLists.txt b/Tests/RunCMake/CommandLineTar/CMakeLists.txt
new file mode 100644
index 000000000..289710955
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.0)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CommandLineTar/RunCMakeTest.cmake b/Tests/RunCMake/CommandLineTar/RunCMakeTest.cmake
new file mode 100644
index 000000000..12635dbfb
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/RunCMakeTest.cmake
@@ -0,0 +1,28 @@
+include(RunCMake)
+
+function(external_command_test NAME)
+ run_cmake_command(${NAME} ${CMAKE_COMMAND} -E ${ARGN})
+endfunction()
+
+external_command_test(bad-opt1 tar cvf bad.tar --bad)
+external_command_test(bad-mtime1 tar cvf bad.tar --mtime=bad .)
+external_command_test(bad-from1 tar cvf bad.tar --files-from=bad)
+external_command_test(bad-from2 tar cvf bad.tar --files-from=.)
+external_command_test(bad-from3 tar cvf bad.tar --files-from=${CMAKE_CURRENT_LIST_DIR}/bad-from3.txt)
+external_command_test(bad-from4 tar cvf bad.tar --files-from=${CMAKE_CURRENT_LIST_DIR}/bad-from4.txt)
+external_command_test(bad-from5 tar cvf bad.tar --files-from=${CMAKE_CURRENT_LIST_DIR}/bad-from5.txt)
+external_command_test(end-opt1 tar cvf bad.tar -- --bad)
+external_command_test(end-opt2 tar cvf bad.tar --)
+external_command_test(mtime tar cvf bad.tar "--mtime=1970-01-01 00:00:00 UTC")
+external_command_test(bad-format tar cvf bad.tar "--format=bad-format")
+external_command_test(zip-bz2 tar cvjf bad.tar "--format=zip")
+external_command_test(7zip-gz tar cvzf bad.tar "--format=7zip")
+
+run_cmake(7zip)
+run_cmake(gnutar)
+run_cmake(gnutar-gz)
+run_cmake(pax)
+run_cmake(pax-xz)
+run_cmake(paxr)
+run_cmake(paxr-bz2)
+run_cmake(zip)
diff --git a/Tests/RunCMake/CommandLineTar/bad-format-result.txt b/Tests/RunCMake/CommandLineTar/bad-format-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/bad-format-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLineTar/bad-format-stderr.txt b/Tests/RunCMake/CommandLineTar/bad-format-stderr.txt
new file mode 100644
index 000000000..fe9e2dccf
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/bad-format-stderr.txt
@@ -0,0 +1 @@
+CMake Error: Unknown -E tar --format= argument: bad-format
diff --git a/Tests/RunCMake/CommandLineTar/bad-from1-result.txt b/Tests/RunCMake/CommandLineTar/bad-from1-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/bad-from1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLineTar/bad-from1-stderr.txt b/Tests/RunCMake/CommandLineTar/bad-from1-stderr.txt
new file mode 100644
index 000000000..d67431d40
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/bad-from1-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: -E tar --files-from= file 'bad' not found$
diff --git a/Tests/RunCMake/CommandLineTar/bad-from2-result.txt b/Tests/RunCMake/CommandLineTar/bad-from2-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/bad-from2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLineTar/bad-from2-stderr.txt b/Tests/RunCMake/CommandLineTar/bad-from2-stderr.txt
new file mode 100644
index 000000000..d1d278c73
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/bad-from2-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: -E tar --files-from= file '\.' is a directory$
diff --git a/Tests/RunCMake/CommandLineTar/bad-from3-result.txt b/Tests/RunCMake/CommandLineTar/bad-from3-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/bad-from3-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLineTar/bad-from3-stderr.txt b/Tests/RunCMake/CommandLineTar/bad-from3-stderr.txt
new file mode 100644
index 000000000..da32ad917
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/bad-from3-stderr.txt
@@ -0,0 +1,2 @@
+^CMake Error: -E tar --files-from='.*/Tests/RunCMake/CommandLineTar/bad-from3.txt' file invalid line:
+-add-file=option-typo$
diff --git a/Tests/RunCMake/CommandLineTar/bad-from3.txt b/Tests/RunCMake/CommandLineTar/bad-from3.txt
new file mode 100644
index 000000000..5bad1c3f3
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/bad-from3.txt
@@ -0,0 +1 @@
+-add-file=option-typo
diff --git a/Tests/RunCMake/CommandLineTar/bad-from4-result.txt b/Tests/RunCMake/CommandLineTar/bad-from4-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/bad-from4-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLineTar/bad-from4-stderr.txt b/Tests/RunCMake/CommandLineTar/bad-from4-stderr.txt
new file mode 100644
index 000000000..1417d4d32
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/bad-from4-stderr.txt
@@ -0,0 +1,2 @@
+^CMake Error: archive_read_disk_entry_from_file 'does-not-exist':.*
+CMake Error: Problem creating tar: bad.tar$
diff --git a/Tests/RunCMake/CommandLineTar/bad-from4.txt b/Tests/RunCMake/CommandLineTar/bad-from4.txt
new file mode 100644
index 000000000..4b97f796c
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/bad-from4.txt
@@ -0,0 +1,2 @@
+
+does-not-exist
diff --git a/Tests/RunCMake/CommandLineTar/bad-from5-result.txt b/Tests/RunCMake/CommandLineTar/bad-from5-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/bad-from5-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLineTar/bad-from5-stderr.txt b/Tests/RunCMake/CommandLineTar/bad-from5-stderr.txt
new file mode 100644
index 000000000..1417d4d32
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/bad-from5-stderr.txt
@@ -0,0 +1,2 @@
+^CMake Error: archive_read_disk_entry_from_file 'does-not-exist':.*
+CMake Error: Problem creating tar: bad.tar$
diff --git a/Tests/RunCMake/CommandLineTar/bad-from5.txt b/Tests/RunCMake/CommandLineTar/bad-from5.txt
new file mode 100644
index 000000000..9ea755b26
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/bad-from5.txt
@@ -0,0 +1,2 @@
+
+--add-file=does-not-exist
diff --git a/Tests/RunCMake/CommandLineTar/bad-mtime1-result.txt b/Tests/RunCMake/CommandLineTar/bad-mtime1-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/bad-mtime1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLineTar/bad-mtime1-stderr.txt b/Tests/RunCMake/CommandLineTar/bad-mtime1-stderr.txt
new file mode 100644
index 000000000..ca925f160
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/bad-mtime1-stderr.txt
@@ -0,0 +1,2 @@
+^CMake Error: unable to parse mtime 'bad'
+CMake Error: Problem creating tar: bad.tar$
diff --git a/Tests/RunCMake/CommandLineTar/bad-opt1-result.txt b/Tests/RunCMake/CommandLineTar/bad-opt1-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/bad-opt1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLineTar/bad-opt1-stderr.txt b/Tests/RunCMake/CommandLineTar/bad-opt1-stderr.txt
new file mode 100644
index 000000000..35133c80d
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/bad-opt1-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: Unknown option to -E tar: --bad$
diff --git a/Tests/RunCMake/CommandLineTar/end-opt1-result.txt b/Tests/RunCMake/CommandLineTar/end-opt1-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/end-opt1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLineTar/end-opt1-stderr.txt b/Tests/RunCMake/CommandLineTar/end-opt1-stderr.txt
new file mode 100644
index 000000000..1fddf6d2d
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/end-opt1-stderr.txt
@@ -0,0 +1,2 @@
+^CMake Error: archive_read_disk_entry_from_file '--bad':.*
+CMake Error: Problem creating tar: bad.tar$
diff --git a/Tests/RunCMake/CommandLineTar/gnutar-gz.cmake b/Tests/RunCMake/CommandLineTar/gnutar-gz.cmake
new file mode 100644
index 000000000..5f2674a8f
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/gnutar-gz.cmake
@@ -0,0 +1,10 @@
+set(OUTPUT_NAME "test.tar.gz")
+
+set(COMPRESSION_FLAGS cvzf)
+set(COMPRESSION_OPTIONS --format=gnutar)
+
+set(DECOMPRESSION_FLAGS xvzf)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("1f8b" LIMIT 2 HEX)
diff --git a/Tests/RunCMake/CommandLineTar/gnutar.cmake b/Tests/RunCMake/CommandLineTar/gnutar.cmake
new file mode 100644
index 000000000..aaca596f5
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/gnutar.cmake
@@ -0,0 +1,10 @@
+set(OUTPUT_NAME "test.tar")
+
+set(COMPRESSION_FLAGS cvf)
+set(COMPRESSION_OPTIONS --format=gnutar)
+
+set(DECOMPRESSION_FLAGS xvf)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("7573746172202000" OFFSET 257 LIMIT 8 HEX)
diff --git a/Tests/RunCMake/CommandLineTar/pax-xz.cmake b/Tests/RunCMake/CommandLineTar/pax-xz.cmake
new file mode 100644
index 000000000..baf63d5c8
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/pax-xz.cmake
@@ -0,0 +1,10 @@
+set(OUTPUT_NAME "test.tar.xz")
+
+set(COMPRESSION_FLAGS cvJf)
+set(COMPRESSION_OPTIONS --format=pax)
+
+set(DECOMPRESSION_FLAGS xvJf)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("fd377a585a00" LIMIT 6 HEX)
diff --git a/Tests/RunCMake/CommandLineTar/pax.cmake b/Tests/RunCMake/CommandLineTar/pax.cmake
new file mode 100644
index 000000000..60ed2385c
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/pax.cmake
@@ -0,0 +1,10 @@
+set(OUTPUT_NAME "test.tar")
+
+set(COMPRESSION_FLAGS cvf)
+set(COMPRESSION_OPTIONS --format=pax)
+
+set(DECOMPRESSION_FLAGS xvf)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("7573746172003030" OFFSET 257 LIMIT 8 HEX)
diff --git a/Tests/RunCMake/CommandLineTar/paxr-bz2.cmake b/Tests/RunCMake/CommandLineTar/paxr-bz2.cmake
new file mode 100644
index 000000000..881a0af3b
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/paxr-bz2.cmake
@@ -0,0 +1,10 @@
+set(OUTPUT_NAME "test.tar.bz2")
+
+set(COMPRESSION_FLAGS cvjf)
+set(COMPRESSION_OPTIONS --format=paxr)
+
+set(DECOMPRESSION_FLAGS xvjf)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("425a68" LIMIT 3 HEX)
diff --git a/Tests/RunCMake/CommandLineTar/paxr.cmake b/Tests/RunCMake/CommandLineTar/paxr.cmake
new file mode 100644
index 000000000..968a103ca
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/paxr.cmake
@@ -0,0 +1,10 @@
+set(OUTPUT_NAME "test.tar")
+
+set(COMPRESSION_FLAGS cvf)
+set(COMPRESSION_OPTIONS --format=paxr)
+
+set(DECOMPRESSION_FLAGS xvf)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("7573746172003030" OFFSET 257 LIMIT 8 HEX)
diff --git a/Tests/RunCMake/CommandLineTar/roundtrip.cmake b/Tests/RunCMake/CommandLineTar/roundtrip.cmake
new file mode 100644
index 000000000..dc1c88528
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/roundtrip.cmake
@@ -0,0 +1,81 @@
+foreach(parameter OUTPUT_NAME COMPRESSION_FLAGS DECOMPRESSION_FLAGS)
+ if(NOT DEFINED ${parameter})
+ message(FATAL_ERROR "missing required parameter ${parameter}")
+ endif()
+endforeach()
+
+function(run_tar WORKING_DIRECTORY)
+ execute_process(COMMAND ${CMAKE_COMMAND} -E tar ${ARGN}
+ WORKING_DIRECTORY ${WORKING_DIRECTORY}
+ RESULT_VARIABLE result
+ )
+
+ if(NOT result STREQUAL "0")
+ message(FATAL_ERROR "tar failed with arguments [${ARGN}] result [${result}]")
+ endif()
+endfunction()
+
+set(COMPRESS_DIR compress_dir)
+set(FULL_COMPRESS_DIR ${CMAKE_CURRENT_BINARY_DIR}/${COMPRESS_DIR})
+
+set(DECOMPRESS_DIR decompress_dir)
+set(FULL_DECOMPRESS_DIR ${CMAKE_CURRENT_BINARY_DIR}/${DECOMPRESS_DIR})
+
+set(FULL_OUTPUT_NAME ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_NAME})
+
+set(CHECK_FILES
+ "f1.txt"
+ "d1/f1.txt"
+ "d 2/f1.txt"
+ "d + 3/f1.txt"
+ "d_4/f1.txt"
+ "d-4/f1.txt"
+ "My Special Directory/f1.txt"
+)
+
+foreach(file ${CHECK_FILES})
+ configure_file(${CMAKE_CURRENT_LIST_FILE} ${FULL_COMPRESS_DIR}/${file} COPYONLY)
+endforeach()
+
+if(UNIX)
+ execute_process(COMMAND ln -sf f1.txt ${FULL_COMPRESS_DIR}/d1/f2.txt)
+ list(APPEND CHECK_FILES "d1/f2.txt")
+endif()
+
+file(REMOVE ${FULL_OUTPUT_NAME})
+file(REMOVE_RECURSE ${FULL_DECOMPRESS_DIR})
+file(MAKE_DIRECTORY ${FULL_DECOMPRESS_DIR})
+
+run_tar(${CMAKE_CURRENT_BINARY_DIR} ${COMPRESSION_FLAGS} ${FULL_OUTPUT_NAME} ${COMPRESSION_OPTIONS} ${COMPRESS_DIR})
+run_tar(${FULL_DECOMPRESS_DIR} ${DECOMPRESSION_FLAGS} ${FULL_OUTPUT_NAME} ${DECOMPRESSION_OPTIONS})
+
+foreach(file ${CHECK_FILES})
+ set(input ${FULL_COMPRESS_DIR}/${file})
+ set(output ${FULL_DECOMPRESS_DIR}/${COMPRESS_DIR}/${file})
+
+ if(NOT EXISTS ${input})
+ message(SEND_ERROR "Cannot find input file ${output}")
+ endif()
+
+ if(NOT EXISTS ${output})
+ message(SEND_ERROR "Cannot find output file ${output}")
+ endif()
+
+ file(MD5 ${input} input_md5)
+ file(MD5 ${output} output_md5)
+
+ if(NOT input_md5 STREQUAL output_md5)
+ message(SEND_ERROR "Files \"${input}\" and \"${output}\" are different")
+ endif()
+endforeach()
+
+function(check_magic EXPECTED)
+ file(READ ${FULL_OUTPUT_NAME} ACTUAL
+ ${ARGN}
+ )
+
+ if(NOT ACTUAL STREQUAL EXPECTED)
+ message(FATAL_ERROR
+ "Actual [${ACTUAL}] does not match expected [${EXPECTED}]")
+ endif()
+endfunction()
diff --git a/Tests/RunCMake/CommandLineTar/zip-bz2-result.txt b/Tests/RunCMake/CommandLineTar/zip-bz2-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/zip-bz2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLineTar/zip-bz2-stderr.txt b/Tests/RunCMake/CommandLineTar/zip-bz2-stderr.txt
new file mode 100644
index 000000000..1134b4fd4
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/zip-bz2-stderr.txt
@@ -0,0 +1 @@
+CMake Error: Can not use compression flags with format: zip
diff --git a/Tests/RunCMake/CommandLineTar/zip.cmake b/Tests/RunCMake/CommandLineTar/zip.cmake
new file mode 100644
index 000000000..08e2fdb9c
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/zip.cmake
@@ -0,0 +1,10 @@
+set(OUTPUT_NAME "test.zip")
+
+set(COMPRESSION_FLAGS cvf)
+set(COMPRESSION_OPTIONS --format=zip)
+
+set(DECOMPRESSION_FLAGS xvf)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("504b0304" LIMIT 4 HEX)
diff --git a/Tests/RunCMake/CompatibleInterface/AutoUic-result.txt b/Tests/RunCMake/CompatibleInterface/AutoUic-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/AutoUic-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompatibleInterface/AutoUic-stderr.txt b/Tests/RunCMake/CompatibleInterface/AutoUic-stderr.txt
new file mode 100644
index 000000000..09f9461da
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/AutoUic-stderr.txt
@@ -0,0 +1,11 @@
+CMake Error: The INTERFACE_AUTOUIC_OPTIONS property of "OtherI18n" does
+not agree with the value of AUTOUIC_OPTIONS already determined
+for "LibWidget".
+
+CMake Debug Log:
+ String compatibility of property "AUTOUIC_OPTIONS" for target "LibWidget"
+ \(result: "-tr;ki18n"\):
+
+ \* Target "LibWidget" property not set.
+ \* Target "KI18n" property value "-tr;ki18n" \(Interface set\)
+ \* Target "OtherI18n" property value "-tr;otheri18n" \(Disagree\)
diff --git a/Tests/RunCMake/CompatibleInterface/AutoUic.cmake b/Tests/RunCMake/CompatibleInterface/AutoUic.cmake
new file mode 100644
index 000000000..03635e2a5
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/AutoUic.cmake
@@ -0,0 +1,19 @@
+
+find_package(Qt4 REQUIRED)
+
+set(CMAKE_AUTOUIC ON)
+
+set(CMAKE_DEBUG_TARGET_PROPERTIES AUTOUIC_OPTIONS)
+
+add_library(KI18n INTERFACE)
+set_property(TARGET KI18n APPEND PROPERTY
+ INTERFACE_AUTOUIC_OPTIONS -tr ki18n
+)
+
+add_library(OtherI18n INTERFACE)
+set_property(TARGET OtherI18n APPEND PROPERTY
+ INTERFACE_AUTOUIC_OPTIONS -tr otheri18n
+)
+
+add_library(LibWidget empty.cpp)
+target_link_libraries(LibWidget KI18n OtherI18n Qt4::QtGui)
diff --git a/Tests/RunCMake/CompatibleInterface/DebugProperties-result.txt b/Tests/RunCMake/CompatibleInterface/DebugProperties-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/DebugProperties-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CompatibleInterface/DebugProperties-stderr.txt b/Tests/RunCMake/CompatibleInterface/DebugProperties-stderr.txt
new file mode 100644
index 000000000..17b8a5cfe
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/DebugProperties-stderr.txt
@@ -0,0 +1,101 @@
+CMake Debug Log:
+ Boolean compatibility of property "BOOL_PROP1" for target
+ "CompatibleInterface" \(result: "TRUE"\):
+
+ \* Target "CompatibleInterface" property not set.
+ \* Target "iface1" property value "TRUE" \(Interface set\)
++
+CMake Debug Log:
+ Boolean compatibility of property "BOOL_PROP2" for target
+ "CompatibleInterface" \(result: "TRUE"\):
+
+ \* Target "CompatibleInterface" has property content "TRUE"
+ \* Target "iface1" property value "TRUE" \(Agree\)
++
+CMake Debug Log:
+ Boolean compatibility of property "BOOL_PROP3" for target
+ "CompatibleInterface" \(result: "TRUE"\):
+
+ \* Target "CompatibleInterface" has property content "TRUE"
++
+CMake Debug Log:
+ Boolean compatibility of property "BOOL_PROP4" for target
+ "CompatibleInterface" \(result: "FALSE"\):
+
+ \* Target "CompatibleInterface" property not set.
++
+CMake Debug Log:
+ Boolean compatibility of property "BOOL_PROP5" for target
+ "CompatibleInterface" \(result: "FALSE"\):
+
+ \* Target "CompatibleInterface" property not set.
+ \* Target "iface1" property value "FALSE" \(Interface set\)
++
+CMake Debug Log:
+ Boolean compatibility of property "BOOL_PROP6" for target
+ "CompatibleInterface" \(result: "FALSE"\):
+
+ \* Target "CompatibleInterface" property not set.
+ \* Target "iface1" property value "FALSE" \(Interface set\)
+ \* Target "iface2" property value "FALSE" \(Agree\)
++
+CMake Debug Log:
+ Boolean compatibility of property "BOOL_PROP7" for target
+ "CompatibleInterface" \(result: "FALSE"\):
+
+ \* Target "CompatibleInterface" property is implied by use.
+ \* Target "iface1" property value "FALSE" \(Agree\)
++
+CMake Debug Log:
+ String compatibility of property "STRING_PROP1" for target
+ "CompatibleInterface" \(result: "prop1"\):
+
+ \* Target "CompatibleInterface" property not set.
+ \* Target "iface1" property value "prop1" \(Interface set\)
++
+CMake Debug Log:
+ String compatibility of property "STRING_PROP2" for target
+ "CompatibleInterface" \(result: "prop2"\):
+
+ \* Target "CompatibleInterface" has property content "prop2"
+ \* Target "iface1" property value "prop2" \(Agree\)
++
+CMake Debug Log:
+ String compatibility of property "STRING_PROP3" for target
+ "CompatibleInterface" \(result: "prop3"\):
+
+ \* Target "CompatibleInterface" has property content "prop3"
++
+CMake Debug Log:
+ String compatibility of property "STRING_PROP4" for target
+ "CompatibleInterface" \(result: "\(unset\)"\):
+
+ \* Target "CompatibleInterface" property not set.
++
+CMake Debug Log:
+ Numeric minimum compatibility of property "NUMBER_MIN_PROP1" for target
+ "CompatibleInterface" \(result: "50"\):
+
+ \* Target "CompatibleInterface" has property content "50"
+ \* Target "iface1" property value "100" \(Ignored\)
++
+CMake Debug Log:
+ Numeric minimum compatibility of property "NUMBER_MIN_PROP2" for target
+ "CompatibleInterface" \(result: "200"\):
+
+ \* Target "CompatibleInterface" has property content "250"
+ \* Target "iface1" property value "200" \(Dominant\)
++
+CMake Debug Log:
+ Numeric maximum compatibility of property "NUMBER_MAX_PROP1" for target
+ "CompatibleInterface" \(result: "100"\):
+
+ \* Target "CompatibleInterface" has property content "50"
+ \* Target "iface1" property value "100" \(Dominant\)
++
+CMake Debug Log:
+ Numeric maximum compatibility of property "NUMBER_MAX_PROP2" for target
+ "CompatibleInterface" \(result: "250"\):
+
+ \* Target "CompatibleInterface" has property content "250"
+ \* Target "iface1" property value "200" \(Ignored\)
diff --git a/Tests/RunCMake/CompatibleInterface/DebugProperties.cmake b/Tests/RunCMake/CompatibleInterface/DebugProperties.cmake
new file mode 100644
index 000000000..0196611ca
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/DebugProperties.cmake
@@ -0,0 +1,74 @@
+
+cmake_minimum_required(VERSION 2.8)
+
+project(CompatibleInterface)
+
+include(GenerateExportHeader)
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_library(iface1 INTERFACE)
+set_property(TARGET iface1 APPEND PROPERTY
+ COMPATIBLE_INTERFACE_BOOL
+ BOOL_PROP1
+ BOOL_PROP2
+ BOOL_PROP3
+ BOOL_PROP4
+ BOOL_PROP5
+ BOOL_PROP6
+ BOOL_PROP7
+)
+set_property(TARGET iface1 APPEND PROPERTY
+ COMPATIBLE_INTERFACE_STRING
+ STRING_PROP1
+ STRING_PROP2
+ STRING_PROP3
+ STRING_PROP4 # Not set.
+)
+set_property(TARGET iface1 APPEND PROPERTY
+ COMPATIBLE_INTERFACE_NUMBER_MIN
+ NUMBER_MIN_PROP1
+ NUMBER_MIN_PROP2
+)
+set_property(TARGET iface1 APPEND PROPERTY
+ COMPATIBLE_INTERFACE_NUMBER_MAX
+ NUMBER_MAX_PROP1
+ NUMBER_MAX_PROP2
+)
+
+set(CMAKE_DEBUG_TARGET_PROPERTIES
+ BOOL_PROP1 BOOL_PROP2 BOOL_PROP3 BOOL_PROP4 BOOL_PROP5 BOOL_PROP6 BOOL_PROP7
+ STRING_PROP1 STRING_PROP2 STRING_PROP3 STRING_PROP4
+ NUMBER_MIN_PROP1 NUMBER_MIN_PROP2
+ NUMBER_MAX_PROP1 NUMBER_MAX_PROP2
+)
+
+set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP1 ON)
+set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP2 ON)
+set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP5 OFF)
+set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP6 OFF)
+set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP7 OFF)
+set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP1 prop1)
+set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP2 prop2)
+set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP1 100)
+set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP2 200)
+set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MAX_PROP1 100)
+set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MAX_PROP2 200)
+
+add_library(iface2 INTERFACE)
+set_property(TARGET iface2 PROPERTY INTERFACE_BOOL_PROP6 OFF)
+
+add_library(iface3 INTERFACE)
+
+add_executable(CompatibleInterface empty.cpp)
+target_link_libraries(CompatibleInterface iface1 iface2
+ $<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP7>>:iface3>
+)
+
+set_property(TARGET CompatibleInterface PROPERTY BOOL_PROP2 ON)
+set_property(TARGET CompatibleInterface PROPERTY BOOL_PROP3 ON)
+set_property(TARGET CompatibleInterface PROPERTY STRING_PROP2 prop2)
+set_property(TARGET CompatibleInterface PROPERTY STRING_PROP3 prop3)
+set_property(TARGET CompatibleInterface PROPERTY NUMBER_MIN_PROP1 50)
+set_property(TARGET CompatibleInterface PROPERTY NUMBER_MIN_PROP2 250)
+set_property(TARGET CompatibleInterface PROPERTY NUMBER_MAX_PROP1 50)
+set_property(TARGET CompatibleInterface PROPERTY NUMBER_MAX_PROP2 250)
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceNumber-mismatched-use-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceNumber-mismatched-use-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceNumber-mismatched-use-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceNumber-mismatched-use-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceNumber-mismatched-use-stderr.txt
new file mode 100644
index 000000000..723daec09
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceNumber-mismatched-use-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error: Property SOMEPROP on target "user" is
+implied to be empty because it was used to determine the link libraries
+already. The INTERFACE_SOMEPROP property on
+dependency "foo" is in conflict.
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceNumber-mismatched-use.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceNumber-mismatched-use.cmake
new file mode 100644
index 000000000..a064d7683
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceNumber-mismatched-use.cmake
@@ -0,0 +1,9 @@
+
+add_library(foo UNKNOWN IMPORTED)
+add_library(bar UNKNOWN IMPORTED)
+
+set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_NUMBER_MIN SOMEPROP)
+set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP 42)
+
+add_executable(user main.cpp)
+target_link_libraries(user foo $<$<STREQUAL:$<TARGET_PROPERTY:SOMEPROP>,42>:bar>)
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-stderr.txt
index 5a8f99df2..900e3f89e 100644
--- a/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-stderr.txt
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-stderr.txt
@@ -2,4 +2,5 @@ CMake Error in CMakeLists.txt:
Property "SOMETHING" appears in both the COMPATIBLE_INTERFACE_BOOL and the
COMPATIBLE_INTERFACE_STRING property in the dependencies of target "user".
This is not allowed. A property may only require compatibility in a
- boolean interpretation or a string interpretation, but not both.
+ boolean interpretation, a numeric minimum, a numeric maximum or a string
+ interpretation, but not a mixture.
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict.cmake
index 711368a80..4bae8042d 100644
--- a/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict.cmake
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict.cmake
@@ -1,9 +1,8 @@
add_library(foo UNKNOWN IMPORTED)
-add_library(bar UNKNOWN IMPORTED)
set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SOMETHING)
set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_STRING SOMETHING)
add_executable(user main.cpp)
-target_link_libraries(user foo bar)
+target_link_libraries(user foo)
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Min-Conflict-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Min-Conflict-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Min-Conflict-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Min-Conflict-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Min-Conflict-stderr.txt
new file mode 100644
index 000000000..2cfbae476
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Min-Conflict-stderr.txt
@@ -0,0 +1,7 @@
+CMake Error in CMakeLists.txt:
+ Property "OTHER" appears in both the COMPATIBLE_INTERFACE_BOOL,
+ COMPATIBLE_INTERFACE_NUMBER_MIN and the COMPATIBLE_INTERFACE_STRING
+ property in the dependencies of target "user". This is not allowed. A
+ property may only require compatibility in a boolean interpretation, a
+ numeric minimum, a numeric maximum or a string interpretation, but not a
+ mixture.
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Min-Conflict.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Min-Conflict.cmake
new file mode 100644
index 000000000..164ffd9fc
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Min-Conflict.cmake
@@ -0,0 +1,9 @@
+
+add_library(foo UNKNOWN IMPORTED)
+
+set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL OTHER)
+set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_STRING OTHER)
+set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_NUMBER_MIN OTHER)
+
+add_executable(user main.cpp)
+target_link_libraries(user foo)
diff --git a/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake b/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake
index 976815111..0b9729bf2 100644
--- a/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake
@@ -7,5 +7,13 @@ run_cmake(InterfaceBool-builtin-prop)
run_cmake(InterfaceString-mismatch-depends)
run_cmake(InterfaceString-mismatch-depend-self)
run_cmake(InterfaceString-mismatched-use)
+run_cmake(InterfaceNumber-mismatched-use)
run_cmake(InterfaceString-builtin-prop)
run_cmake(InterfaceString-Bool-Conflict)
+run_cmake(InterfaceString-Bool-Min-Conflict)
+run_cmake(DebugProperties)
+
+if (QT_QMAKE_EXECUTABLE})
+ set(RunCMake_TEST_OPTIONS -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE})
+ run_cmake(AutoUic)
+endif()
diff --git a/Tests/RunCMake/CompatibleInterface/empty.cpp b/Tests/RunCMake/CompatibleInterface/empty.cpp
new file mode 100644
index 000000000..00323299c
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/empty.cpp
@@ -0,0 +1 @@
+// no content
diff --git a/Tests/RunCMake/CompileDefinitions/CMakeLists.txt b/Tests/RunCMake/CompileDefinitions/CMakeLists.txt
new file mode 100644
index 000000000..74b3ff8de
--- /dev/null
+++ b/Tests/RunCMake/CompileDefinitions/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.3)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CompileDefinitions/RunCMakeTest.cmake b/Tests/RunCMake/CompileDefinitions/RunCMakeTest.cmake
new file mode 100644
index 000000000..233fe3467
--- /dev/null
+++ b/Tests/RunCMake/CompileDefinitions/RunCMakeTest.cmake
@@ -0,0 +1,3 @@
+include(RunCMake)
+
+run_cmake(SetEmpty)
diff --git a/Tests/RunCMake/CompileDefinitions/SetEmpty-result.txt b/Tests/RunCMake/CompileDefinitions/SetEmpty-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CompileDefinitions/SetEmpty-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CompileDefinitions/SetEmpty-stderr.txt b/Tests/RunCMake/CompileDefinitions/SetEmpty-stderr.txt
new file mode 100644
index 000000000..ace6656e2
--- /dev/null
+++ b/Tests/RunCMake/CompileDefinitions/SetEmpty-stderr.txt
@@ -0,0 +1,3 @@
+RESULT1=A;;B
+RESULT2=
+RESULT3=-DBAR
diff --git a/Tests/RunCMake/CompileDefinitions/SetEmpty.cmake b/Tests/RunCMake/CompileDefinitions/SetEmpty.cmake
new file mode 100644
index 000000000..15cb4e9a3
--- /dev/null
+++ b/Tests/RunCMake/CompileDefinitions/SetEmpty.cmake
@@ -0,0 +1,12 @@
+
+set_property(DIRECTORY PROPERTY COMPILE_DEFINITIONS A "" B)
+get_property(result DIRECTORY PROPERTY COMPILE_DEFINITIONS)
+message("RESULT1=${result}")
+
+set_property(DIRECTORY PROPERTY COMPILE_DEFINITIONS)
+get_property(result DIRECTORY PROPERTY COMPILE_DEFINITIONS)
+message("RESULT2=${result}")
+
+set_property(DIRECTORY PROPERTY COMPILE_DEFINITIONS -DBAR)
+get_property(result DIRECTORY PROPERTY COMPILE_DEFINITIONS)
+message("RESULT3=${result}")
diff --git a/Tests/RunCMake/CompileFeatures/CMakeLists.txt b/Tests/RunCMake/CompileFeatures/CMakeLists.txt
new file mode 100644
index 000000000..3482e6baf
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.0)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycle-result.txt b/Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycle-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycle-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycle-stderr.txt b/Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycle-stderr.txt
new file mode 100644
index 000000000..a584d7d8e
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycle-stderr.txt
@@ -0,0 +1,7 @@
+CMake Error in CMakeLists.txt:
+ The COMPILE_FEATURES property of target "empty1" was evaluated when
+ computing the link implementation, and the "CXX_STANDARD" was "98" for that
+ computation. Computing the COMPILE_FEATURES based on the link
+ implementation resulted in a higher "CXX_STANDARD" "11". This is not
+ permitted. The COMPILE_FEATURES may not both depend on and be depended on
+ by the link implementation.
diff --git a/Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycle.cmake b/Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycle.cmake
new file mode 100644
index 000000000..09594bda2
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycle.cmake
@@ -0,0 +1,15 @@
+
+add_library(empty1 empty.cpp)
+
+add_library(empty2 INTERFACE)
+add_library(empty3 INTERFACE)
+target_compile_features(empty3 INTERFACE cxx_static_assert)
+
+target_link_libraries(empty1
+ # When starting, $<COMPILE_FEATURES:cxx_auto_type> is '0', so 'freeze' the
+ # CXX_STANDARD at 98 during computation.
+ $<$<COMPILE_FEATURES:cxx_auto_type>:empty2>
+ # This would add cxx_static_assert, but that would require CXX_STANDARD = 11,
+ # which is not allowed after freeze. Report an error.
+ empty3
+)
diff --git a/Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycleSolved-result.txt b/Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycleSolved-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycleSolved-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycleSolved.cmake b/Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycleSolved.cmake
new file mode 100644
index 000000000..bbcf4e00a
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycleSolved.cmake
@@ -0,0 +1,14 @@
+
+add_library(empty1 empty.cpp)
+
+add_library(empty2 INTERFACE)
+add_library(empty3 INTERFACE)
+target_compile_features(empty3 INTERFACE cxx_static_assert)
+
+target_link_libraries(empty1
+ $<$<COMPILE_FEATURES:cxx_nullptr>:empty2>
+ empty3
+)
+# This, or populating the COMPILE_FEATURES property with a feature in the
+# same standard as cxx_nullptr, solves the cycle above.
+set_property(TARGET empty1 PROPERTY CXX_STANDARD 11)
diff --git a/Tests/RunCMake/CompileFeatures/NoSupportedCFeatures-result.txt b/Tests/RunCMake/CompileFeatures/NoSupportedCFeatures-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NoSupportedCFeatures-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/NoSupportedCFeatures-stderr.txt b/Tests/RunCMake/CompileFeatures/NoSupportedCFeatures-stderr.txt
new file mode 100644
index 000000000..fd18c885b
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NoSupportedCFeatures-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at NoSupportedCFeatures.cmake:[0-9]+ \(target_compile_features\):
+ target_compile_features no known features for C compiler
+
+ "[^"]*"
+
+ version *[.0-9]+\.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CompileFeatures/NoSupportedCFeatures.cmake b/Tests/RunCMake/CompileFeatures/NoSupportedCFeatures.cmake
new file mode 100644
index 000000000..3624d4b9f
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NoSupportedCFeatures.cmake
@@ -0,0 +1,5 @@
+
+enable_language(C)
+
+add_library(no_features empty.c)
+target_compile_features(no_features PRIVATE c_static_assert)
diff --git a/Tests/RunCMake/CompileFeatures/NoSupportedCFeaturesGenex-result.txt b/Tests/RunCMake/CompileFeatures/NoSupportedCFeaturesGenex-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NoSupportedCFeaturesGenex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/NoSupportedCFeaturesGenex-stderr.txt b/Tests/RunCMake/CompileFeatures/NoSupportedCFeaturesGenex-stderr.txt
new file mode 100644
index 000000000..df647e8b3
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NoSupportedCFeaturesGenex-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error in CMakeLists.txt:
+ No known features for C compiler
+
+ "[^"]*"
+
+ version *[.0-9]+\.
diff --git a/Tests/RunCMake/CompileFeatures/NoSupportedCFeaturesGenex.cmake b/Tests/RunCMake/CompileFeatures/NoSupportedCFeaturesGenex.cmake
new file mode 100644
index 000000000..b6053aaf1
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NoSupportedCFeaturesGenex.cmake
@@ -0,0 +1,5 @@
+
+enable_language(C)
+
+add_library(no_features empty.c)
+target_compile_features(no_features PRIVATE $<1:c_static_assert>)
diff --git a/Tests/RunCMake/CompileFeatures/NoSupportedCxxFeatures-result.txt b/Tests/RunCMake/CompileFeatures/NoSupportedCxxFeatures-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NoSupportedCxxFeatures-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/NoSupportedCxxFeatures-stderr.txt b/Tests/RunCMake/CompileFeatures/NoSupportedCxxFeatures-stderr.txt
new file mode 100644
index 000000000..fc882cb1e
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NoSupportedCxxFeatures-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at NoSupportedCxxFeatures.cmake:3 \(target_compile_features\):
+ target_compile_features no known features for CXX compiler
+
+ "[^"]*"
+
+ version *[.0-9]+\.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CompileFeatures/NoSupportedCxxFeatures.cmake b/Tests/RunCMake/CompileFeatures/NoSupportedCxxFeatures.cmake
new file mode 100644
index 000000000..512194879
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NoSupportedCxxFeatures.cmake
@@ -0,0 +1,3 @@
+
+add_library(no_features empty.cpp)
+target_compile_features(no_features PRIVATE cxx_constexpr)
diff --git a/Tests/RunCMake/CompileFeatures/NoSupportedCxxFeaturesGenex-result.txt b/Tests/RunCMake/CompileFeatures/NoSupportedCxxFeaturesGenex-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NoSupportedCxxFeaturesGenex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/NoSupportedCxxFeaturesGenex-stderr.txt b/Tests/RunCMake/CompileFeatures/NoSupportedCxxFeaturesGenex-stderr.txt
new file mode 100644
index 000000000..66d0d4148
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NoSupportedCxxFeaturesGenex-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error in CMakeLists.txt:
+ No known features for CXX compiler
+
+ "[^"]*"
+
+ version *[.0-9]+\.
diff --git a/Tests/RunCMake/CompileFeatures/NoSupportedCxxFeaturesGenex.cmake b/Tests/RunCMake/CompileFeatures/NoSupportedCxxFeaturesGenex.cmake
new file mode 100644
index 000000000..490f187f5
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NoSupportedCxxFeaturesGenex.cmake
@@ -0,0 +1,3 @@
+
+add_library(no_features empty.cpp)
+target_compile_features(no_features PRIVATE $<1:cxx_constexpr>)
diff --git a/Tests/RunCMake/CompileFeatures/NonValidTarget1-result.txt b/Tests/RunCMake/CompileFeatures/NonValidTarget1-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NonValidTarget1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/NonValidTarget1-stderr.txt b/Tests/RunCMake/CompileFeatures/NonValidTarget1-stderr.txt
new file mode 100644
index 000000000..7f3b43b33
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NonValidTarget1-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at NonValidTarget1.cmake:[0-9]+ \(add_custom_command\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_FEATURES:cxx_final>
+
+ \$<COMPILE_FEATURE> may only be used with binary targets. It may not be
+ used with add_custom_command or add_custom_target.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CompileFeatures/NonValidTarget1.cmake b/Tests/RunCMake/CompileFeatures/NonValidTarget1.cmake
new file mode 100644
index 000000000..b544b9977
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NonValidTarget1.cmake
@@ -0,0 +1,17 @@
+
+set(genexvar $<COMPILE_FEATURES:cxx_final>)
+
+if (HAVE_FINAL)
+ set(expected_result 1)
+else()
+ set(expected_result 0)
+endif()
+
+add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/copied_file${expected_result}.cpp"
+ COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp" "${CMAKE_CURRENT_BINARY_DIR}/copied_file${genexvar}.cpp"
+)
+
+add_library(empty "${CMAKE_CURRENT_BINARY_DIR}/copied_file${genexvar}.cpp")
+if (HAVE_FINAL)
+ target_compile_features(empty PRIVATE cxx_final)
+endif()
diff --git a/Tests/RunCMake/CompileFeatures/NonValidTarget2-result.txt b/Tests/RunCMake/CompileFeatures/NonValidTarget2-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NonValidTarget2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/NonValidTarget2-stderr.txt b/Tests/RunCMake/CompileFeatures/NonValidTarget2-stderr.txt
new file mode 100644
index 000000000..635150c25
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NonValidTarget2-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at NonValidTarget2.cmake:4 \(add_custom_target\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_FEATURES:cxx_final>
+
+ \$<COMPILE_FEATURE> may only be used with binary targets. It may not be
+ used with add_custom_command or add_custom_target.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CompileFeatures/NonValidTarget2.cmake b/Tests/RunCMake/CompileFeatures/NonValidTarget2.cmake
new file mode 100644
index 000000000..c41bf57cc
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NonValidTarget2.cmake
@@ -0,0 +1,10 @@
+
+set(genexvar $<COMPILE_FEATURES:cxx_final>)
+
+add_custom_target(copy_target
+ COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp" "${CMAKE_CURRENT_BINARY_DIR}/copied_file${genexvar}.txt"
+)
+set_property(SOURCE "${CMAKE_CURRENT_BINARY_DIR}/copied_file0.cpp" PROPERTY GENERATED 1)
+set_property(SOURCE "${CMAKE_CURRENT_BINARY_DIR}/copied_file1.cpp" PROPERTY GENERATED 1)
+
+add_library(empty "${CMAKE_CURRENT_BINARY_DIR}/copied_file${genexvar}.cpp")
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature-result.txt b/Tests/RunCMake/CompileFeatures/NotAFeature-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature-stderr.txt b/Tests/RunCMake/CompileFeatures/NotAFeature-stderr.txt
new file mode 100644
index 000000000..ff60e50a5
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error in CMakeLists.txt:
+ Specified unknown feature "not_a_feature" for target "somelib".
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature.cmake b/Tests/RunCMake/CompileFeatures/NotAFeature.cmake
new file mode 100644
index 000000000..35246c8bd
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature.cmake
@@ -0,0 +1,3 @@
+
+add_library(somelib STATIC empty.cpp)
+set_property(TARGET somelib PROPERTY COMPILE_FEATURES "not_a_feature")
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeatureGenex-result.txt b/Tests/RunCMake/CompileFeatures/NotAFeatureGenex-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeatureGenex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeatureGenex-stderr.txt b/Tests/RunCMake/CompileFeatures/NotAFeatureGenex-stderr.txt
new file mode 100644
index 000000000..ff60e50a5
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeatureGenex-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error in CMakeLists.txt:
+ Specified unknown feature "not_a_feature" for target "somelib".
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeatureGenex.cmake b/Tests/RunCMake/CompileFeatures/NotAFeatureGenex.cmake
new file mode 100644
index 000000000..ad2bd371d
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeatureGenex.cmake
@@ -0,0 +1,3 @@
+
+add_library(somelib STATIC empty.cpp)
+set_property(TARGET somelib PROPERTY COMPILE_FEATURES "$<1:not_a_feature>")
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeatureTransitive-result.txt b/Tests/RunCMake/CompileFeatures/NotAFeatureTransitive-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeatureTransitive-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeatureTransitive-stderr.txt b/Tests/RunCMake/CompileFeatures/NotAFeatureTransitive-stderr.txt
new file mode 100644
index 000000000..ff60e50a5
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeatureTransitive-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error in CMakeLists.txt:
+ Specified unknown feature "not_a_feature" for target "somelib".
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeatureTransitive.cmake b/Tests/RunCMake/CompileFeatures/NotAFeatureTransitive.cmake
new file mode 100644
index 000000000..7311aecd8
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeatureTransitive.cmake
@@ -0,0 +1,6 @@
+
+add_library(iface INTERFACE)
+set_property(TARGET iface PROPERTY INTERFACE_COMPILE_FEATURES "not_a_feature")
+
+add_library(somelib STATIC empty.cpp)
+target_link_libraries(somelib iface)
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug-result.txt b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug-stderr.txt b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug-stderr.txt
new file mode 100644
index 000000000..60a8e51ce
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug-stderr.txt
@@ -0,0 +1,11 @@
+CMake Debug Log at NotAFeature_OriginDebug.cmake:4 \(set_property\):
+ Used compile features for target somelib:
+
+ \* not_a_feature
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+
+
+CMake Error in CMakeLists.txt:
+ Specified unknown feature "not_a_feature" for target "somelib".
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug.cmake b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug.cmake
new file mode 100644
index 000000000..350c2eaa9
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug.cmake
@@ -0,0 +1,4 @@
+
+set(CMAKE_DEBUG_TARGET_PROPERTIES COMPILE_FEATURES)
+add_library(somelib STATIC empty.cpp)
+set_property(TARGET somelib PROPERTY COMPILE_FEATURES "not_a_feature")
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugCommand-result.txt b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugCommand-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugCommand-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugCommand-stderr.txt b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugCommand-stderr.txt
new file mode 100644
index 000000000..1f2c113c2
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugCommand-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at NotAFeature_OriginDebugCommand.cmake:4 \(target_compile_features\):
+ target_compile_features specified unknown feature "not_a_feature" for
+ target "somelib".
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugCommand.cmake b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugCommand.cmake
new file mode 100644
index 000000000..467d9a17e
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugCommand.cmake
@@ -0,0 +1,4 @@
+
+set(CMAKE_DEBUG_TARGET_PROPERTIES COMPILE_FEATURES)
+add_library(somelib STATIC empty.cpp)
+target_compile_features(somelib PRIVATE not_a_feature)
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex-result.txt b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex-stderr.txt b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex-stderr.txt
new file mode 100644
index 000000000..08e20a856
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex-stderr.txt
@@ -0,0 +1,11 @@
+CMake Debug Log at NotAFeature_OriginDebugGenex.cmake:4 \(set_property\):
+ Used compile features for target somelib:
+
+ \* not_a_feature
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+
+
+CMake Error in CMakeLists.txt:
+ Specified unknown feature "not_a_feature" for target "somelib".
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex.cmake b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex.cmake
new file mode 100644
index 000000000..2122981bf
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex.cmake
@@ -0,0 +1,4 @@
+
+set(CMAKE_DEBUG_TARGET_PROPERTIES COMPILE_FEATURES)
+add_library(somelib STATIC empty.cpp)
+set_property(TARGET somelib PROPERTY COMPILE_FEATURES "$<1:not_a_feature>")
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive-result.txt b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive-stderr.txt b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive-stderr.txt
new file mode 100644
index 000000000..23c3305a7
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive-stderr.txt
@@ -0,0 +1,11 @@
+CMake Debug Log at NotAFeature_OriginDebugTransitive.cmake:6 \(target_link_libraries\):
+ Used compile features for target somelib:
+
+ \* not_a_feature
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+
+
+CMake Error in CMakeLists.txt:
+ Specified unknown feature "not_a_feature" for target "somelib".
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive.cmake b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive.cmake
new file mode 100644
index 000000000..05d00736d
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive.cmake
@@ -0,0 +1,6 @@
+
+set(CMAKE_DEBUG_TARGET_PROPERTIES COMPILE_FEATURES)
+add_library(iface INTERFACE)
+set_property(TARGET iface PROPERTY INTERFACE_COMPILE_FEATURES "not_a_feature")
+add_library(somelib STATIC empty.cpp)
+target_link_libraries(somelib iface)
diff --git a/Tests/RunCMake/CompileFeatures/NotAStandard-result.txt b/Tests/RunCMake/CompileFeatures/NotAStandard-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAStandard-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/NotAStandard-stderr.txt b/Tests/RunCMake/CompileFeatures/NotAStandard-stderr.txt
new file mode 100644
index 000000000..deab12f82
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAStandard-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at NotAStandard.cmake:[0-9]+ \(add_library\):
+ CXX_STANDARD is set to invalid value 'bad'
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/CompileFeatures/NotAStandard.cmake b/Tests/RunCMake/CompileFeatures/NotAStandard.cmake
new file mode 100644
index 000000000..11529d85a
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAStandard.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_CXX_STANDARD bad)
+add_library(somelib STATIC empty.cpp)
diff --git a/Tests/RunCMake/CompileFeatures/RequireCXX11-result.txt b/Tests/RunCMake/CompileFeatures/RequireCXX11-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/RequireCXX11-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/RequireCXX11-stderr.txt b/Tests/RunCMake/CompileFeatures/RequireCXX11-stderr.txt
new file mode 100644
index 000000000..0fc9112f8
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/RequireCXX11-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+ Target "foo" requires the language dialect "CXX11" , but CMake does not
+ know the compile flags to use to enable it.
diff --git a/Tests/RunCMake/CompileFeatures/RequireCXX11.cmake b/Tests/RunCMake/CompileFeatures/RequireCXX11.cmake
new file mode 100644
index 000000000..f60504f93
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/RequireCXX11.cmake
@@ -0,0 +1,5 @@
+
+add_library(foo empty.cpp)
+set_property(TARGET foo PROPERTY CXX_STANDARD 11)
+set_property(TARGET foo PROPERTY CXX_EXTENSIONS FALSE)
+set_property(TARGET foo PROPERTY CXX_STANDARD_REQUIRED TRUE)
diff --git a/Tests/RunCMake/CompileFeatures/RequireCXX11Ext-result.txt b/Tests/RunCMake/CompileFeatures/RequireCXX11Ext-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/RequireCXX11Ext-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/RequireCXX11Ext-stderr.txt b/Tests/RunCMake/CompileFeatures/RequireCXX11Ext-stderr.txt
new file mode 100644
index 000000000..5c68a1cf7
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/RequireCXX11Ext-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+ Target "foo" requires the language dialect "CXX11" \(with compiler
+ extensions\), but CMake does not know the compile flags to use to enable it.
diff --git a/Tests/RunCMake/CompileFeatures/RequireCXX11Ext.cmake b/Tests/RunCMake/CompileFeatures/RequireCXX11Ext.cmake
new file mode 100644
index 000000000..10b251aa4
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/RequireCXX11Ext.cmake
@@ -0,0 +1,4 @@
+
+add_library(foo empty.cpp)
+set_property(TARGET foo PROPERTY CXX_STANDARD 11)
+set_property(TARGET foo PROPERTY CXX_STANDARD_REQUIRED TRUE)
diff --git a/Tests/RunCMake/CompileFeatures/RequireCXX11ExtVariable-result.txt b/Tests/RunCMake/CompileFeatures/RequireCXX11ExtVariable-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/RequireCXX11ExtVariable-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/RequireCXX11ExtVariable-stderr.txt b/Tests/RunCMake/CompileFeatures/RequireCXX11ExtVariable-stderr.txt
new file mode 100644
index 000000000..5c68a1cf7
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/RequireCXX11ExtVariable-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+ Target "foo" requires the language dialect "CXX11" \(with compiler
+ extensions\), but CMake does not know the compile flags to use to enable it.
diff --git a/Tests/RunCMake/CompileFeatures/RequireCXX11ExtVariable.cmake b/Tests/RunCMake/CompileFeatures/RequireCXX11ExtVariable.cmake
new file mode 100644
index 000000000..29703db68
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/RequireCXX11ExtVariable.cmake
@@ -0,0 +1,4 @@
+
+set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
+add_library(foo empty.cpp)
+set_property(TARGET foo PROPERTY CXX_STANDARD 11)
diff --git a/Tests/RunCMake/CompileFeatures/RequireCXX11Variable-result.txt b/Tests/RunCMake/CompileFeatures/RequireCXX11Variable-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/RequireCXX11Variable-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/RequireCXX11Variable-stderr.txt b/Tests/RunCMake/CompileFeatures/RequireCXX11Variable-stderr.txt
new file mode 100644
index 000000000..0fc9112f8
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/RequireCXX11Variable-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+ Target "foo" requires the language dialect "CXX11" , but CMake does not
+ know the compile flags to use to enable it.
diff --git a/Tests/RunCMake/CompileFeatures/RequireCXX11Variable.cmake b/Tests/RunCMake/CompileFeatures/RequireCXX11Variable.cmake
new file mode 100644
index 000000000..c480997d4
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/RequireCXX11Variable.cmake
@@ -0,0 +1,5 @@
+
+set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
+add_library(foo empty.cpp)
+set_property(TARGET foo PROPERTY CXX_STANDARD 11)
+set_property(TARGET foo PROPERTY CXX_EXTENSIONS FALSE)
diff --git a/Tests/RunCMake/CompileFeatures/RequireCXX98-result.txt b/Tests/RunCMake/CompileFeatures/RequireCXX98-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/RequireCXX98-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/RequireCXX98-stderr.txt b/Tests/RunCMake/CompileFeatures/RequireCXX98-stderr.txt
new file mode 100644
index 000000000..47c86889f
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/RequireCXX98-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+ Target "foo" requires the language dialect "CXX98" , but CMake does not
+ know the compile flags to use to enable it.
diff --git a/Tests/RunCMake/CompileFeatures/RequireCXX98.cmake b/Tests/RunCMake/CompileFeatures/RequireCXX98.cmake
new file mode 100644
index 000000000..fd9fb6005
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/RequireCXX98.cmake
@@ -0,0 +1,5 @@
+
+add_library(foo empty.cpp)
+set_property(TARGET foo PROPERTY CXX_STANDARD 98)
+set_property(TARGET foo PROPERTY CXX_STANDARD_REQUIRED TRUE)
+set_property(TARGET foo PROPERTY CXX_EXTENSIONS FALSE)
diff --git a/Tests/RunCMake/CompileFeatures/RequireCXX98Ext-result.txt b/Tests/RunCMake/CompileFeatures/RequireCXX98Ext-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/RequireCXX98Ext-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/RequireCXX98Ext-stderr.txt b/Tests/RunCMake/CompileFeatures/RequireCXX98Ext-stderr.txt
new file mode 100644
index 000000000..b4fdf8a45
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/RequireCXX98Ext-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+ Target "foo" requires the language dialect "CXX98" \(with compiler
+ extensions\), but CMake does not know the compile flags to use to enable it.
diff --git a/Tests/RunCMake/CompileFeatures/RequireCXX98Ext.cmake b/Tests/RunCMake/CompileFeatures/RequireCXX98Ext.cmake
new file mode 100644
index 000000000..4ea595edb
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/RequireCXX98Ext.cmake
@@ -0,0 +1,4 @@
+
+add_library(foo empty.cpp)
+set_property(TARGET foo PROPERTY CXX_STANDARD 98)
+set_property(TARGET foo PROPERTY CXX_STANDARD_REQUIRED TRUE)
diff --git a/Tests/RunCMake/CompileFeatures/RequireCXX98ExtVariable-result.txt b/Tests/RunCMake/CompileFeatures/RequireCXX98ExtVariable-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/RequireCXX98ExtVariable-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/RequireCXX98ExtVariable-stderr.txt b/Tests/RunCMake/CompileFeatures/RequireCXX98ExtVariable-stderr.txt
new file mode 100644
index 000000000..b4fdf8a45
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/RequireCXX98ExtVariable-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+ Target "foo" requires the language dialect "CXX98" \(with compiler
+ extensions\), but CMake does not know the compile flags to use to enable it.
diff --git a/Tests/RunCMake/CompileFeatures/RequireCXX98ExtVariable.cmake b/Tests/RunCMake/CompileFeatures/RequireCXX98ExtVariable.cmake
new file mode 100644
index 000000000..0e3ef8dfb
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/RequireCXX98ExtVariable.cmake
@@ -0,0 +1,4 @@
+
+set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
+add_library(foo empty.cpp)
+set_property(TARGET foo PROPERTY CXX_STANDARD 98)
diff --git a/Tests/RunCMake/CompileFeatures/RequireCXX98Variable-result.txt b/Tests/RunCMake/CompileFeatures/RequireCXX98Variable-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/RequireCXX98Variable-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/RequireCXX98Variable-stderr.txt b/Tests/RunCMake/CompileFeatures/RequireCXX98Variable-stderr.txt
new file mode 100644
index 000000000..47c86889f
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/RequireCXX98Variable-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+ Target "foo" requires the language dialect "CXX98" , but CMake does not
+ know the compile flags to use to enable it.
diff --git a/Tests/RunCMake/CompileFeatures/RequireCXX98Variable.cmake b/Tests/RunCMake/CompileFeatures/RequireCXX98Variable.cmake
new file mode 100644
index 000000000..75622645b
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/RequireCXX98Variable.cmake
@@ -0,0 +1,5 @@
+
+set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
+add_library(foo empty.cpp)
+set_property(TARGET foo PROPERTY CXX_STANDARD 98)
+set_property(TARGET foo PROPERTY CXX_EXTENSIONS FALSE)
diff --git a/Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake b/Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake
new file mode 100644
index 000000000..8dc627d45
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake
@@ -0,0 +1,62 @@
+include(RunCMake)
+
+run_cmake(NotAFeature)
+run_cmake(NotAFeatureGenex)
+run_cmake(NotAFeatureTransitive)
+run_cmake(NotAFeature_OriginDebug)
+run_cmake(NotAFeature_OriginDebugGenex)
+run_cmake(NotAFeature_OriginDebugTransitive)
+run_cmake(NotAFeature_OriginDebugCommand)
+
+run_cmake(generate_feature_list)
+file(READ
+ "${RunCMake_BINARY_DIR}/generate_feature_list-build/c_features.txt"
+ C_FEATURES
+)
+file(READ
+ "${RunCMake_BINARY_DIR}/generate_feature_list-build/cxx_features.txt"
+ CXX_FEATURES
+)
+include("${RunCMake_BINARY_DIR}/generate_feature_list-build/c_standard_default.cmake")
+include("${RunCMake_BINARY_DIR}/generate_feature_list-build/cxx_standard_default.cmake")
+
+if (NOT C_FEATURES)
+ run_cmake(NoSupportedCFeatures)
+ run_cmake(NoSupportedCFeaturesGenex)
+endif()
+
+if (NOT CXX_FEATURES)
+ run_cmake(NoSupportedCxxFeatures)
+ run_cmake(NoSupportedCxxFeaturesGenex)
+else()
+ if(CXX_STANDARD_DEFAULT EQUAL 98)
+ run_cmake(LinkImplementationFeatureCycle)
+ endif()
+ run_cmake(LinkImplementationFeatureCycleSolved)
+
+ if (";${CXX_FEATURES};" MATCHES ";cxx_final;")
+ set(RunCMake_TEST_OPTIONS "-DHAVE_FINAL=1")
+ endif()
+ run_cmake(NonValidTarget1)
+ run_cmake(NonValidTarget2)
+ unset(RunCMake_TEST_OPTIONS)
+endif()
+
+if(CXX_STANDARD_DEFAULT)
+ run_cmake(NotAStandard)
+
+ foreach(standard 98 11)
+ file(READ
+ "${RunCMake_BINARY_DIR}/generate_feature_list-build/cxx${standard}_flag.txt"
+ CXX${standard}_FLAG
+ )
+ if (CXX${standard}_FLAG STREQUAL NOTFOUND)
+ run_cmake(RequireCXX${standard})
+ run_cmake(RequireCXX${standard}Variable)
+ endif()
+ if (CXX${standard}EXT_FLAG STREQUAL NOTFOUND)
+ run_cmake(RequireCXX${standard}Ext)
+ run_cmake(RequireCXX${standard}ExtVariable)
+ endif()
+ endforeach()
+endif()
diff --git a/Tests/RunCMake/CompileFeatures/empty.c b/Tests/RunCMake/CompileFeatures/empty.c
new file mode 100644
index 000000000..bfbbddeb9
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/empty.c
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CompileFeatures/empty.cpp b/Tests/RunCMake/CompileFeatures/empty.cpp
new file mode 100644
index 000000000..bfbbddeb9
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/empty.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CompileFeatures/generate_feature_list.cmake b/Tests/RunCMake/CompileFeatures/generate_feature_list.cmake
new file mode 100644
index 000000000..5c58052b8
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/generate_feature_list.cmake
@@ -0,0 +1,43 @@
+
+enable_language(C)
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/c_features.txt"
+ "${CMAKE_C_COMPILE_FEATURES}"
+)
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cxx_features.txt"
+ "${CMAKE_CXX_COMPILE_FEATURES}"
+)
+
+if(DEFINED CMAKE_C_STANDARD_DEFAULT)
+ set(c_standard_default_code "set(C_STANDARD_DEFAULT \"${CMAKE_C_STANDARD_DEFAULT}\")\n")
+else()
+ set(c_standard_default_code "unset(C_STANDARD_DEFAULT)\n")
+endif()
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/c_standard_default.cmake" "${c_standard_default_code}")
+
+if(DEFINED CMAKE_CXX_STANDARD_DEFAULT)
+ set(cxx_standard_default_code "set(CXX_STANDARD_DEFAULT \"${CMAKE_CXX_STANDARD_DEFAULT}\")\n")
+else()
+ set(cxx_standard_default_code "unset(CXX_STANDARD_DEFAULT)\n")
+endif()
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cxx_standard_default.cmake" "${cxx_standard_default_code}")
+
+foreach(standard 98 11)
+ set(CXX${standard}_FLAG NOTFOUND)
+ if (DEFINED CMAKE_CXX${standard}_STANDARD_COMPILE_OPTION)
+ set(CXX${standard}_FLAG ${CMAKE_CXX${standard}_STANDARD_COMPILE_OPTION})
+ endif()
+
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cxx${standard}_flag.txt"
+ "${CXX${standard}_FLAG}"
+ )
+ set(CXX${standard}EXT_FLAG NOTFOUND)
+ if (DEFINED CMAKE_CXX${standard}_EXTENSION_COMPILE_OPTION)
+ set(CXX${standard}EXT_FLAG ${CMAKE_CXX${standard}_EXTENSION_COMPILE_OPTION})
+ endif()
+
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cxx${standard}ext_flag.txt"
+ "${CXX${standard}EXT_FLAG}"
+ )
+endforeach()
diff --git a/Tests/RunCMake/CompilerChange/EmptyCompiler-override.cmake b/Tests/RunCMake/CompilerChange/EmptyCompiler-override.cmake
new file mode 100644
index 000000000..28d29e03e
--- /dev/null
+++ b/Tests/RunCMake/CompilerChange/EmptyCompiler-override.cmake
@@ -0,0 +1,2 @@
+message(STATUS "CMAKE_C_COMPILER is \"${CMAKE_C_COMPILER}\"")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cc.cmake" "set(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\")\n")
diff --git a/Tests/RunCMake/CompilerChange/EmptyCompiler-stderr.txt b/Tests/RunCMake/CompilerChange/EmptyCompiler-stderr.txt
index 4745b254d..cf3b1b346 100644
--- a/Tests/RunCMake/CompilerChange/EmptyCompiler-stderr.txt
+++ b/Tests/RunCMake/CompilerChange/EmptyCompiler-stderr.txt
@@ -1,5 +1,13 @@
You have changed variables that require your cache to be deleted.
Configure will be re-run and you may have to reset some variables.
The following variables have changed:
-CMAKE_C_COMPILER= *(
-|$)
+CMAKE_C_COMPILER= *
++
+CMake Error at EmptyCompiler.cmake:2 \(enable_language\):
+ No CMAKE_C_COMPILER could be found.
+
+ Tell CMake where to find the compiler by setting either the environment
+ variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to
+ the compiler, or to the compiler name if it is in the PATH.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:6 \(include\)$
diff --git a/Tests/RunCMake/CompilerChange/EmptyCompiler.cmake b/Tests/RunCMake/CompilerChange/EmptyCompiler.cmake
index c87ec4952..06e9e033b 100644
--- a/Tests/RunCMake/CompilerChange/EmptyCompiler.cmake
+++ b/Tests/RunCMake/CompilerChange/EmptyCompiler.cmake
@@ -1,3 +1,2 @@
+set(CMAKE_USER_MAKE_RULES_OVERRIDE_C ${CMAKE_CURRENT_LIST_DIR}/EmptyCompiler-override.cmake)
enable_language(C)
-message(STATUS "CMAKE_C_COMPILER is \"${CMAKE_C_COMPILER}\"")
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cc.cmake" "set(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\")\n")
diff --git a/Tests/RunCMake/CompilerChange/RunCMakeTest.cmake b/Tests/RunCMake/CompilerChange/RunCMakeTest.cmake
index d38371680..5bb2821d9 100644
--- a/Tests/RunCMake/CompilerChange/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CompilerChange/RunCMakeTest.cmake
@@ -22,8 +22,8 @@ set(ccIn ${RunCMake_SOURCE_DIR}/cc.sh.in)
set(cc1 ${RunCMake_BINARY_DIR}/cc1.sh)
set(cc2 ${RunCMake_BINARY_DIR}/cc2.sh)
set(cc3 CMAKE_C_COMPILER-NOTFOUND)
-configure_file(${ccIn} ${cc1} @ONLY IMMEDIATE)
-configure_file(${ccIn} ${cc2} @ONLY IMMEDIATE)
+configure_file(${ccIn} ${cc1} @ONLY)
+configure_file(${ccIn} ${cc2} @ONLY)
# Use a single build tree for remaining tests without cleaning.
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ChangeCompiler-build)
diff --git a/Tests/RunCMake/CompilerLauncher/C-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/C-Build-stdout.txt
new file mode 100644
index 000000000..3313e31f6
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/C-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/CompilerLauncher/C-launch-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/C-launch-Build-stdout.txt
new file mode 100644
index 000000000..3313e31f6
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/C-launch-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/CompilerLauncher/C-launch.cmake b/Tests/RunCMake/CompilerLauncher/C-launch.cmake
new file mode 100644
index 000000000..e66ca203e
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/C-launch.cmake
@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(C.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/C.cmake b/Tests/RunCMake/CompilerLauncher/C.cmake
new file mode 100644
index 000000000..67bf7c4ac
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/C.cmake
@@ -0,0 +1,4 @@
+enable_language(C)
+set(CMAKE_C_COMPILER_LAUNCHER "${CMAKE_COMMAND};-E;env;USED_LAUNCHER=1")
+set(CMAKE_VERBOSE_MAKEFILE TRUE)
+add_executable(main main.c)
diff --git a/Tests/RunCMake/CompilerLauncher/CMakeLists.txt b/Tests/RunCMake/CompilerLauncher/CMakeLists.txt
new file mode 100644
index 000000000..18dfd2686
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.2)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/CXX-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/CXX-Build-stdout.txt
new file mode 100644
index 000000000..3313e31f6
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/CXX-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/CompilerLauncher/CXX-launch-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/CXX-launch-Build-stdout.txt
new file mode 100644
index 000000000..3313e31f6
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/CXX-launch-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/CompilerLauncher/CXX-launch.cmake b/Tests/RunCMake/CompilerLauncher/CXX-launch.cmake
new file mode 100644
index 000000000..3002c9d68
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/CXX-launch.cmake
@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(CXX.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/CXX.cmake b/Tests/RunCMake/CompilerLauncher/CXX.cmake
new file mode 100644
index 000000000..cdd347804
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/CXX.cmake
@@ -0,0 +1,4 @@
+enable_language(CXX)
+set(CMAKE_CXX_COMPILER_LAUNCHER "${CMAKE_COMMAND};-E;env;USED_LAUNCHER=1")
+set(CMAKE_VERBOSE_MAKEFILE TRUE)
+add_executable(main main.cxx)
diff --git a/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake b/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake
new file mode 100644
index 000000000..5884d5c4d
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake
@@ -0,0 +1,23 @@
+include(RunCMake)
+
+function(run_compiler_launcher lang)
+ # Use a single build tree for tests without cleaning.
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${lang}-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ run_cmake(${lang})
+
+ set(RunCMake_TEST_OUTPUT_MERGE 1)
+ if("${RunCMake_GENERATOR}" STREQUAL "Ninja")
+ set(verbose_args -- -v)
+ endif()
+ run_cmake_command(${lang}-Build ${CMAKE_COMMAND} --build . ${verbose_args})
+endfunction()
+
+run_compiler_launcher(C)
+run_compiler_launcher(CXX)
+if (NOT RunCMake_GENERATOR STREQUAL "Watcom WMake")
+ run_compiler_launcher(C-launch)
+ run_compiler_launcher(CXX-launch)
+endif()
diff --git a/Tests/RunCMake/CompilerLauncher/main.c b/Tests/RunCMake/CompilerLauncher/main.c
new file mode 100644
index 000000000..03b2213bb
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/main.c
@@ -0,0 +1,3 @@
+int main(void) {
+ return 0;
+}
diff --git a/Tests/RunCMake/CompilerLauncher/main.cxx b/Tests/RunCMake/CompilerLauncher/main.cxx
new file mode 100644
index 000000000..76e819701
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/main.cxx
@@ -0,0 +1 @@
+int main() { return 0; }
diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerC-result.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerC-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/BadCompilerC-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerC-stderr-JOM.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerC-stderr-JOM.txt
new file mode 100644
index 000000000..b7db7eb58
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/BadCompilerC-stderr-JOM.txt
@@ -0,0 +1,17 @@
+CMake Error at BadCompilerC.cmake:2 \(enable_language\):
+ The CMAKE_C_COMPILER:
+
+ no-C-compiler
+
+ is not a full path and was not found in the PATH.
+
+ To use the JOM generator with Visual C\+\+, cmake must be run from a shell
+ that can use the compiler cl from the command line. This environment is
+ unable to invoke the cl compiler. To fix this problem, run cmake from the
+ Visual Studio Command Prompt \(vcvarsall.bat\).
+
+ Tell CMake where to find the compiler by setting either the environment
+ variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to
+ the compiler, or to the compiler name if it is in the PATH.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerC-stderr-NMake.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerC-stderr-NMake.txt
new file mode 100644
index 000000000..03c593340
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/BadCompilerC-stderr-NMake.txt
@@ -0,0 +1,17 @@
+CMake Error at BadCompilerC.cmake:2 \(enable_language\):
+ The CMAKE_C_COMPILER:
+
+ no-C-compiler
+
+ is not a full path and was not found in the PATH.
+
+ To use the NMake generator with Visual C\+\+, cmake must be run from a shell
+ that can use the compiler cl from the command line. This environment is
+ unable to invoke the cl compiler. To fix this problem, run cmake from the
+ Visual Studio Command Prompt \(vcvarsall.bat\).
+
+ Tell CMake where to find the compiler by setting either the environment
+ variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to
+ the compiler, or to the compiler name if it is in the PATH.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerC-stderr.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerC-stderr.txt
new file mode 100644
index 000000000..c98842d97
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/BadCompilerC-stderr.txt
@@ -0,0 +1,12 @@
+CMake Error at BadCompilerC.cmake:2 \(enable_language\):
+ The CMAKE_C_COMPILER:
+
+ no-C-compiler
+
+ is not a full path and was not found in the PATH.
+
+ Tell CMake where to find the compiler by setting either the environment
+ variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to
+ the compiler, or to the compiler name if it is in the PATH.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerC.cmake b/Tests/RunCMake/CompilerNotFound/BadCompilerC.cmake
new file mode 100644
index 000000000..10fe59aab
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/BadCompilerC.cmake
@@ -0,0 +1,3 @@
+set(CMAKE_C_COMPILER "no-C-compiler")
+enable_language(C)
+message(FATAL_ERROR "This error should not be reached.")
diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-result.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-stderr-JOM.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-stderr-JOM.txt
new file mode 100644
index 000000000..4b42ea6ff
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-stderr-JOM.txt
@@ -0,0 +1,17 @@
+CMake Error at BadCompilerCXX.cmake:2 \(enable_language\):
+ The CMAKE_CXX_COMPILER:
+
+ no-CXX-compiler
+
+ is not a full path and was not found in the PATH.
+
+ To use the JOM generator with Visual C\+\+, cmake must be run from a shell
+ that can use the compiler cl from the command line. This environment is
+ unable to invoke the cl compiler. To fix this problem, run cmake from the
+ Visual Studio Command Prompt \(vcvarsall.bat\).
+
+ Tell CMake where to find the compiler by setting either the environment
+ variable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full path
+ to the compiler, or to the compiler name if it is in the PATH.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-stderr-NMake.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-stderr-NMake.txt
new file mode 100644
index 000000000..1bfcdcc41
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-stderr-NMake.txt
@@ -0,0 +1,17 @@
+CMake Error at BadCompilerCXX.cmake:2 \(enable_language\):
+ The CMAKE_CXX_COMPILER:
+
+ no-CXX-compiler
+
+ is not a full path and was not found in the PATH.
+
+ To use the NMake generator with Visual C\+\+, cmake must be run from a shell
+ that can use the compiler cl from the command line. This environment is
+ unable to invoke the cl compiler. To fix this problem, run cmake from the
+ Visual Studio Command Prompt \(vcvarsall.bat\).
+
+ Tell CMake where to find the compiler by setting either the environment
+ variable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full path
+ to the compiler, or to the compiler name if it is in the PATH.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-stderr.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-stderr.txt
new file mode 100644
index 000000000..7ef4f5e7c
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-stderr.txt
@@ -0,0 +1,12 @@
+CMake Error at BadCompilerCXX.cmake:2 \(enable_language\):
+ The CMAKE_CXX_COMPILER:
+
+ no-CXX-compiler
+
+ is not a full path and was not found in the PATH.
+
+ Tell CMake where to find the compiler by setting either the environment
+ variable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full path
+ to the compiler, or to the compiler name if it is in the PATH.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerCXX.cmake b/Tests/RunCMake/CompilerNotFound/BadCompilerCXX.cmake
new file mode 100644
index 000000000..3b1e8900a
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/BadCompilerCXX.cmake
@@ -0,0 +1,3 @@
+set(CMAKE_CXX_COMPILER "no-CXX-compiler")
+enable_language(CXX)
+message(FATAL_ERROR "This error should not be reached.")
diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-result.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-stderr-JOM.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-stderr-JOM.txt
new file mode 100644
index 000000000..f25a267a6
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-stderr-JOM.txt
@@ -0,0 +1,35 @@
+CMake Error at BadCompilerCandCXX.cmake:3 \(project\):
+ The CMAKE_C_COMPILER:
+
+ no-C-compiler
+
+ is not a full path and was not found in the PATH.
+
+ To use the JOM generator with Visual C\+\+, cmake must be run from a shell
+ that can use the compiler cl from the command line. This environment is
+ unable to invoke the cl compiler. To fix this problem, run cmake from the
+ Visual Studio Command Prompt \(vcvarsall.bat\).
+
+ Tell CMake where to find the compiler by setting either the environment
+ variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to
+ the compiler, or to the compiler name if it is in the PATH.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at BadCompilerCandCXX.cmake:3 \(project\):
+ The CMAKE_CXX_COMPILER:
+
+ no-CXX-compiler
+
+ is not a full path and was not found in the PATH.
+
+ To use the JOM generator with Visual C\+\+, cmake must be run from a shell
+ that can use the compiler cl from the command line. This environment is
+ unable to invoke the cl compiler. To fix this problem, run cmake from the
+ Visual Studio Command Prompt \(vcvarsall.bat\).
+
+ Tell CMake where to find the compiler by setting either the environment
+ variable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full path
+ to the compiler, or to the compiler name if it is in the PATH.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-stderr-NMake.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-stderr-NMake.txt
new file mode 100644
index 000000000..ffcdce868
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-stderr-NMake.txt
@@ -0,0 +1,35 @@
+CMake Error at BadCompilerCandCXX.cmake:3 \(project\):
+ The CMAKE_C_COMPILER:
+
+ no-C-compiler
+
+ is not a full path and was not found in the PATH.
+
+ To use the NMake generator with Visual C\+\+, cmake must be run from a shell
+ that can use the compiler cl from the command line. This environment is
+ unable to invoke the cl compiler. To fix this problem, run cmake from the
+ Visual Studio Command Prompt \(vcvarsall.bat\).
+
+ Tell CMake where to find the compiler by setting either the environment
+ variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to
+ the compiler, or to the compiler name if it is in the PATH.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at BadCompilerCandCXX.cmake:3 \(project\):
+ The CMAKE_CXX_COMPILER:
+
+ no-CXX-compiler
+
+ is not a full path and was not found in the PATH.
+
+ To use the NMake generator with Visual C\+\+, cmake must be run from a shell
+ that can use the compiler cl from the command line. This environment is
+ unable to invoke the cl compiler. To fix this problem, run cmake from the
+ Visual Studio Command Prompt \(vcvarsall.bat\).
+
+ Tell CMake where to find the compiler by setting either the environment
+ variable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full path
+ to the compiler, or to the compiler name if it is in the PATH.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-stderr.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-stderr.txt
new file mode 100644
index 000000000..eecff54fd
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-stderr.txt
@@ -0,0 +1,25 @@
+CMake Error at BadCompilerCandCXX.cmake:3 \(project\):
+ The CMAKE_C_COMPILER:
+
+ no-C-compiler
+
+ is not a full path and was not found in the PATH.
+
+ Tell CMake where to find the compiler by setting either the environment
+ variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to
+ the compiler, or to the compiler name if it is in the PATH.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at BadCompilerCandCXX.cmake:3 \(project\):
+ The CMAKE_CXX_COMPILER:
+
+ no-CXX-compiler
+
+ is not a full path and was not found in the PATH.
+
+ Tell CMake where to find the compiler by setting either the environment
+ variable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full path
+ to the compiler, or to the compiler name if it is in the PATH.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX.cmake b/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX.cmake
new file mode 100644
index 000000000..2b6fa6126
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX.cmake
@@ -0,0 +1,4 @@
+set(CMAKE_C_COMPILER "no-C-compiler")
+set(CMAKE_CXX_COMPILER "no-CXX-compiler")
+project(BadCompilerCandCXXInner C CXX)
+message(FATAL_ERROR "This error should not be reached.")
diff --git a/Tests/RunCMake/CompilerNotFound/CMakeLists.txt b/Tests/RunCMake/CompilerNotFound/CMakeLists.txt
new file mode 100644
index 000000000..12cd3c775
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE-result.txt b/Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE-stderr.txt b/Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE-stderr.txt
new file mode 100644
index 000000000..88bb95e49
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at NoCompilerC-IDE.cmake:2 \(enable_language\):
+ No CMAKE_C_COMPILER could be found.
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE.cmake b/Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE.cmake
new file mode 100644
index 000000000..45e1a68c4
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE.cmake
@@ -0,0 +1,3 @@
+set(CMAKE_C_COMPILER_ID_ERROR_FOR_TEST "#error NoCompilerC-IDE")
+enable_language(C)
+message(FATAL_ERROR "This error should not be reached.")
diff --git a/Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE-result.txt b/Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE-stderr.txt b/Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE-stderr.txt
new file mode 100644
index 000000000..4c92323e2
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at NoCompilerCXX-IDE.cmake:2 \(enable_language\):
+ No CMAKE_CXX_COMPILER could be found.
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE.cmake b/Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE.cmake
new file mode 100644
index 000000000..85025a06b
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE.cmake
@@ -0,0 +1,3 @@
+set(CMAKE_CXX_COMPILER_ID_ERROR_FOR_TEST "#error NoCompilerCXX-IDE")
+enable_language(CXX)
+message(FATAL_ERROR "This error should not be reached.")
diff --git a/Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE-result.txt b/Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE-stderr.txt b/Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE-stderr.txt
new file mode 100644
index 000000000..21c69f579
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE-stderr.txt
@@ -0,0 +1,11 @@
+CMake Error at NoCompilerCandCXX-IDE.cmake:3 \(project\):
+ No CMAKE_C_COMPILER could be found.
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at NoCompilerCandCXX-IDE.cmake:3 \(project\):
+ No CMAKE_CXX_COMPILER could be found.
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE.cmake b/Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE.cmake
new file mode 100644
index 000000000..78256a963
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE.cmake
@@ -0,0 +1,4 @@
+set(CMAKE_C_COMPILER_ID_ERROR_FOR_TEST "#error NoCompilerCandCXX-IDE")
+set(CMAKE_CXX_COMPILER_ID_ERROR_FOR_TEST "#error NoCompilerCandCXX-IDE")
+project(NoCompilerCandCXXInner C CXX)
+message(FATAL_ERROR "This error should not be reached.")
diff --git a/Tests/RunCMake/CompilerNotFound/RunCMakeTest.cmake b/Tests/RunCMake/CompilerNotFound/RunCMakeTest.cmake
new file mode 100644
index 000000000..19d149c11
--- /dev/null
+++ b/Tests/RunCMake/CompilerNotFound/RunCMakeTest.cmake
@@ -0,0 +1,25 @@
+include(RunCMake)
+
+if("${RunCMake_GENERATOR}" MATCHES "Visual Studio|Xcode")
+ run_cmake(NoCompilerC-IDE)
+ run_cmake(NoCompilerCXX-IDE)
+ run_cmake(NoCompilerCandCXX-IDE)
+elseif(RunCMake_GENERATOR STREQUAL "NMake Makefiles")
+ set(RunCMake-stderr-file BadCompilerC-stderr-NMake.txt)
+ run_cmake(BadCompilerC)
+ set(RunCMake-stderr-file BadCompilerCXX-stderr-NMake.txt)
+ run_cmake(BadCompilerCXX)
+ set(RunCMake-stderr-file BadCompilerCandCXX-stderr-NMake.txt)
+ run_cmake(BadCompilerCandCXX)
+elseif(RunCMake_GENERATOR STREQUAL "NMake Makefiles JOM")
+ set(RunCMake-stderr-file BadCompilerC-stderr-JOM.txt)
+ run_cmake(BadCompilerC)
+ set(RunCMake-stderr-file BadCompilerCXX-stderr-JOM.txt)
+ run_cmake(BadCompilerCXX)
+ set(RunCMake-stderr-file BadCompilerCandCXX-stderr-JOM.txt)
+ run_cmake(BadCompilerCandCXX)
+else()
+ run_cmake(BadCompilerC)
+ run_cmake(BadCompilerCXX)
+ run_cmake(BadCompilerCandCXX)
+endif()
diff --git a/Tests/RunCMake/Configure/CustomTargetAfterError-result.txt b/Tests/RunCMake/Configure/CustomTargetAfterError-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Configure/CustomTargetAfterError-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Configure/CustomTargetAfterError-stderr.txt b/Tests/RunCMake/Configure/CustomTargetAfterError-stderr.txt
new file mode 100644
index 000000000..7ce7daf6f
--- /dev/null
+++ b/Tests/RunCMake/Configure/CustomTargetAfterError-stderr.txt
@@ -0,0 +1,9 @@
+^CMake Error at CustomTargetAfterError.cmake:1 \(message\):
+ Error before add_custom_target
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at CustomTargetAfterError.cmake:3 \(message\):
+ Error after add_custom_target
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/Configure/CustomTargetAfterError.cmake b/Tests/RunCMake/Configure/CustomTargetAfterError.cmake
new file mode 100644
index 000000000..3e264553b
--- /dev/null
+++ b/Tests/RunCMake/Configure/CustomTargetAfterError.cmake
@@ -0,0 +1,3 @@
+message(SEND_ERROR "Error before add_custom_target")
+add_custom_target(foo COMMAND echo)
+message(SEND_ERROR "Error after add_custom_target")
diff --git a/Tests/RunCMake/Configure/FailCopyFileABI-stdout.txt b/Tests/RunCMake/Configure/FailCopyFileABI-stdout.txt
index bb87f4c31..92fe2330a 100644
--- a/Tests/RunCMake/Configure/FailCopyFileABI-stdout.txt
+++ b/Tests/RunCMake/Configure/FailCopyFileABI-stdout.txt
@@ -1,4 +1,4 @@
-- Detecting C compiler ABI info
--- Detecting C compiler ABI info - failed
+-- Detecting C compiler ABI info - failed.*
-- Configuring done
-- Generating done
diff --git a/Tests/RunCMake/Configure/RerunCMake-build1-check.cmake b/Tests/RunCMake/Configure/RerunCMake-build1-check.cmake
new file mode 100644
index 000000000..dbf8f6750
--- /dev/null
+++ b/Tests/RunCMake/Configure/RerunCMake-build1-check.cmake
@@ -0,0 +1,9 @@
+file(READ ${stamp} content)
+if(NOT content STREQUAL 1)
+ set(RunCMake_TEST_FAILED "Expected stamp '1' but got: '${content}'")
+endif()
+
+file(READ ${output} content)
+if(NOT content STREQUAL 1)
+ set(RunCMake_TEST_FAILED "Expected output '1' but got: '${content}'")
+endif()
diff --git a/Tests/RunCMake/Configure/RerunCMake-build2-check.cmake b/Tests/RunCMake/Configure/RerunCMake-build2-check.cmake
new file mode 100644
index 000000000..a4897e539
--- /dev/null
+++ b/Tests/RunCMake/Configure/RerunCMake-build2-check.cmake
@@ -0,0 +1,9 @@
+file(READ ${stamp} content)
+if(NOT content STREQUAL 2)
+ set(RunCMake_TEST_FAILED "Expected stamp '2' but got: '${content}'")
+endif()
+
+file(READ ${output} content)
+if(NOT content STREQUAL 2)
+ set(RunCMake_TEST_FAILED "Expected output '2' but got: '${content}'")
+endif()
diff --git a/Tests/RunCMake/Configure/RerunCMake.cmake b/Tests/RunCMake/Configure/RerunCMake.cmake
new file mode 100644
index 000000000..5a561bf45
--- /dev/null
+++ b/Tests/RunCMake/Configure/RerunCMake.cmake
@@ -0,0 +1,11 @@
+set(input ${CMAKE_CURRENT_BINARY_DIR}/CustomCMakeInput.txt)
+set(stamp ${CMAKE_CURRENT_BINARY_DIR}/CustomCMakeStamp.txt)
+file(READ ${input} content)
+file(WRITE ${stamp} "${content}")
+
+set(depend ${CMAKE_CURRENT_BINARY_DIR}/CustomCMakeDepend.txt)
+set(output ${CMAKE_CURRENT_BINARY_DIR}/CustomCMakeOutput.txt)
+set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${depend})
+file(READ ${depend} content)
+file(WRITE ${output} "${content}")
+set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS RerunCMake.txt)
diff --git a/Tests/RunCMake/Configure/RerunCMake.txt b/Tests/RunCMake/Configure/RerunCMake.txt
new file mode 100644
index 000000000..15598c112
--- /dev/null
+++ b/Tests/RunCMake/Configure/RerunCMake.txt
@@ -0,0 +1 @@
+Source-tree dependency for "RerunCMake.cmake".
diff --git a/Tests/RunCMake/Configure/RunCMakeTest.cmake b/Tests/RunCMake/Configure/RunCMakeTest.cmake
index 79e4060cc..58e1a2a98 100644
--- a/Tests/RunCMake/Configure/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Configure/RunCMakeTest.cmake
@@ -1,4 +1,25 @@
include(RunCMake)
+run_cmake(CustomTargetAfterError)
run_cmake(ErrorLogs)
run_cmake(FailCopyFileABI)
+
+# Use a single build tree for a few tests without cleaning.
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/RerunCMake-build)
+set(RunCMake_TEST_NO_CLEAN 1)
+file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+set(input "${RunCMake_TEST_BINARY_DIR}/CustomCMakeInput.txt")
+set(stamp "${RunCMake_TEST_BINARY_DIR}/CustomCMakeStamp.txt")
+set(depend "${RunCMake_TEST_BINARY_DIR}/CustomCMakeDepend.txt")
+set(output "${RunCMake_TEST_BINARY_DIR}/CustomCMakeOutput.txt")
+file(WRITE "${input}" "1")
+file(WRITE "${depend}" "1")
+run_cmake(RerunCMake)
+execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1) # handle 1s resolution
+file(WRITE "${input}" "2")
+run_cmake_command(RerunCMake-build1 ${CMAKE_COMMAND} --build .)
+file(WRITE "${depend}" "2")
+run_cmake_command(RerunCMake-build2 ${CMAKE_COMMAND} --build .)
+unset(RunCMake_TEST_BINARY_DIR)
+unset(RunCMake_TEST_NO_CLEAN)
diff --git a/Tests/RunCMake/CrosscompilingEmulator/AddTest-check.cmake b/Tests/RunCMake/CrosscompilingEmulator/AddTest-check.cmake
new file mode 100644
index 000000000..0aae06cc7
--- /dev/null
+++ b/Tests/RunCMake/CrosscompilingEmulator/AddTest-check.cmake
@@ -0,0 +1,12 @@
+set(testfile "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake")
+if(EXISTS "${testfile}")
+ file(READ "${testfile}" testfile_contents)
+else()
+ message(FATAL_ERROR "Could not find expected CTestTestfile.cmake.")
+endif()
+if(testfile_contents MATCHES "add_test[(]DoesNotUseEmulator ^(pseudo_emulator)+$")
+ message(SEND_ERROR "Used emulator when it should not be used.")
+endif()
+if(NOT testfile_contents MATCHES "add_test[(]UsesEmulator .+pseudo_emulator.+$")
+ message(SEND_ERROR "Did not use emulator when it should be used.")
+endif()
diff --git a/Tests/RunCMake/CrosscompilingEmulator/AddTest.cmake b/Tests/RunCMake/CrosscompilingEmulator/AddTest.cmake
new file mode 100644
index 000000000..41850f267
--- /dev/null
+++ b/Tests/RunCMake/CrosscompilingEmulator/AddTest.cmake
@@ -0,0 +1,8 @@
+set(CMAKE_CROSSCOMPILING 1)
+enable_testing()
+add_test(NAME DoesNotUseEmulator
+ COMMAND ${CMAKE_COMMAND} -E echo "Hi")
+
+add_executable(generated_exe simple_src.cxx)
+add_test(NAME UsesEmulator
+ COMMAND generated_exe)
diff --git a/Tests/RunCMake/CrosscompilingEmulator/CMakeLists.txt b/Tests/RunCMake/CrosscompilingEmulator/CMakeLists.txt
new file mode 100644
index 000000000..2d7598574
--- /dev/null
+++ b/Tests/RunCMake/CrosscompilingEmulator/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.1)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CrosscompilingEmulator/CrosscompilingEmulatorProperty.cmake b/Tests/RunCMake/CrosscompilingEmulator/CrosscompilingEmulatorProperty.cmake
new file mode 100644
index 000000000..22d537c38
--- /dev/null
+++ b/Tests/RunCMake/CrosscompilingEmulator/CrosscompilingEmulatorProperty.cmake
@@ -0,0 +1,28 @@
+# This tests setting the CROSSCOMPILING_EMULATOR target property from the
+# CMAKE_CROSSCOMPILING_EMULATOR variable.
+
+# -DCMAKE_CROSSCOMPILING_EMULATOR=/path/to/pseudo_emulator is passed to this
+# test
+add_executable(target_with_emulator simple_src.cxx)
+get_property(emulator TARGET target_with_emulator
+ PROPERTY CROSSCOMPILING_EMULATOR)
+if(NOT "${emulator}" MATCHES "pseudo_emulator")
+ message(SEND_ERROR "Default CROSSCOMPILING_EMULATOR property not set")
+endif()
+
+set_property(TARGET target_with_emulator
+ PROPERTY CROSSCOMPILING_EMULATOR "another_emulator")
+get_property(emulator TARGET target_with_emulator
+ PROPERTY CROSSCOMPILING_EMULATOR)
+if(NOT "${emulator}" MATCHES "another_emulator")
+ message(SEND_ERROR
+ "set_property/get_property CROSSCOMPILING_EMULATOR is not consistent")
+endif()
+
+unset(CMAKE_CROSSCOMPILING_EMULATOR CACHE)
+add_executable(target_without_emulator simple_src.cxx)
+get_property(emulator TARGET target_without_emulator
+ PROPERTY CROSSCOMPILING_EMULATOR)
+if(NOT "${emulator}" STREQUAL "")
+ message(SEND_ERROR "Default CROSSCOMPILING_EMULATOR property not set to null")
+endif()
diff --git a/Tests/RunCMake/CrosscompilingEmulator/InitialCache.txt.in b/Tests/RunCMake/CrosscompilingEmulator/InitialCache.txt.in
new file mode 100644
index 000000000..c95fd8bb1
--- /dev/null
+++ b/Tests/RunCMake/CrosscompilingEmulator/InitialCache.txt.in
@@ -0,0 +1 @@
+CMAKE_EMULATOR:STRING=@PSEUDO_EMULATOR@
diff --git a/Tests/RunCMake/CrosscompilingEmulator/RunCMakeTest.cmake b/Tests/RunCMake/CrosscompilingEmulator/RunCMakeTest.cmake
new file mode 100644
index 000000000..2581cfcc2
--- /dev/null
+++ b/Tests/RunCMake/CrosscompilingEmulator/RunCMakeTest.cmake
@@ -0,0 +1,8 @@
+include(RunCMake)
+
+set(RunCMake_TEST_OPTIONS
+ "-DCMAKE_CROSSCOMPILING_EMULATOR=${PSEUDO_EMULATOR}")
+
+run_cmake(CrosscompilingEmulatorProperty)
+run_cmake(TryRun)
+run_cmake(AddTest)
diff --git a/Tests/RunCMake/CrosscompilingEmulator/TryRun-stdout.txt b/Tests/RunCMake/CrosscompilingEmulator/TryRun-stdout.txt
new file mode 100644
index 000000000..d012974b5
--- /dev/null
+++ b/Tests/RunCMake/CrosscompilingEmulator/TryRun-stdout.txt
@@ -0,0 +1 @@
+run_result: 42
diff --git a/Tests/RunCMake/CrosscompilingEmulator/TryRun.cmake b/Tests/RunCMake/CrosscompilingEmulator/TryRun.cmake
new file mode 100644
index 000000000..4851cc778
--- /dev/null
+++ b/Tests/RunCMake/CrosscompilingEmulator/TryRun.cmake
@@ -0,0 +1,18 @@
+set(CMAKE_CROSSCOMPILING 1)
+
+try_run(run_result compile_result
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/simple_src.cxx
+ RUN_OUTPUT_VARIABLE run_output)
+
+message(STATUS "run_output: ${run_output}")
+message(STATUS "run_result: ${run_result}")
+
+set(CMAKE_CROSSCOMPILING_EMULATOR ${CMAKE_CROSSCOMPILING_EMULATOR}
+ --flag
+ "multi arg")
+try_run(run_result compile_result
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/simple_src.cxx
+ RUN_OUTPUT_VARIABLE run_output)
+message(STATUS "Emulator with arguments run_output: ${run_output}")
diff --git a/Tests/RunCMake/CrosscompilingEmulator/simple_src.cxx b/Tests/RunCMake/CrosscompilingEmulator/simple_src.cxx
new file mode 100644
index 000000000..e5e94f27e
--- /dev/null
+++ b/Tests/RunCMake/CrosscompilingEmulator/simple_src.cxx
@@ -0,0 +1,4 @@
+int main(int, char **)
+{
+ return 13;
+}
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0029-NEW-result.txt b/Tests/RunCMake/DisallowedCommands/CMP0029-NEW-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0029-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0029-NEW-stderr.txt b/Tests/RunCMake/DisallowedCommands/CMP0029-NEW-stderr.txt
new file mode 100644
index 000000000..e14708112
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0029-NEW-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at CMP0029-NEW.cmake:2 \(subdir_depends\):
+ The subdir_depends command should not be called; see CMP0029.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0029-NEW.cmake b/Tests/RunCMake/DisallowedCommands/CMP0029-NEW.cmake
new file mode 100644
index 000000000..392b9d409
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0029-NEW.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0029 NEW)
+subdir_depends()
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0029-OLD.cmake b/Tests/RunCMake/DisallowedCommands/CMP0029-OLD.cmake
new file mode 100644
index 000000000..099fd90d3
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0029-OLD.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0029 OLD)
+subdir_depends()
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0029-WARN-stderr.txt b/Tests/RunCMake/DisallowedCommands/CMP0029-WARN-stderr.txt
new file mode 100644
index 000000000..32a452a74
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0029-WARN-stderr.txt
@@ -0,0 +1,7 @@
+CMake Warning \(dev\) at CMP0029-WARN.cmake:1 \(subdir_depends\):
+ Policy CMP0029 is not set: The subdir_depends command should not be called.
+ Run "cmake --help-policy CMP0029" for policy details. Use the cmake_policy
+ command to set the policy and suppress this warning.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0029-WARN.cmake b/Tests/RunCMake/DisallowedCommands/CMP0029-WARN.cmake
new file mode 100644
index 000000000..1ceb1f85e
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0029-WARN.cmake
@@ -0,0 +1 @@
+subdir_depends()
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0030-NEW-result.txt b/Tests/RunCMake/DisallowedCommands/CMP0030-NEW-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0030-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0030-NEW-stderr.txt b/Tests/RunCMake/DisallowedCommands/CMP0030-NEW-stderr.txt
new file mode 100644
index 000000000..cb380dbc5
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0030-NEW-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at CMP0030-NEW.cmake:2 \(use_mangled_mesa\):
+ The use_mangled_mesa command should not be called; see CMP0030.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0030-NEW.cmake b/Tests/RunCMake/DisallowedCommands/CMP0030-NEW.cmake
new file mode 100644
index 000000000..73365a71b
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0030-NEW.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0030 NEW)
+use_mangled_mesa()
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0030-OLD-result.txt b/Tests/RunCMake/DisallowedCommands/CMP0030-OLD-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0030-OLD-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0030-OLD-stderr.txt b/Tests/RunCMake/DisallowedCommands/CMP0030-OLD-stderr.txt
new file mode 100644
index 000000000..e95e16f86
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0030-OLD-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at CMP0030-OLD.cmake:2 \(use_mangled_mesa\):
+ use_mangled_mesa called with incorrect number of arguments
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0030-OLD.cmake b/Tests/RunCMake/DisallowedCommands/CMP0030-OLD.cmake
new file mode 100644
index 000000000..efbb852dd
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0030-OLD.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0030 OLD)
+use_mangled_mesa()
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0030-WARN-result.txt b/Tests/RunCMake/DisallowedCommands/CMP0030-WARN-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0030-WARN-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0030-WARN-stderr.txt b/Tests/RunCMake/DisallowedCommands/CMP0030-WARN-stderr.txt
new file mode 100644
index 000000000..db3c23f13
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0030-WARN-stderr.txt
@@ -0,0 +1,12 @@
+CMake Warning \(dev\) at CMP0030-WARN.cmake:1 \(use_mangled_mesa\):
+ Policy CMP0030 is not set: The use_mangled_mesa command should not be
+ called. Run "cmake --help-policy CMP0030" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Error at CMP0030-WARN.cmake:1 \(use_mangled_mesa\):
+ use_mangled_mesa called with incorrect number of arguments
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0030-WARN.cmake b/Tests/RunCMake/DisallowedCommands/CMP0030-WARN.cmake
new file mode 100644
index 000000000..cbe0ff0ab
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0030-WARN.cmake
@@ -0,0 +1 @@
+use_mangled_mesa()
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0031-NEW-result.txt b/Tests/RunCMake/DisallowedCommands/CMP0031-NEW-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0031-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0031-NEW-stderr.txt b/Tests/RunCMake/DisallowedCommands/CMP0031-NEW-stderr.txt
new file mode 100644
index 000000000..78c223698
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0031-NEW-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at CMP0031-NEW.cmake:2 \(load_command\):
+ The load_command command should not be called; see CMP0031.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0031-NEW.cmake b/Tests/RunCMake/DisallowedCommands/CMP0031-NEW.cmake
new file mode 100644
index 000000000..3d9caf21a
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0031-NEW.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0031 NEW)
+load_command()
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0031-OLD-result.txt b/Tests/RunCMake/DisallowedCommands/CMP0031-OLD-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0031-OLD-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0031-OLD-stderr.txt b/Tests/RunCMake/DisallowedCommands/CMP0031-OLD-stderr.txt
new file mode 100644
index 000000000..ba198d614
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0031-OLD-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at CMP0031-OLD.cmake:2 \(load_command\):
+ load_command Attempt to load command failed from file.*bogus_command.*
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0031-OLD.cmake b/Tests/RunCMake/DisallowedCommands/CMP0031-OLD.cmake
new file mode 100644
index 000000000..8fedf98c7
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0031-OLD.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0031 OLD)
+load_command(bogus_command)
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0031-WARN-result.txt b/Tests/RunCMake/DisallowedCommands/CMP0031-WARN-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0031-WARN-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0031-WARN-stderr.txt b/Tests/RunCMake/DisallowedCommands/CMP0031-WARN-stderr.txt
new file mode 100644
index 000000000..4cb65b3b3
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0031-WARN-stderr.txt
@@ -0,0 +1,12 @@
+CMake Warning \(dev\) at CMP0031-WARN.cmake:1 \(load_command\):
+ Policy CMP0031 is not set: The load_command command should not be called.
+ Run "cmake --help-policy CMP0031" for policy details. Use the cmake_policy
+ command to set the policy and suppress this warning.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Error at CMP0031-WARN.cmake:1 \(load_command\):
+ load_command Attempt to load command failed from file.*bogus_command.*
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0031-WARN.cmake b/Tests/RunCMake/DisallowedCommands/CMP0031-WARN.cmake
new file mode 100644
index 000000000..c9d99fcbe
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0031-WARN.cmake
@@ -0,0 +1 @@
+load_command(bogus_command)
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0032-NEW-result.txt b/Tests/RunCMake/DisallowedCommands/CMP0032-NEW-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0032-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0032-NEW-stderr.txt b/Tests/RunCMake/DisallowedCommands/CMP0032-NEW-stderr.txt
new file mode 100644
index 000000000..c7ac16eca
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0032-NEW-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at CMP0032-NEW.cmake:2 \(output_required_files\):
+ The output_required_files command should not be called; see CMP0032.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0032-NEW.cmake b/Tests/RunCMake/DisallowedCommands/CMP0032-NEW.cmake
new file mode 100644
index 000000000..c6fb5e8f0
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0032-NEW.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0032 NEW)
+output_required_files()
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0032-OLD-result.txt b/Tests/RunCMake/DisallowedCommands/CMP0032-OLD-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0032-OLD-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0032-OLD-stderr.txt b/Tests/RunCMake/DisallowedCommands/CMP0032-OLD-stderr.txt
new file mode 100644
index 000000000..2223c420c
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0032-OLD-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at CMP0032-OLD.cmake:2 \(output_required_files\):
+ output_required_files called with incorrect number of arguments
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0032-OLD.cmake b/Tests/RunCMake/DisallowedCommands/CMP0032-OLD.cmake
new file mode 100644
index 000000000..6585110ea
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0032-OLD.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0032 OLD)
+output_required_files()
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0032-WARN-result.txt b/Tests/RunCMake/DisallowedCommands/CMP0032-WARN-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0032-WARN-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0032-WARN-stderr.txt b/Tests/RunCMake/DisallowedCommands/CMP0032-WARN-stderr.txt
new file mode 100644
index 000000000..0cf3f94d6
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0032-WARN-stderr.txt
@@ -0,0 +1,12 @@
+CMake Warning \(dev\) at CMP0032-WARN.cmake:1 \(output_required_files\):
+ Policy CMP0032 is not set: The output_required_files command should not be
+ called. Run "cmake --help-policy CMP0032" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Error at CMP0032-WARN.cmake:1 \(output_required_files\):
+ output_required_files called with incorrect number of arguments
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0032-WARN.cmake b/Tests/RunCMake/DisallowedCommands/CMP0032-WARN.cmake
new file mode 100644
index 000000000..7411e48ca
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0032-WARN.cmake
@@ -0,0 +1 @@
+output_required_files()
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0033-NEW-result.txt b/Tests/RunCMake/DisallowedCommands/CMP0033-NEW-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0033-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0033-NEW-stderr.txt b/Tests/RunCMake/DisallowedCommands/CMP0033-NEW-stderr.txt
new file mode 100644
index 000000000..8d210aa68
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0033-NEW-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at CMP0033-NEW.cmake:2 \(export_library_dependencies\):
+ The export_library_dependencies command should not be called; see CMP0033.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0033-NEW.cmake b/Tests/RunCMake/DisallowedCommands/CMP0033-NEW.cmake
new file mode 100644
index 000000000..6f90f29e8
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0033-NEW.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0033 NEW)
+export_library_dependencies()
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0033-OLD-result.txt b/Tests/RunCMake/DisallowedCommands/CMP0033-OLD-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0033-OLD-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0033-OLD-stderr.txt b/Tests/RunCMake/DisallowedCommands/CMP0033-OLD-stderr.txt
new file mode 100644
index 000000000..e5dd2dd79
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0033-OLD-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at CMP0033-OLD.cmake:2 \(export_library_dependencies\):
+ export_library_dependencies called with incorrect number of arguments
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0033-OLD.cmake b/Tests/RunCMake/DisallowedCommands/CMP0033-OLD.cmake
new file mode 100644
index 000000000..a3504b67d
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0033-OLD.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0033 OLD)
+export_library_dependencies()
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0033-WARN-result.txt b/Tests/RunCMake/DisallowedCommands/CMP0033-WARN-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0033-WARN-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0033-WARN-stderr.txt b/Tests/RunCMake/DisallowedCommands/CMP0033-WARN-stderr.txt
new file mode 100644
index 000000000..e561dacaf
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0033-WARN-stderr.txt
@@ -0,0 +1,12 @@
+CMake Warning \(dev\) at CMP0033-WARN.cmake:1 \(export_library_dependencies\):
+ Policy CMP0033 is not set: The export_library_dependencies command should
+ not be called. Run "cmake --help-policy CMP0033" for policy details. Use
+ the cmake_policy command to set the policy and suppress this warning.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Error at CMP0033-WARN.cmake:1 \(export_library_dependencies\):
+ export_library_dependencies called with incorrect number of arguments
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0033-WARN.cmake b/Tests/RunCMake/DisallowedCommands/CMP0033-WARN.cmake
new file mode 100644
index 000000000..f897dddf5
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0033-WARN.cmake
@@ -0,0 +1 @@
+export_library_dependencies()
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0034-NEW-result.txt b/Tests/RunCMake/DisallowedCommands/CMP0034-NEW-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0034-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0034-NEW-stderr.txt b/Tests/RunCMake/DisallowedCommands/CMP0034-NEW-stderr.txt
new file mode 100644
index 000000000..1dd279b8c
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0034-NEW-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at CMP0034-NEW.cmake:2 \(utility_source\):
+ The utility_source command should not be called; see CMP0034.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0034-NEW.cmake b/Tests/RunCMake/DisallowedCommands/CMP0034-NEW.cmake
new file mode 100644
index 000000000..48724a97e
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0034-NEW.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0034 NEW)
+utility_source()
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0034-OLD-result.txt b/Tests/RunCMake/DisallowedCommands/CMP0034-OLD-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0034-OLD-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0034-OLD-stderr.txt b/Tests/RunCMake/DisallowedCommands/CMP0034-OLD-stderr.txt
new file mode 100644
index 000000000..3358628a6
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0034-OLD-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at CMP0034-OLD.cmake:2 \(utility_source\):
+ utility_source called with incorrect number of arguments
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0034-OLD.cmake b/Tests/RunCMake/DisallowedCommands/CMP0034-OLD.cmake
new file mode 100644
index 000000000..a2c9798dc
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0034-OLD.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0034 OLD)
+utility_source()
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0034-WARN-result.txt b/Tests/RunCMake/DisallowedCommands/CMP0034-WARN-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0034-WARN-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0034-WARN-stderr.txt b/Tests/RunCMake/DisallowedCommands/CMP0034-WARN-stderr.txt
new file mode 100644
index 000000000..ea3831f9b
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0034-WARN-stderr.txt
@@ -0,0 +1,12 @@
+CMake Warning \(dev\) at CMP0034-WARN.cmake:1 \(utility_source\):
+ Policy CMP0034 is not set: The utility_source command should not be called.
+ Run "cmake --help-policy CMP0034" for policy details. Use the cmake_policy
+ command to set the policy and suppress this warning.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Error at CMP0034-WARN.cmake:1 \(utility_source\):
+ utility_source called with incorrect number of arguments
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0034-WARN.cmake b/Tests/RunCMake/DisallowedCommands/CMP0034-WARN.cmake
new file mode 100644
index 000000000..b4ae04566
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0034-WARN.cmake
@@ -0,0 +1 @@
+utility_source()
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0035-NEW-result.txt b/Tests/RunCMake/DisallowedCommands/CMP0035-NEW-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0035-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0035-NEW-stderr.txt b/Tests/RunCMake/DisallowedCommands/CMP0035-NEW-stderr.txt
new file mode 100644
index 000000000..0604829ae
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0035-NEW-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at CMP0035-NEW.cmake:2 \(variable_requires\):
+ The variable_requires command should not be called; see CMP0035.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0035-NEW.cmake b/Tests/RunCMake/DisallowedCommands/CMP0035-NEW.cmake
new file mode 100644
index 000000000..27eb32e18
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0035-NEW.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0035 NEW)
+variable_requires()
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0035-OLD-result.txt b/Tests/RunCMake/DisallowedCommands/CMP0035-OLD-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0035-OLD-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0035-OLD-stderr.txt b/Tests/RunCMake/DisallowedCommands/CMP0035-OLD-stderr.txt
new file mode 100644
index 000000000..86eda438c
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0035-OLD-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at CMP0035-OLD.cmake:2 \(variable_requires\):
+ variable_requires called with incorrect number of arguments
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0035-OLD.cmake b/Tests/RunCMake/DisallowedCommands/CMP0035-OLD.cmake
new file mode 100644
index 000000000..74252628b
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0035-OLD.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0035 OLD)
+variable_requires()
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0035-WARN-result.txt b/Tests/RunCMake/DisallowedCommands/CMP0035-WARN-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0035-WARN-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0035-WARN-stderr.txt b/Tests/RunCMake/DisallowedCommands/CMP0035-WARN-stderr.txt
new file mode 100644
index 000000000..4d4fc8e84
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0035-WARN-stderr.txt
@@ -0,0 +1,12 @@
+CMake Warning \(dev\) at CMP0035-WARN.cmake:1 \(variable_requires\):
+ Policy CMP0035 is not set: The variable_requires command should not be
+ called. Run "cmake --help-policy CMP0035" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Error at CMP0035-WARN.cmake:1 \(variable_requires\):
+ variable_requires called with incorrect number of arguments
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0035-WARN.cmake b/Tests/RunCMake/DisallowedCommands/CMP0035-WARN.cmake
new file mode 100644
index 000000000..3af4de177
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0035-WARN.cmake
@@ -0,0 +1 @@
+variable_requires()
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0036-NEW-result.txt b/Tests/RunCMake/DisallowedCommands/CMP0036-NEW-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0036-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0036-NEW-stderr.txt b/Tests/RunCMake/DisallowedCommands/CMP0036-NEW-stderr.txt
new file mode 100644
index 000000000..11aabd098
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0036-NEW-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at CMP0036-NEW.cmake:2 \(build_name\):
+ The build_name command should not be called; see CMP0036.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0036-NEW.cmake b/Tests/RunCMake/DisallowedCommands/CMP0036-NEW.cmake
new file mode 100644
index 000000000..5341db2a0
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0036-NEW.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0036 NEW)
+build_name()
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0036-OLD-result.txt b/Tests/RunCMake/DisallowedCommands/CMP0036-OLD-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0036-OLD-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0036-OLD-stderr.txt b/Tests/RunCMake/DisallowedCommands/CMP0036-OLD-stderr.txt
new file mode 100644
index 000000000..fef195f40
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0036-OLD-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at CMP0036-OLD.cmake:2 \(build_name\):
+ build_name called with incorrect number of arguments
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0036-OLD.cmake b/Tests/RunCMake/DisallowedCommands/CMP0036-OLD.cmake
new file mode 100644
index 000000000..fdd840f94
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0036-OLD.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0036 OLD)
+build_name()
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0036-WARN-result.txt b/Tests/RunCMake/DisallowedCommands/CMP0036-WARN-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0036-WARN-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0036-WARN-stderr.txt b/Tests/RunCMake/DisallowedCommands/CMP0036-WARN-stderr.txt
new file mode 100644
index 000000000..b9b7c5a9c
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0036-WARN-stderr.txt
@@ -0,0 +1,12 @@
+CMake Warning \(dev\) at CMP0036-WARN.cmake:1 \(build_name\):
+ Policy CMP0036 is not set: The build_name command should not be called.
+ Run "cmake --help-policy CMP0036" for policy details. Use the cmake_policy
+ command to set the policy and suppress this warning.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Error at CMP0036-WARN.cmake:1 \(build_name\):
+ build_name called with incorrect number of arguments
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/DisallowedCommands/CMP0036-WARN.cmake b/Tests/RunCMake/DisallowedCommands/CMP0036-WARN.cmake
new file mode 100644
index 000000000..9556687ab
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMP0036-WARN.cmake
@@ -0,0 +1 @@
+build_name()
diff --git a/Tests/RunCMake/DisallowedCommands/CMakeLists.txt b/Tests/RunCMake/DisallowedCommands/CMakeLists.txt
new file mode 100644
index 000000000..12cd3c775
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/DisallowedCommands/RunCMakeTest.cmake b/Tests/RunCMake/DisallowedCommands/RunCMakeTest.cmake
new file mode 100644
index 000000000..208ea2085
--- /dev/null
+++ b/Tests/RunCMake/DisallowedCommands/RunCMakeTest.cmake
@@ -0,0 +1,16 @@
+include(RunCMake)
+
+foreach(p
+ CMP0029
+ CMP0030
+ CMP0031
+ CMP0032
+ CMP0033
+ CMP0034
+ CMP0035
+ CMP0036
+ )
+ run_cmake(${p}-WARN)
+ run_cmake(${p}-OLD)
+ run_cmake(${p}-NEW)
+endforeach()
diff --git a/Tests/RunCMake/ExportWithoutLanguage/NoLanguage-stderr.txt b/Tests/RunCMake/ExportWithoutLanguage/NoLanguage-stderr.txt
index 67a0ae37c..5658d85d4 100644
--- a/Tests/RunCMake/ExportWithoutLanguage/NoLanguage-stderr.txt
+++ b/Tests/RunCMake/ExportWithoutLanguage/NoLanguage-stderr.txt
@@ -1,6 +1,4 @@
CMake Error: CMake can not determine linker language for target: NoLanguage
-CMake Error at NoLanguage.cmake:2 \(export\):
+CMake Error in CMakeLists.txt:
Exporting the target "NoLanguage" is not allowed since its linker language
cannot be determined
-Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ExportWithoutLanguage/header.h b/Tests/RunCMake/ExportWithoutLanguage/header.h
new file mode 100644
index 000000000..0c803ed03
--- /dev/null
+++ b/Tests/RunCMake/ExportWithoutLanguage/header.h
@@ -0,0 +1,2 @@
+
+enum some_compilers { need_more_than_nothing };
diff --git a/Tests/RunCMake/ExternalData/BadAlgoMap1-result.txt b/Tests/RunCMake/ExternalData/BadAlgoMap1-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadAlgoMap1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalData/BadAlgoMap1-stderr.txt b/Tests/RunCMake/ExternalData/BadAlgoMap1-stderr.txt
new file mode 100644
index 000000000..c3708a9c8
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadAlgoMap1-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+ Bad %\(algo:\) in URL template:
+
+ file:///path/to/%\(algo:\)/%\(hash\)
+
+ The transform name must be a valid C identifier.
+Call Stack \(most recent call first\):
+ BadAlgoMap1.cmake:[0-9]+ \(ExternalData_Add_Target\)
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ExternalData/BadAlgoMap1.cmake b/Tests/RunCMake/ExternalData/BadAlgoMap1.cmake
new file mode 100644
index 000000000..542ec1dab
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadAlgoMap1.cmake
@@ -0,0 +1,5 @@
+include(ExternalData)
+set(ExternalData_URL_TEMPLATES
+ "file:///path/to/%(algo:)/%(hash)"
+ )
+ExternalData_Add_Target(Data)
diff --git a/Tests/RunCMake/ExternalData/BadAlgoMap2-result.txt b/Tests/RunCMake/ExternalData/BadAlgoMap2-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadAlgoMap2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalData/BadAlgoMap2-stderr.txt b/Tests/RunCMake/ExternalData/BadAlgoMap2-stderr.txt
new file mode 100644
index 000000000..1f10644dc
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadAlgoMap2-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+ Bad %\(algo:0BadMap\(\) in URL template:
+
+ file:///path/to/%\(algo:0BadMap\(\)/%\(hash\)
+
+ The transform name must be a valid C identifier.
+Call Stack \(most recent call first\):
+ BadAlgoMap2.cmake:[0-9]+ \(ExternalData_Add_Target\)
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ExternalData/BadAlgoMap2.cmake b/Tests/RunCMake/ExternalData/BadAlgoMap2.cmake
new file mode 100644
index 000000000..0537a7b93
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadAlgoMap2.cmake
@@ -0,0 +1,5 @@
+include(ExternalData)
+set(ExternalData_URL_TEMPLATES
+ "file:///path/to/%(algo:0BadMap()/%(hash)"
+ )
+ExternalData_Add_Target(Data)
diff --git a/Tests/RunCMake/ExternalData/BadCustom1-result.txt b/Tests/RunCMake/ExternalData/BadCustom1-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadCustom1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalData/BadCustom1-stderr.txt b/Tests/RunCMake/ExternalData/BadCustom1-stderr.txt
new file mode 100644
index 000000000..5d2986da5
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadCustom1-stderr.txt
@@ -0,0 +1,9 @@
+^CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+ Bad ExternalDataCustomScript key '0BadKey' in URL template:
+
+ ExternalDataCustomScript://0BadKey/%\(algo\)/%\(hash\)
+
+ The key must be a valid C identifier.
+Call Stack \(most recent call first\):
+ BadCustom1.cmake:[0-9]+ \(ExternalData_Add_Target\)
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/ExternalData/BadCustom1.cmake b/Tests/RunCMake/ExternalData/BadCustom1.cmake
new file mode 100644
index 000000000..ec94fc157
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadCustom1.cmake
@@ -0,0 +1,5 @@
+include(ExternalData)
+set(ExternalData_URL_TEMPLATES
+ "ExternalDataCustomScript://0BadKey/%(algo)/%(hash)"
+ )
+ExternalData_Add_Target(Data)
diff --git a/Tests/RunCMake/ExternalData/BadCustom2-result.txt b/Tests/RunCMake/ExternalData/BadCustom2-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadCustom2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalData/BadCustom2-stderr.txt b/Tests/RunCMake/ExternalData/BadCustom2-stderr.txt
new file mode 100644
index 000000000..4d59ca9fa
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadCustom2-stderr.txt
@@ -0,0 +1,9 @@
+^CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+ Bad ExternalDataCustomScript key '' in URL template:
+
+ ExternalDataCustomScript:///%\(algo\)/%\(hash\)
+
+ The key must be a valid C identifier.
+Call Stack \(most recent call first\):
+ BadCustom2.cmake:[0-9]+ \(ExternalData_Add_Target\)
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/ExternalData/BadCustom2.cmake b/Tests/RunCMake/ExternalData/BadCustom2.cmake
new file mode 100644
index 000000000..1ed764610
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadCustom2.cmake
@@ -0,0 +1,5 @@
+include(ExternalData)
+set(ExternalData_URL_TEMPLATES
+ "ExternalDataCustomScript:///%(algo)/%(hash)"
+ )
+ExternalData_Add_Target(Data)
diff --git a/Tests/RunCMake/ExternalData/BadCustom3-result.txt b/Tests/RunCMake/ExternalData/BadCustom3-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadCustom3-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalData/BadCustom3-stderr.txt b/Tests/RunCMake/ExternalData/BadCustom3-stderr.txt
new file mode 100644
index 000000000..460814b9c
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadCustom3-stderr.txt
@@ -0,0 +1,7 @@
+^CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+ No ExternalData_CUSTOM_SCRIPT_MissingKey is set for URL template:
+
+ ExternalDataCustomScript://MissingKey/%\(algo\)/%\(hash\)
+Call Stack \(most recent call first\):
+ BadCustom3.cmake:[0-9]+ \(ExternalData_Add_Target\)
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/ExternalData/BadCustom3.cmake b/Tests/RunCMake/ExternalData/BadCustom3.cmake
new file mode 100644
index 000000000..b4f2fb8ba
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadCustom3.cmake
@@ -0,0 +1,5 @@
+include(ExternalData)
+set(ExternalData_URL_TEMPLATES
+ "ExternalDataCustomScript://MissingKey/%(algo)/%(hash)"
+ )
+ExternalData_Add_Target(Data)
diff --git a/Tests/RunCMake/ExternalData/BadCustom4-result.txt b/Tests/RunCMake/ExternalData/BadCustom4-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadCustom4-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalData/BadCustom4-stderr.txt b/Tests/RunCMake/ExternalData/BadCustom4-stderr.txt
new file mode 100644
index 000000000..b83bceefa
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadCustom4-stderr.txt
@@ -0,0 +1,7 @@
+^CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+ No ExternalData_CUSTOM_SCRIPT_RelPathKey is not set to a full path:
+
+ RelPathScript.cmake
+Call Stack \(most recent call first\):
+ BadCustom4.cmake:[0-9]+ \(ExternalData_Add_Target\)
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/ExternalData/BadCustom4.cmake b/Tests/RunCMake/ExternalData/BadCustom4.cmake
new file mode 100644
index 000000000..0cc552172
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadCustom4.cmake
@@ -0,0 +1,6 @@
+include(ExternalData)
+set(ExternalData_URL_TEMPLATES
+ "ExternalDataCustomScript://RelPathKey/%(algo)/%(hash)"
+ )
+set(ExternalData_CUSTOM_SCRIPT_RelPathKey "RelPathScript.cmake")
+ExternalData_Add_Target(Data)
diff --git a/Tests/RunCMake/ExternalData/BadRecurse1-result.txt b/Tests/RunCMake/ExternalData/BadRecurse1-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadRecurse1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalData/BadRecurse1-stderr.txt b/Tests/RunCMake/ExternalData/BadRecurse1-stderr.txt
new file mode 100644
index 000000000..aedc33015
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadRecurse1-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+ Recurse option "RECURSE:" allowed only with directories.
+Call Stack \(most recent call first\):
+ .*
+ BadRecurse1.cmake:2 \(ExternalData_Expand_Arguments\)
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ExternalData/BadRecurse1.cmake b/Tests/RunCMake/ExternalData/BadRecurse1.cmake
new file mode 100644
index 000000000..f70b9f9d5
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadRecurse1.cmake
@@ -0,0 +1,2 @@
+include(ExternalData)
+ExternalData_Expand_Arguments(Data args DATA{Series.txt,:,RECURSE:})
diff --git a/Tests/RunCMake/ExternalData/BadRecurse2-result.txt b/Tests/RunCMake/ExternalData/BadRecurse2-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadRecurse2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalData/BadRecurse2-stderr.txt b/Tests/RunCMake/ExternalData/BadRecurse2-stderr.txt
new file mode 100644
index 000000000..3f809ca69
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadRecurse2-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+ Recurse option "RECURSE:" allowed only with directories.
+Call Stack \(most recent call first\):
+ .*
+ BadRecurse2.cmake:2 \(ExternalData_Expand_Arguments\)
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ExternalData/BadRecurse2.cmake b/Tests/RunCMake/ExternalData/BadRecurse2.cmake
new file mode 100644
index 000000000..c4dc35d54
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadRecurse2.cmake
@@ -0,0 +1,2 @@
+include(ExternalData)
+ExternalData_Expand_Arguments(Data args DATA{Data.txt,RECURSE:})
diff --git a/Tests/RunCMake/ExternalData/BadRecurse3-result.txt b/Tests/RunCMake/ExternalData/BadRecurse3-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadRecurse3-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalData/BadRecurse3-stderr.txt b/Tests/RunCMake/ExternalData/BadRecurse3-stderr.txt
new file mode 100644
index 000000000..37740e0f7
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadRecurse3-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+ Unknown option "RECURSE:x" in argument
+
+ DATA{Directory1/,RECURSE:x,Data.dat}
+
+Call Stack \(most recent call first\):
+ .*
+ BadRecurse3.cmake:2 \(ExternalData_Expand_Arguments\)
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ExternalData/BadRecurse3.cmake b/Tests/RunCMake/ExternalData/BadRecurse3.cmake
new file mode 100644
index 000000000..9a22f6218
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadRecurse3.cmake
@@ -0,0 +1,2 @@
+include(ExternalData)
+ExternalData_Expand_Arguments(Data args DATA{Directory1/,RECURSE:x,Data.dat})
diff --git a/Tests/RunCMake/ExternalData/Directory1-stderr.txt b/Tests/RunCMake/ExternalData/Directory1-stderr.txt
index 85c250f02..2bc3c601d 100644
--- a/Tests/RunCMake/ExternalData/Directory1-stderr.txt
+++ b/Tests/RunCMake/ExternalData/Directory1-stderr.txt
@@ -7,7 +7,7 @@ CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
Directory1
- that does not exist as a file \(with or without an extension\)!
+ that is directory instead of a file!
Call Stack \(most recent call first\):
.*
Directory1.cmake:3 \(ExternalData_Add_Test\)
diff --git a/Tests/RunCMake/ExternalData/Directory3-stderr.txt b/Tests/RunCMake/ExternalData/Directory3-stderr.txt
index 56a341e03..ceed2a04d 100644
--- a/Tests/RunCMake/ExternalData/Directory3-stderr.txt
+++ b/Tests/RunCMake/ExternalData/Directory3-stderr.txt
@@ -1,4 +1,4 @@
-CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+CMake Warning \(dev\) at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
Data file referenced by argument
DATA{Directory3/\*}
@@ -12,3 +12,4 @@ Call Stack \(most recent call first\):
.*
Directory3.cmake:3 \(ExternalData_Add_Test\)
CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/ExternalData/MissingData-stderr.txt b/Tests/RunCMake/ExternalData/MissingData-stderr.txt
index e794f955d..39ed2f15f 100644
--- a/Tests/RunCMake/ExternalData/MissingData-stderr.txt
+++ b/Tests/RunCMake/ExternalData/MissingData-stderr.txt
@@ -1,4 +1,4 @@
-CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+CMake Warning \(dev\) at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
Data file referenced by argument
DATA{MissingData.txt}
@@ -10,5 +10,6 @@ CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
that does not exist as a file \(with or without an extension\)!
Call Stack \(most recent call first\):
.*
- MissingData.cmake:2 \(ExternalData_Add_Test\)
+ MissingData.cmake:4 \(ExternalData_Expand_Arguments\)
CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/ExternalData/MissingData-stdout.txt b/Tests/RunCMake/ExternalData/MissingData-stdout.txt
new file mode 100644
index 000000000..addd40eaa
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/MissingData-stdout.txt
@@ -0,0 +1 @@
+-- Missing data reference correctly transformed!
diff --git a/Tests/RunCMake/ExternalData/MissingData.cmake b/Tests/RunCMake/ExternalData/MissingData.cmake
index b3c8a5cdc..f5fefd5cc 100644
--- a/Tests/RunCMake/ExternalData/MissingData.cmake
+++ b/Tests/RunCMake/ExternalData/MissingData.cmake
@@ -1,5 +1,10 @@
include(ExternalData)
-ExternalData_Add_Test(Data
- NAME Test
- COMMAND ${CMAKE_COMMAND} -E echo DATA{MissingData.txt}
- )
+
+set(output "${CMAKE_SOURCE_DIR}/MissingData.txt")
+ExternalData_Expand_Arguments(Data args DATA{MissingData.txt})
+if("x${args}" STREQUAL "x${output}")
+ message(STATUS "Missing data reference correctly transformed!")
+else()
+ message(FATAL_ERROR "Missing data reference transformed to:\n ${args}\n"
+ "but we expected:\n ${output}")
+endif()
diff --git a/Tests/RunCMake/ExternalData/MissingDataWithAssociated-stderr.txt b/Tests/RunCMake/ExternalData/MissingDataWithAssociated-stderr.txt
new file mode 100644
index 000000000..315af5e49
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/MissingDataWithAssociated-stderr.txt
@@ -0,0 +1,15 @@
+CMake Warning \(dev\) at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+ Data file referenced by argument
+
+ DATA{MissingData.txt,Data.txt}
+
+ corresponds to source tree path
+
+ MissingData.txt
+
+ that does not exist as a file \(with or without an extension\)!
+Call Stack \(most recent call first\):
+ .*
+ MissingDataWithAssociated.cmake:4 \(ExternalData_Expand_Arguments\)
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/ExternalData/MissingDataWithAssociated-stdout.txt b/Tests/RunCMake/ExternalData/MissingDataWithAssociated-stdout.txt
new file mode 100644
index 000000000..addd40eaa
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/MissingDataWithAssociated-stdout.txt
@@ -0,0 +1 @@
+-- Missing data reference correctly transformed!
diff --git a/Tests/RunCMake/ExternalData/MissingDataWithAssociated.cmake b/Tests/RunCMake/ExternalData/MissingDataWithAssociated.cmake
new file mode 100644
index 000000000..a4c4638b0
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/MissingDataWithAssociated.cmake
@@ -0,0 +1,10 @@
+include(ExternalData)
+
+set(output "${CMAKE_BINARY_DIR}/MissingData.txt")
+ExternalData_Expand_Arguments(Data args DATA{MissingData.txt,Data.txt})
+if("x${args}" STREQUAL "x${output}")
+ message(STATUS "Missing data reference correctly transformed!")
+else()
+ message(FATAL_ERROR "Missing data reference transformed to:\n ${args}\n"
+ "but we expected:\n ${output}")
+endif()
diff --git a/Tests/RunCMake/ExternalData/NoURLTemplates-stderr.txt b/Tests/RunCMake/ExternalData/NoURLTemplates-stderr.txt
index ad059d434..ccbaf5af3 100644
--- a/Tests/RunCMake/ExternalData/NoURLTemplates-stderr.txt
+++ b/Tests/RunCMake/ExternalData/NoURLTemplates-stderr.txt
@@ -1,5 +1,5 @@
CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
- ExternalData_URL_TEMPLATES is not set!
+ Neither ExternalData_URL_TEMPLATES nor ExternalData_OBJECT_STORES is set!
Call Stack \(most recent call first\):
NoURLTemplates.cmake:2 \(ExternalData_Add_Target\)
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ExternalData/ObjectStoreOnly.cmake b/Tests/RunCMake/ExternalData/ObjectStoreOnly.cmake
new file mode 100644
index 000000000..5e6610144
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/ObjectStoreOnly.cmake
@@ -0,0 +1,3 @@
+include(ExternalData)
+set(ExternalData_OBJECT_STORES "${CMAKE_CURRENT_BINARY_DIR}")
+ExternalData_Add_Target(Data)
diff --git a/Tests/RunCMake/ExternalData/RunCMakeTest.cmake b/Tests/RunCMake/ExternalData/RunCMakeTest.cmake
index 8fba82c39..b5ab22d1a 100644
--- a/Tests/RunCMake/ExternalData/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ExternalData/RunCMakeTest.cmake
@@ -1,8 +1,17 @@
include(RunCMake)
+run_cmake(BadAlgoMap1)
+run_cmake(BadAlgoMap2)
+run_cmake(BadCustom1)
+run_cmake(BadCustom2)
+run_cmake(BadCustom3)
+run_cmake(BadCustom4)
run_cmake(BadHashAlgo1)
run_cmake(BadOption1)
run_cmake(BadOption2)
+run_cmake(BadRecurse1)
+run_cmake(BadRecurse2)
+run_cmake(BadRecurse3)
run_cmake(BadSeries1)
run_cmake(BadSeries2)
run_cmake(BadSeries3)
@@ -15,6 +24,7 @@ run_cmake(LinkContentMD5)
run_cmake(LinkContentSHA1)
run_cmake(LinkDirectory1)
run_cmake(MissingData)
+run_cmake(MissingDataWithAssociated)
run_cmake(NoLinkInSource)
run_cmake(NoURLTemplates)
run_cmake(NormalData1)
@@ -22,6 +32,7 @@ run_cmake(NormalData2)
run_cmake(NormalData3)
run_cmake(NormalDataSub1)
run_cmake(NotUnderRoot)
+run_cmake(ObjectStoreOnly)
run_cmake(Semicolon1)
run_cmake(Semicolon2)
run_cmake(Semicolon3)
diff --git a/Tests/RunCMake/ExternalProject/Add_StepDependencies.cmake b/Tests/RunCMake/ExternalProject/Add_StepDependencies.cmake
new file mode 100644
index 000000000..38683f12e
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/Add_StepDependencies.cmake
@@ -0,0 +1,20 @@
+cmake_minimum_required(VERSION ${CMAKE_VERSION})
+
+include(ExternalProject)
+
+ExternalProject_Add(BAR URL https://cmake.org/bar.tar.gz)
+
+ExternalProject_Add(FOO URL https://cmake.org/foo.tar.gz STEP_TARGETS update)
+ExternalProject_Add_Step(FOO do_something COMMAND ${CMAKE_COMMAND} -E echo "Doing something")
+ExternalProject_Add_Step(FOO do_something_else COMMAND ${CMAKE_COMMAND} -E echo "Doing something else")
+ExternalProject_Add_StepTargets(FOO do_something)
+
+# download and do_something_else are not targets, but the file-level
+# dependency are set.
+ExternalProject_Add_StepDependencies(FOO download BAR)
+ExternalProject_Add_StepDependencies(FOO do_something_else BAR)
+
+# update and do_something are targets, therefore both file-level and
+# target-level dependencies are set.
+ExternalProject_Add_StepDependencies(FOO update BAR)
+ExternalProject_Add_StepDependencies(FOO do_something BAR)
diff --git a/Tests/RunCMake/ExternalProject/Add_StepDependencies_iface-result.txt b/Tests/RunCMake/ExternalProject/Add_StepDependencies_iface-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/Add_StepDependencies_iface-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalProject/Add_StepDependencies_iface-stderr.txt b/Tests/RunCMake/ExternalProject/Add_StepDependencies_iface-stderr.txt
new file mode 100644
index 000000000..1c0b6017b
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/Add_StepDependencies_iface-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at .*/Modules/ExternalProject.cmake:[0-9]+ \(message\):
+ Target "SomeInterface" was not generated by ExternalProject_Add.
+Call Stack \(most recent call first\):
+ Add_StepDependencies_iface.cmake:[0-9]+ \(ExternalProject_Add_StepDependencies\)
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/ExternalProject/Add_StepDependencies_iface.cmake b/Tests/RunCMake/ExternalProject/Add_StepDependencies_iface.cmake
new file mode 100644
index 000000000..f7cfde1c2
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/Add_StepDependencies_iface.cmake
@@ -0,0 +1,4 @@
+include(ExternalProject)
+
+add_library(SomeInterface INTERFACE)
+ExternalProject_Add_StepDependencies(SomeInterface step dep)
diff --git a/Tests/RunCMake/ExternalProject/Add_StepDependencies_iface_step-result.txt b/Tests/RunCMake/ExternalProject/Add_StepDependencies_iface_step-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/Add_StepDependencies_iface_step-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalProject/Add_StepDependencies_iface_step-stderr.txt b/Tests/RunCMake/ExternalProject/Add_StepDependencies_iface_step-stderr.txt
new file mode 100644
index 000000000..22e13bf9a
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/Add_StepDependencies_iface_step-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at .*/Modules/ExternalProject.cmake:[0-9]+ \(message\):
+ Target "MyProj-IFace" was not generated by ExternalProject_Add_StepTargets.
+Call Stack \(most recent call first\):
+ Add_StepDependencies_iface_step.cmake:[0-9]+ \(ExternalProject_Add_StepDependencies\)
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/ExternalProject/Add_StepDependencies_iface_step.cmake b/Tests/RunCMake/ExternalProject/Add_StepDependencies_iface_step.cmake
new file mode 100644
index 000000000..02894939b
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/Add_StepDependencies_iface_step.cmake
@@ -0,0 +1,11 @@
+include(ExternalProject)
+
+ExternalProject_Add(MyProj
+ DOWNLOAD_COMMAND ""
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ )
+
+add_library(MyProj-IFace INTERFACE)
+ExternalProject_Add_StepDependencies(MyProj IFace dep)
diff --git a/Tests/RunCMake/ExternalProject/Add_StepDependencies_no_target.cmake b/Tests/RunCMake/ExternalProject/Add_StepDependencies_no_target.cmake
new file mode 100644
index 000000000..264c3f04c
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/Add_StepDependencies_no_target.cmake
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION ${CMAKE_VERSION})
+
+include(ExternalProject)
+
+ExternalProject_Add(BAR URL https://cmake.org/bar.tar.gz)
+
+ExternalProject_Add(FOO URL https://cmake.org/foo.tar.gz STEP_TARGETS update)
+ExternalProject_Add_Step(FOO do_something COMMAND ${CMAKE_COMMAND} -E echo "Doing something")
+ExternalProject_Add_Step(FOO do_something_else COMMAND ${CMAKE_COMMAND} -E echo "Doing something else")
+ExternalProject_Add_StepTargets(FOO do_something)
diff --git a/Tests/RunCMake/ExternalProject/CMAKE_CACHE_ARGS-check.cmake b/Tests/RunCMake/ExternalProject/CMAKE_CACHE_ARGS-check.cmake
new file mode 100644
index 000000000..c350a63fc
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/CMAKE_CACHE_ARGS-check.cmake
@@ -0,0 +1,17 @@
+set(_cache_file "${RunCMake_TEST_BINARY_DIR}/tmp/FOO-cache-Debug.cmake")
+
+if(NOT EXISTS "${_cache_file}")
+ set(RunCMake_TEST_FAILED "Initial cache not created")
+ return()
+endif()
+
+file(READ "${_cache_file}" _cache)
+
+if(NOT "${_cache}" MATCHES "set\\(FOO \"BAR\".+\\)") # \(\)
+ set(RunCMake_TEST_FAILED "Cannot find FOO argument in cache")
+ return()
+endif()
+if(NOT "${CMAKE_MATCH_0}" MATCHES FORCE)
+ set(RunCMake_TEST_FAILED "Expected forced FOO argument")
+ return()
+endif()
diff --git a/Tests/RunCMake/ExternalProject/CMAKE_CACHE_ARGS.cmake b/Tests/RunCMake/ExternalProject/CMAKE_CACHE_ARGS.cmake
new file mode 100644
index 000000000..62b164040
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/CMAKE_CACHE_ARGS.cmake
@@ -0,0 +1,8 @@
+if(NOT CMAKE_CONFIGURATION_TYPES)
+ set(CMAKE_BUILD_TYPE Debug)
+endif()
+include(ExternalProject)
+
+ExternalProject_Add(FOO TMP_DIR "${CMAKE_CURRENT_BINARY_DIR}/tmp"
+ DOWNLOAD_COMMAND ""
+ CMAKE_CACHE_ARGS "-DFOO:STRING=$<1:BAR>$<0:BAD>")
diff --git a/Tests/RunCMake/ExternalProject/CMAKE_CACHE_DEFAULT_ARGS-check.cmake b/Tests/RunCMake/ExternalProject/CMAKE_CACHE_DEFAULT_ARGS-check.cmake
new file mode 100644
index 000000000..aeee11fa0
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/CMAKE_CACHE_DEFAULT_ARGS-check.cmake
@@ -0,0 +1,17 @@
+set(_cache_file "${RunCMake_TEST_BINARY_DIR}/tmp/FOO-cache-Debug.cmake")
+
+if(NOT EXISTS "${_cache_file}")
+ set(RunCMake_TEST_FAILED "Initial cache not created")
+ return()
+endif()
+
+file(READ "${_cache_file}" _cache)
+
+if(NOT "${_cache}" MATCHES "set\\(FOO \"BAR\".+\\)") # \(\)
+ set(RunCMake_TEST_FAILED "Cannot find FOO argument in cache")
+ return()
+endif()
+if("${CMAKE_MATCH_0}" MATCHES FORCE)
+ set(RunCMake_TEST_FAILED "Expected not forced FOO argument")
+ return()
+endif()
diff --git a/Tests/RunCMake/ExternalProject/CMAKE_CACHE_DEFAULT_ARGS.cmake b/Tests/RunCMake/ExternalProject/CMAKE_CACHE_DEFAULT_ARGS.cmake
new file mode 100644
index 000000000..3a83dbe38
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/CMAKE_CACHE_DEFAULT_ARGS.cmake
@@ -0,0 +1,8 @@
+if(NOT CMAKE_CONFIGURATION_TYPES)
+ set(CMAKE_BUILD_TYPE Debug)
+endif()
+include(ExternalProject)
+
+ExternalProject_Add(FOO TMP_DIR "${CMAKE_CURRENT_BINARY_DIR}/tmp"
+ DOWNLOAD_COMMAND ""
+ CMAKE_CACHE_DEFAULT_ARGS "-DFOO:STRING=$<1:BAR>$<0:BAD>")
diff --git a/Tests/RunCMake/ExternalProject/CMAKE_CACHE_mix-check.cmake b/Tests/RunCMake/ExternalProject/CMAKE_CACHE_mix-check.cmake
new file mode 100644
index 000000000..04d49b9e4
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/CMAKE_CACHE_mix-check.cmake
@@ -0,0 +1,26 @@
+set(_cache_file "${RunCMake_TEST_BINARY_DIR}/tmp/FOO-cache-Debug.cmake")
+
+if(NOT EXISTS "${_cache_file}")
+ set(RunCMake_TEST_FAILED "Initial cache not created")
+ return()
+endif()
+
+file(READ "${_cache_file}" _cache)
+
+if(NOT "${_cache}" MATCHES "set\\(FOO \"BAR\".+\\)") # \(\)
+ set(RunCMake_TEST_FAILED "Cannot find FOO argument in cache")
+ return()
+endif()
+if(NOT "${CMAKE_MATCH_0}" MATCHES FORCE)
+ set(RunCMake_TEST_FAILED "Expected forced FOO argument")
+ return()
+endif()
+
+if(NOT "${_cache}" MATCHES "set\\(BAR \"BAZ\".+\\)") # \(\)
+ set(RunCMake_TEST_FAILED "Cannot find BAR argument in cache")
+ return()
+endif()
+if("${CMAKE_MATCH_0}" MATCHES FORCE)
+ set(RunCMake_TEST_FAILED "Expected not forced BAR argument")
+ return()
+endif()
diff --git a/Tests/RunCMake/ExternalProject/CMAKE_CACHE_mix.cmake b/Tests/RunCMake/ExternalProject/CMAKE_CACHE_mix.cmake
new file mode 100644
index 000000000..192776ba7
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/CMAKE_CACHE_mix.cmake
@@ -0,0 +1,9 @@
+if(NOT CMAKE_CONFIGURATION_TYPES)
+ set(CMAKE_BUILD_TYPE Debug)
+endif()
+include(ExternalProject)
+
+ExternalProject_Add(FOO TMP_DIR "${CMAKE_CURRENT_BINARY_DIR}/tmp"
+ DOWNLOAD_COMMAND ""
+ CMAKE_CACHE_ARGS "-DFOO:STRING=$<1:BAR>$<0:BAD>"
+ CMAKE_CACHE_DEFAULT_ARGS "-DBAR:STRING=$<1:BAZ>$<0:BAD>")
diff --git a/Tests/RunCMake/ExternalProject/CMakeLists.txt b/Tests/RunCMake/ExternalProject/CMakeLists.txt
new file mode 100644
index 000000000..c585733b6
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION ${CMAKE_VERSION})
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/ExternalProject/NO_DEPENDS-stderr.txt b/Tests/RunCMake/ExternalProject/NO_DEPENDS-stderr.txt
new file mode 100644
index 000000000..4cb051dbb
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/NO_DEPENDS-stderr.txt
@@ -0,0 +1,36 @@
+CMake Warning \(dev\) at .*/Modules/ExternalProject.cmake:[0-9]+. \(message\):
+ Using NO_DEPENDS for "configure" step might break parallel builds
+Call Stack \(most recent call first\):
+ .*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_StepTargets\)
+ .*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_Step\)
+ .*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_configure_command\)
+ NO_DEPENDS.cmake:[0-9]+ \(ExternalProject_Add\)
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at .*/Modules/ExternalProject.cmake:[0-9]+. \(message\):
+ Using NO_DEPENDS for "build" step might break parallel builds
+Call Stack \(most recent call first\):
+ .*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_StepTargets\)
+ .*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_Step\)
+ .*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_build_command\)
+ NO_DEPENDS.cmake:[0-9]+ \(ExternalProject_Add\)
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at .*/Modules/ExternalProject.cmake:[0-9]+. \(message\):
+ Using NO_DEPENDS for "install" step might break parallel builds
+Call Stack \(most recent call first\):
+ .*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_StepTargets\)
+ .*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_Step\)
+ .*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_install_command\)
+ NO_DEPENDS.cmake:[0-9]+ \(ExternalProject_Add\)
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at .*/Modules/ExternalProject.cmake:[0-9]+. \(message\):
+ Using NO_DEPENDS for "test" step might break parallel builds
+Call Stack \(most recent call first\):
+ NO_DEPENDS.cmake:[0-9]+ \(ExternalProject_Add_StepTargets\)
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/ExternalProject/NO_DEPENDS.cmake b/Tests/RunCMake/ExternalProject/NO_DEPENDS.cmake
new file mode 100644
index 000000000..57626d679
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/NO_DEPENDS.cmake
@@ -0,0 +1,18 @@
+cmake_minimum_required(VERSION 2.8.12)
+
+include(ExternalProject RESULT_VARIABLE GOO)
+
+set_property(DIRECTORY PROPERTY EP_INDEPENDENT_STEP_TARGETS download patch update configure build)
+
+ExternalProject_Add(FOO
+ URL https://example.org/foo.tar.gz)
+
+ExternalProject_Add(BAR
+ URL https://example.org/bar.tar.gz
+ TEST_COMMAND echo test
+ INDEPENDENT_STEP_TARGETS install)
+# This one should not give a warning
+ExternalProject_Add_Step(BAR bar
+ COMMAND echo bar)
+
+ExternalProject_Add_StepTargets(BAR NO_DEPENDS test bar)
diff --git a/Tests/RunCMake/ExternalProject/NoOptions-result.txt b/Tests/RunCMake/ExternalProject/NoOptions-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/NoOptions-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalProject/NoOptions-stderr.txt b/Tests/RunCMake/ExternalProject/NoOptions-stderr.txt
new file mode 100644
index 000000000..12a76c5d4
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/NoOptions-stderr.txt
@@ -0,0 +1,18 @@
+^CMake Error at .*/Modules/ExternalProject.cmake:[0-9]+ \(message\):
+ No download info given for 'MyProj' and its source directory:
+
+ .*/Tests/RunCMake/ExternalProject/NoOptions-build/MyProj-prefix/src/MyProj
+
+ is not an existing non-empty directory. Please specify one of:
+
+ \* SOURCE_DIR with an existing non-empty directory
+ \* URL
+ \* GIT_REPOSITORY
+ \* HG_REPOSITORY
+ \* CVS_REPOSITORY and CVS_MODULE
+ \* SVN_REVISION
+ \* DOWNLOAD_COMMAND
+Call Stack \(most recent call first\):
+ .*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_download_command\)
+ NoOptions.cmake:[0-9]+ \(ExternalProject_Add\)
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/ExternalProject/NoOptions.cmake b/Tests/RunCMake/ExternalProject/NoOptions.cmake
new file mode 100644
index 000000000..7613c156a
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/NoOptions.cmake
@@ -0,0 +1,2 @@
+include(ExternalProject)
+ExternalProject_Add(MyProj)
diff --git a/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake
new file mode 100644
index 000000000..47d612969
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake
@@ -0,0 +1,14 @@
+include(RunCMake)
+
+run_cmake(NoOptions)
+run_cmake(SourceEmpty)
+run_cmake(SourceMissing)
+run_cmake(CMAKE_CACHE_ARGS)
+run_cmake(CMAKE_CACHE_DEFAULT_ARGS)
+run_cmake(CMAKE_CACHE_mix)
+run_cmake(NO_DEPENDS)
+run_cmake(Add_StepDependencies)
+run_cmake(Add_StepDependencies_iface)
+run_cmake(Add_StepDependencies_iface_step)
+run_cmake(Add_StepDependencies_no_target)
+run_cmake(UsesTerminal)
diff --git a/Tests/RunCMake/ExternalProject/SourceEmpty-result.txt b/Tests/RunCMake/ExternalProject/SourceEmpty-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/SourceEmpty-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalProject/SourceEmpty-stderr.txt b/Tests/RunCMake/ExternalProject/SourceEmpty-stderr.txt
new file mode 100644
index 000000000..58a343ccf
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/SourceEmpty-stderr.txt
@@ -0,0 +1,18 @@
+^CMake Error at .*/Modules/ExternalProject.cmake:[0-9]+ \(message\):
+ No download info given for 'MyProj' and its source directory:
+
+ .*/Tests/RunCMake/ExternalProject/SourceEmpty-build/SourceEmpty
+
+ is not an existing non-empty directory. Please specify one of:
+
+ \* SOURCE_DIR with an existing non-empty directory
+ \* URL
+ \* GIT_REPOSITORY
+ \* HG_REPOSITORY
+ \* CVS_REPOSITORY and CVS_MODULE
+ \* SVN_REVISION
+ \* DOWNLOAD_COMMAND
+Call Stack \(most recent call first\):
+ .*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_download_command\)
+ SourceEmpty.cmake:[0-9]+ \(ExternalProject_Add\)
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/ExternalProject/SourceEmpty.cmake b/Tests/RunCMake/ExternalProject/SourceEmpty.cmake
new file mode 100644
index 000000000..db746e9e4
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/SourceEmpty.cmake
@@ -0,0 +1,5 @@
+include(ExternalProject)
+set(source_dir "${CMAKE_CURRENT_BINARY_DIR}/SourceEmpty")
+file(REMOVE_RECURSE "${source_dir}")
+file(MAKE_DIRECTORY "${source_dir}")
+ExternalProject_Add(MyProj SOURCE_DIR "${source_dir}")
diff --git a/Tests/RunCMake/ExternalProject/SourceMissing-result.txt b/Tests/RunCMake/ExternalProject/SourceMissing-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/SourceMissing-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalProject/SourceMissing-stderr.txt b/Tests/RunCMake/ExternalProject/SourceMissing-stderr.txt
new file mode 100644
index 000000000..e62f7cf5a
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/SourceMissing-stderr.txt
@@ -0,0 +1,18 @@
+^CMake Error at .*/Modules/ExternalProject.cmake:[0-9]+ \(message\):
+ No download info given for 'MyProj' and its source directory:
+
+ .*/Tests/RunCMake/ExternalProject/SourceMissing-build/SourceMissing
+
+ is not an existing non-empty directory. Please specify one of:
+
+ \* SOURCE_DIR with an existing non-empty directory
+ \* URL
+ \* GIT_REPOSITORY
+ \* HG_REPOSITORY
+ \* CVS_REPOSITORY and CVS_MODULE
+ \* SVN_REVISION
+ \* DOWNLOAD_COMMAND
+Call Stack \(most recent call first\):
+ .*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_download_command\)
+ SourceMissing.cmake:[0-9]+ \(ExternalProject_Add\)
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/ExternalProject/SourceMissing.cmake b/Tests/RunCMake/ExternalProject/SourceMissing.cmake
new file mode 100644
index 000000000..8f369d48d
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/SourceMissing.cmake
@@ -0,0 +1,2 @@
+include(ExternalProject)
+ExternalProject_Add(MyProj SOURCE_DIR SourceMissing)
diff --git a/Tests/RunCMake/ExternalProject/UsesTerminal-check.cmake b/Tests/RunCMake/ExternalProject/UsesTerminal-check.cmake
new file mode 100644
index 000000000..201d822ba
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/UsesTerminal-check.cmake
@@ -0,0 +1,97 @@
+cmake_minimum_required(VERSION 3.3)
+
+# If we are using the Ninja generator, we can check and verify that the
+# USES_TERMINAL option actually works by examining the Ninja build file.
+# This is the only way, since CMake doesn't offer a way to examine the
+# options on a custom command after it has been added. Furthermore,
+# there isn't an easy way to test for this by actually running Ninja.
+#
+# Other generators don't currently support USES_TERMINAL at this time.
+# This file can be improved to support them if they do. Until then, we
+# simply assume success for new generator types.
+#
+# For Ninja, there is a complication. If the Ninja generator detects a
+# version of Ninja < 1.5, it won't actually emit the console pool command,
+# because those Ninja versions don't yet support the console pool. In
+# that case, we also have to assume success.
+
+# Check Ninja build output to verify whether or not a target step is in the
+# console pool.
+macro(CheckNinjaStep _target _step _require)
+ if("${_build}" MATCHES
+" DESC = Performing ${_step} step for '${_target}'
+ pool = console"
+ )
+ if(NOT ${_require})
+ set(RunCMake_TEST_FAILED "${_target} ${_step} step is in console pool")
+ return()
+ endif()
+ else()
+ if(${_require})
+ set(RunCMake_TEST_FAILED "${_target} ${_step} step not in console pool")
+ return()
+ endif()
+ endif()
+endmacro()
+
+# Check Ninja build output to verify whether each target step is in the
+# console pool.
+macro(CheckNinjaTarget _target
+ _download _update _configure _build _test _install
+ )
+ CheckNinjaStep(${_target} download ${_download})
+ CheckNinjaStep(${_target} update ${_update})
+ CheckNinjaStep(${_target} configure ${_configure})
+ CheckNinjaStep(${_target} build ${_build})
+ CheckNinjaStep(${_target} test ${_test})
+ CheckNinjaStep(${_target} install ${_install})
+endmacro()
+
+# Load build/make file, depending on generator
+if(RunCMake_GENERATOR STREQUAL Ninja)
+ # Check the Ninja version. If < 1.5, console pool isn't supported and
+ # so the generator would not emit console pool usage. That would cause
+ # this test to fail.
+ execute_process(COMMAND ${RunCMake_MAKE_PROGRAM} --version
+ RESULT_VARIABLE _version_result
+ OUTPUT_VARIABLE _version
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ if(_version_result OR _version VERSION_EQUAL "0")
+ set(RunCMake_TEST_FAILED "Failed to get Ninja version")
+ return()
+ endif()
+ if(_version VERSION_LESS "1.5")
+ return() # console pool not supported on Ninja < 1.5
+ endif()
+
+ # Read the Ninja build file
+ set(_build_file "${RunCMake_TEST_BINARY_DIR}/build.ninja")
+
+ if(NOT EXISTS "${_build_file}")
+ set(RunCMake_TEST_FAILED "Ninja build file not created")
+ return()
+ endif()
+
+ file(READ "${_build_file}" _build)
+
+ set(_target_check_macro CheckNinjaTarget)
+elseif((RunCMake_GENERATOR STREQUAL "") OR NOT DEFINED RunCMake_GENERATOR)
+ # protection in case somebody renamed RunCMake_GENERATOR
+ set(RunCMake_TEST_FAILED "Unknown generator")
+ return()
+else()
+ # We don't yet know how to test USES_TERMINAL on this generator.
+ return()
+endif()
+
+# Actual tests:
+CheckNinjaTarget(TerminalTest1
+ true true true true true true )
+CheckNinjaTarget(TerminalTest2
+ true false true false true false)
+CheckNinjaTarget(TerminalTest3
+ false true false true false true )
+CheckNinjaTarget(TerminalTest4
+ false false false false false false)
diff --git a/Tests/RunCMake/ExternalProject/UsesTerminal.cmake b/Tests/RunCMake/ExternalProject/UsesTerminal.cmake
new file mode 100644
index 000000000..cd874039d
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/UsesTerminal.cmake
@@ -0,0 +1,45 @@
+if(NOT CMAKE_CONFIGURATION_TYPES)
+ set(CMAKE_BUILD_TYPE Debug)
+endif()
+include(ExternalProject)
+
+# Test various combinations of USES_TERMINAL with ExternalProject_Add.
+
+macro(DoTerminalTest _target)
+ ExternalProject_Add(${_target}
+ DOWNLOAD_COMMAND "${CMAKE_COMMAND}" -E echo "download"
+ UPDATE_COMMAND "${CMAKE_COMMAND}" -E echo "update"
+ CONFIGURE_COMMAND "${CMAKE_COMMAND}" -E echo "configure"
+ BUILD_COMMAND "${CMAKE_COMMAND}" -E echo "build"
+ TEST_COMMAND "${CMAKE_COMMAND}" -E echo "test"
+ INSTALL_COMMAND "${CMAKE_COMMAND}" -E echo "install"
+ ${ARGN}
+ )
+endmacro()
+
+# USES_TERMINAL on all steps
+DoTerminalTest(TerminalTest1
+ USES_TERMINAL_DOWNLOAD 1
+ USES_TERMINAL_UPDATE 1
+ USES_TERMINAL_CONFIGURE 1
+ USES_TERMINAL_BUILD 1
+ USES_TERMINAL_TEST 1
+ USES_TERMINAL_INSTALL 1
+ )
+
+# USES_TERMINAL on every other step, starting with download
+DoTerminalTest(TerminalTest2
+ USES_TERMINAL_DOWNLOAD 1
+ USES_TERMINAL_CONFIGURE 1
+ USES_TERMINAL_TEST 1
+ )
+
+# USES_TERMINAL on every other step, starting with update
+DoTerminalTest(TerminalTest3
+ USES_TERMINAL_UPDATE 1
+ USES_TERMINAL_BUILD 1
+ USES_TERMINAL_INSTALL 1
+ )
+
+# USES_TERMINAL on no step
+DoTerminalTest(TerminalTest4)
diff --git a/Tests/RunCMake/FPHSA/FindPseudo.cmake b/Tests/RunCMake/FPHSA/FindPseudo.cmake
new file mode 100644
index 000000000..dc3558bd4
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/FindPseudo.cmake
@@ -0,0 +1,6 @@
+# pseudo find_module
+
+set(FOOBAR TRUE)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Pseudo REQUIRED_VARS FOOBAR VERSION_VAR Pseudo_VERSION)
diff --git a/Tests/RunCMake/FPHSA/RunCMakeTest.cmake b/Tests/RunCMake/FPHSA/RunCMakeTest.cmake
index 0d48fa973..e9b2a7a70 100644
--- a/Tests/RunCMake/FPHSA/RunCMakeTest.cmake
+++ b/Tests/RunCMake/FPHSA/RunCMakeTest.cmake
@@ -1,3 +1,30 @@
include(RunCMake)
run_cmake(BadFoundVar)
+
+# The pseudo module will "find" a package with the given version. Check if the
+# version selection code in FPHSA works correctly.
+set(RunCMake_TEST_OPTIONS "-DCMAKE_MODULE_PATH=${CMAKE_CURRENT_LIST_DIR}" "-DPseudo_VERSION=1.2.3.4.5")
+run_cmake(any_version)
+
+# test EXACT mode with every subcomponent
+run_cmake(exact_1)
+run_cmake(exact_1.2)
+run_cmake(exact_1.2.3)
+run_cmake(exact_1.2.3.4)
+
+# now test every component with an invalid version
+set(RunCMake_DEFAULT_stderr ".")
+run_cmake(exact_0)
+run_cmake(exact_2)
+run_cmake(exact_1.1)
+run_cmake(exact_1.3)
+run_cmake(exact_1.2.2)
+run_cmake(exact_1.2.4)
+run_cmake(exact_1.2.3.3)
+run_cmake(exact_1.2.3.5)
+unset(RunCMake_DEFAULT_stderr)
+
+# check if searching for a version 0 works
+list(APPEND RunCMake_TEST_OPTIONS "-DCMAKE_MODULE_PATH=${CMAKE_CURRENT_LIST_DIR}" "-DPseudo_VERSION=0")
+run_cmake(exact_0_matching)
diff --git a/Tests/RunCMake/FPHSA/any_version.cmake b/Tests/RunCMake/FPHSA/any_version.cmake
new file mode 100644
index 000000000..b34a540c9
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/any_version.cmake
@@ -0,0 +1 @@
+find_package(Pseudo REQUIRED)
diff --git a/Tests/RunCMake/FPHSA/exact_0-result.txt b/Tests/RunCMake/FPHSA/exact_0-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/exact_0-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/FPHSA/exact_0.cmake b/Tests/RunCMake/FPHSA/exact_0.cmake
new file mode 100644
index 000000000..432887bad
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/exact_0.cmake
@@ -0,0 +1 @@
+find_package(Pseudo 0 EXACT REQUIRED)
diff --git a/Tests/RunCMake/FPHSA/exact_0_matching.cmake b/Tests/RunCMake/FPHSA/exact_0_matching.cmake
new file mode 100644
index 000000000..432887bad
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/exact_0_matching.cmake
@@ -0,0 +1 @@
+find_package(Pseudo 0 EXACT REQUIRED)
diff --git a/Tests/RunCMake/FPHSA/exact_1.1-result.txt b/Tests/RunCMake/FPHSA/exact_1.1-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/exact_1.1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/FPHSA/exact_1.1.cmake b/Tests/RunCMake/FPHSA/exact_1.1.cmake
new file mode 100644
index 000000000..d967da927
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/exact_1.1.cmake
@@ -0,0 +1 @@
+find_package(Pseudo 1.1 EXACT REQUIRED)
diff --git a/Tests/RunCMake/FPHSA/exact_1.2.2-result.txt b/Tests/RunCMake/FPHSA/exact_1.2.2-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/exact_1.2.2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/FPHSA/exact_1.2.2.cmake b/Tests/RunCMake/FPHSA/exact_1.2.2.cmake
new file mode 100644
index 000000000..e959f610e
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/exact_1.2.2.cmake
@@ -0,0 +1 @@
+find_package(Pseudo 1.2.2 EXACT REQUIRED)
diff --git a/Tests/RunCMake/FPHSA/exact_1.2.3.3-result.txt b/Tests/RunCMake/FPHSA/exact_1.2.3.3-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/exact_1.2.3.3-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/FPHSA/exact_1.2.3.3.cmake b/Tests/RunCMake/FPHSA/exact_1.2.3.3.cmake
new file mode 100644
index 000000000..af53cc8da
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/exact_1.2.3.3.cmake
@@ -0,0 +1 @@
+find_package(Pseudo 1.2.3.3 EXACT REQUIRED)
diff --git a/Tests/RunCMake/FPHSA/exact_1.2.3.4.cmake b/Tests/RunCMake/FPHSA/exact_1.2.3.4.cmake
new file mode 100644
index 000000000..1e2baa64e
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/exact_1.2.3.4.cmake
@@ -0,0 +1 @@
+find_package(Pseudo 1.2.3.4 EXACT REQUIRED)
diff --git a/Tests/RunCMake/FPHSA/exact_1.2.3.5-result.txt b/Tests/RunCMake/FPHSA/exact_1.2.3.5-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/exact_1.2.3.5-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/FPHSA/exact_1.2.3.5.cmake b/Tests/RunCMake/FPHSA/exact_1.2.3.5.cmake
new file mode 100644
index 000000000..ddb0d1378
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/exact_1.2.3.5.cmake
@@ -0,0 +1 @@
+find_package(Pseudo 1.2.3.5 EXACT REQUIRED)
diff --git a/Tests/RunCMake/FPHSA/exact_1.2.3.cmake b/Tests/RunCMake/FPHSA/exact_1.2.3.cmake
new file mode 100644
index 000000000..bf9b2a316
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/exact_1.2.3.cmake
@@ -0,0 +1 @@
+find_package(Pseudo 1.2.3 EXACT REQUIRED)
diff --git a/Tests/RunCMake/FPHSA/exact_1.2.4-result.txt b/Tests/RunCMake/FPHSA/exact_1.2.4-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/exact_1.2.4-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/FPHSA/exact_1.2.4.cmake b/Tests/RunCMake/FPHSA/exact_1.2.4.cmake
new file mode 100644
index 000000000..548a07956
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/exact_1.2.4.cmake
@@ -0,0 +1 @@
+find_package(Pseudo 1.2.4 EXACT REQUIRED)
diff --git a/Tests/RunCMake/FPHSA/exact_1.2.cmake b/Tests/RunCMake/FPHSA/exact_1.2.cmake
new file mode 100644
index 000000000..080d96108
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/exact_1.2.cmake
@@ -0,0 +1 @@
+find_package(Pseudo 1.2 EXACT REQUIRED)
diff --git a/Tests/RunCMake/FPHSA/exact_1.3-result.txt b/Tests/RunCMake/FPHSA/exact_1.3-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/exact_1.3-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/FPHSA/exact_1.3.cmake b/Tests/RunCMake/FPHSA/exact_1.3.cmake
new file mode 100644
index 000000000..e36b0c568
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/exact_1.3.cmake
@@ -0,0 +1 @@
+find_package(Pseudo 1.3 EXACT REQUIRED)
diff --git a/Tests/RunCMake/FPHSA/exact_1.cmake b/Tests/RunCMake/FPHSA/exact_1.cmake
new file mode 100644
index 000000000..adadbc4cf
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/exact_1.cmake
@@ -0,0 +1 @@
+find_package(Pseudo 1 EXACT REQUIRED)
diff --git a/Tests/RunCMake/FPHSA/exact_2-result.txt b/Tests/RunCMake/FPHSA/exact_2-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/exact_2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/FPHSA/exact_2.cmake b/Tests/RunCMake/FPHSA/exact_2.cmake
new file mode 100644
index 000000000..55353a8b8
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/exact_2.cmake
@@ -0,0 +1 @@
+find_package(Pseudo 2 EXACT REQUIRED)
diff --git a/Tests/RunCMake/FeatureSummary/CMakeLists.txt b/Tests/RunCMake/FeatureSummary/CMakeLists.txt
new file mode 100644
index 000000000..72abfc809
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.11)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatAll-stdout.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatAll-stdout.txt
new file mode 100644
index 000000000..9a3f02387
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatAll-stdout.txt
@@ -0,0 +1,7 @@
+-- The following features have been enabled:
+
+ \* Foo , Foo\.
+
+-- The following features have been disabled:
+
+ \* Bar , Bar\.
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatAll.cmake b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatAll.cmake
new file mode 100644
index 000000000..ec5ebcb5f
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatAll.cmake
@@ -0,0 +1,9 @@
+include(FeatureSummary)
+
+set(WITH_FOO 1)
+set(WITH_BAR 0)
+
+add_feature_info(Foo WITH_FOO "Foo.")
+add_feature_info(Bar WITH_BAR "Bar.")
+
+feature_summary(WHAT ALL)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatList-stdout.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatList-stdout.txt
new file mode 100644
index 000000000..4d8f25f5e
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatList-stdout.txt
@@ -0,0 +1,7 @@
+-- The following features have been disabled:
+
+ \* Bar , Bar\.
+
+-- The following features have been enabled:
+
+ \* Foo , Foo\.
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatList.cmake b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatList.cmake
new file mode 100644
index 000000000..d04ba885a
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatList.cmake
@@ -0,0 +1,9 @@
+include(FeatureSummary)
+
+set(WITH_FOO 1)
+set(WITH_BAR 0)
+
+add_feature_info(Foo WITH_FOO "Foo.")
+add_feature_info(Bar WITH_BAR "Bar.")
+
+feature_summary(WHAT DISABLED_FEATURES ENABLED_FEATURES)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatListAll-result.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatListAll-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatListAll-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatListAll-stderr.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatListAll-stderr.txt
new file mode 100644
index 000000000..18d9ebdee
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatListAll-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at .*/Modules/FeatureSummary\.cmake:[0-9]+. \(message\):
+ The WHAT argument of FEATURE_SUMMARY\(\) contains ALL, which cannot be
+ combined with other values\.
+Call Stack \(most recent call first\):
+ FeatureSummaryWhatListAll\.cmake:[0-9]+ \(feature_summary\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatListAll.cmake b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatListAll.cmake
new file mode 100644
index 000000000..1877ea5a2
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatListAll.cmake
@@ -0,0 +1,9 @@
+include(FeatureSummary)
+
+set(WITH_FOO 1)
+set(WITH_BAR 0)
+
+add_feature_info(Foo WITH_FOO "Foo.")
+add_feature_info(Bar WITH_BAR "Bar.")
+
+feature_summary(WHAT ENABLED_FEATURES ALL)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatListUnknown-result.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatListUnknown-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatListUnknown-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatListUnknown-stderr.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatListUnknown-stderr.txt
new file mode 100644
index 000000000..3ad375030
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatListUnknown-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at .*/Modules/FeatureSummary\.cmake:[0-9]+. \(message\):
+ The WHAT argument of FEATURE_SUMMARY\(\) contains FOO, which is not a valid
+ value\.
+Call Stack \(most recent call first\):
+ FeatureSummaryWhatListUnknown\.cmake:[0-9]+ \(feature_summary\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatListUnknown.cmake b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatListUnknown.cmake
new file mode 100644
index 000000000..46088d417
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatListUnknown.cmake
@@ -0,0 +1,9 @@
+include(FeatureSummary)
+
+set(WITH_FOO 1)
+set(WITH_BAR 0)
+
+add_feature_info(Foo WITH_FOO "Foo.")
+add_feature_info(Bar WITH_BAR "Bar.")
+
+feature_summary(WHAT ENABLED_FEATURES FOO)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatOnce-stdout.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatOnce-stdout.txt
new file mode 100644
index 000000000..39be105e6
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatOnce-stdout.txt
@@ -0,0 +1,4 @@
+--( )
+ \* Foo , Foo decscription\.
++
+--
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatOnce.cmake b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatOnce.cmake
new file mode 100644
index 000000000..545fb927d
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatOnce.cmake
@@ -0,0 +1,8 @@
+include(FeatureSummary)
+
+set(WITH_FOO 1)
+
+add_feature_info(Foo WITH_FOO "Foo decscription.")
+add_feature_info(Foo WITH_FOO "Foo decscription.")
+
+feature_summary(WHAT ENABLED_FEATURES)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatSingle-stdout.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatSingle-stdout.txt
new file mode 100644
index 000000000..240632dda
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatSingle-stdout.txt
@@ -0,0 +1 @@
+ \* Foo , Foo\.
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatSingle.cmake b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatSingle.cmake
new file mode 100644
index 000000000..593dfb6a1
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatSingle.cmake
@@ -0,0 +1,9 @@
+include(FeatureSummary)
+
+set(WITH_FOO 1)
+set(WITH_BAR 0)
+
+add_feature_info(Foo WITH_FOO "Foo.")
+add_feature_info(Bar WITH_BAR "Bar.")
+
+feature_summary(WHAT ENABLED_FEATURES)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatSingleUnknown-result.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatSingleUnknown-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatSingleUnknown-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatSingleUnknown-stderr.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatSingleUnknown-stderr.txt
new file mode 100644
index 000000000..c78853c75
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatSingleUnknown-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at .*/Modules/FeatureSummary\.cmake:[0-9]+. \(message\):
+ The WHAT argument of FEATURE_SUMMARY\(\) contains FOO, which is not a valid
+ value\.
+Call Stack \(most recent call first\):
+ FeatureSummaryWhatSingleUnknown\.cmake:[0-9]+ \(feature_summary\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatSingleUnknown.cmake b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatSingleUnknown.cmake
new file mode 100644
index 000000000..c2d6d2ee4
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatSingleUnknown.cmake
@@ -0,0 +1,9 @@
+include(FeatureSummary)
+
+set(WITH_FOO 1)
+set(WITH_BAR 0)
+
+add_feature_info(Foo WITH_FOO "Foo.")
+add_feature_info(Bar WITH_BAR "Bar.")
+
+feature_summary(WHAT FOO)
diff --git a/Tests/RunCMake/FeatureSummary/RunCMakeTest.cmake b/Tests/RunCMake/FeatureSummary/RunCMakeTest.cmake
new file mode 100644
index 000000000..6a5fc2882
--- /dev/null
+++ b/Tests/RunCMake/FeatureSummary/RunCMakeTest.cmake
@@ -0,0 +1,9 @@
+include(RunCMake)
+
+run_cmake(FeatureSummaryWhatAll)
+run_cmake(FeatureSummaryWhatSingle)
+run_cmake(FeatureSummaryWhatSingleUnknown)
+run_cmake(FeatureSummaryWhatList)
+run_cmake(FeatureSummaryWhatListUnknown)
+run_cmake(FeatureSummaryWhatListAll)
+run_cmake(FeatureSummaryWhatOnce)
diff --git a/Tests/RunCMake/File_Generate/CMakeLists.txt b/Tests/RunCMake/File_Generate/CMakeLists.txt
index 12cd3c775..bc0cf5d16 100644
--- a/Tests/RunCMake/File_Generate/CMakeLists.txt
+++ b/Tests/RunCMake/File_Generate/CMakeLists.txt
@@ -1,3 +1,6 @@
cmake_minimum_required(VERSION 2.8.4)
project(${RunCMake_TEST} NONE)
-include(${RunCMake_TEST}.cmake)
+if(NOT TEST_FILE)
+ set(TEST_FILE ${RunCMake_TEST}.cmake)
+endif()
+include(${TEST_FILE})
diff --git a/Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex-result.txt b/Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex.cmake b/Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex.cmake
new file mode 100644
index 000000000..e2b081d48
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex.cmake
@@ -0,0 +1,12 @@
+
+enable_language(CXX C)
+
+add_library(empty empty.cpp empty.c)
+target_compile_options(empty
+ PRIVATE LANG_IS_$<COMPILE_LANGUAGE>
+)
+
+file(GENERATE
+ OUTPUT opts-$<COMPILE_LANGUAGE>.txt
+ CONTENT "$<TARGET_PROPERTY:empty,COMPILE_OPTIONS>\n"
+)
diff --git a/Tests/RunCMake/File_Generate/CarryPermissions-result.txt b/Tests/RunCMake/File_Generate/CarryPermissions-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/CarryPermissions-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/File_Generate/CarryPermissions.cmake b/Tests/RunCMake/File_Generate/CarryPermissions.cmake
new file mode 100644
index 000000000..a04334f8e
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/CarryPermissions.cmake
@@ -0,0 +1,5 @@
+
+file(GENERATE
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output_script.sh"
+ INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input_script.sh"
+)
diff --git a/Tests/RunCMake/File_Generate/CommandConflict-stderr.txt b/Tests/RunCMake/File_Generate/CommandConflict-stderr.txt
index da97ba476..4fa3f2033 100644
--- a/Tests/RunCMake/File_Generate/CommandConflict-stderr.txt
+++ b/Tests/RunCMake/File_Generate/CommandConflict-stderr.txt
@@ -1 +1 @@
-CMake Error: File to be generated by multiple different commands: .*CommandConflict-build/output_.*.txt
+CMake Error: Files to be generated by multiple different commands: ".*CommandConflict-build/output_.*.txt"
diff --git a/Tests/RunCMake/File_Generate/EmptyCondition1-stderr.txt b/Tests/RunCMake/File_Generate/EmptyCondition1-stderr.txt
index 9fe39cca6..e823b25dd 100644
--- a/Tests/RunCMake/File_Generate/EmptyCondition1-stderr.txt
+++ b/Tests/RunCMake/File_Generate/EmptyCondition1-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at EmptyCondition1.cmake:2 \(file\):
file Incorrect arguments to GENERATE subcommand.
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/File_Generate/EmptyCondition2-stderr.txt b/Tests/RunCMake/File_Generate/EmptyCondition2-stderr.txt
index 73d5f2504..b042946f3 100644
--- a/Tests/RunCMake/File_Generate/EmptyCondition2-stderr.txt
+++ b/Tests/RunCMake/File_Generate/EmptyCondition2-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at EmptyCondition2.cmake:2 \(file\):
file CONDITION of sub-command GENERATE must not be empty if specified.
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/File_Generate/GenerateSource-result.txt b/Tests/RunCMake/File_Generate/GenerateSource-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/GenerateSource-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/File_Generate/GenerateSource.cmake b/Tests/RunCMake/File_Generate/GenerateSource.cmake
new file mode 100644
index 000000000..147a7f66a
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/GenerateSource.cmake
@@ -0,0 +1,12 @@
+
+enable_language(CXX)
+
+# Ensure re-generation
+file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
+
+file(GENERATE
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/main.cpp"
+ CONTENT "int main() { return 0; }\n"
+)
+
+add_executable(mn "${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
diff --git a/Tests/RunCMake/File_Generate/OutputConflict-stderr.txt b/Tests/RunCMake/File_Generate/OutputConflict-stderr.txt
index dbd39de50..0abb7df69 100644
--- a/Tests/RunCMake/File_Generate/OutputConflict-stderr.txt
+++ b/Tests/RunCMake/File_Generate/OutputConflict-stderr.txt
@@ -1,5 +1,5 @@
CMake Error in CMakeLists.txt:
Evaluation file to be written multiple times for different configurations
- with different content:
+ or languages with different content:
.*output.txt
diff --git a/Tests/RunCMake/File_Generate/OutputNameMatchesObjects-result.txt b/Tests/RunCMake/File_Generate/OutputNameMatchesObjects-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/OutputNameMatchesObjects-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/File_Generate/OutputNameMatchesObjects-stderr.txt b/Tests/RunCMake/File_Generate/OutputNameMatchesObjects-stderr.txt
new file mode 100644
index 000000000..d3aa97321
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/OutputNameMatchesObjects-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at OutputNameMatchesObjects.cmake:2 \(file\):
+ Error evaluating generator expression:
+
+ \$<TARGET_OBJECTS:foo>
+
+ The evaluation of the TARGET_OBJECTS generator expression is only suitable
+ for consumption by CMake. It is not suitable for writing out elsewhere.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:6 \(include\)
diff --git a/Tests/RunCMake/File_Generate/OutputNameMatchesObjects.cmake b/Tests/RunCMake/File_Generate/OutputNameMatchesObjects.cmake
new file mode 100644
index 000000000..d8074507b
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/OutputNameMatchesObjects.cmake
@@ -0,0 +1,10 @@
+
+file(GENERATE
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$<BOOL:$<TARGET_OBJECTS:foo>>somefile.cpp"
+ CONTENT "static const char content[] = \"$<TARGET_OBJECTS:foo>\";\n"
+)
+
+add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/input.txt"
+ COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/input.txt" "${CMAKE_CURRENT_BINARY_DIR}")
+
+add_executable(foo empty.cpp "${CMAKE_CURRENT_BINARY_DIR}/1somefile.cpp" "${CMAKE_CURRENT_BINARY_DIR}/input.txt")
diff --git a/Tests/RunCMake/File_Generate/OutputNameMatchesOtherSources-result.txt b/Tests/RunCMake/File_Generate/OutputNameMatchesOtherSources-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/OutputNameMatchesOtherSources-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/File_Generate/OutputNameMatchesOtherSources.cmake b/Tests/RunCMake/File_Generate/OutputNameMatchesOtherSources.cmake
new file mode 100644
index 000000000..ce601daf1
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/OutputNameMatchesOtherSources.cmake
@@ -0,0 +1,14 @@
+
+enable_language(CXX)
+
+file(GENERATE
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$<BOOL:$<TARGET_PROPERTY:foo,SOURCES>>somefile.cpp"
+ CONTENT "static const char content[] = \"$<TARGET_PROPERTY:foo,SOURCES>\";\n"
+)
+
+add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/generated.cpp"
+ COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/generated.cpp" "${CMAKE_CURRENT_BINARY_DIR}")
+
+add_executable(foo empty.cpp "${CMAKE_CURRENT_BINARY_DIR}/generated.cpp")
+
+add_executable(bar "${CMAKE_CURRENT_BINARY_DIR}/1somefile.cpp")
diff --git a/Tests/RunCMake/File_Generate/OutputNameMatchesSources-result.txt b/Tests/RunCMake/File_Generate/OutputNameMatchesSources-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/OutputNameMatchesSources-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/File_Generate/OutputNameMatchesSources-stderr.txt b/Tests/RunCMake/File_Generate/OutputNameMatchesSources-stderr.txt
new file mode 100644
index 000000000..cefb4e5e1
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/OutputNameMatchesSources-stderr.txt
@@ -0,0 +1,7 @@
+CMake Error in CMakeLists.txt:
+ Evaluation output file
+
+ ".*Tests/RunCMake/File_Generate/OutputNameMatchesSources-build/1somefile.cpp"
+
+ depends on the sources of a target it is used in. This is a dependency
+ loop and is not allowed.
diff --git a/Tests/RunCMake/File_Generate/OutputNameMatchesSources.cmake b/Tests/RunCMake/File_Generate/OutputNameMatchesSources.cmake
new file mode 100644
index 000000000..2feb9d11a
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/OutputNameMatchesSources.cmake
@@ -0,0 +1,12 @@
+
+enable_language(CXX)
+
+file(GENERATE
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$<BOOL:$<TARGET_PROPERTY:foo,SOURCES>>somefile.cpp"
+ CONTENT "static const char content[] = \"$<TARGET_PROPERTY:foo,SOURCES>\";\n"
+)
+
+add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/renamed.cpp"
+ COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp" "${CMAKE_CURRENT_BINARY_DIR}/renamed.cpp")
+
+add_executable(foo "${CMAKE_CURRENT_BINARY_DIR}/1somefile.cpp" "${CMAKE_CURRENT_BINARY_DIR}/renamed.cpp")
diff --git a/Tests/RunCMake/File_Generate/ReRunCMake-result.txt b/Tests/RunCMake/File_Generate/ReRunCMake-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/ReRunCMake-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/File_Generate/ReRunCMake.cmake b/Tests/RunCMake/File_Generate/ReRunCMake.cmake
new file mode 100644
index 000000000..109d60e6f
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/ReRunCMake.cmake
@@ -0,0 +1,5 @@
+
+file(GENERATE
+ OUTPUT output_file.txt
+ INPUT "${CMAKE_CURRENT_BINARY_DIR}/input_file.txt"
+)
diff --git a/Tests/RunCMake/File_Generate/RunCMakeTest.cmake b/Tests/RunCMake/File_Generate/RunCMakeTest.cmake
index f07431c0e..db344ef4b 100644
--- a/Tests/RunCMake/File_Generate/RunCMakeTest.cmake
+++ b/Tests/RunCMake/File_Generate/RunCMakeTest.cmake
@@ -1,10 +1,104 @@
include(RunCMake)
run_cmake(CommandConflict)
-if("${RunCMake_GENERATOR}" MATCHES "Visual Studio" OR "${RunCMake_GENERATOR}" MATCHES "XCode" )
- run_cmake(OutputConflict)
+if("${RunCMake_GENERATOR}" MATCHES "Visual Studio|Xcode" AND NOT XCODE_BELOW_2)
+ run_cmake(OutputConflict)
endif()
run_cmake(EmptyCondition1)
run_cmake(EmptyCondition2)
run_cmake(BadCondition)
run_cmake(DebugEvaluate)
+run_cmake(GenerateSource)
+run_cmake(OutputNameMatchesSources)
+run_cmake(OutputNameMatchesObjects)
+run_cmake(OutputNameMatchesOtherSources)
+file(READ "${RunCMake_BINARY_DIR}/OutputNameMatchesOtherSources-build/1somefile.cpp" file_contents)
+if (NOT file_contents MATCHES "generated.cpp.rule")
+ message(SEND_ERROR "Rule file not in target sources! ${file_contents}")
+endif()
+
+if (NOT RunCMake_GENERATOR MATCHES "Visual Studio")
+ run_cmake(COMPILE_LANGUAGE-genex)
+ foreach(l CXX C)
+ file(READ "${RunCMake_BINARY_DIR}/COMPILE_LANGUAGE-genex-build/opts-${l}.txt" l_defs)
+ if (NOT l_defs STREQUAL "LANG_IS_${l}\n")
+ message(FATAL_ERROR "File content does not match: ${l_defs}")
+ endif()
+ endforeach()
+endif()
+
+set(timeformat "%Y%j%H%M%S")
+
+file(REMOVE "${RunCMake_BINARY_DIR}/WriteIfDifferent-build/output_file.txt")
+set(RunCMake_TEST_OPTIONS "-DTEST_FILE=WriteIfDifferent.cmake")
+set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/WriteIfDifferent-build")
+run_cmake(WriteIfDifferent-prepare)
+unset(RunCMake_TEST_OPTIONS)
+unset(RunCMake_TEST_BINARY_DIR)
+file(TIMESTAMP "${RunCMake_BINARY_DIR}/WriteIfDifferent-build/output_file.txt" timestamp ${timeformat})
+if(NOT timestamp)
+ message(SEND_ERROR "Could not get timestamp for \"${RunCMake_BINARY_DIR}/WriteIfDifferent-build/output_file.txt\"")
+endif()
+
+execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1)
+
+set(RunCMake_TEST_NO_CLEAN ON)
+run_cmake(WriteIfDifferent)
+file(TIMESTAMP "${RunCMake_BINARY_DIR}/WriteIfDifferent-build/output_file.txt" timestamp_after ${timeformat})
+if(NOT timestamp_after)
+ message(SEND_ERROR "Could not get timestamp for \"${RunCMake_BINARY_DIR}/WriteIfDifferent-build/output_file.txt\"")
+endif()
+unset(RunCMake_TEST_NO_CLEAN)
+
+if (NOT timestamp_after STREQUAL timestamp)
+ message(SEND_ERROR "WriteIfDifferent changed output file.")
+endif()
+
+if (UNIX AND EXISTS /bin/sh)
+ set(RunCMake_TEST_NO_CLEAN ON)
+ run_cmake(CarryPermissions)
+ execute_process(
+ COMMAND "${RunCMake_BINARY_DIR}/CarryPermissions-build/output_script.sh"
+ OUTPUT_VARIABLE script_output
+ RESULT_VARIABLE script_result
+ ERROR_VARIABLE script_error
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ if (script_result)
+ message(SEND_ERROR "Generated script did not execute correctly: [${script_result}]\n${script_output}\n====\n${script_error}")
+ endif()
+ if (NOT script_output STREQUAL SUCCESS)
+ message(SEND_ERROR "Generated script did not execute correctly:\n${script_output}\n====\n${script_error}")
+ endif()
+endif()
+
+if (RunCMake_GENERATOR MATCHES Makefiles)
+ file(MAKE_DIRECTORY "${RunCMake_BINARY_DIR}/ReRunCMake-build/")
+ file(WRITE "${RunCMake_BINARY_DIR}/ReRunCMake-build/input_file.txt" "InitialContent\n")
+
+ set(RunCMake_TEST_NO_CLEAN ON)
+ run_cmake(ReRunCMake)
+ unset(RunCMake_TEST_NO_CLEAN)
+ file(TIMESTAMP "${RunCMake_BINARY_DIR}/ReRunCMake-build/output_file.txt" timestamp ${timeformat})
+ if(NOT timestamp)
+ message(SEND_ERROR "Could not get timestamp for \"${RunCMake_BINARY_DIR}/ReRunCMake-build/output_file.txt\"")
+ endif()
+
+ execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1)
+
+ file(WRITE "${RunCMake_BINARY_DIR}/ReRunCMake-build/input_file.txt" "ChangedContent\n")
+ execute_process(COMMAND ${CMAKE_COMMAND} --build "${RunCMake_BINARY_DIR}/ReRunCMake-build/")
+ file(READ "${RunCMake_BINARY_DIR}/ReRunCMake-build/output_file.txt" out_content)
+
+ if(NOT out_content STREQUAL "ChangedContent\n")
+ message(SEND_ERROR "File did not change: \"${RunCMake_BINARY_DIR}/ReRunCMake-build/output_file.txt\"")
+ endif()
+
+
+ file(REMOVE "${RunCMake_BINARY_DIR}/ReRunCMake-build/output_file.txt")
+ execute_process(COMMAND ${CMAKE_COMMAND} --build "${RunCMake_BINARY_DIR}/ReRunCMake-build/")
+
+ if (NOT EXISTS "${RunCMake_BINARY_DIR}/ReRunCMake-build/output_file.txt")
+ message(SEND_ERROR "File did not re-generate: \"${RunCMake_BINARY_DIR}/ReRunCMake-build/output_file.txt\"")
+ endif()
+endif()
diff --git a/Tests/RunCMake/File_Generate/WriteIfDifferent-result.txt b/Tests/RunCMake/File_Generate/WriteIfDifferent-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/WriteIfDifferent-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/File_Generate/WriteIfDifferent.cmake b/Tests/RunCMake/File_Generate/WriteIfDifferent.cmake
new file mode 100644
index 000000000..d1d832a11
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/WriteIfDifferent.cmake
@@ -0,0 +1,5 @@
+
+file(GENERATE
+ OUTPUT output_file.txt
+ CONTENT "123"
+)
diff --git a/Tests/RunCMake/File_Generate/empty.c b/Tests/RunCMake/File_Generate/empty.c
new file mode 100644
index 000000000..563eef01c
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/empty.c
@@ -0,0 +1,8 @@
+
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty_c()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/File_Generate/empty.cpp b/Tests/RunCMake/File_Generate/empty.cpp
new file mode 100644
index 000000000..bfbbddeb9
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/empty.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/File_Generate/input_script.sh b/Tests/RunCMake/File_Generate/input_script.sh
new file mode 100755
index 000000000..2cc098384
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/input_script.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+echo "$<$<STREQUAL:foo,foo>:SUCCESS>"
diff --git a/Tests/RunCMake/FindMatlab/CMakeLists.txt b/Tests/RunCMake/FindMatlab/CMakeLists.txt
new file mode 100644
index 000000000..1b9a95788
--- /dev/null
+++ b/Tests/RunCMake/FindMatlab/CMakeLists.txt
@@ -0,0 +1,3 @@
+
+cmake_minimum_required(VERSION 2.8.12)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/FindMatlab/MatlabTest1-result.txt b/Tests/RunCMake/FindMatlab/MatlabTest1-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/FindMatlab/MatlabTest1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/FindMatlab/MatlabTest1-stderr.txt b/Tests/RunCMake/FindMatlab/MatlabTest1-stderr.txt
new file mode 100644
index 000000000..95a787fa1
--- /dev/null
+++ b/Tests/RunCMake/FindMatlab/MatlabTest1-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error at .*FindMatlab.cmake:[0-9]+ \(message\):
+ \[MATLAB\] This functionality needs the MAIN_PROGRAM component \(not default\)
diff --git a/Tests/RunCMake/FindMatlab/MatlabTest1.cmake b/Tests/RunCMake/FindMatlab/MatlabTest1.cmake
new file mode 100644
index 000000000..1cbc1c202
--- /dev/null
+++ b/Tests/RunCMake/FindMatlab/MatlabTest1.cmake
@@ -0,0 +1,22 @@
+
+cmake_minimum_required (VERSION 2.8.12)
+enable_testing()
+project(test_should_fail)
+
+find_package(Matlab REQUIRED COMPONENTS MX_LIBRARY)
+
+matlab_add_mex(
+ # target name
+ NAME cmake_matlab_test_wrapper1
+ # output name
+ OUTPUT_NAME cmake_matlab_mex1
+ SRC ${CMAKE_CURRENT_SOURCE_DIR}/matlab_wrapper1.cpp
+ )
+
+# this command should raise a FATAL_ERROR, component MAIN_PROGRAM is missing
+matlab_add_unit_test(
+ NAME ${PROJECT_NAME}_matlabtest-1
+ TIMEOUT 1
+ UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/cmake_matlab_unit_tests2.m
+ ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper1>
+ )
diff --git a/Tests/RunCMake/FindMatlab/MatlabTest2-result.txt b/Tests/RunCMake/FindMatlab/MatlabTest2-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/FindMatlab/MatlabTest2-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/FindMatlab/MatlabTest2-stderr.txt b/Tests/RunCMake/FindMatlab/MatlabTest2-stderr.txt
new file mode 100644
index 000000000..9abb766ce
--- /dev/null
+++ b/Tests/RunCMake/FindMatlab/MatlabTest2-stderr.txt
@@ -0,0 +1 @@
+.* \ No newline at end of file
diff --git a/Tests/RunCMake/FindMatlab/MatlabTest2.cmake b/Tests/RunCMake/FindMatlab/MatlabTest2.cmake
new file mode 100644
index 000000000..d5b0e6db1
--- /dev/null
+++ b/Tests/RunCMake/FindMatlab/MatlabTest2.cmake
@@ -0,0 +1,9 @@
+cmake_minimum_required (VERSION 2.8.12)
+enable_testing()
+project(findmatlab_runcmake_test2)
+
+if(NOT DEFINED matlab_required)
+ set(matlab_required REQUIRED)
+endif()
+
+find_package(Matlab ${matlab_required} COMPONENTS MX_LIBRARY)
diff --git a/Tests/RunCMake/FindMatlab/RunCMakeTest.cmake b/Tests/RunCMake/FindMatlab/RunCMakeTest.cmake
new file mode 100644
index 000000000..f0eb6b4bb
--- /dev/null
+++ b/Tests/RunCMake/FindMatlab/RunCMakeTest.cmake
@@ -0,0 +1,51 @@
+
+include(RunCMake)
+run_cmake(MatlabTest1)
+
+if(RunCMake_GENERATOR MATCHES "Make" AND UNIX)
+ # Use a single build tree for a few tests without cleaning.
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/RerunFindMatlab-build-init)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+ message(STATUS "RerunFindMatlab: first configuration to extract real Matlab_ROOT_DIR")
+ set(RunCMake_TEST_OPTIONS "-Dmatlab_required=REQUIRED")
+ run_cmake(MatlabTest2)
+
+ message(STATUS "RerunFindMatlab: flushing the variables")
+ execute_process(COMMAND
+ ${CMAKE_COMMAND} -L ${RunCMake_TEST_BINARY_DIR}
+ RESULT_VARIABLE _MatlabTest2_error
+ OUTPUT_VARIABLE _MatlabTest2_output)
+ if(NOT _MatlabTest2_error EQUAL 0)
+ message(FATAL_ERROR "RerunFindMatlab: cannot list the variables ...")
+ endif()
+
+ string(REGEX MATCH "Matlab_ROOT_DIR.+=([^\r\n]+)" _matched ${_MatlabTest2_output})
+
+ set(Matlab_ROOT_DIR_correct "${CMAKE_MATCH_1}")
+ if(Matlab_ROOT_DIR_correct STREQUAL "")
+ message(FATAL_ERROR "RerunFindMatlab: cannot extract Matlab_ROOT_DIR")
+ endif()
+ message(STATUS "RerunFindMatlab: detected correct Matlab_ROOT_DIR=${Matlab_ROOT_DIR_correct}")
+
+ message(STATUS "RerunFindMatlab: change configuration, incorrect Matlab_ROOT_DIR setting")
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/RerunFindMatlab-build-second)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+ set(RunCMake_TEST_OPTIONS "-DMatlab_ROOT_DIR=/" "-Dmatlab_required=")
+ run_cmake(MatlabTest2)
+
+ message(STATUS "RerunFindMatlab: fixing configuration with correct Matlab_ROOT_DIR setting")
+ set(RunCMake_TEST_OPTIONS "-DMatlab_ROOT_DIR=${Matlab_ROOT_DIR_correct}") # required this time?
+ run_cmake(MatlabTest2)
+
+ # no target on this test
+ run_cmake_command(MatlabTest2 ${CMAKE_COMMAND} --build .)
+
+ unset(RunCMake_TEST_BINARY_DIR)
+ unset(RunCMake_TEST_NO_CLEAN)
+endif()
diff --git a/Tests/RunCMake/FindMatlab/cmake_matlab_unit_tests2.m b/Tests/RunCMake/FindMatlab/cmake_matlab_unit_tests2.m
new file mode 100644
index 000000000..7a8a342de
--- /dev/null
+++ b/Tests/RunCMake/FindMatlab/cmake_matlab_unit_tests2.m
@@ -0,0 +1,6 @@
+
+ret = cmake_matlab_mex1(rand(3,3));
+
+if(size(ret) ~= size(rand(3,3)))
+ error('Dimension mismatch!');
+end
diff --git a/Tests/RunCMake/FindMatlab/matlab_wrapper1.cpp b/Tests/RunCMake/FindMatlab/matlab_wrapper1.cpp
new file mode 100644
index 000000000..4149bb954
--- /dev/null
+++ b/Tests/RunCMake/FindMatlab/matlab_wrapper1.cpp
@@ -0,0 +1,26 @@
+
+// simple workaround to some compiler specific problems
+// see http://stackoverflow.com/questions/22367516/mex-compile-error-unknown-type-name-char16-t/23281916#23281916
+#include <algorithm>
+
+#include "mex.h"
+
+// this test should return a matrix of 10 x 10 and should check some of the arguments
+
+void mexFunction(const int nlhs, mxArray *plhs[], const int nrhs, const mxArray *prhs[])
+{
+ if(nrhs != 1)
+ {
+ mexErrMsgTxt("Incorrect arguments");
+ }
+
+ size_t dim1 = mxGetM(prhs[0]);
+ size_t dim2 = mxGetN(prhs[0]);
+
+ if(dim1 == 1 || dim2 == 1)
+ {
+ mexErrMsgIdAndTxt("cmake_matlab:configuration", "Incorrect arguments");
+ }
+
+ plhs[0] = mxCreateNumericMatrix(dim1, dim2, mxGetClassID(prhs[0]), mxREAL);
+}
diff --git a/Tests/RunCMake/FindPkgConfig/CMakeLists.txt b/Tests/RunCMake/FindPkgConfig/CMakeLists.txt
new file mode 100644
index 000000000..72abfc809
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.11)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_CMAKE_APPBUNDLE_PATH.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_CMAKE_APPBUNDLE_PATH.cmake
new file mode 100644
index 000000000..9d4826fa8
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_CMAKE_APPBUNDLE_PATH.cmake
@@ -0,0 +1,51 @@
+# Needed for CMAKE_SYSTEM_NAME, CMAKE_LIBRARY_ARCHITECTURE and FIND_LIBRARY_USE_LIB64_PATHS
+enable_language(C)
+
+# Prepare environment and variables
+set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH TRUE)
+set(CMAKE_APPBUNDLE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/pc-foo")
+if(WIN32)
+ set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}\\dummy-pkg-config.bat")
+ set(ENV{CMAKE_APPBUNDLE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}\\pc-bar;X:\\this\\directory\\should\\not\\exist\\in\\the\\filesystem")
+ set(ENV{PKG_CONFIG_PATH} "C:\\baz")
+else()
+ set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}/dummy-pkg-config.sh")
+ set(ENV{CMAKE_APPBUNDLE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/pc-bar:/this/directory/should/not/exist/in/the/filesystem")
+ set(ENV{PKG_CONFIG_PATH} "/baz")
+endif()
+
+
+find_package(PkgConfig)
+
+
+if(NOT DEFINED CMAKE_SYSTEM_NAME
+ OR (CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU)$"
+ AND NOT CMAKE_CROSSCOMPILING))
+ if(EXISTS "/etc/debian_version") # is this a debian system ?
+ if(CMAKE_LIBRARY_ARCHITECTURE MATCHES "^(i386-linux-gnu|x86_64-linux-gnu)$")
+ # Cannot create directories for all the existing architectures...
+ set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/${CMAKE_LIBRARY_ARCHITECTURE}/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/${CMAKE_LIBRARY_ARCHITECTURE}/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
+ else()
+ set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
+ endif()
+ else()
+ # not debian, chech the FIND_LIBRARY_USE_LIB64_PATHS property
+ get_property(uselib64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
+ if(uselib64)
+ set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib64/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib64/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
+ endif()
+ endif()
+else()
+ if(WIN32)
+ set(expected_path "C:\\baz;${CMAKE_CURRENT_SOURCE_DIR}\\pc-foo\\lib\\pkgconfig;${CMAKE_CURRENT_SOURCE_DIR}\\pc-bar\\lib\\pkgconfig")
+ else()
+ set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
+ endif()
+endif()
+
+
+pkg_check_modules(FOO "${expected_path}")
+
+if(NOT FOO_FOUND)
+ message(FATAL_ERROR "Expected PKG_CONFIG_PATH: \"${expected_path}\".")
+endif()
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_CMAKE_FRAMEWORK_PATH.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_CMAKE_FRAMEWORK_PATH.cmake
new file mode 100644
index 000000000..d9943d4fe
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_CMAKE_FRAMEWORK_PATH.cmake
@@ -0,0 +1,51 @@
+# Needed for CMAKE_SYSTEM_NAME, CMAKE_LIBRARY_ARCHITECTURE and FIND_LIBRARY_USE_LIB64_PATHS
+enable_language(C)
+
+# Prepare environment and variables
+set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH TRUE)
+set(CMAKE_FRAMEWORK_PATH "${CMAKE_CURRENT_SOURCE_DIR}/pc-foo")
+if(WIN32)
+ set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}\\dummy-pkg-config.bat")
+ set(ENV{CMAKE_FRAMEWORK_PATH} "${CMAKE_CURRENT_SOURCE_DIR}\\pc-bar;X:\\this\\directory\\should\\not\\exist\\in\\the\\filesystem")
+ set(ENV{PKG_CONFIG_PATH} "C:\\baz")
+else()
+ set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}/dummy-pkg-config.sh")
+ set(ENV{CMAKE_FRAMEWORK_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/pc-bar:/this/directory/should/not/exist/in/the/filesystem")
+ set(ENV{PKG_CONFIG_PATH} "/baz")
+endif()
+
+
+find_package(PkgConfig)
+
+
+if(NOT DEFINED CMAKE_SYSTEM_NAME
+ OR (CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU)$"
+ AND NOT CMAKE_CROSSCOMPILING))
+ if(EXISTS "/etc/debian_version") # is this a debian system ?
+ if(CMAKE_LIBRARY_ARCHITECTURE MATCHES "^(i386-linux-gnu|x86_64-linux-gnu)$")
+ # Cannot create directories for all the existing architectures...
+ set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/${CMAKE_LIBRARY_ARCHITECTURE}/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/${CMAKE_LIBRARY_ARCHITECTURE}/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
+ else()
+ set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
+ endif()
+ else()
+ # not debian, chech the FIND_LIBRARY_USE_LIB64_PATHS property
+ get_property(uselib64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
+ if(uselib64)
+ set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib64/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib64/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
+ endif()
+ endif()
+else()
+ if(WIN32)
+ set(expected_path "C:\\baz;${CMAKE_CURRENT_SOURCE_DIR}\\pc-foo\\lib\\pkgconfig;${CMAKE_CURRENT_SOURCE_DIR}\\pc-bar\\lib\\pkgconfig")
+ else()
+ set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
+ endif()
+endif()
+
+
+pkg_check_modules(FOO "${expected_path}")
+
+if(NOT FOO_FOUND)
+ message(FATAL_ERROR "Expected PKG_CONFIG_PATH: \"${expected_path}\".")
+endif()
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_VARIABLE-stdout.txt b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_VARIABLE-stdout.txt
new file mode 100644
index 000000000..5f211ebab
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_VARIABLE-stdout.txt
@@ -0,0 +1 @@
+-- g_ir_scanner: .*/g-ir-scanner
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_VARIABLE.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_VARIABLE.cmake
new file mode 100644
index 000000000..c85efaa57
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_VARIABLE.cmake
@@ -0,0 +1,9 @@
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(GOBJECT_INTROSPECTION QUIET gobject-introspection-1.0)
+
+if (GOBJECT_INTROSPECTION_FOUND)
+ pkg_get_variable(g_ir_scanner gobject-introspection-1.0 g_ir_scanner)
+ message(STATUS "g_ir_scanner: ${g_ir_scanner}")
+else ()
+ message(STATUS "g_ir_scanner: skipping test; gobject-introspection-1.0 not found /g-ir-scanner")
+endif ()
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_NO_PKGCONFIG_PATH.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_NO_PKGCONFIG_PATH.cmake
new file mode 100644
index 000000000..89ce4c6d8
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_NO_PKGCONFIG_PATH.cmake
@@ -0,0 +1,41 @@
+# Needed for CMAKE_SYSTEM_NAME, CMAKE_LIBRARY_ARCHITECTURE and FIND_LIBRARY_USE_LIB64_PATHS
+enable_language(C)
+
+# Prepare environment and variables
+set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH FALSE)
+set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/pc-foo")
+if(WIN32)
+ set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}\\dummy-pkg-config.bat")
+ set(ENV{CMAKE_PREFIX_PATH} "${CMAKE_CURRENT_SOURCE_DIR}\\pc-bar;X:\\this\\directory\\should\\not\\exist\\in\\the\\filesystem")
+ set(ENV{PKG_CONFIG_PATH} "C:\\baz")
+else()
+ set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}/dummy-pkg-config.sh")
+ set(ENV{CMAKE_PREFIX_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/pc-bar:/this/directory/should/not/exist/in/the/filesystem")
+ set(ENV{PKG_CONFIG_PATH} "/baz")
+endif()
+
+
+find_package(PkgConfig)
+
+if(WIN32)
+ set(expected_path "C:\\baz")
+else()
+ set(expected_path "/baz")
+endif()
+
+
+pkg_check_modules(FOO "${expected_path}")
+
+if(NOT FOO_FOUND)
+ message(FATAL_ERROR "Expected PKG_CONFIG_PATH: \"${expected_path}\".")
+endif()
+
+
+
+set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH TRUE)
+
+pkg_check_modules(BAR "${expected_path}" NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH)
+
+if(NOT BAR_FOUND)
+ message(FATAL_ERROR "Expected PKG_CONFIG_PATH: \"${expected_path}\".")
+endif()
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_PKGCONFIG_PATH.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_PKGCONFIG_PATH.cmake
new file mode 100644
index 000000000..c90327955
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_PKGCONFIG_PATH.cmake
@@ -0,0 +1,51 @@
+# Needed for CMAKE_SYSTEM_NAME, CMAKE_LIBRARY_ARCHITECTURE and FIND_LIBRARY_USE_LIB64_PATHS
+enable_language(C)
+
+# Prepare environment and variables
+set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH TRUE)
+set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/pc-foo")
+if(WIN32)
+ set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}\\dummy-pkg-config.bat")
+ set(ENV{CMAKE_PREFIX_PATH} "${CMAKE_CURRENT_SOURCE_DIR}\\pc-bar;X:\\this\\directory\\should\\not\\exist\\in\\the\\filesystem")
+ set(ENV{PKG_CONFIG_PATH} "C:\\baz")
+else()
+ set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}/dummy-pkg-config.sh")
+ set(ENV{CMAKE_PREFIX_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/pc-bar:/this/directory/should/not/exist/in/the/filesystem")
+ set(ENV{PKG_CONFIG_PATH} "/baz")
+endif()
+
+
+find_package(PkgConfig)
+
+
+if(NOT DEFINED CMAKE_SYSTEM_NAME
+ OR (CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU)$"
+ AND NOT CMAKE_CROSSCOMPILING))
+ if(EXISTS "/etc/debian_version") # is this a debian system ?
+ if(CMAKE_LIBRARY_ARCHITECTURE MATCHES "^(i386-linux-gnu|x86_64-linux-gnu)$")
+ # Cannot create directories for all the existing architectures...
+ set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/${CMAKE_LIBRARY_ARCHITECTURE}/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/${CMAKE_LIBRARY_ARCHITECTURE}/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
+ else()
+ set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
+ endif()
+ else()
+ # not debian, chech the FIND_LIBRARY_USE_LIB64_PATHS property
+ get_property(uselib64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
+ if(uselib64)
+ set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib64/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib64/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
+ endif()
+ endif()
+else()
+ if(WIN32)
+ set(expected_path "C:\\baz;${CMAKE_CURRENT_SOURCE_DIR}\\pc-foo\\lib\\pkgconfig;${CMAKE_CURRENT_SOURCE_DIR}\\pc-bar\\lib\\pkgconfig")
+ else()
+ set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
+ endif()
+endif()
+
+
+pkg_check_modules(FOO "${expected_path}")
+
+if(NOT FOO_FOUND)
+ message(FATAL_ERROR "Expected PKG_CONFIG_PATH: \"${expected_path}\".")
+endif()
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_PKGCONFIG_PATH_NO_CMAKE_ENVIRONMENT_PATH.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_PKGCONFIG_PATH_NO_CMAKE_ENVIRONMENT_PATH.cmake
new file mode 100644
index 000000000..a52bcbf81
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_PKGCONFIG_PATH_NO_CMAKE_ENVIRONMENT_PATH.cmake
@@ -0,0 +1,51 @@
+# Needed for CMAKE_SYSTEM_NAME, CMAKE_LIBRARY_ARCHITECTURE and FIND_LIBRARY_USE_LIB64_PATHS
+enable_language(C)
+
+# Prepare environment and variables
+set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH TRUE)
+set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/pc-foo")
+if(WIN32)
+ set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}\\dummy-pkg-config.bat")
+ set(ENV{CMAKE_PREFIX_PATH} "${CMAKE_CURRENT_SOURCE_DIR}\\pc-bar;X:\\this\\directory\\should\\not\\exist\\in\\the\\filesystem")
+ set(ENV{PKG_CONFIG_PATH} "C:\\baz")
+else()
+ set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}/dummy-pkg-config.sh")
+ set(ENV{CMAKE_PREFIX_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/pc-bar:/this/directory/should/not/exist/in/the/filesystem")
+ set(ENV{PKG_CONFIG_PATH} "/baz")
+endif()
+
+
+find_package(PkgConfig)
+
+
+if(NOT DEFINED CMAKE_SYSTEM_NAME
+ OR (CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU)$"
+ AND NOT CMAKE_CROSSCOMPILING))
+ if(EXISTS "/etc/debian_version") # is this a debian system ?
+ if(CMAKE_LIBRARY_ARCHITECTURE MATCHES "^(i386-linux-gnu|x86_64-linux-gnu)$")
+ # Cannot create directories for all the existing architectures...
+ set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/${CMAKE_LIBRARY_ARCHITECTURE}/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig")
+ else()
+ set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig")
+ endif()
+ else()
+ # not debian, chech the FIND_LIBRARY_USE_LIB64_PATHS property
+ get_property(uselib64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
+ if(uselib64)
+ set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib64/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig")
+ endif()
+ endif()
+else()
+ if(WIN32)
+ set(expected_path "C:\\baz;${CMAKE_CURRENT_SOURCE_DIR}\\pc-foo\\lib\\pkgconfig")
+ else()
+ set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig")
+ endif()
+endif()
+
+
+pkg_check_modules(FOO "${expected_path}" NO_CMAKE_ENVIRONMENT_PATH)
+
+if(NOT FOO_FOUND)
+ message(FATAL_ERROR "Expected PKG_CONFIG_PATH: \"${expected_path}\".")
+endif()
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_PKGCONFIG_PATH_NO_CMAKE_PATH.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_PKGCONFIG_PATH_NO_CMAKE_PATH.cmake
new file mode 100644
index 000000000..2fabe5b43
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_PKGCONFIG_PATH_NO_CMAKE_PATH.cmake
@@ -0,0 +1,51 @@
+# Needed for CMAKE_SYSTEM_NAME, CMAKE_LIBRARY_ARCHITECTURE and FIND_LIBRARY_USE_LIB64_PATHS
+enable_language(C)
+
+# Prepare environment and variables
+set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH TRUE)
+set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/pc-foo")
+if(WIN32)
+ set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}\\dummy-pkg-config.bat")
+ set(ENV{CMAKE_PREFIX_PATH} "${CMAKE_CURRENT_SOURCE_DIR}\\pc-bar;X:\\this\\directory\\should\\not\\exist\\in\\the\\filesystem")
+ set(ENV{PKG_CONFIG_PATH} "C:\\baz")
+else()
+ set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}/dummy-pkg-config.sh")
+ set(ENV{CMAKE_PREFIX_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/pc-bar:/this/directory/should/not/exist/in/the/filesystem")
+ set(ENV{PKG_CONFIG_PATH} "/baz")
+endif()
+
+
+find_package(PkgConfig)
+
+
+if(NOT DEFINED CMAKE_SYSTEM_NAME
+ OR (CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU)$"
+ AND NOT CMAKE_CROSSCOMPILING))
+ if(EXISTS "/etc/debian_version") # is this a debian system ?
+ if(CMAKE_LIBRARY_ARCHITECTURE MATCHES "^(i386-linux-gnu|x86_64-linux-gnu)$")
+ # Cannot create directories for all the existing architectures...
+ set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/${CMAKE_LIBRARY_ARCHITECTURE}/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
+ else()
+ set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
+ endif()
+ else()
+ # not debian, chech the FIND_LIBRARY_USE_LIB64_PATHS property
+ get_property(uselib64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
+ if(uselib64)
+ set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib64/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
+ endif()
+ endif()
+else()
+ if(WIN32)
+ set(expected_path "C:\\baz;${CMAKE_CURRENT_SOURCE_DIR}\\pc-bar\\lib\\pkgconfig")
+ else()
+ set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
+ endif()
+endif()
+
+
+pkg_check_modules(FOO "${expected_path}" NO_CMAKE_PATH)
+
+if(NOT FOO_FOUND)
+ message(FATAL_ERROR "Expected PKG_CONFIG_PATH: \"${expected_path}\".")
+endif()
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_cache_variables.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_cache_variables.cmake
new file mode 100644
index 000000000..d0046caa1
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_cache_variables.cmake
@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 3.3)
+
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(NCURSES QUIET ncurses)
+
+if (NCURSES_FOUND)
+ foreach (variable IN ITEMS PREFIX INCLUDEDIR LIBDIR)
+ get_property(value
+ CACHE "NCURSES_${variable}"
+ PROPERTY VALUE)
+ if (NOT value STREQUAL NCURSES_${variable})
+ message(FATAL_ERROR "Failed to set cache entry for NCURSES_${variable}:\nexpected -->${value}<--\nreceived -->${NCURSES_${variable}}<--")
+ endif ()
+ endforeach ()
+else ()
+ message(STATUS "skipping test; ncurses not found")
+endif ()
diff --git a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
new file mode 100644
index 000000000..24089e0a5
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
@@ -0,0 +1,18 @@
+include(RunCMake)
+
+run_cmake(FindPkgConfig_NO_PKGCONFIG_PATH)
+run_cmake(FindPkgConfig_PKGCONFIG_PATH)
+run_cmake(FindPkgConfig_PKGCONFIG_PATH_NO_CMAKE_PATH)
+run_cmake(FindPkgConfig_PKGCONFIG_PATH_NO_CMAKE_ENVIRONMENT_PATH)
+
+if(APPLE)
+ run_cmake(FindPkgConfig_CMAKE_FRAMEWORK_PATH)
+ run_cmake(FindPkgConfig_CMAKE_APPBUNDLE_PATH)
+endif()
+
+# We need a real pkg-config to run the test for get_variable.
+find_package(PkgConfig)
+if (PKG_CONFIG_FOUND)
+ run_cmake(FindPkgConfig_GET_VARIABLE)
+ run_cmake(FindPkgConfig_cache_variables)
+endif ()
diff --git a/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.bat b/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.bat
new file mode 100755
index 000000000..f2f86b0a6
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.bat
@@ -0,0 +1,18 @@
+@ECHO OFF
+IF "%1"=="" (
+ EXIT /B 255
+)
+IF "%1"=="--version" (
+ ECHO 0.0-cmake-dummy
+ EXIT /B 0
+)
+
+IF "%1"=="--exists" (
+ SHIFT
+ ECHO Expected: %*
+ ECHO Found: %PKG_CONFIG_PATH%
+ IF NOT "%*"=="%PKG_CONFIG_PATH%" (
+ EXIT /B 1
+ )
+)
+EXIT /B 0
diff --git a/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.sh b/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.sh
new file mode 100755
index 000000000..abe14bf98
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# This is a replacement for pkg-config that compares the string passed
+# to the --exists argument with the PKG_CONFIG_PATH environment variable
+# and returns 1 if they are different.
+
+case $1 in
+ --version)
+ echo "0.0-cmake-dummy"
+ ;;
+ --exists)
+ shift
+ eval last=\${$#}
+ echo "Expected: ${last}"
+ echo "Found: ${PKG_CONFIG_PATH}"
+ [ "${last}" = "${PKG_CONFIG_PATH}" ] || exit 1
+ ;;
+ *)
+ exit 255
+ ;;
+esac
diff --git a/Tests/RunCMake/FindPkgConfig/pc-bar/lib/i386-linux-gnu/pkgconfig/.placeholder b/Tests/RunCMake/FindPkgConfig/pc-bar/lib/i386-linux-gnu/pkgconfig/.placeholder
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/pc-bar/lib/i386-linux-gnu/pkgconfig/.placeholder
diff --git a/Tests/RunCMake/FindPkgConfig/pc-bar/lib/pkgconfig/.placeholder b/Tests/RunCMake/FindPkgConfig/pc-bar/lib/pkgconfig/.placeholder
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/pc-bar/lib/pkgconfig/.placeholder
diff --git a/Tests/RunCMake/FindPkgConfig/pc-bar/lib/x86_64-linux-gnu/pkgconfig/.placeholder b/Tests/RunCMake/FindPkgConfig/pc-bar/lib/x86_64-linux-gnu/pkgconfig/.placeholder
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/pc-bar/lib/x86_64-linux-gnu/pkgconfig/.placeholder
diff --git a/Tests/RunCMake/FindPkgConfig/pc-bar/lib64/pkgconfig/.placeholder b/Tests/RunCMake/FindPkgConfig/pc-bar/lib64/pkgconfig/.placeholder
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/pc-bar/lib64/pkgconfig/.placeholder
diff --git a/Tests/RunCMake/FindPkgConfig/pc-foo/lib/i386-linux-gnu/pkgconfig/.placeholder b/Tests/RunCMake/FindPkgConfig/pc-foo/lib/i386-linux-gnu/pkgconfig/.placeholder
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/pc-foo/lib/i386-linux-gnu/pkgconfig/.placeholder
diff --git a/Tests/RunCMake/FindPkgConfig/pc-foo/lib/pkgconfig/.placeholder b/Tests/RunCMake/FindPkgConfig/pc-foo/lib/pkgconfig/.placeholder
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/pc-foo/lib/pkgconfig/.placeholder
diff --git a/Tests/RunCMake/FindPkgConfig/pc-foo/lib/x86_64-linux-gnu/pkgconfig/.placeholder b/Tests/RunCMake/FindPkgConfig/pc-foo/lib/x86_64-linux-gnu/pkgconfig/.placeholder
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/pc-foo/lib/x86_64-linux-gnu/pkgconfig/.placeholder
diff --git a/Tests/RunCMake/FindPkgConfig/pc-foo/lib64/pkgconfig/.placeholder b/Tests/RunCMake/FindPkgConfig/pc-foo/lib64/pkgconfig/.placeholder
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/pc-foo/lib64/pkgconfig/.placeholder
diff --git a/Tests/RunCMake/Framework/CMakeLists.txt b/Tests/RunCMake/Framework/CMakeLists.txt
new file mode 100644
index 000000000..6dd8cdf55
--- /dev/null
+++ b/Tests/RunCMake/Framework/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.4)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/Framework/FrameworkLayout.cmake b/Tests/RunCMake/Framework/FrameworkLayout.cmake
new file mode 100644
index 000000000..51847555b
--- /dev/null
+++ b/Tests/RunCMake/Framework/FrameworkLayout.cmake
@@ -0,0 +1,11 @@
+cmake_minimum_required(VERSION 3.4)
+enable_language(C)
+
+add_library(Framework SHARED
+ foo.c
+ foo.h
+ res.txt)
+set_target_properties(Framework PROPERTIES
+ FRAMEWORK TRUE
+ PUBLIC_HEADER foo.h
+ RESOURCE "res.txt")
diff --git a/Tests/RunCMake/Framework/OSXFrameworkLayout-build-check.cmake b/Tests/RunCMake/Framework/OSXFrameworkLayout-build-check.cmake
new file mode 100644
index 000000000..da1ccb40b
--- /dev/null
+++ b/Tests/RunCMake/Framework/OSXFrameworkLayout-build-check.cmake
@@ -0,0 +1,35 @@
+set(framework-dir "${RunCMake_TEST_BINARY_DIR}/Framework.framework")
+set(framework-resources "${framework-dir}/Resources")
+set(framework-resource-file "${framework-resources}/res.txt")
+set(framework-library "${framework-dir}/Framework")
+set(framework-versions "${framework-dir}/Versions")
+set(plist-file "${framework-resources}/Info.plist")
+set(framework-header "${framework-dir}/Headers/foo.h")
+
+if(NOT IS_DIRECTORY ${framework-dir})
+ message(SEND_ERROR "Framework not found at ${framework-dir}")
+endif()
+
+if(NOT EXISTS ${plist-file})
+ message(SEND_ERROR "plist file not found at ${plist-file}")
+endif()
+
+if(NOT EXISTS ${framework-library})
+ message(SEND_ERROR "Framework library not found at ${framework-library}")
+endif()
+
+if(NOT EXISTS ${framework-resource-file})
+ message(SEND_ERROR "Framework resource file not found at ${framework-resource-file}")
+endif()
+
+if(NOT EXISTS ${framework-versions})
+ message(SEND_ERROR "Framework versions not found at ${framework-versions}")
+endif()
+
+if(NOT EXISTS ${framework-resources})
+ message(SEND_ERROR "Framework Resources not found at ${framework-resources}")
+endif()
+
+if(NOT EXISTS ${framework-header})
+ message(SEND_ERROR "Framework header file not found at ${framework-header}")
+endif()
diff --git a/Tests/RunCMake/Framework/RunCMakeTest.cmake b/Tests/RunCMake/Framework/RunCMakeTest.cmake
new file mode 100644
index 000000000..d8102837b
--- /dev/null
+++ b/Tests/RunCMake/Framework/RunCMakeTest.cmake
@@ -0,0 +1,33 @@
+include(RunCMake)
+
+# iOS
+
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/iOSFrameworkLayout-build)
+set(RunCMake_TEST_NO_CLEAN 1)
+set(RunCMake_TEST_OPTIONS "-DCMAKE_TOOLCHAIN_FILE=${RunCMake_SOURCE_DIR}/ios.cmake")
+
+file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+run_cmake(FrameworkLayout)
+run_cmake_command(iOSFrameworkLayout-build ${CMAKE_COMMAND} --build .)
+
+unset(RunCMake_TEST_BINARY_DIR)
+unset(RunCMake_TEST_NO_CLEAN)
+unset(RunCMake_TEST_OPTIONS)
+
+# OSX
+
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/OSXFrameworkLayout-build)
+set(RunCMake_TEST_NO_CLEAN 1)
+set(RunCMake_TEST_OPTIONS "-DCMAKE_TOOLCHAIN_FILE=${RunCMake_SOURCE_DIR}/OSX.cmake")
+
+file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+run_cmake(FrameworkLayout)
+run_cmake_command(OSXFrameworkLayout-build ${CMAKE_COMMAND} --build .)
+
+unset(RunCMake_TEST_BINARY_DIR)
+unset(RunCMake_TEST_NO_CLEAN)
+unset(RunCMake_TEST_OPTIONS)
diff --git a/Tests/RunCMake/Framework/foo.c b/Tests/RunCMake/Framework/foo.c
new file mode 100644
index 000000000..bf7759e11
--- /dev/null
+++ b/Tests/RunCMake/Framework/foo.c
@@ -0,0 +1 @@
+int foo() { return 42; }
diff --git a/Tests/RunCMake/Framework/foo.h b/Tests/RunCMake/Framework/foo.h
new file mode 100644
index 000000000..5d5f8f0c9
--- /dev/null
+++ b/Tests/RunCMake/Framework/foo.h
@@ -0,0 +1 @@
+int foo();
diff --git a/Tests/RunCMake/Framework/iOSFrameworkLayout-build-check.cmake b/Tests/RunCMake/Framework/iOSFrameworkLayout-build-check.cmake
new file mode 100644
index 000000000..b81a5f732
--- /dev/null
+++ b/Tests/RunCMake/Framework/iOSFrameworkLayout-build-check.cmake
@@ -0,0 +1,35 @@
+set(framework-dir "${RunCMake_TEST_BINARY_DIR}/Framework.framework")
+set(framework-resources "${framework-dir}/Resources")
+set(framework-resource-file "${framework-dir}/res.txt")
+set(framework-library "${framework-dir}/Framework")
+set(framework-versions "${framework-dir}/Versions")
+set(plist-file "${framework-dir}/Info.plist")
+set(framework-header "${framework-dir}/Headers/foo.h")
+
+if(NOT IS_DIRECTORY ${framework-dir})
+ message(SEND_ERROR "Framework not found at ${framework-dir}")
+endif()
+
+if(NOT EXISTS ${plist-file})
+ message(SEND_ERROR "plist file not found at ${plist-file}")
+endif()
+
+if(NOT EXISTS ${framework-library})
+ message(SEND_ERROR "Framework library not found at ${framework-library}")
+endif()
+
+if(NOT EXISTS ${framework-resource-file})
+ message(SEND_ERROR "Framework resource file not found at ${framework-resource-file}")
+endif()
+
+if(EXISTS ${framework-versions})
+ message(SEND_ERROR "Framework versions found at ${framework-versions}")
+endif()
+
+if(EXISTS ${framework-resources})
+ message(SEND_ERROR "Framework Resources found at ${framework-resources}")
+endif()
+
+if(NOT EXISTS ${framework-header})
+ message(SEND_ERROR "Framework headers not found at ${framework-header}")
+endif()
diff --git a/Tests/RunCMake/Framework/ios.cmake b/Tests/RunCMake/Framework/ios.cmake
new file mode 100644
index 000000000..209a50d39
--- /dev/null
+++ b/Tests/RunCMake/Framework/ios.cmake
@@ -0,0 +1,25 @@
+set(CMAKE_SYSTEM_NAME Darwin)
+set(CMAKE_SYSTEM_VERSION 1)
+set(UNIX True)
+set(APPLE True)
+
+set(CMAKE_MACOSX_BUNDLE TRUE)
+set(CMAKE_CXX_COMPILER_WORKS TRUE)
+set(CMAKE_C_COMPILER_WORKS TRUE)
+set(CMAKE_CROSSCOMPILING TRUE)
+set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
+set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO")
+
+find_program(XCRUN_EXECUTABLE xcrun)
+if(NOT XCRUN_EXECUTABLE)
+ message(FATAL_ERROR "xcrun not found")
+endif()
+
+execute_process(
+ COMMAND ${XCRUN_EXECUTABLE} --sdk iphoneos --show-sdk-path
+ OUTPUT_VARIABLE IOS_SDK_PATH
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+set(CMAKE_OSX_SYSROOT ${IOS_SDK_PATH} CACHE PATH "Sysroot used for iOS support")
+set(CMAKE_OSX_ARCHITECTURES "armv7" CACHE STRING "Architectures to build for")
+set(CMAKE_FIND_ROOT_PATH ${IOS_SDK_PATH} CACHE PATH "Find search path root")
diff --git a/Tests/RunCMake/Framework/osx.cmake b/Tests/RunCMake/Framework/osx.cmake
new file mode 100644
index 000000000..e021fcd45
--- /dev/null
+++ b/Tests/RunCMake/Framework/osx.cmake
@@ -0,0 +1,18 @@
+set(CMAKE_SYSTEM_NAME Darwin)
+set(CMAKE_SYSTEM_VERSION 1)
+set(UNIX True)
+set(APPLE True)
+
+find_program(XCRUN_EXECUTABLE xcrun)
+if(NOT XCRUN_EXECUTABLE)
+ message(FATAL_ERROR "xcrun not found")
+endif()
+
+execute_process(
+ COMMAND ${XCRUN_EXECUTABLE} --sdk macosx --show-sdk-path
+ OUTPUT_VARIABLE OSX_SDK_PATH
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+set(CMAKE_OSX_SYSROOT ${OSX_SDK_PATH} CACHE PATH "Sysroot used for OSX support")
+
+set(CMAKE_FIND_ROOT_PATH ${OSX_SDK_PATH} CACHE PATH "Find search path root")
diff --git a/Tests/RunCMake/Framework/res.txt b/Tests/RunCMake/Framework/res.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/Framework/res.txt
diff --git a/Tests/RunCMake/GNUInstallDirs/CMakeLists.txt b/Tests/RunCMake/GNUInstallDirs/CMakeLists.txt
new file mode 100644
index 000000000..74b3ff8de
--- /dev/null
+++ b/Tests/RunCMake/GNUInstallDirs/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.3)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/GNUInstallDirs/Common.cmake b/Tests/RunCMake/GNUInstallDirs/Common.cmake
new file mode 100644
index 000000000..eff2d54b3
--- /dev/null
+++ b/Tests/RunCMake/GNUInstallDirs/Common.cmake
@@ -0,0 +1,28 @@
+set(CMAKE_SIZEOF_VOID_P 8)
+set(CMAKE_LIBRARY_ARCHITECTURE "arch")
+if(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
+ set(CMAKE_SYSTEM_NAME "OpenBSD-Fake")
+endif()
+include(GNUInstallDirs)
+set(dirs
+ BINDIR
+ DATADIR
+ DATAROOTDIR
+ DOCDIR
+ INCLUDEDIR
+ INFODIR
+ LIBDIR
+ LIBEXECDIR
+ LOCALEDIR
+ LOCALSTATEDIR
+ MANDIR
+ SBINDIR
+ SHAREDSTATEDIR
+ SYSCONFDIR
+ )
+foreach(dir ${dirs})
+ message("CMAKE_INSTALL_${dir}='${CMAKE_INSTALL_${dir}}'")
+endforeach()
+foreach(dir ${dirs})
+ message("CMAKE_INSTALL_FULL_${dir}='${CMAKE_INSTALL_FULL_${dir}}'")
+endforeach()
diff --git a/Tests/RunCMake/GNUInstallDirs/Opt-stderr.txt b/Tests/RunCMake/GNUInstallDirs/Opt-stderr.txt
new file mode 100644
index 000000000..aee8552c8
--- /dev/null
+++ b/Tests/RunCMake/GNUInstallDirs/Opt-stderr.txt
@@ -0,0 +1,28 @@
+^CMAKE_INSTALL_BINDIR='bin'
+CMAKE_INSTALL_DATADIR='share'
+CMAKE_INSTALL_DATAROOTDIR='share'
+CMAKE_INSTALL_DOCDIR='share/doc/Opt'
+CMAKE_INSTALL_INCLUDEDIR='include'
+CMAKE_INSTALL_INFODIR='share/info'
+CMAKE_INSTALL_LIBDIR='(lib|lib64)'
+CMAKE_INSTALL_LIBEXECDIR='libexec'
+CMAKE_INSTALL_LOCALEDIR='share/locale'
+CMAKE_INSTALL_LOCALSTATEDIR='var'
+CMAKE_INSTALL_MANDIR='share/man'
+CMAKE_INSTALL_SBINDIR='sbin'
+CMAKE_INSTALL_SHAREDSTATEDIR='com'
+CMAKE_INSTALL_SYSCONFDIR='etc'
+CMAKE_INSTALL_FULL_BINDIR='/opt/Opt/bin'
+CMAKE_INSTALL_FULL_DATADIR='/opt/Opt/share'
+CMAKE_INSTALL_FULL_DATAROOTDIR='/opt/Opt/share'
+CMAKE_INSTALL_FULL_DOCDIR='/opt/Opt/share/doc/Opt'
+CMAKE_INSTALL_FULL_INCLUDEDIR='/opt/Opt/include'
+CMAKE_INSTALL_FULL_INFODIR='/opt/Opt/share/info'
+CMAKE_INSTALL_FULL_LIBDIR='/opt/Opt/(lib|lib64)'
+CMAKE_INSTALL_FULL_LIBEXECDIR='/opt/Opt/libexec'
+CMAKE_INSTALL_FULL_LOCALEDIR='/opt/Opt/share/locale'
+CMAKE_INSTALL_FULL_LOCALSTATEDIR='/var/opt/Opt'
+CMAKE_INSTALL_FULL_MANDIR='/opt/Opt/share/man'
+CMAKE_INSTALL_FULL_SBINDIR='/opt/Opt/sbin'
+CMAKE_INSTALL_FULL_SHAREDSTATEDIR='/opt/Opt/com'
+CMAKE_INSTALL_FULL_SYSCONFDIR='/etc/opt/Opt'$
diff --git a/Tests/RunCMake/GNUInstallDirs/Opt.cmake b/Tests/RunCMake/GNUInstallDirs/Opt.cmake
new file mode 100644
index 000000000..49eab0e4e
--- /dev/null
+++ b/Tests/RunCMake/GNUInstallDirs/Opt.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_INSTALL_PREFIX "/opt/${PROJECT_NAME}")
+include(Common.cmake)
diff --git a/Tests/RunCMake/GNUInstallDirs/Root-stderr.txt b/Tests/RunCMake/GNUInstallDirs/Root-stderr.txt
new file mode 100644
index 000000000..a95400e86
--- /dev/null
+++ b/Tests/RunCMake/GNUInstallDirs/Root-stderr.txt
@@ -0,0 +1,28 @@
+^CMAKE_INSTALL_BINDIR='usr/bin'
+CMAKE_INSTALL_DATADIR='usr/share'
+CMAKE_INSTALL_DATAROOTDIR='usr/share'
+CMAKE_INSTALL_DOCDIR='usr/share/doc/Root'
+CMAKE_INSTALL_INCLUDEDIR='usr/include'
+CMAKE_INSTALL_INFODIR='usr/share/info'
+CMAKE_INSTALL_LIBDIR='usr/(lib|lib64)'
+CMAKE_INSTALL_LIBEXECDIR='usr/libexec'
+CMAKE_INSTALL_LOCALEDIR='usr/share/locale'
+CMAKE_INSTALL_LOCALSTATEDIR='var'
+CMAKE_INSTALL_MANDIR='usr/share/man'
+CMAKE_INSTALL_SBINDIR='usr/sbin'
+CMAKE_INSTALL_SHAREDSTATEDIR='usr/com'
+CMAKE_INSTALL_SYSCONFDIR='etc'
+CMAKE_INSTALL_FULL_BINDIR='/usr/bin'
+CMAKE_INSTALL_FULL_DATADIR='/usr/share'
+CMAKE_INSTALL_FULL_DATAROOTDIR='/usr/share'
+CMAKE_INSTALL_FULL_DOCDIR='/usr/share/doc/Root'
+CMAKE_INSTALL_FULL_INCLUDEDIR='/usr/include'
+CMAKE_INSTALL_FULL_INFODIR='/usr/share/info'
+CMAKE_INSTALL_FULL_LIBDIR='/usr/(lib|lib64)'
+CMAKE_INSTALL_FULL_LIBEXECDIR='/usr/libexec'
+CMAKE_INSTALL_FULL_LOCALEDIR='/usr/share/locale'
+CMAKE_INSTALL_FULL_LOCALSTATEDIR='/var'
+CMAKE_INSTALL_FULL_MANDIR='/usr/share/man'
+CMAKE_INSTALL_FULL_SBINDIR='/usr/sbin'
+CMAKE_INSTALL_FULL_SHAREDSTATEDIR='/usr/com'
+CMAKE_INSTALL_FULL_SYSCONFDIR='/etc'$
diff --git a/Tests/RunCMake/GNUInstallDirs/Root.cmake b/Tests/RunCMake/GNUInstallDirs/Root.cmake
new file mode 100644
index 000000000..f8cc6411b
--- /dev/null
+++ b/Tests/RunCMake/GNUInstallDirs/Root.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_INSTALL_PREFIX "/")
+include(Common.cmake)
diff --git a/Tests/RunCMake/GNUInstallDirs/RunCMakeTest.cmake b/Tests/RunCMake/GNUInstallDirs/RunCMakeTest.cmake
new file mode 100644
index 000000000..f88569a04
--- /dev/null
+++ b/Tests/RunCMake/GNUInstallDirs/RunCMakeTest.cmake
@@ -0,0 +1,6 @@
+include(RunCMake)
+
+run_cmake(Opt)
+run_cmake(Root)
+run_cmake(Usr)
+run_cmake(UsrLocal)
diff --git a/Tests/RunCMake/GNUInstallDirs/Usr-stderr.txt b/Tests/RunCMake/GNUInstallDirs/Usr-stderr.txt
new file mode 100644
index 000000000..e10c4c595
--- /dev/null
+++ b/Tests/RunCMake/GNUInstallDirs/Usr-stderr.txt
@@ -0,0 +1,28 @@
+^CMAKE_INSTALL_BINDIR='bin'
+CMAKE_INSTALL_DATADIR='share'
+CMAKE_INSTALL_DATAROOTDIR='share'
+CMAKE_INSTALL_DOCDIR='share/doc/Usr'
+CMAKE_INSTALL_INCLUDEDIR='include'
+CMAKE_INSTALL_INFODIR='share/info'
+CMAKE_INSTALL_LIBDIR='(lib|lib64|lib/arch)'
+CMAKE_INSTALL_LIBEXECDIR='libexec'
+CMAKE_INSTALL_LOCALEDIR='share/locale'
+CMAKE_INSTALL_LOCALSTATEDIR='var'
+CMAKE_INSTALL_MANDIR='share/man'
+CMAKE_INSTALL_SBINDIR='sbin'
+CMAKE_INSTALL_SHAREDSTATEDIR='com'
+CMAKE_INSTALL_SYSCONFDIR='etc'
+CMAKE_INSTALL_FULL_BINDIR='/usr/bin'
+CMAKE_INSTALL_FULL_DATADIR='/usr/share'
+CMAKE_INSTALL_FULL_DATAROOTDIR='/usr/share'
+CMAKE_INSTALL_FULL_DOCDIR='/usr/share/doc/Usr'
+CMAKE_INSTALL_FULL_INCLUDEDIR='/usr/include'
+CMAKE_INSTALL_FULL_INFODIR='/usr/share/info'
+CMAKE_INSTALL_FULL_LIBDIR='/usr/(lib|lib64|lib/arch)'
+CMAKE_INSTALL_FULL_LIBEXECDIR='/usr/libexec'
+CMAKE_INSTALL_FULL_LOCALEDIR='/usr/share/locale'
+CMAKE_INSTALL_FULL_LOCALSTATEDIR='/var'
+CMAKE_INSTALL_FULL_MANDIR='/usr/share/man'
+CMAKE_INSTALL_FULL_SBINDIR='/usr/sbin'
+CMAKE_INSTALL_FULL_SHAREDSTATEDIR='/usr/com'
+CMAKE_INSTALL_FULL_SYSCONFDIR='/etc'$
diff --git a/Tests/RunCMake/GNUInstallDirs/Usr.cmake b/Tests/RunCMake/GNUInstallDirs/Usr.cmake
new file mode 100644
index 000000000..62b728804
--- /dev/null
+++ b/Tests/RunCMake/GNUInstallDirs/Usr.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_INSTALL_PREFIX "/usr")
+include(Common.cmake)
diff --git a/Tests/RunCMake/GNUInstallDirs/UsrLocal-stderr.txt b/Tests/RunCMake/GNUInstallDirs/UsrLocal-stderr.txt
new file mode 100644
index 000000000..8dcf25b6e
--- /dev/null
+++ b/Tests/RunCMake/GNUInstallDirs/UsrLocal-stderr.txt
@@ -0,0 +1,28 @@
+^CMAKE_INSTALL_BINDIR='bin'
+CMAKE_INSTALL_DATADIR='share'
+CMAKE_INSTALL_DATAROOTDIR='share'
+CMAKE_INSTALL_DOCDIR='share/doc/UsrLocal'
+CMAKE_INSTALL_INCLUDEDIR='include'
+CMAKE_INSTALL_INFODIR='share/info'
+CMAKE_INSTALL_LIBDIR='(lib|lib64)'
+CMAKE_INSTALL_LIBEXECDIR='libexec'
+CMAKE_INSTALL_LOCALEDIR='share/locale'
+CMAKE_INSTALL_LOCALSTATEDIR='var'
+CMAKE_INSTALL_MANDIR='share/man'
+CMAKE_INSTALL_SBINDIR='sbin'
+CMAKE_INSTALL_SHAREDSTATEDIR='com'
+CMAKE_INSTALL_SYSCONFDIR='etc'
+CMAKE_INSTALL_FULL_BINDIR='/usr/local/bin'
+CMAKE_INSTALL_FULL_DATADIR='/usr/local/share'
+CMAKE_INSTALL_FULL_DATAROOTDIR='/usr/local/share'
+CMAKE_INSTALL_FULL_DOCDIR='/usr/local/share/doc/UsrLocal'
+CMAKE_INSTALL_FULL_INCLUDEDIR='/usr/local/include'
+CMAKE_INSTALL_FULL_INFODIR='/usr/local/share/info'
+CMAKE_INSTALL_FULL_LIBDIR='/usr/local/(lib|lib64)'
+CMAKE_INSTALL_FULL_LIBEXECDIR='/usr/local/libexec'
+CMAKE_INSTALL_FULL_LOCALEDIR='/usr/local/share/locale'
+CMAKE_INSTALL_FULL_LOCALSTATEDIR='/usr/local/var'
+CMAKE_INSTALL_FULL_MANDIR='/usr/local/share/man'
+CMAKE_INSTALL_FULL_SBINDIR='/usr/local/sbin'
+CMAKE_INSTALL_FULL_SHAREDSTATEDIR='/usr/local/com'
+CMAKE_INSTALL_FULL_SYSCONFDIR='/usr/local/etc'$
diff --git a/Tests/RunCMake/GNUInstallDirs/UsrLocal.cmake b/Tests/RunCMake/GNUInstallDirs/UsrLocal.cmake
new file mode 100644
index 000000000..59d933185
--- /dev/null
+++ b/Tests/RunCMake/GNUInstallDirs/UsrLocal.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_INSTALL_PREFIX "/usr/local")
+include(Common.cmake)
diff --git a/Tests/RunCMake/GeneratorExpression/BadCONFIG-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadCONFIG-stderr.txt
index 1cfbf404e..964ea4d4e 100644
--- a/Tests/RunCMake/GeneratorExpression/BadCONFIG-stderr.txt
+++ b/Tests/RunCMake/GeneratorExpression/BadCONFIG-stderr.txt
@@ -1,15 +1,6 @@
CMake Error at BadCONFIG.cmake:1 \(add_custom_target\):
Error evaluating generator expression:
- \$<CONFIG>
-
- \$<CONFIG> expression requires exactly one parameter.
-Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)
-+
-CMake Error at BadCONFIG.cmake:1 \(add_custom_target\):
- Error evaluating generator expression:
-
\$<CONFIG:.>
Expression syntax not recognized.
@@ -21,7 +12,7 @@ CMake Error at BadCONFIG.cmake:1 \(add_custom_target\):
\$<CONFIG:Foo,Bar>
- \$<CONFIG> expression requires exactly one parameter.
+ \$<CONFIG> expression requires one or zero parameters.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
diff --git a/Tests/RunCMake/GeneratorExpression/BadCONFIG.cmake b/Tests/RunCMake/GeneratorExpression/BadCONFIG.cmake
index c27ea5f73..5c22aaabe 100644
--- a/Tests/RunCMake/GeneratorExpression/BadCONFIG.cmake
+++ b/Tests/RunCMake/GeneratorExpression/BadCONFIG.cmake
@@ -1,5 +1,4 @@
add_custom_target(check ALL COMMAND check
- $<CONFIG>
$<CONFIG:.>
$<CONFIG:Foo,Bar>
$<CONFIG:Foo-Bar>
diff --git a/Tests/RunCMake/GeneratorExpression/BadSHELL_PATH-result.txt b/Tests/RunCMake/GeneratorExpression/BadSHELL_PATH-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/BadSHELL_PATH-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/BadSHELL_PATH-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadSHELL_PATH-stderr.txt
new file mode 100644
index 000000000..8d3c4ccd6
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/BadSHELL_PATH-stderr.txt
@@ -0,0 +1,17 @@
+CMake Error at BadSHELL_PATH.cmake:[0-9]+ \(add_custom_target\):
+ Error evaluating generator expression:
+
+ \$<SHELL_PATH:>
+
+ "" is not an absolute path.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at BadSHELL_PATH.cmake:[0-9]+ \(add_custom_target\):
+ Error evaluating generator expression:
+
+ \$<SHELL_PATH:Relative/Path>
+
+ "Relative/Path" is not an absolute path.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/BadSHELL_PATH.cmake b/Tests/RunCMake/GeneratorExpression/BadSHELL_PATH.cmake
new file mode 100644
index 000000000..5eff7bccb
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/BadSHELL_PATH.cmake
@@ -0,0 +1,4 @@
+add_custom_target(check ALL COMMAND check
+ $<SHELL_PATH:>
+ $<SHELL_PATH:Relative/Path>
+ VERBATIM)
diff --git a/Tests/RunCMake/GeneratorExpression/BadTargetTypeInterface-result.txt b/Tests/RunCMake/GeneratorExpression/BadTargetTypeInterface-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/BadTargetTypeInterface-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/BadTargetTypeInterface-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadTargetTypeInterface-stderr.txt
new file mode 100644
index 000000000..3aa457eee
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/BadTargetTypeInterface-stderr.txt
@@ -0,0 +1,26 @@
+CMake Error at BadTargetTypeInterface.cmake:[0-9]+ \(add_custom_target\):
+ Error evaluating generator expression:
+
+ \$<TARGET_FILE:iface>
+
+ Target "iface" is not an executable or library.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
++
+CMake Error at BadTargetTypeInterface.cmake:[0-9]+ \(add_custom_target\):
+ Error evaluating generator expression:
+
+ \$<TARGET_SONAME_FILE:iface>
+
+ Target "iface" is not an executable or library.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
++
+CMake Error at BadTargetTypeInterface.cmake:[0-9]+ \(add_custom_target\):
+ Error evaluating generator expression:
+
+ \$<TARGET_LINKER_FILE:iface>
+
+ Target "iface" is not an executable or library.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/BadTargetTypeInterface.cmake b/Tests/RunCMake/GeneratorExpression/BadTargetTypeInterface.cmake
new file mode 100644
index 000000000..19566f439
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/BadTargetTypeInterface.cmake
@@ -0,0 +1,6 @@
+add_library(iface INTERFACE)
+add_custom_target(check ALL COMMAND echo
+ $<TARGET_FILE:iface>
+ $<TARGET_SONAME_FILE:iface>
+ $<TARGET_LINKER_FILE:iface>
+ )
diff --git a/Tests/RunCMake/GeneratorExpression/CMP0044-WARN-result.txt b/Tests/RunCMake/GeneratorExpression/CMP0044-WARN-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/CMP0044-WARN-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/GeneratorExpression/CMP0044-WARN-stderr.txt b/Tests/RunCMake/GeneratorExpression/CMP0044-WARN-stderr.txt
new file mode 100644
index 000000000..2079c125c
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/CMP0044-WARN-stderr.txt
@@ -0,0 +1,7 @@
+CMake Warning \(dev\) at CMP0044-WARN.cmake:13 \(target_compile_definitions\):
+ Policy CMP0044 is not set: Case sensitive <LANG>_COMPILER_ID generator
+ expressions. Run "cmake --help-policy CMP0044" for policy details. Use
+ the cmake_policy command to set the policy and suppress this warning.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/GeneratorExpression/CMP0044-WARN.cmake b/Tests/RunCMake/GeneratorExpression/CMP0044-WARN.cmake
new file mode 100644
index 000000000..d5b85c936
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/CMP0044-WARN.cmake
@@ -0,0 +1,17 @@
+
+project(CMP0044-WARN)
+
+string(TOLOWER ${CMAKE_C_COMPILER_ID} lc_test)
+if (lc_test STREQUAL CMAKE_C_COMPILER_ID)
+ string(TOUPPER ${CMAKE_C_COMPILER_ID} lc_test)
+ if (lc_test STREQUAL CMAKE_C_COMPILER_ID)
+ message(SEND_ERROR "Try harder.")
+ endif()
+endif()
+
+add_library(cmp0044-check empty.c)
+target_compile_definitions(cmp0044-check
+ PRIVATE
+ Result=$<C_COMPILER_ID:${lc_test}>
+ Type_Is_${CMP0044_TYPE}
+)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-stderr.txt
new file mode 100644
index 000000000..789b4d09a
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error at COMPILE_LANGUAGE-add_custom_command.cmake:6 \(add_custom_command\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANGUAGE>
+
+ \$<COMPILE_LANGUAGE:...> may only be used to specify include directories
+ compile definitions, compile options and to evaluate components of the
+ file\(GENERATE\) command.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command.cmake
new file mode 100644
index 000000000..f4ba26153
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command.cmake
@@ -0,0 +1,8 @@
+
+enable_language(C)
+
+add_library(empty empty.c)
+
+add_custom_command(TARGET empty PRE_BUILD
+ COMMAND ${CMAKE_COMMAND} -E echo $<COMPILE_LANGUAGE>
+)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-stderr.txt
new file mode 100644
index 000000000..400fbc035
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error at COMPILE_LANGUAGE-add_custom_target.cmake:4 \(add_custom_target\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANGUAGE>
+
+ \$<COMPILE_LANGUAGE:...> may only be used to specify include directories
+ compile definitions, compile options and to evaluate components of the
+ file\(GENERATE\) command.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target.cmake
new file mode 100644
index 000000000..4102623f8
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target.cmake
@@ -0,0 +1,6 @@
+
+enable_language(C)
+
+add_custom_target(empty
+ COMMAND ${CMAKE_COMMAND} -E echo $<COMPILE_LANGUAGE>
+)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-stderr.txt
new file mode 100644
index 000000000..e45bb020e
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error at COMPILE_LANGUAGE-add_executable.cmake:4 \(add_executable\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANGUAGE>
+
+ \$<COMPILE_LANGUAGE:...> may only be used to specify include directories
+ compile definitions, compile options and to evaluate components of the
+ file\(GENERATE\) command.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable.cmake
new file mode 100644
index 000000000..5c2ff351c
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+
+add_executable(empty empty.$<COMPILE_LANGUAGE>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-stderr.txt
new file mode 100644
index 000000000..c9ee6fe2a
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error at COMPILE_LANGUAGE-add_library.cmake:4 \(add_library\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANGUAGE>
+
+ \$<COMPILE_LANGUAGE:...> may only be used to specify include directories
+ compile definitions, compile options and to evaluate components of the
+ file\(GENERATE\) command.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library.cmake
new file mode 100644
index 000000000..dd9f82403
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+
+add_library(empty empty.$<COMPILE_LANGUAGE>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-stderr.txt
new file mode 100644
index 000000000..9955f5d91
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error at COMPILE_LANGUAGE-add_test.cmake:5 \(add_test\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANGUAGE>
+
+ \$<COMPILE_LANGUAGE:...> may only be used to specify include directories
+ compile definitions, compile options and to evaluate components of the
+ file\(GENERATE\) command.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test.cmake
new file mode 100644
index 000000000..deedf659e
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test.cmake
@@ -0,0 +1,5 @@
+
+include(CTest)
+enable_testing()
+
+add_test(NAME dummy COMMAND ${CMAKE_COMMAND} -E echo $<COMPILE_LANGUAGE>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-stderr.txt
new file mode 100644
index 000000000..eca700f4d
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error:
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANGUAGE>
+
+ \$<COMPILE_LANGUAGE:...> may only be used to specify include directories
+ compile definitions, compile options and to evaluate components of the
+ file\(GENERATE\) command.
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install.cmake
new file mode 100644
index 000000000..92c20e32d
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install.cmake
@@ -0,0 +1,5 @@
+
+install(FILES
+ empty.$<COMPILE_LANGUAGE>
+ DESTINATION src
+)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-stderr.txt
new file mode 100644
index 000000000..2d324e2ac
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error at COMPILE_LANGUAGE-target_sources.cmake:5 \(target_sources\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANGUAGE>
+
+ \$<COMPILE_LANGUAGE:...> may only be used to specify include directories
+ compile definitions, compile options and to evaluate components of the
+ file\(GENERATE\) command.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources.cmake
new file mode 100644
index 000000000..0c78acd74
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources.cmake
@@ -0,0 +1,5 @@
+
+enable_language(C)
+
+add_library(empty empty.c)
+target_sources(empty PRIVATE empty.$<COMPILE_LANGUAGE>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-stderr.txt
new file mode 100644
index 000000000..444da45ef
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at COMPILE_LANGUAGE-unknown-lang.cmake:4 \(target_compile_options\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANGUAGE:CXX>
+
+ \$<COMPILE_LANGUAGE:...> Unknown language.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang.cmake
new file mode 100644
index 000000000..cec12a3fb
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_compile_options(empty PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-Wall>)
diff --git a/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE-result.txt b/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE-stderr.txt b/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE-stderr.txt
new file mode 100644
index 000000000..d915ecbbf
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at ImportedTarget-TARGET_PDB_FILE.cmake:2 \(add_custom_target\):
+ Error evaluating generator expression:
+
+ \$<TARGET_PDB_FILE:empty>
+
+ TARGET_PDB_FILE not allowed for IMPORTED targets.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE.cmake b/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE.cmake
new file mode 100644
index 000000000..c55c5d594
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE.cmake
@@ -0,0 +1,2 @@
+add_library(empty UNKNOWN IMPORTED)
+add_custom_target(custom COMMAND echo $<TARGET_PDB_FILE:empty>)
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidCompiler-TARGET_PDB_FILE-result.txt b/Tests/RunCMake/GeneratorExpression/NonValidCompiler-TARGET_PDB_FILE-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidCompiler-TARGET_PDB_FILE-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidCompiler-TARGET_PDB_FILE-stderr.txt b/Tests/RunCMake/GeneratorExpression/NonValidCompiler-TARGET_PDB_FILE-stderr.txt
new file mode 100644
index 000000000..831edadcf
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidCompiler-TARGET_PDB_FILE-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at NonValidCompiler-TARGET_PDB_FILE.cmake:6 \(file\):
+ Error evaluating generator expression:
+
+ \$<TARGET_PDB_FILE:empty>
+
+ TARGET_PDB_FILE is not supported by the target linker.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidCompiler-TARGET_PDB_FILE.cmake b/Tests/RunCMake/GeneratorExpression/NonValidCompiler-TARGET_PDB_FILE.cmake
new file mode 100644
index 000000000..84a2b2e8b
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidCompiler-TARGET_PDB_FILE.cmake
@@ -0,0 +1,9 @@
+
+enable_language(C)
+
+add_library(empty STATIC empty.c)
+
+file(GENERATE
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/test.txt"
+ CONTENT "[$<TARGET_PDB_FILE:empty>]"
+)
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-CXX_COMPILER_ID-result.txt b/Tests/RunCMake/GeneratorExpression/NonValidTarget-CXX_COMPILER_ID-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidTarget-CXX_COMPILER_ID-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-CXX_COMPILER_ID-stderr.txt b/Tests/RunCMake/GeneratorExpression/NonValidTarget-CXX_COMPILER_ID-stderr.txt
new file mode 100644
index 000000000..dd7a18304
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidTarget-CXX_COMPILER_ID-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at NonValidTarget-CXX_COMPILER_ID.cmake:4 \(add_custom_command\):
+ Error evaluating generator expression:
+
+ \$<CXX_COMPILER_ID>
+
+ \$<CXX_COMPILER_ID> may only be used with binary targets. It may not be
+ used with add_custom_command or add_custom_target.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-CXX_COMPILER_ID.cmake b/Tests/RunCMake/GeneratorExpression/NonValidTarget-CXX_COMPILER_ID.cmake
new file mode 100644
index 000000000..7dd38da4a
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidTarget-CXX_COMPILER_ID.cmake
@@ -0,0 +1,8 @@
+
+enable_language(CXX)
+
+add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/copied_file.cpp"
+ COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp" "${CMAKE_CURRENT_BINARY_DIR}/copied_file$<CXX_COMPILER_ID>.cpp"
+)
+
+add_library(empty "${CMAKE_CURRENT_BINARY_DIR}/copied_file.cpp")
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-CXX_COMPILER_VERSION-result.txt b/Tests/RunCMake/GeneratorExpression/NonValidTarget-CXX_COMPILER_VERSION-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidTarget-CXX_COMPILER_VERSION-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-CXX_COMPILER_VERSION-stderr.txt b/Tests/RunCMake/GeneratorExpression/NonValidTarget-CXX_COMPILER_VERSION-stderr.txt
new file mode 100644
index 000000000..d4a064af1
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidTarget-CXX_COMPILER_VERSION-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at NonValidTarget-CXX_COMPILER_VERSION.cmake:4 \(add_custom_command\):
+ Error evaluating generator expression:
+
+ \$<CXX_COMPILER_VERSION>
+
+ \$<CXX_COMPILER_VERSION> may only be used with binary targets. It may not
+ be used with add_custom_command or add_custom_target.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-CXX_COMPILER_VERSION.cmake b/Tests/RunCMake/GeneratorExpression/NonValidTarget-CXX_COMPILER_VERSION.cmake
new file mode 100644
index 000000000..1afb2b56f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidTarget-CXX_COMPILER_VERSION.cmake
@@ -0,0 +1,8 @@
+
+enable_language(CXX)
+
+add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/copied_file.cpp"
+ COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp" "${CMAKE_CURRENT_BINARY_DIR}/copied_file$<CXX_COMPILER_VERSION>.cpp"
+)
+
+add_library(empty "${CMAKE_CURRENT_BINARY_DIR}/copied_file.cpp")
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-C_COMPILER_ID-result.txt b/Tests/RunCMake/GeneratorExpression/NonValidTarget-C_COMPILER_ID-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidTarget-C_COMPILER_ID-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-C_COMPILER_ID-stderr.txt b/Tests/RunCMake/GeneratorExpression/NonValidTarget-C_COMPILER_ID-stderr.txt
new file mode 100644
index 000000000..b8e53ed91
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidTarget-C_COMPILER_ID-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at NonValidTarget-C_COMPILER_ID.cmake:4 \(add_custom_command\):
+ Error evaluating generator expression:
+
+ \$<C_COMPILER_ID>
+
+ \$<C_COMPILER_ID> may only be used with binary targets. It may not be used
+ with add_custom_command or add_custom_target.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-C_COMPILER_ID.cmake b/Tests/RunCMake/GeneratorExpression/NonValidTarget-C_COMPILER_ID.cmake
new file mode 100644
index 000000000..2d92ee39e
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidTarget-C_COMPILER_ID.cmake
@@ -0,0 +1,8 @@
+
+enable_language(CXX)
+
+add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/copied_file.cpp"
+ COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp" "${CMAKE_CURRENT_BINARY_DIR}/copied_file$<C_COMPILER_ID>.cpp"
+)
+
+add_library(empty "${CMAKE_CURRENT_BINARY_DIR}/copied_file.cpp")
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-C_COMPILER_VERSION-result.txt b/Tests/RunCMake/GeneratorExpression/NonValidTarget-C_COMPILER_VERSION-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidTarget-C_COMPILER_VERSION-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-C_COMPILER_VERSION-stderr.txt b/Tests/RunCMake/GeneratorExpression/NonValidTarget-C_COMPILER_VERSION-stderr.txt
new file mode 100644
index 000000000..551efe963
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidTarget-C_COMPILER_VERSION-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at NonValidTarget-C_COMPILER_VERSION.cmake:4 \(add_custom_command\):
+ Error evaluating generator expression:
+
+ \$<C_COMPILER_VERSION>
+
+ \$<C_COMPILER_VERSION> may only be used with binary targets. It may not be
+ used with add_custom_command or add_custom_target.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-C_COMPILER_VERSION.cmake b/Tests/RunCMake/GeneratorExpression/NonValidTarget-C_COMPILER_VERSION.cmake
new file mode 100644
index 000000000..9b8a53150
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidTarget-C_COMPILER_VERSION.cmake
@@ -0,0 +1,8 @@
+
+enable_language(CXX)
+
+add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/copied_file.cpp"
+ COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp" "${CMAKE_CURRENT_BINARY_DIR}/copied_file$<C_COMPILER_VERSION>.cpp"
+)
+
+add_library(empty "${CMAKE_CURRENT_BINARY_DIR}/copied_file.cpp")
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PDB_FILE-result.txt b/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PDB_FILE-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PDB_FILE-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PDB_FILE-stderr.txt b/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PDB_FILE-stderr.txt
new file mode 100644
index 000000000..e5f21e2e3
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PDB_FILE-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at NonValidTarget-TARGET_PDB_FILE.cmake:6 \(file\):
+ Error evaluating generator expression:
+
+ \$<TARGET_PDB_FILE:empty>
+
+ TARGET_PDB_FILE is allowed only for targets with linker created artifacts.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PDB_FILE.cmake b/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PDB_FILE.cmake
new file mode 100644
index 000000000..84a2b2e8b
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PDB_FILE.cmake
@@ -0,0 +1,9 @@
+
+enable_language(C)
+
+add_library(empty STATIC empty.c)
+
+file(GENERATE
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/test.txt"
+ CONTENT "[$<TARGET_PDB_FILE:empty>]"
+)
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_POLICY-result.txt b/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_POLICY-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_POLICY-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_POLICY-stderr.txt b/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_POLICY-stderr.txt
new file mode 100644
index 000000000..0e87538c6
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_POLICY-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at NonValidTarget-TARGET_POLICY.cmake:4 \(add_custom_command\):
+ Error evaluating generator expression:
+
+ \$<TARGET_POLICY:CMP0004>
+
+ \$<TARGET_POLICY:prop> may only be used with binary targets. It may not be
+ used with add_custom_command or add_custom_target.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_POLICY.cmake b/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_POLICY.cmake
new file mode 100644
index 000000000..10b37b5a4
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_POLICY.cmake
@@ -0,0 +1,8 @@
+
+enable_language(CXX)
+
+add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/copied_file.cpp"
+ COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp" "${CMAKE_CURRENT_BINARY_DIR}/copied_file$<TARGET_POLICY:CMP0004>.cpp"
+)
+
+add_library(empty "${CMAKE_CURRENT_BINARY_DIR}/copied_file.cpp")
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PROPERTY-result.txt b/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PROPERTY-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PROPERTY-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PROPERTY-stderr.txt b/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PROPERTY-stderr.txt
new file mode 100644
index 000000000..08ad3c2d8
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PROPERTY-stderr.txt
@@ -0,0 +1,11 @@
+CMake Error at NonValidTarget-TARGET_PROPERTY.cmake:4 \(add_custom_command\):
+ Error evaluating generator expression:
+
+ \$<TARGET_PROPERTY:NotAProperty>
+
+ \$<TARGET_PROPERTY:prop> may only be used with binary targets. It may not
+ be used with add_custom_command or add_custom_target. Specify the target
+ to read a property from using the \$<TARGET_PROPERTY:tgt,prop> signature
+ instead.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PROPERTY.cmake b/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PROPERTY.cmake
new file mode 100644
index 000000000..64abc5f90
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PROPERTY.cmake
@@ -0,0 +1,8 @@
+
+enable_language(CXX)
+
+add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/copied_file.cpp"
+ COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp" "${CMAKE_CURRENT_BINARY_DIR}/copied_file$<TARGET_PROPERTY:NotAProperty>.cpp"
+)
+
+add_library(empty "${CMAKE_CURRENT_BINARY_DIR}/copied_file.cpp")
diff --git a/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-result.txt b/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-stderr.txt b/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-stderr.txt
new file mode 100644
index 000000000..bf592e75c
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at OUTPUT_NAME-recursion.cmake:[0-9]+ \(add_executable\):
+ Target 'empty1' OUTPUT_NAME depends on itself.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion.cmake b/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion.cmake
new file mode 100644
index 000000000..5cb80509e
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+add_executable(empty1 empty.c)
+set_property(TARGET empty1 PROPERTY OUTPUT_NAME $<TARGET_FILE_NAME:empty1>)
diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
index 54d5064ce..45175d851 100644
--- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
@@ -7,5 +7,32 @@ run_cmake(BadNOT)
run_cmake(BadStrEqual)
run_cmake(BadZero)
run_cmake(BadTargetName)
+run_cmake(BadTargetTypeInterface)
run_cmake(BadTargetTypeObject)
run_cmake(BadInstallPrefix)
+run_cmake(BadSHELL_PATH)
+run_cmake(CMP0044-WARN)
+run_cmake(NonValidTarget-C_COMPILER_ID)
+run_cmake(NonValidTarget-CXX_COMPILER_ID)
+run_cmake(NonValidTarget-C_COMPILER_VERSION)
+run_cmake(NonValidTarget-CXX_COMPILER_VERSION)
+run_cmake(NonValidTarget-TARGET_PROPERTY)
+run_cmake(NonValidTarget-TARGET_POLICY)
+run_cmake(COMPILE_LANGUAGE-add_custom_target)
+run_cmake(COMPILE_LANGUAGE-add_custom_command)
+run_cmake(COMPILE_LANGUAGE-install)
+run_cmake(COMPILE_LANGUAGE-target_sources)
+run_cmake(COMPILE_LANGUAGE-add_executable)
+run_cmake(COMPILE_LANGUAGE-add_library)
+run_cmake(COMPILE_LANGUAGE-add_test)
+run_cmake(COMPILE_LANGUAGE-unknown-lang)
+run_cmake(TARGET_FILE-recursion)
+run_cmake(OUTPUT_NAME-recursion)
+
+run_cmake(ImportedTarget-TARGET_PDB_FILE)
+if(LINKER_SUPPORTS_PDB)
+ run_cmake(NonValidTarget-TARGET_PDB_FILE)
+ run_cmake(ValidTarget-TARGET_PDB_FILE)
+else()
+ run_cmake(NonValidCompiler-TARGET_PDB_FILE)
+endif()
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion-result.txt b/Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion-stderr.txt b/Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion-stderr.txt
new file mode 100644
index 000000000..5b15526e7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at TARGET_FILE-recursion.cmake:[0-9]+ \(add_executable\):
+ Target 'empty1' OUTPUT_DIRECTORY depends on itself.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion.cmake
new file mode 100644
index 000000000..e780103d9
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion.cmake
@@ -0,0 +1,4 @@
+enable_language(C)
+add_executable(empty1 empty.c)
+set_property(TARGET empty1 PROPERTY OUTPUT_NAME $<TARGET_FILE_NAME:empty1>)
+set_property(TARGET empty1 PROPERTY RUNTIME_OUTPUT_DIRECTORY $<TARGET_FILE_DIR:empty1>)
diff --git a/Tests/RunCMake/GeneratorExpression/ValidTarget-TARGET_PDB_FILE-check.cmake b/Tests/RunCMake/GeneratorExpression/ValidTarget-TARGET_PDB_FILE-check.cmake
new file mode 100644
index 000000000..2a588bcb7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/ValidTarget-TARGET_PDB_FILE-check.cmake
@@ -0,0 +1,17 @@
+file(STRINGS ${RunCMake_TEST_BINARY_DIR}/test.txt TEST_TXT ENCODING UTF-8)
+
+list(GET TEST_TXT 0 PDB_PATH)
+list(GET TEST_TXT 1 PDB_NAME)
+list(GET TEST_TXT 2 PDB_DIR)
+
+if(NOT PDB_PATH MATCHES "empty\\.pdb")
+ message(FATAL_ERROR "unexpected PDB_PATH [${PDB_PATH}]")
+endif()
+
+if(NOT PDB_NAME STREQUAL "empty.pdb")
+ message(FATAL_ERROR "unexpected PDB_NAME [${PDB_NAME}]")
+endif()
+
+if(PDB_DIR MATCHES "empty\\.pdb")
+ message(FATAL_ERROR "unexpected PDB_DIR [${PDB_DIR}]")
+endif()
diff --git a/Tests/RunCMake/GeneratorExpression/ValidTarget-TARGET_PDB_FILE.cmake b/Tests/RunCMake/GeneratorExpression/ValidTarget-TARGET_PDB_FILE.cmake
new file mode 100644
index 000000000..38e47f91f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/ValidTarget-TARGET_PDB_FILE.cmake
@@ -0,0 +1,19 @@
+
+enable_language(C)
+
+add_library(empty SHARED empty.c)
+
+if(CMAKE_CONFIGURATION_TYPES)
+ list(GET CMAKE_CONFIGURATION_TYPES 0 FIRST_CONFIG)
+ set(GENERATE_CONDITION CONDITION $<CONFIG:${FIRST_CONFIG}>)
+endif()
+
+file(GENERATE
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/test.txt"
+ CONTENT
+[[$<TARGET_PDB_FILE:empty>
+$<TARGET_PDB_FILE_NAME:empty>
+$<TARGET_PDB_FILE_DIR:empty>
+]]
+ ${GENERATE_CONDITION}
+)
diff --git a/Tests/RunCMake/GeneratorPlatform/BadPlatform-result.txt b/Tests/RunCMake/GeneratorPlatform/BadPlatform-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorPlatform/BadPlatform-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorPlatform/BadPlatform-stderr.txt b/Tests/RunCMake/GeneratorPlatform/BadPlatform-stderr.txt
new file mode 100644
index 000000000..e31571451
--- /dev/null
+++ b/Tests/RunCMake/GeneratorPlatform/BadPlatform-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error at CMakeLists.txt:[0-9]+ \(project\):
+ Generator
+
+ .*
+
+ does not support platform specification, but platform
+
+ Bad Platform
+
+ was specified.$
diff --git a/Tests/RunCMake/GeneratorPlatform/BadPlatform-toolchain.cmake b/Tests/RunCMake/GeneratorPlatform/BadPlatform-toolchain.cmake
new file mode 100644
index 000000000..1c544b0d4
--- /dev/null
+++ b/Tests/RunCMake/GeneratorPlatform/BadPlatform-toolchain.cmake
@@ -0,0 +1 @@
+set(CMAKE_GENERATOR_PLATFORM "Bad Platform")
diff --git a/Tests/RunCMake/GeneratorPlatform/BadPlatform.cmake b/Tests/RunCMake/GeneratorPlatform/BadPlatform.cmake
new file mode 100644
index 000000000..2fc38e5c5
--- /dev/null
+++ b/Tests/RunCMake/GeneratorPlatform/BadPlatform.cmake
@@ -0,0 +1 @@
+message(FATAL_ERROR "This should not be reached!")
diff --git a/Tests/RunCMake/GeneratorPlatform/BadPlatformToolchain-result.txt b/Tests/RunCMake/GeneratorPlatform/BadPlatformToolchain-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorPlatform/BadPlatformToolchain-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorPlatform/BadPlatformToolchain-stderr.txt b/Tests/RunCMake/GeneratorPlatform/BadPlatformToolchain-stderr.txt
new file mode 100644
index 000000000..e31571451
--- /dev/null
+++ b/Tests/RunCMake/GeneratorPlatform/BadPlatformToolchain-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error at CMakeLists.txt:[0-9]+ \(project\):
+ Generator
+
+ .*
+
+ does not support platform specification, but platform
+
+ Bad Platform
+
+ was specified.$
diff --git a/Tests/RunCMake/GeneratorPlatform/BadPlatformToolchain.cmake b/Tests/RunCMake/GeneratorPlatform/BadPlatformToolchain.cmake
new file mode 100644
index 000000000..2fc38e5c5
--- /dev/null
+++ b/Tests/RunCMake/GeneratorPlatform/BadPlatformToolchain.cmake
@@ -0,0 +1 @@
+message(FATAL_ERROR "This should not be reached!")
diff --git a/Tests/RunCMake/GeneratorPlatform/CMakeLists.txt b/Tests/RunCMake/GeneratorPlatform/CMakeLists.txt
new file mode 100644
index 000000000..12cd3c775
--- /dev/null
+++ b/Tests/RunCMake/GeneratorPlatform/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/GeneratorPlatform/NoPlatform-result.txt b/Tests/RunCMake/GeneratorPlatform/NoPlatform-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorPlatform/NoPlatform-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorPlatform/NoPlatform-stderr.txt b/Tests/RunCMake/GeneratorPlatform/NoPlatform-stderr.txt
new file mode 100644
index 000000000..e1c0da4c5
--- /dev/null
+++ b/Tests/RunCMake/GeneratorPlatform/NoPlatform-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at NoPlatform.cmake:2 \(message\):
+ CMAKE_GENERATOR_PLATFORM is empty as expected.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorPlatform/NoPlatform.cmake b/Tests/RunCMake/GeneratorPlatform/NoPlatform.cmake
new file mode 100644
index 000000000..1e0ca6deb
--- /dev/null
+++ b/Tests/RunCMake/GeneratorPlatform/NoPlatform.cmake
@@ -0,0 +1,7 @@
+if("x${CMAKE_GENERATOR_PLATFORM}" STREQUAL "x")
+ message(FATAL_ERROR "CMAKE_GENERATOR_PLATFORM is empty as expected.")
+else()
+ message(FATAL_ERROR
+ "CMAKE_GENERATOR_PLATFORM is \"${CMAKE_GENERATOR_PLATFORM}\" "
+ "but should be empty!")
+endif()
diff --git a/Tests/RunCMake/GeneratorPlatform/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorPlatform/RunCMakeTest.cmake
new file mode 100644
index 000000000..4d0a0a1a1
--- /dev/null
+++ b/Tests/RunCMake/GeneratorPlatform/RunCMakeTest.cmake
@@ -0,0 +1,28 @@
+include(RunCMake)
+
+set(RunCMake_GENERATOR_PLATFORM "")
+run_cmake(NoPlatform)
+
+if("${RunCMake_GENERATOR}" MATCHES "^Visual Studio ([89]|1[0124])( 20[0-9][0-9])?$")
+ set(RunCMake_GENERATOR_PLATFORM "x64")
+ run_cmake(x64Platform)
+else()
+ set(RunCMake_GENERATOR_PLATFORM "Bad Platform")
+ run_cmake(BadPlatform)
+endif()
+
+set(RunCMake_GENERATOR_TOOLSET "")
+
+set(RunCMake_TEST_OPTIONS -A "Extra Platform")
+run_cmake(TwoPlatforms)
+unset(RunCMake_TEST_OPTIONS)
+
+if("${RunCMake_GENERATOR}" MATCHES "^Visual Studio ([89]|1[0124])( 20[0-9][0-9])?$")
+ set(RunCMake_TEST_OPTIONS -DCMAKE_TOOLCHAIN_FILE=${RunCMake_SOURCE_DIR}/TestPlatform-toolchain.cmake)
+ run_cmake(TestPlatformToolchain)
+ unset(RunCMake_TEST_OPTIONS)
+else()
+ set(RunCMake_TEST_OPTIONS -DCMAKE_TOOLCHAIN_FILE=${RunCMake_SOURCE_DIR}/BadPlatform-toolchain.cmake)
+ run_cmake(BadPlatformToolchain)
+ unset(RunCMake_TEST_OPTIONS)
+endif()
diff --git a/Tests/RunCMake/GeneratorPlatform/TestPlatform-toolchain.cmake b/Tests/RunCMake/GeneratorPlatform/TestPlatform-toolchain.cmake
new file mode 100644
index 000000000..763478cc5
--- /dev/null
+++ b/Tests/RunCMake/GeneratorPlatform/TestPlatform-toolchain.cmake
@@ -0,0 +1 @@
+set(CMAKE_GENERATOR_PLATFORM "Test Platform")
diff --git a/Tests/RunCMake/GeneratorPlatform/TestPlatformToolchain-result.txt b/Tests/RunCMake/GeneratorPlatform/TestPlatformToolchain-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorPlatform/TestPlatformToolchain-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorPlatform/TestPlatformToolchain-stderr.txt b/Tests/RunCMake/GeneratorPlatform/TestPlatformToolchain-stderr.txt
new file mode 100644
index 000000000..b9bb3b231
--- /dev/null
+++ b/Tests/RunCMake/GeneratorPlatform/TestPlatformToolchain-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at TestPlatformToolchain.cmake:[0-9]+ \(message\):
+ CMAKE_GENERATOR_PLATFORM is "Test Platform" as expected.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at TestPlatformToolchain.cmake:[0-9]+ \(message\):
+ CMAKE_VS_PLATFORM_NAME is "Test Platform" as expected.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorPlatform/TestPlatformToolchain.cmake b/Tests/RunCMake/GeneratorPlatform/TestPlatformToolchain.cmake
new file mode 100644
index 000000000..c4430a598
--- /dev/null
+++ b/Tests/RunCMake/GeneratorPlatform/TestPlatformToolchain.cmake
@@ -0,0 +1,16 @@
+if("x${CMAKE_GENERATOR_PLATFORM}" STREQUAL "xTest Platform")
+ message(SEND_ERROR "CMAKE_GENERATOR_PLATFORM is \"Test Platform\" as expected.")
+else()
+ message(FATAL_ERROR
+ "CMAKE_GENERATOR_PLATFORM is \"${CMAKE_GENERATOR_PLATFORM}\" "
+ "but should be \"Test Platform\"!")
+endif()
+if(CMAKE_GENERATOR MATCHES "Visual Studio")
+ if("x${CMAKE_VS_PLATFORM_NAME}" STREQUAL "xTest Platform")
+ message(SEND_ERROR "CMAKE_VS_PLATFORM_NAME is \"Test Platform\" as expected.")
+ else()
+ message(FATAL_ERROR
+ "CMAKE_VS_PLATFORM_NAME is \"${CMAKE_VS_PLATFORM_NAME}\" "
+ "but should be \"Test Platform\"!")
+ endif()
+endif()
diff --git a/Tests/RunCMake/GeneratorPlatform/TwoPlatforms-result.txt b/Tests/RunCMake/GeneratorPlatform/TwoPlatforms-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorPlatform/TwoPlatforms-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorPlatform/TwoPlatforms-stderr.txt b/Tests/RunCMake/GeneratorPlatform/TwoPlatforms-stderr.txt
new file mode 100644
index 000000000..90e4ecad8
--- /dev/null
+++ b/Tests/RunCMake/GeneratorPlatform/TwoPlatforms-stderr.txt
@@ -0,0 +1 @@
+CMake Error: Multiple -A options not allowed
diff --git a/Tests/RunCMake/GeneratorPlatform/TwoPlatforms.cmake b/Tests/RunCMake/GeneratorPlatform/TwoPlatforms.cmake
new file mode 100644
index 000000000..2fc38e5c5
--- /dev/null
+++ b/Tests/RunCMake/GeneratorPlatform/TwoPlatforms.cmake
@@ -0,0 +1 @@
+message(FATAL_ERROR "This should not be reached!")
diff --git a/Tests/RunCMake/GeneratorPlatform/x64Platform-stdout.txt b/Tests/RunCMake/GeneratorPlatform/x64Platform-stdout.txt
new file mode 100644
index 000000000..05a83ff7c
--- /dev/null
+++ b/Tests/RunCMake/GeneratorPlatform/x64Platform-stdout.txt
@@ -0,0 +1,2 @@
+-- CMAKE_GENERATOR_PLATFORM is 'x64' as expected.
+-- CMAKE_VS_PLATFORM_NAME is 'x64' as expected.
diff --git a/Tests/RunCMake/GeneratorPlatform/x64Platform.cmake b/Tests/RunCMake/GeneratorPlatform/x64Platform.cmake
new file mode 100644
index 000000000..a23bdc74b
--- /dev/null
+++ b/Tests/RunCMake/GeneratorPlatform/x64Platform.cmake
@@ -0,0 +1,7 @@
+foreach(v CMAKE_GENERATOR_PLATFORM CMAKE_VS_PLATFORM_NAME)
+ if("x${${v}}" STREQUAL "xx64")
+ message(STATUS "${v} is 'x64' as expected.")
+ else()
+ message(FATAL_ERROR "${v} is '${${v}}' but should be 'x64'!")
+ endif()
+endforeach()
diff --git a/Tests/RunCMake/GeneratorToolset/BadToolset-stderr.txt b/Tests/RunCMake/GeneratorToolset/BadToolset-stderr.txt
index bf1f19018..d0d526c68 100644
--- a/Tests/RunCMake/GeneratorToolset/BadToolset-stderr.txt
+++ b/Tests/RunCMake/GeneratorToolset/BadToolset-stderr.txt
@@ -1,4 +1,4 @@
-CMake Error:
+CMake Error at CMakeLists.txt:[0-9]+ \(project\):
Generator
.*
diff --git a/Tests/RunCMake/GeneratorToolset/BadToolset-toolchain.cmake b/Tests/RunCMake/GeneratorToolset/BadToolset-toolchain.cmake
new file mode 100644
index 000000000..7bbf32757
--- /dev/null
+++ b/Tests/RunCMake/GeneratorToolset/BadToolset-toolchain.cmake
@@ -0,0 +1 @@
+set(CMAKE_GENERATOR_TOOLSET "Bad Toolset")
diff --git a/Tests/RunCMake/GeneratorToolset/BadToolsetToolchain-result.txt b/Tests/RunCMake/GeneratorToolset/BadToolsetToolchain-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorToolset/BadToolsetToolchain-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorToolset/BadToolsetToolchain-stderr.txt b/Tests/RunCMake/GeneratorToolset/BadToolsetToolchain-stderr.txt
new file mode 100644
index 000000000..d0d526c68
--- /dev/null
+++ b/Tests/RunCMake/GeneratorToolset/BadToolsetToolchain-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error at CMakeLists.txt:[0-9]+ \(project\):
+ Generator
+
+ .*
+
+ does not support toolset specification, but toolset
+
+ Bad Toolset
+
+ was specified.$
diff --git a/Tests/RunCMake/GeneratorToolset/BadToolsetToolchain.cmake b/Tests/RunCMake/GeneratorToolset/BadToolsetToolchain.cmake
new file mode 100644
index 000000000..2fc38e5c5
--- /dev/null
+++ b/Tests/RunCMake/GeneratorToolset/BadToolsetToolchain.cmake
@@ -0,0 +1 @@
+message(FATAL_ERROR "This should not be reached!")
diff --git a/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake
index 1ccc1adb2..62206575c 100644
--- a/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake
@@ -3,7 +3,7 @@ include(RunCMake)
set(RunCMake_GENERATOR_TOOLSET "")
run_cmake(NoToolset)
-if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[012]|Xcode" AND NOT XCODE_BELOW_3)
+if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[0124]|Xcode" AND NOT XCODE_BELOW_3)
set(RunCMake_GENERATOR_TOOLSET "Test Toolset")
run_cmake(TestToolset)
else()
@@ -12,6 +12,17 @@ else()
endif()
set(RunCMake_GENERATOR_TOOLSET "")
+
set(RunCMake_TEST_OPTIONS -T "Extra Toolset")
run_cmake(TwoToolsets)
unset(RunCMake_TEST_OPTIONS)
+
+if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[0124]|Xcode" AND NOT XCODE_BELOW_3)
+ set(RunCMake_TEST_OPTIONS -DCMAKE_TOOLCHAIN_FILE=${RunCMake_SOURCE_DIR}/TestToolset-toolchain.cmake)
+ run_cmake(TestToolsetToolchain)
+ unset(RunCMake_TEST_OPTIONS)
+else()
+ set(RunCMake_TEST_OPTIONS -DCMAKE_TOOLCHAIN_FILE=${RunCMake_SOURCE_DIR}/BadToolset-toolchain.cmake)
+ run_cmake(BadToolsetToolchain)
+ unset(RunCMake_TEST_OPTIONS)
+endif()
diff --git a/Tests/RunCMake/GeneratorToolset/TestToolset-toolchain.cmake b/Tests/RunCMake/GeneratorToolset/TestToolset-toolchain.cmake
new file mode 100644
index 000000000..bee2ae4bb
--- /dev/null
+++ b/Tests/RunCMake/GeneratorToolset/TestToolset-toolchain.cmake
@@ -0,0 +1 @@
+set(CMAKE_GENERATOR_TOOLSET "Test Toolset")
diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetToolchain-result.txt b/Tests/RunCMake/GeneratorToolset/TestToolsetToolchain-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorToolset/TestToolsetToolchain-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetToolchain-stderr.txt b/Tests/RunCMake/GeneratorToolset/TestToolsetToolchain-stderr.txt
new file mode 100644
index 000000000..0623e90c7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorToolset/TestToolsetToolchain-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at TestToolsetToolchain.cmake:[0-9]+ \(message\):
+ CMAKE_GENERATOR_TOOLSET is "Test Toolset" as expected.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at TestToolsetToolchain.cmake:[0-9]+ \(message\):
+ CMAKE_(VS|XCODE)_PLATFORM_TOOLSET is "Test Toolset" as expected.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetToolchain.cmake b/Tests/RunCMake/GeneratorToolset/TestToolsetToolchain.cmake
new file mode 100644
index 000000000..7c1c41518
--- /dev/null
+++ b/Tests/RunCMake/GeneratorToolset/TestToolsetToolchain.cmake
@@ -0,0 +1,25 @@
+if("x${CMAKE_GENERATOR_TOOLSET}" STREQUAL "xTest Toolset")
+ message(SEND_ERROR "CMAKE_GENERATOR_TOOLSET is \"Test Toolset\" as expected.")
+else()
+ message(FATAL_ERROR
+ "CMAKE_GENERATOR_TOOLSET is \"${CMAKE_GENERATOR_TOOLSET}\" "
+ "but should be \"Test Toolset\"!")
+endif()
+if(CMAKE_GENERATOR MATCHES "Visual Studio")
+ if("x${CMAKE_VS_PLATFORM_TOOLSET}" STREQUAL "xTest Toolset")
+ message(SEND_ERROR "CMAKE_VS_PLATFORM_TOOLSET is \"Test Toolset\" as expected.")
+ else()
+ message(FATAL_ERROR
+ "CMAKE_VS_PLATFORM_TOOLSET is \"${CMAKE_VS_PLATFORM_TOOLSET}\" "
+ "but should be \"Test Toolset\"!")
+ endif()
+endif()
+if(CMAKE_GENERATOR MATCHES "Xcode")
+ if("x${CMAKE_XCODE_PLATFORM_TOOLSET}" STREQUAL "xTest Toolset")
+ message(SEND_ERROR "CMAKE_XCODE_PLATFORM_TOOLSET is \"Test Toolset\" as expected.")
+ else()
+ message(FATAL_ERROR
+ "CMAKE_XCODE_PLATFORM_TOOLSET is \"${CMAKE_XCODE_PLATFORM_TOOLSET}\" "
+ "but should be \"Test Toolset\"!")
+ endif()
+endif()
diff --git a/Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-NEW-result.txt b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-NEW-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-NEW-stderr_INCLUDE_DIRECTORIES.txt b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-NEW-stderr_INCLUDE_DIRECTORIES.txt
new file mode 100644
index 000000000..f2d749b68
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-NEW-stderr_INCLUDE_DIRECTORIES.txt
@@ -0,0 +1,6 @@
+CMake Error in CMakeLists.txt:
+ Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains path:
+
+ ".*Tests/RunCMake/IfacePaths_INCLUDE_DIRECTORIES/prefix/BinInInstallPrefix-CMP0052-NEW-build/foo"
+
+ which is prefixed in the build directory.
diff --git a/Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-OLD-result.txt b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-OLD-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-OLD-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-WARN-result.txt b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-WARN-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-WARN-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-WARN-stderr_INCLUDE_DIRECTORIES.txt b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-WARN-stderr_INCLUDE_DIRECTORIES.txt
new file mode 100644
index 000000000..3d838926c
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-WARN-stderr_INCLUDE_DIRECTORIES.txt
@@ -0,0 +1,20 @@
+CMake Warning \(dev\) in CMakeLists.txt:
+ Policy CMP0052 is not set: Reject source and build dirs in installed
+ INTERFACE_INCLUDE_DIRECTORIES. Run "cmake --help-policy CMP0052" for
+ policy details. Use the cmake_policy command to set the policy and
+ suppress this warning.
+
+ Directory:
+
+ ".*Tests/RunCMake/IfacePaths_INCLUDE_DIRECTORIES/prefix/BinInInstallPrefix-CMP0052-WARN-build/foo"
+
+ in INTERFACE_INCLUDE_DIRECTORIES of target "testTarget" is a subdirectory
+ of the install directory:
+
+ ".*Tests/RunCMake/IfacePaths_INCLUDE_DIRECTORIES/prefix"
+
+ however it is also a subdirectory of the build tree:
+
+ ".*Tests/RunCMake/IfacePaths_INCLUDE_DIRECTORIES/prefix/BinInInstallPrefix-CMP0052-WARN-build"
+
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/IfacePaths/BinInInstallPrefix-result.txt b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/IfacePaths/BinInInstallPrefix-stderr_SOURCES.txt b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-stderr_SOURCES.txt
new file mode 100644
index 000000000..239c0698b
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-stderr_SOURCES.txt
@@ -0,0 +1,6 @@
+CMake Error in CMakeLists.txt:
+ Target "testTarget" INTERFACE_SOURCES property contains path:
+
+ ".*Tests/RunCMake/IfacePaths_SOURCES/prefix/BinInInstallPrefix-build/empty.cpp"
+
+ which is prefixed in the build directory.
diff --git a/Tests/RunCMake/IfacePaths/BinaryDirectoryInInterface-result.txt b/Tests/RunCMake/IfacePaths/BinaryDirectoryInInterface-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/BinaryDirectoryInInterface-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/IfacePaths/BinaryDirectoryInInterface-stderr_INCLUDE_DIRECTORIES.txt b/Tests/RunCMake/IfacePaths/BinaryDirectoryInInterface-stderr_INCLUDE_DIRECTORIES.txt
new file mode 100644
index 000000000..ed7cd58e3
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/BinaryDirectoryInInterface-stderr_INCLUDE_DIRECTORIES.txt
@@ -0,0 +1,6 @@
+CMake Error in CMakeLists.txt:
+ Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains path:
+
+ ".*RunCMake/IfacePaths_INCLUDE_DIRECTORIES/BinaryDirectoryInInterface-build/foo"
+
+ which is prefixed in the build directory.
diff --git a/Tests/RunCMake/IfacePaths/BinaryDirectoryInInterface-stderr_SOURCES.txt b/Tests/RunCMake/IfacePaths/BinaryDirectoryInInterface-stderr_SOURCES.txt
new file mode 100644
index 000000000..e931a0142
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/BinaryDirectoryInInterface-stderr_SOURCES.txt
@@ -0,0 +1,6 @@
+CMake Error in CMakeLists.txt:
+ Target "testTarget" INTERFACE_SOURCES property contains path:
+
+ ".*Tests/RunCMake/IfacePaths_SOURCES/BinaryDirectoryInInterface-build/empty.cpp"
+
+ which is prefixed in the build directory.
diff --git a/Tests/RunCMake/IfacePaths/BinaryDirectoryInInterface.cmake b/Tests/RunCMake/IfacePaths/BinaryDirectoryInInterface.cmake
new file mode 100644
index 000000000..7001f3f63
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/BinaryDirectoryInInterface.cmake
@@ -0,0 +1,15 @@
+
+enable_language(CXX)
+
+add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
+if (TEST_PROP STREQUAL INCLUDE_DIRECTORIES)
+ set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/foo")
+else()
+ set_property(TARGET testTarget PROPERTY INTERFACE_SOURCES "${CMAKE_CURRENT_BINARY_DIR}/empty.cpp")
+endif()
+
+install(TARGETS testTarget EXPORT testTargets
+ DESTINATION lib
+)
+
+install(EXPORT testTargets DESTINATION lib/cmake)
diff --git a/Tests/RunCMake/IfacePaths/CMakeLists.txt b/Tests/RunCMake/IfacePaths/CMakeLists.txt
new file mode 100644
index 000000000..5cd4825e6
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/CMakeLists.txt
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 3.0)
+project(${RunCMake_TEST} NONE)
+if(NOT TEST_FILE)
+ set(TEST_FILE ${RunCMake_TEST}.cmake)
+endif()
+include(${TEST_FILE})
diff --git a/Tests/RunCMake/IfacePaths/DirInInstallPrefix-result.txt b/Tests/RunCMake/IfacePaths/DirInInstallPrefix-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/DirInInstallPrefix-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/IfacePaths/DirInInstallPrefix.cmake b/Tests/RunCMake/IfacePaths/DirInInstallPrefix.cmake
new file mode 100644
index 000000000..f5f30050e
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/DirInInstallPrefix.cmake
@@ -0,0 +1,14 @@
+enable_language(CXX)
+add_library(testTarget empty.cpp)
+
+if (TEST_PROP STREQUAL INCLUDE_DIRECTORIES)
+ set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/dir")
+else()
+ set_property(TARGET testTarget PROPERTY INTERFACE_SOURCES "${CMAKE_INSTALL_PREFIX}/empty.cpp")
+endif()
+
+install(TARGETS testTarget EXPORT testTargets
+ DESTINATION lib
+)
+
+install(EXPORT testTargets DESTINATION lib/cmake)
diff --git a/Tests/RunCMake/IfacePaths/InstallInBinDir-result.txt b/Tests/RunCMake/IfacePaths/InstallInBinDir-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/InstallInBinDir-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/IfacePaths/InstallInBinDir-stderr_INCLUDE_DIRECTORIES.txt b/Tests/RunCMake/IfacePaths/InstallInBinDir-stderr_INCLUDE_DIRECTORIES.txt
new file mode 100644
index 000000000..3d60831d1
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/InstallInBinDir-stderr_INCLUDE_DIRECTORIES.txt
@@ -0,0 +1,6 @@
+CMake Error in CMakeLists.txt:
+ Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains path:
+
+ ".*Tests/RunCMake/IfacePaths_INCLUDE_DIRECTORIES/InstallInBinDir-build/foo"
+
+ which is prefixed in the build directory.
diff --git a/Tests/RunCMake/IfacePaths/InstallInBinDir-stderr_SOURCES.txt b/Tests/RunCMake/IfacePaths/InstallInBinDir-stderr_SOURCES.txt
new file mode 100644
index 000000000..c79d59828
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/InstallInBinDir-stderr_SOURCES.txt
@@ -0,0 +1,6 @@
+CMake Error in CMakeLists.txt:
+ Target "testTarget" INTERFACE_SOURCES property contains path:
+
+ ".*Tests/RunCMake/IfacePaths_SOURCES/InstallInBinDir-build/empty.cpp"
+
+ which is prefixed in the build directory.
diff --git a/Tests/RunCMake/IfacePaths/InstallInSrcDir-result.txt b/Tests/RunCMake/IfacePaths/InstallInSrcDir-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/InstallInSrcDir-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/IfacePaths/InstallInSrcDir-stderr_INCLUDE_DIRECTORIES.txt b/Tests/RunCMake/IfacePaths/InstallInSrcDir-stderr_INCLUDE_DIRECTORIES.txt
new file mode 100644
index 000000000..11994ddb3
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/InstallInSrcDir-stderr_INCLUDE_DIRECTORIES.txt
@@ -0,0 +1,6 @@
+CMake Error in CMakeLists.txt:
+ Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains path:
+
+ ".*Tests/RunCMake/IfacePaths_INCLUDE_DIRECTORIES/copy/foo"
+
+ which is prefixed in the source directory.
diff --git a/Tests/RunCMake/IfacePaths/InstallInSrcDir-stderr_SOURCES.txt b/Tests/RunCMake/IfacePaths/InstallInSrcDir-stderr_SOURCES.txt
new file mode 100644
index 000000000..e71921e6c
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/InstallInSrcDir-stderr_SOURCES.txt
@@ -0,0 +1,6 @@
+CMake Error in CMakeLists.txt:
+ Target "testTarget" INTERFACE_SOURCES property contains path:
+
+ ".*Tests/RunCMake/IfacePaths_SOURCES/copy/empty.cpp"
+
+ which is prefixed in the source directory.
diff --git a/Tests/RunCMake/IfacePaths/InstallPrefixInInterface-result.txt b/Tests/RunCMake/IfacePaths/InstallPrefixInInterface-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/InstallPrefixInInterface-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/IfacePaths/InstallPrefixInInterface.cmake b/Tests/RunCMake/IfacePaths/InstallPrefixInInterface.cmake
new file mode 100644
index 000000000..8d777f53c
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/InstallPrefixInInterface.cmake
@@ -0,0 +1,11 @@
+
+enable_language(CXX)
+
+add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
+target_include_directories(testTarget INTERFACE "${CMAKE_INSTALL_PREFIX}/foo")
+
+install(TARGETS testTarget EXPORT testTargets
+ DESTINATION lib
+)
+
+install(EXPORT testTargets DESTINATION lib/cmake)
diff --git a/Tests/RunCMake/IfacePaths/InstallToPrefixInSrcDirInSource-result.txt b/Tests/RunCMake/IfacePaths/InstallToPrefixInSrcDirInSource-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/InstallToPrefixInSrcDirInSource-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/IfacePaths/InstallToPrefixInSrcDirOutOfSource-result.txt b/Tests/RunCMake/IfacePaths/InstallToPrefixInSrcDirOutOfSource-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/InstallToPrefixInSrcDirOutOfSource-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/IfacePaths/RelativePathInGenex-result.txt b/Tests/RunCMake/IfacePaths/RelativePathInGenex-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/RelativePathInGenex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/include_directories/RelativePathInGenex-stderr.txt b/Tests/RunCMake/IfacePaths/RelativePathInGenex-stderr_INCLUDE_DIRECTORIES.txt
index 490c700f8..490c700f8 100644
--- a/Tests/RunCMake/include_directories/RelativePathInGenex-stderr.txt
+++ b/Tests/RunCMake/IfacePaths/RelativePathInGenex-stderr_INCLUDE_DIRECTORIES.txt
diff --git a/Tests/RunCMake/IfacePaths/RelativePathInGenex-stderr_SOURCES.txt b/Tests/RunCMake/IfacePaths/RelativePathInGenex-stderr_SOURCES.txt
new file mode 100644
index 000000000..2311af9e3
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/RelativePathInGenex-stderr_SOURCES.txt
@@ -0,0 +1,4 @@
+CMake Error in CMakeLists.txt:
+ Target "testTarget" contains relative path in its INTERFACE_SOURCES:
+
+ "empty.cpp"
diff --git a/Tests/RunCMake/IfacePaths/RelativePathInGenex.cmake b/Tests/RunCMake/IfacePaths/RelativePathInGenex.cmake
new file mode 100644
index 000000000..489c3a1c1
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/RelativePathInGenex.cmake
@@ -0,0 +1,13 @@
+
+enable_language(CXX)
+
+add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
+
+if (TEST_PROP STREQUAL INCLUDE_DIRECTORIES)
+ set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<1:foo>")
+else()
+ set_property(TARGET testTarget PROPERTY INTERFACE_SOURCES "$<1:empty.cpp>")
+endif()
+
+add_library(userTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
+target_link_libraries(userTarget testTarget)
diff --git a/Tests/RunCMake/IfacePaths/RelativePathInInterface-result.txt b/Tests/RunCMake/IfacePaths/RelativePathInInterface-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/RelativePathInInterface-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/include_directories/RelativePathInInterface-stderr.txt b/Tests/RunCMake/IfacePaths/RelativePathInInterface-stderr_INCLUDE_DIRECTORIES.txt
index f6cdb532e..f6cdb532e 100644
--- a/Tests/RunCMake/include_directories/RelativePathInInterface-stderr.txt
+++ b/Tests/RunCMake/IfacePaths/RelativePathInInterface-stderr_INCLUDE_DIRECTORIES.txt
diff --git a/Tests/RunCMake/IfacePaths/RelativePathInInterface-stderr_SOURCES.txt b/Tests/RunCMake/IfacePaths/RelativePathInInterface-stderr_SOURCES.txt
new file mode 100644
index 000000000..f0f002c7c
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/RelativePathInInterface-stderr_SOURCES.txt
@@ -0,0 +1,4 @@
+CMake Error in CMakeLists.txt:
+ Target "testTarget" INTERFACE_SOURCES property contains relative path:
+
+ "empty.cpp"
diff --git a/Tests/RunCMake/IfacePaths/RelativePathInInterface.cmake b/Tests/RunCMake/IfacePaths/RelativePathInInterface.cmake
new file mode 100644
index 000000000..e974aaca1
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/RelativePathInInterface.cmake
@@ -0,0 +1,14 @@
+
+enable_language(CXX)
+
+add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
+if (TEST_PROP STREQUAL INCLUDE_DIRECTORIES)
+ set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "foo")
+else()
+ set_property(TARGET testTarget PROPERTY INTERFACE_SOURCES "empty.cpp")
+endif()
+install(TARGETS testTarget EXPORT testTargets
+ DESTINATION lib
+)
+
+install(EXPORT testTargets DESTINATION lib/cmake)
diff --git a/Tests/RunCMake/IfacePaths/RunCMakeTest.cmake b/Tests/RunCMake/IfacePaths/RunCMakeTest.cmake
new file mode 100644
index 000000000..066c83e63
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/RunCMakeTest.cmake
@@ -0,0 +1,159 @@
+include(RunCMake)
+
+macro(run_cmake test)
+ list(APPEND RunCMake_TEST_OPTIONS -DTEST_PROP=${TEST_PROP})
+ set(RunCMake-stderr-file ${test}-stderr_${TEST_PROP}.txt)
+ _run_cmake(${test})
+endmacro()
+
+# Protect tests from running inside the default install prefix.
+set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/NotDefaultPrefix")
+
+run_cmake(RelativePathInInterface)
+run_cmake(RelativePathInGenex)
+run_cmake(export-NOWARN)
+run_cmake(SourceDirectoryInInterface)
+run_cmake(BinaryDirectoryInInterface)
+
+set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/DirInInstallPrefix/prefix")
+run_cmake(DirInInstallPrefix)
+
+configure_file(
+ "${RunCMake_SOURCE_DIR}/CMakeLists.txt"
+ "${RunCMake_BINARY_DIR}/copy/CMakeLists.txt"
+ COPYONLY
+)
+configure_file(
+ "${RunCMake_SOURCE_DIR}/empty.cpp"
+ "${RunCMake_BINARY_DIR}/copy/empty.cpp"
+ COPYONLY
+)
+configure_file(
+ "${RunCMake_SOURCE_DIR}/SourceDirectoryInInterface.cmake"
+ "${RunCMake_BINARY_DIR}/copy/SourceDirectoryInInterface.cmake"
+ COPYONLY
+)
+set(RunCMake_TEST_OPTIONS
+ "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/copy/SourceDirectoryInInterface/prefix"
+ "-DTEST_FILE=${RunCMake_BINARY_DIR}/copy/SourceDirectoryInInterface.cmake"
+ )
+set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/copy")
+run_cmake(InstallInSrcDir)
+unset(RunCMake_TEST_SOURCE_DIR)
+
+set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/InstallInBinDir-build/prefix")
+set(RunCMake_TEST_OPTIONS
+ "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/InstallInBinDir-build/prefix"
+ "-DTEST_FILE=${RunCMake_SOURCE_DIR}/BinaryDirectoryInInterface.cmake"
+ )
+set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/InstallInBinDir-build")
+run_cmake(InstallInBinDir)
+unset(RunCMake_TEST_BINARY_DIR)
+
+configure_file(
+ "${RunCMake_SOURCE_DIR}/CMakeLists.txt"
+ "${RunCMake_BINARY_DIR}/prefix/src/CMakeLists.txt"
+ COPYONLY
+)
+configure_file(
+ "${RunCMake_SOURCE_DIR}/empty.cpp"
+ "${RunCMake_BINARY_DIR}/prefix/src/empty.cpp"
+ COPYONLY
+)
+configure_file(
+ "${RunCMake_SOURCE_DIR}/SourceDirectoryInInterface.cmake"
+ "${RunCMake_BINARY_DIR}/prefix/src/SourceDirectoryInInterface.cmake"
+ COPYONLY
+)
+
+foreach(policyStatus NEW OLD "")
+ if (TEST_PROP STREQUAL INCLUDE_DIRECTORIES)
+ if (NOT "${policyStatus}" STREQUAL "")
+ set(policyOption -DCMAKE_POLICY_DEFAULT_CMP0052=${policyStatus})
+ else()
+ unset(policyOption)
+ set(policyStatus WARN)
+ endif()
+ set(policySuffix -CMP0052-${policyStatus})
+ endif()
+ set(RunCMake_TEST_OPTIONS
+ "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/prefix" ${policyOption}
+ "-DTEST_FILE=${RunCMake_SOURCE_DIR}/BinaryDirectoryInInterface.cmake"
+ )
+ # Set the RunCMake_TEST_SOURCE_DIR here to the copy too. This is needed to run
+ # the test suite in-source properly. Otherwise the install directory would be
+ # a subdirectory or the source directory, which is allowed and tested separately
+ # below.
+ set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/prefix/src")
+ set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/prefix/BinInInstallPrefix${policySuffix}-build")
+ run_cmake(BinInInstallPrefix${policySuffix})
+ unset(RunCMake_TEST_BINARY_DIR)
+
+ set(RunCMake_TEST_OPTIONS
+ "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/prefix" ${policyOption}
+ "-DTEST_FILE=${RunCMake_BINARY_DIR}/prefix/src/SourceDirectoryInInterface.cmake"
+ )
+ run_cmake(SrcInInstallPrefix${policySuffix})
+ unset(RunCMake_TEST_SOURCE_DIR)
+
+ if (NOT TEST_PROP STREQUAL INCLUDE_DIRECTORIES)
+ break()
+ endif()
+endforeach()
+
+set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/InstallPrefixInInterface-build/prefix")
+run_cmake(InstallPrefixInInterface)
+
+configure_file(
+ "${RunCMake_SOURCE_DIR}/CMakeLists.txt"
+ "${RunCMake_BINARY_DIR}/installToSrc/CMakeLists.txt"
+ COPYONLY
+)
+configure_file(
+ "${RunCMake_SOURCE_DIR}/empty.cpp"
+ "${RunCMake_BINARY_DIR}/installToSrc/empty.cpp"
+ COPYONLY
+)
+configure_file(
+ "${RunCMake_SOURCE_DIR}/InstallPrefixInInterface.cmake"
+ "${RunCMake_BINARY_DIR}/installToSrc/InstallPrefixInInterface.cmake"
+ COPYONLY
+)
+set(RunCMake_TEST_OPTIONS
+ "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/installToSrc/InstallPrefixInInterface/prefix"
+ "-DTEST_FILE=${RunCMake_BINARY_DIR}/installToSrc/InstallPrefixInInterface.cmake"
+ )
+set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/installToSrc")
+run_cmake(InstallToPrefixInSrcDirOutOfSource)
+unset(RunCMake_TEST_SOURCE_DIR)
+
+
+file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}/installToSrcInSrc")
+set(RunCMake_TEST_NO_CLEAN ON)
+
+configure_file(
+ "${RunCMake_SOURCE_DIR}/CMakeLists.txt"
+ "${RunCMake_BINARY_DIR}/installToSrcInSrc/CMakeLists.txt"
+ COPYONLY
+)
+configure_file(
+ "${RunCMake_SOURCE_DIR}/empty.cpp"
+ "${RunCMake_BINARY_DIR}/installToSrcInSrc/empty.cpp"
+ COPYONLY
+)
+configure_file(
+ "${RunCMake_SOURCE_DIR}/InstallPrefixInInterface.cmake"
+ "${RunCMake_BINARY_DIR}/installToSrcInSrc/InstallPrefixInInterface.cmake"
+ COPYONLY
+)
+
+set(RunCMake_TEST_OPTIONS
+ "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/installToSrcInSrc/InstallPrefixInInterface/prefix"
+ "-DTEST_FILE=${RunCMake_BINARY_DIR}/installToSrcInSrc/InstallPrefixInInterface.cmake"
+ )
+set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/installToSrcInSrc")
+set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/installToSrcInSrc")
+run_cmake(InstallToPrefixInSrcDirInSource)
+unset(RunCMake_TEST_SOURCE_DIR)
+unset(RunCMake_TEST_BINARY_DIR)
+unset(RunCMake_TEST_NO_CLEAN)
diff --git a/Tests/RunCMake/IfacePaths/SourceDirectoryInInterface-result.txt b/Tests/RunCMake/IfacePaths/SourceDirectoryInInterface-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/SourceDirectoryInInterface-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/IfacePaths/SourceDirectoryInInterface-stderr_INCLUDE_DIRECTORIES.txt b/Tests/RunCMake/IfacePaths/SourceDirectoryInInterface-stderr_INCLUDE_DIRECTORIES.txt
new file mode 100644
index 000000000..97a94b15f
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/SourceDirectoryInInterface-stderr_INCLUDE_DIRECTORIES.txt
@@ -0,0 +1,6 @@
+CMake Error in CMakeLists.txt:
+ Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains path:
+
+ ".*RunCMake/IfacePaths/foo"
+
+ which is prefixed in the source directory.
diff --git a/Tests/RunCMake/IfacePaths/SourceDirectoryInInterface-stderr_SOURCES.txt b/Tests/RunCMake/IfacePaths/SourceDirectoryInInterface-stderr_SOURCES.txt
new file mode 100644
index 000000000..c5157ad3a
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/SourceDirectoryInInterface-stderr_SOURCES.txt
@@ -0,0 +1,6 @@
+CMake Error in CMakeLists.txt:
+ Target "testTarget" INTERFACE_SOURCES property contains path:
+
+ ".*Tests/RunCMake/IfacePaths/empty.cpp"
+
+ which is prefixed in the source directory.
diff --git a/Tests/RunCMake/IfacePaths/SourceDirectoryInInterface.cmake b/Tests/RunCMake/IfacePaths/SourceDirectoryInInterface.cmake
new file mode 100644
index 000000000..d80cbec85
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/SourceDirectoryInInterface.cmake
@@ -0,0 +1,15 @@
+
+enable_language(CXX)
+
+add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
+if (TEST_PROP STREQUAL INCLUDE_DIRECTORIES)
+ set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/foo")
+else()
+ set_property(TARGET testTarget PROPERTY INTERFACE_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
+endif()
+
+install(TARGETS testTarget EXPORT testTargets
+ DESTINATION lib
+)
+
+install(EXPORT testTargets DESTINATION lib/cmake)
diff --git a/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-NEW-result.txt b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-NEW-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-NEW-stderr_INCLUDE_DIRECTORIES.txt b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-NEW-stderr_INCLUDE_DIRECTORIES.txt
new file mode 100644
index 000000000..ed5df34a4
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-NEW-stderr_INCLUDE_DIRECTORIES.txt
@@ -0,0 +1,6 @@
+CMake Error in CMakeLists.txt:
+ Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains path:
+
+ ".*Tests/RunCMake/IfacePaths_INCLUDE_DIRECTORIES/prefix/src/foo"
+
+ which is prefixed in the source directory.
diff --git a/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-OLD-result.txt b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-OLD-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-OLD-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-WARN-result.txt b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-WARN-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-WARN-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-WARN-stderr_INCLUDE_DIRECTORIES.txt b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-WARN-stderr_INCLUDE_DIRECTORIES.txt
new file mode 100644
index 000000000..cb5a51ccb
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-WARN-stderr_INCLUDE_DIRECTORIES.txt
@@ -0,0 +1,20 @@
+CMake Warning \(dev\) in CMakeLists.txt:
+ Policy CMP0052 is not set: Reject source and build dirs in installed
+ INTERFACE_INCLUDE_DIRECTORIES. Run "cmake --help-policy CMP0052" for
+ policy details. Use the cmake_policy command to set the policy and
+ suppress this warning.
+
+ Directory:
+
+ ".*Tests/RunCMake/IfacePaths_INCLUDE_DIRECTORIES/prefix/src/foo"
+
+ in INTERFACE_INCLUDE_DIRECTORIES of target "testTarget" is a subdirectory
+ of the install directory:
+
+ ".*Tests/RunCMake/IfacePaths_INCLUDE_DIRECTORIES/prefix"
+
+ however it is also a subdirectory of the source tree:
+
+ ".*Tests/RunCMake/IfacePaths_INCLUDE_DIRECTORIES/prefix/src"
+
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-result.txt b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-stderr_SOURCES.txt b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-stderr_SOURCES.txt
new file mode 100644
index 000000000..48f248584
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-stderr_SOURCES.txt
@@ -0,0 +1,6 @@
+CMake Error in CMakeLists.txt:
+ Target "testTarget" INTERFACE_SOURCES property contains path:
+
+ ".*Tests/RunCMake/IfacePaths_SOURCES/prefix/src/empty.cpp"
+
+ which is prefixed in the source directory.
diff --git a/Tests/RunCMake/IfacePaths/empty.cpp b/Tests/RunCMake/IfacePaths/empty.cpp
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/empty.cpp
diff --git a/Tests/RunCMake/IfacePaths/export-NOWARN-result.txt b/Tests/RunCMake/IfacePaths/export-NOWARN-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/export-NOWARN-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/IfacePaths/export-NOWARN.cmake b/Tests/RunCMake/IfacePaths/export-NOWARN.cmake
new file mode 100644
index 000000000..592572cc2
--- /dev/null
+++ b/Tests/RunCMake/IfacePaths/export-NOWARN.cmake
@@ -0,0 +1,77 @@
+enable_language(CXX)
+add_library(foo empty.cpp)
+
+set_property(TARGET foo APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<0:>/include/subdir)
+set_property(TARGET foo APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<INSTALL_PREFIX>/include/subdir)
+set_property(TARGET foo APPEND PROPERTY INTERFACE_SOURCES $<0:>/include/subdir/empty.cpp)
+set_property(TARGET foo APPEND PROPERTY INTERFACE_SOURCES $<INSTALL_PREFIX>/include/subdir/empty.cpp)
+
+set_property(TARGET foo APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/subdir>)
+set_property(TARGET foo APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<INSTALL_INTERFACE:include/subdir>)
+set_property(TARGET foo APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<INSTALL_INTERFACE:include/$<0:>>)
+set_property(TARGET foo APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<INSTALL_INTERFACE:$<0:>/include>)
+set_property(TARGET foo APPEND PROPERTY INTERFACE_SOURCES $<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/subdir/empty.cpp>)
+set_property(TARGET foo APPEND PROPERTY INTERFACE_SOURCES $<INSTALL_INTERFACE:include/subdir/empty.cpp>)
+set_property(TARGET foo APPEND PROPERTY INTERFACE_SOURCES $<INSTALL_INTERFACE:include/subdir/empty.cpp$<0:>>)
+set_property(TARGET foo APPEND PROPERTY INTERFACE_SOURCES $<INSTALL_INTERFACE:$<0:>/include/subdir/empty.cpp>)
+
+# target_include_directories(foo INTERFACE include/subdir) # Does and should warn. INSTALL_INTERFACE must not list src dir paths.
+target_include_directories(foo INTERFACE $<0:>/include/subdir) # Does not and should not should warn, because it starts with a genex.
+target_include_directories(foo INTERFACE $<INSTALL_PREFIX>/include/subdir)
+target_sources(foo INTERFACE $<0:>/include/subdir/empty.cpp)
+target_sources(foo INTERFACE $<INSTALL_PREFIX>/include/subdir/empty.cpp)
+
+target_include_directories(foo INTERFACE $<INSTALL_INTERFACE:include/subdir>)
+target_include_directories(foo INTERFACE $<INSTALL_INTERFACE:include/$<0:>>)
+target_sources(foo INTERFACE $<INSTALL_INTERFACE:include/subdir/empty.cpp>)
+target_sources(foo INTERFACE $<INSTALL_INTERFACE:include/subdir/empty.cpp$<0:>>)
+
+install(FILES include/subdir/empty.cpp
+ DESTINATION include/subdir
+)
+
+install(TARGETS foo EXPORT FooTargets DESTINATION lib)
+install(EXPORT FooTargets DESTINATION lib/cmake)
+
+install(TARGETS foo EXPORT FooTargets2
+ DESTINATION lib
+ INCLUDES DESTINATION include # No warning. Implicit install prefix.
+)
+install(EXPORT FooTargets2 DESTINATION lib/cmake)
+
+install(TARGETS foo EXPORT FooTargets3
+ DESTINATION lib
+ INCLUDES DESTINATION $<INSTALL_PREFIX>include
+)
+install(EXPORT FooTargets3 DESTINATION lib/cmake)
+
+install(TARGETS foo EXPORT FooTargets4
+ DESTINATION lib
+ INCLUDES DESTINATION $<INSTALL_INTERFACE:include>
+)
+install(EXPORT FooTargets4 DESTINATION lib/cmake)
+
+install(TARGETS foo EXPORT FooTargets5
+ DESTINATION lib
+ # The $<0:> is evaluated at export time, leaving 'include' behind, which should be treated as above.
+ INCLUDES DESTINATION $<INSTALL_INTERFACE:$<0:>include>
+)
+install(EXPORT FooTargets5 DESTINATION lib/cmake)
+
+install(TARGETS foo EXPORT FooTargets6
+ DESTINATION lib
+ INCLUDES DESTINATION $<INSTALL_INTERFACE:include$<0:>>
+)
+install(EXPORT FooTargets6 DESTINATION lib/cmake)
+
+install(TARGETS foo EXPORT FooTargets7
+ DESTINATION lib
+ INCLUDES DESTINATION include$<0:>
+)
+install(EXPORT FooTargets7 DESTINATION lib/cmake)
+
+install(TARGETS foo EXPORT FooTargets8
+ DESTINATION lib
+ INCLUDES DESTINATION $<0:>include
+)
+install(EXPORT FooTargets8 DESTINATION lib/cmake)
diff --git a/Tests/RunCMake/IncludeWhatYouUse/C-Build-stdout.txt b/Tests/RunCMake/IncludeWhatYouUse/C-Build-stdout.txt
new file mode 100644
index 000000000..cb7467705
--- /dev/null
+++ b/Tests/RunCMake/IncludeWhatYouUse/C-Build-stdout.txt
@@ -0,0 +1,4 @@
+Warning: include-what-you-use reported diagnostics:
+should add these lines:
+*
+#include <\.\.\.>
diff --git a/Tests/RunCMake/IncludeWhatYouUse/C-launch-Build-stdout.txt b/Tests/RunCMake/IncludeWhatYouUse/C-launch-Build-stdout.txt
new file mode 100644
index 000000000..cb7467705
--- /dev/null
+++ b/Tests/RunCMake/IncludeWhatYouUse/C-launch-Build-stdout.txt
@@ -0,0 +1,4 @@
+Warning: include-what-you-use reported diagnostics:
+should add these lines:
+*
+#include <\.\.\.>
diff --git a/Tests/RunCMake/IncludeWhatYouUse/C-launch.cmake b/Tests/RunCMake/IncludeWhatYouUse/C-launch.cmake
new file mode 100644
index 000000000..e66ca203e
--- /dev/null
+++ b/Tests/RunCMake/IncludeWhatYouUse/C-launch.cmake
@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(C.cmake)
diff --git a/Tests/RunCMake/IncludeWhatYouUse/C.cmake b/Tests/RunCMake/IncludeWhatYouUse/C.cmake
new file mode 100644
index 000000000..f400e861f
--- /dev/null
+++ b/Tests/RunCMake/IncludeWhatYouUse/C.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+set(CMAKE_C_INCLUDE_WHAT_YOU_USE "${PSEUDO_IWYU}" -some -args)
+add_executable(main main.c)
diff --git a/Tests/RunCMake/IncludeWhatYouUse/CMakeLists.txt b/Tests/RunCMake/IncludeWhatYouUse/CMakeLists.txt
new file mode 100644
index 000000000..18dfd2686
--- /dev/null
+++ b/Tests/RunCMake/IncludeWhatYouUse/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.2)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/IncludeWhatYouUse/CXX-Build-stdout.txt b/Tests/RunCMake/IncludeWhatYouUse/CXX-Build-stdout.txt
new file mode 100644
index 000000000..cb7467705
--- /dev/null
+++ b/Tests/RunCMake/IncludeWhatYouUse/CXX-Build-stdout.txt
@@ -0,0 +1,4 @@
+Warning: include-what-you-use reported diagnostics:
+should add these lines:
+*
+#include <\.\.\.>
diff --git a/Tests/RunCMake/IncludeWhatYouUse/CXX-launch-Build-stdout.txt b/Tests/RunCMake/IncludeWhatYouUse/CXX-launch-Build-stdout.txt
new file mode 100644
index 000000000..cb7467705
--- /dev/null
+++ b/Tests/RunCMake/IncludeWhatYouUse/CXX-launch-Build-stdout.txt
@@ -0,0 +1,4 @@
+Warning: include-what-you-use reported diagnostics:
+should add these lines:
+*
+#include <\.\.\.>
diff --git a/Tests/RunCMake/IncludeWhatYouUse/CXX-launch.cmake b/Tests/RunCMake/IncludeWhatYouUse/CXX-launch.cmake
new file mode 100644
index 000000000..3002c9d68
--- /dev/null
+++ b/Tests/RunCMake/IncludeWhatYouUse/CXX-launch.cmake
@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(CXX.cmake)
diff --git a/Tests/RunCMake/IncludeWhatYouUse/CXX.cmake b/Tests/RunCMake/IncludeWhatYouUse/CXX.cmake
new file mode 100644
index 000000000..896930c16
--- /dev/null
+++ b/Tests/RunCMake/IncludeWhatYouUse/CXX.cmake
@@ -0,0 +1,3 @@
+enable_language(CXX)
+set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "${PSEUDO_IWYU}" -some -args)
+add_executable(main main.cxx)
diff --git a/Tests/RunCMake/IncludeWhatYouUse/RunCMakeTest.cmake b/Tests/RunCMake/IncludeWhatYouUse/RunCMakeTest.cmake
new file mode 100644
index 000000000..8f99eb104
--- /dev/null
+++ b/Tests/RunCMake/IncludeWhatYouUse/RunCMakeTest.cmake
@@ -0,0 +1,22 @@
+include(RunCMake)
+
+set(RunCMake_TEST_OPTIONS "-DPSEUDO_IWYU=${PSEUDO_IWYU}")
+
+function(run_iwyu lang)
+ # Use a single build tree for tests without cleaning.
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${lang}-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ run_cmake(${lang})
+
+ set(RunCMake_TEST_OUTPUT_MERGE 1)
+ run_cmake_command(${lang}-Build ${CMAKE_COMMAND} --build .)
+endfunction()
+
+run_iwyu(C)
+run_iwyu(CXX)
+if (NOT RunCMake_GENERATOR STREQUAL "Watcom WMake")
+ run_iwyu(C-launch)
+ run_iwyu(CXX-launch)
+endif()
diff --git a/Tests/RunCMake/IncludeWhatYouUse/main.c b/Tests/RunCMake/IncludeWhatYouUse/main.c
new file mode 100644
index 000000000..78f2de106
--- /dev/null
+++ b/Tests/RunCMake/IncludeWhatYouUse/main.c
@@ -0,0 +1 @@
+int main(void) { return 0; }
diff --git a/Tests/RunCMake/IncludeWhatYouUse/main.cxx b/Tests/RunCMake/IncludeWhatYouUse/main.cxx
new file mode 100644
index 000000000..76e819701
--- /dev/null
+++ b/Tests/RunCMake/IncludeWhatYouUse/main.cxx
@@ -0,0 +1 @@
+int main() { return 0; }
diff --git a/Tests/RunCMake/Languages/CMakeLists.txt b/Tests/RunCMake/Languages/CMakeLists.txt
index 12cd3c775..8996fef6b 100644
--- a/Tests/RunCMake/Languages/CMakeLists.txt
+++ b/Tests/RunCMake/Languages/CMakeLists.txt
@@ -1,3 +1,4 @@
cmake_minimum_required(VERSION 2.8.4)
+cmake_policy(SET CMP0042 NEW)
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/Languages/DetermineFail-result.txt b/Tests/RunCMake/Languages/DetermineFail-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Languages/DetermineFail-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Languages/DetermineFail-stderr.txt b/Tests/RunCMake/Languages/DetermineFail-stderr.txt
new file mode 100644
index 000000000..3b4743e15
--- /dev/null
+++ b/Tests/RunCMake/Languages/DetermineFail-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at Modules/CMakeDetermineFailCompiler.cmake:[0-9]+ \(message\):
+ This language is not supported.
+Call Stack \(most recent call first\):
+ DetermineFail.cmake:[0-9]+ \(enable_language\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/Languages/DetermineFail.cmake b/Tests/RunCMake/Languages/DetermineFail.cmake
new file mode 100644
index 000000000..3c8d17d8f
--- /dev/null
+++ b/Tests/RunCMake/Languages/DetermineFail.cmake
@@ -0,0 +1,2 @@
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/Modules)
+enable_language(Fail)
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt b/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt
index a5d5d5088..03c002e7d 100644
--- a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt
+++ b/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt
@@ -1,7 +1,9 @@
-CMake Error:
+CMake Error at LINK_LANGUAGE-genex.cmake:[0-9]+ \(target_link_libraries\):
Error evaluating generator expression:
\$<TARGET_PROPERTY:LINKER_LANGUAGE>
LINKER_LANGUAGE target property can not be used while evaluating link
- libraries
+ libraries for a static library
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/Languages/Modules/CMakeDetermineFailCompiler.cmake b/Tests/RunCMake/Languages/Modules/CMakeDetermineFailCompiler.cmake
new file mode 100644
index 000000000..3b2d50a34
--- /dev/null
+++ b/Tests/RunCMake/Languages/Modules/CMakeDetermineFailCompiler.cmake
@@ -0,0 +1 @@
+message(FATAL_ERROR "This language is not supported.")
diff --git a/Tests/RunCMake/Languages/RunCMakeTest.cmake b/Tests/RunCMake/Languages/RunCMakeTest.cmake
index 6517a8105..732baae41 100644
--- a/Tests/RunCMake/Languages/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Languages/RunCMakeTest.cmake
@@ -4,3 +4,5 @@ run_cmake(NoLangSHARED)
run_cmake(LINK_LANGUAGE-genex)
run_cmake(link-libraries-TARGET_FILE-genex)
run_cmake(link-libraries-TARGET_FILE-genex-ok)
+
+run_cmake(DetermineFail)
diff --git a/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-stderr.txt b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-stderr.txt
index 2d7a3c9d6..be3b12c3a 100644
--- a/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-stderr.txt
+++ b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-stderr.txt
@@ -1,7 +1,9 @@
-CMake Error:
+CMake Error at link-libraries-TARGET_FILE-genex.cmake:[0-9]+ \(target_link_libraries\):
Error evaluating generator expression:
\$<TARGET_FILE:foo>
Expressions which require the linker language may not be used while
evaluating link libraries
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/LinkStatic/CMakeLists.txt b/Tests/RunCMake/LinkStatic/CMakeLists.txt
new file mode 100644
index 000000000..74b3ff8de
--- /dev/null
+++ b/Tests/RunCMake/LinkStatic/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.3)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/LinkStatic/LINK_SEARCH_STATIC.cmake b/Tests/RunCMake/LinkStatic/LINK_SEARCH_STATIC.cmake
new file mode 100644
index 000000000..6db5c857d
--- /dev/null
+++ b/Tests/RunCMake/LinkStatic/LINK_SEARCH_STATIC.cmake
@@ -0,0 +1,73 @@
+enable_language(C)
+
+set(CMAKE_LINK_SEARCH_START_STATIC ON)
+add_executable(LinkSearchStartStaticInit1 LinkStatic.c)
+get_target_property(LSSS LinkSearchStartStaticInit1
+ LINK_SEARCH_START_STATIC)
+if(NOT LSSS)
+ message(FATAL_ERROR "Failed to correctly initialize LINK_SEARCH_START_STATIC")
+endif()
+unset(CMAKE_LINK_SEARCH_START_STATIC)
+
+add_executable(LinkSearchStartStaticSet1 LinkStatic.c)
+set_target_properties(LinkSearchStartStaticSet1 PROPERTIES
+ LINK_SEARCH_START_STATIC ON)
+get_target_property(LSSS LinkSearchStartStaticSet1
+ LINK_SEARCH_START_STATIC)
+if(NOT LSSS)
+ message(FATAL_ERROR "Failed to correctly set LINK_SEARCH_START_STATIC")
+endif()
+
+set(CMAKE_LINK_SEARCH_START_STATIC OFF)
+add_executable(LinkSearchStartStaticInit2 LinkStatic.c)
+get_target_property(LSSS LinkSearchStartStaticInit2
+ LINK_SEARCH_START_STATIC)
+if(LSSS)
+ message(FATAL_ERROR "Failed to correctly initialize LINK_SEARCH_START_STATIC")
+endif()
+unset(CMAKE_LINK_SEARCH_START_STATIC)
+
+add_executable(LinkSearchStartStaticSet2 LinkStatic.c)
+set_target_properties(LinkSearchStartStaticSet2 PROPERTIES
+ LINK_SEARCH_START_STATIC OFF)
+get_target_property(LSSS LinkSearchStartStaticSet2
+ LINK_SEARCH_START_STATIC)
+if(LSSS)
+ message(FATAL_ERROR "Failed to correctly set LINK_SEARCH_START_STATIC")
+endif()
+
+set(CMAKE_LINK_SEARCH_END_STATIC ON)
+add_executable(LinkSearchEndStaticInit1 LinkStatic.c)
+get_target_property(LSES LinkSearchEndStaticInit1
+ LINK_SEARCH_END_STATIC)
+if(NOT LSES)
+ message(FATAL_ERROR "Failed to correctly initialize LINK_SEARCH_END_STATIC")
+endif()
+unset(CMAKE_LINK_SEARCH_END_STATIC)
+
+add_executable(LinkSearchEndStaticSet1 LinkStatic.c)
+set_target_properties(LinkSearchEndStaticSet1 PROPERTIES
+ LINK_SEARCH_END_STATIC ON)
+get_target_property(LSSS LinkSearchEndStaticSet1
+ LINK_SEARCH_END_STATIC)
+if(NOT LSSS)
+ message(FATAL_ERROR "Failed to correctly set LINK_SEARCH_END_STATIC")
+endif()
+
+set(CMAKE_LINK_SEARCH_END_STATIC OFF)
+add_executable(LinkSearchEndStaticInit2 LinkStatic.c)
+get_target_property(LSES LinkSearchEndStaticInit2
+ LINK_SEARCH_END_STATIC)
+if(LSES)
+ message(FATAL_ERROR "Failed to correctly initialize LINK_SEARCH_END_STATIC")
+endif()
+unset(CMAKE_LINK_SEARCH_END_STATIC)
+
+add_executable(LinkSearchEndStaticSet2 LinkStatic.c)
+set_target_properties(LinkSearchEndStaticSet2 PROPERTIES
+ LINK_SEARCH_END_STATIC ON)
+get_target_property(LSSS LinkSearchEndStaticSet2
+ LINK_SEARCH_END_STATIC)
+if(NOT LSSS)
+ message(FATAL_ERROR "Failed to correctly set LINK_SEARCH_END_STATIC")
+endif()
diff --git a/Tests/RunCMake/LinkStatic/LinkStatic.c b/Tests/RunCMake/LinkStatic/LinkStatic.c
new file mode 100644
index 000000000..360097744
--- /dev/null
+++ b/Tests/RunCMake/LinkStatic/LinkStatic.c
@@ -0,0 +1,5 @@
+#include <math.h>
+int main(void)
+{
+ return (int)sin(0);
+}
diff --git a/Tests/RunCMake/LinkStatic/RunCMakeTest.cmake b/Tests/RunCMake/LinkStatic/RunCMakeTest.cmake
new file mode 100644
index 000000000..0d2949211
--- /dev/null
+++ b/Tests/RunCMake/LinkStatic/RunCMakeTest.cmake
@@ -0,0 +1,3 @@
+include(RunCMake)
+
+run_cmake(LINK_SEARCH_STATIC)
diff --git a/Tests/RunCMake/Make/CMakeLists.txt b/Tests/RunCMake/Make/CMakeLists.txt
new file mode 100644
index 000000000..74b3ff8de
--- /dev/null
+++ b/Tests/RunCMake/Make/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.3)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/Make/RunCMakeTest.cmake b/Tests/RunCMake/Make/RunCMakeTest.cmake
new file mode 100644
index 000000000..c6bbd03c0
--- /dev/null
+++ b/Tests/RunCMake/Make/RunCMakeTest.cmake
@@ -0,0 +1,17 @@
+include(RunCMake)
+
+function(run_TargetMessages case)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/TargetMessages-${case}-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ set(RunCMake_TEST_OPTIONS "${ARGN}")
+ run_cmake(TargetMessages-${case})
+ run_cmake_command(TargetMessages-${case}-build ${CMAKE_COMMAND} --build .)
+endfunction()
+
+run_TargetMessages(ON)
+run_TargetMessages(OFF)
+
+run_TargetMessages(VAR-ON -DCMAKE_TARGET_MESSAGES=ON)
+run_TargetMessages(VAR-OFF -DCMAKE_TARGET_MESSAGES=OFF)
diff --git a/Tests/RunCMake/Make/TargetMessages-OFF-build-stdout.txt b/Tests/RunCMake/Make/TargetMessages-OFF-build-stdout.txt
new file mode 100644
index 000000000..77a582a68
--- /dev/null
+++ b/Tests/RunCMake/Make/TargetMessages-OFF-build-stdout.txt
@@ -0,0 +1,5 @@
+^(([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
+]*
+)*Scanning dependencies of target CustomTarget(
+([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
+]*)*$
diff --git a/Tests/RunCMake/Make/TargetMessages-OFF.cmake b/Tests/RunCMake/Make/TargetMessages-OFF.cmake
new file mode 100644
index 000000000..8f5d52cca
--- /dev/null
+++ b/Tests/RunCMake/Make/TargetMessages-OFF.cmake
@@ -0,0 +1,2 @@
+set_property(GLOBAL PROPERTY TARGET_MESSAGES OFF)
+add_custom_target(CustomTarget ALL)
diff --git a/Tests/RunCMake/Make/TargetMessages-ON-build-stdout.txt b/Tests/RunCMake/Make/TargetMessages-ON-build-stdout.txt
new file mode 100644
index 000000000..a827624bc
--- /dev/null
+++ b/Tests/RunCMake/Make/TargetMessages-ON-build-stdout.txt
@@ -0,0 +1,8 @@
+^(([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
+]*
+)*Scanning dependencies of target CustomTarget(
+([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
+]*)*
+Built target CustomTarget(
+([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
+]*)*$
diff --git a/Tests/RunCMake/Make/TargetMessages-ON.cmake b/Tests/RunCMake/Make/TargetMessages-ON.cmake
new file mode 100644
index 000000000..e0a5f2b3f
--- /dev/null
+++ b/Tests/RunCMake/Make/TargetMessages-ON.cmake
@@ -0,0 +1,2 @@
+set_property(GLOBAL PROPERTY TARGET_MESSAGES ON)
+add_custom_target(CustomTarget ALL)
diff --git a/Tests/RunCMake/Make/TargetMessages-VAR-OFF-build-stdout.txt b/Tests/RunCMake/Make/TargetMessages-VAR-OFF-build-stdout.txt
new file mode 100644
index 000000000..77a582a68
--- /dev/null
+++ b/Tests/RunCMake/Make/TargetMessages-VAR-OFF-build-stdout.txt
@@ -0,0 +1,5 @@
+^(([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
+]*
+)*Scanning dependencies of target CustomTarget(
+([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
+]*)*$
diff --git a/Tests/RunCMake/Make/TargetMessages-VAR-OFF.cmake b/Tests/RunCMake/Make/TargetMessages-VAR-OFF.cmake
new file mode 100644
index 000000000..f27813230
--- /dev/null
+++ b/Tests/RunCMake/Make/TargetMessages-VAR-OFF.cmake
@@ -0,0 +1 @@
+add_custom_target(CustomTarget ALL)
diff --git a/Tests/RunCMake/Make/TargetMessages-VAR-ON-build-stdout.txt b/Tests/RunCMake/Make/TargetMessages-VAR-ON-build-stdout.txt
new file mode 100644
index 000000000..a827624bc
--- /dev/null
+++ b/Tests/RunCMake/Make/TargetMessages-VAR-ON-build-stdout.txt
@@ -0,0 +1,8 @@
+^(([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
+]*
+)*Scanning dependencies of target CustomTarget(
+([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
+]*)*
+Built target CustomTarget(
+([^B]|B[^u]|Bu[^i]|Bui[^l]|Buil[^t]|Built[^ ])[^
+]*)*$
diff --git a/Tests/RunCMake/Make/TargetMessages-VAR-ON.cmake b/Tests/RunCMake/Make/TargetMessages-VAR-ON.cmake
new file mode 100644
index 000000000..f27813230
--- /dev/null
+++ b/Tests/RunCMake/Make/TargetMessages-VAR-ON.cmake
@@ -0,0 +1 @@
+add_custom_target(CustomTarget ALL)
diff --git a/Tests/RunCMake/Ninja/CMP0058-NEW-by-build-stdout.txt b/Tests/RunCMake/Ninja/CMP0058-NEW-by-build-stdout.txt
new file mode 100644
index 000000000..8646a13e8
--- /dev/null
+++ b/Tests/RunCMake/Ninja/CMP0058-NEW-by-build-stdout.txt
@@ -0,0 +1,4 @@
+^[^
+]* Generating output1
+[^
+]* Generating output2$
diff --git a/Tests/RunCMake/Ninja/CMP0058-NEW-by.cmake b/Tests/RunCMake/Ninja/CMP0058-NEW-by.cmake
new file mode 100644
index 000000000..0f7793096
--- /dev/null
+++ b/Tests/RunCMake/Ninja/CMP0058-NEW-by.cmake
@@ -0,0 +1,3 @@
+cmake_policy(SET CMP0058 NEW)
+set(byproducts BYPRODUCTS byproduct1a byproduct1b)
+include(CMP0058-common.cmake)
diff --git a/Tests/RunCMake/Ninja/CMP0058-NEW-no-build-result.txt b/Tests/RunCMake/Ninja/CMP0058-NEW-no-build-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Ninja/CMP0058-NEW-no-build-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Ninja/CMP0058-NEW-no-build-stderr.txt b/Tests/RunCMake/Ninja/CMP0058-NEW-no-build-stderr.txt
new file mode 100644
index 000000000..fa10109fb
--- /dev/null
+++ b/Tests/RunCMake/Ninja/CMP0058-NEW-no-build-stderr.txt
@@ -0,0 +1 @@
+ninja: error: 'byproduct1a', needed by 'output2', missing and no known rule to make it
diff --git a/Tests/RunCMake/Ninja/CMP0058-NEW-no.cmake b/Tests/RunCMake/Ninja/CMP0058-NEW-no.cmake
new file mode 100644
index 000000000..582e3d530
--- /dev/null
+++ b/Tests/RunCMake/Ninja/CMP0058-NEW-no.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0058 NEW)
+include(CMP0058-common.cmake)
diff --git a/Tests/RunCMake/Ninja/CMP0058-OLD-by-build-stdout.txt b/Tests/RunCMake/Ninja/CMP0058-OLD-by-build-stdout.txt
new file mode 100644
index 000000000..8646a13e8
--- /dev/null
+++ b/Tests/RunCMake/Ninja/CMP0058-OLD-by-build-stdout.txt
@@ -0,0 +1,4 @@
+^[^
+]* Generating output1
+[^
+]* Generating output2$
diff --git a/Tests/RunCMake/Ninja/CMP0058-OLD-by.cmake b/Tests/RunCMake/Ninja/CMP0058-OLD-by.cmake
new file mode 100644
index 000000000..92a3a0fb5
--- /dev/null
+++ b/Tests/RunCMake/Ninja/CMP0058-OLD-by.cmake
@@ -0,0 +1,3 @@
+cmake_policy(SET CMP0058 OLD)
+set(byproducts BYPRODUCTS byproduct1a byproduct1b)
+include(CMP0058-common.cmake)
diff --git a/Tests/RunCMake/Ninja/CMP0058-OLD-no-build-stdout.txt b/Tests/RunCMake/Ninja/CMP0058-OLD-no-build-stdout.txt
new file mode 100644
index 000000000..8646a13e8
--- /dev/null
+++ b/Tests/RunCMake/Ninja/CMP0058-OLD-no-build-stdout.txt
@@ -0,0 +1,4 @@
+^[^
+]* Generating output1
+[^
+]* Generating output2$
diff --git a/Tests/RunCMake/Ninja/CMP0058-OLD-no.cmake b/Tests/RunCMake/Ninja/CMP0058-OLD-no.cmake
new file mode 100644
index 000000000..0326e0766
--- /dev/null
+++ b/Tests/RunCMake/Ninja/CMP0058-OLD-no.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0058 OLD)
+include(CMP0058-common.cmake)
diff --git a/Tests/RunCMake/Ninja/CMP0058-WARN-by-build-stdout.txt b/Tests/RunCMake/Ninja/CMP0058-WARN-by-build-stdout.txt
new file mode 100644
index 000000000..8646a13e8
--- /dev/null
+++ b/Tests/RunCMake/Ninja/CMP0058-WARN-by-build-stdout.txt
@@ -0,0 +1,4 @@
+^[^
+]* Generating output1
+[^
+]* Generating output2$
diff --git a/Tests/RunCMake/Ninja/CMP0058-WARN-by.cmake b/Tests/RunCMake/Ninja/CMP0058-WARN-by.cmake
new file mode 100644
index 000000000..612816796
--- /dev/null
+++ b/Tests/RunCMake/Ninja/CMP0058-WARN-by.cmake
@@ -0,0 +1,2 @@
+set(byproducts BYPRODUCTS byproduct1a byproduct1b)
+include(CMP0058-common.cmake)
diff --git a/Tests/RunCMake/Ninja/CMP0058-WARN-no-build-stdout.txt b/Tests/RunCMake/Ninja/CMP0058-WARN-no-build-stdout.txt
new file mode 100644
index 000000000..8646a13e8
--- /dev/null
+++ b/Tests/RunCMake/Ninja/CMP0058-WARN-no-build-stdout.txt
@@ -0,0 +1,4 @@
+^[^
+]* Generating output1
+[^
+]* Generating output2$
diff --git a/Tests/RunCMake/Ninja/CMP0058-WARN-no-stderr.txt b/Tests/RunCMake/Ninja/CMP0058-WARN-no-stderr.txt
new file mode 100644
index 000000000..439a2d9bf
--- /dev/null
+++ b/Tests/RunCMake/Ninja/CMP0058-WARN-no-stderr.txt
@@ -0,0 +1,19 @@
+^CMake Warning \(dev\):
+ Policy CMP0058 is not set: Ninja requires custom command byproducts to be
+ explicit. Run "cmake --help-policy CMP0058" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+
+ This project specifies custom command DEPENDS on files in the build tree
+ that are not specified as the OUTPUT or BYPRODUCTS of any
+ add_custom_command or add_custom_target:
+
+ byproduct1a
+ byproduct1b
+
+ For compatibility with versions of CMake that did not have the BYPRODUCTS
+ option, CMake is generating phony rules for such files to convince 'ninja'
+ to build.
+
+ Project authors should add the missing BYPRODUCTS or OUTPUT options to the
+ custom commands that produce these files.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/Ninja/CMP0058-WARN-no.cmake b/Tests/RunCMake/Ninja/CMP0058-WARN-no.cmake
new file mode 100644
index 000000000..7bc66ef28
--- /dev/null
+++ b/Tests/RunCMake/Ninja/CMP0058-WARN-no.cmake
@@ -0,0 +1 @@
+include(CMP0058-common.cmake)
diff --git a/Tests/RunCMake/Ninja/CMP0058-common.cmake b/Tests/RunCMake/Ninja/CMP0058-common.cmake
new file mode 100644
index 000000000..9274d58cd
--- /dev/null
+++ b/Tests/RunCMake/Ninja/CMP0058-common.cmake
@@ -0,0 +1,17 @@
+add_custom_command(
+ OUTPUT output1
+ ${byproducts}
+ COMMAND ${CMAKE_COMMAND} -E touch output1
+ COMMAND ${CMAKE_COMMAND} -E touch byproduct1a
+ COMMAND ${CMAKE_COMMAND} -E touch byproduct1b
+ )
+add_custom_target(Drive1 ALL DEPENDS output1)
+add_custom_command(
+ OUTPUT output2
+ COMMAND ${CMAKE_COMMAND} -E copy output1 output2
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/output1
+ ${CMAKE_CURRENT_BINARY_DIR}/byproduct1a
+ ${CMAKE_CURRENT_BINARY_DIR}/byproduct1b
+ )
+add_custom_target(Drive2 ALL DEPENDS output2)
+add_dependencies(Drive2 Drive1)
diff --git a/Tests/RunCMake/Ninja/CMakeLists.txt b/Tests/RunCMake/Ninja/CMakeLists.txt
new file mode 100644
index 000000000..2a0591e74
--- /dev/null
+++ b/Tests/RunCMake/Ninja/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.2)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE)
diff --git a/Tests/RunCMake/Ninja/RunCMakeTest.cmake b/Tests/RunCMake/Ninja/RunCMakeTest.cmake
new file mode 100644
index 000000000..64f97bcd6
--- /dev/null
+++ b/Tests/RunCMake/Ninja/RunCMakeTest.cmake
@@ -0,0 +1,18 @@
+include(RunCMake)
+
+function(run_CMP0058 case)
+ # Use a single build tree for a few tests without cleaning.
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CMP0058-${case}-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ run_cmake(CMP0058-${case})
+ run_cmake_command(CMP0058-${case}-build ${CMAKE_COMMAND} --build .)
+endfunction()
+
+run_CMP0058(OLD-no)
+run_CMP0058(OLD-by)
+run_CMP0058(WARN-no)
+run_CMP0058(WARN-by)
+run_CMP0058(NEW-no)
+run_CMP0058(NEW-by)
diff --git a/Tests/RunCMake/ObjectLibrary/BadObjSource1-stderr.txt b/Tests/RunCMake/ObjectLibrary/BadObjSource1-stderr.txt
index b31225b48..a09552b76 100644
--- a/Tests/RunCMake/ObjectLibrary/BadObjSource1-stderr.txt
+++ b/Tests/RunCMake/ObjectLibrary/BadObjSource1-stderr.txt
@@ -3,6 +3,7 @@ CMake Error at BadObjSource1.cmake:1 \(add_library\):
bad.def
- but may contain only headers and sources that compile.
+ but may contain only sources that compile, header files, and other files
+ that would not affect linking of a normal library.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/BadObjSource2-stderr.txt b/Tests/RunCMake/ObjectLibrary/BadObjSource2-stderr.txt
index 906cf0b64..b91ffd068 100644
--- a/Tests/RunCMake/ObjectLibrary/BadObjSource2-stderr.txt
+++ b/Tests/RunCMake/ObjectLibrary/BadObjSource2-stderr.txt
@@ -3,6 +3,7 @@ CMake Error at BadObjSource2.cmake:1 \(add_library\):
bad.obj
- but may contain only headers and sources that compile.
+ but may contain only sources that compile, header files, and other files
+ that would not affect linking of a normal library.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-stderr.txt b/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-stderr.txt
index a1cac36fa..859dc3f8c 100644
--- a/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-stderr.txt
+++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-stderr.txt
@@ -1,6 +1,8 @@
CMake Error at BadSourceExpression1.cmake:1 \(add_library\):
- Unrecognized generator expression:
+ Error evaluating generator expression:
\$<BAD_EXPRESSION>
+
+ Expression did not evaluate to a known generator expression
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/BadSourceExpression2-stderr.txt b/Tests/RunCMake/ObjectLibrary/BadSourceExpression2-stderr.txt
index f1fcbe85f..7060c615e 100644
--- a/Tests/RunCMake/ObjectLibrary/BadSourceExpression2-stderr.txt
+++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression2-stderr.txt
@@ -1,4 +1,8 @@
CMake Error at BadSourceExpression2.cmake:1 \(add_library\):
+ Error evaluating generator expression:
+
+ \$<TARGET_OBJECTS:DoesNotExist>
+
Objects of target "DoesNotExist" referenced but no such target exists.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-stderr.txt b/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-stderr.txt
index ad14a3513..838b3d8c4 100644
--- a/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-stderr.txt
+++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-stderr.txt
@@ -1,4 +1,8 @@
CMake Error at BadSourceExpression3.cmake:2 \(add_library\):
+ Error evaluating generator expression:
+
+ \$<TARGET_OBJECTS:NotObjLib>
+
Objects of target "NotObjLib" referenced but is not an OBJECT library.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/ExportLanguages.cmake b/Tests/RunCMake/ObjectLibrary/ExportLanguages.cmake
deleted file mode 100644
index 0796c21ba..000000000
--- a/Tests/RunCMake/ObjectLibrary/ExportLanguages.cmake
+++ /dev/null
@@ -1,15 +0,0 @@
-enable_language(CXX)
-add_library(A OBJECT a.cxx)
-add_library(B STATIC a.c $<TARGET_OBJECTS:A>)
-
-# Verify that object library languages are propagated.
-export(TARGETS B NAMESPACE Exp FILE BExport.cmake)
-include(${CMAKE_CURRENT_BINARY_DIR}/BExport.cmake)
-get_property(configs TARGET ExpB PROPERTY IMPORTED_CONFIGURATIONS)
-foreach(c ${configs})
- get_property(langs TARGET ExpB PROPERTY IMPORTED_LINK_INTERFACE_LANGUAGES_${c})
- list(FIND langs CXX pos)
- if(${pos} LESS 0)
- message(FATAL_ERROR "Target export does not list object library languages.")
- endif()
-endforeach()
diff --git a/Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake b/Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake
index 2dd8d3859..42973f8af 100644
--- a/Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake
@@ -6,7 +6,6 @@ run_cmake(BadSourceExpression3)
run_cmake(BadObjSource1)
run_cmake(BadObjSource2)
run_cmake(Export)
-run_cmake(ExportLanguages)
run_cmake(Import)
run_cmake(Install)
run_cmake(LinkObjLHS)
diff --git a/Tests/RunCMake/ObsoleteQtMacros/AutomocMacro-WARN-stderr.txt b/Tests/RunCMake/ObsoleteQtMacros/AutomocMacro-WARN-stderr.txt
index 6f7e8ee61..f358cc4be 100644
--- a/Tests/RunCMake/ObsoleteQtMacros/AutomocMacro-WARN-stderr.txt
+++ b/Tests/RunCMake/ObsoleteQtMacros/AutomocMacro-WARN-stderr.txt
@@ -1,4 +1,4 @@
-CMake Warning at .*/Modules/Qt4Macros.cmake:[^ ]+ \(message\):
+CMake Deprecation Warning at .*/Modules/Qt4Macros.cmake:[^ ]+ \(message\):
The qt4_automoc macro is obsolete. Use the CMAKE_AUTOMOC feature instead.
Call Stack \(most recent call first\):
AutomocMacro-WARN.cmake:7 \(qt4_automoc\)
diff --git a/Tests/RunCMake/ObsoleteQtMacros/UseModulesMacro-WARN-stderr.txt b/Tests/RunCMake/ObsoleteQtMacros/UseModulesMacro-WARN-stderr.txt
index b90c6651a..c69af6512 100644
--- a/Tests/RunCMake/ObsoleteQtMacros/UseModulesMacro-WARN-stderr.txt
+++ b/Tests/RunCMake/ObsoleteQtMacros/UseModulesMacro-WARN-stderr.txt
@@ -1,4 +1,4 @@
-CMake Warning at .*/Modules/Qt4Macros.cmake:[^ ]+ \(message\):
+CMake Deprecation Warning at .*/Modules/Qt4Macros.cmake:[^ ]+ \(message\):
The qt4_use_modules function is obsolete. Use target_link_libraries with
IMPORTED targets instead.
Call Stack \(most recent call first\):
diff --git a/Tests/RunCMake/PolicyScope/CMakeLists.txt b/Tests/RunCMake/PolicyScope/CMakeLists.txt
new file mode 100644
index 000000000..667561ea7
--- /dev/null
+++ b/Tests/RunCMake/PolicyScope/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE)
diff --git a/Tests/RunCMake/PolicyScope/NotClosed-result.txt b/Tests/RunCMake/PolicyScope/NotClosed-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/PolicyScope/NotClosed-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/PolicyScope/NotClosed-stderr.txt b/Tests/RunCMake/PolicyScope/NotClosed-stderr.txt
new file mode 100644
index 000000000..293d16117
--- /dev/null
+++ b/Tests/RunCMake/PolicyScope/NotClosed-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at NotClosed.cmake:[0-9]+ \(include\):
+ cmake_policy PUSH without matching POP
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/PolicyScope/NotClosed.cmake b/Tests/RunCMake/PolicyScope/NotClosed.cmake
new file mode 100644
index 000000000..19b880efa
--- /dev/null
+++ b/Tests/RunCMake/PolicyScope/NotClosed.cmake
@@ -0,0 +1 @@
+cmake_policy(PUSH)
diff --git a/Tests/RunCMake/PolicyScope/NotOpened-result.txt b/Tests/RunCMake/PolicyScope/NotOpened-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/PolicyScope/NotOpened-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/PolicyScope/NotOpened-stderr.txt b/Tests/RunCMake/PolicyScope/NotOpened-stderr.txt
new file mode 100644
index 000000000..f27aac8db
--- /dev/null
+++ b/Tests/RunCMake/PolicyScope/NotOpened-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at NotOpened.cmake:[0-9]+ \(cmake_policy\):
+ cmake_policy POP without matching PUSH
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/PolicyScope/NotOpened.cmake b/Tests/RunCMake/PolicyScope/NotOpened.cmake
new file mode 100644
index 000000000..bb9f3a364
--- /dev/null
+++ b/Tests/RunCMake/PolicyScope/NotOpened.cmake
@@ -0,0 +1 @@
+cmake_policy(POP)
diff --git a/Tests/RunCMake/PolicyScope/RunCMakeTest.cmake b/Tests/RunCMake/PolicyScope/RunCMakeTest.cmake
new file mode 100644
index 000000000..abd27f4cd
--- /dev/null
+++ b/Tests/RunCMake/PolicyScope/RunCMakeTest.cmake
@@ -0,0 +1,6 @@
+include(RunCMake)
+
+run_cmake(NotClosed)
+run_cmake(NotOpened)
+run_cmake(parent-dir-generate-time)
+run_cmake(dir-in-macro-generate-time)
diff --git a/Tests/RunCMake/PolicyScope/dir-in-macro-generate-time-result.txt b/Tests/RunCMake/PolicyScope/dir-in-macro-generate-time-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/PolicyScope/dir-in-macro-generate-time-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/PolicyScope/dir-in-macro-generate-time-stderr.txt b/Tests/RunCMake/PolicyScope/dir-in-macro-generate-time-stderr.txt
new file mode 100644
index 000000000..d223f42a8
--- /dev/null
+++ b/Tests/RunCMake/PolicyScope/dir-in-macro-generate-time-stderr.txt
@@ -0,0 +1,5 @@
+CMake Warning \(dev\) at dir1/CMakeLists.txt:5 \(target_compile_definitions\):
+ Policy CMP0044 is not set: Case sensitive <LANG>_COMPILER_ID generator
+ expressions. Run "cmake --help-policy CMP0044" for policy details. Use
+ the cmake_policy command to set the policy and suppress this warning.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/PolicyScope/dir-in-macro-generate-time.cmake b/Tests/RunCMake/PolicyScope/dir-in-macro-generate-time.cmake
new file mode 100644
index 000000000..04a7c2c7f
--- /dev/null
+++ b/Tests/RunCMake/PolicyScope/dir-in-macro-generate-time.cmake
@@ -0,0 +1,2 @@
+
+include(dir-in-macro-include.cmake)
diff --git a/Tests/RunCMake/PolicyScope/dir-in-macro-include.cmake b/Tests/RunCMake/PolicyScope/dir-in-macro-include.cmake
new file mode 100644
index 000000000..fd326f12c
--- /dev/null
+++ b/Tests/RunCMake/PolicyScope/dir-in-macro-include.cmake
@@ -0,0 +1,6 @@
+
+enable_language(CXX)
+
+# This does not affect dir1 despite being set before the add_subdirectory.
+cmake_policy(SET CMP0044 NEW)
+add_subdirectory(dir1)
diff --git a/Tests/RunCMake/PolicyScope/dir1/CMakeLists.txt b/Tests/RunCMake/PolicyScope/dir1/CMakeLists.txt
new file mode 100644
index 000000000..16bcb3689
--- /dev/null
+++ b/Tests/RunCMake/PolicyScope/dir1/CMakeLists.txt
@@ -0,0 +1,5 @@
+
+
+add_library(foo STATIC foo.cpp)
+string(TOLOWER ${CMAKE_CXX_COMPILER_ID} compiler_id)
+target_compile_definitions(foo PRIVATE Foo=$<CXX_COMPILER_ID:${compiler_id}>)
diff --git a/Tests/RunCMake/PolicyScope/dir1/foo.cpp b/Tests/RunCMake/PolicyScope/dir1/foo.cpp
new file mode 100644
index 000000000..766b7751b
--- /dev/null
+++ b/Tests/RunCMake/PolicyScope/dir1/foo.cpp
@@ -0,0 +1,5 @@
+
+int main()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/PolicyScope/parent-dir-generate-time-result.txt b/Tests/RunCMake/PolicyScope/parent-dir-generate-time-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/PolicyScope/parent-dir-generate-time-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/PolicyScope/parent-dir-generate-time.cmake b/Tests/RunCMake/PolicyScope/parent-dir-generate-time.cmake
new file mode 100644
index 000000000..a0842f7b2
--- /dev/null
+++ b/Tests/RunCMake/PolicyScope/parent-dir-generate-time.cmake
@@ -0,0 +1,7 @@
+
+enable_language(CXX)
+
+add_subdirectory(dir1)
+
+# This affects dir1 despite being set after the add_subdirectory.
+cmake_policy(SET CMP0044 NEW)
diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict4-result.txt b/Tests/RunCMake/PositionIndependentCode/Conflict4-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/PositionIndependentCode/Conflict4-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict4-stderr.txt b/Tests/RunCMake/PositionIndependentCode/Conflict4-stderr.txt
new file mode 100644
index 000000000..76d5ea08a
--- /dev/null
+++ b/Tests/RunCMake/PositionIndependentCode/Conflict4-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error: Property POSITION_INDEPENDENT_CODE on target "conflict" is
+implied to be FALSE because it was used to determine the link libraries
+already. The INTERFACE_POSITION_INDEPENDENT_CODE property on
+dependency "picon" is in conflict.
diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict4.cmake b/Tests/RunCMake/PositionIndependentCode/Conflict4.cmake
new file mode 100644
index 000000000..ff5dfb353
--- /dev/null
+++ b/Tests/RunCMake/PositionIndependentCode/Conflict4.cmake
@@ -0,0 +1,8 @@
+
+add_library(piciface INTERFACE)
+
+add_library(picon INTERFACE)
+set_property(TARGET picon PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON)
+
+add_executable(conflict "main.cpp")
+target_link_libraries(conflict picon $<$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>:piciface>)
diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict5-result.txt b/Tests/RunCMake/PositionIndependentCode/Conflict5-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/PositionIndependentCode/Conflict5-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict5-stderr.txt b/Tests/RunCMake/PositionIndependentCode/Conflict5-stderr.txt
new file mode 100644
index 000000000..ecd04928d
--- /dev/null
+++ b/Tests/RunCMake/PositionIndependentCode/Conflict5-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error: The INTERFACE_POSITION_INDEPENDENT_CODE property of "picoff" does
+not agree with the value of POSITION_INDEPENDENT_CODE already determined
+for "conflict".
diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict5.cmake b/Tests/RunCMake/PositionIndependentCode/Conflict5.cmake
new file mode 100644
index 000000000..e6055f450
--- /dev/null
+++ b/Tests/RunCMake/PositionIndependentCode/Conflict5.cmake
@@ -0,0 +1,9 @@
+
+add_library(picon INTERFACE)
+set_property(TARGET picon PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON)
+
+add_library(picoff INTERFACE)
+set_property(TARGET picoff PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE OFF)
+
+add_executable(conflict "main.cpp")
+target_link_libraries(conflict picon picoff)
diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict6-result.txt b/Tests/RunCMake/PositionIndependentCode/Conflict6-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/PositionIndependentCode/Conflict6-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict6-stderr.txt b/Tests/RunCMake/PositionIndependentCode/Conflict6-stderr.txt
new file mode 100644
index 000000000..0254e5557
--- /dev/null
+++ b/Tests/RunCMake/PositionIndependentCode/Conflict6-stderr.txt
@@ -0,0 +1,4 @@
+Property POSITION_INDEPENDENT_CODE on target "conflict" is
+implied to be FALSE because it was used to determine the link libraries
+already. The INTERFACE_POSITION_INDEPENDENT_CODE property on
+dependency "picon" is in conflict.
diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict6.cmake b/Tests/RunCMake/PositionIndependentCode/Conflict6.cmake
new file mode 100644
index 000000000..7ea7c5f73
--- /dev/null
+++ b/Tests/RunCMake/PositionIndependentCode/Conflict6.cmake
@@ -0,0 +1,8 @@
+
+add_library(picoff INTERFACE)
+
+add_library(picon INTERFACE)
+set_property(TARGET picon PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON)
+
+add_executable(conflict "main.cpp")
+target_link_libraries(conflict picon $<$<NOT:$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>>:picoff>)
diff --git a/Tests/RunCMake/PositionIndependentCode/Debug-result.txt b/Tests/RunCMake/PositionIndependentCode/Debug-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/PositionIndependentCode/Debug-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/PositionIndependentCode/Debug-stderr.txt b/Tests/RunCMake/PositionIndependentCode/Debug-stderr.txt
new file mode 100644
index 000000000..774445b2b
--- /dev/null
+++ b/Tests/RunCMake/PositionIndependentCode/Debug-stderr.txt
@@ -0,0 +1,6 @@
+CMake Debug Log:
+ Boolean compatibility of property "POSITION_INDEPENDENT_CODE" for target
+ "foo" \(result: "TRUE"\):
+
+ \* Target "foo" has property content "TRUE"
+ \* Target "iface" property value "TRUE" \(Agree\)
diff --git a/Tests/RunCMake/PositionIndependentCode/Debug.cmake b/Tests/RunCMake/PositionIndependentCode/Debug.cmake
new file mode 100644
index 000000000..4a8fbacba
--- /dev/null
+++ b/Tests/RunCMake/PositionIndependentCode/Debug.cmake
@@ -0,0 +1,8 @@
+
+add_library(iface INTERFACE)
+set_property(TARGET iface PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON)
+
+set(CMAKE_DEBUG_TARGET_PROPERTIES POSITION_INDEPENDENT_CODE)
+add_library(foo main.cpp)
+target_link_libraries(foo iface)
+set_property(TARGET foo PROPERTY POSITION_INDEPENDENT_CODE ON)
diff --git a/Tests/RunCMake/PositionIndependentCode/RunCMakeTest.cmake b/Tests/RunCMake/PositionIndependentCode/RunCMakeTest.cmake
index 64a340c9c..6a67e3cad 100644
--- a/Tests/RunCMake/PositionIndependentCode/RunCMakeTest.cmake
+++ b/Tests/RunCMake/PositionIndependentCode/RunCMakeTest.cmake
@@ -3,3 +3,7 @@ include(RunCMake)
run_cmake(Conflict1)
run_cmake(Conflict2)
run_cmake(Conflict3)
+run_cmake(Conflict4)
+run_cmake(Conflict5)
+run_cmake(Conflict6)
+run_cmake(Debug)
diff --git a/Tests/RunCMake/README.rst b/Tests/RunCMake/README.rst
new file mode 100644
index 000000000..4aae4aed5
--- /dev/null
+++ b/Tests/RunCMake/README.rst
@@ -0,0 +1,67 @@
+This directory contains tests that run CMake to configure a project
+but do not actually build anything. To add a test:
+
+1. Add a subdirectory named for the test, say ``<Test>/``.
+
+2. In ``./CMakeLists.txt`` call ``add_RunCMake_test`` and pass the
+ test directory name ``<Test>``.
+
+3. Create script ``<Test>/RunCMakeTest.cmake`` in the directory containing::
+
+ include(RunCMake)
+ run_cmake(SubTest1)
+ ...
+ run_cmake(SubTestN)
+
+ where ``SubTest1`` through ``SubTestN`` are sub-test names each
+ corresponding to an independent CMake run and project configuration.
+
+ One may also add calls of the form::
+
+ run_cmake_command(SubTestI ${CMAKE_COMMAND} ...)
+
+ to fully customize the test case command-line.
+
+ Alternatively, if the test is to cover running ``ctest -S`` then use::
+
+ include(RunCTest)
+ run_ctest(SubTest1)
+ ...
+ run_ctest(SubTestN)
+
+ and create ``test.cmake.in``, ``CTestConfig.cmake.in``, and
+ ``CMakeLists.txt.in`` files to be configured for each case.
+
+4. Create file ``<Test>/CMakeLists.txt`` in the directory containing::
+
+ cmake_minimum_required(...)
+ project(${RunCMake_TEST} NONE) # or languages needed
+ include(${RunCMake_TEST}.cmake)
+
+ where ``${RunCMake_TEST}`` is literal. A value for ``RunCMake_TEST``
+ will be passed to CMake by the ``run_cmake`` macro when running each
+ sub-test.
+
+5. Create a ``<Test>/<SubTest>.cmake`` file for each sub-test named
+ above containing the actual test code. Optionally create files
+ containing expected test results:
+
+ ``<SubTest>-result.txt``
+ Process result expected if not "0"
+ ``<SubTest>-stdout.txt``
+ Regex matching expected stdout content
+ ``<SubTest>-stderr.txt``
+ Regex matching expected stderr content, if not "^$"
+ ``<SubTest>-check.cmake``
+ Custom result check.
+
+ Note that trailing newlines will be stripped from actual and expected
+ test output before matching against the stdout and stderr expressions.
+ The code in ``<SubTest>-check.cmake`` may use variables
+
+ ``RunCMake_TEST_SOURCE_DIR``
+ Top of test source tree
+ ``RunCMake_TEST_BINARY_DIR``
+ Top of test binary tree
+
+ and an failure must store a message in ``RunCMake_TEST_FAILED``.
diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake
index 00faa4ca7..db9911d8c 100644
--- a/Tests/RunCMake/RunCMake.cmake
+++ b/Tests/RunCMake/RunCMake.cmake
@@ -18,14 +18,26 @@ function(run_cmake test)
set(expect_result 0)
endif()
foreach(o out err)
- if(EXISTS ${top_src}/${test}-std${o}.txt)
+ if(RunCMake-std${o}-file AND EXISTS ${top_src}/${RunCMake-std${o}-file})
+ file(READ ${top_src}/${RunCMake-std${o}-file} expect_std${o})
+ string(REGEX REPLACE "\n+$" "" expect_std${o} "${expect_std${o}}")
+ elseif(EXISTS ${top_src}/${test}-std${o}.txt)
file(READ ${top_src}/${test}-std${o}.txt expect_std${o})
string(REGEX REPLACE "\n+$" "" expect_std${o} "${expect_std${o}}")
else()
unset(expect_std${o})
endif()
endforeach()
- set(RunCMake_TEST_SOURCE_DIR "${top_src}")
+ if (NOT expect_stderr)
+ if (NOT RunCMake_DEFAULT_stderr)
+ set(RunCMake_DEFAULT_stderr "^$")
+ endif()
+ set(expect_stderr ${RunCMake_DEFAULT_stderr})
+ endif()
+
+ if (NOT RunCMake_TEST_SOURCE_DIR)
+ set(RunCMake_TEST_SOURCE_DIR "${top_src}")
+ endif()
if(NOT RunCMake_TEST_BINARY_DIR)
set(RunCMake_TEST_BINARY_DIR "${top_bin}/${test}-build")
endif()
@@ -36,22 +48,61 @@ function(run_cmake test)
if(NOT DEFINED RunCMake_TEST_OPTIONS)
set(RunCMake_TEST_OPTIONS "")
endif()
- execute_process(
- COMMAND ${CMAKE_COMMAND} "${RunCMake_TEST_SOURCE_DIR}"
- -G "${RunCMake_GENERATOR}"
- -T "${RunCMake_GENERATOR_TOOLSET}"
- -DRunCMake_TEST=${test}
- ${RunCMake_TEST_OPTIONS}
- WORKING_DIRECTORY "${RunCMake_TEST_BINARY_DIR}"
- OUTPUT_VARIABLE actual_stdout
- ERROR_VARIABLE actual_stderr
- RESULT_VARIABLE actual_result
- )
+ if(APPLE)
+ list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_POLICY_DEFAULT_CMP0025=NEW)
+ endif()
+ if(RunCMake_GENERATOR STREQUAL "Visual Studio 6" AND NOT RunCMake_WARN_VS6)
+ list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_WARN_VS6=OFF)
+ endif()
+ if(RunCMake_GENERATOR STREQUAL "Visual Studio 7" AND NOT RunCMake_WARN_VS70)
+ list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_WARN_VS70=OFF)
+ endif()
+ if(RunCMake_MAKE_PROGRAM)
+ list(APPEND RunCMake_TEST_OPTIONS "-DCMAKE_MAKE_PROGRAM=${RunCMake_MAKE_PROGRAM}")
+ endif()
+ if(RunCMake_TEST_OUTPUT_MERGE)
+ set(actual_stderr_var actual_stdout)
+ set(actual_stderr "")
+ else()
+ set(actual_stderr_var actual_stderr)
+ endif()
+ if(DEFINED RunCMake_TEST_TIMEOUT)
+ set(maybe_timeout TIMEOUT ${RunCMake_TEST_TIMEOUT})
+ else()
+ set(maybe_timeout "")
+ endif()
+ if(RunCMake_TEST_COMMAND)
+ execute_process(
+ COMMAND ${RunCMake_TEST_COMMAND}
+ WORKING_DIRECTORY "${RunCMake_TEST_BINARY_DIR}"
+ OUTPUT_VARIABLE actual_stdout
+ ERROR_VARIABLE ${actual_stderr_var}
+ RESULT_VARIABLE actual_result
+ ${maybe_timeout}
+ )
+ else()
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} "${RunCMake_TEST_SOURCE_DIR}"
+ -G "${RunCMake_GENERATOR}"
+ -A "${RunCMake_GENERATOR_PLATFORM}"
+ -T "${RunCMake_GENERATOR_TOOLSET}"
+ -DRunCMake_TEST=${test}
+ --no-warn-unused-cli
+ ${RunCMake_TEST_OPTIONS}
+ WORKING_DIRECTORY "${RunCMake_TEST_BINARY_DIR}"
+ OUTPUT_VARIABLE actual_stdout
+ ERROR_VARIABLE ${actual_stderr_var}
+ RESULT_VARIABLE actual_result
+ ${maybe_timeout}
+ )
+ endif()
set(msg "")
- if(NOT "${actual_result}" STREQUAL "${expect_result}")
+ if(NOT "${actual_result}" MATCHES "${expect_result}")
set(msg "${msg}Result is [${actual_result}], not [${expect_result}].\n")
endif()
foreach(o out err)
+ string(REGEX REPLACE "\r\n" "\n" actual_std${o} "${actual_std${o}}")
+ string(REGEX REPLACE "(^|\n)((==[0-9]+==|BullseyeCoverage|[a-z]+\\([0-9]+\\) malloc:|Error kstat returned|[^\n]*from Time Machine by path|[^\n]*Bullseye Testing Technology)[^\n]*\n)+" "\\1" actual_std${o} "${actual_std${o}}")
string(REGEX REPLACE "\n+$" "" actual_std${o} "${actual_std${o}}")
set(expect_${o} "")
if(DEFINED expect_std${o})
@@ -64,10 +115,18 @@ function(run_cmake test)
endif()
endforeach()
unset(RunCMake_TEST_FAILED)
- include(${top_src}/${test}-check.cmake OPTIONAL)
+ if(RunCMake-check-file AND EXISTS ${top_src}/${RunCMake-check-file})
+ include(${top_src}/${RunCMake-check-file})
+ else()
+ include(${top_src}/${test}-check.cmake OPTIONAL)
+ endif()
if(RunCMake_TEST_FAILED)
set(msg "${RunCMake_TEST_FAILED}\n${msg}")
endif()
+ if(msg AND RunCMake_TEST_COMMAND)
+ string(REPLACE ";" "\" \"" command "\"${RunCMake_TEST_COMMAND}\"")
+ set(msg "${msg}Command was:\n command> ${command}\n")
+ endif()
if(msg)
string(REGEX REPLACE "\n" "\n actual-out> " actual_out " actual-out> ${actual_stdout}")
string(REGEX REPLACE "\n" "\n actual-err> " actual_err " actual-err> ${actual_stderr}")
@@ -82,3 +141,11 @@ function(run_cmake test)
message(STATUS "${test} - PASSED")
endif()
endfunction()
+
+function(run_cmake_command test)
+ set(RunCMake_TEST_COMMAND "${ARGN}")
+ run_cmake(${test})
+endfunction()
+
+# Protect RunCMake tests from calling environment.
+unset(ENV{MAKEFLAGS})
diff --git a/Tests/RunCMake/RunCTest.cmake b/Tests/RunCMake/RunCTest.cmake
new file mode 100644
index 000000000..e94432b17
--- /dev/null
+++ b/Tests/RunCMake/RunCTest.cmake
@@ -0,0 +1,17 @@
+include(RunCMake)
+
+function(run_ctest CASE_NAME)
+ configure_file(${RunCMake_SOURCE_DIR}/test.cmake.in
+ ${RunCMake_BINARY_DIR}/${CASE_NAME}/test.cmake @ONLY)
+ configure_file(${RunCMake_SOURCE_DIR}/CTestConfig.cmake.in
+ ${RunCMake_BINARY_DIR}/${CASE_NAME}/CTestConfig.cmake @ONLY)
+ configure_file(${RunCMake_SOURCE_DIR}/CMakeLists.txt.in
+ ${RunCMake_BINARY_DIR}/${CASE_NAME}/CMakeLists.txt @ONLY)
+ run_cmake_command(${CASE_NAME} ${CMAKE_CTEST_COMMAND}
+ -C Debug
+ -S ${RunCMake_BINARY_DIR}/${CASE_NAME}/test.cmake
+ -V
+ --output-log ${RunCMake_BINARY_DIR}/${CASE_NAME}-build/testOutput.log
+ ${ARGN}
+ )
+endfunction()
diff --git a/Tests/RunCMake/Swift/CMakeLists.txt b/Tests/RunCMake/Swift/CMakeLists.txt
new file mode 100644
index 000000000..74b3ff8de
--- /dev/null
+++ b/Tests/RunCMake/Swift/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.3)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/Swift/NotSupported-result.txt b/Tests/RunCMake/Swift/NotSupported-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Swift/NotSupported-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Swift/NotSupported-stderr.txt b/Tests/RunCMake/Swift/NotSupported-stderr.txt
new file mode 100644
index 000000000..9a9c23ff3
--- /dev/null
+++ b/Tests/RunCMake/Swift/NotSupported-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at .*/Modules/CMakeDetermineSwiftCompiler.cmake:[0-9]+ \(message\):
+ Swift language not supported by "[^"]*" generator
+Call Stack \(most recent call first\):
+ NotSupported.cmake:[0-9]+ \(enable_language\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/Swift/NotSupported.cmake b/Tests/RunCMake/Swift/NotSupported.cmake
new file mode 100644
index 000000000..19f297a87
--- /dev/null
+++ b/Tests/RunCMake/Swift/NotSupported.cmake
@@ -0,0 +1 @@
+enable_language(Swift)
diff --git a/Tests/RunCMake/Swift/RunCMakeTest.cmake b/Tests/RunCMake/Swift/RunCMakeTest.cmake
new file mode 100644
index 000000000..4864295dc
--- /dev/null
+++ b/Tests/RunCMake/Swift/RunCMakeTest.cmake
@@ -0,0 +1,9 @@
+include(RunCMake)
+
+if(RunCMake_GENERATOR STREQUAL Xcode)
+ if(XCODE_BELOW_6_1)
+ run_cmake(XcodeTooOld)
+ endif()
+else()
+ run_cmake(NotSupported)
+endif()
diff --git a/Tests/RunCMake/Swift/XcodeTooOld-result.txt b/Tests/RunCMake/Swift/XcodeTooOld-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Swift/XcodeTooOld-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Swift/XcodeTooOld-stderr.txt b/Tests/RunCMake/Swift/XcodeTooOld-stderr.txt
new file mode 100644
index 000000000..8d18f294f
--- /dev/null
+++ b/Tests/RunCMake/Swift/XcodeTooOld-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at .*/Modules/CMakeDetermineSwiftCompiler.cmake:[0-9]+ \(message\):
+ Swift language not supported by Xcode [0-9.]+
+Call Stack \(most recent call first\):
+ XcodeTooOld.cmake:[0-9]+ \(enable_language\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/Swift/XcodeTooOld.cmake b/Tests/RunCMake/Swift/XcodeTooOld.cmake
new file mode 100644
index 000000000..19f297a87
--- /dev/null
+++ b/Tests/RunCMake/Swift/XcodeTooOld.cmake
@@ -0,0 +1 @@
+enable_language(Swift)
diff --git a/Tests/RunCMake/Syntax/.gitattributes b/Tests/RunCMake/Syntax/.gitattributes
index fc9ebff69..35a9eaf2b 100644
--- a/Tests/RunCMake/Syntax/.gitattributes
+++ b/Tests/RunCMake/Syntax/.gitattributes
@@ -1 +1,3 @@
CommandTabs.cmake whitespace=-tab-in-indent
+StringCRLF.cmake whitespace=cr-at-eol -crlf
+BracketCRLF.cmake whitespace=cr-at-eol -crlf
diff --git a/Tests/RunCMake/Syntax/AtWithVariable-stderr.txt b/Tests/RunCMake/Syntax/AtWithVariable-stderr.txt
new file mode 100644
index 000000000..5dcd4d7a1
--- /dev/null
+++ b/Tests/RunCMake/Syntax/AtWithVariable-stderr.txt
@@ -0,0 +1 @@
+-->wrong<--
diff --git a/Tests/RunCMake/Syntax/AtWithVariable.cmake b/Tests/RunCMake/Syntax/AtWithVariable.cmake
new file mode 100644
index 000000000..2bbf61db3
--- /dev/null
+++ b/Tests/RunCMake/Syntax/AtWithVariable.cmake
@@ -0,0 +1,9 @@
+set(right "wrong")
+set(var "\${right}")
+# Expanded here.
+set(ref "@var@")
+
+# 'right' is dereferenced because 'var' was dereferenced when
+# assigning to 'ref' above.
+string(CONFIGURE "${ref}" output)
+message("-->${output}<--")
diff --git a/Tests/RunCMake/Syntax/AtWithVariableAtOnly-stderr.txt b/Tests/RunCMake/Syntax/AtWithVariableAtOnly-stderr.txt
new file mode 100644
index 000000000..cbd1be472
--- /dev/null
+++ b/Tests/RunCMake/Syntax/AtWithVariableAtOnly-stderr.txt
@@ -0,0 +1 @@
+-->\${right}<--
diff --git a/Tests/RunCMake/Syntax/AtWithVariableAtOnly.cmake b/Tests/RunCMake/Syntax/AtWithVariableAtOnly.cmake
new file mode 100644
index 000000000..e06484c22
--- /dev/null
+++ b/Tests/RunCMake/Syntax/AtWithVariableAtOnly.cmake
@@ -0,0 +1,8 @@
+set(right "wrong")
+set(var "\${right}")
+# Expanded here.
+set(ref "@var@")
+
+# No dereference done at all.
+string(CONFIGURE "${ref}" output @ONLY)
+message("-->${output}<--")
diff --git a/Tests/RunCMake/Syntax/AtWithVariableAtOnlyFile-stderr.txt b/Tests/RunCMake/Syntax/AtWithVariableAtOnlyFile-stderr.txt
new file mode 100644
index 000000000..90bffb6c8
--- /dev/null
+++ b/Tests/RunCMake/Syntax/AtWithVariableAtOnlyFile-stderr.txt
@@ -0,0 +1,5 @@
+-->==>\${right}<==
+==><==
+==>\${var}<==
+==>\${empty}<==
+<--
diff --git a/Tests/RunCMake/Syntax/AtWithVariableAtOnlyFile.cmake b/Tests/RunCMake/Syntax/AtWithVariableAtOnlyFile.cmake
new file mode 100644
index 000000000..bdd7bcd25
--- /dev/null
+++ b/Tests/RunCMake/Syntax/AtWithVariableAtOnlyFile.cmake
@@ -0,0 +1,9 @@
+set(right "wrong")
+set(var "\${right}")
+
+configure_file(
+ "${CMAKE_CURRENT_SOURCE_DIR}/atfile.txt.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/atfile.txt"
+ @ONLY)
+file(READ "${CMAKE_CURRENT_BINARY_DIR}/atfile.txt" output)
+message("-->${output}<--")
diff --git a/Tests/RunCMake/Syntax/AtWithVariableEmptyExpansion-stderr.txt b/Tests/RunCMake/Syntax/AtWithVariableEmptyExpansion-stderr.txt
new file mode 100644
index 000000000..cbd1be472
--- /dev/null
+++ b/Tests/RunCMake/Syntax/AtWithVariableEmptyExpansion-stderr.txt
@@ -0,0 +1 @@
+-->\${right}<--
diff --git a/Tests/RunCMake/Syntax/AtWithVariableEmptyExpansion.cmake b/Tests/RunCMake/Syntax/AtWithVariableEmptyExpansion.cmake
new file mode 100644
index 000000000..840c7f0d6
--- /dev/null
+++ b/Tests/RunCMake/Syntax/AtWithVariableEmptyExpansion.cmake
@@ -0,0 +1,8 @@
+# Literal since 'var' is not defined.
+set(ref "@var@")
+set(right "wrong")
+set(var "\${right}")
+
+# 'var' is dereferenced here.
+string(CONFIGURE "${ref}" output)
+message("-->${output}<--")
diff --git a/Tests/RunCMake/Syntax/AtWithVariableEmptyExpansionAtOnly-stderr.txt b/Tests/RunCMake/Syntax/AtWithVariableEmptyExpansionAtOnly-stderr.txt
new file mode 100644
index 000000000..cbd1be472
--- /dev/null
+++ b/Tests/RunCMake/Syntax/AtWithVariableEmptyExpansionAtOnly-stderr.txt
@@ -0,0 +1 @@
+-->\${right}<--
diff --git a/Tests/RunCMake/Syntax/AtWithVariableEmptyExpansionAtOnly.cmake b/Tests/RunCMake/Syntax/AtWithVariableEmptyExpansionAtOnly.cmake
new file mode 100644
index 000000000..b657506be
--- /dev/null
+++ b/Tests/RunCMake/Syntax/AtWithVariableEmptyExpansionAtOnly.cmake
@@ -0,0 +1,8 @@
+# Literal since 'var' is not defined.
+set(ref "@var@")
+set(right "wrong")
+set(var "\${right}")
+
+# 'var' is dereferenced, but now 'right'
+string(CONFIGURE "${ref}" output @ONLY)
+message("-->${output}<--")
diff --git a/Tests/RunCMake/Syntax/AtWithVariableFile-stderr.txt b/Tests/RunCMake/Syntax/AtWithVariableFile-stderr.txt
new file mode 100644
index 000000000..43f029fe0
--- /dev/null
+++ b/Tests/RunCMake/Syntax/AtWithVariableFile-stderr.txt
@@ -0,0 +1,5 @@
+-->==>\${right}<==
+==><==
+==>\${right}<==
+==><==
+<--
diff --git a/Tests/RunCMake/Syntax/AtWithVariableFile.cmake b/Tests/RunCMake/Syntax/AtWithVariableFile.cmake
new file mode 100644
index 000000000..c70909928
--- /dev/null
+++ b/Tests/RunCMake/Syntax/AtWithVariableFile.cmake
@@ -0,0 +1,8 @@
+set(right "wrong")
+set(var "\${right}")
+
+configure_file(
+ "${CMAKE_CURRENT_SOURCE_DIR}/atfile.txt.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/atfile.txt")
+file(READ "${CMAKE_CURRENT_BINARY_DIR}/atfile.txt" output)
+message("-->${output}<--")
diff --git a/Tests/RunCMake/Syntax/BOM-UTF-16-BE-result.txt b/Tests/RunCMake/Syntax/BOM-UTF-16-BE-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BOM-UTF-16-BE-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/BOM-UTF-16-BE-stderr.txt b/Tests/RunCMake/Syntax/BOM-UTF-16-BE-stderr.txt
new file mode 100644
index 000000000..a845ffb1d
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BOM-UTF-16-BE-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error in BOM-UTF-16-BE.cmake:
+ File
+
+ .*/Tests/RunCMake/Syntax/BOM-UTF-16-BE.cmake
+
+ starts with a Byte-Order-Mark that is not UTF-8.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BOM-UTF-16-BE.cmake b/Tests/RunCMake/Syntax/BOM-UTF-16-BE.cmake
new file mode 100644
index 000000000..c51f6e602
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BOM-UTF-16-BE.cmake
Binary files differ
diff --git a/Tests/RunCMake/Syntax/BOM-UTF-16-LE-result.txt b/Tests/RunCMake/Syntax/BOM-UTF-16-LE-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BOM-UTF-16-LE-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/BOM-UTF-16-LE-stderr.txt b/Tests/RunCMake/Syntax/BOM-UTF-16-LE-stderr.txt
new file mode 100644
index 000000000..cc4244b8f
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BOM-UTF-16-LE-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error in BOM-UTF-16-LE.cmake:
+ File
+
+ .*/Tests/RunCMake/Syntax/BOM-UTF-16-LE.cmake
+
+ starts with a Byte-Order-Mark that is not UTF-8.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BOM-UTF-16-LE.cmake b/Tests/RunCMake/Syntax/BOM-UTF-16-LE.cmake
new file mode 100644
index 000000000..b57446f25
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BOM-UTF-16-LE.cmake
Binary files differ
diff --git a/Tests/RunCMake/Syntax/BOM-UTF-32-BE-result.txt b/Tests/RunCMake/Syntax/BOM-UTF-32-BE-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BOM-UTF-32-BE-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/BOM-UTF-32-BE-stderr.txt b/Tests/RunCMake/Syntax/BOM-UTF-32-BE-stderr.txt
new file mode 100644
index 000000000..5f851bfa8
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BOM-UTF-32-BE-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error in BOM-UTF-32-BE.cmake:
+ File
+
+ .*/Tests/RunCMake/Syntax/BOM-UTF-32-BE.cmake
+
+ starts with a Byte-Order-Mark that is not UTF-8.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BOM-UTF-32-BE.cmake b/Tests/RunCMake/Syntax/BOM-UTF-32-BE.cmake
new file mode 100644
index 000000000..23c57f3e8
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BOM-UTF-32-BE.cmake
Binary files differ
diff --git a/Tests/RunCMake/Syntax/BOM-UTF-32-LE-result.txt b/Tests/RunCMake/Syntax/BOM-UTF-32-LE-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BOM-UTF-32-LE-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/BOM-UTF-32-LE-stderr.txt b/Tests/RunCMake/Syntax/BOM-UTF-32-LE-stderr.txt
new file mode 100644
index 000000000..d8fafd0ea
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BOM-UTF-32-LE-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error in BOM-UTF-32-LE.cmake:
+ File
+
+ .*/Tests/RunCMake/Syntax/BOM-UTF-32-LE.cmake
+
+ starts with a Byte-Order-Mark that is not UTF-8.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BOM-UTF-32-LE.cmake b/Tests/RunCMake/Syntax/BOM-UTF-32-LE.cmake
new file mode 100644
index 000000000..c330f5bcb
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BOM-UTF-32-LE.cmake
Binary files differ
diff --git a/Tests/RunCMake/Syntax/BOM-UTF-8-stdout.txt b/Tests/RunCMake/Syntax/BOM-UTF-8-stdout.txt
new file mode 100644
index 000000000..5776d6e81
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BOM-UTF-8-stdout.txt
@@ -0,0 +1 @@
+-- message
diff --git a/Tests/RunCMake/Syntax/BOM-UTF-8.cmake b/Tests/RunCMake/Syntax/BOM-UTF-8.cmake
new file mode 100644
index 000000000..bdff83be8
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BOM-UTF-8.cmake
@@ -0,0 +1 @@
+message(STATUS "message")
diff --git a/Tests/RunCMake/Syntax/Bracket0-stderr.txt b/Tests/RunCMake/Syntax/Bracket0-stderr.txt
new file mode 100644
index 000000000..39cc2bc81
--- /dev/null
+++ b/Tests/RunCMake/Syntax/Bracket0-stderr.txt
@@ -0,0 +1 @@
+^1 \${var} \\n 4$
diff --git a/Tests/RunCMake/Syntax/Bracket0.cmake b/Tests/RunCMake/Syntax/Bracket0.cmake
new file mode 100644
index 000000000..4bc017212
--- /dev/null
+++ b/Tests/RunCMake/Syntax/Bracket0.cmake
@@ -0,0 +1 @@
+message([[1 ${var} \n 4]])
diff --git a/Tests/RunCMake/Syntax/Bracket1-stderr.txt b/Tests/RunCMake/Syntax/Bracket1-stderr.txt
new file mode 100644
index 000000000..e1e13c194
--- /dev/null
+++ b/Tests/RunCMake/Syntax/Bracket1-stderr.txt
@@ -0,0 +1 @@
+^1 \${var} \\n 4\]==$
diff --git a/Tests/RunCMake/Syntax/Bracket1.cmake b/Tests/RunCMake/Syntax/Bracket1.cmake
new file mode 100644
index 000000000..587a57525
--- /dev/null
+++ b/Tests/RunCMake/Syntax/Bracket1.cmake
@@ -0,0 +1,2 @@
+message([==[1 ]==] [=[
+${var} \n 4]==]=])
diff --git a/Tests/RunCMake/Syntax/Bracket2-stdout.txt b/Tests/RunCMake/Syntax/Bracket2-stdout.txt
new file mode 100644
index 000000000..0f8aa2fbb
--- /dev/null
+++ b/Tests/RunCMake/Syntax/Bracket2-stdout.txt
@@ -0,0 +1,2 @@
+-- Bracket Argument 1
+-- Bracket Argument 2
diff --git a/Tests/RunCMake/Syntax/Bracket2.cmake b/Tests/RunCMake/Syntax/Bracket2.cmake
new file mode 100644
index 000000000..5c5feed1a
--- /dev/null
+++ b/Tests/RunCMake/Syntax/Bracket2.cmake
@@ -0,0 +1,2 @@
+message(STATUS [[Bracket Argument 1]] #[[Bracket Comment 1]])
+message(STATUS #[[Bracket Comment 2]] [[Bracket Argument 2]])
diff --git a/Tests/RunCMake/Syntax/BracketBackslash-result.txt b/Tests/RunCMake/Syntax/BracketBackslash-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketBackslash-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/BracketBackslash-stderr.txt b/Tests/RunCMake/Syntax/BracketBackslash-stderr.txt
new file mode 100644
index 000000000..b746953fc
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketBackslash-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at BracketBackslash.cmake:1 \(message\):
+ a\\
+
+ b
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/Syntax/BracketBackslash.cmake b/Tests/RunCMake/Syntax/BracketBackslash.cmake
new file mode 100644
index 000000000..5478e5d76
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketBackslash.cmake
@@ -0,0 +1,2 @@
+message(FATAL_ERROR [==[a\
+b]==])
diff --git a/Tests/RunCMake/Syntax/BracketCRLF-stderr.txt b/Tests/RunCMake/Syntax/BracketCRLF-stderr.txt
new file mode 100644
index 000000000..7aef26eca
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketCRLF-stderr.txt
@@ -0,0 +1 @@
+CRLF->LF worked
diff --git a/Tests/RunCMake/Syntax/BracketCRLF.cmake b/Tests/RunCMake/Syntax/BracketCRLF.cmake
new file mode 100644
index 000000000..bda0e17ef
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketCRLF.cmake
@@ -0,0 +1,8 @@
+if([[
+]] STREQUAL "" AND
+[[a
+b]] STREQUAL "a\nb")
+ message("CRLF->LF worked")
+else()
+ message(FATAL_ERROR "CRLF->LF failed")
+endif()
diff --git a/Tests/RunCMake/Syntax/BracketComment0-stdout.txt b/Tests/RunCMake/Syntax/BracketComment0-stdout.txt
new file mode 100644
index 000000000..c9c0be43b
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketComment0-stdout.txt
@@ -0,0 +1 @@
+-- The above FATAL_ERROR did not occur.
diff --git a/Tests/RunCMake/Syntax/BracketComment0.cmake b/Tests/RunCMake/Syntax/BracketComment0.cmake
new file mode 100644
index 000000000..0ee95de88
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketComment0.cmake
@@ -0,0 +1,5 @@
+#[=[
+#]]
+message(FATAL_ERROR "This is commented out.")
+#]==]=]
+message(STATUS "The above FATAL_ERROR did not occur.")
diff --git a/Tests/RunCMake/Syntax/BracketComment1-result.txt b/Tests/RunCMake/Syntax/BracketComment1-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketComment1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/BracketComment1-stderr.txt b/Tests/RunCMake/Syntax/BracketComment1-stderr.txt
new file mode 100644
index 000000000..a9373decc
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketComment1-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at BracketComment1.cmake:2 \(message\):
+ This is not commented out.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BracketComment1.cmake b/Tests/RunCMake/Syntax/BracketComment1.cmake
new file mode 100644
index 000000000..2ec9d2016
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketComment1.cmake
@@ -0,0 +1,3 @@
+##[[
+message(FATAL_ERROR "This is not commented out.")
+#]]
diff --git a/Tests/RunCMake/Syntax/BracketComment2-result.txt b/Tests/RunCMake/Syntax/BracketComment2-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketComment2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/BracketComment2-stderr.txt b/Tests/RunCMake/Syntax/BracketComment2-stderr.txt
new file mode 100644
index 000000000..7e982229a
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketComment2-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at BracketComment2.cmake:2 \(message\):
+ This is not commented out.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BracketComment2.cmake b/Tests/RunCMake/Syntax/BracketComment2.cmake
new file mode 100644
index 000000000..3eda32d34
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketComment2.cmake
@@ -0,0 +1,3 @@
+# [[
+message(FATAL_ERROR "This is not commented out.")
+#]]
diff --git a/Tests/RunCMake/Syntax/BracketComment3-stdout.txt b/Tests/RunCMake/Syntax/BracketComment3-stdout.txt
new file mode 100644
index 000000000..c9c0be43b
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketComment3-stdout.txt
@@ -0,0 +1 @@
+-- The above FATAL_ERROR did not occur.
diff --git a/Tests/RunCMake/Syntax/BracketComment3.cmake b/Tests/RunCMake/Syntax/BracketComment3.cmake
new file mode 100644
index 000000000..ffd03a931
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketComment3.cmake
@@ -0,0 +1,4 @@
+#[[Text on opening line
+message(FATAL_ERROR "This is commented out.")
+#]=]]
+message(STATUS "The above FATAL_ERROR did not occur.")
diff --git a/Tests/RunCMake/Syntax/BracketComment4-result.txt b/Tests/RunCMake/Syntax/BracketComment4-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketComment4-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/BracketComment4-stderr.txt b/Tests/RunCMake/Syntax/BracketComment4-stderr.txt
new file mode 100644
index 000000000..8ba32c22c
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketComment4-stderr.txt
@@ -0,0 +1,7 @@
+CMake Error: Error in cmake code at
+.*/Tests/RunCMake/Syntax/BracketComment4.cmake:3:
+Parse error. Expected a newline, got identifier with text "message".
+CMake Error at CMakeLists.txt:3 \(include\):
+ include could not find load file:
+
+ BracketComment4.cmake
diff --git a/Tests/RunCMake/Syntax/BracketComment4.cmake b/Tests/RunCMake/Syntax/BracketComment4.cmake
new file mode 100644
index 000000000..9d586f114
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketComment4.cmake
@@ -0,0 +1,3 @@
+#[[
+message(FATAL_ERROR "This is commented out.")
+#]] message(STATUS "This command not allowed here")
diff --git a/Tests/RunCMake/Syntax/BracketComment5-stdout.txt b/Tests/RunCMake/Syntax/BracketComment5-stdout.txt
new file mode 100644
index 000000000..c9c0be43b
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketComment5-stdout.txt
@@ -0,0 +1 @@
+-- The above FATAL_ERROR did not occur.
diff --git a/Tests/RunCMake/Syntax/BracketComment5.cmake b/Tests/RunCMake/Syntax/BracketComment5.cmake
new file mode 100644
index 000000000..dc9e6b48d
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketComment5.cmake
@@ -0,0 +1,11 @@
+#[[
+message(FATAL_ERROR "This is commented out.")
+#]] #[[
+message(FATAL_ERROR "This is commented out.")
+#]]#[[
+message(FATAL_ERROR "This is commented out.")
+#]] #message(FATAL_ERROR "This is commented out.")
+#[[
+message(FATAL_ERROR "This is commented out.")
+#]]#message(FATAL_ERROR "This is commented out.")
+message(STATUS "The above FATAL_ERROR did not occur.")
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace0-result.txt b/Tests/RunCMake/Syntax/BracketNoSpace0-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketNoSpace0-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace0-stderr.txt b/Tests/RunCMake/Syntax/BracketNoSpace0-stderr.txt
new file mode 100644
index 000000000..a28828004
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketNoSpace0-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error in BracketNoSpace0.cmake:
+ Syntax Error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/BracketNoSpace0.cmake:1:27
+
+ Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace0.cmake b/Tests/RunCMake/Syntax/BracketNoSpace0.cmake
new file mode 100644
index 000000000..1de145055
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketNoSpace0.cmake
@@ -0,0 +1 @@
+message(STATUS [[bracket]]unquoted)
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace1-result.txt b/Tests/RunCMake/Syntax/BracketNoSpace1-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketNoSpace1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace1-stderr.txt b/Tests/RunCMake/Syntax/BracketNoSpace1-stderr.txt
new file mode 100644
index 000000000..391e11b7e
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketNoSpace1-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error in BracketNoSpace1.cmake:
+ Syntax Error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/BracketNoSpace1.cmake:1:24
+
+ Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace1.cmake b/Tests/RunCMake/Syntax/BracketNoSpace1.cmake
new file mode 100644
index 000000000..7982bf3c6
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketNoSpace1.cmake
@@ -0,0 +1 @@
+message(STATUS "string"[[bracket]])
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace2-result.txt b/Tests/RunCMake/Syntax/BracketNoSpace2-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketNoSpace2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace2-stderr.txt b/Tests/RunCMake/Syntax/BracketNoSpace2-stderr.txt
new file mode 100644
index 000000000..acaf7fe6e
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketNoSpace2-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error in BracketNoSpace2.cmake:
+ Syntax Error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/BracketNoSpace2.cmake:1:44
+
+ Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace2.cmake b/Tests/RunCMake/Syntax/BracketNoSpace2.cmake
new file mode 100644
index 000000000..f1507f3ac
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketNoSpace2.cmake
@@ -0,0 +1 @@
+message(STATUS "string"#[[bracket comment]][[bracket]])
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace3-result.txt b/Tests/RunCMake/Syntax/BracketNoSpace3-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketNoSpace3-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace3-stderr.txt b/Tests/RunCMake/Syntax/BracketNoSpace3-stderr.txt
new file mode 100644
index 000000000..f12b2e50b
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketNoSpace3-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error in BracketNoSpace3.cmake:
+ Syntax Error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/BracketNoSpace3.cmake:1:45
+
+ Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace3.cmake b/Tests/RunCMake/Syntax/BracketNoSpace3.cmake
new file mode 100644
index 000000000..45dc900ea
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketNoSpace3.cmake
@@ -0,0 +1 @@
+message(STATUS "string" #[[bracket comment]][[bracket]])
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace4-result.txt b/Tests/RunCMake/Syntax/BracketNoSpace4-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketNoSpace4-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace4-stderr.txt b/Tests/RunCMake/Syntax/BracketNoSpace4-stderr.txt
new file mode 100644
index 000000000..71577632d
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketNoSpace4-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error in BracketNoSpace4.cmake:
+ Syntax Error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/BracketNoSpace4.cmake:1:44
+
+ Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace4.cmake b/Tests/RunCMake/Syntax/BracketNoSpace4.cmake
new file mode 100644
index 000000000..cb4ddbec8
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketNoSpace4.cmake
@@ -0,0 +1 @@
+message(STATUS "string"#[[bracket comment]]"string")
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace5-result.txt b/Tests/RunCMake/Syntax/BracketNoSpace5-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketNoSpace5-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace5-stderr.txt b/Tests/RunCMake/Syntax/BracketNoSpace5-stderr.txt
new file mode 100644
index 000000000..c13969ddc
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketNoSpace5-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error in BracketNoSpace5.cmake:
+ Syntax Error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/BracketNoSpace5.cmake:1:45
+
+ Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace5.cmake b/Tests/RunCMake/Syntax/BracketNoSpace5.cmake
new file mode 100644
index 000000000..c68452322
--- /dev/null
+++ b/Tests/RunCMake/Syntax/BracketNoSpace5.cmake
@@ -0,0 +1 @@
+message(STATUS "string" #[[bracket comment]]"string")
diff --git a/Tests/RunCMake/Syntax/BracketWarn-stderr.txt b/Tests/RunCMake/Syntax/BracketWarn-stderr.txt
deleted file mode 100644
index 4a9cca641..000000000
--- a/Tests/RunCMake/Syntax/BracketWarn-stderr.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-CMake Warning \(dev\) at CMakeLists.txt:3 \(include\):
- Syntax Warning in cmake code at
-
- .*/Tests/RunCMake/Syntax/BracketWarn.cmake:1:16
-
- A future version of CMake may treat unquoted argument:
-
- \[\[
-
- as an opening long bracket. Double-quote the argument.
-This warning is for project developers. Use -Wno-dev to suppress it.
-
-CMake Warning \(dev\) at CMakeLists.txt:3 \(include\):
- Syntax Warning in cmake code at
-
- .*/Tests/RunCMake/Syntax/BracketWarn.cmake:1:19
-
- A future version of CMake may treat unquoted argument:
-
- \[=\[
-
- as an opening long bracket. Double-quote the argument.
-This warning is for project developers. Use -Wno-dev to suppress it.
-
-CMake Warning \(dev\) at CMakeLists.txt:3 \(include\):
- Syntax Warning in cmake code at
-
- .*/Tests/RunCMake/Syntax/BracketWarn.cmake:1:27
-
- A future version of CMake may treat unquoted argument:
-
- \[==\[x
-
- as an opening long bracket. Double-quote the argument.
-This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/Syntax/BracketWarn-stdout.txt b/Tests/RunCMake/Syntax/BracketWarn-stdout.txt
deleted file mode 100644
index 01b2caaa4..000000000
--- a/Tests/RunCMake/Syntax/BracketWarn-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
--- \[\[\[=\[\[=x\[==\[x
diff --git a/Tests/RunCMake/Syntax/BracketWarn.cmake b/Tests/RunCMake/Syntax/BracketWarn.cmake
deleted file mode 100644
index 8f33946f0..000000000
--- a/Tests/RunCMake/Syntax/BracketWarn.cmake
+++ /dev/null
@@ -1 +0,0 @@
-message(STATUS [[ [=[ [=x [==[x)
diff --git a/Tests/RunCMake/Syntax/CMP0053-At-NEW-stderr.txt b/Tests/RunCMake/Syntax/CMP0053-At-NEW-stderr.txt
new file mode 100644
index 000000000..e3e533218
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-At-NEW-stderr.txt
@@ -0,0 +1 @@
+^-->\${right}<--$
diff --git a/Tests/RunCMake/Syntax/CMP0053-At-NEW.cmake b/Tests/RunCMake/Syntax/CMP0053-At-NEW.cmake
new file mode 100644
index 000000000..40dbe46c5
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-At-NEW.cmake
@@ -0,0 +1,9 @@
+cmake_policy(SET CMP0053 NEW)
+
+set(right "wrong")
+set(var "\${right}")
+# Not expanded here with the new policy.
+set(ref "@var@")
+
+string(CONFIGURE "${ref}" output)
+message("-->${output}<--")
diff --git a/Tests/RunCMake/Syntax/CMP0053-At-OLD-stderr.txt b/Tests/RunCMake/Syntax/CMP0053-At-OLD-stderr.txt
new file mode 100644
index 000000000..acfa30a25
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-At-OLD-stderr.txt
@@ -0,0 +1 @@
+^-->wrong<--$
diff --git a/Tests/RunCMake/Syntax/CMP0053-At-OLD.cmake b/Tests/RunCMake/Syntax/CMP0053-At-OLD.cmake
new file mode 100644
index 000000000..666f107b8
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-At-OLD.cmake
@@ -0,0 +1,9 @@
+cmake_policy(SET CMP0053 OLD)
+
+set(right "wrong")
+set(var "\${right}")
+# Expanded here with the old policy.
+set(ref "@var@")
+
+string(CONFIGURE "${ref}" output)
+message("-->${output}<--")
diff --git a/Tests/RunCMake/Syntax/CMP0053-At-WARN-newlines-stderr.txt b/Tests/RunCMake/Syntax/CMP0053-At-WARN-newlines-stderr.txt
new file mode 100644
index 000000000..ec3702115
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-At-WARN-newlines-stderr.txt
@@ -0,0 +1,27 @@
+^CMake Warning \(dev\) at CMP0053-At-WARN-newlines.cmake:4 \(set\):
+ Policy CMP0053 is not set: Simplify variable reference and escape sequence
+ evaluation. Run "cmake --help-policy CMP0053" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+
+ For input:
+
+ '
+ @var@
+ '
+
+ the old evaluation rules produce:
+
+ '
+ \${right}
+ '
+
+ but the new evaluation rules produce:
+
+ '
+ @var@
+ '
+
+ Using the old result for compatibility since the policy is not set.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/Syntax/CMP0053-At-WARN-newlines.cmake b/Tests/RunCMake/Syntax/CMP0053-At-WARN-newlines.cmake
new file mode 100644
index 000000000..c493505b1
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-At-WARN-newlines.cmake
@@ -0,0 +1,6 @@
+set(right "wrong")
+set(var "\${right}")
+# Expanded here with the old policy.
+set(ref "
+@var@
+")
diff --git a/Tests/RunCMake/Syntax/CMP0053-At-WARN-stderr.txt b/Tests/RunCMake/Syntax/CMP0053-At-WARN-stderr.txt
new file mode 100644
index 000000000..697b7b38a
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-At-WARN-stderr.txt
@@ -0,0 +1,21 @@
+^CMake Warning \(dev\) at CMP0053-At-WARN.cmake:4 \(set\):
+ Policy CMP0053 is not set: Simplify variable reference and escape sequence
+ evaluation. Run "cmake --help-policy CMP0053" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+
+ For input:
+
+ '@var@'
+
+ the old evaluation rules produce:
+
+ '\${right}'
+
+ but the new evaluation rules produce:
+
+ '@var@'
+
+ Using the old result for compatibility since the policy is not set.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/Syntax/CMP0053-At-WARN.cmake b/Tests/RunCMake/Syntax/CMP0053-At-WARN.cmake
new file mode 100644
index 000000000..19c7f5339
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-At-WARN.cmake
@@ -0,0 +1,4 @@
+set(right "wrong")
+set(var "\${right}")
+# Expanded here with the old policy.
+set(ref "@var@")
diff --git a/Tests/RunCMake/Syntax/CMP0053-NUL-stderr.txt b/Tests/RunCMake/Syntax/CMP0053-NUL-stderr.txt
new file mode 100644
index 000000000..09c7e7c7c
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NUL-stderr.txt
@@ -0,0 +1,56 @@
+^CMake Warning \(dev\) at CMP0053-NUL.cmake:1 \(set\):
+ Policy CMP0053 is not set: Simplify variable reference and escape sequence
+ evaluation. Run "cmake --help-policy CMP0053" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+
+ For input:
+
+ '\\0'
+
+ the old evaluation rules produce:
+
+ ''
+
+ but the new evaluation rules produce an error:
+
+ Syntax error in cmake code at
+ .*/Tests/RunCMake/Syntax/CMP0053-NUL.cmake:1
+ when parsing string
+ \\0
+ Invalid character escape '\\0'.
+
+ Using the old result for compatibility since the policy is not set.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at CMP0053-NUL.cmake:2 \(set\):
+ Policy CMP0053 is not set: Simplify variable reference and escape sequence
+ evaluation. Run "cmake --help-policy CMP0053" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+
+ For input:
+
+ '\\0'
+
+ the old evaluation rules produce:
+
+ ''
+
+ but the new evaluation rules produce an error:
+
+ Syntax error in cmake code at
+ .*/Tests/RunCMake/Syntax/CMP0053-NUL.cmake:2
+ when parsing string
+ \\0
+ Invalid character escape '\\0'.
+
+ Using the old result for compatibility since the policy is not set.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+--><--
+--><--
+--><--
+--><--$
diff --git a/Tests/RunCMake/Syntax/CMP0053-NUL.cmake b/Tests/RunCMake/Syntax/CMP0053-NUL.cmake
new file mode 100644
index 000000000..9ae090680
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NUL.cmake
@@ -0,0 +1,6 @@
+set(qnul "\0")
+set(nul \0)
+message(-->${nul}<--)
+message(-->${qnul}<--)
+message("-->${nul}<--")
+message("-->${qnul}<--")
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithCarriageReturn-result.txt b/Tests/RunCMake/Syntax/CMP0053-NameWithCarriageReturn-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithCarriageReturn-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithCarriageReturn-stderr.txt b/Tests/RunCMake/Syntax/CMP0053-NameWithCarriageReturn-stderr.txt
new file mode 100644
index 000000000..957577851
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithCarriageReturn-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at CMP0053-NameWithCarriageReturn.cmake:2 \(message\):
+ message called with incorrect number of arguments
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithCarriageReturn.cmake b/Tests/RunCMake/Syntax/CMP0053-NameWithCarriageReturn.cmake
new file mode 100644
index 000000000..b8a403d18
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithCarriageReturn.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0053 NEW)
+message(${var\rwith\rcarriagereturn})
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithCarriageReturnQuoted.cmake b/Tests/RunCMake/Syntax/CMP0053-NameWithCarriageReturnQuoted.cmake
new file mode 100644
index 000000000..bb0d93f09
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithCarriageReturnQuoted.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0053 NEW)
+message("${var\rwith\rcarriagereturn}")
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithEscapedSpaces-result.txt b/Tests/RunCMake/Syntax/CMP0053-NameWithEscapedSpaces-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithEscapedSpaces-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithEscapedSpaces-stderr.txt b/Tests/RunCMake/Syntax/CMP0053-NameWithEscapedSpaces-stderr.txt
new file mode 100644
index 000000000..df67d37fe
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithEscapedSpaces-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at CMP0053-NameWithEscapedSpaces.cmake:2 \(message\):
+ message called with incorrect number of arguments
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithEscapedSpaces.cmake b/Tests/RunCMake/Syntax/CMP0053-NameWithEscapedSpaces.cmake
new file mode 100644
index 000000000..805b2ca6f
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithEscapedSpaces.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0053 NEW)
+message(${var\ with\ escaped\ space})
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithEscapedSpacesQuoted.cmake b/Tests/RunCMake/Syntax/CMP0053-NameWithEscapedSpacesQuoted.cmake
new file mode 100644
index 000000000..58d8e8ff7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithEscapedSpacesQuoted.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0053 NEW)
+message("${var\ with\ escaped\ space}")
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithEscapedTabs-result.txt b/Tests/RunCMake/Syntax/CMP0053-NameWithEscapedTabs-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithEscapedTabs-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithEscapedTabs-stderr.txt b/Tests/RunCMake/Syntax/CMP0053-NameWithEscapedTabs-stderr.txt
new file mode 100644
index 000000000..059044fb8
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithEscapedTabs-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at CMP0053-NameWithEscapedTabs.cmake:2 \(message\):
+ message called with incorrect number of arguments
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithEscapedTabs.cmake b/Tests/RunCMake/Syntax/CMP0053-NameWithEscapedTabs.cmake
new file mode 100644
index 000000000..214ab5de2
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithEscapedTabs.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0053 NEW)
+message(${var\ with\ escaped\ tab})
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithEscapedTabsQuoted.cmake b/Tests/RunCMake/Syntax/CMP0053-NameWithEscapedTabsQuoted.cmake
new file mode 100644
index 000000000..aa5123f56
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithEscapedTabsQuoted.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0053 NEW)
+message("${var\ with\ escaped\ tab}")
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithNewline-result.txt b/Tests/RunCMake/Syntax/CMP0053-NameWithNewline-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithNewline-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithNewline-stderr.txt b/Tests/RunCMake/Syntax/CMP0053-NameWithNewline-stderr.txt
new file mode 100644
index 000000000..41f86e69b
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithNewline-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at CMP0053-NameWithNewline.cmake:2 \(message\):
+ message called with incorrect number of arguments
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithNewline.cmake b/Tests/RunCMake/Syntax/CMP0053-NameWithNewline.cmake
new file mode 100644
index 000000000..45b532e10
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithNewline.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0053 NEW)
+message(${var\nwith\nnewline})
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithNewlineQuoted.cmake b/Tests/RunCMake/Syntax/CMP0053-NameWithNewlineQuoted.cmake
new file mode 100644
index 000000000..6fe568db2
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithNewlineQuoted.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0053 NEW)
+message("${var\nwith\nnewline}")
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithSpaces-result.txt b/Tests/RunCMake/Syntax/CMP0053-NameWithSpaces-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithSpaces-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithSpaces-stderr.txt b/Tests/RunCMake/Syntax/CMP0053-NameWithSpaces-stderr.txt
new file mode 100644
index 000000000..95e8684c9
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithSpaces-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Error at CMP0053-NameWithSpaces.cmake:2 \(message\):
+ Syntax error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/CMP0053-NameWithSpaces.cmake:2
+
+ when parsing string
+
+ \${var
+
+ There is an unterminated variable reference.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithSpaces.cmake b/Tests/RunCMake/Syntax/CMP0053-NameWithSpaces.cmake
new file mode 100644
index 000000000..dae7d2548
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithSpaces.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0053 NEW)
+message(${var with space})
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithSpacesQuoted-result.txt b/Tests/RunCMake/Syntax/CMP0053-NameWithSpacesQuoted-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithSpacesQuoted-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithSpacesQuoted-stderr.txt b/Tests/RunCMake/Syntax/CMP0053-NameWithSpacesQuoted-stderr.txt
new file mode 100644
index 000000000..c4f3cfe91
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithSpacesQuoted-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Error at CMP0053-NameWithSpacesQuoted.cmake:2 \(message\):
+ Syntax error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/CMP0053-NameWithSpacesQuoted.cmake:2
+
+ when parsing string
+
+ \${var with space}
+
+ Invalid character \(' '\) in a variable name: 'var'
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithSpacesQuoted.cmake b/Tests/RunCMake/Syntax/CMP0053-NameWithSpacesQuoted.cmake
new file mode 100644
index 000000000..e252cff57
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithSpacesQuoted.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0053 NEW)
+message("${var with space}")
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithTabs-result.txt b/Tests/RunCMake/Syntax/CMP0053-NameWithTabs-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithTabs-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithTabs-stderr.txt b/Tests/RunCMake/Syntax/CMP0053-NameWithTabs-stderr.txt
new file mode 100644
index 000000000..b1678b383
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithTabs-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Error at CMP0053-NameWithTabs.cmake:2 \(message\):
+ Syntax error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/CMP0053-NameWithTabs.cmake:2
+
+ when parsing string
+
+ \${var
+
+ There is an unterminated variable reference.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithTabs.cmake b/Tests/RunCMake/Syntax/CMP0053-NameWithTabs.cmake
new file mode 100644
index 000000000..45e30457f
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithTabs.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0053 NEW)
+message(${var with tab})
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithTabsQuoted-result.txt b/Tests/RunCMake/Syntax/CMP0053-NameWithTabsQuoted-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithTabsQuoted-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithTabsQuoted-stderr.txt b/Tests/RunCMake/Syntax/CMP0053-NameWithTabsQuoted-stderr.txt
new file mode 100644
index 000000000..78adb5e21
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithTabsQuoted-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Error at CMP0053-NameWithTabsQuoted.cmake:2 \(message\):
+ Syntax error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/CMP0053-NameWithTabsQuoted.cmake:2
+
+ when parsing string
+
+ \${var with tab}
+
+ Invalid character \(' '\) in a variable name: 'var'
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/Syntax/CMP0053-NameWithTabsQuoted.cmake b/Tests/RunCMake/Syntax/CMP0053-NameWithTabsQuoted.cmake
new file mode 100644
index 000000000..498675fe4
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-NameWithTabsQuoted.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0053 NEW)
+message("${var with tab}")
diff --git a/Tests/RunCMake/Syntax/CMP0053-ParenInENV-stderr.txt b/Tests/RunCMake/Syntax/CMP0053-ParenInENV-stderr.txt
new file mode 100644
index 000000000..7020c7e73
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-ParenInENV-stderr.txt
@@ -0,0 +1 @@
+-->value<--
diff --git a/Tests/RunCMake/Syntax/CMP0053-ParenInENV.cmake b/Tests/RunCMake/Syntax/CMP0053-ParenInENV.cmake
new file mode 100644
index 000000000..b5cdf0fd1
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-ParenInENV.cmake
@@ -0,0 +1,3 @@
+cmake_policy(SET CMP0053 NEW)
+set("ENV{e(x)}" value)
+message(-->$ENV{e\(x\)}<--)
diff --git a/Tests/RunCMake/Syntax/CMP0053-ParenInQuotedENV-stderr.txt b/Tests/RunCMake/Syntax/CMP0053-ParenInQuotedENV-stderr.txt
new file mode 100644
index 000000000..7020c7e73
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-ParenInQuotedENV-stderr.txt
@@ -0,0 +1 @@
+-->value<--
diff --git a/Tests/RunCMake/Syntax/CMP0053-ParenInQuotedENV.cmake b/Tests/RunCMake/Syntax/CMP0053-ParenInQuotedENV.cmake
new file mode 100644
index 000000000..5559d4b9d
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-ParenInQuotedENV.cmake
@@ -0,0 +1,3 @@
+cmake_policy(SET CMP0053 NEW)
+set("ENV{e(x)}" value)
+message("-->$ENV{e\(x\)}<--")
diff --git a/Tests/RunCMake/Syntax/CMP0053-WARN-stderr.txt b/Tests/RunCMake/Syntax/CMP0053-WARN-stderr.txt
new file mode 100644
index 000000000..c7069390d
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-WARN-stderr.txt
@@ -0,0 +1,28 @@
+^CMake Warning \(dev\) at CMP0053-WARN.cmake:2 \(message\):
+ Policy CMP0053 is not set: Simplify variable reference and escape sequence
+ evaluation. Run "cmake --help-policy CMP0053" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+
+ For input:
+
+ '\\'
+
+ the old evaluation rules produce:
+
+ '\\'
+
+ but the new evaluation rules produce an error:
+
+ Syntax error in cmake code at
+ .*/Tests/RunCMake/Syntax/CMP0053-WARN.cmake:2
+ when parsing string
+ \\
+ Invalid character escape '\\' \(at end of input\).
+
+ Using the old result for compatibility since the policy is not set.
+Call Stack \(most recent call first\):
+ CMP0053-WARN.cmake:5 \(escape\)
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+\\$
diff --git a/Tests/RunCMake/Syntax/CMP0053-WARN.cmake b/Tests/RunCMake/Syntax/CMP0053-WARN.cmake
new file mode 100644
index 000000000..6e8b07bbe
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CMP0053-WARN.cmake
@@ -0,0 +1,5 @@
+macro (escape str)
+ message("${str}")
+endmacro ()
+
+escape("\\")
diff --git a/Tests/RunCMake/Syntax/CMakeLists.txt b/Tests/RunCMake/Syntax/CMakeLists.txt
index 618473aaa..4b3de84d9 100644
--- a/Tests/RunCMake/Syntax/CMakeLists.txt
+++ b/Tests/RunCMake/Syntax/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.9)
+cmake_minimum_required(VERSION 2.8.12)
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/Syntax/CommandError2-result.txt b/Tests/RunCMake/Syntax/CommandError2-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CommandError2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/CommandError2-stderr.txt b/Tests/RunCMake/Syntax/CommandError2-stderr.txt
new file mode 100644
index 000000000..f4dfc7749
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CommandError2-stderr.txt
@@ -0,0 +1,7 @@
+CMake Error: Error in cmake code at
+.*/Tests/RunCMake/Syntax/CommandError2.cmake:1:
+Parse error. Expected a command name, got bracket argument with text "oops-not-a-comment".
+CMake Error at CMakeLists.txt:3 \(include\):
+ include could not find load file:
+
+ CommandError2.cmake
diff --git a/Tests/RunCMake/Syntax/CommandError2.cmake b/Tests/RunCMake/Syntax/CommandError2.cmake
new file mode 100644
index 000000000..a269682a0
--- /dev/null
+++ b/Tests/RunCMake/Syntax/CommandError2.cmake
@@ -0,0 +1 @@
+message("Example Message") [[oops-not-a-comment]]
diff --git a/Tests/RunCMake/Syntax/Escape1-stderr.txt b/Tests/RunCMake/Syntax/Escape1-stderr.txt
new file mode 100644
index 000000000..6601ce764
--- /dev/null
+++ b/Tests/RunCMake/Syntax/Escape1-stderr.txt
@@ -0,0 +1,3 @@
+^\\##\[\[#\]\]#\[\[\]\]x#\\"
+\$\@\^\\; \(\)#\\"
+\$\@\^; \(\)$
diff --git a/Tests/RunCMake/Syntax/Escape1.cmake b/Tests/RunCMake/Syntax/Escape1.cmake
new file mode 100644
index 000000000..3bf801e64
--- /dev/null
+++ b/Tests/RunCMake/Syntax/Escape1.cmake
@@ -0,0 +1,3 @@
+message([[\#]] \#[[ \#]] "#[[]]" x#comment
+ "\#\\\"\n\$\@\^\;\ \t\(\)"#comment
+ \#\\\"\n\$\@\^\;\ \t\(\))
diff --git a/Tests/RunCMake/Syntax/Escape2-result.txt b/Tests/RunCMake/Syntax/Escape2-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/Escape2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/Escape2-stderr.txt b/Tests/RunCMake/Syntax/Escape2-stderr.txt
new file mode 100644
index 000000000..cc3bdf07b
--- /dev/null
+++ b/Tests/RunCMake/Syntax/Escape2-stderr.txt
@@ -0,0 +1,13 @@
+CMake Error at Escape2.cmake:4 \(message\):
+ Syntax error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/Escape2.cmake:4
+
+ when parsing string
+
+ \\
+
+ Invalid character escape '\\' \(at end of input\).
+Call Stack \(most recent call first\):
+ Escape2.cmake:7 \(escape\)
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/Escape2.cmake b/Tests/RunCMake/Syntax/Escape2.cmake
new file mode 100644
index 000000000..078a82289
--- /dev/null
+++ b/Tests/RunCMake/Syntax/Escape2.cmake
@@ -0,0 +1,7 @@
+cmake_policy(SET CMP0053 NEW)
+
+macro (escape str)
+ message("${str}")
+endmacro ()
+
+escape("\\")
diff --git a/Tests/RunCMake/Syntax/EscapeChar-char-result.txt b/Tests/RunCMake/Syntax/EscapeChar-char-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/EscapeChar-char-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/EscapeChar-char-stderr.txt.in b/Tests/RunCMake/Syntax/EscapeChar-char-stderr.txt.in
new file mode 100644
index 000000000..d1d908cbb
--- /dev/null
+++ b/Tests/RunCMake/Syntax/EscapeChar-char-stderr.txt.in
@@ -0,0 +1,12 @@
+CMake Error at EscapeChar-@char@-@testnum@.cmake:3 \(message\):
+ Syntax error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/EscapeChar-@char@-@testnum@.cmake:3
+
+ when parsing string
+
+ -->\\@char@<--
+
+ Invalid character escape '\\@char@'.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/EscapeChar-char.cmake.in b/Tests/RunCMake/Syntax/EscapeChar-char.cmake.in
new file mode 100644
index 000000000..6f265e5b2
--- /dev/null
+++ b/Tests/RunCMake/Syntax/EscapeChar-char.cmake.in
@@ -0,0 +1,3 @@
+cmake_policy(SET CMP0053 NEW)
+
+message("-->\@char@<--")
diff --git a/Tests/RunCMake/Syntax/EscapeCharsAllowed-stderr.txt b/Tests/RunCMake/Syntax/EscapeCharsAllowed-stderr.txt
new file mode 100644
index 000000000..e658de7c8
--- /dev/null
+++ b/Tests/RunCMake/Syntax/EscapeCharsAllowed-stderr.txt
@@ -0,0 +1,12 @@
+^-->semicolon<--
+-->dollar<--
+-->brace<--
+-->bracket<--
+-->newline<--
+-->octothorpe<--
+-->splat<--
+-->caret<--
+-->paren<--
+-->dquote<--
+-->top-levelsemicolon<--
+-->top-level;escaped;semicolon<--$
diff --git a/Tests/RunCMake/Syntax/EscapeCharsAllowed.cmake b/Tests/RunCMake/Syntax/EscapeCharsAllowed.cmake
new file mode 100644
index 000000000..e9c568da0
--- /dev/null
+++ b/Tests/RunCMake/Syntax/EscapeCharsAllowed.cmake
@@ -0,0 +1,26 @@
+cmake_policy(SET CMP0053 NEW)
+
+set("semicolon;in;name" semicolon)
+set("dollar$in$name" dollar)
+set("brace{in}name" brace)
+set("bracket[in]name" bracket)
+set("newline\nin\nname" newline)
+set("octothorpe\#in\#name" octothorpe)
+set("splat\@in\@name" splat)
+set("caret\^in\^name" caret)
+set("paren\(in\)name" paren)
+set("dquote\"in\"name" dquote)
+
+message("-->${semicolon\;in\;name}<--")
+message("-->${dollar\$in\$name}<--")
+message("-->${brace\{in\}name}<--")
+message("-->${bracket\[in\]name}<--")
+message("-->${newline\nin\nname}<--")
+message("-->${octothorpe\#in\#name}<--")
+message("-->${splat\@in\@name}<--")
+message("-->${caret\^in\^name}<--")
+message("-->${paren\(in\)name}<--")
+message("-->${dquote\"in\"name}<--")
+
+message(-->top-level;semicolon<--)
+message(-->top-level\;escaped\;semicolon<--)
diff --git a/Tests/RunCMake/Syntax/EscapeCharsDisallowed.cmake b/Tests/RunCMake/Syntax/EscapeCharsDisallowed.cmake
new file mode 100644
index 000000000..eef01a082
--- /dev/null
+++ b/Tests/RunCMake/Syntax/EscapeCharsDisallowed.cmake
@@ -0,0 +1,42 @@
+set(disallowed_chars
+ a b c d e f g h i j l m o p q s u v w x y z
+ A B C D E F G H I J L M N O P Q R S T U V W X Y Z
+ 0 1 2 3 4 5 6 6 7 8 9)
+set(testnum 0)
+
+configure_file(
+ "${RunCMake_SOURCE_DIR}/CMakeLists.txt"
+ "${RunCMake_BINARY_DIR}/CMakeLists.txt"
+ COPYONLY)
+
+foreach (char IN LISTS disallowed_chars)
+ configure_file(
+ "${RunCMake_SOURCE_DIR}/EscapeChar-char.cmake.in"
+ "${RunCMake_BINARY_DIR}/EscapeChar-${char}-${testnum}.cmake"
+ @ONLY)
+ configure_file(
+ "${RunCMake_SOURCE_DIR}/EscapeChar-char-stderr.txt.in"
+ "${RunCMake_BINARY_DIR}/EscapeChar-${char}-${testnum}-stderr.txt"
+ @ONLY)
+ configure_file(
+ "${RunCMake_SOURCE_DIR}/EscapeChar-char-result.txt"
+ "${RunCMake_BINARY_DIR}/EscapeChar-${char}-${testnum}-result.txt"
+ COPYONLY)
+
+ math(EXPR testnum "${testnum} + 1")
+endforeach ()
+
+function (run_tests)
+ set(GENERATED_RUNCMAKE_TESTS TRUE)
+ # Find the tests in the binary directory.
+ set(RunCMake_SOURCE_DIR "${RunCMake_BINARY_DIR}")
+
+ set(testnum 0)
+ foreach (char IN LISTS disallowed_chars)
+ run_cmake("EscapeChar-${char}-${testnum}")
+
+ math(EXPR testnum "${testnum} + 1")
+ endforeach ()
+endfunction ()
+
+run_tests()
diff --git a/Tests/RunCMake/Syntax/EscapeQuotes-stderr.txt b/Tests/RunCMake/Syntax/EscapeQuotes-stderr.txt
new file mode 100644
index 000000000..077272d4b
--- /dev/null
+++ b/Tests/RunCMake/Syntax/EscapeQuotes-stderr.txt
@@ -0,0 +1 @@
+-->"<--
diff --git a/Tests/RunCMake/Syntax/EscapeQuotes.cmake b/Tests/RunCMake/Syntax/EscapeQuotes.cmake
new file mode 100644
index 000000000..46d2b6f47
--- /dev/null
+++ b/Tests/RunCMake/Syntax/EscapeQuotes.cmake
@@ -0,0 +1,9 @@
+set(var "\"")
+set(ref "@var@")
+set(rref "\${var}")
+
+string(CONFIGURE "${ref}" output ESCAPE_QUOTES)
+message("-->${output}<--")
+
+string(CONFIGURE "${rref}" output ESCAPE_QUOTES)
+message("-->${output}<--")
diff --git a/Tests/RunCMake/Syntax/EscapedAt-stderr.txt b/Tests/RunCMake/Syntax/EscapedAt-stderr.txt
new file mode 100644
index 000000000..a51c0d3fa
--- /dev/null
+++ b/Tests/RunCMake/Syntax/EscapedAt-stderr.txt
@@ -0,0 +1 @@
+-->\\n<--
diff --git a/Tests/RunCMake/Syntax/EscapedAt.cmake b/Tests/RunCMake/Syntax/EscapedAt.cmake
new file mode 100644
index 000000000..1ced62085
--- /dev/null
+++ b/Tests/RunCMake/Syntax/EscapedAt.cmake
@@ -0,0 +1,5 @@
+set(var "n")
+set(ref "\\@var@")
+
+string(CONFIGURE "${ref}" output)
+message("-->${output}<--")
diff --git a/Tests/RunCMake/Syntax/ExpandInAt-stderr.txt b/Tests/RunCMake/Syntax/ExpandInAt-stderr.txt
new file mode 100644
index 000000000..5da8b60c5
--- /dev/null
+++ b/Tests/RunCMake/Syntax/ExpandInAt-stderr.txt
@@ -0,0 +1 @@
+-->@foo@<--
diff --git a/Tests/RunCMake/Syntax/ExpandInAt.cmake b/Tests/RunCMake/Syntax/ExpandInAt.cmake
new file mode 100644
index 000000000..98f0277da
--- /dev/null
+++ b/Tests/RunCMake/Syntax/ExpandInAt.cmake
@@ -0,0 +1,6 @@
+set("\${varname}" bar)
+set(var foo)
+set(ref "@\${var}@")
+
+string(CONFIGURE "${ref}" output)
+message("-->${output}<--")
diff --git a/Tests/RunCMake/Syntax/ForEachBracket1-stderr.txt b/Tests/RunCMake/Syntax/ForEachBracket1-stderr.txt
new file mode 100644
index 000000000..93c31cf05
--- /dev/null
+++ b/Tests/RunCMake/Syntax/ForEachBracket1-stderr.txt
@@ -0,0 +1,2 @@
+^\${x}:a
+\${x}:b$
diff --git a/Tests/RunCMake/Syntax/ForEachBracket1.cmake b/Tests/RunCMake/Syntax/ForEachBracket1.cmake
new file mode 100644
index 000000000..a55e21f07
--- /dev/null
+++ b/Tests/RunCMake/Syntax/ForEachBracket1.cmake
@@ -0,0 +1,3 @@
+foreach(x a b)
+ message([[${x}:]] "${x}")
+endforeach()
diff --git a/Tests/RunCMake/Syntax/FunctionBracket1-stderr.txt b/Tests/RunCMake/Syntax/FunctionBracket1-stderr.txt
new file mode 100644
index 000000000..9ba6179a3
--- /dev/null
+++ b/Tests/RunCMake/Syntax/FunctionBracket1-stderr.txt
@@ -0,0 +1,2 @@
+^\${x},\${ARGN},\${ARGC},\${ARGV},\${ARGV0},\${ARGV1},\${ARGV2}:a,n,2,a;n,a,n,
+\${x},\${ARGN},\${ARGC},\${ARGV},\${ARGV0},\${ARGV1},\${ARGV2}:b,n,2,b;n,b,n,$
diff --git a/Tests/RunCMake/Syntax/FunctionBracket1.cmake b/Tests/RunCMake/Syntax/FunctionBracket1.cmake
new file mode 100644
index 000000000..8ed4f6506
--- /dev/null
+++ b/Tests/RunCMake/Syntax/FunctionBracket1.cmake
@@ -0,0 +1,6 @@
+function(fun x)
+ message([[${x},${ARGN},${ARGC},${ARGV},${ARGV0},${ARGV1},${ARGV2}:]]
+ "${x},${ARGN},${ARGC},${ARGV},${ARGV0},${ARGV1},${ARGV2}")
+endfunction(fun)
+fun(a n)
+fun(b n)
diff --git a/Tests/RunCMake/Syntax/FunctionUnmatched-result.txt b/Tests/RunCMake/Syntax/FunctionUnmatched-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/FunctionUnmatched-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/FunctionUnmatched-stderr.txt b/Tests/RunCMake/Syntax/FunctionUnmatched-stderr.txt
new file mode 100644
index 000000000..776a8f260
--- /dev/null
+++ b/Tests/RunCMake/Syntax/FunctionUnmatched-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Error at CMakeLists.txt:[0-9]+ \(include\):
+ A logical block opening on the line
+
+ .*/Tests/RunCMake/Syntax/FunctionUnmatched.cmake:[0-9]+ \(function\)
+
+ is not closed.$
diff --git a/Tests/RunCMake/Syntax/FunctionUnmatched.cmake b/Tests/RunCMake/Syntax/FunctionUnmatched.cmake
new file mode 100644
index 000000000..515b6bf63
--- /dev/null
+++ b/Tests/RunCMake/Syntax/FunctionUnmatched.cmake
@@ -0,0 +1,2 @@
+function(f)
+#endfunction() # missing
diff --git a/Tests/RunCMake/Syntax/FunctionUnmatchedForeach-result.txt b/Tests/RunCMake/Syntax/FunctionUnmatchedForeach-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/FunctionUnmatchedForeach-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/FunctionUnmatchedForeach-stderr.txt b/Tests/RunCMake/Syntax/FunctionUnmatchedForeach-stderr.txt
new file mode 100644
index 000000000..f4ff70945
--- /dev/null
+++ b/Tests/RunCMake/Syntax/FunctionUnmatchedForeach-stderr.txt
@@ -0,0 +1,8 @@
+^CMake Error at FunctionUnmatchedForeach.cmake:[0-9]+ \(f\):
+ A logical block opening on the line
+
+ .*/Tests/RunCMake/Syntax/FunctionUnmatchedForeach.cmake:[0-9]+ \(foreach\)
+
+ is not closed.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/Syntax/FunctionUnmatchedForeach.cmake b/Tests/RunCMake/Syntax/FunctionUnmatchedForeach.cmake
new file mode 100644
index 000000000..ee9c18459
--- /dev/null
+++ b/Tests/RunCMake/Syntax/FunctionUnmatchedForeach.cmake
@@ -0,0 +1,5 @@
+function(f)
+ foreach(i 1)
+ #endforeach() # missing
+endfunction()
+f()
diff --git a/Tests/RunCMake/Syntax/MacroBracket1-stderr.txt b/Tests/RunCMake/Syntax/MacroBracket1-stderr.txt
new file mode 100644
index 000000000..9ba6179a3
--- /dev/null
+++ b/Tests/RunCMake/Syntax/MacroBracket1-stderr.txt
@@ -0,0 +1,2 @@
+^\${x},\${ARGN},\${ARGC},\${ARGV},\${ARGV0},\${ARGV1},\${ARGV2}:a,n,2,a;n,a,n,
+\${x},\${ARGN},\${ARGC},\${ARGV},\${ARGV0},\${ARGV1},\${ARGV2}:b,n,2,b;n,b,n,$
diff --git a/Tests/RunCMake/Syntax/MacroBracket1.cmake b/Tests/RunCMake/Syntax/MacroBracket1.cmake
new file mode 100644
index 000000000..ef6de20ab
--- /dev/null
+++ b/Tests/RunCMake/Syntax/MacroBracket1.cmake
@@ -0,0 +1,6 @@
+macro(mac x)
+ message([[${x},${ARGN},${ARGC},${ARGV},${ARGV0},${ARGV1},${ARGV2}:]]
+ "${x},${ARGN},${ARGC},${ARGV},${ARGV0},${ARGV1},${ARGV2}")
+endmacro(mac)
+mac(a n)
+mac(b n)
diff --git a/Tests/RunCMake/Syntax/MacroUnmatched-result.txt b/Tests/RunCMake/Syntax/MacroUnmatched-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/MacroUnmatched-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/MacroUnmatched-stderr.txt b/Tests/RunCMake/Syntax/MacroUnmatched-stderr.txt
new file mode 100644
index 000000000..1699c436d
--- /dev/null
+++ b/Tests/RunCMake/Syntax/MacroUnmatched-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Error at CMakeLists.txt:[0-9]+ \(include\):
+ A logical block opening on the line
+
+ .*/Tests/RunCMake/Syntax/MacroUnmatched.cmake:[0-9]+ \(macro\)
+
+ is not closed.$
diff --git a/Tests/RunCMake/Syntax/MacroUnmatched.cmake b/Tests/RunCMake/Syntax/MacroUnmatched.cmake
new file mode 100644
index 000000000..302d96ec3
--- /dev/null
+++ b/Tests/RunCMake/Syntax/MacroUnmatched.cmake
@@ -0,0 +1,2 @@
+macro(m)
+#endmacro() # missing
diff --git a/Tests/RunCMake/Syntax/MacroUnmatchedForeach-result.txt b/Tests/RunCMake/Syntax/MacroUnmatchedForeach-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/MacroUnmatchedForeach-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/MacroUnmatchedForeach-stderr.txt b/Tests/RunCMake/Syntax/MacroUnmatchedForeach-stderr.txt
new file mode 100644
index 000000000..820cd2e5a
--- /dev/null
+++ b/Tests/RunCMake/Syntax/MacroUnmatchedForeach-stderr.txt
@@ -0,0 +1,8 @@
+^CMake Error at MacroUnmatchedForeach.cmake:[0-9]+ \(m\):
+ A logical block opening on the line
+
+ .*/Tests/RunCMake/Syntax/MacroUnmatchedForeach.cmake:[0-9]+ \(foreach\)
+
+ is not closed.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/Syntax/MacroUnmatchedForeach.cmake b/Tests/RunCMake/Syntax/MacroUnmatchedForeach.cmake
new file mode 100644
index 000000000..be443dd9b
--- /dev/null
+++ b/Tests/RunCMake/Syntax/MacroUnmatchedForeach.cmake
@@ -0,0 +1,5 @@
+macro(m)
+ foreach(i 1)
+ #endforeach() # missing
+endmacro()
+m()
diff --git a/Tests/RunCMake/Syntax/NameWithCarriageReturn-result.txt b/Tests/RunCMake/Syntax/NameWithCarriageReturn-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithCarriageReturn-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/NameWithCarriageReturn-stderr.txt b/Tests/RunCMake/Syntax/NameWithCarriageReturn-stderr.txt
new file mode 100644
index 000000000..7448b59cc
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithCarriageReturn-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Error at NameWithCarriageReturn.cmake:1 \(message\):
+ Syntax error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/NameWithCarriageReturn.cmake:1
+
+ when parsing string
+
+ \${var\\rwith\\rcarriagereturn}
+
+ syntax error, unexpected cal_SYMBOL, expecting } \(7\)
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/Syntax/NameWithCarriageReturn.cmake b/Tests/RunCMake/Syntax/NameWithCarriageReturn.cmake
new file mode 100644
index 000000000..614f554bf
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithCarriageReturn.cmake
@@ -0,0 +1 @@
+message(${var\rwith\rcarriagereturn})
diff --git a/Tests/RunCMake/Syntax/NameWithCarriageReturnQuoted-result.txt b/Tests/RunCMake/Syntax/NameWithCarriageReturnQuoted-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithCarriageReturnQuoted-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/NameWithCarriageReturnQuoted-stderr.txt b/Tests/RunCMake/Syntax/NameWithCarriageReturnQuoted-stderr.txt
new file mode 100644
index 000000000..f5e03edb2
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithCarriageReturnQuoted-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Error at NameWithCarriageReturnQuoted.cmake:1 \(message\):
+ Syntax error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/NameWithCarriageReturnQuoted.cmake:1
+
+ when parsing string
+
+ \${var\\rwith\\rcarriagereturn}
+
+ syntax error, unexpected cal_SYMBOL, expecting } \(7\)
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/Syntax/NameWithCarriageReturnQuoted.cmake b/Tests/RunCMake/Syntax/NameWithCarriageReturnQuoted.cmake
new file mode 100644
index 000000000..bac69e4ee
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithCarriageReturnQuoted.cmake
@@ -0,0 +1 @@
+message("${var\rwith\rcarriagereturn}")
diff --git a/Tests/RunCMake/Syntax/NameWithEscapedSpaces-result.txt b/Tests/RunCMake/Syntax/NameWithEscapedSpaces-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithEscapedSpaces-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/NameWithEscapedSpaces-stderr.txt b/Tests/RunCMake/Syntax/NameWithEscapedSpaces-stderr.txt
new file mode 100644
index 000000000..fa16a8a5f
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithEscapedSpaces-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Error at NameWithEscapedSpaces.cmake:1 \(message\):
+ Syntax error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/NameWithEscapedSpaces.cmake:1
+
+ when parsing string
+
+ \${var\\ with\\ escaped\\ space}
+
+ syntax error, unexpected cal_SYMBOL, expecting } \(7\)
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/Syntax/NameWithEscapedSpaces.cmake b/Tests/RunCMake/Syntax/NameWithEscapedSpaces.cmake
new file mode 100644
index 000000000..6cb84014d
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithEscapedSpaces.cmake
@@ -0,0 +1 @@
+message(${var\ with\ escaped\ space})
diff --git a/Tests/RunCMake/Syntax/NameWithEscapedSpacesQuoted-result.txt b/Tests/RunCMake/Syntax/NameWithEscapedSpacesQuoted-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithEscapedSpacesQuoted-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/NameWithEscapedSpacesQuoted-stderr.txt b/Tests/RunCMake/Syntax/NameWithEscapedSpacesQuoted-stderr.txt
new file mode 100644
index 000000000..07cbf24c5
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithEscapedSpacesQuoted-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Error at NameWithEscapedSpacesQuoted.cmake:1 \(message\):
+ Syntax error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/NameWithEscapedSpacesQuoted.cmake:1
+
+ when parsing string
+
+ \${var\\ with\\ escaped\\ space}
+
+ syntax error, unexpected cal_SYMBOL, expecting } \(7\)
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/Syntax/NameWithEscapedSpacesQuoted.cmake b/Tests/RunCMake/Syntax/NameWithEscapedSpacesQuoted.cmake
new file mode 100644
index 000000000..2bd4bfd7a
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithEscapedSpacesQuoted.cmake
@@ -0,0 +1 @@
+message("${var\ with\ escaped\ space}")
diff --git a/Tests/RunCMake/Syntax/NameWithEscapedTabs-result.txt b/Tests/RunCMake/Syntax/NameWithEscapedTabs-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithEscapedTabs-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/NameWithEscapedTabs-stderr.txt b/Tests/RunCMake/Syntax/NameWithEscapedTabs-stderr.txt
new file mode 100644
index 000000000..d7fc38a0a
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithEscapedTabs-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Error at NameWithEscapedTabs.cmake:1 \(message\):
+ Syntax error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/NameWithEscapedTabs.cmake:1
+
+ when parsing string
+
+ \${var\\ with\\ escaped\\ tab}
+
+ Invalid escape sequence \\.?
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/Syntax/NameWithEscapedTabs.cmake b/Tests/RunCMake/Syntax/NameWithEscapedTabs.cmake
new file mode 100644
index 000000000..c6faa7ab4
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithEscapedTabs.cmake
@@ -0,0 +1 @@
+message(${var\ with\ escaped\ tab})
diff --git a/Tests/RunCMake/Syntax/NameWithEscapedTabsQuoted-result.txt b/Tests/RunCMake/Syntax/NameWithEscapedTabsQuoted-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithEscapedTabsQuoted-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/NameWithEscapedTabsQuoted-stderr.txt b/Tests/RunCMake/Syntax/NameWithEscapedTabsQuoted-stderr.txt
new file mode 100644
index 000000000..915dbaa47
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithEscapedTabsQuoted-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Error at NameWithEscapedTabsQuoted.cmake:1 \(message\):
+ Syntax error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/NameWithEscapedTabsQuoted.cmake:1
+
+ when parsing string
+
+ \${var\\ with\\ escaped\\ tab}
+
+ Invalid escape sequence \\.?
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/Syntax/NameWithEscapedTabsQuoted.cmake b/Tests/RunCMake/Syntax/NameWithEscapedTabsQuoted.cmake
new file mode 100644
index 000000000..d9be7634a
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithEscapedTabsQuoted.cmake
@@ -0,0 +1 @@
+message("${var\ with\ escaped\ tab}")
diff --git a/Tests/RunCMake/Syntax/NameWithNewline-result.txt b/Tests/RunCMake/Syntax/NameWithNewline-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithNewline-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/NameWithNewline-stderr.txt b/Tests/RunCMake/Syntax/NameWithNewline-stderr.txt
new file mode 100644
index 000000000..5cc111b5c
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithNewline-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Error at NameWithNewline.cmake:1 \(message\):
+ Syntax error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/NameWithNewline.cmake:1
+
+ when parsing string
+
+ \${var\\nwith\\nnewline}
+
+ syntax error, unexpected cal_SYMBOL, expecting } \(7\)
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/Syntax/NameWithNewline.cmake b/Tests/RunCMake/Syntax/NameWithNewline.cmake
new file mode 100644
index 000000000..583bcb05f
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithNewline.cmake
@@ -0,0 +1 @@
+message(${var\nwith\nnewline})
diff --git a/Tests/RunCMake/Syntax/NameWithNewlineQuoted-result.txt b/Tests/RunCMake/Syntax/NameWithNewlineQuoted-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithNewlineQuoted-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/NameWithNewlineQuoted-stderr.txt b/Tests/RunCMake/Syntax/NameWithNewlineQuoted-stderr.txt
new file mode 100644
index 000000000..0067c2f3a
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithNewlineQuoted-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Error at NameWithNewlineQuoted.cmake:1 \(message\):
+ Syntax error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/NameWithNewlineQuoted.cmake:1
+
+ when parsing string
+
+ \${var\\nwith\\nnewline}
+
+ syntax error, unexpected cal_SYMBOL, expecting } \(7\)
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/Syntax/NameWithNewlineQuoted.cmake b/Tests/RunCMake/Syntax/NameWithNewlineQuoted.cmake
new file mode 100644
index 000000000..da6d2cf8d
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithNewlineQuoted.cmake
@@ -0,0 +1 @@
+message("${var\nwith\nnewline}")
diff --git a/Tests/RunCMake/Syntax/NameWithSpaces-result.txt b/Tests/RunCMake/Syntax/NameWithSpaces-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithSpaces-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/NameWithSpaces-stderr.txt b/Tests/RunCMake/Syntax/NameWithSpaces-stderr.txt
new file mode 100644
index 000000000..04bc2260a
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithSpaces-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Error at NameWithSpaces.cmake:1 \(message\):
+ Syntax error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/NameWithSpaces.cmake:1
+
+ when parsing string
+
+ \${var
+
+ syntax error, unexpected \$end, expecting } \(5\)
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/Syntax/NameWithSpaces.cmake b/Tests/RunCMake/Syntax/NameWithSpaces.cmake
new file mode 100644
index 000000000..01febe9ee
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithSpaces.cmake
@@ -0,0 +1 @@
+message(${var with space})
diff --git a/Tests/RunCMake/Syntax/NameWithSpacesQuoted-result.txt b/Tests/RunCMake/Syntax/NameWithSpacesQuoted-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithSpacesQuoted-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/NameWithSpacesQuoted-stderr.txt b/Tests/RunCMake/Syntax/NameWithSpacesQuoted-stderr.txt
new file mode 100644
index 000000000..66cf9a26a
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithSpacesQuoted-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Error at NameWithSpacesQuoted.cmake:1 \(message\):
+ Syntax error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/NameWithSpacesQuoted.cmake:1
+
+ when parsing string
+
+ \${var with space}
+
+ syntax error, unexpected cal_SYMBOL, expecting } \(17\)
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/Syntax/NameWithSpacesQuoted.cmake b/Tests/RunCMake/Syntax/NameWithSpacesQuoted.cmake
new file mode 100644
index 000000000..3fba53f54
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithSpacesQuoted.cmake
@@ -0,0 +1 @@
+message("${var with space}")
diff --git a/Tests/RunCMake/Syntax/NameWithTabs-result.txt b/Tests/RunCMake/Syntax/NameWithTabs-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithTabs-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/NameWithTabs-stderr.txt b/Tests/RunCMake/Syntax/NameWithTabs-stderr.txt
new file mode 100644
index 000000000..e8880965b
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithTabs-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Error at NameWithTabs.cmake:1 \(message\):
+ Syntax error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/NameWithTabs.cmake:1
+
+ when parsing string
+
+ \${var
+
+ syntax error, unexpected \$end, expecting } \(5\)
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/Syntax/NameWithTabs.cmake b/Tests/RunCMake/Syntax/NameWithTabs.cmake
new file mode 100644
index 000000000..c3b1bea5a
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithTabs.cmake
@@ -0,0 +1 @@
+message(${var with tab})
diff --git a/Tests/RunCMake/Syntax/NameWithTabsQuoted-result.txt b/Tests/RunCMake/Syntax/NameWithTabsQuoted-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithTabsQuoted-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/NameWithTabsQuoted-stderr.txt b/Tests/RunCMake/Syntax/NameWithTabsQuoted-stderr.txt
new file mode 100644
index 000000000..b02007484
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithTabsQuoted-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Error at NameWithTabsQuoted.cmake:1 \(message\):
+ Syntax error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/NameWithTabsQuoted.cmake:1
+
+ when parsing string
+
+ \${var with tab}
+
+ syntax error, unexpected cal_SYMBOL, expecting } \(15\)
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/Syntax/NameWithTabsQuoted.cmake b/Tests/RunCMake/Syntax/NameWithTabsQuoted.cmake
new file mode 100644
index 000000000..8ddb85dcd
--- /dev/null
+++ b/Tests/RunCMake/Syntax/NameWithTabsQuoted.cmake
@@ -0,0 +1 @@
+message("${var with tab}")
diff --git a/Tests/RunCMake/Syntax/OneLetter-stderr.txt b/Tests/RunCMake/Syntax/OneLetter-stderr.txt
new file mode 100644
index 000000000..87c01c71c
--- /dev/null
+++ b/Tests/RunCMake/Syntax/OneLetter-stderr.txt
@@ -0,0 +1 @@
+message
diff --git a/Tests/RunCMake/Syntax/OneLetter.cmake b/Tests/RunCMake/Syntax/OneLetter.cmake
new file mode 100644
index 000000000..3c341fab0
--- /dev/null
+++ b/Tests/RunCMake/Syntax/OneLetter.cmake
@@ -0,0 +1,7 @@
+function(f)
+ g(${ARGN})
+endfunction()
+macro(g)
+ message(${ARGN})
+endmacro()
+f(message)
diff --git a/Tests/RunCMake/Syntax/ParenInENV-result.txt b/Tests/RunCMake/Syntax/ParenInENV-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/ParenInENV-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/ParenInENV-stderr.txt b/Tests/RunCMake/Syntax/ParenInENV-stderr.txt
new file mode 100644
index 000000000..37c5d6eb2
--- /dev/null
+++ b/Tests/RunCMake/Syntax/ParenInENV-stderr.txt
@@ -0,0 +1,22 @@
+CMake Warning \(dev\) in ParenInENV.cmake:
+ Syntax Warning in cmake code at
+
+ .*/Tests/RunCMake/Syntax/ParenInENV.cmake:2:21
+
+ Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Error at ParenInENV.cmake:2 \(message\):
+ Syntax error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/ParenInENV.cmake:2
+
+ when parsing string
+
+ -->\$ENV{e
+
+ syntax error, unexpected \$end, expecting } \(9\)
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/ParenInENV.cmake b/Tests/RunCMake/Syntax/ParenInENV.cmake
new file mode 100644
index 000000000..148f7266d
--- /dev/null
+++ b/Tests/RunCMake/Syntax/ParenInENV.cmake
@@ -0,0 +1,2 @@
+set("ENV{e(x)}" value)
+message(-->$ENV{e(x)}<--)
diff --git a/Tests/RunCMake/Syntax/ParenInQuotedENV-stderr.txt b/Tests/RunCMake/Syntax/ParenInQuotedENV-stderr.txt
new file mode 100644
index 000000000..7020c7e73
--- /dev/null
+++ b/Tests/RunCMake/Syntax/ParenInQuotedENV-stderr.txt
@@ -0,0 +1 @@
+-->value<--
diff --git a/Tests/RunCMake/Syntax/ParenInQuotedENV.cmake b/Tests/RunCMake/Syntax/ParenInQuotedENV.cmake
new file mode 100644
index 000000000..633371740
--- /dev/null
+++ b/Tests/RunCMake/Syntax/ParenInQuotedENV.cmake
@@ -0,0 +1,2 @@
+set("ENV{e(x)}" value)
+message("-->$ENV{e(x)}<--")
diff --git a/Tests/RunCMake/Syntax/ParenInVarName0-result.txt b/Tests/RunCMake/Syntax/ParenInVarName0-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/ParenInVarName0-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/ParenInVarName0-stderr.txt b/Tests/RunCMake/Syntax/ParenInVarName0-stderr.txt
new file mode 100644
index 000000000..0a6b60fb9
--- /dev/null
+++ b/Tests/RunCMake/Syntax/ParenInVarName0-stderr.txt
@@ -0,0 +1,12 @@
+CMake Error at ParenInVarName0.cmake:4 \(message\):
+ Syntax error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/ParenInVarName0.cmake:4
+
+ when parsing string
+
+ -->\${e\(x\)}<--
+
+ Invalid character \('\('\) in a variable name: 'e'
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/ParenInVarName0.cmake b/Tests/RunCMake/Syntax/ParenInVarName0.cmake
new file mode 100644
index 000000000..f863d20c6
--- /dev/null
+++ b/Tests/RunCMake/Syntax/ParenInVarName0.cmake
@@ -0,0 +1,4 @@
+cmake_policy(SET CMP0053 NEW)
+
+set("e(x)" value)
+message("-->${e(x)}<--")
diff --git a/Tests/RunCMake/Syntax/ParenInVarName1-result.txt b/Tests/RunCMake/Syntax/ParenInVarName1-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/ParenInVarName1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/ParenInVarName1-stderr.txt b/Tests/RunCMake/Syntax/ParenInVarName1-stderr.txt
new file mode 100644
index 000000000..81b17174b
--- /dev/null
+++ b/Tests/RunCMake/Syntax/ParenInVarName1-stderr.txt
@@ -0,0 +1,12 @@
+CMake Error at ParenInVarName1.cmake:4 \(message\):
+ Syntax error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/ParenInVarName1.cmake:4
+
+ when parsing string
+
+ -->\${e\(x\)}<--
+
+ syntax error, unexpected cal_SYMBOL, expecting } \(10\)
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/ParenInVarName1.cmake b/Tests/RunCMake/Syntax/ParenInVarName1.cmake
new file mode 100644
index 000000000..9fdc87bbf
--- /dev/null
+++ b/Tests/RunCMake/Syntax/ParenInVarName1.cmake
@@ -0,0 +1,4 @@
+cmake_policy(SET CMP0053 OLD)
+
+set("{e(x)}" value)
+message("-->${e(x)}<--")
diff --git a/Tests/RunCMake/Syntax/ParenNoSpace-stderr.txt b/Tests/RunCMake/Syntax/ParenNoSpace-stderr.txt
deleted file mode 100644
index 10f32932e..000000000
--- a/Tests/RunCMake/Syntax/ParenNoSpace-stderr.txt
+++ /dev/null
@@ -1 +0,0 @@
-^$
diff --git a/Tests/RunCMake/Syntax/ParenNoSpace-stdout.txt b/Tests/RunCMake/Syntax/ParenNoSpace-stdout.txt
deleted file mode 100644
index 72addd794..000000000
--- a/Tests/RunCMake/Syntax/ParenNoSpace-stdout.txt
+++ /dev/null
@@ -1,2 +0,0 @@
--- unquoted\(unquoted\)
--- quoted\(quoted\)
diff --git a/Tests/RunCMake/Syntax/ParenNoSpace.cmake b/Tests/RunCMake/Syntax/ParenNoSpace.cmake
deleted file mode 100644
index c690d964e..000000000
--- a/Tests/RunCMake/Syntax/ParenNoSpace.cmake
+++ /dev/null
@@ -1,2 +0,0 @@
-message(STATUS unquoted(unquoted))
-message(STATUS "quoted"("quoted"))
diff --git a/Tests/RunCMake/Syntax/ParenNoSpace0-stdout.txt b/Tests/RunCMake/Syntax/ParenNoSpace0-stdout.txt
new file mode 100644
index 000000000..5c4076f67
--- /dev/null
+++ b/Tests/RunCMake/Syntax/ParenNoSpace0-stdout.txt
@@ -0,0 +1,3 @@
+-- \(unquoted\)
+-- \(quoted\)
+-- \(bracket\)
diff --git a/Tests/RunCMake/Syntax/ParenNoSpace0.cmake b/Tests/RunCMake/Syntax/ParenNoSpace0.cmake
new file mode 100644
index 000000000..175fe4a80
--- /dev/null
+++ b/Tests/RunCMake/Syntax/ParenNoSpace0.cmake
@@ -0,0 +1,3 @@
+message(STATUS (unquoted))
+message(STATUS ("quoted"))
+message(STATUS ([[bracket]]))
diff --git a/Tests/RunCMake/Syntax/ParenNoSpace1-result.txt b/Tests/RunCMake/Syntax/ParenNoSpace1-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/ParenNoSpace1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/ParenNoSpace1-stderr.txt b/Tests/RunCMake/Syntax/ParenNoSpace1-stderr.txt
new file mode 100644
index 000000000..45b2e6a6a
--- /dev/null
+++ b/Tests/RunCMake/Syntax/ParenNoSpace1-stderr.txt
@@ -0,0 +1,28 @@
+CMake Warning \(dev\) in ParenNoSpace1.cmake:
+ Syntax Warning in cmake code at
+
+ .*/Tests/RunCMake/Syntax/ParenNoSpace1.cmake:1:26
+
+ Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) in ParenNoSpace1.cmake:
+ Syntax Warning in cmake code at
+
+ .*/Tests/RunCMake/Syntax/ParenNoSpace1.cmake:2:26
+
+ Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Error in ParenNoSpace1.cmake:
+ Syntax Error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/ParenNoSpace1.cmake:3:29
+
+ Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/ParenNoSpace1.cmake b/Tests/RunCMake/Syntax/ParenNoSpace1.cmake
new file mode 100644
index 000000000..550339a2f
--- /dev/null
+++ b/Tests/RunCMake/Syntax/ParenNoSpace1.cmake
@@ -0,0 +1,3 @@
+message(STATUS (unquoted)unquoted)
+message(STATUS ("quoted")"quoted")
+message(STATUS ([[bracket]])[[bracket]])
diff --git a/Tests/RunCMake/Syntax/ParenNoSpace2-stdout.txt b/Tests/RunCMake/Syntax/ParenNoSpace2-stdout.txt
new file mode 100644
index 000000000..0e657b92f
--- /dev/null
+++ b/Tests/RunCMake/Syntax/ParenNoSpace2-stdout.txt
@@ -0,0 +1,3 @@
+-- unquoted\(unquoted\)
+-- quoted\(quoted\)
+-- bracket\(bracket\)
diff --git a/Tests/RunCMake/Syntax/ParenNoSpace2.cmake b/Tests/RunCMake/Syntax/ParenNoSpace2.cmake
new file mode 100644
index 000000000..c46a88747
--- /dev/null
+++ b/Tests/RunCMake/Syntax/ParenNoSpace2.cmake
@@ -0,0 +1,3 @@
+message(STATUS unquoted(unquoted))
+message(STATUS "quoted"("quoted"))
+message(STATUS [[bracket]]([[bracket]]))
diff --git a/Tests/RunCMake/Syntax/RunCMakeTest.cmake b/Tests/RunCMake/Syntax/RunCMakeTest.cmake
index 94963f348..fd012b9c4 100644
--- a/Tests/RunCMake/Syntax/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Syntax/RunCMakeTest.cmake
@@ -1,18 +1,116 @@
include(RunCMake)
+run_cmake(BOM-UTF-8)
+run_cmake(BOM-UTF-16-LE)
+run_cmake(BOM-UTF-16-BE)
+run_cmake(BOM-UTF-32-LE)
+run_cmake(BOM-UTF-32-BE)
+run_cmake(CMP0053-At-OLD)
+run_cmake(CMP0053-At-NEW)
+run_cmake(CMP0053-At-WARN)
+run_cmake(CMP0053-At-WARN-newlines)
+run_cmake(CMP0053-WARN)
+run_cmake(CMP0053-NUL)
+run_cmake(CMP0053-ParenInENV)
+run_cmake(CMP0053-ParenInQuotedENV)
run_cmake(CommandSpaces)
run_cmake(CommandTabs)
run_cmake(CommandNewlines)
run_cmake(CommandComments)
run_cmake(CommandError0)
run_cmake(CommandError1)
+run_cmake(CommandError2)
+run_cmake(ForEachBracket1)
+run_cmake(FunctionBracket1)
+run_cmake(MacroBracket1)
run_cmake(String0)
run_cmake(String1)
+run_cmake(StringBackslash)
+run_cmake(StringCRLF)
+run_cmake(StringContinuation1)
+run_cmake(StringContinuation2)
run_cmake(StringNoSpace)
+run_cmake(OneLetter)
run_cmake(Unquoted0)
run_cmake(Unquoted1)
-run_cmake(ParenNoSpace)
+run_cmake(Unquoted2)
+run_cmake(Bracket0)
+run_cmake(Bracket1)
+run_cmake(Bracket2)
+run_cmake(BracketBackslash)
+run_cmake(BracketCRLF)
+run_cmake(BracketComment0)
+run_cmake(BracketComment1)
+run_cmake(BracketComment2)
+run_cmake(BracketComment3)
+run_cmake(BracketComment4)
+run_cmake(BracketComment5)
+run_cmake(BracketNoSpace0)
+run_cmake(BracketNoSpace1)
+run_cmake(BracketNoSpace2)
+run_cmake(BracketNoSpace3)
+run_cmake(BracketNoSpace4)
+run_cmake(BracketNoSpace5)
+run_cmake(Escape1)
+run_cmake(Escape2)
+run_cmake(EscapeCharsAllowed)
+include("${RunCMake_SOURCE_DIR}/EscapeCharsDisallowed.cmake")
+run_cmake(ParenNoSpace0)
+run_cmake(ParenNoSpace1)
+run_cmake(ParenNoSpace2)
+run_cmake(ParenInVarName0)
+run_cmake(ParenInVarName1)
run_cmake(UnterminatedCall1)
run_cmake(UnterminatedCall2)
run_cmake(UnterminatedString)
-run_cmake(BracketWarn)
+run_cmake(UnterminatedBrace0)
+run_cmake(UnterminatedBrace1)
+run_cmake(UnterminatedBrace2)
+run_cmake(UnterminatedBracket0)
+run_cmake(UnterminatedBracket1)
+run_cmake(UnterminatedBracketComment)
+
+# Variable expansion tests
+run_cmake(ExpandInAt)
+run_cmake(EscapedAt)
+run_cmake(EscapeQuotes)
+run_cmake(AtWithVariable)
+run_cmake(AtWithVariableEmptyExpansion)
+run_cmake(AtWithVariableAtOnly)
+run_cmake(AtWithVariableEmptyExpansionAtOnly)
+run_cmake(AtWithVariableFile)
+run_cmake(AtWithVariableAtOnlyFile)
+run_cmake(ParenInENV)
+run_cmake(ParenInQuotedENV)
+
+# Variable name tests
+run_cmake(NameWithSpaces)
+run_cmake(NameWithTabs)
+run_cmake(NameWithNewline)
+run_cmake(NameWithCarriageReturn)
+run_cmake(NameWithEscapedSpaces)
+run_cmake(NameWithEscapedTabs)
+run_cmake(NameWithSpacesQuoted)
+run_cmake(NameWithTabsQuoted)
+run_cmake(NameWithNewlineQuoted)
+run_cmake(NameWithCarriageReturnQuoted)
+run_cmake(NameWithEscapedSpacesQuoted)
+run_cmake(NameWithEscapedTabsQuoted)
+run_cmake(CMP0053-NameWithSpaces)
+run_cmake(CMP0053-NameWithTabs)
+run_cmake(CMP0053-NameWithNewline)
+run_cmake(CMP0053-NameWithCarriageReturn)
+run_cmake(CMP0053-NameWithEscapedSpaces)
+run_cmake(CMP0053-NameWithEscapedTabs)
+run_cmake(CMP0053-NameWithSpacesQuoted)
+run_cmake(CMP0053-NameWithTabsQuoted)
+run_cmake(CMP0053-NameWithNewlineQuoted)
+run_cmake(CMP0053-NameWithCarriageReturnQuoted)
+run_cmake(CMP0053-NameWithEscapedSpacesQuoted)
+run_cmake(CMP0053-NameWithEscapedTabsQuoted)
+
+# Function and macro tests.
+run_cmake(FunctionUnmatched)
+run_cmake(FunctionUnmatchedForeach)
+run_cmake(MacroUnmatched)
+run_cmake(MacroUnmatchedForeach)
diff --git a/Tests/RunCMake/Syntax/StringBackslash-result.txt b/Tests/RunCMake/Syntax/StringBackslash-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/StringBackslash-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/StringBackslash-stderr.txt b/Tests/RunCMake/Syntax/StringBackslash-stderr.txt
new file mode 100644
index 000000000..214f91439
--- /dev/null
+++ b/Tests/RunCMake/Syntax/StringBackslash-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at StringBackslash.cmake:1 \(message\):
+ a\\
+
+ b
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/StringBackslash.cmake b/Tests/RunCMake/Syntax/StringBackslash.cmake
new file mode 100644
index 000000000..066be965d
--- /dev/null
+++ b/Tests/RunCMake/Syntax/StringBackslash.cmake
@@ -0,0 +1,2 @@
+message(FATAL_ERROR "a\\
+b")
diff --git a/Tests/RunCMake/Syntax/StringCRLF-stderr.txt b/Tests/RunCMake/Syntax/StringCRLF-stderr.txt
new file mode 100644
index 000000000..7aef26eca
--- /dev/null
+++ b/Tests/RunCMake/Syntax/StringCRLF-stderr.txt
@@ -0,0 +1 @@
+CRLF->LF worked
diff --git a/Tests/RunCMake/Syntax/StringCRLF.cmake b/Tests/RunCMake/Syntax/StringCRLF.cmake
new file mode 100644
index 000000000..d20cfea7e
--- /dev/null
+++ b/Tests/RunCMake/Syntax/StringCRLF.cmake
@@ -0,0 +1,6 @@
+if("a
+b" STREQUAL "a\nb")
+ message("CRLF->LF worked")
+else()
+ message(FATAL_ERROR "CRLF->LF failed")
+endif()
diff --git a/Tests/RunCMake/Syntax/StringContinuation1-result.txt b/Tests/RunCMake/Syntax/StringContinuation1-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/StringContinuation1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/StringContinuation1-stderr.txt b/Tests/RunCMake/Syntax/StringContinuation1-stderr.txt
new file mode 100644
index 000000000..05771da2a
--- /dev/null
+++ b/Tests/RunCMake/Syntax/StringContinuation1-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at StringContinuation1.cmake:1 \(message\):
+ ab
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/StringContinuation1.cmake b/Tests/RunCMake/Syntax/StringContinuation1.cmake
new file mode 100644
index 000000000..ae86bb22c
--- /dev/null
+++ b/Tests/RunCMake/Syntax/StringContinuation1.cmake
@@ -0,0 +1,2 @@
+message(FATAL_ERROR "a\
+b")
diff --git a/Tests/RunCMake/Syntax/StringContinuation2-result.txt b/Tests/RunCMake/Syntax/StringContinuation2-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/StringContinuation2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/StringContinuation2-stderr.txt b/Tests/RunCMake/Syntax/StringContinuation2-stderr.txt
new file mode 100644
index 000000000..2f4964ca9
--- /dev/null
+++ b/Tests/RunCMake/Syntax/StringContinuation2-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at StringContinuation2.cmake:1 \(message\):
+ a\\b
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/StringContinuation2.cmake b/Tests/RunCMake/Syntax/StringContinuation2.cmake
new file mode 100644
index 000000000..490a40890
--- /dev/null
+++ b/Tests/RunCMake/Syntax/StringContinuation2.cmake
@@ -0,0 +1,2 @@
+message(FATAL_ERROR "a\\\
+b")
diff --git a/Tests/RunCMake/Syntax/StringNoSpace-stderr.txt b/Tests/RunCMake/Syntax/StringNoSpace-stderr.txt
index 89c2d2ae5..a4ec6e779 100644
--- a/Tests/RunCMake/Syntax/StringNoSpace-stderr.txt
+++ b/Tests/RunCMake/Syntax/StringNoSpace-stderr.txt
@@ -1,17 +1,21 @@
-CMake Warning \(dev\) at CMakeLists.txt:3 \(include\):
+CMake Warning \(dev\) in StringNoSpace.cmake:
Syntax Warning in cmake code at
.*/Tests/RunCMake/Syntax/StringNoSpace.cmake:2:28
Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.
-CMake Warning \(dev\) at CMakeLists.txt:3 \(include\):
+CMake Warning \(dev\) in StringNoSpace.cmake:
Syntax Warning in cmake code at
.*/Tests/RunCMake/Syntax/StringNoSpace.cmake:2:31
Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.
\[1 \${var} \\n 4\]
diff --git a/Tests/RunCMake/Syntax/Unquoted1-stderr.txt b/Tests/RunCMake/Syntax/Unquoted1-stderr.txt
index ff8194a6f..85a7a9de6 100644
--- a/Tests/RunCMake/Syntax/Unquoted1-stderr.txt
+++ b/Tests/RunCMake/Syntax/Unquoted1-stderr.txt
@@ -1 +1 @@
-^\[\]\[=\]\[\$\$\(MV\)-DSTR=" \[="\[;\]$
+^\[\]\[=\]\[\$\$\(MV\)-DSTR=" \[="\[;\]\]\[$
diff --git a/Tests/RunCMake/Syntax/Unquoted1.cmake b/Tests/RunCMake/Syntax/Unquoted1.cmake
index 0344fbd59..515161f2b 100644
--- a/Tests/RunCMake/Syntax/Unquoted1.cmake
+++ b/Tests/RunCMake/Syntax/Unquoted1.cmake
@@ -1 +1 @@
-message([] [=] [$ $(MV) -DSTR=" [=" [;])
+message([] [=] [$ $(MV) -DSTR=" [=" [;] ] [)
diff --git a/Tests/RunCMake/Syntax/Unquoted2-stderr.txt b/Tests/RunCMake/Syntax/Unquoted2-stderr.txt
new file mode 100644
index 000000000..eb8883e3f
--- /dev/null
+++ b/Tests/RunCMake/Syntax/Unquoted2-stderr.txt
@@ -0,0 +1 @@
+^\[\[UnquotedBracketArgument1\]\]$
diff --git a/Tests/RunCMake/Syntax/Unquoted2.cmake b/Tests/RunCMake/Syntax/Unquoted2.cmake
new file mode 100644
index 000000000..d94057d90
--- /dev/null
+++ b/Tests/RunCMake/Syntax/Unquoted2.cmake
@@ -0,0 +1,3 @@
+cmake_policy(SET CMP0053 NEW)
+
+message(\[[Unquoted Bracket Argument 1]])
diff --git a/Tests/RunCMake/Syntax/UnterminatedBrace0-result.txt b/Tests/RunCMake/Syntax/UnterminatedBrace0-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/UnterminatedBrace0-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/UnterminatedBrace0-stderr.txt b/Tests/RunCMake/Syntax/UnterminatedBrace0-stderr.txt
new file mode 100644
index 000000000..1e0ce493b
--- /dev/null
+++ b/Tests/RunCMake/Syntax/UnterminatedBrace0-stderr.txt
@@ -0,0 +1,12 @@
+CMake Error at UnterminatedBrace0.cmake:2 \(set\):
+ Syntax error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/UnterminatedBrace0.cmake:2
+
+ when parsing string
+
+ \${
+
+ syntax error, unexpected \$end, expecting } \(2\)
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/UnterminatedBrace0.cmake b/Tests/RunCMake/Syntax/UnterminatedBrace0.cmake
new file mode 100644
index 000000000..0da12902a
--- /dev/null
+++ b/Tests/RunCMake/Syntax/UnterminatedBrace0.cmake
@@ -0,0 +1,2 @@
+cmake_minimum_required(VERSION 3.0)
+set(var "${")
diff --git a/Tests/RunCMake/Syntax/UnterminatedBrace1-stderr.txt b/Tests/RunCMake/Syntax/UnterminatedBrace1-stderr.txt
new file mode 100644
index 000000000..4e3c2b563
--- /dev/null
+++ b/Tests/RunCMake/Syntax/UnterminatedBrace1-stderr.txt
@@ -0,0 +1,13 @@
+CMake Warning \(dev\) at UnterminatedBrace1.cmake:3 \(set\):
+ Syntax error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/UnterminatedBrace1.cmake:3
+
+ when parsing string
+
+ \${
+
+ syntax error, unexpected \$end, expecting } \(2\)
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/Syntax/UnterminatedBrace1.cmake b/Tests/RunCMake/Syntax/UnterminatedBrace1.cmake
new file mode 100644
index 000000000..93fba3413
--- /dev/null
+++ b/Tests/RunCMake/Syntax/UnterminatedBrace1.cmake
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.0)
+cmake_policy(SET CMP0010 OLD)
+set(var "${")
diff --git a/Tests/RunCMake/Syntax/UnterminatedBrace2-result.txt b/Tests/RunCMake/Syntax/UnterminatedBrace2-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/UnterminatedBrace2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/UnterminatedBrace2-stderr.txt b/Tests/RunCMake/Syntax/UnterminatedBrace2-stderr.txt
new file mode 100644
index 000000000..b332d34b2
--- /dev/null
+++ b/Tests/RunCMake/Syntax/UnterminatedBrace2-stderr.txt
@@ -0,0 +1,12 @@
+CMake Error at UnterminatedBrace2.cmake:4 \(set\):
+ Syntax error in cmake code at
+
+ .*/Tests/RunCMake/Syntax/UnterminatedBrace2.cmake:4
+
+ when parsing string
+
+ \${
+
+ There is an unterminated variable reference.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/UnterminatedBrace2.cmake b/Tests/RunCMake/Syntax/UnterminatedBrace2.cmake
new file mode 100644
index 000000000..a650e5b72
--- /dev/null
+++ b/Tests/RunCMake/Syntax/UnterminatedBrace2.cmake
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.0)
+cmake_policy(SET CMP0010 OLD)
+cmake_policy(SET CMP0053 NEW)
+set(var "${")
diff --git a/Tests/RunCMake/Syntax/UnterminatedBracket0-result.txt b/Tests/RunCMake/Syntax/UnterminatedBracket0-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/UnterminatedBracket0-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/UnterminatedBracket0-stderr.txt b/Tests/RunCMake/Syntax/UnterminatedBracket0-stderr.txt
new file mode 100644
index 000000000..3559c1893
--- /dev/null
+++ b/Tests/RunCMake/Syntax/UnterminatedBracket0-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error: Error in cmake code at
+.*/Syntax/UnterminatedBracket0.cmake:2:
+Parse error. Function missing ending "\)". Instead found unterminated bracket with text "\)
+".
+CMake Error at CMakeLists.txt:3 \(include\):
+ include could not find load file:
+
+ UnterminatedBracket0.cmake$
diff --git a/Tests/RunCMake/Syntax/UnterminatedBracket0.cmake b/Tests/RunCMake/Syntax/UnterminatedBracket0.cmake
new file mode 100644
index 000000000..98cd906e0
--- /dev/null
+++ b/Tests/RunCMake/Syntax/UnterminatedBracket0.cmake
@@ -0,0 +1 @@
+set(var [[)
diff --git a/Tests/RunCMake/Syntax/UnterminatedBracket1-result.txt b/Tests/RunCMake/Syntax/UnterminatedBracket1-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/UnterminatedBracket1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/UnterminatedBracket1-stderr.txt b/Tests/RunCMake/Syntax/UnterminatedBracket1-stderr.txt
new file mode 100644
index 000000000..55d458ba2
--- /dev/null
+++ b/Tests/RunCMake/Syntax/UnterminatedBracket1-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error: Error in cmake code at
+.*/Syntax/UnterminatedBracket1.cmake:2:
+Parse error. Function missing ending "\)". Instead found unterminated bracket with text "\]\]\)
+".
+CMake Error at CMakeLists.txt:3 \(include\):
+ include could not find load file:
+
+ UnterminatedBracket1.cmake$
diff --git a/Tests/RunCMake/Syntax/UnterminatedBracket1.cmake b/Tests/RunCMake/Syntax/UnterminatedBracket1.cmake
new file mode 100644
index 000000000..706f7a321
--- /dev/null
+++ b/Tests/RunCMake/Syntax/UnterminatedBracket1.cmake
@@ -0,0 +1 @@
+set(var [=[]])
diff --git a/Tests/RunCMake/Syntax/UnterminatedBracketComment-result.txt b/Tests/RunCMake/Syntax/UnterminatedBracketComment-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Syntax/UnterminatedBracketComment-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Syntax/UnterminatedBracketComment-stderr.txt b/Tests/RunCMake/Syntax/UnterminatedBracketComment-stderr.txt
new file mode 100644
index 000000000..0a799eb5a
--- /dev/null
+++ b/Tests/RunCMake/Syntax/UnterminatedBracketComment-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error: Error in cmake code at
+.*/Syntax/UnterminatedBracketComment.cmake:1:
+Parse error. Expected a command name, got unterminated bracket with text "#\]\]
+".
+CMake Error at CMakeLists.txt:3 \(include\):
+ include could not find load file:
+
+ UnterminatedBracketComment.cmake
diff --git a/Tests/RunCMake/Syntax/UnterminatedBracketComment.cmake b/Tests/RunCMake/Syntax/UnterminatedBracketComment.cmake
new file mode 100644
index 000000000..ad71f3c51
--- /dev/null
+++ b/Tests/RunCMake/Syntax/UnterminatedBracketComment.cmake
@@ -0,0 +1,2 @@
+#[=[
+#]]
diff --git a/Tests/RunCMake/Syntax/atfile.txt.in b/Tests/RunCMake/Syntax/atfile.txt.in
new file mode 100644
index 000000000..3775919f6
--- /dev/null
+++ b/Tests/RunCMake/Syntax/atfile.txt.in
@@ -0,0 +1,4 @@
+==>@var@<==
+==>@empty@<==
+==>${var}<==
+==>${empty}<==
diff --git a/Tests/RunCMake/TargetObjects/BadContext-result.txt b/Tests/RunCMake/TargetObjects/BadContext-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/BadContext-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/TargetObjects/BadContext-stderr.txt b/Tests/RunCMake/TargetObjects/BadContext-stderr.txt
new file mode 100644
index 000000000..b78189eea
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/BadContext-stderr.txt
@@ -0,0 +1,27 @@
+(CMake Error at BadContext.cmake:4 \(file\):
+ Error evaluating generator expression:
+
+ \$<TARGET_OBJECTS:NoTarget>
+
+ The evaluation of the TARGET_OBJECTS generator expression is only suitable
+ for consumption by CMake. It is not suitable for writing out elsewhere.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+*)+
+(CMake Error at BadContext.cmake:5 \(file\):
+ Error evaluating generator expression:
+
+ \$<TARGET_OBJECTS:NoTarget>
+
+ The evaluation of the TARGET_OBJECTS generator expression is only suitable
+ for consumption by CMake. It is not suitable for writing out elsewhere.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+*)+
+CMake Error:
+ Error evaluating generator expression:
+
+ \$<TARGET_OBJECTS:NoTarget>
+
+ The evaluation of the TARGET_OBJECTS generator expression is only suitable
+ for consumption by CMake. It is not suitable for writing out elsewhere.
diff --git a/Tests/RunCMake/TargetObjects/BadContext.cmake b/Tests/RunCMake/TargetObjects/BadContext.cmake
new file mode 100644
index 000000000..5d7e33e79
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/BadContext.cmake
@@ -0,0 +1,7 @@
+add_library(iface INTERFACE)
+target_sources(iface INTERFACE $<TARGET_OBJECTS:NoTarget>)
+
+file(GENERATE OUTPUT test_output CONTENT $<TARGET_OBJECTS:NoTarget>)
+file(GENERATE OUTPUT test_output2 CONTENT $<TARGET_PROPERTY:iface,INTERFACE_SOURCES>)
+
+install(FILES $<TARGET_OBJECTS:NoTarget> DESTINATION objects)
diff --git a/Tests/RunCMake/TargetObjects/CMakeLists.txt b/Tests/RunCMake/TargetObjects/CMakeLists.txt
new file mode 100644
index 000000000..be9d4038d
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST})
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/TargetObjects/RunCMakeTest.cmake b/Tests/RunCMake/TargetObjects/RunCMakeTest.cmake
new file mode 100644
index 000000000..85c76e240
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/RunCMakeTest.cmake
@@ -0,0 +1,3 @@
+include(RunCMake)
+
+run_cmake(BadContext)
diff --git a/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt b/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
index 6533b75d8..57047fb41 100644
--- a/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
+++ b/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
@@ -11,3 +11,15 @@
\* CMP0020
\* CMP0021
\* CMP0022
+ \* CMP0027
+ \* CMP0038
+ \* CMP0041
+ \* CMP0042
+ \* CMP0046
+ \* CMP0052
+ \* CMP0060
+ \* CMP0063
+ \* CMP0065
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference1-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference1-stderr.txt
index 791c4a9b3..75a729e9c 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference1-stderr.txt
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference1-stderr.txt
@@ -3,4 +3,4 @@ CMake Error:
\$<TARGET_PROPERTY:INCLUDE_DIRECTORIES>
- Self reference on target "TargetPropertyGeneratorExpressions".$
+ Self reference on target "TargetPropertyGeneratorExpressions".
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference2-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference2-stderr.txt
index 791c4a9b3..75a729e9c 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference2-stderr.txt
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference2-stderr.txt
@@ -3,4 +3,4 @@ CMake Error:
\$<TARGET_PROPERTY:INCLUDE_DIRECTORIES>
- Self reference on target "TargetPropertyGeneratorExpressions".$
+ Self reference on target "TargetPropertyGeneratorExpressions".
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference3-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference3-stderr.txt
index f60d72632..f52a27df1 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference3-stderr.txt
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference3-stderr.txt
@@ -3,4 +3,4 @@ CMake Error:
\$<TARGET_PROPERTY:TargetPropertyGeneratorExpressions,INCLUDE_DIRECTORIES>
- Self reference on target "TargetPropertyGeneratorExpressions".$
+ Self reference on target "TargetPropertyGeneratorExpressions".
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference4-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference4-stderr.txt
index f60d72632..f52a27df1 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference4-stderr.txt
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference4-stderr.txt
@@ -3,4 +3,4 @@ CMake Error:
\$<TARGET_PROPERTY:TargetPropertyGeneratorExpressions,INCLUDE_DIRECTORIES>
- Self reference on target "TargetPropertyGeneratorExpressions".$
+ Self reference on target "TargetPropertyGeneratorExpressions".
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference5-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference5-stderr.txt
index 2b22d0fc3..d8d12b53d 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference5-stderr.txt
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference5-stderr.txt
@@ -3,4 +3,4 @@ CMake Error:
\$<TARGET_PROPERTY:COMPILE_DEFINITIONS>
- Self reference on target "TargetPropertyGeneratorExpressions".$
+ Self reference on target "TargetPropertyGeneratorExpressions".
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference6-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference6-stderr.txt
index fe7caa3c3..0b1dd26b3 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference6-stderr.txt
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadSelfReference6-stderr.txt
@@ -3,4 +3,4 @@ CMake Error:
\$<TARGET_PROPERTY:TargetPropertyGeneratorExpressions,COMPILE_DEFINITIONS>
- Self reference on target "TargetPropertyGeneratorExpressions".$
+ Self reference on target "TargetPropertyGeneratorExpressions".
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1-result.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1-stderr.txt
new file mode 100644
index 000000000..7e002f547
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error at LinkImplementationCycle1.cmake:5 \(target_link_libraries\):
+ Error evaluating generator expression:
+
+ \$<TARGET_PROPERTY:INCLUDE_DIRECTORIES>
+
+ \$<TARGET_PROPERTY:...> expression in link libraries evaluation depends on
+ target property which is transitive over the link libraries, creating a
+ recursion.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:8 \(include\)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1.cmake b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1.cmake
new file mode 100644
index 000000000..4b60214f4
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1.cmake
@@ -0,0 +1,8 @@
+
+add_library(empty1 empty.cpp)
+add_library(empty2 empty.cpp)
+
+target_link_libraries(empty1
+ LINK_PUBLIC
+ $<$<STREQUAL:$<TARGET_PROPERTY:INCLUDE_DIRECTORIES>,/foo/bar>:empty2>
+)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2-result.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2-stderr.txt
new file mode 100644
index 000000000..2f72de6ec
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error at LinkImplementationCycle2.cmake:5 \(target_link_libraries\):
+ Error evaluating generator expression:
+
+ \$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>
+
+ \$<TARGET_PROPERTY:...> expression in link libraries evaluation depends on
+ target property which is transitive over the link libraries, creating a
+ recursion.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:8 \(include\)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2.cmake b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2.cmake
new file mode 100644
index 000000000..557eac123
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2.cmake
@@ -0,0 +1,8 @@
+
+add_library(empty1 empty.cpp)
+add_library(empty2 empty.cpp)
+
+target_link_libraries(empty1
+ LINK_PUBLIC
+ $<$<STREQUAL:$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>,/foo/bar>:empty2>
+)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3-result.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3.cmake b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3.cmake
new file mode 100644
index 000000000..0f921d457
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3.cmake
@@ -0,0 +1,10 @@
+
+add_library(empty1 empty.cpp)
+add_library(empty2 empty.cpp)
+
+# This is OK, because evaluating the INCLUDE_DIRECTORIES is not affected by
+# the content of the INTERFACE_LINK_LIBRARIES.
+target_link_libraries(empty1
+ INTERFACE
+ $<$<STREQUAL:$<TARGET_PROPERTY:INCLUDE_DIRECTORIES>,/foo/bar>:empty2>
+)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4-result.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4-stderr.txt
new file mode 100644
index 000000000..5cfeb0a9d
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error:
+ Error evaluating generator expression:
+
+ \$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>
+
+ \$<TARGET_PROPERTY:...> expression in link libraries evaluation depends on
+ target property which is transitive over the link libraries, creating a
+ recursion.
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4.cmake b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4.cmake
new file mode 100644
index 000000000..ab6d0b265
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4.cmake
@@ -0,0 +1,14 @@
+
+add_library(empty1 empty.cpp)
+add_library(empty2 empty.cpp)
+
+# The INTERFACE_INCLUDE_DIRECTORIES do not depend on the link interface.
+# On its own, this is fine. It is only when used by empty3 that an error
+# is appropriately issued.
+target_link_libraries(empty1
+ INTERFACE
+ $<$<STREQUAL:$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>,/foo/bar>:empty2>
+)
+
+add_library(empty3 empty.cpp)
+target_link_libraries(empty3 empty1)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5-result.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5-stderr.txt
new file mode 100644
index 000000000..5cfeb0a9d
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error:
+ Error evaluating generator expression:
+
+ \$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>
+
+ \$<TARGET_PROPERTY:...> expression in link libraries evaluation depends on
+ target property which is transitive over the link libraries, creating a
+ recursion.
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5.cmake b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5.cmake
new file mode 100644
index 000000000..dc180e391
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5.cmake
@@ -0,0 +1,10 @@
+
+add_library(empty1 INTERFACE IMPORTED)
+add_library(empty2 INTERFACE IMPORTED)
+
+set_property(TARGET empty1 PROPERTY INTERFACE_LINK_LIBRARIES
+ $<$<STREQUAL:$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>,/foo/bar>:empty2>
+)
+
+add_library(empty3 empty.cpp)
+target_link_libraries(empty3 empty1)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6-result.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6-stderr.txt
new file mode 100644
index 000000000..5cfeb0a9d
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error:
+ Error evaluating generator expression:
+
+ \$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>
+
+ \$<TARGET_PROPERTY:...> expression in link libraries evaluation depends on
+ target property which is transitive over the link libraries, creating a
+ recursion.
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6.cmake b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6.cmake
new file mode 100644
index 000000000..91252d074
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6.cmake
@@ -0,0 +1,14 @@
+
+add_library(empty1 SHARED empty.cpp)
+add_library(empty2 SHARED empty.cpp)
+
+# The INTERFACE_INCLUDE_DIRECTORIES do not depend on the link interface.
+# On its own, this is fine. It is only when used by empty3 that an error
+# is appropriately issued.
+target_link_libraries(empty1
+ INTERFACE
+ $<$<STREQUAL:$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>,/foo/bar>:empty2>
+)
+
+add_library(empty3 SHARED empty.cpp)
+target_link_libraries(empty3 empty1)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/RunCMakeTest.cmake b/Tests/RunCMake/TargetPropertyGeneratorExpressions/RunCMakeTest.cmake
index 0ee32387d..645a57d5f 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/RunCMakeTest.cmake
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/RunCMakeTest.cmake
@@ -15,3 +15,9 @@ run_cmake(BadInvalidName5)
run_cmake(BadInvalidName6)
run_cmake(BadInvalidName7)
run_cmake(BadInvalidName8)
+run_cmake(LinkImplementationCycle1)
+run_cmake(LinkImplementationCycle2)
+run_cmake(LinkImplementationCycle3)
+run_cmake(LinkImplementationCycle4)
+run_cmake(LinkImplementationCycle5)
+run_cmake(LinkImplementationCycle6)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/empty.cpp b/Tests/RunCMake/TargetPropertyGeneratorExpressions/empty.cpp
new file mode 100644
index 000000000..bfbbddeb9
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/empty.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/TargetSources/CMP0026-LOCATION-result.txt b/Tests/RunCMake/TargetSources/CMP0026-LOCATION-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/CMP0026-LOCATION-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/TargetSources/CMP0026-LOCATION.cmake b/Tests/RunCMake/TargetSources/CMP0026-LOCATION.cmake
new file mode 100644
index 000000000..464df3682
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/CMP0026-LOCATION.cmake
@@ -0,0 +1,13 @@
+
+cmake_policy(SET CMP0026 OLD)
+
+add_library(objlib OBJECT
+ empty_1.cpp
+)
+
+add_executable(my_exe
+ empty_2.cpp
+ $<TARGET_OBJECTS:objlib>
+)
+
+get_target_property( loc my_exe LOCATION)
diff --git a/Tests/RunCMake/TargetSources/CMakeLists.txt b/Tests/RunCMake/TargetSources/CMakeLists.txt
new file mode 100644
index 000000000..f452db177
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/TargetSources/ConfigNotAllowed-result.txt b/Tests/RunCMake/TargetSources/ConfigNotAllowed-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/ConfigNotAllowed-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/TargetSources/ConfigNotAllowed-stderr.txt b/Tests/RunCMake/TargetSources/ConfigNotAllowed-stderr.txt
new file mode 100644
index 000000000..1de5dd72e
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/ConfigNotAllowed-stderr.txt
@@ -0,0 +1,14 @@
+CMake Error in CMakeLists.txt:
+ Target "somelib" has source files which vary by configuration. This is not
+ supported by the "[^"]+" generator.
+
+ Config "Debug":
+
+ .*/Tests/RunCMake/TargetSources/empty_1.cpp
+ .*/Tests/RunCMake/TargetSources/empty_2.cpp
+ .*/Tests/RunCMake/TargetSources/CMakeLists.txt
+
+ Config "Release":
+
+ .*/Tests/RunCMake/TargetSources/empty_1.cpp
+ .*/Tests/RunCMake/TargetSources/CMakeLists.txt
diff --git a/Tests/RunCMake/TargetSources/ConfigNotAllowed.cmake b/Tests/RunCMake/TargetSources/ConfigNotAllowed.cmake
new file mode 100644
index 000000000..02af37972
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/ConfigNotAllowed.cmake
@@ -0,0 +1,2 @@
+
+add_library(somelib empty_1.cpp $<$<CONFIG:Debug>:empty_2.cpp>)
diff --git a/Tests/RunCMake/TargetSources/ExportBuild-result.txt b/Tests/RunCMake/TargetSources/ExportBuild-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/ExportBuild-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/TargetSources/ExportBuild.cmake b/Tests/RunCMake/TargetSources/ExportBuild.cmake
new file mode 100644
index 000000000..b626aa6cd
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/ExportBuild.cmake
@@ -0,0 +1,5 @@
+
+add_library(iface INTERFACE)
+target_sources(iface INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/empty_1.cpp")
+
+export(TARGETS iface FILE ${CMAKE_CURRENT_BINARY_DIR}/targets.cmake)
diff --git a/Tests/RunCMake/TargetSources/OriginDebug-result.txt b/Tests/RunCMake/TargetSources/OriginDebug-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/OriginDebug-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/TargetSources/OriginDebug-stderr.txt b/Tests/RunCMake/TargetSources/OriginDebug-stderr.txt
new file mode 100644
index 000000000..11bc96cf9
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/OriginDebug-stderr.txt
@@ -0,0 +1,31 @@
+CMake Debug Log at OriginDebug.cmake:13 \(add_library\):
+ Used sources for target OriginDebug:
+
+ \* .*Tests/RunCMake/TargetSources/empty_2.cpp
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+.*
+CMake Debug Log at OriginDebug.cmake:16 \(set_property\):
+ Used sources for target OriginDebug:
+
+ \* .*Tests/RunCMake/TargetSources/empty_3.cpp
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+.*
+CMake Debug Log at OriginDebug.cmake:20 \(target_sources\):
+ Used sources for target OriginDebug:
+
+ \* .*Tests/RunCMake/TargetSources/empty_4.cpp
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+.*
+CMake Debug Log at OriginDebug.cmake:14 \(target_link_libraries\):
+ Used sources for target OriginDebug:
+
+ \* .*Tests/RunCMake/TargetSources/empty_1.cpp
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/TargetSources/OriginDebug.cmake b/Tests/RunCMake/TargetSources/OriginDebug.cmake
new file mode 100644
index 000000000..d40a1d82a
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/OriginDebug.cmake
@@ -0,0 +1,20 @@
+
+cmake_minimum_required(VERSION 3.0)
+
+project(OriginDebug)
+
+set(CMAKE_DEBUG_TARGET_PROPERTIES SOURCES)
+
+add_library(iface INTERFACE)
+set_property(TARGET iface PROPERTY INTERFACE_SOURCES
+ "${CMAKE_CURRENT_SOURCE_DIR}/empty_1.cpp"
+)
+
+add_library(OriginDebug empty_2.cpp)
+target_link_libraries(OriginDebug iface)
+
+set_property(TARGET OriginDebug APPEND PROPERTY SOURCES
+ empty_3.cpp
+)
+
+target_sources(OriginDebug PRIVATE empty_4.cpp)
diff --git a/Tests/RunCMake/TargetSources/OriginDebugIDE-result.txt b/Tests/RunCMake/TargetSources/OriginDebugIDE-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/OriginDebugIDE-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/TargetSources/OriginDebugIDE-stderr.txt b/Tests/RunCMake/TargetSources/OriginDebugIDE-stderr.txt
new file mode 100644
index 000000000..fad7073c6
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/OriginDebugIDE-stderr.txt
@@ -0,0 +1,40 @@
+CMake Debug Log at OriginDebug.cmake:13 \(add_library\):
+ Used sources for target OriginDebug:
+
+ \* .*Tests/RunCMake/TargetSources/empty_2.cpp
+
+Call Stack \(most recent call first\):
+ OriginDebugIDE.cmake:4 \(include\)
+ CMakeLists.txt:3 \(include\)
++
+CMake Debug Log at OriginDebug.cmake:16 \(set_property\):
+ Used sources for target OriginDebug:
+
+ \* .*Tests/RunCMake/TargetSources/empty_3.cpp
+
+Call Stack \(most recent call first\):
+ OriginDebugIDE.cmake:4 \(include\)
+ CMakeLists.txt:3 \(include\)
++
+CMake Debug Log at OriginDebug.cmake:20 \(target_sources\):
+ Used sources for target OriginDebug:
+
+ \* .*Tests/RunCMake/TargetSources/empty_4.cpp
+
+Call Stack \(most recent call first\):
+ OriginDebugIDE.cmake:4 \(include\)
+ CMakeLists.txt:3 \(include\)
++
+CMake Debug Log:
+ Used sources for target OriginDebug:
+
+ * .*CMakeLists.txt
++
+CMake Debug Log at OriginDebug.cmake:14 \(target_link_libraries\):
+ Used sources for target OriginDebug:
+
+ \* .*Tests/RunCMake/TargetSources/empty_1.cpp
+
+Call Stack \(most recent call first\):
+ OriginDebugIDE.cmake:4 \(include\)
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/TargetSources/OriginDebugIDE.cmake b/Tests/RunCMake/TargetSources/OriginDebugIDE.cmake
new file mode 100644
index 000000000..a3cc3a8ed
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/OriginDebugIDE.cmake
@@ -0,0 +1,4 @@
+
+# Separate test for the IDEs, because they show the CMakeLists.txt file
+# as a source file.
+include(${CMAKE_CURRENT_LIST_DIR}/OriginDebug.cmake)
diff --git a/Tests/RunCMake/TargetSources/RelativePathInInterface-result.txt b/Tests/RunCMake/TargetSources/RelativePathInInterface-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/RelativePathInInterface-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/TargetSources/RelativePathInInterface-stderr.txt b/Tests/RunCMake/TargetSources/RelativePathInInterface-stderr.txt
new file mode 100644
index 000000000..d47dd4de3
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/RelativePathInInterface-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error in CMakeLists.txt:
+ Target "iface" contains relative path in its INTERFACE_SOURCES:
+
+ "empty_1.cpp"
diff --git a/Tests/RunCMake/TargetSources/RelativePathInInterface.cmake b/Tests/RunCMake/TargetSources/RelativePathInInterface.cmake
new file mode 100644
index 000000000..8bb6149d9
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/RelativePathInInterface.cmake
@@ -0,0 +1,6 @@
+
+add_library(iface INTERFACE)
+target_sources(iface INTERFACE empty_1.cpp)
+
+add_executable(main main.cpp)
+target_link_libraries(main iface)
diff --git a/Tests/RunCMake/TargetSources/RunCMakeTest.cmake b/Tests/RunCMake/TargetSources/RunCMakeTest.cmake
new file mode 100644
index 000000000..4416ef9f2
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/RunCMakeTest.cmake
@@ -0,0 +1,12 @@
+include(RunCMake)
+
+if(RunCMake_GENERATOR MATCHES "Visual Studio|Xcode" AND NOT XCODE_BELOW_2)
+ run_cmake(ConfigNotAllowed)
+ run_cmake(OriginDebugIDE)
+else()
+ run_cmake(OriginDebug)
+endif()
+
+run_cmake(CMP0026-LOCATION)
+run_cmake(RelativePathInInterface)
+run_cmake(ExportBuild)
diff --git a/Tests/RunCMake/TargetSources/empty_1.cpp b/Tests/RunCMake/TargetSources/empty_1.cpp
new file mode 100644
index 000000000..bfbbddeb9
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/empty_1.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/TargetSources/empty_2.cpp b/Tests/RunCMake/TargetSources/empty_2.cpp
new file mode 100644
index 000000000..bfbbddeb9
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/empty_2.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/TargetSources/empty_3.cpp b/Tests/RunCMake/TargetSources/empty_3.cpp
new file mode 100644
index 000000000..bfbbddeb9
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/empty_3.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/TargetSources/empty_4.cpp b/Tests/RunCMake/TargetSources/empty_4.cpp
new file mode 100644
index 000000000..bfbbddeb9
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/empty_4.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/TargetSources/main.cpp b/Tests/RunCMake/TargetSources/main.cpp
new file mode 100644
index 000000000..766b7751b
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/main.cpp
@@ -0,0 +1,5 @@
+
+int main()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/VisibilityPreset/CMP0063-Common.cmake b/Tests/RunCMake/VisibilityPreset/CMP0063-Common.cmake
new file mode 100644
index 000000000..afea20b85
--- /dev/null
+++ b/Tests/RunCMake/VisibilityPreset/CMP0063-Common.cmake
@@ -0,0 +1,7 @@
+set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
+set(CMAKE_CXX_VISIBILITY_PRESET hidden)
+add_executable(myexe lib.cpp)
+add_library(mystatic STATIC lib.cpp)
+add_library(myshared SHARED lib.cpp)
+add_library(mymodule MODULE lib.cpp)
+add_library(myobject OBJECT lib.cpp)
diff --git a/Tests/RunCMake/VisibilityPreset/CMP0063-NEW.cmake b/Tests/RunCMake/VisibilityPreset/CMP0063-NEW.cmake
new file mode 100644
index 000000000..9d1ee4074
--- /dev/null
+++ b/Tests/RunCMake/VisibilityPreset/CMP0063-NEW.cmake
@@ -0,0 +1,8 @@
+cmake_policy(SET CMP0063 NEW)
+enable_language(CXX)
+
+# Ensure CMake would warn even if toolchain does not really have these flags.
+set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
+set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY "-fvisibility=")
+
+include(CMP0063-Common.cmake)
diff --git a/Tests/RunCMake/VisibilityPreset/CMP0063-OLD.cmake b/Tests/RunCMake/VisibilityPreset/CMP0063-OLD.cmake
new file mode 100644
index 000000000..8378209c9
--- /dev/null
+++ b/Tests/RunCMake/VisibilityPreset/CMP0063-OLD.cmake
@@ -0,0 +1,8 @@
+cmake_policy(SET CMP0063 OLD)
+enable_language(CXX)
+
+# Ensure CMake would warn even if toolchain does not really have these flags.
+set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
+set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY "-fvisibility=")
+
+include(CMP0063-Common.cmake)
diff --git a/Tests/RunCMake/VisibilityPreset/CMP0063-WARN-exe-stderr.txt b/Tests/RunCMake/VisibilityPreset/CMP0063-WARN-exe-stderr.txt
new file mode 100644
index 000000000..b8d726f8f
--- /dev/null
+++ b/Tests/RunCMake/VisibilityPreset/CMP0063-WARN-exe-stderr.txt
@@ -0,0 +1,15 @@
+CMake Warning \(dev\) at CMP0063-WARN-exe.cmake:[0-9]+ \(add_executable\):
+ Policy CMP0063 is not set: Honor visibility properties for all target
+ types. Run "cmake --help-policy CMP0063" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+
+ Target "myexe" of type "EXECUTABLE" has the following visibility properties
+ set for CXX:
+
+ CXX_VISIBILITY_PRESET
+ VISIBILITY_INLINES_HIDDEN
+
+ For compatibility CMake is not honoring them for this target.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/VisibilityPreset/CMP0063-WARN-exe.cmake b/Tests/RunCMake/VisibilityPreset/CMP0063-WARN-exe.cmake
new file mode 100644
index 000000000..cef1d7521
--- /dev/null
+++ b/Tests/RunCMake/VisibilityPreset/CMP0063-WARN-exe.cmake
@@ -0,0 +1,11 @@
+
+enable_language(CXX)
+
+# Ensure CMake warns even if toolchain does not really have these flags.
+set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
+set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY "-fvisibility=")
+
+set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
+set(CMAKE_CXX_VISIBILITY_PRESET hidden)
+
+add_executable(myexe lib.cpp)
diff --git a/Tests/RunCMake/VisibilityPreset/CMP0063-WARN-no.cmake b/Tests/RunCMake/VisibilityPreset/CMP0063-WARN-no.cmake
new file mode 100644
index 000000000..2a9c9e543
--- /dev/null
+++ b/Tests/RunCMake/VisibilityPreset/CMP0063-WARN-no.cmake
@@ -0,0 +1,8 @@
+
+enable_language(CXX)
+
+# Ensure CMake does not warn even if toolchain really does have these flags.
+unset(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN)
+unset(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY)
+
+include(CMP0063-Common.cmake)
diff --git a/Tests/RunCMake/VisibilityPreset/CMP0063-WARN-obj-stderr.txt b/Tests/RunCMake/VisibilityPreset/CMP0063-WARN-obj-stderr.txt
new file mode 100644
index 000000000..3a7732a65
--- /dev/null
+++ b/Tests/RunCMake/VisibilityPreset/CMP0063-WARN-obj-stderr.txt
@@ -0,0 +1,15 @@
+CMake Warning \(dev\) at CMP0063-WARN-obj.cmake:[0-9]+ \(add_library\):
+ Policy CMP0063 is not set: Honor visibility properties for all target
+ types. Run "cmake --help-policy CMP0063" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+
+ Target "myobject" of type "OBJECT_LIBRARY" has the following visibility
+ properties set for CXX:
+
+ CXX_VISIBILITY_PRESET
+ VISIBILITY_INLINES_HIDDEN
+
+ For compatibility CMake is not honoring them for this target.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/VisibilityPreset/CMP0063-WARN-obj.cmake b/Tests/RunCMake/VisibilityPreset/CMP0063-WARN-obj.cmake
new file mode 100644
index 000000000..81d1c339b
--- /dev/null
+++ b/Tests/RunCMake/VisibilityPreset/CMP0063-WARN-obj.cmake
@@ -0,0 +1,11 @@
+
+enable_language(CXX)
+
+# Ensure CMake warns even if toolchain does not really have these flags.
+set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
+set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY "-fvisibility=")
+
+set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
+set(CMAKE_CXX_VISIBILITY_PRESET hidden)
+
+add_library(myobject OBJECT lib.cpp)
diff --git a/Tests/RunCMake/VisibilityPreset/CMP0063-WARN-sta-stderr.txt b/Tests/RunCMake/VisibilityPreset/CMP0063-WARN-sta-stderr.txt
new file mode 100644
index 000000000..1efa1b5b0
--- /dev/null
+++ b/Tests/RunCMake/VisibilityPreset/CMP0063-WARN-sta-stderr.txt
@@ -0,0 +1,15 @@
+CMake Warning \(dev\) at CMP0063-WARN-sta.cmake:[0-9]+ \(add_library\):
+ Policy CMP0063 is not set: Honor visibility properties for all target
+ types. Run "cmake --help-policy CMP0063" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+
+ Target "mystatic" of type "STATIC_LIBRARY" has the following visibility
+ properties set for CXX:
+
+ CXX_VISIBILITY_PRESET
+ VISIBILITY_INLINES_HIDDEN
+
+ For compatibility CMake is not honoring them for this target.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/VisibilityPreset/CMP0063-WARN-sta.cmake b/Tests/RunCMake/VisibilityPreset/CMP0063-WARN-sta.cmake
new file mode 100644
index 000000000..132e076e2
--- /dev/null
+++ b/Tests/RunCMake/VisibilityPreset/CMP0063-WARN-sta.cmake
@@ -0,0 +1,11 @@
+
+enable_language(CXX)
+
+# Ensure CMake warns even if toolchain does not really have these flags.
+set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
+set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY "-fvisibility=")
+
+set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
+set(CMAKE_CXX_VISIBILITY_PRESET hidden)
+
+add_library(mystatic STATIC lib.cpp)
diff --git a/Tests/RunCMake/VisibilityPreset/CMakeLists.txt b/Tests/RunCMake/VisibilityPreset/CMakeLists.txt
index 90afc127e..18dfd2686 100644
--- a/Tests/RunCMake/VisibilityPreset/CMakeLists.txt
+++ b/Tests/RunCMake/VisibilityPreset/CMakeLists.txt
@@ -1,8 +1,3 @@
-
-cmake_minimum_required(VERSION 2.8.4)
-project(${RunCMake_TEST} CXX)
-
-# MSVC creates extra targets which pollute the stderr unless we set this.
-set(CMAKE_SUPPRESS_REGENERATION TRUE)
-
+cmake_minimum_required(VERSION 3.2)
+project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/VisibilityPreset/PropertyTypo.cmake b/Tests/RunCMake/VisibilityPreset/PropertyTypo.cmake
index 03c0ed9a2..c6e9dd943 100644
--- a/Tests/RunCMake/VisibilityPreset/PropertyTypo.cmake
+++ b/Tests/RunCMake/VisibilityPreset/PropertyTypo.cmake
@@ -1,3 +1,8 @@
+enable_language(CXX)
+
+# Ensure CMake warns even if toolchain does not really have these flags.
+set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
+set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY "-fvisibility=")
add_library(visibility_preset SHARED lib.cpp)
set_property(TARGET visibility_preset PROPERTY CXX_VISIBILITY_PRESET hiden)
diff --git a/Tests/RunCMake/VisibilityPreset/RunCMakeTest.cmake b/Tests/RunCMake/VisibilityPreset/RunCMakeTest.cmake
index 2d7883208..7a000ee9a 100644
--- a/Tests/RunCMake/VisibilityPreset/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VisibilityPreset/RunCMakeTest.cmake
@@ -1,3 +1,9 @@
include(RunCMake)
run_cmake(PropertyTypo)
+run_cmake(CMP0063-OLD)
+run_cmake(CMP0063-WARN-exe)
+run_cmake(CMP0063-WARN-obj)
+run_cmake(CMP0063-WARN-sta)
+run_cmake(CMP0063-WARN-no)
+run_cmake(CMP0063-NEW)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/CMakeLists.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/CMakeLists.txt
new file mode 100644
index 000000000..872338d3c
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.0)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/EmptyPrefix-result.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/EmptyPrefix-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/EmptyPrefix-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/EmptyPrefix-stderr.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/EmptyPrefix-stderr.txt
new file mode 100644
index 000000000..cf8578e26
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/EmptyPrefix-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at .*/Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\):
+ A prefix must be specified
+Call Stack \(most recent call first\):
+ EmptyPrefix.cmake:[0-9]+ \(write_compiler_detection_header\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/EmptyPrefix.cmake b/Tests/RunCMake/WriteCompilerDetectionHeader/EmptyPrefix.cmake
new file mode 100644
index 000000000..eda6b185a
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/EmptyPrefix.cmake
@@ -0,0 +1,10 @@
+
+include(WriteCompilerDetectionHeader)
+
+write_compiler_detection_header(
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/somefile"
+ PREFIX ""
+ VERSION 3.1
+ COMPILERS GNU
+ FEATURES cxx_final
+)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/ExtraArgs-result.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/ExtraArgs-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/ExtraArgs-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/ExtraArgs-stderr.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/ExtraArgs-stderr.txt
new file mode 100644
index 000000000..62c4ff1da
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/ExtraArgs-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\):
+ Unparsed arguments: GarbageArg
+Call Stack \(most recent call first\):
+ ExtraArgs.cmake:4 \(write_compiler_detection_header\)
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/ExtraArgs.cmake b/Tests/RunCMake/WriteCompilerDetectionHeader/ExtraArgs.cmake
new file mode 100644
index 000000000..c2a21af99
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/ExtraArgs.cmake
@@ -0,0 +1,10 @@
+
+include(WriteCompilerDetectionHeader)
+
+write_compiler_detection_header(
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/somefile"
+ PREFIX Pref
+ GarbageArg
+ COMPILERS GNU
+ FEATURES cxx_final
+)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/FileTypo-result.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/FileTypo-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/FileTypo-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/FileTypo-stderr.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/FileTypo-stderr.txt
new file mode 100644
index 000000000..3c0c07689
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/FileTypo-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\):
+ write_compiler_detection_header: FILE parameter missing.
+Call Stack \(most recent call first\):
+ FileTypo.cmake:4 \(write_compiler_detection_header\)
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/FileTypo.cmake b/Tests/RunCMake/WriteCompilerDetectionHeader/FileTypo.cmake
new file mode 100644
index 000000000..c90eda21e
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/FileTypo.cmake
@@ -0,0 +1,7 @@
+
+include(WriteCompilerDetectionHeader)
+
+write_compiler_detection_header(
+ FILE_TYPO "${CMAKE_CURRENT_BINARY_DIR}/somefile"
+ PREFIX Pref
+)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidArgs-result.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidArgs-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidArgs-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidArgs-stderr.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidArgs-stderr.txt
new file mode 100644
index 000000000..b4d7e08eb
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidArgs-stderr.txt
@@ -0,0 +1,11 @@
+CMake Error at InvalidArgs.cmake:4 \(write_compiler_detection_header\):
+ write_compiler_detection_header Function invoked with incorrect arguments
+ for function named: write_compiler_detection_header
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at InvalidArgs.cmake:6 \(write_compiler_detection_header\):
+ write_compiler_detection_header Function invoked with incorrect arguments
+ for function named: write_compiler_detection_header
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidArgs.cmake b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidArgs.cmake
new file mode 100644
index 000000000..cfebae13e
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidArgs.cmake
@@ -0,0 +1,6 @@
+
+include(WriteCompilerDetectionHeader)
+
+write_compiler_detection_header()
+
+write_compiler_detection_header(FILE)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidCXXFeature-result.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidCXXFeature-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidCXXFeature-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidCXXFeature-stderr.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidCXXFeature-stderr.txt
new file mode 100644
index 000000000..f34c9e198
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidCXXFeature-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\):
+ Unsupported feature cxx_not_a_feature.
+Call Stack \(most recent call first\):
+ InvalidCXXFeature.cmake:4 \(write_compiler_detection_header\)
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidCXXFeature.cmake b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidCXXFeature.cmake
new file mode 100644
index 000000000..da870fa82
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidCXXFeature.cmake
@@ -0,0 +1,10 @@
+
+include(WriteCompilerDetectionHeader)
+
+write_compiler_detection_header(
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/somefile"
+ PREFIX PREF_
+ COMPILERS GNU
+ FEATURES cxx_not_a_feature
+ VERSION 3.1
+)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidCompiler-result.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidCompiler-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidCompiler-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidCompiler-stderr.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidCompiler-stderr.txt
new file mode 100644
index 000000000..f35f9f969
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidCompiler-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\):
+ Unsupported compiler NOT_A_COMPILER.
+Call Stack \(most recent call first\):
+ InvalidCompiler.cmake:4 \(write_compiler_detection_header\)
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidCompiler.cmake b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidCompiler.cmake
new file mode 100644
index 000000000..ecd09571b
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidCompiler.cmake
@@ -0,0 +1,10 @@
+
+include(WriteCompilerDetectionHeader)
+
+write_compiler_detection_header(
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/somefile"
+ PREFIX PREF_
+ COMPILERS NOT_A_COMPILER
+ FEATURES cxx_final
+ VERSION 3.1
+)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidFeature-result.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidFeature-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidFeature-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidFeature-stderr.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidFeature-stderr.txt
new file mode 100644
index 000000000..044574404
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidFeature-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\):
+ Unsupported feature not_a_feature.
+Call Stack \(most recent call first\):
+ InvalidFeature.cmake:4 \(write_compiler_detection_header\)
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidFeature.cmake b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidFeature.cmake
new file mode 100644
index 000000000..cd839686a
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidFeature.cmake
@@ -0,0 +1,10 @@
+
+include(WriteCompilerDetectionHeader)
+
+write_compiler_detection_header(
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/somefile"
+ PREFIX PREF_
+ COMPILERS GNU
+ FEATURES not_a_feature
+ VERSION 3.1
+)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidPrefix-result.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidPrefix-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidPrefix-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidPrefix-stderr.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidPrefix-stderr.txt
new file mode 100644
index 000000000..ea1bf6703
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidPrefix-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at .*/Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\):
+ The prefix must be a valid C identifier.
+Call Stack \(most recent call first\):
+ InvalidPrefix.cmake:[0-9]+ \(write_compiler_detection_header\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidPrefix.cmake b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidPrefix.cmake
new file mode 100644
index 000000000..6599f35a9
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidPrefix.cmake
@@ -0,0 +1,10 @@
+
+include(WriteCompilerDetectionHeader)
+
+write_compiler_detection_header(
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/somefile"
+ PREFIX "0compile"
+ VERSION 3.1
+ COMPILERS GNU
+ FEATURES cxx_final
+)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/MultiBadOutDir-result.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiBadOutDir-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiBadOutDir-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/MultiBadOutDir-stderr.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiBadOutDir-stderr.txt
new file mode 100644
index 000000000..6658d5db1
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiBadOutDir-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\):
+ The compiler-specific output directory must be within the same directory as
+ the main file.
+Call Stack \(most recent call first\):
+ MultiBadOutDir.cmake:4 \(write_compiler_detection_header\)
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/MultiBadOutDir.cmake b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiBadOutDir.cmake
new file mode 100644
index 000000000..b545beef6
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiBadOutDir.cmake
@@ -0,0 +1,12 @@
+
+include(WriteCompilerDetectionHeader)
+
+write_compiler_detection_header(
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/dir/somefile"
+ PREFIX Pref
+ OUTPUT_FILES_VAR outfiles
+ OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}"
+ COMPILERS GNU
+ VERSION 3.1
+ FEATURES cxx_auto_type
+)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutFileVar-result.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutFileVar-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutFileVar-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutFileVar-stderr.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutFileVar-stderr.txt
new file mode 100644
index 000000000..50f9b6ff1
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutFileVar-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\):
+ If OUTPUT_DIR is specified, then OUTPUT_FILES_VAR must also be specified.
+Call Stack \(most recent call first\):
+ MultiNoOutFileVar.cmake:4 \(write_compiler_detection_header\)
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutFileVar.cmake b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutFileVar.cmake
new file mode 100644
index 000000000..e42b0ed68
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutFileVar.cmake
@@ -0,0 +1,11 @@
+
+include(WriteCompilerDetectionHeader)
+
+write_compiler_detection_header(
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/somefile"
+ PREFIX Pref
+ OUTPUT_DIR outfiles
+ COMPILERS GNU
+ VERSION 3.1
+ FEATURES cxx_auto_type
+)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutdir-result.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutdir-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutdir-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutdir-stderr.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutdir-stderr.txt
new file mode 100644
index 000000000..1c83a1a01
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutdir-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\):
+ If OUTPUT_FILES_VAR is specified, then OUTPUT_DIR must also be specified.
+Call Stack \(most recent call first\):
+ MultiNoOutdir.cmake:4 \(write_compiler_detection_header\)
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutdir.cmake b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutdir.cmake
new file mode 100644
index 000000000..e8c2ae14f
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutdir.cmake
@@ -0,0 +1,11 @@
+
+include(WriteCompilerDetectionHeader)
+
+write_compiler_detection_header(
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/somefile"
+ PREFIX Pref
+ OUTPUT_FILES_VAR outfiles
+ COMPILERS GNU
+ VERSION 3.1
+ FEATURES cxx_auto_type
+)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/NoCompiler-result.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/NoCompiler-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/NoCompiler-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/NoCompiler-stderr.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/NoCompiler-stderr.txt
new file mode 100644
index 000000000..9451348b2
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/NoCompiler-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\):
+ Invalid arguments. write_compiler_detection_header requires at least one
+ compiler.
+Call Stack \(most recent call first\):
+ NoCompiler.cmake:4 \(write_compiler_detection_header\)
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/NoCompiler.cmake b/Tests/RunCMake/WriteCompilerDetectionHeader/NoCompiler.cmake
new file mode 100644
index 000000000..2dc14e9a6
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/NoCompiler.cmake
@@ -0,0 +1,10 @@
+
+include(WriteCompilerDetectionHeader)
+
+write_compiler_detection_header(
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/somefile"
+ PREFIX PREF_
+ # COMPILERS
+ FEATURES cxx_final
+ VERSION 3.1
+)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/NoFeature-result.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/NoFeature-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/NoFeature-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/NoFeature-stderr.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/NoFeature-stderr.txt
new file mode 100644
index 000000000..193f297d2
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/NoFeature-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\):
+ Invalid arguments. write_compiler_detection_header requires at least one
+ feature.
+Call Stack \(most recent call first\):
+ NoFeature.cmake:4 \(write_compiler_detection_header\)
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/NoFeature.cmake b/Tests/RunCMake/WriteCompilerDetectionHeader/NoFeature.cmake
new file mode 100644
index 000000000..1fbc1292a
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/NoFeature.cmake
@@ -0,0 +1,10 @@
+
+include(WriteCompilerDetectionHeader)
+
+write_compiler_detection_header(
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/somefile"
+ PREFIX PREF_
+ COMPILERS GNU
+ # FEATURES
+ VERSION 3.1
+)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/OldVersion-result.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/OldVersion-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/OldVersion-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/OldVersion-stderr.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/OldVersion-stderr.txt
new file mode 100644
index 000000000..8d4db3431
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/OldVersion-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\):
+ VERSION compatibility for write_compiler_detection_header is set to 3.0,
+ which is too low. It must be set to at least 3.1.0. Either set the
+ VERSION parameter to the write_compiler_detection_header function, or
+ update your minimum required CMake version with the cmake_minimum_required
+ command.
+Call Stack \(most recent call first\):
+ OldVersion.cmake:4 \(write_compiler_detection_header\)
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/OldVersion.cmake b/Tests/RunCMake/WriteCompilerDetectionHeader/OldVersion.cmake
new file mode 100644
index 000000000..a6e30224c
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/OldVersion.cmake
@@ -0,0 +1,10 @@
+
+include(WriteCompilerDetectionHeader)
+
+write_compiler_detection_header(
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/somefile"
+ PREFIX Pref
+ VERSION 3.0
+ COMPILERS GNU
+ FEATURES cxx_final
+)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/PrefixTypo-result.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/PrefixTypo-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/PrefixTypo-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/PrefixTypo-stderr.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/PrefixTypo-stderr.txt
new file mode 100644
index 000000000..5fdcdb83f
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/PrefixTypo-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\):
+ write_compiler_detection_header: PREFIX parameter missing.
+Call Stack \(most recent call first\):
+ PrefixTypo.cmake:4 \(write_compiler_detection_header\)
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/PrefixTypo.cmake b/Tests/RunCMake/WriteCompilerDetectionHeader/PrefixTypo.cmake
new file mode 100644
index 000000000..8b6774c44
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/PrefixTypo.cmake
@@ -0,0 +1,7 @@
+
+include(WriteCompilerDetectionHeader)
+
+write_compiler_detection_header(
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/somefile"
+ PREFIX_TYPO Pref
+)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/RunCMakeTest.cmake b/Tests/RunCMake/WriteCompilerDetectionHeader/RunCMakeTest.cmake
new file mode 100644
index 000000000..a834e6d45
--- /dev/null
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/RunCMakeTest.cmake
@@ -0,0 +1,18 @@
+include(RunCMake)
+
+run_cmake(InvalidArgs)
+run_cmake(NoCompiler)
+run_cmake(NoFeature)
+run_cmake(FileTypo)
+run_cmake(PrefixTypo)
+run_cmake(ExtraArgs)
+run_cmake(OldVersion)
+run_cmake(InvalidCompiler)
+run_cmake(InvalidFeature)
+run_cmake(InvalidCXXFeature)
+run_cmake(EmptyPrefix)
+run_cmake(InvalidPrefix)
+run_cmake(MultiNoOutdir)
+run_cmake(MultiNoOutFileVar)
+set(NO_CACHE TRUE)
+run_cmake(MultiBadOutDir)
diff --git a/Tests/RunCMake/XcodeProject/CMakeLists.txt b/Tests/RunCMake/XcodeProject/CMakeLists.txt
new file mode 100644
index 000000000..12cd3c775
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
new file mode 100644
index 000000000..b77d5d40e
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
@@ -0,0 +1,153 @@
+include(RunCMake)
+
+run_cmake(XcodeFileType)
+run_cmake(XcodeAttributeGenex)
+run_cmake(XcodeAttributeGenexError)
+run_cmake(XcodeObjectNeedsEscape)
+run_cmake(XcodeObjectNeedsQuote)
+run_cmake(XcodeOptimizationFlags)
+run_cmake(XcodePreserveNonOptimizationFlags)
+run_cmake(XcodePreserveObjcFlag)
+if (NOT XCODE_VERSION VERSION_LESS 6)
+ run_cmake(XcodePlatformFrameworks)
+endif()
+
+# Use a single build tree for a few tests without cleaning.
+
+if(NOT XCODE_VERSION VERSION_LESS 5)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeInstallIOS-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX:PATH=${RunCMake_BINARY_DIR}/ios_install")
+
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+ run_cmake(XcodeInstallIOS)
+ run_cmake_command(XcodeInstallIOS-install ${CMAKE_COMMAND} --build . --target install)
+
+ unset(RunCMake_TEST_BINARY_DIR)
+ unset(RunCMake_TEST_NO_CLEAN)
+ unset(RunCMake_TEST_OPTIONS)
+
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeBundlesOSX-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(RunCMake_TEST_OPTIONS "-DTEST_IOS=OFF")
+
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+ run_cmake(XcodeBundles)
+ run_cmake_command(XcodeBundles-build ${CMAKE_COMMAND} --build .)
+
+ unset(RunCMake_TEST_BINARY_DIR)
+ unset(RunCMake_TEST_NO_CLEAN)
+ unset(RunCMake_TEST_OPTIONS)
+
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeBundlesIOS-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(RunCMake_TEST_OPTIONS "-DTEST_IOS=ON")
+
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+ run_cmake(XcodeBundles)
+ run_cmake_command(XcodeBundles-build ${CMAKE_COMMAND} --build .)
+
+ unset(RunCMake_TEST_BINARY_DIR)
+ unset(RunCMake_TEST_NO_CLEAN)
+ unset(RunCMake_TEST_OPTIONS)
+endif()
+
+if(NOT XCODE_VERSION VERSION_LESS 7)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeBundlesWatchOS-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(RunCMake_TEST_OPTIONS "-DTEST_WATCHOS=ON")
+
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+ run_cmake(XcodeBundles)
+ run_cmake_command(XcodeBundles-build ${CMAKE_COMMAND} --build .)
+
+ unset(RunCMake_TEST_BINARY_DIR)
+ unset(RunCMake_TEST_NO_CLEAN)
+ unset(RunCMake_TEST_OPTIONS)
+endif()
+
+if(NOT XCODE_VERSION VERSION_LESS 7.1)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeBundlesTvOS-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(RunCMake_TEST_OPTIONS "-DTEST_TVOS=ON")
+
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+ run_cmake(XcodeBundles)
+ run_cmake_command(XcodeBundles-build ${CMAKE_COMMAND} --build .)
+
+ unset(RunCMake_TEST_BINARY_DIR)
+ unset(RunCMake_TEST_NO_CLEAN)
+ unset(RunCMake_TEST_OPTIONS)
+endif()
+
+if(NOT XCODE_VERSION VERSION_LESS 7)
+ set(RunCMake_TEST_OPTIONS "-DCMAKE_TOOLCHAIN_FILE=${RunCMake_SOURCE_DIR}/osx.cmake")
+ run_cmake(XcodeTbdStub)
+ unset(RunCMake_TEST_OPTIONS)
+endif()
+
+if(NOT XCODE_VERSION VERSION_LESS 6)
+ # XcodeIOSInstallCombined
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeIOSInstallCombined-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(RunCMake_TEST_OPTIONS
+ "-DCMAKE_INSTALL_PREFIX:PATH=${RunCMake_TEST_BINARY_DIR}/_install"
+ "-DCMAKE_IOS_INSTALL_COMBINED=YES")
+
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+ run_cmake(XcodeIOSInstallCombined)
+ run_cmake_command(XcodeIOSInstallCombined-build ${CMAKE_COMMAND} --build .)
+ run_cmake_command(XcodeIOSInstallCombined-install ${CMAKE_COMMAND} --build . --target install)
+
+ unset(RunCMake_TEST_BINARY_DIR)
+ unset(RunCMake_TEST_NO_CLEAN)
+ unset(RunCMake_TEST_OPTIONS)
+
+ # XcodeIOSInstallCombinedPrune
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeIOSInstallCombinedPrune-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(RunCMake_TEST_OPTIONS
+ "-DCMAKE_INSTALL_PREFIX:PATH=${RunCMake_TEST_BINARY_DIR}/_install"
+ "-DCMAKE_IOS_INSTALL_COMBINED=YES")
+
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+ run_cmake(XcodeIOSInstallCombinedPrune)
+ run_cmake_command(XcodeIOSInstallCombinedPrune-build ${CMAKE_COMMAND} --build .)
+ run_cmake_command(XcodeIOSInstallCombinedPrune-install ${CMAKE_COMMAND} --build . --target install)
+
+ unset(RunCMake_TEST_BINARY_DIR)
+ unset(RunCMake_TEST_NO_CLEAN)
+ unset(RunCMake_TEST_OPTIONS)
+
+ # XcodeIOSInstallCombinedSingleArch
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeIOSInstallCombinedSingleArch-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(RunCMake_TEST_OPTIONS
+ "-DCMAKE_INSTALL_PREFIX:PATH=${RunCMake_TEST_BINARY_DIR}/_install"
+ "-DCMAKE_IOS_INSTALL_COMBINED=YES")
+
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+ run_cmake(XcodeIOSInstallCombinedSingleArch)
+ run_cmake_command(XcodeIOSInstallCombinedSingleArch-build ${CMAKE_COMMAND} --build .)
+ run_cmake_command(XcodeIOSInstallCombinedSingleArch-install ${CMAKE_COMMAND} --build . --target install)
+
+ unset(RunCMake_TEST_BINARY_DIR)
+ unset(RunCMake_TEST_NO_CLEAN)
+ unset(RunCMake_TEST_OPTIONS)
+endif()
diff --git a/Tests/RunCMake/XcodeProject/XcodeAttributeGenex-check.cmake b/Tests/RunCMake/XcodeProject/XcodeAttributeGenex-check.cmake
new file mode 100644
index 000000000..8a3950671
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeAttributeGenex-check.cmake
@@ -0,0 +1,55 @@
+# per target attribute with genex
+
+set(expect "TEST_HOST = \"[^;\"]*Tests/RunCMake/XcodeProject/XcodeAttributeGenex-build/[^;\"/]*/some\"")
+file(STRINGS ${RunCMake_TEST_BINARY_DIR}/XcodeAttributeGenex.xcodeproj/project.pbxproj actual
+ REGEX "TEST_HOST = .*;" LIMIT_COUNT 1)
+if(NOT "${actual}" MATCHES "${expect}")
+ message(SEND_ERROR "The actual project contains the line:\n ${actual}\n"
+ "which does not match expected regex:\n ${expect}\n")
+endif()
+
+# per target attribute with variant
+
+file(STRINGS ${RunCMake_TEST_BINARY_DIR}/XcodeAttributeGenex.xcodeproj/project.pbxproj actual
+ REGEX "CONFIG_SPECIFIC = .*;")
+list(REMOVE_DUPLICATES actual)
+
+set(expect "CONFIG_SPECIFIC = general")
+if(NOT "${actual}" MATCHES "${expect}")
+ message(SEND_ERROR "The actual project contains the line:\n ${actual}\n"
+ "which does not match expected regex:\n ${expect}\n")
+endif()
+
+set(expect "CONFIG_SPECIFIC = release")
+if(NOT "${actual}" MATCHES "${expect}")
+ message(SEND_ERROR "The actual project contains the line:\n ${actual}\n"
+ "which does not match expected regex:\n ${expect}\n")
+endif()
+
+# global attribute with genex
+
+set(expect "ANOTHER_GLOBAL = \"[^;\"]*Tests/RunCMake/XcodeProject/XcodeAttributeGenex-build/[^;\"/]*/another\"")
+file(STRINGS ${RunCMake_TEST_BINARY_DIR}/XcodeAttributeGenex.xcodeproj/project.pbxproj actual
+ REGEX "ANOTHER_GLOBAL = .*;" LIMIT_COUNT 1)
+if(NOT "${actual}" MATCHES "${expect}")
+ message(SEND_ERROR "The actual project contains the line:\n ${actual}\n"
+ "which does not match expected regex:\n ${expect}\n")
+endif()
+
+# global attribute with variant
+
+file(STRINGS ${RunCMake_TEST_BINARY_DIR}/XcodeAttributeGenex.xcodeproj/project.pbxproj actual
+ REGEX "ANOTHER_CONFIG = .*;" LIMIT_COUNT 4)
+list(REMOVE_DUPLICATES actual)
+
+set(expect "ANOTHER_CONFIG = general")
+if(NOT "${actual}" MATCHES "${expect}")
+ message(SEND_ERROR "The actual project contains the line:\n ${actual}\n"
+ "which does not match expected regex:\n ${expect}\n")
+endif()
+
+set(expect "ANOTHER_CONFIG = debug")
+if(NOT "${actual}" MATCHES "${expect}")
+ message(SEND_ERROR "The actual project contains the line:\n ${actual}\n"
+ "which does not match expected regex:\n ${expect}\n")
+endif()
diff --git a/Tests/RunCMake/XcodeProject/XcodeAttributeGenex.cmake b/Tests/RunCMake/XcodeProject/XcodeAttributeGenex.cmake
new file mode 100644
index 000000000..d8cb3bd23
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeAttributeGenex.cmake
@@ -0,0 +1,16 @@
+enable_language(C)
+add_executable(some main.c)
+add_executable(another main.c)
+set_target_properties(another PROPERTIES
+ # per target attribute with genex
+ XCODE_ATTRIBUTE_TEST_HOST "$<TARGET_FILE:some>"
+ # per target attribute with variant
+ XCODE_ATTRIBUTE_CONFIG_SPECIFIC[variant=Release] "release"
+ XCODE_ATTRIBUTE_CONFIG_SPECIFIC "general")
+
+# global attribute with genex
+set(CMAKE_XCODE_ATTRIBUTE_ANOTHER_GLOBAL "$<TARGET_FILE:another>")
+
+# global attribute with variant
+set(CMAKE_XCODE_ATTRIBUTE_ANOTHER_CONFIG "general")
+set(CMAKE_XCODE_ATTRIBUTE_ANOTHER_CONFIG[variant=Debug] "debug")
diff --git a/Tests/RunCMake/XcodeProject/XcodeAttributeGenexError-result.txt b/Tests/RunCMake/XcodeProject/XcodeAttributeGenexError-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeAttributeGenexError-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/XcodeProject/XcodeAttributeGenexError-stderr.txt b/Tests/RunCMake/XcodeProject/XcodeAttributeGenexError-stderr.txt
new file mode 100644
index 000000000..984415868
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeAttributeGenexError-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error:
+ Error evaluating generator expression:
+
+ \$<NOTAGENEX>
+
+ Expression did not evaluate to a known generator expression
diff --git a/Tests/RunCMake/XcodeProject/XcodeAttributeGenexError.cmake b/Tests/RunCMake/XcodeProject/XcodeAttributeGenexError.cmake
new file mode 100644
index 000000000..98ad6c5a8
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeAttributeGenexError.cmake
@@ -0,0 +1,4 @@
+enable_language(C)
+add_executable(some main.c)
+add_executable(another main.c)
+set_property(TARGET another PROPERTY XCODE_ATTRIBUTE_TEST_HOST "$<NOTAGENEX>")
diff --git a/Tests/RunCMake/XcodeProject/XcodeBundles.cmake b/Tests/RunCMake/XcodeProject/XcodeBundles.cmake
new file mode 100644
index 000000000..0fdc6af59
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeBundles.cmake
@@ -0,0 +1,63 @@
+# check if Xcode and CMake have the same understanding of Bundle layout
+
+cmake_minimum_required(VERSION 3.3)
+enable_language(C)
+
+if(TEST_IOS)
+ set(CMAKE_OSX_SYSROOT iphoneos)
+ set(CMAKE_OSX_ARCHITECTURES "armv7")
+ set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
+ set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO")
+endif(TEST_IOS)
+
+if(TEST_WATCHOS)
+ set(CMAKE_OSX_SYSROOT watchos)
+ set(CMAKE_OSX_ARCHITECTURES "armv7k")
+ set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
+ set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "")
+ set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "YES")
+endif()
+
+if(TEST_TVOS)
+ set(CMAKE_OSX_SYSROOT appletvos)
+ set(CMAKE_OSX_ARCHITECTURES "arm64")
+ set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
+ set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "")
+ set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "YES")
+endif()
+
+# App Bundle
+
+add_executable(AppBundle MACOSX_BUNDLE main.m)
+
+add_custom_target(AppBundleTest ALL
+ COMMAND ${CMAKE_COMMAND} -E copy
+ "$<TARGET_FILE:AppBundle>" "$<TARGET_FILE:AppBundle>.old")
+
+add_dependencies(AppBundleTest AppBundle)
+
+# Framework (not supported for iOS on Xcode < 6)
+
+if(NOT TEST_IOS OR NOT XCODE_VERSION VERSION_LESS 6)
+ add_library(Framework SHARED main.c)
+ set_target_properties(Framework PROPERTIES FRAMEWORK TRUE)
+
+ add_custom_target(FrameworkTest ALL
+ COMMAND ${CMAKE_COMMAND} -E copy
+ "$<TARGET_FILE:Framework>" "$<TARGET_FILE:Framework>.old")
+
+ add_dependencies(FrameworkTest Framework)
+endif()
+
+# Bundle
+
+if(NOT CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE)
+ add_library(Bundle MODULE main.c)
+ set_target_properties(Bundle PROPERTIES BUNDLE TRUE)
+
+ add_custom_target(BundleTest ALL
+ COMMAND ${CMAKE_COMMAND} -E copy
+ "$<TARGET_FILE:Bundle>" "$<TARGET_FILE:Bundle>.old")
+
+ add_dependencies(BundleTest Bundle)
+endif()
diff --git a/Tests/RunCMake/XcodeProject/XcodeFileType-check.cmake b/Tests/RunCMake/XcodeProject/XcodeFileType-check.cmake
new file mode 100644
index 000000000..1847bc986
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeFileType-check.cmake
@@ -0,0 +1,10 @@
+set(expect-default "explicitFileType = sourcecode")
+set(expect-explicit "explicitFileType = sourcecode.c.h")
+set(expect-lastKnown "lastKnownFileType = sourcecode.c.h")
+foreach(src default explicit lastKnown)
+ file(STRINGS ${RunCMake_TEST_BINARY_DIR}/XcodeFileType.xcodeproj/project.pbxproj actual-${src}
+ REGEX "PBXFileReference.*src-${src}")
+ if(NOT actual-${src} MATCHES "${expect-${src}}")
+ message(SEND_ERROR "src-${src} does not match '${expect-${src}}':\n ${actual-${src}}")
+ endif()
+endforeach()
diff --git a/Tests/RunCMake/XcodeProject/XcodeFileType.cmake b/Tests/RunCMake/XcodeProject/XcodeFileType.cmake
new file mode 100644
index 000000000..7faa78151
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeFileType.cmake
@@ -0,0 +1,4 @@
+enable_language(C)
+add_executable(main main.c src-default src-explicit src-lastKnown)
+set_property(SOURCE src-explicit PROPERTY XCODE_EXPLICIT_FILE_TYPE sourcecode.c.h)
+set_property(SOURCE src-lastKnown PROPERTY XCODE_LAST_KNOWN_FILE_TYPE sourcecode.c.h)
diff --git a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined-install-check.cmake b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined-install-check.cmake
new file mode 100644
index 000000000..a1c06718f
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined-install-check.cmake
@@ -0,0 +1,30 @@
+function(verify_architectures file)
+ execute_process(
+ COMMAND xcrun otool -vf ${RunCMake_TEST_BINARY_DIR}/_install/${file}
+ OUTPUT_VARIABLE otool_out
+ ERROR_VARIABLE otool_err
+ RESULT_VARIABLE otool_result)
+ if(NOT otool_result EQUAL "0")
+ message(SEND_ERROR "Could not retrieve fat headers: ${otool_err}")
+ return()
+ endif()
+
+ string(REGEX MATCHALL "architecture [^ \n\t]+" architectures ${otool_out})
+ string(REPLACE "architecture " "" actual "${architectures}")
+ list(SORT actual)
+
+ set(expected arm64 armv7 i386 x86_64)
+
+ if(NOT actual STREQUAL expected)
+ message(SEND_ERROR
+ "The actual library contains the architectures:\n ${actual} \n"
+ "which do not match expected ones:\n ${expected} \n"
+ "otool output:\n${otool_out}")
+ endif()
+endfunction()
+
+verify_architectures(bin/foo_app.app/foo_app)
+verify_architectures(lib/libfoo_static.a)
+verify_architectures(lib/libfoo_shared.dylib)
+verify_architectures(lib/foo_bundle.bundle/foo_bundle)
+verify_architectures(lib/foo_framework.framework/foo_framework)
diff --git a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined.cmake b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined.cmake
new file mode 100644
index 000000000..fc830b19e
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined.cmake
@@ -0,0 +1,27 @@
+cmake_minimum_required(VERSION 3.3)
+
+project(IOSInstallCombined CXX)
+
+set(CMAKE_OSX_SYSROOT iphoneos)
+set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
+set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf")
+set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO")
+
+set(CMAKE_OSX_ARCHITECTURES "armv7;arm64;i386;x86_64")
+
+add_executable(foo_app MACOSX_BUNDLE main.cpp)
+install(TARGETS foo_app BUNDLE DESTINATION bin)
+
+add_library(foo_static STATIC foo.cpp)
+install(TARGETS foo_static ARCHIVE DESTINATION lib)
+
+add_library(foo_shared SHARED foo.cpp)
+install(TARGETS foo_shared LIBRARY DESTINATION lib)
+
+add_library(foo_bundle MODULE foo.cpp)
+set_target_properties(foo_bundle PROPERTIES BUNDLE TRUE)
+install(TARGETS foo_bundle LIBRARY DESTINATION lib)
+
+add_library(foo_framework SHARED foo.cpp)
+set_target_properties(foo_framework PROPERTIES FRAMEWORK TRUE)
+install(TARGETS foo_framework FRAMEWORK DESTINATION lib)
diff --git a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune-install-check.cmake b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune-install-check.cmake
new file mode 100644
index 000000000..83da17da7
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune-install-check.cmake
@@ -0,0 +1,26 @@
+function(verify_architectures file)
+ execute_process(
+ COMMAND xcrun otool -vf ${RunCMake_TEST_BINARY_DIR}/_install/${file}
+ OUTPUT_VARIABLE otool_out
+ ERROR_VARIABLE otool_err
+ RESULT_VARIABLE otool_result)
+ if(NOT otool_result EQUAL "0")
+ message(SEND_ERROR "Could not retrieve fat headers: ${otool_err}")
+ return()
+ endif()
+
+ string(REGEX MATCHALL "architecture [^ \n\t]+" architectures ${otool_out})
+ string(REPLACE "architecture " "" actual "${architectures}")
+ list(SORT actual)
+
+ set(expected armv7 x86_64)
+
+ if(NOT actual STREQUAL expected)
+ message(SEND_ERROR
+ "The actual library contains the architectures:\n ${actual} \n"
+ "which do not match expected ones:\n ${expected} \n"
+ "otool output:\n${otool_out}")
+ endif()
+endfunction()
+
+verify_architectures(lib/libfoo.dylib)
diff --git a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune-install-stdout.txt b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune-install-stdout.txt
new file mode 100644
index 000000000..28edadc6b
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune-install-stdout.txt
@@ -0,0 +1,2 @@
+.*Unexpected architecture `i386` detected.*
+.*Unexpected architecture `arm64` detected.* \ No newline at end of file
diff --git a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune.cmake b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune.cmake
new file mode 100644
index 000000000..b47d3a597
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune.cmake
@@ -0,0 +1,36 @@
+cmake_minimum_required(VERSION 3.3)
+
+project(XcodeIOSInstallCombinedPrune CXX)
+
+set(CMAKE_OSX_SYSROOT iphoneos)
+set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
+set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf")
+
+add_library(foo SHARED foo.cpp)
+install(TARGETS foo DESTINATION lib)
+
+add_library(baz SHARED foo.cpp)
+set_target_properties(
+ foo baz
+ PROPERTIES
+ XCODE_ATTRIBUTE_ARCHS[sdk=iphoneos*] armv7
+ XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphoneos*] armv7
+ XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] x86_64
+ XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphonesimulator*] x86_64
+)
+
+add_library(boo SHARED foo.cpp)
+set_target_properties(
+ boo
+ PROPERTIES
+ XCODE_ATTRIBUTE_ARCHS[sdk=iphoneos*] arm64
+ XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphoneos*] arm64
+ XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] i386
+ XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphonesimulator*] i386
+)
+
+add_custom_command(
+ TARGET foo
+ POST_BUILD
+ COMMAND lipo -create $<TARGET_FILE:baz> $<TARGET_FILE:boo> -output $<TARGET_FILE:foo>
+)
diff --git a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedSingleArch-install-check.cmake b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedSingleArch-install-check.cmake
new file mode 100644
index 000000000..3c11ae0ee
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedSingleArch-install-check.cmake
@@ -0,0 +1,25 @@
+function(verify_architecture file)
+ execute_process(
+ COMMAND xcrun lipo -info ${RunCMake_TEST_BINARY_DIR}/_install/${file}
+ OUTPUT_VARIABLE lipo_out
+ ERROR_VARIABLE lipo_err
+ RESULT_VARIABLE lipo_result)
+ if(NOT lipo_result EQUAL "0")
+ message(SEND_ERROR "lipo -info failed: ${lipo_err}")
+ return()
+ endif()
+
+ string(REGEX MATCHALL "is architecture: [^ \n\t]+" architecture "${lipo_out}")
+ string(REGEX REPLACE "is architecture: " "" actual "${architecture}")
+
+ set(expected armv7)
+
+ if(NOT actual STREQUAL expected)
+ message(SEND_ERROR
+ "The actual library architecture:\n ${actual} \n"
+ "which do not match expected ones:\n ${expected} \n"
+ "lipo output:\n${lipo_out}")
+ endif()
+endfunction()
+
+verify_architecture(lib/libfoo.dylib)
diff --git a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedSingleArch.cmake b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedSingleArch.cmake
new file mode 100644
index 000000000..4b5e7ce36
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedSingleArch.cmake
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 3.3)
+
+project(XcodeIOSInstallCombinedSingleArch CXX)
+
+set(CMAKE_OSX_SYSROOT iphoneos)
+set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
+set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf")
+
+add_library(foo SHARED foo.cpp)
+install(TARGETS foo DESTINATION lib)
+
+set_target_properties(
+ foo
+ PROPERTIES
+ XCODE_ATTRIBUTE_ARCHS[sdk=iphoneos*] armv7
+ XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphoneos*] armv7
+ XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] ""
+ XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphonesimulator*] ""
+)
diff --git a/Tests/RunCMake/XcodeProject/XcodeInstallIOS-install-stdout.txt b/Tests/RunCMake/XcodeProject/XcodeInstallIOS-install-stdout.txt
new file mode 100644
index 000000000..f2478be86
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeInstallIOS-install-stdout.txt
@@ -0,0 +1,2 @@
+-- Install configuration: .*
+-- Installing: .*/ios_install/lib/libfoo.a
diff --git a/Tests/RunCMake/XcodeProject/XcodeInstallIOS.cmake b/Tests/RunCMake/XcodeProject/XcodeInstallIOS.cmake
new file mode 100644
index 000000000..a79741069
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeInstallIOS.cmake
@@ -0,0 +1,12 @@
+cmake_minimum_required(VERSION 2.8.5)
+
+project(XcodeInstallIOS)
+
+set(CMAKE_OSX_SYSROOT iphoneos)
+set(XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
+set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO")
+
+set(CMAKE_OSX_ARCHITECTURES "armv7;i386")
+
+add_library(foo STATIC foo.cpp)
+install(TARGETS foo ARCHIVE DESTINATION lib)
diff --git a/Tests/RunCMake/XcodeProject/XcodeObjectNeedsEscape-check.cmake b/Tests/RunCMake/XcodeProject/XcodeObjectNeedsEscape-check.cmake
new file mode 100644
index 000000000..c34e3feb6
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeObjectNeedsEscape-check.cmake
@@ -0,0 +1,7 @@
+set(expect "-DKDESRCDIR=\\\\\\\\\\\\\"foo\\\\\\\\\\\\\"")
+file(STRINGS ${RunCMake_TEST_BINARY_DIR}/XcodeObjectNeedsEscape.xcodeproj/project.pbxproj actual
+ REGEX "OTHER_CPLUSPLUSFLAGS = [^;]*;" LIMIT_COUNT 1)
+if(NOT "${actual}" MATCHES "${expect}")
+ message(SEND_ERROR "The actual project contains the line:\n ${actual}\n"
+ "which does not match expected regex:\n ${expect}\n")
+endif()
diff --git a/Tests/RunCMake/XcodeProject/XcodeObjectNeedsEscape.cmake b/Tests/RunCMake/XcodeProject/XcodeObjectNeedsEscape.cmake
new file mode 100644
index 000000000..7606a1906
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeObjectNeedsEscape.cmake
@@ -0,0 +1,3 @@
+enable_language(CXX)
+string(APPEND CMAKE_CXX_FLAGS " -DKDESRCDIR=\\\"foo\\\"")
+add_library(foo STATIC foo.cpp)
diff --git a/Tests/RunCMake/XcodeProject/XcodeObjectNeedsQuote-check.cmake b/Tests/RunCMake/XcodeProject/XcodeObjectNeedsQuote-check.cmake
new file mode 100644
index 000000000..be7d96ab6
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeObjectNeedsQuote-check.cmake
@@ -0,0 +1,7 @@
+set(expect "path = \"")
+file(STRINGS ${RunCMake_TEST_BINARY_DIR}/XcodeObjectNeedsQuote.xcodeproj/project.pbxproj actual
+ REGEX "path = [^;]*someFileWithoutSpecialChars[^;]*;" LIMIT_COUNT 1)
+if(NOT "${actual}" MATCHES "${expect}")
+ message(SEND_ERROR "The actual project contains the line:\n ${actual}\n"
+ "which does not match expected regex:\n ${expect}\n")
+endif()
diff --git a/Tests/RunCMake/XcodeProject/XcodeObjectNeedsQuote.cmake b/Tests/RunCMake/XcodeProject/XcodeObjectNeedsQuote.cmake
new file mode 100644
index 000000000..ecc56abb7
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeObjectNeedsQuote.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+add_library(some /${CMAKE_CURRENT_SOURCE_DIR}/someFileWithoutSpecialChars)
+set_property(SOURCE /${CMAKE_CURRENT_SOURCE_DIR}/someFileWithoutSpecialChars PROPERTY LANGUAGE C)
diff --git a/Tests/RunCMake/XcodeProject/XcodeOptimizationFlags-check.cmake b/Tests/RunCMake/XcodeProject/XcodeOptimizationFlags-check.cmake
new file mode 100644
index 000000000..f5595b315
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeOptimizationFlags-check.cmake
@@ -0,0 +1,7 @@
+foreach(level 1 2 3 s fast)
+ file(STRINGS ${RunCMake_TEST_BINARY_DIR}/XcodeOptimizationFlags.xcodeproj/project.pbxproj actual-${level}
+ REGEX "GCC_OPTIMIZATION_LEVEL = ${level};" LIMIT_COUNT 1)
+ if(NOT actual-${level})
+ message(SEND_ERROR "Optimization level '${level}' not found in Xcode project.")
+ endif()
+endforeach()
diff --git a/Tests/RunCMake/XcodeProject/XcodeOptimizationFlags.cmake b/Tests/RunCMake/XcodeProject/XcodeOptimizationFlags.cmake
new file mode 100644
index 000000000..e14bf808d
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeOptimizationFlags.cmake
@@ -0,0 +1,20 @@
+set(CMAKE_CONFIGURATION_TYPES "Release" CACHE INTERNAL "Supported configuration types")
+
+set(CMAKE_CXX_FLAGS_RELEASE "")
+
+project(XcodeOptimizationFlags CXX)
+
+add_library(fooO1 STATIC foo.cpp)
+set_target_properties(fooO1 PROPERTIES COMPILE_OPTIONS -O1)
+
+add_library(fooO2 STATIC foo.cpp)
+set_target_properties(fooO2 PROPERTIES COMPILE_OPTIONS -O2)
+
+add_library(fooO3 STATIC foo.cpp)
+set_target_properties(fooO3 PROPERTIES COMPILE_OPTIONS -O3)
+
+add_library(fooOs STATIC foo.cpp)
+set_target_properties(fooOs PROPERTIES COMPILE_OPTIONS -Os)
+
+add_library(fooOfast STATIC foo.cpp)
+set_target_properties(fooOfast PROPERTIES COMPILE_OPTIONS -Ofast)
diff --git a/Tests/RunCMake/XcodeProject/XcodePlatformFrameworks.cmake b/Tests/RunCMake/XcodeProject/XcodePlatformFrameworks.cmake
new file mode 100644
index 000000000..74dc9783e
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodePlatformFrameworks.cmake
@@ -0,0 +1,6 @@
+enable_language(C)
+
+find_library(XCTEST_LIBRARY XCTest)
+if(NOT XCTEST_LIBRARY)
+ message(FATAL_ERROR "XCTest Framework not found.")
+endif()
diff --git a/Tests/RunCMake/XcodeProject/XcodePreserveNonOptimizationFlags-check.cmake b/Tests/RunCMake/XcodeProject/XcodePreserveNonOptimizationFlags-check.cmake
new file mode 100644
index 000000000..2f6c03d20
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodePreserveNonOptimizationFlags-check.cmake
@@ -0,0 +1,8 @@
+file(STRINGS ${RunCMake_TEST_BINARY_DIR}/XcodePreserveNonOptimizationFlags.xcodeproj/project.pbxproj actual
+ REGEX "OTHER_CPLUSPLUSFLAGS = [^;]*;")
+foreach(expect "-DA" "-DB +-DC" "-DD")
+ if(NOT "${actual}" MATCHES "${expect}")
+ message(SEND_ERROR "The actual project contains the lines:\n ${actual}\n"
+ "which do not match expected regex:\n ${expect}\n")
+ endif()
+endforeach()
diff --git a/Tests/RunCMake/XcodeProject/XcodePreserveNonOptimizationFlags.cmake b/Tests/RunCMake/XcodeProject/XcodePreserveNonOptimizationFlags.cmake
new file mode 100644
index 000000000..16f038184
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodePreserveNonOptimizationFlags.cmake
@@ -0,0 +1,12 @@
+set(CMAKE_CONFIGURATION_TYPES "Release" CACHE INTERNAL "Supported configuration types")
+
+project(XcodePreserveNonOptimizationFlags CXX)
+
+add_library(preserveStart STATIC foo.cpp)
+set_property(TARGET preserveStart PROPERTY COMPILE_OPTIONS -DA -O1)
+
+add_library(preserveBoth STATIC foo.cpp)
+set_property(TARGET preserveBoth PROPERTY COMPILE_OPTIONS -DB -O1 -DC)
+
+add_library(preserveEnd STATIC foo.cpp)
+set_property(TARGET preserveEnd PROPERTY COMPILE_OPTIONS -O1 -DD)
diff --git a/Tests/RunCMake/XcodeProject/XcodePreserveObjcFlag-check.cmake b/Tests/RunCMake/XcodeProject/XcodePreserveObjcFlag-check.cmake
new file mode 100644
index 000000000..332906f8e
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodePreserveObjcFlag-check.cmake
@@ -0,0 +1,7 @@
+set(expect "-ObjC")
+file(STRINGS ${RunCMake_TEST_BINARY_DIR}/XcodePreserveObjcFlag.xcodeproj/project.pbxproj actual
+ REGEX "OTHER_CPLUSPLUSFLAGS = [^;]*;" LIMIT_COUNT 1)
+if(NOT "${actual}" MATCHES "${expect}")
+ message(SEND_ERROR "The actual project contains the line:\n ${actual}\n"
+ "which does not match expected regex:\n ${expect}\n")
+endif()
diff --git a/Tests/RunCMake/XcodeProject/XcodePreserveObjcFlag.cmake b/Tests/RunCMake/XcodeProject/XcodePreserveObjcFlag.cmake
new file mode 100644
index 000000000..64db63334
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodePreserveObjcFlag.cmake
@@ -0,0 +1,6 @@
+set(CMAKE_CONFIGURATION_TYPES "Release" CACHE INTERNAL "Supported configuration types")
+
+project(XcodePreserveObjcFlag CXX)
+
+add_library(foo STATIC foo.cpp)
+set_target_properties(foo PROPERTIES COMPILE_OPTIONS -ObjC)
diff --git a/Tests/RunCMake/XcodeProject/XcodeTbdStub-stdout.txt b/Tests/RunCMake/XcodeProject/XcodeTbdStub-stdout.txt
new file mode 100644
index 000000000..9d9e14393
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeTbdStub-stdout.txt
@@ -0,0 +1 @@
+.*/libz\.tbd.*
diff --git a/Tests/RunCMake/XcodeProject/XcodeTbdStub.cmake b/Tests/RunCMake/XcodeProject/XcodeTbdStub.cmake
new file mode 100644
index 000000000..e83d7f3cd
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeTbdStub.cmake
@@ -0,0 +1,2 @@
+cmake_minimum_required(VERSION 3.3)
+find_package(ZLIB REQUIRED)
diff --git a/Tests/RunCMake/XcodeProject/foo.cpp b/Tests/RunCMake/XcodeProject/foo.cpp
new file mode 100644
index 000000000..2fb55eed6
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/foo.cpp
@@ -0,0 +1 @@
+void foo() { }
diff --git a/Tests/RunCMake/XcodeProject/main.c b/Tests/RunCMake/XcodeProject/main.c
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/main.c
diff --git a/Tests/RunCMake/XcodeProject/main.cpp b/Tests/RunCMake/XcodeProject/main.cpp
new file mode 100644
index 000000000..1695921f2
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/main.cpp
@@ -0,0 +1,3 @@
+int main(int argc, const char * argv[]) {
+ return 0;
+}
diff --git a/Tests/RunCMake/XcodeProject/main.m b/Tests/RunCMake/XcodeProject/main.m
new file mode 100644
index 000000000..6dc190ad8
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/main.m
@@ -0,0 +1,3 @@
+int main(int argc, const char * argv[]) {
+ return 1;
+}
diff --git a/Tests/RunCMake/XcodeProject/osx.cmake b/Tests/RunCMake/XcodeProject/osx.cmake
new file mode 100644
index 000000000..e021fcd45
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/osx.cmake
@@ -0,0 +1,18 @@
+set(CMAKE_SYSTEM_NAME Darwin)
+set(CMAKE_SYSTEM_VERSION 1)
+set(UNIX True)
+set(APPLE True)
+
+find_program(XCRUN_EXECUTABLE xcrun)
+if(NOT XCRUN_EXECUTABLE)
+ message(FATAL_ERROR "xcrun not found")
+endif()
+
+execute_process(
+ COMMAND ${XCRUN_EXECUTABLE} --sdk macosx --show-sdk-path
+ OUTPUT_VARIABLE OSX_SDK_PATH
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+set(CMAKE_OSX_SYSROOT ${OSX_SDK_PATH} CACHE PATH "Sysroot used for OSX support")
+
+set(CMAKE_FIND_ROOT_PATH ${OSX_SDK_PATH} CACHE PATH "Find search path root")
diff --git a/Tests/RunCMake/XcodeProject/someFileWithoutSpecialChars b/Tests/RunCMake/XcodeProject/someFileWithoutSpecialChars
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/someFileWithoutSpecialChars
diff --git a/Tests/RunCMake/XcodeProject/src-default b/Tests/RunCMake/XcodeProject/src-default
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/src-default
diff --git a/Tests/RunCMake/XcodeProject/src-explicit b/Tests/RunCMake/XcodeProject/src-explicit
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/src-explicit
diff --git a/Tests/RunCMake/XcodeProject/src-lastKnown b/Tests/RunCMake/XcodeProject/src-lastKnown
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/src-lastKnown
diff --git a/Tests/RunCMake/add_custom_command/AppendNoOutput-result.txt b/Tests/RunCMake/add_custom_command/AppendNoOutput-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/AppendNoOutput-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_custom_command/AppendNoOutput-stderr.txt b/Tests/RunCMake/add_custom_command/AppendNoOutput-stderr.txt
new file mode 100644
index 000000000..abbfc5a3e
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/AppendNoOutput-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at AppendNoOutput.cmake:1 \(add_custom_command\):
+ add_custom_command given APPEND option with no OUTPUT.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/add_custom_command/AppendNoOutput.cmake b/Tests/RunCMake/add_custom_command/AppendNoOutput.cmake
new file mode 100644
index 000000000..c6c716b0d
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/AppendNoOutput.cmake
@@ -0,0 +1 @@
+add_custom_command(TARGET x APPEND DEPENDS a b c d)
diff --git a/Tests/RunCMake/add_custom_command/AppendNotOutput-result.txt b/Tests/RunCMake/add_custom_command/AppendNotOutput-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/AppendNotOutput-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_custom_command/AppendNotOutput-stderr.txt b/Tests/RunCMake/add_custom_command/AppendNotOutput-stderr.txt
new file mode 100644
index 000000000..96d097228
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/AppendNotOutput-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at AppendNotOutput.cmake:1 \(add_custom_command\):
+ add_custom_command given APPEND option with output.*
+ which is not already a custom command output.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/add_custom_command/AppendNotOutput.cmake b/Tests/RunCMake/add_custom_command/AppendNotOutput.cmake
new file mode 100644
index 000000000..cc1612980
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/AppendNotOutput.cmake
@@ -0,0 +1 @@
+add_custom_command(OUTPUT out APPEND DEPENDS dep)
diff --git a/Tests/RunCMake/add_custom_command/BadArgument-result.txt b/Tests/RunCMake/add_custom_command/BadArgument-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/BadArgument-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_custom_command/BadArgument-stderr.txt b/Tests/RunCMake/add_custom_command/BadArgument-stderr.txt
new file mode 100644
index 000000000..04c5350cd
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/BadArgument-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at BadArgument.cmake:1 \(add_custom_command\):
+ add_custom_command Wrong syntax. Unknown type of argument.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/add_custom_command/BadArgument.cmake b/Tests/RunCMake/add_custom_command/BadArgument.cmake
new file mode 100644
index 000000000..d9e7bd45b
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/BadArgument.cmake
@@ -0,0 +1 @@
+add_custom_command(bad_arg OUTPUT a b c d)
diff --git a/Tests/RunCMake/add_custom_command/CMakeLists.txt b/Tests/RunCMake/add_custom_command/CMakeLists.txt
new file mode 100644
index 000000000..ef2163c29
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.1)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/add_custom_command/NoArguments-result.txt b/Tests/RunCMake/add_custom_command/NoArguments-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/NoArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_custom_command/NoArguments-stderr.txt b/Tests/RunCMake/add_custom_command/NoArguments-stderr.txt
new file mode 100644
index 000000000..11e0cb0dc
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/NoArguments-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at NoArguments.cmake:1 \(add_custom_command\):
+ add_custom_command called with wrong number of arguments.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/add_custom_command/NoArguments.cmake b/Tests/RunCMake/add_custom_command/NoArguments.cmake
new file mode 100644
index 000000000..8781a87a8
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/NoArguments.cmake
@@ -0,0 +1 @@
+add_custom_command()
diff --git a/Tests/RunCMake/add_custom_command/NoOutputOrTarget-result.txt b/Tests/RunCMake/add_custom_command/NoOutputOrTarget-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/NoOutputOrTarget-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_custom_command/NoOutputOrTarget-stderr.txt b/Tests/RunCMake/add_custom_command/NoOutputOrTarget-stderr.txt
new file mode 100644
index 000000000..6a5c0a313
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/NoOutputOrTarget-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at NoOutputOrTarget.cmake:1 \(add_custom_command\):
+ add_custom_command Wrong syntax. A TARGET or OUTPUT must be specified.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/add_custom_command/NoOutputOrTarget.cmake b/Tests/RunCMake/add_custom_command/NoOutputOrTarget.cmake
new file mode 100644
index 000000000..933ee32b2
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/NoOutputOrTarget.cmake
@@ -0,0 +1 @@
+add_custom_command(COMMAND echo a b c d)
diff --git a/Tests/RunCMake/add_custom_command/OutputAndTarget-result.txt b/Tests/RunCMake/add_custom_command/OutputAndTarget-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/OutputAndTarget-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_custom_command/OutputAndTarget-stderr.txt b/Tests/RunCMake/add_custom_command/OutputAndTarget-stderr.txt
new file mode 100644
index 000000000..632880ec8
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/OutputAndTarget-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at OutputAndTarget.cmake:1 \(add_custom_command\):
+ add_custom_command Wrong syntax. A TARGET and OUTPUT can not both be
+ specified.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/add_custom_command/OutputAndTarget.cmake b/Tests/RunCMake/add_custom_command/OutputAndTarget.cmake
new file mode 100644
index 000000000..55806f3fc
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/OutputAndTarget.cmake
@@ -0,0 +1 @@
+add_custom_command(OUTPUT out TARGET target)
diff --git a/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake b/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake
new file mode 100644
index 000000000..397c63d0a
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake
@@ -0,0 +1,12 @@
+include(RunCMake)
+
+run_cmake(AppendNoOutput)
+run_cmake(AppendNotOutput)
+run_cmake(BadArgument)
+run_cmake(NoArguments)
+run_cmake(NoOutputOrTarget)
+run_cmake(OutputAndTarget)
+run_cmake(SourceByproducts)
+run_cmake(SourceUsesTerminal)
+run_cmake(TargetImported)
+run_cmake(TargetNotInDir)
diff --git a/Tests/RunCMake/add_custom_command/SourceByproducts-result.txt b/Tests/RunCMake/add_custom_command/SourceByproducts-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/SourceByproducts-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_custom_command/SourceByproducts-stderr.txt b/Tests/RunCMake/add_custom_command/SourceByproducts-stderr.txt
new file mode 100644
index 000000000..a9cd64c3f
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/SourceByproducts-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at SourceByproducts.cmake:1 \(add_custom_command\):
+ add_custom_command BYPRODUCTS may not be specified with SOURCE signatures
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/add_custom_command/SourceByproducts.cmake b/Tests/RunCMake/add_custom_command/SourceByproducts.cmake
new file mode 100644
index 000000000..824f41da7
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/SourceByproducts.cmake
@@ -0,0 +1 @@
+add_custom_command(SOURCE t TARGET t BYPRODUCTS b)
diff --git a/Tests/RunCMake/add_custom_command/SourceUsesTerminal-result.txt b/Tests/RunCMake/add_custom_command/SourceUsesTerminal-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/SourceUsesTerminal-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_custom_command/SourceUsesTerminal-stderr.txt b/Tests/RunCMake/add_custom_command/SourceUsesTerminal-stderr.txt
new file mode 100644
index 000000000..1a76c549f
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/SourceUsesTerminal-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at SourceUsesTerminal.cmake:1 \(add_custom_command\):
+ add_custom_command USES_TERMINAL may not be used with SOURCE signatures
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/add_custom_command/SourceUsesTerminal.cmake b/Tests/RunCMake/add_custom_command/SourceUsesTerminal.cmake
new file mode 100644
index 000000000..295fab141
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/SourceUsesTerminal.cmake
@@ -0,0 +1 @@
+add_custom_command(SOURCE t TARGET t USES_TERMINAL)
diff --git a/Tests/RunCMake/add_custom_command/TargetImported-result.txt b/Tests/RunCMake/add_custom_command/TargetImported-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/TargetImported-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_custom_command/TargetImported-stderr.txt b/Tests/RunCMake/add_custom_command/TargetImported-stderr.txt
new file mode 100644
index 000000000..44c4ad886
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/TargetImported-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TargetImported.cmake:2 \(add_custom_command\):
+ TARGET 'TargetImported' is IMPORTED and does not build here.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/add_custom_command/TargetImported.cmake b/Tests/RunCMake/add_custom_command/TargetImported.cmake
new file mode 100644
index 000000000..c0f2d66a0
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/TargetImported.cmake
@@ -0,0 +1,2 @@
+add_library(TargetImported UNKNOWN IMPORTED)
+add_custom_command(TARGET TargetImported COMMAND ${CMAKE_COMMAND} -E echo tada)
diff --git a/Tests/RunCMake/add_custom_command/TargetNotInDir-result.txt b/Tests/RunCMake/add_custom_command/TargetNotInDir-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/TargetNotInDir-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_custom_command/TargetNotInDir-stderr.txt b/Tests/RunCMake/add_custom_command/TargetNotInDir-stderr.txt
new file mode 100644
index 000000000..91876a0a0
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/TargetNotInDir-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TargetNotInDir.cmake:2 \(add_custom_command\):
+ TARGET 'TargetNotInDir' was not created in this directory.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/add_custom_command/TargetNotInDir.cmake b/Tests/RunCMake/add_custom_command/TargetNotInDir.cmake
new file mode 100644
index 000000000..a5510262a
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/TargetNotInDir.cmake
@@ -0,0 +1,2 @@
+add_subdirectory(TargetNotInDir)
+add_custom_command(TARGET TargetNotInDir COMMAND ${CMAKE_COMMAND} -E echo tada)
diff --git a/Tests/RunCMake/add_custom_command/TargetNotInDir/CMakeLists.txt b/Tests/RunCMake/add_custom_command/TargetNotInDir/CMakeLists.txt
new file mode 100644
index 000000000..3d51d27b3
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/TargetNotInDir/CMakeLists.txt
@@ -0,0 +1 @@
+add_custom_target(TargetNotInDir)
diff --git a/Tests/RunCMake/add_custom_target/BadTargetName-result.txt b/Tests/RunCMake/add_custom_target/BadTargetName-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/add_custom_target/BadTargetName-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_custom_target/BadTargetName-stderr.txt b/Tests/RunCMake/add_custom_target/BadTargetName-stderr.txt
new file mode 100644
index 000000000..f352457a8
--- /dev/null
+++ b/Tests/RunCMake/add_custom_target/BadTargetName-stderr.txt
@@ -0,0 +1,17 @@
+CMake Error at BadTargetName.cmake:1 \(add_custom_target\):
+ add_custom_target called with target name containing a "#". This character
+ is not allowed.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at BadTargetName.cmake:2 \(add_custom_target\):
+ add_custom_target called with target name containing a "<". This character
+ is not allowed.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at BadTargetName.cmake:3 \(add_custom_target\):
+ add_custom_target called with target name containing a ">". This character
+ is not allowed.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/add_custom_target/BadTargetName.cmake b/Tests/RunCMake/add_custom_target/BadTargetName.cmake
new file mode 100644
index 000000000..c4381a239
--- /dev/null
+++ b/Tests/RunCMake/add_custom_target/BadTargetName.cmake
@@ -0,0 +1,3 @@
+add_custom_target("#")
+add_custom_target("<")
+add_custom_target(">")
diff --git a/Tests/RunCMake/add_custom_target/ByproductsNoCommand-result.txt b/Tests/RunCMake/add_custom_target/ByproductsNoCommand-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/add_custom_target/ByproductsNoCommand-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_custom_target/ByproductsNoCommand-stderr.txt b/Tests/RunCMake/add_custom_target/ByproductsNoCommand-stderr.txt
new file mode 100644
index 000000000..6c80ca664
--- /dev/null
+++ b/Tests/RunCMake/add_custom_target/ByproductsNoCommand-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at ByproductsNoCommand.cmake:1 \(add_custom_target\):
+ BYPRODUCTS may not be specified without any COMMAND
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/add_custom_target/ByproductsNoCommand.cmake b/Tests/RunCMake/add_custom_target/ByproductsNoCommand.cmake
new file mode 100644
index 000000000..6c142a270
--- /dev/null
+++ b/Tests/RunCMake/add_custom_target/ByproductsNoCommand.cmake
@@ -0,0 +1 @@
+add_custom_target(MyTarget BYPRODUCTS a b c d)
diff --git a/Tests/RunCMake/add_custom_target/CMakeLists.txt b/Tests/RunCMake/add_custom_target/CMakeLists.txt
new file mode 100644
index 000000000..ef2163c29
--- /dev/null
+++ b/Tests/RunCMake/add_custom_target/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.1)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/add_custom_target/NoArguments-result.txt b/Tests/RunCMake/add_custom_target/NoArguments-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/add_custom_target/NoArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_custom_target/NoArguments-stderr.txt b/Tests/RunCMake/add_custom_target/NoArguments-stderr.txt
new file mode 100644
index 000000000..2230093c1
--- /dev/null
+++ b/Tests/RunCMake/add_custom_target/NoArguments-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at NoArguments.cmake:1 \(add_custom_target\):
+ add_custom_target called with incorrect number of arguments
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/add_custom_target/NoArguments.cmake b/Tests/RunCMake/add_custom_target/NoArguments.cmake
new file mode 100644
index 000000000..ec6a21200
--- /dev/null
+++ b/Tests/RunCMake/add_custom_target/NoArguments.cmake
@@ -0,0 +1 @@
+add_custom_target()
diff --git a/Tests/RunCMake/add_custom_target/RunCMakeTest.cmake b/Tests/RunCMake/add_custom_target/RunCMakeTest.cmake
new file mode 100644
index 000000000..92c4a38fe
--- /dev/null
+++ b/Tests/RunCMake/add_custom_target/RunCMakeTest.cmake
@@ -0,0 +1,6 @@
+include(RunCMake)
+
+run_cmake(NoArguments)
+run_cmake(BadTargetName)
+run_cmake(ByproductsNoCommand)
+run_cmake(UsesTerminalNoCommand)
diff --git a/Tests/RunCMake/add_custom_target/UsesTerminalNoCommand-result.txt b/Tests/RunCMake/add_custom_target/UsesTerminalNoCommand-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/add_custom_target/UsesTerminalNoCommand-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_custom_target/UsesTerminalNoCommand-stderr.txt b/Tests/RunCMake/add_custom_target/UsesTerminalNoCommand-stderr.txt
new file mode 100644
index 000000000..beafa7cbf
--- /dev/null
+++ b/Tests/RunCMake/add_custom_target/UsesTerminalNoCommand-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at UsesTerminalNoCommand.cmake:1 \(add_custom_target\):
+ USES_TERMINAL may not be specified without any COMMAND
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/add_custom_target/UsesTerminalNoCommand.cmake b/Tests/RunCMake/add_custom_target/UsesTerminalNoCommand.cmake
new file mode 100644
index 000000000..b0c207b42
--- /dev/null
+++ b/Tests/RunCMake/add_custom_target/UsesTerminalNoCommand.cmake
@@ -0,0 +1 @@
+add_custom_target(MyTarget USES_TERMINAL)
diff --git a/Tests/RunCMake/add_subdirectory/CMakeLists.txt b/Tests/RunCMake/add_subdirectory/CMakeLists.txt
new file mode 100644
index 000000000..18dfd2686
--- /dev/null
+++ b/Tests/RunCMake/add_subdirectory/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.2)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/add_subdirectory/DoesNotExist-result.txt b/Tests/RunCMake/add_subdirectory/DoesNotExist-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/add_subdirectory/DoesNotExist-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_subdirectory/DoesNotExist-stderr.txt b/Tests/RunCMake/add_subdirectory/DoesNotExist-stderr.txt
new file mode 100644
index 000000000..369a956e6
--- /dev/null
+++ b/Tests/RunCMake/add_subdirectory/DoesNotExist-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at DoesNotExist.cmake:1 \(add_subdirectory\):
+ add_subdirectory given source "DoesNotExist" which is not an existing
+ directory.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/add_subdirectory/DoesNotExist.cmake b/Tests/RunCMake/add_subdirectory/DoesNotExist.cmake
new file mode 100644
index 000000000..fe2945ce7
--- /dev/null
+++ b/Tests/RunCMake/add_subdirectory/DoesNotExist.cmake
@@ -0,0 +1 @@
+add_subdirectory(DoesNotExist)
diff --git a/Tests/RunCMake/add_subdirectory/Function-stdout.txt b/Tests/RunCMake/add_subdirectory/Function-stdout.txt
new file mode 100644
index 000000000..16fa857f1
--- /dev/null
+++ b/Tests/RunCMake/add_subdirectory/Function-stdout.txt
@@ -0,0 +1,10 @@
+-- var='1' before my_add_subdirectory
+-- var='2' in my_add_subdirectory before add_subdirectory
+-- var='2' in subdirectory before set
+-- var='3' in subdirectory after set
+-- var_sub='' in subdirectory after set PARENT_SCOPE
+-- var='2' in my_add_subdirectory after add_subdirectory
+-- var_sub='sub' in my_add_subdirectory after add_subdirectory
+-- var='1' after my_add_subdirectory
+-- var_sub='' after my_add_subdirectory
+-- var='3' taken from subdirectory
diff --git a/Tests/RunCMake/add_subdirectory/Function.cmake b/Tests/RunCMake/add_subdirectory/Function.cmake
new file mode 100644
index 000000000..e804da968
--- /dev/null
+++ b/Tests/RunCMake/add_subdirectory/Function.cmake
@@ -0,0 +1,17 @@
+function(my_add_subdirectory dir)
+ set(var 2)
+ message(STATUS "var='${var}' in my_add_subdirectory before add_subdirectory")
+ add_subdirectory(${dir})
+ message(STATUS "var='${var}' in my_add_subdirectory after add_subdirectory")
+ message(STATUS "var_sub='${var_sub}' in my_add_subdirectory after add_subdirectory")
+endfunction()
+
+set(var 1)
+
+message(STATUS "var='${var}' before my_add_subdirectory")
+my_add_subdirectory(Function)
+message(STATUS "var='${var}' after my_add_subdirectory")
+message(STATUS "var_sub='${var_sub}' after my_add_subdirectory")
+
+get_directory_property(sub_var DIRECTORY Function DEFINITION var)
+message(STATUS "var='${sub_var}' taken from subdirectory")
diff --git a/Tests/RunCMake/add_subdirectory/Function/CMakeLists.txt b/Tests/RunCMake/add_subdirectory/Function/CMakeLists.txt
new file mode 100644
index 000000000..7b9e801ce
--- /dev/null
+++ b/Tests/RunCMake/add_subdirectory/Function/CMakeLists.txt
@@ -0,0 +1,5 @@
+message(STATUS "var='${var}' in subdirectory before set")
+set(var 3)
+message(STATUS "var='${var}' in subdirectory after set")
+set(var_sub sub PARENT_SCOPE)
+message(STATUS "var_sub='${var_sub}' in subdirectory after set PARENT_SCOPE")
diff --git a/Tests/RunCMake/add_subdirectory/Missing-result.txt b/Tests/RunCMake/add_subdirectory/Missing-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/add_subdirectory/Missing-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_subdirectory/Missing-stderr.txt b/Tests/RunCMake/add_subdirectory/Missing-stderr.txt
new file mode 100644
index 000000000..aba06755a
--- /dev/null
+++ b/Tests/RunCMake/add_subdirectory/Missing-stderr.txt
@@ -0,0 +1,8 @@
+^CMake Error at Missing.cmake:1 \(add_subdirectory\):
+ The source directory
+
+ .*/Tests/RunCMake/add_subdirectory/Missing
+
+ does not contain a CMakeLists.txt file.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/add_subdirectory/Missing.cmake b/Tests/RunCMake/add_subdirectory/Missing.cmake
new file mode 100644
index 000000000..0e6892763
--- /dev/null
+++ b/Tests/RunCMake/add_subdirectory/Missing.cmake
@@ -0,0 +1 @@
+add_subdirectory(Missing)
diff --git a/Tests/RunCMake/add_subdirectory/Missing/Missing.txt b/Tests/RunCMake/add_subdirectory/Missing/Missing.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/add_subdirectory/Missing/Missing.txt
diff --git a/Tests/RunCMake/add_subdirectory/RunCMakeTest.cmake b/Tests/RunCMake/add_subdirectory/RunCMakeTest.cmake
new file mode 100644
index 000000000..9d514e162
--- /dev/null
+++ b/Tests/RunCMake/add_subdirectory/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(DoesNotExist)
+run_cmake(Missing)
+run_cmake(Function)
diff --git a/Tests/RunCMake/build_command/BeforeProject-stderr.txt b/Tests/RunCMake/build_command/BeforeProject-stderr.txt
index d3d766163..2ae0ed180 100644
--- a/Tests/RunCMake/build_command/BeforeProject-stderr.txt
+++ b/Tests/RunCMake/build_command/BeforeProject-stderr.txt
@@ -1,5 +1,7 @@
-CMake Error at BeforeProject.cmake:[0-9]+ \(build_command\):
- build_command\(\) requires CMAKE_MAKE_PROGRAM to be defined. Call project\(\)
- or enable_language\(\) first.
+CMake Warning \(dev\) at BeforeProject.cmake:2 \(message\):
+ build_command\(\) returned:
+
+ .*cmake.* --build \..*
Call Stack \(most recent call first\):
- CMakeLists.txt:[0-9]+ \(include\)
+ CMakeLists.txt:5 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/build_command/BeforeProject.cmake b/Tests/RunCMake/build_command/BeforeProject.cmake
index 15788d15b..a2175c469 100644
--- a/Tests/RunCMake/build_command/BeforeProject.cmake
+++ b/Tests/RunCMake/build_command/BeforeProject.cmake
@@ -1,2 +1,3 @@
build_command(MAKECOMMAND_DEFAULT_VALUE)
+message(AUTHOR_WARNING "build_command() returned:\n ${MAKECOMMAND_DEFAULT_VALUE}")
project(${RunCMake_TEST} NONE)
diff --git a/Tests/RunCMake/build_command/CMP0061-NEW-stderr.txt b/Tests/RunCMake/build_command/CMP0061-NEW-stderr.txt
new file mode 100644
index 000000000..1dde84379
--- /dev/null
+++ b/Tests/RunCMake/build_command/CMP0061-NEW-stderr.txt
@@ -0,0 +1,10 @@
+^[^
+]+ --build \. --config "Release"
+[^
+]+ --build \. --config "Release" --target "MyTarget"
+[^
+]+ --build \. --config "Debug"
+[^
+]+ --build \. --config "Debug" --target "MyTarget"
+[^
+]+ --build \. --config "Release"$
diff --git a/Tests/RunCMake/build_command/CMP0061-NEW.cmake b/Tests/RunCMake/build_command/CMP0061-NEW.cmake
new file mode 100644
index 000000000..2e439cbbd
--- /dev/null
+++ b/Tests/RunCMake/build_command/CMP0061-NEW.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0061 NEW)
+include(CMP0061Common.cmake)
diff --git a/Tests/RunCMake/build_command/CMP0061-OLD-make-stderr.txt b/Tests/RunCMake/build_command/CMP0061-OLD-make-stderr.txt
new file mode 100644
index 000000000..28e0e7235
--- /dev/null
+++ b/Tests/RunCMake/build_command/CMP0061-OLD-make-stderr.txt
@@ -0,0 +1,10 @@
+^[^
+]+ --build \. --config "Release" -- -i
+[^
+]+ --build \. --config "Release" --target "MyTarget" -- -i
+[^
+]+ --build \. --config "Debug" -- -i
+[^
+]+ --build \. --config "Debug" --target "MyTarget" -- -i
+[^
+]+ --build \. --config "Release" -- -i$
diff --git a/Tests/RunCMake/build_command/CMP0061-OLD-make.cmake b/Tests/RunCMake/build_command/CMP0061-OLD-make.cmake
new file mode 100644
index 000000000..1542d8c16
--- /dev/null
+++ b/Tests/RunCMake/build_command/CMP0061-OLD-make.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0061 OLD)
+include(CMP0061Common.cmake)
diff --git a/Tests/RunCMake/build_command/CMP0061-OLD-other-stderr.txt b/Tests/RunCMake/build_command/CMP0061-OLD-other-stderr.txt
new file mode 100644
index 000000000..1dde84379
--- /dev/null
+++ b/Tests/RunCMake/build_command/CMP0061-OLD-other-stderr.txt
@@ -0,0 +1,10 @@
+^[^
+]+ --build \. --config "Release"
+[^
+]+ --build \. --config "Release" --target "MyTarget"
+[^
+]+ --build \. --config "Debug"
+[^
+]+ --build \. --config "Debug" --target "MyTarget"
+[^
+]+ --build \. --config "Release"$
diff --git a/Tests/RunCMake/build_command/CMP0061-OLD-other.cmake b/Tests/RunCMake/build_command/CMP0061-OLD-other.cmake
new file mode 100644
index 000000000..1542d8c16
--- /dev/null
+++ b/Tests/RunCMake/build_command/CMP0061-OLD-other.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0061 OLD)
+include(CMP0061Common.cmake)
diff --git a/Tests/RunCMake/build_command/CMP0061Common.cmake b/Tests/RunCMake/build_command/CMP0061Common.cmake
new file mode 100644
index 000000000..50cd7d758
--- /dev/null
+++ b/Tests/RunCMake/build_command/CMP0061Common.cmake
@@ -0,0 +1,10 @@
+build_command(command)
+message("${command}")
+build_command(command TARGET MyTarget)
+message("${command}")
+build_command(command CONFIGURATION Debug)
+message("${command}")
+build_command(command CONFIGURATION Debug TARGET MyTarget)
+message("${command}")
+build_command(cache_command "${CMAKE_MAKE_PROGRAM}")
+message("${cache_command}")
diff --git a/Tests/RunCMake/build_command/ErrorsCommon.cmake b/Tests/RunCMake/build_command/ErrorsCommon.cmake
index d22453916..f007b8875 100644
--- a/Tests/RunCMake/build_command/ErrorsCommon.cmake
+++ b/Tests/RunCMake/build_command/ErrorsCommon.cmake
@@ -37,9 +37,9 @@ build_command(cmd)
message("4. cmd='${cmd}'")
# Test the two-arg legacy signature:
-build_command(legacy_cmd ${CMAKE_BUILD_TOOL})
+build_command(legacy_cmd ${CMAKE_MAKE_PROGRAM})
message("5. legacy_cmd='${legacy_cmd}'")
-message(" CMAKE_BUILD_TOOL='${CMAKE_BUILD_TOOL}'")
+message(" CMAKE_MAKE_PROGRAM='${CMAKE_MAKE_PROGRAM}'")
# Test the optional KEYWORDs:
build_command(cmd CONFIGURATION hoohaaConfig)
diff --git a/Tests/RunCMake/build_command/RunCMakeTest.cmake b/Tests/RunCMake/build_command/RunCMakeTest.cmake
index eaa1d77d8..c3bef4c81 100644
--- a/Tests/RunCMake/build_command/RunCMakeTest.cmake
+++ b/Tests/RunCMake/build_command/RunCMakeTest.cmake
@@ -1,4 +1,5 @@
include(RunCMake)
+unset(ENV{CMAKE_CONFIG_TYPE})
run_cmake(ErrorsOFF)
run_cmake(ErrorsON)
@@ -6,3 +7,10 @@ run_cmake(ErrorsON)
set(RunCMake_TEST_OPTIONS -DNoProject=1)
run_cmake(BeforeProject)
unset(RunCMake_TEST_OPTIONS)
+
+run_cmake(CMP0061-NEW)
+if(RunCMake_GENERATOR MATCHES "Make")
+ run_cmake(CMP0061-OLD-make)
+else()
+ run_cmake(CMP0061-OLD-other)
+endif()
diff --git a/Tests/RunCMake/cmake_minimum_required/Before24-stderr.txt b/Tests/RunCMake/cmake_minimum_required/Before24-stderr.txt
new file mode 100644
index 000000000..4a6f16dc3
--- /dev/null
+++ b/Tests/RunCMake/cmake_minimum_required/Before24-stderr.txt
@@ -0,0 +1,5 @@
+CMake Warning \(dev\) at Before24.cmake:1 \(cmake_minimum_required\):
+ Compatibility with CMake < 2.4 is not supported by CMake >= 3.0.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/cmake_minimum_required/Before24.cmake b/Tests/RunCMake/cmake_minimum_required/Before24.cmake
new file mode 100644
index 000000000..c28fc8a9d
--- /dev/null
+++ b/Tests/RunCMake/cmake_minimum_required/Before24.cmake
@@ -0,0 +1 @@
+cmake_minimum_required(VERSION 2.2)
diff --git a/Tests/RunCMake/cmake_minimum_required/CMakeLists.txt b/Tests/RunCMake/cmake_minimum_required/CMakeLists.txt
new file mode 100644
index 000000000..e8db6b05b
--- /dev/null
+++ b/Tests/RunCMake/cmake_minimum_required/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/cmake_minimum_required/CompatBefore24-result.txt b/Tests/RunCMake/cmake_minimum_required/CompatBefore24-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/cmake_minimum_required/CompatBefore24-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/cmake_minimum_required/CompatBefore24-stderr.txt b/Tests/RunCMake/cmake_minimum_required/CompatBefore24-stderr.txt
new file mode 100644
index 000000000..a874466d3
--- /dev/null
+++ b/Tests/RunCMake/cmake_minimum_required/CompatBefore24-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error in CMakeLists.txt:
+ You have set CMAKE_BACKWARDS_COMPATIBILITY to a CMake version less than
+ 2.4. This version of CMake only supports backwards compatibility with
+ CMake 2.4 or later. For compatibility with older versions please use any
+ CMake 2.8.x release or lower.
diff --git a/Tests/RunCMake/cmake_minimum_required/CompatBefore24.cmake b/Tests/RunCMake/cmake_minimum_required/CompatBefore24.cmake
new file mode 100644
index 000000000..ca0cb1ded
--- /dev/null
+++ b/Tests/RunCMake/cmake_minimum_required/CompatBefore24.cmake
@@ -0,0 +1,2 @@
+cmake_minimum_required(VERSION 2.4)
+set(CMAKE_BACKWARDS_COMPATIBILITY 2.2)
diff --git a/Tests/RunCMake/cmake_minimum_required/PolicyBefore24-result.txt b/Tests/RunCMake/cmake_minimum_required/PolicyBefore24-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/cmake_minimum_required/PolicyBefore24-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/cmake_minimum_required/PolicyBefore24-stderr.txt b/Tests/RunCMake/cmake_minimum_required/PolicyBefore24-stderr.txt
new file mode 100644
index 000000000..840211a3b
--- /dev/null
+++ b/Tests/RunCMake/cmake_minimum_required/PolicyBefore24-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at PolicyBefore24.cmake:2 \(cmake_policy\):
+ Compatibility with CMake < 2.4 is not supported by CMake >= 3.0. For
+ compatibility with older versions please use any CMake 2.8.x release or
+ lower.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/cmake_minimum_required/PolicyBefore24.cmake b/Tests/RunCMake/cmake_minimum_required/PolicyBefore24.cmake
new file mode 100644
index 000000000..62d383613
--- /dev/null
+++ b/Tests/RunCMake/cmake_minimum_required/PolicyBefore24.cmake
@@ -0,0 +1,2 @@
+cmake_minimum_required(VERSION 2.4)
+cmake_policy(VERSION 2.2)
diff --git a/Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake b/Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake
new file mode 100644
index 000000000..e4c65e3b6
--- /dev/null
+++ b/Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(Before24)
+run_cmake(CompatBefore24)
+run_cmake(PolicyBefore24)
diff --git a/Tests/RunCMake/cmake_parse_arguments/CMakeLists.txt b/Tests/RunCMake/cmake_parse_arguments/CMakeLists.txt
new file mode 100644
index 000000000..6dd8cdf55
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.4)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/cmake_parse_arguments/CornerCases.cmake b/Tests/RunCMake/cmake_parse_arguments/CornerCases.cmake
new file mode 100644
index 000000000..72c82abce
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/CornerCases.cmake
@@ -0,0 +1,34 @@
+include(${CMAKE_CURRENT_LIST_DIR}/test_utils.cmake)
+
+# example from the documentation
+# OPTIONAL is a keyword and therefore terminates the definition of
+# the multi-value DEFINITION before even a single value has been added
+
+set(options OPTIONAL FAST)
+set(oneValueArgs DESTINATION RENAME)
+set(multiValueArgs TARGETS CONFIGURATIONS)
+cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}"
+ "${multiValueArgs}"
+ TARGETS foo DESTINATION OPTIONAL)
+
+TEST(MY_INSTALL_DESTINATION UNDEFINED)
+TEST(MY_INSTALL_OPTIONAL TRUE)
+
+macro(foo)
+ set(_options )
+ set(_oneValueArgs FOO)
+ set(_multiValueArgs )
+ cmake_parse_arguments(_FOO2 "${_options}"
+ "${_oneValueArgs}"
+ "${_multiValueArgs}"
+ "${ARGN}")
+ cmake_parse_arguments(_FOO1 "${_options}"
+ "${_oneValueArgs}"
+ "${_multiValueArgs}"
+ ${ARGN})
+endmacro()
+
+foo(FOO foo)
+
+TEST(_FOO1_FOO foo)
+TEST(_FOO2_FOO foo)
diff --git a/Tests/RunCMake/cmake_parse_arguments/Errors-result.txt b/Tests/RunCMake/cmake_parse_arguments/Errors-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/Errors-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/cmake_parse_arguments/Errors-stderr.txt b/Tests/RunCMake/cmake_parse_arguments/Errors-stderr.txt
new file mode 100644
index 000000000..f2ba9b84e
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/Errors-stderr.txt
@@ -0,0 +1,44 @@
+CMake Error at Errors\.cmake:2 \(cmake_parse_arguments\):
+ cmake_parse_arguments must be called with at least 4 arguments\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
++
+CMake Error at Errors\.cmake:3 \(cmake_parse_arguments\):
+ cmake_parse_arguments must be called with at least 4 arguments\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
++
+CMake Error at Errors\.cmake:4 \(cmake_parse_arguments\):
+ cmake_parse_arguments must be called with at least 4 arguments\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
++
+CMake Warning at Errors\.cmake:8 \(cmake_parse_arguments\):
+ keyword defined more than once: OPT
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
++
+CMake Warning at Errors\.cmake:9 \(cmake_parse_arguments\):
+ keyword defined more than once: OPT
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
++
+CMake Warning at Errors\.cmake:10 \(cmake_parse_arguments\):
+ keyword defined more than once: OPT
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
++
+CMake Warning at Errors\.cmake:12 \(cmake_parse_arguments\):
+ keyword defined more than once: OPT
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
++
+CMake Warning at Errors\.cmake:13 \(cmake_parse_arguments\):
+ keyword defined more than once: OPT
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
++
+CMake Warning at Errors\.cmake:14 \(cmake_parse_arguments\):
+ keyword defined more than once: OPT
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
diff --git a/Tests/RunCMake/cmake_parse_arguments/Errors.cmake b/Tests/RunCMake/cmake_parse_arguments/Errors.cmake
new file mode 100644
index 000000000..6a380810d
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/Errors.cmake
@@ -0,0 +1,14 @@
+# wrong argument count
+cmake_parse_arguments()
+cmake_parse_arguments(prefix OPT)
+cmake_parse_arguments(prefix OPT SINGLE)
+cmake_parse_arguments(prefix OPT SINGLE MULTI) # not an error
+
+# duplicate keywords
+cmake_parse_arguments(prefix "OPT;OPT" "" "")
+cmake_parse_arguments(prefix "" "OPT;OPT" "")
+cmake_parse_arguments(prefix "" "" "OPT;OPT")
+
+cmake_parse_arguments(prefix "OPT" "OPT" "")
+cmake_parse_arguments(prefix "" "OPT" "OPT")
+cmake_parse_arguments(prefix "OPT" "" "OPT")
diff --git a/Tests/RunCMake/cmake_parse_arguments/Initialization.cmake b/Tests/RunCMake/cmake_parse_arguments/Initialization.cmake
new file mode 100644
index 000000000..462f923db
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/Initialization.cmake
@@ -0,0 +1,68 @@
+include(${CMAKE_CURRENT_LIST_DIR}/test_utils.cmake)
+
+# unparsed arguments
+cmake_parse_arguments(pref "" "" "")
+TEST(pref_UNPARSED_ARGUMENTS UNDEFINED)
+
+cmake_parse_arguments(pref "" "" "" FOO)
+TEST(pref_UNPARSED_ARGUMENTS "FOO")
+cmake_parse_arguments(pref "" "" "" FOO BAR)
+TEST(pref_UNPARSED_ARGUMENTS "FOO;BAR")
+cmake_parse_arguments(pref "" "" "")
+TEST(pref_UNPARSED_ARGUMENTS UNDEFINED)
+
+
+# options
+cmake_parse_arguments(pref "OPT1" "" "")
+TEST(pref_OPT1 FALSE)
+
+cmake_parse_arguments(pref "OPT1;OPT2" "" "")
+TEST(pref_OPT1 FALSE)
+TEST(pref_OPT2 FALSE)
+
+cmake_parse_arguments(pref "OPT1" "" "" OPT1)
+TEST(pref_OPT1 TRUE)
+cmake_parse_arguments(pref "OPT1;OPT2" "" "" OPT1 OPT2)
+TEST(pref_OPT1 TRUE)
+TEST(pref_OPT2 TRUE)
+cmake_parse_arguments(pref "OPT1;OPT2" "" "")
+TEST(pref_OPT1 FALSE)
+TEST(pref_OPT2 FALSE)
+
+
+# single arguments
+cmake_parse_arguments(pref "" "SINGLE1" "")
+TEST(pref_SINGLE1 UNDEFINED)
+
+cmake_parse_arguments(pref "" "SINGLE1;SINGLE2" "")
+TEST(pref_SINGLE1 UNDEFINED)
+TEST(pref_SINGLE2 UNDEFINED)
+
+
+cmake_parse_arguments(pref "" "SINGLE1" "" SINGLE1 foo)
+TEST(pref_SINGLE1 foo)
+cmake_parse_arguments(pref "" "SINGLE1;SINGLE2" "" SINGLE1 foo SINGLE2 bar)
+TEST(pref_SINGLE1 foo)
+TEST(pref_SINGLE2 bar)
+cmake_parse_arguments(pref "" "SINGLE1;SINGLE2" "")
+TEST(pref_SINGLE1 UNDEFINED)
+TEST(pref_SINGLE2 UNDEFINED)
+
+
+# multi arguments
+
+cmake_parse_arguments(pref "" "" "MULTI1")
+TEST(pref_MULTI1 UNDEFINED)
+
+cmake_parse_arguments(pref "" "" "MULTI1;MULTI2")
+TEST(pref_MULTI1 UNDEFINED)
+TEST(pref_MULTI2 UNDEFINED)
+
+cmake_parse_arguments(pref "" "" "MULTI1" MULTI1 foo)
+TEST(pref_MULTI1 foo)
+cmake_parse_arguments(pref "" "" "MULTI1;MULTI2" MULTI1 foo bar MULTI2 bar foo)
+TEST(pref_MULTI1 foo bar)
+TEST(pref_MULTI2 bar foo)
+cmake_parse_arguments(pref "" "" "MULTI1;MULTI2")
+TEST(pref_MULTI1 UNDEFINED)
+TEST(pref_MULTI2 UNDEFINED)
diff --git a/Tests/RunCMake/cmake_parse_arguments/Mix.cmake b/Tests/RunCMake/cmake_parse_arguments/Mix.cmake
new file mode 100644
index 000000000..b3eff3947
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/Mix.cmake
@@ -0,0 +1,24 @@
+include(${CMAKE_CURRENT_LIST_DIR}/test_utils.cmake)
+
+# specify two keywords for each category and set the first keyword of each
+# within ARGN
+cmake_parse_arguments(pref "OPT1;OPT2" "SINGLE1;SINGLE2" "MULTI1;MULTI2"
+ OPT1 SINGLE1 foo MULTI1 bar foo bar)
+TEST(pref_OPT1 TRUE)
+TEST(pref_OPT2 FALSE)
+TEST(pref_SINGLE1 foo)
+TEST(pref_SINGLE2 UNDEFINED)
+TEST(pref_MULTI1 bar foo bar)
+TEST(pref_MULTI2 UNDEFINED)
+TEST(pref_UNPARSED_ARGUMENTS UNDEFINED)
+
+# same as above but reversed ARGN
+cmake_parse_arguments(pref "OPT1;OPT2" "SINGLE1;SINGLE2" "MULTI1;MULTI2"
+ MULTI1 bar foo bar SINGLE1 foo OPT1)
+TEST(pref_OPT1 TRUE)
+TEST(pref_OPT2 FALSE)
+TEST(pref_SINGLE1 foo)
+TEST(pref_SINGLE2 UNDEFINED)
+TEST(pref_MULTI1 bar foo bar)
+TEST(pref_MULTI2 UNDEFINED)
+TEST(pref_UNPARSED_ARGUMENTS UNDEFINED)
diff --git a/Tests/RunCMake/cmake_parse_arguments/RunCMakeTest.cmake b/Tests/RunCMake/cmake_parse_arguments/RunCMakeTest.cmake
new file mode 100644
index 000000000..b89f1a55e
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/RunCMakeTest.cmake
@@ -0,0 +1,7 @@
+include(RunCMake)
+
+run_cmake(Utils)
+run_cmake(Initialization)
+run_cmake(Mix)
+run_cmake(CornerCases)
+run_cmake(Errors)
diff --git a/Tests/RunCMake/cmake_parse_arguments/Utils.cmake b/Tests/RunCMake/cmake_parse_arguments/Utils.cmake
new file mode 100644
index 000000000..3bbf115e8
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/Utils.cmake
@@ -0,0 +1,20 @@
+include(${CMAKE_CURRENT_LIST_DIR}/test_utils.cmake)
+
+# test the TEST macro itself
+
+TEST(asdf UNDEFINED)
+
+SET (asdf FALSE)
+TEST(asdf FALSE)
+
+SET (asdf TRUE)
+TEST(asdf TRUE)
+
+SET (asdf TRUE)
+TEST(asdf TRUE)
+
+SET (asdf "some value")
+TEST(asdf "some value")
+
+SET (asdf some list)
+TEST(asdf "some;list")
diff --git a/Tests/RunCMake/cmake_parse_arguments/test_utils.cmake b/Tests/RunCMake/cmake_parse_arguments/test_utils.cmake
new file mode 100644
index 000000000..f5425c2bc
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/test_utils.cmake
@@ -0,0 +1,20 @@
+macro(TEST variable)
+ SET(expected "${ARGN}")
+ if ( "${expected}" STREQUAL "UNDEFINED" )
+ if (DEFINED ${variable})
+ message(FATAL_ERROR "'${variable}' shall be undefined but has value '${${variable}}'")
+ endif()
+ elseif( "${expected}" STREQUAL "FALSE" )
+ if (NOT ${variable} STREQUAL "FALSE")
+ message(FATAL_ERROR "'${variable}' shall be FALSE")
+ endif()
+ elseif( "${expected}" STREQUAL "TRUE" )
+ if (NOT ${variable} STREQUAL "TRUE")
+ message(FATAL_ERROR "'${variable}' shall be TRUE")
+ endif()
+ else()
+ if (NOT ${variable} STREQUAL "${expected}")
+ message(FATAL_ERROR "'${variable}' shall be '${expected}'")
+ endif()
+ endif()
+endmacro()
diff --git a/Tests/RunCMake/configure_file/BadArg-result.txt b/Tests/RunCMake/configure_file/BadArg-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/configure_file/BadArg-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/configure_file/BadArg-stderr.txt b/Tests/RunCMake/configure_file/BadArg-stderr.txt
new file mode 100644
index 000000000..4567d3f9f
--- /dev/null
+++ b/Tests/RunCMake/configure_file/BadArg-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at BadArg.cmake:[0-9]+ \(configure_file\):
+ configure_file called with incorrect number of arguments, expected 2
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/CMakeTests/ConfigureFile-BadArg.cmake b/Tests/RunCMake/configure_file/BadArg.cmake
index 769fae1ab..769fae1ab 100644
--- a/Tests/CMakeTests/ConfigureFile-BadArg.cmake
+++ b/Tests/RunCMake/configure_file/BadArg.cmake
diff --git a/Tests/RunCMake/configure_file/CMakeLists.txt b/Tests/RunCMake/configure_file/CMakeLists.txt
new file mode 100644
index 000000000..289710955
--- /dev/null
+++ b/Tests/RunCMake/configure_file/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.0)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/configure_file/DirInput-result.txt b/Tests/RunCMake/configure_file/DirInput-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/configure_file/DirInput-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/configure_file/DirInput-stderr.txt b/Tests/RunCMake/configure_file/DirInput-stderr.txt
new file mode 100644
index 000000000..2e0cd144c
--- /dev/null
+++ b/Tests/RunCMake/configure_file/DirInput-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at DirInput.cmake:[0-9]+ \(configure_file\):
+ configure_file input location
+
+ .*/Tests/RunCMake/configure_file/.
+
+ is a directory but a file was expected.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/CMakeTests/ConfigureFile-DirInput.cmake b/Tests/RunCMake/configure_file/DirInput.cmake
index 920ea280c..920ea280c 100644
--- a/Tests/CMakeTests/ConfigureFile-DirInput.cmake
+++ b/Tests/RunCMake/configure_file/DirInput.cmake
diff --git a/Tests/RunCMake/configure_file/DirOutput-stderr.txt b/Tests/RunCMake/configure_file/DirOutput-stderr.txt
new file mode 100644
index 000000000..d051f7c20
--- /dev/null
+++ b/Tests/RunCMake/configure_file/DirOutput-stderr.txt
@@ -0,0 +1 @@
+^DirOutput test file$
diff --git a/Tests/RunCMake/configure_file/DirOutput.cmake b/Tests/RunCMake/configure_file/DirOutput.cmake
new file mode 100644
index 000000000..aa0fadfe6
--- /dev/null
+++ b/Tests/RunCMake/configure_file/DirOutput.cmake
@@ -0,0 +1,4 @@
+file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/DirOutput)
+configure_file(DirOutput.txt DirOutput)
+file(READ ${CMAKE_CURRENT_BINARY_DIR}/DirOutput/DirOutput.txt out)
+message("${out}")
diff --git a/Tests/RunCMake/configure_file/DirOutput.txt b/Tests/RunCMake/configure_file/DirOutput.txt
new file mode 100644
index 000000000..16388a6b5
--- /dev/null
+++ b/Tests/RunCMake/configure_file/DirOutput.txt
@@ -0,0 +1 @@
+DirOutput test file
diff --git a/Tests/RunCMake/configure_file/NO-BOM.cmake b/Tests/RunCMake/configure_file/NO-BOM.cmake
new file mode 100644
index 000000000..003d52663
--- /dev/null
+++ b/Tests/RunCMake/configure_file/NO-BOM.cmake
@@ -0,0 +1,2 @@
+
+configure_file(NO-BOM.txt.in ${CMAKE_CURRENT_BINARY_DIR}/NO-BOM.txt)
diff --git a/Tests/RunCMake/configure_file/NO-BOM.txt.in b/Tests/RunCMake/configure_file/NO-BOM.txt.in
new file mode 100644
index 000000000..557db03de
--- /dev/null
+++ b/Tests/RunCMake/configure_file/NO-BOM.txt.in
@@ -0,0 +1 @@
+Hello World
diff --git a/Tests/RunCMake/configure_file/NewLineStyle-COPYONLY-result.txt b/Tests/RunCMake/configure_file/NewLineStyle-COPYONLY-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/configure_file/NewLineStyle-COPYONLY-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/configure_file/NewLineStyle-COPYONLY-stderr.txt b/Tests/RunCMake/configure_file/NewLineStyle-COPYONLY-stderr.txt
new file mode 100644
index 000000000..3f66909d1
--- /dev/null
+++ b/Tests/RunCMake/configure_file/NewLineStyle-COPYONLY-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at NewLineStyle-COPYONLY.cmake:[0-9]+ \(configure_file\):
+ configure_file COPYONLY could not be used in combination with NEWLINE_STYLE
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/configure_file/NewLineStyle-COPYONLY.cmake b/Tests/RunCMake/configure_file/NewLineStyle-COPYONLY.cmake
new file mode 100644
index 000000000..c07b8f582
--- /dev/null
+++ b/Tests/RunCMake/configure_file/NewLineStyle-COPYONLY.cmake
@@ -0,0 +1,3 @@
+set(file_name ${CMAKE_CURRENT_BINARY_DIR}/NewLineStyle.txt)
+file(WRITE ${file_name} "Data\n")
+configure_file(${file_name} ${file_name}.out COPYONLY NEWLINE_STYLE DOS)
diff --git a/Tests/RunCMake/configure_file/NewLineStyle-NoArg-result.txt b/Tests/RunCMake/configure_file/NewLineStyle-NoArg-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/configure_file/NewLineStyle-NoArg-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/configure_file/NewLineStyle-NoArg-stderr.txt b/Tests/RunCMake/configure_file/NewLineStyle-NoArg-stderr.txt
new file mode 100644
index 000000000..365265715
--- /dev/null
+++ b/Tests/RunCMake/configure_file/NewLineStyle-NoArg-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at NewLineStyle-NoArg.cmake:[0-9]+ \(configure_file\):
+ configure_file NEWLINE_STYLE must set a style: LF, CRLF, UNIX, DOS, or
+ WIN32
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/configure_file/NewLineStyle-NoArg.cmake b/Tests/RunCMake/configure_file/NewLineStyle-NoArg.cmake
new file mode 100644
index 000000000..b35bde11b
--- /dev/null
+++ b/Tests/RunCMake/configure_file/NewLineStyle-NoArg.cmake
@@ -0,0 +1,3 @@
+set(file_name ${CMAKE_CURRENT_BINARY_DIR}/NewLineStyle.txt)
+file(WRITE ${file_name} "Data\n")
+configure_file(${file_name} ${file_name}.out NEWLINE_STYLE)
diff --git a/Tests/RunCMake/configure_file/NewLineStyle-ValidArg.cmake b/Tests/RunCMake/configure_file/NewLineStyle-ValidArg.cmake
new file mode 100644
index 000000000..8d9f47448
--- /dev/null
+++ b/Tests/RunCMake/configure_file/NewLineStyle-ValidArg.cmake
@@ -0,0 +1,17 @@
+set(file_name ${CMAKE_CURRENT_BINARY_DIR}/NewLineStyle.txt)
+
+function(test_eol style in out)
+ file(WRITE ${file_name} "${in}")
+ configure_file(${file_name} ${file_name}.out NEWLINE_STYLE ${style})
+ file(READ ${file_name}.out new HEX)
+ if(NOT "${new}" STREQUAL "${out}")
+ message(FATAL_ERROR "No ${style} line endings")
+ endif()
+endfunction()
+
+test_eol(DOS "a\n" "610d0a")
+test_eol(WIN32 "b\n" "620d0a")
+test_eol(CRLF "c\n" "630d0a")
+
+test_eol(UNIX "d\n" "640a")
+test_eol(LF "e\n" "650a")
diff --git a/Tests/RunCMake/configure_file/NewLineStyle-WrongArg-result.txt b/Tests/RunCMake/configure_file/NewLineStyle-WrongArg-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/configure_file/NewLineStyle-WrongArg-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/configure_file/NewLineStyle-WrongArg-stderr.txt b/Tests/RunCMake/configure_file/NewLineStyle-WrongArg-stderr.txt
new file mode 100644
index 000000000..0d6855f82
--- /dev/null
+++ b/Tests/RunCMake/configure_file/NewLineStyle-WrongArg-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at NewLineStyle-WrongArg.cmake:[0-9]+ \(configure_file\):
+ configure_file NEWLINE_STYLE sets an unknown style, only LF, CRLF, UNIX,
+ DOS, and WIN32 are supported
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/configure_file/NewLineStyle-WrongArg.cmake b/Tests/RunCMake/configure_file/NewLineStyle-WrongArg.cmake
new file mode 100644
index 000000000..3ae906dba
--- /dev/null
+++ b/Tests/RunCMake/configure_file/NewLineStyle-WrongArg.cmake
@@ -0,0 +1,3 @@
+set(file_name ${CMAKE_CURRENT_BINARY_DIR}/NewLineStyle.txt)
+file(WRITE ${file_name} "Data\n")
+configure_file(${file_name} ${file_name}.out NEWLINE_STYLE FOO)
diff --git a/Tests/RunCMake/configure_file/Relative-In.txt b/Tests/RunCMake/configure_file/Relative-In.txt
new file mode 100644
index 000000000..572fe532d
--- /dev/null
+++ b/Tests/RunCMake/configure_file/Relative-In.txt
@@ -0,0 +1 @@
+Relative test file
diff --git a/Tests/RunCMake/configure_file/Relative-stderr.txt b/Tests/RunCMake/configure_file/Relative-stderr.txt
new file mode 100644
index 000000000..b94de0dce
--- /dev/null
+++ b/Tests/RunCMake/configure_file/Relative-stderr.txt
@@ -0,0 +1 @@
+^Relative test file$
diff --git a/Tests/RunCMake/configure_file/Relative.cmake b/Tests/RunCMake/configure_file/Relative.cmake
new file mode 100644
index 000000000..085991c72
--- /dev/null
+++ b/Tests/RunCMake/configure_file/Relative.cmake
@@ -0,0 +1,3 @@
+configure_file(Relative-In.txt Relative-Out.txt)
+file(READ ${CMAKE_CURRENT_BINARY_DIR}/Relative-Out.txt out)
+message("${out}")
diff --git a/Tests/RunCMake/configure_file/RerunCMake-rerun-stderr.txt b/Tests/RunCMake/configure_file/RerunCMake-rerun-stderr.txt
new file mode 100644
index 000000000..26e07b683
--- /dev/null
+++ b/Tests/RunCMake/configure_file/RerunCMake-rerun-stderr.txt
@@ -0,0 +1 @@
+^Running CMake on RerunCMake$
diff --git a/Tests/RunCMake/configure_file/RerunCMake-rerun-stdout.txt b/Tests/RunCMake/configure_file/RerunCMake-rerun-stdout.txt
new file mode 100644
index 000000000..34c873ced
--- /dev/null
+++ b/Tests/RunCMake/configure_file/RerunCMake-rerun-stdout.txt
@@ -0,0 +1,3 @@
+-- Configuring done
+-- Generating done
+-- Build files have been written to: .*/Tests/RunCMake/configure_file/RerunCMake-build
diff --git a/Tests/RunCMake/configure_file/RerunCMake-stderr.txt b/Tests/RunCMake/configure_file/RerunCMake-stderr.txt
new file mode 100644
index 000000000..26e07b683
--- /dev/null
+++ b/Tests/RunCMake/configure_file/RerunCMake-stderr.txt
@@ -0,0 +1 @@
+^Running CMake on RerunCMake$
diff --git a/Tests/RunCMake/configure_file/RerunCMake-stdout.txt b/Tests/RunCMake/configure_file/RerunCMake-stdout.txt
new file mode 100644
index 000000000..34c873ced
--- /dev/null
+++ b/Tests/RunCMake/configure_file/RerunCMake-stdout.txt
@@ -0,0 +1,3 @@
+-- Configuring done
+-- Generating done
+-- Build files have been written to: .*/Tests/RunCMake/configure_file/RerunCMake-build
diff --git a/Tests/RunCMake/configure_file/RerunCMake.cmake b/Tests/RunCMake/configure_file/RerunCMake.cmake
new file mode 100644
index 000000000..890cc1fa8
--- /dev/null
+++ b/Tests/RunCMake/configure_file/RerunCMake.cmake
@@ -0,0 +1,8 @@
+message("Running CMake on RerunCMake") # write to stderr if cmake reruns
+configure_file(
+ "${CMAKE_CURRENT_BINARY_DIR}/ConfigureFileInput.txt.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/ConfigureFileOutput.txt"
+ @ONLY
+ )
+# make sure CMakeCache.txt is newer than ConfigureFileOutput.txt
+execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1)
diff --git a/Tests/RunCMake/configure_file/RunCMakeTest.cmake b/Tests/RunCMake/configure_file/RunCMakeTest.cmake
new file mode 100644
index 000000000..de144682c
--- /dev/null
+++ b/Tests/RunCMake/configure_file/RunCMakeTest.cmake
@@ -0,0 +1,51 @@
+include(RunCMake)
+
+run_cmake(NO-BOM)
+run_cmake(UTF8-BOM)
+run_cmake(UTF16LE-BOM)
+run_cmake(UTF16BE-BOM)
+run_cmake(UTF32LE-BOM)
+run_cmake(UTF32BE-BOM)
+run_cmake(UnknownArg)
+run_cmake(DirInput)
+run_cmake(DirOutput)
+run_cmake(Relative)
+run_cmake(BadArg)
+run_cmake(NewLineStyle-NoArg)
+run_cmake(NewLineStyle-WrongArg)
+run_cmake(NewLineStyle-ValidArg)
+run_cmake(NewLineStyle-COPYONLY)
+
+if(RunCMake_GENERATOR MATCHES "Make")
+ # Use a single build tree for a few tests without cleaning.
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/RerunCMake-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ set(in_conf "${RunCMake_TEST_BINARY_DIR}/ConfigureFileInput.txt.in")
+ file(WRITE "${in_conf}" "1")
+
+ message(STATUS "RerunCMake: first configuration...")
+ run_cmake(RerunCMake)
+ run_cmake_command(RerunCMake-nowork ${CMAKE_COMMAND} --build .)
+
+ execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1) # handle 1s resolution
+ message(STATUS "RerunCMake: touch configure_file input...")
+ file(WRITE "${in_conf}" "1")
+ run_cmake_command(RerunCMake-rerun ${CMAKE_COMMAND} --build .)
+ run_cmake_command(RerunCMake-nowork ${CMAKE_COMMAND} --build .)
+
+ execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1) # handle 1s resolution
+ message(STATUS "RerunCMake: modify configure_file input...")
+ file(WRITE "${in_conf}" "2")
+ run_cmake_command(RerunCMake-rerun ${CMAKE_COMMAND} --build .)
+ run_cmake_command(RerunCMake-nowork ${CMAKE_COMMAND} --build .)
+
+ message(STATUS "RerunCMake: remove configure_file output...")
+ file(REMOVE "${RunCMake_TEST_BINARY_DIR}/ConfigureFileOutput.txt")
+ run_cmake_command(RerunCMake-rerun ${CMAKE_COMMAND} --build .)
+ run_cmake_command(RerunCMake-nowork ${CMAKE_COMMAND} --build .)
+
+ unset(RunCMake_TEST_BINARY_DIR)
+ unset(RunCMake_TEST_NO_CLEAN)
+endif()
diff --git a/Tests/RunCMake/configure_file/UTF16BE-BOM-result.txt b/Tests/RunCMake/configure_file/UTF16BE-BOM-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/configure_file/UTF16BE-BOM-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/configure_file/UTF16BE-BOM-stderr.txt b/Tests/RunCMake/configure_file/UTF16BE-BOM-stderr.txt
new file mode 100644
index 000000000..5132c4ddb
--- /dev/null
+++ b/Tests/RunCMake/configure_file/UTF16BE-BOM-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at UTF16BE-BOM.cmake:2 \(configure_file\):
+ File starts with a Byte-Order-Mark that is not UTF-8:
+
+ .*/Tests/RunCMake/configure_file/UTF16BE-BOM.txt.in
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/configure_file/UTF16BE-BOM.cmake b/Tests/RunCMake/configure_file/UTF16BE-BOM.cmake
new file mode 100644
index 000000000..c5707425a
--- /dev/null
+++ b/Tests/RunCMake/configure_file/UTF16BE-BOM.cmake
@@ -0,0 +1,2 @@
+
+configure_file(UTF16BE-BOM.txt.in ${CMAKE_CURRENT_BINARY_DIR}/UTF16BE-BOM.txt)
diff --git a/Tests/RunCMake/configure_file/UTF16BE-BOM.txt.in b/Tests/RunCMake/configure_file/UTF16BE-BOM.txt.in
new file mode 100644
index 000000000..70fd9cbf7
--- /dev/null
+++ b/Tests/RunCMake/configure_file/UTF16BE-BOM.txt.in
Binary files differ
diff --git a/Tests/RunCMake/configure_file/UTF16LE-BOM-result.txt b/Tests/RunCMake/configure_file/UTF16LE-BOM-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/configure_file/UTF16LE-BOM-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/configure_file/UTF16LE-BOM-stderr.txt b/Tests/RunCMake/configure_file/UTF16LE-BOM-stderr.txt
new file mode 100644
index 000000000..8f997bc71
--- /dev/null
+++ b/Tests/RunCMake/configure_file/UTF16LE-BOM-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at UTF16LE-BOM.cmake:2 \(configure_file\):
+ File starts with a Byte-Order-Mark that is not UTF-8:
+
+ .*/Tests/RunCMake/configure_file/UTF16LE-BOM.txt.in
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/configure_file/UTF16LE-BOM.cmake b/Tests/RunCMake/configure_file/UTF16LE-BOM.cmake
new file mode 100644
index 000000000..05c9cd757
--- /dev/null
+++ b/Tests/RunCMake/configure_file/UTF16LE-BOM.cmake
@@ -0,0 +1,2 @@
+
+configure_file(UTF16LE-BOM.txt.in ${CMAKE_CURRENT_BINARY_DIR}/UTF16LE-BOM.txt)
diff --git a/Tests/RunCMake/configure_file/UTF16LE-BOM.txt.in b/Tests/RunCMake/configure_file/UTF16LE-BOM.txt.in
new file mode 100644
index 000000000..036f8c536
--- /dev/null
+++ b/Tests/RunCMake/configure_file/UTF16LE-BOM.txt.in
Binary files differ
diff --git a/Tests/RunCMake/configure_file/UTF32BE-BOM-result.txt b/Tests/RunCMake/configure_file/UTF32BE-BOM-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/configure_file/UTF32BE-BOM-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/configure_file/UTF32BE-BOM-stderr.txt b/Tests/RunCMake/configure_file/UTF32BE-BOM-stderr.txt
new file mode 100644
index 000000000..12811aaa2
--- /dev/null
+++ b/Tests/RunCMake/configure_file/UTF32BE-BOM-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at UTF32BE-BOM.cmake:2 \(configure_file\):
+ File starts with a Byte-Order-Mark that is not UTF-8:
+
+ .*/Tests/RunCMake/configure_file/UTF32BE-BOM.txt.in
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/configure_file/UTF32BE-BOM.cmake b/Tests/RunCMake/configure_file/UTF32BE-BOM.cmake
new file mode 100644
index 000000000..0c6ea8753
--- /dev/null
+++ b/Tests/RunCMake/configure_file/UTF32BE-BOM.cmake
@@ -0,0 +1,2 @@
+
+configure_file(UTF32BE-BOM.txt.in ${CMAKE_CURRENT_BINARY_DIR}/UTF32BE-BOM.txt)
diff --git a/Tests/RunCMake/configure_file/UTF32BE-BOM.txt.in b/Tests/RunCMake/configure_file/UTF32BE-BOM.txt.in
new file mode 100644
index 000000000..c87cfd5ca
--- /dev/null
+++ b/Tests/RunCMake/configure_file/UTF32BE-BOM.txt.in
Binary files differ
diff --git a/Tests/RunCMake/configure_file/UTF32LE-BOM-result.txt b/Tests/RunCMake/configure_file/UTF32LE-BOM-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/configure_file/UTF32LE-BOM-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/configure_file/UTF32LE-BOM-stderr.txt b/Tests/RunCMake/configure_file/UTF32LE-BOM-stderr.txt
new file mode 100644
index 000000000..fa9e01a2b
--- /dev/null
+++ b/Tests/RunCMake/configure_file/UTF32LE-BOM-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at UTF32LE-BOM.cmake:2 \(configure_file\):
+ File starts with a Byte-Order-Mark that is not UTF-8:
+
+ .*/Tests/RunCMake/configure_file/UTF32LE-BOM.txt.in
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/configure_file/UTF32LE-BOM.cmake b/Tests/RunCMake/configure_file/UTF32LE-BOM.cmake
new file mode 100644
index 000000000..b6351b007
--- /dev/null
+++ b/Tests/RunCMake/configure_file/UTF32LE-BOM.cmake
@@ -0,0 +1,2 @@
+
+configure_file(UTF32LE-BOM.txt.in ${CMAKE_CURRENT_BINARY_DIR}/UTF32LE-BOM.txt)
diff --git a/Tests/RunCMake/configure_file/UTF32LE-BOM.txt.in b/Tests/RunCMake/configure_file/UTF32LE-BOM.txt.in
new file mode 100644
index 000000000..27c8183bd
--- /dev/null
+++ b/Tests/RunCMake/configure_file/UTF32LE-BOM.txt.in
Binary files differ
diff --git a/Tests/RunCMake/configure_file/UTF8-BOM.cmake b/Tests/RunCMake/configure_file/UTF8-BOM.cmake
new file mode 100644
index 000000000..af2adae4a
--- /dev/null
+++ b/Tests/RunCMake/configure_file/UTF8-BOM.cmake
@@ -0,0 +1,2 @@
+
+configure_file(UTF8-BOM.txt.in ${CMAKE_CURRENT_BINARY_DIR}/UTF8-BOM.txt)
diff --git a/Tests/RunCMake/configure_file/UTF8-BOM.txt.in b/Tests/RunCMake/configure_file/UTF8-BOM.txt.in
new file mode 100644
index 000000000..abc0acab2
--- /dev/null
+++ b/Tests/RunCMake/configure_file/UTF8-BOM.txt.in
@@ -0,0 +1 @@
+Hello World
diff --git a/Tests/RunCMake/configure_file/UnknownArg-stderr.txt b/Tests/RunCMake/configure_file/UnknownArg-stderr.txt
new file mode 100644
index 000000000..46930c003
--- /dev/null
+++ b/Tests/RunCMake/configure_file/UnknownArg-stderr.txt
@@ -0,0 +1,10 @@
+CMake Warning \(dev\) at UnknownArg.cmake:1 \(configure_file\):
+ configure_file called with unknown argument\(s\):
+
+ COPY_ONLY
+ COPYFILE
+ COPY_FILE
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/configure_file/UnknownArg.cmake b/Tests/RunCMake/configure_file/UnknownArg.cmake
new file mode 100644
index 000000000..5125c83b2
--- /dev/null
+++ b/Tests/RunCMake/configure_file/UnknownArg.cmake
@@ -0,0 +1,2 @@
+configure_file(${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in UnknownArg.txt
+ @ONLY COPYONLY COPY_ONLY COPYFILE COPY_FILE)
diff --git a/Tests/RunCMake/continue/CMakeLists.txt b/Tests/RunCMake/continue/CMakeLists.txt
new file mode 100644
index 000000000..ef2163c29
--- /dev/null
+++ b/Tests/RunCMake/continue/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.1)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/continue/ContinueForEachInLists.cmake b/Tests/RunCMake/continue/ContinueForEachInLists.cmake
new file mode 100644
index 000000000..fbd7359fe
--- /dev/null
+++ b/Tests/RunCMake/continue/ContinueForEachInLists.cmake
@@ -0,0 +1,10 @@
+list(APPEND foo 1 2 3 4 5)
+
+message(STATUS "start")
+foreach(iter IN LISTS foo)
+ if("${iter}" EQUAL 1 OR "${iter}" EQUAL 3 OR "${iter}" EQUAL 5)
+ continue()
+ endif()
+ message(STATUS "${iter}")
+endforeach()
+message(STATUS "end")
diff --git a/Tests/RunCMake/continue/ContinueForeach-stdout.txt b/Tests/RunCMake/continue/ContinueForeach-stdout.txt
new file mode 100644
index 000000000..955b8595d
--- /dev/null
+++ b/Tests/RunCMake/continue/ContinueForeach-stdout.txt
@@ -0,0 +1,4 @@
+-- start
+-- 2
+-- 4
+-- end
diff --git a/Tests/RunCMake/continue/ContinueForeach.cmake b/Tests/RunCMake/continue/ContinueForeach.cmake
new file mode 100644
index 000000000..9b3e17f3e
--- /dev/null
+++ b/Tests/RunCMake/continue/ContinueForeach.cmake
@@ -0,0 +1,8 @@
+message(STATUS "start")
+foreach(iter RANGE 1 5)
+ if("${iter}" EQUAL 1 OR "${iter}" EQUAL 3 OR "${iter}" EQUAL 5)
+ continue()
+ endif()
+ message(STATUS "${iter}")
+endforeach()
+message(STATUS "end")
diff --git a/Tests/RunCMake/continue/ContinueNestedForeach-stdout.txt b/Tests/RunCMake/continue/ContinueNestedForeach-stdout.txt
new file mode 100644
index 000000000..adb02bccc
--- /dev/null
+++ b/Tests/RunCMake/continue/ContinueNestedForeach-stdout.txt
@@ -0,0 +1,6 @@
+-- start
+-- 7 2
+-- 7 4
+-- 9 2
+-- 9 4
+-- end
diff --git a/Tests/RunCMake/continue/ContinueNestedForeach.cmake b/Tests/RunCMake/continue/ContinueNestedForeach.cmake
new file mode 100644
index 000000000..de7c51b20
--- /dev/null
+++ b/Tests/RunCMake/continue/ContinueNestedForeach.cmake
@@ -0,0 +1,13 @@
+message(STATUS "start")
+foreach(outer RANGE 7 9)
+ if("${outer}" EQUAL 8)
+ continue()
+ endif()
+ foreach(inner RANGE 1 5)
+ if("${inner}" EQUAL 1 OR "${inner}" EQUAL 3 OR "${inner}" EQUAL 5)
+ continue()
+ endif()
+ message(STATUS "${outer} ${inner}")
+ endforeach()
+endforeach()
+message(STATUS "end")
diff --git a/Tests/RunCMake/continue/ContinueWhile-stdout.txt b/Tests/RunCMake/continue/ContinueWhile-stdout.txt
new file mode 100644
index 000000000..f99b2a1ac
--- /dev/null
+++ b/Tests/RunCMake/continue/ContinueWhile-stdout.txt
@@ -0,0 +1,6 @@
+-- start
+-- a
+-- aa
+-- aaaa
+-- aaaaa
+-- end
diff --git a/Tests/RunCMake/continue/ContinueWhile.cmake b/Tests/RunCMake/continue/ContinueWhile.cmake
new file mode 100644
index 000000000..c1fa87ac2
--- /dev/null
+++ b/Tests/RunCMake/continue/ContinueWhile.cmake
@@ -0,0 +1,10 @@
+message(STATUS "start")
+unset(iter)
+while(NOT "${iter}" STREQUAL "aaaaa")
+ set(iter "${iter}a")
+ if("${iter}" STREQUAL "aaa")
+ continue()
+ endif()
+ message(STATUS "${iter}")
+endwhile()
+message(STATUS "end")
diff --git a/Tests/RunCMake/continue/NoArgumentsToContinue-result.txt b/Tests/RunCMake/continue/NoArgumentsToContinue-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/continue/NoArgumentsToContinue-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/continue/NoArgumentsToContinue-stderr.txt b/Tests/RunCMake/continue/NoArgumentsToContinue-stderr.txt
new file mode 100644
index 000000000..66be46295
--- /dev/null
+++ b/Tests/RunCMake/continue/NoArgumentsToContinue-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at NoArgumentsToContinue.cmake:2 \(continue\):
+ The CONTINUE command does not accept any arguments.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/continue/NoArgumentsToContinue.cmake b/Tests/RunCMake/continue/NoArgumentsToContinue.cmake
new file mode 100644
index 000000000..609804d4b
--- /dev/null
+++ b/Tests/RunCMake/continue/NoArgumentsToContinue.cmake
@@ -0,0 +1,3 @@
+foreach(i RANGE 1 2)
+ continue(1)
+endforeach()
diff --git a/Tests/RunCMake/continue/NoEnclosingBlock-result.txt b/Tests/RunCMake/continue/NoEnclosingBlock-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/continue/NoEnclosingBlock-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/continue/NoEnclosingBlock-stderr.txt b/Tests/RunCMake/continue/NoEnclosingBlock-stderr.txt
new file mode 100644
index 000000000..24caf5712
--- /dev/null
+++ b/Tests/RunCMake/continue/NoEnclosingBlock-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at NoEnclosingBlock.cmake:1 \(continue\):
+ A CONTINUE command was found outside of a proper FOREACH or WHILE loop
+ scope.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/continue/NoEnclosingBlock.cmake b/Tests/RunCMake/continue/NoEnclosingBlock.cmake
new file mode 100644
index 000000000..9661e0d3e
--- /dev/null
+++ b/Tests/RunCMake/continue/NoEnclosingBlock.cmake
@@ -0,0 +1 @@
+continue()
diff --git a/Tests/RunCMake/continue/NoEnclosingBlockInFunction-result.txt b/Tests/RunCMake/continue/NoEnclosingBlockInFunction-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/continue/NoEnclosingBlockInFunction-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/continue/NoEnclosingBlockInFunction-stderr.txt b/Tests/RunCMake/continue/NoEnclosingBlockInFunction-stderr.txt
new file mode 100644
index 000000000..af4f3b680
--- /dev/null
+++ b/Tests/RunCMake/continue/NoEnclosingBlockInFunction-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at NoEnclosingBlockInFunction.cmake:2 \(continue\):
+ A CONTINUE command was found outside of a proper FOREACH or WHILE loop
+ scope.
+Call Stack \(most recent call first\):
+ NoEnclosingBlockInFunction.cmake:6 \(foo\)
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/continue/NoEnclosingBlockInFunction.cmake b/Tests/RunCMake/continue/NoEnclosingBlockInFunction.cmake
new file mode 100644
index 000000000..eb2a0984f
--- /dev/null
+++ b/Tests/RunCMake/continue/NoEnclosingBlockInFunction.cmake
@@ -0,0 +1,8 @@
+function(foo)
+ continue()
+endfunction(foo)
+
+foreach(i RANGE 1 2)
+ foo()
+ message(STATUS "Hello World")
+endforeach()
diff --git a/Tests/RunCMake/continue/RunCMakeTest.cmake b/Tests/RunCMake/continue/RunCMakeTest.cmake
new file mode 100644
index 000000000..37caf9c3b
--- /dev/null
+++ b/Tests/RunCMake/continue/RunCMakeTest.cmake
@@ -0,0 +1,9 @@
+include(RunCMake)
+
+run_cmake(ContinueForeach)
+run_cmake(ContinueForEachInLists)
+run_cmake(ContinueNestedForeach)
+run_cmake(ContinueWhile)
+run_cmake(NoArgumentsToContinue)
+run_cmake(NoEnclosingBlock)
+run_cmake(NoEnclosingBlockInFunction)
diff --git a/Tests/RunCMake/ctest_build/BuildChangeId-check.cmake b/Tests/RunCMake/ctest_build/BuildChangeId-check.cmake
new file mode 100644
index 000000000..074801f88
--- /dev/null
+++ b/Tests/RunCMake/ctest_build/BuildChangeId-check.cmake
@@ -0,0 +1,12 @@
+file(GLOB build_xml_file "${RunCMake_TEST_BINARY_DIR}/Testing/*/Build.xml")
+if(build_xml_file)
+ file(READ "${build_xml_file}" build_xml LIMIT 4096)
+ if(NOT build_xml MATCHES [[ChangeId="&lt;&gt;1"]])
+ string(REPLACE "\n" "\n " build_xml " ${build_xml}")
+ set(RunCMake_TEST_FAILED
+ "Build.xml does not have expected ChangeId:\n${build_xml}"
+ )
+ endif()
+else()
+ set(RunCMake_TEST_FAILED "Build.xml not found")
+endif()
diff --git a/Tests/RunCMake/ctest_build/BuildFailure-CMP0061-OLD-result.txt b/Tests/RunCMake/ctest_build/BuildFailure-CMP0061-OLD-result.txt
new file mode 100644
index 000000000..9cdf4a5ad
--- /dev/null
+++ b/Tests/RunCMake/ctest_build/BuildFailure-CMP0061-OLD-result.txt
@@ -0,0 +1 @@
+(0|-1|255)
diff --git a/Tests/RunCMake/ctest_build/BuildFailure-CMP0061-OLD-stderr.txt b/Tests/RunCMake/ctest_build/BuildFailure-CMP0061-OLD-stderr.txt
new file mode 100644
index 000000000..af70ac325
--- /dev/null
+++ b/Tests/RunCMake/ctest_build/BuildFailure-CMP0061-OLD-stderr.txt
@@ -0,0 +1,2 @@
+^(Error\(s\) when building project
+)?ctest_build returned zero$
diff --git a/Tests/RunCMake/ctest_build/BuildFailure-result.txt b/Tests/RunCMake/ctest_build/BuildFailure-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_build/BuildFailure-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_build/BuildFailure-stderr.txt b/Tests/RunCMake/ctest_build/BuildFailure-stderr.txt
new file mode 100644
index 000000000..1e6ad87c4
--- /dev/null
+++ b/Tests/RunCMake/ctest_build/BuildFailure-stderr.txt
@@ -0,0 +1,2 @@
+^Error\(s\) when building project
+ctest_build returned non-zero$
diff --git a/Tests/RunCMake/ctest_build/BuildQuiet-stdout.txt b/Tests/RunCMake/ctest_build/BuildQuiet-stdout.txt
new file mode 100644
index 000000000..2e59d99ec
--- /dev/null
+++ b/Tests/RunCMake/ctest_build/BuildQuiet-stdout.txt
@@ -0,0 +1,12 @@
+Run dashboard with model Experimental
+ Source directory: .*/Tests/RunCMake/ctest_build/BuildQuiet
+ Build directory: .*/Tests/RunCMake/ctest_build/BuildQuiet-build
+ Reading ctest configuration file: .*/Tests/RunCMake/ctest_build/BuildQuiet/CTestConfig.cmake
+ Site: test-site
+ Build name: test-build-name
+ Use Experimental tag: [0-9-]+
+Configure project
+ Each . represents 1024 bytes of output
+ . Size of output: 0K
+ 0 Compiler errors
+ 0 Compiler warnings
diff --git a/Tests/RunCMake/ctest_build/CMakeLists.txt.in b/Tests/RunCMake/ctest_build/CMakeLists.txt.in
new file mode 100644
index 000000000..82cb7c4af
--- /dev/null
+++ b/Tests/RunCMake/ctest_build/CMakeLists.txt.in
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.1)
+project(CTestBuild@CASE_NAME@ NONE)
+include(CTest)
+add_test(NAME RunCMakeVersion COMMAND "${CMAKE_COMMAND}" --version)
+@CASE_CMAKELISTS_SUFFIX_CODE@
diff --git a/Tests/RunCMake/ctest_build/CTestConfig.cmake.in b/Tests/RunCMake/ctest_build/CTestConfig.cmake.in
new file mode 100644
index 000000000..097f82c17
--- /dev/null
+++ b/Tests/RunCMake/ctest_build/CTestConfig.cmake.in
@@ -0,0 +1 @@
+set(CTEST_PROJECT_NAME "CTestBuild@CASE_NAME@")
diff --git a/Tests/RunCMake/ctest_build/RunCMakeTest.cmake b/Tests/RunCMake/ctest_build/RunCMakeTest.cmake
new file mode 100644
index 000000000..324f25c50
--- /dev/null
+++ b/Tests/RunCMake/ctest_build/RunCMakeTest.cmake
@@ -0,0 +1,42 @@
+include(RunCTest)
+
+set(CASE_CTEST_BUILD_ARGS "")
+
+function(run_ctest_build CASE_NAME)
+ set(CASE_CTEST_BUILD_ARGS "${ARGN}")
+ run_ctest(${CASE_NAME})
+endfunction()
+
+run_ctest_build(BuildQuiet QUIET)
+
+function(run_BuildFailure)
+ set(CASE_CMAKELISTS_SUFFIX_CODE [[
+add_custom_target(BuildFailure ALL COMMAND command-does-not-exist)
+]])
+ set(CASE_TEST_PREFIX_CODE [[
+cmake_policy(SET CMP0061 NEW)
+]])
+ set(CASE_TEST_SUFFIX_CODE [[
+if (ctest_build_return_value)
+ message("ctest_build returned non-zero")
+else()
+ message("ctest_build returned zero")
+endif()
+]])
+ run_ctest(BuildFailure)
+
+ if (RunCMake_GENERATOR MATCHES "Makefiles")
+ set(CASE_TEST_PREFIX_CODE "")
+ run_ctest(BuildFailure-CMP0061-OLD)
+ endif()
+endfunction()
+run_BuildFailure()
+
+function(run_BuildChangeId)
+ set(CASE_TEST_PREFIX_CODE [[
+ set(CTEST_CHANGE_ID "<>1")
+ ]])
+
+ run_ctest(BuildChangeId)
+endfunction()
+run_BuildChangeId()
diff --git a/Tests/RunCMake/ctest_build/test.cmake.in b/Tests/RunCMake/ctest_build/test.cmake.in
new file mode 100644
index 000000000..768f1c632
--- /dev/null
+++ b/Tests/RunCMake/ctest_build/test.cmake.in
@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 3.1)
+@CASE_TEST_PREFIX_CODE@
+
+set(CTEST_SITE "test-site")
+set(CTEST_BUILD_NAME "test-build-name")
+set(CTEST_SOURCE_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@")
+set(CTEST_BINARY_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@-build")
+set(CTEST_CMAKE_GENERATOR "@RunCMake_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@RunCMake_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@RunCMake_GENERATOR_TOOLSET@")
+set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
+
+set(ctest_build_args "@CASE_CTEST_BUILD_ARGS@")
+ctest_start(Experimental)
+ctest_configure()
+ctest_build(${ctest_build_args} RETURN_VALUE ctest_build_return_value)
+@CASE_TEST_SUFFIX_CODE@
diff --git a/Tests/RunCMake/ctest_configure/CMakeLists.txt.in b/Tests/RunCMake/ctest_configure/CMakeLists.txt.in
new file mode 100644
index 000000000..2fb21d45d
--- /dev/null
+++ b/Tests/RunCMake/ctest_configure/CMakeLists.txt.in
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.1)
+project(CTestConfigure@CASE_NAME@ NONE)
+include(CTest)
+add_test(NAME RunCMakeVersion COMMAND "${CMAKE_COMMAND}" --version)
diff --git a/Tests/RunCMake/ctest_configure/CTestConfig.cmake.in b/Tests/RunCMake/ctest_configure/CTestConfig.cmake.in
new file mode 100644
index 000000000..7e30ab933
--- /dev/null
+++ b/Tests/RunCMake/ctest_configure/CTestConfig.cmake.in
@@ -0,0 +1 @@
+set(CTEST_PROJECT_NAME "CTestConfigure@CASE_NAME@")
diff --git a/Tests/RunCMake/ctest_configure/ConfigureQuiet-stdout.txt b/Tests/RunCMake/ctest_configure/ConfigureQuiet-stdout.txt
new file mode 100644
index 000000000..015644d81
--- /dev/null
+++ b/Tests/RunCMake/ctest_configure/ConfigureQuiet-stdout.txt
@@ -0,0 +1,9 @@
+Run dashboard with model Experimental
+ Source directory: .*/Tests/RunCMake/ctest_configure/ConfigureQuiet
+ Build directory: .*/Tests/RunCMake/ctest_configure/ConfigureQuiet-build
+ Reading ctest configuration file: .*/Tests/RunCMake/ctest_configure/ConfigureQuiet/CTestConfig.cmake
+ Site: test-site
+ Build name: test-build-name
+ Use Experimental tag: [0-9-]+
+ Each . represents 1024 bytes of output
+ . Size of output: 0K
diff --git a/Tests/RunCMake/ctest_configure/RunCMakeTest.cmake b/Tests/RunCMake/ctest_configure/RunCMakeTest.cmake
new file mode 100644
index 000000000..fc1b02cf0
--- /dev/null
+++ b/Tests/RunCMake/ctest_configure/RunCMakeTest.cmake
@@ -0,0 +1,10 @@
+include(RunCTest)
+
+set(CASE_CTEST_CONFIGURE_ARGS "")
+
+function(run_ctest_configure CASE_NAME)
+ set(CASE_CTEST_CONFIGURE_ARGS "${ARGN}")
+ run_ctest(${CASE_NAME})
+endfunction()
+
+run_ctest_configure(ConfigureQuiet QUIET)
diff --git a/Tests/RunCMake/ctest_configure/test.cmake.in b/Tests/RunCMake/ctest_configure/test.cmake.in
new file mode 100644
index 000000000..72d199acb
--- /dev/null
+++ b/Tests/RunCMake/ctest_configure/test.cmake.in
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.1)
+
+set(CTEST_SITE "test-site")
+set(CTEST_BUILD_NAME "test-build-name")
+set(CTEST_SOURCE_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@")
+set(CTEST_BINARY_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@-build")
+set(CTEST_CMAKE_GENERATOR "@RunCMake_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@RunCMake_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@RunCMake_GENERATOR_TOOLSET@")
+set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
+
+set(ctest_configure_args "@CASE_CTEST_CONFIGURE_ARGS@")
+ctest_start(Experimental)
+ctest_configure(${ctest_configure_args})
diff --git a/Tests/RunCMake/ctest_coverage/CMakeLists.txt.in b/Tests/RunCMake/ctest_coverage/CMakeLists.txt.in
new file mode 100644
index 000000000..1babd72d9
--- /dev/null
+++ b/Tests/RunCMake/ctest_coverage/CMakeLists.txt.in
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.1)
+project(CTestCoverage@CASE_NAME@ NONE)
+include(CTest)
+add_test(NAME RunCMakeVersion COMMAND "${CMAKE_COMMAND}" --version)
diff --git a/Tests/RunCMake/ctest_coverage/CTestConfig.cmake.in b/Tests/RunCMake/ctest_coverage/CTestConfig.cmake.in
new file mode 100644
index 000000000..1f679d5d0
--- /dev/null
+++ b/Tests/RunCMake/ctest_coverage/CTestConfig.cmake.in
@@ -0,0 +1 @@
+set(CTEST_PROJECT_NAME "CTestCoverage@CASE_NAME@")
diff --git a/Tests/RunCMake/ctest_coverage/CoverageQuiet-stdout.txt b/Tests/RunCMake/ctest_coverage/CoverageQuiet-stdout.txt
new file mode 100644
index 000000000..3b09eac96
--- /dev/null
+++ b/Tests/RunCMake/ctest_coverage/CoverageQuiet-stdout.txt
@@ -0,0 +1 @@
+sec$
diff --git a/Tests/RunCMake/ctest_coverage/RunCMakeTest.cmake b/Tests/RunCMake/ctest_coverage/RunCMakeTest.cmake
new file mode 100644
index 000000000..dd443fc49
--- /dev/null
+++ b/Tests/RunCMake/ctest_coverage/RunCMakeTest.cmake
@@ -0,0 +1,10 @@
+include(RunCTest)
+
+set(CASE_CTEST_COVERAGE_ARGS "")
+
+function(run_ctest_coverage CASE_NAME)
+ set(CASE_CTEST_COVERAGE_ARGS "${ARGN}")
+ run_ctest(${CASE_NAME})
+endfunction()
+
+run_ctest_coverage(CoverageQuiet QUIET)
diff --git a/Tests/RunCMake/ctest_coverage/test.cmake.in b/Tests/RunCMake/ctest_coverage/test.cmake.in
new file mode 100644
index 000000000..1788e6647
--- /dev/null
+++ b/Tests/RunCMake/ctest_coverage/test.cmake.in
@@ -0,0 +1,18 @@
+cmake_minimum_required(VERSION 3.1)
+
+set(CTEST_SITE "test-site")
+set(CTEST_BUILD_NAME "test-build-name")
+set(CTEST_SOURCE_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@")
+set(CTEST_BINARY_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@-build")
+set(CTEST_CMAKE_GENERATOR "@RunCMake_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@RunCMake_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@RunCMake_GENERATOR_TOOLSET@")
+set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
+set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
+
+set(ctest_coverage_args "@CASE_CTEST_COVERAGE_ARGS@")
+ctest_start(Experimental)
+ctest_configure()
+ctest_build()
+ctest_test()
+ctest_coverage(${ctest_coverage_args})
diff --git a/Tests/RunCMake/ctest_memcheck/CMakeLists.txt.in b/Tests/RunCMake/ctest_memcheck/CMakeLists.txt.in
new file mode 100644
index 000000000..3b8edf4c9
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/CMakeLists.txt.in
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 2.8.9)
+project(CTestTestMemcheck@CASE_NAME@ NONE)
+include(CTest)
+
+add_test(NAME RunCMake COMMAND "${CMAKE_COMMAND}" --version)
+
+@CMAKELISTS_EXTRA_CODE@
diff --git a/Tests/RunCMake/ctest_memcheck/CTestConfig.cmake.in b/Tests/RunCMake/ctest_memcheck/CTestConfig.cmake.in
new file mode 100644
index 000000000..6d4a718d0
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/CTestConfig.cmake.in
@@ -0,0 +1,9 @@
+set (CTEST_PROJECT_NAME "CTestTestMemcheck@CASE_NAME@")
+set (CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
+set (CTEST_DART_SERVER_VERSION "2")
+set(CTEST_DROP_METHOD "http")
+set(CTEST_DROP_SITE "open.cdash.org")
+set(CTEST_DROP_LOCATION "/submit.php?project=PublicDashboard")
+set(CTEST_DROP_SITE_CDASH TRUE)
+
+@CTEST_EXTRA_CONFIG@
diff --git a/Tests/RunCMake/ctest_memcheck/DummyAddressSanitizer-result.txt b/Tests/RunCMake/ctest_memcheck/DummyAddressSanitizer-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyAddressSanitizer-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_memcheck/DummyAddressSanitizer-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyAddressSanitizer-stderr.txt
new file mode 100644
index 000000000..8fa3f1b8b
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyAddressSanitizer-stderr.txt
@@ -0,0 +1 @@
+Cannot find memory tester output file: .*/Tests/RunCMake/ctest_memcheck/DummyAddressSanitizer-build/Testing/Temporary/MemoryChecker.1.log\.\*
diff --git a/Tests/RunCMake/ctest_memcheck/DummyAddressSanitizer-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyAddressSanitizer-stdout.txt
new file mode 100644
index 000000000..1d255d0fc
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyAddressSanitizer-stdout.txt
@@ -0,0 +1,2 @@
+Memory checking results:
+heap-buffer-overflow - 1
diff --git a/Tests/RunCMake/ctest_memcheck/DummyBC-result.txt b/Tests/RunCMake/ctest_memcheck/DummyBC-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyBC-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_memcheck/DummyBC-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyBC-stderr.txt
new file mode 100644
index 000000000..24f536af2
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyBC-stderr.txt
@@ -0,0 +1 @@
+Error parsing XML in stream at line 1: no element found
diff --git a/Tests/RunCMake/ctest_memcheck/DummyBC-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyBC-stdout.txt
new file mode 100644
index 000000000..58296135a
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyBC-stdout.txt
@@ -0,0 +1,3 @@
+1/1 MemCheck #1: RunCMake \.+ Passed +[0-9]+.[0-9]+ sec
+
+100% tests passed, 0 tests failed out of 1
diff --git a/Tests/RunCMake/ctest_memcheck/DummyBCNoLogFile-result.txt b/Tests/RunCMake/ctest_memcheck/DummyBCNoLogFile-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyBCNoLogFile-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_memcheck/DummyBCNoLogFile-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyBCNoLogFile-stderr.txt
new file mode 100644
index 000000000..adc744b9f
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyBCNoLogFile-stderr.txt
@@ -0,0 +1,2 @@
+Cannot find memory tester output file: .*/Tests/RunCMake/ctest_memcheck/DummyBCNoLogFile-build/Testing/Temporary/MemoryChecker.1.log
+.*Error parsing XML in stream at line 1: no element found
diff --git a/Tests/RunCMake/ctest_memcheck/DummyBCNoLogFile-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyBCNoLogFile-stdout.txt
new file mode 100644
index 000000000..58296135a
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyBCNoLogFile-stdout.txt
@@ -0,0 +1,3 @@
+1/1 MemCheck #1: RunCMake \.+ Passed +[0-9]+.[0-9]+ sec
+
+100% tests passed, 0 tests failed out of 1
diff --git a/Tests/RunCMake/ctest_memcheck/DummyLeakSanitizer-result.txt b/Tests/RunCMake/ctest_memcheck/DummyLeakSanitizer-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyLeakSanitizer-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_memcheck/DummyLeakSanitizer-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyLeakSanitizer-stderr.txt
new file mode 100644
index 000000000..35510431d
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyLeakSanitizer-stderr.txt
@@ -0,0 +1 @@
+Cannot find memory tester output file: .*/Tests/RunCMake/ctest_memcheck/DummyLeakSanitizer-build/Testing/Temporary/MemoryChecker.1.log\.\*
diff --git a/Tests/RunCMake/ctest_memcheck/DummyLeakSanitizer-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyLeakSanitizer-stdout.txt
new file mode 100644
index 000000000..97a8a9b46
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyLeakSanitizer-stdout.txt
@@ -0,0 +1,3 @@
+Memory checking results:
+Direct leak - 2
+Indirect leak - 1
diff --git a/Tests/RunCMake/ctest_memcheck/DummyMemorySanitizer-result.txt b/Tests/RunCMake/ctest_memcheck/DummyMemorySanitizer-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyMemorySanitizer-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_memcheck/DummyMemorySanitizer-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyMemorySanitizer-stderr.txt
new file mode 100644
index 000000000..02d562674
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyMemorySanitizer-stderr.txt
@@ -0,0 +1 @@
+Cannot find memory tester output file: .*/Tests/RunCMake/ctest_memcheck/DummyMemorySanitizer-build/Testing/Temporary/MemoryChecker.1.log\.\*
diff --git a/Tests/RunCMake/ctest_memcheck/DummyMemorySanitizer-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyMemorySanitizer-stdout.txt
new file mode 100644
index 000000000..64390c700
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyMemorySanitizer-stdout.txt
@@ -0,0 +1,2 @@
+Memory checking results:
+use-of-uninitialized-value - 1
diff --git a/Tests/RunCMake/ctest_memcheck/DummyPurify-result.txt b/Tests/RunCMake/ctest_memcheck/DummyPurify-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyPurify-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/ctest_memcheck/DummyPurify-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyPurify-stdout.txt
new file mode 100644
index 000000000..dabb004fe
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyPurify-stdout.txt
@@ -0,0 +1,6 @@
+1/1 MemCheck #1: RunCMake \.+ Passed +[0-9]+.[0-9]+ sec
+
+100% tests passed, 0 tests failed out of 1
+.*
+-- Processing memory checking output:( )
+Memory checking results:
diff --git a/Tests/RunCMake/ctest_memcheck/DummyPurifyNoLogFile-result.txt b/Tests/RunCMake/ctest_memcheck/DummyPurifyNoLogFile-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyPurifyNoLogFile-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_memcheck/DummyPurifyNoLogFile-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyPurifyNoLogFile-stderr.txt
new file mode 100644
index 000000000..653c1367e
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyPurifyNoLogFile-stderr.txt
@@ -0,0 +1 @@
+Cannot find memory tester output file: .*/Tests/RunCMake/ctest_memcheck/DummyPurifyNoLogFile-build/Testing/Temporary/MemoryChecker.1.log
diff --git a/Tests/RunCMake/ctest_memcheck/DummyPurifyNoLogFile-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyPurifyNoLogFile-stdout.txt
new file mode 100644
index 000000000..58296135a
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyPurifyNoLogFile-stdout.txt
@@ -0,0 +1,3 @@
+1/1 MemCheck #1: RunCMake \.+ Passed +[0-9]+.[0-9]+ sec
+
+100% tests passed, 0 tests failed out of 1
diff --git a/Tests/RunCMake/ctest_memcheck/DummyQuiet-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyQuiet-stdout.txt
new file mode 100644
index 000000000..58f55a5a7
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyQuiet-stdout.txt
@@ -0,0 +1 @@
+0 tests failed out of 1$
diff --git a/Tests/RunCMake/ctest_memcheck/DummyThreadSanitizer-result.txt b/Tests/RunCMake/ctest_memcheck/DummyThreadSanitizer-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyThreadSanitizer-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_memcheck/DummyThreadSanitizer-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyThreadSanitizer-stderr.txt
new file mode 100644
index 000000000..5f6c6c1a8
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyThreadSanitizer-stderr.txt
@@ -0,0 +1 @@
+Cannot find memory tester output file: .*/Tests/RunCMake/ctest_memcheck/DummyThreadSanitizer-build/Testing/Temporary/MemoryChecker.1.log\.\*
diff --git a/Tests/RunCMake/ctest_memcheck/DummyThreadSanitizer-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyThreadSanitizer-stdout.txt
new file mode 100644
index 000000000..c3af1f9bf
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyThreadSanitizer-stdout.txt
@@ -0,0 +1,13 @@
+Memory checking results:
+data race - 1
+data race on vptr \(ctor/dtor vs virtual call\) - 1
+heap-use-after-free - 1
+thread leak - 1
+destroy of a locked mutex - 1
+double lock of a mutex - 1
+unlock of an unlocked mutex \(or by a wrong thread\) - 1
+read lock of a write locked mutex - 1
+read unlock of a write locked mutex - 1
+signal-unsafe call inside of a signal - 1
+signal handler spoils errno - 1
+lock-order-inversion \(potential deadlock\) - 1
diff --git a/Tests/RunCMake/ctest_memcheck/DummyUndefinedBehaviorSanitizer-result.txt b/Tests/RunCMake/ctest_memcheck/DummyUndefinedBehaviorSanitizer-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyUndefinedBehaviorSanitizer-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_memcheck/DummyUndefinedBehaviorSanitizer-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyUndefinedBehaviorSanitizer-stderr.txt
new file mode 100644
index 000000000..423b7f704
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyUndefinedBehaviorSanitizer-stderr.txt
@@ -0,0 +1 @@
+Cannot find memory tester output file: .*/Tests/RunCMake/ctest_memcheck/DummyUndefinedBehaviorSanitizer-build/Testing/Temporary/MemoryChecker.1.log\.\*
diff --git a/Tests/RunCMake/ctest_memcheck/DummyUndefinedBehaviorSanitizer-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyUndefinedBehaviorSanitizer-stdout.txt
new file mode 100644
index 000000000..b3473bfd9
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyUndefinedBehaviorSanitizer-stdout.txt
@@ -0,0 +1,2 @@
+Memory checking results:
+left shift of negative value -256 - 1
diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrind-result.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrind-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyValgrind-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrind-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrind-stdout.txt
new file mode 100644
index 000000000..dabb004fe
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyValgrind-stdout.txt
@@ -0,0 +1,6 @@
+1/1 MemCheck #1: RunCMake \.+ Passed +[0-9]+.[0-9]+ sec
+
+100% tests passed, 0 tests failed out of 1
+.*
+-- Processing memory checking output:( )
+Memory checking results:
diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindCustomOptions-result.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindCustomOptions-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindCustomOptions-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindCustomOptions-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindCustomOptions-stderr.txt
new file mode 100644
index 000000000..032b5b44f
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindCustomOptions-stderr.txt
@@ -0,0 +1 @@
+Cannot find memory tester output file: .*/Tests/RunCMake/ctest_memcheck/DummyValgrindCustomOptions-build/Testing/Temporary/MemoryChecker.1.log
diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindCustomOptions-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindCustomOptions-stdout.txt
new file mode 100644
index 000000000..dabb004fe
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindCustomOptions-stdout.txt
@@ -0,0 +1,6 @@
+1/1 MemCheck #1: RunCMake \.+ Passed +[0-9]+.[0-9]+ sec
+
+100% tests passed, 0 tests failed out of 1
+.*
+-- Processing memory checking output:( )
+Memory checking results:
diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPost-result.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPost-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPost-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPost-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPost-stderr.txt
new file mode 100644
index 000000000..6f5231867
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPost-stderr.txt
@@ -0,0 +1,2 @@
+Problem running command: .*memcheck_fail.*
+Problem executing post-memcheck command\(s\).
diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPost-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPost-stdout.txt
new file mode 100644
index 000000000..dabb004fe
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPost-stdout.txt
@@ -0,0 +1,6 @@
+1/1 MemCheck #1: RunCMake \.+ Passed +[0-9]+.[0-9]+ sec
+
+100% tests passed, 0 tests failed out of 1
+.*
+-- Processing memory checking output:( )
+Memory checking results:
diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPre-result.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPre-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPre-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPre-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPre-stderr.txt
new file mode 100644
index 000000000..973c01486
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPre-stderr.txt
@@ -0,0 +1,2 @@
+Problem running command: .*memcheck_fail.*
+Problem executing pre-memcheck command\(s\).
diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPre-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPre-stdout.txt
new file mode 100644
index 000000000..8d8b7e9ee
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPre-stdout.txt
@@ -0,0 +1 @@
+Memory check project .*/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPre-build
diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindIgnoreMemcheck-result.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindIgnoreMemcheck-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindIgnoreMemcheck-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindIgnoreMemcheck-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindIgnoreMemcheck-stdout.txt
new file mode 100644
index 000000000..5a5675cd5
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindIgnoreMemcheck-stdout.txt
@@ -0,0 +1,7 @@
+2/2 Test #2: RunCMakeAgain .*
+1/1 MemCheck #1: RunCMake \.+ Passed +[0-9]+.[0-9]+ sec
+
+100% tests passed, 0 tests failed out of 1
+.*
+-- Processing memory checking output:( )
+Memory checking results:
diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindInvalidSupFile-result.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindInvalidSupFile-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindInvalidSupFile-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindInvalidSupFile-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindInvalidSupFile-stderr.txt
new file mode 100644
index 000000000..42cd5e80b
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindInvalidSupFile-stderr.txt
@@ -0,0 +1 @@
+Cannot find memory checker suppression file: .*/Tests/RunCMake/ctest_memcheck/DummyValgrindInvalidSupFile-build/does-not-exist
diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindInvalidSupFile-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindInvalidSupFile-stdout.txt
new file mode 100644
index 000000000..4c58df40b
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindInvalidSupFile-stdout.txt
@@ -0,0 +1 @@
+Memory check project .*/Tests/RunCMake/ctest_memcheck/DummyValgrindInvalidSupFile-build$
diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindNoLogFile-result.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindNoLogFile-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindNoLogFile-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindNoLogFile-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindNoLogFile-stderr.txt
new file mode 100644
index 000000000..18d9f035f
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindNoLogFile-stderr.txt
@@ -0,0 +1 @@
+Cannot find memory tester output file: .*/Tests/RunCMake/ctest_memcheck/DummyValgrindNoLogFile-build/Testing/Temporary/MemoryChecker.1.log
diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindNoLogFile-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindNoLogFile-stdout.txt
new file mode 100644
index 000000000..58296135a
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindNoLogFile-stdout.txt
@@ -0,0 +1,3 @@
+1/1 MemCheck #1: RunCMake \.+ Passed +[0-9]+.[0-9]+ sec
+
+100% tests passed, 0 tests failed out of 1
diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindPrePost-result.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindPrePost-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindPrePost-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindPrePost-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindPrePost-stdout.txt
new file mode 100644
index 000000000..dabb004fe
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindPrePost-stdout.txt
@@ -0,0 +1,6 @@
+1/1 MemCheck #1: RunCMake \.+ Passed +[0-9]+.[0-9]+ sec
+
+100% tests passed, 0 tests failed out of 1
+.*
+-- Processing memory checking output:( )
+Memory checking results:
diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindTwoTargets-result.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindTwoTargets-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindTwoTargets-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindTwoTargets-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindTwoTargets-stdout.txt
new file mode 100644
index 000000000..3e0fdb2a5
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindTwoTargets-stdout.txt
@@ -0,0 +1,8 @@
+Memory check project .*/DummyValgrindTwoTargets-build
+.*
+ *Start 1: RunCMake
+(.*
+)?Memory check command: .* \"--log-file=.*/DummyValgrindTwoTargets-build/Testing/Temporary/MemoryChecker.1.log\" \"-q\".*
+ *Start 2: RunCMakeAgain
+(.*
+)?Memory check command: .* \"--log-file=.*/DummyValgrindTwoTargets-build/Testing/Temporary/MemoryChecker.2.log\" \"-q\".*
diff --git a/Tests/RunCMake/ctest_memcheck/NotExist-result.txt b/Tests/RunCMake/ctest_memcheck/NotExist-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/NotExist-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/ctest_memcheck/NotExist-stderr.txt b/Tests/RunCMake/ctest_memcheck/NotExist-stderr.txt
new file mode 100644
index 000000000..0af5b7a5c
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/NotExist-stderr.txt
@@ -0,0 +1 @@
+Memory checker \(MemoryCheckCommand\) not set, or cannot find the specified program\.
diff --git a/Tests/RunCMake/ctest_memcheck/NotExist-stdout.txt b/Tests/RunCMake/ctest_memcheck/NotExist-stdout.txt
new file mode 100644
index 000000000..0e58936c5
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/NotExist-stdout.txt
@@ -0,0 +1 @@
+Memory check project .*/Tests/RunCMake/ctest_memcheck/NotExist-build$
diff --git a/Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake b/Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake
new file mode 100644
index 000000000..5ad65110a
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake
@@ -0,0 +1,135 @@
+include(RunCTest)
+
+set(SITE test-site)
+set(BUILDNAME test-build)
+set(COVERAGE_COMMAND "")
+
+unset(ENV{CTEST_PARALLEL_LEVEL})
+
+function(run_mc_test CASE_NAME CHECKER_COMMAND)
+ run_ctest(${CASE_NAME} ${ARGN})
+endfunction()
+
+unset(CTEST_EXTRA_CONFIG)
+unset(CTEST_EXTRA_CODE)
+unset(CMAKELISTS_EXTRA_CODE)
+
+#-----------------------------------------------------------------------------
+# add ThreadSanitizer test
+set(CTEST_EXTRA_CODE
+"set(CTEST_MEMORYCHECK_COMMAND_OPTIONS \"report_bugs=1 history_size=5 exitcode=55\")
+")
+set(CMAKELISTS_EXTRA_CODE
+"add_test(NAME TestSan COMMAND \"\${CMAKE_COMMAND}\"
+-P \"${RunCMake_SOURCE_DIR}/testThreadSanitizer.cmake\")
+")
+run_mc_test(DummyThreadSanitizer "" -DMEMCHECK_TYPE=ThreadSanitizer)
+unset(CMAKELISTS_EXTRA_CODE)
+unset(CTEST_EXTRA_CODE)
+
+#-----------------------------------------------------------------------------
+# add LeakSanitizer test
+set(CTEST_EXTRA_CODE
+"set(CTEST_MEMORYCHECK_SANITIZER_OPTIONS \"simulate_sanitizer=1 report_bugs=1 history_size=5 exitcode=55\")
+")
+set(CMAKELISTS_EXTRA_CODE
+"add_test(NAME TestSan COMMAND \"${CMAKE_COMMAND}\"
+-P \"${RunCMake_SOURCE_DIR}/testLeakSanitizer.cmake\")
+")
+run_mc_test(DummyLeakSanitizer "" -DMEMCHECK_TYPE=AddressSanitizer)
+unset(CMAKELISTS_EXTRA_CODE)
+unset(CTEST_EXTRA_CODE)
+
+#-----------------------------------------------------------------------------
+# add AddressSanitizer test
+set(CTEST_EXTRA_CODE
+"set(CTEST_MEMORYCHECK_SANITIZER_OPTIONS \"simulate_sanitizer=1 report_bugs=1 history_size=5 exitcode=55\")
+")
+set(CMAKELISTS_EXTRA_CODE
+"add_test(NAME TestSan COMMAND \"\${CMAKE_COMMAND}\"
+-P \"${RunCMake_SOURCE_DIR}/testAddressSanitizer.cmake\")
+")
+run_mc_test(DummyAddressSanitizer "" -DMEMCHECK_TYPE=AddressSanitizer)
+unset(CMAKELISTS_EXTRA_CODE)
+unset(CTEST_EXTRA_CODE)
+
+#-----------------------------------------------------------------------------
+# add MemorySanitizer test
+set(CTEST_EXTRA_CODE
+"set(CTEST_MEMORYCHECK_COMMAND_OPTIONS \"simulate_sanitizer=1 report_bugs=1 history_size=5 exitcode=55\")
+")
+set(CMAKELISTS_EXTRA_CODE
+"add_test(NAME TestSan COMMAND \"\${CMAKE_COMMAND}\"
+-P \"${RunCMake_SOURCE_DIR}/testMemorySanitizer.cmake\")
+")
+run_mc_test(DummyMemorySanitizer "" -DMEMCHECK_TYPE=MemorySanitizer)
+unset(CMAKELISTS_EXTRA_CODE)
+unset(CTEST_EXTRA_CODE)
+
+#-----------------------------------------------------------------------------
+# add UndefinedBehaviorSanitizer test
+set(CTEST_EXTRA_CODE
+"set(CTEST_MEMORYCHECK_SANITIZER_OPTIONS \"simulate_sanitizer=1\")
+")
+set(CMAKELISTS_EXTRA_CODE
+"add_test(NAME TestSan COMMAND \"\${CMAKE_COMMAND}\"
+-P \"${RunCMake_SOURCE_DIR}/testUndefinedBehaviorSanitizer.cmake\")
+")
+run_mc_test(DummyUndefinedBehaviorSanitizer "" -DMEMCHECK_TYPE=UndefinedBehaviorSanitizer)
+unset(CMAKELISTS_EXTRA_CODE)
+unset(CTEST_EXTRA_CODE)
+
+#-----------------------------------------------------------------------------
+set(CTEST_EXTRA_CODE "string(REPLACE \" \" \"\\\\ \" PRE_POST_COMMAND \"\${CTEST_MEMORYCHECK_COMMAND}\")
+
+set(CTEST_CUSTOM_PRE_MEMCHECK \"\${PRE_POST_COMMAND} pre command\")
+set(CTEST_CUSTOM_POST_MEMCHECK \"\${PRE_POST_COMMAND} post command \")
+")
+run_mc_test(DummyValgrindPrePost "${PSEUDO_VALGRIND}")
+unset(CTEST_EXTRA_CODE)
+
+#-----------------------------------------------------------------------------
+set(CTEST_EXTRA_CODE "set(CTEST_CUSTOM_POST_MEMCHECK \"${MEMCHECK_FAIL}\")")
+run_mc_test(DummyValgrindFailPost "${PSEUDO_VALGRIND}")
+unset(CTEST_EXTRA_CODE)
+
+#-----------------------------------------------------------------------------
+set(CTEST_EXTRA_CODE "set(CTEST_CUSTOM_PRE_MEMCHECK \"${MEMCHECK_FAIL}\")")
+run_mc_test(DummyValgrindFailPre "${PSEUDO_VALGRIND}")
+unset(CTEST_EXTRA_CODE)
+
+#-----------------------------------------------------------------------------
+set(CTEST_EXTRA_CONFIG "set(CTEST_CUSTOM_MEMCHECK_IGNORE RunCMakeAgain)\n")
+set(CMAKELISTS_EXTRA_CODE "add_test(NAME RunCMakeAgain COMMAND \"\${CMAKE_COMMAND}\" --version)")
+run_mc_test(DummyValgrindIgnoreMemcheck "${PSEUDO_VALGRIND}")
+unset(CTEST_EXTRA_CONFIG)
+unset(CMAKELISTS_EXTRA_CODE)
+
+#-----------------------------------------------------------------------------
+set(CMAKELISTS_EXTRA_CODE "add_test(NAME RunCMakeAgain COMMAND \"\${CMAKE_COMMAND}\" --version)")
+run_mc_test(DummyValgrindTwoTargets "${PSEUDO_VALGRIND}" "-VV")
+unset(CMAKELISTS_EXTRA_CODE)
+
+#-----------------------------------------------------------------------------
+set(CTEST_EXTRA_CONFIG "set(CTEST_MEMORYCHECK_SUPPRESSIONS_FILE \"\${CMAKE_CURRENT_BINARY_DIR}/does-not-exist\")")
+run_mc_test(DummyValgrindInvalidSupFile "${PSEUDO_VALGRIND}")
+unset(CTEST_EXTRA_CONFIG)
+
+#-----------------------------------------------------------------------------
+# CTest will add the logfile option before any custom options. Set the logfile
+# again, this time to an empty string. This will cause the logfile to be
+# missing, which will be the prove for us that the custom option is indeed used.
+set(CTEST_EXTRA_CONFIG "set(CTEST_MEMORYCHECK_COMMAND_OPTIONS \"--log-file=\")")
+run_mc_test(DummyValgrindCustomOptions "${PSEUDO_VALGRIND}")
+unset(CTEST_EXTRA_CONFIG)
+
+#-----------------------------------------------------------------------------
+run_mc_test(DummyPurify "${PSEUDO_PURIFY}")
+run_mc_test(DummyValgrind "${PSEUDO_VALGRIND}")
+run_mc_test(DummyBC "${PSEUDO_BC}")
+run_mc_test(DummyPurifyNoLogFile "${PSEUDO_PURIFY_NOLOG}")
+run_mc_test(DummyValgrindNoLogFile "${PSEUDO_VALGRIND_NOLOG}")
+run_mc_test(DummyBCNoLogFile "${PSEUDO_BC_NOLOG}")
+run_mc_test(NotExist "\${CTEST_BINARY_DIRECTORY}/no-memcheck-exe")
+run_mc_test(Unknown "\${CMAKE_COMMAND}")
+run_mc_test(DummyQuiet "${PSEUDO_VALGRIND}" -DMEMCHECK_ARGS=QUIET)
diff --git a/Tests/RunCMake/ctest_memcheck/Unknown-result.txt b/Tests/RunCMake/ctest_memcheck/Unknown-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/Unknown-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_memcheck/Unknown-stderr.txt b/Tests/RunCMake/ctest_memcheck/Unknown-stderr.txt
new file mode 100644
index 000000000..8868e0c83
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/Unknown-stderr.txt
@@ -0,0 +1 @@
+Do not understand memory checker: .*/cmake.*
diff --git a/Tests/RunCMake/ctest_memcheck/Unknown-stdout.txt b/Tests/RunCMake/ctest_memcheck/Unknown-stdout.txt
new file mode 100644
index 000000000..0208e80f1
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/Unknown-stdout.txt
@@ -0,0 +1 @@
+Memory check project .*/Tests/RunCMake/ctest_memcheck/Unknown-build$
diff --git a/Tests/RunCMake/ctest_memcheck/test.cmake.in b/Tests/RunCMake/ctest_memcheck/test.cmake.in
new file mode 100644
index 000000000..8431fa693
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/test.cmake.in
@@ -0,0 +1,24 @@
+cmake_minimum_required(VERSION 2.8.9)
+
+# Settings:
+set(CTEST_SITE "@SITE@")
+set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-Memcheck@CASE_NAME@")
+
+set(CTEST_SOURCE_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@")
+set(CTEST_BINARY_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@-build")
+set(CTEST_CMAKE_GENERATOR "@RunCMake_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@RunCMake_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@RunCMake_GENERATOR_TOOLSET@")
+set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
+set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
+set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
+
+set(CTEST_MEMORYCHECK_COMMAND "@CHECKER_COMMAND@")
+set(CTEST_MEMORYCHECK_TYPE "${MEMCHECK_TYPE}")
+
+@CTEST_EXTRA_CODE@
+
+CTEST_START(Experimental)
+CTEST_CONFIGURE(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
+CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
+CTEST_MEMCHECK(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res ${MEMCHECK_ARGS})
diff --git a/Tests/RunCMake/ctest_memcheck/testAddressSanitizer.cmake b/Tests/RunCMake/ctest_memcheck/testAddressSanitizer.cmake
new file mode 100644
index 000000000..3082e4b5a
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/testAddressSanitizer.cmake
@@ -0,0 +1,58 @@
+# this file simulates a program that has been built with address sanitizer
+# options
+
+message("ASAN_OPTIONS = [$ENV{ASAN_OPTIONS}]")
+string(REGEX REPLACE ".*log_path=\"([^\"]*)\".*" "\\1" LOG_FILE "$ENV{ASAN_OPTIONS}")
+message("LOG_FILE=[${LOG_FILE}]")
+
+# if we are not asked to simulate address sanitizer don't do it
+if(NOT "$ENV{ASAN_OPTIONS}]" MATCHES "simulate_sanitizer.1")
+ return()
+endif()
+# clear the log file
+file(REMOVE "${LOG_FILE}.2343")
+
+# create an example error from address santizer
+
+file(APPEND "${LOG_FILE}.2343"
+"=================================================================
+==19278== ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60080000bffc at pc 0x4009f1 bp 0x7fff82de6520 sp 0x7fff82de6518
+WRITE of size 4 at 0x60080000bffc thread T0
+ #0 0x4009f0 (/home/kitware/msan/a.out+0x4009f0)
+ #1 0x7f18b02c876c (/lib/x86_64-linux-gnu/libc-2.15.so+0x2176c)
+ #2 0x400858 (/home/kitware/msan/a.out+0x400858)
+0x60080000bffc is located 4 bytes to the right of 40-byte region [0x60080000bfd0,0x60080000bff8)
+allocated by thread T0 here:
+ #0 0x7f18b088f9ca (/usr/lib/x86_64-linux-gnu/libasan.so.0.0.0+0x119ca)
+ #1 0x4009a2 (/home/kitware/msan/a.out+0x4009a2)
+ #2 0x7f18b02c876c (/lib/x86_64-linux-gnu/libc-2.15.so+0x2176c)
+Shadow bytes around the buggy address:
+ 0x0c017fff97a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
+ 0x0c017fff97b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
+ 0x0c017fff97c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
+ 0x0c017fff97d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
+ 0x0c017fff97e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
+=>0x0c017fff97f0: fa fa fa fa fa fa fa fa fa fa 00 00 00 00 00[fa]
+ 0x0c017fff9800:fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
+ 0x0c017fff9810: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
+ 0x0c017fff9820: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
+ 0x0c017fff9830: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
+ 0x0c017fff9840: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
+Shadow byte legend (one shadow byte represents 8 application bytes):
+ Addressable: 00
+ Partially addressable: 01 02 03 04 05 06 07
+ Heap left redzone: fa
+ Heap righ redzone: fb
+ Freed Heap region: fd
+ Stack left redzone: f1
+ Stack mid redzone: f2
+ Stack right redzone: f3
+ Stack partial redzone: f4
+ Stack after return: f5
+ Stack use after scope: f8
+ Global redzone: f9
+ Global init order: f6
+ Poisoned by user: f7
+ ASan internal: fe
+==19278== ABORTING
+")
diff --git a/Tests/RunCMake/ctest_memcheck/testLeakSanitizer.cmake b/Tests/RunCMake/ctest_memcheck/testLeakSanitizer.cmake
new file mode 100644
index 000000000..02030be87
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/testLeakSanitizer.cmake
@@ -0,0 +1,47 @@
+# this file simulates a program that has been built with thread sanitizer
+# options
+
+message("ASAN_OPTIONS = [$ENV{ASAN_OPTIONS}]")
+string(REGEX REPLACE ".*log_path=\"([^\"]*)\".*" "\\1" LOG_FILE "$ENV{ASAN_OPTIONS}")
+message("LOG_FILE=[${LOG_FILE}]")
+# if we are not asked to simulate leak sanitizer don't do it
+if(NOT "$ENV{ASAN_OPTIONS}]" MATCHES "simulate_sanitizer.1")
+ return()
+endif()
+
+# clear the log file
+file(REMOVE "${LOG_FILE}.2343")
+file(REMOVE "${LOG_FILE}.2344")
+
+# create an error of each type of thread santizer
+# these names come from tsan_report.cc in llvm
+
+file(APPEND "${LOG_FILE}.2343"
+"=================================================================
+==25308==ERROR: LeakSanitizer: detected memory leaks
+
+Direct leak of 4360 byte(s) in 1 object(s) allocated from:
+ #0 0x46c669 in operator new[](unsigned long) (/home/kitware/msan/a.out+0x46c669)
+ #1 0x4823b4 in main /home/kitware/msan/memcheck.cxx:12
+ #2 0x7fa72bee476c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226
+
+SUMMARY: AddressSanitizer: 4436 byte(s) leaked in 2 allocation(s).
+")
+file(APPEND "${LOG_FILE}.2342"
+"=================================================================
+==25308==ERROR: LeakSanitizer: detected memory leaks
+
+Direct leak of 76 byte(s) in 1 object(s) allocated from:
+ #0 0x46c669 in operator new[](unsigned long) (/home/kitware/msan/a.out+0x46c669)
+ #1 0x4821b8 in foo() /home/kitware/msan/memcheck.cxx:4
+ #2 0x4823f2 in main /home/kitware/msan/memcheck.cxx:14
+ #3 0x7fa72bee476c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226
+
+Indirect leak of 76 byte(s) in 1 object(s) allocated from:
+ #0 0x46c669 in operator new[](unsigned long) (/home/kitware/msan/a.out+0x46c669)
+ #1 0x4821b8 in foo() /home/kitware/msan/memcheck.cxx:4
+ #2 0x4823f2 in main /home/kitware/msan/memcheck.cxx:14
+ #3 0x7fa72bee476c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226
+
+SUMMARY: AddressSanitizer: 4436 byte(s) leaked in 2 allocation(s).
+")
diff --git a/Tests/RunCMake/ctest_memcheck/testMemorySanitizer.cmake b/Tests/RunCMake/ctest_memcheck/testMemorySanitizer.cmake
new file mode 100644
index 000000000..c87af9a43
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/testMemorySanitizer.cmake
@@ -0,0 +1,27 @@
+# this file simulates a program that has been built with thread sanitizer
+# options
+
+message("MSAN_OPTIONS = [$ENV{MSAN_OPTIONS}]")
+string(REGEX REPLACE ".*log_path=\"([^\"]*)\".*" "\\1" LOG_FILE "$ENV{MSAN_OPTIONS}")
+message("LOG_FILE=[${LOG_FILE}]")
+
+# if we are not asked to simulate address sanitizer don't do it
+if(NOT "$ENV{MSAN_OPTIONS}]" MATCHES "simulate_sanitizer.1")
+ return()
+endif()
+# clear the log file
+file(REMOVE "${LOG_FILE}.2343")
+
+# create an error of each type of thread santizer
+# these names come from tsan_report.cc in llvm
+
+file(APPEND "${LOG_FILE}.2343"
+"=================================================================
+==28423== WARNING: MemorySanitizer: use-of-uninitialized-value
+ #0 0x7f4364210dd9 in main (/home/kitware/msan/msan-bin/umr+0x7bdd9)
+ #1 0x7f4362d9376c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226
+ #2 0x7f4364210b0c in _start (/home/kitware/msan/msan-bin/umr+0x7bb0c)
+
+SUMMARY: MemorySanitizer: use-of-uninitialized-value ??:0 main
+Exiting
+")
diff --git a/Tests/RunCMake/ctest_memcheck/testThreadSanitizer.cmake b/Tests/RunCMake/ctest_memcheck/testThreadSanitizer.cmake
new file mode 100644
index 000000000..d59193146
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/testThreadSanitizer.cmake
@@ -0,0 +1,47 @@
+# this file simulates a program that has been built with thread sanitizer
+# options
+
+message("TSAN_OPTIONS = [$ENV{TSAN_OPTIONS}]")
+string(REGEX REPLACE ".*log_path=\"([^\"]*)\".*" "\\1" LOG_FILE "$ENV{TSAN_OPTIONS}")
+message("LOG_FILE=[${LOG_FILE}]")
+
+set(error_types
+ "data race"
+ "data race on vptr (ctor/dtor vs virtual call)"
+ "heap-use-after-free"
+ "thread leak"
+ "destroy of a locked mutex"
+ "double lock of a mutex"
+ "unlock of an unlocked mutex (or by a wrong thread)"
+ "read lock of a write locked mutex"
+ "read unlock of a write locked mutex"
+ "signal-unsafe call inside of a signal"
+ "signal handler spoils errno"
+ "lock-order-inversion (potential deadlock)"
+ )
+
+# clear the log file
+file(REMOVE "${LOG_FILE}.2343")
+
+# create an error of each type of thread santizer
+# these names come from tsan_report.cc in llvm
+foreach(error_type ${error_types} )
+
+ file(APPEND "${LOG_FILE}.2343"
+"==================
+WARNING: ThreadSanitizer: ${error_type} (pid=27978)
+ Write of size 4 at 0x7fe017ce906c by thread T1:
+ #0 Thread1 ??:0 (exe+0x000000000bb0)
+ #1 <null> <null>:0 (libtsan.so.0+0x00000001b279)
+
+ Previous write of size 4 at 0x7fe017ce906c by main thread:
+ #0 main ??:0 (exe+0x000000000c3c)
+
+ Thread T1 (tid=27979, running) created by main thread at:
+ #0 <null> <null>:0 (libtsan.so.0+0x00000001ed7b)
+ #1 main ??:0 (exe+0x000000000c2c)
+
+SUMMARY: ThreadSanitizer: ${error_type} ??:0 Thread1
+==================
+")
+endforeach()
diff --git a/Tests/RunCMake/ctest_memcheck/testUndefinedBehaviorSanitizer.cmake b/Tests/RunCMake/ctest_memcheck/testUndefinedBehaviorSanitizer.cmake
new file mode 100644
index 000000000..8ef3c0aa6
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/testUndefinedBehaviorSanitizer.cmake
@@ -0,0 +1,21 @@
+# this file simulates a program that has been built with undefined behavior
+# sanitizer options
+
+message("UBSAN_OPTIONS = [$ENV{UBSAN_OPTIONS}]")
+string(REGEX REPLACE ".*log_path=\"([^\"]*)\".*" "\\1" LOG_FILE "$ENV{UBSAN_OPTIONS}")
+message("LOG_FILE=[${LOG_FILE}]")
+
+# if we are not asked to simulate address sanitizer don't do it
+if(NOT "$ENV{UBSAN_OPTIONS}]" MATCHES "simulate_sanitizer.1")
+ return()
+endif()
+# clear the log file
+file(REMOVE "${LOG_FILE}.2343")
+
+# create an error like undefined behavior santizer creates;
+# these names come from ubsan_diag.cc and ubsan_handlers.cc
+# in llvm
+
+file(APPEND "${LOG_FILE}.2343"
+"<unknown>: runtime error: left shift of negative value -256
+")
diff --git a/Tests/RunCMake/ctest_start/CMakeLists.txt.in b/Tests/RunCMake/ctest_start/CMakeLists.txt.in
new file mode 100644
index 000000000..913239c29
--- /dev/null
+++ b/Tests/RunCMake/ctest_start/CMakeLists.txt.in
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.1)
+project(CTestStart@CASE_NAME@ NONE)
+include(CTest)
+add_test(NAME RunCMakeVersion COMMAND "${CMAKE_COMMAND}" --version)
diff --git a/Tests/RunCMake/ctest_start/CTestConfig.cmake.in b/Tests/RunCMake/ctest_start/CTestConfig.cmake.in
new file mode 100644
index 000000000..e75d14fc2
--- /dev/null
+++ b/Tests/RunCMake/ctest_start/CTestConfig.cmake.in
@@ -0,0 +1 @@
+set(CTEST_PROJECT_NAME "CTestStart@CASE_NAME@")
diff --git a/Tests/RunCMake/ctest_start/ConfigInBuild-stdout.txt b/Tests/RunCMake/ctest_start/ConfigInBuild-stdout.txt
new file mode 100644
index 000000000..7e94b8a12
--- /dev/null
+++ b/Tests/RunCMake/ctest_start/ConfigInBuild-stdout.txt
@@ -0,0 +1,7 @@
+Run dashboard with model Experimental
+ Source directory: .*/Tests/RunCMake/ctest_start/ConfigInBuild
+ Build directory: .*/Tests/RunCMake/ctest_start/ConfigInBuild-build
+ Reading ctest configuration file: .*/Tests/RunCMake/ctest_start/ConfigInBuild-build/CTestConfig.cmake
+ Site: test-site
+ Build name: test-build-name
+ Use Experimental tag: [0-9-]+
diff --git a/Tests/RunCMake/ctest_start/ConfigInSource-stdout.txt b/Tests/RunCMake/ctest_start/ConfigInSource-stdout.txt
new file mode 100644
index 000000000..c3903726a
--- /dev/null
+++ b/Tests/RunCMake/ctest_start/ConfigInSource-stdout.txt
@@ -0,0 +1,7 @@
+Run dashboard with model Experimental
+ Source directory: .*/Tests/RunCMake/ctest_start/ConfigInSource
+ Build directory: .*/Tests/RunCMake/ctest_start/ConfigInSource-build
+ Reading ctest configuration file: .*/Tests/RunCMake/ctest_start/ConfigInSource/CTestConfig.cmake
+ Site: test-site
+ Build name: test-build-name
+ Use Experimental tag: [0-9-]+
diff --git a/Tests/RunCMake/ctest_start/RunCMakeTest.cmake b/Tests/RunCMake/ctest_start/RunCMakeTest.cmake
new file mode 100644
index 000000000..d630a7904
--- /dev/null
+++ b/Tests/RunCMake/ctest_start/RunCMakeTest.cmake
@@ -0,0 +1,23 @@
+include(RunCTest)
+
+set(CASE_CTEST_START_ARGS "")
+
+function(run_ctest_start CASE_NAME)
+ set(CASE_CTEST_START_ARGS "${ARGN}")
+ run_ctest(${CASE_NAME})
+endfunction()
+
+run_ctest_start(StartQuiet Experimental QUIET)
+
+run_ctest_start(ConfigInSource Experimental)
+
+function(run_ConfigInBuild)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ConfigInBuild-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ configure_file(${RunCMake_SOURCE_DIR}/CTestConfig.cmake.in
+ ${RunCMake_BINARY_DIR}/ConfigInBuild-build/CTestConfig.cmake @ONLY)
+ run_ctest_start(ConfigInBuild Experimental)
+endfunction()
+run_ConfigInBuild()
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared-stderr.txt b/Tests/RunCMake/ctest_start/StartQuiet-stdout.txt
index 10f32932e..10f32932e 100644
--- a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared-stderr.txt
+++ b/Tests/RunCMake/ctest_start/StartQuiet-stdout.txt
diff --git a/Tests/RunCMake/ctest_start/test.cmake.in b/Tests/RunCMake/ctest_start/test.cmake.in
new file mode 100644
index 000000000..21e3fad2d
--- /dev/null
+++ b/Tests/RunCMake/ctest_start/test.cmake.in
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 3.1)
+
+set(CTEST_SITE "test-site")
+set(CTEST_BUILD_NAME "test-build-name")
+set(CTEST_SOURCE_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@")
+set(CTEST_BINARY_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@-build")
+set(CTEST_CMAKE_GENERATOR "@RunCMake_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@RunCMake_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@RunCMake_GENERATOR_TOOLSET@")
+set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
+
+set(ctest_start_args "@CASE_CTEST_START_ARGS@")
+ctest_start(${ctest_start_args})
diff --git a/Tests/RunCMake/ctest_submit/BadArg-result.txt b/Tests/RunCMake/ctest_submit/BadArg-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/BadArg-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_submit/BadArg-stderr.txt b/Tests/RunCMake/ctest_submit/BadArg-stderr.txt
new file mode 100644
index 000000000..7eeef0a2d
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/BadArg-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error at .*/Tests/RunCMake/ctest_submit/BadArg/test.cmake:[0-9]+ \(ctest_submit\):
+ ctest_submit called with unknown argument "bad-arg".
diff --git a/Tests/RunCMake/ctest_submit/BadFILES-result.txt b/Tests/RunCMake/ctest_submit/BadFILES-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/BadFILES-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_submit/BadFILES-stderr.txt b/Tests/RunCMake/ctest_submit/BadFILES-stderr.txt
new file mode 100644
index 000000000..ab84ab932
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/BadFILES-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error at .*/Tests/RunCMake/ctest_submit/BadFILES/test.cmake:[0-9]+ \(ctest_submit\):
+ File "bad-file" does not exist. Cannot submit a non-existent file.
diff --git a/Tests/RunCMake/ctest_submit/BadPARTS-result.txt b/Tests/RunCMake/ctest_submit/BadPARTS-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/BadPARTS-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_submit/BadPARTS-stderr.txt b/Tests/RunCMake/ctest_submit/BadPARTS-stderr.txt
new file mode 100644
index 000000000..3db54f3ed
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/BadPARTS-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error at .*/Tests/RunCMake/ctest_submit/BadPARTS/test.cmake:[0-9]+ \(ctest_submit\):
+ Part name "bad-part" is invalid.
diff --git a/Tests/RunCMake/ctest_submit/CDashSubmitQuiet-result.txt b/Tests/RunCMake/ctest_submit/CDashSubmitQuiet-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/CDashSubmitQuiet-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_submit/CDashSubmitQuiet-stderr.txt b/Tests/RunCMake/ctest_submit/CDashSubmitQuiet-stderr.txt
new file mode 100644
index 000000000..4825d7a8e
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/CDashSubmitQuiet-stderr.txt
@@ -0,0 +1,3 @@
+ *Error when uploading file: .*/Configure.xml
+ *Error message was: ([Cc]ould *n.t resolve host:? '?-no-site-'?.*|The requested URL returned error:.*)
+ *Problems when submitting via HTTP
diff --git a/Tests/RunCMake/ctest_submit/CDashSubmitQuiet-stdout.txt b/Tests/RunCMake/ctest_submit/CDashSubmitQuiet-stdout.txt
new file mode 100644
index 000000000..cd42c9a6d
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/CDashSubmitQuiet-stdout.txt
@@ -0,0 +1,3 @@
+Configure project
+ Each . represents 1024 bytes of output
+ . Size of output: 0K$
diff --git a/Tests/RunCMake/ctest_submit/CDashUploadFILES-result.txt b/Tests/RunCMake/ctest_submit/CDashUploadFILES-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/CDashUploadFILES-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_submit/CDashUploadFILES-stderr.txt b/Tests/RunCMake/ctest_submit/CDashUploadFILES-stderr.txt
new file mode 100644
index 000000000..0106fee30
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/CDashUploadFILES-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error at .*/Tests/RunCMake/ctest_submit/CDashUploadFILES/test.cmake:[0-9]+ \(ctest_submit\):
+ ctest_submit called with unknown argument "FILES".
diff --git a/Tests/RunCMake/ctest_submit/CDashUploadFTP-result.txt b/Tests/RunCMake/ctest_submit/CDashUploadFTP-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/CDashUploadFTP-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_submit/CDashUploadFTP-stderr.txt b/Tests/RunCMake/ctest_submit/CDashUploadFTP-stderr.txt
new file mode 100644
index 000000000..77df44fec
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/CDashUploadFTP-stderr.txt
@@ -0,0 +1 @@
+Only http and https are supported for CDASH_UPLOAD
diff --git a/Tests/RunCMake/ctest_submit/CDashUploadNone-result.txt b/Tests/RunCMake/ctest_submit/CDashUploadNone-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/CDashUploadNone-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_submit/CDashUploadNone-stderr.txt b/Tests/RunCMake/ctest_submit/CDashUploadNone-stderr.txt
new file mode 100644
index 000000000..af95b5cf5
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/CDashUploadNone-stderr.txt
@@ -0,0 +1 @@
+Upload file not specified
diff --git a/Tests/RunCMake/ctest_submit/CDashUploadPARTS-result.txt b/Tests/RunCMake/ctest_submit/CDashUploadPARTS-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/CDashUploadPARTS-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_submit/CDashUploadPARTS-stderr.txt b/Tests/RunCMake/ctest_submit/CDashUploadPARTS-stderr.txt
new file mode 100644
index 000000000..fe94cb717
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/CDashUploadPARTS-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error at .*/Tests/RunCMake/ctest_submit/CDashUploadPARTS/test.cmake:[0-9]+ \(ctest_submit\):
+ ctest_submit called with unknown argument "PARTS".
diff --git a/Tests/RunCMake/ctest_submit/CDashUploadRETRY_COUNT-result.txt b/Tests/RunCMake/ctest_submit/CDashUploadRETRY_COUNT-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/CDashUploadRETRY_COUNT-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_submit/CDashUploadRETRY_COUNT-stderr.txt b/Tests/RunCMake/ctest_submit/CDashUploadRETRY_COUNT-stderr.txt
new file mode 100644
index 000000000..21621d440
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/CDashUploadRETRY_COUNT-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error at .*/Tests/RunCMake/ctest_submit/CDashUploadRETRY_COUNT/test.cmake:[0-9]+ \(ctest_submit\):
+ ctest_submit called with unknown argument "RETRY_COUNT".
diff --git a/Tests/RunCMake/ctest_submit/CDashUploadRETRY_DELAY-result.txt b/Tests/RunCMake/ctest_submit/CDashUploadRETRY_DELAY-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/CDashUploadRETRY_DELAY-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_submit/CDashUploadRETRY_DELAY-stderr.txt b/Tests/RunCMake/ctest_submit/CDashUploadRETRY_DELAY-stderr.txt
new file mode 100644
index 000000000..f726674d9
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/CDashUploadRETRY_DELAY-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error at .*/Tests/RunCMake/ctest_submit/CDashUploadRETRY_DELAY/test.cmake:[0-9]+ \(ctest_submit\):
+ ctest_submit called with unknown argument "RETRY_DELAY".
diff --git a/Tests/RunCMake/ctest_submit/CMakeLists.txt.in b/Tests/RunCMake/ctest_submit/CMakeLists.txt.in
new file mode 100644
index 000000000..96e6c1313
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/CMakeLists.txt.in
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.1)
+project(CTestSubmit@CASE_NAME@ NONE)
+include(CTest)
+add_test(NAME RunCMakeVersion COMMAND "${CMAKE_COMMAND}" --version)
diff --git a/Tests/RunCMake/ctest_submit/CTestConfig.cmake.in b/Tests/RunCMake/ctest_submit/CTestConfig.cmake.in
new file mode 100644
index 000000000..378a85a0c
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/CTestConfig.cmake.in
@@ -0,0 +1,6 @@
+set(CTEST_PROJECT_NAME "CTestSubmit@CASE_NAME@")
+
+# Intentionally leave out other upload-related CTestConfig.cmake settings
+# so that any ctest_submit calls fail with an error message.
+set(CTEST_DROP_METHOD "@CASE_DROP_METHOD@")
+set(CTEST_DROP_SITE "@CASE_DROP_SITE@")
diff --git a/Tests/RunCMake/ctest_submit/FailDrop-cp-result.txt b/Tests/RunCMake/ctest_submit/FailDrop-cp-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/FailDrop-cp-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_submit/FailDrop-cp-stderr.txt b/Tests/RunCMake/ctest_submit/FailDrop-cp-stderr.txt
new file mode 100644
index 000000000..00a60ac91
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/FailDrop-cp-stderr.txt
@@ -0,0 +1,3 @@
+Missing arguments for submit via cp:
+.*
+ Problems when submitting via CP
diff --git a/Tests/RunCMake/ctest_submit/FailDrop-cp-stdout.txt b/Tests/RunCMake/ctest_submit/FailDrop-cp-stdout.txt
new file mode 100644
index 000000000..fa6e0042c
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/FailDrop-cp-stdout.txt
@@ -0,0 +1 @@
+Submit files \(using cp\)
diff --git a/Tests/RunCMake/ctest_submit/FailDrop-ftp-result.txt b/Tests/RunCMake/ctest_submit/FailDrop-ftp-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/FailDrop-ftp-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_submit/FailDrop-ftp-stderr.txt b/Tests/RunCMake/ctest_submit/FailDrop-ftp-stderr.txt
new file mode 100644
index 000000000..b9d9394fb
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/FailDrop-ftp-stderr.txt
@@ -0,0 +1,2 @@
+Error message was: ([Cc]ould *n.t resolve host:? '?-no-site-'?.*|The requested URL returned error:.*)
+ Problems when submitting via FTP
diff --git a/Tests/RunCMake/ctest_submit/FailDrop-ftp-stdout.txt b/Tests/RunCMake/ctest_submit/FailDrop-ftp-stdout.txt
new file mode 100644
index 000000000..345bb62b1
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/FailDrop-ftp-stdout.txt
@@ -0,0 +1,3 @@
+Submit files \(using ftp\)
+ Using FTP submit method
+ Drop site: ftp://
diff --git a/Tests/RunCMake/ctest_submit/FailDrop-http-result.txt b/Tests/RunCMake/ctest_submit/FailDrop-http-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/FailDrop-http-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_submit/FailDrop-http-stderr.txt b/Tests/RunCMake/ctest_submit/FailDrop-http-stderr.txt
new file mode 100644
index 000000000..f52d2d844
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/FailDrop-http-stderr.txt
@@ -0,0 +1,2 @@
+Error message was: ([Cc]ould *n.t resolve host:? '?-no-site-'?.*|The requested URL returned error:.*)
+ Problems when submitting via HTTP
diff --git a/Tests/RunCMake/ctest_submit/FailDrop-http-stdout.txt b/Tests/RunCMake/ctest_submit/FailDrop-http-stdout.txt
new file mode 100644
index 000000000..c7f35c5ff
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/FailDrop-http-stdout.txt
@@ -0,0 +1,3 @@
+Submit files \(using http\)
+ Using HTTP submit method
+ Drop site:http://
diff --git a/Tests/RunCMake/ctest_submit/FailDrop-https-result.txt b/Tests/RunCMake/ctest_submit/FailDrop-https-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/FailDrop-https-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_submit/FailDrop-https-stderr.txt b/Tests/RunCMake/ctest_submit/FailDrop-https-stderr.txt
new file mode 100644
index 000000000..24083f2bc
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/FailDrop-https-stderr.txt
@@ -0,0 +1,2 @@
+Error message was: ([Cc]ould *n.t resolve host:? '?-no-site-'?.*|The requested URL returned error:.*|Protocol "https" not supported or disabled in .*|.* was built with SSL disabled.*)
+ Problems when submitting via HTTP
diff --git a/Tests/RunCMake/ctest_submit/FailDrop-https-stdout.txt b/Tests/RunCMake/ctest_submit/FailDrop-https-stdout.txt
new file mode 100644
index 000000000..19f82347b
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/FailDrop-https-stdout.txt
@@ -0,0 +1,3 @@
+Submit files \(using https\)
+ Using HTTP submit method
+ Drop site:https://
diff --git a/Tests/RunCMake/ctest_submit/FailDrop-scp-result.txt b/Tests/RunCMake/ctest_submit/FailDrop-scp-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/FailDrop-scp-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_submit/FailDrop-scp-stderr.txt b/Tests/RunCMake/ctest_submit/FailDrop-scp-stderr.txt
new file mode 100644
index 000000000..ef671499e
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/FailDrop-scp-stderr.txt
@@ -0,0 +1 @@
+ Problems when submitting via SCP
diff --git a/Tests/RunCMake/ctest_submit/FailDrop-scp-stdout.txt b/Tests/RunCMake/ctest_submit/FailDrop-scp-stdout.txt
new file mode 100644
index 000000000..ec2ce92be
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/FailDrop-scp-stdout.txt
@@ -0,0 +1 @@
+Submit files \(using scp\)
diff --git a/Tests/RunCMake/ctest_submit/FailDrop-xmlrpc-result.txt b/Tests/RunCMake/ctest_submit/FailDrop-xmlrpc-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/FailDrop-xmlrpc-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_submit/FailDrop-xmlrpc-stderr.txt b/Tests/RunCMake/ctest_submit/FailDrop-xmlrpc-stderr.txt
new file mode 100644
index 000000000..c0f718e76
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/FailDrop-xmlrpc-stderr.txt
@@ -0,0 +1 @@
+ (Problems when submitting via XML-RPC|Submission method "xmlrpc" not compiled into CTest!)
diff --git a/Tests/RunCMake/ctest_submit/FailDrop-xmlrpc-stdout.txt b/Tests/RunCMake/ctest_submit/FailDrop-xmlrpc-stdout.txt
new file mode 100644
index 000000000..ed2acb53c
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/FailDrop-xmlrpc-stdout.txt
@@ -0,0 +1 @@
+Submit files \(using xmlrpc\)
diff --git a/Tests/RunCMake/ctest_submit/PARTSCDashUpload-result.txt b/Tests/RunCMake/ctest_submit/PARTSCDashUpload-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/PARTSCDashUpload-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_submit/PARTSCDashUpload-stderr.txt b/Tests/RunCMake/ctest_submit/PARTSCDashUpload-stderr.txt
new file mode 100644
index 000000000..ad4c8cbf0
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/PARTSCDashUpload-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error at .*/Tests/RunCMake/ctest_submit/PARTSCDashUpload/test.cmake:[0-9]+ \(ctest_submit\):
+ Part name "CDASH_UPLOAD" is invalid.
diff --git a/Tests/RunCMake/ctest_submit/PARTSCDashUploadType-result.txt b/Tests/RunCMake/ctest_submit/PARTSCDashUploadType-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/PARTSCDashUploadType-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_submit/PARTSCDashUploadType-stderr.txt b/Tests/RunCMake/ctest_submit/PARTSCDashUploadType-stderr.txt
new file mode 100644
index 000000000..8d8a8520f
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/PARTSCDashUploadType-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error at .*/Tests/RunCMake/ctest_submit/PARTSCDashUploadType/test.cmake:[0-9]+ \(ctest_submit\):
+ Part name "CDASH_UPLOAD_TYPE" is invalid.
diff --git a/Tests/RunCMake/ctest_submit/RepeatRETURN_VALUE-result.txt b/Tests/RunCMake/ctest_submit/RepeatRETURN_VALUE-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/RepeatRETURN_VALUE-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_submit/RepeatRETURN_VALUE-stderr.txt b/Tests/RunCMake/ctest_submit/RepeatRETURN_VALUE-stderr.txt
new file mode 100644
index 000000000..6e17c759e
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/RepeatRETURN_VALUE-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error at .*/Tests/RunCMake/ctest_submit/RepeatRETURN_VALUE/test.cmake:[0-9]+ \(ctest_submit\):
+ Called with more than one value for RETURN_VALUE
diff --git a/Tests/RunCMake/ctest_submit/RunCMakeTest.cmake b/Tests/RunCMake/ctest_submit/RunCMakeTest.cmake
new file mode 100644
index 000000000..a81bc96a0
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/RunCMakeTest.cmake
@@ -0,0 +1,47 @@
+include(RunCTest)
+
+# Default case parameters.
+set(CASE_DROP_METHOD "http")
+set(CASE_DROP_SITE "-no-site-")
+set(CASE_CTEST_SUBMIT_ARGS "")
+
+#-----------------------------------------------------------------------------
+# Test bad argument combinations.
+
+function(run_ctest_submit CASE_NAME)
+ set(CASE_CTEST_SUBMIT_ARGS "${ARGN}")
+ run_ctest(${CASE_NAME})
+endfunction()
+
+run_ctest_submit(BadArg bad-arg)
+run_ctest_submit(BadPARTS PARTS bad-part)
+run_ctest_submit(BadFILES FILES bad-file)
+run_ctest_submit(RepeatRETURN_VALUE RETURN_VALUE res RETURN_VALUE res)
+run_ctest_submit(PARTSCDashUpload PARTS Configure CDASH_UPLOAD)
+run_ctest_submit(PARTSCDashUploadType PARTS Configure CDASH_UPLOAD_TYPE)
+run_ctest_submit(CDashUploadPARTS CDASH_UPLOAD bad-upload PARTS)
+run_ctest_submit(CDashUploadFILES CDASH_UPLOAD bad-upload FILES)
+run_ctest_submit(CDashUploadRETRY_COUNT CDASH_UPLOAD bad-upload RETRY_COUNT)
+run_ctest_submit(CDashUploadRETRY_DELAY CDASH_UPLOAD bad-upload RETRY_DELAY)
+run_ctest_submit(CDashUploadNone CDASH_UPLOAD)
+run_ctest_submit(CDashSubmitQuiet QUIET)
+
+function(run_ctest_CDashUploadFTP)
+ set(CASE_DROP_METHOD ftp)
+ run_ctest_submit(CDashUploadFTP CDASH_UPLOAD ${CMAKE_CURRENT_LIST_FILE})
+endfunction()
+run_ctest_CDashUploadFTP()
+
+#-----------------------------------------------------------------------------
+# Test failed drops by various protocols
+
+function(run_ctest_submit_FailDrop CASE_DROP_METHOD)
+ run_ctest(FailDrop-${CASE_DROP_METHOD})
+endfunction()
+
+run_ctest_submit_FailDrop(cp)
+run_ctest_submit_FailDrop(ftp)
+run_ctest_submit_FailDrop(http)
+run_ctest_submit_FailDrop(https)
+run_ctest_submit_FailDrop(scp)
+run_ctest_submit_FailDrop(xmlrpc)
diff --git a/Tests/RunCMake/ctest_submit/test.cmake.in b/Tests/RunCMake/ctest_submit/test.cmake.in
new file mode 100644
index 000000000..ba826f1b3
--- /dev/null
+++ b/Tests/RunCMake/ctest_submit/test.cmake.in
@@ -0,0 +1,16 @@
+cmake_minimum_required(VERSION 3.1)
+
+set(CTEST_SITE "test-site")
+set(CTEST_BUILD_NAME "test-build-name")
+set(CTEST_SOURCE_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@")
+set(CTEST_BINARY_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@-build")
+set(CTEST_CMAKE_GENERATOR "@RunCMake_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@RunCMake_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@RunCMake_GENERATOR_TOOLSET@")
+set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
+
+ctest_start(Experimental)
+ctest_configure()
+
+set(ctest_submit_args "@CASE_CTEST_SUBMIT_ARGS@")
+ctest_submit(${ctest_submit_args})
diff --git a/Tests/RunCMake/ctest_test/CMakeLists.txt.in b/Tests/RunCMake/ctest_test/CMakeLists.txt.in
new file mode 100644
index 000000000..e61b55668
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/CMakeLists.txt.in
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.1)
+project(CTestTest@CASE_NAME@ NONE)
+include(CTest)
+add_test(NAME RunCMakeVersion COMMAND "${CMAKE_COMMAND}" --version)
+@CASE_CMAKELISTS_SUFFIX_CODE@
diff --git a/Tests/RunCMake/ctest_test/CTestConfig.cmake.in b/Tests/RunCMake/ctest_test/CTestConfig.cmake.in
new file mode 100644
index 000000000..90044198e
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/CTestConfig.cmake.in
@@ -0,0 +1 @@
+set(CTEST_PROJECT_NAME "CTestTest@CASE_NAME@")
diff --git a/Tests/RunCMake/ctest_test/CTestTestLoadFail-result.txt b/Tests/RunCMake/ctest_test/CTestTestLoadFail-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/CTestTestLoadFail-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_test/CTestTestLoadFail-stderr.txt b/Tests/RunCMake/ctest_test/CTestTestLoadFail-stderr.txt
new file mode 100644
index 000000000..eafba1c69
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/CTestTestLoadFail-stderr.txt
@@ -0,0 +1 @@
+No tests were found!!!
diff --git a/Tests/RunCMake/ctest_test/CTestTestLoadFail-stdout.txt b/Tests/RunCMake/ctest_test/CTestTestLoadFail-stdout.txt
new file mode 100644
index 000000000..e203c10c1
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/CTestTestLoadFail-stdout.txt
@@ -0,0 +1,2 @@
+Test project .*/Tests/RunCMake/ctest_test/CTestTestLoadFail-build
+\*\*\*\*\* WAITING, System Load: 5, Max Allowed Load: 4, Smallest test RunCMakeVersion requires 1\*\*\*\*\*$
diff --git a/Tests/RunCMake/ctest_test/CTestTestLoadInvalid-stderr.txt b/Tests/RunCMake/ctest_test/CTestTestLoadInvalid-stderr.txt
new file mode 100644
index 000000000..7f2d7f6df
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/CTestTestLoadInvalid-stderr.txt
@@ -0,0 +1 @@
+^Invalid value for 'CTEST_TEST_LOAD' : ERR2
diff --git a/Tests/RunCMake/ctest_test/CTestTestLoadInvalid-stdout.txt b/Tests/RunCMake/ctest_test/CTestTestLoadInvalid-stdout.txt
new file mode 100644
index 000000000..b54220cff
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/CTestTestLoadInvalid-stdout.txt
@@ -0,0 +1,7 @@
+Test project .*/Tests/RunCMake/ctest_test/CTestTestLoadInvalid-build
+ Start 1: RunCMakeVersion
+1/1 Test #1: RunCMakeVersion .................. Passed +[0-9.]+ sec
++
+100% tests passed, 0 tests failed out of 1
++
+Total Test time \(real\) = +[0-9.]+ sec$
diff --git a/Tests/RunCMake/ctest_test/CTestTestLoadPass-stdout.txt b/Tests/RunCMake/ctest_test/CTestTestLoadPass-stdout.txt
new file mode 100644
index 000000000..c221eed72
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/CTestTestLoadPass-stdout.txt
@@ -0,0 +1,7 @@
+Test project .*/Tests/RunCMake/ctest_test/CTestTestLoadPass-build
+ Start 1: RunCMakeVersion
+1/1 Test #1: RunCMakeVersion .................. Passed +[0-9.]+ sec
++
+100% tests passed, 0 tests failed out of 1
++
+Total Test time \(real\) = +[0-9.]+ sec$
diff --git a/Tests/RunCMake/ctest_test/RunCMakeTest.cmake b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake
new file mode 100644
index 000000000..1b3172676
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake
@@ -0,0 +1,77 @@
+include(RunCTest)
+set(RunCMake_TEST_TIMEOUT 60)
+
+set(CASE_CTEST_TEST_ARGS "")
+set(CASE_CTEST_TEST_LOAD "")
+
+function(run_ctest_test CASE_NAME)
+ set(CASE_CTEST_TEST_ARGS "${ARGN}")
+ run_ctest(${CASE_NAME})
+endfunction()
+
+run_ctest_test(TestQuiet QUIET)
+
+# Tests for the 'Test Load' feature of ctest
+#
+# Spoof a load average value to make these tests more reliable.
+set(ENV{__CTEST_FAKE_LOAD_AVERAGE_FOR_TESTING} 5)
+
+# Verify that new tests are started when the load average falls below
+# our threshold.
+run_ctest_test(TestLoadPass TEST_LOAD 6)
+
+# Verify that new tests are not started when the load average exceeds
+# our threshold.
+run_ctest_test(TestLoadFail TEST_LOAD 2)
+
+# Verify that when an invalid "TEST_LOAD" value is given, a warning
+# message is displayed and the value is ignored.
+run_ctest_test(TestLoadInvalid TEST_LOAD "ERR1")
+
+# Verify that new tests are started when the load average falls below
+# our threshold.
+set(CASE_CTEST_TEST_LOAD 7)
+run_ctest_test(CTestTestLoadPass)
+
+# Verify that new tests are not started when the load average exceeds
+# our threshold.
+set(CASE_CTEST_TEST_LOAD 4)
+run_ctest_test(CTestTestLoadFail)
+
+# Verify that when an invalid "CTEST_TEST_LOAD" value is given,
+# a warning message is displayed and the value is ignored.
+set(CASE_CTEST_TEST_LOAD "ERR2")
+run_ctest_test(CTestTestLoadInvalid)
+
+# Verify that the "TEST_LOAD" value has higher precedence than
+# the "CTEST_TEST_LOAD" value
+set(CASE_CTEST_TEST_LOAD "ERR3")
+run_ctest_test(TestLoadOrder TEST_LOAD "ERR4")
+
+unset(ENV{__CTEST_FAKE_LOAD_AVERAGE_FOR_TESTING})
+unset(CASE_CTEST_TEST_LOAD)
+
+function(run_TestChangeId)
+ set(CASE_TEST_PREFIX_CODE [[
+ set(CTEST_CHANGE_ID "<>1")
+ ]])
+
+ run_ctest(TestChangeId)
+endfunction()
+run_TestChangeId()
+
+function(run_TestOutputSize)
+ set(CASE_CTEST_TEST_ARGS EXCLUDE RunCMakeVersion)
+ set(CASE_TEST_PREFIX_CODE [[
+set(CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE 10)
+set(CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE 12)
+ ]])
+ set(CASE_CMAKELISTS_SUFFIX_CODE [[
+add_test(NAME PassingTest COMMAND ${CMAKE_COMMAND} -E echo PassingTestOutput)
+add_test(NAME FailingTest COMMAND ${CMAKE_COMMAND} -E no_such_command)
+ ]])
+
+ unset(ENV{CTEST_PARALLEL_LEVEL})
+ run_ctest(TestOutputSize)
+endfunction()
+run_TestOutputSize()
diff --git a/Tests/RunCMake/ctest_test/TestChangeId-check.cmake b/Tests/RunCMake/ctest_test/TestChangeId-check.cmake
new file mode 100644
index 000000000..b9884f1ec
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/TestChangeId-check.cmake
@@ -0,0 +1,12 @@
+file(GLOB test_xml_file "${RunCMake_TEST_BINARY_DIR}/Testing/*/Test.xml")
+if(test_xml_file)
+ file(READ "${test_xml_file}" test_xml LIMIT 4096)
+ if(NOT test_xml MATCHES [[ChangeId="&lt;&gt;1"]])
+ string(REPLACE "\n" "\n " test_xml " ${test_xml}")
+ set(RunCMake_TEST_FAILED
+ "Test.xml does not have expected ChangeId:\n${test_xml}"
+ )
+ endif()
+else()
+ set(RunCMake_TEST_FAILED "Test.xml not found")
+endif()
diff --git a/Tests/RunCMake/ctest_test/TestLoadFail-result.txt b/Tests/RunCMake/ctest_test/TestLoadFail-result.txt
new file mode 100644
index 000000000..b57e2deb7
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/TestLoadFail-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_test/TestLoadFail-stderr.txt b/Tests/RunCMake/ctest_test/TestLoadFail-stderr.txt
new file mode 100644
index 000000000..eafba1c69
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/TestLoadFail-stderr.txt
@@ -0,0 +1 @@
+No tests were found!!!
diff --git a/Tests/RunCMake/ctest_test/TestLoadFail-stdout.txt b/Tests/RunCMake/ctest_test/TestLoadFail-stdout.txt
new file mode 100644
index 000000000..4d7ce48a4
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/TestLoadFail-stdout.txt
@@ -0,0 +1,2 @@
+Test project .*/Tests/RunCMake/ctest_test/TestLoadFail-build
+\*\*\*\*\* WAITING, System Load: 5, Max Allowed Load: 2, Smallest test RunCMakeVersion requires 1\*\*\*\*\*$
diff --git a/Tests/RunCMake/ctest_test/TestLoadInvalid-stderr.txt b/Tests/RunCMake/ctest_test/TestLoadInvalid-stderr.txt
new file mode 100644
index 000000000..40ddb3aec
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/TestLoadInvalid-stderr.txt
@@ -0,0 +1 @@
+^Invalid value for 'TEST_LOAD' : ERR1
diff --git a/Tests/RunCMake/ctest_test/TestLoadInvalid-stdout.txt b/Tests/RunCMake/ctest_test/TestLoadInvalid-stdout.txt
new file mode 100644
index 000000000..c4fd35b4a
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/TestLoadInvalid-stdout.txt
@@ -0,0 +1,7 @@
+Test project .*/Tests/RunCMake/ctest_test/TestLoadInvalid-build
+ Start 1: RunCMakeVersion
+1/1 Test #1: RunCMakeVersion .................. Passed +[0-9.]+ sec
++
+100% tests passed, 0 tests failed out of 1
++
+Total Test time \(real\) = +[0-9.]+ sec$
diff --git a/Tests/RunCMake/ctest_test/TestLoadOrder-stderr.txt b/Tests/RunCMake/ctest_test/TestLoadOrder-stderr.txt
new file mode 100644
index 000000000..1de730e75
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/TestLoadOrder-stderr.txt
@@ -0,0 +1 @@
+^Invalid value for 'TEST_LOAD' : ERR4
diff --git a/Tests/RunCMake/ctest_test/TestLoadOrder-stdout.txt b/Tests/RunCMake/ctest_test/TestLoadOrder-stdout.txt
new file mode 100644
index 000000000..22da09211
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/TestLoadOrder-stdout.txt
@@ -0,0 +1,7 @@
+Test project .*/Tests/RunCMake/ctest_test/TestLoadOrder-build
+ Start 1: RunCMakeVersion
+1/1 Test #1: RunCMakeVersion .................. Passed +[0-9.]+ sec
++
+100% tests passed, 0 tests failed out of 1
++
+Total Test time \(real\) = +[0-9.]+ sec$
diff --git a/Tests/RunCMake/ctest_test/TestLoadPass-stdout.txt b/Tests/RunCMake/ctest_test/TestLoadPass-stdout.txt
new file mode 100644
index 000000000..e5048f4b4
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/TestLoadPass-stdout.txt
@@ -0,0 +1,7 @@
+Test project .*/Tests/RunCMake/ctest_test/TestLoadPass-build
+ Start 1: RunCMakeVersion
+1/1 Test #1: RunCMakeVersion .................. Passed +[0-9.]+ sec
++
+100% tests passed, 0 tests failed out of 1
++
+Total Test time \(real\) = +[0-9.]+ sec$
diff --git a/Tests/RunCMake/ctest_test/TestOutputSize-check.cmake b/Tests/RunCMake/ctest_test/TestOutputSize-check.cmake
new file mode 100644
index 000000000..74ad6695b
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/TestOutputSize-check.cmake
@@ -0,0 +1,17 @@
+file(GLOB test_xml_file "${RunCMake_TEST_BINARY_DIR}/Testing/*/Test.xml")
+if(test_xml_file)
+ file(READ "${test_xml_file}" test_xml LIMIT 4096)
+ if("${test_xml}" MATCHES [[(<Test Status="passed">.*</Test>).*(<Test Status="failed">.*</Test>)]])
+ set(test_passed "${CMAKE_MATCH_1}")
+ set(test_failed "${CMAKE_MATCH_2}")
+ if(NOT "${test_passed}" MATCHES [[<Value>PassingTes\.\.\..*10 bytes]])
+ set(RunCMake_TEST_FAILED "Test.xml passed test output not truncated at 10 bytes:\n ${test_passed}")
+ elseif(NOT "${test_failed}" MATCHES [[<Value>CMake Error:\.\.\..*12 bytes]])
+ set(RunCMake_TEST_FAILED "Test.xml failed test output not truncated at 12 bytes:\n ${test_failed}")
+ endif()
+ else()
+ set(RunCMake_TEST_FAILED "Test.xml does not contain a passed then failed test:\n ${test_xml}")
+ endif()
+else()
+ set(RunCMake_TEST_FAILED "Test.xml not found")
+endif()
diff --git a/Tests/RunCMake/ctest_test/TestQuiet-stdout.txt b/Tests/RunCMake/ctest_test/TestQuiet-stdout.txt
new file mode 100644
index 000000000..14613c565
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/TestQuiet-stdout.txt
@@ -0,0 +1,2 @@
+ 0 Compiler warnings
+ Start 1: RunCMakeVersion
diff --git a/Tests/RunCMake/ctest_test/test.cmake.in b/Tests/RunCMake/ctest_test/test.cmake.in
new file mode 100644
index 000000000..50b936d31
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/test.cmake.in
@@ -0,0 +1,18 @@
+cmake_minimum_required(VERSION 3.1)
+@CASE_TEST_PREFIX_CODE@
+
+set(CTEST_SITE "test-site")
+set(CTEST_BUILD_NAME "test-build-name")
+set(CTEST_SOURCE_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@")
+set(CTEST_BINARY_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@-build")
+set(CTEST_CMAKE_GENERATOR "@RunCMake_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@RunCMake_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@RunCMake_GENERATOR_TOOLSET@")
+set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
+set(CTEST_TEST_LOAD "@CASE_CTEST_TEST_LOAD@")
+
+set(ctest_test_args "@CASE_CTEST_TEST_ARGS@")
+ctest_start(Experimental)
+ctest_configure()
+ctest_build()
+ctest_test(${ctest_test_args})
diff --git a/Tests/RunCMake/ctest_upload/CMakeLists.txt.in b/Tests/RunCMake/ctest_upload/CMakeLists.txt.in
new file mode 100644
index 000000000..1fab71be5
--- /dev/null
+++ b/Tests/RunCMake/ctest_upload/CMakeLists.txt.in
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.1)
+project(CTestUpload@CASE_NAME@ NONE)
+include(CTest)
+add_test(NAME RunCMakeVersion COMMAND "${CMAKE_COMMAND}" --version)
diff --git a/Tests/RunCMake/ctest_upload/CTestConfig.cmake.in b/Tests/RunCMake/ctest_upload/CTestConfig.cmake.in
new file mode 100644
index 000000000..52665a8b8
--- /dev/null
+++ b/Tests/RunCMake/ctest_upload/CTestConfig.cmake.in
@@ -0,0 +1 @@
+set(CTEST_PROJECT_NAME "CTestUpload@CASE_NAME@")
diff --git a/Tests/RunCMake/ctest_upload/RunCMakeTest.cmake b/Tests/RunCMake/ctest_upload/RunCMakeTest.cmake
new file mode 100644
index 000000000..b33d2781e
--- /dev/null
+++ b/Tests/RunCMake/ctest_upload/RunCMakeTest.cmake
@@ -0,0 +1,10 @@
+include(RunCTest)
+
+set(CASE_CTEST_UPLOAD_ARGS "")
+
+function(run_ctest_upload CASE_NAME)
+ set(CASE_CTEST_UPLOAD_ARGS "${ARGN}")
+ run_ctest(${CASE_NAME})
+endfunction()
+
+run_ctest_upload(UploadQuiet QUIET)
diff --git a/Tests/RunCMake/ctest_upload/UploadQuiet-stdout.txt b/Tests/RunCMake/ctest_upload/UploadQuiet-stdout.txt
new file mode 100644
index 000000000..20e13b820
--- /dev/null
+++ b/Tests/RunCMake/ctest_upload/UploadQuiet-stdout.txt
@@ -0,0 +1 @@
+Use Experimental tag: [0-9-]+$
diff --git a/Tests/RunCMake/ctest_upload/test.cmake.in b/Tests/RunCMake/ctest_upload/test.cmake.in
new file mode 100644
index 000000000..f13bdd11d
--- /dev/null
+++ b/Tests/RunCMake/ctest_upload/test.cmake.in
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.1)
+
+set(CTEST_SITE "test-site")
+set(CTEST_BUILD_NAME "test-build-name")
+set(CTEST_SOURCE_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@")
+set(CTEST_BINARY_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@-build")
+set(CTEST_CMAKE_GENERATOR "@RunCMake_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@RunCMake_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@RunCMake_GENERATOR_TOOLSET@")
+set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
+
+set(ctest_upload_args "@CASE_CTEST_UPLOAD_ARGS@")
+ctest_start(Experimental)
+ctest_upload(FILES "${CTEST_SOURCE_DIRECTORY}/CMakeLists.txt" ${ctest_upload_args})
diff --git a/Tests/RunCMake/execute_process/MergeOutput-stdout.txt b/Tests/RunCMake/execute_process/MergeOutput-stdout.txt
new file mode 100644
index 000000000..676f0ed4b
--- /dev/null
+++ b/Tests/RunCMake/execute_process/MergeOutput-stdout.txt
@@ -0,0 +1,10 @@
+^-- Output on stdout
+Output on stderr
+-- Output on stdout
+Output on stderr
+-- Output on stdout
+Output on stderr
+-- Output on stdout
+Output on stderr
+-- Output on stdout
+Output on stderr$
diff --git a/Tests/RunCMake/execute_process/MergeOutput.cmake b/Tests/RunCMake/execute_process/MergeOutput.cmake
new file mode 100644
index 000000000..528ac9014
--- /dev/null
+++ b/Tests/RunCMake/execute_process/MergeOutput.cmake
@@ -0,0 +1,4 @@
+foreach(i RANGE 1 5)
+ message(STATUS "Output on stdout")
+ message("Output on stderr")
+endforeach()
diff --git a/Tests/RunCMake/execute_process/MergeOutputFile-stderr.txt b/Tests/RunCMake/execute_process/MergeOutputFile-stderr.txt
new file mode 100644
index 000000000..676f0ed4b
--- /dev/null
+++ b/Tests/RunCMake/execute_process/MergeOutputFile-stderr.txt
@@ -0,0 +1,10 @@
+^-- Output on stdout
+Output on stderr
+-- Output on stdout
+Output on stderr
+-- Output on stdout
+Output on stderr
+-- Output on stdout
+Output on stderr
+-- Output on stdout
+Output on stderr$
diff --git a/Tests/RunCMake/execute_process/MergeOutputFile.cmake b/Tests/RunCMake/execute_process/MergeOutputFile.cmake
new file mode 100644
index 000000000..1a0d90e16
--- /dev/null
+++ b/Tests/RunCMake/execute_process/MergeOutputFile.cmake
@@ -0,0 +1,7 @@
+execute_process(
+ COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_LIST_DIR}/MergeOutput.cmake
+ OUTPUT_FILE out.txt
+ ERROR_FILE out.txt
+ )
+file(READ out.txt out)
+message("${out}")
diff --git a/Tests/RunCMake/execute_process/MergeOutputVars-stderr.txt b/Tests/RunCMake/execute_process/MergeOutputVars-stderr.txt
new file mode 100644
index 000000000..676f0ed4b
--- /dev/null
+++ b/Tests/RunCMake/execute_process/MergeOutputVars-stderr.txt
@@ -0,0 +1,10 @@
+^-- Output on stdout
+Output on stderr
+-- Output on stdout
+Output on stderr
+-- Output on stdout
+Output on stderr
+-- Output on stdout
+Output on stderr
+-- Output on stdout
+Output on stderr$
diff --git a/Tests/RunCMake/execute_process/MergeOutputVars.cmake b/Tests/RunCMake/execute_process/MergeOutputVars.cmake
new file mode 100644
index 000000000..3e7c69e2e
--- /dev/null
+++ b/Tests/RunCMake/execute_process/MergeOutputVars.cmake
@@ -0,0 +1,6 @@
+execute_process(
+ COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_LIST_DIR}/MergeOutput.cmake
+ OUTPUT_VARIABLE out
+ ERROR_VARIABLE out
+ )
+message("${out}")
diff --git a/Tests/RunCMake/execute_process/RunCMakeTest.cmake b/Tests/RunCMake/execute_process/RunCMakeTest.cmake
new file mode 100644
index 000000000..208043710
--- /dev/null
+++ b/Tests/RunCMake/execute_process/RunCMakeTest.cmake
@@ -0,0 +1,8 @@
+include(RunCMake)
+
+set(RunCMake_TEST_OUTPUT_MERGE 1)
+run_cmake_command(MergeOutput ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/MergeOutput.cmake)
+unset(RunCMake_TEST_OUTPUT_MERGE)
+
+run_cmake_command(MergeOutputFile ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/MergeOutputFile.cmake)
+run_cmake_command(MergeOutputVars ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/MergeOutputVars.cmake)
diff --git a/Tests/RunCMake/export/AppendExport-result.txt b/Tests/RunCMake/export/AppendExport-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/export/AppendExport-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/export/AppendExport-stderr.txt b/Tests/RunCMake/export/AppendExport-stderr.txt
new file mode 100644
index 000000000..d71620e5f
--- /dev/null
+++ b/Tests/RunCMake/export/AppendExport-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at AppendExport.cmake:[0-9]+ \(export\):
+ export EXPORT signature does not recognise the APPEND option.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/export/AppendExport.cmake b/Tests/RunCMake/export/AppendExport.cmake
new file mode 100644
index 000000000..2a99dfce4
--- /dev/null
+++ b/Tests/RunCMake/export/AppendExport.cmake
@@ -0,0 +1,9 @@
+enable_language(CXX)
+add_library(foo empty.cpp)
+export(TARGETS foo FILE "${CMAKE_CURRENT_BINARY_DIR}/foo.cmake")
+install(TARGETS foo EXPORT fooExport
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION lib
+ ARCHIVE DESTINATION lib
+)
+export(EXPORT fooExport APPEND FILE "${CMAKE_CURRENT_BINARY_DIR}/foo.cmake")
diff --git a/Tests/RunCMake/export/CMakeLists.txt b/Tests/RunCMake/export/CMakeLists.txt
new file mode 100644
index 000000000..12cd3c775
--- /dev/null
+++ b/Tests/RunCMake/export/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/export/CustomTarget-result.txt b/Tests/RunCMake/export/CustomTarget-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/export/CustomTarget-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/export/CustomTarget-stderr.txt b/Tests/RunCMake/export/CustomTarget-stderr.txt
new file mode 100644
index 000000000..57a9af368
--- /dev/null
+++ b/Tests/RunCMake/export/CustomTarget-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at CustomTarget.cmake:[0-9]+ \(export\):
+ export given custom target "CustomTarget" which may not be exported.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/export/CustomTarget.cmake b/Tests/RunCMake/export/CustomTarget.cmake
new file mode 100644
index 000000000..4d2bf18db
--- /dev/null
+++ b/Tests/RunCMake/export/CustomTarget.cmake
@@ -0,0 +1,2 @@
+add_custom_target(CustomTarget)
+export(TARGETS CustomTarget FILE somefile.cmake)
diff --git a/Tests/RunCMake/export/NoExportSet-result.txt b/Tests/RunCMake/export/NoExportSet-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/export/NoExportSet-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/export/NoExportSet-stderr.txt b/Tests/RunCMake/export/NoExportSet-stderr.txt
new file mode 100644
index 000000000..9d27805e0
--- /dev/null
+++ b/Tests/RunCMake/export/NoExportSet-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at NoExportSet.cmake:2 \(export\):
+ export Export set "fooExport" not found.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/export/NoExportSet.cmake b/Tests/RunCMake/export/NoExportSet.cmake
new file mode 100644
index 000000000..72390e822
--- /dev/null
+++ b/Tests/RunCMake/export/NoExportSet.cmake
@@ -0,0 +1,2 @@
+
+export(EXPORT fooExport)
diff --git a/Tests/RunCMake/export/OldIface-result.txt b/Tests/RunCMake/export/OldIface-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/export/OldIface-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/export/OldIface-stderr.txt b/Tests/RunCMake/export/OldIface-stderr.txt
new file mode 100644
index 000000000..818c2cb20
--- /dev/null
+++ b/Tests/RunCMake/export/OldIface-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at OldIface.cmake:[0-9]+ \(export\):
+ export EXPORT signature does not recognise the
+ EXPORT_LINK_INTERFACE_LIBRARIES option.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/export/OldIface.cmake b/Tests/RunCMake/export/OldIface.cmake
new file mode 100644
index 000000000..833b023d1
--- /dev/null
+++ b/Tests/RunCMake/export/OldIface.cmake
@@ -0,0 +1,11 @@
+enable_language(CXX)
+add_library(foo empty.cpp)
+export(TARGETS foo FILE "${CMAKE_CURRENT_BINARY_DIR}/foo.cmake")
+install(TARGETS foo EXPORT fooExport
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION lib
+ ARCHIVE DESTINATION lib
+)
+export(EXPORT fooExport
+ EXPORT_LINK_INTERFACE_LIBRARIES
+)
diff --git a/Tests/RunCMake/export/RunCMakeTest.cmake b/Tests/RunCMake/export/RunCMakeTest.cmake
new file mode 100644
index 000000000..6d0b7ca7c
--- /dev/null
+++ b/Tests/RunCMake/export/RunCMakeTest.cmake
@@ -0,0 +1,7 @@
+include(RunCMake)
+
+run_cmake(CustomTarget)
+run_cmake(TargetNotFound)
+run_cmake(AppendExport)
+run_cmake(OldIface)
+run_cmake(NoExportSet)
diff --git a/Tests/RunCMake/export/TargetNotFound-result.txt b/Tests/RunCMake/export/TargetNotFound-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/export/TargetNotFound-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/export/TargetNotFound-stderr.txt b/Tests/RunCMake/export/TargetNotFound-stderr.txt
new file mode 100644
index 000000000..944a68e0e
--- /dev/null
+++ b/Tests/RunCMake/export/TargetNotFound-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at TargetNotFound.cmake:1 \(export\):
+ export given target "nonexistenttarget" which is not built by this project.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/export/TargetNotFound.cmake b/Tests/RunCMake/export/TargetNotFound.cmake
new file mode 100644
index 000000000..a7c398daf
--- /dev/null
+++ b/Tests/RunCMake/export/TargetNotFound.cmake
@@ -0,0 +1 @@
+export(TARGETS nonexistenttarget FILE somefile.cmake)
diff --git a/Tests/RunCMake/file/CMakeLists.txt b/Tests/RunCMake/file/CMakeLists.txt
new file mode 100644
index 000000000..289710955
--- /dev/null
+++ b/Tests/RunCMake/file/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.0)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/file/FileOpenFailRead-result.txt b/Tests/RunCMake/file/FileOpenFailRead-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/file/FileOpenFailRead-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/FileOpenFailRead-stderr.txt b/Tests/RunCMake/file/FileOpenFailRead-stderr.txt
new file mode 100644
index 000000000..23d4337f4
--- /dev/null
+++ b/Tests/RunCMake/file/FileOpenFailRead-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at FileOpenFailRead.cmake:[0-9]+ \(file\):
+ file failed to open for reading \(.*\):
+
+ .*/Tests/RunCMake/file/does_not_exist/file.txt
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/file/FileOpenFailRead.cmake b/Tests/RunCMake/file/FileOpenFailRead.cmake
new file mode 100644
index 000000000..4d4c6dc16
--- /dev/null
+++ b/Tests/RunCMake/file/FileOpenFailRead.cmake
@@ -0,0 +1 @@
+file(READ "${CMAKE_CURRENT_SOURCE_DIR}/does_not_exist/file.txt" content)
diff --git a/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-no-arg-result.txt b/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-no-arg-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-no-arg-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-no-arg-stderr.txt b/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-no-arg-stderr.txt
new file mode 100644
index 000000000..9629cfd68
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-no-arg-stderr.txt
@@ -0,0 +1 @@
+.*file LIST_DIRECTORIES missing bool value\.
diff --git a/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-no-arg.cmake b/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-no-arg.cmake
new file mode 100644
index 000000000..a8e15f23e
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-no-arg.cmake
@@ -0,0 +1 @@
+file(GLOB CONTENT_LIST LIST_DIRECTORIES)
diff --git a/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-not-boolean-result.txt b/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-not-boolean-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-not-boolean-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-not-boolean-stderr.txt b/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-not-boolean-stderr.txt
new file mode 100644
index 000000000..9629cfd68
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-not-boolean-stderr.txt
@@ -0,0 +1 @@
+.*file LIST_DIRECTORIES missing bool value\.
diff --git a/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-not-boolean.cmake b/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-not-boolean.cmake
new file mode 100644
index 000000000..f73543398
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-not-boolean.cmake
@@ -0,0 +1 @@
+file(GLOB CONTENT_LIST LIST_DIRECTORIES 13)
diff --git a/Tests/RunCMake/file/GLOB-stderr.txt b/Tests/RunCMake/file/GLOB-stderr.txt
new file mode 100644
index 000000000..c47dc4097
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB-stderr.txt
@@ -0,0 +1,6 @@
+content: 6[ ]
+.*/test/dir 1/dir 1 file;.*/test/dir 1/empty_dir;.*/test/dir 1/non_empty_dir;.*/test/dir 2/dir 2 file;.*/test/dir 2/empty_dir;.*/test/dir 2/non_empty_dir
+content: 6[ ]
+.*/test/dir 1/dir 1 file;.*/test/dir 1/empty_dir;.*/test/dir 1/non_empty_dir;.*/test/dir 2/dir 2 file;.*/test/dir 2/empty_dir;.*/test/dir 2/non_empty_dir
+content: 2[ ]
+.*/test/dir 1/dir 1 file;.*/test/dir 2/dir 2 file
diff --git a/Tests/RunCMake/file/GLOB.cmake b/Tests/RunCMake/file/GLOB.cmake
new file mode 100644
index 000000000..3d577e3a0
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB.cmake
@@ -0,0 +1,28 @@
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test/dir 1/empty_dir")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test/dir 1/non_empty_dir")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test/dir 2/empty_dir")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test/dir 2/non_empty_dir")
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test/dir 1/dir 1 file" "test file")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test/dir 1/non_empty_dir/dir 1 subdir file" "test file")
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test/dir 2/dir 2 file" "test file")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test/dir 2/non_empty_dir/dir 2 subdir file" "test file")
+
+file(GLOB CONTENT_LIST "${CMAKE_CURRENT_BINARY_DIR}/test/*/*")
+list(LENGTH CONTENT_LIST CONTENT_COUNT)
+message("content: ${CONTENT_COUNT} ")
+list(SORT CONTENT_LIST)
+message("${CONTENT_LIST}")
+
+file(GLOB CONTENT_LIST LIST_DIRECTORIES true "${CMAKE_CURRENT_BINARY_DIR}/test/*/*")
+list(LENGTH CONTENT_LIST CONTENT_COUNT)
+message("content: ${CONTENT_COUNT} ")
+list(SORT CONTENT_LIST)
+message("${CONTENT_LIST}")
+
+file(GLOB CONTENT_LIST LIST_DIRECTORIES false "${CMAKE_CURRENT_BINARY_DIR}/test/*/*")
+list(LENGTH CONTENT_LIST CONTENT_COUNT)
+message("content: ${CONTENT_COUNT} ")
+list(SORT CONTENT_LIST)
+message("${CONTENT_LIST}")
diff --git a/Tests/RunCMake/file/GLOB_RECURSE-cyclic-recursion-stderr.txt b/Tests/RunCMake/file/GLOB_RECURSE-cyclic-recursion-stderr.txt
new file mode 100644
index 000000000..f73aa834e
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB_RECURSE-cyclic-recursion-stderr.txt
@@ -0,0 +1,15 @@
+.*Cyclic recursion detected while globbing for.*
+.*/test/depth1/depth2/depth3.*
+.*/test/depth1/depth2/depth3/recursion.*
+content: 4[ ]
+.*/test/abc;.*/test/depth1/depth2/depth3/file_symlink;.*/test/depth1/depth2/depth3/recursion/abc;.*/test/depth1/depth2/depth3/recursion/depth1/depth2/depth3/file_symlink
+.*Cyclic recursion detected while globbing for.*
+.*/test/depth1/depth2/depth3.*
+.*/test/depth1/depth2/depth3/recursion.*
+content: 4[ ]
+.*/test/abc;.*/test/depth1/depth2/depth3/file_symlink;.*/test/depth1/depth2/depth3/recursion/abc;.*/test/depth1/depth2/depth3/recursion/depth1/depth2/depth3/file_symlink
+.*Cyclic recursion detected while globbing for.*
+.*/test/depth1/depth2/depth3.*
+.*/test/depth1/depth2/depth3/recursion.*
+content: 11[ ]
+.*/test/abc;.*/test/depth1;.*/test/depth1/depth2;.*/test/depth1/depth2/depth3;.*/test/depth1/depth2/depth3/file_symlink;.*/test/depth1/depth2/depth3/recursion;.*/test/depth1/depth2/depth3/recursion/abc;.*/test/depth1/depth2/depth3/recursion/depth1;.*/test/depth1/depth2/depth3/recursion/depth1/depth2;.*/test/depth1/depth2/depth3/recursion/depth1/depth2/depth3;.*/test/depth1/depth2/depth3/recursion/depth1/depth2/depth3/file_symlink
diff --git a/Tests/RunCMake/file/GLOB_RECURSE-cyclic-recursion.cmake b/Tests/RunCMake/file/GLOB_RECURSE-cyclic-recursion.cmake
new file mode 100644
index 000000000..a8c67849f
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB_RECURSE-cyclic-recursion.cmake
@@ -0,0 +1,23 @@
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test/depth1/depth2/depth3")
+execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_CURRENT_BINARY_DIR}/test" "${CMAKE_CURRENT_BINARY_DIR}/test/depth1/depth2/depth3/recursion")
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test/abc" "message to write")
+execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_CURRENT_BINARY_DIR}/test/abc" "${CMAKE_CURRENT_BINARY_DIR}/test/depth1/depth2/depth3/file_symlink")
+
+file(GLOB_RECURSE CONTENT_LIST FOLLOW_SYMLINKS "${CMAKE_CURRENT_BINARY_DIR}/test/*")
+list(LENGTH CONTENT_LIST CONTENT_COUNT)
+message("content: ${CONTENT_COUNT} ")
+list(SORT CONTENT_LIST)
+message("${CONTENT_LIST}")
+
+file(GLOB_RECURSE CONTENT_LIST LIST_DIRECTORIES false FOLLOW_SYMLINKS "${CMAKE_CURRENT_BINARY_DIR}/test/*")
+list(LENGTH CONTENT_LIST CONTENT_COUNT)
+message("content: ${CONTENT_COUNT} ")
+list(SORT CONTENT_LIST)
+message("${CONTENT_LIST}")
+
+file(GLOB_RECURSE CONTENT_LIST LIST_DIRECTORIES true FOLLOW_SYMLINKS "${CMAKE_CURRENT_BINARY_DIR}/test/*")
+list(LENGTH CONTENT_LIST CONTENT_COUNT)
+message("content: ${CONTENT_COUNT} ")
+list(SORT CONTENT_LIST)
+message("${CONTENT_LIST}")
diff --git a/Tests/RunCMake/file/GLOB_RECURSE-stderr.txt b/Tests/RunCMake/file/GLOB_RECURSE-stderr.txt
new file mode 100644
index 000000000..5d48e4730
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB_RECURSE-stderr.txt
@@ -0,0 +1,6 @@
+content: 4[ ]
+.*/test/dir 1/dir 1 file;.*/test/dir 1/non_empty_dir/dir 1 subdir file;.*/test/dir 2/dir 2 file;.*/test/dir 2/non_empty_dir/dir 2 subdir file
+content: 4[ ]
+.*/test/dir 1/dir 1 file;.*/test/dir 1/non_empty_dir/dir 1 subdir file;.*/test/dir 2/dir 2 file;.*/test/dir 2/non_empty_dir/dir 2 subdir file
+content: 8[ ]
+.*/test/dir 1/dir 1 file;.*/test/dir 1/empty_dir;.*/test/dir 1/non_empty_dir;.*/test/dir 1/non_empty_dir/dir 1 subdir file;.*/test/dir 2/dir 2 file;.*/test/dir 2/empty_dir;.*/test/dir 2/non_empty_dir;.*/test/dir 2/non_empty_dir/dir 2 subdir file
diff --git a/Tests/RunCMake/file/GLOB_RECURSE.cmake b/Tests/RunCMake/file/GLOB_RECURSE.cmake
new file mode 100644
index 000000000..6db377b41
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB_RECURSE.cmake
@@ -0,0 +1,28 @@
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test/dir 1/empty_dir")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test/dir 1/non_empty_dir")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test/dir 2/empty_dir")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test/dir 2/non_empty_dir")
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test/dir 1/dir 1 file" "test file")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test/dir 1/non_empty_dir/dir 1 subdir file" "test file")
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test/dir 2/dir 2 file" "test file")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test/dir 2/non_empty_dir/dir 2 subdir file" "test file")
+
+file(GLOB_RECURSE CONTENT_LIST "${CMAKE_CURRENT_BINARY_DIR}/test/*/*")
+list(LENGTH CONTENT_LIST CONTENT_COUNT)
+message("content: ${CONTENT_COUNT} ")
+list(SORT CONTENT_LIST)
+message("${CONTENT_LIST}")
+
+file(GLOB_RECURSE CONTENT_LIST LIST_DIRECTORIES false "${CMAKE_CURRENT_BINARY_DIR}/test/*/*")
+list(LENGTH CONTENT_LIST CONTENT_COUNT)
+message("content: ${CONTENT_COUNT} ")
+list(SORT CONTENT_LIST)
+message("${CONTENT_LIST}")
+
+file(GLOB_RECURSE CONTENT_LIST LIST_DIRECTORIES true "${CMAKE_CURRENT_BINARY_DIR}/test/*/*")
+list(LENGTH CONTENT_LIST CONTENT_COUNT)
+message("content: ${CONTENT_COUNT} ")
+list(SORT CONTENT_LIST)
+message("${CONTENT_LIST}")
diff --git a/Tests/RunCMake/file/INSTALL-DIRECTORY-stdout.txt b/Tests/RunCMake/file/INSTALL-DIRECTORY-stdout.txt
new file mode 100644
index 000000000..561a6b1a5
--- /dev/null
+++ b/Tests/RunCMake/file/INSTALL-DIRECTORY-stdout.txt
@@ -0,0 +1,8 @@
+-- Before Installing
+-- Installing: .*/Tests/RunCMake/file/INSTALL-DIRECTORY-build/dir
+-- Installing: .*/Tests/RunCMake/file/INSTALL-DIRECTORY-build/dir/empty.txt
+-- Up-to-date: .*/Tests/RunCMake/file/INSTALL-DIRECTORY-build/dir
+-- Up-to-date: .*/Tests/RunCMake/file/INSTALL-DIRECTORY-build/dir/empty.txt
+-- Up-to-date: .*/Tests/RunCMake/file/INSTALL-DIRECTORY-build/dir
+-- Up-to-date: .*/Tests/RunCMake/file/INSTALL-DIRECTORY-build/dir/empty.txt
+-- After Installing
diff --git a/Tests/RunCMake/file/INSTALL-DIRECTORY.cmake b/Tests/RunCMake/file/INSTALL-DIRECTORY.cmake
new file mode 100644
index 000000000..0bc1d18a9
--- /dev/null
+++ b/Tests/RunCMake/file/INSTALL-DIRECTORY.cmake
@@ -0,0 +1,10 @@
+set(src ${CMAKE_CURRENT_SOURCE_DIR}/dir)
+set(dst ${CMAKE_CURRENT_BINARY_DIR}/dir)
+file(REMOVE RECURSE ${dst})
+message(STATUS "Before Installing")
+file(INSTALL FILES ${src}/ DESTINATION ${dst} TYPE DIRECTORY)
+file(INSTALL FILES ${src}/ DESTINATION ${dst} TYPE DIRECTORY)
+file(INSTALL FILES ${src}/ DESTINATION ${dst} TYPE DIRECTORY MESSAGE_NEVER)
+file(INSTALL FILES ${src}/ DESTINATION ${dst} TYPE DIRECTORY MESSAGE_LAZY)
+file(INSTALL FILES ${src}/ DESTINATION ${dst} TYPE DIRECTORY MESSAGE_ALWAYS)
+message(STATUS "After Installing")
diff --git a/Tests/RunCMake/file/INSTALL-MESSAGE-bad-result.txt b/Tests/RunCMake/file/INSTALL-MESSAGE-bad-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/file/INSTALL-MESSAGE-bad-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/INSTALL-MESSAGE-bad-stderr.txt b/Tests/RunCMake/file/INSTALL-MESSAGE-bad-stderr.txt
new file mode 100644
index 000000000..557b817bb
--- /dev/null
+++ b/Tests/RunCMake/file/INSTALL-MESSAGE-bad-stderr.txt
@@ -0,0 +1,32 @@
+CMake Error at INSTALL-MESSAGE-bad.cmake:1 \(file\):
+ file INSTALL options MESSAGE_ALWAYS, MESSAGE_LAZY, and MESSAGE_NEVER are
+ mutually exclusive.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at INSTALL-MESSAGE-bad.cmake:2 \(file\):
+ file INSTALL options MESSAGE_ALWAYS, MESSAGE_LAZY, and MESSAGE_NEVER are
+ mutually exclusive.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at INSTALL-MESSAGE-bad.cmake:3 \(file\):
+ file INSTALL options MESSAGE_ALWAYS, MESSAGE_LAZY, and MESSAGE_NEVER are
+ mutually exclusive.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at INSTALL-MESSAGE-bad.cmake:4 \(file\):
+ file option MESSAGE_ALWAYS may not appear after PATTERN or REGEX.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at INSTALL-MESSAGE-bad.cmake:5 \(file\):
+ file option MESSAGE_LAZY may not appear after PATTERN or REGEX.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at INSTALL-MESSAGE-bad.cmake:6 \(file\):
+ file option MESSAGE_NEVER may not appear after PATTERN or REGEX.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/file/INSTALL-MESSAGE-bad.cmake b/Tests/RunCMake/file/INSTALL-MESSAGE-bad.cmake
new file mode 100644
index 000000000..f878c6919
--- /dev/null
+++ b/Tests/RunCMake/file/INSTALL-MESSAGE-bad.cmake
@@ -0,0 +1,6 @@
+file(INSTALL DESTINATION dir MESSAGE_ALWAYS MESSAGE_LAZY)
+file(INSTALL DESTINATION dir MESSAGE_ALWAYS MESSAGE_NEVER)
+file(INSTALL DESTINATION dir MESSAGE_LAZY MESSAGE_NEVER)
+file(INSTALL DESTINATION dir PATTERN *.txt MESSAGE_ALWAYS)
+file(INSTALL DESTINATION dir PATTERN *.txt MESSAGE_LAZY)
+file(INSTALL DESTINATION dir PATTERN *.txt MESSAGE_NEVER)
diff --git a/Tests/RunCMake/file/LOCK-error-file-create-fail-result.txt b/Tests/RunCMake/file/LOCK-error-file-create-fail-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-file-create-fail-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/LOCK-error-file-create-fail-stderr.txt b/Tests/RunCMake/file/LOCK-error-file-create-fail-stderr.txt
new file mode 100644
index 000000000..72b7fe0de
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-file-create-fail-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at LOCK-error-file-create-fail\.cmake:[0-9]+ \(file\):
+ file
+
+ ".*"
+
+ creation failed \(check permissions\)\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/file/LOCK-error-file-create-fail.cmake b/Tests/RunCMake/file/LOCK-error-file-create-fail.cmake
new file mode 100644
index 000000000..4868cfe29
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-file-create-fail.cmake
@@ -0,0 +1,3 @@
+set(tmp "${CMAKE_CURRENT_BINARY_DIR}/temp-directory")
+file(MAKE_DIRECTORY "${tmp}")
+file(LOCK "${tmp}")
diff --git a/Tests/RunCMake/file/LOCK-error-guard-incorrect-result.txt b/Tests/RunCMake/file/LOCK-error-guard-incorrect-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-guard-incorrect-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/LOCK-error-guard-incorrect-stderr.txt b/Tests/RunCMake/file/LOCK-error-guard-incorrect-stderr.txt
new file mode 100644
index 000000000..85136b4bb
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-guard-incorrect-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at LOCK-error-guard-incorrect\.cmake:[0-9]+ \(file\):
+ expected FUNCTION, FILE or PROCESS after GUARD, but got:
+
+ "FUNCTIO"\.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/file/LOCK-error-guard-incorrect.cmake b/Tests/RunCMake/file/LOCK-error-guard-incorrect.cmake
new file mode 100644
index 000000000..51daa7cd1
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-guard-incorrect.cmake
@@ -0,0 +1 @@
+file(LOCK "${CMAKE_CURRENT_BINARY_DIR}/file-to-lock" GUARD FUNCTIO)
diff --git a/Tests/RunCMake/file/LOCK-error-incorrect-timeout-result.txt b/Tests/RunCMake/file/LOCK-error-incorrect-timeout-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-incorrect-timeout-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/LOCK-error-incorrect-timeout-stderr.txt b/Tests/RunCMake/file/LOCK-error-incorrect-timeout-stderr.txt
new file mode 100644
index 000000000..c6ae1e0bf
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-incorrect-timeout-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at LOCK-error-incorrect-timeout\.cmake:[0-9]+ \(file\):
+ TIMEOUT value "qwerty" is not an unsigned integer\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/file/LOCK-error-incorrect-timeout-trail-result.txt b/Tests/RunCMake/file/LOCK-error-incorrect-timeout-trail-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-incorrect-timeout-trail-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/LOCK-error-incorrect-timeout-trail-stderr.txt b/Tests/RunCMake/file/LOCK-error-incorrect-timeout-trail-stderr.txt
new file mode 100644
index 000000000..6ea250728
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-incorrect-timeout-trail-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at LOCK-error-incorrect-timeout-trail\.cmake:[0-9]+ \(file\):
+ TIMEOUT value "123xyz" is not an unsigned integer\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/file/LOCK-error-incorrect-timeout-trail.cmake b/Tests/RunCMake/file/LOCK-error-incorrect-timeout-trail.cmake
new file mode 100644
index 000000000..c4f1b75da
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-incorrect-timeout-trail.cmake
@@ -0,0 +1 @@
+file(LOCK "${CMAKE_CURRENT_BINARY_DIR}/file-to-lock" TIMEOUT 123xyz)
diff --git a/Tests/RunCMake/file/LOCK-error-incorrect-timeout.cmake b/Tests/RunCMake/file/LOCK-error-incorrect-timeout.cmake
new file mode 100644
index 000000000..d882467d4
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-incorrect-timeout.cmake
@@ -0,0 +1 @@
+file(LOCK "${CMAKE_CURRENT_BINARY_DIR}/file-to-lock" TIMEOUT qwerty)
diff --git a/Tests/RunCMake/file/LOCK-error-lock-fail-result.txt b/Tests/RunCMake/file/LOCK-error-lock-fail-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-lock-fail-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/LOCK-error-lock-fail-stderr.txt b/Tests/RunCMake/file/LOCK-error-lock-fail-stderr.txt
new file mode 100644
index 000000000..a7b044724
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-lock-fail-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at LOCK-error-lock-fail.cmake:[0-9]+ \(file\):
+ directory
+
+ ".*"
+
+ creation failed \(check permissions\)\.
diff --git a/Tests/RunCMake/file/LOCK-error-lock-fail.cmake b/Tests/RunCMake/file/LOCK-error-lock-fail.cmake
new file mode 100644
index 000000000..aa7f663c2
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-lock-fail.cmake
@@ -0,0 +1,6 @@
+set(lfile "${CMAKE_CURRENT_BINARY_DIR}/file-to-lock")
+FILE(WRITE "${lfile}" "")
+
+# Try to lock file '${lfile}/cmake.lock'. Since `lfile` is not a directory
+# expected that operation will fail.
+file(LOCK "${lfile}" DIRECTORY)
diff --git a/Tests/RunCMake/file/LOCK-error-negative-timeout-result.txt b/Tests/RunCMake/file/LOCK-error-negative-timeout-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-negative-timeout-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/LOCK-error-negative-timeout-stderr.txt b/Tests/RunCMake/file/LOCK-error-negative-timeout-stderr.txt
new file mode 100644
index 000000000..0d159c104
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-negative-timeout-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at LOCK-error-negative-timeout\.cmake:[0-9]+ \(file\):
+ TIMEOUT value "-2" is not an unsigned integer\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/file/LOCK-error-negative-timeout.cmake b/Tests/RunCMake/file/LOCK-error-negative-timeout.cmake
new file mode 100644
index 000000000..6a0f19023
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-negative-timeout.cmake
@@ -0,0 +1 @@
+file(LOCK "${CMAKE_CURRENT_BINARY_DIR}/file-to-lock" TIMEOUT -2)
diff --git a/Tests/RunCMake/file/LOCK-error-no-function-result.txt b/Tests/RunCMake/file/LOCK-error-no-function-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-no-function-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/LOCK-error-no-function-stderr.txt b/Tests/RunCMake/file/LOCK-error-no-function-stderr.txt
new file mode 100644
index 000000000..51ed12dc5
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-no-function-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at LOCK-error-no-function\.cmake:[0-9]+ \(file\):
+ error locking file
+
+ ".*"
+
+ 'GUARD FUNCTION' not used in function definition\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/file/LOCK-error-no-function.cmake b/Tests/RunCMake/file/LOCK-error-no-function.cmake
new file mode 100644
index 000000000..1b8b06a33
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-no-function.cmake
@@ -0,0 +1 @@
+file(LOCK "${CMAKE_CURRENT_BINARY_DIR}/file-to-lock" GUARD FUNCTION)
diff --git a/Tests/RunCMake/file/LOCK-error-no-guard-result.txt b/Tests/RunCMake/file/LOCK-error-no-guard-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-no-guard-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/LOCK-error-no-guard-stderr.txt b/Tests/RunCMake/file/LOCK-error-no-guard-stderr.txt
new file mode 100644
index 000000000..41177ce3b
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-no-guard-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at LOCK-error-no-guard\.cmake:[0-9]+ \(file\):
+ expected FUNCTION, FILE or PROCESS after GUARD
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/file/LOCK-error-no-guard.cmake b/Tests/RunCMake/file/LOCK-error-no-guard.cmake
new file mode 100644
index 000000000..48ffc5ee7
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-no-guard.cmake
@@ -0,0 +1 @@
+file(LOCK "${CMAKE_CURRENT_BINARY_DIR}/file-to-lock" GUARD)
diff --git a/Tests/RunCMake/file/LOCK-error-no-path-result.txt b/Tests/RunCMake/file/LOCK-error-no-path-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-no-path-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/LOCK-error-no-path-stderr.txt b/Tests/RunCMake/file/LOCK-error-no-path-stderr.txt
new file mode 100644
index 000000000..2247aa68e
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-no-path-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at LOCK-error-no-path.cmake:[0-9]+ \(file\):
+ file must be called with at least two arguments.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/file/LOCK-error-no-path.cmake b/Tests/RunCMake/file/LOCK-error-no-path.cmake
new file mode 100644
index 000000000..12d79b740
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-no-path.cmake
@@ -0,0 +1 @@
+file(LOCK)
diff --git a/Tests/RunCMake/file/LOCK-error-no-result-variable-result.txt b/Tests/RunCMake/file/LOCK-error-no-result-variable-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-no-result-variable-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/LOCK-error-no-result-variable-stderr.txt b/Tests/RunCMake/file/LOCK-error-no-result-variable-stderr.txt
new file mode 100644
index 000000000..b38e23c56
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-no-result-variable-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at LOCK-error-no-result-variable\.cmake:[0-9]+ \(file\):
+ expected variable name after RESULT_VARIABLE
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/file/LOCK-error-no-result-variable.cmake b/Tests/RunCMake/file/LOCK-error-no-result-variable.cmake
new file mode 100644
index 000000000..e6ac18d63
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-no-result-variable.cmake
@@ -0,0 +1 @@
+file(LOCK "${CMAKE_CURRENT_BINARY_DIR}/file-to-lock" RESULT_VARIABLE)
diff --git a/Tests/RunCMake/file/LOCK-error-no-timeout-result.txt b/Tests/RunCMake/file/LOCK-error-no-timeout-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-no-timeout-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/LOCK-error-no-timeout-stderr.txt b/Tests/RunCMake/file/LOCK-error-no-timeout-stderr.txt
new file mode 100644
index 000000000..f34d46fbc
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-no-timeout-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at LOCK-error-no-timeout\.cmake:[0-9]+ \(file\):
+ expected timeout value after TIMEOUT
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/file/LOCK-error-no-timeout.cmake b/Tests/RunCMake/file/LOCK-error-no-timeout.cmake
new file mode 100644
index 000000000..16181922d
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-no-timeout.cmake
@@ -0,0 +1 @@
+file(LOCK "${CMAKE_CURRENT_BINARY_DIR}/file-to-lock" TIMEOUT)
diff --git a/Tests/RunCMake/file/LOCK-error-timeout-result.txt b/Tests/RunCMake/file/LOCK-error-timeout-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-timeout-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/LOCK-error-timeout-stderr.txt b/Tests/RunCMake/file/LOCK-error-timeout-stderr.txt
new file mode 100644
index 000000000..4ad1f04d5
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-timeout-stderr.txt
@@ -0,0 +1,12 @@
+Output:[ ]*
+Error: CMake Error at .*.timeout-script\.cmake:[0-9]+ \(file\):
+ error locking file
+
+ ".*"
+
+ Timeout reached\.
++
+CMake Error at LOCK-error-timeout\.cmake:[0-9]+ \(message\):
+ Result: 1
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/file/LOCK-error-timeout-stdout.txt b/Tests/RunCMake/file/LOCK-error-timeout-stdout.txt
new file mode 100644
index 000000000..8d98f9deb
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-timeout-stdout.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/file/LOCK-error-timeout.cmake b/Tests/RunCMake/file/LOCK-error-timeout.cmake
new file mode 100644
index 000000000..b6b947603
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-timeout.cmake
@@ -0,0 +1,17 @@
+set(script "${CMAKE_CURRENT_LIST_DIR}/timeout-script.cmake")
+set(file_to_lock "${CMAKE_CURRENT_BINARY_DIR}/file-to-lock")
+
+file(LOCK "${file_to_lock}")
+execute_process(
+ COMMAND "${CMAKE_COMMAND}" "-Dfile_to_lock=${file_to_lock}" -P "${script}"
+ RESULT_VARIABLE result
+ OUTPUT_VARIABLE output
+ ERROR_VARIABLE error
+)
+
+message("Output: ${output}")
+message("Error: ${error}")
+
+if(NOT result EQUAL 0)
+ message(FATAL_ERROR "Result: ${result}")
+endif()
diff --git a/Tests/RunCMake/file/LOCK-error-unknown-option-result.txt b/Tests/RunCMake/file/LOCK-error-unknown-option-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-unknown-option-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/LOCK-error-unknown-option-stderr.txt b/Tests/RunCMake/file/LOCK-error-unknown-option-stderr.txt
new file mode 100644
index 000000000..ad596afd7
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-unknown-option-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at LOCK-error-unknown-option\.cmake:[0-9]+ \(file\):
+ expected DIRECTORY, RELEASE, GUARD, RESULT_VARIABLE or TIMEOUT
+
+ but got: "UNKNOWN"\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]* \(include\)
diff --git a/Tests/RunCMake/file/LOCK-error-unknown-option.cmake b/Tests/RunCMake/file/LOCK-error-unknown-option.cmake
new file mode 100644
index 000000000..88ef002b2
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-error-unknown-option.cmake
@@ -0,0 +1 @@
+file(LOCK "${CMAKE_CURRENT_BINARY_DIR}/temp-file" UNKNOWN)
diff --git a/Tests/RunCMake/file/LOCK-stdout.txt b/Tests/RunCMake/file/LOCK-stdout.txt
new file mode 100644
index 000000000..416126a8a
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-stdout.txt
@@ -0,0 +1,11 @@
+-- Simple lock
+-- Directory lock
+-- Release
+-- Lock function scope
+-- Lock file scope
+-- Lock in subdirectory
+-- Lock process scope
+-- Error double lock
+-- Ok
+-- Timeout 0
+-- Timeout not 0
diff --git a/Tests/RunCMake/file/LOCK.cmake b/Tests/RunCMake/file/LOCK.cmake
new file mode 100644
index 000000000..8eff08469
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK.cmake
@@ -0,0 +1,40 @@
+set(lfile "${CMAKE_CURRENT_BINARY_DIR}/file-to-lock")
+set(ldir "${CMAKE_CURRENT_BINARY_DIR}/dir-to-lock")
+
+message(STATUS "Simple lock")
+file(LOCK ${lfile})
+
+message(STATUS "Directory lock")
+file(LOCK ${ldir} DIRECTORY)
+
+message(STATUS "Release")
+file(LOCK ${lfile} RELEASE)
+
+function(foo)
+ file(LOCK "${lfile}" GUARD FUNCTION)
+endfunction()
+
+message(STATUS "Lock function scope")
+foo()
+
+message(STATUS "Lock file scope")
+add_subdirectory(subdir_test_unlock)
+
+message(STATUS "Lock process scope")
+file(LOCK "${lfile}" GUARD PROCESS)
+
+message(STATUS "Error double lock")
+file(LOCK "${lfile}" RESULT_VARIABLE lock_result)
+if(lock_result STREQUAL "File already locked")
+ message(STATUS "Ok")
+else()
+ message(STATUS FATAL_ERROR "Expected error message")
+endif()
+
+message(STATUS "Timeout 0")
+file(LOCK "${lfile}" RELEASE)
+file(LOCK "${lfile}" TIMEOUT 0)
+
+message(STATUS "Timeout not 0")
+file(LOCK "${lfile}" RELEASE)
+file(LOCK "${lfile}" TIMEOUT 3)
diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake
new file mode 100644
index 000000000..d3dfb1b7c
--- /dev/null
+++ b/Tests/RunCMake/file/RunCMakeTest.cmake
@@ -0,0 +1,29 @@
+include(RunCMake)
+
+run_cmake(INSTALL-DIRECTORY)
+run_cmake(INSTALL-MESSAGE-bad)
+run_cmake(FileOpenFailRead)
+run_cmake(LOCK)
+run_cmake(LOCK-error-file-create-fail)
+run_cmake(LOCK-error-guard-incorrect)
+run_cmake(LOCK-error-incorrect-timeout)
+run_cmake(LOCK-error-incorrect-timeout-trail)
+run_cmake(LOCK-error-lock-fail)
+run_cmake(LOCK-error-negative-timeout)
+run_cmake(LOCK-error-no-function)
+run_cmake(LOCK-error-no-guard)
+run_cmake(LOCK-error-no-path)
+run_cmake(LOCK-error-no-result-variable)
+run_cmake(LOCK-error-no-timeout)
+run_cmake(LOCK-error-timeout)
+run_cmake(LOCK-error-unknown-option)
+run_cmake(GLOB)
+run_cmake(GLOB_RECURSE)
+# test is valid both for GLOB and GLOB_RECURSE
+run_cmake(GLOB-error-LIST_DIRECTORIES-not-boolean)
+# test is valid both for GLOB and GLOB_RECURSE
+run_cmake(GLOB-error-LIST_DIRECTORIES-no-arg)
+
+if(NOT WIN32 OR CYGWIN)
+ run_cmake(GLOB_RECURSE-cyclic-recursion)
+endif()
diff --git a/Tests/RunCMake/file/dir/empty.txt b/Tests/RunCMake/file/dir/empty.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/file/dir/empty.txt
diff --git a/Tests/RunCMake/file/subdir_test_unlock/CMakeLists.txt b/Tests/RunCMake/file/subdir_test_unlock/CMakeLists.txt
new file mode 100644
index 000000000..c167cd77c
--- /dev/null
+++ b/Tests/RunCMake/file/subdir_test_unlock/CMakeLists.txt
@@ -0,0 +1,2 @@
+message(STATUS "Lock in subdirectory")
+file(LOCK "${lfile}" GUARD FILE)
diff --git a/Tests/RunCMake/file/timeout-script.cmake b/Tests/RunCMake/file/timeout-script.cmake
new file mode 100644
index 000000000..e07dbf0b8
--- /dev/null
+++ b/Tests/RunCMake/file/timeout-script.cmake
@@ -0,0 +1,5 @@
+if(NOT file_to_lock)
+ message(FATAL_ERROR "file_to_lock is empty")
+endif()
+
+file(LOCK "${file_to_lock}" TIMEOUT 1)
diff --git a/Tests/RunCMake/find_dependency/CMakeLists.txt b/Tests/RunCMake/find_dependency/CMakeLists.txt
new file mode 100644
index 000000000..04d09f2ad
--- /dev/null
+++ b/Tests/RunCMake/find_dependency/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST} NONE)
+set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/find_dependency/EXACT-no-version-result.txt b/Tests/RunCMake/find_dependency/EXACT-no-version-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/find_dependency/EXACT-no-version-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_dependency/EXACT-no-version-stderr.txt b/Tests/RunCMake/find_dependency/EXACT-no-version-stderr.txt
new file mode 100644
index 000000000..348f8bb25
--- /dev/null
+++ b/Tests/RunCMake/find_dependency/EXACT-no-version-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at .*Modules/CMakeFindDependencyMacro.cmake:[0-9]+ \(message\):
+ Invalid arguments to find_dependency. EXACT may only be specified if a
+ VERSION is specified
+Call Stack \(most recent call first\):
+ EXACT-no-version.cmake:4 \(find_dependency\)
+ CMakeLists.txt:4 \(include\)
diff --git a/Tests/RunCMake/find_dependency/EXACT-no-version.cmake b/Tests/RunCMake/find_dependency/EXACT-no-version.cmake
new file mode 100644
index 000000000..b05665b7e
--- /dev/null
+++ b/Tests/RunCMake/find_dependency/EXACT-no-version.cmake
@@ -0,0 +1,4 @@
+
+include(CMakeFindDependencyMacro)
+
+find_dependency(Pack1 EXACT)
diff --git a/Tests/RunCMake/find_dependency/Pack1/Pack1Config.cmake b/Tests/RunCMake/find_dependency/Pack1/Pack1Config.cmake
new file mode 100644
index 000000000..7d55ef61d
--- /dev/null
+++ b/Tests/RunCMake/find_dependency/Pack1/Pack1Config.cmake
@@ -0,0 +1,2 @@
+
+add_library(Pack1::Lib INTERFACE IMPORTED)
diff --git a/Tests/RunCMake/find_dependency/Pack1/Pack1ConfigVersion.cmake b/Tests/RunCMake/find_dependency/Pack1/Pack1ConfigVersion.cmake
new file mode 100644
index 000000000..dfb7b6c84
--- /dev/null
+++ b/Tests/RunCMake/find_dependency/Pack1/Pack1ConfigVersion.cmake
@@ -0,0 +1,11 @@
+
+set(PACKAGE_VERSION "1.3")
+
+if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
+ set(PACKAGE_VERSION_COMPATIBLE FALSE)
+else()
+ set(PACKAGE_VERSION_COMPATIBLE TRUE)
+ if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
+ set(PACKAGE_VERSION_EXACT TRUE)
+ endif()
+endif()
diff --git a/Tests/RunCMake/find_dependency/RunCMakeTest.cmake b/Tests/RunCMake/find_dependency/RunCMakeTest.cmake
new file mode 100644
index 000000000..9403136b7
--- /dev/null
+++ b/Tests/RunCMake/find_dependency/RunCMakeTest.cmake
@@ -0,0 +1,7 @@
+include(RunCMake)
+
+run_cmake(EXACT-no-version)
+run_cmake(empty-version)
+run_cmake(empty-arg-3)
+run_cmake(invalid-arg-3)
+run_cmake(extra-args)
diff --git a/Tests/RunCMake/find_dependency/empty-arg-3-result.txt b/Tests/RunCMake/find_dependency/empty-arg-3-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/find_dependency/empty-arg-3-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_dependency/empty-arg-3-stderr.txt b/Tests/RunCMake/find_dependency/empty-arg-3-stderr.txt
new file mode 100644
index 000000000..bf9b02b43
--- /dev/null
+++ b/Tests/RunCMake/find_dependency/empty-arg-3-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at .*Modules/CMakeFindDependencyMacro.cmake:[0-9]+ \(message\):
+ Invalid arguments to find_dependency
+Call Stack \(most recent call first\):
+ empty-arg-3.cmake:4 \(find_dependency\)
+ CMakeLists.txt:4 \(include\)
diff --git a/Tests/RunCMake/find_dependency/empty-arg-3.cmake b/Tests/RunCMake/find_dependency/empty-arg-3.cmake
new file mode 100644
index 000000000..b08200a5a
--- /dev/null
+++ b/Tests/RunCMake/find_dependency/empty-arg-3.cmake
@@ -0,0 +1,4 @@
+
+include(CMakeFindDependencyMacro)
+
+find_dependency(Pack1 1.2 "")
diff --git a/Tests/RunCMake/find_dependency/empty-version-result.txt b/Tests/RunCMake/find_dependency/empty-version-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/find_dependency/empty-version-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_dependency/empty-version-stderr.txt b/Tests/RunCMake/find_dependency/empty-version-stderr.txt
new file mode 100644
index 000000000..b5e9f4643
--- /dev/null
+++ b/Tests/RunCMake/find_dependency/empty-version-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at .*/Modules/CMakeFindDependencyMacro.cmake:[0-9]+ \(message\):
+ Invalid arguments to find_dependency. VERSION is empty
+Call Stack \(most recent call first\):
+ empty-version.cmake:4 \(find_dependency\)
+ CMakeLists.txt:4 \(include\)
diff --git a/Tests/RunCMake/find_dependency/empty-version.cmake b/Tests/RunCMake/find_dependency/empty-version.cmake
new file mode 100644
index 000000000..e6f17cd13
--- /dev/null
+++ b/Tests/RunCMake/find_dependency/empty-version.cmake
@@ -0,0 +1,4 @@
+
+include(CMakeFindDependencyMacro)
+
+find_dependency(Pack1 "")
diff --git a/Tests/RunCMake/find_dependency/extra-args-result.txt b/Tests/RunCMake/find_dependency/extra-args-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/find_dependency/extra-args-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_dependency/extra-args-stderr.txt b/Tests/RunCMake/find_dependency/extra-args-stderr.txt
new file mode 100644
index 000000000..83a7f0266
--- /dev/null
+++ b/Tests/RunCMake/find_dependency/extra-args-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at .*Modules/CMakeFindDependencyMacro.cmake:[0-9]+ \(message\):
+ Invalid arguments to find_dependency
+Call Stack \(most recent call first\):
+ extra-args.cmake:4 \(find_dependency\)
+ CMakeLists.txt:4 \(include\)
diff --git a/Tests/RunCMake/find_dependency/extra-args.cmake b/Tests/RunCMake/find_dependency/extra-args.cmake
new file mode 100644
index 000000000..209645a5d
--- /dev/null
+++ b/Tests/RunCMake/find_dependency/extra-args.cmake
@@ -0,0 +1,4 @@
+
+include(CMakeFindDependencyMacro)
+
+find_dependency(Pack1 1.2 EXACT PATHS "${CMAKE_BINARY_DIR}")
diff --git a/Tests/RunCMake/find_dependency/invalid-arg-3-result.txt b/Tests/RunCMake/find_dependency/invalid-arg-3-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/find_dependency/invalid-arg-3-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_dependency/invalid-arg-3-stderr.txt b/Tests/RunCMake/find_dependency/invalid-arg-3-stderr.txt
new file mode 100644
index 000000000..fee8d5db7
--- /dev/null
+++ b/Tests/RunCMake/find_dependency/invalid-arg-3-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at .*Modules/CMakeFindDependencyMacro.cmake:[0-9]+ \(message\):
+ Invalid arguments to find_dependency
+Call Stack \(most recent call first\):
+ invalid-arg-3.cmake:4 \(find_dependency\)
+ CMakeLists.txt:4 \(include\)
diff --git a/Tests/RunCMake/find_dependency/invalid-arg-3.cmake b/Tests/RunCMake/find_dependency/invalid-arg-3.cmake
new file mode 100644
index 000000000..40ede07f4
--- /dev/null
+++ b/Tests/RunCMake/find_dependency/invalid-arg-3.cmake
@@ -0,0 +1,4 @@
+
+include(CMakeFindDependencyMacro)
+
+find_dependency(Pack1 1.2 EXACTYPO)
diff --git a/Tests/RunCMake/find_file/CMakeLists.txt b/Tests/RunCMake/find_file/CMakeLists.txt
new file mode 100644
index 000000000..ef2163c29
--- /dev/null
+++ b/Tests/RunCMake/find_file/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.1)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/find_file/PrefixInPATH-stdout.txt b/Tests/RunCMake/find_file/PrefixInPATH-stdout.txt
new file mode 100644
index 000000000..d73bc1dfd
--- /dev/null
+++ b/Tests/RunCMake/find_file/PrefixInPATH-stdout.txt
@@ -0,0 +1,4 @@
+-- PrefixInPATH_INCLUDE_DIR='PrefixInPATH_INCLUDE_DIR-NOTFOUND'
+-- PrefixInPATH_INCLUDE_DIR='.*/Tests/RunCMake/find_file/include/PrefixInPATH.h'
+-- PrefixInPATH_INCLUDE_DIR='.*/Tests/RunCMake/find_file/include/PrefixInPATH.h'
+-- PrefixInPATH_INCLUDE_DIR='.*/Tests/RunCMake/find_file/include/PrefixInPATH.h'
diff --git a/Tests/RunCMake/find_file/PrefixInPATH.cmake b/Tests/RunCMake/find_file/PrefixInPATH.cmake
new file mode 100644
index 000000000..1e33c08a6
--- /dev/null
+++ b/Tests/RunCMake/find_file/PrefixInPATH.cmake
@@ -0,0 +1,8 @@
+set(ENV_PATH "$ENV{PATH}")
+foreach(path "/does_not_exist" "" "/bin" "/sbin")
+ unset(PrefixInPATH_INCLUDE_DIR CACHE)
+ set(ENV{PATH} "${CMAKE_CURRENT_SOURCE_DIR}${path}")
+ find_file(PrefixInPATH_INCLUDE_DIR NAMES PrefixInPATH.h)
+ message(STATUS "PrefixInPATH_INCLUDE_DIR='${PrefixInPATH_INCLUDE_DIR}'")
+endforeach()
+set(ENV{PATH} "${ENV_PATH}")
diff --git a/Tests/RunCMake/find_file/RunCMakeTest.cmake b/Tests/RunCMake/find_file/RunCMakeTest.cmake
new file mode 100644
index 000000000..014f39734
--- /dev/null
+++ b/Tests/RunCMake/find_file/RunCMakeTest.cmake
@@ -0,0 +1,3 @@
+include(RunCMake)
+
+run_cmake(PrefixInPATH)
diff --git a/Tests/RunCMake/find_file/include/PrefixInPATH.h b/Tests/RunCMake/find_file/include/PrefixInPATH.h
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/find_file/include/PrefixInPATH.h
diff --git a/Tests/RunCMake/find_library/CMakeLists.txt b/Tests/RunCMake/find_library/CMakeLists.txt
new file mode 100644
index 000000000..ef2163c29
--- /dev/null
+++ b/Tests/RunCMake/find_library/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.1)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/find_library/Created-stderr.txt b/Tests/RunCMake/find_library/Created-stderr.txt
new file mode 100644
index 000000000..67b347482
--- /dev/null
+++ b/Tests/RunCMake/find_library/Created-stderr.txt
@@ -0,0 +1,2 @@
+CREATED_LIBRARY='CREATED_LIBRARY-NOTFOUND'
+CREATED_LIBRARY='[^']*/Tests/RunCMake/find_library/Created-build/lib/libcreated.a'
diff --git a/Tests/RunCMake/find_library/Created.cmake b/Tests/RunCMake/find_library/Created.cmake
new file mode 100644
index 000000000..c0fd823c7
--- /dev/null
+++ b/Tests/RunCMake/find_library/Created.cmake
@@ -0,0 +1,16 @@
+list(APPEND CMAKE_FIND_LIBRARY_PREFIXES lib)
+list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES .a)
+find_library(CREATED_LIBRARY
+ NAMES created
+ PATHS ${CMAKE_CURRENT_BINARY_DIR}/lib
+ NO_DEFAULT_PATH
+ )
+message("CREATED_LIBRARY='${CREATED_LIBRARY}'")
+file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib/libcreated.a" "created")
+find_library(CREATED_LIBRARY
+ NAMES created
+ PATHS ${CMAKE_CURRENT_BINARY_DIR}/lib
+ NO_DEFAULT_PATH
+ )
+message("CREATED_LIBRARY='${CREATED_LIBRARY}'")
diff --git a/Tests/RunCMake/find_library/PrefixInPATH-stdout.txt b/Tests/RunCMake/find_library/PrefixInPATH-stdout.txt
new file mode 100644
index 000000000..1ab884cb7
--- /dev/null
+++ b/Tests/RunCMake/find_library/PrefixInPATH-stdout.txt
@@ -0,0 +1,4 @@
+-- PrefixInPATH_LIBRARY='PrefixInPATH_LIBRARY-NOTFOUND'
+-- PrefixInPATH_LIBRARY='.*/Tests/RunCMake/find_library/lib/libPrefixInPATH.a'
+-- PrefixInPATH_LIBRARY='.*/Tests/RunCMake/find_library/lib/libPrefixInPATH.a'
+-- PrefixInPATH_LIBRARY='.*/Tests/RunCMake/find_library/lib/libPrefixInPATH.a'
diff --git a/Tests/RunCMake/find_library/PrefixInPATH.cmake b/Tests/RunCMake/find_library/PrefixInPATH.cmake
new file mode 100644
index 000000000..f1b8b187a
--- /dev/null
+++ b/Tests/RunCMake/find_library/PrefixInPATH.cmake
@@ -0,0 +1,11 @@
+list(APPEND CMAKE_FIND_LIBRARY_PREFIXES lib)
+list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES .a)
+
+set(ENV_PATH "$ENV{PATH}")
+foreach(path "/does_not_exist" "" "/bin" "/sbin")
+ unset(PrefixInPATH_LIBRARY CACHE)
+ set(ENV{PATH} "${CMAKE_CURRENT_SOURCE_DIR}${path}")
+ find_library(PrefixInPATH_LIBRARY NAMES PrefixInPATH)
+ message(STATUS "PrefixInPATH_LIBRARY='${PrefixInPATH_LIBRARY}'")
+endforeach()
+set(ENV{PATH} "${ENV_PATH}")
diff --git a/Tests/RunCMake/find_library/RunCMakeTest.cmake b/Tests/RunCMake/find_library/RunCMakeTest.cmake
new file mode 100644
index 000000000..136031c63
--- /dev/null
+++ b/Tests/RunCMake/find_library/RunCMakeTest.cmake
@@ -0,0 +1,4 @@
+include(RunCMake)
+
+run_cmake(Created)
+run_cmake(PrefixInPATH)
diff --git a/Tests/RunCMake/find_library/lib/libPrefixInPATH.a b/Tests/RunCMake/find_library/lib/libPrefixInPATH.a
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/find_library/lib/libPrefixInPATH.a
diff --git a/Tests/RunCMake/find_package/PolicyPop-result.txt b/Tests/RunCMake/find_package/PolicyPop-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/find_package/PolicyPop-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_package/PolicyPop-stderr.txt b/Tests/RunCMake/find_package/PolicyPop-stderr.txt
new file mode 100644
index 000000000..745d39a1a
--- /dev/null
+++ b/Tests/RunCMake/find_package/PolicyPop-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at PolicyPop/PolicyPopConfigVersion.cmake:3 \(cmake_policy\):
+ cmake_policy POP without matching PUSH
+Call Stack \(most recent call first\):
+ PolicyPop.cmake:1 \(find_package\)
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/find_package/PolicyPop.cmake b/Tests/RunCMake/find_package/PolicyPop.cmake
new file mode 100644
index 000000000..4866f24f5
--- /dev/null
+++ b/Tests/RunCMake/find_package/PolicyPop.cmake
@@ -0,0 +1 @@
+find_package(PolicyPop 1 CONFIG PATHS ${CMAKE_CURRENT_SOURCE_DIR}/PolicyPop NO_DEFAULT_PATH)
diff --git a/Tests/RunCMake/find_package/PolicyPop/PolicyPopConfig.cmake b/Tests/RunCMake/find_package/PolicyPop/PolicyPopConfig.cmake
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/find_package/PolicyPop/PolicyPopConfig.cmake
diff --git a/Tests/RunCMake/find_package/PolicyPop/PolicyPopConfigVersion.cmake b/Tests/RunCMake/find_package/PolicyPop/PolicyPopConfigVersion.cmake
new file mode 100644
index 000000000..483fb10f2
--- /dev/null
+++ b/Tests/RunCMake/find_package/PolicyPop/PolicyPopConfigVersion.cmake
@@ -0,0 +1,3 @@
+set(PACKAGE_VERSION 1)
+set(PACKAGE_VERSION_COMPATIBLE 1)
+cmake_policy(POP)
diff --git a/Tests/RunCMake/find_package/PolicyPush-result.txt b/Tests/RunCMake/find_package/PolicyPush-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/find_package/PolicyPush-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_package/PolicyPush-stderr.txt b/Tests/RunCMake/find_package/PolicyPush-stderr.txt
new file mode 100644
index 000000000..1afcb1627
--- /dev/null
+++ b/Tests/RunCMake/find_package/PolicyPush-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at PolicyPush/PolicyPushConfigVersion.cmake:1 \(find_package\):
+ cmake_policy PUSH without matching POP
+Call Stack \(most recent call first\):
+ PolicyPush.cmake:1 \(find_package\)
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/find_package/PolicyPush.cmake b/Tests/RunCMake/find_package/PolicyPush.cmake
new file mode 100644
index 000000000..30c3ce2a3
--- /dev/null
+++ b/Tests/RunCMake/find_package/PolicyPush.cmake
@@ -0,0 +1 @@
+find_package(PolicyPush 1 CONFIG PATHS ${CMAKE_CURRENT_SOURCE_DIR}/PolicyPush NO_DEFAULT_PATH)
diff --git a/Tests/RunCMake/find_package/PolicyPush/PolicyPushConfig.cmake b/Tests/RunCMake/find_package/PolicyPush/PolicyPushConfig.cmake
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/find_package/PolicyPush/PolicyPushConfig.cmake
diff --git a/Tests/RunCMake/find_package/PolicyPush/PolicyPushConfigVersion.cmake b/Tests/RunCMake/find_package/PolicyPush/PolicyPushConfigVersion.cmake
new file mode 100644
index 000000000..45a8dbd40
--- /dev/null
+++ b/Tests/RunCMake/find_package/PolicyPush/PolicyPushConfigVersion.cmake
@@ -0,0 +1,3 @@
+set(PACKAGE_VERSION 1)
+set(PACKAGE_VERSION_COMPATIBLE 1)
+cmake_policy(PUSH)
diff --git a/Tests/RunCMake/find_package/RunCMakeTest.cmake b/Tests/RunCMake/find_package/RunCMakeTest.cmake
index 42705b77a..81b29068c 100644
--- a/Tests/RunCMake/find_package/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_package/RunCMakeTest.cmake
@@ -13,4 +13,6 @@ run_cmake(MissingConfigOneName)
run_cmake(MissingConfigRequired)
run_cmake(MissingConfigVersion)
run_cmake(MixedModeOptions)
+run_cmake(PolicyPush)
+run_cmake(PolicyPop)
run_cmake(SetFoundFALSE)
diff --git a/Tests/RunCMake/find_path/CMakeLists.txt b/Tests/RunCMake/find_path/CMakeLists.txt
new file mode 100644
index 000000000..ef2163c29
--- /dev/null
+++ b/Tests/RunCMake/find_path/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.1)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/find_path/PrefixInPATH-stdout.txt b/Tests/RunCMake/find_path/PrefixInPATH-stdout.txt
new file mode 100644
index 000000000..bb2ceb725
--- /dev/null
+++ b/Tests/RunCMake/find_path/PrefixInPATH-stdout.txt
@@ -0,0 +1,4 @@
+-- PrefixInPATH_INCLUDE_DIR='PrefixInPATH_INCLUDE_DIR-NOTFOUND'
+-- PrefixInPATH_INCLUDE_DIR='.*/Tests/RunCMake/find_path/include'
+-- PrefixInPATH_INCLUDE_DIR='.*/Tests/RunCMake/find_path/include'
+-- PrefixInPATH_INCLUDE_DIR='.*/Tests/RunCMake/find_path/include'
diff --git a/Tests/RunCMake/find_path/PrefixInPATH.cmake b/Tests/RunCMake/find_path/PrefixInPATH.cmake
new file mode 100644
index 000000000..614d64f1f
--- /dev/null
+++ b/Tests/RunCMake/find_path/PrefixInPATH.cmake
@@ -0,0 +1,8 @@
+set(ENV_PATH "$ENV{PATH}")
+foreach(path "/does_not_exist" "" "/bin" "/sbin")
+ unset(PrefixInPATH_INCLUDE_DIR CACHE)
+ set(ENV{PATH} "${CMAKE_CURRENT_SOURCE_DIR}${path}")
+ find_path(PrefixInPATH_INCLUDE_DIR NAMES PrefixInPATH.h)
+ message(STATUS "PrefixInPATH_INCLUDE_DIR='${PrefixInPATH_INCLUDE_DIR}'")
+endforeach()
+set(ENV{PATH} "${ENV_PATH}")
diff --git a/Tests/RunCMake/find_path/RunCMakeTest.cmake b/Tests/RunCMake/find_path/RunCMakeTest.cmake
new file mode 100644
index 000000000..014f39734
--- /dev/null
+++ b/Tests/RunCMake/find_path/RunCMakeTest.cmake
@@ -0,0 +1,3 @@
+include(RunCMake)
+
+run_cmake(PrefixInPATH)
diff --git a/Tests/RunCMake/find_path/include/PrefixInPATH.h b/Tests/RunCMake/find_path/include/PrefixInPATH.h
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/find_path/include/PrefixInPATH.h
diff --git a/Tests/RunCMake/find_program/A/testA b/Tests/RunCMake/find_program/A/testA
new file mode 100755
index 000000000..1a2485251
--- /dev/null
+++ b/Tests/RunCMake/find_program/A/testA
@@ -0,0 +1 @@
+#!/bin/sh
diff --git a/Tests/RunCMake/find_program/A/testAandB b/Tests/RunCMake/find_program/A/testAandB
new file mode 100755
index 000000000..1a2485251
--- /dev/null
+++ b/Tests/RunCMake/find_program/A/testAandB
@@ -0,0 +1 @@
+#!/bin/sh
diff --git a/Tests/RunCMake/find_program/B/testAandB b/Tests/RunCMake/find_program/B/testAandB
new file mode 100755
index 000000000..1a2485251
--- /dev/null
+++ b/Tests/RunCMake/find_program/B/testAandB
@@ -0,0 +1 @@
+#!/bin/sh
diff --git a/Tests/RunCMake/find_program/B/testB b/Tests/RunCMake/find_program/B/testB
new file mode 100755
index 000000000..1a2485251
--- /dev/null
+++ b/Tests/RunCMake/find_program/B/testB
@@ -0,0 +1 @@
+#!/bin/sh
diff --git a/Tests/RunCMake/find_program/CMakeLists.txt b/Tests/RunCMake/find_program/CMakeLists.txt
new file mode 100644
index 000000000..74b3ff8de
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.3)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/find_program/DirsPerName-stdout.txt b/Tests/RunCMake/find_program/DirsPerName-stdout.txt
new file mode 100644
index 000000000..dc1c82b5f
--- /dev/null
+++ b/Tests/RunCMake/find_program/DirsPerName-stdout.txt
@@ -0,0 +1,2 @@
+-- PROG='[^']*/Tests/RunCMake/find_program/B/testB'
+-- PROG_ABS='[^']*/Tests/RunCMake/find_program/A/testA'
diff --git a/Tests/RunCMake/find_program/DirsPerName.cmake b/Tests/RunCMake/find_program/DirsPerName.cmake
new file mode 100644
index 000000000..6db778d7e
--- /dev/null
+++ b/Tests/RunCMake/find_program/DirsPerName.cmake
@@ -0,0 +1,12 @@
+find_program(PROG
+ NAMES testB testA
+ PATHS ${CMAKE_CURRENT_SOURCE_DIR}/A ${CMAKE_CURRENT_SOURCE_DIR}/B
+ NO_DEFAULT_PATH
+ )
+message(STATUS "PROG='${PROG}'")
+
+find_program(PROG_ABS
+ NAMES ${CMAKE_CURRENT_SOURCE_DIR}/A/testA
+ NO_DEFAULT_PATH
+ )
+message(STATUS "PROG_ABS='${PROG_ABS}'")
diff --git a/Tests/RunCMake/find_program/EnvAndHints-stdout.txt b/Tests/RunCMake/find_program/EnvAndHints-stdout.txt
new file mode 100644
index 000000000..39329b22e
--- /dev/null
+++ b/Tests/RunCMake/find_program/EnvAndHints-stdout.txt
@@ -0,0 +1 @@
+-- PROG='[^']*/Tests/RunCMake/find_program/A/testAandB'
diff --git a/Tests/RunCMake/find_program/EnvAndHints.cmake b/Tests/RunCMake/find_program/EnvAndHints.cmake
new file mode 100644
index 000000000..14ebd6e2f
--- /dev/null
+++ b/Tests/RunCMake/find_program/EnvAndHints.cmake
@@ -0,0 +1,8 @@
+set(ENV_PATH "$ENV{PATH}")
+set(ENV{PATH} ${CMAKE_CURRENT_SOURCE_DIR}/A)
+find_program(PROG
+ NAMES testAandB
+ HINTS ${CMAKE_CURRENT_SOURCE_DIR}/A ${CMAKE_CURRENT_SOURCE_DIR}/B
+ )
+message(STATUS "PROG='${PROG}'")
+set(ENV{PATH} "${ENV_PATH}")
diff --git a/Tests/RunCMake/find_program/NamesPerDir-stdout.txt b/Tests/RunCMake/find_program/NamesPerDir-stdout.txt
new file mode 100644
index 000000000..fd79185ac
--- /dev/null
+++ b/Tests/RunCMake/find_program/NamesPerDir-stdout.txt
@@ -0,0 +1,2 @@
+-- PROG='[^']*/Tests/RunCMake/find_program/A/testA'
+-- PROG_ABS='[^']*/Tests/RunCMake/find_program/A/testA'
diff --git a/Tests/RunCMake/find_program/NamesPerDir.cmake b/Tests/RunCMake/find_program/NamesPerDir.cmake
new file mode 100644
index 000000000..5f00a28d0
--- /dev/null
+++ b/Tests/RunCMake/find_program/NamesPerDir.cmake
@@ -0,0 +1,12 @@
+find_program(PROG
+ NAMES testB testA NAMES_PER_DIR
+ PATHS ${CMAKE_CURRENT_SOURCE_DIR}/A ${CMAKE_CURRENT_SOURCE_DIR}/B
+ NO_DEFAULT_PATH
+ )
+message(STATUS "PROG='${PROG}'")
+
+find_program(PROG_ABS
+ NAMES ${CMAKE_CURRENT_SOURCE_DIR}/A/testA NAMES_PER_DIR
+ NO_DEFAULT_PATH
+ )
+message(STATUS "PROG_ABS='${PROG_ABS}'")
diff --git a/Tests/RunCMake/find_program/RunCMakeTest.cmake b/Tests/RunCMake/find_program/RunCMakeTest.cmake
new file mode 100644
index 000000000..89307c1ae
--- /dev/null
+++ b/Tests/RunCMake/find_program/RunCMakeTest.cmake
@@ -0,0 +1,10 @@
+include(RunCMake)
+
+run_cmake(EnvAndHints)
+run_cmake(DirsPerName)
+run_cmake(NamesPerDir)
+
+if(CMAKE_SYSTEM_NAME MATCHES "^(Windows|CYGWIN)$")
+ run_cmake(WindowsCom)
+ run_cmake(WindowsExe)
+endif()
diff --git a/Tests/RunCMake/find_program/Win/testCom.com b/Tests/RunCMake/find_program/Win/testCom.com
new file mode 100755
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/find_program/Win/testCom.com
diff --git a/Tests/RunCMake/find_program/Win/testCom.exe b/Tests/RunCMake/find_program/Win/testCom.exe
new file mode 100755
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/find_program/Win/testCom.exe
diff --git a/Tests/RunCMake/find_program/Win/testExe.exe b/Tests/RunCMake/find_program/Win/testExe.exe
new file mode 100755
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/find_program/Win/testExe.exe
diff --git a/Tests/RunCMake/find_program/WindowsCom-stdout.txt b/Tests/RunCMake/find_program/WindowsCom-stdout.txt
new file mode 100644
index 000000000..e386fce50
--- /dev/null
+++ b/Tests/RunCMake/find_program/WindowsCom-stdout.txt
@@ -0,0 +1 @@
+-- PROG='[^']*/Tests/RunCMake/find_program/Win/testCom.com'
diff --git a/Tests/RunCMake/find_program/WindowsCom.cmake b/Tests/RunCMake/find_program/WindowsCom.cmake
new file mode 100644
index 000000000..b32d9e851
--- /dev/null
+++ b/Tests/RunCMake/find_program/WindowsCom.cmake
@@ -0,0 +1,6 @@
+find_program(PROG
+ NAMES testCom
+ PATHS ${CMAKE_CURRENT_SOURCE_DIR}/Win
+ NO_DEFAULT_PATH
+ )
+message(STATUS "PROG='${PROG}'")
diff --git a/Tests/RunCMake/find_program/WindowsExe-stdout.txt b/Tests/RunCMake/find_program/WindowsExe-stdout.txt
new file mode 100644
index 000000000..bdf48aadb
--- /dev/null
+++ b/Tests/RunCMake/find_program/WindowsExe-stdout.txt
@@ -0,0 +1 @@
+-- PROG='[^']*/Tests/RunCMake/find_program/Win/testExe.exe'
diff --git a/Tests/RunCMake/find_program/WindowsExe.cmake b/Tests/RunCMake/find_program/WindowsExe.cmake
new file mode 100644
index 000000000..3a336ec61
--- /dev/null
+++ b/Tests/RunCMake/find_program/WindowsExe.cmake
@@ -0,0 +1,6 @@
+find_program(PROG
+ NAMES testExe
+ PATHS ${CMAKE_CURRENT_SOURCE_DIR}/Win
+ NO_DEFAULT_PATH
+ )
+message(STATUS "PROG='${PROG}'")
diff --git a/Tests/RunCMake/get_filename_component/CMakeLists.txt b/Tests/RunCMake/get_filename_component/CMakeLists.txt
index 12cd3c775..74b3ff8de 100644
--- a/Tests/RunCMake/get_filename_component/CMakeLists.txt
+++ b/Tests/RunCMake/get_filename_component/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/get_filename_component/KnownComponents.cmake b/Tests/RunCMake/get_filename_component/KnownComponents.cmake
index 9d7cf9079..d82225864 100644
--- a/Tests/RunCMake/get_filename_component/KnownComponents.cmake
+++ b/Tests/RunCMake/get_filename_component/KnownComponents.cmake
@@ -1,9 +1,11 @@
+# Assertion macro
macro(check desc actual expect)
if(NOT "x${actual}" STREQUAL "x${expect}")
message(SEND_ERROR "${desc}: got \"${actual}\", not \"${expect}\"")
endif()
endmacro()
+# General test of all component types given an absolute path.
set(filename "/path/to/filename.ext.in")
set(expect_DIRECTORY "/path/to")
set(expect_NAME "filename.ext.in")
@@ -13,14 +15,19 @@ set(expect_PATH "/path/to")
foreach(c DIRECTORY NAME EXT NAME_WE PATH)
get_filename_component(actual_${c} "${filename}" ${c})
check("${c}" "${actual_${c}}" "${expect_${c}}")
+ list(APPEND non_cache_vars actual_${c})
endforeach()
+# Test Windows paths with DIRECTORY component and an absolute Windows path.
get_filename_component(test_slashes "c:\\path\\to\\filename.ext.in" DIRECTORY)
check("DIRECTORY from backslashes" "${test_slashes}" "c:/path/to")
+list(APPEND non_cache_vars test_slashes)
get_filename_component(test_winroot "c:\\filename.ext.in" DIRECTORY)
check("DIRECTORY in windows root" "${test_winroot}" "c:/")
+list(APPEND non_cache_vars test_winroot)
+# Test finding absolute paths.
get_filename_component(test_absolute "/path/to/a/../filename.ext.in" ABSOLUTE)
check("ABSOLUTE" "${test_absolute}" "/path/to/filename.ext.in")
@@ -29,10 +36,113 @@ check("ABSOLUTE .. in root" "${test_absolute}" "/path/to/filename.ext.in")
get_filename_component(test_absolute "c:/../path/to/filename.ext.in" ABSOLUTE)
check("ABSOLUTE .. in windows root" "${test_absolute}" "c:/path/to/filename.ext.in")
+list(APPEND non_cache_vars test_absolute)
+
+# Test finding absolute paths from various base directories.
+
+get_filename_component(test_abs_base "testdir1" ABSOLUTE)
+check("ABSOLUTE .. from default base" "${test_abs_base}"
+ "${CMAKE_CURRENT_SOURCE_DIR}/testdir1")
+
+get_filename_component(test_abs_base "../testdir2" ABSOLUTE
+ BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dummydir")
+check("ABSOLUTE .. from dummy base to parent" "${test_abs_base}"
+ "${CMAKE_CURRENT_SOURCE_DIR}/testdir2")
+
+get_filename_component(test_abs_base "testdir3" ABSOLUTE
+ BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dummydir")
+check("ABSOLUTE .. from dummy base to child" "${test_abs_base}"
+ "${CMAKE_CURRENT_SOURCE_DIR}/dummydir/testdir3")
+
+list(APPEND non_cache_vars test_abs_base)
+
+# Test finding absolute paths with CACHE parameter. (Note that more
+# rigorous testing of the CACHE parameter comes later with PROGRAM).
+
+get_filename_component(test_abs_base_1 "testdir4" ABSOLUTE CACHE)
+check("ABSOLUTE CACHE 1" "${test_abs_base_1}"
+ "${CMAKE_CURRENT_SOURCE_DIR}/testdir4")
+list(APPEND cache_vars test_abs_base_1)
+
+get_filename_component(test_abs_base_2 "testdir5" ABSOLUTE
+ BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dummydir"
+ CACHE)
+check("ABSOLUTE CACHE 2" "${test_abs_base_2}"
+ "${CMAKE_CURRENT_SOURCE_DIR}/dummydir/testdir5")
+list(APPEND cache_vars test_abs_base_2)
+
+# Test the PROGRAM component type.
+get_filename_component(test_program_name "/ arg1 arg2" PROGRAM)
+check("PROGRAM with no args output" "${test_program_name}" "/")
+
+get_filename_component(test_program_name "/ arg1 arg2" PROGRAM
+ PROGRAM_ARGS test_program_args)
+check("PROGRAM with args output: name" "${test_program_name}" "/")
+check("PROGRAM with args output: args" "${test_program_args}" " arg1 arg2")
+
+list(APPEND non_cache_vars test_program_name)
+list(APPEND non_cache_vars test_program_args)
+
+# Test CACHE parameter for most component types.
get_filename_component(test_cache "/path/to/filename.ext.in" DIRECTORY CACHE)
check("CACHE 1" "${test_cache}" "/path/to")
+# Make sure that the existing CACHE entry from previous is honored:
get_filename_component(test_cache "/path/to/other/filename.ext.in" DIRECTORY CACHE)
check("CACHE 2" "${test_cache}" "/path/to")
unset(test_cache CACHE)
get_filename_component(test_cache "/path/to/other/filename.ext.in" DIRECTORY CACHE)
check("CACHE 3" "${test_cache}" "/path/to/other")
+
+list(APPEND cache_vars test_cache)
+
+# Test the PROGRAM component type with CACHE specified.
+
+# 1. Make sure it makes a cache variable in the first place for basic usage:
+get_filename_component(test_cache_program_name_1 "/ arg1 arg2" PROGRAM CACHE)
+check("PROGRAM CACHE 1 with no args output" "${test_cache_program_name_1}" "/")
+list(APPEND cache_vars test_cache_program_name_1)
+
+# 2. Set some existing cache variables & make sure the function returns them:
+set(test_cache_program_name_2 DummyProgramName CACHE FILEPATH "")
+get_filename_component(test_cache_program_name_2 "/ arg1 arg2" PROGRAM CACHE)
+check("PROGRAM CACHE 2 with no args output" "${test_cache_program_name_2}"
+ "DummyProgramName")
+list(APPEND cache_vars test_cache_program_name_2)
+
+# 3. Now test basic usage when PROGRAM_ARGS is used:
+get_filename_component(test_cache_program_name_3 "/ arg1 arg2" PROGRAM
+ PROGRAM_ARGS test_cache_program_args_3 CACHE)
+check("PROGRAM CACHE 3 name" "${test_cache_program_name_3}" "/")
+check("PROGRAM CACHE 3 args" "${test_cache_program_args_3}" " arg1 arg2")
+list(APPEND cache_vars test_cache_program_name_3)
+list(APPEND cache_vars test_cache_program_args_3)
+
+# 4. Test that existing cache variables are returned when PROGRAM_ARGS is used:
+set(test_cache_program_name_4 DummyPgm CACHE FILEPATH "")
+set(test_cache_program_args_4 DummyArgs CACHE STRING "")
+get_filename_component(test_cache_program_name_4 "/ arg1 arg2" PROGRAM
+ PROGRAM_ARGS test_cache_program_args_4 CACHE)
+check("PROGRAM CACHE 4 name" "${test_cache_program_name_4}" "DummyPgm")
+check("PROGRAM CACHE 4 args" "${test_cache_program_args_4}" "DummyArgs")
+list(APPEND cache_vars test_cache_program_name_4)
+list(APPEND cache_vars test_cache_program_name_4)
+
+# Test that ONLY the expected cache variables were created.
+get_cmake_property(current_cache_vars CACHE_VARIABLES)
+get_cmake_property(current_vars VARIABLES)
+
+foreach(thisVar ${cache_vars})
+ if(NOT thisVar IN_LIST current_cache_vars)
+ message(SEND_ERROR "${thisVar} expected in cache but was not found.")
+ endif()
+endforeach()
+
+foreach(thisVar ${non_cache_vars})
+ if(thisVar IN_LIST current_cache_vars)
+ message(SEND_ERROR "${thisVar} unexpectedly found in cache.")
+ endif()
+ if(NOT thisVar IN_LIST current_vars)
+ # Catch likely typo when appending to non_cache_vars:
+ message(SEND_ERROR "${thisVar} not found in regular variable list.")
+ endif()
+endforeach()
diff --git a/Tests/RunCMake/get_property/BadArgument-result.txt b/Tests/RunCMake/get_property/BadArgument-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/get_property/BadArgument-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/get_property/BadArgument-stderr.txt b/Tests/RunCMake/get_property/BadArgument-stderr.txt
new file mode 100644
index 000000000..37c44775c
--- /dev/null
+++ b/Tests/RunCMake/get_property/BadArgument-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at BadArgument.cmake:1 \(get_property\):
+ get_property given invalid argument "FOO".
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/GetProperty-Bad-Argument.cmake b/Tests/RunCMake/get_property/BadArgument.cmake
index 382dabb50..382dabb50 100644
--- a/Tests/CMakeTests/GetProperty-Bad-Argument.cmake
+++ b/Tests/RunCMake/get_property/BadArgument.cmake
diff --git a/Tests/RunCMake/get_property/BadDirectory-result.txt b/Tests/RunCMake/get_property/BadDirectory-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/get_property/BadDirectory-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/get_property/BadDirectory-stderr.txt b/Tests/RunCMake/get_property/BadDirectory-stderr.txt
new file mode 100644
index 000000000..98464f8dc
--- /dev/null
+++ b/Tests/RunCMake/get_property/BadDirectory-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Error at BadDirectory.cmake:1 \(get_property\):
+ get_property DIRECTORY scope provided but requested directory was not
+ found. This could be because the directory argument was invalid or, it is
+ valid but has not been processed yet.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/GetProperty-Bad-Directory.cmake b/Tests/RunCMake/get_property/BadDirectory.cmake
index cdbfa807c..cdbfa807c 100644
--- a/Tests/CMakeTests/GetProperty-Bad-Directory.cmake
+++ b/Tests/RunCMake/get_property/BadDirectory.cmake
diff --git a/Tests/RunCMake/get_property/BadScope-result.txt b/Tests/RunCMake/get_property/BadScope-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/get_property/BadScope-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/get_property/BadScope-stderr.txt b/Tests/RunCMake/get_property/BadScope-stderr.txt
new file mode 100644
index 000000000..4cc32c87b
--- /dev/null
+++ b/Tests/RunCMake/get_property/BadScope-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at BadScope.cmake:1 \(get_property\):
+ get_property given invalid scope FOO. Valid scopes are GLOBAL, DIRECTORY,
+ TARGET, SOURCE, TEST, VARIABLE, CACHE, INSTALL.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/GetProperty-Bad-Scope.cmake b/Tests/RunCMake/get_property/BadScope.cmake
index ea8566b50..ea8566b50 100644
--- a/Tests/CMakeTests/GetProperty-Bad-Scope.cmake
+++ b/Tests/RunCMake/get_property/BadScope.cmake
diff --git a/Tests/RunCMake/get_property/BadTarget-result.txt b/Tests/RunCMake/get_property/BadTarget-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/get_property/BadTarget-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/get_property/BadTarget-stderr.txt b/Tests/RunCMake/get_property/BadTarget-stderr.txt
new file mode 100644
index 000000000..45a0df6c9
--- /dev/null
+++ b/Tests/RunCMake/get_property/BadTarget-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at BadTarget.cmake:1 \(get_property\):
+ get_property could not find TARGET FOO. Perhaps it has not yet been
+ created.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/GetProperty-Bad-Target.cmake b/Tests/RunCMake/get_property/BadTarget.cmake
index 9992dabed..9992dabed 100644
--- a/Tests/CMakeTests/GetProperty-Bad-Target.cmake
+++ b/Tests/RunCMake/get_property/BadTarget.cmake
diff --git a/Tests/RunCMake/get_property/BadTest-result.txt b/Tests/RunCMake/get_property/BadTest-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/get_property/BadTest-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/get_property/BadTest-stderr.txt b/Tests/RunCMake/get_property/BadTest-stderr.txt
new file mode 100644
index 000000000..819c0704a
--- /dev/null
+++ b/Tests/RunCMake/get_property/BadTest-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at BadTest.cmake:1 \(get_property\):
+ get_property given TEST name that does not exist: FOO
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/GetProperty-Bad-Test.cmake b/Tests/RunCMake/get_property/BadTest.cmake
index 44bf3ebc5..44bf3ebc5 100644
--- a/Tests/CMakeTests/GetProperty-Bad-Test.cmake
+++ b/Tests/RunCMake/get_property/BadTest.cmake
diff --git a/Tests/RunCMake/get_property/CMakeLists.txt b/Tests/RunCMake/get_property/CMakeLists.txt
new file mode 100644
index 000000000..12cd3c775
--- /dev/null
+++ b/Tests/RunCMake/get_property/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/get_property/DebugConfigurations-stderr.txt b/Tests/RunCMake/get_property/DebugConfigurations-stderr.txt
new file mode 100644
index 000000000..b2956043c
--- /dev/null
+++ b/Tests/RunCMake/get_property/DebugConfigurations-stderr.txt
@@ -0,0 +1,11 @@
+CONFIGS:
+IFACE1:\$<\$<CONFIG:DEBUG>:external1>
+CONFIGS:EXTRA
+IFACE1:\$<\$<CONFIG:DEBUG>:external1>
+IFACE1:\$<\$<CONFIG:DEBUG>:external1>;\$<\$<CONFIG:EXTRA>:external2>
+CONFIGS:NEW;CONFIGS
+IFACE1:\$<\$<CONFIG:DEBUG>:external1>;\$<\$<CONFIG:EXTRA>:external2>
+IFACE1:\$<\$<CONFIG:DEBUG>:external1>;\$<\$<CONFIG:EXTRA>:external2>;\$<\$<OR:\$<CONFIG:NEW>,\$<CONFIG:CONFIGS>>:external3>
+CONFIGS:NEW;CONFIGS;EXTRA
+IFACE1:\$<\$<CONFIG:DEBUG>:external1>;\$<\$<CONFIG:EXTRA>:external2>;\$<\$<OR:\$<CONFIG:NEW>,\$<CONFIG:CONFIGS>>:external3>
+IFACE1:\$<\$<CONFIG:DEBUG>:external1>;\$<\$<CONFIG:EXTRA>:external2>;\$<\$<OR:\$<CONFIG:NEW>,\$<CONFIG:CONFIGS>>:external3>;\$<\$<OR:\$<CONFIG:NEW>,\$<CONFIG:CONFIGS>,\$<CONFIG:EXTRA>>:external4>
diff --git a/Tests/RunCMake/get_property/DebugConfigurations.cmake b/Tests/RunCMake/get_property/DebugConfigurations.cmake
new file mode 100644
index 000000000..534beafcd
--- /dev/null
+++ b/Tests/RunCMake/get_property/DebugConfigurations.cmake
@@ -0,0 +1,41 @@
+
+enable_language(CXX)
+
+get_property(configs GLOBAL PROPERTY DEBUG_CONFIGURATIONS)
+message("CONFIGS:${configs}")
+
+add_library(iface1 INTERFACE)
+target_link_libraries(iface1 INTERFACE debug external1)
+
+get_property(tgt_iface TARGET iface1 PROPERTY INTERFACE_LINK_LIBRARIES)
+message("IFACE1:${tgt_iface}")
+
+set_property(GLOBAL APPEND PROPERTY DEBUG_CONFIGURATIONS EXTRA)
+get_property(configs GLOBAL PROPERTY DEBUG_CONFIGURATIONS)
+message("CONFIGS:${configs}")
+
+get_property(tgt_iface TARGET iface1 PROPERTY INTERFACE_LINK_LIBRARIES)
+message("IFACE1:${tgt_iface}")
+target_link_libraries(iface1 INTERFACE debug external2)
+get_property(tgt_iface TARGET iface1 PROPERTY INTERFACE_LINK_LIBRARIES)
+message("IFACE1:${tgt_iface}")
+
+set_property(GLOBAL PROPERTY DEBUG_CONFIGURATIONS NEW CONFIGS)
+get_property(configs GLOBAL PROPERTY DEBUG_CONFIGURATIONS)
+message("CONFIGS:${configs}")
+
+get_property(tgt_iface TARGET iface1 PROPERTY INTERFACE_LINK_LIBRARIES)
+message("IFACE1:${tgt_iface}")
+target_link_libraries(iface1 INTERFACE debug external3)
+get_property(tgt_iface TARGET iface1 PROPERTY INTERFACE_LINK_LIBRARIES)
+message("IFACE1:${tgt_iface}")
+
+set_property(GLOBAL APPEND PROPERTY DEBUG_CONFIGURATIONS EXTRA)
+get_property(configs GLOBAL PROPERTY DEBUG_CONFIGURATIONS)
+message("CONFIGS:${configs}")
+
+get_property(tgt_iface TARGET iface1 PROPERTY INTERFACE_LINK_LIBRARIES)
+message("IFACE1:${tgt_iface}")
+target_link_libraries(iface1 INTERFACE debug external4)
+get_property(tgt_iface TARGET iface1 PROPERTY INTERFACE_LINK_LIBRARIES)
+message("IFACE1:${tgt_iface}")
diff --git a/Tests/RunCMake/get_property/GlobalName-result.txt b/Tests/RunCMake/get_property/GlobalName-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/get_property/GlobalName-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/get_property/GlobalName-stderr.txt b/Tests/RunCMake/get_property/GlobalName-stderr.txt
new file mode 100644
index 000000000..a7d4971c2
--- /dev/null
+++ b/Tests/RunCMake/get_property/GlobalName-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at GlobalName.cmake:1 \(get_property\):
+ get_property given name for GLOBAL scope.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/GetProperty-Global-Name.cmake b/Tests/RunCMake/get_property/GlobalName.cmake
index 497700cb3..497700cb3 100644
--- a/Tests/CMakeTests/GetProperty-Global-Name.cmake
+++ b/Tests/RunCMake/get_property/GlobalName.cmake
diff --git a/Tests/RunCMake/get_property/MissingArgument-result.txt b/Tests/RunCMake/get_property/MissingArgument-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/get_property/MissingArgument-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/get_property/MissingArgument-stderr.txt b/Tests/RunCMake/get_property/MissingArgument-stderr.txt
new file mode 100644
index 000000000..87227127a
--- /dev/null
+++ b/Tests/RunCMake/get_property/MissingArgument-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at MissingArgument.cmake:1 \(get_property\):
+ get_property called with incorrect number of arguments
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/GetProperty-Missing-Argument.cmake b/Tests/RunCMake/get_property/MissingArgument.cmake
index f0d004dc4..f0d004dc4 100644
--- a/Tests/CMakeTests/GetProperty-Missing-Argument.cmake
+++ b/Tests/RunCMake/get_property/MissingArgument.cmake
diff --git a/Tests/RunCMake/get_property/NoCache-result.txt b/Tests/RunCMake/get_property/NoCache-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/get_property/NoCache-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/get_property/NoCache-stderr.txt b/Tests/RunCMake/get_property/NoCache-stderr.txt
new file mode 100644
index 000000000..defafb62d
--- /dev/null
+++ b/Tests/RunCMake/get_property/NoCache-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at NoCache.cmake:1 \(get_property\):
+ get_property not given name for CACHE scope.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/GetProperty-No-Cache.cmake b/Tests/RunCMake/get_property/NoCache.cmake
index 9719fe775..9719fe775 100644
--- a/Tests/CMakeTests/GetProperty-No-Cache.cmake
+++ b/Tests/RunCMake/get_property/NoCache.cmake
diff --git a/Tests/RunCMake/get_property/NoProperty-result.txt b/Tests/RunCMake/get_property/NoProperty-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/get_property/NoProperty-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/get_property/NoProperty-stderr.txt b/Tests/RunCMake/get_property/NoProperty-stderr.txt
new file mode 100644
index 000000000..0ef147fdb
--- /dev/null
+++ b/Tests/RunCMake/get_property/NoProperty-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at NoProperty.cmake:1 \(get_property\):
+ get_property not given a PROPERTY <name> argument.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/GetProperty-No-Property.cmake b/Tests/RunCMake/get_property/NoProperty.cmake
index bee230d9b..bee230d9b 100644
--- a/Tests/CMakeTests/GetProperty-No-Property.cmake
+++ b/Tests/RunCMake/get_property/NoProperty.cmake
diff --git a/Tests/RunCMake/get_property/NoSource-result.txt b/Tests/RunCMake/get_property/NoSource-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/get_property/NoSource-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/get_property/NoSource-stderr.txt b/Tests/RunCMake/get_property/NoSource-stderr.txt
new file mode 100644
index 000000000..59fd0add7
--- /dev/null
+++ b/Tests/RunCMake/get_property/NoSource-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at NoSource.cmake:1 \(get_property\):
+ get_property not given name for SOURCE scope.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/GetProperty-No-Source.cmake b/Tests/RunCMake/get_property/NoSource.cmake
index 89773c810..89773c810 100644
--- a/Tests/CMakeTests/GetProperty-No-Source.cmake
+++ b/Tests/RunCMake/get_property/NoSource.cmake
diff --git a/Tests/RunCMake/get_property/NoTarget-result.txt b/Tests/RunCMake/get_property/NoTarget-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/get_property/NoTarget-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/get_property/NoTarget-stderr.txt b/Tests/RunCMake/get_property/NoTarget-stderr.txt
new file mode 100644
index 000000000..a0e1a9440
--- /dev/null
+++ b/Tests/RunCMake/get_property/NoTarget-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at NoTarget.cmake:1 \(get_property\):
+ get_property not given name for TARGET scope.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/GetProperty-No-Target.cmake b/Tests/RunCMake/get_property/NoTarget.cmake
index 8f1fa23af..8f1fa23af 100644
--- a/Tests/CMakeTests/GetProperty-No-Target.cmake
+++ b/Tests/RunCMake/get_property/NoTarget.cmake
diff --git a/Tests/RunCMake/get_property/NoTest-result.txt b/Tests/RunCMake/get_property/NoTest-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/get_property/NoTest-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/get_property/NoTest-stderr.txt b/Tests/RunCMake/get_property/NoTest-stderr.txt
new file mode 100644
index 000000000..c90a0ffc2
--- /dev/null
+++ b/Tests/RunCMake/get_property/NoTest-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at NoTest.cmake:1 \(get_property\):
+ get_property not given name for TEST scope.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/GetProperty-No-Test.cmake b/Tests/RunCMake/get_property/NoTest.cmake
index 045bd56ec..045bd56ec 100644
--- a/Tests/CMakeTests/GetProperty-No-Test.cmake
+++ b/Tests/RunCMake/get_property/NoTest.cmake
diff --git a/Tests/RunCMake/get_property/RunCMakeTest.cmake b/Tests/RunCMake/get_property/RunCMakeTest.cmake
new file mode 100644
index 000000000..00eef34c0
--- /dev/null
+++ b/Tests/RunCMake/get_property/RunCMakeTest.cmake
@@ -0,0 +1,24 @@
+include(RunCMake)
+
+run_cmake(cache_properties)
+run_cmake(directory_properties)
+run_cmake(global_properties)
+run_cmake(install_properties)
+run_cmake(source_properties)
+run_cmake(target_properties)
+run_cmake(test_properties)
+run_cmake(DebugConfigurations)
+
+run_cmake(MissingArgument)
+run_cmake(GlobalName)
+run_cmake(BadTest)
+run_cmake(BadTarget)
+run_cmake(BadScope)
+run_cmake(BadDirectory)
+run_cmake(BadArgument)
+run_cmake(VariableName)
+run_cmake(NoTest)
+run_cmake(NoTarget)
+run_cmake(NoSource)
+run_cmake(NoProperty)
+run_cmake(NoCache)
diff --git a/Tests/RunCMake/get_property/VariableName-result.txt b/Tests/RunCMake/get_property/VariableName-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/get_property/VariableName-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/get_property/VariableName-stderr.txt b/Tests/RunCMake/get_property/VariableName-stderr.txt
new file mode 100644
index 000000000..e9f382759
--- /dev/null
+++ b/Tests/RunCMake/get_property/VariableName-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at VariableName.cmake:1 \(get_property\):
+ get_property given name for VARIABLE scope.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/GetProperty-Variable-Name.cmake b/Tests/RunCMake/get_property/VariableName.cmake
index 9190f80ad..9190f80ad 100644
--- a/Tests/CMakeTests/GetProperty-Variable-Name.cmake
+++ b/Tests/RunCMake/get_property/VariableName.cmake
diff --git a/Tests/RunCMake/get_property/cache_properties-stderr.txt b/Tests/RunCMake/get_property/cache_properties-stderr.txt
new file mode 100644
index 000000000..ee019c611
--- /dev/null
+++ b/Tests/RunCMake/get_property/cache_properties-stderr.txt
@@ -0,0 +1,3 @@
+^get_property: --><--
+get_property: -->TRUE<--
+get_property: --><--$
diff --git a/Tests/RunCMake/get_property/cache_properties.cmake b/Tests/RunCMake/get_property/cache_properties.cmake
new file mode 100644
index 000000000..bf3e7abe9
--- /dev/null
+++ b/Tests/RunCMake/get_property/cache_properties.cmake
@@ -0,0 +1,15 @@
+function (check_cache_property var prop)
+ get_property(gp_val
+ CACHE "${var}"
+ PROPERTY "${prop}")
+
+ message("get_property: -->${gp_val}<--")
+endfunction ()
+
+set(var val CACHE STRING "doc")
+set_property(CACHE var PROPERTY VALUE "") # empty
+set_property(CACHE var PROPERTY ADVANCED TRUE)
+
+check_cache_property(var VALUE)
+check_cache_property(var ADVANCED)
+check_cache_property(var noexist)
diff --git a/Tests/RunCMake/get_property/directory_properties-stderr.txt b/Tests/RunCMake/get_property/directory_properties-stderr.txt
new file mode 100644
index 000000000..80c9877ab
--- /dev/null
+++ b/Tests/RunCMake/get_property/directory_properties-stderr.txt
@@ -0,0 +1,6 @@
+^get_directory_property: --><--
+get_property: --><--
+get_directory_property: -->value<--
+get_property: -->value<--
+get_directory_property: --><--
+get_property: --><--$
diff --git a/Tests/RunCMake/get_property/directory_properties.cmake b/Tests/RunCMake/get_property/directory_properties.cmake
new file mode 100644
index 000000000..b0a9b1b6d
--- /dev/null
+++ b/Tests/RunCMake/get_property/directory_properties.cmake
@@ -0,0 +1,15 @@
+function (check_directory_property dir prop)
+ get_directory_property(gdp_val DIRECTORY "${dir}" "${prop}")
+ get_property(gp_val
+ DIRECTORY "${dir}"
+ PROPERTY "${prop}")
+
+ message("get_directory_property: -->${gdp_val}<--")
+ message("get_property: -->${gp_val}<--")
+endfunction ()
+
+set_directory_properties(PROPERTIES empty "" custom value)
+
+check_directory_property("${CMAKE_CURRENT_SOURCE_DIR}" empty)
+check_directory_property("${CMAKE_CURRENT_SOURCE_DIR}" custom)
+check_directory_property("${CMAKE_CURRENT_SOURCE_DIR}" noexist)
diff --git a/Tests/RunCMake/get_property/global_properties-stderr.txt b/Tests/RunCMake/get_property/global_properties-stderr.txt
new file mode 100644
index 000000000..4c08ad71d
--- /dev/null
+++ b/Tests/RunCMake/get_property/global_properties-stderr.txt
@@ -0,0 +1,6 @@
+^get_cmake_property: --><--
+get_property: --><--
+get_cmake_property: -->value<--
+get_property: -->value<--
+get_cmake_property: -->NOTFOUND<--
+get_property: --><--$
diff --git a/Tests/RunCMake/get_property/global_properties.cmake b/Tests/RunCMake/get_property/global_properties.cmake
new file mode 100644
index 000000000..20731360b
--- /dev/null
+++ b/Tests/RunCMake/get_property/global_properties.cmake
@@ -0,0 +1,16 @@
+function (check_global_property prop)
+ get_cmake_property(gcp_val "${prop}")
+ get_property(gp_val
+ GLOBAL
+ PROPERTY "${prop}")
+
+ message("get_cmake_property: -->${gcp_val}<--")
+ message("get_property: -->${gp_val}<--")
+endfunction ()
+
+set_property(GLOBAL PROPERTY empty "")
+set_property(GLOBAL PROPERTY custom value)
+
+check_global_property(empty)
+check_global_property(custom)
+check_global_property(noexist)
diff --git a/Tests/RunCMake/get_property/install_properties-stderr.txt b/Tests/RunCMake/get_property/install_properties-stderr.txt
new file mode 100644
index 000000000..b1a29872e
--- /dev/null
+++ b/Tests/RunCMake/get_property/install_properties-stderr.txt
@@ -0,0 +1,3 @@
+^get_property: --><--
+get_property: -->value<--
+get_property: --><--$
diff --git a/Tests/RunCMake/get_property/install_properties.cmake b/Tests/RunCMake/get_property/install_properties.cmake
new file mode 100644
index 000000000..aa8922594
--- /dev/null
+++ b/Tests/RunCMake/get_property/install_properties.cmake
@@ -0,0 +1,18 @@
+function (check_install_property file prop)
+ get_property(gp_val
+ INSTALL "${file}"
+ PROPERTY "${prop}")
+
+ message("get_property: -->${gp_val}<--")
+endfunction ()
+
+install(
+ FILES "${CMAKE_CURRENT_LIST_FILE}"
+ DESTINATION "${CMAKE_CURRENT_LIST_DIR}"
+ RENAME "installed-file-dest")
+set_property(INSTALL "${CMAKE_CURRENT_LIST_FILE}" PROPERTY empty "")
+set_property(INSTALL "${CMAKE_CURRENT_LIST_FILE}" PROPERTY custom value)
+
+check_install_property("${CMAKE_CURRENT_LIST_FILE}" empty)
+check_install_property("${CMAKE_CURRENT_LIST_FILE}" custom)
+check_install_property("${CMAKE_CURRENT_LIST_FILE}" noexist)
diff --git a/Tests/RunCMake/get_property/source_properties-stderr.txt b/Tests/RunCMake/get_property/source_properties-stderr.txt
new file mode 100644
index 000000000..0a46f96a0
--- /dev/null
+++ b/Tests/RunCMake/get_property/source_properties-stderr.txt
@@ -0,0 +1,6 @@
+^get_source_file_property: --><--
+get_property: --><--
+get_source_file_property: -->value<--
+get_property: -->value<--
+get_source_file_property: -->NOTFOUND<--
+get_property: --><--$
diff --git a/Tests/RunCMake/get_property/source_properties.cmake b/Tests/RunCMake/get_property/source_properties.cmake
new file mode 100644
index 000000000..263ffe123
--- /dev/null
+++ b/Tests/RunCMake/get_property/source_properties.cmake
@@ -0,0 +1,15 @@
+function (check_source_file_property file prop)
+ get_source_file_property(gsfp_val "${file}" "${prop}")
+ get_property(gp_val
+ SOURCE "${file}"
+ PROPERTY "${prop}")
+
+ message("get_source_file_property: -->${gsfp_val}<--")
+ message("get_property: -->${gp_val}<--")
+endfunction ()
+
+set_source_files_properties(file.c PROPERTIES empty "" custom value)
+
+check_source_file_property(file.c empty)
+check_source_file_property(file.c custom)
+check_source_file_property(file.c noexist)
diff --git a/Tests/RunCMake/get_property/target_properties-stderr.txt b/Tests/RunCMake/get_property/target_properties-stderr.txt
new file mode 100644
index 000000000..6b3c6ca1b
--- /dev/null
+++ b/Tests/RunCMake/get_property/target_properties-stderr.txt
@@ -0,0 +1,10 @@
+^get_target_property: --><--
+get_property: --><--
+get_target_property: -->value<--
+get_property: -->value<--
+get_target_property: -->gtp_val-NOTFOUND<--
+get_property: --><--
+get_target_property: -->(.*)/Tests/RunCMake/get_property<--
+get_property: -->(.*)/Tests/RunCMake/get_property<--
+get_target_property: -->(.*)/Tests/RunCMake/get_property/target_properties-build<--
+get_property: -->(.*)/Tests/RunCMake/get_property/target_properties-build<--$
diff --git a/Tests/RunCMake/get_property/target_properties.cmake b/Tests/RunCMake/get_property/target_properties.cmake
new file mode 100644
index 000000000..9ff833a67
--- /dev/null
+++ b/Tests/RunCMake/get_property/target_properties.cmake
@@ -0,0 +1,18 @@
+function (check_target_property target prop)
+ get_target_property(gtp_val "${target}" "${prop}")
+ get_property(gp_val
+ TARGET "${target}"
+ PROPERTY "${prop}")
+
+ message("get_target_property: -->${gtp_val}<--")
+ message("get_property: -->${gp_val}<--")
+endfunction ()
+
+add_custom_target(tgt)
+set_target_properties(tgt PROPERTIES empty "" custom value)
+
+check_target_property(tgt empty)
+check_target_property(tgt custom)
+check_target_property(tgt noexist)
+check_target_property(tgt SOURCE_DIR)
+check_target_property(tgt BINARY_DIR)
diff --git a/Tests/RunCMake/get_property/test_properties-stderr.txt b/Tests/RunCMake/get_property/test_properties-stderr.txt
new file mode 100644
index 000000000..a44728051
--- /dev/null
+++ b/Tests/RunCMake/get_property/test_properties-stderr.txt
@@ -0,0 +1,6 @@
+^get_test_property: --><--
+get_property: --><--
+get_test_property: -->value<--
+get_property: -->value<--
+get_test_property: -->NOTFOUND<--
+get_property: --><--$
diff --git a/Tests/RunCMake/get_property/test_properties.cmake b/Tests/RunCMake/get_property/test_properties.cmake
new file mode 100644
index 000000000..1d0295ca7
--- /dev/null
+++ b/Tests/RunCMake/get_property/test_properties.cmake
@@ -0,0 +1,17 @@
+function (check_test_property test prop)
+ get_test_property("${test}" "${prop}" gtp_val)
+ get_property(gp_val
+ TEST "${test}"
+ PROPERTY "${prop}")
+
+ message("get_test_property: -->${gtp_val}<--")
+ message("get_property: -->${gp_val}<--")
+endfunction ()
+
+include(CTest)
+add_test(NAME test COMMAND "${CMAKE_COMMAND}" --help)
+set_tests_properties(test PROPERTIES empty "" custom value)
+
+check_test_property(test empty)
+check_test_property(test custom)
+check_test_property(test noexist)
diff --git a/Tests/RunCMake/if/InvalidArgument1-result.txt b/Tests/RunCMake/if/InvalidArgument1-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/if/InvalidArgument1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/if/InvalidArgument1-stderr.txt b/Tests/RunCMake/if/InvalidArgument1-stderr.txt
new file mode 100644
index 000000000..bf2a994e1
--- /dev/null
+++ b/Tests/RunCMake/if/InvalidArgument1-stderr.txt
@@ -0,0 +1,8 @@
+^CMake Error at InvalidArgument1.cmake:1 \(if\):
+ if given arguments:
+
+ "NOT" "foo" "bar" "STREQUAL" "foo bar"
+
+ Unknown arguments specified
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/If-Invalid-Argument.cmake b/Tests/RunCMake/if/InvalidArgument1.cmake
index b4fb97f41..b4fb97f41 100644
--- a/Tests/CMakeTests/If-Invalid-Argument.cmake
+++ b/Tests/RunCMake/if/InvalidArgument1.cmake
diff --git a/Tests/RunCMake/if/MatchesSelf.cmake b/Tests/RunCMake/if/MatchesSelf.cmake
new file mode 100644
index 000000000..3131ac4f4
--- /dev/null
+++ b/Tests/RunCMake/if/MatchesSelf.cmake
@@ -0,0 +1,4 @@
+foreach(n 0 1 2 3 4 5 6 7 8 9 COUNT)
+ if(CMAKE_MATCH_${n} MATCHES "x")
+ endif()
+endforeach()
diff --git a/Tests/RunCMake/if/RunCMakeTest.cmake b/Tests/RunCMake/if/RunCMakeTest.cmake
index 6b6b74b54..077d00a05 100644
--- a/Tests/RunCMake/if/RunCMakeTest.cmake
+++ b/Tests/RunCMake/if/RunCMakeTest.cmake
@@ -1,4 +1,11 @@
include(RunCMake)
+run_cmake(InvalidArgument1)
run_cmake(IsDirectory)
run_cmake(IsDirectoryLong)
+run_cmake(elseif-message)
+
+run_cmake(MatchesSelf)
+
+run_cmake(TestNameThatExists)
+run_cmake(TestNameThatDoesNotExist)
diff --git a/Tests/RunCMake/if/TestNameThatDoesNotExist-stdout.txt b/Tests/RunCMake/if/TestNameThatDoesNotExist-stdout.txt
new file mode 100644
index 000000000..8874ca894
--- /dev/null
+++ b/Tests/RunCMake/if/TestNameThatDoesNotExist-stdout.txt
@@ -0,0 +1 @@
+TestThatDoesNotExist is false
diff --git a/Tests/RunCMake/if/TestNameThatDoesNotExist.cmake b/Tests/RunCMake/if/TestNameThatDoesNotExist.cmake
new file mode 100644
index 000000000..74bc8b02f
--- /dev/null
+++ b/Tests/RunCMake/if/TestNameThatDoesNotExist.cmake
@@ -0,0 +1,6 @@
+cmake_policy(SET CMP0064 NEW)
+if(TEST TestThatDoesNotExist)
+ message(FATAL_ERROR "if TestThatDoesNotExist is true")
+else()
+ message(STATUS "if TestThatDoesNotExist is false")
+endif()
diff --git a/Tests/RunCMake/if/TestNameThatExists-stdout.txt b/Tests/RunCMake/if/TestNameThatExists-stdout.txt
new file mode 100644
index 000000000..54911bc5b
--- /dev/null
+++ b/Tests/RunCMake/if/TestNameThatExists-stdout.txt
@@ -0,0 +1 @@
+TestThatExists is true
diff --git a/Tests/RunCMake/if/TestNameThatExists.cmake b/Tests/RunCMake/if/TestNameThatExists.cmake
new file mode 100644
index 000000000..65c2b462c
--- /dev/null
+++ b/Tests/RunCMake/if/TestNameThatExists.cmake
@@ -0,0 +1,7 @@
+cmake_policy(SET CMP0064 NEW)
+add_test(NAME TestThatExists COMMAND ${CMAKE_COMMAND} -E echo "A CMake Test")
+if(TEST TestThatExists)
+ message(STATUS "if TestThatExists is true")
+else()
+ message(FATAL_ERROR "if TestThatExists is false")
+endif()
diff --git a/Tests/RunCMake/if/elseif-message-result.txt b/Tests/RunCMake/if/elseif-message-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/if/elseif-message-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/if/elseif-message-stderr.txt b/Tests/RunCMake/if/elseif-message-stderr.txt
new file mode 100644
index 000000000..c73977c42
--- /dev/null
+++ b/Tests/RunCMake/if/elseif-message-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at elseif-message.cmake:[0-9]+ \(elseif\):
+ given arguments:
+
+ "Unknown" "arguments"
+
+ Unknown arguments specified
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/if/elseif-message.cmake b/Tests/RunCMake/if/elseif-message.cmake
new file mode 100644
index 000000000..593096610
--- /dev/null
+++ b/Tests/RunCMake/if/elseif-message.cmake
@@ -0,0 +1,4 @@
+
+if (0)
+elseif(Unknown arguments)
+endif()
diff --git a/Tests/RunCMake/include/CMP0024-NEW-result.txt b/Tests/RunCMake/include/CMP0024-NEW-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/include/CMP0024-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/include/CMP0024-NEW-stderr.txt b/Tests/RunCMake/include/CMP0024-NEW-stderr.txt
new file mode 100644
index 000000000..0fdb3ca7f
--- /dev/null
+++ b/Tests/RunCMake/include/CMP0024-NEW-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at subdir2/CMakeLists.txt:2 \(include\):
+ The file
+
+ .*/Tests/RunCMake/include/CMP0024-NEW-build/subdir1/theTargets.cmake
+
+ was generated by the export\(\) command. It may not be used as the argument
+ to the include\(\) command. Use ALIAS targets instead to refer to targets by
+ alternative names.
diff --git a/Tests/RunCMake/include/CMP0024-NEW.cmake b/Tests/RunCMake/include/CMP0024-NEW.cmake
new file mode 100644
index 000000000..0e03d2af8
--- /dev/null
+++ b/Tests/RunCMake/include/CMP0024-NEW.cmake
@@ -0,0 +1,9 @@
+
+enable_language(CXX)
+
+cmake_policy(SET CMP0024 NEW)
+
+add_library(foo SHARED empty.cpp)
+
+add_subdirectory(subdir1)
+add_subdirectory(subdir2)
diff --git a/Tests/RunCMake/include/CMP0024-WARN-result.txt b/Tests/RunCMake/include/CMP0024-WARN-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/include/CMP0024-WARN-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/include/CMP0024-WARN-stderr.txt b/Tests/RunCMake/include/CMP0024-WARN-stderr.txt
new file mode 100644
index 000000000..9c7900705
--- /dev/null
+++ b/Tests/RunCMake/include/CMP0024-WARN-stderr.txt
@@ -0,0 +1,14 @@
+CMake Warning \(dev\) at subdir2/CMakeLists.txt:2 \(include\):
+ Policy CMP0024 is not set: Disallow include export result. Run "cmake
+ --help-policy CMP0024" for policy details. Use the cmake_policy command to
+ set the policy and suppress this warning.
+
+ The file
+
+ .*/Tests/RunCMake/include/CMP0024-WARN-build/subdir1/theTargets.cmake
+
+ was generated by the export\(\) command. It should not be used as the
+ argument to the include\(\) command. Use ALIAS targets instead to refer to
+ targets by alternative names.
+
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/include/CMP0024-WARN.cmake b/Tests/RunCMake/include/CMP0024-WARN.cmake
new file mode 100644
index 000000000..783cf78e5
--- /dev/null
+++ b/Tests/RunCMake/include/CMP0024-WARN.cmake
@@ -0,0 +1,7 @@
+
+enable_language(CXX)
+
+add_library(foo SHARED empty.cpp)
+
+add_subdirectory(subdir1)
+add_subdirectory(subdir2)
diff --git a/Tests/RunCMake/include/ExportExportInclude-result.txt b/Tests/RunCMake/include/ExportExportInclude-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/include/ExportExportInclude-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/include/ExportExportInclude-stderr.txt b/Tests/RunCMake/include/ExportExportInclude-stderr.txt
new file mode 100644
index 000000000..70d013cfd
--- /dev/null
+++ b/Tests/RunCMake/include/ExportExportInclude-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at ExportExportInclude.cmake:6 \(include\):
+ include could not find load file:
+
+ .*/Tests/RunCMake/include/ExportExportInclude-build/theTargets.cmake
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/include/ExportExportInclude.cmake b/Tests/RunCMake/include/ExportExportInclude.cmake
new file mode 100644
index 000000000..14e5d913f
--- /dev/null
+++ b/Tests/RunCMake/include/ExportExportInclude.cmake
@@ -0,0 +1,6 @@
+
+add_library(iface INTERFACE)
+install(TARGETS iface EXPORT ifaceExport)
+
+export(EXPORT ifaceExport FILE "${CMAKE_CURRENT_BINARY_DIR}/theTargets.cmake")
+include("${CMAKE_CURRENT_BINARY_DIR}/theTargets.cmake")
diff --git a/Tests/RunCMake/include/RunCMakeTest.cmake b/Tests/RunCMake/include/RunCMakeTest.cmake
index 59b87ca75..bea7d5cc4 100644
--- a/Tests/RunCMake/include/RunCMakeTest.cmake
+++ b/Tests/RunCMake/include/RunCMakeTest.cmake
@@ -2,3 +2,6 @@ include(RunCMake)
run_cmake(EmptyString)
run_cmake(EmptyStringOptional)
+run_cmake(CMP0024-WARN)
+run_cmake(CMP0024-NEW)
+run_cmake(ExportExportInclude)
diff --git a/Tests/RunCMake/include/empty.cpp b/Tests/RunCMake/include/empty.cpp
new file mode 100644
index 000000000..bfbbddeb9
--- /dev/null
+++ b/Tests/RunCMake/include/empty.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/include/subdir1/CMakeLists.txt b/Tests/RunCMake/include/subdir1/CMakeLists.txt
new file mode 100644
index 000000000..11a76d1dd
--- /dev/null
+++ b/Tests/RunCMake/include/subdir1/CMakeLists.txt
@@ -0,0 +1,2 @@
+
+export(TARGETS foo FILE "${CMAKE_CURRENT_BINARY_DIR}/theTargets.cmake")
diff --git a/Tests/RunCMake/include/subdir2/CMakeLists.txt b/Tests/RunCMake/include/subdir2/CMakeLists.txt
new file mode 100644
index 000000000..7361f9cb1
--- /dev/null
+++ b/Tests/RunCMake/include/subdir2/CMakeLists.txt
@@ -0,0 +1,2 @@
+
+include("${CMAKE_CURRENT_BINARY_DIR}/../subdir1/theTargets.cmake")
diff --git a/Tests/RunCMake/include_directories/BinaryDirectoryInInterface-stderr.txt b/Tests/RunCMake/include_directories/BinaryDirectoryInInterface-stderr.txt
deleted file mode 100644
index 0d4379eb0..000000000
--- a/Tests/RunCMake/include_directories/BinaryDirectoryInInterface-stderr.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-CMake Error in CMakeLists.txt:
- Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains path:
-
- ".*RunCMake/include_directories/BinaryDirectoryInInterface-build/foo"
-
- which is prefixed in the build directory.
diff --git a/Tests/RunCMake/include_directories/BinaryDirectoryInInterface.cmake b/Tests/RunCMake/include_directories/BinaryDirectoryInInterface.cmake
deleted file mode 100644
index 875454029..000000000
--- a/Tests/RunCMake/include_directories/BinaryDirectoryInInterface.cmake
+++ /dev/null
@@ -1,11 +0,0 @@
-
-project(BinaryDirectoryInInterface)
-
-add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
-target_include_directories(testTarget INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/foo")
-
-install(TARGETS testTarget EXPORT testTargets
- DESTINATION lib
-)
-
-install(EXPORT testTargets DESTINATION lib/cmake)
diff --git a/Tests/RunCMake/include_directories/CMakeLists.txt b/Tests/RunCMake/include_directories/CMakeLists.txt
index 12cd3c775..289710955 100644
--- a/Tests/RunCMake/include_directories/CMakeLists.txt
+++ b/Tests/RunCMake/include_directories/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.0)
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/include_directories/DebugIncludes-stderr.txt b/Tests/RunCMake/include_directories/DebugIncludes-stderr.txt
index 71e6456f3..8dff90f72 100644
--- a/Tests/RunCMake/include_directories/DebugIncludes-stderr.txt
+++ b/Tests/RunCMake/include_directories/DebugIncludes-stderr.txt
@@ -5,7 +5,7 @@ CMake Debug Log at DebugIncludes.cmake:8 \(include_directories\):
\* .*/Tests/RunCMake/include_directories/two
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)
+
CMake Debug Log at DebugIncludes.cmake:13 \(set_property\):
Used includes for target lll:
@@ -13,7 +13,7 @@ CMake Debug Log at DebugIncludes.cmake:13 \(set_property\):
\* .*/Tests/RunCMake/include_directories/three
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)
+
CMake Debug Log at DebugIncludes.cmake:18 \(include_directories\):
Used includes for target lll:
@@ -21,7 +21,7 @@ CMake Debug Log at DebugIncludes.cmake:18 \(include_directories\):
\* .*/Tests/RunCMake/include_directories/four
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)
+
CMake Debug Log at DebugIncludes.cmake:33 \(set_property\):
Used includes for target lll:
@@ -33,7 +33,7 @@ CMake Debug Log at DebugIncludes.cmake:33 \(set_property\):
Call Stack \(most recent call first\):
DebugIncludes.cmake:44 \(some_macro\)
DebugIncludes.cmake:47 \(some_function\)
- CMakeLists.txt:3 \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)
+
CMake Debug Log at DebugIncludes.cmake:30 \(target_link_libraries\):
Used includes for target lll:
@@ -41,7 +41,7 @@ CMake Debug Log at DebugIncludes.cmake:30 \(target_link_libraries\):
\* .*/Tests/RunCMake/include_directories/eight
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)
+
CMake Debug Log at DebugIncludes.cmake:55 \(set_property\):
Used includes for target lll:
@@ -50,4 +50,4 @@ CMake Debug Log at DebugIncludes.cmake:55 \(set_property\):
\* .*/Tests/RunCMake/include_directories/ten
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/include_directories/DebugIncludes.cmake b/Tests/RunCMake/include_directories/DebugIncludes.cmake
index bbc9e4602..10a4c5020 100644
--- a/Tests/RunCMake/include_directories/DebugIncludes.cmake
+++ b/Tests/RunCMake/include_directories/DebugIncludes.cmake
@@ -1,5 +1,5 @@
-project(DebugIncludes)
+enable_language(CXX)
set(CMAKE_DEBUG_TARGET_PROPERTIES INCLUDE_DIRECTORIES)
diff --git a/Tests/RunCMake/include_directories/DirectoryBefore-stdout.txt b/Tests/RunCMake/include_directories/DirectoryBefore-stdout.txt
new file mode 100644
index 000000000..e9860820b
--- /dev/null
+++ b/Tests/RunCMake/include_directories/DirectoryBefore-stdout.txt
@@ -0,0 +1 @@
+-- INCLUDE_DIRECTORIES: '[^;]*/Tests/RunCMake/include_directories/BeforeDir;[^;]*/Tests/RunCMake/include_directories/AfterDir'
diff --git a/Tests/RunCMake/include_directories/DirectoryBefore.cmake b/Tests/RunCMake/include_directories/DirectoryBefore.cmake
new file mode 100644
index 000000000..be3f66381
--- /dev/null
+++ b/Tests/RunCMake/include_directories/DirectoryBefore.cmake
@@ -0,0 +1,4 @@
+include_directories(AfterDir)
+include_directories(BEFORE BeforeDir)
+get_property(dirs DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
+message(STATUS "INCLUDE_DIRECTORIES: '${dirs}'")
diff --git a/Tests/RunCMake/include_directories/ImportedTarget.cmake b/Tests/RunCMake/include_directories/ImportedTarget.cmake
index e1a20b130..f752f98e9 100644
--- a/Tests/RunCMake/include_directories/ImportedTarget.cmake
+++ b/Tests/RunCMake/include_directories/ImportedTarget.cmake
@@ -1,5 +1,5 @@
-project(ImportedTarget)
+enable_language(CXX)
add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
diff --git a/Tests/RunCMake/include_directories/RelativePathInGenex.cmake b/Tests/RunCMake/include_directories/RelativePathInGenex.cmake
deleted file mode 100644
index f72cf3adb..000000000
--- a/Tests/RunCMake/include_directories/RelativePathInGenex.cmake
+++ /dev/null
@@ -1,8 +0,0 @@
-
-project(RelativePathInInterface)
-
-add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
-set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<1:foo>")
-
-add_library(userTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
-target_link_libraries(userTarget testTarget)
diff --git a/Tests/RunCMake/include_directories/RelativePathInInterface.cmake b/Tests/RunCMake/include_directories/RelativePathInInterface.cmake
deleted file mode 100644
index f2ce54ae2..000000000
--- a/Tests/RunCMake/include_directories/RelativePathInInterface.cmake
+++ /dev/null
@@ -1,11 +0,0 @@
-
-project(RelativePathInInterface)
-
-add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
-set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "foo")
-
-install(TARGETS testTarget EXPORT testTargets
- DESTINATION lib
-)
-
-install(EXPORT testTargets DESTINATION lib/cmake)
diff --git a/Tests/RunCMake/include_directories/RunCMakeTest.cmake b/Tests/RunCMake/include_directories/RunCMakeTest.cmake
index f0704f462..57e827493 100644
--- a/Tests/RunCMake/include_directories/RunCMakeTest.cmake
+++ b/Tests/RunCMake/include_directories/RunCMakeTest.cmake
@@ -1,12 +1,13 @@
include(RunCMake)
+# Protect tests from running inside the default install prefix.
+set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/NotDefaultPrefix")
+
run_cmake(NotFoundContent)
run_cmake(DebugIncludes)
+run_cmake(DirectoryBefore)
run_cmake(TID-bad-target)
-run_cmake(SourceDirectoryInInterface)
-run_cmake(BinaryDirectoryInInterface)
-run_cmake(RelativePathInInterface)
run_cmake(ImportedTarget)
-run_cmake(RelativePathInGenex)
run_cmake(CMP0021)
run_cmake(install_config)
+run_cmake(incomplete-genex)
diff --git a/Tests/RunCMake/include_directories/SourceDirectoryInInterface-stderr.txt b/Tests/RunCMake/include_directories/SourceDirectoryInInterface-stderr.txt
deleted file mode 100644
index 9346b994f..000000000
--- a/Tests/RunCMake/include_directories/SourceDirectoryInInterface-stderr.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-CMake Error in CMakeLists.txt:
- Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains path:
-
- ".*RunCMake/include_directories/foo"
-
- which is prefixed in the source directory.
diff --git a/Tests/RunCMake/include_directories/SourceDirectoryInInterface.cmake b/Tests/RunCMake/include_directories/SourceDirectoryInInterface.cmake
deleted file mode 100644
index c9a9c457b..000000000
--- a/Tests/RunCMake/include_directories/SourceDirectoryInInterface.cmake
+++ /dev/null
@@ -1,11 +0,0 @@
-
-project(SourceDirectoryInInterface)
-
-add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
-target_include_directories(testTarget INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/foo")
-
-install(TARGETS testTarget EXPORT testTargets
- DESTINATION lib
-)
-
-install(EXPORT testTargets DESTINATION lib/cmake)
diff --git a/Tests/RunCMake/include_directories/TID-bad-target-stderr.txt b/Tests/RunCMake/include_directories/TID-bad-target-stderr.txt
index 481e358b2..4e15de147 100644
--- a/Tests/RunCMake/include_directories/TID-bad-target-stderr.txt
+++ b/Tests/RunCMake/include_directories/TID-bad-target-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at TID-bad-target.cmake:6 \(target_include_directories\):
target_include_directories called with non-compilable target type
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/include_directories/incomplete-genex.cmake b/Tests/RunCMake/include_directories/incomplete-genex.cmake
new file mode 100644
index 000000000..976695a64
--- /dev/null
+++ b/Tests/RunCMake/include_directories/incomplete-genex.cmake
@@ -0,0 +1,23 @@
+enable_language(CXX)
+
+cmake_policy(SET CMP0022 NEW)
+cmake_policy(SET CMP0023 NEW)
+
+add_library(somelib empty.cpp)
+
+# This test ensures that some internal mechanisms of cmGeneratorExpression
+# do not segfault (#14410).
+
+# Test that cmGeneratorExpression::Preprocess(StripAllGeneratorExpressions)
+# does not segfault
+target_include_directories(somelib PUBLIC
+ "/include;/include/$<BUILD_INTERFACE:subdir"
+)
+
+# Test that cmGeneratorExpression::Preprocess(BuildInterface) does not segfault
+export(TARGETS somelib FILE somelibTargets.cmake)
+
+install(TARGETS somelib EXPORT someExport DESTINATION prefix)
+# Test that cmGeneratorExpression::Preprocess(InstallInterface)
+# and cmGeneratorExpression::Split do not segfault
+install(EXPORT someExport DESTINATION prefix)
diff --git a/Tests/RunCMake/include_external_msproject/check_utils.cmake b/Tests/RunCMake/include_external_msproject/check_utils.cmake
index 7f5ef5394..408cadb78 100644
--- a/Tests/RunCMake/include_external_msproject/check_utils.cmake
+++ b/Tests/RunCMake/include_external_msproject/check_utils.cmake
@@ -80,7 +80,9 @@ function(check_project test name guid type platform)
set(type 8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942)
endif()
if(NOT platform)
- if("${RunCMake_GENERATOR}" MATCHES "Win64")
+ if(RunCMake_GENERATOR_PLATFORM)
+ set(platform "${RunCMake_GENERATOR_PLATFORM}")
+ elseif("${RunCMake_GENERATOR}" MATCHES "Win64")
set(platform "x64")
else()
set(platform "Win32")
diff --git a/Tests/RunCMake/install/CMP0062-NEW-result.txt b/Tests/RunCMake/install/CMP0062-NEW-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/install/CMP0062-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/install/CMP0062-NEW-stderr.txt b/Tests/RunCMake/install/CMP0062-NEW-stderr.txt
new file mode 100644
index 000000000..b03f629e8
--- /dev/null
+++ b/Tests/RunCMake/install/CMP0062-NEW-stderr.txt
@@ -0,0 +1,11 @@
+CMake Error at CMP0062-NEW.cmake:[0-9]+ \(install\):
+ The file
+
+ .*Tests/RunCMake/install/CMP0062-NEW-build/exported.cmake
+
+ was generated by the export\(\) command. It may not be installed with the
+ install\(\) command. Use the install\(EXPORT\) mechanism instead. See the
+ cmake-packages\(7\) manual for more.
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/install/CMP0062-NEW.cmake b/Tests/RunCMake/install/CMP0062-NEW.cmake
new file mode 100644
index 000000000..9e7a5fb82
--- /dev/null
+++ b/Tests/RunCMake/install/CMP0062-NEW.cmake
@@ -0,0 +1,6 @@
+cmake_policy(VERSION 3.2)
+cmake_policy(SET CMP0062 NEW)
+
+add_library(iface INTERFACE)
+export(TARGETS iface FILE "${CMAKE_CURRENT_BINARY_DIR}/exported.cmake")
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/exported.cmake" DESTINATION cmake)
diff --git a/Tests/RunCMake/install/CMP0062-OLD-result.txt b/Tests/RunCMake/install/CMP0062-OLD-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/install/CMP0062-OLD-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/install/CMP0062-OLD.cmake b/Tests/RunCMake/install/CMP0062-OLD.cmake
new file mode 100644
index 000000000..8874923b4
--- /dev/null
+++ b/Tests/RunCMake/install/CMP0062-OLD.cmake
@@ -0,0 +1,6 @@
+cmake_policy(VERSION 3.2)
+cmake_policy(SET CMP0062 OLD)
+
+add_library(iface INTERFACE)
+export(TARGETS iface FILE "${CMAKE_CURRENT_BINARY_DIR}/exported.cmake")
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/exported.cmake" DESTINATION cmake)
diff --git a/Tests/RunCMake/install/CMP0062-WARN-result.txt b/Tests/RunCMake/install/CMP0062-WARN-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/install/CMP0062-WARN-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/install/CMP0062-WARN-stderr.txt b/Tests/RunCMake/install/CMP0062-WARN-stderr.txt
new file mode 100644
index 000000000..12ae74573
--- /dev/null
+++ b/Tests/RunCMake/install/CMP0062-WARN-stderr.txt
@@ -0,0 +1,16 @@
+CMake Warning \(dev\) at CMP0062-WARN.cmake:[0-9]+ \(install\):
+ Policy CMP0062 is not set: Disallow install\(\) of export\(\) result. Run
+ "cmake --help-policy CMP0062" for policy details. Use the cmake_policy
+ command to set the policy and suppress this warning.
+
+ The file
+
+ .*Tests/RunCMake/install/CMP0062-WARN-build/exported.cmake
+
+ was generated by the export\(\) command. It should not be installed with the
+ install\(\) command. Use the install\(EXPORT\) mechanism instead. See the
+ cmake-packages\(7\) manual for more.
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/install/CMP0062-WARN.cmake b/Tests/RunCMake/install/CMP0062-WARN.cmake
new file mode 100644
index 000000000..018f82275
--- /dev/null
+++ b/Tests/RunCMake/install/CMP0062-WARN.cmake
@@ -0,0 +1,5 @@
+cmake_policy(VERSION 3.2)
+
+add_library(iface INTERFACE)
+export(TARGETS iface FILE "${CMAKE_CURRENT_BINARY_DIR}/exported.cmake")
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/exported.cmake" DESTINATION cmake)
diff --git a/Tests/RunCMake/install/CMakeLists.txt b/Tests/RunCMake/install/CMakeLists.txt
new file mode 100644
index 000000000..6dd8cdf55
--- /dev/null
+++ b/Tests/RunCMake/install/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.4)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/install/DIRECTORY-DESTINATION-bad-result.txt b/Tests/RunCMake/install/DIRECTORY-DESTINATION-bad-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/install/DIRECTORY-DESTINATION-bad-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/install/DIRECTORY-DESTINATION-bad-stderr.txt b/Tests/RunCMake/install/DIRECTORY-DESTINATION-bad-stderr.txt
new file mode 100644
index 000000000..984415868
--- /dev/null
+++ b/Tests/RunCMake/install/DIRECTORY-DESTINATION-bad-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error:
+ Error evaluating generator expression:
+
+ \$<NOTAGENEX>
+
+ Expression did not evaluate to a known generator expression
diff --git a/Tests/RunCMake/install/DIRECTORY-DESTINATION-bad.cmake b/Tests/RunCMake/install/DIRECTORY-DESTINATION-bad.cmake
new file mode 100644
index 000000000..f050cdfd7
--- /dev/null
+++ b/Tests/RunCMake/install/DIRECTORY-DESTINATION-bad.cmake
@@ -0,0 +1 @@
+install(DIRECTORY dir DESTINATION $<NOTAGENEX>)
diff --git a/Tests/RunCMake/install/DIRECTORY-DIRECTORY-bad-result.txt b/Tests/RunCMake/install/DIRECTORY-DIRECTORY-bad-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/install/DIRECTORY-DIRECTORY-bad-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/install/DIRECTORY-DIRECTORY-bad-stderr.txt b/Tests/RunCMake/install/DIRECTORY-DIRECTORY-bad-stderr.txt
new file mode 100644
index 000000000..984415868
--- /dev/null
+++ b/Tests/RunCMake/install/DIRECTORY-DIRECTORY-bad-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error:
+ Error evaluating generator expression:
+
+ \$<NOTAGENEX>
+
+ Expression did not evaluate to a known generator expression
diff --git a/Tests/RunCMake/install/DIRECTORY-DIRECTORY-bad.cmake b/Tests/RunCMake/install/DIRECTORY-DIRECTORY-bad.cmake
new file mode 100644
index 000000000..ec0436d38
--- /dev/null
+++ b/Tests/RunCMake/install/DIRECTORY-DIRECTORY-bad.cmake
@@ -0,0 +1 @@
+install(DIRECTORY $<NOTAGENEX> DESTINATION .)
diff --git a/Tests/RunCMake/install/DIRECTORY-MESSAGE_NEVER-check.cmake b/Tests/RunCMake/install/DIRECTORY-MESSAGE_NEVER-check.cmake
new file mode 100644
index 000000000..2c716e1e2
--- /dev/null
+++ b/Tests/RunCMake/install/DIRECTORY-MESSAGE_NEVER-check.cmake
@@ -0,0 +1,13 @@
+file(REMOVE_RECURSE ${RunCMake_TEST_BINARY_DIR}/prefix)
+execute_process(COMMAND ${CMAKE_COMMAND} -P ${RunCMake_TEST_BINARY_DIR}/cmake_install.cmake
+ OUTPUT_VARIABLE out ERROR_VARIABLE err)
+if(out MATCHES "-- Installing: [^\n]*prefix/dir")
+ string(REGEX REPLACE "\n" "\n " out " ${out}")
+ set(RunCMake_TEST_FAILED
+ "${RunCMake_TEST_FAILED}Installation output was not quiet:\n${out}")
+endif()
+set(f ${RunCMake_TEST_BINARY_DIR}/prefix/dir/empty.txt)
+if(NOT EXISTS "${f}")
+ set(RunCMake_TEST_FAILED
+ "${RunCMake_TEST_FAILED}File was not installed:\n ${f}\n")
+endif()
diff --git a/Tests/RunCMake/install/DIRECTORY-MESSAGE_NEVER.cmake b/Tests/RunCMake/install/DIRECTORY-MESSAGE_NEVER.cmake
new file mode 100644
index 000000000..eefb8374f
--- /dev/null
+++ b/Tests/RunCMake/install/DIRECTORY-MESSAGE_NEVER.cmake
@@ -0,0 +1,3 @@
+set(CMAKE_INSTALL_MESSAGE "ALWAYS")
+set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/prefix")
+install(DIRECTORY dir/ DESTINATION dir MESSAGE_NEVER)
diff --git a/Tests/RunCMake/install/DIRECTORY-PATTERN-MESSAGE_NEVER-result.txt b/Tests/RunCMake/install/DIRECTORY-PATTERN-MESSAGE_NEVER-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/install/DIRECTORY-PATTERN-MESSAGE_NEVER-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/install/DIRECTORY-PATTERN-MESSAGE_NEVER-stderr.txt b/Tests/RunCMake/install/DIRECTORY-PATTERN-MESSAGE_NEVER-stderr.txt
new file mode 100644
index 000000000..166ba6f04
--- /dev/null
+++ b/Tests/RunCMake/install/DIRECTORY-PATTERN-MESSAGE_NEVER-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at DIRECTORY-PATTERN-MESSAGE_NEVER.cmake:[0-9]+ \(install\):
+ install DIRECTORY does not allow "MESSAGE_NEVER" after PATTERN or REGEX.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/install/DIRECTORY-PATTERN-MESSAGE_NEVER.cmake b/Tests/RunCMake/install/DIRECTORY-PATTERN-MESSAGE_NEVER.cmake
new file mode 100644
index 000000000..de844f7d4
--- /dev/null
+++ b/Tests/RunCMake/install/DIRECTORY-PATTERN-MESSAGE_NEVER.cmake
@@ -0,0 +1 @@
+install(DIRECTORY src DESTINATION src PATTERN *.txt MESSAGE_NEVER)
diff --git a/Tests/RunCMake/install/DIRECTORY-message-check.cmake b/Tests/RunCMake/install/DIRECTORY-message-check.cmake
new file mode 100644
index 000000000..857681fbc
--- /dev/null
+++ b/Tests/RunCMake/install/DIRECTORY-message-check.cmake
@@ -0,0 +1,28 @@
+file(REMOVE_RECURSE ${RunCMake_TEST_BINARY_DIR}/prefix)
+execute_process(COMMAND ${CMAKE_COMMAND} -P ${RunCMake_TEST_BINARY_DIR}/cmake_install.cmake
+ OUTPUT_VARIABLE out ERROR_VARIABLE err)
+set(expect "
+-- Installing: [^\n]*/prefix/dir\r?
+-- Installing: [^\n]*/prefix/dir/empty.txt\r?
+")
+if(NOT out MATCHES "${expect}")
+ string(REGEX REPLACE "\n" "\n " out " ${out}")
+ set(RunCMake_TEST_FAILED
+ "${RunCMake_TEST_FAILED}First install did not say 'Installing' as expected:\n${out}")
+endif()
+set(f ${RunCMake_TEST_BINARY_DIR}/prefix/dir/empty.txt)
+if(NOT EXISTS "${f}")
+ set(RunCMake_TEST_FAILED
+ "${RunCMake_TEST_FAILED}File was not installed:\n ${f}\n")
+endif()
+execute_process(COMMAND ${CMAKE_COMMAND} -P ${RunCMake_TEST_BINARY_DIR}/cmake_install.cmake
+ OUTPUT_VARIABLE out ERROR_VARIABLE err)
+set(expect "
+-- Up-to-date: [^\n]*/prefix/dir\r?
+-- Up-to-date: [^\n]*/prefix/dir/empty.txt\r?
+")
+if(NOT out MATCHES "${expect}")
+ string(REGEX REPLACE "\n" "\n " out " ${out}")
+ set(RunCMake_TEST_FAILED
+ "${RunCMake_TEST_FAILED}Second install did not say 'Up-to-date' as expected:\n${out}")
+endif()
diff --git a/Tests/RunCMake/install/DIRECTORY-message-lazy-check.cmake b/Tests/RunCMake/install/DIRECTORY-message-lazy-check.cmake
new file mode 100644
index 000000000..c7e601880
--- /dev/null
+++ b/Tests/RunCMake/install/DIRECTORY-message-lazy-check.cmake
@@ -0,0 +1,24 @@
+file(REMOVE_RECURSE ${RunCMake_TEST_BINARY_DIR}/prefix)
+execute_process(COMMAND ${CMAKE_COMMAND} -P ${RunCMake_TEST_BINARY_DIR}/cmake_install.cmake
+ OUTPUT_VARIABLE out ERROR_VARIABLE err)
+set(expect "
+-- Installing: [^\n]*/prefix/dir\r?
+-- Installing: [^\n]*/prefix/dir/empty.txt\r?
+")
+if(NOT out MATCHES "${expect}")
+ string(REGEX REPLACE "\n" "\n " out " ${out}")
+ set(RunCMake_TEST_FAILED
+ "${RunCMake_TEST_FAILED}First install did not say 'Installing' as expected:\n${out}")
+endif()
+set(f ${RunCMake_TEST_BINARY_DIR}/prefix/dir/empty.txt)
+if(NOT EXISTS "${f}")
+ set(RunCMake_TEST_FAILED
+ "${RunCMake_TEST_FAILED}File was not installed:\n ${f}\n")
+endif()
+execute_process(COMMAND ${CMAKE_COMMAND} -P ${RunCMake_TEST_BINARY_DIR}/cmake_install.cmake
+ OUTPUT_VARIABLE out ERROR_VARIABLE err)
+if(out MATCHES "(Installing|Up-to-date)")
+ string(REGEX REPLACE "\n" "\n " out " ${out}")
+ set(RunCMake_TEST_FAILED
+ "${RunCMake_TEST_FAILED}Second install was not silent as expected:\n${out}")
+endif()
diff --git a/Tests/RunCMake/install/DIRECTORY-message-lazy.cmake b/Tests/RunCMake/install/DIRECTORY-message-lazy.cmake
new file mode 100644
index 000000000..ed4356714
--- /dev/null
+++ b/Tests/RunCMake/install/DIRECTORY-message-lazy.cmake
@@ -0,0 +1,3 @@
+set(CMAKE_INSTALL_MESSAGE "LAZY")
+set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/prefix")
+install(DIRECTORY dir/ DESTINATION dir)
diff --git a/Tests/RunCMake/install/DIRECTORY-message.cmake b/Tests/RunCMake/install/DIRECTORY-message.cmake
new file mode 100644
index 000000000..913ed157d
--- /dev/null
+++ b/Tests/RunCMake/install/DIRECTORY-message.cmake
@@ -0,0 +1,3 @@
+set(CMAKE_INSTALL_MESSAGE "ALWAYS")
+set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/prefix")
+install(DIRECTORY dir/ DESTINATION dir)
diff --git a/Tests/RunCMake/install/EXPORT-OldIFace.cmake b/Tests/RunCMake/install/EXPORT-OldIFace.cmake
new file mode 100644
index 000000000..033f68446
--- /dev/null
+++ b/Tests/RunCMake/install/EXPORT-OldIFace.cmake
@@ -0,0 +1,7 @@
+enable_language(C)
+set(CMAKE_BUILD_WITH_INSTALL_RPATH 1)
+add_subdirectory(EXPORT-OldIFace)
+add_library(foo SHARED empty.c)
+target_link_libraries(foo bar)
+install(TARGETS foo DESTINATION lib EXPORT fooExport)
+install(EXPORT fooExport DESTINATION lib/cmake/foo EXPORT_LINK_INTERFACE_LIBRARIES)
diff --git a/Tests/RunCMake/install/EXPORT-OldIFace/CMakeLists.txt b/Tests/RunCMake/install/EXPORT-OldIFace/CMakeLists.txt
new file mode 100644
index 000000000..32292e2f6
--- /dev/null
+++ b/Tests/RunCMake/install/EXPORT-OldIFace/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_library(bar SHARED ../empty.c)
+install(TARGETS bar DESTINATION lib EXPORT fooExport)
diff --git a/Tests/RunCMake/install/FILES-DESTINATION-bad-result.txt b/Tests/RunCMake/install/FILES-DESTINATION-bad-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/install/FILES-DESTINATION-bad-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/install/FILES-DESTINATION-bad-stderr.txt b/Tests/RunCMake/install/FILES-DESTINATION-bad-stderr.txt
new file mode 100644
index 000000000..984415868
--- /dev/null
+++ b/Tests/RunCMake/install/FILES-DESTINATION-bad-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error:
+ Error evaluating generator expression:
+
+ \$<NOTAGENEX>
+
+ Expression did not evaluate to a known generator expression
diff --git a/Tests/RunCMake/install/FILES-DESTINATION-bad.cmake b/Tests/RunCMake/install/FILES-DESTINATION-bad.cmake
new file mode 100644
index 000000000..0fda078db
--- /dev/null
+++ b/Tests/RunCMake/install/FILES-DESTINATION-bad.cmake
@@ -0,0 +1 @@
+install(FILES empty.c DESTINATION $<NOTAGENEX>)
diff --git a/Tests/RunCMake/install/RunCMakeTest.cmake b/Tests/RunCMake/install/RunCMakeTest.cmake
new file mode 100644
index 000000000..c2347d89d
--- /dev/null
+++ b/Tests/RunCMake/install/RunCMakeTest.cmake
@@ -0,0 +1,16 @@
+include(RunCMake)
+run_cmake(DIRECTORY-MESSAGE_NEVER)
+run_cmake(DIRECTORY-PATTERN-MESSAGE_NEVER)
+run_cmake(DIRECTORY-message)
+run_cmake(DIRECTORY-message-lazy)
+run_cmake(SkipInstallRulesWarning)
+run_cmake(SkipInstallRulesNoWarning1)
+run_cmake(SkipInstallRulesNoWarning2)
+run_cmake(DIRECTORY-DIRECTORY-bad)
+run_cmake(DIRECTORY-DESTINATION-bad)
+run_cmake(FILES-DESTINATION-bad)
+run_cmake(TARGETS-DESTINATION-bad)
+run_cmake(EXPORT-OldIFace)
+run_cmake(CMP0062-OLD)
+run_cmake(CMP0062-NEW)
+run_cmake(CMP0062-WARN)
diff --git a/Tests/RunCMake/install/SkipInstallRulesNoWarning1-check.cmake b/Tests/RunCMake/install/SkipInstallRulesNoWarning1-check.cmake
new file mode 100644
index 000000000..28076983d
--- /dev/null
+++ b/Tests/RunCMake/install/SkipInstallRulesNoWarning1-check.cmake
@@ -0,0 +1,9 @@
+if(NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/CMakeCache.txt")
+ message(FATAL_ERROR "missing test prerequisite CMakeCache.txt")
+endif()
+
+set(CMAKE_INSTALL_CMAKE "${RunCMake_TEST_BINARY_DIR}/cmake_install.cmake")
+
+if(EXISTS ${CMAKE_INSTALL_CMAKE})
+ message(FATAL_ERROR "${CMAKE_INSTALL_CMAKE} should not exist")
+endif()
diff --git a/Tests/RunCMake/install/SkipInstallRulesNoWarning1.cmake b/Tests/RunCMake/install/SkipInstallRulesNoWarning1.cmake
new file mode 100644
index 000000000..22c7f8ca8
--- /dev/null
+++ b/Tests/RunCMake/install/SkipInstallRulesNoWarning1.cmake
@@ -0,0 +1 @@
+set(CMAKE_SKIP_INSTALL_RULES ON)
diff --git a/Tests/RunCMake/install/SkipInstallRulesNoWarning2-check.cmake b/Tests/RunCMake/install/SkipInstallRulesNoWarning2-check.cmake
new file mode 100644
index 000000000..4372b77c0
--- /dev/null
+++ b/Tests/RunCMake/install/SkipInstallRulesNoWarning2-check.cmake
@@ -0,0 +1,9 @@
+if(NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/CMakeCache.txt")
+ message(FATAL_ERROR "missing test prerequisite CMakeCache.txt")
+endif()
+
+set(CMAKE_INSTALL_CMAKE "${RunCMake_TEST_BINARY_DIR}/cmake_install.cmake")
+
+if(NOT EXISTS ${CMAKE_INSTALL_CMAKE})
+ message(FATAL_ERROR "${CMAKE_INSTALL_CMAKE} should exist")
+endif()
diff --git a/Tests/RunCMake/install/SkipInstallRulesNoWarning2.cmake b/Tests/RunCMake/install/SkipInstallRulesNoWarning2.cmake
new file mode 100644
index 000000000..2f5f03af0
--- /dev/null
+++ b/Tests/RunCMake/install/SkipInstallRulesNoWarning2.cmake
@@ -0,0 +1 @@
+install(FILES CMakeLists.txt DESTINATION src)
diff --git a/Tests/RunCMake/install/SkipInstallRulesWarning-check.cmake b/Tests/RunCMake/install/SkipInstallRulesWarning-check.cmake
new file mode 100644
index 000000000..28076983d
--- /dev/null
+++ b/Tests/RunCMake/install/SkipInstallRulesWarning-check.cmake
@@ -0,0 +1,9 @@
+if(NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/CMakeCache.txt")
+ message(FATAL_ERROR "missing test prerequisite CMakeCache.txt")
+endif()
+
+set(CMAKE_INSTALL_CMAKE "${RunCMake_TEST_BINARY_DIR}/cmake_install.cmake")
+
+if(EXISTS ${CMAKE_INSTALL_CMAKE})
+ message(FATAL_ERROR "${CMAKE_INSTALL_CMAKE} should not exist")
+endif()
diff --git a/Tests/RunCMake/install/SkipInstallRulesWarning-stderr.txt b/Tests/RunCMake/install/SkipInstallRulesWarning-stderr.txt
new file mode 100644
index 000000000..9130526f1
--- /dev/null
+++ b/Tests/RunCMake/install/SkipInstallRulesWarning-stderr.txt
@@ -0,0 +1,3 @@
+CMake Warning in CMakeLists.txt:
+ CMAKE_SKIP_INSTALL_RULES was enabled even though installation rules have
+ been specified
diff --git a/Tests/RunCMake/install/SkipInstallRulesWarning.cmake b/Tests/RunCMake/install/SkipInstallRulesWarning.cmake
new file mode 100644
index 000000000..b621d9b54
--- /dev/null
+++ b/Tests/RunCMake/install/SkipInstallRulesWarning.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_SKIP_INSTALL_RULES ON)
+install(FILES CMakeLists.txt DESTINATION src)
diff --git a/Tests/RunCMake/install/TARGETS-DESTINATION-bad-result.txt b/Tests/RunCMake/install/TARGETS-DESTINATION-bad-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/install/TARGETS-DESTINATION-bad-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/install/TARGETS-DESTINATION-bad-stderr.txt b/Tests/RunCMake/install/TARGETS-DESTINATION-bad-stderr.txt
new file mode 100644
index 000000000..984415868
--- /dev/null
+++ b/Tests/RunCMake/install/TARGETS-DESTINATION-bad-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error:
+ Error evaluating generator expression:
+
+ \$<NOTAGENEX>
+
+ Expression did not evaluate to a known generator expression
diff --git a/Tests/RunCMake/install/TARGETS-DESTINATION-bad.cmake b/Tests/RunCMake/install/TARGETS-DESTINATION-bad.cmake
new file mode 100644
index 000000000..feff52dfe
--- /dev/null
+++ b/Tests/RunCMake/install/TARGETS-DESTINATION-bad.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+add_library(empty empty.c)
+install(TARGETS empty DESTINATION $<NOTAGENEX>)
diff --git a/Tests/RunCMake/install/dir/empty.txt b/Tests/RunCMake/install/dir/empty.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/install/dir/empty.txt
diff --git a/Tests/RunCMake/install/empty.c b/Tests/RunCMake/install/empty.c
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/install/empty.c
diff --git a/Tests/RunCMake/interface_library/CMakeLists.txt b/Tests/RunCMake/interface_library/CMakeLists.txt
new file mode 100644
index 000000000..12cd3c775
--- /dev/null
+++ b/Tests/RunCMake/interface_library/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/interface_library/RunCMakeTest.cmake b/Tests/RunCMake/interface_library/RunCMakeTest.cmake
new file mode 100644
index 000000000..201daa7c7
--- /dev/null
+++ b/Tests/RunCMake/interface_library/RunCMakeTest.cmake
@@ -0,0 +1,10 @@
+include(RunCMake)
+
+run_cmake(invalid_name)
+run_cmake(target_commands)
+run_cmake(no_shared_libs)
+run_cmake(whitelist)
+run_cmake(invalid_signature)
+run_cmake(global-interface)
+run_cmake(genex_link)
+run_cmake(add_custom_command-TARGET)
diff --git a/Tests/RunCMake/interface_library/add_custom_command-TARGET-result.txt b/Tests/RunCMake/interface_library/add_custom_command-TARGET-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/interface_library/add_custom_command-TARGET-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/interface_library/add_custom_command-TARGET-stderr.txt b/Tests/RunCMake/interface_library/add_custom_command-TARGET-stderr.txt
new file mode 100644
index 000000000..c09526265
--- /dev/null
+++ b/Tests/RunCMake/interface_library/add_custom_command-TARGET-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at add_custom_command-TARGET.cmake:4 \(add_custom_command\):
+ Target "iface" is an INTERFACE library that may not have PRE_BUILD,
+ PRE_LINK, or POST_BUILD commands.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/interface_library/add_custom_command-TARGET.cmake b/Tests/RunCMake/interface_library/add_custom_command-TARGET.cmake
new file mode 100644
index 000000000..a5136eff8
--- /dev/null
+++ b/Tests/RunCMake/interface_library/add_custom_command-TARGET.cmake
@@ -0,0 +1,6 @@
+
+add_library(iface INTERFACE)
+
+add_custom_command(TARGET iface
+ COMMAND "${CMAKE_COMMAND}" -E echo test
+)
diff --git a/Tests/RunCMake/interface_library/genex_link-result.txt b/Tests/RunCMake/interface_library/genex_link-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/interface_library/genex_link-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/interface_library/genex_link.cmake b/Tests/RunCMake/interface_library/genex_link.cmake
new file mode 100644
index 000000000..0dbf029fe
--- /dev/null
+++ b/Tests/RunCMake/interface_library/genex_link.cmake
@@ -0,0 +1,22 @@
+
+cmake_minimum_required(VERSION 2.8.12.20131125 FATAL_ERROR)
+
+project(genex_link)
+
+set(_main_cpp ${CMAKE_CURRENT_BINARY_DIR}/main.cpp)
+file(WRITE ${_main_cpp}
+ "int main(int argc, char** argv) { return 0; }\n"
+)
+
+add_library(foo::bar INTERFACE IMPORTED)
+set_target_properties(foo::bar
+ PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}"
+ # When not using a generator expression here, no error is generated
+ INTERFACE_LINK_LIBRARIES "$<$<NOT:$<CONFIG:DEBUG>>:foo_bar.lib>"
+)
+
+add_executable(main ${_main_cpp})
+target_include_directories(main PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}")
+
+target_link_libraries(main foo::bar)
diff --git a/Tests/RunCMake/interface_library/global-interface-result.txt b/Tests/RunCMake/interface_library/global-interface-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/interface_library/global-interface-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/interface_library/global-interface-stderr.txt b/Tests/RunCMake/interface_library/global-interface-stderr.txt
new file mode 100644
index 000000000..24edd0f89
--- /dev/null
+++ b/Tests/RunCMake/interface_library/global-interface-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at global-interface.cmake:2 \(add_library\):
+ Cannot find source file:
+
+ GLOBAL
+
+ Tried extensions \.c \.C \.c\+\+ \.cc \.cpp \.cxx \.m \.M \.mm \.h \.hh \.h\+\+ \.hm \.hpp
+ \.hxx \.in \.txx
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/interface_library/global-interface.cmake b/Tests/RunCMake/interface_library/global-interface.cmake
new file mode 100644
index 000000000..d2bfc64ed
--- /dev/null
+++ b/Tests/RunCMake/interface_library/global-interface.cmake
@@ -0,0 +1,2 @@
+
+add_library(iface GLOBAL INTERFACE)
diff --git a/Tests/RunCMake/interface_library/invalid_name-result.txt b/Tests/RunCMake/interface_library/invalid_name-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/interface_library/invalid_name-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/interface_library/invalid_name-stderr.txt b/Tests/RunCMake/interface_library/invalid_name-stderr.txt
new file mode 100644
index 000000000..e14fcdedb
--- /dev/null
+++ b/Tests/RunCMake/interface_library/invalid_name-stderr.txt
@@ -0,0 +1,15 @@
+CMake Error at invalid_name.cmake:2 \(add_library\):
+ add_library Invalid name for INTERFACE library target: if\$ace
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_name.cmake:4 \(add_library\):
+ add_library Invalid name for INTERFACE library target: iface::target
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_name.cmake:6 \(add_library\):
+ add_library Invalid name for IMPORTED INTERFACE library target:
+ if\$target_imported
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/interface_library/invalid_name.cmake b/Tests/RunCMake/interface_library/invalid_name.cmake
new file mode 100644
index 000000000..9a965aa8a
--- /dev/null
+++ b/Tests/RunCMake/interface_library/invalid_name.cmake
@@ -0,0 +1,6 @@
+
+add_library(if$ace INTERFACE)
+
+add_library(iface::target INTERFACE)
+
+add_library(if$target_imported INTERFACE IMPORTED)
diff --git a/Tests/RunCMake/interface_library/invalid_signature-result.txt b/Tests/RunCMake/interface_library/invalid_signature-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/interface_library/invalid_signature-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/interface_library/invalid_signature-stderr.txt b/Tests/RunCMake/interface_library/invalid_signature-stderr.txt
new file mode 100644
index 000000000..6374b3392
--- /dev/null
+++ b/Tests/RunCMake/interface_library/invalid_signature-stderr.txt
@@ -0,0 +1,89 @@
+CMake Error at invalid_signature.cmake:2 \(add_library\):
+ add_library INTERFACE library requires no source arguments.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:3 \(add_library\):
+ add_library INTERFACE library specified with conflicting/multiple types.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:4 \(add_library\):
+ add_library INTERFACE library specified with conflicting/multiple types.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:5 \(add_library\):
+ add_library INTERFACE library specified with conflicting/multiple types.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:6 \(add_library\):
+ add_library INTERFACE library specified with conflicting/multiple types.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:7 \(add_library\):
+ add_library INTERFACE library specified with conflicting/multiple types.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:8 \(add_library\):
+ add_library INTERFACE library specified with conflicting/multiple types.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:9 \(add_library\):
+ add_library INTERFACE library specified with conflicting STATIC type.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:10 \(add_library\):
+ add_library INTERFACE library specified with conflicting SHARED type.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:11 \(add_library\):
+ add_library INTERFACE library specified with conflicting MODULE type.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:12 \(add_library\):
+ add_library INTERFACE library specified with conflicting OBJECT type.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:13 \(add_library\):
+ add_library INTERFACE library specified with conflicting UNKNOWN type.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:14 \(add_library\):
+ add_library INTERFACE library specified with conflicting ALIAS type.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:15 \(add_library\):
+ add_library INTERFACE library specified with conflicting ALIAS type.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:16 \(add_library\):
+ add_library INTERFACE library specified with conflicting/multiple types.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:17 \(add_library\):
+ add_library INTERFACE library may not be used with EXCLUDE_FROM_ALL.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:18 \(add_library\):
+ add_library INTERFACE library may not be used with EXCLUDE_FROM_ALL.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:20 \(add_library\):
+ add_library GLOBAL option may only be used with IMPORTED libraries.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/interface_library/invalid_signature.cmake b/Tests/RunCMake/interface_library/invalid_signature.cmake
new file mode 100644
index 000000000..4e53534b2
--- /dev/null
+++ b/Tests/RunCMake/interface_library/invalid_signature.cmake
@@ -0,0 +1,20 @@
+
+add_library(iface1 INTERFACE empty.cpp)
+add_library(iface3 STATIC INTERFACE)
+add_library(iface4 STATIC INTERFACE empty.cpp)
+add_library(iface5 SHARED INTERFACE)
+add_library(iface6 MODULE INTERFACE)
+add_library(iface7 OBJECT INTERFACE)
+add_library(iface8 UNKNOWN INTERFACE)
+add_library(iface9 INTERFACE STATIC)
+add_library(iface10 INTERFACE SHARED)
+add_library(iface11 INTERFACE MODULE)
+add_library(iface12 INTERFACE OBJECT)
+add_library(iface13 INTERFACE UNKNOWN)
+add_library(iface14 INTERFACE ALIAS)
+add_library(iface15 ALIAS INTERFACE)
+add_library(iface16 INTERFACE INTERFACE)
+add_library(iface17 INTERFACE EXCLUDE_FROM_ALL)
+add_library(iface18 EXCLUDE_FROM_ALL INTERFACE)
+# add_library(iface19 GLOBAL INTERFACE) Tested separately
+add_library(iface20 INTERFACE GLOBAL)
diff --git a/Tests/RunCMake/interface_library/no_shared_libs.cmake b/Tests/RunCMake/interface_library/no_shared_libs.cmake
new file mode 100644
index 000000000..ed81878cb
--- /dev/null
+++ b/Tests/RunCMake/interface_library/no_shared_libs.cmake
@@ -0,0 +1,5 @@
+
+cmake_minimum_required(VERSION 2.8.12.20131009)
+set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
+add_library(foo INTERFACE)
+target_compile_definitions(foo INTERFACE FOO_DEFINE)
diff --git a/Tests/RunCMake/interface_library/target_commands-result.txt b/Tests/RunCMake/interface_library/target_commands-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/interface_library/target_commands-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/interface_library/target_commands-stderr.txt b/Tests/RunCMake/interface_library/target_commands-stderr.txt
new file mode 100644
index 000000000..be11b7754
--- /dev/null
+++ b/Tests/RunCMake/interface_library/target_commands-stderr.txt
@@ -0,0 +1,47 @@
+CMake Error at target_commands.cmake:4 \(target_link_libraries\):
+ INTERFACE library can only be used with the INTERFACE keyword of
+ target_link_libraries
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at target_commands.cmake:5 \(target_link_libraries\):
+ INTERFACE library can only be used with the INTERFACE keyword of
+ target_link_libraries
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at target_commands.cmake:6 \(target_link_libraries\):
+ INTERFACE library can only be used with the INTERFACE keyword of
+ target_link_libraries
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at target_commands.cmake:7 \(target_link_libraries\):
+ INTERFACE library can only be used with the INTERFACE keyword of
+ target_link_libraries
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at target_commands.cmake:9 \(target_include_directories\):
+ target_include_directories may only be set INTERFACE properties on
+ INTERFACE targets
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at target_commands.cmake:10 \(target_include_directories\):
+ target_include_directories may only be set INTERFACE properties on
+ INTERFACE targets
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at target_commands.cmake:12 \(target_compile_definitions\):
+ target_compile_definitions may only be set INTERFACE properties on
+ INTERFACE targets
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at target_commands.cmake:13 \(target_compile_definitions\):
+ target_compile_definitions may only be set INTERFACE properties on
+ INTERFACE targets
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/interface_library/target_commands.cmake b/Tests/RunCMake/interface_library/target_commands.cmake
new file mode 100644
index 000000000..3182e8933
--- /dev/null
+++ b/Tests/RunCMake/interface_library/target_commands.cmake
@@ -0,0 +1,13 @@
+
+add_library(iface INTERFACE)
+
+target_link_libraries(iface PRIVATE foo)
+target_link_libraries(iface PUBLIC foo)
+target_link_libraries(iface foo)
+target_link_libraries(iface LINK_INTERFACE_LIBRARIES foo)
+
+target_include_directories(iface PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}")
+target_include_directories(iface PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
+
+target_compile_definitions(iface PRIVATE SOME_DEFINE)
+target_compile_definitions(iface PUBLIC SOME_DEFINE)
diff --git a/Tests/RunCMake/interface_library/whitelist-result.txt b/Tests/RunCMake/interface_library/whitelist-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/interface_library/whitelist-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/interface_library/whitelist-stderr.txt b/Tests/RunCMake/interface_library/whitelist-stderr.txt
new file mode 100644
index 000000000..577c0cc5d
--- /dev/null
+++ b/Tests/RunCMake/interface_library/whitelist-stderr.txt
@@ -0,0 +1,19 @@
+CMake Error at whitelist.cmake:4 \(set_property\):
+ INTERFACE_LIBRARY targets may only have whitelisted properties. The
+ property "OUTPUT_NAME" is not allowed.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+
+
+CMake Error at whitelist.cmake:5 \(set_property\):
+ INTERFACE_LIBRARY targets may only have whitelisted properties. The
+ property "OUTPUT_NAME" is not allowed.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+
+
+CMake Error at whitelist.cmake:6 \(get_target_property\):
+ INTERFACE_LIBRARY targets may only have whitelisted properties. The
+ property "OUTPUT_NAME" is not allowed.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/interface_library/whitelist.cmake b/Tests/RunCMake/interface_library/whitelist.cmake
new file mode 100644
index 000000000..98ef05c0f
--- /dev/null
+++ b/Tests/RunCMake/interface_library/whitelist.cmake
@@ -0,0 +1,6 @@
+
+add_library(iface INTERFACE)
+
+set_property(TARGET iface PROPERTY OUTPUT_NAME output)
+set_property(TARGET iface APPEND PROPERTY OUTPUT_NAME append)
+get_target_property(outname iface OUTPUT_NAME)
diff --git a/Tests/RunCMake/list/GET-CMP0007-WARN-stderr.txt b/Tests/RunCMake/list/GET-CMP0007-WARN-stderr.txt
new file mode 100644
index 000000000..a0f883780
--- /dev/null
+++ b/Tests/RunCMake/list/GET-CMP0007-WARN-stderr.txt
@@ -0,0 +1,8 @@
+^CMake Warning \(dev\) at GET-CMP0007-WARN.cmake:4 \(list\):
+ Policy CMP0007 is not set: list command no longer ignores empty elements.
+ Run "cmake --help-policy CMP0007" for policy details. Use the cmake_policy
+ command to set the policy and suppress this warning. List has value =
+ \[;NEW;OLD\].
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/list/GET-CMP0007-WARN.cmake b/Tests/RunCMake/list/GET-CMP0007-WARN.cmake
new file mode 100644
index 000000000..833f35204
--- /dev/null
+++ b/Tests/RunCMake/list/GET-CMP0007-WARN.cmake
@@ -0,0 +1,7 @@
+cmake_policy(VERSION 2.4)
+set(thelist "" NEW OLD)
+
+list(GET thelist 1 thevalue)
+if (NOT thevalue STREQUAL "OLD")
+ message(SEND_ERROR "returned element '${thevalue}', but expected 'OLD'")
+endif()
diff --git a/Tests/RunCMake/list/GET-InvalidIndex-result.txt b/Tests/RunCMake/list/GET-InvalidIndex-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/list/GET-InvalidIndex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/GET-InvalidIndex-stderr.txt b/Tests/RunCMake/list/GET-InvalidIndex-stderr.txt
new file mode 100644
index 000000000..0409464be
--- /dev/null
+++ b/Tests/RunCMake/list/GET-InvalidIndex-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at GET-InvalidIndex.cmake:2 \(list\):
+ list index: 3 out of range \(-3, 2\)
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-Get-Invalid-Index.cmake b/Tests/RunCMake/list/GET-InvalidIndex.cmake
index 178295a20..178295a20 100644
--- a/Tests/CMakeTests/List-Get-Invalid-Index.cmake
+++ b/Tests/RunCMake/list/GET-InvalidIndex.cmake
diff --git a/Tests/RunCMake/list/INSERT-InvalidIndex-result.txt b/Tests/RunCMake/list/INSERT-InvalidIndex-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/list/INSERT-InvalidIndex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/INSERT-InvalidIndex-stderr.txt b/Tests/RunCMake/list/INSERT-InvalidIndex-stderr.txt
new file mode 100644
index 000000000..6e15c0b43
--- /dev/null
+++ b/Tests/RunCMake/list/INSERT-InvalidIndex-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at INSERT-InvalidIndex.cmake:2 \(list\):
+ list index: 3 out of range \(-3, 2\)
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-Insert-Invalid-Index.cmake b/Tests/RunCMake/list/INSERT-InvalidIndex.cmake
index 4103d974b..4103d974b 100644
--- a/Tests/CMakeTests/List-Insert-Invalid-Index.cmake
+++ b/Tests/RunCMake/list/INSERT-InvalidIndex.cmake
diff --git a/Tests/RunCMake/list/InvalidSubcommand-result.txt b/Tests/RunCMake/list/InvalidSubcommand-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/list/InvalidSubcommand-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/InvalidSubcommand-stderr.txt b/Tests/RunCMake/list/InvalidSubcommand-stderr.txt
new file mode 100644
index 000000000..74703d249
--- /dev/null
+++ b/Tests/RunCMake/list/InvalidSubcommand-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at InvalidSubcommand.cmake:1 \(list\):
+ list does not recognize sub-command NO_SUCH_SUBCOMMAND
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-Invalid-Subcommand.cmake b/Tests/RunCMake/list/InvalidSubcommand.cmake
index f35a1181e..f35a1181e 100644
--- a/Tests/CMakeTests/List-Invalid-Subcommand.cmake
+++ b/Tests/RunCMake/list/InvalidSubcommand.cmake
diff --git a/Tests/RunCMake/list/LENGTH-TooManyArguments-result.txt b/Tests/RunCMake/list/LENGTH-TooManyArguments-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/list/LENGTH-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/LENGTH-TooManyArguments-stderr.txt b/Tests/RunCMake/list/LENGTH-TooManyArguments-stderr.txt
new file mode 100644
index 000000000..239e70874
--- /dev/null
+++ b/Tests/RunCMake/list/LENGTH-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at LENGTH-TooManyArguments.cmake:1 \(list\):
+ list sub-command LENGTH requires two arguments.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-Length-Too-Many-Arguments.cmake b/Tests/RunCMake/list/LENGTH-TooManyArguments.cmake
index 327db6a84..327db6a84 100644
--- a/Tests/CMakeTests/List-Length-Too-Many-Arguments.cmake
+++ b/Tests/RunCMake/list/LENGTH-TooManyArguments.cmake
diff --git a/Tests/RunCMake/list/NoArguments-result.txt b/Tests/RunCMake/list/NoArguments-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/list/NoArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/NoArguments-stderr.txt b/Tests/RunCMake/list/NoArguments-stderr.txt
new file mode 100644
index 000000000..6fdf9cc0b
--- /dev/null
+++ b/Tests/RunCMake/list/NoArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at NoArguments.cmake:1 \(list\):
+ list must be called with at least two arguments.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-No-Arguments.cmake b/Tests/RunCMake/list/NoArguments.cmake
index 7916aaaec..7916aaaec 100644
--- a/Tests/CMakeTests/List-No-Arguments.cmake
+++ b/Tests/RunCMake/list/NoArguments.cmake
diff --git a/Tests/RunCMake/list/REMOVE_AT-InvalidIndex-result.txt b/Tests/RunCMake/list/REMOVE_AT-InvalidIndex-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/list/REMOVE_AT-InvalidIndex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/REMOVE_AT-InvalidIndex-stderr.txt b/Tests/RunCMake/list/REMOVE_AT-InvalidIndex-stderr.txt
new file mode 100644
index 000000000..6f5887538
--- /dev/null
+++ b/Tests/RunCMake/list/REMOVE_AT-InvalidIndex-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at REMOVE_AT-InvalidIndex.cmake:2 \(list\):
+ list index: 3 out of range \(-3, 2\)
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-Remove_At-Invalid-Index.cmake b/Tests/RunCMake/list/REMOVE_AT-InvalidIndex.cmake
index d4f392126..d4f392126 100644
--- a/Tests/CMakeTests/List-Remove_At-Invalid-Index.cmake
+++ b/Tests/RunCMake/list/REMOVE_AT-InvalidIndex.cmake
diff --git a/Tests/RunCMake/list/REMOVE_AT-NotList-result.txt b/Tests/RunCMake/list/REMOVE_AT-NotList-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/list/REMOVE_AT-NotList-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/REMOVE_AT-NotList-stderr.txt b/Tests/RunCMake/list/REMOVE_AT-NotList-stderr.txt
new file mode 100644
index 000000000..d6e8d85f5
--- /dev/null
+++ b/Tests/RunCMake/list/REMOVE_AT-NotList-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at REMOVE_AT-NotList.cmake:2 \(list\):
+ list sub-command REMOVE_AT requires list to be present.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-Remove_At-Nonexistent-List.cmake b/Tests/RunCMake/list/REMOVE_AT-NotList.cmake
index 5266c7fe9..5266c7fe9 100644
--- a/Tests/CMakeTests/List-Remove_At-Nonexistent-List.cmake
+++ b/Tests/RunCMake/list/REMOVE_AT-NotList.cmake
diff --git a/Tests/RunCMake/list/REMOVE_DUPLICATES-NotList-result.txt b/Tests/RunCMake/list/REMOVE_DUPLICATES-NotList-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/list/REMOVE_DUPLICATES-NotList-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/REMOVE_DUPLICATES-NotList-stderr.txt b/Tests/RunCMake/list/REMOVE_DUPLICATES-NotList-stderr.txt
new file mode 100644
index 000000000..96f3446ff
--- /dev/null
+++ b/Tests/RunCMake/list/REMOVE_DUPLICATES-NotList-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at REMOVE_DUPLICATES-NotList.cmake:2 \(list\):
+ list sub-command REMOVE_DUPLICATES requires list to be present.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-Remove_Duplicates-Nonexistent-List.cmake b/Tests/RunCMake/list/REMOVE_DUPLICATES-NotList.cmake
index 218f2272c..218f2272c 100644
--- a/Tests/CMakeTests/List-Remove_Duplicates-Nonexistent-List.cmake
+++ b/Tests/RunCMake/list/REMOVE_DUPLICATES-NotList.cmake
diff --git a/Tests/RunCMake/list/REMOVE_DUPLICATES-TooManyArguments-result.txt b/Tests/RunCMake/list/REMOVE_DUPLICATES-TooManyArguments-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/list/REMOVE_DUPLICATES-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/REMOVE_DUPLICATES-TooManyArguments-stderr.txt b/Tests/RunCMake/list/REMOVE_DUPLICATES-TooManyArguments-stderr.txt
new file mode 100644
index 000000000..f5c871111
--- /dev/null
+++ b/Tests/RunCMake/list/REMOVE_DUPLICATES-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at REMOVE_DUPLICATES-TooManyArguments.cmake:1 \(list\):
+ list sub-command REMOVE_DUPLICATES only takes one argument.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-Remove_Duplicates-Too-Many-Arguments.cmake b/Tests/RunCMake/list/REMOVE_DUPLICATES-TooManyArguments.cmake
index b5eb46e64..b5eb46e64 100644
--- a/Tests/CMakeTests/List-Remove_Duplicates-Too-Many-Arguments.cmake
+++ b/Tests/RunCMake/list/REMOVE_DUPLICATES-TooManyArguments.cmake
diff --git a/Tests/RunCMake/list/REMOVE_ITEM-NotList-result.txt b/Tests/RunCMake/list/REMOVE_ITEM-NotList-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/list/REMOVE_ITEM-NotList-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/REMOVE_ITEM-NotList-stderr.txt b/Tests/RunCMake/list/REMOVE_ITEM-NotList-stderr.txt
new file mode 100644
index 000000000..c32a4c055
--- /dev/null
+++ b/Tests/RunCMake/list/REMOVE_ITEM-NotList-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at REMOVE_ITEM-NotList.cmake:2 \(list\):
+ list sub-command REMOVE_ITEM requires list to be present.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-Remove_Item-Nonexistent-List.cmake b/Tests/RunCMake/list/REMOVE_ITEM-NotList.cmake
index 079e7fbce..079e7fbce 100644
--- a/Tests/CMakeTests/List-Remove_Item-Nonexistent-List.cmake
+++ b/Tests/RunCMake/list/REMOVE_ITEM-NotList.cmake
diff --git a/Tests/RunCMake/list/REVERSE-NotList-result.txt b/Tests/RunCMake/list/REVERSE-NotList-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/list/REVERSE-NotList-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/REVERSE-NotList-stderr.txt b/Tests/RunCMake/list/REVERSE-NotList-stderr.txt
new file mode 100644
index 000000000..e9dcc06b3
--- /dev/null
+++ b/Tests/RunCMake/list/REVERSE-NotList-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at REVERSE-NotList.cmake:2 \(list\):
+ list sub-command REVERSE requires list to be present.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-Reverse-Nonexistent-List.cmake b/Tests/RunCMake/list/REVERSE-NotList.cmake
index 977e2ccac..977e2ccac 100644
--- a/Tests/CMakeTests/List-Reverse-Nonexistent-List.cmake
+++ b/Tests/RunCMake/list/REVERSE-NotList.cmake
diff --git a/Tests/RunCMake/list/REVERSE-TooManyArguments-result.txt b/Tests/RunCMake/list/REVERSE-TooManyArguments-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/list/REVERSE-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/REVERSE-TooManyArguments-stderr.txt b/Tests/RunCMake/list/REVERSE-TooManyArguments-stderr.txt
new file mode 100644
index 000000000..7dabd9d3c
--- /dev/null
+++ b/Tests/RunCMake/list/REVERSE-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at REVERSE-TooManyArguments.cmake:1 \(list\):
+ list sub-command REVERSE only takes one argument.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-Reverse-Too-Many-Arguments.cmake b/Tests/RunCMake/list/REVERSE-TooManyArguments.cmake
index 3a554a01a..3a554a01a 100644
--- a/Tests/CMakeTests/List-Reverse-Too-Many-Arguments.cmake
+++ b/Tests/RunCMake/list/REVERSE-TooManyArguments.cmake
diff --git a/Tests/RunCMake/list/RunCMakeTest.cmake b/Tests/RunCMake/list/RunCMakeTest.cmake
index 555051de0..25d6a0367 100644
--- a/Tests/RunCMake/list/RunCMakeTest.cmake
+++ b/Tests/RunCMake/list/RunCMakeTest.cmake
@@ -3,3 +3,22 @@ include(RunCMake)
run_cmake(EmptyGet0)
run_cmake(EmptyRemoveAt0)
run_cmake(EmptyInsert-1)
+
+run_cmake(NoArguments)
+run_cmake(InvalidSubcommand)
+run_cmake(GET-CMP0007-WARN)
+
+run_cmake(GET-InvalidIndex)
+run_cmake(INSERT-InvalidIndex)
+run_cmake(REMOVE_AT-InvalidIndex)
+
+run_cmake(LENGTH-TooManyArguments)
+run_cmake(REMOVE_DUPLICATES-TooManyArguments)
+run_cmake(REVERSE-TooManyArguments)
+run_cmake(SORT-TooManyArguments)
+
+run_cmake(REMOVE_AT-NotList)
+run_cmake(REMOVE_DUPLICATES-NotList)
+run_cmake(REMOVE_ITEM-NotList)
+run_cmake(REVERSE-NotList)
+run_cmake(SORT-NotList)
diff --git a/Tests/RunCMake/list/SORT-NotList-result.txt b/Tests/RunCMake/list/SORT-NotList-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/list/SORT-NotList-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/SORT-NotList-stderr.txt b/Tests/RunCMake/list/SORT-NotList-stderr.txt
new file mode 100644
index 000000000..396c5b57d
--- /dev/null
+++ b/Tests/RunCMake/list/SORT-NotList-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at SORT-NotList.cmake:2 \(list\):
+ list sub-command SORT requires list to be present.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-Sort-Nonexistent-List.cmake b/Tests/RunCMake/list/SORT-NotList.cmake
index 8f48e1043..8f48e1043 100644
--- a/Tests/CMakeTests/List-Sort-Nonexistent-List.cmake
+++ b/Tests/RunCMake/list/SORT-NotList.cmake
diff --git a/Tests/RunCMake/list/SORT-TooManyArguments-result.txt b/Tests/RunCMake/list/SORT-TooManyArguments-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/list/SORT-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/SORT-TooManyArguments-stderr.txt b/Tests/RunCMake/list/SORT-TooManyArguments-stderr.txt
new file mode 100644
index 000000000..d3fad6068
--- /dev/null
+++ b/Tests/RunCMake/list/SORT-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at SORT-TooManyArguments.cmake:1 \(list\):
+ list sub-command SORT only takes one argument.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/List-Sort-Too-Many-Arguments.cmake b/Tests/RunCMake/list/SORT-TooManyArguments.cmake
index 81b195d67..81b195d67 100644
--- a/Tests/CMakeTests/List-Sort-Too-Many-Arguments.cmake
+++ b/Tests/RunCMake/list/SORT-TooManyArguments.cmake
diff --git a/Tests/RunCMake/message/CMakeLists.txt b/Tests/RunCMake/message/CMakeLists.txt
new file mode 100644
index 000000000..12cd3c775
--- /dev/null
+++ b/Tests/RunCMake/message/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/message/RunCMakeTest.cmake b/Tests/RunCMake/message/RunCMakeTest.cmake
new file mode 100644
index 000000000..94896930a
--- /dev/null
+++ b/Tests/RunCMake/message/RunCMakeTest.cmake
@@ -0,0 +1,10 @@
+include(RunCMake)
+
+run_cmake(defaultmessage)
+run_cmake(nomessage)
+run_cmake(warnmessage)
+# message command sets fatal occurred flag, so check each type of error
+
+# seperately
+run_cmake(errormessage_deprecated)
+run_cmake(errormessage_dev)
diff --git a/Tests/RunCMake/message/defaultmessage-result.txt b/Tests/RunCMake/message/defaultmessage-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/message/defaultmessage-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/message/defaultmessage-stderr.txt b/Tests/RunCMake/message/defaultmessage-stderr.txt
new file mode 100644
index 000000000..dd1b28fde
--- /dev/null
+++ b/Tests/RunCMake/message/defaultmessage-stderr.txt
@@ -0,0 +1,11 @@
+^CMake Deprecation Warning at defaultmessage.cmake:2 \(message\):
+ This is a deprecation warning
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+
+
+CMake Warning \(dev\) at defaultmessage.cmake:4 \(message\):
+ This is a author warning
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/message/defaultmessage.cmake b/Tests/RunCMake/message/defaultmessage.cmake
new file mode 100644
index 000000000..427014d56
--- /dev/null
+++ b/Tests/RunCMake/message/defaultmessage.cmake
@@ -0,0 +1,4 @@
+
+message(DEPRECATION "This is a deprecation warning")
+
+message(AUTHOR_WARNING "This is a author warning")
diff --git a/Tests/RunCMake/message/errormessage_deprecated-result.txt b/Tests/RunCMake/message/errormessage_deprecated-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/message/errormessage_deprecated-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/message/errormessage_deprecated-stderr.txt b/Tests/RunCMake/message/errormessage_deprecated-stderr.txt
new file mode 100644
index 000000000..dd21c3b3b
--- /dev/null
+++ b/Tests/RunCMake/message/errormessage_deprecated-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Deprecation Error at errormessage_deprecated.cmake:3 \(message\):
+ This is a deprecation error
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/message/errormessage_deprecated.cmake b/Tests/RunCMake/message/errormessage_deprecated.cmake
new file mode 100644
index 000000000..579275e94
--- /dev/null
+++ b/Tests/RunCMake/message/errormessage_deprecated.cmake
@@ -0,0 +1,3 @@
+set(CMAKE_ERROR_DEPRECATED ON)
+
+message(DEPRECATION "This is a deprecation error")
diff --git a/Tests/RunCMake/message/errormessage_dev-result.txt b/Tests/RunCMake/message/errormessage_dev-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/message/errormessage_dev-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/message/errormessage_dev-stderr.txt b/Tests/RunCMake/message/errormessage_dev-stderr.txt
new file mode 100644
index 000000000..086b55c47
--- /dev/null
+++ b/Tests/RunCMake/message/errormessage_dev-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error \(dev\) at errormessage_dev.cmake:3 \(message\):
+ This is a author error
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This error is for project developers. Use -Wno-error=dev to suppress it.$
diff --git a/Tests/RunCMake/message/errormessage_dev.cmake b/Tests/RunCMake/message/errormessage_dev.cmake
new file mode 100644
index 000000000..6ba11657f
--- /dev/null
+++ b/Tests/RunCMake/message/errormessage_dev.cmake
@@ -0,0 +1,3 @@
+set(CMAKE_SUPPRESS_DEVELOPER_ERRORS OFF)
+
+message(AUTHOR_WARNING "This is a author error")
diff --git a/Tests/RunCMake/message/nomessage-result.txt b/Tests/RunCMake/message/nomessage-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/message/nomessage-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/message/nomessage.cmake b/Tests/RunCMake/message/nomessage.cmake
new file mode 100644
index 000000000..78f476945
--- /dev/null
+++ b/Tests/RunCMake/message/nomessage.cmake
@@ -0,0 +1,8 @@
+
+set(CMAKE_WARN_DEPRECATED OFF)
+
+message(DEPRECATION "This is not issued")
+
+set(CMAKE_SUPPRESS_DEVELOPER_WARNINGS ON)
+
+message(AUTHOR_WARNING "This is not issued")
diff --git a/Tests/RunCMake/message/warnmessage-result.txt b/Tests/RunCMake/message/warnmessage-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/message/warnmessage-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/message/warnmessage-stderr.txt b/Tests/RunCMake/message/warnmessage-stderr.txt
new file mode 100644
index 000000000..e60af6e43
--- /dev/null
+++ b/Tests/RunCMake/message/warnmessage-stderr.txt
@@ -0,0 +1,11 @@
+^CMake Deprecation Warning at warnmessage.cmake:4 \(message\):
+ This is a deprecation warning
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+
+
+CMake Warning \(dev\) at warnmessage.cmake:8 \(message\):
+ This is a author warning
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/message/warnmessage.cmake b/Tests/RunCMake/message/warnmessage.cmake
new file mode 100644
index 000000000..53f2a4364
--- /dev/null
+++ b/Tests/RunCMake/message/warnmessage.cmake
@@ -0,0 +1,8 @@
+
+set(CMAKE_WARN_DEPRECATED ON)
+
+message(DEPRECATION "This is a deprecation warning")
+
+set(CMAKE_SUPPRESS_DEVELOPER_WARNINGS OFF)
+
+message(AUTHOR_WARNING "This is a author warning")
diff --git a/Tests/RunCMake/no_install_prefix/CMakeLists.txt b/Tests/RunCMake/no_install_prefix/CMakeLists.txt
new file mode 100644
index 000000000..12cd3c775
--- /dev/null
+++ b/Tests/RunCMake/no_install_prefix/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/no_install_prefix/RunCMakeTest.cmake b/Tests/RunCMake/no_install_prefix/RunCMakeTest.cmake
new file mode 100644
index 000000000..292344999
--- /dev/null
+++ b/Tests/RunCMake/no_install_prefix/RunCMakeTest.cmake
@@ -0,0 +1,15 @@
+include(RunCMake)
+
+set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/prefix")
+
+file(REMOVE_RECURSE "${RunCMake_BINARY_DIR}/prefix")
+file(MAKE_DIRECTORY "${RunCMake_BINARY_DIR}/prefix/NoPrefix")
+file(WRITE "${RunCMake_BINARY_DIR}/prefix/NoPrefix/NoPrefixConfig.cmake" "")
+set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX:PATH=${RunCMake_BINARY_DIR}/prefix")
+run_cmake(with_install_prefix)
+
+file(REMOVE_RECURSE "${RunCMake_BINARY_DIR}/prefix")
+file(MAKE_DIRECTORY "${RunCMake_BINARY_DIR}/prefix/NoPrefix")
+file(WRITE "${RunCMake_BINARY_DIR}/prefix/NoPrefix/NoPrefixConfig.cmake" "")
+list(APPEND RunCMake_TEST_OPTIONS "-DCMAKE_FIND_NO_INSTALL_PREFIX=1")
+run_cmake(no_install_prefix)
diff --git a/Tests/RunCMake/no_install_prefix/do_test.cmake b/Tests/RunCMake/no_install_prefix/do_test.cmake
new file mode 100644
index 000000000..340c7dcc9
--- /dev/null
+++ b/Tests/RunCMake/no_install_prefix/do_test.cmake
@@ -0,0 +1,2 @@
+
+find_package(NoPrefix REQUIRED)
diff --git a/Tests/RunCMake/no_install_prefix/no_install_prefix-result.txt b/Tests/RunCMake/no_install_prefix/no_install_prefix-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/no_install_prefix/no_install_prefix-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/no_install_prefix/no_install_prefix-stderr.txt b/Tests/RunCMake/no_install_prefix/no_install_prefix-stderr.txt
new file mode 100644
index 000000000..66c624123
--- /dev/null
+++ b/Tests/RunCMake/no_install_prefix/no_install_prefix-stderr.txt
@@ -0,0 +1,18 @@
+CMake Error at do_test.cmake:2 \(find_package\):
+ By not providing "FindNoPrefix.cmake" in CMAKE_MODULE_PATH this project has
+ asked CMake to find a package configuration file provided by "NoPrefix",
+ but CMake did not find one.
+
+ Could not find a package configuration file provided by "NoPrefix" with any
+ of the following names:
+
+ NoPrefixConfig.cmake
+ noprefix-config.cmake
+
+ Add the installation prefix of "NoPrefix" to CMAKE_PREFIX_PATH or set
+ "NoPrefix_DIR" to a directory containing one of the above files. If
+ "NoPrefix" provides a separate development package or SDK, be sure it has
+ been installed.
+Call Stack \(most recent call first\):
+ no_install_prefix.cmake:2 \(include\)
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/no_install_prefix/no_install_prefix.cmake b/Tests/RunCMake/no_install_prefix/no_install_prefix.cmake
new file mode 100644
index 000000000..c7d28daa8
--- /dev/null
+++ b/Tests/RunCMake/no_install_prefix/no_install_prefix.cmake
@@ -0,0 +1,2 @@
+
+include(do_test.cmake)
diff --git a/Tests/RunCMake/no_install_prefix/with_install_prefix-result.txt b/Tests/RunCMake/no_install_prefix/with_install_prefix-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/no_install_prefix/with_install_prefix-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/no_install_prefix/with_install_prefix.cmake b/Tests/RunCMake/no_install_prefix/with_install_prefix.cmake
new file mode 100644
index 000000000..c7d28daa8
--- /dev/null
+++ b/Tests/RunCMake/no_install_prefix/with_install_prefix.cmake
@@ -0,0 +1,2 @@
+
+include(do_test.cmake)
diff --git a/Tests/RunCMake/project/CMP0048-NEW-stdout.txt b/Tests/RunCMake/project/CMP0048-NEW-stdout.txt
new file mode 100644
index 000000000..38261e50c
--- /dev/null
+++ b/Tests/RunCMake/project/CMP0048-NEW-stdout.txt
@@ -0,0 +1,30 @@
+-- PROJECT_VERSION='1.2.3.4'
+-- ProjectA_VERSION='1.2.3.4'
+-- PROJECT_VERSION_MAJOR='1'
+-- ProjectA_VERSION_MAJOR='1'
+-- PROJECT_VERSION_MINOR='2'
+-- ProjectA_VERSION_MINOR='2'
+-- PROJECT_VERSION_PATCH='3'
+-- ProjectA_VERSION_PATCH='3'
+-- PROJECT_VERSION_TWEAK='4'
+-- ProjectA_VERSION_TWEAK='4'
+-- PROJECT_VERSION='0.1.2'
+-- ProjectB_VERSION='0.1.2'
+-- PROJECT_VERSION_MAJOR='0'
+-- ProjectB_VERSION_MAJOR='0'
+-- PROJECT_VERSION_MINOR='1'
+-- ProjectB_VERSION_MINOR='1'
+-- PROJECT_VERSION_PATCH='2'
+-- ProjectB_VERSION_PATCH='2'
+-- PROJECT_VERSION_TWEAK=''
+-- ProjectB_VERSION_TWEAK=''
+-- PROJECT_VERSION=''
+-- ProjectC_VERSION=''
+-- PROJECT_VERSION_MAJOR=''
+-- ProjectC_VERSION_MAJOR=''
+-- PROJECT_VERSION_MINOR=''
+-- ProjectC_VERSION_MINOR=''
+-- PROJECT_VERSION_PATCH=''
+-- ProjectC_VERSION_PATCH=''
+-- PROJECT_VERSION_TWEAK=''
+-- ProjectC_VERSION_TWEAK=''
diff --git a/Tests/RunCMake/project/CMP0048-NEW.cmake b/Tests/RunCMake/project/CMP0048-NEW.cmake
new file mode 100644
index 000000000..7e16b7081
--- /dev/null
+++ b/Tests/RunCMake/project/CMP0048-NEW.cmake
@@ -0,0 +1,19 @@
+macro(print_versions name)
+ foreach(v "" _MAJOR _MINOR _PATCH _TWEAK)
+ message(STATUS "PROJECT_VERSION${v}='${PROJECT_VERSION${v}}'")
+ message(STATUS "${name}_VERSION${v}='${${name}_VERSION${v}}'")
+ endforeach()
+endmacro()
+
+cmake_policy(SET CMP0048 NEW)
+
+project(ProjectA VERSION 1.2.3.4 LANGUAGES NONE)
+print_versions(ProjectA)
+
+project(ProjectB VERSION 0.1.2 LANGUAGES NONE)
+print_versions(ProjectB)
+
+set(PROJECT_VERSION 1)
+set(ProjectC_VERSION 1)
+project(ProjectC NONE)
+print_versions(ProjectC)
diff --git a/Tests/RunCMake/project/CMP0048-OLD-VERSION-result.txt b/Tests/RunCMake/project/CMP0048-OLD-VERSION-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/project/CMP0048-OLD-VERSION-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/project/CMP0048-OLD-VERSION-stderr.txt b/Tests/RunCMake/project/CMP0048-OLD-VERSION-stderr.txt
new file mode 100644
index 000000000..3a13d3262
--- /dev/null
+++ b/Tests/RunCMake/project/CMP0048-OLD-VERSION-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at CMP0048-OLD-VERSION.cmake:1 \(project\):
+ VERSION not allowed unless CMP0048 is set to NEW
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/project/CMP0048-OLD-VERSION.cmake b/Tests/RunCMake/project/CMP0048-OLD-VERSION.cmake
new file mode 100644
index 000000000..6fbbe0a27
--- /dev/null
+++ b/Tests/RunCMake/project/CMP0048-OLD-VERSION.cmake
@@ -0,0 +1,2 @@
+project(MyProject VERSION 1 LANGUAGES NONE)
+message("This line not reached.")
diff --git a/Tests/RunCMake/project/CMP0048-OLD-stdout.txt b/Tests/RunCMake/project/CMP0048-OLD-stdout.txt
new file mode 100644
index 000000000..1a25c7bca
--- /dev/null
+++ b/Tests/RunCMake/project/CMP0048-OLD-stdout.txt
@@ -0,0 +1,2 @@
+-- PROJECT_VERSION='1'
+-- MyProject_VERSION_TWEAK='0'
diff --git a/Tests/RunCMake/project/CMP0048-OLD.cmake b/Tests/RunCMake/project/CMP0048-OLD.cmake
new file mode 100644
index 000000000..6c32d2cc4
--- /dev/null
+++ b/Tests/RunCMake/project/CMP0048-OLD.cmake
@@ -0,0 +1,6 @@
+cmake_policy(SET CMP0048 OLD)
+set(PROJECT_VERSION 1)
+set(MyProject_VERSION_TWEAK 0)
+project(MyProject NONE)
+message(STATUS "PROJECT_VERSION='${PROJECT_VERSION}'")
+message(STATUS "MyProject_VERSION_TWEAK='${MyProject_VERSION_TWEAK}'")
diff --git a/Tests/RunCMake/project/CMP0048-WARN-stderr.txt b/Tests/RunCMake/project/CMP0048-WARN-stderr.txt
new file mode 100644
index 000000000..6d29ad260
--- /dev/null
+++ b/Tests/RunCMake/project/CMP0048-WARN-stderr.txt
@@ -0,0 +1,12 @@
+CMake Warning \(dev\) at CMP0048-WARN.cmake:3 \(project\):
+ Policy CMP0048 is not set: project\(\) command manages VERSION variables.
+ Run "cmake --help-policy CMP0048" for policy details. Use the cmake_policy
+ command to set the policy and suppress this warning.
+
+ The following variable\(s\) would be set to empty:
+
+ PROJECT_VERSION
+ MyProject_VERSION_TWEAK
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/project/CMP0048-WARN.cmake b/Tests/RunCMake/project/CMP0048-WARN.cmake
new file mode 100644
index 000000000..97359e64f
--- /dev/null
+++ b/Tests/RunCMake/project/CMP0048-WARN.cmake
@@ -0,0 +1,3 @@
+set(PROJECT_VERSION 1)
+set(MyProject_VERSION_TWEAK 0)
+project(MyProject NONE)
diff --git a/Tests/RunCMake/project/CMakeLists.txt b/Tests/RunCMake/project/CMakeLists.txt
new file mode 100644
index 000000000..12cd3c775
--- /dev/null
+++ b/Tests/RunCMake/project/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/project/LanguagesEmpty-stdout.txt b/Tests/RunCMake/project/LanguagesEmpty-stdout.txt
new file mode 100644
index 000000000..fb9c7e87d
--- /dev/null
+++ b/Tests/RunCMake/project/LanguagesEmpty-stdout.txt
@@ -0,0 +1 @@
+ENABLED_LANGUAGES='NONE'
diff --git a/Tests/RunCMake/project/LanguagesEmpty.cmake b/Tests/RunCMake/project/LanguagesEmpty.cmake
new file mode 100644
index 000000000..4de2ccabd
--- /dev/null
+++ b/Tests/RunCMake/project/LanguagesEmpty.cmake
@@ -0,0 +1,3 @@
+project(ProjectA LANGUAGES)
+get_property(langs GLOBAL PROPERTY ENABLED_LANGUAGES)
+message(STATUS "ENABLED_LANGUAGES='${langs}'")
diff --git a/Tests/RunCMake/project/LanguagesImplicit-stdout.txt b/Tests/RunCMake/project/LanguagesImplicit-stdout.txt
new file mode 100644
index 000000000..fb9c7e87d
--- /dev/null
+++ b/Tests/RunCMake/project/LanguagesImplicit-stdout.txt
@@ -0,0 +1 @@
+ENABLED_LANGUAGES='NONE'
diff --git a/Tests/RunCMake/project/LanguagesImplicit.cmake b/Tests/RunCMake/project/LanguagesImplicit.cmake
new file mode 100644
index 000000000..e40845488
--- /dev/null
+++ b/Tests/RunCMake/project/LanguagesImplicit.cmake
@@ -0,0 +1,3 @@
+project(ProjectA NONE)
+get_property(langs GLOBAL PROPERTY ENABLED_LANGUAGES)
+message(STATUS "ENABLED_LANGUAGES='${langs}'")
diff --git a/Tests/RunCMake/project/LanguagesNONE-stdout.txt b/Tests/RunCMake/project/LanguagesNONE-stdout.txt
new file mode 100644
index 000000000..fb9c7e87d
--- /dev/null
+++ b/Tests/RunCMake/project/LanguagesNONE-stdout.txt
@@ -0,0 +1 @@
+ENABLED_LANGUAGES='NONE'
diff --git a/Tests/RunCMake/project/LanguagesNONE.cmake b/Tests/RunCMake/project/LanguagesNONE.cmake
new file mode 100644
index 000000000..2c0125f22
--- /dev/null
+++ b/Tests/RunCMake/project/LanguagesNONE.cmake
@@ -0,0 +1,3 @@
+project(ProjectA LANGUAGES NONE)
+get_property(langs GLOBAL PROPERTY ENABLED_LANGUAGES)
+message(STATUS "ENABLED_LANGUAGES='${langs}'")
diff --git a/Tests/RunCMake/project/LanguagesTwice-result.txt b/Tests/RunCMake/project/LanguagesTwice-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/project/LanguagesTwice-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/project/LanguagesTwice-stderr.txt b/Tests/RunCMake/project/LanguagesTwice-stderr.txt
new file mode 100644
index 000000000..9c69dd003
--- /dev/null
+++ b/Tests/RunCMake/project/LanguagesTwice-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at LanguagesTwice.cmake:1 \(project\):
+ LANGUAGES may be specified at most once.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/project/LanguagesTwice.cmake b/Tests/RunCMake/project/LanguagesTwice.cmake
new file mode 100644
index 000000000..6c4a3dc95
--- /dev/null
+++ b/Tests/RunCMake/project/LanguagesTwice.cmake
@@ -0,0 +1,2 @@
+project(ProjectA LANGUAGES NONE LANGUAGES)
+message("This line not reached.")
diff --git a/Tests/RunCMake/project/RunCMakeTest.cmake b/Tests/RunCMake/project/RunCMakeTest.cmake
new file mode 100644
index 000000000..6ab0fc957
--- /dev/null
+++ b/Tests/RunCMake/project/RunCMakeTest.cmake
@@ -0,0 +1,17 @@
+include(RunCMake)
+
+run_cmake(LanguagesImplicit)
+run_cmake(LanguagesEmpty)
+run_cmake(LanguagesNONE)
+run_cmake(LanguagesTwice)
+run_cmake(VersionAndLanguagesEmpty)
+run_cmake(VersionEmpty)
+run_cmake(VersionInvalid)
+run_cmake(VersionMissingLanguages)
+run_cmake(VersionMissingValueOkay)
+run_cmake(VersionTwice)
+
+run_cmake(CMP0048-OLD)
+run_cmake(CMP0048-OLD-VERSION)
+run_cmake(CMP0048-WARN)
+run_cmake(CMP0048-NEW)
diff --git a/Tests/RunCMake/project/VersionAndLanguagesEmpty-stdout.txt b/Tests/RunCMake/project/VersionAndLanguagesEmpty-stdout.txt
new file mode 100644
index 000000000..eae7da73b
--- /dev/null
+++ b/Tests/RunCMake/project/VersionAndLanguagesEmpty-stdout.txt
@@ -0,0 +1,2 @@
+-- ENABLED_LANGUAGES='NONE'
+-- PROJECT_VERSION='1'
diff --git a/Tests/RunCMake/project/VersionAndLanguagesEmpty.cmake b/Tests/RunCMake/project/VersionAndLanguagesEmpty.cmake
new file mode 100644
index 000000000..d6056ce1b
--- /dev/null
+++ b/Tests/RunCMake/project/VersionAndLanguagesEmpty.cmake
@@ -0,0 +1,5 @@
+cmake_policy(SET CMP0048 NEW)
+project(ProjectA VERSION 1 LANGUAGES NONE)
+get_property(langs GLOBAL PROPERTY ENABLED_LANGUAGES)
+message(STATUS "ENABLED_LANGUAGES='${langs}'")
+message(STATUS "PROJECT_VERSION='${PROJECT_VERSION}'")
diff --git a/Tests/RunCMake/project/VersionEmpty-stdout.txt b/Tests/RunCMake/project/VersionEmpty-stdout.txt
new file mode 100644
index 000000000..3ae42e02d
--- /dev/null
+++ b/Tests/RunCMake/project/VersionEmpty-stdout.txt
@@ -0,0 +1,2 @@
+-- ENABLED_LANGUAGES='NONE'
+-- PROJECT_VERSION=''
diff --git a/Tests/RunCMake/project/VersionEmpty.cmake b/Tests/RunCMake/project/VersionEmpty.cmake
new file mode 100644
index 000000000..0cfb29140
--- /dev/null
+++ b/Tests/RunCMake/project/VersionEmpty.cmake
@@ -0,0 +1,6 @@
+cmake_policy(SET CMP0048 NEW)
+set(PROJECT_VERSION 1)
+project(ProjectA VERSION "" LANGUAGES NONE)
+get_property(langs GLOBAL PROPERTY ENABLED_LANGUAGES)
+message(STATUS "ENABLED_LANGUAGES='${langs}'")
+message(STATUS "PROJECT_VERSION='${PROJECT_VERSION}'")
diff --git a/Tests/RunCMake/project/VersionInvalid-result.txt b/Tests/RunCMake/project/VersionInvalid-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/project/VersionInvalid-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/project/VersionInvalid-stderr.txt b/Tests/RunCMake/project/VersionInvalid-stderr.txt
new file mode 100644
index 000000000..48358d1d7
--- /dev/null
+++ b/Tests/RunCMake/project/VersionInvalid-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at VersionInvalid.cmake:2 \(project\):
+ VERSION "NONE" format invalid.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/project/VersionInvalid.cmake b/Tests/RunCMake/project/VersionInvalid.cmake
new file mode 100644
index 000000000..8d5dd7f25
--- /dev/null
+++ b/Tests/RunCMake/project/VersionInvalid.cmake
@@ -0,0 +1,3 @@
+cmake_policy(SET CMP0048 NEW)
+project(ProjectA VERSION NONE)
+message("This line not reached.")
diff --git a/Tests/RunCMake/project/VersionMissingLanguages-result.txt b/Tests/RunCMake/project/VersionMissingLanguages-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/project/VersionMissingLanguages-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/project/VersionMissingLanguages-stderr.txt b/Tests/RunCMake/project/VersionMissingLanguages-stderr.txt
new file mode 100644
index 000000000..52433bcc0
--- /dev/null
+++ b/Tests/RunCMake/project/VersionMissingLanguages-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at VersionMissingLanguages.cmake:2 \(project\):
+ project with VERSION must use LANGUAGES before language names.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/project/VersionMissingLanguages.cmake b/Tests/RunCMake/project/VersionMissingLanguages.cmake
new file mode 100644
index 000000000..dc415141c
--- /dev/null
+++ b/Tests/RunCMake/project/VersionMissingLanguages.cmake
@@ -0,0 +1,3 @@
+cmake_policy(SET CMP0048 NEW)
+project(ProjectA VERSION 1 NONE)
+message("This line not reached.")
diff --git a/Tests/RunCMake/project/VersionMissingValueOkay-stdout.txt b/Tests/RunCMake/project/VersionMissingValueOkay-stdout.txt
new file mode 100644
index 000000000..3ae42e02d
--- /dev/null
+++ b/Tests/RunCMake/project/VersionMissingValueOkay-stdout.txt
@@ -0,0 +1,2 @@
+-- ENABLED_LANGUAGES='NONE'
+-- PROJECT_VERSION=''
diff --git a/Tests/RunCMake/project/VersionMissingValueOkay.cmake b/Tests/RunCMake/project/VersionMissingValueOkay.cmake
new file mode 100644
index 000000000..1fb143750
--- /dev/null
+++ b/Tests/RunCMake/project/VersionMissingValueOkay.cmake
@@ -0,0 +1,6 @@
+cmake_policy(SET CMP0048 NEW)
+set(PROJECT_VERSION 1)
+project(ProjectA VERSION LANGUAGES NONE)
+get_property(langs GLOBAL PROPERTY ENABLED_LANGUAGES)
+message(STATUS "ENABLED_LANGUAGES='${langs}'")
+message(STATUS "PROJECT_VERSION='${PROJECT_VERSION}'")
diff --git a/Tests/RunCMake/project/VersionTwice-result.txt b/Tests/RunCMake/project/VersionTwice-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/project/VersionTwice-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/project/VersionTwice-stderr.txt b/Tests/RunCMake/project/VersionTwice-stderr.txt
new file mode 100644
index 000000000..ec07ead0f
--- /dev/null
+++ b/Tests/RunCMake/project/VersionTwice-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at VersionTwice.cmake:2 \(project\):
+ VERSION may be specified at most once.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/project/VersionTwice.cmake b/Tests/RunCMake/project/VersionTwice.cmake
new file mode 100644
index 000000000..dc0c996cf
--- /dev/null
+++ b/Tests/RunCMake/project/VersionTwice.cmake
@@ -0,0 +1,3 @@
+cmake_policy(SET CMP0048 NEW)
+project(ProjectA VERSION 1 VERSION)
+message("This line not reached.")
diff --git a/Tests/RunCMake/pseudo_emulator.c b/Tests/RunCMake/pseudo_emulator.c
new file mode 100644
index 000000000..9308f75aa
--- /dev/null
+++ b/Tests/RunCMake/pseudo_emulator.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+int main(int argc, char * argv[] )
+{
+ int ii;
+
+ printf("Command:");
+ for(ii = 1; ii < argc; ++ii)
+ {
+ printf(" \"%s\"", argv[ii]);
+ }
+ printf("\n");
+
+ return 42;
+}
diff --git a/Tests/RunCMake/pseudo_iwyu.c b/Tests/RunCMake/pseudo_iwyu.c
new file mode 100644
index 000000000..1e25de74c
--- /dev/null
+++ b/Tests/RunCMake/pseudo_iwyu.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main(void)
+{
+ fprintf(stderr, "should add these lines:\n#include <...>\n");
+ return 0;
+}
diff --git a/Tests/RunCMake/return/CMakeLists.txt b/Tests/RunCMake/return/CMakeLists.txt
new file mode 100644
index 000000000..ef2163c29
--- /dev/null
+++ b/Tests/RunCMake/return/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.1)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/return/ReturnFromForeach-result.txt b/Tests/RunCMake/return/ReturnFromForeach-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/return/ReturnFromForeach-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/return/ReturnFromForeach.cmake b/Tests/RunCMake/return/ReturnFromForeach.cmake
new file mode 100644
index 000000000..c71cf33d1
--- /dev/null
+++ b/Tests/RunCMake/return/ReturnFromForeach.cmake
@@ -0,0 +1,10 @@
+function(foo)
+ foreach(i RANGE 1 3)
+ foreach(j RANGE 1 3)
+ return()
+ message(FATAL_ERROR "unexpected")
+ endforeach()
+ endforeach()
+endfunction(foo)
+
+foo()
diff --git a/Tests/RunCMake/return/RunCMakeTest.cmake b/Tests/RunCMake/return/RunCMakeTest.cmake
new file mode 100644
index 000000000..2cc6c9d32
--- /dev/null
+++ b/Tests/RunCMake/return/RunCMakeTest.cmake
@@ -0,0 +1,3 @@
+include(RunCMake)
+
+run_cmake(ReturnFromForeach)
diff --git a/Tests/RunCMake/set/CMakeLists.txt b/Tests/RunCMake/set/CMakeLists.txt
new file mode 100644
index 000000000..4b3de84d9
--- /dev/null
+++ b/Tests/RunCMake/set/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/set/ParentPulling-stderr.txt b/Tests/RunCMake/set/ParentPulling-stderr.txt
new file mode 100644
index 000000000..768549bfa
--- /dev/null
+++ b/Tests/RunCMake/set/ParentPulling-stderr.txt
@@ -0,0 +1,3 @@
+^before PARENT_SCOPE blah=value2
+after PARENT_SCOPE blah=value2
+in parent scope, blah=value2$
diff --git a/Tests/RunCMake/set/ParentPulling.cmake b/Tests/RunCMake/set/ParentPulling.cmake
new file mode 100644
index 000000000..2614533f4
--- /dev/null
+++ b/Tests/RunCMake/set/ParentPulling.cmake
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 3.0)
+project(Minimal NONE)
+
+function(test_set)
+ set(blah "value2")
+ message("before PARENT_SCOPE blah=${blah}")
+ set(blah ${blah} PARENT_SCOPE)
+ message("after PARENT_SCOPE blah=${blah}")
+endfunction()
+
+set(blah value1)
+test_set()
+message("in parent scope, blah=${blah}")
diff --git a/Tests/RunCMake/set/ParentPullingRecursive-stderr.txt b/Tests/RunCMake/set/ParentPullingRecursive-stderr.txt
new file mode 100644
index 000000000..f3260aea9
--- /dev/null
+++ b/Tests/RunCMake/set/ParentPullingRecursive-stderr.txt
@@ -0,0 +1,144 @@
+----------
+variable values at top before calls:
+top_implicit_inner_set: -->top<--
+top_implicit_inner_unset: <undefined>
+top_explicit_inner_set: -->top<--
+top_explicit_inner_unset: <undefined>
+top_explicit_inner_tounset: -->top<--
+top_implicit_outer_set: -->top<--
+top_explicit_outer_unset: <undefined>
+top_explicit_outer_set: -->top<--
+top_explicit_outer_unset: <undefined>
+top_explicit_outer_tounset: -->top<--
+outer_implicit_inner_set: <undefined>
+outer_implicit_inner_unset: <undefined>
+outer_explicit_inner_set: <undefined>
+outer_explicit_inner_unset: <undefined>
+outer_explicit_inner_tounset: <undefined>
+----------
+----------
+variable values at outer start:
+top_implicit_inner_set: -->top<--
+top_implicit_inner_unset: <undefined>
+top_explicit_inner_set: -->top<--
+top_explicit_inner_unset: <undefined>
+top_explicit_inner_tounset: -->top<--
+top_implicit_outer_set: -->top<--
+top_explicit_outer_unset: <undefined>
+top_explicit_outer_set: -->top<--
+top_explicit_outer_unset: <undefined>
+top_explicit_outer_tounset: -->top<--
+outer_implicit_inner_set: <undefined>
+outer_implicit_inner_unset: <undefined>
+outer_explicit_inner_set: <undefined>
+outer_explicit_inner_unset: <undefined>
+outer_explicit_inner_tounset: <undefined>
+----------
+----------
+variable values at outer before inner:
+top_implicit_inner_set: -->top<--
+top_implicit_inner_unset: <undefined>
+top_explicit_inner_set: -->top<--
+top_explicit_inner_unset: <undefined>
+top_explicit_inner_tounset: -->top<--
+top_implicit_outer_set: -->top<--
+top_explicit_outer_unset: <undefined>
+top_explicit_outer_set: -->top<--
+top_explicit_outer_unset: <undefined>
+top_explicit_outer_tounset: -->top<--
+outer_implicit_inner_set: -->outer<--
+outer_implicit_inner_unset: <undefined>
+outer_explicit_inner_set: -->outer<--
+outer_explicit_inner_unset: <undefined>
+outer_explicit_inner_tounset: -->outer<--
+----------
+----------
+variable values at inner start:
+top_implicit_inner_set: -->top<--
+top_implicit_inner_unset: <undefined>
+top_explicit_inner_set: -->top<--
+top_explicit_inner_unset: <undefined>
+top_explicit_inner_tounset: -->top<--
+top_implicit_outer_set: -->top<--
+top_explicit_outer_unset: <undefined>
+top_explicit_outer_set: -->top<--
+top_explicit_outer_unset: <undefined>
+top_explicit_outer_tounset: -->top<--
+outer_implicit_inner_set: -->outer<--
+outer_implicit_inner_unset: <undefined>
+outer_explicit_inner_set: -->outer<--
+outer_explicit_inner_unset: <undefined>
+outer_explicit_inner_tounset: -->outer<--
+----------
+----------
+variable values at inner end:
+top_implicit_inner_set: -->top<--
+top_implicit_inner_unset: <undefined>
+top_explicit_inner_set: -->top<--
+top_explicit_inner_unset: <undefined>
+top_explicit_inner_tounset: -->top<--
+top_implicit_outer_set: -->top<--
+top_explicit_outer_unset: <undefined>
+top_explicit_outer_set: -->top<--
+top_explicit_outer_unset: <undefined>
+top_explicit_outer_tounset: -->top<--
+outer_implicit_inner_set: -->outer<--
+outer_implicit_inner_unset: <undefined>
+outer_explicit_inner_set: -->outer<--
+outer_explicit_inner_unset: <undefined>
+outer_explicit_inner_tounset: -->outer<--
+----------
+----------
+variable values at outer after inner:
+top_implicit_inner_set: -->top<--
+top_implicit_inner_unset: <undefined>
+top_explicit_inner_set: -->inner<--
+top_explicit_inner_unset: -->inner<--
+top_explicit_inner_tounset: <undefined>
+top_implicit_outer_set: -->top<--
+top_explicit_outer_unset: <undefined>
+top_explicit_outer_set: -->top<--
+top_explicit_outer_unset: <undefined>
+top_explicit_outer_tounset: -->top<--
+outer_implicit_inner_set: -->outer<--
+outer_implicit_inner_unset: <undefined>
+outer_explicit_inner_set: -->inner<--
+outer_explicit_inner_unset: -->inner<--
+outer_explicit_inner_tounset: <undefined>
+----------
+----------
+variable values at outer end:
+top_implicit_inner_set: -->top<--
+top_implicit_inner_unset: <undefined>
+top_explicit_inner_set: -->inner<--
+top_explicit_inner_unset: -->inner<--
+top_explicit_inner_tounset: <undefined>
+top_implicit_outer_set: -->top<--
+top_explicit_outer_unset: <undefined>
+top_explicit_outer_set: -->top<--
+top_explicit_outer_unset: <undefined>
+top_explicit_outer_tounset: -->top<--
+outer_implicit_inner_set: -->outer<--
+outer_implicit_inner_unset: <undefined>
+outer_explicit_inner_set: -->inner<--
+outer_explicit_inner_unset: -->inner<--
+outer_explicit_inner_tounset: <undefined>
+----------
+----------
+variable values at top after calls:
+top_implicit_inner_set: -->top<--
+top_implicit_inner_unset: <undefined>
+top_explicit_inner_set: -->outer<--
+top_explicit_inner_unset: -->outer<--
+top_explicit_inner_tounset: <undefined>
+top_implicit_outer_set: -->top<--
+top_explicit_outer_unset: -->outer<--
+top_explicit_outer_set: -->outer<--
+top_explicit_outer_unset: -->outer<--
+top_explicit_outer_tounset: <undefined>
+outer_implicit_inner_set: <undefined>
+outer_implicit_inner_unset: <undefined>
+outer_explicit_inner_set: <undefined>
+outer_explicit_inner_unset: <undefined>
+outer_explicit_inner_tounset: <undefined>
+----------
diff --git a/Tests/RunCMake/set/ParentPullingRecursive.cmake b/Tests/RunCMake/set/ParentPullingRecursive.cmake
new file mode 100644
index 000000000..a3e29f5b8
--- /dev/null
+++ b/Tests/RunCMake/set/ParentPullingRecursive.cmake
@@ -0,0 +1,104 @@
+cmake_minimum_required(VERSION 3.0)
+project(Minimal NONE)
+
+function(report where)
+ message("----------")
+ message("variable values at ${where}:")
+ foreach(var IN ITEMS
+ top_implicit_inner_set top_implicit_inner_unset
+ top_explicit_inner_set top_explicit_inner_unset top_explicit_inner_tounset
+ top_implicit_outer_set top_explicit_outer_unset
+ top_explicit_outer_set top_explicit_outer_unset top_explicit_outer_tounset
+
+ outer_implicit_inner_set outer_implicit_inner_unset
+ outer_explicit_inner_set outer_explicit_inner_unset outer_explicit_inner_tounset)
+ if(DEFINED ${var})
+ message("${var}: -->${${var}}<--")
+ else()
+ message("${var}: <undefined>")
+ endif()
+ endforeach()
+ message("----------")
+endfunction()
+
+macro(set_values upscope downscope value)
+ # Pull the value in implicitly.
+ set(dummy ${${upscope}_implicit_${downscope}_set})
+ set(dummy ${${upscope}_implicit_${downscope}_unset})
+ # Pull it down explicitly.
+ set(${upscope}_explicit_${downscope}_set "${value}" PARENT_SCOPE)
+ set(${upscope}_explicit_${downscope}_unset "${value}" PARENT_SCOPE)
+ set(${upscope}_explicit_${downscope}_tounset PARENT_SCOPE)
+endmacro()
+
+function(inner)
+ report("inner start")
+
+ set_values(top inner inner)
+ set_values(outer inner inner)
+
+ report("inner end")
+endfunction()
+
+function(outer)
+ report("outer start")
+
+ set_values(top outer outer)
+
+ # Set values for inner to manipulate.
+ set(outer_implicit_inner_set outer)
+ set(outer_implicit_inner_unset)
+ set(outer_explicit_inner_set outer)
+ set(outer_explicit_inner_unset)
+ set(outer_explicit_inner_tounset outer)
+
+ report("outer before inner")
+
+ inner()
+
+ report("outer after inner")
+
+ # Do what inner does so that we can test the values that inner should have
+ # pulled through to here.
+ set_values(top inner outer)
+
+ report("outer end")
+endfunction()
+
+# variable name is:
+#
+# <upscope>_<pulltype>_<downscope>_<settype>
+#
+# where the value is the name of the scope it was set in. The scopes available
+# are "top", "outer", and "inner". The pull type may either be "implicit" or
+# "explicit" based on whether the pull is due to a variable dereference or a
+# PARENT_SCOPE setting. The settype is "set" where both scopes set a value,
+# "unset" where upscope unsets it and downscope sets it, and "tounset" where
+# upscope sets it and downscope unsets it.
+#
+# We test the following combinations:
+#
+# - outer overriding top's values;
+# - inner overriding top's values;
+# - inner overriding outer's values; and
+# - outer overriding inner's values in top after inner has run.
+
+# Set values for inner to manipulate.
+set(top_implicit_inner_set top)
+set(top_implicit_inner_unset)
+set(top_explicit_inner_set top)
+set(top_explicit_inner_unset)
+set(top_explicit_inner_tounset top)
+
+# Set values for outer to manipulate.
+set(top_implicit_outer_set top)
+set(top_implicit_outer_unset)
+set(top_explicit_outer_set top)
+set(top_explicit_outer_unset)
+set(top_explicit_outer_tounset top)
+
+report("top before calls")
+
+outer()
+
+report("top after calls")
diff --git a/Tests/RunCMake/set/ParentScope-result.txt b/Tests/RunCMake/set/ParentScope-result.txt
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/Tests/RunCMake/set/ParentScope-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/set/ParentScope.cmake b/Tests/RunCMake/set/ParentScope.cmake
new file mode 100644
index 000000000..9bd6bcace
--- /dev/null
+++ b/Tests/RunCMake/set/ParentScope.cmake
@@ -0,0 +1,33 @@
+set(FOO )
+set(BAR "bar")
+set(BAZ "baz")
+set(BOO "boo")
+
+function(_parent_scope)
+ set(FOO "foo" PARENT_SCOPE)
+ set(BAR "" PARENT_SCOPE)
+ set(BAZ PARENT_SCOPE)
+ unset(BOO PARENT_SCOPE)
+endfunction()
+
+_parent_scope()
+
+if(NOT DEFINED FOO)
+ message(FATAL_ERROR "FOO not defined")
+elseif(NOT "${FOO}" STREQUAL "foo")
+ message(FATAL_ERROR "FOO should be \"foo\", not \"${FOO}\"")
+endif()
+
+if(NOT DEFINED BAR)
+ message(FATAL_ERROR "BAR not defined")
+elseif(NOT "${BAR}" STREQUAL "")
+ message(FATAL_ERROR "BAR should be an empty string, not \"${BAR}\"")
+endif()
+
+if(DEFINED BAZ)
+ message(FATAL_ERROR "BAZ defined")
+endif()
+
+if(DEFINED BOO)
+ message(FATAL_ERROR "BOO defined")
+endif()
diff --git a/Tests/RunCMake/set/RunCMakeTest.cmake b/Tests/RunCMake/set/RunCMakeTest.cmake
new file mode 100644
index 000000000..b8e8cf1f9
--- /dev/null
+++ b/Tests/RunCMake/set/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(ParentScope)
+run_cmake(ParentPulling)
+run_cmake(ParentPullingRecursive)
diff --git a/Tests/RunCMake/set_property/CMakeLists.txt b/Tests/RunCMake/set_property/CMakeLists.txt
new file mode 100644
index 000000000..18dfd2686
--- /dev/null
+++ b/Tests/RunCMake/set_property/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.2)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/set_property/COMPILE_DEFINITIONS-stdout.txt b/Tests/RunCMake/set_property/COMPILE_DEFINITIONS-stdout.txt
new file mode 100644
index 000000000..dd5bae1e7
--- /dev/null
+++ b/Tests/RunCMake/set_property/COMPILE_DEFINITIONS-stdout.txt
@@ -0,0 +1,2 @@
+-- Target COMPILE_DEFINITIONS is 'a;b;c;d;;e'
+-- Directory COMPILE_DEFINITIONS is 'a;b;c;d;;e'
diff --git a/Tests/RunCMake/set_property/COMPILE_DEFINITIONS.cmake b/Tests/RunCMake/set_property/COMPILE_DEFINITIONS.cmake
new file mode 100644
index 000000000..f0c63bf0f
--- /dev/null
+++ b/Tests/RunCMake/set_property/COMPILE_DEFINITIONS.cmake
@@ -0,0 +1,3 @@
+include(Common.cmake)
+test_target_property(COMPILE_DEFINITIONS)
+test_directory_property(COMPILE_DEFINITIONS)
diff --git a/Tests/RunCMake/set_property/COMPILE_FEATURES-stdout.txt b/Tests/RunCMake/set_property/COMPILE_FEATURES-stdout.txt
new file mode 100644
index 000000000..bd5a99246
--- /dev/null
+++ b/Tests/RunCMake/set_property/COMPILE_FEATURES-stdout.txt
@@ -0,0 +1 @@
+-- Target COMPILE_FEATURES is 'a;b;c;d;;e'
diff --git a/Tests/RunCMake/set_property/COMPILE_FEATURES.cmake b/Tests/RunCMake/set_property/COMPILE_FEATURES.cmake
new file mode 100644
index 000000000..1ab52ef9d
--- /dev/null
+++ b/Tests/RunCMake/set_property/COMPILE_FEATURES.cmake
@@ -0,0 +1,2 @@
+include(Common.cmake)
+test_target_property(COMPILE_FEATURES)
diff --git a/Tests/RunCMake/set_property/COMPILE_OPTIONS-stdout.txt b/Tests/RunCMake/set_property/COMPILE_OPTIONS-stdout.txt
new file mode 100644
index 000000000..1a2050134
--- /dev/null
+++ b/Tests/RunCMake/set_property/COMPILE_OPTIONS-stdout.txt
@@ -0,0 +1,2 @@
+-- Target COMPILE_OPTIONS is 'a;b;c;d;;e'
+-- Directory COMPILE_OPTIONS is 'a;b;c;d;;e'
diff --git a/Tests/RunCMake/set_property/COMPILE_OPTIONS.cmake b/Tests/RunCMake/set_property/COMPILE_OPTIONS.cmake
new file mode 100644
index 000000000..75f053541
--- /dev/null
+++ b/Tests/RunCMake/set_property/COMPILE_OPTIONS.cmake
@@ -0,0 +1,3 @@
+include(Common.cmake)
+test_target_property(COMPILE_OPTIONS)
+test_directory_property(COMPILE_OPTIONS)
diff --git a/Tests/RunCMake/set_property/Common.cmake b/Tests/RunCMake/set_property/Common.cmake
new file mode 100644
index 000000000..9d5e4f4e8
--- /dev/null
+++ b/Tests/RunCMake/set_property/Common.cmake
@@ -0,0 +1,28 @@
+macro(test_target_property PROP)
+ add_custom_target(CustomTarget)
+ set_property(TARGET CustomTarget PROPERTY ${PROP} x)
+ set_property(TARGET CustomTarget PROPERTY ${PROP})
+ set_property(TARGET CustomTarget APPEND PROPERTY ${PROP})
+ set_property(TARGET CustomTarget PROPERTY ${PROP} a)
+ set_property(TARGET CustomTarget APPEND PROPERTY ${PROP} "")
+ set_property(TARGET CustomTarget APPEND PROPERTY ${PROP} b c)
+ set_property(TARGET CustomTarget APPEND PROPERTY ${PROP})
+ set_property(TARGET CustomTarget APPEND PROPERTY ${PROP} "d;;e")
+ get_property(val TARGET CustomTarget PROPERTY ${PROP})
+ message(STATUS "Target ${PROP} is '${val}'")
+ set_property(TARGET CustomTarget PROPERTY ${PROP})
+endmacro()
+
+macro(test_directory_property PROP)
+ set_property(DIRECTORY PROPERTY ${PROP} x)
+ set_property(DIRECTORY PROPERTY ${PROP})
+ set_property(DIRECTORY APPEND PROPERTY ${PROP})
+ set_property(DIRECTORY PROPERTY ${PROP} a)
+ set_property(DIRECTORY APPEND PROPERTY ${PROP} "")
+ set_property(DIRECTORY APPEND PROPERTY ${PROP} b c)
+ set_property(DIRECTORY APPEND PROPERTY ${PROP})
+ set_property(DIRECTORY APPEND PROPERTY ${PROP} "d;;e")
+ get_property(val DIRECTORY PROPERTY ${PROP})
+ message(STATUS "Directory ${PROP} is '${val}'")
+ set_property(DIRECTORY PROPERTY ${PROP})
+endmacro()
diff --git a/Tests/RunCMake/set_property/INCLUDE_DIRECTORIES-stdout.txt b/Tests/RunCMake/set_property/INCLUDE_DIRECTORIES-stdout.txt
new file mode 100644
index 000000000..c957dd531
--- /dev/null
+++ b/Tests/RunCMake/set_property/INCLUDE_DIRECTORIES-stdout.txt
@@ -0,0 +1,2 @@
+-- Target INCLUDE_DIRECTORIES is 'a;b;c;d;;e'
+-- Directory INCLUDE_DIRECTORIES is 'a;b;c;d;;e'
diff --git a/Tests/RunCMake/set_property/INCLUDE_DIRECTORIES.cmake b/Tests/RunCMake/set_property/INCLUDE_DIRECTORIES.cmake
new file mode 100644
index 000000000..c9a91516a
--- /dev/null
+++ b/Tests/RunCMake/set_property/INCLUDE_DIRECTORIES.cmake
@@ -0,0 +1,3 @@
+include(Common.cmake)
+test_target_property(INCLUDE_DIRECTORIES)
+test_directory_property(INCLUDE_DIRECTORIES)
diff --git a/Tests/RunCMake/set_property/LINK_LIBRARIES-stdout.txt b/Tests/RunCMake/set_property/LINK_LIBRARIES-stdout.txt
new file mode 100644
index 000000000..9a3988e25
--- /dev/null
+++ b/Tests/RunCMake/set_property/LINK_LIBRARIES-stdout.txt
@@ -0,0 +1 @@
+-- Target LINK_LIBRARIES is 'a;b;c;d;;e'
diff --git a/Tests/RunCMake/set_property/LINK_LIBRARIES.cmake b/Tests/RunCMake/set_property/LINK_LIBRARIES.cmake
new file mode 100644
index 000000000..5155f59c4
--- /dev/null
+++ b/Tests/RunCMake/set_property/LINK_LIBRARIES.cmake
@@ -0,0 +1,2 @@
+include(Common.cmake)
+test_target_property(LINK_LIBRARIES)
diff --git a/Tests/RunCMake/set_property/RunCMakeTest.cmake b/Tests/RunCMake/set_property/RunCMakeTest.cmake
new file mode 100644
index 000000000..37c712447
--- /dev/null
+++ b/Tests/RunCMake/set_property/RunCMakeTest.cmake
@@ -0,0 +1,9 @@
+include(RunCMake)
+
+run_cmake(COMPILE_DEFINITIONS)
+run_cmake(COMPILE_FEATURES)
+run_cmake(COMPILE_OPTIONS)
+run_cmake(INCLUDE_DIRECTORIES)
+run_cmake(LINK_LIBRARIES)
+run_cmake(SOURCES)
+run_cmake(USER_PROP)
diff --git a/Tests/RunCMake/set_property/SOURCES-stdout.txt b/Tests/RunCMake/set_property/SOURCES-stdout.txt
new file mode 100644
index 000000000..921d5b165
--- /dev/null
+++ b/Tests/RunCMake/set_property/SOURCES-stdout.txt
@@ -0,0 +1 @@
+-- Target SOURCES is 'a;b;c;d;e'
diff --git a/Tests/RunCMake/set_property/SOURCES.cmake b/Tests/RunCMake/set_property/SOURCES.cmake
new file mode 100644
index 000000000..820641e00
--- /dev/null
+++ b/Tests/RunCMake/set_property/SOURCES.cmake
@@ -0,0 +1,2 @@
+include(Common.cmake)
+test_target_property(SOURCES)
diff --git a/Tests/RunCMake/set_property/USER_PROP-stdout.txt b/Tests/RunCMake/set_property/USER_PROP-stdout.txt
new file mode 100644
index 000000000..107cc8742
--- /dev/null
+++ b/Tests/RunCMake/set_property/USER_PROP-stdout.txt
@@ -0,0 +1,2 @@
+-- Target USER_PROP is 'a;b;c;d;;e'
+-- Directory USER_PROP is 'a;b;c;d;;e'
diff --git a/Tests/RunCMake/set_property/USER_PROP.cmake b/Tests/RunCMake/set_property/USER_PROP.cmake
new file mode 100644
index 000000000..aa0aa8370
--- /dev/null
+++ b/Tests/RunCMake/set_property/USER_PROP.cmake
@@ -0,0 +1,3 @@
+include(Common.cmake)
+test_target_property(USER_PROP)
+test_directory_property(USER_PROP)
diff --git a/Tests/RunCMake/string/Append.cmake b/Tests/RunCMake/string/Append.cmake
new file mode 100644
index 000000000..2634274bf
--- /dev/null
+++ b/Tests/RunCMake/string/Append.cmake
@@ -0,0 +1,58 @@
+set(out)
+string(APPEND out)
+if(DEFINED out)
+ message(FATAL_ERROR "\"string(APPEND out)\" set out to \"${out}\"")
+endif()
+
+set(out "")
+string(APPEND out)
+if(NOT out STREQUAL "")
+ message(FATAL_ERROR "\"string(APPEND out)\" set out to \"${out}\"")
+endif()
+
+set(out x)
+string(APPEND out)
+if(NOT out STREQUAL "x")
+ message(FATAL_ERROR "\"string(APPEND out)\" set out to \"${out}\"")
+endif()
+
+
+set(out)
+string(APPEND out a)
+if(NOT out STREQUAL "a")
+ message(FATAL_ERROR "\"string(APPEND out a)\" set out to \"${out}\"")
+endif()
+
+set(out "")
+string(APPEND out a)
+if(NOT out STREQUAL "a")
+ message(FATAL_ERROR "\"string(APPEND out a)\" set out to \"${out}\"")
+endif()
+
+set(out x)
+string(APPEND out a)
+if(NOT out STREQUAL "xa")
+ message(FATAL_ERROR "\"string(APPEND out a)\" set out to \"${out}\"")
+endif()
+
+
+set(out x)
+string(APPEND out a "b")
+if(NOT out STREQUAL "xab")
+ message(FATAL_ERROR "\"string(APPEND out a \"b\")\" set out to \"${out}\"")
+endif()
+
+set(b)
+set(out x)
+string(APPEND out ${b})
+if(NOT out STREQUAL "x")
+ message(FATAL_ERROR "\"string(APPEND out \${b})\" set out to \"${out}\"")
+endif()
+
+set(b b)
+set(out x)
+string(APPEND out a "${b}" [[
+${c}]])
+if(NOT out STREQUAL "xab\${c}")
+ message(FATAL_ERROR "\"string(APPEND out a \"\${b}\" [[\${c}]])\" set out to \"${out}\"")
+endif()
diff --git a/Tests/RunCMake/string/AppendNoArgs-result.txt b/Tests/RunCMake/string/AppendNoArgs-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/string/AppendNoArgs-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/string/AppendNoArgs-stderr.txt b/Tests/RunCMake/string/AppendNoArgs-stderr.txt
new file mode 100644
index 000000000..75ad427fd
--- /dev/null
+++ b/Tests/RunCMake/string/AppendNoArgs-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at AppendNoArgs.cmake:1 \(string\):
+ string sub-command APPEND requires at least one argument.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/string/AppendNoArgs.cmake b/Tests/RunCMake/string/AppendNoArgs.cmake
new file mode 100644
index 000000000..f54fb7719
--- /dev/null
+++ b/Tests/RunCMake/string/AppendNoArgs.cmake
@@ -0,0 +1 @@
+string(APPEND)
diff --git a/Tests/RunCMake/string/CMakeLists.txt b/Tests/RunCMake/string/CMakeLists.txt
new file mode 100644
index 000000000..12cd3c775
--- /dev/null
+++ b/Tests/RunCMake/string/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/string/Concat.cmake b/Tests/RunCMake/string/Concat.cmake
new file mode 100644
index 000000000..7260c95dd
--- /dev/null
+++ b/Tests/RunCMake/string/Concat.cmake
@@ -0,0 +1,19 @@
+set(b b)
+set(out x)
+string(CONCAT out)
+if(NOT out STREQUAL "")
+ message(FATAL_ERROR "\"string(CONCAT out)\" set out to \"${out}\"")
+endif()
+string(CONCAT out a)
+if(NOT out STREQUAL "a")
+ message(FATAL_ERROR "\"string(CONCAT out a)\" set out to \"${out}\"")
+endif()
+string(CONCAT out a "b")
+if(NOT out STREQUAL "ab")
+ message(FATAL_ERROR "\"string(CONCAT out a \"b\")\" set out to \"${out}\"")
+endif()
+string(CONCAT out a "${b}" [[
+${c}]])
+if(NOT out STREQUAL "ab\${c}")
+ message(FATAL_ERROR "\"string(CONCAT out a \"\${b}\" [[\${c}]])\" set out to \"${out}\"")
+endif()
diff --git a/Tests/RunCMake/string/ConcatNoArgs-result.txt b/Tests/RunCMake/string/ConcatNoArgs-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/string/ConcatNoArgs-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/string/ConcatNoArgs-stderr.txt b/Tests/RunCMake/string/ConcatNoArgs-stderr.txt
new file mode 100644
index 000000000..efea5f1d8
--- /dev/null
+++ b/Tests/RunCMake/string/ConcatNoArgs-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at ConcatNoArgs.cmake:1 \(string\):
+ string sub-command CONCAT requires at least one argument.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/string/ConcatNoArgs.cmake b/Tests/RunCMake/string/ConcatNoArgs.cmake
new file mode 100644
index 000000000..ba2113662
--- /dev/null
+++ b/Tests/RunCMake/string/ConcatNoArgs.cmake
@@ -0,0 +1 @@
+string(CONCAT)
diff --git a/Tests/RunCMake/string/RegexClear-stderr.txt b/Tests/RunCMake/string/RegexClear-stderr.txt
new file mode 100644
index 000000000..22b01593f
--- /dev/null
+++ b/Tests/RunCMake/string/RegexClear-stderr.txt
@@ -0,0 +1,54 @@
+^Matched string properly
+results from: setting up initial state
+CMAKE_MATCH_0: -->01<--
+CMAKE_MATCH_1: -->0<--
+CMAKE_MATCH_2: -->1<--
+CMAKE_MATCH_COUNT: -->2<--
+Matched string properly
+results from: making a match inside of find_package
+CMAKE_MATCH_0: -->01<--
+CMAKE_MATCH_1: -->0<--
+CMAKE_MATCH_2: -->1<--
+CMAKE_MATCH_COUNT: -->2<--
+Matched nothing properly
+results from: making a failure inside of find_package
+CMAKE_MATCH_0: --><--
+CMAKE_MATCH_1: --><--
+CMAKE_MATCH_2: --><--
+CMAKE_MATCH_COUNT: -->0<--
+Matched nothing properly
+results from: checking after find_package
+CMAKE_MATCH_0: --><--
+CMAKE_MATCH_1: --><--
+CMAKE_MATCH_2: --><--
+CMAKE_MATCH_COUNT: -->0<--
+Matched nothing properly
+results from: clearing out results with a failing match
+CMAKE_MATCH_0: --><--
+CMAKE_MATCH_1: --><--
+CMAKE_MATCH_2: --><--
+CMAKE_MATCH_COUNT: -->0<--
+Matched string properly
+results from: making a successful match before add_subdirectory
+CMAKE_MATCH_0: -->01<--
+CMAKE_MATCH_1: -->0<--
+CMAKE_MATCH_2: -->1<--
+CMAKE_MATCH_COUNT: -->2<--
+Matched string properly
+results from: check for success in add_subdirectory
+CMAKE_MATCH_0: -->01<--
+CMAKE_MATCH_1: -->0<--
+CMAKE_MATCH_2: -->1<--
+CMAKE_MATCH_COUNT: -->2<--
+Matched nothing properly
+results from: failing inside of add_subdirectory
+CMAKE_MATCH_0: --><--
+CMAKE_MATCH_1: --><--
+CMAKE_MATCH_2: --><--
+CMAKE_MATCH_COUNT: -->0<--
+Matched string properly
+results from: ensuring the subdirectory did not interfere with the parent
+CMAKE_MATCH_0: -->01<--
+CMAKE_MATCH_1: -->0<--
+CMAKE_MATCH_2: -->1<--
+CMAKE_MATCH_COUNT: -->2<--$
diff --git a/Tests/RunCMake/string/RegexClear.cmake b/Tests/RunCMake/string/RegexClear.cmake
new file mode 100644
index 000000000..d5edaacd6
--- /dev/null
+++ b/Tests/RunCMake/string/RegexClear.cmake
@@ -0,0 +1,54 @@
+cmake_minimum_required (VERSION 3.0)
+project (RegexClear C)
+
+function (output_results msg)
+ message("results from: ${msg}")
+ message("CMAKE_MATCH_0: -->${CMAKE_MATCH_0}<--")
+ message("CMAKE_MATCH_1: -->${CMAKE_MATCH_1}<--")
+ message("CMAKE_MATCH_2: -->${CMAKE_MATCH_2}<--")
+ message("CMAKE_MATCH_COUNT: -->${CMAKE_MATCH_COUNT}<--")
+endfunction ()
+
+function (check_for_success msg)
+ if (CMAKE_MATCH_1 STREQUAL "0" AND
+ CMAKE_MATCH_2 STREQUAL "1")
+ message("Matched string properly")
+ else ()
+ message("Failed to match properly")
+ endif ()
+ output_results("${msg}")
+endfunction ()
+
+function (check_for_failure msg)
+ if (CMAKE_MATCH_1 STREQUAL "" AND
+ CMAKE_MATCH_2 STREQUAL "")
+ message("Matched nothing properly")
+ else ()
+ message("Found a match where there should be none")
+ endif ()
+ output_results("${msg}")
+endfunction ()
+
+macro (do_regex_success msg)
+ string(REGEX MATCH "(0)(1)" output "01")
+ check_for_success("${msg}")
+endmacro ()
+
+macro (do_regex_failure msg)
+ string(REGEX MATCH "(0)(1)" output "12")
+ check_for_failure("${msg}")
+endmacro ()
+
+do_regex_success("setting up initial state")
+
+list(INSERT CMAKE_MODULE_PATH 0
+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
+find_package(dummy) # Ensure cmMakefile::PushScope/PopScope work.
+
+check_for_failure("checking after find_package")
+do_regex_failure("clearing out results with a failing match")
+do_regex_success("making a successful match before add_subdirectory")
+
+add_subdirectory(subdir)
+
+check_for_success("ensuring the subdirectory did not interfere with the parent") # Ensure that the subdir didn't mess with this scope.
diff --git a/Tests/RunCMake/string/RunCMakeTest.cmake b/Tests/RunCMake/string/RunCMakeTest.cmake
new file mode 100644
index 000000000..8067d9dbf
--- /dev/null
+++ b/Tests/RunCMake/string/RunCMakeTest.cmake
@@ -0,0 +1,22 @@
+include(RunCMake)
+
+run_cmake(Append)
+run_cmake(AppendNoArgs)
+
+run_cmake(Concat)
+run_cmake(ConcatNoArgs)
+
+run_cmake(Uuid)
+run_cmake(UuidMissingNamespace)
+run_cmake(UuidMissingNamespaceValue)
+run_cmake(UuidBadNamespace)
+run_cmake(UuidMissingNameValue)
+run_cmake(UuidMissingTypeValue)
+run_cmake(UuidBadType)
+
+run_cmake(RegexClear)
+
+run_cmake(UTF-16BE)
+run_cmake(UTF-16LE)
+run_cmake(UTF-32BE)
+run_cmake(UTF-32LE)
diff --git a/Tests/RunCMake/string/UTF-16BE-stderr.txt b/Tests/RunCMake/string/UTF-16BE-stderr.txt
new file mode 100644
index 000000000..8254f875c
--- /dev/null
+++ b/Tests/RunCMake/string/UTF-16BE-stderr.txt
@@ -0,0 +1,2 @@
+Hello World
+Hello World
diff --git a/Tests/RunCMake/string/UTF-16BE.cmake b/Tests/RunCMake/string/UTF-16BE.cmake
new file mode 100644
index 000000000..da986c0cc
--- /dev/null
+++ b/Tests/RunCMake/string/UTF-16BE.cmake
@@ -0,0 +1,4 @@
+file(STRINGS UTF-16BE.txt str ENCODING UTF-16BE LENGTH_MINIMUM 4)
+message("${str}")
+file(STRINGS UTF-16BE.txt str LENGTH_MINIMUM 4)
+message("${str}")
diff --git a/Tests/RunCMake/string/UTF-16BE.txt b/Tests/RunCMake/string/UTF-16BE.txt
new file mode 100644
index 000000000..9d976bc64
--- /dev/null
+++ b/Tests/RunCMake/string/UTF-16BE.txt
Binary files differ
diff --git a/Tests/RunCMake/string/UTF-16LE-stderr.txt b/Tests/RunCMake/string/UTF-16LE-stderr.txt
new file mode 100644
index 000000000..8254f875c
--- /dev/null
+++ b/Tests/RunCMake/string/UTF-16LE-stderr.txt
@@ -0,0 +1,2 @@
+Hello World
+Hello World
diff --git a/Tests/RunCMake/string/UTF-16LE.cmake b/Tests/RunCMake/string/UTF-16LE.cmake
new file mode 100644
index 000000000..326d848d2
--- /dev/null
+++ b/Tests/RunCMake/string/UTF-16LE.cmake
@@ -0,0 +1,4 @@
+file(STRINGS UTF-16LE.txt str ENCODING UTF-16LE LENGTH_MINIMUM 4)
+message("${str}")
+file(STRINGS UTF-16LE.txt str LENGTH_MINIMUM 4)
+message("${str}")
diff --git a/Tests/RunCMake/string/UTF-16LE.txt b/Tests/RunCMake/string/UTF-16LE.txt
new file mode 100644
index 000000000..ebba8748b
--- /dev/null
+++ b/Tests/RunCMake/string/UTF-16LE.txt
Binary files differ
diff --git a/Tests/RunCMake/string/UTF-32BE-stderr.txt b/Tests/RunCMake/string/UTF-32BE-stderr.txt
new file mode 100644
index 000000000..8254f875c
--- /dev/null
+++ b/Tests/RunCMake/string/UTF-32BE-stderr.txt
@@ -0,0 +1,2 @@
+Hello World
+Hello World
diff --git a/Tests/RunCMake/string/UTF-32BE.cmake b/Tests/RunCMake/string/UTF-32BE.cmake
new file mode 100644
index 000000000..debdeaa73
--- /dev/null
+++ b/Tests/RunCMake/string/UTF-32BE.cmake
@@ -0,0 +1,4 @@
+file(STRINGS UTF-32BE.txt str ENCODING UTF-32BE LENGTH_MINIMUM 4)
+message("${str}")
+file(STRINGS UTF-32BE.txt str LENGTH_MINIMUM 4)
+message("${str}")
diff --git a/Tests/RunCMake/string/UTF-32BE.txt b/Tests/RunCMake/string/UTF-32BE.txt
new file mode 100644
index 000000000..6725fbb45
--- /dev/null
+++ b/Tests/RunCMake/string/UTF-32BE.txt
Binary files differ
diff --git a/Tests/RunCMake/string/UTF-32LE-stderr.txt b/Tests/RunCMake/string/UTF-32LE-stderr.txt
new file mode 100644
index 000000000..8254f875c
--- /dev/null
+++ b/Tests/RunCMake/string/UTF-32LE-stderr.txt
@@ -0,0 +1,2 @@
+Hello World
+Hello World
diff --git a/Tests/RunCMake/string/UTF-32LE.cmake b/Tests/RunCMake/string/UTF-32LE.cmake
new file mode 100644
index 000000000..22aab5f24
--- /dev/null
+++ b/Tests/RunCMake/string/UTF-32LE.cmake
@@ -0,0 +1,4 @@
+file(STRINGS UTF-32LE.txt str ENCODING UTF-32LE LENGTH_MINIMUM 4)
+message("${str}")
+file(STRINGS UTF-32LE.txt str LENGTH_MINIMUM 4)
+message("${str}")
diff --git a/Tests/RunCMake/string/UTF-32LE.txt b/Tests/RunCMake/string/UTF-32LE.txt
new file mode 100644
index 000000000..cf5102f58
--- /dev/null
+++ b/Tests/RunCMake/string/UTF-32LE.txt
Binary files differ
diff --git a/Tests/RunCMake/string/Uuid.cmake b/Tests/RunCMake/string/Uuid.cmake
new file mode 100644
index 000000000..2613d2682
--- /dev/null
+++ b/Tests/RunCMake/string/Uuid.cmake
@@ -0,0 +1,17 @@
+set(UUID_DNS_NAMESPACE 6ba7b810-9dad-11d1-80b4-00c04fd430c8)
+
+string(UUID WWW_EXAMPLE_COM_MD5_UUID
+ NAMESPACE ${UUID_DNS_NAMESPACE} NAME www.example.com TYPE MD5)
+
+if(NOT WWW_EXAMPLE_COM_MD5_UUID STREQUAL "5df41881-3aed-3515-88a7-2f4a814cf09e")
+ message(SEND_ERROR
+ "UUID did not create the expected MD5 result: ${WWW_EXAMPLE_COM_MD5_UUID}")
+endif()
+
+string(UUID WWW_EXAMPLE_COM_SHA1_UUID
+ NAMESPACE ${UUID_DNS_NAMESPACE} NAME www.example.com TYPE SHA1 UPPER)
+
+if(NOT WWW_EXAMPLE_COM_SHA1_UUID STREQUAL "2ED6657D-E927-568B-95E1-2665A8AEA6A2")
+ message(SEND_ERROR
+ "UUID did not create the expected SHA1 result: ${WWW_EXAMPLE_COM_SHA1_UUID}")
+endif()
diff --git a/Tests/RunCMake/string/UuidBadNamespace-result.txt b/Tests/RunCMake/string/UuidBadNamespace-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/string/UuidBadNamespace-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/string/UuidBadNamespace-stderr.txt b/Tests/RunCMake/string/UuidBadNamespace-stderr.txt
new file mode 100644
index 000000000..cb12903e1
--- /dev/null
+++ b/Tests/RunCMake/string/UuidBadNamespace-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at UuidBadNamespace.cmake:3 \(string\):
+ string UUID sub-command, malformed NAMESPACE UUID.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/string/UuidBadNamespace.cmake b/Tests/RunCMake/string/UuidBadNamespace.cmake
new file mode 100644
index 000000000..f6079252b
--- /dev/null
+++ b/Tests/RunCMake/string/UuidBadNamespace.cmake
@@ -0,0 +1,4 @@
+set(UUID_DNS_NAMESPACE 6ba7b810-9dad-fooo-80b4-00c04fd430c8)
+
+string(UUID WWW_EXAMPLE_COM_MD5_UUID
+ NAMESPACE ${UUID_DNS_NAMESPACE} NAME www.example.com TYPE MD5)
diff --git a/Tests/RunCMake/string/UuidBadType-result.txt b/Tests/RunCMake/string/UuidBadType-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/string/UuidBadType-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/string/UuidBadType-stderr.txt b/Tests/RunCMake/string/UuidBadType-stderr.txt
new file mode 100644
index 000000000..1993c044a
--- /dev/null
+++ b/Tests/RunCMake/string/UuidBadType-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at UuidBadType.cmake:3 \(string\):
+ string UUID sub-command, unknown TYPE 'FOO'.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/string/UuidBadType.cmake b/Tests/RunCMake/string/UuidBadType.cmake
new file mode 100644
index 000000000..bf4909e9c
--- /dev/null
+++ b/Tests/RunCMake/string/UuidBadType.cmake
@@ -0,0 +1,4 @@
+set(UUID_DNS_NAMESPACE 6ba7b810-9dad-11d1-80b4-00c04fd430c8)
+
+string(UUID WWW_EXAMPLE_COM_MD5_UUID
+ NAMESPACE ${UUID_DNS_NAMESPACE} NAME www.example.com TYPE FOO)
diff --git a/Tests/RunCMake/string/UuidMissingNameValue-result.txt b/Tests/RunCMake/string/UuidMissingNameValue-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/string/UuidMissingNameValue-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/string/UuidMissingNameValue-stderr.txt b/Tests/RunCMake/string/UuidMissingNameValue-stderr.txt
new file mode 100644
index 000000000..0b7cde463
--- /dev/null
+++ b/Tests/RunCMake/string/UuidMissingNameValue-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at UuidMissingNameValue.cmake:3 \(string\):
+ string UUID sub-command, NAME requires a value.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/string/UuidMissingNameValue.cmake b/Tests/RunCMake/string/UuidMissingNameValue.cmake
new file mode 100644
index 000000000..407a1d7f8
--- /dev/null
+++ b/Tests/RunCMake/string/UuidMissingNameValue.cmake
@@ -0,0 +1,4 @@
+set(UUID_DNS_NAMESPACE 6ba7b810-9dad-11d1-80b4-00c04fd430c8)
+
+string(UUID WWW_EXAMPLE_COM_MD5_UUID
+ NAMESPACE ${UUID_DNS_NAMESPACE} TYPE MD5 NAME)
diff --git a/Tests/RunCMake/string/UuidMissingNamespace-result.txt b/Tests/RunCMake/string/UuidMissingNamespace-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/string/UuidMissingNamespace-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/string/UuidMissingNamespace-stderr.txt b/Tests/RunCMake/string/UuidMissingNamespace-stderr.txt
new file mode 100644
index 000000000..dfcfe42b2
--- /dev/null
+++ b/Tests/RunCMake/string/UuidMissingNamespace-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at UuidMissingNamespace.cmake:3 \(string\):
+ string UUID sub-command, malformed NAMESPACE UUID.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/string/UuidMissingNamespace.cmake b/Tests/RunCMake/string/UuidMissingNamespace.cmake
new file mode 100644
index 000000000..5a71e4f70
--- /dev/null
+++ b/Tests/RunCMake/string/UuidMissingNamespace.cmake
@@ -0,0 +1,4 @@
+set(UUID_DNS_NAMESPACE 6ba7b810-9dad-11d1-80b4-00c04fd430c8)
+
+string(UUID WWW_EXAMPLE_COM_MD5_UUID
+ NAME www.example.com TYPE MD5)
diff --git a/Tests/RunCMake/string/UuidMissingNamespaceValue-result.txt b/Tests/RunCMake/string/UuidMissingNamespaceValue-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/string/UuidMissingNamespaceValue-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/string/UuidMissingNamespaceValue-stderr.txt b/Tests/RunCMake/string/UuidMissingNamespaceValue-stderr.txt
new file mode 100644
index 000000000..86585ad40
--- /dev/null
+++ b/Tests/RunCMake/string/UuidMissingNamespaceValue-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at UuidMissingNamespaceValue.cmake:3 \(string\):
+ string UUID sub-command, NAMESPACE requires a value.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/string/UuidMissingNamespaceValue.cmake b/Tests/RunCMake/string/UuidMissingNamespaceValue.cmake
new file mode 100644
index 000000000..f2219c0ff
--- /dev/null
+++ b/Tests/RunCMake/string/UuidMissingNamespaceValue.cmake
@@ -0,0 +1,4 @@
+set(UUID_DNS_NAMESPACE 6ba7b810-9dad-11d1-80b4-00c04fd430c8)
+
+string(UUID WWW_EXAMPLE_COM_MD5_UUID
+ NAME www.example.com TYPE MD5 NAMESPACE)
diff --git a/Tests/RunCMake/string/UuidMissingTypeValue-result.txt b/Tests/RunCMake/string/UuidMissingTypeValue-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/string/UuidMissingTypeValue-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/string/UuidMissingTypeValue-stderr.txt b/Tests/RunCMake/string/UuidMissingTypeValue-stderr.txt
new file mode 100644
index 000000000..70252f8cd
--- /dev/null
+++ b/Tests/RunCMake/string/UuidMissingTypeValue-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at UuidMissingTypeValue.cmake:3 \(string\):
+ string UUID sub-command, TYPE requires a value.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/string/UuidMissingTypeValue.cmake b/Tests/RunCMake/string/UuidMissingTypeValue.cmake
new file mode 100644
index 000000000..6678a4658
--- /dev/null
+++ b/Tests/RunCMake/string/UuidMissingTypeValue.cmake
@@ -0,0 +1,4 @@
+set(UUID_DNS_NAMESPACE 6ba7b810-9dad-11d1-80b4-00c04fd430c8)
+
+string(UUID WWW_EXAMPLE_COM_MD5_UUID
+ NAMESPACE ${UUID_DNS_NAMESPACE} NAME www.example.com TYPE)
diff --git a/Tests/RunCMake/string/cmake/Finddummy.cmake b/Tests/RunCMake/string/cmake/Finddummy.cmake
new file mode 100644
index 000000000..4cbc1fb4b
--- /dev/null
+++ b/Tests/RunCMake/string/cmake/Finddummy.cmake
@@ -0,0 +1,4 @@
+check_for_success("making a match inside of find_package")
+do_regex_failure("making a failure inside of find_package")
+
+set(dummy_FOUND 1)
diff --git a/Tests/RunCMake/string/subdir/CMakeLists.txt b/Tests/RunCMake/string/subdir/CMakeLists.txt
new file mode 100644
index 000000000..557330892
--- /dev/null
+++ b/Tests/RunCMake/string/subdir/CMakeLists.txt
@@ -0,0 +1,2 @@
+check_for_success("check for success in add_subdirectory")
+do_regex_failure("failing inside of add_subdirectory")
diff --git a/Tests/RunCMake/target_compile_features/CMakeLists.txt b/Tests/RunCMake/target_compile_features/CMakeLists.txt
new file mode 100644
index 000000000..3482e6baf
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.0)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/target_compile_features/RunCMakeTest.cmake b/Tests/RunCMake/target_compile_features/RunCMakeTest.cmake
new file mode 100644
index 000000000..33faf2bbb
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/RunCMakeTest.cmake
@@ -0,0 +1,13 @@
+include(RunCMake)
+
+run_cmake(not_enough_args)
+run_cmake(alias_target)
+run_cmake(utility_target)
+run_cmake(invalid_args)
+run_cmake(invalid_args_on_interface)
+run_cmake(imported_target)
+run_cmake(no_target)
+run_cmake(not_a_cxx_feature)
+run_cmake(no_matching_cxx_feature)
+run_cmake(not_a_c_feature)
+run_cmake(no_matching_c_feature)
diff --git a/Tests/RunCMake/target_compile_features/alias_target-result.txt b/Tests/RunCMake/target_compile_features/alias_target-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/alias_target-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_compile_features/alias_target-stderr.txt b/Tests/RunCMake/target_compile_features/alias_target-stderr.txt
new file mode 100644
index 000000000..417bf62aa
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/alias_target-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at alias_target.cmake:4 \(target_compile_features\):
+ target_compile_features can not be used on an ALIAS target.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/target_compile_features/alias_target.cmake b/Tests/RunCMake/target_compile_features/alias_target.cmake
new file mode 100644
index 000000000..d35ddba54
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/alias_target.cmake
@@ -0,0 +1,4 @@
+
+add_executable(main empty.cpp)
+add_executable(Alias::Main ALIAS main)
+target_compile_features(Alias::Main PRIVATE cxx_delegating_constructors)
diff --git a/Tests/RunCMake/target_compile_features/empty.c b/Tests/RunCMake/target_compile_features/empty.c
new file mode 100644
index 000000000..bfbbddeb9
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/empty.c
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/target_compile_features/empty.cpp b/Tests/RunCMake/target_compile_features/empty.cpp
new file mode 100644
index 000000000..bfbbddeb9
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/empty.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/target_compile_features/imported_target-result.txt b/Tests/RunCMake/target_compile_features/imported_target-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/imported_target-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_compile_features/imported_target-stderr.txt b/Tests/RunCMake/target_compile_features/imported_target-stderr.txt
new file mode 100644
index 000000000..c6ff5ec21
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/imported_target-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at imported_target.cmake:3 \(target_compile_features\):
+ Cannot specify compile features for imported target "main".
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/target_compile_features/imported_target.cmake b/Tests/RunCMake/target_compile_features/imported_target.cmake
new file mode 100644
index 000000000..e248c2fee
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/imported_target.cmake
@@ -0,0 +1,3 @@
+
+add_library(main INTERFACE IMPORTED)
+target_compile_features(main INTERFACE cxx_delegating_constructors)
diff --git a/Tests/RunCMake/target_compile_features/invalid_args-result.txt b/Tests/RunCMake/target_compile_features/invalid_args-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/invalid_args-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_compile_features/invalid_args-stderr.txt b/Tests/RunCMake/target_compile_features/invalid_args-stderr.txt
new file mode 100644
index 000000000..bd5b7b9d5
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/invalid_args-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at invalid_args.cmake:3 \(target_compile_features\):
+ target_compile_features called with invalid arguments
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/target_compile_features/invalid_args.cmake b/Tests/RunCMake/target_compile_features/invalid_args.cmake
new file mode 100644
index 000000000..1a7fb3749
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/invalid_args.cmake
@@ -0,0 +1,3 @@
+
+add_executable(main empty.cpp)
+target_compile_features(main INVALID cxx_delegating_constructors)
diff --git a/Tests/RunCMake/target_compile_features/invalid_args_on_interface-result.txt b/Tests/RunCMake/target_compile_features/invalid_args_on_interface-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/invalid_args_on_interface-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_compile_features/invalid_args_on_interface-stderr.txt b/Tests/RunCMake/target_compile_features/invalid_args_on_interface-stderr.txt
new file mode 100644
index 000000000..c30209a28
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/invalid_args_on_interface-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at invalid_args_on_interface.cmake:3 \(target_compile_features\):
+ target_compile_features may only be set INTERFACE properties on INTERFACE
+ targets
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/target_compile_features/invalid_args_on_interface.cmake b/Tests/RunCMake/target_compile_features/invalid_args_on_interface.cmake
new file mode 100644
index 000000000..324d0f384
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/invalid_args_on_interface.cmake
@@ -0,0 +1,3 @@
+
+add_library(main INTERFACE)
+target_compile_features(main PRIVATE cxx_delegating_constructors)
diff --git a/Tests/RunCMake/target_compile_features/no_matching_c_feature-result.txt b/Tests/RunCMake/target_compile_features/no_matching_c_feature-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/no_matching_c_feature-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_compile_features/no_matching_c_feature-stderr.txt b/Tests/RunCMake/target_compile_features/no_matching_c_feature-stderr.txt
new file mode 100644
index 000000000..96b959cf5
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/no_matching_c_feature-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at no_matching_c_feature.cmake:[0-9][0-9]? \((target_compile_features|message)\):
+ The compiler feature "gnu_c_dummy" is not known to C compiler
+
+ "GNU"
+
+ version 4.8.1.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/target_compile_features/no_matching_c_feature.cmake b/Tests/RunCMake/target_compile_features/no_matching_c_feature.cmake
new file mode 100644
index 000000000..a44caf29a
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/no_matching_c_feature.cmake
@@ -0,0 +1,15 @@
+
+if (NOT ";${CMAKE_C_COMPILE_FEATURES};" MATCHES ";gnu_c_typeof;")
+ # Simulate passing the test.
+ message(SEND_ERROR
+ "The compiler feature \"gnu_c_dummy\" is not known to C compiler\n\"GNU\"\nversion 4.8.1."
+ )
+ return()
+endif()
+
+add_executable(main empty.c)
+
+target_compile_features(main
+ PRIVATE
+ gnu_c_typeof
+)
diff --git a/Tests/RunCMake/target_compile_features/no_matching_cxx_feature-result.txt b/Tests/RunCMake/target_compile_features/no_matching_cxx_feature-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/no_matching_cxx_feature-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_compile_features/no_matching_cxx_feature-stderr.txt b/Tests/RunCMake/target_compile_features/no_matching_cxx_feature-stderr.txt
new file mode 100644
index 000000000..f976dfeab
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/no_matching_cxx_feature-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at no_matching_cxx_feature.cmake:[0-9][0-9]? \((target_compile_features|message)\):
+ The compiler feature "[^"]+" is not known to CXX compiler
+
+ "[^"]*"
+
+ version *[.0-9]+\.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/target_compile_features/no_matching_cxx_feature.cmake b/Tests/RunCMake/target_compile_features/no_matching_cxx_feature.cmake
new file mode 100644
index 000000000..ab1fd7608
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/no_matching_cxx_feature.cmake
@@ -0,0 +1,26 @@
+
+if (NOT ";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";gnu_cxx_typeof;"
+ AND NOT ";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";msvc_cxx_sealed;" )
+ # Simulate passing the test.
+ message(SEND_ERROR
+ "The compiler feature \"gnu_cxx_dummy\" is not known to CXX compiler\n\"GNU\"\nversion 4.8.1."
+ )
+ return()
+endif()
+
+if (";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";gnu_cxx_typeof;")
+ set(feature msvc_cxx_sealed)
+ if (";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";msvc_cxx_sealed;")
+ # If a compiler supports both extensions, remove one of them.
+ list(REMOVE_ITEM CMAKE_CXX_COMPILE_FEATURES msvc_cxx_sealed)
+ endif()
+else()
+ set(feature gnu_cxx_typeof)
+endif()
+
+add_executable(main empty.cpp)
+
+target_compile_features(main
+ PRIVATE
+ ${feature}
+)
diff --git a/Tests/RunCMake/target_compile_features/no_target-result.txt b/Tests/RunCMake/target_compile_features/no_target-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/no_target-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_compile_features/no_target-stderr.txt b/Tests/RunCMake/target_compile_features/no_target-stderr.txt
new file mode 100644
index 000000000..323ba7a90
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/no_target-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at no_target.cmake:2 \(target_compile_features\):
+ Cannot specify compile features for target "main" which is not built by
+ this project.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/target_compile_features/no_target.cmake b/Tests/RunCMake/target_compile_features/no_target.cmake
new file mode 100644
index 000000000..3f0afe273
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/no_target.cmake
@@ -0,0 +1,2 @@
+
+target_compile_features(main INTERFACE cxx_delegating_constructors)
diff --git a/Tests/RunCMake/target_compile_features/not_a_c_feature-result.txt b/Tests/RunCMake/target_compile_features/not_a_c_feature-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/not_a_c_feature-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_compile_features/not_a_c_feature-stderr.txt b/Tests/RunCMake/target_compile_features/not_a_c_feature-stderr.txt
new file mode 100644
index 000000000..6dd00f359
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/not_a_c_feature-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at not_a_c_feature.cmake:3 \(target_compile_features\):
+ target_compile_features specified unknown feature "c_not_a_feature" for
+ target "main".
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/target_compile_features/not_a_c_feature.cmake b/Tests/RunCMake/target_compile_features/not_a_c_feature.cmake
new file mode 100644
index 000000000..0420698bc
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/not_a_c_feature.cmake
@@ -0,0 +1,6 @@
+
+add_executable(main empty.c)
+target_compile_features(main
+ PRIVATE
+ c_not_a_feature
+)
diff --git a/Tests/RunCMake/target_compile_features/not_a_cxx_feature-result.txt b/Tests/RunCMake/target_compile_features/not_a_cxx_feature-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/not_a_cxx_feature-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_compile_features/not_a_cxx_feature-stderr.txt b/Tests/RunCMake/target_compile_features/not_a_cxx_feature-stderr.txt
new file mode 100644
index 000000000..efa2bad5f
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/not_a_cxx_feature-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at not_a_cxx_feature.cmake:3 \(target_compile_features\):
+ target_compile_features specified unknown feature "cxx_not_a_feature" for
+ target "main".
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/target_compile_features/not_a_cxx_feature.cmake b/Tests/RunCMake/target_compile_features/not_a_cxx_feature.cmake
new file mode 100644
index 000000000..0207b724d
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/not_a_cxx_feature.cmake
@@ -0,0 +1,6 @@
+
+add_executable(main empty.cpp)
+target_compile_features(main
+ PRIVATE
+ cxx_not_a_feature
+)
diff --git a/Tests/RunCMake/target_compile_features/not_enough_args-result.txt b/Tests/RunCMake/target_compile_features/not_enough_args-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/not_enough_args-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_compile_features/not_enough_args-stderr.txt b/Tests/RunCMake/target_compile_features/not_enough_args-stderr.txt
new file mode 100644
index 000000000..2f8d81243
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/not_enough_args-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at not_enough_args.cmake:3 \(target_compile_features\):
+ target_compile_features called with incorrect number of arguments
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/target_compile_features/not_enough_args.cmake b/Tests/RunCMake/target_compile_features/not_enough_args.cmake
new file mode 100644
index 000000000..95612300a
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/not_enough_args.cmake
@@ -0,0 +1,3 @@
+
+add_executable(main empty.cpp)
+target_compile_features(main)
diff --git a/Tests/RunCMake/target_compile_features/utility_target-result.txt b/Tests/RunCMake/target_compile_features/utility_target-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/utility_target-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_compile_features/utility_target-stderr.txt b/Tests/RunCMake/target_compile_features/utility_target-stderr.txt
new file mode 100644
index 000000000..d23905995
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/utility_target-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at utility_target.cmake:4 \(target_compile_features\):
+ target_compile_features called with non-compilable target type
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/target_compile_features/utility_target.cmake b/Tests/RunCMake/target_compile_features/utility_target.cmake
new file mode 100644
index 000000000..891905651
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/utility_target.cmake
@@ -0,0 +1,4 @@
+
+add_custom_target(utility)
+
+target_compile_features(utility PRIVATE cxx_delegating_constructors)
diff --git a/Tests/RunCMake/target_link_libraries/CMP0023-NEW-2-stderr.txt b/Tests/RunCMake/target_link_libraries/CMP0023-NEW-2-stderr.txt
index d27686d4b..8e3f3153b 100644
--- a/Tests/RunCMake/target_link_libraries/CMP0023-NEW-2-stderr.txt
+++ b/Tests/RunCMake/target_link_libraries/CMP0023-NEW-2-stderr.txt
@@ -1,9 +1,4 @@
CMake Error at CMP0023-NEW-2.cmake:11 \(target_link_libraries\):
- Policy CMP0023 is not set: Plain and keyword target_link_libraries
- signatures cannot be mixed. Run "cmake --help-policy CMP0023" for policy
- details. Use the cmake_policy command to set the policy and suppress this
- warning.
-
The plain signature for target_link_libraries has already been used with
the target "foo". All uses of target_link_libraries with a target must be
either all-keyword or all-plain.
diff --git a/Tests/RunCMake/target_link_libraries/CMP0023-NEW-stderr.txt b/Tests/RunCMake/target_link_libraries/CMP0023-NEW-stderr.txt
index d7be0ff38..2ef229034 100644
--- a/Tests/RunCMake/target_link_libraries/CMP0023-NEW-stderr.txt
+++ b/Tests/RunCMake/target_link_libraries/CMP0023-NEW-stderr.txt
@@ -1,9 +1,4 @@
CMake Error at CMP0023-NEW.cmake:11 \(target_link_libraries\):
- Policy CMP0023 is not set: Plain and keyword target_link_libraries
- signatures cannot be mixed. Run "cmake --help-policy CMP0023" for policy
- details. Use the cmake_policy command to set the policy and suppress this
- warning.
-
The plain signature for target_link_libraries has already been used with
the target "foo". All uses of target_link_libraries with a target must be
either all-keyword or all-plain.
diff --git a/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake b/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake
index f97022e1b..1466fbf61 100644
--- a/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake
+++ b/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake
@@ -6,3 +6,7 @@ run_cmake(CMP0023-WARN-2)
run_cmake(CMP0023-NEW-2)
run_cmake(MixedSignature)
run_cmake(Separate-PRIVATE-LINK_PRIVATE-uses)
+run_cmake(SubDirTarget)
+run_cmake(SharedDepNotTarget)
+run_cmake(StaticPrivateDepNotExported)
+run_cmake(StaticPrivateDepNotTarget)
diff --git a/Tests/RunCMake/target_link_libraries/SharedDepNotTarget.cmake b/Tests/RunCMake/target_link_libraries/SharedDepNotTarget.cmake
new file mode 100644
index 000000000..bab537edb
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/SharedDepNotTarget.cmake
@@ -0,0 +1,10 @@
+enable_language(C)
+set(CMAKE_LINK_DEPENDENT_LIBRARY_DIRS 1)
+set(CMAKE_SHARED_LIBRARY_SUFFIX ".so")
+add_library(imported SHARED IMPORTED)
+set_target_properties(imported PROPERTIES
+ IMPORTED_LOCATION "imported"
+ IMPORTED_LINK_DEPENDENT_LIBRARIES "/path/to/libSharedDep.so"
+ )
+add_executable(empty empty.c)
+target_link_libraries(empty imported)
diff --git a/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotExported-result.txt b/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotExported-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotExported-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotExported-stderr.txt b/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotExported-stderr.txt
new file mode 100644
index 000000000..6bb44ab4b
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotExported-stderr.txt
@@ -0,0 +1 @@
+CMake Error: install\(EXPORT "Exp" ...\) includes target "foo" which requires target "not_exported" that is not in the export set.
diff --git a/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotExported.cmake b/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotExported.cmake
new file mode 100644
index 000000000..9b97918a5
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotExported.cmake
@@ -0,0 +1,7 @@
+cmake_policy(SET CMP0022 NEW)
+enable_language(C)
+add_library(foo STATIC empty.c)
+add_library(not_exported STATIC empty.c)
+target_link_libraries(foo PRIVATE not_exported)
+install(TARGETS foo EXPORT Exp DESTINATION lib)
+install(EXPORT Exp DESTINATION lib/cmake/Exp)
diff --git a/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotTarget.cmake b/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotTarget.cmake
new file mode 100644
index 000000000..7122ae91e
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotTarget.cmake
@@ -0,0 +1,6 @@
+cmake_policy(SET CMP0022 NEW)
+enable_language(C)
+add_library(foo STATIC empty.c)
+target_link_libraries(foo PRIVATE not_a_target)
+install(TARGETS foo EXPORT Exp DESTINATION lib)
+install(EXPORT Exp DESTINATION lib/cmake/Exp)
diff --git a/Tests/RunCMake/target_link_libraries/SubDirTarget-result.txt b/Tests/RunCMake/target_link_libraries/SubDirTarget-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/SubDirTarget-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_link_libraries/SubDirTarget-stderr.txt b/Tests/RunCMake/target_link_libraries/SubDirTarget-stderr.txt
new file mode 100644
index 000000000..5cd1f23d7
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/SubDirTarget-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at SubDirTarget.cmake:[0-9]+ \(target_link_libraries\):
+ Attempt to add link library "m" to target "subexe" which is not built in
+ this directory.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/target_link_libraries/SubDirTarget.cmake b/Tests/RunCMake/target_link_libraries/SubDirTarget.cmake
new file mode 100644
index 000000000..32431cecc
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/SubDirTarget.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+add_subdirectory(SubDirTarget)
+target_link_libraries(subexe m)
diff --git a/Tests/RunCMake/target_link_libraries/SubDirTarget/CMakeLists.txt b/Tests/RunCMake/target_link_libraries/SubDirTarget/CMakeLists.txt
new file mode 100644
index 000000000..b0b23809a
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/SubDirTarget/CMakeLists.txt
@@ -0,0 +1 @@
+add_executable(subexe ../empty.c)
diff --git a/Tests/RunCMake/target_link_libraries/empty.c b/Tests/RunCMake/target_link_libraries/empty.c
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/empty.c
diff --git a/Tests/RunCMake/try_compile/BadLinkLibraries-stderr.txt b/Tests/RunCMake/try_compile/BadLinkLibraries-stderr.txt
index eceffecc8..652bcfcd1 100644
--- a/Tests/RunCMake/try_compile/BadLinkLibraries-stderr.txt
+++ b/Tests/RunCMake/try_compile/BadLinkLibraries-stderr.txt
@@ -1,5 +1,5 @@
CMake Error at BadLinkLibraries.cmake:2 \(try_compile\):
- Only libraries may be used as try_compile IMPORTED LINK_LIBRARIES. Got
- not_a_library of type UTILITY.
+ Only libraries may be used as try_compile or try_run IMPORTED
+ LINK_LIBRARIES. Got not_a_library of type UTILITY.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/try_compile/CMP0056-stderr.txt b/Tests/RunCMake/try_compile/CMP0056-stderr.txt
new file mode 100644
index 000000000..5c1f0e4cf
--- /dev/null
+++ b/Tests/RunCMake/try_compile/CMP0056-stderr.txt
@@ -0,0 +1,13 @@
+before try_compile with CMP0056 WARN-default
+after try_compile with CMP0056 WARN-default
+*
+CMake Warning \(dev\) at CMP0056.cmake:[0-9]+ \(try_compile\):
+ Policy CMP0056 is not set: Honor link flags in try_compile\(\) source-file
+ signature. Run "cmake --help-policy CMP0056" for policy details. Use the
+ cmake_policy command to set the policy and suppress this warning.
+
+ For compatibility with older versions of CMake, try_compile is not honoring
+ caller link flags \(e.g. CMAKE_EXE_LINKER_FLAGS\) in the test project.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/try_compile/CMP0056-stdout.txt b/Tests/RunCMake/try_compile/CMP0056-stdout.txt
new file mode 100644
index 000000000..89e7c437b
--- /dev/null
+++ b/Tests/RunCMake/try_compile/CMP0056-stdout.txt
@@ -0,0 +1,4 @@
+-- try_compile with CMP0056 WARN-default worked as expected
+-- try_compile with CMP0056 WARN-enabled worked as expected
+-- try_compile with CMP0056 OLD worked as expected
+-- try_compile with CMP0056 NEW worked as expected
diff --git a/Tests/RunCMake/try_compile/CMP0056.cmake b/Tests/RunCMake/try_compile/CMP0056.cmake
new file mode 100644
index 000000000..e8d3d4a3b
--- /dev/null
+++ b/Tests/RunCMake/try_compile/CMP0056.cmake
@@ -0,0 +1,67 @@
+enable_language(C)
+set(obj "${CMAKE_C_OUTPUT_EXTENSION}")
+if(BORLAND)
+ set(pre -)
+endif()
+set(CMAKE_EXE_LINKER_FLAGS ${pre}BADFLAG${obj})
+
+#-----------------------------------------------------------------------------
+message("before try_compile with CMP0056 WARN-default")
+try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+ OUTPUT_VARIABLE out
+ )
+string(REPLACE "\n" "\n " out " ${out}")
+if(NOT RESULT)
+ message(FATAL_ERROR "try_compile failed but should have passed:\n${out}")
+elseif("x${out}" MATCHES "BADFLAG")
+ message(FATAL_ERROR "try_compile output mentions BADFLAG:\n${out}")
+else()
+ message(STATUS "try_compile with CMP0056 WARN-default worked as expected")
+endif()
+message("after try_compile with CMP0056 WARN-default")
+
+#-----------------------------------------------------------------------------
+set(CMAKE_POLICY_WARNING_CMP0056 ON)
+try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+ OUTPUT_VARIABLE out
+ )
+string(REPLACE "\n" "\n " out " ${out}")
+if(NOT RESULT)
+ message(FATAL_ERROR "try_compile failed but should have passed:\n${out}")
+elseif("x${out}" MATCHES "BADFLAG")
+ message(FATAL_ERROR "try_compile output mentions BADFLAG:\n${out}")
+else()
+ message(STATUS "try_compile with CMP0056 WARN-enabled worked as expected")
+endif()
+
+#-----------------------------------------------------------------------------
+cmake_policy(SET CMP0056 OLD)
+try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+ OUTPUT_VARIABLE out
+ )
+string(REPLACE "\n" "\n " out " ${out}")
+if(NOT RESULT)
+ message(FATAL_ERROR "try_compile failed but should have passed:\n${out}")
+elseif("x${out}" MATCHES "BADFLAG")
+ message(FATAL_ERROR "try_compile output mentions BADFLAG:\n${out}")
+else()
+ message(STATUS "try_compile with CMP0056 OLD worked as expected")
+endif()
+
+#-----------------------------------------------------------------------------
+cmake_policy(SET CMP0056 NEW)
+try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+ OUTPUT_VARIABLE out
+ )
+string(REPLACE "\n" "\n " out " ${out}")
+if(RESULT)
+ message(FATAL_ERROR "try_compile passed but should have failed:\n${out}")
+elseif(NOT "x${out}" MATCHES "BADFLAG")
+ message(FATAL_ERROR "try_compile did not fail with BADFLAG:\n${out}")
+else()
+ message(STATUS "try_compile with CMP0056 NEW worked as expected")
+endif()
diff --git a/Tests/RunCMake/try_compile/RerunCMake-nowork-ninja-no-console-stdout.txt b/Tests/RunCMake/try_compile/RerunCMake-nowork-ninja-no-console-stdout.txt
new file mode 100644
index 000000000..e600b9be6
--- /dev/null
+++ b/Tests/RunCMake/try_compile/RerunCMake-nowork-ninja-no-console-stdout.txt
@@ -0,0 +1 @@
+^ninja: no work to do\.$
diff --git a/Tests/RunCMake/try_compile/RerunCMake-rerun-ninja-no-console-stdout.txt b/Tests/RunCMake/try_compile/RerunCMake-rerun-ninja-no-console-stdout.txt
new file mode 100644
index 000000000..b0438f5b2
--- /dev/null
+++ b/Tests/RunCMake/try_compile/RerunCMake-rerun-ninja-no-console-stdout.txt
@@ -0,0 +1,5 @@
+Running CMake on RerunCMake
+FALSE
+-- Configuring done
+-- Generating done
+-- Build files have been written to: .*/Tests/RunCMake/try_compile/RerunCMake-build
diff --git a/Tests/RunCMake/try_compile/RerunCMake-rerun-stderr.txt b/Tests/RunCMake/try_compile/RerunCMake-rerun-stderr.txt
new file mode 100644
index 000000000..88e54b194
--- /dev/null
+++ b/Tests/RunCMake/try_compile/RerunCMake-rerun-stderr.txt
@@ -0,0 +1,2 @@
+^Running CMake on RerunCMake
+FALSE$
diff --git a/Tests/RunCMake/try_compile/RerunCMake-rerun-stdout.txt b/Tests/RunCMake/try_compile/RerunCMake-rerun-stdout.txt
new file mode 100644
index 000000000..9c78b2664
--- /dev/null
+++ b/Tests/RunCMake/try_compile/RerunCMake-rerun-stdout.txt
@@ -0,0 +1,3 @@
+-- Configuring done
+-- Generating done
+-- Build files have been written to: .*/Tests/RunCMake/try_compile/RerunCMake-build
diff --git a/Tests/RunCMake/try_compile/RerunCMake-stderr.txt b/Tests/RunCMake/try_compile/RerunCMake-stderr.txt
new file mode 100644
index 000000000..45d305af4
--- /dev/null
+++ b/Tests/RunCMake/try_compile/RerunCMake-stderr.txt
@@ -0,0 +1,2 @@
+^Running CMake on RerunCMake
+TRUE$
diff --git a/Tests/RunCMake/try_compile/RerunCMake-stdout.txt b/Tests/RunCMake/try_compile/RerunCMake-stdout.txt
new file mode 100644
index 000000000..9c78b2664
--- /dev/null
+++ b/Tests/RunCMake/try_compile/RerunCMake-stdout.txt
@@ -0,0 +1,3 @@
+-- Configuring done
+-- Generating done
+-- Build files have been written to: .*/Tests/RunCMake/try_compile/RerunCMake-build
diff --git a/Tests/RunCMake/try_compile/RerunCMake.cmake b/Tests/RunCMake/try_compile/RerunCMake.cmake
new file mode 100644
index 000000000..5a9f1d41d
--- /dev/null
+++ b/Tests/RunCMake/try_compile/RerunCMake.cmake
@@ -0,0 +1,7 @@
+message("Running CMake on RerunCMake") # write to stderr if cmake reruns
+enable_language(C)
+try_compile(res
+ "${CMAKE_CURRENT_BINARY_DIR}"
+ SOURCES "${CMAKE_CURRENT_BINARY_DIR}/TryCompileInput.c"
+ )
+message("${res}")
diff --git a/Tests/RunCMake/try_compile/RunCMakeTest.cmake b/Tests/RunCMake/try_compile/RunCMakeTest.cmake
index c93445876..6cdbafa87 100644
--- a/Tests/RunCMake/try_compile/RunCMakeTest.cmake
+++ b/Tests/RunCMake/try_compile/RunCMakeTest.cmake
@@ -15,3 +15,38 @@ run_cmake(BadSources1)
run_cmake(BadSources2)
run_cmake(NonSourceCopyFile)
run_cmake(NonSourceCompileDefinitions)
+
+run_cmake(CMP0056)
+
+if(RunCMake_GENERATOR MATCHES "Make|Ninja")
+ # Use a single build tree for a few tests without cleaning.
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/RerunCMake-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ set(in_tc "${RunCMake_TEST_BINARY_DIR}/TryCompileInput.c")
+ file(WRITE "${in_tc}" "int main(void) { return 0; }\n")
+
+ # Older Ninja keeps all rerun output on stdout
+ set(ninja "")
+ if(RunCMake_GENERATOR STREQUAL "Ninja")
+ execute_process(COMMAND ${RunCMake_MAKE_PROGRAM} --version
+ OUTPUT_VARIABLE ninja_version OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if(ninja_version VERSION_LESS 1.5)
+ set(ninja -ninja-no-console)
+ endif()
+ endif()
+
+ message(STATUS "RerunCMake: first configuration...")
+ run_cmake(RerunCMake)
+ run_cmake_command(RerunCMake-nowork${ninja} ${CMAKE_COMMAND} --build .)
+
+ execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1) # handle 1s resolution
+ message(STATUS "RerunCMake: modify try_compile input...")
+ file(WRITE "${in_tc}" "does-not-compile\n")
+ run_cmake_command(RerunCMake-rerun${ninja} ${CMAKE_COMMAND} --build .)
+ run_cmake_command(RerunCMake-nowork${ninja} ${CMAKE_COMMAND} --build .)
+
+ unset(RunCMake_TEST_BINARY_DIR)
+ unset(RunCMake_TEST_NO_CLEAN)
+endif()
diff --git a/Tests/RunCMake/try_run/BadLinkLibraries-result.txt b/Tests/RunCMake/try_run/BadLinkLibraries-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/try_run/BadLinkLibraries-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/try_run/BadLinkLibraries-stderr.txt b/Tests/RunCMake/try_run/BadLinkLibraries-stderr.txt
new file mode 100644
index 000000000..dcd1bfcbc
--- /dev/null
+++ b/Tests/RunCMake/try_run/BadLinkLibraries-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at BadLinkLibraries.cmake:2 \(try_run\):
+ Only libraries may be used as try_compile or try_run IMPORTED
+ LINK_LIBRARIES. Got not_a_library of type UTILITY.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/try_run/BadLinkLibraries.cmake b/Tests/RunCMake/try_run/BadLinkLibraries.cmake
new file mode 100644
index 000000000..a124bf6e1
--- /dev/null
+++ b/Tests/RunCMake/try_run/BadLinkLibraries.cmake
@@ -0,0 +1,4 @@
+add_custom_target(not_a_library)
+try_run(RUN_RESULT COMPILE_RESULT
+ ${CMAKE_CURRENT_BINARY_DIR}/CMakeTmp ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+ LINK_LIBRARIES not_a_library)
diff --git a/Tests/RunCMake/try_run/CMakeLists.txt b/Tests/RunCMake/try_run/CMakeLists.txt
new file mode 100644
index 000000000..e03478039
--- /dev/null
+++ b/Tests/RunCMake/try_run/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.0)
+project(${RunCMake_TEST} C)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/try_run/RunCMakeTest.cmake b/Tests/RunCMake/try_run/RunCMakeTest.cmake
new file mode 100644
index 000000000..1ec9a55aa
--- /dev/null
+++ b/Tests/RunCMake/try_run/RunCMakeTest.cmake
@@ -0,0 +1,3 @@
+include(RunCMake)
+
+run_cmake(BadLinkLibraries)
diff --git a/Tests/RunCMake/try_run/src.c b/Tests/RunCMake/try_run/src.c
new file mode 100644
index 000000000..78f2de106
--- /dev/null
+++ b/Tests/RunCMake/try_run/src.c
@@ -0,0 +1 @@
+int main(void) { return 0; }
diff --git a/Tests/RunCMake/while/CMakeLists.txt b/Tests/RunCMake/while/CMakeLists.txt
new file mode 100644
index 000000000..12cd3c775
--- /dev/null
+++ b/Tests/RunCMake/while/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/while/EndAlone-result.txt b/Tests/RunCMake/while/EndAlone-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/while/EndAlone-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/while/EndAlone-stderr.txt b/Tests/RunCMake/while/EndAlone-stderr.txt
new file mode 100644
index 000000000..cd9868722
--- /dev/null
+++ b/Tests/RunCMake/while/EndAlone-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at EndAlone.cmake:1 \(endwhile\):
+ endwhile An ENDWHILE command was found outside of a proper WHILE ENDWHILE
+ structure.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/While-Endwhile-Alone.cmake b/Tests/RunCMake/while/EndAlone.cmake
index 82c09a07b..82c09a07b 100644
--- a/Tests/CMakeTests/While-Endwhile-Alone.cmake
+++ b/Tests/RunCMake/while/EndAlone.cmake
diff --git a/Tests/RunCMake/while/EndAloneArgs-result.txt b/Tests/RunCMake/while/EndAloneArgs-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/while/EndAloneArgs-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/while/EndAloneArgs-stderr.txt b/Tests/RunCMake/while/EndAloneArgs-stderr.txt
new file mode 100644
index 000000000..a8c043d0f
--- /dev/null
+++ b/Tests/RunCMake/while/EndAloneArgs-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at EndAloneArgs.cmake:1 \(endwhile\):
+ endwhile An ENDWHILE command was found outside of a proper WHILE ENDWHILE
+ structure. Or its arguments did not match the opening WHILE command.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/While-Endwhile-Alone-Args.cmake b/Tests/RunCMake/while/EndAloneArgs.cmake
index 886d98c7c..886d98c7c 100644
--- a/Tests/CMakeTests/While-Endwhile-Alone-Args.cmake
+++ b/Tests/RunCMake/while/EndAloneArgs.cmake
diff --git a/Tests/RunCMake/while/EndMismatch-stderr.txt b/Tests/RunCMake/while/EndMismatch-stderr.txt
new file mode 100644
index 000000000..d7439e8fc
--- /dev/null
+++ b/Tests/RunCMake/while/EndMismatch-stderr.txt
@@ -0,0 +1,13 @@
+^CMake Warning \(dev\) at EndMismatch.cmake:3 \(include\):
+ A logical block opening on the line
+
+ .*/Tests/RunCMake/while/EndMismatch.cmake:1 \(while\)
+
+ closes on the line
+
+ .*/Tests/RunCMake/while/EndMismatch.cmake:2 \(endwhile\)
+
+ with mis-matching arguments.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.$
diff --git a/Tests/CMakeTests/While-Endwhile-Mismatch.cmake b/Tests/RunCMake/while/EndMismatch.cmake
index 5c338d697..5c338d697 100644
--- a/Tests/CMakeTests/While-Endwhile-Mismatch.cmake
+++ b/Tests/RunCMake/while/EndMismatch.cmake
diff --git a/Tests/RunCMake/while/EndMissing-result.txt b/Tests/RunCMake/while/EndMissing-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/while/EndMissing-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/while/EndMissing-stderr.txt b/Tests/RunCMake/while/EndMissing-stderr.txt
new file mode 100644
index 000000000..099a8b273
--- /dev/null
+++ b/Tests/RunCMake/while/EndMissing-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Error at CMakeLists.txt:3 \(include\):
+ A logical block opening on the line
+
+ .*/Tests/RunCMake/while/EndMissing.cmake:1 \(while\)
+
+ is not closed.$
diff --git a/Tests/CMakeTests/While-Missing-Endwhile.cmake b/Tests/RunCMake/while/EndMissing.cmake
index 1abaaaf2b..1abaaaf2b 100644
--- a/Tests/CMakeTests/While-Missing-Endwhile.cmake
+++ b/Tests/RunCMake/while/EndMissing.cmake
diff --git a/Tests/RunCMake/while/MissingArgument-result.txt b/Tests/RunCMake/while/MissingArgument-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/while/MissingArgument-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/while/MissingArgument-stderr.txt b/Tests/RunCMake/while/MissingArgument-stderr.txt
new file mode 100644
index 000000000..7ff0971f4
--- /dev/null
+++ b/Tests/RunCMake/while/MissingArgument-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at MissingArgument.cmake:1 \(while\):
+ while called with incorrect number of arguments
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/CMakeTests/While-Missing-Argument.cmake b/Tests/RunCMake/while/MissingArgument.cmake
index 32eaa2698..32eaa2698 100644
--- a/Tests/CMakeTests/While-Missing-Argument.cmake
+++ b/Tests/RunCMake/while/MissingArgument.cmake
diff --git a/Tests/RunCMake/while/RunCMakeTest.cmake b/Tests/RunCMake/while/RunCMakeTest.cmake
new file mode 100644
index 000000000..7da80ace3
--- /dev/null
+++ b/Tests/RunCMake/while/RunCMakeTest.cmake
@@ -0,0 +1,7 @@
+include(RunCMake)
+
+run_cmake(MissingArgument)
+run_cmake(EndMissing)
+run_cmake(EndMismatch)
+run_cmake(EndAlone)
+run_cmake(EndAloneArgs)
diff --git a/Tests/SimpleInstall/CMakeLists.txt b/Tests/SimpleInstall/CMakeLists.txt
index b969bfdf0..2737f182f 100644
--- a/Tests/SimpleInstall/CMakeLists.txt
+++ b/Tests/SimpleInstall/CMakeLists.txt
@@ -209,9 +209,9 @@ else()
ARCHIVE DESTINATION MyTest/lib/static
OPTIONAL # for coverage...target should always exist
)
- install(FILES lib1.h DESTINATION MyTest/include/foo)
+ install(FILES lib1.h DESTINATION MyTest/include/$<1:foo>$<0:/wrong>)
install(FILES lib2.h
- DESTINATION MyTest/include/foo
+ DESTINATION $<1:MyTest/include/foo>$<0:/wrong>
COMPONENT Development
PERMISSIONS OWNER_READ OWNER_WRITE
RENAME lib2renamed.h
@@ -252,7 +252,7 @@ else()
file(REMOVE_RECURSE "${CMAKE_INSTALL_PREFIX}/MyTest/share/CVS")
file(REMOVE_RECURSE "${CMAKE_INSTALL_PREFIX}/MyTest/share/TestSubDir/CVS")
install(
- DIRECTORY TestSubDir scripts/ DESTINATION MyTest/share
+ DIRECTORY TestSubDir $<1:scripts/>$<0:/wrong> DESTINATION $<1:MyTest/share>$<0:/wrong>
FILE_PERMISSIONS OWNER_READ OWNER_WRITE
DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
GROUP_READ GROUP_EXECUTE
@@ -263,14 +263,14 @@ else()
# Alternate directory installation for coverage.
install(
- DIRECTORY scripts/ DESTINATION MyTest/share/alt
+ DIRECTORY $<1:scripts/>$<0:/wrong> DESTINATION $<1:MyTest/share/alt>$<0:/wrong>
COMPONENT Development
USE_SOURCE_PERMISSIONS
PATTERN "CVS" EXCLUDE
REGEX "\\.txt$" EXCLUDE
)
install(
- DIRECTORY TestSubDir DESTINATION MyTest/share/alt
+ DIRECTORY TestSubDir DESTINATION $<1:MyTest/share/alt>$<0:/wrong>
FILE_PERMISSIONS OWNER_READ OWNER_WRITE
DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
GROUP_READ GROUP_EXECUTE
@@ -308,7 +308,7 @@ else()
endif()
if(CMAKE_CONFIGURATION_TYPES)
- set(SI_CONFIG -C ${CMAKE_CFG_INTDIR})
+ set(SI_CONFIG --config $<CONFIGURATION>)
else()
set(SI_CONFIG)
endif()
@@ -367,7 +367,9 @@ set(CMAKE_INSTALL_DEBUG_LIBRARIES 1)
include(InstallRequiredSystemLibraries)
if(CTEST_TEST_CPACK)
- set(PACKAGE_TARGET --build-target package)
+ set(package_command COMMAND
+ ${CMAKE_COMMAND} --build . --target package ${SI_CONFIG}
+ )
# Avoid settings that require the .zip file command line tools...
# (just build an NSIS installer without component support)
@@ -375,24 +377,19 @@ if(CTEST_TEST_CPACK)
set(CPACK_BINARY_ZIP OFF)
set(CPACK_MONOLITHIC_INSTALL ON)
else()
- set(PACKAGE_TARGET)
+ set(package_command)
endif()
include(CPack)
+set(install_command COMMAND
+ ${CMAKE_COMMAND} --build . --target install ${SI_CONFIG}
+ )
+
add_custom_command(
TARGET ${install_target}
POST_BUILD
- COMMAND ${CMAKE_CTEST_COMMAND}
- ARGS ${SI_CONFIG}
- --build-and-test
- ${CMAKE_SOURCE_DIR}
- ${CMAKE_BINARY_DIR}
- --build-generator ${CMAKE_GENERATOR}
- --build-project ${PROJECT_NAME}
- --build-makeprogram ${CMAKE_MAKE_PROGRAM}
- --build-noclean
- --build-target install
- ${PACKAGE_TARGET}
+ ${install_command}
+ ${package_command}
COMMENT "Install Project"
)
diff --git a/Tests/SimpleInstallS2/CMakeLists.txt b/Tests/SimpleInstallS2/CMakeLists.txt
index b969bfdf0..2737f182f 100644
--- a/Tests/SimpleInstallS2/CMakeLists.txt
+++ b/Tests/SimpleInstallS2/CMakeLists.txt
@@ -209,9 +209,9 @@ else()
ARCHIVE DESTINATION MyTest/lib/static
OPTIONAL # for coverage...target should always exist
)
- install(FILES lib1.h DESTINATION MyTest/include/foo)
+ install(FILES lib1.h DESTINATION MyTest/include/$<1:foo>$<0:/wrong>)
install(FILES lib2.h
- DESTINATION MyTest/include/foo
+ DESTINATION $<1:MyTest/include/foo>$<0:/wrong>
COMPONENT Development
PERMISSIONS OWNER_READ OWNER_WRITE
RENAME lib2renamed.h
@@ -252,7 +252,7 @@ else()
file(REMOVE_RECURSE "${CMAKE_INSTALL_PREFIX}/MyTest/share/CVS")
file(REMOVE_RECURSE "${CMAKE_INSTALL_PREFIX}/MyTest/share/TestSubDir/CVS")
install(
- DIRECTORY TestSubDir scripts/ DESTINATION MyTest/share
+ DIRECTORY TestSubDir $<1:scripts/>$<0:/wrong> DESTINATION $<1:MyTest/share>$<0:/wrong>
FILE_PERMISSIONS OWNER_READ OWNER_WRITE
DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
GROUP_READ GROUP_EXECUTE
@@ -263,14 +263,14 @@ else()
# Alternate directory installation for coverage.
install(
- DIRECTORY scripts/ DESTINATION MyTest/share/alt
+ DIRECTORY $<1:scripts/>$<0:/wrong> DESTINATION $<1:MyTest/share/alt>$<0:/wrong>
COMPONENT Development
USE_SOURCE_PERMISSIONS
PATTERN "CVS" EXCLUDE
REGEX "\\.txt$" EXCLUDE
)
install(
- DIRECTORY TestSubDir DESTINATION MyTest/share/alt
+ DIRECTORY TestSubDir DESTINATION $<1:MyTest/share/alt>$<0:/wrong>
FILE_PERMISSIONS OWNER_READ OWNER_WRITE
DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
GROUP_READ GROUP_EXECUTE
@@ -308,7 +308,7 @@ else()
endif()
if(CMAKE_CONFIGURATION_TYPES)
- set(SI_CONFIG -C ${CMAKE_CFG_INTDIR})
+ set(SI_CONFIG --config $<CONFIGURATION>)
else()
set(SI_CONFIG)
endif()
@@ -367,7 +367,9 @@ set(CMAKE_INSTALL_DEBUG_LIBRARIES 1)
include(InstallRequiredSystemLibraries)
if(CTEST_TEST_CPACK)
- set(PACKAGE_TARGET --build-target package)
+ set(package_command COMMAND
+ ${CMAKE_COMMAND} --build . --target package ${SI_CONFIG}
+ )
# Avoid settings that require the .zip file command line tools...
# (just build an NSIS installer without component support)
@@ -375,24 +377,19 @@ if(CTEST_TEST_CPACK)
set(CPACK_BINARY_ZIP OFF)
set(CPACK_MONOLITHIC_INSTALL ON)
else()
- set(PACKAGE_TARGET)
+ set(package_command)
endif()
include(CPack)
+set(install_command COMMAND
+ ${CMAKE_COMMAND} --build . --target install ${SI_CONFIG}
+ )
+
add_custom_command(
TARGET ${install_target}
POST_BUILD
- COMMAND ${CMAKE_CTEST_COMMAND}
- ARGS ${SI_CONFIG}
- --build-and-test
- ${CMAKE_SOURCE_DIR}
- ${CMAKE_BINARY_DIR}
- --build-generator ${CMAKE_GENERATOR}
- --build-project ${PROJECT_NAME}
- --build-makeprogram ${CMAKE_MAKE_PROGRAM}
- --build-noclean
- --build-target install
- ${PACKAGE_TARGET}
+ ${install_command}
+ ${package_command}
COMMENT "Install Project"
)
diff --git a/Tests/SourceFileProperty/CMakeLists.txt b/Tests/SourceFileProperty/CMakeLists.txt
new file mode 100644
index 000000000..1b6506da5
--- /dev/null
+++ b/Tests/SourceFileProperty/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 3.0)
+project(SourceFileProperty C)
+
+set(sources)
+
+if (EXISTS icasetest.c)
+ # If a file exists by this name, use it.
+ set_source_files_properties(icasetest.c
+ PROPERTIES
+ COMPILE_FLAGS -DNEEDED_TO_WORK)
+else ()
+ # Work on case-sensitive file systems as well.
+ set_source_files_properties(main.c
+ PROPERTIES
+ COMPILE_FLAGS -DNO_NEED_TO_CALL)
+endif ()
+list(APPEND sources ICaseTest.c)
+
+add_executable(SourceFileProperty main.c ${sources})
diff --git a/Tests/SourceFileProperty/ICaseTest.c b/Tests/SourceFileProperty/ICaseTest.c
new file mode 100644
index 000000000..454c721fe
--- /dev/null
+++ b/Tests/SourceFileProperty/ICaseTest.c
@@ -0,0 +1,7 @@
+
+#ifdef NEEDED_TO_WORK
+int icasetest()
+{
+ return 0;
+}
+#endif
diff --git a/Tests/SourceFileProperty/main.c b/Tests/SourceFileProperty/main.c
new file mode 100644
index 000000000..b853408a2
--- /dev/null
+++ b/Tests/SourceFileProperty/main.c
@@ -0,0 +1,13 @@
+
+#ifndef NO_NEED_TO_CALL
+extern int icasetest();
+#endif
+
+int main(int argc, char** argv)
+{
+#ifdef NO_NEED_TO_CALL
+ return 0;
+#else
+ return icasetest();
+#endif
+}
diff --git a/Tests/SourcesProperty/CMakeLists.txt b/Tests/SourcesProperty/CMakeLists.txt
new file mode 100644
index 000000000..d1c35d801
--- /dev/null
+++ b/Tests/SourcesProperty/CMakeLists.txt
@@ -0,0 +1,14 @@
+
+cmake_minimum_required(VERSION 3.0)
+
+project(SourcesProperty)
+
+add_library(iface INTERFACE)
+set_property(TARGET iface PROPERTY INTERFACE_SOURCES
+ "${CMAKE_CURRENT_SOURCE_DIR}/iface.cpp"
+)
+
+add_executable(SourcesProperty main.cpp)
+target_link_libraries(SourcesProperty iface)
+
+set_property(TARGET SourcesProperty APPEND PROPERTY SOURCES prop.cpp)
diff --git a/Tests/SourcesProperty/iface.cpp b/Tests/SourcesProperty/iface.cpp
new file mode 100644
index 000000000..e38ac3778
--- /dev/null
+++ b/Tests/SourcesProperty/iface.cpp
@@ -0,0 +1,5 @@
+
+int iface()
+{
+ return 0;
+}
diff --git a/Tests/SourcesProperty/iface.h b/Tests/SourcesProperty/iface.h
new file mode 100644
index 000000000..6da80a4ed
--- /dev/null
+++ b/Tests/SourcesProperty/iface.h
@@ -0,0 +1,4 @@
+
+int iface();
+
+int prop();
diff --git a/Tests/SourcesProperty/main.cpp b/Tests/SourcesProperty/main.cpp
new file mode 100644
index 000000000..33a97f4be
--- /dev/null
+++ b/Tests/SourcesProperty/main.cpp
@@ -0,0 +1,7 @@
+
+#include "iface.h"
+
+int main(int argc, char** argv)
+{
+ return iface() + prop();
+}
diff --git a/Tests/SourcesProperty/prop.cpp b/Tests/SourcesProperty/prop.cpp
new file mode 100644
index 000000000..e34343175
--- /dev/null
+++ b/Tests/SourcesProperty/prop.cpp
@@ -0,0 +1,5 @@
+
+int prop()
+{
+ return 0;
+}
diff --git a/Tests/StagingPrefix/CMakeLists.txt b/Tests/StagingPrefix/CMakeLists.txt
new file mode 100644
index 000000000..49ff7fee7
--- /dev/null
+++ b/Tests/StagingPrefix/CMakeLists.txt
@@ -0,0 +1,91 @@
+
+cmake_minimum_required(VERSION 2.8.12)
+project(StagingPrefix)
+
+# Wipe out the install tree
+add_custom_command(
+ OUTPUT ${CMAKE_BINARY_DIR}/CleanupProject
+ COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/ConsumerBuild
+ COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/ProducerBuild
+ COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/stage
+ COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/prefix
+ COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/ignored
+ )
+add_custom_target(CleanupTarget ALL DEPENDS ${CMAKE_BINARY_DIR}/CleanupProject)
+set_property(
+ SOURCE ${CMAKE_BINARY_DIR}/CleanupProject
+ PROPERTY SYMBOLIC 1
+ )
+
+if(CMAKE_CONFIGURATION_TYPES)
+ set(NESTED_CONFIG_TYPE -C "${CMAKE_CFG_INTDIR}")
+else()
+ if(CMAKE_BUILD_TYPE)
+ set(NESTED_CONFIG_TYPE -C "${CMAKE_BUILD_TYPE}")
+ else()
+ set(NESTED_CONFIG_TYPE)
+ endif()
+endif()
+
+# Build and install the producer.
+add_custom_command(
+ OUTPUT ${CMAKE_BINARY_DIR}/ProducerProject
+ COMMAND ${CMAKE_CTEST_COMMAND} ${NESTED_CONFIG_TYPE}
+ --build-and-test
+ ${CMAKE_SOURCE_DIR}/Producer
+ ${CMAKE_BINARY_DIR}/ProducerBuild
+ --build-noclean
+ --build-project Producer
+ --build-target install
+ --build-generator ${CMAKE_GENERATOR}
+ --build-generator-platform "${CMAKE_GENERATOR_PLATFORM}"
+ --build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
+ --build-options
+ -DCMAKE_VERBOSE_MAKEFILE=1
+ "-DCMAKE_STAGING_PREFIX=${CMAKE_BINARY_DIR}/stage"
+ "-DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/prefix"
+ VERBATIM
+ )
+
+add_custom_target(ProducerTarget ALL DEPENDS ${CMAKE_BINARY_DIR}/ProducerProject)
+add_dependencies(ProducerTarget CleanupTarget)
+set_property(
+ SOURCE ${CMAKE_BINARY_DIR}/ProducerProject
+ PROPERTY SYMBOLIC 1
+ )
+
+if(NOT WIN32)
+ file(WRITE
+ "${CMAKE_BINARY_DIR}/ignored/${CMAKE_BINARY_DIR}/stage/include/ignored.h"
+ "#define IGNORED\n"
+ )
+endif()
+
+# Build and install the consumer.
+add_custom_command(
+ OUTPUT ${CMAKE_BINARY_DIR}/ConsumerProject
+ COMMAND ${CMAKE_CTEST_COMMAND} ${NESTED_CONFIG_TYPE}
+ --build-and-test
+ ${CMAKE_SOURCE_DIR}/Consumer
+ ${CMAKE_BINARY_DIR}/ConsumerBuild
+ --build-noclean
+ --build-project Consumer
+ --build-target install
+ --build-generator ${CMAKE_GENERATOR}
+ --build-generator-platform "${CMAKE_GENERATOR_PLATFORM}"
+ --build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
+ --build-options
+ "-DCMAKE_FIND_ROOT_PATH=${CMAKE_BINARY_DIR}/ignored"
+ "-DCMAKE_STAGING_PREFIX=${CMAKE_BINARY_DIR}/stage"
+ -DCMAKE_VERBOSE_MAKEFILE=1
+ VERBATIM
+ )
+add_custom_target(ConsumerTarget ALL DEPENDS ${CMAKE_BINARY_DIR}/ConsumerProject)
+add_dependencies(ConsumerTarget ProducerTarget)
+set_property(
+ SOURCE ${CMAKE_BINARY_DIR}/ConsumerProject
+ PROPERTY SYMBOLIC 1
+ )
+
+add_executable(StagingPrefix main.cpp)
+add_dependencies(StagingPrefix ConsumerTarget)
diff --git a/Tests/StagingPrefix/Consumer/CMakeLists.txt b/Tests/StagingPrefix/Consumer/CMakeLists.txt
new file mode 100644
index 000000000..a230441e6
--- /dev/null
+++ b/Tests/StagingPrefix/Consumer/CMakeLists.txt
@@ -0,0 +1,22 @@
+
+cmake_minimum_required (VERSION 2.8.12)
+project(Consumer)
+
+
+add_executable(executable main.cpp)
+find_package(Foo CONFIG REQUIRED)
+target_link_libraries(executable Foo::foo)
+
+set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
+find_package(Bar MODULE REQUIRED)
+include_directories(${Bar_INCLUDE_DIRS})
+target_link_libraries(executable ${Bar_LIBRARIES})
+
+install(TARGETS executable DESTINATION bin)
+
+if(NOT WIN32)
+ find_path(IGNORED_INCLUDE_DIR ignored.h)
+ if (IGNORED_INCLUDE_DIR)
+ message(SEND_ERROR "Should not find this file. The search path should be excluded.")
+ endif()
+endif()
diff --git a/Tests/StagingPrefix/Consumer/cmake/FindBar.cmake b/Tests/StagingPrefix/Consumer/cmake/FindBar.cmake
new file mode 100644
index 000000000..29e4478ae
--- /dev/null
+++ b/Tests/StagingPrefix/Consumer/cmake/FindBar.cmake
@@ -0,0 +1,6 @@
+
+find_path(_inc_prefix bar.h PATH_SUFFIXES bar)
+set(Bar_INCLUDE_DIRS ${_inc_prefix})
+
+find_library(Bar_LIBRARY bar)
+set(Bar_LIBRARIES ${Bar_LIBRARY})
diff --git a/Tests/StagingPrefix/Consumer/main.cpp b/Tests/StagingPrefix/Consumer/main.cpp
new file mode 100644
index 000000000..612ee05a9
--- /dev/null
+++ b/Tests/StagingPrefix/Consumer/main.cpp
@@ -0,0 +1,10 @@
+
+#include "foo.h"
+#include "bar.h"
+
+int main(int, char **)
+{
+ Foo f;
+ Bar b;
+ return f.foo() + b.bar();
+}
diff --git a/Tests/StagingPrefix/Producer/CMakeLists.txt b/Tests/StagingPrefix/Producer/CMakeLists.txt
new file mode 100644
index 000000000..eb3d98f2e
--- /dev/null
+++ b/Tests/StagingPrefix/Producer/CMakeLists.txt
@@ -0,0 +1,26 @@
+
+cmake_minimum_required (VERSION 2.8.12)
+project(Producer)
+
+add_library(foo SHARED foo.cpp)
+
+install(TARGETS foo EXPORT fooTargets
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION lib
+ ARCHIVE DESTINATION lib
+ INCLUDES DESTINATION include/foo
+)
+install(FILES foo.h DESTINATION include/foo)
+install(EXPORT fooTargets
+ FILE FooConfig.cmake
+ NAMESPACE Foo::
+ DESTINATION lib/cmake/Foo
+)
+
+add_library(bar SHARED bar.cpp)
+install(TARGETS bar
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION lib
+ ARCHIVE DESTINATION lib
+)
+install(FILES bar.h DESTINATION include/bar)
diff --git a/Tests/StagingPrefix/Producer/bar.cpp b/Tests/StagingPrefix/Producer/bar.cpp
new file mode 100644
index 000000000..6bb8abecd
--- /dev/null
+++ b/Tests/StagingPrefix/Producer/bar.cpp
@@ -0,0 +1,7 @@
+
+#include "bar.h"
+
+int Bar::bar()
+{
+ return 0;
+}
diff --git a/Tests/StagingPrefix/Producer/bar.h b/Tests/StagingPrefix/Producer/bar.h
new file mode 100644
index 000000000..acd1fae02
--- /dev/null
+++ b/Tests/StagingPrefix/Producer/bar.h
@@ -0,0 +1,10 @@
+
+class
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+Bar
+{
+public:
+ int bar();
+};
diff --git a/Tests/StagingPrefix/Producer/foo.cpp b/Tests/StagingPrefix/Producer/foo.cpp
new file mode 100644
index 000000000..64ad7cd0e
--- /dev/null
+++ b/Tests/StagingPrefix/Producer/foo.cpp
@@ -0,0 +1,7 @@
+
+#include "foo.h"
+
+int Foo::foo()
+{
+ return 0;
+}
diff --git a/Tests/StagingPrefix/Producer/foo.h b/Tests/StagingPrefix/Producer/foo.h
new file mode 100644
index 000000000..614093db8
--- /dev/null
+++ b/Tests/StagingPrefix/Producer/foo.h
@@ -0,0 +1,10 @@
+
+class
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+Foo
+{
+public:
+ int foo();
+};
diff --git a/Tests/StagingPrefix/main.cpp b/Tests/StagingPrefix/main.cpp
new file mode 100644
index 000000000..341aaafa0
--- /dev/null
+++ b/Tests/StagingPrefix/main.cpp
@@ -0,0 +1,5 @@
+
+int main(int, char **)
+{
+ return 0;
+}
diff --git a/Tests/StringFileTest/CMakeLists.txt b/Tests/StringFileTest/CMakeLists.txt
index 00383ab37..faf3bc90b 100644
--- a/Tests/StringFileTest/CMakeLists.txt
+++ b/Tests/StringFileTest/CMakeLists.txt
@@ -55,6 +55,16 @@ else()
"file(STRINGS) incorrectly read from srec file [${infile_strings}]")
endif()
+#this file has utf-8 content
+file(STRINGS test.utf8 infile_strings ENCODING UTF-8)
+list(LENGTH infile_strings content_len)
+if(content_len MATCHES "3")
+ message("file(STRINGS) correctly read from utf8 file [${infile_strings}]")
+else()
+ message(SEND_ERROR
+ "file(STRINGS) incorrectly read from utf8 file [${infile_strings}]")
+endif()
+
# String test
string(REGEX MATCH "[cC][mM][aA][kK][eE]" rmvar "CMake is great")
string(REGEX MATCHALL "[cC][mM][aA][kK][eE]" rmallvar "CMake is better than cmake or CMake")
@@ -113,7 +123,7 @@ string(STRIP "ST2 " ST2)
string(STRIP " ST3" ST3)
foreach(var ST1 ST2 ST3)
- if("${var}" STREQUAL "${${var}}")
+ if("x${var}" STREQUAL "x${${var}}")
message("[${var}] == [${${var}}]")
else()
message(SEND_ERROR "Problem with the STRIP command for ${var}: [${${var}}]")
@@ -127,12 +137,6 @@ string(LENGTH ${substringres} lengthres)
file(RELATIVE_PATH relpath "/usr/local/bin" "/usr/X11R6/bin/xnest")
-# Escaping test
-set(var "\\ \" \ \t \n \r \# \( \) \0")
-message("Output: [${var}]")
-set(var \\ \" \ \t \n \r \# \( \) \0)
-message("Output: [${var}]")
-
# Make-style unquoted argument test
set(var $(VAR1)$(VAR2)/$(VAR3))
message("Output: [${var}]")
@@ -141,13 +145,6 @@ if(NOT result)
message(SEND_ERROR "Unquoted $(VAR) syntax is broken.")
endif()
-# Obscure environment variable name
-set("ENV{x+(y)}" "Obscure environment variable value")
-message("Output: [$ENV{x+(y)}]")
-if(NOT "$ENV{x+(y)}" STREQUAL "Obscure environment variable value")
- message(SEND_ERROR "Environment variable \"ENV{x+(y)}\" does not work.")
-endif()
-
# Make directories test
file(MAKE_DIRECTORY
"${CMAKE_CURRENT_BINARY_DIR}/Includes"
@@ -192,7 +189,7 @@ string(CONFIGURE "${infile}" infile+-/out @ONLY)
set(infile "${infile+-/out}")
# Write include file to a file
-string(REGEX REPLACE "includefile" "${file}" outfile "${infile}")
+string(REGEX REPLACE "includefile" "Includes/Values.h" outfile "${infile}")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/OutputFile.h-tmp" "${outfile}")
file(RENAME "${CMAKE_CURRENT_BINARY_DIR}/OutputFile.h-tmp"
"${CMAKE_CURRENT_BINARY_DIR}/OutputFile.h")
@@ -286,3 +283,9 @@ string(MAKE_C_IDENTIFIER "1one-two$" MCI_1)
if(NOT MCI_1 STREQUAL _1one_two_)
message(SEND_ERROR "MAKE_C_IDENTIFIER did not create expected result.")
endif()
+
+string(GENEX_STRIP "one;$<1:two;three>;four;$<TARGET_OBJECTS:some_target>" strip_result)
+
+if (NOT strip_result STREQUAL "one;four")
+ message(SEND_ERROR "GENEX_STRIP did not create expected result: ${strip_result}")
+endif()
diff --git a/Tests/StringFileTest/test.utf8 b/Tests/StringFileTest/test.utf8
new file mode 100644
index 000000000..6c2917074
--- /dev/null
+++ b/Tests/StringFileTest/test.utf8
@@ -0,0 +1,3 @@
+The value of π (pi) is 3.141593
+Line mixed with binary partially matches valid utf8: Ï€ is à93.1593
+à \ No newline at end of file
diff --git a/Tests/SubDir/CMakeLists.txt b/Tests/SubDir/CMakeLists.txt
index 6822e6bd9..32aa93ffc 100644
--- a/Tests/SubDir/CMakeLists.txt
+++ b/Tests/SubDir/CMakeLists.txt
@@ -1,6 +1,10 @@
cmake_minimum_required (VERSION 2.6)
project(SUBDIR)
+
subdirs(Executable EXCLUDE_FROM_ALL Examples)
+
+set(DEFINED_AFTER_SUBDIRS_COMMAND 42)
+
write_file(${SUBDIR_BINARY_DIR}/ShouldBeHere "This file should exist.")
#WATCOM WMAKE does not support + in the name of a file!
if(WATCOM)
diff --git a/Tests/SubDir/Executable/CMakeLists.txt b/Tests/SubDir/Executable/CMakeLists.txt
index 77e6751cd..fbe338ef4 100644
--- a/Tests/SubDir/Executable/CMakeLists.txt
+++ b/Tests/SubDir/Executable/CMakeLists.txt
@@ -1 +1,13 @@
add_executable(test test.cxx)
+
+if (NOT DEFINED_AFTER_SUBDIRS_COMMAND)
+ message(FATAL_ERROR "DEFINED_AFTER_SUBDIRS_COMMAND should be defined.")
+endif()
+
+string(FIND "${CMAKE_CURRENT_BINARY_DIR}" "SubDir/Executable" location)
+string(LENGTH "${CMAKE_CURRENT_BINARY_DIR}" dirLength)
+math(EXPR suffixLength "${dirLength} - ${location}")
+
+if (NOT suffixLength EQUAL 17)
+ message(FATAL_ERROR "CMAKE_CURRENT_BINARY_DIR does not end with \"SubDir/Executable\"")
+endif()
diff --git a/Tests/SubDirSpaces/CMakeLists.txt b/Tests/SubDirSpaces/CMakeLists.txt
index 69f1d6833..40c265e5f 100644
--- a/Tests/SubDirSpaces/CMakeLists.txt
+++ b/Tests/SubDirSpaces/CMakeLists.txt
@@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 2.6)
project(SUBDIR)
# Some systems do not seem to support rpath with spaces.
-if("${CMAKE_SYSTEM}" MATCHES "IRIX|QNX")
+if(CMAKE_SYSTEM_NAME MATCHES "IRIX|QNX")
set(CMAKE_SKIP_BUILD_RPATH 1)
endif()
diff --git a/Tests/SubProject/CMakeLists.txt b/Tests/SubProject/CMakeLists.txt
index b669621df..b2bada911 100644
--- a/Tests/SubProject/CMakeLists.txt
+++ b/Tests/SubProject/CMakeLists.txt
@@ -1,6 +1,15 @@
cmake_minimum_required (VERSION 2.6)
project(SubProject)
-message("${CMAKE_IMPORT_LIBRARY_SUFFIX}")
+file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/gen.cxx) # require generation
+add_custom_command(
+ OUTPUT gen.cxx
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/gen.cxx.in
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_CURRENT_SOURCE_DIR}/gen.cxx.in gen.cxx
+ )
+add_custom_target(gen DEPENDS gen.cxx)
add_library(bar bar.cxx)
+target_include_directories(bar PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+add_dependencies(bar gen)
add_executable(car car.cxx)
add_subdirectory(foo)
diff --git a/Tests/SubProject/bar.cxx b/Tests/SubProject/bar.cxx
index c3f6a181a..c8b874356 100644
--- a/Tests/SubProject/bar.cxx
+++ b/Tests/SubProject/bar.cxx
@@ -1,4 +1 @@
-int bar()
-{
- return 10;
-}
+#include "gen.cxx"
diff --git a/Tests/SubProject/gen.cxx.in b/Tests/SubProject/gen.cxx.in
new file mode 100644
index 000000000..c3f6a181a
--- /dev/null
+++ b/Tests/SubProject/gen.cxx.in
@@ -0,0 +1,4 @@
+int bar()
+{
+ return 10;
+}
diff --git a/Tests/SwiftMix/CMain.c b/Tests/SwiftMix/CMain.c
new file mode 100644
index 000000000..13e2f8cc6
--- /dev/null
+++ b/Tests/SwiftMix/CMain.c
@@ -0,0 +1,4 @@
+extern int ObjCMain(int argc, char const* const argv[]);
+int main(int argc, char* argv[]) {
+ return ObjCMain(argc, argv);
+}
diff --git a/Tests/SwiftMix/CMakeLists.txt b/Tests/SwiftMix/CMakeLists.txt
new file mode 100644
index 000000000..5e50470f6
--- /dev/null
+++ b/Tests/SwiftMix/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.3)
+project(SwiftMix C Swift)
+
+add_executable(SwiftMix CMain.c ObjCMain.m SwiftMain.swift ObjC-Swift.h)
+set_property(TARGET SwiftMix PROPERTY XCODE_ATTRIBUTE_SWIFT_OBJC_BRIDGING_HEADER "ObjC-Swift.h")
diff --git a/Tests/SwiftMix/ObjC-Swift.h b/Tests/SwiftMix/ObjC-Swift.h
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/SwiftMix/ObjC-Swift.h
diff --git a/Tests/SwiftMix/ObjCMain.m b/Tests/SwiftMix/ObjCMain.m
new file mode 100644
index 000000000..7fa90aefb
--- /dev/null
+++ b/Tests/SwiftMix/ObjCMain.m
@@ -0,0 +1,4 @@
+#import "SwiftMix-Swift.h"
+int ObjCMain(int argc, char const* const argv[]) {
+ return [SwiftMainClass SwiftMain:argc argv:argv];
+}
diff --git a/Tests/SwiftMix/SwiftMain.swift b/Tests/SwiftMix/SwiftMain.swift
new file mode 100644
index 000000000..3629ac82a
--- /dev/null
+++ b/Tests/SwiftMix/SwiftMain.swift
@@ -0,0 +1,12 @@
+import Foundation
+
+@objc class SwiftMainClass : NSObject {
+ class func SwiftMain(argc:Int, argv:UnsafePointer<UnsafePointer<CChar>>) -> Int32 {
+ dump("argc: \(argc)")
+ for (var i = 0; i < argc; ++i) {
+ let argi = String.fromCString(argv[i])
+ dump("arg[\(i)]: \(argi)");
+ }
+ return 0;
+ }
+}
diff --git a/Tests/SwiftOnly/CMakeLists.txt b/Tests/SwiftOnly/CMakeLists.txt
new file mode 100644
index 000000000..5cb973945
--- /dev/null
+++ b/Tests/SwiftOnly/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.3)
+project(SwiftOnly Swift)
+
+add_executable(SwiftOnly main.swift)
diff --git a/Tests/SwiftOnly/main.swift b/Tests/SwiftOnly/main.swift
new file mode 100644
index 000000000..28560d076
--- /dev/null
+++ b/Tests/SwiftOnly/main.swift
@@ -0,0 +1 @@
+dump("SwiftOnly")
diff --git a/Tests/SystemInformation/CMakeLists.txt b/Tests/SystemInformation/CMakeLists.txt
index 838fd4aa1..db5461245 100644
--- a/Tests/SystemInformation/CMakeLists.txt
+++ b/Tests/SystemInformation/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required (VERSION 2.6)
+cmake_minimum_required (VERSION 3.0)
project(SystemInformation)
include_directories("This does not exists")
@@ -57,5 +57,3 @@ endforeach()
get_directory_property(res INCLUDE_REGULAR_EXPRESSION)
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/OtherProperties.txt
"INCLUDE_REGULAR_EXPRESSION: ${res}\n")
-
-
diff --git a/Tests/SystemInformation/SystemInformation.in b/Tests/SystemInformation/SystemInformation.in
index df3bf49d5..f7e81e625 100644
--- a/Tests/SystemInformation/SystemInformation.in
+++ b/Tests/SystemInformation/SystemInformation.in
@@ -19,8 +19,26 @@ CMAKE_COMPILER_IS_GNUCC == "${CMAKE_COMPILER_IS_GNUCC}"
CMAKE_COMPILER_IS_GNUCXX == "${CMAKE_COMPILER_IS_GNUCXX}"
CMAKE_C_COMPILER_ID == "${CMAKE_C_COMPILER_ID}"
CMAKE_C_COMPILER_VERSION == "${CMAKE_C_COMPILER_VERSION}"
+CMAKE_C90_STANDARD_COMPILE_OPTION == "${CMAKE_C90_STANDARD_COMPILE_OPTION}"
+CMAKE_C99_STANDARD_COMPILE_OPTION == "${CMAKE_C99_STANDARD_COMPILE_OPTION}"
+CMAKE_C11_STANDARD_COMPILE_OPTION == "${CMAKE_C11_STANDARD_COMPILE_OPTION}"
+CMAKE_C90_EXTENSION_COMPILE_OPTION == "${CMAKE_C90_EXTENSION_COMPILE_OPTION}"
+CMAKE_C99_EXTENSION_COMPILE_OPTION == "${CMAKE_C99_EXTENSION_COMPILE_OPTION}"
+CMAKE_C11_EXTENSION_COMPILE_OPTION == "${CMAKE_C11_EXTENSION_COMPILE_OPTION}"
+CMAKE_C_COMPILE_FEATURES == "${CMAKE_C_COMPILE_FEATURES}"
+CMAKE_C90_COMPILE_FEATURES == "${CMAKE_C90_COMPILE_FEATURES}"
+CMAKE_C99_COMPILE_FEATURES == "${CMAKE_C99_COMPILE_FEATURES}"
+CMAKE_C11_COMPILE_FEATURES == "${CMAKE_C11_COMPILE_FEATURES}"
CMAKE_CXX_COMPILER_ID == "${CMAKE_CXX_COMPILER_ID}"
CMAKE_CXX_COMPILER_VERSION == "${CMAKE_CXX_COMPILER_VERSION}"
+CMAKE_CXX98_STANDARD_COMPILE_OPTION == "${CMAKE_CXX98_STANDARD_COMPILE_OPTION}"
+CMAKE_CXX11_STANDARD_COMPILE_OPTION == "${CMAKE_CXX11_STANDARD_COMPILE_OPTION}"
+CMAKE_CXX98_EXTENSION_COMPILE_OPTION == "${CMAKE_CXX98_EXTENSION_COMPILE_OPTION}"
+CMAKE_CXX11_EXTENSION_COMPILE_OPTION == "${CMAKE_CXX11_EXTENSION_COMPILE_OPTION}"
+CMAKE_CXX_COMPILE_FEATURES == "${CMAKE_CXX_COMPILE_FEATURES}"
+CMAKE_CXX98_COMPILE_FEATURES == "${CMAKE_CXX98_COMPILE_FEATURES}"
+CMAKE_CXX11_COMPILE_FEATURES == "${CMAKE_CXX11_COMPILE_FEATURES}"
+CMAKE_CXX14_COMPILE_FEATURES == "${CMAKE_CXX14_COMPILE_FEATURES}"
// C shared library flag
CMAKE_SHARED_LIBRARY_C_FLAGS == "${CMAKE_SHARED_LIBRARY_C_FLAGS}"
diff --git a/Tests/TarTest/CMakeLists.txt b/Tests/TarTest/CMakeLists.txt
deleted file mode 100644
index bcc340bb3..000000000
--- a/Tests/TarTest/CMakeLists.txt
+++ /dev/null
@@ -1,69 +0,0 @@
-cmake_minimum_required (VERSION 2.6)
-project(TarTest)
-
-# this is macro that we will be running
-macro(EXEC_TAR_COMMAND DIR ARGS)
- exec_program("${CMAKE_COMMAND}" "${DIR}" ARGS "-E tar ${ARGS}" RETURN_VALUE RET)
- if(${RET})
- message(FATAL_ERROR "CMake tar command failed with arguments \"${ARGS}\"")
- endif()
-endmacro()
-
-# Create a directory structure
-set(CHECK_FILES)
-macro(COPY F1 F2)
- configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${F1}" "${CMAKE_CURRENT_BINARY_DIR}/tar_dir/${F2}" COPYONLY)
- set(CHECK_FILES ${CHECK_FILES} "${F2}")
-endmacro()
-COPY("CMakeLists.txt" "f1.txt")
-COPY("CMakeLists.txt" "d1/f1.txt")
-COPY("CMakeLists.txt" "d 2/f1.txt")
-COPY("CMakeLists.txt" "d + 3/f1.txt")
-COPY("CMakeLists.txt" "d_4/f1.txt")
-COPY("CMakeLists.txt" "d-4/f1.txt")
-COPY("CMakeLists.txt" "My Special Directory/f1.txt")
-
-if(UNIX)
- exec_program("ln" ARGS "-sf f1.txt \"${CMAKE_CURRENT_BINARY_DIR}/tar_dir/d1/f2.txt\"")
- set(CHECK_FILES ${CHECK_FILES} "d1/f2.txt")
-endif()
-
-# cleanup first in case there are files left from previous runs
-# if the umask is odd on the machine it might create files that
-# are not automatically over written. These tests are run
-# each time the configure step is run.
-file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/test_tar.tar")
-file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/test_tgz.tgz")
-file(REMOVE_RECURSE "${CMAKE_CURRENT_BINARY_DIR}/test_output_tar")
-file(REMOVE_RECURSE "${CMAKE_CURRENT_BINARY_DIR}/test_output_tgz")
-
-make_directory("${CMAKE_CURRENT_BINARY_DIR}/test_output_tar")
-make_directory("${CMAKE_CURRENT_BINARY_DIR}/test_output_tgz")
-
-
-# Run tests
-EXEC_TAR_COMMAND("${CMAKE_CURRENT_BINARY_DIR}" "cvf \"${CMAKE_CURRENT_BINARY_DIR}/test_tar.tar\" tar_dir")
-EXEC_TAR_COMMAND("${CMAKE_CURRENT_BINARY_DIR}" "cvfz \"${CMAKE_CURRENT_BINARY_DIR}/test_tgz.tgz\" tar_dir")
-
-EXEC_TAR_COMMAND("${CMAKE_CURRENT_BINARY_DIR}/test_output_tar" "xvf \"${CMAKE_CURRENT_BINARY_DIR}/test_tar.tar\"")
-EXEC_TAR_COMMAND("${CMAKE_CURRENT_BINARY_DIR}/test_output_tgz" "xvfz \"${CMAKE_CURRENT_BINARY_DIR}/test_tgz.tgz\"")
-
-macro(CHECK_DIR_STRUCTURE DIR)
- foreach(file ${CHECK_FILES})
- set(sfile "${DIR}/${file}")
- set(rfile "${CMAKE_CURRENT_BINARY_DIR}/tar_dir/${file}")
- if(NOT EXISTS "${sfile}")
- message(SEND_ERROR "Cannot find file ${sfile}")
- else()
- exec_program("${CMAKE_COMMAND}" ARGS "-E compare_files \"${sfile}\" \"${rfile}\"" RETURN_VALUE ret)
- if(${ret})
- message(SEND_ERROR "Files \"${sfile}\" \"${rfile}\" are different")
- endif()
- endif()
- endforeach()
-endmacro()
-
-CHECK_DIR_STRUCTURE("${CMAKE_CURRENT_BINARY_DIR}/test_output_tar/tar_dir")
-
-add_executable(TarTest TestTarExec.cxx)
-
diff --git a/Tests/TarTest/TestTarExec.cxx b/Tests/TarTest/TestTarExec.cxx
deleted file mode 100644
index 86f2cd170..000000000
--- a/Tests/TarTest/TestTarExec.cxx
+++ /dev/null
@@ -1,5 +0,0 @@
-int main()
-{
- return 0;
-}
-
diff --git a/Tests/TestInstall.sh.in b/Tests/TestInstall.sh.in
deleted file mode 100755
index 953578050..000000000
--- a/Tests/TestInstall.sh.in
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/bin/sh
-
-CMAKE_COMMAND="@CMAKE_INSTALL_PREFIX@/bin/cmake"
-CMake_SOURCE_DIR="@CMake_SOURCE_DIR@"
-CMake_BINARY_DIR="@CMake_BINARY_DIR@"
-CMAKE_INSTALL_PREFIX="@CMAKE_INSTALL_PREFIX@"
-CMAKE_BUILD_TOOL="@CMAKE_BUILD_TOOL@"
-
-SOURCE_DIR="${CMake_SOURCE_DIR}/Tests/Simple"
-BINARY_DIR="${CMake_BINARY_DIR}/Tests/TestInstall"
-
-install()
-{
- echo "Erasing ${CMAKE_INSTALL_PREFIX}" &&
- ([ ! -d "${CMAKE_INSTALL_PREFIX}" ] || rm -rf "${CMAKE_INSTALL_PREFIX}") &&
- mkdir -p "${CMAKE_INSTALL_PREFIX}" &&
- echo "Running make install" &&
- (
- cd "${CMake_BINARY_DIR}" &&
- "${CMAKE_BUILD_TOOL}" install
- )
-}
-
-setup()
-{
- echo "Entering ${BINARY_DIR}" &&
- cd "${BINARY_DIR}"
-}
-
-write_cache()
-{
- install || return 1
- setup || return 1
- echo "Writing CMakeCache.txt"
- (
- cat > CMakeCache.txt <<EOF
-EOF
- )
-}
-
-run_cmake()
-{
- write_cache || return 1
- echo "Running CMake"
- "${CMAKE_COMMAND}" "${SOURCE_DIR}"
-}
-
-run_make()
-{
- run_cmake || return 1
- echo "Running ${CMAKE_BUILD_TOOL}"
- "${CMAKE_BUILD_TOOL}"
-}
-
-run_test()
-{
- echo "Running ${BINARY_DIR}/simple"
- (
- "${BINARY_DIR}/simple"
- )
-}
-
-run_make && run_test
diff --git a/Tests/TryCompile/CMakeLists.txt b/Tests/TryCompile/CMakeLists.txt
index a4d949006..e497503e2 100644
--- a/Tests/TryCompile/CMakeLists.txt
+++ b/Tests/TryCompile/CMakeLists.txt
@@ -265,7 +265,7 @@ TEST_FAIL(CXX_RUN_SHOULD_FAIL "CHECK_CXX_SOURCE_RUNS() succeeded, but should hav
TEST_ASSERT(CXX_RUN_SHOULD_WORK "CHECK_CXX_SOURCE_RUNS() failed")
foreach(lang C CXX)
- if(NOT "${CMAKE_${lang}_COMPILER_ID}" MATCHES "^(PathScale)$")
+ if(NOT CMAKE_${lang}_COMPILER_ID STREQUAL "PathScale")
set(${lang}_DD --)
endif()
endforeach()
@@ -280,7 +280,7 @@ include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG(${CXX_DD}-_this_is_not_a_flag_ CXX_BOGUS_FLAG)
TEST_FAIL(CXX_BOGUS_FLAG "CHECK_CXX_COMPILER_FLAG() succeeded, but should have failed")
-if("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
+if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
unset(C_STRICT_PROTOTYPES CACHE)
CHECK_C_COMPILER_FLAG("-Werror;-Wstrict-prototypes" C_STRICT_PROTOTYPES)
TEST_ASSERT(C_STRICT_PROTOTYPES "CHECK_C_COMPILER_FLAG failed -Werror -Wstrict-prototypes")
diff --git a/Tests/Tutorial/Step2/tutorial.cxx b/Tests/Tutorial/Step2/tutorial.cxx
index 82b416f11..c27da0b84 100644
--- a/Tests/Tutorial/Step2/tutorial.cxx
+++ b/Tests/Tutorial/Step2/tutorial.cxx
@@ -21,12 +21,16 @@ int main (int argc, char *argv[])
}
double inputValue = atof(argv[1]);
+ double outputValue = 0;
+ if(inputValue >= 0)
+ {
#ifdef USE_MYMATH
- double outputValue = mysqrt(inputValue);
+ outputValue = mysqrt(inputValue);
#else
- double outputValue = sqrt(inputValue);
+ outputValue = sqrt(inputValue);
#endif
+ }
fprintf(stdout,"The square root of %g is %g\n",
inputValue, outputValue);
diff --git a/Tests/Tutorial/Step3/tutorial.cxx b/Tests/Tutorial/Step3/tutorial.cxx
index 82b416f11..c27da0b84 100644
--- a/Tests/Tutorial/Step3/tutorial.cxx
+++ b/Tests/Tutorial/Step3/tutorial.cxx
@@ -21,12 +21,16 @@ int main (int argc, char *argv[])
}
double inputValue = atof(argv[1]);
+ double outputValue = 0;
+ if(inputValue >= 0)
+ {
#ifdef USE_MYMATH
- double outputValue = mysqrt(inputValue);
+ outputValue = mysqrt(inputValue);
#else
- double outputValue = sqrt(inputValue);
+ outputValue = sqrt(inputValue);
#endif
+ }
fprintf(stdout,"The square root of %g is %g\n",
inputValue, outputValue);
diff --git a/Tests/Tutorial/Step4/tutorial.cxx b/Tests/Tutorial/Step4/tutorial.cxx
index 82b416f11..c27da0b84 100644
--- a/Tests/Tutorial/Step4/tutorial.cxx
+++ b/Tests/Tutorial/Step4/tutorial.cxx
@@ -21,12 +21,16 @@ int main (int argc, char *argv[])
}
double inputValue = atof(argv[1]);
+ double outputValue = 0;
+ if(inputValue >= 0)
+ {
#ifdef USE_MYMATH
- double outputValue = mysqrt(inputValue);
+ outputValue = mysqrt(inputValue);
#else
- double outputValue = sqrt(inputValue);
+ outputValue = sqrt(inputValue);
#endif
+ }
fprintf(stdout,"The square root of %g is %g\n",
inputValue, outputValue);
diff --git a/Tests/Tutorial/Step5/tutorial.cxx b/Tests/Tutorial/Step5/tutorial.cxx
index 82b416f11..c27da0b84 100644
--- a/Tests/Tutorial/Step5/tutorial.cxx
+++ b/Tests/Tutorial/Step5/tutorial.cxx
@@ -21,12 +21,16 @@ int main (int argc, char *argv[])
}
double inputValue = atof(argv[1]);
+ double outputValue = 0;
+ if(inputValue >= 0)
+ {
#ifdef USE_MYMATH
- double outputValue = mysqrt(inputValue);
+ outputValue = mysqrt(inputValue);
#else
- double outputValue = sqrt(inputValue);
+ outputValue = sqrt(inputValue);
#endif
+ }
fprintf(stdout,"The square root of %g is %g\n",
inputValue, outputValue);
diff --git a/Tests/Tutorial/Step6/MathFunctions/CMakeLists.txt b/Tests/Tutorial/Step6/MathFunctions/CMakeLists.txt
index 9961e6945..70a35f662 100644
--- a/Tests/Tutorial/Step6/MathFunctions/CMakeLists.txt
+++ b/Tests/Tutorial/Step6/MathFunctions/CMakeLists.txt
@@ -1,13 +1,11 @@
# first we add the executable that generates the table
add_executable(MakeTable MakeTable.cxx)
-get_target_property(MakeTableLocation MakeTable LOCATION)
-
# add the command to generate the source code
add_custom_command (
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
DEPENDS MakeTable
- COMMAND ${MakeTableLocation}
+ COMMAND MakeTable
ARGS ${CMAKE_CURRENT_BINARY_DIR}/Table.h
)
diff --git a/Tests/Tutorial/Step6/tutorial.cxx b/Tests/Tutorial/Step6/tutorial.cxx
index 82b416f11..c27da0b84 100644
--- a/Tests/Tutorial/Step6/tutorial.cxx
+++ b/Tests/Tutorial/Step6/tutorial.cxx
@@ -21,12 +21,16 @@ int main (int argc, char *argv[])
}
double inputValue = atof(argv[1]);
+ double outputValue = 0;
+ if(inputValue >= 0)
+ {
#ifdef USE_MYMATH
- double outputValue = mysqrt(inputValue);
+ outputValue = mysqrt(inputValue);
#else
- double outputValue = sqrt(inputValue);
+ outputValue = sqrt(inputValue);
#endif
+ }
fprintf(stdout,"The square root of %g is %g\n",
inputValue, outputValue);
diff --git a/Tests/Tutorial/Step7/MathFunctions/CMakeLists.txt b/Tests/Tutorial/Step7/MathFunctions/CMakeLists.txt
index 9961e6945..70a35f662 100644
--- a/Tests/Tutorial/Step7/MathFunctions/CMakeLists.txt
+++ b/Tests/Tutorial/Step7/MathFunctions/CMakeLists.txt
@@ -1,13 +1,11 @@
# first we add the executable that generates the table
add_executable(MakeTable MakeTable.cxx)
-get_target_property(MakeTableLocation MakeTable LOCATION)
-
# add the command to generate the source code
add_custom_command (
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
DEPENDS MakeTable
- COMMAND ${MakeTableLocation}
+ COMMAND MakeTable
ARGS ${CMAKE_CURRENT_BINARY_DIR}/Table.h
)
diff --git a/Tests/Tutorial/Step7/tutorial.cxx b/Tests/Tutorial/Step7/tutorial.cxx
index 82b416f11..c27da0b84 100644
--- a/Tests/Tutorial/Step7/tutorial.cxx
+++ b/Tests/Tutorial/Step7/tutorial.cxx
@@ -21,12 +21,16 @@ int main (int argc, char *argv[])
}
double inputValue = atof(argv[1]);
+ double outputValue = 0;
+ if(inputValue >= 0)
+ {
#ifdef USE_MYMATH
- double outputValue = mysqrt(inputValue);
+ outputValue = mysqrt(inputValue);
#else
- double outputValue = sqrt(inputValue);
+ outputValue = sqrt(inputValue);
#endif
+ }
fprintf(stdout,"The square root of %g is %g\n",
inputValue, outputValue);
diff --git a/Tests/Unset/CMakeLists.txt b/Tests/Unset/CMakeLists.txt
index 781da3fa6..07aa68e7a 100644
--- a/Tests/Unset/CMakeLists.txt
+++ b/Tests/Unset/CMakeLists.txt
@@ -51,5 +51,32 @@ if(DEFINED BAR)
message(FATAL_ERROR "BAR still defined")
endif()
+# Test unset(... PARENT_SCOPE)
+function(unset_zots)
+ if(NOT DEFINED ZOT1)
+ message(FATAL_ERROR "ZOT1 is not defined inside function")
+ endif()
+ if(NOT DEFINED ZOT2)
+ message(FATAL_ERROR "ZOT2 is not defined inside function")
+ endif()
+ unset(ZOT1)
+ unset(ZOT2 PARENT_SCOPE)
+ if(DEFINED ZOT1)
+ message(FATAL_ERROR "ZOT1 is defined inside function after unset")
+ endif()
+ if(NOT DEFINED ZOT2)
+ message(FATAL_ERROR
+ "ZOT2 is not defined inside function after unset(... PARENT_SCOPE)")
+ endif()
+endfunction()
+set(ZOT1 1)
+set(ZOT2 2)
+unset_zots()
+if(NOT DEFINED ZOT1)
+ message(FATAL_ERROR "ZOT1 is not still defined after function")
+endif()
+if(DEFINED ZOT2)
+ message(FATAL_ERROR "ZOT2 is still defined after function unset PARENT_SCOPE")
+endif()
add_executable(Unset unset.c)
diff --git a/Tests/VSExcludeFromDefaultBuild/CMakeLists.txt b/Tests/VSExcludeFromDefaultBuild/CMakeLists.txt
index d30414b4b..243fdf589 100644
--- a/Tests/VSExcludeFromDefaultBuild/CMakeLists.txt
+++ b/Tests/VSExcludeFromDefaultBuild/CMakeLists.txt
@@ -1,6 +1,9 @@
cmake_minimum_required(VERSION 2.8.9)
project(VSExcludeFromDefaultBuild)
+# CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD will enable the INSTALL target to be part of the default build
+set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1)
+
# First step is to clear all .exe files in output so that possible past
# failures of this test do not prevent it from succeeding.
add_custom_target(ClearExes ALL
@@ -13,6 +16,7 @@ add_custom_target(ClearExes ALL
function(add_test_executable target)
add_executable("${target}" ${ARGN})
add_dependencies("${target}" ClearExes)
+ install(TARGETS "${target}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/install" OPTIONAL)
endfunction()
add_test_executable(DefaultBuilt main.c)
diff --git a/Tests/VSExcludeFromDefaultBuild/ClearExes.cmake b/Tests/VSExcludeFromDefaultBuild/ClearExes.cmake
index ece30ad00..99cf1a5cf 100644
--- a/Tests/VSExcludeFromDefaultBuild/ClearExes.cmake
+++ b/Tests/VSExcludeFromDefaultBuild/ClearExes.cmake
@@ -2,3 +2,7 @@ file(GLOB exeFiles "${dir}/*.exe")
foreach(exeFile IN LISTS exeFiles)
file(REMOVE "${exeFile}")
endforeach()
+file(GLOB exeFiles "${dir}/install/*.exe")
+foreach(exeFile IN LISTS exeFiles)
+ file(REMOVE "${exeFile}")
+endforeach()
diff --git a/Tests/VSExcludeFromDefaultBuild/ResultTest.cmake b/Tests/VSExcludeFromDefaultBuild/ResultTest.cmake
index 8fb00bfad..f96e70bc7 100644
--- a/Tests/VSExcludeFromDefaultBuild/ResultTest.cmake
+++ b/Tests/VSExcludeFromDefaultBuild/ResultTest.cmake
@@ -7,6 +7,12 @@ macro(TestExists exeName)
else()
message(FATAL_ERROR "File ${exeFile} was expected ${ARGN} to exist!")
endif()
+ set(exeFile "${dir}/${activeConfig}/install/${exeName}.exe")
+ if(${ARGN} EXISTS "${exeFile}")
+ message(STATUS "File ${exeFile} was correctly found ${ARGN} to exist.")
+ else()
+ message(FATAL_ERROR "File ${exeFile} was expected ${ARGN} to exist!")
+ endif()
endmacro()
TestExists(DefaultBuilt)
diff --git a/Tests/VSExternalInclude/CMakeLists.txt b/Tests/VSExternalInclude/CMakeLists.txt
index 8fc287145..73ea05a29 100644
--- a/Tests/VSExternalInclude/CMakeLists.txt
+++ b/Tests/VSExternalInclude/CMakeLists.txt
@@ -6,7 +6,7 @@ if(${CMAKE_GENERATOR} MATCHES "Visual Studio 6")
else()
set(PROJECT_EXT vcproj)
endif()
-if(${CMAKE_GENERATOR} MATCHES "Visual Studio 1[012]")
+if(${CMAKE_GENERATOR} MATCHES "Visual Studio 1[0124]")
set(PROJECT_EXT vcxproj)
endif()
@@ -19,7 +19,9 @@ make_directory("${LIB2_BINARY_DIR}")
# generate lib1
execute_process(
- COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" -T "${CMAKE_GENERATOR_TOOLSET}" "${VSExternalInclude_SOURCE_DIR}/Lib1"
+ COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}"
+ -A "${CMAKE_GENERATOR_PLATFORM}"
+ -T "${CMAKE_GENERATOR_TOOLSET}" "${VSExternalInclude_SOURCE_DIR}/Lib1"
WORKING_DIRECTORY ${LIB1_BINARY_DIR}
OUTPUT_VARIABLE OUT
ERROR_VARIABLE OUT
@@ -28,7 +30,9 @@ message("CMAKE Ran with the following output:\n\"${OUT}\"")
# generate lib2
execute_process(
- COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" -T "${CMAKE_GENERATOR_TOOLSET}" "${VSExternalInclude_SOURCE_DIR}/Lib2"
+ COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}"
+ -A "${CMAKE_GENERATOR_PLATFORM}"
+ -T "${CMAKE_GENERATOR_TOOLSET}" "${VSExternalInclude_SOURCE_DIR}/Lib2"
WORKING_DIRECTORY ${LIB2_BINARY_DIR}
OUTPUT_VARIABLE OUT
ERROR_VARIABLE OUT
@@ -54,7 +58,7 @@ add_dependencies(VSExternalInclude lib2)
# and the sln file can no longer be the only source
# of that depend. So, for VS 10 make the executable
# depend on lib1 and lib2
-if(${CMAKE_GENERATOR} MATCHES "Visual Studio 1[012]")
+if(${CMAKE_GENERATOR} MATCHES "Visual Studio 1[0124]")
add_dependencies(VSExternalInclude lib1)
endif()
diff --git a/Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt b/Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt
index 3ee1855c3..f68e38e20 100644
--- a/Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt
+++ b/Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt
@@ -35,12 +35,12 @@ add_library(hello SHARED hello.f)
add_library(world SHARED world.f)
target_link_libraries(hello world)
if(CMAKE_Fortran_COMPILER_ID MATCHES SunPro)
- target_link_libraries(hello fsu)
+ target_link_libraries(hello PRIVATE fsu)
if(CMAKE_Fortran_PLATFORM_ID MATCHES SunOS)
- target_link_libraries(hello sunmath m)
+ target_link_libraries(hello PRIVATE sunmath m)
test_sunquad(CMAKE_HAS_SUNQUAD)
if(CMAKE_HAS_SUNQUAD)
- target_link_libraries(hello sunquad)
+ target_link_libraries(hello PRIVATE sunquad)
endif()
endif()
endif()
diff --git a/Tests/VSMASM/CMakeLists.txt b/Tests/VSMASM/CMakeLists.txt
new file mode 100644
index 000000000..f2570a309
--- /dev/null
+++ b/Tests/VSMASM/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 2.8.12)
+project(VSMASM C ASM_MASM)
+if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ add_definitions(-DTESTx64)
+else()
+ add_definitions(-DTESTi386)
+ set(CMAKE_ASM_MASM_FLAGS "${CMAKE_ASM_MASM_FLAGS} /safeseh")
+endif()
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
+add_executable(VSMASM main.c foo.asm)
diff --git a/Tests/VSMASM/foo.asm b/Tests/VSMASM/foo.asm
new file mode 100644
index 000000000..51cb96931
--- /dev/null
+++ b/Tests/VSMASM/foo.asm
@@ -0,0 +1,7 @@
+ifndef TESTx64
+.386
+.model flat, c
+endif
+.code
+include <foo-proc.asm>
+end
diff --git a/Tests/VSMASM/include/foo-proc.asm b/Tests/VSMASM/include/foo-proc.asm
new file mode 100644
index 000000000..e8ba5dcb4
--- /dev/null
+++ b/Tests/VSMASM/include/foo-proc.asm
@@ -0,0 +1,4 @@
+foo proc public
+ mov eax,0
+ ret
+foo endp
diff --git a/Tests/VSMASM/main.c b/Tests/VSMASM/main.c
new file mode 100644
index 000000000..570ba161b
--- /dev/null
+++ b/Tests/VSMASM/main.c
@@ -0,0 +1,2 @@
+extern int foo(void);
+int main(void) { return foo(); }
diff --git a/Tests/VSNsightTegra/AndroidManifest.xml b/Tests/VSNsightTegra/AndroidManifest.xml
new file mode 100644
index 000000000..951e8f308
--- /dev/null
+++ b/Tests/VSNsightTegra/AndroidManifest.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.twolibs"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <uses-sdk android:minSdkVersion="3" />
+ <application android:label="@string/app_name">
+ <activity android:name=".TwoLibs"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/Tests/VSNsightTegra/CMakeLists.txt b/Tests/VSNsightTegra/CMakeLists.txt
new file mode 100644
index 000000000..61a04fdd3
--- /dev/null
+++ b/Tests/VSNsightTegra/CMakeLists.txt
@@ -0,0 +1,57 @@
+cmake_minimum_required(VERSION 3.3)
+project(VSNsightTegra C CXX)
+
+set(CMAKE_ANDROID_ARCH armv7-a-hard)
+set(CMAKE_ANDROID_STL_TYPE stlport_shared)
+set(CMAKE_ANDROID_API_MIN 9)
+set(CMAKE_ANDROID_API 15)
+set(CMAKE_ANDROID_GUI 1)
+
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
+
+set(FIRST_C_FILES
+ jni/first.c
+ jni/first.h
+ )
+
+source_group(jni FILES ${FIRST_C_FILES})
+add_library(twolib-first ${FIRST_C_FILES})
+
+set(SECOND_C_FILES
+ jni/second.c
+ )
+set(SECOND_JAVA_FILES
+ src/com/example/twolibs/TwoLibs.java
+ )
+set(SECOND_RES_FILES
+ res/values/strings.xml
+ )
+set(SECOND_ANDROID_FILES
+ AndroidManifest.xml
+ )
+
+source_group(jni FILES ${SECOND_C_FILES})
+source_group(res\\values FILES ${SECOND_RES_FILES})
+source_group(src\\com\\example\\twolibs FILES ${SECOND_JAVA_FILES})
+add_executable(twolib-second
+ ${SECOND_C_FILES}
+ ${SECOND_JAVA_FILES}
+ ${SECOND_RES_FILES}
+ ${SECOND_ANDROID_FILES}
+ )
+target_include_directories(twolib-second PUBLIC jni)
+target_link_libraries(twolib-second twolib-first)
+target_link_libraries(twolib-second m) # test linking to library by name
+
+set_property(TARGET twolib-second PROPERTY C_STANDARD 11)
+set_target_properties(twolib-second PROPERTIES ANDROID_SKIP_ANT_STEP 1)
+set_target_properties(twolib-second PROPERTIES ANDROID_PROGUARD 1)
+set_target_properties(twolib-second PROPERTIES ANDROID_PROGUARD_CONFIG_PATH proguard-android.txt)
+set_target_properties(twolib-second PROPERTIES ANDROID_SECURE_PROPS_PATH /definitely/insecure)
+
+set_property(TARGET twolib-second PROPERTY ANDROID_NATIVE_LIB_DIRECTORIES $<TARGET_FILE_DIR:twolib-second>)
+set_property(TARGET twolib-second PROPERTY ANDROID_NATIVE_LIB_DEPENDENCIES $<TARGET_FILE_NAME:twolib-second>)
+
+set_property(TARGET twolib-second PROPERTY ANDROID_JAR_DIRECTORIES $<TARGET_FILE_DIR:twolib-first>)
diff --git a/Tests/VSNsightTegra/build.xml b/Tests/VSNsightTegra/build.xml
new file mode 100644
index 000000000..17a2cc07b
--- /dev/null
+++ b/Tests/VSNsightTegra/build.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="TwoLibs" default="help">
+ <import file="${sdk.dir}/tools/ant/build.xml" />
+</project>
diff --git a/Tests/VSNsightTegra/jni/first.c b/Tests/VSNsightTegra/jni/first.c
new file mode 100644
index 000000000..f09e376de
--- /dev/null
+++ b/Tests/VSNsightTegra/jni/first.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include "first.h"
+
+int first(int x, int y)
+{
+ return x + y;
+}
diff --git a/Tests/VSNsightTegra/jni/first.h b/Tests/VSNsightTegra/jni/first.h
new file mode 100644
index 000000000..d89348015
--- /dev/null
+++ b/Tests/VSNsightTegra/jni/first.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#ifndef FIRST_H
+#define FIRST_H
+
+extern int first(int x, int y);
+
+#endif /* FIRST_H */
diff --git a/Tests/VSNsightTegra/jni/second.c b/Tests/VSNsightTegra/jni/second.c
new file mode 100644
index 000000000..463184855
--- /dev/null
+++ b/Tests/VSNsightTegra/jni/second.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include "first.h"
+#include <jni.h>
+
+jint
+Java_com_example_twolibs_TwoLibs_add( JNIEnv* env,
+ jobject this,
+ jint x,
+ jint y )
+{
+ return first(x, y);
+}
diff --git a/Tests/VSNsightTegra/proguard-android.txt b/Tests/VSNsightTegra/proguard-android.txt
new file mode 100644
index 000000000..fe73baeb5
--- /dev/null
+++ b/Tests/VSNsightTegra/proguard-android.txt
@@ -0,0 +1,57 @@
+# This is a configuration file for ProGuard.
+# http://proguard.sourceforge.net/index.html#manual/usage.html
+
+-dontusemixedcaseclassnames
+-dontskipnonpubliclibraryclasses
+-verbose
+
+# Optimization is turned off by default. Dex does not like code run
+# through the ProGuard optimize and preverify steps (and performs some
+# of these optimizations on its own).
+-dontoptimize
+-dontpreverify
+# Note that if you want to enable optimization, you cannot just
+# include optimization flags in your own project configuration file;
+# instead you will need to point to the
+# "proguard-android-optimize.txt" file instead of this one from your
+# project.properties file.
+
+-keepattributes *Annotation*
+-keep public class com.google.vending.licensing.ILicensingService
+-keep public class com.android.vending.licensing.ILicensingService
+
+# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
+-keepclasseswithmembernames class * {
+ native <methods>;
+}
+
+# keep setters in Views so that animations can still work.
+# see http://proguard.sourceforge.net/manual/examples.html#beans
+-keepclassmembers public class * extends android.view.View {
+ void set*(***);
+ *** get*();
+}
+
+# We want to keep methods in Activity that could be used in the XML attribute onClick
+-keepclassmembers class * extends android.app.Activity {
+ public void *(android.view.View);
+}
+
+# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
+-keepclassmembers enum * {
+ public static **[] values();
+ public static ** valueOf(java.lang.String);
+}
+
+-keep class * implements android.os.Parcelable {
+ public static final android.os.Parcelable$Creator *;
+}
+
+-keepclassmembers class **.R$* {
+ public static <fields>;
+}
+
+# The support library contains references to newer platform versions.
+# Don't warn about those in case this app is linking against an older
+# platform version. We know about them, and they are safe.
+-dontwarn android.support.**
diff --git a/Tests/VSNsightTegra/res/values/strings.xml b/Tests/VSNsightTegra/res/values/strings.xml
new file mode 100644
index 000000000..858cdb40e
--- /dev/null
+++ b/Tests/VSNsightTegra/res/values/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_name">TwoLibs</string>
+</resources>
diff --git a/Tests/VSNsightTegra/src/com/example/twolibs/TwoLibs.java b/Tests/VSNsightTegra/src/com/example/twolibs/TwoLibs.java
new file mode 100644
index 000000000..ef9da01cf
--- /dev/null
+++ b/Tests/VSNsightTegra/src/com/example/twolibs/TwoLibs.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.twolibs;
+
+import android.app.Activity;
+import android.widget.TextView;
+import android.os.Bundle;
+
+public class TwoLibs extends Activity
+{
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+
+ TextView tv = new TextView(this);
+ int x = 1000;
+ int y = 42;
+
+ // here, we dynamically load the library at runtime
+ // before calling the native method.
+ //
+ System.loadLibrary("twolib-second");
+
+ int z = add(x, y);
+
+ tv.setText( "The sum of " + x + " and " + y + " is " + z );
+ setContentView(tv);
+ }
+
+ public native int add(int x, int y);
+}
diff --git a/Tests/VSResource/CMakeLists.txt b/Tests/VSResource/CMakeLists.txt
index c5cb336ae..3b9cfc396 100644
--- a/Tests/VSResource/CMakeLists.txt
+++ b/Tests/VSResource/CMakeLists.txt
@@ -18,6 +18,11 @@ if(CMAKE_RC_COMPILER MATCHES windres)
message(STATUS "CMAKE_RC_COMPILER MATCHES windres")
add_definitions(/DCMAKE_RCDEFINE=test.txt)
add_definitions(/DCMAKE_RCDEFINE_NO_QUOTED_STRINGS)
+ if(MSYS AND CMAKE_CURRENT_BINARY_DIR MATCHES " ")
+ # windres cannot handle spaces in include dir, and
+ # for the MSys shell we do not convert to shortpath.
+ set(CMAKE_RC_NO_INCLUDE 1)
+ endif()
elseif(MSVC60)
# VS6 rc compiler does not deal well with spaces in a "/D" value, but it can
# handle the quoting
@@ -30,11 +35,21 @@ else()
set(TEXTFILE_FROM_SOURCE_DIR "textfile, spaces in name, from binary dir")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test.txt
"${CMAKE_CURRENT_BINARY_DIR}/test with spaces.txt" @ONLY)
- include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_definitions(/DCMAKE_RCDEFINE="test with spaces.txt")
endif()
+if(CMAKE_RC_NO_INCLUDE)
+ add_definitions(/DCMAKE_RC_NO_INCLUDE)
+else()
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include.rc.in
+ "${CMAKE_CURRENT_BINARY_DIR}/include.rc" @ONLY)
+ include_directories(${CMAKE_CURRENT_BINARY_DIR})
+endif()
+
+add_library(ResourceLib STATIC lib.cpp lib.rc)
+
add_executable(VSResource main.cpp test.rc)
+target_link_libraries(VSResource ResourceLib)
set_property(TARGET VSResource
PROPERTY VS_GLOBAL_CMakeTestVsGlobalVariable "test val")
diff --git a/Tests/VSResource/include.rc.in b/Tests/VSResource/include.rc.in
new file mode 100644
index 000000000..f0f685980
--- /dev/null
+++ b/Tests/VSResource/include.rc.in
@@ -0,0 +1 @@
+// This file should be included.
diff --git a/Tests/VSResource/lib.cpp b/Tests/VSResource/lib.cpp
new file mode 100644
index 000000000..006e3e48a
--- /dev/null
+++ b/Tests/VSResource/lib.cpp
@@ -0,0 +1 @@
+int lib() { return 0; }
diff --git a/Tests/VSResource/lib.rc b/Tests/VSResource/lib.rc
new file mode 100644
index 000000000..1ffade6ca
--- /dev/null
+++ b/Tests/VSResource/lib.rc
@@ -0,0 +1,4 @@
+STRINGTABLE
+BEGIN
+ 1234 "5"
+END
diff --git a/Tests/VSResource/main.cpp b/Tests/VSResource/main.cpp
index 7ee0c74fa..ccf700c42 100644
--- a/Tests/VSResource/main.cpp
+++ b/Tests/VSResource/main.cpp
@@ -1,6 +1,8 @@
#include <windows.h>
#include <stdio.h>
+extern int lib();
+
struct x
{
const char *txt;
@@ -76,5 +78,5 @@ int main(int argc, char** argv)
}
}
- return ret;
+ return ret + lib();
}
diff --git a/Tests/VSResource/test.rc b/Tests/VSResource/test.rc
index 4ce4b5312..0de468386 100644
--- a/Tests/VSResource/test.rc
+++ b/Tests/VSResource/test.rc
@@ -1,4 +1,7 @@
#ifdef CMAKE_RCDEFINE
+# ifndef CMAKE_RC_NO_INCLUDE
+# include <include.rc>
+# endif
// This line can compile with either an unquoted or a quoted string
1025 TEXTFILE CMAKE_RCDEFINE
diff --git a/Tests/VSWinStorePhone/CMakeLists.txt b/Tests/VSWinStorePhone/CMakeLists.txt
new file mode 100644
index 000000000..ae8275551
--- /dev/null
+++ b/Tests/VSWinStorePhone/CMakeLists.txt
@@ -0,0 +1,140 @@
+cmake_minimum_required(VERSION 3.0)
+project(VSWinStorePhone)
+if(MSVC_VERSION GREATER 1899)
+ set(COMPILER_VERSION "14")
+elseif(MSVC_VERSION GREATER 1700)
+ set(COMPILER_VERSION "12")
+elseif(MSVC_VERSION GREATER 1600)
+ set(COMPILER_VERSION "11")
+endif()
+
+set (APP_MANIFEST_NAME Package.appxmanifest)
+if("${CMAKE_SYSTEM_NAME}" STREQUAL "WindowsPhone")
+ set(PLATFORM WP)
+ add_definitions("-DPHONE")
+ if("${CMAKE_SYSTEM_VERSION}" STREQUAL "8.0")
+ set(APP_MANIFEST_NAME WMAppManifest.xml)
+ set(WINDOWS_PHONE8 1)
+ endif()
+elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "WindowsStore")
+ set(PLATFORM STORE)
+else()
+ set(PLATFORM DESKTOP)
+ message(FATAL_ERROR "This app supports Store / Phone only. Please edit the target platform.")
+endif()
+
+set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+
+set(EXE_NAME Direct3DApp1)
+set(SHORT_NAME ${EXE_NAME})
+set(PACKAGE_GUID "6514377e-dfd4-4cdb-80df-4e0366346efc")
+
+if (NOT "${PLATFORM}" STREQUAL "DESKTOP")
+ configure_file(
+ cmake/Package_vc${COMPILER_VERSION}.${PLATFORM}.appxmanifest.in
+ ${CMAKE_CURRENT_BINARY_DIR}/${APP_MANIFEST_NAME}
+ @ONLY)
+endif()
+
+set(SOURCE_FILES
+ Direct3DApp1/CubeRenderer.cpp
+ Direct3DApp1/Direct3DApp1.cpp
+ Direct3DApp1/Direct3DBase.cpp
+ Direct3DApp1/pch.cpp
+ )
+
+set(HEADER_FILES
+ Direct3DApp1/BasicTimer.h
+ Direct3DApp1/CubeRenderer.h
+ Direct3DApp1/Direct3DApp1.h
+ Direct3DApp1/Direct3DBase.h
+ Direct3DApp1/DirectXHelper.h
+ Direct3DApp1/pch.h
+ )
+
+set(PIXELSHADER_FILES
+ Direct3DApp1/SimplePixelShader.hlsl
+ )
+
+set(VERTEXSHADER_FILES
+ Direct3DApp1/SimpleVertexShader.hlsl
+ )
+
+set(CONTENT_FILES ${PIXELSHADER_FILES} ${VERTEXSHADER_FILES})
+
+if (WINDOWS_PHONE8)
+ set(CONTENT_FILES ${CONTENT_FILES}
+ ${CMAKE_CURRENT_BINARY_DIR}/${APP_MANIFEST_NAME}
+ Direct3DApp1/Assets/Tiles/FlipCycleTileLarge.png
+ Direct3DApp1/Assets/Tiles/FlipCycleTileMedium.png
+ Direct3DApp1/Assets/Tiles/FlipCycleTileSmall.png
+ Direct3DApp1/Assets/Tiles/IconicTileMediumLarge.png
+ Direct3DApp1/Assets/Tiles/IconicTileSmall.png
+ Direct3DApp1/Assets/ApplicationIcon.png
+ )
+ # Windows Phone 8.0 needs to copy all the images.
+ # It doesn't know to use relative paths.
+ file(COPY
+ Direct3DApp1/Assets/Tiles/FlipCycleTileLarge.png
+ Direct3DApp1/Assets/Tiles/FlipCycleTileMedium.png
+ Direct3DApp1/Assets/Tiles/FlipCycleTileSmall.png
+ Direct3DApp1/Assets/Tiles/IconicTileMediumLarge.png
+ Direct3DApp1/Assets/Tiles/IconicTileSmall.png
+ Direct3DApp1/Assets/ApplicationIcon.png
+ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
+ )
+
+elseif (NOT "${PLATFORM}" STREQUAL "DESKTOP")
+ set(CONTENT_FILES ${CONTENT_FILES}
+ ${CMAKE_CURRENT_BINARY_DIR}/${APP_MANIFEST_NAME}
+ )
+
+ set(ASSET_FILES ${ASSET_FILES}
+ Direct3DApp1/Assets/Logo.png
+ Direct3DApp1/Assets/SmallLogo.png
+ Direct3DApp1/Assets/SmallLogo44x44.png
+ Direct3DApp1/Assets/SplashScreen.png
+ Direct3DApp1/Assets/StoreLogo.png
+ )
+endif()
+
+set(RESOURCE_FILES
+ ${CONTENT_FILES} ${DEBUG_CONTENT_FILES} ${RELEASE_CONTENT_FILES} ${ASSET_FILES}
+ Direct3DApp1/Direct3DApp1_TemporaryKey.pfx)
+
+set_property(SOURCE ${CONTENT_FILES} PROPERTY VS_DEPLOYMENT_CONTENT 1)
+set_property(SOURCE ${ASSET_FILES} PROPERTY VS_DEPLOYMENT_CONTENT 1)
+set_property(SOURCE ${ASSET_FILES} PROPERTY VS_DEPLOYMENT_LOCATION "Assets")
+set_property(SOURCE ${DEBUG_CONTENT_FILES} PROPERTY VS_DEPLOYMENT_CONTENT $<CONFIG:Debug>)
+set_property(SOURCE ${RELEASE_CONTENT_FILES} PROPERTY
+ VS_DEPLOYMENT_CONTENT $<OR:$<CONFIG:Release>,$<CONFIG:RelWithDebInfo>,$<CONFIG:MinSizeRel>>)
+
+set_property(SOURCE ${PIXELSHADER_FILES} PROPERTY VS_SHADER_TYPE Pixel)
+set_property(SOURCE ${PIXELSHADER_FILES} PROPERTY VS_SHADER_ENTRYPOINT mainPS)
+set_property(SOURCE ${PIXELSHADER_FILES} PROPERTY VS_SHADER_MODEL 4.0_level_9_3)
+set_property(SOURCE ${PIXELSHADER_FILES} PROPERTY VS_SHADER_FLAGS "/DFLAGS_ADDED /Fh \"$(OutDir)%(Filename).h\"")
+
+set_property(SOURCE ${VERTEXSHADER_FILES} PROPERTY VS_SHADER_TYPE Vertex)
+set_property(SOURCE ${VERTEXSHADER_FILES} PROPERTY VS_SHADER_ENTRYPOINT mainVS)
+set_property(SOURCE ${VERTEXSHADER_FILES} PROPERTY VS_SHADER_MODEL 4.0_level_9_3)
+set_property(SOURCE ${VERTEXSHADER_FILES} PROPERTY VS_SHADER_FLAGS "/DFLAGS_ADDED /Fh \"$(OutDir)%(Filename).h\"")
+
+
+source_group("Source Files" FILES ${SOURCE_FILES})
+source_group("Header Files" FILES ${HEADER_FILES})
+source_group("Resource Files" FILES ${RESOURCE_FILES})
+
+add_executable(${EXE_NAME} WIN32 ${SOURCE_FILES} ${HEADER_FILES} ${RESOURCE_FILES})
+set_property(TARGET ${EXE_NAME} PROPERTY VS_WINRT_COMPONENT TRUE)
+
+string(SUBSTRING "${CMAKE_SYSTEM_VERSION}" 0, 4, SHORT_VERSION)
+
+if("${SHORT_VERSION}" STREQUAL "10.0")
+ message(STATUS "Targeting Windows 10. Setting Extensions to version ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}")
+ set_property(TARGET ${EXE_NAME} PROPERTY VS_DESKTOP_EXTENSIONS_VERSION "${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}")
+ set_property(TARGET ${EXE_NAME} PROPERTY VS_MOBILE_EXTENSIONS_VERSION "${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}")
+ set_property(TARGET ${EXE_NAME} PROPERTY VS_IOT_EXTENSIONS_VERSION "${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}")
+endif()
+
+
+target_link_libraries(${EXE_NAME} d3d11)
diff --git a/Tests/VSWinStorePhone/Direct3DApp1/Assets/ApplicationIcon.png b/Tests/VSWinStorePhone/Direct3DApp1/Assets/ApplicationIcon.png
new file mode 100644
index 000000000..7d95d4e08
--- /dev/null
+++ b/Tests/VSWinStorePhone/Direct3DApp1/Assets/ApplicationIcon.png
Binary files differ
diff --git a/Tests/VSWinStorePhone/Direct3DApp1/Assets/Logo.png b/Tests/VSWinStorePhone/Direct3DApp1/Assets/Logo.png
new file mode 100644
index 000000000..e26771cb3
--- /dev/null
+++ b/Tests/VSWinStorePhone/Direct3DApp1/Assets/Logo.png
Binary files differ
diff --git a/Tests/VSWinStorePhone/Direct3DApp1/Assets/SmallLogo.png b/Tests/VSWinStorePhone/Direct3DApp1/Assets/SmallLogo.png
new file mode 100644
index 000000000..1eb0d9d52
--- /dev/null
+++ b/Tests/VSWinStorePhone/Direct3DApp1/Assets/SmallLogo.png
Binary files differ
diff --git a/Tests/VSWinStorePhone/Direct3DApp1/Assets/SmallLogo44x44.png b/Tests/VSWinStorePhone/Direct3DApp1/Assets/SmallLogo44x44.png
new file mode 100644
index 000000000..28810b7c0
--- /dev/null
+++ b/Tests/VSWinStorePhone/Direct3DApp1/Assets/SmallLogo44x44.png
Binary files differ
diff --git a/Tests/VSWinStorePhone/Direct3DApp1/Assets/SplashScreen.png b/Tests/VSWinStorePhone/Direct3DApp1/Assets/SplashScreen.png
new file mode 100644
index 000000000..c951e031b
--- /dev/null
+++ b/Tests/VSWinStorePhone/Direct3DApp1/Assets/SplashScreen.png
Binary files differ
diff --git a/Tests/VSWinStorePhone/Direct3DApp1/Assets/StoreLogo.png b/Tests/VSWinStorePhone/Direct3DApp1/Assets/StoreLogo.png
new file mode 100644
index 000000000..dcb672712
--- /dev/null
+++ b/Tests/VSWinStorePhone/Direct3DApp1/Assets/StoreLogo.png
Binary files differ
diff --git a/Tests/VSWinStorePhone/Direct3DApp1/Assets/Tiles/FlipCycleTileLarge.png b/Tests/VSWinStorePhone/Direct3DApp1/Assets/Tiles/FlipCycleTileLarge.png
new file mode 100644
index 000000000..e0c59ac01
--- /dev/null
+++ b/Tests/VSWinStorePhone/Direct3DApp1/Assets/Tiles/FlipCycleTileLarge.png
Binary files differ
diff --git a/Tests/VSWinStorePhone/Direct3DApp1/Assets/Tiles/FlipCycleTileMedium.png b/Tests/VSWinStorePhone/Direct3DApp1/Assets/Tiles/FlipCycleTileMedium.png
new file mode 100644
index 000000000..e93b89d60
--- /dev/null
+++ b/Tests/VSWinStorePhone/Direct3DApp1/Assets/Tiles/FlipCycleTileMedium.png
Binary files differ
diff --git a/Tests/VSWinStorePhone/Direct3DApp1/Assets/Tiles/FlipCycleTileSmall.png b/Tests/VSWinStorePhone/Direct3DApp1/Assets/Tiles/FlipCycleTileSmall.png
new file mode 100644
index 000000000..550b1b5e8
--- /dev/null
+++ b/Tests/VSWinStorePhone/Direct3DApp1/Assets/Tiles/FlipCycleTileSmall.png
Binary files differ
diff --git a/Tests/VSWinStorePhone/Direct3DApp1/Assets/Tiles/IconicTileMediumLarge.png b/Tests/VSWinStorePhone/Direct3DApp1/Assets/Tiles/IconicTileMediumLarge.png
new file mode 100644
index 000000000..686e6b53f
--- /dev/null
+++ b/Tests/VSWinStorePhone/Direct3DApp1/Assets/Tiles/IconicTileMediumLarge.png
Binary files differ
diff --git a/Tests/VSWinStorePhone/Direct3DApp1/Assets/Tiles/IconicTileSmall.png b/Tests/VSWinStorePhone/Direct3DApp1/Assets/Tiles/IconicTileSmall.png
new file mode 100644
index 000000000..d4b5ede1b
--- /dev/null
+++ b/Tests/VSWinStorePhone/Direct3DApp1/Assets/Tiles/IconicTileSmall.png
Binary files differ
diff --git a/Tests/VSWinStorePhone/Direct3DApp1/BasicTimer.h b/Tests/VSWinStorePhone/Direct3DApp1/BasicTimer.h
new file mode 100644
index 000000000..b58c77d38
--- /dev/null
+++ b/Tests/VSWinStorePhone/Direct3DApp1/BasicTimer.h
@@ -0,0 +1,76 @@
+#pragma once
+
+#include <wrl.h>
+
+// Helper class for basic timing.
+ref class BasicTimer sealed
+{
+public:
+ // Initializes internal timer values.
+ BasicTimer()
+ {
+ if (!QueryPerformanceFrequency(&m_frequency))
+ {
+ throw ref new Platform::FailureException();
+ }
+ Reset();
+ }
+
+ // Reset the timer to initial values.
+ void Reset()
+ {
+ Update();
+ m_startTime = m_currentTime;
+ m_total = 0.0f;
+ m_delta = 1.0f / 60.0f;
+ }
+
+ // Update the timer's internal values.
+ void Update()
+ {
+ if (!QueryPerformanceCounter(&m_currentTime))
+ {
+ throw ref new Platform::FailureException();
+ }
+
+ m_total = static_cast<float>(
+ static_cast<double>(m_currentTime.QuadPart - m_startTime.QuadPart) /
+ static_cast<double>(m_frequency.QuadPart)
+ );
+
+ if (m_lastTime.QuadPart == m_startTime.QuadPart)
+ {
+ // If the timer was just reset, report a time delta equivalent to 60Hz frame time.
+ m_delta = 1.0f / 60.0f;
+ }
+ else
+ {
+ m_delta = static_cast<float>(
+ static_cast<double>(m_currentTime.QuadPart - m_lastTime.QuadPart) /
+ static_cast<double>(m_frequency.QuadPart)
+ );
+ }
+
+ m_lastTime = m_currentTime;
+ }
+
+ // Duration in seconds between the last call to Reset() and the last call to Update().
+ property float Total
+ {
+ float get() { return m_total; }
+ }
+
+ // Duration in seconds between the previous two calls to Update().
+ property float Delta
+ {
+ float get() { return m_delta; }
+ }
+
+private:
+ LARGE_INTEGER m_frequency;
+ LARGE_INTEGER m_currentTime;
+ LARGE_INTEGER m_startTime;
+ LARGE_INTEGER m_lastTime;
+ float m_total;
+ float m_delta;
+};
diff --git a/Tests/VSWinStorePhone/Direct3DApp1/CubeRenderer.cpp b/Tests/VSWinStorePhone/Direct3DApp1/CubeRenderer.cpp
new file mode 100644
index 000000000..f4827f2d6
--- /dev/null
+++ b/Tests/VSWinStorePhone/Direct3DApp1/CubeRenderer.cpp
@@ -0,0 +1,260 @@
+#include "pch.h"
+#include "CubeRenderer.h"
+
+using namespace DirectX;
+using namespace Microsoft::WRL;
+using namespace Windows::Foundation;
+using namespace Windows::UI::Core;
+
+CubeRenderer::CubeRenderer() :
+ m_loadingComplete(false),
+ m_indexCount(0)
+{
+}
+
+void CubeRenderer::CreateDeviceResources()
+{
+ Direct3DBase::CreateDeviceResources();
+
+ auto loadVSTask = DX::ReadDataAsync("SimpleVertexShader.cso");
+ auto loadPSTask = DX::ReadDataAsync("SimplePixelShader.cso");
+
+ auto createVSTask = loadVSTask.then([this](Platform::Array<byte>^ fileData) {
+ DX::ThrowIfFailed(
+ m_d3dDevice->CreateVertexShader(
+ fileData->Data,
+ fileData->Length,
+ nullptr,
+ &m_vertexShader
+ )
+ );
+
+ const D3D11_INPUT_ELEMENT_DESC vertexDesc[] =
+ {
+ { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ { "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ };
+
+ DX::ThrowIfFailed(
+ m_d3dDevice->CreateInputLayout(
+ vertexDesc,
+ ARRAYSIZE(vertexDesc),
+ fileData->Data,
+ fileData->Length,
+ &m_inputLayout
+ )
+ );
+ });
+
+ auto createPSTask = loadPSTask.then([this](Platform::Array<byte>^ fileData) {
+ DX::ThrowIfFailed(
+ m_d3dDevice->CreatePixelShader(
+ fileData->Data,
+ fileData->Length,
+ nullptr,
+ &m_pixelShader
+ )
+ );
+
+ CD3D11_BUFFER_DESC constantBufferDesc(sizeof(ModelViewProjectionConstantBuffer), D3D11_BIND_CONSTANT_BUFFER);
+ DX::ThrowIfFailed(
+ m_d3dDevice->CreateBuffer(
+ &constantBufferDesc,
+ nullptr,
+ &m_constantBuffer
+ )
+ );
+ });
+
+ auto createCubeTask = (createPSTask && createVSTask).then([this] () {
+ VertexPositionColor cubeVertices[] =
+ {
+ {XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT3(0.0f, 0.0f, 0.0f)},
+ {XMFLOAT3(-0.5f, -0.5f, 0.5f), XMFLOAT3(0.0f, 0.0f, 1.0f)},
+ {XMFLOAT3(-0.5f, 0.5f, -0.5f), XMFLOAT3(0.0f, 1.0f, 0.0f)},
+ {XMFLOAT3(-0.5f, 0.5f, 0.5f), XMFLOAT3(0.0f, 1.0f, 1.0f)},
+ {XMFLOAT3( 0.5f, -0.5f, -0.5f), XMFLOAT3(1.0f, 0.0f, 0.0f)},
+ {XMFLOAT3( 0.5f, -0.5f, 0.5f), XMFLOAT3(1.0f, 0.0f, 1.0f)},
+ {XMFLOAT3( 0.5f, 0.5f, -0.5f), XMFLOAT3(1.0f, 1.0f, 0.0f)},
+ {XMFLOAT3( 0.5f, 0.5f, 0.5f), XMFLOAT3(1.0f, 1.0f, 1.0f)},
+ };
+
+ D3D11_SUBRESOURCE_DATA vertexBufferData = {0};
+ vertexBufferData.pSysMem = cubeVertices;
+ vertexBufferData.SysMemPitch = 0;
+ vertexBufferData.SysMemSlicePitch = 0;
+ CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(cubeVertices), D3D11_BIND_VERTEX_BUFFER);
+ DX::ThrowIfFailed(
+ m_d3dDevice->CreateBuffer(
+ &vertexBufferDesc,
+ &vertexBufferData,
+ &m_vertexBuffer
+ )
+ );
+
+ unsigned short cubeIndices[] =
+ {
+ 0,2,1, // -x
+ 1,2,3,
+
+ 4,5,6, // +x
+ 5,7,6,
+
+ 0,1,5, // -y
+ 0,5,4,
+
+ 2,6,7, // +y
+ 2,7,3,
+
+ 0,4,6, // -z
+ 0,6,2,
+
+ 1,3,7, // +z
+ 1,7,5,
+ };
+
+ m_indexCount = ARRAYSIZE(cubeIndices);
+
+ D3D11_SUBRESOURCE_DATA indexBufferData = {0};
+ indexBufferData.pSysMem = cubeIndices;
+ indexBufferData.SysMemPitch = 0;
+ indexBufferData.SysMemSlicePitch = 0;
+ CD3D11_BUFFER_DESC indexBufferDesc(sizeof(cubeIndices), D3D11_BIND_INDEX_BUFFER);
+ DX::ThrowIfFailed(
+ m_d3dDevice->CreateBuffer(
+ &indexBufferDesc,
+ &indexBufferData,
+ &m_indexBuffer
+ )
+ );
+ });
+
+ createCubeTask.then([this] () {
+ m_loadingComplete = true;
+ });
+}
+
+void CubeRenderer::CreateWindowSizeDependentResources()
+{
+ Direct3DBase::CreateWindowSizeDependentResources();
+
+ float aspectRatio = m_windowBounds.Width / m_windowBounds.Height;
+ float fovAngleY = 70.0f * XM_PI / 180.0f;
+ if (aspectRatio < 1.0f)
+ {
+ fovAngleY /= aspectRatio;
+ }
+
+ // Note that the m_orientationTransform3D matrix is post-multiplied here
+ // in order to correctly orient the scene to match the display orientation.
+ // This post-multiplication step is required for any draw calls that are
+ // made to the swap chain render target. For draw calls to other targets,
+ // this transform should not be applied.
+ XMStoreFloat4x4(
+ &m_constantBufferData.projection,
+ XMMatrixTranspose(
+ XMMatrixMultiply(
+ XMMatrixPerspectiveFovRH(
+ fovAngleY,
+ aspectRatio,
+ 0.01f,
+ 100.0f
+ ),
+ XMLoadFloat4x4(&m_orientationTransform3D)
+ )
+ )
+ );
+}
+
+void CubeRenderer::Update(float timeTotal, float timeDelta)
+{
+ (void) timeDelta; // Unused parameter.
+
+ XMVECTOR eye = XMVectorSet(0.0f, 0.7f, 1.5f, 0.0f);
+ XMVECTOR at = XMVectorSet(0.0f, -0.1f, 0.0f, 0.0f);
+ XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
+
+ XMStoreFloat4x4(&m_constantBufferData.view, XMMatrixTranspose(XMMatrixLookAtRH(eye, at, up)));
+ XMStoreFloat4x4(&m_constantBufferData.model, XMMatrixTranspose(XMMatrixRotationY(timeTotal * XM_PIDIV4)));
+}
+
+void CubeRenderer::Render()
+{
+ const float midnightBlue[] = { 0.098f, 0.098f, 0.439f, 1.000f };
+ m_d3dContext->ClearRenderTargetView(
+ m_renderTargetView.Get(),
+ midnightBlue
+ );
+
+ m_d3dContext->ClearDepthStencilView(
+ m_depthStencilView.Get(),
+ D3D11_CLEAR_DEPTH,
+ 1.0f,
+ 0
+ );
+
+ // Only draw the cube once it is loaded (loading is asynchronous).
+ if (!m_loadingComplete)
+ {
+ return;
+ }
+
+ m_d3dContext->OMSetRenderTargets(
+ 1,
+ m_renderTargetView.GetAddressOf(),
+ m_depthStencilView.Get()
+ );
+
+ m_d3dContext->UpdateSubresource(
+ m_constantBuffer.Get(),
+ 0,
+ NULL,
+ &m_constantBufferData,
+ 0,
+ 0
+ );
+
+ UINT stride = sizeof(VertexPositionColor);
+ UINT offset = 0;
+ m_d3dContext->IASetVertexBuffers(
+ 0,
+ 1,
+ m_vertexBuffer.GetAddressOf(),
+ &stride,
+ &offset
+ );
+
+ m_d3dContext->IASetIndexBuffer(
+ m_indexBuffer.Get(),
+ DXGI_FORMAT_R16_UINT,
+ 0
+ );
+
+ m_d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+
+ m_d3dContext->IASetInputLayout(m_inputLayout.Get());
+
+ m_d3dContext->VSSetShader(
+ m_vertexShader.Get(),
+ nullptr,
+ 0
+ );
+
+ m_d3dContext->VSSetConstantBuffers(
+ 0,
+ 1,
+ m_constantBuffer.GetAddressOf()
+ );
+
+ m_d3dContext->PSSetShader(
+ m_pixelShader.Get(),
+ nullptr,
+ 0
+ );
+
+ m_d3dContext->DrawIndexed(
+ m_indexCount,
+ 0,
+ 0
+ );
+}
diff --git a/Tests/VSWinStorePhone/Direct3DApp1/CubeRenderer.h b/Tests/VSWinStorePhone/Direct3DApp1/CubeRenderer.h
new file mode 100644
index 000000000..68cb188d1
--- /dev/null
+++ b/Tests/VSWinStorePhone/Direct3DApp1/CubeRenderer.h
@@ -0,0 +1,44 @@
+#pragma once
+
+#include "Direct3DBase.h"
+
+struct ModelViewProjectionConstantBuffer
+{
+ DirectX::XMFLOAT4X4 model;
+ DirectX::XMFLOAT4X4 view;
+ DirectX::XMFLOAT4X4 projection;
+};
+
+struct VertexPositionColor
+{
+ DirectX::XMFLOAT3 pos;
+ DirectX::XMFLOAT3 color;
+};
+
+// This class renders a simple spinning cube.
+ref class CubeRenderer sealed : public Direct3DBase
+{
+public:
+ CubeRenderer();
+
+ // Direct3DBase methods.
+ virtual void CreateDeviceResources() override;
+ virtual void CreateWindowSizeDependentResources() override;
+ virtual void Render() override;
+
+ // Method for updating time-dependent objects.
+ void Update(float timeTotal, float timeDelta);
+
+private:
+ bool m_loadingComplete;
+
+ Microsoft::WRL::ComPtr<ID3D11InputLayout> m_inputLayout;
+ Microsoft::WRL::ComPtr<ID3D11Buffer> m_vertexBuffer;
+ Microsoft::WRL::ComPtr<ID3D11Buffer> m_indexBuffer;
+ Microsoft::WRL::ComPtr<ID3D11VertexShader> m_vertexShader;
+ Microsoft::WRL::ComPtr<ID3D11PixelShader> m_pixelShader;
+ Microsoft::WRL::ComPtr<ID3D11Buffer> m_constantBuffer;
+
+ uint32 m_indexCount;
+ ModelViewProjectionConstantBuffer m_constantBufferData;
+};
diff --git a/Tests/VSWinStorePhone/Direct3DApp1/Direct3DApp1.cpp b/Tests/VSWinStorePhone/Direct3DApp1/Direct3DApp1.cpp
new file mode 100644
index 000000000..3dbb97f10
--- /dev/null
+++ b/Tests/VSWinStorePhone/Direct3DApp1/Direct3DApp1.cpp
@@ -0,0 +1,153 @@
+#include "pch.h"
+#include "Direct3DApp1.h"
+#include "BasicTimer.h"
+
+using namespace Windows::ApplicationModel;
+using namespace Windows::ApplicationModel::Core;
+using namespace Windows::ApplicationModel::Activation;
+using namespace Windows::UI::Core;
+using namespace Windows::System;
+using namespace Windows::Foundation;
+using namespace Windows::Graphics::Display;
+using namespace concurrency;
+
+Direct3DApp1::Direct3DApp1() :
+ m_windowClosed(false),
+ m_windowVisible(true)
+{
+}
+
+void Direct3DApp1::Initialize(CoreApplicationView^ applicationView)
+{
+ applicationView->Activated +=
+ ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &Direct3DApp1::OnActivated);
+
+ CoreApplication::Suspending +=
+ ref new EventHandler<SuspendingEventArgs^>(this, &Direct3DApp1::OnSuspending);
+
+ CoreApplication::Resuming +=
+ ref new EventHandler<Platform::Object^>(this, &Direct3DApp1::OnResuming);
+
+ m_renderer = ref new CubeRenderer();
+}
+
+void Direct3DApp1::SetWindow(CoreWindow^ window)
+{
+ window->SizeChanged +=
+ ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(this, &Direct3DApp1::OnWindowSizeChanged);
+
+ window->VisibilityChanged +=
+ ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &Direct3DApp1::OnVisibilityChanged);
+
+ window->Closed +=
+ ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &Direct3DApp1::OnWindowClosed);
+
+#ifndef PHONE
+ window->PointerCursor = ref new CoreCursor(CoreCursorType::Arrow, 0);
+#endif
+
+ window->PointerPressed +=
+ ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &Direct3DApp1::OnPointerPressed);
+
+ window->PointerMoved +=
+ ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &Direct3DApp1::OnPointerMoved);
+
+ m_renderer->Initialize(CoreWindow::GetForCurrentThread());
+}
+
+void Direct3DApp1::Load(Platform::String^ entryPoint)
+{
+}
+
+void Direct3DApp1::Run()
+{
+ BasicTimer^ timer = ref new BasicTimer();
+
+ while (!m_windowClosed)
+ {
+ if (m_windowVisible)
+ {
+ timer->Update();
+ CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
+ m_renderer->Update(timer->Total, timer->Delta);
+ m_renderer->Render();
+ m_renderer->Present(); // This call is synchronized to the display frame rate.
+ }
+ else
+ {
+ CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
+ }
+ }
+}
+
+void Direct3DApp1::Uninitialize()
+{
+}
+
+void Direct3DApp1::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args)
+{
+ m_renderer->UpdateForWindowSizeChange();
+}
+
+void Direct3DApp1::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
+{
+ m_windowVisible = args->Visible;
+}
+
+void Direct3DApp1::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args)
+{
+ m_windowClosed = true;
+}
+
+void Direct3DApp1::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args)
+{
+ // Insert your code here.
+}
+
+void Direct3DApp1::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args)
+{
+ // Insert your code here.
+}
+
+void Direct3DApp1::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args)
+{
+ CoreWindow::GetForCurrentThread()->Activate();
+}
+
+void Direct3DApp1::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args)
+{
+ // Save app state asynchronously after requesting a deferral. Holding a deferral
+ // indicates that the application is busy performing suspending operations. Be
+ // aware that a deferral may not be held indefinitely. After about five seconds,
+ // the app will be forced to exit.
+ SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral();
+ m_renderer->ReleaseResourcesForSuspending();
+
+ create_task([this, deferral]()
+ {
+ // Insert your code here.
+
+ deferral->Complete();
+ });
+}
+
+void Direct3DApp1::OnResuming(Platform::Object^ sender, Platform::Object^ args)
+{
+ // Restore any data or state that was unloaded on suspend. By default, data
+ // and state are persisted when resuming from suspend. Note that this event
+ // does not occur if the app was previously terminated.
+ m_renderer->CreateWindowSizeDependentResources();
+}
+
+IFrameworkView^ Direct3DApplicationSource::CreateView()
+{
+ return ref new Direct3DApp1();
+}
+
+[Platform::MTAThread]
+int main(Platform::Array<Platform::String^>^)
+{
+ auto direct3DApplicationSource = ref new Direct3DApplicationSource();
+ CoreApplication::Run(direct3DApplicationSource);
+ return 0;
+}
diff --git a/Tests/VSWinStorePhone/Direct3DApp1/Direct3DApp1.h b/Tests/VSWinStorePhone/Direct3DApp1/Direct3DApp1.h
new file mode 100644
index 000000000..40b69a173
--- /dev/null
+++ b/Tests/VSWinStorePhone/Direct3DApp1/Direct3DApp1.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#include "pch.h"
+#include "CubeRenderer.h"
+
+ref class Direct3DApp1 sealed : public Windows::ApplicationModel::Core::IFrameworkView
+{
+public:
+ Direct3DApp1();
+
+ // IFrameworkView Methods.
+ virtual void Initialize(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView);
+ virtual void SetWindow(Windows::UI::Core::CoreWindow^ window);
+ virtual void Load(Platform::String^ entryPoint);
+ virtual void Run();
+ virtual void Uninitialize();
+
+protected:
+ // Event Handlers.
+ void OnWindowSizeChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ args);
+ void OnLogicalDpiChanged(Platform::Object^ sender);
+ void OnActivated(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView, Windows::ApplicationModel::Activation::IActivatedEventArgs^ args);
+ void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ args);
+ void OnResuming(Platform::Object^ sender, Platform::Object^ args);
+ void OnWindowClosed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CoreWindowEventArgs^ args);
+ void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args);
+ void OnPointerPressed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
+ void OnPointerMoved(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
+
+private:
+ CubeRenderer^ m_renderer;
+ bool m_windowClosed;
+ bool m_windowVisible;
+};
+
+ref class Direct3DApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource
+{
+public:
+ virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView();
+};
diff --git a/Tests/VSWinStorePhone/Direct3DApp1/Direct3DApp1_TemporaryKey.pfx b/Tests/VSWinStorePhone/Direct3DApp1/Direct3DApp1_TemporaryKey.pfx
new file mode 100644
index 000000000..1cad9993d
--- /dev/null
+++ b/Tests/VSWinStorePhone/Direct3DApp1/Direct3DApp1_TemporaryKey.pfx
Binary files differ
diff --git a/Tests/VSWinStorePhone/Direct3DApp1/Direct3DBase.cpp b/Tests/VSWinStorePhone/Direct3DApp1/Direct3DBase.cpp
new file mode 100644
index 000000000..46727b5ff
--- /dev/null
+++ b/Tests/VSWinStorePhone/Direct3DApp1/Direct3DBase.cpp
@@ -0,0 +1,384 @@
+#include "pch.h"
+#include "Direct3DBase.h"
+
+using namespace DirectX;
+using namespace Microsoft::WRL;
+using namespace Windows::UI::Core;
+using namespace Windows::Foundation;
+using namespace Windows::Graphics::Display;
+
+// Constructor.
+Direct3DBase::Direct3DBase()
+{
+}
+
+// Initialize the Direct3D resources required to run.
+void Direct3DBase::Initialize(CoreWindow^ window)
+{
+ m_window = window;
+
+ CreateDeviceResources();
+ CreateWindowSizeDependentResources();
+}
+
+// Recreate all device resources and set them back to the current state.
+void Direct3DBase::HandleDeviceLost()
+{
+ // Reset these member variables to ensure that UpdateForWindowSizeChange recreates all resources.
+ m_windowBounds.Width = 0;
+ m_windowBounds.Height = 0;
+ m_swapChain = nullptr;
+
+ CreateDeviceResources();
+ UpdateForWindowSizeChange();
+}
+
+// These are the resources that depend on the device.
+void Direct3DBase::CreateDeviceResources()
+{
+ // This flag adds support for surfaces with a different color channel ordering
+ // than the API default. It is required for compatibility with Direct2D.
+ UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
+
+#if defined(_DEBUG)
+ // If the project is in a debug build, enable debugging via SDK Layers with this flag.
+ creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
+#endif
+
+ // This array defines the set of DirectX hardware feature levels this app will support.
+ // Note the ordering should be preserved.
+ // Don't forget to declare your application's minimum required feature level in its
+ // description. All applications are assumed to support 9.1 unless otherwise stated.
+ D3D_FEATURE_LEVEL featureLevels[] =
+ {
+ D3D_FEATURE_LEVEL_11_1,
+ D3D_FEATURE_LEVEL_11_0,
+ D3D_FEATURE_LEVEL_10_1,
+ D3D_FEATURE_LEVEL_10_0,
+ D3D_FEATURE_LEVEL_9_3,
+ D3D_FEATURE_LEVEL_9_2,
+ D3D_FEATURE_LEVEL_9_1
+ };
+
+ // Create the Direct3D 11 API device object and a corresponding context.
+ ComPtr<ID3D11Device> device;
+ ComPtr<ID3D11DeviceContext> context;
+ DX::ThrowIfFailed(
+ D3D11CreateDevice(
+ nullptr, // Specify nullptr to use the default adapter.
+ D3D_DRIVER_TYPE_HARDWARE,
+ nullptr,
+ creationFlags, // Set set debug and Direct2D compatibility flags.
+ featureLevels, // List of feature levels this app can support.
+ ARRAYSIZE(featureLevels),
+ D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Store apps.
+ &device, // Returns the Direct3D device created.
+ &m_featureLevel, // Returns feature level of device created.
+ &context // Returns the device immediate context.
+ )
+ );
+
+ // Get the Direct3D 11.1 API device and context interfaces.
+ DX::ThrowIfFailed(
+ device.As(&m_d3dDevice)
+ );
+
+ DX::ThrowIfFailed(
+ context.As(&m_d3dContext)
+ );
+}
+
+// Allocate all memory resources that change on a window SizeChanged event.
+void Direct3DBase::CreateWindowSizeDependentResources()
+{
+ // Store the window bounds so the next time we get a SizeChanged event we can
+ // avoid rebuilding everything if the size is identical.
+ m_windowBounds = m_window->Bounds;
+
+ // Calculate the necessary swap chain and render target size in pixels.
+ float windowWidth = ConvertDipsToPixels(m_windowBounds.Width);
+ float windowHeight = ConvertDipsToPixels(m_windowBounds.Height);
+
+ // The width and height of the swap chain must be based on the window's
+ // landscape-oriented width and height. If the window is in a portrait
+ // orientation, the dimensions must be reversed.
+#if WINVER > 0x0602
+ m_orientation = DisplayInformation::GetForCurrentView()->CurrentOrientation;
+#else
+#if PHONE
+ // WP8 doesn't support rotations so always make it landscape
+ m_orientation = DisplayOrientations::Landscape;
+#else
+ m_orientation = DisplayProperties::CurrentOrientation;
+#endif
+#endif
+ bool swapDimensions =
+ m_orientation == DisplayOrientations::Portrait ||
+ m_orientation == DisplayOrientations::PortraitFlipped;
+ m_renderTargetSize.Width = swapDimensions ? windowHeight : windowWidth;
+ m_renderTargetSize.Height = swapDimensions ? windowWidth : windowHeight;
+
+ if(m_swapChain != nullptr)
+ {
+ // If the swap chain already exists, resize it.
+ DX::ThrowIfFailed(
+ m_swapChain->ResizeBuffers(
+ 2, // Double-buffered swap chain.
+ static_cast<UINT>(m_renderTargetSize.Width),
+ static_cast<UINT>(m_renderTargetSize.Height),
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ 0
+ )
+ );
+ }
+ else
+ {
+ // Otherwise, create a new one using the same adapter as the existing Direct3D device.
+ DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
+ swapChainDesc.Width = static_cast<UINT>(m_renderTargetSize.Width); // Match the size of the window.
+ swapChainDesc.Height = static_cast<UINT>(m_renderTargetSize.Height);
+ swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // This is the most common swap chain format.
+ swapChainDesc.Stereo = false;
+ swapChainDesc.SampleDesc.Count = 1; // Don't use multi-sampling.
+ swapChainDesc.SampleDesc.Quality = 0;
+ swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+#if PHONE && WINVER <= 0x0602
+ swapChainDesc.BufferCount = 1; // Use double-buffering to minimize latency.
+ swapChainDesc.Scaling = DXGI_SCALING_STRETCH; // On phone, only stretch and aspect-ratio stretch scaling are allowed.
+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; // On phone, no swap effects are supported.
+#else
+ swapChainDesc.BufferCount = 2; // Use double-buffering to minimize latency.
+ swapChainDesc.Scaling = DXGI_SCALING_NONE;
+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // All Windows Store apps must use this SwapEffect.
+#endif
+ swapChainDesc.Flags = 0;
+
+ ComPtr<IDXGIDevice1> dxgiDevice;
+ DX::ThrowIfFailed(
+ m_d3dDevice.As(&dxgiDevice)
+ );
+
+ ComPtr<IDXGIAdapter> dxgiAdapter;
+ DX::ThrowIfFailed(
+ dxgiDevice->GetAdapter(&dxgiAdapter)
+ );
+
+ ComPtr<IDXGIFactory2> dxgiFactory;
+ DX::ThrowIfFailed(
+ dxgiAdapter->GetParent(
+ __uuidof(IDXGIFactory2),
+ &dxgiFactory
+ )
+ );
+
+ Windows::UI::Core::CoreWindow^ window = m_window.Get();
+ DX::ThrowIfFailed(
+ dxgiFactory->CreateSwapChainForCoreWindow(
+ m_d3dDevice.Get(),
+ reinterpret_cast<IUnknown*>(window),
+ &swapChainDesc,
+ nullptr, // Allow on all displays.
+ &m_swapChain
+ )
+ );
+
+ // Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and
+ // ensures that the application will only render after each VSync, minimizing power consumption.
+ DX::ThrowIfFailed(
+ dxgiDevice->SetMaximumFrameLatency(1)
+ );
+ }
+
+ // Set the proper orientation for the swap chain, and generate the
+ // 3D matrix transformation for rendering to the rotated swap chain.
+ DXGI_MODE_ROTATION rotation = DXGI_MODE_ROTATION_UNSPECIFIED;
+ switch (m_orientation)
+ {
+ case DisplayOrientations::Landscape:
+ rotation = DXGI_MODE_ROTATION_IDENTITY;
+ m_orientationTransform3D = XMFLOAT4X4( // 0-degree Z-rotation
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f
+ );
+ break;
+
+ case DisplayOrientations::Portrait:
+ rotation = DXGI_MODE_ROTATION_ROTATE270;
+ m_orientationTransform3D = XMFLOAT4X4( // 90-degree Z-rotation
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ -1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f
+ );
+ break;
+
+ case DisplayOrientations::LandscapeFlipped:
+ rotation = DXGI_MODE_ROTATION_ROTATE180;
+ m_orientationTransform3D = XMFLOAT4X4( // 180-degree Z-rotation
+ -1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f
+ );
+ break;
+
+ case DisplayOrientations::PortraitFlipped:
+ rotation = DXGI_MODE_ROTATION_ROTATE90;
+ m_orientationTransform3D = XMFLOAT4X4( // 270-degree Z-rotation
+ 0.0f, -1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f
+ );
+ break;
+
+ default:
+ throw ref new Platform::FailureException();
+ }
+
+#if !PHONE || WINVER > 0x0602
+ DX::ThrowIfFailed(
+ m_swapChain->SetRotation(rotation)
+ );
+#endif // !PHONE
+
+ // Create a render target view of the swap chain back buffer.
+ ComPtr<ID3D11Texture2D> backBuffer;
+ DX::ThrowIfFailed(
+ m_swapChain->GetBuffer(
+ 0,
+ __uuidof(ID3D11Texture2D),
+ &backBuffer
+ )
+ );
+
+ DX::ThrowIfFailed(
+ m_d3dDevice->CreateRenderTargetView(
+ backBuffer.Get(),
+ nullptr,
+ &m_renderTargetView
+ )
+ );
+
+ // Create a depth stencil view.
+ CD3D11_TEXTURE2D_DESC depthStencilDesc(
+ DXGI_FORMAT_D24_UNORM_S8_UINT,
+ static_cast<UINT>(m_renderTargetSize.Width),
+ static_cast<UINT>(m_renderTargetSize.Height),
+ 1,
+ 1,
+ D3D11_BIND_DEPTH_STENCIL
+ );
+
+ ComPtr<ID3D11Texture2D> depthStencil;
+ DX::ThrowIfFailed(
+ m_d3dDevice->CreateTexture2D(
+ &depthStencilDesc,
+ nullptr,
+ &depthStencil
+ )
+ );
+
+ CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(D3D11_DSV_DIMENSION_TEXTURE2D);
+ DX::ThrowIfFailed(
+ m_d3dDevice->CreateDepthStencilView(
+ depthStencil.Get(),
+ &depthStencilViewDesc,
+ &m_depthStencilView
+ )
+ );
+
+ // Set the rendering viewport to target the entire window.
+ CD3D11_VIEWPORT viewport(
+ 0.0f,
+ 0.0f,
+ m_renderTargetSize.Width,
+ m_renderTargetSize.Height
+ );
+
+ m_d3dContext->RSSetViewports(1, &viewport);
+}
+
+// This method is called in the event handler for the SizeChanged event.
+void Direct3DBase::UpdateForWindowSizeChange()
+{
+ if (m_window->Bounds.Width != m_windowBounds.Width ||
+ m_window->Bounds.Height != m_windowBounds.Height ||
+#if WINVER > 0x0602
+ m_orientation != DisplayInformation::GetForCurrentView()->CurrentOrientation)
+#else
+ m_orientation != DisplayProperties::CurrentOrientation)
+#endif
+ {
+ ID3D11RenderTargetView* nullViews[] = {nullptr};
+ m_d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr);
+ m_renderTargetView = nullptr;
+ m_depthStencilView = nullptr;
+ m_d3dContext->Flush();
+ CreateWindowSizeDependentResources();
+ }
+}
+
+void Direct3DBase::ReleaseResourcesForSuspending()
+{
+ // Phone applications operate in a memory-constrained environment, so when entering
+ // the background it is a good idea to free memory-intensive objects that will be
+ // easy to restore upon reactivation. The swapchain and backbuffer are good candidates
+ // here, as they consume a large amount of memory and can be reinitialized quickly.
+ m_swapChain = nullptr;
+ m_renderTargetView = nullptr;
+ m_depthStencilView = nullptr;
+}
+
+// Method to deliver the final image to the display.
+void Direct3DBase::Present()
+{
+ // The first argument instructs DXGI to block until VSync, putting the application
+ // to sleep until the next VSync. This ensures we don't waste any cycles rendering
+ // frames that will never be displayed to the screen.
+#if PHONE && WINVER <= 0x0602
+ HRESULT hr = m_swapChain->Present(1, 0);
+#else
+ // The application may optionally specify "dirty" or "scroll"
+ // rects to improve efficiency in certain scenarios.
+ DXGI_PRESENT_PARAMETERS parameters = { 0 };
+ parameters.DirtyRectsCount = 0;
+ parameters.pDirtyRects = nullptr;
+ parameters.pScrollRect = nullptr;
+ parameters.pScrollOffset = nullptr;
+
+ HRESULT hr = m_swapChain->Present1(1, 0 , &parameters);
+#endif
+
+ // Discard the contents of the render target.
+ // This is a valid operation only when the existing contents will be entirely
+ // overwritten. If dirty or scroll rects are used, this call should be removed.
+ m_d3dContext->DiscardView(m_renderTargetView.Get());
+
+ // Discard the contents of the depth stencil.
+ m_d3dContext->DiscardView(m_depthStencilView.Get());
+
+ // If the device was removed either by a disconnect or a driver upgrade, we
+ // must recreate all device resources.
+ if (hr == DXGI_ERROR_DEVICE_REMOVED)
+ {
+ HandleDeviceLost();
+ }
+ else
+ {
+ DX::ThrowIfFailed(hr);
+ }
+}
+
+// Method to convert a length in device-independent pixels (DIPs) to a length in physical pixels.
+float Direct3DBase::ConvertDipsToPixels(float dips)
+{
+ static const float dipsPerInch = 96.0f;
+#if WINVER > 0x0602
+ return floor(dips * DisplayInformation::GetForCurrentView()->LogicalDpi / dipsPerInch + 0.5f); // Round to nearest integer.
+#else
+ return floor(dips * DisplayProperties::LogicalDpi / dipsPerInch + 0.5f); // Round to nearest integer.
+#endif
+}
diff --git a/Tests/VSWinStorePhone/Direct3DApp1/Direct3DBase.h b/Tests/VSWinStorePhone/Direct3DApp1/Direct3DBase.h
new file mode 100644
index 000000000..bba9f1697
--- /dev/null
+++ b/Tests/VSWinStorePhone/Direct3DApp1/Direct3DBase.h
@@ -0,0 +1,39 @@
+#pragma once
+
+#include "DirectXHelper.h"
+
+// Helper class that initializes DirectX APIs for 3D rendering.
+ref class Direct3DBase abstract
+{
+internal:
+ Direct3DBase();
+
+public:
+ virtual void Initialize(Windows::UI::Core::CoreWindow^ window);
+ virtual void HandleDeviceLost();
+ virtual void CreateDeviceResources();
+ virtual void CreateWindowSizeDependentResources();
+ virtual void UpdateForWindowSizeChange();
+ virtual void ReleaseResourcesForSuspending();
+ virtual void Render() = 0;
+ virtual void Present();
+ virtual float ConvertDipsToPixels(float dips);
+
+protected private:
+ // Direct3D Objects.
+ Microsoft::WRL::ComPtr<ID3D11Device1> m_d3dDevice;
+ Microsoft::WRL::ComPtr<ID3D11DeviceContext1> m_d3dContext;
+ Microsoft::WRL::ComPtr<IDXGISwapChain1> m_swapChain;
+ Microsoft::WRL::ComPtr<ID3D11RenderTargetView> m_renderTargetView;
+ Microsoft::WRL::ComPtr<ID3D11DepthStencilView> m_depthStencilView;
+
+ // Cached renderer properties.
+ D3D_FEATURE_LEVEL m_featureLevel;
+ Windows::Foundation::Size m_renderTargetSize;
+ Windows::Foundation::Rect m_windowBounds;
+ Platform::Agile<Windows::UI::Core::CoreWindow> m_window;
+ Windows::Graphics::Display::DisplayOrientations m_orientation;
+
+ // Transform used for display orientation.
+ DirectX::XMFLOAT4X4 m_orientationTransform3D;
+};
diff --git a/Tests/VSWinStorePhone/Direct3DApp1/DirectXHelper.h b/Tests/VSWinStorePhone/Direct3DApp1/DirectXHelper.h
new file mode 100644
index 000000000..d411a9b81
--- /dev/null
+++ b/Tests/VSWinStorePhone/Direct3DApp1/DirectXHelper.h
@@ -0,0 +1,45 @@
+#pragma once
+
+#include <wrl/client.h>
+#include <ppl.h>
+#include <ppltasks.h>
+
+namespace DX
+{
+ inline void ThrowIfFailed(HRESULT hr)
+ {
+ if (FAILED(hr))
+ {
+ // Set a breakpoint on this line to catch Win32 API errors.
+ throw Platform::Exception::CreateException(hr);
+ }
+ }
+
+ // Function that reads from a binary file asynchronously.
+ inline Concurrency::task<Platform::Array<byte>^> ReadDataAsync(Platform::String^ filename)
+ {
+ using namespace Windows::Storage;
+ using namespace Concurrency;
+
+ auto folder = Windows::ApplicationModel::Package::Current->InstalledLocation;
+
+ return create_task(folder->GetFileAsync(filename)).then([] (StorageFile^ file)
+ {
+#if !PHONE
+ return FileIO::ReadBufferAsync(file);
+#else
+ return file->OpenReadAsync();
+ }).then([](Streams::IRandomAccessStreamWithContentType^ stream)
+ {
+ unsigned int bufferSize = static_cast<unsigned int>(stream->Size);
+ auto fileBuffer = ref new Streams::Buffer(bufferSize);
+ return stream->ReadAsync(fileBuffer, bufferSize, Streams::InputStreamOptions::None);
+#endif
+ }).then([] (Streams::IBuffer^ fileBuffer) -> Platform::Array<byte>^
+ {
+ auto fileData = ref new Platform::Array<byte>(fileBuffer->Length);
+ Streams::DataReader::FromBuffer(fileBuffer)->ReadBytes(fileData);
+ return fileData;
+ });
+ }
+}
diff --git a/Tests/VSWinStorePhone/Direct3DApp1/SimplePixelShader.cso b/Tests/VSWinStorePhone/Direct3DApp1/SimplePixelShader.cso
new file mode 100644
index 000000000..56f9c1756
--- /dev/null
+++ b/Tests/VSWinStorePhone/Direct3DApp1/SimplePixelShader.cso
Binary files differ
diff --git a/Tests/VSWinStorePhone/Direct3DApp1/SimplePixelShader.hlsl b/Tests/VSWinStorePhone/Direct3DApp1/SimplePixelShader.hlsl
new file mode 100644
index 000000000..b2fe7bef0
--- /dev/null
+++ b/Tests/VSWinStorePhone/Direct3DApp1/SimplePixelShader.hlsl
@@ -0,0 +1,14 @@
+#if !defined(FLAGS_ADDED)
+# error FLAGS_ADDED not defined
+#endif
+
+struct PixelShaderInput
+{
+ float4 pos : SV_POSITION;
+ float3 color : COLOR0;
+};
+
+float4 mainPS(PixelShaderInput input) : SV_TARGET
+{
+ return float4(input.color,1.0f);
+}
diff --git a/Tests/VSWinStorePhone/Direct3DApp1/SimpleVertexShader.cso b/Tests/VSWinStorePhone/Direct3DApp1/SimpleVertexShader.cso
new file mode 100644
index 000000000..ea8025821
--- /dev/null
+++ b/Tests/VSWinStorePhone/Direct3DApp1/SimpleVertexShader.cso
Binary files differ
diff --git a/Tests/VSWinStorePhone/Direct3DApp1/SimpleVertexShader.hlsl b/Tests/VSWinStorePhone/Direct3DApp1/SimpleVertexShader.hlsl
new file mode 100644
index 000000000..3f9a4ebbb
--- /dev/null
+++ b/Tests/VSWinStorePhone/Direct3DApp1/SimpleVertexShader.hlsl
@@ -0,0 +1,39 @@
+#if !defined(FLAGS_ADDED)
+# error FLAGS_ADDED not defined
+#endif
+
+cbuffer ModelViewProjectionConstantBuffer : register(b0)
+{
+ matrix model;
+ matrix view;
+ matrix projection;
+};
+
+struct VertexShaderInput
+{
+ float3 pos : POSITION;
+ float3 color : COLOR0;
+};
+
+struct VertexShaderOutput
+{
+ float4 pos : SV_POSITION;
+ float3 color : COLOR0;
+};
+
+VertexShaderOutput mainVS(VertexShaderInput input)
+{
+ VertexShaderOutput output;
+ float4 pos = float4(input.pos, 1.0f);
+
+ // Transform the vertex position into projected space.
+ pos = mul(pos, model);
+ pos = mul(pos, view);
+ pos = mul(pos, projection);
+ output.pos = pos;
+
+ // Pass through the color without modification.
+ output.color = input.color;
+
+ return output;
+}
diff --git a/Tests/VSWinStorePhone/Direct3DApp1/pch.cpp b/Tests/VSWinStorePhone/Direct3DApp1/pch.cpp
new file mode 100644
index 000000000..1d9f38c57
--- /dev/null
+++ b/Tests/VSWinStorePhone/Direct3DApp1/pch.cpp
@@ -0,0 +1 @@
+#include "pch.h"
diff --git a/Tests/VSWinStorePhone/Direct3DApp1/pch.h b/Tests/VSWinStorePhone/Direct3DApp1/pch.h
new file mode 100644
index 000000000..2302e66ba
--- /dev/null
+++ b/Tests/VSWinStorePhone/Direct3DApp1/pch.h
@@ -0,0 +1,7 @@
+#pragma once
+
+#include <wrl/client.h>
+#include <d3d11_1.h>
+#include <DirectXMath.h>
+#include <memory>
+#include <agile.h>
diff --git a/Tests/VSWinStorePhone/cmake/Package_vc11.store.appxmanifest.in b/Tests/VSWinStorePhone/cmake/Package_vc11.store.appxmanifest.in
new file mode 100644
index 000000000..68172fa1e
--- /dev/null
+++ b/Tests/VSWinStorePhone/cmake/Package_vc11.store.appxmanifest.in
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest">
+ <Identity Name="@PACKAGE_GUID@" Publisher="CN=mgong" Version="1.0.0.0" />
+ <Properties>
+ <DisplayName>@SHORT_NAME@</DisplayName>
+ <PublisherDisplayName>mgong</PublisherDisplayName>
+ <Logo>Assets/StoreLogo.png</Logo>
+ </Properties>
+ <Prerequisites>
+ <OSMinVersion>6.2.1</OSMinVersion>
+ <OSMaxVersionTested>6.2.1</OSMaxVersionTested>
+ </Prerequisites>
+ <Resources>
+ <Resource Language="x-generate" />
+ </Resources>
+ <Applications>
+ <Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="@SHORT_NAME@.App">
+ <VisualElements DisplayName="@SHORT_NAME@" Description="@SHORT_NAME@" BackgroundColor="#336699" ForegroundText="light" Logo="Assets/Logo.png" SmallLogo="Assets/SmallLogo.png">
+ <DefaultTile ShowName="allLogos" ShortName="@SHORT_NAME@" />
+ <SplashScreen Image="Assets/SplashScreen.png" />
+ </VisualElements>
+ </Application>
+ </Applications>
+</Package>
diff --git a/Tests/VSWinStorePhone/cmake/Package_vc11.wp.appxmanifest.in b/Tests/VSWinStorePhone/cmake/Package_vc11.wp.appxmanifest.in
new file mode 100644
index 000000000..70f3abf79
--- /dev/null
+++ b/Tests/VSWinStorePhone/cmake/Package_vc11.wp.appxmanifest.in
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Deployment xmlns="http://schemas.microsoft.com/windowsphone/2012/deployment" AppPlatformVersion="8.0">
+ <DefaultLanguage xmlns="" code="en-US"/>
+ <App xmlns="" ProductID="{@PACKAGE_GUID@}" Title="@SHORT_NAME@" RuntimeType="Modern Native" Version="1.0.0.0" Genre="apps.normal" Author="mgong" Description="Simple Direct3D application" Publisher="@SHORT_NAME@" PublisherID="{c618991e-1d39-41c2-a881-d3310705a091}">
+ <IconPath IsRelative="true" IsResource="false">ApplicationIcon.png</IconPath>
+ <Capabilities>
+ <Capability Name="ID_CAP_NETWORKING" />
+ <Capability Name="ID_CAP_MEDIALIB_AUDIO" />
+ <Capability Name="ID_CAP_MEDIALIB_PLAYBACK" />
+ </Capabilities>
+ <Tasks>
+ <DefaultTask Name="_default" ImagePath="@SHORT_NAME@.exe" ImageParams="" />
+ </Tasks>
+ <Tokens>
+ <PrimaryToken TokenID="@SHORT_NAME@Token" TaskName="_default">
+ <TemplateFlip>
+ <SmallImageURI IsRelative="true" IsResource="false">FlipCycleTileSmall.png</SmallImageURI>
+ <Count>0</Count>
+ <BackgroundImageURI IsRelative="true" IsResource="false">FlipCycleTileMedium.png</BackgroundImageURI>
+ <Title>@SHORT_NAME@</Title>
+ <BackContent></BackContent>
+ <BackBackgroundImageURI></BackBackgroundImageURI>
+ <BackTitle></BackTitle>
+ <DeviceLockImageURI></DeviceLockImageURI>
+ <HasLarge></HasLarge>
+ </TemplateFlip>
+ </PrimaryToken>
+ </Tokens>
+ <ScreenResolutions>
+ <ScreenResolution Name="ID_RESOLUTION_WVGA" />
+ <ScreenResolution Name="ID_RESOLUTION_WXGA" />
+ <ScreenResolution Name="ID_RESOLUTION_HD720P" />
+ </ScreenResolutions>
+ </App>
+</Deployment>
diff --git a/Tests/VSWinStorePhone/cmake/Package_vc12.store.appxmanifest.in b/Tests/VSWinStorePhone/cmake/Package_vc12.store.appxmanifest.in
new file mode 100644
index 000000000..08205f5bb
--- /dev/null
+++ b/Tests/VSWinStorePhone/cmake/Package_vc12.store.appxmanifest.in
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest">
+ <Identity Name="@PACKAGE_GUID@" Publisher="CN=mgong" Version="1.1.0.0" />
+ <Properties>
+ <DisplayName>@SHORT_NAME@</DisplayName>
+ <PublisherDisplayName>mgong</PublisherDisplayName>
+ <Logo>Assets/StoreLogo.png</Logo>
+ </Properties>
+ <Prerequisites>
+ <OSMinVersion>6.3</OSMinVersion>
+ <OSMaxVersionTested>6.3</OSMaxVersionTested>
+ </Prerequisites>
+ <Resources>
+ <Resource Language="x-generate" />
+ </Resources>
+ <Applications>
+ <Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="@SHORT_NAME@.App">
+ <m2:VisualElements
+ DisplayName="@SHORT_NAME@"
+ Description="@SHORT_NAME@"
+ BackgroundColor="#336699"
+ ForegroundText="light"
+ Square150x150Logo="Assets/Logo.png"
+ Square30x30Logo="Assets/SmallLogo.png">
+ <m2:DefaultTile ShortName="@SHORT_NAME@">
+ <m2:ShowNameOnTiles>
+ <m2:ShowOn Tile="square150x150Logo" />
+ </m2:ShowNameOnTiles>
+ </m2:DefaultTile>
+ <m2:SplashScreen Image="Assets/SplashScreen.png" />
+ </m2:VisualElements>
+ </Application>
+ </Applications>
+</Package>
diff --git a/Tests/VSWinStorePhone/cmake/Package_vc12.wp.appxmanifest.in b/Tests/VSWinStorePhone/cmake/Package_vc12.wp.appxmanifest.in
new file mode 100644
index 000000000..d47d43c9f
--- /dev/null
+++ b/Tests/VSWinStorePhone/cmake/Package_vc12.wp.appxmanifest.in
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest">
+ <Identity Name="@PACKAGE_GUID@" Publisher="CN=mgong" Version="1.1.0.0" />
+ <mp:PhoneIdentity PhoneProductId="@PACKAGE_GUID@" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
+
+ <Properties>
+ <DisplayName>@SHORT_NAME@</DisplayName>
+ <PublisherDisplayName>mgong</PublisherDisplayName>
+ <Logo>Assets/StoreLogo.png</Logo>
+ </Properties>
+ <Prerequisites>
+ <OSMinVersion>6.3.1</OSMinVersion>
+ <OSMaxVersionTested>6.3.1</OSMaxVersionTested>
+ </Prerequisites>
+ <Resources>
+ <Resource Language="x-generate" />
+ </Resources>
+ <Applications>
+ <Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="@SHORT_NAME@.App">
+ <m2:VisualElements
+ DisplayName="@SHORT_NAME@"
+ Description="@SHORT_NAME@"
+ BackgroundColor="#336699"
+ ForegroundText="light"
+ Square150x150Logo="Assets/Logo.png"
+ Square30x30Logo="Assets/SmallLogo.png">
+ <m2:DefaultTile ShortName="@SHORT_NAME@">
+ <m2:ShowNameOnTiles>
+ <m2:ShowOn Tile="square150x150Logo" />
+ </m2:ShowNameOnTiles>
+ </m2:DefaultTile>
+ <m2:SplashScreen Image="Assets/SplashScreen.png" />
+ </m2:VisualElements>
+ </Application>
+ </Applications>
+</Package>
diff --git a/Tests/VSWinStorePhone/cmake/Package_vc14.store.appxmanifest.in b/Tests/VSWinStorePhone/cmake/Package_vc14.store.appxmanifest.in
new file mode 100644
index 000000000..6b27ab71b
--- /dev/null
+++ b/Tests/VSWinStorePhone/cmake/Package_vc14.store.appxmanifest.in
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Package
+ xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
+ xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
+ xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
+ IgnorableNamespaces="uap mp">
+
+ <Identity Name="@PACKAGE_GUID@" Publisher="CN=mgong" Version="1.1.0.0" />
+ <mp:PhoneIdentity PhoneProductId="@PACKAGE_GUID@" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
+
+ <Properties>
+ <DisplayName>@SHORT_NAME@</DisplayName>
+ <PublisherDisplayName>mgong</PublisherDisplayName>
+ <Logo>Assets/StoreLogo.png</Logo>
+ </Properties>
+
+ <Dependencies>
+ <TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.65535.65535" />
+ </Dependencies>
+
+ <Resources>
+ <Resource Language="x-generate" />
+ </Resources>
+ <Applications>
+ <Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="@SHORT_NAME@.App">
+ <uap:VisualElements
+ DisplayName="@SHORT_NAME@"
+ Description="@SHORT_NAME@"
+ BackgroundColor="#336699"
+ Square150x150Logo="Assets/Logo.png"
+ Square44x44Logo="Assets/SmallLogo44x44.png">
+ <uap:SplashScreen Image="Assets/SplashScreen.png" />
+ </uap:VisualElements>
+ </Application>
+ </Applications>
+</Package>
diff --git a/Tests/VSWindowsFormsResx/CMakeLists.txt b/Tests/VSWindowsFormsResx/CMakeLists.txt
index 437381085..43c483383 100644
--- a/Tests/VSWindowsFormsResx/CMakeLists.txt
+++ b/Tests/VSWindowsFormsResx/CMakeLists.txt
@@ -14,7 +14,7 @@ include(CheckCXXSourceCompiles)
include(CheckIncludeFile)
# Note: The designable form is assumed to have a .h extension as is default in Visual Studio.
-# Node: The designable form is assumed to have a .resx file with the same name and path (save extension) as is default in Visual Studio
+# Note: The designable form is assumed to have a .resx file with the same name and path (save extension) as is default in Visual Studio
set(TARGET_H
WindowsFormsResx/MyForm.h
diff --git a/Tests/VSXaml/App.xaml b/Tests/VSXaml/App.xaml
new file mode 100644
index 000000000..eecf2c192
--- /dev/null
+++ b/Tests/VSXaml/App.xaml
@@ -0,0 +1,7 @@
+<Application
+ x:Class="VSXaml.App"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:local="using:VSXaml">
+
+</Application>
diff --git a/Tests/VSXaml/App.xaml.cpp b/Tests/VSXaml/App.xaml.cpp
new file mode 100644
index 000000000..334dc1f9c
--- /dev/null
+++ b/Tests/VSXaml/App.xaml.cpp
@@ -0,0 +1,125 @@
+//
+// App.xaml.cpp
+// Implementation of the App class.
+//
+
+#include "pch.h"
+#include "MainPage.xaml.h"
+
+using namespace VSXaml;
+
+using namespace Platform;
+using namespace Windows::ApplicationModel;
+using namespace Windows::ApplicationModel::Activation;
+using namespace Windows::Foundation;
+using namespace Windows::Foundation::Collections;
+using namespace Windows::UI::Xaml;
+using namespace Windows::UI::Xaml::Controls;
+using namespace Windows::UI::Xaml::Controls::Primitives;
+using namespace Windows::UI::Xaml::Data;
+using namespace Windows::UI::Xaml::Input;
+using namespace Windows::UI::Xaml::Interop;
+using namespace Windows::UI::Xaml::Media;
+using namespace Windows::UI::Xaml::Navigation;
+
+// The Blank Application template is documented at http://go.microsoft.com/fwlink/?LinkId=234227
+
+/// <summary>
+/// Initializes the singleton application object. This is the first line of authored code
+/// executed, and as such is the logical equivalent of main() or WinMain().
+/// </summary>
+App::App()
+{
+ InitializeComponent();
+ Suspending += ref new SuspendingEventHandler(this, &App::OnSuspending);
+}
+
+/// <summary>
+/// Invoked when the application is launched normally by the end user. Other entry points
+/// will be used such as when the application is launched to open a specific file.
+/// </summary>
+/// <param name="e">Details about the launch request and process.</param>
+void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e)
+{
+
+#if _DEBUG
+ // Show graphics profiling information while debugging.
+ if (IsDebuggerPresent())
+ {
+ // Display the current frame rate counters
+ DebugSettings->EnableFrameRateCounter = true;
+ }
+#endif
+
+ auto rootFrame = dynamic_cast<Frame^>(Window::Current->Content);
+
+ // Do not repeat app initialization when the Window already has content,
+ // just ensure that the window is active
+ if (rootFrame == nullptr)
+ {
+ // Create a Frame to act as the navigation context and associate it with
+ // a SuspensionManager key
+ rootFrame = ref new Frame();
+
+ // Set the default language
+ rootFrame->Language = Windows::Globalization::ApplicationLanguages::Languages->GetAt(0);
+
+ rootFrame->NavigationFailed += ref new Windows::UI::Xaml::Navigation::NavigationFailedEventHandler(this, &App::OnNavigationFailed);
+
+ if (e->PreviousExecutionState == ApplicationExecutionState::Terminated)
+ {
+ // TODO: Restore the saved session state only when appropriate, scheduling the
+ // final launch steps after the restore is complete
+
+ }
+
+ if (rootFrame->Content == nullptr)
+ {
+ // When the navigation stack isn't restored navigate to the first page,
+ // configuring the new page by passing required information as a navigation
+ // parameter
+ rootFrame->Navigate(TypeName(MainPage::typeid), e->Arguments);
+ }
+ // Place the frame in the current Window
+ Window::Current->Content = rootFrame;
+ // Ensure the current window is active
+ Window::Current->Activate();
+ }
+ else
+ {
+ if (rootFrame->Content == nullptr)
+ {
+ // When the navigation stack isn't restored navigate to the first page,
+ // configuring the new page by passing required information as a navigation
+ // parameter
+ rootFrame->Navigate(TypeName(MainPage::typeid), e->Arguments);
+ }
+ // Ensure the current window is active
+ Window::Current->Activate();
+ }
+}
+
+/// <summary>
+/// Invoked when application execution is being suspended. Application state is saved
+/// without knowing whether the application will be terminated or resumed with the contents
+/// of memory still intact.
+/// </summary>
+/// <param name="sender">The source of the suspend request.</param>
+/// <param name="e">Details about the suspend request.</param>
+void App::OnSuspending(Object^ sender, SuspendingEventArgs^ e)
+{
+ (void) sender; // Unused parameter
+ (void) e; // Unused parameter
+
+ //TODO: Save application state and stop any background activity
+}
+
+/// <summary>
+/// Invoked when Navigation to a certain page fails
+/// </summary>
+/// <param name="sender">The Frame which failed navigation</param>
+/// <param name="e">Details about the navigation failure</param>
+void App::OnNavigationFailed(Platform::Object ^sender, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs ^e)
+{
+ throw ref new FailureException("Failed to load Page " + e->SourcePageType.Name);
+} \ No newline at end of file
diff --git a/Tests/VSXaml/App.xaml.h b/Tests/VSXaml/App.xaml.h
new file mode 100644
index 000000000..1f65bdab9
--- /dev/null
+++ b/Tests/VSXaml/App.xaml.h
@@ -0,0 +1,27 @@
+//
+// App.xaml.h
+// Declaration of the App class.
+//
+
+#pragma once
+
+#include "App.g.h"
+
+namespace VSXaml
+{
+ /// <summary>
+ /// Provides application-specific behavior to supplement the default Application class.
+ /// </summary>
+ ref class App sealed
+ {
+ protected:
+ virtual void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e) override;
+
+ internal:
+ App();
+
+ private:
+ void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ e);
+ void OnNavigationFailed(Platform::Object ^sender, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs ^e);
+ };
+}
diff --git a/Tests/VSXaml/Assets/Logo.scale-100.png b/Tests/VSXaml/Assets/Logo.scale-100.png
new file mode 100644
index 000000000..e26771cb3
--- /dev/null
+++ b/Tests/VSXaml/Assets/Logo.scale-100.png
Binary files differ
diff --git a/Tests/VSXaml/Assets/SmallLogo.scale-100.png b/Tests/VSXaml/Assets/SmallLogo.scale-100.png
new file mode 100644
index 000000000..1eb0d9d52
--- /dev/null
+++ b/Tests/VSXaml/Assets/SmallLogo.scale-100.png
Binary files differ
diff --git a/Tests/VSXaml/Assets/SplashScreen.scale-100.png b/Tests/VSXaml/Assets/SplashScreen.scale-100.png
new file mode 100644
index 000000000..c951e031b
--- /dev/null
+++ b/Tests/VSXaml/Assets/SplashScreen.scale-100.png
Binary files differ
diff --git a/Tests/VSXaml/Assets/StoreLogo.scale-100.png b/Tests/VSXaml/Assets/StoreLogo.scale-100.png
new file mode 100644
index 000000000..dcb672712
--- /dev/null
+++ b/Tests/VSXaml/Assets/StoreLogo.scale-100.png
Binary files differ
diff --git a/Tests/VSXaml/CMakeLists.txt b/Tests/VSXaml/CMakeLists.txt
new file mode 100644
index 000000000..f384c8213
--- /dev/null
+++ b/Tests/VSXaml/CMakeLists.txt
@@ -0,0 +1,52 @@
+cmake_minimum_required(VERSION 3.2)
+project(VSXaml)
+
+set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+
+set(SOURCE_FILES
+ App.xaml.cpp
+ MainPage.xaml.cpp
+ pch.cpp
+ )
+
+set(HEADER_FILES
+ App.xaml.h
+ MainPage.xaml.h
+ pch.h
+ )
+
+set(XAML_FILES
+ App.xaml
+ MainPage.xaml
+ )
+
+set(ASSET_FILES
+ Assets/Logo.scale-100.png
+ Assets/SmallLogo.scale-100.png
+ Assets/SplashScreen.scale-100.png
+ Assets/StoreLogo.scale-100.png
+ )
+
+set(CONTENT_FILES
+ Package.appxmanifest
+ )
+
+set(RESOURCE_FILES
+ ${CONTENT_FILES} ${ASSET_FILES}
+ VSXaml_TemporaryKey.pfx)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+
+set_property(SOURCE ${CONTENT_FILES} PROPERTY VS_DEPLOYMENT_CONTENT 1)
+set_property(SOURCE ${ASSET_FILES} PROPERTY VS_DEPLOYMENT_CONTENT 1)
+set_property(SOURCE ${ASSET_FILES} PROPERTY VS_DEPLOYMENT_LOCATION "Assets")
+
+set_property(SOURCE "App.xaml" PROPERTY VS_XAML_TYPE "ApplicationDefinition")
+
+source_group("Source Files" FILES ${SOURCE_FILES})
+source_group("Header Files" FILES ${HEADER_FILES})
+source_group("Resource Files" FILES ${RESOURCE_FILES})
+source_group("Xaml Files" FILES ${XAML_FILES})
+
+add_executable(VSXaml WIN32 ${SOURCE_FILES} ${HEADER_FILES} ${RESOURCE_FILES} ${XAML_FILES})
+set_property(TARGET VSXaml PROPERTY VS_WINRT_COMPONENT TRUE)
diff --git a/Tests/VSXaml/MainPage.xaml b/Tests/VSXaml/MainPage.xaml
new file mode 100644
index 000000000..62139cab3
--- /dev/null
+++ b/Tests/VSXaml/MainPage.xaml
@@ -0,0 +1,14 @@
+<Page
+ x:Class="VSXaml.MainPage"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:local="using:VSXaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ mc:Ignorable="d">
+
+ <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
+ <TextBlock Text="I'm a CMake XAML App" HorizontalAlignment="Center" VerticalAlignment="Center"
+ Style="{StaticResource HeaderTextBlockStyle}"/>
+ </Grid>
+</Page>
diff --git a/Tests/VSXaml/MainPage.xaml.cpp b/Tests/VSXaml/MainPage.xaml.cpp
new file mode 100644
index 000000000..d0a64e8b2
--- /dev/null
+++ b/Tests/VSXaml/MainPage.xaml.cpp
@@ -0,0 +1,27 @@
+//
+// MainPage.xaml.cpp
+// Implementation of the MainPage class.
+//
+
+#include "pch.h"
+#include "MainPage.xaml.h"
+
+using namespace VSXaml;
+
+using namespace Platform;
+using namespace Windows::Foundation;
+using namespace Windows::Foundation::Collections;
+using namespace Windows::UI::Xaml;
+using namespace Windows::UI::Xaml::Controls;
+using namespace Windows::UI::Xaml::Controls::Primitives;
+using namespace Windows::UI::Xaml::Data;
+using namespace Windows::UI::Xaml::Input;
+using namespace Windows::UI::Xaml::Media;
+using namespace Windows::UI::Xaml::Navigation;
+
+// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
+
+MainPage::MainPage()
+{
+ InitializeComponent();
+}
diff --git a/Tests/VSXaml/MainPage.xaml.h b/Tests/VSXaml/MainPage.xaml.h
new file mode 100644
index 000000000..ccc781b8f
--- /dev/null
+++ b/Tests/VSXaml/MainPage.xaml.h
@@ -0,0 +1,21 @@
+//
+// MainPage.xaml.h
+// Declaration of the MainPage class.
+//
+
+#pragma once
+
+#include "MainPage.g.h"
+
+namespace VSXaml
+{
+ /// <summary>
+ /// An empty page that can be used on its own or navigated to within a Frame.
+ /// </summary>
+ public ref class MainPage sealed
+ {
+ public:
+ MainPage();
+
+ };
+}
diff --git a/Tests/VSXaml/Package.appxmanifest b/Tests/VSXaml/Package.appxmanifest
new file mode 100644
index 000000000..873a64aeb
--- /dev/null
+++ b/Tests/VSXaml/Package.appxmanifest
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest">
+
+ <Identity Name="19ff96f1-8379-4e14-8b9d-04648b3b36a9"
+ Publisher="CN=Microsoft"
+ Version="1.0.0.0" />
+
+ <Properties>
+ <DisplayName>VSXaml</DisplayName>
+ <PublisherDisplayName>Microsoft</PublisherDisplayName>
+ <Logo>Assets\StoreLogo.png</Logo>
+ </Properties>
+
+ <Prerequisites>
+ <OSMinVersion>6.3.0</OSMinVersion>
+ <OSMaxVersionTested>6.3.0</OSMaxVersionTested>
+ </Prerequisites>
+
+ <Resources>
+ <Resource Language="x-generate"/>
+ </Resources>
+
+ <Applications>
+ <Application Id="App"
+ Executable="$targetnametoken$.exe"
+ EntryPoint="VSXaml.App">
+ <m2:VisualElements
+ DisplayName="VSXaml"
+ Square150x150Logo="Assets\Logo.png"
+ Square30x30Logo="Assets\SmallLogo.png"
+ Description="VSXaml"
+ ForegroundText="light"
+ BackgroundColor="#464646">
+ <m2:SplashScreen Image="Assets\SplashScreen.png" />
+ </m2:VisualElements>
+ </Application>
+ </Applications>
+ <Capabilities>
+ <Capability Name="internetClient" />
+ </Capabilities>
+</Package> \ No newline at end of file
diff --git a/Tests/VSXaml/VSXaml_TemporaryKey.pfx b/Tests/VSXaml/VSXaml_TemporaryKey.pfx
new file mode 100644
index 000000000..1cad9993d
--- /dev/null
+++ b/Tests/VSXaml/VSXaml_TemporaryKey.pfx
Binary files differ
diff --git a/Tests/VSXaml/pch.cpp b/Tests/VSXaml/pch.cpp
new file mode 100644
index 000000000..01484ff5a
--- /dev/null
+++ b/Tests/VSXaml/pch.cpp
@@ -0,0 +1,6 @@
+//
+// pch.cpp
+// Include the standard header and generate the precompiled header.
+//
+
+#include "pch.h"
diff --git a/Tests/VSXaml/pch.h b/Tests/VSXaml/pch.h
new file mode 100644
index 000000000..2c4354dd1
--- /dev/null
+++ b/Tests/VSXaml/pch.h
@@ -0,0 +1,11 @@
+//
+// pch.h
+// Header for standard system include files.
+//
+
+#pragma once
+
+#include <collection.h>
+#include <ppltasks.h>
+
+#include "App.xaml.h"
diff --git a/Tests/Visibility/CMakeLists.txt b/Tests/Visibility/CMakeLists.txt
new file mode 100644
index 000000000..9498ca65c
--- /dev/null
+++ b/Tests/Visibility/CMakeLists.txt
@@ -0,0 +1,66 @@
+cmake_minimum_required(VERSION 3.2)
+cmake_policy(SET CMP0063 NEW)
+
+project(Visibility)
+
+add_library(hidden1 SHARED hidden.c)
+set_property(TARGET hidden1 PROPERTY C_VISIBILITY_PRESET hidden)
+
+add_library(hidden_object OBJECT hidden.c)
+set_property(TARGET hidden_object PROPERTY C_VISIBILITY_PRESET hidden)
+set_property(TARGET hidden_object PROPERTY POSITION_INDEPENDENT_CODE ON)
+
+add_library(hidden_static STATIC hidden.c)
+set_property(TARGET hidden_static PROPERTY C_VISIBILITY_PRESET hidden)
+set_property(TARGET hidden_static PROPERTY POSITION_INDEPENDENT_CODE ON)
+
+add_library(hidden2 SHARED $<TARGET_OBJECTS:hidden_object> shared.c)
+
+add_library(hidden3 SHARED shared.c)
+target_link_libraries(hidden3 hidden_static)
+
+foreach(t
+ hidden1
+ hidden2
+ hidden3
+ )
+ add_custom_command(TARGET ${t} POST_BUILD
+ COMMAND ${CMAKE_COMMAND}
+ -DCMAKE_NM=${CMAKE_NM}
+ -DTEST_LIBRARY_PATH=$<TARGET_FILE:${t}>
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/verify.cmake
+ )
+endforeach()
+
+
+add_library(inlines_hidden1 SHARED foo.cpp bar.c)
+set_property(TARGET inlines_hidden1 PROPERTY VISIBILITY_INLINES_HIDDEN ON)
+target_compile_options(inlines_hidden1 PRIVATE -Werror)
+
+add_library(inlines_hidden_object OBJECT foo.cpp bar.c)
+set_property(TARGET inlines_hidden_object PROPERTY VISIBILITY_INLINES_HIDDEN ON)
+set_property(TARGET inlines_hidden_object PROPERTY POSITION_INDEPENDENT_CODE ON)
+target_compile_options(inlines_hidden_object PRIVATE -Werror)
+
+add_library(inlines_hidden_static STATIC foo.cpp bar.c)
+set_property(TARGET inlines_hidden_static PROPERTY VISIBILITY_INLINES_HIDDEN ON)
+set_property(TARGET inlines_hidden_static PROPERTY POSITION_INDEPENDENT_CODE ON)
+target_compile_options(inlines_hidden_static PRIVATE -Werror)
+
+add_library(inlines_hidden2 SHARED $<TARGET_OBJECTS:inlines_hidden_object> shared.cpp)
+
+add_library(inlines_hidden3 SHARED shared.cpp)
+target_link_libraries(inlines_hidden3 inlines_hidden_static)
+
+foreach(t
+ inlines_hidden1
+ inlines_hidden2
+ inlines_hidden3
+ )
+ add_custom_command(TARGET ${t} POST_BUILD
+ COMMAND ${CMAKE_COMMAND}
+ -DCMAKE_NM=${CMAKE_NM}
+ -DTEST_LIBRARY_PATH=$<TARGET_FILE:${t}>
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/verify.cmake
+ )
+endforeach()
diff --git a/Tests/Visibility/bar.c b/Tests/Visibility/bar.c
new file mode 100644
index 000000000..e42599986
--- /dev/null
+++ b/Tests/Visibility/bar.c
@@ -0,0 +1 @@
+void bar() {}
diff --git a/Tests/Visibility/foo.cpp b/Tests/Visibility/foo.cpp
new file mode 100644
index 000000000..2b66b69be
--- /dev/null
+++ b/Tests/Visibility/foo.cpp
@@ -0,0 +1,11 @@
+class Foo
+{
+public:
+ void bar() {}
+};
+
+void baz()
+{
+ Foo foo;
+ foo.bar();
+}
diff --git a/Tests/Visibility/hidden.c b/Tests/Visibility/hidden.c
new file mode 100644
index 000000000..6e97343ed
--- /dev/null
+++ b/Tests/Visibility/hidden.c
@@ -0,0 +1,4 @@
+int hidden_function(void) { return 0; }
+
+__attribute__((visibility("default")))
+int not_hidden(void) { return hidden_function(); }
diff --git a/Tests/Visibility/shared.c b/Tests/Visibility/shared.c
new file mode 100644
index 000000000..bb9497695
--- /dev/null
+++ b/Tests/Visibility/shared.c
@@ -0,0 +1,3 @@
+extern int not_hidden(void);
+
+int shared(void) { return not_hidden(); }
diff --git a/Tests/Visibility/shared.cpp b/Tests/Visibility/shared.cpp
new file mode 100644
index 000000000..4897ff819
--- /dev/null
+++ b/Tests/Visibility/shared.cpp
@@ -0,0 +1,8 @@
+extern "C" int bar(void);
+void baz();
+
+int shared()
+{
+ baz();
+ return bar();
+}
diff --git a/Tests/Visibility/verify.cmake b/Tests/Visibility/verify.cmake
new file mode 100644
index 000000000..3b2028cf7
--- /dev/null
+++ b/Tests/Visibility/verify.cmake
@@ -0,0 +1,14 @@
+execute_process(COMMAND ${CMAKE_NM} -D ${TEST_LIBRARY_PATH}
+ RESULT_VARIABLE RESULT
+ OUTPUT_VARIABLE OUTPUT
+ ERROR_VARIABLE ERROR
+)
+
+if(NOT "${RESULT}" STREQUAL "0")
+ message(FATAL_ERROR "nm failed [${RESULT}] [${OUTPUT}] [${ERROR}]")
+endif()
+
+if(${OUTPUT} MATCHES "(Foo[^\\n]*bar|hidden_function)")
+ message(FATAL_ERROR
+ "Found ${CMAKE_MATCH_1} which should have been hidden [${OUTPUT}]")
+endif()
diff --git a/Tests/Wrapping/CMakeLists.txt b/Tests/Wrapping/CMakeLists.txt
index 58e9c3242..aca36bc31 100644
--- a/Tests/Wrapping/CMakeLists.txt
+++ b/Tests/Wrapping/CMakeLists.txt
@@ -54,7 +54,7 @@ if (QT_FOUND AND QT_WRAP_UI)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/foo.ui.in
- ${CMAKE_CURRENT_BINARY_DIR}/foo.ui IMMEDIATE)
+ ${CMAKE_CURRENT_BINARY_DIR}/foo.ui)
set (QT_WRAP_UI "On")
set (QT_UIC_EXE "${QT_UIC_EXECUTABLE}")
@@ -85,23 +85,24 @@ endif ()
# Since FLTK_FLUID_EXE is supposed to create a .cxx/.h from a .fl/.fld,
# create an empty one so that the dependencies can be met.
#
-set (FLTK_SRCS
- fltk1.fl
- )
add_executable(fakefluid fakefluid.cxx)
-get_target_property(FLUID_LOC fakefluid LOCATION)
set (FLTK_WRAP_UI "On")
-set (FLTK_FLUID_EXECUTABLE "${FLUID_LOC}")
-fltk_wrap_ui (wraplibFLTK ${FLTK_SRCS})
+set (FLTK_FLUID_EXECUTABLE fakefluid)
+fltk_wrap_ui (wraplibFLTK fltk1.fl)
add_library(wraplibFLTK ${wraplibFLTK_FLTK_UI_SRCS})
add_dependencies(wraplibFLTK fakefluid)
add_dependencies(fakefluid Wrap)
+fltk_wrap_ui (wrapFLTK fltk2.fl)
+add_executable(wrapFLTK wrapFLTK.c ${wrapFLTK_FLTK_UI_SRCS})
+target_link_libraries(wrapFLTK wraplibFLTK)
+add_dependencies(wrapFLTK fakefluid)
+
#
# Mangled Mesa
#
configure_file(
${Wrapping_SOURCE_DIR}/dummy
${Wrapping_BINARY_DIR}/gl.h
- COPYONLY IMMEDIATE)
+ COPYONLY)
use_mangled_mesa (${Wrapping_BINARY_DIR} ${Wrapping_BINARY_DIR}/mangled_mesa)
diff --git a/Tests/Wrapping/fltk2.fl b/Tests/Wrapping/fltk2.fl
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/Wrapping/fltk2.fl
diff --git a/Tests/Wrapping/wrapFLTK.c b/Tests/Wrapping/wrapFLTK.c
new file mode 100644
index 000000000..78f2de106
--- /dev/null
+++ b/Tests/Wrapping/wrapFLTK.c
@@ -0,0 +1 @@
+int main(void) { return 0; }
diff --git a/Tests/XCTest/CMakeLists.txt b/Tests/XCTest/CMakeLists.txt
new file mode 100644
index 000000000..e8666231b
--- /dev/null
+++ b/Tests/XCTest/CMakeLists.txt
@@ -0,0 +1,57 @@
+cmake_minimum_required(VERSION 3.1)
+project(XCTest)
+enable_testing()
+
+find_package(XCTest REQUIRED)
+
+# Framework
+
+add_library(FrameworkExample SHARED
+ FrameworkExample/FrameworkExample.c
+ FrameworkExample/FrameworkExample.h
+ FrameworkExample/Info.plist)
+
+target_include_directories(FrameworkExample PUBLIC .)
+
+set_target_properties(FrameworkExample PROPERTIES
+ FRAMEWORK TRUE
+ VERSION "1.0.0"
+ SOVERSION "1.0.0"
+ FRAMEWORK_VERSION "A"
+ MACOSX_FRAMEWORK_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/FrameworkExample/Info.plist
+ PUBLIC_HEADER FrameworkExample/FrameworkExample.h)
+
+# XCTest for Framework
+
+xctest_add_bundle(FrameworkExampleTests FrameworkExample
+ FrameworkExampleTests/FrameworkExampleTests.m
+ FrameworkExampleTests/Info.plist)
+
+set_target_properties(FrameworkExampleTests PROPERTIES
+ MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/FrameworkExampleTests/Info.plist
+ )
+
+xctest_add_test(XCTest.FrameworkExample FrameworkExampleTests)
+
+# Cocoa App Bundle
+
+add_executable(CocoaExample MACOSX_BUNDLE
+ CocoaExample/main.m
+ CocoaExample/AppDelegate.m
+ CocoaExample/AppDelegate.h
+ CocoaExample/MainMenu.xib
+)
+
+target_link_libraries(CocoaExample PRIVATE "-framework Foundation")
+target_link_libraries(CocoaExample PRIVATE "-framework AppKit")
+
+set_target_properties(CocoaExample PROPERTIES
+ MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/CocoaExample/Info.plist
+ RESOURCE "CocoaExample/MainMenu.xib")
+
+# XCTest for Cocoa App Bundle
+
+xctest_add_bundle(CocoaExampleTests CocoaExample
+ CocoaExampleTests/CocoaExampleTests.m)
+
+xctest_add_test(XCTest.CocoaExample CocoaExampleTests)
diff --git a/Tests/XCTest/CocoaExample/AppDelegate.h b/Tests/XCTest/CocoaExample/AppDelegate.h
new file mode 100644
index 000000000..4bf41019e
--- /dev/null
+++ b/Tests/XCTest/CocoaExample/AppDelegate.h
@@ -0,0 +1,6 @@
+#import <Cocoa/Cocoa.h>
+
+@interface AppDelegate : NSObject <NSApplicationDelegate>
+
+
+@end
diff --git a/Tests/XCTest/CocoaExample/AppDelegate.m b/Tests/XCTest/CocoaExample/AppDelegate.m
new file mode 100644
index 000000000..07af62fd5
--- /dev/null
+++ b/Tests/XCTest/CocoaExample/AppDelegate.m
@@ -0,0 +1,18 @@
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@property (assign) IBOutlet NSWindow *window;
+@end
+
+@implementation AppDelegate
+
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
+ // Insert code here to initialize your application
+}
+
+- (void)applicationWillTerminate:(NSNotification *)aNotification {
+ // Insert code here to tear down your application
+}
+
+@end
diff --git a/Tests/XCTest/CocoaExample/Info.plist b/Tests/XCTest/CocoaExample/Info.plist
new file mode 100644
index 000000000..5267c6322
--- /dev/null
+++ b/Tests/XCTest/CocoaExample/Info.plist
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleExecutable</key>
+ <string>CocoaExample</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>org.cmake.CocoaExample</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>CocoaExample</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+ <key>NSMainNibFile</key>
+ <string>MainMenu</string>
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+</dict>
+</plist>
diff --git a/Tests/XCTest/CocoaExample/MainMenu.xib b/Tests/XCTest/CocoaExample/MainMenu.xib
new file mode 100644
index 000000000..9498a0a7d
--- /dev/null
+++ b/Tests/XCTest/CocoaExample/MainMenu.xib
@@ -0,0 +1,680 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6233" systemVersion="14A329f" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+ <dependencies>
+ <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6233"/>
+ </dependencies>
+ <objects>
+ <customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
+ <connections>
+ <outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/>
+ </connections>
+ </customObject>
+ <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+ <customObject id="-3" userLabel="Application" customClass="NSObject"/>
+ <customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModuleProvider="">
+ <connections>
+ <outlet property="window" destination="QvC-M9-y7g" id="gIp-Ho-8D9"/>
+ </connections>
+ </customObject>
+ <customObject id="YLy-65-1bz" customClass="NSFontManager"/>
+ <menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
+ <items>
+ <menuItem title="CocoaExample" id="1Xt-HY-uBw">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="CocoaExample" systemMenu="apple" id="uQy-DD-JDr">
+ <items>
+ <menuItem title="About CocoaExample" id="5kV-Vb-QxS">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="orderFrontStandardAboutPanel:" target="-1" id="Exp-CZ-Vem"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
+ <menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
+ <menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
+ <menuItem title="Services" id="NMo-om-nkz">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
+ <menuItem title="Hide CocoaExample" keyEquivalent="h" id="Olw-nP-bQN">
+ <connections>
+ <action selector="hide:" target="-1" id="PnN-Uc-m68"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ <connections>
+ <action selector="hideOtherApplications:" target="-1" id="VT4-aY-XCT"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Show All" id="Kd2-mp-pUS">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="unhideAllApplications:" target="-1" id="Dhg-Le-xox"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
+ <menuItem title="Quit CocoaExample" keyEquivalent="q" id="4sb-4s-VLi">
+ <connections>
+ <action selector="terminate:" target="-1" id="Te7-pn-YzF"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="File" id="dMs-cI-mzQ">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="File" id="bib-Uj-vzu">
+ <items>
+ <menuItem title="New" keyEquivalent="n" id="Was-JA-tGl">
+ <connections>
+ <action selector="newDocument:" target="-1" id="4Si-XN-c54"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Open…" keyEquivalent="o" id="IAo-SY-fd9">
+ <connections>
+ <action selector="openDocument:" target="-1" id="bVn-NM-KNZ"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Open Recent" id="tXI-mr-wws">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="oas-Oc-fiZ">
+ <items>
+ <menuItem title="Clear Menu" id="vNY-rz-j42">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="clearRecentDocuments:" target="-1" id="Daa-9d-B3U"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
+ <menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG">
+ <connections>
+ <action selector="performClose:" target="-1" id="HmO-Ls-i7Q"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Save…" keyEquivalent="s" id="pxx-59-PXV">
+ <connections>
+ <action selector="saveDocument:" target="-1" id="teZ-XB-qJY"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Save As…" keyEquivalent="S" id="Bw7-FT-i3A">
+ <connections>
+ <action selector="saveDocumentAs:" target="-1" id="mDf-zr-I0C"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Revert to Saved" id="KaW-ft-85H">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="revertDocumentToSaved:" target="-1" id="iJ3-Pv-kwq"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="aJh-i4-bef"/>
+ <menuItem title="Page Setup…" keyEquivalent="P" id="qIS-W8-SiK">
+ <modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
+ <connections>
+ <action selector="runPageLayout:" target="-1" id="Din-rz-gC5"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Print…" keyEquivalent="p" id="aTl-1u-JFS">
+ <connections>
+ <action selector="print:" target="-1" id="qaZ-4w-aoO"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Edit" id="5QF-Oa-p0T">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Edit" id="W48-6f-4Dl">
+ <items>
+ <menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
+ <connections>
+ <action selector="undo:" target="-1" id="M6e-cu-g7V"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
+ <connections>
+ <action selector="redo:" target="-1" id="oIA-Rs-6OD"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
+ <menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
+ <connections>
+ <action selector="cut:" target="-1" id="YJe-68-I9s"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
+ <connections>
+ <action selector="copy:" target="-1" id="G1f-GL-Joy"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
+ <connections>
+ <action selector="paste:" target="-1" id="UvS-8e-Qdg"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ <connections>
+ <action selector="pasteAsPlainText:" target="-1" id="cEh-KX-wJQ"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Delete" id="pa3-QI-u2k">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="delete:" target="-1" id="0Mk-Ml-PaM"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
+ <connections>
+ <action selector="selectAll:" target="-1" id="VNm-Mi-diN"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
+ <menuItem title="Find" id="4EN-yA-p0u">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Find" id="1b7-l0-nxx">
+ <items>
+ <menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
+ <connections>
+ <action selector="performFindPanelAction:" target="-1" id="cD7-Qs-BN4"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ <connections>
+ <action selector="performFindPanelAction:" target="-1" id="WD3-Gg-5AJ"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
+ <connections>
+ <action selector="performFindPanelAction:" target="-1" id="NDo-RZ-v9R"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
+ <connections>
+ <action selector="performFindPanelAction:" target="-1" id="HOh-sY-3ay"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
+ <connections>
+ <action selector="performFindPanelAction:" target="-1" id="U76-nv-p5D"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
+ <connections>
+ <action selector="centerSelectionInVisibleArea:" target="-1" id="IOG-6D-g5B"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
+ <items>
+ <menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
+ <connections>
+ <action selector="showGuessPanel:" target="-1" id="vFj-Ks-hy3"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
+ <connections>
+ <action selector="checkSpelling:" target="-1" id="fz7-VC-reM"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
+ <menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleContinuousSpellChecking:" target="-1" id="7w6-Qz-0kB"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleGrammarChecking:" target="-1" id="muD-Qn-j4w"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticSpellingCorrection:" target="-1" id="2lM-Qi-WAP"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Substitutions" id="9ic-FL-obx">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
+ <items>
+ <menuItem title="Show Substitutions" id="z6F-FW-3nz">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="orderFrontSubstitutionsPanel:" target="-1" id="oku-mr-iSq"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
+ <menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleSmartInsertDelete:" target="-1" id="3IJ-Se-DZD"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Smart Quotes" id="hQb-2v-fYv">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="ptq-xd-QOA"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Smart Dashes" id="rgM-f4-ycn">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticDashSubstitution:" target="-1" id="oCt-pO-9gS"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Smart Links" id="cwL-P1-jid">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticLinkDetection:" target="-1" id="Gip-E3-Fov"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Data Detectors" id="tRr-pd-1PS">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticDataDetection:" target="-1" id="R1I-Nq-Kbl"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Text Replacement" id="HFQ-gK-NFA">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticTextReplacement:" target="-1" id="DvP-Fe-Py6"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Transformations" id="2oI-Rn-ZJC">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Transformations" id="c8a-y6-VQd">
+ <items>
+ <menuItem title="Make Upper Case" id="vmV-6d-7jI">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="uppercaseWord:" target="-1" id="sPh-Tk-edu"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Make Lower Case" id="d9M-CD-aMd">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="lowercaseWord:" target="-1" id="iUZ-b5-hil"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Capitalize" id="UEZ-Bs-lqG">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="capitalizeWord:" target="-1" id="26H-TL-nsh"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Speech" id="xrE-MZ-jX0">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Speech" id="3rS-ZA-NoH">
+ <items>
+ <menuItem title="Start Speaking" id="Ynk-f8-cLZ">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="startSpeaking:" target="-1" id="654-Ng-kyl"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Stop Speaking" id="Oyz-dy-DGm">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="stopSpeaking:" target="-1" id="dX8-6p-jy9"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Format" id="jxT-CU-nIS">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Format" id="GEO-Iw-cKr">
+ <items>
+ <menuItem title="Font" id="Gi5-1S-RQB">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Font" systemMenu="font" id="aXa-aM-Jaq">
+ <items>
+ <menuItem title="Show Fonts" keyEquivalent="t" id="Q5e-8K-NDq">
+ <connections>
+ <action selector="orderFrontFontPanel:" target="YLy-65-1bz" id="WHr-nq-2xA"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Bold" tag="2" keyEquivalent="b" id="GB9-OM-e27">
+ <connections>
+ <action selector="addFontTrait:" target="YLy-65-1bz" id="hqk-hr-sYV"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Italic" tag="1" keyEquivalent="i" id="Vjx-xi-njq">
+ <connections>
+ <action selector="addFontTrait:" target="YLy-65-1bz" id="IHV-OB-c03"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Underline" keyEquivalent="u" id="WRG-CD-K1S">
+ <connections>
+ <action selector="underline:" target="-1" id="FYS-2b-JAY"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="5gT-KC-WSO"/>
+ <menuItem title="Bigger" tag="3" keyEquivalent="+" id="Ptp-SP-VEL">
+ <connections>
+ <action selector="modifyFont:" target="YLy-65-1bz" id="Uc7-di-UnL"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Smaller" tag="4" keyEquivalent="-" id="i1d-Er-qST">
+ <connections>
+ <action selector="modifyFont:" target="YLy-65-1bz" id="HcX-Lf-eNd"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="kx3-Dk-x3B"/>
+ <menuItem title="Kern" id="jBQ-r6-VK2">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Kern" id="tlD-Oa-oAM">
+ <items>
+ <menuItem title="Use Default" id="GUa-eO-cwY">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="useStandardKerning:" target="-1" id="6dk-9l-Ckg"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Use None" id="cDB-IK-hbR">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="turnOffKerning:" target="-1" id="U8a-gz-Maa"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Tighten" id="46P-cB-AYj">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="tightenKerning:" target="-1" id="hr7-Nz-8ro"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Loosen" id="ogc-rX-tC1">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="loosenKerning:" target="-1" id="8i4-f9-FKE"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Ligatures" id="o6e-r0-MWq">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Ligatures" id="w0m-vy-SC9">
+ <items>
+ <menuItem title="Use Default" id="agt-UL-0e3">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="useStandardLigatures:" target="-1" id="7uR-wd-Dx6"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Use None" id="J7y-lM-qPV">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="turnOffLigatures:" target="-1" id="iX2-gA-Ilz"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Use All" id="xQD-1f-W4t">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="useAllLigatures:" target="-1" id="KcB-kA-TuK"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Baseline" id="OaQ-X3-Vso">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Baseline" id="ijk-EB-dga">
+ <items>
+ <menuItem title="Use Default" id="3Om-Ey-2VK">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="unscript:" target="-1" id="0vZ-95-Ywn"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Superscript" id="Rqc-34-cIF">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="superscript:" target="-1" id="3qV-fo-wpU"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Subscript" id="I0S-gh-46l">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="subscript:" target="-1" id="Q6W-4W-IGz"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Raise" id="2h7-ER-AoG">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="raiseBaseline:" target="-1" id="4sk-31-7Q9"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Lower" id="1tx-W0-xDw">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="lowerBaseline:" target="-1" id="OF1-bc-KW4"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="Ndw-q3-faq"/>
+ <menuItem title="Show Colors" keyEquivalent="C" id="bgn-CT-cEk">
+ <connections>
+ <action selector="orderFrontColorPanel:" target="-1" id="mSX-Xz-DV3"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="iMs-zA-UFJ"/>
+ <menuItem title="Copy Style" keyEquivalent="c" id="5Vv-lz-BsD">
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ <connections>
+ <action selector="copyFont:" target="-1" id="GJO-xA-L4q"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Paste Style" keyEquivalent="v" id="vKC-jM-MkH">
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ <connections>
+ <action selector="pasteFont:" target="-1" id="JfD-CL-leO"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Text" id="Fal-I4-PZk">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Text" id="d9c-me-L2H">
+ <items>
+ <menuItem title="Align Left" keyEquivalent="{" id="ZM1-6Q-yy1">
+ <connections>
+ <action selector="alignLeft:" target="-1" id="zUv-R1-uAa"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Center" keyEquivalent="|" id="VIY-Ag-zcb">
+ <connections>
+ <action selector="alignCenter:" target="-1" id="spX-mk-kcS"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Justify" id="J5U-5w-g23">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="alignJustified:" target="-1" id="ljL-7U-jND"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Align Right" keyEquivalent="}" id="wb2-vD-lq4">
+ <connections>
+ <action selector="alignRight:" target="-1" id="r48-bG-YeY"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="4s2-GY-VfK"/>
+ <menuItem title="Writing Direction" id="H1b-Si-o9J">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Writing Direction" id="8mr-sm-Yjd">
+ <items>
+ <menuItem title="Paragraph" enabled="NO" id="ZvO-Gk-QUH">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ </menuItem>
+ <menuItem id="YGs-j5-SAR">
+ <string key="title"> Default</string>
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="makeBaseWritingDirectionNatural:" target="-1" id="qtV-5e-UBP"/>
+ </connections>
+ </menuItem>
+ <menuItem id="Lbh-J2-qVU">
+ <string key="title"> Left to Right</string>
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="makeBaseWritingDirectionLeftToRight:" target="-1" id="S0X-9S-QSf"/>
+ </connections>
+ </menuItem>
+ <menuItem id="jFq-tB-4Kx">
+ <string key="title"> Right to Left</string>
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="makeBaseWritingDirectionRightToLeft:" target="-1" id="5fk-qB-AqJ"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="swp-gr-a21"/>
+ <menuItem title="Selection" enabled="NO" id="cqv-fj-IhA">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ </menuItem>
+ <menuItem id="Nop-cj-93Q">
+ <string key="title"> Default</string>
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="makeTextWritingDirectionNatural:" target="-1" id="lPI-Se-ZHp"/>
+ </connections>
+ </menuItem>
+ <menuItem id="BgM-ve-c93">
+ <string key="title"> Left to Right</string>
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="makeTextWritingDirectionLeftToRight:" target="-1" id="caW-Bv-w94"/>
+ </connections>
+ </menuItem>
+ <menuItem id="RB4-Sm-HuC">
+ <string key="title"> Right to Left</string>
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="makeTextWritingDirectionRightToLeft:" target="-1" id="EXD-6r-ZUu"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="fKy-g9-1gm"/>
+ <menuItem title="Show Ruler" id="vLm-3I-IUL">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleRuler:" target="-1" id="FOx-HJ-KwY"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Copy Ruler" keyEquivalent="c" id="MkV-Pr-PK5">
+ <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
+ <connections>
+ <action selector="copyRuler:" target="-1" id="71i-fW-3W2"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Paste Ruler" keyEquivalent="v" id="LVM-kO-fVI">
+ <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
+ <connections>
+ <action selector="pasteRuler:" target="-1" id="cSh-wd-qM2"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="View" id="H8h-7b-M4v">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="View" id="HyV-fh-RgO">
+ <items>
+ <menuItem title="Show Toolbar" keyEquivalent="t" id="snW-S8-Cw5">
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ <connections>
+ <action selector="toggleToolbarShown:" target="-1" id="BXY-wc-z0C"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Customize Toolbar…" id="1UK-8n-QPP">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="runToolbarCustomizationPalette:" target="-1" id="pQI-g3-MTW"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Window" id="aUF-d1-5bR">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
+ <items>
+ <menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
+ <connections>
+ <action selector="performMiniaturize:" target="-1" id="VwT-WD-YPe"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Zoom" id="R4o-n2-Eq4">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="performZoom:" target="-1" id="DIl-cC-cCs"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
+ <menuItem title="Bring All to Front" id="LE2-aR-0XJ">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="arrangeInFront:" target="-1" id="DRN-fu-gQh"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Help" id="wpr-3q-Mcd">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
+ <items>
+ <menuItem title="CocoaExample Help" keyEquivalent="?" id="FKE-Sm-Kum">
+ <connections>
+ <action selector="showHelp:" target="-1" id="y7X-2Q-9no"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ </items>
+ </menu>
+ <window title="CocoaExample" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g">
+ <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
+ <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
+ <rect key="contentRect" x="335" y="390" width="480" height="360"/>
+ <rect key="screenRect" x="0.0" y="0.0" width="1920" height="1177"/>
+ <view key="contentView" id="EiT-Mj-1SZ">
+ <rect key="frame" x="0.0" y="0.0" width="480" height="360"/>
+ <autoresizingMask key="autoresizingMask"/>
+ </view>
+ </window>
+ </objects>
+</document>
diff --git a/Tests/XCTest/CocoaExample/main.m b/Tests/XCTest/CocoaExample/main.m
new file mode 100644
index 000000000..8a6799b41
--- /dev/null
+++ b/Tests/XCTest/CocoaExample/main.m
@@ -0,0 +1,5 @@
+#import <Cocoa/Cocoa.h>
+
+int main(int argc, const char * argv[]) {
+ return NSApplicationMain(argc, argv);
+}
diff --git a/Tests/XCTest/CocoaExampleTests/CocoaExampleTests.m b/Tests/XCTest/CocoaExampleTests/CocoaExampleTests.m
new file mode 100644
index 000000000..70d61d6ff
--- /dev/null
+++ b/Tests/XCTest/CocoaExampleTests/CocoaExampleTests.m
@@ -0,0 +1,13 @@
+#import <XCTest/XCTest.h>
+
+@interface CocoaExampleTests : XCTestCase
+
+@end
+
+@implementation CocoaExampleTests
+
+- (void)testExample {
+ XCTAssert(YES, @"Pass");
+}
+
+@end
diff --git a/Tests/XCTest/FrameworkExample/FrameworkExample.c b/Tests/XCTest/FrameworkExample/FrameworkExample.c
new file mode 100644
index 000000000..2da78da78
--- /dev/null
+++ b/Tests/XCTest/FrameworkExample/FrameworkExample.c
@@ -0,0 +1,6 @@
+#include "FrameworkExample.h"
+
+int FourtyTwo()
+{
+ return 42;
+}
diff --git a/Tests/XCTest/FrameworkExample/FrameworkExample.h b/Tests/XCTest/FrameworkExample/FrameworkExample.h
new file mode 100644
index 000000000..2e0b499bf
--- /dev/null
+++ b/Tests/XCTest/FrameworkExample/FrameworkExample.h
@@ -0,0 +1 @@
+int FourtyTwo();
diff --git a/Tests/XCTest/FrameworkExample/Info.plist b/Tests/XCTest/FrameworkExample/Info.plist
new file mode 100644
index 000000000..a22acea22
--- /dev/null
+++ b/Tests/XCTest/FrameworkExample/Info.plist
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleExecutable</key>
+ <string>FrameworkExample</string>
+ <key>CFBundleIdentifier</key>
+ <string>org.cmake.FrameworkExample</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>FrameworkExample</string>
+ <key>CFBundlePackageType</key>
+ <string>FMWK</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string></string>
+ <key>NSHumanReadableCopyright</key>
+ <string></string>
+ <key>NSPrincipalClass</key>
+ <string></string>
+</dict>
+</plist>
diff --git a/Tests/XCTest/FrameworkExampleTests/FrameworkExampleTests.m b/Tests/XCTest/FrameworkExampleTests/FrameworkExampleTests.m
new file mode 100644
index 000000000..7cba23ecb
--- /dev/null
+++ b/Tests/XCTest/FrameworkExampleTests/FrameworkExampleTests.m
@@ -0,0 +1,16 @@
+#import <XCTest/XCTest.h>
+
+#import "FrameworkExample/FrameworkExample.h"
+
+@interface FrameworkExampleTests : XCTestCase
+
+@end
+
+@implementation FrameworkExampleTests
+
+- (void)testFourtyTwo {
+ // This is an example of a functional test case.
+ XCTAssertEqual(42, FourtyTwo());
+}
+
+@end
diff --git a/Tests/XCTest/FrameworkExampleTests/Info.plist b/Tests/XCTest/FrameworkExampleTests/Info.plist
new file mode 100644
index 000000000..293921b75
--- /dev/null
+++ b/Tests/XCTest/FrameworkExampleTests/Info.plist
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleExecutable</key>
+ <string>FrameworkExampleTests</string>
+ <key>CFBundleIdentifier</key>
+ <string>org.cmake.FrameworkExampleTests</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>FrameworkExampleTests</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+</dict>
+</plist>
diff --git a/Tests/iOSNavApp/CMakeLists.txt b/Tests/iOSNavApp/CMakeLists.txt
index 12c3ada35..1fc33e01a 100644
--- a/Tests/iOSNavApp/CMakeLists.txt
+++ b/Tests/iOSNavApp/CMakeLists.txt
@@ -3,7 +3,6 @@ project(NavApp3)
set(CMAKE_OSX_SYSROOT iphoneos4.3)
set(CMAKE_OSX_ARCHITECTURES "armv6;armv7;i386")
-set(CMAKE_XCODE_EFFECTIVE_PLATFORMS "-iphoneos;-iphonesimulator")
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
diff --git a/Utilities/CMakeLists.txt b/Utilities/CMakeLists.txt
index bad8d630e..cf6bb7285 100644
--- a/Utilities/CMakeLists.txt
+++ b/Utilities/CMakeLists.txt
@@ -11,157 +11,29 @@
#=============================================================================
subdirs(Doxygen KWStyle)
-make_directory(${CMake_BINARY_DIR}/Docs)
-
-# Add a documentation target.
-set(DOC_FILES "")
-
-set(MAN_FILES
- ${CMake_BINARY_DIR}/Docs/cmake.1
- ${CMake_BINARY_DIR}/Docs/cmakecommands.1
- ${CMake_BINARY_DIR}/Docs/cmakecompat.1
- ${CMake_BINARY_DIR}/Docs/cmakeprops.1
- ${CMake_BINARY_DIR}/Docs/cmakepolicies.1
- ${CMake_BINARY_DIR}/Docs/cmakevars.1
- ${CMake_BINARY_DIR}/Docs/cmakemodules.1
- )
-set(TEXT_FILES
- ${CMake_BINARY_DIR}/Docs/cmake.txt
- ${CMake_BINARY_DIR}/Docs/cmake-policies.txt
- ${CMake_BINARY_DIR}/Docs/cmake-properties.txt
- ${CMake_BINARY_DIR}/Docs/cmake-variables.txt
- ${CMake_BINARY_DIR}/Docs/cmake-modules.txt
- ${CMake_BINARY_DIR}/Docs/cmake-commands.txt
- ${CMake_BINARY_DIR}/Docs/cmake-compatcommands.txt
- )
-set(HTML_FILES
- ${CMake_BINARY_DIR}/Docs/cmake.html
- ${CMake_BINARY_DIR}/Docs/cmake-policies.html
- ${CMake_BINARY_DIR}/Docs/cmake-properties.html
- ${CMake_BINARY_DIR}/Docs/cmake-variables.html
- ${CMake_BINARY_DIR}/Docs/cmake-modules.html
- ${CMake_BINARY_DIR}/Docs/cmake-commands.html
- ${CMake_BINARY_DIR}/Docs/cmake-compatcommands.html
- )
-set(DOCBOOK_FILES
- ${CMake_BINARY_DIR}/Docs/cmake.docbook
- )
-
-macro(ADD_DOCS target dependency)
- # Generate documentation for "ctest" executable.
- get_target_property(CMD ${target} LOCATION)
- # only generate the documentation if the target is actually built
- if(CMD)
- add_custom_command(
- OUTPUT ${CMake_BINARY_DIR}/Docs/${target}.txt
- ${${target}-PATH} # Possibly set PATH, see below.
- COMMAND ${CMD}
- ARGS --help-full ${CMake_BINARY_DIR}/Docs/${target}.txt
- --help-full ${CMake_BINARY_DIR}/Docs/${target}.html
- --help-full ${CMake_BINARY_DIR}/Docs/${target}.1
- --help-full ${CMake_BINARY_DIR}/Docs/${target}.docbook
- DEPENDS ${target}
- MAIN_DEPENDENCY ${dependency}
- )
- set(DOC_FILES ${DOC_FILES} ${CMake_BINARY_DIR}/Docs/${target}.txt)
- list(APPEND MAN_FILES ${CMake_BINARY_DIR}/Docs/${target}.1)
- list(APPEND TEXT_FILES ${CMake_BINARY_DIR}/Docs/${target}.txt)
- list(APPEND HTML_FILES ${CMake_BINARY_DIR}/Docs/${target}.html)
- list(APPEND DOCBOOK_FILES ${CMake_BINARY_DIR}/Docs/${target}.docbook)
- endif()
-endmacro()
-
-# Help cmake-gui find the Qt DLLs on Windows.
-if(TARGET cmake-gui)
- get_property(Qt_BIN_DIR TARGET cmake-gui PROPERTY Qt_BIN_DIR)
- set(WIN_SHELL_GENS "Visual Studio|NMake|MinGW|Watcom|Borland")
- if(Qt_BIN_DIR AND "${CMAKE_GENERATOR}" MATCHES "${WIN_SHELL_GENS}"
- AND NOT CMAKE_NO_AUTO_QT_ENV)
- # Tell the macro to set the path before running cmake-gui.
- string(REPLACE ";" "\\;" _PATH "PATH=${Qt_BIN_DIR};%PATH%")
- set(cmake-gui-PATH COMMAND set "${_PATH}")
+if(CMAKE_DOC_TARBALL)
+ # Undocumented option to extract and install pre-built documentation.
+ # This is intended for use during packaging of CMake itself.
+ if(CMAKE_DOC_TARBALL MATCHES "/([^/]+)\\.tar\\.gz$")
+ set(dir "${CMAKE_MATCH_1}")
+ else()
+ message(FATAL_ERROR "CMAKE_DOC_TARBALL must end in .tar.gz")
endif()
+ add_custom_command(
+ OUTPUT ${dir}.stamp
+ COMMAND cmake -E remove_directory ${dir}
+ COMMAND cmake -E tar xf ${CMAKE_DOC_TARBALL}
+ COMMAND cmake -E touch ${dir}.stamp
+ DEPENDS ${CMAKE_DOC_TARBALL}
+ )
+ add_custom_target(documentation ALL DEPENDS ${dir}.stamp)
+ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${dir}/
+ DESTINATION . USE_SOURCE_PERMISSIONS)
+else()
+ # Normal documentation build.
+ add_subdirectory(Sphinx)
endif()
-# add the docs for the executables
-ADD_DOCS(ctest ${CMake_SOURCE_DIR}/Utilities/Doxygen/authors.txt)
-ADD_DOCS(cpack ${CMake_SOURCE_DIR}/Utilities/Doxygen/authors.txt)
-ADD_DOCS(ccmake ${CMake_SOURCE_DIR}/Utilities/Doxygen/authors.txt)
-ADD_DOCS(CMakeSetup ${CMake_SOURCE_DIR}/Utilities/Doxygen/doxyfile.in)
-ADD_DOCS(cmake-gui ${CMake_SOURCE_DIR}/Utilities/Doxygen/doxyfile.in)
-
-# add the documentation for cmake itself
-
-get_target_property(CMD cmake LOCATION)
-add_custom_command(
- OUTPUT ${CMake_BINARY_DIR}/Docs/cmake.txt
- COMMAND ${CMD}
- ARGS --copyright ${CMake_BINARY_DIR}/Docs/Copyright.txt
- --help-full ${CMake_BINARY_DIR}/Docs/cmake.txt
- --help-full ${CMake_BINARY_DIR}/Docs/cmake.html
- --help-full ${CMake_BINARY_DIR}/Docs/cmake.1
- --help-full ${CMake_BINARY_DIR}/Docs/cmake.docbook
- --help-policies ${CMake_BINARY_DIR}/Docs/cmake-policies.txt
- --help-policies ${CMake_BINARY_DIR}/Docs/cmake-policies.html
- --help-policies ${CMake_BINARY_DIR}/Docs/cmakepolicies.1
- --help-properties ${CMake_BINARY_DIR}/Docs/cmake-properties.txt
- --help-properties ${CMake_BINARY_DIR}/Docs/cmake-properties.html
- --help-properties ${CMake_BINARY_DIR}/Docs/cmakeprops.1
- --help-variables ${CMake_BINARY_DIR}/Docs/cmake-variables.txt
- --help-variables ${CMake_BINARY_DIR}/Docs/cmake-variables.html
- --help-variables ${CMake_BINARY_DIR}/Docs/cmakevars.1
- --help-modules ${CMake_BINARY_DIR}/Docs/cmake-modules.txt
- --help-modules ${CMake_BINARY_DIR}/Docs/cmake-modules.html
- --help-modules ${CMake_BINARY_DIR}/Docs/cmakemodules.1
- --help-commands ${CMake_BINARY_DIR}/Docs/cmake-commands.txt
- --help-commands ${CMake_BINARY_DIR}/Docs/cmake-commands.html
- --help-commands ${CMake_BINARY_DIR}/Docs/cmakecommands.1
- --help-compatcommands ${CMake_BINARY_DIR}/Docs/cmake-compatcommands.txt
- --help-compatcommands ${CMake_BINARY_DIR}/Docs/cmake-compatcommands.html
- --help-compatcommands ${CMake_BINARY_DIR}/Docs/cmakecompat.1
- DEPENDS cmake
- MAIN_DEPENDENCY ${CMake_SOURCE_DIR}/Utilities/Doxygen/authors.txt
- )
-
-install(FILES ${MAN_FILES} DESTINATION ${CMAKE_MAN_DIR}/man1)
-install(FILES
- ${TEXT_FILES}
- ${HTML_FILES}
- ${DOCBOOK_FILES}
- DESTINATION ${CMAKE_DOC_DIR}
- )
-install(FILES cmake.m4 DESTINATION share/aclocal)
-
-# Drive documentation generation.
-add_custom_target(documentation ALL DEPENDS ${DOC_FILES} ${CMake_BINARY_DIR}/Docs/cmake.txt )
-
-# Documentation testing.
-if(BUILD_TESTING)
- find_package(LibXml2 QUIET)
- if(NOT DEFINED LIBXML2_XMLLINT_EXECUTABLE)
- find_program(LIBXML2_XMLLINT_EXECUTABLE xmllint)
- endif()
- mark_as_advanced(LIBXML2_XMLLINT_EXECUTABLE)
- if(LIBXML2_XMLLINT_EXECUTABLE)
- execute_process(COMMAND ${LIBXML2_XMLLINT_EXECUTABLE} --help
- OUTPUT_VARIABLE _help ERROR_VARIABLE _err)
- if("${_help}" MATCHES "--path" AND "${_help}" MATCHES "--nonet")
- # We provide DTDs in the 'xml' directory so that xmllint can run without
- # network access. Note that xmllints's --path option accepts a
- # space-separated list of url-encoded paths.
- set(_dtd_dir "${CMAKE_CURRENT_SOURCE_DIR}/xml")
- string(REPLACE " " "%20" _dtd_dir "${_dtd_dir}")
- string(REPLACE ":" "%3A" _dtd_dir "${_dtd_dir}")
- add_test(CMake.HTML
- ${LIBXML2_XMLLINT_EXECUTABLE} --valid --noout --nonet
- --path ${_dtd_dir}/xhtml1
- ${HTML_FILES}
- )
- add_test(CMake.DocBook
- ${LIBXML2_XMLLINT_EXECUTABLE} --valid --noout --nonet
- --path ${_dtd_dir}/docbook-4.5
- ${DOCBOOK_FILES}
- )
- endif()
- endif()
+if(WIX_CUSTOM_ACTION_ENABLED)
+ add_subdirectory(Release/WiX)
endif()
diff --git a/Utilities/Doxygen/doc_makeall.sh.in b/Utilities/Doxygen/doc_makeall.sh.in
index ed7b521e4..fceafdd69 100755
--- a/Utilities/Doxygen/doc_makeall.sh.in
+++ b/Utilities/Doxygen/doc_makeall.sh.in
@@ -130,7 +130,7 @@ export RESULTING_HTML_TARZ_ARCHIVE_FILE="$DOXTEMP/$PROJECT_NAME-html.tar.gz"
if test "x@VTK_SOURCE_DIR@" != "x" ; then
if test "x$PERL_PROG" != "xNOTFOUND" ; then
- $PERL_PROG "$PATH_TO_VTK_DOX_SCRIPTS/doc_contributors.pl" \
+ "$PERL_PROG" "$PATH_TO_VTK_DOX_SCRIPTS/doc_contributors.pl" \
--authors "$SOURCE_DIR/Utilities/Doxygen/authors.txt" \
--cachedir "$DOXTEMP/cache" \
--class_group '^(cm[A-Z0-9][A-Za-z0-9]+)\.(?:c|cpp|cxx|h|fl)$' \
@@ -158,7 +158,7 @@ if test "x@VTK_SOURCE_DIR@" != "x" ; then
fi
if test "x$GNUPLOT_PROG" != "xNOTFOUND" ; then
- $GNUPLOT_PROG "$DOXTEMP/contrib/history.plt"
+ "$GNUPLOT_PROG" "$DOXTEMP/contrib/history.plt"
fi
fi
@@ -168,7 +168,7 @@ fi
if test "x$DOXYGEN_PROG" != "xNOTFOUND" ; then
if test "x$RM_PROG" != "xNOTFOUND" ; then
- $RM_PROG -fr "$OUTPUT_DIRECTORY"
+ "$RM_PROG" -fr "$OUTPUT_DIRECTORY"
fi
"$DOXYGEN_PROG" "$DOXYFILE"
@@ -182,7 +182,7 @@ fi
if test "x@VTK_SOURCE_DIR@" != "x" ; then
if test "x$PERL_PROG" != "xNOTFOUND" ; then
- $PERL_PROG "$PATH_TO_VTK_DOX_SCRIPTS/doc_rmpath.pl" \
+ "$PERL_PROG" "$PATH_TO_VTK_DOX_SCRIPTS/doc_rmpath.pl" \
--verbose \
--to "$INTERMEDIATE_DOX_DIR" \
--html "$OUTPUT_DIRECTORY/html"
@@ -198,7 +198,7 @@ if test "x$COMPILE_HTML_HELP" == "xON" ; then
if test "x$HHC_PROG" != "xNOTFOUND" ; then
"$HHC_PROG" index.hhp
if test "x$MV_PROG" != "xNOTFOUND" ; then
- $MV_PROG -f index.chm "$RESULTING_HTML_HELP_FILE"
+ "$MV_PROG" -f index.chm "$RESULTING_HTML_HELP_FILE"
fi
fi
fi
@@ -212,15 +212,15 @@ if test "x$CREATE_HTML_TARZ_ARCHIVE" == "xON" ; then
cd "$OUTPUT_DIRECTORY"
if test "x$TAR_PROG" != "xNOTFOUND" ; then
if test "x$RM_PROG" != "xNOTFOUND" ; then
- $RM_PROG -f html.tar
+ "$RM_PROG" -f html.tar
fi
- $TAR_PROG -cf html.tar html
+ "$TAR_PROG" -cf html.tar html
if test "x$GZIP_PROG" != "xNOTFOUND" ; then
if test "x$RM_PROG" != "xNOTFOUND" ; then
- $RM_PROG -f html.tar.gz
+ "$RM_PROG" -f html.tar.gz
fi
- $GZIP_PROG html.tar
- $MV_PROG -f html.tar.gz "$RESULTING_HTML_TARZ_ARCHIVE_FILE"
+ "$GZIP_PROG" html.tar
+ "$MV_PROG" -f html.tar.gz "$RESULTING_HTML_TARZ_ARCHIVE_FILE"
fi
fi
fi
@@ -230,18 +230,18 @@ fi
# Clean-up.
if test "x$RM_PROG" != "xNOTFOUND" ; then
- $RM_PROG -fr "$INTERMEDIATE_DOX_DIR"
+ "$RM_PROG" -fr "$INTERMEDIATE_DOX_DIR"
if test "x$DOWNLOAD_VTK_TAGFILE" == "xON" ; then
if test "x$VTK_TAGFILE" != "x" ; then
- $RM_PROG -f "$VTK_TAGFILE_DEST_DIR/$VTK_TAGFILE"
+ "$RM_PROG" -f "$VTK_TAGFILE_DEST_DIR/$VTK_TAGFILE"
fi
fi
if test "x$COMPILE_HTML_HELP" == "xON" ; then
if test "x$RESULTING_HTML_HELP_FILE" != "x" ; then
if test "x$ALLOW_ERASE_OUTPUT_DIRECTORY" == "xON" ; then
- $RM_PROG -fr "$OUTPUT_DIRECTORY"
+ "$RM_PROG" -fr "$OUTPUT_DIRECTORY"
fi
fi
fi
diff --git a/Utilities/Doxygen/doxyfile.in b/Utilities/Doxygen/doxyfile.in
index 9743af721..2c131f50b 100644
--- a/Utilities/Doxygen/doxyfile.in
+++ b/Utilities/Doxygen/doxyfile.in
@@ -6,6 +6,10 @@
PROJECT_NAME = CMake
FULL_PATH_NAMES = YES
+STRIP_FROM_PATH = \
+ "@CMake_SOURCE_DIR@/Source/" \
+ "@CMake_BINARY_DIR@/Source/"
+
WARN_IF_UNDOCUMENTED = NO
GENERATE_TREEVIEW = NO
@@ -40,6 +44,7 @@ OUTPUT_DIRECTORY = "@CMake_BINARY_DIR@/Utilities/Doxygen/doc"
INPUT = \
"@CMake_SOURCE_DIR@/Source" \
"@CMake_SOURCE_DIR@/Source/CPack" \
+ "@CMake_SOURCE_DIR@/Source/CPack/IFW" \
"@CMake_SOURCE_DIR@/Source/CTest" \
"@CMake_SOURCE_DIR@/Source/CursesDialog" \
"@CMake_SOURCE_DIR@/Source/MFCDialog" \
diff --git a/Utilities/KWIML/.gitattributes b/Utilities/KWIML/.gitattributes
new file mode 100644
index 000000000..ecbf2196c
--- /dev/null
+++ b/Utilities/KWIML/.gitattributes
@@ -0,0 +1 @@
+*.md conflict-marker-size=78
diff --git a/Utilities/KWIML/ABI.h.in b/Utilities/KWIML/ABI.h.in
deleted file mode 100644
index b71cdfb9f..000000000
--- a/Utilities/KWIML/ABI.h.in
+++ /dev/null
@@ -1,492 +0,0 @@
-/*============================================================================
- Kitware Information Macro Library
- Copyright 2010-2011 Kitware, Inc.
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of Kitware, Inc. nor the names of its contributors
- may be used to endorse or promote products derived from this
- software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-============================================================================*/
-#ifndef @KWIML@_ABI_H
-#define @KWIML@_ABI_H
-/*
-This header defines macros with information about the C ABI.
-Only information that can be determined using the preprocessor at
-compilation time is available. No try-compile results may be added
-here. Instead we memorize results on platforms of interest.
-
-An includer may optionally define the following macros to suppress errors:
-
- @KWIML@_ABI_NO_VERIFY = skip verification declarations
- @KWIML@_ABI_NO_ERROR_CHAR_SIGN = signedness of 'char' may be unknown
- @KWIML@_ABI_NO_ERROR_LONG_LONG = existence of 'long long' may be unknown
- @KWIML@_ABI_NO_ERROR_ENDIAN = byte order of CPU may be unknown
-
-An includer may test the following macros after inclusion:
-
- @KWIML@_ABI_SIZEOF_DATA_PTR = sizeof(void*)
- @KWIML@_ABI_SIZEOF_CODE_PTR = sizeof(void(*)(void))
- @KWIML@_ABI_SIZEOF_FLOAT = sizeof(float)
- @KWIML@_ABI_SIZEOF_DOUBLE = sizeof(double)
- @KWIML@_ABI_SIZEOF_CHAR = sizeof(char)
- @KWIML@_ABI_SIZEOF_SHORT = sizeof(short)
- @KWIML@_ABI_SIZEOF_INT = sizeof(int)
- @KWIML@_ABI_SIZEOF_LONG = sizeof(long)
-
- @KWIML@_ABI_SIZEOF_LONG_LONG = sizeof(long long) or 0 if not a type
- Undefined if existence is unknown and error suppression macro
- @KWIML@_ABI_NO_ERROR_LONG_LONG was defined.
-
- @KWIML@_ABI_SIZEOF___INT64 = 8 if '__int64' exists or 0 if not
- Undefined if existence is unknown.
-
- @KWIML@_ABI___INT64_IS_LONG = 1 if '__int64' is 'long' (same type)
- Undefined otherwise.
- @KWIML@_ABI___INT64_IS_LONG_LONG = 1 if '__int64' is 'long long' (same type)
- Undefined otherwise.
- @KWIML@_ABI___INT64_IS_UNIQUE = 1 if '__int64' is a distinct type
- Undefined otherwise.
-
- @KWIML@_ABI_CHAR_IS_UNSIGNED = 1 if 'char' is unsigned, else undefined
- @KWIML@_ABI_CHAR_IS_SIGNED = 1 if 'char' is signed, else undefined
- One of these is defined unless signedness of 'char' is unknown and
- error suppression macro @KWIML@_ABI_NO_ERROR_CHAR_SIGN was defined.
-
- @KWIML@_ABI_ENDIAN_ID_BIG = id for big-endian (always defined)
- @KWIML@_ABI_ENDIAN_ID_LITTLE = id for little-endian (always defined)
- @KWIML@_ABI_ENDIAN_ID = id of byte order of target CPU
- Defined to @KWIML@_ABI_ENDIAN_ID_BIG or @KWIML@_ABI_ENDIAN_ID_LITTLE
- unless byte order is unknown and error suppression macro
- @KWIML@_ABI_NO_ERROR_ENDIAN was defined.
-
-We verify most results using dummy "extern" declarations that are
-invalid if the macros are wrong. Verification is disabled if
-suppression macro @KWIML@_ABI_NO_VERIFY was defined.
-*/
-
-/*--------------------------------------------------------------------------*/
-#if !defined(@KWIML@_ABI_SIZEOF_DATA_PTR)
-# if defined(__SIZEOF_POINTER__)
-# define @KWIML@_ABI_SIZEOF_DATA_PTR __SIZEOF_POINTER__
-# elif defined(_SIZE_PTR)
-# define @KWIML@_ABI_SIZEOF_DATA_PTR (_SIZE_PTR >> 3)
-# elif defined(_LP64) || defined(__LP64__)
-# define @KWIML@_ABI_SIZEOF_DATA_PTR 8
-# elif defined(_ILP32)
-# define @KWIML@_ABI_SIZEOF_DATA_PTR 4
-# elif defined(__64BIT__) /* IBM XL */
-# define @KWIML@_ABI_SIZEOF_DATA_PTR 8
-# elif defined(_M_X64)
-# define @KWIML@_ABI_SIZEOF_DATA_PTR 8
-# elif defined(__ia64)
-# define @KWIML@_ABI_SIZEOF_DATA_PTR 8
-# elif defined(__sparcv9)
-# define @KWIML@_ABI_SIZEOF_DATA_PTR 8
-# elif defined(__x86_64) || defined(__x86_64__)
-# define @KWIML@_ABI_SIZEOF_DATA_PTR 8
-# elif defined(__amd64) || defined(__amd64__)
-# define @KWIML@_ABI_SIZEOF_DATA_PTR 8
-# elif defined(__i386) || defined(__i386__)
-# define @KWIML@_ABI_SIZEOF_DATA_PTR 4
-# endif
-#endif
-#if !defined(@KWIML@_ABI_SIZEOF_DATA_PTR)
-# define @KWIML@_ABI_SIZEOF_DATA_PTR 4
-#endif
-#if !defined(@KWIML@_ABI_SIZEOF_CODE_PTR)
-# define @KWIML@_ABI_SIZEOF_CODE_PTR @KWIML@_ABI_SIZEOF_DATA_PTR
-#endif
-
-/*--------------------------------------------------------------------------*/
-#if !defined(@KWIML@_ABI_SIZEOF_CHAR)
-# define @KWIML@_ABI_SIZEOF_CHAR 1
-#endif
-
-#if !defined(@KWIML@_ABI_CHAR_IS_UNSIGNED) && !defined(@KWIML@_ABI_CHAR_IS_SIGNED)
-# if defined(__CHAR_UNSIGNED__) /* GNU, some IBM XL, others? */
-# define @KWIML@_ABI_CHAR_IS_UNSIGNED 1
-# elif defined(_CHAR_UNSIGNED) /* Intel, IBM XL, MSVC, Borland, others? */
-# define @KWIML@_ABI_CHAR_IS_UNSIGNED 1
-# elif defined(_CHAR_SIGNED) /* IBM XL, others? */
-# define @KWIML@_ABI_CHAR_IS_SIGNED 1
-# elif defined(__CHAR_SIGNED__) /* IBM XL, Watcom, others? */
-# define @KWIML@_ABI_CHAR_IS_SIGNED 1
-# elif defined(__SIGNED_CHARS__) /* EDG, Intel, SGI MIPSpro */
-# define @KWIML@_ABI_CHAR_IS_SIGNED 1
-# elif defined(_CHAR_IS_SIGNED) /* Some SunPro, others? */
-# define @KWIML@_ABI_CHAR_IS_SIGNED 1
-# elif defined(_CHAR_IS_UNSIGNED) /* SunPro, others? */
-# define @KWIML@_ABI_CHAR_IS_UNSIGNED 1
-# elif defined(__GNUC__) /* GNU default */
-# define @KWIML@_ABI_CHAR_IS_SIGNED 1
-# elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* SunPro default */
-# define @KWIML@_ABI_CHAR_IS_SIGNED 1
-# elif defined(__HP_cc) || defined(__HP_aCC) /* HP default (unless +uc) */
-# define @KWIML@_ABI_CHAR_IS_SIGNED 1
-# elif defined(_SGI_COMPILER_VERSION) /* SGI MIPSpro default */
-# define @KWIML@_ABI_CHAR_IS_UNSIGNED 1
-# elif defined(__PGIC__) /* PGI default */
-# define @KWIML@_ABI_CHAR_IS_SIGNED 1
-# elif defined(_MSC_VER) /* MSVC default */
-# define @KWIML@_ABI_CHAR_IS_SIGNED 1
-# elif defined(__WATCOMC__) /* Watcom default */
-# define @KWIML@_ABI_CHAR_IS_UNSIGNED 1
-# elif defined(__BORLANDC__) /* Borland default */
-# define @KWIML@_ABI_CHAR_IS_SIGNED 1
-# elif defined(__hpux) /* Old HP: no __HP_cc/__HP_aCC/__GNUC__ above */
-# define @KWIML@_ABI_CHAR_IS_SIGNED 1 /* (unless +uc) */
-# endif
-#endif
-#if !defined(@KWIML@_ABI_CHAR_IS_UNSIGNED) && !defined(@KWIML@_ABI_CHAR_IS_SIGNED) \
- && !defined(@KWIML@_ABI_NO_ERROR_CHAR_SIGN)
-# error "Signedness of 'char' unknown."
-#endif
-
-/*--------------------------------------------------------------------------*/
-#if !defined(@KWIML@_ABI_SIZEOF_SHORT)
-# if defined(__SIZEOF_SHORT__)
-# define @KWIML@_ABI_SIZEOF_SHORT __SIZEOF_SHORT__
-# endif
-#endif
-#if !defined(@KWIML@_ABI_SIZEOF_SHORT)
-# define @KWIML@_ABI_SIZEOF_SHORT 2
-#endif
-
-/*--------------------------------------------------------------------------*/
-#if !defined(@KWIML@_ABI_SIZEOF_INT)
-# if defined(__SIZEOF_INT__)
-# define @KWIML@_ABI_SIZEOF_INT __SIZEOF_INT__
-# elif defined(_SIZE_INT)
-# define @KWIML@_ABI_SIZEOF_INT (_SIZE_INT >> 3)
-# endif
-#endif
-#if !defined(@KWIML@_ABI_SIZEOF_INT)
-# define @KWIML@_ABI_SIZEOF_INT 4
-#endif
-
-/*--------------------------------------------------------------------------*/
-#if !defined(@KWIML@_ABI_SIZEOF_LONG)
-# if defined(__SIZEOF_LONG__)
-# define @KWIML@_ABI_SIZEOF_LONG __SIZEOF_LONG__
-# elif defined(_SIZE_LONG)
-# define @KWIML@_ABI_SIZEOF_LONG (_SIZE_LONG >> 3)
-# elif defined(__LONG_MAX__)
-# if __LONG_MAX__ == 0x7fffffff
-# define @KWIML@_ABI_SIZEOF_LONG 4
-# elif __LONG_MAX__>>32 == 0x7fffffff
-# define @KWIML@_ABI_SIZEOF_LONG 8
-# endif
-# elif defined(_MSC_VER) /* MSVC and Intel on Windows */
-# define @KWIML@_ABI_SIZEOF_LONG 4
-# endif
-#endif
-#if !defined(@KWIML@_ABI_SIZEOF_LONG)
-# define @KWIML@_ABI_SIZEOF_LONG @KWIML@_ABI_SIZEOF_DATA_PTR
-#endif
-
-/*--------------------------------------------------------------------------*/
-#if !defined(@KWIML@_ABI_SIZEOF_LONG_LONG)
-# if defined(__SIZEOF_LONG_LONG__)
-# define @KWIML@_ABI_SIZEOF_LONG_LONG __SIZEOF_LONG_LONG__
-# elif defined(__LONG_LONG_MAX__)
-# if __LONG_LONG_MAX__ == 0x7fffffff
-# define @KWIML@_ABI_SIZEOF_LONG_LONG 4
-# elif __LONG_LONG_MAX__>>32 == 0x7fffffff
-# define @KWIML@_ABI_SIZEOF_LONG_LONG 8
-# endif
-# endif
-#endif
-#if !defined(@KWIML@_ABI_SIZEOF_LONG_LONG)
-# if defined(_LONGLONG) /* SGI, some GNU, perhaps others. */ \
- && !defined(_MSC_VER)
-# define @KWIML@_ABI_SIZEOF_LONG_LONG 8
-# elif defined(_LONG_LONG) /* IBM XL, perhaps others. */
-# define @KWIML@_ABI_SIZEOF_LONG_LONG 8
-# elif defined(__NO_LONG_LONG) /* EDG */
-# define @KWIML@_ABI_SIZEOF_LONG_LONG 0
-# elif defined(__cplusplus) && __cplusplus > 199711L /* C++0x */
-# define @KWIML@_ABI_SIZEOF_LONG_LONG 8
-# elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
-# define @KWIML@_ABI_SIZEOF_LONG_LONG 8
-# elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* SunPro */
-# define @KWIML@_ABI_SIZEOF_LONG_LONG 8
-# elif defined(__HP_cc) || defined(__HP_aCC) /* HP */
-# define @KWIML@_ABI_SIZEOF_LONG_LONG 8
-# elif defined(__PGIC__) /* PGI */
-# define @KWIML@_ABI_SIZEOF_LONG_LONG 8
-# elif defined(__WATCOMC__) /* Watcom */
-# define @KWIML@_ABI_SIZEOF_LONG_LONG 8
-# elif defined(__INTEL_COMPILER) /* Intel */
-# define @KWIML@_ABI_SIZEOF_LONG_LONG 8
-# elif defined(__BORLANDC__) /* Borland */
-# if __BORLANDC__ >= 0x0560
-# define @KWIML@_ABI_SIZEOF_LONG_LONG 8
-# else
-# define @KWIML@_ABI_SIZEOF_LONG_LONG 0
-# endif
-# elif defined(_MSC_VER) /* Microsoft */
-# if _MSC_VER >= 1310
-# define @KWIML@_ABI_SIZEOF_LONG_LONG 8
-# else
-# define @KWIML@_ABI_SIZEOF_LONG_LONG 0
-# endif
-# elif defined(__GNUC__) /* GNU */
-# define @KWIML@_ABI_SIZEOF_LONG_LONG 8
-# elif defined(__hpux) /* Old HP: no __HP_cc/__HP_aCC/__GNUC__ above */
-# define @KWIML@_ABI_SIZEOF_LONG_LONG 8
-# endif
-#endif
-#if !defined(@KWIML@_ABI_SIZEOF_LONG_LONG) && !defined(@KWIML@_ABI_NO_ERROR_LONG_LONG)
-# error "Existence of 'long long' unknown."
-#endif
-
-/*--------------------------------------------------------------------------*/
-#if !defined(@KWIML@_ABI_SIZEOF___INT64)
-# if defined(__INTEL_COMPILER)
-# define @KWIML@_ABI_SIZEOF___INT64 8
-# elif defined(_MSC_VER)
-# define @KWIML@_ABI_SIZEOF___INT64 8
-# elif defined(__BORLANDC__)
-# define @KWIML@_ABI_SIZEOF___INT64 8
-# else
-# define @KWIML@_ABI_SIZEOF___INT64 0
-# endif
-#endif
-
-#if defined(@KWIML@_ABI_SIZEOF___INT64) && @KWIML@_ABI_SIZEOF___INT64 > 0
-# if @KWIML@_ABI_SIZEOF_LONG == 8
-# define @KWIML@_ABI___INT64_IS_LONG 1
-# elif defined(@KWIML@_ABI_SIZEOF_LONG_LONG) && @KWIML@_ABI_SIZEOF_LONG_LONG == 8
-# define @KWIML@_ABI___INT64_IS_LONG_LONG 1
-# else
-# define @KWIML@_ABI___INT64_IS_UNIQUE 1
-# endif
-#endif
-
-/*--------------------------------------------------------------------------*/
-#if !defined(@KWIML@_ABI_SIZEOF_FLOAT)
-# if defined(__SIZEOF_FLOAT__)
-# define @KWIML@_ABI_SIZEOF_FLOAT __SIZEOF_FLOAT__
-# endif
-#endif
-#if !defined(@KWIML@_ABI_SIZEOF_FLOAT)
-# define @KWIML@_ABI_SIZEOF_FLOAT 4
-#endif
-
-/*--------------------------------------------------------------------------*/
-#if !defined(@KWIML@_ABI_SIZEOF_DOUBLE)
-# if defined(__SIZEOF_DOUBLE__)
-# define @KWIML@_ABI_SIZEOF_DOUBLE __SIZEOF_DOUBLE__
-# endif
-#endif
-#if !defined(@KWIML@_ABI_SIZEOF_DOUBLE)
-# define @KWIML@_ABI_SIZEOF_DOUBLE 8
-#endif
-
-/*--------------------------------------------------------------------------*/
-/* Identify possible endian cases. The macro @KWIML@_ABI_ENDIAN_ID will be
- defined to one of these, or undefined if unknown. */
-#if !defined(@KWIML@_ABI_ENDIAN_ID_BIG)
-# define @KWIML@_ABI_ENDIAN_ID_BIG 4321
-#endif
-#if !defined(@KWIML@_ABI_ENDIAN_ID_LITTLE)
-# define @KWIML@_ABI_ENDIAN_ID_LITTLE 1234
-#endif
-#if @KWIML@_ABI_ENDIAN_ID_BIG == @KWIML@_ABI_ENDIAN_ID_LITTLE
-# error "@KWIML@_ABI_ENDIAN_ID_BIG == @KWIML@_ABI_ENDIAN_ID_LITTLE"
-#endif
-
-#if defined(@KWIML@_ABI_ENDIAN_ID) /* Skip #elif cases if already defined. */
-
-/* Use dedicated symbols if the compiler defines them. Do this first
- because some architectures allow runtime byte order selection by
- the operating system (values for such architectures below are
- guesses for compilers that do not define a dedicated symbol).
- Ensure that only one is defined in case the platform or a header
- defines both as possible values for some third symbol. */
-#elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_BIG
-#elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_LITTLE
-#elif defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_BIG
-#elif defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_LITTLE
-
-/* Alpha */
-#elif defined(__alpha) || defined(__alpha__) || defined(_M_ALPHA)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_LITTLE
-
-/* Arm */
-#elif defined(__arm__)
-# if !defined(__ARMEB__)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_LITTLE
-# else
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_BIG
-# endif
-
-/* Intel x86 */
-#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_LITTLE
-#elif defined(_X86_) || defined(__THW_INTEL__) || defined(__I86__)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_LITTLE
-#elif defined(__MWERKS__) && defined(__INTEL__)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_LITTLE
-
-/* Intel x86-64 */
-#elif defined(__x86_64) || defined(__x86_64__) || defined(_M_X64)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_LITTLE
-#elif defined(__amd64) || defined(__amd64__)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_LITTLE
-
-/* Intel Architecture-64 (Itanium) */
-#elif defined(__ia64) || defined(__ia64__)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_LITTLE
-#elif defined(_IA64) || defined(__IA64__) || defined(_M_IA64)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_LITTLE
-
-/* PowerPC */
-#elif defined(__powerpc) || defined(__powerpc__)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_BIG
-#elif defined(__ppc) || defined(__ppc__) || defined(__POWERPC__)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_BIG
-
-/* SPARC */
-#elif defined(__sparc) || defined(__sparc__)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_BIG
-
-/* HP/PA RISC */
-#elif defined(__hppa) || defined(__hppa__)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_BIG
-
-/* Motorola 68k */
-#elif defined(__m68k__) || defined(M68000)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_BIG
-
-/* MIPSel (MIPS little endian) */
-#elif defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_LITTLE
-
-/* MIPSeb (MIPS big endian) */
-#elif defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_BIG
-
-/* MIPS (fallback, big endian) */
-#elif defined(__mips) || defined(__mips__) || defined(__MIPS__)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_BIG
-
-/* RS/6000 */
-#elif defined(__THW_RS600) || defined(_IBMR2) || defined(_POWER)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_BIG
-#elif defined(_ARCH_PWR) || defined(_ARCH_PWR2)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_BIG
-
-/* System/370 */
-#elif defined(__370__) || defined(__THW_370__)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_BIG
-
-/* System/390 */
-#elif defined(__s390__) || defined(__s390x__)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_BIG
-
-/* z/Architecture */
-#elif defined(__SYSC_ZARCH__)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_BIG
-
-/* VAX */
-#elif defined(__vax__)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_BIG
-
-/* Aarch64 */
-#elif defined(__aarch64__)
-# if !defined(__AARCH64EB__)
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_LITTLE
-# else
-# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_BIG
-# endif
-
-/* Unknown CPU */
-#elif !defined(@KWIML@_ABI_NO_ERROR_ENDIAN)
-# error "Byte order of target CPU unknown."
-#endif
-
-/*--------------------------------------------------------------------------*/
-#if !defined(@KWIML@_ABI_NO_VERIFY)
-#define @KWIML@_ABI__VERIFY(n, x, y) extern int (*n)[x]; extern int (*n)[y]
-#define @KWIML@_ABI__VERIFY2(n, x, y) extern int (*n)(x*); extern int (*n)(y*)
-#if defined(__cplusplus)
-# define @KWIML@_ABI__VERIFY3(n, x, y) extern int* n(x*); extern char* n(y*)
-#else
-# define @KWIML@_ABI__VERIFY3(n, x, y) extern int* n(x*) /* TODO: possible? */
-#endif
-#define @KWIML@_ABI__VERIFY_BOOL(m, b) @KWIML@_ABI__VERIFY(m##__VERIFY__, 2, (b)?2:3)
-#define @KWIML@_ABI__VERIFY_SIZE(m, t) @KWIML@_ABI__VERIFY(m##__VERIFY__, m, sizeof(t))
-#define @KWIML@_ABI__VERIFY_SAME(m, x, y) @KWIML@_ABI__VERIFY2(m##__VERIFY__, x, y)
-#define @KWIML@_ABI__VERIFY_DIFF(m, x, y) @KWIML@_ABI__VERIFY3(m##__VERIFY__, x, y)
-
-@KWIML@_ABI__VERIFY_SIZE(@KWIML@_ABI_SIZEOF_DATA_PTR, int*);
-@KWIML@_ABI__VERIFY_SIZE(@KWIML@_ABI_SIZEOF_CODE_PTR, int(*)(int));
-@KWIML@_ABI__VERIFY_SIZE(@KWIML@_ABI_SIZEOF_CHAR, char);
-@KWIML@_ABI__VERIFY_SIZE(@KWIML@_ABI_SIZEOF_SHORT, short);
-@KWIML@_ABI__VERIFY_SIZE(@KWIML@_ABI_SIZEOF_INT, int);
-@KWIML@_ABI__VERIFY_SIZE(@KWIML@_ABI_SIZEOF_LONG, long);
-#if defined(@KWIML@_ABI_SIZEOF_LONG_LONG) && @KWIML@_ABI_SIZEOF_LONG_LONG > 0
-@KWIML@_ABI__VERIFY_SIZE(@KWIML@_ABI_SIZEOF_LONG_LONG, long long);
-#endif
-#if defined(@KWIML@_ABI_SIZEOF___INT64) && @KWIML@_ABI_SIZEOF___INT64 > 0
-@KWIML@_ABI__VERIFY_SIZE(@KWIML@_ABI_SIZEOF___INT64, __int64);
-#endif
-@KWIML@_ABI__VERIFY_SIZE(@KWIML@_ABI_SIZEOF_FLOAT, float);
-@KWIML@_ABI__VERIFY_SIZE(@KWIML@_ABI_SIZEOF_DOUBLE, double);
-
-#if defined(@KWIML@_ABI___INT64_IS_LONG)
-@KWIML@_ABI__VERIFY_SAME(@KWIML@_ABI___INT64_IS_LONG, __int64, long);
-#elif defined(@KWIML@_ABI___INT64_IS_LONG_LONG)
-@KWIML@_ABI__VERIFY_SAME(@KWIML@_ABI___INT64_IS_LONG_LONG, __int64, long long);
-#elif defined(@KWIML@_ABI_SIZEOF___INT64) && @KWIML@_ABI_SIZEOF___INT64 > 0
-@KWIML@_ABI__VERIFY_DIFF(@KWIML@_ABI___INT64_NOT_LONG, __int64, long);
-# if defined(@KWIML@_ABI_SIZEOF_LONG_LONG) && @KWIML@_ABI_SIZEOF_LONG_LONG > 0
-@KWIML@_ABI__VERIFY_DIFF(@KWIML@_ABI___INT64_NOT_LONG_LONG, __int64, long long);
-# endif
-#endif
-
-#if defined(@KWIML@_ABI_CHAR_IS_UNSIGNED)
-@KWIML@_ABI__VERIFY_BOOL(@KWIML@_ABI_CHAR_IS_UNSIGNED, (char)0x80 > 0);
-#elif defined(@KWIML@_ABI_CHAR_IS_SIGNED)
-@KWIML@_ABI__VERIFY_BOOL(@KWIML@_ABI_CHAR_IS_SIGNED, (char)0x80 < 0);
-#endif
-
-#undef @KWIML@_ABI__VERIFY_DIFF
-#undef @KWIML@_ABI__VERIFY_SAME
-#undef @KWIML@_ABI__VERIFY_SIZE
-#undef @KWIML@_ABI__VERIFY_BOOL
-#undef @KWIML@_ABI__VERIFY3
-#undef @KWIML@_ABI__VERIFY2
-#undef @KWIML@_ABI__VERIFY
-
-#endif
-
-#endif
diff --git a/Utilities/KWIML/CMakeLists.txt b/Utilities/KWIML/CMakeLists.txt
index 62b6fffb7..15e65e5c7 100644
--- a/Utilities/KWIML/CMakeLists.txt
+++ b/Utilities/KWIML/CMakeLists.txt
@@ -1,52 +1,29 @@
-#=============================================================================
-# Kitware Information Macro Library
-# Copyright 2010-2011 Kitware, Inc.
#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
+# Copyright Kitware, Inc.
+# Distributed under the OSI-approved BSD 3-Clause License.
+# See accompanying file Copyright.txt for details.
#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-
-# Import the KWIML directory tree into a subdirectory under a parent
-# project and configure the library as follows:
-#
-# set(KWIML myIML)
-# subdirs(KWIML)
-#
-# Optional settings are as follows:
-#
-# KWIML_HEADER_ROOT = build tree directory to hold KWIML headers.
-# Headers will go in a directory called "${KWIML}" under this root.
-# For example:
-#
-# set(KWIML_HEADER_ROOT ${PROJECT_BINARY_DIR})
-# include_directories(${PROJECT_BINARY_DIR})
-#
-# KWIML_INSTALL_INCLUDE_DIR = install KWIML with "make install"
-# Specify a value relative to the install prefix and do NOT start with '/'.
-# KWIML_INSTALL_INCLUDE_OPTIONS = extra header installation options
-# Specify options for the install(FILES) command.
-#
-# KWIML_LABELS_TEST = list of labels for KWIML tests
-
-cmake_minimum_required(VERSION 2.6.3 FATAL_ERROR)
-
-#-----------------------------------------------------------------------------
-if(NOT DEFINED KWIML)
- if(NOT "${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
- message(FATAL_ERROR "Set KWIML namespace in parent directory!")
- endif()
- set(KWIML KWIML)
- set(KWIML_STANDALONE 1)
+if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
+ cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
+ set(kwiml_standalone 1)
project(KWIML)
include(CTest)
mark_as_advanced(BUILD_TESTING)
+ if(BUILD_TESTING)
+ set(KWIML_TEST_ENABLE 1)
+ endif()
+ if(NOT DEFINED KWIML_INSTALL_INCLUDE_DIR)
+ set(KWIML_INSTALL_INCLUDE_DIR include)
+ endif()
+ set(KWIML_INCLUDE_PREFIX kwiml)
+else()
+ cmake_minimum_required(VERSION 2.8.2 FATAL_ERROR)
+ set(kwiml_standalone 0)
+ if(KWIML_INSTALL_INCLUDE_DIR AND NOT DEFINED KWIML_INCLUDE_PREFIX)
+ message(FATAL_ERROR "Host project must set KWIML_INCLUDE_PREFIX")
+ endif()
endif()
-#-----------------------------------------------------------------------------
get_property(KWIML_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
foreach(lang ${KWIML_LANGUAGES})
set(KWIML_LANGUAGE_${lang} 1)
@@ -55,25 +32,73 @@ if(NOT KWIML_LANGUAGE_C AND NOT KWIML_LANGUAGE_CXX)
set(BUILD_TESTING OFF)
endif()
-#-----------------------------------------------------------------------------
-if(NOT KWIML_HEADER_ROOT)
- set(KWIML_HEADER_ROOT "${PROJECT_BINARY_DIR}")
+if(KWIML_INSTALL_INCLUDE_DIR)
+ install(FILES
+ include/kwiml/abi.h
+ include/kwiml/int.h
+ DESTINATION ${KWIML_INSTALL_INCLUDE_DIR}/${KWIML_INCLUDE_PREFIX}
+ ${KWIML_INSTALL_INCLUDE_OPTIONS}
+ )
endif()
-set(KWIML_HEADER_DIR "${KWIML_HEADER_ROOT}/${KWIML}")
-include_directories(${KWIML_HEADER_ROOT})
-#-----------------------------------------------------------------------------
-foreach(h ABI INT)
- set(header ${KWIML_HEADER_DIR}/${h}.h)
- configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${h}.h.in ${header} @ONLY)
- if(KWIML_INSTALL_INCLUDE_DIR)
- install(FILES ${header}
- DESTINATION ${KWIML_INSTALL_INCLUDE_DIR}/${KWIML}
- ${KWIML_INSTALL_INCLUDE_OPTIONS})
- endif()
-endforeach()
-
-#-----------------------------------------------------------------------------
-if(BUILD_TESTING)
+if(KWIML_TEST_ENABLE)
add_subdirectory(test)
endif()
+
+if(NOT kwiml_standalone)
+ return()
+endif()
+
+#----------------------------------------------------------------------------
+set(KWIML_VERSION 1.0.0)
+if(KWIML_VERSION MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)")
+ set(KWIML_VERSION_MAJOR "${CMAKE_MATCH_1}")
+ set(KWIML_VERSION_MINOR "${CMAKE_MATCH_2}")
+ set(KWIML_VERSION_PATCH "${CMAKE_MATCH_3}")
+ math(EXPR KWIML_VERSION_DECIMAL
+ "${KWIML_VERSION_MAJOR}*1000000 + ${KWIML_VERSION_MINOR}*1000 + ${KWIML_VERSION_PATCH}")
+else()
+ message(FATAL_ERROR "Failed to parse KWIML_VERSION='${KWIML_VERSION}'")
+endif()
+
+configure_file(src/version.h.in include/kwiml/version.h @ONLY)
+install(FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/include/kwiml/version.h
+ DESTINATION ${KWIML_INSTALL_INCLUDE_DIR}/kwiml
+ )
+
+if(NOT KWIML_INSTALL_PACKAGE_DIR)
+ set(KWIML_INSTALL_PACKAGE_DIR share/cmake/kwiml-${KWIML_VERSION_MAJOR}.${KWIML_VERSION_MINOR})
+endif()
+
+add_library(kwiml INTERFACE)
+target_include_directories(kwiml INTERFACE
+ $<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${KWIML_INSTALL_INCLUDE_DIR}>
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
+ )
+export(TARGETS kwiml
+ NAMESPACE kwiml::
+ FILE kwiml-targets.cmake
+ )
+install(TARGETS kwiml
+ DESTINATION lib
+ EXPORT kwiml-targets
+ )
+install(EXPORT kwiml-targets
+ NAMESPACE kwiml::
+ DESTINATION ${KWIML_INSTALL_PACKAGE_DIR}
+ )
+
+configure_file(src/kwiml-config.cmake.in kwiml-config.cmake @ONLY)
+include(CMakePackageConfigHelpers)
+write_basic_package_version_file(
+ "${CMAKE_CURRENT_BINARY_DIR}/kwiml-config-version.cmake"
+ VERSION ${KWIML_VERSION}
+ COMPATIBILITY AnyNewerVersion
+ )
+install(FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/kwiml-config.cmake
+ ${CMAKE_CURRENT_BINARY_DIR}/kwiml-config-version.cmake
+ DESTINATION ${KWIML_INSTALL_PACKAGE_DIR}
+ )
diff --git a/Utilities/KWIML/Copyright.txt b/Utilities/KWIML/Copyright.txt
index c1e5ebc3f..a6204b0c2 100644
--- a/Utilities/KWIML/Copyright.txt
+++ b/Utilities/KWIML/Copyright.txt
@@ -1,5 +1,5 @@
Kitware Information Macro Library
-Copyright 2010-2011 Kitware, Inc.
+Copyright 2010-2015 Kitware, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/Utilities/KWIML/INT.h.in b/Utilities/KWIML/INT.h.in
deleted file mode 100644
index d2eda6387..000000000
--- a/Utilities/KWIML/INT.h.in
+++ /dev/null
@@ -1,861 +0,0 @@
-/*============================================================================
- Kitware Information Macro Library
- Copyright 2010-2011 Kitware, Inc.
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of Kitware, Inc. nor the names of its contributors
- may be used to endorse or promote products derived from this
- software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-============================================================================*/
-#ifndef @KWIML@_INT_H
-#define @KWIML@_INT_H
-/*
-This header defines macros with information about sized integer types.
-Only information that can be determined using the preprocessor at
-compilation time is available. No try-compile results may be added
-here. Instead we memorize results on platforms of interest.
-
-An includer may optionally define the following macros to suppress errors:
-
-Input:
- @KWIML@_INT_NO_VERIFY = skip verification declarations
- @KWIML@_INT_NO_ERROR_INT64_T = type '@KWIML@_INT_int64_t' is optional (*)
- @KWIML@_INT_NO_ERROR_UINT64_T = type '@KWIML@_INT_uint64_t' is optional (*)
- @KWIML@_INT_NO_ERROR_INTPTR_T = type '@KWIML@_INT_intptr_t' is optional (*)
- @KWIML@_INT_NO_ERROR_UINTPTR_T = type '@KWIML@_INT_uintptr_t' is optional (*)
-
-An includer may optionally define the following macros to override defaults.
-Either way, an includer may test these macros after inclusion:
-
- @KWIML@_INT_HAVE_STDINT_H = include <stdint.h>
- @KWIML@_INT_NO_STDINT_H = do not include <stdint.h>
- @KWIML@_INT_HAVE_INTTYPES_H = include <inttypes.h>
- @KWIML@_INT_NO_INTTYPES_H = do not include <inttypes.h>
-
-An includer may test the following macros after inclusion:
-
- @KWIML@_INT_HAVE_INT#_T = type 'int#_t' is available
- @KWIML@_INT_HAVE_UINT#_T = type 'uint#_t' is available
- # = 8, 16, 32, 64, PTR
-
- @KWIML@_INT_int#_t = signed integer type exactly # bits wide
- @KWIML@_INT_uint#_t = unsigned integer type exactly # bits wide
- # = 8, 16, 32, 64 (*), ptr (*)
-
- @KWIML@_INT_NO_INT64_T = type '@KWIML@_INT_int64_t' not available
- @KWIML@_INT_NO_UINT64_T = type '@KWIML@_INT_uint64_t' not available
- @KWIML@_INT_NO_INTPTR_T = type '@KWIML@_INT_intptr_t' not available
- @KWIML@_INT_NO_UINTPTR_T = type '@KWIML@_INT_uintptr_t' not available
-
- @KWIML@_INT_INT#_C(c) = signed integer constant at least # bits wide
- @KWIML@_INT_UINT#_C(c) = unsigned integer constant at least # bits wide
- # = 8, 16, 32, 64 (*)
-
- @KWIML@_INT_<fmt># = print or scan format, <fmt> in table below
- # = 8, 16, 32, 64, PTR (*)
-
- signed unsigned
- ----------- ------------------------------
- | decimal | decimal octal hexadecimal |
- print | PRId PRIi | PRIu PRIo PRIx PRIX |
- scan | SCNd SCNi | SCNu SCNo SCNx |
- ----------- ------------------------------
-
- The SCN*8 and SCN*64 format macros will not be defined on systems
- with scanf implementations known not to support them.
-
- @KWIML@_INT_BROKEN_<fmt># = macro <fmt># is incorrect if defined
- Some compilers define integer format macros incorrectly for their
- own formatted print/scan implementations.
-
- @KWIML@_INT_BROKEN_INT#_C = macro INT#_C is incorrect if defined
- @KWIML@_INT_BROKEN_UINT#_C = macro UINT#_C is incorrect if defined
- Some compilers define integer constant macros incorrectly and
- cannot handle literals as large as the integer type or even
- produce bad preprocessor syntax.
-
- @KWIML@_INT_BROKEN_INT8_T = type 'int8_t' is available but incorrect
- Some compilers have a flag to make 'char' (un)signed but do not account
- for it while defining int8_t in the non-default case.
-
- The broken cases do not affect correctness of the macros documented above.
-*/
-
-#include "ABI.h"
-
-/*--------------------------------------------------------------------------*/
-#if defined(@KWIML@_INT_HAVE_STDINT_H) /* Already defined. */
-#elif defined(@KWIML@_INT_NO_STDINT_H) /* Already defined. */
-#elif defined(HAVE_STDINT_H) /* Optionally provided by includer. */
-# define @KWIML@_INT_HAVE_STDINT_H 1
-#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
-# define @KWIML@_INT_HAVE_STDINT_H 1
-#elif defined(_MSC_VER) /* MSVC */
-# if _MSC_VER >= 1600
-# define @KWIML@_INT_HAVE_STDINT_H 1
-# else
-# define @KWIML@_INT_NO_STDINT_H 1
-# endif
-#elif defined(__BORLANDC__) /* Borland */
-# if __BORLANDC__ >= 0x560
-# define @KWIML@_INT_HAVE_STDINT_H 1
-# else
-# define @KWIML@_INT_NO_STDINT_H 1
-# endif
-#elif defined(__WATCOMC__) /* Watcom */
-# define @KWIML@_INT_NO_STDINT_H 1
-#endif
-
-/*--------------------------------------------------------------------------*/
-#if defined(@KWIML@_INT_HAVE_INTTYPES_H) /* Already defined. */
-#elif defined(@KWIML@_INT_NO_INTTYPES_H) /* Already defined. */
-#elif defined(HAVE_INTTYPES_H) /* Optionally provided by includer. */
-# define @KWIML@_INT_HAVE_INTTYPES_H 1
-#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
-# define @KWIML@_INT_HAVE_INTTYPES_H 1
-#elif defined(_MSC_VER) /* MSVC */
-# define @KWIML@_INT_NO_INTTYPES_H 1
-#elif defined(__BORLANDC__) /* Borland */
-# define @KWIML@_INT_NO_INTTYPES_H 1
-#elif defined(__WATCOMC__) /* Watcom */
-# define @KWIML@_INT_NO_INTTYPES_H 1
-#else /* Assume it exists. */
-# define @KWIML@_INT_HAVE_INTTYPES_H 1
-#endif
-
-/*--------------------------------------------------------------------------*/
-#if defined(@KWIML@_INT_HAVE_STDINT_H) && defined(@KWIML@_INT_NO_STDINT_H)
-# error "Both @KWIML@_INT_HAVE_STDINT_H and @KWIML@_INT_NO_STDINT_H defined!"
-#endif
-#if defined(@KWIML@_INT_HAVE_INTTYPES_H) && defined(@KWIML@_INT_NO_INTTYPES_H)
-# error "Both @KWIML@_INT_HAVE_INTTYPES_H and @KWIML@_INT_NO_INTTYPES_H defined!"
-#endif
-
-#if defined(@KWIML@_INT_HAVE_STDINT_H)
-# include <stdint.h>
-#endif
-#if defined(@KWIML@_INT_HAVE_INTTYPES_H)
-# if defined(__cplusplus) && !defined(__STDC_FORMAT_MACROS)
-# define __STDC_FORMAT_MACROS
-# endif
-# include <inttypes.h>
-#endif
-
-#if defined(@KWIML@_INT_HAVE_STDINT_H) || defined(@KWIML@_INT_HAVE_INTTYPES_H)
-#define @KWIML@_INT_HAVE_INT8_T 1
-#define @KWIML@_INT_HAVE_UINT8_T 1
-#define @KWIML@_INT_HAVE_INT16_T 1
-#define @KWIML@_INT_HAVE_UINT16_T 1
-#define @KWIML@_INT_HAVE_INT32_T 1
-#define @KWIML@_INT_HAVE_UINT32_T 1
-#define @KWIML@_INT_HAVE_INT64_T 1
-#define @KWIML@_INT_HAVE_UINT64_T 1
-#define @KWIML@_INT_HAVE_INTPTR_T 1
-#define @KWIML@_INT_HAVE_UINTPTR_T 1
-#endif
-
-#if defined(_AIX43) && !defined(_AIX50) && !defined(_AIX51)
- /* AIX 4.3 defines these incorrectly with % and no quotes. */
-# define @KWIML@_INT_BROKEN_PRId8
-# define @KWIML@_INT_BROKEN_SCNd8
-# define @KWIML@_INT_BROKEN_PRIi8
-# define @KWIML@_INT_BROKEN_SCNi8
-# define @KWIML@_INT_BROKEN_PRIo8
-# define @KWIML@_INT_BROKEN_SCNo8
-# define @KWIML@_INT_BROKEN_PRIu8
-# define @KWIML@_INT_BROKEN_SCNu8
-# define @KWIML@_INT_BROKEN_PRIx8
-# define @KWIML@_INT_BROKEN_SCNx8
-# define @KWIML@_INT_BROKEN_PRIX8
-# define @KWIML@_INT_BROKEN_PRId16
-# define @KWIML@_INT_BROKEN_SCNd16
-# define @KWIML@_INT_BROKEN_PRIi16
-# define @KWIML@_INT_BROKEN_SCNi16
-# define @KWIML@_INT_BROKEN_PRIo16
-# define @KWIML@_INT_BROKEN_SCNo16
-# define @KWIML@_INT_BROKEN_PRIu16
-# define @KWIML@_INT_BROKEN_SCNu16
-# define @KWIML@_INT_BROKEN_PRIx16
-# define @KWIML@_INT_BROKEN_SCNx16
-# define @KWIML@_INT_BROKEN_PRIX16
-# define @KWIML@_INT_BROKEN_PRId32
-# define @KWIML@_INT_BROKEN_SCNd32
-# define @KWIML@_INT_BROKEN_PRIi32
-# define @KWIML@_INT_BROKEN_SCNi32
-# define @KWIML@_INT_BROKEN_PRIo32
-# define @KWIML@_INT_BROKEN_SCNo32
-# define @KWIML@_INT_BROKEN_PRIu32
-# define @KWIML@_INT_BROKEN_SCNu32
-# define @KWIML@_INT_BROKEN_PRIx32
-# define @KWIML@_INT_BROKEN_SCNx32
-# define @KWIML@_INT_BROKEN_PRIX32
-# define @KWIML@_INT_BROKEN_PRId64
-# define @KWIML@_INT_BROKEN_SCNd64
-# define @KWIML@_INT_BROKEN_PRIi64
-# define @KWIML@_INT_BROKEN_SCNi64
-# define @KWIML@_INT_BROKEN_PRIo64
-# define @KWIML@_INT_BROKEN_SCNo64
-# define @KWIML@_INT_BROKEN_PRIu64
-# define @KWIML@_INT_BROKEN_SCNu64
-# define @KWIML@_INT_BROKEN_PRIx64
-# define @KWIML@_INT_BROKEN_SCNx64
-# define @KWIML@_INT_BROKEN_PRIX64
-# define @KWIML@_INT_BROKEN_PRIdPTR
-# define @KWIML@_INT_BROKEN_SCNdPTR
-# define @KWIML@_INT_BROKEN_PRIiPTR
-# define @KWIML@_INT_BROKEN_SCNiPTR
-# define @KWIML@_INT_BROKEN_PRIoPTR
-# define @KWIML@_INT_BROKEN_SCNoPTR
-# define @KWIML@_INT_BROKEN_PRIuPTR
-# define @KWIML@_INT_BROKEN_SCNuPTR
-# define @KWIML@_INT_BROKEN_PRIxPTR
-# define @KWIML@_INT_BROKEN_SCNxPTR
-# define @KWIML@_INT_BROKEN_PRIXPTR
-#endif
-
-#if (defined(__SUNPRO_C)||defined(__SUNPRO_CC)) && defined(_CHAR_IS_UNSIGNED)
-# define @KWIML@_INT_BROKEN_INT8_T /* system type defined incorrectly */
-#elif defined(__BORLANDC__) && defined(_CHAR_UNSIGNED)
-# define @KWIML@_INT_BROKEN_INT8_T /* system type defined incorrectly */
-#endif
-
-/*--------------------------------------------------------------------------*/
-#if defined(@KWIML@_INT_HAVE_INT8_T) && !defined(@KWIML@_INT_BROKEN_INT8_T)
-# define @KWIML@_INT_int8_t int8_t
-#else
-# define @KWIML@_INT_int8_t signed char
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT8_T)
-# define @KWIML@_INT_uint8_t uint8_t
-#else
-# define @KWIML@_INT_uint8_t unsigned char
-#endif
-
-#if defined(__INTEL_COMPILER)
-# if defined(_WIN32)
-# define @KWIML@_INT__NO_SCN8
-# endif
-#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
-# define @KWIML@_INT__NO_SCN8
-#elif defined(__BORLANDC__)
-# define @KWIML@_INT__NO_SCN8
-# define @KWIML@_INT__NO_SCN64
-#elif defined(_MSC_VER)
-# define @KWIML@_INT__NO_SCN8
-#elif defined(__WATCOMC__)
-# define @KWIML@_INT__NO_SCN8
-# elif defined(__hpux) /* HP runtime lacks support (any compiler) */
-# define @KWIML@_INT__NO_SCN8
-#endif
-
-/* 8-bit d, i */
-#if defined(@KWIML@_INT_HAVE_INT8_T) && defined(PRId8) \
- && !defined(@KWIML@_INT_BROKEN_PRId8)
-# define @KWIML@_INT_PRId8 PRId8
-#else
-# define @KWIML@_INT_PRId8 "d"
-#endif
-#if defined(@KWIML@_INT_HAVE_INT8_T) && defined(SCNd8) \
- && !defined(@KWIML@_INT_BROKEN_SCNd8)
-# define @KWIML@_INT_SCNd8 SCNd8
-#elif !defined(@KWIML@_INT__NO_SCN8)
-# define @KWIML@_INT_SCNd8 "hhd"
-#endif
-#if defined(@KWIML@_INT_HAVE_INT8_T) && defined(PRIi8) \
- && !defined(@KWIML@_INT_BROKEN_PRIi8)
-# define @KWIML@_INT_PRIi8 PRIi8
-#else
-# define @KWIML@_INT_PRIi8 "i"
-#endif
-#if defined(@KWIML@_INT_HAVE_INT8_T) && defined(SCNi8) \
- && !defined(@KWIML@_INT_BROKEN_SCNi8)
-# define @KWIML@_INT_SCNi8 SCNi8
-#elif !defined(@KWIML@_INT__NO_SCN8)
-# define @KWIML@_INT_SCNi8 "hhi"
-#endif
-
-/* 8-bit o, u, x, X */
-#if defined(@KWIML@_INT_HAVE_UINT8_T) && defined(PRIo8) \
- && !defined(@KWIML@_INT_BROKEN_PRIo8)
-# define @KWIML@_INT_PRIo8 PRIo8
-#else
-# define @KWIML@_INT_PRIo8 "o"
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT8_T) && defined(SCNo8) \
- && !defined(@KWIML@_INT_BROKEN_SCNo8)
-# define @KWIML@_INT_SCNo8 SCNo8
-#elif !defined(@KWIML@_INT__NO_SCN8)
-# define @KWIML@_INT_SCNo8 "hho"
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT8_T) && defined(PRIu8) \
- && !defined(@KWIML@_INT_BROKEN_PRIu8)
-# define @KWIML@_INT_PRIu8 PRIu8
-#else
-# define @KWIML@_INT_PRIu8 "u"
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT8_T) && defined(SCNu8) \
- && !defined(@KWIML@_INT_BROKEN_SCNu8)
-# define @KWIML@_INT_SCNu8 SCNu8
-#elif !defined(@KWIML@_INT__NO_SCN8)
-# define @KWIML@_INT_SCNu8 "hhu"
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT8_T) && defined(PRIx8) \
- && !defined(@KWIML@_INT_BROKEN_PRIx8)
-# define @KWIML@_INT_PRIx8 PRIx8
-#else
-# define @KWIML@_INT_PRIx8 "x"
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT8_T) && defined(SCNx8) \
- && !defined(@KWIML@_INT_BROKEN_SCNx8)
-# define @KWIML@_INT_SCNx8 SCNx8
-#elif !defined(@KWIML@_INT__NO_SCN8)
-# define @KWIML@_INT_SCNx8 "hhx"
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT8_T) && defined(PRIX8) \
- && !defined(@KWIML@_INT_BROKEN_PRIX8)
-# define @KWIML@_INT_PRIX8 PRIX8
-#else
-# define @KWIML@_INT_PRIX8 "X"
-#endif
-
-/* 8-bit constants */
-#if defined(INT8_C) && !defined(@KWIML@_INT_BROKEN_INT8_C)
-# define @KWIML@_INT_INT8_C(c) INT8_C(c)
-#else
-# define @KWIML@_INT_INT8_C(c) c
-#endif
-#if defined(UINT8_C) && !defined(@KWIML@_INT_BROKEN_UINT8_C)
-# define @KWIML@_INT_UINT8_C(c) UINT8_C(c)
-#else
-# define @KWIML@_INT_UINT8_C(c) c ## u
-#endif
-
-/*--------------------------------------------------------------------------*/
-#if defined(@KWIML@_INT_HAVE_INT16_T)
-# define @KWIML@_INT_int16_t int16_t
-#else
-# define @KWIML@_INT_int16_t signed short
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT16_T)
-# define @KWIML@_INT_uint16_t uint16_t
-#else
-# define @KWIML@_INT_uint16_t unsigned short
-#endif
-
-/* 16-bit d, i */
-#if defined(@KWIML@_INT_HAVE_INT16_T) && defined(PRId16) \
- && !defined(@KWIML@_INT_BROKEN_PRId16)
-# define @KWIML@_INT_PRId16 PRId16
-#else
-# define @KWIML@_INT_PRId16 "d"
-#endif
-#if defined(@KWIML@_INT_HAVE_INT16_T) && defined(SCNd16) \
- && !defined(@KWIML@_INT_BROKEN_SCNd16)
-# define @KWIML@_INT_SCNd16 SCNd16
-#else
-# define @KWIML@_INT_SCNd16 "hd"
-#endif
-#if defined(@KWIML@_INT_HAVE_INT16_T) && defined(PRIi16) \
- && !defined(@KWIML@_INT_BROKEN_PRIi16)
-# define @KWIML@_INT_PRIi16 PRIi16
-#else
-# define @KWIML@_INT_PRIi16 "i"
-#endif
-#if defined(@KWIML@_INT_HAVE_INT16_T) && defined(SCNi16) \
- && !defined(@KWIML@_INT_BROKEN_SCNi16)
-# define @KWIML@_INT_SCNi16 SCNi16
-#else
-# define @KWIML@_INT_SCNi16 "hi"
-#endif
-
-/* 16-bit o, u, x, X */
-#if defined(@KWIML@_INT_HAVE_UINT16_T) && defined(PRIo16) \
- && !defined(@KWIML@_INT_BROKEN_PRIo16)
-# define @KWIML@_INT_PRIo16 PRIo16
-#else
-# define @KWIML@_INT_PRIo16 "o"
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT16_T) && defined(SCNo16) \
- && !defined(@KWIML@_INT_BROKEN_SCNo16)
-# define @KWIML@_INT_SCNo16 SCNo16
-#else
-# define @KWIML@_INT_SCNo16 "ho"
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT16_T) && defined(PRIu16) \
- && !defined(@KWIML@_INT_BROKEN_PRIu16)
-# define @KWIML@_INT_PRIu16 PRIu16
-#else
-# define @KWIML@_INT_PRIu16 "u"
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT16_T) && defined(SCNu16) \
- && !defined(@KWIML@_INT_BROKEN_SCNu16)
-# define @KWIML@_INT_SCNu16 SCNu16
-#else
-# define @KWIML@_INT_SCNu16 "hu"
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT16_T) && defined(PRIx16) \
- && !defined(@KWIML@_INT_BROKEN_PRIx16)
-# define @KWIML@_INT_PRIx16 PRIx16
-#else
-# define @KWIML@_INT_PRIx16 "x"
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT16_T) && defined(SCNx16) \
- && !defined(@KWIML@_INT_BROKEN_SCNx16)
-# define @KWIML@_INT_SCNx16 SCNx16
-#else
-# define @KWIML@_INT_SCNx16 "hx"
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT16_T) && defined(PRIX16) \
- && !defined(@KWIML@_INT_BROKEN_PRIX16)
-# define @KWIML@_INT_PRIX16 PRIX16
-#else
-# define @KWIML@_INT_PRIX16 "X"
-#endif
-
-/* 16-bit constants */
-#if defined(INT16_C) && !defined(@KWIML@_INT_BROKEN_INT16_C)
-# define @KWIML@_INT_INT16_C(c) INT16_C(c)
-#else
-# define @KWIML@_INT_INT16_C(c) c
-#endif
-#if defined(UINT16_C) && !defined(@KWIML@_INT_BROKEN_UINT16_C)
-# define @KWIML@_INT_UINT16_C(c) UINT16_C(c)
-#else
-# define @KWIML@_INT_UINT16_C(c) c ## u
-#endif
-
-/*--------------------------------------------------------------------------*/
-#if defined(@KWIML@_INT_HAVE_INT32_T)
-# define @KWIML@_INT_int32_t int32_t
-#else
-# define @KWIML@_INT_int32_t signed int
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT32_T)
-# define @KWIML@_INT_uint32_t uint32_t
-#else
-# define @KWIML@_INT_uint32_t unsigned int
-#endif
-
-/* 32-bit d, i */
-#if defined(@KWIML@_INT_HAVE_INT32_T) && defined(PRId32) \
- && !defined(@KWIML@_INT_BROKEN_PRId32)
-# define @KWIML@_INT_PRId32 PRId32
-#else
-# define @KWIML@_INT_PRId32 "d"
-#endif
-#if defined(@KWIML@_INT_HAVE_INT32_T) && defined(SCNd32) \
- && !defined(@KWIML@_INT_BROKEN_SCNd32)
-# define @KWIML@_INT_SCNd32 SCNd32
-#else
-# define @KWIML@_INT_SCNd32 "d"
-#endif
-#if defined(@KWIML@_INT_HAVE_INT32_T) && defined(PRIi32) \
- && !defined(@KWIML@_INT_BROKEN_PRIi32)
-# define @KWIML@_INT_PRIi32 PRIi32
-#else
-# define @KWIML@_INT_PRIi32 "i"
-#endif
-#if defined(@KWIML@_INT_HAVE_INT32_T) && defined(SCNi32) \
- && !defined(@KWIML@_INT_BROKEN_SCNi32)
-# define @KWIML@_INT_SCNi32 SCNi32
-#else
-# define @KWIML@_INT_SCNi32 "i"
-#endif
-
-/* 32-bit o, u, x, X */
-#if defined(@KWIML@_INT_HAVE_UINT32_T) && defined(PRIo32) \
- && !defined(@KWIML@_INT_BROKEN_PRIo32)
-# define @KWIML@_INT_PRIo32 PRIo32
-#else
-# define @KWIML@_INT_PRIo32 "o"
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT32_T) && defined(SCNo32) \
- && !defined(@KWIML@_INT_BROKEN_SCNo32)
-# define @KWIML@_INT_SCNo32 SCNo32
-#else
-# define @KWIML@_INT_SCNo32 "o"
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT32_T) && defined(PRIu32) \
- && !defined(@KWIML@_INT_BROKEN_PRIu32)
-# define @KWIML@_INT_PRIu32 PRIu32
-#else
-# define @KWIML@_INT_PRIu32 "u"
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT32_T) && defined(SCNu32) \
- && !defined(@KWIML@_INT_BROKEN_SCNu32)
-# define @KWIML@_INT_SCNu32 SCNu32
-#else
-# define @KWIML@_INT_SCNu32 "u"
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT32_T) && defined(PRIx32) \
- && !defined(@KWIML@_INT_BROKEN_PRIx32)
-# define @KWIML@_INT_PRIx32 PRIx32
-#else
-# define @KWIML@_INT_PRIx32 "x"
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT32_T) && defined(SCNx32) \
- && !defined(@KWIML@_INT_BROKEN_SCNx32)
-# define @KWIML@_INT_SCNx32 SCNx32
-#else
-# define @KWIML@_INT_SCNx32 "x"
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT32_T) && defined(PRIX32) \
- && !defined(@KWIML@_INT_BROKEN_PRIX32)
-# define @KWIML@_INT_PRIX32 PRIX32
-#else
-# define @KWIML@_INT_PRIX32 "X"
-#endif
-
-#if defined(__hpux) && defined(__GNUC__) && !defined(__LP64__) \
- && defined(__CONCAT__) && defined(__CONCAT_U__)
- /* Some HPs define UINT32_C incorrectly and break GNU. */
-# define @KWIML@_INT_BROKEN_UINT32_C
-#endif
-
-/* 32-bit constants */
-#if defined(INT32_C) && !defined(@KWIML@_INT_BROKEN_INT32_C)
-# define @KWIML@_INT_INT32_C(c) INT32_C(c)
-#else
-# define @KWIML@_INT_INT32_C(c) c
-#endif
-#if defined(UINT32_C) && !defined(@KWIML@_INT_BROKEN_UINT32_C)
-# define @KWIML@_INT_UINT32_C(c) UINT32_C(c)
-#else
-# define @KWIML@_INT_UINT32_C(c) c ## u
-#endif
-
-/*--------------------------------------------------------------------------*/
-#if defined(@KWIML@_INT_HAVE_INT64_T)
-# define @KWIML@_INT_int64_t int64_t
-#elif @KWIML@_ABI_SIZEOF_LONG == 8
-# define @KWIML@_INT_int64_t signed long
-#elif defined(@KWIML@_ABI_SIZEOF_LONG_LONG) && @KWIML@_ABI_SIZEOF_LONG_LONG == 8
-# define @KWIML@_INT_int64_t signed long long
-#elif defined(@KWIML@_ABI_SIZEOF___INT64)
-# define @KWIML@_INT_int64_t signed __int64
-#elif defined(@KWIML@_INT_NO_ERROR_INT64_T)
-# define @KWIML@_INT_NO_INT64_T
-#else
-# error "No type known for 'int64_t'."
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT64_T)
-# define @KWIML@_INT_uint64_t uint64_t
-#elif @KWIML@_ABI_SIZEOF_LONG == 8
-# define @KWIML@_INT_uint64_t unsigned long
-#elif defined(@KWIML@_ABI_SIZEOF_LONG_LONG) && @KWIML@_ABI_SIZEOF_LONG_LONG == 8
-# define @KWIML@_INT_uint64_t unsigned long long
-#elif defined(@KWIML@_ABI_SIZEOF___INT64)
-# define @KWIML@_INT_uint64_t unsigned __int64
-#elif defined(@KWIML@_INT_NO_ERROR_UINT64_T)
-# define @KWIML@_INT_NO_UINT64_T
-#else
-# error "No type known for 'uint64_t'."
-#endif
-
-#if defined(__INTEL_COMPILER)
-#elif defined(__BORLANDC__)
-# define @KWIML@_INT__NO_FMTLL /* type 'long long' but not 'll' format */
-# define @KWIML@_INT_BROKEN_INT64_C /* system macro defined incorrectly */
-# define @KWIML@_INT_BROKEN_UINT64_C /* system macro defined incorrectly */
-#elif defined(_MSC_VER) && _MSC_VER < 1400
-# define @KWIML@_INT__NO_FMTLL /* type 'long long' but not 'll' format */
-#endif
-
-#if @KWIML@_ABI_SIZEOF_LONG == 8
-# define @KWIML@_INT__FMT64 "l"
-#elif defined(@KWIML@_ABI_SIZEOF_LONG_LONG) && @KWIML@_ABI_SIZEOF_LONG_LONG == 8
-# if !defined(@KWIML@_INT__NO_FMTLL)
-# define @KWIML@_INT__FMT64 "ll"
-# else
-# define @KWIML@_INT__FMT64 "I64"
-# endif
-#elif defined(@KWIML@_ABI_SIZEOF___INT64)
-# if defined(__BORLANDC__)
-# define @KWIML@_INT__FMT64 "L"
-# else
-# define @KWIML@_INT__FMT64 "I64"
-# endif
-#endif
-
-/* 64-bit d, i */
-#if defined(@KWIML@_INT_HAVE_INT64_T) && defined(PRId64) \
- && !defined(@KWIML@_INT_BROKEN_PRId64)
-# define @KWIML@_INT_PRId64 PRId64
-#elif defined(@KWIML@_INT__FMT64)
-# define @KWIML@_INT_PRId64 @KWIML@_INT__FMT64 "d"
-#endif
-#if defined(@KWIML@_INT_HAVE_INT64_T) && defined(SCNd64) \
- && !defined(@KWIML@_INT_BROKEN_SCNd64)
-# define @KWIML@_INT_SCNd64 SCNd64
-#elif defined(@KWIML@_INT__FMT64) && !defined(@KWIML@_INT__NO_SCN64)
-# define @KWIML@_INT_SCNd64 @KWIML@_INT__FMT64 "d"
-#endif
-#if defined(@KWIML@_INT_HAVE_INT64_T) && defined(PRIi64) \
- && !defined(@KWIML@_INT_BROKEN_PRIi64)
-# define @KWIML@_INT_PRIi64 PRIi64
-#elif defined(@KWIML@_INT__FMT64)
-# define @KWIML@_INT_PRIi64 @KWIML@_INT__FMT64 "d"
-#endif
-#if defined(@KWIML@_INT_HAVE_INT64_T) && defined(SCNi64) \
- && !defined(@KWIML@_INT_BROKEN_SCNi64)
-# define @KWIML@_INT_SCNi64 SCNi64
-#elif defined(@KWIML@_INT__FMT64) && !defined(@KWIML@_INT__NO_SCN64)
-# define @KWIML@_INT_SCNi64 @KWIML@_INT__FMT64 "d"
-#endif
-
-/* 64-bit o, u, x, X */
-#if defined(@KWIML@_INT_HAVE_UINT64_T) && defined(PRIo64) \
- && !defined(@KWIML@_INT_BROKEN_PRIo64)
-# define @KWIML@_INT_PRIo64 PRIo64
-#elif defined(@KWIML@_INT__FMT64)
-# define @KWIML@_INT_PRIo64 @KWIML@_INT__FMT64 "o"
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT64_T) && defined(SCNo64) \
- && !defined(@KWIML@_INT_BROKEN_SCNo64)
-# define @KWIML@_INT_SCNo64 SCNo64
-#elif defined(@KWIML@_INT__FMT64) && !defined(@KWIML@_INT__NO_SCN64)
-# define @KWIML@_INT_SCNo64 @KWIML@_INT__FMT64 "o"
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT64_T) && defined(PRIu64) \
- && !defined(@KWIML@_INT_BROKEN_PRIu64)
-# define @KWIML@_INT_PRIu64 PRIu64
-#elif defined(@KWIML@_INT__FMT64)
-# define @KWIML@_INT_PRIu64 @KWIML@_INT__FMT64 "u"
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT64_T) && defined(SCNu64) \
- && !defined(@KWIML@_INT_BROKEN_SCNu64)
-# define @KWIML@_INT_SCNu64 SCNu64
-#elif defined(@KWIML@_INT__FMT64) && !defined(@KWIML@_INT__NO_SCN64)
-# define @KWIML@_INT_SCNu64 @KWIML@_INT__FMT64 "u"
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT64_T) && defined(PRIx64) \
- && !defined(@KWIML@_INT_BROKEN_PRIx64)
-# define @KWIML@_INT_PRIx64 PRIx64
-#elif defined(@KWIML@_INT__FMT64)
-# define @KWIML@_INT_PRIx64 @KWIML@_INT__FMT64 "x"
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT64_T) && defined(SCNx64) \
- && !defined(@KWIML@_INT_BROKEN_SCNx64)
-# define @KWIML@_INT_SCNx64 SCNx64
-#elif defined(@KWIML@_INT__FMT64) && !defined(@KWIML@_INT__NO_SCN64)
-# define @KWIML@_INT_SCNx64 @KWIML@_INT__FMT64 "x"
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT64_T) && defined(PRIX64) \
- && !defined(@KWIML@_INT_BROKEN_PRIX64)
-# define @KWIML@_INT_PRIX64 PRIX64
-#elif defined(@KWIML@_INT__FMT64)
-# define @KWIML@_INT_PRIX64 @KWIML@_INT__FMT64 "X"
-#endif
-
-/* 64-bit constants */
-#if defined(@KWIML@_INT_HAVE_INT64_T) && defined(INT64_C) \
- && !defined(@KWIML@_INT_BROKEN_INT64_C)
-# define @KWIML@_INT_INT64_C(c) INT64_C(c)
-#elif @KWIML@_ABI_SIZEOF_LONG == 8
-# define @KWIML@_INT_INT64_C(c) c ## l
-#elif defined(@KWIML@_ABI_SIZEOF_LONG_LONG) && @KWIML@_ABI_SIZEOF_LONG_LONG == 8
-# define @KWIML@_INT_INT64_C(c) c ## ll
-#elif defined(@KWIML@_ABI_SIZEOF___INT64)
-# define @KWIML@_INT_INT64_C(c) c ## i64
-#endif
-#if defined(@KWIML@_INT_HAVE_UINT64_T) && defined(UINT64_C) \
- && !defined(@KWIML@_INT_BROKEN_UINT64_C)
-# define @KWIML@_INT_UINT64_C(c) UINT64_C(c)
-#elif @KWIML@_ABI_SIZEOF_LONG == 8
-# define @KWIML@_INT_UINT64_C(c) c ## ul
-#elif defined(@KWIML@_ABI_SIZEOF_LONG_LONG) && @KWIML@_ABI_SIZEOF_LONG_LONG == 8
-# define @KWIML@_INT_UINT64_C(c) c ## ull
-#elif defined(@KWIML@_ABI_SIZEOF___INT64)
-# define @KWIML@_INT_UINT64_C(c) c ## ui64
-#endif
-
-/*--------------------------------------------------------------------------*/
-#if defined(@KWIML@_INT_HAVE_INTPTR_T)
-# define @KWIML@_INT_intptr_t intptr_t
-#elif @KWIML@_ABI_SIZEOF_DATA_PTR == 4
-# define @KWIML@_INT_intptr_t @KWIML@_INT_int32_t
-#elif !defined(@KWIML@_INT_NO_INT64_T)
-# define @KWIML@_INT_intptr_t @KWIML@_INT_int64_t
-#elif defined(@KWIML@_INT_NO_ERROR_INTPTR_T)
-# define @KWIML@_INT_NO_INTPTR_T
-#else
-# error "No type known for 'intptr_t'."
-#endif
-#if defined(@KWIML@_INT_HAVE_UINTPTR_T)
-# define @KWIML@_INT_uintptr_t uintptr_t
-#elif @KWIML@_ABI_SIZEOF_DATA_PTR == 4
-# define @KWIML@_INT_uintptr_t @KWIML@_INT_uint32_t
-#elif !defined(@KWIML@_INT_NO_UINT64_T)
-# define @KWIML@_INT_uintptr_t @KWIML@_INT_uint64_t
-#elif defined(@KWIML@_INT_NO_ERROR_UINTPTR_T)
-# define @KWIML@_INT_NO_UINTPTR_T
-#else
-# error "No type known for 'uintptr_t'."
-#endif
-
-#if defined(@KWIML@_INT_HAVE_INTPTR_T) && defined(PRIdPTR) \
- && !defined(@KWIML@_INT_BROKEN_PRIdPTR)
-# define @KWIML@_INT_PRIdPTR PRIdPTR
-#elif @KWIML@_ABI_SIZEOF_DATA_PTR == 4
-# define @KWIML@_INT_PRIdPTR @KWIML@_INT_PRId32
-#elif !defined(@KWIML@_INT_NO_UINT64_T)
-# define @KWIML@_INT_PRIdPTR @KWIML@_INT_PRId64
-#endif
-#if defined(@KWIML@_INT_HAVE_INTPTR_T) && defined(SCNdPTR) \
- && !defined(@KWIML@_INT_BROKEN_SCNdPTR)
-# define @KWIML@_INT_SCNdPTR SCNdPTR
-#elif @KWIML@_ABI_SIZEOF_DATA_PTR == 4
-# define @KWIML@_INT_SCNdPTR @KWIML@_INT_SCNd32
-#elif !defined(@KWIML@_INT_NO_UINT64_T)
-# define @KWIML@_INT_SCNdPTR @KWIML@_INT_SCNd64
-#endif
-#if defined(@KWIML@_INT_HAVE_INTPTR_T) && defined(PRIiPTR) \
- && !defined(@KWIML@_INT_BROKEN_PRIiPTR)
-# define @KWIML@_INT_PRIiPTR PRIiPTR
-#elif @KWIML@_ABI_SIZEOF_DATA_PTR == 4
-# define @KWIML@_INT_PRIiPTR @KWIML@_INT_PRIi32
-#elif !defined(@KWIML@_INT_NO_UINT64_T)
-# define @KWIML@_INT_PRIiPTR @KWIML@_INT_PRIi64
-#endif
-#if defined(@KWIML@_INT_HAVE_INTPTR_T) && defined(SCNiPTR) \
- && !defined(@KWIML@_INT_BROKEN_SCNiPTR)
-# define @KWIML@_INT_SCNiPTR SCNiPTR
-#elif @KWIML@_ABI_SIZEOF_DATA_PTR == 4
-# define @KWIML@_INT_SCNiPTR @KWIML@_INT_SCNi32
-#elif !defined(@KWIML@_INT_NO_UINT64_T)
-# define @KWIML@_INT_SCNiPTR @KWIML@_INT_SCNi64
-#endif
-
-#if defined(@KWIML@_INT_HAVE_UINTPTR_T) && defined(PRIoPTR) \
- && !defined(@KWIML@_INT_BROKEN_PRIoPTR)
-# define @KWIML@_INT_PRIoPTR PRIoPTR
-#elif @KWIML@_ABI_SIZEOF_DATA_PTR == 4
-# define @KWIML@_INT_PRIoPTR @KWIML@_INT_PRIo32
-#elif !defined(@KWIML@_INT_NO_UINT64_T)
-# define @KWIML@_INT_PRIoPTR @KWIML@_INT_PRIo64
-#endif
-#if defined(@KWIML@_INT_HAVE_UINTPTR_T) && defined(SCNoPTR) \
- && !defined(@KWIML@_INT_BROKEN_SCNoPTR)
-# define @KWIML@_INT_SCNoPTR SCNoPTR
-#elif @KWIML@_ABI_SIZEOF_DATA_PTR == 4
-# define @KWIML@_INT_SCNoPTR @KWIML@_INT_SCNo32
-#elif !defined(@KWIML@_INT_NO_UINT64_T)
-# define @KWIML@_INT_SCNoPTR @KWIML@_INT_SCNo64
-#endif
-#if defined(@KWIML@_INT_HAVE_UINTPTR_T) && defined(PRIuPTR) \
- && !defined(@KWIML@_INT_BROKEN_PRIuPTR)
-# define @KWIML@_INT_PRIuPTR PRIuPTR
-#elif @KWIML@_ABI_SIZEOF_DATA_PTR == 4
-# define @KWIML@_INT_PRIuPTR @KWIML@_INT_PRIu32
-#elif !defined(@KWIML@_INT_NO_UINT64_T)
-# define @KWIML@_INT_PRIuPTR @KWIML@_INT_PRIu64
-#endif
-#if defined(@KWIML@_INT_HAVE_UINTPTR_T) && defined(SCNuPTR) \
- && !defined(@KWIML@_INT_BROKEN_SCNuPTR)
-# define @KWIML@_INT_SCNuPTR SCNuPTR
-#elif @KWIML@_ABI_SIZEOF_DATA_PTR == 4
-# define @KWIML@_INT_SCNuPTR @KWIML@_INT_SCNu32
-#elif !defined(@KWIML@_INT_NO_UINT64_T)
-# define @KWIML@_INT_SCNuPTR @KWIML@_INT_SCNu64
-#endif
-#if defined(@KWIML@_INT_HAVE_UINTPTR_T) && defined(PRIxPTR) \
- && !defined(@KWIML@_INT_BROKEN_PRIxPTR)
-# define @KWIML@_INT_PRIxPTR PRIxPTR
-#elif @KWIML@_ABI_SIZEOF_DATA_PTR == 4
-# define @KWIML@_INT_PRIxPTR @KWIML@_INT_PRIx32
-#elif !defined(@KWIML@_INT_NO_UINT64_T)
-# define @KWIML@_INT_PRIxPTR @KWIML@_INT_PRIx64
-#endif
-#if defined(@KWIML@_INT_HAVE_UINTPTR_T) && defined(SCNxPTR) \
- && !defined(@KWIML@_INT_BROKEN_SCNxPTR)
-# define @KWIML@_INT_SCNxPTR SCNxPTR
-#elif @KWIML@_ABI_SIZEOF_DATA_PTR == 4
-# define @KWIML@_INT_SCNxPTR @KWIML@_INT_SCNx32
-#elif !defined(@KWIML@_INT_NO_UINT64_T)
-# define @KWIML@_INT_SCNxPTR @KWIML@_INT_SCNx64
-#endif
-#if defined(@KWIML@_INT_HAVE_UINTPTR_T) && defined(PRIXPTR) \
- && !defined(@KWIML@_INT_BROKEN_PRIXPTR)
-# define @KWIML@_INT_PRIXPTR PRIXPTR
-#elif @KWIML@_ABI_SIZEOF_DATA_PTR == 4
-# define @KWIML@_INT_PRIXPTR @KWIML@_INT_PRIX32
-#elif !defined(@KWIML@_INT_NO_UINT64_T)
-# define @KWIML@_INT_PRIXPTR @KWIML@_INT_PRIX64
-#endif
-
-/*--------------------------------------------------------------------------*/
-#if !defined(@KWIML@_INT_NO_VERIFY)
-#define @KWIML@_INT__VERIFY(n, x, y) extern int (*n)[x]; extern int (*n)[y]
-#define @KWIML@_INT__VERIFY_BOOL(m, b) @KWIML@_INT__VERIFY(m##__VERIFY__, 2, (b)?2:3)
-#define @KWIML@_INT__VERIFY_TYPE(t, s) @KWIML@_INT__VERIFY(t##__VERIFY__, s, sizeof(t))
-#define @KWIML@_INT__VERIFY_SIGN(t, u, o) @KWIML@_INT__VERIFY_BOOL(t##__SIGN, (t)((u)1 << ((sizeof(t)<<3)-1)) o 0)
-
-@KWIML@_INT__VERIFY_TYPE(@KWIML@_INT_int8_t, 1);
-@KWIML@_INT__VERIFY_TYPE(@KWIML@_INT_uint8_t, 1);
-@KWIML@_INT__VERIFY_TYPE(@KWIML@_INT_int16_t, 2);
-@KWIML@_INT__VERIFY_TYPE(@KWIML@_INT_uint16_t, 2);
-@KWIML@_INT__VERIFY_TYPE(@KWIML@_INT_int32_t, 4);
-@KWIML@_INT__VERIFY_TYPE(@KWIML@_INT_uint32_t, 4);
-#if !defined(@KWIML@_INT_NO_INT64_T)
-@KWIML@_INT__VERIFY_TYPE(@KWIML@_INT_int64_t, 8);
-#endif
-#if !defined(@KWIML@_INT_NO_UINT64_T)
-@KWIML@_INT__VERIFY_TYPE(@KWIML@_INT_uint64_t, 8);
-#endif
-#if !defined(@KWIML@_INT_NO_INTPTR_T)
-@KWIML@_INT__VERIFY_TYPE(@KWIML@_INT_intptr_t, sizeof(void*));
-#endif
-#if !defined(@KWIML@_INT_NO_UINTPTR_T)
-@KWIML@_INT__VERIFY_TYPE(@KWIML@_INT_uintptr_t, sizeof(void*));
-#endif
-
-@KWIML@_INT__VERIFY_SIGN(@KWIML@_INT_int8_t, @KWIML@_INT_uint8_t, <);
-@KWIML@_INT__VERIFY_SIGN(@KWIML@_INT_uint8_t, @KWIML@_INT_uint8_t, >);
-@KWIML@_INT__VERIFY_SIGN(@KWIML@_INT_int16_t, @KWIML@_INT_uint16_t, <);
-@KWIML@_INT__VERIFY_SIGN(@KWIML@_INT_uint16_t, @KWIML@_INT_uint16_t, >);
-@KWIML@_INT__VERIFY_SIGN(@KWIML@_INT_int32_t, @KWIML@_INT_uint32_t, <);
-@KWIML@_INT__VERIFY_SIGN(@KWIML@_INT_uint32_t, @KWIML@_INT_uint32_t, >);
-#if !defined(@KWIML@_INT_NO_INT64_T)
-@KWIML@_INT__VERIFY_SIGN(@KWIML@_INT_int64_t, @KWIML@_INT_uint64_t, <);
-#endif
-#if !defined(@KWIML@_INT_NO_UINT64_T)
-@KWIML@_INT__VERIFY_SIGN(@KWIML@_INT_uint64_t, @KWIML@_INT_uint64_t, >);
-#endif
-#if !defined(@KWIML@_INT_NO_INTPTR_T)
-@KWIML@_INT__VERIFY_SIGN(@KWIML@_INT_intptr_t, @KWIML@_INT_uintptr_t, <);
-#endif
-#if !defined(@KWIML@_INT_NO_UINTPTR_T)
-@KWIML@_INT__VERIFY_SIGN(@KWIML@_INT_uintptr_t, @KWIML@_INT_uintptr_t, >);
-#endif
-
-#undef @KWIML@_INT__VERIFY_SIGN
-#undef @KWIML@_INT__VERIFY_TYPE
-#undef @KWIML@_INT__VERIFY_BOOL
-#undef @KWIML@_INT__VERIFY
-
-#endif
-
-#endif
diff --git a/Utilities/KWIML/README.md b/Utilities/KWIML/README.md
new file mode 100644
index 000000000..37d72d1b1
--- /dev/null
+++ b/Utilities/KWIML/README.md
@@ -0,0 +1,36 @@
+Kitware Information Macro Library (KWIML)
+=========================================
+
+KWIML provides header files that use preprocessor tests to detect and
+provide information about the compiler and its target architecture.
+The headers contain no configuration-time test results and thus may
+be installed into an architecture-independent include directory.
+This makes them suitable for use in the public interface of any package.
+
+The following headers are provided. See header comments for details:
+
+* [kwiml/abi.h][]: Fundamental type size and representation.
+
+* [kwiml/int.h][]: Fixed-size integer types and format specifiers.
+
+* [kwiml/version.h][]: Information about this version of KWIML.
+
+The [test][] subdirectory builds tests that verify correctness of the
+information provided by each header.
+
+License
+=======
+
+KWIML is distributed under the OSI-approved 3-clause BSD License.
+
+Files used only for build and test purposes contain a copyright notice and
+reference [Copyright.txt][] for details. Headers meant for installation and
+distribution outside the source tree come with full inlined copies of the
+copyright notice and license text. This makes them suitable for distribution
+with any package under compatible license terms.
+
+[Copyright.txt]: Copyright.txt
+[kwiml/abi.h]: include/kwiml/abi.h
+[kwiml/int.h]: include/kwiml/int.h
+[kwiml/version.h]: src/version.h.in
+[test]: test/
diff --git a/Utilities/KWIML/README.txt b/Utilities/KWIML/README.txt
deleted file mode 100644
index 6bdf859d9..000000000
--- a/Utilities/KWIML/README.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-KWIML - The Kitware Information Macro Library
-
-KWIML provides header files that use preprocessor tests to detect and
-provide information about the compiler and its target architecture. The
-headers contain no configuration-time test results and thus may be
-installed into an architecture-independent include directory. This
-makes them suitable for use in the public interface of any package.
-
-This source tree is intended for distribution inside the source trees of
-other packages. In order to avoid name collisions among multiple
-packages the KWIML headers are configured with a per-package prefix on
-both the header locations and the macros they define. See comments in
-CMakeLists.txt for instructions to include KWIML inside another project.
-
-The entire KWIML source tree is distributed under the OSI-approved
-3-clause BSD License. Files used only for build and test purposes
-contain a copyright notice and reference Copyright.txt for details.
-Headers meant for installation and distribution outside the source tree
-come with full inlined copies of the copyright notice and license text.
-This makes them suitable for distribution with any package under
-compatible license terms.
-
-The following components are provided. See header comments for details:
-
- ABI.h = Fundamental type size and representation
- INT.h = Fixed-size integer types and format specifiers
-
-The "test" subdirectory builds tests that verify correctness of the
-information provided by each header.
diff --git a/Utilities/KWIML/include/kwiml/abi.h b/Utilities/KWIML/include/kwiml/abi.h
new file mode 100644
index 000000000..362636165
--- /dev/null
+++ b/Utilities/KWIML/include/kwiml/abi.h
@@ -0,0 +1,562 @@
+/*============================================================================
+ Kitware Information Macro Library
+ Copyright 2010-2015 Kitware, Inc.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of Kitware, Inc. nor the names of its contributors
+ may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+============================================================================*/
+/*
+This header defines macros with information about the C ABI.
+Only information that can be determined using the preprocessor at
+compilation time is available. No try-compile results may be added
+here. Instead we memorize results on platforms of interest.
+
+An includer may optionally define the following macros to suppress errors:
+
+ KWIML_ABI_NO_VERIFY = skip verification declarations
+ KWIML_ABI_NO_ERROR_CHAR_SIGN = signedness of 'char' may be unknown
+ KWIML_ABI_NO_ERROR_LONG_LONG = existence of 'long long' may be unknown
+ KWIML_ABI_NO_ERROR_ENDIAN = byte order of CPU may be unknown
+
+An includer may test the following macros after inclusion:
+
+ KWIML_ABI_VERSION = interface version number # of this header
+
+ KWIML_ABI_SIZEOF_DATA_PTR = sizeof(void*)
+ KWIML_ABI_SIZEOF_CODE_PTR = sizeof(void(*)(void))
+ KWIML_ABI_SIZEOF_FLOAT = sizeof(float)
+ KWIML_ABI_SIZEOF_DOUBLE = sizeof(double)
+ KWIML_ABI_SIZEOF_CHAR = sizeof(char)
+ KWIML_ABI_SIZEOF_SHORT = sizeof(short)
+ KWIML_ABI_SIZEOF_INT = sizeof(int)
+ KWIML_ABI_SIZEOF_LONG = sizeof(long)
+
+ KWIML_ABI_SIZEOF_LONG_LONG = sizeof(long long) or 0 if not a type
+ Undefined if existence is unknown and error suppression macro
+ KWIML_ABI_NO_ERROR_LONG_LONG was defined.
+
+ KWIML_ABI_SIZEOF___INT64 = 8 if '__int64' exists or 0 if not
+ Undefined if existence is unknown.
+
+ KWIML_ABI___INT64_IS_LONG = 1 if '__int64' is 'long' (same type)
+ Undefined otherwise.
+ KWIML_ABI___INT64_IS_LONG_LONG = 1 if '__int64' is 'long long' (same type)
+ Undefined otherwise.
+ KWIML_ABI___INT64_IS_UNIQUE = 1 if '__int64' is a distinct type
+ Undefined otherwise.
+
+ KWIML_ABI_CHAR_IS_UNSIGNED = 1 if 'char' is unsigned, else undefined
+ KWIML_ABI_CHAR_IS_SIGNED = 1 if 'char' is signed, else undefined
+ One of these is defined unless signedness of 'char' is unknown and
+ error suppression macro KWIML_ABI_NO_ERROR_CHAR_SIGN was defined.
+
+ KWIML_ABI_ENDIAN_ID_BIG = id for big-endian (always defined)
+ KWIML_ABI_ENDIAN_ID_LITTLE = id for little-endian (always defined)
+ KWIML_ABI_ENDIAN_ID = id of byte order of target CPU
+ Defined to KWIML_ABI_ENDIAN_ID_BIG or KWIML_ABI_ENDIAN_ID_LITTLE
+ unless byte order is unknown and error suppression macro
+ KWIML_ABI_NO_ERROR_ENDIAN was defined.
+
+We verify most results using dummy "extern" declarations that are
+invalid if the macros are wrong. Verification is disabled if
+suppression macro KWIML_ABI_NO_VERIFY was defined.
+*/
+
+#define KWIML_ABI_private_VERSION 1
+
+/* Guard definition of this version. */
+#ifndef KWIML_ABI_detail_DEFINED_VERSION_1
+# define KWIML_ABI_detail_DEFINED_VERSION_1 1
+# define KWIML_ABI_private_DO_DEFINE
+#endif
+
+/* Guard verification of this version. */
+#if !defined(KWIML_ABI_NO_VERIFY)
+# ifndef KWIML_ABI_detail_VERIFIED_VERSION_1
+# define KWIML_ABI_detail_VERIFIED_VERSION_1
+# define KWIML_ABI_private_DO_VERIFY
+# endif
+#endif
+
+#ifdef KWIML_ABI_private_DO_DEFINE
+#undef KWIML_ABI_private_DO_DEFINE
+
+/* Define version as most recent of those included. */
+#if !defined(KWIML_ABI_VERSION) || KWIML_ABI_VERSION < KWIML_ABI_private_VERSION
+# undef KWIML_ABI_VERSION
+# define KWIML_ABI_VERSION 1
+#endif
+
+/*--------------------------------------------------------------------------*/
+#if !defined(KWIML_ABI_SIZEOF_DATA_PTR)
+# if defined(__SIZEOF_POINTER__)
+# define KWIML_ABI_SIZEOF_DATA_PTR __SIZEOF_POINTER__
+# elif defined(_SIZE_PTR)
+# define KWIML_ABI_SIZEOF_DATA_PTR (_SIZE_PTR >> 3)
+# elif defined(_LP64) || defined(__LP64__)
+# define KWIML_ABI_SIZEOF_DATA_PTR 8
+# elif defined(_ILP32)
+# define KWIML_ABI_SIZEOF_DATA_PTR 4
+# elif defined(__64BIT__) /* IBM XL */
+# define KWIML_ABI_SIZEOF_DATA_PTR 8
+# elif defined(_M_X64)
+# define KWIML_ABI_SIZEOF_DATA_PTR 8
+# elif defined(__ia64)
+# define KWIML_ABI_SIZEOF_DATA_PTR 8
+# elif defined(__sparcv9)
+# define KWIML_ABI_SIZEOF_DATA_PTR 8
+# elif defined(__x86_64) || defined(__x86_64__)
+# define KWIML_ABI_SIZEOF_DATA_PTR 8
+# elif defined(__amd64) || defined(__amd64__)
+# define KWIML_ABI_SIZEOF_DATA_PTR 8
+# elif defined(__i386) || defined(__i386__)
+# define KWIML_ABI_SIZEOF_DATA_PTR 4
+# endif
+#endif
+#if !defined(KWIML_ABI_SIZEOF_DATA_PTR)
+# define KWIML_ABI_SIZEOF_DATA_PTR 4
+#endif
+#if !defined(KWIML_ABI_SIZEOF_CODE_PTR)
+# define KWIML_ABI_SIZEOF_CODE_PTR KWIML_ABI_SIZEOF_DATA_PTR
+#endif
+
+/*--------------------------------------------------------------------------*/
+#if !defined(KWIML_ABI_SIZEOF_CHAR)
+# define KWIML_ABI_SIZEOF_CHAR 1
+#endif
+
+#if !defined(KWIML_ABI_CHAR_IS_UNSIGNED) && !defined(KWIML_ABI_CHAR_IS_SIGNED)
+# if defined(__CHAR_UNSIGNED__) /* GNU, some IBM XL, others? */
+# define KWIML_ABI_CHAR_IS_UNSIGNED 1
+# elif defined(_CHAR_UNSIGNED) /* Intel, IBM XL, MSVC, Borland, others? */
+# define KWIML_ABI_CHAR_IS_UNSIGNED 1
+# elif defined(_CHAR_SIGNED) /* IBM XL, others? */
+# define KWIML_ABI_CHAR_IS_SIGNED 1
+# elif defined(__CHAR_SIGNED__) /* IBM XL, Watcom, others? */
+# define KWIML_ABI_CHAR_IS_SIGNED 1
+# elif defined(__SIGNED_CHARS__) /* EDG, Intel, SGI MIPSpro */
+# define KWIML_ABI_CHAR_IS_SIGNED 1
+# elif defined(_CHAR_IS_SIGNED) /* Some SunPro, others? */
+# define KWIML_ABI_CHAR_IS_SIGNED 1
+# elif defined(_CHAR_IS_UNSIGNED) /* SunPro, others? */
+# define KWIML_ABI_CHAR_IS_UNSIGNED 1
+# elif defined(__GNUC__) /* GNU default */
+# define KWIML_ABI_CHAR_IS_SIGNED 1
+# elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* SunPro default */
+# define KWIML_ABI_CHAR_IS_SIGNED 1
+# elif defined(__HP_cc) || defined(__HP_aCC) /* HP default (unless +uc) */
+# define KWIML_ABI_CHAR_IS_SIGNED 1
+# elif defined(_SGI_COMPILER_VERSION) /* SGI MIPSpro default */
+# define KWIML_ABI_CHAR_IS_UNSIGNED 1
+# elif defined(__PGIC__) /* PGI default */
+# define KWIML_ABI_CHAR_IS_SIGNED 1
+# elif defined(_MSC_VER) /* MSVC default */
+# define KWIML_ABI_CHAR_IS_SIGNED 1
+# elif defined(__WATCOMC__) /* Watcom default */
+# define KWIML_ABI_CHAR_IS_UNSIGNED 1
+# elif defined(__BORLANDC__) /* Borland default */
+# define KWIML_ABI_CHAR_IS_SIGNED 1
+# elif defined(__hpux) /* Old HP: no __HP_cc/__HP_aCC/__GNUC__ above */
+# define KWIML_ABI_CHAR_IS_SIGNED 1 /* (unless +uc) */
+# endif
+#endif
+#if !defined(KWIML_ABI_CHAR_IS_UNSIGNED) && !defined(KWIML_ABI_CHAR_IS_SIGNED) \
+ && !defined(KWIML_ABI_NO_ERROR_CHAR_SIGN)
+# error "Signedness of 'char' unknown."
+#endif
+
+/*--------------------------------------------------------------------------*/
+#if !defined(KWIML_ABI_SIZEOF_SHORT)
+# if defined(__SIZEOF_SHORT__)
+# define KWIML_ABI_SIZEOF_SHORT __SIZEOF_SHORT__
+# endif
+#endif
+#if !defined(KWIML_ABI_SIZEOF_SHORT)
+# define KWIML_ABI_SIZEOF_SHORT 2
+#endif
+
+/*--------------------------------------------------------------------------*/
+#if !defined(KWIML_ABI_SIZEOF_INT)
+# if defined(__SIZEOF_INT__)
+# define KWIML_ABI_SIZEOF_INT __SIZEOF_INT__
+# elif defined(_SIZE_INT)
+# define KWIML_ABI_SIZEOF_INT (_SIZE_INT >> 3)
+# endif
+#endif
+#if !defined(KWIML_ABI_SIZEOF_INT)
+# define KWIML_ABI_SIZEOF_INT 4
+#endif
+
+/*--------------------------------------------------------------------------*/
+#if !defined(KWIML_ABI_SIZEOF_LONG)
+# if defined(__SIZEOF_LONG__)
+# define KWIML_ABI_SIZEOF_LONG __SIZEOF_LONG__
+# elif defined(_SIZE_LONG)
+# define KWIML_ABI_SIZEOF_LONG (_SIZE_LONG >> 3)
+# elif defined(__LONG_MAX__)
+# if __LONG_MAX__ == 0x7fffffff
+# define KWIML_ABI_SIZEOF_LONG 4
+# elif __LONG_MAX__>>32 == 0x7fffffff
+# define KWIML_ABI_SIZEOF_LONG 8
+# endif
+# elif defined(_MSC_VER) /* MSVC and Intel on Windows */
+# define KWIML_ABI_SIZEOF_LONG 4
+# endif
+#endif
+#if !defined(KWIML_ABI_SIZEOF_LONG)
+# define KWIML_ABI_SIZEOF_LONG KWIML_ABI_SIZEOF_DATA_PTR
+#endif
+
+/*--------------------------------------------------------------------------*/
+#if !defined(KWIML_ABI_SIZEOF_LONG_LONG)
+# if defined(__SIZEOF_LONG_LONG__)
+# define KWIML_ABI_SIZEOF_LONG_LONG __SIZEOF_LONG_LONG__
+# elif defined(__LONG_LONG_MAX__)
+# if __LONG_LONG_MAX__ == 0x7fffffff
+# define KWIML_ABI_SIZEOF_LONG_LONG 4
+# elif __LONG_LONG_MAX__>>32 == 0x7fffffff
+# define KWIML_ABI_SIZEOF_LONG_LONG 8
+# endif
+# endif
+#endif
+#if !defined(KWIML_ABI_SIZEOF_LONG_LONG)
+# if defined(_LONGLONG) /* SGI, some GNU, perhaps others. */ \
+ && !defined(_MSC_VER)
+# define KWIML_ABI_SIZEOF_LONG_LONG 8
+# elif defined(_LONG_LONG) /* IBM XL, perhaps others. */
+# define KWIML_ABI_SIZEOF_LONG_LONG 8
+# elif defined(__NO_LONG_LONG) /* EDG */
+# define KWIML_ABI_SIZEOF_LONG_LONG 0
+# elif defined(__cplusplus) && __cplusplus > 199711L /* C++0x */
+# define KWIML_ABI_SIZEOF_LONG_LONG 8
+# elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
+# define KWIML_ABI_SIZEOF_LONG_LONG 8
+# elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* SunPro */
+# define KWIML_ABI_SIZEOF_LONG_LONG 8
+# elif defined(__HP_cc) || defined(__HP_aCC) /* HP */
+# define KWIML_ABI_SIZEOF_LONG_LONG 8
+# elif defined(__PGIC__) /* PGI */
+# define KWIML_ABI_SIZEOF_LONG_LONG 8
+# elif defined(__WATCOMC__) /* Watcom */
+# define KWIML_ABI_SIZEOF_LONG_LONG 8
+# elif defined(__INTEL_COMPILER) /* Intel */
+# define KWIML_ABI_SIZEOF_LONG_LONG 8
+# elif defined(__BORLANDC__) /* Borland */
+# if __BORLANDC__ >= 0x0560
+# define KWIML_ABI_SIZEOF_LONG_LONG 8
+# else
+# define KWIML_ABI_SIZEOF_LONG_LONG 0
+# endif
+# elif defined(_MSC_VER) /* Microsoft */
+# if _MSC_VER >= 1310
+# define KWIML_ABI_SIZEOF_LONG_LONG 8
+# else
+# define KWIML_ABI_SIZEOF_LONG_LONG 0
+# endif
+# elif defined(__GNUC__) /* GNU */
+# define KWIML_ABI_SIZEOF_LONG_LONG 8
+# elif defined(__hpux) /* Old HP: no __HP_cc/__HP_aCC/__GNUC__ above */
+# define KWIML_ABI_SIZEOF_LONG_LONG 8
+# endif
+#endif
+#if !defined(KWIML_ABI_SIZEOF_LONG_LONG) && !defined(KWIML_ABI_NO_ERROR_LONG_LONG)
+# error "Existence of 'long long' unknown."
+#endif
+
+/*--------------------------------------------------------------------------*/
+#if !defined(KWIML_ABI_SIZEOF___INT64)
+# if defined(__INTEL_COMPILER)
+# define KWIML_ABI_SIZEOF___INT64 8
+# elif defined(_MSC_VER)
+# define KWIML_ABI_SIZEOF___INT64 8
+# elif defined(__BORLANDC__)
+# define KWIML_ABI_SIZEOF___INT64 8
+# else
+# define KWIML_ABI_SIZEOF___INT64 0
+# endif
+#endif
+
+#if defined(KWIML_ABI_SIZEOF___INT64) && KWIML_ABI_SIZEOF___INT64 > 0
+# if KWIML_ABI_SIZEOF_LONG == 8
+# define KWIML_ABI___INT64_IS_LONG 1
+# elif defined(KWIML_ABI_SIZEOF_LONG_LONG) && KWIML_ABI_SIZEOF_LONG_LONG == 8
+# define KWIML_ABI___INT64_IS_LONG_LONG 1
+# else
+# define KWIML_ABI___INT64_IS_UNIQUE 1
+# endif
+#endif
+
+/*--------------------------------------------------------------------------*/
+#if !defined(KWIML_ABI_SIZEOF_FLOAT)
+# if defined(__SIZEOF_FLOAT__)
+# define KWIML_ABI_SIZEOF_FLOAT __SIZEOF_FLOAT__
+# endif
+#endif
+#if !defined(KWIML_ABI_SIZEOF_FLOAT)
+# define KWIML_ABI_SIZEOF_FLOAT 4
+#endif
+
+/*--------------------------------------------------------------------------*/
+#if !defined(KWIML_ABI_SIZEOF_DOUBLE)
+# if defined(__SIZEOF_DOUBLE__)
+# define KWIML_ABI_SIZEOF_DOUBLE __SIZEOF_DOUBLE__
+# endif
+#endif
+#if !defined(KWIML_ABI_SIZEOF_DOUBLE)
+# define KWIML_ABI_SIZEOF_DOUBLE 8
+#endif
+
+/*--------------------------------------------------------------------------*/
+/* Identify possible endian cases. The macro KWIML_ABI_ENDIAN_ID will be
+ defined to one of these, or undefined if unknown. */
+#if !defined(KWIML_ABI_ENDIAN_ID_BIG)
+# define KWIML_ABI_ENDIAN_ID_BIG 4321
+#endif
+#if !defined(KWIML_ABI_ENDIAN_ID_LITTLE)
+# define KWIML_ABI_ENDIAN_ID_LITTLE 1234
+#endif
+#if KWIML_ABI_ENDIAN_ID_BIG == KWIML_ABI_ENDIAN_ID_LITTLE
+# error "KWIML_ABI_ENDIAN_ID_BIG == KWIML_ABI_ENDIAN_ID_LITTLE"
+#endif
+
+#if defined(KWIML_ABI_ENDIAN_ID) /* Skip #elif cases if already defined. */
+
+/* Use dedicated symbols if the compiler defines them. Do this first
+ because some architectures allow runtime byte order selection by
+ the operating system (values for such architectures below are
+ guesses for compilers that do not define a dedicated symbol).
+ Ensure that only one is defined in case the platform or a header
+ defines both as possible values for some third symbol. */
+#elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_BIG
+#elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_LITTLE
+#elif defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_BIG
+#elif defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_LITTLE
+
+/* Alpha */
+#elif defined(__alpha) || defined(__alpha__) || defined(_M_ALPHA)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_LITTLE
+
+/* Arm */
+#elif defined(__arm__)
+# if !defined(__ARMEB__)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_LITTLE
+# else
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_BIG
+# endif
+
+/* Intel x86 */
+#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_LITTLE
+#elif defined(_X86_) || defined(__THW_INTEL__) || defined(__I86__)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_LITTLE
+#elif defined(__MWERKS__) && defined(__INTEL__)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_LITTLE
+
+/* Intel x86-64 */
+#elif defined(__x86_64) || defined(__x86_64__) || defined(_M_X64)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_LITTLE
+#elif defined(__amd64) || defined(__amd64__)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_LITTLE
+
+/* Intel Architecture-64 (Itanium) */
+#elif defined(__ia64) || defined(__ia64__)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_LITTLE
+#elif defined(_IA64) || defined(__IA64__) || defined(_M_IA64)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_LITTLE
+
+/* PowerPC */
+#elif defined(__powerpc) || defined(__powerpc__)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_BIG
+#elif defined(__ppc) || defined(__ppc__) || defined(__POWERPC__)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_BIG
+
+/* SPARC */
+#elif defined(__sparc) || defined(__sparc__)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_BIG
+
+/* HP/PA RISC */
+#elif defined(__hppa) || defined(__hppa__)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_BIG
+
+/* Motorola 68k */
+#elif defined(__m68k__) || defined(M68000)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_BIG
+
+/* MIPSel (MIPS little endian) */
+#elif defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_LITTLE
+
+/* MIPSeb (MIPS big endian) */
+#elif defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_BIG
+
+/* MIPS (fallback, big endian) */
+#elif defined(__mips) || defined(__mips__) || defined(__MIPS__)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_BIG
+
+/* NIOS2 */
+#elif defined(__NIOS2__) || defined(__NIOS2) || defined(__nios2__)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_LITTLE
+
+/* OpenRISC 1000 */
+#elif defined(__or1k__)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_BIG
+
+/* RS/6000 */
+#elif defined(__THW_RS600) || defined(_IBMR2) || defined(_POWER)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_BIG
+#elif defined(_ARCH_PWR) || defined(_ARCH_PWR2)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_BIG
+
+/* System/370 */
+#elif defined(__370__) || defined(__THW_370__)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_BIG
+
+/* System/390 */
+#elif defined(__s390__) || defined(__s390x__)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_BIG
+
+/* z/Architecture */
+#elif defined(__SYSC_ZARCH__)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_BIG
+
+/* VAX */
+#elif defined(__vax__)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_BIG
+
+/* Aarch64 */
+#elif defined(__aarch64__)
+# if !defined(__AARCH64EB__)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_LITTLE
+# else
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_BIG
+# endif
+
+/* Xtensa */
+#elif defined(__XTENSA_EB__)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_BIG
+#elif defined(__XTENSA_EL__)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_LITTLE
+
+/* Unknown CPU */
+#elif !defined(KWIML_ABI_NO_ERROR_ENDIAN)
+# error "Byte order of target CPU unknown."
+#endif
+
+#endif /* KWIML_ABI_private_DO_DEFINE */
+
+/*--------------------------------------------------------------------------*/
+#ifdef KWIML_ABI_private_DO_VERIFY
+#undef KWIML_ABI_private_DO_VERIFY
+
+#if defined(_MSC_VER)
+# pragma warning (push)
+# pragma warning (disable:4310) /* cast truncates constant value */
+#endif
+
+#define KWIML_ABI_private_VERIFY(n, x, y) KWIML_ABI_private_VERIFY_0(KWIML_ABI_private_VERSION, n, x, y)
+#define KWIML_ABI_private_VERIFY_0(V, n, x, y) KWIML_ABI_private_VERIFY_1(V, n, x, y)
+#define KWIML_ABI_private_VERIFY_1(V, n, x, y) extern int (*n##_v##V)[x]; extern int (*n##_v##V)[y]
+
+#define KWIML_ABI_private_VERIFY_SAME_IMPL(n, x, y) KWIML_ABI_private_VERIFY_SAME_IMPL_0(KWIML_ABI_private_VERSION, n, x, y)
+#define KWIML_ABI_private_VERIFY_SAME_IMPL_0(V, n, x, y) KWIML_ABI_private_VERIFY_SAME_IMPL_1(V, n, x, y)
+#define KWIML_ABI_private_VERIFY_SAME_IMPL_1(V, n, x, y) extern int (*n##_v##V)(x*); extern int (*n##_v##V)(y*)
+
+#define KWIML_ABI_private_VERIFY_DIFF_IMPL(n, x, y) KWIML_ABI_private_VERIFY_DIFF_IMPL_0(KWIML_ABI_private_VERSION, n, x, y)
+#define KWIML_ABI_private_VERIFY_DIFF_IMPL_0(V, n, x, y) KWIML_ABI_private_VERIFY_DIFF_IMPL_1(V, n, x, y)
+#if defined(__cplusplus)
+# define KWIML_ABI_private_VERIFY_DIFF_IMPL_1(V, n, x, y) extern int* n##_v##V(x*); extern char* n##_v##V(y*)
+#else
+# define KWIML_ABI_private_VERIFY_DIFF_IMPL_1(V, n, x, y) extern int* n##_v##V(x*) /* TODO: possible? */
+#endif
+
+#define KWIML_ABI_private_VERIFY_BOOL(m, b) KWIML_ABI_private_VERIFY(KWIML_ABI_detail_VERIFY_##m, 2, (b)?2:3)
+#define KWIML_ABI_private_VERIFY_SIZE(m, t) KWIML_ABI_private_VERIFY(KWIML_ABI_detail_VERIFY_##m, m, sizeof(t))
+#define KWIML_ABI_private_VERIFY_SAME(m, x, y) KWIML_ABI_private_VERIFY_SAME_IMPL(KWIML_ABI_detail_VERIFY_##m, x, y)
+#define KWIML_ABI_private_VERIFY_DIFF(m, x, y) KWIML_ABI_private_VERIFY_DIFF_IMPL(KWIML_ABI_detail_VERIFY_##m, x, y)
+
+KWIML_ABI_private_VERIFY_SIZE(KWIML_ABI_SIZEOF_DATA_PTR, int*);
+KWIML_ABI_private_VERIFY_SIZE(KWIML_ABI_SIZEOF_CODE_PTR, int(*)(int));
+KWIML_ABI_private_VERIFY_SIZE(KWIML_ABI_SIZEOF_CHAR, char);
+KWIML_ABI_private_VERIFY_SIZE(KWIML_ABI_SIZEOF_SHORT, short);
+KWIML_ABI_private_VERIFY_SIZE(KWIML_ABI_SIZEOF_INT, int);
+KWIML_ABI_private_VERIFY_SIZE(KWIML_ABI_SIZEOF_LONG, long);
+#if defined(KWIML_ABI_SIZEOF_LONG_LONG) && KWIML_ABI_SIZEOF_LONG_LONG > 0
+KWIML_ABI_private_VERIFY_SIZE(KWIML_ABI_SIZEOF_LONG_LONG, long long);
+#endif
+#if defined(KWIML_ABI_SIZEOF___INT64) && KWIML_ABI_SIZEOF___INT64 > 0
+KWIML_ABI_private_VERIFY_SIZE(KWIML_ABI_SIZEOF___INT64, __int64);
+#endif
+KWIML_ABI_private_VERIFY_SIZE(KWIML_ABI_SIZEOF_FLOAT, float);
+KWIML_ABI_private_VERIFY_SIZE(KWIML_ABI_SIZEOF_DOUBLE, double);
+
+#if defined(KWIML_ABI___INT64_IS_LONG)
+KWIML_ABI_private_VERIFY_SAME(KWIML_ABI___INT64_IS_LONG, __int64, long);
+#elif defined(KWIML_ABI___INT64_IS_LONG_LONG)
+KWIML_ABI_private_VERIFY_SAME(KWIML_ABI___INT64_IS_LONG_LONG, __int64, long long);
+#elif defined(KWIML_ABI_SIZEOF___INT64) && KWIML_ABI_SIZEOF___INT64 > 0
+KWIML_ABI_private_VERIFY_DIFF(KWIML_ABI___INT64_NOT_LONG, __int64, long);
+# if defined(KWIML_ABI_SIZEOF_LONG_LONG) && KWIML_ABI_SIZEOF_LONG_LONG > 0
+KWIML_ABI_private_VERIFY_DIFF(KWIML_ABI___INT64_NOT_LONG_LONG, __int64, long long);
+# endif
+#endif
+
+#if defined(KWIML_ABI_CHAR_IS_UNSIGNED)
+KWIML_ABI_private_VERIFY_BOOL(KWIML_ABI_CHAR_IS_UNSIGNED, (char)0x80 > 0);
+#elif defined(KWIML_ABI_CHAR_IS_SIGNED)
+KWIML_ABI_private_VERIFY_BOOL(KWIML_ABI_CHAR_IS_SIGNED, (char)0x80 < 0);
+#endif
+
+#undef KWIML_ABI_private_VERIFY_DIFF
+#undef KWIML_ABI_private_VERIFY_SAME
+#undef KWIML_ABI_private_VERIFY_SIZE
+#undef KWIML_ABI_private_VERIFY_BOOL
+
+#undef KWIML_ABI_private_VERIFY_DIFF_IMPL_1
+#undef KWIML_ABI_private_VERIFY_DIFF_IMPL_0
+#undef KWIML_ABI_private_VERIFY_DIFF_IMPL
+
+#undef KWIML_ABI_private_VERIFY_SAME_IMPL_1
+#undef KWIML_ABI_private_VERIFY_SAME_IMPL_0
+#undef KWIML_ABI_private_VERIFY_SAME_IMPL
+
+#undef KWIML_ABI_private_VERIFY_1
+#undef KWIML_ABI_private_VERIFY_0
+#undef KWIML_ABI_private_VERIFY
+
+#if defined(_MSC_VER)
+# pragma warning (pop)
+#endif
+
+#endif /* KWIML_ABI_private_DO_VERIFY */
+
+#undef KWIML_ABI_private_VERSION
diff --git a/Utilities/KWIML/include/kwiml/int.h b/Utilities/KWIML/include/kwiml/int.h
new file mode 100644
index 000000000..b297acee4
--- /dev/null
+++ b/Utilities/KWIML/include/kwiml/int.h
@@ -0,0 +1,1069 @@
+/*============================================================================
+ Kitware Information Macro Library
+ Copyright 2010-2015 Kitware, Inc.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of Kitware, Inc. nor the names of its contributors
+ may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+============================================================================*/
+/*
+This header defines macros with information about sized integer types.
+Only information that can be determined using the preprocessor at
+compilation time is available. No try-compile results may be added
+here. Instead we memorize results on platforms of interest.
+
+An includer may optionally define the following macros to suppress errors:
+
+Input:
+ KWIML_INT_NO_VERIFY = skip verification declarations
+ KWIML_INT_NO_ERROR_INT64_T = type 'KWIML_INT_int64_t' is optional (*)
+ KWIML_INT_NO_ERROR_UINT64_T = type 'KWIML_INT_uint64_t' is optional (*)
+ KWIML_INT_NO_ERROR_INTPTR_T = type 'KWIML_INT_intptr_t' is optional (*)
+ KWIML_INT_NO_ERROR_UINTPTR_T = type 'KWIML_INT_uintptr_t' is optional (*)
+
+An includer may optionally define the following macros to override defaults.
+Either way, an includer may test these macros after inclusion:
+
+ KWIML_INT_HAVE_STDINT_H = include <stdint.h>
+ KWIML_INT_NO_STDINT_H = do not include <stdint.h>
+ KWIML_INT_HAVE_INTTYPES_H = include <inttypes.h>
+ KWIML_INT_NO_INTTYPES_H = do not include <inttypes.h>
+
+An includer may test the following macros after inclusion:
+
+ KWIML_INT_VERSION = interface version number # of this header
+
+ KWIML_INT_HAVE_INT#_T = type 'int#_t' is available
+ KWIML_INT_HAVE_UINT#_T = type 'uint#_t' is available
+ # = 8, 16, 32, 64, PTR
+
+ KWIML_INT_int#_t = signed integer type exactly # bits wide
+ KWIML_INT_uint#_t = unsigned integer type exactly # bits wide
+ # = 8, 16, 32, 64 (*), ptr (*)
+
+ KWIML_INT_NO_INT64_T = type 'KWIML_INT_int64_t' not available
+ KWIML_INT_NO_UINT64_T = type 'KWIML_INT_uint64_t' not available
+ KWIML_INT_NO_INTPTR_T = type 'KWIML_INT_intptr_t' not available
+ KWIML_INT_NO_UINTPTR_T = type 'KWIML_INT_uintptr_t' not available
+
+ KWIML_INT_INT#_C(c) = signed integer constant at least # bits wide
+ KWIML_INT_UINT#_C(c) = unsigned integer constant at least # bits wide
+ # = 8, 16, 32, 64 (*)
+
+ KWIML_INT_<fmt># = print or scan format, <fmt> in table below
+ # = 8, 16, 32, 64, PTR (*)
+
+ signed unsigned
+ ----------- ------------------------------
+ | decimal | decimal octal hexadecimal |
+ print | PRId PRIi | PRIu PRIo PRIx PRIX |
+ scan | SCNd SCNi | SCNu SCNo SCNx |
+ ----------- ------------------------------
+
+ The SCN*8 and SCN*64 format macros will not be defined on systems
+ with scanf implementations known not to support them.
+
+ KWIML_INT_BROKEN_<fmt># = macro <fmt># is incorrect if defined
+ Some compilers define integer format macros incorrectly for their
+ own formatted print/scan implementations.
+
+ KWIML_INT_BROKEN_INT#_C = macro INT#_C is incorrect if defined
+ KWIML_INT_BROKEN_UINT#_C = macro UINT#_C is incorrect if defined
+ Some compilers define integer constant macros incorrectly and
+ cannot handle literals as large as the integer type or even
+ produce bad preprocessor syntax.
+
+ KWIML_INT_BROKEN_INT8_T = type 'int8_t' is available but incorrect
+ Some compilers have a flag to make 'char' (un)signed but do not account
+ for it while defining int8_t in the non-default case.
+
+ The broken cases do not affect correctness of the macros documented above.
+*/
+
+#include "abi.h"
+
+#define KWIML_INT_private_VERSION 1
+
+/* Guard definition of this version. */
+#ifndef KWIML_INT_detail_DEFINED_VERSION_1
+# define KWIML_INT_detail_DEFINED_VERSION_1 1
+# define KWIML_INT_private_DO_DEFINE
+#endif
+
+/* Guard verification of this version. */
+#if !defined(KWIML_INT_NO_VERIFY)
+# ifndef KWIML_INT_detail_VERIFIED_VERSION_1
+# define KWIML_INT_detail_VERIFIED_VERSION_1
+# define KWIML_INT_private_DO_VERIFY
+# endif
+#endif
+
+#ifdef KWIML_INT_private_DO_DEFINE
+#undef KWIML_INT_private_DO_DEFINE
+
+/* Define version as most recent of those included. */
+#if !defined(KWIML_INT_VERSION) || KWIML_INT_VERSION < KWIML_INT_private_VERSION
+# undef KWIML_INT_VERSION
+# define KWIML_INT_VERSION 1
+#endif
+
+/*--------------------------------------------------------------------------*/
+#if defined(KWIML_INT_HAVE_STDINT_H) /* Already defined. */
+#elif defined(KWIML_INT_NO_STDINT_H) /* Already defined. */
+#elif defined(HAVE_STDINT_H) /* Optionally provided by includer. */
+# define KWIML_INT_HAVE_STDINT_H 1
+#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
+# define KWIML_INT_HAVE_STDINT_H 1
+#elif defined(_MSC_VER) /* MSVC */
+# if _MSC_VER >= 1600
+# define KWIML_INT_HAVE_STDINT_H 1
+# else
+# define KWIML_INT_NO_STDINT_H 1
+# endif
+#elif defined(__BORLANDC__) /* Borland */
+# if __BORLANDC__ >= 0x560
+# define KWIML_INT_HAVE_STDINT_H 1
+# else
+# define KWIML_INT_NO_STDINT_H 1
+# endif
+#elif defined(__WATCOMC__) /* Watcom */
+# define KWIML_INT_NO_STDINT_H 1
+#endif
+
+/*--------------------------------------------------------------------------*/
+#if defined(KWIML_INT_HAVE_INTTYPES_H) /* Already defined. */
+#elif defined(KWIML_INT_NO_INTTYPES_H) /* Already defined. */
+#elif defined(HAVE_INTTYPES_H) /* Optionally provided by includer. */
+# define KWIML_INT_HAVE_INTTYPES_H 1
+#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
+# define KWIML_INT_HAVE_INTTYPES_H 1
+#elif defined(_MSC_VER) /* MSVC */
+# define KWIML_INT_NO_INTTYPES_H 1
+#elif defined(__BORLANDC__) /* Borland */
+# define KWIML_INT_NO_INTTYPES_H 1
+#elif defined(__WATCOMC__) /* Watcom */
+# define KWIML_INT_NO_INTTYPES_H 1
+#else /* Assume it exists. */
+# define KWIML_INT_HAVE_INTTYPES_H 1
+#endif
+
+/*--------------------------------------------------------------------------*/
+#if defined(KWIML_INT_HAVE_STDINT_H) && defined(KWIML_INT_NO_STDINT_H)
+# error "Both KWIML_INT_HAVE_STDINT_H and KWIML_INT_NO_STDINT_H defined!"
+#endif
+#if defined(KWIML_INT_HAVE_INTTYPES_H) && defined(KWIML_INT_NO_INTTYPES_H)
+# error "Both KWIML_INT_HAVE_INTTYPES_H and KWIML_INT_NO_INTTYPES_H defined!"
+#endif
+
+#if defined(KWIML_INT_HAVE_STDINT_H)
+# ifndef KWIML_INT_detail_INCLUDED_STDINT_H
+# define KWIML_INT_detail_INCLUDED_STDINT_H
+# include <stdint.h>
+# endif
+#endif
+#if defined(KWIML_INT_HAVE_INTTYPES_H)
+# ifndef KWIML_INT_detail_INCLUDED_INTTYPES_H
+# define KWIML_INT_detail_INCLUDED_INTTYPES_H
+# if defined(__cplusplus) && !defined(__STDC_FORMAT_MACROS)
+# define __STDC_FORMAT_MACROS
+# endif
+# include <inttypes.h>
+# endif
+#endif
+
+#if defined(KWIML_INT_HAVE_STDINT_H) || defined(KWIML_INT_HAVE_INTTYPES_H)
+#define KWIML_INT_HAVE_INT8_T 1
+#define KWIML_INT_HAVE_UINT8_T 1
+#define KWIML_INT_HAVE_INT16_T 1
+#define KWIML_INT_HAVE_UINT16_T 1
+#define KWIML_INT_HAVE_INT32_T 1
+#define KWIML_INT_HAVE_UINT32_T 1
+#define KWIML_INT_HAVE_INT64_T 1
+#define KWIML_INT_HAVE_UINT64_T 1
+#define KWIML_INT_HAVE_INTPTR_T 1
+#define KWIML_INT_HAVE_UINTPTR_T 1
+# if defined(__cplusplus)
+# define KWIML_INT_detail_GLOBAL_NS(T) ::T
+# else
+# define KWIML_INT_detail_GLOBAL_NS(T) T
+# endif
+#endif
+
+#if defined(_AIX43) && !defined(_AIX50) && !defined(_AIX51)
+ /* AIX 4.3 defines these incorrectly with % and no quotes. */
+# define KWIML_INT_BROKEN_PRId8 1
+# define KWIML_INT_BROKEN_SCNd8 1
+# define KWIML_INT_BROKEN_PRIi8 1
+# define KWIML_INT_BROKEN_SCNi8 1
+# define KWIML_INT_BROKEN_PRIo8 1
+# define KWIML_INT_BROKEN_SCNo8 1
+# define KWIML_INT_BROKEN_PRIu8 1
+# define KWIML_INT_BROKEN_SCNu8 1
+# define KWIML_INT_BROKEN_PRIx8 1
+# define KWIML_INT_BROKEN_SCNx8 1
+# define KWIML_INT_BROKEN_PRIX8 1
+# define KWIML_INT_BROKEN_PRId16 1
+# define KWIML_INT_BROKEN_SCNd16 1
+# define KWIML_INT_BROKEN_PRIi16 1
+# define KWIML_INT_BROKEN_SCNi16 1
+# define KWIML_INT_BROKEN_PRIo16 1
+# define KWIML_INT_BROKEN_SCNo16 1
+# define KWIML_INT_BROKEN_PRIu16 1
+# define KWIML_INT_BROKEN_SCNu16 1
+# define KWIML_INT_BROKEN_PRIx16 1
+# define KWIML_INT_BROKEN_SCNx16 1
+# define KWIML_INT_BROKEN_PRIX16 1
+# define KWIML_INT_BROKEN_PRId32 1
+# define KWIML_INT_BROKEN_SCNd32 1
+# define KWIML_INT_BROKEN_PRIi32 1
+# define KWIML_INT_BROKEN_SCNi32 1
+# define KWIML_INT_BROKEN_PRIo32 1
+# define KWIML_INT_BROKEN_SCNo32 1
+# define KWIML_INT_BROKEN_PRIu32 1
+# define KWIML_INT_BROKEN_SCNu32 1
+# define KWIML_INT_BROKEN_PRIx32 1
+# define KWIML_INT_BROKEN_SCNx32 1
+# define KWIML_INT_BROKEN_PRIX32 1
+# define KWIML_INT_BROKEN_PRId64 1
+# define KWIML_INT_BROKEN_SCNd64 1
+# define KWIML_INT_BROKEN_PRIi64 1
+# define KWIML_INT_BROKEN_SCNi64 1
+# define KWIML_INT_BROKEN_PRIo64 1
+# define KWIML_INT_BROKEN_SCNo64 1
+# define KWIML_INT_BROKEN_PRIu64 1
+# define KWIML_INT_BROKEN_SCNu64 1
+# define KWIML_INT_BROKEN_PRIx64 1
+# define KWIML_INT_BROKEN_SCNx64 1
+# define KWIML_INT_BROKEN_PRIX64 1
+# define KWIML_INT_BROKEN_PRIdPTR 1
+# define KWIML_INT_BROKEN_SCNdPTR 1
+# define KWIML_INT_BROKEN_PRIiPTR 1
+# define KWIML_INT_BROKEN_SCNiPTR 1
+# define KWIML_INT_BROKEN_PRIoPTR 1
+# define KWIML_INT_BROKEN_SCNoPTR 1
+# define KWIML_INT_BROKEN_PRIuPTR 1
+# define KWIML_INT_BROKEN_SCNuPTR 1
+# define KWIML_INT_BROKEN_PRIxPTR 1
+# define KWIML_INT_BROKEN_SCNxPTR 1
+# define KWIML_INT_BROKEN_PRIXPTR 1
+#endif
+
+#if (defined(__SUNPRO_C)||defined(__SUNPRO_CC)) && defined(_CHAR_IS_UNSIGNED)
+# define KWIML_INT_BROKEN_INT8_T 1 /* system type defined incorrectly */
+#elif defined(__BORLANDC__) && defined(_CHAR_UNSIGNED)
+# define KWIML_INT_BROKEN_INT8_T 1 /* system type defined incorrectly */
+#endif
+
+/*--------------------------------------------------------------------------*/
+#if !defined(KWIML_INT_int8_t)
+# if defined(KWIML_INT_HAVE_INT8_T) && !defined(KWIML_INT_BROKEN_INT8_T)
+# define KWIML_INT_int8_t KWIML_INT_detail_GLOBAL_NS(int8_t)
+# else
+# define KWIML_INT_int8_t signed char
+# endif
+#endif
+#if !defined(KWIML_INT_uint8_t)
+# if defined(KWIML_INT_HAVE_UINT8_T)
+# define KWIML_INT_uint8_t KWIML_INT_detail_GLOBAL_NS(uint8_t)
+# else
+# define KWIML_INT_uint8_t unsigned char
+# endif
+#endif
+
+#if defined(__INTEL_COMPILER)
+# if defined(_WIN32)
+# define KWIML_INT_private_NO_SCN8
+# endif
+#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+# define KWIML_INT_private_NO_SCN8
+#elif defined(__BORLANDC__)
+# define KWIML_INT_private_NO_SCN8
+# define KWIML_INT_private_NO_SCN64
+#elif defined(_MSC_VER)
+# define KWIML_INT_private_NO_SCN8
+#elif defined(__WATCOMC__)
+# define KWIML_INT_private_NO_SCN8
+# elif defined(__hpux) /* HP runtime lacks support (any compiler) */
+# define KWIML_INT_private_NO_SCN8
+#endif
+
+/* 8-bit d, i */
+#if !defined(KWIML_INT_PRId8)
+# if defined(KWIML_INT_HAVE_INT8_T) && defined(PRId8) \
+ && !defined(KWIML_INT_BROKEN_PRId8)
+# define KWIML_INT_PRId8 PRId8
+# else
+# define KWIML_INT_PRId8 "d"
+# endif
+#endif
+#if !defined(KWIML_INT_SCNd8)
+# if defined(KWIML_INT_HAVE_INT8_T) && defined(SCNd8) \
+ && !defined(KWIML_INT_BROKEN_SCNd8)
+# define KWIML_INT_SCNd8 SCNd8
+# elif !defined(KWIML_INT_private_NO_SCN8)
+# define KWIML_INT_SCNd8 "hhd"
+# endif
+#endif
+#if !defined(KWIML_INT_PRIi8)
+# if defined(KWIML_INT_HAVE_INT8_T) && defined(PRIi8) \
+ && !defined(KWIML_INT_BROKEN_PRIi8)
+# define KWIML_INT_PRIi8 PRIi8
+# else
+# define KWIML_INT_PRIi8 "i"
+# endif
+#endif
+#if !defined(KWIML_INT_SCNi8)
+# if defined(KWIML_INT_HAVE_INT8_T) && defined(SCNi8) \
+ && !defined(KWIML_INT_BROKEN_SCNi8)
+# define KWIML_INT_SCNi8 SCNi8
+# elif !defined(KWIML_INT_private_NO_SCN8)
+# define KWIML_INT_SCNi8 "hhi"
+# endif
+#endif
+
+/* 8-bit o, u, x, X */
+#if !defined(KWIML_INT_PRIo8)
+# if defined(KWIML_INT_HAVE_UINT8_T) && defined(PRIo8) \
+ && !defined(KWIML_INT_BROKEN_PRIo8)
+# define KWIML_INT_PRIo8 PRIo8
+# else
+# define KWIML_INT_PRIo8 "o"
+# endif
+#endif
+#if !defined(KWIML_INT_SCNo8)
+# if defined(KWIML_INT_HAVE_UINT8_T) && defined(SCNo8) \
+ && !defined(KWIML_INT_BROKEN_SCNo8)
+# define KWIML_INT_SCNo8 SCNo8
+# elif !defined(KWIML_INT_private_NO_SCN8)
+# define KWIML_INT_SCNo8 "hho"
+# endif
+#endif
+#if !defined(KWIML_INT_PRIu8)
+# if defined(KWIML_INT_HAVE_UINT8_T) && defined(PRIu8) \
+ && !defined(KWIML_INT_BROKEN_PRIu8)
+# define KWIML_INT_PRIu8 PRIu8
+# else
+# define KWIML_INT_PRIu8 "u"
+# endif
+#endif
+#if !defined(KWIML_INT_SCNu8)
+# if defined(KWIML_INT_HAVE_UINT8_T) && defined(SCNu8) \
+ && !defined(KWIML_INT_BROKEN_SCNu8)
+# define KWIML_INT_SCNu8 SCNu8
+# elif !defined(KWIML_INT_private_NO_SCN8)
+# define KWIML_INT_SCNu8 "hhu"
+# endif
+#endif
+#if !defined(KWIML_INT_PRIx8)
+# if defined(KWIML_INT_HAVE_UINT8_T) && defined(PRIx8) \
+ && !defined(KWIML_INT_BROKEN_PRIx8)
+# define KWIML_INT_PRIx8 PRIx8
+# else
+# define KWIML_INT_PRIx8 "x"
+# endif
+#endif
+#if !defined(KWIML_INT_SCNx8)
+# if defined(KWIML_INT_HAVE_UINT8_T) && defined(SCNx8) \
+ && !defined(KWIML_INT_BROKEN_SCNx8)
+# define KWIML_INT_SCNx8 SCNx8
+# elif !defined(KWIML_INT_private_NO_SCN8)
+# define KWIML_INT_SCNx8 "hhx"
+# endif
+#endif
+#if !defined(KWIML_INT_PRIX8)
+# if defined(KWIML_INT_HAVE_UINT8_T) && defined(PRIX8) \
+ && !defined(KWIML_INT_BROKEN_PRIX8)
+# define KWIML_INT_PRIX8 PRIX8
+# else
+# define KWIML_INT_PRIX8 "X"
+# endif
+#endif
+
+/* 8-bit constants */
+#if !defined(KWIML_INT_INT8_C)
+# if defined(INT8_C) && !defined(KWIML_INT_BROKEN_INT8_C)
+# define KWIML_INT_INT8_C(c) INT8_C(c)
+# else
+# define KWIML_INT_INT8_C(c) c
+# endif
+#endif
+#if !defined(KWIML_INT_UINT8_C)
+# if defined(UINT8_C) && !defined(KWIML_INT_BROKEN_UINT8_C)
+# define KWIML_INT_UINT8_C(c) UINT8_C(c)
+# else
+# define KWIML_INT_UINT8_C(c) c ## u
+# endif
+#endif
+
+/*--------------------------------------------------------------------------*/
+#if !defined(KWIML_INT_int16_t)
+# if defined(KWIML_INT_HAVE_INT16_T)
+# define KWIML_INT_int16_t KWIML_INT_detail_GLOBAL_NS(int16_t)
+# else
+# define KWIML_INT_int16_t signed short
+# endif
+#endif
+#if !defined(KWIML_INT_uint16_t)
+# if defined(KWIML_INT_HAVE_UINT16_T)
+# define KWIML_INT_uint16_t KWIML_INT_detail_GLOBAL_NS(uint16_t)
+# else
+# define KWIML_INT_uint16_t unsigned short
+# endif
+#endif
+
+/* 16-bit d, i */
+#if !defined(KWIML_INT_PRId16)
+# if defined(KWIML_INT_HAVE_INT16_T) && defined(PRId16) \
+ && !defined(KWIML_INT_BROKEN_PRId16)
+# define KWIML_INT_PRId16 PRId16
+# else
+# define KWIML_INT_PRId16 "d"
+# endif
+#endif
+#if !defined(KWIML_INT_SCNd16)
+# if defined(KWIML_INT_HAVE_INT16_T) && defined(SCNd16) \
+ && !defined(KWIML_INT_BROKEN_SCNd16)
+# define KWIML_INT_SCNd16 SCNd16
+# else
+# define KWIML_INT_SCNd16 "hd"
+# endif
+#endif
+#if !defined(KWIML_INT_PRIi16)
+# if defined(KWIML_INT_HAVE_INT16_T) && defined(PRIi16) \
+ && !defined(KWIML_INT_BROKEN_PRIi16)
+# define KWIML_INT_PRIi16 PRIi16
+# else
+# define KWIML_INT_PRIi16 "i"
+# endif
+#endif
+#if !defined(KWIML_INT_SCNi16)
+# if defined(KWIML_INT_HAVE_INT16_T) && defined(SCNi16) \
+ && !defined(KWIML_INT_BROKEN_SCNi16)
+# define KWIML_INT_SCNi16 SCNi16
+# else
+# define KWIML_INT_SCNi16 "hi"
+# endif
+#endif
+
+/* 16-bit o, u, x, X */
+#if !defined(KWIML_INT_PRIo16)
+# if defined(KWIML_INT_HAVE_UINT16_T) && defined(PRIo16) \
+ && !defined(KWIML_INT_BROKEN_PRIo16)
+# define KWIML_INT_PRIo16 PRIo16
+# else
+# define KWIML_INT_PRIo16 "o"
+# endif
+#endif
+#if !defined(KWIML_INT_SCNo16)
+# if defined(KWIML_INT_HAVE_UINT16_T) && defined(SCNo16) \
+ && !defined(KWIML_INT_BROKEN_SCNo16)
+# define KWIML_INT_SCNo16 SCNo16
+# else
+# define KWIML_INT_SCNo16 "ho"
+# endif
+#endif
+#if !defined(KWIML_INT_PRIu16)
+# if defined(KWIML_INT_HAVE_UINT16_T) && defined(PRIu16) \
+ && !defined(KWIML_INT_BROKEN_PRIu16)
+# define KWIML_INT_PRIu16 PRIu16
+# else
+# define KWIML_INT_PRIu16 "u"
+# endif
+#endif
+#if !defined(KWIML_INT_SCNu16)
+# if defined(KWIML_INT_HAVE_UINT16_T) && defined(SCNu16) \
+ && !defined(KWIML_INT_BROKEN_SCNu16)
+# define KWIML_INT_SCNu16 SCNu16
+# else
+# define KWIML_INT_SCNu16 "hu"
+# endif
+#endif
+#if !defined(KWIML_INT_PRIx16)
+# if defined(KWIML_INT_HAVE_UINT16_T) && defined(PRIx16) \
+ && !defined(KWIML_INT_BROKEN_PRIx16)
+# define KWIML_INT_PRIx16 PRIx16
+# else
+# define KWIML_INT_PRIx16 "x"
+# endif
+#endif
+#if !defined(KWIML_INT_SCNx16)
+# if defined(KWIML_INT_HAVE_UINT16_T) && defined(SCNx16) \
+ && !defined(KWIML_INT_BROKEN_SCNx16)
+# define KWIML_INT_SCNx16 SCNx16
+# else
+# define KWIML_INT_SCNx16 "hx"
+# endif
+#endif
+#if !defined(KWIML_INT_PRIX16)
+# if defined(KWIML_INT_HAVE_UINT16_T) && defined(PRIX16) \
+ && !defined(KWIML_INT_BROKEN_PRIX16)
+# define KWIML_INT_PRIX16 PRIX16
+# else
+# define KWIML_INT_PRIX16 "X"
+# endif
+#endif
+
+/* 16-bit constants */
+#if !defined(KWIML_INT_INT16_C)
+# if defined(INT16_C) && !defined(KWIML_INT_BROKEN_INT16_C)
+# define KWIML_INT_INT16_C(c) INT16_C(c)
+# else
+# define KWIML_INT_INT16_C(c) c
+# endif
+#endif
+#if !defined(KWIML_INT_UINT16_C)
+# if defined(UINT16_C) && !defined(KWIML_INT_BROKEN_UINT16_C)
+# define KWIML_INT_UINT16_C(c) UINT16_C(c)
+# else
+# define KWIML_INT_UINT16_C(c) c ## u
+# endif
+#endif
+
+/*--------------------------------------------------------------------------*/
+#if !defined(KWIML_INT_int32_t)
+# if defined(KWIML_INT_HAVE_INT32_T)
+# define KWIML_INT_int32_t KWIML_INT_detail_GLOBAL_NS(int32_t)
+# else
+# define KWIML_INT_int32_t signed int
+# endif
+#endif
+#if !defined(KWIML_INT_uint32_t)
+# if defined(KWIML_INT_HAVE_UINT32_T)
+# define KWIML_INT_uint32_t KWIML_INT_detail_GLOBAL_NS(uint32_t)
+# else
+# define KWIML_INT_uint32_t unsigned int
+# endif
+#endif
+
+/* 32-bit d, i */
+#if !defined(KWIML_INT_PRId32)
+# if defined(KWIML_INT_HAVE_INT32_T) && defined(PRId32) \
+ && !defined(KWIML_INT_BROKEN_PRId32)
+# define KWIML_INT_PRId32 PRId32
+# else
+# define KWIML_INT_PRId32 "d"
+# endif
+#endif
+#if !defined(KWIML_INT_SCNd32)
+# if defined(KWIML_INT_HAVE_INT32_T) && defined(SCNd32) \
+ && !defined(KWIML_INT_BROKEN_SCNd32)
+# define KWIML_INT_SCNd32 SCNd32
+# else
+# define KWIML_INT_SCNd32 "d"
+# endif
+#endif
+#if !defined(KWIML_INT_PRIi32)
+# if defined(KWIML_INT_HAVE_INT32_T) && defined(PRIi32) \
+ && !defined(KWIML_INT_BROKEN_PRIi32)
+# define KWIML_INT_PRIi32 PRIi32
+# else
+# define KWIML_INT_PRIi32 "i"
+# endif
+#endif
+#if !defined(KWIML_INT_SCNi32)
+# if defined(KWIML_INT_HAVE_INT32_T) && defined(SCNi32) \
+ && !defined(KWIML_INT_BROKEN_SCNi32)
+# define KWIML_INT_SCNi32 SCNi32
+# else
+# define KWIML_INT_SCNi32 "i"
+# endif
+#endif
+
+/* 32-bit o, u, x, X */
+#if !defined(KWIML_INT_PRIo32)
+# if defined(KWIML_INT_HAVE_UINT32_T) && defined(PRIo32) \
+ && !defined(KWIML_INT_BROKEN_PRIo32)
+# define KWIML_INT_PRIo32 PRIo32
+# else
+# define KWIML_INT_PRIo32 "o"
+# endif
+#endif
+#if !defined(KWIML_INT_SCNo32)
+# if defined(KWIML_INT_HAVE_UINT32_T) && defined(SCNo32) \
+ && !defined(KWIML_INT_BROKEN_SCNo32)
+# define KWIML_INT_SCNo32 SCNo32
+# else
+# define KWIML_INT_SCNo32 "o"
+# endif
+#endif
+#if !defined(KWIML_INT_PRIu32)
+# if defined(KWIML_INT_HAVE_UINT32_T) && defined(PRIu32) \
+ && !defined(KWIML_INT_BROKEN_PRIu32)
+# define KWIML_INT_PRIu32 PRIu32
+# else
+# define KWIML_INT_PRIu32 "u"
+# endif
+#endif
+#if !defined(KWIML_INT_SCNu32)
+# if defined(KWIML_INT_HAVE_UINT32_T) && defined(SCNu32) \
+ && !defined(KWIML_INT_BROKEN_SCNu32)
+# define KWIML_INT_SCNu32 SCNu32
+# else
+# define KWIML_INT_SCNu32 "u"
+# endif
+#endif
+#if !defined(KWIML_INT_PRIx32)
+# if defined(KWIML_INT_HAVE_UINT32_T) && defined(PRIx32) \
+ && !defined(KWIML_INT_BROKEN_PRIx32)
+# define KWIML_INT_PRIx32 PRIx32
+# else
+# define KWIML_INT_PRIx32 "x"
+# endif
+#endif
+#if !defined(KWIML_INT_SCNx32)
+# if defined(KWIML_INT_HAVE_UINT32_T) && defined(SCNx32) \
+ && !defined(KWIML_INT_BROKEN_SCNx32)
+# define KWIML_INT_SCNx32 SCNx32
+# else
+# define KWIML_INT_SCNx32 "x"
+# endif
+#endif
+#if !defined(KWIML_INT_PRIX32)
+# if defined(KWIML_INT_HAVE_UINT32_T) && defined(PRIX32) \
+ && !defined(KWIML_INT_BROKEN_PRIX32)
+# define KWIML_INT_PRIX32 PRIX32
+# else
+# define KWIML_INT_PRIX32 "X"
+# endif
+#endif
+
+#if defined(__hpux) && defined(__GNUC__) && !defined(__LP64__) \
+ && defined(__CONCAT__) && defined(__CONCAT_U__)
+ /* Some HPs define UINT32_C incorrectly and break GNU. */
+# define KWIML_INT_BROKEN_UINT32_C 1
+#endif
+
+/* 32-bit constants */
+#if !defined(KWIML_INT_INT32_C)
+# if defined(INT32_C) && !defined(KWIML_INT_BROKEN_INT32_C)
+# define KWIML_INT_INT32_C(c) INT32_C(c)
+# else
+# define KWIML_INT_INT32_C(c) c
+# endif
+#endif
+#if !defined(KWIML_INT_UINT32_C)
+# if defined(UINT32_C) && !defined(KWIML_INT_BROKEN_UINT32_C)
+# define KWIML_INT_UINT32_C(c) UINT32_C(c)
+# else
+# define KWIML_INT_UINT32_C(c) c ## u
+# endif
+#endif
+
+/*--------------------------------------------------------------------------*/
+#if !defined(KWIML_INT_int64_t) && !defined(KWIML_INT_NO_INT64_T)
+# if defined(KWIML_INT_HAVE_INT64_T)
+# define KWIML_INT_int64_t KWIML_INT_detail_GLOBAL_NS(int64_t)
+# elif KWIML_ABI_SIZEOF_LONG == 8
+# define KWIML_INT_int64_t signed long
+# elif defined(KWIML_ABI_SIZEOF_LONG_LONG) && KWIML_ABI_SIZEOF_LONG_LONG == 8
+# define KWIML_INT_int64_t signed long long
+# elif defined(KWIML_ABI_SIZEOF___INT64)
+# define KWIML_INT_int64_t signed __int64
+# elif defined(KWIML_INT_NO_ERROR_INT64_T)
+# define KWIML_INT_NO_INT64_T
+# else
+# error "No type known for 'int64_t'."
+# endif
+#endif
+#if !defined(KWIML_INT_uint64_t) && !defined(KWIML_INT_NO_UINT64_T)
+# if defined(KWIML_INT_HAVE_UINT64_T)
+# define KWIML_INT_uint64_t KWIML_INT_detail_GLOBAL_NS(uint64_t)
+# elif KWIML_ABI_SIZEOF_LONG == 8
+# define KWIML_INT_uint64_t unsigned long
+# elif defined(KWIML_ABI_SIZEOF_LONG_LONG) && KWIML_ABI_SIZEOF_LONG_LONG == 8
+# define KWIML_INT_uint64_t unsigned long long
+# elif defined(KWIML_ABI_SIZEOF___INT64)
+# define KWIML_INT_uint64_t unsigned __int64
+# elif defined(KWIML_INT_NO_ERROR_UINT64_T)
+# define KWIML_INT_NO_UINT64_T
+# else
+# error "No type known for 'uint64_t'."
+# endif
+#endif
+
+#if defined(__INTEL_COMPILER)
+#elif defined(__BORLANDC__)
+# define KWIML_INT_private_NO_FMTLL /* type 'long long' but not 'll' format */
+# define KWIML_INT_BROKEN_INT64_C 1 /* system macro defined incorrectly */
+# define KWIML_INT_BROKEN_UINT64_C 1 /* system macro defined incorrectly */
+#elif defined(_MSC_VER) && _MSC_VER < 1400
+# define KWIML_INT_private_NO_FMTLL /* type 'long long' but not 'll' format */
+#endif
+
+#if !defined(KWIML_INT_detail_FMT64)
+# if KWIML_ABI_SIZEOF_LONG == 8
+# define KWIML_INT_detail_FMT64 "l"
+# elif defined(KWIML_ABI_SIZEOF_LONG_LONG) && KWIML_ABI_SIZEOF_LONG_LONG == 8
+# if !defined(KWIML_INT_private_NO_FMTLL)
+# define KWIML_INT_detail_FMT64 "ll"
+# else
+# define KWIML_INT_detail_FMT64 "I64"
+# endif
+# elif defined(KWIML_ABI_SIZEOF___INT64)
+# if defined(__BORLANDC__)
+# define KWIML_INT_detail_FMT64 "L"
+# else
+# define KWIML_INT_detail_FMT64 "I64"
+# endif
+# endif
+#endif
+
+#undef KWIML_INT_private_NO_FMTLL
+
+/* 64-bit d, i */
+#if !defined(KWIML_INT_PRId64)
+# if defined(KWIML_INT_HAVE_INT64_T) && defined(PRId64) \
+ && !defined(KWIML_INT_BROKEN_PRId64)
+# define KWIML_INT_PRId64 PRId64
+# elif defined(KWIML_INT_detail_FMT64)
+# define KWIML_INT_PRId64 KWIML_INT_detail_FMT64 "d"
+# endif
+#endif
+#if !defined(KWIML_INT_SCNd64)
+# if defined(KWIML_INT_HAVE_INT64_T) && defined(SCNd64) \
+ && !defined(KWIML_INT_BROKEN_SCNd64)
+# define KWIML_INT_SCNd64 SCNd64
+# elif defined(KWIML_INT_detail_FMT64) && !defined(KWIML_INT_private_NO_SCN64)
+# define KWIML_INT_SCNd64 KWIML_INT_detail_FMT64 "d"
+# endif
+#endif
+#if !defined(KWIML_INT_PRIi64)
+# if defined(KWIML_INT_HAVE_INT64_T) && defined(PRIi64) \
+ && !defined(KWIML_INT_BROKEN_PRIi64)
+# define KWIML_INT_PRIi64 PRIi64
+# elif defined(KWIML_INT_detail_FMT64)
+# define KWIML_INT_PRIi64 KWIML_INT_detail_FMT64 "d"
+# endif
+#endif
+#if !defined(KWIML_INT_SCNi64)
+# if defined(KWIML_INT_HAVE_INT64_T) && defined(SCNi64) \
+ && !defined(KWIML_INT_BROKEN_SCNi64)
+# define KWIML_INT_SCNi64 SCNi64
+# elif defined(KWIML_INT_detail_FMT64) && !defined(KWIML_INT_private_NO_SCN64)
+# define KWIML_INT_SCNi64 KWIML_INT_detail_FMT64 "d"
+# endif
+#endif
+
+/* 64-bit o, u, x, X */
+#if !defined(KWIML_INT_PRIo64)
+# if defined(KWIML_INT_HAVE_UINT64_T) && defined(PRIo64) \
+ && !defined(KWIML_INT_BROKEN_PRIo64)
+# define KWIML_INT_PRIo64 PRIo64
+# elif defined(KWIML_INT_detail_FMT64)
+# define KWIML_INT_PRIo64 KWIML_INT_detail_FMT64 "o"
+# endif
+#endif
+#if !defined(KWIML_INT_SCNo64)
+# if defined(KWIML_INT_HAVE_UINT64_T) && defined(SCNo64) \
+ && !defined(KWIML_INT_BROKEN_SCNo64)
+# define KWIML_INT_SCNo64 SCNo64
+# elif defined(KWIML_INT_detail_FMT64) && !defined(KWIML_INT_private_NO_SCN64)
+# define KWIML_INT_SCNo64 KWIML_INT_detail_FMT64 "o"
+# endif
+#endif
+#if !defined(KWIML_INT_PRIu64)
+# if defined(KWIML_INT_HAVE_UINT64_T) && defined(PRIu64) \
+ && !defined(KWIML_INT_BROKEN_PRIu64)
+# define KWIML_INT_PRIu64 PRIu64
+# elif defined(KWIML_INT_detail_FMT64)
+# define KWIML_INT_PRIu64 KWIML_INT_detail_FMT64 "u"
+# endif
+#endif
+#if !defined(KWIML_INT_SCNu64)
+# if defined(KWIML_INT_HAVE_UINT64_T) && defined(SCNu64) \
+ && !defined(KWIML_INT_BROKEN_SCNu64)
+# define KWIML_INT_SCNu64 SCNu64
+# elif defined(KWIML_INT_detail_FMT64) && !defined(KWIML_INT_private_NO_SCN64)
+# define KWIML_INT_SCNu64 KWIML_INT_detail_FMT64 "u"
+# endif
+#endif
+#if !defined(KWIML_INT_PRIx64)
+# if defined(KWIML_INT_HAVE_UINT64_T) && defined(PRIx64) \
+ && !defined(KWIML_INT_BROKEN_PRIx64)
+# define KWIML_INT_PRIx64 PRIx64
+# elif defined(KWIML_INT_detail_FMT64)
+# define KWIML_INT_PRIx64 KWIML_INT_detail_FMT64 "x"
+# endif
+#endif
+#if !defined(KWIML_INT_SCNx64)
+# if defined(KWIML_INT_HAVE_UINT64_T) && defined(SCNx64) \
+ && !defined(KWIML_INT_BROKEN_SCNx64)
+# define KWIML_INT_SCNx64 SCNx64
+# elif defined(KWIML_INT_detail_FMT64) && !defined(KWIML_INT_private_NO_SCN64)
+# define KWIML_INT_SCNx64 KWIML_INT_detail_FMT64 "x"
+# endif
+#endif
+#if !defined(KWIML_INT_PRIX64)
+# if defined(KWIML_INT_HAVE_UINT64_T) && defined(PRIX64) \
+ && !defined(KWIML_INT_BROKEN_PRIX64)
+# define KWIML_INT_PRIX64 PRIX64
+# elif defined(KWIML_INT_detail_FMT64)
+# define KWIML_INT_PRIX64 KWIML_INT_detail_FMT64 "X"
+# endif
+#endif
+
+/* 64-bit constants */
+#if !defined(KWIML_INT_INT64_C)
+# if defined(KWIML_INT_HAVE_INT64_T) && defined(INT64_C) \
+ && !defined(KWIML_INT_BROKEN_INT64_C)
+# define KWIML_INT_INT64_C(c) INT64_C(c)
+# elif KWIML_ABI_SIZEOF_LONG == 8
+# define KWIML_INT_INT64_C(c) c ## l
+# elif defined(KWIML_ABI_SIZEOF_LONG_LONG) && KWIML_ABI_SIZEOF_LONG_LONG == 8
+# define KWIML_INT_INT64_C(c) c ## ll
+# elif defined(KWIML_ABI_SIZEOF___INT64)
+# define KWIML_INT_INT64_C(c) c ## i64
+# endif
+#endif
+#if !defined(KWIML_INT_UINT64_C)
+# if defined(KWIML_INT_HAVE_UINT64_T) && defined(UINT64_C) \
+ && !defined(KWIML_INT_BROKEN_UINT64_C)
+# define KWIML_INT_UINT64_C(c) UINT64_C(c)
+# elif KWIML_ABI_SIZEOF_LONG == 8
+# define KWIML_INT_UINT64_C(c) c ## ul
+# elif defined(KWIML_ABI_SIZEOF_LONG_LONG) && KWIML_ABI_SIZEOF_LONG_LONG == 8
+# define KWIML_INT_UINT64_C(c) c ## ull
+# elif defined(KWIML_ABI_SIZEOF___INT64)
+# define KWIML_INT_UINT64_C(c) c ## ui64
+# endif
+#endif
+
+/*--------------------------------------------------------------------------*/
+#if !defined(KWIML_INT_intptr_t) && !defined(KWIML_INT_NO_INTPTR_T)
+# if defined(KWIML_INT_HAVE_INTPTR_T)
+# define KWIML_INT_intptr_t KWIML_INT_detail_GLOBAL_NS(intptr_t)
+# elif KWIML_ABI_SIZEOF_DATA_PTR == 4
+# define KWIML_INT_intptr_t KWIML_INT_int32_t
+# elif !defined(KWIML_INT_NO_INT64_T)
+# define KWIML_INT_intptr_t KWIML_INT_int64_t
+# elif defined(KWIML_INT_NO_ERROR_INTPTR_T)
+# define KWIML_INT_NO_INTPTR_T
+# else
+# error "No type known for 'intptr_t'."
+# endif
+#endif
+#if !defined(KWIML_INT_uintptr_t) && !defined(KWIML_INT_NO_UINTPTR_T)
+# if defined(KWIML_INT_HAVE_UINTPTR_T)
+# define KWIML_INT_uintptr_t KWIML_INT_detail_GLOBAL_NS(uintptr_t)
+# elif KWIML_ABI_SIZEOF_DATA_PTR == 4
+# define KWIML_INT_uintptr_t KWIML_INT_uint32_t
+# elif !defined(KWIML_INT_NO_UINT64_T)
+# define KWIML_INT_uintptr_t KWIML_INT_uint64_t
+# elif defined(KWIML_INT_NO_ERROR_UINTPTR_T)
+# define KWIML_INT_NO_UINTPTR_T
+# else
+# error "No type known for 'uintptr_t'."
+# endif
+#endif
+
+#if !defined(KWIML_INT_PRIdPTR)
+# if defined(KWIML_INT_HAVE_INTPTR_T) && defined(PRIdPTR) \
+ && !defined(KWIML_INT_BROKEN_PRIdPTR)
+# define KWIML_INT_PRIdPTR PRIdPTR
+# elif KWIML_ABI_SIZEOF_DATA_PTR == 4
+# define KWIML_INT_PRIdPTR KWIML_INT_PRId32
+# elif !defined(KWIML_INT_NO_UINT64_T)
+# define KWIML_INT_PRIdPTR KWIML_INT_PRId64
+# endif
+#endif
+#if !defined(KWIML_INT_SCNdPTR)
+# if defined(KWIML_INT_HAVE_INTPTR_T) && defined(SCNdPTR) \
+ && !defined(KWIML_INT_BROKEN_SCNdPTR)
+# define KWIML_INT_SCNdPTR SCNdPTR
+# elif KWIML_ABI_SIZEOF_DATA_PTR == 4
+# define KWIML_INT_SCNdPTR KWIML_INT_SCNd32
+# elif !defined(KWIML_INT_NO_UINT64_T)
+# define KWIML_INT_SCNdPTR KWIML_INT_SCNd64
+# endif
+#endif
+#if !defined(KWIML_INT_PRIiPTR)
+# if defined(KWIML_INT_HAVE_INTPTR_T) && defined(PRIiPTR) \
+ && !defined(KWIML_INT_BROKEN_PRIiPTR)
+# define KWIML_INT_PRIiPTR PRIiPTR
+# elif KWIML_ABI_SIZEOF_DATA_PTR == 4
+# define KWIML_INT_PRIiPTR KWIML_INT_PRIi32
+# elif !defined(KWIML_INT_NO_UINT64_T)
+# define KWIML_INT_PRIiPTR KWIML_INT_PRIi64
+# endif
+#endif
+#if !defined(KWIML_INT_SCNiPTR)
+# if defined(KWIML_INT_HAVE_INTPTR_T) && defined(SCNiPTR) \
+ && !defined(KWIML_INT_BROKEN_SCNiPTR)
+# define KWIML_INT_SCNiPTR SCNiPTR
+# elif KWIML_ABI_SIZEOF_DATA_PTR == 4
+# define KWIML_INT_SCNiPTR KWIML_INT_SCNi32
+# elif !defined(KWIML_INT_NO_UINT64_T)
+# define KWIML_INT_SCNiPTR KWIML_INT_SCNi64
+# endif
+#endif
+
+#if !defined(KWIML_INT_PRIoPTR)
+# if defined(KWIML_INT_HAVE_UINTPTR_T) && defined(PRIoPTR) \
+ && !defined(KWIML_INT_BROKEN_PRIoPTR)
+# define KWIML_INT_PRIoPTR PRIoPTR
+# elif KWIML_ABI_SIZEOF_DATA_PTR == 4
+# define KWIML_INT_PRIoPTR KWIML_INT_PRIo32
+# elif !defined(KWIML_INT_NO_UINT64_T)
+# define KWIML_INT_PRIoPTR KWIML_INT_PRIo64
+# endif
+#endif
+#if !defined(KWIML_INT_SCNoPTR)
+# if defined(KWIML_INT_HAVE_UINTPTR_T) && defined(SCNoPTR) \
+ && !defined(KWIML_INT_BROKEN_SCNoPTR)
+# define KWIML_INT_SCNoPTR SCNoPTR
+# elif KWIML_ABI_SIZEOF_DATA_PTR == 4
+# define KWIML_INT_SCNoPTR KWIML_INT_SCNo32
+# elif !defined(KWIML_INT_NO_UINT64_T)
+# define KWIML_INT_SCNoPTR KWIML_INT_SCNo64
+# endif
+#endif
+#if !defined(KWIML_INT_PRIuPTR)
+# if defined(KWIML_INT_HAVE_UINTPTR_T) && defined(PRIuPTR) \
+ && !defined(KWIML_INT_BROKEN_PRIuPTR)
+# define KWIML_INT_PRIuPTR PRIuPTR
+# elif KWIML_ABI_SIZEOF_DATA_PTR == 4
+# define KWIML_INT_PRIuPTR KWIML_INT_PRIu32
+# elif !defined(KWIML_INT_NO_UINT64_T)
+# define KWIML_INT_PRIuPTR KWIML_INT_PRIu64
+# endif
+#endif
+#if !defined(KWIML_INT_SCNuPTR)
+# if defined(KWIML_INT_HAVE_UINTPTR_T) && defined(SCNuPTR) \
+ && !defined(KWIML_INT_BROKEN_SCNuPTR)
+# define KWIML_INT_SCNuPTR SCNuPTR
+# elif KWIML_ABI_SIZEOF_DATA_PTR == 4
+# define KWIML_INT_SCNuPTR KWIML_INT_SCNu32
+# elif !defined(KWIML_INT_NO_UINT64_T)
+# define KWIML_INT_SCNuPTR KWIML_INT_SCNu64
+# endif
+#endif
+#if !defined(KWIML_INT_PRIxPTR)
+# if defined(KWIML_INT_HAVE_UINTPTR_T) && defined(PRIxPTR) \
+ && !defined(KWIML_INT_BROKEN_PRIxPTR)
+# define KWIML_INT_PRIxPTR PRIxPTR
+# elif KWIML_ABI_SIZEOF_DATA_PTR == 4
+# define KWIML_INT_PRIxPTR KWIML_INT_PRIx32
+# elif !defined(KWIML_INT_NO_UINT64_T)
+# define KWIML_INT_PRIxPTR KWIML_INT_PRIx64
+# endif
+#endif
+#if !defined(KWIML_INT_SCNxPTR)
+# if defined(KWIML_INT_HAVE_UINTPTR_T) && defined(SCNxPTR) \
+ && !defined(KWIML_INT_BROKEN_SCNxPTR)
+# define KWIML_INT_SCNxPTR SCNxPTR
+# elif KWIML_ABI_SIZEOF_DATA_PTR == 4
+# define KWIML_INT_SCNxPTR KWIML_INT_SCNx32
+# elif !defined(KWIML_INT_NO_UINT64_T)
+# define KWIML_INT_SCNxPTR KWIML_INT_SCNx64
+# endif
+#endif
+#if !defined(KWIML_INT_PRIXPTR)
+# if defined(KWIML_INT_HAVE_UINTPTR_T) && defined(PRIXPTR) \
+ && !defined(KWIML_INT_BROKEN_PRIXPTR)
+# define KWIML_INT_PRIXPTR PRIXPTR
+# elif KWIML_ABI_SIZEOF_DATA_PTR == 4
+# define KWIML_INT_PRIXPTR KWIML_INT_PRIX32
+# elif !defined(KWIML_INT_NO_UINT64_T)
+# define KWIML_INT_PRIXPTR KWIML_INT_PRIX64
+# endif
+#endif
+
+#undef KWIML_INT_private_NO_SCN64
+#undef KWIML_INT_private_NO_SCN8
+
+#endif /* KWIML_INT_private_DO_DEFINE */
+
+/*--------------------------------------------------------------------------*/
+#ifdef KWIML_INT_private_DO_VERIFY
+#undef KWIML_INT_private_DO_VERIFY
+
+#if defined(_MSC_VER)
+# pragma warning (push)
+# pragma warning (disable:4310) /* cast truncates constant value */
+#endif
+
+#define KWIML_INT_private_VERIFY(n, x, y) KWIML_INT_private_VERIFY_0(KWIML_INT_private_VERSION, n, x, y)
+#define KWIML_INT_private_VERIFY_0(V, n, x, y) KWIML_INT_private_VERIFY_1(V, n, x, y)
+#define KWIML_INT_private_VERIFY_1(V, n, x, y) extern int (*n##_v##V)[x]; extern int (*n##_v##V)[y]
+
+#define KWIML_INT_private_VERIFY_BOOL(m, b) KWIML_INT_private_VERIFY(KWIML_INT_detail_VERIFY_##m, 2, (b)?2:3)
+#define KWIML_INT_private_VERIFY_TYPE(t, s) KWIML_INT_private_VERIFY(KWIML_INT_detail_VERIFY_##t, s, sizeof(t))
+#define KWIML_INT_private_VERIFY_SIGN(t, u, o) KWIML_INT_private_VERIFY_BOOL(SIGN_##t, (t)((u)1 << ((sizeof(t)<<3)-1)) o 0)
+
+KWIML_INT_private_VERIFY_TYPE(KWIML_INT_int8_t, 1);
+KWIML_INT_private_VERIFY_TYPE(KWIML_INT_uint8_t, 1);
+KWIML_INT_private_VERIFY_TYPE(KWIML_INT_int16_t, 2);
+KWIML_INT_private_VERIFY_TYPE(KWIML_INT_uint16_t, 2);
+KWIML_INT_private_VERIFY_TYPE(KWIML_INT_int32_t, 4);
+KWIML_INT_private_VERIFY_TYPE(KWIML_INT_uint32_t, 4);
+#if !defined(KWIML_INT_NO_INT64_T)
+KWIML_INT_private_VERIFY_TYPE(KWIML_INT_int64_t, 8);
+#endif
+#if !defined(KWIML_INT_NO_UINT64_T)
+KWIML_INT_private_VERIFY_TYPE(KWIML_INT_uint64_t, 8);
+#endif
+#if !defined(KWIML_INT_NO_INTPTR_T)
+KWIML_INT_private_VERIFY_TYPE(KWIML_INT_intptr_t, sizeof(void*));
+#endif
+#if !defined(KWIML_INT_NO_UINTPTR_T)
+KWIML_INT_private_VERIFY_TYPE(KWIML_INT_uintptr_t, sizeof(void*));
+#endif
+
+KWIML_INT_private_VERIFY_SIGN(KWIML_INT_int8_t, KWIML_INT_uint8_t, <);
+KWIML_INT_private_VERIFY_SIGN(KWIML_INT_uint8_t, KWIML_INT_uint8_t, >);
+KWIML_INT_private_VERIFY_SIGN(KWIML_INT_int16_t, KWIML_INT_uint16_t, <);
+KWIML_INT_private_VERIFY_SIGN(KWIML_INT_uint16_t, KWIML_INT_uint16_t, >);
+KWIML_INT_private_VERIFY_SIGN(KWIML_INT_int32_t, KWIML_INT_uint32_t, <);
+KWIML_INT_private_VERIFY_SIGN(KWIML_INT_uint32_t, KWIML_INT_uint32_t, >);
+#if !defined(KWIML_INT_NO_INT64_T)
+KWIML_INT_private_VERIFY_SIGN(KWIML_INT_int64_t, KWIML_INT_uint64_t, <);
+#endif
+#if !defined(KWIML_INT_NO_UINT64_T)
+KWIML_INT_private_VERIFY_SIGN(KWIML_INT_uint64_t, KWIML_INT_uint64_t, >);
+#endif
+#if !defined(KWIML_INT_NO_INTPTR_T)
+KWIML_INT_private_VERIFY_SIGN(KWIML_INT_intptr_t, KWIML_INT_uintptr_t, <);
+#endif
+#if !defined(KWIML_INT_NO_UINTPTR_T)
+KWIML_INT_private_VERIFY_SIGN(KWIML_INT_uintptr_t, KWIML_INT_uintptr_t, >);
+#endif
+
+#undef KWIML_INT_private_VERIFY_SIGN
+#undef KWIML_INT_private_VERIFY_TYPE
+#undef KWIML_INT_private_VERIFY_BOOL
+
+#undef KWIML_INT_private_VERIFY_1
+#undef KWIML_INT_private_VERIFY_0
+#undef KWIML_INT_private_VERIFY
+
+#if defined(_MSC_VER)
+# pragma warning (pop)
+#endif
+
+#endif /* KWIML_INT_private_DO_VERIFY */
+
+#undef KWIML_INT_private_VERSION
diff --git a/Utilities/KWIML/src/kwiml-config.cmake.in b/Utilities/KWIML/src/kwiml-config.cmake.in
new file mode 100644
index 000000000..124f0fc55
--- /dev/null
+++ b/Utilities/KWIML/src/kwiml-config.cmake.in
@@ -0,0 +1 @@
+include(${CMAKE_CURRENT_LIST_DIR}/kwiml-targets.cmake)
diff --git a/Utilities/KWIML/src/version.h.in b/Utilities/KWIML/src/version.h.in
new file mode 100644
index 000000000..e58e0dce3
--- /dev/null
+++ b/Utilities/KWIML/src/version.h.in
@@ -0,0 +1,59 @@
+/*============================================================================
+ Kitware Information Macro Library
+ Copyright 2010-2015 Kitware, Inc.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of Kitware, Inc. nor the names of its contributors
+ may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+============================================================================*/
+#ifndef KWIML_VERSION_H
+#define KWIML_VERSION_H
+/*
+This header defines macros with information about this version of KWIML.
+
+An includer may test the following macros after inclusion:
+
+ KWIML_VERSION = KWIML version number encoded in an integer as
+ `printf("%d%03d%03d", MAJOR, MINOR, PATCH)`.
+ MAJOR is incremented on incompatible changes.
+ MINOR is incremented on interface additions.
+ PATCH is incremented on implementation updates.
+
+ KWIML_VERSION_STRING = KWIML version number in string formatted as
+ `printf("%d.%d.%d", MAJOR, MINOR PATCH)`.
+
+ KWIML_VERSION_HAS_ABI_H = header 'kwiml/abi.h' is available
+ KWIML_VERSION_HAS_INT_H = header 'kwiml/int.h' is available
+*/
+
+#define KWIML_VERSION @KWIML_VERSION_DECIMAL@
+#define KWIML_VERSION_STRING "@KWIML_VERSION@"
+
+#define KWIML_VERSION_HAS_ABI_H 1
+#define KWIML_VERSION_HAS_INT_H 1
+
+#endif
diff --git a/Utilities/KWIML/test/CMakeLists.txt b/Utilities/KWIML/test/CMakeLists.txt
index a2359cce1..4f6f37b4f 100644
--- a/Utilities/KWIML/test/CMakeLists.txt
+++ b/Utilities/KWIML/test/CMakeLists.txt
@@ -1,26 +1,15 @@
-#=============================================================================
-# Kitware Information Macro Library
-# Copyright 2010-2011 Kitware, Inc.
#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
+# Copyright Kitware, Inc.
+# Distributed under the OSI-approved BSD 3-Clause License.
+# See accompanying file Copyright.txt for details.
#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-
-set(test_defs KWIML_NAMESPACE=${KWIML})
-
-# Tell CMake how to follow dependencies of sources in this directory.
-set_property(DIRECTORY
- PROPERTY IMPLICIT_DEPENDS_INCLUDE_TRANSFORM
- "KWIML_HEADER(%)=<${KWIML}/%>"
- )
+if(NOT KWIML_TEST_PREFIX)
+ set(KWIML_TEST_PREFIX kwiml)
+endif()
# Suppress printf/scanf format warnings; we test if the sizes match.
foreach(lang C CXX)
- if(KWIML_LANGUAGE_${lang} AND "${CMAKE_${lang}_COMPILER_ID}" STREQUAL GNU)
+ if(KWIML_LANGUAGE_${lang} AND CMAKE_${lang}_COMPILER_ID STREQUAL "GNU")
set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} -Wno-format")
endif()
endforeach()
@@ -33,38 +22,33 @@ endif()
if(KWIML_LANGUAGE_C)
list(APPEND test_defs KWIML_LANGUAGE_C)
list(APPEND test_srcs
- test_ABI_C.c
- test_INT_C.c
+ test_abi_C.c
+ test_int_C.c
test_include_C.c
)
endif()
if(KWIML_LANGUAGE_CXX)
list(APPEND test_defs KWIML_LANGUAGE_CXX)
list(APPEND test_srcs
- test_ABI_CXX.cxx
- test_INT_CXX.cxx
+ test_abi_CXX.cxx
+ test_int_CXX.cxx
test_include_CXX.cxx
)
endif()
-foreach(th test_ABI_endian test_INT_format)
- configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${th}.h.in
- ${CMAKE_CURRENT_BINARY_DIR}/${th}.h @ONLY)
-endforeach()
-include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
-add_executable(${KWIML}_test ${test_srcs})
-set_property(TARGET ${KWIML}_test PROPERTY COMPILE_DEFINITIONS ${test_defs})
-set_property(TARGET ${KWIML}_test PROPERTY
+add_executable(kwiml_test ${test_srcs})
+set_property(TARGET kwiml_test PROPERTY COMPILE_DEFINITIONS ${test_defs})
+set_property(TARGET kwiml_test PROPERTY
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
-add_test(${KWIML}.test ${CMAKE_CURRENT_BINARY_DIR}/${KWIML}_test)
-set_property(TEST ${KWIML}.test PROPERTY LABELS ${KWIML_LABELS_TEST})
+add_test(NAME ${KWIML_TEST_PREFIX}.test COMMAND kwiml_test)
+set_property(TEST ${KWIML_TEST_PREFIX}.test PROPERTY LABELS ${KWIML_TEST_LABELS})
# Xcode 2.x forgets to create the output directory before linking
# the individual architectures.
if(CMAKE_OSX_ARCHITECTURES AND XCODE
AND NOT "${XCODE_VERSION}" MATCHES "^[^12]")
add_custom_command(
- TARGET ${KWIML}_test
+ TARGET kwiml_test
PRE_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CFG_INTDIR}"
)
endif()
diff --git a/Utilities/KWIML/test/test.c b/Utilities/KWIML/test/test.c
index 131c81f92..5f5b5d776 100644
--- a/Utilities/KWIML/test/test.c
+++ b/Utilities/KWIML/test/test.c
@@ -1,21 +1,15 @@
-/*============================================================================
- Kitware Information Macro Library
- Copyright 2010-2011 Kitware, Inc.
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
+/*
+ Copyright Kitware, Inc.
+ Distributed under the OSI-approved BSD 3-Clause License.
+ See accompanying file Copyright.txt for details.
+*/
#ifdef __cplusplus
extern "C" {
#endif
-extern int test_ABI_C(void);
-extern int test_INT_C(void);
-extern int test_ABI_CXX(void);
-extern int test_INT_CXX(void);
+extern int test_abi_C(void);
+extern int test_int_C(void);
+extern int test_abi_CXX(void);
+extern int test_int_CXX(void);
extern int test_include_C(void);
extern int test_include_CXX(void);
#ifdef __cplusplus
@@ -26,13 +20,13 @@ int main(void)
{
int result = 1;
#ifdef KWIML_LANGUAGE_C
- result = test_ABI_C() && result;
- result = test_INT_C() && result;
+ result = test_abi_C() && result;
+ result = test_int_C() && result;
result = test_include_C() && result;
#endif
#ifdef KWIML_LANGUAGE_CXX
- result = test_ABI_CXX() && result;
- result = test_INT_CXX() && result;
+ result = test_abi_CXX() && result;
+ result = test_int_CXX() && result;
result = test_include_CXX() && result;
#endif
return result? 0 : 1;
diff --git a/Utilities/KWIML/test/test.cxx b/Utilities/KWIML/test/test.cxx
index bf614218a..464325ba4 100644
--- a/Utilities/KWIML/test/test.cxx
+++ b/Utilities/KWIML/test/test.cxx
@@ -1,12 +1,6 @@
-/*============================================================================
- Kitware Information Macro Library
- Copyright 2010-2011 Kitware, Inc.
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
+/*
+ Copyright Kitware, Inc.
+ Distributed under the OSI-approved BSD 3-Clause License.
+ See accompanying file Copyright.txt for details.
+*/
#include "test.c"
diff --git a/Utilities/KWIML/test/test.h b/Utilities/KWIML/test/test.h
index b87a0e7e9..44add3faf 100644
--- a/Utilities/KWIML/test/test.h
+++ b/Utilities/KWIML/test/test.h
@@ -1,31 +1,10 @@
-/*============================================================================
- Kitware Information Macro Library
- Copyright 2010-2011 Kitware, Inc.
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#ifndef KWIML_NAMESPACE
-# error "Do not include test.h outside of KWIML test files."
-#endif
-
-#ifndef KWIML_TEST_H
-#define KWIML_TEST_H
-
/*
- Define KWIML_HEADER macro to help the test files include kwiml
- headers from the configured namespace directory. The macro can be
- used like this:
-
- #include KWIML_HEADER(ABI.h)
+ Copyright Kitware, Inc.
+ Distributed under the OSI-approved BSD 3-Clause License.
+ See accompanying file Copyright.txt for details.
*/
-#define KWIML_HEADER(x) KWIML_HEADER0(KWIML_NAMESPACE/x)
-#define KWIML_HEADER0(x) KWIML_HEADER1(x)
-#define KWIML_HEADER1(x) <x>
+#ifndef KWIML_TEST_H
+#define KWIML_TEST_H
/* Quiet MS standard library deprecation warnings. */
#ifndef _CRT_SECURE_NO_DEPRECATE
diff --git a/Utilities/KWIML/test/test_ABI_C.c b/Utilities/KWIML/test/test_ABI_C.c
deleted file mode 100644
index 3ca4ad390..000000000
--- a/Utilities/KWIML/test/test_ABI_C.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/*============================================================================
- Kitware Information Macro Library
- Copyright 2010-2011 Kitware, Inc.
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#include "test.h"
-#include KWIML_HEADER(ABI.h)
-#include "test_ABI_endian.h"
-int test_ABI_C(void)
-{
- if(!test_ABI_endian())
- {
- return 0;
- }
- return 1;
-}
diff --git a/Utilities/KWIML/test/test_ABI_CXX.cxx b/Utilities/KWIML/test/test_ABI_CXX.cxx
deleted file mode 100644
index 7ede20e09..000000000
--- a/Utilities/KWIML/test/test_ABI_CXX.cxx
+++ /dev/null
@@ -1,22 +0,0 @@
-/*============================================================================
- Kitware Information Macro Library
- Copyright 2010-2011 Kitware, Inc.
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#include "test.h"
-#include KWIML_HEADER(ABI.h)
-#include "test_ABI_endian.h"
-extern "C" int test_ABI_CXX(void)
-{
- if(!test_ABI_endian())
- {
- return 0;
- }
- return 1;
-}
diff --git a/Utilities/KWIML/test/test_ABI_endian.h.in b/Utilities/KWIML/test/test_ABI_endian.h.in
deleted file mode 100644
index 992baeaeb..000000000
--- a/Utilities/KWIML/test/test_ABI_endian.h.in
+++ /dev/null
@@ -1,47 +0,0 @@
-/*============================================================================
- Kitware Information Macro Library
- Copyright 2010-2011 Kitware, Inc.
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#include <stdio.h>
-
-#ifdef __cplusplus
-# define LANG "C++ "
-#else
-# define LANG "C "
-#endif
-
-static int test_ABI_endian(void)
-{
- int result = 1;
- {
-#if defined(@KWIML@_ABI_ENDIAN_ID)
- int expect;
- union { short s; unsigned char c[sizeof(short)]; } x;
- x.s = 1;
- expect = (x.c[0] == 1 ?
- @KWIML@_ABI_ENDIAN_ID_LITTLE : @KWIML@_ABI_ENDIAN_ID_BIG);
- printf(LANG "@KWIML@_ABI_ENDIAN_ID: expected [%d], got [%d]",
- expect, @KWIML@_ABI_ENDIAN_ID);
- if(@KWIML@_ABI_ENDIAN_ID == expect)
- {
- printf(", PASSED\n");
- }
- else
- {
- printf(", FAILED\n");
- result = 0;
- }
-#else
- printf(LANG "@KWIML@_ABI_ENDIAN_ID: unknown, FAILED\n");
- result = 0;
-#endif
- }
- return result;
-}
diff --git a/Utilities/KWIML/test/test_INT_C.c b/Utilities/KWIML/test/test_INT_C.c
deleted file mode 100644
index 5513a0bd8..000000000
--- a/Utilities/KWIML/test/test_INT_C.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/*============================================================================
- Kitware Information Macro Library
- Copyright 2010-2011 Kitware, Inc.
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#include "test.h"
-#include KWIML_HEADER(INT.h)
-#include "test_INT_format.h"
-int test_INT_C(void)
-{
- if(!test_INT_format())
- {
- return 0;
- }
- return 1;
-}
diff --git a/Utilities/KWIML/test/test_INT_CXX.cxx b/Utilities/KWIML/test/test_INT_CXX.cxx
deleted file mode 100644
index 9f74e9680..000000000
--- a/Utilities/KWIML/test/test_INT_CXX.cxx
+++ /dev/null
@@ -1,22 +0,0 @@
-/*============================================================================
- Kitware Information Macro Library
- Copyright 2010-2011 Kitware, Inc.
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#include "test.h"
-#include KWIML_HEADER(INT.h)
-#include "test_INT_format.h"
-extern "C" int test_INT_CXX(void)
-{
- if(!test_INT_format())
- {
- return 0;
- }
- return 1;
-}
diff --git a/Utilities/KWIML/test/test_INT_format.h.in b/Utilities/KWIML/test/test_INT_format.h.in
deleted file mode 100644
index 71b443d6e..000000000
--- a/Utilities/KWIML/test/test_INT_format.h.in
+++ /dev/null
@@ -1,200 +0,0 @@
-/*============================================================================
- Kitware Information Macro Library
- Copyright 2010-2011 Kitware, Inc.
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
-#include <stdio.h>
-#include <string.h>
-
-#ifdef __cplusplus
-# define LANG "C++ "
-#else
-# define LANG "C "
-#endif
-
-#define VALUE(T, U) (T)((U)0xab << ((sizeof(T)-1)<<3))
-
-#define TEST_C_(C, V, PRI, T, U) \
- { \
- T const x = VALUE(T, U); \
- T y = C(V); \
- printf(LANG #C ":" \
- " expression [%" @KWIML@_INT_PRI##PRI "]," \
- " literal [%" @KWIML@_INT_PRI##PRI "]", x, y); \
- if(x == y) \
- { \
- printf(", PASSED\n"); \
- } \
- else \
- { \
- printf(", FAILED\n"); \
- result = 0; \
- } \
- }
-
-#define TEST_PRI_(PRI, T, U, STR) \
- { \
- T const x = VALUE(T, U); \
- char const* str = STR; \
- sprintf(buf, "%" @KWIML@_INT_PRI##PRI, x); \
- printf(LANG "@KWIML@_INT_PRI" #PRI ":" \
- " expected [%s], got [%s]", str, buf); \
- if(strcmp(str, buf) == 0) \
- { \
- printf(", PASSED\n"); \
- } \
- else \
- { \
- printf(", FAILED\n"); \
- result = 0; \
- } \
- }
-
-#define TEST_SCN_(SCN, T, U, STR) TEST_SCN2_(SCN, SCN, T, U, STR)
-#define TEST_SCN2_(PRI, SCN, T, U, STR) \
- { \
- T const x = VALUE(T, U); \
- T y; \
- char const* str = STR; \
- if(sscanf(str, "%" @KWIML@_INT_SCN##SCN, &y) != 1) \
- { \
- y = 0; \
- } \
- printf(LANG "@KWIML@_INT_SCN" #SCN ":" \
- " expected [%" @KWIML@_INT_PRI##PRI "]," \
- " got [%" @KWIML@_INT_PRI##PRI "]", x, y); \
- if(x == y) \
- { \
- printf(", PASSED\n"); \
- } \
- else \
- { \
- printf(", FAILED\n"); \
- result = 0; \
- } \
- }
-
-#define TEST_(FMT, T, U, STR) TEST2_(FMT, FMT, T, U, STR)
-#define TEST2_(PRI, SCN, T, U, STR) \
- TEST_PRI_(PRI, T, U, STR) \
- TEST_SCN2_(PRI, SCN, T, U, STR)
-
-/* Concatenate T and U now to avoid expanding them. */
-#define TEST(FMT, T, U, STR) \
- TEST_(FMT, @KWIML@_INT_##T, @KWIML@_INT_##U, STR)
-#define TEST2(PRI, SCN, T, U, STR) \
- TEST2_(PRI, SCN, @KWIML@_INT_##T, @KWIML@_INT_##U, STR)
-#define TEST_C(C, V, PRI, T, U) \
- TEST_C_(@KWIML@_INT_##C, V, PRI, @KWIML@_INT_##T, @KWIML@_INT_##U)
-#define TEST_PRI(PRI, T, U, STR) \
- TEST_PRI_(PRI, @KWIML@_INT_##T, @KWIML@_INT_##U, STR)
-#define TEST_SCN(SCN, T, U, STR) \
- TEST_SCN_(SCN, @KWIML@_INT_##T, @KWIML@_INT_##U, STR)
-#define TEST_SCN2(PRI, SCN, T, U, STR) \
- TEST_SCN2_(PRI, SCN, @KWIML@_INT_##T, @KWIML@_INT_##U, STR)
-
-static int test_INT_format(void)
-{
- int result = 1;
- char buf[256];
- TEST_PRI(i8, int8_t, uint8_t, "-85")
-#if defined(@KWIML@_INT_SCNi8)
- TEST_SCN(i8, int8_t, uint8_t, "-85")
-#endif
- TEST_PRI(d8, int8_t, uint8_t, "-85")
-#if defined(@KWIML@_INT_SCNd8)
- TEST_SCN(d8, int8_t, uint8_t, "-85")
-#endif
- TEST_PRI(o8, uint8_t, uint8_t, "253")
-#if defined(@KWIML@_INT_SCNo8)
- TEST_SCN(o8, uint8_t, uint8_t, "253")
-#endif
- TEST_PRI(u8, uint8_t, uint8_t, "171")
-#if defined(@KWIML@_INT_SCNu8)
- TEST_SCN(u8, uint8_t, uint8_t, "171")
-#endif
- TEST_PRI(x8, uint8_t, uint8_t, "ab")
- TEST_PRI(X8, uint8_t, uint8_t, "AB")
-#if defined(@KWIML@_INT_SCNx8)
- TEST_SCN(x8, uint8_t, uint8_t, "ab")
- TEST_SCN2(X8, x8, uint8_t, uint8_t, "AB")
-#endif
-
- TEST(i16, int16_t, uint16_t, "-21760")
- TEST(d16, int16_t, uint16_t, "-21760")
- TEST(o16, uint16_t, uint16_t, "125400")
- TEST(u16, uint16_t, uint16_t, "43776")
- TEST(x16, uint16_t, uint16_t, "ab00")
- TEST2(X16, x16, uint16_t, uint16_t, "AB00")
-
- TEST(i32, int32_t, uint32_t, "-1426063360")
- TEST(d32, int32_t, uint32_t, "-1426063360")
- TEST(o32, uint32_t, uint32_t, "25300000000")
- TEST(u32, uint32_t, uint32_t, "2868903936")
- TEST(x32, uint32_t, uint32_t, "ab000000")
- TEST2(X32, x32, uint32_t, uint32_t, "AB000000")
-
- TEST_PRI(i64, int64_t, uint64_t, "-6124895493223874560")
-#if defined(@KWIML@_INT_SCNi64)
- TEST_SCN(i64, int64_t, uint64_t, "-6124895493223874560")
-#endif
- TEST_PRI(d64, int64_t, uint64_t, "-6124895493223874560")
-#if defined(@KWIML@_INT_SCNd64)
- TEST_SCN(d64, int64_t, uint64_t, "-6124895493223874560")
-#endif
- TEST_PRI(o64, uint64_t, uint64_t, "1254000000000000000000")
-#if defined(@KWIML@_INT_SCNo64)
- TEST_SCN(o64, uint64_t, uint64_t, "1254000000000000000000")
-#endif
- TEST_PRI(u64, uint64_t, uint64_t, "12321848580485677056")
-#if defined(@KWIML@_INT_SCNu64)
- TEST_SCN(u64, uint64_t, uint64_t, "12321848580485677056")
-#endif
- TEST_PRI(x64, uint64_t, uint64_t, "ab00000000000000")
- TEST_PRI(X64, uint64_t, uint64_t, "AB00000000000000")
-#if defined(@KWIML@_INT_SCNx64)
- TEST_SCN(x64, uint64_t, uint64_t, "ab00000000000000")
- TEST_SCN2(X64, x64, uint64_t, uint64_t, "AB00000000000000")
-#endif
-
-#if !defined(@KWIML@_INT_NO_INTPTR_T)
-# if @KWIML@_ABI_SIZEOF_DATA_PTR == 4
- TEST(iPTR, intptr_t, uint32_t, "-1426063360")
- TEST(dPTR, intptr_t, uint32_t, "-1426063360")
-# else
- TEST(iPTR, intptr_t, uint64_t, "-6124895493223874560")
- TEST(dPTR, intptr_t, uint64_t, "-6124895493223874560")
-# endif
-#endif
-
-#if !defined(@KWIML@_INT_NO_UINTPTR_T)
-# if @KWIML@_ABI_SIZEOF_DATA_PTR == 4
- TEST(oPTR, uintptr_t, uintptr_t, "25300000000")
- TEST(uPTR, uintptr_t, uintptr_t, "2868903936")
- TEST(xPTR, uintptr_t, uintptr_t, "ab000000")
- TEST2(XPTR, xPTR, uintptr_t, uintptr_t, "AB000000")
-# else
- TEST(oPTR, uintptr_t, uintptr_t, "1254000000000000000000")
- TEST(uPTR, uintptr_t, uintptr_t, "12321848580485677056")
- TEST(xPTR, uintptr_t, uintptr_t, "ab00000000000000")
- TEST2(XPTR, xPTR, uintptr_t, uintptr_t, "AB00000000000000")
-# endif
-#endif
-
- TEST_C(INT8_C, -0x55, i8, int8_t, uint8_t)
- TEST_C(UINT8_C, 0xAB, u8, uint8_t, uint8_t)
- TEST_C(INT16_C, -0x5500, i16, int16_t, uint16_t)
- TEST_C(UINT16_C, 0xAB00, u16, uint16_t, uint16_t)
- TEST_C(INT32_C, -0x55000000, i32, int32_t, uint32_t)
- TEST_C(UINT32_C, 0xAB000000, u32, uint32_t, uint32_t)
- TEST_C(INT64_C, -0x5500000000000000, i64, int64_t, uint64_t)
- TEST_C(UINT64_C, 0xAB00000000000000, u64, uint64_t, uint64_t)
-
- return result;
-}
diff --git a/Utilities/KWIML/test/test_abi_C.c b/Utilities/KWIML/test/test_abi_C.c
new file mode 100644
index 000000000..18b639f4a
--- /dev/null
+++ b/Utilities/KWIML/test/test_abi_C.c
@@ -0,0 +1,19 @@
+/*
+ Copyright Kitware, Inc.
+ Distributed under the OSI-approved BSD 3-Clause License.
+ See accompanying file Copyright.txt for details.
+*/
+#include "test.h"
+#include "../include/kwiml/abi.h"
+#include "test_abi_endian.h"
+#ifndef KWIML_ABI_VERSION
+# error "KWIML_ABI_VERSION not defined!"
+#endif
+int test_abi_C(void)
+{
+ if(!test_abi_endian())
+ {
+ return 0;
+ }
+ return 1;
+}
diff --git a/Utilities/KWIML/test/test_abi_CXX.cxx b/Utilities/KWIML/test/test_abi_CXX.cxx
new file mode 100644
index 000000000..e8feb44d2
--- /dev/null
+++ b/Utilities/KWIML/test/test_abi_CXX.cxx
@@ -0,0 +1,19 @@
+/*
+ Copyright Kitware, Inc.
+ Distributed under the OSI-approved BSD 3-Clause License.
+ See accompanying file Copyright.txt for details.
+*/
+#include "test.h"
+#include "../include/kwiml/abi.h"
+#include "test_abi_endian.h"
+#ifndef KWIML_ABI_VERSION
+# error "KWIML_ABI_VERSION not defined!"
+#endif
+extern "C" int test_abi_CXX(void)
+{
+ if(!test_abi_endian())
+ {
+ return 0;
+ }
+ return 1;
+}
diff --git a/Utilities/KWIML/test/test_abi_endian.h b/Utilities/KWIML/test/test_abi_endian.h
new file mode 100644
index 000000000..334b018a1
--- /dev/null
+++ b/Utilities/KWIML/test/test_abi_endian.h
@@ -0,0 +1,41 @@
+/*
+ Copyright Kitware, Inc.
+ Distributed under the OSI-approved BSD 3-Clause License.
+ See accompanying file Copyright.txt for details.
+*/
+#include <stdio.h>
+
+#ifdef __cplusplus
+# define LANG "C++ "
+#else
+# define LANG "C "
+#endif
+
+static int test_abi_endian(void)
+{
+ int result = 1;
+ {
+#if defined(KWIML_ABI_ENDIAN_ID)
+ int expect;
+ union { short s; unsigned char c[sizeof(short)]; } x;
+ x.s = 1;
+ expect = (x.c[0] == 1 ?
+ KWIML_ABI_ENDIAN_ID_LITTLE : KWIML_ABI_ENDIAN_ID_BIG);
+ printf(LANG "KWIML_ABI_ENDIAN_ID: expected [%d], got [%d]",
+ expect, KWIML_ABI_ENDIAN_ID);
+ if(KWIML_ABI_ENDIAN_ID == expect)
+ {
+ printf(", PASSED\n");
+ }
+ else
+ {
+ printf(", FAILED\n");
+ result = 0;
+ }
+#else
+ printf(LANG "KWIML_ABI_ENDIAN_ID: unknown, FAILED\n");
+ result = 0;
+#endif
+ }
+ return result;
+}
diff --git a/Utilities/KWIML/test/test_include_C.c b/Utilities/KWIML/test/test_include_C.c
index fb3e4cf7f..518544d25 100644
--- a/Utilities/KWIML/test/test_include_C.c
+++ b/Utilities/KWIML/test/test_include_C.c
@@ -1,20 +1,14 @@
-/*============================================================================
- Kitware Information Macro Library
- Copyright 2010-2011 Kitware, Inc.
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
+/*
+ Copyright Kitware, Inc.
+ Distributed under the OSI-approved BSD 3-Clause License.
+ See accompanying file Copyright.txt for details.
+*/
#include <stdio.h>
/* Test KWIML header inclusion after above system headers. */
#include "test.h"
-#include KWIML_HEADER(ABI.h)
-#include KWIML_HEADER(INT.h)
+#include "../include/kwiml/abi.h"
+#include "../include/kwiml/int.h"
int test_include_C(void)
{
diff --git a/Utilities/KWIML/test/test_include_CXX.cxx b/Utilities/KWIML/test/test_include_CXX.cxx
index 111311a84..82aa54616 100644
--- a/Utilities/KWIML/test/test_include_CXX.cxx
+++ b/Utilities/KWIML/test/test_include_CXX.cxx
@@ -1,14 +1,8 @@
-/*============================================================================
- Kitware Information Macro Library
- Copyright 2010-2011 Kitware, Inc.
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
-============================================================================*/
+/*
+ Copyright Kitware, Inc.
+ Distributed under the OSI-approved BSD 3-Clause License.
+ See accompanying file Copyright.txt for details.
+*/
#include <string>
#if defined(_MSC_VER) && defined(NDEBUG)
@@ -19,8 +13,8 @@ std::string test_include_CXX_use_stl_string;
/* Test KWIML header inclusion after above system headers. */
#include "test.h"
-#include KWIML_HEADER(ABI.h)
-#include KWIML_HEADER(INT.h)
+#include "../include/kwiml/abi.h"
+#include "../include/kwiml/int.h"
extern "C" int test_include_CXX(void)
{
diff --git a/Utilities/KWIML/test/test_int_C.c b/Utilities/KWIML/test/test_int_C.c
new file mode 100644
index 000000000..fe8ee8e3c
--- /dev/null
+++ b/Utilities/KWIML/test/test_int_C.c
@@ -0,0 +1,19 @@
+/*
+ Copyright Kitware, Inc.
+ Distributed under the OSI-approved BSD 3-Clause License.
+ See accompanying file Copyright.txt for details.
+*/
+#include "test.h"
+#include "../include/kwiml/int.h"
+#include "test_int_format.h"
+#ifndef KWIML_INT_VERSION
+# error "KWIML_INT_VERSION not defined!"
+#endif
+int test_int_C(void)
+{
+ if(!test_int_format())
+ {
+ return 0;
+ }
+ return 1;
+}
diff --git a/Utilities/KWIML/test/test_int_CXX.cxx b/Utilities/KWIML/test/test_int_CXX.cxx
new file mode 100644
index 000000000..ffa4c9b08
--- /dev/null
+++ b/Utilities/KWIML/test/test_int_CXX.cxx
@@ -0,0 +1,19 @@
+/*
+ Copyright Kitware, Inc.
+ Distributed under the OSI-approved BSD 3-Clause License.
+ See accompanying file Copyright.txt for details.
+*/
+#include "test.h"
+#include "../include/kwiml/int.h"
+#include "test_int_format.h"
+#ifndef KWIML_INT_VERSION
+# error "KWIML_INT_VERSION not defined!"
+#endif
+extern "C" int test_int_CXX(void)
+{
+ if(!test_int_format())
+ {
+ return 0;
+ }
+ return 1;
+}
diff --git a/Utilities/KWIML/test/test_int_format.h b/Utilities/KWIML/test/test_int_format.h
new file mode 100644
index 000000000..24dcdfba6
--- /dev/null
+++ b/Utilities/KWIML/test/test_int_format.h
@@ -0,0 +1,203 @@
+/*
+ Copyright Kitware, Inc.
+ Distributed under the OSI-approved BSD 3-Clause License.
+ See accompanying file Copyright.txt for details.
+*/
+#include <stdio.h>
+#include <string.h>
+
+#if defined(_MSC_VER)
+# pragma warning (push)
+# pragma warning (disable:4310) /* cast truncates constant value */
+#endif
+
+#ifdef __cplusplus
+# define LANG "C++ "
+#else
+# define LANG "C "
+#endif
+
+#define VALUE(T, U) (T)((U)0xab << ((sizeof(T)-1)<<3))
+
+#define TEST_C_(C, V, PRI, T, U) \
+ { \
+ T const x = VALUE(T, U); \
+ T y = C(V); \
+ printf(LANG #C ":" \
+ " expression [%" KWIML_INT_PRI##PRI "]," \
+ " literal [%" KWIML_INT_PRI##PRI "]", x, y); \
+ if(x == y) \
+ { \
+ printf(", PASSED\n"); \
+ } \
+ else \
+ { \
+ printf(", FAILED\n"); \
+ result = 0; \
+ } \
+ }
+
+#define TEST_PRI_(PRI, T, U, STR) \
+ { \
+ T const x = VALUE(T, U); \
+ char const* str = STR; \
+ sprintf(buf, "%" KWIML_INT_PRI##PRI, x); \
+ printf(LANG "KWIML_INT_PRI" #PRI ":" \
+ " expected [%s], got [%s]", str, buf); \
+ if(strcmp(str, buf) == 0) \
+ { \
+ printf(", PASSED\n"); \
+ } \
+ else \
+ { \
+ printf(", FAILED\n"); \
+ result = 0; \
+ } \
+ }
+
+#define TEST_SCN_(SCN, T, U, STR) TEST_SCN2_(SCN, SCN, T, U, STR)
+#define TEST_SCN2_(PRI, SCN, T, U, STR) \
+ { \
+ T const x = VALUE(T, U); \
+ T y; \
+ char const* str = STR; \
+ if(sscanf(str, "%" KWIML_INT_SCN##SCN, &y) != 1) \
+ { \
+ y = 0; \
+ } \
+ printf(LANG "KWIML_INT_SCN" #SCN ":" \
+ " expected [%" KWIML_INT_PRI##PRI "]," \
+ " got [%" KWIML_INT_PRI##PRI "]", x, y); \
+ if(x == y) \
+ { \
+ printf(", PASSED\n"); \
+ } \
+ else \
+ { \
+ printf(", FAILED\n"); \
+ result = 0; \
+ } \
+ }
+
+#define TEST_(FMT, T, U, STR) TEST2_(FMT, FMT, T, U, STR)
+#define TEST2_(PRI, SCN, T, U, STR) \
+ TEST_PRI_(PRI, T, U, STR) \
+ TEST_SCN2_(PRI, SCN, T, U, STR)
+
+/* Concatenate T and U now to avoid expanding them. */
+#define TEST(FMT, T, U, STR) \
+ TEST_(FMT, KWIML_INT_##T, KWIML_INT_##U, STR)
+#define TEST2(PRI, SCN, T, U, STR) \
+ TEST2_(PRI, SCN, KWIML_INT_##T, KWIML_INT_##U, STR)
+#define TEST_C(C, V, PRI, T, U) \
+ TEST_C_(KWIML_INT_##C, V, PRI, KWIML_INT_##T, KWIML_INT_##U)
+#define TEST_PRI(PRI, T, U, STR) \
+ TEST_PRI_(PRI, KWIML_INT_##T, KWIML_INT_##U, STR)
+#define TEST_SCN(SCN, T, U, STR) \
+ TEST_SCN_(SCN, KWIML_INT_##T, KWIML_INT_##U, STR)
+#define TEST_SCN2(PRI, SCN, T, U, STR) \
+ TEST_SCN2_(PRI, SCN, KWIML_INT_##T, KWIML_INT_##U, STR)
+
+static int test_int_format(void)
+{
+ int result = 1;
+ char buf[256];
+ TEST_PRI(i8, int8_t, uint8_t, "-85")
+#if defined(KWIML_INT_SCNi8)
+ TEST_SCN(i8, int8_t, uint8_t, "-85")
+#endif
+ TEST_PRI(d8, int8_t, uint8_t, "-85")
+#if defined(KWIML_INT_SCNd8)
+ TEST_SCN(d8, int8_t, uint8_t, "-85")
+#endif
+ TEST_PRI(o8, uint8_t, uint8_t, "253")
+#if defined(KWIML_INT_SCNo8)
+ TEST_SCN(o8, uint8_t, uint8_t, "253")
+#endif
+ TEST_PRI(u8, uint8_t, uint8_t, "171")
+#if defined(KWIML_INT_SCNu8)
+ TEST_SCN(u8, uint8_t, uint8_t, "171")
+#endif
+ TEST_PRI(x8, uint8_t, uint8_t, "ab")
+ TEST_PRI(X8, uint8_t, uint8_t, "AB")
+#if defined(KWIML_INT_SCNx8)
+ TEST_SCN(x8, uint8_t, uint8_t, "ab")
+ TEST_SCN2(X8, x8, uint8_t, uint8_t, "AB")
+#endif
+
+ TEST(i16, int16_t, uint16_t, "-21760")
+ TEST(d16, int16_t, uint16_t, "-21760")
+ TEST(o16, uint16_t, uint16_t, "125400")
+ TEST(u16, uint16_t, uint16_t, "43776")
+ TEST(x16, uint16_t, uint16_t, "ab00")
+ TEST2(X16, x16, uint16_t, uint16_t, "AB00")
+
+ TEST(i32, int32_t, uint32_t, "-1426063360")
+ TEST(d32, int32_t, uint32_t, "-1426063360")
+ TEST(o32, uint32_t, uint32_t, "25300000000")
+ TEST(u32, uint32_t, uint32_t, "2868903936")
+ TEST(x32, uint32_t, uint32_t, "ab000000")
+ TEST2(X32, x32, uint32_t, uint32_t, "AB000000")
+
+ TEST_PRI(i64, int64_t, uint64_t, "-6124895493223874560")
+#if defined(KWIML_INT_SCNi64)
+ TEST_SCN(i64, int64_t, uint64_t, "-6124895493223874560")
+#endif
+ TEST_PRI(d64, int64_t, uint64_t, "-6124895493223874560")
+#if defined(KWIML_INT_SCNd64)
+ TEST_SCN(d64, int64_t, uint64_t, "-6124895493223874560")
+#endif
+ TEST_PRI(o64, uint64_t, uint64_t, "1254000000000000000000")
+#if defined(KWIML_INT_SCNo64)
+ TEST_SCN(o64, uint64_t, uint64_t, "1254000000000000000000")
+#endif
+ TEST_PRI(u64, uint64_t, uint64_t, "12321848580485677056")
+#if defined(KWIML_INT_SCNu64)
+ TEST_SCN(u64, uint64_t, uint64_t, "12321848580485677056")
+#endif
+ TEST_PRI(x64, uint64_t, uint64_t, "ab00000000000000")
+ TEST_PRI(X64, uint64_t, uint64_t, "AB00000000000000")
+#if defined(KWIML_INT_SCNx64)
+ TEST_SCN(x64, uint64_t, uint64_t, "ab00000000000000")
+ TEST_SCN2(X64, x64, uint64_t, uint64_t, "AB00000000000000")
+#endif
+
+#if !defined(KWIML_INT_NO_INTPTR_T)
+# if KWIML_ABI_SIZEOF_DATA_PTR == 4
+ TEST(iPTR, intptr_t, uint32_t, "-1426063360")
+ TEST(dPTR, intptr_t, uint32_t, "-1426063360")
+# else
+ TEST(iPTR, intptr_t, uint64_t, "-6124895493223874560")
+ TEST(dPTR, intptr_t, uint64_t, "-6124895493223874560")
+# endif
+#endif
+
+#if !defined(KWIML_INT_NO_UINTPTR_T)
+# if KWIML_ABI_SIZEOF_DATA_PTR == 4
+ TEST(oPTR, uintptr_t, uintptr_t, "25300000000")
+ TEST(uPTR, uintptr_t, uintptr_t, "2868903936")
+ TEST(xPTR, uintptr_t, uintptr_t, "ab000000")
+ TEST2(XPTR, xPTR, uintptr_t, uintptr_t, "AB000000")
+# else
+ TEST(oPTR, uintptr_t, uintptr_t, "1254000000000000000000")
+ TEST(uPTR, uintptr_t, uintptr_t, "12321848580485677056")
+ TEST(xPTR, uintptr_t, uintptr_t, "ab00000000000000")
+ TEST2(XPTR, xPTR, uintptr_t, uintptr_t, "AB00000000000000")
+# endif
+#endif
+
+ TEST_C(INT8_C, -0x55, i8, int8_t, uint8_t)
+ TEST_C(UINT8_C, 0xAB, u8, uint8_t, uint8_t)
+ TEST_C(INT16_C, -0x5500, i16, int16_t, uint16_t)
+ TEST_C(UINT16_C, 0xAB00, u16, uint16_t, uint16_t)
+ TEST_C(INT32_C, -0x55000000, i32, int32_t, uint32_t)
+ TEST_C(UINT32_C, 0xAB000000, u32, uint32_t, uint32_t)
+ TEST_C(INT64_C, -0x5500000000000000, i64, int64_t, uint64_t)
+ TEST_C(UINT64_C, 0xAB00000000000000, u64, uint64_t, uint64_t)
+
+ return result;
+}
+
+#if defined(_MSC_VER)
+# pragma warning (pop)
+#endif
diff --git a/Utilities/Release/Cygwin/CMakeLists.txt b/Utilities/Release/Cygwin/CMakeLists.txt
index c59a6fa94..73a8220b9 100644
--- a/Utilities/Release/Cygwin/CMakeLists.txt
+++ b/Utilities/Release/Cygwin/CMakeLists.txt
@@ -14,9 +14,9 @@ message(STATUS "Using curses version: libncurses${MAX}")
configure_file("${CMake_SOURCE_DIR}/Utilities/Release/Cygwin/cygwin-setup.hint.in"
"${CMake_BINARY_DIR}/setup.hint")
configure_file("${CMake_SOURCE_DIR}/Utilities/Release/Cygwin/README.cygwin.in"
- "${CMake_BINARY_DIR}/Docs/@CPACK_PACKAGE_FILE_NAME@-@CPACK_CYGWIN_PATCH_NUMBER@.README")
+ "${CMake_BINARY_DIR}/Docs/${CPACK_PACKAGE_FILE_NAME}-${CPACK_CYGWIN_PATCH_NUMBER}.README")
install_files(/share/doc/Cygwin FILES
- ${CMake_BINARY_DIR}/Docs/@CPACK_PACKAGE_FILE_NAME@-@CPACK_CYGWIN_PATCH_NUMBER@.README
+ ${CMake_BINARY_DIR}/Docs/${CPACK_PACKAGE_FILE_NAME}-${CPACK_CYGWIN_PATCH_NUMBER}.README
)
configure_file("${CMake_SOURCE_DIR}/Utilities/Release/Cygwin/cygwin-package.sh.in"
${CPACK_CYGWIN_BUILD_SCRIPT})
diff --git a/Utilities/Release/Cygwin/README.cygwin.in b/Utilities/Release/Cygwin/README.cygwin.in
index 6c42a4c20..17cf2a1e6 100644
--- a/Utilities/Release/Cygwin/README.cygwin.in
+++ b/Utilities/Release/Cygwin/README.cygwin.in
@@ -8,7 +8,7 @@ Build requirements
make
Canonical homepage:
- http://www.cmake.org
+ https://cmake.org
Canonical download:
ftp://www.cmake.org/pub/cmake/
diff --git a/Utilities/Release/WiX/CMakeLists.txt b/Utilities/Release/WiX/CMakeLists.txt
new file mode 100644
index 000000000..cc0dbe1a6
--- /dev/null
+++ b/Utilities/Release/WiX/CMakeLists.txt
@@ -0,0 +1,12 @@
+add_subdirectory(CustomAction)
+
+if(CMAKE_CONFIGURATION_TYPES)
+ set(CUSTOM_ACTION_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/custom_action_dll-$<CONFIG>.wxs")
+else()
+ set(CUSTOM_ACTION_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/custom_action_dll.wxs")
+endif()
+
+file(GENERATE
+ OUTPUT "${CUSTOM_ACTION_OUTPUT}"
+ INPUT "${CMAKE_CURRENT_SOURCE_DIR}/custom_action_dll.wxs.in"
+ )
diff --git a/Utilities/Release/WiX/CustomAction/CMakeLists.txt b/Utilities/Release/WiX/CustomAction/CMakeLists.txt
new file mode 100644
index 000000000..7efd01e00
--- /dev/null
+++ b/Utilities/Release/WiX/CustomAction/CMakeLists.txt
@@ -0,0 +1,13 @@
+foreach(CONFIG DEBUG MINSIZEREL RELEASE RELWITHDEBINFO)
+ string(REPLACE "/MD" "/MT"
+ "CMAKE_CXX_FLAGS_${CONFIG}"
+ "${CMAKE_CXX_FLAGS_${CONFIG}}"
+ )
+endforeach()
+
+add_library(CMakeWiXCustomActions MODULE
+ detect_nsis_overwrite.cpp
+ exports.def
+)
+
+target_link_libraries(CMakeWiXCustomActions PRIVATE msi)
diff --git a/Utilities/Release/WiX/CustomAction/detect_nsis_overwrite.cpp b/Utilities/Release/WiX/CustomAction/detect_nsis_overwrite.cpp
new file mode 100644
index 000000000..dad1ae511
--- /dev/null
+++ b/Utilities/Release/WiX/CustomAction/detect_nsis_overwrite.cpp
@@ -0,0 +1,45 @@
+#include <windows.h>
+#include <msi.h>
+#include <msiquery.h>
+
+#include <string>
+#include <vector>
+
+std::wstring get_property(MSIHANDLE msi_handle, std::wstring const& name)
+{
+ DWORD size = 0;
+
+ UINT status = MsiGetPropertyW(msi_handle, name.c_str(), L"", &size);
+
+ if(status == ERROR_MORE_DATA)
+ {
+ std::vector<wchar_t> buffer(size + 1);
+ MsiGetPropertyW(msi_handle, name.c_str(), &buffer[0], &size);
+ return std::wstring(&buffer[0]);
+ }
+ else
+ {
+ return std::wstring();
+ }
+}
+
+void set_property(MSIHANDLE msi_handle,
+ std::wstring const& name, std::wstring const& value)
+{
+ MsiSetPropertyW(msi_handle, name.c_str(), value.c_str());
+}
+
+extern "C" UINT __stdcall DetectNsisOverwrite(MSIHANDLE msi_handle)
+{
+ std::wstring install_root = get_property(msi_handle, L"INSTALL_ROOT");
+
+ std::wstring uninstall_exe = install_root + L"\\uninstall.exe";
+
+ bool uninstall_exe_exists =
+ GetFileAttributesW(uninstall_exe.c_str()) != INVALID_FILE_ATTRIBUTES;
+
+ set_property(msi_handle, L"CMAKE_NSIS_OVERWRITE_DETECTED",
+ uninstall_exe_exists ? L"1" : L"0");
+
+ return ERROR_SUCCESS;
+}
diff --git a/Utilities/Release/WiX/CustomAction/exports.def b/Utilities/Release/WiX/CustomAction/exports.def
new file mode 100644
index 000000000..0e448b20e
--- /dev/null
+++ b/Utilities/Release/WiX/CustomAction/exports.def
@@ -0,0 +1,2 @@
+EXPORTS
+ DetectNsisOverwrite=DetectNsisOverwrite
diff --git a/Utilities/Release/WiX/WIX.template.in b/Utilities/Release/WiX/WIX.template.in
new file mode 100644
index 000000000..094999f1d
--- /dev/null
+++ b/Utilities/Release/WiX/WIX.template.in
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?include "cpack_variables.wxi"?>
+
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
+ RequiredVersion="3.6.3303.0">
+
+ <Product Id="$(var.CPACK_WIX_PRODUCT_GUID)"
+ Name="$(var.CPACK_PACKAGE_NAME)"
+ Language="1033"
+ Version="$(var.CPACK_PACKAGE_VERSION)"
+ Manufacturer="$(var.CPACK_PACKAGE_VENDOR)"
+ UpgradeCode="$(var.CPACK_WIX_UPGRADE_GUID)">
+
+ <Package InstallerVersion="301" Compressed="yes" InstallScope="perMachine"/>
+
+ <Media Id="1" Cabinet="media1.cab" EmbedCab="yes"/>
+
+ <MajorUpgrade
+ Schedule="afterInstallInitialize"
+ AllowDowngrades="yes"/>
+
+ <WixVariable Id="WixUILicenseRtf" Value="$(var.CPACK_WIX_LICENSE_RTF)"/>
+ <Property Id="WIXUI_INSTALLDIR" Value="INSTALL_ROOT"/>
+
+ <?ifdef CPACK_WIX_PRODUCT_ICON?>
+ <Property Id="ARPPRODUCTICON">ProductIcon.ico</Property>
+ <Icon Id="ProductIcon.ico" SourceFile="$(var.CPACK_WIX_PRODUCT_ICON)"/>
+ <?endif?>
+
+ <?ifdef CPACK_WIX_UI_BANNER?>
+ <WixVariable Id="WixUIBannerBmp" Value="$(var.CPACK_WIX_UI_BANNER)"/>
+ <?endif?>
+
+ <?ifdef CPACK_WIX_UI_DIALOG?>
+ <WixVariable Id="WixUIDialogBmp" Value="$(var.CPACK_WIX_UI_DIALOG)"/>
+ <?endif?>
+
+ <FeatureRef Id="ProductFeature"/>
+
+ <UIRef Id="$(var.CPACK_WIX_UI_REF)" />
+
+ <?include "properties.wxi"?>
+ <?include "product_fragment.wxi"?>
+ </Product>
+</Wix>
diff --git a/Utilities/Release/WiX/cmake_extra_dialog.wxs b/Utilities/Release/WiX/cmake_extra_dialog.wxs
new file mode 100644
index 000000000..0ee3d99e7
--- /dev/null
+++ b/Utilities/Release/WiX/cmake_extra_dialog.wxs
@@ -0,0 +1,36 @@
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Fragment>
+ <UI>
+ <Property Id="ADD_CMAKE_TO_PATH" Value="None"/>
+ <Dialog Id="CMakeExtraDialog" Width="370" Height="270" Title="Install Options">
+
+ <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.WixUINext)"/>
+ <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="!(loc.WixUIBack)"/>
+
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.WixUICancel)">
+ <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
+ </Control>
+
+ <Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes" Text="Choose options for installing CMake [ProductVersion]"/>
+ <Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes" Text="Install Options"/>
+ <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="!(loc.InstallDirDlgBannerBitmap)"/>
+ <Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0"/>
+ <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0"/>
+
+ <Control Id="Hint" Type="Text" X="26" Y="60" Width="250" Height="16" Transparent="yes" Text="By default CMake does not add its directory to the system PATH."/>
+
+ <Control Id="ADD_CMAKE_TO_PATHOption" Type="RadioButtonGroup" X="26" Y="100" Width="305" Height="65" Property="ADD_CMAKE_TO_PATH">
+ <RadioButtonGroup Property="ADD_CMAKE_TO_PATH">
+ <RadioButton Value="None" X="0" Y="0" Width="295" Height="16" Text="Do not add CMake to the system PATH"/>
+ <RadioButton Value="System" X="0" Y="20" Width="295" Height="16" Text="Add CMake to the system PATH for all users"/>
+ <RadioButton Value="User" X="0" Y="40" Width="295" Height="16" Text="Add CMake to the system PATH for the current user"/>
+ </RadioButtonGroup>
+ </Control>
+
+ <?ifdef BUILD_QtDialog ?>
+ <Control Id="DesktopShortcutCheckBox" Type="CheckBox" X="20" Y="170" Width="330" Height="18" CheckBoxValue="1" Property="DESKTOP_SHORTCUT_REQUESTED" Text="Create CMake Desktop Icon"/>
+ <?endif ?>
+ </Dialog>
+ </UI>
+ </Fragment>
+</Wix>
diff --git a/Utilities/Release/WiX/cmake_nsis_overwrite_dialog.wxs b/Utilities/Release/WiX/cmake_nsis_overwrite_dialog.wxs
new file mode 100644
index 000000000..8fe60f2cd
--- /dev/null
+++ b/Utilities/Release/WiX/cmake_nsis_overwrite_dialog.wxs
@@ -0,0 +1,21 @@
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Fragment>
+ <UI>
+ <Dialog Id="CMakeNsisOverwriteDialog" Width="310" Height="120" Title="NSIS Installation Conflict">
+ <Control Id="OK" Type="PushButton" X="122" Y="90" Width="56" Height="17" Default="yes" Cancel="yes" Text="!(loc.WixUIOK)">
+ <Publish Event="EndDialog" Value="Return">1</Publish>
+ </Control>
+ <Control Id="Text" Type="Text" X="48" Y="22" Width="260" Height="60">
+ <Text>
+ Uninstall.exe was detected in your chosen installation prefix.
+ This indicates a conflicting NSIS based installation of CMake.
+
+ Please uninstall your old CMake installation or choose a different
+ installation directory.
+ </Text>
+ </Control>
+ <Control Id="Icon" Type="Icon" X="15" Y="15" Width="24" Height="24" ToolTip="!(loc.InvalidDirDlgIconTooltip)" FixedSize="yes" IconSize="32" Text="!(loc.InvalidDirDlgIcon)" />
+ </Dialog>
+ </UI>
+ </Fragment>
+</Wix>
diff --git a/Utilities/Release/WiX/custom_action_dll.wxs.in b/Utilities/Release/WiX/custom_action_dll.wxs.in
new file mode 100644
index 000000000..021e63c5f
--- /dev/null
+++ b/Utilities/Release/WiX/custom_action_dll.wxs.in
@@ -0,0 +1,6 @@
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Fragment>
+ <Binary Id="CMakeCustomActionsDll"
+ SourceFile="$<TARGET_FILE:CMakeWiXCustomActions>"/>
+ </Fragment>
+</Wix>
diff --git a/Utilities/Release/WiX/install_dir.wxs b/Utilities/Release/WiX/install_dir.wxs
new file mode 100644
index 000000000..49b74e37d
--- /dev/null
+++ b/Utilities/Release/WiX/install_dir.wxs
@@ -0,0 +1,72 @@
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Fragment>
+ <UI Id="CMakeUI_InstallDir">
+ <TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
+ <TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="12" />
+ <TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />
+
+ <Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
+ <Property Id="WixUI_Mode" Value="InstallDir" />
+
+ <DialogRef Id="CMakeExtraDialog" />
+ <?ifdef CHECK_NSIS ?>
+ <DialogRef Id="CMakeNsisOverwriteDialog" />
+ <?endif ?>
+
+ <DialogRef Id="BrowseDlg" />
+ <DialogRef Id="DiskCostDlg" />
+ <DialogRef Id="ErrorDlg" />
+ <DialogRef Id="FatalError" />
+ <DialogRef Id="FilesInUse" />
+ <DialogRef Id="MsiRMFilesInUse" />
+ <DialogRef Id="PrepareDlg" />
+ <DialogRef Id="ProgressDlg" />
+ <DialogRef Id="ResumeDlg" />
+ <DialogRef Id="UserExit" />
+
+ <Publish Dialog="BrowseDlg" Control="OK" Event="DoAction" Value="WixUIValidatePath" Order="3">1</Publish>
+ <Publish Dialog="BrowseDlg" Control="OK" Event="SpawnDialog" Value="InvalidDirDlg" Order="4"><![CDATA[WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
+
+ <Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>
+
+ <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="LicenseAgreementDlg">NOT Installed</Publish>
+ <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">Installed AND PATCH</Publish>
+
+ <Publish Dialog="LicenseAgreementDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
+ <Publish Dialog="LicenseAgreementDlg" Control="Next" Event="NewDialog" Value="CMakeExtraDialog">LicenseAccepted = "1"</Publish>
+
+ <Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="CMakeExtraDialog">1</Publish>
+ <Publish Dialog="InstallDirDlg" Control="Next" Event="SetTargetPath" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
+ <Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="WixUIValidatePath" Order="2">NOT WIXUI_DONTVALIDATEPATH</Publish>
+ <Publish Dialog="InstallDirDlg" Control="Next" Event="SpawnDialog" Value="InvalidDirDlg" Order="3"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
+ <?ifdef CHECK_NSIS ?>
+ <Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="CMakeDetectNsisOverwrite" Order="4">1</Publish>
+ <Publish Dialog="InstallDirDlg" Control="Next" Event="SpawnDialog" Value="CMakeNsisOverwriteDialog" Order="5">CMAKE_NSIS_OVERWRITE_DETECTED="1"</Publish>
+ <?endif ?>
+ <Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="6"><![CDATA[(WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID="1") AND CMAKE_NSIS_OVERWRITE_DETECTED<>1]]></Publish>
+ <Publish Dialog="InstallDirDlg" Control="ChangeFolder" Property="_BrowseProperty" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
+ <Publish Dialog="InstallDirDlg" Control="ChangeFolder" Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>
+
+ <Publish Dialog="CMakeExtraDialog" Control="Back" Event="NewDialog" Value="LicenseAgreementDlg">1</Publish>
+ <Publish Dialog="CMakeExtraDialog" Control="Next" Event="NewDialog" Value="InstallDirDlg">1</Publish>
+
+ <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="InstallDirDlg" Order="1">NOT Installed</Publish>
+ <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="2">Installed AND NOT PATCH</Publish>
+ <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="2">Installed AND PATCH</Publish>
+
+ <Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>
+
+ <Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
+ <Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
+ <Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg">1</Publish>
+
+ <Property Id="ARPNOMODIFY" Value="1" />
+ </UI>
+
+ <UIRef Id="WixUI_Common" />
+
+ <?ifdef CHECK_NSIS ?>
+ <CustomAction Id="CMakeDetectNsisOverwrite" BinaryKey="CMakeCustomActionsDll" DllEntry="DetectNsisOverwrite"/>
+ <?endif ?>
+ </Fragment>
+</Wix>
diff --git a/Utilities/Release/WiX/patch_desktop_shortcut.xml b/Utilities/Release/WiX/patch_desktop_shortcut.xml
new file mode 100644
index 000000000..d30705dd1
--- /dev/null
+++ b/Utilities/Release/WiX/patch_desktop_shortcut.xml
@@ -0,0 +1,5 @@
+<CPackWiXPatch>
+ <CPackWiXFragment Id="CM_SHORTCUT_DESKTOP">
+ <Condition>DESKTOP_SHORTCUT_REQUESTED = 1</Condition>
+ </CPackWiXFragment>
+</CPackWiXPatch>
diff --git a/Utilities/Release/WiX/patch_path_env.xml b/Utilities/Release/WiX/patch_path_env.xml
new file mode 100644
index 000000000..0e335c4d5
--- /dev/null
+++ b/Utilities/Release/WiX/patch_path_env.xml
@@ -0,0 +1,26 @@
+<CPackWiXPatch>
+ <CPackWiXFragment Id="CM_DP_bin">
+ <Component Id="CMakeSystemPathEntryCMP" KeyPath="yes" Guid="0E782367-5D68-4539-81D1-B9757AE496A1">
+
+ <Condition>ADD_CMAKE_TO_PATH = "System"</Condition>
+
+ <Environment Id="CMakeSystemPathEntryENV" Action="set" Part="last"
+ Name="PATH" Value="[INSTALL_ROOT]bin"
+ System="yes"/>
+ </Component>
+
+ <Component Id="CMakeUserPathEntryCMP" KeyPath="yes" Guid="392E524D-D5BF-4F16-A7AF-A82B07482CB9">
+
+ <Condition>ADD_CMAKE_TO_PATH = "User"</Condition>
+
+ <Environment Id="CMakeUserPathEntryENV" Action="set" Part="last"
+ Name="PATH" Value="[INSTALL_ROOT]bin"
+ System="no"/>
+ </Component>
+ </CPackWiXFragment>
+
+ <CPackWiXFragment Id="#PRODUCTFEATURE">
+ <ComponentRef Id="CMakeSystemPathEntryCMP"/>
+ <ComponentRef Id="CMakeUserPathEntryCMP"/>
+ </CPackWiXFragment>
+</CPackWiXPatch>
diff --git a/Utilities/Release/WiX/ui_banner.jpg b/Utilities/Release/WiX/ui_banner.jpg
new file mode 100644
index 000000000..8d950a6ba
--- /dev/null
+++ b/Utilities/Release/WiX/ui_banner.jpg
Binary files differ
diff --git a/Utilities/Release/WiX/ui_dialog.jpg b/Utilities/Release/WiX/ui_dialog.jpg
new file mode 100644
index 000000000..bb6fa5ba7
--- /dev/null
+++ b/Utilities/Release/WiX/ui_dialog.jpg
Binary files differ
diff --git a/Utilities/Release/create-cmake-release.cmake b/Utilities/Release/create-cmake-release.cmake
index 37e223d28..d41c4ecbc 100644
--- a/Utilities/Release/create-cmake-release.cmake
+++ b/Utilities/Release/create-cmake-release.cmake
@@ -6,13 +6,10 @@ endif()
file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/logs)
set(RELEASE_SCRIPTS_BATCH_1
- dash2win64_release.cmake # Windows
- dashmacmini2_release.cmake # Mac Darwin universal ppc;i386
- dashmacmini5_release.cmake # Mac Darwin64 universal x86_64;i386
+ dash3win7_release.cmake # Windows
+ dashmacmini5_release.cmake # OS X x86_64
magrathea_release.cmake # Linux
- v20n250_aix_release.cmake # AIX 5.3
- ferrari_sgi64_release.cmake # IRIX 64
- ferrari_sgi_release.cmake # IRIX
+ linux64_release.cmake # Linux x86_64
)
set(RELEASE_SCRIPTS_BATCH_2
@@ -28,15 +25,54 @@ function(write_batch_shell_script filename)
math(EXPR y "160*(${i}%4)")
file(APPEND ${filename}
"
-${CMAKE_COMMAND} -DCMAKE_CREATE_VERSION=${CMAKE_CREATE_VERSION} -P ${CMAKE_ROOT}/Utilities/Release/${f} < /dev/null >& ${CMAKE_CURRENT_SOURCE_DIR}/logs/${f}-${CMAKE_CREATE_VERSION}.log &
-xterm -geometry 64x6+${x}+${y} -sb -sl 2000 -T ${f}-${CMAKE_CREATE_VERSION}.log -e tail -f ${CMAKE_CURRENT_SOURCE_DIR}/logs/${f}-${CMAKE_CREATE_VERSION}.log&
+\"${CMAKE_COMMAND}\" -DCMAKE_CREATE_VERSION=${CMAKE_CREATE_VERSION} -DCMAKE_DOC_TARBALL=\"${CMAKE_DOC_TARBALL}\" -P \"${CMAKE_ROOT}/Utilities/Release/${f}\" < /dev/null >& \"${CMAKE_CURRENT_SOURCE_DIR}/logs/${f}-${CMAKE_CREATE_VERSION}.log\" &
+xterm -geometry 64x6+${x}+${y} -sb -sl 2000 -T ${f}-${CMAKE_CREATE_VERSION}.log -e tail -f \"${CMAKE_CURRENT_SOURCE_DIR}/logs/${f}-${CMAKE_CREATE_VERSION}.log\" &
")
math(EXPR i "${i}+1")
endforeach()
execute_process(COMMAND chmod a+x ${filename})
endfunction()
+function(write_docs_shell_script filename)
+ find_program(SPHINX_EXECUTABLE
+ NAMES sphinx-build sphinx-build.py
+ DOC "Sphinx Documentation Builder (sphinx-doc.org)"
+ )
+ if(NOT SPHINX_EXECUTABLE)
+ message(FATAL_ERROR "SPHINX_EXECUTABLE (sphinx-build) is not found!")
+ endif()
+
+ set(name cmake-${CMAKE_CREATE_VERSION}-docs)
+ file(WRITE "${filename}" "#!/usr/bin/env bash
+
+name=${name} &&
+inst=\"\$PWD/\$name\"
+(GIT_WORK_TREE=x git archive --prefix=\${name}-src/ ${CMAKE_CREATE_VERSION}) | tar x &&
+rm -rf \${name}-build &&
+mkdir \${name}-build &&
+cd \${name}-build &&
+\"${CMAKE_COMMAND}\" ../\${name}-src/Utilities/Sphinx \\
+ -DCMAKE_INSTALL_PREFIX=\"\$inst/\" \\
+ -DCMAKE_DOC_DIR=doc/cmake \\
+ -DSPHINX_EXECUTABLE=\"${SPHINX_EXECUTABLE}\" \\
+ -DSPHINX_HTML=ON -DSPHINX_MAN=ON &&
+make install &&
+cd .. &&
+tar czf \${name}.tar.gz \${name} ||
+echo 'Failed to create \${name}.tar.gz'
+")
+ execute_process(COMMAND chmod a+x ${filename})
+ set(CMAKE_DOC_TARBALL "${name}.tar.gz" PARENT_SCOPE)
+endfunction()
+
+write_docs_shell_script("create-${CMAKE_CREATE_VERSION}-docs.sh")
write_batch_shell_script("create-${CMAKE_CREATE_VERSION}-batch1.sh" ${RELEASE_SCRIPTS_BATCH_1})
+unset(CMAKE_DOC_TARBALL) # No pre-built docs in second batch.
write_batch_shell_script("create-${CMAKE_CREATE_VERSION}-batch2.sh" ${RELEASE_SCRIPTS_BATCH_2})
-message("Run ./create-${CMAKE_CREATE_VERSION}-batch1.sh, then after all those builds complete, run ./create-${CMAKE_CREATE_VERSION}-batch2.sh")
+message("Run one at a time:
+ ./create-${CMAKE_CREATE_VERSION}-docs.sh &&
+ ./create-${CMAKE_CREATE_VERSION}-batch1.sh &&
+ ./create-${CMAKE_CREATE_VERSION}-batch2.sh &&
+ echo done
+")
diff --git a/Utilities/Release/dash2win64_cygwin.cmake b/Utilities/Release/dash2win64_cygwin.cmake
index 663c61581..ca590ed1f 100644
--- a/Utilities/Release/dash2win64_cygwin.cmake
+++ b/Utilities/Release/dash2win64_cygwin.cmake
@@ -1,5 +1,6 @@
set(CMAKE_RELEASE_DIRECTORY "c:/cygwin/home/dashboard/CMakeReleaseCygwin")
set(PROCESSORS 9)
+set(BOOTSTRAP_ARGS "")
set(MAKE_PROGRAM "make")
set(MAKE "${MAKE_PROGRAM} -j8")
set(HOST dash2win64)
@@ -10,11 +11,14 @@ set(INITIAL_CACHE "CMAKE_BUILD_TYPE:STRING=Release
CMAKE_Fortran_COMPILER_FULLPATH:FILEPATH=FALSE
CTEST_TEST_TIMEOUT:STRING=7200
DART_TESTING_TIMEOUT:STRING=7200
+SPHINX_HTML:BOOL=ON
+SPHINX_MAN:BOOL=ON
+CMake_INSTALL_DEPENDENCIES:BOOL=ON
")
set(CXX g++)
set(CC gcc)
set(SCRIPT_NAME dash2win64cygwin)
-set(GIT_EXTRA "git config core.autocrlf true")
+set(GIT_EXTRA "git config core.autocrlf false")
get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH)
# WARNING: Temporary fix!! This exclusion of the ExternalProject test
@@ -24,4 +28,6 @@ get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH)
# allows us to produce cygwin builds in the short term.
set(EXTRA_CTEST_ARGS "-E ExternalProject")
+set(LOCAL_DIR cygwin)
+
include(${path}/release_cmake.cmake)
diff --git a/Utilities/Release/dash2win64_release.cmake b/Utilities/Release/dash2win64_release.cmake
deleted file mode 100644
index 6d1ac767e..000000000
--- a/Utilities/Release/dash2win64_release.cmake
+++ /dev/null
@@ -1,20 +0,0 @@
-set(CMAKE_RELEASE_DIRECTORY "c:/cygwin/home/dashboard/CMakeReleaseDirectory")
-set(CONFIGURE_WITH_CMAKE TRUE)
-set(CMAKE_CONFIGURE_PATH "c:/Program\\ Files\\ \\(x86\\)/CMake\\ 2.8/bin/cmake.exe")
-set(PROCESSORS 8)
-set(HOST dash2win64)
-set(CPACK_BINARY_GENERATORS "NSIS ZIP")
-set(CPACK_SOURCE_GENERATORS "ZIP")
-set(MAKE_PROGRAM "make")
-set(MAKE "${MAKE_PROGRAM} -j8")
-set(INITIAL_CACHE "CMAKE_BUILD_TYPE:STRING=Release
-CMAKE_USE_OPENSSL:BOOL=ON
-CMAKE_SKIP_BOOTSTRAP_TEST:STRING=TRUE
-CMAKE_Fortran_COMPILER:FILEPATH=FALSE
-CMAKE_GENERATOR:INTERNAL=Unix Makefiles
-BUILD_QtDialog:BOOL:=TRUE
-QT_QMAKE_EXECUTABLE:FILEPATH=c:/Dashboards/Support/qt-build/Qt/bin/qmake.exe
-")
-get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH)
-set(GIT_EXTRA "git config core.autocrlf true")
-include(${path}/release_cmake.cmake)
diff --git a/Utilities/Release/dash3win7_release.cmake b/Utilities/Release/dash3win7_release.cmake
new file mode 100644
index 000000000..f25d63897
--- /dev/null
+++ b/Utilities/Release/dash3win7_release.cmake
@@ -0,0 +1,28 @@
+set(CMAKE_RELEASE_DIRECTORY "c:/msys64/home/dashboard/CMakeReleaseDirectory")
+set(CONFIGURE_WITH_CMAKE TRUE)
+set(CMAKE_CONFIGURE_PATH "c:/Program\\ Files\\ \\(x86\\)/CMake/bin/cmake.exe")
+set(PROCESSORS 8)
+set(HOST dash3win7)
+set(RUN_LAUNCHER ~/rel/run)
+set(CPACK_BINARY_GENERATORS "WIX ZIP")
+set(CPACK_SOURCE_GENERATORS "ZIP")
+set(MAKE_PROGRAM "ninja")
+set(MAKE "${MAKE_PROGRAM} -j8")
+set(INITIAL_CACHE "CMAKE_BUILD_TYPE:STRING=Release
+CMAKE_DOC_DIR:STRING=doc/cmake
+CMAKE_USE_OPENSSL:BOOL=OFF
+CMAKE_SKIP_BOOTSTRAP_TEST:STRING=TRUE
+CMAKE_Fortran_COMPILER:FILEPATH=FALSE
+CMAKE_GENERATOR:INTERNAL=Ninja
+BUILD_QtDialog:BOOL:=TRUE
+CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL:BOOL=TRUE
+CMake_INSTALL_DEPENDENCIES:BOOL=ON
+CMAKE_EXE_LINKER_FLAGS:STRING=-machine:x86 -subsystem:console,5.01
+")
+set(ppflags "-D_WIN32_WINNT=0x501 -D_USING_V110_SDK71_")
+set(CFLAGS "${ppflags}")
+set(CXXFLAGS "${ppflags}")
+set(ENV ". ~/rel/env")
+get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH)
+set(GIT_EXTRA "git config core.autocrlf true")
+include(${path}/release_cmake.cmake)
diff --git a/Utilities/Release/dashmacmini2_release.cmake b/Utilities/Release/dashmacmini2_release.cmake
deleted file mode 100644
index 5e57a70b2..000000000
--- a/Utilities/Release/dashmacmini2_release.cmake
+++ /dev/null
@@ -1,22 +0,0 @@
-set(PROCESSORS 2)
-set(CMAKE_RELEASE_DIRECTORY /Users/kitware/CMakeReleaseDirectory)
-set(USER_OVERRIDE "set(CMAKE_CXX_LINK_EXECUTABLE \\\"gcc <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -shared-libgcc -lstdc++-static\\\")")
-set(INSTALL_PREFIX /)
-set(HOST dashmacmini2)
-set(MAKE_PROGRAM "make")
-set(MAKE "${MAKE_PROGRAM} -j2")
-set(CPACK_BINARY_GENERATORS "PackageMaker TGZ TZ")
-set(INITIAL_CACHE "
-CMAKE_BUILD_TYPE:STRING=Release
-CMAKE_OSX_ARCHITECTURES:STRING=ppc;i386
-CMAKE_USE_OPENSSL:BOOL=ON
-OPENSSL_CRYPTO_LIBRARY:FILEPATH=/Users/kitware/openssl-1.0.1c-install/lib/libcrypto.a
-OPENSSL_INCLUDE_DIR:PATH=/Users/kitware/openssl-1.0.1c-install/include
-OPENSSL_SSL_LIBRARY:FILEPATH=/Users/kitware/openssl-1.0.1c-install/lib/libssl.a
-CMAKE_SKIP_BOOTSTRAP_TEST:STRING=TRUE
-CPACK_SYSTEM_NAME:STRING=Darwin-universal
-BUILD_QtDialog:BOOL=TRUE
-QT_QMAKE_EXECUTABLE:FILEPATH=/Users/kitware/Support/qt-4.8.0/install/bin/qmake
-")
-get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH)
-include(${path}/release_cmake.cmake)
diff --git a/Utilities/Release/dashmacmini5_release.cmake b/Utilities/Release/dashmacmini5_release.cmake
index 36b095287..b147013a7 100644
--- a/Utilities/Release/dashmacmini5_release.cmake
+++ b/Utilities/Release/dashmacmini5_release.cmake
@@ -1,24 +1,27 @@
set(PROCESSORS 4)
set(CMAKE_RELEASE_DIRECTORY /Users/kitware/CMakeReleaseDirectory)
# set(USER_OVERRIDE "set(CMAKE_CXX_LINK_EXECUTABLE \\\"gcc <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -shared-libgcc -lstdc++-static\\\")")
-set(INSTALL_PREFIX /)
+set(BOOTSTRAP_ARGS "--prefix=/ --docdir=doc/cmake")
set(HOST dashmacmini5)
set(MAKE_PROGRAM "make")
set(MAKE "${MAKE_PROGRAM} -j5")
-set(CPACK_BINARY_GENERATORS "PackageMaker TGZ TZ")
+set(CPACK_BINARY_GENERATORS "DragNDrop TGZ TZ")
set(CPACK_SOURCE_GENERATORS "TGZ TZ")
+set(CPACK_DMG_FORMAT "UDBZ") #build using bzip2 for smaller package size
set(INITIAL_CACHE "
-CMAKE_USE_OPENSSL:BOOL=ON
-OPENSSL_CRYPTO_LIBRARY:FILEPATH=/Users/kitware/openssl-1.0.1c-install/lib/libcrypto.a
-OPENSSL_INCLUDE_DIR:PATH=/Users/kitware/openssl-1.0.1c-install/include
-OPENSSL_SSL_LIBRARY:FILEPATH=/Users/kitware/openssl-1.0.1c-install/lib/libssl.a
+CMAKE_USE_OPENSSL:BOOL=OFF
+OPENSSL_CRYPTO_LIBRARY:FILEPATH=/Users/kitware/openssl-1.0.1g-install/lib/libcrypto.a
+OPENSSL_INCLUDE_DIR:PATH=/Users/kitware/openssl-1.0.1g-install/include
+OPENSSL_SSL_LIBRARY:FILEPATH=/Users/kitware/openssl-1.0.1g-install/lib/libssl.a
CMAKE_BUILD_TYPE:STRING=Release
-CMAKE_OSX_ARCHITECTURES:STRING=x86_64;i386
-CMAKE_OSX_DEPLOYMENT_TARGET:STRING=10.5
+CMAKE_OSX_ARCHITECTURES:STRING=x86_64
+CMAKE_OSX_DEPLOYMENT_TARGET:STRING=10.6
CMAKE_SKIP_BOOTSTRAP_TEST:STRING=TRUE
-CPACK_SYSTEM_NAME:STRING=Darwin64-universal
+CPACK_SYSTEM_NAME:STRING=Darwin-x86_64
BUILD_QtDialog:BOOL=TRUE
-QT_QMAKE_EXECUTABLE:FILEPATH=/Users/kitware/Support/qt-4.8.0/install/bin/qmake
+CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL:BOOL=TRUE
+CMake_INSTALL_DEPENDENCIES:BOOL=ON
+QT_QMAKE_EXECUTABLE:FILEPATH=/Users/kitware/Support/qt-4.8.6/install/bin/qmake
")
get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH)
include(${path}/release_cmake.cmake)
diff --git a/Utilities/Release/ferrari_sgi64_release.cmake b/Utilities/Release/ferrari_sgi64_release.cmake
deleted file mode 100644
index 4425f0557..000000000
--- a/Utilities/Release/ferrari_sgi64_release.cmake
+++ /dev/null
@@ -1,16 +0,0 @@
-set(CMAKE_RELEASE_DIRECTORY "/home/whoffman/CMakeReleaseDirectory64")
-set(PROCESSORS 2)
-set(CFLAGS "-64")
-set(FFLAGS "-64")
-set(CXXFLAGS "-64")
-set(LDFLAGS="-64")
-set(HOST sgi)
-set(SCRIPT_NAME sgi64)
-set(MAKE_PROGRAM "make")
-set(MAKE "${MAKE_PROGRAM} -P")
-set(INITIAL_CACHE "CMAKE_BUILD_TYPE:STRING=Release
-CMAKE_SKIP_BOOTSTRAP_TEST:STRING=TRUE
-CPACK_SYSTEM_NAME:STRING=IRIX64-64
-")
-get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH)
-include(${path}/release_cmake.cmake)
diff --git a/Utilities/Release/ferrari_sgi_release.cmake b/Utilities/Release/ferrari_sgi_release.cmake
deleted file mode 100644
index ee5121a9b..000000000
--- a/Utilities/Release/ferrari_sgi_release.cmake
+++ /dev/null
@@ -1,11 +0,0 @@
-set(CMAKE_RELEASE_DIRECTORY "/home/whoffman/CMakeReleaseDirectory")
-set(PROCESSORS 2)
-set(HOST sgi)
-set(MAKE_PROGRAM "make")
-set(MAKE "${MAKE_PROGRAM} -P")
-set(INITIAL_CACHE "CMAKE_BUILD_TYPE:STRING=Release
-CMAKE_SKIP_BOOTSTRAP_TEST:STRING=TRUE
-CPACK_SYSTEM_NAME:STRING=IRIX64-n32
-")
-get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH)
-include(${path}/release_cmake.cmake)
diff --git a/Utilities/Release/linux64_release.cmake b/Utilities/Release/linux64_release.cmake
new file mode 100644
index 000000000..81442e72b
--- /dev/null
+++ b/Utilities/Release/linux64_release.cmake
@@ -0,0 +1,25 @@
+set(PROCESSORS 4)
+set(BOOTSTRAP_ARGS "--docdir=doc/cmake")
+set(HOST linux64)
+set(MAKE_PROGRAM "make")
+set(CC /opt/gcc-4.9.2/bin/gcc)
+set(CXX /opt/gcc-4.9.2/bin/g++)
+set(CFLAGS "")
+set(CXXFLAGS "")
+set(INITIAL_CACHE "
+CMAKE_BUILD_TYPE:STRING=Release
+CURSES_LIBRARY:FILEPATH=/home/kitware/ncurses-5.9/lib/libncurses.a
+CURSES_INCLUDE_PATH:PATH=/home/kitware/ncurses-5.9/include
+FORM_LIBRARY:FILEPATH=/home/kitware/ncurses-5.9/lib/libform.a
+CMAKE_USE_OPENSSL:BOOL=ON
+OPENSSL_CRYPTO_LIBRARY:FILEPATH=/home/kitware/openssl-1.0.2d/lib/libcrypto.a
+OPENSSL_INCLUDE_DIR:PATH=/home/kitware/openssl-1.0.2d/include
+OPENSSL_SSL_LIBRARY:FILEPATH=/home/kitware/openssl-1.0.2d/lib/libssl.a
+CPACK_SYSTEM_NAME:STRING=Linux-x86_64
+BUILD_QtDialog:BOOL:=TRUE
+CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL:BOOL=TRUE
+CMake_INSTALL_DEPENDENCIES:BOOL=ON
+QT_QMAKE_EXECUTABLE:FILEPATH=/home/kitware/qt-4.8.6/bin/qmake
+")
+get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH)
+include(${path}/release_cmake.cmake)
diff --git a/Utilities/Release/magrathea_release.cmake b/Utilities/Release/magrathea_release.cmake
index 4783fdad3..0634ddadf 100644
--- a/Utilities/Release/magrathea_release.cmake
+++ b/Utilities/Release/magrathea_release.cmake
@@ -1,4 +1,5 @@
set(PROCESSORS 1)
+set(BOOTSTRAP_ARGS "--docdir=doc/cmake")
set(HOST magrathea)
set(MAKE_PROGRAM "make")
set(CC gcc332s)
@@ -11,11 +12,13 @@ CURSES_LIBRARY:FILEPATH=/usr/i686-gcc-332s/lib/libncurses.a
CURSES_INCLUDE_PATH:PATH=/usr/i686-gcc-332s/include/ncurses
FORM_LIBRARY:FILEPATH=/usr/i686-gcc-332s/lib/libform.a
CMAKE_USE_OPENSSL:BOOL=ON
-OPENSSL_CRYPTO_LIBRARY:FILEPATH=/home/kitware/openssl-1.0.1c-install/lib/libcrypto.a
-OPENSSL_INCLUDE_DIR:PATH=/home/kitware/openssl-1.0.1c-install/include
-OPENSSL_SSL_LIBRARY:FILEPATH=/home/kitware/openssl-1.0.1c-install/lib/libssl.a
+OPENSSL_CRYPTO_LIBRARY:FILEPATH=/home/kitware/openssl-1.0.2d/lib/libcrypto.a
+OPENSSL_INCLUDE_DIR:PATH=/home/kitware/openssl-1.0.2d/include
+OPENSSL_SSL_LIBRARY:FILEPATH=/home/kitware/openssl-1.0.2d/lib/libssl.a
CPACK_SYSTEM_NAME:STRING=Linux-i386
BUILD_QtDialog:BOOL:=TRUE
+CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL:BOOL=TRUE
+CMake_INSTALL_DEPENDENCIES:BOOL=ON
QT_QMAKE_EXECUTABLE:FILEPATH=/home/kitware/qt-4.43-install/bin/qmake
")
get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH)
diff --git a/Utilities/Release/release_cmake.cmake b/Utilities/Release/release_cmake.cmake
index f351ac8c0..0d9c78458 100644
--- a/Utilities/Release/release_cmake.cmake
+++ b/Utilities/Release/release_cmake.cmake
@@ -4,9 +4,6 @@ get_filename_component(SCRIPT_PATH "${CMAKE_CURRENT_LIST_FILE}" PATH)
if(NOT DEFINED CPACK_BINARY_GENERATORS)
set(CPACK_BINARY_GENERATORS "STGZ TGZ TZ")
endif()
-if(DEFINED EXTRA_COPY)
- set(HAS_EXTRA_COPY 1)
-endif()
if(NOT DEFINED CMAKE_RELEASE_DIRECTORY)
set(CMAKE_RELEASE_DIRECTORY "~/CMakeReleaseDirectory")
endif()
@@ -22,6 +19,9 @@ endif()
if(NOT DEFINED RUN_SHELL)
set(RUN_SHELL "/bin/sh")
endif()
+if(NOT DEFINED RUN_LAUNCHER)
+ set(RUN_LAUNCHER "")
+endif()
if(NOT DEFINED PROCESSORS)
set(PROCESSORS 1)
endif()
@@ -55,17 +55,29 @@ message("Creating CMake release ${CMAKE_CREATE_VERSION} on ${HOST} with parallel
macro(remote_command comment command)
message("${comment}")
if(${ARGC} GREATER 2)
- message("ssh ${HOST} ${EXTRA_HOP} ${command}")
- execute_process(COMMAND ssh ${HOST} ${EXTRA_HOP} ${command} RESULT_VARIABLE result INPUT_FILE ${ARGV2})
+ message("ssh ${HOST} ${RUN_LAUNCHER} ${command}")
+ execute_process(COMMAND ssh ${HOST} ${RUN_LAUNCHER} ${command} RESULT_VARIABLE result INPUT_FILE ${ARGV2})
else()
- message("ssh ${HOST} ${EXTRA_HOP} ${command}")
- execute_process(COMMAND ssh ${HOST} ${EXTRA_HOP} ${command} RESULT_VARIABLE result)
+ message("ssh ${HOST} ${RUN_LAUNCHER} ${command}")
+ execute_process(COMMAND ssh ${HOST} ${RUN_LAUNCHER} ${command} RESULT_VARIABLE result)
endif()
if(${result} GREATER 0)
message(FATAL_ERROR "Error running command: ${command}, return value = ${result}")
endif()
endmacro()
+if(CMAKE_DOC_TARBALL)
+ get_filename_component(CMAKE_DOC_TARBALL_NAME "${CMAKE_DOC_TARBALL}" NAME)
+ string(REPLACE ".tar.gz" "-${SCRIPT_NAME}.tar.gz" CMAKE_DOC_TARBALL_STAGED "${CMAKE_DOC_TARBALL_NAME}")
+ message("scp '${CMAKE_DOC_TARBALL}' '${HOST}:${CMAKE_DOC_TARBALL_STAGED}'")
+ execute_process(COMMAND
+ scp ${CMAKE_DOC_TARBALL} ${HOST}:${CMAKE_DOC_TARBALL_STAGED}
+ RESULT_VARIABLE result)
+ if(${result} GREATER 0)
+ message("error sending doc tarball with scp '${CMAKE_DOC_TARBALL}' '${HOST}:${CMAKE_DOC_TARBALL_STAGED}'")
+ endif()
+endif()
+
# set this so configure file will work from script mode
# create the script specific for the given host
set(SCRIPT_FILE release_cmake-${SCRIPT_NAME}.sh)
@@ -90,7 +102,7 @@ foreach(gen ${generators})
if("${gen}" STREQUAL "STGZ")
set(SUFFIXES ${SUFFIXES} "*.sh")
endif()
- if("${gen}" STREQUAL "PackageMaker")
+ if("${gen}" STREQUAL "DragNDrop")
set(SUFFIXES ${SUFFIXES} "*.dmg")
endif()
if("${gen}" STREQUAL "TBZ2")
@@ -103,6 +115,9 @@ foreach(gen ${generators})
if("${gen}" STREQUAL "TZ")
set(SUFFIXES ${SUFFIXES} "*.tar.Z")
endif()
+ if("${gen}" STREQUAL "WIX")
+ set(SUFFIXES ${SUFFIXES} "*.msi")
+ endif()
if("${gen}" STREQUAL "ZIP")
set(SUFFIXES ${SUFFIXES} "*.zip")
endif()
@@ -110,27 +125,38 @@ foreach(gen ${generators})
set(SUFFIXES ${SUFFIXES} "*.exe")
endif()
endforeach()
+
+if(SUFFIXES)
+ list(REMOVE_DUPLICATES SUFFIXES)
+endif()
+
+if(LOCAL_DIR)
+ file(MAKE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${LOCAL_DIR}")
+else()
+ set(LOCAL_DIR .)
+endif()
+
# copy all the files over from the remote machine
set(PROJECT_PREFIX cmake-)
foreach(suffix ${SUFFIXES})
- message("scp ${HOST}:${FINAL_PATH}/${PROJECT_PREFIX}${suffix} .")
+ message("scp ${HOST}:${FINAL_PATH}/${PROJECT_PREFIX}${suffix} ${LOCAL_DIR}")
execute_process(COMMAND
- scp ${HOST}:${FINAL_PATH}/${PROJECT_PREFIX}${suffix} .
+ scp ${HOST}:${FINAL_PATH}/${PROJECT_PREFIX}${suffix} ${LOCAL_DIR}
RESULT_VARIABLE result)
if(${result} GREATER 0)
- message("error getting file back scp ${HOST}:${FINAL_PATH}/${PROJECT_PREFIX}${suffix} .")
+ message("error getting file back scp ${HOST}:${FINAL_PATH}/${PROJECT_PREFIX}${suffix} ${LOCAL_DIR}")
endif()
endforeach()
# if there are extra files to copy get them as well
if(extra_files)
foreach(f ${extra_files})
- message("scp ${HOST}:${FINAL_PATH}/${f} .")
+ message("scp ${HOST}:${FINAL_PATH}/${f} ${LOCAL_DIR}")
execute_process(COMMAND
- scp ${HOST}:${FINAL_PATH}/${f} .
+ scp ${HOST}:${FINAL_PATH}/${f} ${LOCAL_DIR}
RESULT_VARIABLE result)
if(${result} GREATER 0)
- message("error getting file back scp ${HOST}:${FINAL_PATH}/${f} .")
+ message("error getting file back scp ${HOST}:${FINAL_PATH}/${f} ${LOCAL_DIR}")
endif()
endforeach()
endif()
diff --git a/Utilities/Release/release_cmake.sh.in b/Utilities/Release/release_cmake.sh.in
index 82c039b43..14651297b 100755
--- a/Utilities/Release/release_cmake.sh.in
+++ b/Utilities/Release/release_cmake.sh.in
@@ -5,6 +5,7 @@ echo ""
echo "remove and create working directory @CMAKE_RELEASE_DIRECTORY@"
rm -rf @CMAKE_RELEASE_DIRECTORY@
mkdir @CMAKE_RELEASE_DIRECTORY@
+@ENV@
check_exit_value()
{
@@ -15,6 +16,13 @@ check_exit_value()
fi
}
+CMAKE_DOC_TARBALL=""
+if [ ! -z "@CMAKE_DOC_TARBALL_NAME@" ] ; then
+ CMAKE_DOC_TARBALL=@CMAKE_RELEASE_DIRECTORY@/@CMAKE_DOC_TARBALL_NAME@
+ mv "$HOME/@CMAKE_DOC_TARBALL_STAGED@" "$CMAKE_DOC_TARBALL"
+ check_exit_value $? "mv doc tarball" || exit 1
+fi
+
if [ ! -z "@CC@" ]; then
export CC="@CC@"
check_exit_value $? "set CC compiler env var" || exit 1
@@ -76,6 +84,11 @@ if [ ! -z "@USER_OVERRIDE@" ]; then
echo "CMAKE_USER_MAKE_RULES_OVERRIDE:FILEPATH=@CMAKE_RELEASE_DIRECTORY@/@CMAKE_CREATE_VERSION@-build/user.txt" >> @CMAKE_RELEASE_DIRECTORY@/@CMAKE_CREATE_VERSION@-build/CMakeCache.txt
fi
+# Point build at pre-built documentation tarball, if any.
+if [ ! -z "$CMAKE_DOC_TARBALL" ]; then
+ echo "CMAKE_DOC_TARBALL:FILEPATH=$CMAKE_DOC_TARBALL" >> @CMAKE_RELEASE_DIRECTORY@/@CMAKE_CREATE_VERSION@-build/CMakeCache.txt
+fi
+
echo "Checkout the source for @CMAKE_CREATE_VERSION@"
cd @CMAKE_RELEASE_DIRECTORY@
if [ ! -z "@GIT_COMMAND@" ]; then
@@ -104,15 +117,9 @@ if [ ! -z "@CONFIGURE_WITH_CMAKE@" ]; then
@CMAKE_CONFIGURE_PATH@ ../@CMAKE_CREATE_VERSION@
check_exit_value $? "Configure cmake" || exit 1
else
- if [ -z "@INSTALL_PREFIX@" ]; then
- echo "Run cmake bootstrap --parallel=@PROCESSORS@"
- ../@CMAKE_CREATE_VERSION@/bootstrap --parallel=@PROCESSORS@
- check_exit_value $? "Bootstrap cmake" || exit 1
- else
- echo "Run cmake bootstrap --prefix=@INSTALL_PREFIX@ --parallel=@PROCESSORS@"
- ../@CMAKE_CREATE_VERSION@/bootstrap --prefix=@INSTALL_PREFIX@ --parallel=@PROCESSORS@
- check_exit_value $? "Bootstrap cmake" || exit 1
- fi
+ echo "Run cmake bootstrap @BOOTSTRAP_ARGS@ --parallel=@PROCESSORS@"
+ ../@CMAKE_CREATE_VERSION@/bootstrap @BOOTSTRAP_ARGS@ --parallel=@PROCESSORS@
+ check_exit_value $? "Bootstrap cmake" || exit 1
fi
echo "Build cmake with @MAKE@"
@@ -143,11 +150,6 @@ done
-# need to add an extra copy thing here
-if [ ! -z "@EXTRA_COPY@" ]; then
- @EXTRA_COPY@
- check_exit_value $? "Extra copy step @EXTRA_COPY@" || exit 1
-fi
echo "End release"
date
echo ""
diff --git a/Utilities/Release/upload_release.cmake b/Utilities/Release/upload_release.cmake
index 9bf35236d..f5e325e55 100644
--- a/Utilities/Release/upload_release.cmake
+++ b/Utilities/Release/upload_release.cmake
@@ -1,20 +1,19 @@
set(CTEST_RUN_CURRENT_SCRIPT 0)
-if(NOT DEFINED PROJECT_PREFIX)
- set(PROJECT_PREFIX cmake-)
-endif()
if(NOT VERSION)
- set(VERSION 2.8)
+ set(VERSION 3.5)
+endif()
+if(NOT DEFINED PROJECT_PREFIX)
+ set(PROJECT_PREFIX cmake-${VERSION})
endif()
-set(dir "v${VERSION}")
-if("${VERSION}" MATCHES "master")
- set(dir "dev")
+if(NOT DEFINED DIR)
+ set(DIR "v${VERSION}")
endif()
file(GLOB FILES ${CMAKE_CURRENT_SOURCE_DIR} "${PROJECT_PREFIX}*")
list(SORT FILES)
list(REVERSE FILES)
message("${FILES}")
set(UPLOAD_LOC
- "kitware@www.cmake.org:/projects/FTP/pub/cmake/${dir}")
+ "kitware@www.cmake.org:/projects/FTP/pub/cmake/${DIR}")
set(count 0)
foreach(file ${FILES})
if(NOT IS_DIRECTORY ${file})
diff --git a/Utilities/Release/v20n250_aix_release.cmake b/Utilities/Release/v20n250_aix_release.cmake
deleted file mode 100644
index cc8cd058b..000000000
--- a/Utilities/Release/v20n250_aix_release.cmake
+++ /dev/null
@@ -1,22 +0,0 @@
-set(CMAKE_RELEASE_DIRECTORY "/bench1/noibm34/CMakeReleaseDirectory")
-set(FINAL_PATH /u/noibm34/cmake-release)
-set(PROCESSORS 2)
-set(HOST "sshserv.centers.ihost.com")
-set(EXTRA_HOP "rsh p90n03")
-set(MAKE_PROGRAM "make")
-set(CC "xlc_r")
-set(CXX "xlC_r")
-set(FC "xlf")
-set(LDFLAGS "-Wl,-bmaxdata:0x80000000") # Push "Segmentation fault in extend_brk" over horizon
-set(INITIAL_CACHE "
-CMAKE_BUILD_TYPE:STRING=Release
-CMAKE_SKIP_BOOTSTRAP_TEST:STRING=TRUE
-")
-set(EXTRA_COPY "
-rm -rf ~/cmake-release
-mkdir ~/cmake-release
-mv *.sh ~/cmake-release
-mv *.Z ~/cmake-release
-mv *.gz ~/cmake-release")
-get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH)
-include(${path}/release_cmake.cmake)
diff --git a/Utilities/Scripts/BoostScanDeps.cmake b/Utilities/Scripts/BoostScanDeps.cmake
new file mode 100644
index 000000000..1fbea4bda
--- /dev/null
+++ b/Utilities/Scripts/BoostScanDeps.cmake
@@ -0,0 +1,217 @@
+# Scan the Boost headers and determine the library dependencies. Note
+# that this script only scans one Boost version at once; invoke once
+# for each Boost release. Note that this does require the headers for
+# a given component to match the library name, since this computes
+# inter-library dependencies. Library components for which this
+# assumption does not hold true and which have dependencies on other
+# Boost libraries will require special-casing. It also doesn't handle
+# private dependencies not described in the headers, for static
+# library dependencies--this is also a limitation of auto-linking, and
+# I'm unaware of any specific instances where this would be
+# problematic.
+#
+# Invoke in script mode, defining these variables:
+# BOOST_DIR - the root of the boost includes
+#
+# The script will process each directory under the root as a
+# "component". For each component, all the headers will be scanned to
+# determine the components it depends upon by following all the
+# possible includes from this component. This is to match the
+# behaviour of autolinking.
+
+# Written by Roger Leigh <rleigh@codelibre.net>
+
+#=============================================================================
+# Copyright 2014-2015 University of Dundee
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# Determine header dependencies on libraries using the embedded dependency information.
+#
+# component - the component to check (uses all headers from boost/${component})
+# includedir - the path to the Boost headers
+# _ret_libs - list of library dependencies
+#
+function(_Boost_FIND_COMPONENT_DEPENDENCIES component includedir _ret_libs)
+ # _boost_unprocessed_headers - list of headers requiring parsing
+ # _boost_processed_headers - headers already parsed (or currently being parsed)
+ # _boost_new_headers - new headers discovered for future processing
+
+ set(library_component FALSE)
+
+ # Start by finding all headers for the component; header
+ # dependencies via #include will be solved by future passes
+
+ # Special-case since it is part of mpi; look only in boost/mpi/python*
+ if(component STREQUAL "mpi_python")
+ set(_boost_DEPS "python")
+ set(library_component TRUE)
+ file(GLOB_RECURSE _boost_unprocessed_headers
+ RELATIVE "${includedir}"
+ "${includedir}/boost/mpi/python/*")
+ list(INSERT _boost_unprocessed_headers 0 "${includedir}/boost/mpi/python.hpp")
+ # Special-case since it is a serialization variant; look in boost/serialization
+ elseif(component STREQUAL "wserialization")
+ set(library_component TRUE)
+ file(GLOB_RECURSE _boost_unprocessed_headers
+ RELATIVE "${includedir}"
+ "${includedir}/boost/serialization/*")
+ list(INSERT _boost_unprocessed_headers 0 "${includedir}/boost/serialization.hpp")
+ # Not really a library in its own right, but treat it as one
+ elseif(component STREQUAL "math")
+ set(library_component TRUE)
+ file(GLOB_RECURSE _boost_unprocessed_headers
+ RELATIVE "${includedir}"
+ "${includedir}/boost/math/*")
+ list(INSERT _boost_unprocessed_headers 0 "${includedir}/boost/math.hpp")
+ # Single test header
+ elseif(component STREQUAL "unit_test_framework")
+ set(library_component TRUE)
+ set(_boost_unprocessed_headers "${BOOST_DIR}/test/unit_test.hpp")
+ # Single test header
+ elseif(component STREQUAL "prg_exec_monitor")
+ set(library_component TRUE)
+ set(_boost_unprocessed_headers "${BOOST_DIR}/test/prg_exec_monitor.hpp")
+ # Single test header
+ elseif(component STREQUAL "test_exec_monitor")
+ set(library_component TRUE)
+ set(_boost_unprocessed_headers "${BOOST_DIR}/test/test_exec_monitor.hpp")
+ else()
+ # Default behaviour where header directory is the same as the library name.
+ file(GLOB_RECURSE _boost_unprocessed_headers
+ RELATIVE "${includedir}"
+ "${includedir}/boost/${component}/*")
+ list(INSERT _boost_unprocessed_headers 0 "${includedir}/boost/${component}.hpp")
+ endif()
+
+ while(_boost_unprocessed_headers)
+ list(APPEND _boost_processed_headers ${_boost_unprocessed_headers})
+ foreach(header ${_boost_unprocessed_headers})
+ if(EXISTS "${includedir}/${header}")
+ file(STRINGS "${includedir}/${header}" _boost_header_includes REGEX "^#[ \t]*include[ \t]*<boost/[^>][^>]*>")
+ # The optional whitespace before "#" is intentional
+ # (boost/serialization/config.hpp bug).
+ file(STRINGS "${includedir}/${header}" _boost_header_deps REGEX "^[ \t]*#[ \t]*define[ \t][ \t]*BOOST_LIB_NAME[ \t][ \t]*boost_")
+
+ foreach(line ${_boost_header_includes})
+ string(REGEX REPLACE "^#[ \t]*include[ \t]*<(boost/[^>][^>]*)>.*" "\\1" _boost_header_match "${line}")
+ list(FIND _boost_processed_headers "${_boost_header_match}" _boost_header_processed)
+ list(FIND _boost_new_headers "${_boost_header_match}" _boost_header_new)
+ if (_boost_header_processed EQUAL -1 AND _boost_header_new EQUAL -1)
+ list(APPEND _boost_new_headers ${_boost_header_match})
+ endif()
+ endforeach()
+
+ foreach(line ${_boost_header_deps})
+ string(REGEX REPLACE "^[ \t]*#[ \t]*define[ \t][ \t]*BOOST_LIB_NAME[ \t][ \t]*boost_([^ \t][^ \t]*).*" "\\1" _boost_component_match "${line}")
+ list(FIND _boost_DEPS "${_boost_component_match}" _boost_dep_found)
+ if(_boost_component_match STREQUAL "bzip2" OR
+ _boost_component_match STREQUAL "zlib")
+ # These components may or may not be required; not
+ # possible to tell without knowing where and when
+ # BOOST_BZIP2_BINARY and BOOST_ZLIB_BINARY are defined.
+ # If building against an external zlib or bzip2, this is
+ # undesirable.
+ continue()
+ endif()
+ if(component STREQUAL "mpi" AND
+ (_boost_component_match STREQUAL "mpi_python" OR
+ _boost_component_match STREQUAL "python"))
+ # Optional python dependency; skip to avoid making it a
+ # hard dependency (handle as special-case for mpi_python).
+ continue()
+ endif()
+ if (_boost_dep_found EQUAL -1 AND
+ NOT "${_boost_component_match}" STREQUAL "${component}")
+ list(APPEND _boost_DEPS "${_boost_component_match}")
+ endif()
+ if("${_boost_component_match}" STREQUAL "${component}")
+ set(library_component TRUE)
+ endif()
+ endforeach()
+ endif()
+ endforeach()
+ set(_boost_unprocessed_headers ${_boost_new_headers})
+ unset(_boost_new_headers)
+ endwhile()
+
+ # message(STATUS "Unfiltered dependencies for Boost::${component}: ${_boost_DEPS}")
+
+ if(NOT library_component)
+ unset(_boost_DEPS)
+ endif()
+ set(${_ret_libs} ${_boost_DEPS} PARENT_SCOPE)
+
+ #string(REGEX REPLACE ";" " " _boost_DEPS_STRING "${_boost_DEPS}")
+ #if (NOT _boost_DEPS_STRING)
+ # set(_boost_DEPS_STRING "(none)")
+ #endif()
+ #message(STATUS "Dependencies for Boost::${component}: ${_boost_DEPS_STRING}")
+endfunction()
+
+
+message(STATUS "Scanning ${BOOST_DIR}")
+
+# List of all directories and files
+file(GLOB boost_contents RELATIVE "${BOOST_DIR}/boost" "${BOOST_DIR}/boost/*")
+
+# Components as directories
+foreach(component ${boost_contents})
+ if(IS_DIRECTORY "${BOOST_DIR}/boost/${component}")
+ list(APPEND boost_components "${component}")
+ endif()
+endforeach()
+
+# The following components are not top-level directories, so require
+# special-casing:
+
+# Special-case mpi_python, since it's a part of mpi
+if(IS_DIRECTORY "${BOOST_DIR}/boost/mpi" AND
+ IS_DIRECTORY "${BOOST_DIR}/boost/python")
+ list(APPEND boost_components "mpi_python")
+endif()
+# Special-case wserialization, which is a variant of serialization
+if(IS_DIRECTORY "${BOOST_DIR}/boost/serialization")
+ list(APPEND boost_components "wserialization")
+endif()
+# Special-case math* since there are six libraries, but no actual math
+# library component. Handle specially when scanning above.
+#
+# Special-case separate test libraries, which are all part of test
+if(EXISTS "${BOOST_DIR}/test/unit_test.hpp")
+ list(APPEND boost_components "unit_test_framework")
+endif()
+if(EXISTS "${BOOST_DIR}/test/prg_exec_monitor.hpp")
+ list(APPEND boost_components "prg_exec_monitor")
+endif()
+if(EXISTS "${BOOST_DIR}/test/test_exec_monitor.hpp")
+ list(APPEND boost_components "test_exec_monitor")
+endif()
+
+if(boost_components)
+ list(SORT boost_components)
+endif()
+
+# Process each component defined above
+foreach(component ${boost_components})
+ string(TOUPPER ${component} UPPERCOMPONENT)
+ _Boost_FIND_COMPONENT_DEPENDENCIES("${component}" "${BOOST_DIR}"
+ _Boost_${UPPERCOMPONENT}_LIBRARY_DEPENDENCIES)
+endforeach()
+
+# Output results
+foreach(component ${boost_components})
+ string(TOUPPER ${component} UPPERCOMPONENT)
+ if(_Boost_${UPPERCOMPONENT}_LIBRARY_DEPENDENCIES)
+ string(REGEX REPLACE ";" " " _boost_DEPS_STRING "${_Boost_${UPPERCOMPONENT}_LIBRARY_DEPENDENCIES}")
+ message(STATUS "set(_Boost_${UPPERCOMPONENT}_DEPENDENCIES ${_boost_DEPS_STRING})")
+ endif()
+endforeach()
diff --git a/Utilities/Scripts/update-kwiml.bash b/Utilities/Scripts/update-kwiml.bash
new file mode 100755
index 000000000..5c0d1922a
--- /dev/null
+++ b/Utilities/Scripts/update-kwiml.bash
@@ -0,0 +1,20 @@
+#!/usr/bin/env bash
+
+set -e
+set -x
+shopt -s dotglob
+
+readonly name="KWIML"
+readonly ownership="KWIML Upstream <kwrobot@kitware.com>"
+readonly subtree="Utilities/KWIML"
+readonly repo="https://github.com/Kitware/KWIML.git"
+readonly tag="master"
+readonly shortlog=true
+readonly paths="
+"
+
+extract_source () {
+ git_archive
+}
+
+. "${BASH_SOURCE%/*}/update-third-party.bash"
diff --git a/Utilities/Scripts/update-kwsys.bash b/Utilities/Scripts/update-kwsys.bash
new file mode 100755
index 000000000..650841f10
--- /dev/null
+++ b/Utilities/Scripts/update-kwsys.bash
@@ -0,0 +1,22 @@
+#!/usr/bin/env bash
+
+set -e
+set -x
+shopt -s dotglob
+
+readonly name="KWSys"
+readonly ownership="KWSys Upstream <kwrobot@kitware.com>"
+readonly subtree="Source/kwsys"
+readonly repo="http://public.kitware.com/KWSys.git"
+readonly tag="master"
+readonly shortlog=true
+readonly paths="
+"
+
+extract_source () {
+ git_archive
+}
+
+export HOOKS_ALLOW_KWSYS=1
+
+. "${BASH_SOURCE%/*}/update-third-party.bash"
diff --git a/Utilities/Scripts/update-third-party.bash b/Utilities/Scripts/update-third-party.bash
new file mode 100644
index 000000000..8925296cb
--- /dev/null
+++ b/Utilities/Scripts/update-third-party.bash
@@ -0,0 +1,146 @@
+########################################################################
+# Script for updating third party packages.
+#
+# This script should be sourced in a project-specific script which sets
+# the following variables:
+#
+# name
+# The name of the project.
+# ownership
+# A git author name/email for the commits.
+# subtree
+# The location of the thirdparty package within the main source
+# tree.
+# repo
+# The git repository to use as upstream.
+# tag
+# The tag, branch or commit hash to use for upstream.
+# shortlog
+# Optional. Set to 'true' to get a shortlog in the commit message.
+#
+# Additionally, an "extract_source" function must be defined. It will be
+# run within the checkout of the project on the requested tag. It should
+# should place the desired tree into $extractdir/$name-reduced. This
+# directory will be used as the newest commit for the project.
+#
+# For convenience, the function may use the "git_archive" function which
+# does a standard "git archive" extraction using the (optional) "paths"
+# variable to only extract a subset of the source tree.
+########################################################################
+
+########################################################################
+# Utility functions
+########################################################################
+git_archive () {
+ git archive --prefix="$name-reduced/" HEAD -- $paths | \
+ tar -C "$extractdir" -x
+}
+
+die () {
+ echo >&2 "$@"
+ exit 1
+}
+
+warn () {
+ echo >&2 "warning: $@"
+}
+
+readonly regex_date='20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]'
+readonly basehash_regex="$name $regex_date ([0-9a-f]*)"
+readonly basehash="$( git rev-list --author="$ownership" --grep="$basehash_regex" -n 1 HEAD )"
+readonly upstream_old_short="$( git cat-file commit "$basehash" | sed -n '/'"$basehash_regex"'/ {s/.*(//;s/)//;p}' | egrep '^[0-9a-f]+$' )"
+
+########################################################################
+# Sanity checking
+########################################################################
+[ -n "$name" ] || \
+ die "'name' is empty"
+[ -n "$ownership" ] || \
+ die "'ownership' is empty"
+[ -n "$subtree" ] || \
+ die "'subtree' is empty"
+[ -n "$repo" ] || \
+ die "'repo' is empty"
+[ -n "$tag" ] || \
+ die "'tag' is empty"
+[ -n "$basehash" ] || \
+ warn "'basehash' is empty; performing initial import"
+readonly do_shortlog="${shortlog-false}"
+
+readonly workdir="$PWD/work"
+readonly upstreamdir="$workdir/upstream"
+readonly extractdir="$workdir/extract"
+
+[ -d "$workdir" ] && \
+ die "error: workdir '$workdir' already exists"
+
+trap "rm -rf '$workdir'" EXIT
+
+# Get upstream
+git clone "$repo" "$upstreamdir"
+
+if [ -n "$basehash" ]; then
+ # Use the existing package's history
+ git worktree add "$extractdir" "$basehash"
+ # Clear out the working tree
+ pushd "$extractdir"
+ git ls-files | xargs rm -v
+ popd
+else
+ # Create a repo to hold this package's history
+ mkdir -p "$extractdir"
+ git -C "$extractdir" init
+fi
+
+# Extract the subset of upstream we care about
+pushd "$upstreamdir"
+git checkout "$tag"
+readonly upstream_hash="$( git rev-parse HEAD )"
+readonly upstream_hash_short="$( git rev-parse --short=8 "$upstream_hash" )"
+readonly upstream_datetime="$( git rev-list "$upstream_hash" --format='%ci' -n 1 | grep -e "^$regex_date" )"
+readonly upstream_date="$( echo "$upstream_datetime" | grep -o -e "$regex_date" )"
+if $do_shortlog && [ -n "$basehash" ]; then
+ readonly commit_shortlog="
+
+Upstream Shortlog
+-----------------
+
+$( git shortlog --no-merges --abbrev=8 --format='%h %s' "$upstream_old_short".."$upstream_hash" )"
+else
+ readonly commit_shortlog=""
+fi
+extract_source || \
+ die "failed to extract source"
+popd
+
+[ -d "$extractdir/$name-reduced" ] || \
+ die "expected directory to extract does not exist"
+readonly commit_summary="$name $upstream_date ($upstream_hash_short)"
+
+# Commit the subset
+pushd "$extractdir"
+mv -v "$name-reduced/"* .
+rmdir "$name-reduced/"
+git add -A .
+git commit -n --author="$ownership" --date="$upstream_datetime" -F - <<-EOF
+$commit_summary
+
+Code extracted from:
+
+ $repo
+
+at commit $upstream_hash ($tag).$commit_shortlog
+EOF
+git branch -f "upstream-$name"
+popd
+
+# Merge the subset into this repository
+if [ -n "$basehash" ]; then
+ git merge --log -s recursive "-Xsubtree=$subtree/" --no-commit "upstream-$name"
+else
+ git fetch "$extractdir" "upstream-$name:upstream-$name"
+ git merge --log -s ours --no-commit "upstream-$name"
+ git read-tree -u --prefix="$subtree/" "upstream-$name"
+fi
+git commit --no-edit
+git branch -d "upstream-$name"
diff --git a/Utilities/Sphinx/.gitignore b/Utilities/Sphinx/.gitignore
new file mode 100644
index 000000000..0d20b6487
--- /dev/null
+++ b/Utilities/Sphinx/.gitignore
@@ -0,0 +1 @@
+*.pyc
diff --git a/Utilities/Sphinx/CMakeLists.txt b/Utilities/Sphinx/CMakeLists.txt
new file mode 100644
index 000000000..257ba620a
--- /dev/null
+++ b/Utilities/Sphinx/CMakeLists.txt
@@ -0,0 +1,198 @@
+#=============================================================================
+# CMake - Cross Platform Makefile Generator
+# Copyright 2000-2013 Kitware, Inc., Insight Software Consortium
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+if(NOT CMake_SOURCE_DIR)
+ set(CMakeHelp_STANDALONE 1)
+ cmake_minimum_required(VERSION 2.8.4 FATAL_ERROR)
+ get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH)
+ get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH)
+ include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake)
+ include(${CMake_SOURCE_DIR}/Source/CMakeVersionCompute.cmake)
+ include(${CMake_SOURCE_DIR}/Source/CMakeInstallDestinations.cmake)
+ unset(CMAKE_DATA_DIR)
+ unset(CMAKE_DATA_DIR CACHE)
+ macro(CMake_OPTIONAL_COMPONENT)
+ set(COMPONENT "")
+ endmacro()
+endif()
+project(CMakeHelp NONE)
+
+option(SPHINX_MAN "Build man pages with Sphinx" OFF)
+option(SPHINX_HTML "Build html help with Sphinx" OFF)
+option(SPHINX_SINGLEHTML "Build html single page help with Sphinx" OFF)
+option(SPHINX_QTHELP "Build Qt help with Sphinx" OFF)
+option(SPHINX_TEXT "Build text help with Sphinx (not installed)" OFF)
+find_program(SPHINX_EXECUTABLE
+ NAMES sphinx-build
+ DOC "Sphinx Documentation Builder (sphinx-doc.org)"
+ )
+set(SPHINX_FLAGS "" CACHE STRING "Flags to pass to sphinx-build")
+separate_arguments(sphinx_flags UNIX_COMMAND "${SPHINX_FLAGS}")
+
+mark_as_advanced(SPHINX_TEXT)
+mark_as_advanced(SPHINX_FLAGS)
+
+if(NOT SPHINX_MAN AND NOT SPHINX_HTML AND NOT SPHINX_SINGLEHTML AND NOT SPHINX_QTHELP AND NOT SPHINX_TEXT)
+ return()
+elseif(NOT SPHINX_EXECUTABLE)
+ message(FATAL_ERROR "SPHINX_EXECUTABLE (sphinx-build) is not found!")
+endif()
+
+set(copyright_line_regex "^Copyright (2000-20[0-9][0-9] Kitware.*)")
+file(STRINGS "${CMake_SOURCE_DIR}/Copyright.txt" copyright_line
+ LIMIT_COUNT 1 REGEX "${copyright_line_regex}")
+if(copyright_line MATCHES "${copyright_line_regex}")
+ set(conf_copyright "${CMAKE_MATCH_1}")
+else()
+ set(conf_copyright "Kitware, Inc.")
+endif()
+
+set(conf_docs "${CMake_SOURCE_DIR}/Help")
+set(conf_path "${CMAKE_CURRENT_SOURCE_DIR}")
+set(conf_version "${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}.${CMake_VERSION_PATCH}")
+set(conf_release "${CMake_VERSION}")
+configure_file(conf.py.in conf.py @ONLY)
+
+set(doc_formats "")
+if(SPHINX_HTML)
+ list(APPEND doc_formats html)
+endif()
+if(SPHINX_MAN)
+ list(APPEND doc_formats man)
+endif()
+if(SPHINX_SINGLEHTML)
+ list(APPEND doc_formats singlehtml)
+endif()
+if(SPHINX_TEXT)
+ list(APPEND doc_formats text)
+endif()
+if(SPHINX_QTHELP)
+ find_package(PythonInterp REQUIRED)
+
+ find_program(QCOLLECTIONGENERATOR_EXECUTABLE
+ NAMES qcollectiongenerator
+ DOC "qcollectiongenerator tool"
+ )
+ if (NOT QCOLLECTIONGENERATOR_EXECUTABLE)
+ message(FATAL_ERROR "QCOLLECTIONGENERATOR_EXECUTABLE (qcollectiongenerator) not found!")
+ endif()
+ list(APPEND doc_formats qthelp)
+
+ set(qthelp_extra_commands
+ # Workaround for assistant prior to
+ # https://codereview.qt-project.org/#change,82250 in Qt 4.
+ COMMAND ${CMAKE_COMMAND} "-DCSS_DIR=${CMAKE_CURRENT_BINARY_DIR}/qthelp/_static"
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/apply_qthelp_css_workaround.cmake"
+ # Workaround sphinx configurability:
+ # https://bitbucket.org/birkenfeld/sphinx/issue/1448/make-qthelp-more-configurable
+ COMMAND ${CMAKE_COMMAND} "-DQTHELP_DIR=${CMAKE_CURRENT_BINARY_DIR}/qthelp/"
+ "-DCMake_VERSION=${CMake_VERSION_MAJOR}${CMake_VERSION_MINOR}${CMake_VERSION_PATCH}"
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/fixup_qthelp_names.cmake"
+
+ # Create proper identifiers. Workaround for
+ # https://bitbucket.org/birkenfeld/sphinx/issue/1491/qthelp-should-generate-identifiers-for
+ COMMAND "${PYTHON_EXECUTABLE}"
+ "${CMAKE_CURRENT_SOURCE_DIR}/create_identifiers.py"
+ "${CMAKE_CURRENT_BINARY_DIR}/qthelp/"
+
+ COMMAND ${QCOLLECTIONGENERATOR_EXECUTABLE}
+ ${CMAKE_CURRENT_BINARY_DIR}/qthelp/CMake.qhcp
+ )
+endif()
+
+
+set(doc_format_outputs "")
+set(doc_format_last "")
+foreach(format ${doc_formats})
+ set(doc_format_output "doc_format_${format}")
+ set(doc_format_log "build-${format}.log")
+ add_custom_command(
+ OUTPUT ${doc_format_output}
+ COMMAND ${SPHINX_EXECUTABLE}
+ -c ${CMAKE_CURRENT_BINARY_DIR}
+ -d ${CMAKE_CURRENT_BINARY_DIR}/doctrees
+ -b ${format}
+ ${sphinx_flags}
+ ${CMake_SOURCE_DIR}/Help
+ ${CMAKE_CURRENT_BINARY_DIR}/${format}
+ > ${doc_format_log} # log stdout, pass stderr
+ ${${format}_extra_commands}
+ DEPENDS ${doc_format_last}
+ COMMENT "sphinx-build ${format}: see Utilities/Sphinx/${doc_format_log}"
+ VERBATIM
+ )
+ set_property(SOURCE ${doc_format_output} PROPERTY SYMBOLIC 1)
+ list(APPEND doc_format_outputs ${doc_format_output})
+ set(doc_format_last ${doc_format_output})
+endforeach()
+
+add_custom_target(documentation ALL DEPENDS ${doc_format_outputs})
+
+foreach(t
+ cmake
+ ccmake
+ cmake-gui
+ cpack
+ ctest
+ )
+ if(TARGET ${t})
+ # Build documentation after main executables.
+ add_dependencies(documentation ${t})
+ endif()
+endforeach()
+
+if(SPHINX_MAN)
+ file(GLOB man_rst RELATIVE ${CMake_SOURCE_DIR}/Help/manual
+ ${CMake_SOURCE_DIR}/Help/manual/*.[1-9].rst)
+ foreach(m ${man_rst})
+ if("x${m}" MATCHES "^x(.+)\\.([1-9])\\.rst$")
+ set(name "${CMAKE_MATCH_1}")
+ set(sec "${CMAKE_MATCH_2}")
+ if(NOT CMakeHelp_STANDALONE)
+ if(name STREQUAL "ccmake" AND NOT BUILD_CursesDialog)
+ continue()
+ endif()
+ if(name STREQUAL "cmake-gui" AND NOT BUILD_QtDialog)
+ continue()
+ endif()
+ endif()
+ CMake_OPTIONAL_COMPONENT(sphinx-man)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/man/${name}.${sec}
+ DESTINATION ${CMAKE_MAN_DIR}/man${sec}
+ ${COMPONENT})
+ endif()
+ endforeach()
+endif()
+
+if(SPHINX_HTML)
+ CMake_OPTIONAL_COMPONENT(sphinx-html)
+ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html
+ DESTINATION ${CMAKE_DOC_DIR}
+ ${COMPONENT}
+ PATTERN .buildinfo EXCLUDE
+ )
+endif()
+
+if(SPHINX_SINGLEHTML)
+ CMake_OPTIONAL_COMPONENT(sphinx-singlehtml)
+ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/singlehtml
+ DESTINATION ${CMAKE_DOC_DIR}
+ ${COMPONENT}
+ PATTERN .buildinfo EXCLUDE
+ )
+endif()
+
+if(SPHINX_QTHELP)
+ CMake_OPTIONAL_COMPONENT(sphinx-qthelp)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/qthelp/CMake-${CMake_VERSION_MAJOR}${CMake_VERSION_MINOR}${CMake_VERSION_PATCH}.qch
+ DESTINATION ${CMAKE_DOC_DIR} ${COMPONENT}
+ )
+endif()
diff --git a/Utilities/Sphinx/apply_qthelp_css_workaround.cmake b/Utilities/Sphinx/apply_qthelp_css_workaround.cmake
new file mode 100644
index 000000000..8b74d12bb
--- /dev/null
+++ b/Utilities/Sphinx/apply_qthelp_css_workaround.cmake
@@ -0,0 +1,15 @@
+
+file(READ "${CSS_DIR}/basic.css" BasicCssContent)
+
+file(READ "${CSS_DIR}/default.css" DefaultCssContent)
+string(REPLACE
+ "@import url(\"basic.css\")" "${BasicCssContent}"
+ DefaultCssContent "${DefaultCssContent}"
+)
+
+file(READ "${CSS_DIR}/cmake.css" CMakeCssContent)
+string(REPLACE
+ "@import url(\"default.css\")" "${DefaultCssContent}"
+ CMakeCssContent "${CMakeCssContent}"
+)
+file(WRITE "${CSS_DIR}/cmake.css" "${CMakeCssContent}")
diff --git a/Utilities/Sphinx/cmake.py b/Utilities/Sphinx/cmake.py
new file mode 100644
index 000000000..5c0406d05
--- /dev/null
+++ b/Utilities/Sphinx/cmake.py
@@ -0,0 +1,392 @@
+#=============================================================================
+# CMake - Cross Platform Makefile Generator
+# Copyright 2000-2013 Kitware, Inc., Insight Software Consortium
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+import os
+import re
+
+# Monkey patch for pygments reporting an error when generator expressions are
+# used.
+# https://bitbucket.org/birkenfeld/pygments-main/issue/942/cmake-generator-expressions-not-handled
+from pygments.lexers import CMakeLexer
+from pygments.token import Name, Operator
+from pygments.lexer import bygroups
+CMakeLexer.tokens["args"].append(('(\\$<)(.+?)(>)',
+ bygroups(Operator, Name.Variable, Operator)))
+
+# Monkey patch for sphinx generating invalid content for qcollectiongenerator
+# https://bitbucket.org/birkenfeld/sphinx/issue/1435/qthelp-builder-should-htmlescape-keywords
+from sphinx.util.pycompat import htmlescape
+from sphinx.builders.qthelp import QtHelpBuilder
+old_build_keywords = QtHelpBuilder.build_keywords
+def new_build_keywords(self, title, refs, subitems):
+ old_items = old_build_keywords(self, title, refs, subitems)
+ new_items = []
+ for item in old_items:
+ before, rest = item.split("ref=\"", 1)
+ ref, after = rest.split("\"")
+ if ("<" in ref and ">" in ref):
+ new_items.append(before + "ref=\"" + htmlescape(ref) + "\"" + after)
+ else:
+ new_items.append(item)
+ return new_items
+QtHelpBuilder.build_keywords = new_build_keywords
+
+
+from docutils.parsers.rst import Directive, directives
+from docutils.transforms import Transform
+try:
+ from docutils.utils.error_reporting import SafeString, ErrorString
+except ImportError:
+ # error_reporting was not in utils before version 0.11:
+ from docutils.error_reporting import SafeString, ErrorString
+
+from docutils import io, nodes
+
+from sphinx.directives import ObjectDescription
+from sphinx.domains import Domain, ObjType
+from sphinx.roles import XRefRole
+from sphinx.util.nodes import make_refnode
+from sphinx import addnodes
+
+class CMakeModule(Directive):
+ required_arguments = 1
+ optional_arguments = 0
+ final_argument_whitespace = True
+ option_spec = {'encoding': directives.encoding}
+
+ def __init__(self, *args, **keys):
+ self.re_start = re.compile(r'^#\[(?P<eq>=*)\[\.rst:$')
+ Directive.__init__(self, *args, **keys)
+
+ def run(self):
+ settings = self.state.document.settings
+ if not settings.file_insertion_enabled:
+ raise self.warning('"%s" directive disabled.' % self.name)
+
+ env = self.state.document.settings.env
+ rel_path, path = env.relfn2path(self.arguments[0])
+ path = os.path.normpath(path)
+ encoding = self.options.get('encoding', settings.input_encoding)
+ e_handler = settings.input_encoding_error_handler
+ try:
+ settings.record_dependencies.add(path)
+ f = io.FileInput(source_path=path, encoding=encoding,
+ error_handler=e_handler)
+ except UnicodeEncodeError as error:
+ raise self.severe('Problems with "%s" directive path:\n'
+ 'Cannot encode input file path "%s" '
+ '(wrong locale?).' %
+ (self.name, SafeString(path)))
+ except IOError as error:
+ raise self.severe('Problems with "%s" directive path:\n%s.' %
+ (self.name, ErrorString(error)))
+ raw_lines = f.read().splitlines()
+ f.close()
+ rst = None
+ lines = []
+ for line in raw_lines:
+ if rst is not None and rst != '#':
+ # Bracket mode: check for end bracket
+ pos = line.find(rst)
+ if pos >= 0:
+ if line[0] == '#':
+ line = ''
+ else:
+ line = line[0:pos]
+ rst = None
+ else:
+ # Line mode: check for .rst start (bracket or line)
+ m = self.re_start.match(line)
+ if m:
+ rst = ']%s]' % m.group('eq')
+ line = ''
+ elif line == '#.rst:':
+ rst = '#'
+ line = ''
+ elif rst == '#':
+ if line == '#' or line[:2] == '# ':
+ line = line[2:]
+ else:
+ rst = None
+ line = ''
+ elif rst is None:
+ line = ''
+ lines.append(line)
+ if rst is not None and rst != '#':
+ raise self.warning('"%s" found unclosed bracket "#[%s[.rst:" in %s' %
+ (self.name, rst[1:-1], path))
+ self.state_machine.insert_input(lines, path)
+ return []
+
+class _cmake_index_entry:
+ def __init__(self, desc):
+ self.desc = desc
+
+ def __call__(self, title, targetid, main = 'main'):
+ return ('pair', u'%s ; %s' % (self.desc, title), targetid, main)
+
+_cmake_index_objs = {
+ 'command': _cmake_index_entry('command'),
+ 'generator': _cmake_index_entry('generator'),
+ 'manual': _cmake_index_entry('manual'),
+ 'module': _cmake_index_entry('module'),
+ 'policy': _cmake_index_entry('policy'),
+ 'prop_cache': _cmake_index_entry('cache property'),
+ 'prop_dir': _cmake_index_entry('directory property'),
+ 'prop_gbl': _cmake_index_entry('global property'),
+ 'prop_inst': _cmake_index_entry('installed file property'),
+ 'prop_sf': _cmake_index_entry('source file property'),
+ 'prop_test': _cmake_index_entry('test property'),
+ 'prop_tgt': _cmake_index_entry('target property'),
+ 'variable': _cmake_index_entry('variable'),
+ }
+
+def _cmake_object_inventory(env, document, line, objtype, targetid):
+ inv = env.domaindata['cmake']['objects']
+ if targetid in inv:
+ document.reporter.warning(
+ 'CMake object "%s" also described in "%s".' %
+ (targetid, env.doc2path(inv[targetid][0])), line=line)
+ inv[targetid] = (env.docname, objtype)
+
+class CMakeTransform(Transform):
+
+ # Run this transform early since we insert nodes we want
+ # treated as if they were written in the documents.
+ default_priority = 210
+
+ def __init__(self, document, startnode):
+ Transform.__init__(self, document, startnode)
+ self.titles = {}
+
+ def parse_title(self, docname):
+ """Parse a document title as the first line starting in [A-Za-z0-9<]
+ or fall back to the document basename if no such line exists.
+ The cmake --help-*-list commands also depend on this convention.
+ Return the title or False if the document file does not exist.
+ """
+ env = self.document.settings.env
+ title = self.titles.get(docname)
+ if title is None:
+ fname = os.path.join(env.srcdir, docname+'.rst')
+ try:
+ f = open(fname, 'r')
+ except IOError:
+ title = False
+ else:
+ for line in f:
+ if len(line) > 0 and (line[0].isalnum() or line[0] == '<'):
+ title = line.rstrip()
+ break
+ f.close()
+ if title is None:
+ title = os.path.basename(docname)
+ self.titles[docname] = title
+ return title
+
+ def apply(self):
+ env = self.document.settings.env
+
+ # Treat some documents as cmake domain objects.
+ objtype, sep, tail = env.docname.rpartition('/')
+ make_index_entry = _cmake_index_objs.get(objtype)
+ if make_index_entry:
+ title = self.parse_title(env.docname)
+ # Insert the object link target.
+ if objtype == 'command':
+ targetname = title.lower()
+ else:
+ targetname = title
+ targetid = '%s:%s' % (objtype, targetname)
+ targetnode = nodes.target('', '', ids=[targetid])
+ self.document.note_explicit_target(targetnode)
+ self.document.insert(0, targetnode)
+ # Insert the object index entry.
+ indexnode = addnodes.index()
+ indexnode['entries'] = [make_index_entry(title, targetid)]
+ self.document.insert(0, indexnode)
+ # Add to cmake domain object inventory
+ _cmake_object_inventory(env, self.document, 1, objtype, targetid)
+
+class CMakeObject(ObjectDescription):
+
+ def handle_signature(self, sig, signode):
+ # called from sphinx.directives.ObjectDescription.run()
+ signode += addnodes.desc_name(sig, sig)
+ return sig
+
+ def add_target_and_index(self, name, sig, signode):
+ if self.objtype == 'command':
+ targetname = name.lower()
+ else:
+ targetname = name
+ targetid = '%s:%s' % (self.objtype, targetname)
+ if targetid not in self.state.document.ids:
+ signode['names'].append(targetid)
+ signode['ids'].append(targetid)
+ signode['first'] = (not self.names)
+ self.state.document.note_explicit_target(signode)
+ _cmake_object_inventory(self.env, self.state.document,
+ self.lineno, self.objtype, targetid)
+
+ make_index_entry = _cmake_index_objs.get(self.objtype)
+ if make_index_entry:
+ self.indexnode['entries'].append(make_index_entry(name, targetid))
+
+class CMakeXRefRole(XRefRole):
+
+ # See sphinx.util.nodes.explicit_title_re; \x00 escapes '<'.
+ _re = re.compile(r'^(.+?)(\s*)(?<!\x00)<(.*?)>$', re.DOTALL)
+ _re_sub = re.compile(r'^([^()\s]+)\s*\(([^()]*)\)$', re.DOTALL)
+
+ def __call__(self, typ, rawtext, text, *args, **keys):
+ # Translate CMake command cross-references of the form:
+ # `command_name(SUB_COMMAND)`
+ # to have an explicit target:
+ # `command_name(SUB_COMMAND) <command_name>`
+ if typ == 'cmake:command':
+ m = CMakeXRefRole._re_sub.match(text)
+ if m:
+ text = '%s <%s>' % (text, m.group(1))
+ # CMake cross-reference targets frequently contain '<' so escape
+ # any explicit `<target>` with '<' not preceded by whitespace.
+ while True:
+ m = CMakeXRefRole._re.match(text)
+ if m and len(m.group(2)) == 0:
+ text = '%s\x00<%s>' % (m.group(1), m.group(3))
+ else:
+ break
+ return XRefRole.__call__(self, typ, rawtext, text, *args, **keys)
+
+ # We cannot insert index nodes using the result_nodes method
+ # because CMakeXRefRole is processed before substitution_reference
+ # nodes are evaluated so target nodes (with 'ids' fields) would be
+ # duplicated in each evaluted substitution replacement. The
+ # docutils substitution transform does not allow this. Instead we
+ # use our own CMakeXRefTransform below to add index entries after
+ # substitutions are completed.
+ #
+ # def result_nodes(self, document, env, node, is_ref):
+ # pass
+
+class CMakeXRefTransform(Transform):
+
+ # Run this transform early since we insert nodes we want
+ # treated as if they were written in the documents, but
+ # after the sphinx (210) and docutils (220) substitutions.
+ default_priority = 221
+
+ def apply(self):
+ env = self.document.settings.env
+
+ # Find CMake cross-reference nodes and add index and target
+ # nodes for them.
+ for ref in self.document.traverse(addnodes.pending_xref):
+ if not ref['refdomain'] == 'cmake':
+ continue
+
+ objtype = ref['reftype']
+ make_index_entry = _cmake_index_objs.get(objtype)
+ if not make_index_entry:
+ continue
+
+ objname = ref['reftarget']
+ targetnum = env.new_serialno('index-%s:%s' % (objtype, objname))
+
+ targetid = 'index-%s-%s:%s' % (targetnum, objtype, objname)
+ targetnode = nodes.target('', '', ids=[targetid])
+ self.document.note_explicit_target(targetnode)
+
+ indexnode = addnodes.index()
+ indexnode['entries'] = [make_index_entry(objname, targetid, '')]
+ ref.replace_self([indexnode, targetnode, ref])
+
+class CMakeDomain(Domain):
+ """CMake domain."""
+ name = 'cmake'
+ label = 'CMake'
+ object_types = {
+ 'command': ObjType('command', 'command'),
+ 'generator': ObjType('generator', 'generator'),
+ 'variable': ObjType('variable', 'variable'),
+ 'module': ObjType('module', 'module'),
+ 'policy': ObjType('policy', 'policy'),
+ 'prop_cache': ObjType('prop_cache', 'prop_cache'),
+ 'prop_dir': ObjType('prop_dir', 'prop_dir'),
+ 'prop_gbl': ObjType('prop_gbl', 'prop_gbl'),
+ 'prop_inst': ObjType('prop_inst', 'prop_inst'),
+ 'prop_sf': ObjType('prop_sf', 'prop_sf'),
+ 'prop_test': ObjType('prop_test', 'prop_test'),
+ 'prop_tgt': ObjType('prop_tgt', 'prop_tgt'),
+ 'manual': ObjType('manual', 'manual'),
+ }
+ directives = {
+ 'command': CMakeObject,
+ 'variable': CMakeObject,
+ # Other object types cannot be created except by the CMakeTransform
+ # 'generator': CMakeObject,
+ # 'module': CMakeObject,
+ # 'policy': CMakeObject,
+ # 'prop_cache': CMakeObject,
+ # 'prop_dir': CMakeObject,
+ # 'prop_gbl': CMakeObject,
+ # 'prop_inst': CMakeObject,
+ # 'prop_sf': CMakeObject,
+ # 'prop_test': CMakeObject,
+ # 'prop_tgt': CMakeObject,
+ # 'manual': CMakeObject,
+ }
+ roles = {
+ 'command': CMakeXRefRole(fix_parens = True, lowercase = True),
+ 'generator': CMakeXRefRole(),
+ 'variable': CMakeXRefRole(),
+ 'module': CMakeXRefRole(),
+ 'policy': CMakeXRefRole(),
+ 'prop_cache': CMakeXRefRole(),
+ 'prop_dir': CMakeXRefRole(),
+ 'prop_gbl': CMakeXRefRole(),
+ 'prop_inst': CMakeXRefRole(),
+ 'prop_sf': CMakeXRefRole(),
+ 'prop_test': CMakeXRefRole(),
+ 'prop_tgt': CMakeXRefRole(),
+ 'manual': CMakeXRefRole(),
+ }
+ initial_data = {
+ 'objects': {}, # fullname -> docname, objtype
+ }
+
+ def clear_doc(self, docname):
+ to_clear = set()
+ for fullname, (fn, _) in self.data['objects'].items():
+ if fn == docname:
+ to_clear.add(fullname)
+ for fullname in to_clear:
+ del self.data['objects'][fullname]
+
+ def resolve_xref(self, env, fromdocname, builder,
+ typ, target, node, contnode):
+ targetid = '%s:%s' % (typ, target)
+ obj = self.data['objects'].get(targetid)
+ if obj is None:
+ # TODO: warn somehow?
+ return None
+ return make_refnode(builder, fromdocname, obj[0], targetid,
+ contnode, target)
+
+ def get_objects(self):
+ for refname, (docname, type) in self.data['objects'].items():
+ yield (refname, refname, type, docname, refname, 1)
+
+def setup(app):
+ app.add_directive('cmake-module', CMakeModule)
+ app.add_transform(CMakeTransform)
+ app.add_transform(CMakeXRefTransform)
+ app.add_domain(CMakeDomain)
diff --git a/Utilities/Sphinx/conf.py.in b/Utilities/Sphinx/conf.py.in
new file mode 100644
index 000000000..eb24a6ecc
--- /dev/null
+++ b/Utilities/Sphinx/conf.py.in
@@ -0,0 +1,69 @@
+#=============================================================================
+# CMake - Cross Platform Makefile Generator
+# Copyright 2000-2013 Kitware, Inc., Insight Software Consortium
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+import sys
+import os
+import re
+import glob
+
+sys.path.insert(0, r'@conf_path@')
+
+source_suffix = '.rst'
+master_doc = 'index'
+
+project = 'CMake'
+copyright = '@conf_copyright@'
+version = '@conf_version@' # feature version
+release = '@conf_release@' # full version string
+
+primary_domain = 'cmake'
+
+exclude_patterns = []
+
+extensions = ['cmake']
+templates_path = ['@conf_path@/templates']
+
+nitpicky = True
+
+cmake_manuals = sorted(glob.glob(r'@conf_docs@/manual/*.rst'))
+cmake_manual_description = re.compile('^\.\. cmake-manual-description:(.*)$')
+man_pages = []
+for fpath in cmake_manuals:
+ try:
+ name, sec, rst = os.path.basename(fpath).split('.')
+ desc = None
+ f = open(fpath, 'r')
+ for l in f:
+ m = cmake_manual_description.match(l)
+ if m:
+ desc = m.group(1).strip()
+ break
+ f.close()
+ if desc:
+ man_pages.append(('manual/%s.%s' % (name, sec),
+ name, desc, [], int(sec)))
+ else:
+ sys.stderr.write("ERROR: No cmake-manual-description in '%s'\n" % fpath)
+ except Exception as e:
+ sys.stderr.write("ERROR: %s\n" % str(e))
+man_show_urls = False
+
+html_show_sourcelink = True
+html_static_path = ['@conf_path@/static']
+html_style = 'cmake.css'
+html_theme = 'default'
+html_title = 'CMake %s Documentation' % release
+html_short_title = '%s Documentation' % release
+html_favicon = '@conf_path@/static/cmake-favicon.ico'
+# Not supported yet by sphinx:
+# https://bitbucket.org/birkenfeld/sphinx/issue/1448/make-qthelp-more-configurable
+# qthelp_namespace = "org.cmake"
+# qthelp_qch_name = "CMake-300.qch"
diff --git a/Utilities/Sphinx/create_identifiers.py b/Utilities/Sphinx/create_identifiers.py
new file mode 100755
index 000000000..3fe3fcbe5
--- /dev/null
+++ b/Utilities/Sphinx/create_identifiers.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+
+import sys, os
+
+if len(sys.argv) != 2:
+ sys.exit(-1)
+name = sys.argv[1] + "/CMake.qhp"
+
+f = open(name)
+
+if not f:
+ sys.exit(-1)
+
+lines = f.read().splitlines()
+
+if not lines:
+ sys.exit(-1)
+
+newlines = []
+
+for line in lines:
+
+ mapping = (("command", "command"),
+ ("variable", "variable"),
+ ("target property", "prop_tgt"),
+ ("test property", "prop_test"),
+ ("source file property", "prop_sf"),
+ ("global property", "prop_gbl"),
+ ("module", "module"),
+ ("directory property", "prop_dir"),
+ ("cache property", "prop_cache"),
+ ("policy", "policy"),
+ ("installed file property", "prop_inst"))
+
+ for domain_object_string, domain_object_type in mapping:
+ if "<keyword name=\"" + domain_object_string + "\"" in line:
+ if not "id=\"" in line and not "#index-" in line:
+ prefix = "<keyword name=\"" + domain_object_string + "\" "
+ part1, part2 = line.split(prefix)
+ head, tail = part2.split("#" + domain_object_type + ":")
+ domain_object, rest = tail.split("\"")
+ line = part1 + prefix + "id=\"" + domain_object_type + "/" + domain_object + "\" " + part2
+ newlines.append(line + "\n")
+
+f = open(name, "w")
+f.writelines(newlines)
diff --git a/Utilities/Sphinx/fixup_qthelp_names.cmake b/Utilities/Sphinx/fixup_qthelp_names.cmake
new file mode 100644
index 000000000..e35ef25be
--- /dev/null
+++ b/Utilities/Sphinx/fixup_qthelp_names.cmake
@@ -0,0 +1,32 @@
+
+file(READ "${QTHELP_DIR}/CMake.qhcp" QHCP_CONTENT)
+
+string(REPLACE
+ "<homePage>qthelp://org.sphinx.cmake" "<homePage>qthelp://org.cmake"
+ QHCP_CONTENT "${QHCP_CONTENT}"
+)
+string(REPLACE
+ "<startPage>qthelp://org.sphinx.cmake" "<startPage>qthelp://org.cmake"
+ QHCP_CONTENT "${QHCP_CONTENT}"
+)
+
+string(REPLACE
+ "<output>CMake.qch" "<output>CMake-${CMake_VERSION}.qch"
+ QHCP_CONTENT "${QHCP_CONTENT}"
+)
+string(REPLACE
+ "<file>CMake.qch" "<file>CMake-${CMake_VERSION}.qch"
+ QHCP_CONTENT "${QHCP_CONTENT}"
+)
+
+file(WRITE "${QTHELP_DIR}/CMake.qhcp" "${QHCP_CONTENT}")
+
+
+file(READ "${QTHELP_DIR}/CMake.qhp" QHP_CONTENT)
+
+string(REPLACE
+ "<namespace>org.sphinx.cmake" "<namespace>org.cmake"
+ QHP_CONTENT "${QHP_CONTENT}"
+)
+
+file(WRITE "${QTHELP_DIR}/CMake.qhp" "${QHP_CONTENT}")
diff --git a/Utilities/Sphinx/static/cmake-favicon.ico b/Utilities/Sphinx/static/cmake-favicon.ico
new file mode 100644
index 000000000..fce8f922f
--- /dev/null
+++ b/Utilities/Sphinx/static/cmake-favicon.ico
Binary files differ
diff --git a/Utilities/Sphinx/static/cmake-logo-16.png b/Utilities/Sphinx/static/cmake-logo-16.png
new file mode 100644
index 000000000..2039c25b0
--- /dev/null
+++ b/Utilities/Sphinx/static/cmake-logo-16.png
Binary files differ
diff --git a/Utilities/Sphinx/static/cmake.css b/Utilities/Sphinx/static/cmake.css
new file mode 100644
index 000000000..2a326d47d
--- /dev/null
+++ b/Utilities/Sphinx/static/cmake.css
@@ -0,0 +1,8 @@
+/* Import the Sphinx theme style. */
+@import url("default.css");
+
+/* Wrap sidebar content even within words so that long
+ document names do not escape sidebar borders. */
+div.sphinxsidebarwrapper {
+ word-wrap: break-word;
+}
diff --git a/Utilities/Sphinx/templates/layout.html b/Utilities/Sphinx/templates/layout.html
new file mode 100644
index 000000000..177e04455
--- /dev/null
+++ b/Utilities/Sphinx/templates/layout.html
@@ -0,0 +1,19 @@
+{% extends "!layout.html" %}
+{% block rootrellink %}
+ <li>
+ <img src="{{ pathto('_static/cmake-logo-16.png', 1) }}" alt=""
+ style="vertical-align: middle; margin-top: -2px" />
+ </li>
+ <li>
+ <a href="https://cmake.org/">CMake</a>{{ reldelim1 }}
+ </li>
+ <li>
+ <a href="{{ pathto(master_doc) }}">{{ shorttitle|e }}</a>{{ reldelim1 }}
+ </li>
+{% endblock %}
+
+{# Put some context in the html title element. Workaround for #}
+{# https://bitbucket.org/birkenfeld/sphinx/issue/1492/qthelp-generate-html-title-element-should #}
+{% block htmltitle %}
+ <title>{{ title|striptags|e }} {{ "&mdash;"|safe }} {{ docstitle|e }}</title>
+{% endblock %}
diff --git a/Utilities/cmThirdParty.h.in b/Utilities/cmThirdParty.h.in
index c8240850e..4c1177ca8 100644
--- a/Utilities/cmThirdParty.h.in
+++ b/Utilities/cmThirdParty.h.in
@@ -9,15 +9,19 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#ifndef __cmThirdParty_h
-#define __cmThirdParty_h
+#ifndef cmThirdParty_h
+#define cmThirdParty_h
/* Whether CMake is using its own utility libraries. */
#cmakedefine CMAKE_USE_SYSTEM_CURL
#cmakedefine CMAKE_USE_SYSTEM_EXPAT
+#cmakedefine CMAKE_USE_SYSTEM_KWIML
#cmakedefine CMAKE_USE_SYSTEM_ZLIB
#cmakedefine CMAKE_USE_SYSTEM_BZIP2
#cmakedefine CMAKE_USE_SYSTEM_LIBARCHIVE
+#cmakedefine CMAKE_USE_SYSTEM_LIBLZMA
+#cmakedefine CMAKE_USE_SYSTEM_FORM
+#cmakedefine CMAKE_USE_SYSTEM_JSONCPP
#cmakedefine CTEST_USE_XMLRPC
#endif
diff --git a/Utilities/cm_bzlib.h b/Utilities/cm_bzlib.h
index d1fffa1aa..567802561 100644
--- a/Utilities/cm_bzlib.h
+++ b/Utilities/cm_bzlib.h
@@ -9,8 +9,8 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#ifndef __cm_bzlib_h
-#define __cm_bzlib_h
+#ifndef cm_bzlib_h
+#define cm_bzlib_h
/* Use the bzip2 library configured for CMake. */
#include "cmThirdParty.h"
diff --git a/Utilities/cm_curl.h b/Utilities/cm_curl.h
index 43944a3f4..c9835e73a 100644
--- a/Utilities/cm_curl.h
+++ b/Utilities/cm_curl.h
@@ -9,15 +9,15 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#ifndef __cm_curl_h
-#define __cm_curl_h
+#ifndef cm_curl_h
+#define cm_curl_h
/* Use the curl library configured for CMake. */
#include "cmThirdParty.h"
#ifdef CMAKE_USE_SYSTEM_CURL
# include <curl/curl.h>
#else
-# include <cmcurl/curl/curl.h>
+# include <cmcurl/include/curl/curl.h>
#endif
#endif
diff --git a/Utilities/cm_expat.h b/Utilities/cm_expat.h
index 91f4a7b52..f361541d0 100644
--- a/Utilities/cm_expat.h
+++ b/Utilities/cm_expat.h
@@ -9,8 +9,8 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#ifndef __cm_expat_h
-#define __cm_expat_h
+#ifndef cm_expat_h
+#define cm_expat_h
/* Use the expat library configured for CMake. */
#include "cmThirdParty.h"
diff --git a/Utilities/cm_jsoncpp_reader.h b/Utilities/cm_jsoncpp_reader.h
new file mode 100644
index 000000000..22f2d8115
--- /dev/null
+++ b/Utilities/cm_jsoncpp_reader.h
@@ -0,0 +1,23 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cm_jsoncpp_reader_h
+#define cm_jsoncpp_reader_h
+
+/* Use the jsoncpp library configured for CMake. */
+#include "cmThirdParty.h"
+#ifdef CMAKE_USE_SYSTEM_JSONCPP
+# include <json/reader.h>
+#else
+# include <cmjsoncpp/include/json/reader.h>
+#endif
+
+#endif
diff --git a/Utilities/cm_jsoncpp_value.h b/Utilities/cm_jsoncpp_value.h
new file mode 100644
index 000000000..b4cf62057
--- /dev/null
+++ b/Utilities/cm_jsoncpp_value.h
@@ -0,0 +1,23 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cm_jsoncpp_value_h
+#define cm_jsoncpp_value_h
+
+/* Use the jsoncpp library configured for CMake. */
+#include "cmThirdParty.h"
+#ifdef CMAKE_USE_SYSTEM_JSONCPP
+# include <json/value.h>
+#else
+# include <cmjsoncpp/include/json/value.h>
+#endif
+
+#endif
diff --git a/Utilities/cm_jsoncpp_writer.h b/Utilities/cm_jsoncpp_writer.h
new file mode 100644
index 000000000..c99a0d090
--- /dev/null
+++ b/Utilities/cm_jsoncpp_writer.h
@@ -0,0 +1,23 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cm_jsoncpp_writer_h
+#define cm_jsoncpp_writer_h
+
+/* Use the jsoncpp library configured for CMake. */
+#include "cmThirdParty.h"
+#ifdef CMAKE_USE_SYSTEM_JSONCPP
+# include <json/writer.h>
+#else
+# include <cmjsoncpp/include/json/writer.h>
+#endif
+
+#endif
diff --git a/Utilities/cm_kwiml.h b/Utilities/cm_kwiml.h
new file mode 100644
index 000000000..ab2b80b3c
--- /dev/null
+++ b/Utilities/cm_kwiml.h
@@ -0,0 +1,25 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cm_kwiml_h
+#define cm_kwiml_h
+
+/* Use the KWIML library configured for CMake. */
+#include "cmThirdParty.h"
+#ifdef CMAKE_USE_SYSTEM_KWIML
+# include <kwiml/abi.h>
+# include <kwiml/int.h>
+#else
+# include "KWIML/include/kwiml/abi.h"
+# include "KWIML/include/kwiml/int.h"
+#endif
+
+#endif
diff --git a/Utilities/cm_libarchive.h b/Utilities/cm_libarchive.h
index 1469baeb4..0f18c91a8 100644
--- a/Utilities/cm_libarchive.h
+++ b/Utilities/cm_libarchive.h
@@ -9,8 +9,8 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#ifndef __cm_libarchive_h
-#define __cm_libarchive_h
+#ifndef cm_libarchive_h
+#define cm_libarchive_h
/* Use the libarchive configured for CMake. */
#include "cmThirdParty.h"
diff --git a/Utilities/cm_lzma.h b/Utilities/cm_lzma.h
new file mode 100644
index 000000000..02d7e4fd4
--- /dev/null
+++ b/Utilities/cm_lzma.h
@@ -0,0 +1,23 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cm_lzma_h
+#define cm_lzma_h
+
+/* Use the liblzma configured for CMake. */
+#include "cmThirdParty.h"
+#ifdef CMAKE_USE_SYSTEM_LIBLZMA
+# include <lzma.h>
+#else
+# include <cmliblzma/liblzma/api/lzma.h>
+#endif
+
+#endif
diff --git a/Utilities/cm_xmlrpc.h b/Utilities/cm_xmlrpc.h
index a6b375da8..ac461f9db 100644
--- a/Utilities/cm_xmlrpc.h
+++ b/Utilities/cm_xmlrpc.h
@@ -9,8 +9,8 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#ifndef __cm_xmlrpc_h
-#define __cm_xmlrpc_h
+#ifndef cm_xmlrpc_h
+#define cm_xmlrpc_h
/* Use the xmlrpc library configured for CMake. */
#include "cmThirdParty.h"
diff --git a/Utilities/cm_zlib.h b/Utilities/cm_zlib.h
index fb5832e35..1b5c06e7e 100644
--- a/Utilities/cm_zlib.h
+++ b/Utilities/cm_zlib.h
@@ -9,8 +9,8 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#ifndef __cm_zlib_h
-#define __cm_zlib_h
+#ifndef cm_zlib_h
+#define cm_zlib_h
/* Use the zlib library configured for CMake. */
#include "cmThirdParty.h"
diff --git a/Utilities/cmbzip2/compress.c b/Utilities/cmbzip2/compress.c
index 7d9b3da75..feea233c2 100644
--- a/Utilities/cmbzip2/compress.c
+++ b/Utilities/cmbzip2/compress.c
@@ -239,7 +239,7 @@ static
void sendMTFValues ( EState* s )
{
Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
- Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
+ Int32 nSelectors = 0, alphaSize, minLen, maxLen, selCtr;
Int32 nGroups, nBytes;
/*--
diff --git a/Utilities/cmcompress/cmcompress.h b/Utilities/cmcompress/cmcompress.h
index fdb0d90b7..4cd3a1c3e 100644
--- a/Utilities/cmcompress/cmcompress.h
+++ b/Utilities/cmcompress/cmcompress.h
@@ -35,8 +35,8 @@
* SUCH DAMAGE.
*/
-#ifndef __cmcompress__h_
-#define __cmcompress__h_
+#ifndef cmcompress__h_
+#define cmcompress__h_
#include <stdio.h>
@@ -192,4 +192,4 @@ extern "C"
#endif
-#endif /* __cmcompress__h_ */
+#endif /* cmcompress__h_ */
diff --git a/Utilities/xml/.gitattributes b/Utilities/cmcurl/.gitattributes
index 562b12e16..562b12e16 100644
--- a/Utilities/xml/.gitattributes
+++ b/Utilities/cmcurl/.gitattributes
diff --git a/Utilities/cmcurl/CMake/CurlCheckCSourceCompiles.cmake b/Utilities/cmcurl/CMake/CurlCheckCSourceCompiles.cmake
deleted file mode 100644
index d025769aa..000000000
--- a/Utilities/cmcurl/CMake/CurlCheckCSourceCompiles.cmake
+++ /dev/null
@@ -1,75 +0,0 @@
-# - Check if the source code provided in the SOURCE argument compiles.
-# CURL_CHECK_C_SOURCE_COMPILES(SOURCE VAR)
-# - macro which checks if the source code compiles
-# SOURCE - source code to try to compile
-# VAR - variable to store whether the source code compiled
-#
-# The following variables may be set before calling this macro to
-# modify the way the check is run:
-#
-# CMAKE_REQUIRED_FLAGS = string of compile command line flags
-# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
-# CMAKE_REQUIRED_INCLUDES = list of include directories
-# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
-
-MACRO(CURL_CHECK_C_SOURCE_COMPILES SOURCE VAR)
- IF("${VAR}" MATCHES "^${VAR}$" OR "${VAR}" MATCHES "UNKNOWN")
- SET(message "${VAR}")
- # If the number of arguments is greater than 2 (SOURCE VAR)
- IF(${ARGC} GREATER 2)
- # then add the third argument as a message
- SET(message "${ARGV2} (${VAR})")
- ENDIF(${ARGC} GREATER 2)
- SET(MACRO_CHECK_FUNCTION_DEFINITIONS
- "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
- IF(CMAKE_REQUIRED_LIBRARIES)
- SET(CURL_CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES
- "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
- ELSE(CMAKE_REQUIRED_LIBRARIES)
- SET(CURL_CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES)
- ENDIF(CMAKE_REQUIRED_LIBRARIES)
- IF(CMAKE_REQUIRED_INCLUDES)
- SET(CURL_CHECK_C_SOURCE_COMPILES_ADD_INCLUDES
- "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
- ELSE(CMAKE_REQUIRED_INCLUDES)
- SET(CURL_CHECK_C_SOURCE_COMPILES_ADD_INCLUDES)
- ENDIF(CMAKE_REQUIRED_INCLUDES)
- SET(src "")
- FOREACH(def ${EXTRA_DEFINES})
- SET(src "${src}#define ${def} 1\n")
- ENDFOREACH(def)
- FOREACH(inc ${HEADER_INCLUDES})
- SET(src "${src}#include <${inc}>\n")
- ENDFOREACH(inc)
-
- SET(src "${src}\nint main() { ${SOURCE} ; return 0; }")
- SET(CMAKE_CONFIGURABLE_FILE_CONTENT "${src}")
- CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/CMake/CMakeConfigurableFile.in
- "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c"
- IMMEDIATE)
- MESSAGE(STATUS "Performing Test ${message}")
- TRY_COMPILE(${VAR}
- ${CMAKE_BINARY_DIR}
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c
- COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
- CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
- "${CURL_CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES}"
- "${CURL_CHECK_C_SOURCE_COMPILES_ADD_INCLUDES}"
- OUTPUT_VARIABLE OUTPUT)
- IF(${VAR})
- SET(${VAR} 1 CACHE INTERNAL "Test ${message}")
- MESSAGE(STATUS "Performing Test ${message} - Success")
- FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
- "Performing C SOURCE FILE Test ${message} succeded with the following output:\n"
- "${OUTPUT}\n"
- "Source file was:\n${src}\n")
- ELSE(${VAR})
- MESSAGE(STATUS "Performing Test ${message} - Failed")
- SET(${VAR} "" CACHE INTERNAL "Test ${message}")
- FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
- "Performing C SOURCE FILE Test ${message} failed with the following output:\n"
- "${OUTPUT}\n"
- "Source file was:\n${src}\n")
- ENDIF(${VAR})
- ENDIF("${VAR}" MATCHES "^${VAR}$" OR "${VAR}" MATCHES "UNKNOWN")
-ENDMACRO(CURL_CHECK_C_SOURCE_COMPILES)
diff --git a/Utilities/cmcurl/CMake/CurlCheckCSourceRuns.cmake b/Utilities/cmcurl/CMake/CurlCheckCSourceRuns.cmake
deleted file mode 100644
index 19681bd85..000000000
--- a/Utilities/cmcurl/CMake/CurlCheckCSourceRuns.cmake
+++ /dev/null
@@ -1,83 +0,0 @@
-# - Check if the source code provided in the SOURCE argument compiles and runs.
-# CURL_CHECK_C_SOURCE_RUNS(SOURCE VAR)
-# - macro which checks if the source code runs
-# SOURCE - source code to try to compile
-# VAR - variable to store size if the type exists.
-#
-# The following variables may be set before calling this macro to
-# modify the way the check is run:
-#
-# CMAKE_REQUIRED_FLAGS = string of compile command line flags
-# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
-# CMAKE_REQUIRED_INCLUDES = list of include directories
-# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
-
-MACRO(CURL_CHECK_C_SOURCE_RUNS SOURCE VAR)
- IF("${VAR}" MATCHES "^${VAR}$" OR "${VAR}" MATCHES "UNKNOWN")
- SET(message "${VAR}")
- # If the number of arguments is greater than 2 (SOURCE VAR)
- IF(${ARGC} GREATER 2)
- # then add the third argument as a message
- SET(message "${ARGV2} (${VAR})")
- ENDIF(${ARGC} GREATER 2)
- SET(MACRO_CHECK_FUNCTION_DEFINITIONS
- "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
- IF(CMAKE_REQUIRED_LIBRARIES)
- SET(CURL_CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES
- "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
- ELSE(CMAKE_REQUIRED_LIBRARIES)
- SET(CURL_CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES)
- ENDIF(CMAKE_REQUIRED_LIBRARIES)
- IF(CMAKE_REQUIRED_INCLUDES)
- SET(CURL_CHECK_C_SOURCE_COMPILES_ADD_INCLUDES
- "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
- ELSE(CMAKE_REQUIRED_INCLUDES)
- SET(CURL_CHECK_C_SOURCE_COMPILES_ADD_INCLUDES)
- ENDIF(CMAKE_REQUIRED_INCLUDES)
- SET(src "")
- FOREACH(def ${EXTRA_DEFINES})
- SET(src "${src}#define ${def} 1\n")
- ENDFOREACH(def)
- FOREACH(inc ${HEADER_INCLUDES})
- SET(src "${src}#include <${inc}>\n")
- ENDFOREACH(inc)
-
- SET(src "${src}\nint main() { ${SOURCE} ; return 0; }")
- SET(CMAKE_CONFIGURABLE_FILE_CONTENT "${src}")
- CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/CMake/CMakeConfigurableFile.in
- "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c"
- IMMEDIATE)
- MESSAGE(STATUS "Performing Test ${message}")
- TRY_RUN(${VAR} ${VAR}_COMPILED
- ${CMAKE_BINARY_DIR}
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c
- COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
- CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
- "${CURL_CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES}"
- "${CURL_CHECK_C_SOURCE_COMPILES_ADD_INCLUDES}"
- OUTPUT_VARIABLE OUTPUT)
- # if it did not compile make the return value fail code of 1
- IF(NOT ${VAR}_COMPILED)
- SET(${VAR} 1)
- ENDIF(NOT ${VAR}_COMPILED)
- # if the return value was 0 then it worked
- SET(result_var ${${VAR}})
- IF("${result_var}" EQUAL 0)
- SET(${VAR} 1 CACHE INTERNAL "Test ${message}")
- MESSAGE(STATUS "Performing Test ${message} - Success")
- FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
- "Performing C SOURCE FILE Test ${message} succeded with the following output:\n"
- "${OUTPUT}\n"
- "Return value: ${${VAR}}\n"
- "Source file was:\n${src}\n")
- ELSE("${result_var}" EQUAL 0)
- MESSAGE(STATUS "Performing Test ${message} - Failed")
- SET(${VAR} "" CACHE INTERNAL "Test ${message}")
- FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
- "Performing C SOURCE FILE Test ${message} failed with the following output:\n"
- "${OUTPUT}\n"
- "Return value: ${result_var}\n"
- "Source file was:\n${src}\n")
- ENDIF("${result_var}" EQUAL 0)
- ENDIF("${VAR}" MATCHES "^${VAR}$" OR "${VAR}" MATCHES "UNKNOWN")
-ENDMACRO(CURL_CHECK_C_SOURCE_RUNS)
diff --git a/Utilities/cmcurl/CMake/CurlTests.c b/Utilities/cmcurl/CMake/CurlTests.c
index d74a4f016..3c712325f 100644
--- a/Utilities/cmcurl/CMake/CurlTests.c
+++ b/Utilities/cmcurl/CMake/CurlTests.c
@@ -1,6 +1,27 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
#ifdef TIME_WITH_SYS_TIME
/* Time with sys/time test */
-
+
#include <sys/types.h>
#include <sys/time.h>
#include <time.h>
@@ -16,295 +37,122 @@ return 0;
#endif
-#ifdef HAVE_O_NONBLOCK
+#ifdef HAVE_FCNTL_O_NONBLOCK
+/* headers for FCNTL_O_NONBLOCK test */
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
-
-int
-main ()
-{
- /* try to compile O_NONBLOCK */
-
-#if defined(sun) || defined(__sun__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+/* */
+#if defined(sun) || defined(__sun__) || \
+ defined(__SUNPRO_C) || defined(__SUNPRO_CC)
# if defined(__SVR4) || defined(__srv4__)
# define PLATFORM_SOLARIS
# else
# define PLATFORM_SUNOS4
# endif
#endif
-#if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX4)
+#if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX41)
# define PLATFORM_AIX_V3
#endif
-
-#if defined(PLATFORM_SUNOS4) || defined(PLATFORM_AIX_V3) || (defined(__BEOS__) && !defined(__HAIKU__))
+/* */
+#if defined(PLATFORM_SUNOS4) || defined(PLATFORM_AIX_V3) || defined(__BEOS__)
#error "O_NONBLOCK does not work on this platform"
#endif
- int socket;
- int flags = fcntl(socket, F_SETFL, flags | O_NONBLOCK);
- return 0;
-}
-#endif
-#ifdef HAVE_GETHOSTBYADDR_R_5
-#include <sys/types.h>
-#include <netdb.h>
int
main ()
{
-
-char * address;
-int length;
-int type;
-struct hostent h;
-struct hostent_data hdata;
-int rc;
-#ifndef gethostbyaddr_r
- (void)gethostbyaddr_r;
-#endif
-rc = gethostbyaddr_r(address, length, type, &h, &hdata);
- ;
- return 0;
+ /* O_NONBLOCK source test */
+ int flags = 0;
+ if(0 != fcntl(0, F_SETFL, flags | O_NONBLOCK))
+ return 1;
+ return 0;
}
#endif
-#ifdef HAVE_GETHOSTBYADDR_R_5_REENTRANT
-#define _REENTRANT
-#include <sys/types.h>
-#include <netdb.h>
-int
-main ()
-{
-char * address;
-int length;q
-int type;
-struct hostent h;
-struct hostent_data hdata;
-int rc;
-#ifndef gethostbyaddr_r
- (void)gethostbyaddr_r;
-#endif
-rc = gethostbyaddr_r(address, length, type, &h, &hdata);
- ;
- return 0;
-}
-#endif
-#ifdef HAVE_GETHOSTBYADDR_R_7
-#include <sys/types.h>
-#include <netdb.h>
-int
-main ()
-{
-
-char * address;
-int length;
-int type;
-struct hostent h;
-char buffer[8192];
-int h_errnop;
-struct hostent * hp;
-
-#ifndef gethostbyaddr_r
- (void)gethostbyaddr_r;
-#endif
-hp = gethostbyaddr_r(address, length, type, &h,
- buffer, 8192, &h_errnop);
- ;
- return 0;
-}
-#endif
-#ifdef HAVE_GETHOSTBYADDR_R_7_REENTRANT
-#define _REENTRANT
-#include <sys/types.h>
-#include <netdb.h>
-int
-main ()
-{
-
-char * address;
-int length;
-int type;
-struct hostent h;
-char buffer[8192];
-int h_errnop;
-struct hostent * hp;
-
-#ifndef gethostbyaddr_r
- (void)gethostbyaddr_r;
-#endif
-hp = gethostbyaddr_r(address, length, type, &h,
- buffer, 8192, &h_errnop);
- ;
- return 0;
-}
-#endif
-#ifdef HAVE_GETHOSTBYADDR_R_8
+/* tests for gethostbyaddr_r or gethostbyname_r */
+#if defined(HAVE_GETHOSTBYADDR_R_5_REENTRANT) || \
+ defined(HAVE_GETHOSTBYADDR_R_7_REENTRANT) || \
+ defined(HAVE_GETHOSTBYADDR_R_8_REENTRANT) || \
+ defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT) || \
+ defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT) || \
+ defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT)
+# define _REENTRANT
+ /* no idea whether _REENTRANT is always set, just invent a new flag */
+# define TEST_GETHOSTBYFOO_REENTRANT
+#endif
+#if defined(HAVE_GETHOSTBYADDR_R_5) || \
+ defined(HAVE_GETHOSTBYADDR_R_7) || \
+ defined(HAVE_GETHOSTBYADDR_R_8) || \
+ defined(HAVE_GETHOSTBYNAME_R_3) || \
+ defined(HAVE_GETHOSTBYNAME_R_5) || \
+ defined(HAVE_GETHOSTBYNAME_R_6) || \
+ defined(TEST_GETHOSTBYFOO_REENTRANT)
#include <sys/types.h>
#include <netdb.h>
-int
-main ()
+int main(void)
{
-
-char * address;
-int length;
-int type;
-struct hostent h;
-char buffer[8192];
-int h_errnop;
-struct hostent * hp;
-int rc;
-
-#ifndef gethostbyaddr_r
- (void)gethostbyaddr_r;
-#endif
-rc = gethostbyaddr_r(address, length, type, &h,
- buffer, 8192, &hp, &h_errnop);
- ;
- return 0;
-}
+ char *address = "example.com";
+ int length = 0;
+ int type = 0;
+ struct hostent h;
+ int rc = 0;
+#if defined(HAVE_GETHOSTBYADDR_R_5) || \
+ defined(HAVE_GETHOSTBYADDR_R_5_REENTRANT) || \
+ \
+ defined(HAVE_GETHOSTBYNAME_R_3) || \
+ defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT)
+ struct hostent_data hdata;
+#elif defined(HAVE_GETHOSTBYADDR_R_7) || \
+ defined(HAVE_GETHOSTBYADDR_R_7_REENTRANT) || \
+ defined(HAVE_GETHOSTBYADDR_R_8) || \
+ defined(HAVE_GETHOSTBYADDR_R_8_REENTRANT) || \
+ \
+ defined(HAVE_GETHOSTBYNAME_R_5) || \
+ defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT) || \
+ defined(HAVE_GETHOSTBYNAME_R_6) || \
+ defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT)
+ char buffer[8192];
+ int h_errnop;
+ struct hostent *hp;
#endif
-#ifdef HAVE_GETHOSTBYADDR_R_8_REENTRANT
-#define _REENTRANT
-#include <sys/types.h>
-#include <netdb.h>
-int
-main ()
-{
-
-char * address;
-int length;
-int type;
-struct hostent h;
-char buffer[8192];
-int h_errnop;
-struct hostent * hp;
-int rc;
#ifndef gethostbyaddr_r
(void)gethostbyaddr_r;
#endif
-rc = gethostbyaddr_r(address, length, type, &h,
- buffer, 8192, &hp, &h_errnop);
- ;
- return 0;
-}
-#endif
-#ifdef HAVE_GETHOSTBYNAME_R_3
-#include <string.h>
-#include <sys/types.h>
-#include <netdb.h>
-#undef NULL
-#define NULL (void *)0
-int
-main ()
-{
-
-struct hostent_data data;
-#ifndef gethostbyname_r
- (void)gethostbyname_r;
-#endif
-gethostbyname_r(NULL, NULL, NULL);
- ;
+#if defined(HAVE_GETHOSTBYADDR_R_5) || \
+ defined(HAVE_GETHOSTBYADDR_R_5_REENTRANT)
+ rc = gethostbyaddr_r(address, length, type, &h, &hdata);
+#elif defined(HAVE_GETHOSTBYADDR_R_7) || \
+ defined(HAVE_GETHOSTBYADDR_R_7_REENTRANT)
+ hp = gethostbyaddr_r(address, length, type, &h, buffer, 8192, &h_errnop);
+ (void)hp;
+#elif defined(HAVE_GETHOSTBYADDR_R_8) || \
+ defined(HAVE_GETHOSTBYADDR_R_8_REENTRANT)
+ rc = gethostbyaddr_r(address, length, type, &h, buffer, 8192, &hp, &h_errnop);
+#endif
+
+#if defined(HAVE_GETHOSTBYNAME_R_3) || \
+ defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT)
+ rc = gethostbyname_r(address, &h, &hdata);
+#elif defined(HAVE_GETHOSTBYNAME_R_5) || \
+ defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT)
+ rc = gethostbyname_r(address, &h, buffer, 8192, &h_errnop);
+ (void)hp; /* not used for test */
+#elif defined(HAVE_GETHOSTBYNAME_R_6) || \
+ defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT)
+ rc = gethostbyname_r(address, &h, buffer, 8192, &hp, &h_errnop);
+#endif
+
+ (void)length;
+ (void)type;
+ (void)rc;
return 0;
}
#endif
-#ifdef HAVE_GETHOSTBYNAME_R_3_REENTRANT
-#define _REENTRANT
-#include <string.h>
-#include <sys/types.h>
-#include <netdb.h>
-#undef NULL
-#define NULL (void *)0
-int
-main ()
-{
-
-struct hostent_data data;
-#ifndef gethostbyname_r
- (void)gethostbyname_r;
-#endif
-gethostbyname_r(NULL, NULL, NULL);
- ;
- return 0;
-}
-#endif
-#ifdef HAVE_GETHOSTBYNAME_R_5
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#undef NULL
-#define NULL (void *)0
-
-int
-main ()
-{
-#ifndef gethostbyname_r
- (void)gethostbyname_r;
-#endif
-gethostbyname_r(NULL, NULL, NULL, 0, NULL);
- ;
- return 0;
-}
-#endif
-#ifdef HAVE_GETHOSTBYNAME_R_5_REENTRANT
-#define _REENTRANT
-#include <sys/types.h>
-#include <netdb.h>
-#undef NULL
-#define NULL (void *)0
-
-int
-main ()
-{
-
-#ifndef gethostbyname_r
- (void)gethostbyname_r;
-#endif
-gethostbyname_r(NULL, NULL, NULL, 0, NULL);
- ;
- return 0;
-}
-#endif
-#ifdef HAVE_GETHOSTBYNAME_R_6
-#include <sys/types.h>
-#include <netdb.h>
-#undef NULL
-#define NULL (void *)0
-
-int
-main ()
-{
-
-#ifndef gethostbyname_r
- (void)gethostbyname_r;
-#endif
-gethostbyname_r(NULL, NULL, NULL, 0, NULL, NULL);
- ;
- return 0;
-}
-#endif
-#ifdef HAVE_GETHOSTBYNAME_R_6_REENTRANT
-#define _REENTRANT
-#include <sys/types.h>
-#include <netdb.h>
-#undef NULL
-#define NULL (void *)0
-
-int
-main ()
-{
-
-#ifndef gethostbyname_r
- (void)gethostbyname_r;
-#endif
-gethostbyname_r(NULL, NULL, NULL, 0, NULL, NULL);
- ;
- return 0;
-}
-#endif
#ifdef HAVE_SOCKLEN_T
#ifdef _WIN32
#include <ws2tcpip.h>
@@ -339,6 +187,24 @@ if (sizeof (in_addr_t))
return 0;
}
#endif
+
+#ifdef HAVE_BOOL_T
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_STDBOOL_H
+#include <stdbool.h>
+#endif
+int
+main ()
+{
+if (sizeof (bool *) )
+ return 0;
+ ;
+ return 0;
+}
+#endif
+
#ifdef STDC_HEADERS
#include <stdlib.h>
#include <stdarg.h>
@@ -432,7 +298,20 @@ int main(void) {
int main () { ; return 0; }
#endif
#ifdef HAVE_IOCTLSOCKET
-#include <windows.h>
+/* includes start */
+#ifdef HAVE_WINDOWS_H
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include <windows.h>
+# ifdef HAVE_WINSOCK2_H
+# include <winsock2.h>
+# else
+# ifdef HAVE_WINSOCK_H
+# include <winsock.h>
+# endif
+# endif
+#endif
int
main ()
@@ -447,52 +326,182 @@ main ()
}
#endif
-#ifdef HAVE_IOCTLSOCKET_CASE
-#include <windows.h>
+#ifdef HAVE_IOCTLSOCKET_CAMEL
+/* includes start */
+#ifdef HAVE_WINDOWS_H
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include <windows.h>
+# ifdef HAVE_WINSOCK2_H
+# include <winsock2.h>
+# else
+# ifdef HAVE_WINSOCK_H
+# include <winsock.h>
+# endif
+# endif
+#endif
int
main ()
{
/* IoctlSocket source code */
- int socket;
- int flags = IoctlSocket(socket, FIONBIO, (long)1);
+ if(0 != IoctlSocket(0, 0, 0))
+ return 1;
+ ;
+ return 0;
+}
+#endif
+#ifdef HAVE_IOCTLSOCKET_CAMEL_FIONBIO
+/* includes start */
+#ifdef HAVE_WINDOWS_H
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include <windows.h>
+# ifdef HAVE_WINSOCK2_H
+# include <winsock2.h>
+# else
+# ifdef HAVE_WINSOCK_H
+# include <winsock.h>
+# endif
+# endif
+#endif
+int
+main ()
+{
+
+/* IoctlSocket source code */
+ long flags = 0;
+ if(0 != ioctlsocket(0, FIONBIO, &flags))
+ return 1;
;
return 0;
}
#endif
-#ifdef HAVE_FIONBIO
+#ifdef HAVE_IOCTLSOCKET_FIONBIO
+/* includes start */
+#ifdef HAVE_WINDOWS_H
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include <windows.h>
+# ifdef HAVE_WINSOCK2_H
+# include <winsock2.h>
+# else
+# ifdef HAVE_WINSOCK_H
+# include <winsock.h>
+# endif
+# endif
+#endif
+
+int
+main ()
+{
+
+ int flags = 0;
+ if(0 != ioctlsocket(0, FIONBIO, &flags))
+ return 1;
+
+ ;
+ return 0;
+}
+#endif
+#ifdef HAVE_IOCTL_FIONBIO
/* headers for FIONBIO test */
-#include <unistd.h>
-#include <stropts.h>
+/* includes start */
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+#ifdef HAVE_STROPTS_H
+# include <stropts.h>
+#endif
int
main ()
{
-/* FIONBIO source test (old-style unix) */
- int socket;
- int flags = ioctl(socket, FIONBIO, &flags);
+ int flags = 0;
+ if(0 != ioctl(0, FIONBIO, &flags))
+ return 1;
;
return 0;
}
#endif
-#ifdef HAVE_SO_NONBLOCK
+#ifdef HAVE_IOCTL_SIOCGIFADDR
+/* headers for FIONBIO test */
+/* includes start */
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+#ifdef HAVE_STROPTS_H
+# include <stropts.h>
+#endif
+#include <net/if.h>
-/* headers for SO_NONBLOCK test (BeOS) */
-#include <sys/types.h>
-#include <unistd.h>
-#include <fcntl.h>
+int
+main ()
+{
+ struct ifreq ifr;
+ if(0 != ioctl(0, SIOCGIFADDR, &ifr))
+ return 1;
-int main()
+ ;
+ return 0;
+}
+#endif
+#ifdef HAVE_SETSOCKOPT_SO_NONBLOCK
+/* includes start */
+#ifdef HAVE_WINDOWS_H
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include <windows.h>
+# ifdef HAVE_WINSOCK2_H
+# include <winsock2.h>
+# else
+# ifdef HAVE_WINSOCK_H
+# include <winsock.h>
+# endif
+# endif
+#endif
+/* includes start */
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+/* includes end */
+
+int
+main ()
{
-/* SO_NONBLOCK source code */
- long b = 1;
- int socket;
- int flags = setsockopt(socket, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
- return 0;
+ if(0 != setsockopt(0, SOL_SOCKET, SO_NONBLOCK, 0, 0))
+ return 1;
+ ;
+ return 0;
}
#endif
#ifdef HAVE_GLIBC_STRERROR_R
diff --git a/Utilities/cmcurl/CMake/FindCARES.cmake b/Utilities/cmcurl/CMake/FindCARES.cmake
new file mode 100644
index 000000000..c4ab5f132
--- /dev/null
+++ b/Utilities/cmcurl/CMake/FindCARES.cmake
@@ -0,0 +1,42 @@
+# - Find c-ares
+# Find the c-ares includes and library
+# This module defines
+# CARES_INCLUDE_DIR, where to find ares.h, etc.
+# CARES_LIBRARIES, the libraries needed to use c-ares.
+# CARES_FOUND, If false, do not try to use c-ares.
+# also defined, but not for general use are
+# CARES_LIBRARY, where to find the c-ares library.
+
+FIND_PATH(CARES_INCLUDE_DIR ares.h
+ /usr/local/include
+ /usr/include
+ )
+
+SET(CARES_NAMES ${CARES_NAMES} cares)
+FIND_LIBRARY(CARES_LIBRARY
+ NAMES ${CARES_NAMES}
+ PATHS /usr/lib /usr/local/lib
+ )
+
+IF (CARES_LIBRARY AND CARES_INCLUDE_DIR)
+ SET(CARES_LIBRARIES ${CARES_LIBRARY})
+ SET(CARES_FOUND "YES")
+ELSE (CARES_LIBRARY AND CARES_INCLUDE_DIR)
+ SET(CARES_FOUND "NO")
+ENDIF (CARES_LIBRARY AND CARES_INCLUDE_DIR)
+
+
+IF (CARES_FOUND)
+ IF (NOT CARES_FIND_QUIETLY)
+ MESSAGE(STATUS "Found c-ares: ${CARES_LIBRARIES}")
+ ENDIF (NOT CARES_FIND_QUIETLY)
+ELSE (CARES_FOUND)
+ IF (CARES_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Could not find c-ares library")
+ ENDIF (CARES_FIND_REQUIRED)
+ENDIF (CARES_FOUND)
+
+MARK_AS_ADVANCED(
+ CARES_LIBRARY
+ CARES_INCLUDE_DIR
+ )
diff --git a/Utilities/cmcurl/CMake/FindGSS.cmake b/Utilities/cmcurl/CMake/FindGSS.cmake
new file mode 100644
index 000000000..dfaeaf307
--- /dev/null
+++ b/Utilities/cmcurl/CMake/FindGSS.cmake
@@ -0,0 +1,289 @@
+# - Try to find the GSS Kerberos library
+# Once done this will define
+#
+# GSS_ROOT_DIR - Set this variable to the root installation of GSS
+#
+# Read-Only variables:
+# GSS_FOUND - system has the Heimdal library
+# GSS_FLAVOUR - "MIT" or "Heimdal" if anything found.
+# GSS_INCLUDE_DIR - the Heimdal include directory
+# GSS_LIBRARIES - The libraries needed to use GSS
+# GSS_LINK_DIRECTORIES - Directories to add to linker search path
+# GSS_LINKER_FLAGS - Additional linker flags
+# GSS_COMPILER_FLAGS - Additional compiler flags
+# GSS_VERSION - This is set to version advertised by pkg-config or read from manifest.
+# In case the library is found but no version info availabe it'll be set to "unknown"
+
+set(_MIT_MODNAME mit-krb5-gssapi)
+set(_HEIMDAL_MODNAME heimdal-gssapi)
+
+include(CheckIncludeFile)
+include(CheckIncludeFiles)
+include(CheckTypeSize)
+
+set(_GSS_ROOT_HINTS
+ "${GSS_ROOT_DIR}"
+ "$ENV{GSS_ROOT_DIR}"
+)
+
+# try to find library using system pkg-config if user didn't specify root dir
+if(NOT GSS_ROOT_DIR AND NOT "$ENV{GSS_ROOT_DIR}")
+ if(UNIX)
+ find_package(PkgConfig QUIET)
+ pkg_search_module(_GSS_PKG ${_MIT_MODNAME} ${_HEIMDAL_MODNAME})
+ list(APPEND _GSS_ROOT_HINTS "${_GSS_PKG_PREFIX}")
+ elseif(WIN32)
+ list(APPEND _GSS_ROOT_HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos;InstallDir]")
+ endif()
+endif()
+
+if(NOT _GSS_FOUND) #not found by pkg-config. Let's take more traditional approach.
+ find_file(_GSS_CONFIGURE_SCRIPT
+ NAMES
+ "krb5-config"
+ HINTS
+ ${_GSS_ROOT_HINTS}
+ PATH_SUFFIXES
+ bin
+ NO_CMAKE_PATH
+ NO_CMAKE_ENVIRONMENT_PATH
+ )
+
+ # if not found in user-supplied directories, maybe system knows better
+ find_file(_GSS_CONFIGURE_SCRIPT
+ NAMES
+ "krb5-config"
+ PATH_SUFFIXES
+ bin
+ )
+
+ if(_GSS_CONFIGURE_SCRIPT)
+ execute_process(
+ COMMAND ${_GSS_CONFIGURE_SCRIPT} "--cflags" "gssapi"
+ OUTPUT_VARIABLE _GSS_CFLAGS
+ RESULT_VARIABLE _GSS_CONFIGURE_FAILED
+ )
+message(STATUS "CFLAGS: ${_GSS_CFLAGS}")
+ if(NOT _GSS_CONFIGURE_FAILED) # 0 means success
+ # should also work in an odd case when multiple directories are given
+ string(STRIP "${_GSS_CFLAGS}" _GSS_CFLAGS)
+ string(REGEX REPLACE " +-I" ";" _GSS_CFLAGS "${_GSS_CFLAGS}")
+ string(REGEX REPLACE " +-([^I][^ \\t;]*)" ";-\\1"_GSS_CFLAGS "${_GSS_CFLAGS}")
+
+ foreach(_flag ${_GSS_CFLAGS})
+ if(_flag MATCHES "^-I.*")
+ string(REGEX REPLACE "^-I" "" _val "${_flag}")
+ list(APPEND _GSS_INCLUDE_DIR "${_val}")
+ else()
+ list(APPEND _GSS_COMPILER_FLAGS "${_flag}")
+ endif()
+ endforeach()
+ endif()
+
+ execute_process(
+ COMMAND ${_GSS_CONFIGURE_SCRIPT} "--libs" "gssapi"
+ OUTPUT_VARIABLE _GSS_LIB_FLAGS
+ RESULT_VARIABLE _GSS_CONFIGURE_FAILED
+ )
+message(STATUS "LDFLAGS: ${_GSS_LIB_FLAGS}")
+ if(NOT _GSS_CONFIGURE_FAILED) # 0 means success
+ # this script gives us libraries and link directories. Blah. We have to deal with it.
+ string(STRIP "${_GSS_LIB_FLAGS}" _GSS_LIB_FLAGS)
+ string(REGEX REPLACE " +-(L|l)" ";-\\1" _GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
+ string(REGEX REPLACE " +-([^Ll][^ \\t;]*)" ";-\\1"_GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
+
+ foreach(_flag ${_GSS_LIB_FLAGS})
+ if(_flag MATCHES "^-l.*")
+ string(REGEX REPLACE "^-l" "" _val "${_flag}")
+ list(APPEND _GSS_LIBRARIES "${_val}")
+ elseif(_flag MATCHES "^-L.*")
+ string(REGEX REPLACE "^-L" "" _val "${_flag}")
+ list(APPEND _GSS_LINK_DIRECTORIES "${_val}")
+ else()
+ list(APPEND _GSS_LINKER_FLAGS "${_flag}")
+ endif()
+ endforeach()
+ endif()
+
+
+ execute_process(
+ COMMAND ${_GSS_CONFIGURE_SCRIPT} "--version"
+ OUTPUT_VARIABLE _GSS_VERSION
+ RESULT_VARIABLE _GSS_CONFIGURE_FAILED
+ )
+
+ # older versions may not have the "--version" parameter. In this case we just don't care.
+ if(_GSS_CONFIGURE_FAILED)
+ set(_GSS_VERSION 0)
+ endif()
+
+
+ execute_process(
+ COMMAND ${_GSS_CONFIGURE_SCRIPT} "--vendor"
+ OUTPUT_VARIABLE _GSS_VENDOR
+ RESULT_VARIABLE _GSS_CONFIGURE_FAILED
+ )
+
+ # older versions may not have the "--vendor" parameter. In this case we just don't care.
+ if(_GSS_CONFIGURE_FAILED)
+ set(GSS_FLAVOUR "Heimdal") # most probably, shouldn't really matter
+ else()
+ if(_GSS_VENDOR MATCHES ".*H|heimdal.*")
+ set(GSS_FLAVOUR "Heimdal")
+ else()
+ set(GSS_FLAVOUR "MIT")
+ endif()
+ endif()
+
+ else() # either there is no config script or we are on platform that doesn't provide one (Windows?)
+
+ find_path(_GSS_INCLUDE_DIR
+ NAMES
+ "gssapi/gssapi.h"
+ HINTS
+ ${_GSS_ROOT_HINTS}
+ PATH_SUFFIXES
+ include
+ inc
+ )
+
+ if(_GSS_INCLUDE_DIR) #jay, we've found something
+ set(CMAKE_REQUIRED_INCLUDES "${_GSS_INCLUDE_DIR}")
+ check_include_files( "gssapi/gssapi_generic.h;gssapi/gssapi_krb5.h" _GSS_HAVE_MIT_HEADERS)
+
+ if(_GSS_HAVE_MIT_HEADERS)
+ set(GSS_FLAVOUR "MIT")
+ else()
+ # prevent compiling the header - just check if we can include it
+ set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D__ROKEN_H__")
+ check_include_file( "roken.h" _GSS_HAVE_ROKEN_H)
+
+ check_include_file( "heimdal/roken.h" _GSS_HAVE_HEIMDAL_ROKEN_H)
+ if(_GSS_HAVE_ROKEN_H OR _GSS_HAVE_HEIMDAL_ROKEN_H)
+ set(GSS_FLAVOUR "Heimdal")
+ endif()
+ set(CMAKE_REQUIRED_DEFINITIONS "")
+ endif()
+ else()
+ # I'm not convienced if this is the right way but this is what autotools do at the moment
+ find_path(_GSS_INCLUDE_DIR
+ NAMES
+ "gssapi.h"
+ HINTS
+ ${_GSS_ROOT_HINTS}
+ PATH_SUFFIXES
+ include
+ inc
+ )
+
+ if(_GSS_INCLUDE_DIR)
+ set(GSS_FLAVOUR "Heimdal")
+ endif()
+ endif()
+
+ # if we have headers, check if we can link libraries
+ if(GSS_FLAVOUR)
+ set(_GSS_LIBDIR_SUFFIXES "")
+ set(_GSS_LIBDIR_HINTS ${_GSS_ROOT_HINTS})
+ get_filename_component(_GSS_CALCULATED_POTENTIAL_ROOT "${_GSS_INCLUDE_DIR}" PATH)
+ list(APPEND _GSS_LIBDIR_HINTS ${_GSS_CALCULATED_POTENTIAL_ROOT})
+
+ if(WIN32)
+ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ list(APPEND _GSS_LIBDIR_SUFFIXES "lib/AMD64")
+ if(GSS_FLAVOUR STREQUAL "MIT")
+ set(_GSS_LIBNAME "gssapi64")
+ else()
+ set(_GSS_LIBNAME "libgssapi")
+ endif()
+ else()
+ list(APPEND _GSS_LIBDIR_SUFFIXES "lib/i386")
+ if(GSS_FLAVOUR STREQUAL "MIT")
+ set(_GSS_LIBNAME "gssapi32")
+ else()
+ set(_GSS_LIBNAME "libgssapi")
+ endif()
+ endif()
+ else()
+ list(APPEND _GSS_LIBDIR_SUFFIXES "lib;lib64") # those suffixes are not checked for HINTS
+ if(GSS_FLAVOUR STREQUAL "MIT")
+ set(_GSS_LIBNAME "gssapi_krb5")
+ else()
+ set(_GSS_LIBNAME "gssapi")
+ endif()
+ endif()
+
+ find_library(_GSS_LIBRARIES
+ NAMES
+ ${_GSS_LIBNAME}
+ HINTS
+ ${_GSS_LIBDIR_HINTS}
+ PATH_SUFFIXES
+ ${_GSS_LIBDIR_SUFFIXES}
+ )
+
+ endif()
+
+ endif()
+else()
+ if(_GSS_PKG_${_MIT_MODNAME}_VERSION)
+ set(GSS_FLAVOUR "MIT")
+ set(_GSS_VERSION _GSS_PKG_${_MIT_MODNAME}_VERSION)
+ else()
+ set(GSS_FLAVOUR "Heimdal")
+ set(_GSS_VERSION _GSS_PKG_${_MIT_HEIMDAL}_VERSION)
+ endif()
+endif()
+
+set(GSS_INCLUDE_DIR ${_GSS_INCLUDE_DIR})
+set(GSS_LIBRARIES ${_GSS_LIBRARIES})
+set(GSS_LINK_DIRECTORIES ${_GSS_LINK_DIRECTORIES})
+set(GSS_LINKER_FLAGS ${_GSS_LINKER_FLAGS})
+set(GSS_COMPILER_FLAGS ${_GSS_COMPILER_FLAGS})
+set(GSS_VERSION ${_GSS_VERSION})
+
+if(GSS_FLAVOUR)
+
+ if(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "Heimdal")
+ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.amd64.manifest")
+ else()
+ set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.x86.manifest")
+ endif()
+
+ if(EXISTS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}")
+ file(STRINGS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}" heimdal_version_str
+ REGEX "^.*version=\"[0-9]\\.[^\"]+\".*$")
+
+ string(REGEX MATCH "[0-9]\\.[^\"]+"
+ GSS_VERSION "${heimdal_version_str}")
+ endif()
+
+ if(NOT GSS_VERSION)
+ set(GSS_VERSION "Heimdal Unknown")
+ endif()
+ elseif(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "MIT")
+ get_filename_component(_MIT_VERSION "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos\\SDK\\CurrentVersion;VersionString]" NAME CACHE)
+ if(WIN32 AND _MIT_VERSION)
+ set(GSS_VERSION "${_MIT_VERSION}")
+ else()
+ set(GSS_VERSION "MIT Unknown")
+ endif()
+ endif()
+endif()
+
+
+include(FindPackageHandleStandardArgs)
+
+set(_GSS_REQUIRED_VARS GSS_LIBRARIES GSS_FLAVOUR)
+
+find_package_handle_standard_args(GSS
+ REQUIRED_VARS
+ ${_GSS_REQUIRED_VARS}
+ VERSION_VAR
+ GSS_VERSION
+ FAIL_MESSAGE
+ "Could NOT find GSS, try to set the path to GSS root folder in the system variable GSS_ROOT_DIR"
+)
+
+mark_as_advanced(GSS_INCLUDE_DIR GSS_LIBRARIES)
diff --git a/Utilities/cmcurl/CMake/FindLibSSH2.cmake b/Utilities/cmcurl/CMake/FindLibSSH2.cmake
new file mode 100644
index 000000000..12a7c612b
--- /dev/null
+++ b/Utilities/cmcurl/CMake/FindLibSSH2.cmake
@@ -0,0 +1,35 @@
+# - Try to find the libssh2 library
+# Once done this will define
+#
+# LIBSSH2_FOUND - system has the libssh2 library
+# LIBSSH2_INCLUDE_DIR - the libssh2 include directory
+# LIBSSH2_LIBRARY - the libssh2 library name
+
+if (LIBSSH2_INCLUDE_DIR AND LIBSSH2_LIBRARY)
+ set(LibSSH2_FIND_QUIETLY TRUE)
+endif (LIBSSH2_INCLUDE_DIR AND LIBSSH2_LIBRARY)
+
+FIND_PATH(LIBSSH2_INCLUDE_DIR libssh2.h
+)
+
+FIND_LIBRARY(LIBSSH2_LIBRARY NAMES ssh2
+)
+
+if(LIBSSH2_INCLUDE_DIR)
+ file(STRINGS "${LIBSSH2_INCLUDE_DIR}/libssh2.h" libssh2_version_str REGEX "^#define[\t ]+LIBSSH2_VERSION_NUM[\t ]+0x[0-9][0-9][0-9][0-9][0-9][0-9].*")
+
+ string(REGEX REPLACE "^.*LIBSSH2_VERSION_NUM[\t ]+0x([0-9][0-9]).*$" "\\1" LIBSSH2_VERSION_MAJOR "${libssh2_version_str}")
+ string(REGEX REPLACE "^.*LIBSSH2_VERSION_NUM[\t ]+0x[0-9][0-9]([0-9][0-9]).*$" "\\1" LIBSSH2_VERSION_MINOR "${libssh2_version_str}")
+ string(REGEX REPLACE "^.*LIBSSH2_VERSION_NUM[\t ]+0x[0-9][0-9][0-9][0-9]([0-9][0-9]).*$" "\\1" LIBSSH2_VERSION_PATCH "${libssh2_version_str}")
+
+ string(REGEX REPLACE "^0(.+)" "\\1" LIBSSH2_VERSION_MAJOR "${LIBSSH2_VERSION_MAJOR}")
+ string(REGEX REPLACE "^0(.+)" "\\1" LIBSSH2_VERSION_MINOR "${LIBSSH2_VERSION_MINOR}")
+ string(REGEX REPLACE "^0(.+)" "\\1" LIBSSH2_VERSION_PATCH "${LIBSSH2_VERSION_PATCH}")
+
+ set(LIBSSH2_VERSION "${LIBSSH2_VERSION_MAJOR}.${LIBSSH2_VERSION_MINOR}.${LIBSSH2_VERSION_PATCH}")
+endif(LIBSSH2_INCLUDE_DIR)
+
+include(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibSSH2 DEFAULT_MSG LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY )
+
+MARK_AS_ADVANCED(LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY LIBSSH2_VERSION_MAJOR LIBSSH2_VERSION_MINOR LIBSSH2_VERSION_PATCH LIBSSH2_VERSION)
diff --git a/Utilities/cmcurl/CMake/Macros.cmake b/Utilities/cmcurl/CMake/Macros.cmake
new file mode 100644
index 000000000..dab005f73
--- /dev/null
+++ b/Utilities/cmcurl/CMake/Macros.cmake
@@ -0,0 +1,95 @@
+#File defines convenience macros for available feature testing
+
+# This macro checks if the symbol exists in the library and if it
+# does, it prepends library to the list. It is intended to be called
+# multiple times with a sequence of possibly dependent libraries in
+# order of least-to-most-dependent. Some libraries depend on others
+# to link correctly.
+macro(CHECK_LIBRARY_EXISTS_CONCAT LIBRARY SYMBOL VARIABLE)
+ check_library_exists("${LIBRARY};${CURL_LIBS}" ${SYMBOL} "${CMAKE_LIBRARY_PATH}"
+ ${VARIABLE})
+ if(${VARIABLE})
+ set(CURL_LIBS ${LIBRARY} ${CURL_LIBS})
+ endif(${VARIABLE})
+endmacro(CHECK_LIBRARY_EXISTS_CONCAT)
+
+# Check if header file exists and add it to the list.
+# This macro is intended to be called multiple times with a sequence of
+# possibly dependent header files. Some headers depend on others to be
+# compiled correctly.
+macro(CHECK_INCLUDE_FILE_CONCAT FILE VARIABLE)
+ check_include_files("${CURL_INCLUDES};${FILE}" ${VARIABLE})
+ if(${VARIABLE})
+ set(CURL_INCLUDES ${CURL_INCLUDES} ${FILE})
+ set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D${VARIABLE}")
+ endif(${VARIABLE})
+endmacro(CHECK_INCLUDE_FILE_CONCAT)
+
+# For other curl specific tests, use this macro.
+macro(CURL_INTERNAL_TEST CURL_TEST)
+ if(NOT DEFINED "${CURL_TEST}")
+ set(MACRO_CHECK_FUNCTION_DEFINITIONS
+ "-D${CURL_TEST} ${CURL_TEST_DEFINES} ${CMAKE_REQUIRED_FLAGS}")
+ if(CMAKE_REQUIRED_LIBRARIES)
+ set(CURL_TEST_ADD_LIBRARIES
+ "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
+ endif(CMAKE_REQUIRED_LIBRARIES)
+
+ message(STATUS "Performing Curl Test ${CURL_TEST}")
+ try_compile(${CURL_TEST}
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/CMake/CurlTests.c
+ CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
+ "${CURL_TEST_ADD_LIBRARIES}"
+ OUTPUT_VARIABLE OUTPUT)
+ if(${CURL_TEST})
+ set(${CURL_TEST} 1 CACHE INTERNAL "Curl test ${FUNCTION}")
+ message(STATUS "Performing Curl Test ${CURL_TEST} - Success")
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Performing Curl Test ${CURL_TEST} passed with the following output:\n"
+ "${OUTPUT}\n")
+ else(${CURL_TEST})
+ message(STATUS "Performing Curl Test ${CURL_TEST} - Failed")
+ set(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}")
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Performing Curl Test ${CURL_TEST} failed with the following output:\n"
+ "${OUTPUT}\n")
+ endif(${CURL_TEST})
+ endif()
+endmacro(CURL_INTERNAL_TEST)
+
+macro(CURL_INTERNAL_TEST_RUN CURL_TEST)
+ if(NOT DEFINED "${CURL_TEST}_COMPILE")
+ set(MACRO_CHECK_FUNCTION_DEFINITIONS
+ "-D${CURL_TEST} ${CMAKE_REQUIRED_FLAGS}")
+ if(CMAKE_REQUIRED_LIBRARIES)
+ set(CURL_TEST_ADD_LIBRARIES
+ "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
+ endif(CMAKE_REQUIRED_LIBRARIES)
+
+ message(STATUS "Performing Curl Test ${CURL_TEST}")
+ try_run(${CURL_TEST} ${CURL_TEST}_COMPILE
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/CMake/CurlTests.c
+ CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
+ "${CURL_TEST_ADD_LIBRARIES}"
+ OUTPUT_VARIABLE OUTPUT)
+ if(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
+ set(${CURL_TEST} 1 CACHE INTERNAL "Curl test ${FUNCTION}")
+ message(STATUS "Performing Curl Test ${CURL_TEST} - Success")
+ else(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
+ message(STATUS "Performing Curl Test ${CURL_TEST} - Failed")
+ set(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}")
+ file(APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
+ "Performing Curl Test ${CURL_TEST} failed with the following output:\n"
+ "${OUTPUT}")
+ if(${CURL_TEST}_COMPILE)
+ file(APPEND
+ "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
+ "There was a problem running this test\n")
+ endif(${CURL_TEST}_COMPILE)
+ file(APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
+ "\n\n")
+ endif(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
+ endif()
+endmacro(CURL_INTERNAL_TEST_RUN)
diff --git a/Utilities/cmcurl/CMake/OtherTests.cmake b/Utilities/cmcurl/CMake/OtherTests.cmake
index 7d2c66fa1..4f07f2251 100644
--- a/Utilities/cmcurl/CMake/OtherTests.cmake
+++ b/Utilities/cmcurl/CMake/OtherTests.cmake
@@ -1,242 +1,229 @@
-INCLUDE(CurlCheckCSourceCompiles)
-SET(EXTRA_DEFINES "__unused1\n#undef inline\n#define __unused2")
-SET(HEADER_INCLUDES)
-SET(headers_hack)
+include(CheckCSourceCompiles)
+# The begin of the sources (macros and includes)
+set(_source_epilogue "#undef inline")
-MACRO(add_header_include check header)
- IF(${check})
- SET(headers_hack
- "${headers_hack}\n#include <${header}>")
- #SET(HEADER_INCLUDES
- # ${HEADER_INCLUDES}
- # "${header}")
- ENDIF(${check})
-ENDMACRO(add_header_include)
+macro(add_header_include check header)
+ if(${check})
+ set(_source_epilogue "${_source_epilogue}\n#include <${header}>")
+ endif(${check})
+endmacro(add_header_include)
-SET(signature_call_conv)
-IF(HAVE_WINDOWS_H)
+set(signature_call_conv)
+if(HAVE_WINDOWS_H)
add_header_include(HAVE_WINDOWS_H "windows.h")
add_header_include(HAVE_WINSOCK2_H "winsock2.h")
add_header_include(HAVE_WINSOCK_H "winsock.h")
- SET(EXTRA_DEFINES ${EXTRA_DEFINES}
- "__unused7\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif\n#define __unused3")
- SET(signature_call_conv "PASCAL")
-ELSE(HAVE_WINDOWS_H)
+ set(_source_epilogue
+ "${_source_epilogue}\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif")
+ set(signature_call_conv "PASCAL")
+ if(HAVE_LIBWS2_32)
+ set(CMAKE_REQUIRED_LIBRARIES ws2_32)
+ endif()
+else(HAVE_WINDOWS_H)
add_header_include(HAVE_SYS_TYPES_H "sys/types.h")
add_header_include(HAVE_SYS_SOCKET_H "sys/socket.h")
-ENDIF(HAVE_WINDOWS_H)
+endif(HAVE_WINDOWS_H)
-SET(EXTRA_DEFINES_BACKUP "${EXTRA_DEFINES}")
-SET(EXTRA_DEFINES "${EXTRA_DEFINES_BACKUP}\n${headers_hack}\n${extern_line}\n#define __unused5")
-CURL_CHECK_C_SOURCE_COMPILES("recv(0, 0, 0, 0)" curl_cv_recv)
-IF(curl_cv_recv)
- # AC_CACHE_CHECK([types of arguments and return type for recv],
- #[curl_cv_func_recv_args], [
- #SET(curl_cv_func_recv_args "unknown")
- #for recv_retv in 'int' 'ssize_t'; do
- IF(NOT DEFINED curl_cv_func_recv_args OR "${curl_cv_func_recv_args}" STREQUAL "unknown")
- FOREACH(recv_retv "int" "ssize_t" )
- FOREACH(recv_arg1 "int" "ssize_t" "SOCKET")
- FOREACH(recv_arg2 "void *" "char *")
- FOREACH(recv_arg3 "size_t" "int" "socklen_t" "unsigned int")
- FOREACH(recv_arg4 "int" "unsigned int")
- IF(NOT curl_cv_func_recv_done)
- SET(curl_cv_func_recv_test "UNKNOWN")
- SET(extern_line "extern ${recv_retv} ${signature_call_conv} recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4})\;")
- SET(EXTRA_DEFINES "${EXTRA_DEFINES_BACKUP}\n${headers_hack}\n${extern_line}\n#define __unused5")
- CURL_CHECK_C_SOURCE_COMPILES("
+check_c_source_compiles("${_source_epilogue}
+int main(void) {
+ recv(0, 0, 0, 0);
+ return 0;
+}" curl_cv_recv)
+if(curl_cv_recv)
+ if(NOT DEFINED curl_cv_func_recv_args OR "${curl_cv_func_recv_args}" STREQUAL "unknown")
+ foreach(recv_retv "int" "ssize_t" )
+ foreach(recv_arg1 "int" "ssize_t" "SOCKET")
+ foreach(recv_arg2 "void *" "char *")
+ foreach(recv_arg3 "size_t" "int" "socklen_t" "unsigned int")
+ foreach(recv_arg4 "int" "unsigned int")
+ if(NOT curl_cv_func_recv_done)
+ unset(curl_cv_func_recv_test CACHE)
+ check_c_source_compiles("
+ ${_source_epilogue}
+ extern ${recv_retv} ${signature_call_conv}
+ recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4});
+ int main(void) {
${recv_arg1} s=0;
${recv_arg2} buf=0;
${recv_arg3} len=0;
${recv_arg4} flags=0;
- ${recv_retv} res = recv(s, buf, len, flags)"
- curl_cv_func_recv_test
- "${recv_retv} recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4})")
- IF(curl_cv_func_recv_test)
- SET(curl_cv_func_recv_args
+ ${recv_retv} res = recv(s, buf, len, flags);
+ (void) res;
+ return 0;
+ }"
+ curl_cv_func_recv_test)
+ message(STATUS
+ "Tested: ${recv_retv} recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4})")
+ if(curl_cv_func_recv_test)
+ set(curl_cv_func_recv_args
"${recv_arg1},${recv_arg2},${recv_arg3},${recv_arg4},${recv_retv}")
- SET(RECV_TYPE_ARG1 "${recv_arg1}")
- SET(RECV_TYPE_ARG2 "${recv_arg2}")
- SET(RECV_TYPE_ARG3 "${recv_arg3}")
- SET(RECV_TYPE_ARG4 "${recv_arg4}")
- SET(RECV_TYPE_RETV "${recv_retv}")
- SET(HAVE_RECV 1)
- SET(curl_cv_func_recv_done 1)
- ENDIF(curl_cv_func_recv_test)
- ENDIF(NOT curl_cv_func_recv_done)
- ENDFOREACH(recv_arg4)
- ENDFOREACH(recv_arg3)
- ENDFOREACH(recv_arg2)
- ENDFOREACH(recv_arg1)
- ENDFOREACH(recv_retv)
- ELSE(NOT DEFINED curl_cv_func_recv_args OR "${curl_cv_func_recv_args}" STREQUAL "unknown")
- STRING(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG1 "${curl_cv_func_recv_args}")
- STRING(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG2 "${curl_cv_func_recv_args}")
- STRING(REGEX REPLACE "^[^,]*,[^,]*,([^,]*),[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG3 "${curl_cv_func_recv_args}")
- STRING(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,([^,]*),[^,]*$" "\\1" RECV_TYPE_ARG4 "${curl_cv_func_recv_args}")
- STRING(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,([^,]*)$" "\\1" RECV_TYPE_RETV "${curl_cv_func_recv_args}")
- #MESSAGE("RECV_TYPE_ARG1 ${RECV_TYPE_ARG1}")
- #MESSAGE("RECV_TYPE_ARG2 ${RECV_TYPE_ARG2}")
- #MESSAGE("RECV_TYPE_ARG3 ${RECV_TYPE_ARG3}")
- #MESSAGE("RECV_TYPE_ARG4 ${RECV_TYPE_ARG4}")
- #MESSAGE("RECV_TYPE_RETV ${RECV_TYPE_RETV}")
- ENDIF(NOT DEFINED curl_cv_func_recv_args OR "${curl_cv_func_recv_args}" STREQUAL "unknown")
-
- IF("${curl_cv_func_recv_args}" STREQUAL "unknown")
- MESSAGE(FATAL_ERROR "Cannot find proper types to use for recv args")
- ENDIF("${curl_cv_func_recv_args}" STREQUAL "unknown")
-ELSE(curl_cv_recv)
- MESSAGE(FATAL_ERROR "Unable to link function recv")
-ENDIF(curl_cv_recv)
-SET(curl_cv_func_recv_args "${curl_cv_func_recv_args}" CACHE INTERNAL "Arguments for recv")
-SET(HAVE_RECV 1)
+ set(RECV_TYPE_ARG1 "${recv_arg1}")
+ set(RECV_TYPE_ARG2 "${recv_arg2}")
+ set(RECV_TYPE_ARG3 "${recv_arg3}")
+ set(RECV_TYPE_ARG4 "${recv_arg4}")
+ set(RECV_TYPE_RETV "${recv_retv}")
+ set(HAVE_RECV 1)
+ set(curl_cv_func_recv_done 1)
+ endif(curl_cv_func_recv_test)
+ endif(NOT curl_cv_func_recv_done)
+ endforeach(recv_arg4)
+ endforeach(recv_arg3)
+ endforeach(recv_arg2)
+ endforeach(recv_arg1)
+ endforeach(recv_retv)
+ else()
+ string(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG1 "${curl_cv_func_recv_args}")
+ string(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG2 "${curl_cv_func_recv_args}")
+ string(REGEX REPLACE "^[^,]*,[^,]*,([^,]*),[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG3 "${curl_cv_func_recv_args}")
+ string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,([^,]*),[^,]*$" "\\1" RECV_TYPE_ARG4 "${curl_cv_func_recv_args}")
+ string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,([^,]*)$" "\\1" RECV_TYPE_RETV "${curl_cv_func_recv_args}")
+ endif()
-CURL_CHECK_C_SOURCE_COMPILES("send(0, 0, 0, 0)" curl_cv_send)
-IF(curl_cv_send)
- # AC_CACHE_CHECK([types of arguments and return type for send],
- #[curl_cv_func_send_args], [
- #SET(curl_cv_func_send_args "unknown")
- #for send_retv in 'int' 'ssize_t'; do
- IF(NOT DEFINED curl_cv_func_send_args OR "${curl_cv_func_send_args}" STREQUAL "unknown")
- FOREACH(send_retv "int" "ssize_t" )
- FOREACH(send_arg1 "int" "ssize_t" "SOCKET")
- FOREACH(send_arg2 "const void *" "void *" "char *" "const char *")
- FOREACH(send_arg3 "size_t" "int" "socklen_t" "unsigned int")
- FOREACH(send_arg4 "int" "unsigned int")
- IF(NOT curl_cv_func_send_done)
- SET(curl_cv_func_send_test "UNKNOWN")
- SET(extern_line "extern ${send_retv} ${signature_call_conv} send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4})\;")
- SET(EXTRA_DEFINES "${EXTRA_DEFINES_BACKUP}\n${headers_hack}\n${extern_line}\n#define __unused5")
- CURL_CHECK_C_SOURCE_COMPILES("
+ if("${curl_cv_func_recv_args}" STREQUAL "unknown")
+ message(FATAL_ERROR "Cannot find proper types to use for recv args")
+ endif("${curl_cv_func_recv_args}" STREQUAL "unknown")
+else(curl_cv_recv)
+ message(FATAL_ERROR "Unable to link function recv")
+endif(curl_cv_recv)
+set(curl_cv_func_recv_args "${curl_cv_func_recv_args}" CACHE INTERNAL "Arguments for recv")
+set(HAVE_RECV 1)
+
+check_c_source_compiles("${_source_epilogue}
+int main(void) {
+ send(0, 0, 0, 0);
+ return 0;
+}" curl_cv_send)
+if(curl_cv_send)
+ if(NOT DEFINED curl_cv_func_send_args OR "${curl_cv_func_send_args}" STREQUAL "unknown")
+ foreach(send_retv "int" "ssize_t" )
+ foreach(send_arg1 "int" "ssize_t" "SOCKET")
+ foreach(send_arg2 "const void *" "void *" "char *" "const char *")
+ foreach(send_arg3 "size_t" "int" "socklen_t" "unsigned int")
+ foreach(send_arg4 "int" "unsigned int")
+ if(NOT curl_cv_func_send_done)
+ unset(curl_cv_func_send_test CACHE)
+ check_c_source_compiles("
+ ${_source_epilogue}
+ extern ${send_retv} ${signature_call_conv}
+ send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4});
+ int main(void) {
${send_arg1} s=0;
${send_arg2} buf=0;
${send_arg3} len=0;
${send_arg4} flags=0;
- ${send_retv} res = send(s, buf, len, flags)"
- curl_cv_func_send_test
- "${send_retv} send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4})")
- IF(curl_cv_func_send_test)
- #MESSAGE("Found arguments: ${curl_cv_func_send_test}")
- STRING(REGEX REPLACE "(const) .*" "\\1" send_qual_arg2 "${send_arg2}")
- STRING(REGEX REPLACE "const (.*)" "\\1" send_arg2 "${send_arg2}")
- SET(curl_cv_func_send_args
+ ${send_retv} res = send(s, buf, len, flags);
+ (void) res;
+ return 0;
+ }"
+ curl_cv_func_send_test)
+ message(STATUS
+ "Tested: ${send_retv} send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4})")
+ if(curl_cv_func_send_test)
+ string(REGEX REPLACE "(const) .*" "\\1" send_qual_arg2 "${send_arg2}")
+ string(REGEX REPLACE "const (.*)" "\\1" send_arg2 "${send_arg2}")
+ set(curl_cv_func_send_args
"${send_arg1},${send_arg2},${send_arg3},${send_arg4},${send_retv},${send_qual_arg2}")
- SET(SEND_TYPE_ARG1 "${send_arg1}")
- SET(SEND_TYPE_ARG2 "${send_arg2}")
- SET(SEND_TYPE_ARG3 "${send_arg3}")
- SET(SEND_TYPE_ARG4 "${send_arg4}")
- SET(SEND_TYPE_RETV "${send_retv}")
- SET(HAVE_SEND 1)
- SET(curl_cv_func_send_done 1)
- ENDIF(curl_cv_func_send_test)
- ENDIF(NOT curl_cv_func_send_done)
- ENDFOREACH(send_arg4)
- ENDFOREACH(send_arg3)
- ENDFOREACH(send_arg2)
- ENDFOREACH(send_arg1)
- ENDFOREACH(send_retv)
- ELSE(NOT DEFINED curl_cv_func_send_args OR "${curl_cv_func_send_args}" STREQUAL "unknown")
- STRING(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG1 "${curl_cv_func_send_args}")
- STRING(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG2 "${curl_cv_func_send_args}")
- STRING(REGEX REPLACE "^[^,]*,[^,]*,([^,]*),[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG3 "${curl_cv_func_send_args}")
- STRING(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,([^,]*),[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG4 "${curl_cv_func_send_args}")
- STRING(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,([^,]*),[^,]*$" "\\1" SEND_TYPE_RETV "${curl_cv_func_send_args}")
- STRING(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,([^,]*)$" "\\1" SEND_QUAL_ARG2 "${curl_cv_func_send_args}")
- #MESSAGE("SEND_TYPE_ARG1 ${SEND_TYPE_ARG1}")
- #MESSAGE("SEND_TYPE_ARG2 ${SEND_TYPE_ARG2}")
- #MESSAGE("SEND_TYPE_ARG3 ${SEND_TYPE_ARG3}")
- #MESSAGE("SEND_TYPE_ARG4 ${SEND_TYPE_ARG4}")
- #MESSAGE("SEND_TYPE_RETV ${SEND_TYPE_RETV}")
- #MESSAGE("SEND_QUAL_ARG2 ${SEND_QUAL_ARG2}")
- ENDIF(NOT DEFINED curl_cv_func_send_args OR "${curl_cv_func_send_args}" STREQUAL "unknown")
-
- IF("${curl_cv_func_send_args}" STREQUAL "unknown")
- MESSAGE(FATAL_ERROR "Cannot find proper types to use for send args")
- ENDIF("${curl_cv_func_send_args}" STREQUAL "unknown")
- SET(SEND_QUAL_ARG2 "const")
-ELSE(curl_cv_send)
- MESSAGE(FATAL_ERROR "Unable to link function send")
-ENDIF(curl_cv_send)
-SET(curl_cv_func_send_args "${curl_cv_func_send_args}" CACHE INTERNAL "Arguments for send")
-SET(HAVE_SEND 1)
-
-SET(EXTRA_DEFINES "${EXTRA_DEFINES}\n${headers_hack}\n#define __unused5")
-CURL_CHECK_C_SOURCE_COMPILES("int flag = MSG_NOSIGNAL" HAVE_MSG_NOSIGNAL)
+ set(SEND_TYPE_ARG1 "${send_arg1}")
+ set(SEND_TYPE_ARG2 "${send_arg2}")
+ set(SEND_TYPE_ARG3 "${send_arg3}")
+ set(SEND_TYPE_ARG4 "${send_arg4}")
+ set(SEND_TYPE_RETV "${send_retv}")
+ set(HAVE_SEND 1)
+ set(curl_cv_func_send_done 1)
+ endif(curl_cv_func_send_test)
+ endif(NOT curl_cv_func_send_done)
+ endforeach(send_arg4)
+ endforeach(send_arg3)
+ endforeach(send_arg2)
+ endforeach(send_arg1)
+ endforeach(send_retv)
+ else()
+ string(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG1 "${curl_cv_func_send_args}")
+ string(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG2 "${curl_cv_func_send_args}")
+ string(REGEX REPLACE "^[^,]*,[^,]*,([^,]*),[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG3 "${curl_cv_func_send_args}")
+ string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,([^,]*),[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG4 "${curl_cv_func_send_args}")
+ string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,([^,]*),[^,]*$" "\\1" SEND_TYPE_RETV "${curl_cv_func_send_args}")
+ string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,([^,]*)$" "\\1" SEND_QUAL_ARG2 "${curl_cv_func_send_args}")
+ endif()
-SET(EXTRA_DEFINES "__unused1\n#undef inline\n#define __unused2")
-SET(HEADER_INCLUDES)
-SET(headers_hack)
+ if("${curl_cv_func_send_args}" STREQUAL "unknown")
+ message(FATAL_ERROR "Cannot find proper types to use for send args")
+ endif("${curl_cv_func_send_args}" STREQUAL "unknown")
+ set(SEND_QUAL_ARG2 "const")
+else(curl_cv_send)
+ message(FATAL_ERROR "Unable to link function send")
+endif(curl_cv_send)
+set(curl_cv_func_send_args "${curl_cv_func_send_args}" CACHE INTERNAL "Arguments for send")
+set(HAVE_SEND 1)
-MACRO(add_header_include check header)
- IF(${check})
- SET(headers_hack
- "${headers_hack}\n#include <${header}>")
- #SET(HEADER_INCLUDES
- # ${HEADER_INCLUDES}
- # "${header}")
- ENDIF(${check})
-ENDMACRO(add_header_include header)
+check_c_source_compiles("${_source_epilogue}
+ int main(void) {
+ int flag = MSG_NOSIGNAL;
+ (void)flag;
+ return 0;
+ }" HAVE_MSG_NOSIGNAL)
-IF(HAVE_WINDOWS_H)
- SET(EXTRA_DEFINES ${EXTRA_DEFINES}
- "__unused7\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif\n#define __unused3")
- add_header_include(HAVE_WINDOWS_H "windows.h")
- add_header_include(HAVE_WINSOCK2_H "winsock2.h")
- add_header_include(HAVE_WINSOCK_H "winsock.h")
-ELSE(HAVE_WINDOWS_H)
- add_header_include(HAVE_SYS_TYPES_H "sys/types.h")
+if(NOT HAVE_WINDOWS_H)
add_header_include(HAVE_SYS_TIME_H "sys/time.h")
add_header_include(TIME_WITH_SYS_TIME "time.h")
add_header_include(HAVE_TIME_H "time.h")
-ENDIF(HAVE_WINDOWS_H)
-SET(EXTRA_DEFINES "${EXTRA_DEFINES}\n${headers_hack}\n#define __unused5")
-CURL_CHECK_C_SOURCE_COMPILES("struct timeval ts;\nts.tv_sec = 0;\nts.tv_usec = 0" HAVE_STRUCT_TIMEVAL)
+endif()
+check_c_source_compiles("${_source_epilogue}
+int main(void) {
+ struct timeval ts;
+ ts.tv_sec = 0;
+ ts.tv_usec = 0;
+ (void)ts;
+ return 0;
+}" HAVE_STRUCT_TIMEVAL)
-SET(HAVE_SIG_ATOMIC_T 1)
-SET(EXTRA_DEFINES)
-SET(HEADER_INCLUDES)
-IF(HAVE_SIGNAL_H)
- SET(HEADER_INCLUDES "signal.h")
- SET(CMAKE_EXTRA_INCLUDE_FILES "signal.h")
-ENDIF(HAVE_SIGNAL_H)
-CHECK_TYPE_SIZE("sig_atomic_t" SIZEOF_SIG_ATOMIC_T)
-IF(HAVE_SIZEOF_SIG_ATOMIC_T)
- CURL_CHECK_C_SOURCE_COMPILES("static volatile sig_atomic_t dummy = 0" HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
- IF(NOT HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
- SET(HAVE_SIG_ATOMIC_T_VOLATILE 1)
- ENDIF(NOT HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
-ENDIF(HAVE_SIZEOF_SIG_ATOMIC_T)
+include(CheckCSourceRuns)
+set(CMAKE_REQUIRED_FLAGS)
+if(HAVE_SYS_POLL_H)
+ set(CMAKE_REQUIRED_FLAGS "-DHAVE_SYS_POLL_H")
+endif(HAVE_SYS_POLL_H)
+check_c_source_runs("
+ #ifdef HAVE_SYS_POLL_H
+ # include <sys/poll.h>
+ #endif
+ int main(void) {
+ return poll((void *)0, 0, 10 /*ms*/);
+ }" HAVE_POLL_FINE)
-SET(CHECK_TYPE_SIZE_PREINCLUDE
- "#undef inline")
+set(HAVE_SIG_ATOMIC_T 1)
+set(CMAKE_REQUIRED_FLAGS)
+if(HAVE_SIGNAL_H)
+ set(CMAKE_REQUIRED_FLAGS "-DHAVE_SIGNAL_H")
+ set(CMAKE_EXTRA_INCLUDE_FILES "signal.h")
+endif(HAVE_SIGNAL_H)
+check_type_size("sig_atomic_t" SIZEOF_SIG_ATOMIC_T)
+if(HAVE_SIZEOF_SIG_ATOMIC_T)
+ check_c_source_compiles("
+ #ifdef HAVE_SIGNAL_H
+ # include <signal.h>
+ #endif
+ int main(void) {
+ static volatile sig_atomic_t dummy = 0;
+ (void)dummy;
+ return 0;
+ }" HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
+ if(NOT HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
+ set(HAVE_SIG_ATOMIC_T_VOLATILE 1)
+ endif(NOT HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
+endif(HAVE_SIZEOF_SIG_ATOMIC_T)
-IF(HAVE_WINDOWS_H)
- SET(CHECK_TYPE_SIZE_PREINCLUDE "${CHECK_TYPE_SIZE_PREINCLUDE}
- #ifndef WIN32_LEAN_AND_MEAN
- #define WIN32_LEAN_AND_MEAN
- #endif
- #include <windows.h>")
- IF(HAVE_WINSOCK2_H)
- SET(CHECK_TYPE_SIZE_PREINCLUDE "${CHECK_TYPE_SIZE_PREINCLUDE}\n#include <winsock2.h>")
- ENDIF(HAVE_WINSOCK2_H)
-ELSE(HAVE_WINDOWS_H)
- IF(HAVE_SYS_SOCKET_H)
- SET(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES}
- "sys/socket.h")
- ENDIF(HAVE_SYS_SOCKET_H)
- IF(HAVE_NETINET_IN_H)
- SET(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES}
- "netinet/in.h")
- ENDIF(HAVE_NETINET_IN_H)
- IF(HAVE_ARPA_INET_H)
- SET(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES}
- "arpa/inet.h")
- ENDIF(HAVE_ARPA_INET_H)
-ENDIF(HAVE_WINDOWS_H)
+if(HAVE_WINDOWS_H)
+ set(CMAKE_EXTRA_INCLUDE_FILES winsock2.h)
+else()
+ set(CMAKE_EXTRA_INCLUDE_FILES)
+ if(HAVE_SYS_SOCKET_H)
+ set(CMAKE_EXTRA_INCLUDE_FILES sys/socket.h)
+ endif(HAVE_SYS_SOCKET_H)
+endif()
-CHECK_TYPE_SIZE("struct sockaddr_storage" SIZEOF_STRUCT_SOCKADDR_STORAGE)
-IF(HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE)
- SET(HAVE_STRUCT_SOCKADDR_STORAGE 1)
-ENDIF(HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE)
+check_type_size("struct sockaddr_storage" SIZEOF_STRUCT_SOCKADDR_STORAGE)
+if(HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE)
+ set(HAVE_STRUCT_SOCKADDR_STORAGE 1)
+endif(HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE)
diff --git a/Utilities/cmcurl/CMake/Platforms/WindowsCache.cmake b/Utilities/cmcurl/CMake/Platforms/WindowsCache.cmake
new file mode 100644
index 000000000..53d0a5e88
--- /dev/null
+++ b/Utilities/cmcurl/CMake/Platforms/WindowsCache.cmake
@@ -0,0 +1,122 @@
+if(NOT UNIX)
+ if(WIN32)
+ set(HAVE_LIBDL 0)
+ set(HAVE_LIBUCB 0)
+ set(HAVE_LIBSOCKET 0)
+ set(NOT_NEED_LIBNSL 0)
+ set(HAVE_LIBNSL 0)
+ set(HAVE_GETHOSTNAME 1)
+ set(HAVE_LIBZ 0)
+ set(HAVE_LIBCRYPTO 0)
+
+ set(HAVE_DLOPEN 0)
+
+ set(HAVE_ALLOCA_H 0)
+ set(HAVE_ARPA_INET_H 0)
+ set(HAVE_DLFCN_H 0)
+ set(HAVE_FCNTL_H 1)
+ set(HAVE_INTTYPES_H 0)
+ set(HAVE_IO_H 1)
+ set(HAVE_MALLOC_H 1)
+ set(HAVE_MEMORY_H 1)
+ set(HAVE_NETDB_H 0)
+ set(HAVE_NETINET_IF_ETHER_H 0)
+ set(HAVE_NETINET_IN_H 0)
+ set(HAVE_NET_IF_H 0)
+ set(HAVE_PROCESS_H 1)
+ set(HAVE_PWD_H 0)
+ set(HAVE_SETJMP_H 1)
+ set(HAVE_SGTTY_H 0)
+ set(HAVE_SIGNAL_H 1)
+ set(HAVE_SOCKIO_H 0)
+ set(HAVE_STDINT_H 0)
+ set(HAVE_STDLIB_H 1)
+ set(HAVE_STRINGS_H 0)
+ set(HAVE_STRING_H 1)
+ set(HAVE_SYS_PARAM_H 0)
+ set(HAVE_SYS_POLL_H 0)
+ set(HAVE_SYS_SELECT_H 0)
+ set(HAVE_SYS_SOCKET_H 0)
+ set(HAVE_SYS_SOCKIO_H 0)
+ set(HAVE_SYS_STAT_H 1)
+ set(HAVE_SYS_TIME_H 0)
+ set(HAVE_SYS_TYPES_H 1)
+ set(HAVE_SYS_UTIME_H 1)
+ set(HAVE_TERMIOS_H 0)
+ set(HAVE_TERMIO_H 0)
+ set(HAVE_TIME_H 1)
+ set(HAVE_UNISTD_H 0)
+ set(HAVE_UTIME_H 0)
+ set(HAVE_X509_H 0)
+ set(HAVE_ZLIB_H 0)
+
+ set(HAVE_SOCKET 1)
+ set(HAVE_POLL 0)
+ set(HAVE_SELECT 1)
+ set(HAVE_STRDUP 1)
+ set(HAVE_STRSTR 1)
+ set(HAVE_STRTOK_R 0)
+ set(HAVE_STRFTIME 1)
+ set(HAVE_UNAME 0)
+ set(HAVE_STRCASECMP 0)
+ set(HAVE_STRICMP 1)
+ set(HAVE_STRCMPI 1)
+ set(HAVE_GETHOSTBYADDR 1)
+ set(HAVE_GETTIMEOFDAY 0)
+ set(HAVE_INET_ADDR 1)
+ set(HAVE_INET_NTOA 1)
+ set(HAVE_INET_NTOA_R 0)
+ set(HAVE_TCGETATTR 0)
+ set(HAVE_TCSETATTR 0)
+ set(HAVE_PERROR 1)
+ set(HAVE_CLOSESOCKET 1)
+ set(HAVE_SETVBUF 0)
+ set(HAVE_SIGSETJMP 0)
+ set(HAVE_GETPASS_R 0)
+ set(HAVE_STRLCAT 0)
+ set(HAVE_GETPWUID 0)
+ set(HAVE_GETEUID 0)
+ set(HAVE_UTIME 1)
+ set(HAVE_RAND_EGD 0)
+ set(HAVE_RAND_SCREEN 0)
+ set(HAVE_RAND_STATUS 0)
+ set(HAVE_GMTIME_R 0)
+ set(HAVE_LOCALTIME_R 0)
+ set(HAVE_GETHOSTBYADDR_R 0)
+ set(HAVE_GETHOSTBYNAME_R 0)
+ set(HAVE_SIGNAL_FUNC 1)
+ set(HAVE_SIGNAL_MACRO 0)
+
+ set(HAVE_GETHOSTBYADDR_R_5 0)
+ set(HAVE_GETHOSTBYADDR_R_5_REENTRANT 0)
+ set(HAVE_GETHOSTBYADDR_R_7 0)
+ set(HAVE_GETHOSTBYADDR_R_7_REENTRANT 0)
+ set(HAVE_GETHOSTBYADDR_R_8 0)
+ set(HAVE_GETHOSTBYADDR_R_8_REENTRANT 0)
+ set(HAVE_GETHOSTBYNAME_R_3 0)
+ set(HAVE_GETHOSTBYNAME_R_3_REENTRANT 0)
+ set(HAVE_GETHOSTBYNAME_R_5 0)
+ set(HAVE_GETHOSTBYNAME_R_5_REENTRANT 0)
+ set(HAVE_GETHOSTBYNAME_R_6 0)
+ set(HAVE_GETHOSTBYNAME_R_6_REENTRANT 0)
+
+ set(TIME_WITH_SYS_TIME 0)
+ set(HAVE_O_NONBLOCK 0)
+ set(HAVE_IN_ADDR_T 0)
+ set(HAVE_INET_NTOA_R_DECL 0)
+ set(HAVE_INET_NTOA_R_DECL_REENTRANT 0)
+ if(ENABLE_IPV6)
+ set(HAVE_GETADDRINFO 1)
+ else()
+ set(HAVE_GETADDRINFO 0)
+ endif()
+ set(STDC_HEADERS 1)
+ set(RETSIGTYPE_TEST 1)
+
+ set(HAVE_SIGACTION 0)
+ set(HAVE_MACRO_SIGSETJMP 0)
+ else(WIN32)
+ message("This file should be included on Windows platform only")
+ endif(WIN32)
+endif(NOT UNIX)
+
diff --git a/Utilities/cmcurl/CMake/Utilities.cmake b/Utilities/cmcurl/CMake/Utilities.cmake
new file mode 100644
index 000000000..37cdfe3bf
--- /dev/null
+++ b/Utilities/cmcurl/CMake/Utilities.cmake
@@ -0,0 +1,31 @@
+# File containing various utilities
+
+# Converts a CMake list to a string containing elements separated by spaces
+function(TO_LIST_SPACES _LIST_NAME OUTPUT_VAR)
+ set(NEW_LIST_SPACE)
+ foreach(ITEM ${${_LIST_NAME}})
+ set(NEW_LIST_SPACE "${NEW_LIST_SPACE} ${ITEM}")
+ endforeach()
+ string(STRIP ${NEW_LIST_SPACE} NEW_LIST_SPACE)
+ set(${OUTPUT_VAR} "${NEW_LIST_SPACE}" PARENT_SCOPE)
+endfunction()
+
+# Appends a lis of item to a string which is a space-separated list, if they don't already exist.
+function(LIST_SPACES_APPEND_ONCE LIST_NAME)
+ string(REPLACE " " ";" _LIST ${${LIST_NAME}})
+ list(APPEND _LIST ${ARGN})
+ list(REMOVE_DUPLICATES _LIST)
+ to_list_spaces(_LIST NEW_LIST_SPACE)
+ set(${LIST_NAME} "${NEW_LIST_SPACE}" PARENT_SCOPE)
+endfunction()
+
+# Convinience function that does the same as LIST(FIND ...) but with a TRUE/FALSE return value.
+# Ex: IN_STR_LIST(MY_LIST "Searched item" WAS_FOUND)
+function(IN_STR_LIST LIST_NAME ITEM_SEARCHED RETVAL)
+ list(FIND ${LIST_NAME} ${ITEM_SEARCHED} FIND_POS)
+ if(${FIND_POS} EQUAL -1)
+ set(${RETVAL} FALSE PARENT_SCOPE)
+ else()
+ set(${RETVAL} TRUE PARENT_SCOPE)
+ endif()
+endfunction()
diff --git a/Utilities/cmcurl/CMakeLists.txt b/Utilities/cmcurl/CMakeLists.txt
index 74a713dd8..39b70c0d6 100644
--- a/Utilities/cmcurl/CMakeLists.txt
+++ b/Utilities/cmcurl/CMakeLists.txt
@@ -1,549 +1,902 @@
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6.3 FATAL_ERROR)
-PROJECT(LIBCURL C)
+# Set curl options as needed for CMake build
+set(BUILD_CURL_EXE OFF CACHE INTERNAL "No curl exe")
+set(BUILD_CURL_TESTS OFF CACHE INTERNAL "No curl tests")
+set(BUILD_DASHBOARD_REPORTS OFF CACHE INTERNAL "No curl dashboard reports")
+set(BUILD_RELEASE_DEBUG_DIRS OFF CACHE INTERNAL "No curl release/debug dirs")
+set(CMAKE_USE_GSSAPI OFF CACHE INTERNAL "Disable curl gssapi")
+set(CMAKE_USE_LIBSSH2 OFF CACHE INTERNAL "Disable curl libssh2")
+set(CMAKE_USE_OPENLDAP OFF CACHE INTERNAL "No curl OpenLDAP")
+set(CURL_DISABLE_COOKIES OFF CACHE INTERNAL "Do not disable curl cookie support")
+set(CURL_DISABLE_CRYPTO_AUTH OFF CACHE INTERNAL "Do not disable curl crypto auth")
+set(CURL_DISABLE_DICT ON CACHE INTERNAL "Disable curl dict protocol?")
+set(CURL_DISABLE_FILE OFF CACHE INTERNAL "Disable curl file protocol?")
+set(CURL_DISABLE_FTP OFF CACHE INTERNAL "Disable curl ftp protocol?")
+set(CURL_DISABLE_GOPHER ON CACHE INTERNAL "Disable curl gopher protocol?")
+set(CURL_DISABLE_HTTP OFF CACHE INTERNAL "Disable curl http protocol?")
+set(CURL_DISABLE_IMAP ON CACHE INTERNAL "Disable curl imap protocol?")
+set(CURL_DISABLE_LDAP ON CACHE INTERNAL "Disable curl ldap protocol?")
+set(CURL_DISABLE_LDAPS ON CACHE INTERNAL "Disable curl ldaps protocol?")
+set(CURL_DISABLE_POP3 ON CACHE INTERNAL "Disable curl pop3 protocol?")
+set(CURL_DISABLE_PROXY OFF CACHE INTERNAL "Do not disable curl proxy")
+set(CURL_DISABLE_RTSP ON CACHE INTERNAL "Disable curl rtsp protocol?")
+set(CURL_DISABLE_SMTP ON CACHE INTERNAL "Disable curl smtp protocol?")
+set(CURL_DISABLE_TELNET ON CACHE INTERNAL "Disable curl telnet protocol?")
+set(CURL_DISABLE_TFTP ON CACHE INTERNAL "Disable curl tftp protocol?")
+set(CURL_DISABLE_VERBOSE_STRINGS OFF CACHE INTERNAL "Do not disable curl verbosity")
+set(CURL_HIDDEN_SYMBOLS OFF CACHE INTERNAL "No curl hidden symbols")
+set(CURL_STATICLIB ON CACHE INTERNAL "Static curl")
+set(DISABLED_THREADSAFE OFF CACHE INTERNAL "Curl can use thread-safe functions")
+set(ENABLE_ARES OFF CACHE INTERNAL "No curl c-ares support")
+set(ENABLE_CURLDEBUG OFF CACHE INTERNAL "No curl TrackMemory features")
+set(ENABLE_DEBUG OFF CACHE INTERNAL "No curl debug features")
+set(ENABLE_IPV6 OFF CACHE INTERNAL "No curl IPv6 support")
+set(ENABLE_MANUAL OFF CACHE INTERNAL "No curl built-in manual")
+set(ENABLE_THREADED_RESOLVER OFF CACHE INTERNAL "No curl POSIX threaded DNS lookup")
+set(ENABLE_UNIX_SOCKETS OFF CACHE INTERNAL "No curl Unix domain sockets support")
+set(HTTP_ONLY OFF CACHE INTERNAL "Curl is not http-only")
+set(USE_WIN32_LDAP OFF CACHE INTERNAL "No curl Windows LDAP")
+
+# Windows Vista and above have inet_pton, but this will link on
+# older versions and then the executable will fail to launch at
+# runtime on older versions because no DLL provides the symbol.
+if(WIN32)
+ set(HAVE_INET_PTON 0 CACHE INTERNAL "Do not use inet_pton")
+endif()
+
+# Starting with OSX 10.11 there is an unrelated libnetwork library which will
+# be picked up during curl configuration. Linking against this library is
+# unnecessary and breaks backward compatibility of the resulting binaries
+# because libnetwork is unavailable on older OSX versions.
+if(APPLE)
+ set(HAVE_LIBNETWORK 0 CACHE INTERNAL "Do not use libnetwork")
+endif(APPLE)
+
+# Disable warnings to avoid changing 3rd party code.
+if(CMAKE_C_COMPILER_ID MATCHES
+ "^(GNU|Clang|AppleClang|XL|VisualAge|SunPro|MIPSpro|HP|Intel)$")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w")
+elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall")
+endif()
+
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at http://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+# cURL/libcurl CMake script
+# by Tetetest and Sukender (Benoit Neil)
+
+# TODO:
+# The output .so file lacks the soname number which we currently have within the lib/Makefile.am file
+# Add full (4 or 5 libs) SSL support
+# Add INSTALL target (EXTRA_DIST variables in Makefile.am may be moved to Makefile.inc so that CMake/CPack is aware of what's to include).
+# Add CTests(?)
+# Check on all possible platforms
+# Test with as many configurations possible (With or without any option)
+# Create scripts that help keeping the CMake build system up to date (to reduce maintenance). According to Tetetest:
+# - lists of headers that 'configure' checks for;
+# - curl-specific tests (the ones that are in m4/curl-*.m4 files);
+# - (most obvious thing:) curl version numbers.
+# Add documentation subproject
+#
+# To check:
+# (From Daniel Stenberg) The cmake build selected to run gcc with -fPIC on my box while the plain configure script did not.
+# (From Daniel Stenberg) The gcc command line use neither -g nor any -O options. As a developer, I also treasure our configure scripts's --enable-debug option that sets a long range of "picky" compiler options.
+cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
+set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}")
+include(Utilities)
+include(Macros)
+
+project( CURL C )
+
+if(0) # This code not needed for building within CMake.
+message(WARNING "the curl cmake build system is poorly maintained. Be aware")
+endif()
+
+file (READ ${CURL_SOURCE_DIR}/include/curl/curlver.h CURL_VERSION_H_CONTENTS)
+string (REGEX MATCH "#define LIBCURL_VERSION \"[^\"]*"
+ CURL_VERSION ${CURL_VERSION_H_CONTENTS})
+string (REGEX REPLACE "[^\"]+\"" "" CURL_VERSION ${CURL_VERSION})
+string (REGEX MATCH "#define LIBCURL_VERSION_NUM 0x[0-9a-fA-F]+"
+ CURL_VERSION_NUM ${CURL_VERSION_H_CONTENTS})
+string (REGEX REPLACE "[^0]+0x" "" CURL_VERSION_NUM ${CURL_VERSION_NUM})
+
+include_regular_expression("^.*$") # Sukender: Is it necessary?
# Setup package meta-data
-SET(PACKAGE "curl")
-SET(VERSION "7.16.1")
-SET(PACKAGE_TARNAME "curl")
-SET(PACKAGE_BUGREPORT " ")
-SET(PACKAGE_NAME "curl")
-SET(PACKAGE_VERSION "-")
-SET(PACKAGE_STRING "curl-")
-SET(PACKAGE_BUGREPORT "a suitable curl mailing list => http://curl.haxx.se/mail/")
-SET(OPERATING_SYSTEM "${CMAKE_SYSTEM_NAME}")
+# SET(PACKAGE "curl")
+if(0) # This code not needed for building within CMake.
+message(STATUS "curl version=[${CURL_VERSION}]")
+endif()
+# SET(PACKAGE_TARNAME "curl")
+# SET(PACKAGE_NAME "curl")
+# SET(PACKAGE_VERSION "-")
+# SET(PACKAGE_STRING "curl-")
+# SET(PACKAGE_BUGREPORT "a suitable curl mailing list => http://curl.haxx.se/mail/")
+set(OPERATING_SYSTEM "${CMAKE_SYSTEM_NAME}")
+set(OS "\"${CMAKE_SYSTEM_NAME}\"")
+
+include_directories(${PROJECT_BINARY_DIR}/include/curl)
+include_directories( ${CURL_SOURCE_DIR}/include )
+
+option(BUILD_CURL_EXE "Set to ON to build cURL executable." ON)
+option(BUILD_CURL_TESTS "Set to ON to build cURL tests." ON)
+option(CURL_STATICLIB "Set to ON to build libcurl with static linking." OFF)
+option(ENABLE_ARES "Set to ON to enable c-ares support" OFF)
+option(ENABLE_THREADED_RESOLVER "Set to ON to enable POSIX threaded DNS lookup" OFF)
+
+option(ENABLE_DEBUG "Set to ON to enable curl debug features" OFF)
+option(ENABLE_CURLDEBUG "Set to ON to build with TrackMemory feature enabled" OFF)
+
+if (ENABLE_DEBUG)
+ # DEBUGBUILD will be defined only for Debug builds
+ if(NOT CMAKE_VERSION VERSION_LESS 3.0)
+ set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS $<$<CONFIG:Debug>:DEBUGBUILD>)
+ else()
+ set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG DEBUGBUILD)
+ endif()
+ set(ENABLE_CURLDEBUG ON)
+endif()
+
+if (ENABLE_CURLDEBUG)
+ set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS CURLDEBUG)
+endif()
+
+# initialize CURL_LIBS
+set(CURL_LIBS "")
+
+if(ENABLE_THREADED_RESOLVER AND ENABLE_ARES)
+ message(FATAL_ERROR "Options ENABLE_THREADED_RESOLVER and ENABLE_ARES are mutually exclusive")
+endif()
+
+if(ENABLE_ARES)
+ set(USE_ARES 1)
+ find_package(CARES REQUIRED)
+ list(APPEND CURL_LIBS ${CARES_LIBRARY} )
+ set(CURL_LIBS ${CURL_LIBS} ${CARES_LIBRARY})
+endif()
+
+option(BUILD_DASHBOARD_REPORTS "Set to ON to activate reporting of cURL builds here http://www.cdash.org/CDashPublic/index.php?project=CURL" OFF)
+if(BUILD_DASHBOARD_REPORTS)
+ #INCLUDE(Dart)
+ include(CTest)
+endif(BUILD_DASHBOARD_REPORTS)
+
+if(MSVC)
+ option(BUILD_RELEASE_DEBUG_DIRS "Set OFF to build each configuration to a separate directory" OFF)
+ mark_as_advanced(BUILD_RELEASE_DEBUG_DIRS)
+endif()
+
+option(CURL_HIDDEN_SYMBOLS "Set to ON to hide libcurl internal symbols (=hide all symbols that aren't officially external)." ON)
+mark_as_advanced(CURL_HIDDEN_SYMBOLS)
+
+# IF(WIN32)
+# OPTION(CURL_WINDOWS_SSPI "Use windows libraries to allow NTLM authentication without openssl" ON)
+# MARK_AS_ADVANCED(CURL_WINDOWS_SSPI)
+# ENDIF()
+
+option(HTTP_ONLY "disables all protocols except HTTP (This overrides all CURL_DISABLE_* options)" OFF)
+mark_as_advanced(HTTP_ONLY)
+option(CURL_DISABLE_FTP "disables FTP" OFF)
+mark_as_advanced(CURL_DISABLE_FTP)
+option(CURL_DISABLE_LDAP "disables LDAP" OFF)
+mark_as_advanced(CURL_DISABLE_LDAP)
+option(CURL_DISABLE_TELNET "disables Telnet" OFF)
+mark_as_advanced(CURL_DISABLE_TELNET)
+option(CURL_DISABLE_DICT "disables DICT" OFF)
+mark_as_advanced(CURL_DISABLE_DICT)
+option(CURL_DISABLE_FILE "disables FILE" OFF)
+mark_as_advanced(CURL_DISABLE_FILE)
+option(CURL_DISABLE_TFTP "disables TFTP" OFF)
+mark_as_advanced(CURL_DISABLE_TFTP)
+option(CURL_DISABLE_HTTP "disables HTTP" OFF)
+mark_as_advanced(CURL_DISABLE_HTTP)
+
+option(CURL_DISABLE_LDAPS "to disable LDAPS" OFF)
+mark_as_advanced(CURL_DISABLE_LDAPS)
+
+option(CURL_DISABLE_RTSP "to disable RTSP" OFF)
+mark_as_advanced(CURL_DISABLE_RTSP)
+option(CURL_DISABLE_PROXY "to disable proxy" OFF)
+mark_as_advanced(CURL_DISABLE_PROXY)
+option(CURL_DISABLE_POP3 "to disable POP3" OFF)
+mark_as_advanced(CURL_DISABLE_POP3)
+option(CURL_DISABLE_IMAP "to disable IMAP" OFF)
+mark_as_advanced(CURL_DISABLE_IMAP)
+option(CURL_DISABLE_SMTP "to disable SMTP" OFF)
+mark_as_advanced(CURL_DISABLE_SMTP)
+option(CURL_DISABLE_GOPHER "to disable Gopher" OFF)
+mark_as_advanced(CURL_DISABLE_GOPHER)
+
+if(HTTP_ONLY)
+ set(CURL_DISABLE_FTP ON)
+ set(CURL_DISABLE_LDAP ON)
+ set(CURL_DISABLE_LDAPS ON)
+ set(CURL_DISABLE_TELNET ON)
+ set(CURL_DISABLE_DICT ON)
+ set(CURL_DISABLE_FILE ON)
+ set(CURL_DISABLE_TFTP ON)
+ set(CURL_DISABLE_RTSP ON)
+ set(CURL_DISABLE_POP3 ON)
+ set(CURL_DISABLE_IMAP ON)
+ set(CURL_DISABLE_SMTP ON)
+ set(CURL_DISABLE_GOPHER ON)
+endif()
+
+option(CURL_DISABLE_COOKIES "to disable cookies support" OFF)
+mark_as_advanced(CURL_DISABLE_COOKIES)
+
+option(CURL_DISABLE_CRYPTO_AUTH "to disable cryptographic authentication" OFF)
+mark_as_advanced(CURL_DISABLE_CRYPTO_AUTH)
+option(CURL_DISABLE_VERBOSE_STRINGS "to disable verbose strings" OFF)
+mark_as_advanced(CURL_DISABLE_VERBOSE_STRINGS)
+option(DISABLED_THREADSAFE "Set to explicitly specify we don't want to use thread-safe functions" OFF)
+mark_as_advanced(DISABLED_THREADSAFE)
+option(ENABLE_IPV6 "Define if you want to enable IPv6 support" ON)
+mark_as_advanced(ENABLE_IPV6)
+if(ENABLE_IPV6)
+ include(CheckStructHasMember)
+ check_struct_has_member("struct sockaddr_in6" sin6_addr "netinet/in.h"
+ HAVE_SOCKADDR_IN6_SIN6_ADDR)
+ check_struct_has_member("struct sockaddr_in6" sin6_scope_id "netinet/in.h"
+ HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
+ if(NOT HAVE_SOCKADDR_IN6_SIN6_ADDR)
+ message(WARNING "struct sockaddr_in6 not available, disabling IPv6 support")
+ # Force the feature off as this name is used as guard macro...
+ set(ENABLE_IPV6 OFF
+ CACHE BOOL "Define if you want to enable IPv6 support" FORCE)
+ endif()
+endif()
+
+option(ENABLE_MANUAL "to provide the built-in manual" ON)
+unset(USE_MANUAL CACHE) # TODO: cache NROFF/NROFF_MANOPT/USE_MANUAL vars?
+if(ENABLE_MANUAL)
+ find_program(NROFF NAMES gnroff nroff)
+ if(NROFF)
+ # Need a way to write to stdin, this will do
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/nroff-input.txt" "test")
+ # Tests for a valid nroff option to generate a manpage
+ foreach(_MANOPT "-man" "-mandoc")
+ execute_process(COMMAND "${NROFF}" ${_MANOPT}
+ OUTPUT_VARIABLE NROFF_MANOPT_OUTPUT
+ INPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/nroff-input.txt"
+ ERROR_QUIET)
+ # Save the option if it was valid
+ if(NROFF_MANOPT_OUTPUT)
+ message("Found *nroff option: -- ${_MANOPT}")
+ set(NROFF_MANOPT ${_MANOPT})
+ set(USE_MANUAL 1)
+ break()
+ endif()
+ endforeach()
+ # No need for the temporary file
+ file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/nroff-input.txt")
+ if(NOT USE_MANUAL)
+ message(WARNING "Found no *nroff option to get plaintext from man pages")
+ endif()
+ else()
+ message(WARNING "Found no *nroff program")
+ endif()
+endif()
# We need ansi c-flags, especially on HP
-SET(CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS}")
-SET(CMAKE_REQUIRED_FLAGS ${CMAKE_ANSI_CFLAGS})
+set(CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS}")
+set(CMAKE_REQUIRED_FLAGS ${CMAKE_ANSI_CFLAGS})
# Disable warnings on Borland to avoid changing 3rd party code.
-IF(BORLAND)
- SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w-")
-ENDIF(BORLAND)
+if(BORLAND)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w-")
+endif(BORLAND)
# If we are on AIX, do the _ALL_SOURCE magic
-IF(${CMAKE_SYSTEM_NAME} MATCHES AIX)
- SET(_ALL_SOURCE 1)
-ENDIF(${CMAKE_SYSTEM_NAME} MATCHES AIX)
+if(${CMAKE_SYSTEM_NAME} MATCHES AIX)
+ set(_ALL_SOURCE 1)
+endif(${CMAKE_SYSTEM_NAME} MATCHES AIX)
# Include all the necessary files for macros
-SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake")
-INCLUDE (CheckFunctionExists)
-INCLUDE (CheckIncludeFile)
-INCLUDE (CheckIncludeFiles)
-INCLUDE (CheckLibraryExists)
-INCLUDE (CheckSymbolExists)
-INCLUDE (CheckTypeSize)
-
-SET(libCurl_SRCS
- # amigaos.c - does not build on AmigaOS
- base64.c
- connect.c
- content_encoding.c
- cookie.c
- dict.c
- easy.c
- escape.c
- file.c
- formdata.c
- ftp.c
- getenv.c
- getinfo.c
- gtls.c
- hash.c
- hostares.c
- hostasyn.c
- hostip4.c
- hostip6.c
- hostip.c
- hostsyn.c
- hostthre.c
- http.c
- http_chunks.c
- http_digest.c
- http_negotiate.c
- http_ntlm.c
- if2ip.c
- inet_ntop.c
- inet_pton.c
- krb4.c
- ldap.c
- llist.c
- md5.c
-# memdebug.c -not used
- mprintf.c
- multi.c
- netrc.c
- # nwlib.c - Not used
- parsedate.c
- progress.c
- security.c
- select.c
- sendf.c
- share.c
- socks.c
- speedcheck.c
- splay.c
- ssh.c
- sslgen.c
- ssluse.c
- strdup.c
- strequal.c
- strerror.c
- # strtok.c - specify later
- # strtoofft.c - specify later
- telnet.c
- tftp.c
- timeval.c
- transfer.c
- url.c
- version.c
- )
-
-SET(CURL_DISABLE_LDAP 1)
-IF(NOT CURL_DISABLE_LDAP)
- SET(libCurl_SRCS
- ${libCurl_SRCS}
- ldap.c
- )
-ENDIF(NOT CURL_DISABLE_LDAP)
-
-# if we have Kerberos 4, right now this is never on
-#OPTION(CURL_KRB4 "Use Kerberos 4" OFF)
-IF(CURL_KRB4)
- SET(libCurl_SRCS ${libCurl_SRCS}
- krb4.c
- security.c
- )
-ENDIF(CURL_KRB4)
-
-#OPTION(CURL_MALLOC_DEBUG "Debug mallocs in Curl" OFF)
-MARK_AS_ADVANCED(CURL_MALLOC_DEBUG)
-IF(CURL_MALLOC_DEBUG)
- SET(libCurl_SRCS ${libCurl_SRCS}
- memdebug.c
- )
-ENDIF(CURL_MALLOC_DEBUG)
+include (CheckFunctionExists)
+include (CheckIncludeFile)
+include (CheckIncludeFiles)
+include (CheckLibraryExists)
+include (CheckSymbolExists)
+include (CheckTypeSize)
+include (CheckCSourceCompiles)
# On windows preload settings
-IF(WIN32 AND NOT MINGW)
- INCLUDE(${LIBCURL_SOURCE_DIR}/Platforms/WindowsCache.cmake)
-ENDIF()
-
-# This macro checks if the symbol exists in the library and if it
-# does, it appends library to the list.
-SET(CURL_LIBS "")
-MACRO(CHECK_LIBRARY_EXISTS_CONCAT LIBRARY SYMBOL VARIABLE)
- CHECK_LIBRARY_EXISTS("${LIBRARY};${CURL_LIBS}" ${SYMBOL} ""
- ${VARIABLE})
- IF(${VARIABLE})
- SET(CURL_LIBS ${CURL_LIBS} ${LIBRARY})
- ENDIF(${VARIABLE})
-ENDMACRO(CHECK_LIBRARY_EXISTS_CONCAT)
+if(WIN32)
+ set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_WINSOCKAPI_")
+ include(${CMAKE_CURRENT_SOURCE_DIR}/CMake/Platforms/WindowsCache.cmake)
+endif(WIN32)
+
+if(ENABLE_THREADED_RESOLVER)
+ check_include_file_concat("pthread.h" HAVE_PTHREAD_H)
+ if(HAVE_PTHREAD_H)
+ set(CMAKE_THREAD_PREFER_PTHREAD 1)
+ find_package(Threads)
+ if(CMAKE_USE_PTHREADS_INIT)
+ set(CURL_LIBS ${CURL_LIBS} ${CMAKE_THREAD_LIBS_INIT})
+ set(USE_THREADS_POSIX 1)
+ endif()
+ endif()
+endif()
# Check for all needed libraries
-# use the cmake defined dl libs as dl is should not be used
-# on HPUX, but rather dld this avoids a warning
-SET(CURL_LIBS ${CURL_LIBS} ${CMAKE_DL_LIBS})
-#CHECK_LIBRARY_EXISTS_CONCAT("dl" dlopen HAVE_LIBDL)
-#CHECK_LIBRARY_EXISTS_CONCAT("ucb" gethostname HAVE_LIBUCB)
-CHECK_LIBRARY_EXISTS_CONCAT("socket" connect HAVE_LIBSOCKET)
-CHECK_LIBRARY_EXISTS("c" gethostbyname "" NOT_NEED_LIBNSL)
+if(0) # This code not needed for building within CMake.
+check_library_exists_concat("dl" dlopen HAVE_LIBDL)
+else()
+ # Use the cmake-defined dl libs as dl is should not be used
+ # on HPUX, but rather dld this avoids a warning
+ list(APPEND CURL_LIBS ${CMAKE_DL_LIBS})
+endif()
+check_library_exists_concat("socket" connect HAVE_LIBSOCKET)
+check_library_exists("c" gethostbyname "" NOT_NEED_LIBNSL)
# Yellowtab Zeta needs different libraries than BeOS 5.
-IF(BEOS)
- SET(NOT_NEED_LIBNSL 1)
- CHECK_LIBRARY_EXISTS_CONCAT("bind" gethostbyname HAVE_LIBBIND)
- CHECK_LIBRARY_EXISTS_CONCAT("bnetapi" closesocket HAVE_LIBBNETAPI)
-ENDIF(BEOS)
-
-CHECK_LIBRARY_EXISTS_CONCAT("network" recv HAVE_LIBNETWORK)
-
-IF(NOT NOT_NEED_LIBNSL)
- CHECK_LIBRARY_EXISTS_CONCAT("nsl" gethostbyname HAVE_LIBNSL)
-ENDIF(NOT NOT_NEED_LIBNSL)
-
-CHECK_LIBRARY_EXISTS_CONCAT("ws2_32" getch HAVE_LIBWS2_32)
-CHECK_LIBRARY_EXISTS_CONCAT("winmm" getch HAVE_LIBWINMM)
-IF(NOT CURL_SPECIAL_LIBZ)
- CHECK_LIBRARY_EXISTS_CONCAT("z" inflateEnd HAVE_LIBZ)
-ENDIF(NOT CURL_SPECIAL_LIBZ)
-
-OPTION(CMAKE_USE_OPENSSL "Use OpenSSL code with curl." OFF)
-MARK_AS_ADVANCED(CMAKE_USE_OPENSSL)
-IF(CMAKE_USE_OPENSSL)
- SET(USE_SSLEAY TRUE)
- SET(USE_OPENSSL TRUE)
- FIND_PACKAGE(OpenSSL REQUIRED)
- INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
- SET(CURL_LIBS ${CURL_LIBS} ${OPENSSL_LIBRARIES})
- SET(CURL_CA_BUNDLE "" CACHE FILEPATH "Path to SSL CA Certificate Bundle")
- MARK_AS_ADVANCED(CURL_CA_BUNDLE)
- IF(CURL_CA_BUNDLE)
- ADD_DEFINITIONS(-DCURL_CA_BUNDLE="${CURL_CA_BUNDLE}")
- ENDIF(CURL_CA_BUNDLE)
- # for windows we want to install OPENSSL_LIBRARIES dlls
- # and also copy them into the build tree so that testing
- # can find them.
- IF(WIN32)
- FIND_FILE(CMAKE_EAY_DLL NAME libeay32.dll HINTS ${OPENSSL_INCLUDE_DIR}/..)
- FIND_FILE(CMAKE_SSL_DLL NAME ssleay32.dll HINTS ${OPENSSL_INCLUDE_DIR}/..)
- MARK_AS_ADVANCED(CMAKE_EAY_DLL CMAKE_SSL_DLL)
- IF(CMAKE_SSL_DLL AND CMAKE_EAY_DLL)
- SET(CMAKE_CURL_SSL_DLLS ${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/libeay32.dll
- ${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/ssleay32.dll)
- ADD_CUSTOM_COMMAND(OUTPUT
- ${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/libeay32.dll
- DEPENDS ${CMAKE_EAY_DLL}
- COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_EAY_DLL}
- ${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/libeay32.dll)
- ADD_CUSTOM_COMMAND(OUTPUT
- ${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/ssleay32.dll
- DEPENDS ${CMAKE_SSL_DLL}
- COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SSL_DLL}
- ${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/ssleay32.dll)
- INSTALL(PROGRAMS ${CMAKE_EAY_DLL} ${CMAKE_SSL_DLL} DESTINATION bin)
- ENDIF()
- ENDIF()
-ENDIF(CMAKE_USE_OPENSSL)
+if(BEOS)
+ set(NOT_NEED_LIBNSL 1)
+ check_library_exists_concat("bind" gethostbyname HAVE_LIBBIND)
+ check_library_exists_concat("bnetapi" closesocket HAVE_LIBBNETAPI)
+endif(BEOS)
+
+check_library_exists_concat("network" recv HAVE_LIBNETWORK)
+
+if(NOT NOT_NEED_LIBNSL)
+ check_library_exists_concat("nsl" gethostbyname HAVE_LIBNSL)
+endif(NOT NOT_NEED_LIBNSL)
+
+check_function_exists(gethostname HAVE_GETHOSTNAME)
+
+if(WIN32)
+ check_library_exists_concat("ws2_32" getch HAVE_LIBWS2_32)
+ check_library_exists_concat("winmm" getch HAVE_LIBWINMM)
+endif()
+
+set(USE_OPENSSL OFF)
+set(HAVE_LIBCRYPTO OFF)
+set(HAVE_LIBSSL OFF)
+
+if(CMAKE_USE_OPENSSL)
+ find_package(OpenSSL)
+ if(OPENSSL_FOUND)
+ list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES})
+ set(USE_OPENSSL ON)
+ set(HAVE_LIBCRYPTO ON)
+ set(HAVE_LIBSSL ON)
+ include_directories(${OPENSSL_INCLUDE_DIR})
+ set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
+ check_include_file("openssl/crypto.h" HAVE_OPENSSL_CRYPTO_H)
+ check_include_file("openssl/engine.h" HAVE_OPENSSL_ENGINE_H)
+ check_include_file("openssl/err.h" HAVE_OPENSSL_ERR_H)
+ check_include_file("openssl/pem.h" HAVE_OPENSSL_PEM_H)
+ check_include_file("openssl/pkcs12.h" HAVE_OPENSSL_PKCS12_H)
+ check_include_file("openssl/rsa.h" HAVE_OPENSSL_RSA_H)
+ check_include_file("openssl/ssl.h" HAVE_OPENSSL_SSL_H)
+ check_include_file("openssl/x509.h" HAVE_OPENSSL_X509_H)
+ check_include_file("openssl/rand.h" HAVE_OPENSSL_RAND_H)
+
+ # Optionally build with a specific CA cert bundle.
+ if(CURL_CA_BUNDLE)
+ add_definitions(-DCURL_CA_BUNDLE="${CURL_CA_BUNDLE}")
+ endif()
+ # Optionally build with a specific CA cert dir.
+ if(CURL_CA_PATH)
+ add_definitions(-DCURL_CA_PATH="${CURL_CA_PATH}")
+ endif()
+ endif()
+elseif(WIN32)
+ # Use Windows SSL/TLS native implementation.
+ add_definitions(-DUSE_SCHANNEL)
+ set(USE_WINDOWS_SSPI 1)
+elseif(APPLE)
+ # Use OS X SSL/TLS native implementation if available on target version.
+ if(CMAKE_OSX_DEPLOYMENT_TARGET)
+ set(OSX_VERSION ${CMAKE_OSX_DEPLOYMENT_TARGET})
+ else()
+ execute_process(
+ COMMAND sw_vers -productVersion
+ OUTPUT_VARIABLE OSX_VERSION
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ endif()
+ if(NOT OSX_VERSION VERSION_LESS 10.6 AND
+ CMAKE_C_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
+ add_definitions(-DUSE_DARWINSSL)
+ list(APPEND CURL_LIBS
+ "-framework CoreFoundation"
+ "-framework Security"
+ )
+ endif()
+endif()
+
+if(NOT CURL_DISABLE_LDAP)
+
+ if(WIN32)
+ option(USE_WIN32_LDAP "Use Windows LDAP implementation" ON)
+ if(USE_WIN32_LDAP)
+ check_library_exists("wldap32" cldap_open "" HAVE_WLDAP32)
+ if(NOT HAVE_WLDAP32)
+ set(USE_WIN32_LDAP OFF)
+ endif()
+ endif()
+ endif()
+
+ option(CMAKE_USE_OPENLDAP "Use OpenLDAP code." OFF)
+ mark_as_advanced(CMAKE_USE_OPENLDAP)
+ set(CMAKE_LDAP_LIB "ldap" CACHE STRING "Name or full path to ldap library")
+ set(CMAKE_LBER_LIB "lber" CACHE STRING "Name or full path to lber library")
+
+ if(CMAKE_USE_OPENLDAP AND USE_WIN32_LDAP)
+ message(FATAL_ERROR "Cannot use USE_WIN32_LDAP and CMAKE_USE_OPENLDAP at the same time")
+ endif()
+
+ # Now that we know, we're not using windows LDAP...
+ if(NOT USE_WIN32_LDAP)
+ # Check for LDAP
+ set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES})
+ check_library_exists_concat(${CMAKE_LDAP_LIB} ldap_init HAVE_LIBLDAP)
+ check_library_exists_concat(${CMAKE_LBER_LIB} ber_init HAVE_LIBLBER)
+ else()
+ check_include_file_concat("winldap.h" HAVE_WINLDAP_H)
+ check_include_file_concat("winber.h" HAVE_WINBER_H)
+ endif()
+
+ set(CMAKE_LDAP_INCLUDE_DIR "" CACHE STRING "Path to LDAP include directory")
+ if(CMAKE_LDAP_INCLUDE_DIR)
+ set(CMAKE_REQUIRED_INCLUDES ${CMAKE_LDAP_INCLUDE_DIR})
+ endif()
+ check_include_file_concat("ldap.h" HAVE_LDAP_H)
+ check_include_file_concat("lber.h" HAVE_LBER_H)
+
+ if(NOT HAVE_LDAP_H)
+ message(STATUS "LDAP_H not found CURL_DISABLE_LDAP set ON")
+ set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE)
+ elseif(NOT HAVE_LIBLDAP)
+ message(STATUS "LDAP library '${CMAKE_LDAP_LIB}' not found CURL_DISABLE_LDAP set ON")
+ set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE)
+ else()
+ if(CMAKE_USE_OPENLDAP)
+ set(USE_OPENLDAP ON)
+ endif()
+ if(CMAKE_LDAP_INCLUDE_DIR)
+ include_directories(${CMAKE_LDAP_INCLUDE_DIR})
+ endif()
+ set(NEED_LBER_H ON)
+ set(_HEADER_LIST)
+ if(HAVE_WINDOWS_H)
+ list(APPEND _HEADER_LIST "windows.h")
+ endif()
+ if(HAVE_SYS_TYPES_H)
+ list(APPEND _HEADER_LIST "sys/types.h")
+ endif()
+ list(APPEND _HEADER_LIST "ldap.h")
+
+ set(_SRC_STRING "")
+ foreach(_HEADER ${_HEADER_LIST})
+ set(_INCLUDE_STRING "${_INCLUDE_STRING}#include <${_HEADER}>\n")
+ endforeach()
+
+ set(_SRC_STRING
+ "
+ ${_INCLUDE_STRING}
+ int main(int argc, char ** argv)
+ {
+ BerValue *bvp = NULL;
+ BerElement *bep = ber_init(bvp);
+ ber_free(bep, 1);
+ return 0;
+ }"
+ )
+ set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -DLDAP_DEPRECATED=1")
+ list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_LDAP_LIB})
+ if(HAVE_LIBLBER)
+ list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_LBER_LIB})
+ endif()
+ check_c_source_compiles("${_SRC_STRING}" NOT_NEED_LBER_H)
+
+ if(NOT_NEED_LBER_H)
+ set(NEED_LBER_H OFF)
+ else()
+ set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -DNEED_LBER_H")
+ endif()
+ endif()
+
+endif()
+
+# No ldap, no ldaps.
+if(CURL_DISABLE_LDAP)
+ if(NOT CURL_DISABLE_LDAPS)
+ message(STATUS "LDAP needs to be enabled to support LDAPS")
+ set(CURL_DISABLE_LDAPS ON CACHE BOOL "" FORCE)
+ endif()
+endif()
+
+if(NOT CURL_DISABLE_LDAPS)
+ check_include_file_concat("ldap_ssl.h" HAVE_LDAP_SSL_H)
+ check_include_file_concat("ldapssl.h" HAVE_LDAPSSL_H)
+endif()
# Check for idn
-CHECK_LIBRARY_EXISTS_CONCAT("idn" idna_to_ascii_lz HAVE_LIBIDN)
+check_library_exists_concat("idn" idna_to_ascii_lz HAVE_LIBIDN)
# Check for symbol dlopen (same as HAVE_LIBDL)
-CHECK_LIBRARY_EXISTS("${CURL_LIBS}" dlopen "" HAVE_DLOPEN)
-
-# For other tests to use the same libraries
-SET(CMAKE_REQUIRED_LIBRARIES ${CURL_LIBS})
-
-IF(CURL_SPECIAL_LIBZ)
- SET(CURL_LIBS ${CURL_LIBS} "${CURL_SPECIAL_LIBZ}")
- INCLUDE_DIRECTORIES(${CURL_SPECIAL_LIBZ_INCLUDES})
- SET(HAVE_LIBZ 0)
- SET(HAVE_ZLIB_H 0)
-ENDIF(CURL_SPECIAL_LIBZ)
-
-# do we have process.h
-CHECK_INCLUDE_FILE("process.h" HAVE_PROCESS_H)
-
-# If we have features.h, then do the _BSD_SOURCE magic
-CHECK_INCLUDE_FILE("features.h" HAVE_FEATURES_H)
-IF(HAVE_FEATURES_H)
- SET_SOURCE_FILES_PROPERTIES(
- cookie.c
- easy.c
- formdata.c
- getenv.c
- hash.c
- http.c
- if2ip.c
- mprintf.c
- multi.c
- sendf.c
- telnet.c
- transfer.c
- url.c
- COMPILE_FLAGS -D_BSD_SOURCE)
-ENDIF(HAVE_FEATURES_H)
-
-# Check if header file exists and add it to the list.
-MACRO(CHECK_INCLUDE_FILE_CONCAT FILE VARIABLE)
- CHECK_INCLUDE_FILES("${CURL_INCLUDES};${FILE}" ${VARIABLE})
- IF(${VARIABLE})
- SET(CURL_INCLUDES ${CURL_INCLUDES} ${FILE})
- ENDIF(${VARIABLE})
-ENDMACRO(CHECK_INCLUDE_FILE_CONCAT)
+check_library_exists("${CURL_LIBS}" dlopen "" HAVE_DLOPEN)
+
+if(0) # This code not needed for building within CMake.
+option(CURL_ZLIB "Set to ON to enable building cURL with zlib support." ON)
+set(HAVE_LIBZ OFF)
+set(HAVE_ZLIB_H OFF)
+set(HAVE_ZLIB OFF)
+if(CURL_ZLIB)
+ find_package(ZLIB QUIET)
+ if(ZLIB_FOUND)
+ set(HAVE_ZLIB_H ON)
+ set(HAVE_ZLIB ON)
+ set(HAVE_LIBZ ON)
+ list(APPEND CURL_LIBS ${ZLIB_LIBRARIES})
+ include_directories(${ZLIB_INCLUDE_DIRS})
+ endif()
+endif()
+endif()
+
+#-----------------------------------------------------------------------------
+# CMake-specific curl code.
+
+if(CURL_SPECIAL_LIBZ)
+ set(CURL_LIBS ${CURL_LIBS} "${CURL_SPECIAL_LIBZ}")
+ include_directories(${CURL_SPECIAL_LIBZ_INCLUDES})
+ set(HAVE_LIBZ 0)
+ set(HAVE_ZLIB_H 0)
+endif()
+
+#libSSH2
+option(CMAKE_USE_LIBSSH2 "Use libSSH2" ON)
+mark_as_advanced(CMAKE_USE_LIBSSH2)
+set(USE_LIBSSH2 OFF)
+set(HAVE_LIBSSH2 OFF)
+set(HAVE_LIBSSH2_H OFF)
+
+if(CMAKE_USE_LIBSSH2)
+ find_package(LibSSH2)
+ if(LIBSSH2_FOUND)
+ list(APPEND CURL_LIBS ${LIBSSH2_LIBRARY})
+ set(CMAKE_REQUIRED_LIBRARIES ${LIBSSH2_LIBRARY})
+ set(CMAKE_REQUIRED_INCLUDES "${LIBSSH2_INCLUDE_DIR}")
+ include_directories("${LIBSSH2_INCLUDE_DIR}")
+ set(HAVE_LIBSSH2 ON)
+ set(USE_LIBSSH2 ON)
+
+ # find_package has already found the headers
+ set(HAVE_LIBSSH2_H ON)
+ set(CURL_INCLUDES ${CURL_INCLUDES} "${LIBSSH2_INCLUDE_DIR}/libssh2.h")
+ set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -DHAVE_LIBSSH2_H")
+
+ # now check for specific libssh2 symbols as they were added in different versions
+ set(CMAKE_EXTRA_INCLUDE_FILES "libssh2.h")
+ check_function_exists(libssh2_version HAVE_LIBSSH2_VERSION)
+ check_function_exists(libssh2_init HAVE_LIBSSH2_INIT)
+ check_function_exists(libssh2_exit HAVE_LIBSSH2_EXIT)
+ check_function_exists(libssh2_scp_send64 HAVE_LIBSSH2_SCP_SEND64)
+ check_function_exists(libssh2_session_handshake HAVE_LIBSSH2_SESSION_HANDSHAKE)
+ set(CMAKE_EXTRA_INCLUDE_FILES "")
+
+ endif(LIBSSH2_FOUND)
+endif(CMAKE_USE_LIBSSH2)
+
+option(CMAKE_USE_GSSAPI "Use GSSAPI implementation (right now only Heimdal is supported with CMake build)" OFF)
+mark_as_advanced(CMAKE_USE_GSSAPI)
+
+if(CMAKE_USE_GSSAPI)
+ find_package(GSS)
+
+ set(HAVE_GSSAPI ${GSS_FOUND})
+ if(GSS_FOUND)
+
+ message(STATUS "Found ${GSS_FLAVOUR} GSSAPI version: \"${GSS_VERSION}\"")
+
+ set(CMAKE_REQUIRED_INCLUDES ${GSS_INCLUDE_DIR})
+ check_include_file_concat("gssapi/gssapi.h" HAVE_GSSAPI_GSSAPI_H)
+ check_include_file_concat("gssapi/gssapi_generic.h" HAVE_GSSAPI_GSSAPI_GENERIC_H)
+ check_include_file_concat("gssapi/gssapi_krb5.h" HAVE_GSSAPI_GSSAPI_KRB5_H)
+
+ if(GSS_FLAVOUR STREQUAL "Heimdal")
+ set(HAVE_GSSHEIMDAL ON)
+ else() # MIT
+ set(HAVE_GSSMIT ON)
+ set(_INCLUDE_LIST "")
+ if(HAVE_GSSAPI_GSSAPI_H)
+ list(APPEND _INCLUDE_LIST "gssapi/gssapi.h")
+ endif()
+ if(HAVE_GSSAPI_GSSAPI_GENERIC_H)
+ list(APPEND _INCLUDE_LIST "gssapi/gssapi_generic.h")
+ endif()
+ if(HAVE_GSSAPI_GSSAPI_KRB5_H)
+ list(APPEND _INCLUDE_LIST "gssapi/gssapi_krb5.h")
+ endif()
+
+ string(REPLACE ";" " " _COMPILER_FLAGS_STR "${GSS_COMPILER_FLAGS}")
+ string(REPLACE ";" " " _LINKER_FLAGS_STR "${GSS_LINKER_FLAGS}")
+
+ foreach(_dir ${GSS_LINK_DIRECTORIES})
+ set(_LINKER_FLAGS_STR "${_LINKER_FLAGS_STR} -L\"${_dir}\"")
+ endforeach()
+
+ set(CMAKE_REQUIRED_FLAGS "${_COMPILER_FLAGS_STR} ${_LINKER_FLAGS_STR}")
+ set(CMAKE_REQUIRED_LIBRARIES ${GSS_LIBRARIES})
+ check_symbol_exists("GSS_C_NT_HOSTBASED_SERVICE" ${_INCLUDE_LIST} HAVE_GSS_C_NT_HOSTBASED_SERVICE)
+ if(NOT HAVE_GSS_C_NT_HOSTBASED_SERVICE)
+ set(HAVE_OLD_GSSMIT ON)
+ endif()
+
+ endif()
+
+ include_directories(${GSS_INCLUDE_DIR})
+ link_directories(${GSS_LINK_DIRECTORIES})
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GSS_COMPILER_FLAGS}")
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${GSS_LINKER_FLAGS}")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GSS_LINKER_FLAGS}")
+ list(APPEND CURL_LIBS ${GSS_LIBRARIES})
+
+ else()
+ message(WARNING "GSSAPI support has been requested but no supporting libraries found. Skipping.")
+ endif()
+endif()
+
+option(ENABLE_UNIX_SOCKETS "Define if you want Unix domain sockets support" ON)
+if(ENABLE_UNIX_SOCKETS)
+ include(CheckStructHasMember)
+ check_struct_has_member("struct sockaddr_un" sun_path "sys/un.h" USE_UNIX_SOCKETS)
+else()
+ unset(USE_UNIX_SOCKETS CACHE)
+endif()
# Check for header files
-IF(UNIX)
- SET(HAVE_WINDOWS_H 0)
- SET(HAVE_WINSOCK_H 0)
- SET(HAVE_WS2TCPIP_H 0)
- SET(HAVE_WINSOCK2_H 0)
-ENDIF(UNIX)
-IF(NOT UNIX)
- CHECK_INCLUDE_FILE_CONCAT("ws2tcpip.h" HAVE_WS2TCPIP_H)
- CHECK_INCLUDE_FILE_CONCAT("winsock2.h" HAVE_WINSOCK2_H)
-ENDIF(NOT UNIX)
-CHECK_INCLUDE_FILE_CONCAT("stdio.h" HAVE_STDIO_H)
-IF(NOT UNIX)
- CHECK_INCLUDE_FILE_CONCAT("windows.h" HAVE_WINDOWS_H)
- CHECK_INCLUDE_FILE_CONCAT("winsock.h" HAVE_WINSOCK_H)
-ENDIF(NOT UNIX)
-CHECK_INCLUDE_FILE_CONCAT("stddef.h" HAVE_STDDEF_H)
-CHECK_INCLUDE_FILE_CONCAT("sys/types.h" HAVE_SYS_TYPES_H)
-CHECK_INCLUDE_FILE_CONCAT("inttypes.h" HAVE_INTTYPES_H)
-CHECK_INCLUDE_FILE_CONCAT("alloca.h" HAVE_ALLOCA_H)
-CHECK_INCLUDE_FILE_CONCAT("arpa/inet.h" HAVE_ARPA_INET_H)
-CHECK_INCLUDE_FILE_CONCAT("dlfcn.h" HAVE_DLFCN_H)
-CHECK_INCLUDE_FILE_CONCAT("fcntl.h" HAVE_FCNTL_H)
-CHECK_INCLUDE_FILE_CONCAT("malloc.h" HAVE_MALLOC_H)
-CHECK_INCLUDE_FILE_CONCAT("memory.h" HAVE_MEMORY_H)
-CHECK_INCLUDE_FILE_CONCAT("netdb.h" HAVE_NETDB_H)
-CHECK_INCLUDE_FILE_CONCAT("sys/poll.h" HAVE_SYS_POLL_H)
-CHECK_INCLUDE_FILE_CONCAT("assert.h" HAVE_ASSERT_H)
-CHECK_INCLUDE_FILE_CONCAT("limits.h" HAVE_LIMITS_H)
-
-IF(CMAKE_USE_OPENSSL)
- CHECK_INCLUDE_FILE_CONCAT("openssl/x509.h" HAVE_OPENSSL_X509_H)
- CHECK_INCLUDE_FILE_CONCAT("openssl/engine.h" HAVE_OPENSSL_ENGINE_H)
- CHECK_INCLUDE_FILE_CONCAT("openssl/rsa.h" HAVE_OPENSSL_RSA_H)
- CHECK_INCLUDE_FILE_CONCAT("openssl/crypto.h" HAVE_OPENSSL_CRYPTO_H)
- CHECK_INCLUDE_FILE_CONCAT("openssl/pem.h" HAVE_OPENSSL_PEM_H)
- CHECK_INCLUDE_FILE_CONCAT("openssl/ssl.h" HAVE_OPENSSL_SSL_H)
- CHECK_INCLUDE_FILE_CONCAT("openssl/err.h" HAVE_OPENSSL_ERR_H)
- CHECK_INCLUDE_FILE_CONCAT("openssl/rand.h" HAVE_OPENSSL_RAND_H)
- CHECK_INCLUDE_FILE_CONCAT("openssl/pkcs12.h" HAVE_OPENSSL_PKCS12_H)
-ENDIF(CMAKE_USE_OPENSSL)
-
-IF(NOT CURL_SPECIAL_LIBZ)
- CHECK_INCLUDE_FILE_CONCAT("zlib.h" HAVE_ZLIB_H)
-ENDIF(NOT CURL_SPECIAL_LIBZ)
-CHECK_INCLUDE_FILE_CONCAT("sys/socket.h" HAVE_SYS_SOCKET_H)
-CHECK_INCLUDE_FILE_CONCAT("netinet/in.h" HAVE_NETINET_IN_H)
-CHECK_INCLUDE_FILE_CONCAT("net/if.h" HAVE_NET_IF_H)
-CHECK_INCLUDE_FILE_CONCAT("netinet/if_ether.h"
- HAVE_NETINET_IF_ETHER_H)
-CHECK_INCLUDE_FILE_CONCAT("netinet/tcp.h"
- HAVE_NETINET_TCP_H)
-CHECK_INCLUDE_FILE_CONCAT("sys/select.h" HAVE_SYS_SELECT_H)
-CHECK_INCLUDE_FILE_CONCAT("utime.h" HAVE_UTIME_H)
-CHECK_INCLUDE_FILE_CONCAT("netinet/in.h" HAVE_NETINET_IN_H)
-CHECK_INCLUDE_FILE_CONCAT("pwd.h" HAVE_PWD_H)
-CHECK_INCLUDE_FILE_CONCAT("sgtty.h" HAVE_SGTTY_H)
-CHECK_INCLUDE_FILE_CONCAT("stdint.h" HAVE_STDINT_H)
-CHECK_INCLUDE_FILE_CONCAT("stdlib.h" HAVE_STDLIB_H)
-CHECK_INCLUDE_FILE_CONCAT("string.h" HAVE_STRING_H)
-CHECK_INCLUDE_FILE_CONCAT("strings.h" HAVE_STRINGS_H)
-CHECK_INCLUDE_FILE_CONCAT("sys/param.h" HAVE_SYS_PARAM_H)
-CHECK_INCLUDE_FILE_CONCAT("sys/stat.h" HAVE_SYS_STAT_H)
-CHECK_INCLUDE_FILE_CONCAT("sys/time.h" HAVE_SYS_TIME_H)
-CHECK_INCLUDE_FILE_CONCAT("sys/resource.h" HAVE_SYS_RESOURCE_H)
-CHECK_INCLUDE_FILE_CONCAT("termios.h" HAVE_TERMIOS_H)
-CHECK_INCLUDE_FILE_CONCAT("termio.h" HAVE_TERMIO_H)
-CHECK_INCLUDE_FILE_CONCAT("io.h" HAVE_IO_H)
-CHECK_INCLUDE_FILE_CONCAT("time.h" HAVE_TIME_H)
-CHECK_INCLUDE_FILE_CONCAT("unistd.h" HAVE_UNISTD_H)
-CHECK_INCLUDE_FILE_CONCAT("sys/utime.h" HAVE_SYS_UTIME_H)
-CHECK_INCLUDE_FILE_CONCAT("sockio.h" HAVE_SOCKIO_H)
-CHECK_INCLUDE_FILE_CONCAT("sys/sockio.h" HAVE_SYS_SOCKIO_H)
-CHECK_INCLUDE_FILE_CONCAT("x509.h" HAVE_X509_H)
-CHECK_INCLUDE_FILE_CONCAT("locale.h" HAVE_LOCALE_H)
-CHECK_INCLUDE_FILE_CONCAT("setjmp.h" HAVE_SETJMP_H)
-CHECK_INCLUDE_FILE_CONCAT("signal.h" HAVE_SIGNAL_H)
-CHECK_INCLUDE_FILE_CONCAT("sys/ioctl.h" HAVE_SYS_IOCTL_H)
-CHECK_INCLUDE_FILE_CONCAT("sys/utsname.h" HAVE_SYS_UTSNAME_H)
-CHECK_INCLUDE_FILE_CONCAT("idn-free.h" HAVE_IDN_FREE_H)
-CHECK_INCLUDE_FILE_CONCAT("idna.h" HAVE_IDNA_H)
-CHECK_INCLUDE_FILE_CONCAT("tld.h" HAVE_TLD_H)
-CHECK_INCLUDE_FILE_CONCAT("arpa/tftp.h" HAVE_ARPA_TFTP_H)
-CHECK_INCLUDE_FILE_CONCAT("errno.h" HAVE_ERRNO_H)
-CHECK_INCLUDE_FILE_CONCAT("libgen.h" HAVE_LIBGEN_H)
-CHECK_INCLUDE_FILE_CONCAT("sys/filio.h" HAVE_SYS_FILIO_H)
-CHECK_TYPE_SIZE(size_t SIZEOF_SIZE_T)
-CHECK_TYPE_SIZE(ssize_t SIZEOF_SSIZE_T)
-CHECK_TYPE_SIZE("long long" SIZEOF_LONG_LONG)
-CHECK_TYPE_SIZE("long" SIZEOF_LONG)
-CHECK_TYPE_SIZE("__int64" SIZEOF___INT64)
-CHECK_TYPE_SIZE("time_t" SIZEOF_TIME_T)
-
-IF(HAVE_SIZEOF_LONG_LONG)
- SET(HAVE_LONGLONG 1)
- SET(HAVE_LL 1)
-ENDIF(HAVE_SIZEOF_LONG_LONG)
-
-FIND_FILE(RANDOM_FILE urandom /dev)
-MARK_AS_ADVANCED(RANDOM_FILE)
-
-#strtoll \
-#socket \
-#select \
-#strdup \
-#strstr \
-#strtok_r \
-#uname \
-#strcasecmp \
-#stricmp \
-#strcmpi \
-#gethostbyaddr \
-#gettimeofday \
-#inet_addr \
-#inet_ntoa \
-#inet_pton \
-#perror \
-#closesocket \
-#siginterrupt \
-#sigaction \
-#signal \
-#getpass_r \
-#getpwuid \
-#geteuid \
-#dlopen \
-#utime \
-#sigsetjmp \
-#basename \
-#setlocale \
-#ftruncate \
-#pipe \
-#poll \
-#getprotobyname \
-#getrlimit \
-#setrlimit \
-#fork
+if(NOT UNIX)
+ check_include_file_concat("windows.h" HAVE_WINDOWS_H)
+ check_include_file_concat("winsock.h" HAVE_WINSOCK_H)
+ check_include_file_concat("ws2tcpip.h" HAVE_WS2TCPIP_H)
+ check_include_file_concat("winsock2.h" HAVE_WINSOCK2_H)
+else()
+ set(HAVE_WINDOWS_H 0)
+ set(HAVE_WINSOCK_H 0)
+ set(HAVE_WS2TCPIP_H 0)
+ set(HAVE_WINSOCK2_H 0)
+endif()
+
+check_include_file_concat("stdio.h" HAVE_STDIO_H)
+check_include_file_concat("inttypes.h" HAVE_INTTYPES_H)
+check_include_file_concat("sys/filio.h" HAVE_SYS_FILIO_H)
+check_include_file_concat("sys/ioctl.h" HAVE_SYS_IOCTL_H)
+check_include_file_concat("sys/param.h" HAVE_SYS_PARAM_H)
+check_include_file_concat("sys/poll.h" HAVE_SYS_POLL_H)
+check_include_file_concat("sys/resource.h" HAVE_SYS_RESOURCE_H)
+check_include_file_concat("sys/select.h" HAVE_SYS_SELECT_H)
+check_include_file_concat("sys/socket.h" HAVE_SYS_SOCKET_H)
+check_include_file_concat("sys/sockio.h" HAVE_SYS_SOCKIO_H)
+check_include_file_concat("sys/stat.h" HAVE_SYS_STAT_H)
+check_include_file_concat("sys/time.h" HAVE_SYS_TIME_H)
+check_include_file_concat("sys/types.h" HAVE_SYS_TYPES_H)
+check_include_file_concat("sys/uio.h" HAVE_SYS_UIO_H)
+check_include_file_concat("sys/un.h" HAVE_SYS_UN_H)
+check_include_file_concat("sys/utime.h" HAVE_SYS_UTIME_H)
+check_include_file_concat("alloca.h" HAVE_ALLOCA_H)
+check_include_file_concat("arpa/inet.h" HAVE_ARPA_INET_H)
+check_include_file_concat("arpa/tftp.h" HAVE_ARPA_TFTP_H)
+check_include_file_concat("assert.h" HAVE_ASSERT_H)
+check_include_file_concat("crypto.h" HAVE_CRYPTO_H)
+check_include_file_concat("des.h" HAVE_DES_H)
+check_include_file_concat("err.h" HAVE_ERR_H)
+check_include_file_concat("errno.h" HAVE_ERRNO_H)
+check_include_file_concat("fcntl.h" HAVE_FCNTL_H)
+check_include_file_concat("idn-free.h" HAVE_IDN_FREE_H)
+check_include_file_concat("ifaddrs.h" HAVE_IFADDRS_H)
+check_include_file_concat("io.h" HAVE_IO_H)
+check_include_file_concat("krb.h" HAVE_KRB_H)
+check_include_file_concat("libgen.h" HAVE_LIBGEN_H)
+check_include_file_concat("limits.h" HAVE_LIMITS_H)
+check_include_file_concat("locale.h" HAVE_LOCALE_H)
+check_include_file_concat("net/if.h" HAVE_NET_IF_H)
+check_include_file_concat("netdb.h" HAVE_NETDB_H)
+check_include_file_concat("netinet/in.h" HAVE_NETINET_IN_H)
+check_include_file_concat("netinet/tcp.h" HAVE_NETINET_TCP_H)
+
+check_include_file_concat("pem.h" HAVE_PEM_H)
+check_include_file_concat("poll.h" HAVE_POLL_H)
+check_include_file_concat("pwd.h" HAVE_PWD_H)
+check_include_file_concat("rsa.h" HAVE_RSA_H)
+check_include_file_concat("setjmp.h" HAVE_SETJMP_H)
+check_include_file_concat("sgtty.h" HAVE_SGTTY_H)
+check_include_file_concat("signal.h" HAVE_SIGNAL_H)
+check_include_file_concat("ssl.h" HAVE_SSL_H)
+check_include_file_concat("stdbool.h" HAVE_STDBOOL_H)
+check_include_file_concat("stdint.h" HAVE_STDINT_H)
+check_include_file_concat("stdio.h" HAVE_STDIO_H)
+check_include_file_concat("stdlib.h" HAVE_STDLIB_H)
+check_include_file_concat("string.h" HAVE_STRING_H)
+check_include_file_concat("strings.h" HAVE_STRINGS_H)
+check_include_file_concat("stropts.h" HAVE_STROPTS_H)
+check_include_file_concat("termio.h" HAVE_TERMIO_H)
+check_include_file_concat("termios.h" HAVE_TERMIOS_H)
+check_include_file_concat("time.h" HAVE_TIME_H)
+check_include_file_concat("tld.h" HAVE_TLD_H)
+check_include_file_concat("unistd.h" HAVE_UNISTD_H)
+check_include_file_concat("utime.h" HAVE_UTIME_H)
+check_include_file_concat("x509.h" HAVE_X509_H)
+
+check_include_file_concat("process.h" HAVE_PROCESS_H)
+check_include_file_concat("stddef.h" HAVE_STDDEF_H)
+check_include_file_concat("dlfcn.h" HAVE_DLFCN_H)
+check_include_file_concat("malloc.h" HAVE_MALLOC_H)
+check_include_file_concat("memory.h" HAVE_MEMORY_H)
+check_include_file_concat("netinet/if_ether.h" HAVE_NETINET_IF_ETHER_H)
+check_include_file_concat("stdint.h" HAVE_STDINT_H)
+check_include_file_concat("sockio.h" HAVE_SOCKIO_H)
+check_include_file_concat("sys/utsname.h" HAVE_SYS_UTSNAME_H)
+check_include_file_concat("idna.h" HAVE_IDNA_H)
+
+
+
+check_type_size(size_t SIZEOF_SIZE_T)
+check_type_size(ssize_t SIZEOF_SSIZE_T)
+check_type_size("long long" SIZEOF_LONG_LONG)
+check_type_size("long" SIZEOF_LONG)
+check_type_size("short" SIZEOF_SHORT)
+check_type_size("int" SIZEOF_INT)
+check_type_size("__int64" SIZEOF___INT64)
+check_type_size("time_t" SIZEOF_TIME_T)
+check_type_size("off_t" SIZEOF_OFF_T)
+
+# Make public versions of some type sizes for curlbuild.h.
+foreach(t INT LONG LONG_LONG SSIZE_T)
+ string(REPLACE "SIZEOF_" "CURL_SIZEOF_" CURL_SIZEOF_${t}_CODE "${SIZEOF_${t}_CODE}")
+endforeach()
+
+if(HAVE_SIZEOF_LONG_LONG)
+ set(HAVE_LONGLONG 1)
+ set(HAVE_LL 1)
+endif(HAVE_SIZEOF_LONG_LONG)
+
+find_file(RANDOM_FILE urandom /dev)
+mark_as_advanced(RANDOM_FILE)
# Check for some functions that are used
-CHECK_SYMBOL_EXISTS(basename "${CURL_INCLUDES}" HAVE_BASENAME)
-CHECK_SYMBOL_EXISTS(socket "${CURL_INCLUDES}" HAVE_SOCKET)
-CHECK_SYMBOL_EXISTS(poll "${CURL_INCLUDES}" HAVE_POLL)
-CHECK_SYMBOL_EXISTS(select "${CURL_INCLUDES}" HAVE_SELECT)
-CHECK_SYMBOL_EXISTS(strdup "${CURL_INCLUDES}" HAVE_STRDUP)
-CHECK_SYMBOL_EXISTS(strstr "${CURL_INCLUDES}" HAVE_STRSTR)
-CHECK_SYMBOL_EXISTS(strtok_r "${CURL_INCLUDES}" HAVE_STRTOK_R)
-CHECK_SYMBOL_EXISTS(strftime "${CURL_INCLUDES}" HAVE_STRFTIME)
-CHECK_SYMBOL_EXISTS(uname "${CURL_INCLUDES}" HAVE_UNAME)
-CHECK_SYMBOL_EXISTS(strcasecmp "${CURL_INCLUDES}" HAVE_STRCASECMP)
-CHECK_SYMBOL_EXISTS(stricmp "${CURL_INCLUDES}" HAVE_STRICMP)
-CHECK_SYMBOL_EXISTS(strcmpi "${CURL_INCLUDES}" HAVE_STRCMPI)
-CHECK_SYMBOL_EXISTS(strncmpi "${CURL_INCLUDES}" HAVE_STRNCMPI)
-CHECK_SYMBOL_EXISTS(basename "${CURL_INCLUDES}" HAVE_BASENAME)
-IF(NOT HAVE_STRNCMPI)
- SET(HAVE_STRCMPI)
-ENDIF(NOT HAVE_STRNCMPI)
-CHECK_SYMBOL_EXISTS(gethostbyaddr "${CURL_INCLUDES}" HAVE_GETHOSTBYADDR)
-CHECK_SYMBOL_EXISTS(gettimeofday "${CURL_INCLUDES}" HAVE_GETTIMEOFDAY)
-CHECK_SYMBOL_EXISTS(inet_addr "${CURL_INCLUDES}" HAVE_INET_ADDR)
-# windows only has this for vista, but will link with it and say
-# that it has it at link time! So, force it off
-IF(WIN32)
- SET(HAVE_INET_PTON 0 CACHE "" INTERNAL )
-ENDIF(WIN32)
-CHECK_SYMBOL_EXISTS(inet_pton "${CURL_INCLUDES}" HAVE_INET_PTON)
-CHECK_SYMBOL_EXISTS(inet_ntoa "${CURL_INCLUDES}" HAVE_INET_NTOA)
-CHECK_SYMBOL_EXISTS(inet_ntoa_r "${CURL_INCLUDES}" HAVE_INET_NTOA_R)
-CHECK_SYMBOL_EXISTS(tcsetattr "${CURL_INCLUDES}" HAVE_TCSETATTR)
-CHECK_SYMBOL_EXISTS(tcgetattr "${CURL_INCLUDES}" HAVE_TCGETATTR)
-CHECK_SYMBOL_EXISTS(perror "${CURL_INCLUDES}" HAVE_PERROR)
-CHECK_SYMBOL_EXISTS(closesocket "${CURL_INCLUDES}" HAVE_CLOSESOCKET)
-CHECK_SYMBOL_EXISTS(setvbuf "${CURL_INCLUDES}" HAVE_SETVBUF)
-CHECK_SYMBOL_EXISTS(sigsetjmp "${CURL_INCLUDES}" HAVE_SIGSETJMP)
-CHECK_SYMBOL_EXISTS(getpass_r "${CURL_INCLUDES}" HAVE_GETPASS_R)
-CHECK_SYMBOL_EXISTS(getpwuid "${CURL_INCLUDES}" HAVE_GETPWUID)
-CHECK_SYMBOL_EXISTS(geteuid "${CURL_INCLUDES}" HAVE_GETEUID)
-CHECK_SYMBOL_EXISTS(utime "${CURL_INCLUDES}" HAVE_UTIME)
-IF(CMAKE_USE_OPENSSL)
- CHECK_SYMBOL_EXISTS(RAND_status "${CURL_INCLUDES}" HAVE_RAND_STATUS)
- CHECK_SYMBOL_EXISTS(RAND_screen "${CURL_INCLUDES}" HAVE_RAND_SCREEN)
- CHECK_SYMBOL_EXISTS(RAND_egd "${CURL_INCLUDES}" HAVE_RAND_EGD)
- CHECK_SYMBOL_EXISTS(CRYPTO_cleanup_all_ex_data "${CURL_INCLUDES}"
+if(HAVE_LIBWS2_32)
+ set(CMAKE_REQUIRED_LIBRARIES ws2_32)
+elseif(HAVE_LIBSOCKET)
+ set(CMAKE_REQUIRED_LIBRARIES socket)
+endif()
+
+check_symbol_exists(basename "${CURL_INCLUDES}" HAVE_BASENAME)
+check_symbol_exists(socket "${CURL_INCLUDES}" HAVE_SOCKET)
+check_symbol_exists(poll "${CURL_INCLUDES}" HAVE_POLL)
+check_symbol_exists(select "${CURL_INCLUDES}" HAVE_SELECT)
+check_symbol_exists(strdup "${CURL_INCLUDES}" HAVE_STRDUP)
+check_symbol_exists(strstr "${CURL_INCLUDES}" HAVE_STRSTR)
+check_symbol_exists(strtok_r "${CURL_INCLUDES}" HAVE_STRTOK_R)
+check_symbol_exists(strftime "${CURL_INCLUDES}" HAVE_STRFTIME)
+check_symbol_exists(uname "${CURL_INCLUDES}" HAVE_UNAME)
+check_symbol_exists(strcasecmp "${CURL_INCLUDES}" HAVE_STRCASECMP)
+check_symbol_exists(stricmp "${CURL_INCLUDES}" HAVE_STRICMP)
+check_symbol_exists(strcmpi "${CURL_INCLUDES}" HAVE_STRCMPI)
+check_symbol_exists(strncmpi "${CURL_INCLUDES}" HAVE_STRNCMPI)
+check_symbol_exists(alarm "${CURL_INCLUDES}" HAVE_ALARM)
+if(NOT HAVE_STRNCMPI)
+ set(HAVE_STRCMPI)
+endif(NOT HAVE_STRNCMPI)
+check_symbol_exists(gethostbyaddr "${CURL_INCLUDES}" HAVE_GETHOSTBYADDR)
+check_symbol_exists(gethostbyaddr_r "${CURL_INCLUDES}" HAVE_GETHOSTBYADDR_R)
+check_symbol_exists(gettimeofday "${CURL_INCLUDES}" HAVE_GETTIMEOFDAY)
+check_symbol_exists(inet_addr "${CURL_INCLUDES}" HAVE_INET_ADDR)
+check_symbol_exists(inet_ntoa "${CURL_INCLUDES}" HAVE_INET_NTOA)
+check_symbol_exists(inet_ntoa_r "${CURL_INCLUDES}" HAVE_INET_NTOA_R)
+check_symbol_exists(tcsetattr "${CURL_INCLUDES}" HAVE_TCSETATTR)
+check_symbol_exists(tcgetattr "${CURL_INCLUDES}" HAVE_TCGETATTR)
+check_symbol_exists(perror "${CURL_INCLUDES}" HAVE_PERROR)
+check_symbol_exists(closesocket "${CURL_INCLUDES}" HAVE_CLOSESOCKET)
+check_symbol_exists(setvbuf "${CURL_INCLUDES}" HAVE_SETVBUF)
+check_symbol_exists(sigsetjmp "${CURL_INCLUDES}" HAVE_SIGSETJMP)
+check_symbol_exists(getpass_r "${CURL_INCLUDES}" HAVE_GETPASS_R)
+check_symbol_exists(strlcat "${CURL_INCLUDES}" HAVE_STRLCAT)
+check_symbol_exists(getpwuid "${CURL_INCLUDES}" HAVE_GETPWUID)
+check_symbol_exists(geteuid "${CURL_INCLUDES}" HAVE_GETEUID)
+check_symbol_exists(utime "${CURL_INCLUDES}" HAVE_UTIME)
+if(CMAKE_USE_OPENSSL)
+ check_symbol_exists(RAND_status "${CURL_INCLUDES}" HAVE_RAND_STATUS)
+ check_symbol_exists(RAND_screen "${CURL_INCLUDES}" HAVE_RAND_SCREEN)
+ check_symbol_exists(RAND_egd "${CURL_INCLUDES}" HAVE_RAND_EGD)
+ check_symbol_exists(CRYPTO_cleanup_all_ex_data "${CURL_INCLUDES}"
HAVE_CRYPTO_CLEANUP_ALL_EX_DATA)
-ENDIF(CMAKE_USE_OPENSSL)
-CHECK_SYMBOL_EXISTS(gmtime_r "${CURL_INCLUDES}" HAVE_GMTIME_R)
-CHECK_SYMBOL_EXISTS(localtime_r "${CURL_INCLUDES}" HAVE_LOCALTIME_R)
-
-CHECK_SYMBOL_EXISTS(gethostbyname "${CURL_INCLUDES}" HAVE_GETHOSTBYNAME)
-CHECK_SYMBOL_EXISTS(gethostbyname_r "${CURL_INCLUDES}" HAVE_GETHOSTBYNAME_R)
-CHECK_SYMBOL_EXISTS(gethostbyaddr_r "${CURL_INCLUDES}" HAVE_GETHOSTBYADDR_R)
-
-CHECK_SYMBOL_EXISTS(signal "${CURL_INCLUDES}" HAVE_SIGNAL_FUNC)
-CHECK_SYMBOL_EXISTS(SIGALRM "${CURL_INCLUDES}" HAVE_SIGNAL_MACRO)
-IF(HAVE_SIGNAL_FUNC AND HAVE_SIGNAL_MACRO)
- SET(HAVE_SIGNAL 1)
-ENDIF(HAVE_SIGNAL_FUNC AND HAVE_SIGNAL_MACRO)
-CHECK_SYMBOL_EXISTS(uname "${CURL_INCLUDES}" HAVE_UNAME)
-CHECK_SYMBOL_EXISTS(strtoll "${CURL_INCLUDES}" HAVE_STRTOLL)
-CHECK_SYMBOL_EXISTS(_strtoi64 "${CURL_INCLUDES}" HAVE__STRTOI64)
-CHECK_SYMBOL_EXISTS(strerror_r "${CURL_INCLUDES}" HAVE_STRERROR_R)
-CHECK_SYMBOL_EXISTS(siginterrupt "${CURL_INCLUDES}" HAVE_SIGINTERRUPT)
-CHECK_SYMBOL_EXISTS(perror "${CURL_INCLUDES}" HAVE_PERROR)
-CHECK_SYMBOL_EXISTS(fork "${CURL_INCLUDES}" HAVE_FORK)
-CHECK_SYMBOL_EXISTS(pipe "${CURL_INCLUDES}" HAVE_PIPE)
-CHECK_SYMBOL_EXISTS(ftruncate "${CURL_INCLUDES}" HAVE_FTRUNCATE)
-CHECK_SYMBOL_EXISTS(getprotobyname "${CURL_INCLUDES}" HAVE_GETPROTOBYNAME)
-CHECK_SYMBOL_EXISTS(getrlimit "${CURL_INCLUDES}" HAVE_GETRLIMIT)
-CHECK_SYMBOL_EXISTS(idn_free "${CURL_INCLUDES}" HAVE_IDN_FREE)
-CHECK_SYMBOL_EXISTS(idna_strerror "${CURL_INCLUDES}" HAVE_IDNA_STRERROR)
-CHECK_SYMBOL_EXISTS(tld_strerror "${CURL_INCLUDES}" HAVE_TLD_STRERROR)
-CHECK_SYMBOL_EXISTS(setlocale "${CURL_INCLUDES}" HAVE_SETLOCALE)
-CHECK_SYMBOL_EXISTS(setrlimit "${CURL_INCLUDES}" HAVE_SETRLIMIT)
-
-# only build compat strtok if we need to
-IF (NOT HAVE_STRTOK_R)
- SET(libCurl_SRCS ${libCurl_SRCS}
- strtok.c
- )
-ENDIF (NOT HAVE_STRTOK_R)
-
-# only build compat strtoofft if we need to
-IF(NOT HAVE_STRTOLL AND NOT HAVE__STRTOI64)
- SET(libCurl_SRCS ${libCurl_SRCS}
- strtoofft.c
- )
-ENDIF(NOT HAVE_STRTOLL AND NOT HAVE__STRTOI64)
+ if(HAVE_LIBCRYPTO AND HAVE_LIBSSL)
+ set(USE_OPENSSL 1)
+ endif(HAVE_LIBCRYPTO AND HAVE_LIBSSL)
+endif(CMAKE_USE_OPENSSL)
+check_symbol_exists(gmtime_r "${CURL_INCLUDES}" HAVE_GMTIME_R)
+check_symbol_exists(localtime_r "${CURL_INCLUDES}" HAVE_LOCALTIME_R)
+
+check_symbol_exists(gethostbyname "${CURL_INCLUDES}" HAVE_GETHOSTBYNAME)
+check_symbol_exists(gethostbyname_r "${CURL_INCLUDES}" HAVE_GETHOSTBYNAME_R)
+
+check_symbol_exists(signal "${CURL_INCLUDES}" HAVE_SIGNAL_FUNC)
+check_symbol_exists(SIGALRM "${CURL_INCLUDES}" HAVE_SIGNAL_MACRO)
+if(HAVE_SIGNAL_FUNC AND HAVE_SIGNAL_MACRO)
+ set(HAVE_SIGNAL 1)
+endif(HAVE_SIGNAL_FUNC AND HAVE_SIGNAL_MACRO)
+check_symbol_exists(uname "${CURL_INCLUDES}" HAVE_UNAME)
+check_symbol_exists(strtoll "${CURL_INCLUDES}" HAVE_STRTOLL)
+check_symbol_exists(_strtoi64 "${CURL_INCLUDES}" HAVE__STRTOI64)
+check_symbol_exists(strerror_r "${CURL_INCLUDES}" HAVE_STRERROR_R)
+check_symbol_exists(siginterrupt "${CURL_INCLUDES}" HAVE_SIGINTERRUPT)
+check_symbol_exists(perror "${CURL_INCLUDES}" HAVE_PERROR)
+check_symbol_exists(fork "${CURL_INCLUDES}" HAVE_FORK)
+check_symbol_exists(getaddrinfo "${CURL_INCLUDES}" HAVE_GETADDRINFO)
+check_symbol_exists(freeaddrinfo "${CURL_INCLUDES}" HAVE_FREEADDRINFO)
+check_symbol_exists(freeifaddrs "${CURL_INCLUDES}" HAVE_FREEIFADDRS)
+check_symbol_exists(pipe "${CURL_INCLUDES}" HAVE_PIPE)
+check_symbol_exists(ftruncate "${CURL_INCLUDES}" HAVE_FTRUNCATE)
+check_symbol_exists(getprotobyname "${CURL_INCLUDES}" HAVE_GETPROTOBYNAME)
+check_symbol_exists(getrlimit "${CURL_INCLUDES}" HAVE_GETRLIMIT)
+check_symbol_exists(idn_free "${CURL_INCLUDES}" HAVE_IDN_FREE)
+check_symbol_exists(idna_strerror "${CURL_INCLUDES}" HAVE_IDNA_STRERROR)
+check_symbol_exists(tld_strerror "${CURL_INCLUDES}" HAVE_TLD_STRERROR)
+check_symbol_exists(setlocale "${CURL_INCLUDES}" HAVE_SETLOCALE)
+check_symbol_exists(setrlimit "${CURL_INCLUDES}" HAVE_SETRLIMIT)
+check_symbol_exists(fcntl "${CURL_INCLUDES}" HAVE_FCNTL)
+check_symbol_exists(ioctl "${CURL_INCLUDES}" HAVE_IOCTL)
+check_symbol_exists(setsockopt "${CURL_INCLUDES}" HAVE_SETSOCKOPT)
+
+# symbol exists in win32, but function does not.
+check_function_exists(inet_pton HAVE_INET_PTON)
# sigaction and sigsetjmp are special. Use special mechanism for
# detecting those, but only if previous attempt failed.
-IF(HAVE_SIGNAL_H)
- CHECK_SYMBOL_EXISTS(sigaction "signal.h" HAVE_SIGACTION)
-ENDIF(HAVE_SIGNAL_H)
-
-IF(NOT HAVE_SIGSETJMP)
- IF(HAVE_SETJMP_H)
- CHECK_SYMBOL_EXISTS(sigsetjmp "setjmp.h" HAVE_MACRO_SIGSETJMP)
- IF(HAVE_MACRO_SIGSETJMP)
- SET(HAVE_SIGSETJMP 1)
- ENDIF(HAVE_MACRO_SIGSETJMP)
- ENDIF(HAVE_SETJMP_H)
-ENDIF(NOT HAVE_SIGSETJMP)
-
-# For other curl specific tests, use this macro.
-MACRO(CURL_INTERNAL_TEST CURL_TEST)
- IF("${CURL_TEST}" MATCHES "^${CURL_TEST}$")
- SET(MACRO_CHECK_FUNCTION_DEFINITIONS
- "-D${CURL_TEST} ${CMAKE_REQUIRED_FLAGS}")
- IF(CMAKE_REQUIRED_LIBRARIES)
- SET(CURL_TEST_ADD_LIBRARIES
- "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
- ENDIF(CMAKE_REQUIRED_LIBRARIES)
-
- MESSAGE(STATUS "Performing Curl Test ${CURL_TEST}")
- TRY_COMPILE(${CURL_TEST}
- ${CMAKE_BINARY_DIR}
- ${LIBCURL_SOURCE_DIR}/CMake/CurlTests.c
- CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
- "${CURL_TEST_ADD_LIBRARIES}"
- OUTPUT_VARIABLE OUTPUT)
- IF(${CURL_TEST})
- SET(${CURL_TEST} 1 CACHE INTERNAL "Curl test ${FUNCTION}")
- MESSAGE(STATUS "Performing Curl Test ${CURL_TEST} - Success")
- FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
- "Performing Curl Test ${CURL_TEST} passed with the following output:\n"
- "${OUTPUT}\n")
- ELSE(${CURL_TEST})
- MESSAGE(STATUS "Performing Curl Test ${CURL_TEST} - Failed")
- SET(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}")
- FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
- "Performing Curl Test ${CURL_TEST} failed with the following output:\n"
- "${OUTPUT}\n")
- ENDIF(${CURL_TEST})
- ENDIF("${CURL_TEST}" MATCHES "^${CURL_TEST}$")
-ENDMACRO(CURL_INTERNAL_TEST)
+if(HAVE_SIGNAL_H)
+ check_symbol_exists(sigaction "signal.h" HAVE_SIGACTION)
+endif(HAVE_SIGNAL_H)
+
+if(NOT HAVE_SIGSETJMP)
+ if(HAVE_SETJMP_H)
+ check_symbol_exists(sigsetjmp "setjmp.h" HAVE_MACRO_SIGSETJMP)
+ if(HAVE_MACRO_SIGSETJMP)
+ set(HAVE_SIGSETJMP 1)
+ endif(HAVE_MACRO_SIGSETJMP)
+ endif(HAVE_SETJMP_H)
+endif(NOT HAVE_SIGSETJMP)
+
+# If there is no stricmp(), do not allow LDAP to parse URLs
+if(NOT HAVE_STRICMP)
+ set(HAVE_LDAP_URL_PARSE 1)
+endif(NOT HAVE_STRICMP)
# Do curl specific tests
-#OPTION(CURL_HAVE_DISABLED_NONBLOCKING "Disable non-blocking socket detection" OFF)
-SET(CURL_NONBLOCKING_TESTS)
-IF(NOT CURL_HAVE_DISABLED_NONBLOCKING)
- SET(CURL_NONBLOCKING_TESTS
- HAVE_FIONBIO
+foreach(CURL_TEST
+ HAVE_FCNTL_O_NONBLOCK
HAVE_IOCTLSOCKET
- HAVE_IOCTLSOCKET_CASE
- HAVE_O_NONBLOCK
- HAVE_SO_NONBLOCK
- )
-ENDIF(NOT CURL_HAVE_DISABLED_NONBLOCKING)
-FOREACH(CURL_TEST
- ${CURL_NONBLOCKING_TESTS}
+ HAVE_IOCTLSOCKET_CAMEL
+ HAVE_IOCTLSOCKET_CAMEL_FIONBIO
+ HAVE_IOCTLSOCKET_FIONBIO
+ HAVE_IOCTL_FIONBIO
+ HAVE_IOCTL_SIOCGIFADDR
+ HAVE_SETSOCKOPT_SO_NONBLOCK
+ HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
TIME_WITH_SYS_TIME
- HAVE_O_NONBLOCKHAVE_GETHOSTBYADDR_R_5
+ HAVE_O_NONBLOCK
+ HAVE_GETHOSTBYADDR_R_5
HAVE_GETHOSTBYADDR_R_7
HAVE_GETHOSTBYADDR_R_8
HAVE_GETHOSTBYADDR_R_5_REENTRANT
@@ -557,6 +910,7 @@ FOREACH(CURL_TEST
HAVE_GETHOSTBYNAME_R_6_REENTRANT
HAVE_SOCKLEN_T
HAVE_IN_ADDR_T
+ HAVE_BOOL_T
STDC_HEADERS
RETSIGTYPE_TEST
HAVE_INET_NTOA_R_DECL
@@ -564,14 +918,20 @@ FOREACH(CURL_TEST
HAVE_GETADDRINFO
HAVE_FILE_OFFSET_BITS
)
- CURL_INTERNAL_TEST(${CURL_TEST})
-ENDFOREACH(CURL_TEST)
-IF(HAVE_FILE_OFFSET_BITS)
- SET(_FILE_OFFSET_BITS 64)
-ENDIF(HAVE_FILE_OFFSET_BITS)
+ curl_internal_test(${CURL_TEST})
+endforeach(CURL_TEST)
+if(HAVE_FILE_OFFSET_BITS)
+ set(_FILE_OFFSET_BITS 64)
+endif(HAVE_FILE_OFFSET_BITS)
+foreach(CURL_TEST
+ HAVE_GLIBC_STRERROR_R
+ HAVE_POSIX_STRERROR_R
+ )
+ curl_internal_test_run(${CURL_TEST})
+endforeach(CURL_TEST)
# Check for reentrant
-FOREACH(CURL_TEST
+foreach(CURL_TEST
HAVE_GETHOSTBYADDR_R_5
HAVE_GETHOSTBYADDR_R_7
HAVE_GETHOSTBYADDR_R_8
@@ -579,156 +939,323 @@ FOREACH(CURL_TEST
HAVE_GETHOSTBYNAME_R_5
HAVE_GETHOSTBYNAME_R_6
HAVE_INET_NTOA_R_DECL_REENTRANT)
- IF(NOT ${CURL_TEST})
- IF(${CURL_TEST}_REENTRANT)
- SET(NEED_REENTRANT 1)
- ENDIF(${CURL_TEST}_REENTRANT)
- ENDIF(NOT ${CURL_TEST})
-ENDFOREACH(CURL_TEST)
-
-IF(NEED_REENTRANT)
- FOREACH(CURL_TEST
+ if(NOT ${CURL_TEST})
+ if(${CURL_TEST}_REENTRANT)
+ set(NEED_REENTRANT 1)
+ endif(${CURL_TEST}_REENTRANT)
+ endif(NOT ${CURL_TEST})
+endforeach(CURL_TEST)
+
+if(NEED_REENTRANT)
+ foreach(CURL_TEST
HAVE_GETHOSTBYADDR_R_5
HAVE_GETHOSTBYADDR_R_7
HAVE_GETHOSTBYADDR_R_8
HAVE_GETHOSTBYNAME_R_3
HAVE_GETHOSTBYNAME_R_5
HAVE_GETHOSTBYNAME_R_6)
- SET(${CURL_TEST} 0)
- IF(${CURL_TEST}_REENTRANT)
- SET(${CURL_TEST} 1)
- ENDIF(${CURL_TEST}_REENTRANT)
- ENDFOREACH(CURL_TEST)
-ENDIF(NEED_REENTRANT)
-
-IF(HAVE_INET_NTOA_R_DECL_REENTRANT)
- SET(HAVE_INET_NTOA_R_DECL 1)
- SET(NEED_REENTRANT 1)
-ENDIF(HAVE_INET_NTOA_R_DECL_REENTRANT)
+ set(${CURL_TEST} 0)
+ if(${CURL_TEST}_REENTRANT)
+ set(${CURL_TEST} 1)
+ endif(${CURL_TEST}_REENTRANT)
+ endforeach(CURL_TEST)
+endif(NEED_REENTRANT)
+
+if(HAVE_INET_NTOA_R_DECL_REENTRANT)
+ set(HAVE_INET_NTOA_R_DECL 1)
+ set(NEED_REENTRANT 1)
+endif(HAVE_INET_NTOA_R_DECL_REENTRANT)
# Some other minor tests
-IF(NOT HAVE_SOCKLEN_T)
- SET(socklen_t "int")
-ENDIF(NOT HAVE_SOCKLEN_T)
-
-IF(NOT HAVE_IN_ADDR_T)
- SET(in_addr_t "unsigned long")
-ENDIF(NOT HAVE_IN_ADDR_T)
+if(NOT HAVE_IN_ADDR_T)
+ set(in_addr_t "unsigned long")
+endif(NOT HAVE_IN_ADDR_T)
# Fix libz / zlib.h
-IF(NOT CURL_SPECIAL_LIBZ)
- IF(NOT HAVE_LIBZ)
- SET(HAVE_ZLIB_H 0)
- ENDIF(NOT HAVE_LIBZ)
+if(NOT CURL_SPECIAL_LIBZ)
+ if(NOT HAVE_LIBZ)
+ set(HAVE_ZLIB_H 0)
+ endif(NOT HAVE_LIBZ)
- IF(NOT HAVE_ZLIB_H)
- SET(HAVE_LIBZ 0)
- ENDIF(NOT HAVE_ZLIB_H)
-ENDIF(NOT CURL_SPECIAL_LIBZ)
+ if(NOT HAVE_ZLIB_H)
+ set(HAVE_LIBZ 0)
+ endif(NOT HAVE_ZLIB_H)
+endif(NOT CURL_SPECIAL_LIBZ)
-IF(_FILE_OFFSET_BITS)
- SET(_FILE_OFFSET_BITS 64)
-ENDIF(_FILE_OFFSET_BITS)
-SET(CMAKE_REQUIRED_FLAGS "-D_FILE_OFFSET_BITS=64")
-SET(CMAKE_EXTRA_INCLUDE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/curl/curl.h")
-CHECK_TYPE_SIZE("curl_off_t" SIZEOF_CURL_OFF_T)
-SET(CMAKE_EXTRA_INCLUDE_FILES)
-SET(CMAKE_REQUIRED_FLAGS)
+if(_FILE_OFFSET_BITS)
+ set(_FILE_OFFSET_BITS 64)
+endif(_FILE_OFFSET_BITS)
+set(CMAKE_REQUIRED_FLAGS "-D_FILE_OFFSET_BITS=64")
+set(CMAKE_EXTRA_INCLUDE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/curl/curl.h")
+check_type_size("curl_off_t" SIZEOF_CURL_OFF_T)
+set(CMAKE_EXTRA_INCLUDE_FILES)
+set(CMAKE_REQUIRED_FLAGS)
# Check for nonblocking
-SET(HAVE_DISABLED_NONBLOCKING 1)
-IF(HAVE_FIONBIO OR
+set(HAVE_DISABLED_NONBLOCKING 1)
+if(HAVE_FIONBIO OR
HAVE_IOCTLSOCKET OR
HAVE_IOCTLSOCKET_CASE OR
HAVE_O_NONBLOCK)
- SET(HAVE_DISABLED_NONBLOCKING)
-ENDIF(HAVE_FIONBIO OR
+ set(HAVE_DISABLED_NONBLOCKING)
+endif(HAVE_FIONBIO OR
HAVE_IOCTLSOCKET OR
HAVE_IOCTLSOCKET_CASE OR
HAVE_O_NONBLOCK)
-IF(RETSIGTYPE_TEST)
- SET(RETSIGTYPE void)
-ELSE(RETSIGTYPE_TEST)
- SET(RETSIGTYPE int)
-ENDIF(RETSIGTYPE_TEST)
+if(RETSIGTYPE_TEST)
+ set(RETSIGTYPE void)
+else(RETSIGTYPE_TEST)
+ set(RETSIGTYPE int)
+endif(RETSIGTYPE_TEST)
-IF(CMAKE_COMPILER_IS_GNUCC AND APPLE)
- INCLUDE(CheckCCompilerFlag)
- CHECK_C_COMPILER_FLAG(-Wno-long-double HAVE_C_FLAG_Wno_long_double)
- IF(HAVE_C_FLAG_Wno_long_double)
+if(CMAKE_COMPILER_IS_GNUCC AND APPLE)
+ include(CheckCCompilerFlag)
+ check_c_compiler_flag(-Wno-long-double HAVE_C_FLAG_Wno_long_double)
+ if(HAVE_C_FLAG_Wno_long_double)
# The Mac version of GCC warns about use of long double. Disable it.
- GET_SOURCE_FILE_PROPERTY(MPRINTF_COMPILE_FLAGS mprintf.c COMPILE_FLAGS)
- IF(MPRINTF_COMPILE_FLAGS)
- SET(MPRINTF_COMPILE_FLAGS "${MPRINTF_COMPILE_FLAGS} -Wno-long-double")
- ELSE(MPRINTF_COMPILE_FLAGS)
- SET(MPRINTF_COMPILE_FLAGS "-Wno-long-double")
- ENDIF(MPRINTF_COMPILE_FLAGS)
- SET_SOURCE_FILES_PROPERTIES(mprintf.c PROPERTIES
+ get_source_file_property(MPRINTF_COMPILE_FLAGS mprintf.c COMPILE_FLAGS)
+ if(MPRINTF_COMPILE_FLAGS)
+ set(MPRINTF_COMPILE_FLAGS "${MPRINTF_COMPILE_FLAGS} -Wno-long-double")
+ else(MPRINTF_COMPILE_FLAGS)
+ set(MPRINTF_COMPILE_FLAGS "-Wno-long-double")
+ endif(MPRINTF_COMPILE_FLAGS)
+ set_source_files_properties(mprintf.c PROPERTIES
COMPILE_FLAGS ${MPRINTF_COMPILE_FLAGS})
- ENDIF(HAVE_C_FLAG_Wno_long_double)
-ENDIF(CMAKE_COMPILER_IS_GNUCC AND APPLE)
-
-INCLUDE(CMake/OtherTests.cmake)
-
-# The rest of the build
-
-INCLUDE_DIRECTORIES(${LIBCURL_SOURCE_DIR})
-INCLUDE_DIRECTORIES(${LIBCURL_BINARY_DIR})
-OPTION(CMAKE_BUILD_CURL_SHARED "Should curl be built shared" TRUE)
-IF(CMAKE_BUILD_CURL_SHARED)
- SET(LIBRARY_TYPE SHARED)
- ADD_DEFINITIONS(-DHAVE_CONFIG_H)
-ELSE(CMAKE_BUILD_CURL_SHARED)
- ADD_DEFINITIONS(-DHAVE_CONFIG_H
- -DCURL_STATICLIB)
-ENDIF(CMAKE_BUILD_CURL_SHARED)
-SET(CURL_STATICLIB)
-
-# Support CheckTypeSize module from CMake 2.8.0 and lower.
-FOREACH(var
- SIZEOF_CURL_OFF_T
- SIZEOF_LONG
- SIZEOF_LONG_LONG
- SIZEOF___INT64
- SIZEOF_SIZE_T
- SIZEOF_SSIZE_T
- SIZEOF_TIME_T
- )
- IF(NOT ${var}_CODE)
- MESSAGE("creating ${var}_CODE")
- IF(${var})
- SET(${var}_CODE "#define ${var} ${${var}}")
- ELSE()
- SET(${var}_CODE "/* #undef ${var} */")
- ENDIF()
- ENDIF()
-ENDFOREACH()
-
-CONFIGURE_FILE(${LIBCURL_SOURCE_DIR}/config.h.in
- ${LIBCURL_BINARY_DIR}/config.h)
-
-ADD_LIBRARY(cmcurl ${LIBRARY_TYPE} ${libCurl_SRCS} ${CMAKE_CURL_SSL_DLLS})
-TARGET_LINK_LIBRARIES(cmcurl ${CURL_LIBS})
-IF(CMAKE_BUILD_CURL_SHARED)
- SET_TARGET_PROPERTIES(cmcurl PROPERTIES DEFINE_SYMBOL BUILDING_LIBCURL
- RUNTIME_OUTPUT_DIRECTORY ${CMake_BIN_DIR})
- INSTALL(TARGETS cmcurl RUNTIME DESTINATION bin)
-ENDIF(CMAKE_BUILD_CURL_SHARED)
-
-OPTION(CURL_TESTING "Do libCurl testing" OFF)
-IF(CURL_TESTING)
- SUBDIRS(Testing)
-ENDIF(CURL_TESTING)
-
-ADD_EXECUTABLE(LIBCURL Testing/curltest.c)
-TARGET_LINK_LIBRARIES(LIBCURL cmcurl ${CMAKE_DL_LIBS})
-
-IF(CMAKE_CURL_TEST_URL)
- ADD_TEST(curl LIBCURL ${CMAKE_CURL_TEST_URL})
-ENDIF(CMAKE_CURL_TEST_URL)
-
-INSTALL(FILES COPYING DESTINATION ${CMAKE_DOC_DIR}/cmcurl)
+ endif(HAVE_C_FLAG_Wno_long_double)
+endif(CMAKE_COMPILER_IS_GNUCC AND APPLE)
+
+if(HAVE_SOCKLEN_T)
+ set(CURL_HAVE_SOCKLEN_T 1)
+ set(CURL_TYPEOF_CURL_SOCKLEN_T "socklen_t")
+ if(WIN32)
+ set(CMAKE_EXTRA_INCLUDE_FILES "winsock2.h;ws2tcpip.h")
+ elseif(HAVE_SYS_SOCKET_H)
+ set(CMAKE_EXTRA_INCLUDE_FILES "sys/socket.h")
+ endif()
+ check_type_size("socklen_t" CURL_SIZEOF_CURL_SOCKLEN_T)
+ set(CMAKE_EXTRA_INCLUDE_FILES)
+ if(NOT HAVE_CURL_SIZEOF_CURL_SOCKLEN_T)
+ message(FATAL_ERROR
+ "Check for sizeof socklen_t failed, see CMakeFiles/CMakerror.log")
+ endif()
+else()
+ set(CURL_HAVE_SOCKLEN_T 0)
+endif()
+
+# TODO test which of these headers are required for the typedefs used in curlbuild.h
+if(WIN32)
+ set(CURL_PULL_WS2TCPIP_H ${HAVE_WS2TCPIP_H})
+else()
+ set(CURL_PULL_SYS_TYPES_H ${HAVE_SYS_TYPES_H})
+ set(CURL_PULL_SYS_SOCKET_H ${HAVE_SYS_SOCKET_H})
+ set(CURL_PULL_SYS_POLL_H ${HAVE_SYS_POLL_H})
+endif()
+set(CURL_PULL_STDINT_H ${HAVE_STDINT_H})
+set(CURL_PULL_INTTYPES_H ${HAVE_INTTYPES_H})
+
+include(CMake/OtherTests.cmake)
+
+add_definitions(-DHAVE_CONFIG_H)
+
+# For windows, do not allow the compiler to use default target (Vista).
+if(WIN32)
+ add_definitions(-D_WIN32_WINNT=0x0501)
+endif(WIN32)
+
+if(MSVC)
+ add_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE)
+endif(MSVC)
+
+# Ugly (but functional) way to include "Makefile.inc" by transforming it (= regenerate it).
+function(TRANSFORM_MAKEFILE_INC INPUT_FILE OUTPUT_FILE)
+ file(READ ${INPUT_FILE} MAKEFILE_INC_TEXT)
+ string(REPLACE "$(top_srcdir)" "\${CURL_SOURCE_DIR}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
+ string(REPLACE "$(top_builddir)" "\${CURL_BINARY_DIR}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
+
+ string(REGEX REPLACE "\\\\\n" "§!§" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
+ string(REGEX REPLACE "([a-zA-Z_][a-zA-Z0-9_]*)[\t ]*=[\t ]*([^\n]*)" "SET(\\1 \\2)" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
+ string(REPLACE "§!§" "\n" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
+
+ string(REGEX REPLACE "\\$\\(([a-zA-Z_][a-zA-Z0-9_]*)\\)" "\${\\1}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) # Replace $() with ${}
+ string(REGEX REPLACE "@([a-zA-Z_][a-zA-Z0-9_]*)@" "\${\\1}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) # Replace @@ with ${}, even if that may not be read by CMake scripts.
+ file(WRITE ${OUTPUT_FILE} ${MAKEFILE_INC_TEXT})
+
+endfunction()
+
+add_subdirectory(lib)
+if(BUILD_CURL_EXE)
+ add_subdirectory(src)
+endif()
+if(BUILD_CURL_TESTS)
+ add_subdirectory(tests)
+endif()
+
+#-----------------------------------------------------------------------------
+# CMake-specific curl code.
+add_executable(LIBCURL curltest.c)
+target_link_libraries(LIBCURL cmcurl)
+
+if(CMAKE_CURL_TEST_URL)
+ add_test(curl LIBCURL ${CMAKE_CURL_TEST_URL})
+endif()
+
+install(FILES COPYING DESTINATION ${CMAKE_DOC_DIR}/cmcurl)
+#-----------------------------------------------------------------------------
+
+if(0) # This code not needed for building within CMake.
+# TODO support GNUTLS, NSS, POLARSSL, AXTLS, CYASSL, WINSSL, DARWINSSL
+if(USE_OPENSSL)
+ set(SSL_ENABLED 1)
+endif()
+
+# Helper to populate a list (_items) with a label when conditions (the remaining
+# args) are satisfied
+function(_add_if label)
+ # TODO need to disable policy CMP0054 (CMake 3.1) to allow this indirection
+ if(${ARGN})
+ set(_items ${_items} "${label}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+# Clear list and try to detect available features
+set(_items)
+_add_if("SSL" SSL_ENABLED)
+_add_if("IPv6" ENABLE_IPV6)
+_add_if("unix-sockets" USE_UNIX_SOCKETS)
+_add_if("libz" HAVE_LIBZ)
+_add_if("AsynchDNS" USE_ARES OR USE_THREADS_POSIX)
+_add_if("IDN" HAVE_LIBIDN)
+# TODO SSP1 (WinSSL) check is missing
+_add_if("SSPI" USE_WINDOWS_SSPI)
+_add_if("GSS-API" HAVE_GSSAPI)
+# TODO SSP1 missing for SPNEGO
+_add_if("SPNEGO" NOT CURL_DISABLE_CRYPTO_AUTH AND
+ (HAVE_GSSAPI OR USE_WINDOWS_SSPI))
+_add_if("Kerberos" NOT CURL_DISABLE_CRYPTO_AUTH AND
+ (HAVE_GSSAPI OR USE_WINDOWS_SSPI))
+# NTLM support requires crypto function adaptions from various SSL libs
+# TODO alternative SSL libs tests for SSP1, GNUTLS, NSS, DARWINSSL
+if(NOT CURL_DISABLE_CRYPTO_AUTH AND (USE_OPENSSL OR
+ USE_WINDOWS_SSPI OR GNUTLS_ENABLED OR NSS_ENABLED OR DARWINSSL_ENABLED))
+ _add_if("NTLM" 1)
+ # TODO missing option (autoconf: --enable-ntlm-wb)
+ _add_if("NTLM_WB" NOT CURL_DISABLE_HTTP AND NTLM_WB_ENABLED)
+endif()
+# TODO missing option (--enable-tls-srp), depends on GNUTLS_SRP/OPENSSL_SRP
+_add_if("TLS-SRP" USE_TLS_SRP)
+# TODO option --with-nghttp2 tests for nghttp2 lib and nghttp2/nghttp2.h header
+_add_if("HTTP2" USE_NGHTTP2)
+string(REPLACE ";" " " SUPPORT_FEATURES "${_items}")
+message(STATUS "Enabled features: ${SUPPORT_FEATURES}")
+
+# Clear list and try to detect available protocols
+set(_items)
+_add_if("HTTP" NOT CURL_DISABLE_HTTP)
+_add_if("HTTPS" NOT CURL_DISABLE_HTTP AND SSL_ENABLED)
+_add_if("FTP" NOT CURL_DISABLE_FTP)
+_add_if("FTPS" NOT CURL_DISABLE_FTP AND SSL_ENABLED)
+_add_if("FILE" NOT CURL_DISABLE_FILE)
+_add_if("TELNET" NOT CURL_DISABLE_TELNET)
+_add_if("LDAP" NOT CURL_DISABLE_LDAP)
+# CURL_DISABLE_LDAP implies CURL_DISABLE_LDAPS
+# TODO check HAVE_LDAP_SSL (in autoconf this is enabled with --enable-ldaps)
+_add_if("LDAPS" NOT CURL_DISABLE_LDAPS AND
+ ((USE_OPENLDAP AND SSL_ENABLED) OR
+ (NOT USE_OPENLDAP AND HAVE_LDAP_SSL)))
+_add_if("DICT" NOT CURL_DISABLE_DICT)
+_add_if("TFTP" NOT CURL_DISABLE_TFTP)
+_add_if("GOPHER" NOT CURL_DISABLE_GOPHER)
+_add_if("POP3" NOT CURL_DISABLE_POP3)
+_add_if("POP3S" NOT CURL_DISABLE_POP3 AND SSL_ENABLED)
+_add_if("IMAP" NOT CURL_DISABLE_IMAP)
+_add_if("IMAPS" NOT CURL_DISABLE_IMAP AND SSL_ENABLED)
+_add_if("SMTP" NOT CURL_DISABLE_SMTP)
+_add_if("SMTPS" NOT CURL_DISABLE_SMTP AND SSL_ENABLED)
+_add_if("SCP" USE_LIBSSH2)
+_add_if("SFTP" USE_LIBSSH2)
+_add_if("RTSP" NOT CURL_DISABLE_RTSP)
+_add_if("RTMP" USE_LIBRTMP)
+list(SORT _items)
+string(REPLACE ";" " " SUPPORT_PROTOCOLS "${_items}")
+message(STATUS "Enabled protocols: ${SUPPORT_PROTOCOLS}")
+
+# curl-config needs the following options to be set.
+set(CC "${CMAKE_C_COMPILER}")
+# TODO probably put a -D... options here?
+set(CONFIGURE_OPTIONS "")
+# TODO when to set "-DCURL_STATICLIB" for CPPFLAG_CURL_STATICLIB?
+set(CPPFLAG_CURL_STATICLIB "")
+# TODO need to set this (see CURL_CHECK_CA_BUNDLE in acinclude.m4)
+set(CURL_CA_BUNDLE "")
+set(CURLVERSION "${CURL_VERSION}")
+set(ENABLE_SHARED "yes")
+if(CURL_STATICLIB)
+ # Broken: LIBCURL_LIBS below; .a lib is not built
+ message(WARNING "Static linking is broken!")
+ set(ENABLE_STATIC "no")
+else()
+ set(ENABLE_STATIC "no")
+endif()
+set(exec_prefix "\${prefix}")
+set(includedir "\${prefix}/include")
+set(LDFLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
+set(LIBCURL_LIBS "")
+set(libdir "${CMAKE_INSTALL_PREFIX}/lib")
+# TODO CURL_LIBS also contains absolute paths which don't work with static -l...
+foreach(_lib ${CMAKE_C_IMPLICIT_LINK_LIBRARIES} ${CURL_LIBS})
+ set(LIBCURL_LIBS "${LIBCURL_LIBS} -l${_lib}")
+endforeach()
+# "a" (Linux) or "lib" (Windows)
+string(REPLACE "." "" libext "${CMAKE_STATIC_LIBRARY_SUFFIX}")
+set(prefix "${CMAKE_INSTALL_PREFIX}")
+# Set this to "yes" to append all libraries on which -lcurl is dependent
+set(REQUIRE_LIB_DEPS "no")
+# SUPPORT_FEATURES
+# SUPPORT_PROTOCOLS
+set(VERSIONNUM "${CURL_VERSION_NUM}")
+
+# Finally generate a "curl-config" matching this config
+configure_file("${CURL_SOURCE_DIR}/curl-config.in"
+ "${CURL_BINARY_DIR}/curl-config" @ONLY)
+install(FILES "${CMAKE_BINARY_DIR}/curl-config"
+ DESTINATION bin
+ PERMISSIONS
+ OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE
+ WORLD_READ WORLD_EXECUTE)
+
+# Finally generate a pkg-config file matching this config
+configure_file("${CURL_SOURCE_DIR}/libcurl.pc.in"
+ "${CURL_BINARY_DIR}/libcurl.pc" @ONLY)
+install(FILES "${CMAKE_BINARY_DIR}/libcurl.pc"
+ DESTINATION lib/pkgconfig)
+
+# This needs to be run very last so other parts of the scripts can take advantage of this.
+if(NOT CURL_CONFIG_HAS_BEEN_RUN_BEFORE)
+ set(CURL_CONFIG_HAS_BEEN_RUN_BEFORE 1 CACHE INTERNAL "Flag to track whether this is the first time running CMake or if CMake has been configured before")
+endif()
+
+# Installation.
+# First, install generated curlbuild.h
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/include/curl/curlbuild.h"
+ DESTINATION include/curl )
+# Next, install other headers excluding curlbuild.h
+install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/curl"
+ DESTINATION include
+ FILES_MATCHING PATTERN "*.h"
+ PATTERN "curlbuild.h" EXCLUDE)
+
+
+# Workaround for MSVS10 to avoid the Dialog Hell
+# FIXME: This could be removed with future version of CMake.
+if(MSVC_VERSION EQUAL 1600)
+ set(CURL_SLN_FILENAME "${CMAKE_CURRENT_BINARY_DIR}/CURL.sln")
+ if(EXISTS "${CURL_SLN_FILENAME}")
+ file(APPEND "${CURL_SLN_FILENAME}" "\n# This should be regenerated!\n")
+ endif()
+endif()
+endif()
diff --git a/Utilities/cmcurl/COPYING b/Utilities/cmcurl/COPYING
index 048cf5657..6b5d59f86 100644
--- a/Utilities/cmcurl/COPYING
+++ b/Utilities/cmcurl/COPYING
@@ -1,6 +1,6 @@
COPYRIGHT AND PERMISSION NOTICE
-Copyright (c) 1996 - 2009, Daniel Stenberg, <daniel@haxx.se>.
+Copyright (c) 1996 - 2015, Daniel Stenberg, <daniel@haxx.se>.
All rights reserved.
diff --git a/Utilities/cmcurl/Platforms/WindowsCache.cmake b/Utilities/cmcurl/Platforms/WindowsCache.cmake
deleted file mode 100644
index 57ab30be3..000000000
--- a/Utilities/cmcurl/Platforms/WindowsCache.cmake
+++ /dev/null
@@ -1,120 +0,0 @@
-IF(NOT UNIX)
- IF(WIN32)
- SET(HAVE_LIBDL 0)
- SET(HAVE_LIBUCB 0)
- SET(HAVE_LIBSOCKET 0)
- SET(NOT_NEED_LIBNSL 0)
- SET(HAVE_LIBNSL 0)
- SET(HAVE_LIBZ 0)
- SET(HAVE_LIBCRYPTO 0)
-
- SET(HAVE_DLOPEN 0)
-
- SET(HAVE_ALLOCA_H 0)
- SET(HAVE_ARPA_INET_H 0)
- SET(HAVE_DLFCN_H 0)
- SET(HAVE_FCNTL_H 1)
- SET(HAVE_FEATURES_H 0)
- SET(HAVE_INTTYPES_H 0)
- SET(HAVE_IO_H 1)
- SET(HAVE_MALLOC_H 1)
- SET(HAVE_MEMORY_H 1)
- SET(HAVE_NETDB_H 0)
- SET(HAVE_NETINET_IF_ETHER_H 0)
- SET(HAVE_NETINET_IN_H 0)
- SET(HAVE_NET_IF_H 0)
- SET(HAVE_PROCESS_H 1)
- SET(HAVE_PWD_H 0)
- SET(HAVE_SETJMP_H 1)
- SET(HAVE_SGTTY_H 0)
- SET(HAVE_SIGNAL_H 1)
- SET(HAVE_SOCKIO_H 0)
- SET(HAVE_STDINT_H 0)
- SET(HAVE_STDLIB_H 1)
- SET(HAVE_STRINGS_H 0)
- SET(HAVE_STRING_H 1)
- SET(HAVE_SYS_PARAM_H 0)
- SET(HAVE_SYS_POLL_H 0)
- SET(HAVE_SYS_SELECT_H 0)
- SET(HAVE_SYS_SOCKET_H 0)
- SET(HAVE_SYS_SOCKIO_H 0)
- SET(HAVE_SYS_STAT_H 1)
- SET(HAVE_SYS_TIME_H 0)
- SET(HAVE_SYS_TYPES_H 1)
- SET(HAVE_SYS_UTIME_H 1)
- SET(HAVE_TERMIOS_H 0)
- SET(HAVE_TERMIO_H 0)
- SET(HAVE_TIME_H 1)
- SET(HAVE_UNISTD_H 0)
- SET(HAVE_UTIME_H 0)
- SET(HAVE_X509_H 0)
- SET(HAVE_ZLIB_H 0)
-
- SET(HAVE_SIZEOF_LONG_DOUBLE 1)
- SET(SIZEOF_LONG_DOUBLE 8)
-
- SET(HAVE_SOCKET 1)
- SET(HAVE_POLL 0)
- SET(HAVE_SELECT 1)
- SET(HAVE_STRDUP 1)
- SET(HAVE_STRSTR 1)
- SET(HAVE_STRTOK_R 0)
- SET(HAVE_STRFTIME 1)
- SET(HAVE_UNAME 0)
- SET(HAVE_STRCASECMP 0)
- SET(HAVE_STRICMP 1)
- SET(HAVE_STRCMPI 1)
- SET(HAVE_GETHOSTBYADDR 1)
- SET(HAVE_GETTIMEOFDAY 0)
- SET(HAVE_INET_ADDR 1)
- SET(HAVE_INET_NTOA 1)
- SET(HAVE_INET_NTOA_R 0)
- SET(HAVE_TCGETATTR 0)
- SET(HAVE_TCSETATTR 0)
- SET(HAVE_PERROR 1)
- SET(HAVE_CLOSESOCKET 1)
- SET(HAVE_SETVBUF 0)
- SET(HAVE_SIGSETJMP 0)
- SET(HAVE_GETPASS_R 0)
- SET(HAVE_GETPWUID 0)
- SET(HAVE_GETEUID 0)
- SET(HAVE_UTIME 1)
- SET(HAVE_RAND_EGD 0)
- SET(HAVE_RAND_SCREEN 0)
- SET(HAVE_RAND_STATUS 0)
- SET(HAVE_GMTIME_R 0)
- SET(HAVE_LOCALTIME_R 0)
- SET(HAVE_GETHOSTBYADDR_R 0)
- SET(HAVE_GETHOSTBYNAME_R 0)
- SET(HAVE_SIGNAL_FUNC 1)
- SET(HAVE_SIGNAL_MACRO 0)
-
- SET(HAVE_GETHOSTBYADDR_R_5 0)
- SET(HAVE_GETHOSTBYADDR_R_5_REENTRANT 0)
- SET(HAVE_GETHOSTBYADDR_R_7 0)
- SET(HAVE_GETHOSTBYADDR_R_7_REENTRANT 0)
- SET(HAVE_GETHOSTBYADDR_R_8 0)
- SET(HAVE_GETHOSTBYADDR_R_8_REENTRANT 0)
- SET(HAVE_GETHOSTBYNAME_R_3 0)
- SET(HAVE_GETHOSTBYNAME_R_3_REENTRANT 0)
- SET(HAVE_GETHOSTBYNAME_R_5 0)
- SET(HAVE_GETHOSTBYNAME_R_5_REENTRANT 0)
- SET(HAVE_GETHOSTBYNAME_R_6 0)
- SET(HAVE_GETHOSTBYNAME_R_6_REENTRANT 0)
-
- SET(TIME_WITH_SYS_TIME 0)
- SET(HAVE_O_NONBLOCK 0)
- SET(HAVE_IN_ADDR_T 0)
- SET(HAVE_INET_NTOA_R_DECL 0)
- SET(HAVE_INET_NTOA_R_DECL_REENTRANT 0)
- SET(HAVE_GETADDRINFO 0)
- SET(STDC_HEADERS 1)
- SET(RETSIGTYPE_TEST 1)
-
- SET(HAVE_SIGACTION 0)
- SET(HAVE_MACRO_SIGSETJMP 0)
- ELSE(WIN32)
- MESSAGE("This file should be included on Windows platform only")
- ENDIF(WIN32)
-ENDIF(NOT UNIX)
-
diff --git a/Utilities/cmcurl/Platforms/config-aix.h b/Utilities/cmcurl/Platforms/config-aix.h
deleted file mode 100644
index c98b10fdd..000000000
--- a/Utilities/cmcurl/Platforms/config-aix.h
+++ /dev/null
@@ -1,483 +0,0 @@
-/* lib/config.h. Generated by configure. */
-/* lib/config.h.in. Generated from configure.in by autoheader. */
-/* Name of this package! */
-#define PACKAGE "curl"
-
-/* Version number of this archive. */
-#define VERSION "7.10.2"
-
-/* Define if you have the getpass function. */
-/* #undef HAVE_GETPASS */
-
-/* Define cpu-machine-OS */
-#define OS "powerpc-ibm-aix5.1.0.0"
-
-/* Define if you have the gethostbyaddr_r() function with 5 arguments */
-#define HAVE_GETHOSTBYADDR_R_5 1
-
-/* Define if you have the gethostbyaddr_r() function with 7 arguments */
-/* #undef HAVE_GETHOSTBYADDR_R_7 */
-
-/* Define if you have the gethostbyaddr_r() function with 8 arguments */
-/* #undef HAVE_GETHOSTBYADDR_R_8 */
-
-/* Define if you have the gethostbyname_r() function with 3 arguments */
-#define HAVE_GETHOSTBYNAME_R_3 1
-
-/* Define if you have the gethostbyname_r() function with 5 arguments */
-/* #undef HAVE_GETHOSTBYNAME_R_5 */
-
-/* Define if you have the gethostbyname_r() function with 6 arguments */
-/* #undef HAVE_GETHOSTBYNAME_R_6 */
-
-/* Define if you have the inet_ntoa_r function declared. */
-/* #undef HAVE_INET_NTOA_R_DECL */
-
-/* Define if you need the _REENTRANT define for some functions */
-/* #undef NEED_REENTRANT */
-
-/* Define if you have the Kerberos4 libraries (including -ldes) */
-/* #undef KRB4 */
-
-/* Define if you want to enable IPv6 support */
-#define ENABLE_IPV6 1
-
-/* Define this to 'int' if ssize_t is not an available typedefed type */
-/* #undef ssize_t */
-
-/* Define this to 'int' if socklen_t is not an available typedefed type */
-/* #undef socklen_t */
-
-/* Define this as a suitable file to read random data from */
-/* #undef RANDOM_FILE */
-
-/* Define this to your Entropy Gathering Daemon socket pathname */
-/* #undef EGD_SOCKET */
-
-/* Define if you have a working OpenSSL installation */
-/* #undef OPENSSL_ENABLED */
-
-/* Define the one correct non-blocking socket method below */
-/* #undef HAVE_FIONBIO */
-/* #undef HAVE_IOCTLSOCKET */
-/* #undef HAVE_IOCTLSOCKET_CASE */
-/* #undef HAVE_O_NONBLOCK */
-#define HAVE_DISABLED_NONBLOCKING 1
-
-/* Define this to 'int' if in_addr_t is not an available typedefed type */
-/* #undef in_addr_t */
-
-/* Define to disable DICT */
-/* #undef CURL_DISABLE_DICT */
-
-/* Define to disable FILE */
-/* #undef CURL_DISABLE_FILE */
-
-/* Define to disable FTP */
-/* #undef CURL_DISABLE_FTP */
-
-/* Define to disable GOPHER */
-/* #undef CURL_DISABLE_GOPHER */
-
-/* Define to disable HTTP */
-/* #undef CURL_DISABLE_HTTP */
-
-/* Define to disable LDAP */
-/* #undef CURL_DISABLE_LDAP */
-
-/* Define to disable TELNET */
-/* #undef CURL_DISABLE_TELNET */
-
-/* Define if you have zlib present */
-#define HAVE_LIBZ 1
-
-/* CA bundle full path name */
-#define CURL_CA_BUNDLE "/usr/local/share/curl/curl-ca-bundle.crt"
-
-/* to disable FILE */
-/* #undef CURL_DISABLE_FILE */
-
-/* to disable FTP */
-/* #undef CURL_DISABLE_FTP */
-
-/* to disable GOPHER */
-/* #undef CURL_DISABLE_GOPHER */
-
-/* to disable HTTP */
-/* #undef CURL_DISABLE_HTTP */
-
-/* to disable LDAP */
-/* #undef CURL_DISABLE_LDAP */
-
-/* to disable TELNET */
-/* #undef CURL_DISABLE_TELNET */
-
-/* Set to explicitly specify we don't want to use thread-safe functions */
-/* #undef DISABLED_THREADSAFE */
-
-/* your Entropy Gathering Daemon socket pathname */
-/* #undef EGD_SOCKET */
-
-/* Define if you want to enable IPv6 support */
-#define ENABLE_IPV6 1
-
-/* Define to 1 if you have the <alloca.h> header file. */
-#define HAVE_ALLOCA_H 1
-
-/* Define to 1 if you have the <arpa/inet.h> header file. */
-#define HAVE_ARPA_INET_H 1
-
-/* Define to 1 if you have the `closesocket' function. */
-/* #undef HAVE_CLOSESOCKET */
-
-/* Define to 1 if you have the <crypto.h> header file. */
-/* #undef HAVE_CRYPTO_H */
-
-/* Define to 1 if you have the <des.h> header file. */
-/* #undef HAVE_DES_H */
-
-/* to disable NON-BLOCKING connections */
-#define HAVE_DISABLED_NONBLOCKING 1
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define to 1 if you have the `dlopen' function. */
-#define HAVE_DLOPEN 1
-
-/* Define to 1 if you have the <err.h> header file. */
-/* #undef HAVE_ERR_H */
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#define HAVE_FCNTL_H 1
-
-/* Define if getaddrinfo exists and works */
-#define HAVE_GETADDRINFO 1
-
-/* Define to 1 if you have the `geteuid' function. */
-#define HAVE_GETEUID 1
-
-/* Define to 1 if you have the `gethostbyaddr' function. */
-#define HAVE_GETHOSTBYADDR 1
-
-/* Define to 1 if you have the `gethostbyaddr_r' function. */
-#define HAVE_GETHOSTBYADDR_R 1
-
-/* Define to 1 if you have the `gethostbyname_r' function. */
-#define HAVE_GETHOSTBYNAME_R 1
-
-/* Define to 1 if you have the `getpass_r' function. */
-/* #undef HAVE_GETPASS_R */
-
-/* Define to 1 if you have the `getpwuid' function. */
-#define HAVE_GETPWUID 1
-
-/* Define to 1 if you have the `gettimeofday' function. */
-#define HAVE_GETTIMEOFDAY 1
-
-/* Define to 1 if you have the `gmtime_r' function. */
-#define HAVE_GMTIME_R 1
-
-/* Define to 1 if you have the `inet_addr' function. */
-#define HAVE_INET_ADDR 1
-
-/* Define to 1 if you have the `inet_ntoa' function. */
-#define HAVE_INET_NTOA 1
-
-/* Define to 1 if you have the `inet_ntoa_r' function. */
-#define HAVE_INET_NTOA_R 1
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the <io.h> header file. */
-/* #undef HAVE_IO_H */
-
-/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */
-/* #undef HAVE_KRB_GET_OUR_IP_FOR_REALM */
-
-/* Define to 1 if you have the <krb.h> header file. */
-/* #undef HAVE_KRB_H */
-
-/* Define to 1 if you have the `crypto' library (-lcrypto). */
-/* #undef HAVE_LIBCRYPTO */
-
-/* Define to 1 if you have the `dl' library (-ldl). */
-/* #undef HAVE_LIBDL */
-
-/* Define to 1 if you have the `nsl' library (-lnsl). */
-/* #undef HAVE_LIBNSL */
-
-/* Define to 1 if you have the `resolv' library (-lresolv). */
-/* #undef HAVE_LIBRESOLV */
-
-/* Define to 1 if you have the `resolve' library (-lresolve). */
-/* #undef HAVE_LIBRESOLVE */
-
-/* Define to 1 if you have the `socket' library (-lsocket). */
-/* #undef HAVE_LIBSOCKET */
-
-/* Define to 1 if you have the `ssl' library (-lssl). */
-/* #undef HAVE_LIBSSL */
-
-/* If zlib is available */
-#define HAVE_LIBZ 1
-
-/* Define to 1 if you have the `localtime_r' function. */
-#define HAVE_LOCALTIME_R 1
-
-/* Define to 1 if you have the <malloc.h> header file. */
-#define HAVE_MALLOC_H 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the <netdb.h> header file. */
-#define HAVE_NETDB_H 1
-
-/* Define to 1 if you have the <netinet/if_ether.h> header file. */
-#define HAVE_NETINET_IF_ETHER_H 1
-
-/* Define to 1 if you have the <netinet/in.h> header file. */
-#define HAVE_NETINET_IN_H 1
-
-/* Define to 1 if you have the <net/if.h> header file. */
-#define HAVE_NET_IF_H 1
-
-/* Define to 1 if you have the <openssl/crypto.h> header file. */
-/* #undef HAVE_OPENSSL_CRYPTO_H */
-
-/* Define to 1 if you have the <openssl/engine.h> header file. */
-/* #undef HAVE_OPENSSL_ENGINE_H */
-
-/* Define to 1 if you have the <openssl/err.h> header file. */
-/* #undef HAVE_OPENSSL_ERR_H */
-
-/* Define to 1 if you have the <openssl/pem.h> header file. */
-/* #undef HAVE_OPENSSL_PEM_H */
-
-/* Define to 1 if you have the <openssl/rsa.h> header file. */
-/* #undef HAVE_OPENSSL_RSA_H */
-
-/* Define to 1 if you have the <openssl/ssl.h> header file. */
-/* #undef HAVE_OPENSSL_SSL_H */
-
-/* Define to 1 if you have the <openssl/x509.h> header file. */
-/* #undef HAVE_OPENSSL_X509_H */
-
-/* Define to 1 if you have the <pem.h> header file. */
-/* #undef HAVE_PEM_H */
-
-/* Define to 1 if you have the `perror' function. */
-#define HAVE_PERROR 1
-
-/* Define to 1 if you have the `poll' function. */
-#define HAVE_POLL 1
-
-/* Define to 1 if you have the <pwd.h> header file. */
-#define HAVE_PWD_H 1
-
-/* Define to 1 if you have the `RAND_egd' function. */
-/* #undef HAVE_RAND_EGD */
-
-/* Define to 1 if you have the `RAND_screen' function. */
-/* #undef HAVE_RAND_SCREEN */
-
-/* Define to 1 if you have the `RAND_status' function. */
-/* #undef HAVE_RAND_STATUS */
-
-/* Define to 1 if you have the <rsa.h> header file. */
-/* #undef HAVE_RSA_H */
-
-/* Define to 1 if you have the `select' function. */
-#define HAVE_SELECT 1
-
-/* Define to 1 if you have the <setjmp.h> header file. */
-#define HAVE_SETJMP_H 1
-
-/* Define to 1 if you have the `setvbuf' function. */
-#define HAVE_SETVBUF 1
-
-/* Define to 1 if you have the <sgtty.h> header file. */
-#define HAVE_SGTTY_H 1
-
-/* Define to 1 if you have the `sigaction' function. */
-#define HAVE_SIGACTION 1
-
-/* Define to 1 if you have the `signal' function. */
-#define HAVE_SIGNAL 1
-
-/* If you have sigsetjmp */
-#define HAVE_SIGSETJMP 1
-
-/* Define to 1 if you have the `socket' function. */
-#define HAVE_SOCKET 1
-
-/* Define to 1 if you have the <ssl.h> header file. */
-/* #undef HAVE_SSL_H */
-
-/* Define to 1 if you have the <stdint.h> header file. */
-/* #undef HAVE_STDINT_H */
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the `strcasecmp' function. */
-#define HAVE_STRCASECMP 1
-
-/* Define to 1 if you have the `strcmpi' function. */
-/* #undef HAVE_STRCMPI */
-
-/* Define to 1 if you have the `strdup' function. */
-#define HAVE_STRDUP 1
-
-/* Define to 1 if you have the `strftime' function. */
-#define HAVE_STRFTIME 1
-
-/* Define to 1 if you have the `stricmp' function. */
-/* #undef HAVE_STRICMP */
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the `strlcpy' function. */
-/* #undef HAVE_STRLCPY */
-
-/* Define to 1 if you have the `strstr' function. */
-#define HAVE_STRSTR 1
-
-/* Define to 1 if you have the `strtok_r' function. */
-#define HAVE_STRTOK_R 1
-
-/* Define to 1 if you have the <sys/param.h> header file. */
-#define HAVE_SYS_PARAM_H 1
-
-/* Define to 1 if you have the <sys/poll.h> header file. */
-#define HAVE_SYS_POLL_H 1
-
-/* Define to 1 if you have the <sys/select.h> header file. */
-#define HAVE_SYS_SELECT_H 1
-
-/* Define to 1 if you have the <sys/socket.h> header file. */
-#define HAVE_SYS_SOCKET_H 1
-
-/* Define to 1 if you have the <sys/sockio.h> header file. */
-/* #undef HAVE_SYS_SOCKIO_H */
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/time.h> header file. */
-#define HAVE_SYS_TIME_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <sys/utime.h> header file. */
-/* #undef HAVE_SYS_UTIME_H */
-
-/* Define to 1 if you have the `tcgetattr' function. */
-#define HAVE_TCGETATTR 1
-
-/* Define to 1 if you have the `tcsetattr' function. */
-#define HAVE_TCSETATTR 1
-
-/* Define to 1 if you have the <termios.h> header file. */
-#define HAVE_TERMIOS_H 1
-
-/* Define to 1 if you have the <termio.h> header file. */
-#define HAVE_TERMIO_H 1
-
-/* Define to 1 if you have the <time.h> header file. */
-#define HAVE_TIME_H 1
-
-/* Define to 1 if you have the `uname' function. */
-#define HAVE_UNAME 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define to 1 if you have the `utime' function. */
-#define HAVE_UTIME 1
-
-/* Define to 1 if you have the <utime.h> header file. */
-#define HAVE_UTIME_H 1
-
-/* Define to 1 if you have the <winsock.h> header file. */
-/* #undef HAVE_WINSOCK_H */
-
-/* Define to 1 if you have the <x509.h> header file. */
-/* #undef HAVE_X509_H */
-
-/* if you have the zlib.h header file */
-/* #undef HAVE_ZLIB_H */
-
-/* if you have the Kerberos4 libraries (including -ldes) */
-/* #undef KRB4 */
-
-/* cpu-machine-OS */
-#define OS "powerpc-ibm-aix5.1.0.0"
-
-/* Name of package */
-#define PACKAGE "curl"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT ""
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME ""
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING ""
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION ""
-
-/* a suitable file to read random data from */
-/* #undef RANDOM_FILE */
-
-/* Define as the return type of signal handlers (`int' or `void'). */
-#define RETSIGTYPE void
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
-#define TIME_WITH_SYS_TIME 1
-
-/* Version number of package */
-#define VERSION "7.10.2"
-
-/* Define to 1 if on AIX 3.
- System headers sometimes define this.
- We just want to avoid a redefinition error message. */
-#ifndef _ALL_SOURCE
-# define _ALL_SOURCE 1
-#endif
-
-/* Number of bits in a file offset, on hosts where this is settable. */
-/* #undef _FILE_OFFSET_BITS */
-
-/* Define for large files, on AIX-style hosts. */
-#define _LARGE_FILES 1
-
-/* Define to empty if `const' does not conform to ANSI C. */
-/* #undef const */
-
-/* type to use in place of in_addr_t if not defined */
-/* #undef in_addr_t */
-
-/* Define to `unsigned' if <sys/types.h> does not define. */
-/* #undef size_t */
-
-/* type to use in place of socklen_t if not defined */
-/* #undef socklen_t */
-
-/* Define to `int' if <sys/types.h> does not define. */
-/* #undef ssize_t */
diff --git a/Utilities/cmcurl/README-CMake.txt b/Utilities/cmcurl/README-CMake.txt
new file mode 100644
index 000000000..1e7567289
--- /dev/null
+++ b/Utilities/cmcurl/README-CMake.txt
@@ -0,0 +1,66 @@
+The Utilities/cmcurl directory contains a reduced distribution
+of the curl source tree with only the library source code and
+CMake build system. It is not a submodule; the actual content is part
+of our source tree and changes can be made and committed directly.
+
+We update from upstream using Git's "subtree" merge strategy. A
+special branch contains commits of upstream curl snapshots and
+nothing else. No Git ref points explicitly to the head of this
+branch, but it is merged into our history.
+
+Update curl from upstream as follows. Create a local branch to
+explicitly reference the upstream snapshot branch head:
+
+ git branch curl-upstream 70654261
+
+Use a temporary directory to checkout the branch:
+
+ mkdir curl-tmp
+ cd curl-tmp
+ git init
+ git pull .. curl-upstream
+ rm -rf *
+
+Now place the (reduced) curl content in this directory. See
+instructions shown by
+
+ git log 70654261
+
+for help extracting the content from the upstream repo. Then run
+the following commands to commit the new version. Substitute the
+appropriate date and version number:
+
+ git add --all
+
+ GIT_AUTHOR_NAME='Curl Upstream' \
+ GIT_AUTHOR_EMAIL='curl-library@cool.haxx.se' \
+ GIT_AUTHOR_DATE='Tue Aug 11 20:13:01 2015 +0200' \
+ git commit -m 'curl 7.44.0 (reduced)' &&
+ git commit --amend
+
+Edit the commit message to describe the procedure used to obtain the
+content. Then push the changes back up to the main local repository:
+
+ git push .. HEAD:curl-upstream
+ cd ..
+ rm -rf curl-tmp
+
+Create a topic in the main repository on which to perform the update:
+
+ git checkout -b update-curl master
+
+Merge the curl-upstream branch as a subtree:
+
+ git merge -s recursive -X subtree=Utilities/cmcurl \
+ curl-upstream
+
+If there are conflicts, resolve them and commit. Build and test the
+tree. Commit any additional changes needed to succeed.
+
+Finally, run
+
+ git rev-parse --short=8 curl-upstream
+
+to get the commit from which the curl-upstream branch must be started
+on the next update. Edit the "git branch curl-upstream" line above to
+record it, and commit this file.
diff --git a/Utilities/cmcurl/Testing/CMakeLists.txt b/Utilities/cmcurl/Testing/CMakeLists.txt
deleted file mode 100644
index 214410fd5..000000000
--- a/Utilities/cmcurl/Testing/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-SET(CURL_TESTS
- ftpget
- ftpgetresp
- ftpupload
- getinmemory
- persistant
- sepheaders
- simple
- )
-
-CONFIGURE_FILE(${LIBCURL_SOURCE_DIR}/Testing/testconfig.h.in
- ${LIBCURL_BINARY_DIR}/Testing/testconfig.h)
-
-INCLUDE_DIRECTORIES(${LIBCURL_BINARY_DIR}/Testing)
-
-FOREACH(TEST ${CURL_TESTS})
- ADD_EXECUTABLE(${TEST} ${TEST}.c)
- TARGET_LINK_LIBRARIES(${TEST} cmcurl)
-ENDFOREACH(TEST)
diff --git a/Utilities/cmcurl/Testing/curlgtk.c b/Utilities/cmcurl/Testing/curlgtk.c
deleted file mode 100644
index 7c9ce2a1b..000000000
--- a/Utilities/cmcurl/Testing/curlgtk.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*****************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * $Id$
- */
-/* Copyright (c) 2000 David Odin (aka DindinX) for MandrakeSoft */
-/* an attempt to use the curl library in concert with a gtk-threaded application */
-
-#include <stdio.h>
-#include <gtk/gtk.h>
-
-#include <curl/curl.h>
-#include <curl/types.h> /* new for v7 */
-#include <curl/easy.h> /* new for v7 */
-
-#include <pthread.h>
-
-GtkWidget *Bar;
-
-size_t my_read_func(void *ptr, size_t size, size_t nmemb, FILE *stream)
-{
- return fread(ptr, size, nmemb, stream);
-}
-
-int my_progress_func(GtkWidget *Bar, int t, int d)
-{
-/* printf("%d / %d (%g %%)\n", d, t, d*100.0/t);*/
- gdk_threads_enter();
- gtk_progress_set_value(GTK_PROGRESS(Bar), d*100.0/t);
- gdk_threads_leave();
- return 0;
-}
-
-void *curl_thread(void *ptr)
-{
- CURL *curl;
- CURLcode res;
- FILE *outfile;
- gchar *url = ptr;
-
- curl = curl_easy_init();
- if(curl)
- {
- outfile = fopen("/tmp/test.curl", "w");
-
- curl_easy_setopt(curl, CURLOPT_URL, url);
- curl_easy_setopt(curl, CURLOPT_FILE, outfile);
- curl_easy_setopt(curl, CURLOPT_READFUNCTION, my_read_func);
- curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, my_progress_func);
- curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, Bar);
-
- res = curl_easy_perform(curl);
-
- fclose(outfile);
- /* always cleanup */
- curl_easy_cleanup(curl);
- }
- return NULL;
-}
-
-int main(int argc, char **argv)
-{
- GtkWidget *Window, *Frame, *Frame2;
- GtkAdjustment *adj;
- pthread_t curl_tid;
-
- /* Init thread */
- g_thread_init(NULL);
-
- gtk_init(&argc, &argv);
- Window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- Frame = gtk_frame_new(NULL);
- gtk_frame_set_shadow_type(GTK_FRAME(Frame), GTK_SHADOW_OUT);
- gtk_container_add(GTK_CONTAINER(Window), Frame);
- Frame2 = gtk_frame_new(NULL);
- gtk_frame_set_shadow_type(GTK_FRAME(Frame2), GTK_SHADOW_IN);
- gtk_container_add(GTK_CONTAINER(Frame), Frame2);
- gtk_container_set_border_width(GTK_CONTAINER(Frame2), 5);
- adj = (GtkAdjustment*)gtk_adjustment_new(0, 0, 100, 0, 0, 0);
- Bar = gtk_progress_bar_new_with_adjustment(adj);
- gtk_container_add(GTK_CONTAINER(Frame2), Bar);
- gtk_widget_show_all(Window);
-
- pthread_create(&curl_tid, NULL, curl_thread, argv[1]);
-
- gdk_threads_enter();
- gtk_main();
- gdk_threads_leave();
- return 0;
-}
-
diff --git a/Utilities/cmcurl/Testing/ftpget.c b/Utilities/cmcurl/Testing/ftpget.c
deleted file mode 100644
index 1a3633ec9..000000000
--- a/Utilities/cmcurl/Testing/ftpget.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*****************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * $Id$
- */
-
-#include "curl/curl.h"
-#include "curl/types.h"
-#include "curl/easy.h"
-#include "setup.h"
-
-#include "testconfig.h"
-
-/*
- * This is an example showing how to get a single file from an FTP server.
- * It delays the actual destination file creation until the first write
- * callback so that it won't create an empty file in case the remote file
- * doesn't exist or something else fails.
- */
-
-struct FtpFile {
- char *filename;
- FILE *stream;
-};
-
-int my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
-{
- struct FtpFile *out=(struct FtpFile *)stream;
- if(out && !out->stream) {
- /* open file for writing */
- out->stream=fopen(out->filename, "wb");
- if(!out->stream)
- return -1; /* failure, can't open file to write */
- }
- return fwrite(buffer, size, nmemb, out->stream);
-}
-
-
-int main(void)
-{
- CURL *curl;
- CURLcode res;
- struct FtpFile ftpfile={
- LIBCURL_BINARY_DIR "/Testing/ftpget-download.txt", /* name to store the file as if succesful */
- NULL
- };
-
- curl_global_init(CURL_GLOBAL_DEFAULT);
-
- curl = curl_easy_init();
- if(curl) {
- /* Get curl 7.9.2 from sunet.se's FTP site: */
- curl_easy_setopt(curl, CURLOPT_URL,
- "ftp://public.kitware.com/pub/cmake/cygwin/setup.hint");
- /* Define our callback to get called when there's data to be written */
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
- /* Set a pointer to our struct to pass to the callback */
- curl_easy_setopt(curl, CURLOPT_FILE, &ftpfile);
-
- /* Switch on full protocol/debug output */
- curl_easy_setopt(curl, CURLOPT_VERBOSE, TRUE);
-
- res = curl_easy_perform(curl);
-
- /* always cleanup */
- curl_easy_cleanup(curl);
-
- if(CURLE_OK != res) {
- /* we failed */
- fprintf(stderr, "curl told us %d\n", res);
- }
- }
-
- if(ftpfile.stream)
- fclose(ftpfile.stream); /* close the local file */
-
- curl_global_cleanup();
-
- return 0;
-}
diff --git a/Utilities/cmcurl/Testing/ftpgetresp.c b/Utilities/cmcurl/Testing/ftpgetresp.c
deleted file mode 100644
index 9548b2a34..000000000
--- a/Utilities/cmcurl/Testing/ftpgetresp.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*****************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * $Id$
- */
-
-#include "curl/curl.h"
-#include "curl/types.h"
-#include "curl/easy.h"
-
-#include "testconfig.h"
-
-/*
- * Similar to ftpget.c but this also stores the received response-lines
- * in a separate file using our own callback!
- *
- * This functionality was introduced in libcurl 7.9.3.
- */
-
-size_t
-write_response(void *ptr, size_t size, size_t nmemb, void *data)
-{
- FILE *writehere = (FILE *)data;
- return fwrite(ptr, size, nmemb, writehere);
-}
-
-int main(int argc, char **argv)
-{
- CURL *curl;
- CURLcode res;
- FILE *ftpfile;
- FILE *respfile;
- (void)argc; (void)argv;
-
- /* local file name to store the file as */
- ftpfile = fopen(LIBCURL_BINARY_DIR "/Testing/ftpgetresp-list.txt", "wb"); /* b is binary, needed on win32 */
-
- /* local file name to store the FTP server's response lines in */
- respfile = fopen(LIBCURL_BINARY_DIR "/Testing/ftpgetresp-responses.txt", "wb"); /* b is binary, needed on win32 */
-
- curl_global_init(CURL_GLOBAL_DEFAULT);
-
- curl = curl_easy_init();
- if(curl) {
- /* Get a file listing from sunet */
- curl_easy_setopt(curl, CURLOPT_URL, "ftp://public.kitware.com/");
- curl_easy_setopt(curl, CURLOPT_FILE, ftpfile);
- curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, write_response);
- curl_easy_setopt(curl, CURLOPT_WRITEHEADER, respfile);
- res = curl_easy_perform(curl);
-
- /* always cleanup */
- curl_easy_cleanup(curl);
- }
-
- fclose(ftpfile); /* close the local file */
- fclose(respfile); /* close the response file */
-
- return 0;
-}
diff --git a/Utilities/cmcurl/Testing/ftpupload.c b/Utilities/cmcurl/Testing/ftpupload.c
deleted file mode 100644
index 780c9cd27..000000000
--- a/Utilities/cmcurl/Testing/ftpupload.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*****************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * $Id$
- */
-
-#include "curl/curl.h"
-#include "setup.h"
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "testconfig.h"
-
-/*
- * This example shows an FTP upload, with a rename of the file just after
- * a successful upload.
- *
- * Example based on source code provided by Erick Nuwendam. Thanks!
- */
-
-#define LOCAL_FILE LIBCURL_SOURCE_DIR "/Testing/ftpupload.c"
-#define UPLOAD_FILE_AS "while-uploading.txt"
-#define REMOTE_URL "ftp://public.kitware.com/incoming/" UPLOAD_FILE_AS
-#define RENAME_FILE_TO "renamed-and-fine.txt"
-
-int main(int argc, char **argv)
-{
- CURL *curl;
- CURLcode res;
- FILE *ftpfile;
- FILE * hd_src ;
- int hd ;
- struct stat file_info;
-
- struct curl_slist *headerlist=NULL;
- char buf_1 [] = "RNFR " UPLOAD_FILE_AS;
- char buf_2 [] = "RNTO " RENAME_FILE_TO;
-
- /* get the file size of the local file */
- hd = open(LOCAL_FILE, O_RDONLY) ;
- fstat(hd, &file_info);
- close(hd) ;
-
- /* get a FILE * of the same file, could also be made with
- fdopen() from the previous descriptor, but hey this is just
- an example! */
- hd_src = fopen(LOCAL_FILE, "rb");
-
- /* In windows, this will init the winsock stuff */
- curl_global_init(CURL_GLOBAL_ALL);
-
- /* get a curl handle */
- curl = curl_easy_init();
- if(curl) {
- /* build a list of commands to pass to libcurl */
- headerlist = curl_slist_append(headerlist, buf_1);
- headerlist = curl_slist_append(headerlist, buf_2);
-
- /* enable uploading */
- curl_easy_setopt(curl, CURLOPT_UPLOAD, TRUE) ;
-
- /* specify target */
- curl_easy_setopt(curl,CURLOPT_URL, REMOTE_URL);
-
- /* pass in that last of FTP commands to run after the transfer */
- curl_easy_setopt(curl, CURLOPT_POSTQUOTE, headerlist);
-
- /* now specify which file to upload */
- curl_easy_setopt(curl, CURLOPT_INFILE, hd_src);
-
- /* and give the size of the upload (optional) */
- curl_easy_setopt(curl, CURLOPT_INFILESIZE, (long)file_info.st_size);
-
- /* Now run off and do what you've been told! */
- res = curl_easy_perform(curl);
-
- /* clean up the FTP commands list */
- curl_slist_free_all (headerlist);
-
- /* always cleanup */
- curl_easy_cleanup(curl);
- }
- fclose(hd_src); /* close the local file */
-
- curl_global_cleanup();
- return 0;
-}
diff --git a/Utilities/cmcurl/Testing/getinmemory.c b/Utilities/cmcurl/Testing/getinmemory.c
deleted file mode 100644
index a8872da77..000000000
--- a/Utilities/cmcurl/Testing/getinmemory.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*****************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * $Id$
- *
- * Example source code to show how the callback function can be used to
- * download data into a chunk of memory instead of storing it in a file.
- *
- * This exact source code has not been verified to work.
- */
-
-/* to make this work under windows, use the win32-functions from the
- win32socket.c file as well */
-
-#include "curl/curl.h"
-#include "curl/types.h"
-#include "curl/easy.h"
-
-struct MemoryStruct {
- char *memory;
- size_t size;
-};
-
-size_t
-WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
-{
- register int realsize = size * nmemb;
- struct MemoryStruct *mem = (struct MemoryStruct *)data;
-
- mem->memory = (char *)realloc(mem->memory, mem->size + realsize + 1);
- if (mem->memory) {
- memcpy(&(mem->memory[mem->size]), ptr, realsize);
- mem->size += realsize;
- mem->memory[mem->size] = 0;
- }
- return realsize;
-}
-
-int main(int argc, char **argv)
-{
- CURL *curl_handle;
-
- struct MemoryStruct chunk;
-
- chunk.memory=NULL; /* we expect realloc(NULL, size) to work */
- chunk.size = 0; /* no data at this point */
-
- curl_global_init(CURL_GLOBAL_DEFAULT);
-
- /* init the curl session */
- curl_handle = curl_easy_init();
-
- /* specify URL to get */
- curl_easy_setopt(curl_handle, CURLOPT_URL, "http://www.cmake.org/HTML/Index.html");
-
- /* send all data to this function */
- curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
-
- /* we pass our 'chunk' struct to the callback function */
- curl_easy_setopt(curl_handle, CURLOPT_FILE, (void *)&chunk);
-
- /* get it! */
- curl_easy_perform(curl_handle);
-
- /* cleanup curl stuff */
- curl_easy_cleanup(curl_handle);
-
- /*
- * Now, our chunk.memory points to a memory block that is chunk.size
- * bytes big and contains the remote file.
- *
- * Do something nice with it!
- */
-
- /* For example display it... */
- write(1, chunk.memory, chunk.size);
-
- return 0;
-}
diff --git a/Utilities/cmcurl/Testing/http-post.c b/Utilities/cmcurl/Testing/http-post.c
deleted file mode 100644
index 1b4154fbf..000000000
--- a/Utilities/cmcurl/Testing/http-post.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/*****************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * $Id$
- */
-
-#include <stdio.h>
-#include <curl/curl.h>
-
-int main(void)
-{
- CURL *curl;
- CURLcode res;
-
- curl = curl_easy_init();
- if(curl) {
- /* First set the URL that is about to receive our POST. This URL can
- just as well be a https:// URL if that is what should receive the
- data. */
- curl_easy_setopt(curl, CURLOPT_URL, "http://postit.example.com/moo.cgi");
- /* Now specify the POST data */
- curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "name=daniel&project=curl");
-
- /* Perform the request, res will get the return code */
- res = curl_easy_perform(curl);
-
- /* always cleanup */
- curl_easy_cleanup(curl);
- }
- return 0;
-}
diff --git a/Utilities/cmcurl/Testing/httpput.c b/Utilities/cmcurl/Testing/httpput.c
deleted file mode 100644
index 78275c40a..000000000
--- a/Utilities/cmcurl/Testing/httpput.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*****************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * $Id$
- */
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-
-#include <curl/curl.h>
-
-/*
- * This example shows a HTTP PUT operation. PUTs a file given as a command
- * line argument to the URL also given on the command line.
- *
- * This example also uses its own read callback.
- */
-
-size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
-{
- size_t retcode;
-
- /* in real-world cases, this would probably get this data differently
- as this fread() stuff is exactly what the library already would do
- by default internally */
- retcode = fread(ptr, size, nmemb, stream);
-
- fprintf(stderr, "*** We read %d bytes from file\n", retcode);
-
- return retcode;
-}
-
-int main(int argc, char **argv)
-{
- CURL *curl;
- CURLcode res;
- FILE *ftpfile;
- FILE * hd_src ;
- int hd ;
- struct stat file_info;
-
- char *file;
- char *url;
-
- if(argc < 3)
- return 1;
-
- file= argv[1];
- url = argv[2];
-
- /* get the file size of the local file */
- hd = open(file, O_RDONLY) ;
- fstat(hd, &file_info);
- close(hd) ;
-
- /* get a FILE * of the same file, could also be made with
- fdopen() from the previous descriptor, but hey this is just
- an example! */
- hd_src = fopen(file, "rb");
-
- /* In windows, this will init the winsock stuff */
- curl_global_init(CURL_GLOBAL_ALL);
-
- /* get a curl handle */
- curl = curl_easy_init();
- if(curl) {
- /* we want to use our own read function */
- curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
-
- /* enable uploading */
- curl_easy_setopt(curl, CURLOPT_UPLOAD, TRUE) ;
-
- /* HTTP PUT please */
- curl_easy_setopt(curl, CURLOPT_PUT, TRUE);
-
- /* specify target */
- curl_easy_setopt(curl,CURLOPT_URL, url);
-
- /* now specify which file to upload */
- curl_easy_setopt(curl, CURLOPT_INFILE, hd_src);
-
- /* and give the size of the upload (optional) */
- curl_easy_setopt(curl, CURLOPT_INFILESIZE, file_info.st_size);
-
- /* Now run off and do what you've been told! */
- res = curl_easy_perform(curl);
-
- /* always cleanup */
- curl_easy_cleanup(curl);
- }
- fclose(hd_src); /* close the local file */
-
- curl_global_cleanup();
- return 0;
-}
diff --git a/Utilities/cmcurl/Testing/multithread.c b/Utilities/cmcurl/Testing/multithread.c
deleted file mode 100644
index c3936ef4a..000000000
--- a/Utilities/cmcurl/Testing/multithread.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*****************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * $Id$
- */
-
-/* A multi-threaded example that uses pthreads extensively to fetch
- * X remote files at once */
-
-#include <stdio.h>
-#include <pthread.h>
-#include <curl/curl.h>
-
-/* silly list of test-URLs */
-char *urls[]= {
- "http://curl.haxx.se/",
- "ftp://cool.haxx.se/",
- "http://www.contactor.se/",
- "www.haxx.se"
-};
-
-void *pull_one_url(void *url)
-{
- CURL *curl;
-
- curl = curl_easy_init();
-
- curl_easy_setopt(curl, CURLOPT_URL, url);
- curl_easy_perform(curl);
-
- curl_easy_cleanup(curl);
-
- return NULL;
-}
-
-
-/*
- int pthread_create(pthread_t *new_thread_ID,
- const pthread_attr_t *attr,
- void * (*start_func)(void *), void *arg);
-*/
-
-int main(int argc, char **argv)
-{
- pthread_t tid[4];
- int i;
- int error;
- for(i=0; i< 4; i++) {
- error = pthread_create(&tid[i],
- NULL, /* default attributes please */
- pull_one_url,
- urls[i]);
- if(0 != error)
- fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error);
- else
- fprintf(stderr, "Thread %d, gets %s\n", i, urls[i]);
- }
-
- /* now wait for all threads to terminate */
- for(i=0; i< 4; i++) {
- error = pthread_join(tid[i], NULL);
- fprintf(stderr, "Thread %d terminated\n", i);
- }
-
- return 0;
-}
diff --git a/Utilities/cmcurl/Testing/persistant.c b/Utilities/cmcurl/Testing/persistant.c
deleted file mode 100644
index 853470345..000000000
--- a/Utilities/cmcurl/Testing/persistant.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*****************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * $Id$
- */
-
-#include <stdio.h>
-
-#include "curl/curl.h"
-
-/* to make this work under windows, use the win32-functions from the
- docs/examples/win32socket.c file as well */
-
-/* This example REQUIRES libcurl 7.7 or later */
-#if (LIBCURL_VERSION_NUM < 0x070700)
-#error Too old libcurl version, upgrade or stay away.
-#endif
-
-int main(int argc, char **argv)
-{
- CURL *curl;
- CURLcode res;
-
-#ifdef MALLOCDEBUG
- /* this sends all memory debug messages to a specified logfile */
- curl_memdebug("memdump");
-#endif
-
- curl_global_init(CURL_GLOBAL_DEFAULT);
- curl = curl_easy_init();
- if(curl) {
- curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
- curl_easy_setopt(curl, CURLOPT_HEADER, 1);
-
- /* get the first document */
- curl_easy_setopt(curl, CURLOPT_URL, "http://www.cmake.org/");
- res = curl_easy_perform(curl);
-
- /* get another document from the same server using the same
- connection */
- curl_easy_setopt(curl, CURLOPT_URL, "http://www.cmake.org/HTML/Index.html");
- res = curl_easy_perform(curl);
-
- /* always cleanup */
- curl_easy_cleanup(curl);
- }
-
- return 0;
-}
diff --git a/Utilities/cmcurl/Testing/postit2.c b/Utilities/cmcurl/Testing/postit2.c
deleted file mode 100644
index 9b7cda07e..000000000
--- a/Utilities/cmcurl/Testing/postit2.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*****************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * $Id$
- *
- * Example code that uploads a file name 'foo' to a remote script that accepts
- * "HTML form based" (as described in RFC1738) uploads using HTTP POST.
- *
- * The imaginary form we'll fill in looks like:
- *
- * <form method="post" enctype="multipart/form-data" action="examplepost.cgi">
- * Enter file: <input type="file" name="sendfile" size="40">
- * Enter file name: <input type="text" name="filename" size="30">
- * <input type="submit" value="send" name="submit">
- * </form>
- *
- * This exact source code has not been verified to work.
- */
-
-/* to make this work under windows, use the win32-functions from the
- win32socket.c file as well */
-
-#include <stdio.h>
-#include <string.h>
-
-#include <curl/curl.h>
-#include <curl/types.h>
-#include <curl/easy.h>
-
-#if LIBCURL_VERSION_NUM < 0x070900
-#error "curl_formadd() is not introduced until libcurl 7.9 and later"
-#endif
-
-int main(int argc, char *argv[])
-{
- CURL *curl;
- CURLcode res;
-
- struct HttpPost *formpost=NULL;
- struct HttpPost *lastptr=NULL;
- struct curl_slist *headerlist=NULL;
- char buf[] = "Expect:";
-
- /* Fill in the file upload field */
- curl_formadd(&formpost,
- &lastptr,
- CURLFORM_COPYNAME, "sendfile",
- CURLFORM_FILE, "postit2.c",
- CURLFORM_END);
-
- /* Fill in the filename field */
- curl_formadd(&formpost,
- &lastptr,
- CURLFORM_COPYNAME, "filename",
- CURLFORM_COPYCONTENTS, "postit2.c",
- CURLFORM_END);
-
-
- /* Fill in the submit field too, even if this is rarely needed */
- curl_formadd(&formpost,
- &lastptr,
- CURLFORM_COPYNAME, "submit",
- CURLFORM_COPYCONTENTS, "send",
- CURLFORM_END);
-
- curl = curl_easy_init();
- /* initalize custom header list (stating that Expect: 100-continue is not
- wanted */
- headerlist = curl_slist_append(headerlist, buf);
- if(curl) {
- /* what URL that receives this POST */
- curl_easy_setopt(curl, CURLOPT_URL, "http://curl.haxx.se/examplepost.cgi");
- if ( (argc == 2) && (!strcmp(argv[1], "noexpectheader")) )
- /* only disable 100-continue header if explicitly requested */
- curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
- curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
- res = curl_easy_perform(curl);
-
- /* always cleanup */
- curl_easy_cleanup(curl);
-
- /* then cleanup the formpost chain */
- curl_formfree(formpost);
- /* free slist */
- curl_slist_free_all (headerlist);
- }
- return 0;
-}
diff --git a/Utilities/cmcurl/Testing/sepheaders.c b/Utilities/cmcurl/Testing/sepheaders.c
deleted file mode 100644
index fc5b783bc..000000000
--- a/Utilities/cmcurl/Testing/sepheaders.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*****************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * $Id$
- */
-
-/* to make this work under windows, use the win32-functions from the
- win32socket.c file as well */
-
-#include "curl/curl.h"
-#include "curl/types.h"
-#include "curl/easy.h"
-
-#include "testconfig.h"
-
-size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
-{
- int written = fwrite(ptr, size, nmemb, (FILE *)stream);
- return written;
-}
-
-int main(int argc, char **argv)
-{
- CURL *curl_handle;
- char *headerfilename = LIBCURL_BINARY_DIR "/Testing/sepheaders-head.out";
- FILE *headerfile;
- char *bodyfilename = LIBCURL_BINARY_DIR "/Testing/sepheaders-body.out";
- FILE *bodyfile;
-
- curl_global_init(CURL_GLOBAL_DEFAULT);
- /* init the curl session */
- curl_handle = curl_easy_init();
-
- /* set URL to get */
- curl_easy_setopt(curl_handle, CURLOPT_URL, "http://www.cmake.org/HTML/Index.html");
-
- /* no progress meter please */
- curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1);
-
- /* shut up completely */
- //curl_easy_setopt(curl_handle, CURLOPT_MUTE, 1);
-
- /* send all data to this function */
- curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);
-
- /* open the files */
- headerfile = fopen(headerfilename,"w");
- if (headerfile == NULL) {
- curl_easy_cleanup(curl_handle);
- return -1;
- }
- bodyfile = fopen(bodyfilename,"w");
- if (bodyfile == NULL) {
- curl_easy_cleanup(curl_handle);
- fclose(headerfile);
- return -1;
- }
-
- /* we want the headers to this file handle */
- curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER ,headerfile);
-
- /* we want the body to this file handle */
- curl_easy_setopt(curl_handle, CURLOPT_FILE ,bodyfile);
-
- /* get it! */
- curl_easy_perform(curl_handle);
-
- /* close the header file */
- fclose(headerfile);
- fclose(bodyfile);
-
- /* cleanup curl stuff */
- curl_easy_cleanup(curl_handle);
-
- return 0;
-}
diff --git a/Utilities/cmcurl/Testing/simple.c b/Utilities/cmcurl/Testing/simple.c
deleted file mode 100644
index 6dd6050ec..000000000
--- a/Utilities/cmcurl/Testing/simple.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/*****************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * $Id$
- */
-
-#include "curl/curl.h"
-
-int main(void)
-{
- CURL *curl;
- CURLcode res;
-
- curl_global_init(CURL_GLOBAL_DEFAULT);
- curl = curl_easy_init();
- if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://www.cmake.org/HTML/Index.html");
- res = curl_easy_perform(curl);
-
- /* always cleanup */
- curl_easy_cleanup(curl);
- }
- return 0;
-}
diff --git a/Utilities/cmcurl/Testing/simplessl.c b/Utilities/cmcurl/Testing/simplessl.c
deleted file mode 100644
index e307eaa6f..000000000
--- a/Utilities/cmcurl/Testing/simplessl.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*****************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * $Id$
- */
-
-#include <stdio.h>
-
-#include <curl/curl.h>
-#include <curl/types.h>
-#include <curl/easy.h>
-
-
-/* some requirements for this to work:
- 1. set pCertFile to the file with the client certificate
- 2. if the key is passphrase protected, set pPassphrase to the
- passphrase you use
- 3. if you are using a crypto engine:
- 3.1. set a #define USE_ENGINE
- 3.2. set pEngine to the name of the crypto engine you use
- 3.3. set pKeyName to the key identifier you want to use
- 4. if you don't use a crypto engine:
- 4.1. set pKeyName to the file name of your client key
- 4.2. if the format of the key file is DER, set pKeyType to "DER"
-
- !! verify of the server certificate is not implemented here !!
-
- **** This example only works with libcurl 7.9.3 and later! ****
-
-*/
-
-int main(int argc, char **argv)
-{
- CURL *curl;
- CURLcode res;
- FILE *headerfile;
-
- const char *pCertFile = "testcert.pem";
- const char *pCACertFile="cacert.pem"
-
- const char *pKeyName;
- const char *pKeyType;
-
- const char *pEngine;
-
-#if USE_ENGINE
- pKeyName = "rsa_test";
- pKeyType = "ENG";
- pEngine = "chil"; /* for nChiper HSM... */
-#else
- pKeyName = "testkey.pem";
- pKeyType = "PEM";
- pEngine = NULL;
-#endif
-
- const char *pPassphrase = NULL;
-
- headerfile = fopen("dumpit", "w");
-
- curl_global_init(CURL_GLOBAL_DEFAULT);
-
- curl = curl_easy_init();
- if(curl) {
- /* what call to write: */
- curl_easy_setopt(curl, CURLOPT_URL, "HTTPS://curl.haxx.se");
- curl_easy_setopt(curl, CURLOPT_WRITEHEADER, headerfile);
-
- while(1) /* do some ugly short cut... */
- {
- if (pEngine) /* use crypto engine */
- {
- if (curl_easy_setopt(curl, CURLOPT_SSLENGINE,pEngine) != CURLE_OK)
- { /* load the crypto engine */
- fprintf(stderr,"can't set crypto engine\n");
- break;
- }
- if (curl_easy_setopt(curl, CURLOPT_SSLENGINE_DEFAULT,1) != CURLE_OK)
- { /* set the crypto engine as default */
- /* only needed for the first time you load
- a engine in a curl object... */
- fprintf(stderr,"can't set crypto engine as default\n");
- break;
- }
- }
- /* cert is stored PEM coded in file... */
- /* since PEM is default, we needn't set it for PEM */
- curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"PEM");
- /* set the cert for client authentication */
- curl_easy_setopt(curl,CURLOPT_SSLCERT,pCertFile);
- /* sorry, for engine we must set the passphrase
- (if the key has one...) */
- if (pPassphrase)
- curl_easy_setopt(curl,CURLOPT_SSLKEYPASSWD,pPassphrase);
- /* if we use a key stored in a crypto engine,
- we must set the key type to "ENG" */
- curl_easy_setopt(curl,CURLOPT_SSLKEYTYPE,pKeyType);
- /* set the private key (file or ID in engine) */
- curl_easy_setopt(curl,CURLOPT_SSLKEY,pKeyName);
- /* set the file with the certs vaildating the server */
- curl_easy_setopt(curl,CURLOPT_CAINFO,pCACertFile);
- /* disconnect if we can't validate server's cert */
- curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,1);
-
- res = curl_easy_perform(curl);
- break; /* we are done... */
- }
- /* always cleanup */
- curl_easy_cleanup(curl);
- }
-
- curl_global_cleanup();
-
- if (headerfile)
- fclose(headerfile);
- return 0;
-}
diff --git a/Utilities/cmcurl/Testing/testconfig.h.in b/Utilities/cmcurl/Testing/testconfig.h.in
deleted file mode 100644
index faab46223..000000000
--- a/Utilities/cmcurl/Testing/testconfig.h.in
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __testconfig_h__
-#define __testconfig_h__
-
-#define LIBCURL_SOURCE_DIR "${LIBCURL_SOURCE_DIR}"
-#define LIBCURL_BINARY_DIR "${LIBCURL_BINARY_DIR}"
-
-#endif /* __testconfig_h__ */
diff --git a/Utilities/cmcurl/Testing/win32sockets.c b/Utilities/cmcurl/Testing/win32sockets.c
deleted file mode 100644
index 5f791c8b5..000000000
--- a/Utilities/cmcurl/Testing/win32sockets.c
+++ /dev/null
@@ -1,49 +0,0 @@
-
-/*
- * Note: This is only required if you use curl 7.8 or lower, later
- * versions provide an option to curl_global_init() that does the
- * win32 initialization for you.
- */
-
-/*
- * These are example functions doing socket init that Windows
- * require. If you don't use windows, you can safely ignore this crap.
- */
-
-#include <windows.h>
-
-void win32_cleanup(void)
-{
- WSACleanup();
-}
-
-int win32_init(void)
-{
- WORD wVersionRequested;
- WSADATA wsaData;
- int err;
- wVersionRequested = MAKEWORD(1, 1);
-
- err = WSAStartup(wVersionRequested, &wsaData);
-
- if (err != 0)
- /* Tell the user that we couldn't find a useable */
- /* winsock.dll. */
- return 1;
-
- /* Confirm that the Windows Sockets DLL supports 1.1.*/
- /* Note that if the DLL supports versions greater */
- /* than 1.1 in addition to 1.1, it will still return */
- /* 1.1 in wVersion since that is the version we */
- /* requested. */
-
- if ( LOBYTE( wsaData.wVersion ) != 1 ||
- HIBYTE( wsaData.wVersion ) != 1 ) {
- /* Tell the user that we couldn't find a useable */
-
- /* winsock.dll. */
- WSACleanup();
- return 1;
- }
- return 0; /* 0 is ok */
-}
diff --git a/Utilities/cmcurl/amigaos.c b/Utilities/cmcurl/amigaos.c
deleted file mode 100644
index 7106f8daf..000000000
--- a/Utilities/cmcurl/amigaos.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "amigaos.h"
-#include <amitcp/socketbasetags.h>
-
-struct Library *SocketBase = NULL;
-extern int errno, h_errno;
-
-#ifdef __libnix__
-#include <stabs.h>
-void __request(const char *msg);
-#else
-# define __request( msg ) Printf( msg "\n\a")
-#endif
-
-void amiga_cleanup()
-{
- if(SocketBase) {
- CloseLibrary(SocketBase);
- SocketBase = NULL;
- }
-}
-
-BOOL amiga_init()
-{
- if(!SocketBase)
- SocketBase = OpenLibrary("bsdsocket.library", 4);
-
- if(!SocketBase) {
- __request("No TCP/IP Stack running!");
- return FALSE;
- }
-
- if(SocketBaseTags(
- SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG) &errno,
-// SBTM_SETVAL(SBTC_HERRNOLONGPTR), (ULONG) &h_errno,
- SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "cURL",
- TAG_DONE)) {
-
- __request("SocketBaseTags ERROR");
- return FALSE;
- }
-
-#ifndef __libnix__
- atexit(amiga_cleanup);
-#endif
-
- return TRUE;
-}
-
-#ifdef __libnix__
-ADD2EXIT(amiga_cleanup,-50);
-#endif
diff --git a/Utilities/cmcurl/amigaos.h b/Utilities/cmcurl/amigaos.h
deleted file mode 100644
index e5786d482..000000000
--- a/Utilities/cmcurl/amigaos.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#ifndef LIBCURL_AMIGAOS_H
-#define LIBCURL_AMIGAOS_H
-
-#ifndef __ixemul__
-
-#include <exec/types.h>
-#include <exec/execbase.h>
-
-#include <proto/exec.h>
-#include <proto/dos.h>
-
-#include <sys/socket.h>
-
-#include "config-amigaos.h"
-
-#ifndef select
-# define select(args...) WaitSelect( args, NULL)
-#endif
-#ifndef inet_ntoa
-# define inet_ntoa(x) Inet_NtoA( x ## .s_addr)
-#endif
-#ifndef ioctl
-# define ioctl(a,b,c,d) IoctlSocket( (LONG)a, (ULONG)b, (char*)c)
-#endif
-#define _AMIGASF 1
-
-extern void amiga_cleanup();
-extern BOOL amiga_init();
-
-#else /* __ixemul__ */
-
-#warning compiling with ixemul...
-
-#endif /* __ixemul__ */
-#endif /* LIBCURL_AMIGAOS_H */
diff --git a/Utilities/cmcurl/arpa_telnet.h b/Utilities/cmcurl/arpa_telnet.h
deleted file mode 100644
index e6a04dcef..000000000
--- a/Utilities/cmcurl/arpa_telnet.h
+++ /dev/null
@@ -1,101 +0,0 @@
-#ifndef __ARPA_TELNET_H
-#define __ARPA_TELNET_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-#ifndef CURL_DISABLE_TELNET
-/*
- * Telnet option defines. Add more here if in need.
- */
-#define CURL_TELOPT_BINARY 0 /* binary 8bit data */
-#define CURL_TELOPT_SGA 3 /* Supress Go Ahead */
-#define CURL_TELOPT_EXOPL 255 /* EXtended OPtions List */
-#define CURL_TELOPT_TTYPE 24 /* Terminal TYPE */
-#define CURL_TELOPT_XDISPLOC 35 /* X DISPlay LOCation */
-
-#define CURL_TELOPT_NEW_ENVIRON 39 /* NEW ENVIRONment variables */
-#define CURL_NEW_ENV_VAR 0
-#define CURL_NEW_ENV_VALUE 1
-
-/*
- * The telnet options represented as strings
- */
-static const char * const telnetoptions[]=
-{
- "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD",
- "NAME", "STATUS", "TIMING MARK", "RCTE",
- "NAOL", "NAOP", "NAOCRD", "NAOHTS",
- "NAOHTD", "NAOFFD", "NAOVTS", "NAOVTD",
- "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",
- "DE TERMINAL", "SUPDUP", "SUPDUP OUTPUT", "SEND LOCATION",
- "TERM TYPE", "END OF RECORD", "TACACS UID", "OUTPUT MARKING",
- "TTYLOC", "3270 REGIME", "X3 PAD", "NAWS",
- "TERM SPEED", "LFLOW", "LINEMODE", "XDISPLOC",
- "OLD-ENVIRON", "AUTHENTICATION", "ENCRYPT", "NEW-ENVIRON"
-};
-
-#define CURL_TELOPT_MAXIMUM CURL_TELOPT_NEW_ENVIRON
-
-#define CURL_TELOPT_OK(x) ((x) <= CURL_TELOPT_MAXIMUM)
-#define CURL_TELOPT(x) telnetoptions[x]
-
-#define CURL_NTELOPTS 40
-
-/*
- * First some defines
- */
-#define CURL_xEOF 236 /* End Of File */
-#define CURL_SE 240 /* Sub negotiation End */
-#define CURL_NOP 241 /* No OPeration */
-#define CURL_DM 242 /* Data Mark */
-#define CURL_GA 249 /* Go Ahead, reverse the line */
-#define CURL_SB 250 /* SuBnegotiation */
-#define CURL_WILL 251 /* Our side WILL use this option */
-#define CURL_WONT 252 /* Our side WON'T use this option */
-#define CURL_DO 253 /* DO use this option! */
-#define CURL_DONT 254 /* DON'T use this option! */
-#define CURL_IAC 255 /* Interpret As Command */
-
-/*
- * Then those numbers represented as strings:
- */
-static const char * const telnetcmds[]=
-{
- "EOF", "SUSP", "ABORT", "EOR", "SE",
- "NOP", "DMARK", "BRK", "IP", "AO",
- "AYT", "EC", "EL", "GA", "SB",
- "WILL", "WONT", "DO", "DONT", "IAC"
-};
-
-#define CURL_TELCMD_MINIMUM CURL_xEOF /* the first one */
-#define CURL_TELCMD_MAXIMUM CURL_IAC /* surprise, 255 is the last one! ;-) */
-
-#define CURL_TELQUAL_IS 0
-#define CURL_TELQUAL_SEND 1
-#define CURL_TELQUAL_INFO 2
-#define CURL_TELQUAL_NAME 3
-
-#define CURL_TELCMD_OK(x) ( ((unsigned int)(x) >= CURL_TELCMD_MINIMUM) && \
- ((unsigned int)(x) <= CURL_TELCMD_MAXIMUM) )
-#define CURL_TELCMD(x) telnetcmds[(x)-CURL_TELCMD_MINIMUM]
-#endif
-#endif
diff --git a/Utilities/cmcurl/base64.c b/Utilities/cmcurl/base64.c
deleted file mode 100644
index aa03f8346..000000000
--- a/Utilities/cmcurl/base64.c
+++ /dev/null
@@ -1,366 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-/* Base64 encoding/decoding
- *
- * Test harnesses down the bottom - compile with -DTEST_ENCODE for
- * a program that will read in raw data from stdin and write out
- * a base64-encoded version to stdout, and the length returned by the
- * encoding function to stderr. Compile with -DTEST_DECODE for a program that
- * will go the other way.
- *
- * This code will break if int is smaller than 32 bits
- */
-
-#include "setup.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-#include "urldata.h" /* for the SessionHandle definition */
-#include "easyif.h" /* for Curl_convert_... prototypes */
-#include "base64.h"
-#include "memory.h"
-
-/* include memdebug.h last */
-#include "memdebug.h"
-
-/* ---- Base64 Encoding/Decoding Table --- */
-static const char table64[]=
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-static void decodeQuantum(unsigned char *dest, const char *src)
-{
- unsigned int x = 0;
- int i;
- char *found;
-
- for(i = 0; i < 4; i++) {
- if((found = strchr(table64, src[i])))
- x = (x << 6) + (unsigned int)(found - table64);
- else if(src[i] == '=')
- x = (x << 6);
- }
-
- dest[2] = (unsigned char)(x & 255);
- x >>= 8;
- dest[1] = (unsigned char)(x & 255);
- x >>= 8;
- dest[0] = (unsigned char)(x & 255);
-}
-
-/*
- * Curl_base64_decode()
- *
- * Given a base64 string at src, decode it and return an allocated memory in
- * the *outptr. Returns the length of the decoded data.
- */
-size_t Curl_base64_decode(const char *src, unsigned char **outptr)
-{
- int length = 0;
- int equalsTerm = 0;
- int i;
- int numQuantums;
- unsigned char lastQuantum[3];
- size_t rawlen=0;
- unsigned char *newstr;
-
- *outptr = NULL;
-
- while((src[length] != '=') && src[length])
- length++;
- /* A maximum of two = padding characters is allowed */
- if(src[length] == '=') {
- equalsTerm++;
- if(src[length+equalsTerm] == '=')
- equalsTerm++;
- }
- numQuantums = (length + equalsTerm) / 4;
-
- /* Don't allocate a buffer if the decoded length is 0 */
- if (numQuantums <= 0)
- return 0;
-
- rawlen = (numQuantums * 3) - equalsTerm;
-
- /* The buffer must be large enough to make room for the last quantum
- (which may be partially thrown out) and the zero terminator. */
- newstr = malloc(rawlen+4);
- if(!newstr)
- return 0;
-
- *outptr = newstr;
-
- /* Decode all but the last quantum (which may not decode to a
- multiple of 3 bytes) */
- for(i = 0; i < numQuantums - 1; i++) {
- decodeQuantum((unsigned char *)newstr, src);
- newstr += 3; src += 4;
- }
-
- /* This final decode may actually read slightly past the end of the buffer
- if the input string is missing pad bytes. This will almost always be
- harmless. */
- decodeQuantum(lastQuantum, src);
- for(i = 0; i < 3 - equalsTerm; i++)
- newstr[i] = lastQuantum[i];
-
- newstr[i] = 0; /* zero terminate */
- return rawlen;
-}
-
-/*
- * Curl_base64_encode()
- *
- * Returns the length of the newly created base64 string. The third argument
- * is a pointer to an allocated area holding the base64 data. If something
- * went wrong, -1 is returned.
- *
- */
-size_t Curl_base64_encode(struct SessionHandle *data,
- const char *inp, size_t insize, char **outptr)
-{
- unsigned char ibuf[3];
- unsigned char obuf[4];
- int i;
- int inputparts;
- char *output;
- char *base64data;
-#ifdef CURL_DOES_CONVERSIONS
- char *convbuf;
-#endif
-
- char *indata = (char *)inp;
-
- *outptr = NULL; /* set to NULL in case of failure before we reach the end */
-
- if(0 == insize)
- insize = strlen(indata);
-
- base64data = output = (char*)malloc(insize*4/3+4);
- if(NULL == output)
- return 0;
-
-#ifdef CURL_DOES_CONVERSIONS
- /*
- * The base64 data needs to be created using the network encoding
- * not the host encoding. And we can't change the actual input
- * so we copy it to a buffer, translate it, and use that instead.
- */
- if(data) {
- convbuf = (char*)malloc(insize);
- if(!convbuf) {
- return 0;
- }
- memcpy(convbuf, indata, insize);
- if(CURLE_OK != Curl_convert_to_network(data, convbuf, insize)) {
- free(convbuf);
- return 0;
- }
- indata = convbuf; /* switch to the converted buffer */
- }
-#else
- (void)data;
-#endif
-
- while(insize > 0) {
- for (i = inputparts = 0; i < 3; i++) {
- if(insize > 0) {
- inputparts++;
- ibuf[i] = *indata;
- indata++;
- insize--;
- }
- else
- ibuf[i] = 0;
- }
-
- obuf[0] = (unsigned char) ((ibuf[0] & 0xFC) >> 2);
- obuf[1] = (unsigned char) (((ibuf[0] & 0x03) << 4) | \
- ((ibuf[1] & 0xF0) >> 4));
- obuf[2] = (unsigned char) (((ibuf[1] & 0x0F) << 2) | \
- ((ibuf[2] & 0xC0) >> 6));
- obuf[3] = (unsigned char) (ibuf[2] & 0x3F);
-
- switch(inputparts) {
- case 1: /* only one byte read */
- snprintf(output, 5, "%c%c==",
- table64[obuf[0]],
- table64[obuf[1]]);
- break;
- case 2: /* two bytes read */
- snprintf(output, 5, "%c%c%c=",
- table64[obuf[0]],
- table64[obuf[1]],
- table64[obuf[2]]);
- break;
- default:
- snprintf(output, 5, "%c%c%c%c",
- table64[obuf[0]],
- table64[obuf[1]],
- table64[obuf[2]],
- table64[obuf[3]] );
- break;
- }
- output += 4;
- }
- *output=0;
- *outptr = base64data; /* make it return the actual data memory */
-
-#ifdef CURL_DOES_CONVERSIONS
- if(data)
- free(convbuf);
-#endif
- return strlen(base64data); /* return the length of the new data */
-}
-/* ---- End of Base64 Encoding ---- */
-
-/************* TEST HARNESS STUFF ****************/
-
-
-#ifdef TEST_ENCODE
-/* encoding test harness. Read in standard input and write out the length
- * returned by Curl_base64_encode, followed by the base64'd data itself
- */
-#include <stdio.h>
-
-#define TEST_NEED_SUCK
-void *suck(int *);
-
-int main(int argc, char **argv, char **envp)
-{
- char *base64;
- size_t base64Len;
- unsigned char *data;
- int dataLen;
- struct SessionHandle *handle = NULL;
-
-#ifdef CURL_DOES_CONVERSIONS
- /* get a Curl handle so Curl_base64_encode can translate properly */
- handle = curl_easy_init();
- if(handle == NULL) {
- fprintf(stderr, "Error: curl_easy_init failed\n");
- return 0;
- }
-#endif
- data = (unsigned char *)suck(&dataLen);
- base64Len = Curl_base64_encode(handle, data, dataLen, &base64);
-
- fprintf(stderr, "%d\n", base64Len);
- fprintf(stdout, "%s\n", base64);
-
- free(base64); free(data);
-#ifdef CURL_DOES_CONVERSIONS
- curl_easy_cleanup(handle);
-#endif
- return 0;
-}
-#endif
-
-#ifdef TEST_DECODE
-/* decoding test harness. Read in a base64 string from stdin and write out the
- * length returned by Curl_base64_decode, followed by the decoded data itself
- *
- * gcc -DTEST_DECODE base64.c -o base64 mprintf.o memdebug.o
- */
-#include <stdio.h>
-
-#define TEST_NEED_SUCK
-void *suck(int *);
-
-int main(int argc, char **argv, char **envp)
-{
- char *base64;
- int base64Len;
- unsigned char *data;
- int dataLen;
- int i, j;
-#ifdef CURL_DOES_CONVERSIONS
- /* get a Curl handle so main can translate properly */
- struct SessionHandle *handle = curl_easy_init();
- if(handle == NULL) {
- fprintf(stderr, "Error: curl_easy_init failed\n");
- return 0;
- }
-#endif
-
- base64 = (char *)suck(&base64Len);
- dataLen = Curl_base64_decode(base64, &data);
-
- fprintf(stderr, "%d\n", dataLen);
-
- for(i=0; i < dataLen; i+=0x10) {
- printf("0x%02x: ", i);
- for(j=0; j < 0x10; j++)
- if((j+i) < dataLen)
- printf("%02x ", data[i+j]);
- else
- printf(" ");
-
- printf(" | ");
-
- for(j=0; j < 0x10; j++)
- if((j+i) < dataLen) {
-#ifdef CURL_DOES_CONVERSIONS
- if(CURLE_OK !=
- Curl_convert_from_network(handle, &data[i+j], (size_t)1))
- data[i+j] = '.';
-#endif /* CURL_DOES_CONVERSIONS */
- printf("%c", ISGRAPH(data[i+j])?data[i+j]:'.');
- } else
- break;
- puts("");
- }
-
-#ifdef CURL_DOES_CONVERSIONS
- curl_easy_cleanup(handle);
-#endif
- free(base64); free(data);
- return 0;
-}
-#endif
-
-#ifdef TEST_NEED_SUCK
-/* this function 'sucks' in as much as possible from stdin */
-void *suck(int *lenptr)
-{
- int cursize = 8192;
- unsigned char *buf = NULL;
- int lastread;
- int len = 0;
-
- do {
- cursize *= 2;
- buf = (unsigned char *)realloc(buf, cursize);
- memset(buf + len, 0, cursize - len);
- lastread = fread(buf + len, 1, cursize - len, stdin);
- len += lastread;
- } while(!feof(stdin));
-
- lenptr[0] = len;
- return (void *)buf;
-}
-#endif
diff --git a/Utilities/cmcurl/base64.h b/Utilities/cmcurl/base64.h
deleted file mode 100644
index 59742bcd3..000000000
--- a/Utilities/cmcurl/base64.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef __BASE64_H
-#define __BASE64_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-size_t Curl_base64_encode(struct SessionHandle *data,
- const char *input, size_t size, char **str);
-size_t Curl_base64_decode(const char *source, unsigned char **outptr);
-#endif
diff --git a/Utilities/cmcurl/ca-bundle.h b/Utilities/cmcurl/ca-bundle.h
deleted file mode 100644
index 12390bc7b..000000000
--- a/Utilities/cmcurl/ca-bundle.h
+++ /dev/null
@@ -1 +0,0 @@
-/* ca bundle path set in here*/
diff --git a/Utilities/cmcurl/config.h.in b/Utilities/cmcurl/config.h.in
deleted file mode 100644
index 148722b2f..000000000
--- a/Utilities/cmcurl/config.h.in
+++ /dev/null
@@ -1,720 +0,0 @@
-/* lib/config.h.in. Generated from configure.ac by autoheader. */
-
-/* when building libcurl itself */
-#cmakedefine BUILDING_LIBCURL ${BUILDING_LIBCURL}
-
-/* to disable cookies support */
-#cmakedefine CURL_DISABLE_COOKIES ${CURL_DISABLE_COOKIES}
-
-/* to disable cryptographic authentication */
-#cmakedefine CURL_DISABLE_CRYPTO_AUTH ${CURL_DISABLE_CRYPTO_AUTH}
-
-/* to disable DICT */
-#cmakedefine CURL_DISABLE_DICT ${CURL_DISABLE_DICT}
-
-/* to disable FILE */
-#cmakedefine CURL_DISABLE_FILE ${CURL_DISABLE_FILE}
-
-/* to disable FTP */
-#cmakedefine CURL_DISABLE_FTP ${CURL_DISABLE_FTP}
-
-/* to disable HTTP */
-#cmakedefine CURL_DISABLE_HTTP ${CURL_DISABLE_HTTP}
-
-/* to disable LDAP */
-#cmakedefine CURL_DISABLE_LDAP ${CURL_DISABLE_LDAP}
-
-/* to disable TELNET */
-#cmakedefine CURL_DISABLE_TELNET ${CURL_DISABLE_TELNET}
-
-/* to disable TFTP */
-#cmakedefine CURL_DISABLE_TFTP ${CURL_DISABLE_TFTP}
-
-/* to disable verbose strings */
-#cmakedefine CURL_DISABLE_VERBOSE_STRINGS ${CURL_DISABLE_VERBOSE_STRINGS}
-
-/* to make a symbol visible */
-#cmakedefine CURL_EXTERN_SYMBOL ${CURL_EXTERN_SYMBOL}
-
-/* to enable hidden symbols */
-#cmakedefine CURL_HIDDEN_SYMBOLS ${CURL_HIDDEN_SYMBOLS}
-
-/* when not building a shared library */
-#cmakedefine CURL_STATICLIB ${CURL_STATICLIB}
-
-/* Set to explicitly specify we don't want to use thread-safe functions */
-#cmakedefine DISABLED_THREADSAFE ${DISABLED_THREADSAFE}
-
-/* lber dynamic library file */
-#cmakedefine DL_LBER_FILE ${DL_LBER_FILE}
-
-/* ldap dynamic library file */
-#cmakedefine DL_LDAP_FILE ${DL_LDAP_FILE}
-
-/* your Entropy Gathering Daemon socket pathname */
-#cmakedefine EGD_SOCKET ${EGD_SOCKET}
-
-/* Define if you want to enable IPv6 support */
-#cmakedefine ENABLE_IPV6 ${ENABLE_IPV6}
-
-/* Define to the type qualifier of arg 1 for getnameinfo. */
-#cmakedefine GETNAMEINFO_QUAL_ARG1 ${GETNAMEINFO_QUAL_ARG1}
-
-/* Define to the type of arg 1 for getnameinfo. */
-#cmakedefine GETNAMEINFO_TYPE_ARG1 ${GETNAMEINFO_TYPE_ARG1}
-
-/* Define to the type of arg 2 for getnameinfo. */
-#cmakedefine GETNAMEINFO_TYPE_ARG2 ${GETNAMEINFO_TYPE_ARG2}
-
-/* Define to the type of args 4 and 6 for getnameinfo. */
-#cmakedefine GETNAMEINFO_TYPE_ARG46 ${GETNAMEINFO_TYPE_ARG46}
-
-/* Define to the type of arg 7 for getnameinfo. */
-#cmakedefine GETNAMEINFO_TYPE_ARG7 ${GETNAMEINFO_TYPE_ARG7}
-
-/* Define to 1 if you have the <alloca.h> header file. */
-#cmakedefine HAVE_ALLOCA_H ${HAVE_ALLOCA_H}
-
-/* Define to 1 if you have the <arpa/inet.h> header file. */
-#cmakedefine HAVE_ARPA_INET_H ${HAVE_ARPA_INET_H}
-
-/* Define to 1 if you have the <arpa/tftp.h> header file. */
-#cmakedefine HAVE_ARPA_TFTP_H ${HAVE_ARPA_TFTP_H}
-
-/* Define to 1 if you have the <assert.h> header file. */
-#cmakedefine HAVE_ASSERT_H ${HAVE_ASSERT_H}
-
-/* Define to 1 if you have the `basename' function. */
-#cmakedefine HAVE_BASENAME ${HAVE_BASENAME}
-
-/* Define to 1 if you have the `closesocket' function. */
-#cmakedefine HAVE_CLOSESOCKET ${HAVE_CLOSESOCKET}
-
-/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
-#cmakedefine HAVE_CRYPTO_CLEANUP_ALL_EX_DATA ${HAVE_CRYPTO_CLEANUP_ALL_EX_DATA}
-
-/* Define to 1 if you have the <crypto.h> header file. */
-#cmakedefine HAVE_CRYPTO_H ${HAVE_CRYPTO_H}
-
-/* Define to 1 if you have the <des.h> header file. */
-#cmakedefine HAVE_DES_H ${HAVE_DES_H}
-
-/* disabled non-blocking sockets */
-#cmakedefine HAVE_DISABLED_NONBLOCKING ${HAVE_DISABLED_NONBLOCKING}
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#cmakedefine HAVE_DLFCN_H ${HAVE_DLFCN_H}
-
-/* Define to 1 if you have the `dlopen' function. */
-#cmakedefine HAVE_DLOPEN ${HAVE_DLOPEN}
-
-/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */
-#cmakedefine HAVE_ENGINE_LOAD_BUILTIN_ENGINES ${HAVE_ENGINE_LOAD_BUILTIN_ENGINES}
-
-/* Define to 1 if you have the <errno.h> header file. */
-#cmakedefine HAVE_ERRNO_H ${HAVE_ERRNO_H}
-
-/* Define to 1 if you have the <err.h> header file. */
-#cmakedefine HAVE_ERR_H ${HAVE_ERR_H}
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#cmakedefine HAVE_FCNTL_H ${HAVE_FCNTL_H}
-
-/* use FIONBIO for non-blocking sockets */
-#cmakedefine HAVE_FIONBIO ${HAVE_FIONBIO}
-
-/* Define to 1 if you have the `fork' function. */
-#cmakedefine HAVE_FORK ${HAVE_FORK}
-
-/* Define to 1 if you have the `ftruncate' function. */
-#cmakedefine HAVE_FTRUNCATE ${HAVE_FTRUNCATE}
-
-/* Define if getaddrinfo exists and works */
-#cmakedefine HAVE_GETADDRINFO ${HAVE_GETADDRINFO}
-
-/* Define to 1 if you have the `geteuid' function. */
-#cmakedefine HAVE_GETEUID ${HAVE_GETEUID}
-
-/* Define to 1 if you have the `gethostbyaddr' function. */
-#cmakedefine HAVE_GETHOSTBYADDR ${HAVE_GETHOSTBYADDR}
-
-/* If you have gethostbyname */
-#cmakedefine HAVE_GETHOSTBYNAME ${HAVE_GETHOSTBYNAME}
-
-/* Define to 1 if you have the `gethostbyname_r' function. */
-#cmakedefine HAVE_GETHOSTBYNAME_R ${HAVE_GETHOSTBYNAME_R}
-
-/* gethostbyname_r() takes 3 args */
-#cmakedefine HAVE_GETHOSTBYNAME_R_3 ${HAVE_GETHOSTBYNAME_R_3}
-
-/* gethostbyname_r() takes 5 args */
-#cmakedefine HAVE_GETHOSTBYNAME_R_5 ${HAVE_GETHOSTBYNAME_R_5}
-
-/* gethostbyname_r() takes 6 args */
-#cmakedefine HAVE_GETHOSTBYNAME_R_6 ${HAVE_GETHOSTBYNAME_R_6}
-
-/* Define to 1 if you have the getnameinfo function. */
-#cmakedefine HAVE_GETNAMEINFO ${HAVE_GETNAMEINFO}
-
-/* Define to 1 if you have the `getpass_r' function. */
-#cmakedefine HAVE_GETPASS_R ${HAVE_GETPASS_R}
-
-/* Define to 1 if you have the `getprotobyname' function. */
-#cmakedefine HAVE_GETPROTOBYNAME ${HAVE_GETPROTOBYNAME}
-
-/* Define to 1 if you have the `getpwuid' function. */
-#cmakedefine HAVE_GETPWUID ${HAVE_GETPWUID}
-
-/* Define to 1 if you have the `getrlimit' function. */
-#cmakedefine HAVE_GETRLIMIT ${HAVE_GETRLIMIT}
-
-/* Define to 1 if you have the `gettimeofday' function. */
-#cmakedefine HAVE_GETTIMEOFDAY ${HAVE_GETTIMEOFDAY}
-
-/* Define to 1 if you have the `gmtime_r' function. */
-#cmakedefine HAVE_GMTIME_R ${HAVE_GMTIME_R}
-
-/* if you have the gssapi libraries */
-#cmakedefine HAVE_GSSAPI ${HAVE_GSSAPI}
-
-/* if you have the GNU gssapi libraries */
-#cmakedefine HAVE_GSSGNU ${HAVE_GSSGNU}
-
-/* if you have the Heimdal gssapi libraries */
-#cmakedefine HAVE_GSSHEIMDAL ${HAVE_GSSHEIMDAL}
-
-/* if you have the MIT gssapi libraries */
-#cmakedefine HAVE_GSSMIT ${HAVE_GSSMIT}
-
-/* Define to 1 if you have the `idna_strerror' function. */
-#cmakedefine HAVE_IDNA_STRERROR ${HAVE_IDNA_STRERROR}
-
-/* Define to 1 if you have the `idn_free' function. */
-#cmakedefine HAVE_IDN_FREE ${HAVE_IDN_FREE}
-
-/* Define to 1 if you have the <idn-free.h> header file. */
-#cmakedefine HAVE_IDN_FREE_H ${HAVE_IDN_FREE_H}
-
-/* Define to 1 if you have the `inet_addr' function. */
-#cmakedefine HAVE_INET_ADDR ${HAVE_INET_ADDR}
-
-/* Define to 1 if you have the `inet_ntoa' function. */
-#cmakedefine HAVE_INET_NTOA ${HAVE_INET_NTOA}
-
-/* Define to 1 if you have the `inet_ntoa_r' function. */
-#cmakedefine HAVE_INET_NTOA_R ${HAVE_INET_NTOA_R}
-
-/* inet_ntoa_r() is declared */
-#cmakedefine HAVE_INET_NTOA_R_DECL ${HAVE_INET_NTOA_R_DECL}
-
-/* Define to 1 if you have the `inet_pton' function. */
-#cmakedefine HAVE_INET_PTON ${HAVE_INET_PTON}
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#cmakedefine HAVE_INTTYPES_H ${HAVE_INTTYPES_H}
-
-/* use ioctlsocket() for non-blocking sockets */
-#cmakedefine HAVE_IOCTLSOCKET ${HAVE_IOCTLSOCKET}
-
-/* use Ioctlsocket() for non-blocking sockets */
-#cmakedefine HAVE_IOCTLSOCKET_CASE ${HAVE_IOCTLSOCKET_CASE}
-
-/* Define to 1 if you have the <io.h> header file. */
-#cmakedefine HAVE_IO_H ${HAVE_IO_H}
-
-/* if you have the Kerberos4 libraries (including -ldes) */
-#cmakedefine HAVE_KRB4 ${HAVE_KRB4}
-
-/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */
-#cmakedefine HAVE_KRB_GET_OUR_IP_FOR_REALM ${HAVE_KRB_GET_OUR_IP_FOR_REALM}
-
-/* Define to 1 if you have the <krb.h> header file. */
-#cmakedefine HAVE_KRB_H ${HAVE_KRB_H}
-
-/* Define to 1 if you have the `dl' library (-ldl). */
-#cmakedefine HAVE_LIBDL ${HAVE_LIBDL}
-
-/* Define to 1 if you have the <libgen.h> header file. */
-#cmakedefine HAVE_LIBGEN_H ${HAVE_LIBGEN_H}
-
-/* Define to 1 if you have the `idn' library (-lidn). */
-#cmakedefine HAVE_LIBIDN ${HAVE_LIBIDN}
-
-/* Define to 1 if you have the `resolv' library (-lresolv). */
-#cmakedefine HAVE_LIBRESOLV ${HAVE_LIBRESOLV}
-
-/* Define to 1 if you have the `resolve' library (-lresolve). */
-#cmakedefine HAVE_LIBRESOLVE ${HAVE_LIBRESOLVE}
-
-/* Define to 1 if you have the `socket' library (-lsocket). */
-#cmakedefine HAVE_LIBSOCKET ${HAVE_LIBSOCKET}
-
-/* Define to 1 if you have the `ssh2' library (-lssh2). */
-#cmakedefine HAVE_LIBSSH2 ${HAVE_LIBSSH2}
-
-/* Define to 1 if you have the <libssh2.h> header file. */
-#cmakedefine HAVE_LIBSSH2_H ${HAVE_LIBSSH2_H}
-
-/* if zlib is available */
-#cmakedefine HAVE_LIBZ ${HAVE_LIBZ}
-
-/* Define to 1 if you have the <limits.h> header file. */
-#cmakedefine HAVE_LIMITS_H ${HAVE_LIMITS_H}
-
-/* if your compiler supports LL */
-#cmakedefine HAVE_LL ${HAVE_LL}
-
-/* Define to 1 if you have the <locale.h> header file. */
-#cmakedefine HAVE_LOCALE_H ${HAVE_LOCALE_H}
-
-/* Define to 1 if you have the `localtime_r' function. */
-#cmakedefine HAVE_LOCALTIME_R ${HAVE_LOCALTIME_R}
-
-/* if your compiler supports long long */
-#cmakedefine HAVE_LONGLONG ${HAVE_LONGLONG}
-
-/* Define to 1 if you have the malloc.h header file. */
-#cmakedefine HAVE_MALLOC_H ${HAVE_MALLOC_H}
-
-/* Define to 1 if you have the <memory.h> header file. */
-#cmakedefine HAVE_MEMORY_H ${HAVE_MEMORY_H}
-
-/* Define to 1 if you have the MSG_NOSIGNAL flag. */
-#cmakedefine HAVE_MSG_NOSIGNAL ${HAVE_MSG_NOSIGNAL}
-
-/* Define to 1 if you have the <netdb.h> header file. */
-#cmakedefine HAVE_NETDB_H ${HAVE_NETDB_H}
-
-/* Define to 1 if you have the <netinet/in.h> header file. */
-#cmakedefine HAVE_NETINET_IN_H ${HAVE_NETINET_IN_H}
-
-/* Define to 1 if you have the <netinet/tcp.h> header file. */
-#cmakedefine HAVE_NETINET_TCP_H ${HAVE_NETINET_TCP_H}
-
-/* Define to 1 if you have the <net/if.h> header file. */
-#cmakedefine HAVE_NET_IF_H ${HAVE_NET_IF_H}
-
-/* Define to 1 if NI_WITHSCOPEID exists and works. */
-#cmakedefine HAVE_NI_WITHSCOPEID ${HAVE_NI_WITHSCOPEID}
-
-/* Defined if no inet_pton() prototype available */
-#cmakedefine HAVE_NO_INET_PTON_PROTO ${HAVE_NO_INET_PTON_PROTO}
-
-/* we have no strerror_r() proto */
-#cmakedefine HAVE_NO_STRERROR_R_DECL ${HAVE_NO_STRERROR_R_DECL}
-
-/* Define to 1 if you have the <openssl/crypto.h> header file. */
-#cmakedefine HAVE_OPENSSL_CRYPTO_H ${HAVE_OPENSSL_CRYPTO_H}
-
-/* Define to 1 if you have the <openssl/engine.h> header file. */
-#cmakedefine HAVE_OPENSSL_ENGINE_H ${HAVE_OPENSSL_ENGINE_H}
-
-/* Define to 1 if you have the <openssl/err.h> header file. */
-#cmakedefine HAVE_OPENSSL_ERR_H ${HAVE_OPENSSL_ERR_H}
-
-/* Define to 1 if you have the <openssl/pem.h> header file. */
-#cmakedefine HAVE_OPENSSL_PEM_H ${HAVE_OPENSSL_PEM_H}
-
-/* Define to 1 if you have the <openssl/pkcs12.h> header file. */
-#cmakedefine HAVE_OPENSSL_PKCS12_H ${HAVE_OPENSSL_PKCS12_H}
-
-/* Define to 1 if you have the <openssl/rsa.h> header file. */
-#cmakedefine HAVE_OPENSSL_RSA_H ${HAVE_OPENSSL_RSA_H}
-
-/* Define to 1 if you have the <openssl/ssl.h> header file. */
-#cmakedefine HAVE_OPENSSL_SSL_H ${HAVE_OPENSSL_SSL_H}
-
-/* Define to 1 if you have the <openssl/x509.h> header file. */
-#cmakedefine HAVE_OPENSSL_X509_H ${HAVE_OPENSSL_X509_H}
-
-/* use O_NONBLOCK for non-blocking sockets */
-#cmakedefine HAVE_O_NONBLOCK ${HAVE_O_NONBLOCK}
-
-/* Define to 1 if you have the <pem.h> header file. */
-#cmakedefine HAVE_PEM_H ${HAVE_PEM_H}
-
-/* Define to 1 if you have the `perror' function. */
-#cmakedefine HAVE_PERROR ${HAVE_PERROR}
-
-/* Define to 1 if you have the `pipe' function. */
-#cmakedefine HAVE_PIPE ${HAVE_PIPE}
-
-/* Define to 1 if you have the `poll' function. */
-#cmakedefine HAVE_POLL ${HAVE_POLL}
-
-/* Define to 1 if you have the <process.h> header file. */
-#cmakedefine HAVE_PROCESS_H ${HAVE_PROCESS_H}
-
-/* Define to 1 if you have the <pwd.h> header file. */
-#cmakedefine HAVE_PWD_H ${HAVE_PWD_H}
-
-/* Define to 1 if you have the `RAND_egd' function. */
-#cmakedefine HAVE_RAND_EGD ${HAVE_RAND_EGD}
-
-/* Define to 1 if you have the `RAND_screen' function. */
-#cmakedefine HAVE_RAND_SCREEN ${HAVE_RAND_SCREEN}
-
-/* Define to 1 if you have the `RAND_status' function. */
-#cmakedefine HAVE_RAND_STATUS ${HAVE_RAND_STATUS}
-
-/* Define to 1 if you have the recv function. */
-#cmakedefine HAVE_RECV ${HAVE_RECV}
-
-/* Define to 1 if you have the <rsa.h> header file. */
-#cmakedefine HAVE_RSA_H ${HAVE_RSA_H}
-
-/* Define to 1 if you have the select function. */
-#cmakedefine HAVE_SELECT ${HAVE_SELECT}
-
-/* Define to 1 if you have the send function. */
-#cmakedefine HAVE_SEND ${HAVE_SEND}
-
-/* Define to 1 if you have the <setjmp.h> header file. */
-#cmakedefine HAVE_SETJMP_H ${HAVE_SETJMP_H}
-
-/* Define to 1 if you have the `setlocale' function. */
-#cmakedefine HAVE_SETLOCALE ${HAVE_SETLOCALE}
-
-/* Define to 1 if you have the `setrlimit' function. */
-#cmakedefine HAVE_SETRLIMIT ${HAVE_SETRLIMIT}
-
-/* Define to 1 if you have the <sgtty.h> header file. */
-#cmakedefine HAVE_SGTTY_H ${HAVE_SGTTY_H}
-
-/* Define to 1 if you have the `sigaction' function. */
-#cmakedefine HAVE_SIGACTION ${HAVE_SIGACTION}
-
-/* Define to 1 if you have the `siginterrupt' function. */
-#cmakedefine HAVE_SIGINTERRUPT ${HAVE_SIGINTERRUPT}
-
-/* Define to 1 if you have the `signal' function. */
-#cmakedefine HAVE_SIGNAL ${HAVE_SIGNAL}
-
-/* Define to 1 if you have the <signal.h> header file. */
-#cmakedefine HAVE_SIGNAL_H ${HAVE_SIGNAL_H}
-
-/* If you have sigsetjmp */
-#cmakedefine HAVE_SIGSETJMP ${HAVE_SIGSETJMP}
-
-/* Define to 1 if sig_atomic_t is an available typedef. */
-#cmakedefine HAVE_SIG_ATOMIC_T ${HAVE_SIG_ATOMIC_T}
-
-/* Define to 1 if sig_atomic_t is already defined as volatile. */
-#cmakedefine HAVE_SIG_ATOMIC_T_VOLATILE ${HAVE_SIG_ATOMIC_T_VOLATILE}
-
-/* Define to 1 if you have the `socket' function. */
-#cmakedefine HAVE_SOCKET ${HAVE_SOCKET}
-
-/* use SO_NONBLOCK for non-blocking sockets */
-#cmakedefine HAVE_SO_NONBLOCK ${HAVE_SO_NONBLOCK}
-
-/* Define this if you have the SPNEGO library fbopenssl */
-#cmakedefine HAVE_SPNEGO ${HAVE_SPNEGO}
-
-/* Define to 1 if you have the <ssl.h> header file. */
-#cmakedefine HAVE_SSL_H ${HAVE_SSL_H}
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#cmakedefine HAVE_STDINT_H ${HAVE_STDINT_H}
-
-/* Define to 1 if you have the <stdio.h> header file. */
-#cmakedefine HAVE_STDIO_H ${HAVE_STDIO_H}
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#cmakedefine HAVE_STDLIB_H ${HAVE_STDLIB_H}
-
-/* Define to 1 if you have the `strcasecmp' function. */
-#cmakedefine HAVE_STRCASECMP ${HAVE_STRCASECMP}
-
-/* Define to 1 if you have the `strcmpi' function. */
-#cmakedefine HAVE_STRCMPI ${HAVE_STRCMPI}
-
-/* Define to 1 if you have the `strdup' function. */
-#cmakedefine HAVE_STRDUP ${HAVE_STRDUP}
-
-/* Define to 1 if you have the `stricmp' function. */
-#cmakedefine HAVE_STRICMP ${HAVE_STRICMP}
-
-/* Define to 1 if you have the <strings.h> header file. */
-#cmakedefine HAVE_STRINGS_H ${HAVE_STRINGS_H}
-
-/* Define to 1 if you have the <string.h> header file. */
-#cmakedefine HAVE_STRING_H ${HAVE_STRING_H}
-
-/* Define to 1 if you have the `strlcpy' function. */
-#cmakedefine HAVE_STRLCPY ${HAVE_STRLCPY}
-
-/* Define to 1 if you have the `strstr' function. */
-#cmakedefine HAVE_STRSTR ${HAVE_STRSTR}
-
-/* Define to 1 if you have the `strtok_r' function. */
-#cmakedefine HAVE_STRTOK_R ${HAVE_STRTOK_R}
-
-/* Define to 1 if you have the `strtoll' function. */
-#cmakedefine HAVE_STRTOLL ${HAVE_STRTOLL}
-
-/* if struct sockaddr_storage is defined */
-#cmakedefine HAVE_STRUCT_SOCKADDR_STORAGE ${HAVE_STRUCT_SOCKADDR_STORAGE}
-
-/* Define to 1 if you have the timeval struct. */
-#cmakedefine HAVE_STRUCT_TIMEVAL ${HAVE_STRUCT_TIMEVAL}
-
-/* Define to 1 if you have the <sys/filio.h> header file. */
-#cmakedefine HAVE_SYS_FILIO_H ${HAVE_SYS_FILIO_H}
-
-/* Define to 1 if you have the <sys/ioctl.h> header file. */
-#cmakedefine HAVE_SYS_IOCTL_H ${HAVE_SYS_IOCTL_H}
-
-/* Define to 1 if you have the <sys/param.h> header file. */
-#cmakedefine HAVE_SYS_PARAM_H ${HAVE_SYS_PARAM_H}
-
-/* Define to 1 if you have the <sys/poll.h> header file. */
-#cmakedefine HAVE_SYS_POLL_H ${HAVE_SYS_POLL_H}
-
-/* Define to 1 if you have the <sys/resource.h> header file. */
-#cmakedefine HAVE_SYS_RESOURCE_H ${HAVE_SYS_RESOURCE_H}
-
-/* Define to 1 if you have the <sys/select.h> header file. */
-#cmakedefine HAVE_SYS_SELECT_H ${HAVE_SYS_SELECT_H}
-
-/* Define to 1 if you have the <sys/socket.h> header file. */
-#cmakedefine HAVE_SYS_SOCKET_H ${HAVE_SYS_SOCKET_H}
-
-/* Define to 1 if you have the <sys/sockio.h> header file. */
-#cmakedefine HAVE_SYS_SOCKIO_H ${HAVE_SYS_SOCKIO_H}
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#cmakedefine HAVE_SYS_STAT_H ${HAVE_SYS_STAT_H}
-
-/* Define to 1 if you have the <sys/time.h> header file. */
-#cmakedefine HAVE_SYS_TIME_H ${HAVE_SYS_TIME_H}
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#cmakedefine HAVE_SYS_TYPES_H ${HAVE_SYS_TYPES_H}
-
-/* Define to 1 if you have the <sys/utime.h> header file. */
-#cmakedefine HAVE_SYS_UTIME_H ${HAVE_SYS_UTIME_H}
-
-/* Define to 1 if you have the <termios.h> header file. */
-#cmakedefine HAVE_TERMIOS_H ${HAVE_TERMIOS_H}
-
-/* Define to 1 if you have the <termio.h> header file. */
-#cmakedefine HAVE_TERMIO_H ${HAVE_TERMIO_H}
-
-/* Define to 1 if you have the <time.h> header file. */
-#cmakedefine HAVE_TIME_H ${HAVE_TIME_H}
-
-/* Define to 1 if you have the <tld.h> header file. */
-#cmakedefine HAVE_TLD_H ${HAVE_TLD_H}
-
-/* Define to 1 if you have the `tld_strerror' function. */
-#cmakedefine HAVE_TLD_STRERROR ${HAVE_TLD_STRERROR}
-
-/* Define to 1 if you have the `uname' function. */
-#cmakedefine HAVE_UNAME ${HAVE_UNAME}
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#cmakedefine HAVE_UNISTD_H ${HAVE_UNISTD_H}
-
-/* Define to 1 if you have the `utime' function. */
-#cmakedefine HAVE_UTIME ${HAVE_UTIME}
-
-/* Define to 1 if you have the <utime.h> header file. */
-#cmakedefine HAVE_UTIME_H ${HAVE_UTIME_H}
-
-/* Define to 1 if you have the windows.h header file. */
-#cmakedefine HAVE_WINDOWS_H ${HAVE_WINDOWS_H}
-
-/* Define to 1 if you have the winsock2.h header file. */
-#cmakedefine HAVE_WINSOCK2_H ${HAVE_WINSOCK2_H}
-
-/* Define to 1 if you have the winsock.h header file. */
-#cmakedefine HAVE_WINSOCK_H ${HAVE_WINSOCK_H}
-
-/* Define this symbol if your OS supports changing the contents of argv */
-#cmakedefine HAVE_WRITABLE_ARGV ${HAVE_WRITABLE_ARGV}
-
-/* Define to 1 if you have the ws2tcpip.h header file. */
-#cmakedefine HAVE_WS2TCPIP_H ${HAVE_WS2TCPIP_H}
-
-/* Define to 1 if you have the <x509.h> header file. */
-#cmakedefine HAVE_X509_H ${HAVE_X509_H}
-
-/* if you have the zlib.h header file */
-#cmakedefine HAVE_ZLIB_H ${HAVE_ZLIB_H}
-
-/* If you lack a fine basename() prototype */
-#cmakedefine NEED_BASENAME_PROTO ${NEED_BASENAME_PROTO}
-
-/* Define to 1 if you need the malloc.h header file even with stdlib.h */
-#cmakedefine NEED_MALLOC_H ${NEED_MALLOC_H}
-
-/* need REENTRANT defined */
-#cmakedefine NEED_REENTRANT ${NEED_REENTRANT}
-
-/* cpu-machine-OS */
-#define OS "${OPERATING_SYSTEM}"
-
-/* Name of package */
-#cmakedefine PACKAGE "${PACKAGE}"
-
-/* Define to the address where bug reports for this package should be sent. */
-#cmakedefine PACKAGE_BUGREPORT "${PACKAGE_BUGREPORT}"
-
-/* Define to the full name of this package. */
-#cmakedefine PACKAGE_NAME "${PACKAGE_NAME}"
-
-/* Define to the full name and version of this package. */
-#cmakedefine PACKAGE_STRING "${PACKAGE_STRING}"
-
-/* Define to the one symbol short name of this package. */
-#cmakedefine PACKAGE_TARNAME "${PACKAGE_TARNAME}"
-
-/* Define to the version of this package. */
-#cmakedefine PACKAGE_VERSION "${PACKAGE_VERSION}"
-
-/* a suitable file to read random data from */
-#cmakedefine RANDOM_FILE "${RANDOM_FILE}"
-
-/* Define to the type of arg 1 for recv. */
-#cmakedefine RECV_TYPE_ARG1 ${RECV_TYPE_ARG1}
-
-/* Define to the type of arg 2 for recv. */
-#cmakedefine RECV_TYPE_ARG2 ${RECV_TYPE_ARG2}
-
-/* Define to the type of arg 3 for recv. */
-#cmakedefine RECV_TYPE_ARG3 ${RECV_TYPE_ARG3}
-
-/* Define to the type of arg 4 for recv. */
-#cmakedefine RECV_TYPE_ARG4 ${RECV_TYPE_ARG4}
-
-/* Define to the function return type for recv. */
-#cmakedefine RECV_TYPE_RETV ${RECV_TYPE_RETV}
-
-/* Define as the return type of signal handlers (`int' or `void'). */
-#cmakedefine RETSIGTYPE ${RETSIGTYPE}
-
-/* Define to the type of arg 1 for `select'. */
-#cmakedefine SELECT_TYPE_ARG1 ${SELECT_TYPE_ARG1}
-
-/* Define to the type of args 2, 3 and 4 for `select'. */
-#cmakedefine SELECT_TYPE_ARG234 ${SELECT_TYPE_ARG234}
-
-/* Define to the type of arg 5 for `select'. */
-#cmakedefine SELECT_TYPE_ARG5 ${SELECT_TYPE_ARG5}
-
-/* Define to the type qualifier of arg 2 for send. */
-#cmakedefine SEND_QUAL_ARG2 ${SEND_QUAL_ARG2}
-
-/* Define to the type of arg 1 for send. */
-#cmakedefine SEND_TYPE_ARG1 ${SEND_TYPE_ARG1}
-
-/* Define to the type of arg 2 for send. */
-#cmakedefine SEND_TYPE_ARG2 ${SEND_TYPE_ARG2}
-
-/* Define to the type of arg 3 for send. */
-#cmakedefine SEND_TYPE_ARG3 ${SEND_TYPE_ARG3}
-
-/* Define to the type of arg 4 for send. */
-#cmakedefine SEND_TYPE_ARG4 ${SEND_TYPE_ARG4}
-
-/* Define to the function return type for send. */
-#cmakedefine SEND_TYPE_RETV ${SEND_TYPE_RETV}
-
-/* The size of `curl_off_t', as computed by sizeof. */
-@SIZEOF_CURL_OFF_T_CODE@
-
-/* The size of `long', as computed by sizeof. */
-@SIZEOF_LONG_CODE@
-
-/* The size of `long long', as computed by sizeof. */
-@SIZEOF_LONG_LONG_CODE@
-
-/* The size of `__int64', as computed by sizeof. */
-@SIZEOF___INT64_CODE@
-
-/* The size of `size_t', as computed by sizeof. */
-@SIZEOF_SIZE_T_CODE@
-
-/* The size of `ssize_t', as computed by sizeof. */
-@SIZEOF_SSIZE_T_CODE@
-
-/* The size of `time_t', as computed by sizeof. */
-@SIZEOF_TIME_T_CODE@
-
-/* Define to 1 if you have the ANSI C header files. */
-#cmakedefine STDC_HEADERS ${STDC_HEADERS}
-
-/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
-#cmakedefine TIME_WITH_SYS_TIME ${TIME_WITH_SYS_TIME}
-
-/* Define if you want to enable ares support */
-#cmakedefine USE_ARES ${USE_ARES}
-
-/* if GnuTLS is enabled */
-#cmakedefine USE_GNUTLS ${USE_GNUTLS}
-
-/* if libSSH2 is in use */
-#cmakedefine USE_LIBSSH2 ${USE_LIBSSH2}
-
-/* If you want to build curl with the built-in manual */
-#cmakedefine USE_MANUAL ${USE_MANUAL}
-
-/* if OpenSSL is in use */
-#cmakedefine USE_OPENSSL ${USE_OPENSSL}
-
-/* if SSL is enabled */
-#cmakedefine USE_SSLEAY ${USE_SSLEAY}
-
-/* to enable SSPI support */
-#cmakedefine USE_WINDOWS_SSPI ${USE_WINDOWS_SSPI}
-
-/* Version number of package */
-#cmakedefine VERSION "${VERSION}"
-
-/* Define to avoid automatic inclusion of winsock.h */
-#cmakedefine WIN32_LEAN_AND_MEAN ${WIN32_LEAN_AND_MEAN}
-
-/* Define to 1 if on AIX 3.
- System headers sometimes define this.
- We just want to avoid a redefinition error message. */
-#ifndef _ALL_SOURCE
-#cmakedefine _ALL_SOURCE ${_ALL_SOURCE}
-#endif
-
-/* Number of bits in a file offset, on hosts where this is settable. */
-#cmakedefine _FILE_OFFSET_BITS ${_FILE_OFFSET_BITS}
-
-/* Define for large files, on AIX-style hosts. */
-#cmakedefine _LARGE_FILES ${_LARGE_FILES}
-
-/* define this if you need it to compile thread-safe code */
-#cmakedefine _THREAD_SAFE ${_THREAD_SAFE}
-
-/* Define to empty if `const' does not conform to ANSI C. */
-#cmakedefine const ${const}
-
-/* type to use in place of in_addr_t if not defined */
-#cmakedefine in_addr_t ${in_addr_t}
-
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-#cmakedefine size_t ${size_t}
-
-/* type to use in place of socklen_t if not defined */
-#cmakedefine socklen_t ${socklen_t}
-
-/* the signed version of size_t */
-#ifndef SIZEOF_SSIZE_T
-# if SIZEOF_LONG == SIZEOF_SIZE_T
- typedef long ssize_t;
-# elif SIZEOF_LONG_LONG == SIZEOF_SIZE_T
- typedef long long ssize_t;
-# elif SIZEOF___INT64 == SIZEOF_SIZE_T
- typedef __int64 ssize_t;
-# else
- typedef int ssize_t;
-# endif
-#endif
-
-/* Special handling of zlib library */
-#cmakedefine CURL_SPECIAL_ZLIB_H "${CURL_SPECIAL_ZLIB_H}"
diff --git a/Utilities/cmcurl/connect.c b/Utilities/cmcurl/connect.c
deleted file mode 100644
index 2b3897204..000000000
--- a/Utilities/cmcurl/connect.c
+++ /dev/null
@@ -1,905 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#ifndef WIN32
-/* headers for non-win32 */
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h> /* <netinet/tcp.h> may need it */
-#endif
-#ifdef HAVE_NETINET_TCP_H
-#include <netinet/tcp.h> /* for TCP_NODELAY */
-#endif
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h> /* required for free() prototype, without it, this crashes
- on macos 68K */
-#endif
-#if (defined(HAVE_FIONBIO) && defined(__NOVELL_LIBC__))
-#include <sys/filio.h>
-#endif
-#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
-#undef in_addr_t
-#define in_addr_t unsigned long
-#endif
-#ifdef VMS
-#include <in.h>
-#include <inet.h>
-#endif
-
-#endif
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-
-#ifndef TRUE
-#define TRUE 1
-#define FALSE 0
-#endif
-
-#ifdef USE_WINSOCK
-#define EINPROGRESS WSAEINPROGRESS
-#define EWOULDBLOCK WSAEWOULDBLOCK
-#define EISCONN WSAEISCONN
-#define ENOTSOCK WSAENOTSOCK
-#define ECONNREFUSED WSAECONNREFUSED
-#endif
-
-#include "urldata.h"
-#include "sendf.h"
-#include "if2ip.h"
-#include "strerror.h"
-#include "connect.h"
-#include "memory.h"
-#include "select.h"
-#include "url.h" /* for Curl_safefree() */
-#include "multiif.h"
-#include "sockaddr.h" /* required for Curl_sockaddr_storage */
-#include "inet_ntop.h"
-
-/* The last #include file should be: */
-#include "memdebug.h"
-
-static bool verifyconnect(curl_socket_t sockfd, int *error);
-
-static curl_socket_t
-singleipconnect(struct connectdata *conn,
- const Curl_addrinfo *ai, /* start connecting to this */
- long timeout_ms,
- bool *connected);
-
-/*
- * Curl_sockerrno() returns the *socket-related* errno (or equivalent) on this
- * platform to hide platform specific for the function that calls this.
- */
-int Curl_sockerrno(void)
-{
-#ifdef USE_WINSOCK
- return (int)WSAGetLastError();
-#else
- return errno;
-#endif
-}
-
-/*
- * Curl_nonblock() set the given socket to either blocking or non-blocking
- * mode based on the 'nonblock' boolean argument. This function is highly
- * portable.
- */
-int Curl_nonblock(curl_socket_t sockfd, /* operate on this */
- int nonblock /* TRUE or FALSE */)
-{
-#undef SETBLOCK
-#define SETBLOCK 0
-#ifdef HAVE_O_NONBLOCK
- /* most recent unix versions */
- int flags;
-
- flags = fcntl(sockfd, F_GETFL, 0);
- if (TRUE == nonblock)
- return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
- else
- return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
-#undef SETBLOCK
-#define SETBLOCK 1
-#endif
-
-#if defined(HAVE_FIONBIO) && (SETBLOCK == 0)
- /* older unix versions */
- int flags;
-
- flags = nonblock;
- return ioctl(sockfd, FIONBIO, &flags);
-#undef SETBLOCK
-#define SETBLOCK 2
-#endif
-
-#if defined(HAVE_IOCTLSOCKET) && (SETBLOCK == 0)
- /* Windows? */
- unsigned long flags;
- flags = nonblock;
-
- return ioctlsocket(sockfd, FIONBIO, &flags);
-#undef SETBLOCK
-#define SETBLOCK 3
-#endif
-
-#if defined(HAVE_IOCTLSOCKET_CASE) && (SETBLOCK == 0)
- /* presumably for Amiga */
- return IoctlSocket(sockfd, FIONBIO, (long)nonblock);
-#undef SETBLOCK
-#define SETBLOCK 4
-#endif
-
-#if defined(HAVE_SO_NONBLOCK) && (SETBLOCK == 0)
- /* BeOS */
- long b = nonblock ? 1 : 0;
- return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
-#undef SETBLOCK
-#define SETBLOCK 5
-#endif
-
-#ifdef HAVE_DISABLED_NONBLOCKING
- return 0; /* returns success */
-#undef SETBLOCK
-#define SETBLOCK 6
-#endif
-
-#if (SETBLOCK == 0)
-#error "no non-blocking method was found/used/set"
-#endif
-}
-
-/*
- * waitconnect() waits for a TCP connect on the given socket for the specified
- * number if milliseconds. It returns:
- * 0 fine connect
- * -1 select() error
- * 1 select() timeout
- * 2 select() returned with an error condition fd_set
- */
-
-#define WAITCONN_CONNECTED 0
-#define WAITCONN_SELECT_ERROR -1
-#define WAITCONN_TIMEOUT 1
-#define WAITCONN_FDSET_ERROR 2
-
-static
-int waitconnect(curl_socket_t sockfd, /* socket */
- long timeout_msec)
-{
- int rc;
-#ifdef mpeix
- /* Call this function once now, and ignore the results. We do this to
- "clear" the error state on the socket so that we can later read it
- reliably. This is reported necessary on the MPE/iX operating system. */
- (void)verifyconnect(sockfd, NULL);
-#endif
-
- /* now select() until we get connect or timeout */
- rc = Curl_select(CURL_SOCKET_BAD, sockfd, (int)timeout_msec);
- if(-1 == rc)
- /* error, no connect here, try next */
- return WAITCONN_SELECT_ERROR;
-
- else if(0 == rc)
- /* timeout, no connect today */
- return WAITCONN_TIMEOUT;
-
- if(rc & CSELECT_ERR)
- /* error condition caught */
- return WAITCONN_FDSET_ERROR;
-
- /* we have a connect! */
- return WAITCONN_CONNECTED;
-}
-
-static CURLcode bindlocal(struct connectdata *conn,
- curl_socket_t sockfd)
-{
- struct SessionHandle *data = conn->data;
- struct sockaddr_in me;
- struct sockaddr *sock = NULL; /* bind to this address */
- socklen_t socksize; /* size of the data sock points to */
- unsigned short port = data->set.localport; /* use this port number, 0 for
- "random" */
- /* how many port numbers to try to bind to, increasing one at a time */
- int portnum = data->set.localportrange;
-
- /*************************************************************
- * Select device to bind socket to
- *************************************************************/
- if (data->set.device && (strlen(data->set.device)<255) ) {
- struct Curl_dns_entry *h=NULL;
- char myhost[256] = "";
- in_addr_t in;
- int rc;
- bool was_iface = FALSE;
-
- /* First check if the given name is an IP address */
- in=inet_addr(data->set.device);
-
- if((in == CURL_INADDR_NONE) &&
- Curl_if2ip(data->set.device, myhost, sizeof(myhost))) {
- /*
- * We now have the numerical IPv4-style x.y.z.w in the 'myhost' buffer
- */
- rc = Curl_resolv(conn, myhost, 0, &h);
- if(rc == CURLRESOLV_PENDING)
- (void)Curl_wait_for_resolv(conn, &h);
-
- if(h) {
- was_iface = TRUE;
- Curl_resolv_unlock(data, h);
- }
- }
-
- if(!was_iface) {
- /*
- * This was not an interface, resolve the name as a host name
- * or IP number
- */
- rc = Curl_resolv(conn, data->set.device, 0, &h);
- if(rc == CURLRESOLV_PENDING)
- (void)Curl_wait_for_resolv(conn, &h);
-
- if(h) {
- if(in == CURL_INADDR_NONE)
- /* convert the resolved address, sizeof myhost >= INET_ADDRSTRLEN */
- Curl_inet_ntop(h->addr->ai_addr->sa_family,
- &((struct sockaddr_in*)h->addr->ai_addr)->sin_addr,
- myhost, sizeof myhost);
- else
- /* we know data->set.device is shorter than the myhost array */
- strcpy(myhost, data->set.device);
- Curl_resolv_unlock(data, h);
- }
- }
-
- if(! *myhost) {
- /* need to fix this
- h=Curl_gethost(data,
- getmyhost(*myhost,sizeof(myhost)),
- hostent_buf,
- sizeof(hostent_buf));
- */
- failf(data, "Couldn't bind to '%s'", data->set.device);
- return CURLE_HTTP_PORT_FAILED;
- }
-
- infof(data, "Bind local address to %s\n", myhost);
-
-#ifdef SO_BINDTODEVICE
- /* I am not sure any other OSs than Linux that provide this feature, and
- * at the least I cannot test. --Ben
- *
- * This feature allows one to tightly bind the local socket to a
- * particular interface. This will force even requests to other local
- * interfaces to go out the external interface.
- *
- */
- if (was_iface) {
- /* Only bind to the interface when specified as interface, not just as a
- * hostname or ip address.
- */
- if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
- data->set.device, strlen(data->set.device)+1) != 0) {
- /* printf("Failed to BINDTODEVICE, socket: %d device: %s error: %s\n",
- sockfd, data->set.device, Curl_strerror(Curl_sockerrno())); */
- infof(data, "SO_BINDTODEVICE %s failed\n",
- data->set.device);
- /* This is typically "errno 1, error: Operation not permitted" if
- you're not running as root or another suitable privileged user */
- }
- }
-#endif
-
- in=inet_addr(myhost);
- if (CURL_INADDR_NONE == in) {
- failf(data,"couldn't find my own IP address (%s)", myhost);
- return CURLE_HTTP_PORT_FAILED;
- } /* end of inet_addr */
-
- if ( h ) {
- Curl_addrinfo *addr = h->addr;
- sock = addr->ai_addr;
- socksize = addr->ai_addrlen;
- }
- else
- return CURLE_HTTP_PORT_FAILED;
-
- }
- else if(port) {
- /* if a local port number is requested but no local IP, extract the
- address from the socket */
- memset(&me, 0, sizeof(struct sockaddr));
- me.sin_family = AF_INET;
- me.sin_addr.s_addr = INADDR_ANY;
-
- sock = (struct sockaddr *)&me;
- socksize = sizeof(struct sockaddr);
-
- }
- else
- /* no local kind of binding was requested */
- return CURLE_OK;
-
- do {
-
- /* Set port number to bind to, 0 makes the system pick one */
- if(sock->sa_family == AF_INET)
- ((struct sockaddr_in *)sock)->sin_port = htons(port);
-#ifdef ENABLE_IPV6
- else
- ((struct sockaddr_in6 *)sock)->sin6_port = htons(port);
-#endif
-
- if( bind(sockfd, sock, socksize) >= 0) {
- /* we succeeded to bind */
- struct Curl_sockaddr_storage add;
- socklen_t size;
-
- size = sizeof(add);
- if(getsockname(sockfd, (struct sockaddr *) &add, &size) < 0) {
- failf(data, "getsockname() failed");
- return CURLE_HTTP_PORT_FAILED;
- }
- /* We re-use/clobber the port variable here below */
- if(((struct sockaddr *)&add)->sa_family == AF_INET)
- port = ntohs(((struct sockaddr_in *)&add)->sin_port);
-#ifdef ENABLE_IPV6
- else
- port = ntohs(((struct sockaddr_in6 *)&add)->sin6_port);
-#endif
- infof(data, "Local port: %d\n", port);
- return CURLE_OK;
- }
- if(--portnum > 0) {
- infof(data, "Bind to local port %d failed, trying next\n", port);
- port++; /* try next port */
- }
- else
- break;
- } while(1);
-
- data->state.os_errno = Curl_sockerrno();
- failf(data, "bind failure: %s",
- Curl_strerror(conn, data->state.os_errno));
- return CURLE_HTTP_PORT_FAILED;
-
-}
-
-/*
- * verifyconnect() returns TRUE if the connect really has happened.
- */
-static bool verifyconnect(curl_socket_t sockfd, int *error)
-{
- bool rc = TRUE;
-#ifdef SO_ERROR
- int err = 0;
- socklen_t errSize = sizeof(err);
-
-#ifdef WIN32
- /*
- * In October 2003 we effectively nullified this function on Windows due to
- * problems with it using all CPU in multi-threaded cases.
- *
- * In May 2004, we bring it back to offer more info back on connect failures.
- * Gisle Vanem could reproduce the former problems with this function, but
- * could avoid them by adding this SleepEx() call below:
- *
- * "I don't have Rational Quantify, but the hint from his post was
- * ntdll::NtRemoveIoCompletion(). So I'd assume the SleepEx (or maybe
- * just Sleep(0) would be enough?) would release whatever
- * mutex/critical-section the ntdll call is waiting on.
- *
- * Someone got to verify this on Win-NT 4.0, 2000."
- */
-
-#ifdef _WIN32_WCE
- Sleep(0);
-#else
- SleepEx(0, FALSE);
-#endif
-
-#endif
-
- if( -1 == getsockopt(sockfd, SOL_SOCKET, SO_ERROR,
- (void *)&err, &errSize))
- err = Curl_sockerrno();
-
-#ifdef _WIN32_WCE
- /* Always returns this error, bug in CE? */
- if(WSAENOPROTOOPT==err)
- err=0;
-#endif
-
- if ((0 == err) || (EISCONN == err))
- /* we are connected, awesome! */
- rc = TRUE;
- else
- /* This wasn't a successful connect */
- rc = FALSE;
- if (error)
- *error = err;
-#else
- (void)sockfd;
- if (error)
- *error = Curl_sockerrno();
-#endif
- return rc;
-}
-
-CURLcode Curl_store_ip_addr(struct connectdata *conn)
-{
- char addrbuf[256];
- Curl_printable_address(conn->ip_addr, addrbuf, sizeof(addrbuf));
-
- /* save the string */
- Curl_safefree(conn->ip_addr_str);
- conn->ip_addr_str = strdup(addrbuf);
- if(!conn->ip_addr_str)
- return CURLE_OUT_OF_MEMORY; /* FAIL */
-
-#ifdef PF_INET6
- if(conn->ip_addr->ai_family == PF_INET6)
- conn->bits.ipv6 = TRUE;
-#endif
-
- return CURLE_OK;
-}
-
-/* Used within the multi interface. Try next IP address, return TRUE if no
- more address exists */
-static bool trynextip(struct connectdata *conn,
- int sockindex,
- bool *connected)
-{
- curl_socket_t sockfd;
- Curl_addrinfo *ai;
-
- /* first close the failed socket */
- sclose(conn->sock[sockindex]);
- conn->sock[sockindex] = CURL_SOCKET_BAD;
- *connected = FALSE;
-
- if(sockindex != FIRSTSOCKET)
- return TRUE; /* no next */
-
- /* try the next address */
- ai = conn->ip_addr->ai_next;
-
- while (ai) {
- sockfd = singleipconnect(conn, ai, 0L, connected);
- if(sockfd != CURL_SOCKET_BAD) {
- /* store the new socket descriptor */
- conn->sock[sockindex] = sockfd;
- conn->ip_addr = ai;
-
- Curl_store_ip_addr(conn);
- return FALSE;
- }
- ai = ai->ai_next;
- }
- return TRUE;
-}
-
-/*
- * Curl_is_connected() is used from the multi interface to check if the
- * firstsocket has connected.
- */
-
-CURLcode Curl_is_connected(struct connectdata *conn,
- int sockindex,
- bool *connected)
-{
- int rc;
- struct SessionHandle *data = conn->data;
- CURLcode code = CURLE_OK;
- curl_socket_t sockfd = conn->sock[sockindex];
- long allow = DEFAULT_CONNECT_TIMEOUT;
- long allow_total = 0;
- long has_passed;
-
- curlassert(sockindex >= FIRSTSOCKET && sockindex <= SECONDARYSOCKET);
-
- *connected = FALSE; /* a very negative world view is best */
-
- /* Evaluate in milliseconds how much time that has passed */
- has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
-
- /* subtract the most strict timeout of the ones */
- if(data->set.timeout && data->set.connecttimeout) {
- if (data->set.timeout < data->set.connecttimeout)
- allow_total = allow = data->set.timeout*1000;
- else
- allow = data->set.connecttimeout*1000;
- }
- else if(data->set.timeout) {
- allow_total = allow = data->set.timeout*1000;
- }
- else if(data->set.connecttimeout) {
- allow = data->set.connecttimeout*1000;
- }
-
- if(has_passed > allow ) {
- /* time-out, bail out, go home */
- failf(data, "Connection time-out after %ld ms", has_passed);
- return CURLE_OPERATION_TIMEOUTED;
- }
- if(conn->bits.tcpconnect) {
- /* we are connected already! */
- Curl_expire(data, allow_total);
- *connected = TRUE;
- return CURLE_OK;
- }
-
- Curl_expire(data, allow);
-
- /* check for connect without timeout as we want to return immediately */
- rc = waitconnect(sockfd, 0);
-
- if(WAITCONN_CONNECTED == rc) {
- int error;
- if (verifyconnect(sockfd, &error)) {
- /* we are connected, awesome! */
- *connected = TRUE;
- return CURLE_OK;
- }
- /* nope, not connected for real */
- data->state.os_errno = error;
- infof(data, "Connection failed\n");
- if(trynextip(conn, sockindex, connected)) {
- code = CURLE_COULDNT_CONNECT;
- }
- }
- else if(WAITCONN_TIMEOUT != rc) {
- int error = 0;
-
- /* nope, not connected */
- if (WAITCONN_FDSET_ERROR == rc) {
- (void)verifyconnect(sockfd, &error);
- data->state.os_errno = error;
- infof(data, "%s\n",Curl_strerror(conn,error));
- }
- else
- infof(data, "Connection failed\n");
-
- if(trynextip(conn, sockindex, connected)) {
- error = Curl_sockerrno();
- data->state.os_errno = error;
- failf(data, "Failed connect to %s:%d; %s",
- conn->host.name, conn->port, Curl_strerror(conn,error));
- code = CURLE_COULDNT_CONNECT;
- }
- }
- /*
- * If the connection failed here, we should attempt to connect to the "next
- * address" for the given host.
- */
-
- return code;
-}
-
-static void tcpnodelay(struct connectdata *conn,
- curl_socket_t sockfd)
-{
-#ifdef TCP_NODELAY
- struct SessionHandle *data= conn->data;
- socklen_t onoff = (socklen_t) data->set.tcp_nodelay;
- int proto = IPPROTO_TCP;
-
-#ifdef HAVE_GETPROTOBYNAME
- struct protoent *pe = getprotobyname("tcp");
- if (pe)
- proto = pe->p_proto;
-#endif
-
- if(setsockopt(sockfd, proto, TCP_NODELAY, (void *)&onoff,
- sizeof(onoff)) < 0)
- infof(data, "Could not set TCP_NODELAY: %s\n",
- Curl_strerror(conn, Curl_sockerrno()));
- else
- infof(data,"TCP_NODELAY set\n");
-#else
- (void)conn;
- (void)sockfd;
-#endif
-}
-
-#ifdef SO_NOSIGPIPE
-/* The preferred method on Mac OS X (10.2 and later) to prevent SIGPIPEs when
- sending data to a dead peer (instead of relying on the 4th argument to send
- being MSG_NOSIGNAL). Possibly also existing and in use on other BSD
- systems? */
-static void nosigpipe(struct connectdata *conn,
- curl_socket_t sockfd)
-{
- struct SessionHandle *data= conn->data;
- int onoff = 1;
- if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff,
- sizeof(onoff)) < 0)
- infof(data, "Could not set SO_NOSIGPIPE: %s\n",
- Curl_strerror(conn, Curl_sockerrno()));
-}
-#else
-#define nosigpipe(x,y)
-#endif
-
-/* singleipconnect() connects to the given IP only, and it may return without
- having connected if used from the multi interface. */
-static curl_socket_t
-singleipconnect(struct connectdata *conn,
- const Curl_addrinfo *ai,
- long timeout_ms,
- bool *connected)
-{
- char addr_buf[128];
- int rc;
- int error;
- bool isconnected;
- struct SessionHandle *data = conn->data;
- curl_socket_t sockfd;
- CURLcode res;
-
- sockfd = socket(ai->ai_family, conn->socktype, ai->ai_protocol);
- if (sockfd == CURL_SOCKET_BAD)
- return CURL_SOCKET_BAD;
-
- *connected = FALSE; /* default is not connected */
-
- Curl_printable_address(ai, addr_buf, sizeof(addr_buf));
- infof(data, " Trying %s... ", addr_buf);
-
- if(data->set.tcp_nodelay)
- tcpnodelay(conn, sockfd);
-
- nosigpipe(conn, sockfd);
-
- if(data->set.fsockopt) {
- /* activate callback for setting socket options */
- error = data->set.fsockopt(data->set.sockopt_client,
- sockfd,
- CURLSOCKTYPE_IPCXN);
- if (error) {
- sclose(sockfd); /* close the socket and bail out */
- return CURL_SOCKET_BAD;
- }
- }
-
- /* possibly bind the local end to an IP, interface or port */
- res = bindlocal(conn, sockfd);
- if(res) {
- sclose(sockfd); /* close socket and bail out */
- return CURL_SOCKET_BAD;
- }
-
- /* set socket non-blocking */
- Curl_nonblock(sockfd, TRUE);
-
- /* Connect TCP sockets, bind UDP */
- if(conn->socktype == SOCK_STREAM)
- rc = connect(sockfd, ai->ai_addr, ai->ai_addrlen);
- else
- rc = 0;
-
- if(-1 == rc) {
- error = Curl_sockerrno();
-
- switch (error) {
- case EINPROGRESS:
- case EWOULDBLOCK:
-#if defined(EAGAIN) && EAGAIN != EWOULDBLOCK
- /* On some platforms EAGAIN and EWOULDBLOCK are the
- * same value, and on others they are different, hence
- * the odd #if
- */
- case EAGAIN:
-#endif
- rc = waitconnect(sockfd, timeout_ms);
- break;
- default:
- /* unknown error, fallthrough and try another address! */
- failf(data, "Failed to connect to %s: %s",
- addr_buf, Curl_strerror(conn,error));
- data->state.os_errno = error;
- break;
- }
- }
-
- /* The 'WAITCONN_TIMEOUT == rc' comes from the waitconnect(), and not from
- connect(). We can be sure of this since connect() cannot return 1. */
- if((WAITCONN_TIMEOUT == rc) &&
- (data->state.used_interface == Curl_if_multi)) {
- /* Timeout when running the multi interface */
- return sockfd;
- }
-
- isconnected = verifyconnect(sockfd, &error);
-
- if(!rc && isconnected) {
- /* we are connected, awesome! */
- *connected = TRUE; /* this is a true connect */
- infof(data, "connected\n");
- return sockfd;
- }
- else if(WAITCONN_TIMEOUT == rc)
- infof(data, "Timeout\n");
- else {
- data->state.os_errno = error;
- infof(data, "%s\n", Curl_strerror(conn, error));
- }
-
- /* connect failed or timed out */
- sclose(sockfd);
-
- return CURL_SOCKET_BAD;
-}
-
-/*
- * TCP connect to the given host with timeout, proxy or remote doesn't matter.
- * There might be more than one IP address to try out. Fill in the passed
- * pointer with the connected socket.
- */
-
-CURLcode Curl_connecthost(struct connectdata *conn, /* context */
- const struct Curl_dns_entry *remotehost, /* use this one */
- curl_socket_t *sockconn, /* the connected socket */
- Curl_addrinfo **addr, /* the one we used */
- bool *connected) /* really connected? */
-{
- struct SessionHandle *data = conn->data;
- curl_socket_t sockfd = CURL_SOCKET_BAD;
- int aliasindex;
- int num_addr;
- Curl_addrinfo *ai;
- Curl_addrinfo *curr_addr;
-
- struct timeval after;
- struct timeval before = Curl_tvnow();
-
- /*************************************************************
- * Figure out what maximum time we have left
- *************************************************************/
- long timeout_ms= DEFAULT_CONNECT_TIMEOUT;
- long timeout_per_addr;
-
- *connected = FALSE; /* default to not connected */
-
- if(data->set.timeout || data->set.connecttimeout) {
- long has_passed;
-
- /* Evaluate in milliseconds how much time that has passed */
- has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
-
-#ifndef min
-#define min(a, b) ((a) < (b) ? (a) : (b))
-#endif
-
- /* get the most strict timeout of the ones converted to milliseconds */
- if(data->set.timeout && data->set.connecttimeout) {
- if (data->set.timeout < data->set.connecttimeout)
- timeout_ms = data->set.timeout*1000;
- else
- timeout_ms = data->set.connecttimeout*1000;
- }
- else if(data->set.timeout)
- timeout_ms = data->set.timeout*1000;
- else
- timeout_ms = data->set.connecttimeout*1000;
-
- /* subtract the passed time */
- timeout_ms -= has_passed;
-
- if(timeout_ms < 0) {
- /* a precaution, no need to continue if time already is up */
- failf(data, "Connection time-out");
- return CURLE_OPERATION_TIMEOUTED;
- }
- }
- Curl_expire(data, timeout_ms);
-
- /* Max time for each address */
- num_addr = Curl_num_addresses(remotehost->addr);
- timeout_per_addr = timeout_ms / num_addr;
-
- ai = remotehost->addr;
-
- /* Below is the loop that attempts to connect to all IP-addresses we
- * know for the given host. One by one until one IP succeeds.
- */
-
- if(data->state.used_interface == Curl_if_multi)
- /* don't hang when doing multi */
- timeout_per_addr = 0;
-
- /*
- * Connecting with a Curl_addrinfo chain
- */
- for (curr_addr = ai, aliasindex=0; curr_addr;
- curr_addr = curr_addr->ai_next, aliasindex++) {
-
- /* start connecting to the IP curr_addr points to */
- sockfd = singleipconnect(conn, curr_addr, timeout_per_addr, connected);
-
- if(sockfd != CURL_SOCKET_BAD)
- break;
-
- /* get a new timeout for next attempt */
- after = Curl_tvnow();
- timeout_ms -= Curl_tvdiff(after, before);
- if(timeout_ms < 0) {
- failf(data, "connect() timed out!");
- return CURLE_OPERATION_TIMEOUTED;
- }
- before = after;
- } /* end of connect-to-each-address loop */
-
- if (sockfd == CURL_SOCKET_BAD) {
- /* no good connect was made */
- *sockconn = CURL_SOCKET_BAD;
- failf(data, "couldn't connect to host");
- return CURLE_COULDNT_CONNECT;
- }
-
- /* leave the socket in non-blocking mode */
-
- /* store the address we use */
- if(addr)
- *addr = curr_addr;
-
- /* allow NULL-pointers to get passed in */
- if(sockconn)
- *sockconn = sockfd; /* the socket descriptor we've connected */
-
- data->info.numconnects++; /* to track the number of connections made */
-
- return CURLE_OK;
-}
diff --git a/Utilities/cmcurl/connect.h b/Utilities/cmcurl/connect.h
deleted file mode 100644
index 599572b27..000000000
--- a/Utilities/cmcurl/connect.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef __CONNECT_H
-#define __CONNECT_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-int Curl_nonblock(curl_socket_t sockfd, /* operate on this */
- int nonblock /* TRUE or FALSE */);
-
-CURLcode Curl_is_connected(struct connectdata *conn,
- int sockindex,
- bool *connected);
-
-CURLcode Curl_connecthost(struct connectdata *conn,
- const struct Curl_dns_entry *host, /* connect to this */
- curl_socket_t *sockconn, /* not set if error */
- Curl_addrinfo **addr, /* the one we used */
- bool *connected /* truly connected? */
- );
-
-int Curl_sockerrno(void);
-
-CURLcode Curl_store_ip_addr(struct connectdata *conn);
-
-#define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */
-
-#endif
diff --git a/Utilities/cmcurl/content_encoding.c b/Utilities/cmcurl/content_encoding.c
deleted file mode 100644
index 97f834177..000000000
--- a/Utilities/cmcurl/content_encoding.c
+++ /dev/null
@@ -1,424 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#ifdef HAVE_LIBZ
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "urldata.h"
-#include <curl/curl.h>
-#include "sendf.h"
-#include "content_encoding.h"
-#include "memory.h"
-
-#include "memdebug.h"
-
-/* Comment this out if zlib is always going to be at least ver. 1.2.0.4
- (doing so will reduce code size slightly). */
-#define OLD_ZLIB_SUPPORT 1
-
-#define DSIZ 0x10000 /* buffer size for decompressed data */
-
-#define GZIP_MAGIC_0 0x1f
-#define GZIP_MAGIC_1 0x8b
-
-/* gzip flag byte */
-#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
-#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
-#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
-#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
-#define COMMENT 0x10 /* bit 4 set: file comment present */
-#define RESERVED 0xE0 /* bits 5..7: reserved */
-
-enum zlibState {
- ZLIB_UNINIT, /* uninitialized */
- ZLIB_INIT, /* initialized */
- ZLIB_GZIP_HEADER, /* reading gzip header */
- ZLIB_GZIP_INFLATING, /* inflating gzip stream */
- ZLIB_INIT_GZIP /* initialized in transparent gzip mode */
-};
-
-static CURLcode
-process_zlib_error(struct connectdata *conn, z_stream *z)
-{
- struct SessionHandle *data = conn->data;
- if (z->msg)
- failf (data, "Error while processing content unencoding: %s",
- z->msg);
- else
- failf (data, "Error while processing content unencoding: "
- "Unknown failure within decompression software.");
-
- return CURLE_BAD_CONTENT_ENCODING;
-}
-
-static CURLcode
-exit_zlib(z_stream *z, bool *zlib_init, CURLcode result)
-{
- inflateEnd(z);
- *zlib_init = ZLIB_UNINIT;
- return result;
-}
-
-static CURLcode
-inflate_stream(struct connectdata *conn,
- struct Curl_transfer_keeper *k)
-{
- int allow_restart = 1;
- z_stream *z = &k->z; /* zlib state structure */
- uInt nread = z->avail_in;
- Bytef *orig_in = z->next_in;
- int status; /* zlib status */
- CURLcode result = CURLE_OK; /* Curl_client_write status */
- char *decomp; /* Put the decompressed data here. */
-
- /* Dynamically allocate a buffer for decompression because it's uncommonly
- large to hold on the stack */
- decomp = (char*)malloc(DSIZ);
- if (decomp == NULL) {
- return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY);
- }
-
- /* because the buffer size is fixed, iteratively decompress and transfer to
- the client via client_write. */
- for (;;) {
- /* (re)set buffer for decompressed output for every iteration */
- z->next_out = (Bytef *)decomp;
- z->avail_out = DSIZ;
-
- status = inflate(z, Z_SYNC_FLUSH);
- if (status == Z_OK || status == Z_STREAM_END) {
- allow_restart = 0;
- if(DSIZ - z->avail_out) {
- result = Curl_client_write(conn, CLIENTWRITE_BODY, decomp,
- DSIZ - z->avail_out);
- /* if !CURLE_OK, clean up, return */
- if (result) {
- free(decomp);
- return exit_zlib(z, &k->zlib_init, result);
- }
- }
-
- /* Done? clean up, return */
- if (status == Z_STREAM_END) {
- free(decomp);
- if (inflateEnd(z) == Z_OK)
- return exit_zlib(z, &k->zlib_init, result);
- else
- return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
- }
-
- /* Done with these bytes, exit */
- if (status == Z_OK && z->avail_in == 0) {
- free(decomp);
- return result;
- }
- }
- else if (allow_restart && status == Z_DATA_ERROR) {
- /* some servers seem to not generate zlib headers, so this is an attempt
- to fix and continue anyway */
-
- inflateReset(z);
- if (inflateInit2(z, -MAX_WBITS) != Z_OK) {
- return process_zlib_error(conn, z);
- }
- z->next_in = orig_in;
- z->avail_in = nread;
- allow_restart = 0;
- continue;
- }
- else { /* Error; exit loop, handle below */
- free(decomp);
- return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
- }
- }
- /* Will never get here */
-}
-
-CURLcode
-Curl_unencode_deflate_write(struct connectdata *conn,
- struct Curl_transfer_keeper *k,
- ssize_t nread)
-{
- z_stream *z = &k->z; /* zlib state structure */
-
- /* Initialize zlib? */
- if (k->zlib_init == ZLIB_UNINIT) {
- z->zalloc = (alloc_func)Z_NULL;
- z->zfree = (free_func)Z_NULL;
- z->opaque = 0;
- z->next_in = NULL;
- z->avail_in = 0;
- if (inflateInit(z) != Z_OK)
- return process_zlib_error(conn, z);
- k->zlib_init = ZLIB_INIT;
- }
-
- /* Set the compressed input when this function is called */
- z->next_in = (Bytef *)k->str;
- z->avail_in = (uInt)nread;
-
- /* Now uncompress the data */
- return inflate_stream(conn, k);
-}
-
-#ifdef OLD_ZLIB_SUPPORT
-/* Skip over the gzip header */
-static enum {
- GZIP_OK,
- GZIP_BAD,
- GZIP_UNDERFLOW
-} check_gzip_header(unsigned char const *data, ssize_t len, ssize_t *headerlen)
-{
- int method, flags;
- const ssize_t totallen = len;
-
- /* The shortest header is 10 bytes */
- if (len < 10)
- return GZIP_UNDERFLOW;
-
- if ((data[0] != GZIP_MAGIC_0) || (data[1] != GZIP_MAGIC_1))
- return GZIP_BAD;
-
- method = data[2];
- flags = data[3];
-
- if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
- /* Can't handle this compression method or unknown flag */
- return GZIP_BAD;
- }
-
- /* Skip over time, xflags, OS code and all previous bytes */
- len -= 10;
- data += 10;
-
- if (flags & EXTRA_FIELD) {
- ssize_t extra_len;
-
- if (len < 2)
- return GZIP_UNDERFLOW;
-
- extra_len = (data[1] << 8) | data[0];
-
- if (len < (extra_len+2))
- return GZIP_UNDERFLOW;
-
- len -= (extra_len + 2);
- data += (extra_len + 2);
- }
-
- if (flags & ORIG_NAME) {
- /* Skip over NUL-terminated file name */
- while (len && *data) {
- --len;
- ++data;
- }
- if (!len || *data)
- return GZIP_UNDERFLOW;
-
- /* Skip over the NUL */
- --len;
- ++data;
- }
-
- if (flags & COMMENT) {
- /* Skip over NUL-terminated comment */
- while (len && *data) {
- --len;
- ++data;
- }
- if (!len || *data)
- return GZIP_UNDERFLOW;
-
- /* Skip over the NUL */
- --len;
- ++data;
- }
-
- if (flags & HEAD_CRC) {
- if (len < 2)
- return GZIP_UNDERFLOW;
-
- len -= 2;
- data += 2;
- }
-
- *headerlen = totallen - len;
- return GZIP_OK;
-}
-#endif
-
-CURLcode
-Curl_unencode_gzip_write(struct connectdata *conn,
- struct Curl_transfer_keeper *k,
- ssize_t nread)
-{
- z_stream *z = &k->z; /* zlib state structure */
-
- /* Initialize zlib? */
- if (k->zlib_init == ZLIB_UNINIT) {
- z->zalloc = (alloc_func)Z_NULL;
- z->zfree = (free_func)Z_NULL;
- z->opaque = 0;
- z->next_in = NULL;
- z->avail_in = 0;
-
- if (strcmp(zlibVersion(), "1.2.0.4") >= 0) {
- /* zlib ver. >= 1.2.0.4 supports transparent gzip decompressing */
- if (inflateInit2(z, MAX_WBITS+32) != Z_OK) {
- return process_zlib_error(conn, z);
- }
- k->zlib_init = ZLIB_INIT_GZIP; /* Transparent gzip decompress state */
-
- } else {
- /* we must parse the gzip header ourselves */
- if (inflateInit2(z, -MAX_WBITS) != Z_OK) {
- return process_zlib_error(conn, z);
- }
- k->zlib_init = ZLIB_INIT; /* Initial call state */
- }
- }
-
- if (k->zlib_init == ZLIB_INIT_GZIP) {
- /* Let zlib handle the gzip decompression entirely */
- z->next_in = (Bytef *)k->str;
- z->avail_in = (uInt)nread;
- /* Now uncompress the data */
- return inflate_stream(conn, k);
- }
-
-#ifndef OLD_ZLIB_SUPPORT
- /* Support for old zlib versions is compiled away and we are running with
- an old version, so return an error. */
- return exit_zlib(z, &k->zlib_init, CURLE_FUNCTION_NOT_FOUND);
-
-#else
- /* This next mess is to get around the potential case where there isn't
- * enough data passed in to skip over the gzip header. If that happens, we
- * malloc a block and copy what we have then wait for the next call. If
- * there still isn't enough (this is definitely a worst-case scenario), we
- * make the block bigger, copy the next part in and keep waiting.
- *
- * This is only required with zlib versions < 1.2.0.4 as newer versions
- * can handle the gzip header themselves.
- */
-
- switch (k->zlib_init) {
- /* Skip over gzip header? */
- case ZLIB_INIT:
- {
- /* Initial call state */
- ssize_t hlen;
-
- switch (check_gzip_header((unsigned char *)k->str, nread, &hlen)) {
- case GZIP_OK:
- z->next_in = (Bytef *)k->str + hlen;
- z->avail_in = (uInt)(nread - hlen);
- k->zlib_init = ZLIB_GZIP_INFLATING; /* Inflating stream state */
- break;
-
- case GZIP_UNDERFLOW:
- /* We need more data so we can find the end of the gzip header. It's
- * possible that the memory block we malloc here will never be freed if
- * the transfer abruptly aborts after this point. Since it's unlikely
- * that circumstances will be right for this code path to be followed in
- * the first place, and it's even more unlikely for a transfer to fail
- * immediately afterwards, it should seldom be a problem.
- */
- z->avail_in = (uInt)nread;
- z->next_in = malloc(z->avail_in);
- if (z->next_in == NULL) {
- return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY);
- }
- memcpy(z->next_in, k->str, z->avail_in);
- k->zlib_init = ZLIB_GZIP_HEADER; /* Need more gzip header data state */
- /* We don't have any data to inflate yet */
- return CURLE_OK;
-
- case GZIP_BAD:
- default:
- return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
- }
-
- }
- break;
-
- case ZLIB_GZIP_HEADER:
- {
- /* Need more gzip header data state */
- ssize_t hlen;
- unsigned char *oldblock = z->next_in;
-
- z->avail_in += nread;
- z->next_in = realloc(z->next_in, z->avail_in);
- if (z->next_in == NULL) {
- free(oldblock);
- return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY);
- }
- /* Append the new block of data to the previous one */
- memcpy(z->next_in + z->avail_in - nread, k->str, nread);
-
- switch (check_gzip_header(z->next_in, z->avail_in, &hlen)) {
- case GZIP_OK:
- /* This is the zlib stream data */
- free(z->next_in);
- /* Don't point into the malloced block since we just freed it */
- z->next_in = (Bytef *)k->str + hlen + nread - z->avail_in;
- z->avail_in = (uInt)(z->avail_in - hlen);
- k->zlib_init = ZLIB_GZIP_INFLATING; /* Inflating stream state */
- break;
-
- case GZIP_UNDERFLOW:
- /* We still don't have any data to inflate! */
- return CURLE_OK;
-
- case GZIP_BAD:
- default:
- free(z->next_in);
- return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
- }
-
- }
- break;
-
- case ZLIB_GZIP_INFLATING:
- default:
- /* Inflating stream state */
- z->next_in = (Bytef *)k->str;
- z->avail_in = (uInt)nread;
- break;
- }
-
- if (z->avail_in == 0) {
- /* We don't have any data to inflate; wait until next time */
- return CURLE_OK;
- }
-
- /* We've parsed the header, now uncompress the data */
- return inflate_stream(conn, k);
-#endif
-}
-#endif /* HAVE_LIBZ */
diff --git a/Utilities/cmcurl/content_encoding.h b/Utilities/cmcurl/content_encoding.h
deleted file mode 100644
index b31669be4..000000000
--- a/Utilities/cmcurl/content_encoding.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-#include "setup.h"
-
-/*
- * Comma-separated list all supported Content-Encodings ('identity' is implied)
- */
-#ifdef HAVE_LIBZ
-#define ALL_CONTENT_ENCODINGS "deflate, gzip"
-#else
-#define ALL_CONTENT_ENCODINGS "identity"
-#endif
-
-CURLcode Curl_unencode_deflate_write(struct connectdata *conn,
- struct Curl_transfer_keeper *k,
- ssize_t nread);
-
-CURLcode
-Curl_unencode_gzip_write(struct connectdata *conn,
- struct Curl_transfer_keeper *k,
- ssize_t nread);
diff --git a/Utilities/cmcurl/cookie.c b/Utilities/cmcurl/cookie.c
deleted file mode 100644
index d8ea24196..000000000
--- a/Utilities/cmcurl/cookie.c
+++ /dev/null
@@ -1,1019 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-/***
-
-
-RECEIVING COOKIE INFORMATION
-============================
-
-struct CookieInfo *cookie_init(char *file);
-
- Inits a cookie struct to store data in a local file. This is always
- called before any cookies are set.
-
-int cookies_set(struct CookieInfo *cookie, char *cookie_line);
-
- The 'cookie_line' parameter is a full "Set-cookie:" line as
- received from a server.
-
- The function need to replace previously stored lines that this new
- line superceeds.
-
- It may remove lines that are expired.
-
- It should return an indication of success/error.
-
-
-SENDING COOKIE INFORMATION
-==========================
-
-struct Cookies *cookie_getlist(struct CookieInfo *cookie,
- char *host, char *path, bool secure);
-
- For a given host and path, return a linked list of cookies that
- the client should send to the server if used now. The secure
- boolean informs the cookie if a secure connection is achieved or
- not.
-
- It shall only return cookies that haven't expired.
-
-
-Example set of cookies:
-
- Set-cookie: PRODUCTINFO=webxpress; domain=.fidelity.com; path=/; secure
- Set-cookie: PERSONALIZE=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
- domain=.fidelity.com; path=/ftgw; secure
- Set-cookie: FidHist=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
- domain=.fidelity.com; path=/; secure
- Set-cookie: FidOrder=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
- domain=.fidelity.com; path=/; secure
- Set-cookie: DisPend=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
- domain=.fidelity.com; path=/; secure
- Set-cookie: FidDis=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
- domain=.fidelity.com; path=/; secure
- Set-cookie:
- Session_Key@6791a9e0-901a-11d0-a1c8-9b012c88aa77=none;expires=Monday,
- 13-Jun-1988 03:04:55 GMT; domain=.fidelity.com; path=/; secure
-****/
-
-
-#include "setup.h"
-
-#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
-
-#include <stdlib.h>
-#include <string.h>
-
-#define _MPRINTF_REPLACE /* without this on windows OS we get undefined reference to snprintf */
-#include <curl/mprintf.h>
-
-#include "urldata.h"
-#include "cookie.h"
-#include "strequal.h"
-#include "strtok.h"
-#include "sendf.h"
-#include "memory.h"
-#include "share.h"
-#include "strtoofft.h"
-
-/* The last #include file should be: */
-#ifdef CURLDEBUG
-#include "memdebug.h"
-#endif
-
-#define my_isspace(x) ((x == ' ') || (x == '\t'))
-
-static void freecookie(struct Cookie *co)
-{
- if(co->expirestr)
- free(co->expirestr);
- if(co->domain)
- free(co->domain);
- if(co->path)
- free(co->path);
- if(co->name)
- free(co->name);
- if(co->value)
- free(co->value);
- if(co->maxage)
- free(co->maxage);
- if(co->version)
- free(co->version);
-
- free(co);
-}
-
-static bool tailmatch(const char *little, const char *bigone)
-{
- size_t littlelen = strlen(little);
- size_t biglen = strlen(bigone);
-
- if(littlelen > biglen)
- return FALSE;
-
- return (bool)strequal(little, bigone+biglen-littlelen);
-}
-
-/*
- * Load cookies from all given cookie files (CURLOPT_COOKIEFILE).
- */
-void Curl_cookie_loadfiles(struct SessionHandle *data)
-{
- struct curl_slist *list = data->change.cookielist;
- if(list) {
- Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
- while(list) {
- data->cookies = Curl_cookie_init(data,
- list->data,
- data->cookies,
- data->set.cookiesession);
- list = list->next;
- }
- Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
- curl_slist_free_all(data->change.cookielist); /* clean up list */
- data->change.cookielist = NULL; /* don't do this again! */
- }
-}
-
-/****************************************************************************
- *
- * Curl_cookie_add()
- *
- * Add a single cookie line to the cookie keeping object.
- *
- ***************************************************************************/
-
-struct Cookie *
-Curl_cookie_add(struct SessionHandle *data,
- /* The 'data' pointer here may be NULL at times, and thus
- must only be used very carefully for things that can deal
- with data being NULL. Such as infof() and similar */
-
- struct CookieInfo *c,
- bool httpheader, /* TRUE if HTTP header-style line */
- char *lineptr, /* first character of the line */
- char *domain, /* default domain */
- char *path) /* full path used when this cookie is set,
- used to get default path for the cookie
- unless set */
-{
- struct Cookie *clist;
- char *what;
- char name[MAX_NAME];
- char *ptr;
- char *semiptr;
- struct Cookie *co;
- struct Cookie *lastc=NULL;
- time_t now = time(NULL);
- bool replace_old = FALSE;
- bool badcookie = FALSE; /* cookies are good by default. mmmmm yummy */
-
- /* First, alloc and init a new struct for it */
- co = (struct Cookie *)calloc(sizeof(struct Cookie), 1);
- if(!co)
- return NULL; /* bail out if we're this low on memory */
-
- if(httpheader) {
- /* This line was read off a HTTP-header */
- char *sep;
-
- what = malloc(MAX_COOKIE_LINE);
- if(!what) {
- free(co);
- return NULL;
- }
-
- semiptr=strchr(lineptr, ';'); /* first, find a semicolon */
-
- while(*lineptr && my_isspace(*lineptr))
- lineptr++;
-
- ptr = lineptr;
- do {
- /* we have a <what>=<this> pair or a 'secure' word here */
- sep = strchr(ptr, '=');
- if(sep && (!semiptr || (semiptr>sep)) ) {
- /*
- * There is a = sign and if there was a semicolon too, which make sure
- * that the semicolon comes _after_ the equal sign.
- */
-
- name[0]=what[0]=0; /* init the buffers */
- if(1 <= sscanf(ptr, "%" MAX_NAME_TXT "[^;=]=%"
- MAX_COOKIE_LINE_TXT "[^;\r\n]",
- name, what)) {
- /* this is a <name>=<what> pair */
-
- char *whatptr;
-
- /* Strip off trailing whitespace from the 'what' */
- size_t len=strlen(what);
- while(len && my_isspace(what[len-1])) {
- what[len-1]=0;
- len--;
- }
-
- /* Skip leading whitespace from the 'what' */
- whatptr=what;
- while(my_isspace(*whatptr)) {
- whatptr++;
- }
-
- if(strequal("path", name)) {
- co->path=strdup(whatptr);
- if(!co->path) {
- badcookie = TRUE; /* out of memory bad */
- break;
- }
- }
- else if(strequal("domain", name)) {
- /* note that this name may or may not have a preceeding dot, but
- we don't care about that, we treat the names the same anyway */
-
- const char *domptr=whatptr;
- int dotcount=1;
-
- /* Count the dots, we need to make sure that there are enough
- of them. */
-
- if('.' == whatptr[0])
- /* don't count the initial dot, assume it */
- domptr++;
-
- do {
- domptr = strchr(domptr, '.');
- if(domptr) {
- domptr++;
- dotcount++;
- }
- } while(domptr);
-
- /* The original Netscape cookie spec defined that this domain name
- MUST have three dots (or two if one of the seven holy TLDs),
- but it seems that these kinds of cookies are in use "out there"
- so we cannot be that strict. I've therefore lowered the check
- to not allow less than two dots. */
-
- if(dotcount < 2) {
- /* Received and skipped a cookie with a domain using too few
- dots. */
- badcookie=TRUE; /* mark this as a bad cookie */
- infof(data, "skipped cookie with illegal dotcount domain: %s\n",
- whatptr);
- }
- else {
- /* Now, we make sure that our host is within the given domain,
- or the given domain is not valid and thus cannot be set. */
-
- if('.' == whatptr[0])
- whatptr++; /* ignore preceeding dot */
-
- if(!domain || tailmatch(whatptr, domain)) {
- const char *tailptr=whatptr;
- if(tailptr[0] == '.')
- tailptr++;
- co->domain=strdup(tailptr); /* don't prefix w/dots
- internally */
- if(!co->domain) {
- badcookie = TRUE;
- break;
- }
- co->tailmatch=TRUE; /* we always do that if the domain name was
- given */
- }
- else {
- /* we did not get a tailmatch and then the attempted set domain
- is not a domain to which the current host belongs. Mark as
- bad. */
- badcookie=TRUE;
- infof(data, "skipped cookie with bad tailmatch domain: %s\n",
- whatptr);
- }
- }
- }
- else if(strequal("version", name)) {
- co->version=strdup(whatptr);
- if(!co->version) {
- badcookie = TRUE;
- break;
- }
- }
- else if(strequal("max-age", name)) {
- /* Defined in RFC2109:
-
- Optional. The Max-Age attribute defines the lifetime of the
- cookie, in seconds. The delta-seconds value is a decimal non-
- negative integer. After delta-seconds seconds elapse, the
- client should discard the cookie. A value of zero means the
- cookie should be discarded immediately.
-
- */
- co->maxage = strdup(whatptr);
- if(!co->maxage) {
- badcookie = TRUE;
- break;
- }
- co->expires =
- atoi((*co->maxage=='\"')?&co->maxage[1]:&co->maxage[0]) + (long)now;
- }
- else if(strequal("expires", name)) {
- co->expirestr=strdup(whatptr);
- if(!co->expirestr) {
- badcookie = TRUE;
- break;
- }
- co->expires = curl_getdate(what, &now);
- }
- else if(!co->name) {
- co->name = strdup(name);
- co->value = strdup(whatptr);
- if(!co->name || !co->value) {
- badcookie = TRUE;
- break;
- }
- }
- /*
- else this is the second (or more) name we don't know
- about! */
- }
- else {
- /* this is an "illegal" <what>=<this> pair */
- }
- }
- else {
- if(sscanf(ptr, "%" MAX_COOKIE_LINE_TXT "[^;\r\n]",
- what)) {
- if(strequal("secure", what))
- co->secure = TRUE;
- /* else,
- unsupported keyword without assign! */
-
- }
- }
- if(!semiptr || !*semiptr) {
- /* we already know there are no more cookies */
- semiptr = NULL;
- continue;
- }
-
- ptr=semiptr+1;
- while(ptr && *ptr && my_isspace(*ptr))
- ptr++;
- semiptr=strchr(ptr, ';'); /* now, find the next semicolon */
-
- if(!semiptr && *ptr)
- /* There are no more semicolons, but there's a final name=value pair
- coming up */
- semiptr=strchr(ptr, '\0');
- } while(semiptr);
-
- if(!badcookie && !co->domain) {
- if(domain) {
- /* no domain was given in the header line, set the default */
- co->domain=strdup(domain);
- if(!co->domain)
- badcookie = TRUE;
- }
- }
-
- if(!badcookie && !co->path && path) {
- /* no path was given in the header line, set the default */
- char *endslash = strrchr(path, '/');
- if(endslash) {
- size_t pathlen = endslash-path+1; /* include the ending slash */
- co->path=malloc(pathlen+1); /* one extra for the zero byte */
- if(co->path) {
- memcpy(co->path, path, pathlen);
- co->path[pathlen]=0; /* zero terminate */
- }
- else
- badcookie = TRUE;
- }
- }
-
- free(what);
-
- if(badcookie || !co->name) {
- /* we didn't get a cookie name or a bad one,
- this is an illegal line, bail out */
- freecookie(co);
- return NULL;
- }
-
- }
- else {
- /* This line is NOT a HTTP header style line, we do offer support for
- reading the odd netscape cookies-file format here */
- char *firstptr;
- char *tok_buf;
- int fields;
-
- if(lineptr[0]=='#') {
- /* don't even try the comments */
- free(co);
- return NULL;
- }
- /* strip off the possible end-of-line characters */
- ptr=strchr(lineptr, '\r');
- if(ptr)
- *ptr=0; /* clear it */
- ptr=strchr(lineptr, '\n');
- if(ptr)
- *ptr=0; /* clear it */
-
- firstptr=strtok_r(lineptr, "\t", &tok_buf); /* tokenize it on the TAB */
-
- /* Here's a quick check to eliminate normal HTTP-headers from this */
- if(!firstptr || strchr(firstptr, ':')) {
- free(co);
- return NULL;
- }
-
- /* Now loop through the fields and init the struct we already have
- allocated */
- for(ptr=firstptr, fields=0; ptr && !badcookie;
- ptr=strtok_r(NULL, "\t", &tok_buf), fields++) {
- switch(fields) {
- case 0:
- if(ptr[0]=='.') /* skip preceeding dots */
- ptr++;
- co->domain = strdup(ptr);
- if(!co->domain)
- badcookie = TRUE;
- break;
- case 1:
- /* This field got its explanation on the 23rd of May 2001 by
- Andrés García:
-
- flag: A TRUE/FALSE value indicating if all machines within a given
- domain can access the variable. This value is set automatically by
- the browser, depending on the value you set for the domain.
-
- As far as I can see, it is set to true when the cookie says
- .domain.com and to false when the domain is complete www.domain.com
- */
- co->tailmatch=(bool)strequal(ptr, "TRUE"); /* store information */
- break;
- case 2:
- /* It turns out, that sometimes the file format allows the path
- field to remain not filled in, we try to detect this and work
- around it! Andrés García made us aware of this... */
- if (strcmp("TRUE", ptr) && strcmp("FALSE", ptr)) {
- /* only if the path doesn't look like a boolean option! */
- co->path = strdup(ptr);
- if(!co->path)
- badcookie = TRUE;
- break;
- }
- /* this doesn't look like a path, make one up! */
- co->path = strdup("/");
- if(!co->path)
- badcookie = TRUE;
- fields++; /* add a field and fall down to secure */
- /* FALLTHROUGH */
- case 3:
- co->secure = (bool)strequal(ptr, "TRUE");
- break;
- case 4:
- co->expires = curlx_strtoofft(ptr, NULL, 10);
- break;
- case 5:
- co->name = strdup(ptr);
- if(!co->name)
- badcookie = TRUE;
- break;
- case 6:
- co->value = strdup(ptr);
- if(!co->value)
- badcookie = TRUE;
- break;
- }
- }
- if(6 == fields) {
- /* we got a cookie with blank contents, fix it */
- co->value = strdup("");
- if(!co->value)
- badcookie = TRUE;
- else
- fields++;
- }
-
- if(!badcookie && (7 != fields))
- /* we did not find the sufficient number of fields */
- badcookie = TRUE;
-
- if(badcookie) {
- freecookie(co);
- return NULL;
- }
-
- }
-
- if(!c->running && /* read from a file */
- c->newsession && /* clean session cookies */
- !co->expires) { /* this is a session cookie since it doesn't expire! */
- freecookie(co);
- return NULL;
- }
-
- co->livecookie = c->running;
-
- /* now, we have parsed the incoming line, we must now check if this
- superceeds an already existing cookie, which it may if the previous have
- the same domain and path as this */
-
- clist = c->cookies;
- replace_old = FALSE;
- while(clist) {
- if(strequal(clist->name, co->name)) {
- /* the names are identical */
-
- if(clist->domain && co->domain) {
- if(strequal(clist->domain, co->domain))
- /* The domains are identical */
- replace_old=TRUE;
- }
- else if(!clist->domain && !co->domain)
- replace_old = TRUE;
-
- if(replace_old) {
- /* the domains were identical */
-
- if(clist->path && co->path) {
- if(strequal(clist->path, co->path)) {
- replace_old = TRUE;
- }
- else
- replace_old = FALSE;
- }
- else if(!clist->path && !co->path)
- replace_old = TRUE;
- else
- replace_old = FALSE;
-
- }
-
- if(replace_old && !co->livecookie && clist->livecookie) {
- /* Both cookies matched fine, except that the already present
- cookie is "live", which means it was set from a header, while
- the new one isn't "live" and thus only read from a file. We let
- live cookies stay alive */
-
- /* Free the newcomer and get out of here! */
- freecookie(co);
- return NULL;
- }
-
- if(replace_old) {
- co->next = clist->next; /* get the next-pointer first */
-
- /* then free all the old pointers */
- if(clist->name)
- free(clist->name);
- if(clist->value)
- free(clist->value);
- if(clist->domain)
- free(clist->domain);
- if(clist->path)
- free(clist->path);
- if(clist->expirestr)
- free(clist->expirestr);
-
- if(clist->version)
- free(clist->version);
- if(clist->maxage)
- free(clist->maxage);
-
- *clist = *co; /* then store all the new data */
-
- free(co); /* free the newly alloced memory */
- co = clist; /* point to the previous struct instead */
-
- /* We have replaced a cookie, now skip the rest of the list but
- make sure the 'lastc' pointer is properly set */
- do {
- lastc = clist;
- clist = clist->next;
- } while(clist);
- break;
- }
- }
- lastc = clist;
- clist = clist->next;
- }
-
- if(c->running)
- /* Only show this when NOT reading the cookies from a file */
- infof(data, "%s cookie %s=\"%s\" for domain %s, path %s, expire %d\n",
- replace_old?"Replaced":"Added", co->name, co->value,
- co->domain, co->path, co->expires);
-
- if(!replace_old) {
- /* then make the last item point on this new one */
- if(lastc)
- lastc->next = co;
- else
- c->cookies = co;
- }
-
- c->numcookies++; /* one more cookie in the jar */
- return co;
-}
-
-/*****************************************************************************
- *
- * Curl_cookie_init()
- *
- * Inits a cookie struct to read data from a local file. This is always
- * called before any cookies are set. File may be NULL.
- *
- * If 'newsession' is TRUE, discard all "session cookies" on read from file.
- *
- ****************************************************************************/
-struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
- char *file,
- struct CookieInfo *inc,
- bool newsession)
-{
- struct CookieInfo *c;
- FILE *fp;
- bool fromfile=TRUE;
-
- if(NULL == inc) {
- /* we didn't get a struct, create one */
- c = (struct CookieInfo *)calloc(1, sizeof(struct CookieInfo));
- if(!c)
- return NULL; /* failed to get memory */
- c->filename = strdup(file?file:"none"); /* copy the name just in case */
- }
- else {
- /* we got an already existing one, use that */
- c = inc;
- }
- c->running = FALSE; /* this is not running, this is init */
-
- if(file && strequal(file, "-")) {
- fp = stdin;
- fromfile=FALSE;
- }
- else if(file && !*file) {
- /* points to a "" string */
- fp = NULL;
- }
- else
- fp = file?fopen(file, "r"):NULL;
-
- c->newsession = newsession; /* new session? */
-
- if(fp) {
- char *lineptr;
- bool headerline;
-
- char *line = (char *)malloc(MAX_COOKIE_LINE);
- if(line) {
- while(fgets(line, MAX_COOKIE_LINE, fp)) {
- if(checkprefix("Set-Cookie:", line)) {
- /* This is a cookie line, get it! */
- lineptr=&line[11];
- headerline=TRUE;
- }
- else {
- lineptr=line;
- headerline=FALSE;
- }
- while(*lineptr && my_isspace(*lineptr))
- lineptr++;
-
- Curl_cookie_add(data, c, headerline, lineptr, NULL, NULL);
- }
- free(line); /* free the line buffer */
- }
- if(fromfile)
- fclose(fp);
- }
-
- c->running = TRUE; /* now, we're running */
-
- return c;
-}
-
-/*****************************************************************************
- *
- * Curl_cookie_getlist()
- *
- * For a given host and path, return a linked list of cookies that the
- * client should send to the server if used now. The secure boolean informs
- * the cookie if a secure connection is achieved or not.
- *
- * It shall only return cookies that haven't expired.
- *
- ****************************************************************************/
-
-struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
- char *host, char *path, bool secure)
-{
- struct Cookie *newco;
- struct Cookie *co;
- time_t now = time(NULL);
- struct Cookie *mainco=NULL;
-
- if(!c || !c->cookies)
- return NULL; /* no cookie struct or no cookies in the struct */
-
- co = c->cookies;
-
- while(co) {
- /* only process this cookie if it is not expired or had no expire
- date AND that if the cookie requires we're secure we must only
- continue if we are! */
- if( (co->expires<=0 || (co->expires> now)) &&
- (co->secure?secure:TRUE) ) {
-
- /* now check if the domain is correct */
- if(!co->domain ||
- (co->tailmatch && tailmatch(co->domain, host)) ||
- (!co->tailmatch && strequal(host, co->domain)) ) {
- /* the right part of the host matches the domain stuff in the
- cookie data */
-
- /* now check the left part of the path with the cookies path
- requirement */
- if(!co->path ||
- /* not using checkprefix() because matching should be
- case-sensitive */
- !strncmp(co->path, path, strlen(co->path)) ) {
-
- /* and now, we know this is a match and we should create an
- entry for the return-linked-list */
-
- newco = (struct Cookie *)malloc(sizeof(struct Cookie));
- if(newco) {
- /* first, copy the whole source cookie: */
- memcpy(newco, co, sizeof(struct Cookie));
-
- /* then modify our next */
- newco->next = mainco;
-
- /* point the main to us */
- mainco = newco;
- }
- else {
- /* failure, clear up the allocated chain and return NULL */
- while(mainco) {
- co = mainco->next;
- free(mainco);
- mainco = co;
- }
-
- return NULL;
- }
- }
- }
- }
- co = co->next;
- }
-
- return mainco; /* return the new list */
-}
-
-/*****************************************************************************
- *
- * Curl_cookie_clearall()
- *
- * Clear all existing cookies and reset the counter.
- *
- ****************************************************************************/
-void Curl_cookie_clearall(struct CookieInfo *cookies)
-{
- if(cookies) {
- Curl_cookie_freelist(cookies->cookies);
- cookies->cookies = NULL;
- cookies->numcookies = 0;
- }
-}
-
-/*****************************************************************************
- *
- * Curl_cookie_freelist()
- *
- * Free a list of cookies previously returned by Curl_cookie_getlist();
- *
- ****************************************************************************/
-
-void Curl_cookie_freelist(struct Cookie *co)
-{
- struct Cookie *next;
- if(co) {
- while(co) {
- next = co->next;
- free(co); /* we only free the struct since the "members" are all
- just copied! */
- co = next;
- }
- }
-}
-
-
-/*****************************************************************************
- *
- * Curl_cookie_clearsess()
- *
- * Free all session cookies in the cookies list.
- *
- ****************************************************************************/
-void Curl_cookie_clearsess(struct CookieInfo *cookies)
-{
- struct Cookie *first, *curr, *next, *prev = NULL;
-
- if(!cookies->cookies)
- return;
-
- first = curr = prev = cookies->cookies;
-
- for(; curr; curr = next) {
- next = curr->next;
- if(!curr->expires) {
- if(first == curr)
- first = next;
-
- if(prev == curr)
- prev = next;
- else
- prev->next = next;
-
- free(curr);
- cookies->numcookies--;
- }
- else
- prev = curr;
- }
-
- cookies->cookies = first;
-}
-
-
-/*****************************************************************************
- *
- * Curl_cookie_cleanup()
- *
- * Free a "cookie object" previous created with cookie_init().
- *
- ****************************************************************************/
-void Curl_cookie_cleanup(struct CookieInfo *c)
-{
- struct Cookie *co;
- struct Cookie *next;
- if(c) {
- if(c->filename)
- free(c->filename);
- co = c->cookies;
-
- while(co) {
- next = co->next;
- freecookie(co);
- co = next;
- }
- free(c); /* free the base struct as well */
- }
-}
-
-/* get_netscape_format()
- *
- * Formats a string for Netscape output file, w/o a newline at the end.
- *
- * Function returns a char * to a formatted line. Has to be free()d
-*/
-static char *get_netscape_format(const struct Cookie *co)
-{
- return aprintf(
- "%s%s\t" /* domain */
- "%s\t" /* tailmatch */
- "%s\t" /* path */
- "%s\t" /* secure */
- "%" FORMAT_OFF_T "\t" /* expires */
- "%s\t" /* name */
- "%s", /* value */
- /* Make sure all domains are prefixed with a dot if they allow
- tailmatching. This is Mozilla-style. */
- (co->tailmatch && co->domain && co->domain[0] != '.')? ".":"",
- co->domain?co->domain:"unknown",
- co->tailmatch?"TRUE":"FALSE",
- co->path?co->path:"/",
- co->secure?"TRUE":"FALSE",
- co->expires,
- co->name,
- co->value?co->value:"");
-}
-
-/*
- * Curl_cookie_output()
- *
- * Writes all internally known cookies to the specified file. Specify
- * "-" as file name to write to stdout.
- *
- * The function returns non-zero on write failure.
- */
-int Curl_cookie_output(struct CookieInfo *c, char *dumphere)
-{
- struct Cookie *co;
- FILE *out;
- bool use_stdout=FALSE;
-
- if((NULL == c) || (0 == c->numcookies))
- /* If there are no known cookies, we don't write or even create any
- destination file */
- return 0;
-
- if(strequal("-", dumphere)) {
- /* use stdout */
- out = stdout;
- use_stdout=TRUE;
- }
- else {
- out = fopen(dumphere, "w");
- if(!out)
- return 1; /* failure */
- }
-
- if(c) {
- char *format_ptr;
-
- fputs("# Netscape HTTP Cookie File\n"
- "# http://curlm.haxx.se/rfc/cookie_spec.html\n"
- "# This file was generated by libcurl! Edit at your own risk.\n\n",
- out);
- co = c->cookies;
-
- while(co) {
- format_ptr = get_netscape_format(co);
- if (format_ptr == NULL) {
- fprintf(out, "#\n# Fatal libcurl error\n");
- if(!use_stdout)
- fclose(out);
- return 1;
- }
- fprintf(out, "%s\n", format_ptr);
- free(format_ptr);
- co=co->next;
- }
- }
-
- if(!use_stdout)
- fclose(out);
-
- return 0;
-}
-
-struct curl_slist *Curl_cookie_list(struct SessionHandle *data)
-{
- struct curl_slist *list = NULL;
- struct curl_slist *beg;
- struct Cookie *c;
- char *line;
-
- if ((data->cookies == NULL) ||
- (data->cookies->numcookies == 0))
- return NULL;
-
- c = data->cookies->cookies;
-
- beg = list;
- while (c) {
- /* fill the list with _all_ the cookies we know */
- line = get_netscape_format(c);
- if (line == NULL) {
- /* get_netscape_format returns null only if we run out of memory */
-
- curl_slist_free_all(beg); /* free some memory */
- return NULL;
- }
- list = curl_slist_append(list, line);
- free(line);
- c = c->next;
- }
-
- return list;
-}
-
-#endif /* CURL_DISABLE_HTTP || CURL_DISABLE_COOKIES */
diff --git a/Utilities/cmcurl/cookie.h b/Utilities/cmcurl/cookie.h
deleted file mode 100644
index 57c3acbdd..000000000
--- a/Utilities/cmcurl/cookie.h
+++ /dev/null
@@ -1,107 +0,0 @@
-#ifndef __COOKIE_H
-#define __COOKIE_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include <stdio.h>
-#if defined(WIN32)
-#include <time.h>
-#else
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#endif
-
-#include <curl/curl.h>
-
-struct Cookie {
- struct Cookie *next; /* next in the chain */
- char *name; /* <this> = value */
- char *value; /* name = <this> */
- char *path; /* path = <this> */
- char *domain; /* domain = <this> */
- curl_off_t expires; /* expires = <this> */
- char *expirestr; /* the plain text version */
- bool tailmatch; /* weather we do tail-matchning of the domain name */
-
- /* RFC 2109 keywords. Version=1 means 2109-compliant cookie sending */
- char *version; /* Version = <value> */
- char *maxage; /* Max-Age = <value> */
-
- bool secure; /* whether the 'secure' keyword was used */
- bool livecookie; /* updated from a server, not a stored file */
-};
-
-struct CookieInfo {
- /* linked list of cookies we know of */
- struct Cookie *cookies;
-
- char *filename; /* file we read from/write to */
- bool running; /* state info, for cookie adding information */
- long numcookies; /* number of cookies in the "jar" */
- bool newsession; /* new session, discard session cookies on load */
-};
-
-/* This is the maximum line length we accept for a cookie line. RFC 2109
- section 6.3 says:
-
- "at least 4096 bytes per cookie (as measured by the size of the characters
- that comprise the cookie non-terminal in the syntax description of the
- Set-Cookie header)"
-
-*/
-#define MAX_COOKIE_LINE 5000
-#define MAX_COOKIE_LINE_TXT "4999"
-
-/* This is the maximum length of a cookie name we deal with: */
-#define MAX_NAME 1024
-#define MAX_NAME_TXT "1023"
-
-struct SessionHandle;
-/*
- * Add a cookie to the internal list of cookies. The domain and path arguments
- * are only used if the header boolean is TRUE.
- */
-
-struct Cookie *Curl_cookie_add(struct SessionHandle *data,
- struct CookieInfo *, bool header, char *line,
- char *domain, char *path);
-
-struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
- char *, struct CookieInfo *, bool);
-struct Cookie *Curl_cookie_getlist(struct CookieInfo *, char *, char *, bool);
-void Curl_cookie_freelist(struct Cookie *);
-void Curl_cookie_clearall(struct CookieInfo *cookies);
-void Curl_cookie_clearsess(struct CookieInfo *cookies);
-void Curl_cookie_cleanup(struct CookieInfo *);
-int Curl_cookie_output(struct CookieInfo *, char *);
-
-#if defined(CURL_DISABLE_HTTP) || defined(CURL_DISABLE_COOKIES)
-#define Curl_cookie_list(x) NULL
-#define Curl_cookie_loadfiles(x) do { } while (0)
-#else
-struct curl_slist *Curl_cookie_list(struct SessionHandle *data);
-void Curl_cookie_loadfiles(struct SessionHandle *data);
-#endif
-
-#endif
diff --git a/Utilities/cmcurl/curl/curl.h b/Utilities/cmcurl/curl/curl.h
deleted file mode 100644
index e586c4a8c..000000000
--- a/Utilities/cmcurl/curl/curl.h
+++ /dev/null
@@ -1,1644 +0,0 @@
-#ifndef __CURL_CURL_H
-#define __CURL_CURL_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-/* If you have problems, all libcurl docs and details are found here:
- http://curl.haxx.se/libcurl/
-*/
-
-#include "curlver.h" /* the libcurl version defines */
-
-#include <stdio.h>
-#include <limits.h>
-
-/* The include stuff here below is mainly for time_t! */
-#ifdef vms
-# include <types.h>
-# include <time.h>
-#else
-# include <sys/types.h>
-# include <time.h>
-#endif /* defined (vms) */
-
-typedef void CURL;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Decorate exportable functions for Win32 DLL linking.
- * This avoids using a .def file for building libcurl.dll.
- */
-#if (defined(WIN32) || defined(_WIN32)) && !defined(CURL_STATICLIB)
-#if defined(BUILDING_LIBCURL)
-#define CURL_EXTERN __declspec(dllexport)
-#else
-#define CURL_EXTERN __declspec(dllimport)
-#endif
-#else
-
-#ifdef CURL_HIDDEN_SYMBOLS
-/*
- * This definition is used to make external definitions visibile in the
- * shared library when symbols are hidden by default. It makes no
- * difference when compiling applications whether this is set or not,
- * only when compiling the library.
- */
-#define CURL_EXTERN CURL_EXTERN_SYMBOL
-#else
-#define CURL_EXTERN
-#endif
-#endif
-
-/*
- * We want the typedef curl_off_t setup for large file support on all
- * platforms. We also provide a CURL_FORMAT_OFF_T define to use in *printf
- * format strings when outputting a variable of type curl_off_t.
- *
- * Note: "pocc -Ze" is MSVC compatibily mode and this sets _MSC_VER!
- */
-
-#if (defined(_MSC_VER) && !defined(__POCC__)) || (defined(__LCC__) && defined(WIN32))
-/* MSVC */
-#ifdef _WIN32_WCE
- typedef long curl_off_t;
-#define CURL_FORMAT_OFF_T "%ld"
-#else
- typedef signed __int64 curl_off_t;
-#define CURL_FORMAT_OFF_T "%I64d"
-#endif
-#else /* (_MSC_VER && !__POCC__) || (__LCC__ && WIN32) */
-#if (defined(__GNUC__) && defined(WIN32)) || defined(__WATCOMC__)
-/* gcc on windows or Watcom */
- typedef long long curl_off_t;
-#define CURL_FORMAT_OFF_T "%I64d"
-#else /* GCC or Watcom on Windows */
-
-/* "normal" POSIX approach, do note that this does not necessarily mean that
- the type is >32 bits, see the SIZEOF_CURL_OFF_T define for that! */
- typedef off_t curl_off_t;
-
-/* Check a range of defines to detect large file support. On Linux it seems
- none of these are set by default, so if you don't explicitly switches on
- large file support, this define will be made for "small file" support. */
-#ifndef _FILE_OFFSET_BITS
-#define _FILE_OFFSET_BITS 0 /* to prevent warnings in the check below */
-#define UNDEF_FILE_OFFSET_BITS
-#endif
-#ifndef FILESIZEBITS
-#define FILESIZEBITS 0 /* to prevent warnings in the check below */
-#define UNDEF_FILESIZEBITS
-#endif
-
-#if defined(_LARGE_FILES) || (_FILE_OFFSET_BITS > 32) || (FILESIZEBITS > 32) \
- || defined(_LARGEFILE_SOURCE) || defined(_LARGEFILE64_SOURCE)
- /* For now, we assume at least one of these to be set for large files to
- work! */
-#define CURL_FORMAT_OFF_T "%lld"
-#else /* LARGE_FILE support */
-#define CURL_FORMAT_OFF_T "%ld"
-#endif
-#endif /* GCC or Watcom on Windows */
-#endif /* (_MSC_VER && !__POCC__) || (__LCC__ && WIN32) */
-
-#ifdef UNDEF_FILE_OFFSET_BITS
-/* this was defined above for our checks, undefine it again */
-#undef _FILE_OFFSET_BITS
-#endif
-
-#ifdef UNDEF_FILESIZEBITS
-/* this was defined above for our checks, undefine it again */
-#undef FILESIZEBITS
-#endif
-
-#if defined(_WIN32) && !defined(WIN32)
-/* Chris Lewis mentioned that he doesn't get WIN32 defined, only _WIN32 so we
- make this adjustment to catch this. */
-#define WIN32 1
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__GNUC__) && \
- !defined(__CYGWIN__) || defined(__MINGW32__)
-#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H))
-/* The check above prevents the winsock2 inclusion if winsock.h already was
- included, since they can't co-exist without problems */
-#include <winsock2.h>
-#endif
-#else
-
-/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
- libc5-based Linux systems. Only include it on system that are known to
- require it! */
-#if defined(_AIX) || defined(NETWARE) || defined(__NetBSD__) || defined(__minix)
-#include <sys/select.h>
-#endif
-
-#ifndef _WIN32_WCE
-#include <sys/socket.h>
-#endif
-#ifndef __WATCOMC__
-#include <sys/time.h>
-#endif
-#include <sys/types.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef curl_socket_typedef
-/* socket typedef */
-#ifdef WIN32
-typedef SOCKET curl_socket_t;
-#define CURL_SOCKET_BAD INVALID_SOCKET
-#else
-typedef int curl_socket_t;
-#define CURL_SOCKET_BAD -1
-#endif
-#define curl_socket_typedef
-#endif /* curl_socket_typedef */
-
-struct curl_httppost {
- struct curl_httppost *next; /* next entry in the list */
- char *name; /* pointer to allocated name */
- long namelength; /* length of name length */
- char *contents; /* pointer to allocated data contents */
- long contentslength; /* length of contents field */
- char *buffer; /* pointer to allocated buffer contents */
- long bufferlength; /* length of buffer field */
- char *contenttype; /* Content-Type */
- struct curl_slist* contentheader; /* list of extra headers for this form */
- struct curl_httppost *more; /* if one field name has more than one
- file, this link should link to following
- files */
- long flags; /* as defined below */
-#define HTTPPOST_FILENAME (1<<0) /* specified content is a file name */
-#define HTTPPOST_READFILE (1<<1) /* specified content is a file name */
-#define HTTPPOST_PTRNAME (1<<2) /* name is only stored pointer
- do not free in formfree */
-#define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer
- do not free in formfree */
-#define HTTPPOST_BUFFER (1<<4) /* upload file from buffer */
-#define HTTPPOST_PTRBUFFER (1<<5) /* upload file from pointer contents */
-
- char *showfilename; /* The file name to show. If not set, the
- actual file name will be used (if this
- is a file part) */
-};
-
-typedef int (*curl_progress_callback)(void *clientp,
- double dltotal,
- double dlnow,
- double ultotal,
- double ulnow);
-
- /* Tests have proven that 20K is a very bad buffer size for uploads on
- Windows, while 16K for some odd reason performed a lot better. */
-#define CURL_MAX_WRITE_SIZE 16384
-
-typedef size_t (*curl_write_callback)(char *buffer,
- size_t size,
- size_t nitems,
- void *outstream);
-
-/* This is a return code for the read callback that, when returned, will
- signal libcurl to immediately abort the current transfer. */
-#define CURL_READFUNC_ABORT 0x10000000
-typedef size_t (*curl_read_callback)(char *buffer,
- size_t size,
- size_t nitems,
- void *instream);
-
-typedef enum {
- CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */
- CURLSOCKTYPE_LAST /* never use */
-} curlsocktype;
-
-typedef int (*curl_sockopt_callback)(void *clientp,
- curl_socket_t curlfd,
- curlsocktype purpose);
-
-#ifndef CURL_NO_OLDIES
- /* not used since 7.10.8, will be removed in a future release */
-typedef int (*curl_passwd_callback)(void *clientp,
- const char *prompt,
- char *buffer,
- int buflen);
-#endif
-
-typedef enum {
- CURLIOE_OK, /* I/O operation successful */
- CURLIOE_UNKNOWNCMD, /* command was unknown to callback */
- CURLIOE_FAILRESTART, /* failed to restart the read */
- CURLIOE_LAST /* never use */
-} curlioerr;
-
-typedef enum {
- CURLIOCMD_NOP, /* no operation */
- CURLIOCMD_RESTARTREAD, /* restart the read stream from start */
- CURLIOCMD_LAST /* never use */
-} curliocmd;
-
-typedef curlioerr (*curl_ioctl_callback)(CURL *handle,
- int cmd,
- void *clientp);
-
-/*
- * The following typedef's are signatures of malloc, free, realloc, strdup and
- * calloc respectively. Function pointers of these types can be passed to the
- * curl_global_init_mem() function to set user defined memory management
- * callback routines.
- */
-typedef void *(*curl_malloc_callback)(size_t size);
-typedef void (*curl_free_callback)(void *ptr);
-typedef void *(*curl_realloc_callback)(void *ptr, size_t size);
-typedef char *(*curl_strdup_callback)(const char *str);
-typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size);
-
-/* the kind of data that is passed to information_callback*/
-typedef enum {
- CURLINFO_TEXT = 0,
- CURLINFO_HEADER_IN, /* 1 */
- CURLINFO_HEADER_OUT, /* 2 */
- CURLINFO_DATA_IN, /* 3 */
- CURLINFO_DATA_OUT, /* 4 */
- CURLINFO_SSL_DATA_IN, /* 5 */
- CURLINFO_SSL_DATA_OUT, /* 6 */
- CURLINFO_END
-} curl_infotype;
-
-typedef int (*curl_debug_callback)
- (CURL *handle, /* the handle/transfer this concerns */
- curl_infotype type, /* what kind of data */
- char *data, /* points to the data */
- size_t size, /* size of the data pointed to */
- void *userptr); /* whatever the user please */
-
-/* All possible error codes from all sorts of curl functions. Future versions
- may return other values, stay prepared.
-
- Always add new return codes last. Never *EVER* remove any. The return
- codes must remain the same!
- */
-
-typedef enum {
- CURLE_OK = 0,
- CURLE_UNSUPPORTED_PROTOCOL, /* 1 */
- CURLE_FAILED_INIT, /* 2 */
- CURLE_URL_MALFORMAT, /* 3 */
- CURLE_NOT_BUILT_IN, /* 4 */
- CURLE_COULDNT_RESOLVE_PROXY, /* 5 */
- CURLE_COULDNT_RESOLVE_HOST, /* 6 */
- CURLE_COULDNT_CONNECT, /* 7 */
- CURLE_FTP_WEIRD_SERVER_REPLY, /* 8 */
- CURLE_FTP_ACCESS_DENIED, /* 9 a service was denied by the FTP server
- due to lack of access - when login fails
- this is not returned. */
- CURLE_FTP_USER_PASSWORD_INCORRECT, /* 10 - NOT USED */
- CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */
- CURLE_FTP_WEIRD_USER_REPLY, /* 12 */
- CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */
- CURLE_FTP_WEIRD_227_FORMAT, /* 14 */
- CURLE_FTP_CANT_GET_HOST, /* 15 */
- CURLE_FTP_CANT_RECONNECT, /* 16 */
- CURLE_FTP_COULDNT_SET_BINARY, /* 17 */
- CURLE_PARTIAL_FILE, /* 18 */
- CURLE_FTP_COULDNT_RETR_FILE, /* 19 */
- CURLE_FTP_WRITE_ERROR, /* 20 */
- CURLE_FTP_QUOTE_ERROR, /* 21 */
- CURLE_HTTP_RETURNED_ERROR, /* 22 */
- CURLE_WRITE_ERROR, /* 23 */
- CURLE_MALFORMAT_USER, /* 24 - NOT USED */
- CURLE_FTP_COULDNT_STOR_FILE, /* 25 - failed FTP upload */
- CURLE_READ_ERROR, /* 26 - could open/read from file */
- CURLE_OUT_OF_MEMORY, /* 27 */
- /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error
- instead of a memory allocation error if CURL_DOES_CONVERSIONS
- is defined
- */
- CURLE_OPERATION_TIMEOUTED, /* 28 - the timeout time was reached */
- CURLE_FTP_COULDNT_SET_ASCII, /* 29 - TYPE A failed */
- CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */
- CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */
- CURLE_FTP_COULDNT_GET_SIZE, /* 32 - the SIZE command failed */
- CURLE_HTTP_RANGE_ERROR, /* 33 - RANGE "command" didn't work */
- CURLE_HTTP_POST_ERROR, /* 34 */
- CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */
- CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */
- CURLE_FILE_COULDNT_READ_FILE, /* 37 */
- CURLE_LDAP_CANNOT_BIND, /* 38 */
- CURLE_LDAP_SEARCH_FAILED, /* 39 */
- CURLE_LIBRARY_NOT_FOUND, /* 40 */
- CURLE_FUNCTION_NOT_FOUND, /* 41 */
- CURLE_ABORTED_BY_CALLBACK, /* 42 */
- CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */
- CURLE_BAD_CALLING_ORDER, /* 44 - NOT USED */
- CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */
- CURLE_BAD_PASSWORD_ENTERED, /* 46 - NOT USED */
- CURLE_TOO_MANY_REDIRECTS , /* 47 - catch endless re-direct loops */
- CURLE_UNKNOWN_TELNET_OPTION, /* 48 - User specified an unknown option */
- CURLE_TELNET_OPTION_SYNTAX , /* 49 - Malformed telnet option */
- CURLE_OBSOLETE, /* 50 - NOT USED */
- CURLE_SSL_PEER_CERTIFICATE, /* 51 - peer's certificate wasn't ok */
- CURLE_GOT_NOTHING, /* 52 - when this is a specific error */
- CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */
- CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as
- default */
- CURLE_SEND_ERROR, /* 55 - failed sending network data */
- CURLE_RECV_ERROR, /* 56 - failure in receiving network data */
- CURLE_SHARE_IN_USE, /* 57 - share is in use */
- CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */
- CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */
- CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */
- CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized transfer encoding */
- CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */
- CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */
- CURLE_FTP_SSL_FAILED, /* 64 - Requested FTP SSL level failed */
- CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind
- that failed */
- CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */
- CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not
- accepted and we failed to login */
- CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */
- CURLE_TFTP_PERM, /* 69 - permission problem on server */
- CURLE_TFTP_DISKFULL, /* 70 - out of disk space on server */
- CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */
- CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */
- CURLE_TFTP_EXISTS, /* 73 - File already exists */
- CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */
- CURLE_CONV_FAILED, /* 75 - conversion failed */
- CURLE_CONV_REQD, /* 76 - caller must register conversion
- callbacks using curl_easy_setopt options
- CURLOPT_CONV_FROM_NETWORK_FUNCTION,
- CURLOPT_CONV_TO_NETWORK_FUNCTION, and
- CURLOPT_CONV_FROM_UTF8_FUNCTION */
- CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing
- or wrong format */
- CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */
- CURLE_SSH, /* 79 - error from the SSH layer, somewhat
- generic so the error message will be of
- interest when this has happened */
-
- CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL
- connection */
- CURL_LAST /* never use! */
-} CURLcode;
-
-/* This prototype applies to all conversion callbacks */
-typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length);
-
-typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */
- void *ssl_ctx, /* actually an
- OpenSSL SSL_CTX */
- void *userptr);
-
-/* Make a spelling correction for the operation timed-out define */
-#define CURLE_OPERATION_TIMEDOUT CURLE_OPERATION_TIMEOUTED
-
-#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
- the obsolete stuff removed! */
-/* backwards compatibility with older names */
-#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR
-#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED
-#endif
-
-typedef enum {
- CURLPROXY_HTTP = 0,
- CURLPROXY_SOCKS4 = 4,
- CURLPROXY_SOCKS5 = 5
-} curl_proxytype;
-
-#define CURLAUTH_NONE 0 /* nothing */
-#define CURLAUTH_BASIC (1<<0) /* Basic (default) */
-#define CURLAUTH_DIGEST (1<<1) /* Digest */
-#define CURLAUTH_GSSNEGOTIATE (1<<2) /* GSS-Negotiate */
-#define CURLAUTH_NTLM (1<<3) /* NTLM */
-#define CURLAUTH_ANY ~0 /* all types set */
-#define CURLAUTH_ANYSAFE (~CURLAUTH_BASIC)
-
-#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */
-#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */
-#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */
-#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */
-#define CURLSSH_AUTH_HOST (1<<2) /* host key files */
-#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */
-#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY
-
-#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
- the obsolete stuff removed! */
-/* this was the error code 50 in 7.7.3 and a few earlier versions, this
- is no longer used by libcurl but is instead #defined here only to not
- make programs break */
-#define CURLE_ALREADY_COMPLETE 99999
-
-/* These are just to make older programs not break: */
-#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE
-#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME
-#endif
-
-#define CURL_ERROR_SIZE 256
-
-/* parameter for the CURLOPT_FTP_SSL option */
-typedef enum {
- CURLFTPSSL_NONE, /* do not attempt to use SSL */
- CURLFTPSSL_TRY, /* try using SSL, proceed anyway otherwise */
- CURLFTPSSL_CONTROL, /* SSL for the control connection or fail */
- CURLFTPSSL_ALL, /* SSL for all communication or fail */
- CURLFTPSSL_LAST /* not an option, never use */
-} curl_ftpssl;
-
-/* parameter for the CURLOPT_FTPSSLAUTH option */
-typedef enum {
- CURLFTPAUTH_DEFAULT, /* let libcurl decide */
- CURLFTPAUTH_SSL, /* use "AUTH SSL" */
- CURLFTPAUTH_TLS, /* use "AUTH TLS" */
- CURLFTPAUTH_LAST /* not an option, never use */
-} curl_ftpauth;
-
-/* parameter for the CURLOPT_FTP_FILEMETHOD option */
-typedef enum {
- CURLFTPMETHOD_DEFAULT, /* let libcurl pick */
- CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */
- CURLFTPMETHOD_NOCWD, /* no CWD at all */
- CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */
- CURLFTPMETHOD_LAST /* not an option, never use */
-} curl_ftpmethod;
-
-/* long may be 32 or 64 bits, but we should never depend on anything else
- but 32 */
-#define CURLOPTTYPE_LONG 0
-#define CURLOPTTYPE_OBJECTPOINT 10000
-#define CURLOPTTYPE_FUNCTIONPOINT 20000
-#define CURLOPTTYPE_OFF_T 30000
-
-/* name is uppercase CURLOPT_<name>,
- type is one of the defined CURLOPTTYPE_<type>
- number is unique identifier */
-#ifdef CINIT
-#undef CINIT
-#endif
-/*
- * Figure out if we can use the ## operator, which is supported by ISO/ANSI C
- * and C++. Some compilers support it without setting __STDC__ or __cplusplus
- * so we need to carefully check for them too. We don't use configure-checks
- * for these since we want these headers to remain generic and working for all
- * platforms.
- */
-#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
- defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \
- defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__)
- /* This compiler is believed to have an ISO compatible preprocessor */
-#define CURL_ISOCPP
-#else
- /* This compiler is believed NOT to have an ISO compatible preprocessor */
-#undef CURL_ISOCPP
-#endif
-
-#ifdef CURL_ISOCPP
-#define CINIT(name,type,number) CURLOPT_ ## name = CURLOPTTYPE_ ## type + number
-#else
-/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
-#define LONG CURLOPTTYPE_LONG
-#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT
-#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT
-#define OFF_T CURLOPTTYPE_OFF_T
-#define CINIT(name,type,number) CURLOPT_/**/name = type + number
-#endif
-
-/*
- * This macro-mania below setups the CURLOPT_[what] enum, to be used with
- * curl_easy_setopt(). The first argument in the CINIT() macro is the [what]
- * word.
- */
-
-typedef enum {
- /* This is the FILE * or void * the regular output should be written to. */
- CINIT(FILE, OBJECTPOINT, 1),
-
- /* The full URL to get/put */
- CINIT(URL, OBJECTPOINT, 2),
-
- /* Port number to connect to, if other than default. */
- CINIT(PORT, LONG, 3),
-
- /* Name of proxy to use. */
- CINIT(PROXY, OBJECTPOINT, 4),
-
- /* "name:password" to use when fetching. */
- CINIT(USERPWD, OBJECTPOINT, 5),
-
- /* "name:password" to use with proxy. */
- CINIT(PROXYUSERPWD, OBJECTPOINT, 6),
-
- /* Range to get, specified as an ASCII string. */
- CINIT(RANGE, OBJECTPOINT, 7),
-
- /* not used */
-
- /* Specified file stream to upload from (use as input): */
- CINIT(INFILE, OBJECTPOINT, 9),
-
- /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE
- * bytes big. If this is not used, error messages go to stderr instead: */
- CINIT(ERRORBUFFER, OBJECTPOINT, 10),
-
- /* Function that will be called to store the output (instead of fwrite). The
- * parameters will use fwrite() syntax, make sure to follow them. */
- CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11),
-
- /* Function that will be called to read the input (instead of fread). The
- * parameters will use fread() syntax, make sure to follow them. */
- CINIT(READFUNCTION, FUNCTIONPOINT, 12),
-
- /* Time-out the read operation after this amount of seconds */
- CINIT(TIMEOUT, LONG, 13),
-
- /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about
- * how large the file being sent really is. That allows better error
- * checking and better verifies that the upload was succcessful. -1 means
- * unknown size.
- *
- * For large file support, there is also a _LARGE version of the key
- * which takes an off_t type, allowing platforms with larger off_t
- * sizes to handle larger files. See below for INFILESIZE_LARGE.
- */
- CINIT(INFILESIZE, LONG, 14),
-
- /* POST input fields. */
- CINIT(POSTFIELDS, OBJECTPOINT, 15),
-
- /* Set the referer page (needed by some CGIs) */
- CINIT(REFERER, OBJECTPOINT, 16),
-
- /* Set the FTP PORT string (interface name, named or numerical IP address)
- Use i.e '-' to use default address. */
- CINIT(FTPPORT, OBJECTPOINT, 17),
-
- /* Set the User-Agent string (examined by some CGIs) */
- CINIT(USERAGENT, OBJECTPOINT, 18),
-
- /* If the download receives less than "low speed limit" bytes/second
- * during "low speed time" seconds, the operations is aborted.
- * You could i.e if you have a pretty high speed connection, abort if
- * it is less than 2000 bytes/sec during 20 seconds.
- */
-
- /* Set the "low speed limit" */
- CINIT(LOW_SPEED_LIMIT, LONG , 19),
-
- /* Set the "low speed time" */
- CINIT(LOW_SPEED_TIME, LONG, 20),
-
- /* Set the continuation offset.
- *
- * Note there is also a _LARGE version of this key which uses
- * off_t types, allowing for large file offsets on platforms which
- * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE.
- */
- CINIT(RESUME_FROM, LONG, 21),
-
- /* Set cookie in request: */
- CINIT(COOKIE, OBJECTPOINT, 22),
-
- /* This points to a linked list of headers, struct curl_slist kind */
- CINIT(HTTPHEADER, OBJECTPOINT, 23),
-
- /* This points to a linked list of post entries, struct HttpPost */
- CINIT(HTTPPOST, OBJECTPOINT, 24),
-
- /* name of the file keeping your private SSL-certificate */
- CINIT(SSLCERT, OBJECTPOINT, 25),
-
- /* password for the SSL-private key, keep this for compatibility */
- CINIT(SSLCERTPASSWD, OBJECTPOINT, 26),
- /* password for the SSL private key */
- CINIT(SSLKEYPASSWD, OBJECTPOINT, 26),
-
- /* send TYPE parameter? */
- CINIT(CRLF, LONG, 27),
-
- /* send linked-list of QUOTE commands */
- CINIT(QUOTE, OBJECTPOINT, 28),
-
- /* send FILE * or void * to store headers to, if you use a callback it
- is simply passed to the callback unmodified */
- CINIT(WRITEHEADER, OBJECTPOINT, 29),
-
- /* point to a file to read the initial cookies from, also enables
- "cookie awareness" */
- CINIT(COOKIEFILE, OBJECTPOINT, 31),
-
- /* What version to specifly try to use.
- See CURL_SSLVERSION defines below. */
- CINIT(SSLVERSION, LONG, 32),
-
- /* What kind of HTTP time condition to use, see defines */
- CINIT(TIMECONDITION, LONG, 33),
-
- /* Time to use with the above condition. Specified in number of seconds
- since 1 Jan 1970 */
- CINIT(TIMEVALUE, LONG, 34),
-
- /* 35 = OBSOLETE */
-
- /* Custom request, for customizing the get command like
- HTTP: DELETE, TRACE and others
- FTP: to use a different list command
- */
- CINIT(CUSTOMREQUEST, OBJECTPOINT, 36),
-
- /* HTTP request, for odd commands like DELETE, TRACE and others */
- CINIT(STDERR, OBJECTPOINT, 37),
-
- /* 38 is not used */
-
- /* send linked-list of post-transfer QUOTE commands */
- CINIT(POSTQUOTE, OBJECTPOINT, 39),
-
- /* Pass a pointer to string of the output using full variable-replacement
- as described elsewhere. */
- CINIT(WRITEINFO, OBJECTPOINT, 40),
-
- CINIT(VERBOSE, LONG, 41), /* talk a lot */
- CINIT(HEADER, LONG, 42), /* throw the header out too */
- CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */
- CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */
- CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 300 */
- CINIT(UPLOAD, LONG, 46), /* this is an upload */
- CINIT(POST, LONG, 47), /* HTTP POST method */
- CINIT(FTPLISTONLY, LONG, 48), /* Use NLST when listing ftp dir */
-
- CINIT(FTPAPPEND, LONG, 50), /* Append instead of overwrite on upload! */
-
- /* Specify whether to read the user+password from the .netrc or the URL.
- * This must be one of the CURL_NETRC_* enums below. */
- CINIT(NETRC, LONG, 51),
-
- CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */
-
- CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */
- CINIT(PUT, LONG, 54), /* HTTP PUT */
-
- /* 55 = OBSOLETE */
-
- /* Function that will be called instead of the internal progress display
- * function. This function should be defined as the curl_progress_callback
- * prototype defines. */
- CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56),
-
- /* Data passed to the progress callback */
- CINIT(PROGRESSDATA, OBJECTPOINT, 57),
-
- /* We want the referer field set automatically when following locations */
- CINIT(AUTOREFERER, LONG, 58),
-
- /* Port of the proxy, can be set in the proxy string as well with:
- "[host]:[port]" */
- CINIT(PROXYPORT, LONG, 59),
-
- /* size of the POST input data, if strlen() is not good to use */
- CINIT(POSTFIELDSIZE, LONG, 60),
-
- /* tunnel non-http operations through a HTTP proxy */
- CINIT(HTTPPROXYTUNNEL, LONG, 61),
-
- /* Set the interface string to use as outgoing network interface */
- CINIT(INTERFACE, OBJECTPOINT, 62),
-
- /* Set the krb4 security level, this also enables krb4 awareness. This is a
- * string, 'clear', 'safe', 'confidential' or 'private'. If the string is
- * set but doesn't match one of these, 'private' will be used. */
- CINIT(KRB4LEVEL, OBJECTPOINT, 63),
-
- /* Set if we should verify the peer in ssl handshake, set 1 to verify. */
- CINIT(SSL_VERIFYPEER, LONG, 64),
-
- /* The CApath or CAfile used to validate the peer certificate
- this option is used only if SSL_VERIFYPEER is true */
- CINIT(CAINFO, OBJECTPOINT, 65),
-
- /* 66 = OBSOLETE */
- /* 67 = OBSOLETE */
-
- /* Maximum number of http redirects to follow */
- CINIT(MAXREDIRS, LONG, 68),
-
- /* Pass a long set to 1 to get the date of the requested document (if
- possible)! Pass a zero to shut it off. */
- CINIT(FILETIME, LONG, 69),
-
- /* This points to a linked list of telnet options */
- CINIT(TELNETOPTIONS, OBJECTPOINT, 70),
-
- /* Max amount of cached alive connections */
- CINIT(MAXCONNECTS, LONG, 71),
-
- /* What policy to use when closing connections when the cache is filled
- up */
- CINIT(CLOSEPOLICY, LONG, 72),
-
- /* 73 = OBSOLETE */
-
- /* Set to explicitly use a new connection for the upcoming transfer.
- Do not use this unless you're absolutely sure of this, as it makes the
- operation slower and is less friendly for the network. */
- CINIT(FRESH_CONNECT, LONG, 74),
-
- /* Set to explicitly forbid the upcoming transfer's connection to be re-used
- when done. Do not use this unless you're absolutely sure of this, as it
- makes the operation slower and is less friendly for the network. */
- CINIT(FORBID_REUSE, LONG, 75),
-
- /* Set to a file name that contains random data for libcurl to use to
- seed the random engine when doing SSL connects. */
- CINIT(RANDOM_FILE, OBJECTPOINT, 76),
-
- /* Set to the Entropy Gathering Daemon socket pathname */
- CINIT(EGDSOCKET, OBJECTPOINT, 77),
-
- /* Time-out connect operations after this amount of seconds, if connects
- are OK within this time, then fine... This only aborts the connect
- phase. [Only works on unix-style/SIGALRM operating systems] */
- CINIT(CONNECTTIMEOUT, LONG, 78),
-
- /* Function that will be called to store headers (instead of fwrite). The
- * parameters will use fwrite() syntax, make sure to follow them. */
- CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79),
-
- /* Set this to force the HTTP request to get back to GET. Only really usable
- if POST, PUT or a custom request have been used first.
- */
- CINIT(HTTPGET, LONG, 80),
-
- /* Set if we should verify the Common name from the peer certificate in ssl
- * handshake, set 1 to check existence, 2 to ensure that it matches the
- * provided hostname. */
- CINIT(SSL_VERIFYHOST, LONG, 81),
-
- /* Specify which file name to write all known cookies in after completed
- operation. Set file name to "-" (dash) to make it go to stdout. */
- CINIT(COOKIEJAR, OBJECTPOINT, 82),
-
- /* Specify which SSL ciphers to use */
- CINIT(SSL_CIPHER_LIST, OBJECTPOINT, 83),
-
- /* Specify which HTTP version to use! This must be set to one of the
- CURL_HTTP_VERSION* enums set below. */
- CINIT(HTTP_VERSION, LONG, 84),
-
- /* Specificly switch on or off the FTP engine's use of the EPSV command. By
- default, that one will always be attempted before the more traditional
- PASV command. */
- CINIT(FTP_USE_EPSV, LONG, 85),
-
- /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */
- CINIT(SSLCERTTYPE, OBJECTPOINT, 86),
-
- /* name of the file keeping your private SSL-key */
- CINIT(SSLKEY, OBJECTPOINT, 87),
-
- /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */
- CINIT(SSLKEYTYPE, OBJECTPOINT, 88),
-
- /* crypto engine for the SSL-sub system */
- CINIT(SSLENGINE, OBJECTPOINT, 89),
-
- /* set the crypto engine for the SSL-sub system as default
- the param has no meaning...
- */
- CINIT(SSLENGINE_DEFAULT, LONG, 90),
-
- /* Non-zero value means to use the global dns cache */
- CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* To becomeO BSOLETE soon */
-
- /* DNS cache timeout */
- CINIT(DNS_CACHE_TIMEOUT, LONG, 92),
-
- /* send linked-list of pre-transfer QUOTE commands (Wesley Laxton)*/
- CINIT(PREQUOTE, OBJECTPOINT, 93),
-
- /* set the debug function */
- CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94),
-
- /* set the data for the debug function */
- CINIT(DEBUGDATA, OBJECTPOINT, 95),
-
- /* mark this as start of a cookie session */
- CINIT(COOKIESESSION, LONG, 96),
-
- /* The CApath directory used to validate the peer certificate
- this option is used only if SSL_VERIFYPEER is true */
- CINIT(CAPATH, OBJECTPOINT, 97),
-
- /* Instruct libcurl to use a smaller receive buffer */
- CINIT(BUFFERSIZE, LONG, 98),
-
- /* Instruct libcurl to not use any signal/alarm handlers, even when using
- timeouts. This option is useful for multi-threaded applications.
- See libcurl-the-guide for more background information. */
- CINIT(NOSIGNAL, LONG, 99),
-
- /* Provide a CURLShare for mutexing non-ts data */
- CINIT(SHARE, OBJECTPOINT, 100),
-
- /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default),
- CURLPROXY_SOCKS4 and CURLPROXY_SOCKS5. */
- CINIT(PROXYTYPE, LONG, 101),
-
- /* Set the Accept-Encoding string. Use this to tell a server you would like
- the response to be compressed. */
- CINIT(ENCODING, OBJECTPOINT, 102),
-
- /* Set pointer to private data */
- CINIT(PRIVATE, OBJECTPOINT, 103),
-
- /* Set aliases for HTTP 200 in the HTTP Response header */
- CINIT(HTTP200ALIASES, OBJECTPOINT, 104),
-
- /* Continue to send authentication (user+password) when following locations,
- even when hostname changed. This can potentionally send off the name
- and password to whatever host the server decides. */
- CINIT(UNRESTRICTED_AUTH, LONG, 105),
-
- /* Specificly switch on or off the FTP engine's use of the EPRT command ( it
- also disables the LPRT attempt). By default, those ones will always be
- attempted before the good old traditional PORT command. */
- CINIT(FTP_USE_EPRT, LONG, 106),
-
- /* Set this to a bitmask value to enable the particular authentications
- methods you like. Use this in combination with CURLOPT_USERPWD.
- Note that setting multiple bits may cause extra network round-trips. */
- CINIT(HTTPAUTH, LONG, 107),
-
- /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx
- in second argument. The function must be matching the
- curl_ssl_ctx_callback proto. */
- CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108),
-
- /* Set the userdata for the ssl context callback function's third
- argument */
- CINIT(SSL_CTX_DATA, OBJECTPOINT, 109),
-
- /* FTP Option that causes missing dirs to be created on the remote server */
- CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110),
-
- /* Set this to a bitmask value to enable the particular authentications
- methods you like. Use this in combination with CURLOPT_PROXYUSERPWD.
- Note that setting multiple bits may cause extra network round-trips. */
- CINIT(PROXYAUTH, LONG, 111),
-
- /* FTP option that changes the timeout, in seconds, associated with
- getting a response. This is different from transfer timeout time and
- essentially places a demand on the FTP server to acknowledge commands
- in a timely manner. */
- CINIT(FTP_RESPONSE_TIMEOUT, LONG , 112),
-
- /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to
- tell libcurl to resolve names to those IP versions only. This only has
- affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */
- CINIT(IPRESOLVE, LONG, 113),
-
- /* Set this option to limit the size of a file that will be downloaded from
- an HTTP or FTP server.
-
- Note there is also _LARGE version which adds large file support for
- platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */
- CINIT(MAXFILESIZE, LONG, 114),
-
- /* See the comment for INFILESIZE above, but in short, specifies
- * the size of the file being uploaded. -1 means unknown.
- */
- CINIT(INFILESIZE_LARGE, OFF_T, 115),
-
- /* Sets the continuation offset. There is also a LONG version of this;
- * look above for RESUME_FROM.
- */
- CINIT(RESUME_FROM_LARGE, OFF_T, 116),
-
- /* Sets the maximum size of data that will be downloaded from
- * an HTTP or FTP server. See MAXFILESIZE above for the LONG version.
- */
- CINIT(MAXFILESIZE_LARGE, OFF_T, 117),
-
- /* Set this option to the file name of your .netrc file you want libcurl
- to parse (using the CURLOPT_NETRC option). If not set, libcurl will do
- a poor attempt to find the user's home directory and check for a .netrc
- file in there. */
- CINIT(NETRC_FILE, OBJECTPOINT, 118),
-
- /* Enable SSL/TLS for FTP, pick one of:
- CURLFTPSSL_TRY - try using SSL, proceed anyway otherwise
- CURLFTPSSL_CONTROL - SSL for the control connection or fail
- CURLFTPSSL_ALL - SSL for all communication or fail
- */
- CINIT(FTP_SSL, LONG, 119),
-
- /* The _LARGE version of the standard POSTFIELDSIZE option */
- CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120),
-
- /* Enable/disable the TCP Nagle algorithm */
- CINIT(TCP_NODELAY, LONG, 121),
-
- /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
- /* 123 OBSOLETE. Gone in 7.16.0 */
- /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
- /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
- /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
- /* 127 OBSOLETE. Gone in 7.16.0 */
- /* 128 OBSOLETE. Gone in 7.16.0 */
-
- /* When FTP over SSL/TLS is selected (with CURLOPT_FTP_SSL), this option
- can be used to change libcurl's default action which is to first try
- "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK
- response has been received.
-
- Available parameters are:
- CURLFTPAUTH_DEFAULT - let libcurl decide
- CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS
- CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL
- */
- CINIT(FTPSSLAUTH, LONG, 129),
-
- CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130),
- CINIT(IOCTLDATA, OBJECTPOINT, 131),
-
- /* 132 OBSOLETE. Gone in 7.16.0 */
- /* 133 OBSOLETE. Gone in 7.16.0 */
-
- /* zero terminated string for pass on to the FTP server when asked for
- "account" info */
- CINIT(FTP_ACCOUNT, OBJECTPOINT, 134),
-
- /* feed cookies into cookie engine */
- CINIT(COOKIELIST, OBJECTPOINT, 135),
-
- /* ignore Content-Length */
- CINIT(IGNORE_CONTENT_LENGTH, LONG, 136),
-
- /* Set to non-zero to skip the IP address received in a 227 PASV FTP server
- response. Typically used for FTP-SSL purposes but is not restricted to
- that. libcurl will then instead use the same IP address it used for the
- control connection. */
- CINIT(FTP_SKIP_PASV_IP, LONG, 137),
-
- /* Select "file method" to use when doing FTP, see the curl_ftpmethod
- above. */
- CINIT(FTP_FILEMETHOD, LONG, 138),
-
- /* Local port number to bind the socket to */
- CINIT(LOCALPORT, LONG, 139),
-
- /* Number of ports to try, including the first one set with LOCALPORT.
- Thus, setting it to 1 will make no additional attempts but the first.
- */
- CINIT(LOCALPORTRANGE, LONG, 140),
-
- /* no transfer, set up connection and let application use the socket by
- extracting it with CURLINFO_LASTSOCKET */
- CINIT(CONNECT_ONLY, LONG, 141),
-
- /* Function that will be called to convert from the
- network encoding (instead of using the iconv calls in libcurl) */
- CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142),
-
- /* Function that will be called to convert to the
- network encoding (instead of using the iconv calls in libcurl) */
- CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143),
-
- /* Function that will be called to convert from UTF8
- (instead of using the iconv calls in libcurl)
- Note that this is used only for SSL certificate processing */
- CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144),
-
- /* if the connection proceeds too quickly then need to slow it down */
- /* limit-rate: maximum number of bytes per second to send or receive */
- CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145),
- CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146),
-
- /* Pointer to command string to send if USER/PASS fails. */
- CINIT(FTP_ALTERNATIVE_TO_USER, OBJECTPOINT, 147),
-
- /* callback function for setting socket options */
- CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148),
- CINIT(SOCKOPTDATA, OBJECTPOINT, 149),
-
- /* set to 0 to disable session ID re-use for this transfer, default is
- enabled (== 1) */
- CINIT(SSL_SESSIONID_CACHE, LONG, 150),
-
- /* allowed SSH authentication methods */
- CINIT(SSH_AUTH_TYPES, LONG, 151),
-
- /* Used by scp/sftp to do public/private key authentication */
- CINIT(SSH_PUBLIC_KEYFILE, OBJECTPOINT, 152),
- CINIT(SSH_PRIVATE_KEYFILE, OBJECTPOINT, 153),
-
- /* Send CCC (Clear Command Channel) after authentication */
- CINIT(FTP_SSL_CCC, LONG, 154),
-
- CURLOPT_LASTENTRY /* the last unused */
-} CURLoption;
-
- /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host
- name resolves addresses using more than one IP protocol version, this
- option might be handy to force libcurl to use a specific IP version. */
-#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP
- versions that your system allows */
-#define CURL_IPRESOLVE_V4 1 /* resolve to ipv4 addresses */
-#define CURL_IPRESOLVE_V6 2 /* resolve to ipv6 addresses */
-
- /* three convenient "aliases" that follow the name scheme better */
-#define CURLOPT_WRITEDATA CURLOPT_FILE
-#define CURLOPT_READDATA CURLOPT_INFILE
-#define CURLOPT_HEADERDATA CURLOPT_WRITEHEADER
-
-#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
- the obsolete stuff removed! */
-#else
-/* This is set if CURL_NO_OLDIES is defined at compile-time */
-#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */
-#endif
-
-
- /* These enums are for use with the CURLOPT_HTTP_VERSION option. */
-enum {
- CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd
- like the library to choose the best possible
- for us! */
- CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */
- CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */
-
- CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */
-};
-
- /* These enums are for use with the CURLOPT_NETRC option. */
-enum CURL_NETRC_OPTION {
- CURL_NETRC_IGNORED, /* The .netrc will never be read.
- * This is the default. */
- CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred
- * to one in the .netrc. */
- CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored.
- * Unless one is set programmatically, the .netrc
- * will be queried. */
- CURL_NETRC_LAST
-};
-
-enum {
- CURL_SSLVERSION_DEFAULT,
- CURL_SSLVERSION_TLSv1,
- CURL_SSLVERSION_SSLv2,
- CURL_SSLVERSION_SSLv3,
-
- CURL_SSLVERSION_LAST /* never use, keep last */
-};
-
-
-typedef enum {
- CURL_TIMECOND_NONE,
-
- CURL_TIMECOND_IFMODSINCE,
- CURL_TIMECOND_IFUNMODSINCE,
- CURL_TIMECOND_LASTMOD,
-
- CURL_TIMECOND_LAST
-} curl_TimeCond;
-
-#ifdef __cplusplus
-}
-#endif
-
-#if defined __BEOS__ || defined __HAIKU__
-#include <support/SupportDefs.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* curl_strequal() and curl_strnequal() are subject for removal in a future
- libcurl, see lib/README.curlx for details */
-CURL_EXTERN int (curl_strequal)(const char *s1, const char *s2);
-CURL_EXTERN int (curl_strnequal)(const char *s1, const char *s2, size_t n);
-
-/* name is uppercase CURLFORM_<name> */
-#ifdef CFINIT
-#undef CFINIT
-#endif
-
-#ifdef CURL_ISOCPP
-#define CFINIT(name) CURLFORM_ ## name
-#else
-/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
-#define CFINIT(name) CURLFORM_/**/name
-#endif
-
-typedef enum {
- CFINIT(NOTHING), /********* the first one is unused ************/
-
- /* */
- CFINIT(COPYNAME),
- CFINIT(PTRNAME),
- CFINIT(NAMELENGTH),
- CFINIT(COPYCONTENTS),
- CFINIT(PTRCONTENTS),
- CFINIT(CONTENTSLENGTH),
- CFINIT(FILECONTENT),
- CFINIT(ARRAY),
- CFINIT(OBSOLETE),
- CFINIT(FILE),
-
- CFINIT(BUFFER),
- CFINIT(BUFFERPTR),
- CFINIT(BUFFERLENGTH),
-
- CFINIT(CONTENTTYPE),
- CFINIT(CONTENTHEADER),
- CFINIT(FILENAME),
- CFINIT(END),
- CFINIT(OBSOLETE2),
-
- CURLFORM_LASTENTRY /* the last unusued */
-} CURLformoption;
-
-#undef CFINIT /* done */
-
-/* structure to be used as parameter for CURLFORM_ARRAY */
-struct curl_forms {
- CURLformoption option;
- const char *value;
-};
-
-/* use this for multipart formpost building */
-/* Returns code for curl_formadd()
- *
- * Returns:
- * CURL_FORMADD_OK on success
- * CURL_FORMADD_MEMORY if the FormInfo allocation fails
- * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form
- * CURL_FORMADD_NULL if a null pointer was given for a char
- * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed
- * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
- * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error)
- * CURL_FORMADD_MEMORY if a HttpPost struct cannot be allocated
- * CURL_FORMADD_MEMORY if some allocation for string copying failed.
- * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array
- *
- ***************************************************************************/
-typedef enum {
- CURL_FORMADD_OK, /* first, no error */
-
- CURL_FORMADD_MEMORY,
- CURL_FORMADD_OPTION_TWICE,
- CURL_FORMADD_NULL,
- CURL_FORMADD_UNKNOWN_OPTION,
- CURL_FORMADD_INCOMPLETE,
- CURL_FORMADD_ILLEGAL_ARRAY,
- CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */
-
- CURL_FORMADD_LAST /* last */
-} CURLFORMcode;
-
-/*
- * NAME curl_formadd()
- *
- * DESCRIPTION
- *
- * Pretty advanved function for building multi-part formposts. Each invoke
- * adds one part that together construct a full post. Then use
- * CURLOPT_HTTPPOST to send it off to libcurl.
- */
-CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost,
- struct curl_httppost **last_post,
- ...);
-
-/*
- * callback function for curl_formget()
- * The void *arg pointer will be the one passed as second argument to curl_formget().
- * The character buffer passed to it must not be freed.
- * Should return the buffer length passed to it as the argument "len" on success.
- */
-typedef size_t (*curl_formget_callback)(void *arg, const char *buf, size_t len);
-
-/*
- * NAME curl_formget()
- *
- * DESCRIPTION
- *
- * Serialize a curl_httppost struct built with curl_formadd().
- * Accepts a void pointer as second argument which will be passed to
- * the curl_formget_callback function.
- * Returns 0 on success.
- */
-CURL_EXTERN int curl_formget(struct curl_httppost *form, void *arg,
- curl_formget_callback append);
-/*
- * NAME curl_formfree()
- *
- * DESCRIPTION
- *
- * Free a multipart formpost previously built with curl_formadd().
- */
-CURL_EXTERN void curl_formfree(struct curl_httppost *form);
-
-/*
- * NAME curl_getenv()
- *
- * DESCRIPTION
- *
- * Returns a malloc()'ed string that MUST be curl_free()ed after usage is
- * complete. DEPRECATED - see lib/README.curlx
- */
-CURL_EXTERN char *curl_getenv(const char *variable);
-
-/*
- * NAME curl_version()
- *
- * DESCRIPTION
- *
- * Returns a static ascii string of the libcurl version.
- */
-CURL_EXTERN char *curl_version(void);
-
-/*
- * NAME curl_easy_escape()
- *
- * DESCRIPTION
- *
- * Escapes URL strings (converts all letters consider illegal in URLs to their
- * %XX versions). This function returns a new allocated string or NULL if an
- * error occurred.
- */
-CURL_EXTERN char *curl_easy_escape(CURL *handle,
- const char *string,
- int length);
-
-/* the previous version: */
-CURL_EXTERN char *curl_escape(const char *string,
- int length);
-
-
-/*
- * NAME curl_easy_unescape()
- *
- * DESCRIPTION
- *
- * Unescapes URL encoding in strings (converts all %XX codes to their 8bit
- * versions). This function returns a new allocated string or NULL if an error
- * occurred.
- * Conversion Note: On non-ASCII platforms the ASCII %XX codes are
- * converted into the host encoding.
- */
-CURL_EXTERN char *curl_easy_unescape(CURL *handle,
- const char *string,
- int length,
- int *outlength);
-
-/* the previous version */
-CURL_EXTERN char *curl_unescape(const char *string,
- int length);
-
-/*
- * NAME curl_free()
- *
- * DESCRIPTION
- *
- * Provided for de-allocation in the same translation unit that did the
- * allocation. Added in libcurl 7.10
- */
-CURL_EXTERN void curl_free(void *p);
-
-/*
- * NAME curl_global_init()
- *
- * DESCRIPTION
- *
- * curl_global_init() should be invoked exactly once for each application that
- * uses libcurl
- */
-CURL_EXTERN CURLcode curl_global_init(long flags);
-
-/*
- * NAME curl_global_init_mem()
- *
- * DESCRIPTION
- *
- * curl_global_init() or curl_global_init_mem() should be invoked exactly once
- * for each application that uses libcurl. This function can be used to
- * initialize libcurl and set user defined memory management callback
- * functions. Users can implement memory management routines to check for
- * memory leaks, check for mis-use of the curl library etc. User registered
- * callback routines with be invoked by this library instead of the system
- * memory management routines like malloc, free etc.
- */
-CURL_EXTERN CURLcode curl_global_init_mem(long flags,
- curl_malloc_callback m,
- curl_free_callback f,
- curl_realloc_callback r,
- curl_strdup_callback s,
- curl_calloc_callback c);
-
-/*
- * NAME curl_global_cleanup()
- *
- * DESCRIPTION
- *
- * curl_global_cleanup() should be invoked exactly once for each application
- * that uses libcurl
- */
-CURL_EXTERN void curl_global_cleanup(void);
-
-/* linked-list structure for the CURLOPT_QUOTE option (and other) */
-struct curl_slist {
- char *data;
- struct curl_slist *next;
-};
-
-/*
- * NAME curl_slist_append()
- *
- * DESCRIPTION
- *
- * Appends a string to a linked list. If no list exists, it will be created
- * first. Returns the new list, after appending.
- */
-CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *,
- const char *);
-
-/*
- * NAME curl_slist_free_all()
- *
- * DESCRIPTION
- *
- * free a previously built curl_slist.
- */
-CURL_EXTERN void curl_slist_free_all(struct curl_slist *);
-
-/*
- * NAME curl_getdate()
- *
- * DESCRIPTION
- *
- * Returns the time, in seconds since 1 Jan 1970 of the time string given in
- * the first argument. The time argument in the second parameter is unused
- * and should be set to NULL.
- */
-CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused);
-
-#define CURLINFO_STRING 0x100000
-#define CURLINFO_LONG 0x200000
-#define CURLINFO_DOUBLE 0x300000
-#define CURLINFO_SLIST 0x400000
-#define CURLINFO_MASK 0x0fffff
-#define CURLINFO_TYPEMASK 0xf00000
-
-typedef enum {
- CURLINFO_NONE, /* first, never use this */
- CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1,
- CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2,
- CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3,
- CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4,
- CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5,
- CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6,
- CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE + 7,
- CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE + 8,
- CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE + 9,
- CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE + 10,
- CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11,
- CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12,
- CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13,
- CURLINFO_FILETIME = CURLINFO_LONG + 14,
- CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15,
- CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16,
- CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17,
- CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18,
- CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19,
- CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20,
- CURLINFO_PRIVATE = CURLINFO_STRING + 21,
- CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22,
- CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23,
- CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24,
- CURLINFO_OS_ERRNO = CURLINFO_LONG + 25,
- CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26,
- CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27,
- CURLINFO_COOKIELIST = CURLINFO_SLIST + 28,
- CURLINFO_LASTSOCKET = CURLINFO_LONG + 29,
- CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30,
- /* Fill in new entries below here! */
-
- CURLINFO_LASTONE = 30
-} CURLINFO;
-
-/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
- CURLINFO_HTTP_CODE */
-#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE
-
-typedef enum {
- CURLCLOSEPOLICY_NONE, /* first, never use this */
-
- CURLCLOSEPOLICY_OLDEST,
- CURLCLOSEPOLICY_LEAST_RECENTLY_USED,
- CURLCLOSEPOLICY_LEAST_TRAFFIC,
- CURLCLOSEPOLICY_SLOWEST,
- CURLCLOSEPOLICY_CALLBACK,
-
- CURLCLOSEPOLICY_LAST /* last, never use this */
-} curl_closepolicy;
-
-#define CURL_GLOBAL_SSL (1<<0)
-#define CURL_GLOBAL_WIN32 (1<<1)
-#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32)
-#define CURL_GLOBAL_NOTHING 0
-#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL
-
-
-/*****************************************************************************
- * Setup defines, protos etc for the sharing stuff.
- */
-
-/* Different data locks for a single share */
-typedef enum {
- CURL_LOCK_DATA_NONE = 0,
- /* CURL_LOCK_DATA_SHARE is used internaly to say that
- * the locking is just made to change the internal state of the share
- * itself.
- */
- CURL_LOCK_DATA_SHARE,
- CURL_LOCK_DATA_COOKIE,
- CURL_LOCK_DATA_DNS,
- CURL_LOCK_DATA_SSL_SESSION,
- CURL_LOCK_DATA_CONNECT,
- CURL_LOCK_DATA_LAST
-} curl_lock_data;
-
-/* Different lock access types */
-typedef enum {
- CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */
- CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */
- CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */
- CURL_LOCK_ACCESS_LAST /* never use */
-} curl_lock_access;
-
-typedef void (*curl_lock_function)(CURL *handle,
- curl_lock_data data,
- curl_lock_access locktype,
- void *userptr);
-typedef void (*curl_unlock_function)(CURL *handle,
- curl_lock_data data,
- void *userptr);
-
-typedef void CURLSH;
-
-typedef enum {
- CURLSHE_OK, /* all is fine */
- CURLSHE_BAD_OPTION, /* 1 */
- CURLSHE_IN_USE, /* 2 */
- CURLSHE_INVALID, /* 3 */
- CURLSHE_NOMEM, /* out of memory */
- CURLSHE_LAST /* never use */
-} CURLSHcode;
-
-typedef enum {
- CURLSHOPT_NONE, /* don't use */
- CURLSHOPT_SHARE, /* specify a data type to share */
- CURLSHOPT_UNSHARE, /* specify shich data type to stop sharing */
- CURLSHOPT_LOCKFUNC, /* pass in a 'curl_lock_function' pointer */
- CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */
- CURLSHOPT_USERDATA, /* pass in a user data pointer used in the lock/unlock
- callback functions */
- CURLSHOPT_LAST /* never use */
-} CURLSHoption;
-
-CURL_EXTERN CURLSH *curl_share_init(void);
-CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...);
-CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *);
-
-/****************************************************************************
- * Structures for querying information about the curl library at runtime.
- */
-
-typedef enum {
- CURLVERSION_FIRST,
- CURLVERSION_SECOND,
- CURLVERSION_THIRD,
- CURLVERSION_FOURTH,
- CURLVERSION_LAST /* never actually use this */
-} CURLversion;
-
-/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by
- basicly all programs ever, that want to get version information. It is
- meant to be a built-in version number for what kind of struct the caller
- expects. If the struct ever changes, we redefine the NOW to another enum
- from above. */
-#define CURLVERSION_NOW CURLVERSION_FOURTH
-
-typedef struct {
- CURLversion age; /* age of the returned struct */
- const char *version; /* LIBCURL_VERSION */
- unsigned int version_num; /* LIBCURL_VERSION_NUM */
- const char *host; /* OS/host/cpu/machine when configured */
- int features; /* bitmask, see defines below */
- const char *ssl_version; /* human readable string */
- long ssl_version_num; /* not used anymore, always 0 */
- const char *libz_version; /* human readable string */
- /* protocols is terminated by an entry with a NULL protoname */
- const char * const *protocols;
-
- /* The fields below this were added in CURLVERSION_SECOND */
- const char *ares;
- int ares_num;
-
- /* This field was added in CURLVERSION_THIRD */
- const char *libidn;
-
- /* These field were added in CURLVERSION_FOURTH */
-
- /* Same as '_libiconv_version' if built with HAVE_ICONV */
- int iconv_ver_num;
-
- const char *libssh_version; /* human readable string */
-
-} curl_version_info_data;
-
-#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */
-#define CURL_VERSION_KERBEROS4 (1<<1) /* kerberos auth is supported */
-#define CURL_VERSION_SSL (1<<2) /* SSL options are present */
-#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */
-#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */
-#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth support */
-#define CURL_VERSION_DEBUG (1<<6) /* built with debug capabilities */
-#define CURL_VERSION_ASYNCHDNS (1<<7) /* asynchronous dns resolves */
-#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth */
-#define CURL_VERSION_LARGEFILE (1<<9) /* supports files bigger than 2GB */
-#define CURL_VERSION_IDN (1<<10) /* International Domain Names support */
-#define CURL_VERSION_SSPI (1<<11) /* SSPI is supported */
-#define CURL_VERSION_CONV (1<<12) /* character conversions are
- supported */
-
-/*
- * NAME curl_version_info()
- *
- * DESCRIPTION
- *
- * This function returns a pointer to a static copy of the version info
- * struct. See above.
- */
-CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion);
-
-/*
- * NAME curl_easy_strerror()
- *
- * DESCRIPTION
- *
- * The curl_easy_strerror function may be used to turn a CURLcode value
- * into the equivalent human readable error string. This is useful
- * for printing meaningful error messages.
- */
-CURL_EXTERN const char *curl_easy_strerror(CURLcode);
-
-/*
- * NAME curl_share_strerror()
- *
- * DESCRIPTION
- *
- * The curl_share_strerror function may be used to turn a CURLSHcode value
- * into the equivalent human readable error string. This is useful
- * for printing meaningful error messages.
- */
-CURL_EXTERN const char *curl_share_strerror(CURLSHcode);
-
-#ifdef __cplusplus
-}
-#endif
-
-/* unfortunately, the easy.h and multi.h include files need options and info
- stuff before they can be included! */
-#include "easy.h" /* nothing in curl is fun without the easy stuff */
-#include "multi.h"
-
-#endif /* __CURL_CURL_H */
diff --git a/Utilities/cmcurl/curl/curlver.h b/Utilities/cmcurl/curl/curlver.h
deleted file mode 100644
index 938002285..000000000
--- a/Utilities/cmcurl/curl/curlver.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef __CURL_CURLVER_H
-#define __CURL_CURLVER_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-/* This header file contains nothing but libcurl version info, generated by
- a script at release-time. This was made its own header file in 7.11.2 */
-
-/* This is the version number of the libcurl package from which this header
- file origins: */
-#define LIBCURL_VERSION "7.16.1"
-
-/* The numeric version number is also available "in parts" by using these
- defines: */
-#define LIBCURL_VERSION_MAJOR 7
-#define LIBCURL_VERSION_MINOR 16
-#define LIBCURL_VERSION_PATCH 1
-
-/* This is the numeric version of the libcurl version number, meant for easier
- parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
- always follow this syntax:
-
- 0xXXYYZZ
-
- Where XX, YY and ZZ are the main version, release and patch numbers in
- hexadecimal (using 8 bits each). All three numbers are always represented
- using two digits. 1.2 would appear as "0x010200" while version 9.11.7
- appears as "0x090b07".
-
- This 6-digit (24 bits) hexadecimal number does not show pre-release number,
- and it is always a greater number in a more recent release. It makes
- comparisons with greater than and less than work.
-*/
-#define LIBCURL_VERSION_NUM 0x071001
-
-#endif /* __CURL_CURLVER_H */
diff --git a/Utilities/cmcurl/curl/easy.h b/Utilities/cmcurl/curl/easy.h
deleted file mode 100644
index 17de21070..000000000
--- a/Utilities/cmcurl/curl/easy.h
+++ /dev/null
@@ -1,81 +0,0 @@
-#ifndef __CURL_EASY_H
-#define __CURL_EASY_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-CURL_EXTERN CURL *curl_easy_init(void);
-CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
-CURL_EXTERN CURLcode curl_easy_perform(CURL *curl);
-CURL_EXTERN void curl_easy_cleanup(CURL *curl);
-
-/*
- * NAME curl_easy_getinfo()
- *
- * DESCRIPTION
- *
- * Request internal information from the curl session with this function. The
- * third argument MUST be a pointer to a long, a pointer to a char * or a
- * pointer to a double (as the documentation describes elsewhere). The data
- * pointed to will be filled in accordingly and can be relied upon only if the
- * function returns CURLE_OK. This function is intended to get used *AFTER* a
- * performed transfer, all results from this function are undefined until the
- * transfer is completed.
- */
-CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...);
-
-
-/*
- * NAME curl_easy_duphandle()
- *
- * DESCRIPTION
- *
- * Creates a new curl session handle with the same options set for the handle
- * passed in. Duplicating a handle could only be a matter of cloning data and
- * options, internal state info and things like persistant connections cannot
- * be transfered. It is useful in multithreaded applications when you can run
- * curl_easy_duphandle() for each new thread to avoid a series of identical
- * curl_easy_setopt() invokes in every thread.
- */
-CURL_EXTERN CURL* curl_easy_duphandle(CURL *curl);
-
-/*
- * NAME curl_easy_reset()
- *
- * DESCRIPTION
- *
- * Re-initializes a CURL handle to the default values. This puts back the
- * handle to the same state as it was in when it was just created.
- *
- * It does keep: live connections, the Session ID cache, the DNS cache and the
- * cookies.
- */
-CURL_EXTERN void curl_easy_reset(CURL *curl);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/Utilities/cmcurl/curl/mprintf.h b/Utilities/cmcurl/curl/mprintf.h
deleted file mode 100644
index 5c526882f..000000000
--- a/Utilities/cmcurl/curl/mprintf.h
+++ /dev/null
@@ -1,80 +0,0 @@
-#ifndef __CURL_MPRINTF_H
-#define __CURL_MPRINTF_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include <stdarg.h>
-#include <stdio.h> /* needed for FILE */
-
-#include "curl.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-CURL_EXTERN int curl_mprintf(const char *format, ...);
-CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...);
-CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...);
-CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength, const char *format, ...);
-CURL_EXTERN int curl_mvprintf(const char *format, va_list args);
-CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args);
-CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args);
-CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength, const char *format, va_list args);
-CURL_EXTERN char *curl_maprintf(const char *format, ...);
-CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args);
-
-#ifdef _MPRINTF_REPLACE
-# undef printf
-# undef fprintf
-# undef sprintf
-# undef vsprintf
-# undef snprintf
-# undef vprintf
-# undef vfprintf
-# undef vsnprintf
-# undef aprintf
-# undef vaprintf
-# define printf curl_mprintf
-# define fprintf curl_mfprintf
-#ifdef CURLDEBUG
-/* When built with CURLDEBUG we define away the sprintf() functions since we
- don't want internal code to be using them */
-# define sprintf sprintf_was_used
-# define vsprintf vsprintf_was_used
-#else
-# define sprintf curl_msprintf
-# define vsprintf curl_mvsprintf
-#endif
-# define snprintf curl_msnprintf
-# define vprintf curl_mvprintf
-# define vfprintf curl_mvfprintf
-# define vsnprintf curl_mvsnprintf
-# define aprintf curl_maprintf
-# define vaprintf curl_mvaprintf
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __CURL_MPRINTF_H */
diff --git a/Utilities/cmcurl/curl/multi.h b/Utilities/cmcurl/curl/multi.h
deleted file mode 100644
index 1b6674768..000000000
--- a/Utilities/cmcurl/curl/multi.h
+++ /dev/null
@@ -1,327 +0,0 @@
-#ifndef __CURL_MULTI_H
-#define __CURL_MULTI_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-/*
- This is an "external" header file. Don't give away any internals here!
-
- GOALS
-
- o Enable a "pull" interface. The application that uses libcurl decides where
- and when to ask libcurl to get/send data.
-
- o Enable multiple simultaneous transfers in the same thread without making it
- complicated for the application.
-
- o Enable the application to select() on its own file descriptors and curl's
- file descriptors simultaneous easily.
-
-*/
-
-/*
- * This header file should not really need to include "curl.h" since curl.h
- * itself includes this file and we expect user applications to do #include
- * <curl/curl.h> without the need for especially including multi.h.
- *
- * For some reason we added this include here at one point, and rather than to
- * break existing (wrongly written) libcurl applications, we leave it as-is
- * but with this warning attached.
- */
-#include "curl.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef void CURLM;
-
-typedef enum {
- CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or
- curl_multi_socket*() soon */
- CURLM_OK,
- CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */
- CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */
- CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */
- CURLM_INTERNAL_ERROR, /* this is a libcurl bug */
- CURLM_BAD_SOCKET, /* the passed in socket argument did not match */
- CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */
- CURLM_LAST
-} CURLMcode;
-
-/* just to make code nicer when using curl_multi_socket() you can now check
- for CURLM_CALL_MULTI_SOCKET too in the same style it works for
- curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */
-#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM
-
-typedef enum {
- CURLMSG_NONE, /* first, not used */
- CURLMSG_DONE, /* This easy handle has completed. 'result' contains
- the CURLcode of the transfer */
- CURLMSG_LAST /* last, not used */
-} CURLMSG;
-
-struct CURLMsg {
- CURLMSG msg; /* what this message means */
- CURL *easy_handle; /* the handle it concerns */
- union {
- void *whatever; /* message-specific data */
- CURLcode result; /* return code for transfer */
- } data;
-};
-typedef struct CURLMsg CURLMsg;
-
-/*
- * Name: curl_multi_init()
- *
- * Desc: inititalize multi-style curl usage
- *
- * Returns: a new CURLM handle to use in all 'curl_multi' functions.
- */
-CURL_EXTERN CURLM *curl_multi_init(void);
-
-/*
- * Name: curl_multi_add_handle()
- *
- * Desc: add a standard curl handle to the multi stack
- *
- * Returns: CURLMcode type, general multi error code.
- */
-CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle,
- CURL *curl_handle);
-
- /*
- * Name: curl_multi_remove_handle()
- *
- * Desc: removes a curl handle from the multi stack again
- *
- * Returns: CURLMcode type, general multi error code.
- */
-CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
- CURL *curl_handle);
-
- /*
- * Name: curl_multi_fdset()
- *
- * Desc: Ask curl for its fd_set sets. The app can use these to select() or
- * poll() on. We want curl_multi_perform() called as soon as one of
- * them are ready.
- *
- * Returns: CURLMcode type, general multi error code.
- */
-CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle,
- fd_set *read_fd_set,
- fd_set *write_fd_set,
- fd_set *exc_fd_set,
- int *max_fd);
-
- /*
- * Name: curl_multi_perform()
- *
- * Desc: When the app thinks there's data available for curl it calls this
- * function to read/write whatever there is right now. This returns
- * as soon as the reads and writes are done. This function does not
- * require that there actually is data available for reading or that
- * data can be written, it can be called just in case. It returns
- * the number of handles that still transfer data in the second
- * argument's integer-pointer.
- *
- * Returns: CURLMcode type, general multi error code. *NOTE* that this only
- * returns errors etc regarding the whole multi stack. There might
- * still have occurred problems on invidual transfers even when this
- * returns OK.
- */
-CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle,
- int *running_handles);
-
- /*
- * Name: curl_multi_cleanup()
- *
- * Desc: Cleans up and removes a whole multi stack. It does not free or
- * touch any individual easy handles in any way. We need to define
- * in what state those handles will be if this function is called
- * in the middle of a transfer.
- *
- * Returns: CURLMcode type, general multi error code.
- */
-CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle);
-
-/*
- * Name: curl_multi_info_read()
- *
- * Desc: Ask the multi handle if there's any messages/informationals from
- * the individual transfers. Messages include informationals such as
- * error code from the transfer or just the fact that a transfer is
- * completed. More details on these should be written down as well.
- *
- * Repeated calls to this function will return a new struct each
- * time, until a special "end of msgs" struct is returned as a signal
- * that there is no more to get at this point.
- *
- * The data the returned pointer points to will not survive calling
- * curl_multi_cleanup().
- *
- * The 'CURLMsg' struct is meant to be very simple and only contain
- * very basic information. If more involved information is wanted,
- * we will provide the particular "transfer handle" in that struct
- * and that should/could/would be used in subsequent
- * curl_easy_getinfo() calls (or similar). The point being that we
- * must never expose complex structs to applications, as then we'll
- * undoubtably get backwards compatibility problems in the future.
- *
- * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out
- * of structs. It also writes the number of messages left in the
- * queue (after this read) in the integer the second argument points
- * to.
- */
-CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle,
- int *msgs_in_queue);
-
-/*
- * Name: curl_multi_strerror()
- *
- * Desc: The curl_multi_strerror function may be used to turn a CURLMcode
- * value into the equivalent human readable error string. This is
- * useful for printing meaningful error messages.
- *
- * Returns: A pointer to a zero-terminated error message.
- */
-CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
-
-/*
- * Name: curl_multi_socket() and
- * curl_multi_socket_all()
- *
- * Desc: An alternative version of curl_multi_perform() that allows the
- * application to pass in one of the file descriptors that have been
- * detected to have "action" on them and let libcurl perform.
- * See man page for details.
- */
-#define CURL_POLL_NONE 0
-#define CURL_POLL_IN 1
-#define CURL_POLL_OUT 2
-#define CURL_POLL_INOUT 3
-#define CURL_POLL_REMOVE 4
-
-#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD
-
-typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */
- curl_socket_t s, /* socket */
- int what, /* see above */
- void *userp, /* private callback
- pointer */
- void *socketp); /* private socket
- pointer */
-/*
- * Name: curl_multi_timer_callback
- *
- * Desc: Called by libcurl whenever the library detects a change in the
- * maximum number of milliseconds the app is allowed to wait before
- * curl_multi_socket() or curl_multi_perform() must be called
- * (to allow libcurl's timed events to take place).
- *
- * Returns: The callback should return zero.
- */
-typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */
- long timeout_ms, /* see above */
- void *userp); /* private callback
- pointer */
-
-CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
- int *running_handles);
-
-CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle,
- int *running_handles);
-
-/*
- * Name: curl_multi_timeout()
- *
- * Desc: Returns the maximum number of milliseconds the app is allowed to
- * wait before curl_multi_socket() or curl_multi_perform() must be
- * called (to allow libcurl's timed events to take place).
- *
- * Returns: CURLM error code.
- */
-CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle,
- long *milliseconds);
-
-#undef CINIT /* re-using the same name as in curl.h */
-
-#ifdef CURL_ISOCPP
-#define CINIT(name,type,number) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + number
-#else
-/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
-#define LONG CURLOPTTYPE_LONG
-#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT
-#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT
-#define OFF_T CURLOPTTYPE_OFF_T
-#define CINIT(name,type,number) CURLMOPT_/**/name = type + number
-#endif
-
-typedef enum {
- /* This is the socket callback function pointer */
- CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1),
-
- /* This is the argument passed to the socket callback */
- CINIT(SOCKETDATA, OBJECTPOINT, 2),
-
- /* set to 1 to enable pipelining for this multi handle */
- CINIT(PIPELINING, LONG, 3),
-
- /* This is the timer callback function pointer */
- CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4),
-
- /* This is the argument passed to the timer callback */
- CINIT(TIMERDATA, OBJECTPOINT, 5),
-
- CURLMOPT_LASTENTRY /* the last unused */
-} CURLMoption;
-
-
-/*
- * Name: curl_multi_setopt()
- *
- * Desc: Sets options for the multi handle.
- *
- * Returns: CURLM error code.
- */
-CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle,
- CURLMoption option, ...);
-
-
-/*
- * Name: curl_multi_assign()
- *
- * Desc: This function sets an association in the multi handle between the
- * given socket and a private pointer of the application. This is
- * (only) useful for curl_multi_socket uses.
- *
- * Returns: CURLM error code.
- */
-CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle,
- curl_socket_t sockfd, void *sockp);
-
-#ifdef __cplusplus
-} /* end of extern "C" */
-#endif
-
-#endif
diff --git a/Utilities/cmcurl/curl/stdcheaders.h b/Utilities/cmcurl/curl/stdcheaders.h
deleted file mode 100644
index 11c1e2f6e..000000000
--- a/Utilities/cmcurl/curl/stdcheaders.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef __STDC_HEADERS_H
-#define __STDC_HEADERS_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include <sys/types.h>
-
-size_t fread (void *, size_t, size_t, FILE *);
-size_t fwrite (const void *, size_t, size_t, FILE *);
-
-int strcasecmp(const char *, const char *);
-int strncasecmp(const char *, const char *, size_t);
-
-#endif
diff --git a/Utilities/cmcurl/curl/types.h b/Utilities/cmcurl/curl/types.h
deleted file mode 100644
index d37d6ae9e..000000000
--- a/Utilities/cmcurl/curl/types.h
+++ /dev/null
@@ -1 +0,0 @@
-/* not used */
diff --git a/Utilities/cmcurl/Testing/curltest.c b/Utilities/cmcurl/curltest.c
index 210868e36..210868e36 100644
--- a/Utilities/cmcurl/Testing/curltest.c
+++ b/Utilities/cmcurl/curltest.c
diff --git a/Utilities/cmcurl/curlx.h b/Utilities/cmcurl/curlx.h
deleted file mode 100644
index 26948d305..000000000
--- a/Utilities/cmcurl/curlx.h
+++ /dev/null
@@ -1,107 +0,0 @@
-#ifndef __CURLX_H
-#define __CURLX_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-/*
- * Defines protos and includes all header files that provide the curlx_*
- * functions. The curlx_* functions are not part of the libcurl API, but are
- * stand-alone functions whose sources can be built and linked by apps if need
- * be.
- */
-
-#include <curl/mprintf.h>
-/* this is still a public header file that provides the curl_mprintf()
- functions while they still are offered publicly. They will be made library-
- private one day */
-
-#include "strequal.h"
-/* "strequal.h" provides the strequal protos */
-
-#include "strtoofft.h"
-/* "strtoofft.h" provides this function: curlx_strtoofft(), returns a
- curl_off_t number from a given string.
-*/
-
-#include "timeval.h"
-/*
- "timeval.h" sets up a 'struct timeval' even for platforms that otherwise
- don't have one and has protos for these functions:
-
- curlx_tvnow()
- curlx_tvdiff()
- curlx_tvdiff_secs()
-*/
-
-/* Now setup curlx_ * names for the functions that are to become curlx_ and
- be removed from a future libcurl official API:
- curlx_getenv
- curlx_mprintf (and its variations)
- curlx_strequal
- curlx_strnequal
-
-*/
-
-#define curlx_getenv curl_getenv
-#define curlx_strequal curl_strequal
-#define curlx_strnequal curl_strnequal
-#define curlx_mvsnprintf curl_mvsnprintf
-#define curlx_msnprintf curl_msnprintf
-#define curlx_maprintf curl_maprintf
-#define curlx_mvaprintf curl_mvaprintf
-#define curlx_msprintf curl_msprintf
-#define curlx_mprintf curl_mprintf
-#define curlx_mfprintf curl_mfprintf
-#define curlx_mvsprintf curl_mvsprintf
-#define curlx_mvprintf curl_mvprintf
-#define curlx_mvfprintf curl_mvfprintf
-
-#ifdef ENABLE_CURLX_PRINTF
-/* If this define is set, we define all "standard" printf() functions to use
- the curlx_* version instead. It makes the source code transparant and
- easier to understand/patch. Undefine them first in case _MPRINTF_REPLACE
- is set. */
-# undef printf
-# undef fprintf
-# undef sprintf
-# undef snprintf
-# undef vprintf
-# undef vfprintf
-# undef vsprintf
-# undef vsnprintf
-# undef aprintf
-# undef vaprintf
-
-# define printf curlx_mprintf
-# define fprintf curlx_mfprintf
-# define sprintf curlx_msprintf
-# define snprintf curlx_msnprintf
-# define vprintf curlx_mvprintf
-# define vfprintf curlx_mvfprintf
-# define vsprintf curlx_mvsprintf
-# define vsnprintf curlx_mvsnprintf
-# define aprintf curlx_maprintf
-# define vaprintf curlx_mvaprintf
-#endif /* ENABLE_CURLX_PRINTF */
-
-#endif /* __CURLX_H */
diff --git a/Utilities/cmcurl/dict.c b/Utilities/cmcurl/dict.c
deleted file mode 100644
index d6443f4b9..000000000
--- a/Utilities/cmcurl/dict.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#ifndef CURL_DISABLE_DICT
-
-/* -- WIN32 approved -- */
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <ctype.h>
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-
-#ifdef WIN32
-#include <time.h>
-#include <io.h>
-#else
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#include <netinet/in.h>
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <netdb.h>
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_NET_IF_H
-#include <net/if.h>
-#endif
-#include <sys/ioctl.h>
-#include <signal.h>
-
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-
-#endif
-
-#include "urldata.h"
-#include <curl/curl.h>
-#include "transfer.h"
-#include "sendf.h"
-
-#include "progress.h"
-#include "strequal.h"
-#include "dict.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
-#include "memdebug.h"
-
-static char *unescape_word(struct SessionHandle *data, char *inp)
-{
- char *newp;
- char *dictp;
- char *ptr;
- int len;
- unsigned char byte;
- int olen=0;
-
- newp = curl_easy_unescape(data, inp, 0, &len);
- if(!newp)
- return NULL;
-
- dictp = malloc(len*2 + 1); /* add one for terminating zero */
- if(dictp) {
- /* According to RFC2229 section 2.2, these letters need to be escaped with
- \[letter] */
- for(ptr = newp;
- (byte = (unsigned char)*ptr) != 0;
- ptr++) {
- if ((byte <= 32) || (byte == 127) ||
- (byte == '\'') || (byte == '\"') || (byte == '\\')) {
- dictp[olen++] = '\\';
- }
- dictp[olen++] = byte;
- }
- dictp[olen]=0;
-
- free(newp);
- }
- return dictp;
-}
-
-CURLcode Curl_dict(struct connectdata *conn, bool *done)
-{
- char *word;
- char *eword;
- char *ppath;
- char *database = NULL;
- char *strategy = NULL;
- char *nthdef = NULL; /* This is not part of the protocol, but required
- by RFC 2229 */
- CURLcode result=CURLE_OK;
- struct SessionHandle *data=conn->data;
- curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
-
- char *path = data->reqdata.path;
- curl_off_t *bytecount = &data->reqdata.keep.bytecount;
-
- *done = TRUE; /* unconditionally */
-
- if(conn->bits.user_passwd) {
- /* AUTH is missing */
- }
-
- if (strnequal(path, DICT_MATCH, sizeof(DICT_MATCH)-1) ||
- strnequal(path, DICT_MATCH2, sizeof(DICT_MATCH2)-1) ||
- strnequal(path, DICT_MATCH3, sizeof(DICT_MATCH3)-1)) {
-
- word = strchr(path, ':');
- if (word) {
- word++;
- database = strchr(word, ':');
- if (database) {
- *database++ = (char)0;
- strategy = strchr(database, ':');
- if (strategy) {
- *strategy++ = (char)0;
- nthdef = strchr(strategy, ':');
- if (nthdef) {
- *nthdef++ = (char)0;
- }
- }
- }
- }
-
- if ((word == NULL) || (*word == (char)0)) {
- failf(data, "lookup word is missing");
- }
- if ((database == NULL) || (*database == (char)0)) {
- database = (char *)"!";
- }
- if ((strategy == NULL) || (*strategy == (char)0)) {
- strategy = (char *)".";
- }
-
- eword = unescape_word(data, word);
- if(!eword)
- return CURLE_OUT_OF_MEMORY;
-
- result = Curl_sendf(sockfd, conn,
- "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
- "MATCH "
- "%s " /* database */
- "%s " /* strategy */
- "%s\r\n" /* word */
- "QUIT\r\n",
-
- database,
- strategy,
- eword
- );
-
- free(eword);
-
- if(result)
- failf(data, "Failed sending DICT request");
- else
- result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
- -1, NULL); /* no upload */
- if(result)
- return result;
- }
- else if (strnequal(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) ||
- strnequal(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) ||
- strnequal(path, DICT_DEFINE3, sizeof(DICT_DEFINE3)-1)) {
-
- word = strchr(path, ':');
- if (word) {
- word++;
- database = strchr(word, ':');
- if (database) {
- *database++ = (char)0;
- nthdef = strchr(database, ':');
- if (nthdef) {
- *nthdef++ = (char)0;
- }
- }
- }
-
- if ((word == NULL) || (*word == (char)0)) {
- failf(data, "lookup word is missing");
- }
- if ((database == NULL) || (*database == (char)0)) {
- database = (char *)"!";
- }
-
- eword = unescape_word(data, word);
- if(!eword)
- return CURLE_OUT_OF_MEMORY;
-
- result = Curl_sendf(sockfd, conn,
- "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
- "DEFINE "
- "%s " /* database */
- "%s\r\n" /* word */
- "QUIT\r\n",
- database,
- eword);
-
- free(eword);
-
- if(result)
- failf(data, "Failed sending DICT request");
- else
- result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
- -1, NULL); /* no upload */
-
- if(result)
- return result;
-
- }
- else {
-
- ppath = strchr(path, '/');
- if (ppath) {
- int i;
-
- ppath++;
- for (i = 0; ppath[i]; i++) {
- if (ppath[i] == ':')
- ppath[i] = ' ';
- }
- result = Curl_sendf(sockfd, conn,
- "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
- "%s\r\n"
- "QUIT\r\n", ppath);
- if(result)
- failf(data, "Failed sending DICT request");
- else
- result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
- -1, NULL);
- if(result)
- return result;
- }
- }
-
- return CURLE_OK;
-}
-#endif /*CURL_DISABLE_DICT*/
diff --git a/Utilities/cmcurl/dict.h b/Utilities/cmcurl/dict.h
deleted file mode 100644
index d3da1936f..000000000
--- a/Utilities/cmcurl/dict.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef __DICT_H
-#define __DICT_H
-
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-#ifndef CURL_DISABLE_DICT
-CURLcode Curl_dict(struct connectdata *conn, bool *done);
-CURLcode Curl_dict_done(struct connectdata *conn);
-#endif
-#endif
diff --git a/Utilities/cmcurl/easy.c b/Utilities/cmcurl/easy.c
deleted file mode 100644
index 209d1c3e0..000000000
--- a/Utilities/cmcurl/easy.c
+++ /dev/null
@@ -1,895 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-/* -- WIN32 approved -- */
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <ctype.h>
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-
-#include <errno.h>
-
-#include "strequal.h"
-
-#ifdef WIN32
-#include <time.h>
-#include <io.h>
-#else
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#include <netinet/in.h>
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <netdb.h>
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_NET_IF_H
-#include <net/if.h>
-#endif
-#include <sys/ioctl.h>
-#include <signal.h>
-
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-#endif /* WIN32 ... */
-
-#include "urldata.h"
-#include <curl/curl.h>
-#include "transfer.h"
-#include "sslgen.h"
-#include "url.h"
-#include "getinfo.h"
-#include "hostip.h"
-#include "share.h"
-#include "strdup.h"
-#include "memory.h"
-#include "progress.h"
-#include "easyif.h"
-#include "sendf.h" /* for failf function prototype */
-#include <ca-bundle.h>
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
-#include <iconv.h>
-/* set default codesets for iconv */
-#ifndef CURL_ICONV_CODESET_OF_NETWORK
-#define CURL_ICONV_CODESET_OF_NETWORK "ISO8859-1"
-#endif
-#ifndef CURL_ICONV_CODESET_FOR_UTF8
-#define CURL_ICONV_CODESET_FOR_UTF8 "UTF-8"
-#endif
-#define ICONV_ERROR (size_t)-1
-#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
-
-/* The last #include file should be: */
-#include "memdebug.h"
-
-#ifdef USE_WINSOCK
-/* win32_cleanup() is for win32 socket cleanup functionality, the opposite
- of win32_init() */
-static void win32_cleanup(void)
-{
- WSACleanup();
-}
-
-/* win32_init() performs win32 socket initialization to properly setup the
- stack to allow networking */
-static CURLcode win32_init(void)
-{
- WORD wVersionRequested;
- WSADATA wsaData;
- int err;
-
-#if defined(ENABLE_IPV6) && (USE_WINSOCK < 2)
- Error IPV6_requires_winsock2
-#endif
-
- wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
-
- err = WSAStartup(wVersionRequested, &wsaData);
-
- if (err != 0)
- /* Tell the user that we couldn't find a useable */
- /* winsock.dll. */
- return CURLE_FAILED_INIT;
-
- /* Confirm that the Windows Sockets DLL supports what we need.*/
- /* Note that if the DLL supports versions greater */
- /* than wVersionRequested, it will still return */
- /* wVersionRequested in wVersion. wHighVersion contains the */
- /* highest supported version. */
-
- if ( LOBYTE( wsaData.wVersion ) != LOBYTE(wVersionRequested) ||
- HIBYTE( wsaData.wVersion ) != HIBYTE(wVersionRequested) ) {
- /* Tell the user that we couldn't find a useable */
-
- /* winsock.dll. */
- WSACleanup();
- return CURLE_FAILED_INIT;
- }
- /* The Windows Sockets DLL is acceptable. Proceed. */
- return CURLE_OK;
-}
-
-#else
-/* These functions exist merely to prevent compiler warnings */
-static CURLcode win32_init(void) { return CURLE_OK; }
-static void win32_cleanup(void) { }
-#endif
-
-#ifdef USE_LIBIDN
-/*
- * Initialise use of IDNA library.
- * It falls back to ASCII if $CHARSET isn't defined. This doesn't work for
- * idna_to_ascii_lz().
- */
-static void idna_init (void)
-{
-#ifdef WIN32
- char buf[60];
- UINT cp = GetACP();
-
- if (!getenv("CHARSET") && cp > 0) {
- snprintf(buf, sizeof(buf), "CHARSET=cp%u", cp);
- putenv(buf);
- }
-#else
- /* to do? */
-#endif
-}
-#endif /* USE_LIBIDN */
-
-/* true globals -- for curl_global_init() and curl_global_cleanup() */
-static unsigned int initialized;
-static long init_flags;
-
-/*
- * strdup (and other memory functions) is redefined in complicated
- * ways, but at this point it must be defined as the system-supplied strdup
- * so the callback pointer is initialized correctly.
- */
-#if defined(_WIN32_WCE)
-#define system_strdup _strdup
-#elif !defined(HAVE_STRDUP)
-#define system_strdup curlx_strdup
-#else
-#define system_strdup strdup
-#endif
-
-/*
- * If a memory-using function (like curl_getenv) is used before
- * curl_global_init() is called, we need to have these pointers set already.
- */
-
-curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc;
-curl_free_callback Curl_cfree = (curl_free_callback)free;
-curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc;
-curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)system_strdup;
-curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
-
-/**
- * curl_global_init() globally initializes cURL given a bitwise set of the
- * different features of what to initialize.
- */
-CURLcode curl_global_init(long flags)
-{
- if (initialized++)
- return CURLE_OK;
-
- /* Setup the default memory functions here (again) */
- Curl_cmalloc = (curl_malloc_callback)malloc;
- Curl_cfree = (curl_free_callback)free;
- Curl_crealloc = (curl_realloc_callback)realloc;
- Curl_cstrdup = (curl_strdup_callback)system_strdup;
- Curl_ccalloc = (curl_calloc_callback)calloc;
-
- if (flags & CURL_GLOBAL_SSL)
- if (!Curl_ssl_init())
- return CURLE_FAILED_INIT;
-
- if (flags & CURL_GLOBAL_WIN32)
- if (win32_init() != CURLE_OK)
- return CURLE_FAILED_INIT;
-
-#ifdef _AMIGASF
- if(!amiga_init())
- return CURLE_FAILED_INIT;
-#endif
-
-#ifdef USE_LIBIDN
- idna_init();
-#endif
-
- init_flags = flags;
-
- return CURLE_OK;
-}
-
-/*
- * curl_global_init_mem() globally initializes cURL and also registers the
- * user provided callback routines.
- */
-CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
- curl_free_callback f, curl_realloc_callback r,
- curl_strdup_callback s, curl_calloc_callback c)
-{
- CURLcode code = CURLE_OK;
-
- /* Invalid input, return immediately */
- if (!m || !f || !r || !s || !c)
- return CURLE_FAILED_INIT;
-
- /* Already initialized, don't do it again */
- if ( initialized )
- return CURLE_OK;
-
- /* Call the actual init function first */
- code = curl_global_init(flags);
- if (code == CURLE_OK) {
- Curl_cmalloc = m;
- Curl_cfree = f;
- Curl_cstrdup = s;
- Curl_crealloc = r;
- Curl_ccalloc = c;
- }
-
- return code;
-}
-
-/**
- * curl_global_cleanup() globally cleanups cURL, uses the value of
- * "init_flags" to determine what needs to be cleaned up and what doesn't.
- */
-void curl_global_cleanup(void)
-{
- if (!initialized)
- return;
-
- if (--initialized)
- return;
-
- Curl_global_host_cache_dtor();
-
- if (init_flags & CURL_GLOBAL_SSL)
- Curl_ssl_cleanup();
-
- if (init_flags & CURL_GLOBAL_WIN32)
- win32_cleanup();
-
-#ifdef _AMIGASF
- amiga_cleanup();
-#endif
-
- init_flags = 0;
-}
-
-/*
- * curl_easy_init() is the external interface to alloc, setup and init an
- * easy handle that is returned. If anything goes wrong, NULL is returned.
- */
-CURL *curl_easy_init(void)
-{
- CURLcode res;
- struct SessionHandle *data;
-
- /* Make sure we inited the global SSL stuff */
- if (!initialized) {
- res = curl_global_init(CURL_GLOBAL_DEFAULT);
- if(res)
- /* something in the global init failed, return nothing */
- return NULL;
- }
-
- /* We use curl_open() with undefined URL so far */
- res = Curl_open(&data);
- if(res != CURLE_OK)
- return NULL;
-
- return data;
-}
-
-/*
- * curl_easy_setopt() is the external interface for setting options on an
- * easy handle.
- */
-
-CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
-{
- va_list arg;
- struct SessionHandle *data = curl;
- CURLcode ret;
-
- if(!curl)
- return CURLE_BAD_FUNCTION_ARGUMENT;
-
- va_start(arg, tag);
-
- ret = Curl_setopt(data, tag, arg);
-
- va_end(arg);
- return ret;
-}
-
-#ifdef CURL_MULTIEASY
-/***************************************************************************
- * This function is still only for testing purposes. It makes a great way
- * to run the full test suite on the multi interface instead of the easy one.
- ***************************************************************************
- *
- * The *new* curl_easy_perform() is the external interface that performs a
- * transfer previously setup.
- *
- * Wrapper-function that: creates a multi handle, adds the easy handle to it,
- * runs curl_multi_perform() until the transfer is done, then detaches the
- * easy handle, destroys the multi handle and returns the easy handle's return
- * code. This will make everything internally use and assume multi interface.
- */
-CURLcode curl_easy_perform(CURL *easy)
-{
- CURLM *multi;
- CURLMcode mcode;
- CURLcode code = CURLE_OK;
- int still_running;
- struct timeval timeout;
- int rc;
- CURLMsg *msg;
- fd_set fdread;
- fd_set fdwrite;
- fd_set fdexcep;
- int maxfd;
-
- if(!easy)
- return CURLE_BAD_FUNCTION_ARGUMENT;
-
- multi = curl_multi_init();
- if(!multi)
- return CURLE_OUT_OF_MEMORY;
-
- mcode = curl_multi_add_handle(multi, easy);
- if(mcode) {
- curl_multi_cleanup(multi);
- return CURLE_FAILED_INIT;
- }
-
- /* we start some action by calling perform right away */
-
- do {
- while(CURLM_CALL_MULTI_PERFORM ==
- curl_multi_perform(multi, &still_running));
-
- if(!still_running)
- break;
-
- FD_ZERO(&fdread);
- FD_ZERO(&fdwrite);
- FD_ZERO(&fdexcep);
-
- /* timeout once per second */
- timeout.tv_sec = 1;
- timeout.tv_usec = 0;
-
- /* get file descriptors from the transfers */
- curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
-
- rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
-
- if(rc == -1)
- /* select error */
- break;
-
- /* timeout or data to send/receive => loop! */
- } while(still_running);
-
- msg = curl_multi_info_read(multi, &rc);
- if(msg)
- code = msg->data.result;
-
- mcode = curl_multi_remove_handle(multi, easy);
- /* what to do if it fails? */
-
- mcode = curl_multi_cleanup(multi);
- /* what to do if it fails? */
-
- return code;
-}
-#else
-/*
- * curl_easy_perform() is the external interface that performs a transfer
- * previously setup.
- */
-CURLcode curl_easy_perform(CURL *curl)
-{
- struct SessionHandle *data = (struct SessionHandle *)curl;
-
- if(!data)
- return CURLE_BAD_FUNCTION_ARGUMENT;
-
- if ( ! (data->share && data->share->hostcache) ) {
-
- if (Curl_global_host_cache_use(data) &&
- (data->dns.hostcachetype != HCACHE_GLOBAL)) {
- if (data->dns.hostcachetype == HCACHE_PRIVATE)
- Curl_hash_destroy(data->dns.hostcache);
- data->dns.hostcache = Curl_global_host_cache_get();
- data->dns.hostcachetype = HCACHE_GLOBAL;
- }
-
- if (!data->dns.hostcache) {
- data->dns.hostcachetype = HCACHE_PRIVATE;
- data->dns.hostcache = Curl_mk_dnscache();
-
- if(!data->dns.hostcache)
- /* While we possibly could survive and do good without a host cache,
- the fact that creating it failed indicates that things are truly
- screwed up and we should bail out! */
- return CURLE_OUT_OF_MEMORY;
- }
-
- }
-
- if(!data->state.connc) {
- /* oops, no connection cache, make one up */
- data->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE, -1);
- if(!data->state.connc)
- return CURLE_OUT_OF_MEMORY;
- }
-
- return Curl_perform(data);
-}
-#endif
-
-/*
- * curl_easy_cleanup() is the external interface to cleaning/freeing the given
- * easy handle.
- */
-void curl_easy_cleanup(CURL *curl)
-{
- struct SessionHandle *data = (struct SessionHandle *)curl;
-
- if(!data)
- return;
-
- Curl_close(data);
-}
-
-/*
- * Store a pointed to the multi handle within the easy handle's data struct.
- */
-void Curl_easy_addmulti(struct SessionHandle *data,
- void *multi)
-{
- data->multi = multi;
-}
-
-void Curl_easy_initHandleData(struct SessionHandle *data)
-{
- memset(&data->reqdata, 0, sizeof(struct HandleData));
-
- data->reqdata.maxdownload = -1;
-}
-
-/*
- * curl_easy_getinfo() is an external interface that allows an app to retrieve
- * information from a performed transfer and similar.
- */
-CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
-{
- va_list arg;
- void *paramp;
- struct SessionHandle *data = (struct SessionHandle *)curl;
-
- va_start(arg, info);
- paramp = va_arg(arg, void *);
-
- return Curl_getinfo(data, info, paramp);
-}
-
-/*
- * curl_easy_duphandle() is an external interface to allow duplication of a
- * given input easy handle. The returned handle will be a new working handle
- * with all options set exactly as the input source handle.
- */
-CURL *curl_easy_duphandle(CURL *incurl)
-{
- bool fail = TRUE;
- struct SessionHandle *data=(struct SessionHandle *)incurl;
-
- struct SessionHandle *outcurl = (struct SessionHandle *)
- calloc(sizeof(struct SessionHandle), 1);
-
- if(NULL == outcurl)
- return NULL; /* failure */
-
- do {
-
- /*
- * We setup a few buffers we need. We should probably make them
- * get setup on-demand in the code, as that would probably decrease
- * the likeliness of us forgetting to init a buffer here in the future.
- */
- outcurl->state.headerbuff=(char*)malloc(HEADERSIZE);
- if(!outcurl->state.headerbuff) {
- break;
- }
- outcurl->state.headersize=HEADERSIZE;
-
- /* copy all userdefined values */
- outcurl->set = data->set;
-
- if(data->state.used_interface == Curl_if_multi)
- outcurl->state.connc = data->state.connc;
- else
- outcurl->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE, -1);
-
- if(!outcurl->state.connc)
- break;
-
- outcurl->state.lastconnect = -1;
-
- outcurl->progress.flags = data->progress.flags;
- outcurl->progress.callback = data->progress.callback;
-
-#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
- if(data->cookies) {
- /* If cookies are enabled in the parent handle, we enable them
- in the clone as well! */
- outcurl->cookies = Curl_cookie_init(data,
- data->cookies->filename,
- outcurl->cookies,
- data->set.cookiesession);
- if(!outcurl->cookies) {
- break;
- }
- }
-#endif /* CURL_DISABLE_HTTP */
-
- /* duplicate all values in 'change' */
-
- if(data->change.url) {
- outcurl->change.url = strdup(data->change.url);
- if(!outcurl->change.url)
- break;
- outcurl->change.url_alloc = TRUE;
- }
-
- if(data->change.referer) {
- outcurl->change.referer = strdup(data->change.referer);
- if(!outcurl->change.referer)
- break;
- outcurl->change.referer_alloc = TRUE;
- }
-
-#ifdef USE_ARES
- /* If we use ares, we setup a new ares channel for the new handle */
- if(ARES_SUCCESS != ares_init(&outcurl->state.areschannel))
- break;
-#endif
-
-#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
- outcurl->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
- CURL_ICONV_CODESET_OF_NETWORK);
- outcurl->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
- CURL_ICONV_CODESET_OF_HOST);
- outcurl->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
- CURL_ICONV_CODESET_FOR_UTF8);
-#endif
-
- Curl_easy_initHandleData(outcurl);
-
- outcurl->magic = CURLEASY_MAGIC_NUMBER;
-
- fail = FALSE; /* we reach this point and thus we are OK */
-
- } while(0);
-
- if(fail) {
- if(outcurl) {
- if(outcurl->state.connc->type == CONNCACHE_PRIVATE)
- Curl_rm_connc(outcurl->state.connc);
- if(outcurl->state.headerbuff)
- free(outcurl->state.headerbuff);
- if(outcurl->change.url)
- free(outcurl->change.url);
- if(outcurl->change.referer)
- free(outcurl->change.referer);
- free(outcurl); /* free the memory again */
- outcurl = NULL;
- }
- }
-
- return outcurl;
-}
-
-/*
- * curl_easy_reset() is an external interface that allows an app to re-
- * initialize a session handle to the default values.
- */
-void curl_easy_reset(CURL *curl)
-{
- struct SessionHandle *data = (struct SessionHandle *)curl;
-
- Curl_safefree(data->reqdata.pathbuffer);
- data->reqdata.pathbuffer=NULL;
-
- Curl_safefree(data->reqdata.proto.generic);
- data->reqdata.proto.generic=NULL;
-
- /* zero out UserDefined data: */
- memset(&data->set, 0, sizeof(struct UserDefined));
-
- /* zero out Progress data: */
- memset(&data->progress, 0, sizeof(struct Progress));
-
- /* init Handle data */
- Curl_easy_initHandleData(data);
-
- /* The remainder of these calls have been taken from Curl_open() */
-
- data->set.out = stdout; /* default output to stdout */
- data->set.in = stdin; /* default input from stdin */
- data->set.err = stderr; /* default stderr to stderr */
-
- /* use fwrite as default function to store output */
- data->set.fwrite = (curl_write_callback)fwrite;
-
- /* use fread as default function to read input */
- data->set.fread = (curl_read_callback)fread;
-
- data->set.infilesize = -1; /* we don't know any size */
- data->set.postfieldsize = -1;
-
- data->state.current_speed = -1; /* init to negative == impossible */
-
- data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */
- data->set.ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */
- data->set.ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */
-
- data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
-
- /* make libcurl quiet by default: */
- data->set.hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */
- data->progress.flags |= PGRS_HIDE;
-
- /* Set the default size of the SSL session ID cache */
- data->set.ssl.numsessions = 5;
-
- data->set.proxyport = 1080;
- data->set.proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
- data->set.httpauth = CURLAUTH_BASIC; /* defaults to basic */
- data->set.proxyauth = CURLAUTH_BASIC; /* defaults to basic */
-
- /*
- * libcurl 7.10 introduced SSL verification *by default*! This needs to be
- * switched off unless wanted.
- */
- data->set.ssl.verifypeer = TRUE;
- data->set.ssl.verifyhost = 2;
-#ifdef CURL_CA_BUNDLE
- /* This is our preferred CA cert bundle since install time */
- data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE;
-#endif
-
- data->set.ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
- type */
-}
-
-#ifdef CURL_DOES_CONVERSIONS
-/*
- * Curl_convert_to_network() is an internal function
- * for performing ASCII conversions on non-ASCII platforms.
- */
-CURLcode Curl_convert_to_network(struct SessionHandle *data,
- char *buffer, size_t length)
-{
- CURLcode rc;
-
- if(data->set.convtonetwork) {
- /* use translation callback */
- rc = data->set.convtonetwork(buffer, length);
- if(rc != CURLE_OK) {
- failf(data,
- "CURLOPT_CONV_TO_NETWORK_FUNCTION callback returned %i: %s",
- rc, curl_easy_strerror(rc));
- }
- return(rc);
- } else {
-#ifdef HAVE_ICONV
- /* do the translation ourselves */
- char *input_ptr, *output_ptr;
- size_t in_bytes, out_bytes, rc;
-
- /* open an iconv conversion descriptor if necessary */
- if(data->outbound_cd == (iconv_t)-1) {
- data->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
- CURL_ICONV_CODESET_OF_HOST);
- if(data->outbound_cd == (iconv_t)-1) {
- failf(data,
- "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
- CURL_ICONV_CODESET_OF_NETWORK,
- CURL_ICONV_CODESET_OF_HOST,
- errno, strerror(errno));
- return CURLE_CONV_FAILED;
- }
- }
- /* call iconv */
- input_ptr = output_ptr = buffer;
- in_bytes = out_bytes = length;
- rc = iconv(data->outbound_cd, (const char**)&input_ptr, &in_bytes,
- &output_ptr, &out_bytes);
- if ((rc == ICONV_ERROR) || (in_bytes != 0)) {
- failf(data,
- "The Curl_convert_to_network iconv call failed with errno %i: %s",
- errno, strerror(errno));
- return CURLE_CONV_FAILED;
- }
-#else
- failf(data, "CURLOPT_CONV_TO_NETWORK_FUNCTION callback required");
- return CURLE_CONV_REQD;
-#endif /* HAVE_ICONV */
- }
-
- return CURLE_OK;
-}
-
-/*
- * Curl_convert_from_network() is an internal function
- * for performing ASCII conversions on non-ASCII platforms.
- */
-CURLcode Curl_convert_from_network(struct SessionHandle *data,
- char *buffer, size_t length)
-{
- CURLcode rc;
-
- if(data->set.convfromnetwork) {
- /* use translation callback */
- rc = data->set.convfromnetwork(buffer, length);
- if(rc != CURLE_OK) {
- failf(data,
- "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback returned %i: %s",
- rc, curl_easy_strerror(rc));
- }
- return(rc);
- } else {
-#ifdef HAVE_ICONV
- /* do the translation ourselves */
- char *input_ptr, *output_ptr;
- size_t in_bytes, out_bytes, rc;
-
- /* open an iconv conversion descriptor if necessary */
- if(data->inbound_cd == (iconv_t)-1) {
- data->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
- CURL_ICONV_CODESET_OF_NETWORK);
- if(data->inbound_cd == (iconv_t)-1) {
- failf(data,
- "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
- CURL_ICONV_CODESET_OF_HOST,
- CURL_ICONV_CODESET_OF_NETWORK,
- errno, strerror(errno));
- return CURLE_CONV_FAILED;
- }
- }
- /* call iconv */
- input_ptr = output_ptr = buffer;
- in_bytes = out_bytes = length;
- rc = iconv(data->inbound_cd, (const char **)&input_ptr, &in_bytes,
- &output_ptr, &out_bytes);
- if ((rc == ICONV_ERROR) || (in_bytes != 0)) {
- failf(data,
- "The Curl_convert_from_network iconv call failed with errno %i: %s",
- errno, strerror(errno));
- return CURLE_CONV_FAILED;
- }
-#else
- failf(data, "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback required");
- return CURLE_CONV_REQD;
-#endif /* HAVE_ICONV */
- }
-
- return CURLE_OK;
-}
-
-/*
- * Curl_convert_from_utf8() is an internal function
- * for performing UTF-8 conversions on non-ASCII platforms.
- */
-CURLcode Curl_convert_from_utf8(struct SessionHandle *data,
- char *buffer, size_t length)
-{
- CURLcode rc;
-
- if(data->set.convfromutf8) {
- /* use translation callback */
- rc = data->set.convfromutf8(buffer, length);
- if(rc != CURLE_OK) {
- failf(data,
- "CURLOPT_CONV_FROM_UTF8_FUNCTION callback returned %i: %s",
- rc, curl_easy_strerror(rc));
- }
- return(rc);
- } else {
-#ifdef HAVE_ICONV
- /* do the translation ourselves */
- char *input_ptr, *output_ptr;
- size_t in_bytes, out_bytes, rc;
-
- /* open an iconv conversion descriptor if necessary */
- if(data->utf8_cd == (iconv_t)-1) {
- data->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
- CURL_ICONV_CODESET_FOR_UTF8);
- if(data->utf8_cd == (iconv_t)-1) {
- failf(data,
- "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
- CURL_ICONV_CODESET_OF_HOST,
- CURL_ICONV_CODESET_FOR_UTF8,
- errno, strerror(errno));
- return CURLE_CONV_FAILED;
- }
- }
- /* call iconv */
- input_ptr = output_ptr = buffer;
- in_bytes = out_bytes = length;
- rc = iconv(data->utf8_cd, (const char**)&input_ptr, &in_bytes,
- &output_ptr, &out_bytes);
- if ((rc == ICONV_ERROR) || (in_bytes != 0)) {
- failf(data,
- "The Curl_convert_from_utf8 iconv call failed with errno %i: %s",
- errno, strerror(errno));
- return CURLE_CONV_FAILED;
- }
- if (output_ptr < input_ptr) {
- /* null terminate the now shorter output string */
- *output_ptr = 0x00;
- }
-#else
- failf(data, "CURLOPT_CONV_FROM_UTF8_FUNCTION callback required");
- return CURLE_CONV_REQD;
-#endif /* HAVE_ICONV */
- }
-
- return CURLE_OK;
-}
-
-#endif /* CURL_DOES_CONVERSIONS */
diff --git a/Utilities/cmcurl/easyif.h b/Utilities/cmcurl/easyif.h
deleted file mode 100644
index 4c0f7e795..000000000
--- a/Utilities/cmcurl/easyif.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef __EASYIF_H
-#define __EASYIF_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-/*
- * Prototypes for library-wide functions provided by easy.c
- */
-void Curl_easy_addmulti(struct SessionHandle *data, void *multi);
-
-void Curl_easy_initHandleData(struct SessionHandle *data);
-
-CURLcode Curl_convert_to_network(struct SessionHandle *data,
- char *buffer, size_t length);
-CURLcode Curl_convert_from_network(struct SessionHandle *data,
- char *buffer, size_t length);
-CURLcode Curl_convert_from_utf8(struct SessionHandle *data,
- char *buffer, size_t length);
-
-#endif /* __EASYIF_H */
diff --git a/Utilities/cmcurl/escape.c b/Utilities/cmcurl/escape.c
deleted file mode 100644
index 9552b0f31..000000000
--- a/Utilities/cmcurl/escape.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-/* Escape and unescape URL encoding in strings. The functions return a new
- * allocated string or NULL if an error occurred. */
-
-#include "setup.h"
-#include <ctype.h>
-#include <curl/curl.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "memory.h"
-/* urldata.h and easyif.h are included for Curl_convert_... prototypes */
-#include "urldata.h"
-#include "easyif.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
-#include "memdebug.h"
-
-/* for ABI-compatibility with previous versions */
-char *curl_escape(const char *string, int inlength)
-{
- return curl_easy_escape(NULL, string, inlength);
-}
-
-/* for ABI-compatibility with previous versions */
-char *curl_unescape(const char *string, int length)
-{
- return curl_easy_unescape(NULL, string, length, NULL);
-}
-
-char *curl_easy_escape(CURL *handle, const char *string, int inlength)
-{
- size_t alloc = (inlength?(size_t)inlength:strlen(string))+1;
- char *ns;
- char *testing_ptr = NULL;
- unsigned char in;
- size_t newlen = alloc;
- int strindex=0;
- size_t length;
-
-#ifndef CURL_DOES_CONVERSIONS
- /* avoid compiler warnings */
- (void)handle;
-#endif
- ns = malloc(alloc);
- if(!ns)
- return NULL;
-
- length = alloc-1;
- while(length--) {
- in = *string;
- if(!(in >= 'a' && in <= 'z') &&
- !(in >= 'A' && in <= 'Z') &&
- !(in >= '0' && in <= '9')) {
- /* encode it */
- newlen += 2; /* the size grows with two, since this'll become a %XX */
- if(newlen > alloc) {
- alloc *= 2;
- testing_ptr = realloc(ns, alloc);
- if(!testing_ptr) {
- free( ns );
- return NULL;
- }
- else {
- ns = testing_ptr;
- }
- }
-
-#ifdef CURL_DOES_CONVERSIONS
-/* escape sequences are always in ASCII so convert them on non-ASCII hosts */
- if (!handle ||
- (Curl_convert_to_network(handle, &in, 1) != CURLE_OK)) {
- /* Curl_convert_to_network calls failf if unsuccessful */
- free(ns);
- return NULL;
- }
-#endif /* CURL_DOES_CONVERSIONS */
-
- snprintf(&ns[strindex], 4, "%%%02X", in);
-
- strindex+=3;
- }
- else {
- /* just copy this */
- ns[strindex++]=in;
- }
- string++;
- }
- ns[strindex]=0; /* terminate it */
- return ns;
-}
-
-char *curl_easy_unescape(CURL *handle, const char *string, int length,
- int *olen)
-{
- int alloc = (length?length:(int)strlen(string))+1;
- char *ns = malloc(alloc);
- unsigned char in;
- int strindex=0;
- long hex;
-
-#ifndef CURL_DOES_CONVERSIONS
- /* avoid compiler warnings */
- (void)handle;
-#endif
- if( !ns )
- return NULL;
-
- while(--alloc > 0) {
- in = *string;
- if(('%' == in) && ISXDIGIT(string[1]) && ISXDIGIT(string[2])) {
- /* this is two hexadecimal digits following a '%' */
- char hexstr[3];
- char *ptr;
- hexstr[0] = string[1];
- hexstr[1] = string[2];
- hexstr[2] = 0;
-
- hex = strtol(hexstr, &ptr, 16);
-
- in = (unsigned char)hex; /* this long is never bigger than 255 anyway */
-
-#ifdef CURL_DOES_CONVERSIONS
-/* escape sequences are always in ASCII so convert them on non-ASCII hosts */
- if (!handle ||
- (Curl_convert_from_network(handle, &in, 1) != CURLE_OK)) {
- /* Curl_convert_from_network calls failf if unsuccessful */
- free(ns);
- return NULL;
- }
-#endif /* CURL_DOES_CONVERSIONS */
-
- string+=2;
- alloc-=2;
- }
-
- ns[strindex++] = in;
- string++;
- }
- ns[strindex]=0; /* terminate it */
-
- if(olen)
- /* store output size */
- *olen = strindex;
- return ns;
-}
-
-/* For operating systems/environments that use different malloc/free
- ssystems for the app and for this library, we provide a free that uses
- the library's memory system */
-void curl_free(void *p)
-{
- if(p)
- free(p);
-}
diff --git a/Utilities/cmcurl/escape.h b/Utilities/cmcurl/escape.h
deleted file mode 100644
index a0a0209c4..000000000
--- a/Utilities/cmcurl/escape.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef __ESCAPE_H
-#define __ESCAPE_H
-
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-/* Escape and unescape URL encoding in strings. The functions return a new
- * allocated string or NULL if an error occurred. */
-
-
-#endif
diff --git a/Utilities/cmcurl/file.c b/Utilities/cmcurl/file.c
deleted file mode 100644
index b247a7736..000000000
--- a/Utilities/cmcurl/file.c
+++ /dev/null
@@ -1,407 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#ifndef CURL_DISABLE_FILE
-/* -- WIN32 approved -- */
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <ctype.h>
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-
-#ifdef WIN32
-#include <time.h>
-#include <io.h>
-#include <fcntl.h>
-#else
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_NET_IF_H
-#include <net/if.h>
-#endif
-#include <sys/ioctl.h>
-#include <signal.h>
-
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-#endif
-
-#include "urldata.h"
-#include <curl/curl.h>
-#include "progress.h"
-#include "sendf.h"
-#include "escape.h"
-#include "file.h"
-#include "speedcheck.h"
-#include "getinfo.h"
-#include "transfer.h"
-#include "url.h"
-#include "memory.h"
-#include "parsedate.h" /* for the week day and month names */
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
-#include "memdebug.h"
-
-/*
- * Curl_file_connect() gets called from Curl_protocol_connect() to allow us to
- * do protocol-specific actions at connect-time. We emulate a
- * connect-then-transfer protocol and "connect" to the file here
- */
-CURLcode Curl_file_connect(struct connectdata *conn)
-{
- char *real_path = curl_easy_unescape(conn->data, conn->data->reqdata.path, 0, NULL);
- struct FILEPROTO *file;
- int fd;
-#if defined(WIN32) || defined(MSDOS) || defined(__EMX__)
- int i;
- char *actual_path;
-#endif
-
- if(!real_path)
- return CURLE_OUT_OF_MEMORY;
-
- file = (struct FILEPROTO *)calloc(sizeof(struct FILEPROTO), 1);
- if(!file) {
- free(real_path);
- return CURLE_OUT_OF_MEMORY;
- }
-
- if (conn->data->reqdata.proto.file) {
- free(conn->data->reqdata.proto.file);
- }
-
- conn->data->reqdata.proto.file = file;
-
-#if defined(WIN32) || defined(MSDOS) || defined(__EMX__)
- /* If the first character is a slash, and there's
- something that looks like a drive at the beginning of
- the path, skip the slash. If we remove the initial
- slash in all cases, paths without drive letters end up
- relative to the current directory which isn't how
- browsers work.
-
- Some browsers accept | instead of : as the drive letter
- separator, so we do too.
-
- On other platforms, we need the slash to indicate an
- absolute pathname. On Windows, absolute paths start
- with a drive letter.
- */
- actual_path = real_path;
- if ((actual_path[0] == '/') &&
- actual_path[1] &&
- (actual_path[2] == ':' || actual_path[2] == '|'))
- {
- actual_path[2] = ':';
- actual_path++;
- }
-
- /* change path separators from '/' to '\\' for DOS, Windows and OS/2 */
- for (i=0; actual_path[i] != '\0'; ++i)
- if (actual_path[i] == '/')
- actual_path[i] = '\\';
-
- fd = open(actual_path, O_RDONLY | O_BINARY); /* no CR/LF translation! */
- file->path = actual_path;
-#else
- fd = open(real_path, O_RDONLY);
- file->path = real_path;
-#endif
- file->freepath = real_path; /* free this when done */
-
- file->fd = fd;
- if(!conn->data->set.upload && (fd == -1)) {
- failf(conn->data, "Couldn't open file %s", conn->data->reqdata.path);
- Curl_file_done(conn, CURLE_FILE_COULDNT_READ_FILE, FALSE);
- return CURLE_FILE_COULDNT_READ_FILE;
- }
-
- return CURLE_OK;
-}
-
-CURLcode Curl_file_done(struct connectdata *conn,
- CURLcode status, bool premature)
-{
- struct FILEPROTO *file = conn->data->reqdata.proto.file;
- (void)status; /* not used */
- (void)premature; /* not used */
- Curl_safefree(file->freepath);
-
- if(file->fd != -1)
- close(file->fd);
-
- return CURLE_OK;
-}
-
-#if defined(WIN32) || defined(MSDOS) || defined(__EMX__)
-#define DIRSEP '\\'
-#else
-#define DIRSEP '/'
-#endif
-
-static CURLcode file_upload(struct connectdata *conn)
-{
- struct FILEPROTO *file = conn->data->reqdata.proto.file;
- char *dir = strchr(file->path, DIRSEP);
- FILE *fp;
- CURLcode res=CURLE_OK;
- struct SessionHandle *data = conn->data;
- char *buf = data->state.buffer;
- size_t nread;
- size_t nwrite;
- curl_off_t bytecount = 0;
- struct timeval now = Curl_tvnow();
-
- /*
- * Since FILE: doesn't do the full init, we need to provide some extra
- * assignments here.
- */
- conn->fread = data->set.fread;
- conn->fread_in = data->set.in;
- conn->data->reqdata.upload_fromhere = buf;
-
- if(!dir)
- return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
-
- if(!dir[1])
- return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
-
- fp = fopen(file->path, "wb");
- if(!fp) {
- failf(data, "Can't open %s for writing", file->path);
- return CURLE_WRITE_ERROR;
- }
-
- if(-1 != data->set.infilesize)
- /* known size of data to "upload" */
- Curl_pgrsSetUploadSize(data, data->set.infilesize);
-
- while (res == CURLE_OK) {
- int readcount;
- res = Curl_fillreadbuffer(conn, BUFSIZE, &readcount);
- if(res)
- break;
-
- if (readcount <= 0) /* fix questionable compare error. curlvms */
- break;
-
- nread = (size_t)readcount;
-
- /* write the data to the target */
- nwrite = fwrite(buf, 1, nread, fp);
- if(nwrite != nread) {
- res = CURLE_SEND_ERROR;
- break;
- }
-
- bytecount += nread;
-
- Curl_pgrsSetUploadCounter(data, bytecount);
-
- if(Curl_pgrsUpdate(conn))
- res = CURLE_ABORTED_BY_CALLBACK;
- else
- res = Curl_speedcheck(data, now);
- }
- if(!res && Curl_pgrsUpdate(conn))
- res = CURLE_ABORTED_BY_CALLBACK;
-
- fclose(fp);
-
- return res;
-}
-
-/*
- * Curl_file() is the protocol-specific function for the do-phase, separated
- * from the connect-phase above. Other protocols merely setup the transfer in
- * the do-phase, to have it done in the main transfer loop but since some
- * platforms we support don't allow select()ing etc on file handles (as
- * opposed to sockets) we instead perform the whole do-operation in this
- * function.
- */
-CURLcode Curl_file(struct connectdata *conn, bool *done)
-{
- /* This implementation ignores the host name in conformance with
- RFC 1738. Only local files (reachable via the standard file system)
- are supported. This means that files on remotely mounted directories
- (via NFS, Samba, NT sharing) can be accessed through a file:// URL
- */
- CURLcode res = CURLE_OK;
- struct_stat statbuf; /* struct_stat instead of struct stat just to allow the
- Windows version to have a different struct without
- having to redefine the simple word 'stat' */
- curl_off_t expected_size=0;
- bool fstated=FALSE;
- ssize_t nread;
- struct SessionHandle *data = conn->data;
- char *buf = data->state.buffer;
- curl_off_t bytecount = 0;
- int fd;
- struct timeval now = Curl_tvnow();
-
- *done = TRUE; /* unconditionally */
-
- Curl_readwrite_init(conn);
- Curl_initinfo(data);
- Curl_pgrsStartNow(data);
-
- if(data->set.upload)
- return file_upload(conn);
-
- /* get the fd from the connection phase */
- fd = conn->data->reqdata.proto.file->fd;
-
- /* VMS: This only works reliable for STREAMLF files */
- if( -1 != fstat(fd, &statbuf)) {
- /* we could stat it, then read out the size */
- expected_size = statbuf.st_size;
- fstated = TRUE;
- }
-
- /* If we have selected NOBODY and HEADER, it means that we only want file
- information. Which for FILE can't be much more than the file size and
- date. */
- if(conn->bits.no_body && data->set.include_header && fstated) {
- CURLcode result;
- snprintf(buf, sizeof(data->state.buffer),
- "Content-Length: %" FORMAT_OFF_T "\r\n", expected_size);
- result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
- if(result)
- return result;
-
- result = Curl_client_write(conn, CLIENTWRITE_BOTH,
- (char *)"Accept-ranges: bytes\r\n", 0);
- if(result)
- return result;
-
- if(fstated) {
- struct tm *tm;
- time_t clock = (time_t)statbuf.st_mtime;
-#ifdef HAVE_GMTIME_R
- struct tm buffer;
- tm = (struct tm *)gmtime_r(&clock, &buffer);
-#else
- tm = gmtime(&clock);
-#endif
- /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
- snprintf(buf, BUFSIZE-1,
- "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
- Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
- tm->tm_mday,
- Curl_month[tm->tm_mon],
- tm->tm_year + 1900,
- tm->tm_hour,
- tm->tm_min,
- tm->tm_sec);
- result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
- }
- return result;
- }
-
- if (data->reqdata.resume_from <= expected_size)
- expected_size -= data->reqdata.resume_from;
- else {
- failf(data, "failed to resume file:// transfer");
- return CURLE_BAD_DOWNLOAD_RESUME;
- }
-
- if (fstated && (expected_size == 0))
- return CURLE_OK;
-
- /* The following is a shortcut implementation of file reading
- this is both more efficient than the former call to download() and
- it avoids problems with select() and recv() on file descriptors
- in Winsock */
- if(fstated)
- Curl_pgrsSetDownloadSize(data, expected_size);
-
- if(data->reqdata.resume_from) {
- if(data->reqdata.resume_from !=
- lseek(fd, data->reqdata.resume_from, SEEK_SET))
- return CURLE_BAD_DOWNLOAD_RESUME;
- }
-
- Curl_pgrsTime(data, TIMER_STARTTRANSFER);
-
- while (res == CURLE_OK) {
- nread = read(fd, buf, BUFSIZE-1);
-
- if ( nread > 0)
- buf[nread] = 0;
-
- if (nread <= 0)
- break;
-
- bytecount += nread;
-
- res = Curl_client_write(conn, CLIENTWRITE_BODY, buf, nread);
- if(res)
- return res;
-
- Curl_pgrsSetDownloadCounter(data, bytecount);
-
- if(Curl_pgrsUpdate(conn))
- res = CURLE_ABORTED_BY_CALLBACK;
- else
- res = Curl_speedcheck(data, now);
- }
- if(Curl_pgrsUpdate(conn))
- res = CURLE_ABORTED_BY_CALLBACK;
-
- return res;
-}
-
-#endif
diff --git a/Utilities/cmcurl/file.h b/Utilities/cmcurl/file.h
deleted file mode 100644
index 20a1c4c06..000000000
--- a/Utilities/cmcurl/file.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef __FILE_H
-#define __FILE_H
-
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-#ifndef CURL_DISABLE_FILE
-CURLcode Curl_file(struct connectdata *, bool *done);
-CURLcode Curl_file_done(struct connectdata *, CURLcode, bool premature);
-CURLcode Curl_file_connect(struct connectdata *);
-#endif
-#endif
diff --git a/Utilities/cmcurl/formdata.c b/Utilities/cmcurl/formdata.c
deleted file mode 100644
index f10c6c70e..000000000
--- a/Utilities/cmcurl/formdata.c
+++ /dev/null
@@ -1,1694 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-/*
- Debug the form generator stand-alone by compiling this source file with:
-
- gcc -DHAVE_CONFIG_H -I../ -g -D_FORM_DEBUG -DCURLDEBUG -o formdata -I../include formdata.c strequal.c memdebug.c mprintf.c strerror.c
-
- run the 'formdata' executable the output should end with:
- All Tests seem to have worked ...
- and the following parts should be there:
-
-Content-Disposition: form-data; name="simple_COPYCONTENTS"
-value for simple COPYCONTENTS
-
-Content-Disposition: form-data; name="COPYCONTENTS_+_CONTENTTYPE"
-Content-Type: image/gif
-value for COPYCONTENTS + CONTENTTYPE
-
-Content-Disposition: form-data; name="PRNAME_+_NAMELENGTH_+_COPYNAME_+_CONTENTSLENGTH"
-vlue for PTRNAME + NAMELENGTH + COPYNAME + CONTENTSLENGTH
-(or you might see P^@RNAME and v^@lue at the start)
-
-Content-Disposition: form-data; name="simple_PTRCONTENTS"
-value for simple PTRCONTENTS
-
-Content-Disposition: form-data; name="PTRCONTENTS_+_CONTENTSLENGTH"
-vlue for PTRCONTENTS + CONTENTSLENGTH
-(or you might see v^@lue at the start)
-
-Content-Disposition: form-data; name="PTRCONTENTS_+_CONTENTSLENGTH_+_CONTENTTYPE"
-Content-Type: text/plain
-vlue for PTRCOTNENTS + CONTENTSLENGTH + CONTENTTYPE
-(or you might see v^@lue at the start)
-
-Content-Disposition: form-data; name="FILE1_+_CONTENTTYPE"; filename="inet_ntoa_r.h"
-Content-Type: text/html
-...
-
-Content-Disposition: form-data; name="FILE1_+_FILE2"
-Content-Type: multipart/mixed, boundary=curlz1s0dkticx49MV1KGcYP5cvfSsz
-...
-Content-Disposition: attachment; filename="inet_ntoa_r.h"
-Content-Type: text/plain
-...
-Content-Disposition: attachment; filename="Makefile.b32"
-Content-Type: text/plain
-...
-
-Content-Disposition: form-data; name="FILE1_+_FILE2_+_FILE3"
-Content-Type: multipart/mixed, boundary=curlirkYPmPwu6FrJ1vJ1u1BmtIufh1
-...
-Content-Disposition: attachment; filename="inet_ntoa_r.h"
-Content-Type: text/plain
-...
-Content-Disposition: attachment; filename="Makefile.b32"
-Content-Type: text/plain
-...
-Content-Disposition: attachment; filename="inet_ntoa_r.h"
-Content-Type: text/plain
-...
-
-
-Content-Disposition: form-data; name="ARRAY: FILE1_+_FILE2_+_FILE3"
-Content-Type: multipart/mixed, boundary=curlirkYPmPwu6FrJ1vJ1u1BmtIufh1
-...
-Content-Disposition: attachment; filename="inet_ntoa_r.h"
-Content-Type: text/plain
-...
-Content-Disposition: attachment; filename="Makefile.b32"
-Content-Type: text/plain
-...
-Content-Disposition: attachment; filename="inet_ntoa_r.h"
-Content-Type: text/plain
-...
-
-Content-Disposition: form-data; name="FILECONTENT"
-...
-
- */
-
-#include "setup.h"
-#include <curl/curl.h>
-
-/* Length of the random boundary string. */
-#define BOUNDARY_LENGTH 40
-
-#if !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY)
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <time.h>
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
-#include <libgen.h>
-#endif
-#include "urldata.h" /* for struct SessionHandle */
-#include "easyif.h" /* for Curl_convert_... prototypes */
-#include "formdata.h"
-#include "strequal.h"
-#include "memory.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
-#include "memdebug.h"
-
-#endif /* !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY) */
-
-#ifndef CURL_DISABLE_HTTP
-
-#if defined(HAVE_BASENAME) && defined(NEED_BASENAME_PROTO)
-/* This system has a basename() but no prototype for it! */
-char *basename(char *path);
-#endif
-
-static size_t readfromfile(struct Form *form, char *buffer, size_t size);
-
-/* What kind of Content-Type to use on un-specified files with unrecognized
- extensions. */
-#define HTTPPOST_CONTENTTYPE_DEFAULT "application/octet-stream"
-
-#define FORM_FILE_SEPARATOR ','
-#define FORM_TYPE_SEPARATOR ';'
-
-/***************************************************************************
- *
- * AddHttpPost()
- *
- * Adds a HttpPost structure to the list, if parent_post is given becomes
- * a subpost of parent_post instead of a direct list element.
- *
- * Returns newly allocated HttpPost on success and NULL if malloc failed.
- *
- ***************************************************************************/
-static struct curl_httppost *
-AddHttpPost(char * name, size_t namelength,
- char * value, size_t contentslength,
- char * buffer, size_t bufferlength,
- char *contenttype,
- long flags,
- struct curl_slist* contentHeader,
- char *showfilename,
- struct curl_httppost *parent_post,
- struct curl_httppost **httppost,
- struct curl_httppost **last_post)
-{
- struct curl_httppost *post;
- post = (struct curl_httppost *)calloc(sizeof(struct curl_httppost), 1);
- if(post) {
- post->name = name;
- post->namelength = (long)(name?(namelength?namelength:strlen(name)):0);
- post->contents = value;
- post->contentslength = (long)contentslength;
- post->buffer = buffer;
- post->bufferlength = (long)bufferlength;
- post->contenttype = contenttype;
- post->contentheader = contentHeader;
- post->showfilename = showfilename;
- post->flags = flags;
- }
- else
- return NULL;
-
- if (parent_post) {
- /* now, point our 'more' to the original 'more' */
- post->more = parent_post->more;
-
- /* then move the original 'more' to point to ourselves */
- parent_post->more = post;
- }
- else {
- /* make the previous point to this */
- if(*last_post)
- (*last_post)->next = post;
- else
- (*httppost) = post;
-
- (*last_post) = post;
- }
- return post;
-}
-
-/***************************************************************************
- *
- * AddFormInfo()
- *
- * Adds a FormInfo structure to the list presented by parent_form_info.
- *
- * Returns newly allocated FormInfo on success and NULL if malloc failed/
- * parent_form_info is NULL.
- *
- ***************************************************************************/
-static FormInfo * AddFormInfo(char *value,
- char *contenttype,
- FormInfo *parent_form_info)
-{
- FormInfo *form_info;
- form_info = (FormInfo *)malloc(sizeof(FormInfo));
- if(form_info) {
- memset(form_info, 0, sizeof(FormInfo));
- if (value)
- form_info->value = value;
- if (contenttype)
- form_info->contenttype = contenttype;
- form_info->flags = HTTPPOST_FILENAME;
- }
- else
- return NULL;
-
- if (parent_form_info) {
- /* now, point our 'more' to the original 'more' */
- form_info->more = parent_form_info->more;
-
- /* then move the original 'more' to point to ourselves */
- parent_form_info->more = form_info;
- }
- else
- return NULL;
-
- return form_info;
-}
-
-/***************************************************************************
- *
- * ContentTypeForFilename()
- *
- * Provides content type for filename if one of the known types (else
- * (either the prevtype or the default is returned).
- *
- * Returns some valid contenttype for filename.
- *
- ***************************************************************************/
-static const char * ContentTypeForFilename (const char *filename,
- const char *prevtype)
-{
- const char *contenttype = NULL;
- unsigned int i;
- /*
- * No type was specified, we scan through a few well-known
- * extensions and pick the first we match!
- */
- struct ContentType {
- const char *extension;
- const char *type;
- };
- static const struct ContentType ctts[]={
- {".gif", "image/gif"},
- {".jpg", "image/jpeg"},
- {".jpeg", "image/jpeg"},
- {".txt", "text/plain"},
- {".html", "text/html"}
- };
-
- if(prevtype)
- /* default to the previously set/used! */
- contenttype = prevtype;
- else
- /* It seems RFC1867 defines no Content-Type to default to
- text/plain so we don't actually need to set this: */
- contenttype = HTTPPOST_CONTENTTYPE_DEFAULT;
-
- for(i=0; i<sizeof(ctts)/sizeof(ctts[0]); i++) {
- if(strlen(filename) >= strlen(ctts[i].extension)) {
- if(strequal(filename +
- strlen(filename) - strlen(ctts[i].extension),
- ctts[i].extension)) {
- contenttype = ctts[i].type;
- break;
- }
- }
- }
- /* we have a contenttype by now */
- return contenttype;
-}
-
-/***************************************************************************
- *
- * memdup()
- *
- * Copies the 'source' data to a newly allocated buffer buffer (that is
- * returned). Uses buffer_length if not null, else uses strlen to determine
- * the length of the buffer to be copied
- *
- * Returns the new pointer or NULL on failure.
- *
- ***************************************************************************/
-static char *memdup(const char *src, size_t buffer_length)
-{
- size_t length;
- bool add = FALSE;
- char *buffer;
-
- if (buffer_length)
- length = buffer_length;
- else {
- length = strlen(src);
- add = TRUE;
- }
- buffer = (char*)malloc(length+add);
- if (!buffer)
- return NULL; /* fail */
-
- memcpy(buffer, src, length);
-
- /* if length unknown do null termination */
- if (add)
- buffer[length] = '\0';
-
- return buffer;
-}
-
-/***************************************************************************
- *
- * FormAdd()
- *
- * Stores a formpost parameter and builds the appropriate linked list.
- *
- * Has two principal functionalities: using files and byte arrays as
- * post parts. Byte arrays are either copied or just the pointer is stored
- * (as the user requests) while for files only the filename and not the
- * content is stored.
- *
- * While you may have only one byte array for each name, multiple filenames
- * are allowed (and because of this feature CURLFORM_END is needed after
- * using CURLFORM_FILE).
- *
- * Examples:
- *
- * Simple name/value pair with copied contents:
- * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
- * CURLFORM_COPYCONTENTS, "value", CURLFORM_END);
- *
- * name/value pair where only the content pointer is remembered:
- * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
- * CURLFORM_PTRCONTENTS, ptr, CURLFORM_CONTENTSLENGTH, 10, CURLFORM_END);
- * (if CURLFORM_CONTENTSLENGTH is missing strlen () is used)
- *
- * storing a filename (CONTENTTYPE is optional!):
- * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
- * CURLFORM_FILE, "filename1", CURLFORM_CONTENTTYPE, "plain/text",
- * CURLFORM_END);
- *
- * storing multiple filenames:
- * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
- * CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", CURLFORM_END);
- *
- * Returns:
- * CURL_FORMADD_OK on success
- * CURL_FORMADD_MEMORY if the FormInfo allocation fails
- * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form
- * CURL_FORMADD_NULL if a null pointer was given for a char
- * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed
- * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
- * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or an error)
- * CURL_FORMADD_MEMORY if a HttpPost struct cannot be allocated
- * CURL_FORMADD_MEMORY if some allocation for string copying failed.
- * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array
- *
- ***************************************************************************/
-
-static
-CURLFORMcode FormAdd(struct curl_httppost **httppost,
- struct curl_httppost **last_post,
- va_list params)
-{
- FormInfo *first_form, *current_form, *form = NULL;
- CURLFORMcode return_value = CURL_FORMADD_OK;
- const char *prevtype = NULL;
- struct curl_httppost *post = NULL;
- CURLformoption option;
- struct curl_forms *forms = NULL;
- char *array_value=NULL; /* value read from an array */
-
- /* This is a state variable, that if TRUE means that we're parsing an
- array that we got passed to us. If FALSE we're parsing the input
- va_list arguments. */
- bool array_state = FALSE;
-
- /*
- * We need to allocate the first struct to fill in.
- */
- first_form = (FormInfo *)calloc(sizeof(struct FormInfo), 1);
- if(!first_form)
- return CURL_FORMADD_MEMORY;
-
- current_form = first_form;
-
- /*
- * Loop through all the options set. Break if we have an error to report.
- */
- while (return_value == CURL_FORMADD_OK) {
-
- /* first see if we have more parts of the array param */
- if ( array_state ) {
- /* get the upcoming option from the given array */
- option = forms->option;
- array_value = (char *)forms->value;
-
- forms++; /* advance this to next entry */
- if (CURLFORM_END == option) {
- /* end of array state */
- array_state = FALSE;
- continue;
- }
- }
- else {
- /* This is not array-state, get next option */
- option = va_arg(params, CURLformoption);
- if (CURLFORM_END == option)
- break;
- }
-
- switch (option) {
- case CURLFORM_ARRAY:
- if(array_state)
- /* we don't support an array from within an array */
- return_value = CURL_FORMADD_ILLEGAL_ARRAY;
- else {
- forms = va_arg(params, struct curl_forms *);
- if (forms)
- array_state = TRUE;
- else
- return_value = CURL_FORMADD_NULL;
- }
- break;
-
- /*
- * Set the Name property.
- */
- case CURLFORM_PTRNAME:
-#ifdef CURL_DOES_CONVERSIONS
- /* treat CURLFORM_PTR like CURLFORM_COPYNAME so we'll
- have safe memory for the eventual conversion */
-#else
- current_form->flags |= HTTPPOST_PTRNAME; /* fall through */
-#endif
- case CURLFORM_COPYNAME:
- if (current_form->name)
- return_value = CURL_FORMADD_OPTION_TWICE;
- else {
- char *name = array_state?
- array_value:va_arg(params, char *);
- if (name)
- current_form->name = name; /* store for the moment */
- else
- return_value = CURL_FORMADD_NULL;
- }
- break;
- case CURLFORM_NAMELENGTH:
- if (current_form->namelength)
- return_value = CURL_FORMADD_OPTION_TWICE;
- else
- current_form->namelength =
- array_state?(long)array_value:(long)va_arg(params, long);
- break;
-
- /*
- * Set the contents property.
- */
- case CURLFORM_PTRCONTENTS:
- current_form->flags |= HTTPPOST_PTRCONTENTS; /* fall through */
- case CURLFORM_COPYCONTENTS:
- if (current_form->value)
- return_value = CURL_FORMADD_OPTION_TWICE;
- else {
- char *value =
- array_state?array_value:va_arg(params, char *);
- if (value)
- current_form->value = value; /* store for the moment */
- else
- return_value = CURL_FORMADD_NULL;
- }
- break;
- case CURLFORM_CONTENTSLENGTH:
- if (current_form->contentslength)
- return_value = CURL_FORMADD_OPTION_TWICE;
- else
- current_form->contentslength =
- array_state?(long)array_value:va_arg(params, long);
- break;
-
- /* Get contents from a given file name */
- case CURLFORM_FILECONTENT:
- if (current_form->flags != 0)
- return_value = CURL_FORMADD_OPTION_TWICE;
- else {
- char *filename = array_state?
- array_value:va_arg(params, char *);
- if (filename) {
- current_form->value = strdup(filename);
- if(!current_form->value)
- return_value = CURL_FORMADD_MEMORY;
- else {
- current_form->flags |= HTTPPOST_READFILE;
- current_form->value_alloc = TRUE;
- }
- }
- else
- return_value = CURL_FORMADD_NULL;
- }
- break;
-
- /* We upload a file */
- case CURLFORM_FILE:
- {
- char *filename = array_state?array_value:
- va_arg(params, char *);
-
- if (current_form->value) {
- if (current_form->flags & HTTPPOST_FILENAME) {
- if (filename) {
- if ((current_form = AddFormInfo(strdup(filename),
- NULL, current_form)) == NULL)
- return_value = CURL_FORMADD_MEMORY;
- }
- else
- return_value = CURL_FORMADD_NULL;
- }
- else
- return_value = CURL_FORMADD_OPTION_TWICE;
- }
- else {
- if (filename) {
- current_form->value = strdup(filename);
- if(!current_form->value)
- return_value = CURL_FORMADD_MEMORY;
- else {
- current_form->flags |= HTTPPOST_FILENAME;
- current_form->value_alloc = TRUE;
- }
- }
- else
- return_value = CURL_FORMADD_NULL;
- }
- break;
- }
-
- case CURLFORM_BUFFER:
- {
- char *filename = array_state?array_value:
- va_arg(params, char *);
-
- if (current_form->value) {
- if (current_form->flags & HTTPPOST_BUFFER) {
- if (filename) {
- if ((current_form = AddFormInfo(strdup(filename),
- NULL, current_form)) == NULL)
- return_value = CURL_FORMADD_MEMORY;
- }
- else
- return_value = CURL_FORMADD_NULL;
- }
- else
- return_value = CURL_FORMADD_OPTION_TWICE;
- }
- else {
- if (filename) {
- current_form->value = strdup(filename);
- if(!current_form->value)
- return_value = CURL_FORMADD_MEMORY;
- }
- else
- return_value = CURL_FORMADD_NULL;
- current_form->flags |= HTTPPOST_BUFFER;
- }
- break;
- }
-
- case CURLFORM_BUFFERPTR:
- current_form->flags |= HTTPPOST_PTRBUFFER;
- if (current_form->buffer)
- return_value = CURL_FORMADD_OPTION_TWICE;
- else {
- char *buffer =
- array_state?array_value:va_arg(params, char *);
- if (buffer)
- current_form->buffer = buffer; /* store for the moment */
- else
- return_value = CURL_FORMADD_NULL;
- }
- break;
-
- case CURLFORM_BUFFERLENGTH:
- if (current_form->bufferlength)
- return_value = CURL_FORMADD_OPTION_TWICE;
- else
- current_form->bufferlength =
- array_state?(long)array_value:va_arg(params, long);
- break;
-
- case CURLFORM_CONTENTTYPE:
- {
- char *contenttype =
- array_state?array_value:va_arg(params, char *);
- if (current_form->contenttype) {
- if (current_form->flags & HTTPPOST_FILENAME) {
- if (contenttype) {
- if ((current_form = AddFormInfo(NULL,
- strdup(contenttype),
- current_form)) == NULL)
- return_value = CURL_FORMADD_MEMORY;
- }
- else
- return_value = CURL_FORMADD_NULL;
- }
- else
- return_value = CURL_FORMADD_OPTION_TWICE;
- }
- else {
- if (contenttype) {
- current_form->contenttype = strdup(contenttype);
- if(!current_form->contenttype)
- return_value = CURL_FORMADD_MEMORY;
- else
- current_form->contenttype_alloc = TRUE;
- }
- else
- return_value = CURL_FORMADD_NULL;
- }
- break;
- }
- case CURLFORM_CONTENTHEADER:
- {
- /* this "cast increases required alignment of target type" but
- we consider it OK anyway */
- struct curl_slist* list = array_state?
- (struct curl_slist*)array_value:
- va_arg(params, struct curl_slist*);
-
- if( current_form->contentheader )
- return_value = CURL_FORMADD_OPTION_TWICE;
- else
- current_form->contentheader = list;
-
- break;
- }
- case CURLFORM_FILENAME:
- {
- char *filename = array_state?array_value:
- va_arg(params, char *);
- if( current_form->showfilename )
- return_value = CURL_FORMADD_OPTION_TWICE;
- else {
- current_form->showfilename = strdup(filename);
- if(!current_form->showfilename)
- return_value = CURL_FORMADD_MEMORY;
- else
- current_form->showfilename_alloc = TRUE;
- }
- break;
- }
- default:
- return_value = CURL_FORMADD_UNKNOWN_OPTION;
- }
- }
-
- if(CURL_FORMADD_OK == return_value) {
- /* go through the list, check for copleteness and if everything is
- * alright add the HttpPost item otherwise set return_value accordingly */
-
- post = NULL;
- for(form = first_form;
- form != NULL;
- form = form->more) {
- if ( ((!form->name || !form->value) && !post) ||
- ( (form->contentslength) &&
- (form->flags & HTTPPOST_FILENAME) ) ||
- ( (form->flags & HTTPPOST_FILENAME) &&
- (form->flags & HTTPPOST_PTRCONTENTS) ) ||
-
- ( (!form->buffer) &&
- (form->flags & HTTPPOST_BUFFER) &&
- (form->flags & HTTPPOST_PTRBUFFER) ) ||
-
- ( (form->flags & HTTPPOST_READFILE) &&
- (form->flags & HTTPPOST_PTRCONTENTS) )
- ) {
- return_value = CURL_FORMADD_INCOMPLETE;
- break;
- }
- else {
- if ( ((form->flags & HTTPPOST_FILENAME) ||
- (form->flags & HTTPPOST_BUFFER)) &&
- !form->contenttype ) {
- /* our contenttype is missing */
- form->contenttype
- = strdup(ContentTypeForFilename(form->value, prevtype));
- if(!form->contenttype) {
- return_value = CURL_FORMADD_MEMORY;
- break;
- }
- form->contenttype_alloc = TRUE;
- }
- if ( !(form->flags & HTTPPOST_PTRNAME) &&
- (form == first_form) ) {
- /* copy name (without strdup; possibly contains null characters) */
- form->name = memdup(form->name, form->namelength);
- if (!form->name) {
- return_value = CURL_FORMADD_MEMORY;
- break;
- }
- form->name_alloc = TRUE;
- }
- if ( !(form->flags & HTTPPOST_FILENAME) &&
- !(form->flags & HTTPPOST_READFILE) &&
- !(form->flags & HTTPPOST_PTRCONTENTS) &&
- !(form->flags & HTTPPOST_PTRBUFFER) ) {
- /* copy value (without strdup; possibly contains null characters) */
- form->value = memdup(form->value, form->contentslength);
- if (!form->value) {
- return_value = CURL_FORMADD_MEMORY;
- break;
- }
- form->value_alloc = TRUE;
- }
- post = AddHttpPost(form->name, form->namelength,
- form->value, form->contentslength,
- form->buffer, form->bufferlength,
- form->contenttype, form->flags,
- form->contentheader, form->showfilename,
- post, httppost,
- last_post);
-
- if(!post) {
- return_value = CURL_FORMADD_MEMORY;
- break;
- }
-
- if (form->contenttype)
- prevtype = form->contenttype;
- }
- }
- }
-
- if(return_value) {
- /* we return on error, free possibly allocated fields */
- if(!form)
- form = current_form;
- if(form) {
- if(form->name_alloc)
- free(form->name);
- if(form->value_alloc)
- free(form->value);
- if(form->contenttype_alloc)
- free(form->contenttype);
- if(form->showfilename_alloc)
- free(form->showfilename);
- }
- }
-
- /* always delete the allocated memory before returning */
- form = first_form;
- while (form != NULL) {
- FormInfo *delete_form;
-
- delete_form = form;
- form = form->more;
- free (delete_form);
- }
-
- return return_value;
-}
-
-/*
- * curl_formadd() is a public API to add a section to the multipart formpost.
- */
-
-CURLFORMcode curl_formadd(struct curl_httppost **httppost,
- struct curl_httppost **last_post,
- ...)
-{
- va_list arg;
- CURLFORMcode result;
- va_start(arg, last_post);
- result = FormAdd(httppost, last_post, arg);
- va_end(arg);
- return result;
-}
-
-/*
- * AddFormData() adds a chunk of data to the FormData linked list.
- *
- * size is incremented by the chunk length, unless it is NULL
- */
-static CURLcode AddFormData(struct FormData **formp,
- enum formtype type,
- const void *line,
- size_t length,
- curl_off_t *size)
-{
- struct FormData *newform = (struct FormData *)
- malloc(sizeof(struct FormData));
- if (!newform)
- return CURLE_OUT_OF_MEMORY;
- newform->next = NULL;
-
- /* we make it easier for plain strings: */
- if(!length)
- length = strlen((char *)line);
-
- newform->line = (char *)malloc(length+1);
- if (!newform->line) {
- free(newform);
- return CURLE_OUT_OF_MEMORY;
- }
- memcpy(newform->line, line, length);
- newform->length = length;
- newform->line[length]=0; /* zero terminate for easier debugging */
- newform->type = type;
-
- if(*formp) {
- (*formp)->next = newform;
- *formp = newform;
- }
- else
- *formp = newform;
-
- if (size) {
- if((type == FORM_DATA) || (type == FORM_CONTENT))
- *size += length;
- else {
- /* Since this is a file to be uploaded here, add the size of the actual
- file */
- if(!strequal("-", newform->line)) {
- struct_stat file;
- if(!stat(newform->line, &file)) {
- *size += file.st_size;
- }
- }
- }
- }
- return CURLE_OK;
-}
-
-/*
- * AddFormDataf() adds printf()-style formatted data to the formdata chain.
- */
-
-static CURLcode AddFormDataf(struct FormData **formp,
- curl_off_t *size,
- const char *fmt, ...)
-{
- char s[4096];
- va_list ap;
- va_start(ap, fmt);
- vsnprintf(s, sizeof(s), fmt, ap);
- va_end(ap);
-
- return AddFormData(formp, FORM_DATA, s, 0, size);
-}
-
-/*
- * Curl_formclean() is used from http.c, this cleans a built FormData linked
- * list
- */
-void Curl_formclean(struct FormData **form_ptr)
-{
- struct FormData *next, *form;
-
- form = *form_ptr;
- if(!form)
- return;
-
- do {
- next=form->next; /* the following form line */
- free(form->line); /* free the line */
- free(form); /* free the struct */
-
- } while ((form = next) != NULL); /* continue */
-
- *form_ptr = NULL;
-}
-
-#ifdef CURL_DOES_CONVERSIONS
-/*
- * Curl_formcovert() is used from http.c, this converts any
- form items that need to be sent in the network encoding.
- Returns CURLE_OK on success.
- */
-CURLcode Curl_formconvert(struct SessionHandle *data, struct FormData *form)
-{
- struct FormData *next;
- CURLcode rc;
-
- if(!form)
- return CURLE_OK;
-
- if(!data)
- return CURLE_BAD_FUNCTION_ARGUMENT;
-
- do {
- next=form->next; /* the following form line */
- if (form->type == FORM_DATA) {
- rc = Curl_convert_to_network(data, form->line, form->length);
- /* Curl_convert_to_network calls failf if unsuccessful */
- if (rc != CURLE_OK)
- return rc;
- }
- } while ((form = next) != NULL); /* continue */
- return CURLE_OK;
-}
-#endif /* CURL_DOES_CONVERSIONS */
-
-/*
- * curl_formget()
- * Serialize a curl_httppost struct.
- * Returns 0 on success.
- */
-int curl_formget(struct curl_httppost *form, void *arg,
- curl_formget_callback append)
-{
- CURLcode rc;
- curl_off_t size;
- struct FormData *data, *ptr;
-
- rc = Curl_getFormData(&data, form, NULL, &size);
- if (rc != CURLE_OK)
- return (int)rc;
-
- for (ptr = data; ptr; ptr = ptr->next) {
- if (ptr->type == FORM_FILE) {
- char buffer[8192];
- size_t read;
- struct Form temp;
-
- Curl_FormInit(&temp, ptr);
-
- do {
- read = readfromfile(&temp, buffer, sizeof(buffer));
- if ((read == (size_t) -1) || (read != append(arg, buffer, read))) {
- if (temp.fp) {
- fclose(temp.fp);
- }
- Curl_formclean(&data);
- return -1;
- }
- } while (read == sizeof(buffer));
- } else {
- if (ptr->length != append(arg, ptr->line, ptr->length)) {
- Curl_formclean(&data);
- return -1;
- }
- }
- }
- Curl_formclean(&data);
- return 0;
-}
-
-/*
- * curl_formfree() is an external function to free up a whole form post
- * chain
- */
-void curl_formfree(struct curl_httppost *form)
-{
- struct curl_httppost *next;
-
- if(!form)
- /* no form to free, just get out of this */
- return;
-
- do {
- next=form->next; /* the following form line */
-
- /* recurse to sub-contents */
- if(form->more)
- curl_formfree(form->more);
-
- if( !(form->flags & HTTPPOST_PTRNAME) && form->name)
- free(form->name); /* free the name */
- if( !(form->flags & HTTPPOST_PTRCONTENTS) && form->contents)
- free(form->contents); /* free the contents */
- if(form->contenttype)
- free(form->contenttype); /* free the content type */
- if(form->showfilename)
- free(form->showfilename); /* free the faked file name */
- free(form); /* free the struct */
-
- } while ((form = next) != NULL); /* continue */
-}
-
-#ifndef HAVE_BASENAME
-/*
- (Quote from The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004
- Edition)
-
- The basename() function shall take the pathname pointed to by path and
- return a pointer to the final component of the pathname, deleting any
- trailing '/' characters.
-
- If the string pointed to by path consists entirely of the '/' character,
- basename() shall return a pointer to the string "/". If the string pointed
- to by path is exactly "//", it is implementation-defined whether '/' or "//"
- is returned.
-
- If path is a null pointer or points to an empty string, basename() shall
- return a pointer to the string ".".
-
- The basename() function may modify the string pointed to by path, and may
- return a pointer to static storage that may then be overwritten by a
- subsequent call to basename().
-
- The basename() function need not be reentrant. A function that is not
- required to be reentrant is not required to be thread-safe.
-
-*/
-static char *basename(char *path)
-{
- /* Ignore all the details above for now and make a quick and simple
- implementaion here */
- char *s1;
- char *s2;
-
- s1=strrchr(path, '/');
- s2=strrchr(path, '\\');
-
- if(s1 && s2) {
- path = (s1 > s2? s1 : s2)+1;
- }
- else if(s1)
- path = s1 + 1;
- else if(s2)
- path = s2 + 1;
-
- return path;
-}
-#endif
-
-static char *strippath(char *fullfile)
-{
- char *filename;
- char *base;
- filename = strdup(fullfile); /* duplicate since basename() may ruin the
- buffer it works on */
- if(!filename)
- return NULL;
- base = strdup(basename(filename));
-
- free(filename); /* free temporary buffer */
-
- return base; /* returns an allocated string! */
-}
-
-/*
- * Curl_getFormData() converts a linked list of "meta data" into a complete
- * (possibly huge) multipart formdata. The input list is in 'post', while the
- * output resulting linked lists gets stored in '*finalform'. *sizep will get
- * the total size of the whole POST.
- * A multipart/form_data content-type is built, unless a custom content-type
- * is passed in 'custom_content_type'.
- */
-
-CURLcode Curl_getFormData(struct FormData **finalform,
- struct curl_httppost *post,
- const char *custom_content_type,
- curl_off_t *sizep)
-{
- struct FormData *form = NULL;
- struct FormData *firstform;
- struct curl_httppost *file;
- CURLcode result = CURLE_OK;
-
- curl_off_t size=0; /* support potentially ENORMOUS formposts */
- char *boundary;
- char *fileboundary=NULL;
- struct curl_slist* curList;
-
- *finalform=NULL; /* default form is empty */
-
- if(!post)
- return result; /* no input => no output! */
-
- boundary = Curl_FormBoundary();
- if(!boundary)
- return CURLE_OUT_OF_MEMORY;
-
- /* Make the first line of the output */
- result = AddFormDataf(&form, NULL,
- "%s; boundary=%s\r\n",
- custom_content_type?custom_content_type:
- "Content-Type: multipart/form-data",
- boundary);
-
- if (result) {
- free(boundary);
- return result;
- }
- /* we DO NOT include that line in the total size of the POST, since it'll be
- part of the header! */
-
- firstform = form;
-
- do {
-
- if(size) {
- result = AddFormDataf(&form, &size, "\r\n");
- if (result)
- break;
- }
-
- /* boundary */
- result = AddFormDataf(&form, &size, "--%s\r\n", boundary);
- if (result)
- break;
-
- /* Maybe later this should be disabled when a custom_content_type is
- passed, since Content-Disposition is not meaningful for all multipart
- types.
- */
- result = AddFormDataf(&form, &size,
- "Content-Disposition: form-data; name=\"");
- if (result)
- break;
-
- result = AddFormData(&form, FORM_DATA, post->name, post->namelength,
- &size);
- if (result)
- break;
-
- result = AddFormDataf(&form, &size, "\"");
- if (result)
- break;
-
- if(post->more) {
- /* If used, this is a link to more file names, we must then do
- the magic to include several files with the same field name */
-
- fileboundary = Curl_FormBoundary();
-
- result = AddFormDataf(&form, &size,
- "\r\nContent-Type: multipart/mixed,"
- " boundary=%s\r\n",
- fileboundary);
- if (result)
- break;
- }
-
- file = post;
-
- do {
-
- /* If 'showfilename' is set, that is a faked name passed on to us
- to use to in the formpost. If that is not set, the actually used
- local file name should be added. */
-
- if(post->more) {
- /* if multiple-file */
- char *filebasename=
- (!file->showfilename)?strippath(file->contents):NULL;
-
- result = AddFormDataf(&form, &size,
- "\r\n--%s\r\nContent-Disposition: "
- "attachment; filename=\"%s\"",
- fileboundary,
- (file->showfilename?file->showfilename:
- filebasename));
- if (filebasename)
- free(filebasename);
- if (result)
- break;
- }
- else if((post->flags & HTTPPOST_FILENAME) ||
- (post->flags & HTTPPOST_BUFFER)) {
-
- char *filebasename=
- (!post->showfilename)?strippath(post->contents):NULL;
-
- result = AddFormDataf(&form, &size,
- "; filename=\"%s\"",
- (post->showfilename?post->showfilename:
- filebasename));
- if (filebasename)
- free(filebasename);
-
- if (result)
- break;
- }
-
- if(file->contenttype) {
- /* we have a specified type */
- result = AddFormDataf(&form, &size,
- "\r\nContent-Type: %s",
- file->contenttype);
- if (result)
- break;
- }
-
- curList = file->contentheader;
- while( curList ) {
- /* Process the additional headers specified for this form */
- result = AddFormDataf( &form, &size, "\r\n%s", curList->data );
- if (result)
- break;
- curList = curList->next;
- }
- if (result) {
- Curl_formclean(&firstform);
- free(boundary);
- return result;
- }
-
-#if 0
- /* The header Content-Transfer-Encoding: seems to confuse some receivers
- * (like the built-in PHP engine). While I can't see any reason why it
- * should, I can just as well skip this to the benefit of the users who
- * are using such confused receivers.
- */
-
- if(file->contenttype &&
- !checkprefix("text/", file->contenttype)) {
- /* this is not a text content, mention our binary encoding */
- result = AddFormDataf(&form, &size,
- "\r\nContent-Transfer-Encoding: binary");
- if (result)
- break;
- }
-#endif
-
- result = AddFormDataf(&form, &size, "\r\n\r\n");
- if (result)
- break;
-
- if((post->flags & HTTPPOST_FILENAME) ||
- (post->flags & HTTPPOST_READFILE)) {
- /* we should include the contents from the specified file */
- FILE *fileread;
-
- fileread = strequal("-", file->contents)?
- stdin:fopen(file->contents, "rb"); /* binary read for win32 */
-
- /*
- * VMS: This only allows for stream files on VMS. Stream files are
- * OK, as are FIXED & VAR files WITHOUT implied CC For implied CC,
- * every record needs to have a \n appended & 1 added to SIZE
- */
-
- if(fileread) {
- if(fileread != stdin) {
- /* close the file again */
- fclose(fileread);
- /* add the file name only - for later reading from this */
- result = AddFormData(&form, FORM_FILE, file->contents, 0, &size);
- }
- else {
- /* When uploading from stdin, we can't know the size of the file,
- * thus must read the full file as before. We *could* use chunked
- * transfer-encoding, but that only works for HTTP 1.1 and we
- * can't be sure we work with such a server.
- */
- size_t nread;
- char buffer[512];
- while ((nread = fread(buffer, 1, sizeof(buffer), fileread)) != 0) {
- result = AddFormData(&form, FORM_CONTENT, buffer, nread, &size);
- if (result)
- break;
- }
- }
-
- if (result) {
- Curl_formclean(&firstform);
- free(boundary);
- return result;
- }
-
- }
- else {
-#ifdef _FORM_DEBUG
- fprintf(stderr,
- "\n==> Curl_getFormData couldn't open/read \"%s\"\n",
- file->contents);
-#endif
- Curl_formclean(&firstform);
- free(boundary);
- *finalform = NULL;
- return CURLE_READ_ERROR;
- }
-
- }
- else if (post->flags & HTTPPOST_BUFFER) {
- /* include contents of buffer */
- result = AddFormData(&form, FORM_CONTENT, post->buffer,
- post->bufferlength, &size);
- if (result)
- break;
- }
-
- else {
- /* include the contents we got */
- result = AddFormData(&form, FORM_CONTENT, post->contents,
- post->contentslength, &size);
- if (result)
- break;
- }
- } while ((file = file->more) != NULL); /* for each specified file for this field */
- if (result) {
- Curl_formclean(&firstform);
- free(boundary);
- return result;
- }
-
- if(post->more) {
- /* this was a multiple-file inclusion, make a termination file
- boundary: */
- result = AddFormDataf(&form, &size,
- "\r\n--%s--",
- fileboundary);
- free(fileboundary);
- if (result)
- break;
- }
-
- } while ((post = post->next) != NULL); /* for each field */
- if (result) {
- Curl_formclean(&firstform);
- free(boundary);
- return result;
- }
-
- /* end-boundary for everything */
- result = AddFormDataf(&form, &size,
- "\r\n--%s--\r\n",
- boundary);
- if (result) {
- Curl_formclean(&firstform);
- free(boundary);
- return result;
- }
-
- *sizep = size;
-
- free(boundary);
-
- *finalform=firstform;
-
- return result;
-}
-
-/*
- * Curl_FormInit() inits the struct 'form' points to with the 'formdata'
- * and resets the 'sent' counter.
- */
-int Curl_FormInit(struct Form *form, struct FormData *formdata )
-{
- if(!formdata)
- return 1; /* error */
-
- form->data = formdata;
- form->sent = 0;
- form->fp = NULL;
-
- return 0;
-}
-
-static size_t readfromfile(struct Form *form, char *buffer, size_t size)
-{
- size_t nread;
- if(!form->fp) {
- /* this file hasn't yet been opened */
- form->fp = fopen(form->data->line, "rb"); /* b is for binary */
- if(!form->fp)
- return (size_t)-1; /* failure */
- }
- nread = fread(buffer, 1, size, form->fp);
-
- if(nread != size) {
- /* this is the last chunk from the file, move on */
- fclose(form->fp);
- form->fp = NULL;
- form->data = form->data->next;
- }
-
- return nread;
-}
-
-/*
- * Curl_FormReader() is the fread() emulation function that will be used to
- * deliver the formdata to the transfer loop and then sent away to the peer.
- */
-size_t Curl_FormReader(char *buffer,
- size_t size,
- size_t nitems,
- FILE *mydata)
-{
- struct Form *form;
- size_t wantedsize;
- size_t gotsize = 0;
-
- form=(struct Form *)mydata;
-
- wantedsize = size * nitems;
-
- if(!form->data)
- return 0; /* nothing, error, empty */
-
- if(form->data->type == FORM_FILE) {
- gotsize = readfromfile(form, buffer, wantedsize);
-
- if(gotsize)
- /* If positive or -1, return. If zero, continue! */
- return gotsize;
- }
- do {
-
- if( (form->data->length - form->sent ) > wantedsize - gotsize) {
-
- memcpy(buffer + gotsize , form->data->line + form->sent,
- wantedsize - gotsize);
-
- form->sent += wantedsize-gotsize;
-
- return wantedsize;
- }
-
- memcpy(buffer+gotsize,
- form->data->line + form->sent,
- (form->data->length - form->sent) );
- gotsize += form->data->length - form->sent;
-
- form->sent = 0;
-
- form->data = form->data->next; /* advance */
-
- } while(form->data && (form->data->type != FORM_FILE));
- /* If we got an empty line and we have more data, we proceed to the next
- line immediately to avoid returning zero before we've reached the end.
- This is the bug reported November 22 1999 on curl 6.3. (Daniel) */
-
- return gotsize;
-}
-
-/*
- * Curl_formpostheader() returns the first line of the formpost, the
- * request-header part (which is not part of the request-body like the rest of
- * the post).
- */
-char *Curl_formpostheader(void *formp, size_t *len)
-{
- char *header;
- struct Form *form=(struct Form *)formp;
-
- if(!form->data)
- return 0; /* nothing, ERROR! */
-
- header = form->data->line;
- *len = form->data->length;
-
- form->data = form->data->next; /* advance */
-
- return header;
-}
-
-
-#ifdef _FORM_DEBUG
-int FormAddTest(const char * errormsg,
- struct curl_httppost **httppost,
- struct curl_httppost **last_post,
- ...)
-{
- int result;
- va_list arg;
- va_start(arg, last_post);
- if ((result = FormAdd(httppost, last_post, arg)))
- fprintf (stderr, "ERROR doing FormAdd ret: %d action: %s\n", result,
- errormsg);
- va_end(arg);
- return result;
-}
-
-
-int main()
-{
- char name1[] = "simple_COPYCONTENTS";
- char name2[] = "COPYCONTENTS_+_CONTENTTYPE";
- char name3[] = "PTRNAME_+_NAMELENGTH_+_COPYNAME_+_CONTENTSLENGTH";
- char name4[] = "simple_PTRCONTENTS";
- char name5[] = "PTRCONTENTS_+_CONTENTSLENGTH";
- char name6[] = "PTRCONTENTS_+_CONTENTSLENGTH_+_CONTENTTYPE";
- char name7[] = "FILE1_+_CONTENTTYPE";
- char name8[] = "FILE1_+_FILE2";
- char name9[] = "FILE1_+_FILE2_+_FILE3";
- char name10[] = "ARRAY: FILE1_+_FILE2_+_FILE3";
- char name11[] = "FILECONTENT";
- char value1[] = "value for simple COPYCONTENTS";
- char value2[] = "value for COPYCONTENTS + CONTENTTYPE";
- char value3[] = "value for PTRNAME + NAMELENGTH + COPYNAME + CONTENTSLENGTH";
- char value4[] = "value for simple PTRCONTENTS";
- char value5[] = "value for PTRCONTENTS + CONTENTSLENGTH";
- char value6[] = "value for PTRCOTNENTS + CONTENTSLENGTH + CONTENTTYPE";
- char value7[] = "inet_ntoa_r.h";
- char value8[] = "Makefile.b32";
- char type2[] = "image/gif";
- char type6[] = "text/plain";
- char type7[] = "text/html";
- int name3length = strlen(name3);
- int value3length = strlen(value3);
- int value5length = strlen(value4);
- int value6length = strlen(value5);
- int errors = 0;
- CURLcode rc;
- size_t size;
- size_t nread;
- char buffer[4096];
- struct curl_httppost *httppost=NULL;
- struct curl_httppost *last_post=NULL;
- struct curl_forms forms[4];
-
- struct FormData *form;
- struct Form formread;
-
- if (FormAddTest("simple COPYCONTENTS test", &httppost, &last_post,
- CURLFORM_COPYNAME, name1, CURLFORM_COPYCONTENTS, value1,
- CURLFORM_END))
- ++errors;
- if (FormAddTest("COPYCONTENTS + CONTENTTYPE test", &httppost, &last_post,
- CURLFORM_COPYNAME, name2, CURLFORM_COPYCONTENTS, value2,
- CURLFORM_CONTENTTYPE, type2, CURLFORM_END))
- ++errors;
- /* make null character at start to check that contentslength works
- correctly */
- name3[1] = '\0';
- value3[1] = '\0';
- if (FormAddTest("PTRNAME + NAMELENGTH + COPYNAME + CONTENTSLENGTH test",
- &httppost, &last_post,
- CURLFORM_PTRNAME, name3, CURLFORM_COPYCONTENTS, value3,
- CURLFORM_CONTENTSLENGTH, value3length,
- CURLFORM_NAMELENGTH, name3length, CURLFORM_END))
- ++errors;
- if (FormAddTest("simple PTRCONTENTS test", &httppost, &last_post,
- CURLFORM_COPYNAME, name4, CURLFORM_PTRCONTENTS, value4,
- CURLFORM_END))
- ++errors;
- /* make null character at start to check that contentslength works
- correctly */
- value5[1] = '\0';
- if (FormAddTest("PTRCONTENTS + CONTENTSLENGTH test", &httppost, &last_post,
- CURLFORM_COPYNAME, name5, CURLFORM_PTRCONTENTS, value5,
- CURLFORM_CONTENTSLENGTH, value5length, CURLFORM_END))
- ++errors;
- /* make null character at start to check that contentslength works
- correctly */
- value6[1] = '\0';
- if (FormAddTest("PTRCONTENTS + CONTENTSLENGTH + CONTENTTYPE test",
- &httppost, &last_post,
- CURLFORM_COPYNAME, name6, CURLFORM_PTRCONTENTS, value6,
- CURLFORM_CONTENTSLENGTH, value6length,
- CURLFORM_CONTENTTYPE, type6, CURLFORM_END))
- ++errors;
- if (FormAddTest("FILE + CONTENTTYPE test", &httppost, &last_post,
- CURLFORM_COPYNAME, name7, CURLFORM_FILE, value7,
- CURLFORM_CONTENTTYPE, type7, CURLFORM_END))
- ++errors;
- if (FormAddTest("FILE1 + FILE2 test", &httppost, &last_post,
- CURLFORM_COPYNAME, name8, CURLFORM_FILE, value7,
- CURLFORM_FILE, value8, CURLFORM_END))
- ++errors;
- if (FormAddTest("FILE1 + FILE2 + FILE3 test", &httppost, &last_post,
- CURLFORM_COPYNAME, name9, CURLFORM_FILE, value7,
- CURLFORM_FILE, value8, CURLFORM_FILE, value7, CURLFORM_END))
- ++errors;
- forms[0].option = CURLFORM_FILE;
- forms[0].value = value7;
- forms[1].option = CURLFORM_FILE;
- forms[1].value = value8;
- forms[2].option = CURLFORM_FILE;
- forms[2].value = value7;
- forms[3].option = CURLFORM_END;
- if (FormAddTest("FILE1 + FILE2 + FILE3 ARRAY test", &httppost, &last_post,
- CURLFORM_COPYNAME, name10, CURLFORM_ARRAY, forms,
- CURLFORM_END))
- ++errors;
- if (FormAddTest("FILECONTENT test", &httppost, &last_post,
- CURLFORM_COPYNAME, name11, CURLFORM_FILECONTENT, value7,
- CURLFORM_END))
- ++errors;
-
- rc = Curl_getFormData(&form, httppost, NULL, &size);
- if(rc != CURLE_OK) {
- if(rc != CURLE_READ_ERROR) {
- const char *errortext = curl_easy_strerror(rc);
- fprintf(stdout, "\n==> Curl_getFormData error: %s\n", errortext);
- }
- return 0;
- }
-
- Curl_FormInit(&formread, form);
-
- do {
- nread = Curl_FormReader(buffer, 1, sizeof(buffer),
- (FILE *)&formread);
-
- if(nread < 1)
- break;
- fwrite(buffer, nread, 1, stdout);
- } while(1);
-
- fprintf(stdout, "size: %d\n", size);
- if (errors)
- fprintf(stdout, "\n==> %d Test(s) failed!\n", errors);
- else
- fprintf(stdout, "\nAll Tests seem to have worked (please check output)\n");
-
- return 0;
-}
-
-#endif /* _FORM_DEBUG */
-
-#else /* CURL_DISABLE_HTTP */
-CURLFORMcode curl_formadd(struct curl_httppost **httppost,
- struct curl_httppost **last_post,
- ...)
-{
- (void)httppost;
- (void)last_post;
- return CURL_FORMADD_DISABLED;
-}
-
-int curl_formget(struct curl_httppost *form, void *arg,
- curl_formget_callback append)
-{
- (void) form;
- (void) arg;
- (void) append;
- return CURL_FORMADD_DISABLED;
-}
-
-void curl_formfree(struct curl_httppost *form)
-{
- (void)form;
- /* does nothing HTTP is disabled */
-}
-
-#endif /* CURL_DISABLE_HTTP */
-
-#if !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY)
-
-/*
- * Curl_FormBoundary() creates a suitable boundary string and returns an
- * allocated one. This is also used by SSL-code so it must be present even
- * if HTTP is disabled!
- */
-char *Curl_FormBoundary(void)
-{
- char *retstring;
- static int randomizer; /* this is just so that two boundaries within
- the same form won't be identical */
- size_t i;
-
- static const char table16[]="abcdef0123456789";
-
- retstring = (char *)malloc(BOUNDARY_LENGTH+1);
-
- if(!retstring)
- return NULL; /* failed */
-
- srand((unsigned int)time(NULL)+randomizer++); /* seed */
-
- strcpy(retstring, "----------------------------");
-
- for(i=strlen(retstring); i<BOUNDARY_LENGTH; i++)
- retstring[i] = table16[rand()%16];
-
- /* 28 dashes and 12 hexadecimal digits makes 12^16 (184884258895036416)
- combinations */
- retstring[BOUNDARY_LENGTH]=0; /* zero terminate */
-
- return retstring;
-}
-
-#endif /* !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY) */
diff --git a/Utilities/cmcurl/formdata.h b/Utilities/cmcurl/formdata.h
deleted file mode 100644
index 4ca0f3c5c..000000000
--- a/Utilities/cmcurl/formdata.h
+++ /dev/null
@@ -1,97 +0,0 @@
-#ifndef __FORMDATA_H
-#define __FORMDATA_H
-
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-enum formtype {
- FORM_DATA, /* form metadata (convert to network encoding if necessary) */
- FORM_CONTENT, /* form content (never convert) */
- FORM_FILE /* 'line' points to a file name we should read from
- to create the form data (never convert) */
-};
-
-/* plain and simple linked list with lines to send */
-struct FormData {
- struct FormData *next;
- enum formtype type;
- char *line;
- size_t length;
-};
-
-struct Form {
- struct FormData *data; /* current form line to send */
- size_t sent; /* number of bytes of the current line that has
- already been sent in a previous invoke */
- FILE *fp; /* file to read from */
-};
-
-/* used by FormAdd for temporary storage */
-typedef struct FormInfo {
- char *name;
- bool name_alloc;
- size_t namelength;
- char *value;
- bool value_alloc;
- size_t contentslength;
- char *contenttype;
- bool contenttype_alloc;
- long flags;
- char *buffer; /* pointer to existing buffer used for file upload */
- size_t bufferlength;
- char *showfilename; /* The file name to show. If not set, the actual
- file name will be used */
- bool showfilename_alloc;
- struct curl_slist* contentheader;
- struct FormInfo *more;
-} FormInfo;
-
-int Curl_FormInit(struct Form *form, struct FormData *formdata );
-
-CURLcode
-Curl_getFormData(struct FormData **,
- struct curl_httppost *post,
- const char *custom_contenttype,
- curl_off_t *size);
-
-/* fread() emulation */
-size_t Curl_FormReader(char *buffer,
- size_t size,
- size_t nitems,
- FILE *mydata);
-
-/*
- * Curl_formpostheader() returns the first line of the formpost, the
- * request-header part (which is not part of the request-body like the rest of
- * the post).
- */
-char *Curl_formpostheader(void *formp, size_t *len);
-
-char *Curl_FormBoundary(void);
-
-void Curl_formclean(struct FormData **);
-
-CURLcode Curl_formconvert(struct SessionHandle *, struct FormData *);
-
-#endif
-
diff --git a/Utilities/cmcurl/ftp.c b/Utilities/cmcurl/ftp.c
deleted file mode 100644
index 3ccbc4364..000000000
--- a/Utilities/cmcurl/ftp.c
+++ /dev/null
@@ -1,3865 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#ifndef CURL_DISABLE_FTP
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <ctype.h>
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#ifdef WIN32
-
-#else /* probably some kind of unix */
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#include <sys/types.h>
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_UTSNAME_H
-#include <sys/utsname.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifdef VMS
-#include <in.h>
-#include <inet.h>
-#endif
-#endif
-
-#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
-#undef in_addr_t
-#define in_addr_t unsigned long
-#endif
-
-#include <curl/curl.h>
-#include "urldata.h"
-#include "sendf.h"
-#include "easyif.h" /* for Curl_convert_... prototypes */
-
-#include "if2ip.h"
-#include "hostip.h"
-#include "progress.h"
-#include "transfer.h"
-#include "escape.h"
-#include "http.h" /* for HTTP proxy tunnel stuff */
-#include "ftp.h"
-
-#ifdef HAVE_KRB4
-#include "krb4.h"
-#endif
-
-#include "strtoofft.h"
-#include "strequal.h"
-#include "sslgen.h"
-#include "connect.h"
-#include "strerror.h"
-#include "memory.h"
-#include "inet_ntop.h"
-#include "select.h"
-#include "parsedate.h" /* for the week day and month names */
-#include "sockaddr.h" /* required for Curl_sockaddr_storage */
-#include "multiif.h"
-
-#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
-#include "inet_ntoa_r.h"
-#endif
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
-#ifdef CURLDEBUG
-#include "memdebug.h"
-#endif
-
-#ifdef HAVE_NI_WITHSCOPEID
-#define NIFLAGS NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID
-#else
-#define NIFLAGS NI_NUMERICHOST | NI_NUMERICSERV
-#endif
-
-/* Local API functions */
-static CURLcode ftp_sendquote(struct connectdata *conn,
- struct curl_slist *quote);
-static CURLcode ftp_quit(struct connectdata *conn);
-static CURLcode ftp_parse_url_path(struct connectdata *conn);
-static CURLcode ftp_regular_transfer(struct connectdata *conn, bool *done);
-static void ftp_pasv_verbose(struct connectdata *conn,
- Curl_addrinfo *ai,
- char *newhost, /* ascii version */
- int port);
-static CURLcode ftp_state_post_rest(struct connectdata *conn);
-static CURLcode ftp_state_post_cwd(struct connectdata *conn);
-static CURLcode ftp_state_quote(struct connectdata *conn,
- bool init, ftpstate instate);
-static CURLcode ftp_nb_type(struct connectdata *conn,
- bool ascii, ftpstate state);
-static int ftp_need_type(struct connectdata *conn,
- bool ascii);
-
-/* easy-to-use macro: */
-#define FTPSENDF(x,y,z) if ((result = Curl_ftpsendf(x,y,z)) != CURLE_OK) \
- return result
-#define NBFTPSENDF(x,y,z) if ((result = Curl_nbftpsendf(x,y,z)) != CURLE_OK) \
- return result
-
-static void freedirs(struct connectdata *conn)
-{
- struct ftp_conn *ftpc = &conn->proto.ftpc;
- struct FTP *ftp = conn->data->reqdata.proto.ftp;
-
- int i;
- if(ftpc->dirs) {
- for (i=0; i < ftpc->dirdepth; i++){
- if(ftpc->dirs[i]) {
- free(ftpc->dirs[i]);
- ftpc->dirs[i]=NULL;
- }
- }
- free(ftpc->dirs);
- ftpc->dirs = NULL;
- }
- if(ftp->file) {
- free(ftp->file);
- ftp->file = NULL;
- }
-}
-
-/* Returns non-zero if the given string contains CR (\r) or LF (\n),
- which are not allowed within RFC 959 <string>.
- Note: The input string is in the client's encoding which might
- not be ASCII, so escape sequences \r & \n must be used instead
- of hex values 0x0d & 0x0a.
-*/
-static bool isBadFtpString(const char *string)
-{
- return (bool)((NULL != strchr(string, '\r')) || (NULL != strchr(string, '\n')));
-}
-
-/***********************************************************************
- *
- * AllowServerConnect()
- *
- * When we've issue the PORT command, we have told the server to connect
- * to us. This function will sit and wait here until the server has
- * connected.
- *
- */
-static CURLcode AllowServerConnect(struct connectdata *conn)
-{
- int timeout_ms;
- struct SessionHandle *data = conn->data;
- curl_socket_t sock = conn->sock[SECONDARYSOCKET];
- struct timeval now = Curl_tvnow();
- long timespent = Curl_tvdiff(Curl_tvnow(), now)/1000;
- long timeout = data->set.connecttimeout?data->set.connecttimeout:
- (data->set.timeout?data->set.timeout: 0);
-
- if(timeout) {
- timeout -= timespent;
- if(timeout<=0) {
- failf(data, "Timed out before server could connect to us");
- return CURLE_OPERATION_TIMEDOUT;
- }
- }
-
- /* We allow the server 60 seconds to connect to us, or a custom timeout.
- Note the typecast here. */
- timeout_ms = (timeout?(int)timeout:60) * 1000;
-
- switch (Curl_select(sock, CURL_SOCKET_BAD, timeout_ms)) {
- case -1: /* error */
- /* let's die here */
- failf(data, "Error while waiting for server connect");
- return CURLE_FTP_PORT_FAILED;
- case 0: /* timeout */
- /* let's die here */
- failf(data, "Timeout while waiting for server connect");
- return CURLE_FTP_PORT_FAILED;
- default:
- /* we have received data here */
- {
- curl_socket_t s = CURL_SOCKET_BAD;
-#ifdef ENABLE_IPV6
- struct Curl_sockaddr_storage add;
-#else
- struct sockaddr_in add;
-#endif
- socklen_t size = (socklen_t) sizeof(add);
-
- if(0 == getsockname(sock, (struct sockaddr *) &add, &size)) {
- size = sizeof(add);
-
- s=accept(sock, (struct sockaddr *) &add, &size);
- }
- sclose(sock); /* close the first socket */
-
- if (CURL_SOCKET_BAD == s) {
- /* DIE! */
- failf(data, "Error accept()ing server connect");
- return CURLE_FTP_PORT_FAILED;
- }
- infof(data, "Connection accepted from server\n");
-
- conn->sock[SECONDARYSOCKET] = s;
- Curl_nonblock(s, TRUE); /* enable non-blocking */
- }
- break;
- }
-
- return CURLE_OK;
-}
-
-/* initialize stuff to prepare for reading a fresh new response */
-static void ftp_respinit(struct connectdata *conn)
-{
- struct ftp_conn *ftpc = &conn->proto.ftpc;
- ftpc->nread_resp = 0;
- ftpc->linestart_resp = conn->data->state.buffer;
-}
-
-/* macro to check for the last line in an FTP server response */
-#define lastline(line) (ISDIGIT(line[0]) && ISDIGIT(line[1]) && \
- ISDIGIT(line[2]) && (' ' == line[3]))
-
-static CURLcode ftp_readresp(curl_socket_t sockfd,
- struct connectdata *conn,
- int *ftpcode, /* return the ftp-code if done */
- size_t *size) /* size of the response */
-{
- int perline; /* count bytes per line */
- bool keepon=TRUE;
- ssize_t gotbytes;
- char *ptr;
- struct SessionHandle *data = conn->data;
- char *buf = data->state.buffer;
- CURLcode result = CURLE_OK;
- struct ftp_conn *ftpc = &conn->proto.ftpc;
- int code = 0;
-
- if (ftpcode)
- *ftpcode = 0; /* 0 for errors or not done */
-
- ptr=buf + ftpc->nread_resp;
-
- perline= (int)(ptr-ftpc->linestart_resp); /* number of bytes in the current
- line, so far */
- keepon=TRUE;
-
- while((ftpc->nread_resp<BUFSIZE) && (keepon && !result)) {
-
- if(ftpc->cache) {
- /* we had data in the "cache", copy that instead of doing an actual
- * read
- *
- * ftp->cache_size is cast to int here. This should be safe,
- * because it would have been populated with something of size
- * int to begin with, even though its datatype may be larger
- * than an int.
- */
- memcpy(ptr, ftpc->cache, (int)ftpc->cache_size);
- gotbytes = (int)ftpc->cache_size;
- free(ftpc->cache); /* free the cache */
- ftpc->cache = NULL; /* clear the pointer */
- ftpc->cache_size = 0; /* zero the size just in case */
- }
- else {
- int res = Curl_read(conn, sockfd, ptr, BUFSIZE-ftpc->nread_resp,
- &gotbytes);
- if(res < 0)
- /* EWOULDBLOCK */
- return CURLE_OK; /* return */
-
-#ifdef CURL_DOES_CONVERSIONS
- if((res == CURLE_OK) && (gotbytes > 0)) {
- /* convert from the network encoding */
- result = res = Curl_convert_from_network(data, ptr, gotbytes);
- /* Curl_convert_from_network calls failf if unsuccessful */
- }
-#endif /* CURL_DOES_CONVERSIONS */
-
- if(CURLE_OK != res)
- keepon = FALSE;
- }
-
- if(!keepon)
- ;
- else if(gotbytes <= 0) {
- keepon = FALSE;
- result = CURLE_RECV_ERROR;
- failf(data, "FTP response reading failed");
- }
- else {
- /* we got a whole chunk of data, which can be anything from one
- * byte to a set of lines and possible just a piece of the last
- * line */
- int i;
-
- conn->headerbytecount += gotbytes;
-
- ftpc->nread_resp += gotbytes;
- for(i = 0; i < gotbytes; ptr++, i++) {
- perline++;
- if(*ptr=='\n') {
- /* a newline is CRLF in ftp-talk, so the CR is ignored as
- the line isn't really terminated until the LF comes */
-
- /* output debug output if that is requested */
- if(data->set.verbose)
- Curl_debug(data, CURLINFO_HEADER_IN,
- ftpc->linestart_resp, (size_t)perline, conn);
-
- /*
- * We pass all response-lines to the callback function registered
- * for "headers". The response lines can be seen as a kind of
- * headers.
- */
- result = Curl_client_write(conn, CLIENTWRITE_HEADER,
- ftpc->linestart_resp, perline);
- if(result)
- return result;
-
- if(perline>3 && lastline(ftpc->linestart_resp)) {
- /* This is the end of the last line, copy the last line to the
- start of the buffer and zero terminate, for old times sake (and
- krb4)! */
- char *meow;
- int n;
- for(meow=ftpc->linestart_resp, n=0; meow<ptr; meow++, n++)
- buf[n] = *meow;
- *meow=0; /* zero terminate */
- keepon=FALSE;
- ftpc->linestart_resp = ptr+1; /* advance pointer */
- i++; /* skip this before getting out */
-
- *size = ftpc->nread_resp; /* size of the response */
- ftpc->nread_resp = 0; /* restart */
- break;
- }
- perline=0; /* line starts over here */
- ftpc->linestart_resp = ptr+1;
- }
- }
- if(!keepon && (i != gotbytes)) {
- /* We found the end of the response lines, but we didn't parse the
- full chunk of data we have read from the server. We therefore need
- to store the rest of the data to be checked on the next invoke as
- it may actually contain another end of response already! */
- ftpc->cache_size = gotbytes - i;
- ftpc->cache = (char *)malloc((int)ftpc->cache_size);
- if(ftpc->cache)
- memcpy(ftpc->cache, ftpc->linestart_resp, (int)ftpc->cache_size);
- else
- return CURLE_OUT_OF_MEMORY; /**BANG**/
- }
- } /* there was data */
-
- } /* while there's buffer left and loop is requested */
-
- if(!result)
- code = atoi(buf);
-
-#ifdef HAVE_KRB4
- /* handle the security-oriented responses 6xx ***/
- /* FIXME: some errorchecking perhaps... ***/
- switch(code) {
- case 631:
- Curl_sec_read_msg(conn, buf, prot_safe);
- break;
- case 632:
- Curl_sec_read_msg(conn, buf, prot_private);
- break;
- case 633:
- Curl_sec_read_msg(conn, buf, prot_confidential);
- break;
- default:
- /* normal ftp stuff we pass through! */
- break;
- }
-#endif
-
- *ftpcode=code; /* return the initial number like this */
-
-
- /* store the latest code for later retrieval */
- conn->data->info.httpcode=code;
-
- return result;
-}
-
-/* --- parse FTP server responses --- */
-
-/*
- * Curl_GetFTPResponse() is supposed to be invoked after each command sent to
- * a remote FTP server. This function will wait and read all lines of the
- * response and extract the relevant return code for the invoking function.
- */
-
-CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
- struct connectdata *conn,
- int *ftpcode) /* return the ftp-code */
-{
- /*
- * We cannot read just one byte per read() and then go back to select() as
- * the OpenSSL read() doesn't grok that properly.
- *
- * Alas, read as much as possible, split up into lines, use the ending
- * line in a response or continue reading. */
-
- curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
- int perline; /* count bytes per line */
- bool keepon=TRUE;
- ssize_t gotbytes;
- char *ptr;
- long timeout; /* timeout in seconds */
- int interval_ms;
- struct SessionHandle *data = conn->data;
- char *line_start;
- int code=0; /* default ftp "error code" to return */
- char *buf = data->state.buffer;
- CURLcode result = CURLE_OK;
- struct ftp_conn *ftpc = &conn->proto.ftpc;
- struct timeval now = Curl_tvnow();
-
- if (ftpcode)
- *ftpcode = 0; /* 0 for errors */
-
- ptr=buf;
- line_start = buf;
-
- *nreadp=0;
- perline=0;
- keepon=TRUE;
-
- while((*nreadp<BUFSIZE) && (keepon && !result)) {
- /* check and reset timeout value every lap */
- if(data->set.ftp_response_timeout )
- /* if CURLOPT_FTP_RESPONSE_TIMEOUT is set, use that to determine
- remaining time. Also, use "now" as opposed to "conn->now"
- because ftp_response_timeout is only supposed to govern
- the response for any given ftp response, not for the time
- from connect to the given ftp response. */
- timeout = data->set.ftp_response_timeout - /* timeout time */
- Curl_tvdiff(Curl_tvnow(), now)/1000; /* spent time */
- else if(data->set.timeout)
- /* if timeout is requested, find out how much remaining time we have */
- timeout = data->set.timeout - /* timeout time */
- Curl_tvdiff(Curl_tvnow(), conn->now)/1000; /* spent time */
- else
- /* Even without a requested timeout, we only wait response_time
- seconds for the full response to arrive before we bail out */
- timeout = ftpc->response_time -
- Curl_tvdiff(Curl_tvnow(), now)/1000; /* spent time */
-
- if(timeout <=0 ) {
- failf(data, "FTP response timeout");
- return CURLE_OPERATION_TIMEDOUT; /* already too little time */
- }
-
- if(!ftpc->cache) {
- interval_ms = 1 * 1000; /* use 1 second timeout intervals */
-
- switch (Curl_select(sockfd, CURL_SOCKET_BAD, interval_ms)) {
- case -1: /* select() error, stop reading */
- result = CURLE_RECV_ERROR;
- failf(data, "FTP response aborted due to select() error: %d",
- Curl_sockerrno());
- break;
- case 0: /* timeout */
- if(Curl_pgrsUpdate(conn))
- return CURLE_ABORTED_BY_CALLBACK;
- continue; /* just continue in our loop for the timeout duration */
-
- default:
- break;
- }
- }
- if(CURLE_OK == result) {
- /*
- * This code previously didn't use the kerberos sec_read() code
- * to read, but when we use Curl_read() it may do so. Do confirm
- * that this is still ok and then remove this comment!
- */
- if(ftpc->cache) {
- /* we had data in the "cache", copy that instead of doing an actual
- * read
- *
- * Dave Meyer, December 2003:
- * ftp->cache_size is cast to int here. This should be safe,
- * because it would have been populated with something of size
- * int to begin with, even though its datatype may be larger
- * than an int.
- */
- memcpy(ptr, ftpc->cache, (int)ftpc->cache_size);
- gotbytes = (int)ftpc->cache_size;
- free(ftpc->cache); /* free the cache */
- ftpc->cache = NULL; /* clear the pointer */
- ftpc->cache_size = 0; /* zero the size just in case */
- }
- else {
- int res = Curl_read(conn, sockfd, ptr, BUFSIZE-*nreadp, &gotbytes);
- if(res < 0)
- /* EWOULDBLOCK */
- continue; /* go looping again */
-
-#ifdef CURL_DOES_CONVERSIONS
- if((res == CURLE_OK) && (gotbytes > 0)) {
- /* convert from the network encoding */
- result = res = Curl_convert_from_network(data, ptr, gotbytes);
- /* Curl_convert_from_network calls failf if unsuccessful */
- }
-#endif /* CURL_DOES_CONVERSIONS */
-
- if(CURLE_OK != res)
- keepon = FALSE;
- }
-
- if(!keepon)
- ;
- else if(gotbytes <= 0) {
- keepon = FALSE;
- result = CURLE_RECV_ERROR;
- failf(data, "FTP response reading failed");
- }
- else {
- /* we got a whole chunk of data, which can be anything from one
- * byte to a set of lines and possible just a piece of the last
- * line */
- int i;
-
- conn->headerbytecount += gotbytes;
-
- *nreadp += gotbytes;
- for(i = 0; i < gotbytes; ptr++, i++) {
- perline++;
- if(*ptr=='\n') {
- /* a newline is CRLF in ftp-talk, so the CR is ignored as
- the line isn't really terminated until the LF comes */
-
- /* output debug output if that is requested */
- if(data->set.verbose)
- Curl_debug(data, CURLINFO_HEADER_IN,
- line_start, (size_t)perline, conn);
-
- /*
- * We pass all response-lines to the callback function registered
- * for "headers". The response lines can be seen as a kind of
- * headers.
- */
- result = Curl_client_write(conn, CLIENTWRITE_HEADER,
- line_start, perline);
- if(result)
- return result;
-
- if(perline>3 && lastline(line_start)) {
- /* This is the end of the last line, copy the last
- * line to the start of the buffer and zero terminate,
- * for old times sake (and krb4)! */
- char *meow;
- int n;
- for(meow=line_start, n=0; meow<ptr; meow++, n++)
- buf[n] = *meow;
- *meow=0; /* zero terminate */
- keepon=FALSE;
- line_start = ptr+1; /* advance pointer */
- i++; /* skip this before getting out */
- break;
- }
- perline=0; /* line starts over here */
- line_start = ptr+1;
- }
- }
- if(!keepon && (i != gotbytes)) {
- /* We found the end of the response lines, but we didn't parse the
- full chunk of data we have read from the server. We therefore
- need to store the rest of the data to be checked on the next
- invoke as it may actually contain another end of response
- already! Cleverly figured out by Eric Lavigne in December
- 2001. */
- ftpc->cache_size = gotbytes - i;
- ftpc->cache = (char *)malloc((int)ftpc->cache_size);
- if(ftpc->cache)
- memcpy(ftpc->cache, line_start, (int)ftpc->cache_size);
- else
- return CURLE_OUT_OF_MEMORY; /**BANG**/
- }
- } /* there was data */
- } /* if(no error) */
- } /* while there's buffer left and loop is requested */
-
- if(!result)
- code = atoi(buf);
-
-#ifdef HAVE_KRB4
- /* handle the security-oriented responses 6xx ***/
- /* FIXME: some errorchecking perhaps... ***/
- switch(code) {
- case 631:
- Curl_sec_read_msg(conn, buf, prot_safe);
- break;
- case 632:
- Curl_sec_read_msg(conn, buf, prot_private);
- break;
- case 633:
- Curl_sec_read_msg(conn, buf, prot_confidential);
- break;
- default:
- /* normal ftp stuff we pass through! */
- break;
- }
-#endif
-
- if(ftpcode)
- *ftpcode=code; /* return the initial number like this */
-
- /* store the latest code for later retrieval */
- conn->data->info.httpcode=code;
-
- return result;
-}
-
-/* This is the ONLY way to change FTP state! */
-static void state(struct connectdata *conn,
- ftpstate state)
-{
-#ifdef CURLDEBUG
- /* for debug purposes */
- const char *names[]={
- "STOP",
- "WAIT220",
- "AUTH",
- "USER",
- "PASS",
- "ACCT",
- "PBSZ",
- "PROT",
- "CCC",
- "PWD",
- "QUOTE",
- "RETR_PREQUOTE",
- "STOR_PREQUOTE",
- "POSTQUOTE",
- "CWD",
- "MKD",
- "MDTM",
- "TYPE",
- "LIST_TYPE",
- "RETR_TYPE",
- "STOR_TYPE",
- "SIZE",
- "RETR_SIZE",
- "STOR_SIZE",
- "REST",
- "RETR_REST",
- "PORT",
- "PASV",
- "LIST",
- "RETR",
- "STOR",
- "QUIT"
- };
-#endif
- struct ftp_conn *ftpc = &conn->proto.ftpc;
-#ifdef CURLDEBUG
- if(ftpc->state != state)
- infof(conn->data, "FTP %p state change from %s to %s\n",
- ftpc, names[ftpc->state], names[state]);
-#endif
- ftpc->state = state;
-}
-
-static CURLcode ftp_state_user(struct connectdata *conn)
-{
- CURLcode result;
- struct FTP *ftp = conn->data->reqdata.proto.ftp;
- /* send USER */
- NBFTPSENDF(conn, "USER %s", ftp->user?ftp->user:"");
-
- state(conn, FTP_USER);
- conn->data->state.ftp_trying_alternative = FALSE;
-
- return CURLE_OK;
-}
-
-static CURLcode ftp_state_pwd(struct connectdata *conn)
-{
- CURLcode result;
-
- /* send PWD to discover our entry point */
- NBFTPSENDF(conn, "PWD", NULL);
- state(conn, FTP_PWD);
-
- return CURLE_OK;
-}
-
-/* For the FTP "protocol connect" and "doing" phases only */
-int Curl_ftp_getsock(struct connectdata *conn,
- curl_socket_t *socks,
- int numsocks)
-{
- struct ftp_conn *ftpc = &conn->proto.ftpc;
-
- if(!numsocks)
- return GETSOCK_BLANK;
-
- socks[0] = conn->sock[FIRSTSOCKET];
-
- if(ftpc->sendleft) {
- /* write mode */
- return GETSOCK_WRITESOCK(0);
- }
-
- /* read mode */
- return GETSOCK_READSOCK(0);
-}
-
-/* This is called after the FTP_QUOTE state is passed.
-
- ftp_state_cwd() sends the range of PWD commands to the server to change to
- the correct directory. It may also need to send MKD commands to create
- missing ones, if that option is enabled.
-*/
-static CURLcode ftp_state_cwd(struct connectdata *conn)
-{
- CURLcode result = CURLE_OK;
- struct ftp_conn *ftpc = &conn->proto.ftpc;
-
- if(ftpc->cwddone)
- /* already done and fine */
- result = ftp_state_post_cwd(conn);
- else {
- ftpc->count2 = 0;
- if (conn->bits.reuse && ftpc->entrypath) {
- /* This is a re-used connection. Since we change directory to where the
- transfer is taking place, we must first get back to the original dir
- where we ended up after login: */
- ftpc->count1 = 0; /* we count this as the first path, then we add one
- for all upcoming ones in the ftp->dirs[] array */
- NBFTPSENDF(conn, "CWD %s", ftpc->entrypath);
- state(conn, FTP_CWD);
- }
- else {
- if(ftpc->dirdepth) {
- ftpc->count1 = 1;
- /* issue the first CWD, the rest is sent when the CWD responses are
- received... */
- NBFTPSENDF(conn, "CWD %s", ftpc->dirs[ftpc->count1 -1]);
- state(conn, FTP_CWD);
- }
- else {
- /* No CWD necessary */
- result = ftp_state_post_cwd(conn);
- }
- }
- }
- return result;
-}
-
-typedef enum {
- EPRT,
- PORT,
- DONE
-} ftpport;
-
-static CURLcode ftp_state_use_port(struct connectdata *conn,
- ftpport fcmd) /* start with this */
-
-{
- CURLcode result = CURLE_OK;
- struct ftp_conn *ftpc = &conn->proto.ftpc;
- struct SessionHandle *data=conn->data;
- curl_socket_t portsock= CURL_SOCKET_BAD;
- char myhost[256] = "";
-
-#ifdef ENABLE_IPV6
- /******************************************************************
- * IPv6-specific section
- */
- struct Curl_sockaddr_storage ss;
- struct addrinfo *res, *ai;
- socklen_t sslen;
- char hbuf[NI_MAXHOST];
- struct sockaddr *sa=(struct sockaddr *)&ss;
- char tmp[1024];
- const char *mode[] = { "EPRT", "PORT", NULL };
- int rc;
- int error;
- char *host=NULL;
- struct Curl_dns_entry *h=NULL;
- unsigned short port = 0;
-
- /* Step 1, figure out what address that is requested */
-
- if(data->set.ftpport && (strlen(data->set.ftpport) > 1)) {
- /* attempt to get the address of the given interface name */
- if(!Curl_if2ip(data->set.ftpport, hbuf, sizeof(hbuf)))
- /* not an interface, use the given string as host name instead */
- host = data->set.ftpport;
- else
- host = hbuf; /* use the hbuf for host name */
- } /* data->set.ftpport */
-
- if(!host) {
- /* not an interface and not a host name, get default by extracting
- the IP from the control connection */
-
- sslen = sizeof(ss);
- if (getsockname(conn->sock[FIRSTSOCKET], (struct sockaddr *)&ss, &sslen)) {
- failf(data, "getsockname() failed: %s",
- Curl_strerror(conn, Curl_sockerrno()) );
- return CURLE_FTP_PORT_FAILED;
- }
-
- if (sslen > (socklen_t)sizeof(ss))
- sslen = sizeof(ss);
- rc = getnameinfo((struct sockaddr *)&ss, sslen, hbuf, sizeof(hbuf), NULL,
- 0, NIFLAGS);
- if(rc) {
- failf(data, "getnameinfo() returned %d \n", rc);
- return CURLE_FTP_PORT_FAILED;
- }
- host = hbuf; /* use this host name */
- }
-
- rc = Curl_resolv(conn, host, 0, &h);
- if(rc == CURLRESOLV_PENDING)
- rc = Curl_wait_for_resolv(conn, &h);
- if(h) {
- res = h->addr;
- /* when we return from this function, we can forget about this entry
- to we can unlock it now already */
- Curl_resolv_unlock(data, h);
- } /* (h) */
- else
- res = NULL; /* failure! */
-
-
- /* step 2, create a socket for the requested address */
-
- portsock = CURL_SOCKET_BAD;
- error = 0;
- for (ai = res; ai; ai = ai->ai_next) {
- /*
- * Workaround for AIX5 getaddrinfo() problem (it doesn't set ai_socktype):
- */
- if (ai->ai_socktype == 0)
- ai->ai_socktype = conn->socktype;
-
- portsock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
- if (portsock == CURL_SOCKET_BAD) {
- error = Curl_sockerrno();
- continue;
- }
- break;
- }
- if(!ai) {
- failf(data, "socket failure: %s", Curl_strerror(conn, error));
- return CURLE_FTP_PORT_FAILED;
- }
-
- /* step 3, bind to a suitable local address */
-
- /* Try binding the given address. */
- if (bind(portsock, ai->ai_addr, ai->ai_addrlen)) {
-
- /* It failed. Bind the address used for the control connection instead */
- sslen = sizeof(ss);
- if (getsockname(conn->sock[FIRSTSOCKET],
- (struct sockaddr *)sa, &sslen)) {
- failf(data, "getsockname() failed: %s",
- Curl_strerror(conn, Curl_sockerrno()) );
- sclose(portsock);
- return CURLE_FTP_PORT_FAILED;
- }
-
- /* set port number to zero to make bind() pick "any" */
- if(((struct sockaddr *)sa)->sa_family == AF_INET)
- ((struct sockaddr_in *)sa)->sin_port=0;
- else
- ((struct sockaddr_in6 *)sa)->sin6_port =0;
-
- if (sslen > (socklen_t)sizeof(ss))
- sslen = sizeof(ss);
-
- if(bind(portsock, (struct sockaddr *)sa, sslen)) {
- failf(data, "bind failed: %s", Curl_strerror(conn, Curl_sockerrno()));
- sclose(portsock);
- return CURLE_FTP_PORT_FAILED;
- }
- }
-
- /* get the name again after the bind() so that we can extract the
- port number it uses now */
- sslen = sizeof(ss);
- if(getsockname(portsock, (struct sockaddr *)sa, &sslen)) {
- failf(data, "getsockname() failed: %s",
- Curl_strerror(conn, Curl_sockerrno()) );
- sclose(portsock);
- return CURLE_FTP_PORT_FAILED;
- }
-
- /* step 4, listen on the socket */
-
- if (listen(portsock, 1)) {
- failf(data, "socket failure: %s", Curl_strerror(conn, Curl_sockerrno()));
- sclose(portsock);
- return CURLE_FTP_PORT_FAILED;
- }
-
- /* step 5, send the proper FTP command */
-
- /* get a plain printable version of the numerical address to work with
- below */
- Curl_printable_address(ai, myhost, sizeof(myhost));
-
-#ifdef PF_INET6
- if(!conn->bits.ftp_use_eprt && conn->bits.ipv6)
- /* EPRT is disabled but we are connected to a IPv6 host, so we ignore the
- request and enable EPRT again! */
- conn->bits.ftp_use_eprt = TRUE;
-#endif
-
- for (; fcmd != DONE; fcmd++) {
-
- if(!conn->bits.ftp_use_eprt && (EPRT == fcmd))
- /* if disabled, goto next */
- continue;
-
- switch (sa->sa_family) {
- case AF_INET:
- port = ntohs(((struct sockaddr_in *)sa)->sin_port);
- break;
- case AF_INET6:
- port = ntohs(((struct sockaddr_in6 *)sa)->sin6_port);
- break;
- default:
- break;
- }
-
- if (EPRT == fcmd) {
- /*
- * Two fine examples from RFC2428;
- *
- * EPRT |1|132.235.1.2|6275|
- *
- * EPRT |2|1080::8:800:200C:417A|5282|
- */
-
- result = Curl_nbftpsendf(conn, "%s |%d|%s|%d|", mode[fcmd],
- ai->ai_family == AF_INET?1:2,
- myhost, port);
- if(result)
- return result;
- break;
- }
- else if (PORT == fcmd) {
- char *source = myhost;
- char *dest = tmp;
-
- if ((PORT == fcmd) && ai->ai_family != AF_INET)
- continue;
-
- /* translate x.x.x.x to x,x,x,x */
- while(source && *source) {
- if(*source == '.')
- *dest=',';
- else
- *dest = *source;
- dest++;
- source++;
- }
- *dest = 0;
- snprintf(dest, 20, ",%d,%d", port>>8, port&0xff);
-
- result = Curl_nbftpsendf(conn, "%s %s", mode[fcmd], tmp);
- if(result)
- return result;
- break;
- }
- }
-
- /* store which command was sent */
- ftpc->count1 = fcmd;
-
- /* we set the secondary socket variable to this for now, it is only so that
- the cleanup function will close it in case we fail before the true
- secondary stuff is made */
- if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
- sclose(conn->sock[SECONDARYSOCKET]);
- conn->sock[SECONDARYSOCKET] = portsock;
-
-#else
- /******************************************************************
- * IPv4-specific section
- */
- struct sockaddr_in sa;
- unsigned short porttouse;
- bool sa_filled_in = FALSE;
- Curl_addrinfo *addr = NULL;
- unsigned short ip[4];
- bool freeaddr = TRUE;
- socklen_t sslen = sizeof(sa);
-
- (void)fcmd; /* not used in the IPv4 code */
- if(data->set.ftpport) {
- in_addr_t in;
-
- /* First check if the given name is an IP address */
- in=inet_addr(data->set.ftpport);
-
- if(in != CURL_INADDR_NONE)
- /* this is an IPv4 address */
- addr = Curl_ip2addr(in, data->set.ftpport, 0);
- else {
- if(Curl_if2ip(data->set.ftpport, myhost, sizeof(myhost))) {
- /* The interface to IP conversion provided a dotted address */
- in=inet_addr(myhost);
- addr = Curl_ip2addr(in, myhost, 0);
- }
- else if(strlen(data->set.ftpport)> 1) {
- /* might be a host name! */
- struct Curl_dns_entry *h=NULL;
- int rc = Curl_resolv(conn, data->set.ftpport, 0, &h);
- if(rc == CURLRESOLV_PENDING)
- /* BLOCKING */
- rc = Curl_wait_for_resolv(conn, &h);
- if(h) {
- addr = h->addr;
- /* when we return from this function, we can forget about this entry
- so we can unlock it now already */
- Curl_resolv_unlock(data, h);
-
- freeaddr = FALSE; /* make sure we don't free 'addr' in this function
- since it points to a DNS cache entry! */
- } /* (h) */
- else {
- infof(data, "Failed to resolve host name %s\n", data->set.ftpport);
- }
- } /* strlen */
- } /* CURL_INADDR_NONE */
- } /* data->set.ftpport */
-
- if(!addr) {
- /* pick a suitable default here */
-
- if (getsockname(conn->sock[FIRSTSOCKET],
- (struct sockaddr *)&sa, &sslen)) {
- failf(data, "getsockname() failed: %s",
- Curl_strerror(conn, Curl_sockerrno()) );
- return CURLE_FTP_PORT_FAILED;
- }
- if (sslen > (socklen_t)sizeof(sa))
- sslen = sizeof(sa);
-
- sa_filled_in = TRUE; /* the sa struct is filled in */
- }
-
- if (addr || sa_filled_in) {
- portsock = socket(AF_INET, SOCK_STREAM, 0);
- if(CURL_SOCKET_BAD != portsock) {
-
- /* we set the secondary socket variable to this for now, it
- is only so that the cleanup function will close it in case
- we fail before the true secondary stuff is made */
- if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
- sclose(conn->sock[SECONDARYSOCKET]);
- conn->sock[SECONDARYSOCKET] = portsock;
-
- if(!sa_filled_in) {
- memcpy(&sa, addr->ai_addr, sslen);
- sa.sin_addr.s_addr = INADDR_ANY;
- }
-
- sa.sin_port = 0;
- sslen = sizeof(sa);
-
- if(bind(portsock, (struct sockaddr *)&sa, sslen) == 0) {
- /* we succeeded to bind */
- struct sockaddr_in add;
- socklen_t socksize = sizeof(add);
-
- if(getsockname(portsock, (struct sockaddr *) &add,
- &socksize)) {
- failf(data, "getsockname() failed: %s",
- Curl_strerror(conn, Curl_sockerrno()) );
- return CURLE_FTP_PORT_FAILED;
- }
- porttouse = ntohs(add.sin_port);
-
- if ( listen(portsock, 1) < 0 ) {
- failf(data, "listen(2) failed on socket");
- return CURLE_FTP_PORT_FAILED;
- }
- }
- else {
- failf(data, "bind(2) failed on socket");
- return CURLE_FTP_PORT_FAILED;
- }
- }
- else {
- failf(data, "socket(2) failed (%s)");
- return CURLE_FTP_PORT_FAILED;
- }
- }
- else {
- failf(data, "couldn't find IP address to use");
- return CURLE_FTP_PORT_FAILED;
- }
-
- if(sa_filled_in)
- Curl_inet_ntop(AF_INET, &((struct sockaddr_in *)&sa)->sin_addr,
- myhost, sizeof(myhost));
- else
- Curl_printable_address(addr, myhost, sizeof(myhost));
-
- if(4 == sscanf(myhost, "%hu.%hu.%hu.%hu",
- &ip[0], &ip[1], &ip[2], &ip[3])) {
-
- infof(data, "Telling server to connect to %d.%d.%d.%d:%d\n",
- ip[0], ip[1], ip[2], ip[3], porttouse);
-
- result=Curl_nbftpsendf(conn, "PORT %d,%d,%d,%d,%d,%d",
- ip[0], ip[1], ip[2], ip[3],
- porttouse >> 8, porttouse & 255);
- if(result)
- return result;
- }
- else
- return CURLE_FTP_PORT_FAILED;
-
- if(freeaddr)
- Curl_freeaddrinfo(addr);
-
- ftpc->count1 = PORT;
-
-#endif /* end of ipv4-specific code */
-
- /* this tcpconnect assignment below is a hackish work-around to make the
- multi interface with active FTP work - as it will not wait for a
- (passive) connect in Curl_is_connected().
-
- The *proper* fix is to make sure that the active connection from the
- server is done in a non-blocking way. Currently, it is still BLOCKING.
- */
- conn->bits.tcpconnect = TRUE;
-
- state(conn, FTP_PORT);
- return result;
-}
-
-static CURLcode ftp_state_use_pasv(struct connectdata *conn)
-{
- struct ftp_conn *ftpc = &conn->proto.ftpc;
- CURLcode result = CURLE_OK;
- /*
- Here's the excecutive summary on what to do:
-
- PASV is RFC959, expect:
- 227 Entering Passive Mode (a1,a2,a3,a4,p1,p2)
-
- LPSV is RFC1639, expect:
- 228 Entering Long Passive Mode (4,4,a1,a2,a3,a4,2,p1,p2)
-
- EPSV is RFC2428, expect:
- 229 Entering Extended Passive Mode (|||port|)
-
- */
-
- const char *mode[] = { "EPSV", "PASV", NULL };
- int modeoff;
-
-#ifdef PF_INET6
- if(!conn->bits.ftp_use_epsv && conn->bits.ipv6)
- /* EPSV is disabled but we are connected to a IPv6 host, so we ignore the
- request and enable EPSV again! */
- conn->bits.ftp_use_epsv = TRUE;
-#endif
-
- modeoff = conn->bits.ftp_use_epsv?0:1;
-
- result = Curl_nbftpsendf(conn, "%s", mode[modeoff]);
- if(result)
- return result;
-
- ftpc->count1 = modeoff;
- state(conn, FTP_PASV);
- infof(conn->data, "Connect data stream passively\n");
-
- return result;
-}
-
-/* REST is the last command in the chain of commands when a "head"-like
- request is made. Thus, if an actual transfer is to be made this is where
- we take off for real. */
-static CURLcode ftp_state_post_rest(struct connectdata *conn)
-{
- CURLcode result = CURLE_OK;
- struct FTP *ftp = conn->data->reqdata.proto.ftp;
- struct SessionHandle *data = conn->data;
-
- if(ftp->no_transfer || conn->bits.no_body) {
- /* doesn't transfer any data */
- ftp->no_transfer = TRUE;
-
- /* still possibly do PRE QUOTE jobs */
- state(conn, FTP_RETR_PREQUOTE);
- result = ftp_state_quote(conn, TRUE, FTP_RETR_PREQUOTE);
- }
- else if(data->set.ftp_use_port) {
- /* We have chosen to use the PORT (or similar) command */
- result = ftp_state_use_port(conn, EPRT);
- }
- else {
- /* We have chosen (this is default) to use the PASV (or similar) command */
- result = ftp_state_use_pasv(conn);
- }
- return result;
-}
-
-static CURLcode ftp_state_post_size(struct connectdata *conn)
-{
- CURLcode result = CURLE_OK;
- struct FTP *ftp = conn->data->reqdata.proto.ftp;
-
- if(ftp->no_transfer) {
- /* if a "head"-like request is being made */
-
- /* Determine if server can respond to REST command and therefore
- whether it supports range */
- NBFTPSENDF(conn, "REST %d", 0);
-
- state(conn, FTP_REST);
- }
- else
- result = ftp_state_post_rest(conn);
-
- return result;
-}
-
-static CURLcode ftp_state_post_type(struct connectdata *conn)
-{
- CURLcode result = CURLE_OK;
- struct FTP *ftp = conn->data->reqdata.proto.ftp;
-
- if(ftp->no_transfer) {
- /* if a "head"-like request is being made */
-
- /* we know ftp->file is a valid pointer to a file name */
- NBFTPSENDF(conn, "SIZE %s", ftp->file);
-
- state(conn, FTP_SIZE);
- }
- else
- result = ftp_state_post_size(conn);
-
- return result;
-}
-
-static CURLcode ftp_state_post_listtype(struct connectdata *conn)
-{
- CURLcode result = CURLE_OK;
- struct SessionHandle *data = conn->data;
-
- /* If this output is to be machine-parsed, the NLST command might be better
- to use, since the LIST command output is not specified or standard in any
- way. It has turned out that the NLST list output is not the same on all
- servers either... */
-
- NBFTPSENDF(conn, "%s",
- data->set.customrequest?data->set.customrequest:
- (data->set.ftp_list_only?"NLST":"LIST"));
-
- state(conn, FTP_LIST);
-
- return result;
-}
-
-static CURLcode ftp_state_post_retrtype(struct connectdata *conn)
-{
- CURLcode result = CURLE_OK;
-
- /* We've sent the TYPE, now we must send the list of prequote strings */
-
- result = ftp_state_quote(conn, TRUE, FTP_RETR_PREQUOTE);
-
- return result;
-}
-
-static CURLcode ftp_state_post_stortype(struct connectdata *conn)
-{
- CURLcode result = CURLE_OK;
-
- /* We've sent the TYPE, now we must send the list of prequote strings */
-
- result = ftp_state_quote(conn, TRUE, FTP_STOR_PREQUOTE);
-
- return result;
-}
-
-static CURLcode ftp_state_post_mdtm(struct connectdata *conn)
-{
- CURLcode result = CURLE_OK;
- struct FTP *ftp = conn->data->reqdata.proto.ftp;
- struct SessionHandle *data = conn->data;
-
- /* If we have selected NOBODY and HEADER, it means that we only want file
- information. Which in FTP can't be much more than the file size and
- date. */
- if(conn->bits.no_body && data->set.include_header && ftp->file &&
- ftp_need_type(conn, data->set.prefer_ascii)) {
- /* The SIZE command is _not_ RFC 959 specified, and therefor many servers
- may not support it! It is however the only way we have to get a file's
- size! */
-
- ftp->no_transfer = TRUE; /* this means no actual transfer will be made */
-
- /* Some servers return different sizes for different modes, and thus we
- must set the proper type before we check the size */
- result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_TYPE);
- if (result)
- return result;
- }
- else
- result = ftp_state_post_type(conn);
-
- return result;
-}
-
-/* This is called after the CWD commands have been done in the beginning of
- the DO phase */
-static CURLcode ftp_state_post_cwd(struct connectdata *conn)
-{
- CURLcode result = CURLE_OK;
- struct FTP *ftp = conn->data->reqdata.proto.ftp;
- struct SessionHandle *data = conn->data;
-
- /* Requested time of file or time-depended transfer? */
- if((data->set.get_filetime || data->set.timecondition) && ftp->file) {
-
- /* we have requested to get the modified-time of the file, this is a white
- spot as the MDTM is not mentioned in RFC959 */
- NBFTPSENDF(conn, "MDTM %s", ftp->file);
-
- state(conn, FTP_MDTM);
- }
- else
- result = ftp_state_post_mdtm(conn);
-
- return result;
-}
-
-
-/* This is called after the TYPE and possible quote commands have been sent */
-static CURLcode ftp_state_ul_setup(struct connectdata *conn,
- bool sizechecked)
-{
- CURLcode result = CURLE_OK;
- struct FTP *ftp = conn->data->reqdata.proto.ftp;
- struct SessionHandle *data = conn->data;
- curl_off_t passed=0;
-
- if((data->reqdata.resume_from && !sizechecked) ||
- ((data->reqdata.resume_from > 0) && sizechecked)) {
- /* we're about to continue the uploading of a file */
- /* 1. get already existing file's size. We use the SIZE command for this
- which may not exist in the server! The SIZE command is not in
- RFC959. */
-
- /* 2. This used to set REST. But since we can do append, we
- don't another ftp command. We just skip the source file
- offset and then we APPEND the rest on the file instead */
-
- /* 3. pass file-size number of bytes in the source file */
- /* 4. lower the infilesize counter */
- /* => transfer as usual */
-
- if(data->reqdata.resume_from < 0 ) {
- /* Got no given size to start from, figure it out */
- NBFTPSENDF(conn, "SIZE %s", ftp->file);
- state(conn, FTP_STOR_SIZE);
- return result;
- }
-
- /* enable append */
- data->set.ftp_append = TRUE;
-
- /* Let's read off the proper amount of bytes from the input. If we knew it
- was a proper file we could've just fseek()ed but we only have a stream
- here */
-
- /* TODO: allow the ioctlfunction to provide a fast forward function that
- can be used here and use this method only as a fallback! */
- do {
- curl_off_t readthisamountnow = (data->reqdata.resume_from - passed);
- curl_off_t actuallyread;
-
- if(readthisamountnow > BUFSIZE)
- readthisamountnow = BUFSIZE;
-
- actuallyread = (curl_off_t)
- conn->fread(data->state.buffer, 1, (size_t)readthisamountnow,
- conn->fread_in);
-
- passed += actuallyread;
- if(actuallyread != readthisamountnow) {
- failf(data, "Could only read %" FORMAT_OFF_T
- " bytes from the input", passed);
- return CURLE_FTP_COULDNT_USE_REST;
- }
- } while(passed != data->reqdata.resume_from);
-
- /* now, decrease the size of the read */
- if(data->set.infilesize>0) {
- data->set.infilesize -= data->reqdata.resume_from;
-
- if(data->set.infilesize <= 0) {
- infof(data, "File already completely uploaded\n");
-
- /* no data to transfer */
- result=Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
-
- /* Set no_transfer so that we won't get any error in
- * Curl_ftp_done() because we didn't transfer anything! */
- ftp->no_transfer = TRUE;
-
- state(conn, FTP_STOP);
- return CURLE_OK;
- }
- }
- /* we've passed, proceed as normal */
- } /* resume_from */
-
- NBFTPSENDF(conn, data->set.ftp_append?"APPE %s":"STOR %s",
- ftp->file);
-
- state(conn, FTP_STOR);
-
- return result;
-}
-
-static CURLcode ftp_state_quote(struct connectdata *conn,
- bool init,
- ftpstate instate)
-{
- CURLcode result = CURLE_OK;
- struct SessionHandle *data = conn->data;
- struct FTP *ftp = data->reqdata.proto.ftp;
- struct ftp_conn *ftpc = &conn->proto.ftpc;
- bool quote=FALSE;
- struct curl_slist *item;
-
- switch(instate) {
- case FTP_QUOTE:
- default:
- item = data->set.quote;
- break;
- case FTP_RETR_PREQUOTE:
- case FTP_STOR_PREQUOTE:
- item = data->set.prequote;
- break;
- case FTP_POSTQUOTE:
- item = data->set.postquote;
- break;
- }
-
- if(init)
- ftpc->count1 = 0;
- else
- ftpc->count1++;
-
- if(item) {
- int i = 0;
-
- /* Skip count1 items in the linked list */
- while((i< ftpc->count1) && item) {
- item = item->next;
- i++;
- }
- if(item) {
- NBFTPSENDF(conn, "%s", item->data);
- state(conn, instate);
- quote = TRUE;
- }
- }
-
- if(!quote) {
- /* No more quote to send, continue to ... */
- switch(instate) {
- case FTP_QUOTE:
- default:
- result = ftp_state_cwd(conn);
- break;
- case FTP_RETR_PREQUOTE:
- if (ftp->no_transfer)
- state(conn, FTP_STOP);
- else {
- NBFTPSENDF(conn, "SIZE %s", ftp->file);
- state(conn, FTP_RETR_SIZE);
- }
- break;
- case FTP_STOR_PREQUOTE:
- result = ftp_state_ul_setup(conn, FALSE);
- break;
- case FTP_POSTQUOTE:
- break;
- }
- }
-
- return result;
-}
-
-static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
- int ftpcode)
-{
- struct ftp_conn *ftpc = &conn->proto.ftpc;
- CURLcode result;
- struct SessionHandle *data=conn->data;
- Curl_addrinfo *conninfo;
- struct Curl_dns_entry *addr=NULL;
- int rc;
- unsigned short connectport; /* the local port connect() should use! */
- unsigned short newport=0; /* remote port */
- bool connected;
-
- /* newhost must be able to hold a full IP-style address in ASCII, which
- in the IPv6 case means 5*8-1 = 39 letters */
-#define NEWHOST_BUFSIZE 48
- char newhost[NEWHOST_BUFSIZE];
- char *str=&data->state.buffer[4]; /* start on the first letter */
-
- if((ftpc->count1 == 0) &&
- (ftpcode == 229)) {
- /* positive EPSV response */
- char *ptr = strchr(str, '(');
- if(ptr) {
- unsigned int num;
- char separator[4];
- ptr++;
- if(5 == sscanf(ptr, "%c%c%c%u%c",
- &separator[0],
- &separator[1],
- &separator[2],
- &num,
- &separator[3])) {
- const char sep1 = separator[0];
- int i;
-
- /* The four separators should be identical, or else this is an oddly
- formatted reply and we bail out immediately. */
- for(i=1; i<4; i++) {
- if(separator[i] != sep1) {
- ptr=NULL; /* set to NULL to signal error */
- break;
- }
- }
- if(ptr) {
- newport = num;
-
- if (conn->bits.tunnel_proxy)
- /* proxy tunnel -> use other host info because ip_addr_str is the
- proxy address not the ftp host */
- snprintf(newhost, sizeof(newhost), "%s", conn->host.name);
- else
- /* use the same IP we are already connected to */
- snprintf(newhost, NEWHOST_BUFSIZE, "%s", conn->ip_addr_str);
- }
- }
- else
- ptr=NULL;
- }
- if(!ptr) {
- failf(data, "Weirdly formatted EPSV reply");
- return CURLE_FTP_WEIRD_PASV_REPLY;
- }
- }
- else if((ftpc->count1 == 1) &&
- (ftpcode == 227)) {
- /* positive PASV response */
- int ip[4];
- int port[2];
-
- /*
- * Scan for a sequence of six comma-separated numbers and use them as
- * IP+port indicators.
- *
- * Found reply-strings include:
- * "227 Entering Passive Mode (127,0,0,1,4,51)"
- * "227 Data transfer will passively listen to 127,0,0,1,4,51"
- * "227 Entering passive mode. 127,0,0,1,4,51"
- */
- while(*str) {
- if (6 == sscanf(str, "%d,%d,%d,%d,%d,%d",
- &ip[0], &ip[1], &ip[2], &ip[3],
- &port[0], &port[1]))
- break;
- str++;
- }
-
- if(!*str) {
- failf(data, "Couldn't interpret the 227-response");
- return CURLE_FTP_WEIRD_227_FORMAT;
- }
-
- /* we got OK from server */
- if(data->set.ftp_skip_ip) {
- /* told to ignore the remotely given IP but instead use the one we used
- for the control connection */
- infof(data, "Skips %d.%d.%d.%d for data connection, uses %s instead\n",
- ip[0], ip[1], ip[2], ip[3],
- conn->ip_addr_str);
- if (conn->bits.tunnel_proxy)
- /* proxy tunnel -> use other host info because ip_addr_str is the
- proxy address not the ftp host */
- snprintf(newhost, sizeof(newhost), "%s", conn->host.name);
- else
- snprintf(newhost, sizeof(newhost), "%s", conn->ip_addr_str);
- }
- else
- snprintf(newhost, sizeof(newhost),
- "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
- newport = (port[0]<<8) + port[1];
- }
- else if(ftpc->count1 == 0) {
- /* EPSV failed, move on to PASV */
-
- /* disable it for next transfer */
- conn->bits.ftp_use_epsv = FALSE;
- infof(data, "disabling EPSV usage\n");
-
- NBFTPSENDF(conn, "PASV", NULL);
- ftpc->count1++;
- /* remain in the FTP_PASV state */
- return result;
- }
- else {
- failf(data, "Bad PASV/EPSV response: %03d", ftpcode);
- return CURLE_FTP_WEIRD_PASV_REPLY;
- }
-
- if(data->set.proxy && *data->set.proxy) {
- /*
- * This is a tunnel through a http proxy and we need to connect to the
- * proxy again here.
- *
- * We don't want to rely on a former host lookup that might've expired
- * now, instead we remake the lookup here and now!
- */
- rc = Curl_resolv(conn, conn->proxy.name, (int)conn->port, &addr);
- if(rc == CURLRESOLV_PENDING)
- /* BLOCKING */
- rc = Curl_wait_for_resolv(conn, &addr);
-
- connectport =
- (unsigned short)conn->port; /* we connect to the proxy's port */
-
- }
- else {
- /* normal, direct, ftp connection */
- rc = Curl_resolv(conn, newhost, newport, &addr);
- if(rc == CURLRESOLV_PENDING)
- /* BLOCKING */
- rc = Curl_wait_for_resolv(conn, &addr);
-
- if(!addr) {
- failf(data, "Can't resolve new host %s:%d", newhost, newport);
- return CURLE_FTP_CANT_GET_HOST;
- }
- connectport = newport; /* we connect to the remote port */
- }
-
- result = Curl_connecthost(conn,
- addr,
- &conn->sock[SECONDARYSOCKET],
- &conninfo,
- &connected);
-
- Curl_resolv_unlock(data, addr); /* we're done using this address */
-
- if (result && ftpc->count1 == 0 && ftpcode == 229) {
- infof(data, "got positive EPSV response, but can't connect. "
- "Disabling EPSV\n");
- /* disable it for next transfer */
- conn->bits.ftp_use_epsv = FALSE;
- data->state.errorbuf = FALSE; /* allow error message to get rewritten */
- NBFTPSENDF(conn, "PASV", NULL);
- ftpc->count1++;
- /* remain in the FTP_PASV state */
- return result;
- }
-
- if(result)
- return result;
-
- conn->bits.tcpconnect = connected; /* simply TRUE or FALSE */
-
- /*
- * When this is used from the multi interface, this might've returned with
- * the 'connected' set to FALSE and thus we are now awaiting a non-blocking
- * connect to connect and we should not be "hanging" here waiting.
- */
-
- if(data->set.verbose)
- /* this just dumps information about this second connection */
- ftp_pasv_verbose(conn, conninfo, newhost, connectport);
-
-#ifndef CURL_DISABLE_HTTP
- if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
- /* FIX: this MUST wait for a proper connect first if 'connected' is
- * FALSE */
-
- /* BLOCKING */
- /* We want "seamless" FTP operations through HTTP proxy tunnel */
-
- /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the member
- * conn->proto.http; we want FTP through HTTP and we have to change the
- * member temporarily for connecting to the HTTP proxy. After
- * Curl_proxyCONNECT we have to set back the member to the original struct
- * FTP pointer
- */
- struct HTTP http_proxy;
- struct FTP *ftp_save = data->reqdata.proto.ftp;
- memset(&http_proxy, 0, sizeof(http_proxy));
- data->reqdata.proto.http = &http_proxy;
-
- result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, newhost, newport);
-
- data->reqdata.proto.ftp = ftp_save;
-
- if(CURLE_OK != result)
- return result;
- }
-#endif /* CURL_DISABLE_HTTP */
-
- state(conn, FTP_STOP); /* this phase is completed */
-
- return result;
-}
-
-static CURLcode ftp_state_port_resp(struct connectdata *conn,
- int ftpcode)
-{
- struct SessionHandle *data = conn->data;
- struct ftp_conn *ftpc = &conn->proto.ftpc;
- ftpport fcmd = (ftpport)ftpc->count1;
- CURLcode result = CURLE_OK;
-
- if(ftpcode != 200) {
- /* the command failed */
-
- if (EPRT == fcmd) {
- infof(data, "disabling EPRT usage\n");
- conn->bits.ftp_use_eprt = FALSE;
- }
- fcmd++;
-
- if(fcmd == DONE) {
- failf(data, "Failed to do PORT");
- result = CURLE_FTP_PORT_FAILED;
- }
- else
- /* try next */
- result = ftp_state_use_port(conn, fcmd);
- }
- else {
- infof(data, "Connect data stream actively\n");
- state(conn, FTP_STOP); /* end of DO phase */
- }
-
- return result;
-}
-
-static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
- int ftpcode)
-{
- CURLcode result = CURLE_OK;
- struct SessionHandle *data=conn->data;
- struct FTP *ftp = data->reqdata.proto.ftp;
-
- switch(ftpcode) {
- case 213:
- {
- /* we got a time. Format should be: "YYYYMMDDHHMMSS[.sss]" where the
- last .sss part is optional and means fractions of a second */
- int year, month, day, hour, minute, second;
- char *buf = data->state.buffer;
- if(6 == sscanf(buf+4, "%04d%02d%02d%02d%02d%02d",
- &year, &month, &day, &hour, &minute, &second)) {
- /* we have a time, reformat it */
- time_t secs=time(NULL);
- /* using the good old yacc/bison yuck */
- snprintf(buf, sizeof(conn->data->state.buffer),
- "%04d%02d%02d %02d:%02d:%02d GMT",
- year, month, day, hour, minute, second);
- /* now, convert this into a time() value: */
- data->info.filetime = (long)curl_getdate(buf, &secs);
- }
-
- /* If we asked for a time of the file and we actually got one as well,
- we "emulate" a HTTP-style header in our output. */
-
- if(conn->bits.no_body &&
- data->set.include_header &&
- ftp->file &&
- data->set.get_filetime &&
- (data->info.filetime>=0) ) {
- struct tm *tm;
- time_t clock = (time_t)data->info.filetime;
-#ifdef HAVE_GMTIME_R
- struct tm buffer;
- tm = (struct tm *)gmtime_r(&clock, &buffer);
-#else
- tm = gmtime(&clock);
-#endif
- /* format: "Tue, 15 Nov 1994 12:45:26" */
- snprintf(buf, BUFSIZE-1,
- "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
- Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
- tm->tm_mday,
- Curl_month[tm->tm_mon],
- tm->tm_year + 1900,
- tm->tm_hour,
- tm->tm_min,
- tm->tm_sec);
- result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
- if(result)
- return result;
- } /* end of a ridiculous amount of conditionals */
- }
- break;
- default:
- infof(data, "unsupported MDTM reply format\n");
- break;
- case 550: /* "No such file or directory" */
- failf(data, "Given file does not exist");
- result = CURLE_FTP_COULDNT_RETR_FILE;
- break;
- }
-
- if(data->set.timecondition) {
- if((data->info.filetime > 0) && (data->set.timevalue > 0)) {
- switch(data->set.timecondition) {
- case CURL_TIMECOND_IFMODSINCE:
- default:
- if(data->info.filetime <= data->set.timevalue) {
- infof(data, "The requested document is not new enough\n");
- ftp->no_transfer = TRUE; /* mark this to not transfer data */
- state(conn, FTP_STOP);
- return CURLE_OK;
- }
- break;
- case CURL_TIMECOND_IFUNMODSINCE:
- if(data->info.filetime > data->set.timevalue) {
- infof(data, "The requested document is not old enough\n");
- ftp->no_transfer = TRUE; /* mark this to not transfer data */
- state(conn, FTP_STOP);
- return CURLE_OK;
- }
- break;
- } /* switch */
- }
- else {
- infof(data, "Skipping time comparison\n");
- }
- }
-
- if(!result)
- result = ftp_state_post_mdtm(conn);
-
- return result;
-}
-
-static CURLcode ftp_state_type_resp(struct connectdata *conn,
- int ftpcode,
- ftpstate instate)
-{
- CURLcode result = CURLE_OK;
- struct SessionHandle *data=conn->data;
-
- if(ftpcode/100 != 2) {
- /* "sasserftpd" and "(u)r(x)bot ftpd" both responds with 226 after a
- successful 'TYPE I'. While that is not as RFC959 says, it is still a
- positive response code and we allow that. */
- failf(data, "Couldn't set desired mode");
- return CURLE_FTP_COULDNT_SET_BINARY; /* FIX */
- }
- if(ftpcode != 200)
- infof(data, "Got a %03d response code instead of the assumed 200\n",
- ftpcode);
-
- if(instate == FTP_TYPE)
- result = ftp_state_post_type(conn);
- else if(instate == FTP_LIST_TYPE)
- result = ftp_state_post_listtype(conn);
- else if(instate == FTP_RETR_TYPE)
- result = ftp_state_post_retrtype(conn);
- else if(instate == FTP_STOR_TYPE)
- result = ftp_state_post_stortype(conn);
-
- return result;
-}
-
-static CURLcode ftp_state_post_retr_size(struct connectdata *conn,
- curl_off_t filesize)
-{
- CURLcode result = CURLE_OK;
- struct SessionHandle *data=conn->data;
- struct FTP *ftp = data->reqdata.proto.ftp;
-
- if (data->set.max_filesize && (filesize > data->set.max_filesize)) {
- failf(data, "Maximum file size exceeded");
- return CURLE_FILESIZE_EXCEEDED;
- }
- ftp->downloadsize = filesize;
-
- if(data->reqdata.resume_from) {
- /* We always (attempt to) get the size of downloads, so it is done before
- this even when not doing resumes. */
- if(filesize == -1) {
- infof(data, "ftp server doesn't support SIZE\n");
- /* We couldn't get the size and therefore we can't know if there really
- is a part of the file left to get, although the server will just
- close the connection when we start the connection so it won't cause
- us any harm, just not make us exit as nicely. */
- }
- else {
- /* We got a file size report, so we check that there actually is a
- part of the file left to get, or else we go home. */
- if(data->reqdata.resume_from< 0) {
- /* We're supposed to download the last abs(from) bytes */
- if(filesize < -data->reqdata.resume_from) {
- failf(data, "Offset (%" FORMAT_OFF_T
- ") was beyond file size (%" FORMAT_OFF_T ")",
- data->reqdata.resume_from, filesize);
- return CURLE_BAD_DOWNLOAD_RESUME;
- }
- /* convert to size to download */
- ftp->downloadsize = -data->reqdata.resume_from;
- /* download from where? */
- data->reqdata.resume_from = filesize - ftp->downloadsize;
- }
- else {
- if(filesize < data->reqdata.resume_from) {
- failf(data, "Offset (%" FORMAT_OFF_T
- ") was beyond file size (%" FORMAT_OFF_T ")",
- data->reqdata.resume_from, filesize);
- return CURLE_BAD_DOWNLOAD_RESUME;
- }
- /* Now store the number of bytes we are expected to download */
- ftp->downloadsize = filesize-data->reqdata.resume_from;
- }
- }
-
- if(ftp->downloadsize == 0) {
- /* no data to transfer */
- result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
- infof(data, "File already completely downloaded\n");
-
- /* Set no_transfer so that we won't get any error in Curl_ftp_done()
- * because we didn't transfer the any file */
- ftp->no_transfer = TRUE;
- state(conn, FTP_STOP);
- return CURLE_OK;
- }
-
- /* Set resume file transfer offset */
- infof(data, "Instructs server to resume from offset %" FORMAT_OFF_T
- "\n", data->reqdata.resume_from);
-
- NBFTPSENDF(conn, "REST %" FORMAT_OFF_T, data->reqdata.resume_from);
-
- state(conn, FTP_RETR_REST);
-
- }
- else {
- /* no resume */
- NBFTPSENDF(conn, "RETR %s", ftp->file);
- state(conn, FTP_RETR);
- }
-
- return result;
-}
-
-static CURLcode ftp_state_size_resp(struct connectdata *conn,
- int ftpcode,
- ftpstate instate)
-{
- CURLcode result = CURLE_OK;
- struct SessionHandle *data=conn->data;
- curl_off_t filesize;
- char *buf = data->state.buffer;
-
- /* get the size from the ascii string: */
- filesize = (ftpcode == 213)?curlx_strtoofft(buf+4, NULL, 0):-1;
-
- if(instate == FTP_SIZE) {
- if(-1 != filesize) {
- snprintf(buf, sizeof(data->state.buffer),
- "Content-Length: %" FORMAT_OFF_T "\r\n", filesize);
- result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
- if(result)
- return result;
- }
- result = ftp_state_post_size(conn);
- }
- else if(instate == FTP_RETR_SIZE)
- result = ftp_state_post_retr_size(conn, filesize);
- else if(instate == FTP_STOR_SIZE) {
- data->reqdata.resume_from = filesize;
- result = ftp_state_ul_setup(conn, TRUE);
- }
-
- return result;
-}
-
-static CURLcode ftp_state_rest_resp(struct connectdata *conn,
- int ftpcode,
- ftpstate instate)
-{
- CURLcode result = CURLE_OK;
- struct FTP *ftp = conn->data->reqdata.proto.ftp;
-
- switch(instate) {
- case FTP_REST:
- default:
- if (ftpcode == 350) {
- result = Curl_client_write(conn, CLIENTWRITE_BOTH,
- (char *)"Accept-ranges: bytes\r\n", 0);
- if(result)
- return result;
- }
-
- result = ftp_state_post_rest(conn);
- break;
-
- case FTP_RETR_REST:
- if (ftpcode != 350) {
- failf(conn->data, "Couldn't use REST");
- result = CURLE_FTP_COULDNT_USE_REST;
- }
- else {
- NBFTPSENDF(conn, "RETR %s", ftp->file);
- state(conn, FTP_RETR);
- }
- break;
- }
-
- return result;
-}
-
-static CURLcode ftp_state_stor_resp(struct connectdata *conn,
- int ftpcode)
-{
- CURLcode result = CURLE_OK;
- struct SessionHandle *data = conn->data;
- struct FTP *ftp = data->reqdata.proto.ftp;
-
- if(ftpcode>=400) {
- failf(data, "Failed FTP upload: %0d", ftpcode);
- /* oops, we never close the sockets! */
- return CURLE_FTP_COULDNT_STOR_FILE;
- }
-
- if(data->set.ftp_use_port) {
- /* BLOCKING */
- /* PORT means we are now awaiting the server to connect to us. */
- result = AllowServerConnect(conn);
- if( result )
- return result;
- }
-
- if(conn->ssl[SECONDARYSOCKET].use) {
- /* since we only have a plaintext TCP connection here, we must now
- do the TLS stuff */
- infof(data, "Doing the SSL/TLS handshake on the data stream\n");
- /* BLOCKING */
- result = Curl_ssl_connect(conn, SECONDARYSOCKET);
- if(result)
- return result;
- }
-
- *(ftp->bytecountp)=0;
-
- /* When we know we're uploading a specified file, we can get the file
- size prior to the actual upload. */
-
- Curl_pgrsSetUploadSize(data, data->set.infilesize);
-
- result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
- SECONDARYSOCKET, ftp->bytecountp);
- state(conn, FTP_STOP);
-
- return result;
-}
-
-/* for LIST and RETR responses */
-static CURLcode ftp_state_get_resp(struct connectdata *conn,
- int ftpcode,
- ftpstate instate)
-{
- CURLcode result = CURLE_OK;
- struct SessionHandle *data = conn->data;
- struct FTP *ftp = data->reqdata.proto.ftp;
- char *buf = data->state.buffer;
-
- if((ftpcode == 150) || (ftpcode == 125)) {
-
- /*
- A;
- 150 Opening BINARY mode data connection for /etc/passwd (2241
- bytes). (ok, the file is being transfered)
-
- B:
- 150 Opening ASCII mode data connection for /bin/ls
-
- C:
- 150 ASCII data connection for /bin/ls (137.167.104.91,37445) (0 bytes).
-
- D:
- 150 Opening ASCII mode data connection for /linux/fisk/kpanelrc (0.0.0.0,0) (545 bytes).
-
- E:
- 125 Data connection already open; Transfer starting. */
-
- curl_off_t size=-1; /* default unknown size */
-
-
- /*
- * It appears that there are FTP-servers that return size 0 for files when
- * SIZE is used on the file while being in BINARY mode. To work around
- * that (stupid) behavior, we attempt to parse the RETR response even if
- * the SIZE returned size zero.
- *
- * Debugging help from Salvatore Sorrentino on February 26, 2003.
- */
-
- if((instate != FTP_LIST) &&
- !data->set.prefer_ascii &&
- (ftp->downloadsize < 1)) {
- /*
- * It seems directory listings either don't show the size or very
- * often uses size 0 anyway. ASCII transfers may very well turn out
- * that the transfered amount of data is not the same as this line
- * tells, why using this number in those cases only confuses us.
- *
- * Example D above makes this parsing a little tricky */
- char *bytes;
- bytes=strstr(buf, " bytes");
- if(bytes--) {
- long in=(long)(bytes-buf);
- /* this is a hint there is size information in there! ;-) */
- while(--in) {
- /* scan for the left parenthesis and break there */
- if('(' == *bytes)
- break;
- /* skip only digits */
- if(!ISDIGIT(*bytes)) {
- bytes=NULL;
- break;
- }
- /* one more estep backwards */
- bytes--;
- }
- /* if we have nothing but digits: */
- if(bytes++) {
- /* get the number! */
- size = curlx_strtoofft(bytes, NULL, 0);
- }
- }
- }
- else if(ftp->downloadsize > -1)
- size = ftp->downloadsize;
-
- if(data->set.ftp_use_port) {
- /* BLOCKING */
- result = AllowServerConnect(conn);
- if( result )
- return result;
- }
-
- if(conn->ssl[SECONDARYSOCKET].use) {
- /* since we only have a plaintext TCP connection here, we must now
- do the TLS stuff */
- infof(data, "Doing the SSL/TLS handshake on the data stream\n");
- result = Curl_ssl_connect(conn, SECONDARYSOCKET);
- if(result)
- return result;
- }
-
- if(size > data->reqdata.maxdownload && data->reqdata.maxdownload > 0)
- size = data->reqdata.size = data->reqdata.maxdownload;
-
- infof(data, "Maxdownload = %" FORMAT_OFF_T "\n", data->reqdata.maxdownload);
-
- if(instate != FTP_LIST)
- infof(data, "Getting file with size: %" FORMAT_OFF_T "\n", size);
-
- /* FTP download: */
- result=Curl_setup_transfer(conn, SECONDARYSOCKET, size, FALSE,
- ftp->bytecountp,
- -1, NULL); /* no upload here */
- if(result)
- return result;
-
- state(conn, FTP_STOP);
- }
- else {
- if((instate == FTP_LIST) && (ftpcode == 450)) {
- /* simply no matching files in the dir listing */
- ftp->no_transfer = TRUE; /* don't download anything */
- state(conn, FTP_STOP); /* this phase is over */
- }
- else {
- failf(data, "RETR response: %03d", ftpcode);
- return CURLE_FTP_COULDNT_RETR_FILE;
- }
- }
-
- return result;
-}
-
-/* after USER, PASS and ACCT */
-static CURLcode ftp_state_loggedin(struct connectdata *conn)
-{
- CURLcode result = CURLE_OK;
-
-#ifdef HAVE_KRB4
- if(conn->data->set.krb4) {
- /* We are logged in, asked to use Kerberos. Set the requested
- * protection level
- */
- if(conn->sec_complete)
- /* BLOCKING */
- Curl_sec_set_protection_level(conn);
-
- /* We may need to issue a KAUTH here to have access to the files
- * do it if user supplied a password
- */
- if(conn->passwd && *conn->passwd) {
- /* BLOCKING */
- result = Curl_krb_kauth(conn);
- if(result)
- return result;
- }
- }
-#endif
- if(conn->ssl[FIRSTSOCKET].use) {
- /* PBSZ = PROTECTION BUFFER SIZE.
-
- The 'draft-murray-auth-ftp-ssl' (draft 12, page 7) says:
-
- Specifically, the PROT command MUST be preceded by a PBSZ
- command and a PBSZ command MUST be preceded by a successful
- security data exchange (the TLS negotiation in this case)
-
- ... (and on page 8):
-
- Thus the PBSZ command must still be issued, but must have a
- parameter of '0' to indicate that no buffering is taking place
- and the data connection should not be encapsulated.
- */
- NBFTPSENDF(conn, "PBSZ %d", 0);
- state(conn, FTP_PBSZ);
- }
- else {
- result = ftp_state_pwd(conn);
- }
- return result;
-}
-
-/* for USER and PASS responses */
-static CURLcode ftp_state_user_resp(struct connectdata *conn,
- int ftpcode,
- ftpstate instate)
-{
- CURLcode result = CURLE_OK;
- struct SessionHandle *data = conn->data;
- struct FTP *ftp = data->reqdata.proto.ftp;
- struct ftp_conn *ftpc = &conn->proto.ftpc;
- (void)instate; /* no use for this yet */
-
- if((ftpcode == 331) && (ftpc->state == FTP_USER)) {
- /* 331 Password required for ...
- (the server requires to send the user's password too) */
- NBFTPSENDF(conn, "PASS %s", ftp->passwd?ftp->passwd:"");
- state(conn, FTP_PASS);
- }
- else if(ftpcode/100 == 2) {
- /* 230 User ... logged in.
- (the user logged in with or without password) */
- result = ftp_state_loggedin(conn);
- }
- else if(ftpcode == 332) {
- if(data->set.ftp_account) {
- NBFTPSENDF(conn, "ACCT %s", data->set.ftp_account);
- state(conn, FTP_ACCT);
- }
- else {
- failf(data, "ACCT requested but none available");
- result = CURLE_LOGIN_DENIED;
- }
- }
- else {
- /* All other response codes, like:
-
- 530 User ... access denied
- (the server denies to log the specified user) */
-
- if (conn->data->set.ftp_alternative_to_user &&
- !conn->data->state.ftp_trying_alternative) {
- /* Ok, USER failed. Let's try the supplied command. */
- NBFTPSENDF(conn, "%s", conn->data->set.ftp_alternative_to_user);
- conn->data->state.ftp_trying_alternative = TRUE;
- state(conn, FTP_USER);
- result = CURLE_OK;
- }
- else {
- failf(data, "Access denied: %03d", ftpcode);
- result = CURLE_LOGIN_DENIED;
- }
- }
- return result;
-}
-
-/* for ACCT response */
-static CURLcode ftp_state_acct_resp(struct connectdata *conn,
- int ftpcode)
-{
- CURLcode result = CURLE_OK;
- struct SessionHandle *data = conn->data;
- if(ftpcode != 230) {
- failf(data, "ACCT rejected by server: %03d", ftpcode);
- result = CURLE_FTP_WEIRD_PASS_REPLY; /* FIX */
- }
- else
- result = ftp_state_loggedin(conn);
-
- return result;
-}
-
-
-static CURLcode ftp_statemach_act(struct connectdata *conn)
-{
- CURLcode result;
- curl_socket_t sock = conn->sock[FIRSTSOCKET];
- struct SessionHandle *data=conn->data;
- int ftpcode;
- struct ftp_conn *ftpc = &conn->proto.ftpc;
- static const char * const ftpauth[] = {
- "SSL", "TLS"
- };
- size_t nread = 0;
-
- if(ftpc->sendleft) {
- /* we have a piece of a command still left to send */
- ssize_t written;
- result = Curl_write(conn, sock, ftpc->sendthis + ftpc->sendsize -
- ftpc->sendleft, ftpc->sendleft, &written);
- if(result)
- return result;
-
- if(written != (ssize_t)ftpc->sendleft) {
- /* only a fraction was sent */
- ftpc->sendleft -= written;
- }
- else {
- free(ftpc->sendthis);
- ftpc->sendthis=NULL;
- ftpc->sendleft = ftpc->sendsize = 0;
- ftpc->response = Curl_tvnow();
- }
- return CURLE_OK;
- }
-
- /* we read a piece of response */
- result = ftp_readresp(sock, conn, &ftpcode, &nread);
- if(result)
- return result;
-
- if(ftpcode) {
- /* we have now received a full FTP server response */
- switch(ftpc->state) {
- case FTP_WAIT220:
- if(ftpcode != 220) {
- failf(data, "This doesn't seem like a nice ftp-server response");
- return CURLE_FTP_WEIRD_SERVER_REPLY;
- }
-
- /* We have received a 220 response fine, now we proceed. */
-#ifdef HAVE_KRB4
- if(data->set.krb4) {
- /* If not anonymous login, try a secure login. Note that this
- procedure is still BLOCKING. */
-
- Curl_sec_request_prot(conn, "private");
- /* We set private first as default, in case the line below fails to
- set a valid level */
- Curl_sec_request_prot(conn, data->set.krb4_level);
-
- if(Curl_sec_login(conn) != 0)
- infof(data, "Logging in with password in cleartext!\n");
- else
- infof(data, "Authentication successful\n");
- }
-#endif
-
- if(data->set.ftp_ssl && !conn->ssl[FIRSTSOCKET].use) {
- /* We don't have a SSL/TLS connection yet, but FTPS is
- requested. Try a FTPS connection now */
-
- ftpc->count3=0;
- switch(data->set.ftpsslauth) {
- case CURLFTPAUTH_DEFAULT:
- case CURLFTPAUTH_SSL:
- ftpc->count2 = 1; /* add one to get next */
- ftpc->count1 = 0;
- break;
- case CURLFTPAUTH_TLS:
- ftpc->count2 = -1; /* subtract one to get next */
- ftpc->count1 = 1;
- break;
- default:
- failf(data, "unsupported parameter to CURLOPT_FTPSSLAUTH: %d\n",
- data->set.ftpsslauth);
- return CURLE_FAILED_INIT; /* we don't know what to do */
- }
- NBFTPSENDF(conn, "AUTH %s", ftpauth[ftpc->count1]);
- state(conn, FTP_AUTH);
- }
- else {
- result = ftp_state_user(conn);
- if(result)
- return result;
- }
-
- break;
-
- case FTP_AUTH:
- /* we have gotten the response to a previous AUTH command */
-
- /* RFC2228 (page 5) says:
- *
- * If the server is willing to accept the named security mechanism,
- * and does not require any security data, it must respond with
- * reply code 234/334.
- */
-
- if((ftpcode == 234) || (ftpcode == 334)) {
- /* Curl_ssl_connect is BLOCKING */
- result = Curl_ssl_connect(conn, FIRSTSOCKET);
- if(CURLE_OK == result) {
- conn->protocol |= PROT_FTPS;
- conn->ssl[SECONDARYSOCKET].use = FALSE; /* clear-text data */
- result = ftp_state_user(conn);
- }
- }
- else if(ftpc->count3 < 1) {
- ftpc->count3++;
- ftpc->count1 += ftpc->count2; /* get next attempt */
- result = Curl_nbftpsendf(conn, "AUTH %s", ftpauth[ftpc->count1]);
- /* remain in this same state */
- }
- else {
- if(data->set.ftp_ssl > CURLFTPSSL_TRY)
- /* we failed and CURLFTPSSL_CONTROL or CURLFTPSSL_ALL is set */
- result = CURLE_FTP_SSL_FAILED;
- else
- /* ignore the failure and continue */
- result = ftp_state_user(conn);
- }
-
- if(result)
- return result;
- break;
-
- case FTP_USER:
- case FTP_PASS:
- result = ftp_state_user_resp(conn, ftpcode, ftpc->state);
- break;
-
- case FTP_ACCT:
- result = ftp_state_acct_resp(conn, ftpcode);
- break;
-
- case FTP_PBSZ:
- /* FIX: check response code */
-
- /* For TLS, the data connection can have one of two security levels.
-
- 1) Clear (requested by 'PROT C')
-
- 2)Private (requested by 'PROT P')
- */
- if(!conn->ssl[SECONDARYSOCKET].use) {
- NBFTPSENDF(conn, "PROT %c",
- data->set.ftp_ssl == CURLFTPSSL_CONTROL ? 'C' : 'P');
- state(conn, FTP_PROT);
- }
- else {
- result = ftp_state_pwd(conn);
- if(result)
- return result;
- }
-
- break;
-
- case FTP_PROT:
- if(ftpcode/100 == 2)
- /* We have enabled SSL for the data connection! */
- conn->ssl[SECONDARYSOCKET].use =
- (bool)(data->set.ftp_ssl != CURLFTPSSL_CONTROL);
- /* FTP servers typically responds with 500 if they decide to reject
- our 'P' request */
- else if(data->set.ftp_ssl> CURLFTPSSL_CONTROL)
- /* we failed and bails out */
- return CURLE_FTP_SSL_FAILED;
-
- if(data->set.ftp_use_ccc) {
- /* CCC - Clear Command Channel
- */
- NBFTPSENDF(conn, "CCC", NULL);
- state(conn, FTP_CCC);
- }
- else {
- result = ftp_state_pwd(conn);
- if(result)
- return result;
- }
- break;
-
- case FTP_CCC:
- if (ftpcode < 500) {
- /* First shut down the SSL layer (note: this call will block) */
- result = Curl_ssl_shutdown(conn, FIRSTSOCKET);
-
- if(result) {
- failf(conn->data, "Failed to clear the command channel (CCC)");
- return result;
- }
- }
-
- /* Then continue as normal */
- result = ftp_state_pwd(conn);
- if(result)
- return result;
- break;
-
- case FTP_PWD:
- if(ftpcode == 257) {
- char *dir = (char *)malloc(nread+1);
- char *store=dir;
- char *ptr=&data->state.buffer[4]; /* start on the first letter */
-
- if(!dir)
- return CURLE_OUT_OF_MEMORY;
-
- /* Reply format is like
- 257<space>"<directory-name>"<space><commentary> and the RFC959
- says
-
- The directory name can contain any character; embedded
- double-quotes should be escaped by double-quotes (the
- "quote-doubling" convention).
- */
- if('\"' == *ptr) {
- /* it started good */
- ptr++;
- while(ptr && *ptr) {
- if('\"' == *ptr) {
- if('\"' == ptr[1]) {
- /* "quote-doubling" */
- *store = ptr[1];
- ptr++;
- }
- else {
- /* end of path */
- *store = '\0'; /* zero terminate */
- break; /* get out of this loop */
- }
- }
- else
- *store = *ptr;
- store++;
- ptr++;
- }
- ftpc->entrypath =dir; /* remember this */
- infof(data, "Entry path is '%s'\n", ftpc->entrypath);
- /* also save it where getinfo can access it: */
- data->state.most_recent_ftp_entrypath = ftpc->entrypath;
- }
- else {
- /* couldn't get the path */
- free(dir);
- infof(data, "Failed to figure out path\n");
- }
- }
- state(conn, FTP_STOP); /* we are done with the CONNECT phase! */
- DEBUGF(infof(data, "protocol connect phase DONE\n"));
- break;
-
- case FTP_QUOTE:
- case FTP_POSTQUOTE:
- case FTP_RETR_PREQUOTE:
- case FTP_STOR_PREQUOTE:
- if(ftpcode >= 400) {
- failf(conn->data, "QUOT command failed with %03d", ftpcode);
- return CURLE_FTP_QUOTE_ERROR;
- }
- result = ftp_state_quote(conn, FALSE, ftpc->state);
- if(result)
- return result;
-
- break;
-
- case FTP_CWD:
- if(ftpcode/100 != 2) {
- /* failure to CWD there */
- if(conn->data->set.ftp_create_missing_dirs &&
- ftpc->count1 && !ftpc->count2) {
- /* try making it */
- ftpc->count2++; /* counter to prevent CWD-MKD loops */
- NBFTPSENDF(conn, "MKD %s", ftpc->dirs[ftpc->count1 - 1]);
- state(conn, FTP_MKD);
- }
- else {
- /* return failure */
- failf(data, "Server denied you to change to the given directory");
- ftpc->cwdfail = TRUE; /* don't remember this path as we failed
- to enter it */
- return CURLE_FTP_ACCESS_DENIED;
- }
- }
- else {
- /* success */
- ftpc->count2=0;
- if(++ftpc->count1 <= ftpc->dirdepth) {
- /* send next CWD */
- NBFTPSENDF(conn, "CWD %s", ftpc->dirs[ftpc->count1 - 1]);
- }
- else {
- result = ftp_state_post_cwd(conn);
- if(result)
- return result;
- }
- }
- break;
-
- case FTP_MKD:
- if(ftpcode/100 != 2) {
- /* failure to MKD the dir */
- failf(data, "Failed to MKD dir: %03d", ftpcode);
- return CURLE_FTP_ACCESS_DENIED;
- }
- state(conn, FTP_CWD);
- /* send CWD */
- NBFTPSENDF(conn, "CWD %s", ftpc->dirs[ftpc->count1 - 1]);
- break;
-
- case FTP_MDTM:
- result = ftp_state_mdtm_resp(conn, ftpcode);
- break;
-
- case FTP_TYPE:
- case FTP_LIST_TYPE:
- case FTP_RETR_TYPE:
- case FTP_STOR_TYPE:
- result = ftp_state_type_resp(conn, ftpcode, ftpc->state);
- break;
-
- case FTP_SIZE:
- case FTP_RETR_SIZE:
- case FTP_STOR_SIZE:
- result = ftp_state_size_resp(conn, ftpcode, ftpc->state);
- break;
-
- case FTP_REST:
- case FTP_RETR_REST:
- result = ftp_state_rest_resp(conn, ftpcode, ftpc->state);
- break;
-
- case FTP_PASV:
- result = ftp_state_pasv_resp(conn, ftpcode);
- break;
-
- case FTP_PORT:
- result = ftp_state_port_resp(conn, ftpcode);
- break;
-
- case FTP_LIST:
- case FTP_RETR:
- result = ftp_state_get_resp(conn, ftpcode, ftpc->state);
- break;
-
- case FTP_STOR:
- result = ftp_state_stor_resp(conn, ftpcode);
- break;
-
- case FTP_QUIT:
- /* fallthrough, just stop! */
- default:
- /* internal error */
- state(conn, FTP_STOP);
- break;
- }
- } /* if(ftpcode) */
-
- return result;
-}
-
-/* Returns timeout in ms. 0 or negative number means the timeout has already
- triggered */
-static long ftp_state_timeout(struct connectdata *conn)
-{
- struct SessionHandle *data=conn->data;
- struct ftp_conn *ftpc = &conn->proto.ftpc;
- long timeout_ms=360000; /* in milliseconds */
-
- if(data->set.ftp_response_timeout )
- /* if CURLOPT_FTP_RESPONSE_TIMEOUT is set, use that to determine remaining
- time. Also, use ftp->response because FTP_RESPONSE_TIMEOUT is supposed
- to govern the response for any given ftp response, not for the time
- from connect to the given ftp response. */
- timeout_ms = data->set.ftp_response_timeout*1000 - /* timeout time */
- Curl_tvdiff(Curl_tvnow(), ftpc->response); /* spent time */
- else if(data->set.timeout)
- /* if timeout is requested, find out how much remaining time we have */
- timeout_ms = data->set.timeout*1000 - /* timeout time */
- Curl_tvdiff(Curl_tvnow(), conn->now); /* spent time */
- else
- /* Without a requested timeout, we only wait 'response_time' seconds for
- the full response to arrive before we bail out */
- timeout_ms = ftpc->response_time*1000 -
- Curl_tvdiff(Curl_tvnow(), ftpc->response); /* spent time */
-
- return timeout_ms;
-}
-
-
-/* called repeatedly until done from multi.c */
-CURLcode Curl_ftp_multi_statemach(struct connectdata *conn,
- bool *done)
-{
- curl_socket_t sock = conn->sock[FIRSTSOCKET];
- int rc;
- struct SessionHandle *data=conn->data;
- struct ftp_conn *ftpc = &conn->proto.ftpc;
- CURLcode result = CURLE_OK;
- long timeout_ms = ftp_state_timeout(conn);
-
- *done = FALSE; /* default to not done yet */
-
- if(timeout_ms <= 0) {
- failf(data, "FTP response timeout");
- return CURLE_OPERATION_TIMEDOUT;
- }
-
- rc = Curl_select(ftpc->sendleft?CURL_SOCKET_BAD:sock, /* reading */
- ftpc->sendleft?sock:CURL_SOCKET_BAD, /* writing */
- 0);
-
- if(rc == -1) {
- failf(data, "select error");
- return CURLE_OUT_OF_MEMORY;
- }
- else if(rc != 0) {
- result = ftp_statemach_act(conn);
- *done = (bool)(ftpc->state == FTP_STOP);
- }
- /* if rc == 0, then select() timed out */
-
- return result;
-}
-
-static CURLcode ftp_easy_statemach(struct connectdata *conn)
-{
- curl_socket_t sock = conn->sock[FIRSTSOCKET];
- int rc;
- struct SessionHandle *data=conn->data;
- struct ftp_conn *ftpc = &conn->proto.ftpc;
- CURLcode result = CURLE_OK;
-
- while(ftpc->state != FTP_STOP) {
- long timeout_ms = ftp_state_timeout(conn);
-
- if(timeout_ms <=0 ) {
- failf(data, "FTP response timeout");
- return CURLE_OPERATION_TIMEDOUT; /* already too little time */
- }
-
- rc = Curl_select(ftpc->sendleft?CURL_SOCKET_BAD:sock, /* reading */
- ftpc->sendleft?sock:CURL_SOCKET_BAD, /* writing */
- (int)timeout_ms);
-
- if(rc == -1) {
- failf(data, "select error");
- return CURLE_OUT_OF_MEMORY;
- }
- else if(rc == 0) {
- result = CURLE_OPERATION_TIMEDOUT;
- break;
- }
- else {
- result = ftp_statemach_act(conn);
- if(result)
- break;
- }
- }
-
- return result;
-}
-
-/*
- * Allocate and initialize the struct FTP for the current SessionHandle. If
- * need be.
- */
-static CURLcode ftp_init(struct connectdata *conn)
-{
- struct SessionHandle *data = conn->data;
- struct FTP *ftp;
- if(data->reqdata.proto.ftp)
- return CURLE_OK;
-
- ftp = (struct FTP *)calloc(sizeof(struct FTP), 1);
- if(!ftp)
- return CURLE_OUT_OF_MEMORY;
-
- data->reqdata.proto.ftp = ftp;
-
- /* get some initial data into the ftp struct */
- ftp->bytecountp = &data->reqdata.keep.bytecount;
-
- /* no need to duplicate them, this connectdata struct won't change */
- ftp->user = conn->user;
- ftp->passwd = conn->passwd;
- if (isBadFtpString(ftp->user) || isBadFtpString(ftp->passwd))
- return CURLE_URL_MALFORMAT;
-
- return CURLE_OK;
-}
-
-/*
- * Curl_ftp_connect() should do everything that is to be considered a part of
- * the connection phase.
- *
- * The variable 'done' points to will be TRUE if the protocol-layer connect
- * phase is done when this function returns, or FALSE is not. When called as
- * a part of the easy interface, it will always be TRUE.
- */
-CURLcode Curl_ftp_connect(struct connectdata *conn,
- bool *done) /* see description above */
-{
- CURLcode result;
-#ifndef CURL_DISABLE_HTTP
- /* for FTP over HTTP proxy */
- struct HTTP http_proxy;
- struct FTP *ftp_save;
-#endif /* CURL_DISABLE_HTTP */
- struct ftp_conn *ftpc = &conn->proto.ftpc;
- struct SessionHandle *data=conn->data;
-
- *done = FALSE; /* default to not done yet */
-
- if (data->reqdata.proto.ftp) {
- Curl_ftp_disconnect(conn);
- free(data->reqdata.proto.ftp);
- data->reqdata.proto.ftp = NULL;
- }
-
- result = ftp_init(conn);
- if(result)
- return result;
-
- /* We always support persistant connections on ftp */
- conn->bits.close = FALSE;
-
- ftpc->response_time = 3600; /* set default response time-out */
-
-#ifndef CURL_DISABLE_HTTP
- if (conn->bits.tunnel_proxy && conn->bits.httpproxy) {
- /* BLOCKING */
- /* We want "seamless" FTP operations through HTTP proxy tunnel */
-
- /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the member
- * conn->proto.http; we want FTP through HTTP and we have to change the
- * member temporarily for connecting to the HTTP proxy. After
- * Curl_proxyCONNECT we have to set back the member to the original struct
- * FTP pointer
- */
- ftp_save = data->reqdata.proto.ftp;
- memset(&http_proxy, 0, sizeof(http_proxy));
- data->reqdata.proto.http = &http_proxy;
-
- result = Curl_proxyCONNECT(conn, FIRSTSOCKET,
- conn->host.name, conn->remote_port);
-
- data->reqdata.proto.ftp = ftp_save;
-
- if(CURLE_OK != result)
- return result;
- }
-#endif /* CURL_DISABLE_HTTP */
-
- if(conn->protocol & PROT_FTPS) {
- /* BLOCKING */
- /* FTPS is simply ftp with SSL for the control channel */
- /* now, perform the SSL initialization for this socket */
- result = Curl_ssl_connect(conn, FIRSTSOCKET);
- if(result)
- return result;
- }
-
- /* When we connect, we start in the state where we await the 220
- response */
- ftp_respinit(conn); /* init the response reader stuff */
- state(conn, FTP_WAIT220);
- ftpc->response = Curl_tvnow(); /* start response time-out now! */
-
- if(data->state.used_interface == Curl_if_multi)
- result = Curl_ftp_multi_statemach(conn, done);
- else {
- result = ftp_easy_statemach(conn);
- if(!result)
- *done = TRUE;
- }
-
- return result;
-}
-
-/***********************************************************************
- *
- * Curl_ftp_done()
- *
- * The DONE function. This does what needs to be done after a single DO has
- * performed.
- *
- * Input argument is already checked for validity.
- */
-CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status, bool premature)
-{
- struct SessionHandle *data = conn->data;
- struct FTP *ftp = data->reqdata.proto.ftp;
- struct ftp_conn *ftpc = &conn->proto.ftpc;
- ssize_t nread;
- int ftpcode;
- CURLcode result=CURLE_OK;
- bool was_ctl_valid = ftpc->ctl_valid;
- size_t flen;
- size_t dlen;
- char *path;
- char *path_to_use = data->reqdata.path;
- struct Curl_transfer_keeper *k = &data->reqdata.keep;
-
- if(!ftp)
- /* When the easy handle is removed from the multi while libcurl is still
- * trying to resolve the host name, it seems that the ftp struct is not
- * yet initialized, but the removal action calls Curl_done() which calls
- * this function. So we simply return success if no ftp pointer is set.
- */
- return CURLE_OK;
-
- switch(status) {
- case CURLE_BAD_DOWNLOAD_RESUME:
- case CURLE_FTP_WEIRD_PASV_REPLY:
- case CURLE_FTP_PORT_FAILED:
- case CURLE_FTP_COULDNT_SET_BINARY:
- case CURLE_FTP_COULDNT_RETR_FILE:
- case CURLE_FTP_COULDNT_STOR_FILE:
- case CURLE_FTP_ACCESS_DENIED:
- /* the connection stays alive fine even though this happened */
- /* fall-through */
- case CURLE_OK: /* doesn't affect the control connection's status */
- if (!premature) {
- ftpc->ctl_valid = was_ctl_valid;
- break;
- }
- /* until we cope better with prematurely ended requests, let them
- * fallback as if in complete failure */
- default: /* by default, an error means the control connection is
- wedged and should not be used anymore */
- ftpc->ctl_valid = FALSE;
- ftpc->cwdfail = TRUE; /* set this TRUE to prevent us to remember the
- current path, as this connection is going */
- conn->bits.close = TRUE; /* marked for closure */
- break;
- }
-
- /* now store a copy of the directory we are in */
- if(ftpc->prevpath)
- free(ftpc->prevpath);
-
- /* get the "raw" path */
- path = curl_easy_unescape(data, path_to_use, 0, NULL);
- if(!path)
- return CURLE_OUT_OF_MEMORY;
-
- flen = ftp->file?strlen(ftp->file):0; /* file is "raw" already */
- dlen = strlen(path)-flen;
- if(dlen && !ftpc->cwdfail) {
- ftpc->prevpath = path;
- if(flen)
- /* if 'path' is not the whole string */
- ftpc->prevpath[dlen]=0; /* terminate */
- infof(data, "Remembering we are in dir %s\n", ftpc->prevpath);
- }
- else {
- ftpc->prevpath = NULL; /* no path */
- free(path);
- }
- /* free the dir tree and file parts */
- freedirs(conn);
-
-#ifdef HAVE_KRB4
- Curl_sec_fflush_fd(conn, conn->sock[SECONDARYSOCKET]);
-#endif
-
- /* shut down the socket to inform the server we're done */
-
-#ifdef _WIN32_WCE
- shutdown(conn->sock[SECONDARYSOCKET],2); /* SD_BOTH */
-#endif
-
- sclose(conn->sock[SECONDARYSOCKET]);
-
- conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
-
- if(!ftp->no_transfer && !status && !premature) {
- /*
- * Let's see what the server says about the transfer we just performed,
- * but lower the timeout as sometimes this connection has died while the
- * data has been transfered. This happens when doing through NATs etc that
- * abandon old silent connections.
- */
- long old_time = ftpc->response_time;
-
- ftpc->response_time = 60; /* give it only a minute for now */
-
- result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
-
- ftpc->response_time = old_time; /* set this back to previous value */
-
- if(!nread && (CURLE_OPERATION_TIMEDOUT == result)) {
- failf(data, "control connection looks dead");
- ftpc->ctl_valid = FALSE; /* mark control connection as bad */
- return result;
- }
-
- if(result)
- return result;
-
- if(!ftpc->dont_check) {
- /* 226 Transfer complete, 250 Requested file action okay, completed. */
- if((ftpcode != 226) && (ftpcode != 250)) {
- failf(data, "server did not report OK, got %d", ftpcode);
- result = CURLE_PARTIAL_FILE;
- }
- }
- }
-
- if(result || premature)
- /* the response code from the transfer showed an error already so no
- use checking further */
- ;
- else if(data->set.upload) {
- if((-1 != data->set.infilesize) &&
- (data->set.infilesize != *ftp->bytecountp) &&
- !data->set.crlf &&
- !ftp->no_transfer) {
- failf(data, "Uploaded unaligned file size (%" FORMAT_OFF_T
- " out of %" FORMAT_OFF_T " bytes)",
- *ftp->bytecountp, data->set.infilesize);
- result = CURLE_PARTIAL_FILE;
- }
- }
- else {
- if((-1 != k->size) && (k->size != *ftp->bytecountp) &&
-#ifdef CURL_DO_LINEEND_CONV
- /* Most FTP servers don't adjust their file SIZE response for CRLFs, so
- * we'll check to see if the discrepancy can be explained by the number
- * of CRLFs we've changed to LFs.
- */
- ((k->size + data->state.crlf_conversions) != *ftp->bytecountp) &&
-#endif /* CURL_DO_LINEEND_CONV */
- (k->maxdownload != *ftp->bytecountp)) {
- failf(data, "Received only partial file: %" FORMAT_OFF_T " bytes",
- *ftp->bytecountp);
- result = CURLE_PARTIAL_FILE;
- }
- else if(!ftpc->dont_check &&
- !*ftp->bytecountp &&
- (k->size>0)) {
- failf(data, "No data was received!");
- result = CURLE_FTP_COULDNT_RETR_FILE;
- }
- }
-
- /* clear these for next connection */
- ftp->no_transfer = FALSE;
- ftpc->dont_check = FALSE;
-
- /* Send any post-transfer QUOTE strings? */
- if(!status && !result && !premature && data->set.postquote)
- result = ftp_sendquote(conn, data->set.postquote);
-
- return result;
-}
-
-/***********************************************************************
- *
- * ftp_sendquote()
- *
- * Where a 'quote' means a list of custom commands to send to the server.
- * The quote list is passed as an argument.
- */
-
-static
-CURLcode ftp_sendquote(struct connectdata *conn, struct curl_slist *quote)
-{
- struct curl_slist *item;
- ssize_t nread;
- int ftpcode;
- CURLcode result;
-
- item = quote;
- while (item) {
- if (item->data) {
- FTPSENDF(conn, "%s", item->data);
-
- result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
- if (result)
- return result;
-
- if (ftpcode >= 400) {
- failf(conn->data, "QUOT string not accepted: %s", item->data);
- return CURLE_FTP_QUOTE_ERROR;
- }
- }
-
- item = item->next;
- }
-
- return CURLE_OK;
-}
-
-/***********************************************************************
- *
- * ftp_need_type()
- *
- * Returns TRUE if we in the current situation should send TYPE
- */
-static int ftp_need_type(struct connectdata *conn,
- bool ascii_wanted)
-{
- return conn->proto.ftpc.transfertype != (ascii_wanted?'A':'I');
-}
-
-/***********************************************************************
- *
- * ftp_nb_type()
- *
- * Set TYPE. We only deal with ASCII or BINARY so this function
- * sets one of them.
- * If the transfer type is not sent, simulate on OK response in newstate
- */
-static CURLcode ftp_nb_type(struct connectdata *conn,
- bool ascii, ftpstate newstate)
-{
- struct ftp_conn *ftpc = &conn->proto.ftpc;
- CURLcode result;
- int want = ascii?'A':'I';
-
- if (ftpc->transfertype == want) {
- state(conn, newstate);
- return ftp_state_type_resp(conn, 200, newstate);
- }
-
- NBFTPSENDF(conn, "TYPE %c", want);
- state(conn, newstate);
-
- /* keep track of our current transfer type */
- ftpc->transfertype = want;
- return CURLE_OK;
-}
-
-/***************************************************************************
- *
- * ftp_pasv_verbose()
- *
- * This function only outputs some informationals about this second connection
- * when we've issued a PASV command before and thus we have connected to a
- * possibly new IP address.
- *
- */
-static void
-ftp_pasv_verbose(struct connectdata *conn,
- Curl_addrinfo *ai,
- char *newhost, /* ascii version */
- int port)
-{
- char buf[256];
- Curl_printable_address(ai, buf, sizeof(buf));
- infof(conn->data, "Connecting to %s (%s) port %d\n", newhost, buf, port);
-}
-
-/*
- Check if this is a range download, and if so, set the internal variables
- properly.
- */
-
-static CURLcode ftp_range(struct connectdata *conn)
-{
- curl_off_t from, to;
- curl_off_t totalsize=-1;
- char *ptr;
- char *ptr2;
- struct SessionHandle *data = conn->data;
- struct ftp_conn *ftpc = &conn->proto.ftpc;
-
- if(data->reqdata.use_range && data->reqdata.range) {
- from=curlx_strtoofft(data->reqdata.range, &ptr, 0);
- while(ptr && *ptr && (ISSPACE(*ptr) || (*ptr=='-')))
- ptr++;
- to=curlx_strtoofft(ptr, &ptr2, 0);
- if(ptr == ptr2) {
- /* we didn't get any digit */
- to=-1;
- }
- if((-1 == to) && (from>=0)) {
- /* X - */
- data->reqdata.resume_from = from;
- DEBUGF(infof(conn->data, "FTP RANGE %" FORMAT_OFF_T " to end of file\n",
- from));
- }
- else if(from < 0) {
- /* -Y */
- totalsize = -from;
- data->reqdata.maxdownload = -from;
- data->reqdata.resume_from = from;
- DEBUGF(infof(conn->data, "FTP RANGE the last %" FORMAT_OFF_T " bytes\n",
- totalsize));
- }
- else {
- /* X-Y */
- totalsize = to-from;
- data->reqdata.maxdownload = totalsize+1; /* include last byte */
- data->reqdata.resume_from = from;
- DEBUGF(infof(conn->data, "FTP RANGE from %" FORMAT_OFF_T
- " getting %" FORMAT_OFF_T " bytes\n",
- from, data->reqdata.maxdownload));
- }
- DEBUGF(infof(conn->data, "range-download from %" FORMAT_OFF_T
- " to %" FORMAT_OFF_T ", totally %" FORMAT_OFF_T " bytes\n",
- from, to, data->reqdata.maxdownload));
- ftpc->dont_check = TRUE; /* dont check for successful transfer */
- }
- return CURLE_OK;
-}
-
-
-/*
- * Curl_ftp_nextconnect()
- *
- * This function shall be called when the second FTP (data) connection is
- * connected.
- */
-
-CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
-{
- struct SessionHandle *data=conn->data;
- CURLcode result = CURLE_OK;
-
- /* the ftp struct is inited in Curl_ftp_connect() */
- struct FTP *ftp = data->reqdata.proto.ftp;
-
- DEBUGF(infof(data, "DO-MORE phase starts\n"));
-
- if(!ftp->no_transfer && !conn->bits.no_body) {
- /* a transfer is about to take place */
-
- if(data->set.upload) {
- result = ftp_nb_type(conn, data->set.prefer_ascii,
- FTP_STOR_TYPE);
- if (result)
- return result;
- }
- else {
- /* download */
- ftp->downloadsize = -1; /* unknown as of yet */
-
- result = ftp_range(conn);
- if(result)
- ;
- else if((data->set.ftp_list_only) || !ftp->file) {
- /* The specified path ends with a slash, and therefore we think this
- is a directory that is requested, use LIST. But before that we
- need to set ASCII transfer mode. */
- result = ftp_nb_type(conn, 1, FTP_LIST_TYPE);
- if (result)
- return result;
- }
- else {
- result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_RETR_TYPE);
- if (result)
- return result;
- }
- }
- result = ftp_easy_statemach(conn);
- }
-
- if(ftp->no_transfer)
- /* no data to transfer. FIX: it feels like a kludge to have this here
- too! */
- result=Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
-
- /* end of transfer */
- DEBUGF(infof(data, "DO-MORE phase ends with %d\n", result));
-
- return result;
-}
-
-
-
-/***********************************************************************
- *
- * ftp_perform()
- *
- * This is the actual DO function for FTP. Get a file/directory according to
- * the options previously setup.
- */
-
-static
-CURLcode ftp_perform(struct connectdata *conn,
- bool *connected, /* connect status after PASV / PORT */
- bool *dophase_done)
-{
- /* this is FTP and no proxy */
- CURLcode result=CURLE_OK;
-
- DEBUGF(infof(conn->data, "DO phase starts\n"));
-
- *dophase_done = FALSE; /* not done yet */
-
- /* start the first command in the DO phase */
- result = ftp_state_quote(conn, TRUE, FTP_QUOTE);
- if(result)
- return result;
-
- /* run the state-machine */
- if(conn->data->state.used_interface == Curl_if_multi)
- result = Curl_ftp_multi_statemach(conn, dophase_done);
- else {
- result = ftp_easy_statemach(conn);
- *dophase_done = TRUE; /* with the easy interface we are done here */
- }
- *connected = conn->bits.tcpconnect;
-
- if(*dophase_done) {
- DEBUGF(infof(conn->data, "DO phase is complete\n"));
- }
-
- return result;
-}
-
-/***********************************************************************
- *
- * Curl_ftp()
- *
- * This function is registered as 'curl_do' function. It decodes the path
- * parts etc as a wrapper to the actual DO function (ftp_perform).
- *
- * The input argument is already checked for validity.
- */
-CURLcode Curl_ftp(struct connectdata *conn, bool *done)
-{
- CURLcode retcode = CURLE_OK;
-
- *done = FALSE; /* default to false */
-
- /*
- Since connections can be re-used between SessionHandles, this might be a
- connection already existing but on a fresh SessionHandle struct so we must
- make sure we have a good 'struct FTP' to play with. For new connections,
- the struct FTP is allocated and setup in the Curl_ftp_connect() function.
- */
- retcode = ftp_init(conn);
- if(retcode)
- return retcode;
-
- retcode = ftp_parse_url_path(conn);
- if (retcode)
- return retcode;
-
- retcode = ftp_regular_transfer(conn, done);
-
- return retcode;
-}
-
-/***********************************************************************
- *
- * Curl_(nb)ftpsendf()
- *
- * Sends the formated string as a ftp command to a ftp server
- *
- * NOTE: we build the command in a fixed-length buffer, which sets length
- * restrictions on the command!
- *
- * The "nb" version is made to Never Block.
- */
-CURLcode Curl_nbftpsendf(struct connectdata *conn,
- const char *fmt, ...)
-{
- ssize_t bytes_written;
- char s[256];
- size_t write_len;
- char *sptr=s;
- CURLcode res = CURLE_OK;
- struct SessionHandle *data = conn->data;
- struct ftp_conn *ftpc = &conn->proto.ftpc;
-
- va_list ap;
- va_start(ap, fmt);
- vsnprintf(s, 250, fmt, ap);
- va_end(ap);
-
- strcat(s, "\r\n"); /* append a trailing CRLF */
-
- bytes_written=0;
- write_len = strlen(s);
-
- ftp_respinit(conn);
-
-#ifdef CURL_DOES_CONVERSIONS
- res = Curl_convert_to_network(data, s, write_len);
- /* Curl_convert_to_network calls failf if unsuccessful */
- if(res != CURLE_OK) {
- return res;
- }
-#endif /* CURL_DOES_CONVERSIONS */
-
- res = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len,
- &bytes_written);
-
- if(CURLE_OK != res)
- return res;
-
- if(conn->data->set.verbose)
- Curl_debug(conn->data, CURLINFO_HEADER_OUT,
- sptr, (size_t)bytes_written, conn);
-
- if(bytes_written != (ssize_t)write_len) {
- /* the whole chunk was not sent, store the rest of the data */
- write_len -= bytes_written;
- sptr += bytes_written;
- ftpc->sendthis = malloc(write_len);
- if(ftpc->sendthis) {
- memcpy(ftpc->sendthis, sptr, write_len);
- ftpc->sendsize = ftpc->sendleft = write_len;
- }
- else {
- failf(data, "out of memory");
- res = CURLE_OUT_OF_MEMORY;
- }
- }
- else
- ftpc->response = Curl_tvnow();
-
- return res;
-}
-
-CURLcode Curl_ftpsendf(struct connectdata *conn,
- const char *fmt, ...)
-{
- ssize_t bytes_written;
- char s[256];
- size_t write_len;
- char *sptr=s;
- CURLcode res = CURLE_OK;
-
- va_list ap;
- va_start(ap, fmt);
- vsnprintf(s, 250, fmt, ap);
- va_end(ap);
-
- strcat(s, "\r\n"); /* append a trailing CRLF */
-
- bytes_written=0;
- write_len = strlen(s);
-
-#ifdef CURL_DOES_CONVERSIONS
- res = Curl_convert_to_network(conn->data, s, write_len);
- /* Curl_convert_to_network calls failf if unsuccessful */
- if(res != CURLE_OK) {
- return(res);
- }
-#endif /* CURL_DOES_CONVERSIONS */
-
- while(1) {
- res = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len,
- &bytes_written);
-
- if(CURLE_OK != res)
- break;
-
- if(conn->data->set.verbose)
- Curl_debug(conn->data, CURLINFO_HEADER_OUT,
- sptr, (size_t)bytes_written, conn);
-
- if(bytes_written != (ssize_t)write_len) {
- write_len -= bytes_written;
- sptr += bytes_written;
- }
- else
- break;
- }
-
- return res;
-}
-
-/***********************************************************************
- *
- * ftp_quit()
- *
- * This should be called before calling sclose() on an ftp control connection
- * (not data connections). We should then wait for the response from the
- * server before returning. The calling code should then try to close the
- * connection.
- *
- */
-static CURLcode ftp_quit(struct connectdata *conn)
-{
- CURLcode result = CURLE_OK;
-
- if(conn->proto.ftpc.ctl_valid) {
- NBFTPSENDF(conn, "QUIT", NULL);
- state(conn, FTP_QUIT);
-
- result = ftp_easy_statemach(conn);
- }
-
- return result;
-}
-
-/***********************************************************************
- *
- * Curl_ftp_disconnect()
- *
- * Disconnect from an FTP server. Cleanup protocol-specific per-connection
- * resources. BLOCKING.
- */
-CURLcode Curl_ftp_disconnect(struct connectdata *conn)
-{
- struct ftp_conn *ftpc= &conn->proto.ftpc;
-
- /* We cannot send quit unconditionally. If this connection is stale or
- bad in any way, sending quit and waiting around here will make the
- disconnect wait in vain and cause more problems than we need to.
-
- ftp_quit() will check the state of ftp->ctl_valid. If it's ok it
- will try to send the QUIT command, otherwise it will just return.
- */
-
- /* The FTP session may or may not have been allocated/setup at this point! */
- if(conn->data->reqdata.proto.ftp) {
- (void)ftp_quit(conn); /* ignore errors on the QUIT */
-
- if(ftpc->entrypath) {
- struct SessionHandle *data = conn->data;
- data->state.most_recent_ftp_entrypath = NULL;
- free(ftpc->entrypath);
- ftpc->entrypath = NULL;
- }
- if(ftpc->cache) {
- free(ftpc->cache);
- ftpc->cache = NULL;
- }
- freedirs(conn);
- if(ftpc->prevpath) {
- free(ftpc->prevpath);
- ftpc->prevpath = NULL;
- }
- }
- return CURLE_OK;
-}
-
-/***********************************************************************
- *
- * ftp_parse_url_path()
- *
- * Parse the URL path into separate path components.
- *
- */
-static
-CURLcode ftp_parse_url_path(struct connectdata *conn)
-{
- CURLcode retcode = CURLE_OK;
- struct SessionHandle *data = conn->data;
- /* the ftp struct is already inited in ftp_connect() */
- struct FTP *ftp = data->reqdata.proto.ftp;
- struct ftp_conn *ftpc = &conn->proto.ftpc;
- size_t dlen;
- char *slash_pos; /* position of the first '/' char in curpos */
- char *path_to_use = data->reqdata.path;
- char *cur_pos;
-
- cur_pos = path_to_use; /* current position in path. point at the begin
- of next path component */
-
- ftpc->ctl_valid = FALSE;
- ftpc->cwdfail = FALSE;
-
- switch(data->set.ftp_filemethod) {
- case FTPFILE_NOCWD:
- /* fastest, but less standard-compliant */
- ftp->file = data->reqdata.path; /* this is a full file path */
- break;
-
- case FTPFILE_SINGLECWD:
- /* get the last slash */
- slash_pos=strrchr(cur_pos, '/');
- if(slash_pos || !cur_pos || !*cur_pos) {
- ftpc->dirdepth = 1; /* we consider it to be a single dir */
- ftpc->dirs = (char **)calloc(1, sizeof(ftpc->dirs[0]));
- if(!ftpc->dirs)
- return CURLE_OUT_OF_MEMORY;
-
- ftpc->dirs[0] = curl_easy_unescape(conn->data, slash_pos ? cur_pos : "/",
- slash_pos?(int)(slash_pos-cur_pos):1,
- NULL);
- if(!ftpc->dirs[0]) {
- free(ftpc->dirs);
- return CURLE_OUT_OF_MEMORY;
- }
- ftp->file = slash_pos ? slash_pos+1 : cur_pos; /* rest is file name */
- }
- else
- ftp->file = cur_pos; /* this is a file name only */
- break;
-
- default: /* allow pretty much anything */
- case FTPFILE_MULTICWD:
- ftpc->dirdepth = 0;
- ftpc->diralloc = 5; /* default dir depth to allocate */
- ftpc->dirs = (char **)calloc(ftpc->diralloc, sizeof(ftpc->dirs[0]));
- if(!ftpc->dirs)
- return CURLE_OUT_OF_MEMORY;
-
- /* parse the URL path into separate path components */
- while ((slash_pos = strchr(cur_pos, '/')) != NULL) {
- /* 1 or 0 to indicate absolute directory */
- bool absolute_dir = (bool)((cur_pos - data->reqdata.path > 0) &&
- (ftpc->dirdepth == 0));
-
- /* seek out the next path component */
- if (slash_pos-cur_pos) {
- /* we skip empty path components, like "x//y" since the FTP command
- CWD requires a parameter and a non-existent parameter a) doesn't
- work on many servers and b) has no effect on the others. */
- int len = (int)(slash_pos - cur_pos + absolute_dir);
- ftpc->dirs[ftpc->dirdepth] = curl_easy_unescape(conn->data,
- cur_pos - absolute_dir,
- len, NULL);
- if (!ftpc->dirs[ftpc->dirdepth]) { /* run out of memory ... */
- failf(data, "no memory");
- freedirs(conn);
- return CURLE_OUT_OF_MEMORY;
- }
- if (isBadFtpString(ftpc->dirs[ftpc->dirdepth])) {
- freedirs(conn);
- return CURLE_URL_MALFORMAT;
- }
- }
- else {
- cur_pos = slash_pos + 1; /* jump to the rest of the string */
- continue;
- }
-
- if(!retcode) {
- cur_pos = slash_pos + 1; /* jump to the rest of the string */
- if(++ftpc->dirdepth >= ftpc->diralloc) {
- /* enlarge array */
- char *bigger;
- ftpc->diralloc *= 2; /* double the size each time */
- bigger = realloc(ftpc->dirs, ftpc->diralloc * sizeof(ftpc->dirs[0]));
- if(!bigger) {
- ftpc->dirdepth--;
- freedirs(conn);
- return CURLE_OUT_OF_MEMORY;
- }
- ftpc->dirs = (char **)bigger;
- }
- }
- }
-
- ftp->file = cur_pos; /* the rest is the file name */
- }
-
- if(*ftp->file) {
- ftp->file = curl_easy_unescape(conn->data, ftp->file, 0, NULL);
- if(NULL == ftp->file) {
- freedirs(conn);
- failf(data, "no memory");
- return CURLE_OUT_OF_MEMORY;
- }
- if (isBadFtpString(ftp->file)) {
- freedirs(conn);
- return CURLE_URL_MALFORMAT;
- }
- }
- else
- ftp->file=NULL; /* instead of point to a zero byte, we make it a NULL
- pointer */
-
- if(data->set.upload && !ftp->file &&
- (!ftp->no_transfer || conn->bits.no_body)) {
- /* We need a file name when uploading. Return error! */
- failf(data, "Uploading to a URL without a file name!");
- return CURLE_URL_MALFORMAT;
- }
-
- ftpc->cwddone = FALSE; /* default to not done */
-
- if(ftpc->prevpath) {
- /* prevpath is "raw" so we convert the input path before we compare the
- strings */
- char *path = curl_easy_unescape(conn->data, data->reqdata.path, 0, NULL);
- if(!path)
- return CURLE_OUT_OF_MEMORY;
-
- dlen = strlen(path) - (ftp->file?strlen(ftp->file):0);
- if((dlen == strlen(ftpc->prevpath)) &&
- curl_strnequal(path, ftpc->prevpath, dlen)) {
- infof(data, "Request has same path as previous transfer\n");
- ftpc->cwddone = TRUE;
- }
- free(path);
- }
-
- return retcode;
-}
-
-/* call this when the DO phase has completed */
-static CURLcode ftp_dophase_done(struct connectdata *conn,
- bool connected)
-{
- CURLcode result = CURLE_OK;
- struct FTP *ftp = conn->data->reqdata.proto.ftp;
- struct ftp_conn *ftpc = &conn->proto.ftpc;
-
- if(connected)
- result = Curl_ftp_nextconnect(conn);
-
- if(result && (conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD)) {
- /* Failure detected, close the second socket if it was created already */
- sclose(conn->sock[SECONDARYSOCKET]);
- conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
- return result;
- }
-
- if(ftp->no_transfer)
- /* no data to transfer */
- result=Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
- else if(!connected)
- /* since we didn't connect now, we want do_more to get called */
- conn->bits.do_more = TRUE;
-
- ftpc->ctl_valid = TRUE; /* seems good */
-
- return result;
-}
-
-/* called from multi.c while DOing */
-CURLcode Curl_ftp_doing(struct connectdata *conn,
- bool *dophase_done)
-{
- CURLcode result;
- result = Curl_ftp_multi_statemach(conn, dophase_done);
-
- if(*dophase_done) {
- result = ftp_dophase_done(conn, FALSE /* not connected */);
-
- DEBUGF(infof(conn->data, "DO phase is complete\n"));
- }
- return result;
-}
-
-/***********************************************************************
- *
- * ftp_regular_transfer()
- *
- * The input argument is already checked for validity.
- *
- * Performs all commands done before a regular transfer between a local and a
- * remote host.
- *
- * ftp->ctl_valid starts out as FALSE, and gets set to TRUE if we reach the
- * Curl_ftp_done() function without finding any major problem.
- */
-static
-CURLcode ftp_regular_transfer(struct connectdata *conn,
- bool *dophase_done)
-{
- CURLcode result=CURLE_OK;
- bool connected=0;
- struct SessionHandle *data = conn->data;
- struct ftp_conn *ftpc = &conn->proto.ftpc;
- data->reqdata.size = -1; /* make sure this is unknown at this point */
-
- Curl_pgrsSetUploadCounter(data, 0);
- Curl_pgrsSetDownloadCounter(data, 0);
- Curl_pgrsSetUploadSize(data, 0);
- Curl_pgrsSetDownloadSize(data, 0);
-
- ftpc->ctl_valid = TRUE; /* starts good */
-
- result = ftp_perform(conn,
- &connected, /* have we connected after PASV/PORT */
- dophase_done); /* all commands in the DO-phase done? */
-
- if(CURLE_OK == result) {
-
- if(!*dophase_done)
- /* the DO phase has not completed yet */
- return CURLE_OK;
-
- result = ftp_dophase_done(conn, connected);
- if(result)
- return result;
- }
- else
- freedirs(conn);
-
- return result;
-}
-
-#endif /* CURL_DISABLE_FTP */
diff --git a/Utilities/cmcurl/ftp.h b/Utilities/cmcurl/ftp.h
deleted file mode 100644
index b64e70506..000000000
--- a/Utilities/cmcurl/ftp.h
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef __FTP_H
-#define __FTP_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#ifndef CURL_DISABLE_FTP
-CURLcode Curl_ftp(struct connectdata *conn, bool *done);
-CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode, bool premature);
-CURLcode Curl_ftp_connect(struct connectdata *conn, bool *done);
-CURLcode Curl_ftp_disconnect(struct connectdata *conn);
-CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...);
-CURLcode Curl_nbftpsendf(struct connectdata *, const char *fmt, ...);
-CURLcode Curl_GetFTPResponse(ssize_t *nread, struct connectdata *conn,
- int *ftpcode);
-CURLcode Curl_ftp_nextconnect(struct connectdata *conn);
-CURLcode Curl_ftp_multi_statemach(struct connectdata *conn, bool *done);
-int Curl_ftp_getsock(struct connectdata *conn,
- curl_socket_t *socks,
- int numsocks);
-CURLcode Curl_ftp_doing(struct connectdata *conn,
- bool *dophase_done);
-#endif /* CURL_DISABLE_FTP */
-#endif /* __FTP_H */
diff --git a/Utilities/cmcurl/getenv.c b/Utilities/cmcurl/getenv.c
deleted file mode 100644
index 4f955f893..000000000
--- a/Utilities/cmcurl/getenv.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef VMS
-#include <unixlib.h>
-#endif
-
-#include <curl/curl.h>
-#include "memory.h"
-
-#include "memdebug.h"
-
-static
-char *GetEnv(const char *variable)
-{
-#ifdef _WIN32_WCE
- return NULL;
-#else
-#ifdef WIN32
- char env[MAX_PATH]; /* MAX_PATH is from windef.h */
- char *temp = getenv(variable);
- env[0] = '\0';
- if (temp != NULL)
- ExpandEnvironmentStrings(temp, env, sizeof(env));
-#else
-#ifdef VMS
- char *env = getenv(variable);
- if (env && strcmp("HOME",variable) == 0) {
- env = decc$translate_vms(env);
- }
-#else
- /* no length control */
- char *env = getenv(variable);
-#endif
-#endif
- return (env && env[0])?strdup(env):NULL;
-#endif
-}
-
-char *curl_getenv(const char *v)
-{
- return GetEnv(v);
-}
diff --git a/Utilities/cmcurl/getinfo.c b/Utilities/cmcurl/getinfo.c
deleted file mode 100644
index 5cf3bcacd..000000000
--- a/Utilities/cmcurl/getinfo.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#include <curl/curl.h>
-
-#include "urldata.h"
-#include "getinfo.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include "memory.h"
-#include "sslgen.h"
-
-/* Make this the last #include */
-#include "memdebug.h"
-
-/*
- * This is supposed to be called in the beginning of a perform() session
- * and should reset all session-info variables
- */
-CURLcode Curl_initinfo(struct SessionHandle *data)
-{
- struct Progress *pro = &data->progress;
- struct PureInfo *info =&data->info;
-
- pro->t_nslookup = 0;
- pro->t_connect = 0;
- pro->t_pretransfer = 0;
- pro->t_starttransfer = 0;
- pro->timespent = 0;
- pro->t_redirect = 0;
-
- info->httpcode = 0;
- info->httpversion=0;
- info->filetime=-1; /* -1 is an illegal time and thus means unknown */
-
- if (info->contenttype)
- free(info->contenttype);
- info->contenttype = NULL;
-
- info->header_size = 0;
- info->request_size = 0;
- info->numconnects = 0;
- return CURLE_OK;
-}
-
-CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
-{
- va_list arg;
- long *param_longp=NULL;
- double *param_doublep=NULL;
- char **param_charp=NULL;
- struct curl_slist **param_slistp=NULL;
- char buf;
-
- if(!data)
- return CURLE_BAD_FUNCTION_ARGUMENT;
-
- va_start(arg, info);
-
- switch(info&CURLINFO_TYPEMASK) {
- default:
- return CURLE_BAD_FUNCTION_ARGUMENT;
- case CURLINFO_STRING:
- param_charp = va_arg(arg, char **);
- if(NULL == param_charp)
- return CURLE_BAD_FUNCTION_ARGUMENT;
- break;
- case CURLINFO_LONG:
- param_longp = va_arg(arg, long *);
- if(NULL == param_longp)
- return CURLE_BAD_FUNCTION_ARGUMENT;
- break;
- case CURLINFO_DOUBLE:
- param_doublep = va_arg(arg, double *);
- if(NULL == param_doublep)
- return CURLE_BAD_FUNCTION_ARGUMENT;
- break;
- case CURLINFO_SLIST:
- param_slistp = va_arg(arg, struct curl_slist **);
- if(NULL == param_slistp)
- return CURLE_BAD_FUNCTION_ARGUMENT;
- break;
- }
-
- switch(info) {
- case CURLINFO_EFFECTIVE_URL:
- *param_charp = data->change.url?data->change.url:(char *)"";
- break;
- case CURLINFO_RESPONSE_CODE:
- *param_longp = data->info.httpcode;
- break;
- case CURLINFO_HTTP_CONNECTCODE:
- *param_longp = data->info.httpproxycode;
- break;
- case CURLINFO_FILETIME:
- *param_longp = data->info.filetime;
- break;
- case CURLINFO_HEADER_SIZE:
- *param_longp = data->info.header_size;
- break;
- case CURLINFO_REQUEST_SIZE:
- *param_longp = data->info.request_size;
- break;
- case CURLINFO_TOTAL_TIME:
- *param_doublep = data->progress.timespent;
- break;
- case CURLINFO_NAMELOOKUP_TIME:
- *param_doublep = data->progress.t_nslookup;
- break;
- case CURLINFO_CONNECT_TIME:
- *param_doublep = data->progress.t_connect;
- break;
- case CURLINFO_PRETRANSFER_TIME:
- *param_doublep = data->progress.t_pretransfer;
- break;
- case CURLINFO_STARTTRANSFER_TIME:
- *param_doublep = data->progress.t_starttransfer;
- break;
- case CURLINFO_SIZE_UPLOAD:
- *param_doublep = (double)data->progress.uploaded;
- break;
- case CURLINFO_SIZE_DOWNLOAD:
- *param_doublep = (double)data->progress.downloaded;
- break;
- case CURLINFO_SPEED_DOWNLOAD:
- *param_doublep = (double)data->progress.dlspeed;
- break;
- case CURLINFO_SPEED_UPLOAD:
- *param_doublep = (double)data->progress.ulspeed;
- break;
- case CURLINFO_SSL_VERIFYRESULT:
- *param_longp = data->set.ssl.certverifyresult;
- break;
- case CURLINFO_CONTENT_LENGTH_DOWNLOAD:
- *param_doublep = (double)data->progress.size_dl;
- break;
- case CURLINFO_CONTENT_LENGTH_UPLOAD:
- *param_doublep = (double)data->progress.size_ul;
- break;
- case CURLINFO_REDIRECT_TIME:
- *param_doublep = data->progress.t_redirect;
- break;
- case CURLINFO_REDIRECT_COUNT:
- *param_longp = data->set.followlocation;
- break;
- case CURLINFO_CONTENT_TYPE:
- *param_charp = data->info.contenttype;
- break;
- case CURLINFO_PRIVATE:
- *param_charp = data->set.private_data;
- break;
- case CURLINFO_HTTPAUTH_AVAIL:
- *param_longp = data->info.httpauthavail;
- break;
- case CURLINFO_PROXYAUTH_AVAIL:
- *param_longp = data->info.proxyauthavail;
- break;
- case CURLINFO_OS_ERRNO:
- *param_longp = data->state.os_errno;
- break;
- case CURLINFO_NUM_CONNECTS:
- *param_longp = data->info.numconnects;
- break;
- case CURLINFO_SSL_ENGINES:
- *param_slistp = Curl_ssl_engines_list(data);
- break;
- case CURLINFO_COOKIELIST:
- *param_slistp = Curl_cookie_list(data);
- break;
- case CURLINFO_FTP_ENTRY_PATH:
- /* Return the entrypath string from the most recent connection.
- This pointer was copied from the connectdata structure by FTP.
- The actual string may be free()ed by subsequent libcurl calls so
- it must be copied to a safer area before the next libcurl call.
- Callers must never free it themselves. */
- *param_charp = data->state.most_recent_ftp_entrypath;
- break;
- case CURLINFO_LASTSOCKET:
- if((data->state.lastconnect != -1) &&
- (data->state.connc->connects[data->state.lastconnect] != NULL)) {
- struct connectdata *c = data->state.connc->connects
- [data->state.lastconnect];
- *param_longp = c->sock[FIRSTSOCKET];
- /* we have a socket connected, let's determine if the server shut down */
- /* determine if ssl */
- if(c->ssl[FIRSTSOCKET].use) {
- /* use the SSL context */
- if (!Curl_ssl_check_cxn(c))
- *param_longp = -1; /* FIN received */
- }
-/* Minix 3.1 doesn't support any flags on recv; just assume socket is OK */
-#ifdef MSG_PEEK
- else {
- /* use the socket */
- if(recv((RECV_TYPE_ARG1)c->sock[FIRSTSOCKET], (RECV_TYPE_ARG2)&buf,
- (RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK) == 0) {
- *param_longp = -1; /* FIN received */
- }
- }
-#endif
- }
- else
- *param_longp = -1;
- break;
- default:
- return CURLE_BAD_FUNCTION_ARGUMENT;
- }
- return CURLE_OK;
-}
diff --git a/Utilities/cmcurl/getinfo.h b/Utilities/cmcurl/getinfo.h
deleted file mode 100644
index 2fe1b5c36..000000000
--- a/Utilities/cmcurl/getinfo.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef __GETINFO_H
-#define __GETINFO_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...);
-CURLcode Curl_initinfo(struct SessionHandle *data);
-
-#endif
diff --git a/Utilities/cmcurl/gtls.c b/Utilities/cmcurl/gtls.c
deleted file mode 100644
index 250ecada4..000000000
--- a/Utilities/cmcurl/gtls.c
+++ /dev/null
@@ -1,640 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-/*
- * Source file for all GnuTLS-specific code for the TLS/SSL layer. No code
- * but sslgen.c should ever call or use these functions.
- *
- * Note: don't use the GnuTLS' *_t variable type names in this source code,
- * since they were not present in 1.0.X.
- */
-
-#include "setup.h"
-#ifdef USE_GNUTLS
-#include <gnutls/gnutls.h>
-#include <gnutls/x509.h>
-
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-
-#include "urldata.h"
-#include "sendf.h"
-#include "gtls.h"
-#include "sslgen.h"
-#include "parsedate.h"
-#include "connect.h" /* for the connect timeout */
-#include "select.h"
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-#include "memory.h"
-/* The last #include file should be: */
-#include "memdebug.h"
-
-/* Enable GnuTLS debugging by defining GTLSDEBUG */
-/*#define GTLSDEBUG */
-
-#ifdef GTLSDEBUG
-static void tls_log_func(int level, const char *str)
-{
- fprintf(stderr, "|<%d>| %s", level, str);
-}
-#endif
-
-/*
- * Custom push and pull callback functions used by GNU TLS to read and write
- * to the socket. These functions are simple wrappers to send() and recv()
- * (although here using the sread/swrite macros as defined by setup_once.h).
- * We use custom functions rather than the GNU TLS defaults because it allows
- * us to get specific about the fourth "flags" argument, and to use arbitrary
- * private data with gnutls_transport_set_ptr if we wish.
- */
-static ssize_t Curl_gtls_push(void *s, const void *buf, size_t len)
-{
- return swrite(s, buf, len);
-}
-
-static ssize_t Curl_gtls_pull(void *s, void *buf, size_t len)
-{
- return sread(s, buf, len);
-}
-
-/* Global GnuTLS init, called from Curl_ssl_init() */
-int Curl_gtls_init(void)
-{
- gnutls_global_init();
-#ifdef GTLSDEBUG
- gnutls_global_set_log_function(tls_log_func);
- gnutls_global_set_log_level(2);
-#endif
- return 1;
-}
-
-int Curl_gtls_cleanup(void)
-{
- gnutls_global_deinit();
- return 1;
-}
-
-static void showtime(struct SessionHandle *data,
- const char *text,
- time_t stamp)
-{
- struct tm *tm;
-#ifdef HAVE_GMTIME_R
- struct tm buffer;
- tm = (struct tm *)gmtime_r(&stamp, &buffer);
-#else
- tm = gmtime(&stamp);
-#endif
- snprintf(data->state.buffer,
- BUFSIZE,
- "\t %s: %s, %02d %s %4d %02d:%02d:%02d GMT\n",
- text,
- Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
- tm->tm_mday,
- Curl_month[tm->tm_mon],
- tm->tm_year + 1900,
- tm->tm_hour,
- tm->tm_min,
- tm->tm_sec);
- infof(data, "%s", data->state.buffer);
-}
-
-/* this function does a BLOCKING SSL/TLS (re-)handshake */
-static CURLcode handshake(struct connectdata *conn,
- gnutls_session session,
- int sockindex,
- bool duringconnect)
-{
- struct SessionHandle *data = conn->data;
- int rc;
-
- do {
- rc = gnutls_handshake(session);
-
- if((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED)) {
- long timeout_ms = DEFAULT_CONNECT_TIMEOUT;
- long has_passed;
-
- if(duringconnect && data->set.connecttimeout)
- timeout_ms = data->set.connecttimeout*1000;
-
- if(data->set.timeout) {
- /* get the strictest timeout of the ones converted to milliseconds */
- if((data->set.timeout*1000) < timeout_ms)
- timeout_ms = data->set.timeout*1000;
- }
-
- /* Evaluate in milliseconds how much time that has passed */
- has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
-
- /* subtract the passed time */
- timeout_ms -= has_passed;
-
- if(timeout_ms < 0) {
- /* a precaution, no need to continue if time already is up */
- failf(data, "SSL connection timeout");
- return CURLE_OPERATION_TIMEOUTED;
- }
-
- rc = Curl_select(conn->sock[sockindex],
- conn->sock[sockindex], (int)timeout_ms);
- if(rc > 0)
- /* reabable or writable, go loop*/
- continue;
- else if(0 == rc) {
- /* timeout */
- failf(data, "SSL connection timeout");
- return CURLE_OPERATION_TIMEDOUT;
- }
- else {
- /* anything that gets here is fatally bad */
- failf(data, "select on SSL socket, errno: %d", Curl_sockerrno());
- return CURLE_SSL_CONNECT_ERROR;
- }
- }
- else
- break;
- } while(1);
-
- if (rc < 0) {
- failf(data, "gnutls_handshake() failed: %s", gnutls_strerror(rc));
- return CURLE_SSL_CONNECT_ERROR;
- }
-
- return CURLE_OK;
-}
-
-static gnutls_x509_crt_fmt do_file_type(const char *type)
-{
- if(!type || !type[0])
- return GNUTLS_X509_FMT_PEM;
- if(curl_strequal(type, "PEM"))
- return GNUTLS_X509_FMT_PEM;
- if(curl_strequal(type, "DER"))
- return GNUTLS_X509_FMT_DER;
- return -1;
-}
-
-
-/*
- * This function is called after the TCP connect has completed. Setup the TLS
- * layer and do all necessary magic.
- */
-CURLcode
-Curl_gtls_connect(struct connectdata *conn,
- int sockindex)
-
-{
- const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
- struct SessionHandle *data = conn->data;
- gnutls_session session;
- int rc;
- unsigned int cert_list_size;
- const gnutls_datum *chainp;
- unsigned int verify_status;
- gnutls_x509_crt x509_cert;
- char certbuf[256]; /* big enough? */
- size_t size;
- unsigned int algo;
- unsigned int bits;
- time_t clock;
- const char *ptr;
- void *ssl_sessionid;
- size_t ssl_idsize;
-
- /* GnuTLS only supports TLSv1 (and SSLv3?) */
- if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
- failf(data, "GnuTLS does not support SSLv2");
- return CURLE_SSL_CONNECT_ERROR;
- }
-
- /* allocate a cred struct */
- rc = gnutls_certificate_allocate_credentials(&conn->ssl[sockindex].cred);
- if(rc < 0) {
- failf(data, "gnutls_cert_all_cred() failed: %s", gnutls_strerror(rc));
- return CURLE_SSL_CONNECT_ERROR;
- }
-
- if(data->set.ssl.CAfile) {
- /* set the trusted CA cert bundle file */
- gnutls_certificate_set_verify_flags(conn->ssl[sockindex].cred,
- GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
-
- rc = gnutls_certificate_set_x509_trust_file(conn->ssl[sockindex].cred,
- data->set.ssl.CAfile,
- GNUTLS_X509_FMT_PEM);
- if(rc < 0) {
- infof(data, "error reading ca cert file %s (%s)\n",
- data->set.ssl.CAfile, gnutls_strerror(rc));
- if (data->set.ssl.verifypeer)
- return CURLE_SSL_CACERT_BADFILE;
- }
- else
- infof(data, "found %d certificates in %s\n",
- rc, data->set.ssl.CAfile);
- }
-
- /* Initialize TLS session as a client */
- rc = gnutls_init(&conn->ssl[sockindex].session, GNUTLS_CLIENT);
- if(rc) {
- failf(data, "gnutls_init() failed: %d", rc);
- return CURLE_SSL_CONNECT_ERROR;
- }
-
- /* convenient assign */
- session = conn->ssl[sockindex].session;
-
- /* Use default priorities */
- rc = gnutls_set_default_priority(session);
- if(rc < 0)
- return CURLE_SSL_CONNECT_ERROR;
-
- /* Sets the priority on the certificate types supported by gnutls. Priority
- is higher for types specified before others. After specifying the types
- you want, you must append a 0. */
- rc = gnutls_certificate_type_set_priority(session, cert_type_priority);
- if(rc < 0)
- return CURLE_SSL_CONNECT_ERROR;
-
- if(data->set.cert) {
- if( gnutls_certificate_set_x509_key_file(
- conn->ssl[sockindex].cred, data->set.cert,
- data->set.key != 0 ? data->set.key : data->set.cert,
- do_file_type(data->set.cert_type) ) ) {
- failf(data, "error reading X.509 key or certificate file");
- return CURLE_SSL_CONNECT_ERROR;
- }
- }
-
- /* put the credentials to the current session */
- rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
- conn->ssl[sockindex].cred);
-
- /* set the connection handle (file descriptor for the socket) */
- gnutls_transport_set_ptr(session,
- (gnutls_transport_ptr)conn->sock[sockindex]);
-
- /* register callback functions to send and receive data. */
- gnutls_transport_set_push_function(session, Curl_gtls_push);
- gnutls_transport_set_pull_function(session, Curl_gtls_pull);
-
- /* lowat must be set to zero when using custom push and pull functions. */
- gnutls_transport_set_lowat(session, 0);
-
- /* This might be a reconnect, so we check for a session ID in the cache
- to speed up things */
-
- if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, &ssl_idsize)) {
- /* we got a session id, use it! */
- gnutls_session_set_data(session, ssl_sessionid, ssl_idsize);
-
- /* Informational message */
- infof (data, "SSL re-using session ID\n");
- }
-
- rc = handshake(conn, session, sockindex, TRUE);
- if(rc)
- /* handshake() sets its own error message with failf() */
- return rc;
-
- /* This function will return the peer's raw certificate (chain) as sent by
- the peer. These certificates are in raw format (DER encoded for
- X.509). In case of a X.509 then a certificate list may be present. The
- first certificate in the list is the peer's certificate, following the
- issuer's certificate, then the issuer's issuer etc. */
-
- chainp = gnutls_certificate_get_peers(session, &cert_list_size);
- if(!chainp) {
- if(data->set.ssl.verifyhost) {
- failf(data, "failed to get server cert");
- return CURLE_SSL_PEER_CERTIFICATE;
- }
- infof(data, "\t common name: WARNING couldn't obtain\n");
- }
-
- /* This function will try to verify the peer's certificate and return its
- status (trusted, invalid etc.). The value of status should be one or more
- of the gnutls_certificate_status_t enumerated elements bitwise or'd. To
- avoid denial of service attacks some default upper limits regarding the
- certificate key size and chain size are set. To override them use
- gnutls_certificate_set_verify_limits(). */
-
- rc = gnutls_certificate_verify_peers2(session, &verify_status);
- if (rc < 0) {
- failf(data, "server cert verify failed: %d", rc);
- return CURLE_SSL_CONNECT_ERROR;
- }
-
- /* verify_status is a bitmask of gnutls_certificate_status bits */
- if(verify_status & GNUTLS_CERT_INVALID) {
- if (data->set.ssl.verifypeer) {
- failf(data, "server certificate verification failed. CAfile: %s",
- data->set.ssl.CAfile?data->set.ssl.CAfile:"none");
- return CURLE_SSL_CACERT;
- }
- else
- infof(data, "\t server certificate verification FAILED\n");
- }
- else
- infof(data, "\t server certificate verification OK\n");
-
- /* initialize an X.509 certificate structure. */
- gnutls_x509_crt_init(&x509_cert);
-
- /* convert the given DER or PEM encoded Certificate to the native
- gnutls_x509_crt_t format */
- gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER);
-
- size=sizeof(certbuf);
- rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME,
- 0, /* the first and only one */
- FALSE,
- certbuf,
- &size);
- if(rc) {
- infof(data, "error fetching CN from cert:%s\n",
- gnutls_strerror(rc));
- }
-
- /* This function will check if the given certificate's subject matches the
- given hostname. This is a basic implementation of the matching described
- in RFC2818 (HTTPS), which takes into account wildcards, and the subject
- alternative name PKIX extension. Returns non zero on success, and zero on
- failure. */
- rc = gnutls_x509_crt_check_hostname(x509_cert, conn->host.name);
-
- if(!rc) {
- if (data->set.ssl.verifyhost > 1) {
- failf(data, "SSL: certificate subject name (%s) does not match "
- "target host name '%s'", certbuf, conn->host.dispname);
- gnutls_x509_crt_deinit(x509_cert);
- return CURLE_SSL_PEER_CERTIFICATE;
- }
- else
- infof(data, "\t common name: %s (does not match '%s')\n",
- certbuf, conn->host.dispname);
- }
- else
- infof(data, "\t common name: %s (matched)\n", certbuf);
-
- /* Show:
-
- - ciphers used
- - subject
- - start date
- - expire date
- - common name
- - issuer
-
- */
-
- /* public key algorithm's parameters */
- algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &bits);
- infof(data, "\t certificate public key: %s\n",
- gnutls_pk_algorithm_get_name(algo));
-
- /* version of the X.509 certificate. */
- infof(data, "\t certificate version: #%d\n",
- gnutls_x509_crt_get_version(x509_cert));
-
-
- size = sizeof(certbuf);
- gnutls_x509_crt_get_dn(x509_cert, certbuf, &size);
- infof(data, "\t subject: %s\n", certbuf);
-
- clock = gnutls_x509_crt_get_activation_time(x509_cert);
- showtime(data, "start date", clock);
-
- clock = gnutls_x509_crt_get_expiration_time(x509_cert);
- showtime(data, "expire date", clock);
-
- size = sizeof(certbuf);
- gnutls_x509_crt_get_issuer_dn(x509_cert, certbuf, &size);
- infof(data, "\t issuer: %s\n", certbuf);
-
- gnutls_x509_crt_deinit(x509_cert);
-
- /* compression algorithm (if any) */
- ptr = gnutls_compression_get_name(gnutls_compression_get(session));
- /* the *_get_name() says "NULL" if GNUTLS_COMP_NULL is returned */
- infof(data, "\t compression: %s\n", ptr);
-
- /* the name of the cipher used. ie 3DES. */
- ptr = gnutls_cipher_get_name(gnutls_cipher_get(session));
- infof(data, "\t cipher: %s\n", ptr);
-
- /* the MAC algorithms name. ie SHA1 */
- ptr = gnutls_mac_get_name(gnutls_mac_get(session));
- infof(data, "\t MAC: %s\n", ptr);
-
- if(!ssl_sessionid) {
- /* this session was not previously in the cache, add it now */
-
- /* get the session ID data size */
- gnutls_session_get_data(session, NULL, &ssl_idsize);
- ssl_sessionid = malloc(ssl_idsize); /* get a buffer for it */
-
- if(ssl_sessionid) {
- /* extract session ID to the allocated buffer */
- gnutls_session_get_data(session, ssl_sessionid, &ssl_idsize);
-
- /* store this session id */
- return Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_idsize);
- }
- }
-
- return CURLE_OK;
-}
-
-
-/* return number of sent (non-SSL) bytes */
-ssize_t Curl_gtls_send(struct connectdata *conn,
- int sockindex,
- void *mem,
- size_t len)
-{
- ssize_t rc = gnutls_record_send(conn->ssl[sockindex].session, mem, len);
-
- if(rc < 0 ) {
- if(rc == GNUTLS_E_AGAIN)
- return 0; /* EWOULDBLOCK equivalent */
- rc = -1; /* generic error code for send failure */
- }
-
- return rc;
-}
-
-void Curl_gtls_close_all(struct SessionHandle *data)
-{
- /* FIX: make the OpenSSL code more generic and use parts of it here */
- (void)data;
-}
-
-static void close_one(struct connectdata *conn,
- int index)
-{
- if(conn->ssl[index].session) {
- gnutls_bye(conn->ssl[index].session, GNUTLS_SHUT_RDWR);
- gnutls_deinit(conn->ssl[index].session);
- }
- gnutls_certificate_free_credentials(conn->ssl[index].cred);
-}
-
-void Curl_gtls_close(struct connectdata *conn)
-{
- if(conn->ssl[0].use)
- close_one(conn, 0);
- if(conn->ssl[1].use)
- close_one(conn, 1);
-}
-
-/*
- * This function is called to shut down the SSL layer but keep the
- * socket open (CCC - Clear Command Channel)
- */
-int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
-{
- int result;
- int retval = 0;
- struct SessionHandle *data = conn->data;
- int done = 0;
- ssize_t nread;
- char buf[120];
-
- /* This has only been tested on the proftpd server, and the mod_tls code
- sends a close notify alert without waiting for a close notify alert in
- response. Thus we wait for a close notify alert from the server, but
- we do not send one. Let's hope other servers do the same... */
-
- if(conn->ssl[sockindex].session) {
- while(!done) {
- int what = Curl_select(conn->sock[sockindex],
- CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
- if(what > 0) {
- /* Something to read, let's do it and hope that it is the close
- notify alert from the server */
- result = gnutls_record_recv(conn->ssl[sockindex].session,
- buf, sizeof(buf));
- switch(result) {
- case 0:
- /* This is the expected response. There was no data but only
- the close notify alert */
- done = 1;
- break;
- case GNUTLS_E_AGAIN:
- case GNUTLS_E_INTERRUPTED:
- infof(data, "GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED\n");
- break;
- default:
- retval = -1;
- done = 1;
- break;
- }
- }
- else if(0 == what) {
- /* timeout */
- failf(data, "SSL shutdown timeout");
- done = 1;
- break;
- }
- else {
- /* anything that gets here is fatally bad */
- failf(data, "select on SSL socket, errno: %d", Curl_sockerrno());
- retval = -1;
- done = 1;
- }
- }
- gnutls_deinit(conn->ssl[sockindex].session);
- }
- gnutls_certificate_free_credentials(conn->ssl[sockindex].cred);
-
- conn->ssl[sockindex].session = NULL;
- conn->ssl[sockindex].use = FALSE;
-
- return retval;
-}
-
-/*
- * If the read would block we return -1 and set 'wouldblock' to TRUE.
- * Otherwise we return the amount of data read. Other errors should return -1
- * and set 'wouldblock' to FALSE.
- */
-ssize_t Curl_gtls_recv(struct connectdata *conn, /* connection data */
- int num, /* socketindex */
- char *buf, /* store read data here */
- size_t buffersize, /* max amount to read */
- bool *wouldblock)
-{
- ssize_t ret;
-
- ret = gnutls_record_recv(conn->ssl[num].session, buf, buffersize);
- if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) {
- *wouldblock = TRUE;
- return -1;
- }
-
- if(ret == GNUTLS_E_REHANDSHAKE) {
- /* BLOCKING call, this is bad but a work-around for now. Fixing this "the
- proper way" takes a whole lot of work. */
- CURLcode rc = handshake(conn, conn->ssl[num].session, num, FALSE);
- if(rc)
- /* handshake() writes error message on its own */
- return rc;
- *wouldblock = TRUE; /* then return as if this was a wouldblock */
- return -1;
- }
-
- *wouldblock = FALSE;
- if (!ret) {
- failf(conn->data, "Peer closed the TLS connection");
- return -1;
- }
-
- if (ret < 0) {
- failf(conn->data, "GnuTLS recv error (%d): %s",
- (int)ret, gnutls_strerror(ret));
- return -1;
- }
-
- return ret;
-}
-
-void Curl_gtls_session_free(void *ptr)
-{
- free(ptr);
-}
-
-size_t Curl_gtls_version(char *buffer, size_t size)
-{
- return snprintf(buffer, size, " GnuTLS/%s", gnutls_check_version(NULL));
-}
-
-#endif /* USE_GNUTLS */
diff --git a/Utilities/cmcurl/gtls.h b/Utilities/cmcurl/gtls.h
deleted file mode 100644
index bff3f8693..000000000
--- a/Utilities/cmcurl/gtls.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef __GTLS_H
-#define __GTLS_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-int Curl_gtls_init(void);
-int Curl_gtls_cleanup(void);
-CURLcode Curl_gtls_connect(struct connectdata *conn, int sockindex);
-
-/* tell GnuTLS to close down all open information regarding connections (and
- thus session ID caching etc) */
-void Curl_gtls_close_all(struct SessionHandle *data);
-void Curl_gtls_close(struct connectdata *conn); /* close a SSL connection */
-
-/* return number of sent (non-SSL) bytes */
-ssize_t Curl_gtls_send(struct connectdata *conn, int sockindex,
- void *mem, size_t len);
-ssize_t Curl_gtls_recv(struct connectdata *conn, /* connection data */
- int num, /* socketindex */
- char *buf, /* store read data here */
- size_t buffersize, /* max amount to read */
- bool *wouldblock);
-void Curl_gtls_session_free(void *ptr);
-size_t Curl_gtls_version(char *buffer, size_t size);
-int Curl_gtls_shutdown(struct connectdata *conn, int sockindex);
-
-#endif
diff --git a/Utilities/cmcurl/hash.c b/Utilities/cmcurl/hash.c
deleted file mode 100644
index e00462778..000000000
--- a/Utilities/cmcurl/hash.c
+++ /dev/null
@@ -1,315 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#include <string.h>
-#include <stdlib.h>
-
-#include "hash.h"
-#include "llist.h"
-#include "memory.h"
-
-/* this must be the last include file */
-#include "memdebug.h"
-
-static unsigned long
-hash_str(const char *key, size_t key_length)
-{
- char *end = (char *) key + key_length;
- unsigned long h = 5381;
-
- while (key < end) {
- h += h << 5;
- h ^= (unsigned long) *key++;
- }
-
- return h;
-}
-
-static void
-hash_element_dtor(void *user, void *element)
-{
- struct curl_hash *h = (struct curl_hash *) user;
- struct curl_hash_element *e = (struct curl_hash_element *) element;
-
- if (e->key)
- free(e->key);
-
- h->dtor(e->ptr);
-
- free(e);
-}
-
-/* return 1 on error, 0 is fine */
-int
-Curl_hash_init(struct curl_hash *h, int slots, curl_hash_dtor dtor)
-{
- int i;
-
- h->dtor = dtor;
- h->size = 0;
- h->slots = slots;
-
- h->table = (struct curl_llist **) malloc(slots * sizeof(struct curl_llist *));
- if(h->table) {
- for (i = 0; i < slots; ++i) {
- h->table[i] = Curl_llist_alloc((curl_llist_dtor) hash_element_dtor);
- if(!h->table[i]) {
- while(i--)
- Curl_llist_destroy(h->table[i], NULL);
- free(h->table);
- return 1; /* failure */
- }
- }
- return 0; /* fine */
- }
- else
- return 1; /* failure */
-}
-
-struct curl_hash *
-Curl_hash_alloc(int slots, curl_hash_dtor dtor)
-{
- struct curl_hash *h;
-
- h = (struct curl_hash *) malloc(sizeof(struct curl_hash));
- if (h) {
- if(Curl_hash_init(h, slots, dtor)) {
- /* failure */
- free(h);
- h = NULL;
- }
- }
-
- return h;
-}
-
-static int
-hash_key_compare(char *key1, size_t key1_len, char *key2, size_t key2_len)
-{
- if (key1_len == key2_len &&
- *key1 == *key2 &&
- memcmp(key1, key2, key1_len) == 0) {
- return 1;
- }
-
- return 0;
-}
-
-static struct curl_hash_element *
-mk_hash_element(char *key, size_t key_len, const void *p)
-{
- struct curl_hash_element *he =
- (struct curl_hash_element *) malloc(sizeof(struct curl_hash_element));
-
- if(he) {
- char *dup = malloc(key_len);
- if(dup) {
- /* copy the key */
- memcpy(dup, key, key_len);
-
- he->key = dup;
- he->key_len = key_len;
- he->ptr = (void *) p;
- }
- else {
- /* failed to duplicate the key, free memory and fail */
- free(he);
- he = NULL;
- }
- }
- return he;
-}
-
-#define find_slot(__h, __k, __k_len) (hash_str(__k, __k_len) % (__h)->slots)
-
-#define FETCH_LIST(x,y,z) x->table[find_slot(x, y, z)]
-
-/* Return the data in the hash. If there already was a match in the hash,
- that data is returned. */
-void *
-Curl_hash_add(struct curl_hash *h, char *key, size_t key_len, void *p)
-{
- struct curl_hash_element *he;
- struct curl_llist_element *le;
- struct curl_llist *l = FETCH_LIST(h, key, key_len);
-
- for (le = l->head; le; le = le->next) {
- he = (struct curl_hash_element *) le->ptr;
- if (hash_key_compare(he->key, he->key_len, key, key_len)) {
- h->dtor(p); /* remove the NEW entry */
- return he->ptr; /* return the EXISTING entry */
- }
- }
-
- he = mk_hash_element(key, key_len, p);
- if (he) {
- if(Curl_llist_insert_next(l, l->tail, he)) {
- ++h->size;
- return p; /* return the new entry */
- }
- /*
- * Couldn't insert it, destroy the 'he' element and the key again. We
- * don't call hash_element_dtor() since that would also call the
- * "destructor" for the actual data 'p'. When we fail, we shall not touch
- * that data.
- */
- free(he->key);
- free(he);
- }
-
- return NULL; /* failure */
-}
-
-/* remove the identified hash entry, returns non-zero on failure */
-int Curl_hash_delete(struct curl_hash *h, char *key, size_t key_len)
-{
- struct curl_llist_element *le;
- struct curl_hash_element *he;
- struct curl_llist *l = FETCH_LIST(h, key, key_len);
-
- for (le = l->head; le; le = le->next) {
- he = le->ptr;
- if (hash_key_compare(he->key, he->key_len, key, key_len)) {
- Curl_llist_remove(l, le, (void *) h);
- return 0;
- }
- }
- return 1;
-}
-
-void *
-Curl_hash_pick(struct curl_hash *h, char *key, size_t key_len)
-{
- struct curl_llist_element *le;
- struct curl_hash_element *he;
- struct curl_llist *l = FETCH_LIST(h, key, key_len);
-
- for (le = l->head; le; le = le->next) {
- he = le->ptr;
- if (hash_key_compare(he->key, he->key_len, key, key_len)) {
- return he->ptr;
- }
- }
-
- return NULL;
-}
-
-#if defined(CURLDEBUG) && defined(AGGRESIVE_TEST)
-void
-Curl_hash_apply(curl_hash *h, void *user,
- void (*cb)(void *user, void *ptr))
-{
- struct curl_llist_element *le;
- int i;
-
- for (i = 0; i < h->slots; ++i) {
- for (le = (h->table[i])->head;
- le;
- le = le->next) {
- curl_hash_element *el = le->ptr;
- cb(user, el->ptr);
- }
- }
-}
-#endif
-
-void
-Curl_hash_clean(struct curl_hash *h)
-{
- int i;
-
- for (i = 0; i < h->slots; ++i) {
- Curl_llist_destroy(h->table[i], (void *) h);
- }
-
- free(h->table);
-}
-
-void
-Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
- int (*comp)(void *, void *))
-{
- struct curl_llist_element *le;
- struct curl_llist_element *lnext;
- struct curl_llist *list;
- int i;
-
- for (i = 0; i < h->slots; ++i) {
- list = h->table[i];
- le = list->head; /* get first list entry */
- while(le) {
- struct curl_hash_element *he = le->ptr;
- lnext = le->next;
- /* ask the callback function if we shall remove this entry or not */
- if (comp(user, he->ptr)) {
- Curl_llist_remove(list, le, (void *) h);
- --h->size; /* one less entry in the hash now */
- }
- le = lnext;
- }
- }
-}
-
-void
-Curl_hash_destroy(struct curl_hash *h)
-{
- if (!h)
- return;
-
- Curl_hash_clean(h);
- free(h);
-}
-
-#if 0 /* useful function for debugging hashes and their contents */
-void Curl_hash_print(struct curl_hash *h,
- void (*func)(void *))
-{
- int i;
- struct curl_llist_element *le;
- struct curl_llist *list;
- struct curl_hash_element *he;
- if (!h)
- return;
-
- fprintf(stderr, "=Hash dump=\n");
-
- for (i = 0; i < h->slots; i++) {
- list = h->table[i];
- le = list->head; /* get first list entry */
- if(le) {
- fprintf(stderr, "index %d:", i);
- while(le) {
- he = le->ptr;
- if(func)
- func(he->ptr);
- else
- fprintf(stderr, " [%p]", he->ptr);
- le = le->next;
- }
- fprintf(stderr, "\n");
- }
- }
-}
-#endif
diff --git a/Utilities/cmcurl/hash.h b/Utilities/cmcurl/hash.h
deleted file mode 100644
index ceebb5234..000000000
--- a/Utilities/cmcurl/hash.h
+++ /dev/null
@@ -1,61 +0,0 @@
-#ifndef __HASH_H
-#define __HASH_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#include <stddef.h>
-
-#include "llist.h"
-
-typedef void (*curl_hash_dtor)(void *);
-
-struct curl_hash {
- struct curl_llist **table;
- curl_hash_dtor dtor;
- int slots;
- size_t size;
-};
-
-struct curl_hash_element {
- void *ptr;
- char *key;
- size_t key_len;
-};
-
-
-int Curl_hash_init(struct curl_hash *, int, curl_hash_dtor);
-struct curl_hash *Curl_hash_alloc(int, curl_hash_dtor);
-void *Curl_hash_add(struct curl_hash *, char *, size_t, void *);
-int Curl_hash_delete(struct curl_hash *h, char *key, size_t key_len);
-void *Curl_hash_pick(struct curl_hash *, char *, size_t);
-void Curl_hash_apply(struct curl_hash *h, void *user,
- void (*cb)(void *user, void *ptr));
-int Curl_hash_count(struct curl_hash *h);
-void Curl_hash_clean(struct curl_hash *h);
-void Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
- int (*comp)(void *, void *));
-void Curl_hash_destroy(struct curl_hash *h);
-
-#endif
diff --git a/Utilities/cmcurl/hostares.c b/Utilities/cmcurl/hostares.c
deleted file mode 100644
index 1db0f4320..000000000
--- a/Utilities/cmcurl/hostares.c
+++ /dev/null
@@ -1,307 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#include <string.h>
-
-#ifdef NEED_MALLOC_H
-#include <malloc.h>
-#endif
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h> /* required for free() prototypes */
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h> /* for the close() proto */
-#endif
-#ifdef VMS
-#include <in.h>
-#include <inet.h>
-#include <stdlib.h>
-#endif
-
-#ifdef HAVE_SETJMP_H
-#include <setjmp.h>
-#endif
-
-#ifdef HAVE_PROCESS_H
-#include <process.h>
-#endif
-
-#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
-#undef in_addr_t
-#define in_addr_t unsigned long
-#endif
-
-#include "urldata.h"
-#include "sendf.h"
-#include "hostip.h"
-#include "hash.h"
-#include "share.h"
-#include "strerror.h"
-#include "url.h"
-#include "multiif.h"
-#include "connect.h" /* for the Curl_sockerrno() proto */
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
-#include "inet_ntoa_r.h"
-#endif
-
-#include "memory.h"
-
-/* The last #include file should be: */
-#include "memdebug.h"
-
-/***********************************************************************
- * Only for ares-enabled builds
- **********************************************************************/
-
-#ifdef CURLRES_ARES
-
-/*
- * Curl_resolv_fdset() is called when someone from the outside world (using
- * curl_multi_fdset()) wants to get our fd_set setup and we're talking with
- * ares. The caller must make sure that this function is only called when we
- * have a working ares channel.
- *
- * Returns: CURLE_OK always!
- */
-
-int Curl_resolv_getsock(struct connectdata *conn,
- curl_socket_t *socks,
- int numsocks)
-
-{
- struct timeval maxtime;
- struct timeval timeout;
- int max = ares_getsock(conn->data->state.areschannel,
- (int *)socks, numsocks);
-
-
- maxtime.tv_sec = CURL_TIMEOUT_RESOLVE;
- maxtime.tv_usec = 0;
-
- ares_timeout(conn->data->state.areschannel, &maxtime, &timeout);
-
- Curl_expire(conn->data,
- (timeout.tv_sec * 1000) + (timeout.tv_usec/1000) );
-
- return max;
-}
-
-/*
- * Curl_is_resolved() is called repeatedly to check if a previous name resolve
- * request has completed. It should also make sure to time-out if the
- * operation seems to take too long.
- *
- * Returns normal CURLcode errors.
- */
-CURLcode Curl_is_resolved(struct connectdata *conn,
- struct Curl_dns_entry **dns)
-{
- fd_set read_fds, write_fds;
- struct timeval tv={0,0};
- struct SessionHandle *data = conn->data;
- int nfds;
-
- FD_ZERO(&read_fds);
- FD_ZERO(&write_fds);
-
- nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);
-
- (void)select(nfds, &read_fds, &write_fds, NULL,
- (struct timeval *)&tv);
-
- /* Call ares_process() unconditonally here, even if we simply timed out
- above, as otherwise the ares name resolve won't timeout! */
- ares_process(data->state.areschannel, &read_fds, &write_fds);
-
- *dns = NULL;
-
- if(conn->async.done) {
- /* we're done, kill the ares handle */
- if(!conn->async.dns) {
- failf(data, "Could not resolve host: %s (%s)", conn->host.dispname,
- ares_strerror(conn->async.status));
- return CURLE_COULDNT_RESOLVE_HOST;
- }
- *dns = conn->async.dns;
- }
-
- return CURLE_OK;
-}
-
-/*
- * Curl_wait_for_resolv() waits for a resolve to finish. This function should
- * be avoided since using this risk getting the multi interface to "hang".
- *
- * If 'entry' is non-NULL, make it point to the resolved dns entry
- *
- * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, and
- * CURLE_OPERATION_TIMEDOUT if a time-out occurred.
- */
-CURLcode Curl_wait_for_resolv(struct connectdata *conn,
- struct Curl_dns_entry **entry)
-{
- CURLcode rc=CURLE_OK;
- struct SessionHandle *data = conn->data;
- long timeout = CURL_TIMEOUT_RESOLVE; /* default name resolve timeout */
-
- /* now, see if there's a connect timeout or a regular timeout to
- use instead of the default one */
- if(conn->data->set.connecttimeout)
- timeout = conn->data->set.connecttimeout;
- else if(conn->data->set.timeout)
- timeout = conn->data->set.timeout;
-
- /* We convert the number of seconds into number of milliseconds here: */
- if(timeout < 2147483)
- /* maximum amount of seconds that can be multiplied with 1000 and
- still fit within 31 bits */
- timeout *= 1000;
- else
- timeout = 0x7fffffff; /* ridiculous amount of time anyway */
-
- /* Wait for the name resolve query to complete. */
- while (1) {
- int nfds=0;
- fd_set read_fds, write_fds;
- struct timeval *tvp, tv, store;
- int count;
- struct timeval now = Curl_tvnow();
- long timediff;
-
- store.tv_sec = (int)timeout/1000;
- store.tv_usec = (timeout%1000)*1000;
-
- FD_ZERO(&read_fds);
- FD_ZERO(&write_fds);
- nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);
- if (nfds == 0)
- /* no file descriptors means we're done waiting */
- break;
- tvp = ares_timeout(data->state.areschannel, &store, &tv);
- count = select(nfds, &read_fds, &write_fds, NULL, tvp);
- if (count < 0 && Curl_sockerrno() != EINVAL)
- break;
-
- ares_process(data->state.areschannel, &read_fds, &write_fds);
-
- timediff = Curl_tvdiff(Curl_tvnow(), now); /* spent time */
- timeout -= timediff?timediff:1; /* always deduct at least 1 */
- if (timeout < 0) {
- /* our timeout, so we cancel the ares operation */
- ares_cancel(data->state.areschannel);
- break;
- }
- }
-
- /* Operation complete, if the lookup was successful we now have the entry
- in the cache. */
-
- if(entry)
- *entry = conn->async.dns;
-
- if(!conn->async.dns) {
- /* a name was not resolved */
- if((timeout < 0) || (conn->async.status == ARES_ETIMEOUT)) {
- failf(data, "Resolving host timed out: %s", conn->host.dispname);
- rc = CURLE_OPERATION_TIMEDOUT;
- }
- else if(conn->async.done) {
- failf(data, "Could not resolve host: %s (%s)", conn->host.dispname,
- ares_strerror(conn->async.status));
- rc = CURLE_COULDNT_RESOLVE_HOST;
- }
- else
- rc = CURLE_OPERATION_TIMEDOUT;
-
- /* close the connection, since we can't return failure here without
- cleaning up this connection properly */
- conn->bits.close = TRUE;
- }
-
- return rc;
-}
-
-/*
- * Curl_getaddrinfo() - when using ares
- *
- * Returns name information about the given hostname and port number. If
- * successful, the 'hostent' is returned and the forth argument will point to
- * memory we need to free after use. That memory *MUST* be freed with
- * Curl_freeaddrinfo(), nothing else.
- */
-Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
- const char *hostname,
- int port,
- int *waitp)
-{
- char *bufp;
- struct SessionHandle *data = conn->data;
- in_addr_t in = inet_addr(hostname);
-
- *waitp = FALSE;
-
- if (in != CURL_INADDR_NONE) {
- /* This is a dotted IP address 123.123.123.123-style */
- return Curl_ip2addr(in, hostname, port);
- }
-
- bufp = strdup(hostname);
-
- if(bufp) {
- Curl_safefree(conn->async.hostname);
- conn->async.hostname = bufp;
- conn->async.port = port;
- conn->async.done = FALSE; /* not done */
- conn->async.status = 0; /* clear */
- conn->async.dns = NULL; /* clear */
-
- /* areschannel is already setup in the Curl_open() function */
- ares_gethostbyname(data->state.areschannel, hostname, PF_INET,
- (ares_host_callback)Curl_addrinfo4_callback, conn);
-
- *waitp = TRUE; /* please wait for the response */
- }
- return NULL; /* no struct yet */
-}
-#endif /* CURLRES_ARES */
diff --git a/Utilities/cmcurl/hostasyn.c b/Utilities/cmcurl/hostasyn.c
deleted file mode 100644
index 3df147910..000000000
--- a/Utilities/cmcurl/hostasyn.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#include <string.h>
-
-#ifdef NEED_MALLOC_H
-#include <malloc.h>
-#endif
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h> /* required for free() prototypes */
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h> /* for the close() proto */
-#endif
-#ifdef VMS
-#include <in.h>
-#include <inet.h>
-#include <stdlib.h>
-#endif
-
-#ifdef HAVE_SETJMP_H
-#include <setjmp.h>
-#endif
-
-#ifdef HAVE_PROCESS_H
-#include <process.h>
-#endif
-
-#include "urldata.h"
-#include "sendf.h"
-#include "hostip.h"
-#include "hash.h"
-#include "share.h"
-#include "strerror.h"
-#include "url.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
-#include "inet_ntoa_r.h"
-#endif
-
-#include "memory.h"
-/* The last #include file should be: */
-#include "memdebug.h"
-
-/***********************************************************************
- * Only for builds using asynchronous name resolves
- **********************************************************************/
-#ifdef CURLRES_ASYNCH
-/*
- * addrinfo_callback() gets called by ares, gethostbyname_thread() or
- * getaddrinfo_thread() when we got the name resolved (or not!).
- *
- * If the status argument is CURL_ASYNC_SUCCESS, we might need to copy the
- * address field since it might be freed when this function returns. This
- * operation stores the resolved data in the DNS cache.
- *
- * NOTE: for IPv6 operations, Curl_addrinfo_copy() returns the same
- * pointer it is given as argument!
- *
- * The storage operation locks and unlocks the DNS cache.
- */
-static CURLcode addrinfo_callback(void *arg, /* "struct connectdata *" */
- int status,
- void *addr)
-{
- struct connectdata *conn = (struct connectdata *)arg;
- struct Curl_dns_entry *dns = NULL;
- CURLcode rc = CURLE_OK;
-
- conn->async.status = status;
-
- if(CURL_ASYNC_SUCCESS == status) {
-
- /*
- * IPv4/ares: Curl_addrinfo_copy() copies the address and returns an
- * allocated version.
- *
- * IPv6: Curl_addrinfo_copy() returns the input pointer!
- */
- Curl_addrinfo *ai = Curl_addrinfo_copy(addr, conn->async.port);
- if(ai) {
- struct SessionHandle *data = conn->data;
-
- if(data->share)
- Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
-
- dns = Curl_cache_addr(data, ai,
- conn->async.hostname,
- conn->async.port);
- if(!dns) {
- /* failed to store, cleanup and return error */
- Curl_freeaddrinfo(ai);
- rc = CURLE_OUT_OF_MEMORY;
- }
-
- if(data->share)
- Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
- }
- else
- rc = CURLE_OUT_OF_MEMORY;
- }
-
- conn->async.dns = dns;
-
- /* Set async.done TRUE last in this function since it may be used multi-
- threaded and once this is TRUE the other thread may read fields from the
- async struct */
- conn->async.done = TRUE;
-
- /* ipv4: The input hostent struct will be freed by ares when we return from
- this function */
- return rc;
-}
-
-CURLcode Curl_addrinfo4_callback(void *arg, /* "struct connectdata *" */
- int status,
- struct hostent *hostent)
-{
- return addrinfo_callback(arg, status, hostent);
-}
-
-#ifdef CURLRES_IPV6
-CURLcode Curl_addrinfo6_callback(void *arg, /* "struct connectdata *" */
- int status,
- struct addrinfo *ai)
-{
- /* NOTE: for CURLRES_ARES, the 'ai' argument is really a
- * 'struct hostent' pointer.
- */
- return addrinfo_callback(arg, status, ai);
-}
-#endif
-
-#endif /* CURLRES_ASYNC */
diff --git a/Utilities/cmcurl/hostip.c b/Utilities/cmcurl/hostip.c
deleted file mode 100644
index fd555ef9d..000000000
--- a/Utilities/cmcurl/hostip.c
+++ /dev/null
@@ -1,636 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#include <string.h>
-
-#ifdef NEED_MALLOC_H
-#include <malloc.h>
-#endif
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h> /* required for free() prototypes */
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h> /* for the close() proto */
-#endif
-#ifdef VMS
-#include <in.h>
-#include <inet.h>
-#include <stdlib.h>
-#endif
-
-#ifdef HAVE_SETJMP_H
-#include <setjmp.h>
-#endif
-
-#ifdef HAVE_PROCESS_H
-#include <process.h>
-#endif
-
-#include "urldata.h"
-#include "sendf.h"
-#include "hostip.h"
-#include "hash.h"
-#include "share.h"
-#include "strerror.h"
-#include "url.h"
-#include "inet_ntop.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
-#include "inet_ntoa_r.h"
-#endif
-
-#include "memory.h"
-/* The last #include file should be: */
-#include "memdebug.h"
-
-/*
- * hostip.c explained
- * ==================
- *
- * The main COMPILE-TIME DEFINES to keep in mind when reading the host*.c
- * source file are these:
- *
- * CURLRES_IPV6 - this host has getaddrinfo() and family, and thus we use
- * that. The host may not be able to resolve IPv6, but we don't really have to
- * take that into account. Hosts that aren't IPv6-enabled have CURLRES_IPV4
- * defined.
- *
- * CURLRES_ARES - is defined if libcurl is built to use c-ares for
- * asynchronous name resolves. This can be Windows or *nix.
- *
- * CURLRES_THREADED - is defined if libcurl is built to run under (native)
- * Windows, and then the name resolve will be done in a new thread, and the
- * supported API will be the same as for ares-builds.
- *
- * If any of the two previous are defined, CURLRES_ASYNCH is defined too. If
- * libcurl is not built to use an asynchronous resolver, CURLRES_SYNCH is
- * defined.
- *
- * The host*.c sources files are split up like this:
- *
- * hostip.c - method-independent resolver functions and utility functions
- * hostasyn.c - functions for asynchronous name resolves
- * hostsyn.c - functions for synchronous name resolves
- * hostares.c - functions for ares-using name resolves
- * hostthre.c - functions for threaded name resolves
- * hostip4.c - ipv4-specific functions
- * hostip6.c - ipv6-specific functions
- *
- * The hostip.h is the united header file for all this. It defines the
- * CURLRES_* defines based on the config*.h and setup.h defines.
- */
-
-/* These two symbols are for the global DNS cache */
-static struct curl_hash hostname_cache;
-static int host_cache_initialized;
-
-static void freednsentry(void *freethis);
-
-/*
- * Curl_global_host_cache_init() initializes and sets up a global DNS cache.
- * Global DNS cache is general badness. Do not use. This will be removed in
- * a future version. Use the share interface instead!
- */
-void Curl_global_host_cache_init(void)
-{
- if (!host_cache_initialized) {
- Curl_hash_init(&hostname_cache, 7, freednsentry);
- host_cache_initialized = 1;
- }
-}
-
-/*
- * Return a pointer to the global cache
- */
-struct curl_hash *Curl_global_host_cache_get(void)
-{
- return &hostname_cache;
-}
-
-/*
- * Destroy and cleanup the global DNS cache
- */
-void Curl_global_host_cache_dtor(void)
-{
- if (host_cache_initialized) {
- Curl_hash_clean(&hostname_cache);
- host_cache_initialized = 0;
- }
-}
-
-/*
- * Return # of adresses in a Curl_addrinfo struct
- */
-int Curl_num_addresses(const Curl_addrinfo *addr)
-{
- int i;
- for (i = 0; addr; addr = addr->ai_next, i++)
- ; /* empty loop */
- return i;
-}
-
-/*
- * Curl_printable_address() returns a printable version of the 1st address
- * given in the 'ip' argument. The result will be stored in the buf that is
- * bufsize bytes big.
- *
- * If the conversion fails, it returns NULL.
- */
-const char *Curl_printable_address(const Curl_addrinfo *ip,
- char *buf, size_t bufsize)
-{
- const void *ip4 = &((const struct sockaddr_in*)ip->ai_addr)->sin_addr;
- int af = ip->ai_family;
-#ifdef CURLRES_IPV6
- const void *ip6 = &((const struct sockaddr_in6*)ip->ai_addr)->sin6_addr;
-#else
- const void *ip6 = NULL;
-#endif
-
- return Curl_inet_ntop(af, af == AF_INET ? ip4 : ip6, buf, bufsize);
-}
-
-/*
- * Return a hostcache id string for the providing host + port, to be used by
- * the DNS caching.
- */
-static char *
-create_hostcache_id(const char *server, int port)
-{
- /* create and return the new allocated entry */
- return aprintf("%s:%d", server, port);
-}
-
-struct hostcache_prune_data {
- int cache_timeout;
- time_t now;
-};
-
-/*
- * This function is set as a callback to be called for every entry in the DNS
- * cache when we want to prune old unused entries.
- *
- * Returning non-zero means remove the entry, return 0 to keep it in the
- * cache.
- */
-static int
-hostcache_timestamp_remove(void *datap, void *hc)
-{
- struct hostcache_prune_data *data =
- (struct hostcache_prune_data *) datap;
- struct Curl_dns_entry *c = (struct Curl_dns_entry *) hc;
-
- if ((data->now - c->timestamp < data->cache_timeout) ||
- c->inuse) {
- /* please don't remove */
- return 0;
- }
-
- /* fine, remove */
- return 1;
-}
-
-/*
- * Prune the DNS cache. This assumes that a lock has already been taken.
- */
-static void
-hostcache_prune(struct curl_hash *hostcache, int cache_timeout, time_t now)
-{
- struct hostcache_prune_data user;
-
- user.cache_timeout = cache_timeout;
- user.now = now;
-
- Curl_hash_clean_with_criterium(hostcache,
- (void *) &user,
- hostcache_timestamp_remove);
-}
-
-/*
- * Library-wide function for pruning the DNS cache. This function takes and
- * returns the appropriate locks.
- */
-void Curl_hostcache_prune(struct SessionHandle *data)
-{
- time_t now;
-
- if((data->set.dns_cache_timeout == -1) || !data->dns.hostcache)
- /* cache forever means never prune, and NULL hostcache means
- we can't do it */
- return;
-
- if(data->share)
- Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
-
- time(&now);
-
- /* Remove outdated and unused entries from the hostcache */
- hostcache_prune(data->dns.hostcache,
- data->set.dns_cache_timeout,
- now);
-
- if(data->share)
- Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
-}
-
-static int
-remove_entry_if_stale(struct SessionHandle *data, struct Curl_dns_entry *dns)
-{
- struct hostcache_prune_data user;
-
- if( !dns || (data->set.dns_cache_timeout == -1) || !data->dns.hostcache)
- /* cache forever means never prune, and NULL hostcache means
- we can't do it */
- return 0;
-
- time(&user.now);
- user.cache_timeout = data->set.dns_cache_timeout;
-
- if ( !hostcache_timestamp_remove(&user,dns) )
- return 0;
-
- /* ok, we do need to clear the cache. although we need to remove just a
- single entry we clean the entire hash, as no explicit delete function
- is provided */
- if(data->share)
- Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
-
- Curl_hash_clean_with_criterium(data->dns.hostcache,
- (void *) &user,
- hostcache_timestamp_remove);
-
- if(data->share)
- Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
-
- return 1;
-}
-
-
-#ifdef HAVE_SIGSETJMP
-/* Beware this is a global and unique instance. This is used to store the
- return address that we can jump back to from inside a signal handler. This
- is not thread-safe stuff. */
-sigjmp_buf curl_jmpenv;
-#endif
-
-
-/*
- * Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache.
- *
- * When calling Curl_resolv() has resulted in a response with a returned
- * address, we call this function to store the information in the dns
- * cache etc
- *
- * Returns the Curl_dns_entry entry pointer or NULL if the storage failed.
- */
-struct Curl_dns_entry *
-Curl_cache_addr(struct SessionHandle *data,
- Curl_addrinfo *addr,
- const char *hostname,
- int port)
-{
- char *entry_id;
- size_t entry_len;
- struct Curl_dns_entry *dns;
- struct Curl_dns_entry *dns2;
- time_t now;
-
- /* Create an entry id, based upon the hostname and port */
- entry_id = create_hostcache_id(hostname, port);
- /* If we can't create the entry id, fail */
- if (!entry_id)
- return NULL;
- entry_len = strlen(entry_id);
-
- /* Create a new cache entry */
- dns = (struct Curl_dns_entry *) calloc(sizeof(struct Curl_dns_entry), 1);
- if (!dns) {
- free(entry_id);
- return NULL;
- }
-
- dns->inuse = 0; /* init to not used */
- dns->addr = addr; /* this is the address(es) */
-
- /* Store the resolved data in our DNS cache. This function may return a
- pointer to an existing struct already present in the hash, and it may
- return the same argument we pass in. Make no assumptions. */
- dns2 = Curl_hash_add(data->dns.hostcache, entry_id, entry_len+1,
- (void *)dns);
- if(!dns2) {
- /* Major badness, run away. */
- free(dns);
- free(entry_id);
- return NULL;
- }
- time(&now);
- dns = dns2;
-
- dns->timestamp = now; /* used now */
- dns->inuse++; /* mark entry as in-use */
-
- /* free the allocated entry_id again */
- free(entry_id);
-
- return dns;
-}
-
-/*
- * Curl_resolv() is the main name resolve function within libcurl. It resolves
- * a name and returns a pointer to the entry in the 'entry' argument (if one
- * is provided). This function might return immediately if we're using asynch
- * resolves. See the return codes.
- *
- * The cache entry we return will get its 'inuse' counter increased when this
- * function is used. You MUST call Curl_resolv_unlock() later (when you're
- * done using this struct) to decrease the counter again.
- *
- * Return codes:
- *
- * CURLRESOLV_ERROR (-1) = error, no pointer
- * CURLRESOLV_RESOLVED (0) = OK, pointer provided
- * CURLRESOLV_PENDING (1) = waiting for response, no pointer
- */
-
-int Curl_resolv(struct connectdata *conn,
- const char *hostname,
- int port,
- struct Curl_dns_entry **entry)
-{
- char *entry_id = NULL;
- struct Curl_dns_entry *dns = NULL;
- size_t entry_len;
- int wait;
- struct SessionHandle *data = conn->data;
- CURLcode result;
- int rc;
- *entry = NULL;
-
-#ifdef HAVE_SIGSETJMP
- /* this allows us to time-out from the name resolver, as the timeout
- will generate a signal and we will siglongjmp() from that here */
- if(!data->set.no_signal) {
- if (sigsetjmp(curl_jmpenv, 1)) {
- /* this is coming from a siglongjmp() */
- failf(data, "name lookup timed out");
- return CURLRESOLV_ERROR;
- }
- }
-#endif
-
- /* Create an entry id, based upon the hostname and port */
- entry_id = create_hostcache_id(hostname, port);
- /* If we can't create the entry id, fail */
- if (!entry_id)
- return CURLRESOLV_ERROR;
-
- entry_len = strlen(entry_id);
-
- if(data->share)
- Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
-
- /* See if its already in our dns cache */
- dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len+1);
-
- if(data->share)
- Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
-
- /* free the allocated entry_id again */
- free(entry_id);
-
- /* See whether the returned entry is stale. Deliberately done after the
- locked block */
- if ( remove_entry_if_stale(data,dns) )
- dns = NULL; /* the memory deallocation is being handled by the hash */
-
- rc = CURLRESOLV_ERROR; /* default to failure */
-
- if (!dns) {
- /* The entry was not in the cache. Resolve it to IP address */
-
- Curl_addrinfo *addr;
-
- /* Check what IP specifics the app has requested and if we can provide it.
- * If not, bail out. */
- if(!Curl_ipvalid(data))
- return CURLRESOLV_ERROR;
-
- /* If Curl_getaddrinfo() returns NULL, 'wait' might be set to a non-zero
- value indicating that we need to wait for the response to the resolve
- call */
- addr = Curl_getaddrinfo(conn, hostname, port, &wait);
-
- if (!addr) {
- if(wait) {
- /* the response to our resolve call will come asynchronously at
- a later time, good or bad */
- /* First, check that we haven't received the info by now */
- result = Curl_is_resolved(conn, &dns);
- if(result) /* error detected */
- return CURLRESOLV_ERROR;
- if(dns)
- rc = CURLRESOLV_RESOLVED; /* pointer provided */
- else
- rc = CURLRESOLV_PENDING; /* no info yet */
- }
- }
- else {
- if(data->share)
- Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
-
- /* we got a response, store it in the cache */
- dns = Curl_cache_addr(data, addr, hostname, port);
-
- if(data->share)
- Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
-
- if(!dns)
- /* returned failure, bail out nicely */
- Curl_freeaddrinfo(addr);
- else
- rc = CURLRESOLV_RESOLVED;
- }
- }
- else {
- if(data->share)
- Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
- dns->inuse++; /* we use it! */
- if(data->share)
- Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
- rc = CURLRESOLV_RESOLVED;
- }
-
- *entry = dns;
-
- return rc;
-}
-
-/*
- * Curl_resolv_unlock() unlocks the given cached DNS entry. When this has been
- * made, the struct may be destroyed due to pruning. It is important that only
- * one unlock is made for each Curl_resolv() call.
- */
-void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns)
-{
- curlassert(dns && (dns->inuse>0));
-
- if(data->share)
- Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
-
- dns->inuse--;
-
- if(data->share)
- Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
-}
-
-/*
- * File-internal: free a cache dns entry.
- */
-static void freednsentry(void *freethis)
-{
- struct Curl_dns_entry *p = (struct Curl_dns_entry *) freethis;
-
- Curl_freeaddrinfo(p->addr);
-
- free(p);
-}
-
-/*
- * Curl_mk_dnscache() creates a new DNS cache and returns the handle for it.
- */
-struct curl_hash *Curl_mk_dnscache(void)
-{
- return Curl_hash_alloc(7, freednsentry);
-}
-
-#ifdef CURLRES_ADDRINFO_COPY
-
-/* align on even 64bit boundaries */
-#define MEMALIGN(x) ((x)+(8-(((unsigned long)(x))&0x7)))
-
-/*
- * Curl_addrinfo_copy() performs a "deep" copy of a hostent into a buffer and
- * returns a pointer to the malloc()ed copy. You need to call free() on the
- * returned buffer when you're done with it.
- */
-Curl_addrinfo *Curl_addrinfo_copy(const void *org, int port)
-{
- const struct hostent *orig = org;
-
- return Curl_he2ai(orig, port);
-}
-#endif /* CURLRES_ADDRINFO_COPY */
-
-/***********************************************************************
- * Only for plain-ipv4 and c-ares builds
- **********************************************************************/
-
-#if defined(CURLRES_IPV4) || defined(CURLRES_ARES)
-/*
- * This is a function for freeing name information in a protocol independent
- * way.
- */
-void Curl_freeaddrinfo(Curl_addrinfo *ai)
-{
- Curl_addrinfo *next;
-
- /* walk over the list and free all entries */
- while(ai) {
- next = ai->ai_next;
- free(ai);
- ai = next;
- }
-}
-
-struct namebuf {
- struct hostent hostentry;
- char *h_addr_list[2];
- struct in_addr addrentry;
- char h_name[16]; /* 123.123.123.123 = 15 letters is maximum */
-};
-
-/*
- * Curl_ip2addr() takes a 32bit ipv4 internet address as input parameter
- * together with a pointer to the string version of the address, and it
- * returns a Curl_addrinfo chain filled in correctly with information for this
- * address/host.
- *
- * The input parameters ARE NOT checked for validity but they are expected
- * to have been checked already when this is called.
- */
-Curl_addrinfo *Curl_ip2addr(in_addr_t num, const char *hostname, int port)
-{
- Curl_addrinfo *ai;
- struct hostent *h;
- struct in_addr *addrentry;
- struct namebuf buffer;
- struct namebuf *buf = &buffer;
-
- h = &buf->hostentry;
- h->h_addr_list = &buf->h_addr_list[0];
- addrentry = &buf->addrentry;
-#ifdef _CRAYC
- /* On UNICOS, s_addr is a bit field and for some reason assigning to it
- * doesn't work. There must be a better fix than this ugly hack.
- */
- memcpy(addrentry, &num, SIZEOF_in_addr);
-#else
- addrentry->s_addr = num;
-#endif
- h->h_addr_list[0] = (char*)addrentry;
- h->h_addr_list[1] = NULL;
- h->h_addrtype = AF_INET;
- h->h_length = sizeof(*addrentry);
- h->h_name = &buf->h_name[0];
- h->h_aliases = NULL;
-
- /* Now store the dotted version of the address */
- snprintf((char *)h->h_name, 16, "%s", hostname);
-
- ai = Curl_he2ai(h, port);
-
- return ai;
-}
-#endif
-
-
diff --git a/Utilities/cmcurl/hostip.h b/Utilities/cmcurl/hostip.h
deleted file mode 100644
index e6d63ca71..000000000
--- a/Utilities/cmcurl/hostip.h
+++ /dev/null
@@ -1,271 +0,0 @@
-#ifndef __HOSTIP_H
-#define __HOSTIP_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-#include "hash.h"
-
-#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
-#undef in_addr_t
-#define in_addr_t uint32_t
-#endif
-
-/*
- * Setup comfortable CURLRES_* defines to use in the host*.c sources.
- */
-
-#ifdef USE_ARES
-#define CURLRES_ASYNCH
-#define CURLRES_ARES
-#endif
-
-#ifdef USE_THREADING_GETHOSTBYNAME
-#define CURLRES_ASYNCH
-#define CURLRES_THREADED
-#endif
-
-#ifdef USE_THREADING_GETADDRINFO
-#define CURLRES_ASYNCH
-#define CURLRES_THREADED
-#endif
-
-#ifdef ENABLE_IPV6
-#define CURLRES_IPV6
-#else
-#define CURLRES_IPV4
-#endif
-
-#if defined(CURLRES_IPV4) || defined(CURLRES_ARES)
-#if !defined(HAVE_GETHOSTBYNAME_R) || defined(CURLRES_ASYNCH)
-/* If built for ipv4 and missing gethostbyname_r(), or if using async name
- resolve, we need the Curl_addrinfo_copy() function (which itself needs the
- Curl_he2ai() function)) */
-#define CURLRES_ADDRINFO_COPY
-#endif
-#endif /* IPv4/ares-only */
-
-#ifndef CURLRES_ASYNCH
-#define CURLRES_SYNCH
-#endif
-
-#ifndef USE_LIBIDN
-#define CURLRES_IDN
-#endif
-
-/* Allocate enough memory to hold the full name information structs and
- * everything. OSF1 is known to require at least 8872 bytes. The buffer
- * required for storing all possible aliases and IP numbers is according to
- * Stevens' Unix Network Programming 2nd edition, p. 304: 8192 bytes!
- */
-#define CURL_HOSTENT_SIZE 9000
-
-#define CURL_TIMEOUT_RESOLVE 300 /* when using asynch methods, we allow this
- many seconds for a name resolve */
-
-#ifdef CURLRES_ARES
-#define CURL_ASYNC_SUCCESS ARES_SUCCESS
-#else
-#define CURL_ASYNC_SUCCESS CURLE_OK
-#define ares_cancel(x) do {} while(0)
-#define ares_destroy(x) do {} while(0)
-#endif
-
-/*
- * Curl_addrinfo MUST be used for all name resolved info.
- */
-#ifdef CURLRES_IPV6
-typedef struct addrinfo Curl_addrinfo;
-#else
-/* OK, so some ipv4-only include tree probably have the addrinfo struct, but
- to work even on those that don't, we provide our own look-alike! */
-struct Curl_addrinfo {
- int ai_flags;
- int ai_family;
- int ai_socktype;
- int ai_protocol;
- socklen_t ai_addrlen; /* Follow rfc3493 struct addrinfo */
- char *ai_canonname;
- struct sockaddr *ai_addr;
- struct Curl_addrinfo *ai_next;
-};
-typedef struct Curl_addrinfo Curl_addrinfo;
-#endif
-
-struct addrinfo;
-struct hostent;
-struct SessionHandle;
-struct connectdata;
-
-void Curl_global_host_cache_init(void);
-void Curl_global_host_cache_dtor(void);
-struct curl_hash *Curl_global_host_cache_get(void);
-
-#define Curl_global_host_cache_use(__p) ((__p)->set.global_dns_cache)
-
-struct Curl_dns_entry {
- Curl_addrinfo *addr;
- time_t timestamp;
- long inuse; /* use-counter, make very sure you decrease this
- when you're done using the address you received */
-};
-
-/*
- * Curl_resolv() returns an entry with the info for the specified host
- * and port.
- *
- * The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after
- * use, or we'll leak memory!
- */
-/* return codes */
-#define CURLRESOLV_ERROR -1
-#define CURLRESOLV_RESOLVED 0
-#define CURLRESOLV_PENDING 1
-int Curl_resolv(struct connectdata *conn, const char *hostname,
- int port, struct Curl_dns_entry **dnsentry);
-
-/*
- * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
- * been set and returns TRUE if they are OK.
- */
-bool Curl_ipvalid(struct SessionHandle *data);
-
-/*
- * Curl_getaddrinfo() is the generic low-level name resolve API within this
- * source file. There are several versions of this function - for different
- * name resolve layers (selected at build-time). They all take this same set
- * of arguments
- */
-Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
- const char *hostname,
- int port,
- int *waitp);
-
-CURLcode Curl_is_resolved(struct connectdata *conn,
- struct Curl_dns_entry **dns);
-CURLcode Curl_wait_for_resolv(struct connectdata *conn,
- struct Curl_dns_entry **dnsentry);
-
-/* Curl_resolv_getsock() is a generic function that exists in multiple
- versions depending on what name resolve technology we've built to use. The
- function is called from the multi_getsock() function. 'sock' is a pointer
- to an array to hold the file descriptors, with 'numsock' being the size of
- that array (in number of entries). This function is supposed to return
- bitmask indicating what file descriptors (referring to array indexes in the
- 'sock' array) to wait for, read/write. */
-int Curl_resolv_getsock(struct connectdata *conn, curl_socket_t *sock,
- int numsocks);
-
-/* unlock a previously resolved dns entry */
-void Curl_resolv_unlock(struct SessionHandle *data,
- struct Curl_dns_entry *dns);
-
-/* for debugging purposes only: */
-void Curl_scan_cache_used(void *user, void *ptr);
-
-/* free name info */
-void Curl_freeaddrinfo(Curl_addrinfo *freeaddr);
-
-/* make a new dns cache and return the handle */
-struct curl_hash *Curl_mk_dnscache(void);
-
-/* prune old entries from the DNS cache */
-void Curl_hostcache_prune(struct SessionHandle *data);
-
-/* Return # of adresses in a Curl_addrinfo struct */
-int Curl_num_addresses (const Curl_addrinfo *addr);
-
-#ifdef CURLDEBUG
-void curl_dofreeaddrinfo(struct addrinfo *freethis,
- int line, const char *source);
-int curl_dogetaddrinfo(const char *hostname, const char *service,
- struct addrinfo *hints,
- struct addrinfo **result,
- int line, const char *source);
-#ifdef HAVE_GETNAMEINFO
-int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
- GETNAMEINFO_TYPE_ARG2 salen,
- char *host, GETNAMEINFO_TYPE_ARG46 hostlen,
- char *serv, GETNAMEINFO_TYPE_ARG46 servlen,
- GETNAMEINFO_TYPE_ARG7 flags,
- int line, const char *source);
-#endif
-#endif
-
-/* This is the callback function that is used when we build with asynch
- resolve, ipv4 */
-CURLcode Curl_addrinfo4_callback(void *arg,
- int status,
- struct hostent *hostent);
-/* This is the callback function that is used when we build with asynch
- resolve, ipv6 */
-CURLcode Curl_addrinfo6_callback(void *arg,
- int status,
- struct addrinfo *ai);
-
-
-/* [ipv4/ares only] Creates a Curl_addrinfo struct from a numerical-only IP
- address */
-Curl_addrinfo *Curl_ip2addr(in_addr_t num, const char *hostname, int port);
-
-/* [ipv4/ares only] Curl_he2ai() converts a struct hostent to a Curl_addrinfo chain
- and returns it */
-Curl_addrinfo *Curl_he2ai(const struct hostent *, int port);
-
-/* Clone a Curl_addrinfo struct, works protocol independently */
-Curl_addrinfo *Curl_addrinfo_copy(const void *orig, int port);
-
-/*
- * Curl_printable_address() returns a printable version of the 1st address
- * given in the 'ip' argument. The result will be stored in the buf that is
- * bufsize bytes big.
- */
-const char *Curl_printable_address(const Curl_addrinfo *ip,
- char *buf, size_t bufsize);
-
-/*
- * Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache.
- *
- * Returns the Curl_dns_entry entry pointer or NULL if the storage failed.
- */
-struct Curl_dns_entry *
-Curl_cache_addr(struct SessionHandle *data, Curl_addrinfo *addr,
- const char *hostname, int port);
-
-/*
- * Curl_destroy_thread_data() cleans up async resolver data.
- * Complementary of ares_destroy.
- */
-struct Curl_async; /* forward-declaration */
-void Curl_destroy_thread_data(struct Curl_async *async);
-
-#ifndef INADDR_NONE
-#define CURL_INADDR_NONE (in_addr_t) ~0
-#else
-#define CURL_INADDR_NONE INADDR_NONE
-#endif
-
-
-
-
-#endif
diff --git a/Utilities/cmcurl/hostip4.c b/Utilities/cmcurl/hostip4.c
deleted file mode 100644
index 877baa2ca..000000000
--- a/Utilities/cmcurl/hostip4.c
+++ /dev/null
@@ -1,389 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#include <string.h>
-#include <errno.h>
-
-#ifdef NEED_MALLOC_H
-#include <malloc.h>
-#endif
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h> /* required for free() prototypes */
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h> /* for the close() proto */
-#endif
-#ifdef VMS
-#include <in.h>
-#include <inet.h>
-#include <stdlib.h>
-#endif
-
-#ifdef HAVE_SETJMP_H
-#include <setjmp.h>
-#endif
-
-#ifdef HAVE_PROCESS_H
-#include <process.h>
-#endif
-
-#include "urldata.h"
-#include "sendf.h"
-#include "hostip.h"
-#include "hash.h"
-#include "share.h"
-#include "strerror.h"
-#include "url.h"
-#include "inet_pton.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
-#include "inet_ntoa_r.h"
-#endif
-
-#include "memory.h"
-/* The last #include file should be: */
-#include "memdebug.h"
-
-/***********************************************************************
- * Only for plain-ipv4 builds
- **********************************************************************/
-#ifdef CURLRES_IPV4 /* plain ipv4 code coming up */
-/*
- * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
- * been set and returns TRUE if they are OK.
- */
-bool Curl_ipvalid(struct SessionHandle *data)
-{
- if(data->set.ip_version == CURL_IPRESOLVE_V6)
- /* an ipv6 address was requested and we can't get/use one */
- return FALSE;
-
- return TRUE; /* OK, proceed */
-}
-
-#ifdef CURLRES_SYNCH /* the functions below are for synchronous resolves */
-
-/*
- * Curl_getaddrinfo() - the ipv4 synchronous version.
- *
- * The original code to this function was from the Dancer source code, written
- * by Bjorn Reese, it has since been patched and modified considerably.
- *
- * gethostbyname_r() is the thread-safe version of the gethostbyname()
- * function. When we build for plain IPv4, we attempt to use this
- * function. There are _three_ different gethostbyname_r() versions, and we
- * detect which one this platform supports in the configure script and set up
- * the HAVE_GETHOSTBYNAME_R_3, HAVE_GETHOSTBYNAME_R_5 or
- * HAVE_GETHOSTBYNAME_R_6 defines accordingly. Note that HAVE_GETADDRBYNAME
- * has the corresponding rules. This is primarily on *nix. Note that some unix
- * flavours have thread-safe versions of the plain gethostbyname() etc.
- *
- */
-Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
- const char *hostname,
- int port,
- int *waitp)
-{
- Curl_addrinfo *ai = NULL;
- struct hostent *h = NULL;
- in_addr_t in;
- struct SessionHandle *data = conn->data;
- struct hostent *buf = NULL;
-
- (void)port; /* unused in IPv4 code */
-
- *waitp = 0; /* don't wait, we act synchronously */
-
- if(1 == Curl_inet_pton(AF_INET, hostname, &in))
- /* This is a dotted IP address 123.123.123.123-style */
- return Curl_ip2addr(in, hostname, port);
-
-#if defined(HAVE_GETHOSTBYNAME_R)
- /*
- * gethostbyname_r() is the preferred resolve function for many platforms.
- * Since there are three different versions of it, the following code is
- * somewhat #ifdef-ridden.
- */
- else {
- int h_errnop;
- int res=ERANGE;
-
- buf = (struct hostent *)calloc(CURL_HOSTENT_SIZE, 1);
- if(!buf)
- return NULL; /* major failure */
- /*
- * The clearing of the buffer is a workaround for a gethostbyname_r bug in
- * qnx nto and it is also _required_ for some of these functions on some
- * platforms.
- */
-
-#ifdef HAVE_GETHOSTBYNAME_R_5
- /* Solaris, IRIX and more */
- (void)res; /* prevent compiler warning */
- h = gethostbyname_r(hostname,
- (struct hostent *)buf,
- (char *)buf + sizeof(struct hostent),
- CURL_HOSTENT_SIZE - sizeof(struct hostent),
- &h_errnop);
-
- /* If the buffer is too small, it returns NULL and sets errno to
- * ERANGE. The errno is thread safe if this is compiled with
- * -D_REENTRANT as then the 'errno' variable is a macro defined to get
- * used properly for threads.
- */
-
- if(h) {
- ;
- }
- else
-#endif /* HAVE_GETHOSTBYNAME_R_5 */
-#ifdef HAVE_GETHOSTBYNAME_R_6
- /* Linux */
-
- res=gethostbyname_r(hostname,
- (struct hostent *)buf,
- (char *)buf + sizeof(struct hostent),
- CURL_HOSTENT_SIZE - sizeof(struct hostent),
- &h, /* DIFFERENCE */
- &h_errnop);
- /* Redhat 8, using glibc 2.2.93 changed the behavior. Now all of a
- * sudden this function returns EAGAIN if the given buffer size is too
- * small. Previous versions are known to return ERANGE for the same
- * problem.
- *
- * This wouldn't be such a big problem if older versions wouldn't
- * sometimes return EAGAIN on a common failure case. Alas, we can't
- * assume that EAGAIN *or* ERANGE means ERANGE for any given version of
- * glibc.
- *
- * For now, we do that and thus we may call the function repeatedly and
- * fail for older glibc versions that return EAGAIN, until we run out of
- * buffer size (step_size grows beyond CURL_HOSTENT_SIZE).
- *
- * If anyone has a better fix, please tell us!
- *
- * -------------------------------------------------------------------
- *
- * On October 23rd 2003, Dan C dug up more details on the mysteries of
- * gethostbyname_r() in glibc:
- *
- * In glibc 2.2.5 the interface is different (this has also been
- * discovered in glibc 2.1.1-6 as shipped by Redhat 6). What I can't
- * explain, is that tests performed on glibc 2.2.4-34 and 2.2.4-32
- * (shipped/upgraded by Redhat 7.2) don't show this behavior!
- *
- * In this "buggy" version, the return code is -1 on error and 'errno'
- * is set to the ERANGE or EAGAIN code. Note that 'errno' is not a
- * thread-safe variable.
- */
-
- if(!h) /* failure */
-#endif/* HAVE_GETHOSTBYNAME_R_6 */
-#ifdef HAVE_GETHOSTBYNAME_R_3
- /* AIX, Digital Unix/Tru64, HPUX 10, more? */
-
- /* For AIX 4.3 or later, we don't use gethostbyname_r() at all, because of
- * the plain fact that it does not return unique full buffers on each
- * call, but instead several of the pointers in the hostent structs will
- * point to the same actual data! This have the unfortunate down-side that
- * our caching system breaks down horribly. Luckily for us though, AIX 4.3
- * and more recent versions have a "completely thread-safe"[*] libc where
- * all the data is stored in thread-specific memory areas making calls to
- * the plain old gethostbyname() work fine even for multi-threaded
- * programs.
- *
- * This AIX 4.3 or later detection is all made in the configure script.
- *
- * Troels Walsted Hansen helped us work this out on March 3rd, 2003.
- *
- * [*] = much later we've found out that it isn't at all "completely
- * thread-safe", but at least the gethostbyname() function is.
- */
-
- if(CURL_HOSTENT_SIZE >=
- (sizeof(struct hostent)+sizeof(struct hostent_data))) {
-
- /* August 22nd, 2000: Albert Chin-A-Young brought an updated version
- * that should work! September 20: Richard Prescott worked on the buffer
- * size dilemma.
- */
-
- res = gethostbyname_r(hostname,
- (struct hostent *)buf,
- (struct hostent_data *)((char *)buf +
- sizeof(struct hostent)));
- h_errnop= errno; /* we don't deal with this, but set it anyway */
- }
- else
- res = -1; /* failure, too smallish buffer size */
-
- if(!res) { /* success */
-
- h = buf; /* result expected in h */
-
- /* This is the worst kind of the different gethostbyname_r() interfaces.
- * Since we don't know how big buffer this particular lookup required,
- * we can't realloc down the huge alloc without doing closer analysis of
- * the returned data. Thus, we always use CURL_HOSTENT_SIZE for every
- * name lookup. Fixing this would require an extra malloc() and then
- * calling Curl_addrinfo_copy() that subsequent realloc()s down the new
- * memory area to the actually used amount.
- */
- }
- else
-#endif /* HAVE_GETHOSTBYNAME_R_3 */
- {
- infof(data, "gethostbyname_r(2) failed for %s\n", hostname);
- h = NULL; /* set return code to NULL */
- free(buf);
- }
-#else /* HAVE_GETHOSTBYNAME_R */
- /*
- * Here is code for platforms that don't have gethostbyname_r() or for
- * which the gethostbyname() is the preferred() function.
- */
- else {
- h = gethostbyname(hostname);
- if (!h)
- infof(data, "gethostbyname(2) failed for %s\n", hostname);
-#endif /*HAVE_GETHOSTBYNAME_R */
- }
-
- if(h) {
- ai = Curl_he2ai(h, port);
-
- if (buf) /* used a *_r() function */
- free(buf);
- }
-
- return ai;
-}
-
-#endif /* CURLRES_SYNCH */
-#endif /* CURLRES_IPV4 */
-
-/*
- * Curl_he2ai() translates from a hostent struct to a Curl_addrinfo struct.
- * The Curl_addrinfo is meant to work like the addrinfo struct does for IPv6
- * stacks, but for all hosts and environments.
- *
- * Curl_addrinfo defined in "lib/hostip.h"
- *
- * struct Curl_addrinfo {
- * int ai_flags;
- * int ai_family;
- * int ai_socktype;
- * int ai_protocol;
- * socklen_t ai_addrlen; * Follow rfc3493 struct addrinfo *
- * char *ai_canonname;
- * struct sockaddr *ai_addr;
- * struct Curl_addrinfo *ai_next;
- * };
- *
- * hostent defined in <netdb.h>
- *
- * struct hostent {
- * char *h_name;
- * char **h_aliases;
- * int h_addrtype;
- * int h_length;
- * char **h_addr_list;
- * };
- *
- * for backward compatibility:
- *
- * #define h_addr h_addr_list[0]
- */
-
-Curl_addrinfo *Curl_he2ai(const struct hostent *he, int port)
-{
- Curl_addrinfo *ai;
- Curl_addrinfo *prevai = NULL;
- Curl_addrinfo *firstai = NULL;
- struct sockaddr_in *addr;
- int i;
- struct in_addr *curr;
-
- if(!he)
- /* no input == no output! */
- return NULL;
-
- for(i=0; (curr = (struct in_addr *)he->h_addr_list[i]) != NULL; i++) {
-
- ai = calloc(1, sizeof(Curl_addrinfo) + sizeof(struct sockaddr_in));
-
- if(!ai)
- break;
-
- if(!firstai)
- /* store the pointer we want to return from this function */
- firstai = ai;
-
- if(prevai)
- /* make the previous entry point to this */
- prevai->ai_next = ai;
-
- ai->ai_family = AF_INET; /* we only support this */
-
- /* we return all names as STREAM, so when using this address for TFTP
- the type must be ignored and conn->socktype be used instead! */
- ai->ai_socktype = SOCK_STREAM;
-
- ai->ai_addrlen = sizeof(struct sockaddr_in);
- /* make the ai_addr point to the address immediately following this struct
- and use that area to store the address */
- ai->ai_addr = (struct sockaddr *) ((char*)ai + sizeof(Curl_addrinfo));
-
- /* leave the rest of the struct filled with zero */
-
- addr = (struct sockaddr_in *)ai->ai_addr; /* storage area for this info */
-
- memcpy((char *)&(addr->sin_addr), curr, sizeof(struct in_addr));
- addr->sin_family = he->h_addrtype;
- addr->sin_port = htons((unsigned short)port);
-
- prevai = ai;
- }
- return firstai;
-}
-
diff --git a/Utilities/cmcurl/hostip6.c b/Utilities/cmcurl/hostip6.c
deleted file mode 100644
index c8bbdb5e9..000000000
--- a/Utilities/cmcurl/hostip6.c
+++ /dev/null
@@ -1,306 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#include <string.h>
-
-#ifdef NEED_MALLOC_H
-#include <malloc.h>
-#endif
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h> /* required for free() prototypes */
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h> /* for the close() proto */
-#endif
-#ifdef VMS
-#include <in.h>
-#include <inet.h>
-#include <stdlib.h>
-#endif
-
-#ifdef HAVE_SETJMP_H
-#include <setjmp.h>
-#endif
-
-#ifdef HAVE_PROCESS_H
-#include <process.h>
-#endif
-
-#include "urldata.h"
-#include "sendf.h"
-#include "hostip.h"
-#include "hash.h"
-#include "share.h"
-#include "strerror.h"
-#include "url.h"
-#include "inet_pton.h"
-#include "connect.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
-#include "inet_ntoa_r.h"
-#endif
-
-#include "memory.h"
-/* The last #include file should be: */
-#include "memdebug.h"
-
-/***********************************************************************
- * Only for ipv6-enabled builds
- **********************************************************************/
-#ifdef CURLRES_IPV6
-#ifndef CURLRES_ARES
-/*
- * This is a wrapper function for freeing name information in a protocol
- * independent way. This takes care of using the appropriate underlaying
- * function.
- */
-void Curl_freeaddrinfo(Curl_addrinfo *p)
-{
- freeaddrinfo(p);
-}
-
-#ifdef CURLRES_ASYNCH
-/*
- * Curl_addrinfo_copy() is used by the asynch callback to copy a given
- * address. But this is an ipv6 build and then we don't copy the address, we
- * just return the same pointer!
- */
-Curl_addrinfo *Curl_addrinfo_copy(const void *orig, int port)
-{
- (void) port;
- return (Curl_addrinfo*)orig;
-}
-#endif /* CURLRES_ASYNCH */
-#endif /* CURLRES_ARES */
-
-#ifdef CURLDEBUG
-/* These are strictly for memory tracing and are using the same style as the
- * family otherwise present in memdebug.c. I put these ones here since they
- * require a bunch of structs I didn't wanna include in memdebug.c
- */
-int curl_dogetaddrinfo(const char *hostname, const char *service,
- struct addrinfo *hints,
- struct addrinfo **result,
- int line, const char *source)
-{
- int res=(getaddrinfo)(hostname, service, hints, result);
- if(0 == res) {
- /* success */
- if(logfile)
- fprintf(logfile, "ADDR %s:%d getaddrinfo() = %p\n",
- source, line, (void *)*result);
- }
- else {
- if(logfile)
- fprintf(logfile, "ADDR %s:%d getaddrinfo() failed\n",
- source, line);
- }
- return res;
-}
-
-/*
- * For CURLRES_ARS, this should be written using ares_gethostbyaddr()
- * (ignoring the fact c-ares doesn't return 'serv').
- */
-#ifdef HAVE_GETNAMEINFO
-int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
- GETNAMEINFO_TYPE_ARG2 salen,
- char *host, GETNAMEINFO_TYPE_ARG46 hostlen,
- char *serv, GETNAMEINFO_TYPE_ARG46 servlen,
- GETNAMEINFO_TYPE_ARG7 flags,
- int line, const char *source)
-{
- int res = (getnameinfo)(sa, salen,
- host, hostlen,
- serv, servlen,
- flags);
- if(0 == res) {
- /* success */
- if(logfile)
- fprintf(logfile, "GETNAME %s:%d getnameinfo()\n",
- source, line);
- }
- else {
- if(logfile)
- fprintf(logfile, "GETNAME %s:%d getnameinfo() failed = %d\n",
- source, line, res);
- }
- return res;
-}
-#endif
-
-void curl_dofreeaddrinfo(struct addrinfo *freethis,
- int line, const char *source)
-{
- (freeaddrinfo)(freethis);
- if(logfile)
- fprintf(logfile, "ADDR %s:%d freeaddrinfo(%p)\n",
- source, line, (void *)freethis);
-}
-#endif /* CURLDEBUG */
-
-/*
- * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
- * been set and returns TRUE if they are OK.
- */
-bool Curl_ipvalid(struct SessionHandle *data)
-{
- if(data->set.ip_version == CURL_IPRESOLVE_V6) {
- /* see if we have an IPv6 stack */
- curl_socket_t s = socket(PF_INET6, SOCK_DGRAM, 0);
- if (s == CURL_SOCKET_BAD)
- /* an ipv6 address was requested and we can't get/use one */
- return FALSE;
- sclose(s);
- }
- return TRUE;
-}
-
-#if !defined(USE_THREADING_GETADDRINFO) && !defined(CURLRES_ARES)
-
-#ifdef DEBUG_ADDRINFO
-static void dump_addrinfo(struct connectdata *conn, const struct addrinfo *ai)
-{
- printf("dump_addrinfo:\n");
- for ( ; ai; ai = ai->ai_next) {
- char buf[INET6_ADDRSTRLEN];
-
- printf(" fam %2d, CNAME %s, ",
- ai->ai_family, ai->ai_canonname ? ai->ai_canonname : "<none>");
- if (Curl_printable_address(ai, buf, sizeof(buf)))
- printf("%s\n", buf);
- else
- printf("failed; %s\n", Curl_strerror(conn, Curl_sockerrno()));
- }
-}
-#else
-#define dump_addrinfo(x,y)
-#endif
-
-/*
- * Curl_getaddrinfo() when built ipv6-enabled (non-threading and
- * non-ares version).
- *
- * Returns name information about the given hostname and port number. If
- * successful, the 'addrinfo' is returned and the forth argument will point to
- * memory we need to free after use. That memory *MUST* be freed with
- * Curl_freeaddrinfo(), nothing else.
- */
-Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
- const char *hostname,
- int port,
- int *waitp)
-{
- struct addrinfo hints, *res;
- int error;
- char sbuf[NI_MAXSERV];
- char *sbufptr = NULL;
- char addrbuf[128];
- curl_socket_t s;
- int pf;
- struct SessionHandle *data = conn->data;
-
- *waitp=0; /* don't wait, we have the response now */
-
- /* see if we have an IPv6 stack */
- s = socket(PF_INET6, SOCK_DGRAM, 0);
- if (s == CURL_SOCKET_BAD) {
- /* Some non-IPv6 stacks have been found to make very slow name resolves
- * when PF_UNSPEC is used, so thus we switch to a mere PF_INET lookup if
- * the stack seems to be a non-ipv6 one. */
-
- pf = PF_INET;
- }
- else {
- /* This seems to be an IPv6-capable stack, use PF_UNSPEC for the widest
- * possible checks. And close the socket again.
- */
- sclose(s);
-
- /*
- * Check if a more limited name resolve has been requested.
- */
- switch(data->set.ip_version) {
- case CURL_IPRESOLVE_V4:
- pf = PF_INET;
- break;
- case CURL_IPRESOLVE_V6:
- pf = PF_INET6;
- break;
- default:
- pf = PF_UNSPEC;
- break;
- }
- }
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = pf;
- hints.ai_socktype = conn->socktype;
-
- if((1 == Curl_inet_pton(AF_INET, hostname, addrbuf)) ||
- (1 == Curl_inet_pton(AF_INET6, hostname, addrbuf))) {
- /* the given address is numerical only, prevent a reverse lookup */
- hints.ai_flags = AI_NUMERICHOST;
- }
-#if 0 /* removed nov 8 2005 before 7.15.1 */
- else
- hints.ai_flags = AI_CANONNAME;
-#endif
-
- if(port) {
- snprintf(sbuf, sizeof(sbuf), "%d", port);
- sbufptr=sbuf;
- }
- error = getaddrinfo(hostname, sbufptr, &hints, &res);
- if (error) {
- infof(data, "getaddrinfo(3) failed for %s:%d\n", hostname, port);
- return NULL;
- }
-
- dump_addrinfo(conn, res);
-
- return res;
-}
-#endif /* !USE_THREADING_GETADDRINFO && !CURLRES_ARES */
-#endif /* ipv6 */
-
diff --git a/Utilities/cmcurl/hostsyn.c b/Utilities/cmcurl/hostsyn.c
deleted file mode 100644
index 2f816b858..000000000
--- a/Utilities/cmcurl/hostsyn.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#include <string.h>
-
-#ifdef NEED_MALLOC_H
-#include <malloc.h>
-#endif
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h> /* required for free() prototypes */
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h> /* for the close() proto */
-#endif
-#ifdef VMS
-#include <in.h>
-#include <inet.h>
-#include <stdlib.h>
-#endif
-
-#ifdef HAVE_SETJMP_H
-#include <setjmp.h>
-#endif
-
-#ifdef HAVE_PROCESS_H
-#include <process.h>
-#endif
-
-#include "urldata.h"
-#include "sendf.h"
-#include "hostip.h"
-#include "hash.h"
-#include "share.h"
-#include "strerror.h"
-#include "url.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
-#include "inet_ntoa_r.h"
-#endif
-
-#include "memory.h"
-/* The last #include file should be: */
-#include "memdebug.h"
-
-/***********************************************************************
- * Only for builds using synchronous name resolves
- **********************************************************************/
-#ifdef CURLRES_SYNCH
-
-/*
- * Curl_wait_for_resolv() for synch-builds. Curl_resolv() can never return
- * wait==TRUE, so this function will never be called. If it still gets called,
- * we return failure at once.
- *
- * We provide this function only to allow multi.c to remain unaware if we are
- * doing asynch resolves or not.
- */
-CURLcode Curl_wait_for_resolv(struct connectdata *conn,
- struct Curl_dns_entry **entry)
-{
- (void)conn;
- *entry=NULL;
- return CURLE_COULDNT_RESOLVE_HOST;
-}
-
-/*
- * This function will never be called when synch-built. If it still gets
- * called, we return failure at once.
- *
- * We provide this function only to allow multi.c to remain unaware if we are
- * doing asynch resolves or not.
- */
-CURLcode Curl_is_resolved(struct connectdata *conn,
- struct Curl_dns_entry **dns)
-{
- (void)conn;
- *dns = NULL;
-
- return CURLE_COULDNT_RESOLVE_HOST;
-}
-
-/*
- * We just return OK, this function is never actually used for synch builds.
- * It is present here to keep #ifdefs out from multi.c
- */
-
-int Curl_resolv_getsock(struct connectdata *conn,
- curl_socket_t *sock,
- int numsocks)
-{
- (void)conn;
- (void)sock;
- (void)numsocks;
-
- return 0; /* no bits since we don't use any socks */
-}
-
-#endif /* truly sync */
diff --git a/Utilities/cmcurl/hostthre.c b/Utilities/cmcurl/hostthre.c
deleted file mode 100644
index 12e31ea34..000000000
--- a/Utilities/cmcurl/hostthre.c
+++ /dev/null
@@ -1,840 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#include <string.h>
-#include <errno.h>
-
-#ifdef NEED_MALLOC_H
-#include <malloc.h>
-#endif
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h> /* required for free() prototypes */
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h> /* for the close() proto */
-#endif
-#ifdef VMS
-#include <in.h>
-#include <inet.h>
-#include <stdlib.h>
-#endif
-
-#ifdef HAVE_SETJMP_H
-#include <setjmp.h>
-#endif
-
-#ifdef HAVE_PROCESS_H
-#include <process.h>
-#endif
-
-#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
-#undef in_addr_t
-#define in_addr_t unsigned long
-#endif
-
-#include "urldata.h"
-#include "sendf.h"
-#include "hostip.h"
-#include "hash.h"
-#include "share.h"
-#include "strerror.h"
-#include "url.h"
-#include "multiif.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-#include "inet_ntop.h"
-
-#include "memory.h"
-/* The last #include file should be: */
-#include "memdebug.h"
-
-#if defined(_MSC_VER) && defined(CURL_NO__BEGINTHREADEX)
-#pragma message ("No _beginthreadex() available in this RTL")
-#endif
-
-/***********************************************************************
- * Only for Windows threaded name resolves builds
- **********************************************************************/
-#ifdef CURLRES_THREADED
-
-/* This function is used to init a threaded resolve */
-static bool init_resolve_thread(struct connectdata *conn,
- const char *hostname, int port,
- const Curl_addrinfo *hints);
-
-#ifdef CURLRES_IPV4
- #define THREAD_FUNC gethostbyname_thread
- #define THREAD_NAME "gethostbyname_thread"
-#else
- #define THREAD_FUNC getaddrinfo_thread
- #define THREAD_NAME "getaddrinfo_thread"
-#endif
-
-#if defined(DEBUG_THREADING_GETHOSTBYNAME) || \
- defined(DEBUG_THREADING_GETADDRINFO)
-/* If this is defined, provide tracing */
-#define TRACE(args) \
- do { trace_it("%u: ", __LINE__); trace_it args; } while (0)
-
-static void trace_it (const char *fmt, ...)
-{
- static int do_trace = -1;
- va_list args;
-
- if (do_trace == -1) {
- const char *env = getenv("CURL_TRACE");
- do_trace = (env && atoi(env) > 0);
- }
- if (!do_trace)
- return;
- va_start (args, fmt);
- vfprintf (stderr, fmt, args);
- fflush (stderr);
- va_end (args);
-}
-#else
-#define TRACE(x)
-#endif
-
-#ifdef DEBUG_THREADING_GETADDRINFO
-static void dump_addrinfo (struct connectdata *conn, const struct addrinfo *ai)
-{
- TRACE(("dump_addrinfo:\n"));
- for ( ; ai; ai = ai->ai_next) {
- char buf [INET6_ADDRSTRLEN];
-
- trace_it(" fam %2d, CNAME %s, ",
- ai->ai_family, ai->ai_canonname ? ai->ai_canonname : "<none>");
- if (Curl_printable_address(ai, buf, sizeof(buf)))
- trace_it("%s\n", buf);
- else
- trace_it("failed; %s\n", Curl_strerror(conn,WSAGetLastError()));
- }
-}
-#endif
-
-struct thread_data {
- HANDLE thread_hnd;
- unsigned thread_id;
- DWORD thread_status;
- curl_socket_t dummy_sock; /* dummy for Curl_resolv_fdset() */
- HANDLE mutex_waiting; /* marks that we are still waiting for a resolve */
- HANDLE event_resolved; /* marks that the thread obtained the information */
- HANDLE event_thread_started; /* marks that the thread has initialized and
- started */
- HANDLE mutex_terminate; /* serializes access to flag_terminate */
- HANDLE event_terminate; /* flag for thread to terminate instead of calling
- callbacks */
-#ifdef CURLRES_IPV6
- struct addrinfo hints;
-#endif
-};
-
-/* Data for synchronization between resolver thread and its parent */
-struct thread_sync_data {
- HANDLE mutex_waiting; /* thread_data.mutex_waiting duplicate */
- HANDLE mutex_terminate; /* thread_data.mutex_terminate duplicate */
- HANDLE event_terminate; /* thread_data.event_terminate duplicate */
- char * hostname; /* hostname to resolve, Curl_async.hostname
- duplicate */
-};
-
-/* Destroy resolver thread synchronization data */
-static
-void destroy_thread_sync_data(struct thread_sync_data * tsd)
-{
- if (tsd->hostname) {
- free(tsd->hostname);
- tsd->hostname = NULL;
- }
- if (tsd->event_terminate) {
- CloseHandle(tsd->event_terminate);
- tsd->event_terminate = NULL;
- }
- if (tsd->mutex_terminate) {
- CloseHandle(tsd->mutex_terminate);
- tsd->mutex_terminate = NULL;
- }
- if (tsd->mutex_waiting) {
- CloseHandle(tsd->mutex_waiting);
- tsd->mutex_waiting = NULL;
- }
-}
-
-/* Initialize resolver thread synchronization data */
-static
-BOOL init_thread_sync_data(struct thread_data * td,
- char * hostname,
- struct thread_sync_data * tsd)
-{
- HANDLE curr_proc = GetCurrentProcess();
-
- memset(tsd, 0, sizeof(*tsd));
- if (!DuplicateHandle(curr_proc, td->mutex_waiting,
- curr_proc, &tsd->mutex_waiting, 0, FALSE,
- DUPLICATE_SAME_ACCESS)) {
- /* failed to duplicate the mutex, no point in continuing */
- destroy_thread_sync_data(tsd);
- return FALSE;
- }
- if (!DuplicateHandle(curr_proc, td->mutex_terminate,
- curr_proc, &tsd->mutex_terminate, 0, FALSE,
- DUPLICATE_SAME_ACCESS)) {
- /* failed to duplicate the mutex, no point in continuing */
- destroy_thread_sync_data(tsd);
- return FALSE;
- }
- if (!DuplicateHandle(curr_proc, td->event_terminate,
- curr_proc, &tsd->event_terminate, 0, FALSE,
- DUPLICATE_SAME_ACCESS)) {
- /* failed to duplicate the event, no point in continuing */
- destroy_thread_sync_data(tsd);
- return FALSE;
- }
- /* Copying hostname string because original can be destroyed by parent
- * thread during gethostbyname execution.
- */
- tsd->hostname = strdup(hostname);
- if (!tsd->hostname) {
- /* Memory allocation failed */
- destroy_thread_sync_data(tsd);
- return FALSE;
- }
- return TRUE;
-}
-
-/* acquire resolver thread synchronization */
-static
-BOOL acquire_thread_sync(struct thread_sync_data * tsd)
-{
- /* is the thread initiator still waiting for us ? */
- if (WaitForSingleObject(tsd->mutex_waiting, 0) == WAIT_TIMEOUT) {
- /* yes, it is */
-
- /* Waiting access to event_terminate */
- if (WaitForSingleObject(tsd->mutex_terminate, INFINITE) != WAIT_OBJECT_0) {
- /* Something went wrong - now just ignoring */
- }
- else {
- if (WaitForSingleObject(tsd->event_terminate, 0) != WAIT_TIMEOUT) {
- /* Parent thread signaled us to terminate.
- * This means that all data in conn->async is now destroyed
- * and we cannot use it.
- */
- }
- else {
- return TRUE;
- }
- }
- }
- return FALSE;
-}
-
-/* release resolver thread synchronization */
-static
-void release_thread_sync(struct thread_sync_data * tsd)
-{
- ReleaseMutex(tsd->mutex_terminate);
-}
-
-#if defined(CURLRES_IPV4)
-/*
- * gethostbyname_thread() resolves a name, calls the Curl_addrinfo4_callback
- * and then exits.
- *
- * For builds without ARES/ENABLE_IPV6, create a resolver thread and wait on
- * it.
- */
-static unsigned __stdcall gethostbyname_thread (void *arg)
-{
- struct connectdata *conn = (struct connectdata*) arg;
- struct thread_data *td = (struct thread_data*) conn->async.os_specific;
- struct hostent *he;
- int rc = 0;
-
- /* Duplicate the passed mutex and event handles.
- * This allows us to use it even after the container gets destroyed
- * due to a resolver timeout.
- */
- struct thread_sync_data tsd = { 0,0,0,NULL };
- if (!init_thread_sync_data(td, conn->async.hostname, &tsd)) {
- /* thread synchronization data initialization failed */
- return (unsigned)-1;
- }
-
- WSASetLastError (conn->async.status = NO_DATA); /* pending status */
-
- /* Signaling that we have initialized all copies of data and handles we
- need */
- SetEvent(td->event_thread_started);
-
- he = gethostbyname (tsd.hostname);
-
- /* is parent thread waiting for us and are we able to access conn members? */
- if (acquire_thread_sync(&tsd)) {
- /* Mark that we have obtained the information, and that we are calling
- * back with it. */
- SetEvent(td->event_resolved);
- if (he) {
- rc = Curl_addrinfo4_callback(conn, CURL_ASYNC_SUCCESS, he);
- }
- else {
- rc = Curl_addrinfo4_callback(conn, (int)WSAGetLastError(), NULL);
- }
- TRACE(("Winsock-error %d, addr %s\n", conn->async.status,
- he ? inet_ntoa(*(struct in_addr*)he->h_addr) : "unknown"));
- release_thread_sync(&tsd);
- }
-
- /* clean up */
- destroy_thread_sync_data(&tsd);
-
- return (rc);
- /* An implicit _endthreadex() here */
-}
-
-#elif defined(CURLRES_IPV6)
-
-/*
- * getaddrinfo_thread() resolves a name, calls Curl_addrinfo6_callback and then
- * exits.
- *
- * For builds without ARES, but with ENABLE_IPV6, create a resolver thread
- * and wait on it.
- */
-static unsigned __stdcall getaddrinfo_thread (void *arg)
-{
- struct connectdata *conn = (struct connectdata*) arg;
- struct thread_data *td = (struct thread_data*) conn->async.os_specific;
- struct addrinfo *res;
- char service [NI_MAXSERV];
- int rc;
- struct addrinfo hints = td->hints;
-
- /* Duplicate the passed mutex handle.
- * This allows us to use it even after the container gets destroyed
- * due to a resolver timeout.
- */
- struct thread_sync_data tsd = { 0,0,0,NULL };
- if (!init_thread_sync_data(td, conn->async.hostname, &tsd)) {
- /* thread synchronization data initialization failed */
- return -1;
- }
-
- itoa(conn->async.port, service, 10);
-
- WSASetLastError(conn->async.status = NO_DATA); /* pending status */
-
- /* Signaling that we have initialized all copies of data and handles we
- need */
- SetEvent(td->event_thread_started);
-
- rc = getaddrinfo(tsd.hostname, service, &hints, &res);
-
- /* is parent thread waiting for us and are we able to access conn members? */
- if (acquire_thread_sync(&tsd)) {
- /* Mark that we have obtained the information, and that we are calling
- back with it. */
- SetEvent(td->event_resolved);
-
- if (rc == 0) {
-#ifdef DEBUG_THREADING_GETADDRINFO
- dump_addrinfo (conn, res);
-#endif
- rc = Curl_addrinfo6_callback(conn, CURL_ASYNC_SUCCESS, res);
- }
- else {
- rc = Curl_addrinfo6_callback(conn, (int)WSAGetLastError(), NULL);
- TRACE(("Winsock-error %d, no address\n", conn->async.status));
- }
- release_thread_sync(&tsd);
- }
-
- /* clean up */
- destroy_thread_sync_data(&tsd);
-
- return (rc);
- /* An implicit _endthreadex() here */
-}
-#endif
-
-/*
- * Curl_destroy_thread_data() cleans up async resolver data and thread handle.
- * Complementary of ares_destroy.
- */
-void Curl_destroy_thread_data (struct Curl_async *async)
-{
- if (async->hostname)
- free(async->hostname);
-
- if (async->os_specific) {
- struct thread_data *td = (struct thread_data*) async->os_specific;
- curl_socket_t sock = td->dummy_sock;
-
- if (td->mutex_terminate && td->event_terminate) {
- /* Signaling resolver thread to terminate */
- if (WaitForSingleObject(td->mutex_terminate, INFINITE) == WAIT_OBJECT_0) {
- SetEvent(td->event_terminate);
- ReleaseMutex(td->mutex_terminate);
- }
- else {
- /* Something went wrong - just ignoring it */
- }
- }
-
- if (td->mutex_terminate)
- CloseHandle(td->mutex_terminate);
- if (td->event_terminate)
- CloseHandle(td->event_terminate);
- if (td->event_thread_started)
- CloseHandle(td->event_thread_started);
-
- if (sock != CURL_SOCKET_BAD)
- sclose(sock);
-
- /* destroy the synchronization objects */
- if (td->mutex_waiting)
- CloseHandle(td->mutex_waiting);
- td->mutex_waiting = NULL;
- if (td->event_resolved)
- CloseHandle(td->event_resolved);
-
- if (td->thread_hnd)
- CloseHandle(td->thread_hnd);
-
- free(async->os_specific);
- }
- async->hostname = NULL;
- async->os_specific = NULL;
-}
-
-/*
- * init_resolve_thread() starts a new thread that performs the actual
- * resolve. This function returns before the resolve is done.
- *
- * Returns FALSE in case of failure, otherwise TRUE.
- */
-static bool init_resolve_thread (struct connectdata *conn,
- const char *hostname, int port,
- const Curl_addrinfo *hints)
-{
- struct thread_data *td = calloc(sizeof(*td), 1);
- HANDLE thread_and_event[2] = {0};
-
- if (!td) {
- SetLastError(ENOMEM);
- return FALSE;
- }
-
- Curl_safefree(conn->async.hostname);
- conn->async.hostname = strdup(hostname);
- if (!conn->async.hostname) {
- free(td);
- SetLastError(ENOMEM);
- return FALSE;
- }
-
- conn->async.port = port;
- conn->async.done = FALSE;
- conn->async.status = 0;
- conn->async.dns = NULL;
- conn->async.os_specific = (void*) td;
- td->dummy_sock = CURL_SOCKET_BAD;
-
- /* Create the mutex used to inform the resolver thread that we're
- * still waiting, and take initial ownership.
- */
- td->mutex_waiting = CreateMutex(NULL, TRUE, NULL);
- if (td->mutex_waiting == NULL) {
- Curl_destroy_thread_data(&conn->async);
- SetLastError(EAGAIN);
- return FALSE;
- }
-
- /* Create the event that the thread uses to inform us that it's
- * done resolving. Do not signal it.
- */
- td->event_resolved = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (td->event_resolved == NULL) {
- Curl_destroy_thread_data(&conn->async);
- SetLastError(EAGAIN);
- return FALSE;
- }
- /* Create the mutex used to serialize access to event_terminated
- * between us and resolver thread.
- */
- td->mutex_terminate = CreateMutex(NULL, FALSE, NULL);
- if (td->mutex_terminate == NULL) {
- Curl_destroy_thread_data(&conn->async);
- SetLastError(EAGAIN);
- return FALSE;
- }
- /* Create the event used to signal thread that it should terminate.
- */
- td->event_terminate = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (td->event_terminate == NULL) {
- Curl_destroy_thread_data(&conn->async);
- SetLastError(EAGAIN);
- return FALSE;
- }
- /* Create the event used by thread to inform it has initialized its own data.
- */
- td->event_thread_started = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (td->event_thread_started == NULL) {
- Curl_destroy_thread_data(&conn->async);
- SetLastError(EAGAIN);
- return FALSE;
- }
-
-#ifdef _WIN32_WCE
- td->thread_hnd = (HANDLE) CreateThread(NULL, 0,
- (LPTHREAD_START_ROUTINE) THREAD_FUNC,
- conn, 0, &td->thread_id);
-#else
- td->thread_hnd = (HANDLE) _beginthreadex(NULL, 0, THREAD_FUNC,
- conn, 0, &td->thread_id);
-#endif
-
-#ifdef CURLRES_IPV6
- curlassert(hints);
- td->hints = *hints;
-#else
- (void) hints;
-#endif
-
- if (!td->thread_hnd) {
-#ifdef _WIN32_WCE
- TRACE(("CreateThread() failed; %s\n", Curl_strerror(conn,GetLastError())));
-#else
- SetLastError(errno);
- TRACE(("_beginthreadex() failed; %s\n", Curl_strerror(conn,errno)));
-#endif
- Curl_destroy_thread_data(&conn->async);
- return FALSE;
- }
- /* Waiting until the thread will initialize its data or it will exit due errors.
- */
- thread_and_event[0] = td->thread_hnd;
- thread_and_event[1] = td->event_thread_started;
- if (WaitForMultipleObjects(sizeof(thread_and_event) /
- sizeof(thread_and_event[0]),
- (const HANDLE*)thread_and_event, FALSE,
- INFINITE) == WAIT_FAILED) {
- /* The resolver thread has been created,
- * most probably it works now - ignoring this "minor" error
- */
- }
- /* This socket is only to keep Curl_resolv_fdset() and select() happy;
- * should never become signalled for read/write since it's unbound but
- * Windows needs atleast 1 socket in select().
- */
- td->dummy_sock = socket(AF_INET, SOCK_DGRAM, 0);
- return TRUE;
-}
-
-
-/*
- * Curl_wait_for_resolv() waits for a resolve to finish. This function should
- * be avoided since using this risk getting the multi interface to "hang".
- *
- * If 'entry' is non-NULL, make it point to the resolved dns entry
- *
- * This is the version for resolves-in-a-thread.
- */
-CURLcode Curl_wait_for_resolv(struct connectdata *conn,
- struct Curl_dns_entry **entry)
-{
- struct thread_data *td = (struct thread_data*) conn->async.os_specific;
- struct SessionHandle *data = conn->data;
- long timeout;
- DWORD status, ticks;
- CURLcode rc;
-
- curlassert (conn && td);
-
- /* now, see if there's a connect timeout or a regular timeout to
- use instead of the default one */
- timeout =
- conn->data->set.connecttimeout ? conn->data->set.connecttimeout :
- conn->data->set.timeout ? conn->data->set.timeout :
- CURL_TIMEOUT_RESOLVE; /* default name resolve timeout */
- ticks = GetTickCount();
-
- /* wait for the thread to resolve the name */
- status = WaitForSingleObject(td->event_resolved, 1000UL*timeout);
-
- /* mark that we are now done waiting */
- ReleaseMutex(td->mutex_waiting);
-
- /* close our handle to the mutex, no point in hanging on to it */
- CloseHandle(td->mutex_waiting);
- td->mutex_waiting = NULL;
-
- /* close the event handle, it's useless now */
- CloseHandle(td->event_resolved);
- td->event_resolved = NULL;
-
- /* has the resolver thread succeeded in resolving our query ? */
- if (status == WAIT_OBJECT_0) {
- /* wait for the thread to exit, it's in the callback sequence */
- if (WaitForSingleObject(td->thread_hnd, 5000) == WAIT_TIMEOUT) {
- TerminateThread(td->thread_hnd, 0);
- conn->async.done = TRUE;
- td->thread_status = (DWORD)-1;
- TRACE(("%s() thread stuck?!, ", THREAD_NAME));
- }
- else {
- /* Thread finished before timeout; propagate Winsock error to this
- * thread. 'conn->async.done = TRUE' is set in
- * Curl_addrinfo4/6_callback().
- */
- WSASetLastError(conn->async.status);
- GetExitCodeThread(td->thread_hnd, &td->thread_status);
- TRACE(("%s() status %lu, thread retval %lu, ",
- THREAD_NAME, status, td->thread_status));
- }
- }
- else {
- conn->async.done = TRUE;
- td->thread_status = (DWORD)-1;
- TRACE(("%s() timeout, ", THREAD_NAME));
- }
-
- TRACE(("elapsed %lu ms\n", GetTickCount()-ticks));
-
- if(entry)
- *entry = conn->async.dns;
-
- rc = CURLE_OK;
-
- if (!conn->async.dns) {
- /* a name was not resolved */
- if (td->thread_status == CURLE_OUT_OF_MEMORY) {
- rc = CURLE_OUT_OF_MEMORY;
- failf(data, "Could not resolve host: %s", curl_easy_strerror(rc));
- }
- else if(conn->async.done) {
- if(conn->bits.httpproxy) {
- failf(data, "Could not resolve proxy: %s; %s",
- conn->proxy.dispname, Curl_strerror(conn, conn->async.status));
- rc = CURLE_COULDNT_RESOLVE_PROXY;
- }
- else {
- failf(data, "Could not resolve host: %s; %s",
- conn->host.name, Curl_strerror(conn, conn->async.status));
- rc = CURLE_COULDNT_RESOLVE_HOST;
- }
- }
- else if (td->thread_status == (DWORD)-1 || conn->async.status == NO_DATA) {
- failf(data, "Resolving host timed out: %s", conn->host.name);
- rc = CURLE_OPERATION_TIMEDOUT;
- }
- else
- rc = CURLE_OPERATION_TIMEDOUT;
- }
-
- Curl_destroy_thread_data(&conn->async);
-
- if(!conn->async.dns)
- conn->bits.close = TRUE;
-
- return (rc);
-}
-
-/*
- * Curl_is_resolved() is called repeatedly to check if a previous name resolve
- * request has completed. It should also make sure to time-out if the
- * operation seems to take too long.
- */
-CURLcode Curl_is_resolved(struct connectdata *conn,
- struct Curl_dns_entry **entry)
-{
- *entry = NULL;
-
- if (conn->async.done) {
- /* we're done */
- Curl_destroy_thread_data(&conn->async);
- if (!conn->async.dns) {
- TRACE(("Curl_is_resolved(): CURLE_COULDNT_RESOLVE_HOST\n"));
- return CURLE_COULDNT_RESOLVE_HOST;
- }
- *entry = conn->async.dns;
- TRACE(("resolved okay, dns %p\n", *entry));
- }
- return CURLE_OK;
-}
-
-int Curl_resolv_getsock(struct connectdata *conn,
- curl_socket_t *socks,
- int numsocks)
-{
- const struct thread_data *td =
- (const struct thread_data *) conn->async.os_specific;
-
- if (td && td->dummy_sock != CURL_SOCKET_BAD) {
- if(numsocks) {
- /* return one socket waiting for writable, even though this is just
- a dummy */
- socks[0] = td->dummy_sock;
- return GETSOCK_WRITESOCK(0);
- }
- }
- return 0;
-}
-
-#ifdef CURLRES_IPV4
-/*
- * Curl_getaddrinfo() - for Windows threading without ENABLE_IPV6.
- */
-Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
- const char *hostname,
- int port,
- int *waitp)
-{
- struct hostent *h = NULL;
- struct SessionHandle *data = conn->data;
- in_addr_t in;
-
- *waitp = 0; /* don't wait, we act synchronously */
-
- in = inet_addr(hostname);
- if (in != CURL_INADDR_NONE)
- /* This is a dotted IP address 123.123.123.123-style */
- return Curl_ip2addr(in, hostname, port);
-
- /* fire up a new resolver thread! */
- if (init_resolve_thread(conn, hostname, port, NULL)) {
- *waitp = TRUE; /* please wait for the response */
- return NULL;
- }
-
- /* fall-back to blocking version */
- infof(data, "init_resolve_thread() failed for %s; %s\n",
- hostname, Curl_strerror(conn,GetLastError()));
-
- h = gethostbyname(hostname);
- if (!h) {
- infof(data, "gethostbyname(2) failed for %s:%d; %s\n",
- hostname, port, Curl_strerror(conn,WSAGetLastError()));
- return NULL;
- }
- return Curl_he2ai(h, port);
-}
-#endif /* CURLRES_IPV4 */
-
-#ifdef CURLRES_IPV6
-/*
- * Curl_getaddrinfo() - for Windows threading IPv6 enabled
- */
-Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
- const char *hostname,
- int port,
- int *waitp)
-{
- struct addrinfo hints, *res;
- int error;
- char sbuf[NI_MAXSERV];
- curl_socket_t s;
- int pf;
- struct SessionHandle *data = conn->data;
-
- *waitp = FALSE; /* default to synch response */
-
- /* see if we have an IPv6 stack */
- s = socket(PF_INET6, SOCK_DGRAM, 0);
- if (s == CURL_SOCKET_BAD) {
- /* Some non-IPv6 stacks have been found to make very slow name resolves
- * when PF_UNSPEC is used, so thus we switch to a mere PF_INET lookup if
- * the stack seems to be a non-ipv6 one. */
-
- pf = PF_INET;
- }
- else {
- /* This seems to be an IPv6-capable stack, use PF_UNSPEC for the widest
- * possible checks. And close the socket again.
- */
- sclose(s);
-
- /*
- * Check if a more limited name resolve has been requested.
- */
- switch(data->set.ip_version) {
- case CURL_IPRESOLVE_V4:
- pf = PF_INET;
- break;
- case CURL_IPRESOLVE_V6:
- pf = PF_INET6;
- break;
- default:
- pf = PF_UNSPEC;
- break;
- }
- }
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = pf;
- hints.ai_socktype = conn->socktype;
-#if 0 /* removed nov 8 2005 before 7.15.1 */
- hints.ai_flags = AI_CANONNAME;
-#endif
- itoa(port, sbuf, 10);
-
- /* fire up a new resolver thread! */
- if (init_resolve_thread(conn, hostname, port, &hints)) {
- *waitp = TRUE; /* please wait for the response */
- return NULL;
- }
-
- /* fall-back to blocking version */
- infof(data, "init_resolve_thread() failed for %s; %s\n",
- hostname, Curl_strerror(conn,GetLastError()));
-
- error = getaddrinfo(hostname, sbuf, &hints, &res);
- if (error) {
- infof(data, "getaddrinfo() failed for %s:%d; %s\n",
- hostname, port, Curl_strerror(conn,WSAGetLastError()));
- return NULL;
- }
- return res;
-}
-#endif /* CURLRES_IPV6 */
-#endif /* CURLRES_THREADED */
diff --git a/Utilities/cmcurl/http.c b/Utilities/cmcurl/http.c
deleted file mode 100644
index 5405aace1..000000000
--- a/Utilities/cmcurl/http.c
+++ /dev/null
@@ -1,2422 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#ifndef CURL_DISABLE_HTTP
-/* -- WIN32 approved -- */
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <ctype.h>
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-
-#ifdef WIN32
-#include <time.h>
-#include <io.h>
-#else
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-
-#ifdef HAVE_TIME_H
-#ifdef TIME_WITH_SYS_TIME
-#include <time.h>
-#endif
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <netdb.h>
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_NET_IF_H
-#include <net/if.h>
-#endif
-#include <sys/ioctl.h>
-#include <signal.h>
-
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
-#endif
-
-#include "urldata.h"
-#include <curl/curl.h>
-#include "transfer.h"
-#include "sendf.h"
-#include "easyif.h" /* for Curl_convert_... prototypes */
-#include "formdata.h"
-#include "progress.h"
-#include "base64.h"
-#include "cookie.h"
-#include "strequal.h"
-#include "sslgen.h"
-#include "http_digest.h"
-#include "http_ntlm.h"
-#include "http_negotiate.h"
-#include "url.h"
-#include "share.h"
-#include "hostip.h"
-#include "http.h"
-#include "memory.h"
-#include "select.h"
-#include "parsedate.h" /* for the week day and month names */
-#include "strtoofft.h"
-#include "multiif.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
-#include "memdebug.h"
-
-/*
- * checkheaders() checks the linked list of custom HTTP headers for a
- * particular header (prefix).
- *
- * Returns a pointer to the first matching header or NULL if none matched.
- */
-static char *checkheaders(struct SessionHandle *data, const char *thisheader)
-{
- struct curl_slist *head;
- size_t thislen = strlen(thisheader);
-
- for(head = data->set.headers; head; head=head->next) {
- if(strnequal(head->data, thisheader, thislen))
- return head->data;
- }
- return NULL;
-}
-
-/*
- * Curl_output_basic() sets up an Authorization: header (or the proxy version)
- * for HTTP Basic authentication.
- *
- * Returns CURLcode.
- */
-static CURLcode Curl_output_basic(struct connectdata *conn, bool proxy)
-{
- char *authorization;
- struct SessionHandle *data=conn->data;
- char **userp;
- char *user;
- char *pwd;
-
- if(proxy) {
- userp = &conn->allocptr.proxyuserpwd;
- user = conn->proxyuser;
- pwd = conn->proxypasswd;
- }
- else {
- userp = &conn->allocptr.userpwd;
- user = conn->user;
- pwd = conn->passwd;
- }
-
- snprintf(data->state.buffer, sizeof(data->state.buffer), "%s:%s", user, pwd);
- if(Curl_base64_encode(data, data->state.buffer,
- strlen(data->state.buffer),
- &authorization) > 0) {
- if(*userp)
- free(*userp);
- *userp = aprintf( "%sAuthorization: Basic %s\r\n",
- proxy?"Proxy-":"",
- authorization);
- free(authorization);
- }
- else
- return CURLE_OUT_OF_MEMORY;
- return CURLE_OK;
-}
-
-/* pickoneauth() selects the most favourable authentication method from the
- * ones available and the ones we want.
- *
- * return TRUE if one was picked
- */
-static bool pickoneauth(struct auth *pick)
-{
- bool picked;
- /* only deal with authentication we want */
- long avail = pick->avail & pick->want;
- picked = TRUE;
-
- /* The order of these checks is highly relevant, as this will be the order
- of preference in case of the existence of multiple accepted types. */
- if(avail & CURLAUTH_GSSNEGOTIATE)
- pick->picked = CURLAUTH_GSSNEGOTIATE;
- else if(avail & CURLAUTH_DIGEST)
- pick->picked = CURLAUTH_DIGEST;
- else if(avail & CURLAUTH_NTLM)
- pick->picked = CURLAUTH_NTLM;
- else if(avail & CURLAUTH_BASIC)
- pick->picked = CURLAUTH_BASIC;
- else {
- pick->picked = CURLAUTH_PICKNONE; /* we select to use nothing */
- picked = FALSE;
- }
- pick->avail = CURLAUTH_NONE; /* clear it here */
-
- return picked;
-}
-
-/*
- * perhapsrewind()
- *
- * If we are doing POST or PUT {
- * If we have more data to send {
- * If we are doing NTLM {
- * Keep sending since we must not disconnect
- * }
- * else {
- * If there is more than just a little data left to send, close
- * the current connection by force.
- * }
- * }
- * If we have sent any data {
- * If we don't have track of all the data {
- * call app to tell it to rewind
- * }
- * else {
- * rewind internally so that the operation can restart fine
- * }
- * }
- * }
- */
-static CURLcode perhapsrewind(struct connectdata *conn)
-{
- struct SessionHandle *data = conn->data;
- struct HTTP *http = data->reqdata.proto.http;
- struct Curl_transfer_keeper *k = &data->reqdata.keep;
- curl_off_t bytessent;
- curl_off_t expectsend = -1; /* default is unknown */
-
- if(!http)
- /* If this is still NULL, we have not reach very far and we can
- safely skip this rewinding stuff */
- return CURLE_OK;
-
- bytessent = http->writebytecount;
-
- if(conn->bits.authneg)
- /* This is a state where we are known to be negotiating and we don't send
- any data then. */
- expectsend = 0;
- else {
- /* figure out how much data we are expected to send */
- switch(data->set.httpreq) {
- case HTTPREQ_POST:
- if(data->set.postfieldsize != -1)
- expectsend = data->set.postfieldsize;
- break;
- case HTTPREQ_PUT:
- if(data->set.infilesize != -1)
- expectsend = data->set.infilesize;
- break;
- case HTTPREQ_POST_FORM:
- expectsend = http->postsize;
- break;
- default:
- break;
- }
- }
-
- conn->bits.rewindaftersend = FALSE; /* default */
-
- if((expectsend == -1) || (expectsend > bytessent)) {
- /* There is still data left to send */
- if((data->state.authproxy.picked == CURLAUTH_NTLM) ||
- (data->state.authhost.picked == CURLAUTH_NTLM)) {
- if(((expectsend - bytessent) < 2000) ||
- (conn->ntlm.state != NTLMSTATE_NONE)) {
- /* The NTLM-negotiation has started *OR* there is just a little (<2K)
- data left to send, keep on sending. */
-
- /* rewind data when completely done sending! */
- if(!conn->bits.authneg)
- conn->bits.rewindaftersend = TRUE;
-
- return CURLE_OK;
- }
- if(conn->bits.close)
- /* this is already marked to get closed */
- return CURLE_OK;
-
- infof(data, "NTLM send, close instead of sending %" FORMAT_OFF_T
- " bytes\n", (curl_off_t)(expectsend - bytessent));
- }
-
- /* This is not NTLM or NTLM with many bytes left to send: close
- */
- conn->bits.close = TRUE;
- k->size = 0; /* don't download any more than 0 bytes */
- }
-
- if(bytessent)
- return Curl_readrewind(conn);
-
- return CURLE_OK;
-}
-
-/*
- * Curl_http_auth_act() gets called when a all HTTP headers have been received
- * and it checks what authentication methods that are available and decides
- * which one (if any) to use. It will set 'newurl' if an auth metod was
- * picked.
- */
-
-CURLcode Curl_http_auth_act(struct connectdata *conn)
-{
- struct SessionHandle *data = conn->data;
- bool pickhost = FALSE;
- bool pickproxy = FALSE;
- CURLcode code = CURLE_OK;
-
- if(100 == data->reqdata.keep.httpcode)
- /* this is a transient response code, ignore */
- return CURLE_OK;
-
- if(data->state.authproblem)
- return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
-
- if(conn->bits.user_passwd &&
- ((data->reqdata.keep.httpcode == 401) ||
- (conn->bits.authneg && data->reqdata.keep.httpcode < 300))) {
- pickhost = pickoneauth(&data->state.authhost);
- if(!pickhost)
- data->state.authproblem = TRUE;
- }
- if(conn->bits.proxy_user_passwd &&
- ((data->reqdata.keep.httpcode == 407) ||
- (conn->bits.authneg && data->reqdata.keep.httpcode < 300))) {
- pickproxy = pickoneauth(&data->state.authproxy);
- if(!pickproxy)
- data->state.authproblem = TRUE;
- }
-
- if(pickhost || pickproxy) {
- data->reqdata.newurl = strdup(data->change.url); /* clone URL */
-
- if((data->set.httpreq != HTTPREQ_GET) &&
- (data->set.httpreq != HTTPREQ_HEAD) &&
- !conn->bits.rewindaftersend) {
- code = perhapsrewind(conn);
- if(code)
- return code;
- }
- }
-
- else if((data->reqdata.keep.httpcode < 300) &&
- (!data->state.authhost.done) &&
- conn->bits.authneg) {
- /* no (known) authentication available,
- authentication is not "done" yet and
- no authentication seems to be required and
- we didn't try HEAD or GET */
- if((data->set.httpreq != HTTPREQ_GET) &&
- (data->set.httpreq != HTTPREQ_HEAD)) {
- data->reqdata.newurl = strdup(data->change.url); /* clone URL */
- data->state.authhost.done = TRUE;
- }
- }
- if (Curl_http_should_fail(conn)) {
- failf (data, "The requested URL returned error: %d",
- data->reqdata.keep.httpcode);
- code = CURLE_HTTP_RETURNED_ERROR;
- }
-
- return code;
-}
-
-/**
- * Curl_http_output_auth() setups the authentication headers for the
- * host/proxy and the correct authentication
- * method. conn->data->state.authdone is set to TRUE when authentication is
- * done.
- *
- * @param conn all information about the current connection
- * @param request pointer to the request keyword
- * @param path pointer to the requested path
- * @param proxytunnel boolean if this is the request setting up a "proxy
- * tunnel"
- *
- * @returns CURLcode
- */
-static CURLcode
-Curl_http_output_auth(struct connectdata *conn,
- char *request,
- char *path,
- bool proxytunnel) /* TRUE if this is the request setting
- up the proxy tunnel */
-{
- CURLcode result = CURLE_OK;
- struct SessionHandle *data = conn->data;
- char *auth=NULL;
- struct auth *authhost;
- struct auth *authproxy;
-
- curlassert(data);
-
- authhost = &data->state.authhost;
- authproxy = &data->state.authproxy;
-
- if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
- conn->bits.user_passwd)
- /* continue please */ ;
- else {
- authhost->done = TRUE;
- authproxy->done = TRUE;
- return CURLE_OK; /* no authentication with no user or password */
- }
-
- if(authhost->want && !authhost->picked)
- /* The app has selected one or more methods, but none has been picked
- so far by a server round-trip. Then we set the picked one to the
- want one, and if this is one single bit it'll be used instantly. */
- authhost->picked = authhost->want;
-
- if(authproxy->want && !authproxy->picked)
- /* The app has selected one or more methods, but none has been picked so
- far by a proxy round-trip. Then we set the picked one to the want one,
- and if this is one single bit it'll be used instantly. */
- authproxy->picked = authproxy->want;
-
- /* Send proxy authentication header if needed */
- if (conn->bits.httpproxy &&
- (conn->bits.tunnel_proxy == proxytunnel)) {
-#ifdef USE_NTLM
- if(authproxy->picked == CURLAUTH_NTLM) {
- auth=(char *)"NTLM";
- result = Curl_output_ntlm(conn, TRUE);
- if(result)
- return result;
- }
- else
-#endif
- if(authproxy->picked == CURLAUTH_BASIC) {
- /* Basic */
- if(conn->bits.proxy_user_passwd &&
- !checkheaders(data, "Proxy-authorization:")) {
- auth=(char *)"Basic";
- result = Curl_output_basic(conn, TRUE);
- if(result)
- return result;
- }
- /* NOTE: Curl_output_basic() should set 'done' TRUE, as the other auth
- functions work that way */
- authproxy->done = TRUE;
- }
-#ifndef CURL_DISABLE_CRYPTO_AUTH
- else if(authproxy->picked == CURLAUTH_DIGEST) {
- auth=(char *)"Digest";
- result = Curl_output_digest(conn,
- TRUE, /* proxy */
- (unsigned char *)request,
- (unsigned char *)path);
- if(result)
- return result;
- }
-#endif
- if(auth) {
- infof(data, "Proxy auth using %s with user '%s'\n",
- auth, conn->proxyuser?conn->proxyuser:"");
- authproxy->multi = (bool)(!authproxy->done);
- }
- else
- authproxy->multi = FALSE;
- }
- else
- /* we have no proxy so let's pretend we're done authenticating
- with it */
- authproxy->done = TRUE;
-
- /* To prevent the user+password to get sent to other than the original
- host due to a location-follow, we do some weirdo checks here */
- if(!data->state.this_is_a_follow ||
- conn->bits.netrc ||
- !data->state.first_host ||
- curl_strequal(data->state.first_host, conn->host.name) ||
- data->set.http_disable_hostname_check_before_authentication) {
-
- /* Send web authentication header if needed */
- {
- auth = NULL;
-#ifdef HAVE_GSSAPI
- if((authhost->picked == CURLAUTH_GSSNEGOTIATE) &&
- data->state.negotiate.context &&
- !GSS_ERROR(data->state.negotiate.status)) {
- auth=(char *)"GSS-Negotiate";
- result = Curl_output_negotiate(conn);
- if (result)
- return result;
- authhost->done = TRUE;
- }
- else
-#endif
-#ifdef USE_NTLM
- if(authhost->picked == CURLAUTH_NTLM) {
- auth=(char *)"NTLM";
- result = Curl_output_ntlm(conn, FALSE);
- if(result)
- return result;
- }
- else
-#endif
- {
-#ifndef CURL_DISABLE_CRYPTO_AUTH
- if(authhost->picked == CURLAUTH_DIGEST) {
- auth=(char *)"Digest";
- result = Curl_output_digest(conn,
- FALSE, /* not a proxy */
- (unsigned char *)request,
- (unsigned char *)path);
- if(result)
- return result;
- } else
-#endif
- if(authhost->picked == CURLAUTH_BASIC) {
- if(conn->bits.user_passwd &&
- !checkheaders(data, "Authorization:")) {
- auth=(char *)"Basic";
- result = Curl_output_basic(conn, FALSE);
- if(result)
- return result;
- }
- /* basic is always ready */
- authhost->done = TRUE;
- }
- }
- if(auth) {
- infof(data, "Server auth using %s with user '%s'\n",
- auth, conn->user);
-
- authhost->multi = (bool)(!authhost->done);
- }
- else
- authhost->multi = FALSE;
- }
- }
- else
- authhost->done = TRUE;
-
- return result;
-}
-
-
-/*
- * Curl_http_input_auth() deals with Proxy-Authenticate: and WWW-Authenticate:
- * headers. They are dealt with both in the transfer.c main loop and in the
- * proxy CONNECT loop.
- */
-
-CURLcode Curl_http_input_auth(struct connectdata *conn,
- int httpcode,
- char *header) /* the first non-space */
-{
- /*
- * This resource requires authentication
- */
- struct SessionHandle *data = conn->data;
-
- long *availp;
- char *start;
- struct auth *authp;
-
- if (httpcode == 407) {
- start = header+strlen("Proxy-authenticate:");
- availp = &data->info.proxyauthavail;
- authp = &data->state.authproxy;
- }
- else {
- start = header+strlen("WWW-Authenticate:");
- availp = &data->info.httpauthavail;
- authp = &data->state.authhost;
- }
-
- /* pass all white spaces */
- while(*start && ISSPACE(*start))
- start++;
-
- /*
- * Here we check if we want the specific single authentication (using ==) and
- * if we do, we initiate usage of it.
- *
- * If the provided authentication is wanted as one out of several accepted
- * types (using &), we OR this authentication type to the authavail
- * variable.
- */
-
-#ifdef HAVE_GSSAPI
- if (checkprefix("GSS-Negotiate", start) ||
- checkprefix("Negotiate", start)) {
- *availp |= CURLAUTH_GSSNEGOTIATE;
- authp->avail |= CURLAUTH_GSSNEGOTIATE;
- if(authp->picked == CURLAUTH_GSSNEGOTIATE) {
- /* if exactly this is wanted, go */
- int neg = Curl_input_negotiate(conn, start);
- if (neg == 0) {
- data->reqdata.newurl = strdup(data->change.url);
- data->state.authproblem = (data->reqdata.newurl == NULL);
- }
- else {
- infof(data, "Authentication problem. Ignoring this.\n");
- data->state.authproblem = TRUE;
- }
- }
- }
- else
-#endif
-#ifdef USE_NTLM
- /* NTLM support requires the SSL crypto libs */
- if(checkprefix("NTLM", start)) {
- *availp |= CURLAUTH_NTLM;
- authp->avail |= CURLAUTH_NTLM;
- if(authp->picked == CURLAUTH_NTLM) {
- /* NTLM authentication is picked and activated */
- CURLntlm ntlm =
- Curl_input_ntlm(conn, (bool)(httpcode == 407), start);
-
- if(CURLNTLM_BAD != ntlm)
- data->state.authproblem = FALSE;
- else {
- infof(data, "Authentication problem. Ignoring this.\n");
- data->state.authproblem = TRUE;
- }
- }
- }
- else
-#endif
-#ifndef CURL_DISABLE_CRYPTO_AUTH
- if(checkprefix("Digest", start)) {
- if((authp->avail & CURLAUTH_DIGEST) != 0) {
- infof(data, "Ignoring duplicate digest auth header.\n");
- }
- else {
- CURLdigest dig;
- *availp |= CURLAUTH_DIGEST;
- authp->avail |= CURLAUTH_DIGEST;
-
- /* We call this function on input Digest headers even if Digest
- * authentication isn't activated yet, as we need to store the
- * incoming data from this header in case we are gonna use Digest. */
- dig = Curl_input_digest(conn, (bool)(httpcode == 407), start);
-
- if(CURLDIGEST_FINE != dig) {
- infof(data, "Authentication problem. Ignoring this.\n");
- data->state.authproblem = TRUE;
- }
- }
- }
- else
-#endif
- if(checkprefix("Basic", start)) {
- *availp |= CURLAUTH_BASIC;
- authp->avail |= CURLAUTH_BASIC;
- if(authp->picked == CURLAUTH_BASIC) {
- /* We asked for Basic authentication but got a 40X back
- anyway, which basicly means our name+password isn't
- valid. */
- authp->avail = CURLAUTH_NONE;
- infof(data, "Authentication problem. Ignoring this.\n");
- data->state.authproblem = TRUE;
- }
- }
-
- return CURLE_OK;
-}
-
-/**
- * Curl_http_should_fail() determines whether an HTTP response has gotten us
- * into an error state or not.
- *
- * @param conn all information about the current connection
- *
- * @retval 0 communications should continue
- *
- * @retval 1 communications should not continue
- */
-int Curl_http_should_fail(struct connectdata *conn)
-{
- struct SessionHandle *data;
- struct Curl_transfer_keeper *k;
-
- curlassert(conn);
- data = conn->data;
- curlassert(data);
-
- /*
- ** For readability
- */
- k = &data->reqdata.keep;
-
- /*
- ** If we haven't been asked to fail on error,
- ** don't fail.
- */
- if (!data->set.http_fail_on_error)
- return 0;
-
- /*
- ** Any code < 400 is never terminal.
- */
- if (k->httpcode < 400)
- return 0;
-
- if (data->reqdata.resume_from &&
- (data->set.httpreq==HTTPREQ_GET) &&
- (k->httpcode == 416)) {
- /* "Requested Range Not Satisfiable", just proceed and
- pretend this is no error */
- return 0;
- }
-
- /*
- ** Any code >= 400 that's not 401 or 407 is always
- ** a terminal error
- */
- if ((k->httpcode != 401) &&
- (k->httpcode != 407))
- return 1;
-
- /*
- ** All we have left to deal with is 401 and 407
- */
- curlassert((k->httpcode == 401) || (k->httpcode == 407));
-
- /*
- ** Examine the current authentication state to see if this
- ** is an error. The idea is for this function to get
- ** called after processing all the headers in a response
- ** message. So, if we've been to asked to authenticate a
- ** particular stage, and we've done it, we're OK. But, if
- ** we're already completely authenticated, it's not OK to
- ** get another 401 or 407.
- **
- ** It is possible for authentication to go stale such that
- ** the client needs to reauthenticate. Once that info is
- ** available, use it here.
- */
-#if 0 /* set to 1 when debugging this functionality */
- infof(data,"%s: authstage = %d\n",__FUNCTION__,data->state.authstage);
- infof(data,"%s: authwant = 0x%08x\n",__FUNCTION__,data->state.authwant);
- infof(data,"%s: authavail = 0x%08x\n",__FUNCTION__,data->state.authavail);
- infof(data,"%s: httpcode = %d\n",__FUNCTION__,k->httpcode);
- infof(data,"%s: authdone = %d\n",__FUNCTION__,data->state.authdone);
- infof(data,"%s: newurl = %s\n",__FUNCTION__,data->reqdata.newurl ? data->reqdata.newurl : "(null)");
- infof(data,"%s: authproblem = %d\n",__FUNCTION__,data->state.authproblem);
-#endif
-
- /*
- ** Either we're not authenticating, or we're supposed to
- ** be authenticating something else. This is an error.
- */
- if((k->httpcode == 401) && !conn->bits.user_passwd)
- return TRUE;
- if((k->httpcode == 407) && !conn->bits.proxy_user_passwd)
- return TRUE;
-
- return data->state.authproblem;
-}
-
-/*
- * readmoredata() is a "fread() emulation" to provide POST and/or request
- * data. It is used when a huge POST is to be made and the entire chunk wasn't
- * sent in the first send(). This function will then be called from the
- * transfer.c loop when more data is to be sent to the peer.
- *
- * Returns the amount of bytes it filled the buffer with.
- */
-static size_t readmoredata(char *buffer,
- size_t size,
- size_t nitems,
- void *userp)
-{
- struct connectdata *conn = (struct connectdata *)userp;
- struct HTTP *http = conn->data->reqdata.proto.http;
- size_t fullsize = size * nitems;
-
- if(0 == http->postsize)
- /* nothing to return */
- return 0;
-
- /* make sure that a HTTP request is never sent away chunked! */
- conn->bits.forbidchunk = (bool)(http->sending == HTTPSEND_REQUEST);
-
- if(http->postsize <= (curl_off_t)fullsize) {
- memcpy(buffer, http->postdata, (size_t)http->postsize);
- fullsize = (size_t)http->postsize;
-
- if(http->backup.postsize) {
- /* move backup data into focus and continue on that */
- http->postdata = http->backup.postdata;
- http->postsize = http->backup.postsize;
- conn->fread = http->backup.fread;
- conn->fread_in = http->backup.fread_in;
-
- http->sending++; /* move one step up */
-
- http->backup.postsize=0;
- }
- else
- http->postsize = 0;
-
- return fullsize;
- }
-
- memcpy(buffer, http->postdata, fullsize);
- http->postdata += fullsize;
- http->postsize -= fullsize;
-
- return fullsize;
-}
-
-/* ------------------------------------------------------------------------- */
-/*
- * The add_buffer series of functions are used to build one large memory chunk
- * from repeated function invokes. Used so that the entire HTTP request can
- * be sent in one go.
- */
-
-struct send_buffer {
- char *buffer;
- size_t size_max;
- size_t size_used;
-};
-typedef struct send_buffer send_buffer;
-
-static CURLcode add_custom_headers(struct connectdata *conn,
- send_buffer *req_buffer);
-static CURLcode
- add_buffer(send_buffer *in, const void *inptr, size_t size);
-
-/*
- * add_buffer_init() sets up and returns a fine buffer struct
- */
-static
-send_buffer *add_buffer_init(void)
-{
- send_buffer *blonk;
- blonk=(send_buffer *)malloc(sizeof(send_buffer));
- if(blonk) {
- memset(blonk, 0, sizeof(send_buffer));
- return blonk;
- }
- return NULL; /* failed, go home */
-}
-
-/*
- * add_buffer_send() sends a header buffer and frees all associated memory.
- * Body data may be appended to the header data if desired.
- *
- * Returns CURLcode
- */
-static
-CURLcode add_buffer_send(send_buffer *in,
- struct connectdata *conn,
- long *bytes_written, /* add the number of sent
- bytes to this counter */
- size_t included_body_bytes, /* how much of the buffer
- contains body data (for log tracing) */
- int socketindex)
-
-{
- ssize_t amount;
- CURLcode res;
- char *ptr;
- size_t size;
- struct HTTP *http = conn->data->reqdata.proto.http;
- size_t sendsize;
- curl_socket_t sockfd;
-
- curlassert(socketindex <= SECONDARYSOCKET);
-
- sockfd = conn->sock[socketindex];
-
- /* The looping below is required since we use non-blocking sockets, but due
- to the circumstances we will just loop and try again and again etc */
-
- ptr = in->buffer;
- size = in->size_used;
-
-#ifdef CURL_DOES_CONVERSIONS
- if(size - included_body_bytes > 0) {
- res = Curl_convert_to_network(conn->data, ptr, size - included_body_bytes);
- /* Curl_convert_to_network calls failf if unsuccessful */
- if(res != CURLE_OK) {
- /* conversion failed, free memory and return to the caller */
- if(in->buffer)
- free(in->buffer);
- free(in);
- return res;
- }
- }
-#endif /* CURL_DOES_CONVERSIONS */
-
- if(conn->protocol & PROT_HTTPS) {
- /* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
- when we speak HTTPS, as if only a fraction of it is sent now, this data
- needs to fit into the normal read-callback buffer later on and that
- buffer is using this size.
- */
-
- sendsize= (size > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:size;
-
- /* OpenSSL is very picky and we must send the SAME buffer pointer to the
- library when we attempt to re-send this buffer. Sending the same data
- is not enough, we must use the exact same address. For this reason, we
- must copy the data to the uploadbuffer first, since that is the buffer
- we will be using if this send is retried later.
- */
- memcpy(conn->data->state.uploadbuffer, ptr, sendsize);
- ptr = conn->data->state.uploadbuffer;
- }
- else
- sendsize = size;
-
- res = Curl_write(conn, sockfd, ptr, sendsize, &amount);
-
- if(CURLE_OK == res) {
-
- if(conn->data->set.verbose) {
- /* this data _may_ contain binary stuff */
- Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr,
- (size_t)(amount-included_body_bytes), conn);
- if (included_body_bytes)
- Curl_debug(conn->data, CURLINFO_DATA_OUT,
- ptr+amount-included_body_bytes,
- (size_t)included_body_bytes, conn);
- }
-
- *bytes_written += amount;
-
- if(http) {
- if((size_t)amount != size) {
- /* The whole request could not be sent in one system call. We must
- queue it up and send it later when we get the chance. We must not
- loop here and wait until it might work again. */
-
- size -= amount;
-
- ptr = in->buffer + amount;
-
- /* backup the currently set pointers */
- http->backup.fread = conn->fread;
- http->backup.fread_in = conn->fread_in;
- http->backup.postdata = http->postdata;
- http->backup.postsize = http->postsize;
-
- /* set the new pointers for the request-sending */
- conn->fread = (curl_read_callback)readmoredata;
- conn->fread_in = (void *)conn;
- http->postdata = ptr;
- http->postsize = (curl_off_t)size;
-
- http->send_buffer = in;
- http->sending = HTTPSEND_REQUEST;
-
- return CURLE_OK;
- }
- http->sending = HTTPSEND_BODY;
- /* the full buffer was sent, clean up and return */
- }
- else {
- if((size_t)amount != size)
- /* We have no continue-send mechanism now, fail. This can only happen
- when this function is used from the CONNECT sending function. We
- currently (stupidly) assume that the whole request is always sent
- away in the first single chunk.
-
- This needs FIXing.
- */
- return CURLE_SEND_ERROR;
- else
- conn->writechannel_inuse = FALSE;
- }
- }
- if(in->buffer)
- free(in->buffer);
- free(in);
-
- return res;
-}
-
-
-/*
- * add_bufferf() add the formatted input to the buffer.
- */
-static
-CURLcode add_bufferf(send_buffer *in, const char *fmt, ...)
-{
- char *s;
- va_list ap;
- va_start(ap, fmt);
- s = vaprintf(fmt, ap); /* this allocs a new string to append */
- va_end(ap);
-
- if(s) {
- CURLcode result = add_buffer(in, s, strlen(s));
- free(s);
- if(CURLE_OK == result)
- return CURLE_OK;
- }
- /* If we failed, we cleanup the whole buffer and return error */
- if(in->buffer)
- free(in->buffer);
- free(in);
- return CURLE_OUT_OF_MEMORY;
-}
-
-/*
- * add_buffer() appends a memory chunk to the existing buffer
- */
-static
-CURLcode add_buffer(send_buffer *in, const void *inptr, size_t size)
-{
- char *new_rb;
- size_t new_size;
-
- if(!in->buffer ||
- ((in->size_used + size) > (in->size_max - 1))) {
- new_size = (in->size_used+size)*2;
- if(in->buffer)
- /* we have a buffer, enlarge the existing one */
- new_rb = (char *)realloc(in->buffer, new_size);
- else
- /* create a new buffer */
- new_rb = (char *)malloc(new_size);
-
- if(!new_rb)
- return CURLE_OUT_OF_MEMORY;
-
- in->buffer = new_rb;
- in->size_max = new_size;
- }
- memcpy(&in->buffer[in->size_used], inptr, size);
-
- in->size_used += size;
-
- return CURLE_OK;
-}
-
-/* end of the add_buffer functions */
-/* ------------------------------------------------------------------------- */
-
-/*
- * Curl_compareheader()
- *
- * Returns TRUE if 'headerline' contains the 'header' with given 'content'.
- * Pass headers WITH the colon.
- */
-bool
-Curl_compareheader(char *headerline, /* line to check */
- const char *header, /* header keyword _with_ colon */
- const char *content) /* content string to find */
-{
- /* RFC2616, section 4.2 says: "Each header field consists of a name followed
- * by a colon (":") and the field value. Field names are case-insensitive.
- * The field value MAY be preceded by any amount of LWS, though a single SP
- * is preferred." */
-
- size_t hlen = strlen(header);
- size_t clen;
- size_t len;
- char *start;
- char *end;
-
- if(!strnequal(headerline, header, hlen))
- return FALSE; /* doesn't start with header */
-
- /* pass the header */
- start = &headerline[hlen];
-
- /* pass all white spaces */
- while(*start && ISSPACE(*start))
- start++;
-
- /* find the end of the header line */
- end = strchr(start, '\r'); /* lines end with CRLF */
- if(!end) {
- /* in case there's a non-standard compliant line here */
- end = strchr(start, '\n');
-
- if(!end)
- /* hm, there's no line ending here, use the zero byte! */
- end = strchr(start, '\0');
- }
-
- len = end-start; /* length of the content part of the input line */
- clen = strlen(content); /* length of the word to find */
-
- /* find the content string in the rest of the line */
- for(;len>=clen;len--, start++) {
- if(strnequal(start, content, clen))
- return TRUE; /* match! */
- }
-
- return FALSE; /* no match */
-}
-
-/*
- * Curl_proxyCONNECT() requires that we're connected to a HTTP proxy. This
- * function will issue the necessary commands to get a seamless tunnel through
- * this proxy. After that, the socket can be used just as a normal socket.
- *
- * This badly needs to be rewritten. CONNECT should be sent and dealt with
- * like any ordinary HTTP request, and not specially crafted like this. This
- * function only remains here like this for now since the rewrite is a bit too
- * much work to do at the moment.
- *
- * This function is BLOCKING which is nasty for all multi interface using apps.
- */
-
-CURLcode Curl_proxyCONNECT(struct connectdata *conn,
- int sockindex,
- char *hostname,
- int remote_port)
-{
- int subversion=0;
- struct SessionHandle *data=conn->data;
- struct Curl_transfer_keeper *k = &data->reqdata.keep;
- CURLcode result;
- int res;
- size_t nread; /* total size read */
- int perline; /* count bytes per line */
- int keepon=TRUE;
- ssize_t gotbytes;
- char *ptr;
- long timeout =
- data->set.timeout?data->set.timeout:3600; /* in seconds */
- char *line_start;
- char *host_port;
- curl_socket_t tunnelsocket = conn->sock[sockindex];
- send_buffer *req_buffer;
- curl_off_t cl=0;
- bool closeConnection = FALSE;
-
-#define SELECT_OK 0
-#define SELECT_ERROR 1
-#define SELECT_TIMEOUT 2
- int error = SELECT_OK;
-
- infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port);
- conn->bits.proxy_connect_closed = FALSE;
-
- do {
- if(data->reqdata.newurl) {
- /* This only happens if we've looped here due to authentication reasons,
- and we don't really use the newly cloned URL here then. Just free()
- it. */
- free(data->reqdata.newurl);
- data->reqdata.newurl = NULL;
- }
-
- /* initialize a dynamic send-buffer */
- req_buffer = add_buffer_init();
-
- if(!req_buffer)
- return CURLE_OUT_OF_MEMORY;
-
- host_port = aprintf("%s:%d", hostname, remote_port);
- if(!host_port)
- return CURLE_OUT_OF_MEMORY;
-
- /* Setup the proxy-authorization header, if any */
- result = Curl_http_output_auth(conn, (char *)"CONNECT", host_port, TRUE);
-
- if(CURLE_OK == result) {
- char *host=(char *)"";
- const char *proxyconn="";
- const char *useragent="";
-
- if(!checkheaders(data, "Host:")) {
- host = aprintf("Host: %s\r\n", host_port);
- if(!host)
- result = CURLE_OUT_OF_MEMORY;
- }
- if(!checkheaders(data, "Proxy-Connection:"))
- proxyconn = "Proxy-Connection: Keep-Alive\r\n";
-
- if(!checkheaders(data, "User-Agent:") && data->set.useragent)
- useragent = conn->allocptr.uagent;
-
- if(CURLE_OK == result) {
- /* Send the connect request to the proxy */
- /* BLOCKING */
- result =
- add_bufferf(req_buffer,
- "CONNECT %s:%d HTTP/1.0\r\n"
- "%s" /* Host: */
- "%s" /* Proxy-Authorization */
- "%s" /* User-Agent */
- "%s", /* Proxy-Connection */
- hostname, remote_port,
- host,
- conn->allocptr.proxyuserpwd?
- conn->allocptr.proxyuserpwd:"",
- useragent,
- proxyconn);
-
- if(CURLE_OK == result)
- result = add_custom_headers(conn, req_buffer);
-
- if(host && *host)
- free(host);
-
- if(CURLE_OK == result)
- /* CRLF terminate the request */
- result = add_bufferf(req_buffer, "\r\n");
-
- if(CURLE_OK == result)
- /* Now send off the request */
- result = add_buffer_send(req_buffer, conn,
- &data->info.request_size, 0, sockindex);
- }
- if(result)
- failf(data, "Failed sending CONNECT to proxy");
- }
- free(host_port);
- if(result)
- return result;
-
- ptr=data->state.buffer;
- line_start = ptr;
-
- nread=0;
- perline=0;
- keepon=TRUE;
-
- while((nread<BUFSIZE) && (keepon && !error)) {
-
- /* if timeout is requested, find out how much remaining time we have */
- long check = timeout - /* timeout time */
- Curl_tvdiff(Curl_tvnow(), conn->now)/1000; /* spent time */
- if(check <=0 ) {
- failf(data, "Proxy CONNECT aborted due to timeout");
- error = SELECT_TIMEOUT; /* already too little time */
- break;
- }
-
- /* timeout each second and check the timeout */
- switch (Curl_select(tunnelsocket, CURL_SOCKET_BAD, 1000)) {
- case -1: /* select() error, stop reading */
- error = SELECT_ERROR;
- failf(data, "Proxy CONNECT aborted due to select() error");
- break;
- case 0: /* timeout */
- break;
- default:
- res = Curl_read(conn, tunnelsocket, ptr, BUFSIZE-nread, &gotbytes);
- if(res< 0)
- /* EWOULDBLOCK */
- continue; /* go loop yourself */
- else if(res)
- keepon = FALSE;
- else if(gotbytes <= 0) {
- keepon = FALSE;
- error = SELECT_ERROR;
- failf(data, "Proxy CONNECT aborted");
- }
- else {
- /*
- * We got a whole chunk of data, which can be anything from one byte
- * to a set of lines and possibly just a piece of the last line.
- */
- int i;
-
- nread += gotbytes;
-
- if(keepon > TRUE) {
- /* This means we are currently ignoring a response-body, so we
- simply count down our counter and make sure to break out of the
- loop when we're done! */
- cl -= gotbytes;
- if(cl<=0) {
- keepon = FALSE;
- break;
- }
- }
- else
- for(i = 0; i < gotbytes; ptr++, i++) {
- perline++; /* amount of bytes in this line so far */
- if(*ptr=='\n') {
- char letter;
- int writetype;
-
- /* output debug if that is requested */
- if(data->set.verbose)
- Curl_debug(data, CURLINFO_HEADER_IN,
- line_start, (size_t)perline, conn);
-
- /* send the header to the callback */
- writetype = CLIENTWRITE_HEADER;
- if(data->set.include_header)
- writetype |= CLIENTWRITE_BODY;
-
- result = Curl_client_write(conn, writetype, line_start, perline);
- if(result)
- return result;
-
- /* Newlines are CRLF, so the CR is ignored as the line isn't
- really terminated until the LF comes. Treat a following CR
- as end-of-headers as well.*/
-
- if(('\r' == line_start[0]) ||
- ('\n' == line_start[0])) {
- /* end of response-headers from the proxy */
- if(cl && (407 == k->httpcode) && !data->state.authproblem) {
- /* If we get a 407 response code with content length when we
- * have no auth problem, we must ignore the whole
- * response-body */
- keepon = 2;
- infof(data, "Ignore %" FORMAT_OFF_T
- " bytes of response-body\n", cl);
- cl -= (gotbytes - i);/* remove the remaining chunk of what
- we already read */
- if(cl<=0)
- /* if the whole thing was already read, we are done! */
- keepon=FALSE;
- }
- else
- keepon = FALSE;
- break; /* breaks out of for-loop, not switch() */
- }
-
- /* keep a backup of the position we are about to blank */
- letter = line_start[perline];
- line_start[perline]=0; /* zero terminate the buffer */
- if((checkprefix("WWW-Authenticate:", line_start) &&
- (401 == k->httpcode)) ||
- (checkprefix("Proxy-authenticate:", line_start) &&
- (407 == k->httpcode))) {
- result = Curl_http_input_auth(conn, k->httpcode, line_start);
- if(result)
- return result;
- }
- else if(checkprefix("Content-Length:", line_start)) {
- cl = curlx_strtoofft(line_start + strlen("Content-Length:"),
- NULL, 10);
- }
- else if(Curl_compareheader(line_start,
- "Connection:", "close"))
- closeConnection = TRUE;
- else if(2 == sscanf(line_start, "HTTP/1.%d %d",
- &subversion,
- &k->httpcode)) {
- /* store the HTTP code from the proxy */
- data->info.httpproxycode = k->httpcode;
- }
- /* put back the letter we blanked out before */
- line_start[perline]= letter;
-
- perline=0; /* line starts over here */
- line_start = ptr+1; /* this skips the zero byte we wrote */
- }
- }
- }
- break;
- } /* switch */
- } /* while there's buffer left and loop is requested */
-
- if(error)
- return CURLE_RECV_ERROR;
-
- if(data->info.httpproxycode != 200)
- /* Deal with the possibly already received authenticate
- headers. 'newurl' is set to a new URL if we must loop. */
- Curl_http_auth_act(conn);
-
- if (closeConnection && data->reqdata.newurl) {
- /* Connection closed by server. Don't use it anymore */
- sclose(conn->sock[sockindex]);
- conn->sock[sockindex] = CURL_SOCKET_BAD;
- break;
- }
- } while(data->reqdata.newurl);
-
- if(200 != k->httpcode) {
- failf(data, "Received HTTP code %d from proxy after CONNECT",
- k->httpcode);
-
- if (closeConnection && data->reqdata.newurl)
- conn->bits.proxy_connect_closed = TRUE;
-
- return CURLE_RECV_ERROR;
- }
-
- /* If a proxy-authorization header was used for the proxy, then we should
- make sure that it isn't accidentally used for the document request
- after we've connected. So let's free and clear it here. */
- Curl_safefree(conn->allocptr.proxyuserpwd);
- conn->allocptr.proxyuserpwd = NULL;
-
- data->state.authproxy.done = TRUE;
-
- infof (data, "Proxy replied OK to CONNECT request\n");
- return CURLE_OK;
-}
-
-/*
- * Curl_http_connect() performs HTTP stuff to do at connect-time, called from
- * the generic Curl_connect().
- */
-CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
-{
- struct SessionHandle *data;
- CURLcode result;
-
- data=conn->data;
-
- /* If we are not using a proxy and we want a secure connection, perform SSL
- * initialization & connection now. If using a proxy with https, then we
- * must tell the proxy to CONNECT to the host we want to talk to. Only
- * after the connect has occurred, can we start talking SSL
- */
-
- if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
-
- /* either SSL over proxy, or explicitly asked for */
- result = Curl_proxyCONNECT(conn, FIRSTSOCKET,
- conn->host.name,
- conn->remote_port);
- if(CURLE_OK != result)
- return result;
- }
-
- if(!data->state.this_is_a_follow) {
- /* this is not a followed location, get the original host name */
- if (data->state.first_host)
- /* Free to avoid leaking memory on multiple requests*/
- free(data->state.first_host);
-
- data->state.first_host = strdup(conn->host.name);
- if(!data->state.first_host)
- return CURLE_OUT_OF_MEMORY;
- }
-
- if(conn->protocol & PROT_HTTPS) {
- /* perform SSL initialization */
- if(data->state.used_interface == Curl_if_multi) {
- result = Curl_https_connecting(conn, done);
- if(result)
- return result;
- }
- else {
- /* BLOCKING */
- result = Curl_ssl_connect(conn, FIRSTSOCKET);
- if(result)
- return result;
- *done = TRUE;
- }
- }
- else {
- *done = TRUE;
- }
-
- return CURLE_OK;
-}
-
-CURLcode Curl_https_connecting(struct connectdata *conn, bool *done)
-{
- CURLcode result;
- curlassert(conn->protocol & PROT_HTTPS);
-
- /* perform SSL initialization for this socket */
- result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
- if(result)
- return result;
-
- return CURLE_OK;
-}
-
-#ifdef USE_SSLEAY
-/* This function is OpenSSL-specific. It should be made to query the generic
- SSL layer instead. */
-int Curl_https_getsock(struct connectdata *conn,
- curl_socket_t *socks,
- int numsocks)
-{
- if (conn->protocol & PROT_HTTPS) {
- struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
-
- if(!numsocks)
- return GETSOCK_BLANK;
-
- if (connssl->connecting_state == ssl_connect_2_writing) {
- /* write mode */
- socks[0] = conn->sock[FIRSTSOCKET];
- return GETSOCK_WRITESOCK(0);
- }
- else if (connssl->connecting_state == ssl_connect_2_reading) {
- /* read mode */
- socks[0] = conn->sock[FIRSTSOCKET];
- return GETSOCK_READSOCK(0);
- }
- }
- return CURLE_OK;
-}
-#else
-#ifdef USE_GNUTLS
-int Curl_https_getsock(struct connectdata *conn,
- curl_socket_t *socks,
- int numsocks)
-{
- (void)conn;
- (void)socks;
- (void)numsocks;
- return GETSOCK_BLANK;
-}
-#endif
-#endif
-
-/*
- * Curl_http_done() gets called from Curl_done() after a single HTTP request
- * has been performed.
- */
-
-CURLcode Curl_http_done(struct connectdata *conn,
- CURLcode status, bool premature)
-{
- struct SessionHandle *data = conn->data;
- struct HTTP *http =data->reqdata.proto.http;
- struct Curl_transfer_keeper *k = &data->reqdata.keep;
- (void)premature; /* not used */
-
- /* set the proper values (possibly modified on POST) */
- conn->fread = data->set.fread; /* restore */
- conn->fread_in = data->set.in; /* restore */
-
- if (http == NULL)
- return CURLE_OK;
-
- if(http->send_buffer) {
- send_buffer *buff = http->send_buffer;
-
- free(buff->buffer);
- free(buff);
- http->send_buffer = NULL; /* clear the pointer */
- }
-
- if(HTTPREQ_POST_FORM == data->set.httpreq) {
- k->bytecount = http->readbytecount + http->writebytecount;
-
- Curl_formclean(&http->sendit); /* Now free that whole lot */
- if(http->form.fp) {
- /* a file being uploaded was left opened, close it! */
- fclose(http->form.fp);
- http->form.fp = NULL;
- }
- }
- else if(HTTPREQ_PUT == data->set.httpreq)
- k->bytecount = http->readbytecount + http->writebytecount;
-
- if (status != CURLE_OK)
- return (status);
-
- if(!conn->bits.retry &&
- ((http->readbytecount +
- conn->headerbytecount -
- conn->deductheadercount)) <= 0) {
- /* If this connection isn't simply closed to be retried, AND nothing was
- read from the HTTP server (that counts), this can't be right so we
- return an error here */
- failf(data, "Empty reply from server");
- return CURLE_GOT_NOTHING;
- }
-
- return CURLE_OK;
-}
-
-/* check and possibly add an Expect: header */
-static CURLcode expect100(struct SessionHandle *data,
- send_buffer *req_buffer)
-{
- CURLcode result = CURLE_OK;
- data->state.expect100header = FALSE; /* default to false unless it is set
- to TRUE below */
- if((data->set.httpversion != CURL_HTTP_VERSION_1_0) &&
- !checkheaders(data, "Expect:")) {
- /* if not doing HTTP 1.0 or disabled explicitly, we add a Expect:
- 100-continue to the headers which actually speeds up post
- operations (as there is one packet coming back from the web
- server) */
- result = add_bufferf(req_buffer,
- "Expect: 100-continue\r\n");
- if(result == CURLE_OK)
- data->state.expect100header = TRUE;
- }
- return result;
-}
-
-static CURLcode add_custom_headers(struct connectdata *conn,
- send_buffer *req_buffer)
-{
- CURLcode result = CURLE_OK;
- char *ptr;
- struct curl_slist *headers=conn->data->set.headers;
-
- while(headers) {
- ptr = strchr(headers->data, ':');
- if(ptr) {
- /* we require a colon for this to be a true header */
-
- ptr++; /* pass the colon */
- while(*ptr && ISSPACE(*ptr))
- ptr++;
-
- if(*ptr) {
- /* only send this if the contents was non-blank */
-
- if(conn->allocptr.host &&
- /* a Host: header was sent already, don't pass on any custom Host:
- header as that will produce *two* in the same request! */
- curl_strnequal("Host:", headers->data, 5))
- ;
- else if(conn->data->set.httpreq == HTTPREQ_POST_FORM &&
- /* this header (extended by formdata.c) is sent later */
- curl_strnequal("Content-Type:", headers->data,
- strlen("Content-Type:")))
- ;
- else {
- result = add_bufferf(req_buffer, "%s\r\n", headers->data);
- if(result)
- return result;
- }
- }
- }
- headers = headers->next;
- }
- return result;
-}
-
-/*
- * Curl_http() gets called from the generic Curl_do() function when a HTTP
- * request is to be performed. This creates and sends a properly constructed
- * HTTP request.
- */
-CURLcode Curl_http(struct connectdata *conn, bool *done)
-{
- struct SessionHandle *data=conn->data;
- char *buf = data->state.buffer; /* this is a short cut to the buffer */
- CURLcode result=CURLE_OK;
- struct HTTP *http;
- char *ppath = data->reqdata.path;
- char *host = conn->host.name;
- const char *te = ""; /* transfer-encoding */
- char *ptr;
- char *request;
- Curl_HttpReq httpreq = data->set.httpreq;
- char *addcookies = NULL;
- curl_off_t included_body = 0;
-
- /* Always consider the DO phase done after this function call, even if there
- may be parts of the request that is not yet sent, since we can deal with
- the rest of the request in the PERFORM phase. */
- *done = TRUE;
-
- if(!data->reqdata.proto.http) {
- /* Only allocate this struct if we don't already have it! */
-
- http = (struct HTTP *)malloc(sizeof(struct HTTP));
- if(!http)
- return CURLE_OUT_OF_MEMORY;
- memset(http, 0, sizeof(struct HTTP));
- data->reqdata.proto.http = http;
- }
- else
- http = data->reqdata.proto.http;
-
- /* We default to persistent connections */
- conn->bits.close = FALSE;
-
- if ( (conn->protocol&(PROT_HTTP|PROT_FTP)) &&
- data->set.upload) {
- httpreq = HTTPREQ_PUT;
- }
-
- /* Now set the 'request' pointer to the proper request string */
- if(data->set.customrequest)
- request = data->set.customrequest;
- else {
- if(conn->bits.no_body)
- request = (char *)"HEAD";
- else {
- curlassert((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST));
- switch(httpreq) {
- case HTTPREQ_POST:
- case HTTPREQ_POST_FORM:
- request = (char *)"POST";
- break;
- case HTTPREQ_PUT:
- request = (char *)"PUT";
- break;
- default: /* this should never happen */
- case HTTPREQ_GET:
- request = (char *)"GET";
- break;
- case HTTPREQ_HEAD:
- request = (char *)"HEAD";
- break;
- }
- }
- }
-
- /* The User-Agent string might have been allocated in url.c already, because
- it might have been used in the proxy connect, but if we have got a header
- with the user-agent string specified, we erase the previously made string
- here. */
- if(checkheaders(data, "User-Agent:") && conn->allocptr.uagent) {
- free(conn->allocptr.uagent);
- conn->allocptr.uagent=NULL;
- }
-
- /* setup the authentication headers */
- result = Curl_http_output_auth(conn, request, ppath, FALSE);
- if(result)
- return result;
-
- if((data->state.authhost.multi || data->state.authproxy.multi) &&
- (httpreq != HTTPREQ_GET) &&
- (httpreq != HTTPREQ_HEAD)) {
- /* Auth is required and we are not authenticated yet. Make a PUT or POST
- with content-length zero as a "probe". */
- conn->bits.authneg = TRUE;
- }
- else
- conn->bits.authneg = FALSE;
-
- Curl_safefree(conn->allocptr.ref);
- if(data->change.referer && !checkheaders(data, "Referer:"))
- conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
- else
- conn->allocptr.ref = NULL;
-
- if(data->set.cookie && !checkheaders(data, "Cookie:"))
- addcookies = data->set.cookie;
-
- if(!checkheaders(data, "Accept-Encoding:") &&
- data->set.encoding) {
- Curl_safefree(conn->allocptr.accept_encoding);
- conn->allocptr.accept_encoding =
- aprintf("Accept-Encoding: %s\r\n", data->set.encoding);
- if(!conn->allocptr.accept_encoding)
- return CURLE_OUT_OF_MEMORY;
- }
-
- ptr = checkheaders(data, "Transfer-Encoding:");
- if(ptr) {
- /* Some kind of TE is requested, check if 'chunked' is chosen */
- conn->bits.upload_chunky =
- Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
- }
- else {
- if (httpreq == HTTPREQ_GET)
- conn->bits.upload_chunky = FALSE;
- if(conn->bits.upload_chunky)
- te = "Transfer-Encoding: chunked\r\n";
- }
-
- Curl_safefree(conn->allocptr.host);
-
- ptr = checkheaders(data, "Host:");
- if(ptr && (!data->state.this_is_a_follow ||
- curl_strequal(data->state.first_host, conn->host.name))) {
-#if !defined(CURL_DISABLE_COOKIES)
- /* If we have a given custom Host: header, we extract the host name in
- order to possibly use it for cookie reasons later on. We only allow the
- custom Host: header if this is NOT a redirect, as setting Host: in the
- redirected request is being out on thin ice. Except if the host name
- is the same as the first one! */
- char *start = ptr+strlen("Host:");
- while(*start && ISSPACE(*start ))
- start++;
- ptr = start; /* start host-scanning here */
-
- /* scan through the string to find the end (space or colon) */
- while(*ptr && !ISSPACE(*ptr) && !(':'==*ptr))
- ptr++;
-
- if(ptr != start) {
- size_t len=ptr-start;
- Curl_safefree(conn->allocptr.cookiehost);
- conn->allocptr.cookiehost = malloc(len+1);
- if(!conn->allocptr.cookiehost)
- return CURLE_OUT_OF_MEMORY;
- memcpy(conn->allocptr.cookiehost, start, len);
- conn->allocptr.cookiehost[len]=0;
- }
-#endif
-
- conn->allocptr.host = NULL;
- }
- else {
- /* When building Host: headers, we must put the host name within
- [brackets] if the host name is a plain IPv6-address. RFC2732-style. */
-
- if(((conn->protocol&PROT_HTTPS) && (conn->remote_port == PORT_HTTPS)) ||
- (!(conn->protocol&PROT_HTTPS) && (conn->remote_port == PORT_HTTP)) )
- /* If (HTTPS on port 443) OR (non-HTTPS on port 80) then don't include
- the port number in the host string */
- conn->allocptr.host = aprintf("Host: %s%s%s\r\n",
- conn->bits.ipv6_ip?"[":"",
- host,
- conn->bits.ipv6_ip?"]":"");
- else
- conn->allocptr.host = aprintf("Host: %s%s%s:%d\r\n",
- conn->bits.ipv6_ip?"[":"",
- host,
- conn->bits.ipv6_ip?"]":"",
- conn->remote_port);
-
- if(!conn->allocptr.host)
- /* without Host: we can't make a nice request */
- return CURLE_OUT_OF_MEMORY;
- }
-
- if (conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
- /* Using a proxy but does not tunnel through it */
-
- /* The path sent to the proxy is in fact the entire URL. But if the remote
- host is a IDN-name, we must make sure that the request we produce only
- uses the encoded host name! */
- if(conn->host.dispname != conn->host.name) {
- char *url = data->change.url;
- ptr = strstr(url, conn->host.dispname);
- if(ptr) {
- /* This is where the display name starts in the URL, now replace this
- part with the encoded name. TODO: This method of replacing the host
- name is rather crude as I believe there's a slight risk that the
- user has entered a user name or password that contain the host name
- string. */
- size_t currlen = strlen(conn->host.dispname);
- size_t newlen = strlen(conn->host.name);
- size_t urllen = strlen(url);
-
- char *newurl;
-
- newurl = malloc(urllen + newlen - currlen + 1);
- if(newurl) {
- /* copy the part before the host name */
- memcpy(newurl, url, ptr - url);
- /* append the new host name instead of the old */
- memcpy(newurl + (ptr - url), conn->host.name, newlen);
- /* append the piece after the host name */
- memcpy(newurl + newlen + (ptr - url),
- ptr + currlen, /* copy the trailing zero byte too */
- urllen - (ptr-url) - currlen + 1);
- if(data->change.url_alloc)
- free(data->change.url);
- data->change.url = newurl;
- data->change.url_alloc = TRUE;
- }
- else
- return CURLE_OUT_OF_MEMORY;
- }
- }
- ppath = data->change.url;
- }
- if(HTTPREQ_POST_FORM == httpreq) {
- /* we must build the whole darned post sequence first, so that we have
- a size of the whole shebang before we start to send it */
- result = Curl_getFormData(&http->sendit, data->set.httppost,
- checkheaders(data, "Content-Type:"),
- &http->postsize);
- if(CURLE_OK != result) {
- /* Curl_getFormData() doesn't use failf() */
- failf(data, "failed creating formpost data");
- return result;
- }
- }
-
-
- http->p_pragma =
- (!checkheaders(data, "Pragma:") &&
- (conn->bits.httpproxy && !conn->bits.tunnel_proxy) )?
- "Pragma: no-cache\r\n":NULL;
-
- if(!checkheaders(data, "Accept:"))
- http->p_accept = "Accept: */*\r\n";
-
- if(( (HTTPREQ_POST == httpreq) ||
- (HTTPREQ_POST_FORM == httpreq) ||
- (HTTPREQ_PUT == httpreq) ) &&
- data->reqdata.resume_from) {
- /**********************************************************************
- * Resuming upload in HTTP means that we PUT or POST and that we have
- * got a resume_from value set. The resume value has already created
- * a Range: header that will be passed along. We need to "fast forward"
- * the file the given number of bytes and decrease the assume upload
- * file size before we continue this venture in the dark lands of HTTP.
- *********************************************************************/
-
- if(data->reqdata.resume_from < 0 ) {
- /*
- * This is meant to get the size of the present remote-file by itself.
- * We don't support this now. Bail out!
- */
- data->reqdata.resume_from = 0;
- }
-
- if(data->reqdata.resume_from) {
- /* do we still game? */
- curl_off_t passed=0;
-
- /* Now, let's read off the proper amount of bytes from the
- input. If we knew it was a proper file we could've just
- fseek()ed but we only have a stream here */
- do {
- size_t readthisamountnow = (size_t)(data->reqdata.resume_from - passed);
- size_t actuallyread;
-
- if(readthisamountnow > BUFSIZE)
- readthisamountnow = BUFSIZE;
-
- actuallyread =
- data->set.fread(data->state.buffer, 1, (size_t)readthisamountnow,
- data->set.in);
-
- passed += actuallyread;
- if(actuallyread != readthisamountnow) {
- failf(data, "Could only read %" FORMAT_OFF_T
- " bytes from the input",
- passed);
- return CURLE_READ_ERROR;
- }
- } while(passed != data->reqdata.resume_from); /* loop until done */
-
- /* now, decrease the size of the read */
- if(data->set.infilesize>0) {
- data->set.infilesize -= data->reqdata.resume_from;
-
- if(data->set.infilesize <= 0) {
- failf(data, "File already completely uploaded");
- return CURLE_PARTIAL_FILE;
- }
- }
- /* we've passed, proceed as normal */
- }
- }
- if(data->reqdata.use_range) {
- /*
- * A range is selected. We use different headers whether we're downloading
- * or uploading and we always let customized headers override our internal
- * ones if any such are specified.
- */
- if((httpreq == HTTPREQ_GET) &&
- !checkheaders(data, "Range:")) {
- /* if a line like this was already allocated, free the previous one */
- if(conn->allocptr.rangeline)
- free(conn->allocptr.rangeline);
- conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n", data->reqdata.range);
- }
- else if((httpreq != HTTPREQ_GET) &&
- !checkheaders(data, "Content-Range:")) {
-
- if(data->reqdata.resume_from) {
- /* This is because "resume" was selected */
- curl_off_t total_expected_size=
- data->reqdata.resume_from + data->set.infilesize;
- conn->allocptr.rangeline =
- aprintf("Content-Range: bytes %s%" FORMAT_OFF_T
- "/%" FORMAT_OFF_T "\r\n",
- data->reqdata.range, total_expected_size-1,
- total_expected_size);
- }
- else {
- /* Range was selected and then we just pass the incoming range and
- append total size */
- conn->allocptr.rangeline =
- aprintf("Content-Range: bytes %s/%" FORMAT_OFF_T "\r\n",
- data->reqdata.range, data->set.infilesize);
- }
- }
- }
-
- {
- /* Use 1.1 unless the use specificly asked for 1.0 */
- const char *httpstring=
- data->set.httpversion==CURL_HTTP_VERSION_1_0?"1.0":"1.1";
-
- send_buffer *req_buffer;
- curl_off_t postsize; /* off_t type to be able to hold a large file size */
-
- /* initialize a dynamic send-buffer */
- req_buffer = add_buffer_init();
-
- if(!req_buffer)
- return CURLE_OUT_OF_MEMORY;
-
- /* add the main request stuff */
- result =
- add_bufferf(req_buffer,
- "%s " /* GET/HEAD/POST/PUT */
- "%s HTTP/%s\r\n" /* path + HTTP version */
- "%s" /* proxyuserpwd */
- "%s" /* userpwd */
- "%s" /* range */
- "%s" /* user agent */
- "%s" /* host */
- "%s" /* pragma */
- "%s" /* accept */
- "%s" /* accept-encoding */
- "%s" /* referer */
- "%s" /* Proxy-Connection */
- "%s",/* transfer-encoding */
-
- request,
- ppath,
- httpstring,
- conn->allocptr.proxyuserpwd?
- conn->allocptr.proxyuserpwd:"",
- conn->allocptr.userpwd?conn->allocptr.userpwd:"",
- (data->reqdata.use_range && conn->allocptr.rangeline)?
- conn->allocptr.rangeline:"",
- (data->set.useragent && *data->set.useragent && conn->allocptr.uagent)?
- conn->allocptr.uagent:"",
- (conn->allocptr.host?conn->allocptr.host:""), /* Host: host */
- http->p_pragma?http->p_pragma:"",
- http->p_accept?http->p_accept:"",
- (data->set.encoding && *data->set.encoding && conn->allocptr.accept_encoding)?
- conn->allocptr.accept_encoding:"",
- (data->change.referer && conn->allocptr.ref)?conn->allocptr.ref:"" /* Referer: <data> */,
- (conn->bits.httpproxy &&
- !conn->bits.tunnel_proxy &&
- !checkheaders(data, "Proxy-Connection:"))?
- "Proxy-Connection: Keep-Alive\r\n":"",
- te
- );
-
- if(result)
- return result;
-
-#if !defined(CURL_DISABLE_COOKIES)
- if(data->cookies || addcookies) {
- struct Cookie *co=NULL; /* no cookies from start */
- int count=0;
-
- if(data->cookies) {
- Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
- co = Curl_cookie_getlist(data->cookies,
- conn->allocptr.cookiehost?
- conn->allocptr.cookiehost:host, data->reqdata.path,
- (bool)(conn->protocol&PROT_HTTPS?TRUE:FALSE));
- Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
- }
- if(co) {
- struct Cookie *store=co;
- /* now loop through all cookies that matched */
- while(co) {
- if(co->value) {
- if(0 == count) {
- result = add_bufferf(req_buffer, "Cookie: ");
- if(result)
- break;
- }
- result = add_bufferf(req_buffer,
- "%s%s=%s", count?"; ":"",
- co->name, co->value);
- if(result)
- break;
- count++;
- }
- co = co->next; /* next cookie please */
- }
- Curl_cookie_freelist(store); /* free the cookie list */
- }
- if(addcookies && (CURLE_OK == result)) {
- if(!count)
- result = add_bufferf(req_buffer, "Cookie: ");
- if(CURLE_OK == result) {
- result = add_bufferf(req_buffer, "%s%s",
- count?"; ":"",
- addcookies);
- count++;
- }
- }
- if(count && (CURLE_OK == result))
- result = add_buffer(req_buffer, "\r\n", 2);
-
- if(result)
- return result;
- }
-#endif
-
- if(data->set.timecondition) {
- struct tm *tm;
-
- /* Phil Karn (Fri, 13 Apr 2001) pointed out that the If-Modified-Since
- * header family should have their times set in GMT as RFC2616 defines:
- * "All HTTP date/time stamps MUST be represented in Greenwich Mean Time
- * (GMT), without exception. For the purposes of HTTP, GMT is exactly
- * equal to UTC (Coordinated Universal Time)." (see page 20 of RFC2616).
- */
-
-#ifdef HAVE_GMTIME_R
- /* thread-safe version */
- struct tm keeptime;
- tm = (struct tm *)gmtime_r(&data->set.timevalue, &keeptime);
-#else
- tm = gmtime(&data->set.timevalue);
-#endif
-
- /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
- snprintf(buf, BUFSIZE-1,
- "%s, %02d %s %4d %02d:%02d:%02d GMT",
- Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
- tm->tm_mday,
- Curl_month[tm->tm_mon],
- tm->tm_year + 1900,
- tm->tm_hour,
- tm->tm_min,
- tm->tm_sec);
-
- switch(data->set.timecondition) {
- case CURL_TIMECOND_IFMODSINCE:
- default:
- result = add_bufferf(req_buffer,
- "If-Modified-Since: %s\r\n", buf);
- break;
- case CURL_TIMECOND_IFUNMODSINCE:
- result = add_bufferf(req_buffer,
- "If-Unmodified-Since: %s\r\n", buf);
- break;
- case CURL_TIMECOND_LASTMOD:
- result = add_bufferf(req_buffer,
- "Last-Modified: %s\r\n", buf);
- break;
- }
- if(result)
- return result;
- }
-
- result = add_custom_headers(conn, req_buffer);
- if(result)
- return result;
-
- http->postdata = NULL; /* nothing to post at this point */
- Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */
-
- /* If 'authdone' is FALSE, we must not set the write socket index to the
- Curl_transfer() call below, as we're not ready to actually upload any
- data yet. */
-
- switch(httpreq) {
-
- case HTTPREQ_POST_FORM:
- if(!http->sendit || conn->bits.authneg) {
- /* nothing to post! */
- result = add_bufferf(req_buffer, "Content-Length: 0\r\n\r\n");
- if(result)
- return result;
-
- result = add_buffer_send(req_buffer, conn,
- &data->info.request_size, 0, FIRSTSOCKET);
- if(result)
- failf(data, "Failed sending POST request");
- else
- /* setup variables for the upcoming transfer */
- result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
- &http->readbytecount,
- -1, NULL);
- break;
- }
-
- if(Curl_FormInit(&http->form, http->sendit)) {
- failf(data, "Internal HTTP POST error!");
- return CURLE_HTTP_POST_ERROR;
- }
-
- /* set the read function to read from the generated form data */
- conn->fread = (curl_read_callback)Curl_FormReader;
- conn->fread_in = &http->form;
-
- http->sending = HTTPSEND_BODY;
-
- if(!conn->bits.upload_chunky) {
- /* only add Content-Length if not uploading chunked */
- result = add_bufferf(req_buffer,
- "Content-Length: %" FORMAT_OFF_T "\r\n",
- http->postsize);
- if(result)
- return result;
- }
-
- result = expect100(data, req_buffer);
- if(result)
- return result;
-
- {
-
- /* Get Content-Type: line from Curl_formpostheader.
- */
- char *contentType;
- size_t linelength=0;
- contentType = Curl_formpostheader((void *)&http->form,
- &linelength);
- if(!contentType) {
- failf(data, "Could not get Content-Type header line!");
- return CURLE_HTTP_POST_ERROR;
- }
-
- result = add_buffer(req_buffer, contentType, linelength);
- if(result)
- return result;
- }
-
- /* make the request end in a true CRLF */
- result = add_buffer(req_buffer, "\r\n", 2);
- if(result)
- return result;
-
- /* set upload size to the progress meter */
- Curl_pgrsSetUploadSize(data, http->postsize);
-
- /* fire away the whole request to the server */
- result = add_buffer_send(req_buffer, conn,
- &data->info.request_size, 0, FIRSTSOCKET);
- if(result)
- failf(data, "Failed sending POST request");
- else
- /* setup variables for the upcoming transfer */
- result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
- &http->readbytecount,
- FIRSTSOCKET,
- &http->writebytecount);
-
- if(result) {
- Curl_formclean(&http->sendit); /* free that whole lot */
- return result;
- }
-#ifdef CURL_DOES_CONVERSIONS
-/* time to convert the form data... */
- result = Curl_formconvert(data, http->sendit);
- if(result) {
- Curl_formclean(&http->sendit); /* free that whole lot */
- return result;
- }
-#endif /* CURL_DOES_CONVERSIONS */
- break;
-
- case HTTPREQ_PUT: /* Let's PUT the data to the server! */
-
- if(conn->bits.authneg)
- postsize = 0;
- else
- postsize = data->set.infilesize;
-
- if((postsize != -1) && !conn->bits.upload_chunky) {
- /* only add Content-Length if not uploading chunked */
- result = add_bufferf(req_buffer,
- "Content-Length: %" FORMAT_OFF_T "\r\n",
- postsize );
- if(result)
- return result;
- }
-
- result = expect100(data, req_buffer);
- if(result)
- return result;
-
- result = add_buffer(req_buffer, "\r\n", 2); /* end of headers */
- if(result)
- return result;
-
- /* set the upload size to the progress meter */
- Curl_pgrsSetUploadSize(data, postsize);
-
- /* this sends the buffer and frees all the buffer resources */
- result = add_buffer_send(req_buffer, conn,
- &data->info.request_size, 0, FIRSTSOCKET);
- if(result)
- failf(data, "Failed sending PUT request");
- else
- /* prepare for transfer */
- result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
- &http->readbytecount,
- postsize?FIRSTSOCKET:-1,
- postsize?&http->writebytecount:NULL);
- if(result)
- return result;
- break;
-
- case HTTPREQ_POST:
- /* this is the simple POST, using x-www-form-urlencoded style */
-
- if(conn->bits.authneg)
- postsize = 0;
- else
- /* figure out the size of the postfields */
- postsize = (data->set.postfieldsize != -1)?
- data->set.postfieldsize:
- (data->set.postfields?(curl_off_t)strlen(data->set.postfields):0);
-
- if(!conn->bits.upload_chunky) {
- /* We only set Content-Length and allow a custom Content-Length if
- we don't upload data chunked, as RFC2616 forbids us to set both
- kinds of headers (Transfer-Encoding: chunked and Content-Length) */
-
- if(!checkheaders(data, "Content-Length:")) {
- /* we allow replacing this header, although it isn't very wise to
- actually set your own */
- result = add_bufferf(req_buffer,
- "Content-Length: %" FORMAT_OFF_T"\r\n",
- postsize);
- if(result)
- return result;
- }
- }
-
- if(!checkheaders(data, "Content-Type:")) {
- result = add_bufferf(req_buffer,
- "Content-Type: application/x-www-form-urlencoded\r\n");
- if(result)
- return result;
- }
-
- if(data->set.postfields) {
-
- /* for really small posts we don't use Expect: headers at all, and for
- the somewhat bigger ones we allow the app to disable it */
- if(postsize > TINY_INITIAL_POST_SIZE) {
- result = expect100(data, req_buffer);
- if(result)
- return result;
- }
- else
- data->state.expect100header = FALSE;
-
- if(!data->state.expect100header &&
- (postsize < MAX_INITIAL_POST_SIZE)) {
- /* if we don't use expect:-100 AND
- postsize is less than MAX_INITIAL_POST_SIZE
-
- then append the post data to the HTTP request header. This limit
- is no magic limit but only set to prevent really huge POSTs to
- get the data duplicated with malloc() and family. */
-
- result = add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
- if(result)
- return result;
-
- if(!conn->bits.upload_chunky) {
- /* We're not sending it 'chunked', append it to the request
- already now to reduce the number if send() calls */
- result = add_buffer(req_buffer, data->set.postfields,
- (size_t)postsize);
- included_body = postsize;
- }
- else {
- /* Append the POST data chunky-style */
- result = add_bufferf(req_buffer, "%x\r\n", (int)postsize);
- if(CURLE_OK == result)
- result = add_buffer(req_buffer, data->set.postfields,
- (size_t)postsize);
- if(CURLE_OK == result)
- result = add_buffer(req_buffer,
- "\x0d\x0a\x30\x0d\x0a\x0d\x0a", 7);
- /* CR LF 0 CR LF CR LF */
- included_body = postsize + 7;
- }
- if(result)
- return result;
- }
- else {
- /* A huge POST coming up, do data separate from the request */
- http->postsize = postsize;
- http->postdata = data->set.postfields;
-
- http->sending = HTTPSEND_BODY;
-
- conn->fread = (curl_read_callback)readmoredata;
- conn->fread_in = (void *)conn;
-
- /* set the upload size to the progress meter */
- Curl_pgrsSetUploadSize(data, http->postsize);
-
- add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
- }
- }
- else {
- add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
-
- if(data->set.postfieldsize) {
- /* set the upload size to the progress meter */
- Curl_pgrsSetUploadSize(data, postsize?postsize:-1);
-
- /* set the pointer to mark that we will send the post body using
- the read callback */
- http->postdata = (char *)&http->postdata;
- }
- }
- /* issue the request */
- result = add_buffer_send(req_buffer, conn, &data->info.request_size,
- (size_t)included_body, FIRSTSOCKET);
-
- if(result)
- failf(data, "Failed sending HTTP POST request");
- else
- result =
- Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
- &http->readbytecount,
- http->postdata?FIRSTSOCKET:-1,
- http->postdata?&http->writebytecount:NULL);
- break;
-
- default:
- add_buffer(req_buffer, "\r\n", 2);
-
- /* issue the request */
- result = add_buffer_send(req_buffer, conn,
- &data->info.request_size, 0, FIRSTSOCKET);
-
- if(result)
- failf(data, "Failed sending HTTP request");
- else
- /* HTTP GET/HEAD download: */
- result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
- &http->readbytecount,
- http->postdata?FIRSTSOCKET:-1,
- http->postdata?&http->writebytecount:NULL);
- }
- if(result)
- return result;
- }
-
- return CURLE_OK;
-}
-#endif
diff --git a/Utilities/cmcurl/http.h b/Utilities/cmcurl/http.h
deleted file mode 100644
index 0f4b58f72..000000000
--- a/Utilities/cmcurl/http.h
+++ /dev/null
@@ -1,85 +0,0 @@
-#ifndef __HTTP_H
-#define __HTTP_H
-
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-#ifndef CURL_DISABLE_HTTP
-bool Curl_compareheader(char *headerline, /* line to check */
- const char *header, /* header keyword _with_ colon */
- const char *content); /* content string to find */
-
-/* ftp can use this as well */
-CURLcode Curl_proxyCONNECT(struct connectdata *conn,
- int tunnelsocket,
- char *hostname, int remote_port);
-
-/* protocol-specific functions set up to be called by the main engine */
-CURLcode Curl_http(struct connectdata *conn, bool *done);
-CURLcode Curl_http_done(struct connectdata *, CURLcode, bool premature);
-CURLcode Curl_http_connect(struct connectdata *conn, bool *done);
-CURLcode Curl_https_connecting(struct connectdata *conn, bool *done);
-int Curl_https_getsock(struct connectdata *conn,
- curl_socket_t *socks,
- int numsocks);
-
-/* The following functions are defined in http_chunks.c */
-void Curl_httpchunk_init(struct connectdata *conn);
-CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap,
- ssize_t length, ssize_t *wrote);
-
-/* These functions are in http.c */
-void Curl_http_auth_stage(struct SessionHandle *data, int stage);
-CURLcode Curl_http_input_auth(struct connectdata *conn,
- int httpcode, char *header);
-CURLcode Curl_http_auth_act(struct connectdata *conn);
-
-int Curl_http_should_fail(struct connectdata *conn);
-
-/* If only the PICKNONE bit is set, there has been a round-trip and we
- selected to use no auth at all. Ie, we actively select no auth, as opposed
- to not having one selected. The other CURLAUTH_* defines are present in the
- public curl/curl.h header. */
-#define CURLAUTH_PICKNONE (1<<30) /* don't use auth */
-
-/* MAX_INITIAL_POST_SIZE indicates the number of bytes that will make the POST
- data get included in the initial data chunk sent to the server. If the
- data is larger than this, it will automatically get split up in multiple
- system calls.
-
- This value used to be fairly big (100K), but we must take into account that
- if the server rejects the POST due for authentication reasons, this data
- will always be uncondtionally sent and thus it may not be larger than can
- always be afforded to send twice.
-
- It must not be greater than 64K to work on VMS.
-*/
-#ifndef MAX_INITIAL_POST_SIZE
-#define MAX_INITIAL_POST_SIZE (64*1024)
-#endif
-
-#ifndef TINY_INITIAL_POST_SIZE
-#define TINY_INITIAL_POST_SIZE 1024
-#endif
-
-#endif
-#endif
diff --git a/Utilities/cmcurl/http_chunks.c b/Utilities/cmcurl/http_chunks.c
deleted file mode 100644
index 1b03a5569..000000000
--- a/Utilities/cmcurl/http_chunks.c
+++ /dev/null
@@ -1,360 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-#include "setup.h"
-
-#ifndef CURL_DISABLE_HTTP
-/* -- WIN32 approved -- */
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <ctype.h>
-
-#include "urldata.h" /* it includes http_chunks.h */
-#include "sendf.h" /* for the client write stuff */
-
-#include "content_encoding.h"
-#include "http.h"
-#include "memory.h"
-#include "easyif.h" /* for Curl_convert_to_network prototype */
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
-#include "memdebug.h"
-
-/*
- * Chunk format (simplified):
- *
- * <HEX SIZE>[ chunk extension ] CRLF
- * <DATA> CRLF
- *
- * Highlights from RFC2616 section 3.6 say:
-
- The chunked encoding modifies the body of a message in order to
- transfer it as a series of chunks, each with its own size indicator,
- followed by an OPTIONAL trailer containing entity-header fields. This
- allows dynamically produced content to be transferred along with the
- information necessary for the recipient to verify that it has
- received the full message.
-
- Chunked-Body = *chunk
- last-chunk
- trailer
- CRLF
-
- chunk = chunk-size [ chunk-extension ] CRLF
- chunk-data CRLF
- chunk-size = 1*HEX
- last-chunk = 1*("0") [ chunk-extension ] CRLF
-
- chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
- chunk-ext-name = token
- chunk-ext-val = token | quoted-string
- chunk-data = chunk-size(OCTET)
- trailer = *(entity-header CRLF)
-
- The chunk-size field is a string of hex digits indicating the size of
- the chunk. The chunked encoding is ended by any chunk whose size is
- zero, followed by the trailer, which is terminated by an empty line.
-
- */
-
-
-void Curl_httpchunk_init(struct connectdata *conn)
-{
- struct Curl_chunker *chunk = &conn->data->reqdata.proto.http->chunk;
- chunk->hexindex=0; /* start at 0 */
- chunk->dataleft=0; /* no data left yet! */
- chunk->state = CHUNK_HEX; /* we get hex first! */
-}
-
-/*
- * chunk_read() returns a OK for normal operations, or a positive return code
- * for errors. STOP means this sequence of chunks is complete. The 'wrote'
- * argument is set to tell the caller how many bytes we actually passed to the
- * client (for byte-counting and whatever).
- *
- * The states and the state-machine is further explained in the header file.
- *
- * This function always uses ASCII hex values to accommodate non-ASCII hosts.
- * For example, 0x0d and 0x0a are used instead of '\r' and '\n'.
- */
-CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
- char *datap,
- ssize_t datalen,
- ssize_t *wrotep)
-{
- CURLcode result=CURLE_OK;
- struct SessionHandle *data = conn->data;
- struct Curl_chunker *ch = &data->reqdata.proto.http->chunk;
- struct Curl_transfer_keeper *k = &data->reqdata.keep;
- size_t piece;
- size_t length = (size_t)datalen;
- size_t *wrote = (size_t *)wrotep;
-
- *wrote = 0; /* nothing's written yet */
-
- while(length) {
- switch(ch->state) {
- case CHUNK_HEX:
- /* Check for an ASCII hex digit.
- We avoid the use of isxdigit to accommodate non-ASCII hosts. */
- if((*datap >= 0x30 && *datap <= 0x39) /* 0-9 */
- || (*datap >= 0x41 && *datap <= 0x46) /* A-F */
- || (*datap >= 0x61 && *datap <= 0x66)) { /* a-f */
- if(ch->hexindex < MAXNUM_SIZE) {
- ch->hexbuffer[ch->hexindex] = *datap;
- datap++;
- length--;
- ch->hexindex++;
- }
- else {
- return CHUNKE_TOO_LONG_HEX; /* longer hex than we support */
- }
- }
- else {
- if(0 == ch->hexindex) {
- /* This is illegal data, we received junk where we expected
- a hexadecimal digit. */
- return CHUNKE_ILLEGAL_HEX;
- }
- /* length and datap are unmodified */
- ch->hexbuffer[ch->hexindex]=0;
-#ifdef CURL_DOES_CONVERSIONS
- /* convert to host encoding before calling strtoul */
- result = Curl_convert_from_network(conn->data,
- ch->hexbuffer,
- ch->hexindex);
- if(result != CURLE_OK) {
- /* Curl_convert_from_network calls failf if unsuccessful */
- /* Treat it as a bad hex character */
- return(CHUNKE_ILLEGAL_HEX);
- }
-#endif /* CURL_DOES_CONVERSIONS */
- ch->datasize=strtoul(ch->hexbuffer, NULL, 16);
- ch->state = CHUNK_POSTHEX;
- }
- break;
-
- case CHUNK_POSTHEX:
- /* In this state, we're waiting for CRLF to arrive. We support
- this to allow so called chunk-extensions to show up here
- before the CRLF comes. */
- if(*datap == 0x0d)
- ch->state = CHUNK_CR;
- length--;
- datap++;
- break;
-
- case CHUNK_CR:
- /* waiting for the LF */
- if(*datap == 0x0a) {
- /* we're now expecting data to come, unless size was zero! */
- if(0 == ch->datasize) {
- if (conn->bits.trailerHdrPresent!=TRUE) {
- /* No Trailer: header found - revert to original Curl processing */
- ch->state = CHUNK_STOP;
- if (1 == length) {
- /* This is the final byte, return right now */
- return CHUNKE_STOP;
- }
- }
- else {
- ch->state = CHUNK_TRAILER; /* attempt to read trailers */
- conn->trlPos=0;
- }
- }
- else
- ch->state = CHUNK_DATA;
- }
- else
- /* previously we got a fake CR, go back to CR waiting! */
- ch->state = CHUNK_CR;
- datap++;
- length--;
- break;
-
- case CHUNK_DATA:
- /* we get pure and fine data
-
- We expect another 'datasize' of data. We have 'length' right now,
- it can be more or less than 'datasize'. Get the smallest piece.
- */
- piece = (ch->datasize >= length)?length:ch->datasize;
-
- /* Write the data portion available */
-#ifdef HAVE_LIBZ
- switch (data->reqdata.keep.content_encoding) {
- case IDENTITY:
-#endif
- if(!k->ignorebody)
- result = Curl_client_write(conn, CLIENTWRITE_BODY, datap,
- piece);
-#ifdef HAVE_LIBZ
- break;
-
- case DEFLATE:
- /* update data->reqdata.keep.str to point to the chunk data. */
- data->reqdata.keep.str = datap;
- result = Curl_unencode_deflate_write(conn, &data->reqdata.keep,
- (ssize_t)piece);
- break;
-
- case GZIP:
- /* update data->reqdata.keep.str to point to the chunk data. */
- data->reqdata.keep.str = datap;
- result = Curl_unencode_gzip_write(conn, &data->reqdata.keep,
- (ssize_t)piece);
- break;
-
- case COMPRESS:
- default:
- failf (conn->data,
- "Unrecognized content encoding type. "
- "libcurl understands `identity', `deflate' and `gzip' "
- "content encodings.");
- return CHUNKE_BAD_ENCODING;
- }
-#endif
-
- if(result)
- return CHUNKE_WRITE_ERROR;
-
- *wrote += piece;
-
- ch->datasize -= piece; /* decrease amount left to expect */
- datap += piece; /* move read pointer forward */
- length -= piece; /* decrease space left in this round */
-
- if(0 == ch->datasize)
- /* end of data this round, we now expect a trailing CRLF */
- ch->state = CHUNK_POSTCR;
- break;
-
- case CHUNK_POSTCR:
- if(*datap == 0x0d) {
- ch->state = CHUNK_POSTLF;
- datap++;
- length--;
- }
- else
- return CHUNKE_BAD_CHUNK;
- break;
-
- case CHUNK_POSTLF:
- if(*datap == 0x0a) {
- /*
- * The last one before we go back to hex state and start all
- * over.
- */
- Curl_httpchunk_init(conn);
- datap++;
- length--;
- }
- else
- return CHUNKE_BAD_CHUNK;
- break;
-
- case CHUNK_TRAILER:
- /* conn->trailer is assumed to be freed in url.c on a
- connection basis */
- if (conn->trlPos >= conn->trlMax) {
- char *ptr;
- if(conn->trlMax) {
- conn->trlMax *= 2;
- ptr = (char*)realloc(conn->trailer,conn->trlMax);
- }
- else {
- conn->trlMax=128;
- ptr = (char*)malloc(conn->trlMax);
- }
- if(!ptr)
- return CHUNKE_OUT_OF_MEMORY;
- conn->trailer = ptr;
- }
- conn->trailer[conn->trlPos++]=*datap;
-
- if(*datap == 0x0d)
- ch->state = CHUNK_TRAILER_CR;
- else {
- datap++;
- length--;
- }
- break;
-
- case CHUNK_TRAILER_CR:
- if(*datap == 0x0d) {
- ch->state = CHUNK_TRAILER_POSTCR;
- datap++;
- length--;
- }
- else
- return CHUNKE_BAD_CHUNK;
- break;
-
- case CHUNK_TRAILER_POSTCR:
- if (*datap == 0x0a) {
- conn->trailer[conn->trlPos++]=0x0a;
- conn->trailer[conn->trlPos]=0;
- if (conn->trlPos==2) {
- ch->state = CHUNK_STOP;
- return CHUNKE_STOP;
- }
- else {
-#ifdef CURL_DOES_CONVERSIONS
- /* Convert to host encoding before calling Curl_client_write */
- result = Curl_convert_from_network(conn->data,
- conn->trailer,
- conn->trlPos);
- if(result != CURLE_OK) {
- /* Curl_convert_from_network calls failf if unsuccessful */
- /* Treat it as a bad chunk */
- return(CHUNKE_BAD_CHUNK);
- }
-#endif /* CURL_DOES_CONVERSIONS */
- Curl_client_write(conn, CLIENTWRITE_HEADER,
- conn->trailer, conn->trlPos);
- }
- ch->state = CHUNK_TRAILER;
- conn->trlPos=0;
- datap++;
- length--;
- }
- else
- return CHUNKE_BAD_CHUNK;
- break;
-
- case CHUNK_STOP:
- /* If we arrive here, there is data left in the end of the buffer
- even if there's no more chunks to read */
- ch->dataleft = length;
- return CHUNKE_STOP; /* return stop */
- default:
- return CHUNKE_STATE_ERROR;
- }
- }
- return CHUNKE_OK;
-}
-#endif /* CURL_DISABLE_HTTP */
diff --git a/Utilities/cmcurl/http_chunks.h b/Utilities/cmcurl/http_chunks.h
deleted file mode 100644
index 211818ab7..000000000
--- a/Utilities/cmcurl/http_chunks.h
+++ /dev/null
@@ -1,104 +0,0 @@
-#ifndef __HTTP_CHUNKS_H
-#define __HTTP_CHUNKS_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-/*
- * The longest possible hexadecimal number we support in a chunked transfer.
- * Weird enough, RFC2616 doesn't set a maximum size! Since we use strtoul()
- * to convert it, we "only" support 2^32 bytes chunk data.
- */
-#define MAXNUM_SIZE 16
-
-typedef enum {
- CHUNK_FIRST, /* never use */
-
- /* In this we await and buffer all hexadecimal digits until we get one
- that isn't a hexadecimal digit. When done, we go POSTHEX */
- CHUNK_HEX,
-
- /* We have received the hexadecimal digit and we eat all characters until
- we get a CRLF pair. When we see a CR we go to the CR state. */
- CHUNK_POSTHEX,
-
- /* A single CR has been found and we should get a LF right away in this
- state or we go back to POSTHEX. When LF is received, we go to DATA.
- If the size given was zero, we set state to STOP and return. */
- CHUNK_CR,
-
- /* We eat the amount of data specified. When done, we move on to the
- POST_CR state. */
- CHUNK_DATA,
-
- /* POSTCR should get a CR and nothing else, then move to POSTLF */
- CHUNK_POSTCR,
-
- /* POSTLF should get a LF and nothing else, then move back to HEX as the
- CRLF combination marks the end of a chunk */
- CHUNK_POSTLF,
-
- /* This is mainly used to really mark that we're out of the game.
- NOTE: that there's a 'dataleft' field in the struct that will tell how
- many bytes that were not passed to the client in the end of the last
- buffer! */
- CHUNK_STOP,
-
- /* At this point optional trailer headers can be found, unless the next line
- is CRLF */
- CHUNK_TRAILER,
-
- /* A trailer CR has been found - next state is CHUNK_TRAILER_POSTCR.
- Next char must be a LF */
- CHUNK_TRAILER_CR,
-
- /* A trailer LF must be found now, otherwise CHUNKE_BAD_CHUNK will be
- signalled If this is an empty trailer CHUNKE_STOP will be signalled.
- Otherwise the trailer will be broadcasted via Curl_client_write() and the
- next state will be CHUNK_TRAILER */
- CHUNK_TRAILER_POSTCR,
-
- CHUNK_LAST /* never use */
-
-} ChunkyState;
-
-typedef enum {
- CHUNKE_STOP = -1,
- CHUNKE_OK = 0,
- CHUNKE_TOO_LONG_HEX = 1,
- CHUNKE_ILLEGAL_HEX,
- CHUNKE_BAD_CHUNK,
- CHUNKE_WRITE_ERROR,
- CHUNKE_STATE_ERROR,
- CHUNKE_BAD_ENCODING,
- CHUNKE_OUT_OF_MEMORY,
- CHUNKE_LAST
-} CHUNKcode;
-
-struct Curl_chunker {
- char hexbuffer[ MAXNUM_SIZE + 1];
- int hexindex;
- ChunkyState state;
- size_t datasize;
- size_t dataleft; /* untouched data amount at the end of the last buffer */
-};
-
-#endif
diff --git a/Utilities/cmcurl/http_digest.c b/Utilities/cmcurl/http_digest.c
deleted file mode 100644
index c223784f9..000000000
--- a/Utilities/cmcurl/http_digest.c
+++ /dev/null
@@ -1,504 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-#include "setup.h"
-
-#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
-/* -- WIN32 approved -- */
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <ctype.h>
-
-#include "urldata.h"
-#include "sendf.h"
-#include "strequal.h"
-#include "base64.h"
-#include "md5.h"
-#include "http_digest.h"
-#include "strtok.h"
-#include "url.h" /* for Curl_safefree() */
-#include "memory.h"
-#include "easyif.h" /* included for Curl_convert_... prototypes */
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
-#include "memdebug.h"
-
-/* Test example headers:
-
-WWW-Authenticate: Digest realm="testrealm", nonce="1053604598"
-Proxy-Authenticate: Digest realm="testrealm", nonce="1053604598"
-
-*/
-
-CURLdigest Curl_input_digest(struct connectdata *conn,
- bool proxy,
- char *header) /* rest of the *-authenticate:
- header */
-{
- bool more = TRUE;
- char *token = NULL;
- char *tmp = NULL;
- bool foundAuth = FALSE;
- bool foundAuthInt = FALSE;
- struct SessionHandle *data=conn->data;
- bool before = FALSE; /* got a nonce before */
- struct digestdata *d;
-
- if(proxy) {
- d = &data->state.proxydigest;
- }
- else {
- d = &data->state.digest;
- }
-
- /* skip initial whitespaces */
- while(*header && ISSPACE(*header))
- header++;
-
- if(checkprefix("Digest", header)) {
- header += strlen("Digest");
-
- /* If we already have received a nonce, keep that in mind */
- if(d->nonce)
- before = TRUE;
-
- /* clear off any former leftovers and init to defaults */
- Curl_digest_cleanup_one(d);
-
- while(more) {
- char value[32];
- char content[128];
- size_t totlen=0;
-
- while(*header && ISSPACE(*header))
- header++;
-
- /* how big can these strings be? */
- if((2 == sscanf(header, "%31[^=]=\"%127[^\"]\"",
- value, content)) ||
- /* try the same scan but without quotes around the content but don't
- include the possibly trailing comma */
- (2 == sscanf(header, "%31[^=]=%127[^,]",
- value, content)) ) {
- if(strequal(value, "nonce")) {
- d->nonce = strdup(content);
- if(!d->nonce)
- return CURLDIGEST_NOMEM;
- }
- else if(strequal(value, "stale")) {
- if(strequal(content, "true")) {
- d->stale = TRUE;
- d->nc = 1; /* we make a new nonce now */
- }
- }
- else if(strequal(value, "realm")) {
- d->realm = strdup(content);
- if(!d->realm)
- return CURLDIGEST_NOMEM;
- }
- else if(strequal(value, "opaque")) {
- d->opaque = strdup(content);
- if(!d->opaque)
- return CURLDIGEST_NOMEM;
- }
- else if(strequal(value, "qop")) {
- char *tok_buf;
- /* tokenize the list and choose auth if possible, use a temporary
- clone of the buffer since strtok_r() ruins it */
- tmp = strdup(content);
- if(!tmp)
- return CURLDIGEST_NOMEM;
- token = strtok_r(tmp, ",", &tok_buf);
- while (token != NULL) {
- if (strequal(token, "auth")) {
- foundAuth = TRUE;
- }
- else if (strequal(token, "auth-int")) {
- foundAuthInt = TRUE;
- }
- token = strtok_r(NULL, ",", &tok_buf);
- }
- free(tmp);
- /*select only auth o auth-int. Otherwise, ignore*/
- if (foundAuth) {
- d->qop = strdup("auth");
- if(!d->qop)
- return CURLDIGEST_NOMEM;
- }
- else if (foundAuthInt) {
- d->qop = strdup("auth-int");
- if(!d->qop)
- return CURLDIGEST_NOMEM;
- }
- }
- else if(strequal(value, "algorithm")) {
- d->algorithm = strdup(content);
- if(!d->algorithm)
- return CURLDIGEST_NOMEM;
- if(strequal(content, "MD5-sess"))
- d->algo = CURLDIGESTALGO_MD5SESS;
- else if(strequal(content, "MD5"))
- d->algo = CURLDIGESTALGO_MD5;
- else
- return CURLDIGEST_BADALGO;
- }
- else {
- /* unknown specifier, ignore it! */
- }
- totlen = strlen(value)+strlen(content)+1;
-
- if(header[strlen(value)+1] == '\"')
- /* the contents were within quotes, then add 2 for them to the
- length */
- totlen += 2;
- }
- else
- break; /* we're done here */
-
- header += totlen;
- if(',' == *header)
- /* allow the list to be comma-separated */
- header++;
- }
- /* We had a nonce since before, and we got another one now without
- 'stale=true'. This means we provided bad credentials in the previous
- request */
- if(before && !d->stale)
- return CURLDIGEST_BAD;
-
- /* We got this header without a nonce, that's a bad Digest line! */
- if(!d->nonce)
- return CURLDIGEST_BAD;
- }
- else
- /* else not a digest, get out */
- return CURLDIGEST_NONE;
-
- return CURLDIGEST_FINE;
-}
-
-/* convert md5 chunk to RFC2617 (section 3.1.3) -suitable ascii string*/
-static void md5_to_ascii(unsigned char *source, /* 16 bytes */
- unsigned char *dest) /* 33 bytes */
-{
- int i;
- for(i=0; i<16; i++)
- snprintf((char *)&dest[i*2], 3, "%02x", source[i]);
-}
-
-CURLcode Curl_output_digest(struct connectdata *conn,
- bool proxy,
- unsigned char *request,
- unsigned char *uripath)
-{
- /* We have a Digest setup for this, use it! Now, to get all the details for
- this sorted out, I must urge you dear friend to read up on the RFC2617
- section 3.2.2, */
- unsigned char md5buf[16]; /* 16 bytes/128 bits */
- unsigned char request_digest[33];
- unsigned char *md5this;
- unsigned char *ha1;
- unsigned char ha2[33];/* 32 digits and 1 zero byte */
- char cnoncebuf[7];
- char *cnonce;
- char *tmp = NULL;
- struct timeval now;
-
- char **allocuserpwd;
- char *userp;
- char *passwdp;
- struct auth *authp;
-
- struct SessionHandle *data = conn->data;
- struct digestdata *d;
-#ifdef CURL_DOES_CONVERSIONS
- CURLcode rc;
-/* The CURL_OUTPUT_DIGEST_CONV macro below is for non-ASCII machines.
- It converts digest text to ASCII so the MD5 will be correct for
- what ultimately goes over the network.
-*/
-#define CURL_OUTPUT_DIGEST_CONV(a, b) \
- rc = Curl_convert_to_network(a, (char *)b, strlen((const char*)b)); \
- if (rc != CURLE_OK) { \
- free(b); \
- return rc; \
- }
-#else
-#define CURL_OUTPUT_DIGEST_CONV(a, b)
-#endif /* CURL_DOES_CONVERSIONS */
-
- if(proxy) {
- d = &data->state.proxydigest;
- allocuserpwd = &conn->allocptr.proxyuserpwd;
- userp = conn->proxyuser;
- passwdp = conn->proxypasswd;
- authp = &data->state.authproxy;
- }
- else {
- d = &data->state.digest;
- allocuserpwd = &conn->allocptr.userpwd;
- userp = conn->user;
- passwdp = conn->passwd;
- authp = &data->state.authhost;
- }
-
- /* not set means empty */
- if(!userp)
- userp=(char *)"";
-
- if(!passwdp)
- passwdp=(char *)"";
-
- if(!d->nonce) {
- authp->done = FALSE;
- return CURLE_OK;
- }
- authp->done = TRUE;
-
- if(!d->nc)
- d->nc = 1;
-
- if(!d->cnonce) {
- /* Generate a cnonce */
- now = Curl_tvnow();
- snprintf(cnoncebuf, sizeof(cnoncebuf), "%06ld", now.tv_sec);
- if(Curl_base64_encode(data, cnoncebuf, strlen(cnoncebuf), &cnonce))
- d->cnonce = cnonce;
- else
- return CURLE_OUT_OF_MEMORY;
- }
-
- /*
- if the algorithm is "MD5" or unspecified (which then defaults to MD5):
-
- A1 = unq(username-value) ":" unq(realm-value) ":" passwd
-
- if the algorithm is "MD5-sess" then:
-
- A1 = H( unq(username-value) ":" unq(realm-value) ":" passwd )
- ":" unq(nonce-value) ":" unq(cnonce-value)
- */
-
- md5this = (unsigned char *)
- aprintf("%s:%s:%s", userp, d->realm, passwdp);
- if(!md5this)
- return CURLE_OUT_OF_MEMORY;
-
- CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
- Curl_md5it(md5buf, md5this);
- free(md5this); /* free this again */
-
- ha1 = (unsigned char *)malloc(33); /* 32 digits and 1 zero byte */
- if(!ha1)
- return CURLE_OUT_OF_MEMORY;
-
- md5_to_ascii(md5buf, ha1);
-
- if(d->algo == CURLDIGESTALGO_MD5SESS) {
- /* nonce and cnonce are OUTSIDE the hash */
- tmp = aprintf("%s:%s:%s", ha1, d->nonce, d->cnonce);
- if(!tmp)
- return CURLE_OUT_OF_MEMORY;
- CURL_OUTPUT_DIGEST_CONV(data, tmp); /* convert on non-ASCII machines */
- Curl_md5it(md5buf, (unsigned char *)tmp);
- free(tmp); /* free this again */
- md5_to_ascii(md5buf, ha1);
- }
-
- /*
- If the "qop" directive's value is "auth" or is unspecified, then A2 is:
-
- A2 = Method ":" digest-uri-value
-
- If the "qop" value is "auth-int", then A2 is:
-
- A2 = Method ":" digest-uri-value ":" H(entity-body)
-
- (The "Method" value is the HTTP request method as specified in section
- 5.1.1 of RFC 2616)
- */
-
- md5this = (unsigned char *)aprintf("%s:%s", request, uripath);
- if(!md5this) {
- free(ha1);
- return CURLE_OUT_OF_MEMORY;
- }
-
- if (d->qop && strequal(d->qop, "auth-int")) {
- /* We don't support auth-int at the moment. I can't see a easy way to get
- entity-body here */
- /* TODO: Append H(entity-body)*/
- }
- CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
- Curl_md5it(md5buf, md5this);
- free(md5this); /* free this again */
- md5_to_ascii(md5buf, ha2);
-
- if (d->qop) {
- md5this = (unsigned char *)aprintf("%s:%s:%08x:%s:%s:%s",
- ha1,
- d->nonce,
- d->nc,
- d->cnonce,
- d->qop,
- ha2);
- }
- else {
- md5this = (unsigned char *)aprintf("%s:%s:%s",
- ha1,
- d->nonce,
- ha2);
- }
- free(ha1);
- if(!md5this)
- return CURLE_OUT_OF_MEMORY;
-
- CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
- Curl_md5it(md5buf, md5this);
- free(md5this); /* free this again */
- md5_to_ascii(md5buf, request_digest);
-
- /* for test case 64 (snooped from a Mozilla 1.3a request)
-
- Authorization: Digest username="testuser", realm="testrealm", \
- nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca"
- */
-
- Curl_safefree(*allocuserpwd);
-
- if (d->qop) {
- *allocuserpwd =
- aprintf( "%sAuthorization: Digest "
- "username=\"%s\", "
- "realm=\"%s\", "
- "nonce=\"%s\", "
- "uri=\"%s\", "
- "cnonce=\"%s\", "
- "nc=%08x, "
- "qop=\"%s\", "
- "response=\"%s\"",
- proxy?"Proxy-":"",
- userp,
- d->realm,
- d->nonce,
- uripath, /* this is the PATH part of the URL */
- d->cnonce,
- d->nc,
- d->qop,
- request_digest);
-
- if(strequal(d->qop, "auth"))
- d->nc++; /* The nc (from RFC) has to be a 8 hex digit number 0 padded
- which tells to the server how many times you are using the
- same nonce in the qop=auth mode. */
- }
- else {
- *allocuserpwd =
- aprintf( "%sAuthorization: Digest "
- "username=\"%s\", "
- "realm=\"%s\", "
- "nonce=\"%s\", "
- "uri=\"%s\", "
- "response=\"%s\"",
- proxy?"Proxy-":"",
- userp,
- d->realm,
- d->nonce,
- uripath, /* this is the PATH part of the URL */
- request_digest);
- }
- if(!*allocuserpwd)
- return CURLE_OUT_OF_MEMORY;
-
- /* Add optional fields */
- if(d->opaque) {
- /* append opaque */
- tmp = aprintf("%s, opaque=\"%s\"", *allocuserpwd, d->opaque);
- if(!tmp)
- return CURLE_OUT_OF_MEMORY;
- free(*allocuserpwd);
- *allocuserpwd = tmp;
- }
-
- if(d->algorithm) {
- /* append algorithm */
- tmp = aprintf("%s, algorithm=\"%s\"", *allocuserpwd, d->algorithm);
- if(!tmp)
- return CURLE_OUT_OF_MEMORY;
- free(*allocuserpwd);
- *allocuserpwd = tmp;
- }
-
- /* append CRLF to the userpwd header */
- tmp = (char*) realloc(*allocuserpwd, strlen(*allocuserpwd) + 3 + 1);
- if(!tmp)
- return CURLE_OUT_OF_MEMORY;
- strcat(tmp, "\r\n");
- *allocuserpwd = tmp;
-
- return CURLE_OK;
-}
-
-void Curl_digest_cleanup_one(struct digestdata *d)
-{
- if(d->nonce)
- free(d->nonce);
- d->nonce = NULL;
-
- if(d->cnonce)
- free(d->cnonce);
- d->cnonce = NULL;
-
- if(d->realm)
- free(d->realm);
- d->realm = NULL;
-
- if(d->opaque)
- free(d->opaque);
- d->opaque = NULL;
-
- if(d->qop)
- free(d->qop);
- d->qop = NULL;
-
- if(d->algorithm)
- free(d->algorithm);
- d->algorithm = NULL;
-
- d->nc = 0;
- d->algo = CURLDIGESTALGO_MD5; /* default algorithm */
- d->stale = FALSE; /* default means normal, not stale */
-}
-
-
-void Curl_digest_cleanup(struct SessionHandle *data)
-{
- Curl_digest_cleanup_one(&data->state.digest);
- Curl_digest_cleanup_one(&data->state.proxydigest);
-}
-
-#endif
diff --git a/Utilities/cmcurl/http_digest.h b/Utilities/cmcurl/http_digest.h
deleted file mode 100644
index 6cf025975..000000000
--- a/Utilities/cmcurl/http_digest.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#ifndef __HTTP_DIGEST_H
-#define __HTTP_DIGEST_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-typedef enum {
- CURLDIGEST_NONE, /* not a digest */
- CURLDIGEST_BAD, /* a digest, but one we don't like */
- CURLDIGEST_BADALGO, /* unsupported algorithm requested */
- CURLDIGEST_NOMEM,
- CURLDIGEST_FINE, /* a digest we act on */
-
- CURLDIGEST_LAST /* last entry in this enum, don't use */
-} CURLdigest;
-
-enum {
- CURLDIGESTALGO_MD5,
- CURLDIGESTALGO_MD5SESS
-};
-
-/* this is for digest header input */
-CURLdigest Curl_input_digest(struct connectdata *conn,
- bool proxy, char *header);
-
-/* this is for creating digest header output */
-CURLcode Curl_output_digest(struct connectdata *conn,
- bool proxy,
- unsigned char *request,
- unsigned char *uripath);
-void Curl_digest_cleanup_one(struct digestdata *dig);
-
-#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
-void Curl_digest_cleanup(struct SessionHandle *data);
-#else
-#define Curl_digest_cleanup(x) do {} while(0)
-#endif
-
-#endif
diff --git a/Utilities/cmcurl/http_negotiate.c b/Utilities/cmcurl/http_negotiate.c
deleted file mode 100644
index bdfeefa0a..000000000
--- a/Utilities/cmcurl/http_negotiate.c
+++ /dev/null
@@ -1,327 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-#include "setup.h"
-
-#ifdef HAVE_GSSAPI
-#ifdef HAVE_GSSMIT
-#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name
-#endif
-
-#ifndef CURL_DISABLE_HTTP
- /* -- WIN32 approved -- */
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <ctype.h>
-
-#include "urldata.h"
-#include "sendf.h"
-#include "strequal.h"
-#include "base64.h"
-#include "http_negotiate.h"
-#include "memory.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
-#include "memdebug.h"
-
-static int
-get_gss_name(struct connectdata *conn, gss_name_t *server)
-{
- struct negotiatedata *neg_ctx = &conn->data->state.negotiate;
- OM_uint32 major_status, minor_status;
- gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
- char name[2048];
- const char* service;
-
- /* GSSAPI implementation by Globus (known as GSI) requires the name to be
- of form "<service>/<fqdn>" instead of <service>@<fqdn> (ie. slash instead
- of at-sign). Also GSI servers are often identified as 'host' not 'khttp'.
- Change following lines if you want to use GSI */
-
- /* IIS uses the <service>@<fqdn> form but uses 'http' as the service name */
-
- if (neg_ctx->gss)
- service = "KHTTP";
- else
- service = "HTTP";
-
- token.length = strlen(service) + 1 + strlen(conn->host.name) + 1;
- if (token.length + 1 > sizeof(name))
- return EMSGSIZE;
-
- snprintf(name, sizeof(name), "%s@%s", service, conn->host.name);
-
- token.value = (void *) name;
- major_status = gss_import_name(&minor_status,
- &token,
- GSS_C_NT_HOSTBASED_SERVICE,
- server);
-
- return GSS_ERROR(major_status) ? -1 : 0;
-}
-
-static void
-log_gss_error(struct connectdata *conn, OM_uint32 error_status, char *prefix)
-{
- OM_uint32 maj_stat, min_stat;
- OM_uint32 msg_ctx = 0;
- gss_buffer_desc status_string;
- char buf[1024];
- size_t len;
-
- snprintf(buf, sizeof(buf), "%s", prefix);
- len = strlen(buf);
- do {
- maj_stat = gss_display_status (&min_stat,
- error_status,
- GSS_C_MECH_CODE,
- GSS_C_NO_OID,
- &msg_ctx,
- &status_string);
- if (sizeof(buf) > len + status_string.length + 1) {
- snprintf(buf + len, sizeof(buf) - len,
- ": %s", (char*) status_string.value);
- len += status_string.length;
- }
- gss_release_buffer(&min_stat, &status_string);
- } while (!GSS_ERROR(maj_stat) && msg_ctx != 0);
-
- infof(conn->data, "%s", buf);
-}
-
-int Curl_input_negotiate(struct connectdata *conn, char *header)
-{
- struct negotiatedata *neg_ctx = &conn->data->state.negotiate;
- OM_uint32 major_status, minor_status, minor_status2;
- gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
- gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
- int ret;
- size_t len;
- bool gss;
- const char* protocol;
-
- while(*header && ISSPACE(*header))
- header++;
- if(checkprefix("GSS-Negotiate", header)) {
- protocol = "GSS-Negotiate";
- gss = TRUE;
- }
- else if (checkprefix("Negotiate", header)) {
- protocol = "Negotiate";
- gss = FALSE;
- }
- else
- return -1;
-
- if (neg_ctx->context) {
- if (neg_ctx->gss != gss) {
- return -1;
- }
- }
- else {
- neg_ctx->protocol = protocol;
- neg_ctx->gss = gss;
- }
-
- if (neg_ctx->context && neg_ctx->status == GSS_S_COMPLETE) {
- /* We finished succesfully our part of authentication, but server
- * rejected it (since we're again here). Exit with an error since we
- * can't invent anything better */
- Curl_cleanup_negotiate(conn->data);
- return -1;
- }
-
- if (neg_ctx->server_name == NULL &&
- (ret = get_gss_name(conn, &neg_ctx->server_name)))
- return ret;
-
- header += strlen(neg_ctx->protocol);
- while(*header && ISSPACE(*header))
- header++;
-
- len = strlen(header);
- if (len > 0) {
- int rawlen = Curl_base64_decode(header, (unsigned char **)&input_token.value);
- if (rawlen < 0)
- return -1;
- input_token.length = rawlen;
-
-#ifdef HAVE_SPNEGO /* Handle SPNEGO */
- if (checkprefix("Negotiate", header)) {
- ASN1_OBJECT * object = NULL;
- int rc = 1;
- unsigned char * spnegoToken = NULL;
- size_t spnegoTokenLength = 0;
- unsigned char * mechToken = NULL;
- size_t mechTokenLength = 0;
-
- spnegoToken = malloc(input_token.length);
- if (input_token.value == NULL)
- return ENOMEM;
- spnegoTokenLength = input_token.length;
-
- object = OBJ_txt2obj ("1.2.840.113554.1.2.2", 1);
- if (!parseSpnegoTargetToken(spnegoToken,
- spnegoTokenLength,
- NULL,
- NULL,
- &mechToken,
- &mechTokenLength,
- NULL,
- NULL)) {
- free(spnegoToken);
- spnegoToken = NULL;
- infof(conn->data, "Parse SPNEGO Target Token failed\n");
- }
- else {
- free(input_token.value);
- input_token.value = NULL;
- input_token.value = malloc(mechTokenLength);
- memcpy(input_token.value, mechToken,mechTokenLength);
- input_token.length = mechTokenLength;
- free(mechToken);
- mechToken = NULL;
- infof(conn->data, "Parse SPNEGO Target Token succeeded\n");
- }
- }
-#endif
- }
-
- major_status = gss_init_sec_context(&minor_status,
- GSS_C_NO_CREDENTIAL,
- &neg_ctx->context,
- neg_ctx->server_name,
- GSS_C_NO_OID,
- GSS_C_DELEG_FLAG,
- 0,
- GSS_C_NO_CHANNEL_BINDINGS,
- &input_token,
- NULL,
- &output_token,
- NULL,
- NULL);
- if (input_token.length > 0)
- gss_release_buffer(&minor_status2, &input_token);
- neg_ctx->status = major_status;
- if (GSS_ERROR(major_status)) {
- /* Curl_cleanup_negotiate(conn->data) ??? */
- log_gss_error(conn, minor_status,
- (char *)"gss_init_sec_context() failed: ");
- return -1;
- }
-
- if (output_token.length == 0) {
- return -1;
- }
-
- neg_ctx->output_token = output_token;
- /* conn->bits.close = FALSE; */
-
- return 0;
-}
-
-
-CURLcode Curl_output_negotiate(struct connectdata *conn)
-{
- struct negotiatedata *neg_ctx = &conn->data->state.negotiate;
- OM_uint32 minor_status;
- char *encoded = NULL;
- int len;
-
-#ifdef HAVE_SPNEGO /* Handle SPNEGO */
- if (checkprefix("Negotiate",neg_ctx->protocol)) {
- ASN1_OBJECT * object = NULL;
- int rc = 1;
- unsigned char * spnegoToken = NULL;
- size_t spnegoTokenLength = 0;
- unsigned char * responseToken = NULL;
- size_t responseTokenLength = 0;
-
- responseToken = malloc(neg_ctx->output_token.length);
- if ( responseToken == NULL)
- return CURLE_OUT_OF_MEMORY;
- memcpy(responseToken, neg_ctx->output_token.value,
- neg_ctx->output_token.length);
- responseTokenLength = neg_ctx->output_token.length;
-
- object=OBJ_txt2obj ("1.2.840.113554.1.2.2", 1);
- if (!makeSpnegoInitialToken (object,
- responseToken,
- responseTokenLength,
- &spnegoToken,
- &spnegoTokenLength)) {
- free(responseToken);
- responseToken = NULL;
- infof(conn->data, "Make SPNEGO Initial Token failed\n");
- }
- else {
- free(neg_ctx->output_token.value);
- responseToken = NULL;
- neg_ctx->output_token.value = malloc(spnegoTokenLength);
- memcpy(neg_ctx->output_token.value, spnegoToken,spnegoTokenLength);
- neg_ctx->output_token.length = spnegoTokenLength;
- free(spnegoToken);
- spnegoToken = NULL;
- infof(conn->data, "Make SPNEGO Initial Token succeeded\n");
- }
- }
-#endif
- len = Curl_base64_encode(conn->data,
- neg_ctx->output_token.value,
- neg_ctx->output_token.length,
- &encoded);
-
- if (len < 0)
- return CURLE_OUT_OF_MEMORY;
-
- conn->allocptr.userpwd =
- aprintf("Authorization: %s %s\r\n", neg_ctx->protocol, encoded);
- free(encoded);
- gss_release_buffer(&minor_status, &neg_ctx->output_token);
- return (conn->allocptr.userpwd == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;
-}
-
-void Curl_cleanup_negotiate(struct SessionHandle *data)
-{
- OM_uint32 minor_status;
- struct negotiatedata *neg_ctx = &data->state.negotiate;
-
- if (neg_ctx->context != GSS_C_NO_CONTEXT)
- gss_delete_sec_context(&minor_status, &neg_ctx->context, GSS_C_NO_BUFFER);
-
- if (neg_ctx->output_token.length != 0)
- gss_release_buffer(&minor_status, &neg_ctx->output_token);
-
- if (neg_ctx->server_name != GSS_C_NO_NAME)
- gss_release_name(&minor_status, &neg_ctx->server_name);
-
- memset(neg_ctx, 0, sizeof(*neg_ctx));
-}
-
-
-#endif
-#endif
diff --git a/Utilities/cmcurl/http_negotiate.h b/Utilities/cmcurl/http_negotiate.h
deleted file mode 100644
index ce0d083f9..000000000
--- a/Utilities/cmcurl/http_negotiate.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef __HTTP_NEGOTIATE_H
-#define __HTTP_NEGOTIATE_H
-
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#ifdef HAVE_GSSAPI
-
-/* this is for Negotiate header input */
-int Curl_input_negotiate(struct connectdata *conn, char *header);
-
-/* this is for creating Negotiate header output */
-CURLcode Curl_output_negotiate(struct connectdata *conn);
-
-void Curl_cleanup_negotiate(struct SessionHandle *data);
-
-#endif
-
-#endif
diff --git a/Utilities/cmcurl/http_ntlm.c b/Utilities/cmcurl/http_ntlm.c
deleted file mode 100644
index aff1bb1b6..000000000
--- a/Utilities/cmcurl/http_ntlm.c
+++ /dev/null
@@ -1,1111 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-#include "setup.h"
-
-/* NTLM details:
-
- http://davenport.sourceforge.net/ntlm.html
- http://www.innovation.ch/java/ntlm.html
-
- Another implementation:
- http://lxr.mozilla.org/mozilla/source/security/manager/ssl/src/nsNTLMAuthModule.cpp
-
-*/
-
-#ifndef CURL_DISABLE_HTTP
-#ifdef USE_NTLM
-
-#define DEBUG_ME 0
-
-/* -- WIN32 approved -- */
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <ctype.h>
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "urldata.h"
-#include "easyif.h" /* for Curl_convert_... prototypes */
-#include "sendf.h"
-#include "strequal.h"
-#include "base64.h"
-#include "http_ntlm.h"
-#include "url.h"
-#include "memory.h"
-#include "ssluse.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* "NTLMSSP" signature is always in ASCII regardless of the platform */
-#define NTLMSSP_SIGNATURE "\x4e\x54\x4c\x4d\x53\x53\x50"
-
-#ifndef USE_WINDOWS_SSPI
-
-#include <openssl/des.h>
-#include <openssl/md4.h>
-#include <openssl/md5.h>
-#include <openssl/ssl.h>
-#include <openssl/rand.h>
-
-#if OPENSSL_VERSION_NUMBER < 0x00907001L
-#define DES_key_schedule des_key_schedule
-#define DES_cblock des_cblock
-#define DES_set_odd_parity des_set_odd_parity
-#define DES_set_key des_set_key
-#define DES_ecb_encrypt des_ecb_encrypt
-
-/* This is how things were done in the old days */
-#define DESKEY(x) x
-#define DESKEYARG(x) x
-#else
-/* Modern version */
-#define DESKEYARG(x) *x
-#define DESKEY(x) &x
-#endif
-
-#else
-
-#include <rpc.h>
-
-/* Handle of security.dll or secur32.dll, depending on Windows version */
-static HMODULE s_hSecDll = NULL;
-/* Pointer to SSPI dispatch table */
-static PSecurityFunctionTable s_pSecFn = NULL;
-
-#endif
-
-/* The last #include file should be: */
-#include "memdebug.h"
-
-/* Define this to make the type-3 message include the NT response message */
-#define USE_NTRESPONSES 1
-
-/* Define this to make the type-3 message include the NTLM2Session response
- message, requires USE_NTRESPONSES. */
-#define USE_NTLM2SESSION 1
-
-#ifndef USE_WINDOWS_SSPI
-/* this function converts from the little endian format used in the incoming
- package to whatever endian format we're using natively */
-static unsigned int readint_le(unsigned char *buf) /* must point to a
- 4 bytes buffer*/
-{
- return ((unsigned int)buf[0]) | ((unsigned int)buf[1] << 8) |
- ((unsigned int)buf[2] << 16) | ((unsigned int)buf[3] << 24);
-}
-#endif
-
-#if DEBUG_ME
-# define DEBUG_OUT(x) x
-static void print_flags(FILE *handle, unsigned long flags)
-{
- if(flags & NTLMFLAG_NEGOTIATE_UNICODE)
- fprintf(handle, "NTLMFLAG_NEGOTIATE_UNICODE ");
- if(flags & NTLMFLAG_NEGOTIATE_OEM)
- fprintf(handle, "NTLMFLAG_NEGOTIATE_OEM ");
- if(flags & NTLMFLAG_REQUEST_TARGET)
- fprintf(handle, "NTLMFLAG_REQUEST_TARGET ");
- if(flags & (1<<3))
- fprintf(handle, "NTLMFLAG_UNKNOWN_3 ");
- if(flags & NTLMFLAG_NEGOTIATE_SIGN)
- fprintf(handle, "NTLMFLAG_NEGOTIATE_SIGN ");
- if(flags & NTLMFLAG_NEGOTIATE_SEAL)
- fprintf(handle, "NTLMFLAG_NEGOTIATE_SEAL ");
- if(flags & NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE)
- fprintf(handle, "NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE ");
- if(flags & NTLMFLAG_NEGOTIATE_LM_KEY)
- fprintf(handle, "NTLMFLAG_NEGOTIATE_LM_KEY ");
- if(flags & NTLMFLAG_NEGOTIATE_NETWARE)
- fprintf(handle, "NTLMFLAG_NEGOTIATE_NETWARE ");
- if(flags & NTLMFLAG_NEGOTIATE_NTLM_KEY)
- fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM_KEY ");
- if(flags & (1<<10))
- fprintf(handle, "NTLMFLAG_UNKNOWN_10 ");
- if(flags & (1<<11))
- fprintf(handle, "NTLMFLAG_UNKNOWN_11 ");
- if(flags & NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED)
- fprintf(handle, "NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED ");
- if(flags & NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED)
- fprintf(handle, "NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED ");
- if(flags & NTLMFLAG_NEGOTIATE_LOCAL_CALL)
- fprintf(handle, "NTLMFLAG_NEGOTIATE_LOCAL_CALL ");
- if(flags & NTLMFLAG_NEGOTIATE_ALWAYS_SIGN)
- fprintf(handle, "NTLMFLAG_NEGOTIATE_ALWAYS_SIGN ");
- if(flags & NTLMFLAG_TARGET_TYPE_DOMAIN)
- fprintf(handle, "NTLMFLAG_TARGET_TYPE_DOMAIN ");
- if(flags & NTLMFLAG_TARGET_TYPE_SERVER)
- fprintf(handle, "NTLMFLAG_TARGET_TYPE_SERVER ");
- if(flags & NTLMFLAG_TARGET_TYPE_SHARE)
- fprintf(handle, "NTLMFLAG_TARGET_TYPE_SHARE ");
- if(flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY)
- fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM2_KEY ");
- if(flags & NTLMFLAG_REQUEST_INIT_RESPONSE)
- fprintf(handle, "NTLMFLAG_REQUEST_INIT_RESPONSE ");
- if(flags & NTLMFLAG_REQUEST_ACCEPT_RESPONSE)
- fprintf(handle, "NTLMFLAG_REQUEST_ACCEPT_RESPONSE ");
- if(flags & NTLMFLAG_REQUEST_NONNT_SESSION_KEY)
- fprintf(handle, "NTLMFLAG_REQUEST_NONNT_SESSION_KEY ");
- if(flags & NTLMFLAG_NEGOTIATE_TARGET_INFO)
- fprintf(handle, "NTLMFLAG_NEGOTIATE_TARGET_INFO ");
- if(flags & (1<<24))
- fprintf(handle, "NTLMFLAG_UNKNOWN_24 ");
- if(flags & (1<<25))
- fprintf(handle, "NTLMFLAG_UNKNOWN_25 ");
- if(flags & (1<<26))
- fprintf(handle, "NTLMFLAG_UNKNOWN_26 ");
- if(flags & (1<<27))
- fprintf(handle, "NTLMFLAG_UNKNOWN_27 ");
- if(flags & (1<<28))
- fprintf(handle, "NTLMFLAG_UNKNOWN_28 ");
- if(flags & NTLMFLAG_NEGOTIATE_128)
- fprintf(handle, "NTLMFLAG_NEGOTIATE_128 ");
- if(flags & NTLMFLAG_NEGOTIATE_KEY_EXCHANGE)
- fprintf(handle, "NTLMFLAG_NEGOTIATE_KEY_EXCHANGE ");
- if(flags & NTLMFLAG_NEGOTIATE_56)
- fprintf(handle, "NTLMFLAG_NEGOTIATE_56 ");
-}
-
-static void print_hex(FILE *handle, const char *buf, size_t len)
-{
- const char *p = buf;
- fprintf(stderr, "0x");
- while (len-- > 0)
- fprintf(stderr, "%02.2x", (unsigned int)*p++);
-}
-#else
-# define DEBUG_OUT(x)
-#endif
-
-/*
- (*) = A "security buffer" is a triplet consisting of two shorts and one
- long:
-
- 1. a 'short' containing the length of the buffer in bytes
- 2. a 'short' containing the allocated space for the buffer in bytes
- 3. a 'long' containing the offset to the start of the buffer from the
- beginning of the NTLM message, in bytes.
-*/
-
-
-CURLntlm Curl_input_ntlm(struct connectdata *conn,
- bool proxy, /* if proxy or not */
- char *header) /* rest of the www-authenticate:
- header */
-{
- /* point to the correct struct with this */
- struct ntlmdata *ntlm;
-#ifndef USE_WINDOWS_SSPI
- static const char type2_marker[] = { 0x02, 0x00, 0x00, 0x00 };
-#endif
-
- ntlm = proxy?&conn->proxyntlm:&conn->ntlm;
-
- /* skip initial whitespaces */
- while(*header && ISSPACE(*header))
- header++;
-
- if(checkprefix("NTLM", header)) {
- header += strlen("NTLM");
-
- while(*header && ISSPACE(*header))
- header++;
-
- if(*header) {
- /* We got a type-2 message here:
-
- Index Description Content
- 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
- (0x4e544c4d53535000)
- 8 NTLM Message Type long (0x02000000)
- 12 Target Name security buffer(*)
- 20 Flags long
- 24 Challenge 8 bytes
- (32) Context (optional) 8 bytes (two consecutive longs)
- (40) Target Information (optional) security buffer(*)
- 32 (48) start of data block
- */
- size_t size;
- unsigned char *buffer;
- size = Curl_base64_decode(header, &buffer);
- if(!buffer)
- return CURLNTLM_BAD;
-
- ntlm->state = NTLMSTATE_TYPE2; /* we got a type-2 */
-
-#ifdef USE_WINDOWS_SSPI
- ntlm->type_2 = malloc(size+1);
- if (ntlm->type_2 == NULL) {
- free(buffer);
- return CURLE_OUT_OF_MEMORY;
- }
- ntlm->n_type_2 = size;
- memcpy(ntlm->type_2, buffer, size);
-#else
- ntlm->flags = 0;
-
- if((size < 32) ||
- (memcmp(buffer, NTLMSSP_SIGNATURE, 8) != 0) ||
- (memcmp(buffer+8, type2_marker, sizeof(type2_marker)) != 0)) {
- /* This was not a good enough type-2 message */
- free(buffer);
- return CURLNTLM_BAD;
- }
-
- ntlm->flags = readint_le(&buffer[20]);
- memcpy(ntlm->nonce, &buffer[24], 8);
-
- DEBUG_OUT({
- fprintf(stderr, "**** TYPE2 header flags=0x%08.8lx ", ntlm->flags);
- print_flags(stderr, ntlm->flags);
- fprintf(stderr, "\n nonce=");
- print_hex(stderr, (char *)ntlm->nonce, 8);
- fprintf(stderr, "\n****\n");
- fprintf(stderr, "**** Header %s\n ", header);
- });
-
- free(buffer);
-#endif
- }
- else {
- if(ntlm->state >= NTLMSTATE_TYPE1)
- return CURLNTLM_BAD;
-
- ntlm->state = NTLMSTATE_TYPE1; /* we should sent away a type-1 */
- }
- }
- return CURLNTLM_FINE;
-}
-
-#ifndef USE_WINDOWS_SSPI
-
-/*
- * Turns a 56 bit key into the 64 bit, odd parity key and sets the key. The
- * key schedule ks is also set.
- */
-static void setup_des_key(unsigned char *key_56,
- DES_key_schedule DESKEYARG(ks))
-{
- DES_cblock key;
-
- key[0] = key_56[0];
- key[1] = (unsigned char)(((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1));
- key[2] = (unsigned char)(((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2));
- key[3] = (unsigned char)(((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3));
- key[4] = (unsigned char)(((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4));
- key[5] = (unsigned char)(((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5));
- key[6] = (unsigned char)(((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6));
- key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF);
-
- DES_set_odd_parity(&key);
- DES_set_key(&key, ks);
-}
-
- /*
- * takes a 21 byte array and treats it as 3 56-bit DES keys. The
- * 8 byte plaintext is encrypted with each key and the resulting 24
- * bytes are stored in the results array.
- */
-static void lm_resp(unsigned char *keys,
- unsigned char *plaintext,
- unsigned char *results)
-{
- DES_key_schedule ks;
-
- setup_des_key(keys, DESKEY(ks));
- DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) results,
- DESKEY(ks), DES_ENCRYPT);
-
- setup_des_key(keys+7, DESKEY(ks));
- DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+8),
- DESKEY(ks), DES_ENCRYPT);
-
- setup_des_key(keys+14, DESKEY(ks));
- DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+16),
- DESKEY(ks), DES_ENCRYPT);
-}
-
-
-/*
- * Set up lanmanager hashed password
- */
-static void mk_lm_hash(struct SessionHandle *data,
- char *password,
- unsigned char *lmbuffer /* 21 bytes */)
-{
- unsigned char pw[14];
- static const unsigned char magic[] = {
- 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */
- };
- unsigned int i;
- size_t len = strlen(password);
-
- if (len > 14)
- len = 14;
-
- for (i=0; i<len; i++)
- pw[i] = (unsigned char)toupper(password[i]);
-
- for (; i<14; i++)
- pw[i] = 0;
-
-#ifdef CURL_DOES_CONVERSIONS
- /*
- * The LanManager hashed password needs to be created using the
- * password in the network encoding not the host encoding.
- */
- if(data)
- Curl_convert_to_network(data, (char *)pw, 14);
-#else
- (void)data;
-#endif
-
- {
- /* Create LanManager hashed password. */
-
- DES_key_schedule ks;
-
- setup_des_key(pw, DESKEY(ks));
- DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer,
- DESKEY(ks), DES_ENCRYPT);
-
- setup_des_key(pw+7, DESKEY(ks));
- DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer+8),
- DESKEY(ks), DES_ENCRYPT);
-
- memset(lmbuffer + 16, 0, 21 - 16);
- }
- }
-
-#if USE_NTRESPONSES
-static void utf8_to_unicode_le(unsigned char *dest, const char *src,
- size_t srclen)
-{
- size_t i;
- for (i=0; i<srclen; i++) {
- dest[2*i] = (unsigned char)src[i];
- dest[2*i+1] = '\0';
- }
-}
-
-/*
- * Set up nt hashed passwords
- */
-static void mk_nt_hash(struct SessionHandle *data,
- char *password,
- unsigned char *ntbuffer /* 21 bytes */)
-{
- size_t len = strlen(password);
- unsigned char *pw = malloc(len*2);
-
- utf8_to_unicode_le(pw, password, len);
-
-#ifdef CURL_DOES_CONVERSIONS
- /*
- * The NT hashed password needs to be created using the
- * password in the network encoding not the host encoding.
- */
- if(data)
- Curl_convert_to_network(data, (char *)pw, len*2);
-#else
- (void)data;
-#endif
-
- {
- /* Create NT hashed password. */
- MD4_CTX MD4;
-
- MD4_Init(&MD4);
- MD4_Update(&MD4, pw, 2*len);
- MD4_Final(ntbuffer, &MD4);
-
- memset(ntbuffer + 16, 0, 21 - 16);
- }
-
- free(pw);
-}
-#endif
-
-
-#endif
-
-#ifdef USE_WINDOWS_SSPI
-
-static void
-ntlm_sspi_cleanup(struct ntlmdata *ntlm)
-{
- if (ntlm->type_2) {
- free(ntlm->type_2);
- ntlm->type_2 = NULL;
- }
- if (ntlm->has_handles) {
- s_pSecFn->DeleteSecurityContext(&ntlm->c_handle);
- s_pSecFn->FreeCredentialsHandle(&ntlm->handle);
- ntlm->has_handles = 0;
- }
- if (ntlm->p_identity) {
- if (ntlm->identity.User) free(ntlm->identity.User);
- if (ntlm->identity.Password) free(ntlm->identity.Password);
- if (ntlm->identity.Domain) free(ntlm->identity.Domain);
- ntlm->p_identity = NULL;
- }
-}
-
-#endif
-
-#define SHORTPAIR(x) ((x) & 0xff), (((x) >> 8) & 0xff)
-#define LONGQUARTET(x) ((x) & 0xff), (((x) >> 8)&0xff), \
- (((x) >>16)&0xff), (((x)>>24) & 0xff)
-
-#define HOSTNAME_MAX 1024
-
-/* this is for creating ntlm header output */
-CURLcode Curl_output_ntlm(struct connectdata *conn,
- bool proxy)
-{
- const char *domain=""; /* empty */
- char host [HOSTNAME_MAX+ 1] = ""; /* empty */
-#ifndef USE_WINDOWS_SSPI
- size_t domlen = strlen(domain);
- size_t hostlen = strlen(host);
- size_t hostoff; /* host name offset */
- size_t domoff; /* domain name offset */
-#endif
- size_t size;
- char *base64=NULL;
- unsigned char ntlmbuf[1024]; /* enough, unless the user+host+domain is very
- long */
-
- /* point to the address of the pointer that holds the string to sent to the
- server, which is for a plain host or for a HTTP proxy */
- char **allocuserpwd;
-
- /* point to the name and password for this */
- char *userp;
- char *passwdp;
- /* point to the correct struct with this */
- struct ntlmdata *ntlm;
- struct auth *authp;
-
- curlassert(conn);
- curlassert(conn->data);
-
- if(proxy) {
- allocuserpwd = &conn->allocptr.proxyuserpwd;
- userp = conn->proxyuser;
- passwdp = conn->proxypasswd;
- ntlm = &conn->proxyntlm;
- authp = &conn->data->state.authproxy;
- }
- else {
- allocuserpwd = &conn->allocptr.userpwd;
- userp = conn->user;
- passwdp = conn->passwd;
- ntlm = &conn->ntlm;
- authp = &conn->data->state.authhost;
- }
- authp->done = FALSE;
-
- /* not set means empty */
- if(!userp)
- userp=(char *)"";
-
- if(!passwdp)
- passwdp=(char *)"";
-
-#ifdef USE_WINDOWS_SSPI
- /* If security interface is not yet initialized try to do this */
- if (s_hSecDll == NULL) {
- /* Determine Windows version. Security functions are located in
- * security.dll on WinNT 4.0 and in secur32.dll on Win9x. Win2K and XP
- * contain both these DLLs (security.dll just forwards calls to
- * secur32.dll)
- */
- OSVERSIONINFO osver;
- osver.dwOSVersionInfoSize = sizeof(osver);
- GetVersionEx(&osver);
- if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT
- && osver.dwMajorVersion == 4)
- s_hSecDll = LoadLibrary("security.dll");
- else
- s_hSecDll = LoadLibrary("secur32.dll");
- if (s_hSecDll != NULL) {
- INIT_SECURITY_INTERFACE pInitSecurityInterface;
- pInitSecurityInterface =
- (INIT_SECURITY_INTERFACE)GetProcAddress(s_hSecDll,
- "InitSecurityInterfaceA");
- if (pInitSecurityInterface != NULL)
- s_pSecFn = pInitSecurityInterface();
- }
- }
- if (s_pSecFn == NULL)
- return CURLE_RECV_ERROR;
-#endif
-
- switch(ntlm->state) {
- case NTLMSTATE_TYPE1:
- default: /* for the weird cases we (re)start here */
-#ifdef USE_WINDOWS_SSPI
- {
- SecBuffer buf;
- SecBufferDesc desc;
- SECURITY_STATUS status;
- ULONG attrs;
- const char *user;
- int domlen;
- TimeStamp tsDummy; /* For Windows 9x compatibility of SPPI calls */
-
- ntlm_sspi_cleanup(ntlm);
-
- user = strchr(userp, '\\');
- if (!user)
- user = strchr(userp, '/');
-
- if (user) {
- domain = userp;
- domlen = user - userp;
- user++;
- }
- else {
- user = userp;
- domain = "";
- domlen = 0;
- }
-
- if (user && *user) {
- /* note: initialize all of this before doing the mallocs so that
- * it can be cleaned up later without leaking memory.
- */
- ntlm->p_identity = &ntlm->identity;
- memset(ntlm->p_identity, 0, sizeof(*ntlm->p_identity));
- if ((ntlm->identity.User = (unsigned char *)strdup(user)) == NULL)
- return CURLE_OUT_OF_MEMORY;
- ntlm->identity.UserLength = strlen(user);
- if ((ntlm->identity.Password = (unsigned char *)strdup(passwdp)) == NULL)
- return CURLE_OUT_OF_MEMORY;
- ntlm->identity.PasswordLength = strlen(passwdp);
- if ((ntlm->identity.Domain = malloc(domlen+1)) == NULL)
- return CURLE_OUT_OF_MEMORY;
- strncpy((char *)ntlm->identity.Domain, domain, domlen);
- ntlm->identity.Domain[domlen] = '\0';
- ntlm->identity.DomainLength = domlen;
- ntlm->identity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
- }
- else {
- ntlm->p_identity = NULL;
- }
-
- if (s_pSecFn->AcquireCredentialsHandle(
- NULL, (char *)"NTLM", SECPKG_CRED_OUTBOUND, NULL, ntlm->p_identity,
- NULL, NULL, &ntlm->handle, &tsDummy
- ) != SEC_E_OK) {
- return CURLE_OUT_OF_MEMORY;
- }
-
- desc.ulVersion = SECBUFFER_VERSION;
- desc.cBuffers = 1;
- desc.pBuffers = &buf;
- buf.cbBuffer = sizeof(ntlmbuf);
- buf.BufferType = SECBUFFER_TOKEN;
- buf.pvBuffer = ntlmbuf;
-
- status = s_pSecFn->InitializeSecurityContext(&ntlm->handle, NULL,
- (char *) host,
- ISC_REQ_CONFIDENTIALITY |
- ISC_REQ_REPLAY_DETECT |
- ISC_REQ_CONNECTION,
- 0, SECURITY_NETWORK_DREP,
- NULL, 0,
- &ntlm->c_handle, &desc,
- &attrs, &tsDummy);
-
- if (status == SEC_I_COMPLETE_AND_CONTINUE ||
- status == SEC_I_CONTINUE_NEEDED) {
- s_pSecFn->CompleteAuthToken(&ntlm->c_handle, &desc);
- }
- else if (status != SEC_E_OK) {
- s_pSecFn->FreeCredentialsHandle(&ntlm->handle);
- return CURLE_RECV_ERROR;
- }
-
- ntlm->has_handles = 1;
- size = buf.cbBuffer;
- }
-#else
- hostoff = 0;
- domoff = hostoff + hostlen; /* This is 0: remember that host and domain
- are empty */
-
- /* Create and send a type-1 message:
-
- Index Description Content
- 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
- (0x4e544c4d53535000)
- 8 NTLM Message Type long (0x01000000)
- 12 Flags long
- 16 Supplied Domain security buffer(*)
- 24 Supplied Workstation security buffer(*)
- 32 start of data block
-
- */
-#if USE_NTLM2SESSION
-#define NTLM2FLAG NTLMFLAG_NEGOTIATE_NTLM2_KEY
-#else
-#define NTLM2FLAG 0
-#endif
- snprintf((char *)ntlmbuf, sizeof(ntlmbuf), NTLMSSP_SIGNATURE "%c"
- "\x01%c%c%c" /* 32-bit type = 1 */
- "%c%c%c%c" /* 32-bit NTLM flag field */
- "%c%c" /* domain length */
- "%c%c" /* domain allocated space */
- "%c%c" /* domain name offset */
- "%c%c" /* 2 zeroes */
- "%c%c" /* host length */
- "%c%c" /* host allocated space */
- "%c%c" /* host name offset */
- "%c%c" /* 2 zeroes */
- "%s" /* host name */
- "%s", /* domain string */
- 0, /* trailing zero */
- 0,0,0, /* part of type-1 long */
-
- LONGQUARTET(
- NTLMFLAG_NEGOTIATE_OEM|
- NTLMFLAG_REQUEST_TARGET|
- NTLMFLAG_NEGOTIATE_NTLM_KEY|
- NTLM2FLAG|
- NTLMFLAG_NEGOTIATE_ALWAYS_SIGN
- ),
- SHORTPAIR(domlen),
- SHORTPAIR(domlen),
- SHORTPAIR(domoff),
- 0,0,
- SHORTPAIR(hostlen),
- SHORTPAIR(hostlen),
- SHORTPAIR(hostoff),
- 0,0,
- host /* this is empty */, domain /* this is empty */);
-
- /* initial packet length */
- size = 32 + hostlen + domlen;
-#endif
-
- DEBUG_OUT({
- fprintf(stderr, "**** TYPE1 header flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ",
- LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM|
- NTLMFLAG_REQUEST_TARGET|
- NTLMFLAG_NEGOTIATE_NTLM_KEY|
- NTLM2FLAG|
- NTLMFLAG_NEGOTIATE_ALWAYS_SIGN),
- NTLMFLAG_NEGOTIATE_OEM|
- NTLMFLAG_REQUEST_TARGET|
- NTLMFLAG_NEGOTIATE_NTLM_KEY|
- NTLM2FLAG|
- NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
- print_flags(stderr,
- NTLMFLAG_NEGOTIATE_OEM|
- NTLMFLAG_REQUEST_TARGET|
- NTLMFLAG_NEGOTIATE_NTLM_KEY|
- NTLM2FLAG|
- NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
- fprintf(stderr, "\n****\n");
- });
-
- /* now size is the size of the base64 encoded package size */
- size = Curl_base64_encode(NULL, (char *)ntlmbuf, size, &base64);
-
- if(size >0 ) {
- Curl_safefree(*allocuserpwd);
- *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
- proxy?"Proxy-":"",
- base64);
- DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd));
- free(base64);
- }
- else
- return CURLE_OUT_OF_MEMORY; /* FIX TODO */
-
- break;
-
- case NTLMSTATE_TYPE2:
- /* We received the type-2 message already, create a type-3 message:
-
- Index Description Content
- 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
- (0x4e544c4d53535000)
- 8 NTLM Message Type long (0x03000000)
- 12 LM/LMv2 Response security buffer(*)
- 20 NTLM/NTLMv2 Response security buffer(*)
- 28 Domain Name security buffer(*)
- 36 User Name security buffer(*)
- 44 Workstation Name security buffer(*)
- (52) Session Key (optional) security buffer(*)
- (60) Flags (optional) long
- 52 (64) start of data block
-
- */
-
- {
-#ifdef USE_WINDOWS_SSPI
- SecBuffer type_2, type_3;
- SecBufferDesc type_2_desc, type_3_desc;
- SECURITY_STATUS status;
- ULONG attrs;
- TimeStamp tsDummy; /* For Windows 9x compatibility of SPPI calls */
-
- type_2_desc.ulVersion = type_3_desc.ulVersion = SECBUFFER_VERSION;
- type_2_desc.cBuffers = type_3_desc.cBuffers = 1;
- type_2_desc.pBuffers = &type_2;
- type_3_desc.pBuffers = &type_3;
-
- type_2.BufferType = SECBUFFER_TOKEN;
- type_2.pvBuffer = ntlm->type_2;
- type_2.cbBuffer = ntlm->n_type_2;
- type_3.BufferType = SECBUFFER_TOKEN;
- type_3.pvBuffer = ntlmbuf;
- type_3.cbBuffer = sizeof(ntlmbuf);
-
- status = s_pSecFn->InitializeSecurityContext(&ntlm->handle, &ntlm->c_handle,
- (char *) host,
- ISC_REQ_CONFIDENTIALITY |
- ISC_REQ_REPLAY_DETECT |
- ISC_REQ_CONNECTION,
- 0, SECURITY_NETWORK_DREP, &type_2_desc,
- 0, &ntlm->c_handle, &type_3_desc,
- &attrs, &tsDummy);
-
- if (status != SEC_E_OK)
- return CURLE_RECV_ERROR;
-
- size = type_3.cbBuffer;
-
- ntlm_sspi_cleanup(ntlm);
-
-#else
- int lmrespoff;
- unsigned char lmresp[24]; /* fixed-size */
-#if USE_NTRESPONSES
- int ntrespoff;
- unsigned char ntresp[24]; /* fixed-size */
-#endif
- size_t useroff;
- const char *user;
- size_t userlen;
-
- user = strchr(userp, '\\');
- if(!user)
- user = strchr(userp, '/');
-
- if (user) {
- domain = userp;
- domlen = (user - domain);
- user++;
- }
- else
- user = userp;
- userlen = strlen(user);
-
- if (gethostname(host, HOSTNAME_MAX)) {
- infof(conn->data, "gethostname() failed, continuing without!");
- hostlen = 0;
- }
- else {
- /* If the workstation if configured with a full DNS name (i.e.
- * workstation.somewhere.net) gethostname() returns the fully qualified
- * name, which NTLM doesn't like.
- */
- char *dot = strchr(host, '.');
- if (dot)
- *dot = '\0';
- hostlen = strlen(host);
- }
-
-#if USE_NTLM2SESSION
- /* We don't support NTLM2 if we don't have USE_NTRESPONSES */
- if (ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) {
- unsigned char ntbuffer[0x18];
- unsigned char tmp[0x18];
- unsigned char md5sum[MD5_DIGEST_LENGTH];
- MD5_CTX MD5;
- unsigned char random[8];
-
- /* Need to create 8 bytes random data */
- Curl_ossl_seed(conn->data); /* Initiate the seed if not already done */
- RAND_bytes(random,8);
-
- /* 8 bytes random data as challenge in lmresp */
- memcpy(lmresp,random,8);
- /* Pad with zeros */
- memset(lmresp+8,0,0x10);
-
- /* Fill tmp with challenge(nonce?) + random */
- memcpy(tmp,&ntlm->nonce[0],8);
- memcpy(tmp+8,random,8);
-
- MD5_Init(&MD5);
- MD5_Update(&MD5, tmp, 16);
- MD5_Final(md5sum, &MD5);
- /* We shall only use the first 8 bytes of md5sum,
- but the des code in lm_resp only encrypt the first 8 bytes */
- mk_nt_hash(conn->data, passwdp, ntbuffer);
- lm_resp(ntbuffer, md5sum, ntresp);
-
- /* End of NTLM2 Session code */
- }
- else {
-#endif
-
-#if USE_NTRESPONSES
- unsigned char ntbuffer[0x18];
-#endif
- unsigned char lmbuffer[0x18];
-
-#if USE_NTRESPONSES
- mk_nt_hash(conn->data, passwdp, ntbuffer);
- lm_resp(ntbuffer, &ntlm->nonce[0], ntresp);
-#endif
-
- mk_lm_hash(conn->data, passwdp, lmbuffer);
- lm_resp(lmbuffer, &ntlm->nonce[0], lmresp);
- /* A safer but less compatible alternative is:
- * lm_resp(ntbuffer, &ntlm->nonce[0], lmresp);
- * See http://davenport.sourceforge.net/ntlm.html#ntlmVersion2 */
-#if USE_NTLM2SESSION
- }
-#endif
-
- lmrespoff = 64; /* size of the message header */
-#if USE_NTRESPONSES
- ntrespoff = lmrespoff + 0x18;
- domoff = ntrespoff + 0x18;
-#else
- domoff = lmrespoff + 0x18;
-#endif
- useroff = domoff + domlen;
- hostoff = useroff + userlen;
-
- /* Create the big type-3 message binary blob */
- size = snprintf((char *)ntlmbuf, sizeof(ntlmbuf),
- NTLMSSP_SIGNATURE "%c"
- "\x03%c%c%c" /* type-3, 32 bits */
-
- "%c%c" /* LanManager length */
- "%c%c" /* LanManager allocated space */
- "%c%c" /* LanManager offset */
- "%c%c" /* 2 zeroes */
-
- "%c%c" /* NT-response length */
- "%c%c" /* NT-response allocated space */
- "%c%c" /* NT-response offset */
- "%c%c" /* 2 zeroes */
-
- "%c%c" /* domain length */
- "%c%c" /* domain allocated space */
- "%c%c" /* domain name offset */
- "%c%c" /* 2 zeroes */
-
- "%c%c" /* user length */
- "%c%c" /* user allocated space */
- "%c%c" /* user offset */
- "%c%c" /* 2 zeroes */
-
- "%c%c" /* host length */
- "%c%c" /* host allocated space */
- "%c%c" /* host offset */
- "%c%c" /* 2 zeroes */
-
- "%c%c" /* session key length (unknown purpose) */
- "%c%c" /* session key allocated space (unknown purpose) */
- "%c%c" /* session key offset (unknown purpose) */
- "%c%c" /* 2 zeroes */
-
- "%c%c%c%c" /* flags */
-
- /* domain string */
- /* user string */
- /* host string */
- /* LanManager response */
- /* NT response */
- ,
- 0, /* zero termination */
- 0,0,0, /* type-3 long, the 24 upper bits */
-
- SHORTPAIR(0x18), /* LanManager response length, twice */
- SHORTPAIR(0x18),
- SHORTPAIR(lmrespoff),
- 0x0, 0x0,
-
-#if USE_NTRESPONSES
- SHORTPAIR(0x18), /* NT-response length, twice */
- SHORTPAIR(0x18),
- SHORTPAIR(ntrespoff),
- 0x0, 0x0,
-#else
- 0x0, 0x0,
- 0x0, 0x0,
- 0x0, 0x0,
- 0x0, 0x0,
-#endif
- SHORTPAIR(domlen),
- SHORTPAIR(domlen),
- SHORTPAIR(domoff),
- 0x0, 0x0,
-
- SHORTPAIR(userlen),
- SHORTPAIR(userlen),
- SHORTPAIR(useroff),
- 0x0, 0x0,
-
- SHORTPAIR(hostlen),
- SHORTPAIR(hostlen),
- SHORTPAIR(hostoff),
- 0x0, 0x0,
-
- 0x0, 0x0,
- 0x0, 0x0,
- 0x0, 0x0,
- 0x0, 0x0,
-
- LONGQUARTET(ntlm->flags));
- DEBUG_OUT(assert(size==64));
-
- DEBUG_OUT(assert(size == lmrespoff));
- /* We append the binary hashes */
- if(size < (sizeof(ntlmbuf) - 0x18)) {
- memcpy(&ntlmbuf[size], lmresp, 0x18);
- size += 0x18;
- }
-
- DEBUG_OUT({
- fprintf(stderr, "**** TYPE3 header lmresp=");
- print_hex(stderr, (char *)&ntlmbuf[lmrespoff], 0x18);
- });
-
-#if USE_NTRESPONSES
- if(size < (sizeof(ntlmbuf) - 0x18)) {
- DEBUG_OUT(assert(size == ntrespoff));
- memcpy(&ntlmbuf[size], ntresp, 0x18);
- size += 0x18;
- }
-
- DEBUG_OUT({
- fprintf(stderr, "\n ntresp=");
- print_hex(stderr, (char *)&ntlmbuf[ntrespoff], 0x18);
- });
-
-#endif
-
- DEBUG_OUT({
- fprintf(stderr, "\n flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ",
- LONGQUARTET(ntlm->flags), ntlm->flags);
- print_flags(stderr, ntlm->flags);
- fprintf(stderr, "\n****\n");
- });
-
-
- /* Make sure that the domain, user and host strings fit in the target
- buffer before we copy them there. */
- if(size + userlen + domlen + hostlen >= sizeof(ntlmbuf)) {
- failf(conn->data, "user + domain + host name too big");
- return CURLE_OUT_OF_MEMORY;
- }
-
- curlassert(size == domoff);
- memcpy(&ntlmbuf[size], domain, domlen);
- size += domlen;
-
- curlassert(size == useroff);
- memcpy(&ntlmbuf[size], user, userlen);
- size += userlen;
-
- curlassert(size == hostoff);
- memcpy(&ntlmbuf[size], host, hostlen);
- size += hostlen;
-
-#ifdef CURL_DOES_CONVERSIONS
- /* convert domain, user, and host to ASCII but leave the rest as-is */
- if(CURLE_OK != Curl_convert_to_network(conn->data,
- (char *)&ntlmbuf[domoff],
- size-domoff)) {
- return CURLE_CONV_FAILED;
- }
-#endif /* CURL_DOES_CONVERSIONS */
-
-#endif
-
- /* convert the binary blob into base64 */
- size = Curl_base64_encode(NULL, (char *)ntlmbuf, size, &base64);
-
- if(size >0 ) {
- Curl_safefree(*allocuserpwd);
- *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
- proxy?"Proxy-":"",
- base64);
- DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
- free(base64);
- }
- else
- return CURLE_OUT_OF_MEMORY; /* FIX TODO */
-
- ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
- authp->done = TRUE;
- }
- break;
-
- case NTLMSTATE_TYPE3:
- /* connection is already authenticated,
- * don't send a header in future requests */
- if(*allocuserpwd) {
- free(*allocuserpwd);
- *allocuserpwd=NULL;
- }
- authp->done = TRUE;
- break;
- }
-
- return CURLE_OK;
-}
-
-
-void
-Curl_ntlm_cleanup(struct connectdata *conn)
-{
-#ifdef USE_WINDOWS_SSPI
- ntlm_sspi_cleanup(&conn->ntlm);
- ntlm_sspi_cleanup(&conn->proxyntlm);
- if (s_hSecDll != NULL) {
- FreeLibrary(s_hSecDll);
- s_hSecDll = NULL;
- s_pSecFn = NULL;
- }
-#else
- (void)conn;
-#endif
-}
-
-#endif /* USE_NTLM */
-#endif /* !CURL_DISABLE_HTTP */
diff --git a/Utilities/cmcurl/http_ntlm.h b/Utilities/cmcurl/http_ntlm.h
deleted file mode 100644
index a8de220a7..000000000
--- a/Utilities/cmcurl/http_ntlm.h
+++ /dev/null
@@ -1,146 +0,0 @@
-#ifndef __HTTP_NTLM_H
-#define __HTTP_NTLM_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-typedef enum {
- CURLNTLM_NONE, /* not a ntlm */
- CURLNTLM_BAD, /* an ntlm, but one we don't like */
- CURLNTLM_FIRST, /* the first 401-reply we got with NTLM */
- CURLNTLM_FINE, /* an ntlm we act on */
-
- CURLNTLM_LAST /* last entry in this enum, don't use */
-} CURLntlm;
-
-/* this is for ntlm header input */
-CURLntlm Curl_input_ntlm(struct connectdata *conn, bool proxy, char *header);
-
-/* this is for creating ntlm header output */
-CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy);
-
-void Curl_ntlm_cleanup(struct connectdata *conn);
-#ifndef USE_NTLM
-#define Curl_ntlm_cleanup(x)
-#endif
-
-
-/* Flag bits definitions based on http://davenport.sourceforge.net/ntlm.html */
-
-#define NTLMFLAG_NEGOTIATE_UNICODE (1<<0)
-/* Indicates that Unicode strings are supported for use in security buffer
- data. */
-
-#define NTLMFLAG_NEGOTIATE_OEM (1<<1)
-/* Indicates that OEM strings are supported for use in security buffer data. */
-
-#define NTLMFLAG_REQUEST_TARGET (1<<2)
-/* Requests that the server's authentication realm be included in the Type 2
- message. */
-
-/* unknown (1<<3) */
-#define NTLMFLAG_NEGOTIATE_SIGN (1<<4)
-/* Specifies that authenticated communication between the client and server
- should carry a digital signature (message integrity). */
-
-#define NTLMFLAG_NEGOTIATE_SEAL (1<<5)
-/* Specifies that authenticated communication between the client and server
- should be encrypted (message confidentiality). */
-
-#define NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE (1<<6)
-/* unknown purpose */
-
-#define NTLMFLAG_NEGOTIATE_LM_KEY (1<<7)
-/* Indicates that the LAN Manager session key should be used for signing and
- sealing authenticated communications. */
-
-#define NTLMFLAG_NEGOTIATE_NETWARE (1<<8)
-/* unknown purpose */
-
-#define NTLMFLAG_NEGOTIATE_NTLM_KEY (1<<9)
-/* Indicates that NTLM authentication is being used. */
-
-/* unknown (1<<10) */
-/* unknown (1<<11) */
-
-#define NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED (1<<12)
-/* Sent by the client in the Type 1 message to indicate that a desired
- authentication realm is included in the message. */
-
-#define NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED (1<<13)
-/* Sent by the client in the Type 1 message to indicate that the client
- workstation's name is included in the message. */
-
-#define NTLMFLAG_NEGOTIATE_LOCAL_CALL (1<<14)
-/* Sent by the server to indicate that the server and client are on the same
- machine. Implies that the client may use a pre-established local security
- context rather than responding to the challenge. */
-
-#define NTLMFLAG_NEGOTIATE_ALWAYS_SIGN (1<<15)
-/* Indicates that authenticated communication between the client and server
- should be signed with a "dummy" signature. */
-
-#define NTLMFLAG_TARGET_TYPE_DOMAIN (1<<16)
-/* Sent by the server in the Type 2 message to indicate that the target
- authentication realm is a domain. */
-
-#define NTLMFLAG_TARGET_TYPE_SERVER (1<<17)
-/* Sent by the server in the Type 2 message to indicate that the target
- authentication realm is a server. */
-
-#define NTLMFLAG_TARGET_TYPE_SHARE (1<<18)
-/* Sent by the server in the Type 2 message to indicate that the target
- authentication realm is a share. Presumably, this is for share-level
- authentication. Usage is unclear. */
-
-#define NTLMFLAG_NEGOTIATE_NTLM2_KEY (1<<19)
-/* Indicates that the NTLM2 signing and sealing scheme should be used for
- protecting authenticated communications. */
-
-#define NTLMFLAG_REQUEST_INIT_RESPONSE (1<<20)
-/* unknown purpose */
-
-#define NTLMFLAG_REQUEST_ACCEPT_RESPONSE (1<<21)
-/* unknown purpose */
-
-#define NTLMFLAG_REQUEST_NONNT_SESSION_KEY (1<<22)
-/* unknown purpose */
-
-#define NTLMFLAG_NEGOTIATE_TARGET_INFO (1<<23)
-/* Sent by the server in the Type 2 message to indicate that it is including a
- Target Information block in the message. */
-
-/* unknown (1<24) */
-/* unknown (1<25) */
-/* unknown (1<26) */
-/* unknown (1<27) */
-/* unknown (1<28) */
-
-#define NTLMFLAG_NEGOTIATE_128 (1<<29)
-/* Indicates that 128-bit encryption is supported. */
-
-#define NTLMFLAG_NEGOTIATE_KEY_EXCHANGE (1<<30)
-/* unknown purpose */
-
-#define NTLMFLAG_NEGOTIATE_56 (1<<31)
-/* Indicates that 56-bit encryption is supported. */
-#endif
diff --git a/Utilities/cmcurl/if2ip.c b/Utilities/cmcurl/if2ip.c
deleted file mode 100644
index b4a98c662..000000000
--- a/Utilities/cmcurl/if2ip.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "if2ip.h"
-
-/*
- * This test can probably be simplified to #if defined(SIOCGIFADDR) and
- * moved after the following includes.
- */
-#if !defined(WIN32) && !defined(__BEOS__) && !defined(__CYGWIN__) && \
- !defined(__riscos__) && !defined(__INTERIX) && !defined(NETWARE) && \
- !defined(_AMIGASF) && !defined(__minix)
-
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-
-#ifdef HAVE_SYS_TIME_H
-/* This must be before net/if.h for AIX 3.2 to enjoy life */
-#include <sys/time.h>
-#endif
-#ifdef HAVE_NET_IF_H
-#include <net/if.h>
-#endif
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-
-#ifdef HAVE_SYS_SOCKIO_H
-#include <sys/sockio.h>
-#endif
-
-#ifdef VMS
-#include <inet.h>
-#endif
-
-#include "inet_ntop.h"
-#include "memory.h"
-
-/* The last #include file should be: */
-#include "memdebug.h"
-
-#define SYS_ERROR -1
-
-char *Curl_if2ip(const char *interface, char *buf, int buf_size)
-{
- int dummy;
- char *ip=NULL;
-
- if(!interface)
- return NULL;
-
- dummy = socket(AF_INET, SOCK_STREAM, 0);
- if (SYS_ERROR == dummy) {
- return NULL;
- }
- else {
- struct ifreq req;
- size_t len = strlen(interface);
- memset(&req, 0, sizeof(req));
- if(len >= sizeof(req.ifr_name))
- return NULL; /* this can't be a fine interface name */
- memcpy(req.ifr_name, interface, len+1);
- req.ifr_addr.sa_family = AF_INET;
-#ifdef IOCTL_3_ARGS
- if (SYS_ERROR == ioctl(dummy, SIOCGIFADDR, &req)) {
-#else
- if (SYS_ERROR == ioctl(dummy, SIOCGIFADDR, &req, sizeof(req))) {
-#endif
- sclose(dummy);
- return NULL;
- }
- else {
- struct in_addr in;
-
- struct sockaddr_in *s = (struct sockaddr_in *)&req.ifr_dstaddr;
- memcpy(&in, &s->sin_addr, sizeof(in));
- ip = (char *) Curl_inet_ntop(s->sin_family, &in, buf, buf_size);
- }
- sclose(dummy);
- }
- return ip;
-}
-
-/* -- end of if2ip() -- */
-#else
-char *Curl_if2ip(const char *interf, char *buf, int buf_size)
-{
- (void) interf;
- (void) buf;
- (void) buf_size;
- return NULL;
-}
-#endif
diff --git a/Utilities/cmcurl/if2ip.h b/Utilities/cmcurl/if2ip.h
deleted file mode 100644
index 4e86e2b27..000000000
--- a/Utilities/cmcurl/if2ip.h
+++ /dev/null
@@ -1,67 +0,0 @@
-#ifndef __IF2IP_H
-#define __IF2IP_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-#include "setup.h"
-
-extern char *Curl_if2ip(const char *interf, char *buf, int buf_size);
-
-#ifdef __INTERIX
-#include <sys/socket.h>
-
-/* Nedelcho Stanev's work-around for SFU 3.0 */
-struct ifreq {
-#define IFNAMSIZ 16
-#define IFHWADDRLEN 6
- union {
- char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */
- } ifr_ifrn;
-
- union {
- struct sockaddr ifru_addr;
- struct sockaddr ifru_broadaddr;
- struct sockaddr ifru_netmask;
- struct sockaddr ifru_hwaddr;
- short ifru_flags;
- int ifru_metric;
- int ifru_mtu;
- } ifr_ifru;
-};
-
-/* This define was added by Daniel to avoid an extra #ifdef INTERIX in the
- C code. */
-#define ifr_dstaddr ifr_addr
-
-#define ifr_name ifr_ifrn.ifrn_name /* interface name */
-#define ifr_addr ifr_ifru.ifru_addr /* address */
-#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
-#define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */
-#define ifr_flags ifr_ifru.ifru_flags /* flags */
-#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */
-#define ifr_metric ifr_ifru.ifru_metric /* metric */
-#define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
-
-#define SIOCGIFADDR _IOW('s', 102, struct ifreq) /* Get if addr */
-#endif /* interix */
-
-#endif
diff --git a/Utilities/cmcurl/include/curl/curl.h b/Utilities/cmcurl/include/curl/curl.h
new file mode 100644
index 000000000..86ce1ffde
--- /dev/null
+++ b/Utilities/cmcurl/include/curl/curl.h
@@ -0,0 +1,2382 @@
+#ifndef __CURL_CURL_H
+#define __CURL_CURL_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * If you have libcurl problems, all docs and details are found here:
+ * http://curl.haxx.se/libcurl/
+ *
+ * curl-library mailing list subscription and unsubscription web interface:
+ * http://cool.haxx.se/mailman/listinfo/curl-library/
+ */
+
+#include "curlver.h" /* libcurl version defines */
+#include "cmcurl/include/curl/curlbuild.h" /* libcurl build definitions */
+#include "curlrules.h" /* libcurl rules enforcement */
+
+/*
+ * Define WIN32 when build target is Win32 API
+ */
+
+#if (defined(_WIN32) || defined(__WIN32__)) && \
+ !defined(WIN32) && !defined(__SYMBIAN32__)
+#define WIN32
+#endif
+
+#include <stdio.h>
+#include <limits.h>
+
+#if defined(__FreeBSD__) && (__FreeBSD__ >= 2)
+/* Needed for __FreeBSD_version symbol definition */
+#include <osreldate.h>
+#endif
+
+/* The include stuff here below is mainly for time_t! */
+#include <sys/types.h>
+#include <time.h>
+
+#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__)
+#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || defined(__LWIP_OPT_H__))
+/* The check above prevents the winsock2 inclusion if winsock.h already was
+ included, since they can't co-exist without problems */
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#endif
+#endif
+
+/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
+ libc5-based Linux systems. Only include it on systems that are known to
+ require it! */
+#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
+ defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \
+ defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \
+ (defined(__FreeBSD_version) && (__FreeBSD_version < 800000))
+#include <sys/select.h>
+#endif
+
+#if !defined(WIN32) && !defined(_WIN32_WCE)
+#include <sys/socket.h>
+#endif
+
+#if !defined(WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__)
+#include <sys/time.h>
+#endif
+
+#if defined __BEOS__ || defined __HAIKU__
+#include <support/SupportDefs.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void CURL;
+
+/*
+ * libcurl external API function linkage decorations.
+ */
+
+#ifdef CURL_STATICLIB
+# define CURL_EXTERN
+#elif defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__)
+# if defined(BUILDING_LIBCURL)
+# define CURL_EXTERN __declspec(dllexport)
+# else
+# define CURL_EXTERN __declspec(dllimport)
+# endif
+#elif defined(BUILDING_LIBCURL) && defined(CURL_HIDDEN_SYMBOLS)
+# define CURL_EXTERN CURL_EXTERN_SYMBOL
+#else
+# define CURL_EXTERN
+#endif
+
+#ifndef curl_socket_typedef
+/* socket typedef */
+#if defined(WIN32) && !defined(__LWIP_OPT_H__)
+typedef SOCKET curl_socket_t;
+#define CURL_SOCKET_BAD INVALID_SOCKET
+#else
+typedef int curl_socket_t;
+#define CURL_SOCKET_BAD -1
+#endif
+#define curl_socket_typedef
+#endif /* curl_socket_typedef */
+
+struct curl_httppost {
+ struct curl_httppost *next; /* next entry in the list */
+ char *name; /* pointer to allocated name */
+ long namelength; /* length of name length */
+ char *contents; /* pointer to allocated data contents */
+ long contentslength; /* length of contents field */
+ char *buffer; /* pointer to allocated buffer contents */
+ long bufferlength; /* length of buffer field */
+ char *contenttype; /* Content-Type */
+ struct curl_slist* contentheader; /* list of extra headers for this form */
+ struct curl_httppost *more; /* if one field name has more than one
+ file, this link should link to following
+ files */
+ long flags; /* as defined below */
+#define HTTPPOST_FILENAME (1<<0) /* specified content is a file name */
+#define HTTPPOST_READFILE (1<<1) /* specified content is a file name */
+#define HTTPPOST_PTRNAME (1<<2) /* name is only stored pointer
+ do not free in formfree */
+#define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer
+ do not free in formfree */
+#define HTTPPOST_BUFFER (1<<4) /* upload file from buffer */
+#define HTTPPOST_PTRBUFFER (1<<5) /* upload file from pointer contents */
+#define HTTPPOST_CALLBACK (1<<6) /* upload file contents by using the
+ regular read callback to get the data
+ and pass the given pointer as custom
+ pointer */
+
+ char *showfilename; /* The file name to show. If not set, the
+ actual file name will be used (if this
+ is a file part) */
+ void *userp; /* custom pointer used for
+ HTTPPOST_CALLBACK posts */
+};
+
+/* This is the CURLOPT_PROGRESSFUNCTION callback proto. It is now considered
+ deprecated but was the only choice up until 7.31.0 */
+typedef int (*curl_progress_callback)(void *clientp,
+ double dltotal,
+ double dlnow,
+ double ultotal,
+ double ulnow);
+
+/* This is the CURLOPT_XFERINFOFUNCTION callback proto. It was introduced in
+ 7.32.0, it avoids floating point and provides more detailed information. */
+typedef int (*curl_xferinfo_callback)(void *clientp,
+ curl_off_t dltotal,
+ curl_off_t dlnow,
+ curl_off_t ultotal,
+ curl_off_t ulnow);
+
+#ifndef CURL_MAX_WRITE_SIZE
+ /* Tests have proven that 20K is a very bad buffer size for uploads on
+ Windows, while 16K for some odd reason performed a lot better.
+ We do the ifndef check to allow this value to easier be changed at build
+ time for those who feel adventurous. The practical minimum is about
+ 400 bytes since libcurl uses a buffer of this size as a scratch area
+ (unrelated to network send operations). */
+#define CURL_MAX_WRITE_SIZE 16384
+#endif
+
+#ifndef CURL_MAX_HTTP_HEADER
+/* The only reason to have a max limit for this is to avoid the risk of a bad
+ server feeding libcurl with a never-ending header that will cause reallocs
+ infinitely */
+#define CURL_MAX_HTTP_HEADER (100*1024)
+#endif
+
+/* This is a magic return code for the write callback that, when returned,
+ will signal libcurl to pause receiving on the current transfer. */
+#define CURL_WRITEFUNC_PAUSE 0x10000001
+
+typedef size_t (*curl_write_callback)(char *buffer,
+ size_t size,
+ size_t nitems,
+ void *outstream);
+
+
+
+/* enumeration of file types */
+typedef enum {
+ CURLFILETYPE_FILE = 0,
+ CURLFILETYPE_DIRECTORY,
+ CURLFILETYPE_SYMLINK,
+ CURLFILETYPE_DEVICE_BLOCK,
+ CURLFILETYPE_DEVICE_CHAR,
+ CURLFILETYPE_NAMEDPIPE,
+ CURLFILETYPE_SOCKET,
+ CURLFILETYPE_DOOR, /* is possible only on Sun Solaris now */
+
+ CURLFILETYPE_UNKNOWN /* should never occur */
+} curlfiletype;
+
+#define CURLFINFOFLAG_KNOWN_FILENAME (1<<0)
+#define CURLFINFOFLAG_KNOWN_FILETYPE (1<<1)
+#define CURLFINFOFLAG_KNOWN_TIME (1<<2)
+#define CURLFINFOFLAG_KNOWN_PERM (1<<3)
+#define CURLFINFOFLAG_KNOWN_UID (1<<4)
+#define CURLFINFOFLAG_KNOWN_GID (1<<5)
+#define CURLFINFOFLAG_KNOWN_SIZE (1<<6)
+#define CURLFINFOFLAG_KNOWN_HLINKCOUNT (1<<7)
+
+/* Content of this structure depends on information which is known and is
+ achievable (e.g. by FTP LIST parsing). Please see the url_easy_setopt(3) man
+ page for callbacks returning this structure -- some fields are mandatory,
+ some others are optional. The FLAG field has special meaning. */
+struct curl_fileinfo {
+ char *filename;
+ curlfiletype filetype;
+ time_t time;
+ unsigned int perm;
+ int uid;
+ int gid;
+ curl_off_t size;
+ long int hardlinks;
+
+ struct {
+ /* If some of these fields is not NULL, it is a pointer to b_data. */
+ char *time;
+ char *perm;
+ char *user;
+ char *group;
+ char *target; /* pointer to the target filename of a symlink */
+ } strings;
+
+ unsigned int flags;
+
+ /* used internally */
+ char * b_data;
+ size_t b_size;
+ size_t b_used;
+};
+
+/* return codes for CURLOPT_CHUNK_BGN_FUNCTION */
+#define CURL_CHUNK_BGN_FUNC_OK 0
+#define CURL_CHUNK_BGN_FUNC_FAIL 1 /* tell the lib to end the task */
+#define CURL_CHUNK_BGN_FUNC_SKIP 2 /* skip this chunk over */
+
+/* if splitting of data transfer is enabled, this callback is called before
+ download of an individual chunk started. Note that parameter "remains" works
+ only for FTP wildcard downloading (for now), otherwise is not used */
+typedef long (*curl_chunk_bgn_callback)(const void *transfer_info,
+ void *ptr,
+ int remains);
+
+/* return codes for CURLOPT_CHUNK_END_FUNCTION */
+#define CURL_CHUNK_END_FUNC_OK 0
+#define CURL_CHUNK_END_FUNC_FAIL 1 /* tell the lib to end the task */
+
+/* If splitting of data transfer is enabled this callback is called after
+ download of an individual chunk finished.
+ Note! After this callback was set then it have to be called FOR ALL chunks.
+ Even if downloading of this chunk was skipped in CHUNK_BGN_FUNC.
+ This is the reason why we don't need "transfer_info" parameter in this
+ callback and we are not interested in "remains" parameter too. */
+typedef long (*curl_chunk_end_callback)(void *ptr);
+
+/* return codes for FNMATCHFUNCTION */
+#define CURL_FNMATCHFUNC_MATCH 0 /* string corresponds to the pattern */
+#define CURL_FNMATCHFUNC_NOMATCH 1 /* pattern doesn't match the string */
+#define CURL_FNMATCHFUNC_FAIL 2 /* an error occurred */
+
+/* callback type for wildcard downloading pattern matching. If the
+ string matches the pattern, return CURL_FNMATCHFUNC_MATCH value, etc. */
+typedef int (*curl_fnmatch_callback)(void *ptr,
+ const char *pattern,
+ const char *string);
+
+/* These are the return codes for the seek callbacks */
+#define CURL_SEEKFUNC_OK 0
+#define CURL_SEEKFUNC_FAIL 1 /* fail the entire transfer */
+#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking can't be done, so
+ libcurl might try other means instead */
+typedef int (*curl_seek_callback)(void *instream,
+ curl_off_t offset,
+ int origin); /* 'whence' */
+
+/* This is a return code for the read callback that, when returned, will
+ signal libcurl to immediately abort the current transfer. */
+#define CURL_READFUNC_ABORT 0x10000000
+/* This is a return code for the read callback that, when returned, will
+ signal libcurl to pause sending data on the current transfer. */
+#define CURL_READFUNC_PAUSE 0x10000001
+
+typedef size_t (*curl_read_callback)(char *buffer,
+ size_t size,
+ size_t nitems,
+ void *instream);
+
+typedef enum {
+ CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */
+ CURLSOCKTYPE_ACCEPT, /* socket created by accept() call */
+ CURLSOCKTYPE_LAST /* never use */
+} curlsocktype;
+
+/* The return code from the sockopt_callback can signal information back
+ to libcurl: */
+#define CURL_SOCKOPT_OK 0
+#define CURL_SOCKOPT_ERROR 1 /* causes libcurl to abort and return
+ CURLE_ABORTED_BY_CALLBACK */
+#define CURL_SOCKOPT_ALREADY_CONNECTED 2
+
+typedef int (*curl_sockopt_callback)(void *clientp,
+ curl_socket_t curlfd,
+ curlsocktype purpose);
+
+struct curl_sockaddr {
+ int family;
+ int socktype;
+ int protocol;
+ unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it
+ turned really ugly and painful on the systems that
+ lack this type */
+ struct sockaddr addr;
+};
+
+typedef curl_socket_t
+(*curl_opensocket_callback)(void *clientp,
+ curlsocktype purpose,
+ struct curl_sockaddr *address);
+
+typedef int
+(*curl_closesocket_callback)(void *clientp, curl_socket_t item);
+
+typedef enum {
+ CURLIOE_OK, /* I/O operation successful */
+ CURLIOE_UNKNOWNCMD, /* command was unknown to callback */
+ CURLIOE_FAILRESTART, /* failed to restart the read */
+ CURLIOE_LAST /* never use */
+} curlioerr;
+
+typedef enum {
+ CURLIOCMD_NOP, /* no operation */
+ CURLIOCMD_RESTARTREAD, /* restart the read stream from start */
+ CURLIOCMD_LAST /* never use */
+} curliocmd;
+
+typedef curlioerr (*curl_ioctl_callback)(CURL *handle,
+ int cmd,
+ void *clientp);
+
+/*
+ * The following typedef's are signatures of malloc, free, realloc, strdup and
+ * calloc respectively. Function pointers of these types can be passed to the
+ * curl_global_init_mem() function to set user defined memory management
+ * callback routines.
+ */
+typedef void *(*curl_malloc_callback)(size_t size);
+typedef void (*curl_free_callback)(void *ptr);
+typedef void *(*curl_realloc_callback)(void *ptr, size_t size);
+typedef char *(*curl_strdup_callback)(const char *str);
+typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size);
+
+/* the kind of data that is passed to information_callback*/
+typedef enum {
+ CURLINFO_TEXT = 0,
+ CURLINFO_HEADER_IN, /* 1 */
+ CURLINFO_HEADER_OUT, /* 2 */
+ CURLINFO_DATA_IN, /* 3 */
+ CURLINFO_DATA_OUT, /* 4 */
+ CURLINFO_SSL_DATA_IN, /* 5 */
+ CURLINFO_SSL_DATA_OUT, /* 6 */
+ CURLINFO_END
+} curl_infotype;
+
+typedef int (*curl_debug_callback)
+ (CURL *handle, /* the handle/transfer this concerns */
+ curl_infotype type, /* what kind of data */
+ char *data, /* points to the data */
+ size_t size, /* size of the data pointed to */
+ void *userptr); /* whatever the user please */
+
+/* All possible error codes from all sorts of curl functions. Future versions
+ may return other values, stay prepared.
+
+ Always add new return codes last. Never *EVER* remove any. The return
+ codes must remain the same!
+ */
+
+typedef enum {
+ CURLE_OK = 0,
+ CURLE_UNSUPPORTED_PROTOCOL, /* 1 */
+ CURLE_FAILED_INIT, /* 2 */
+ CURLE_URL_MALFORMAT, /* 3 */
+ CURLE_NOT_BUILT_IN, /* 4 - [was obsoleted in August 2007 for
+ 7.17.0, reused in April 2011 for 7.21.5] */
+ CURLE_COULDNT_RESOLVE_PROXY, /* 5 */
+ CURLE_COULDNT_RESOLVE_HOST, /* 6 */
+ CURLE_COULDNT_CONNECT, /* 7 */
+ CURLE_FTP_WEIRD_SERVER_REPLY, /* 8 */
+ CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server
+ due to lack of access - when login fails
+ this is not returned. */
+ CURLE_FTP_ACCEPT_FAILED, /* 10 - [was obsoleted in April 2006 for
+ 7.15.4, reused in Dec 2011 for 7.24.0]*/
+ CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */
+ CURLE_FTP_ACCEPT_TIMEOUT, /* 12 - timeout occurred accepting server
+ [was obsoleted in August 2007 for 7.17.0,
+ reused in Dec 2011 for 7.24.0]*/
+ CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */
+ CURLE_FTP_WEIRD_227_FORMAT, /* 14 */
+ CURLE_FTP_CANT_GET_HOST, /* 15 */
+ CURLE_HTTP2, /* 16 - A problem in the http2 framing layer.
+ [was obsoleted in August 2007 for 7.17.0,
+ reused in July 2014 for 7.38.0] */
+ CURLE_FTP_COULDNT_SET_TYPE, /* 17 */
+ CURLE_PARTIAL_FILE, /* 18 */
+ CURLE_FTP_COULDNT_RETR_FILE, /* 19 */
+ CURLE_OBSOLETE20, /* 20 - NOT USED */
+ CURLE_QUOTE_ERROR, /* 21 - quote command failure */
+ CURLE_HTTP_RETURNED_ERROR, /* 22 */
+ CURLE_WRITE_ERROR, /* 23 */
+ CURLE_OBSOLETE24, /* 24 - NOT USED */
+ CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */
+ CURLE_READ_ERROR, /* 26 - couldn't open/read from file */
+ CURLE_OUT_OF_MEMORY, /* 27 */
+ /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error
+ instead of a memory allocation error if CURL_DOES_CONVERSIONS
+ is defined
+ */
+ CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */
+ CURLE_OBSOLETE29, /* 29 - NOT USED */
+ CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */
+ CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */
+ CURLE_OBSOLETE32, /* 32 - NOT USED */
+ CURLE_RANGE_ERROR, /* 33 - RANGE "command" didn't work */
+ CURLE_HTTP_POST_ERROR, /* 34 */
+ CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */
+ CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */
+ CURLE_FILE_COULDNT_READ_FILE, /* 37 */
+ CURLE_LDAP_CANNOT_BIND, /* 38 */
+ CURLE_LDAP_SEARCH_FAILED, /* 39 */
+ CURLE_OBSOLETE40, /* 40 - NOT USED */
+ CURLE_FUNCTION_NOT_FOUND, /* 41 */
+ CURLE_ABORTED_BY_CALLBACK, /* 42 */
+ CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */
+ CURLE_OBSOLETE44, /* 44 - NOT USED */
+ CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */
+ CURLE_OBSOLETE46, /* 46 - NOT USED */
+ CURLE_TOO_MANY_REDIRECTS , /* 47 - catch endless re-direct loops */
+ CURLE_UNKNOWN_OPTION, /* 48 - User specified an unknown option */
+ CURLE_TELNET_OPTION_SYNTAX , /* 49 - Malformed telnet option */
+ CURLE_OBSOLETE50, /* 50 - NOT USED */
+ CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint
+ wasn't verified fine */
+ CURLE_GOT_NOTHING, /* 52 - when this is a specific error */
+ CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */
+ CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as
+ default */
+ CURLE_SEND_ERROR, /* 55 - failed sending network data */
+ CURLE_RECV_ERROR, /* 56 - failure in receiving network data */
+ CURLE_OBSOLETE57, /* 57 - NOT IN USE */
+ CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */
+ CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */
+ CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */
+ CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized/bad encoding */
+ CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */
+ CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */
+ CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */
+ CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind
+ that failed */
+ CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */
+ CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not
+ accepted and we failed to login */
+ CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */
+ CURLE_TFTP_PERM, /* 69 - permission problem on server */
+ CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */
+ CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */
+ CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */
+ CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */
+ CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */
+ CURLE_CONV_FAILED, /* 75 - conversion failed */
+ CURLE_CONV_REQD, /* 76 - caller must register conversion
+ callbacks using curl_easy_setopt options
+ CURLOPT_CONV_FROM_NETWORK_FUNCTION,
+ CURLOPT_CONV_TO_NETWORK_FUNCTION, and
+ CURLOPT_CONV_FROM_UTF8_FUNCTION */
+ CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing
+ or wrong format */
+ CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */
+ CURLE_SSH, /* 79 - error from the SSH layer, somewhat
+ generic so the error message will be of
+ interest when this has happened */
+
+ CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL
+ connection */
+ CURLE_AGAIN, /* 81 - socket is not ready for send/recv,
+ wait till it's ready and try again (Added
+ in 7.18.2) */
+ CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or
+ wrong format (Added in 7.19.0) */
+ CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in
+ 7.19.0) */
+ CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */
+ CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */
+ CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Ids */
+ CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */
+ CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */
+ CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the
+ session will be queued */
+ CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not
+ match */
+ CURLE_SSL_INVALIDCERTSTATUS, /* 91 - invalid certificate status */
+ CURL_LAST /* never use! */
+} CURLcode;
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+ the obsolete stuff removed! */
+
+/* Previously obsolete error code re-used in 7.38.0 */
+#define CURLE_OBSOLETE16 CURLE_HTTP2
+
+/* Previously obsolete error codes re-used in 7.24.0 */
+#define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED
+#define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT
+
+/* compatibility with older names */
+#define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING
+
+/* The following were added in 7.21.5, April 2011 */
+#define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION
+
+/* The following were added in 7.17.1 */
+/* These are scheduled to disappear by 2009 */
+#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION
+
+/* The following were added in 7.17.0 */
+/* These are scheduled to disappear by 2009 */
+#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* no one should be using this! */
+#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46
+#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44
+#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10
+#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16
+#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32
+#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29
+#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12
+#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20
+#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40
+#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24
+#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57
+#define CURLE_URL_MALFORMAT_USER CURLE_NOT_BUILT_IN
+
+#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED
+#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE
+#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR
+#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL
+#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS
+#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR
+#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED
+
+/* The following were added earlier */
+
+#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT
+
+#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR
+#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED
+#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED
+
+#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE
+#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME
+
+/* This was the error code 50 in 7.7.3 and a few earlier versions, this
+ is no longer used by libcurl but is instead #defined here only to not
+ make programs break */
+#define CURLE_ALREADY_COMPLETE 99999
+
+/* Provide defines for really old option names */
+#define CURLOPT_FILE CURLOPT_WRITEDATA /* name changed in 7.9.7 */
+#define CURLOPT_INFILE CURLOPT_READDATA /* name changed in 7.9.7 */
+#define CURLOPT_WRITEHEADER CURLOPT_HEADERDATA
+
+/* Since long deprecated options with no code in the lib that does anything
+ with them. */
+#define CURLOPT_WRITEINFO CURLOPT_OBSOLETE40
+#define CURLOPT_CLOSEPOLICY CURLOPT_OBSOLETE72
+
+#endif /*!CURL_NO_OLDIES*/
+
+/* This prototype applies to all conversion callbacks */
+typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length);
+
+typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */
+ void *ssl_ctx, /* actually an
+ OpenSSL SSL_CTX */
+ void *userptr);
+
+typedef enum {
+ CURLPROXY_HTTP = 0, /* added in 7.10, new in 7.19.4 default is to use
+ CONNECT HTTP/1.1 */
+ CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT
+ HTTP/1.0 */
+ CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already
+ in 7.10 */
+ CURLPROXY_SOCKS5 = 5, /* added in 7.10 */
+ CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */
+ CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the
+ host name rather than the IP address. added
+ in 7.18.0 */
+} curl_proxytype; /* this enum was added in 7.10 */
+
+/*
+ * Bitmasks for CURLOPT_HTTPAUTH and CURLOPT_PROXYAUTH options:
+ *
+ * CURLAUTH_NONE - No HTTP authentication
+ * CURLAUTH_BASIC - HTTP Basic authentication (default)
+ * CURLAUTH_DIGEST - HTTP Digest authentication
+ * CURLAUTH_NEGOTIATE - HTTP Negotiate (SPNEGO) authentication
+ * CURLAUTH_GSSNEGOTIATE - Alias for CURLAUTH_NEGOTIATE (deprecated)
+ * CURLAUTH_NTLM - HTTP NTLM authentication
+ * CURLAUTH_DIGEST_IE - HTTP Digest authentication with IE flavour
+ * CURLAUTH_NTLM_WB - HTTP NTLM authentication delegated to winbind helper
+ * CURLAUTH_ONLY - Use together with a single other type to force no
+ * authentication or just that single type
+ * CURLAUTH_ANY - All fine types set
+ * CURLAUTH_ANYSAFE - All fine types except Basic
+ */
+
+#define CURLAUTH_NONE ((unsigned long)0)
+#define CURLAUTH_BASIC (((unsigned long)1)<<0)
+#define CURLAUTH_DIGEST (((unsigned long)1)<<1)
+#define CURLAUTH_NEGOTIATE (((unsigned long)1)<<2)
+/* Deprecated since the advent of CURLAUTH_NEGOTIATE */
+#define CURLAUTH_GSSNEGOTIATE CURLAUTH_NEGOTIATE
+#define CURLAUTH_NTLM (((unsigned long)1)<<3)
+#define CURLAUTH_DIGEST_IE (((unsigned long)1)<<4)
+#define CURLAUTH_NTLM_WB (((unsigned long)1)<<5)
+#define CURLAUTH_ONLY (((unsigned long)1)<<31)
+#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE)
+#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE))
+
+#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */
+#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */
+#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */
+#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */
+#define CURLSSH_AUTH_HOST (1<<2) /* host key files */
+#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */
+#define CURLSSH_AUTH_AGENT (1<<4) /* agent (ssh-agent, pageant...) */
+#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY
+
+#define CURLGSSAPI_DELEGATION_NONE 0 /* no delegation (default) */
+#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */
+#define CURLGSSAPI_DELEGATION_FLAG (1<<1) /* delegate always */
+
+#define CURL_ERROR_SIZE 256
+
+enum curl_khtype {
+ CURLKHTYPE_UNKNOWN,
+ CURLKHTYPE_RSA1,
+ CURLKHTYPE_RSA,
+ CURLKHTYPE_DSS
+};
+
+struct curl_khkey {
+ const char *key; /* points to a zero-terminated string encoded with base64
+ if len is zero, otherwise to the "raw" data */
+ size_t len;
+ enum curl_khtype keytype;
+};
+
+/* this is the set of return values expected from the curl_sshkeycallback
+ callback */
+enum curl_khstat {
+ CURLKHSTAT_FINE_ADD_TO_FILE,
+ CURLKHSTAT_FINE,
+ CURLKHSTAT_REJECT, /* reject the connection, return an error */
+ CURLKHSTAT_DEFER, /* do not accept it, but we can't answer right now so
+ this causes a CURLE_DEFER error but otherwise the
+ connection will be left intact etc */
+ CURLKHSTAT_LAST /* not for use, only a marker for last-in-list */
+};
+
+/* this is the set of status codes pass in to the callback */
+enum curl_khmatch {
+ CURLKHMATCH_OK, /* match */
+ CURLKHMATCH_MISMATCH, /* host found, key mismatch! */
+ CURLKHMATCH_MISSING, /* no matching host/key found */
+ CURLKHMATCH_LAST /* not for use, only a marker for last-in-list */
+};
+
+typedef int
+ (*curl_sshkeycallback) (CURL *easy, /* easy handle */
+ const struct curl_khkey *knownkey, /* known */
+ const struct curl_khkey *foundkey, /* found */
+ enum curl_khmatch, /* libcurl's view on the keys */
+ void *clientp); /* custom pointer passed from app */
+
+/* parameter for the CURLOPT_USE_SSL option */
+typedef enum {
+ CURLUSESSL_NONE, /* do not attempt to use SSL */
+ CURLUSESSL_TRY, /* try using SSL, proceed anyway otherwise */
+ CURLUSESSL_CONTROL, /* SSL for the control connection or fail */
+ CURLUSESSL_ALL, /* SSL for all communication or fail */
+ CURLUSESSL_LAST /* not an option, never use */
+} curl_usessl;
+
+/* Definition of bits for the CURLOPT_SSL_OPTIONS argument: */
+
+/* - ALLOW_BEAST tells libcurl to allow the BEAST SSL vulnerability in the
+ name of improving interoperability with older servers. Some SSL libraries
+ have introduced work-arounds for this flaw but those work-arounds sometimes
+ make the SSL communication fail. To regain functionality with those broken
+ servers, a user can this way allow the vulnerability back. */
+#define CURLSSLOPT_ALLOW_BEAST (1<<0)
+
+/* - NO_REVOKE tells libcurl to disable certificate revocation checks for those
+ SSL backends where such behavior is present. */
+#define CURLSSLOPT_NO_REVOKE (1<<1)
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+ the obsolete stuff removed! */
+
+/* Backwards compatibility with older names */
+/* These are scheduled to disappear by 2009 */
+
+#define CURLFTPSSL_NONE CURLUSESSL_NONE
+#define CURLFTPSSL_TRY CURLUSESSL_TRY
+#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL
+#define CURLFTPSSL_ALL CURLUSESSL_ALL
+#define CURLFTPSSL_LAST CURLUSESSL_LAST
+#define curl_ftpssl curl_usessl
+#endif /*!CURL_NO_OLDIES*/
+
+/* parameter for the CURLOPT_FTP_SSL_CCC option */
+typedef enum {
+ CURLFTPSSL_CCC_NONE, /* do not send CCC */
+ CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */
+ CURLFTPSSL_CCC_ACTIVE, /* Initiate the shutdown */
+ CURLFTPSSL_CCC_LAST /* not an option, never use */
+} curl_ftpccc;
+
+/* parameter for the CURLOPT_FTPSSLAUTH option */
+typedef enum {
+ CURLFTPAUTH_DEFAULT, /* let libcurl decide */
+ CURLFTPAUTH_SSL, /* use "AUTH SSL" */
+ CURLFTPAUTH_TLS, /* use "AUTH TLS" */
+ CURLFTPAUTH_LAST /* not an option, never use */
+} curl_ftpauth;
+
+/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */
+typedef enum {
+ CURLFTP_CREATE_DIR_NONE, /* do NOT create missing dirs! */
+ CURLFTP_CREATE_DIR, /* (FTP/SFTP) if CWD fails, try MKD and then CWD
+ again if MKD succeeded, for SFTP this does
+ similar magic */
+ CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD
+ again even if MKD failed! */
+ CURLFTP_CREATE_DIR_LAST /* not an option, never use */
+} curl_ftpcreatedir;
+
+/* parameter for the CURLOPT_FTP_FILEMETHOD option */
+typedef enum {
+ CURLFTPMETHOD_DEFAULT, /* let libcurl pick */
+ CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */
+ CURLFTPMETHOD_NOCWD, /* no CWD at all */
+ CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */
+ CURLFTPMETHOD_LAST /* not an option, never use */
+} curl_ftpmethod;
+
+/* bitmask defines for CURLOPT_HEADEROPT */
+#define CURLHEADER_UNIFIED 0
+#define CURLHEADER_SEPARATE (1<<0)
+
+/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */
+#define CURLPROTO_HTTP (1<<0)
+#define CURLPROTO_HTTPS (1<<1)
+#define CURLPROTO_FTP (1<<2)
+#define CURLPROTO_FTPS (1<<3)
+#define CURLPROTO_SCP (1<<4)
+#define CURLPROTO_SFTP (1<<5)
+#define CURLPROTO_TELNET (1<<6)
+#define CURLPROTO_LDAP (1<<7)
+#define CURLPROTO_LDAPS (1<<8)
+#define CURLPROTO_DICT (1<<9)
+#define CURLPROTO_FILE (1<<10)
+#define CURLPROTO_TFTP (1<<11)
+#define CURLPROTO_IMAP (1<<12)
+#define CURLPROTO_IMAPS (1<<13)
+#define CURLPROTO_POP3 (1<<14)
+#define CURLPROTO_POP3S (1<<15)
+#define CURLPROTO_SMTP (1<<16)
+#define CURLPROTO_SMTPS (1<<17)
+#define CURLPROTO_RTSP (1<<18)
+#define CURLPROTO_RTMP (1<<19)
+#define CURLPROTO_RTMPT (1<<20)
+#define CURLPROTO_RTMPE (1<<21)
+#define CURLPROTO_RTMPTE (1<<22)
+#define CURLPROTO_RTMPS (1<<23)
+#define CURLPROTO_RTMPTS (1<<24)
+#define CURLPROTO_GOPHER (1<<25)
+#define CURLPROTO_SMB (1<<26)
+#define CURLPROTO_SMBS (1<<27)
+#define CURLPROTO_ALL (~0) /* enable everything */
+
+/* long may be 32 or 64 bits, but we should never depend on anything else
+ but 32 */
+#define CURLOPTTYPE_LONG 0
+#define CURLOPTTYPE_OBJECTPOINT 10000
+#define CURLOPTTYPE_FUNCTIONPOINT 20000
+#define CURLOPTTYPE_OFF_T 30000
+
+/* name is uppercase CURLOPT_<name>,
+ type is one of the defined CURLOPTTYPE_<type>
+ number is unique identifier */
+#ifdef CINIT
+#undef CINIT
+#endif
+
+#ifdef CURL_ISOCPP
+#define CINIT(na,t,nu) CURLOPT_ ## na = CURLOPTTYPE_ ## t + nu
+#else
+/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
+#define LONG CURLOPTTYPE_LONG
+#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT
+#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT
+#define OFF_T CURLOPTTYPE_OFF_T
+#define CINIT(name,type,number) CURLOPT_/**/name = type + number
+#endif
+
+/*
+ * This macro-mania below setups the CURLOPT_[what] enum, to be used with
+ * curl_easy_setopt(). The first argument in the CINIT() macro is the [what]
+ * word.
+ */
+
+typedef enum {
+ /* This is the FILE * or void * the regular output should be written to. */
+ CINIT(WRITEDATA, OBJECTPOINT, 1),
+
+ /* The full URL to get/put */
+ CINIT(URL, OBJECTPOINT, 2),
+
+ /* Port number to connect to, if other than default. */
+ CINIT(PORT, LONG, 3),
+
+ /* Name of proxy to use. */
+ CINIT(PROXY, OBJECTPOINT, 4),
+
+ /* "user:password;options" to use when fetching. */
+ CINIT(USERPWD, OBJECTPOINT, 5),
+
+ /* "user:password" to use with proxy. */
+ CINIT(PROXYUSERPWD, OBJECTPOINT, 6),
+
+ /* Range to get, specified as an ASCII string. */
+ CINIT(RANGE, OBJECTPOINT, 7),
+
+ /* not used */
+
+ /* Specified file stream to upload from (use as input): */
+ CINIT(READDATA, OBJECTPOINT, 9),
+
+ /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE
+ * bytes big. If this is not used, error messages go to stderr instead: */
+ CINIT(ERRORBUFFER, OBJECTPOINT, 10),
+
+ /* Function that will be called to store the output (instead of fwrite). The
+ * parameters will use fwrite() syntax, make sure to follow them. */
+ CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11),
+
+ /* Function that will be called to read the input (instead of fread). The
+ * parameters will use fread() syntax, make sure to follow them. */
+ CINIT(READFUNCTION, FUNCTIONPOINT, 12),
+
+ /* Time-out the read operation after this amount of seconds */
+ CINIT(TIMEOUT, LONG, 13),
+
+ /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about
+ * how large the file being sent really is. That allows better error
+ * checking and better verifies that the upload was successful. -1 means
+ * unknown size.
+ *
+ * For large file support, there is also a _LARGE version of the key
+ * which takes an off_t type, allowing platforms with larger off_t
+ * sizes to handle larger files. See below for INFILESIZE_LARGE.
+ */
+ CINIT(INFILESIZE, LONG, 14),
+
+ /* POST static input fields. */
+ CINIT(POSTFIELDS, OBJECTPOINT, 15),
+
+ /* Set the referrer page (needed by some CGIs) */
+ CINIT(REFERER, OBJECTPOINT, 16),
+
+ /* Set the FTP PORT string (interface name, named or numerical IP address)
+ Use i.e '-' to use default address. */
+ CINIT(FTPPORT, OBJECTPOINT, 17),
+
+ /* Set the User-Agent string (examined by some CGIs) */
+ CINIT(USERAGENT, OBJECTPOINT, 18),
+
+ /* If the download receives less than "low speed limit" bytes/second
+ * during "low speed time" seconds, the operations is aborted.
+ * You could i.e if you have a pretty high speed connection, abort if
+ * it is less than 2000 bytes/sec during 20 seconds.
+ */
+
+ /* Set the "low speed limit" */
+ CINIT(LOW_SPEED_LIMIT, LONG, 19),
+
+ /* Set the "low speed time" */
+ CINIT(LOW_SPEED_TIME, LONG, 20),
+
+ /* Set the continuation offset.
+ *
+ * Note there is also a _LARGE version of this key which uses
+ * off_t types, allowing for large file offsets on platforms which
+ * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE.
+ */
+ CINIT(RESUME_FROM, LONG, 21),
+
+ /* Set cookie in request: */
+ CINIT(COOKIE, OBJECTPOINT, 22),
+
+ /* This points to a linked list of headers, struct curl_slist kind. This
+ list is also used for RTSP (in spite of its name) */
+ CINIT(HTTPHEADER, OBJECTPOINT, 23),
+
+ /* This points to a linked list of post entries, struct curl_httppost */
+ CINIT(HTTPPOST, OBJECTPOINT, 24),
+
+ /* name of the file keeping your private SSL-certificate */
+ CINIT(SSLCERT, OBJECTPOINT, 25),
+
+ /* password for the SSL or SSH private key */
+ CINIT(KEYPASSWD, OBJECTPOINT, 26),
+
+ /* send TYPE parameter? */
+ CINIT(CRLF, LONG, 27),
+
+ /* send linked-list of QUOTE commands */
+ CINIT(QUOTE, OBJECTPOINT, 28),
+
+ /* send FILE * or void * to store headers to, if you use a callback it
+ is simply passed to the callback unmodified */
+ CINIT(HEADERDATA, OBJECTPOINT, 29),
+
+ /* point to a file to read the initial cookies from, also enables
+ "cookie awareness" */
+ CINIT(COOKIEFILE, OBJECTPOINT, 31),
+
+ /* What version to specifically try to use.
+ See CURL_SSLVERSION defines below. */
+ CINIT(SSLVERSION, LONG, 32),
+
+ /* What kind of HTTP time condition to use, see defines */
+ CINIT(TIMECONDITION, LONG, 33),
+
+ /* Time to use with the above condition. Specified in number of seconds
+ since 1 Jan 1970 */
+ CINIT(TIMEVALUE, LONG, 34),
+
+ /* 35 = OBSOLETE */
+
+ /* Custom request, for customizing the get command like
+ HTTP: DELETE, TRACE and others
+ FTP: to use a different list command
+ */
+ CINIT(CUSTOMREQUEST, OBJECTPOINT, 36),
+
+ /* HTTP request, for odd commands like DELETE, TRACE and others */
+ CINIT(STDERR, OBJECTPOINT, 37),
+
+ /* 38 is not used */
+
+ /* send linked-list of post-transfer QUOTE commands */
+ CINIT(POSTQUOTE, OBJECTPOINT, 39),
+
+ CINIT(OBSOLETE40, OBJECTPOINT, 40), /* OBSOLETE, do not use! */
+
+ CINIT(VERBOSE, LONG, 41), /* talk a lot */
+ CINIT(HEADER, LONG, 42), /* throw the header out too */
+ CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */
+ CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */
+ CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 400 */
+ CINIT(UPLOAD, LONG, 46), /* this is an upload */
+ CINIT(POST, LONG, 47), /* HTTP POST method */
+ CINIT(DIRLISTONLY, LONG, 48), /* bare names when listing directories */
+
+ CINIT(APPEND, LONG, 50), /* Append instead of overwrite on upload! */
+
+ /* Specify whether to read the user+password from the .netrc or the URL.
+ * This must be one of the CURL_NETRC_* enums below. */
+ CINIT(NETRC, LONG, 51),
+
+ CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */
+
+ CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */
+ CINIT(PUT, LONG, 54), /* HTTP PUT */
+
+ /* 55 = OBSOLETE */
+
+ /* DEPRECATED
+ * Function that will be called instead of the internal progress display
+ * function. This function should be defined as the curl_progress_callback
+ * prototype defines. */
+ CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56),
+
+ /* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION
+ callbacks */
+ CINIT(PROGRESSDATA, OBJECTPOINT, 57),
+#define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA
+
+ /* We want the referrer field set automatically when following locations */
+ CINIT(AUTOREFERER, LONG, 58),
+
+ /* Port of the proxy, can be set in the proxy string as well with:
+ "[host]:[port]" */
+ CINIT(PROXYPORT, LONG, 59),
+
+ /* size of the POST input data, if strlen() is not good to use */
+ CINIT(POSTFIELDSIZE, LONG, 60),
+
+ /* tunnel non-http operations through a HTTP proxy */
+ CINIT(HTTPPROXYTUNNEL, LONG, 61),
+
+ /* Set the interface string to use as outgoing network interface */
+ CINIT(INTERFACE, OBJECTPOINT, 62),
+
+ /* Set the krb4/5 security level, this also enables krb4/5 awareness. This
+ * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string
+ * is set but doesn't match one of these, 'private' will be used. */
+ CINIT(KRBLEVEL, OBJECTPOINT, 63),
+
+ /* Set if we should verify the peer in ssl handshake, set 1 to verify. */
+ CINIT(SSL_VERIFYPEER, LONG, 64),
+
+ /* The CApath or CAfile used to validate the peer certificate
+ this option is used only if SSL_VERIFYPEER is true */
+ CINIT(CAINFO, OBJECTPOINT, 65),
+
+ /* 66 = OBSOLETE */
+ /* 67 = OBSOLETE */
+
+ /* Maximum number of http redirects to follow */
+ CINIT(MAXREDIRS, LONG, 68),
+
+ /* Pass a long set to 1 to get the date of the requested document (if
+ possible)! Pass a zero to shut it off. */
+ CINIT(FILETIME, LONG, 69),
+
+ /* This points to a linked list of telnet options */
+ CINIT(TELNETOPTIONS, OBJECTPOINT, 70),
+
+ /* Max amount of cached alive connections */
+ CINIT(MAXCONNECTS, LONG, 71),
+
+ CINIT(OBSOLETE72, LONG, 72), /* OBSOLETE, do not use! */
+
+ /* 73 = OBSOLETE */
+
+ /* Set to explicitly use a new connection for the upcoming transfer.
+ Do not use this unless you're absolutely sure of this, as it makes the
+ operation slower and is less friendly for the network. */
+ CINIT(FRESH_CONNECT, LONG, 74),
+
+ /* Set to explicitly forbid the upcoming transfer's connection to be re-used
+ when done. Do not use this unless you're absolutely sure of this, as it
+ makes the operation slower and is less friendly for the network. */
+ CINIT(FORBID_REUSE, LONG, 75),
+
+ /* Set to a file name that contains random data for libcurl to use to
+ seed the random engine when doing SSL connects. */
+ CINIT(RANDOM_FILE, OBJECTPOINT, 76),
+
+ /* Set to the Entropy Gathering Daemon socket pathname */
+ CINIT(EGDSOCKET, OBJECTPOINT, 77),
+
+ /* Time-out connect operations after this amount of seconds, if connects are
+ OK within this time, then fine... This only aborts the connect phase. */
+ CINIT(CONNECTTIMEOUT, LONG, 78),
+
+ /* Function that will be called to store headers (instead of fwrite). The
+ * parameters will use fwrite() syntax, make sure to follow them. */
+ CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79),
+
+ /* Set this to force the HTTP request to get back to GET. Only really usable
+ if POST, PUT or a custom request have been used first.
+ */
+ CINIT(HTTPGET, LONG, 80),
+
+ /* Set if we should verify the Common name from the peer certificate in ssl
+ * handshake, set 1 to check existence, 2 to ensure that it matches the
+ * provided hostname. */
+ CINIT(SSL_VERIFYHOST, LONG, 81),
+
+ /* Specify which file name to write all known cookies in after completed
+ operation. Set file name to "-" (dash) to make it go to stdout. */
+ CINIT(COOKIEJAR, OBJECTPOINT, 82),
+
+ /* Specify which SSL ciphers to use */
+ CINIT(SSL_CIPHER_LIST, OBJECTPOINT, 83),
+
+ /* Specify which HTTP version to use! This must be set to one of the
+ CURL_HTTP_VERSION* enums set below. */
+ CINIT(HTTP_VERSION, LONG, 84),
+
+ /* Specifically switch on or off the FTP engine's use of the EPSV command. By
+ default, that one will always be attempted before the more traditional
+ PASV command. */
+ CINIT(FTP_USE_EPSV, LONG, 85),
+
+ /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */
+ CINIT(SSLCERTTYPE, OBJECTPOINT, 86),
+
+ /* name of the file keeping your private SSL-key */
+ CINIT(SSLKEY, OBJECTPOINT, 87),
+
+ /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */
+ CINIT(SSLKEYTYPE, OBJECTPOINT, 88),
+
+ /* crypto engine for the SSL-sub system */
+ CINIT(SSLENGINE, OBJECTPOINT, 89),
+
+ /* set the crypto engine for the SSL-sub system as default
+ the param has no meaning...
+ */
+ CINIT(SSLENGINE_DEFAULT, LONG, 90),
+
+ /* Non-zero value means to use the global dns cache */
+ CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* DEPRECATED, do not use! */
+
+ /* DNS cache timeout */
+ CINIT(DNS_CACHE_TIMEOUT, LONG, 92),
+
+ /* send linked-list of pre-transfer QUOTE commands */
+ CINIT(PREQUOTE, OBJECTPOINT, 93),
+
+ /* set the debug function */
+ CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94),
+
+ /* set the data for the debug function */
+ CINIT(DEBUGDATA, OBJECTPOINT, 95),
+
+ /* mark this as start of a cookie session */
+ CINIT(COOKIESESSION, LONG, 96),
+
+ /* The CApath directory used to validate the peer certificate
+ this option is used only if SSL_VERIFYPEER is true */
+ CINIT(CAPATH, OBJECTPOINT, 97),
+
+ /* Instruct libcurl to use a smaller receive buffer */
+ CINIT(BUFFERSIZE, LONG, 98),
+
+ /* Instruct libcurl to not use any signal/alarm handlers, even when using
+ timeouts. This option is useful for multi-threaded applications.
+ See libcurl-the-guide for more background information. */
+ CINIT(NOSIGNAL, LONG, 99),
+
+ /* Provide a CURLShare for mutexing non-ts data */
+ CINIT(SHARE, OBJECTPOINT, 100),
+
+ /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default),
+ CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5. */
+ CINIT(PROXYTYPE, LONG, 101),
+
+ /* Set the Accept-Encoding string. Use this to tell a server you would like
+ the response to be compressed. Before 7.21.6, this was known as
+ CURLOPT_ENCODING */
+ CINIT(ACCEPT_ENCODING, OBJECTPOINT, 102),
+
+ /* Set pointer to private data */
+ CINIT(PRIVATE, OBJECTPOINT, 103),
+
+ /* Set aliases for HTTP 200 in the HTTP Response header */
+ CINIT(HTTP200ALIASES, OBJECTPOINT, 104),
+
+ /* Continue to send authentication (user+password) when following locations,
+ even when hostname changed. This can potentially send off the name
+ and password to whatever host the server decides. */
+ CINIT(UNRESTRICTED_AUTH, LONG, 105),
+
+ /* Specifically switch on or off the FTP engine's use of the EPRT command (
+ it also disables the LPRT attempt). By default, those ones will always be
+ attempted before the good old traditional PORT command. */
+ CINIT(FTP_USE_EPRT, LONG, 106),
+
+ /* Set this to a bitmask value to enable the particular authentications
+ methods you like. Use this in combination with CURLOPT_USERPWD.
+ Note that setting multiple bits may cause extra network round-trips. */
+ CINIT(HTTPAUTH, LONG, 107),
+
+ /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx
+ in second argument. The function must be matching the
+ curl_ssl_ctx_callback proto. */
+ CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108),
+
+ /* Set the userdata for the ssl context callback function's third
+ argument */
+ CINIT(SSL_CTX_DATA, OBJECTPOINT, 109),
+
+ /* FTP Option that causes missing dirs to be created on the remote server.
+ In 7.19.4 we introduced the convenience enums for this option using the
+ CURLFTP_CREATE_DIR prefix.
+ */
+ CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110),
+
+ /* Set this to a bitmask value to enable the particular authentications
+ methods you like. Use this in combination with CURLOPT_PROXYUSERPWD.
+ Note that setting multiple bits may cause extra network round-trips. */
+ CINIT(PROXYAUTH, LONG, 111),
+
+ /* FTP option that changes the timeout, in seconds, associated with
+ getting a response. This is different from transfer timeout time and
+ essentially places a demand on the FTP server to acknowledge commands
+ in a timely manner. */
+ CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112),
+#define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT
+
+ /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to
+ tell libcurl to resolve names to those IP versions only. This only has
+ affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */
+ CINIT(IPRESOLVE, LONG, 113),
+
+ /* Set this option to limit the size of a file that will be downloaded from
+ an HTTP or FTP server.
+
+ Note there is also _LARGE version which adds large file support for
+ platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */
+ CINIT(MAXFILESIZE, LONG, 114),
+
+ /* See the comment for INFILESIZE above, but in short, specifies
+ * the size of the file being uploaded. -1 means unknown.
+ */
+ CINIT(INFILESIZE_LARGE, OFF_T, 115),
+
+ /* Sets the continuation offset. There is also a LONG version of this;
+ * look above for RESUME_FROM.
+ */
+ CINIT(RESUME_FROM_LARGE, OFF_T, 116),
+
+ /* Sets the maximum size of data that will be downloaded from
+ * an HTTP or FTP server. See MAXFILESIZE above for the LONG version.
+ */
+ CINIT(MAXFILESIZE_LARGE, OFF_T, 117),
+
+ /* Set this option to the file name of your .netrc file you want libcurl
+ to parse (using the CURLOPT_NETRC option). If not set, libcurl will do
+ a poor attempt to find the user's home directory and check for a .netrc
+ file in there. */
+ CINIT(NETRC_FILE, OBJECTPOINT, 118),
+
+ /* Enable SSL/TLS for FTP, pick one of:
+ CURLUSESSL_TRY - try using SSL, proceed anyway otherwise
+ CURLUSESSL_CONTROL - SSL for the control connection or fail
+ CURLUSESSL_ALL - SSL for all communication or fail
+ */
+ CINIT(USE_SSL, LONG, 119),
+
+ /* The _LARGE version of the standard POSTFIELDSIZE option */
+ CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120),
+
+ /* Enable/disable the TCP Nagle algorithm */
+ CINIT(TCP_NODELAY, LONG, 121),
+
+ /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+ /* 123 OBSOLETE. Gone in 7.16.0 */
+ /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+ /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+ /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+ /* 127 OBSOLETE. Gone in 7.16.0 */
+ /* 128 OBSOLETE. Gone in 7.16.0 */
+
+ /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option
+ can be used to change libcurl's default action which is to first try
+ "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK
+ response has been received.
+
+ Available parameters are:
+ CURLFTPAUTH_DEFAULT - let libcurl decide
+ CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS
+ CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL
+ */
+ CINIT(FTPSSLAUTH, LONG, 129),
+
+ CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130),
+ CINIT(IOCTLDATA, OBJECTPOINT, 131),
+
+ /* 132 OBSOLETE. Gone in 7.16.0 */
+ /* 133 OBSOLETE. Gone in 7.16.0 */
+
+ /* zero terminated string for pass on to the FTP server when asked for
+ "account" info */
+ CINIT(FTP_ACCOUNT, OBJECTPOINT, 134),
+
+ /* feed cookies into cookie engine */
+ CINIT(COOKIELIST, OBJECTPOINT, 135),
+
+ /* ignore Content-Length */
+ CINIT(IGNORE_CONTENT_LENGTH, LONG, 136),
+
+ /* Set to non-zero to skip the IP address received in a 227 PASV FTP server
+ response. Typically used for FTP-SSL purposes but is not restricted to
+ that. libcurl will then instead use the same IP address it used for the
+ control connection. */
+ CINIT(FTP_SKIP_PASV_IP, LONG, 137),
+
+ /* Select "file method" to use when doing FTP, see the curl_ftpmethod
+ above. */
+ CINIT(FTP_FILEMETHOD, LONG, 138),
+
+ /* Local port number to bind the socket to */
+ CINIT(LOCALPORT, LONG, 139),
+
+ /* Number of ports to try, including the first one set with LOCALPORT.
+ Thus, setting it to 1 will make no additional attempts but the first.
+ */
+ CINIT(LOCALPORTRANGE, LONG, 140),
+
+ /* no transfer, set up connection and let application use the socket by
+ extracting it with CURLINFO_LASTSOCKET */
+ CINIT(CONNECT_ONLY, LONG, 141),
+
+ /* Function that will be called to convert from the
+ network encoding (instead of using the iconv calls in libcurl) */
+ CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142),
+
+ /* Function that will be called to convert to the
+ network encoding (instead of using the iconv calls in libcurl) */
+ CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143),
+
+ /* Function that will be called to convert from UTF8
+ (instead of using the iconv calls in libcurl)
+ Note that this is used only for SSL certificate processing */
+ CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144),
+
+ /* if the connection proceeds too quickly then need to slow it down */
+ /* limit-rate: maximum number of bytes per second to send or receive */
+ CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145),
+ CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146),
+
+ /* Pointer to command string to send if USER/PASS fails. */
+ CINIT(FTP_ALTERNATIVE_TO_USER, OBJECTPOINT, 147),
+
+ /* callback function for setting socket options */
+ CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148),
+ CINIT(SOCKOPTDATA, OBJECTPOINT, 149),
+
+ /* set to 0 to disable session ID re-use for this transfer, default is
+ enabled (== 1) */
+ CINIT(SSL_SESSIONID_CACHE, LONG, 150),
+
+ /* allowed SSH authentication methods */
+ CINIT(SSH_AUTH_TYPES, LONG, 151),
+
+ /* Used by scp/sftp to do public/private key authentication */
+ CINIT(SSH_PUBLIC_KEYFILE, OBJECTPOINT, 152),
+ CINIT(SSH_PRIVATE_KEYFILE, OBJECTPOINT, 153),
+
+ /* Send CCC (Clear Command Channel) after authentication */
+ CINIT(FTP_SSL_CCC, LONG, 154),
+
+ /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */
+ CINIT(TIMEOUT_MS, LONG, 155),
+ CINIT(CONNECTTIMEOUT_MS, LONG, 156),
+
+ /* set to zero to disable the libcurl's decoding and thus pass the raw body
+ data to the application even when it is encoded/compressed */
+ CINIT(HTTP_TRANSFER_DECODING, LONG, 157),
+ CINIT(HTTP_CONTENT_DECODING, LONG, 158),
+
+ /* Permission used when creating new files and directories on the remote
+ server for protocols that support it, SFTP/SCP/FILE */
+ CINIT(NEW_FILE_PERMS, LONG, 159),
+ CINIT(NEW_DIRECTORY_PERMS, LONG, 160),
+
+ /* Set the behaviour of POST when redirecting. Values must be set to one
+ of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */
+ CINIT(POSTREDIR, LONG, 161),
+
+ /* used by scp/sftp to verify the host's public key */
+ CINIT(SSH_HOST_PUBLIC_KEY_MD5, OBJECTPOINT, 162),
+
+ /* Callback function for opening socket (instead of socket(2)). Optionally,
+ callback is able change the address or refuse to connect returning
+ CURL_SOCKET_BAD. The callback should have type
+ curl_opensocket_callback */
+ CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163),
+ CINIT(OPENSOCKETDATA, OBJECTPOINT, 164),
+
+ /* POST volatile input fields. */
+ CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165),
+
+ /* set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy */
+ CINIT(PROXY_TRANSFER_MODE, LONG, 166),
+
+ /* Callback function for seeking in the input stream */
+ CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167),
+ CINIT(SEEKDATA, OBJECTPOINT, 168),
+
+ /* CRL file */
+ CINIT(CRLFILE, OBJECTPOINT, 169),
+
+ /* Issuer certificate */
+ CINIT(ISSUERCERT, OBJECTPOINT, 170),
+
+ /* (IPv6) Address scope */
+ CINIT(ADDRESS_SCOPE, LONG, 171),
+
+ /* Collect certificate chain info and allow it to get retrievable with
+ CURLINFO_CERTINFO after the transfer is complete. */
+ CINIT(CERTINFO, LONG, 172),
+
+ /* "name" and "pwd" to use when fetching. */
+ CINIT(USERNAME, OBJECTPOINT, 173),
+ CINIT(PASSWORD, OBJECTPOINT, 174),
+
+ /* "name" and "pwd" to use with Proxy when fetching. */
+ CINIT(PROXYUSERNAME, OBJECTPOINT, 175),
+ CINIT(PROXYPASSWORD, OBJECTPOINT, 176),
+
+ /* Comma separated list of hostnames defining no-proxy zones. These should
+ match both hostnames directly, and hostnames within a domain. For
+ example, local.com will match local.com and www.local.com, but NOT
+ notlocal.com or www.notlocal.com. For compatibility with other
+ implementations of this, .local.com will be considered to be the same as
+ local.com. A single * is the only valid wildcard, and effectively
+ disables the use of proxy. */
+ CINIT(NOPROXY, OBJECTPOINT, 177),
+
+ /* block size for TFTP transfers */
+ CINIT(TFTP_BLKSIZE, LONG, 178),
+
+ /* Socks Service */
+ CINIT(SOCKS5_GSSAPI_SERVICE, OBJECTPOINT, 179),
+
+ /* Socks Service */
+ CINIT(SOCKS5_GSSAPI_NEC, LONG, 180),
+
+ /* set the bitmask for the protocols that are allowed to be used for the
+ transfer, which thus helps the app which takes URLs from users or other
+ external inputs and want to restrict what protocol(s) to deal
+ with. Defaults to CURLPROTO_ALL. */
+ CINIT(PROTOCOLS, LONG, 181),
+
+ /* set the bitmask for the protocols that libcurl is allowed to follow to,
+ as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
+ to be set in both bitmasks to be allowed to get redirected to. Defaults
+ to all protocols except FILE and SCP. */
+ CINIT(REDIR_PROTOCOLS, LONG, 182),
+
+ /* set the SSH knownhost file name to use */
+ CINIT(SSH_KNOWNHOSTS, OBJECTPOINT, 183),
+
+ /* set the SSH host key callback, must point to a curl_sshkeycallback
+ function */
+ CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184),
+
+ /* set the SSH host key callback custom pointer */
+ CINIT(SSH_KEYDATA, OBJECTPOINT, 185),
+
+ /* set the SMTP mail originator */
+ CINIT(MAIL_FROM, OBJECTPOINT, 186),
+
+ /* set the SMTP mail receiver(s) */
+ CINIT(MAIL_RCPT, OBJECTPOINT, 187),
+
+ /* FTP: send PRET before PASV */
+ CINIT(FTP_USE_PRET, LONG, 188),
+
+ /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */
+ CINIT(RTSP_REQUEST, LONG, 189),
+
+ /* The RTSP session identifier */
+ CINIT(RTSP_SESSION_ID, OBJECTPOINT, 190),
+
+ /* The RTSP stream URI */
+ CINIT(RTSP_STREAM_URI, OBJECTPOINT, 191),
+
+ /* The Transport: header to use in RTSP requests */
+ CINIT(RTSP_TRANSPORT, OBJECTPOINT, 192),
+
+ /* Manually initialize the client RTSP CSeq for this handle */
+ CINIT(RTSP_CLIENT_CSEQ, LONG, 193),
+
+ /* Manually initialize the server RTSP CSeq for this handle */
+ CINIT(RTSP_SERVER_CSEQ, LONG, 194),
+
+ /* The stream to pass to INTERLEAVEFUNCTION. */
+ CINIT(INTERLEAVEDATA, OBJECTPOINT, 195),
+
+ /* Let the application define a custom write method for RTP data */
+ CINIT(INTERLEAVEFUNCTION, FUNCTIONPOINT, 196),
+
+ /* Turn on wildcard matching */
+ CINIT(WILDCARDMATCH, LONG, 197),
+
+ /* Directory matching callback called before downloading of an
+ individual file (chunk) started */
+ CINIT(CHUNK_BGN_FUNCTION, FUNCTIONPOINT, 198),
+
+ /* Directory matching callback called after the file (chunk)
+ was downloaded, or skipped */
+ CINIT(CHUNK_END_FUNCTION, FUNCTIONPOINT, 199),
+
+ /* Change match (fnmatch-like) callback for wildcard matching */
+ CINIT(FNMATCH_FUNCTION, FUNCTIONPOINT, 200),
+
+ /* Let the application define custom chunk data pointer */
+ CINIT(CHUNK_DATA, OBJECTPOINT, 201),
+
+ /* FNMATCH_FUNCTION user pointer */
+ CINIT(FNMATCH_DATA, OBJECTPOINT, 202),
+
+ /* send linked-list of name:port:address sets */
+ CINIT(RESOLVE, OBJECTPOINT, 203),
+
+ /* Set a username for authenticated TLS */
+ CINIT(TLSAUTH_USERNAME, OBJECTPOINT, 204),
+
+ /* Set a password for authenticated TLS */
+ CINIT(TLSAUTH_PASSWORD, OBJECTPOINT, 205),
+
+ /* Set authentication type for authenticated TLS */
+ CINIT(TLSAUTH_TYPE, OBJECTPOINT, 206),
+
+ /* Set to 1 to enable the "TE:" header in HTTP requests to ask for
+ compressed transfer-encoded responses. Set to 0 to disable the use of TE:
+ in outgoing requests. The current default is 0, but it might change in a
+ future libcurl release.
+
+ libcurl will ask for the compressed methods it knows of, and if that
+ isn't any, it will not ask for transfer-encoding at all even if this
+ option is set to 1.
+
+ */
+ CINIT(TRANSFER_ENCODING, LONG, 207),
+
+ /* Callback function for closing socket (instead of close(2)). The callback
+ should have type curl_closesocket_callback */
+ CINIT(CLOSESOCKETFUNCTION, FUNCTIONPOINT, 208),
+ CINIT(CLOSESOCKETDATA, OBJECTPOINT, 209),
+
+ /* allow GSSAPI credential delegation */
+ CINIT(GSSAPI_DELEGATION, LONG, 210),
+
+ /* Set the name servers to use for DNS resolution */
+ CINIT(DNS_SERVERS, OBJECTPOINT, 211),
+
+ /* Time-out accept operations (currently for FTP only) after this amount
+ of miliseconds. */
+ CINIT(ACCEPTTIMEOUT_MS, LONG, 212),
+
+ /* Set TCP keepalive */
+ CINIT(TCP_KEEPALIVE, LONG, 213),
+
+ /* non-universal keepalive knobs (Linux, AIX, HP-UX, more) */
+ CINIT(TCP_KEEPIDLE, LONG, 214),
+ CINIT(TCP_KEEPINTVL, LONG, 215),
+
+ /* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */
+ CINIT(SSL_OPTIONS, LONG, 216),
+
+ /* Set the SMTP auth originator */
+ CINIT(MAIL_AUTH, OBJECTPOINT, 217),
+
+ /* Enable/disable SASL initial response */
+ CINIT(SASL_IR, LONG, 218),
+
+ /* Function that will be called instead of the internal progress display
+ * function. This function should be defined as the curl_xferinfo_callback
+ * prototype defines. (Deprecates CURLOPT_PROGRESSFUNCTION) */
+ CINIT(XFERINFOFUNCTION, FUNCTIONPOINT, 219),
+
+ /* The XOAUTH2 bearer token */
+ CINIT(XOAUTH2_BEARER, OBJECTPOINT, 220),
+
+ /* Set the interface string to use as outgoing network
+ * interface for DNS requests.
+ * Only supported by the c-ares DNS backend */
+ CINIT(DNS_INTERFACE, OBJECTPOINT, 221),
+
+ /* Set the local IPv4 address to use for outgoing DNS requests.
+ * Only supported by the c-ares DNS backend */
+ CINIT(DNS_LOCAL_IP4, OBJECTPOINT, 222),
+
+ /* Set the local IPv4 address to use for outgoing DNS requests.
+ * Only supported by the c-ares DNS backend */
+ CINIT(DNS_LOCAL_IP6, OBJECTPOINT, 223),
+
+ /* Set authentication options directly */
+ CINIT(LOGIN_OPTIONS, OBJECTPOINT, 224),
+
+ /* Enable/disable TLS NPN extension (http2 over ssl might fail without) */
+ CINIT(SSL_ENABLE_NPN, LONG, 225),
+
+ /* Enable/disable TLS ALPN extension (http2 over ssl might fail without) */
+ CINIT(SSL_ENABLE_ALPN, LONG, 226),
+
+ /* Time to wait for a response to a HTTP request containing an
+ * Expect: 100-continue header before sending the data anyway. */
+ CINIT(EXPECT_100_TIMEOUT_MS, LONG, 227),
+
+ /* This points to a linked list of headers used for proxy requests only,
+ struct curl_slist kind */
+ CINIT(PROXYHEADER, OBJECTPOINT, 228),
+
+ /* Pass in a bitmask of "header options" */
+ CINIT(HEADEROPT, LONG, 229),
+
+ /* The public key in DER form used to validate the peer public key
+ this option is used only if SSL_VERIFYPEER is true */
+ CINIT(PINNEDPUBLICKEY, OBJECTPOINT, 230),
+
+ /* Path to Unix domain socket */
+ CINIT(UNIX_SOCKET_PATH, OBJECTPOINT, 231),
+
+ /* Set if we should verify the certificate status. */
+ CINIT(SSL_VERIFYSTATUS, LONG, 232),
+
+ /* Set if we should enable TLS false start. */
+ CINIT(SSL_FALSESTART, LONG, 233),
+
+ /* Do not squash dot-dot sequences */
+ CINIT(PATH_AS_IS, LONG, 234),
+
+ /* Proxy Service Name */
+ CINIT(PROXY_SERVICE_NAME, OBJECTPOINT, 235),
+
+ /* Service Name */
+ CINIT(SERVICE_NAME, OBJECTPOINT, 236),
+
+ /* Wait/don't wait for pipe/mutex to clarify */
+ CINIT(PIPEWAIT, LONG, 237),
+
+ CURLOPT_LASTENTRY /* the last unused */
+} CURLoption;
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+ the obsolete stuff removed! */
+
+/* Backwards compatibility with older names */
+/* These are scheduled to disappear by 2011 */
+
+/* This was added in version 7.19.1 */
+#define CURLOPT_POST301 CURLOPT_POSTREDIR
+
+/* These are scheduled to disappear by 2009 */
+
+/* The following were added in 7.17.0 */
+#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD
+#define CURLOPT_FTPAPPEND CURLOPT_APPEND
+#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY
+#define CURLOPT_FTP_SSL CURLOPT_USE_SSL
+
+/* The following were added earlier */
+
+#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD
+#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL
+
+#else
+/* This is set if CURL_NO_OLDIES is defined at compile-time */
+#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */
+#endif
+
+
+ /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host
+ name resolves addresses using more than one IP protocol version, this
+ option might be handy to force libcurl to use a specific IP version. */
+#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP
+ versions that your system allows */
+#define CURL_IPRESOLVE_V4 1 /* resolve to IPv4 addresses */
+#define CURL_IPRESOLVE_V6 2 /* resolve to IPv6 addresses */
+
+ /* three convenient "aliases" that follow the name scheme better */
+#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER
+
+ /* These enums are for use with the CURLOPT_HTTP_VERSION option. */
+enum {
+ CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd
+ like the library to choose the best possible
+ for us! */
+ CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */
+ CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */
+ CURL_HTTP_VERSION_2_0, /* please use HTTP 2.0 in the request */
+
+ CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */
+};
+
+/* Convenience definition simple because the name of the version is HTTP/2 and
+ not 2.0. The 2_0 version of the enum name was set while the version was
+ still planned to be 2.0 and we stick to it for compatibility. */
+#define CURL_HTTP_VERSION_2 CURL_HTTP_VERSION_2_0
+
+/*
+ * Public API enums for RTSP requests
+ */
+enum {
+ CURL_RTSPREQ_NONE, /* first in list */
+ CURL_RTSPREQ_OPTIONS,
+ CURL_RTSPREQ_DESCRIBE,
+ CURL_RTSPREQ_ANNOUNCE,
+ CURL_RTSPREQ_SETUP,
+ CURL_RTSPREQ_PLAY,
+ CURL_RTSPREQ_PAUSE,
+ CURL_RTSPREQ_TEARDOWN,
+ CURL_RTSPREQ_GET_PARAMETER,
+ CURL_RTSPREQ_SET_PARAMETER,
+ CURL_RTSPREQ_RECORD,
+ CURL_RTSPREQ_RECEIVE,
+ CURL_RTSPREQ_LAST /* last in list */
+};
+
+ /* These enums are for use with the CURLOPT_NETRC option. */
+enum CURL_NETRC_OPTION {
+ CURL_NETRC_IGNORED, /* The .netrc will never be read.
+ * This is the default. */
+ CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred
+ * to one in the .netrc. */
+ CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored.
+ * Unless one is set programmatically, the .netrc
+ * will be queried. */
+ CURL_NETRC_LAST
+};
+
+enum {
+ CURL_SSLVERSION_DEFAULT,
+ CURL_SSLVERSION_TLSv1, /* TLS 1.x */
+ CURL_SSLVERSION_SSLv2,
+ CURL_SSLVERSION_SSLv3,
+ CURL_SSLVERSION_TLSv1_0,
+ CURL_SSLVERSION_TLSv1_1,
+ CURL_SSLVERSION_TLSv1_2,
+
+ CURL_SSLVERSION_LAST /* never use, keep last */
+};
+
+enum CURL_TLSAUTH {
+ CURL_TLSAUTH_NONE,
+ CURL_TLSAUTH_SRP,
+ CURL_TLSAUTH_LAST /* never use, keep last */
+};
+
+/* symbols to use with CURLOPT_POSTREDIR.
+ CURL_REDIR_POST_301, CURL_REDIR_POST_302 and CURL_REDIR_POST_303
+ can be bitwise ORed so that CURL_REDIR_POST_301 | CURL_REDIR_POST_302
+ | CURL_REDIR_POST_303 == CURL_REDIR_POST_ALL */
+
+#define CURL_REDIR_GET_ALL 0
+#define CURL_REDIR_POST_301 1
+#define CURL_REDIR_POST_302 2
+#define CURL_REDIR_POST_303 4
+#define CURL_REDIR_POST_ALL \
+ (CURL_REDIR_POST_301|CURL_REDIR_POST_302|CURL_REDIR_POST_303)
+
+typedef enum {
+ CURL_TIMECOND_NONE,
+
+ CURL_TIMECOND_IFMODSINCE,
+ CURL_TIMECOND_IFUNMODSINCE,
+ CURL_TIMECOND_LASTMOD,
+
+ CURL_TIMECOND_LAST
+} curl_TimeCond;
+
+
+/* curl_strequal() and curl_strnequal() are subject for removal in a future
+ libcurl, see lib/README.curlx for details */
+CURL_EXTERN int (curl_strequal)(const char *s1, const char *s2);
+CURL_EXTERN int (curl_strnequal)(const char *s1, const char *s2, size_t n);
+
+/* name is uppercase CURLFORM_<name> */
+#ifdef CFINIT
+#undef CFINIT
+#endif
+
+#ifdef CURL_ISOCPP
+#define CFINIT(name) CURLFORM_ ## name
+#else
+/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
+#define CFINIT(name) CURLFORM_/**/name
+#endif
+
+typedef enum {
+ CFINIT(NOTHING), /********* the first one is unused ************/
+
+ /* */
+ CFINIT(COPYNAME),
+ CFINIT(PTRNAME),
+ CFINIT(NAMELENGTH),
+ CFINIT(COPYCONTENTS),
+ CFINIT(PTRCONTENTS),
+ CFINIT(CONTENTSLENGTH),
+ CFINIT(FILECONTENT),
+ CFINIT(ARRAY),
+ CFINIT(OBSOLETE),
+ CFINIT(FILE),
+
+ CFINIT(BUFFER),
+ CFINIT(BUFFERPTR),
+ CFINIT(BUFFERLENGTH),
+
+ CFINIT(CONTENTTYPE),
+ CFINIT(CONTENTHEADER),
+ CFINIT(FILENAME),
+ CFINIT(END),
+ CFINIT(OBSOLETE2),
+
+ CFINIT(STREAM),
+
+ CURLFORM_LASTENTRY /* the last unused */
+} CURLformoption;
+
+#undef CFINIT /* done */
+
+/* structure to be used as parameter for CURLFORM_ARRAY */
+struct curl_forms {
+ CURLformoption option;
+ const char *value;
+};
+
+/* use this for multipart formpost building */
+/* Returns code for curl_formadd()
+ *
+ * Returns:
+ * CURL_FORMADD_OK on success
+ * CURL_FORMADD_MEMORY if the FormInfo allocation fails
+ * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form
+ * CURL_FORMADD_NULL if a null pointer was given for a char
+ * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed
+ * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
+ * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error)
+ * CURL_FORMADD_MEMORY if a curl_httppost struct cannot be allocated
+ * CURL_FORMADD_MEMORY if some allocation for string copying failed.
+ * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array
+ *
+ ***************************************************************************/
+typedef enum {
+ CURL_FORMADD_OK, /* first, no error */
+
+ CURL_FORMADD_MEMORY,
+ CURL_FORMADD_OPTION_TWICE,
+ CURL_FORMADD_NULL,
+ CURL_FORMADD_UNKNOWN_OPTION,
+ CURL_FORMADD_INCOMPLETE,
+ CURL_FORMADD_ILLEGAL_ARRAY,
+ CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */
+
+ CURL_FORMADD_LAST /* last */
+} CURLFORMcode;
+
+/*
+ * NAME curl_formadd()
+ *
+ * DESCRIPTION
+ *
+ * Pretty advanced function for building multi-part formposts. Each invoke
+ * adds one part that together construct a full post. Then use
+ * CURLOPT_HTTPPOST to send it off to libcurl.
+ */
+CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost,
+ struct curl_httppost **last_post,
+ ...);
+
+/*
+ * callback function for curl_formget()
+ * The void *arg pointer will be the one passed as second argument to
+ * curl_formget().
+ * The character buffer passed to it must not be freed.
+ * Should return the buffer length passed to it as the argument "len" on
+ * success.
+ */
+typedef size_t (*curl_formget_callback)(void *arg, const char *buf,
+ size_t len);
+
+/*
+ * NAME curl_formget()
+ *
+ * DESCRIPTION
+ *
+ * Serialize a curl_httppost struct built with curl_formadd().
+ * Accepts a void pointer as second argument which will be passed to
+ * the curl_formget_callback function.
+ * Returns 0 on success.
+ */
+CURL_EXTERN int curl_formget(struct curl_httppost *form, void *arg,
+ curl_formget_callback append);
+/*
+ * NAME curl_formfree()
+ *
+ * DESCRIPTION
+ *
+ * Free a multipart formpost previously built with curl_formadd().
+ */
+CURL_EXTERN void curl_formfree(struct curl_httppost *form);
+
+/*
+ * NAME curl_getenv()
+ *
+ * DESCRIPTION
+ *
+ * Returns a malloc()'ed string that MUST be curl_free()ed after usage is
+ * complete. DEPRECATED - see lib/README.curlx
+ */
+CURL_EXTERN char *curl_getenv(const char *variable);
+
+/*
+ * NAME curl_version()
+ *
+ * DESCRIPTION
+ *
+ * Returns a static ascii string of the libcurl version.
+ */
+CURL_EXTERN char *curl_version(void);
+
+/*
+ * NAME curl_easy_escape()
+ *
+ * DESCRIPTION
+ *
+ * Escapes URL strings (converts all letters consider illegal in URLs to their
+ * %XX versions). This function returns a new allocated string or NULL if an
+ * error occurred.
+ */
+CURL_EXTERN char *curl_easy_escape(CURL *handle,
+ const char *string,
+ int length);
+
+/* the previous version: */
+CURL_EXTERN char *curl_escape(const char *string,
+ int length);
+
+
+/*
+ * NAME curl_easy_unescape()
+ *
+ * DESCRIPTION
+ *
+ * Unescapes URL encoding in strings (converts all %XX codes to their 8bit
+ * versions). This function returns a new allocated string or NULL if an error
+ * occurred.
+ * Conversion Note: On non-ASCII platforms the ASCII %XX codes are
+ * converted into the host encoding.
+ */
+CURL_EXTERN char *curl_easy_unescape(CURL *handle,
+ const char *string,
+ int length,
+ int *outlength);
+
+/* the previous version */
+CURL_EXTERN char *curl_unescape(const char *string,
+ int length);
+
+/*
+ * NAME curl_free()
+ *
+ * DESCRIPTION
+ *
+ * Provided for de-allocation in the same translation unit that did the
+ * allocation. Added in libcurl 7.10
+ */
+CURL_EXTERN void curl_free(void *p);
+
+/*
+ * NAME curl_global_init()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_init() should be invoked exactly once for each application that
+ * uses libcurl and before any call of other libcurl functions.
+ *
+ * This function is not thread-safe!
+ */
+CURL_EXTERN CURLcode curl_global_init(long flags);
+
+/*
+ * NAME curl_global_init_mem()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_init() or curl_global_init_mem() should be invoked exactly once
+ * for each application that uses libcurl. This function can be used to
+ * initialize libcurl and set user defined memory management callback
+ * functions. Users can implement memory management routines to check for
+ * memory leaks, check for mis-use of the curl library etc. User registered
+ * callback routines with be invoked by this library instead of the system
+ * memory management routines like malloc, free etc.
+ */
+CURL_EXTERN CURLcode curl_global_init_mem(long flags,
+ curl_malloc_callback m,
+ curl_free_callback f,
+ curl_realloc_callback r,
+ curl_strdup_callback s,
+ curl_calloc_callback c);
+
+/*
+ * NAME curl_global_cleanup()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_cleanup() should be invoked exactly once for each application
+ * that uses libcurl
+ */
+CURL_EXTERN void curl_global_cleanup(void);
+
+/* linked-list structure for the CURLOPT_QUOTE option (and other) */
+struct curl_slist {
+ char *data;
+ struct curl_slist *next;
+};
+
+/*
+ * NAME curl_slist_append()
+ *
+ * DESCRIPTION
+ *
+ * Appends a string to a linked list. If no list exists, it will be created
+ * first. Returns the new list, after appending.
+ */
+CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *,
+ const char *);
+
+/*
+ * NAME curl_slist_free_all()
+ *
+ * DESCRIPTION
+ *
+ * free a previously built curl_slist.
+ */
+CURL_EXTERN void curl_slist_free_all(struct curl_slist *);
+
+/*
+ * NAME curl_getdate()
+ *
+ * DESCRIPTION
+ *
+ * Returns the time, in seconds since 1 Jan 1970 of the time string given in
+ * the first argument. The time argument in the second parameter is unused
+ * and should be set to NULL.
+ */
+CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused);
+
+/* info about the certificate chain, only for OpenSSL builds. Asked
+ for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */
+struct curl_certinfo {
+ int num_of_certs; /* number of certificates with information */
+ struct curl_slist **certinfo; /* for each index in this array, there's a
+ linked list with textual information in the
+ format "name: value" */
+};
+
+/* enum for the different supported SSL backends */
+typedef enum {
+ CURLSSLBACKEND_NONE = 0,
+ CURLSSLBACKEND_OPENSSL = 1,
+ CURLSSLBACKEND_GNUTLS = 2,
+ CURLSSLBACKEND_NSS = 3,
+ CURLSSLBACKEND_OBSOLETE4 = 4, /* Was QSOSSL. */
+ CURLSSLBACKEND_GSKIT = 5,
+ CURLSSLBACKEND_POLARSSL = 6,
+ CURLSSLBACKEND_CYASSL = 7,
+ CURLSSLBACKEND_SCHANNEL = 8,
+ CURLSSLBACKEND_DARWINSSL = 9,
+ CURLSSLBACKEND_AXTLS = 10
+} curl_sslbackend;
+
+/* Information about the SSL library used and the respective internal SSL
+ handle, which can be used to obtain further information regarding the
+ connection. Asked for with CURLINFO_TLS_SESSION. */
+struct curl_tlssessioninfo {
+ curl_sslbackend backend;
+ void *internals;
+};
+
+#define CURLINFO_STRING 0x100000
+#define CURLINFO_LONG 0x200000
+#define CURLINFO_DOUBLE 0x300000
+#define CURLINFO_SLIST 0x400000
+#define CURLINFO_MASK 0x0fffff
+#define CURLINFO_TYPEMASK 0xf00000
+
+typedef enum {
+ CURLINFO_NONE, /* first, never use this */
+ CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1,
+ CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2,
+ CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3,
+ CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4,
+ CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5,
+ CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6,
+ CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE + 7,
+ CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE + 8,
+ CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE + 9,
+ CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE + 10,
+ CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11,
+ CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12,
+ CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13,
+ CURLINFO_FILETIME = CURLINFO_LONG + 14,
+ CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15,
+ CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16,
+ CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17,
+ CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18,
+ CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19,
+ CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20,
+ CURLINFO_PRIVATE = CURLINFO_STRING + 21,
+ CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22,
+ CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23,
+ CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24,
+ CURLINFO_OS_ERRNO = CURLINFO_LONG + 25,
+ CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26,
+ CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27,
+ CURLINFO_COOKIELIST = CURLINFO_SLIST + 28,
+ CURLINFO_LASTSOCKET = CURLINFO_LONG + 29,
+ CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30,
+ CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31,
+ CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32,
+ CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33,
+ CURLINFO_CERTINFO = CURLINFO_SLIST + 34,
+ CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35,
+ CURLINFO_RTSP_SESSION_ID = CURLINFO_STRING + 36,
+ CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG + 37,
+ CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG + 38,
+ CURLINFO_RTSP_CSEQ_RECV = CURLINFO_LONG + 39,
+ CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40,
+ CURLINFO_LOCAL_IP = CURLINFO_STRING + 41,
+ CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42,
+ CURLINFO_TLS_SESSION = CURLINFO_SLIST + 43,
+ /* Fill in new entries below here! */
+
+ CURLINFO_LASTONE = 43
+} CURLINFO;
+
+/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
+ CURLINFO_HTTP_CODE */
+#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE
+
+typedef enum {
+ CURLCLOSEPOLICY_NONE, /* first, never use this */
+
+ CURLCLOSEPOLICY_OLDEST,
+ CURLCLOSEPOLICY_LEAST_RECENTLY_USED,
+ CURLCLOSEPOLICY_LEAST_TRAFFIC,
+ CURLCLOSEPOLICY_SLOWEST,
+ CURLCLOSEPOLICY_CALLBACK,
+
+ CURLCLOSEPOLICY_LAST /* last, never use this */
+} curl_closepolicy;
+
+#define CURL_GLOBAL_SSL (1<<0)
+#define CURL_GLOBAL_WIN32 (1<<1)
+#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32)
+#define CURL_GLOBAL_NOTHING 0
+#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL
+#define CURL_GLOBAL_ACK_EINTR (1<<2)
+
+
+/*****************************************************************************
+ * Setup defines, protos etc for the sharing stuff.
+ */
+
+/* Different data locks for a single share */
+typedef enum {
+ CURL_LOCK_DATA_NONE = 0,
+ /* CURL_LOCK_DATA_SHARE is used internally to say that
+ * the locking is just made to change the internal state of the share
+ * itself.
+ */
+ CURL_LOCK_DATA_SHARE,
+ CURL_LOCK_DATA_COOKIE,
+ CURL_LOCK_DATA_DNS,
+ CURL_LOCK_DATA_SSL_SESSION,
+ CURL_LOCK_DATA_CONNECT,
+ CURL_LOCK_DATA_LAST
+} curl_lock_data;
+
+/* Different lock access types */
+typedef enum {
+ CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */
+ CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */
+ CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */
+ CURL_LOCK_ACCESS_LAST /* never use */
+} curl_lock_access;
+
+typedef void (*curl_lock_function)(CURL *handle,
+ curl_lock_data data,
+ curl_lock_access locktype,
+ void *userptr);
+typedef void (*curl_unlock_function)(CURL *handle,
+ curl_lock_data data,
+ void *userptr);
+
+typedef void CURLSH;
+
+typedef enum {
+ CURLSHE_OK, /* all is fine */
+ CURLSHE_BAD_OPTION, /* 1 */
+ CURLSHE_IN_USE, /* 2 */
+ CURLSHE_INVALID, /* 3 */
+ CURLSHE_NOMEM, /* 4 out of memory */
+ CURLSHE_NOT_BUILT_IN, /* 5 feature not present in lib */
+ CURLSHE_LAST /* never use */
+} CURLSHcode;
+
+typedef enum {
+ CURLSHOPT_NONE, /* don't use */
+ CURLSHOPT_SHARE, /* specify a data type to share */
+ CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */
+ CURLSHOPT_LOCKFUNC, /* pass in a 'curl_lock_function' pointer */
+ CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */
+ CURLSHOPT_USERDATA, /* pass in a user data pointer used in the lock/unlock
+ callback functions */
+ CURLSHOPT_LAST /* never use */
+} CURLSHoption;
+
+CURL_EXTERN CURLSH *curl_share_init(void);
+CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...);
+CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *);
+
+/****************************************************************************
+ * Structures for querying information about the curl library at runtime.
+ */
+
+typedef enum {
+ CURLVERSION_FIRST,
+ CURLVERSION_SECOND,
+ CURLVERSION_THIRD,
+ CURLVERSION_FOURTH,
+ CURLVERSION_LAST /* never actually use this */
+} CURLversion;
+
+/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by
+ basically all programs ever that want to get version information. It is
+ meant to be a built-in version number for what kind of struct the caller
+ expects. If the struct ever changes, we redefine the NOW to another enum
+ from above. */
+#define CURLVERSION_NOW CURLVERSION_FOURTH
+
+typedef struct {
+ CURLversion age; /* age of the returned struct */
+ const char *version; /* LIBCURL_VERSION */
+ unsigned int version_num; /* LIBCURL_VERSION_NUM */
+ const char *host; /* OS/host/cpu/machine when configured */
+ int features; /* bitmask, see defines below */
+ const char *ssl_version; /* human readable string */
+ long ssl_version_num; /* not used anymore, always 0 */
+ const char *libz_version; /* human readable string */
+ /* protocols is terminated by an entry with a NULL protoname */
+ const char * const *protocols;
+
+ /* The fields below this were added in CURLVERSION_SECOND */
+ const char *ares;
+ int ares_num;
+
+ /* This field was added in CURLVERSION_THIRD */
+ const char *libidn;
+
+ /* These field were added in CURLVERSION_FOURTH */
+
+ /* Same as '_libiconv_version' if built with HAVE_ICONV */
+ int iconv_ver_num;
+
+ const char *libssh_version; /* human readable string */
+
+} curl_version_info_data;
+
+#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */
+#define CURL_VERSION_KERBEROS4 (1<<1) /* Kerberos V4 auth is supported
+ (deprecated) */
+#define CURL_VERSION_SSL (1<<2) /* SSL options are present */
+#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */
+#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */
+#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth is supported
+ (deprecated) */
+#define CURL_VERSION_DEBUG (1<<6) /* Built with debug capabilities */
+#define CURL_VERSION_ASYNCHDNS (1<<7) /* Asynchronous DNS resolves */
+#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth is supported */
+#define CURL_VERSION_LARGEFILE (1<<9) /* Supports files larger than 2GB */
+#define CURL_VERSION_IDN (1<<10) /* Internationized Domain Names are
+ supported */
+#define CURL_VERSION_SSPI (1<<11) /* Built against Windows SSPI */
+#define CURL_VERSION_CONV (1<<12) /* Character conversions supported */
+#define CURL_VERSION_CURLDEBUG (1<<13) /* Debug memory tracking supported */
+#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */
+#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegation to winbind helper
+ is suported */
+#define CURL_VERSION_HTTP2 (1<<16) /* HTTP2 support built-in */
+#define CURL_VERSION_GSSAPI (1<<17) /* Built against a GSS-API library */
+#define CURL_VERSION_KERBEROS5 (1<<18) /* Kerberos V5 auth is supported */
+#define CURL_VERSION_UNIX_SOCKETS (1<<19) /* Unix domain sockets support */
+
+ /*
+ * NAME curl_version_info()
+ *
+ * DESCRIPTION
+ *
+ * This function returns a pointer to a static copy of the version info
+ * struct. See above.
+ */
+CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion);
+
+/*
+ * NAME curl_easy_strerror()
+ *
+ * DESCRIPTION
+ *
+ * The curl_easy_strerror function may be used to turn a CURLcode value
+ * into the equivalent human readable error string. This is useful
+ * for printing meaningful error messages.
+ */
+CURL_EXTERN const char *curl_easy_strerror(CURLcode);
+
+/*
+ * NAME curl_share_strerror()
+ *
+ * DESCRIPTION
+ *
+ * The curl_share_strerror function may be used to turn a CURLSHcode value
+ * into the equivalent human readable error string. This is useful
+ * for printing meaningful error messages.
+ */
+CURL_EXTERN const char *curl_share_strerror(CURLSHcode);
+
+/*
+ * NAME curl_easy_pause()
+ *
+ * DESCRIPTION
+ *
+ * The curl_easy_pause function pauses or unpauses transfers. Select the new
+ * state by setting the bitmask, use the convenience defines below.
+ *
+ */
+CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask);
+
+#define CURLPAUSE_RECV (1<<0)
+#define CURLPAUSE_RECV_CONT (0)
+
+#define CURLPAUSE_SEND (1<<2)
+#define CURLPAUSE_SEND_CONT (0)
+
+#define CURLPAUSE_ALL (CURLPAUSE_RECV|CURLPAUSE_SEND)
+#define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT)
+
+#ifdef __cplusplus
+}
+#endif
+
+/* unfortunately, the easy.h and multi.h include files need options and info
+ stuff before they can be included! */
+#include "easy.h" /* nothing in curl is fun without the easy stuff */
+#include "multi.h"
+
+/* the typechecker doesn't work in C++ (yet) */
+#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \
+ ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \
+ !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK)
+#include "typecheck-gcc.h"
+#else
+#if defined(__STDC__) && (__STDC__ >= 1)
+#if 0 /* Triggers clang -Wdisabled-macro-expansion, skip for CMake. */
+/* This preprocessor magic that replaces a call with the exact same call is
+ only done to make sure application authors pass exactly three arguments
+ to these functions. */
+#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param)
+#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg)
+#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
+#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
+#endif
+#endif /* __STDC__ >= 1 */
+#endif /* gcc >= 4.3 && !__cplusplus */
+
+#endif /* __CURL_CURL_H */
diff --git a/Utilities/cmcurl/include/curl/curlbuild.h.cmake b/Utilities/cmcurl/include/curl/curlbuild.h.cmake
new file mode 100644
index 000000000..6608694b2
--- /dev/null
+++ b/Utilities/cmcurl/include/curl/curlbuild.h.cmake
@@ -0,0 +1,218 @@
+#ifndef __CURL_CURLBUILD_H
+#define __CURL_CURLBUILD_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* ================================================================ */
+/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */
+/* ================================================================ */
+
+/*
+ * NOTE 1:
+ * -------
+ *
+ * Nothing in this file is intended to be modified or adjusted by the
+ * curl library user nor by the curl library builder.
+ *
+ * If you think that something actually needs to be changed, adjusted
+ * or fixed in this file, then, report it on the libcurl development
+ * mailing list: http://cool.haxx.se/mailman/listinfo/curl-library/
+ *
+ * This header file shall only export symbols which are 'curl' or 'CURL'
+ * prefixed, otherwise public name space would be polluted.
+ *
+ * NOTE 2:
+ * -------
+ *
+ * Right now you might be staring at file include/curl/curlbuild.h.in or
+ * at file include/curl/curlbuild.h, this is due to the following reason:
+ *
+ * On systems capable of running the configure script, the configure process
+ * will overwrite the distributed include/curl/curlbuild.h file with one that
+ * is suitable and specific to the library being configured and built, which
+ * is generated from the include/curl/curlbuild.h.in template file.
+ *
+ */
+
+/* ================================================================ */
+/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */
+/* ================================================================ */
+
+#ifdef CURL_SIZEOF_LONG
+#error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined
+#endif
+
+#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
+#error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined
+#endif
+
+#ifdef CURL_SIZEOF_CURL_SOCKLEN_T
+#error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined
+#endif
+
+#ifdef CURL_TYPEOF_CURL_OFF_T
+#error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_FORMAT_CURL_OFF_T
+#error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_FORMAT_CURL_OFF_TU
+#error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined
+#endif
+
+#ifdef CURL_FORMAT_OFF_T
+#error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined
+#endif
+
+#ifdef CURL_SIZEOF_CURL_OFF_T
+#error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_SUFFIX_CURL_OFF_T
+#error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined
+#endif
+
+#ifdef CURL_SUFFIX_CURL_OFF_TU
+#error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h"
+ Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined
+#endif
+
+/* ================================================================ */
+/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */
+/* ================================================================ */
+
+/* Configure process defines this to 1 when it finds out that system */
+/* header file ws2tcpip.h must be included by the external interface. */
+#cmakedefine CURL_PULL_WS2TCPIP_H
+#ifdef CURL_PULL_WS2TCPIP_H
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include <windows.h>
+# include <winsock2.h>
+# include <ws2tcpip.h>
+#endif
+
+/* Configure process defines this to 1 when it finds out that system */
+/* header file sys/types.h must be included by the external interface. */
+#cmakedefine CURL_PULL_SYS_TYPES_H
+#ifdef CURL_PULL_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+/* Configure process defines this to 1 when it finds out that system */
+/* header file stdint.h must be included by the external interface. */
+#cmakedefine CURL_PULL_STDINT_H
+#ifdef CURL_PULL_STDINT_H
+# include <stdint.h>
+#endif
+
+/* Configure process defines this to 1 when it finds out that system */
+/* header file inttypes.h must be included by the external interface. */
+#cmakedefine CURL_PULL_INTTYPES_H
+#ifdef CURL_PULL_INTTYPES_H
+# include <inttypes.h>
+#endif
+
+/* Configure process defines this to 1 when it finds out that system */
+/* header file sys/socket.h must be included by the external interface. */
+#cmakedefine CURL_PULL_SYS_SOCKET_H
+#ifdef CURL_PULL_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+
+/* Configure process defines this to 1 when it finds out that system */
+/* header file sys/poll.h must be included by the external interface. */
+#cmakedefine CURL_PULL_SYS_POLL_H
+#ifdef CURL_PULL_SYS_POLL_H
+# include <sys/poll.h>
+#endif
+
+/* The size of `int', as computed by sizeof. */
+@CURL_SIZEOF_INT_CODE@
+
+/* The size of `long', as computed by sizeof. */
+@CURL_SIZEOF_LONG_CODE@
+
+/* The size of `long long', as computed by sizeof. */
+@CURL_SIZEOF_LONG_LONG_CODE@
+
+/* The size of `ssize_t', as computed by sizeof. */
+@CURL_SIZEOF_SSIZE_T_CODE@
+
+#define CURL_HAVE_SOCKLEN_T @CURL_HAVE_SOCKLEN_T@
+#if CURL_HAVE_SOCKLEN_T
+/* Integral data type used for curl_socklen_t. */
+#define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+
+/* The size of `curl_socklen_t', as computed by sizeof. */
+@CURL_SIZEOF_CURL_SOCKLEN_T_CODE@
+#else
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+# define CURL_SIZEOF_CURL_SOCKLEN_T CURL_SIZEOF_INT
+#endif
+
+/* Data type definition of curl_socklen_t. */
+typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t;
+
+#if CURL_SIZEOF_LONG == 8
+# define CURL_TYPEOF_CURL_OFF_T long
+# define CURL_SIZEOF_CURL_OFF_T 8
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_FORMAT_OFF_T "%ld"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+#elif CURL_SIZEOF_LONG_LONG == 8
+# define CURL_TYPEOF_CURL_OFF_T long long
+# define CURL_SIZEOF_CURL_OFF_T 8
+# define CURL_FORMAT_CURL_OFF_T "lld"
+# define CURL_FORMAT_CURL_OFF_TU "llu"
+# define CURL_FORMAT_OFF_T "%lld"
+# define CURL_SUFFIX_CURL_OFF_T LL
+# define CURL_SUFFIX_CURL_OFF_TU ULL
+#else
+# define CURL_TYPEOF_CURL_OFF_T ssize_t
+# define CURL_SIZEOF_CURL_OFF_T CURL_SIZEOF_SSIZE_T
+/* TODO: need adjustment here. */
+# define CURL_FORMAT_CURL_OFF_T "ld"
+# define CURL_FORMAT_CURL_OFF_TU "lu"
+# define CURL_FORMAT_OFF_T "%ld"
+# define CURL_SUFFIX_CURL_OFF_T L
+# define CURL_SUFFIX_CURL_OFF_TU UL
+#endif
+
+/* Data type definition of curl_off_t. */
+typedef CURL_TYPEOF_CURL_OFF_T curl_off_t;
+
+#endif /* __CURL_CURLBUILD_H */
diff --git a/Utilities/cmcurl/include/curl/curlrules.h b/Utilities/cmcurl/include/curl/curlrules.h
new file mode 100644
index 000000000..7c2ede35b
--- /dev/null
+++ b/Utilities/cmcurl/include/curl/curlrules.h
@@ -0,0 +1,262 @@
+#ifndef __CURL_CURLRULES_H
+#define __CURL_CURLRULES_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* ================================================================ */
+/* COMPILE TIME SANITY CHECKS */
+/* ================================================================ */
+
+/*
+ * NOTE 1:
+ * -------
+ *
+ * All checks done in this file are intentionally placed in a public
+ * header file which is pulled by curl/curl.h when an application is
+ * being built using an already built libcurl library. Additionally
+ * this file is also included and used when building the library.
+ *
+ * If compilation fails on this file it is certainly sure that the
+ * problem is elsewhere. It could be a problem in the curlbuild.h
+ * header file, or simply that you are using different compilation
+ * settings than those used to build the library.
+ *
+ * Nothing in this file is intended to be modified or adjusted by the
+ * curl library user nor by the curl library builder.
+ *
+ * Do not deactivate any check, these are done to make sure that the
+ * library is properly built and used.
+ *
+ * You can find further help on the libcurl development mailing list:
+ * http://cool.haxx.se/mailman/listinfo/curl-library/
+ *
+ * NOTE 2
+ * ------
+ *
+ * Some of the following compile time checks are based on the fact
+ * that the dimension of a constant array can not be a negative one.
+ * In this way if the compile time verification fails, the compilation
+ * will fail issuing an error. The error description wording is compiler
+ * dependent but it will be quite similar to one of the following:
+ *
+ * "negative subscript or subscript is too large"
+ * "array must have at least one element"
+ * "-1 is an illegal array size"
+ * "size of array is negative"
+ *
+ * If you are building an application which tries to use an already
+ * built libcurl library and you are getting this kind of errors on
+ * this file, it is a clear indication that there is a mismatch between
+ * how the library was built and how you are trying to use it for your
+ * application. Your already compiled or binary library provider is the
+ * only one who can give you the details you need to properly use it.
+ */
+
+/*
+ * Verify that some macros are actually defined.
+ */
+
+#ifndef CURL_SIZEOF_LONG
+# error "CURL_SIZEOF_LONG definition is missing!"
+ Error Compilation_aborted_CURL_SIZEOF_LONG_is_missing
+#endif
+
+#ifndef CURL_TYPEOF_CURL_SOCKLEN_T
+# error "CURL_TYPEOF_CURL_SOCKLEN_T definition is missing!"
+ Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_is_missing
+#endif
+
+#ifndef CURL_SIZEOF_CURL_SOCKLEN_T
+# error "CURL_SIZEOF_CURL_SOCKLEN_T definition is missing!"
+ Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_is_missing
+#endif
+
+#ifndef CURL_TYPEOF_CURL_OFF_T
+# error "CURL_TYPEOF_CURL_OFF_T definition is missing!"
+ Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_is_missing
+#endif
+
+#ifndef CURL_FORMAT_CURL_OFF_T
+# error "CURL_FORMAT_CURL_OFF_T definition is missing!"
+ Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_is_missing
+#endif
+
+#ifndef CURL_FORMAT_CURL_OFF_TU
+# error "CURL_FORMAT_CURL_OFF_TU definition is missing!"
+ Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_is_missing
+#endif
+
+#ifndef CURL_FORMAT_OFF_T
+# error "CURL_FORMAT_OFF_T definition is missing!"
+ Error Compilation_aborted_CURL_FORMAT_OFF_T_is_missing
+#endif
+
+#ifndef CURL_SIZEOF_CURL_OFF_T
+# error "CURL_SIZEOF_CURL_OFF_T definition is missing!"
+ Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_is_missing
+#endif
+
+#ifndef CURL_SUFFIX_CURL_OFF_T
+# error "CURL_SUFFIX_CURL_OFF_T definition is missing!"
+ Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_is_missing
+#endif
+
+#ifndef CURL_SUFFIX_CURL_OFF_TU
+# error "CURL_SUFFIX_CURL_OFF_TU definition is missing!"
+ Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_is_missing
+#endif
+
+/*
+ * Macros private to this header file.
+ */
+
+#define CurlchkszEQ(t, s) sizeof(t) == s ? 1 : -1
+
+#define CurlchkszGE(t1, t2) sizeof(t1) >= sizeof(t2) ? 1 : -1
+
+/*
+ * Verify that the size previously defined and expected for long
+ * is the same as the one reported by sizeof() at compile time.
+ */
+
+typedef char
+ __curl_rule_01__
+ [CurlchkszEQ(long, CURL_SIZEOF_LONG)];
+
+/*
+ * Verify that the size previously defined and expected for
+ * curl_off_t is actually the the same as the one reported
+ * by sizeof() at compile time.
+ */
+
+typedef char
+ __curl_rule_02__
+ [CurlchkszEQ(curl_off_t, CURL_SIZEOF_CURL_OFF_T)];
+
+/*
+ * Verify at compile time that the size of curl_off_t as reported
+ * by sizeof() is greater or equal than the one reported for long
+ * for the current compilation.
+ */
+
+typedef char
+ __curl_rule_03__
+ [CurlchkszGE(curl_off_t, long)];
+
+/*
+ * Verify that the size previously defined and expected for
+ * curl_socklen_t is actually the the same as the one reported
+ * by sizeof() at compile time.
+ */
+
+typedef char
+ __curl_rule_04__
+ [CurlchkszEQ(curl_socklen_t, CURL_SIZEOF_CURL_SOCKLEN_T)];
+
+/*
+ * Verify at compile time that the size of curl_socklen_t as reported
+ * by sizeof() is greater or equal than the one reported for int for
+ * the current compilation.
+ */
+
+typedef char
+ __curl_rule_05__
+ [CurlchkszGE(curl_socklen_t, int)];
+
+/* ================================================================ */
+/* EXTERNALLY AND INTERNALLY VISIBLE DEFINITIONS */
+/* ================================================================ */
+
+/*
+ * CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow
+ * these to be visible and exported by the external libcurl interface API,
+ * while also making them visible to the library internals, simply including
+ * curl_setup.h, without actually needing to include curl.h internally.
+ * If some day this section would grow big enough, all this should be moved
+ * to its own header file.
+ */
+
+/*
+ * Figure out if we can use the ## preprocessor operator, which is supported
+ * by ISO/ANSI C and C++. Some compilers support it without setting __STDC__
+ * or __cplusplus so we need to carefully check for them too.
+ */
+
+#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
+ defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \
+ defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \
+ defined(__ILEC400__)
+ /* This compiler is believed to have an ISO compatible preprocessor */
+#define CURL_ISOCPP
+#else
+ /* This compiler is believed NOT to have an ISO compatible preprocessor */
+#undef CURL_ISOCPP
+#endif
+
+/*
+ * Macros for minimum-width signed and unsigned curl_off_t integer constants.
+ */
+
+#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551)
+# define __CURL_OFF_T_C_HLPR2(x) x
+# define __CURL_OFF_T_C_HLPR1(x) __CURL_OFF_T_C_HLPR2(x)
+# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \
+ __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T)
+# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \
+ __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU)
+#else
+# ifdef CURL_ISOCPP
+# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix
+# else
+# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix
+# endif
+# define __CURL_OFF_T_C_HLPR1(Val,Suffix) __CURL_OFF_T_C_HLPR2(Val,Suffix)
+# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T)
+# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU)
+#endif
+
+/*
+ * Get rid of macros private to this header file.
+ */
+
+#undef CurlchkszEQ
+#undef CurlchkszGE
+
+/*
+ * Get rid of macros not intended to exist beyond this point.
+ */
+
+#undef CURL_PULL_WS2TCPIP_H
+#undef CURL_PULL_SYS_TYPES_H
+#undef CURL_PULL_SYS_SOCKET_H
+#undef CURL_PULL_SYS_POLL_H
+#undef CURL_PULL_STDINT_H
+#undef CURL_PULL_INTTYPES_H
+
+#undef CURL_TYPEOF_CURL_SOCKLEN_T
+#undef CURL_TYPEOF_CURL_OFF_T
+
+#ifdef CURL_NO_OLDIES
+#undef CURL_FORMAT_OFF_T /* not required since 7.19.0 - obsoleted in 7.20.0 */
+#endif
+
+#endif /* __CURL_CURLRULES_H */
diff --git a/Utilities/cmcurl/include/curl/curlver.h b/Utilities/cmcurl/include/curl/curlver.h
new file mode 100644
index 000000000..a41fdef1c
--- /dev/null
+++ b/Utilities/cmcurl/include/curl/curlver.h
@@ -0,0 +1,77 @@
+#ifndef __CURL_CURLVER_H
+#define __CURL_CURLVER_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* This header file contains nothing but libcurl version info, generated by
+ a script at release-time. This was made its own header file in 7.11.2 */
+
+/* This is the global package copyright */
+#define LIBCURL_COPYRIGHT "1996 - 2015 Daniel Stenberg, <daniel@haxx.se>."
+
+/* This is the version number of the libcurl package from which this header
+ file origins: */
+#define LIBCURL_VERSION "7.44.0"
+
+/* The numeric version number is also available "in parts" by using these
+ defines: */
+#define LIBCURL_VERSION_MAJOR 7
+#define LIBCURL_VERSION_MINOR 44
+#define LIBCURL_VERSION_PATCH 0
+
+/* This is the numeric version of the libcurl version number, meant for easier
+ parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
+ always follow this syntax:
+
+ 0xXXYYZZ
+
+ Where XX, YY and ZZ are the main version, release and patch numbers in
+ hexadecimal (using 8 bits each). All three numbers are always represented
+ using two digits. 1.2 would appear as "0x010200" while version 9.11.7
+ appears as "0x090b07".
+
+ This 6-digit (24 bits) hexadecimal number does not show pre-release number,
+ and it is always a greater number in a more recent release. It makes
+ comparisons with greater than and less than work.
+
+ Note: This define is the full hex number and _does not_ use the
+ CURL_VERSION_BITS() macro since curl's own configure script greps for it
+ and needs it to contain the full number.
+*/
+#define LIBCURL_VERSION_NUM 0x072C00
+
+/*
+ * This is the date and time when the full source package was created. The
+ * timestamp is not stored in git, as the timestamp is properly set in the
+ * tarballs by the maketgz script.
+ *
+ * The format of the date should follow this template:
+ *
+ * "Mon Feb 12 11:35:33 UTC 2007"
+ */
+#define LIBCURL_TIMESTAMP "DEV"
+
+#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|z)
+#define CURL_AT_LEAST_VERSION(x,y,z) \
+ (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z))
+
+#endif /* __CURL_CURLVER_H */
diff --git a/Utilities/cmcurl/include/curl/easy.h b/Utilities/cmcurl/include/curl/easy.h
new file mode 100644
index 000000000..c1e3e7609
--- /dev/null
+++ b/Utilities/cmcurl/include/curl/easy.h
@@ -0,0 +1,102 @@
+#ifndef __CURL_EASY_H
+#define __CURL_EASY_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+CURL_EXTERN CURL *curl_easy_init(void);
+CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
+CURL_EXTERN CURLcode curl_easy_perform(CURL *curl);
+CURL_EXTERN void curl_easy_cleanup(CURL *curl);
+
+/*
+ * NAME curl_easy_getinfo()
+ *
+ * DESCRIPTION
+ *
+ * Request internal information from the curl session with this function. The
+ * third argument MUST be a pointer to a long, a pointer to a char * or a
+ * pointer to a double (as the documentation describes elsewhere). The data
+ * pointed to will be filled in accordingly and can be relied upon only if the
+ * function returns CURLE_OK. This function is intended to get used *AFTER* a
+ * performed transfer, all results from this function are undefined until the
+ * transfer is completed.
+ */
+CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...);
+
+
+/*
+ * NAME curl_easy_duphandle()
+ *
+ * DESCRIPTION
+ *
+ * Creates a new curl session handle with the same options set for the handle
+ * passed in. Duplicating a handle could only be a matter of cloning data and
+ * options, internal state info and things like persistent connections cannot
+ * be transferred. It is useful in multithreaded applications when you can run
+ * curl_easy_duphandle() for each new thread to avoid a series of identical
+ * curl_easy_setopt() invokes in every thread.
+ */
+CURL_EXTERN CURL* curl_easy_duphandle(CURL *curl);
+
+/*
+ * NAME curl_easy_reset()
+ *
+ * DESCRIPTION
+ *
+ * Re-initializes a CURL handle to the default values. This puts back the
+ * handle to the same state as it was in when it was just created.
+ *
+ * It does keep: live connections, the Session ID cache, the DNS cache and the
+ * cookies.
+ */
+CURL_EXTERN void curl_easy_reset(CURL *curl);
+
+/*
+ * NAME curl_easy_recv()
+ *
+ * DESCRIPTION
+ *
+ * Receives data from the connected socket. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ */
+CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen,
+ size_t *n);
+
+/*
+ * NAME curl_easy_send()
+ *
+ * DESCRIPTION
+ *
+ * Sends data over the connected socket. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ */
+CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer,
+ size_t buflen, size_t *n);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Utilities/cmcurl/include/curl/mprintf.h b/Utilities/cmcurl/include/curl/mprintf.h
new file mode 100644
index 000000000..c6b0d7679
--- /dev/null
+++ b/Utilities/cmcurl/include/curl/mprintf.h
@@ -0,0 +1,74 @@
+#ifndef __CURL_MPRINTF_H
+#define __CURL_MPRINTF_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <stdarg.h>
+#include <stdio.h> /* needed for FILE */
+
+#include "curl.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+CURL_EXTERN int curl_mprintf(const char *format, ...);
+CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...);
+CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...);
+CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength,
+ const char *format, ...);
+CURL_EXTERN int curl_mvprintf(const char *format, va_list args);
+CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args);
+CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args);
+CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength,
+ const char *format, va_list args);
+CURL_EXTERN char *curl_maprintf(const char *format, ...);
+CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args);
+
+#ifdef _MPRINTF_REPLACE
+# undef printf
+# undef fprintf
+# undef sprintf
+# undef vsprintf
+# undef snprintf
+# undef vprintf
+# undef vfprintf
+# undef vsnprintf
+# undef aprintf
+# undef vaprintf
+# define printf curl_mprintf
+# define fprintf curl_mfprintf
+# define sprintf curl_msprintf
+# define vsprintf curl_mvsprintf
+# define snprintf curl_msnprintf
+# define vprintf curl_mvprintf
+# define vfprintf curl_mvfprintf
+# define vsnprintf curl_mvsnprintf
+# define aprintf curl_maprintf
+# define vaprintf curl_mvaprintf
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CURL_MPRINTF_H */
diff --git a/Utilities/cmcurl/include/curl/multi.h b/Utilities/cmcurl/include/curl/multi.h
new file mode 100644
index 000000000..0f1561d0b
--- /dev/null
+++ b/Utilities/cmcurl/include/curl/multi.h
@@ -0,0 +1,435 @@
+#ifndef __CURL_MULTI_H
+#define __CURL_MULTI_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/*
+ This is an "external" header file. Don't give away any internals here!
+
+ GOALS
+
+ o Enable a "pull" interface. The application that uses libcurl decides where
+ and when to ask libcurl to get/send data.
+
+ o Enable multiple simultaneous transfers in the same thread without making it
+ complicated for the application.
+
+ o Enable the application to select() on its own file descriptors and curl's
+ file descriptors simultaneous easily.
+
+*/
+
+/*
+ * This header file should not really need to include "curl.h" since curl.h
+ * itself includes this file and we expect user applications to do #include
+ * <curl/curl.h> without the need for especially including multi.h.
+ *
+ * For some reason we added this include here at one point, and rather than to
+ * break existing (wrongly written) libcurl applications, we leave it as-is
+ * but with this warning attached.
+ */
+#include "curl.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void CURLM;
+
+typedef enum {
+ CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or
+ curl_multi_socket*() soon */
+ CURLM_OK,
+ CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */
+ CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */
+ CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */
+ CURLM_INTERNAL_ERROR, /* this is a libcurl bug */
+ CURLM_BAD_SOCKET, /* the passed in socket argument did not match */
+ CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */
+ CURLM_ADDED_ALREADY, /* an easy handle already added to a multi handle was
+ attempted to get added - again */
+ CURLM_LAST
+} CURLMcode;
+
+/* just to make code nicer when using curl_multi_socket() you can now check
+ for CURLM_CALL_MULTI_SOCKET too in the same style it works for
+ curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */
+#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM
+
+/* bitmask bits for CURLMOPT_PIPELINING */
+#define CURLPIPE_NOTHING 0L
+#define CURLPIPE_HTTP1 1L
+#define CURLPIPE_MULTIPLEX 2L
+
+typedef enum {
+ CURLMSG_NONE, /* first, not used */
+ CURLMSG_DONE, /* This easy handle has completed. 'result' contains
+ the CURLcode of the transfer */
+ CURLMSG_LAST /* last, not used */
+} CURLMSG;
+
+struct CURLMsg {
+ CURLMSG msg; /* what this message means */
+ CURL *easy_handle; /* the handle it concerns */
+ union {
+ void *whatever; /* message-specific data */
+ CURLcode result; /* return code for transfer */
+ } data;
+};
+typedef struct CURLMsg CURLMsg;
+
+/* Based on poll(2) structure and values.
+ * We don't use pollfd and POLL* constants explicitly
+ * to cover platforms without poll(). */
+#define CURL_WAIT_POLLIN 0x0001
+#define CURL_WAIT_POLLPRI 0x0002
+#define CURL_WAIT_POLLOUT 0x0004
+
+struct curl_waitfd {
+ curl_socket_t fd;
+ short events;
+ short revents; /* not supported yet */
+};
+
+/*
+ * Name: curl_multi_init()
+ *
+ * Desc: inititalize multi-style curl usage
+ *
+ * Returns: a new CURLM handle to use in all 'curl_multi' functions.
+ */
+CURL_EXTERN CURLM *curl_multi_init(void);
+
+/*
+ * Name: curl_multi_add_handle()
+ *
+ * Desc: add a standard curl handle to the multi stack
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle,
+ CURL *curl_handle);
+
+ /*
+ * Name: curl_multi_remove_handle()
+ *
+ * Desc: removes a curl handle from the multi stack again
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
+ CURL *curl_handle);
+
+ /*
+ * Name: curl_multi_fdset()
+ *
+ * Desc: Ask curl for its fd_set sets. The app can use these to select() or
+ * poll() on. We want curl_multi_perform() called as soon as one of
+ * them are ready.
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle,
+ fd_set *read_fd_set,
+ fd_set *write_fd_set,
+ fd_set *exc_fd_set,
+ int *max_fd);
+
+/*
+ * Name: curl_multi_wait()
+ *
+ * Desc: Poll on all fds within a CURLM set as well as any
+ * additional fds passed to the function.
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle,
+ struct curl_waitfd extra_fds[],
+ unsigned int extra_nfds,
+ int timeout_ms,
+ int *ret);
+
+ /*
+ * Name: curl_multi_perform()
+ *
+ * Desc: When the app thinks there's data available for curl it calls this
+ * function to read/write whatever there is right now. This returns
+ * as soon as the reads and writes are done. This function does not
+ * require that there actually is data available for reading or that
+ * data can be written, it can be called just in case. It returns
+ * the number of handles that still transfer data in the second
+ * argument's integer-pointer.
+ *
+ * Returns: CURLMcode type, general multi error code. *NOTE* that this only
+ * returns errors etc regarding the whole multi stack. There might
+ * still have occurred problems on invidual transfers even when this
+ * returns OK.
+ */
+CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle,
+ int *running_handles);
+
+ /*
+ * Name: curl_multi_cleanup()
+ *
+ * Desc: Cleans up and removes a whole multi stack. It does not free or
+ * touch any individual easy handles in any way. We need to define
+ * in what state those handles will be if this function is called
+ * in the middle of a transfer.
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle);
+
+/*
+ * Name: curl_multi_info_read()
+ *
+ * Desc: Ask the multi handle if there's any messages/informationals from
+ * the individual transfers. Messages include informationals such as
+ * error code from the transfer or just the fact that a transfer is
+ * completed. More details on these should be written down as well.
+ *
+ * Repeated calls to this function will return a new struct each
+ * time, until a special "end of msgs" struct is returned as a signal
+ * that there is no more to get at this point.
+ *
+ * The data the returned pointer points to will not survive calling
+ * curl_multi_cleanup().
+ *
+ * The 'CURLMsg' struct is meant to be very simple and only contain
+ * very basic information. If more involved information is wanted,
+ * we will provide the particular "transfer handle" in that struct
+ * and that should/could/would be used in subsequent
+ * curl_easy_getinfo() calls (or similar). The point being that we
+ * must never expose complex structs to applications, as then we'll
+ * undoubtably get backwards compatibility problems in the future.
+ *
+ * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out
+ * of structs. It also writes the number of messages left in the
+ * queue (after this read) in the integer the second argument points
+ * to.
+ */
+CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle,
+ int *msgs_in_queue);
+
+/*
+ * Name: curl_multi_strerror()
+ *
+ * Desc: The curl_multi_strerror function may be used to turn a CURLMcode
+ * value into the equivalent human readable error string. This is
+ * useful for printing meaningful error messages.
+ *
+ * Returns: A pointer to a zero-terminated error message.
+ */
+CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
+
+/*
+ * Name: curl_multi_socket() and
+ * curl_multi_socket_all()
+ *
+ * Desc: An alternative version of curl_multi_perform() that allows the
+ * application to pass in one of the file descriptors that have been
+ * detected to have "action" on them and let libcurl perform.
+ * See man page for details.
+ */
+#define CURL_POLL_NONE 0
+#define CURL_POLL_IN 1
+#define CURL_POLL_OUT 2
+#define CURL_POLL_INOUT 3
+#define CURL_POLL_REMOVE 4
+
+#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD
+
+#define CURL_CSELECT_IN 0x01
+#define CURL_CSELECT_OUT 0x02
+#define CURL_CSELECT_ERR 0x04
+
+typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */
+ curl_socket_t s, /* socket */
+ int what, /* see above */
+ void *userp, /* private callback
+ pointer */
+ void *socketp); /* private socket
+ pointer */
+/*
+ * Name: curl_multi_timer_callback
+ *
+ * Desc: Called by libcurl whenever the library detects a change in the
+ * maximum number of milliseconds the app is allowed to wait before
+ * curl_multi_socket() or curl_multi_perform() must be called
+ * (to allow libcurl's timed events to take place).
+ *
+ * Returns: The callback should return zero.
+ */
+typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */
+ long timeout_ms, /* see above */
+ void *userp); /* private callback
+ pointer */
+
+CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
+ int *running_handles);
+
+CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle,
+ curl_socket_t s,
+ int ev_bitmask,
+ int *running_handles);
+
+CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle,
+ int *running_handles);
+
+#ifndef CURL_ALLOW_OLD_MULTI_SOCKET
+/* This macro below was added in 7.16.3 to push users who recompile to use
+ the new curl_multi_socket_action() instead of the old curl_multi_socket()
+*/
+#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z)
+#endif
+
+/*
+ * Name: curl_multi_timeout()
+ *
+ * Desc: Returns the maximum number of milliseconds the app is allowed to
+ * wait before curl_multi_socket() or curl_multi_perform() must be
+ * called (to allow libcurl's timed events to take place).
+ *
+ * Returns: CURLM error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle,
+ long *milliseconds);
+
+#undef CINIT /* re-using the same name as in curl.h */
+
+#ifdef CURL_ISOCPP
+#define CINIT(name,type,num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num
+#else
+/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
+#define LONG CURLOPTTYPE_LONG
+#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT
+#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT
+#define OFF_T CURLOPTTYPE_OFF_T
+#define CINIT(name,type,number) CURLMOPT_/**/name = type + number
+#endif
+
+typedef enum {
+ /* This is the socket callback function pointer */
+ CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1),
+
+ /* This is the argument passed to the socket callback */
+ CINIT(SOCKETDATA, OBJECTPOINT, 2),
+
+ /* set to 1 to enable pipelining for this multi handle */
+ CINIT(PIPELINING, LONG, 3),
+
+ /* This is the timer callback function pointer */
+ CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4),
+
+ /* This is the argument passed to the timer callback */
+ CINIT(TIMERDATA, OBJECTPOINT, 5),
+
+ /* maximum number of entries in the connection cache */
+ CINIT(MAXCONNECTS, LONG, 6),
+
+ /* maximum number of (pipelining) connections to one host */
+ CINIT(MAX_HOST_CONNECTIONS, LONG, 7),
+
+ /* maximum number of requests in a pipeline */
+ CINIT(MAX_PIPELINE_LENGTH, LONG, 8),
+
+ /* a connection with a content-length longer than this
+ will not be considered for pipelining */
+ CINIT(CONTENT_LENGTH_PENALTY_SIZE, OFF_T, 9),
+
+ /* a connection with a chunk length longer than this
+ will not be considered for pipelining */
+ CINIT(CHUNK_LENGTH_PENALTY_SIZE, OFF_T, 10),
+
+ /* a list of site names(+port) that are blacklisted from
+ pipelining */
+ CINIT(PIPELINING_SITE_BL, OBJECTPOINT, 11),
+
+ /* a list of server types that are blacklisted from
+ pipelining */
+ CINIT(PIPELINING_SERVER_BL, OBJECTPOINT, 12),
+
+ /* maximum number of open connections in total */
+ CINIT(MAX_TOTAL_CONNECTIONS, LONG, 13),
+
+ /* This is the server push callback function pointer */
+ CINIT(PUSHFUNCTION, FUNCTIONPOINT, 14),
+
+ /* This is the argument passed to the server push callback */
+ CINIT(PUSHDATA, OBJECTPOINT, 15),
+
+ CURLMOPT_LASTENTRY /* the last unused */
+} CURLMoption;
+
+
+/*
+ * Name: curl_multi_setopt()
+ *
+ * Desc: Sets options for the multi handle.
+ *
+ * Returns: CURLM error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle,
+ CURLMoption option, ...);
+
+
+/*
+ * Name: curl_multi_assign()
+ *
+ * Desc: This function sets an association in the multi handle between the
+ * given socket and a private pointer of the application. This is
+ * (only) useful for curl_multi_socket uses.
+ *
+ * Returns: CURLM error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle,
+ curl_socket_t sockfd, void *sockp);
+
+
+/*
+ * Name: curl_push_callback
+ *
+ * Desc: This callback gets called when a new stream is being pushed by the
+ * server. It approves or denies the new stream.
+ *
+ * Returns: CURL_PUSH_OK or CURL_PUSH_DENY.
+ */
+#define CURL_PUSH_OK 0
+#define CURL_PUSH_DENY 1
+
+struct curl_pushheaders; /* forward declaration only */
+
+CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h,
+ size_t num);
+CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h,
+ const char *name);
+
+typedef int (*curl_push_callback)(CURL *parent,
+ CURL *easy,
+ size_t num_headers,
+ struct curl_pushheaders *headers,
+ void *userp);
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif
diff --git a/Utilities/cmcurl/include/curl/stdcheaders.h b/Utilities/cmcurl/include/curl/stdcheaders.h
new file mode 100644
index 000000000..ad82ef633
--- /dev/null
+++ b/Utilities/cmcurl/include/curl/stdcheaders.h
@@ -0,0 +1,33 @@
+#ifndef __STDC_HEADERS_H
+#define __STDC_HEADERS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <sys/types.h>
+
+size_t fread (void *, size_t, size_t, FILE *);
+size_t fwrite (const void *, size_t, size_t, FILE *);
+
+int strcasecmp(const char *, const char *);
+int strncasecmp(const char *, const char *, size_t);
+
+#endif /* __STDC_HEADERS_H */
diff --git a/Utilities/cmcurl/include/curl/typecheck-gcc.h b/Utilities/cmcurl/include/curl/typecheck-gcc.h
new file mode 100644
index 000000000..13fb0fa9e
--- /dev/null
+++ b/Utilities/cmcurl/include/curl/typecheck-gcc.h
@@ -0,0 +1,612 @@
+#ifndef __CURL_TYPECHECK_GCC_H
+#define __CURL_TYPECHECK_GCC_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* wraps curl_easy_setopt() with typechecking */
+
+/* To add a new kind of warning, add an
+ * if(_curl_is_sometype_option(_curl_opt))
+ * if(!_curl_is_sometype(value))
+ * _curl_easy_setopt_err_sometype();
+ * block and define _curl_is_sometype_option, _curl_is_sometype and
+ * _curl_easy_setopt_err_sometype below
+ *
+ * NOTE: We use two nested 'if' statements here instead of the && operator, in
+ * order to work around gcc bug #32061. It affects only gcc 4.3.x/4.4.x
+ * when compiling with -Wlogical-op.
+ *
+ * To add an option that uses the same type as an existing option, you'll just
+ * need to extend the appropriate _curl_*_option macro
+ */
+#define curl_easy_setopt(handle, option, value) \
+__extension__ ({ \
+ __typeof__ (option) _curl_opt = option; \
+ if(__builtin_constant_p(_curl_opt)) { \
+ if(_curl_is_long_option(_curl_opt)) \
+ if(!_curl_is_long(value)) \
+ _curl_easy_setopt_err_long(); \
+ if(_curl_is_off_t_option(_curl_opt)) \
+ if(!_curl_is_off_t(value)) \
+ _curl_easy_setopt_err_curl_off_t(); \
+ if(_curl_is_string_option(_curl_opt)) \
+ if(!_curl_is_string(value)) \
+ _curl_easy_setopt_err_string(); \
+ if(_curl_is_write_cb_option(_curl_opt)) \
+ if(!_curl_is_write_cb(value)) \
+ _curl_easy_setopt_err_write_callback(); \
+ if((_curl_opt) == CURLOPT_READFUNCTION) \
+ if(!_curl_is_read_cb(value)) \
+ _curl_easy_setopt_err_read_cb(); \
+ if((_curl_opt) == CURLOPT_IOCTLFUNCTION) \
+ if(!_curl_is_ioctl_cb(value)) \
+ _curl_easy_setopt_err_ioctl_cb(); \
+ if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \
+ if(!_curl_is_sockopt_cb(value)) \
+ _curl_easy_setopt_err_sockopt_cb(); \
+ if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \
+ if(!_curl_is_opensocket_cb(value)) \
+ _curl_easy_setopt_err_opensocket_cb(); \
+ if((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \
+ if(!_curl_is_progress_cb(value)) \
+ _curl_easy_setopt_err_progress_cb(); \
+ if((_curl_opt) == CURLOPT_DEBUGFUNCTION) \
+ if(!_curl_is_debug_cb(value)) \
+ _curl_easy_setopt_err_debug_cb(); \
+ if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \
+ if(!_curl_is_ssl_ctx_cb(value)) \
+ _curl_easy_setopt_err_ssl_ctx_cb(); \
+ if(_curl_is_conv_cb_option(_curl_opt)) \
+ if(!_curl_is_conv_cb(value)) \
+ _curl_easy_setopt_err_conv_cb(); \
+ if((_curl_opt) == CURLOPT_SEEKFUNCTION) \
+ if(!_curl_is_seek_cb(value)) \
+ _curl_easy_setopt_err_seek_cb(); \
+ if(_curl_is_cb_data_option(_curl_opt)) \
+ if(!_curl_is_cb_data(value)) \
+ _curl_easy_setopt_err_cb_data(); \
+ if((_curl_opt) == CURLOPT_ERRORBUFFER) \
+ if(!_curl_is_error_buffer(value)) \
+ _curl_easy_setopt_err_error_buffer(); \
+ if((_curl_opt) == CURLOPT_STDERR) \
+ if(!_curl_is_FILE(value)) \
+ _curl_easy_setopt_err_FILE(); \
+ if(_curl_is_postfields_option(_curl_opt)) \
+ if(!_curl_is_postfields(value)) \
+ _curl_easy_setopt_err_postfields(); \
+ if((_curl_opt) == CURLOPT_HTTPPOST) \
+ if(!_curl_is_arr((value), struct curl_httppost)) \
+ _curl_easy_setopt_err_curl_httpost(); \
+ if(_curl_is_slist_option(_curl_opt)) \
+ if(!_curl_is_arr((value), struct curl_slist)) \
+ _curl_easy_setopt_err_curl_slist(); \
+ if((_curl_opt) == CURLOPT_SHARE) \
+ if(!_curl_is_ptr((value), CURLSH)) \
+ _curl_easy_setopt_err_CURLSH(); \
+ } \
+ curl_easy_setopt(handle, _curl_opt, value); \
+})
+
+/* wraps curl_easy_getinfo() with typechecking */
+/* FIXME: don't allow const pointers */
+#define curl_easy_getinfo(handle, info, arg) \
+__extension__ ({ \
+ __typeof__ (info) _curl_info = info; \
+ if(__builtin_constant_p(_curl_info)) { \
+ if(_curl_is_string_info(_curl_info)) \
+ if(!_curl_is_arr((arg), char *)) \
+ _curl_easy_getinfo_err_string(); \
+ if(_curl_is_long_info(_curl_info)) \
+ if(!_curl_is_arr((arg), long)) \
+ _curl_easy_getinfo_err_long(); \
+ if(_curl_is_double_info(_curl_info)) \
+ if(!_curl_is_arr((arg), double)) \
+ _curl_easy_getinfo_err_double(); \
+ if(_curl_is_slist_info(_curl_info)) \
+ if(!_curl_is_arr((arg), struct curl_slist *)) \
+ _curl_easy_getinfo_err_curl_slist(); \
+ } \
+ curl_easy_getinfo(handle, _curl_info, arg); \
+})
+
+/* TODO: typechecking for curl_share_setopt() and curl_multi_setopt(),
+ * for now just make sure that the functions are called with three
+ * arguments
+ */
+#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
+#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
+
+
+/* the actual warnings, triggered by calling the _curl_easy_setopt_err*
+ * functions */
+
+/* To define a new warning, use _CURL_WARNING(identifier, "message") */
+#define _CURL_WARNING(id, message) \
+ static void __attribute__((__warning__(message))) \
+ __attribute__((__unused__)) __attribute__((__noinline__)) \
+ id(void) { __asm__(""); }
+
+_CURL_WARNING(_curl_easy_setopt_err_long,
+ "curl_easy_setopt expects a long argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_curl_off_t,
+ "curl_easy_setopt expects a curl_off_t argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_string,
+ "curl_easy_setopt expects a "
+ "string (char* or char[]) argument for this option"
+ )
+_CURL_WARNING(_curl_easy_setopt_err_write_callback,
+ "curl_easy_setopt expects a curl_write_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_read_cb,
+ "curl_easy_setopt expects a curl_read_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb,
+ "curl_easy_setopt expects a curl_ioctl_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb,
+ "curl_easy_setopt expects a curl_sockopt_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb,
+ "curl_easy_setopt expects a "
+ "curl_opensocket_callback argument for this option"
+ )
+_CURL_WARNING(_curl_easy_setopt_err_progress_cb,
+ "curl_easy_setopt expects a curl_progress_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_debug_cb,
+ "curl_easy_setopt expects a curl_debug_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb,
+ "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_conv_cb,
+ "curl_easy_setopt expects a curl_conv_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_seek_cb,
+ "curl_easy_setopt expects a curl_seek_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_cb_data,
+ "curl_easy_setopt expects a "
+ "private data pointer as argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_error_buffer,
+ "curl_easy_setopt expects a "
+ "char buffer of CURL_ERROR_SIZE as argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_FILE,
+ "curl_easy_setopt expects a FILE* argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_postfields,
+ "curl_easy_setopt expects a void* or char* argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_curl_httpost,
+ "curl_easy_setopt expects a struct curl_httppost* argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_curl_slist,
+ "curl_easy_setopt expects a struct curl_slist* argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_CURLSH,
+ "curl_easy_setopt expects a CURLSH* argument for this option")
+
+_CURL_WARNING(_curl_easy_getinfo_err_string,
+ "curl_easy_getinfo expects a pointer to char * for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_long,
+ "curl_easy_getinfo expects a pointer to long for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_double,
+ "curl_easy_getinfo expects a pointer to double for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
+ "curl_easy_getinfo expects a pointer to struct curl_slist * for this info")
+
+/* groups of curl_easy_setops options that take the same type of argument */
+
+/* To add a new option to one of the groups, just add
+ * (option) == CURLOPT_SOMETHING
+ * to the or-expression. If the option takes a long or curl_off_t, you don't
+ * have to do anything
+ */
+
+/* evaluates to true if option takes a long argument */
+#define _curl_is_long_option(option) \
+ (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT)
+
+#define _curl_is_off_t_option(option) \
+ ((option) > CURLOPTTYPE_OFF_T)
+
+/* evaluates to true if option takes a char* argument */
+#define _curl_is_string_option(option) \
+ ((option) == CURLOPT_URL || \
+ (option) == CURLOPT_PROXY || \
+ (option) == CURLOPT_INTERFACE || \
+ (option) == CURLOPT_NETRC_FILE || \
+ (option) == CURLOPT_USERPWD || \
+ (option) == CURLOPT_USERNAME || \
+ (option) == CURLOPT_PASSWORD || \
+ (option) == CURLOPT_PROXYUSERPWD || \
+ (option) == CURLOPT_PROXYUSERNAME || \
+ (option) == CURLOPT_PROXYPASSWORD || \
+ (option) == CURLOPT_NOPROXY || \
+ (option) == CURLOPT_ACCEPT_ENCODING || \
+ (option) == CURLOPT_REFERER || \
+ (option) == CURLOPT_USERAGENT || \
+ (option) == CURLOPT_COOKIE || \
+ (option) == CURLOPT_COOKIEFILE || \
+ (option) == CURLOPT_COOKIEJAR || \
+ (option) == CURLOPT_COOKIELIST || \
+ (option) == CURLOPT_FTPPORT || \
+ (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \
+ (option) == CURLOPT_FTP_ACCOUNT || \
+ (option) == CURLOPT_RANGE || \
+ (option) == CURLOPT_CUSTOMREQUEST || \
+ (option) == CURLOPT_SSLCERT || \
+ (option) == CURLOPT_SSLCERTTYPE || \
+ (option) == CURLOPT_SSLKEY || \
+ (option) == CURLOPT_SSLKEYTYPE || \
+ (option) == CURLOPT_KEYPASSWD || \
+ (option) == CURLOPT_SSLENGINE || \
+ (option) == CURLOPT_CAINFO || \
+ (option) == CURLOPT_CAPATH || \
+ (option) == CURLOPT_RANDOM_FILE || \
+ (option) == CURLOPT_EGDSOCKET || \
+ (option) == CURLOPT_SSL_CIPHER_LIST || \
+ (option) == CURLOPT_KRBLEVEL || \
+ (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 || \
+ (option) == CURLOPT_SSH_PUBLIC_KEYFILE || \
+ (option) == CURLOPT_SSH_PRIVATE_KEYFILE || \
+ (option) == CURLOPT_CRLFILE || \
+ (option) == CURLOPT_ISSUERCERT || \
+ (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE || \
+ (option) == CURLOPT_SSH_KNOWNHOSTS || \
+ (option) == CURLOPT_MAIL_FROM || \
+ (option) == CURLOPT_RTSP_SESSION_ID || \
+ (option) == CURLOPT_RTSP_STREAM_URI || \
+ (option) == CURLOPT_RTSP_TRANSPORT || \
+ (option) == CURLOPT_XOAUTH2_BEARER || \
+ (option) == CURLOPT_DNS_SERVERS || \
+ (option) == CURLOPT_DNS_INTERFACE || \
+ (option) == CURLOPT_DNS_LOCAL_IP4 || \
+ (option) == CURLOPT_DNS_LOCAL_IP6 || \
+ (option) == CURLOPT_LOGIN_OPTIONS || \
+ (option) == CURLOPT_PROXY_SERVICE_NAME || \
+ (option) == CURLOPT_SERVICE_NAME || \
+ 0)
+
+/* evaluates to true if option takes a curl_write_callback argument */
+#define _curl_is_write_cb_option(option) \
+ ((option) == CURLOPT_HEADERFUNCTION || \
+ (option) == CURLOPT_WRITEFUNCTION)
+
+/* evaluates to true if option takes a curl_conv_callback argument */
+#define _curl_is_conv_cb_option(option) \
+ ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION || \
+ (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION || \
+ (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION)
+
+/* evaluates to true if option takes a data argument to pass to a callback */
+#define _curl_is_cb_data_option(option) \
+ ((option) == CURLOPT_WRITEDATA || \
+ (option) == CURLOPT_READDATA || \
+ (option) == CURLOPT_IOCTLDATA || \
+ (option) == CURLOPT_SOCKOPTDATA || \
+ (option) == CURLOPT_OPENSOCKETDATA || \
+ (option) == CURLOPT_PROGRESSDATA || \
+ (option) == CURLOPT_HEADERDATA || \
+ (option) == CURLOPT_DEBUGDATA || \
+ (option) == CURLOPT_SSL_CTX_DATA || \
+ (option) == CURLOPT_SEEKDATA || \
+ (option) == CURLOPT_PRIVATE || \
+ (option) == CURLOPT_SSH_KEYDATA || \
+ (option) == CURLOPT_INTERLEAVEDATA || \
+ (option) == CURLOPT_CHUNK_DATA || \
+ (option) == CURLOPT_FNMATCH_DATA || \
+ 0)
+
+/* evaluates to true if option takes a POST data argument (void* or char*) */
+#define _curl_is_postfields_option(option) \
+ ((option) == CURLOPT_POSTFIELDS || \
+ (option) == CURLOPT_COPYPOSTFIELDS || \
+ 0)
+
+/* evaluates to true if option takes a struct curl_slist * argument */
+#define _curl_is_slist_option(option) \
+ ((option) == CURLOPT_HTTPHEADER || \
+ (option) == CURLOPT_HTTP200ALIASES || \
+ (option) == CURLOPT_QUOTE || \
+ (option) == CURLOPT_POSTQUOTE || \
+ (option) == CURLOPT_PREQUOTE || \
+ (option) == CURLOPT_TELNETOPTIONS || \
+ (option) == CURLOPT_MAIL_RCPT || \
+ 0)
+
+/* groups of curl_easy_getinfo infos that take the same type of argument */
+
+/* evaluates to true if info expects a pointer to char * argument */
+#define _curl_is_string_info(info) \
+ (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG)
+
+/* evaluates to true if info expects a pointer to long argument */
+#define _curl_is_long_info(info) \
+ (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE)
+
+/* evaluates to true if info expects a pointer to double argument */
+#define _curl_is_double_info(info) \
+ (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST)
+
+/* true if info expects a pointer to struct curl_slist * argument */
+#define _curl_is_slist_info(info) \
+ (CURLINFO_SLIST < (info))
+
+
+/* typecheck helpers -- check whether given expression has requested type*/
+
+/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros,
+ * otherwise define a new macro. Search for __builtin_types_compatible_p
+ * in the GCC manual.
+ * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is
+ * the actual expression passed to the curl_easy_setopt macro. This
+ * means that you can only apply the sizeof and __typeof__ operators, no
+ * == or whatsoever.
+ */
+
+/* XXX: should evaluate to true iff expr is a pointer */
+#define _curl_is_any_ptr(expr) \
+ (sizeof(expr) == sizeof(void*))
+
+/* evaluates to true if expr is NULL */
+/* XXX: must not evaluate expr, so this check is not accurate */
+#define _curl_is_NULL(expr) \
+ (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL)))
+
+/* evaluates to true if expr is type*, const type* or NULL */
+#define _curl_is_ptr(expr, type) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), type *) || \
+ __builtin_types_compatible_p(__typeof__(expr), const type *))
+
+/* evaluates to true if expr is one of type[], type*, NULL or const type* */
+#define _curl_is_arr(expr, type) \
+ (_curl_is_ptr((expr), type) || \
+ __builtin_types_compatible_p(__typeof__(expr), type []))
+
+/* evaluates to true if expr is a string */
+#define _curl_is_string(expr) \
+ (_curl_is_arr((expr), char) || \
+ _curl_is_arr((expr), signed char) || \
+ _curl_is_arr((expr), unsigned char))
+
+/* evaluates to true if expr is a long (no matter the signedness)
+ * XXX: for now, int is also accepted (and therefore short and char, which
+ * are promoted to int when passed to a variadic function) */
+#define _curl_is_long(expr) \
+ (__builtin_types_compatible_p(__typeof__(expr), long) || \
+ __builtin_types_compatible_p(__typeof__(expr), signed long) || \
+ __builtin_types_compatible_p(__typeof__(expr), unsigned long) || \
+ __builtin_types_compatible_p(__typeof__(expr), int) || \
+ __builtin_types_compatible_p(__typeof__(expr), signed int) || \
+ __builtin_types_compatible_p(__typeof__(expr), unsigned int) || \
+ __builtin_types_compatible_p(__typeof__(expr), short) || \
+ __builtin_types_compatible_p(__typeof__(expr), signed short) || \
+ __builtin_types_compatible_p(__typeof__(expr), unsigned short) || \
+ __builtin_types_compatible_p(__typeof__(expr), char) || \
+ __builtin_types_compatible_p(__typeof__(expr), signed char) || \
+ __builtin_types_compatible_p(__typeof__(expr), unsigned char))
+
+/* evaluates to true if expr is of type curl_off_t */
+#define _curl_is_off_t(expr) \
+ (__builtin_types_compatible_p(__typeof__(expr), curl_off_t))
+
+/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */
+/* XXX: also check size of an char[] array? */
+#define _curl_is_error_buffer(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), char *) || \
+ __builtin_types_compatible_p(__typeof__(expr), char[]))
+
+/* evaluates to true if expr is of type (const) void* or (const) FILE* */
+#if 0
+#define _curl_is_cb_data(expr) \
+ (_curl_is_ptr((expr), void) || \
+ _curl_is_ptr((expr), FILE))
+#else /* be less strict */
+#define _curl_is_cb_data(expr) \
+ _curl_is_any_ptr(expr)
+#endif
+
+/* evaluates to true if expr is of type FILE* */
+#define _curl_is_FILE(expr) \
+ (__builtin_types_compatible_p(__typeof__(expr), FILE *))
+
+/* evaluates to true if expr can be passed as POST data (void* or char*) */
+#define _curl_is_postfields(expr) \
+ (_curl_is_ptr((expr), void) || \
+ _curl_is_arr((expr), char))
+
+/* FIXME: the whole callback checking is messy...
+ * The idea is to tolerate char vs. void and const vs. not const
+ * pointers in arguments at least
+ */
+/* helper: __builtin_types_compatible_p distinguishes between functions and
+ * function pointers, hide it */
+#define _curl_callback_compatible(func, type) \
+ (__builtin_types_compatible_p(__typeof__(func), type) || \
+ __builtin_types_compatible_p(__typeof__(func), type*))
+
+/* evaluates to true if expr is of type curl_read_callback or "similar" */
+#define _curl_is_read_cb(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), __typeof__(fread)) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_read_callback) || \
+ _curl_callback_compatible((expr), _curl_read_callback1) || \
+ _curl_callback_compatible((expr), _curl_read_callback2) || \
+ _curl_callback_compatible((expr), _curl_read_callback3) || \
+ _curl_callback_compatible((expr), _curl_read_callback4) || \
+ _curl_callback_compatible((expr), _curl_read_callback5) || \
+ _curl_callback_compatible((expr), _curl_read_callback6))
+typedef size_t (_curl_read_callback1)(char *, size_t, size_t, void*);
+typedef size_t (_curl_read_callback2)(char *, size_t, size_t, const void*);
+typedef size_t (_curl_read_callback3)(char *, size_t, size_t, FILE*);
+typedef size_t (_curl_read_callback4)(void *, size_t, size_t, void*);
+typedef size_t (_curl_read_callback5)(void *, size_t, size_t, const void*);
+typedef size_t (_curl_read_callback6)(void *, size_t, size_t, FILE*);
+
+/* evaluates to true if expr is of type curl_write_callback or "similar" */
+#define _curl_is_write_cb(expr) \
+ (_curl_is_read_cb(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), __typeof__(fwrite)) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_write_callback) || \
+ _curl_callback_compatible((expr), _curl_write_callback1) || \
+ _curl_callback_compatible((expr), _curl_write_callback2) || \
+ _curl_callback_compatible((expr), _curl_write_callback3) || \
+ _curl_callback_compatible((expr), _curl_write_callback4) || \
+ _curl_callback_compatible((expr), _curl_write_callback5) || \
+ _curl_callback_compatible((expr), _curl_write_callback6))
+typedef size_t (_curl_write_callback1)(const char *, size_t, size_t, void*);
+typedef size_t (_curl_write_callback2)(const char *, size_t, size_t,
+ const void*);
+typedef size_t (_curl_write_callback3)(const char *, size_t, size_t, FILE*);
+typedef size_t (_curl_write_callback4)(const void *, size_t, size_t, void*);
+typedef size_t (_curl_write_callback5)(const void *, size_t, size_t,
+ const void*);
+typedef size_t (_curl_write_callback6)(const void *, size_t, size_t, FILE*);
+
+/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */
+#define _curl_is_ioctl_cb(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_ioctl_callback) || \
+ _curl_callback_compatible((expr), _curl_ioctl_callback1) || \
+ _curl_callback_compatible((expr), _curl_ioctl_callback2) || \
+ _curl_callback_compatible((expr), _curl_ioctl_callback3) || \
+ _curl_callback_compatible((expr), _curl_ioctl_callback4))
+typedef curlioerr (_curl_ioctl_callback1)(CURL *, int, void*);
+typedef curlioerr (_curl_ioctl_callback2)(CURL *, int, const void*);
+typedef curlioerr (_curl_ioctl_callback3)(CURL *, curliocmd, void*);
+typedef curlioerr (_curl_ioctl_callback4)(CURL *, curliocmd, const void*);
+
+/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */
+#define _curl_is_sockopt_cb(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_sockopt_callback) || \
+ _curl_callback_compatible((expr), _curl_sockopt_callback1) || \
+ _curl_callback_compatible((expr), _curl_sockopt_callback2))
+typedef int (_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype);
+typedef int (_curl_sockopt_callback2)(const void *, curl_socket_t,
+ curlsocktype);
+
+/* evaluates to true if expr is of type curl_opensocket_callback or
+ "similar" */
+#define _curl_is_opensocket_cb(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_opensocket_callback) ||\
+ _curl_callback_compatible((expr), _curl_opensocket_callback1) || \
+ _curl_callback_compatible((expr), _curl_opensocket_callback2) || \
+ _curl_callback_compatible((expr), _curl_opensocket_callback3) || \
+ _curl_callback_compatible((expr), _curl_opensocket_callback4))
+typedef curl_socket_t (_curl_opensocket_callback1)
+ (void *, curlsocktype, struct curl_sockaddr *);
+typedef curl_socket_t (_curl_opensocket_callback2)
+ (void *, curlsocktype, const struct curl_sockaddr *);
+typedef curl_socket_t (_curl_opensocket_callback3)
+ (const void *, curlsocktype, struct curl_sockaddr *);
+typedef curl_socket_t (_curl_opensocket_callback4)
+ (const void *, curlsocktype, const struct curl_sockaddr *);
+
+/* evaluates to true if expr is of type curl_progress_callback or "similar" */
+#define _curl_is_progress_cb(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_progress_callback) || \
+ _curl_callback_compatible((expr), _curl_progress_callback1) || \
+ _curl_callback_compatible((expr), _curl_progress_callback2))
+typedef int (_curl_progress_callback1)(void *,
+ double, double, double, double);
+typedef int (_curl_progress_callback2)(const void *,
+ double, double, double, double);
+
+/* evaluates to true if expr is of type curl_debug_callback or "similar" */
+#define _curl_is_debug_cb(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_debug_callback) || \
+ _curl_callback_compatible((expr), _curl_debug_callback1) || \
+ _curl_callback_compatible((expr), _curl_debug_callback2) || \
+ _curl_callback_compatible((expr), _curl_debug_callback3) || \
+ _curl_callback_compatible((expr), _curl_debug_callback4) || \
+ _curl_callback_compatible((expr), _curl_debug_callback5) || \
+ _curl_callback_compatible((expr), _curl_debug_callback6) || \
+ _curl_callback_compatible((expr), _curl_debug_callback7) || \
+ _curl_callback_compatible((expr), _curl_debug_callback8))
+typedef int (_curl_debug_callback1) (CURL *,
+ curl_infotype, char *, size_t, void *);
+typedef int (_curl_debug_callback2) (CURL *,
+ curl_infotype, char *, size_t, const void *);
+typedef int (_curl_debug_callback3) (CURL *,
+ curl_infotype, const char *, size_t, void *);
+typedef int (_curl_debug_callback4) (CURL *,
+ curl_infotype, const char *, size_t, const void *);
+typedef int (_curl_debug_callback5) (CURL *,
+ curl_infotype, unsigned char *, size_t, void *);
+typedef int (_curl_debug_callback6) (CURL *,
+ curl_infotype, unsigned char *, size_t, const void *);
+typedef int (_curl_debug_callback7) (CURL *,
+ curl_infotype, const unsigned char *, size_t, void *);
+typedef int (_curl_debug_callback8) (CURL *,
+ curl_infotype, const unsigned char *, size_t, const void *);
+
+/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */
+/* this is getting even messier... */
+#define _curl_is_ssl_ctx_cb(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_ssl_ctx_callback) || \
+ _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) || \
+ _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) || \
+ _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) || \
+ _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) || \
+ _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) || \
+ _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) || \
+ _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) || \
+ _curl_callback_compatible((expr), _curl_ssl_ctx_callback8))
+typedef CURLcode (_curl_ssl_ctx_callback1)(CURL *, void *, void *);
+typedef CURLcode (_curl_ssl_ctx_callback2)(CURL *, void *, const void *);
+typedef CURLcode (_curl_ssl_ctx_callback3)(CURL *, const void *, void *);
+typedef CURLcode (_curl_ssl_ctx_callback4)(CURL *, const void *, const void *);
+#ifdef HEADER_SSL_H
+/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX
+ * this will of course break if we're included before OpenSSL headers...
+ */
+typedef CURLcode (_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *);
+typedef CURLcode (_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *);
+typedef CURLcode (_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *);
+typedef CURLcode (_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX,
+ const void *);
+#else
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8;
+#endif
+
+/* evaluates to true if expr is of type curl_conv_callback or "similar" */
+#define _curl_is_conv_cb(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_conv_callback) || \
+ _curl_callback_compatible((expr), _curl_conv_callback1) || \
+ _curl_callback_compatible((expr), _curl_conv_callback2) || \
+ _curl_callback_compatible((expr), _curl_conv_callback3) || \
+ _curl_callback_compatible((expr), _curl_conv_callback4))
+typedef CURLcode (*_curl_conv_callback1)(char *, size_t length);
+typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length);
+typedef CURLcode (*_curl_conv_callback3)(void *, size_t length);
+typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length);
+
+/* evaluates to true if expr is of type curl_seek_callback or "similar" */
+#define _curl_is_seek_cb(expr) \
+ (_curl_is_NULL(expr) || \
+ __builtin_types_compatible_p(__typeof__(expr), curl_seek_callback) || \
+ _curl_callback_compatible((expr), _curl_seek_callback1) || \
+ _curl_callback_compatible((expr), _curl_seek_callback2))
+typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int);
+typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int);
+
+
+#endif /* __CURL_TYPECHECK_GCC_H */
diff --git a/Utilities/cmcurl/inet_ntoa_r.h b/Utilities/cmcurl/inet_ntoa_r.h
deleted file mode 100644
index c6c9bd895..000000000
--- a/Utilities/cmcurl/inet_ntoa_r.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifndef __INET_NTOA_R_H
-#define __INET_NTOA_R_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#ifdef HAVE_INET_NTOA_R_2_ARGS
-/*
- * uClibc 0.9.26 (at least) doesn't define this prototype. The buffer
- * must be at least 16 characters long.
- */
-char *inet_ntoa_r(const struct in_addr in, char buffer[]);
-
-#else
-/*
- * My solaris 5.6 system running gcc 2.8.1 does *not* have this prototype
- * in any system include file! Isn't that weird?
- */
-char *inet_ntoa_r(const struct in_addr in, char *buffer, int buflen);
-
-#endif
-
-#endif
diff --git a/Utilities/cmcurl/inet_ntop.c b/Utilities/cmcurl/inet_ntop.c
deleted file mode 100644
index 9381963f5..000000000
--- a/Utilities/cmcurl/inet_ntop.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 1996-2001 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
- * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
- * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-/*
- * Original code by Paul Vixie. "curlified" by Gisle Vanem.
- */
-
-#include "setup.h"
-
-#ifndef HAVE_INET_NTOP
-
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#include <string.h>
-#include <errno.h>
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-#include "inet_ntop.h"
-
-#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
-/* this platform has a inet_ntoa_r() function, but no proto declared anywhere
- so we include our own proto to make compilers happy */
-#include "inet_ntoa_r.h"
-#endif
-
-#define IN6ADDRSZ 16
-#define INADDRSZ 4
-#define INT16SZ 2
-
-#ifdef USE_WINSOCK
-#define EAFNOSUPPORT WSAEAFNOSUPPORT
-#define SET_ERRNO(e) WSASetLastError(errno = (e))
-#else
-#define SET_ERRNO(e) errno = e
-#endif
-
-/*
- * Format an IPv4 address, more or less like inet_ntoa().
- *
- * Returns `dst' (as a const)
- * Note:
- * - uses no statics
- * - takes a unsigned char* not an in_addr as input
- */
-static char *inet_ntop4 (const unsigned char *src, char *dst, size_t size)
-{
-#if defined(HAVE_INET_NTOA_R_2_ARGS)
- const char *ptr;
- curlassert(size >= 16);
- ptr = inet_ntoa_r(*(struct in_addr*)src, dst);
- return (char *)memmove(dst, ptr, strlen(ptr)+1);
-
-#elif defined(HAVE_INET_NTOA_R)
- return inet_ntoa_r(*(struct in_addr*)src, dst, size);
-
-#else
- const char *addr = inet_ntoa(*(struct in_addr*)src);
-
- if (strlen(addr) >= size)
- {
- SET_ERRNO(ENOSPC);
- return (NULL);
- }
- return strcpy(dst, addr);
-#endif
-}
-
-#ifdef ENABLE_IPV6
-/*
- * Convert IPv6 binary address into presentation (printable) format.
- */
-static char *inet_ntop6 (const unsigned char *src, char *dst, size_t size)
-{
- /*
- * Note that int32_t and int16_t need only be "at least" large enough
- * to contain a value of the specified size. On some systems, like
- * Crays, there is no such thing as an integer variable with 16 bits.
- * Keep this in mind if you think this function should have been coded
- * to use pointer overlays. All the world's not a VAX.
- */
- char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
- char *tp;
- struct {
- long base;
- long len;
- } best, cur;
- unsigned long words[IN6ADDRSZ / INT16SZ];
- int i;
-
- /* Preprocess:
- * Copy the input (bytewise) array into a wordwise array.
- * Find the longest run of 0x00's in src[] for :: shorthanding.
- */
- memset(words, '\0', sizeof(words));
- for (i = 0; i < IN6ADDRSZ; i++)
- words[i/2] |= (src[i] << ((1 - (i % 2)) << 3));
-
- best.base = -1;
- cur.base = -1;
- best.len = 0;
- cur.len = 0;
-
- for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
- {
- if (words[i] == 0)
- {
- if (cur.base == -1)
- cur.base = i, cur.len = 1;
- else
- cur.len++;
- }
- else if (cur.base != -1)
- {
- if (best.base == -1 || cur.len > best.len)
- best = cur;
- cur.base = -1;
- }
- }
- if ((cur.base != -1) && (best.base == -1 || cur.len > best.len))
- best = cur;
- if (best.base != -1 && best.len < 2)
- best.base = -1;
-
- /* Format the result.
- */
- tp = tmp;
- for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
- {
- /* Are we inside the best run of 0x00's?
- */
- if (best.base != -1 && i >= best.base && i < (best.base + best.len))
- {
- if (i == best.base)
- *tp++ = ':';
- continue;
- }
-
- /* Are we following an initial run of 0x00s or any real hex?
- */
- if (i != 0)
- *tp++ = ':';
-
- /* Is this address an encapsulated IPv4?
- */
- if (i == 6 && best.base == 0 &&
- (best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
- {
- if (!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp)))
- {
- SET_ERRNO(ENOSPC);
- return (NULL);
- }
- tp += strlen(tp);
- break;
- }
- tp += snprintf(tp, 5, "%lx", words[i]);
- }
-
- /* Was it a trailing run of 0x00's?
- */
- if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
- *tp++ = ':';
- *tp++ = '\0';
-
- /* Check for overflow, copy, and we're done.
- */
- if ((size_t)(tp - tmp) > size)
- {
- SET_ERRNO(ENOSPC);
- return (NULL);
- }
- return strcpy (dst, tmp);
-}
-#endif /* ENABLE_IPV6 */
-
-/*
- * Convert a network format address to presentation format.
- *
- * Returns pointer to presentation format address (`buf'),
- * Returns NULL on error (see errno).
- */
-char *Curl_inet_ntop(int af, const void *src, char *buf, size_t size)
-{
- switch (af) {
- case AF_INET:
- return inet_ntop4((const unsigned char*)src, buf, size);
-#ifdef ENABLE_IPV6
- case AF_INET6:
- return inet_ntop6((const unsigned char*)src, buf, size);
-#endif
- default:
- SET_ERRNO(EAFNOSUPPORT);
- return NULL;
- }
-}
-#endif /* HAVE_INET_NTOP */
diff --git a/Utilities/cmcurl/inet_ntop.h b/Utilities/cmcurl/inet_ntop.h
deleted file mode 100644
index 54d64bd19..000000000
--- a/Utilities/cmcurl/inet_ntop.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef __INET_NTOP_H
-#define __INET_NTOP_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-char *Curl_inet_ntop(int af, const void *addr, char *buf, size_t size);
-
-#ifdef HAVE_INET_NTOP
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#define Curl_inet_ntop(af,addr,buf,size) inet_ntop(af,addr,buf,size)
-#endif
-
-#endif /* __INET_NTOP_H */
diff --git a/Utilities/cmcurl/inet_pton.c b/Utilities/cmcurl/inet_pton.c
deleted file mode 100644
index 9b9f88b5e..000000000
--- a/Utilities/cmcurl/inet_pton.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/* This is from the BIND 4.9.4 release, modified to compile by itself */
-
-/* Copyright (c) 1996 by Internet Software Consortium.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
- * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-#include "setup.h"
-
-#ifndef HAVE_INET_PTON
-
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#include <string.h>
-#include <errno.h>
-
-#include "inet_pton.h"
-
-#define IN6ADDRSZ 16
-#define INADDRSZ 4
-#define INT16SZ 2
-
-#ifdef USE_WINSOCK
-#define EAFNOSUPPORT WSAEAFNOSUPPORT
-#endif
-
-/*
- * WARNING: Don't even consider trying to compile this on a system where
- * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
- */
-
-static int inet_pton4(const char *src, unsigned char *dst);
-#ifdef ENABLE_IPV6
-static int inet_pton6(const char *src, unsigned char *dst);
-#endif
-
-/* int
- * inet_pton(af, src, dst)
- * convert from presentation format (which usually means ASCII printable)
- * to network format (which is usually some kind of binary format).
- * return:
- * 1 if the address was valid for the specified address family
- * 0 if the address wasn't valid (`dst' is untouched in this case)
- * -1 if some other error occurred (`dst' is untouched in this case, too)
- * author:
- * Paul Vixie, 1996.
- */
-int
-Curl_inet_pton(int af, const char *src, void *dst)
-{
- switch (af) {
- case AF_INET:
- return (inet_pton4(src, (unsigned char *)dst));
-#ifdef ENABLE_IPV6
-#ifndef AF_INET6
-#define AF_INET6 (AF_MAX+1) /* just to let this compile */
-#endif
- case AF_INET6:
- return (inet_pton6(src, (unsigned char *)dst));
-#endif
- default:
- errno = EAFNOSUPPORT;
- return (-1);
- }
- /* NOTREACHED */
-}
-
-/* int
- * inet_pton4(src, dst)
- * like inet_aton() but without all the hexadecimal and shorthand.
- * return:
- * 1 if `src' is a valid dotted quad, else 0.
- * notice:
- * does not touch `dst' unless it's returning 1.
- * author:
- * Paul Vixie, 1996.
- */
-static int
-inet_pton4(const char *src, unsigned char *dst)
-{
- static const char digits[] = "0123456789";
- int saw_digit, octets, ch;
- unsigned char tmp[INADDRSZ], *tp;
-
- saw_digit = 0;
- octets = 0;
- tp = tmp;
- *tp = 0;
- while ((ch = *src++) != '\0') {
- const char *pch;
-
- if ((pch = strchr(digits, ch)) != NULL) {
- unsigned int val = *tp * 10 + (unsigned int)(pch - digits);
-
- if (val > 255)
- return (0);
- *tp = val;
- if (! saw_digit) {
- if (++octets > 4)
- return (0);
- saw_digit = 1;
- }
- } else if (ch == '.' && saw_digit) {
- if (octets == 4)
- return (0);
- *++tp = 0;
- saw_digit = 0;
- } else
- return (0);
- }
- if (octets < 4)
- return (0);
- /* bcopy(tmp, dst, INADDRSZ); */
- memcpy(dst, tmp, INADDRSZ);
- return (1);
-}
-
-#ifdef ENABLE_IPV6
-/* int
- * inet_pton6(src, dst)
- * convert presentation level address to network order binary form.
- * return:
- * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
- * notice:
- * (1) does not touch `dst' unless it's returning 1.
- * (2) :: in a full address is silently ignored.
- * credit:
- * inspired by Mark Andrews.
- * author:
- * Paul Vixie, 1996.
- */
-static int
-inet_pton6(const char *src, unsigned char *dst)
-{
- static const char xdigits_l[] = "0123456789abcdef",
- xdigits_u[] = "0123456789ABCDEF";
- unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
- const char *xdigits, *curtok;
- int ch, saw_xdigit;
- unsigned int val;
-
- memset((tp = tmp), 0, IN6ADDRSZ);
- endp = tp + IN6ADDRSZ;
- colonp = NULL;
- /* Leading :: requires some special handling. */
- if (*src == ':')
- if (*++src != ':')
- return (0);
- curtok = src;
- saw_xdigit = 0;
- val = 0;
- while ((ch = *src++) != '\0') {
- const char *pch;
-
- if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
- pch = strchr((xdigits = xdigits_u), ch);
- if (pch != NULL) {
- val <<= 4;
- val |= (pch - xdigits);
- if (val > 0xffff)
- return (0);
- saw_xdigit = 1;
- continue;
- }
- if (ch == ':') {
- curtok = src;
- if (!saw_xdigit) {
- if (colonp)
- return (0);
- colonp = tp;
- continue;
- }
- if (tp + INT16SZ > endp)
- return (0);
- *tp++ = (unsigned char) (val >> 8) & 0xff;
- *tp++ = (unsigned char) val & 0xff;
- saw_xdigit = 0;
- val = 0;
- continue;
- }
- if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
- inet_pton4(curtok, tp) > 0) {
- tp += INADDRSZ;
- saw_xdigit = 0;
- break; /* '\0' was seen by inet_pton4(). */
- }
- return (0);
- }
- if (saw_xdigit) {
- if (tp + INT16SZ > endp)
- return (0);
- *tp++ = (unsigned char) (val >> 8) & 0xff;
- *tp++ = (unsigned char) val & 0xff;
- }
- if (colonp != NULL) {
- /*
- * Since some memmove()'s erroneously fail to handle
- * overlapping regions, we'll do the shift by hand.
- */
- const int n = tp - colonp;
- int i;
-
- for (i = 1; i <= n; i++) {
- endp[- i] = colonp[n - i];
- colonp[n - i] = 0;
- }
- tp = endp;
- }
- if (tp != endp)
- return (0);
- /* bcopy(tmp, dst, IN6ADDRSZ); */
- memcpy(dst, tmp, IN6ADDRSZ);
- return (1);
-}
-#endif /* ENABLE_IPV6 */
-
-#endif /* HAVE_INET_PTON */
diff --git a/Utilities/cmcurl/inet_pton.h b/Utilities/cmcurl/inet_pton.h
deleted file mode 100644
index a659a9774..000000000
--- a/Utilities/cmcurl/inet_pton.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef __INET_PTON_H
-#define __INET_PTON_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-int Curl_inet_pton(int, const char *, void *);
-
-#ifdef HAVE_INET_PTON
-
-#if defined(HAVE_NO_INET_PTON_PROTO)
-int inet_pton(int af, const char *src, void *dst);
-#endif
-
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#define Curl_inet_pton(x,y,z) inet_pton(x,y,z)
-#endif
-
-#endif /* __INET_PTON_H */
diff --git a/Utilities/cmcurl/krb4.c b/Utilities/cmcurl/krb4.c
deleted file mode 100644
index f2b91df69..000000000
--- a/Utilities/cmcurl/krb4.c
+++ /dev/null
@@ -1,425 +0,0 @@
-/* This source code was modified by Martin Hedenfalk <mhe@stacken.kth.se> for
- * use in Curl. Martin's latest changes were done 2000-09-18.
- *
- * It has since been patched away like a madman by Daniel Stenberg to make it
- * better applied to curl conditions, and to make it not use globals, pollute
- * name space and more.
- *
- * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * Copyright (c) 2004 - 2007 Daniel Stenberg
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * 3. Neither the name of the Institute nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- */
-
-#include "setup.h"
-
-#ifndef CURL_DISABLE_FTP
-#ifdef HAVE_KRB4
-
-#include <stdlib.h>
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#include <string.h>
-#include <krb.h>
-#include <des.h>
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h> /* for getpid() */
-#endif
-
-#include "urldata.h"
-#include "base64.h"
-#include "ftp.h"
-#include "sendf.h"
-#include "krb4.h"
-#include "memory.h"
-
-#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
-#include "inet_ntoa_r.h"
-#endif
-
-/* The last #include file should be: */
-#include "memdebug.h"
-
-#define LOCAL_ADDR (&conn->local_addr)
-#define REMOTE_ADDR conn->ip_addr->ai_addr
-#define myctladdr LOCAL_ADDR
-#define hisctladdr REMOTE_ADDR
-
-struct krb4_data {
- des_cblock key;
- des_key_schedule schedule;
- char name[ANAME_SZ];
- char instance[INST_SZ];
- char realm[REALM_SZ];
-};
-
-#ifndef HAVE_STRLCPY
-/* if it ever goes non-static, make it Curl_ prefixed! */
-static size_t
-strlcpy (char *dst, const char *src, size_t dst_sz)
-{
- size_t n;
- char *p;
-
- for (p = dst, n = 0;
- n + 1 < dst_sz && *src != '\0';
- ++p, ++src, ++n)
- *p = *src;
- *p = '\0';
- if (*src == '\0')
- return n;
- else
- return n + strlen (src);
-}
-#else
-size_t strlcpy (char *dst, const char *src, size_t dst_sz);
-#endif
-
-static int
-krb4_check_prot(void *app_data, int level)
-{
- app_data = NULL; /* prevent compiler warning */
- if(level == prot_confidential)
- return -1;
- return 0;
-}
-
-static int
-krb4_decode(void *app_data, void *buf, int len, int level,
- struct connectdata *conn)
-{
- MSG_DAT m;
- int e;
- struct krb4_data *d = app_data;
-
- if(level == prot_safe)
- e = krb_rd_safe(buf, len, &d->key,
- (struct sockaddr_in *)REMOTE_ADDR,
- (struct sockaddr_in *)LOCAL_ADDR, &m);
- else
- e = krb_rd_priv(buf, len, d->schedule, &d->key,
- (struct sockaddr_in *)REMOTE_ADDR,
- (struct sockaddr_in *)LOCAL_ADDR, &m);
- if(e) {
- struct SessionHandle *data = conn->data;
- infof(data, "krb4_decode: %s\n", krb_get_err_text(e));
- return -1;
- }
- memmove(buf, m.app_data, m.app_length);
- return m.app_length;
-}
-
-static int
-krb4_overhead(void *app_data, int level, int len)
-{
- /* no arguments are used, just init them to prevent compiler warnings */
- app_data = NULL;
- level = 0;
- len = 0;
- return 31;
-}
-
-static int
-krb4_encode(void *app_data, void *from, int length, int level, void **to,
- struct connectdata *conn)
-{
- struct krb4_data *d = app_data;
- *to = malloc(length + 31);
- if(level == prot_safe)
- return krb_mk_safe(from, *to, length, &d->key,
- (struct sockaddr_in *)LOCAL_ADDR,
- (struct sockaddr_in *)REMOTE_ADDR);
- else if(level == prot_private)
- return krb_mk_priv(from, *to, length, d->schedule, &d->key,
- (struct sockaddr_in *)LOCAL_ADDR,
- (struct sockaddr_in *)REMOTE_ADDR);
- else
- return -1;
-}
-
-static int
-mk_auth(struct krb4_data *d, KTEXT adat,
- const char *service, char *host, int checksum)
-{
- int ret;
- CREDENTIALS cred;
- char sname[SNAME_SZ], inst[INST_SZ], realm[REALM_SZ];
-
- strlcpy(sname, service, sizeof(sname));
- strlcpy(inst, krb_get_phost(host), sizeof(inst));
- strlcpy(realm, krb_realmofhost(host), sizeof(realm));
- ret = krb_mk_req(adat, sname, inst, realm, checksum);
- if(ret)
- return ret;
- strlcpy(sname, service, sizeof(sname));
- strlcpy(inst, krb_get_phost(host), sizeof(inst));
- strlcpy(realm, krb_realmofhost(host), sizeof(realm));
- ret = krb_get_cred(sname, inst, realm, &cred);
- memmove(&d->key, &cred.session, sizeof(des_cblock));
- des_key_sched(&d->key, d->schedule);
- memset(&cred, 0, sizeof(cred));
- return ret;
-}
-
-#ifdef HAVE_KRB_GET_OUR_IP_FOR_REALM
-int krb_get_our_ip_for_realm(char *, struct in_addr *);
-#endif
-
-static int
-krb4_auth(void *app_data, struct connectdata *conn)
-{
- int ret;
- char *p;
- unsigned char *ptr;
- size_t len;
- KTEXT_ST adat;
- MSG_DAT msg_data;
- int checksum;
- u_int32_t cs;
- struct krb4_data *d = app_data;
- char *host = conn->host.name;
- ssize_t nread;
- int l = sizeof(conn->local_addr);
- struct SessionHandle *data = conn->data;
- CURLcode result;
-
- if(getsockname(conn->sock[FIRSTSOCKET],
- (struct sockaddr *)LOCAL_ADDR, &l) < 0)
- perror("getsockname()");
-
- checksum = getpid();
- ret = mk_auth(d, &adat, "ftp", host, checksum);
- if(ret == KDC_PR_UNKNOWN)
- ret = mk_auth(d, &adat, "rcmd", host, checksum);
- if(ret) {
- infof(data, "%s\n", krb_get_err_text(ret));
- return AUTH_CONTINUE;
- }
-
-#ifdef HAVE_KRB_GET_OUR_IP_FOR_REALM
- if (krb_get_config_bool("nat_in_use")) {
- struct sockaddr_in *localaddr = (struct sockaddr_in *)LOCAL_ADDR;
- struct in_addr natAddr;
-
- if (krb_get_our_ip_for_realm(krb_realmofhost(host),
- &natAddr) != KSUCCESS
- && krb_get_our_ip_for_realm(NULL, &natAddr) != KSUCCESS)
- infof(data, "Can't get address for realm %s\n",
- krb_realmofhost(host));
- else {
- if (natAddr.s_addr != localaddr->sin_addr.s_addr) {
-#ifdef HAVE_INET_NTOA_R
- char ntoa_buf[64];
- char *ip = (char *)inet_ntoa_r(natAddr, ntoa_buf, sizeof(ntoa_buf));
-#else
- char *ip = (char *)inet_ntoa(natAddr);
-#endif
- infof(data, "Using NAT IP address (%s) for kerberos 4\n", ip);
- localaddr->sin_addr = natAddr;
- }
- }
- }
-#endif
-
- if(Curl_base64_encode(conn->data, (char *)adat.dat, adat.length, &p) < 1) {
- Curl_failf(data, "Out of memory base64-encoding");
- return AUTH_CONTINUE;
- }
-
- result = Curl_ftpsendf(conn, "ADAT %s", p);
-
- free(p);
-
- if(result)
- return -2;
-
- if(Curl_GetFTPResponse(&nread, conn, NULL))
- return -1;
-
- if(data->state.buffer[0] != '2'){
- Curl_failf(data, "Server didn't accept auth data");
- return AUTH_ERROR;
- }
-
- p = strstr(data->state.buffer, "ADAT=");
- if(!p) {
- Curl_failf(data, "Remote host didn't send adat reply");
- return AUTH_ERROR;
- }
- p += 5;
- len = Curl_base64_decode(p, &ptr);
- if(len > sizeof(adat.dat)-1) {
- free(ptr);
- len=0;
- }
- if(!len || !ptr) {
- Curl_failf(data, "Failed to decode base64 from server");
- return AUTH_ERROR;
- }
- memcpy((char *)adat.dat, ptr, len);
- free(ptr);
- adat.length = len;
- ret = krb_rd_safe(adat.dat, adat.length, &d->key,
- (struct sockaddr_in *)hisctladdr,
- (struct sockaddr_in *)myctladdr, &msg_data);
- if(ret) {
- Curl_failf(data, "Error reading reply from server: %s",
- krb_get_err_text(ret));
- return AUTH_ERROR;
- }
- krb_get_int(msg_data.app_data, &cs, 4, 0);
- if(cs - checksum != 1) {
- Curl_failf(data, "Bad checksum returned from server");
- return AUTH_ERROR;
- }
- return AUTH_OK;
-}
-
-struct Curl_sec_client_mech Curl_krb4_client_mech = {
- "KERBEROS_V4",
- sizeof(struct krb4_data),
- NULL, /* init */
- krb4_auth,
- NULL, /* end */
- krb4_check_prot,
- krb4_overhead,
- krb4_encode,
- krb4_decode
-};
-
-CURLcode Curl_krb_kauth(struct connectdata *conn)
-{
- des_cblock key;
- des_key_schedule schedule;
- KTEXT_ST tkt, tktcopy;
- char *name;
- char *p;
- char passwd[100];
- size_t tmp;
- ssize_t nread;
- int save;
- CURLcode result;
- unsigned char *ptr;
-
- save = Curl_set_command_prot(conn, prot_private);
-
- result = Curl_ftpsendf(conn, "SITE KAUTH %s", conn->user);
-
- if(result)
- return result;
-
- result = Curl_GetFTPResponse(&nread, conn, NULL);
- if(result)
- return result;
-
- if(conn->data->state.buffer[0] != '3'){
- Curl_set_command_prot(conn, save);
- return CURLE_FTP_WEIRD_SERVER_REPLY;
- }
-
- p = strstr(conn->data->state.buffer, "T=");
- if(!p) {
- Curl_failf(conn->data, "Bad reply from server");
- Curl_set_command_prot(conn, save);
- return CURLE_FTP_WEIRD_SERVER_REPLY;
- }
-
- p += 2;
- tmp = Curl_base64_decode(p, &ptr);
- if(tmp >= sizeof(tkt.dat)) {
- free(ptr);
- tmp=0;
- }
- if(!tmp || !ptr) {
- Curl_failf(conn->data, "Failed to decode base64 in reply.\n");
- Curl_set_command_prot(conn, save);
- return CURLE_FTP_WEIRD_SERVER_REPLY;
- }
- memcpy((char *)tkt.dat, ptr, tmp);
- free(ptr);
- tkt.length = tmp;
- tktcopy.length = tkt.length;
-
- p = strstr(conn->data->state.buffer, "P=");
- if(!p) {
- Curl_failf(conn->data, "Bad reply from server");
- Curl_set_command_prot(conn, save);
- return CURLE_FTP_WEIRD_SERVER_REPLY;
- }
- name = p + 2;
- for(; *p && *p != ' ' && *p != '\r' && *p != '\n'; p++);
- *p = 0;
-
- des_string_to_key (conn->passwd, &key);
- des_key_sched(&key, schedule);
-
- des_pcbc_encrypt((void *)tkt.dat, (void *)tktcopy.dat,
- tkt.length,
- schedule, &key, DES_DECRYPT);
- if (strcmp ((char*)tktcopy.dat + 8,
- KRB_TICKET_GRANTING_TICKET) != 0) {
- afs_string_to_key(passwd,
- krb_realmofhost(conn->host.name),
- &key);
- des_key_sched(&key, schedule);
- des_pcbc_encrypt((void *)tkt.dat, (void *)tktcopy.dat,
- tkt.length,
- schedule, &key, DES_DECRYPT);
- }
- memset(key, 0, sizeof(key));
- memset(schedule, 0, sizeof(schedule));
- memset(passwd, 0, sizeof(passwd));
- if(Curl_base64_encode(conn->data, (char *)tktcopy.dat, tktcopy.length, &p)
- < 1) {
- failf(conn->data, "Out of memory base64-encoding.");
- Curl_set_command_prot(conn, save);
- return CURLE_OUT_OF_MEMORY;
- }
- memset (tktcopy.dat, 0, tktcopy.length);
-
- result = Curl_ftpsendf(conn, "SITE KAUTH %s %s", name, p);
- free(p);
- if(result)
- return result;
-
- result = Curl_GetFTPResponse(&nread, conn, NULL);
- if(result)
- return result;
- Curl_set_command_prot(conn, save);
-
- return CURLE_OK;
-}
-
-#endif /* HAVE_KRB4 */
-#endif /* CURL_DISABLE_FTP */
diff --git a/Utilities/cmcurl/krb4.h b/Utilities/cmcurl/krb4.h
deleted file mode 100644
index f46416e62..000000000
--- a/Utilities/cmcurl/krb4.h
+++ /dev/null
@@ -1,70 +0,0 @@
-#ifndef __KRB4_H
-#define __KRB4_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-struct Curl_sec_client_mech {
- const char *name;
- size_t size;
- int (*init)(void *);
- int (*auth)(void *, struct connectdata *);
- void (*end)(void *);
- int (*check_prot)(void *, int);
- int (*overhead)(void *, int, int);
- int (*encode)(void *, void*, int, int, void**, struct connectdata *);
- int (*decode)(void *, void*, int, int, struct connectdata *);
-};
-
-
-#define AUTH_OK 0
-#define AUTH_CONTINUE 1
-#define AUTH_ERROR 2
-
-extern struct Curl_sec_client_mech Curl_krb4_client_mech;
-
-CURLcode Curl_krb_kauth(struct connectdata *conn);
-int Curl_sec_fflush_fd(struct connectdata *conn, int fd);
-int Curl_sec_fprintf (struct connectdata *, FILE *, const char *, ...);
-int Curl_sec_getc (struct connectdata *conn, FILE *);
-int Curl_sec_putc (struct connectdata *conn, int, FILE *);
-int Curl_sec_read (struct connectdata *conn, int, void *, int);
-int Curl_sec_read_msg (struct connectdata *conn, char *, int);
-
-int Curl_sec_vfprintf(struct connectdata *, FILE *, const char *, va_list);
-int Curl_sec_fprintf2(struct connectdata *conn, FILE *f, const char *fmt, ...);
-int Curl_sec_vfprintf2(struct connectdata *conn, FILE *, const char *, va_list);
-ssize_t Curl_sec_send(struct connectdata *conn, int, char *, int);
-int Curl_sec_write(struct connectdata *conn, int, char *, int);
-
-void Curl_sec_end (struct connectdata *);
-int Curl_sec_login (struct connectdata *);
-void Curl_sec_prot (int, char **);
-int Curl_sec_request_prot (struct connectdata *conn, const char *level);
-void Curl_sec_set_protection_level(struct connectdata *conn);
-void Curl_sec_status (void);
-
-enum protection_level Curl_set_command_prot(struct connectdata *,
- enum protection_level);
-
-
-#endif
diff --git a/Utilities/cmcurl/ldap.c b/Utilities/cmcurl/ldap.c
deleted file mode 100644
index 3e1144d4f..000000000
--- a/Utilities/cmcurl/ldap.c
+++ /dev/null
@@ -1,702 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#ifndef CURL_DISABLE_LDAP
-/* -- WIN32 approved -- */
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <ctype.h>
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef NEED_MALLOC_H
-#include <malloc.h>
-#endif
-#include <errno.h>
-
-#if defined(WIN32)
-# include <winldap.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#ifdef HAVE_DLFCN_H
-# include <dlfcn.h>
-#endif
-
-#include "urldata.h"
-#include <curl/curl.h>
-#include "sendf.h"
-#include "escape.h"
-#include "transfer.h"
-#include "strequal.h"
-#include "strtok.h"
-#include "ldap.h"
-#include "memory.h"
-#include "base64.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-#include "memdebug.h"
-
-/* WLdap32.dll functions are *not* stdcall. Must call these via __cdecl
- * pointers in case libcurl was compiled as fastcall (cl -Gr). Watcom
- * uses fastcall by default.
- */
-#if !defined(WIN32) && !defined(__cdecl)
-#define __cdecl
-#endif
-
-#ifndef LDAP_SIZELIMIT_EXCEEDED
-#define LDAP_SIZELIMIT_EXCEEDED 4
-#endif
-#ifndef LDAP_VERSION2
-#define LDAP_VERSION2 2
-#endif
-#ifndef LDAP_VERSION3
-#define LDAP_VERSION3 3
-#endif
-#ifndef LDAP_OPT_PROTOCOL_VERSION
-#define LDAP_OPT_PROTOCOL_VERSION 0x0011
-#endif
-
-#define DLOPEN_MODE RTLD_LAZY /*! assume all dlopen() implementations have
- this */
-
-#if defined(RTLD_LAZY_GLOBAL) /* It turns out some systems use this: */
-# undef DLOPEN_MODE
-# define DLOPEN_MODE RTLD_LAZY_GLOBAL
-#elif defined(RTLD_GLOBAL)
-# undef DLOPEN_MODE
-# define DLOPEN_MODE (RTLD_LAZY | RTLD_GLOBAL)
-#endif
-
-#define DYNA_GET_FUNCTION(type, fnc) do { \
- (fnc) = (type)DynaGetFunction(#fnc); \
- if ((fnc) == NULL) \
- return CURLE_FUNCTION_NOT_FOUND; \
- } while (0)
-
-/*! CygWin etc. configure could set these, but we don't want it.
- * Must use WLdap32.dll code.
- */
-#if defined(WIN32)
-#undef HAVE_DLOPEN
-#undef HAVE_LIBDL
-#endif
-
-/*
- * We use this ZERO_NULL to avoid picky compiler warnings,
- * when assigning a NULL pointer to a function pointer var.
- */
-
-#define ZERO_NULL 0
-
-typedef void * (*dynafunc)(void *input);
-
-/***********************************************************************
- */
-#if defined(HAVE_DLOPEN) || defined(HAVE_LIBDL) || defined(WIN32)
-static void *libldap = NULL;
-#if defined(DL_LBER_FILE)
-static void *liblber = NULL;
-#endif
-#endif
-
-struct bv {
- unsigned long bv_len;
- char *bv_val;
-};
-
-static int DynaOpen(const char **mod_name)
-{
-#if defined(HAVE_DLOPEN) || defined(HAVE_LIBDL)
- if (libldap == NULL) {
- /*
- * libldap.so can normally resolve its dependency on liblber.so
- * automatically, but in broken installation it does not so
- * handle it here by opening liblber.so as global.
- */
-#ifdef DL_LBER_FILE
- *mod_name = DL_LBER_FILE;
- liblber = dlopen(*mod_name, DLOPEN_MODE);
- if (!liblber)
- return 0;
-#endif
-
- /* Assume loading libldap.so will fail if loading of liblber.so failed
- */
- *mod_name = DL_LDAP_FILE;
- libldap = dlopen(*mod_name, RTLD_LAZY);
- }
- return (libldap != NULL);
-
-#elif defined(WIN32)
- *mod_name = DL_LDAP_FILE;
- if (!libldap)
- libldap = (void*)LoadLibrary(*mod_name);
- return (libldap != NULL);
-
-#else
- *mod_name = "";
- return (0);
-#endif
-}
-
-static void DynaClose(void)
-{
-#if defined(HAVE_DLOPEN) || defined(HAVE_LIBDL)
- if (libldap) {
- dlclose(libldap);
- libldap=NULL;
- }
-#ifdef DL_LBER_FILE
- if (liblber) {
- dlclose(liblber);
- liblber=NULL;
- }
-#endif
-#elif defined(WIN32)
- if (libldap) {
- FreeLibrary ((HMODULE)libldap);
- libldap = NULL;
- }
-#endif
-}
-
-static dynafunc DynaGetFunction(const char *name)
-{
- dynafunc func = (dynafunc)ZERO_NULL;
-
-#if defined(HAVE_DLOPEN) || defined(HAVE_LIBDL)
- if (libldap) {
- /* This typecast magic below was brought by Joe Halpin. In ISO C, you
- * cannot typecast a data pointer to a function pointer, but that's
- * exactly what we need to do here to avoid compiler warnings on picky
- * compilers! */
- *(void**) (&func) = dlsym(libldap, name);
- }
-#elif defined(WIN32)
- if (libldap) {
- func = (dynafunc)GetProcAddress((HINSTANCE)libldap, name);
- }
-#else
- (void) name;
-#endif
- return func;
-}
-
-/***********************************************************************
- */
-typedef struct ldap_url_desc {
- struct ldap_url_desc *lud_next;
- char *lud_scheme;
- char *lud_host;
- int lud_port;
- char *lud_dn;
- char **lud_attrs;
- int lud_scope;
- char *lud_filter;
- char **lud_exts;
- int lud_crit_exts;
-} LDAPURLDesc;
-
-#ifdef WIN32
-static int _ldap_url_parse (const struct connectdata *conn,
- LDAPURLDesc **ludp);
-static void _ldap_free_urldesc (LDAPURLDesc *ludp);
-
-static void (*ldap_free_urldesc)(LDAPURLDesc *) = _ldap_free_urldesc;
-#endif
-
-#ifdef DEBUG_LDAP
- #define LDAP_TRACE(x) do { \
- _ldap_trace ("%u: ", __LINE__); \
- _ldap_trace x; \
- } while (0)
-
- static void _ldap_trace (const char *fmt, ...);
-#else
- #define LDAP_TRACE(x) ((void)0)
-#endif
-
-
-CURLcode Curl_ldap(struct connectdata *conn, bool *done)
-{
- CURLcode status = CURLE_OK;
- int rc = 0;
-#ifndef WIN32
- int (*ldap_url_parse)(char *, LDAPURLDesc **);
- void (*ldap_free_urldesc)(void *);
-#endif
- void *(__cdecl *ldap_init)(char *, int);
- int (__cdecl *ldap_simple_bind_s)(void *, char *, char *);
- int (__cdecl *ldap_unbind_s)(void *);
- int (__cdecl *ldap_search_s)(void *, char *, int, char *, char **,
- int, void **);
- void *(__cdecl *ldap_first_entry)(void *, void *);
- void *(__cdecl *ldap_next_entry)(void *, void *);
- char *(__cdecl *ldap_err2string)(int);
- char *(__cdecl *ldap_get_dn)(void *, void *);
- char *(__cdecl *ldap_first_attribute)(void *, void *, void **);
- char *(__cdecl *ldap_next_attribute)(void *, void *, void *);
- void **(__cdecl *ldap_get_values_len)(void *, void *, const char *);
- void (__cdecl *ldap_value_free_len)(void **);
- void (__cdecl *ldap_memfree)(void *);
- void (__cdecl *ber_free)(void *, int);
- int (__cdecl *ldap_set_option)(void *, int, void *);
-
- void *server;
- LDAPURLDesc *ludp = NULL;
- const char *mod_name;
- void *result;
- void *entryIterator; /*! type should be 'LDAPMessage *' */
- int num = 0;
- struct SessionHandle *data=conn->data;
- int ldap_proto;
- char *val_b64;
- size_t val_b64_sz;
-
- *done = TRUE; /* unconditionally */
- infof(data, "LDAP local: %s\n", data->change.url);
-
- if (!DynaOpen(&mod_name)) {
- failf(data, "The %s LDAP library/libraries couldn't be opened", mod_name);
- return CURLE_LIBRARY_NOT_FOUND;
- }
-
- /* The types are needed because ANSI C distinguishes between
- * pointer-to-object (data) and pointer-to-function.
- */
- DYNA_GET_FUNCTION(void *(__cdecl *)(char *, int), ldap_init);
- DYNA_GET_FUNCTION(int (__cdecl *)(void *, char *, char *),
- ldap_simple_bind_s);
- DYNA_GET_FUNCTION(int (__cdecl *)(void *), ldap_unbind_s);
-#ifndef WIN32
- DYNA_GET_FUNCTION(int (*)(char *, LDAPURLDesc **), ldap_url_parse);
- DYNA_GET_FUNCTION(void (*)(void *), ldap_free_urldesc);
-#endif
- DYNA_GET_FUNCTION(int (__cdecl *)(void *, char *, int, char *, char **, int,
- void **), ldap_search_s);
- DYNA_GET_FUNCTION(void *(__cdecl *)(void *, void *), ldap_first_entry);
- DYNA_GET_FUNCTION(void *(__cdecl *)(void *, void *), ldap_next_entry);
- DYNA_GET_FUNCTION(char *(__cdecl *)(int), ldap_err2string);
- DYNA_GET_FUNCTION(char *(__cdecl *)(void *, void *), ldap_get_dn);
- DYNA_GET_FUNCTION(char *(__cdecl *)(void *, void *, void **),
- ldap_first_attribute);
- DYNA_GET_FUNCTION(char *(__cdecl *)(void *, void *, void *),
- ldap_next_attribute);
- DYNA_GET_FUNCTION(void **(__cdecl *)(void *, void *, const char *),
- ldap_get_values_len);
- DYNA_GET_FUNCTION(void (__cdecl *)(void **), ldap_value_free_len);
- DYNA_GET_FUNCTION(void (__cdecl *)(void *), ldap_memfree);
- DYNA_GET_FUNCTION(void (__cdecl *)(void *, int), ber_free);
- DYNA_GET_FUNCTION(int (__cdecl *)(void *, int, void *), ldap_set_option);
-
- server = (*ldap_init)(conn->host.name, (int)conn->port);
- if (server == NULL) {
- failf(data, "LDAP local: Cannot connect to %s:%d",
- conn->host.name, conn->port);
- status = CURLE_COULDNT_CONNECT;
- goto quit;
- }
-
- ldap_proto = LDAP_VERSION3;
- (*ldap_set_option)(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
- rc = (*ldap_simple_bind_s)(server,
- conn->bits.user_passwd ? conn->user : NULL,
- conn->bits.user_passwd ? conn->passwd : NULL);
- if (rc != 0) {
- ldap_proto = LDAP_VERSION2;
- (*ldap_set_option)(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
- rc = (*ldap_simple_bind_s)(server,
- conn->bits.user_passwd ? conn->user : NULL,
- conn->bits.user_passwd ? conn->passwd : NULL);
- }
- if (rc != 0) {
- failf(data, "LDAP local: %s", (*ldap_err2string)(rc));
- status = CURLE_LDAP_CANNOT_BIND;
- goto quit;
- }
-
-#ifdef WIN32
- rc = _ldap_url_parse(conn, &ludp);
-#else
- rc = (*ldap_url_parse)(data->change.url, &ludp);
-#endif
-
- if (rc != 0) {
- failf(data, "LDAP local: %s", (*ldap_err2string)(rc));
- status = CURLE_LDAP_INVALID_URL;
- goto quit;
- }
-
- rc = (*ldap_search_s)(server, ludp->lud_dn, ludp->lud_scope,
- ludp->lud_filter, ludp->lud_attrs, 0, &result);
-
- if (rc != 0 && rc != LDAP_SIZELIMIT_EXCEEDED) {
- failf(data, "LDAP remote: %s", (*ldap_err2string)(rc));
- status = CURLE_LDAP_SEARCH_FAILED;
- goto quit;
- }
-
- for(num = 0, entryIterator = (*ldap_first_entry)(server, result);
- entryIterator;
- entryIterator = (*ldap_next_entry)(server, entryIterator), num++)
- {
- void *ber = NULL; /*! is really 'BerElement **' */
- void *attribute; /*! suspicious that this isn't 'const' */
- char *dn = (*ldap_get_dn)(server, entryIterator);
- int i;
-
- Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
- Curl_client_write(conn, CLIENTWRITE_BODY, (char *)dn, 0);
- Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
-
- for (attribute = (*ldap_first_attribute)(server, entryIterator, &ber);
- attribute;
- attribute = (*ldap_next_attribute)(server, entryIterator, ber))
- {
- struct bv **vals = (struct bv **)
- (*ldap_get_values_len)(server, entryIterator, attribute);
-
- if (vals != NULL)
- {
- for (i = 0; (vals[i] != NULL); i++)
- {
- Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
- Curl_client_write(conn, CLIENTWRITE_BODY, (char *) attribute, 0);
- Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2);
- if ((strlen(attribute) > 7) &&
- (strcmp(";binary",
- (char *)attribute +
- (strlen((char *)attribute) - 7)) == 0)) {
- /* Binary attribute, encode to base64. */
- val_b64_sz = Curl_base64_encode(conn->data,
- vals[i]->bv_val,
- vals[i]->bv_len,
- &val_b64);
- if (val_b64_sz > 0) {
- Curl_client_write(conn, CLIENTWRITE_BODY, val_b64, val_b64_sz);
- free(val_b64);
- }
- } else
- Curl_client_write(conn, CLIENTWRITE_BODY, vals[i]->bv_val,
- vals[i]->bv_len);
- Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
- }
-
- /* Free memory used to store values */
- (*ldap_value_free_len)((void **)vals);
- }
- Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
-
- (*ldap_memfree)(attribute);
- }
- (*ldap_memfree)(dn);
- if (ber)
- (*ber_free)(ber, 0);
- }
-
-quit:
- LDAP_TRACE (("Received %d entries\n", num));
- if (rc == LDAP_SIZELIMIT_EXCEEDED)
- infof(data, "There are more than %d entries\n", num);
- if (ludp)
- (*ldap_free_urldesc)(ludp);
- if (server)
- (*ldap_unbind_s)(server);
-
- DynaClose();
-
- /* no data to transfer */
- Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
- conn->bits.close = TRUE;
-
- return status;
-}
-
-#ifdef DEBUG_LDAP
-static void _ldap_trace (const char *fmt, ...)
-{
- static int do_trace = -1;
- va_list args;
-
- if (do_trace == -1) {
- const char *env = getenv("CURL_TRACE");
- do_trace = (env && atoi(env) > 0);
- }
- if (!do_trace)
- return;
-
- va_start (args, fmt);
- vfprintf (stderr, fmt, args);
- va_end (args);
-}
-#endif
-
-#ifdef WIN32
-/*
- * Return scope-value for a scope-string.
- */
-static int str2scope (const char *p)
-{
- if (!stricmp(p, "one"))
- return LDAP_SCOPE_ONELEVEL;
- if (!stricmp(p, "onetree"))
- return LDAP_SCOPE_ONELEVEL;
- if (!stricmp(p, "base"))
- return LDAP_SCOPE_BASE;
- if (!stricmp(p, "sub"))
- return LDAP_SCOPE_SUBTREE;
- if (!stricmp( p, "subtree"))
- return LDAP_SCOPE_SUBTREE;
- return (-1);
-}
-
-/*
- * Split 'str' into strings separated by commas.
- * Note: res[] points into 'str'.
- */
-static char **split_str (char *str)
-{
- char **res, *lasts, *s;
- int i;
-
- for (i = 2, s = strchr(str,','); s; i++)
- s = strchr(++s,',');
-
- res = calloc(i, sizeof(char*));
- if (!res)
- return NULL;
-
- for (i = 0, s = strtok_r(str, ",", &lasts); s;
- s = strtok_r(NULL, ",", &lasts), i++)
- res[i] = s;
- return res;
-}
-
-/*
- * Unescape the LDAP-URL components
- */
-static bool unescape_elements (void *data, LDAPURLDesc *ludp)
-{
- int i;
-
- if (ludp->lud_filter) {
- ludp->lud_filter = curl_easy_unescape(data, ludp->lud_filter, 0, NULL);
- if (!ludp->lud_filter)
- return (FALSE);
- }
-
- for (i = 0; ludp->lud_attrs && ludp->lud_attrs[i]; i++) {
- ludp->lud_attrs[i] = curl_easy_unescape(data, ludp->lud_attrs[i], 0, NULL);
- if (!ludp->lud_attrs[i])
- return (FALSE);
- }
-
- for (i = 0; ludp->lud_exts && ludp->lud_exts[i]; i++) {
- ludp->lud_exts[i] = curl_easy_unescape(data, ludp->lud_exts[i], 0, NULL);
- if (!ludp->lud_exts[i])
- return (FALSE);
- }
-
- if (ludp->lud_dn) {
- char *dn = ludp->lud_dn;
- char *new_dn = curl_easy_unescape(data, dn, 0, NULL);
-
- free(dn);
- ludp->lud_dn = new_dn;
- if (!new_dn)
- return (FALSE);
- }
- return (TRUE);
-}
-
-/*
- * Break apart the pieces of an LDAP URL.
- * Syntax:
- * ldap://<hostname>:<port>/<base_dn>?<attributes>?<scope>?<filter>?<ext>
- *
- * <hostname> already known from 'conn->host.name'.
- * <port> already known from 'conn->remote_port'.
- * extract the rest from 'conn->data->reqdata.path+1'. All fields are optional.
- * e.g.
- * ldap://<hostname>:<port>/?<attributes>?<scope>?<filter>
- * yields ludp->lud_dn = "".
- *
- * Ref. http://developer.netscape.com/docs/manuals/dirsdk/csdk30/url.htm#2831915
- */
-static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp)
-{
- char *p, *q;
- int i;
-
- if (!conn->data ||
- !conn->data->reqdata.path ||
- conn->data->reqdata.path[0] != '/' ||
- !checkprefix(conn->protostr, conn->data->change.url))
- return LDAP_INVALID_SYNTAX;
-
- ludp->lud_scope = LDAP_SCOPE_BASE;
- ludp->lud_port = conn->remote_port;
- ludp->lud_host = conn->host.name;
-
- /* parse DN (Distinguished Name).
- */
- ludp->lud_dn = strdup(conn->data->reqdata.path+1);
- if (!ludp->lud_dn)
- return LDAP_NO_MEMORY;
-
- p = strchr(ludp->lud_dn, '?');
- LDAP_TRACE (("DN '%.*s'\n", p ? (size_t)(p-ludp->lud_dn) :
- strlen(ludp->lud_dn), ludp->lud_dn));
-
- if (!p)
- goto success;
-
- *p++ = '\0';
-
- /* parse attributes. skip "??".
- */
- q = strchr(p, '?');
- if (q)
- *q++ = '\0';
-
- if (*p && *p != '?') {
- ludp->lud_attrs = split_str(p);
- if (!ludp->lud_attrs)
- return LDAP_NO_MEMORY;
-
- for (i = 0; ludp->lud_attrs[i]; i++)
- LDAP_TRACE (("attr[%d] '%s'\n", i, ludp->lud_attrs[i]));
- }
-
- p = q;
- if (!p)
- goto success;
-
- /* parse scope. skip "??"
- */
- q = strchr(p, '?');
- if (q)
- *q++ = '\0';
-
- if (*p && *p != '?') {
- ludp->lud_scope = str2scope(p);
- if (ludp->lud_scope == -1)
- return LDAP_INVALID_SYNTAX;
- LDAP_TRACE (("scope %d\n", ludp->lud_scope));
- }
-
- p = q;
- if (!p)
- goto success;
-
- /* parse filter
- */
- q = strchr(p, '?');
- if (q)
- *q++ = '\0';
- if (!*p)
- return LDAP_INVALID_SYNTAX;
-
- ludp->lud_filter = p;
- LDAP_TRACE (("filter '%s'\n", ludp->lud_filter));
-
- p = q;
- if (!p)
- goto success;
-
- /* parse extensions
- */
- ludp->lud_exts = split_str(p);
- if (!ludp->lud_exts)
- return LDAP_NO_MEMORY;
-
- for (i = 0; ludp->lud_exts[i]; i++)
- LDAP_TRACE (("exts[%d] '%s'\n", i, ludp->lud_exts[i]));
-
-success:
- if (!unescape_elements(conn->data, ludp))
- return LDAP_NO_MEMORY;
- return LDAP_SUCCESS;
-}
-
-static int _ldap_url_parse (const struct connectdata *conn,
- LDAPURLDesc **ludpp)
-{
- LDAPURLDesc *ludp = calloc(sizeof(*ludp), 1);
- int rc;
-
- *ludpp = NULL;
- if (!ludp)
- return LDAP_NO_MEMORY;
-
- rc = _ldap_url_parse2 (conn, ludp);
- if (rc != LDAP_SUCCESS) {
- _ldap_free_urldesc(ludp);
- ludp = NULL;
- }
- *ludpp = ludp;
- return (rc);
-}
-
-static void _ldap_free_urldesc (LDAPURLDesc *ludp)
-{
- int i;
-
- if (!ludp)
- return;
-
- if (ludp->lud_dn)
- free(ludp->lud_dn);
-
- if (ludp->lud_filter)
- free(ludp->lud_filter);
-
- if (ludp->lud_attrs) {
- for (i = 0; ludp->lud_attrs[i]; i++)
- free(ludp->lud_attrs[i]);
- free(ludp->lud_attrs);
- }
-
- if (ludp->lud_exts) {
- for (i = 0; ludp->lud_exts[i]; i++)
- free(ludp->lud_exts[i]);
- free(ludp->lud_exts);
- }
- free (ludp);
-}
-#endif /* WIN32 */
-#endif /* CURL_DISABLE_LDAP */
diff --git a/Utilities/cmcurl/ldap.h b/Utilities/cmcurl/ldap.h
deleted file mode 100644
index b2d4f3973..000000000
--- a/Utilities/cmcurl/ldap.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef __LDAP_H
-#define __LDAP_H
-
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-#ifndef CURL_DISABLE_LDAP
-CURLcode Curl_ldap(struct connectdata *conn, bool *done);
-#endif
-#endif /* __LDAP_H */
diff --git a/Utilities/cmcurl/lib/CMakeLists.txt b/Utilities/cmcurl/lib/CMakeLists.txt
new file mode 100644
index 000000000..0d7b717b2
--- /dev/null
+++ b/Utilities/cmcurl/lib/CMakeLists.txt
@@ -0,0 +1,129 @@
+set(LIB_NAME cmcurl)
+
+configure_file(${CURL_SOURCE_DIR}/include/curl/curlbuild.h.cmake
+ ${CURL_BINARY_DIR}/include/curl/curlbuild.h)
+configure_file(curl_config.h.cmake
+ ${CMAKE_CURRENT_BINARY_DIR}/curl_config.h)
+
+transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
+include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake)
+
+list(APPEND HHEADERS
+ ${CMAKE_CURRENT_BINARY_DIR}/curl_config.h
+ ${CURL_BINARY_DIR}/include/curl/curlbuild.h
+ )
+
+if(MSVC AND NOT CURL_STATICLIB)
+ list(APPEND CSOURCES libcurl.rc)
+endif()
+
+# SET(CSOURCES
+# # memdebug.c -not used
+# # nwlib.c - Not used
+# # strtok.c - specify later
+# # strtoofft.c - specify later
+# )
+
+# # if we have Kerberos 4, right now this is never on
+# #OPTION(CURL_KRB4 "Use Kerberos 4" OFF)
+# IF(CURL_KRB4)
+# SET(CSOURCES ${CSOURCES}
+# krb4.c
+# security.c
+# )
+# ENDIF(CURL_KRB4)
+
+# #OPTION(CURL_MALLOC_DEBUG "Debug mallocs in Curl" OFF)
+# MARK_AS_ADVANCED(CURL_MALLOC_DEBUG)
+# IF(CURL_MALLOC_DEBUG)
+# SET(CSOURCES ${CSOURCES}
+# memdebug.c
+# )
+# ENDIF(CURL_MALLOC_DEBUG)
+
+# # only build compat strtoofft if we need to
+# IF(NOT HAVE_STRTOLL AND NOT HAVE__STRTOI64)
+# SET(CSOURCES ${CSOURCES}
+# strtoofft.c
+# )
+# ENDIF(NOT HAVE_STRTOLL AND NOT HAVE__STRTOI64)
+
+
+# The rest of the build
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR}/../include)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include)
+include_directories(${CMAKE_CURRENT_BINARY_DIR}/..)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+if(USE_ARES)
+ include_directories(${CARES_INCLUDE_DIR})
+endif()
+
+if(CURL_STATICLIB)
+ # Static lib
+ set(CURL_USER_DEFINED_DYNAMIC_OR_STATIC STATIC)
+else()
+ # DLL / so dynamic lib
+ set(CURL_USER_DEFINED_DYNAMIC_OR_STATIC SHARED)
+endif()
+
+# For windows we want to install OPENSSL_LIBRARIES dlls
+# and also copy them into the build tree so that testing
+# can find them.
+if(CMAKE_USE_OPENSSL AND OPENSSL_FOUND AND WIN32)
+ find_file(CMAKE_EAY_DLL NAME libeay32.dll HINTS ${OPENSSL_INCLUDE_DIR}/..)
+ find_file(CMAKE_SSL_DLL NAME ssleay32.dll HINTS ${OPENSSL_INCLUDE_DIR}/..)
+ mark_as_advanced(CMAKE_EAY_DLL CMAKE_SSL_DLL)
+ if(CMAKE_SSL_DLL AND CMAKE_EAY_DLL)
+ set(CMAKE_CURL_SSL_DLLS ${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/libeay32.dll
+ ${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/ssleay32.dll)
+ add_custom_command(OUTPUT
+ ${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/libeay32.dll
+ DEPENDS ${CMAKE_EAY_DLL}
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_EAY_DLL}
+ ${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/libeay32.dll)
+ add_custom_command(OUTPUT
+ ${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/ssleay32.dll
+ DEPENDS ${CMAKE_SSL_DLL}
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SSL_DLL}
+ ${CMake_BIN_DIR}/${CMAKE_CFG_INTDIR}/ssleay32.dll)
+ install(PROGRAMS ${CMAKE_EAY_DLL} ${CMAKE_SSL_DLL} DESTINATION bin)
+ endif()
+endif()
+
+add_library(
+ ${LIB_NAME}
+ ${CURL_USER_DEFINED_DYNAMIC_OR_STATIC}
+ ${HHEADERS} ${CSOURCES}
+ ${CMAKE_CURL_SSL_DLLS}
+ )
+
+target_link_libraries(${LIB_NAME} ${CURL_LIBS})
+
+if(0) # This code not needed for building within CMake.
+if(WIN32)
+ add_definitions( -D_USRDLL )
+endif()
+endif()
+
+set_target_properties(${LIB_NAME} PROPERTIES COMPILE_DEFINITIONS BUILDING_LIBCURL)
+
+if(0) # This code not needed for building within CMake.
+# Remove the "lib" prefix since the library is already named "libcurl".
+set_target_properties(${LIB_NAME} PROPERTIES PREFIX "")
+set_target_properties(${LIB_NAME} PROPERTIES IMPORT_PREFIX "")
+
+if(WIN32)
+ if(NOT CURL_STATICLIB)
+ # Add "_imp" as a suffix before the extension to avoid conflicting with the statically linked "libcurl.lib"
+ set_target_properties(${LIB_NAME} PROPERTIES IMPORT_SUFFIX "_imp.lib")
+ endif()
+endif()
+
+install(TARGETS ${LIB_NAME}
+ ARCHIVE DESTINATION lib
+ LIBRARY DESTINATION lib
+ RUNTIME DESTINATION bin)
+endif()
diff --git a/Utilities/cmcurl/lib/Makefile.inc b/Utilities/cmcurl/lib/Makefile.inc
new file mode 100644
index 000000000..d444a6b21
--- /dev/null
+++ b/Utilities/cmcurl/lib/Makefile.inc
@@ -0,0 +1,73 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at http://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+
+LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c \
+ vtls/polarssl.c vtls/polarssl_threadlock.c vtls/axtls.c \
+ vtls/cyassl.c vtls/schannel.c vtls/darwinssl.c vtls/gskit.c
+
+LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h \
+ vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h vtls/axtls.h \
+ vtls/cyassl.h vtls/schannel.h vtls/darwinssl.h vtls/gskit.h
+
+LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
+ cookie.c http.c sendf.c ftp.c url.c dict.c if2ip.c speedcheck.c \
+ ldap.c version.c getenv.c escape.c mprintf.c telnet.c netrc.c \
+ getinfo.c transfer.c strequal.c easy.c security.c curl_fnmatch.c \
+ fileinfo.c ftplistparser.c wildcard.c krb5.c memdebug.c http_chunks.c \
+ strtok.c connect.c llist.c hash.c multi.c content_encoding.c share.c \
+ http_digest.c md4.c md5.c http_negotiate.c inet_pton.c strtoofft.c \
+ strerror.c amigaos.c hostasyn.c hostip4.c hostip6.c hostsyn.c \
+ inet_ntop.c parsedate.c select.c tftp.c splay.c strdup.c socks.c \
+ ssh.c rawstr.c curl_addrinfo.c socks_gssapi.c socks_sspi.c \
+ curl_sspi.c slist.c nonblock.c curl_memrchr.c imap.c pop3.c smtp.c \
+ pingpong.c rtsp.c curl_threads.c warnless.c hmac.c curl_rtmp.c \
+ openldap.c curl_gethostname.c gopher.c idn_win32.c \
+ http_negotiate_sspi.c http_proxy.c non-ascii.c asyn-ares.c \
+ asyn-thread.c curl_gssapi.c curl_ntlm.c curl_ntlm_wb.c \
+ curl_ntlm_core.c curl_ntlm_msgs.c curl_sasl.c curl_multibyte.c \
+ hostcheck.c conncache.c pipeline.c dotdot.c x509asn1.c \
+ http2.c curl_sasl_sspi.c smb.c curl_sasl_gssapi.c curl_endian.c \
+ curl_des.c
+
+LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
+ formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h \
+ speedcheck.h urldata.h curl_ldap.h escape.h telnet.h getinfo.h \
+ strequal.h curl_sec.h memdebug.h http_chunks.h curl_fnmatch.h \
+ wildcard.h fileinfo.h ftplistparser.h strtok.h connect.h llist.h \
+ hash.h content_encoding.h share.h curl_md4.h curl_md5.h http_digest.h \
+ http_negotiate.h inet_pton.h amigaos.h strtoofft.h strerror.h \
+ inet_ntop.h curlx.h curl_memory.h curl_setup.h transfer.h select.h \
+ easyif.h multiif.h parsedate.h tftp.h sockaddr.h splay.h strdup.h \
+ socks.h ssh.h curl_base64.h rawstr.h curl_addrinfo.h curl_sspi.h \
+ slist.h nonblock.h curl_memrchr.h imap.h pop3.h smtp.h pingpong.h \
+ rtsp.h curl_threads.h warnless.h curl_hmac.h curl_rtmp.h \
+ curl_gethostname.h gopher.h http_proxy.h non-ascii.h asyn.h \
+ curl_ntlm.h curl_gssapi.h curl_ntlm_wb.h curl_ntlm_core.h \
+ curl_ntlm_msgs.h curl_sasl.h curl_multibyte.h hostcheck.h \
+ conncache.h curl_setup_once.h multihandle.h setup-vms.h pipeline.h \
+ dotdot.h x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h \
+ curl_printf.h
+
+LIB_RCFILES = libcurl.rc
+
+CSOURCES = $(LIB_CFILES) $(LIB_VTLS_CFILES)
+HHEADERS = $(LIB_HFILES) $(LIB_VTLS_HFILES)
diff --git a/Utilities/cmcurl/lib/amigaos.c b/Utilities/cmcurl/lib/amigaos.c
new file mode 100644
index 000000000..e3ff85f98
--- /dev/null
+++ b/Utilities/cmcurl/lib/amigaos.c
@@ -0,0 +1,77 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(__AMIGA__) && !defined(__ixemul__)
+
+#include <amitcp/socketbasetags.h>
+
+#include "amigaos.h"
+
+struct Library *SocketBase = NULL;
+extern int errno, h_errno;
+
+#ifdef __libnix__
+#include <stabs.h>
+void __request(const char *msg);
+#else
+# define __request( msg ) Printf( msg "\n\a")
+#endif
+
+void Curl_amiga_cleanup()
+{
+ if(SocketBase) {
+ CloseLibrary(SocketBase);
+ SocketBase = NULL;
+ }
+}
+
+bool Curl_amiga_init()
+{
+ if(!SocketBase)
+ SocketBase = OpenLibrary("bsdsocket.library", 4);
+
+ if(!SocketBase) {
+ __request("No TCP/IP Stack running!");
+ return FALSE;
+ }
+
+ if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG) &errno,
+ SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "cURL",
+ TAG_DONE)) {
+ __request("SocketBaseTags ERROR");
+ return FALSE;
+ }
+
+#ifndef __libnix__
+ atexit(Curl_amiga_cleanup);
+#endif
+
+ return TRUE;
+}
+
+#ifdef __libnix__
+ADD2EXIT(Curl_amiga_cleanup, -50);
+#endif
+
+#endif /* __AMIGA__ && ! __ixemul__ */
diff --git a/Utilities/cmcurl/lib/amigaos.h b/Utilities/cmcurl/lib/amigaos.h
new file mode 100644
index 000000000..76578be86
--- /dev/null
+++ b/Utilities/cmcurl/lib/amigaos.h
@@ -0,0 +1,39 @@
+#ifndef HEADER_CURL_AMIGAOS_H
+#define HEADER_CURL_AMIGAOS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#if defined(__AMIGA__) && !defined(__ixemul__)
+
+bool Curl_amiga_init();
+void Curl_amiga_cleanup();
+
+#else
+
+#define Curl_amiga_init() 1
+#define Curl_amiga_cleanup() Curl_nop_stmt
+
+#endif
+
+#endif /* HEADER_CURL_AMIGAOS_H */
+
diff --git a/Utilities/cmcurl/lib/arpa_telnet.h b/Utilities/cmcurl/lib/arpa_telnet.h
new file mode 100644
index 000000000..098d9a92f
--- /dev/null
+++ b/Utilities/cmcurl/lib/arpa_telnet.h
@@ -0,0 +1,104 @@
+#ifndef HEADER_CURL_ARPA_TELNET_H
+#define HEADER_CURL_ARPA_TELNET_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#ifndef CURL_DISABLE_TELNET
+/*
+ * Telnet option defines. Add more here if in need.
+ */
+#define CURL_TELOPT_BINARY 0 /* binary 8bit data */
+#define CURL_TELOPT_ECHO 1 /* just echo! */
+#define CURL_TELOPT_SGA 3 /* Suppress Go Ahead */
+#define CURL_TELOPT_EXOPL 255 /* EXtended OPtions List */
+#define CURL_TELOPT_TTYPE 24 /* Terminal TYPE */
+#define CURL_TELOPT_NAWS 31 /* Negotiate About Window Size */
+#define CURL_TELOPT_XDISPLOC 35 /* X DISPlay LOCation */
+
+#define CURL_TELOPT_NEW_ENVIRON 39 /* NEW ENVIRONment variables */
+#define CURL_NEW_ENV_VAR 0
+#define CURL_NEW_ENV_VALUE 1
+
+/*
+ * The telnet options represented as strings
+ */
+static const char * const telnetoptions[]=
+{
+ "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD",
+ "NAME", "STATUS", "TIMING MARK", "RCTE",
+ "NAOL", "NAOP", "NAOCRD", "NAOHTS",
+ "NAOHTD", "NAOFFD", "NAOVTS", "NAOVTD",
+ "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",
+ "DE TERMINAL", "SUPDUP", "SUPDUP OUTPUT", "SEND LOCATION",
+ "TERM TYPE", "END OF RECORD", "TACACS UID", "OUTPUT MARKING",
+ "TTYLOC", "3270 REGIME", "X3 PAD", "NAWS",
+ "TERM SPEED", "LFLOW", "LINEMODE", "XDISPLOC",
+ "OLD-ENVIRON", "AUTHENTICATION", "ENCRYPT", "NEW-ENVIRON"
+};
+
+#define CURL_TELOPT_MAXIMUM CURL_TELOPT_NEW_ENVIRON
+
+#define CURL_TELOPT_OK(x) ((x) <= CURL_TELOPT_MAXIMUM)
+#define CURL_TELOPT(x) telnetoptions[x]
+
+#define CURL_NTELOPTS 40
+
+/*
+ * First some defines
+ */
+#define CURL_xEOF 236 /* End Of File */
+#define CURL_SE 240 /* Sub negotiation End */
+#define CURL_NOP 241 /* No OPeration */
+#define CURL_DM 242 /* Data Mark */
+#define CURL_GA 249 /* Go Ahead, reverse the line */
+#define CURL_SB 250 /* SuBnegotiation */
+#define CURL_WILL 251 /* Our side WILL use this option */
+#define CURL_WONT 252 /* Our side WON'T use this option */
+#define CURL_DO 253 /* DO use this option! */
+#define CURL_DONT 254 /* DON'T use this option! */
+#define CURL_IAC 255 /* Interpret As Command */
+
+/*
+ * Then those numbers represented as strings:
+ */
+static const char * const telnetcmds[]=
+{
+ "EOF", "SUSP", "ABORT", "EOR", "SE",
+ "NOP", "DMARK", "BRK", "IP", "AO",
+ "AYT", "EC", "EL", "GA", "SB",
+ "WILL", "WONT", "DO", "DONT", "IAC"
+};
+
+#define CURL_TELCMD_MINIMUM CURL_xEOF /* the first one */
+#define CURL_TELCMD_MAXIMUM CURL_IAC /* surprise, 255 is the last one! ;-) */
+
+#define CURL_TELQUAL_IS 0
+#define CURL_TELQUAL_SEND 1
+#define CURL_TELQUAL_INFO 2
+#define CURL_TELQUAL_NAME 3
+
+#define CURL_TELCMD_OK(x) ( ((unsigned int)(x) >= CURL_TELCMD_MINIMUM) && \
+ ((unsigned int)(x) <= CURL_TELCMD_MAXIMUM) )
+#define CURL_TELCMD(x) telnetcmds[(x)-CURL_TELCMD_MINIMUM]
+
+#endif /* CURL_DISABLE_TELNET */
+
+#endif /* HEADER_CURL_ARPA_TELNET_H */
diff --git a/Utilities/cmcurl/lib/asyn-ares.c b/Utilities/cmcurl/lib/asyn-ares.c
new file mode 100644
index 000000000..98ecdfd71
--- /dev/null
+++ b/Utilities/cmcurl/lib/asyn-ares.c
@@ -0,0 +1,691 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+/***********************************************************************
+ * Only for ares-enabled builds
+ * And only for functions that fulfill the asynch resolver backend API
+ * as defined in asyn.h, nothing else belongs in this file!
+ **********************************************************************/
+
+#ifdef CURLRES_ARES
+
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "hash.h"
+#include "share.h"
+#include "strerror.h"
+#include "url.h"
+#include "multiif.h"
+#include "inet_pton.h"
+#include "connect.h"
+#include "select.h"
+#include "progress.h"
+#include "curl_printf.h"
+
+# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
+ (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__))
+# define CARES_STATICLIB
+# endif
+# include <ares.h>
+# include <ares_version.h> /* really old c-ares didn't include this by
+ itself */
+
+#if ARES_VERSION >= 0x010500
+/* c-ares 1.5.0 or later, the callback proto is modified */
+#define HAVE_CARES_CALLBACK_TIMEOUTS 1
+#endif
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+struct ResolverResults {
+ int num_pending; /* number of ares_gethostbyname() requests */
+ Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares parts */
+ int last_status;
+};
+
+/*
+ * Curl_resolver_global_init() - the generic low-level asynchronous name
+ * resolve API. Called from curl_global_init() to initialize global resolver
+ * environment. Initializes ares library.
+ */
+int Curl_resolver_global_init(void)
+{
+#ifdef CARES_HAVE_ARES_LIBRARY_INIT
+ if(ares_library_init(ARES_LIB_INIT_ALL)) {
+ return CURLE_FAILED_INIT;
+ }
+#endif
+ return CURLE_OK;
+}
+
+/*
+ * Curl_resolver_global_cleanup()
+ *
+ * Called from curl_global_cleanup() to destroy global resolver environment.
+ * Deinitializes ares library.
+ */
+void Curl_resolver_global_cleanup(void)
+{
+#ifdef CARES_HAVE_ARES_LIBRARY_CLEANUP
+ ares_library_cleanup();
+#endif
+}
+
+/*
+ * Curl_resolver_init()
+ *
+ * Called from curl_easy_init() -> Curl_open() to initialize resolver
+ * URL-state specific environment ('resolver' member of the UrlState
+ * structure). Fills the passed pointer by the initialized ares_channel.
+ */
+CURLcode Curl_resolver_init(void **resolver)
+{
+ int status = ares_init((ares_channel*)resolver);
+ if(status != ARES_SUCCESS) {
+ if(status == ARES_ENOMEM)
+ return CURLE_OUT_OF_MEMORY;
+ else
+ return CURLE_FAILED_INIT;
+ }
+ return CURLE_OK;
+ /* make sure that all other returns from this function should destroy the
+ ares channel before returning error! */
+}
+
+/*
+ * Curl_resolver_cleanup()
+ *
+ * Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver
+ * URL-state specific environment ('resolver' member of the UrlState
+ * structure). Destroys the ares channel.
+ */
+void Curl_resolver_cleanup(void *resolver)
+{
+ ares_destroy((ares_channel)resolver);
+}
+
+/*
+ * Curl_resolver_duphandle()
+ *
+ * Called from curl_easy_duphandle() to duplicate resolver URL-state specific
+ * environment ('resolver' member of the UrlState structure). Duplicates the
+ * 'from' ares channel and passes the resulting channel to the 'to' pointer.
+ */
+int Curl_resolver_duphandle(void **to, void *from)
+{
+ /* Clone the ares channel for the new handle */
+ if(ARES_SUCCESS != ares_dup((ares_channel*)to, (ares_channel)from))
+ return CURLE_FAILED_INIT;
+ return CURLE_OK;
+}
+
+static void destroy_async_data (struct Curl_async *async);
+
+/*
+ * Cancel all possibly still on-going resolves for this connection.
+ */
+void Curl_resolver_cancel(struct connectdata *conn)
+{
+ if(conn->data && conn->data->state.resolver)
+ ares_cancel((ares_channel)conn->data->state.resolver);
+ destroy_async_data(&conn->async);
+}
+
+/*
+ * destroy_async_data() cleans up async resolver data.
+ */
+static void destroy_async_data (struct Curl_async *async)
+{
+ free(async->hostname);
+
+ if(async->os_specific) {
+ struct ResolverResults *res = (struct ResolverResults *)async->os_specific;
+ if(res) {
+ if(res->temp_ai) {
+ Curl_freeaddrinfo(res->temp_ai);
+ res->temp_ai = NULL;
+ }
+ free(res);
+ }
+ async->os_specific = NULL;
+ }
+
+ async->hostname = NULL;
+}
+
+/*
+ * Curl_resolver_getsock() is called when someone from the outside world
+ * (using curl_multi_fdset()) wants to get our fd_set setup and we're talking
+ * with ares. The caller must make sure that this function is only called when
+ * we have a working ares channel.
+ *
+ * Returns: sockets-in-use-bitmap
+ */
+
+int Curl_resolver_getsock(struct connectdata *conn,
+ curl_socket_t *socks,
+ int numsocks)
+
+{
+ struct timeval maxtime;
+ struct timeval timebuf;
+ struct timeval *timeout;
+ long milli;
+ int max = ares_getsock((ares_channel)conn->data->state.resolver,
+ (ares_socket_t *)socks, numsocks);
+
+ maxtime.tv_sec = CURL_TIMEOUT_RESOLVE;
+ maxtime.tv_usec = 0;
+
+ timeout = ares_timeout((ares_channel)conn->data->state.resolver, &maxtime,
+ &timebuf);
+ milli = (timeout->tv_sec * 1000) + (timeout->tv_usec/1000);
+ if(milli == 0)
+ milli += 10;
+ Curl_expire_latest(conn->data, milli);
+
+ return max;
+}
+
+/*
+ * waitperform()
+ *
+ * 1) Ask ares what sockets it currently plays with, then
+ * 2) wait for the timeout period to check for action on ares' sockets.
+ * 3) tell ares to act on all the sockets marked as "with action"
+ *
+ * return number of sockets it worked on
+ */
+
+static int waitperform(struct connectdata *conn, int timeout_ms)
+{
+ struct SessionHandle *data = conn->data;
+ int nfds;
+ int bitmask;
+ ares_socket_t socks[ARES_GETSOCK_MAXNUM];
+ struct pollfd pfd[ARES_GETSOCK_MAXNUM];
+ int i;
+ int num = 0;
+
+ bitmask = ares_getsock((ares_channel)data->state.resolver, socks,
+ ARES_GETSOCK_MAXNUM);
+
+ for(i=0; i < ARES_GETSOCK_MAXNUM; i++) {
+ pfd[i].events = 0;
+ pfd[i].revents = 0;
+ if(ARES_GETSOCK_READABLE(bitmask, i)) {
+ pfd[i].fd = socks[i];
+ pfd[i].events |= POLLRDNORM|POLLIN;
+ }
+ if(ARES_GETSOCK_WRITABLE(bitmask, i)) {
+ pfd[i].fd = socks[i];
+ pfd[i].events |= POLLWRNORM|POLLOUT;
+ }
+ if(pfd[i].events != 0)
+ num++;
+ else
+ break;
+ }
+
+ if(num)
+ nfds = Curl_poll(pfd, num, timeout_ms);
+ else
+ nfds = 0;
+
+ if(!nfds)
+ /* Call ares_process() unconditonally here, even if we simply timed out
+ above, as otherwise the ares name resolve won't timeout! */
+ ares_process_fd((ares_channel)data->state.resolver, ARES_SOCKET_BAD,
+ ARES_SOCKET_BAD);
+ else {
+ /* move through the descriptors and ask for processing on them */
+ for(i=0; i < num; i++)
+ ares_process_fd((ares_channel)data->state.resolver,
+ pfd[i].revents & (POLLRDNORM|POLLIN)?
+ pfd[i].fd:ARES_SOCKET_BAD,
+ pfd[i].revents & (POLLWRNORM|POLLOUT)?
+ pfd[i].fd:ARES_SOCKET_BAD);
+ }
+ return nfds;
+}
+
+/*
+ * Curl_resolver_is_resolved() is called repeatedly to check if a previous
+ * name resolve request has completed. It should also make sure to time-out if
+ * the operation seems to take too long.
+ *
+ * Returns normal CURLcode errors.
+ */
+CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
+ struct Curl_dns_entry **dns)
+{
+ struct SessionHandle *data = conn->data;
+ struct ResolverResults *res = (struct ResolverResults *)
+ conn->async.os_specific;
+ CURLcode result = CURLE_OK;
+
+ *dns = NULL;
+
+ waitperform(conn, 0);
+
+ if(res && !res->num_pending) {
+ (void)Curl_addrinfo_callback(conn, res->last_status, res->temp_ai);
+ /* temp_ai ownership is moved to the connection, so we need not free-up
+ them */
+ res->temp_ai = NULL;
+ if(!conn->async.dns) {
+ failf(data, "Could not resolve: %s (%s)",
+ conn->async.hostname, ares_strerror(conn->async.status));
+ result = conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
+ CURLE_COULDNT_RESOLVE_HOST;
+ }
+ else
+ *dns = conn->async.dns;
+
+ destroy_async_data(&conn->async);
+ }
+
+ return result;
+}
+
+/*
+ * Curl_resolver_wait_resolv()
+ *
+ * waits for a resolve to finish. This function should be avoided since using
+ * this risk getting the multi interface to "hang".
+ *
+ * If 'entry' is non-NULL, make it point to the resolved dns entry
+ *
+ * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, and
+ * CURLE_OPERATION_TIMEDOUT if a time-out occurred.
+ */
+CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
+ struct Curl_dns_entry **entry)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ long timeout;
+ struct timeval now = Curl_tvnow();
+ struct Curl_dns_entry *temp_entry;
+
+ timeout = Curl_timeleft(data, &now, TRUE);
+ if(!timeout)
+ timeout = CURL_TIMEOUT_RESOLVE * 1000; /* default name resolve timeout */
+
+ /* Wait for the name resolve query to complete. */
+ for(;;) {
+ struct timeval *tvp, tv, store;
+ long timediff;
+ int itimeout;
+ int timeout_ms;
+
+ itimeout = (timeout > (long)INT_MAX) ? INT_MAX : (int)timeout;
+
+ store.tv_sec = itimeout/1000;
+ store.tv_usec = (itimeout%1000)*1000;
+
+ tvp = ares_timeout((ares_channel)data->state.resolver, &store, &tv);
+
+ /* use the timeout period ares returned to us above if less than one
+ second is left, otherwise just use 1000ms to make sure the progress
+ callback gets called frequent enough */
+ if(!tvp->tv_sec)
+ timeout_ms = (int)(tvp->tv_usec/1000);
+ else
+ timeout_ms = 1000;
+
+ waitperform(conn, timeout_ms);
+ Curl_resolver_is_resolved(conn, &temp_entry);
+
+ if(conn->async.done)
+ break;
+
+ if(Curl_pgrsUpdate(conn)) {
+ result = CURLE_ABORTED_BY_CALLBACK;
+ timeout = -1; /* trigger the cancel below */
+ }
+ else {
+ struct timeval now2 = Curl_tvnow();
+ timediff = Curl_tvdiff(now2, now); /* spent time */
+ timeout -= timediff?timediff:1; /* always deduct at least 1 */
+ now = now2; /* for next loop */
+ }
+
+ if(timeout < 0) {
+ /* our timeout, so we cancel the ares operation */
+ ares_cancel((ares_channel)data->state.resolver);
+ break;
+ }
+ }
+
+ /* Operation complete, if the lookup was successful we now have the entry
+ in the cache. */
+ if(entry)
+ *entry = conn->async.dns;
+
+ if(result)
+ /* close the connection, since we can't return failure here without
+ cleaning up this connection properly.
+ TODO: remove this action from here, it is not a name resolver decision.
+ */
+ connclose(conn, "c-ares resolve failed");
+
+ return result;
+}
+
+/* Connects results to the list */
+static void compound_results(struct ResolverResults *res,
+ Curl_addrinfo *ai)
+{
+ Curl_addrinfo *ai_tail;
+ if(!ai)
+ return;
+ ai_tail = ai;
+
+ while(ai_tail->ai_next)
+ ai_tail = ai_tail->ai_next;
+
+ /* Add the new results to the list of old results. */
+ ai_tail->ai_next = res->temp_ai;
+ res->temp_ai = ai;
+}
+
+/*
+ * ares_query_completed_cb() is the callback that ares will call when
+ * the host query initiated by ares_gethostbyname() from Curl_getaddrinfo(),
+ * when using ares, is completed either successfully or with failure.
+ */
+static void query_completed_cb(void *arg, /* (struct connectdata *) */
+ int status,
+#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
+ int timeouts,
+#endif
+ struct hostent *hostent)
+{
+ struct connectdata *conn = (struct connectdata *)arg;
+ struct ResolverResults *res;
+
+#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
+ (void)timeouts; /* ignored */
+#endif
+
+ if(ARES_EDESTRUCTION == status)
+ /* when this ares handle is getting destroyed, the 'arg' pointer may not
+ be valid so only defer it when we know the 'status' says its fine! */
+ return;
+
+ res = (struct ResolverResults *)conn->async.os_specific;
+ res->num_pending--;
+
+ if(CURL_ASYNC_SUCCESS == status) {
+ Curl_addrinfo *ai = Curl_he2ai(hostent, conn->async.port);
+ if(ai) {
+ compound_results(res, ai);
+ }
+ }
+ /* A successful result overwrites any previous error */
+ if(res->last_status != ARES_SUCCESS)
+ res->last_status = status;
+}
+
+/*
+ * Curl_resolver_getaddrinfo() - when using ares
+ *
+ * Returns name information about the given hostname and port number. If
+ * successful, the 'hostent' is returned and the forth argument will point to
+ * memory we need to free after use. That memory *MUST* be freed with
+ * Curl_freeaddrinfo(), nothing else.
+ */
+Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
+ const char *hostname,
+ int port,
+ int *waitp)
+{
+ char *bufp;
+ struct SessionHandle *data = conn->data;
+ struct in_addr in;
+ int family = PF_INET;
+#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
+ struct in6_addr in6;
+#endif /* CURLRES_IPV6 */
+
+ *waitp = 0; /* default to synchronous response */
+
+ /* First check if this is an IPv4 address string */
+ if(Curl_inet_pton(AF_INET, hostname, &in) > 0) {
+ /* This is a dotted IP address 123.123.123.123-style */
+ return Curl_ip2addr(AF_INET, &in, hostname, port);
+ }
+
+#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
+ /* Otherwise, check if this is an IPv6 address string */
+ if(Curl_inet_pton (AF_INET6, hostname, &in6) > 0)
+ /* This must be an IPv6 address literal. */
+ return Curl_ip2addr(AF_INET6, &in6, hostname, port);
+
+ switch(conn->ip_version) {
+ default:
+#if ARES_VERSION >= 0x010601
+ family = PF_UNSPEC; /* supported by c-ares since 1.6.1, so for older
+ c-ares versions this just falls through and defaults
+ to PF_INET */
+ break;
+#endif
+ case CURL_IPRESOLVE_V4:
+ family = PF_INET;
+ break;
+ case CURL_IPRESOLVE_V6:
+ family = PF_INET6;
+ break;
+ }
+#endif /* CURLRES_IPV6 */
+
+ bufp = strdup(hostname);
+ if(bufp) {
+ struct ResolverResults *res = NULL;
+ free(conn->async.hostname);
+ conn->async.hostname = bufp;
+ conn->async.port = port;
+ conn->async.done = FALSE; /* not done */
+ conn->async.status = 0; /* clear */
+ conn->async.dns = NULL; /* clear */
+ res = calloc(sizeof(struct ResolverResults), 1);
+ if(!res) {
+ free(conn->async.hostname);
+ conn->async.hostname = NULL;
+ return NULL;
+ }
+ conn->async.os_specific = res;
+
+ /* initial status - failed */
+ res->last_status = ARES_ENOTFOUND;
+#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
+ if(family == PF_UNSPEC) {
+ if(Curl_ipv6works()) {
+ res->num_pending = 2;
+
+ /* areschannel is already setup in the Curl_open() function */
+ ares_gethostbyname((ares_channel)data->state.resolver, hostname,
+ PF_INET, query_completed_cb, conn);
+ ares_gethostbyname((ares_channel)data->state.resolver, hostname,
+ PF_INET6, query_completed_cb, conn);
+ }
+ else {
+ res->num_pending = 1;
+
+ /* areschannel is already setup in the Curl_open() function */
+ ares_gethostbyname((ares_channel)data->state.resolver, hostname,
+ PF_INET, query_completed_cb, conn);
+ }
+ }
+ else
+#endif /* CURLRES_IPV6 */
+ {
+ res->num_pending = 1;
+
+ /* areschannel is already setup in the Curl_open() function */
+ ares_gethostbyname((ares_channel)data->state.resolver, hostname, family,
+ query_completed_cb, conn);
+ }
+
+ *waitp = 1; /* expect asynchronous response */
+ }
+ return NULL; /* no struct yet */
+}
+
+CURLcode Curl_set_dns_servers(struct SessionHandle *data,
+ char *servers)
+{
+ CURLcode result = CURLE_NOT_BUILT_IN;
+ int ares_result;
+
+ /* If server is NULL or empty, this would purge all DNS servers
+ * from ares library, which will cause any and all queries to fail.
+ * So, just return OK if none are configured and don't actually make
+ * any changes to c-ares. This lets c-ares use it's defaults, which
+ * it gets from the OS (for instance from /etc/resolv.conf on Linux).
+ */
+ if(!(servers && servers[0]))
+ return CURLE_OK;
+
+#if (ARES_VERSION >= 0x010704)
+ ares_result = ares_set_servers_csv(data->state.resolver, servers);
+ switch(ares_result) {
+ case ARES_SUCCESS:
+ result = CURLE_OK;
+ break;
+ case ARES_ENOMEM:
+ result = CURLE_OUT_OF_MEMORY;
+ break;
+ case ARES_ENOTINITIALIZED:
+ case ARES_ENODATA:
+ case ARES_EBADSTR:
+ default:
+ result = CURLE_BAD_FUNCTION_ARGUMENT;
+ break;
+ }
+#else /* too old c-ares version! */
+ (void)data;
+ (void)(ares_result);
+#endif
+ return result;
+}
+
+CURLcode Curl_set_dns_interface(struct SessionHandle *data,
+ const char *interf)
+{
+#if (ARES_VERSION >= 0x010704)
+ if(!interf)
+ interf = "";
+
+ ares_set_local_dev((ares_channel)data->state.resolver, interf);
+
+ return CURLE_OK;
+#else /* c-ares version too old! */
+ (void)data;
+ (void)interf;
+ return CURLE_NOT_BUILT_IN;
+#endif
+}
+
+CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
+ const char *local_ip4)
+{
+#if (ARES_VERSION >= 0x010704)
+ struct in_addr a4;
+
+ if((!local_ip4) || (local_ip4[0] == 0)) {
+ a4.s_addr = 0; /* disabled: do not bind to a specific address */
+ }
+ else {
+ if(Curl_inet_pton(AF_INET, local_ip4, &a4) != 1) {
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+ }
+
+ ares_set_local_ip4((ares_channel)data->state.resolver, ntohl(a4.s_addr));
+
+ return CURLE_OK;
+#else /* c-ares version too old! */
+ (void)data;
+ (void)local_ip4;
+ return CURLE_NOT_BUILT_IN;
+#endif
+}
+
+CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data,
+ const char *local_ip6)
+{
+#if (ARES_VERSION >= 0x010704) && defined(ENABLE_IPV6)
+ unsigned char a6[INET6_ADDRSTRLEN];
+
+ if((!local_ip6) || (local_ip6[0] == 0)) {
+ /* disabled: do not bind to a specific address */
+ memset(a6, 0, sizeof(a6));
+ }
+ else {
+ if(Curl_inet_pton(AF_INET6, local_ip6, a6) != 1) {
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+ }
+
+ ares_set_local_ip6((ares_channel)data->state.resolver, a6);
+
+ return CURLE_OK;
+#else /* c-ares version too old! */
+ (void)data;
+ (void)local_ip6;
+ return CURLE_NOT_BUILT_IN;
+#endif
+}
+#endif /* CURLRES_ARES */
diff --git a/Utilities/cmcurl/lib/asyn-thread.c b/Utilities/cmcurl/lib/asyn-thread.c
new file mode 100644
index 000000000..bd47d5ad5
--- /dev/null
+++ b/Utilities/cmcurl/lib/asyn-thread.c
@@ -0,0 +1,698 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#if defined(USE_THREADS_POSIX)
+# ifdef HAVE_PTHREAD_H
+# include <pthread.h>
+# endif
+#elif defined(USE_THREADS_WIN32)
+# ifdef HAVE_PROCESS_H
+# include <process.h>
+# endif
+#endif
+
+#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+#ifdef HAVE_GETADDRINFO
+# define RESOLVER_ENOMEM EAI_MEMORY
+#else
+# define RESOLVER_ENOMEM ENOMEM
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "hash.h"
+#include "share.h"
+#include "strerror.h"
+#include "url.h"
+#include "multiif.h"
+#include "inet_pton.h"
+#include "inet_ntop.h"
+#include "curl_threads.h"
+#include "connect.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/***********************************************************************
+ * Only for threaded name resolves builds
+ **********************************************************************/
+#ifdef CURLRES_THREADED
+
+/*
+ * Curl_resolver_global_init()
+ * Called from curl_global_init() to initialize global resolver environment.
+ * Does nothing here.
+ */
+int Curl_resolver_global_init(void)
+{
+ return CURLE_OK;
+}
+
+/*
+ * Curl_resolver_global_cleanup()
+ * Called from curl_global_cleanup() to destroy global resolver environment.
+ * Does nothing here.
+ */
+void Curl_resolver_global_cleanup(void)
+{
+}
+
+/*
+ * Curl_resolver_init()
+ * Called from curl_easy_init() -> Curl_open() to initialize resolver
+ * URL-state specific environment ('resolver' member of the UrlState
+ * structure). Does nothing here.
+ */
+CURLcode Curl_resolver_init(void **resolver)
+{
+ (void)resolver;
+ return CURLE_OK;
+}
+
+/*
+ * Curl_resolver_cleanup()
+ * Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver
+ * URL-state specific environment ('resolver' member of the UrlState
+ * structure). Does nothing here.
+ */
+void Curl_resolver_cleanup(void *resolver)
+{
+ (void)resolver;
+}
+
+/*
+ * Curl_resolver_duphandle()
+ * Called from curl_easy_duphandle() to duplicate resolver URL state-specific
+ * environment ('resolver' member of the UrlState structure). Does nothing
+ * here.
+ */
+int Curl_resolver_duphandle(void **to, void *from)
+{
+ (void)to;
+ (void)from;
+ return CURLE_OK;
+}
+
+static void destroy_async_data(struct Curl_async *);
+
+/*
+ * Cancel all possibly still on-going resolves for this connection.
+ */
+void Curl_resolver_cancel(struct connectdata *conn)
+{
+ destroy_async_data(&conn->async);
+}
+
+/* This function is used to init a threaded resolve */
+static bool init_resolve_thread(struct connectdata *conn,
+ const char *hostname, int port,
+ const struct addrinfo *hints);
+
+
+/* Data for synchronization between resolver thread and its parent */
+struct thread_sync_data {
+ curl_mutex_t * mtx;
+ int done;
+
+ char * hostname; /* hostname to resolve, Curl_async.hostname
+ duplicate */
+ int port;
+ int sock_error;
+ Curl_addrinfo *res;
+#ifdef HAVE_GETADDRINFO
+ struct addrinfo hints;
+#endif
+ struct thread_data *td; /* for thread-self cleanup */
+};
+
+struct thread_data {
+ curl_thread_t thread_hnd;
+ unsigned int poll_interval;
+ long interval_end;
+ struct thread_sync_data tsd;
+};
+
+static struct thread_sync_data *conn_thread_sync_data(struct connectdata *conn)
+{
+ return &(((struct thread_data *)conn->async.os_specific)->tsd);
+}
+
+#define CONN_THREAD_SYNC_DATA(conn) &(((conn)->async.os_specific)->tsd);
+
+/* Destroy resolver thread synchronization data */
+static
+void destroy_thread_sync_data(struct thread_sync_data * tsd)
+{
+ if(tsd->mtx) {
+ Curl_mutex_destroy(tsd->mtx);
+ free(tsd->mtx);
+ }
+
+ free(tsd->hostname);
+
+ if(tsd->res)
+ Curl_freeaddrinfo(tsd->res);
+
+ memset(tsd, 0, sizeof(*tsd));
+}
+
+/* Initialize resolver thread synchronization data */
+static
+int init_thread_sync_data(struct thread_data * td,
+ const char * hostname,
+ int port,
+ const struct addrinfo *hints)
+{
+ struct thread_sync_data *tsd = &td->tsd;
+
+ memset(tsd, 0, sizeof(*tsd));
+
+ tsd->td = td;
+ tsd->port = port;
+#ifdef HAVE_GETADDRINFO
+ DEBUGASSERT(hints);
+ tsd->hints = *hints;
+#else
+ (void) hints;
+#endif
+
+ tsd->mtx = malloc(sizeof(curl_mutex_t));
+ if(tsd->mtx == NULL)
+ goto err_exit;
+
+ Curl_mutex_init(tsd->mtx);
+
+ tsd->sock_error = CURL_ASYNC_SUCCESS;
+
+ /* Copying hostname string because original can be destroyed by parent
+ * thread during gethostbyname execution.
+ */
+ tsd->hostname = strdup(hostname);
+ if(!tsd->hostname)
+ goto err_exit;
+
+ return 1;
+
+ err_exit:
+ /* Memory allocation failed */
+ destroy_thread_sync_data(tsd);
+ return 0;
+}
+
+static int getaddrinfo_complete(struct connectdata *conn)
+{
+ struct thread_sync_data *tsd = conn_thread_sync_data(conn);
+ int rc;
+
+ rc = Curl_addrinfo_callback(conn, tsd->sock_error, tsd->res);
+ /* The tsd->res structure has been copied to async.dns and perhaps the DNS
+ cache. Set our copy to NULL so destroy_thread_sync_data doesn't free it.
+ */
+ tsd->res = NULL;
+
+ return rc;
+}
+
+
+#ifdef HAVE_GETADDRINFO
+
+/*
+ * getaddrinfo_thread() resolves a name and then exits.
+ *
+ * For builds without ARES, but with ENABLE_IPV6, create a resolver thread
+ * and wait on it.
+ */
+static unsigned int CURL_STDCALL getaddrinfo_thread (void *arg)
+{
+ struct thread_sync_data *tsd = (struct thread_sync_data*)arg;
+ struct thread_data *td = tsd->td;
+ char service[12];
+ int rc;
+
+ snprintf(service, sizeof(service), "%d", tsd->port);
+
+ rc = Curl_getaddrinfo_ex(tsd->hostname, service, &tsd->hints, &tsd->res);
+
+ if(rc != 0) {
+ tsd->sock_error = SOCKERRNO?SOCKERRNO:rc;
+ if(tsd->sock_error == 0)
+ tsd->sock_error = RESOLVER_ENOMEM;
+ }
+
+ Curl_mutex_acquire(tsd->mtx);
+ if(tsd->done) {
+ /* too late, gotta clean up the mess */
+ Curl_mutex_release(tsd->mtx);
+ destroy_thread_sync_data(tsd);
+ free(td);
+ }
+ else {
+ tsd->done = 1;
+ Curl_mutex_release(tsd->mtx);
+ }
+
+ return 0;
+}
+
+#else /* HAVE_GETADDRINFO */
+
+/*
+ * gethostbyname_thread() resolves a name and then exits.
+ */
+static unsigned int CURL_STDCALL gethostbyname_thread (void *arg)
+{
+ struct thread_sync_data *tsd = (struct thread_sync_data *)arg;
+ struct thread_data *td = tsd->td;
+
+ tsd->res = Curl_ipv4_resolve_r(tsd->hostname, tsd->port);
+
+ if(!tsd->res) {
+ tsd->sock_error = SOCKERRNO;
+ if(tsd->sock_error == 0)
+ tsd->sock_error = RESOLVER_ENOMEM;
+ }
+
+ Curl_mutex_acquire(tsd->mtx);
+ if(tsd->done) {
+ /* too late, gotta clean up the mess */
+ Curl_mutex_release(tsd->mtx);
+ destroy_thread_sync_data(tsd);
+ free(td);
+ }
+ else {
+ tsd->done = 1;
+ Curl_mutex_release(tsd->mtx);
+ }
+
+ return 0;
+}
+
+#endif /* HAVE_GETADDRINFO */
+
+/*
+ * destroy_async_data() cleans up async resolver data and thread handle.
+ */
+static void destroy_async_data (struct Curl_async *async)
+{
+ if(async->os_specific) {
+ struct thread_data *td = (struct thread_data*) async->os_specific;
+ int done;
+
+ /*
+ * if the thread is still blocking in the resolve syscall, detach it and
+ * let the thread do the cleanup...
+ */
+ Curl_mutex_acquire(td->tsd.mtx);
+ done = td->tsd.done;
+ td->tsd.done = 1;
+ Curl_mutex_release(td->tsd.mtx);
+
+ if(!done) {
+ Curl_thread_destroy(td->thread_hnd);
+ }
+ else {
+ if(td->thread_hnd != curl_thread_t_null)
+ Curl_thread_join(&td->thread_hnd);
+
+ destroy_thread_sync_data(&td->tsd);
+
+ free(async->os_specific);
+ }
+ }
+ async->os_specific = NULL;
+
+ free(async->hostname);
+ async->hostname = NULL;
+}
+
+/*
+ * init_resolve_thread() starts a new thread that performs the actual
+ * resolve. This function returns before the resolve is done.
+ *
+ * Returns FALSE in case of failure, otherwise TRUE.
+ */
+static bool init_resolve_thread (struct connectdata *conn,
+ const char *hostname, int port,
+ const struct addrinfo *hints)
+{
+ struct thread_data *td = calloc(1, sizeof(struct thread_data));
+ int err = RESOLVER_ENOMEM;
+
+ conn->async.os_specific = (void*) td;
+ if(!td)
+ goto err_exit;
+
+ conn->async.port = port;
+ conn->async.done = FALSE;
+ conn->async.status = 0;
+ conn->async.dns = NULL;
+ td->thread_hnd = curl_thread_t_null;
+
+ if(!init_thread_sync_data(td, hostname, port, hints))
+ goto err_exit;
+
+ free(conn->async.hostname);
+ conn->async.hostname = strdup(hostname);
+ if(!conn->async.hostname)
+ goto err_exit;
+
+#ifdef HAVE_GETADDRINFO
+ td->thread_hnd = Curl_thread_create(getaddrinfo_thread, &td->tsd);
+#else
+ td->thread_hnd = Curl_thread_create(gethostbyname_thread, &td->tsd);
+#endif
+
+ if(!td->thread_hnd) {
+#ifndef _WIN32_WCE
+ err = errno;
+#endif
+ goto err_exit;
+ }
+
+ return TRUE;
+
+ err_exit:
+ destroy_async_data(&conn->async);
+
+ SET_ERRNO(err);
+
+ return FALSE;
+}
+
+/*
+ * resolver_error() calls failf() with the appropriate message after a resolve
+ * error
+ */
+
+static CURLcode resolver_error(struct connectdata *conn)
+{
+ const char *host_or_proxy;
+ CURLcode result;
+
+ if(conn->bits.httpproxy) {
+ host_or_proxy = "proxy";
+ result = CURLE_COULDNT_RESOLVE_PROXY;
+ }
+ else {
+ host_or_proxy = "host";
+ result = CURLE_COULDNT_RESOLVE_HOST;
+ }
+
+ failf(conn->data, "Could not resolve %s: %s", host_or_proxy,
+ conn->async.hostname);
+
+ return result;
+}
+
+/*
+ * Curl_resolver_wait_resolv()
+ *
+ * waits for a resolve to finish. This function should be avoided since using
+ * this risk getting the multi interface to "hang".
+ *
+ * If 'entry' is non-NULL, make it point to the resolved dns entry
+ *
+ * This is the version for resolves-in-a-thread.
+ */
+CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
+ struct Curl_dns_entry **entry)
+{
+ struct thread_data *td = (struct thread_data*) conn->async.os_specific;
+ CURLcode result = CURLE_OK;
+
+ DEBUGASSERT(conn && td);
+
+ /* wait for the thread to resolve the name */
+ if(Curl_thread_join(&td->thread_hnd))
+ result = getaddrinfo_complete(conn);
+ else
+ DEBUGASSERT(0);
+
+ conn->async.done = TRUE;
+
+ if(entry)
+ *entry = conn->async.dns;
+
+ if(!conn->async.dns)
+ /* a name was not resolved, report error */
+ result = resolver_error(conn);
+
+ destroy_async_data(&conn->async);
+
+ if(!conn->async.dns)
+ connclose(conn, "asynch resolve failed");
+
+ return result;
+}
+
+/*
+ * Curl_resolver_is_resolved() is called repeatedly to check if a previous
+ * name resolve request has completed. It should also make sure to time-out if
+ * the operation seems to take too long.
+ */
+CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
+ struct Curl_dns_entry **entry)
+{
+ struct SessionHandle *data = conn->data;
+ struct thread_data *td = (struct thread_data*) conn->async.os_specific;
+ int done = 0;
+
+ *entry = NULL;
+
+ if(!td) {
+ DEBUGASSERT(td);
+ return CURLE_COULDNT_RESOLVE_HOST;
+ }
+
+ Curl_mutex_acquire(td->tsd.mtx);
+ done = td->tsd.done;
+ Curl_mutex_release(td->tsd.mtx);
+
+ if(done) {
+ getaddrinfo_complete(conn);
+
+ if(!conn->async.dns) {
+ CURLcode result = resolver_error(conn);
+ destroy_async_data(&conn->async);
+ return result;
+ }
+ destroy_async_data(&conn->async);
+ *entry = conn->async.dns;
+ }
+ else {
+ /* poll for name lookup done with exponential backoff up to 250ms */
+ long elapsed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
+ if(elapsed < 0)
+ elapsed = 0;
+
+ if(td->poll_interval == 0)
+ /* Start at 1ms poll interval */
+ td->poll_interval = 1;
+ else if(elapsed >= td->interval_end)
+ /* Back-off exponentially if last interval expired */
+ td->poll_interval *= 2;
+
+ if(td->poll_interval > 250)
+ td->poll_interval = 250;
+
+ td->interval_end = elapsed + td->poll_interval;
+ Curl_expire(conn->data, td->poll_interval);
+ }
+
+ return CURLE_OK;
+}
+
+int Curl_resolver_getsock(struct connectdata *conn,
+ curl_socket_t *socks,
+ int numsocks)
+{
+ (void)conn;
+ (void)socks;
+ (void)numsocks;
+ return 0;
+}
+
+#ifndef HAVE_GETADDRINFO
+/*
+ * Curl_getaddrinfo() - for platforms without getaddrinfo
+ */
+Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
+ const char *hostname,
+ int port,
+ int *waitp)
+{
+ struct in_addr in;
+
+ *waitp = 0; /* default to synchronous response */
+
+ if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
+ /* This is a dotted IP address 123.123.123.123-style */
+ return Curl_ip2addr(AF_INET, &in, hostname, port);
+
+ /* fire up a new resolver thread! */
+ if(init_resolve_thread(conn, hostname, port, NULL)) {
+ *waitp = 1; /* expect asynchronous response */
+ return NULL;
+ }
+
+ /* fall-back to blocking version */
+ return Curl_ipv4_resolve_r(hostname, port);
+}
+
+#else /* !HAVE_GETADDRINFO */
+
+/*
+ * Curl_resolver_getaddrinfo() - for getaddrinfo
+ */
+Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
+ const char *hostname,
+ int port,
+ int *waitp)
+{
+ struct addrinfo hints;
+ struct in_addr in;
+ Curl_addrinfo *res;
+ int error;
+ char sbuf[12];
+ int pf = PF_INET;
+#ifdef CURLRES_IPV6
+ struct in6_addr in6;
+#endif /* CURLRES_IPV6 */
+
+ *waitp = 0; /* default to synchronous response */
+
+ /* First check if this is an IPv4 address string */
+ if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
+ /* This is a dotted IP address 123.123.123.123-style */
+ return Curl_ip2addr(AF_INET, &in, hostname, port);
+
+#ifdef CURLRES_IPV6
+ /* check if this is an IPv6 address string */
+ if(Curl_inet_pton (AF_INET6, hostname, &in6) > 0)
+ /* This is an IPv6 address literal */
+ return Curl_ip2addr(AF_INET6, &in6, hostname, port);
+
+ /*
+ * Check if a limited name resolve has been requested.
+ */
+ switch(conn->ip_version) {
+ case CURL_IPRESOLVE_V4:
+ pf = PF_INET;
+ break;
+ case CURL_IPRESOLVE_V6:
+ pf = PF_INET6;
+ break;
+ default:
+ pf = PF_UNSPEC;
+ break;
+ }
+
+ if((pf != PF_INET) && !Curl_ipv6works())
+ /* The stack seems to be a non-IPv6 one */
+ pf = PF_INET;
+
+#endif /* CURLRES_IPV6 */
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = pf;
+ hints.ai_socktype = conn->socktype;
+
+ snprintf(sbuf, sizeof(sbuf), "%d", port);
+
+ /* fire up a new resolver thread! */
+ if(init_resolve_thread(conn, hostname, port, &hints)) {
+ *waitp = 1; /* expect asynchronous response */
+ return NULL;
+ }
+
+ /* fall-back to blocking version */
+ infof(conn->data, "init_resolve_thread() failed for %s; %s\n",
+ hostname, Curl_strerror(conn, ERRNO));
+
+ error = Curl_getaddrinfo_ex(hostname, sbuf, &hints, &res);
+ if(error) {
+ infof(conn->data, "getaddrinfo() failed for %s:%d; %s\n",
+ hostname, port, Curl_strerror(conn, SOCKERRNO));
+ return NULL;
+ }
+ return res;
+}
+
+#endif /* !HAVE_GETADDRINFO */
+
+CURLcode Curl_set_dns_servers(struct SessionHandle *data,
+ char *servers)
+{
+ (void)data;
+ (void)servers;
+ return CURLE_NOT_BUILT_IN;
+
+}
+
+CURLcode Curl_set_dns_interface(struct SessionHandle *data,
+ const char *interf)
+{
+ (void)data;
+ (void)interf;
+ return CURLE_NOT_BUILT_IN;
+}
+
+CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
+ const char *local_ip4)
+{
+ (void)data;
+ (void)local_ip4;
+ return CURLE_NOT_BUILT_IN;
+}
+
+CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data,
+ const char *local_ip6)
+{
+ (void)data;
+ (void)local_ip6;
+ return CURLE_NOT_BUILT_IN;
+}
+
+#endif /* CURLRES_THREADED */
diff --git a/Utilities/cmcurl/lib/asyn.h b/Utilities/cmcurl/lib/asyn.h
new file mode 100644
index 000000000..1b681ea12
--- /dev/null
+++ b/Utilities/cmcurl/lib/asyn.h
@@ -0,0 +1,168 @@
+#ifndef HEADER_CURL_ASYN_H
+#define HEADER_CURL_ASYN_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include "curl_addrinfo.h"
+
+struct addrinfo;
+struct hostent;
+struct SessionHandle;
+struct connectdata;
+struct Curl_dns_entry;
+
+/*
+ * This header defines all functions in the internal asynch resolver interface.
+ * All asynch resolvers need to provide these functions.
+ * asyn-ares.c and asyn-thread.c are the current implementations of asynch
+ * resolver backends.
+ */
+
+/*
+ * Curl_resolver_global_init()
+ *
+ * Called from curl_global_init() to initialize global resolver environment.
+ * Returning anything else than CURLE_OK fails curl_global_init().
+ */
+int Curl_resolver_global_init(void);
+
+/*
+ * Curl_resolver_global_cleanup()
+ * Called from curl_global_cleanup() to destroy global resolver environment.
+ */
+void Curl_resolver_global_cleanup(void);
+
+/*
+ * Curl_resolver_init()
+ * Called from curl_easy_init() -> Curl_open() to initialize resolver
+ * URL-state specific environment ('resolver' member of the UrlState
+ * structure). Should fill the passed pointer by the initialized handler.
+ * Returning anything else than CURLE_OK fails curl_easy_init() with the
+ * correspondent code.
+ */
+CURLcode Curl_resolver_init(void **resolver);
+
+/*
+ * Curl_resolver_cleanup()
+ * Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver
+ * URL-state specific environment ('resolver' member of the UrlState
+ * structure). Should destroy the handler and free all resources connected to
+ * it.
+ */
+void Curl_resolver_cleanup(void *resolver);
+
+/*
+ * Curl_resolver_duphandle()
+ * Called from curl_easy_duphandle() to duplicate resolver URL-state specific
+ * environment ('resolver' member of the UrlState structure). Should
+ * duplicate the 'from' handle and pass the resulting handle to the 'to'
+ * pointer. Returning anything else than CURLE_OK causes failed
+ * curl_easy_duphandle() call.
+ */
+int Curl_resolver_duphandle(void **to, void *from);
+
+/*
+ * Curl_resolver_cancel().
+ *
+ * It is called from inside other functions to cancel currently performing
+ * resolver request. Should also free any temporary resources allocated to
+ * perform a request.
+ */
+void Curl_resolver_cancel(struct connectdata *conn);
+
+/* Curl_resolver_getsock()
+ *
+ * This function is called from the multi_getsock() function. 'sock' is a
+ * pointer to an array to hold the file descriptors, with 'numsock' being the
+ * size of that array (in number of entries). This function is supposed to
+ * return bitmask indicating what file descriptors (referring to array indexes
+ * in the 'sock' array) to wait for, read/write.
+ */
+int Curl_resolver_getsock(struct connectdata *conn, curl_socket_t *sock,
+ int numsocks);
+
+/*
+ * Curl_resolver_is_resolved()
+ *
+ * Called repeatedly to check if a previous name resolve request has
+ * completed. It should also make sure to time-out if the operation seems to
+ * take too long.
+ *
+ * Returns normal CURLcode errors.
+ */
+CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
+ struct Curl_dns_entry **dns);
+
+/*
+ * Curl_resolver_wait_resolv()
+ *
+ * waits for a resolve to finish. This function should be avoided since using
+ * this risk getting the multi interface to "hang".
+ *
+ * If 'entry' is non-NULL, make it point to the resolved dns entry
+ *
+ * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, and
+ * CURLE_OPERATION_TIMEDOUT if a time-out occurred.
+
+ */
+CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
+ struct Curl_dns_entry **dnsentry);
+
+/*
+ * Curl_resolver_getaddrinfo() - when using this resolver
+ *
+ * Returns name information about the given hostname and port number. If
+ * successful, the 'hostent' is returned and the forth argument will point to
+ * memory we need to free after use. That memory *MUST* be freed with
+ * Curl_freeaddrinfo(), nothing else.
+ *
+ * Each resolver backend must of course make sure to return data in the
+ * correct format to comply with this.
+ */
+Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
+ const char *hostname,
+ int port,
+ int *waitp);
+
+#ifndef CURLRES_ASYNCH
+/* convert these functions if an asynch resolver isn't used */
+#define Curl_resolver_cancel(x) Curl_nop_stmt
+#define Curl_resolver_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST
+#define Curl_resolver_wait_resolv(x,y) CURLE_COULDNT_RESOLVE_HOST
+#define Curl_resolver_getsock(x,y,z) 0
+#define Curl_resolver_duphandle(x,y) CURLE_OK
+#define Curl_resolver_init(x) CURLE_OK
+#define Curl_resolver_global_init() CURLE_OK
+#define Curl_resolver_global_cleanup() Curl_nop_stmt
+#define Curl_resolver_cleanup(x) Curl_nop_stmt
+#endif
+
+#ifdef CURLRES_ASYNCH
+#define Curl_resolver_asynch() 1
+#else
+#define Curl_resolver_asynch() 0
+#endif
+
+
+/********** end of generic resolver interface functions *****************/
+#endif /* HEADER_CURL_ASYN_H */
diff --git a/Utilities/cmcurl/lib/base64.c b/Utilities/cmcurl/lib/base64.c
new file mode 100644
index 000000000..6b87eed40
--- /dev/null
+++ b/Utilities/cmcurl/lib/base64.c
@@ -0,0 +1,309 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* Base64 encoding/decoding */
+
+#include "curl_setup.h"
+#include "curl_printf.h"
+#include "urldata.h" /* for the SessionHandle definition */
+#include "warnless.h"
+#include "curl_base64.h"
+#include "non-ascii.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* ---- Base64 Encoding/Decoding Table --- */
+static const char base64[]=
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/* The Base 64 encoding with an URL and filename safe alphabet, RFC 4648
+ section 5 */
+static const char base64url[]=
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
+
+static size_t decodeQuantum(unsigned char *dest, const char *src)
+{
+ size_t padding = 0;
+ const char *s, *p;
+ unsigned long i, x = 0;
+
+ for(i = 0, s = src; i < 4; i++, s++) {
+ unsigned long v = 0;
+
+ if(*s == '=') {
+ x = (x << 6);
+ padding++;
+ }
+ else {
+ p = base64;
+
+ while(*p && (*p != *s)) {
+ v++;
+ p++;
+ }
+
+ if(*p == *s)
+ x = (x << 6) + v;
+ else
+ return 0;
+ }
+ }
+
+ if(padding < 1)
+ dest[2] = curlx_ultouc(x & 0xFFUL);
+
+ x >>= 8;
+ if(padding < 2)
+ dest[1] = curlx_ultouc(x & 0xFFUL);
+
+ x >>= 8;
+ dest[0] = curlx_ultouc(x & 0xFFUL);
+
+ return 3 - padding;
+}
+
+/*
+ * Curl_base64_decode()
+ *
+ * Given a base64 NUL-terminated string at src, decode it and return a
+ * pointer in *outptr to a newly allocated memory area holding decoded
+ * data. Size of decoded data is returned in variable pointed by outlen.
+ *
+ * Returns CURLE_OK on success, otherwise specific error code. Function
+ * output shall not be considered valid unless CURLE_OK is returned.
+ *
+ * When decoded data length is 0, returns NULL in *outptr.
+ *
+ * @unittest: 1302
+ */
+CURLcode Curl_base64_decode(const char *src,
+ unsigned char **outptr, size_t *outlen)
+{
+ size_t srclen = 0;
+ size_t length = 0;
+ size_t padding = 0;
+ size_t i;
+ size_t numQuantums;
+ size_t rawlen = 0;
+ unsigned char *pos;
+ unsigned char *newstr;
+
+ *outptr = NULL;
+ *outlen = 0;
+ srclen = strlen(src);
+
+ /* Check the length of the input string is valid */
+ if(!srclen || srclen % 4)
+ return CURLE_BAD_CONTENT_ENCODING;
+
+ /* Find the position of any = padding characters */
+ while((src[length] != '=') && src[length])
+ length++;
+
+ /* A maximum of two = padding characters is allowed */
+ if(src[length] == '=') {
+ padding++;
+ if(src[length + 1] == '=')
+ padding++;
+ }
+
+ /* Check the = padding characters weren't part way through the input */
+ if(length + padding != srclen)
+ return CURLE_BAD_CONTENT_ENCODING;
+
+ /* Calculate the number of quantums */
+ numQuantums = srclen / 4;
+
+ /* Calculate the size of the decoded string */
+ rawlen = (numQuantums * 3) - padding;
+
+ /* Allocate our buffer including room for a zero terminator */
+ newstr = malloc(rawlen + 1);
+ if(!newstr)
+ return CURLE_OUT_OF_MEMORY;
+
+ pos = newstr;
+
+ /* Decode the quantums */
+ for(i = 0; i < numQuantums; i++) {
+ size_t result = decodeQuantum(pos, src);
+ if(!result) {
+ free(newstr);
+
+ return CURLE_BAD_CONTENT_ENCODING;
+ }
+
+ pos += result;
+ src += 4;
+ }
+
+ /* Zero terminate */
+ *pos = '\0';
+
+ /* Return the decoded data */
+ *outptr = newstr;
+ *outlen = rawlen;
+
+ return CURLE_OK;
+}
+
+static CURLcode base64_encode(const char *table64,
+ struct SessionHandle *data,
+ const char *inputbuff, size_t insize,
+ char **outptr, size_t *outlen)
+{
+ CURLcode error;
+ unsigned char ibuf[3];
+ unsigned char obuf[4];
+ int i;
+ int inputparts;
+ char *output;
+ char *base64data;
+ char *convbuf = NULL;
+
+ const char *indata = inputbuff;
+
+ *outptr = NULL;
+ *outlen = 0;
+
+ if(0 == insize)
+ insize = strlen(indata);
+
+ base64data = output = malloc(insize*4/3+4);
+ if(NULL == output)
+ return CURLE_OUT_OF_MEMORY;
+
+ /*
+ * The base64 data needs to be created using the network encoding
+ * not the host encoding. And we can't change the actual input
+ * so we copy it to a buffer, translate it, and use that instead.
+ */
+ error = Curl_convert_clone(data, indata, insize, &convbuf);
+ if(error) {
+ free(output);
+ return error;
+ }
+
+ if(convbuf)
+ indata = (char *)convbuf;
+
+ while(insize > 0) {
+ for(i = inputparts = 0; i < 3; i++) {
+ if(insize > 0) {
+ inputparts++;
+ ibuf[i] = (unsigned char) *indata;
+ indata++;
+ insize--;
+ }
+ else
+ ibuf[i] = 0;
+ }
+
+ obuf[0] = (unsigned char) ((ibuf[0] & 0xFC) >> 2);
+ obuf[1] = (unsigned char) (((ibuf[0] & 0x03) << 4) | \
+ ((ibuf[1] & 0xF0) >> 4));
+ obuf[2] = (unsigned char) (((ibuf[1] & 0x0F) << 2) | \
+ ((ibuf[2] & 0xC0) >> 6));
+ obuf[3] = (unsigned char) (ibuf[2] & 0x3F);
+
+ switch(inputparts) {
+ case 1: /* only one byte read */
+ snprintf(output, 5, "%c%c==",
+ table64[obuf[0]],
+ table64[obuf[1]]);
+ break;
+ case 2: /* two bytes read */
+ snprintf(output, 5, "%c%c%c=",
+ table64[obuf[0]],
+ table64[obuf[1]],
+ table64[obuf[2]]);
+ break;
+ default:
+ snprintf(output, 5, "%c%c%c%c",
+ table64[obuf[0]],
+ table64[obuf[1]],
+ table64[obuf[2]],
+ table64[obuf[3]] );
+ break;
+ }
+ output += 4;
+ }
+ *output = '\0';
+ *outptr = base64data; /* return pointer to new data, allocated memory */
+
+ free(convbuf);
+
+ *outlen = strlen(base64data); /* return the length of the new data */
+
+ return CURLE_OK;
+}
+
+/*
+ * Curl_base64_encode()
+ *
+ * Given a pointer to an input buffer and an input size, encode it and
+ * return a pointer in *outptr to a newly allocated memory area holding
+ * encoded data. Size of encoded data is returned in variable pointed by
+ * outlen.
+ *
+ * Input length of 0 indicates input buffer holds a NUL-terminated string.
+ *
+ * Returns CURLE_OK on success, otherwise specific error code. Function
+ * output shall not be considered valid unless CURLE_OK is returned.
+ *
+ * When encoded data length is 0, returns NULL in *outptr.
+ *
+ * @unittest: 1302
+ */
+CURLcode Curl_base64_encode(struct SessionHandle *data,
+ const char *inputbuff, size_t insize,
+ char **outptr, size_t *outlen)
+{
+ return base64_encode(base64, data, inputbuff, insize, outptr, outlen);
+}
+
+/*
+ * Curl_base64url_encode()
+ *
+ * Given a pointer to an input buffer and an input size, encode it and
+ * return a pointer in *outptr to a newly allocated memory area holding
+ * encoded data. Size of encoded data is returned in variable pointed by
+ * outlen.
+ *
+ * Input length of 0 indicates input buffer holds a NUL-terminated string.
+ *
+ * Returns CURLE_OK on success, otherwise specific error code. Function
+ * output shall not be considered valid unless CURLE_OK is returned.
+ *
+ * When encoded data length is 0, returns NULL in *outptr.
+ *
+ * @unittest: 1302
+ */
+CURLcode Curl_base64url_encode(struct SessionHandle *data,
+ const char *inputbuff, size_t insize,
+ char **outptr, size_t *outlen)
+{
+ return base64_encode(base64url, data, inputbuff, insize, outptr, outlen);
+}
+/* ---- End of Base64 Encoding ---- */
diff --git a/Utilities/cmcurl/lib/conncache.c b/Utilities/cmcurl/lib/conncache.c
new file mode 100644
index 000000000..c712ed7b9
--- /dev/null
+++ b/Utilities/cmcurl/lib/conncache.c
@@ -0,0 +1,364 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012, Linus Nielsen Feltzing, <linus@haxx.se>
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#include "urldata.h"
+#include "url.h"
+#include "progress.h"
+#include "multiif.h"
+#include "sendf.h"
+#include "rawstr.h"
+#include "conncache.h"
+#include "curl_printf.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+static void conn_llist_dtor(void *user, void *element)
+{
+ struct connectdata *data = element;
+ (void)user;
+
+ data->bundle = NULL;
+}
+
+static CURLcode bundle_create(struct SessionHandle *data,
+ struct connectbundle **cb_ptr)
+{
+ (void)data;
+ DEBUGASSERT(*cb_ptr == NULL);
+ *cb_ptr = malloc(sizeof(struct connectbundle));
+ if(!*cb_ptr)
+ return CURLE_OUT_OF_MEMORY;
+
+ (*cb_ptr)->num_connections = 0;
+ (*cb_ptr)->multiuse = BUNDLE_UNKNOWN;
+
+ (*cb_ptr)->conn_list = Curl_llist_alloc((curl_llist_dtor) conn_llist_dtor);
+ if(!(*cb_ptr)->conn_list) {
+ Curl_safefree(*cb_ptr);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ return CURLE_OK;
+}
+
+static void bundle_destroy(struct connectbundle *cb_ptr)
+{
+ if(!cb_ptr)
+ return;
+
+ if(cb_ptr->conn_list) {
+ Curl_llist_destroy(cb_ptr->conn_list, NULL);
+ cb_ptr->conn_list = NULL;
+ }
+ free(cb_ptr);
+}
+
+/* Add a connection to a bundle */
+static CURLcode bundle_add_conn(struct connectbundle *cb_ptr,
+ struct connectdata *conn)
+{
+ if(!Curl_llist_insert_next(cb_ptr->conn_list, cb_ptr->conn_list->tail, conn))
+ return CURLE_OUT_OF_MEMORY;
+
+ conn->bundle = cb_ptr;
+
+ cb_ptr->num_connections++;
+ return CURLE_OK;
+}
+
+/* Remove a connection from a bundle */
+static int bundle_remove_conn(struct connectbundle *cb_ptr,
+ struct connectdata *conn)
+{
+ struct curl_llist_element *curr;
+
+ curr = cb_ptr->conn_list->head;
+ while(curr) {
+ if(curr->ptr == conn) {
+ Curl_llist_remove(cb_ptr->conn_list, curr, NULL);
+ cb_ptr->num_connections--;
+ conn->bundle = NULL;
+ return 1; /* we removed a handle */
+ }
+ curr = curr->next;
+ }
+ return 0;
+}
+
+static void free_bundle_hash_entry(void *freethis)
+{
+ struct connectbundle *b = (struct connectbundle *) freethis;
+
+ bundle_destroy(b);
+}
+
+int Curl_conncache_init(struct conncache *connc, int size)
+{
+ return Curl_hash_init(&connc->hash, size, Curl_hash_str,
+ Curl_str_key_compare, free_bundle_hash_entry);
+}
+
+void Curl_conncache_destroy(struct conncache *connc)
+{
+ if(connc)
+ Curl_hash_destroy(&connc->hash);
+}
+
+/* returns an allocated key to find a bundle for this connection */
+static char *hashkey(struct connectdata *conn)
+{
+ return aprintf("%s:%d",
+ conn->bits.proxy?conn->proxy.name:conn->host.name,
+ conn->localport);
+}
+
+/* Look up the bundle with all the connections to the same host this
+ connectdata struct is setup to use. */
+struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
+ struct conncache *connc)
+{
+ struct connectbundle *bundle = NULL;
+ if(connc) {
+ char *key = hashkey(conn);
+ if(key) {
+ bundle = Curl_hash_pick(&connc->hash, key, strlen(key));
+ free(key);
+ }
+ }
+
+ return bundle;
+}
+
+static bool conncache_add_bundle(struct conncache *connc,
+ char *key,
+ struct connectbundle *bundle)
+{
+ void *p = Curl_hash_add(&connc->hash, key, strlen(key), bundle);
+
+ return p?TRUE:FALSE;
+}
+
+static void conncache_remove_bundle(struct conncache *connc,
+ struct connectbundle *bundle)
+{
+ struct curl_hash_iterator iter;
+ struct curl_hash_element *he;
+
+ if(!connc)
+ return;
+
+ Curl_hash_start_iterate(&connc->hash, &iter);
+
+ he = Curl_hash_next_element(&iter);
+ while(he) {
+ if(he->ptr == bundle) {
+ /* The bundle is destroyed by the hash destructor function,
+ free_bundle_hash_entry() */
+ Curl_hash_delete(&connc->hash, he->key, he->key_len);
+ return;
+ }
+
+ he = Curl_hash_next_element(&iter);
+ }
+}
+
+CURLcode Curl_conncache_add_conn(struct conncache *connc,
+ struct connectdata *conn)
+{
+ CURLcode result;
+ struct connectbundle *bundle;
+ struct connectbundle *new_bundle = NULL;
+ struct SessionHandle *data = conn->data;
+
+ bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache);
+ if(!bundle) {
+ char *key;
+ int rc;
+
+ result = bundle_create(data, &new_bundle);
+ if(result)
+ return result;
+
+ key = hashkey(conn);
+ if(!key) {
+ bundle_destroy(new_bundle);
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ rc = conncache_add_bundle(data->state.conn_cache, key, new_bundle);
+ free(key);
+ if(!rc) {
+ bundle_destroy(new_bundle);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ bundle = new_bundle;
+ }
+
+ result = bundle_add_conn(bundle, conn);
+ if(result) {
+ if(new_bundle)
+ conncache_remove_bundle(data->state.conn_cache, new_bundle);
+ return result;
+ }
+
+ conn->connection_id = connc->next_connection_id++;
+ connc->num_connections++;
+
+ DEBUGF(infof(conn->data, "Added connection %ld. "
+ "The cache now contains %" CURL_FORMAT_CURL_OFF_TU " members\n",
+ conn->connection_id, (curl_off_t) connc->num_connections));
+
+ return CURLE_OK;
+}
+
+void Curl_conncache_remove_conn(struct conncache *connc,
+ struct connectdata *conn)
+{
+ struct connectbundle *bundle = conn->bundle;
+
+ /* The bundle pointer can be NULL, since this function can be called
+ due to a failed connection attempt, before being added to a bundle */
+ if(bundle) {
+ bundle_remove_conn(bundle, conn);
+ if(bundle->num_connections == 0) {
+ conncache_remove_bundle(connc, bundle);
+ }
+
+ if(connc) {
+ connc->num_connections--;
+
+ DEBUGF(infof(conn->data, "The cache now contains %"
+ CURL_FORMAT_CURL_OFF_TU " members\n",
+ (curl_off_t) connc->num_connections));
+ }
+ }
+}
+
+/* This function iterates the entire connection cache and calls the
+ function func() with the connection pointer as the first argument
+ and the supplied 'param' argument as the other,
+
+ Return 0 from func() to continue the loop, return 1 to abort it.
+ */
+void Curl_conncache_foreach(struct conncache *connc,
+ void *param,
+ int (*func)(struct connectdata *conn, void *param))
+{
+ struct curl_hash_iterator iter;
+ struct curl_llist_element *curr;
+ struct curl_hash_element *he;
+
+ if(!connc)
+ return;
+
+ Curl_hash_start_iterate(&connc->hash, &iter);
+
+ he = Curl_hash_next_element(&iter);
+ while(he) {
+ struct connectbundle *bundle;
+
+ bundle = he->ptr;
+ he = Curl_hash_next_element(&iter);
+
+ curr = bundle->conn_list->head;
+ while(curr) {
+ /* Yes, we need to update curr before calling func(), because func()
+ might decide to remove the connection */
+ struct connectdata *conn = curr->ptr;
+ curr = curr->next;
+
+ if(1 == func(conn, param))
+ return;
+ }
+ }
+}
+
+/* Return the first connection found in the cache. Used when closing all
+ connections */
+struct connectdata *
+Curl_conncache_find_first_connection(struct conncache *connc)
+{
+ struct curl_hash_iterator iter;
+ struct curl_hash_element *he;
+ struct connectbundle *bundle;
+
+ Curl_hash_start_iterate(&connc->hash, &iter);
+
+ he = Curl_hash_next_element(&iter);
+ while(he) {
+ struct curl_llist_element *curr;
+ bundle = he->ptr;
+
+ curr = bundle->conn_list->head;
+ if(curr) {
+ return curr->ptr;
+ }
+
+ he = Curl_hash_next_element(&iter);
+ }
+
+ return NULL;
+}
+
+
+#if 0
+/* Useful for debugging the connection cache */
+void Curl_conncache_print(struct conncache *connc)
+{
+ struct curl_hash_iterator iter;
+ struct curl_llist_element *curr;
+ struct curl_hash_element *he;
+
+ if(!connc)
+ return;
+
+ fprintf(stderr, "=Bundle cache=\n");
+
+ Curl_hash_start_iterate(connc->hash, &iter);
+
+ he = Curl_hash_next_element(&iter);
+ while(he) {
+ struct connectbundle *bundle;
+ struct connectdata *conn;
+
+ bundle = he->ptr;
+
+ fprintf(stderr, "%s -", he->key);
+ curr = bundle->conn_list->head;
+ while(curr) {
+ conn = curr->ptr;
+
+ fprintf(stderr, " [%p %d]", (void *)conn, conn->inuse);
+ curr = curr->next;
+ }
+ fprintf(stderr, "\n");
+
+ he = Curl_hash_next_element(&iter);
+ }
+}
+#endif
diff --git a/Utilities/cmcurl/lib/conncache.h b/Utilities/cmcurl/lib/conncache.h
new file mode 100644
index 000000000..59181bf3d
--- /dev/null
+++ b/Utilities/cmcurl/lib/conncache.h
@@ -0,0 +1,68 @@
+#ifndef HEADER_CURL_CONNCACHE_H
+#define HEADER_CURL_CONNCACHE_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+struct conncache {
+ struct curl_hash hash;
+ size_t num_connections;
+ long next_connection_id;
+ struct timeval last_cleanup;
+};
+
+#define BUNDLE_NO_MULTIUSE -1
+#define BUNDLE_UNKNOWN 0 /* initial value */
+#define BUNDLE_PIPELINING 1
+#define BUNDLE_MULTIPLEX 2
+
+struct connectbundle {
+ int multiuse; /* supports multi-use */
+ size_t num_connections; /* Number of connections in the bundle */
+ struct curl_llist *conn_list; /* The connectdata members of the bundle */
+};
+
+int Curl_conncache_init(struct conncache *, int size);
+
+void Curl_conncache_destroy(struct conncache *connc);
+
+/* return the correct bundle, to a host or a proxy */
+struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
+ struct conncache *connc);
+
+CURLcode Curl_conncache_add_conn(struct conncache *connc,
+ struct connectdata *conn);
+
+void Curl_conncache_remove_conn(struct conncache *connc,
+ struct connectdata *conn);
+
+void Curl_conncache_foreach(struct conncache *connc,
+ void *param,
+ int (*func)(struct connectdata *conn,
+ void *param));
+
+struct connectdata *
+Curl_conncache_find_first_connection(struct conncache *connc);
+
+void Curl_conncache_print(struct conncache *connc);
+
+#endif /* HEADER_CURL_CONNCACHE_H */
diff --git a/Utilities/cmcurl/lib/connect.c b/Utilities/cmcurl/lib/connect.c
new file mode 100644
index 000000000..18ac32c32
--- /dev/null
+++ b/Utilities/cmcurl/lib/connect.c
@@ -0,0 +1,1383 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h> /* <netinet/tcp.h> may need it */
+#endif
+#ifdef HAVE_SYS_UN_H
+#include <sys/un.h> /* for sockaddr_un */
+#endif
+#ifdef HAVE_NETINET_TCP_H
+#include <netinet/tcp.h> /* for TCP_NODELAY */
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#if (defined(HAVE_IOCTL_FIONBIO) && defined(NETWARE))
+#include <sys/filio.h>
+#endif
+#ifdef NETWARE
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#include "curl_printf.h"
+#include "urldata.h"
+#include "sendf.h"
+#include "if2ip.h"
+#include "strerror.h"
+#include "connect.h"
+#include "select.h"
+#include "url.h" /* for Curl_safefree() */
+#include "multiif.h"
+#include "sockaddr.h" /* required for Curl_sockaddr_storage */
+#include "inet_ntop.h"
+#include "inet_pton.h"
+#include "vtls/vtls.h" /* for Curl_ssl_check_cxn() */
+#include "progress.h"
+#include "warnless.h"
+#include "conncache.h"
+#include "multihandle.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#ifdef __SYMBIAN32__
+/* This isn't actually supported under Symbian OS */
+#undef SO_NOSIGPIPE
+#endif
+
+static bool verifyconnect(curl_socket_t sockfd, int *error);
+
+#if defined(__DragonFly__) || defined(HAVE_WINSOCK_H)
+/* DragonFlyBSD and Windows use millisecond units */
+#define KEEPALIVE_FACTOR(x) (x *= 1000)
+#else
+#define KEEPALIVE_FACTOR(x)
+#endif
+
+#if defined(HAVE_WINSOCK2_H) && !defined(SIO_KEEPALIVE_VALS)
+#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4)
+
+struct tcp_keepalive {
+ u_long onoff;
+ u_long keepalivetime;
+ u_long keepaliveinterval;
+};
+#endif
+
+static void
+tcpkeepalive(struct SessionHandle *data,
+ curl_socket_t sockfd)
+{
+ int optval = data->set.tcp_keepalive?1:0;
+
+ /* only set IDLE and INTVL if setting KEEPALIVE is successful */
+ if(setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE,
+ (void *)&optval, sizeof(optval)) < 0) {
+ infof(data, "Failed to set SO_KEEPALIVE on fd %d\n", sockfd);
+ }
+ else {
+#if defined(SIO_KEEPALIVE_VALS)
+ struct tcp_keepalive vals;
+ DWORD dummy;
+ vals.onoff = 1;
+ optval = curlx_sltosi(data->set.tcp_keepidle);
+ KEEPALIVE_FACTOR(optval);
+ vals.keepalivetime = optval;
+ optval = curlx_sltosi(data->set.tcp_keepintvl);
+ KEEPALIVE_FACTOR(optval);
+ vals.keepaliveinterval = optval;
+ if(WSAIoctl(sockfd, SIO_KEEPALIVE_VALS, (LPVOID) &vals, sizeof(vals),
+ NULL, 0, &dummy, NULL, NULL) != 0) {
+ infof(data, "Failed to set SIO_KEEPALIVE_VALS on fd %d: %d\n",
+ (int)sockfd, WSAGetLastError());
+ }
+#else
+#ifdef TCP_KEEPIDLE
+ optval = curlx_sltosi(data->set.tcp_keepidle);
+ KEEPALIVE_FACTOR(optval);
+ if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE,
+ (void *)&optval, sizeof(optval)) < 0) {
+ infof(data, "Failed to set TCP_KEEPIDLE on fd %d\n", sockfd);
+ }
+#endif
+#ifdef TCP_KEEPINTVL
+ optval = curlx_sltosi(data->set.tcp_keepintvl);
+ KEEPALIVE_FACTOR(optval);
+ if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL,
+ (void *)&optval, sizeof(optval)) < 0) {
+ infof(data, "Failed to set TCP_KEEPINTVL on fd %d\n", sockfd);
+ }
+#endif
+#ifdef TCP_KEEPALIVE
+ /* Mac OS X style */
+ optval = curlx_sltosi(data->set.tcp_keepidle);
+ KEEPALIVE_FACTOR(optval);
+ if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPALIVE,
+ (void *)&optval, sizeof(optval)) < 0) {
+ infof(data, "Failed to set TCP_KEEPALIVE on fd %d\n", sockfd);
+ }
+#endif
+#endif
+ }
+}
+
+static CURLcode
+singleipconnect(struct connectdata *conn,
+ const Curl_addrinfo *ai, /* start connecting to this */
+ curl_socket_t *sock);
+
+/*
+ * Curl_timeleft() returns the amount of milliseconds left allowed for the
+ * transfer/connection. If the value is negative, the timeout time has already
+ * elapsed.
+ *
+ * The start time is stored in progress.t_startsingle - as set with
+ * Curl_pgrsTime(..., TIMER_STARTSINGLE);
+ *
+ * If 'nowp' is non-NULL, it points to the current time.
+ * 'duringconnect' is FALSE if not during a connect, as then of course the
+ * connect timeout is not taken into account!
+ *
+ * @unittest: 1303
+ */
+long Curl_timeleft(struct SessionHandle *data,
+ struct timeval *nowp,
+ bool duringconnect)
+{
+ int timeout_set = 0;
+ long timeout_ms = duringconnect?DEFAULT_CONNECT_TIMEOUT:0;
+ struct timeval now;
+
+ /* if a timeout is set, use the most restrictive one */
+
+ if(data->set.timeout > 0)
+ timeout_set |= 1;
+ if(duringconnect && (data->set.connecttimeout > 0))
+ timeout_set |= 2;
+
+ switch (timeout_set) {
+ case 1:
+ timeout_ms = data->set.timeout;
+ break;
+ case 2:
+ timeout_ms = data->set.connecttimeout;
+ break;
+ case 3:
+ if(data->set.timeout < data->set.connecttimeout)
+ timeout_ms = data->set.timeout;
+ else
+ timeout_ms = data->set.connecttimeout;
+ break;
+ default:
+ /* use the default */
+ if(!duringconnect)
+ /* if we're not during connect, there's no default timeout so if we're
+ at zero we better just return zero and not make it a negative number
+ by the math below */
+ return 0;
+ break;
+ }
+
+ if(!nowp) {
+ now = Curl_tvnow();
+ nowp = &now;
+ }
+
+ /* subtract elapsed time */
+ if(duringconnect)
+ /* since this most recent connect started */
+ timeout_ms -= Curl_tvdiff(*nowp, data->progress.t_startsingle);
+ else
+ /* since the entire operation started */
+ timeout_ms -= Curl_tvdiff(*nowp, data->progress.t_startop);
+ if(!timeout_ms)
+ /* avoid returning 0 as that means no timeout! */
+ return -1;
+
+ return timeout_ms;
+}
+
+static CURLcode bindlocal(struct connectdata *conn,
+ curl_socket_t sockfd, int af, unsigned int scope)
+{
+ struct SessionHandle *data = conn->data;
+
+ struct Curl_sockaddr_storage sa;
+ struct sockaddr *sock = (struct sockaddr *)&sa; /* bind to this address */
+ curl_socklen_t sizeof_sa = 0; /* size of the data sock points to */
+ struct sockaddr_in *si4 = (struct sockaddr_in *)&sa;
+#ifdef ENABLE_IPV6
+ struct sockaddr_in6 *si6 = (struct sockaddr_in6 *)&sa;
+#endif
+
+ struct Curl_dns_entry *h=NULL;
+ unsigned short port = data->set.localport; /* use this port number, 0 for
+ "random" */
+ /* how many port numbers to try to bind to, increasing one at a time */
+ int portnum = data->set.localportrange;
+ const char *dev = data->set.str[STRING_DEVICE];
+ int error;
+
+ /*************************************************************
+ * Select device to bind socket to
+ *************************************************************/
+ if(!dev && !port)
+ /* no local kind of binding was requested */
+ return CURLE_OK;
+
+ memset(&sa, 0, sizeof(struct Curl_sockaddr_storage));
+
+ if(dev && (strlen(dev)<255) ) {
+ char myhost[256] = "";
+ int done = 0; /* -1 for error, 1 for address found */
+ bool is_interface = FALSE;
+ bool is_host = FALSE;
+ static const char *if_prefix = "if!";
+ static const char *host_prefix = "host!";
+
+ if(strncmp(if_prefix, dev, strlen(if_prefix)) == 0) {
+ dev += strlen(if_prefix);
+ is_interface = TRUE;
+ }
+ else if(strncmp(host_prefix, dev, strlen(host_prefix)) == 0) {
+ dev += strlen(host_prefix);
+ is_host = TRUE;
+ }
+
+ /* interface */
+ if(!is_host) {
+ switch(Curl_if2ip(af, scope, conn->scope_id, dev,
+ myhost, sizeof(myhost))) {
+ case IF2IP_NOT_FOUND:
+ if(is_interface) {
+ /* Do not fall back to treating it as a host name */
+ failf(data, "Couldn't bind to interface '%s'", dev);
+ return CURLE_INTERFACE_FAILED;
+ }
+ break;
+ case IF2IP_AF_NOT_SUPPORTED:
+ /* Signal the caller to try another address family if available */
+ return CURLE_UNSUPPORTED_PROTOCOL;
+ case IF2IP_FOUND:
+ is_interface = TRUE;
+ /*
+ * We now have the numerical IP address in the 'myhost' buffer
+ */
+ infof(data, "Local Interface %s is ip %s using address family %i\n",
+ dev, myhost, af);
+ done = 1;
+
+#ifdef SO_BINDTODEVICE
+ /* I am not sure any other OSs than Linux that provide this feature,
+ * and at the least I cannot test. --Ben
+ *
+ * This feature allows one to tightly bind the local socket to a
+ * particular interface. This will force even requests to other
+ * local interfaces to go out the external interface.
+ *
+ *
+ * Only bind to the interface when specified as interface, not just
+ * as a hostname or ip address.
+ */
+ if(setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
+ dev, (curl_socklen_t)strlen(dev)+1) != 0) {
+ error = SOCKERRNO;
+ infof(data, "SO_BINDTODEVICE %s failed with errno %d: %s;"
+ " will do regular bind\n",
+ dev, error, Curl_strerror(conn, error));
+ /* This is typically "errno 1, error: Operation not permitted" if
+ you're not running as root or another suitable privileged
+ user */
+ }
+#endif
+ break;
+ }
+ }
+ if(!is_interface) {
+ /*
+ * This was not an interface, resolve the name as a host name
+ * or IP number
+ *
+ * Temporarily force name resolution to use only the address type
+ * of the connection. The resolve functions should really be changed
+ * to take a type parameter instead.
+ */
+ long ipver = conn->ip_version;
+ int rc;
+
+ if(af == AF_INET)
+ conn->ip_version = CURL_IPRESOLVE_V4;
+#ifdef ENABLE_IPV6
+ else if(af == AF_INET6)
+ conn->ip_version = CURL_IPRESOLVE_V6;
+#endif
+
+ rc = Curl_resolv(conn, dev, 0, &h);
+ if(rc == CURLRESOLV_PENDING)
+ (void)Curl_resolver_wait_resolv(conn, &h);
+ conn->ip_version = ipver;
+
+ if(h) {
+ /* convert the resolved address, sizeof myhost >= INET_ADDRSTRLEN */
+ Curl_printable_address(h->addr, myhost, sizeof(myhost));
+ infof(data, "Name '%s' family %i resolved to '%s' family %i\n",
+ dev, af, myhost, h->addr->ai_family);
+ Curl_resolv_unlock(data, h);
+ done = 1;
+ }
+ else {
+ /*
+ * provided dev was no interface (or interfaces are not supported
+ * e.g. solaris) no ip address and no domain we fail here
+ */
+ done = -1;
+ }
+ }
+
+ if(done > 0) {
+#ifdef ENABLE_IPV6
+ /* IPv6 address */
+ if(af == AF_INET6) {
+#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+ char *scope_ptr = strchr(myhost, '%');
+ if(scope_ptr)
+ *(scope_ptr++) = 0;
+#endif
+ if(Curl_inet_pton(AF_INET6, myhost, &si6->sin6_addr) > 0) {
+ si6->sin6_family = AF_INET6;
+ si6->sin6_port = htons(port);
+#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+ if(scope_ptr)
+ /* The "myhost" string either comes from Curl_if2ip or from
+ Curl_printable_address. The latter returns only numeric scope
+ IDs and the former returns none at all. So the scope ID, if
+ present, is known to be numeric */
+ si6->sin6_scope_id = atoi(scope_ptr);
+#endif
+ }
+ sizeof_sa = sizeof(struct sockaddr_in6);
+ }
+ else
+#endif
+ /* IPv4 address */
+ if((af == AF_INET) &&
+ (Curl_inet_pton(AF_INET, myhost, &si4->sin_addr) > 0)) {
+ si4->sin_family = AF_INET;
+ si4->sin_port = htons(port);
+ sizeof_sa = sizeof(struct sockaddr_in);
+ }
+ }
+
+ if(done < 1) {
+ failf(data, "Couldn't bind to '%s'", dev);
+ return CURLE_INTERFACE_FAILED;
+ }
+ }
+ else {
+ /* no device was given, prepare sa to match af's needs */
+#ifdef ENABLE_IPV6
+ if(af == AF_INET6) {
+ si6->sin6_family = AF_INET6;
+ si6->sin6_port = htons(port);
+ sizeof_sa = sizeof(struct sockaddr_in6);
+ }
+ else
+#endif
+ if(af == AF_INET) {
+ si4->sin_family = AF_INET;
+ si4->sin_port = htons(port);
+ sizeof_sa = sizeof(struct sockaddr_in);
+ }
+ }
+
+ for(;;) {
+ if(bind(sockfd, sock, sizeof_sa) >= 0) {
+ /* we succeeded to bind */
+ struct Curl_sockaddr_storage add;
+ curl_socklen_t size = sizeof(add);
+ memset(&add, 0, sizeof(struct Curl_sockaddr_storage));
+ if(getsockname(sockfd, (struct sockaddr *) &add, &size) < 0) {
+ data->state.os_errno = error = SOCKERRNO;
+ failf(data, "getsockname() failed with errno %d: %s",
+ error, Curl_strerror(conn, error));
+ return CURLE_INTERFACE_FAILED;
+ }
+ infof(data, "Local port: %hu\n", port);
+ conn->bits.bound = TRUE;
+ return CURLE_OK;
+ }
+
+ if(--portnum > 0) {
+ infof(data, "Bind to local port %hu failed, trying next\n", port);
+ port++; /* try next port */
+ /* We re-use/clobber the port variable here below */
+ if(sock->sa_family == AF_INET)
+ si4->sin_port = ntohs(port);
+#ifdef ENABLE_IPV6
+ else
+ si6->sin6_port = ntohs(port);
+#endif
+ }
+ else
+ break;
+ }
+
+ data->state.os_errno = error = SOCKERRNO;
+ failf(data, "bind failed with errno %d: %s",
+ error, Curl_strerror(conn, error));
+
+ return CURLE_INTERFACE_FAILED;
+}
+
+/*
+ * verifyconnect() returns TRUE if the connect really has happened.
+ */
+static bool verifyconnect(curl_socket_t sockfd, int *error)
+{
+ bool rc = TRUE;
+#ifdef SO_ERROR
+ int err = 0;
+ curl_socklen_t errSize = sizeof(err);
+
+#ifdef WIN32
+ /*
+ * In October 2003 we effectively nullified this function on Windows due to
+ * problems with it using all CPU in multi-threaded cases.
+ *
+ * In May 2004, we bring it back to offer more info back on connect failures.
+ * Gisle Vanem could reproduce the former problems with this function, but
+ * could avoid them by adding this SleepEx() call below:
+ *
+ * "I don't have Rational Quantify, but the hint from his post was
+ * ntdll::NtRemoveIoCompletion(). So I'd assume the SleepEx (or maybe
+ * just Sleep(0) would be enough?) would release whatever
+ * mutex/critical-section the ntdll call is waiting on.
+ *
+ * Someone got to verify this on Win-NT 4.0, 2000."
+ */
+
+#ifdef _WIN32_WCE
+ Sleep(0);
+#else
+ SleepEx(0, FALSE);
+#endif
+
+#endif
+
+ if(0 != getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void *)&err, &errSize))
+ err = SOCKERRNO;
+#ifdef _WIN32_WCE
+ /* Old WinCE versions don't support SO_ERROR */
+ if(WSAENOPROTOOPT == err) {
+ SET_SOCKERRNO(0);
+ err = 0;
+ }
+#endif
+#ifdef __minix
+ /* Minix 3.1.x doesn't support getsockopt on UDP sockets */
+ if(EBADIOCTL == err) {
+ SET_SOCKERRNO(0);
+ err = 0;
+ }
+#endif
+ if((0 == err) || (EISCONN == err))
+ /* we are connected, awesome! */
+ rc = TRUE;
+ else
+ /* This wasn't a successful connect */
+ rc = FALSE;
+ if(error)
+ *error = err;
+#else
+ (void)sockfd;
+ if(error)
+ *error = SOCKERRNO;
+#endif
+ return rc;
+}
+
+/* Used within the multi interface. Try next IP address, return TRUE if no
+ more address exists or error */
+static CURLcode trynextip(struct connectdata *conn,
+ int sockindex,
+ int tempindex)
+{
+ const int other = tempindex ^ 1;
+ CURLcode result = CURLE_COULDNT_CONNECT;
+
+ /* First clean up after the failed socket.
+ Don't close it yet to ensure that the next IP's socket gets a different
+ file descriptor, which can prevent bugs when the curl_multi_socket_action
+ interface is used with certain select() replacements such as kqueue. */
+ curl_socket_t fd_to_close = conn->tempsock[tempindex];
+ conn->tempsock[tempindex] = CURL_SOCKET_BAD;
+
+ if(sockindex == FIRSTSOCKET) {
+ Curl_addrinfo *ai = NULL;
+ int family = AF_UNSPEC;
+
+ if(conn->tempaddr[tempindex]) {
+ /* find next address in the same protocol family */
+ family = conn->tempaddr[tempindex]->ai_family;
+ ai = conn->tempaddr[tempindex]->ai_next;
+ }
+#ifdef ENABLE_IPV6
+ else if(conn->tempaddr[0]) {
+ /* happy eyeballs - try the other protocol family */
+ int firstfamily = conn->tempaddr[0]->ai_family;
+ family = (firstfamily == AF_INET) ? AF_INET6 : AF_INET;
+ ai = conn->tempaddr[0]->ai_next;
+ }
+#endif
+
+ while(ai) {
+ if(conn->tempaddr[other]) {
+ /* we can safely skip addresses of the other protocol family */
+ while(ai && ai->ai_family != family)
+ ai = ai->ai_next;
+ }
+
+ if(ai) {
+ result = singleipconnect(conn, ai, &conn->tempsock[tempindex]);
+ if(result == CURLE_COULDNT_CONNECT) {
+ ai = ai->ai_next;
+ continue;
+ }
+
+ conn->tempaddr[tempindex] = ai;
+ }
+ break;
+ }
+ }
+
+ if(fd_to_close != CURL_SOCKET_BAD)
+ Curl_closesocket(conn, fd_to_close);
+
+ return result;
+}
+
+/* Copies connection info into the session handle to make it available
+ when the session handle is no longer associated with a connection. */
+void Curl_persistconninfo(struct connectdata *conn)
+{
+ memcpy(conn->data->info.conn_primary_ip, conn->primary_ip, MAX_IPADR_LEN);
+ memcpy(conn->data->info.conn_local_ip, conn->local_ip, MAX_IPADR_LEN);
+ conn->data->info.conn_primary_port = conn->primary_port;
+ conn->data->info.conn_local_port = conn->local_port;
+}
+
+/* retrieves ip address and port from a sockaddr structure */
+static bool getaddressinfo(struct sockaddr* sa, char* addr,
+ long* port)
+{
+ unsigned short us_port;
+ struct sockaddr_in* si = NULL;
+#ifdef ENABLE_IPV6
+ struct sockaddr_in6* si6 = NULL;
+#endif
+#if defined(HAVE_SYS_UN_H) && defined(AF_UNIX)
+ struct sockaddr_un* su = NULL;
+#endif
+
+ switch (sa->sa_family) {
+ case AF_INET:
+ si = (struct sockaddr_in*) sa;
+ if(Curl_inet_ntop(sa->sa_family, &si->sin_addr,
+ addr, MAX_IPADR_LEN)) {
+ us_port = ntohs(si->sin_port);
+ *port = us_port;
+ return TRUE;
+ }
+ break;
+#ifdef ENABLE_IPV6
+ case AF_INET6:
+ si6 = (struct sockaddr_in6*)sa;
+ if(Curl_inet_ntop(sa->sa_family, &si6->sin6_addr,
+ addr, MAX_IPADR_LEN)) {
+ us_port = ntohs(si6->sin6_port);
+ *port = us_port;
+ return TRUE;
+ }
+ break;
+#endif
+#if defined(HAVE_SYS_UN_H) && defined(AF_UNIX)
+ case AF_UNIX:
+ su = (struct sockaddr_un*)sa;
+ snprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path);
+ *port = 0;
+ return TRUE;
+#endif
+ default:
+ break;
+ }
+
+ addr[0] = '\0';
+ *port = 0;
+
+ return FALSE;
+}
+
+/* retrieves the start/end point information of a socket of an established
+ connection */
+void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
+{
+ curl_socklen_t len;
+ struct Curl_sockaddr_storage ssrem;
+ struct Curl_sockaddr_storage ssloc;
+ struct SessionHandle *data = conn->data;
+
+ if(conn->socktype == SOCK_DGRAM)
+ /* there's no connection! */
+ return;
+
+ if(!conn->bits.reuse) {
+ int error;
+
+ len = sizeof(struct Curl_sockaddr_storage);
+ if(getpeername(sockfd, (struct sockaddr*) &ssrem, &len)) {
+ error = SOCKERRNO;
+ failf(data, "getpeername() failed with errno %d: %s",
+ error, Curl_strerror(conn, error));
+ return;
+ }
+
+ len = sizeof(struct Curl_sockaddr_storage);
+ memset(&ssloc, 0, sizeof(ssloc));
+ if(getsockname(sockfd, (struct sockaddr*) &ssloc, &len)) {
+ error = SOCKERRNO;
+ failf(data, "getsockname() failed with errno %d: %s",
+ error, Curl_strerror(conn, error));
+ return;
+ }
+
+ if(!getaddressinfo((struct sockaddr*)&ssrem,
+ conn->primary_ip, &conn->primary_port)) {
+ error = ERRNO;
+ failf(data, "ssrem inet_ntop() failed with errno %d: %s",
+ error, Curl_strerror(conn, error));
+ return;
+ }
+ memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
+
+ if(!getaddressinfo((struct sockaddr*)&ssloc,
+ conn->local_ip, &conn->local_port)) {
+ error = ERRNO;
+ failf(data, "ssloc inet_ntop() failed with errno %d: %s",
+ error, Curl_strerror(conn, error));
+ return;
+ }
+
+ }
+
+ /* persist connection info in session handle */
+ Curl_persistconninfo(conn);
+}
+
+/*
+ * Curl_is_connected() checks if the socket has connected.
+ */
+
+CURLcode Curl_is_connected(struct connectdata *conn,
+ int sockindex,
+ bool *connected)
+{
+ struct SessionHandle *data = conn->data;
+ CURLcode result = CURLE_OK;
+ long allow;
+ int error = 0;
+ struct timeval now;
+ int rc;
+ int i;
+
+ DEBUGASSERT(sockindex >= FIRSTSOCKET && sockindex <= SECONDARYSOCKET);
+
+ *connected = FALSE; /* a very negative world view is best */
+
+ if(conn->bits.tcpconnect[sockindex]) {
+ /* we are connected already! */
+ *connected = TRUE;
+ return CURLE_OK;
+ }
+
+ now = Curl_tvnow();
+
+ /* figure out how long time we have left to connect */
+ allow = Curl_timeleft(data, &now, TRUE);
+
+ if(allow < 0) {
+ /* time-out, bail out, go home */
+ failf(data, "Connection time-out");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+
+ for(i=0; i<2; i++) {
+ const int other = i ^ 1;
+ if(conn->tempsock[i] == CURL_SOCKET_BAD)
+ continue;
+
+#ifdef mpeix
+ /* Call this function once now, and ignore the results. We do this to
+ "clear" the error state on the socket so that we can later read it
+ reliably. This is reported necessary on the MPE/iX operating system. */
+ (void)verifyconnect(conn->tempsock[i], NULL);
+#endif
+
+ /* check socket for connect */
+ rc = Curl_socket_ready(CURL_SOCKET_BAD, conn->tempsock[i], 0);
+
+ if(rc == 0) { /* no connection yet */
+ if(curlx_tvdiff(now, conn->connecttime) >= conn->timeoutms_per_addr) {
+ infof(data, "After %ldms connect time, move on!\n",
+ conn->timeoutms_per_addr);
+ error = ETIMEDOUT;
+ }
+
+ /* should we try another protocol family? */
+ if(i == 0 && conn->tempaddr[1] == NULL &&
+ curlx_tvdiff(now, conn->connecttime) >= HAPPY_EYEBALLS_TIMEOUT) {
+ trynextip(conn, sockindex, 1);
+ }
+ }
+ else if(rc == CURL_CSELECT_OUT) {
+ if(verifyconnect(conn->tempsock[i], &error)) {
+ /* we are connected with TCP, awesome! */
+
+ /* use this socket from now on */
+ conn->sock[sockindex] = conn->tempsock[i];
+ conn->ip_addr = conn->tempaddr[i];
+ conn->tempsock[i] = CURL_SOCKET_BAD;
+
+ /* close the other socket, if open */
+ if(conn->tempsock[other] != CURL_SOCKET_BAD) {
+ Curl_closesocket(conn, conn->tempsock[other]);
+ conn->tempsock[other] = CURL_SOCKET_BAD;
+ }
+
+ /* see if we need to do any proxy magic first once we connected */
+ result = Curl_connected_proxy(conn, sockindex);
+ if(result)
+ return result;
+
+ conn->bits.tcpconnect[sockindex] = TRUE;
+
+ *connected = TRUE;
+ if(sockindex == FIRSTSOCKET)
+ Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
+ Curl_updateconninfo(conn, conn->sock[sockindex]);
+ Curl_verboseconnect(conn);
+
+ return CURLE_OK;
+ }
+ else
+ infof(data, "Connection failed\n");
+ }
+ else if(rc & CURL_CSELECT_ERR)
+ (void)verifyconnect(conn->tempsock[i], &error);
+
+ /*
+ * The connection failed here, we should attempt to connect to the "next
+ * address" for the given host. But first remember the latest error.
+ */
+ if(error) {
+ data->state.os_errno = error;
+ SET_SOCKERRNO(error);
+ if(conn->tempaddr[i]) {
+ CURLcode status;
+ char ipaddress[MAX_IPADR_LEN];
+ Curl_printable_address(conn->tempaddr[i], ipaddress, MAX_IPADR_LEN);
+ infof(data, "connect to %s port %ld failed: %s\n",
+ ipaddress, conn->port, Curl_strerror(conn, error));
+
+ conn->timeoutms_per_addr = conn->tempaddr[i]->ai_next == NULL ?
+ allow : allow / 2;
+
+ status = trynextip(conn, sockindex, i);
+ if(status != CURLE_COULDNT_CONNECT
+ || conn->tempsock[other] == CURL_SOCKET_BAD)
+ /* the last attempt failed and no other sockets remain open */
+ result = status;
+ }
+ }
+ }
+
+ if(result) {
+ /* no more addresses to try */
+
+ /* if the first address family runs out of addresses to try before
+ the happy eyeball timeout, go ahead and try the next family now */
+ if(conn->tempaddr[1] == NULL) {
+ result = trynextip(conn, sockindex, 1);
+ if(!result)
+ return result;
+ }
+
+ failf(data, "Failed to connect to %s port %ld: %s",
+ conn->bits.proxy?conn->proxy.name:conn->host.name,
+ conn->port, Curl_strerror(conn, error));
+ }
+
+ return result;
+}
+
+static void tcpnodelay(struct connectdata *conn,
+ curl_socket_t sockfd)
+{
+#ifdef TCP_NODELAY
+ struct SessionHandle *data= conn->data;
+ curl_socklen_t onoff = (curl_socklen_t) data->set.tcp_nodelay;
+ int level = IPPROTO_TCP;
+
+#if 0
+ /* The use of getprotobyname() is disabled since it isn't thread-safe on
+ numerous systems. On these getprotobyname_r() should be used instead, but
+ that exists in at least one 4 arg version and one 5 arg version, and
+ since the proto number rarely changes anyway we now just use the hard
+ coded number. The "proper" fix would need a configure check for the
+ correct function much in the same style the gethostbyname_r versions are
+ detected. */
+ struct protoent *pe = getprotobyname("tcp");
+ if(pe)
+ level = pe->p_proto;
+#endif
+
+ if(setsockopt(sockfd, level, TCP_NODELAY, (void *)&onoff,
+ sizeof(onoff)) < 0)
+ infof(data, "Could not set TCP_NODELAY: %s\n",
+ Curl_strerror(conn, SOCKERRNO));
+ else
+ infof(data, "TCP_NODELAY set\n");
+#else
+ (void)conn;
+ (void)sockfd;
+#endif
+}
+
+#ifdef SO_NOSIGPIPE
+/* The preferred method on Mac OS X (10.2 and later) to prevent SIGPIPEs when
+ sending data to a dead peer (instead of relying on the 4th argument to send
+ being MSG_NOSIGNAL). Possibly also existing and in use on other BSD
+ systems? */
+static void nosigpipe(struct connectdata *conn,
+ curl_socket_t sockfd)
+{
+ struct SessionHandle *data= conn->data;
+ int onoff = 1;
+ if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff,
+ sizeof(onoff)) < 0)
+ infof(data, "Could not set SO_NOSIGPIPE: %s\n",
+ Curl_strerror(conn, SOCKERRNO));
+}
+#else
+#define nosigpipe(x,y) Curl_nop_stmt
+#endif
+
+#ifdef USE_WINSOCK
+/* When you run a program that uses the Windows Sockets API, you may
+ experience slow performance when you copy data to a TCP server.
+
+ http://support.microsoft.com/kb/823764
+
+ Work-around: Make the Socket Send Buffer Size Larger Than the Program Send
+ Buffer Size
+
+ The problem described in this knowledge-base is applied only to pre-Vista
+ Windows. Following function trying to detect OS version and skips
+ SO_SNDBUF adjustment for Windows Vista and above.
+*/
+#define DETECT_OS_NONE 0
+#define DETECT_OS_PREVISTA 1
+#define DETECT_OS_VISTA_OR_LATER 2
+
+void Curl_sndbufset(curl_socket_t sockfd)
+{
+ int val = CURL_MAX_WRITE_SIZE + 32;
+ int curval = 0;
+ int curlen = sizeof(curval);
+ DWORD majorVersion = 6;
+
+ static int detectOsState = DETECT_OS_NONE;
+
+ if(detectOsState == DETECT_OS_NONE) {
+#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_WIN2K) || \
+ (_WIN32_WINNT < _WIN32_WINNT_WIN2K)
+ OSVERSIONINFO osver;
+
+ memset(&osver, 0, sizeof(osver));
+ osver.dwOSVersionInfoSize = sizeof(osver);
+
+ detectOsState = DETECT_OS_PREVISTA;
+ if(GetVersionEx(&osver)) {
+ if(osver.dwMajorVersion >= majorVersion)
+ detectOsState = DETECT_OS_VISTA_OR_LATER;
+ }
+#else
+ ULONGLONG cm;
+ OSVERSIONINFOEX osver;
+
+ memset(&osver, 0, sizeof(osver));
+ osver.dwOSVersionInfoSize = sizeof(osver);
+ osver.dwMajorVersion = majorVersion;
+
+ cm = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
+ cm = VerSetConditionMask(cm, VER_MINORVERSION, VER_GREATER_EQUAL);
+ cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
+ cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL);
+
+ if(VerifyVersionInfo(&osver, (VER_MAJORVERSION | VER_MINORVERSION |
+ VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR),
+ cm))
+ detectOsState = DETECT_OS_VISTA_OR_LATER;
+ else
+ detectOsState = DETECT_OS_PREVISTA;
+#endif
+ }
+
+ if(detectOsState == DETECT_OS_VISTA_OR_LATER)
+ return;
+
+ if(getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&curval, &curlen) == 0)
+ if(curval > val)
+ return;
+
+ setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (const char *)&val, sizeof(val));
+}
+#endif
+
+/*
+ * singleipconnect()
+ *
+ * Note that even on connect fail it returns CURLE_OK, but with 'sock' set to
+ * CURL_SOCKET_BAD. Other errors will however return proper errors.
+ *
+ * singleipconnect() connects to the given IP only, and it may return without
+ * having connected.
+ */
+static CURLcode singleipconnect(struct connectdata *conn,
+ const Curl_addrinfo *ai,
+ curl_socket_t *sockp)
+{
+ struct Curl_sockaddr_ex addr;
+ int rc;
+ int error = 0;
+ bool isconnected = FALSE;
+ struct SessionHandle *data = conn->data;
+ curl_socket_t sockfd;
+ CURLcode result;
+ char ipaddress[MAX_IPADR_LEN];
+ long port;
+ bool is_tcp;
+
+ *sockp = CURL_SOCKET_BAD;
+
+ result = Curl_socket(conn, ai, &addr, &sockfd);
+ if(result)
+ /* Failed to create the socket, but still return OK since we signal the
+ lack of socket as well. This allows the parent function to keep looping
+ over alternative addresses/socket families etc. */
+ return CURLE_OK;
+
+ /* store remote address and port used in this connection attempt */
+ if(!getaddressinfo((struct sockaddr*)&addr.sa_addr,
+ ipaddress, &port)) {
+ /* malformed address or bug in inet_ntop, try next address */
+ error = ERRNO;
+ failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
+ error, Curl_strerror(conn, error));
+ Curl_closesocket(conn, sockfd);
+ return CURLE_OK;
+ }
+ infof(data, " Trying %s...\n", ipaddress);
+
+#ifdef ENABLE_IPV6
+ is_tcp = (addr.family == AF_INET || addr.family == AF_INET6) &&
+ addr.socktype == SOCK_STREAM;
+#else
+ is_tcp = (addr.family == AF_INET) && addr.socktype == SOCK_STREAM;
+#endif
+ if(is_tcp && data->set.tcp_nodelay)
+ tcpnodelay(conn, sockfd);
+
+ nosigpipe(conn, sockfd);
+
+ Curl_sndbufset(sockfd);
+
+ if(is_tcp && data->set.tcp_keepalive)
+ tcpkeepalive(data, sockfd);
+
+ if(data->set.fsockopt) {
+ /* activate callback for setting socket options */
+ error = data->set.fsockopt(data->set.sockopt_client,
+ sockfd,
+ CURLSOCKTYPE_IPCXN);
+
+ if(error == CURL_SOCKOPT_ALREADY_CONNECTED)
+ isconnected = TRUE;
+ else if(error) {
+ Curl_closesocket(conn, sockfd); /* close the socket and bail out */
+ return CURLE_ABORTED_BY_CALLBACK;
+ }
+ }
+
+ /* possibly bind the local end to an IP, interface or port */
+ if(addr.family == AF_INET
+#ifdef ENABLE_IPV6
+ || addr.family == AF_INET6
+#endif
+ ) {
+ result = bindlocal(conn, sockfd, addr.family,
+ Curl_ipv6_scope((struct sockaddr*)&addr.sa_addr));
+ if(result) {
+ Curl_closesocket(conn, sockfd); /* close socket and bail out */
+ if(result == CURLE_UNSUPPORTED_PROTOCOL) {
+ /* The address family is not supported on this interface.
+ We can continue trying addresses */
+ return CURLE_COULDNT_CONNECT;
+ }
+ return result;
+ }
+ }
+
+ /* set socket non-blocking */
+ (void)curlx_nonblock(sockfd, TRUE);
+
+ conn->connecttime = Curl_tvnow();
+ if(conn->num_addr > 1)
+ Curl_expire_latest(data, conn->timeoutms_per_addr);
+
+ /* Connect TCP sockets, bind UDP */
+ if(!isconnected && (conn->socktype == SOCK_STREAM)) {
+ rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
+ if(-1 == rc)
+ error = SOCKERRNO;
+ }
+ else {
+ *sockp = sockfd;
+ return CURLE_OK;
+ }
+
+#ifdef ENABLE_IPV6
+ conn->bits.ipv6 = (addr.family == AF_INET6)?TRUE:FALSE;
+#endif
+
+ if(-1 == rc) {
+ switch(error) {
+ case EINPROGRESS:
+ case EWOULDBLOCK:
+#if defined(EAGAIN)
+#if (EAGAIN) != (EWOULDBLOCK)
+ /* On some platforms EAGAIN and EWOULDBLOCK are the
+ * same value, and on others they are different, hence
+ * the odd #if
+ */
+ case EAGAIN:
+#endif
+#endif
+ result = CURLE_OK;
+ break;
+
+ default:
+ /* unknown error, fallthrough and try another address! */
+ infof(data, "Immediate connect fail for %s: %s\n",
+ ipaddress, Curl_strerror(conn, error));
+ data->state.os_errno = error;
+
+ /* connect failed */
+ Curl_closesocket(conn, sockfd);
+ result = CURLE_COULDNT_CONNECT;
+ }
+ }
+
+ if(!result)
+ *sockp = sockfd;
+
+ return result;
+}
+
+/*
+ * TCP connect to the given host with timeout, proxy or remote doesn't matter.
+ * There might be more than one IP address to try out. Fill in the passed
+ * pointer with the connected socket.
+ */
+
+CURLcode Curl_connecthost(struct connectdata *conn, /* context */
+ const struct Curl_dns_entry *remotehost)
+{
+ struct SessionHandle *data = conn->data;
+ struct timeval before = Curl_tvnow();
+ CURLcode result = CURLE_COULDNT_CONNECT;
+
+ long timeout_ms = Curl_timeleft(data, &before, TRUE);
+
+ if(timeout_ms < 0) {
+ /* a precaution, no need to continue if time already is up */
+ failf(data, "Connection time-out");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+
+ conn->num_addr = Curl_num_addresses(remotehost->addr);
+ conn->tempaddr[0] = remotehost->addr;
+ conn->tempaddr[1] = NULL;
+ conn->tempsock[0] = CURL_SOCKET_BAD;
+ conn->tempsock[1] = CURL_SOCKET_BAD;
+ Curl_expire(conn->data, HAPPY_EYEBALLS_TIMEOUT);
+
+ /* Max time for the next connection attempt */
+ conn->timeoutms_per_addr =
+ conn->tempaddr[0]->ai_next == NULL ? timeout_ms : timeout_ms / 2;
+
+ /* start connecting to first IP */
+ while(conn->tempaddr[0]) {
+ result = singleipconnect(conn, conn->tempaddr[0], &(conn->tempsock[0]));
+ if(!result)
+ break;
+ conn->tempaddr[0] = conn->tempaddr[0]->ai_next;
+ }
+
+ if(conn->tempsock[0] == CURL_SOCKET_BAD) {
+ if(!result)
+ result = CURLE_COULDNT_CONNECT;
+ return result;
+ }
+
+ data->info.numconnects++; /* to track the number of connections made */
+
+ return CURLE_OK;
+}
+
+struct connfind {
+ struct connectdata *tofind;
+ bool found;
+};
+
+static int conn_is_conn(struct connectdata *conn, void *param)
+{
+ struct connfind *f = (struct connfind *)param;
+ if(conn == f->tofind) {
+ f->found = TRUE;
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Used to extract socket and connectdata struct for the most recent
+ * transfer on the given SessionHandle.
+ *
+ * The returned socket will be CURL_SOCKET_BAD in case of failure!
+ */
+curl_socket_t Curl_getconnectinfo(struct SessionHandle *data,
+ struct connectdata **connp)
+{
+ curl_socket_t sockfd;
+
+ DEBUGASSERT(data);
+
+ /* this works for an easy handle:
+ * - that has been used for curl_easy_perform()
+ * - that is associated with a multi handle, and whose connection
+ * was detached with CURLOPT_CONNECT_ONLY
+ */
+ if(data->state.lastconnect && (data->multi_easy || data->multi)) {
+ struct connectdata *c = data->state.lastconnect;
+ struct connfind find;
+ find.tofind = data->state.lastconnect;
+ find.found = FALSE;
+
+ Curl_conncache_foreach(data->multi_easy?
+ &data->multi_easy->conn_cache:
+ &data->multi->conn_cache, &find, conn_is_conn);
+
+ if(!find.found) {
+ data->state.lastconnect = NULL;
+ return CURL_SOCKET_BAD;
+ }
+
+ if(connp)
+ /* only store this if the caller cares for it */
+ *connp = c;
+ sockfd = c->sock[FIRSTSOCKET];
+ /* we have a socket connected, let's determine if the server shut down */
+ /* determine if ssl */
+ if(c->ssl[FIRSTSOCKET].use) {
+ /* use the SSL context */
+ if(!Curl_ssl_check_cxn(c))
+ return CURL_SOCKET_BAD; /* FIN received */
+ }
+/* Minix 3.1 doesn't support any flags on recv; just assume socket is OK */
+#ifdef MSG_PEEK
+ else {
+ /* use the socket */
+ char buf;
+ if(recv((RECV_TYPE_ARG1)c->sock[FIRSTSOCKET], (RECV_TYPE_ARG2)&buf,
+ (RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK) == 0) {
+ return CURL_SOCKET_BAD; /* FIN received */
+ }
+ }
+#endif
+ }
+ else
+ return CURL_SOCKET_BAD;
+
+ return sockfd;
+}
+
+/*
+ * Close a socket.
+ *
+ * 'conn' can be NULL, beware!
+ */
+int Curl_closesocket(struct connectdata *conn,
+ curl_socket_t sock)
+{
+ if(conn && conn->fclosesocket) {
+ if((sock == conn->sock[SECONDARYSOCKET]) &&
+ conn->sock_accepted[SECONDARYSOCKET])
+ /* if this socket matches the second socket, and that was created with
+ accept, then we MUST NOT call the callback but clear the accepted
+ status */
+ conn->sock_accepted[SECONDARYSOCKET] = FALSE;
+ else {
+ Curl_multi_closed(conn, sock);
+ return conn->fclosesocket(conn->closesocket_client, sock);
+ }
+ }
+
+ if(conn)
+ /* tell the multi-socket code about this */
+ Curl_multi_closed(conn, sock);
+
+ sclose(sock);
+
+ return 0;
+}
+
+/*
+ * Create a socket based on info from 'conn' and 'ai'.
+ *
+ * 'addr' should be a pointer to the correct struct to get data back, or NULL.
+ * 'sockfd' must be a pointer to a socket descriptor.
+ *
+ * If the open socket callback is set, used that!
+ *
+ */
+CURLcode Curl_socket(struct connectdata *conn,
+ const Curl_addrinfo *ai,
+ struct Curl_sockaddr_ex *addr,
+ curl_socket_t *sockfd)
+{
+ struct SessionHandle *data = conn->data;
+ struct Curl_sockaddr_ex dummy;
+
+ if(!addr)
+ /* if the caller doesn't want info back, use a local temp copy */
+ addr = &dummy;
+
+ /*
+ * The Curl_sockaddr_ex structure is basically libcurl's external API
+ * curl_sockaddr structure with enough space available to directly hold
+ * any protocol-specific address structures. The variable declared here
+ * will be used to pass / receive data to/from the fopensocket callback
+ * if this has been set, before that, it is initialized from parameters.
+ */
+
+ addr->family = ai->ai_family;
+ addr->socktype = conn->socktype;
+ addr->protocol = conn->socktype==SOCK_DGRAM?IPPROTO_UDP:ai->ai_protocol;
+ addr->addrlen = ai->ai_addrlen;
+
+ if(addr->addrlen > sizeof(struct Curl_sockaddr_storage))
+ addr->addrlen = sizeof(struct Curl_sockaddr_storage);
+ memcpy(&addr->sa_addr, ai->ai_addr, addr->addrlen);
+
+ if(data->set.fopensocket)
+ /*
+ * If the opensocket callback is set, all the destination address
+ * information is passed to the callback. Depending on this information the
+ * callback may opt to abort the connection, this is indicated returning
+ * CURL_SOCKET_BAD; otherwise it will return a not-connected socket. When
+ * the callback returns a valid socket the destination address information
+ * might have been changed and this 'new' address will actually be used
+ * here to connect.
+ */
+ *sockfd = data->set.fopensocket(data->set.opensocket_client,
+ CURLSOCKTYPE_IPCXN,
+ (struct curl_sockaddr *)addr);
+ else
+ /* opensocket callback not set, so simply create the socket now */
+ *sockfd = socket(addr->family, addr->socktype, addr->protocol);
+
+ if(*sockfd == CURL_SOCKET_BAD)
+ /* no socket, no connection */
+ return CURLE_COULDNT_CONNECT;
+
+#if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
+ if(conn->scope_id && (addr->family == AF_INET6)) {
+ struct sockaddr_in6 * const sa6 = (void *)&addr->sa_addr;
+ sa6->sin6_scope_id = conn->scope_id;
+ }
+#endif
+
+ return CURLE_OK;
+
+}
+
+#ifdef CURLDEBUG
+/*
+ * Curl_conncontrol() is used to set the conn->bits.close bit on or off. It
+ * MUST be called with the connclose() or connkeep() macros with a stated
+ * reason. The reason is only shown in debug builds but helps to figure out
+ * decision paths when connections are or aren't re-used as expected.
+ */
+void Curl_conncontrol(struct connectdata *conn, bool closeit,
+ const char *reason)
+{
+#if defined(CURL_DISABLE_VERBOSE_STRINGS)
+ (void) reason;
+#endif
+ if(closeit != conn->bits.close) {
+ infof(conn->data, "Marked for [%s]: %s\n", closeit?"closure":"keep alive",
+ reason);
+
+ conn->bits.close = closeit; /* the only place in the source code that
+ should assign this bit */
+ }
+}
+#endif
diff --git a/Utilities/cmcurl/lib/connect.h b/Utilities/cmcurl/lib/connect.h
new file mode 100644
index 000000000..91646c75e
--- /dev/null
+++ b/Utilities/cmcurl/lib/connect.h
@@ -0,0 +1,122 @@
+#ifndef HEADER_CURL_CONNECT_H
+#define HEADER_CURL_CONNECT_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#include "nonblock.h" /* for curlx_nonblock(), formerly Curl_nonblock() */
+#include "sockaddr.h"
+
+CURLcode Curl_is_connected(struct connectdata *conn,
+ int sockindex,
+ bool *connected);
+
+CURLcode Curl_connecthost(struct connectdata *conn,
+ const struct Curl_dns_entry *host);
+
+/* generic function that returns how much time there's left to run, according
+ to the timeouts set */
+long Curl_timeleft(struct SessionHandle *data,
+ struct timeval *nowp,
+ bool duringconnect);
+
+#define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */
+#define HAPPY_EYEBALLS_TIMEOUT 200 /* milliseconds to wait between
+ IPv4/IPv6 connection attempts */
+
+/*
+ * Used to extract socket and connectdata struct for the most recent
+ * transfer on the given SessionHandle.
+ *
+ * The returned socket will be CURL_SOCKET_BAD in case of failure!
+ */
+curl_socket_t Curl_getconnectinfo(struct SessionHandle *data,
+ struct connectdata **connp);
+
+#ifdef USE_WINSOCK
+/* When you run a program that uses the Windows Sockets API, you may
+ experience slow performance when you copy data to a TCP server.
+
+ http://support.microsoft.com/kb/823764
+
+ Work-around: Make the Socket Send Buffer Size Larger Than the Program Send
+ Buffer Size
+
+*/
+void Curl_sndbufset(curl_socket_t sockfd);
+#else
+#define Curl_sndbufset(y) Curl_nop_stmt
+#endif
+
+void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd);
+void Curl_persistconninfo(struct connectdata *conn);
+int Curl_closesocket(struct connectdata *conn, curl_socket_t sock);
+
+/*
+ * The Curl_sockaddr_ex structure is basically libcurl's external API
+ * curl_sockaddr structure with enough space available to directly hold any
+ * protocol-specific address structures. The variable declared here will be
+ * used to pass / receive data to/from the fopensocket callback if this has
+ * been set, before that, it is initialized from parameters.
+ */
+struct Curl_sockaddr_ex {
+ int family;
+ int socktype;
+ int protocol;
+ unsigned int addrlen;
+ union {
+ struct sockaddr addr;
+ struct Curl_sockaddr_storage buff;
+ } _sa_ex_u;
+};
+#define sa_addr _sa_ex_u.addr
+
+/*
+ * Create a socket based on info from 'conn' and 'ai'.
+ *
+ * Fill in 'addr' and 'sockfd' accordingly if OK is returned. If the open
+ * socket callback is set, used that!
+ *
+ */
+CURLcode Curl_socket(struct connectdata *conn,
+ const Curl_addrinfo *ai,
+ struct Curl_sockaddr_ex *addr,
+ curl_socket_t *sockfd);
+
+#ifdef CURLDEBUG
+/*
+ * Curl_connclose() sets the bit.close bit to TRUE with an explanation.
+ * Nothing else.
+ */
+void Curl_conncontrol(struct connectdata *conn,
+ bool closeit,
+ const char *reason);
+#define connclose(x,y) Curl_conncontrol(x,TRUE, y)
+#define connkeep(x,y) Curl_conncontrol(x, FALSE, y)
+#else /* if !CURLDEBUG */
+
+#define connclose(x,y) (x)->bits.close = TRUE
+#define connkeep(x,y) (x)->bits.close = FALSE
+
+#endif
+
+#endif /* HEADER_CURL_CONNECT_H */
diff --git a/Utilities/cmcurl/lib/content_encoding.c b/Utilities/cmcurl/lib/content_encoding.c
new file mode 100644
index 000000000..c68e6e5f5
--- /dev/null
+++ b/Utilities/cmcurl/lib/content_encoding.c
@@ -0,0 +1,435 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_LIBZ
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "sendf.h"
+#include "content_encoding.h"
+#include "curl_memory.h"
+
+#include "memdebug.h"
+
+/* Comment this out if zlib is always going to be at least ver. 1.2.0.4
+ (doing so will reduce code size slightly). */
+#define OLD_ZLIB_SUPPORT 1
+
+#define DSIZ CURL_MAX_WRITE_SIZE /* buffer size for decompressed data */
+
+#define GZIP_MAGIC_0 0x1f
+#define GZIP_MAGIC_1 0x8b
+
+/* gzip flag byte */
+#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
+#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
+#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
+#define COMMENT 0x10 /* bit 4 set: file comment present */
+#define RESERVED 0xE0 /* bits 5..7: reserved */
+
+static voidpf
+zalloc_cb(voidpf opaque, unsigned int items, unsigned int size)
+{
+ (void) opaque;
+ /* not a typo, keep it calloc() */
+ return (voidpf) calloc(items, size);
+}
+
+static void
+zfree_cb(voidpf opaque, voidpf ptr)
+{
+ (void) opaque;
+ free(ptr);
+}
+
+static CURLcode
+process_zlib_error(struct connectdata *conn, z_stream *z)
+{
+ struct SessionHandle *data = conn->data;
+ if(z->msg)
+ failf (data, "Error while processing content unencoding: %s",
+ z->msg);
+ else
+ failf (data, "Error while processing content unencoding: "
+ "Unknown failure within decompression software.");
+
+ return CURLE_BAD_CONTENT_ENCODING;
+}
+
+static CURLcode
+exit_zlib(z_stream *z, zlibInitState *zlib_init, CURLcode result)
+{
+ inflateEnd(z);
+ *zlib_init = ZLIB_UNINIT;
+ return result;
+}
+
+static CURLcode
+inflate_stream(struct connectdata *conn,
+ struct SingleRequest *k)
+{
+ int allow_restart = 1;
+ z_stream *z = &k->z; /* zlib state structure */
+ uInt nread = z->avail_in;
+ Bytef *orig_in = z->next_in;
+ int status; /* zlib status */
+ CURLcode result = CURLE_OK; /* Curl_client_write status */
+ char *decomp; /* Put the decompressed data here. */
+
+ /* Dynamically allocate a buffer for decompression because it's uncommonly
+ large to hold on the stack */
+ decomp = malloc(DSIZ);
+ if(decomp == NULL) {
+ return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY);
+ }
+
+ /* because the buffer size is fixed, iteratively decompress and transfer to
+ the client via client_write. */
+ for(;;) {
+ /* (re)set buffer for decompressed output for every iteration */
+ z->next_out = (Bytef *)decomp;
+ z->avail_out = DSIZ;
+
+ status = inflate(z, Z_SYNC_FLUSH);
+ if(status == Z_OK || status == Z_STREAM_END) {
+ allow_restart = 0;
+ if((DSIZ - z->avail_out) && (!k->ignorebody)) {
+ result = Curl_client_write(conn, CLIENTWRITE_BODY, decomp,
+ DSIZ - z->avail_out);
+ /* if !CURLE_OK, clean up, return */
+ if(result) {
+ free(decomp);
+ return exit_zlib(z, &k->zlib_init, result);
+ }
+ }
+
+ /* Done? clean up, return */
+ if(status == Z_STREAM_END) {
+ free(decomp);
+ if(inflateEnd(z) == Z_OK)
+ return exit_zlib(z, &k->zlib_init, result);
+ else
+ return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
+ }
+
+ /* Done with these bytes, exit */
+
+ /* status is always Z_OK at this point! */
+ if(z->avail_in == 0) {
+ free(decomp);
+ return result;
+ }
+ }
+ else if(allow_restart && status == Z_DATA_ERROR) {
+ /* some servers seem to not generate zlib headers, so this is an attempt
+ to fix and continue anyway */
+
+ (void) inflateEnd(z); /* don't care about the return code */
+ if(inflateInit2(z, -MAX_WBITS) != Z_OK) {
+ free(decomp);
+ return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
+ }
+ z->next_in = orig_in;
+ z->avail_in = nread;
+ allow_restart = 0;
+ continue;
+ }
+ else { /* Error; exit loop, handle below */
+ free(decomp);
+ return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
+ }
+ }
+ /* Will never get here */
+}
+
+CURLcode
+Curl_unencode_deflate_write(struct connectdata *conn,
+ struct SingleRequest *k,
+ ssize_t nread)
+{
+ z_stream *z = &k->z; /* zlib state structure */
+
+ /* Initialize zlib? */
+ if(k->zlib_init == ZLIB_UNINIT) {
+ memset(z, 0, sizeof(z_stream));
+ z->zalloc = (alloc_func)zalloc_cb;
+ z->zfree = (free_func)zfree_cb;
+
+ if(inflateInit(z) != Z_OK)
+ return process_zlib_error(conn, z);
+ k->zlib_init = ZLIB_INIT;
+ }
+
+ /* Set the compressed input when this function is called */
+ z->next_in = (Bytef *)k->str;
+ z->avail_in = (uInt)nread;
+
+ /* Now uncompress the data */
+ return inflate_stream(conn, k);
+}
+
+#ifdef OLD_ZLIB_SUPPORT
+/* Skip over the gzip header */
+static enum {
+ GZIP_OK,
+ GZIP_BAD,
+ GZIP_UNDERFLOW
+} check_gzip_header(unsigned char const *data, ssize_t len, ssize_t *headerlen)
+{
+ int method, flags;
+ const ssize_t totallen = len;
+
+ /* The shortest header is 10 bytes */
+ if(len < 10)
+ return GZIP_UNDERFLOW;
+
+ if((data[0] != GZIP_MAGIC_0) || (data[1] != GZIP_MAGIC_1))
+ return GZIP_BAD;
+
+ method = data[2];
+ flags = data[3];
+
+ if(method != Z_DEFLATED || (flags & RESERVED) != 0) {
+ /* Can't handle this compression method or unknown flag */
+ return GZIP_BAD;
+ }
+
+ /* Skip over time, xflags, OS code and all previous bytes */
+ len -= 10;
+ data += 10;
+
+ if(flags & EXTRA_FIELD) {
+ ssize_t extra_len;
+
+ if(len < 2)
+ return GZIP_UNDERFLOW;
+
+ extra_len = (data[1] << 8) | data[0];
+
+ if(len < (extra_len+2))
+ return GZIP_UNDERFLOW;
+
+ len -= (extra_len + 2);
+ data += (extra_len + 2);
+ }
+
+ if(flags & ORIG_NAME) {
+ /* Skip over NUL-terminated file name */
+ while(len && *data) {
+ --len;
+ ++data;
+ }
+ if(!len || *data)
+ return GZIP_UNDERFLOW;
+
+ /* Skip over the NUL */
+ --len;
+ ++data;
+ }
+
+ if(flags & COMMENT) {
+ /* Skip over NUL-terminated comment */
+ while(len && *data) {
+ --len;
+ ++data;
+ }
+ if(!len || *data)
+ return GZIP_UNDERFLOW;
+
+ /* Skip over the NUL */
+ --len;
+ }
+
+ if(flags & HEAD_CRC) {
+ if(len < 2)
+ return GZIP_UNDERFLOW;
+
+ len -= 2;
+ }
+
+ *headerlen = totallen - len;
+ return GZIP_OK;
+}
+#endif
+
+CURLcode
+Curl_unencode_gzip_write(struct connectdata *conn,
+ struct SingleRequest *k,
+ ssize_t nread)
+{
+ z_stream *z = &k->z; /* zlib state structure */
+
+ /* Initialize zlib? */
+ if(k->zlib_init == ZLIB_UNINIT) {
+ memset(z, 0, sizeof(z_stream));
+ z->zalloc = (alloc_func)zalloc_cb;
+ z->zfree = (free_func)zfree_cb;
+
+ if(strcmp(zlibVersion(), "1.2.0.4") >= 0) {
+ /* zlib ver. >= 1.2.0.4 supports transparent gzip decompressing */
+ if(inflateInit2(z, MAX_WBITS+32) != Z_OK) {
+ return process_zlib_error(conn, z);
+ }
+ k->zlib_init = ZLIB_INIT_GZIP; /* Transparent gzip decompress state */
+ }
+ else {
+ /* we must parse the gzip header ourselves */
+ if(inflateInit2(z, -MAX_WBITS) != Z_OK) {
+ return process_zlib_error(conn, z);
+ }
+ k->zlib_init = ZLIB_INIT; /* Initial call state */
+ }
+ }
+
+ if(k->zlib_init == ZLIB_INIT_GZIP) {
+ /* Let zlib handle the gzip decompression entirely */
+ z->next_in = (Bytef *)k->str;
+ z->avail_in = (uInt)nread;
+ /* Now uncompress the data */
+ return inflate_stream(conn, k);
+ }
+
+#ifndef OLD_ZLIB_SUPPORT
+ /* Support for old zlib versions is compiled away and we are running with
+ an old version, so return an error. */
+ return exit_zlib(z, &k->zlib_init, CURLE_FUNCTION_NOT_FOUND);
+
+#else
+ /* This next mess is to get around the potential case where there isn't
+ * enough data passed in to skip over the gzip header. If that happens, we
+ * malloc a block and copy what we have then wait for the next call. If
+ * there still isn't enough (this is definitely a worst-case scenario), we
+ * make the block bigger, copy the next part in and keep waiting.
+ *
+ * This is only required with zlib versions < 1.2.0.4 as newer versions
+ * can handle the gzip header themselves.
+ */
+
+ switch (k->zlib_init) {
+ /* Skip over gzip header? */
+ case ZLIB_INIT:
+ {
+ /* Initial call state */
+ ssize_t hlen;
+
+ switch (check_gzip_header((unsigned char *)k->str, nread, &hlen)) {
+ case GZIP_OK:
+ z->next_in = (Bytef *)k->str + hlen;
+ z->avail_in = (uInt)(nread - hlen);
+ k->zlib_init = ZLIB_GZIP_INFLATING; /* Inflating stream state */
+ break;
+
+ case GZIP_UNDERFLOW:
+ /* We need more data so we can find the end of the gzip header. It's
+ * possible that the memory block we malloc here will never be freed if
+ * the transfer abruptly aborts after this point. Since it's unlikely
+ * that circumstances will be right for this code path to be followed in
+ * the first place, and it's even more unlikely for a transfer to fail
+ * immediately afterwards, it should seldom be a problem.
+ */
+ z->avail_in = (uInt)nread;
+ z->next_in = malloc(z->avail_in);
+ if(z->next_in == NULL) {
+ return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY);
+ }
+ memcpy(z->next_in, k->str, z->avail_in);
+ k->zlib_init = ZLIB_GZIP_HEADER; /* Need more gzip header data state */
+ /* We don't have any data to inflate yet */
+ return CURLE_OK;
+
+ case GZIP_BAD:
+ default:
+ return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
+ }
+
+ }
+ break;
+
+ case ZLIB_GZIP_HEADER:
+ {
+ /* Need more gzip header data state */
+ ssize_t hlen;
+ unsigned char *oldblock = z->next_in;
+
+ z->avail_in += (uInt)nread;
+ z->next_in = realloc(z->next_in, z->avail_in);
+ if(z->next_in == NULL) {
+ free(oldblock);
+ return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY);
+ }
+ /* Append the new block of data to the previous one */
+ memcpy(z->next_in + z->avail_in - nread, k->str, nread);
+
+ switch (check_gzip_header(z->next_in, z->avail_in, &hlen)) {
+ case GZIP_OK:
+ /* This is the zlib stream data */
+ free(z->next_in);
+ /* Don't point into the malloced block since we just freed it */
+ z->next_in = (Bytef *)k->str + hlen + nread - z->avail_in;
+ z->avail_in = (uInt)(z->avail_in - hlen);
+ k->zlib_init = ZLIB_GZIP_INFLATING; /* Inflating stream state */
+ break;
+
+ case GZIP_UNDERFLOW:
+ /* We still don't have any data to inflate! */
+ return CURLE_OK;
+
+ case GZIP_BAD:
+ default:
+ free(z->next_in);
+ return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
+ }
+
+ }
+ break;
+
+ case ZLIB_GZIP_INFLATING:
+ default:
+ /* Inflating stream state */
+ z->next_in = (Bytef *)k->str;
+ z->avail_in = (uInt)nread;
+ break;
+ }
+
+ if(z->avail_in == 0) {
+ /* We don't have any data to inflate; wait until next time */
+ return CURLE_OK;
+ }
+
+ /* We've parsed the header, now uncompress the data */
+ return inflate_stream(conn, k);
+#endif
+}
+
+void Curl_unencode_cleanup(struct connectdata *conn)
+{
+ struct SessionHandle *data = conn->data;
+ struct SingleRequest *k = &data->req;
+ z_stream *z = &k->z;
+ if(k->zlib_init != ZLIB_UNINIT)
+ (void) exit_zlib(z, &k->zlib_init, CURLE_OK);
+}
+
+#endif /* HAVE_LIBZ */
diff --git a/Utilities/cmcurl/lib/content_encoding.h b/Utilities/cmcurl/lib/content_encoding.h
new file mode 100644
index 000000000..501f6c8ce
--- /dev/null
+++ b/Utilities/cmcurl/lib/content_encoding.h
@@ -0,0 +1,48 @@
+#ifndef HEADER_CURL_CONTENT_ENCODING_H
+#define HEADER_CURL_CONTENT_ENCODING_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+/*
+ * Comma-separated list all supported Content-Encodings ('identity' is implied)
+ */
+#ifdef HAVE_LIBZ
+#define ALL_CONTENT_ENCODINGS "deflate, gzip"
+/* force a cleanup */
+void Curl_unencode_cleanup(struct connectdata *conn);
+#else
+#define ALL_CONTENT_ENCODINGS "identity"
+#define Curl_unencode_cleanup(x) Curl_nop_stmt
+#endif
+
+CURLcode Curl_unencode_deflate_write(struct connectdata *conn,
+ struct SingleRequest *req,
+ ssize_t nread);
+
+CURLcode
+Curl_unencode_gzip_write(struct connectdata *conn,
+ struct SingleRequest *k,
+ ssize_t nread);
+
+
+#endif /* HEADER_CURL_CONTENT_ENCODING_H */
diff --git a/Utilities/cmcurl/lib/cookie.c b/Utilities/cmcurl/lib/cookie.c
new file mode 100644
index 000000000..22730cff4
--- /dev/null
+++ b/Utilities/cmcurl/lib/cookie.c
@@ -0,0 +1,1363 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/***
+
+
+RECEIVING COOKIE INFORMATION
+============================
+
+struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
+ const char *file, struct CookieInfo *inc, bool newsession);
+
+ Inits a cookie struct to store data in a local file. This is always
+ called before any cookies are set.
+
+struct Cookie *Curl_cookie_add(struct SessionHandle *data,
+ struct CookieInfo *c, bool httpheader, char *lineptr,
+ const char *domain, const char *path);
+
+ The 'lineptr' parameter is a full "Set-cookie:" line as
+ received from a server.
+
+ The function need to replace previously stored lines that this new
+ line superceeds.
+
+ It may remove lines that are expired.
+
+ It should return an indication of success/error.
+
+
+SENDING COOKIE INFORMATION
+==========================
+
+struct Cookies *Curl_cookie_getlist(struct CookieInfo *cookie,
+ char *host, char *path, bool secure);
+
+ For a given host and path, return a linked list of cookies that
+ the client should send to the server if used now. The secure
+ boolean informs the cookie if a secure connection is achieved or
+ not.
+
+ It shall only return cookies that haven't expired.
+
+
+Example set of cookies:
+
+ Set-cookie: PRODUCTINFO=webxpress; domain=.fidelity.com; path=/; secure
+ Set-cookie: PERSONALIZE=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
+ domain=.fidelity.com; path=/ftgw; secure
+ Set-cookie: FidHist=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
+ domain=.fidelity.com; path=/; secure
+ Set-cookie: FidOrder=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
+ domain=.fidelity.com; path=/; secure
+ Set-cookie: DisPend=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
+ domain=.fidelity.com; path=/; secure
+ Set-cookie: FidDis=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
+ domain=.fidelity.com; path=/; secure
+ Set-cookie:
+ Session_Key@6791a9e0-901a-11d0-a1c8-9b012c88aa77=none;expires=Monday,
+ 13-Jun-1988 03:04:55 GMT; domain=.fidelity.com; path=/; secure
+****/
+
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
+
+#include "curl_printf.h"
+#include "urldata.h"
+#include "cookie.h"
+#include "strequal.h"
+#include "strtok.h"
+#include "sendf.h"
+#include "slist.h"
+#include "share.h"
+#include "strtoofft.h"
+#include "rawstr.h"
+#include "curl_memrchr.h"
+#include "inet_pton.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+static void freecookie(struct Cookie *co)
+{
+ free(co->expirestr);
+ free(co->domain);
+ free(co->path);
+ free(co->spath);
+ free(co->name);
+ free(co->value);
+ free(co->maxage);
+ free(co->version);
+ free(co);
+}
+
+static bool tailmatch(const char *cooke_domain, const char *hostname)
+{
+ size_t cookie_domain_len = strlen(cooke_domain);
+ size_t hostname_len = strlen(hostname);
+
+ if(hostname_len < cookie_domain_len)
+ return FALSE;
+
+ if(!Curl_raw_equal(cooke_domain, hostname+hostname_len-cookie_domain_len))
+ return FALSE;
+
+ /* A lead char of cookie_domain is not '.'.
+ RFC6265 4.1.2.3. The Domain Attribute says:
+ For example, if the value of the Domain attribute is
+ "example.com", the user agent will include the cookie in the Cookie
+ header when making HTTP requests to example.com, www.example.com, and
+ www.corp.example.com.
+ */
+ if(hostname_len == cookie_domain_len)
+ return TRUE;
+ if('.' == *(hostname + hostname_len - cookie_domain_len - 1))
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ * matching cookie path and url path
+ * RFC6265 5.1.4 Paths and Path-Match
+ */
+static bool pathmatch(const char* cookie_path, const char* request_uri)
+{
+ size_t cookie_path_len;
+ size_t uri_path_len;
+ char* uri_path = NULL;
+ char* pos;
+ bool ret = FALSE;
+
+ /* cookie_path must not have last '/' separator. ex: /sample */
+ cookie_path_len = strlen(cookie_path);
+ if(1 == cookie_path_len) {
+ /* cookie_path must be '/' */
+ return TRUE;
+ }
+
+ uri_path = strdup(request_uri);
+ if(!uri_path)
+ return FALSE;
+ pos = strchr(uri_path, '?');
+ if(pos)
+ *pos = 0x0;
+
+ /* #-fragments are already cut off! */
+ if(0 == strlen(uri_path) || uri_path[0] != '/') {
+ free(uri_path);
+ uri_path = strdup("/");
+ if(!uri_path)
+ return FALSE;
+ }
+
+ /* here, RFC6265 5.1.4 says
+ 4. Output the characters of the uri-path from the first character up
+ to, but not including, the right-most %x2F ("/").
+ but URL path /hoge?fuga=xxx means /hoge/index.cgi?fuga=xxx in some site
+ without redirect.
+ Ignore this algorithm because /hoge is uri path for this case
+ (uri path is not /).
+ */
+
+ uri_path_len = strlen(uri_path);
+
+ if(uri_path_len < cookie_path_len) {
+ ret = FALSE;
+ goto pathmatched;
+ }
+
+ /* not using checkprefix() because matching should be case-sensitive */
+ if(strncmp(cookie_path, uri_path, cookie_path_len)) {
+ ret = FALSE;
+ goto pathmatched;
+ }
+
+ /* The cookie-path and the uri-path are identical. */
+ if(cookie_path_len == uri_path_len) {
+ ret = TRUE;
+ goto pathmatched;
+ }
+
+ /* here, cookie_path_len < url_path_len */
+ if(uri_path[cookie_path_len] == '/') {
+ ret = TRUE;
+ goto pathmatched;
+ }
+
+ ret = FALSE;
+
+pathmatched:
+ free(uri_path);
+ return ret;
+}
+
+/*
+ * cookie path sanitize
+ */
+static char *sanitize_cookie_path(const char *cookie_path)
+{
+ size_t len;
+ char *new_path = strdup(cookie_path);
+ if(!new_path)
+ return NULL;
+
+ /* some stupid site sends path attribute with '"'. */
+ len = strlen(new_path);
+ if(new_path[0] == '\"') {
+ memmove((void *)new_path, (const void *)(new_path + 1), len);
+ len--;
+ }
+ if(len && (new_path[len - 1] == '\"')) {
+ new_path[len - 1] = 0x0;
+ len--;
+ }
+
+ /* RFC6265 5.2.4 The Path Attribute */
+ if(new_path[0] != '/') {
+ /* Let cookie-path be the default-path. */
+ free(new_path);
+ new_path = strdup("/");
+ return new_path;
+ }
+
+ /* convert /hoge/ to /hoge */
+ if(len && new_path[len - 1] == '/') {
+ new_path[len - 1] = 0x0;
+ }
+
+ return new_path;
+}
+
+/*
+ * Load cookies from all given cookie files (CURLOPT_COOKIEFILE).
+ *
+ * NOTE: OOM or cookie parsing failures are ignored.
+ */
+void Curl_cookie_loadfiles(struct SessionHandle *data)
+{
+ struct curl_slist *list = data->change.cookielist;
+ if(list) {
+ Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
+ while(list) {
+ struct CookieInfo *newcookies = Curl_cookie_init(data,
+ list->data,
+ data->cookies,
+ data->set.cookiesession);
+ if(!newcookies)
+ /* Failure may be due to OOM or a bad cookie; both are ignored
+ * but only the first should be
+ */
+ infof(data, "ignoring failed cookie_init for %s\n", list->data);
+ else
+ data->cookies = newcookies;
+ list = list->next;
+ }
+ curl_slist_free_all(data->change.cookielist); /* clean up list */
+ data->change.cookielist = NULL; /* don't do this again! */
+ Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
+ }
+}
+
+/*
+ * strstore() makes a strdup() on the 'newstr' and if '*str' is non-NULL
+ * that will be freed before the allocated string is stored there.
+ *
+ * It is meant to easily replace strdup()
+ */
+static void strstore(char **str, const char *newstr)
+{
+ free(*str);
+ *str = strdup(newstr);
+}
+
+/*
+ * remove_expired() removes expired cookies.
+ */
+static void remove_expired(struct CookieInfo *cookies)
+{
+ struct Cookie *co, *nx, *pv;
+ curl_off_t now = (curl_off_t)time(NULL);
+
+ co = cookies->cookies;
+ pv = NULL;
+ while(co) {
+ nx = co->next;
+ if((co->expirestr || co->maxage) && co->expires < now) {
+ if(co == cookies->cookies) {
+ cookies->cookies = co->next;
+ }
+ else {
+ pv->next = co->next;
+ }
+ cookies->numcookies--;
+ freecookie(co);
+ }
+ else {
+ pv = co;
+ }
+ co = nx;
+ }
+}
+
+/*
+ * Return true if the given string is an IP(v4|v6) address.
+ */
+static bool isip(const char *domain)
+{
+ struct in_addr addr;
+#ifdef ENABLE_IPV6
+ struct in6_addr addr6;
+#endif
+
+ if(Curl_inet_pton(AF_INET, domain, &addr)
+#ifdef ENABLE_IPV6
+ || Curl_inet_pton(AF_INET6, domain, &addr6)
+#endif
+ ) {
+ /* domain name given as IP address */
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/****************************************************************************
+ *
+ * Curl_cookie_add()
+ *
+ * Add a single cookie line to the cookie keeping object.
+ *
+ * Be aware that sometimes we get an IP-only host name, and that might also be
+ * a numerical IPv6 address.
+ *
+ * Returns NULL on out of memory or invalid cookie. This is suboptimal,
+ * as they should be treated separately.
+ ***************************************************************************/
+
+struct Cookie *
+Curl_cookie_add(struct SessionHandle *data,
+ /* The 'data' pointer here may be NULL at times, and thus
+ must only be used very carefully for things that can deal
+ with data being NULL. Such as infof() and similar */
+
+ struct CookieInfo *c,
+ bool httpheader, /* TRUE if HTTP header-style line */
+ char *lineptr, /* first character of the line */
+ const char *domain, /* default domain */
+ const char *path) /* full path used when this cookie is set,
+ used to get default path for the cookie
+ unless set */
+{
+ struct Cookie *clist;
+ char name[MAX_NAME];
+ struct Cookie *co;
+ struct Cookie *lastc=NULL;
+ time_t now = time(NULL);
+ bool replace_old = FALSE;
+ bool badcookie = FALSE; /* cookies are good by default. mmmmm yummy */
+
+#ifdef CURL_DISABLE_VERBOSE_STRINGS
+ (void)data;
+#endif
+
+ /* First, alloc and init a new struct for it */
+ co = calloc(1, sizeof(struct Cookie));
+ if(!co)
+ return NULL; /* bail out if we're this low on memory */
+
+ if(httpheader) {
+ /* This line was read off a HTTP-header */
+ const char *ptr;
+ const char *semiptr;
+ char *what;
+
+ what = malloc(MAX_COOKIE_LINE);
+ if(!what) {
+ free(co);
+ return NULL;
+ }
+
+ semiptr=strchr(lineptr, ';'); /* first, find a semicolon */
+
+ while(*lineptr && ISBLANK(*lineptr))
+ lineptr++;
+
+ ptr = lineptr;
+ do {
+ /* we have a <what>=<this> pair or a stand-alone word here */
+ name[0]=what[0]=0; /* init the buffers */
+ if(1 <= sscanf(ptr, "%" MAX_NAME_TXT "[^;\r\n =] =%"
+ MAX_COOKIE_LINE_TXT "[^;\r\n]",
+ name, what)) {
+ /* Use strstore() below to properly deal with received cookie
+ headers that have the same string property set more than once,
+ and then we use the last one. */
+ const char *whatptr;
+ bool done = FALSE;
+ bool sep;
+ size_t len=strlen(what);
+ const char *endofn = &ptr[ strlen(name) ];
+
+ /* skip trailing spaces in name */
+ while(*endofn && ISBLANK(*endofn))
+ endofn++;
+
+ /* name ends with a '=' ? */
+ sep = (*endofn == '=')?TRUE:FALSE;
+
+ /* Strip off trailing whitespace from the 'what' */
+ while(len && ISBLANK(what[len-1])) {
+ what[len-1]=0;
+ len--;
+ }
+
+ /* Skip leading whitespace from the 'what' */
+ whatptr=what;
+ while(*whatptr && ISBLANK(*whatptr))
+ whatptr++;
+
+ if(!len) {
+ /* this was a "<name>=" with no content, and we must allow
+ 'secure' and 'httponly' specified this weirdly */
+ done = TRUE;
+ if(Curl_raw_equal("secure", name))
+ co->secure = TRUE;
+ else if(Curl_raw_equal("httponly", name))
+ co->httponly = TRUE;
+ else if(sep)
+ /* there was a '=' so we're not done parsing this field */
+ done = FALSE;
+ }
+ if(done)
+ ;
+ else if(Curl_raw_equal("path", name)) {
+ strstore(&co->path, whatptr);
+ if(!co->path) {
+ badcookie = TRUE; /* out of memory bad */
+ break;
+ }
+ co->spath = sanitize_cookie_path(co->path);
+ if(!co->spath) {
+ badcookie = TRUE; /* out of memory bad */
+ break;
+ }
+ }
+ else if(Curl_raw_equal("domain", name)) {
+ bool is_ip;
+ const char *dotp;
+
+ /* Now, we make sure that our host is within the given domain,
+ or the given domain is not valid and thus cannot be set. */
+
+ if('.' == whatptr[0])
+ whatptr++; /* ignore preceding dot */
+
+ is_ip = isip(domain ? domain : whatptr);
+
+ /* check for more dots */
+ dotp = strchr(whatptr, '.');
+ if(!dotp)
+ domain=":";
+
+ if(!domain
+ || (is_ip && !strcmp(whatptr, domain))
+ || (!is_ip && tailmatch(whatptr, domain))) {
+ strstore(&co->domain, whatptr);
+ if(!co->domain) {
+ badcookie = TRUE;
+ break;
+ }
+ if(!is_ip)
+ co->tailmatch=TRUE; /* we always do that if the domain name was
+ given */
+ }
+ else {
+ /* we did not get a tailmatch and then the attempted set domain
+ is not a domain to which the current host belongs. Mark as
+ bad. */
+ badcookie=TRUE;
+ infof(data, "skipped cookie with bad tailmatch domain: %s\n",
+ whatptr);
+ }
+ }
+ else if(Curl_raw_equal("version", name)) {
+ strstore(&co->version, whatptr);
+ if(!co->version) {
+ badcookie = TRUE;
+ break;
+ }
+ }
+ else if(Curl_raw_equal("max-age", name)) {
+ /* Defined in RFC2109:
+
+ Optional. The Max-Age attribute defines the lifetime of the
+ cookie, in seconds. The delta-seconds value is a decimal non-
+ negative integer. After delta-seconds seconds elapse, the
+ client should discard the cookie. A value of zero means the
+ cookie should be discarded immediately.
+
+ */
+ strstore(&co->maxage, whatptr);
+ if(!co->maxage) {
+ badcookie = TRUE;
+ break;
+ }
+ }
+ else if(Curl_raw_equal("expires", name)) {
+ strstore(&co->expirestr, whatptr);
+ if(!co->expirestr) {
+ badcookie = TRUE;
+ break;
+ }
+ }
+ else if(!co->name) {
+ co->name = strdup(name);
+ co->value = strdup(whatptr);
+ if(!co->name || !co->value) {
+ badcookie = TRUE;
+ break;
+ }
+ }
+ /*
+ else this is the second (or more) name we don't know
+ about! */
+ }
+ else {
+ /* this is an "illegal" <what>=<this> pair */
+ }
+
+ if(!semiptr || !*semiptr) {
+ /* we already know there are no more cookies */
+ semiptr = NULL;
+ continue;
+ }
+
+ ptr=semiptr+1;
+ while(*ptr && ISBLANK(*ptr))
+ ptr++;
+ semiptr=strchr(ptr, ';'); /* now, find the next semicolon */
+
+ if(!semiptr && *ptr)
+ /* There are no more semicolons, but there's a final name=value pair
+ coming up */
+ semiptr=strchr(ptr, '\0');
+ } while(semiptr);
+
+ if(co->maxage) {
+ co->expires =
+ curlx_strtoofft((*co->maxage=='\"')?
+ &co->maxage[1]:&co->maxage[0], NULL, 10);
+ if(CURL_OFF_T_MAX - now < co->expires)
+ /* avoid overflow */
+ co->expires = CURL_OFF_T_MAX;
+ else
+ co->expires += now;
+ }
+ else if(co->expirestr) {
+ /* Note that if the date couldn't get parsed for whatever reason,
+ the cookie will be treated as a session cookie */
+ co->expires = curl_getdate(co->expirestr, NULL);
+
+ /* Session cookies have expires set to 0 so if we get that back
+ from the date parser let's add a second to make it a
+ non-session cookie */
+ if(co->expires == 0)
+ co->expires = 1;
+ else if(co->expires < 0)
+ co->expires = 0;
+ }
+
+ if(!badcookie && !co->domain) {
+ if(domain) {
+ /* no domain was given in the header line, set the default */
+ co->domain=strdup(domain);
+ if(!co->domain)
+ badcookie = TRUE;
+ }
+ }
+
+ if(!badcookie && !co->path && path) {
+ /* No path was given in the header line, set the default.
+ Note that the passed-in path to this function MAY have a '?' and
+ following part that MUST not be stored as part of the path. */
+ char *queryp = strchr(path, '?');
+
+ /* queryp is where the interesting part of the path ends, so now we
+ want to the find the last */
+ char *endslash;
+ if(!queryp)
+ endslash = strrchr(path, '/');
+ else
+ endslash = memrchr(path, '/', (size_t)(queryp - path));
+ if(endslash) {
+ size_t pathlen = (size_t)(endslash-path+1); /* include ending slash */
+ co->path=malloc(pathlen+1); /* one extra for the zero byte */
+ if(co->path) {
+ memcpy(co->path, path, pathlen);
+ co->path[pathlen]=0; /* zero terminate */
+ co->spath = sanitize_cookie_path(co->path);
+ if(!co->spath)
+ badcookie = TRUE; /* out of memory bad */
+ }
+ else
+ badcookie = TRUE;
+ }
+ }
+
+ free(what);
+
+ if(badcookie || !co->name) {
+ /* we didn't get a cookie name or a bad one,
+ this is an illegal line, bail out */
+ freecookie(co);
+ return NULL;
+ }
+
+ }
+ else {
+ /* This line is NOT a HTTP header style line, we do offer support for
+ reading the odd netscape cookies-file format here */
+ char *ptr;
+ char *firstptr;
+ char *tok_buf=NULL;
+ int fields;
+
+ /* IE introduced HTTP-only cookies to prevent XSS attacks. Cookies
+ marked with httpOnly after the domain name are not accessible
+ from javascripts, but since curl does not operate at javascript
+ level, we include them anyway. In Firefox's cookie files, these
+ lines are preceded with #HttpOnly_ and then everything is
+ as usual, so we skip 10 characters of the line..
+ */
+ if(strncmp(lineptr, "#HttpOnly_", 10) == 0) {
+ lineptr += 10;
+ co->httponly = TRUE;
+ }
+
+ if(lineptr[0]=='#') {
+ /* don't even try the comments */
+ free(co);
+ return NULL;
+ }
+ /* strip off the possible end-of-line characters */
+ ptr=strchr(lineptr, '\r');
+ if(ptr)
+ *ptr=0; /* clear it */
+ ptr=strchr(lineptr, '\n');
+ if(ptr)
+ *ptr=0; /* clear it */
+
+ firstptr=strtok_r(lineptr, "\t", &tok_buf); /* tokenize it on the TAB */
+
+ /* Now loop through the fields and init the struct we already have
+ allocated */
+ for(ptr=firstptr, fields=0; ptr && !badcookie;
+ ptr=strtok_r(NULL, "\t", &tok_buf), fields++) {
+ switch(fields) {
+ case 0:
+ if(ptr[0]=='.') /* skip preceding dots */
+ ptr++;
+ co->domain = strdup(ptr);
+ if(!co->domain)
+ badcookie = TRUE;
+ break;
+ case 1:
+ /* This field got its explanation on the 23rd of May 2001 by
+ Andrés García:
+
+ flag: A TRUE/FALSE value indicating if all machines within a given
+ domain can access the variable. This value is set automatically by
+ the browser, depending on the value you set for the domain.
+
+ As far as I can see, it is set to true when the cookie says
+ .domain.com and to false when the domain is complete www.domain.com
+ */
+ co->tailmatch = Curl_raw_equal(ptr, "TRUE")?TRUE:FALSE;
+ break;
+ case 2:
+ /* It turns out, that sometimes the file format allows the path
+ field to remain not filled in, we try to detect this and work
+ around it! Andrés García made us aware of this... */
+ if(strcmp("TRUE", ptr) && strcmp("FALSE", ptr)) {
+ /* only if the path doesn't look like a boolean option! */
+ co->path = strdup(ptr);
+ if(!co->path)
+ badcookie = TRUE;
+ else {
+ co->spath = sanitize_cookie_path(co->path);
+ if(!co->spath) {
+ badcookie = TRUE; /* out of memory bad */
+ }
+ }
+ break;
+ }
+ /* this doesn't look like a path, make one up! */
+ co->path = strdup("/");
+ if(!co->path)
+ badcookie = TRUE;
+ co->spath = strdup("/");
+ if(!co->spath)
+ badcookie = TRUE;
+ fields++; /* add a field and fall down to secure */
+ /* FALLTHROUGH */
+ case 3:
+ co->secure = Curl_raw_equal(ptr, "TRUE")?TRUE:FALSE;
+ break;
+ case 4:
+ co->expires = curlx_strtoofft(ptr, NULL, 10);
+ break;
+ case 5:
+ co->name = strdup(ptr);
+ if(!co->name)
+ badcookie = TRUE;
+ break;
+ case 6:
+ co->value = strdup(ptr);
+ if(!co->value)
+ badcookie = TRUE;
+ break;
+ }
+ }
+ if(6 == fields) {
+ /* we got a cookie with blank contents, fix it */
+ co->value = strdup("");
+ if(!co->value)
+ badcookie = TRUE;
+ else
+ fields++;
+ }
+
+ if(!badcookie && (7 != fields))
+ /* we did not find the sufficient number of fields */
+ badcookie = TRUE;
+
+ if(badcookie) {
+ freecookie(co);
+ return NULL;
+ }
+
+ }
+
+ if(!c->running && /* read from a file */
+ c->newsession && /* clean session cookies */
+ !co->expires) { /* this is a session cookie since it doesn't expire! */
+ freecookie(co);
+ return NULL;
+ }
+
+ co->livecookie = c->running;
+
+ /* now, we have parsed the incoming line, we must now check if this
+ superceeds an already existing cookie, which it may if the previous have
+ the same domain and path as this */
+
+ /* at first, remove expired cookies */
+ remove_expired(c);
+
+ clist = c->cookies;
+ replace_old = FALSE;
+ while(clist) {
+ if(Curl_raw_equal(clist->name, co->name)) {
+ /* the names are identical */
+
+ if(clist->domain && co->domain) {
+ if(Curl_raw_equal(clist->domain, co->domain))
+ /* The domains are identical */
+ replace_old=TRUE;
+ }
+ else if(!clist->domain && !co->domain)
+ replace_old = TRUE;
+
+ if(replace_old) {
+ /* the domains were identical */
+
+ if(clist->spath && co->spath) {
+ if(Curl_raw_equal(clist->spath, co->spath)) {
+ replace_old = TRUE;
+ }
+ else
+ replace_old = FALSE;
+ }
+ else if(!clist->spath && !co->spath)
+ replace_old = TRUE;
+ else
+ replace_old = FALSE;
+
+ }
+
+ if(replace_old && !co->livecookie && clist->livecookie) {
+ /* Both cookies matched fine, except that the already present
+ cookie is "live", which means it was set from a header, while
+ the new one isn't "live" and thus only read from a file. We let
+ live cookies stay alive */
+
+ /* Free the newcomer and get out of here! */
+ freecookie(co);
+ return NULL;
+ }
+
+ if(replace_old) {
+ co->next = clist->next; /* get the next-pointer first */
+
+ /* then free all the old pointers */
+ free(clist->name);
+ free(clist->value);
+ free(clist->domain);
+ free(clist->path);
+ free(clist->spath);
+ free(clist->expirestr);
+ free(clist->version);
+ free(clist->maxage);
+
+ *clist = *co; /* then store all the new data */
+
+ free(co); /* free the newly alloced memory */
+ co = clist; /* point to the previous struct instead */
+
+ /* We have replaced a cookie, now skip the rest of the list but
+ make sure the 'lastc' pointer is properly set */
+ do {
+ lastc = clist;
+ clist = clist->next;
+ } while(clist);
+ break;
+ }
+ }
+ lastc = clist;
+ clist = clist->next;
+ }
+
+ if(c->running)
+ /* Only show this when NOT reading the cookies from a file */
+ infof(data, "%s cookie %s=\"%s\" for domain %s, path %s, "
+ "expire %" CURL_FORMAT_CURL_OFF_T "\n",
+ replace_old?"Replaced":"Added", co->name, co->value,
+ co->domain, co->path, co->expires);
+
+ if(!replace_old) {
+ /* then make the last item point on this new one */
+ if(lastc)
+ lastc->next = co;
+ else
+ c->cookies = co;
+ c->numcookies++; /* one more cookie in the jar */
+ }
+
+ return co;
+}
+
+/*****************************************************************************
+ *
+ * Curl_cookie_init()
+ *
+ * Inits a cookie struct to read data from a local file. This is always
+ * called before any cookies are set. File may be NULL.
+ *
+ * If 'newsession' is TRUE, discard all "session cookies" on read from file.
+ *
+ * Returns NULL on out of memory. Invalid cookies are ignored.
+ ****************************************************************************/
+struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
+ const char *file,
+ struct CookieInfo *inc,
+ bool newsession)
+{
+ struct CookieInfo *c;
+ FILE *fp = NULL;
+ bool fromfile=TRUE;
+ char *line = NULL;
+
+ if(NULL == inc) {
+ /* we didn't get a struct, create one */
+ c = calloc(1, sizeof(struct CookieInfo));
+ if(!c)
+ return NULL; /* failed to get memory */
+ c->filename = strdup(file?file:"none"); /* copy the name just in case */
+ if(!c->filename)
+ goto fail; /* failed to get memory */
+ }
+ else {
+ /* we got an already existing one, use that */
+ c = inc;
+ }
+ c->running = FALSE; /* this is not running, this is init */
+
+ if(file && strequal(file, "-")) {
+ fp = stdin;
+ fromfile=FALSE;
+ }
+ else if(file && !*file) {
+ /* points to a "" string */
+ fp = NULL;
+ }
+ else
+ fp = file?fopen(file, FOPEN_READTEXT):NULL;
+
+ c->newsession = newsession; /* new session? */
+
+ if(fp) {
+ char *lineptr;
+ bool headerline;
+
+ line = malloc(MAX_COOKIE_LINE);
+ if(!line)
+ goto fail;
+ while(fgets(line, MAX_COOKIE_LINE, fp)) {
+ if(checkprefix("Set-Cookie:", line)) {
+ /* This is a cookie line, get it! */
+ lineptr=&line[11];
+ headerline=TRUE;
+ }
+ else {
+ lineptr=line;
+ headerline=FALSE;
+ }
+ while(*lineptr && ISBLANK(*lineptr))
+ lineptr++;
+
+ Curl_cookie_add(data, c, headerline, lineptr, NULL, NULL);
+ }
+ free(line); /* free the line buffer */
+
+ if(fromfile)
+ fclose(fp);
+ }
+
+ c->running = TRUE; /* now, we're running */
+
+ return c;
+
+fail:
+ free(line);
+ if(!inc)
+ /* Only clean up if we allocated it here, as the original could still be in
+ * use by a share handle */
+ Curl_cookie_cleanup(c);
+ if(fromfile && fp)
+ fclose(fp);
+ return NULL; /* out of memory */
+}
+
+/* sort this so that the longest path gets before the shorter path */
+static int cookie_sort(const void *p1, const void *p2)
+{
+ struct Cookie *c1 = *(struct Cookie **)p1;
+ struct Cookie *c2 = *(struct Cookie **)p2;
+ size_t l1, l2;
+
+ /* 1 - compare cookie path lengths */
+ l1 = c1->path ? strlen(c1->path) : 0;
+ l2 = c2->path ? strlen(c2->path) : 0;
+
+ if(l1 != l2)
+ return (l2 > l1) ? 1 : -1 ; /* avoid size_t <=> int conversions */
+
+ /* 2 - compare cookie domain lengths */
+ l1 = c1->domain ? strlen(c1->domain) : 0;
+ l2 = c2->domain ? strlen(c2->domain) : 0;
+
+ if(l1 != l2)
+ return (l2 > l1) ? 1 : -1 ; /* avoid size_t <=> int conversions */
+
+ /* 3 - compare cookie names */
+ if(c1->name && c2->name)
+ return strcmp(c1->name, c2->name);
+
+ /* sorry, can't be more deterministic */
+ return 0;
+}
+
+/*****************************************************************************
+ *
+ * Curl_cookie_getlist()
+ *
+ * For a given host and path, return a linked list of cookies that the
+ * client should send to the server if used now. The secure boolean informs
+ * the cookie if a secure connection is achieved or not.
+ *
+ * It shall only return cookies that haven't expired.
+ *
+ ****************************************************************************/
+
+struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
+ const char *host, const char *path,
+ bool secure)
+{
+ struct Cookie *newco;
+ struct Cookie *co;
+ time_t now = time(NULL);
+ struct Cookie *mainco=NULL;
+ size_t matches = 0;
+ bool is_ip;
+
+ if(!c || !c->cookies)
+ return NULL; /* no cookie struct or no cookies in the struct */
+
+ /* at first, remove expired cookies */
+ remove_expired(c);
+
+ /* check if host is an IP(v4|v6) address */
+ is_ip = isip(host);
+
+ co = c->cookies;
+
+ while(co) {
+ /* only process this cookie if it is not expired or had no expire
+ date AND that if the cookie requires we're secure we must only
+ continue if we are! */
+ if((!co->expires || (co->expires > now)) &&
+ (co->secure?secure:TRUE)) {
+
+ /* now check if the domain is correct */
+ if(!co->domain ||
+ (co->tailmatch && !is_ip && tailmatch(co->domain, host)) ||
+ ((!co->tailmatch || is_ip) && Curl_raw_equal(host, co->domain)) ) {
+ /* the right part of the host matches the domain stuff in the
+ cookie data */
+
+ /* now check the left part of the path with the cookies path
+ requirement */
+ if(!co->spath || pathmatch(co->spath, path) ) {
+
+ /* and now, we know this is a match and we should create an
+ entry for the return-linked-list */
+
+ newco = malloc(sizeof(struct Cookie));
+ if(newco) {
+ /* first, copy the whole source cookie: */
+ memcpy(newco, co, sizeof(struct Cookie));
+
+ /* then modify our next */
+ newco->next = mainco;
+
+ /* point the main to us */
+ mainco = newco;
+
+ matches++;
+ }
+ else {
+ fail:
+ /* failure, clear up the allocated chain and return NULL */
+ while(mainco) {
+ co = mainco->next;
+ free(mainco);
+ mainco = co;
+ }
+
+ return NULL;
+ }
+ }
+ }
+ }
+ co = co->next;
+ }
+
+ if(matches) {
+ /* Now we need to make sure that if there is a name appearing more than
+ once, the longest specified path version comes first. To make this
+ the swiftest way, we just sort them all based on path length. */
+ struct Cookie **array;
+ size_t i;
+
+ /* alloc an array and store all cookie pointers */
+ array = malloc(sizeof(struct Cookie *) * matches);
+ if(!array)
+ goto fail;
+
+ co = mainco;
+
+ for(i=0; co; co = co->next)
+ array[i++] = co;
+
+ /* now sort the cookie pointers in path length order */
+ qsort(array, matches, sizeof(struct Cookie *), cookie_sort);
+
+ /* remake the linked list order according to the new order */
+
+ mainco = array[0]; /* start here */
+ for(i=0; i<matches-1; i++)
+ array[i]->next = array[i+1];
+ array[matches-1]->next = NULL; /* terminate the list */
+
+ free(array); /* remove the temporary data again */
+ }
+
+ return mainco; /* return the new list */
+}
+
+/*****************************************************************************
+ *
+ * Curl_cookie_clearall()
+ *
+ * Clear all existing cookies and reset the counter.
+ *
+ ****************************************************************************/
+void Curl_cookie_clearall(struct CookieInfo *cookies)
+{
+ if(cookies) {
+ Curl_cookie_freelist(cookies->cookies, TRUE);
+ cookies->cookies = NULL;
+ cookies->numcookies = 0;
+ }
+}
+
+/*****************************************************************************
+ *
+ * Curl_cookie_freelist()
+ *
+ * Free a list of cookies previously returned by Curl_cookie_getlist();
+ *
+ * The 'cookiestoo' argument tells this function whether to just free the
+ * list or actually also free all cookies within the list as well.
+ *
+ ****************************************************************************/
+
+void Curl_cookie_freelist(struct Cookie *co, bool cookiestoo)
+{
+ struct Cookie *next;
+ while(co) {
+ next = co->next;
+ if(cookiestoo)
+ freecookie(co);
+ else
+ free(co); /* we only free the struct since the "members" are all just
+ pointed out in the main cookie list! */
+ co = next;
+ }
+}
+
+
+/*****************************************************************************
+ *
+ * Curl_cookie_clearsess()
+ *
+ * Free all session cookies in the cookies list.
+ *
+ ****************************************************************************/
+void Curl_cookie_clearsess(struct CookieInfo *cookies)
+{
+ struct Cookie *first, *curr, *next, *prev = NULL;
+
+ if(!cookies || !cookies->cookies)
+ return;
+
+ first = curr = prev = cookies->cookies;
+
+ for(; curr; curr = next) {
+ next = curr->next;
+ if(!curr->expires) {
+ if(first == curr)
+ first = next;
+
+ if(prev == curr)
+ prev = next;
+ else
+ prev->next = next;
+
+ freecookie(curr);
+ cookies->numcookies--;
+ }
+ else
+ prev = curr;
+ }
+
+ cookies->cookies = first;
+}
+
+
+/*****************************************************************************
+ *
+ * Curl_cookie_cleanup()
+ *
+ * Free a "cookie object" previous created with Curl_cookie_init().
+ *
+ ****************************************************************************/
+void Curl_cookie_cleanup(struct CookieInfo *c)
+{
+ if(c) {
+ free(c->filename);
+ Curl_cookie_freelist(c->cookies, TRUE);
+ free(c); /* free the base struct as well */
+ }
+}
+
+/* get_netscape_format()
+ *
+ * Formats a string for Netscape output file, w/o a newline at the end.
+ *
+ * Function returns a char * to a formatted line. Has to be free()d
+*/
+static char *get_netscape_format(const struct Cookie *co)
+{
+ return aprintf(
+ "%s" /* httponly preamble */
+ "%s%s\t" /* domain */
+ "%s\t" /* tailmatch */
+ "%s\t" /* path */
+ "%s\t" /* secure */
+ "%" CURL_FORMAT_CURL_OFF_T "\t" /* expires */
+ "%s\t" /* name */
+ "%s", /* value */
+ co->httponly?"#HttpOnly_":"",
+ /* Make sure all domains are prefixed with a dot if they allow
+ tailmatching. This is Mozilla-style. */
+ (co->tailmatch && co->domain && co->domain[0] != '.')? ".":"",
+ co->domain?co->domain:"unknown",
+ co->tailmatch?"TRUE":"FALSE",
+ co->path?co->path:"/",
+ co->secure?"TRUE":"FALSE",
+ co->expires,
+ co->name,
+ co->value?co->value:"");
+}
+
+/*
+ * cookie_output()
+ *
+ * Writes all internally known cookies to the specified file. Specify
+ * "-" as file name to write to stdout.
+ *
+ * The function returns non-zero on write failure.
+ */
+static int cookie_output(struct CookieInfo *c, const char *dumphere)
+{
+ struct Cookie *co;
+ FILE *out;
+ bool use_stdout=FALSE;
+
+ if((NULL == c) || (0 == c->numcookies))
+ /* If there are no known cookies, we don't write or even create any
+ destination file */
+ return 0;
+
+ /* at first, remove expired cookies */
+ remove_expired(c);
+
+ if(strequal("-", dumphere)) {
+ /* use stdout */
+ out = stdout;
+ use_stdout=TRUE;
+ }
+ else {
+ out = fopen(dumphere, FOPEN_WRITETEXT);
+ if(!out)
+ return 1; /* failure */
+ }
+
+ if(c) {
+ char *format_ptr;
+
+ fputs("# Netscape HTTP Cookie File\n"
+ "# http://curl.haxx.se/docs/http-cookies.html\n"
+ "# This file was generated by libcurl! Edit at your own risk.\n\n",
+ out);
+
+ for(co = c->cookies; co; co = co->next) {
+ if(!co->domain)
+ continue;
+ format_ptr = get_netscape_format(co);
+ if(format_ptr == NULL) {
+ fprintf(out, "#\n# Fatal libcurl error\n");
+ if(!use_stdout)
+ fclose(out);
+ return 1;
+ }
+ fprintf(out, "%s\n", format_ptr);
+ free(format_ptr);
+ }
+ }
+
+ if(!use_stdout)
+ fclose(out);
+
+ return 0;
+}
+
+struct curl_slist *Curl_cookie_list(struct SessionHandle *data)
+{
+ struct curl_slist *list = NULL;
+ struct curl_slist *beg;
+ struct Cookie *c;
+ char *line;
+
+ if((data->cookies == NULL) ||
+ (data->cookies->numcookies == 0))
+ return NULL;
+
+ for(c = data->cookies->cookies; c; c = c->next) {
+ if(!c->domain)
+ continue;
+ line = get_netscape_format(c);
+ if(!line) {
+ curl_slist_free_all(list);
+ return NULL;
+ }
+ beg = Curl_slist_append_nodup(list, line);
+ if(!beg) {
+ free(line);
+ curl_slist_free_all(list);
+ return NULL;
+ }
+ list = beg;
+ }
+
+ return list;
+}
+
+void Curl_flush_cookies(struct SessionHandle *data, int cleanup)
+{
+ if(data->set.str[STRING_COOKIEJAR]) {
+ if(data->change.cookielist) {
+ /* If there is a list of cookie files to read, do it first so that
+ we have all the told files read before we write the new jar.
+ Curl_cookie_loadfiles() LOCKS and UNLOCKS the share itself! */
+ Curl_cookie_loadfiles(data);
+ }
+
+ Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
+
+ /* if we have a destination file for all the cookies to get dumped to */
+ if(cookie_output(data->cookies, data->set.str[STRING_COOKIEJAR]))
+ infof(data, "WARNING: failed to save cookies in %s\n",
+ data->set.str[STRING_COOKIEJAR]);
+ }
+ else {
+ if(cleanup && data->change.cookielist) {
+ /* since nothing is written, we can just free the list of cookie file
+ names */
+ curl_slist_free_all(data->change.cookielist); /* clean up list */
+ data->change.cookielist = NULL;
+ }
+ Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
+ }
+
+ if(cleanup && (!data->share || (data->cookies != data->share->cookies))) {
+ Curl_cookie_cleanup(data->cookies);
+ }
+ Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
+}
+
+#endif /* CURL_DISABLE_HTTP || CURL_DISABLE_COOKIES */
diff --git a/Utilities/cmcurl/lib/cookie.h b/Utilities/cmcurl/lib/cookie.h
new file mode 100644
index 000000000..bd890827c
--- /dev/null
+++ b/Utilities/cmcurl/lib/cookie.h
@@ -0,0 +1,104 @@
+#ifndef HEADER_CURL_COOKIE_H
+#define HEADER_CURL_COOKIE_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+struct Cookie {
+ struct Cookie *next; /* next in the chain */
+ char *name; /* <this> = value */
+ char *value; /* name = <this> */
+ char *path; /* path = <this> which is in Set-Cookie: */
+ char *spath; /* sanitized cookie path */
+ char *domain; /* domain = <this> */
+ curl_off_t expires; /* expires = <this> */
+ char *expirestr; /* the plain text version */
+ bool tailmatch; /* weather we do tail-matchning of the domain name */
+
+ /* RFC 2109 keywords. Version=1 means 2109-compliant cookie sending */
+ char *version; /* Version = <value> */
+ char *maxage; /* Max-Age = <value> */
+
+ bool secure; /* whether the 'secure' keyword was used */
+ bool livecookie; /* updated from a server, not a stored file */
+ bool httponly; /* true if the httponly directive is present */
+};
+
+struct CookieInfo {
+ /* linked list of cookies we know of */
+ struct Cookie *cookies;
+
+ char *filename; /* file we read from/write to */
+ bool running; /* state info, for cookie adding information */
+ long numcookies; /* number of cookies in the "jar" */
+ bool newsession; /* new session, discard session cookies on load */
+};
+
+/* This is the maximum line length we accept for a cookie line. RFC 2109
+ section 6.3 says:
+
+ "at least 4096 bytes per cookie (as measured by the size of the characters
+ that comprise the cookie non-terminal in the syntax description of the
+ Set-Cookie header)"
+
+*/
+#define MAX_COOKIE_LINE 5000
+#define MAX_COOKIE_LINE_TXT "4999"
+
+/* This is the maximum length of a cookie name we deal with: */
+#define MAX_NAME 1024
+#define MAX_NAME_TXT "1023"
+
+struct SessionHandle;
+/*
+ * Add a cookie to the internal list of cookies. The domain and path arguments
+ * are only used if the header boolean is TRUE.
+ */
+
+struct Cookie *Curl_cookie_add(struct SessionHandle *data,
+ struct CookieInfo *, bool header, char *lineptr,
+ const char *domain, const char *path);
+
+struct Cookie *Curl_cookie_getlist(struct CookieInfo *, const char *,
+ const char *, bool);
+void Curl_cookie_freelist(struct Cookie *cookies, bool cookiestoo);
+void Curl_cookie_clearall(struct CookieInfo *cookies);
+void Curl_cookie_clearsess(struct CookieInfo *cookies);
+
+#if defined(CURL_DISABLE_HTTP) || defined(CURL_DISABLE_COOKIES)
+#define Curl_cookie_list(x) NULL
+#define Curl_cookie_loadfiles(x) Curl_nop_stmt
+#define Curl_cookie_init(x,y,z,w) NULL
+#define Curl_cookie_cleanup(x) Curl_nop_stmt
+#define Curl_flush_cookies(x,y) Curl_nop_stmt
+#else
+void Curl_flush_cookies(struct SessionHandle *data, int cleanup);
+void Curl_cookie_cleanup(struct CookieInfo *);
+struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
+ const char *, struct CookieInfo *, bool);
+struct curl_slist *Curl_cookie_list(struct SessionHandle *data);
+void Curl_cookie_loadfiles(struct SessionHandle *data);
+#endif
+
+#endif /* HEADER_CURL_COOKIE_H */
diff --git a/Utilities/cmcurl/lib/curl_addrinfo.c b/Utilities/cmcurl/lib/curl_addrinfo.c
new file mode 100644
index 000000000..6627a6b96
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_addrinfo.c
@@ -0,0 +1,558 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+# include <sys/un.h>
+#endif
+
+#ifdef __VMS
+# include <in.h>
+# include <inet.h>
+#endif
+
+#if defined(NETWARE) && defined(__NOVELL_LIBC__)
+# undef in_addr_t
+# define in_addr_t unsigned long
+#endif
+
+#include "curl_addrinfo.h"
+#include "inet_pton.h"
+#include "warnless.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ * Curl_freeaddrinfo()
+ *
+ * This is used to free a linked list of Curl_addrinfo structs along
+ * with all its associated allocated storage. This function should be
+ * called once for each successful call to Curl_getaddrinfo_ex() or to
+ * any function call which actually allocates a Curl_addrinfo struct.
+ */
+
+#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
+ defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
+ /* workaround icc 9.1 optimizer issue */
+# define vqualifier volatile
+#else
+# define vqualifier
+#endif
+
+void
+Curl_freeaddrinfo(Curl_addrinfo *cahead)
+{
+ Curl_addrinfo *vqualifier canext;
+ Curl_addrinfo *ca;
+
+ for(ca = cahead; ca != NULL; ca = canext) {
+ free(ca->ai_addr);
+ free(ca->ai_canonname);
+ canext = ca->ai_next;
+
+ free(ca);
+ }
+}
+
+
+#ifdef HAVE_GETADDRINFO
+/*
+ * Curl_getaddrinfo_ex()
+ *
+ * This is a wrapper function around system's getaddrinfo(), with
+ * the only difference that instead of returning a linked list of
+ * addrinfo structs this one returns a linked list of Curl_addrinfo
+ * ones. The memory allocated by this function *MUST* be free'd with
+ * Curl_freeaddrinfo(). For each successful call to this function
+ * there must be an associated call later to Curl_freeaddrinfo().
+ *
+ * There should be no single call to system's getaddrinfo() in the
+ * whole library, any such call should be 'routed' through this one.
+ */
+
+int
+Curl_getaddrinfo_ex(const char *nodename,
+ const char *servname,
+ const struct addrinfo *hints,
+ Curl_addrinfo **result)
+{
+ const struct addrinfo *ai;
+ struct addrinfo *aihead;
+ Curl_addrinfo *cafirst = NULL;
+ Curl_addrinfo *calast = NULL;
+ Curl_addrinfo *ca;
+ size_t ss_size;
+ int error;
+
+ *result = NULL; /* assume failure */
+
+ error = getaddrinfo(nodename, servname, hints, &aihead);
+ if(error)
+ return error;
+
+ /* traverse the addrinfo list */
+
+ for(ai = aihead; ai != NULL; ai = ai->ai_next) {
+
+ /* ignore elements with unsupported address family, */
+ /* settle family-specific sockaddr structure size. */
+ if(ai->ai_family == AF_INET)
+ ss_size = sizeof(struct sockaddr_in);
+#ifdef ENABLE_IPV6
+ else if(ai->ai_family == AF_INET6)
+ ss_size = sizeof(struct sockaddr_in6);
+#endif
+ else
+ continue;
+
+ /* ignore elements without required address info */
+ if((ai->ai_addr == NULL) || !(ai->ai_addrlen > 0))
+ continue;
+
+ /* ignore elements with bogus address size */
+ if((size_t)ai->ai_addrlen < ss_size)
+ continue;
+
+ if((ca = malloc(sizeof(Curl_addrinfo))) == NULL) {
+ error = EAI_MEMORY;
+ break;
+ }
+
+ /* copy each structure member individually, member ordering, */
+ /* size, or padding might be different for each platform. */
+
+ ca->ai_flags = ai->ai_flags;
+ ca->ai_family = ai->ai_family;
+ ca->ai_socktype = ai->ai_socktype;
+ ca->ai_protocol = ai->ai_protocol;
+ ca->ai_addrlen = (curl_socklen_t)ss_size;
+ ca->ai_addr = NULL;
+ ca->ai_canonname = NULL;
+ ca->ai_next = NULL;
+
+ if((ca->ai_addr = malloc(ss_size)) == NULL) {
+ error = EAI_MEMORY;
+ free(ca);
+ break;
+ }
+ memcpy(ca->ai_addr, ai->ai_addr, ss_size);
+
+ if(ai->ai_canonname != NULL) {
+ if((ca->ai_canonname = strdup(ai->ai_canonname)) == NULL) {
+ error = EAI_MEMORY;
+ free(ca->ai_addr);
+ free(ca);
+ break;
+ }
+ }
+
+ /* if the return list is empty, this becomes the first element */
+ if(!cafirst)
+ cafirst = ca;
+
+ /* add this element last in the return list */
+ if(calast)
+ calast->ai_next = ca;
+ calast = ca;
+
+ }
+
+ /* destroy the addrinfo list */
+ if(aihead)
+ freeaddrinfo(aihead);
+
+ /* if we failed, also destroy the Curl_addrinfo list */
+ if(error) {
+ Curl_freeaddrinfo(cafirst);
+ cafirst = NULL;
+ }
+ else if(!cafirst) {
+#ifdef EAI_NONAME
+ /* rfc3493 conformant */
+ error = EAI_NONAME;
+#else
+ /* rfc3493 obsoleted */
+ error = EAI_NODATA;
+#endif
+#ifdef USE_WINSOCK
+ SET_SOCKERRNO(error);
+#endif
+ }
+
+ *result = cafirst;
+
+ /* This is not a CURLcode */
+ return error;
+}
+#endif /* HAVE_GETADDRINFO */
+
+
+/*
+ * Curl_he2ai()
+ *
+ * This function returns a pointer to the first element of a newly allocated
+ * Curl_addrinfo struct linked list filled with the data of a given hostent.
+ * Curl_addrinfo is meant to work like the addrinfo struct does for a IPv6
+ * stack, but usable also for IPv4, all hosts and environments.
+ *
+ * The memory allocated by this function *MUST* be free'd later on calling
+ * Curl_freeaddrinfo(). For each successful call to this function there
+ * must be an associated call later to Curl_freeaddrinfo().
+ *
+ * Curl_addrinfo defined in "lib/curl_addrinfo.h"
+ *
+ * struct Curl_addrinfo {
+ * int ai_flags;
+ * int ai_family;
+ * int ai_socktype;
+ * int ai_protocol;
+ * curl_socklen_t ai_addrlen; * Follow rfc3493 struct addrinfo *
+ * char *ai_canonname;
+ * struct sockaddr *ai_addr;
+ * struct Curl_addrinfo *ai_next;
+ * };
+ * typedef struct Curl_addrinfo Curl_addrinfo;
+ *
+ * hostent defined in <netdb.h>
+ *
+ * struct hostent {
+ * char *h_name;
+ * char **h_aliases;
+ * int h_addrtype;
+ * int h_length;
+ * char **h_addr_list;
+ * };
+ *
+ * for backward compatibility:
+ *
+ * #define h_addr h_addr_list[0]
+ */
+
+Curl_addrinfo *
+Curl_he2ai(const struct hostent *he, int port)
+{
+ Curl_addrinfo *ai;
+ Curl_addrinfo *prevai = NULL;
+ Curl_addrinfo *firstai = NULL;
+ struct sockaddr_in *addr;
+#ifdef ENABLE_IPV6
+ struct sockaddr_in6 *addr6;
+#endif
+ CURLcode result = CURLE_OK;
+ int i;
+ char *curr;
+
+ if(!he)
+ /* no input == no output! */
+ return NULL;
+
+ DEBUGASSERT((he->h_name != NULL) && (he->h_addr_list != NULL));
+
+ for(i=0; (curr = he->h_addr_list[i]) != NULL; i++) {
+
+ size_t ss_size;
+#ifdef ENABLE_IPV6
+ if(he->h_addrtype == AF_INET6)
+ ss_size = sizeof (struct sockaddr_in6);
+ else
+#endif
+ ss_size = sizeof (struct sockaddr_in);
+
+ if((ai = calloc(1, sizeof(Curl_addrinfo))) == NULL) {
+ result = CURLE_OUT_OF_MEMORY;
+ break;
+ }
+ if((ai->ai_canonname = strdup(he->h_name)) == NULL) {
+ result = CURLE_OUT_OF_MEMORY;
+ free(ai);
+ break;
+ }
+ if((ai->ai_addr = calloc(1, ss_size)) == NULL) {
+ result = CURLE_OUT_OF_MEMORY;
+ free(ai->ai_canonname);
+ free(ai);
+ break;
+ }
+
+ if(!firstai)
+ /* store the pointer we want to return from this function */
+ firstai = ai;
+
+ if(prevai)
+ /* make the previous entry point to this */
+ prevai->ai_next = ai;
+
+ ai->ai_family = he->h_addrtype;
+
+ /* we return all names as STREAM, so when using this address for TFTP
+ the type must be ignored and conn->socktype be used instead! */
+ ai->ai_socktype = SOCK_STREAM;
+
+ ai->ai_addrlen = (curl_socklen_t)ss_size;
+
+ /* leave the rest of the struct filled with zero */
+
+ switch (ai->ai_family) {
+ case AF_INET:
+ addr = (void *)ai->ai_addr; /* storage area for this info */
+
+ memcpy(&addr->sin_addr, curr, sizeof(struct in_addr));
+ addr->sin_family = (unsigned short)(he->h_addrtype);
+ addr->sin_port = htons((unsigned short)port);
+ break;
+
+#ifdef ENABLE_IPV6
+ case AF_INET6:
+ addr6 = (void *)ai->ai_addr; /* storage area for this info */
+
+ memcpy(&addr6->sin6_addr, curr, sizeof(struct in6_addr));
+ addr6->sin6_family = (unsigned short)(he->h_addrtype);
+ addr6->sin6_port = htons((unsigned short)port);
+ break;
+#endif
+ }
+
+ prevai = ai;
+ }
+
+ if(result) {
+ Curl_freeaddrinfo(firstai);
+ firstai = NULL;
+ }
+
+ return firstai;
+}
+
+
+struct namebuff {
+ struct hostent hostentry;
+ union {
+ struct in_addr ina4;
+#ifdef ENABLE_IPV6
+ struct in6_addr ina6;
+#endif
+ } addrentry;
+ char *h_addr_list[2];
+};
+
+
+/*
+ * Curl_ip2addr()
+ *
+ * This function takes an internet address, in binary form, as input parameter
+ * along with its address family and the string version of the address, and it
+ * returns a Curl_addrinfo chain filled in correctly with information for the
+ * given address/host
+ */
+
+Curl_addrinfo *
+Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port)
+{
+ Curl_addrinfo *ai;
+
+#if defined(__VMS) && \
+ defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
+#pragma pointer_size save
+#pragma pointer_size short
+#pragma message disable PTRMISMATCH
+#endif
+
+ struct hostent *h;
+ struct namebuff *buf;
+ char *addrentry;
+ char *hoststr;
+ size_t addrsize;
+
+ DEBUGASSERT(inaddr && hostname);
+
+ buf = malloc(sizeof(struct namebuff));
+ if(!buf)
+ return NULL;
+
+ hoststr = strdup(hostname);
+ if(!hoststr) {
+ free(buf);
+ return NULL;
+ }
+
+ switch(af) {
+ case AF_INET:
+ addrsize = sizeof(struct in_addr);
+ addrentry = (void *)&buf->addrentry.ina4;
+ memcpy(addrentry, inaddr, sizeof(struct in_addr));
+ break;
+#ifdef ENABLE_IPV6
+ case AF_INET6:
+ addrsize = sizeof(struct in6_addr);
+ addrentry = (void *)&buf->addrentry.ina6;
+ memcpy(addrentry, inaddr, sizeof(struct in6_addr));
+ break;
+#endif
+ default:
+ free(hoststr);
+ free(buf);
+ return NULL;
+ }
+
+ h = &buf->hostentry;
+ h->h_name = hoststr;
+ h->h_aliases = NULL;
+ h->h_addrtype = (short)af;
+ h->h_length = (short)addrsize;
+ h->h_addr_list = &buf->h_addr_list[0];
+ h->h_addr_list[0] = addrentry;
+ h->h_addr_list[1] = NULL; /* terminate list of entries */
+
+#if defined(__VMS) && \
+ defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
+#pragma pointer_size restore
+#pragma message enable PTRMISMATCH
+#endif
+
+ ai = Curl_he2ai(h, port);
+
+ free(hoststr);
+ free(buf);
+
+ return ai;
+}
+
+/*
+ * Given an IPv4 or IPv6 dotted string address, this converts it to a proper
+ * allocated Curl_addrinfo struct and returns it.
+ */
+Curl_addrinfo *Curl_str2addr(char *address, int port)
+{
+ struct in_addr in;
+ if(Curl_inet_pton(AF_INET, address, &in) > 0)
+ /* This is a dotted IP address 123.123.123.123-style */
+ return Curl_ip2addr(AF_INET, &in, address, port);
+#ifdef ENABLE_IPV6
+ else {
+ struct in6_addr in6;
+ if(Curl_inet_pton(AF_INET6, address, &in6) > 0)
+ /* This is a dotted IPv6 address ::1-style */
+ return Curl_ip2addr(AF_INET6, &in6, address, port);
+ }
+#endif
+ return NULL; /* bad input format */
+}
+
+#ifdef USE_UNIX_SOCKETS
+/**
+ * Given a path to a Unix domain socket, return a newly allocated Curl_addrinfo
+ * struct initialized with this path.
+ */
+Curl_addrinfo *Curl_unix2addr(const char *path)
+{
+ Curl_addrinfo *ai;
+ struct sockaddr_un *sa_un;
+ size_t path_len;
+
+ ai = calloc(1, sizeof(Curl_addrinfo));
+ if(!ai)
+ return NULL;
+ if((ai->ai_addr = calloc(1, sizeof(struct sockaddr_un))) == NULL) {
+ free(ai);
+ return NULL;
+ }
+ /* sun_path must be able to store the NUL-terminated path */
+ path_len = strlen(path);
+ if(path_len >= sizeof(sa_un->sun_path)) {
+ free(ai->ai_addr);
+ free(ai);
+ return NULL;
+ }
+
+ ai->ai_family = AF_UNIX;
+ ai->ai_socktype = SOCK_STREAM; /* assume reliable transport for HTTP */
+ ai->ai_addrlen = (curl_socklen_t) sizeof(struct sockaddr_un);
+ sa_un = (void *) ai->ai_addr;
+ sa_un->sun_family = AF_UNIX;
+ memcpy(sa_un->sun_path, path, path_len + 1); /* copy NUL byte */
+ return ai;
+}
+#endif
+
+#if defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO)
+/*
+ * curl_dofreeaddrinfo()
+ *
+ * This is strictly for memory tracing and are using the same style as the
+ * family otherwise present in memdebug.c. I put these ones here since they
+ * require a bunch of structs I didn't want to include in memdebug.c
+ */
+
+void
+curl_dofreeaddrinfo(struct addrinfo *freethis,
+ int line, const char *source)
+{
+ (freeaddrinfo)(freethis);
+ curl_memlog("ADDR %s:%d freeaddrinfo(%p)\n",
+ source, line, (void *)freethis);
+}
+#endif /* defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO) */
+
+
+#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO)
+/*
+ * curl_dogetaddrinfo()
+ *
+ * This is strictly for memory tracing and are using the same style as the
+ * family otherwise present in memdebug.c. I put these ones here since they
+ * require a bunch of structs I didn't want to include in memdebug.c
+ */
+
+int
+curl_dogetaddrinfo(const char *hostname,
+ const char *service,
+ const struct addrinfo *hints,
+ struct addrinfo **result,
+ int line, const char *source)
+{
+ int res=(getaddrinfo)(hostname, service, hints, result);
+ if(0 == res)
+ /* success */
+ curl_memlog("ADDR %s:%d getaddrinfo() = %p\n",
+ source, line, (void *)*result);
+ else
+ curl_memlog("ADDR %s:%d getaddrinfo() failed\n",
+ source, line);
+ return res;
+}
+#endif /* defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) */
+
diff --git a/Utilities/cmcurl/lib/curl_addrinfo.h b/Utilities/cmcurl/lib/curl_addrinfo.h
new file mode 100644
index 000000000..4ef882703
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_addrinfo.h
@@ -0,0 +1,101 @@
+#ifndef HEADER_CURL_ADDRINFO_H
+#define HEADER_CURL_ADDRINFO_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+
+#ifdef __VMS
+# include <in.h>
+# include <inet.h>
+# include <stdlib.h>
+#endif
+
+
+/*
+ * Curl_addrinfo is our internal struct definition that we use to allow
+ * consistent internal handling of this data. We use this even when the
+ * system provides an addrinfo structure definition. And we use this for
+ * all sorts of IPv4 and IPV6 builds.
+ */
+
+struct Curl_addrinfo {
+ int ai_flags;
+ int ai_family;
+ int ai_socktype;
+ int ai_protocol;
+ curl_socklen_t ai_addrlen; /* Follow rfc3493 struct addrinfo */
+ char *ai_canonname;
+ struct sockaddr *ai_addr;
+ struct Curl_addrinfo *ai_next;
+};
+typedef struct Curl_addrinfo Curl_addrinfo;
+
+void
+Curl_freeaddrinfo(Curl_addrinfo *cahead);
+
+#ifdef HAVE_GETADDRINFO
+int
+Curl_getaddrinfo_ex(const char *nodename,
+ const char *servname,
+ const struct addrinfo *hints,
+ Curl_addrinfo **result);
+#endif
+
+Curl_addrinfo *
+Curl_he2ai(const struct hostent *he, int port);
+
+Curl_addrinfo *
+Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port);
+
+Curl_addrinfo *Curl_str2addr(char *dotted, int port);
+
+#ifdef USE_UNIX_SOCKETS
+Curl_addrinfo *Curl_unix2addr(const char *path);
+#endif
+
+#if defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO)
+void
+curl_dofreeaddrinfo(struct addrinfo *freethis,
+ int line, const char *source);
+#endif
+
+#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO)
+int
+curl_dogetaddrinfo(const char *hostname,
+ const char *service,
+ const struct addrinfo *hints,
+ struct addrinfo **result,
+ int line, const char *source);
+#endif
+
+#endif /* HEADER_CURL_ADDRINFO_H */
diff --git a/Utilities/cmcurl/lib/curl_base64.h b/Utilities/cmcurl/lib/curl_base64.h
new file mode 100644
index 000000000..92896fec1
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_base64.h
@@ -0,0 +1,35 @@
+#ifndef HEADER_CURL_BASE64_H
+#define HEADER_CURL_BASE64_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+CURLcode Curl_base64_encode(struct SessionHandle *data,
+ const char *inputbuff, size_t insize,
+ char **outptr, size_t *outlen);
+CURLcode Curl_base64url_encode(struct SessionHandle *data,
+ const char *inputbuff, size_t insize,
+ char **outptr, size_t *outlen);
+
+CURLcode Curl_base64_decode(const char *src,
+ unsigned char **outptr, size_t *outlen);
+
+#endif /* HEADER_CURL_BASE64_H */
diff --git a/Utilities/cmcurl/lib/curl_config.h.cmake b/Utilities/cmcurl/lib/curl_config.h.cmake
new file mode 100644
index 000000000..06201ec37
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_config.h.cmake
@@ -0,0 +1,961 @@
+/* lib/curl_config.h.in. Generated somehow by cmake. */
+
+/* when building libcurl itself */
+#cmakedefine BUILDING_LIBCURL 1
+
+/* to disable cookies support */
+#cmakedefine CURL_DISABLE_COOKIES 1
+
+/* to disable cryptographic authentication */
+#cmakedefine CURL_DISABLE_CRYPTO_AUTH 1
+
+/* to disable DICT */
+#cmakedefine CURL_DISABLE_DICT 1
+
+/* to disable FILE */
+#cmakedefine CURL_DISABLE_FILE 1
+
+/* to disable FTP */
+#cmakedefine CURL_DISABLE_FTP 1
+
+/* to disable HTTP */
+#cmakedefine CURL_DISABLE_HTTP 1
+
+/* to disable LDAP */
+#cmakedefine CURL_DISABLE_LDAP 1
+
+/* to disable LDAPS */
+#cmakedefine CURL_DISABLE_LDAPS 1
+
+/* to disable proxies */
+#cmakedefine CURL_DISABLE_PROXY 1
+
+/* to disable TELNET */
+#cmakedefine CURL_DISABLE_TELNET 1
+
+/* to disable TFTP */
+#cmakedefine CURL_DISABLE_TFTP 1
+
+/* to disable verbose strings */
+#cmakedefine CURL_DISABLE_VERBOSE_STRINGS 1
+
+/* to make a symbol visible */
+#cmakedefine CURL_EXTERN_SYMBOL 1
+/* Ensure using CURL_EXTERN_SYMBOL is possible */
+#ifndef CURL_EXTERN_SYMBOL
+#define CURL_EXTERN_SYMBOL
+#endif
+
+/* Use Windows LDAP implementation */
+#cmakedefine USE_WIN32_LDAP 1
+
+/* when not building a shared library */
+#cmakedefine CURL_STATICLIB 1
+
+/* Set to explicitly specify we don't want to use thread-safe functions */
+#cmakedefine DISABLED_THREADSAFE 1
+
+/* your Entropy Gathering Daemon socket pathname */
+#cmakedefine EGD_SOCKET ${EGD_SOCKET}
+
+/* Define if you want to enable IPv6 support */
+#cmakedefine ENABLE_IPV6 1
+
+/* Define to the type qualifier of arg 1 for getnameinfo. */
+#cmakedefine GETNAMEINFO_QUAL_ARG1 ${GETNAMEINFO_QUAL_ARG1}
+
+/* Define to the type of arg 1 for getnameinfo. */
+#cmakedefine GETNAMEINFO_TYPE_ARG1 ${GETNAMEINFO_TYPE_ARG1}
+
+/* Define to the type of arg 2 for getnameinfo. */
+#cmakedefine GETNAMEINFO_TYPE_ARG2 ${GETNAMEINFO_TYPE_ARG2}
+
+/* Define to the type of args 4 and 6 for getnameinfo. */
+#cmakedefine GETNAMEINFO_TYPE_ARG46 ${GETNAMEINFO_TYPE_ARG46}
+
+/* Define to the type of arg 7 for getnameinfo. */
+#cmakedefine GETNAMEINFO_TYPE_ARG7 ${GETNAMEINFO_TYPE_ARG7}
+
+/* Specifies the number of arguments to getservbyport_r */
+#cmakedefine GETSERVBYPORT_R_ARGS ${GETSERVBYPORT_R_ARGS}
+
+/* Specifies the size of the buffer to pass to getservbyport_r */
+#cmakedefine GETSERVBYPORT_R_BUFSIZE ${GETSERVBYPORT_R_BUFSIZE}
+
+/* Define to 1 if you have the alarm function. */
+#cmakedefine HAVE_ALARM 1
+
+/* Define to 1 if you have the <alloca.h> header file. */
+#cmakedefine HAVE_ALLOCA_H 1
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#cmakedefine HAVE_ARPA_INET_H 1
+
+/* Define to 1 if you have the <arpa/tftp.h> header file. */
+#cmakedefine HAVE_ARPA_TFTP_H 1
+
+/* Define to 1 if you have the <assert.h> header file. */
+#cmakedefine HAVE_ASSERT_H 1
+
+/* Define to 1 if you have the `basename' function. */
+#cmakedefine HAVE_BASENAME 1
+
+/* Define to 1 if bool is an available type. */
+#cmakedefine HAVE_BOOL_T 1
+
+/* Define to 1 if you have the clock_gettime function and monotonic timer. */
+#cmakedefine HAVE_CLOCK_GETTIME_MONOTONIC 1
+
+/* Define to 1 if you have the `closesocket' function. */
+#cmakedefine HAVE_CLOSESOCKET 1
+
+/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
+#cmakedefine HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1
+
+/* Define to 1 if you have the <crypto.h> header file. */
+#cmakedefine HAVE_CRYPTO_H 1
+
+/* Define to 1 if you have the <des.h> header file. */
+#cmakedefine HAVE_DES_H 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#cmakedefine HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */
+#cmakedefine HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1
+
+/* Define to 1 if you have the <errno.h> header file. */
+#cmakedefine HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the <err.h> header file. */
+#cmakedefine HAVE_ERR_H 1
+
+/* Define to 1 if you have the fcntl function. */
+#cmakedefine HAVE_FCNTL 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#cmakedefine HAVE_FCNTL_H 1
+
+/* Define to 1 if you have a working fcntl O_NONBLOCK function. */
+#cmakedefine HAVE_FCNTL_O_NONBLOCK 1
+
+/* Define to 1 if you have the fdopen function. */
+#cmakedefine HAVE_FDOPEN 1
+
+/* Define to 1 if you have the `fork' function. */
+#cmakedefine HAVE_FORK 1
+
+/* Define to 1 if you have the freeaddrinfo function. */
+#cmakedefine HAVE_FREEADDRINFO 1
+
+/* Define to 1 if you have the freeifaddrs function. */
+#cmakedefine HAVE_FREEIFADDRS 1
+
+/* Define to 1 if you have the ftruncate function. */
+#cmakedefine HAVE_FTRUNCATE 1
+
+/* Define to 1 if you have a working getaddrinfo function. */
+#cmakedefine HAVE_GETADDRINFO 1
+
+/* Define to 1 if you have the `geteuid' function. */
+#cmakedefine HAVE_GETEUID 1
+
+/* Define to 1 if you have the gethostbyaddr function. */
+#cmakedefine HAVE_GETHOSTBYADDR 1
+
+/* Define to 1 if you have the gethostbyaddr_r function. */
+#cmakedefine HAVE_GETHOSTBYADDR_R 1
+
+/* gethostbyaddr_r() takes 5 args */
+#cmakedefine HAVE_GETHOSTBYADDR_R_5 1
+
+/* gethostbyaddr_r() takes 7 args */
+#cmakedefine HAVE_GETHOSTBYADDR_R_7 1
+
+/* gethostbyaddr_r() takes 8 args */
+#cmakedefine HAVE_GETHOSTBYADDR_R_8 1
+
+/* Define to 1 if you have the gethostbyname function. */
+#cmakedefine HAVE_GETHOSTBYNAME 1
+
+/* Define to 1 if you have the gethostbyname_r function. */
+#cmakedefine HAVE_GETHOSTBYNAME_R 1
+
+/* gethostbyname_r() takes 3 args */
+#cmakedefine HAVE_GETHOSTBYNAME_R_3 1
+
+/* gethostbyname_r() takes 5 args */
+#cmakedefine HAVE_GETHOSTBYNAME_R_5 1
+
+/* gethostbyname_r() takes 6 args */
+#cmakedefine HAVE_GETHOSTBYNAME_R_6 1
+
+/* Define to 1 if you have the gethostname function. */
+#cmakedefine HAVE_GETHOSTNAME 1
+
+/* Define to 1 if you have a working getifaddrs function. */
+#cmakedefine HAVE_GETIFADDRS 1
+
+/* Define to 1 if you have the getnameinfo function. */
+#cmakedefine HAVE_GETNAMEINFO 1
+
+/* Define to 1 if you have the `getpass_r' function. */
+#cmakedefine HAVE_GETPASS_R 1
+
+/* Define to 1 if you have the `getppid' function. */
+#cmakedefine HAVE_GETPPID 1
+
+/* Define to 1 if you have the `getprotobyname' function. */
+#cmakedefine HAVE_GETPROTOBYNAME 1
+
+/* Define to 1 if you have the `getpwuid' function. */
+#cmakedefine HAVE_GETPWUID 1
+
+/* Define to 1 if you have the `getrlimit' function. */
+#cmakedefine HAVE_GETRLIMIT 1
+
+/* Define to 1 if you have the getservbyport_r function. */
+#cmakedefine HAVE_GETSERVBYPORT_R 1
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#cmakedefine HAVE_GETTIMEOFDAY 1
+
+/* Define to 1 if you have a working glibc-style strerror_r function. */
+#cmakedefine HAVE_GLIBC_STRERROR_R 1
+
+/* Define to 1 if you have a working gmtime_r function. */
+#cmakedefine HAVE_GMTIME_R 1
+
+/* if you have the gssapi libraries */
+#cmakedefine HAVE_GSSAPI 1
+
+/* Define to 1 if you have the <gssapi/gssapi_generic.h> header file. */
+#cmakedefine HAVE_GSSAPI_GSSAPI_GENERIC_H 1
+
+/* Define to 1 if you have the <gssapi/gssapi.h> header file. */
+#cmakedefine HAVE_GSSAPI_GSSAPI_H 1
+
+/* Define to 1 if you have the <gssapi/gssapi_krb5.h> header file. */
+#cmakedefine HAVE_GSSAPI_GSSAPI_KRB5_H 1
+
+/* if you have the GNU gssapi libraries */
+#cmakedefine HAVE_GSSGNU 1
+
+/* if you have the Heimdal gssapi libraries */
+#cmakedefine HAVE_GSSHEIMDAL 1
+
+/* if you have the MIT gssapi libraries */
+#cmakedefine HAVE_GSSMIT 1
+
+/* Define to 1 if you have the `idna_strerror' function. */
+#cmakedefine HAVE_IDNA_STRERROR 1
+
+/* Define to 1 if you have the `idn_free' function. */
+#cmakedefine HAVE_IDN_FREE 1
+
+/* Define to 1 if you have the <idn-free.h> header file. */
+#cmakedefine HAVE_IDN_FREE_H 1
+
+/* Define to 1 if you have the <ifaddrs.h> header file. */
+#cmakedefine HAVE_IFADDRS_H 1
+
+/* Define to 1 if you have the `inet_addr' function. */
+#cmakedefine HAVE_INET_ADDR 1
+
+/* Define to 1 if you have the inet_ntoa_r function. */
+#cmakedefine HAVE_INET_NTOA_R 1
+
+/* inet_ntoa_r() takes 2 args */
+#cmakedefine HAVE_INET_NTOA_R_2 1
+
+/* inet_ntoa_r() takes 3 args */
+#cmakedefine HAVE_INET_NTOA_R_3 1
+
+/* Define to 1 if you have a IPv6 capable working inet_ntop function. */
+#cmakedefine HAVE_INET_NTOP 1
+
+/* Define to 1 if you have a IPv6 capable working inet_pton function. */
+#cmakedefine HAVE_INET_PTON 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#cmakedefine HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the ioctl function. */
+#cmakedefine HAVE_IOCTL 1
+
+/* Define to 1 if you have the ioctlsocket function. */
+#cmakedefine HAVE_IOCTLSOCKET 1
+
+/* Define to 1 if you have the IoctlSocket camel case function. */
+#cmakedefine HAVE_IOCTLSOCKET_CAMEL 1
+
+/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function.
+ */
+#cmakedefine HAVE_IOCTLSOCKET_CAMEL_FIONBIO 1
+
+/* Define to 1 if you have a working ioctlsocket FIONBIO function. */
+#cmakedefine HAVE_IOCTLSOCKET_FIONBIO 1
+
+/* Define to 1 if you have a working ioctl FIONBIO function. */
+#cmakedefine HAVE_IOCTL_FIONBIO 1
+
+/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */
+#cmakedefine HAVE_IOCTL_SIOCGIFADDR 1
+
+/* Define to 1 if you have the <io.h> header file. */
+#cmakedefine HAVE_IO_H 1
+
+/* if you have the Kerberos4 libraries (including -ldes) */
+#cmakedefine HAVE_KRB4 1
+
+/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */
+#cmakedefine HAVE_KRB_GET_OUR_IP_FOR_REALM 1
+
+/* Define to 1 if you have the <krb.h> header file. */
+#cmakedefine HAVE_KRB_H 1
+
+/* Define to 1 if you have the lber.h header file. */
+#cmakedefine HAVE_LBER_H 1
+
+/* Define to 1 if you have the ldapssl.h header file. */
+#cmakedefine HAVE_LDAPSSL_H 1
+
+/* Define to 1 if you have the ldap.h header file. */
+#cmakedefine HAVE_LDAP_H 1
+
+/* Use LDAPS implementation */
+#cmakedefine HAVE_LDAP_SSL 1
+
+/* Define to 1 if you have the ldap_ssl.h header file. */
+#cmakedefine HAVE_LDAP_SSL_H 1
+
+/* Define to 1 if you have the `ldap_url_parse' function. */
+#cmakedefine HAVE_LDAP_URL_PARSE 1
+
+/* Define to 1 if you have the <libgen.h> header file. */
+#cmakedefine HAVE_LIBGEN_H 1
+
+/* Define to 1 if you have the `idn' library (-lidn). */
+#cmakedefine HAVE_LIBIDN 1
+
+/* Define to 1 if you have the `resolv' library (-lresolv). */
+#cmakedefine HAVE_LIBRESOLV 1
+
+/* Define to 1 if you have the `resolve' library (-lresolve). */
+#cmakedefine HAVE_LIBRESOLVE 1
+
+/* Define to 1 if you have the `socket' library (-lsocket). */
+#cmakedefine HAVE_LIBSOCKET 1
+
+/* Define to 1 if you have the `ssh2' library (-lssh2). */
+#cmakedefine HAVE_LIBSSH2 1
+
+/* Define to 1 if libssh2 provides `libssh2_version'. */
+#cmakedefine HAVE_LIBSSH2_VERSION 1
+
+/* Define to 1 if libssh2 provides `libssh2_init'. */
+#cmakedefine HAVE_LIBSSH2_INIT 1
+
+/* Define to 1 if libssh2 provides `libssh2_exit'. */
+#cmakedefine HAVE_LIBSSH2_EXIT 1
+
+/* Define to 1 if libssh2 provides `libssh2_scp_send64'. */
+#cmakedefine HAVE_LIBSSH2_SCP_SEND64 1
+
+/* Define to 1 if libssh2 provides `libssh2_session_handshake'. */
+#cmakedefine HAVE_LIBSSH2_SESSION_HANDSHAKE 1
+
+/* Define to 1 if you have the <libssh2.h> header file. */
+#cmakedefine HAVE_LIBSSH2_H 1
+
+/* Define to 1 if you have the `ssl' library (-lssl). */
+#cmakedefine HAVE_LIBSSL 1
+
+/* if zlib is available */
+#cmakedefine HAVE_LIBZ 1
+
+/* Define to 1 if you have the <limits.h> header file. */
+#cmakedefine HAVE_LIMITS_H 1
+
+/* if your compiler supports LL */
+#cmakedefine HAVE_LL 1
+
+/* Define to 1 if you have the <locale.h> header file. */
+#cmakedefine HAVE_LOCALE_H 1
+
+/* Define to 1 if you have a working localtime_r function. */
+#cmakedefine HAVE_LOCALTIME_R 1
+
+/* Define to 1 if the compiler supports the 'long long' data type. */
+#cmakedefine HAVE_LONGLONG 1
+
+/* Define to 1 if you have the malloc.h header file. */
+#cmakedefine HAVE_MALLOC_H 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#cmakedefine HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the MSG_NOSIGNAL flag. */
+#cmakedefine HAVE_MSG_NOSIGNAL 1
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#cmakedefine HAVE_NETDB_H 1
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#cmakedefine HAVE_NETINET_IN_H 1
+
+/* Define to 1 if you have the <netinet/tcp.h> header file. */
+#cmakedefine HAVE_NETINET_TCP_H 1
+
+/* Define to 1 if you have the <net/if.h> header file. */
+#cmakedefine HAVE_NET_IF_H 1
+
+/* Define to 1 if NI_WITHSCOPEID exists and works. */
+#cmakedefine HAVE_NI_WITHSCOPEID 1
+
+/* if you have an old MIT gssapi library, lacking GSS_C_NT_HOSTBASED_SERVICE */
+#cmakedefine HAVE_OLD_GSSMIT 1
+
+/* Define to 1 if you have the <openssl/crypto.h> header file. */
+#cmakedefine HAVE_OPENSSL_CRYPTO_H 1
+
+/* Define to 1 if you have the <openssl/engine.h> header file. */
+#cmakedefine HAVE_OPENSSL_ENGINE_H 1
+
+/* Define to 1 if you have the <openssl/err.h> header file. */
+#cmakedefine HAVE_OPENSSL_ERR_H 1
+
+/* Define to 1 if you have the <openssl/pem.h> header file. */
+#cmakedefine HAVE_OPENSSL_PEM_H 1
+
+/* Define to 1 if you have the <openssl/pkcs12.h> header file. */
+#cmakedefine HAVE_OPENSSL_PKCS12_H 1
+
+/* Define to 1 if you have the <openssl/rsa.h> header file. */
+#cmakedefine HAVE_OPENSSL_RSA_H 1
+
+/* Define to 1 if you have the <openssl/ssl.h> header file. */
+#cmakedefine HAVE_OPENSSL_SSL_H 1
+
+/* Define to 1 if you have the <openssl/x509.h> header file. */
+#cmakedefine HAVE_OPENSSL_X509_H 1
+
+/* Define to 1 if you have the <pem.h> header file. */
+#cmakedefine HAVE_PEM_H 1
+
+/* Define to 1 if you have the `perror' function. */
+#cmakedefine HAVE_PERROR 1
+
+/* Define to 1 if you have the `pipe' function. */
+#cmakedefine HAVE_PIPE 1
+
+/* Define to 1 if you have a working poll function. */
+#cmakedefine HAVE_POLL 1
+
+/* If you have a fine poll */
+#cmakedefine HAVE_POLL_FINE 1
+
+/* Define to 1 if you have the <poll.h> header file. */
+#cmakedefine HAVE_POLL_H 1
+
+/* Define to 1 if you have a working POSIX-style strerror_r function. */
+#cmakedefine HAVE_POSIX_STRERROR_R 1
+
+/* Define to 1 if you have the <pthread.h> header file */
+#cmakedefine HAVE_PTHREAD_H 1
+
+/* Define to 1 if you have the <pwd.h> header file. */
+#cmakedefine HAVE_PWD_H 1
+
+/* Define to 1 if you have the `RAND_egd' function. */
+#cmakedefine HAVE_RAND_EGD 1
+
+/* Define to 1 if you have the `RAND_screen' function. */
+#cmakedefine HAVE_RAND_SCREEN 1
+
+/* Define to 1 if you have the `RAND_status' function. */
+#cmakedefine HAVE_RAND_STATUS 1
+
+/* Define to 1 if you have the recv function. */
+#cmakedefine HAVE_RECV 1
+
+/* Define to 1 if you have the recvfrom function. */
+#cmakedefine HAVE_RECVFROM 1
+
+/* Define to 1 if you have the <rsa.h> header file. */
+#cmakedefine HAVE_RSA_H 1
+
+/* Define to 1 if you have the select function. */
+#cmakedefine HAVE_SELECT 1
+
+/* Define to 1 if you have the send function. */
+#cmakedefine HAVE_SEND 1
+
+/* Define to 1 if you have the <setjmp.h> header file. */
+#cmakedefine HAVE_SETJMP_H 1
+
+/* Define to 1 if you have the `setlocale' function. */
+#cmakedefine HAVE_SETLOCALE 1
+
+/* Define to 1 if you have the `setmode' function. */
+#cmakedefine HAVE_SETMODE 1
+
+/* Define to 1 if you have the `setrlimit' function. */
+#cmakedefine HAVE_SETRLIMIT 1
+
+/* Define to 1 if you have the setsockopt function. */
+#cmakedefine HAVE_SETSOCKOPT 1
+
+/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */
+#cmakedefine HAVE_SETSOCKOPT_SO_NONBLOCK 1
+
+/* Define to 1 if you have the <sgtty.h> header file. */
+#cmakedefine HAVE_SGTTY_H 1
+
+/* Define to 1 if you have the sigaction function. */
+#cmakedefine HAVE_SIGACTION 1
+
+/* Define to 1 if you have the siginterrupt function. */
+#cmakedefine HAVE_SIGINTERRUPT 1
+
+/* Define to 1 if you have the signal function. */
+#cmakedefine HAVE_SIGNAL 1
+
+/* Define to 1 if you have the <signal.h> header file. */
+#cmakedefine HAVE_SIGNAL_H 1
+
+/* Define to 1 if you have the sigsetjmp function or macro. */
+#cmakedefine HAVE_SIGSETJMP 1
+
+/* Define to 1 if sig_atomic_t is an available typedef. */
+#cmakedefine HAVE_SIG_ATOMIC_T 1
+
+/* Define to 1 if sig_atomic_t is already defined as volatile. */
+#cmakedefine HAVE_SIG_ATOMIC_T_VOLATILE 1
+
+/* Define to 1 if struct sockaddr_in6 has the sin6_scope_id member */
+#cmakedefine HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
+
+/* Define to 1 if you have the `socket' function. */
+#cmakedefine HAVE_SOCKET 1
+
+/* Define to 1 if you have the `SSL_get_shutdown' function. */
+#cmakedefine HAVE_SSL_GET_SHUTDOWN 1
+
+/* Define to 1 if you have the <ssl.h> header file. */
+#cmakedefine HAVE_SSL_H 1
+
+/* Define to 1 if you have the <stdbool.h> header file. */
+#cmakedefine HAVE_STDBOOL_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#cmakedefine HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdio.h> header file. */
+#cmakedefine HAVE_STDIO_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#cmakedefine HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the strcasecmp function. */
+#cmakedefine HAVE_STRCASECMP 1
+
+/* Define to 1 if you have the strcasestr function. */
+#cmakedefine HAVE_STRCASESTR 1
+
+/* Define to 1 if you have the strcmpi function. */
+#cmakedefine HAVE_STRCMPI 1
+
+/* Define to 1 if you have the strdup function. */
+#cmakedefine HAVE_STRDUP 1
+
+/* Define to 1 if you have the strerror_r function. */
+#cmakedefine HAVE_STRERROR_R 1
+
+/* Define to 1 if you have the stricmp function. */
+#cmakedefine HAVE_STRICMP 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#cmakedefine HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#cmakedefine HAVE_STRING_H 1
+
+/* Define to 1 if you have the strlcat function. */
+#cmakedefine HAVE_STRLCAT 1
+
+/* Define to 1 if you have the `strlcpy' function. */
+#cmakedefine HAVE_STRLCPY 1
+
+/* Define to 1 if you have the strncasecmp function. */
+#cmakedefine HAVE_STRNCASECMP 1
+
+/* Define to 1 if you have the strncmpi function. */
+#cmakedefine HAVE_STRNCMPI 1
+
+/* Define to 1 if you have the strnicmp function. */
+#cmakedefine HAVE_STRNICMP 1
+
+/* Define to 1 if you have the <stropts.h> header file. */
+#cmakedefine HAVE_STROPTS_H 1
+
+/* Define to 1 if you have the strstr function. */
+#cmakedefine HAVE_STRSTR 1
+
+/* Define to 1 if you have the strtok_r function. */
+#cmakedefine HAVE_STRTOK_R 1
+
+/* Define to 1 if you have the strtoll function. */
+#cmakedefine HAVE_STRTOLL 1
+
+/* if struct sockaddr_storage is defined */
+#cmakedefine HAVE_STRUCT_SOCKADDR_STORAGE 1
+
+/* Define to 1 if you have the timeval struct. */
+#cmakedefine HAVE_STRUCT_TIMEVAL 1
+
+/* Define to 1 if you have the <sys/filio.h> header file. */
+#cmakedefine HAVE_SYS_FILIO_H 1
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#cmakedefine HAVE_SYS_IOCTL_H 1
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#cmakedefine HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/poll.h> header file. */
+#cmakedefine HAVE_SYS_POLL_H 1
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#cmakedefine HAVE_SYS_RESOURCE_H 1
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#cmakedefine HAVE_SYS_SELECT_H 1
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#cmakedefine HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/sockio.h> header file. */
+#cmakedefine HAVE_SYS_SOCKIO_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#cmakedefine HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#cmakedefine HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#cmakedefine HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#cmakedefine HAVE_SYS_UIO_H 1
+
+/* Define to 1 if you have the <sys/un.h> header file. */
+#cmakedefine HAVE_SYS_UN_H 1
+
+/* Define to 1 if you have the <sys/utime.h> header file. */
+#cmakedefine HAVE_SYS_UTIME_H 1
+
+/* Define to 1 if you have the <termios.h> header file. */
+#cmakedefine HAVE_TERMIOS_H 1
+
+/* Define to 1 if you have the <termio.h> header file. */
+#cmakedefine HAVE_TERMIO_H 1
+
+/* Define to 1 if you have the <time.h> header file. */
+#cmakedefine HAVE_TIME_H 1
+
+/* Define to 1 if you have the <tld.h> header file. */
+#cmakedefine HAVE_TLD_H 1
+
+/* Define to 1 if you have the `tld_strerror' function. */
+#cmakedefine HAVE_TLD_STRERROR 1
+
+/* Define to 1 if you have the `uname' function. */
+#cmakedefine HAVE_UNAME 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#cmakedefine HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `utime' function. */
+#cmakedefine HAVE_UTIME 1
+
+/* Define to 1 if you have the <utime.h> header file. */
+#cmakedefine HAVE_UTIME_H 1
+
+/* Define to 1 if compiler supports C99 variadic macro style. */
+#cmakedefine HAVE_VARIADIC_MACROS_C99 1
+
+/* Define to 1 if compiler supports old gcc variadic macro style. */
+#cmakedefine HAVE_VARIADIC_MACROS_GCC 1
+
+/* Define to 1 if you have the winber.h header file. */
+#cmakedefine HAVE_WINBER_H 1
+
+/* Define to 1 if you have the windows.h header file. */
+#cmakedefine HAVE_WINDOWS_H 1
+
+/* Define to 1 if you have the winldap.h header file. */
+#cmakedefine HAVE_WINLDAP_H 1
+
+/* Define to 1 if you have the winsock2.h header file. */
+#cmakedefine HAVE_WINSOCK2_H 1
+
+/* Define to 1 if you have the winsock.h header file. */
+#cmakedefine HAVE_WINSOCK_H 1
+
+/* Define this symbol if your OS supports changing the contents of argv */
+#cmakedefine HAVE_WRITABLE_ARGV 1
+
+/* Define to 1 if you have the writev function. */
+#cmakedefine HAVE_WRITEV 1
+
+/* Define to 1 if you have the ws2tcpip.h header file. */
+#cmakedefine HAVE_WS2TCPIP_H 1
+
+/* Define to 1 if you have the <x509.h> header file. */
+#cmakedefine HAVE_X509_H 1
+
+/* Define if you have the <process.h> header file. */
+#cmakedefine HAVE_PROCESS_H 1
+
+/* if you have the zlib.h header file */
+#cmakedefine HAVE_ZLIB_H 1
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#cmakedefine LT_OBJDIR ${LT_OBJDIR}
+
+/* If you lack a fine basename() prototype */
+#cmakedefine NEED_BASENAME_PROTO 1
+
+/* Define to 1 if you need the lber.h header file even with ldap.h */
+#cmakedefine NEED_LBER_H 1
+
+/* Define to 1 if you need the malloc.h header file even with stdlib.h */
+#cmakedefine NEED_MALLOC_H 1
+
+/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */
+#cmakedefine NEED_REENTRANT 1
+
+/* cpu-machine-OS */
+#cmakedefine OS ${OS}
+
+/* Name of package */
+#cmakedefine PACKAGE ${PACKAGE}
+
+/* Define to the address where bug reports for this package should be sent. */
+#cmakedefine PACKAGE_BUGREPORT ${PACKAGE_BUGREPORT}
+
+/* Define to the full name of this package. */
+#cmakedefine PACKAGE_NAME ${PACKAGE_NAME}
+
+/* Define to the full name and version of this package. */
+#cmakedefine PACKAGE_STRING ${PACKAGE_STRING}
+
+/* Define to the one symbol short name of this package. */
+#cmakedefine PACKAGE_TARNAME ${PACKAGE_TARNAME}
+
+/* Define to the version of this package. */
+#cmakedefine PACKAGE_VERSION ${PACKAGE_VERSION}
+
+/* a suitable file to read random data from */
+#cmakedefine RANDOM_FILE "${RANDOM_FILE}"
+
+/* Define to the type of arg 1 for recvfrom. */
+#cmakedefine RECVFROM_TYPE_ARG1 ${RECVFROM_TYPE_ARG1}
+
+/* Define to the type pointed by arg 2 for recvfrom. */
+#cmakedefine RECVFROM_TYPE_ARG2 ${RECVFROM_TYPE_ARG2}
+
+/* Define to 1 if the type pointed by arg 2 for recvfrom is void. */
+#cmakedefine RECVFROM_TYPE_ARG2_IS_VOID 1
+
+/* Define to the type of arg 3 for recvfrom. */
+#cmakedefine RECVFROM_TYPE_ARG3 ${RECVFROM_TYPE_ARG3}
+
+/* Define to the type of arg 4 for recvfrom. */
+#cmakedefine RECVFROM_TYPE_ARG4 ${RECVFROM_TYPE_ARG4}
+
+/* Define to the type pointed by arg 5 for recvfrom. */
+#cmakedefine RECVFROM_TYPE_ARG5 ${RECVFROM_TYPE_ARG5}
+
+/* Define to 1 if the type pointed by arg 5 for recvfrom is void. */
+#cmakedefine RECVFROM_TYPE_ARG5_IS_VOID 1
+
+/* Define to the type pointed by arg 6 for recvfrom. */
+#cmakedefine RECVFROM_TYPE_ARG6 ${RECVFROM_TYPE_ARG6}
+
+/* Define to 1 if the type pointed by arg 6 for recvfrom is void. */
+#cmakedefine RECVFROM_TYPE_ARG6_IS_VOID 1
+
+/* Define to the function return type for recvfrom. */
+#cmakedefine RECVFROM_TYPE_RETV ${RECVFROM_TYPE_RETV}
+
+/* Define to the type of arg 1 for recv. */
+#cmakedefine RECV_TYPE_ARG1 ${RECV_TYPE_ARG1}
+
+/* Define to the type of arg 2 for recv. */
+#cmakedefine RECV_TYPE_ARG2 ${RECV_TYPE_ARG2}
+
+/* Define to the type of arg 3 for recv. */
+#cmakedefine RECV_TYPE_ARG3 ${RECV_TYPE_ARG3}
+
+/* Define to the type of arg 4 for recv. */
+#cmakedefine RECV_TYPE_ARG4 ${RECV_TYPE_ARG4}
+
+/* Define to the function return type for recv. */
+#cmakedefine RECV_TYPE_RETV ${RECV_TYPE_RETV}
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#cmakedefine RETSIGTYPE ${RETSIGTYPE}
+
+/* Define to the type qualifier of arg 5 for select. */
+#cmakedefine SELECT_QUAL_ARG5 ${SELECT_QUAL_ARG5}
+
+/* Define to the type of arg 1 for select. */
+#cmakedefine SELECT_TYPE_ARG1 ${SELECT_TYPE_ARG1}
+
+/* Define to the type of args 2, 3 and 4 for select. */
+#cmakedefine SELECT_TYPE_ARG234 ${SELECT_TYPE_ARG234}
+
+/* Define to the type of arg 5 for select. */
+#cmakedefine SELECT_TYPE_ARG5 ${SELECT_TYPE_ARG5}
+
+/* Define to the function return type for select. */
+#cmakedefine SELECT_TYPE_RETV ${SELECT_TYPE_RETV}
+
+/* Define to the type qualifier of arg 2 for send. */
+#cmakedefine SEND_QUAL_ARG2 ${SEND_QUAL_ARG2}
+
+/* Define to the type of arg 1 for send. */
+#cmakedefine SEND_TYPE_ARG1 ${SEND_TYPE_ARG1}
+
+/* Define to the type of arg 2 for send. */
+#cmakedefine SEND_TYPE_ARG2 ${SEND_TYPE_ARG2}
+
+/* Define to the type of arg 3 for send. */
+#cmakedefine SEND_TYPE_ARG3 ${SEND_TYPE_ARG3}
+
+/* Define to the type of arg 4 for send. */
+#cmakedefine SEND_TYPE_ARG4 ${SEND_TYPE_ARG4}
+
+/* Define to the function return type for send. */
+#cmakedefine SEND_TYPE_RETV ${SEND_TYPE_RETV}
+
+/* The size of `int', as computed by sizeof. */
+@SIZEOF_INT_CODE@
+
+/* The size of `short', as computed by sizeof. */
+@SIZEOF_SHORT_CODE@
+
+/* The size of `long', as computed by sizeof. */
+@SIZEOF_LONG_CODE@
+
+/* The size of `off_t', as computed by sizeof. */
+@SIZEOF_OFF_T_CODE@
+
+/* The size of `size_t', as computed by sizeof. */
+@SIZEOF_SIZE_T_CODE@
+
+/* The size of `ssize_t', as computed by sizeof. */
+@SIZEOF_SSIZE_T_CODE@
+
+/* The size of `time_t', as computed by sizeof. */
+@SIZEOF_TIME_T_CODE@
+
+/* Define to 1 if you have the ANSI C header files. */
+#cmakedefine STDC_HEADERS 1
+
+/* Define to the type of arg 3 for strerror_r. */
+#cmakedefine STRERROR_R_TYPE_ARG3 ${STRERROR_R_TYPE_ARG3}
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#cmakedefine TIME_WITH_SYS_TIME 1
+
+/* Define if you want to enable c-ares support */
+#cmakedefine USE_ARES 1
+
+/* Define if you want to enable POSIX threaded DNS lookup */
+#cmakedefine USE_THREADS_POSIX 1
+
+/* Define to disable non-blocking sockets. */
+#cmakedefine USE_BLOCKING_SOCKETS 1
+
+/* if GnuTLS is enabled */
+#cmakedefine USE_GNUTLS 1
+
+/* if PolarSSL is enabled */
+#cmakedefine USE_POLARSSL 1
+
+/* if libSSH2 is in use */
+#cmakedefine USE_LIBSSH2 1
+
+/* If you want to build curl with the built-in manual */
+#cmakedefine USE_MANUAL 1
+
+/* if NSS is enabled */
+#cmakedefine USE_NSS 1
+
+/* if you want to use OpenLDAP code instead of legacy ldap implementation */
+#cmakedefine USE_OPENLDAP 1
+
+/* if OpenSSL is in use */
+#cmakedefine USE_OPENSSL 1
+
+/* if Unix domain sockets are enabled */
+#cmakedefine USE_UNIX_SOCKETS
+
+/* to enable SSPI support */
+#cmakedefine USE_WINDOWS_SSPI 1
+
+/* Define to 1 if using yaSSL in OpenSSL compatibility mode. */
+#cmakedefine USE_YASSLEMUL 1
+
+/* Version number of package */
+#cmakedefine VERSION ${VERSION}
+
+/* Define to avoid automatic inclusion of winsock.h */
+#cmakedefine WIN32_LEAN_AND_MEAN 1
+
+/* Define to 1 if OS is AIX. */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#cmakedefine _FILE_OFFSET_BITS ${_FILE_OFFSET_BITS}
+
+/* Define for large files, on AIX-style hosts. */
+#cmakedefine _LARGE_FILES ${_LARGE_FILES}
+
+/* define this if you need it to compile thread-safe code */
+#cmakedefine _THREAD_SAFE ${_THREAD_SAFE}
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#cmakedefine const ${const}
+
+/* Type to use in place of in_addr_t when system does not provide it. */
+#cmakedefine in_addr_t ${in_addr_t}
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#cmakedefine size_t ${size_t}
+
+/* the signed version of size_t */
+#ifndef SIZEOF_SSIZE_T
+# if SIZEOF_LONG == SIZEOF_SIZE_T
+ typedef long ssize_t;
+# elif SIZEOF_LONG_LONG == SIZEOF_SIZE_T
+ typedef long long ssize_t;
+# elif SIZEOF___INT64 == SIZEOF_SIZE_T
+ typedef __int64 ssize_t;
+# else
+ typedef int ssize_t;
+# endif
+#endif
diff --git a/Utilities/cmcurl/lib/curl_des.c b/Utilities/cmcurl/lib/curl_des.c
new file mode 100644
index 000000000..42c1df956
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_des.c
@@ -0,0 +1,63 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2015, Steve Holme, <steve_holme@hotmail.com>.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_NTLM) && (!defined(USE_OPENSSL) || defined(HAVE_BORINGSSL))
+
+#include "curl_des.h"
+
+/*
+ * Curl_des_set_odd_parity()
+ *
+ * This is used to apply odd parity to the given byte array. It is typically
+ * used by when a cryptography engines doesn't have it's own version.
+ *
+ * The function is a port of the Java based oddParity() function over at:
+ *
+ * http://davenport.sourceforge.net/ntlm.html
+ *
+ * Parameters:
+ *
+ * bytes [in/out] - The data whose parity bits are to be adjusted for
+ * odd parity.
+ * len [out] - The length of the data.
+ */
+void Curl_des_set_odd_parity(unsigned char *bytes, size_t len)
+{
+ size_t i;
+
+ for(i = 0; i < len; i++) {
+ unsigned char b = bytes[i];
+
+ bool needs_parity = (((b >> 7) ^ (b >> 6) ^ (b >> 5) ^
+ (b >> 4) ^ (b >> 3) ^ (b >> 2) ^
+ (b >> 1)) & 0x01) == 0;
+
+ if(needs_parity)
+ bytes[i] |= 0x01;
+ else
+ bytes[i] &= 0xfe;
+ }
+}
+
+#endif /* USE_NTLM && (!USE_OPENSSL || HAVE_BORINGSSL) */
diff --git a/Utilities/cmcurl/lib/curl_des.h b/Utilities/cmcurl/lib/curl_des.h
new file mode 100644
index 000000000..b855db4c1
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_des.h
@@ -0,0 +1,34 @@
+#ifndef HEADER_CURL_DES_H
+#define HEADER_CURL_DES_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2015, Steve Holme, <steve_holme@hotmail.com>.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_NTLM) && (!defined(USE_OPENSSL) || defined(HAVE_BORINGSSL))
+
+/* Applies odd parity to the given byte array */
+void Curl_des_set_odd_parity(unsigned char *bytes, size_t length);
+
+#endif /* USE_NTLM && (!USE_OPENSSL || HAVE_BORINGSSL) */
+
+#endif /* HEADER_CURL_DES_H */
diff --git a/Utilities/cmcurl/lib/curl_endian.c b/Utilities/cmcurl/lib/curl_endian.c
new file mode 100644
index 000000000..bcd66ed84
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_endian.c
@@ -0,0 +1,236 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "curl_endian.h"
+
+/*
+ * Curl_read16_le()
+ *
+ * This function converts a 16-bit integer from the little endian format, as
+ * used in the incoming package to whatever endian format we're using
+ * natively.
+ *
+ * Parameters:
+ *
+ * buf [in] - A pointer to a 2 byte buffer.
+ *
+ * Returns the integer.
+ */
+unsigned short Curl_read16_le(unsigned char *buf)
+{
+ return (unsigned short)(((unsigned short)buf[0]) |
+ ((unsigned short)buf[1] << 8));
+}
+
+/*
+ * Curl_read32_le()
+ *
+ * This function converts a 32-bit integer from the little endian format, as
+ * used in the incoming package to whatever endian format we're using
+ * natively.
+ *
+ * Parameters:
+ *
+ * buf [in] - A pointer to a 4 byte buffer.
+ *
+ * Returns the integer.
+ */
+unsigned int Curl_read32_le(unsigned char *buf)
+{
+ return ((unsigned int)buf[0]) | ((unsigned int)buf[1] << 8) |
+ ((unsigned int)buf[2] << 16) | ((unsigned int)buf[3] << 24);
+}
+
+#if (CURL_SIZEOF_CURL_OFF_T > 4)
+/*
+ * Curl_read64_le()
+ *
+ * This function converts a 64-bit integer from the little endian format, as
+ * used in the incoming package to whatever endian format we're using
+ * natively.
+ *
+ * Parameters:
+ *
+ * buf [in] - A pointer to a 8 byte buffer.
+ *
+ * Returns the integer.
+ */
+#if defined(HAVE_LONGLONG)
+unsigned long long Curl_read64_le(unsigned char *buf)
+{
+ return ((unsigned long long)buf[0]) |
+ ((unsigned long long)buf[1] << 8) |
+ ((unsigned long long)buf[2] << 16) |
+ ((unsigned long long)buf[3] << 24) |
+ ((unsigned long long)buf[4] << 32) |
+ ((unsigned long long)buf[5] << 40) |
+ ((unsigned long long)buf[6] << 48) |
+ ((unsigned long long)buf[7] << 56);
+}
+#else
+unsigned __int64 Curl_read64_le(unsigned char *buf)
+{
+ return ((unsigned __int64)buf[0]) | ((unsigned __int64)buf[1] << 8) |
+ ((unsigned __int64)buf[2] << 16) | ((unsigned __int64)buf[3] << 24) |
+ ((unsigned __int64)buf[4] << 32) | ((unsigned __int64)buf[5] << 40) |
+ ((unsigned __int64)buf[6] << 48) | ((unsigned __int64)buf[7] << 56);
+}
+#endif
+
+#endif /* CURL_SIZEOF_CURL_OFF_T > 4 */
+
+/*
+ * Curl_read16_be()
+ *
+ * This function converts a 16-bit integer from the big endian format, as
+ * used in the incoming package to whatever endian format we're using
+ * natively.
+ *
+ * Parameters:
+ *
+ * buf [in] - A pointer to a 2 byte buffer.
+ *
+ * Returns the integer.
+ */
+unsigned short Curl_read16_be(unsigned char *buf)
+{
+ return (unsigned short)(((unsigned short)buf[0] << 8) |
+ ((unsigned short)buf[1]));
+}
+
+/*
+ * Curl_read32_be()
+ *
+ * This function converts a 32-bit integer from the big endian format, as
+ * used in the incoming package to whatever endian format we're using
+ * natively.
+ *
+ * Parameters:
+ *
+ * buf [in] - A pointer to a 4 byte buffer.
+ *
+ * Returns the integer.
+ */
+unsigned int Curl_read32_be(unsigned char *buf)
+{
+ return ((unsigned int)buf[0] << 24) | ((unsigned int)buf[1] << 16) |
+ ((unsigned int)buf[2] << 8) | ((unsigned int)buf[3]);
+}
+
+#if (CURL_SIZEOF_CURL_OFF_T > 4)
+/*
+ * Curl_read64_be()
+ *
+ * This function converts a 64-bit integer from the big endian format, as
+ * used in the incoming package to whatever endian format we're using
+ * natively.
+ *
+ * Parameters:
+ *
+ * buf [in] - A pointer to a 8 byte buffer.
+ *
+ * Returns the integer.
+ */
+#if defined(HAVE_LONGLONG)
+unsigned long long Curl_read64_be(unsigned char *buf)
+{
+ return ((unsigned long long)buf[0] << 56) |
+ ((unsigned long long)buf[1] << 48) |
+ ((unsigned long long)buf[2] << 40) |
+ ((unsigned long long)buf[3] << 32) |
+ ((unsigned long long)buf[4] << 24) |
+ ((unsigned long long)buf[5] << 16) |
+ ((unsigned long long)buf[6] << 8) |
+ ((unsigned long long)buf[7]);
+}
+#else
+unsigned __int64 Curl_read64_be(unsigned char *buf)
+{
+ return ((unsigned __int64)buf[0] << 56) | ((unsigned __int64)buf[1] << 48) |
+ ((unsigned __int64)buf[2] << 40) | ((unsigned __int64)buf[3] << 32) |
+ ((unsigned __int64)buf[4] << 24) | ((unsigned __int64)buf[5] << 16) |
+ ((unsigned __int64)buf[6] << 8) | ((unsigned __int64)buf[7]);
+}
+#endif
+
+#endif /* CURL_SIZEOF_CURL_OFF_T > 4 */
+
+/*
+ * Curl_write16_le()
+ *
+ * This function converts a 16-bit integer from the native endian format,
+ * to little endian format ready for sending down the wire.
+ *
+ * Parameters:
+ *
+ * value [in] - The 16-bit integer value.
+ * buffer [in] - A pointer to the output buffer.
+ */
+void Curl_write16_le(const short value, unsigned char *buffer)
+{
+ buffer[0] = (char)(value & 0x00FF);
+ buffer[1] = (char)((value & 0xFF00) >> 8);
+}
+
+/*
+ * Curl_write32_le()
+ *
+ * This function converts a 32-bit integer from the native endian format,
+ * to little endian format ready for sending down the wire.
+ *
+ * Parameters:
+ *
+ * value [in] - The 32-bit integer value.
+ * buffer [in] - A pointer to the output buffer.
+ */
+void Curl_write32_le(const int value, unsigned char *buffer)
+{
+ buffer[0] = (char)(value & 0x000000FF);
+ buffer[1] = (char)((value & 0x0000FF00) >> 8);
+ buffer[2] = (char)((value & 0x00FF0000) >> 16);
+ buffer[3] = (char)((value & 0xFF000000) >> 24);
+}
+
+#if (CURL_SIZEOF_CURL_OFF_T > 4)
+/*
+ * Curl_write64_le()
+ *
+ * This function converts a 64-bit integer from the native endian format,
+ * to little endian format ready for sending down the wire.
+ *
+ * Parameters:
+ *
+ * value [in] - The 64-bit integer value.
+ * buffer [in] - A pointer to the output buffer.
+ */
+#if defined(HAVE_LONGLONG)
+void Curl_write64_le(const long long value, unsigned char *buffer)
+#else
+void Curl_write64_le(const __int64 value, unsigned char *buffer)
+#endif
+{
+ Curl_write32_le((int)value, buffer);
+ Curl_write32_le((int)(value >> 32), buffer + 4);
+}
+#endif /* CURL_SIZEOF_CURL_OFF_T > 4 */
diff --git a/Utilities/cmcurl/lib/curl_endian.h b/Utilities/cmcurl/lib/curl_endian.h
new file mode 100644
index 000000000..e384279fa
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_endian.h
@@ -0,0 +1,70 @@
+#ifndef HEADER_CURL_ENDIAN_H
+#define HEADER_CURL_ENDIAN_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* Converts a 16-bit integer from little endian */
+unsigned short Curl_read16_le(unsigned char *buf);
+
+/* Converts a 32-bit integer from little endian */
+unsigned int Curl_read32_le(unsigned char *buf);
+
+#if (CURL_SIZEOF_CURL_OFF_T > 4)
+/* Converts a 64-bit integer from little endian */
+#if defined(HAVE_LONGLONG)
+unsigned long long Curl_read64_le(unsigned char *buf);
+#else
+unsigned __int64 Curl_read64_le(unsigned char *buf);
+#endif
+#endif
+
+/* Converts a 16-bit integer from big endian */
+unsigned short Curl_read16_be(unsigned char *buf);
+
+/* Converts a 32-bit integer from big endian */
+unsigned int Curl_read32_be(unsigned char *buf);
+
+#if (CURL_SIZEOF_CURL_OFF_T > 4)
+/* Converts a 64-bit integer from big endian */
+#if defined(HAVE_LONGLONG)
+unsigned long long Curl_read64_be(unsigned char *buf);
+#else
+unsigned __int64 Curl_read64_be(unsigned char *buf);
+#endif
+#endif
+
+/* Converts a 16-bit integer to little endian */
+void Curl_write16_le(const short value, unsigned char *buffer);
+
+/* Converts a 32-bit integer to little endian */
+void Curl_write32_le(const int value, unsigned char *buffer);
+
+#if (CURL_SIZEOF_CURL_OFF_T > 4)
+/* Converts a 64-bit integer to little endian */
+#if defined(HAVE_LONGLONG)
+void Curl_write64_le(const long long value, unsigned char *buffer);
+#else
+void Curl_write64_le(const __int64 value, unsigned char *buffer);
+#endif
+#endif
+
+#endif /* HEADER_CURL_ENDIAN_H */
diff --git a/Utilities/cmcurl/lib/curl_fnmatch.c b/Utilities/cmcurl/lib/curl_fnmatch.c
new file mode 100644
index 000000000..1e53918d8
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_fnmatch.c
@@ -0,0 +1,424 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "curl_fnmatch.h"
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#define CURLFNM_CHARSET_LEN (sizeof(char) * 256)
+#define CURLFNM_CHSET_SIZE (CURLFNM_CHARSET_LEN + 15)
+
+#define CURLFNM_NEGATE CURLFNM_CHARSET_LEN
+
+#define CURLFNM_ALNUM (CURLFNM_CHARSET_LEN + 1)
+#define CURLFNM_DIGIT (CURLFNM_CHARSET_LEN + 2)
+#define CURLFNM_XDIGIT (CURLFNM_CHARSET_LEN + 3)
+#define CURLFNM_ALPHA (CURLFNM_CHARSET_LEN + 4)
+#define CURLFNM_PRINT (CURLFNM_CHARSET_LEN + 5)
+#define CURLFNM_BLANK (CURLFNM_CHARSET_LEN + 6)
+#define CURLFNM_LOWER (CURLFNM_CHARSET_LEN + 7)
+#define CURLFNM_GRAPH (CURLFNM_CHARSET_LEN + 8)
+#define CURLFNM_SPACE (CURLFNM_CHARSET_LEN + 9)
+#define CURLFNM_UPPER (CURLFNM_CHARSET_LEN + 10)
+
+typedef enum {
+ CURLFNM_LOOP_DEFAULT = 0,
+ CURLFNM_LOOP_BACKSLASH
+} loop_state;
+
+typedef enum {
+ CURLFNM_SCHS_DEFAULT = 0,
+ CURLFNM_SCHS_MAYRANGE,
+ CURLFNM_SCHS_MAYRANGE2,
+ CURLFNM_SCHS_RIGHTBR,
+ CURLFNM_SCHS_RIGHTBRLEFTBR
+} setcharset_state;
+
+typedef enum {
+ CURLFNM_PKW_INIT = 0,
+ CURLFNM_PKW_DDOT
+} parsekey_state;
+
+#define SETCHARSET_OK 1
+#define SETCHARSET_FAIL 0
+
+static int parsekeyword(unsigned char **pattern, unsigned char *charset)
+{
+ parsekey_state state = CURLFNM_PKW_INIT;
+#define KEYLEN 10
+ char keyword[KEYLEN] = { 0 };
+ int found = FALSE;
+ int i;
+ unsigned char *p = *pattern;
+ for(i = 0; !found; i++) {
+ char c = *p++;
+ if(i >= KEYLEN)
+ return SETCHARSET_FAIL;
+ switch(state) {
+ case CURLFNM_PKW_INIT:
+ if(ISALPHA(c) && ISLOWER(c))
+ keyword[i] = c;
+ else if(c == ':')
+ state = CURLFNM_PKW_DDOT;
+ else
+ return 0;
+ break;
+ case CURLFNM_PKW_DDOT:
+ if(c == ']')
+ found = TRUE;
+ else
+ return SETCHARSET_FAIL;
+ }
+ }
+#undef KEYLEN
+
+ *pattern = p; /* move caller's pattern pointer */
+ if(strcmp(keyword, "digit") == 0)
+ charset[CURLFNM_DIGIT] = 1;
+ else if(strcmp(keyword, "alnum") == 0)
+ charset[CURLFNM_ALNUM] = 1;
+ else if(strcmp(keyword, "alpha") == 0)
+ charset[CURLFNM_ALPHA] = 1;
+ else if(strcmp(keyword, "xdigit") == 0)
+ charset[CURLFNM_XDIGIT] = 1;
+ else if(strcmp(keyword, "print") == 0)
+ charset[CURLFNM_PRINT] = 1;
+ else if(strcmp(keyword, "graph") == 0)
+ charset[CURLFNM_GRAPH] = 1;
+ else if(strcmp(keyword, "space") == 0)
+ charset[CURLFNM_SPACE] = 1;
+ else if(strcmp(keyword, "blank") == 0)
+ charset[CURLFNM_BLANK] = 1;
+ else if(strcmp(keyword, "upper") == 0)
+ charset[CURLFNM_UPPER] = 1;
+ else if(strcmp(keyword, "lower") == 0)
+ charset[CURLFNM_LOWER] = 1;
+ else
+ return SETCHARSET_FAIL;
+ return SETCHARSET_OK;
+}
+
+/* returns 1 (true) if pattern is OK, 0 if is bad ("p" is pattern pointer) */
+static int setcharset(unsigned char **p, unsigned char *charset)
+{
+ setcharset_state state = CURLFNM_SCHS_DEFAULT;
+ unsigned char rangestart = 0;
+ unsigned char lastchar = 0;
+ bool something_found = FALSE;
+ unsigned char c;
+ for(;;) {
+ c = **p;
+ switch(state) {
+ case CURLFNM_SCHS_DEFAULT:
+ if(ISALNUM(c)) { /* ASCII value */
+ rangestart = c;
+ charset[c] = 1;
+ (*p)++;
+ state = CURLFNM_SCHS_MAYRANGE;
+ something_found = TRUE;
+ }
+ else if(c == ']') {
+ if(something_found)
+ return SETCHARSET_OK;
+ else
+ something_found = TRUE;
+ state = CURLFNM_SCHS_RIGHTBR;
+ charset[c] = 1;
+ (*p)++;
+ }
+ else if(c == '[') {
+ char c2 = *((*p)+1);
+ if(c2 == ':') { /* there has to be a keyword */
+ (*p) += 2;
+ if(parsekeyword(p, charset)) {
+ state = CURLFNM_SCHS_DEFAULT;
+ }
+ else
+ return SETCHARSET_FAIL;
+ }
+ else {
+ charset[c] = 1;
+ (*p)++;
+ }
+ something_found = TRUE;
+ }
+ else if(c == '?' || c == '*') {
+ something_found = TRUE;
+ charset[c] = 1;
+ (*p)++;
+ }
+ else if(c == '^' || c == '!') {
+ if(!something_found) {
+ if(charset[CURLFNM_NEGATE]) {
+ charset[c] = 1;
+ something_found = TRUE;
+ }
+ else
+ charset[CURLFNM_NEGATE] = 1; /* negate charset */
+ }
+ else
+ charset[c] = 1;
+ (*p)++;
+ }
+ else if(c == '\\') {
+ c = *(++(*p));
+ if(ISPRINT((c))) {
+ something_found = TRUE;
+ state = CURLFNM_SCHS_MAYRANGE;
+ charset[c] = 1;
+ rangestart = c;
+ (*p)++;
+ }
+ else
+ return SETCHARSET_FAIL;
+ }
+ else if(c == '\0') {
+ return SETCHARSET_FAIL;
+ }
+ else {
+ charset[c] = 1;
+ (*p)++;
+ something_found = TRUE;
+ }
+ break;
+ case CURLFNM_SCHS_MAYRANGE:
+ if(c == '-') {
+ charset[c] = 1;
+ (*p)++;
+ lastchar = '-';
+ state = CURLFNM_SCHS_MAYRANGE2;
+ }
+ else if(c == '[') {
+ state = CURLFNM_SCHS_DEFAULT;
+ }
+ else if(ISALNUM(c)) {
+ charset[c] = 1;
+ (*p)++;
+ }
+ else if(c == '\\') {
+ c = *(++(*p));
+ if(ISPRINT(c)) {
+ charset[c] = 1;
+ (*p)++;
+ }
+ else
+ return SETCHARSET_FAIL;
+ }
+ else if(c == ']') {
+ return SETCHARSET_OK;
+ }
+ else
+ return SETCHARSET_FAIL;
+ break;
+ case CURLFNM_SCHS_MAYRANGE2:
+ if(c == '\\') {
+ c = *(++(*p));
+ if(!ISPRINT(c))
+ return SETCHARSET_FAIL;
+ }
+ if(c == ']') {
+ return SETCHARSET_OK;
+ }
+ else if(c == '\\') {
+ c = *(++(*p));
+ if(ISPRINT(c)) {
+ charset[c] = 1;
+ state = CURLFNM_SCHS_DEFAULT;
+ (*p)++;
+ }
+ else
+ return SETCHARSET_FAIL;
+ }
+ if(c >= rangestart) {
+ if((ISLOWER(c) && ISLOWER(rangestart)) ||
+ (ISDIGIT(c) && ISDIGIT(rangestart)) ||
+ (ISUPPER(c) && ISUPPER(rangestart))) {
+ charset[lastchar] = 0;
+ rangestart++;
+ while(rangestart++ <= c)
+ charset[rangestart-1] = 1;
+ (*p)++;
+ state = CURLFNM_SCHS_DEFAULT;
+ }
+ else
+ return SETCHARSET_FAIL;
+ }
+ break;
+ case CURLFNM_SCHS_RIGHTBR:
+ if(c == '[') {
+ state = CURLFNM_SCHS_RIGHTBRLEFTBR;
+ charset[c] = 1;
+ (*p)++;
+ }
+ else if(c == ']') {
+ return SETCHARSET_OK;
+ }
+ else if(c == '\0') {
+ return SETCHARSET_FAIL;
+ }
+ else if(ISPRINT(c)) {
+ charset[c] = 1;
+ (*p)++;
+ state = CURLFNM_SCHS_DEFAULT;
+ }
+ else
+ /* used 'goto fail' instead of 'return SETCHARSET_FAIL' to avoid a
+ * nonsense warning 'statement not reached' at end of the fnc when
+ * compiling on Solaris */
+ goto fail;
+ break;
+ case CURLFNM_SCHS_RIGHTBRLEFTBR:
+ if(c == ']') {
+ return SETCHARSET_OK;
+ }
+ else {
+ state = CURLFNM_SCHS_DEFAULT;
+ charset[c] = 1;
+ (*p)++;
+ }
+ break;
+ }
+ }
+fail:
+ return SETCHARSET_FAIL;
+}
+
+static int loop(const unsigned char *pattern, const unsigned char *string)
+{
+ loop_state state = CURLFNM_LOOP_DEFAULT;
+ unsigned char *p = (unsigned char *)pattern;
+ unsigned char *s = (unsigned char *)string;
+ unsigned char charset[CURLFNM_CHSET_SIZE] = { 0 };
+ int rc = 0;
+
+ for(;;) {
+ switch(state) {
+ case CURLFNM_LOOP_DEFAULT:
+ if(*p == '*') {
+ while(*(p+1) == '*') /* eliminate multiple stars */
+ p++;
+ if(*s == '\0' && *(p+1) == '\0')
+ return CURL_FNMATCH_MATCH;
+ rc = loop(p + 1, s); /* *.txt matches .txt <=> .txt matches .txt */
+ if(rc == CURL_FNMATCH_MATCH)
+ return CURL_FNMATCH_MATCH;
+ if(*s) /* let the star eat up one character */
+ s++;
+ else
+ return CURL_FNMATCH_NOMATCH;
+ }
+ else if(*p == '?') {
+ if(ISPRINT(*s)) {
+ s++;
+ p++;
+ }
+ else if(*s == '\0')
+ return CURL_FNMATCH_NOMATCH;
+ else
+ return CURL_FNMATCH_FAIL; /* cannot deal with other character */
+ }
+ else if(*p == '\0') {
+ if(*s == '\0')
+ return CURL_FNMATCH_MATCH;
+ else
+ return CURL_FNMATCH_NOMATCH;
+ }
+ else if(*p == '\\') {
+ state = CURLFNM_LOOP_BACKSLASH;
+ p++;
+ }
+ else if(*p == '[') {
+ unsigned char *pp = p+1; /* cannot handle with pointer to register */
+ if(setcharset(&pp, charset)) {
+ int found = FALSE;
+ if(charset[(unsigned int)*s])
+ found = TRUE;
+ else if(charset[CURLFNM_ALNUM])
+ found = ISALNUM(*s);
+ else if(charset[CURLFNM_ALPHA])
+ found = ISALPHA(*s);
+ else if(charset[CURLFNM_DIGIT])
+ found = ISDIGIT(*s);
+ else if(charset[CURLFNM_XDIGIT])
+ found = ISXDIGIT(*s);
+ else if(charset[CURLFNM_PRINT])
+ found = ISPRINT(*s);
+ else if(charset[CURLFNM_SPACE])
+ found = ISSPACE(*s);
+ else if(charset[CURLFNM_UPPER])
+ found = ISUPPER(*s);
+ else if(charset[CURLFNM_LOWER])
+ found = ISLOWER(*s);
+ else if(charset[CURLFNM_BLANK])
+ found = ISBLANK(*s);
+ else if(charset[CURLFNM_GRAPH])
+ found = ISGRAPH(*s);
+
+ if(charset[CURLFNM_NEGATE])
+ found = !found;
+
+ if(found) {
+ p = pp+1;
+ s++;
+ memset(charset, 0, CURLFNM_CHSET_SIZE);
+ }
+ else
+ return CURL_FNMATCH_NOMATCH;
+ }
+ else
+ return CURL_FNMATCH_FAIL;
+ }
+ else {
+ if(*p++ != *s++)
+ return CURL_FNMATCH_NOMATCH;
+ }
+ break;
+ case CURLFNM_LOOP_BACKSLASH:
+ if(ISPRINT(*p)) {
+ if(*p++ == *s++)
+ state = CURLFNM_LOOP_DEFAULT;
+ else
+ return CURL_FNMATCH_NOMATCH;
+ }
+ else
+ return CURL_FNMATCH_FAIL;
+ break;
+ }
+ }
+}
+
+/*
+ * @unittest: 1307
+ */
+int Curl_fnmatch(void *ptr, const char *pattern, const char *string)
+{
+ (void)ptr; /* the argument is specified by the curl_fnmatch_callback
+ prototype, but not used by Curl_fnmatch() */
+ if(!pattern || !string) {
+ return CURL_FNMATCH_FAIL;
+ }
+ return loop((unsigned char *)pattern, (unsigned char *)string);
+}
diff --git a/Utilities/cmcurl/lib/curl_fnmatch.h b/Utilities/cmcurl/lib/curl_fnmatch.h
new file mode 100644
index 000000000..6335d0312
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_fnmatch.h
@@ -0,0 +1,44 @@
+#ifndef HEADER_CURL_FNMATCH_H
+#define HEADER_CURL_FNMATCH_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#define CURL_FNMATCH_MATCH 0
+#define CURL_FNMATCH_NOMATCH 1
+#define CURL_FNMATCH_FAIL 2
+
+/* default pattern matching function
+ * =================================
+ * Implemented with recursive backtracking, if you want to use Curl_fnmatch,
+ * please note that there is not implemented UTF/UNICODE support.
+ *
+ * Implemented features:
+ * '?' notation, does not match UTF characters
+ * '*' can also work with UTF string
+ * [a-zA-Z0-9] enumeration support
+ *
+ * keywords: alnum, digit, xdigit, alpha, print, blank, lower, graph, space
+ * and upper (use as "[[:alnum:]]")
+ */
+int Curl_fnmatch(void *ptr, const char *pattern, const char *string);
+
+#endif /* HEADER_CURL_FNMATCH_H */
diff --git a/Utilities/cmcurl/lib/curl_gethostname.c b/Utilities/cmcurl/lib/curl_gethostname.c
new file mode 100644
index 000000000..ded1e6f94
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_gethostname.c
@@ -0,0 +1,100 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "curl_gethostname.h"
+
+/*
+ * Curl_gethostname() is a wrapper around gethostname() which allows
+ * overriding the host name that the function would normally return.
+ * This capability is used by the test suite to verify exact matching
+ * of NTLM authentication, which exercises libcurl's MD4 and DES code
+ * as well as by the SMTP module when a hostname is not provided.
+ *
+ * For libcurl debug enabled builds host name overriding takes place
+ * when environment variable CURL_GETHOSTNAME is set, using the value
+ * held by the variable to override returned host name.
+ *
+ * Note: The function always returns the un-qualified hostname rather
+ * than being provider dependent.
+ *
+ * For libcurl shared library release builds the test suite preloads
+ * another shared library named libhostname using the LD_PRELOAD
+ * mechanism which intercepts, and might override, the gethostname()
+ * function call. In this case a given platform must support the
+ * LD_PRELOAD mechanism and additionally have environment variable
+ * CURL_GETHOSTNAME set in order to override the returned host name.
+ *
+ * For libcurl static library release builds no overriding takes place.
+ */
+
+int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen) {
+
+#ifndef HAVE_GETHOSTNAME
+
+ /* Allow compilation and return failure when unavailable */
+ (void) name;
+ (void) namelen;
+ return -1;
+
+#else
+ int err;
+ char* dot;
+
+#ifdef DEBUGBUILD
+
+ /* Override host name when environment variable CURL_GETHOSTNAME is set */
+ const char *force_hostname = getenv("CURL_GETHOSTNAME");
+ if(force_hostname) {
+ strncpy(name, force_hostname, namelen);
+ err = 0;
+ }
+ else {
+ name[0] = '\0';
+ err = gethostname(name, namelen);
+ }
+
+#else /* DEBUGBUILD */
+
+ /* The call to system's gethostname() might get intercepted by the
+ libhostname library when libcurl is built as a non-debug shared
+ library when running the test suite. */
+ name[0] = '\0';
+ err = gethostname(name, namelen);
+
+#endif
+
+ name[namelen - 1] = '\0';
+
+ if(err)
+ return err;
+
+ /* Truncate domain, leave only machine name */
+ dot = strchr(name, '.');
+ if(dot)
+ *dot = '\0';
+
+ return 0;
+#endif
+
+}
diff --git a/Utilities/cmcurl/lib/curl_gethostname.h b/Utilities/cmcurl/lib/curl_gethostname.h
new file mode 100644
index 000000000..48740f62a
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_gethostname.h
@@ -0,0 +1,31 @@
+#ifndef HEADER_CURL_GETHOSTNAME_H
+#define HEADER_CURL_GETHOSTNAME_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* Hostname buffer size */
+#define HOSTNAME_MAX 1024
+
+/* This returns the local machine's un-qualified hostname */
+int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen);
+
+#endif /* HEADER_CURL_GETHOSTNAME_H */
diff --git a/Utilities/cmcurl/lib/curl_gssapi.c b/Utilities/cmcurl/lib/curl_gssapi.c
new file mode 100644
index 000000000..9baece5ad
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_gssapi.c
@@ -0,0 +1,120 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2011 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_GSSAPI
+
+#include "curl_gssapi.h"
+#include "sendf.h"
+
+static char spnego_oid_bytes[] = "\x2b\x06\x01\x05\x05\x02";
+gss_OID_desc Curl_spnego_mech_oid = { 6, &spnego_oid_bytes };
+static char krb5_oid_bytes[] = "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02";
+gss_OID_desc Curl_krb5_mech_oid = { 9, &krb5_oid_bytes };
+
+OM_uint32 Curl_gss_init_sec_context(
+ struct SessionHandle *data,
+ OM_uint32 *minor_status,
+ gss_ctx_id_t *context,
+ gss_name_t target_name,
+ gss_OID mech_type,
+ gss_channel_bindings_t input_chan_bindings,
+ gss_buffer_t input_token,
+ gss_buffer_t output_token,
+ const bool mutual_auth,
+ OM_uint32 *ret_flags)
+{
+ OM_uint32 req_flags = GSS_C_REPLAY_FLAG;
+
+ if(mutual_auth)
+ req_flags |= GSS_C_MUTUAL_FLAG;
+
+ if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_POLICY_FLAG) {
+#ifdef GSS_C_DELEG_POLICY_FLAG
+ req_flags |= GSS_C_DELEG_POLICY_FLAG;
+#else
+ infof(data, "warning: support for CURLGSSAPI_DELEGATION_POLICY_FLAG not "
+ "compiled in\n");
+#endif
+ }
+
+ if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_FLAG)
+ req_flags |= GSS_C_DELEG_FLAG;
+
+ return gss_init_sec_context(minor_status,
+ GSS_C_NO_CREDENTIAL, /* cred_handle */
+ context,
+ target_name,
+ mech_type,
+ req_flags,
+ 0, /* time_req */
+ input_chan_bindings,
+ input_token,
+ NULL, /* actual_mech_type */
+ output_token,
+ ret_flags,
+ NULL /* time_rec */);
+}
+
+/*
+ * Curl_gss_log_error()
+ *
+ * This is used to log a GSS-API error status.
+ *
+ * Parameters:
+ *
+ * data [in] - The session handle.
+ * status [in] - The status code.
+ * prefix [in] - The prefix of the log message.
+ */
+void Curl_gss_log_error(struct SessionHandle *data, OM_uint32 status,
+ const char *prefix)
+{
+ OM_uint32 maj_stat;
+ OM_uint32 min_stat;
+ OM_uint32 msg_ctx = 0;
+ gss_buffer_desc status_string;
+ char buf[1024];
+ size_t len;
+
+ snprintf(buf, sizeof(buf), "%s", prefix);
+ len = strlen(buf);
+ do {
+ maj_stat = gss_display_status(&min_stat,
+ status,
+ GSS_C_MECH_CODE,
+ GSS_C_NO_OID,
+ &msg_ctx,
+ &status_string);
+ if(sizeof(buf) > len + status_string.length + 1) {
+ snprintf(buf + len, sizeof(buf) - len,
+ ": %s", (char*)status_string.value);
+ len += status_string.length;
+ }
+ gss_release_buffer(&min_stat, &status_string);
+ } while(!GSS_ERROR(maj_stat) && msg_ctx != 0);
+
+ infof(data, "%s\n", buf);
+}
+
+#endif /* HAVE_GSSAPI */
diff --git a/Utilities/cmcurl/lib/curl_gssapi.h b/Utilities/cmcurl/lib/curl_gssapi.h
new file mode 100644
index 000000000..19aab64e6
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_gssapi.h
@@ -0,0 +1,75 @@
+#ifndef HEADER_CURL_GSSAPI_H
+#define HEADER_CURL_GSSAPI_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2011 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include "urldata.h"
+
+#ifdef HAVE_GSSAPI
+
+#ifdef HAVE_GSSGNU
+# include <gss.h>
+#elif defined HAVE_GSSMIT
+ /* MIT style */
+# include <gssapi/gssapi.h>
+# include <gssapi/gssapi_generic.h>
+# include <gssapi/gssapi_krb5.h>
+#else
+ /* Heimdal-style */
+# include <gssapi.h>
+#endif
+
+extern gss_OID_desc Curl_spnego_mech_oid;
+extern gss_OID_desc Curl_krb5_mech_oid;
+
+/* Common method for using GSS-API */
+OM_uint32 Curl_gss_init_sec_context(
+ struct SessionHandle *data,
+ OM_uint32 *minor_status,
+ gss_ctx_id_t *context,
+ gss_name_t target_name,
+ gss_OID mech_type,
+ gss_channel_bindings_t input_chan_bindings,
+ gss_buffer_t input_token,
+ gss_buffer_t output_token,
+ const bool mutual_auth,
+ OM_uint32 *ret_flags);
+
+/* Helper to log a GSS-API error status */
+void Curl_gss_log_error(struct SessionHandle *data, OM_uint32 status,
+ const char *prefix);
+
+/* Provide some definitions missing in old headers */
+#ifdef HAVE_OLD_GSSMIT
+#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name
+#define NCOMPAT 1
+#endif
+
+/* Define our privacy and integrity protection values */
+#define GSSAUTH_P_NONE 1
+#define GSSAUTH_P_INTEGRITY 2
+#define GSSAUTH_P_PRIVACY 4
+
+#endif /* HAVE_GSSAPI */
+
+#endif /* HEADER_CURL_GSSAPI_H */
diff --git a/Utilities/cmcurl/lib/curl_hmac.h b/Utilities/cmcurl/lib/curl_hmac.h
new file mode 100644
index 000000000..9b65c8c2a
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_hmac.h
@@ -0,0 +1,67 @@
+#ifndef HEADER_CURL_HMAC_H
+#define HEADER_CURL_HMAC_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+
+typedef void (* HMAC_hinit_func)(void * context);
+typedef void (* HMAC_hupdate_func)(void * context,
+ const unsigned char * data,
+ unsigned int len);
+typedef void (* HMAC_hfinal_func)(unsigned char * result, void * context);
+
+
+/* Per-hash function HMAC parameters. */
+
+typedef struct {
+ HMAC_hinit_func hmac_hinit; /* Initialize context procedure. */
+ HMAC_hupdate_func hmac_hupdate; /* Update context with data. */
+ HMAC_hfinal_func hmac_hfinal; /* Get final result procedure. */
+ unsigned int hmac_ctxtsize; /* Context structure size. */
+ unsigned int hmac_maxkeylen; /* Maximum key length (bytes). */
+ unsigned int hmac_resultlen; /* Result length (bytes). */
+} HMAC_params;
+
+
+/* HMAC computation context. */
+
+typedef struct {
+ const HMAC_params * hmac_hash; /* Hash function definition. */
+ void * hmac_hashctxt1; /* Hash function context 1. */
+ void * hmac_hashctxt2; /* Hash function context 2. */
+} HMAC_context;
+
+
+/* Prototypes. */
+
+HMAC_context * Curl_HMAC_init(const HMAC_params * hashparams,
+ const unsigned char * key,
+ unsigned int keylen);
+int Curl_HMAC_update(HMAC_context * context,
+ const unsigned char * data,
+ unsigned int len);
+int Curl_HMAC_final(HMAC_context * context, unsigned char * result);
+
+#endif
+
+#endif /* HEADER_CURL_HMAC_H */
diff --git a/Utilities/cmcurl/lib/curl_ldap.h b/Utilities/cmcurl/lib/curl_ldap.h
new file mode 100644
index 000000000..93fb4b07a
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_ldap.h
@@ -0,0 +1,35 @@
+#ifndef HEADER_CURL_LDAP_H
+#define HEADER_CURL_LDAP_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#ifndef CURL_DISABLE_LDAP
+extern const struct Curl_handler Curl_handler_ldap;
+
+#if !defined(CURL_DISABLE_LDAPS) && \
+ ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \
+ (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))
+extern const struct Curl_handler Curl_handler_ldaps;
+#endif
+
+#endif
+#endif /* HEADER_CURL_LDAP_H */
+
diff --git a/Utilities/cmcurl/lib/curl_md4.h b/Utilities/cmcurl/lib/curl_md4.h
new file mode 100644
index 000000000..13c79034d
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_md4.h
@@ -0,0 +1,35 @@
+#ifndef HEADER_CURL_MD4_H
+#define HEADER_CURL_MD4_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+/* NSS and OS/400 crypto library do not provide the MD4 hash algorithm, so
+ * that we have a local implementation of it */
+#if defined(USE_NSS) || defined(USE_OS400CRYPTO)
+
+void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len);
+
+#endif /* defined(USE_NSS) || defined(USE_OS400CRYPTO) */
+
+#endif /* HEADER_CURL_MD4_H */
diff --git a/Utilities/cmcurl/lib/curl_md5.h b/Utilities/cmcurl/lib/curl_md5.h
new file mode 100644
index 000000000..9c0e0b5ee
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_md5.h
@@ -0,0 +1,63 @@
+#ifndef HEADER_CURL_MD5_H
+#define HEADER_CURL_MD5_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+#include "curl_hmac.h"
+
+#define MD5_DIGEST_LEN 16
+
+typedef void (* Curl_MD5_init_func)(void *context);
+typedef void (* Curl_MD5_update_func)(void *context,
+ const unsigned char *data,
+ unsigned int len);
+typedef void (* Curl_MD5_final_func)(unsigned char *result, void *context);
+
+typedef struct {
+ Curl_MD5_init_func md5_init_func; /* Initialize context procedure */
+ Curl_MD5_update_func md5_update_func; /* Update context with data */
+ Curl_MD5_final_func md5_final_func; /* Get final result procedure */
+ unsigned int md5_ctxtsize; /* Context structure size */
+ unsigned int md5_resultlen; /* Result length (bytes) */
+} MD5_params;
+
+typedef struct {
+ const MD5_params *md5_hash; /* Hash function definition */
+ void *md5_hashctx; /* Hash function context */
+} MD5_context;
+
+extern const MD5_params Curl_DIGEST_MD5[1];
+extern const HMAC_params Curl_HMAC_MD5[1];
+
+void Curl_md5it(unsigned char *output,
+ const unsigned char *input);
+
+MD5_context * Curl_MD5_init(const MD5_params *md5params);
+int Curl_MD5_update(MD5_context *context,
+ const unsigned char *data,
+ unsigned int len);
+int Curl_MD5_final(MD5_context *context, unsigned char *result);
+
+#endif
+
+#endif /* HEADER_CURL_MD5_H */
diff --git a/Utilities/cmcurl/lib/curl_memory.h b/Utilities/cmcurl/lib/curl_memory.h
new file mode 100644
index 000000000..bc744ccd8
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_memory.h
@@ -0,0 +1,143 @@
+#ifndef HEADER_CURL_MEMORY_H
+#define HEADER_CURL_MEMORY_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Nasty internal details ahead...
+ *
+ * File curl_memory.h must be included by _all_ *.c source files
+ * that use memory related functions strdup, malloc, calloc, realloc
+ * or free, and given source file is used to build libcurl library.
+ * It should be included immediately before memdebug.h as the last files
+ * included to avoid undesired interaction with other memory function
+ * headers in dependent libraries.
+ *
+ * There is nearly no exception to above rule. All libcurl source
+ * files in 'lib' subdirectory as well as those living deep inside
+ * 'packages' subdirectories and linked together in order to build
+ * libcurl library shall follow it.
+ *
+ * File lib/strdup.c is an exception, given that it provides a strdup
+ * clone implementation while using malloc. Extra care needed inside
+ * this one. TODO: revisit this paragraph and related code.
+ *
+ * The need for curl_memory.h inclusion is due to libcurl's feature
+ * of allowing library user to provide memory replacement functions,
+ * memory callbacks, at runtime with curl_global_init_mem()
+ *
+ * Any *.c source file used to build libcurl library that does not
+ * include curl_memory.h and uses any memory function of the five
+ * mentioned above will compile without any indication, but it will
+ * trigger weird memory related issues at runtime.
+ *
+ * OTOH some source files from 'lib' subdirectory may additionally be
+ * used directly as source code when using some curlx_ functions by
+ * third party programs that don't even use libcurl at all. When using
+ * these source files in this way it is necessary these are compiled
+ * with CURLX_NO_MEMORY_CALLBACKS defined, in order to ensure that no
+ * attempt of calling libcurl's memory callbacks is done from code
+ * which can not use this machinery.
+ *
+ * Notice that libcurl's 'memory tracking' system works chaining into
+ * the memory callback machinery. This implies that when compiling
+ * 'lib' source files with CURLX_NO_MEMORY_CALLBACKS defined this file
+ * disengages usage of libcurl's 'memory tracking' system, defining
+ * MEMDEBUG_NODEFINES and overriding CURLDEBUG purpose.
+ *
+ * CURLX_NO_MEMORY_CALLBACKS takes precedence over CURLDEBUG. This is
+ * done in order to allow building a 'memory tracking' enabled libcurl
+ * and at the same time allow building programs which do not use it.
+ *
+ * Programs and libraries in 'tests' subdirectories have specific
+ * purposes and needs, and as such each one will use whatever fits
+ * best, depending additionally wether it links with libcurl or not.
+ *
+ * Caveat emptor. Proper curlx_* separation is a work in progress
+ * the same as CURLX_NO_MEMORY_CALLBACKS usage, some adjustments may
+ * still be required. IOW don't use them yet, there are sharp edges.
+ */
+
+#ifdef HEADER_CURL_MEMDEBUG_H
+#error "Header memdebug.h shall not be included before curl_memory.h"
+#endif
+
+#ifndef CURLX_NO_MEMORY_CALLBACKS
+
+#include <curl/curl.h> /* for the callback typedefs */
+
+extern curl_malloc_callback Curl_cmalloc;
+extern curl_free_callback Curl_cfree;
+extern curl_realloc_callback Curl_crealloc;
+extern curl_strdup_callback Curl_cstrdup;
+extern curl_calloc_callback Curl_ccalloc;
+#if defined(WIN32) && defined(UNICODE)
+extern curl_wcsdup_callback Curl_cwcsdup;
+#endif
+
+#ifndef CURLDEBUG
+
+/*
+ * libcurl's 'memory tracking' system defines strdup, malloc, calloc,
+ * realloc and free, along with others, in memdebug.h in a different
+ * way although still using memory callbacks forward declared above.
+ * When using the 'memory tracking' system (CURLDEBUG defined) we do
+ * not define here the five memory functions given that definitions
+ * from memdebug.h are the ones that shall be used.
+ */
+
+#undef strdup
+#define strdup(ptr) Curl_cstrdup(ptr)
+#undef malloc
+#define malloc(size) Curl_cmalloc(size)
+#undef calloc
+#define calloc(nbelem,size) Curl_ccalloc(nbelem, size)
+#undef realloc
+#define realloc(ptr,size) Curl_crealloc(ptr, size)
+#undef free
+#define free(ptr) Curl_cfree(ptr)
+
+#ifdef WIN32
+# ifdef UNICODE
+# undef wcsdup
+# define wcsdup(ptr) Curl_cwcsdup(ptr)
+# undef _wcsdup
+# define _wcsdup(ptr) Curl_cwcsdup(ptr)
+# undef _tcsdup
+# define _tcsdup(ptr) Curl_cwcsdup(ptr)
+# else
+# undef _tcsdup
+# define _tcsdup(ptr) Curl_cstrdup(ptr)
+# endif
+#endif
+
+#endif /* CURLDEBUG */
+
+#else /* CURLX_NO_MEMORY_CALLBACKS */
+
+#ifndef MEMDEBUG_NODEFINES
+#define MEMDEBUG_NODEFINES
+#endif
+
+#endif /* CURLX_NO_MEMORY_CALLBACKS */
+
+#endif /* HEADER_CURL_MEMORY_H */
diff --git a/Utilities/cmcurl/lib/curl_memrchr.c b/Utilities/cmcurl/lib/curl_memrchr.c
new file mode 100644
index 000000000..6722c6a20
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_memrchr.c
@@ -0,0 +1,58 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include "curl_memrchr.h"
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#ifndef HAVE_MEMRCHR
+
+/*
+ * Curl_memrchr()
+ *
+ * Our memrchr() function clone for systems which lack this function. The
+ * memrchr() function is like the memchr() function, except that it searches
+ * backwards from the end of the n bytes pointed to by s instead of forward
+ * from the beginning.
+ */
+
+void *
+Curl_memrchr(const void *s, int c, size_t n)
+{
+ const unsigned char *p = s;
+ const unsigned char *q = s;
+
+ p += n - 1;
+
+ while(p >= q) {
+ if(*p == (unsigned char)c)
+ return (void *)p;
+ p--;
+ }
+
+ return NULL;
+}
+
+#endif /* HAVE_MEMRCHR */
diff --git a/Utilities/cmcurl/lib/curl_memrchr.h b/Utilities/cmcurl/lib/curl_memrchr.h
new file mode 100644
index 000000000..324c73a7b
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_memrchr.h
@@ -0,0 +1,44 @@
+#ifndef HEADER_CURL_MEMRCHR_H
+#define HEADER_CURL_MEMRCHR_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_MEMRCHR
+
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#else /* HAVE_MEMRCHR */
+
+void *Curl_memrchr(const void *s, int c, size_t n);
+
+#define memrchr(x,y,z) Curl_memrchr((x),(y),(z))
+
+#endif /* HAVE_MEMRCHR */
+
+#endif /* HEADER_CURL_MEMRCHR_H */
diff --git a/Utilities/cmcurl/lib/curl_multibyte.c b/Utilities/cmcurl/lib/curl_multibyte.c
new file mode 100644
index 000000000..403d00537
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_multibyte.c
@@ -0,0 +1,82 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_WIN32_IDN) || ((defined(USE_WINDOWS_SSPI) || \
+ defined(USE_WIN32_LDAP)) && defined(UNICODE))
+
+ /*
+ * MultiByte conversions using Windows kernel32 library.
+ */
+
+#include "curl_multibyte.h"
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+wchar_t *Curl_convert_UTF8_to_wchar(const char *str_utf8)
+{
+ wchar_t *str_w = NULL;
+
+ if(str_utf8) {
+ int str_w_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
+ str_utf8, -1, NULL, 0);
+ if(str_w_len > 0) {
+ str_w = malloc(str_w_len * sizeof(wchar_t));
+ if(str_w) {
+ if(MultiByteToWideChar(CP_UTF8, 0, str_utf8, -1, str_w,
+ str_w_len) == 0) {
+ free(str_w);
+ return NULL;
+ }
+ }
+ }
+ }
+
+ return str_w;
+}
+
+char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w)
+{
+ char *str_utf8 = NULL;
+
+ if(str_w) {
+ int str_utf8_len = WideCharToMultiByte(CP_UTF8, 0, str_w, -1, NULL,
+ 0, NULL, NULL);
+ if(str_utf8_len > 0) {
+ str_utf8 = malloc(str_utf8_len * sizeof(wchar_t));
+ if(str_utf8) {
+ if(WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, str_utf8_len,
+ NULL, FALSE) == 0) {
+ free(str_utf8);
+ return NULL;
+ }
+ }
+ }
+ }
+
+ return str_utf8;
+}
+
+#endif /* USE_WIN32_IDN || ((USE_WINDOWS_SSPI || USE_WIN32_LDAP) && UNICODE) */
diff --git a/Utilities/cmcurl/lib/curl_multibyte.h b/Utilities/cmcurl/lib/curl_multibyte.h
new file mode 100644
index 000000000..dc7ed4c39
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_multibyte.h
@@ -0,0 +1,92 @@
+#ifndef HEADER_CURL_MULTIBYTE_H
+#define HEADER_CURL_MULTIBYTE_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#if defined(USE_WIN32_IDN) || ((defined(USE_WINDOWS_SSPI) || \
+ defined(USE_WIN32_LDAP)) && defined(UNICODE))
+
+ /*
+ * MultiByte conversions using Windows kernel32 library.
+ */
+
+wchar_t *Curl_convert_UTF8_to_wchar(const char *str_utf8);
+char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w);
+
+#endif /* USE_WIN32_IDN || ((USE_WINDOWS_SSPI || USE_WIN32_LDAP) && UNICODE) */
+
+
+#if defined(USE_WIN32_IDN) || defined(USE_WINDOWS_SSPI) || \
+ defined(USE_WIN32_LDAP)
+
+/*
+ * Macros Curl_convert_UTF8_to_tchar(), Curl_convert_tchar_to_UTF8()
+ * and Curl_unicodefree() main purpose is to minimize the number of
+ * preprocessor conditional directives needed by code using these
+ * to differentiate UNICODE from non-UNICODE builds.
+ *
+ * When building with UNICODE defined, this two macros
+ * Curl_convert_UTF8_to_tchar() and Curl_convert_tchar_to_UTF8()
+ * return a pointer to a newly allocated memory area holding result.
+ * When the result is no longer needed, allocated memory is intended
+ * to be free'ed with Curl_unicodefree().
+ *
+ * When building without UNICODE defined, this macros
+ * Curl_convert_UTF8_to_tchar() and Curl_convert_tchar_to_UTF8()
+ * return the pointer received as argument. Curl_unicodefree() does
+ * no actual free'ing of this pointer it is simply set to NULL.
+ */
+
+#ifdef UNICODE
+
+#define Curl_convert_UTF8_to_tchar(ptr) Curl_convert_UTF8_to_wchar((ptr))
+#define Curl_convert_tchar_to_UTF8(ptr) Curl_convert_wchar_to_UTF8((ptr))
+#define Curl_unicodefree(ptr) \
+ do {if((ptr)) {free((ptr)); (ptr) = NULL;}} WHILE_FALSE
+
+typedef union {
+ unsigned short *tchar_ptr;
+ const unsigned short *const_tchar_ptr;
+ unsigned short *tbyte_ptr;
+ const unsigned short *const_tbyte_ptr;
+} xcharp_u;
+
+#else
+
+#define Curl_convert_UTF8_to_tchar(ptr) (ptr)
+#define Curl_convert_tchar_to_UTF8(ptr) (ptr)
+#define Curl_unicodefree(ptr) \
+ do {(ptr) = NULL;} WHILE_FALSE
+
+typedef union {
+ char *tchar_ptr;
+ const char *const_tchar_ptr;
+ unsigned char *tbyte_ptr;
+ const unsigned char *const_tbyte_ptr;
+} xcharp_u;
+
+#endif /* UNICODE */
+
+#endif /* USE_WIN32_IDN || USE_WINDOWS_SSPI || USE_WIN32_LDAP */
+
+#endif /* HEADER_CURL_MULTIBYTE_H */
diff --git a/Utilities/cmcurl/lib/curl_ntlm.c b/Utilities/cmcurl/lib/curl_ntlm.c
new file mode 100644
index 000000000..f9ddf506d
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_ntlm.c
@@ -0,0 +1,239 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM)
+
+/*
+ * NTLM details:
+ *
+ * http://davenport.sourceforge.net/ntlm.html
+ * http://www.innovation.ch/java/ntlm.html
+ */
+
+#define DEBUG_ME 0
+
+#include "urldata.h"
+#include "sendf.h"
+#include "rawstr.h"
+#include "curl_ntlm.h"
+#include "curl_ntlm_msgs.h"
+#include "curl_ntlm_wb.h"
+#include "curl_sasl.h"
+#include "url.h"
+#include "curl_printf.h"
+
+#if defined(USE_NSS)
+#include "vtls/nssg.h"
+#elif defined(USE_WINDOWS_SSPI)
+#include "curl_sspi.h"
+#endif
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#if DEBUG_ME
+# define DEBUG_OUT(x) x
+#else
+# define DEBUG_OUT(x) Curl_nop_stmt
+#endif
+
+CURLcode Curl_input_ntlm(struct connectdata *conn,
+ bool proxy, /* if proxy or not */
+ const char *header) /* rest of the www-authenticate:
+ header */
+{
+ /* point to the correct struct with this */
+ struct ntlmdata *ntlm;
+ CURLcode result = CURLE_OK;
+
+ ntlm = proxy ? &conn->proxyntlm : &conn->ntlm;
+
+ if(checkprefix("NTLM", header)) {
+ header += strlen("NTLM");
+
+ while(*header && ISSPACE(*header))
+ header++;
+
+ if(*header) {
+ result = Curl_sasl_decode_ntlm_type2_message(conn->data, header, ntlm);
+ if(result)
+ return result;
+
+ ntlm->state = NTLMSTATE_TYPE2; /* We got a type-2 message */
+ }
+ else {
+ if(ntlm->state == NTLMSTATE_LAST) {
+ infof(conn->data, "NTLM auth restarted\n");
+ Curl_http_ntlm_cleanup(conn);
+ }
+ else if(ntlm->state == NTLMSTATE_TYPE3) {
+ infof(conn->data, "NTLM handshake rejected\n");
+ Curl_http_ntlm_cleanup(conn);
+ ntlm->state = NTLMSTATE_NONE;
+ return CURLE_REMOTE_ACCESS_DENIED;
+ }
+ else if(ntlm->state >= NTLMSTATE_TYPE1) {
+ infof(conn->data, "NTLM handshake failure (internal error)\n");
+ return CURLE_REMOTE_ACCESS_DENIED;
+ }
+
+ ntlm->state = NTLMSTATE_TYPE1; /* We should send away a type-1 */
+ }
+ }
+
+ return result;
+}
+
+/*
+ * This is for creating ntlm header output
+ */
+CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
+{
+ char *base64 = NULL;
+ size_t len = 0;
+ CURLcode result;
+
+ /* point to the address of the pointer that holds the string to send to the
+ server, which is for a plain host or for a HTTP proxy */
+ char **allocuserpwd;
+
+ /* point to the name and password for this */
+ const char *userp;
+ const char *passwdp;
+
+ /* point to the correct struct with this */
+ struct ntlmdata *ntlm;
+ struct auth *authp;
+
+ DEBUGASSERT(conn);
+ DEBUGASSERT(conn->data);
+
+#ifdef USE_NSS
+ if(CURLE_OK != Curl_nss_force_init(conn->data))
+ return CURLE_OUT_OF_MEMORY;
+#endif
+
+ if(proxy) {
+ allocuserpwd = &conn->allocptr.proxyuserpwd;
+ userp = conn->proxyuser;
+ passwdp = conn->proxypasswd;
+ ntlm = &conn->proxyntlm;
+ authp = &conn->data->state.authproxy;
+ }
+ else {
+ allocuserpwd = &conn->allocptr.userpwd;
+ userp = conn->user;
+ passwdp = conn->passwd;
+ ntlm = &conn->ntlm;
+ authp = &conn->data->state.authhost;
+ }
+ authp->done = FALSE;
+
+ /* not set means empty */
+ if(!userp)
+ userp = "";
+
+ if(!passwdp)
+ passwdp = "";
+
+#ifdef USE_WINDOWS_SSPI
+ if(s_hSecDll == NULL) {
+ /* not thread safe and leaks - use curl_global_init() to avoid */
+ CURLcode err = Curl_sspi_global_init();
+ if(s_hSecDll == NULL)
+ return err;
+ }
+#endif
+
+ switch(ntlm->state) {
+ case NTLMSTATE_TYPE1:
+ default: /* for the weird cases we (re)start here */
+ /* Create a type-1 message */
+ result = Curl_sasl_create_ntlm_type1_message(userp, passwdp, ntlm, &base64,
+ &len);
+ if(result)
+ return result;
+
+ if(base64) {
+ free(*allocuserpwd);
+ *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
+ proxy ? "Proxy-" : "",
+ base64);
+ free(base64);
+ if(!*allocuserpwd)
+ return CURLE_OUT_OF_MEMORY;
+
+ DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd));
+ }
+ break;
+
+ case NTLMSTATE_TYPE2:
+ /* We already received the type-2 message, create a type-3 message */
+ result = Curl_sasl_create_ntlm_type3_message(conn->data, userp, passwdp,
+ ntlm, &base64, &len);
+ if(result)
+ return result;
+
+ if(base64) {
+ free(*allocuserpwd);
+ *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
+ proxy ? "Proxy-" : "",
+ base64);
+ free(base64);
+ if(!*allocuserpwd)
+ return CURLE_OUT_OF_MEMORY;
+
+ DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
+
+ ntlm->state = NTLMSTATE_TYPE3; /* we send a type-3 */
+ authp->done = TRUE;
+ }
+ break;
+
+ case NTLMSTATE_TYPE3:
+ /* connection is already authenticated,
+ * don't send a header in future requests */
+ ntlm->state = NTLMSTATE_LAST;
+
+ case NTLMSTATE_LAST:
+ Curl_safefree(*allocuserpwd);
+ authp->done = TRUE;
+ break;
+ }
+
+ return CURLE_OK;
+}
+
+void Curl_http_ntlm_cleanup(struct connectdata *conn)
+{
+ Curl_sasl_ntlm_cleanup(&conn->ntlm);
+ Curl_sasl_ntlm_cleanup(&conn->proxyntlm);
+
+#if defined(NTLM_WB_ENABLED)
+ Curl_ntlm_wb_cleanup(conn);
+#endif
+}
+
+#endif /* !CURL_DISABLE_HTTP && USE_NTLM */
diff --git a/Utilities/cmcurl/lib/curl_ntlm.h b/Utilities/cmcurl/lib/curl_ntlm.h
new file mode 100644
index 000000000..947eac20d
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_ntlm.h
@@ -0,0 +1,40 @@
+#ifndef HEADER_CURL_NTLM_H
+#define HEADER_CURL_NTLM_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM)
+
+/* this is for ntlm header input */
+CURLcode Curl_input_ntlm(struct connectdata *conn, bool proxy,
+ const char *header);
+
+/* this is for creating ntlm header output */
+CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy);
+
+void Curl_http_ntlm_cleanup(struct connectdata *conn);
+
+#endif /* !CURL_DISABLE_HTTP && USE_NTLM */
+
+#endif /* HEADER_CURL_NTLM_H */
diff --git a/Utilities/cmcurl/lib/curl_ntlm_core.c b/Utilities/cmcurl/lib/curl_ntlm_core.c
new file mode 100644
index 000000000..2e5b573fd
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_ntlm_core.c
@@ -0,0 +1,765 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_NTLM)
+
+/*
+ * NTLM details:
+ *
+ * http://davenport.sourceforge.net/ntlm.html
+ * http://www.innovation.ch/java/ntlm.html
+ */
+
+#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
+
+#ifdef USE_OPENSSL
+
+# ifdef USE_OPENSSL
+# include <openssl/des.h>
+# ifndef OPENSSL_NO_MD4
+# include <openssl/md4.h>
+# endif
+# include <openssl/md5.h>
+# include <openssl/ssl.h>
+# include <openssl/rand.h>
+# else
+# include <des.h>
+# ifndef OPENSSL_NO_MD4
+# include <md4.h>
+# endif
+# include <md5.h>
+# include <ssl.h>
+# include <rand.h>
+# endif
+# if (OPENSSL_VERSION_NUMBER < 0x00907001L)
+# define DES_key_schedule des_key_schedule
+# define DES_cblock des_cblock
+# define DES_set_odd_parity des_set_odd_parity
+# define DES_set_key des_set_key
+# define DES_ecb_encrypt des_ecb_encrypt
+# define DESKEY(x) x
+# define DESKEYARG(x) x
+# else
+# define DESKEYARG(x) *x
+# define DESKEY(x) &x
+# endif
+
+#elif defined(USE_GNUTLS_NETTLE)
+
+# include <nettle/des.h>
+# include <nettle/md4.h>
+
+#elif defined(USE_GNUTLS)
+
+# include <gcrypt.h>
+# define MD5_DIGEST_LENGTH 16
+# define MD4_DIGEST_LENGTH 16
+
+#elif defined(USE_NSS)
+
+# include <nss.h>
+# include <pk11pub.h>
+# include <hasht.h>
+# include "curl_md4.h"
+# define MD5_DIGEST_LENGTH MD5_LENGTH
+
+#elif defined(USE_DARWINSSL)
+
+# include <CommonCrypto/CommonCryptor.h>
+# include <CommonCrypto/CommonDigest.h>
+
+#elif defined(USE_OS400CRYPTO)
+# include "cipher.mih" /* mih/cipher */
+# include "curl_md4.h"
+#elif defined(USE_WIN32_CRYPTO)
+# include <wincrypt.h>
+#else
+# error "Can't compile NTLM support without a crypto library."
+#endif
+
+#include "urldata.h"
+#include "non-ascii.h"
+#include "rawstr.h"
+#include "curl_ntlm_core.h"
+#include "curl_md5.h"
+#include "curl_hmac.h"
+#include "warnless.h"
+#include "curl_endian.h"
+#include "curl_des.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define NTLM_HMAC_MD5_LEN (16)
+#define NTLMv2_BLOB_SIGNATURE "\x01\x01\x00\x00"
+#define NTLMv2_BLOB_LEN (44 -16 + ntlm->target_info_len + 4)
+
+/*
+* Turns a 56-bit key into being 64-bit wide.
+*/
+static void extend_key_56_to_64(const unsigned char *key_56, char *key)
+{
+ key[0] = key_56[0];
+ key[1] = (unsigned char)(((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1));
+ key[2] = (unsigned char)(((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2));
+ key[3] = (unsigned char)(((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3));
+ key[4] = (unsigned char)(((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4));
+ key[5] = (unsigned char)(((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5));
+ key[6] = (unsigned char)(((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6));
+ key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF);
+}
+
+#ifdef USE_OPENSSL
+/*
+ * Turns a 56 bit key into the 64 bit, odd parity key and sets the key. The
+ * key schedule ks is also set.
+ */
+static void setup_des_key(const unsigned char *key_56,
+ DES_key_schedule DESKEYARG(ks))
+{
+ DES_cblock key;
+
+ /* Expand the 56-bit key to 64-bits */
+ extend_key_56_to_64(key_56, (char *) key);
+
+ /* Set the key parity to odd */
+#if defined(HAVE_BORINGSSL)
+ Curl_des_set_odd_parity((unsigned char *) &key, sizeof(key));
+#else
+ DES_set_odd_parity(&key);
+#endif
+
+ /* Set the key */
+ DES_set_key(&key, ks);
+}
+
+#elif defined(USE_GNUTLS_NETTLE)
+
+static void setup_des_key(const unsigned char *key_56,
+ struct des_ctx *des)
+{
+ char key[8];
+
+ /* Expand the 56-bit key to 64-bits */
+ extend_key_56_to_64(key_56, key);
+
+ /* Set the key parity to odd */
+ Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
+
+ /* Set the key */
+ des_set_key(des, (const uint8_t *) key);
+}
+
+#elif defined(USE_GNUTLS)
+
+/*
+ * Turns a 56 bit key into the 64 bit, odd parity key and sets the key.
+ */
+static void setup_des_key(const unsigned char *key_56,
+ gcry_cipher_hd_t *des)
+{
+ char key[8];
+
+ /* Expand the 56-bit key to 64-bits */
+ extend_key_56_to_64(key_56, key);
+
+ /* Set the key parity to odd */
+ Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
+
+ /* Set the key */
+ gcry_cipher_setkey(*des, key, sizeof(key));
+}
+
+#elif defined(USE_NSS)
+
+/*
+ * Expands a 56 bit key KEY_56 to 64 bit and encrypts 64 bit of data, using
+ * the expanded key. The caller is responsible for giving 64 bit of valid
+ * data is IN and (at least) 64 bit large buffer as OUT.
+ */
+static bool encrypt_des(const unsigned char *in, unsigned char *out,
+ const unsigned char *key_56)
+{
+ const CK_MECHANISM_TYPE mech = CKM_DES_ECB; /* DES cipher in ECB mode */
+ PK11SlotInfo *slot = NULL;
+ char key[8]; /* expanded 64 bit key */
+ SECItem key_item;
+ PK11SymKey *symkey = NULL;
+ SECItem *param = NULL;
+ PK11Context *ctx = NULL;
+ int out_len; /* not used, required by NSS */
+ bool rv = FALSE;
+
+ /* use internal slot for DES encryption (requires NSS to be initialized) */
+ slot = PK11_GetInternalKeySlot();
+ if(!slot)
+ return FALSE;
+
+ /* Expand the 56-bit key to 64-bits */
+ extend_key_56_to_64(key_56, key);
+
+ /* Set the key parity to odd */
+ Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
+
+ /* Import the key */
+ key_item.data = (unsigned char *)key;
+ key_item.len = sizeof(key);
+ symkey = PK11_ImportSymKey(slot, mech, PK11_OriginUnwrap, CKA_ENCRYPT,
+ &key_item, NULL);
+ if(!symkey)
+ goto fail;
+
+ /* Create the DES encryption context */
+ param = PK11_ParamFromIV(mech, /* no IV in ECB mode */ NULL);
+ if(!param)
+ goto fail;
+ ctx = PK11_CreateContextBySymKey(mech, CKA_ENCRYPT, symkey, param);
+ if(!ctx)
+ goto fail;
+
+ /* Perform the encryption */
+ if(SECSuccess == PK11_CipherOp(ctx, out, &out_len, /* outbuflen */ 8,
+ (unsigned char *)in, /* inbuflen */ 8)
+ && SECSuccess == PK11_Finalize(ctx))
+ rv = /* all OK */ TRUE;
+
+fail:
+ /* cleanup */
+ if(ctx)
+ PK11_DestroyContext(ctx, PR_TRUE);
+ if(symkey)
+ PK11_FreeSymKey(symkey);
+ if(param)
+ SECITEM_FreeItem(param, PR_TRUE);
+ PK11_FreeSlot(slot);
+ return rv;
+}
+
+#elif defined(USE_DARWINSSL)
+
+static bool encrypt_des(const unsigned char *in, unsigned char *out,
+ const unsigned char *key_56)
+{
+ char key[8];
+ size_t out_len;
+ CCCryptorStatus err;
+
+ /* Expand the 56-bit key to 64-bits */
+ extend_key_56_to_64(key_56, key);
+
+ /* Set the key parity to odd */
+ Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
+
+ /* Perform the encryption */
+ err = CCCrypt(kCCEncrypt, kCCAlgorithmDES, kCCOptionECBMode, key,
+ kCCKeySizeDES, NULL, in, 8 /* inbuflen */, out,
+ 8 /* outbuflen */, &out_len);
+
+ return err == kCCSuccess;
+}
+
+#elif defined(USE_OS400CRYPTO)
+
+static bool encrypt_des(const unsigned char *in, unsigned char *out,
+ const unsigned char *key_56)
+{
+ char key[8];
+ _CIPHER_Control_T ctl;
+
+ /* Setup the cipher control structure */
+ ctl.Func_ID = ENCRYPT_ONLY;
+ ctl.Data_Len = sizeof(key);
+
+ /* Expand the 56-bit key to 64-bits */
+ extend_key_56_to_64(key_56, ctl.Crypto_Key);
+
+ /* Set the key parity to odd */
+ Curl_des_set_odd_parity((unsigned char *) ctl.Crypto_Key, ctl.Data_Len);
+
+ /* Perform the encryption */
+ _CIPHER((_SPCPTR *) &out, &ctl, (_SPCPTR *) &in);
+
+ return TRUE;
+}
+
+#elif defined(USE_WIN32_CRYPTO)
+
+static bool encrypt_des(const unsigned char *in, unsigned char *out,
+ const unsigned char *key_56)
+{
+ HCRYPTPROV hprov;
+ HCRYPTKEY hkey;
+ struct {
+ BLOBHEADER hdr;
+ unsigned int len;
+ char key[8];
+ } blob;
+ DWORD len = 8;
+
+ /* Acquire the crypto provider */
+ if(!CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT))
+ return FALSE;
+
+ /* Setup the key blob structure */
+ memset(&blob, 0, sizeof(blob));
+ blob.hdr.bType = PLAINTEXTKEYBLOB;
+ blob.hdr.bVersion = 2;
+ blob.hdr.aiKeyAlg = CALG_DES;
+ blob.len = sizeof(blob.key);
+
+ /* Expand the 56-bit key to 64-bits */
+ extend_key_56_to_64(key_56, blob.key);
+
+ /* Set the key parity to odd */
+ Curl_des_set_odd_parity((unsigned char *) blob.key, sizeof(blob.key));
+
+ /* Import the key */
+ if(!CryptImportKey(hprov, (BYTE *) &blob, sizeof(blob), 0, 0, &hkey)) {
+ CryptReleaseContext(hprov, 0);
+
+ return FALSE;
+ }
+
+ memcpy(out, in, 8);
+
+ /* Perform the encryption */
+ CryptEncrypt(hkey, 0, FALSE, 0, out, &len, len);
+
+ CryptDestroyKey(hkey);
+ CryptReleaseContext(hprov, 0);
+
+ return TRUE;
+}
+
+#endif /* defined(USE_WIN32_CRYPTO) */
+
+ /*
+ * takes a 21 byte array and treats it as 3 56-bit DES keys. The
+ * 8 byte plaintext is encrypted with each key and the resulting 24
+ * bytes are stored in the results array.
+ */
+void Curl_ntlm_core_lm_resp(const unsigned char *keys,
+ const unsigned char *plaintext,
+ unsigned char *results)
+{
+#ifdef USE_OPENSSL
+ DES_key_schedule ks;
+
+ setup_des_key(keys, DESKEY(ks));
+ DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) results,
+ DESKEY(ks), DES_ENCRYPT);
+
+ setup_des_key(keys + 7, DESKEY(ks));
+ DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 8),
+ DESKEY(ks), DES_ENCRYPT);
+
+ setup_des_key(keys + 14, DESKEY(ks));
+ DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 16),
+ DESKEY(ks), DES_ENCRYPT);
+#elif defined(USE_GNUTLS_NETTLE)
+ struct des_ctx des;
+ setup_des_key(keys, &des);
+ des_encrypt(&des, 8, results, plaintext);
+ setup_des_key(keys + 7, &des);
+ des_encrypt(&des, 8, results + 8, plaintext);
+ setup_des_key(keys + 14, &des);
+ des_encrypt(&des, 8, results + 16, plaintext);
+#elif defined(USE_GNUTLS)
+ gcry_cipher_hd_t des;
+
+ gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
+ setup_des_key(keys, &des);
+ gcry_cipher_encrypt(des, results, 8, plaintext, 8);
+ gcry_cipher_close(des);
+
+ gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
+ setup_des_key(keys + 7, &des);
+ gcry_cipher_encrypt(des, results + 8, 8, plaintext, 8);
+ gcry_cipher_close(des);
+
+ gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
+ setup_des_key(keys + 14, &des);
+ gcry_cipher_encrypt(des, results + 16, 8, plaintext, 8);
+ gcry_cipher_close(des);
+#elif defined(USE_NSS) || defined(USE_DARWINSSL) || defined(USE_OS400CRYPTO) \
+ || defined(USE_WIN32_CRYPTO)
+ encrypt_des(plaintext, results, keys);
+ encrypt_des(plaintext, results + 8, keys + 7);
+ encrypt_des(plaintext, results + 16, keys + 14);
+#endif
+}
+
+/*
+ * Set up lanmanager hashed password
+ */
+CURLcode Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data,
+ const char *password,
+ unsigned char *lmbuffer /* 21 bytes */)
+{
+ CURLcode result;
+ unsigned char pw[14];
+ static const unsigned char magic[] = {
+ 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */
+ };
+ size_t len = CURLMIN(strlen(password), 14);
+
+ Curl_strntoupper((char *)pw, password, len);
+ memset(&pw[len], 0, 14 - len);
+
+ /*
+ * The LanManager hashed password needs to be created using the
+ * password in the network encoding not the host encoding.
+ */
+ result = Curl_convert_to_network(data, (char *)pw, 14);
+ if(result)
+ return result;
+
+ {
+ /* Create LanManager hashed password. */
+
+#ifdef USE_OPENSSL
+ DES_key_schedule ks;
+
+ setup_des_key(pw, DESKEY(ks));
+ DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer,
+ DESKEY(ks), DES_ENCRYPT);
+
+ setup_des_key(pw + 7, DESKEY(ks));
+ DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer + 8),
+ DESKEY(ks), DES_ENCRYPT);
+#elif defined(USE_GNUTLS_NETTLE)
+ struct des_ctx des;
+ setup_des_key(pw, &des);
+ des_encrypt(&des, 8, lmbuffer, magic);
+ setup_des_key(pw + 7, &des);
+ des_encrypt(&des, 8, lmbuffer + 8, magic);
+#elif defined(USE_GNUTLS)
+ gcry_cipher_hd_t des;
+
+ gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
+ setup_des_key(pw, &des);
+ gcry_cipher_encrypt(des, lmbuffer, 8, magic, 8);
+ gcry_cipher_close(des);
+
+ gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
+ setup_des_key(pw + 7, &des);
+ gcry_cipher_encrypt(des, lmbuffer + 8, 8, magic, 8);
+ gcry_cipher_close(des);
+#elif defined(USE_NSS) || defined(USE_DARWINSSL) || defined(USE_OS400CRYPTO) \
+ || defined(USE_WIN32_CRYPTO)
+ encrypt_des(magic, lmbuffer, pw);
+ encrypt_des(magic, lmbuffer + 8, pw + 7);
+#endif
+
+ memset(lmbuffer + 16, 0, 21 - 16);
+ }
+
+ return CURLE_OK;
+}
+
+#if USE_NTRESPONSES
+static void ascii_to_unicode_le(unsigned char *dest, const char *src,
+ size_t srclen)
+{
+ size_t i;
+ for(i = 0; i < srclen; i++) {
+ dest[2 * i] = (unsigned char)src[i];
+ dest[2 * i + 1] = '\0';
+ }
+}
+
+#if USE_NTLM_V2 && !defined(USE_WINDOWS_SSPI)
+
+static void ascii_uppercase_to_unicode_le(unsigned char *dest,
+ const char *src, size_t srclen)
+{
+ size_t i;
+ for(i = 0; i < srclen; i++) {
+ dest[2 * i] = (unsigned char)(toupper(src[i]));
+ dest[2 * i + 1] = '\0';
+ }
+}
+
+#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */
+
+/*
+ * Set up nt hashed passwords
+ * @unittest: 1600
+ */
+CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data,
+ const char *password,
+ unsigned char *ntbuffer /* 21 bytes */)
+{
+ size_t len = strlen(password);
+ unsigned char *pw = malloc(len * 2);
+ CURLcode result;
+ if(!pw)
+ return CURLE_OUT_OF_MEMORY;
+
+ ascii_to_unicode_le(pw, password, len);
+
+ /*
+ * The NT hashed password needs to be created using the password in the
+ * network encoding not the host encoding.
+ */
+ result = Curl_convert_to_network(data, (char *)pw, len * 2);
+ if(result)
+ return result;
+
+ {
+ /* Create NT hashed password. */
+#ifdef USE_OPENSSL
+ MD4_CTX MD4pw;
+ MD4_Init(&MD4pw);
+ MD4_Update(&MD4pw, pw, 2 * len);
+ MD4_Final(ntbuffer, &MD4pw);
+#elif defined(USE_GNUTLS_NETTLE)
+ struct md4_ctx MD4pw;
+ md4_init(&MD4pw);
+ md4_update(&MD4pw, (unsigned int)(2 * len), pw);
+ md4_digest(&MD4pw, MD4_DIGEST_SIZE, ntbuffer);
+#elif defined(USE_GNUTLS)
+ gcry_md_hd_t MD4pw;
+ gcry_md_open(&MD4pw, GCRY_MD_MD4, 0);
+ gcry_md_write(MD4pw, pw, 2 * len);
+ memcpy (ntbuffer, gcry_md_read (MD4pw, 0), MD4_DIGEST_LENGTH);
+ gcry_md_close(MD4pw);
+#elif defined(USE_NSS) || defined(USE_OS400CRYPTO)
+ Curl_md4it(ntbuffer, pw, 2 * len);
+#elif defined(USE_DARWINSSL)
+ (void)CC_MD4(pw, (CC_LONG)(2 * len), ntbuffer);
+#elif defined(USE_WIN32_CRYPTO)
+ HCRYPTPROV hprov;
+ if(CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT)) {
+ HCRYPTHASH hhash;
+ if(CryptCreateHash(hprov, CALG_MD4, 0, 0, &hhash)) {
+ DWORD length = 16;
+ CryptHashData(hhash, pw, (unsigned int)len * 2, 0);
+ CryptGetHashParam(hhash, HP_HASHVAL, ntbuffer, &length, 0);
+ CryptDestroyHash(hhash);
+ }
+ CryptReleaseContext(hprov, 0);
+ }
+#endif
+
+ memset(ntbuffer + 16, 0, 21 - 16);
+ }
+
+ free(pw);
+
+ return CURLE_OK;
+}
+
+#if USE_NTLM_V2 && !defined(USE_WINDOWS_SSPI)
+
+/* This returns the HMAC MD5 digest */
+CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen,
+ const unsigned char *data, unsigned int datalen,
+ unsigned char *output)
+{
+ HMAC_context *ctxt = Curl_HMAC_init(Curl_HMAC_MD5, key, keylen);
+
+ if(!ctxt)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Update the digest with the given challenge */
+ Curl_HMAC_update(ctxt, data, datalen);
+
+ /* Finalise the digest */
+ Curl_HMAC_final(ctxt, output);
+
+ return CURLE_OK;
+}
+
+/* This creates the NTLMv2 hash by using NTLM hash as the key and Unicode
+ * (uppercase UserName + Domain) as the data
+ */
+CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
+ const char *domain, size_t domlen,
+ unsigned char *ntlmhash,
+ unsigned char *ntlmv2hash)
+{
+ /* Unicode representation */
+ size_t identity_len = (userlen + domlen) * 2;
+ unsigned char *identity = malloc(identity_len);
+ CURLcode result = CURLE_OK;
+
+ if(!identity)
+ return CURLE_OUT_OF_MEMORY;
+
+ ascii_uppercase_to_unicode_le(identity, user, userlen);
+ ascii_to_unicode_le(identity + (userlen << 1), domain, domlen);
+
+ result = Curl_hmac_md5(ntlmhash, 16, identity, curlx_uztoui(identity_len),
+ ntlmv2hash);
+
+ free(identity);
+
+ return result;
+}
+
+/*
+ * Curl_ntlm_core_mk_ntlmv2_resp()
+ *
+ * This creates the NTLMv2 response as set in the ntlm type-3 message.
+ *
+ * Parameters:
+ *
+ * ntlmv2hash [in] - The ntlmv2 hash (16 bytes)
+ * challenge_client [in] - The client nonce (8 bytes)
+ * ntlm [in] - The ntlm data struct being used to read TargetInfo
+ and Server challenge received in the type-2 message
+ * ntresp [out] - The address where a pointer to newly allocated
+ * memory holding the NTLMv2 response.
+ * ntresp_len [out] - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
+ unsigned char *challenge_client,
+ struct ntlmdata *ntlm,
+ unsigned char **ntresp,
+ unsigned int *ntresp_len)
+{
+/* NTLMv2 response structure :
+------------------------------------------------------------------------------
+0 HMAC MD5 16 bytes
+------BLOB--------------------------------------------------------------------
+16 Signature 0x01010000
+20 Reserved long (0x00000000)
+24 Timestamp LE, 64-bit signed value representing the number of
+ tenths of a microsecond since January 1, 1601.
+32 Client Nonce 8 bytes
+40 Unknown 4 bytes
+44 Target Info N bytes (from the type-2 message)
+44+N Unknown 4 bytes
+------------------------------------------------------------------------------
+*/
+
+ unsigned int len = 0;
+ unsigned char *ptr = NULL;
+ unsigned char hmac_output[NTLM_HMAC_MD5_LEN];
+#if defined(HAVE_LONGLONG)
+ long long tw;
+#else
+ __int64 tw;
+#endif
+ CURLcode result = CURLE_OK;
+
+ /* Calculate the timestamp */
+#ifdef DEBUGBUILD
+ char *force_timestamp = getenv("CURL_FORCETIME");
+ if(force_timestamp)
+ tw = 11644473600ULL * 10000000ULL;
+ else
+#endif
+ tw = ((long long)time(NULL) + 11644473600ULL) * 10000000ULL;
+
+ /* Calculate the response len */
+ len = NTLM_HMAC_MD5_LEN + NTLMv2_BLOB_LEN;
+
+ /* Allocate the response */
+ ptr = malloc(len);
+ if(!ptr)
+ return CURLE_OUT_OF_MEMORY;
+
+ memset(ptr, 0, len);
+
+ /* Create the BLOB structure */
+ snprintf((char *)ptr + NTLM_HMAC_MD5_LEN, NTLMv2_BLOB_LEN,
+ NTLMv2_BLOB_SIGNATURE
+ "%c%c%c%c", /* Reserved = 0 */
+ 0, 0, 0, 0);
+
+ Curl_write64_le(tw, ptr + 24);
+ memcpy(ptr + 32, challenge_client, 8);
+ memcpy(ptr + 44, ntlm->target_info, ntlm->target_info_len);
+
+ /* Concatenate the Type 2 challenge with the BLOB and do HMAC MD5 */
+ memcpy(ptr + 8, &ntlm->nonce[0], 8);
+ result = Curl_hmac_md5(ntlmv2hash, NTLM_HMAC_MD5_LEN, ptr + 8,
+ NTLMv2_BLOB_LEN + 8, hmac_output);
+ if(result) {
+ free(ptr);
+ return result;
+ }
+
+ /* Concatenate the HMAC MD5 output with the BLOB */
+ memcpy(ptr, hmac_output, NTLM_HMAC_MD5_LEN);
+
+ /* Return the response */
+ *ntresp = ptr;
+ *ntresp_len = len;
+
+ return result;
+}
+
+/*
+ * Curl_ntlm_core_mk_lmv2_resp()
+ *
+ * This creates the LMv2 response as used in the ntlm type-3 message.
+ *
+ * Parameters:
+ *
+ * ntlmv2hash [in] - The ntlmv2 hash (16 bytes)
+ * challenge_client [in] - The client nonce (8 bytes)
+ * challenge_client [in] - The server challenge (8 bytes)
+ * lmresp [out] - The LMv2 response (24 bytes)
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash,
+ unsigned char *challenge_client,
+ unsigned char *challenge_server,
+ unsigned char *lmresp)
+{
+ unsigned char data[16];
+ unsigned char hmac_output[16];
+ CURLcode result = CURLE_OK;
+
+ memcpy(&data[0], challenge_server, 8);
+ memcpy(&data[8], challenge_client, 8);
+
+ result = Curl_hmac_md5(ntlmv2hash, 16, &data[0], 16, hmac_output);
+ if(result)
+ return result;
+
+ /* Concatenate the HMAC MD5 output with the client nonce */
+ memcpy(lmresp, hmac_output, 16);
+ memcpy(lmresp+16, challenge_client, 8);
+
+ return result;
+}
+
+#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */
+
+#endif /* USE_NTRESPONSES */
+
+#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
+
+#endif /* USE_NTLM */
diff --git a/Utilities/cmcurl/lib/curl_ntlm_core.h b/Utilities/cmcurl/lib/curl_ntlm_core.h
new file mode 100644
index 000000000..3a763592a
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_ntlm_core.h
@@ -0,0 +1,106 @@
+#ifndef HEADER_CURL_NTLM_CORE_H
+#define HEADER_CURL_NTLM_CORE_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_NTLM)
+
+#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
+
+#ifdef USE_OPENSSL
+# if !defined(OPENSSL_VERSION_NUMBER) && \
+ !defined(HEADER_SSL_H) && !defined(HEADER_MD5_H)
+# error "curl_ntlm_core.h shall not be included before OpenSSL headers."
+# endif
+# ifdef OPENSSL_NO_MD4
+# define USE_NTRESPONSES 0
+# define USE_NTLM2SESSION 0
+# define USE_NTLM_V2 0
+# endif
+#endif
+
+/* Define USE_NTRESPONSES to 1 in order to make the type-3 message include
+ * the NT response message. */
+#ifndef USE_NTRESPONSES
+#define USE_NTRESPONSES 1
+#endif
+
+/* Define USE_NTLM2SESSION to 1 in order to make the type-3 message include the
+ NTLM2Session response message, requires USE_NTRESPONSES defined to 1 and a
+ Crypto engine that we have curl_ssl_md5sum() for. */
+#if !defined(USE_NTLM2SESSION) && USE_NTRESPONSES && !defined(USE_WIN32_CRYPTO)
+#define USE_NTLM2SESSION 1
+#endif
+
+/* Define USE_NTLM_V2 to 1 in order to allow the type-3 message to include the
+ LMv2 and NTLMv2 response messages, requires USE_NTRESPONSES defined to 1
+ and support for 64-bit integers. */
+#if !defined(USE_NTLM_V2) && USE_NTRESPONSES && (CURL_SIZEOF_CURL_OFF_T > 4)
+#define USE_NTLM_V2 1
+#endif
+
+void Curl_ntlm_core_lm_resp(const unsigned char *keys,
+ const unsigned char *plaintext,
+ unsigned char *results);
+
+CURLcode Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data,
+ const char *password,
+ unsigned char *lmbuffer /* 21 bytes */);
+
+#if USE_NTRESPONSES
+CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data,
+ const char *password,
+ unsigned char *ntbuffer /* 21 bytes */);
+
+#if USE_NTLM_V2 && !defined(USE_WINDOWS_SSPI)
+
+CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen,
+ const unsigned char *data, unsigned int datalen,
+ unsigned char *output);
+
+CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
+ const char *domain, size_t domlen,
+ unsigned char *ntlmhash,
+ unsigned char *ntlmv2hash);
+
+CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
+ unsigned char *challenge_client,
+ struct ntlmdata *ntlm,
+ unsigned char **ntresp,
+ unsigned int *ntresp_len);
+
+CURLcode Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash,
+ unsigned char *challenge_client,
+ unsigned char *challenge_server,
+ unsigned char *lmresp);
+
+#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */
+
+#endif /* USE_NTRESPONSES */
+
+#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
+
+#endif /* USE_NTLM */
+
+#endif /* HEADER_CURL_NTLM_CORE_H */
diff --git a/Utilities/cmcurl/lib/curl_ntlm_msgs.c b/Utilities/cmcurl/lib/curl_ntlm_msgs.c
new file mode 100644
index 000000000..7f07decb8
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_ntlm_msgs.c
@@ -0,0 +1,817 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_NTLM) && !defined(USE_WINDOWS_SSPI)
+
+/*
+ * NTLM details:
+ *
+ * http://davenport.sourceforge.net/ntlm.html
+ * http://www.innovation.ch/java/ntlm.html
+ */
+
+#define DEBUG_ME 0
+
+#include "urldata.h"
+#include "non-ascii.h"
+#include "sendf.h"
+#include "curl_base64.h"
+#include "curl_ntlm_core.h"
+#include "curl_gethostname.h"
+#include "curl_multibyte.h"
+#include "warnless.h"
+
+#include "vtls/vtls.h"
+
+#ifdef USE_NSS
+#include "vtls/nssg.h" /* for Curl_nss_force_init() */
+#endif
+
+#define BUILDING_CURL_NTLM_MSGS_C
+#include "curl_ntlm_msgs.h"
+#include "curl_sasl.h"
+#include "curl_endian.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* "NTLMSSP" signature is always in ASCII regardless of the platform */
+#define NTLMSSP_SIGNATURE "\x4e\x54\x4c\x4d\x53\x53\x50"
+
+#define SHORTPAIR(x) ((x) & 0xff), (((x) >> 8) & 0xff)
+#define LONGQUARTET(x) ((x) & 0xff), (((x) >> 8) & 0xff), \
+ (((x) >> 16) & 0xff), (((x) >> 24) & 0xff)
+
+#if DEBUG_ME
+# define DEBUG_OUT(x) x
+static void ntlm_print_flags(FILE *handle, unsigned long flags)
+{
+ if(flags & NTLMFLAG_NEGOTIATE_UNICODE)
+ fprintf(handle, "NTLMFLAG_NEGOTIATE_UNICODE ");
+ if(flags & NTLMFLAG_NEGOTIATE_OEM)
+ fprintf(handle, "NTLMFLAG_NEGOTIATE_OEM ");
+ if(flags & NTLMFLAG_REQUEST_TARGET)
+ fprintf(handle, "NTLMFLAG_REQUEST_TARGET ");
+ if(flags & (1<<3))
+ fprintf(handle, "NTLMFLAG_UNKNOWN_3 ");
+ if(flags & NTLMFLAG_NEGOTIATE_SIGN)
+ fprintf(handle, "NTLMFLAG_NEGOTIATE_SIGN ");
+ if(flags & NTLMFLAG_NEGOTIATE_SEAL)
+ fprintf(handle, "NTLMFLAG_NEGOTIATE_SEAL ");
+ if(flags & NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE)
+ fprintf(handle, "NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE ");
+ if(flags & NTLMFLAG_NEGOTIATE_LM_KEY)
+ fprintf(handle, "NTLMFLAG_NEGOTIATE_LM_KEY ");
+ if(flags & NTLMFLAG_NEGOTIATE_NETWARE)
+ fprintf(handle, "NTLMFLAG_NEGOTIATE_NETWARE ");
+ if(flags & NTLMFLAG_NEGOTIATE_NTLM_KEY)
+ fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM_KEY ");
+ if(flags & (1<<10))
+ fprintf(handle, "NTLMFLAG_UNKNOWN_10 ");
+ if(flags & NTLMFLAG_NEGOTIATE_ANONYMOUS)
+ fprintf(handle, "NTLMFLAG_NEGOTIATE_ANONYMOUS ");
+ if(flags & NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED)
+ fprintf(handle, "NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED ");
+ if(flags & NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED)
+ fprintf(handle, "NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED ");
+ if(flags & NTLMFLAG_NEGOTIATE_LOCAL_CALL)
+ fprintf(handle, "NTLMFLAG_NEGOTIATE_LOCAL_CALL ");
+ if(flags & NTLMFLAG_NEGOTIATE_ALWAYS_SIGN)
+ fprintf(handle, "NTLMFLAG_NEGOTIATE_ALWAYS_SIGN ");
+ if(flags & NTLMFLAG_TARGET_TYPE_DOMAIN)
+ fprintf(handle, "NTLMFLAG_TARGET_TYPE_DOMAIN ");
+ if(flags & NTLMFLAG_TARGET_TYPE_SERVER)
+ fprintf(handle, "NTLMFLAG_TARGET_TYPE_SERVER ");
+ if(flags & NTLMFLAG_TARGET_TYPE_SHARE)
+ fprintf(handle, "NTLMFLAG_TARGET_TYPE_SHARE ");
+ if(flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY)
+ fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM2_KEY ");
+ if(flags & NTLMFLAG_REQUEST_INIT_RESPONSE)
+ fprintf(handle, "NTLMFLAG_REQUEST_INIT_RESPONSE ");
+ if(flags & NTLMFLAG_REQUEST_ACCEPT_RESPONSE)
+ fprintf(handle, "NTLMFLAG_REQUEST_ACCEPT_RESPONSE ");
+ if(flags & NTLMFLAG_REQUEST_NONNT_SESSION_KEY)
+ fprintf(handle, "NTLMFLAG_REQUEST_NONNT_SESSION_KEY ");
+ if(flags & NTLMFLAG_NEGOTIATE_TARGET_INFO)
+ fprintf(handle, "NTLMFLAG_NEGOTIATE_TARGET_INFO ");
+ if(flags & (1<<24))
+ fprintf(handle, "NTLMFLAG_UNKNOWN_24 ");
+ if(flags & (1<<25))
+ fprintf(handle, "NTLMFLAG_UNKNOWN_25 ");
+ if(flags & (1<<26))
+ fprintf(handle, "NTLMFLAG_UNKNOWN_26 ");
+ if(flags & (1<<27))
+ fprintf(handle, "NTLMFLAG_UNKNOWN_27 ");
+ if(flags & (1<<28))
+ fprintf(handle, "NTLMFLAG_UNKNOWN_28 ");
+ if(flags & NTLMFLAG_NEGOTIATE_128)
+ fprintf(handle, "NTLMFLAG_NEGOTIATE_128 ");
+ if(flags & NTLMFLAG_NEGOTIATE_KEY_EXCHANGE)
+ fprintf(handle, "NTLMFLAG_NEGOTIATE_KEY_EXCHANGE ");
+ if(flags & NTLMFLAG_NEGOTIATE_56)
+ fprintf(handle, "NTLMFLAG_NEGOTIATE_56 ");
+}
+
+static void ntlm_print_hex(FILE *handle, const char *buf, size_t len)
+{
+ const char *p = buf;
+ (void)handle;
+ fprintf(stderr, "0x");
+ while(len-- > 0)
+ fprintf(stderr, "%02.2x", (unsigned int)*p++);
+}
+#else
+# define DEBUG_OUT(x) Curl_nop_stmt
+#endif
+
+/*
+ * ntlm_decode_type2_target()
+ *
+ * This is used to decode the "target info" in the ntlm type-2 message
+ * received.
+ *
+ * Parameters:
+ *
+ * data [in] - The session handle.
+ * buffer [in] - The decoded type-2 message.
+ * size [in] - The input buffer size, at least 32 bytes.
+ * ntlm [in/out] - The ntlm data struct being used and modified.
+ *
+ * Returns CURLE_OK on success.
+ */
+static CURLcode ntlm_decode_type2_target(struct SessionHandle *data,
+ unsigned char *buffer,
+ size_t size,
+ struct ntlmdata *ntlm)
+{
+ unsigned short target_info_len = 0;
+ unsigned int target_info_offset = 0;
+
+ if(size >= 48) {
+ target_info_len = Curl_read16_le(&buffer[40]);
+ target_info_offset = Curl_read32_le(&buffer[44]);
+ if(target_info_len > 0) {
+ if(((target_info_offset + target_info_len) > size) ||
+ (target_info_offset < 48)) {
+ infof(data, "NTLM handshake failure (bad type-2 message). "
+ "Target Info Offset Len is set incorrect by the peer\n");
+ return CURLE_BAD_CONTENT_ENCODING;
+ }
+
+ ntlm->target_info = malloc(target_info_len);
+ if(!ntlm->target_info)
+ return CURLE_OUT_OF_MEMORY;
+
+ memcpy(ntlm->target_info, &buffer[target_info_offset], target_info_len);
+ }
+ }
+
+ ntlm->target_info_len = target_info_len;
+
+ return CURLE_OK;
+}
+
+/*
+ NTLM message structure notes:
+
+ A 'short' is a 'network short', a little-endian 16-bit unsigned value.
+
+ A 'long' is a 'network long', a little-endian, 32-bit unsigned value.
+
+ A 'security buffer' represents a triplet used to point to a buffer,
+ consisting of two shorts and one long:
+
+ 1. A 'short' containing the length of the buffer content in bytes.
+ 2. A 'short' containing the allocated space for the buffer in bytes.
+ 3. A 'long' containing the offset to the start of the buffer in bytes,
+ from the beginning of the NTLM message.
+*/
+
+/*
+ * Curl_sasl_decode_ntlm_type2_message()
+ *
+ * This is used to decode an already encoded NTLM type-2 message. The message
+ * is first decoded from a base64 string into a raw NTLM message and checked
+ * for validity before the appropriate data for creating a type-3 message is
+ * written to the given NTLM data structure.
+ *
+ * Parameters:
+ *
+ * data [in] - The session handle.
+ * type2msg [in] - The base64 encoded type-2 message.
+ * ntlm [in/out] - The ntlm data struct being used and modified.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_decode_ntlm_type2_message(struct SessionHandle *data,
+ const char *type2msg,
+ struct ntlmdata *ntlm)
+{
+ static const char type2_marker[] = { 0x02, 0x00, 0x00, 0x00 };
+
+ /* NTLM type-2 message structure:
+
+ Index Description Content
+ 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
+ (0x4e544c4d53535000)
+ 8 NTLM Message Type long (0x02000000)
+ 12 Target Name security buffer
+ 20 Flags long
+ 24 Challenge 8 bytes
+ (32) Context 8 bytes (two consecutive longs) (*)
+ (40) Target Information security buffer (*)
+ (48) OS Version Structure 8 bytes (*)
+ 32 (48) (56) Start of data block (*)
+ (*) -> Optional
+ */
+
+ CURLcode result = CURLE_OK;
+ unsigned char *type2 = NULL;
+ size_t type2_len = 0;
+
+#if defined(USE_NSS)
+ /* Make sure the crypto backend is initialized */
+ result = Curl_nss_force_init(data);
+ if(result)
+ return result;
+#elif defined(CURL_DISABLE_VERBOSE_STRINGS)
+ (void)data;
+#endif
+
+ /* Decode the base-64 encoded type-2 message */
+ if(strlen(type2msg) && *type2msg != '=') {
+ result = Curl_base64_decode(type2msg, &type2, &type2_len);
+ if(result)
+ return result;
+ }
+
+ /* Ensure we have a valid type-2 message */
+ if(!type2) {
+ infof(data, "NTLM handshake failure (empty type-2 message)\n");
+ return CURLE_BAD_CONTENT_ENCODING;
+ }
+
+ ntlm->flags = 0;
+
+ if((type2_len < 32) ||
+ (memcmp(type2, NTLMSSP_SIGNATURE, 8) != 0) ||
+ (memcmp(type2 + 8, type2_marker, sizeof(type2_marker)) != 0)) {
+ /* This was not a good enough type-2 message */
+ free(type2);
+ infof(data, "NTLM handshake failure (bad type-2 message)\n");
+ return CURLE_BAD_CONTENT_ENCODING;
+ }
+
+ ntlm->flags = Curl_read32_le(&type2[20]);
+ memcpy(ntlm->nonce, &type2[24], 8);
+
+ if(ntlm->flags & NTLMFLAG_NEGOTIATE_TARGET_INFO) {
+ result = ntlm_decode_type2_target(data, type2, type2_len, ntlm);
+ if(result) {
+ free(type2);
+ infof(data, "NTLM handshake failure (bad type-2 message)\n");
+ return result;
+ }
+ }
+
+ DEBUG_OUT({
+ fprintf(stderr, "**** TYPE2 header flags=0x%08.8lx ", ntlm->flags);
+ ntlm_print_flags(stderr, ntlm->flags);
+ fprintf(stderr, "\n nonce=");
+ ntlm_print_hex(stderr, (char *)ntlm->nonce, 8);
+ fprintf(stderr, "\n****\n");
+ fprintf(stderr, "**** Header %s\n ", header);
+ });
+
+ free(type2);
+
+ return result;
+}
+
+/* copy the source to the destination and fill in zeroes in every
+ other destination byte! */
+static void unicodecpy(unsigned char *dest, const char *src, size_t length)
+{
+ size_t i;
+ for(i = 0; i < length; i++) {
+ dest[2 * i] = (unsigned char)src[i];
+ dest[2 * i + 1] = '\0';
+ }
+}
+
+/*
+ * Curl_sasl_create_ntlm_type1_message()
+ *
+ * This is used to generate an already encoded NTLM type-1 message ready for
+ * sending to the recipient using the appropriate compile time crypto API.
+ *
+ * Parameters:
+ *
+ * userp [in] - The user name in the format User or Domain\User.
+ * passdwp [in] - The user's password.
+ * ntlm [in/out] - The ntlm data struct being used and modified.
+ * outptr [in/out] - The address where a pointer to newly allocated memory
+ * holding the result will be stored upon completion.
+ * outlen [out] - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_create_ntlm_type1_message(const char *userp,
+ const char *passwdp,
+ struct ntlmdata *ntlm,
+ char **outptr, size_t *outlen)
+{
+ /* NTLM type-1 message structure:
+
+ Index Description Content
+ 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
+ (0x4e544c4d53535000)
+ 8 NTLM Message Type long (0x01000000)
+ 12 Flags long
+ (16) Supplied Domain security buffer (*)
+ (24) Supplied Workstation security buffer (*)
+ (32) OS Version Structure 8 bytes (*)
+ (32) (40) Start of data block (*)
+ (*) -> Optional
+ */
+
+ size_t size;
+
+ unsigned char ntlmbuf[NTLM_BUFSIZE];
+ const char *host = ""; /* empty */
+ const char *domain = ""; /* empty */
+ size_t hostlen = 0;
+ size_t domlen = 0;
+ size_t hostoff = 0;
+ size_t domoff = hostoff + hostlen; /* This is 0: remember that host and
+ domain are empty */
+ (void)userp;
+ (void)passwdp;
+
+ /* Clean up any former leftovers and initialise to defaults */
+ Curl_sasl_ntlm_cleanup(ntlm);
+
+#if USE_NTRESPONSES && USE_NTLM2SESSION
+#define NTLM2FLAG NTLMFLAG_NEGOTIATE_NTLM2_KEY
+#else
+#define NTLM2FLAG 0
+#endif
+ snprintf((char *)ntlmbuf, NTLM_BUFSIZE,
+ NTLMSSP_SIGNATURE "%c"
+ "\x01%c%c%c" /* 32-bit type = 1 */
+ "%c%c%c%c" /* 32-bit NTLM flag field */
+ "%c%c" /* domain length */
+ "%c%c" /* domain allocated space */
+ "%c%c" /* domain name offset */
+ "%c%c" /* 2 zeroes */
+ "%c%c" /* host length */
+ "%c%c" /* host allocated space */
+ "%c%c" /* host name offset */
+ "%c%c" /* 2 zeroes */
+ "%s" /* host name */
+ "%s", /* domain string */
+ 0, /* trailing zero */
+ 0, 0, 0, /* part of type-1 long */
+
+ LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM |
+ NTLMFLAG_REQUEST_TARGET |
+ NTLMFLAG_NEGOTIATE_NTLM_KEY |
+ NTLM2FLAG |
+ NTLMFLAG_NEGOTIATE_ALWAYS_SIGN),
+ SHORTPAIR(domlen),
+ SHORTPAIR(domlen),
+ SHORTPAIR(domoff),
+ 0, 0,
+ SHORTPAIR(hostlen),
+ SHORTPAIR(hostlen),
+ SHORTPAIR(hostoff),
+ 0, 0,
+ host, /* this is empty */
+ domain /* this is empty */);
+
+ /* Initial packet length */
+ size = 32 + hostlen + domlen;
+
+ DEBUG_OUT({
+ fprintf(stderr, "* TYPE1 header flags=0x%02.2x%02.2x%02.2x%02.2x "
+ "0x%08.8x ",
+ LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM |
+ NTLMFLAG_REQUEST_TARGET |
+ NTLMFLAG_NEGOTIATE_NTLM_KEY |
+ NTLM2FLAG |
+ NTLMFLAG_NEGOTIATE_ALWAYS_SIGN),
+ NTLMFLAG_NEGOTIATE_OEM |
+ NTLMFLAG_REQUEST_TARGET |
+ NTLMFLAG_NEGOTIATE_NTLM_KEY |
+ NTLM2FLAG |
+ NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
+ ntlm_print_flags(stderr,
+ NTLMFLAG_NEGOTIATE_OEM |
+ NTLMFLAG_REQUEST_TARGET |
+ NTLMFLAG_NEGOTIATE_NTLM_KEY |
+ NTLM2FLAG |
+ NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
+ fprintf(stderr, "\n****\n");
+ });
+
+ /* Return with binary blob encoded into base64 */
+ return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen);
+}
+
+/*
+ * Curl_sasl_create_ntlm_type3_message()
+ *
+ * This is used to generate an already encoded NTLM type-3 message ready for
+ * sending to the recipient using the appropriate compile time crypto API.
+ *
+ * Parameters:
+ *
+ * data [in] - The session handle.
+ * userp [in] - The user name in the format User or Domain\User.
+ * passdwp [in] - The user's password.
+ * ntlm [in/out] - The ntlm data struct being used and modified.
+ * outptr [in/out] - The address where a pointer to newly allocated memory
+ * holding the result will be stored upon completion.
+ * outlen [out] - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
+ const char *userp,
+ const char *passwdp,
+ struct ntlmdata *ntlm,
+ char **outptr, size_t *outlen)
+
+{
+ /* NTLM type-3 message structure:
+
+ Index Description Content
+ 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
+ (0x4e544c4d53535000)
+ 8 NTLM Message Type long (0x03000000)
+ 12 LM/LMv2 Response security buffer
+ 20 NTLM/NTLMv2 Response security buffer
+ 28 Target Name security buffer
+ 36 User Name security buffer
+ 44 Workstation Name security buffer
+ (52) Session Key security buffer (*)
+ (60) Flags long (*)
+ (64) OS Version Structure 8 bytes (*)
+ 52 (64) (72) Start of data block
+ (*) -> Optional
+ */
+
+ CURLcode result = CURLE_OK;
+ size_t size;
+ unsigned char ntlmbuf[NTLM_BUFSIZE];
+ int lmrespoff;
+ unsigned char lmresp[24]; /* fixed-size */
+#if USE_NTRESPONSES
+ int ntrespoff;
+ unsigned int ntresplen = 24;
+ unsigned char ntresp[24]; /* fixed-size */
+ unsigned char *ptr_ntresp = &ntresp[0];
+ unsigned char *ntlmv2resp = NULL;
+#endif
+ bool unicode = (ntlm->flags & NTLMFLAG_NEGOTIATE_UNICODE) ? TRUE : FALSE;
+ char host[HOSTNAME_MAX + 1] = "";
+ const char *user;
+ const char *domain = "";
+ size_t hostoff = 0;
+ size_t useroff = 0;
+ size_t domoff = 0;
+ size_t hostlen = 0;
+ size_t userlen = 0;
+ size_t domlen = 0;
+
+ user = strchr(userp, '\\');
+ if(!user)
+ user = strchr(userp, '/');
+
+ if(user) {
+ domain = userp;
+ domlen = (user - domain);
+ user++;
+ }
+ else
+ user = userp;
+
+ if(user)
+ userlen = strlen(user);
+
+ /* Get the machine's un-qualified host name as NTLM doesn't like the fully
+ qualified domain name */
+ if(Curl_gethostname(host, sizeof(host))) {
+ infof(data, "gethostname() failed, continuing without!\n");
+ hostlen = 0;
+ }
+ else {
+ hostlen = strlen(host);
+ }
+
+#if USE_NTRESPONSES && USE_NTLM_V2
+ if(ntlm->target_info_len) {
+ unsigned char ntbuffer[0x18];
+ unsigned int entropy[2];
+ unsigned char ntlmv2hash[0x18];
+
+ entropy[0] = Curl_rand(data);
+ entropy[1] = Curl_rand(data);
+
+ result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
+ if(result)
+ return result;
+
+ result = Curl_ntlm_core_mk_ntlmv2_hash(user, userlen, domain, domlen,
+ ntbuffer, ntlmv2hash);
+ if(result)
+ return result;
+
+ /* LMv2 response */
+ result = Curl_ntlm_core_mk_lmv2_resp(ntlmv2hash,
+ (unsigned char *)&entropy[0],
+ &ntlm->nonce[0], lmresp);
+ if(result)
+ return result;
+
+ /* NTLMv2 response */
+ result = Curl_ntlm_core_mk_ntlmv2_resp(ntlmv2hash,
+ (unsigned char *)&entropy[0],
+ ntlm, &ntlmv2resp, &ntresplen);
+ if(result)
+ return result;
+
+ ptr_ntresp = ntlmv2resp;
+ }
+ else
+#endif
+
+#if USE_NTRESPONSES && USE_NTLM2SESSION
+ /* We don't support NTLM2 if we don't have USE_NTRESPONSES */
+ if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) {
+ unsigned char ntbuffer[0x18];
+ unsigned char tmp[0x18];
+ unsigned char md5sum[MD5_DIGEST_LENGTH];
+ unsigned int entropy[2];
+
+ /* Need to create 8 bytes random data */
+ entropy[0] = Curl_rand(data);
+ entropy[1] = Curl_rand(data);
+
+ /* 8 bytes random data as challenge in lmresp */
+ memcpy(lmresp, entropy, 8);
+
+ /* Pad with zeros */
+ memset(lmresp + 8, 0, 0x10);
+
+ /* Fill tmp with challenge(nonce?) + entropy */
+ memcpy(tmp, &ntlm->nonce[0], 8);
+ memcpy(tmp + 8, entropy, 8);
+
+ result = Curl_ssl_md5sum(tmp, 16, md5sum, MD5_DIGEST_LENGTH);
+ if(!result)
+ /* We shall only use the first 8 bytes of md5sum, but the des code in
+ Curl_ntlm_core_lm_resp only encrypt the first 8 bytes */
+ result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
+ if(result)
+ return result;
+
+ Curl_ntlm_core_lm_resp(ntbuffer, md5sum, ntresp);
+
+ /* End of NTLM2 Session code */
+
+ }
+ else
+#endif
+ {
+
+#if USE_NTRESPONSES
+ unsigned char ntbuffer[0x18];
+#endif
+ unsigned char lmbuffer[0x18];
+
+#if USE_NTRESPONSES
+ result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
+ if(result)
+ return result;
+
+ Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], ntresp);
+#endif
+
+ result = Curl_ntlm_core_mk_lm_hash(data, passwdp, lmbuffer);
+ if(result)
+ return result;
+
+ Curl_ntlm_core_lm_resp(lmbuffer, &ntlm->nonce[0], lmresp);
+
+ /* A safer but less compatible alternative is:
+ * Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], lmresp);
+ * See http://davenport.sourceforge.net/ntlm.html#ntlmVersion2 */
+ }
+
+ if(unicode) {
+ domlen = domlen * 2;
+ userlen = userlen * 2;
+ hostlen = hostlen * 2;
+ }
+
+ lmrespoff = 64; /* size of the message header */
+#if USE_NTRESPONSES
+ ntrespoff = lmrespoff + 0x18;
+ domoff = ntrespoff + ntresplen;
+#else
+ domoff = lmrespoff + 0x18;
+#endif
+ useroff = domoff + domlen;
+ hostoff = useroff + userlen;
+
+ /* Create the big type-3 message binary blob */
+ size = snprintf((char *)ntlmbuf, NTLM_BUFSIZE,
+ NTLMSSP_SIGNATURE "%c"
+ "\x03%c%c%c" /* 32-bit type = 3 */
+
+ "%c%c" /* LanManager length */
+ "%c%c" /* LanManager allocated space */
+ "%c%c" /* LanManager offset */
+ "%c%c" /* 2 zeroes */
+
+ "%c%c" /* NT-response length */
+ "%c%c" /* NT-response allocated space */
+ "%c%c" /* NT-response offset */
+ "%c%c" /* 2 zeroes */
+
+ "%c%c" /* domain length */
+ "%c%c" /* domain allocated space */
+ "%c%c" /* domain name offset */
+ "%c%c" /* 2 zeroes */
+
+ "%c%c" /* user length */
+ "%c%c" /* user allocated space */
+ "%c%c" /* user offset */
+ "%c%c" /* 2 zeroes */
+
+ "%c%c" /* host length */
+ "%c%c" /* host allocated space */
+ "%c%c" /* host offset */
+ "%c%c" /* 2 zeroes */
+
+ "%c%c" /* session key length (unknown purpose) */
+ "%c%c" /* session key allocated space (unknown purpose) */
+ "%c%c" /* session key offset (unknown purpose) */
+ "%c%c" /* 2 zeroes */
+
+ "%c%c%c%c", /* flags */
+
+ /* domain string */
+ /* user string */
+ /* host string */
+ /* LanManager response */
+ /* NT response */
+
+ 0, /* zero termination */
+ 0, 0, 0, /* type-3 long, the 24 upper bits */
+
+ SHORTPAIR(0x18), /* LanManager response length, twice */
+ SHORTPAIR(0x18),
+ SHORTPAIR(lmrespoff),
+ 0x0, 0x0,
+
+#if USE_NTRESPONSES
+ SHORTPAIR(ntresplen), /* NT-response length, twice */
+ SHORTPAIR(ntresplen),
+ SHORTPAIR(ntrespoff),
+ 0x0, 0x0,
+#else
+ 0x0, 0x0,
+ 0x0, 0x0,
+ 0x0, 0x0,
+ 0x0, 0x0,
+#endif
+ SHORTPAIR(domlen),
+ SHORTPAIR(domlen),
+ SHORTPAIR(domoff),
+ 0x0, 0x0,
+
+ SHORTPAIR(userlen),
+ SHORTPAIR(userlen),
+ SHORTPAIR(useroff),
+ 0x0, 0x0,
+
+ SHORTPAIR(hostlen),
+ SHORTPAIR(hostlen),
+ SHORTPAIR(hostoff),
+ 0x0, 0x0,
+
+ 0x0, 0x0,
+ 0x0, 0x0,
+ 0x0, 0x0,
+ 0x0, 0x0,
+
+ LONGQUARTET(ntlm->flags));
+
+ DEBUGASSERT(size == 64);
+ DEBUGASSERT(size == (size_t)lmrespoff);
+
+ /* We append the binary hashes */
+ if(size < (NTLM_BUFSIZE - 0x18)) {
+ memcpy(&ntlmbuf[size], lmresp, 0x18);
+ size += 0x18;
+ }
+
+ DEBUG_OUT({
+ fprintf(stderr, "**** TYPE3 header lmresp=");
+ ntlm_print_hex(stderr, (char *)&ntlmbuf[lmrespoff], 0x18);
+ });
+
+#if USE_NTRESPONSES
+ if(size < (NTLM_BUFSIZE - ntresplen)) {
+ DEBUGASSERT(size == (size_t)ntrespoff);
+ memcpy(&ntlmbuf[size], ptr_ntresp, ntresplen);
+ size += ntresplen;
+ }
+
+ DEBUG_OUT({
+ fprintf(stderr, "\n ntresp=");
+ ntlm_print_hex(stderr, (char *)&ntlmbuf[ntrespoff], ntresplen);
+ });
+
+ free(ntlmv2resp);/* Free the dynamic buffer allocated for NTLMv2 */
+
+#endif
+
+ DEBUG_OUT({
+ fprintf(stderr, "\n flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ",
+ LONGQUARTET(ntlm->flags), ntlm->flags);
+ ntlm_print_flags(stderr, ntlm->flags);
+ fprintf(stderr, "\n****\n");
+ });
+
+ /* Make sure that the domain, user and host strings fit in the
+ buffer before we copy them there. */
+ if(size + userlen + domlen + hostlen >= NTLM_BUFSIZE) {
+ failf(data, "user + domain + host name too big");
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ DEBUGASSERT(size == domoff);
+ if(unicode)
+ unicodecpy(&ntlmbuf[size], domain, domlen / 2);
+ else
+ memcpy(&ntlmbuf[size], domain, domlen);
+
+ size += domlen;
+
+ DEBUGASSERT(size == useroff);
+ if(unicode)
+ unicodecpy(&ntlmbuf[size], user, userlen / 2);
+ else
+ memcpy(&ntlmbuf[size], user, userlen);
+
+ size += userlen;
+
+ DEBUGASSERT(size == hostoff);
+ if(unicode)
+ unicodecpy(&ntlmbuf[size], host, hostlen / 2);
+ else
+ memcpy(&ntlmbuf[size], host, hostlen);
+
+ size += hostlen;
+
+ /* Convert domain, user, and host to ASCII but leave the rest as-is */
+ result = Curl_convert_to_network(data, (char *)&ntlmbuf[domoff],
+ size - domoff);
+ if(result)
+ return CURLE_CONV_FAILED;
+
+ /* Return with binary blob encoded into base64 */
+ result = Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen);
+
+ Curl_sasl_ntlm_cleanup(ntlm);
+
+ return result;
+}
+
+#endif /* USE_NTLM && !USE_WINDOWS_SSPI */
diff --git a/Utilities/cmcurl/lib/curl_ntlm_msgs.h b/Utilities/cmcurl/lib/curl_ntlm_msgs.h
new file mode 100644
index 000000000..2a7143199
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_ntlm_msgs.h
@@ -0,0 +1,143 @@
+#ifndef HEADER_CURL_NTLM_MSGS_H
+#define HEADER_CURL_NTLM_MSGS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_NTLM
+
+/* NTLM buffer fixed size, large enough for long user + host + domain */
+#define NTLM_BUFSIZE 1024
+
+/* Stuff only required for curl_ntlm_msgs.c */
+#ifdef BUILDING_CURL_NTLM_MSGS_C
+
+/* Flag bits definitions based on http://davenport.sourceforge.net/ntlm.html */
+
+#define NTLMFLAG_NEGOTIATE_UNICODE (1<<0)
+/* Indicates that Unicode strings are supported for use in security buffer
+ data. */
+
+#define NTLMFLAG_NEGOTIATE_OEM (1<<1)
+/* Indicates that OEM strings are supported for use in security buffer data. */
+
+#define NTLMFLAG_REQUEST_TARGET (1<<2)
+/* Requests that the server's authentication realm be included in the Type 2
+ message. */
+
+/* unknown (1<<3) */
+#define NTLMFLAG_NEGOTIATE_SIGN (1<<4)
+/* Specifies that authenticated communication between the client and server
+ should carry a digital signature (message integrity). */
+
+#define NTLMFLAG_NEGOTIATE_SEAL (1<<5)
+/* Specifies that authenticated communication between the client and server
+ should be encrypted (message confidentiality). */
+
+#define NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE (1<<6)
+/* Indicates that datagram authentication is being used. */
+
+#define NTLMFLAG_NEGOTIATE_LM_KEY (1<<7)
+/* Indicates that the LAN Manager session key should be used for signing and
+ sealing authenticated communications. */
+
+#define NTLMFLAG_NEGOTIATE_NETWARE (1<<8)
+/* unknown purpose */
+
+#define NTLMFLAG_NEGOTIATE_NTLM_KEY (1<<9)
+/* Indicates that NTLM authentication is being used. */
+
+/* unknown (1<<10) */
+
+#define NTLMFLAG_NEGOTIATE_ANONYMOUS (1<<11)
+/* Sent by the client in the Type 3 message to indicate that an anonymous
+ context has been established. This also affects the response fields. */
+
+#define NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED (1<<12)
+/* Sent by the client in the Type 1 message to indicate that a desired
+ authentication realm is included in the message. */
+
+#define NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED (1<<13)
+/* Sent by the client in the Type 1 message to indicate that the client
+ workstation's name is included in the message. */
+
+#define NTLMFLAG_NEGOTIATE_LOCAL_CALL (1<<14)
+/* Sent by the server to indicate that the server and client are on the same
+ machine. Implies that the client may use a pre-established local security
+ context rather than responding to the challenge. */
+
+#define NTLMFLAG_NEGOTIATE_ALWAYS_SIGN (1<<15)
+/* Indicates that authenticated communication between the client and server
+ should be signed with a "dummy" signature. */
+
+#define NTLMFLAG_TARGET_TYPE_DOMAIN (1<<16)
+/* Sent by the server in the Type 2 message to indicate that the target
+ authentication realm is a domain. */
+
+#define NTLMFLAG_TARGET_TYPE_SERVER (1<<17)
+/* Sent by the server in the Type 2 message to indicate that the target
+ authentication realm is a server. */
+
+#define NTLMFLAG_TARGET_TYPE_SHARE (1<<18)
+/* Sent by the server in the Type 2 message to indicate that the target
+ authentication realm is a share. Presumably, this is for share-level
+ authentication. Usage is unclear. */
+
+#define NTLMFLAG_NEGOTIATE_NTLM2_KEY (1<<19)
+/* Indicates that the NTLM2 signing and sealing scheme should be used for
+ protecting authenticated communications. */
+
+#define NTLMFLAG_REQUEST_INIT_RESPONSE (1<<20)
+/* unknown purpose */
+
+#define NTLMFLAG_REQUEST_ACCEPT_RESPONSE (1<<21)
+/* unknown purpose */
+
+#define NTLMFLAG_REQUEST_NONNT_SESSION_KEY (1<<22)
+/* unknown purpose */
+
+#define NTLMFLAG_NEGOTIATE_TARGET_INFO (1<<23)
+/* Sent by the server in the Type 2 message to indicate that it is including a
+ Target Information block in the message. */
+
+/* unknown (1<24) */
+/* unknown (1<25) */
+/* unknown (1<26) */
+/* unknown (1<27) */
+/* unknown (1<28) */
+
+#define NTLMFLAG_NEGOTIATE_128 (1<<29)
+/* Indicates that 128-bit encryption is supported. */
+
+#define NTLMFLAG_NEGOTIATE_KEY_EXCHANGE (1<<30)
+/* Indicates that the client will provide an encrypted master key in
+ the "Session Key" field of the Type 3 message. */
+
+#define NTLMFLAG_NEGOTIATE_56 (1<<31)
+/* Indicates that 56-bit encryption is supported. */
+
+#endif /* BUILDING_CURL_NTLM_MSGS_C */
+
+#endif /* USE_NTLM */
+
+#endif /* HEADER_CURL_NTLM_MSGS_H */
diff --git a/Utilities/cmcurl/lib/curl_ntlm_wb.c b/Utilities/cmcurl/lib/curl_ntlm_wb.c
new file mode 100644
index 000000000..b2a5fb343
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_ntlm_wb.c
@@ -0,0 +1,431 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
+ defined(NTLM_WB_ENABLED)
+
+/*
+ * NTLM details:
+ *
+ * http://davenport.sourceforge.net/ntlm.html
+ * http://www.innovation.ch/java/ntlm.html
+ */
+
+#define DEBUG_ME 0
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "select.h"
+#include "curl_ntlm_msgs.h"
+#include "curl_ntlm_wb.h"
+#include "url.h"
+#include "strerror.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#if DEBUG_ME
+# define DEBUG_OUT(x) x
+#else
+# define DEBUG_OUT(x) Curl_nop_stmt
+#endif
+
+/* Portable 'sclose_nolog' used only in child process instead of 'sclose'
+ to avoid fooling the socket leak detector */
+#if defined(HAVE_CLOSESOCKET)
+# define sclose_nolog(x) closesocket((x))
+#elif defined(HAVE_CLOSESOCKET_CAMEL)
+# define sclose_nolog(x) CloseSocket((x))
+#else
+# define sclose_nolog(x) close((x))
+#endif
+
+void Curl_ntlm_wb_cleanup(struct connectdata *conn)
+{
+ if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD) {
+ sclose(conn->ntlm_auth_hlpr_socket);
+ conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
+ }
+
+ if(conn->ntlm_auth_hlpr_pid) {
+ int i;
+ for(i = 0; i < 4; i++) {
+ pid_t ret = waitpid(conn->ntlm_auth_hlpr_pid, NULL, WNOHANG);
+ if(ret == conn->ntlm_auth_hlpr_pid || errno == ECHILD)
+ break;
+ switch(i) {
+ case 0:
+ kill(conn->ntlm_auth_hlpr_pid, SIGTERM);
+ break;
+ case 1:
+ /* Give the process another moment to shut down cleanly before
+ bringing down the axe */
+ Curl_wait_ms(1);
+ break;
+ case 2:
+ kill(conn->ntlm_auth_hlpr_pid, SIGKILL);
+ break;
+ case 3:
+ break;
+ }
+ }
+ conn->ntlm_auth_hlpr_pid = 0;
+ }
+
+ free(conn->challenge_header);
+ conn->challenge_header = NULL;
+ free(conn->response_header);
+ conn->response_header = NULL;
+}
+
+static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
+{
+ curl_socket_t sockfds[2];
+ pid_t child_pid;
+ const char *username;
+ char *slash, *domain = NULL;
+ const char *ntlm_auth = NULL;
+ char *ntlm_auth_alloc = NULL;
+#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
+ struct passwd pw, *pw_res;
+ char pwbuf[1024];
+#endif
+ int error;
+
+ /* Return if communication with ntlm_auth already set up */
+ if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD ||
+ conn->ntlm_auth_hlpr_pid)
+ return CURLE_OK;
+
+ username = userp;
+ /* The real ntlm_auth really doesn't like being invoked with an
+ empty username. It won't make inferences for itself, and expects
+ the client to do so (mostly because it's really designed for
+ servers like squid to use for auth, and client support is an
+ afterthought for it). So try hard to provide a suitable username
+ if we don't already have one. But if we can't, provide the
+ empty one anyway. Perhaps they have an implementation of the
+ ntlm_auth helper which *doesn't* need it so we might as well try */
+ if(!username || !username[0]) {
+ username = getenv("NTLMUSER");
+ if(!username || !username[0])
+ username = getenv("LOGNAME");
+ if(!username || !username[0])
+ username = getenv("USER");
+#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
+ if((!username || !username[0]) &&
+ !getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res) &&
+ pw_res) {
+ username = pw.pw_name;
+ }
+#endif
+ if(!username || !username[0])
+ username = userp;
+ }
+ slash = strpbrk(username, "\\/");
+ if(slash) {
+ if((domain = strdup(username)) == NULL)
+ return CURLE_OUT_OF_MEMORY;
+ slash = domain + (slash - username);
+ *slash = '\0';
+ username = username + (slash - domain) + 1;
+ }
+
+ /* For testing purposes, when DEBUGBUILD is defined and environment
+ variable CURL_NTLM_WB_FILE is set a fake_ntlm is used to perform
+ NTLM challenge/response which only accepts commands and output
+ strings pre-written in test case definitions */
+#ifdef DEBUGBUILD
+ ntlm_auth_alloc = curl_getenv("CURL_NTLM_WB_FILE");
+ if(ntlm_auth_alloc)
+ ntlm_auth = ntlm_auth_alloc;
+ else
+#endif
+ ntlm_auth = NTLM_WB_FILE;
+
+ if(access(ntlm_auth, X_OK) != 0) {
+ error = ERRNO;
+ failf(conn->data, "Could not access ntlm_auth: %s errno %d: %s",
+ ntlm_auth, error, Curl_strerror(conn, error));
+ goto done;
+ }
+
+ if(socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds)) {
+ error = ERRNO;
+ failf(conn->data, "Could not open socket pair. errno %d: %s",
+ error, Curl_strerror(conn, error));
+ goto done;
+ }
+
+ child_pid = fork();
+ if(child_pid == -1) {
+ error = ERRNO;
+ sclose(sockfds[0]);
+ sclose(sockfds[1]);
+ failf(conn->data, "Could not fork. errno %d: %s",
+ error, Curl_strerror(conn, error));
+ goto done;
+ }
+ else if(!child_pid) {
+ /*
+ * child process
+ */
+
+ /* Don't use sclose in the child since it fools the socket leak detector */
+ sclose_nolog(sockfds[0]);
+ if(dup2(sockfds[1], STDIN_FILENO) == -1) {
+ error = ERRNO;
+ failf(conn->data, "Could not redirect child stdin. errno %d: %s",
+ error, Curl_strerror(conn, error));
+ exit(1);
+ }
+
+ if(dup2(sockfds[1], STDOUT_FILENO) == -1) {
+ error = ERRNO;
+ failf(conn->data, "Could not redirect child stdout. errno %d: %s",
+ error, Curl_strerror(conn, error));
+ exit(1);
+ }
+
+ if(domain)
+ execl(ntlm_auth, ntlm_auth,
+ "--helper-protocol", "ntlmssp-client-1",
+ "--use-cached-creds",
+ "--username", username,
+ "--domain", domain,
+ NULL);
+ else
+ execl(ntlm_auth, ntlm_auth,
+ "--helper-protocol", "ntlmssp-client-1",
+ "--use-cached-creds",
+ "--username", username,
+ NULL);
+
+ error = ERRNO;
+ sclose_nolog(sockfds[1]);
+ failf(conn->data, "Could not execl(). errno %d: %s",
+ error, Curl_strerror(conn, error));
+ exit(1);
+ }
+
+ sclose(sockfds[1]);
+ conn->ntlm_auth_hlpr_socket = sockfds[0];
+ conn->ntlm_auth_hlpr_pid = child_pid;
+ free(domain);
+ free(ntlm_auth_alloc);
+ return CURLE_OK;
+
+done:
+ free(domain);
+ free(ntlm_auth_alloc);
+ return CURLE_REMOTE_ACCESS_DENIED;
+}
+
+static CURLcode ntlm_wb_response(struct connectdata *conn,
+ const char *input, curlntlm state)
+{
+ char *buf = malloc(NTLM_BUFSIZE);
+ size_t len_in = strlen(input), len_out = 0;
+
+ if(!buf)
+ return CURLE_OUT_OF_MEMORY;
+
+ while(len_in > 0) {
+ ssize_t written = swrite(conn->ntlm_auth_hlpr_socket, input, len_in);
+ if(written == -1) {
+ /* Interrupted by a signal, retry it */
+ if(errno == EINTR)
+ continue;
+ /* write failed if other errors happen */
+ goto done;
+ }
+ input += written;
+ len_in -= written;
+ }
+ /* Read one line */
+ while(1) {
+ ssize_t size;
+ char *newbuf;
+
+ size = sread(conn->ntlm_auth_hlpr_socket, buf + len_out, NTLM_BUFSIZE);
+ if(size == -1) {
+ if(errno == EINTR)
+ continue;
+ goto done;
+ }
+ else if(size == 0)
+ goto done;
+
+ len_out += size;
+ if(buf[len_out - 1] == '\n') {
+ buf[len_out - 1] = '\0';
+ break;
+ }
+ newbuf = realloc(buf, len_out + NTLM_BUFSIZE);
+ if(!newbuf) {
+ free(buf);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ buf = newbuf;
+ }
+
+ /* Samba/winbind installed but not configured */
+ if(state == NTLMSTATE_TYPE1 &&
+ len_out == 3 &&
+ buf[0] == 'P' && buf[1] == 'W')
+ goto done;
+ /* invalid response */
+ if(len_out < 4)
+ goto done;
+ if(state == NTLMSTATE_TYPE1 &&
+ (buf[0]!='Y' || buf[1]!='R' || buf[2]!=' '))
+ goto done;
+ if(state == NTLMSTATE_TYPE2 &&
+ (buf[0]!='K' || buf[1]!='K' || buf[2]!=' ') &&
+ (buf[0]!='A' || buf[1]!='F' || buf[2]!=' '))
+ goto done;
+
+ conn->response_header = aprintf("NTLM %.*s", len_out - 4, buf + 3);
+ free(buf);
+ return CURLE_OK;
+done:
+ free(buf);
+ return CURLE_REMOTE_ACCESS_DENIED;
+}
+
+/*
+ * This is for creating ntlm header output by delegating challenge/response
+ * to Samba's winbind daemon helper ntlm_auth.
+ */
+CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
+ bool proxy)
+{
+ /* point to the address of the pointer that holds the string to send to the
+ server, which is for a plain host or for a HTTP proxy */
+ char **allocuserpwd;
+ /* point to the name and password for this */
+ const char *userp;
+ /* point to the correct struct with this */
+ struct ntlmdata *ntlm;
+ struct auth *authp;
+
+ CURLcode res = CURLE_OK;
+ char *input;
+
+ DEBUGASSERT(conn);
+ DEBUGASSERT(conn->data);
+
+ if(proxy) {
+ allocuserpwd = &conn->allocptr.proxyuserpwd;
+ userp = conn->proxyuser;
+ ntlm = &conn->proxyntlm;
+ authp = &conn->data->state.authproxy;
+ }
+ else {
+ allocuserpwd = &conn->allocptr.userpwd;
+ userp = conn->user;
+ ntlm = &conn->ntlm;
+ authp = &conn->data->state.authhost;
+ }
+ authp->done = FALSE;
+
+ /* not set means empty */
+ if(!userp)
+ userp="";
+
+ switch(ntlm->state) {
+ case NTLMSTATE_TYPE1:
+ default:
+ /* Use Samba's 'winbind' daemon to support NTLM authentication,
+ * by delegating the NTLM challenge/response protocal to a helper
+ * in ntlm_auth.
+ * http://devel.squid-cache.org/ntlm/squid_helper_protocol.html
+ * http://www.samba.org/samba/docs/man/manpages-3/winbindd.8.html
+ * http://www.samba.org/samba/docs/man/manpages-3/ntlm_auth.1.html
+ * Preprocessor symbol 'NTLM_WB_ENABLED' is defined when this
+ * feature is enabled and 'NTLM_WB_FILE' symbol holds absolute
+ * filename of ntlm_auth helper.
+ * If NTLM authentication using winbind fails, go back to original
+ * request handling process.
+ */
+ /* Create communication with ntlm_auth */
+ res = ntlm_wb_init(conn, userp);
+ if(res)
+ return res;
+ res = ntlm_wb_response(conn, "YR\n", ntlm->state);
+ if(res)
+ return res;
+
+ free(*allocuserpwd);
+ *allocuserpwd = aprintf("%sAuthorization: %s\r\n",
+ proxy ? "Proxy-" : "",
+ conn->response_header);
+ DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd));
+ free(conn->response_header);
+ conn->response_header = NULL;
+ break;
+ case NTLMSTATE_TYPE2:
+ input = aprintf("TT %s\n", conn->challenge_header);
+ if(!input)
+ return CURLE_OUT_OF_MEMORY;
+ res = ntlm_wb_response(conn, input, ntlm->state);
+ free(input);
+ input = NULL;
+ if(res)
+ return res;
+
+ free(*allocuserpwd);
+ *allocuserpwd = aprintf("%sAuthorization: %s\r\n",
+ proxy ? "Proxy-" : "",
+ conn->response_header);
+ DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
+ ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
+ authp->done = TRUE;
+ Curl_ntlm_wb_cleanup(conn);
+ break;
+ case NTLMSTATE_TYPE3:
+ /* connection is already authenticated,
+ * don't send a header in future requests */
+ free(*allocuserpwd);
+ *allocuserpwd=NULL;
+ authp->done = TRUE;
+ break;
+ }
+
+ return CURLE_OK;
+}
+
+#endif /* !CURL_DISABLE_HTTP && USE_NTLM && NTLM_WB_ENABLED */
diff --git a/Utilities/cmcurl/lib/curl_ntlm_wb.h b/Utilities/cmcurl/lib/curl_ntlm_wb.h
new file mode 100644
index 000000000..828bb5767
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_ntlm_wb.h
@@ -0,0 +1,38 @@
+#ifndef HEADER_CURL_NTLM_WB_H
+#define HEADER_CURL_NTLM_WB_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
+ defined(NTLM_WB_ENABLED)
+
+/* this is for creating ntlm header output by delegating challenge/response
+ to Samba's winbind daemon helper ntlm_auth */
+CURLcode Curl_output_ntlm_wb(struct connectdata *conn, bool proxy);
+
+void Curl_ntlm_wb_cleanup(struct connectdata *conn);
+
+#endif /* !CURL_DISABLE_HTTP && USE_NTLM && NTLM_WB_ENABLED */
+
+#endif /* HEADER_CURL_NTLM_WB_H */
diff --git a/Utilities/cmcurl/lib/curl_printf.h b/Utilities/cmcurl/lib/curl_printf.h
new file mode 100644
index 000000000..086923f1d
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_printf.h
@@ -0,0 +1,56 @@
+#ifndef HEADER_CURL_PRINTF_H
+#define HEADER_CURL_PRINTF_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * This header should be included by ALL code in libcurl that uses any
+ * *rintf() functions.
+ */
+
+#include <curl/mprintf.h>
+
+# undef printf
+# undef fprintf
+# undef snprintf
+# undef vprintf
+# undef vfprintf
+# undef vsnprintf
+# undef aprintf
+# undef vaprintf
+# define printf curl_mprintf
+# define fprintf curl_mfprintf
+# define snprintf curl_msnprintf
+# define vprintf curl_mvprintf
+# define vfprintf curl_mvfprintf
+# define vsnprintf curl_mvsnprintf
+# define aprintf curl_maprintf
+# define vaprintf curl_mvaprintf
+
+/* We define away the sprintf functions unconditonally since we don't want
+ internal code to be using them, intentionally or by mistake!*/
+# undef sprintf
+# undef vsprintf
+# define sprintf sprintf_was_used
+# define vsprintf vsprintf_was_used
+
+#endif /* HEADER_CURL_PRINTF_H */
diff --git a/Utilities/cmcurl/lib/curl_rtmp.c b/Utilities/cmcurl/lib/curl_rtmp.c
new file mode 100644
index 000000000..293897288
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_rtmp.c
@@ -0,0 +1,306 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010, Howard Chu, <hyc@highlandsun.com>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_LIBRTMP
+
+#include "urldata.h"
+#include "nonblock.h" /* for curlx_nonblock */
+#include "progress.h" /* for Curl_pgrsSetUploadSize */
+#include "transfer.h"
+#include "warnless.h"
+#include <curl/curl.h>
+#include <librtmp/rtmp.h>
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#ifdef _WIN32
+#define setsockopt(a,b,c,d,e) (setsockopt)(a,b,c,(const char *)d,(int)e)
+#define SET_RCVTIMEO(tv,s) int tv = s*1000
+#else
+#define SET_RCVTIMEO(tv,s) struct timeval tv = {s,0}
+#endif
+
+#define DEF_BUFTIME (2*60*60*1000) /* 2 hours */
+
+static CURLcode rtmp_setup_connection(struct connectdata *conn);
+static CURLcode rtmp_do(struct connectdata *conn, bool *done);
+static CURLcode rtmp_done(struct connectdata *conn, CURLcode, bool premature);
+static CURLcode rtmp_connect(struct connectdata *conn, bool *done);
+static CURLcode rtmp_disconnect(struct connectdata *conn, bool dead);
+
+static Curl_recv rtmp_recv;
+static Curl_send rtmp_send;
+
+/*
+ * RTMP protocol handler.h, based on http://rtmpdump.mplayerhq.hu
+ */
+
+const struct Curl_handler Curl_handler_rtmp = {
+ "RTMP", /* scheme */
+ rtmp_setup_connection, /* setup_connection */
+ rtmp_do, /* do_it */
+ rtmp_done, /* done */
+ ZERO_NULL, /* do_more */
+ rtmp_connect, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_getsock */
+ ZERO_NULL, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ rtmp_disconnect, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_RTMP, /* defport */
+ CURLPROTO_RTMP, /* protocol */
+ PROTOPT_NONE /* flags*/
+};
+
+const struct Curl_handler Curl_handler_rtmpt = {
+ "RTMPT", /* scheme */
+ rtmp_setup_connection, /* setup_connection */
+ rtmp_do, /* do_it */
+ rtmp_done, /* done */
+ ZERO_NULL, /* do_more */
+ rtmp_connect, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_getsock */
+ ZERO_NULL, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ rtmp_disconnect, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_RTMPT, /* defport */
+ CURLPROTO_RTMPT, /* protocol */
+ PROTOPT_NONE /* flags*/
+};
+
+const struct Curl_handler Curl_handler_rtmpe = {
+ "RTMPE", /* scheme */
+ rtmp_setup_connection, /* setup_connection */
+ rtmp_do, /* do_it */
+ rtmp_done, /* done */
+ ZERO_NULL, /* do_more */
+ rtmp_connect, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_getsock */
+ ZERO_NULL, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ rtmp_disconnect, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_RTMP, /* defport */
+ CURLPROTO_RTMPE, /* protocol */
+ PROTOPT_NONE /* flags*/
+};
+
+const struct Curl_handler Curl_handler_rtmpte = {
+ "RTMPTE", /* scheme */
+ rtmp_setup_connection, /* setup_connection */
+ rtmp_do, /* do_it */
+ rtmp_done, /* done */
+ ZERO_NULL, /* do_more */
+ rtmp_connect, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_getsock */
+ ZERO_NULL, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ rtmp_disconnect, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_RTMPT, /* defport */
+ CURLPROTO_RTMPTE, /* protocol */
+ PROTOPT_NONE /* flags*/
+};
+
+const struct Curl_handler Curl_handler_rtmps = {
+ "RTMPS", /* scheme */
+ rtmp_setup_connection, /* setup_connection */
+ rtmp_do, /* do_it */
+ rtmp_done, /* done */
+ ZERO_NULL, /* do_more */
+ rtmp_connect, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_getsock */
+ ZERO_NULL, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ rtmp_disconnect, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_RTMPS, /* defport */
+ CURLPROTO_RTMPS, /* protocol */
+ PROTOPT_NONE /* flags*/
+};
+
+const struct Curl_handler Curl_handler_rtmpts = {
+ "RTMPTS", /* scheme */
+ rtmp_setup_connection, /* setup_connection */
+ rtmp_do, /* do_it */
+ rtmp_done, /* done */
+ ZERO_NULL, /* do_more */
+ rtmp_connect, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_getsock */
+ ZERO_NULL, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ rtmp_disconnect, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_RTMPS, /* defport */
+ CURLPROTO_RTMPTS, /* protocol */
+ PROTOPT_NONE /* flags*/
+};
+
+static CURLcode rtmp_setup_connection(struct connectdata *conn)
+{
+ RTMP *r = RTMP_Alloc();
+ if(!r)
+ return CURLE_OUT_OF_MEMORY;
+
+ RTMP_Init(r);
+ RTMP_SetBufferMS(r, DEF_BUFTIME);
+ if(!RTMP_SetupURL(r, conn->data->change.url)) {
+ RTMP_Free(r);
+ return CURLE_URL_MALFORMAT;
+ }
+ conn->proto.generic = r;
+ return CURLE_OK;
+}
+
+static CURLcode rtmp_connect(struct connectdata *conn, bool *done)
+{
+ RTMP *r = conn->proto.generic;
+ SET_RCVTIMEO(tv, 10);
+
+ r->m_sb.sb_socket = conn->sock[FIRSTSOCKET];
+
+ /* We have to know if it's a write before we send the
+ * connect request packet
+ */
+ if(conn->data->set.upload)
+ r->Link.protocol |= RTMP_FEATURE_WRITE;
+
+ /* For plain streams, use the buffer toggle trick to keep data flowing */
+ if(!(r->Link.lFlags & RTMP_LF_LIVE) &&
+ !(r->Link.protocol & RTMP_FEATURE_HTTP))
+ r->Link.lFlags |= RTMP_LF_BUFX;
+
+ (void)curlx_nonblock(r->m_sb.sb_socket, FALSE);
+ setsockopt(r->m_sb.sb_socket, SOL_SOCKET, SO_RCVTIMEO,
+ (char *)&tv, sizeof(tv));
+
+ if(!RTMP_Connect1(r, NULL))
+ return CURLE_FAILED_INIT;
+
+ /* Clients must send a periodic BytesReceived report to the server */
+ r->m_bSendCounter = true;
+
+ *done = TRUE;
+ conn->recv[FIRSTSOCKET] = rtmp_recv;
+ conn->send[FIRSTSOCKET] = rtmp_send;
+ return CURLE_OK;
+}
+
+static CURLcode rtmp_do(struct connectdata *conn, bool *done)
+{
+ RTMP *r = conn->proto.generic;
+
+ if(!RTMP_ConnectStream(r, 0))
+ return CURLE_FAILED_INIT;
+
+ if(conn->data->set.upload) {
+ Curl_pgrsSetUploadSize(conn->data, conn->data->state.infilesize);
+ Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
+ }
+ else
+ Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL);
+ *done = TRUE;
+ return CURLE_OK;
+}
+
+static CURLcode rtmp_done(struct connectdata *conn, CURLcode status,
+ bool premature)
+{
+ (void)conn; /* unused */
+ (void)status; /* unused */
+ (void)premature; /* unused */
+
+ return CURLE_OK;
+}
+
+static CURLcode rtmp_disconnect(struct connectdata *conn,
+ bool dead_connection)
+{
+ RTMP *r = conn->proto.generic;
+ (void)dead_connection;
+ if(r) {
+ conn->proto.generic = NULL;
+ RTMP_Close(r);
+ RTMP_Free(r);
+ }
+ return CURLE_OK;
+}
+
+static ssize_t rtmp_recv(struct connectdata *conn, int sockindex, char *buf,
+ size_t len, CURLcode *err)
+{
+ RTMP *r = conn->proto.generic;
+ ssize_t nread;
+
+ (void)sockindex; /* unused */
+
+ nread = RTMP_Read(r, buf, curlx_uztosi(len));
+ if(nread < 0) {
+ if(r->m_read.status == RTMP_READ_COMPLETE ||
+ r->m_read.status == RTMP_READ_EOF) {
+ conn->data->req.size = conn->data->req.bytecount;
+ nread = 0;
+ }
+ else
+ *err = CURLE_RECV_ERROR;
+ }
+ return nread;
+}
+
+static ssize_t rtmp_send(struct connectdata *conn, int sockindex,
+ const void *buf, size_t len, CURLcode *err)
+{
+ RTMP *r = conn->proto.generic;
+ ssize_t num;
+
+ (void)sockindex; /* unused */
+
+ num = RTMP_Write(r, (char *)buf, curlx_uztosi(len));
+ if(num < 0)
+ *err = CURLE_SEND_ERROR;
+
+ return num;
+}
+#endif /* USE_LIBRTMP */
diff --git a/Utilities/cmcurl/lib/curl_rtmp.h b/Utilities/cmcurl/lib/curl_rtmp.h
new file mode 100644
index 000000000..4a9e9e60c
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_rtmp.h
@@ -0,0 +1,33 @@
+#ifndef HEADER_CURL_RTMP_H
+#define HEADER_CURL_RTMP_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2010, Howard Chu, <hyc@highlandsun.com>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#ifdef USE_LIBRTMP
+extern const struct Curl_handler Curl_handler_rtmp;
+extern const struct Curl_handler Curl_handler_rtmpt;
+extern const struct Curl_handler Curl_handler_rtmpe;
+extern const struct Curl_handler Curl_handler_rtmpte;
+extern const struct Curl_handler Curl_handler_rtmps;
+extern const struct Curl_handler Curl_handler_rtmpts;
+#endif
+
+#endif /* HEADER_CURL_RTMP_H */
diff --git a/Utilities/cmcurl/lib/curl_sasl.c b/Utilities/cmcurl/lib/curl_sasl.c
new file mode 100644
index 000000000..68646bc1a
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_sasl.c
@@ -0,0 +1,1669 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * RFC2195 CRAM-MD5 authentication
+ * RFC2617 Basic and Digest Access Authentication
+ * RFC2831 DIGEST-MD5 authentication
+ * RFC4422 Simple Authentication and Security Layer (SASL)
+ * RFC4616 PLAIN authentication
+ * RFC6749 OAuth 2.0 Authorization Framework
+ * Draft LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+#include "urldata.h"
+
+#include "curl_base64.h"
+#include "curl_md5.h"
+#include "vtls/vtls.h"
+#include "curl_hmac.h"
+#include "curl_sasl.h"
+#include "warnless.h"
+#include "strtok.h"
+#include "strequal.h"
+#include "rawstr.h"
+#include "sendf.h"
+#include "non-ascii.h" /* included for Curl_convert_... prototypes */
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* Supported mechanisms */
+const struct {
+ const char *name; /* Name */
+ size_t len; /* Name length */
+ unsigned int bit; /* Flag bit */
+} mechtable[] = {
+ { "LOGIN", 5, SASL_MECH_LOGIN },
+ { "PLAIN", 5, SASL_MECH_PLAIN },
+ { "CRAM-MD5", 8, SASL_MECH_CRAM_MD5 },
+ { "DIGEST-MD5", 10, SASL_MECH_DIGEST_MD5 },
+ { "GSSAPI", 6, SASL_MECH_GSSAPI },
+ { "EXTERNAL", 8, SASL_MECH_EXTERNAL },
+ { "NTLM", 4, SASL_MECH_NTLM },
+ { "XOAUTH2", 7, SASL_MECH_XOAUTH2 },
+ { ZERO_NULL, 0, 0 }
+};
+
+#if !defined(CURL_DISABLE_CRYPTO_AUTH) && !defined(USE_WINDOWS_SSPI)
+#define DIGEST_QOP_VALUE_AUTH (1 << 0)
+#define DIGEST_QOP_VALUE_AUTH_INT (1 << 1)
+#define DIGEST_QOP_VALUE_AUTH_CONF (1 << 2)
+
+#define DIGEST_QOP_VALUE_STRING_AUTH "auth"
+#define DIGEST_QOP_VALUE_STRING_AUTH_INT "auth-int"
+#define DIGEST_QOP_VALUE_STRING_AUTH_CONF "auth-conf"
+
+/* The CURL_OUTPUT_DIGEST_CONV macro below is for non-ASCII machines.
+ It converts digest text to ASCII so the MD5 will be correct for
+ what ultimately goes over the network.
+*/
+#define CURL_OUTPUT_DIGEST_CONV(a, b) \
+ result = Curl_convert_to_network(a, (char *)b, strlen((const char*)b)); \
+ if(result) { \
+ free(b); \
+ return result; \
+ }
+
+#endif
+
+#if !defined(CURL_DISABLE_CRYPTO_AUTH)
+/*
+ * Returns 0 on success and then the buffers are filled in fine.
+ *
+ * Non-zero means failure to parse.
+ */
+int Curl_sasl_digest_get_pair(const char *str, char *value, char *content,
+ const char **endptr)
+{
+ int c;
+ bool starts_with_quote = FALSE;
+ bool escape = FALSE;
+
+ for(c = DIGEST_MAX_VALUE_LENGTH - 1; (*str && (*str != '=') && c--); )
+ *value++ = *str++;
+ *value = 0;
+
+ if('=' != *str++)
+ /* eek, no match */
+ return 1;
+
+ if('\"' == *str) {
+ /* this starts with a quote so it must end with one as well! */
+ str++;
+ starts_with_quote = TRUE;
+ }
+
+ for(c = DIGEST_MAX_CONTENT_LENGTH - 1; *str && c--; str++) {
+ switch(*str) {
+ case '\\':
+ if(!escape) {
+ /* possibly the start of an escaped quote */
+ escape = TRUE;
+ *content++ = '\\'; /* even though this is an escape character, we still
+ store it as-is in the target buffer */
+ continue;
+ }
+ break;
+ case ',':
+ if(!starts_with_quote) {
+ /* this signals the end of the content if we didn't get a starting
+ quote and then we do "sloppy" parsing */
+ c = 0; /* the end */
+ continue;
+ }
+ break;
+ case '\r':
+ case '\n':
+ /* end of string */
+ c = 0;
+ continue;
+ case '\"':
+ if(!escape && starts_with_quote) {
+ /* end of string */
+ c = 0;
+ continue;
+ }
+ break;
+ }
+ escape = FALSE;
+ *content++ = *str;
+ }
+ *content = 0;
+
+ *endptr = str;
+
+ return 0; /* all is fine! */
+}
+#endif
+
+#if !defined(CURL_DISABLE_CRYPTO_AUTH) && !defined(USE_WINDOWS_SSPI)
+/* Convert md5 chunk to RFC2617 (section 3.1.3) -suitable ascii string*/
+static void sasl_digest_md5_to_ascii(unsigned char *source, /* 16 bytes */
+ unsigned char *dest) /* 33 bytes */
+{
+ int i;
+ for(i = 0; i < 16; i++)
+ snprintf((char *)&dest[i*2], 3, "%02x", source[i]);
+}
+
+/* Perform quoted-string escaping as described in RFC2616 and its errata */
+static char *sasl_digest_string_quoted(const char *source)
+{
+ char *dest, *d;
+ const char *s = source;
+ size_t n = 1; /* null terminator */
+
+ /* Calculate size needed */
+ while(*s) {
+ ++n;
+ if(*s == '"' || *s == '\\') {
+ ++n;
+ }
+ ++s;
+ }
+
+ dest = malloc(n);
+ if(dest) {
+ s = source;
+ d = dest;
+ while(*s) {
+ if(*s == '"' || *s == '\\') {
+ *d++ = '\\';
+ }
+ *d++ = *s++;
+ }
+ *d = 0;
+ }
+
+ return dest;
+}
+
+/* Retrieves the value for a corresponding key from the challenge string
+ * returns TRUE if the key could be found, FALSE if it does not exists
+ */
+static bool sasl_digest_get_key_value(const char *chlg,
+ const char *key,
+ char *value,
+ size_t max_val_len,
+ char end_char)
+{
+ char *find_pos;
+ size_t i;
+
+ find_pos = strstr(chlg, key);
+ if(!find_pos)
+ return FALSE;
+
+ find_pos += strlen(key);
+
+ for(i = 0; *find_pos && *find_pos != end_char && i < max_val_len - 1; ++i)
+ value[i] = *find_pos++;
+ value[i] = '\0';
+
+ return TRUE;
+}
+
+static CURLcode sasl_digest_get_qop_values(const char *options, int *value)
+{
+ char *tmp;
+ char *token;
+ char *tok_buf;
+
+ /* Initialise the output */
+ *value = 0;
+
+ /* Tokenise the list of qop values. Use a temporary clone of the buffer since
+ strtok_r() ruins it. */
+ tmp = strdup(options);
+ if(!tmp)
+ return CURLE_OUT_OF_MEMORY;
+
+ token = strtok_r(tmp, ",", &tok_buf);
+ while(token != NULL) {
+ if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH))
+ *value |= DIGEST_QOP_VALUE_AUTH;
+ else if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH_INT))
+ *value |= DIGEST_QOP_VALUE_AUTH_INT;
+ else if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH_CONF))
+ *value |= DIGEST_QOP_VALUE_AUTH_CONF;
+
+ token = strtok_r(NULL, ",", &tok_buf);
+ }
+
+ free(tmp);
+
+ return CURLE_OK;
+}
+#endif /* !CURL_DISABLE_CRYPTO_AUTH && !USE_WINDOWS_SSPI */
+
+#if !defined(USE_WINDOWS_SSPI)
+/*
+ * Curl_sasl_build_spn()
+ *
+ * This is used to build a SPN string in the format service/host.
+ *
+ * Parameters:
+ *
+ * service [in] - The service type such as www, smtp, pop or imap.
+ * host [in] - The host name or realm.
+ *
+ * Returns a pointer to the newly allocated SPN.
+ */
+char *Curl_sasl_build_spn(const char *service, const char *host)
+{
+ /* Generate and return our SPN */
+ return aprintf("%s/%s", service, host);
+}
+#endif
+
+/*
+ * sasl_create_plain_message()
+ *
+ * This is used to generate an already encoded PLAIN message ready
+ * for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data [in] - The session handle.
+ * userp [in] - The user name.
+ * passdwp [in] - The user's password.
+ * outptr [in/out] - The address where a pointer to newly allocated memory
+ * holding the result will be stored upon completion.
+ * outlen [out] - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+static CURLcode sasl_create_plain_message(struct SessionHandle *data,
+ const char *userp,
+ const char *passwdp,
+ char **outptr, size_t *outlen)
+{
+ CURLcode result;
+ char *plainauth;
+ size_t ulen;
+ size_t plen;
+
+ ulen = strlen(userp);
+ plen = strlen(passwdp);
+
+ plainauth = malloc(2 * ulen + plen + 2);
+ if(!plainauth) {
+ *outlen = 0;
+ *outptr = NULL;
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ /* Calculate the reply */
+ memcpy(plainauth, userp, ulen);
+ plainauth[ulen] = '\0';
+ memcpy(plainauth + ulen + 1, userp, ulen);
+ plainauth[2 * ulen + 1] = '\0';
+ memcpy(plainauth + 2 * ulen + 2, passwdp, plen);
+
+ /* Base64 encode the reply */
+ result = Curl_base64_encode(data, plainauth, 2 * ulen + plen + 2, outptr,
+ outlen);
+ free(plainauth);
+ return result;
+}
+
+/*
+ * sasl_create_login_message()
+ *
+ * This is used to generate an already encoded LOGIN message containing the
+ * user name or password ready for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data [in] - The session handle.
+ * valuep [in] - The user name or user's password.
+ * outptr [in/out] - The address where a pointer to newly allocated memory
+ * holding the result will be stored upon completion.
+ * outlen [out] - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+static CURLcode sasl_create_login_message(struct SessionHandle *data,
+ const char *valuep, char **outptr,
+ size_t *outlen)
+{
+ size_t vlen = strlen(valuep);
+
+ if(!vlen) {
+ /* Calculate an empty reply */
+ *outptr = strdup("=");
+ if(*outptr) {
+ *outlen = (size_t) 1;
+ return CURLE_OK;
+ }
+
+ *outlen = 0;
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ /* Base64 encode the value */
+ return Curl_base64_encode(data, valuep, vlen, outptr, outlen);
+}
+
+/*
+ * sasl_create_external_message()
+ *
+ * This is used to generate an already encoded EXTERNAL message containing
+ * the user name ready for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data [in] - The session handle.
+ * user [in] - The user name.
+ * outptr [in/out] - The address where a pointer to newly allocated memory
+ * holding the result will be stored upon completion.
+ * outlen [out] - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+static CURLcode sasl_create_external_message(struct SessionHandle *data,
+ const char *user, char **outptr,
+ size_t *outlen)
+{
+ /* This is the same formatting as the login message. */
+ return sasl_create_login_message(data, user, outptr, outlen);
+}
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+ /*
+ * sasl_decode_cram_md5_message()
+ *
+ * This is used to decode an already encoded CRAM-MD5 challenge message.
+ *
+ * Parameters:
+ *
+ * chlg64 [in] - The base64 encoded challenge message.
+ * outptr [in/out] - The address where a pointer to newly allocated memory
+ * holding the result will be stored upon completion.
+ * outlen [out] - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+static CURLcode sasl_decode_cram_md5_message(const char *chlg64, char **outptr,
+ size_t *outlen)
+{
+ CURLcode result = CURLE_OK;
+ size_t chlg64len = strlen(chlg64);
+
+ *outptr = NULL;
+ *outlen = 0;
+
+ /* Decode the challenge if necessary */
+ if(chlg64len && *chlg64 != '=')
+ result = Curl_base64_decode(chlg64, (unsigned char **) outptr, outlen);
+
+ return result;
+ }
+
+ /*
+ * sasl_create_cram_md5_message()
+ *
+ * This is used to generate an already encoded CRAM-MD5 response message ready
+ * for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data [in] - The session handle.
+ * chlg [in] - The challenge.
+ * userp [in] - The user name.
+ * passdwp [in] - The user's password.
+ * outptr [in/out] - The address where a pointer to newly allocated memory
+ * holding the result will be stored upon completion.
+ * outlen [out] - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+static CURLcode sasl_create_cram_md5_message(struct SessionHandle *data,
+ const char *chlg,
+ const char *userp,
+ const char *passwdp,
+ char **outptr, size_t *outlen)
+{
+ CURLcode result = CURLE_OK;
+ size_t chlglen = 0;
+ HMAC_context *ctxt;
+ unsigned char digest[MD5_DIGEST_LEN];
+ char *response;
+
+ if(chlg)
+ chlglen = strlen(chlg);
+
+ /* Compute the digest using the password as the key */
+ ctxt = Curl_HMAC_init(Curl_HMAC_MD5,
+ (const unsigned char *) passwdp,
+ curlx_uztoui(strlen(passwdp)));
+ if(!ctxt)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Update the digest with the given challenge */
+ if(chlglen > 0)
+ Curl_HMAC_update(ctxt, (const unsigned char *) chlg,
+ curlx_uztoui(chlglen));
+
+ /* Finalise the digest */
+ Curl_HMAC_final(ctxt, digest);
+
+ /* Generate the response */
+ response = aprintf(
+ "%s %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+ userp, digest[0], digest[1], digest[2], digest[3], digest[4],
+ digest[5], digest[6], digest[7], digest[8], digest[9], digest[10],
+ digest[11], digest[12], digest[13], digest[14], digest[15]);
+ if(!response)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Base64 encode the response */
+ result = Curl_base64_encode(data, response, 0, outptr, outlen);
+
+ free(response);
+
+ return result;
+}
+
+#ifndef USE_WINDOWS_SSPI
+/*
+ * sasl_decode_digest_md5_message()
+ *
+ * This is used internally to decode an already encoded DIGEST-MD5 challenge
+ * message into the seperate attributes.
+ *
+ * Parameters:
+ *
+ * chlg64 [in] - The base64 encoded challenge message.
+ * nonce [in/out] - The buffer where the nonce will be stored.
+ * nlen [in] - The length of the nonce buffer.
+ * realm [in/out] - The buffer where the realm will be stored.
+ * rlen [in] - The length of the realm buffer.
+ * alg [in/out] - The buffer where the algorithm will be stored.
+ * alen [in] - The length of the algorithm buffer.
+ * qop [in/out] - The buffer where the qop-options will be stored.
+ * qlen [in] - The length of the qop buffer.
+ *
+ * Returns CURLE_OK on success.
+ */
+static CURLcode sasl_decode_digest_md5_message(const char *chlg64,
+ char *nonce, size_t nlen,
+ char *realm, size_t rlen,
+ char *alg, size_t alen,
+ char *qop, size_t qlen)
+{
+ CURLcode result = CURLE_OK;
+ unsigned char *chlg = NULL;
+ size_t chlglen = 0;
+ size_t chlg64len = strlen(chlg64);
+
+ /* Decode the base-64 encoded challenge message */
+ if(chlg64len && *chlg64 != '=') {
+ result = Curl_base64_decode(chlg64, &chlg, &chlglen);
+ if(result)
+ return result;
+ }
+
+ /* Ensure we have a valid challenge message */
+ if(!chlg)
+ return CURLE_BAD_CONTENT_ENCODING;
+
+ /* Retrieve nonce string from the challenge */
+ if(!sasl_digest_get_key_value((char *)chlg, "nonce=\"", nonce, nlen, '\"')) {
+ free(chlg);
+ return CURLE_BAD_CONTENT_ENCODING;
+ }
+
+ /* Retrieve realm string from the challenge */
+ if(!sasl_digest_get_key_value((char *)chlg, "realm=\"", realm, rlen, '\"')) {
+ /* Challenge does not have a realm, set empty string [RFC2831] page 6 */
+ strcpy(realm, "");
+ }
+
+ /* Retrieve algorithm string from the challenge */
+ if(!sasl_digest_get_key_value((char *)chlg, "algorithm=", alg, alen, ',')) {
+ free(chlg);
+ return CURLE_BAD_CONTENT_ENCODING;
+ }
+
+ /* Retrieve qop-options string from the challenge */
+ if(!sasl_digest_get_key_value((char *)chlg, "qop=\"", qop, qlen, '\"')) {
+ free(chlg);
+ return CURLE_BAD_CONTENT_ENCODING;
+ }
+
+ free(chlg);
+
+ return CURLE_OK;
+}
+
+/*
+ * Curl_sasl_create_digest_md5_message()
+ *
+ * This is used to generate an already encoded DIGEST-MD5 response message
+ * ready for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data [in] - The session handle.
+ * chlg64 [in] - The base64 encoded challenge message.
+ * userp [in] - The user name.
+ * passdwp [in] - The user's password.
+ * service [in] - The service type such as www, smtp, pop or imap.
+ * outptr [in/out] - The address where a pointer to newly allocated memory
+ * holding the result will be stored upon completion.
+ * outlen [out] - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
+ const char *chlg64,
+ const char *userp,
+ const char *passwdp,
+ const char *service,
+ char **outptr, size_t *outlen)
+{
+ CURLcode result = CURLE_OK;
+ size_t i;
+ MD5_context *ctxt;
+ char *response = NULL;
+ unsigned char digest[MD5_DIGEST_LEN];
+ char HA1_hex[2 * MD5_DIGEST_LEN + 1];
+ char HA2_hex[2 * MD5_DIGEST_LEN + 1];
+ char resp_hash_hex[2 * MD5_DIGEST_LEN + 1];
+ char nonce[64];
+ char realm[128];
+ char algorithm[64];
+ char qop_options[64];
+ int qop_values;
+ char cnonce[33];
+ unsigned int entropy[4];
+ char nonceCount[] = "00000001";
+ char method[] = "AUTHENTICATE";
+ char qop[] = DIGEST_QOP_VALUE_STRING_AUTH;
+ char *spn = NULL;
+
+ /* Decode the challange message */
+ result = sasl_decode_digest_md5_message(chlg64, nonce, sizeof(nonce),
+ realm, sizeof(realm),
+ algorithm, sizeof(algorithm),
+ qop_options, sizeof(qop_options));
+ if(result)
+ return result;
+
+ /* We only support md5 sessions */
+ if(strcmp(algorithm, "md5-sess") != 0)
+ return CURLE_BAD_CONTENT_ENCODING;
+
+ /* Get the qop-values from the qop-options */
+ result = sasl_digest_get_qop_values(qop_options, &qop_values);
+ if(result)
+ return result;
+
+ /* We only support auth quality-of-protection */
+ if(!(qop_values & DIGEST_QOP_VALUE_AUTH))
+ return CURLE_BAD_CONTENT_ENCODING;
+
+ /* Generate 16 bytes of random data */
+ entropy[0] = Curl_rand(data);
+ entropy[1] = Curl_rand(data);
+ entropy[2] = Curl_rand(data);
+ entropy[3] = Curl_rand(data);
+
+ /* Convert the random data into a 32 byte hex string */
+ snprintf(cnonce, sizeof(cnonce), "%08x%08x%08x%08x",
+ entropy[0], entropy[1], entropy[2], entropy[3]);
+
+ /* So far so good, now calculate A1 and H(A1) according to RFC 2831 */
+ ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
+ if(!ctxt)
+ return CURLE_OUT_OF_MEMORY;
+
+ Curl_MD5_update(ctxt, (const unsigned char *) userp,
+ curlx_uztoui(strlen(userp)));
+ Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+ Curl_MD5_update(ctxt, (const unsigned char *) realm,
+ curlx_uztoui(strlen(realm)));
+ Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+ Curl_MD5_update(ctxt, (const unsigned char *) passwdp,
+ curlx_uztoui(strlen(passwdp)));
+ Curl_MD5_final(ctxt, digest);
+
+ ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
+ if(!ctxt)
+ return CURLE_OUT_OF_MEMORY;
+
+ Curl_MD5_update(ctxt, (const unsigned char *) digest, MD5_DIGEST_LEN);
+ Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+ Curl_MD5_update(ctxt, (const unsigned char *) nonce,
+ curlx_uztoui(strlen(nonce)));
+ Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+ Curl_MD5_update(ctxt, (const unsigned char *) cnonce,
+ curlx_uztoui(strlen(cnonce)));
+ Curl_MD5_final(ctxt, digest);
+
+ /* Convert calculated 16 octet hex into 32 bytes string */
+ for(i = 0; i < MD5_DIGEST_LEN; i++)
+ snprintf(&HA1_hex[2 * i], 3, "%02x", digest[i]);
+
+ /* Generate our SPN */
+ spn = Curl_sasl_build_spn(service, realm);
+ if(!spn)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Calculate H(A2) */
+ ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
+ if(!ctxt) {
+ free(spn);
+
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ Curl_MD5_update(ctxt, (const unsigned char *) method,
+ curlx_uztoui(strlen(method)));
+ Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+ Curl_MD5_update(ctxt, (const unsigned char *) spn,
+ curlx_uztoui(strlen(spn)));
+ Curl_MD5_final(ctxt, digest);
+
+ for(i = 0; i < MD5_DIGEST_LEN; i++)
+ snprintf(&HA2_hex[2 * i], 3, "%02x", digest[i]);
+
+ /* Now calculate the response hash */
+ ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
+ if(!ctxt) {
+ free(spn);
+
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ Curl_MD5_update(ctxt, (const unsigned char *) HA1_hex, 2 * MD5_DIGEST_LEN);
+ Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+ Curl_MD5_update(ctxt, (const unsigned char *) nonce,
+ curlx_uztoui(strlen(nonce)));
+ Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+
+ Curl_MD5_update(ctxt, (const unsigned char *) nonceCount,
+ curlx_uztoui(strlen(nonceCount)));
+ Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+ Curl_MD5_update(ctxt, (const unsigned char *) cnonce,
+ curlx_uztoui(strlen(cnonce)));
+ Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+ Curl_MD5_update(ctxt, (const unsigned char *) qop,
+ curlx_uztoui(strlen(qop)));
+ Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+
+ Curl_MD5_update(ctxt, (const unsigned char *) HA2_hex, 2 * MD5_DIGEST_LEN);
+ Curl_MD5_final(ctxt, digest);
+
+ for(i = 0; i < MD5_DIGEST_LEN; i++)
+ snprintf(&resp_hash_hex[2 * i], 3, "%02x", digest[i]);
+
+ /* Generate the response */
+ response = aprintf("username=\"%s\",realm=\"%s\",nonce=\"%s\","
+ "cnonce=\"%s\",nc=\"%s\",digest-uri=\"%s\",response=%s,"
+ "qop=%s",
+ userp, realm, nonce,
+ cnonce, nonceCount, spn, resp_hash_hex, qop);
+ free(spn);
+ if(!response)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Base64 encode the response */
+ result = Curl_base64_encode(data, response, 0, outptr, outlen);
+
+ free(response);
+
+ return result;
+}
+
+/*
+ * Curl_sasl_decode_digest_http_message()
+ *
+ * This is used to decode a HTTP DIGEST challenge message into the seperate
+ * attributes.
+ *
+ * Parameters:
+ *
+ * chlg [in] - The challenge message.
+ * digest [in/out] - The digest data struct being used and modified.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_decode_digest_http_message(const char *chlg,
+ struct digestdata *digest)
+{
+ bool before = FALSE; /* got a nonce before */
+ bool foundAuth = FALSE;
+ bool foundAuthInt = FALSE;
+ char *token = NULL;
+ char *tmp = NULL;
+
+ /* If we already have received a nonce, keep that in mind */
+ if(digest->nonce)
+ before = TRUE;
+
+ /* Clean up any former leftovers and initialise to defaults */
+ Curl_sasl_digest_cleanup(digest);
+
+ for(;;) {
+ char value[DIGEST_MAX_VALUE_LENGTH];
+ char content[DIGEST_MAX_CONTENT_LENGTH];
+
+ /* Pass all additional spaces here */
+ while(*chlg && ISSPACE(*chlg))
+ chlg++;
+
+ /* Extract a value=content pair */
+ if(!Curl_sasl_digest_get_pair(chlg, value, content, &chlg)) {
+ if(Curl_raw_equal(value, "nonce")) {
+ digest->nonce = strdup(content);
+ if(!digest->nonce)
+ return CURLE_OUT_OF_MEMORY;
+ }
+ else if(Curl_raw_equal(value, "stale")) {
+ if(Curl_raw_equal(content, "true")) {
+ digest->stale = TRUE;
+ digest->nc = 1; /* we make a new nonce now */
+ }
+ }
+ else if(Curl_raw_equal(value, "realm")) {
+ digest->realm = strdup(content);
+ if(!digest->realm)
+ return CURLE_OUT_OF_MEMORY;
+ }
+ else if(Curl_raw_equal(value, "opaque")) {
+ digest->opaque = strdup(content);
+ if(!digest->opaque)
+ return CURLE_OUT_OF_MEMORY;
+ }
+ else if(Curl_raw_equal(value, "qop")) {
+ char *tok_buf;
+ /* Tokenize the list and choose auth if possible, use a temporary
+ clone of the buffer since strtok_r() ruins it */
+ tmp = strdup(content);
+ if(!tmp)
+ return CURLE_OUT_OF_MEMORY;
+
+ token = strtok_r(tmp, ",", &tok_buf);
+ while(token != NULL) {
+ if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH)) {
+ foundAuth = TRUE;
+ }
+ else if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH_INT)) {
+ foundAuthInt = TRUE;
+ }
+ token = strtok_r(NULL, ",", &tok_buf);
+ }
+
+ free(tmp);
+
+ /* Select only auth or auth-int. Otherwise, ignore */
+ if(foundAuth) {
+ digest->qop = strdup(DIGEST_QOP_VALUE_STRING_AUTH);
+ if(!digest->qop)
+ return CURLE_OUT_OF_MEMORY;
+ }
+ else if(foundAuthInt) {
+ digest->qop = strdup(DIGEST_QOP_VALUE_STRING_AUTH_INT);
+ if(!digest->qop)
+ return CURLE_OUT_OF_MEMORY;
+ }
+ }
+ else if(Curl_raw_equal(value, "algorithm")) {
+ digest->algorithm = strdup(content);
+ if(!digest->algorithm)
+ return CURLE_OUT_OF_MEMORY;
+
+ if(Curl_raw_equal(content, "MD5-sess"))
+ digest->algo = CURLDIGESTALGO_MD5SESS;
+ else if(Curl_raw_equal(content, "MD5"))
+ digest->algo = CURLDIGESTALGO_MD5;
+ else
+ return CURLE_BAD_CONTENT_ENCODING;
+ }
+ else {
+ /* unknown specifier, ignore it! */
+ }
+ }
+ else
+ break; /* we're done here */
+
+ /* Pass all additional spaces here */
+ while(*chlg && ISSPACE(*chlg))
+ chlg++;
+
+ /* Allow the list to be comma-separated */
+ if(',' == *chlg)
+ chlg++;
+ }
+
+ /* We had a nonce since before, and we got another one now without
+ 'stale=true'. This means we provided bad credentials in the previous
+ request */
+ if(before && !digest->stale)
+ return CURLE_BAD_CONTENT_ENCODING;
+
+ /* We got this header without a nonce, that's a bad Digest line! */
+ if(!digest->nonce)
+ return CURLE_BAD_CONTENT_ENCODING;
+
+ return CURLE_OK;
+}
+
+/*
+ * Curl_sasl_create_digest_http_message()
+ *
+ * This is used to generate a HTTP DIGEST response message ready for sending
+ * to the recipient.
+ *
+ * Parameters:
+ *
+ * data [in] - The session handle.
+ * userp [in] - The user name.
+ * passdwp [in] - The user's password.
+ * request [in] - The HTTP request.
+ * uripath [in] - The path of the HTTP uri.
+ * digest [in/out] - The digest data struct being used and modified.
+ * outptr [in/out] - The address where a pointer to newly allocated memory
+ * holding the result will be stored upon completion.
+ * outlen [out] - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_create_digest_http_message(struct SessionHandle *data,
+ const char *userp,
+ const char *passwdp,
+ const unsigned char *request,
+ const unsigned char *uripath,
+ struct digestdata *digest,
+ char **outptr, size_t *outlen)
+{
+ CURLcode result;
+ unsigned char md5buf[16]; /* 16 bytes/128 bits */
+ unsigned char request_digest[33];
+ unsigned char *md5this;
+ unsigned char ha1[33];/* 32 digits and 1 zero byte */
+ unsigned char ha2[33];/* 32 digits and 1 zero byte */
+ char cnoncebuf[33];
+ char *cnonce = NULL;
+ size_t cnonce_sz = 0;
+ char *userp_quoted;
+ char *response = NULL;
+ char *tmp = NULL;
+
+ if(!digest->nc)
+ digest->nc = 1;
+
+ if(!digest->cnonce) {
+ snprintf(cnoncebuf, sizeof(cnoncebuf), "%08x%08x%08x%08x",
+ Curl_rand(data), Curl_rand(data),
+ Curl_rand(data), Curl_rand(data));
+
+ result = Curl_base64_encode(data, cnoncebuf, strlen(cnoncebuf),
+ &cnonce, &cnonce_sz);
+ if(result)
+ return result;
+
+ digest->cnonce = cnonce;
+ }
+
+ /*
+ if the algorithm is "MD5" or unspecified (which then defaults to MD5):
+
+ A1 = unq(username-value) ":" unq(realm-value) ":" passwd
+
+ if the algorithm is "MD5-sess" then:
+
+ A1 = H( unq(username-value) ":" unq(realm-value) ":" passwd )
+ ":" unq(nonce-value) ":" unq(cnonce-value)
+ */
+
+ md5this = (unsigned char *)
+ aprintf("%s:%s:%s", userp, digest->realm, passwdp);
+ if(!md5this)
+ return CURLE_OUT_OF_MEMORY;
+
+ CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
+ Curl_md5it(md5buf, md5this);
+ free(md5this);
+ sasl_digest_md5_to_ascii(md5buf, ha1);
+
+ if(digest->algo == CURLDIGESTALGO_MD5SESS) {
+ /* nonce and cnonce are OUTSIDE the hash */
+ tmp = aprintf("%s:%s:%s", ha1, digest->nonce, digest->cnonce);
+ if(!tmp)
+ return CURLE_OUT_OF_MEMORY;
+
+ CURL_OUTPUT_DIGEST_CONV(data, tmp); /* convert on non-ASCII machines */
+ Curl_md5it(md5buf, (unsigned char *)tmp);
+ free(tmp);
+ sasl_digest_md5_to_ascii(md5buf, ha1);
+ }
+
+ /*
+ If the "qop" directive's value is "auth" or is unspecified, then A2 is:
+
+ A2 = Method ":" digest-uri-value
+
+ If the "qop" value is "auth-int", then A2 is:
+
+ A2 = Method ":" digest-uri-value ":" H(entity-body)
+
+ (The "Method" value is the HTTP request method as specified in section
+ 5.1.1 of RFC 2616)
+ */
+
+ md5this = (unsigned char *)aprintf("%s:%s", request, uripath);
+
+ if(digest->qop && Curl_raw_equal(digest->qop, "auth-int")) {
+ /* We don't support auth-int for PUT or POST at the moment.
+ TODO: replace md5 of empty string with entity-body for PUT/POST */
+ unsigned char *md5this2 = (unsigned char *)
+ aprintf("%s:%s", md5this, "d41d8cd98f00b204e9800998ecf8427e");
+ free(md5this);
+ md5this = md5this2;
+ }
+
+ if(!md5this)
+ return CURLE_OUT_OF_MEMORY;
+
+ CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
+ Curl_md5it(md5buf, md5this);
+ free(md5this);
+ sasl_digest_md5_to_ascii(md5buf, ha2);
+
+ if(digest->qop) {
+ md5this = (unsigned char *)aprintf("%s:%s:%08x:%s:%s:%s",
+ ha1,
+ digest->nonce,
+ digest->nc,
+ digest->cnonce,
+ digest->qop,
+ ha2);
+ }
+ else {
+ md5this = (unsigned char *)aprintf("%s:%s:%s",
+ ha1,
+ digest->nonce,
+ ha2);
+ }
+
+ if(!md5this)
+ return CURLE_OUT_OF_MEMORY;
+
+ CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
+ Curl_md5it(md5buf, md5this);
+ free(md5this);
+ sasl_digest_md5_to_ascii(md5buf, request_digest);
+
+ /* for test case 64 (snooped from a Mozilla 1.3a request)
+
+ Authorization: Digest username="testuser", realm="testrealm", \
+ nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca"
+
+ Digest parameters are all quoted strings. Username which is provided by
+ the user will need double quotes and backslashes within it escaped. For
+ the other fields, this shouldn't be an issue. realm, nonce, and opaque
+ are copied as is from the server, escapes and all. cnonce is generated
+ with web-safe characters. uri is already percent encoded. nc is 8 hex
+ characters. algorithm and qop with standard values only contain web-safe
+ chracters.
+ */
+ userp_quoted = sasl_digest_string_quoted(userp);
+ if(!userp_quoted)
+ return CURLE_OUT_OF_MEMORY;
+
+ if(digest->qop) {
+ response = aprintf("username=\"%s\", "
+ "realm=\"%s\", "
+ "nonce=\"%s\", "
+ "uri=\"%s\", "
+ "cnonce=\"%s\", "
+ "nc=%08x, "
+ "qop=%s, "
+ "response=\"%s\"",
+ userp_quoted,
+ digest->realm,
+ digest->nonce,
+ uripath,
+ digest->cnonce,
+ digest->nc,
+ digest->qop,
+ request_digest);
+
+ if(Curl_raw_equal(digest->qop, "auth"))
+ digest->nc++; /* The nc (from RFC) has to be a 8 hex digit number 0
+ padded which tells to the server how many times you are
+ using the same nonce in the qop=auth mode */
+ }
+ else {
+ response = aprintf("username=\"%s\", "
+ "realm=\"%s\", "
+ "nonce=\"%s\", "
+ "uri=\"%s\", "
+ "response=\"%s\"",
+ userp_quoted,
+ digest->realm,
+ digest->nonce,
+ uripath,
+ request_digest);
+ }
+ free(userp_quoted);
+ if(!response)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Add the optional fields */
+ if(digest->opaque) {
+ /* Append the opaque */
+ tmp = aprintf("%s, opaque=\"%s\"", response, digest->opaque);
+ free(response);
+ if(!tmp)
+ return CURLE_OUT_OF_MEMORY;
+
+ response = tmp;
+ }
+
+ if(digest->algorithm) {
+ /* Append the algorithm */
+ tmp = aprintf("%s, algorithm=\"%s\"", response, digest->algorithm);
+ free(response);
+ if(!tmp)
+ return CURLE_OUT_OF_MEMORY;
+
+ response = tmp;
+ }
+
+ /* Return the output */
+ *outptr = response;
+ *outlen = strlen(response);
+
+ return CURLE_OK;
+}
+
+/*
+ * Curl_sasl_digest_cleanup()
+ *
+ * This is used to clean up the digest specific data.
+ *
+ * Parameters:
+ *
+ * digest [in/out] - The digest data struct being cleaned up.
+ *
+ */
+void Curl_sasl_digest_cleanup(struct digestdata *digest)
+{
+ Curl_safefree(digest->nonce);
+ Curl_safefree(digest->cnonce);
+ Curl_safefree(digest->realm);
+ Curl_safefree(digest->opaque);
+ Curl_safefree(digest->qop);
+ Curl_safefree(digest->algorithm);
+
+ digest->nc = 0;
+ digest->algo = CURLDIGESTALGO_MD5; /* default algorithm */
+ digest->stale = FALSE; /* default means normal, not stale */
+}
+#endif /* !USE_WINDOWS_SSPI */
+
+#endif /* CURL_DISABLE_CRYPTO_AUTH */
+
+#if defined(USE_NTLM) && !defined(USE_WINDOWS_SSPI)
+/*
+ * Curl_sasl_ntlm_cleanup()
+ *
+ * This is used to clean up the ntlm specific data.
+ *
+ * Parameters:
+ *
+ * ntlm [in/out] - The ntlm data struct being cleaned up.
+ *
+ */
+void Curl_sasl_ntlm_cleanup(struct ntlmdata *ntlm)
+{
+ /* Free the target info */
+ Curl_safefree(ntlm->target_info);
+
+ /* Reset any variables */
+ ntlm->target_info_len = 0;
+}
+#endif /* USE_NTLM && !USE_WINDOWS_SSPI*/
+
+/*
+ * sasl_create_xoauth2_message()
+ *
+ * This is used to generate an already encoded OAuth 2.0 message ready for
+ * sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data [in] - The session handle.
+ * user [in] - The user name.
+ * bearer [in] - The bearer token.
+ * outptr [in/out] - The address where a pointer to newly allocated memory
+ * holding the result will be stored upon completion.
+ * outlen [out] - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+static CURLcode sasl_create_xoauth2_message(struct SessionHandle *data,
+ const char *user,
+ const char *bearer,
+ char **outptr, size_t *outlen)
+{
+ CURLcode result = CURLE_OK;
+ char *xoauth = NULL;
+
+ /* Generate the message */
+ xoauth = aprintf("user=%s\1auth=Bearer %s\1\1", user, bearer);
+ if(!xoauth)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Base64 encode the reply */
+ result = Curl_base64_encode(data, xoauth, strlen(xoauth), outptr, outlen);
+
+ free(xoauth);
+
+ return result;
+}
+
+/*
+ * Curl_sasl_cleanup()
+ *
+ * This is used to cleanup any libraries or curl modules used by the sasl
+ * functions.
+ *
+ * Parameters:
+ *
+ * conn [in] - The connection data.
+ * authused [in] - The authentication mechanism used.
+ */
+void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused)
+{
+#if defined(USE_KERBEROS5)
+ /* Cleanup the gssapi structure */
+ if(authused == SASL_MECH_GSSAPI) {
+ Curl_sasl_gssapi_cleanup(&conn->krb5);
+ }
+#endif
+
+#if defined(USE_NTLM)
+ /* Cleanup the ntlm structure */
+ if(authused == SASL_MECH_NTLM) {
+ Curl_sasl_ntlm_cleanup(&conn->ntlm);
+ }
+#endif
+
+#if !defined(USE_KERBEROS5) && !defined(USE_NTLM)
+ /* Reserved for future use */
+ (void)conn;
+ (void)authused;
+#endif
+}
+
+/*
+ * Curl_sasl_decode_mech()
+ *
+ * Convert a SASL mechanism name into a token.
+ *
+ * Parameters:
+ *
+ * ptr [in] - The mechanism string.
+ * maxlen [in] - Maximum mechanism string length.
+ * len [out] - If not NULL, effective name length.
+ *
+ * Returns the SASL mechanism token or 0 if no match.
+ */
+unsigned int Curl_sasl_decode_mech(const char *ptr, size_t maxlen, size_t *len)
+{
+ unsigned int i;
+ char c;
+
+ for(i = 0; mechtable[i].name; i++) {
+ if(maxlen >= mechtable[i].len &&
+ !memcmp(ptr, mechtable[i].name, mechtable[i].len)) {
+ if(len)
+ *len = mechtable[i].len;
+
+ if(maxlen == mechtable[i].len)
+ return mechtable[i].bit;
+
+ c = ptr[mechtable[i].len];
+ if(!ISUPPER(c) && !ISDIGIT(c) && c != '-' && c != '_')
+ return mechtable[i].bit;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Curl_sasl_parse_url_auth_option()
+ *
+ * Parse the URL login options.
+ */
+CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl,
+ const char *value, size_t len)
+{
+ CURLcode result = CURLE_OK;
+ unsigned int mechbit;
+ size_t mechlen;
+
+ if(!len)
+ return CURLE_URL_MALFORMAT;
+
+ if(sasl->resetprefs) {
+ sasl->resetprefs = FALSE;
+ sasl->prefmech = SASL_AUTH_NONE;
+ }
+
+ if(strnequal(value, "*", len))
+ sasl->prefmech = SASL_AUTH_DEFAULT;
+ else if((mechbit = Curl_sasl_decode_mech(value, len, &mechlen)) &&
+ mechlen == len)
+ sasl->prefmech |= mechbit;
+ else
+ result = CURLE_URL_MALFORMAT;
+
+ return result;
+}
+
+/*
+ * Curl_sasl_init()
+ *
+ * Initializes the SASL structure.
+ */
+void Curl_sasl_init(struct SASL *sasl, const struct SASLproto *params)
+{
+ sasl->params = params; /* Set protocol dependent parameters */
+ sasl->state = SASL_STOP; /* Not yet running */
+ sasl->authmechs = SASL_AUTH_NONE; /* No known authentication mechanism yet */
+ sasl->prefmech = SASL_AUTH_DEFAULT; /* Prefer all mechanisms */
+ sasl->authused = SASL_AUTH_NONE; /* No the authentication mechanism used */
+ sasl->resetprefs = TRUE; /* Reset prefmech upon AUTH parsing. */
+ sasl->mutual_auth = FALSE; /* No mutual authentication (GSSAPI only) */
+ sasl->force_ir = FALSE; /* Respect external option */
+}
+
+/*
+ * state()
+ *
+ * This is the ONLY way to change SASL state!
+ */
+static void state(struct SASL *sasl, struct connectdata *conn,
+ saslstate newstate)
+{
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+ /* for debug purposes */
+ static const char * const names[]={
+ "STOP",
+ "PLAIN",
+ "LOGIN",
+ "LOGIN_PASSWD",
+ "EXTERNAL",
+ "CRAMMD5",
+ "DIGESTMD5",
+ "DIGESTMD5_RESP",
+ "NTLM",
+ "NTLM_TYPE2MSG",
+ "GSSAPI",
+ "GSSAPI_TOKEN",
+ "GSSAPI_NO_DATA",
+ "XOAUTH2",
+ "CANCEL",
+ "FINAL",
+ /* LAST */
+ };
+
+ if(sasl->state != newstate)
+ infof(conn->data, "SASL %p state change from %s to %s\n",
+ (void *)sasl, names[sasl->state], names[newstate]);
+#else
+ (void) conn;
+#endif
+
+ sasl->state = newstate;
+}
+
+/*
+ * Curl_sasl_can_authenticate()
+ *
+ * Check if we have enough auth data and capabilities to authenticate.
+ */
+bool Curl_sasl_can_authenticate(struct SASL *sasl, struct connectdata *conn)
+{
+ /* Have credentials been provided? */
+ if(conn->bits.user_passwd)
+ return TRUE;
+
+ /* EXTERNAL can authenticate without a user name and/or password */
+ if(sasl->authmechs & sasl->prefmech & SASL_MECH_EXTERNAL)
+ return TRUE;
+
+ return FALSE;
+}
+
+/*
+ * Curl_sasl_start()
+ *
+ * Calculate the required login details for SASL authentication.
+ */
+CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
+ bool force_ir, saslprogress *progress)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ unsigned int enabledmechs;
+ const char *mech = NULL;
+ char *resp = NULL;
+ size_t len = 0;
+ saslstate state1 = SASL_STOP;
+ saslstate state2 = SASL_FINAL;
+
+ sasl->force_ir = force_ir; /* Latch for future use */
+ sasl->authused = 0; /* No mechanism used yet */
+ enabledmechs = sasl->authmechs & sasl->prefmech;
+ *progress = SASL_IDLE;
+
+ /* Calculate the supported authentication mechanism, by decreasing order of
+ security, as well as the initial response where appropriate */
+ if((enabledmechs & SASL_MECH_EXTERNAL) && !conn->passwd[0]) {
+ mech = SASL_MECH_STRING_EXTERNAL;
+ state1 = SASL_EXTERNAL;
+ sasl->authused = SASL_MECH_EXTERNAL;
+
+ if(force_ir || data->set.sasl_ir)
+ result = sasl_create_external_message(data, conn->user, &resp, &len);
+ }
+ else if(conn->bits.user_passwd) {
+#if defined(USE_KERBEROS5)
+ if(enabledmechs & SASL_MECH_GSSAPI) {
+ sasl->mutual_auth = FALSE; /* TODO: Calculate mutual authentication */
+ mech = SASL_MECH_STRING_GSSAPI;
+ state1 = SASL_GSSAPI;
+ state2 = SASL_GSSAPI_TOKEN;
+ sasl->authused = SASL_MECH_GSSAPI;
+
+ if(force_ir || data->set.sasl_ir)
+ result = Curl_sasl_create_gssapi_user_message(data, conn->user,
+ conn->passwd,
+ sasl->params->service,
+ sasl->mutual_auth,
+ NULL, &conn->krb5,
+ &resp, &len);
+ }
+ else
+#endif
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+ if(enabledmechs & SASL_MECH_DIGEST_MD5) {
+ mech = SASL_MECH_STRING_DIGEST_MD5;
+ state1 = SASL_DIGESTMD5;
+ sasl->authused = SASL_MECH_DIGEST_MD5;
+ }
+ else if(enabledmechs & SASL_MECH_CRAM_MD5) {
+ mech = SASL_MECH_STRING_CRAM_MD5;
+ state1 = SASL_CRAMMD5;
+ sasl->authused = SASL_MECH_CRAM_MD5;
+ }
+ else
+#endif
+#ifdef USE_NTLM
+ if(enabledmechs & SASL_MECH_NTLM) {
+ mech = SASL_MECH_STRING_NTLM;
+ state1 = SASL_NTLM;
+ state2 = SASL_NTLM_TYPE2MSG;
+ sasl->authused = SASL_MECH_NTLM;
+
+ if(force_ir || data->set.sasl_ir)
+ result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd,
+ &conn->ntlm, &resp, &len);
+ }
+ else
+#endif
+ if((enabledmechs & SASL_MECH_XOAUTH2) || conn->xoauth2_bearer) {
+ mech = SASL_MECH_STRING_XOAUTH2;
+ state1 = SASL_XOAUTH2;
+ sasl->authused = SASL_MECH_XOAUTH2;
+
+ if(force_ir || data->set.sasl_ir)
+ result = sasl_create_xoauth2_message(data, conn->user,
+ conn->xoauth2_bearer,
+ &resp, &len);
+ }
+ else if(enabledmechs & SASL_MECH_LOGIN) {
+ mech = SASL_MECH_STRING_LOGIN;
+ state1 = SASL_LOGIN;
+ state2 = SASL_LOGIN_PASSWD;
+ sasl->authused = SASL_MECH_LOGIN;
+
+ if(force_ir || data->set.sasl_ir)
+ result = sasl_create_login_message(data, conn->user, &resp, &len);
+ }
+ else if(enabledmechs & SASL_MECH_PLAIN) {
+ mech = SASL_MECH_STRING_PLAIN;
+ state1 = SASL_PLAIN;
+ sasl->authused = SASL_MECH_PLAIN;
+
+ if(force_ir || data->set.sasl_ir)
+ result = sasl_create_plain_message(data, conn->user, conn->passwd,
+ &resp, &len);
+ }
+ }
+
+ if(!result) {
+ if(resp && sasl->params->maxirlen &&
+ strlen(mech) + len > sasl->params->maxirlen) {
+ free(resp);
+ resp = NULL;
+ }
+
+ if(mech) {
+ result = sasl->params->sendauth(conn, mech, resp);
+ if(!result) {
+ *progress = SASL_INPROGRESS;
+ state(sasl, conn, resp? state2: state1);
+ }
+ }
+ }
+
+ free(resp);
+
+ return result;
+}
+
+/*
+ * Curl_sasl_continue()
+ *
+ * Continue the authentication.
+ */
+CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
+ int code, saslprogress *progress)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ saslstate newstate = SASL_FINAL;
+ char *resp = NULL;
+#if !defined(CURL_DISABLE_CRYPTO_AUTH)
+ char *serverdata;
+ char *chlg = NULL;
+ size_t chlglen = 0;
+#endif
+ size_t len = 0;
+
+ *progress = SASL_INPROGRESS;
+
+ if(sasl->state == SASL_FINAL) {
+ if(code != sasl->params->finalcode)
+ result = CURLE_LOGIN_DENIED;
+ *progress = SASL_DONE;
+ state(sasl, conn, SASL_STOP);
+ return result;
+ }
+
+ if(sasl->state != SASL_CANCEL && code != sasl->params->contcode) {
+ *progress = SASL_DONE;
+ state(sasl, conn, SASL_STOP);
+ return CURLE_LOGIN_DENIED;
+ }
+
+ switch(sasl->state) {
+ case SASL_STOP:
+ *progress = SASL_DONE;
+ return result;
+ case SASL_PLAIN:
+ result = sasl_create_plain_message(data, conn->user, conn->passwd, &resp,
+ &len);
+ break;
+ case SASL_LOGIN:
+ result = sasl_create_login_message(data, conn->user, &resp, &len);
+ newstate = SASL_LOGIN_PASSWD;
+ break;
+ case SASL_LOGIN_PASSWD:
+ result = sasl_create_login_message(data, conn->passwd, &resp, &len);
+ break;
+ case SASL_EXTERNAL:
+ result = sasl_create_external_message(data, conn->user, &resp, &len);
+ break;
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+ case SASL_CRAMMD5:
+ sasl->params->getmessage(data->state.buffer, &serverdata);
+ result = sasl_decode_cram_md5_message(serverdata, &chlg, &chlglen);
+ if(!result)
+ result = sasl_create_cram_md5_message(data, chlg, conn->user,
+ conn->passwd, &resp, &len);
+ free(chlg);
+ break;
+ case SASL_DIGESTMD5:
+ sasl->params->getmessage(data->state.buffer, &serverdata);
+ result = Curl_sasl_create_digest_md5_message(data, serverdata,
+ conn->user, conn->passwd,
+ sasl->params->service,
+ &resp, &len);
+ newstate = SASL_DIGESTMD5_RESP;
+ break;
+ case SASL_DIGESTMD5_RESP:
+ if(!(resp = strdup("")))
+ result = CURLE_OUT_OF_MEMORY;
+ break;
+#endif
+
+#ifdef USE_NTLM
+ case SASL_NTLM:
+ /* Create the type-1 message */
+ result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd,
+ &conn->ntlm, &resp, &len);
+ newstate = SASL_NTLM_TYPE2MSG;
+ break;
+ case SASL_NTLM_TYPE2MSG:
+ /* Decode the type-2 message */
+ sasl->params->getmessage(data->state.buffer, &serverdata);
+ result = Curl_sasl_decode_ntlm_type2_message(data, serverdata,
+ &conn->ntlm);
+ if(!result)
+ result = Curl_sasl_create_ntlm_type3_message(data, conn->user,
+ conn->passwd, &conn->ntlm,
+ &resp, &len);
+ break;
+#endif
+
+#if defined(USE_KERBEROS5)
+ case SASL_GSSAPI:
+ result = Curl_sasl_create_gssapi_user_message(data, conn->user,
+ conn->passwd,
+ sasl->params->service,
+ sasl->mutual_auth, NULL,
+ &conn->krb5,
+ &resp, &len);
+ newstate = SASL_GSSAPI_TOKEN;
+ break;
+ case SASL_GSSAPI_TOKEN:
+ sasl->params->getmessage(data->state.buffer, &serverdata);
+ if(sasl->mutual_auth) {
+ /* Decode the user token challenge and create the optional response
+ message */
+ result = Curl_sasl_create_gssapi_user_message(data, NULL, NULL, NULL,
+ sasl->mutual_auth,
+ serverdata, &conn->krb5,
+ &resp, &len);
+ newstate = SASL_GSSAPI_NO_DATA;
+ }
+ else
+ /* Decode the security challenge and create the response message */
+ result = Curl_sasl_create_gssapi_security_message(data, serverdata,
+ &conn->krb5,
+ &resp, &len);
+ break;
+ case SASL_GSSAPI_NO_DATA:
+ sasl->params->getmessage(data->state.buffer, &serverdata);
+ /* Decode the security challenge and create the response message */
+ result = Curl_sasl_create_gssapi_security_message(data, serverdata,
+ &conn->krb5,
+ &resp, &len);
+ break;
+#endif
+
+ case SASL_XOAUTH2:
+ /* Create the authorisation message */
+ result = sasl_create_xoauth2_message(data, conn->user,
+ conn->xoauth2_bearer, &resp, &len);
+ break;
+ case SASL_CANCEL:
+ /* Remove the offending mechanism from the supported list */
+ sasl->authmechs ^= sasl->authused;
+
+ /* Start an alternative SASL authentication */
+ result = Curl_sasl_start(sasl, conn, sasl->force_ir, progress);
+ newstate = sasl->state; /* Use state from Curl_sasl_start() */
+ break;
+ default:
+ failf(data, "Unsupported SASL authentication mechanism");
+ result = CURLE_UNSUPPORTED_PROTOCOL; /* Should not happen */
+ break;
+ }
+
+ switch(result) {
+ case CURLE_BAD_CONTENT_ENCODING:
+ /* Cancel dialog */
+ result = sasl->params->sendcont(conn, "*");
+ newstate = SASL_CANCEL;
+ break;
+ case CURLE_OK:
+ if(resp)
+ result = sasl->params->sendcont(conn, resp);
+ break;
+ default:
+ newstate = SASL_STOP; /* Stop on error */
+ *progress = SASL_DONE;
+ break;
+ }
+
+ free(resp);
+
+ state(sasl, conn, newstate);
+
+ return result;
+}
diff --git a/Utilities/cmcurl/lib/curl_sasl.h b/Utilities/cmcurl/lib/curl_sasl.h
new file mode 100644
index 000000000..117d60e32
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_sasl.h
@@ -0,0 +1,254 @@
+#ifndef HEADER_CURL_SASL_H
+#define HEADER_CURL_SASL_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <curl/curl.h>
+
+struct SessionHandle;
+struct connectdata;
+
+#if !defined(CURL_DISABLE_CRYPTO_AUTH)
+struct digestdata;
+#endif
+
+#if defined(USE_NTLM)
+struct ntlmdata;
+#endif
+
+#if defined(USE_KERBEROS5)
+struct kerberos5data;
+#endif
+
+/* Authentication mechanism flags */
+#define SASL_MECH_LOGIN (1 << 0)
+#define SASL_MECH_PLAIN (1 << 1)
+#define SASL_MECH_CRAM_MD5 (1 << 2)
+#define SASL_MECH_DIGEST_MD5 (1 << 3)
+#define SASL_MECH_GSSAPI (1 << 4)
+#define SASL_MECH_EXTERNAL (1 << 5)
+#define SASL_MECH_NTLM (1 << 6)
+#define SASL_MECH_XOAUTH2 (1 << 7)
+
+/* Authentication mechanism values */
+#define SASL_AUTH_NONE 0
+#define SASL_AUTH_ANY ~0U
+#define SASL_AUTH_DEFAULT (SASL_AUTH_ANY & \
+ ~(SASL_MECH_EXTERNAL | SASL_MECH_XOAUTH2))
+
+/* Authentication mechanism strings */
+#define SASL_MECH_STRING_LOGIN "LOGIN"
+#define SASL_MECH_STRING_PLAIN "PLAIN"
+#define SASL_MECH_STRING_CRAM_MD5 "CRAM-MD5"
+#define SASL_MECH_STRING_DIGEST_MD5 "DIGEST-MD5"
+#define SASL_MECH_STRING_GSSAPI "GSSAPI"
+#define SASL_MECH_STRING_EXTERNAL "EXTERNAL"
+#define SASL_MECH_STRING_NTLM "NTLM"
+#define SASL_MECH_STRING_XOAUTH2 "XOAUTH2"
+
+#if !defined(CURL_DISABLE_CRYPTO_AUTH)
+#define DIGEST_MAX_VALUE_LENGTH 256
+#define DIGEST_MAX_CONTENT_LENGTH 1024
+#endif
+
+enum {
+ CURLDIGESTALGO_MD5,
+ CURLDIGESTALGO_MD5SESS
+};
+
+/* SASL machine states */
+typedef enum {
+ SASL_STOP,
+ SASL_PLAIN,
+ SASL_LOGIN,
+ SASL_LOGIN_PASSWD,
+ SASL_EXTERNAL,
+ SASL_CRAMMD5,
+ SASL_DIGESTMD5,
+ SASL_DIGESTMD5_RESP,
+ SASL_NTLM,
+ SASL_NTLM_TYPE2MSG,
+ SASL_GSSAPI,
+ SASL_GSSAPI_TOKEN,
+ SASL_GSSAPI_NO_DATA,
+ SASL_XOAUTH2,
+ SASL_CANCEL,
+ SASL_FINAL
+} saslstate;
+
+/* Progress indicator */
+typedef enum {
+ SASL_IDLE,
+ SASL_INPROGRESS,
+ SASL_DONE
+} saslprogress;
+
+/* Protocol dependent SASL parameters */
+struct SASLproto {
+ const char *service; /* The service name */
+ int contcode; /* Code to receive when continuation is expected */
+ int finalcode; /* Code to receive upon authentication success */
+ size_t maxirlen; /* Maximum initial response length */
+ CURLcode (*sendauth)(struct connectdata *conn,
+ const char *mech, const char *ir);
+ /* Send authentication command */
+ CURLcode (*sendcont)(struct connectdata *conn, const char *contauth);
+ /* Send authentication continuation */
+ void (*getmessage)(char *buffer, char **outptr);
+ /* Get SASL response message */
+};
+
+/* Per-connection parameters */
+struct SASL {
+ const struct SASLproto *params; /* Protocol dependent parameters */
+ saslstate state; /* Current machine state */
+ unsigned int authmechs; /* Accepted authentication mechanisms */
+ unsigned int prefmech; /* Preferred authentication mechanism */
+ unsigned int authused; /* Auth mechanism used for the connection */
+ bool resetprefs; /* For URL auth option parsing. */
+ bool mutual_auth; /* Mutual authentication enabled (GSSAPI only) */
+ bool force_ir; /* Protocol always supports initial response */
+};
+
+/* This is used to test whether the line starts with the given mechanism */
+#define sasl_mech_equal(line, wordlen, mech) \
+ (wordlen == (sizeof(mech) - 1) / sizeof(char) && \
+ !memcmp(line, mech, wordlen))
+
+/* This is used to build a SPN string */
+#if !defined(USE_WINDOWS_SSPI)
+char *Curl_sasl_build_spn(const char *service, const char *instance);
+#else
+TCHAR *Curl_sasl_build_spn(const char *service, const char *instance);
+#endif
+
+/* This is used to extract the realm from a challenge message */
+int Curl_sasl_digest_get_pair(const char *str, char *value, char *content,
+ const char **endptr);
+
+#if defined(HAVE_GSSAPI)
+char *Curl_sasl_build_gssapi_spn(const char *service, const char *host);
+#endif
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+
+/* This is used to generate a base64 encoded DIGEST-MD5 response message */
+CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
+ const char *chlg64,
+ const char *userp,
+ const char *passwdp,
+ const char *service,
+ char **outptr, size_t *outlen);
+
+/* This is used to decode a HTTP DIGEST challenge message */
+CURLcode Curl_sasl_decode_digest_http_message(const char *chlg,
+ struct digestdata *digest);
+
+/* This is used to generate a HTTP DIGEST response message */
+CURLcode Curl_sasl_create_digest_http_message(struct SessionHandle *data,
+ const char *userp,
+ const char *passwdp,
+ const unsigned char *request,
+ const unsigned char *uri,
+ struct digestdata *digest,
+ char **outptr, size_t *outlen);
+
+/* This is used to clean up the digest specific data */
+void Curl_sasl_digest_cleanup(struct digestdata *digest);
+#endif
+
+#ifdef USE_NTLM
+/* This is used to generate a base64 encoded NTLM type-1 message */
+CURLcode Curl_sasl_create_ntlm_type1_message(const char *userp,
+ const char *passwdp,
+ struct ntlmdata *ntlm,
+ char **outptr,
+ size_t *outlen);
+
+/* This is used to decode a base64 encoded NTLM type-2 message */
+CURLcode Curl_sasl_decode_ntlm_type2_message(struct SessionHandle *data,
+ const char *type2msg,
+ struct ntlmdata *ntlm);
+
+/* This is used to generate a base64 encoded NTLM type-3 message */
+CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
+ const char *userp,
+ const char *passwdp,
+ struct ntlmdata *ntlm,
+ char **outptr, size_t *outlen);
+
+/* This is used to clean up the ntlm specific data */
+void Curl_sasl_ntlm_cleanup(struct ntlmdata *ntlm);
+
+#endif /* USE_NTLM */
+
+#if defined(USE_KERBEROS5)
+/* This is used to generate a base64 encoded GSSAPI (Kerberos V5) user token
+ message */
+CURLcode Curl_sasl_create_gssapi_user_message(struct SessionHandle *data,
+ const char *userp,
+ const char *passwdp,
+ const char *service,
+ const bool mutual,
+ const char *chlg64,
+ struct kerberos5data *krb5,
+ char **outptr, size_t *outlen);
+
+/* This is used to generate a base64 encoded GSSAPI (Kerberos V5) security
+ token message */
+CURLcode Curl_sasl_create_gssapi_security_message(struct SessionHandle *data,
+ const char *input,
+ struct kerberos5data *krb5,
+ char **outptr,
+ size_t *outlen);
+
+/* This is used to clean up the gssapi specific data */
+void Curl_sasl_gssapi_cleanup(struct kerberos5data *krb5);
+#endif /* USE_KERBEROS5 */
+
+/* This is used to cleanup any libraries or curl modules used by the sasl
+ functions */
+void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused);
+
+/* Convert a mechanism name to a token */
+unsigned int Curl_sasl_decode_mech(const char *ptr,
+ size_t maxlen, size_t *len);
+
+/* Parse the URL login options */
+CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl,
+ const char *value, size_t len);
+
+/* Initializes an SASL structure */
+void Curl_sasl_init(struct SASL *sasl, const struct SASLproto *params);
+
+/* Check if we have enough auth data and capabilities to authenticate */
+bool Curl_sasl_can_authenticate(struct SASL *sasl, struct connectdata *conn);
+
+/* Calculate the required login details for SASL authentication */
+CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
+ bool force_ir, saslprogress *progress);
+
+/* Continue an SASL authentication */
+CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
+ int code, saslprogress *progress);
+
+#endif /* HEADER_CURL_SASL_H */
diff --git a/Utilities/cmcurl/lib/curl_sasl_gssapi.c b/Utilities/cmcurl/lib/curl_sasl_gssapi.c
new file mode 100644
index 000000000..3c6f3ce32
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_sasl_gssapi.c
@@ -0,0 +1,392 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2014 - 2015, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(HAVE_GSSAPI) && defined(USE_KERBEROS5)
+
+#include <curl/curl.h>
+
+#include "curl_sasl.h"
+#include "urldata.h"
+#include "curl_base64.h"
+#include "curl_gssapi.h"
+#include "sendf.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+* Curl_sasl_build_gssapi_spn()
+*
+* This is used to build a SPN string in the format service@host.
+*
+* Parameters:
+*
+* serivce [in] - The service type such as www, smtp, pop or imap.
+* host [in] - The host name or realm.
+*
+* Returns a pointer to the newly allocated SPN.
+*/
+char *Curl_sasl_build_gssapi_spn(const char *service, const char *host)
+{
+ /* Generate and return our SPN */
+ return aprintf("%s@%s", service, host);
+}
+
+/*
+ * Curl_sasl_create_gssapi_user_message()
+ *
+ * This is used to generate an already encoded GSSAPI (Kerberos V5) user token
+ * message ready for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data [in] - The session handle.
+ * userp [in] - The user name.
+ * passdwp [in] - The user's password.
+ * service [in] - The service type such as www, smtp, pop or imap.
+ * mutual_auth [in] - Flag specifing whether or not mutual authentication
+ * is enabled.
+ * chlg64 [in] - Pointer to the optional base64 encoded challenge
+ * message.
+ * krb5 [in/out] - The gssapi data struct being used and modified.
+ * outptr [in/out] - The address where a pointer to newly allocated memory
+ * holding the result will be stored upon completion.
+ * outlen [out] - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_create_gssapi_user_message(struct SessionHandle *data,
+ const char *userp,
+ const char *passwdp,
+ const char *service,
+ const bool mutual_auth,
+ const char *chlg64,
+ struct kerberos5data *krb5,
+ char **outptr, size_t *outlen)
+{
+ CURLcode result = CURLE_OK;
+ size_t chlglen = 0;
+ unsigned char *chlg = NULL;
+ OM_uint32 gss_status;
+ OM_uint32 gss_major_status;
+ OM_uint32 gss_minor_status;
+ gss_buffer_desc spn_token = GSS_C_EMPTY_BUFFER;
+ gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
+ gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+
+ (void) userp;
+ (void) passwdp;
+
+ if(krb5->context == GSS_C_NO_CONTEXT) {
+ /* Generate our SPN */
+ char *spn = Curl_sasl_build_gssapi_spn(service,
+ data->easy_conn->host.name);
+ if(!spn)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Populate the SPN structure */
+ spn_token.value = spn;
+ spn_token.length = strlen(spn);
+
+ /* Import the SPN */
+ gss_major_status = gss_import_name(&gss_minor_status, &spn_token,
+ GSS_C_NT_HOSTBASED_SERVICE, &krb5->spn);
+ if(GSS_ERROR(gss_major_status)) {
+ Curl_gss_log_error(data, gss_minor_status, "gss_import_name() failed: ");
+
+ free(spn);
+
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ free(spn);
+ }
+ else {
+ /* Decode the base-64 encoded challenge message */
+ if(strlen(chlg64) && *chlg64 != '=') {
+ result = Curl_base64_decode(chlg64, &chlg, &chlglen);
+ if(result)
+ return result;
+ }
+
+ /* Ensure we have a valid challenge message */
+ if(!chlg) {
+ infof(data, "GSSAPI handshake failure (empty challenge message)\n");
+
+ return CURLE_BAD_CONTENT_ENCODING;
+ }
+
+ /* Setup the challenge "input" security buffer */
+ input_token.value = chlg;
+ input_token.length = chlglen;
+ }
+
+ gss_major_status = Curl_gss_init_sec_context(data,
+ &gss_minor_status,
+ &krb5->context,
+ krb5->spn,
+ &Curl_krb5_mech_oid,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ &input_token,
+ &output_token,
+ mutual_auth,
+ NULL);
+
+ free(input_token.value);
+
+ if(GSS_ERROR(gss_major_status)) {
+ if(output_token.value)
+ gss_release_buffer(&gss_status, &output_token);
+
+ Curl_gss_log_error(data, gss_minor_status,
+ "gss_init_sec_context() failed: ");
+
+ return CURLE_RECV_ERROR;
+ }
+
+ if(output_token.value && output_token.length) {
+ /* Base64 encode the response */
+ result = Curl_base64_encode(data, (char *) output_token.value,
+ output_token.length, outptr, outlen);
+
+ gss_release_buffer(&gss_status, &output_token);
+ }
+
+ return result;
+}
+
+/*
+ * Curl_sasl_create_gssapi_security_message()
+ *
+ * This is used to generate an already encoded GSSAPI (Kerberos V5) security
+ * token message ready for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data [in] - The session handle.
+ * chlg64 [in] - Pointer to the optional base64 encoded challenge message.
+ * krb5 [in/out] - The gssapi data struct being used and modified.
+ * outptr [in/out] - The address where a pointer to newly allocated memory
+ * holding the result will be stored upon completion.
+ * outlen [out] - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_create_gssapi_security_message(struct SessionHandle *data,
+ const char *chlg64,
+ struct kerberos5data *krb5,
+ char **outptr,
+ size_t *outlen)
+{
+ CURLcode result = CURLE_OK;
+ size_t chlglen = 0;
+ size_t messagelen = 0;
+ unsigned char *chlg = NULL;
+ unsigned char *message = NULL;
+ OM_uint32 gss_status;
+ OM_uint32 gss_major_status;
+ OM_uint32 gss_minor_status;
+ gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
+ gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+ unsigned int indata = 0;
+ unsigned int outdata = 0;
+ gss_qop_t qop = GSS_C_QOP_DEFAULT;
+ unsigned int sec_layer = 0;
+ unsigned int max_size = 0;
+ gss_name_t username = GSS_C_NO_NAME;
+ gss_buffer_desc username_token;
+
+ /* Decode the base-64 encoded input message */
+ if(strlen(chlg64) && *chlg64 != '=') {
+ result = Curl_base64_decode(chlg64, &chlg, &chlglen);
+ if(result)
+ return result;
+ }
+
+ /* Ensure we have a valid challenge message */
+ if(!chlg) {
+ infof(data, "GSSAPI handshake failure (empty security message)\n");
+
+ return CURLE_BAD_CONTENT_ENCODING;
+ }
+
+ /* Get the fully qualified username back from the context */
+ gss_major_status = gss_inquire_context(&gss_minor_status, krb5->context,
+ &username, NULL, NULL, NULL, NULL,
+ NULL, NULL);
+ if(GSS_ERROR(gss_major_status)) {
+ Curl_gss_log_error(data, gss_minor_status,
+ "gss_inquire_context() failed: ");
+
+ free(chlg);
+
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ /* Convert the username from internal format to a displayable token */
+ gss_major_status = gss_display_name(&gss_minor_status, username,
+ &username_token, NULL);
+ if(GSS_ERROR(gss_major_status)) {
+ Curl_gss_log_error(data, gss_minor_status, "gss_display_name() failed: ");
+
+ free(chlg);
+
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ /* Setup the challenge "input" security buffer */
+ input_token.value = chlg;
+ input_token.length = chlglen;
+
+ /* Decrypt the inbound challenge and obtain the qop */
+ gss_major_status = gss_unwrap(&gss_minor_status, krb5->context, &input_token,
+ &output_token, NULL, &qop);
+ if(GSS_ERROR(gss_major_status)) {
+ Curl_gss_log_error(data, gss_minor_status, "gss_unwrap() failed: ");
+
+ gss_release_buffer(&gss_status, &username_token);
+ free(chlg);
+
+ return CURLE_BAD_CONTENT_ENCODING;
+ }
+
+ /* Not 4 octets long so fail as per RFC4752 Section 3.1 */
+ if(output_token.length != 4) {
+ infof(data, "GSSAPI handshake failure (invalid security data)\n");
+
+ gss_release_buffer(&gss_status, &username_token);
+ free(chlg);
+
+ return CURLE_BAD_CONTENT_ENCODING;
+ }
+
+ /* Copy the data out and free the challenge as it is not required anymore */
+ memcpy(&indata, output_token.value, 4);
+ gss_release_buffer(&gss_status, &output_token);
+ free(chlg);
+
+ /* Extract the security layer */
+ sec_layer = indata & 0x000000FF;
+ if(!(sec_layer & GSSAUTH_P_NONE)) {
+ infof(data, "GSSAPI handshake failure (invalid security layer)\n");
+
+ gss_release_buffer(&gss_status, &username_token);
+
+ return CURLE_BAD_CONTENT_ENCODING;
+ }
+
+ /* Extract the maximum message size the server can receive */
+ max_size = ntohl(indata & 0xFFFFFF00);
+ if(max_size > 0) {
+ /* The server has told us it supports a maximum receive buffer, however, as
+ we don't require one unless we are encrypting data, we tell the server
+ our receive buffer is zero. */
+ max_size = 0;
+ }
+
+ /* Allocate our message */
+ messagelen = sizeof(outdata) + username_token.length + 1;
+ message = malloc(messagelen);
+ if(!message) {
+ gss_release_buffer(&gss_status, &username_token);
+
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ /* Populate the message with the security layer, client supported receive
+ message size and authorization identity including the 0x00 based
+ terminator. Note: Dispite RFC4752 Section 3.1 stating "The authorization
+ identity is not terminated with the zero-valued (%x00) octet." it seems
+ necessary to include it. */
+ outdata = htonl(max_size) | sec_layer;
+ memcpy(message, &outdata, sizeof(outdata));
+ memcpy(message + sizeof(outdata), username_token.value,
+ username_token.length);
+ message[messagelen - 1] = '\0';
+
+ /* Free the username token as it is not required anymore */
+ gss_release_buffer(&gss_status, &username_token);
+
+ /* Setup the "authentication data" security buffer */
+ input_token.value = message;
+ input_token.length = messagelen;
+
+ /* Encrypt the data */
+ gss_major_status = gss_wrap(&gss_minor_status, krb5->context, 0,
+ GSS_C_QOP_DEFAULT, &input_token, NULL,
+ &output_token);
+ if(GSS_ERROR(gss_major_status)) {
+ Curl_gss_log_error(data, gss_minor_status, "gss_wrap() failed: ");
+
+ free(message);
+
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ /* Base64 encode the response */
+ result = Curl_base64_encode(data, (char *) output_token.value,
+ output_token.length, outptr, outlen);
+
+ /* Free the output buffer */
+ gss_release_buffer(&gss_status, &output_token);
+
+ /* Free the message buffer */
+ free(message);
+
+ return result;
+}
+
+/*
+ * Curl_sasl_gssapi_cleanup()
+ *
+ * This is used to clean up the gssapi specific data.
+ *
+ * Parameters:
+ *
+ * krb5 [in/out] - The kerberos 5 data struct being cleaned up.
+ *
+ */
+void Curl_sasl_gssapi_cleanup(struct kerberos5data *krb5)
+{
+ OM_uint32 minor_status;
+
+ /* Free our security context */
+ if(krb5->context != GSS_C_NO_CONTEXT) {
+ gss_delete_sec_context(&minor_status, &krb5->context, GSS_C_NO_BUFFER);
+ krb5->context = GSS_C_NO_CONTEXT;
+ }
+
+ /* Free the SPN */
+ if(krb5->spn != GSS_C_NO_NAME) {
+ gss_release_name(&minor_status, &krb5->spn);
+ krb5->spn = GSS_C_NO_NAME;
+ }
+}
+
+#endif /* HAVE_GSSAPI && USE_KERBEROS5 */
diff --git a/Utilities/cmcurl/lib/curl_sasl_sspi.c b/Utilities/cmcurl/lib/curl_sasl_sspi.c
new file mode 100644
index 000000000..b149530ff
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_sasl_sspi.c
@@ -0,0 +1,1281 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2014 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2014, Steve Holme, <steve_holme@hotmail.com>.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * RFC2617 Basic and Digest Access Authentication
+ * RFC2831 DIGEST-MD5 authentication
+ * RFC4422 Simple Authentication and Security Layer (SASL)
+ * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_WINDOWS_SSPI)
+
+#include <curl/curl.h>
+
+#include "curl_sasl.h"
+#include "urldata.h"
+#include "curl_base64.h"
+#include "warnless.h"
+#include "curl_multibyte.h"
+#include "sendf.h"
+#include "strdup.h"
+#include "curl_printf.h"
+#include "rawstr.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+ * Curl_sasl_build_spn()
+ *
+ * This is used to build a SPN string in the format service/host.
+ *
+ * Parameters:
+ *
+ * serivce [in] - The service type such as www, smtp, pop or imap.
+ * host [in] - The host name or realm.
+ *
+ * Returns a pointer to the newly allocated SPN.
+ */
+TCHAR *Curl_sasl_build_spn(const char *service, const char *host)
+{
+ char *utf8_spn = NULL;
+ TCHAR *tchar_spn = NULL;
+
+ /* Note: We could use DsMakeSPN() or DsClientMakeSpnForTargetServer() rather
+ than doing this ourselves but the first is only available in Windows XP
+ and Windows Server 2003 and the latter is only available in Windows 2000
+ but not Windows95/98/ME or Windows NT4.0 unless the Active Directory
+ Client Extensions are installed. As such it is far simpler for us to
+ formulate the SPN instead. */
+
+ /* Allocate our UTF8 based SPN */
+ utf8_spn = aprintf("%s/%s", service, host);
+ if(!utf8_spn) {
+ return NULL;
+ }
+
+ /* Allocate our TCHAR based SPN */
+ tchar_spn = Curl_convert_UTF8_to_tchar(utf8_spn);
+ if(!tchar_spn) {
+ free(utf8_spn);
+
+ return NULL;
+ }
+
+ /* Release the UTF8 variant when operating with Unicode */
+ Curl_unicodefree(utf8_spn);
+
+ /* Return our newly allocated SPN */
+ return tchar_spn;
+}
+
+#if !defined(CURL_DISABLE_CRYPTO_AUTH)
+/*
+ * Curl_sasl_create_digest_md5_message()
+ *
+ * This is used to generate an already encoded DIGEST-MD5 response message
+ * ready for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data [in] - The session handle.
+ * chlg64 [in] - The base64 encoded challenge message.
+ * userp [in] - The user name in the format User or Domain\User.
+ * passdwp [in] - The user's password.
+ * service [in] - The service type such as www, smtp, pop or imap.
+ * outptr [in/out] - The address where a pointer to newly allocated memory
+ * holding the result will be stored upon completion.
+ * outlen [out] - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
+ const char *chlg64,
+ const char *userp,
+ const char *passwdp,
+ const char *service,
+ char **outptr, size_t *outlen)
+{
+ CURLcode result = CURLE_OK;
+ TCHAR *spn = NULL;
+ size_t chlglen = 0;
+ size_t token_max = 0;
+ unsigned char *input_token = NULL;
+ unsigned char *output_token = NULL;
+ CredHandle credentials;
+ CtxtHandle context;
+ PSecPkgInfo SecurityPackage;
+ SEC_WINNT_AUTH_IDENTITY identity;
+ SEC_WINNT_AUTH_IDENTITY *p_identity;
+ SecBuffer chlg_buf;
+ SecBuffer resp_buf;
+ SecBufferDesc chlg_desc;
+ SecBufferDesc resp_desc;
+ SECURITY_STATUS status;
+ unsigned long attrs;
+ TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */
+
+ /* Decode the base-64 encoded challenge message */
+ if(strlen(chlg64) && *chlg64 != '=') {
+ result = Curl_base64_decode(chlg64, &input_token, &chlglen);
+ if(result)
+ return result;
+ }
+
+ /* Ensure we have a valid challenge message */
+ if(!input_token) {
+ infof(data, "DIGEST-MD5 handshake failure (empty challenge message)\n");
+
+ return CURLE_BAD_CONTENT_ENCODING;
+ }
+
+ /* Query the security package for DigestSSP */
+ status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_DIGEST),
+ &SecurityPackage);
+ if(status != SEC_E_OK) {
+ free(input_token);
+
+ return CURLE_NOT_BUILT_IN;
+ }
+
+ token_max = SecurityPackage->cbMaxToken;
+
+ /* Release the package buffer as it is not required anymore */
+ s_pSecFn->FreeContextBuffer(SecurityPackage);
+
+ /* Allocate our response buffer */
+ output_token = malloc(token_max);
+ if(!output_token) {
+ free(input_token);
+
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ /* Generate our SPN */
+ spn = Curl_sasl_build_spn(service, data->easy_conn->host.name);
+ if(!spn) {
+ free(output_token);
+ free(input_token);
+
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ if(userp && *userp) {
+ /* Populate our identity structure */
+ result = Curl_create_sspi_identity(userp, passwdp, &identity);
+ if(result) {
+ free(spn);
+ free(output_token);
+ free(input_token);
+
+ return result;
+ }
+
+ /* Allow proper cleanup of the identity structure */
+ p_identity = &identity;
+ }
+ else
+ /* Use the current Windows user */
+ p_identity = NULL;
+
+ /* Acquire our credentials handle */
+ status = s_pSecFn->AcquireCredentialsHandle(NULL,
+ (TCHAR *) TEXT(SP_NAME_DIGEST),
+ SECPKG_CRED_OUTBOUND, NULL,
+ p_identity, NULL, NULL,
+ &credentials, &expiry);
+
+ if(status != SEC_E_OK) {
+ Curl_sspi_free_identity(p_identity);
+ free(spn);
+ free(output_token);
+ free(input_token);
+
+ return CURLE_LOGIN_DENIED;
+ }
+
+ /* Setup the challenge "input" security buffer */
+ chlg_desc.ulVersion = SECBUFFER_VERSION;
+ chlg_desc.cBuffers = 1;
+ chlg_desc.pBuffers = &chlg_buf;
+ chlg_buf.BufferType = SECBUFFER_TOKEN;
+ chlg_buf.pvBuffer = input_token;
+ chlg_buf.cbBuffer = curlx_uztoul(chlglen);
+
+ /* Setup the response "output" security buffer */
+ resp_desc.ulVersion = SECBUFFER_VERSION;
+ resp_desc.cBuffers = 1;
+ resp_desc.pBuffers = &resp_buf;
+ resp_buf.BufferType = SECBUFFER_TOKEN;
+ resp_buf.pvBuffer = output_token;
+ resp_buf.cbBuffer = curlx_uztoul(token_max);
+
+ /* Generate our response message */
+ status = s_pSecFn->InitializeSecurityContext(&credentials, NULL, spn,
+ 0, 0, 0, &chlg_desc, 0,
+ &context, &resp_desc, &attrs,
+ &expiry);
+
+ if(status == SEC_I_COMPLETE_NEEDED ||
+ status == SEC_I_COMPLETE_AND_CONTINUE)
+ s_pSecFn->CompleteAuthToken(&credentials, &resp_desc);
+ else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) {
+ s_pSecFn->FreeCredentialsHandle(&credentials);
+ Curl_sspi_free_identity(p_identity);
+ free(spn);
+ free(output_token);
+ free(input_token);
+
+ return CURLE_RECV_ERROR;
+ }
+
+ /* Base64 encode the response */
+ result = Curl_base64_encode(data, (char *) output_token, resp_buf.cbBuffer,
+ outptr, outlen);
+
+ /* Free our handles */
+ s_pSecFn->DeleteSecurityContext(&context);
+ s_pSecFn->FreeCredentialsHandle(&credentials);
+
+ /* Free the identity structure */
+ Curl_sspi_free_identity(p_identity);
+
+ /* Free the SPN */
+ free(spn);
+
+ /* Free the response buffer */
+ free(output_token);
+
+ /* Free the decoded challenge message */
+ free(input_token);
+
+ return result;
+}
+
+/*
+* Curl_override_sspi_http_realm()
+*
+* This is used to populate the domain in a SSPI identity structure
+* The realm is extracted from the challenge message and used as the
+* domain if it is not already explicitly set.
+*
+* Parameters:
+*
+* chlg [in] - The challenge message.
+* identity [in/out] - The identity structure.
+*
+* Returns CURLE_OK on success.
+*/
+CURLcode Curl_override_sspi_http_realm(const char *chlg,
+ SEC_WINNT_AUTH_IDENTITY *identity)
+{
+ xcharp_u domain, dup_domain;
+
+ /* If domain is blank or unset, check challenge message for realm */
+ if(!identity->Domain || !identity->DomainLength) {
+ for(;;) {
+ char value[DIGEST_MAX_VALUE_LENGTH];
+ char content[DIGEST_MAX_CONTENT_LENGTH];
+
+ /* Pass all additional spaces here */
+ while(*chlg && ISSPACE(*chlg))
+ chlg++;
+
+ /* Extract a value=content pair */
+ if(!Curl_sasl_digest_get_pair(chlg, value, content, &chlg)) {
+ if(Curl_raw_equal(value, "realm")) {
+
+ /* Setup identity's domain and length */
+ domain.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)content);
+ if(!domain.tchar_ptr)
+ return CURLE_OUT_OF_MEMORY;
+ dup_domain.tchar_ptr = _tcsdup(domain.tchar_ptr);
+ if(!dup_domain.tchar_ptr) {
+ Curl_unicodefree(domain.tchar_ptr);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ identity->Domain = dup_domain.tbyte_ptr;
+ identity->DomainLength = curlx_uztoul(_tcslen(dup_domain.tchar_ptr));
+ dup_domain.tchar_ptr = NULL;
+
+ Curl_unicodefree(domain.tchar_ptr);
+ }
+ else {
+ /* unknown specifier, ignore it! */
+ }
+ }
+ else
+ break; /* we're done here */
+
+ /* Pass all additional spaces here */
+ while(*chlg && ISSPACE(*chlg))
+ chlg++;
+
+ /* Allow the list to be comma-separated */
+ if(',' == *chlg)
+ chlg++;
+ }
+ }
+
+ return CURLE_OK;
+}
+
+/*
+ * Curl_sasl_decode_digest_http_message()
+ *
+ * This is used to decode a HTTP DIGEST challenge message into the seperate
+ * attributes.
+ *
+ * Parameters:
+ *
+ * chlg [in] - The challenge message.
+ * digest [in/out] - The digest data struct being used and modified.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_decode_digest_http_message(const char *chlg,
+ struct digestdata *digest)
+{
+ size_t chlglen = strlen(chlg);
+
+ /* We had an input token before and we got another one now. This means we
+ provided bad credentials in the previous request. */
+ if(digest->input_token)
+ return CURLE_BAD_CONTENT_ENCODING;
+
+ /* Simply store the challenge for use later */
+ digest->input_token = (BYTE *) Curl_memdup(chlg, chlglen);
+ if(!digest->input_token)
+ return CURLE_OUT_OF_MEMORY;
+
+ digest->input_token_len = chlglen;
+
+ return CURLE_OK;
+}
+
+/*
+ * Curl_sasl_create_digest_http_message()
+ *
+ * This is used to generate a HTTP DIGEST response message ready for sending
+ * to the recipient.
+ *
+ * Parameters:
+ *
+ * data [in] - The session handle.
+ * userp [in] - The user name in the format User or Domain\User.
+ * passdwp [in] - The user's password.
+ * request [in] - The HTTP request.
+ * uripath [in] - The path of the HTTP uri.
+ * digest [in/out] - The digest data struct being used and modified.
+ * outptr [in/out] - The address where a pointer to newly allocated memory
+ * holding the result will be stored upon completion.
+ * outlen [out] - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_create_digest_http_message(struct SessionHandle *data,
+ const char *userp,
+ const char *passwdp,
+ const unsigned char *request,
+ const unsigned char *uripath,
+ struct digestdata *digest,
+ char **outptr, size_t *outlen)
+{
+ size_t token_max;
+ CredHandle credentials;
+ CtxtHandle context;
+ char *resp;
+ BYTE *output_token;
+ PSecPkgInfo SecurityPackage;
+ SEC_WINNT_AUTH_IDENTITY identity;
+ SEC_WINNT_AUTH_IDENTITY *p_identity;
+ SecBuffer chlg_buf[3];
+ SecBuffer resp_buf;
+ SecBufferDesc chlg_desc;
+ SecBufferDesc resp_desc;
+ SECURITY_STATUS status;
+ unsigned long attrs;
+ TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */
+
+ (void) data;
+
+ /* Query the security package for DigestSSP */
+ status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_DIGEST),
+ &SecurityPackage);
+ if(status != SEC_E_OK)
+ return CURLE_NOT_BUILT_IN;
+
+ token_max = SecurityPackage->cbMaxToken;
+
+ /* Release the package buffer as it is not required anymore */
+ s_pSecFn->FreeContextBuffer(SecurityPackage);
+
+ /* Allocate the output buffer according to the max token size as indicated
+ by the security package */
+ output_token = malloc(token_max);
+ if(!output_token)
+ return CURLE_OUT_OF_MEMORY;
+
+ if(userp && *userp) {
+ /* Populate our identity structure */
+ if(Curl_create_sspi_identity(userp, passwdp, &identity))
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Populate our identity domain */
+ if(Curl_override_sspi_http_realm((const char*)digest->input_token,
+ &identity))
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Allow proper cleanup of the identity structure */
+ p_identity = &identity;
+ }
+ else
+ /* Use the current Windows user */
+ p_identity = NULL;
+
+ /* Acquire our credentials handle */
+ status = s_pSecFn->AcquireCredentialsHandle(NULL,
+ (TCHAR *) TEXT(SP_NAME_DIGEST),
+ SECPKG_CRED_OUTBOUND, NULL,
+ p_identity, NULL, NULL,
+ &credentials, &expiry);
+ if(status != SEC_E_OK) {
+ free(output_token);
+
+ return CURLE_LOGIN_DENIED;
+ }
+
+ /* Setup the challenge "input" security buffer if present */
+ chlg_desc.ulVersion = SECBUFFER_VERSION;
+ chlg_desc.cBuffers = 3;
+ chlg_desc.pBuffers = chlg_buf;
+ chlg_buf[0].BufferType = SECBUFFER_TOKEN;
+ chlg_buf[0].pvBuffer = digest->input_token;
+ chlg_buf[0].cbBuffer = curlx_uztoul(digest->input_token_len);
+ chlg_buf[1].BufferType = SECBUFFER_PKG_PARAMS;
+ chlg_buf[1].pvBuffer = (void *)request;
+ chlg_buf[1].cbBuffer = curlx_uztoul(strlen((const char *) request));
+ chlg_buf[2].BufferType = SECBUFFER_PKG_PARAMS;
+ chlg_buf[2].pvBuffer = NULL;
+ chlg_buf[2].cbBuffer = 0;
+
+ /* Setup the response "output" security buffer */
+ resp_desc.ulVersion = SECBUFFER_VERSION;
+ resp_desc.cBuffers = 1;
+ resp_desc.pBuffers = &resp_buf;
+ resp_buf.BufferType = SECBUFFER_TOKEN;
+ resp_buf.pvBuffer = output_token;
+ resp_buf.cbBuffer = curlx_uztoul(token_max);
+
+ /* Generate our reponse message */
+ status = s_pSecFn->InitializeSecurityContext(&credentials, NULL,
+ (TCHAR *) uripath,
+ ISC_REQ_USE_HTTP_STYLE, 0, 0,
+ &chlg_desc, 0, &context,
+ &resp_desc, &attrs, &expiry);
+
+ if(status == SEC_I_COMPLETE_NEEDED ||
+ status == SEC_I_COMPLETE_AND_CONTINUE)
+ s_pSecFn->CompleteAuthToken(&credentials, &resp_desc);
+ else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) {
+ s_pSecFn->FreeCredentialsHandle(&credentials);
+
+ free(output_token);
+
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ resp = malloc(resp_buf.cbBuffer + 1);
+ if(!resp) {
+ s_pSecFn->DeleteSecurityContext(&context);
+ s_pSecFn->FreeCredentialsHandle(&credentials);
+
+ free(output_token);
+
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ /* Copy the generated reponse */
+ memcpy(resp, resp_buf.pvBuffer, resp_buf.cbBuffer);
+ resp[resp_buf.cbBuffer] = 0x00;
+
+ /* Return the response */
+ *outptr = resp;
+ *outlen = resp_buf.cbBuffer;
+
+ /* Free our handles */
+ s_pSecFn->DeleteSecurityContext(&context);
+ s_pSecFn->FreeCredentialsHandle(&credentials);
+
+ /* Free the identity structure */
+ Curl_sspi_free_identity(p_identity);
+
+ /* Free the response buffer */
+ free(output_token);
+
+ return CURLE_OK;
+}
+
+/*
+ * Curl_sasl_digest_cleanup()
+ *
+ * This is used to clean up the digest specific data.
+ *
+ * Parameters:
+ *
+ * digest [in/out] - The digest data struct being cleaned up.
+ *
+ */
+void Curl_sasl_digest_cleanup(struct digestdata *digest)
+{
+ /* Free the input token */
+ Curl_safefree(digest->input_token);
+
+ /* Reset any variables */
+ digest->input_token_len = 0;
+}
+#endif /* !CURL_DISABLE_CRYPTO_AUTH */
+
+#if defined USE_NTLM
+/*
+* Curl_sasl_create_ntlm_type1_message()
+*
+* This is used to generate an already encoded NTLM type-1 message ready for
+* sending to the recipient.
+*
+* Parameters:
+*
+* userp [in] - The user name in the format User or Domain\User.
+* passdwp [in] - The user's password.
+* ntlm [in/out] - The ntlm data struct being used and modified.
+* outptr [in/out] - The address where a pointer to newly allocated memory
+* holding the result will be stored upon completion.
+* outlen [out] - The length of the output message.
+*
+* Returns CURLE_OK on success.
+*/
+CURLcode Curl_sasl_create_ntlm_type1_message(const char *userp,
+ const char *passwdp,
+ struct ntlmdata *ntlm,
+ char **outptr, size_t *outlen)
+{
+ PSecPkgInfo SecurityPackage;
+ SecBuffer type_1_buf;
+ SecBufferDesc type_1_desc;
+ SECURITY_STATUS status;
+ unsigned long attrs;
+ TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */
+
+ /* Clean up any former leftovers and initialise to defaults */
+ Curl_sasl_ntlm_cleanup(ntlm);
+
+ /* Query the security package for NTLM */
+ status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_NTLM),
+ &SecurityPackage);
+ if(status != SEC_E_OK)
+ return CURLE_NOT_BUILT_IN;
+
+ ntlm->token_max = SecurityPackage->cbMaxToken;
+
+ /* Release the package buffer as it is not required anymore */
+ s_pSecFn->FreeContextBuffer(SecurityPackage);
+
+ /* Allocate our output buffer */
+ ntlm->output_token = malloc(ntlm->token_max);
+ if(!ntlm->output_token)
+ return CURLE_OUT_OF_MEMORY;
+
+ if(userp && *userp) {
+ CURLcode result;
+
+ /* Populate our identity structure */
+ result = Curl_create_sspi_identity(userp, passwdp, &ntlm->identity);
+ if(result)
+ return result;
+
+ /* Allow proper cleanup of the identity structure */
+ ntlm->p_identity = &ntlm->identity;
+ }
+ else
+ /* Use the current Windows user */
+ ntlm->p_identity = NULL;
+
+ /* Allocate our credentials handle */
+ ntlm->credentials = malloc(sizeof(CredHandle));
+ if(!ntlm->credentials)
+ return CURLE_OUT_OF_MEMORY;
+
+ memset(ntlm->credentials, 0, sizeof(CredHandle));
+
+ /* Acquire our credentials handle */
+ status = s_pSecFn->AcquireCredentialsHandle(NULL,
+ (TCHAR *) TEXT(SP_NAME_NTLM),
+ SECPKG_CRED_OUTBOUND, NULL,
+ ntlm->p_identity, NULL, NULL,
+ ntlm->credentials, &expiry);
+ if(status != SEC_E_OK)
+ return CURLE_LOGIN_DENIED;
+
+ /* Allocate our new context handle */
+ ntlm->context = malloc(sizeof(CtxtHandle));
+ if(!ntlm->context)
+ return CURLE_OUT_OF_MEMORY;
+
+ memset(ntlm->context, 0, sizeof(CtxtHandle));
+
+ /* Setup the type-1 "output" security buffer */
+ type_1_desc.ulVersion = SECBUFFER_VERSION;
+ type_1_desc.cBuffers = 1;
+ type_1_desc.pBuffers = &type_1_buf;
+ type_1_buf.BufferType = SECBUFFER_TOKEN;
+ type_1_buf.pvBuffer = ntlm->output_token;
+ type_1_buf.cbBuffer = curlx_uztoul(ntlm->token_max);
+
+ /* Generate our type-1 message */
+ status = s_pSecFn->InitializeSecurityContext(ntlm->credentials, NULL,
+ (TCHAR *) TEXT(""),
+ 0, 0, SECURITY_NETWORK_DREP,
+ NULL, 0,
+ ntlm->context, &type_1_desc,
+ &attrs, &expiry);
+ if(status == SEC_I_COMPLETE_NEEDED ||
+ status == SEC_I_COMPLETE_AND_CONTINUE)
+ s_pSecFn->CompleteAuthToken(ntlm->context, &type_1_desc);
+ else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED)
+ return CURLE_RECV_ERROR;
+
+ /* Base64 encode the response */
+ return Curl_base64_encode(NULL, (char *) ntlm->output_token,
+ type_1_buf.cbBuffer, outptr, outlen);
+}
+
+/*
+* Curl_sasl_decode_ntlm_type2_message()
+*
+* This is used to decode an already encoded NTLM type-2 message.
+*
+* Parameters:
+*
+* data [in] - The session handle.
+* type2msg [in] - The base64 encoded type-2 message.
+* ntlm [in/out] - The ntlm data struct being used and modified.
+*
+* Returns CURLE_OK on success.
+*/
+CURLcode Curl_sasl_decode_ntlm_type2_message(struct SessionHandle *data,
+ const char *type2msg,
+ struct ntlmdata *ntlm)
+{
+ CURLcode result = CURLE_OK;
+ unsigned char *type2 = NULL;
+ size_t type2_len = 0;
+
+#if defined(CURL_DISABLE_VERBOSE_STRINGS)
+ (void) data;
+#endif
+
+ /* Decode the base-64 encoded type-2 message */
+ if(strlen(type2msg) && *type2msg != '=') {
+ result = Curl_base64_decode(type2msg, &type2, &type2_len);
+ if(result)
+ return result;
+ }
+
+ /* Ensure we have a valid type-2 message */
+ if(!type2) {
+ infof(data, "NTLM handshake failure (empty type-2 message)\n");
+
+ return CURLE_BAD_CONTENT_ENCODING;
+ }
+
+ /* Simply store the challenge for use later */
+ ntlm->input_token = type2;
+ ntlm->input_token_len = type2_len;
+
+ return result;
+}
+
+/*
+* Curl_sasl_create_ntlm_type3_message()
+*
+* This is used to generate an already encoded NTLM type-3 message ready for
+* sending to the recipient.
+*
+* Parameters:
+*
+* data [in] - The session handle.
+* userp [in] - The user name in the format User or Domain\User.
+* passdwp [in] - The user's password.
+* ntlm [in/out] - The ntlm data struct being used and modified.
+* outptr [in/out] - The address where a pointer to newly allocated memory
+* holding the result will be stored upon completion.
+* outlen [out] - The length of the output message.
+*
+* Returns CURLE_OK on success.
+*/
+CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
+ const char *userp,
+ const char *passwdp,
+ struct ntlmdata *ntlm,
+ char **outptr, size_t *outlen)
+{
+ CURLcode result = CURLE_OK;
+ SecBuffer type_2_buf;
+ SecBuffer type_3_buf;
+ SecBufferDesc type_2_desc;
+ SecBufferDesc type_3_desc;
+ SECURITY_STATUS status;
+ unsigned long attrs;
+ TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */
+
+ (void) passwdp;
+ (void) userp;
+
+ /* Setup the type-2 "input" security buffer */
+ type_2_desc.ulVersion = SECBUFFER_VERSION;
+ type_2_desc.cBuffers = 1;
+ type_2_desc.pBuffers = &type_2_buf;
+ type_2_buf.BufferType = SECBUFFER_TOKEN;
+ type_2_buf.pvBuffer = ntlm->input_token;
+ type_2_buf.cbBuffer = curlx_uztoul(ntlm->input_token_len);
+
+ /* Setup the type-3 "output" security buffer */
+ type_3_desc.ulVersion = SECBUFFER_VERSION;
+ type_3_desc.cBuffers = 1;
+ type_3_desc.pBuffers = &type_3_buf;
+ type_3_buf.BufferType = SECBUFFER_TOKEN;
+ type_3_buf.pvBuffer = ntlm->output_token;
+ type_3_buf.cbBuffer = curlx_uztoul(ntlm->token_max);
+
+ /* Generate our type-3 message */
+ status = s_pSecFn->InitializeSecurityContext(ntlm->credentials,
+ ntlm->context,
+ (TCHAR *) TEXT(""),
+ 0, 0, SECURITY_NETWORK_DREP,
+ &type_2_desc,
+ 0, ntlm->context,
+ &type_3_desc,
+ &attrs, &expiry);
+ if(status != SEC_E_OK) {
+ infof(data, "NTLM handshake failure (type-3 message): Status=%x\n",
+ status);
+
+ return CURLE_RECV_ERROR;
+ }
+
+ /* Base64 encode the response */
+ result = Curl_base64_encode(data, (char *) ntlm->output_token,
+ type_3_buf.cbBuffer, outptr, outlen);
+
+ Curl_sasl_ntlm_cleanup(ntlm);
+
+ return result;
+}
+
+/*
+ * Curl_sasl_ntlm_cleanup()
+ *
+ * This is used to clean up the ntlm specific data.
+ *
+ * Parameters:
+ *
+ * ntlm [in/out] - The ntlm data struct being cleaned up.
+ *
+ */
+void Curl_sasl_ntlm_cleanup(struct ntlmdata *ntlm)
+{
+ /* Free our security context */
+ if(ntlm->context) {
+ s_pSecFn->DeleteSecurityContext(ntlm->context);
+ free(ntlm->context);
+ ntlm->context = NULL;
+ }
+
+ /* Free our credentials handle */
+ if(ntlm->credentials) {
+ s_pSecFn->FreeCredentialsHandle(ntlm->credentials);
+ free(ntlm->credentials);
+ ntlm->credentials = NULL;
+ }
+
+ /* Free our identity */
+ Curl_sspi_free_identity(ntlm->p_identity);
+ ntlm->p_identity = NULL;
+
+ /* Free the input and output tokens */
+ Curl_safefree(ntlm->input_token);
+ Curl_safefree(ntlm->output_token);
+
+ /* Reset any variables */
+ ntlm->token_max = 0;
+}
+#endif /* USE_NTLM */
+
+#if defined(USE_KERBEROS5)
+/*
+ * Curl_sasl_create_gssapi_user_message()
+ *
+ * This is used to generate an already encoded GSSAPI (Kerberos V5) user token
+ * message ready for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data [in] - The session handle.
+ * userp [in] - The user name in the format User or Domain\User.
+ * passdwp [in] - The user's password.
+ * service [in] - The service type such as www, smtp, pop or imap.
+ * mutual_auth [in] - Flag specifing whether or not mutual authentication
+ * is enabled.
+ * chlg64 [in] - The optional base64 encoded challenge message.
+ * krb5 [in/out] - The gssapi data struct being used and modified.
+ * outptr [in/out] - The address where a pointer to newly allocated memory
+ * holding the result will be stored upon completion.
+ * outlen [out] - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_create_gssapi_user_message(struct SessionHandle *data,
+ const char *userp,
+ const char *passwdp,
+ const char *service,
+ const bool mutual_auth,
+ const char *chlg64,
+ struct kerberos5data *krb5,
+ char **outptr, size_t *outlen)
+{
+ CURLcode result = CURLE_OK;
+ size_t chlglen = 0;
+ unsigned char *chlg = NULL;
+ CtxtHandle context;
+ PSecPkgInfo SecurityPackage;
+ SecBuffer chlg_buf;
+ SecBuffer resp_buf;
+ SecBufferDesc chlg_desc;
+ SecBufferDesc resp_desc;
+ SECURITY_STATUS status;
+ unsigned long attrs;
+ TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */
+
+ if(!krb5->credentials) {
+ /* Query the security package for Kerberos */
+ status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *)
+ TEXT(SP_NAME_KERBEROS),
+ &SecurityPackage);
+ if(status != SEC_E_OK) {
+ return CURLE_NOT_BUILT_IN;
+ }
+
+ krb5->token_max = SecurityPackage->cbMaxToken;
+
+ /* Release the package buffer as it is not required anymore */
+ s_pSecFn->FreeContextBuffer(SecurityPackage);
+
+ /* Allocate our response buffer */
+ krb5->output_token = malloc(krb5->token_max);
+ if(!krb5->output_token)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Generate our SPN */
+ krb5->spn = Curl_sasl_build_spn(service, data->easy_conn->host.name);
+ if(!krb5->spn)
+ return CURLE_OUT_OF_MEMORY;
+
+ if(userp && *userp) {
+ /* Populate our identity structure */
+ result = Curl_create_sspi_identity(userp, passwdp, &krb5->identity);
+ if(result)
+ return result;
+
+ /* Allow proper cleanup of the identity structure */
+ krb5->p_identity = &krb5->identity;
+ }
+ else
+ /* Use the current Windows user */
+ krb5->p_identity = NULL;
+
+ /* Allocate our credentials handle */
+ krb5->credentials = malloc(sizeof(CredHandle));
+ if(!krb5->credentials)
+ return CURLE_OUT_OF_MEMORY;
+
+ memset(krb5->credentials, 0, sizeof(CredHandle));
+
+ /* Acquire our credentials handle */
+ status = s_pSecFn->AcquireCredentialsHandle(NULL,
+ (TCHAR *)
+ TEXT(SP_NAME_KERBEROS),
+ SECPKG_CRED_OUTBOUND, NULL,
+ krb5->p_identity, NULL, NULL,
+ krb5->credentials, &expiry);
+ if(status != SEC_E_OK)
+ return CURLE_LOGIN_DENIED;
+
+ /* Allocate our new context handle */
+ krb5->context = malloc(sizeof(CtxtHandle));
+ if(!krb5->context)
+ return CURLE_OUT_OF_MEMORY;
+
+ memset(krb5->context, 0, sizeof(CtxtHandle));
+ }
+ else {
+ /* Decode the base-64 encoded challenge message */
+ if(strlen(chlg64) && *chlg64 != '=') {
+ result = Curl_base64_decode(chlg64, &chlg, &chlglen);
+ if(result)
+ return result;
+ }
+
+ /* Ensure we have a valid challenge message */
+ if(!chlg) {
+ infof(data, "GSSAPI handshake failure (empty challenge message)\n");
+
+ return CURLE_BAD_CONTENT_ENCODING;
+ }
+
+ /* Setup the challenge "input" security buffer */
+ chlg_desc.ulVersion = SECBUFFER_VERSION;
+ chlg_desc.cBuffers = 1;
+ chlg_desc.pBuffers = &chlg_buf;
+ chlg_buf.BufferType = SECBUFFER_TOKEN;
+ chlg_buf.pvBuffer = chlg;
+ chlg_buf.cbBuffer = curlx_uztoul(chlglen);
+ }
+
+ /* Setup the response "output" security buffer */
+ resp_desc.ulVersion = SECBUFFER_VERSION;
+ resp_desc.cBuffers = 1;
+ resp_desc.pBuffers = &resp_buf;
+ resp_buf.BufferType = SECBUFFER_TOKEN;
+ resp_buf.pvBuffer = krb5->output_token;
+ resp_buf.cbBuffer = curlx_uztoul(krb5->token_max);
+
+ /* Generate our challenge-response message */
+ status = s_pSecFn->InitializeSecurityContext(krb5->credentials,
+ chlg ? krb5->context : NULL,
+ krb5->spn,
+ (mutual_auth ?
+ ISC_REQ_MUTUAL_AUTH : 0),
+ 0, SECURITY_NATIVE_DREP,
+ chlg ? &chlg_desc : NULL, 0,
+ &context,
+ &resp_desc, &attrs,
+ &expiry);
+
+ if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) {
+ free(chlg);
+
+ return CURLE_RECV_ERROR;
+ }
+
+ if(memcmp(&context, krb5->context, sizeof(context))) {
+ s_pSecFn->DeleteSecurityContext(krb5->context);
+
+ memcpy(krb5->context, &context, sizeof(context));
+ }
+
+ if(resp_buf.cbBuffer) {
+ /* Base64 encode the response */
+ result = Curl_base64_encode(data, (char *)resp_buf.pvBuffer,
+ resp_buf.cbBuffer, outptr, outlen);
+ }
+
+ /* Free the decoded challenge */
+ free(chlg);
+
+ return result;
+}
+
+/*
+ * Curl_sasl_create_gssapi_security_message()
+ *
+ * This is used to generate an already encoded GSSAPI (Kerberos V5) security
+ * token message ready for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data [in] - The session handle.
+ * chlg64 [in] - The optional base64 encoded challenge message.
+ * krb5 [in/out] - The gssapi data struct being used and modified.
+ * outptr [in/out] - The address where a pointer to newly allocated memory
+ * holding the result will be stored upon completion.
+ * outlen [out] - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_create_gssapi_security_message(struct SessionHandle *data,
+ const char *chlg64,
+ struct kerberos5data *krb5,
+ char **outptr,
+ size_t *outlen)
+{
+ CURLcode result = CURLE_OK;
+ size_t offset = 0;
+ size_t chlglen = 0;
+ size_t messagelen = 0;
+ size_t appdatalen = 0;
+ unsigned char *chlg = NULL;
+ unsigned char *trailer = NULL;
+ unsigned char *message = NULL;
+ unsigned char *padding = NULL;
+ unsigned char *appdata = NULL;
+ SecBuffer input_buf[2];
+ SecBuffer wrap_buf[3];
+ SecBufferDesc input_desc;
+ SecBufferDesc wrap_desc;
+ unsigned long indata = 0;
+ unsigned long outdata = 0;
+ unsigned long qop = 0;
+ unsigned long sec_layer = 0;
+ unsigned long max_size = 0;
+ SecPkgContext_Sizes sizes;
+ SecPkgCredentials_Names names;
+ SECURITY_STATUS status;
+ char *user_name;
+
+ /* Decode the base-64 encoded input message */
+ if(strlen(chlg64) && *chlg64 != '=') {
+ result = Curl_base64_decode(chlg64, &chlg, &chlglen);
+ if(result)
+ return result;
+ }
+
+ /* Ensure we have a valid challenge message */
+ if(!chlg) {
+ infof(data, "GSSAPI handshake failure (empty security message)\n");
+
+ return CURLE_BAD_CONTENT_ENCODING;
+ }
+
+ /* Get our response size information */
+ status = s_pSecFn->QueryContextAttributes(krb5->context,
+ SECPKG_ATTR_SIZES,
+ &sizes);
+ if(status != SEC_E_OK) {
+ free(chlg);
+
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ /* Get the fully qualified username back from the context */
+ status = s_pSecFn->QueryCredentialsAttributes(krb5->credentials,
+ SECPKG_CRED_ATTR_NAMES,
+ &names);
+ if(status != SEC_E_OK) {
+ free(chlg);
+
+ return CURLE_RECV_ERROR;
+ }
+
+ /* Setup the "input" security buffer */
+ input_desc.ulVersion = SECBUFFER_VERSION;
+ input_desc.cBuffers = 2;
+ input_desc.pBuffers = input_buf;
+ input_buf[0].BufferType = SECBUFFER_STREAM;
+ input_buf[0].pvBuffer = chlg;
+ input_buf[0].cbBuffer = curlx_uztoul(chlglen);
+ input_buf[1].BufferType = SECBUFFER_DATA;
+ input_buf[1].pvBuffer = NULL;
+ input_buf[1].cbBuffer = 0;
+
+ /* Decrypt the inbound challenge and obtain the qop */
+ status = s_pSecFn->DecryptMessage(krb5->context, &input_desc, 0, &qop);
+ if(status != SEC_E_OK) {
+ infof(data, "GSSAPI handshake failure (empty security message)\n");
+
+ free(chlg);
+
+ return CURLE_BAD_CONTENT_ENCODING;
+ }
+
+ /* Not 4 octets long so fail as per RFC4752 Section 3.1 */
+ if(input_buf[1].cbBuffer != 4) {
+ infof(data, "GSSAPI handshake failure (invalid security data)\n");
+
+ free(chlg);
+
+ return CURLE_BAD_CONTENT_ENCODING;
+ }
+
+ /* Copy the data out and free the challenge as it is not required anymore */
+ memcpy(&indata, input_buf[1].pvBuffer, 4);
+ s_pSecFn->FreeContextBuffer(input_buf[1].pvBuffer);
+ free(chlg);
+
+ /* Extract the security layer */
+ sec_layer = indata & 0x000000FF;
+ if(!(sec_layer & KERB_WRAP_NO_ENCRYPT)) {
+ infof(data, "GSSAPI handshake failure (invalid security layer)\n");
+
+ return CURLE_BAD_CONTENT_ENCODING;
+ }
+
+ /* Extract the maximum message size the server can receive */
+ max_size = ntohl(indata & 0xFFFFFF00);
+ if(max_size > 0) {
+ /* The server has told us it supports a maximum receive buffer, however, as
+ we don't require one unless we are encrypting data, we tell the server
+ our receive buffer is zero. */
+ max_size = 0;
+ }
+
+ /* Allocate the trailer */
+ trailer = malloc(sizes.cbSecurityTrailer);
+ if(!trailer)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Convert the user name to UTF8 when operating with Unicode */
+ user_name = Curl_convert_tchar_to_UTF8(names.sUserName);
+ if(!user_name) {
+ free(trailer);
+
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ /* Allocate our message */
+ messagelen = sizeof(outdata) + strlen(user_name) + 1;
+ message = malloc(messagelen);
+ if(!message) {
+ free(trailer);
+ Curl_unicodefree(user_name);
+
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ /* Populate the message with the security layer, client supported receive
+ message size and authorization identity including the 0x00 based
+ terminator. Note: Dispite RFC4752 Section 3.1 stating "The authorization
+ identity is not terminated with the zero-valued (%x00) octet." it seems
+ necessary to include it. */
+ outdata = htonl(max_size) | sec_layer;
+ memcpy(message, &outdata, sizeof(outdata));
+ strcpy((char *) message + sizeof(outdata), user_name);
+ Curl_unicodefree(user_name);
+
+ /* Allocate the padding */
+ padding = malloc(sizes.cbBlockSize);
+ if(!padding) {
+ free(message);
+ free(trailer);
+
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ /* Setup the "authentication data" security buffer */
+ wrap_desc.ulVersion = SECBUFFER_VERSION;
+ wrap_desc.cBuffers = 3;
+ wrap_desc.pBuffers = wrap_buf;
+ wrap_buf[0].BufferType = SECBUFFER_TOKEN;
+ wrap_buf[0].pvBuffer = trailer;
+ wrap_buf[0].cbBuffer = sizes.cbSecurityTrailer;
+ wrap_buf[1].BufferType = SECBUFFER_DATA;
+ wrap_buf[1].pvBuffer = message;
+ wrap_buf[1].cbBuffer = curlx_uztoul(messagelen);
+ wrap_buf[2].BufferType = SECBUFFER_PADDING;
+ wrap_buf[2].pvBuffer = padding;
+ wrap_buf[2].cbBuffer = sizes.cbBlockSize;
+
+ /* Encrypt the data */
+ status = s_pSecFn->EncryptMessage(krb5->context, KERB_WRAP_NO_ENCRYPT,
+ &wrap_desc, 0);
+ if(status != SEC_E_OK) {
+ free(padding);
+ free(message);
+ free(trailer);
+
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ /* Allocate the encryption (wrap) buffer */
+ appdatalen = wrap_buf[0].cbBuffer + wrap_buf[1].cbBuffer +
+ wrap_buf[2].cbBuffer;
+ appdata = malloc(appdatalen);
+ if(!appdata) {
+ free(padding);
+ free(message);
+ free(trailer);
+
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ /* Populate the encryption buffer */
+ memcpy(appdata, wrap_buf[0].pvBuffer, wrap_buf[0].cbBuffer);
+ offset += wrap_buf[0].cbBuffer;
+ memcpy(appdata + offset, wrap_buf[1].pvBuffer, wrap_buf[1].cbBuffer);
+ offset += wrap_buf[1].cbBuffer;
+ memcpy(appdata + offset, wrap_buf[2].pvBuffer, wrap_buf[2].cbBuffer);
+
+ /* Base64 encode the response */
+ result = Curl_base64_encode(data, (char *)appdata, appdatalen, outptr,
+ outlen);
+
+ /* Free all of our local buffers */
+ free(appdata);
+ free(padding);
+ free(message);
+ free(trailer);
+
+ return result;
+}
+
+/*
+ * Curl_sasl_gssapi_cleanup()
+ *
+ * This is used to clean up the gssapi specific data.
+ *
+ * Parameters:
+ *
+ * krb5 [in/out] - The kerberos 5 data struct being cleaned up.
+ *
+ */
+void Curl_sasl_gssapi_cleanup(struct kerberos5data *krb5)
+{
+ /* Free our security context */
+ if(krb5->context) {
+ s_pSecFn->DeleteSecurityContext(krb5->context);
+ free(krb5->context);
+ krb5->context = NULL;
+ }
+
+ /* Free our credentials handle */
+ if(krb5->credentials) {
+ s_pSecFn->FreeCredentialsHandle(krb5->credentials);
+ free(krb5->credentials);
+ krb5->credentials = NULL;
+ }
+
+ /* Free our identity */
+ Curl_sspi_free_identity(krb5->p_identity);
+ krb5->p_identity = NULL;
+
+ /* Free the SPN and output token */
+ Curl_safefree(krb5->spn);
+ Curl_safefree(krb5->output_token);
+
+ /* Reset any variables */
+ krb5->token_max = 0;
+}
+#endif /* USE_KERBEROS5 */
+
+#endif /* USE_WINDOWS_SSPI */
diff --git a/Utilities/cmcurl/lib/curl_sec.h b/Utilities/cmcurl/lib/curl_sec.h
new file mode 100644
index 000000000..6c48da243
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_sec.h
@@ -0,0 +1,51 @@
+#ifndef HEADER_CURL_SECURITY_H
+#define HEADER_CURL_SECURITY_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+struct Curl_sec_client_mech {
+ const char *name;
+ size_t size;
+ int (*init)(void *);
+ int (*auth)(void *, struct connectdata *);
+ void (*end)(void *);
+ int (*check_prot)(void *, int);
+ int (*overhead)(void *, int, int);
+ int (*encode)(void *, const void*, int, int, void**);
+ int (*decode)(void *, void*, int, int, struct connectdata *);
+};
+
+#define AUTH_OK 0
+#define AUTH_CONTINUE 1
+#define AUTH_ERROR 2
+
+#ifdef HAVE_GSSAPI
+int Curl_sec_read_msg (struct connectdata *conn, char *,
+ enum protection_level);
+void Curl_sec_end (struct connectdata *);
+CURLcode Curl_sec_login (struct connectdata *);
+int Curl_sec_request_prot (struct connectdata *conn, const char *level);
+
+extern struct Curl_sec_client_mech Curl_krb5_client_mech;
+#endif
+
+#endif /* HEADER_CURL_SECURITY_H */
diff --git a/Utilities/cmcurl/lib/curl_setup.h b/Utilities/cmcurl/lib/curl_setup.h
new file mode 100644
index 000000000..19c1bafd5
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_setup.h
@@ -0,0 +1,745 @@
+#ifndef HEADER_CURL_SETUP_H
+#define HEADER_CURL_SETUP_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Define WIN32 when build target is Win32 API
+ */
+
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) && \
+ !defined(__SYMBIAN32__)
+#define WIN32
+#endif
+
+/*
+ * Include configuration script results or hand-crafted
+ * configuration file for platforms which lack config tool.
+ */
+
+#ifdef HAVE_CONFIG_H
+
+#include "curl_config.h"
+
+#else /* HAVE_CONFIG_H */
+
+#ifdef _WIN32_WCE
+# include "config-win32ce.h"
+#else
+# ifdef WIN32
+# include "config-win32.h"
+# endif
+#endif
+
+#if defined(macintosh) && defined(__MRC__)
+# include "config-mac.h"
+#endif
+
+#ifdef __riscos__
+# include "config-riscos.h"
+#endif
+
+#ifdef __AMIGA__
+# include "config-amigaos.h"
+#endif
+
+#ifdef __SYMBIAN32__
+# include "config-symbian.h"
+#endif
+
+#ifdef __OS400__
+# include "config-os400.h"
+#endif
+
+#ifdef TPF
+# include "config-tpf.h"
+#endif
+
+#ifdef __VXWORKS__
+# include "config-vxworks.h"
+#endif
+
+#endif /* HAVE_CONFIG_H */
+
+#if defined(_MSC_VER)
+# pragma warning(push,1)
+#endif
+
+/* ================================================================ */
+/* Definition of preprocessor macros/symbols which modify compiler */
+/* behavior or generated code characteristics must be done here, */
+/* as appropriate, before any system header file is included. It is */
+/* also possible to have them defined in the config file included */
+/* before this point. As a result of all this we frown inclusion of */
+/* system header files in our config files, avoid this at any cost. */
+/* ================================================================ */
+
+/*
+ * AIX 4.3 and newer needs _THREAD_SAFE defined to build
+ * proper reentrant code. Others may also need it.
+ */
+
+#ifdef NEED_THREAD_SAFE
+# ifndef _THREAD_SAFE
+# define _THREAD_SAFE
+# endif
+#endif
+
+/*
+ * Tru64 needs _REENTRANT set for a few function prototypes and
+ * things to appear in the system header files. Unixware needs it
+ * to build proper reentrant code. Others may also need it.
+ */
+
+#ifdef NEED_REENTRANT
+# ifndef _REENTRANT
+# define _REENTRANT
+# endif
+#endif
+
+/* Solaris needs this to get a POSIX-conformant getpwuid_r */
+#if defined(sun) || defined(__sun)
+# ifndef _POSIX_PTHREAD_SEMANTICS
+# define _POSIX_PTHREAD_SEMANTICS 1
+# endif
+#endif
+
+/* ================================================================ */
+/* If you need to include a system header file for your platform, */
+/* please, do it beyond the point further indicated in this file. */
+/* ================================================================ */
+
+/*
+ * libcurl's external interface definitions are also used internally,
+ * and might also include required system header files to define them.
+ */
+
+#include <curl/curlbuild.h>
+
+/*
+ * Compile time sanity checks must also be done when building the library.
+ */
+
+#include <curl/curlrules.h>
+
+/*
+ * Ensure that no one is using the old SIZEOF_CURL_OFF_T macro
+ */
+
+#ifdef SIZEOF_CURL_OFF_T
+# error "SIZEOF_CURL_OFF_T shall not be defined!"
+ Error Compilation_aborted_SIZEOF_CURL_OFF_T_shall_not_be_defined
+#endif
+
+/*
+ * Disable other protocols when http is the only one desired.
+ */
+
+#ifdef HTTP_ONLY
+# ifndef CURL_DISABLE_TFTP
+# define CURL_DISABLE_TFTP
+# endif
+# ifndef CURL_DISABLE_FTP
+# define CURL_DISABLE_FTP
+# endif
+# ifndef CURL_DISABLE_LDAP
+# define CURL_DISABLE_LDAP
+# endif
+# ifndef CURL_DISABLE_TELNET
+# define CURL_DISABLE_TELNET
+# endif
+# ifndef CURL_DISABLE_DICT
+# define CURL_DISABLE_DICT
+# endif
+# ifndef CURL_DISABLE_FILE
+# define CURL_DISABLE_FILE
+# endif
+# ifndef CURL_DISABLE_RTSP
+# define CURL_DISABLE_RTSP
+# endif
+# ifndef CURL_DISABLE_POP3
+# define CURL_DISABLE_POP3
+# endif
+# ifndef CURL_DISABLE_IMAP
+# define CURL_DISABLE_IMAP
+# endif
+# ifndef CURL_DISABLE_SMTP
+# define CURL_DISABLE_SMTP
+# endif
+# ifndef CURL_DISABLE_RTSP
+# define CURL_DISABLE_RTSP
+# endif
+# ifndef CURL_DISABLE_RTMP
+# define CURL_DISABLE_RTMP
+# endif
+# ifndef CURL_DISABLE_GOPHER
+# define CURL_DISABLE_GOPHER
+# endif
+# ifndef CURL_DISABLE_SMB
+# define CURL_DISABLE_SMB
+# endif
+#endif
+
+/*
+ * When http is disabled rtsp is not supported.
+ */
+
+#if defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_RTSP)
+# define CURL_DISABLE_RTSP
+#endif
+
+/* ================================================================ */
+/* No system header file shall be included in this file before this */
+/* point. The only allowed ones are those included from curlbuild.h */
+/* ================================================================ */
+
+/*
+ * OS/400 setup file includes some system headers.
+ */
+
+#ifdef __OS400__
+# include "setup-os400.h"
+#endif
+
+/*
+ * VMS setup file includes some system headers.
+ */
+
+#ifdef __VMS
+# include "setup-vms.h"
+#endif
+
+/*
+ * Include header files for windows builds before redefining anything.
+ * Use this preprocessor block only to include or exclude windows.h,
+ * winsock2.h, ws2tcpip.h or winsock.h. Any other windows thing belongs
+ * to any other further and independent block. Under Cygwin things work
+ * just as under linux (e.g. <sys/socket.h>) and the winsock headers should
+ * never be included when __CYGWIN__ is defined. configure script takes
+ * care of this, not defining HAVE_WINDOWS_H, HAVE_WINSOCK_H, HAVE_WINSOCK2_H,
+ * neither HAVE_WS2TCPIP_H when __CYGWIN__ is defined.
+ */
+
+#ifdef HAVE_WINDOWS_H
+# if defined(UNICODE) && !defined(_UNICODE)
+# define _UNICODE
+# endif
+# if defined(_UNICODE) && !defined(UNICODE)
+# define UNICODE
+# endif
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include <windows.h>
+# ifdef HAVE_WINSOCK2_H
+# include <winsock2.h>
+# ifdef HAVE_WS2TCPIP_H
+# include <ws2tcpip.h>
+# endif
+# else
+# ifdef HAVE_WINSOCK_H
+# include <winsock.h>
+# endif
+# endif
+# include <tchar.h>
+# ifdef UNICODE
+ typedef wchar_t *(*curl_wcsdup_callback)(const wchar_t *str);
+# endif
+#endif
+
+/*
+ * Define USE_WINSOCK to 2 if we have and use WINSOCK2 API, else
+ * define USE_WINSOCK to 1 if we have and use WINSOCK API, else
+ * undefine USE_WINSOCK.
+ */
+
+#undef USE_WINSOCK
+
+#ifdef HAVE_WINSOCK2_H
+# define USE_WINSOCK 2
+#else
+# ifdef HAVE_WINSOCK_H
+# define USE_WINSOCK 1
+# endif
+#endif
+
+#ifdef USE_LWIPSOCK
+# include <lwip/init.h>
+# include <lwip/sockets.h>
+# include <lwip/netdb.h>
+#endif
+
+#ifdef HAVE_EXTRA_STRICMP_H
+# include <extra/stricmp.h>
+#endif
+
+#ifdef HAVE_EXTRA_STRDUP_H
+# include <extra/strdup.h>
+#endif
+
+#ifdef TPF
+# include <strings.h> /* for bzero, strcasecmp, and strncasecmp */
+# include <string.h> /* for strcpy and strlen */
+# include <stdlib.h> /* for rand and srand */
+# include <sys/socket.h> /* for select and ioctl*/
+# include <netdb.h> /* for in_addr_t definition */
+# include <tpf/sysapi.h> /* for tpf_process_signals */
+ /* change which select is used for libcurl */
+# define select(a,b,c,d,e) tpf_select_libcurl(a,b,c,d,e)
+#endif
+
+#ifdef __VXWORKS__
+# include <sockLib.h> /* for generic BSD socket functions */
+# include <ioLib.h> /* for basic I/O interface functions */
+#endif
+
+#ifdef __AMIGA__
+# ifndef __ixemul__
+# include <exec/types.h>
+# include <exec/execbase.h>
+# include <proto/exec.h>
+# include <proto/dos.h>
+# define select(a,b,c,d,e) WaitSelect(a,b,c,d,e,0)
+# endif
+#endif
+
+#include <stdio.h>
+#ifdef HAVE_ASSERT_H
+#include <assert.h>
+#endif
+
+#ifdef __TANDEM /* for nsr-tandem-nsk systems */
+#include <floss.h>
+#endif
+
+#ifndef STDC_HEADERS /* no standard C headers! */
+#include <curl/stdcheaders.h>
+#endif
+
+#ifdef __POCC__
+# include <sys/types.h>
+# include <unistd.h>
+# define sys_nerr EILSEQ
+#endif
+
+/*
+ * Salford-C kludge section (mostly borrowed from wxWidgets).
+ */
+#ifdef __SALFORDC__
+ #pragma suppress 353 /* Possible nested comments */
+ #pragma suppress 593 /* Define not used */
+ #pragma suppress 61 /* enum has no name */
+ #pragma suppress 106 /* unnamed, unused parameter */
+ #include <clib.h>
+#endif
+
+/* Default Windows file API selection. */
+#ifdef _WIN32
+# if defined(_MSC_VER) && (_INTEGRAL_MAX_BITS >= 64)
+# define USE_WIN32_LARGE_FILES
+# elif defined(__MINGW32__)
+# define USE_WIN32_LARGE_FILES
+# else
+# define USE_WIN32_SMALL_FILES
+# endif
+#endif
+
+/*
+ * Large file (>2Gb) support using WIN32 functions.
+ */
+
+#ifdef USE_WIN32_LARGE_FILES
+# include <io.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# undef lseek
+# define lseek(fdes,offset,whence) _lseeki64(fdes, offset, whence)
+# undef fstat
+# define fstat(fdes,stp) _fstati64(fdes, stp)
+# undef stat
+# define stat(fname,stp) _stati64(fname, stp)
+# define struct_stat struct _stati64
+# define LSEEK_ERROR (__int64)-1
+#endif
+
+/*
+ * Small file (<2Gb) support using WIN32 functions.
+ */
+
+#ifdef USE_WIN32_SMALL_FILES
+# include <io.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# ifndef _WIN32_WCE
+# undef lseek
+# define lseek(fdes,offset,whence) _lseek(fdes, (long)offset, whence)
+# define fstat(fdes,stp) _fstat(fdes, stp)
+# define stat(fname,stp) _stat(fname, stp)
+# define struct_stat struct _stat
+# endif
+# define LSEEK_ERROR (long)-1
+#endif
+
+#ifndef struct_stat
+# define struct_stat struct stat
+#endif
+
+#ifndef LSEEK_ERROR
+# define LSEEK_ERROR (off_t)-1
+#endif
+
+/*
+ * Default sizeof(off_t) in case it hasn't been defined in config file.
+ */
+
+#ifndef SIZEOF_OFF_T
+# if defined(__VMS) && !defined(__VAX)
+# if defined(_LARGEFILE)
+# define SIZEOF_OFF_T 8
+# endif
+# elif defined(__OS400__) && defined(__ILEC400__)
+# if defined(_LARGE_FILES)
+# define SIZEOF_OFF_T 8
+# endif
+# elif defined(__MVS__) && defined(__IBMC__)
+# if defined(_LP64) || defined(_LARGE_FILES)
+# define SIZEOF_OFF_T 8
+# endif
+# elif defined(__370__) && defined(__IBMC__)
+# if defined(_LP64) || defined(_LARGE_FILES)
+# define SIZEOF_OFF_T 8
+# endif
+# endif
+# ifndef SIZEOF_OFF_T
+# define SIZEOF_OFF_T 4
+# endif
+#endif
+
+/*
+ * Arg 2 type for gethostname in case it hasn't been defined in config file.
+ */
+
+#ifndef GETHOSTNAME_TYPE_ARG2
+# ifdef USE_WINSOCK
+# define GETHOSTNAME_TYPE_ARG2 int
+# else
+# define GETHOSTNAME_TYPE_ARG2 size_t
+# endif
+#endif
+
+/* Below we define some functions. They should
+
+ 4. set the SIGALRM signal timeout
+ 5. set dir/file naming defines
+ */
+
+#ifdef WIN32
+
+# define DIR_CHAR "\\"
+# define DOT_CHAR "_"
+
+#else /* WIN32 */
+
+# ifdef MSDOS /* Watt-32 */
+
+# include <sys/ioctl.h>
+# define select(n,r,w,x,t) select_s(n,r,w,x,t)
+# define ioctl(x,y,z) ioctlsocket(x,y,(char *)(z))
+# include <tcp.h>
+# ifdef word
+# undef word
+# endif
+# ifdef byte
+# undef byte
+# endif
+
+# endif /* MSDOS */
+
+# ifdef __minix
+ /* Minix 3 versions up to at least 3.1.3 are missing these prototypes */
+ extern char * strtok_r(char *s, const char *delim, char **last);
+ extern struct tm * gmtime_r(const time_t * const timep, struct tm *tmp);
+# endif
+
+# define DIR_CHAR "/"
+# ifndef DOT_CHAR
+# define DOT_CHAR "."
+# endif
+
+# ifdef MSDOS
+# undef DOT_CHAR
+# define DOT_CHAR "_"
+# endif
+
+# ifndef fileno /* sunos 4 have this as a macro! */
+ int fileno( FILE *stream);
+# endif
+
+#endif /* WIN32 */
+
+/*
+ * msvc 6.0 requires PSDK in order to have INET6_ADDRSTRLEN
+ * defined in ws2tcpip.h as well as to provide IPv6 support.
+ */
+
+#if defined(_MSC_VER) && !defined(__POCC__)
+# if !defined(HAVE_WS2TCPIP_H) || \
+ ((_MSC_VER < 1300) && !defined(INET6_ADDRSTRLEN))
+# undef HAVE_GETADDRINFO_THREADSAFE
+# undef HAVE_FREEADDRINFO
+# undef HAVE_GETADDRINFO
+# undef HAVE_GETNAMEINFO
+# undef ENABLE_IPV6
+# endif
+#endif
+
+/* ---------------------------------------------------------------- */
+/* resolver specialty compile-time defines */
+/* CURLRES_* defines to use in the host*.c sources */
+/* ---------------------------------------------------------------- */
+
+/*
+ * lcc-win32 doesn't have _beginthreadex(), lacks threads support.
+ */
+
+#if defined(__LCC__) && defined(WIN32)
+# undef USE_THREADS_POSIX
+# undef USE_THREADS_WIN32
+#endif
+
+/*
+ * MSVC threads support requires a multi-threaded runtime library.
+ * _beginthreadex() is not available in single-threaded ones.
+ */
+
+#if defined(_MSC_VER) && !defined(__POCC__) && !defined(_MT)
+# undef USE_THREADS_POSIX
+# undef USE_THREADS_WIN32
+#endif
+
+/*
+ * Mutually exclusive CURLRES_* definitions.
+ */
+
+#ifdef USE_ARES
+# define CURLRES_ASYNCH
+# define CURLRES_ARES
+/* now undef the stock libc functions just to avoid them being used */
+# undef HAVE_GETADDRINFO
+# undef HAVE_GETHOSTBYNAME
+#elif defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
+# define CURLRES_ASYNCH
+# define CURLRES_THREADED
+#else
+# define CURLRES_SYNCH
+#endif
+
+#ifdef ENABLE_IPV6
+# define CURLRES_IPV6
+#else
+# define CURLRES_IPV4
+#endif
+
+/* ---------------------------------------------------------------- */
+
+/*
+ * When using WINSOCK, TELNET protocol requires WINSOCK2 API.
+ */
+
+#if defined(USE_WINSOCK) && (USE_WINSOCK != 2)
+# define CURL_DISABLE_TELNET 1
+#endif
+
+/*
+ * msvc 6.0 does not have struct sockaddr_storage and
+ * does not define IPPROTO_ESP in winsock2.h. But both
+ * are available if PSDK is properly installed.
+ */
+
+#if defined(_MSC_VER) && !defined(__POCC__)
+# if !defined(HAVE_WINSOCK2_H) || ((_MSC_VER < 1300) && !defined(IPPROTO_ESP))
+# undef HAVE_STRUCT_SOCKADDR_STORAGE
+# endif
+#endif
+
+/*
+ * Intentionally fail to build when using msvc 6.0 without PSDK installed.
+ * The brave of heart can circumvent this, defining ALLOW_MSVC6_WITHOUT_PSDK
+ * in lib/config-win32.h although absolutely discouraged and unsupported.
+ */
+
+#if defined(_MSC_VER) && !defined(__POCC__)
+# if !defined(HAVE_WINDOWS_H) || ((_MSC_VER < 1300) && !defined(_FILETIME_))
+# if !defined(ALLOW_MSVC6_WITHOUT_PSDK)
+# error MSVC 6.0 requires "February 2003 Platform SDK" a.k.a. \
+ "Windows Server 2003 PSDK"
+# else
+# define CURL_DISABLE_LDAP 1
+# endif
+# endif
+#endif
+
+#ifdef NETWARE
+int netware_init(void);
+#ifndef __NOVELL_LIBC__
+#include <sys/bsdskt.h>
+#include <sys/timeval.h>
+#endif
+#endif
+
+#if defined(HAVE_LIBIDN) && defined(HAVE_TLD_H)
+/* The lib was present and the tld.h header (which is missing in libidn 0.3.X
+ but we only work with libidn 0.4.1 or later) */
+#define USE_LIBIDN
+#endif
+
+#ifndef SIZEOF_TIME_T
+/* assume default size of time_t to be 32 bit */
+#define SIZEOF_TIME_T 4
+#endif
+
+#define LIBIDN_REQUIRED_VERSION "0.4.1"
+
+#if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_NSS) || \
+ defined(USE_POLARSSL) || defined(USE_AXTLS) || \
+ defined(USE_CYASSL) || defined(USE_SCHANNEL) || \
+ defined(USE_DARWINSSL) || defined(USE_GSKIT)
+#define USE_SSL /* SSL support has been enabled */
+#endif
+
+/* Single point where USE_SPNEGO definition might be defined */
+#if !defined(CURL_DISABLE_CRYPTO_AUTH) && \
+ (defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI))
+#define USE_SPNEGO
+#endif
+
+/* Single point where USE_KERBEROS5 definition might be defined */
+#if !defined(CURL_DISABLE_CRYPTO_AUTH) && \
+ (defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI))
+#define USE_KERBEROS5
+#endif
+
+/* Single point where USE_NTLM definition might be defined */
+#if !defined(CURL_DISABLE_NTLM) && !defined(CURL_DISABLE_CRYPTO_AUTH)
+#if defined(USE_OPENSSL) || defined(USE_WINDOWS_SSPI) || \
+ defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_DARWINSSL) || \
+ defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
+
+#ifdef HAVE_BORINGSSL /* BoringSSL is not NTLM capable */
+#undef USE_NTLM
+#else
+#define USE_NTLM
+#endif
+#endif
+#endif
+
+/* non-configure builds may define CURL_WANTS_CA_BUNDLE_ENV */
+#if defined(CURL_WANTS_CA_BUNDLE_ENV) && !defined(CURL_CA_BUNDLE)
+#define CURL_CA_BUNDLE getenv("CURL_CA_BUNDLE")
+#endif
+
+/*
+ * Provide a mechanism to silence picky compilers, such as gcc 4.6+.
+ * Parameters should of course normally not be unused, but for example when
+ * we have multiple implementations of the same interface it may happen.
+ */
+
+#if defined(__GNUC__) && ((__GNUC__ >= 3) || \
+ ((__GNUC__ == 2) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 7)))
+# define UNUSED_PARAM __attribute__((__unused__))
+# define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#else
+# define UNUSED_PARAM /*NOTHING*/
+# define WARN_UNUSED_RESULT
+#endif
+
+/*
+ * Include macros and defines that should only be processed once.
+ */
+
+#ifndef HEADER_CURL_SETUP_ONCE_H
+#include "curl_setup_once.h"
+#endif
+
+/*
+ * Definition of our NOP statement Object-like macro
+ */
+
+#ifndef Curl_nop_stmt
+# define Curl_nop_stmt do { } WHILE_FALSE
+#endif
+
+/*
+ * Ensure that Winsock and lwIP TCP/IP stacks are not mixed.
+ */
+
+#if defined(__LWIP_OPT_H__)
+# if defined(SOCKET) || \
+ defined(USE_WINSOCK) || \
+ defined(HAVE_WINSOCK_H) || \
+ defined(HAVE_WINSOCK2_H) || \
+ defined(HAVE_WS2TCPIP_H)
+# error "Winsock and lwIP TCP/IP stack definitions shall not coexist!"
+# endif
+#endif
+
+/*
+ * Portable symbolic names for Winsock shutdown() mode flags.
+ */
+
+#ifdef USE_WINSOCK
+# define SHUT_RD 0x00
+# define SHUT_WR 0x01
+# define SHUT_RDWR 0x02
+#endif
+
+/* Define S_ISREG if not defined by system headers, f.e. MSVC */
+#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG)
+#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#endif
+
+/* Define S_ISDIR if not defined by system headers, f.e. MSVC */
+#if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+
+/* In Windows the default file mode is text but an application can override it.
+Therefore we specify it explicitly. https://github.com/bagder/curl/pull/258
+*/
+#if defined(WIN32) || defined(MSDOS)
+#define FOPEN_READTEXT "rt"
+#define FOPEN_WRITETEXT "wt"
+#elif defined(__CYGWIN__)
+/* Cygwin has specific behavior we need to address when WIN32 is not defined.
+https://cygwin.com/cygwin-ug-net/using-textbinary.html
+For write we want our output to have line endings of LF and be compatible with
+other Cygwin utilities. For read we want to handle input that may have line
+endings either CRLF or LF so 't' is appropriate.
+*/
+#define FOPEN_READTEXT "rt"
+#define FOPEN_WRITETEXT "w"
+#else
+#define FOPEN_READTEXT "r"
+#define FOPEN_WRITETEXT "w"
+#endif
+
+#endif /* HEADER_CURL_SETUP_H */
diff --git a/Utilities/cmcurl/lib/curl_setup_once.h b/Utilities/cmcurl/lib/curl_setup_once.h
new file mode 100644
index 000000000..69d6d4790
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_setup_once.h
@@ -0,0 +1,551 @@
+#ifndef HEADER_CURL_SETUP_ONCE_H
+#define HEADER_CURL_SETUP_ONCE_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+
+/*
+ * Inclusion of common header files.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <ctype.h>
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef NEED_MALLOC_H
+#include <malloc.h>
+#endif
+
+#ifdef NEED_MEMORY_H
+#include <memory.h>
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#ifdef TIME_WITH_SYS_TIME
+#include <time.h>
+#endif
+#else
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+#endif
+
+#ifdef WIN32
+#include <io.h>
+#include <fcntl.h>
+#endif
+
+#if defined(HAVE_STDBOOL_H) && defined(HAVE_BOOL_T)
+#include <stdbool.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef __hpux
+# if !defined(_XOPEN_SOURCE_EXTENDED) || defined(_KERNEL)
+# ifdef _APP32_64BIT_OFF_T
+# define OLD_APP32_64BIT_OFF_T _APP32_64BIT_OFF_T
+# undef _APP32_64BIT_OFF_T
+# else
+# undef OLD_APP32_64BIT_OFF_T
+# endif
+# endif
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#ifdef __hpux
+# if !defined(_XOPEN_SOURCE_EXTENDED) || defined(_KERNEL)
+# ifdef OLD_APP32_64BIT_OFF_T
+# define _APP32_64BIT_OFF_T OLD_APP32_64BIT_OFF_T
+# undef OLD_APP32_64BIT_OFF_T
+# endif
+# endif
+#endif
+
+
+/*
+ * Definition of timeval struct for platforms that don't have it.
+ */
+
+#ifndef HAVE_STRUCT_TIMEVAL
+struct timeval {
+ long tv_sec;
+ long tv_usec;
+};
+#endif
+
+
+/*
+ * If we have the MSG_NOSIGNAL define, make sure we use
+ * it as the fourth argument of function send()
+ */
+
+#ifdef HAVE_MSG_NOSIGNAL
+#define SEND_4TH_ARG MSG_NOSIGNAL
+#else
+#define SEND_4TH_ARG 0
+#endif
+
+
+#if defined(__minix)
+/* Minix doesn't support recv on TCP sockets */
+#define sread(x,y,z) (ssize_t)read((RECV_TYPE_ARG1)(x), \
+ (RECV_TYPE_ARG2)(y), \
+ (RECV_TYPE_ARG3)(z))
+
+#elif defined(HAVE_RECV)
+/*
+ * The definitions for the return type and arguments types
+ * of functions recv() and send() belong and come from the
+ * configuration file. Do not define them in any other place.
+ *
+ * HAVE_RECV is defined if you have a function named recv()
+ * which is used to read incoming data from sockets. If your
+ * function has another name then don't define HAVE_RECV.
+ *
+ * If HAVE_RECV is defined then RECV_TYPE_ARG1, RECV_TYPE_ARG2,
+ * RECV_TYPE_ARG3, RECV_TYPE_ARG4 and RECV_TYPE_RETV must also
+ * be defined.
+ *
+ * HAVE_SEND is defined if you have a function named send()
+ * which is used to write outgoing data on a connected socket.
+ * If yours has another name then don't define HAVE_SEND.
+ *
+ * If HAVE_SEND is defined then SEND_TYPE_ARG1, SEND_QUAL_ARG2,
+ * SEND_TYPE_ARG2, SEND_TYPE_ARG3, SEND_TYPE_ARG4 and
+ * SEND_TYPE_RETV must also be defined.
+ */
+
+#if !defined(RECV_TYPE_ARG1) || \
+ !defined(RECV_TYPE_ARG2) || \
+ !defined(RECV_TYPE_ARG3) || \
+ !defined(RECV_TYPE_ARG4) || \
+ !defined(RECV_TYPE_RETV)
+ /* */
+ Error Missing_definition_of_return_and_arguments_types_of_recv
+ /* */
+#else
+#define sread(x,y,z) (ssize_t)recv((RECV_TYPE_ARG1)(x), \
+ (RECV_TYPE_ARG2)(y), \
+ (RECV_TYPE_ARG3)(z), \
+ (RECV_TYPE_ARG4)(0))
+#endif
+#else /* HAVE_RECV */
+#ifndef sread
+ /* */
+ Error Missing_definition_of_macro_sread
+ /* */
+#endif
+#endif /* HAVE_RECV */
+
+
+#if defined(__minix)
+/* Minix doesn't support send on TCP sockets */
+#define swrite(x,y,z) (ssize_t)write((SEND_TYPE_ARG1)(x), \
+ (SEND_TYPE_ARG2)(y), \
+ (SEND_TYPE_ARG3)(z))
+
+#elif defined(HAVE_SEND)
+#if !defined(SEND_TYPE_ARG1) || \
+ !defined(SEND_QUAL_ARG2) || \
+ !defined(SEND_TYPE_ARG2) || \
+ !defined(SEND_TYPE_ARG3) || \
+ !defined(SEND_TYPE_ARG4) || \
+ !defined(SEND_TYPE_RETV)
+ /* */
+ Error Missing_definition_of_return_and_arguments_types_of_send
+ /* */
+#else
+#define swrite(x,y,z) (ssize_t)send((SEND_TYPE_ARG1)(x), \
+ (SEND_TYPE_ARG2)(y), \
+ (SEND_TYPE_ARG3)(z), \
+ (SEND_TYPE_ARG4)(SEND_4TH_ARG))
+#endif
+#else /* HAVE_SEND */
+#ifndef swrite
+ /* */
+ Error Missing_definition_of_macro_swrite
+ /* */
+#endif
+#endif /* HAVE_SEND */
+
+
+#if 0
+#if defined(HAVE_RECVFROM)
+/*
+ * Currently recvfrom is only used on udp sockets.
+ */
+#if !defined(RECVFROM_TYPE_ARG1) || \
+ !defined(RECVFROM_TYPE_ARG2) || \
+ !defined(RECVFROM_TYPE_ARG3) || \
+ !defined(RECVFROM_TYPE_ARG4) || \
+ !defined(RECVFROM_TYPE_ARG5) || \
+ !defined(RECVFROM_TYPE_ARG6) || \
+ !defined(RECVFROM_TYPE_RETV)
+ /* */
+ Error Missing_definition_of_return_and_arguments_types_of_recvfrom
+ /* */
+#else
+#define sreadfrom(s,b,bl,f,fl) (ssize_t)recvfrom((RECVFROM_TYPE_ARG1) (s), \
+ (RECVFROM_TYPE_ARG2 *)(b), \
+ (RECVFROM_TYPE_ARG3) (bl), \
+ (RECVFROM_TYPE_ARG4) (0), \
+ (RECVFROM_TYPE_ARG5 *)(f), \
+ (RECVFROM_TYPE_ARG6 *)(fl))
+#endif
+#else /* HAVE_RECVFROM */
+#ifndef sreadfrom
+ /* */
+ Error Missing_definition_of_macro_sreadfrom
+ /* */
+#endif
+#endif /* HAVE_RECVFROM */
+
+
+#ifdef RECVFROM_TYPE_ARG6_IS_VOID
+# define RECVFROM_ARG6_T int
+#else
+# define RECVFROM_ARG6_T RECVFROM_TYPE_ARG6
+#endif
+#endif /* if 0 */
+
+
+/*
+ * Function-like macro definition used to close a socket.
+ */
+
+#if defined(HAVE_CLOSESOCKET)
+# define sclose(x) closesocket((x))
+#elif defined(HAVE_CLOSESOCKET_CAMEL)
+# define sclose(x) CloseSocket((x))
+#elif defined(HAVE_CLOSE_S)
+# define sclose(x) close_s((x))
+#elif defined(USE_LWIPSOCK)
+# define sclose(x) lwip_close((x))
+#else
+# define sclose(x) close((x))
+#endif
+
+/*
+ * Stack-independent version of fcntl() on sockets:
+ */
+#if defined(USE_LWIPSOCK)
+# define sfcntl lwip_fcntl
+#else
+# define sfcntl fcntl
+#endif
+
+/*
+ * Uppercase macro versions of ANSI/ISO is*() functions/macros which
+ * avoid negative number inputs with argument byte codes > 127.
+ */
+
+#define ISSPACE(x) (isspace((int) ((unsigned char)x)))
+#define ISDIGIT(x) (isdigit((int) ((unsigned char)x)))
+#define ISALNUM(x) (isalnum((int) ((unsigned char)x)))
+#define ISXDIGIT(x) (isxdigit((int) ((unsigned char)x)))
+#define ISGRAPH(x) (isgraph((int) ((unsigned char)x)))
+#define ISALPHA(x) (isalpha((int) ((unsigned char)x)))
+#define ISPRINT(x) (isprint((int) ((unsigned char)x)))
+#define ISUPPER(x) (isupper((int) ((unsigned char)x)))
+#define ISLOWER(x) (islower((int) ((unsigned char)x)))
+#define ISASCII(x) (isascii((int) ((unsigned char)x)))
+
+#define ISBLANK(x) (int)((((unsigned char)x) == ' ') || \
+ (((unsigned char)x) == '\t'))
+
+#define TOLOWER(x) (tolower((int) ((unsigned char)x)))
+
+
+/*
+ * 'bool' stuff compatible with HP-UX headers.
+ */
+
+#if defined(__hpux) && !defined(HAVE_BOOL_T)
+ typedef int bool;
+# define false 0
+# define true 1
+# define HAVE_BOOL_T
+#endif
+
+
+/*
+ * 'bool' exists on platforms with <stdbool.h>, i.e. C99 platforms.
+ * On non-C99 platforms there's no bool, so define an enum for that.
+ * On C99 platforms 'false' and 'true' also exist. Enum uses a
+ * global namespace though, so use bool_false and bool_true.
+ */
+
+#ifndef HAVE_BOOL_T
+ typedef enum {
+ bool_false = 0,
+ bool_true = 1
+ } bool;
+
+/*
+ * Use a define to let 'true' and 'false' use those enums. There
+ * are currently no use of true and false in libcurl proper, but
+ * there are some in the examples. This will cater for any later
+ * code happening to use true and false.
+ */
+# define false bool_false
+# define true bool_true
+# define HAVE_BOOL_T
+#endif
+
+
+/*
+ * Redefine TRUE and FALSE too, to catch current use. With this
+ * change, 'bool found = 1' will give a warning on MIPSPro, but
+ * 'bool found = TRUE' will not. Change tested on IRIX/MIPSPro,
+ * AIX 5.1/Xlc, Tru64 5.1/cc, w/make test too.
+ */
+
+#ifndef TRUE
+#define TRUE true
+#endif
+#ifndef FALSE
+#define FALSE false
+#endif
+
+
+/*
+ * Macro WHILE_FALSE may be used to build single-iteration do-while loops,
+ * avoiding compiler warnings. Mostly intended for other macro definitions.
+ */
+
+#define WHILE_FALSE while(0)
+
+#if defined(_MSC_VER) && !defined(__POCC__)
+# undef WHILE_FALSE
+# if (_MSC_VER < 1500)
+# define WHILE_FALSE while(1, 0)
+# else
+# define WHILE_FALSE \
+__pragma(warning(push)) \
+__pragma(warning(disable:4127)) \
+while(0) \
+__pragma(warning(pop))
+# endif
+#endif
+
+
+/*
+ * Typedef to 'int' if sig_atomic_t is not an available 'typedefed' type.
+ */
+
+#ifndef HAVE_SIG_ATOMIC_T
+typedef int sig_atomic_t;
+#define HAVE_SIG_ATOMIC_T
+#endif
+
+
+/*
+ * Convenience SIG_ATOMIC_T definition
+ */
+
+#ifdef HAVE_SIG_ATOMIC_T_VOLATILE
+#define SIG_ATOMIC_T static sig_atomic_t
+#else
+#define SIG_ATOMIC_T static volatile sig_atomic_t
+#endif
+
+
+/*
+ * Default return type for signal handlers.
+ */
+
+#ifndef RETSIGTYPE
+#define RETSIGTYPE void
+#endif
+
+
+/*
+ * Macro used to include code only in debug builds.
+ */
+
+#ifdef DEBUGBUILD
+#define DEBUGF(x) x
+#else
+#define DEBUGF(x) do { } WHILE_FALSE
+#endif
+
+
+/*
+ * Macro used to include assertion code only in debug builds.
+ */
+
+#if defined(DEBUGBUILD) && defined(HAVE_ASSERT_H)
+#define DEBUGASSERT(x) assert(x)
+#else
+#define DEBUGASSERT(x) do { } WHILE_FALSE
+#endif
+
+
+/*
+ * Macro SOCKERRNO / SET_SOCKERRNO() returns / sets the *socket-related* errno
+ * (or equivalent) on this platform to hide platform details to code using it.
+ */
+
+#ifdef USE_WINSOCK
+#define SOCKERRNO ((int)WSAGetLastError())
+#define SET_SOCKERRNO(x) (WSASetLastError((int)(x)))
+#else
+#define SOCKERRNO (errno)
+#define SET_SOCKERRNO(x) (errno = (x))
+#endif
+
+
+/*
+ * Macro ERRNO / SET_ERRNO() returns / sets the NOT *socket-related* errno
+ * (or equivalent) on this platform to hide platform details to code using it.
+ */
+
+#if defined(WIN32) && !defined(USE_LWIPSOCK)
+#define ERRNO ((int)GetLastError())
+#define SET_ERRNO(x) (SetLastError((DWORD)(x)))
+#else
+#define ERRNO (errno)
+#define SET_ERRNO(x) (errno = (x))
+#endif
+
+
+/*
+ * Portable error number symbolic names defined to Winsock error codes.
+ */
+
+#ifdef USE_WINSOCK
+#undef EBADF /* override definition in errno.h */
+#define EBADF WSAEBADF
+#undef EINTR /* override definition in errno.h */
+#define EINTR WSAEINTR
+#undef EINVAL /* override definition in errno.h */
+#define EINVAL WSAEINVAL
+#undef EWOULDBLOCK /* override definition in errno.h */
+#define EWOULDBLOCK WSAEWOULDBLOCK
+#undef EINPROGRESS /* override definition in errno.h */
+#define EINPROGRESS WSAEINPROGRESS
+#undef EALREADY /* override definition in errno.h */
+#define EALREADY WSAEALREADY
+#undef ENOTSOCK /* override definition in errno.h */
+#define ENOTSOCK WSAENOTSOCK
+#undef EDESTADDRREQ /* override definition in errno.h */
+#define EDESTADDRREQ WSAEDESTADDRREQ
+#undef EMSGSIZE /* override definition in errno.h */
+#define EMSGSIZE WSAEMSGSIZE
+#undef EPROTOTYPE /* override definition in errno.h */
+#define EPROTOTYPE WSAEPROTOTYPE
+#undef ENOPROTOOPT /* override definition in errno.h */
+#define ENOPROTOOPT WSAENOPROTOOPT
+#undef EPROTONOSUPPORT /* override definition in errno.h */
+#define EPROTONOSUPPORT WSAEPROTONOSUPPORT
+#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
+#undef EOPNOTSUPP /* override definition in errno.h */
+#define EOPNOTSUPP WSAEOPNOTSUPP
+#define EPFNOSUPPORT WSAEPFNOSUPPORT
+#undef EAFNOSUPPORT /* override definition in errno.h */
+#define EAFNOSUPPORT WSAEAFNOSUPPORT
+#undef EADDRINUSE /* override definition in errno.h */
+#define EADDRINUSE WSAEADDRINUSE
+#undef EADDRNOTAVAIL /* override definition in errno.h */
+#define EADDRNOTAVAIL WSAEADDRNOTAVAIL
+#undef ENETDOWN /* override definition in errno.h */
+#define ENETDOWN WSAENETDOWN
+#undef ENETUNREACH /* override definition in errno.h */
+#define ENETUNREACH WSAENETUNREACH
+#undef ENETRESET /* override definition in errno.h */
+#define ENETRESET WSAENETRESET
+#undef ECONNABORTED /* override definition in errno.h */
+#define ECONNABORTED WSAECONNABORTED
+#undef ECONNRESET /* override definition in errno.h */
+#define ECONNRESET WSAECONNRESET
+#undef ENOBUFS /* override definition in errno.h */
+#define ENOBUFS WSAENOBUFS
+#undef EISCONN /* override definition in errno.h */
+#define EISCONN WSAEISCONN
+#undef ENOTCONN /* override definition in errno.h */
+#define ENOTCONN WSAENOTCONN
+#define ESHUTDOWN WSAESHUTDOWN
+#define ETOOMANYREFS WSAETOOMANYREFS
+#undef ETIMEDOUT /* override definition in errno.h */
+#define ETIMEDOUT WSAETIMEDOUT
+#undef ECONNREFUSED /* override definition in errno.h */
+#define ECONNREFUSED WSAECONNREFUSED
+#undef ELOOP /* override definition in errno.h */
+#define ELOOP WSAELOOP
+#ifndef ENAMETOOLONG /* possible previous definition in errno.h */
+#define ENAMETOOLONG WSAENAMETOOLONG
+#endif
+#define EHOSTDOWN WSAEHOSTDOWN
+#undef EHOSTUNREACH /* override definition in errno.h */
+#define EHOSTUNREACH WSAEHOSTUNREACH
+#ifndef ENOTEMPTY /* possible previous definition in errno.h */
+#define ENOTEMPTY WSAENOTEMPTY
+#endif
+#define EPROCLIM WSAEPROCLIM
+#define EUSERS WSAEUSERS
+#define EDQUOT WSAEDQUOT
+#define ESTALE WSAESTALE
+#define EREMOTE WSAEREMOTE
+#endif
+
+/*
+ * Macro argv_item_t hides platform details to code using it.
+ */
+
+#ifdef __VMS
+#define argv_item_t __char_ptr32
+#else
+#define argv_item_t char *
+#endif
+
+
+/*
+ * We use this ZERO_NULL to avoid picky compiler warnings,
+ * when assigning a NULL pointer to a function pointer var.
+ */
+
+#define ZERO_NULL 0
+
+
+#endif /* HEADER_CURL_SETUP_ONCE_H */
+
diff --git a/Utilities/cmcurl/lib/curl_sspi.c b/Utilities/cmcurl/lib/curl_sspi.c
new file mode 100644
index 000000000..070424dd1
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_sspi.c
@@ -0,0 +1,257 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_WINDOWS_SSPI
+
+#include <curl/curl.h>
+#include "curl_sspi.h"
+#include "curl_multibyte.h"
+#include "warnless.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* We use our own typedef here since some headers might lack these */
+typedef PSecurityFunctionTable (APIENTRY *INITSECURITYINTERFACE_FN)(VOID);
+
+/* See definition of SECURITY_ENTRYPOINT in sspi.h */
+#ifdef UNICODE
+# ifdef _WIN32_WCE
+# define SECURITYENTRYPOINT L"InitSecurityInterfaceW"
+# else
+# define SECURITYENTRYPOINT "InitSecurityInterfaceW"
+# endif
+#else
+# define SECURITYENTRYPOINT "InitSecurityInterfaceA"
+#endif
+
+/* Handle of security.dll or secur32.dll, depending on Windows version */
+HMODULE s_hSecDll = NULL;
+
+/* Pointer to SSPI dispatch table */
+PSecurityFunctionTable s_pSecFn = NULL;
+
+/*
+ * Curl_sspi_global_init()
+ *
+ * This is used to load the Security Service Provider Interface (SSPI)
+ * dynamic link library portably across all Windows versions, without
+ * the need to directly link libcurl, nor the application using it, at
+ * build time.
+ *
+ * Once this function has been executed, Windows SSPI functions can be
+ * called through the Security Service Provider Interface dispatch table.
+ */
+CURLcode Curl_sspi_global_init(void)
+{
+ bool securityDll = FALSE;
+ INITSECURITYINTERFACE_FN pInitSecurityInterface;
+
+ /* If security interface is not yet initialized try to do this */
+ if(!s_hSecDll) {
+ /* Security Service Provider Interface (SSPI) functions are located in
+ * security.dll on WinNT 4.0 and in secur32.dll on Win9x. Win2K and XP
+ * have both these DLLs (security.dll forwards calls to secur32.dll) */
+ DWORD majorVersion = 4;
+ DWORD platformId = VER_PLATFORM_WIN32_NT;
+
+#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_WIN2K) || \
+ (_WIN32_WINNT < _WIN32_WINNT_WIN2K)
+ OSVERSIONINFO osver;
+
+ memset(&osver, 0, sizeof(osver));
+ osver.dwOSVersionInfoSize = sizeof(osver);
+
+ /* Find out Windows version */
+ if(!GetVersionEx(&osver))
+ return CURLE_FAILED_INIT;
+
+ /* Verify the major version number == 4 and platform id == WIN_NT */
+ if(osver.dwMajorVersion == majorVersion &&
+ osver.dwPlatformId == platformId)
+ securityDll = TRUE;
+#else
+ ULONGLONG cm;
+ OSVERSIONINFOEX osver;
+
+ memset(&osver, 0, sizeof(osver));
+ osver.dwOSVersionInfoSize = sizeof(osver);
+ osver.dwMajorVersion = majorVersion;
+ osver.dwPlatformId = platformId;
+
+ cm = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
+ cm = VerSetConditionMask(cm, VER_MINORVERSION, VER_GREATER_EQUAL);
+ cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
+ cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL);
+ cm = VerSetConditionMask(cm, VER_PLATFORMID, VER_EQUAL);
+
+ /* Verify the major version number == 4 and platform id == WIN_NT */
+ if(VerifyVersionInfo(&osver, (VER_MAJORVERSION | VER_MINORVERSION |
+ VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR |
+ VER_PLATFORMID),
+ cm))
+ securityDll = TRUE;
+#endif
+
+ /* Load SSPI dll into the address space of the calling process */
+ if(securityDll)
+ s_hSecDll = LoadLibrary(TEXT("security.dll"));
+ else
+ s_hSecDll = LoadLibrary(TEXT("secur32.dll"));
+ if(!s_hSecDll)
+ return CURLE_FAILED_INIT;
+
+ /* Get address of the InitSecurityInterfaceA function from the SSPI dll */
+ pInitSecurityInterface = (INITSECURITYINTERFACE_FN)
+ GetProcAddress(s_hSecDll, SECURITYENTRYPOINT);
+ if(!pInitSecurityInterface)
+ return CURLE_FAILED_INIT;
+
+ /* Get pointer to Security Service Provider Interface dispatch table */
+ s_pSecFn = pInitSecurityInterface();
+ if(!s_pSecFn)
+ return CURLE_FAILED_INIT;
+ }
+
+ return CURLE_OK;
+}
+
+/*
+ * Curl_sspi_global_cleanup()
+ *
+ * This deinitializes the Security Service Provider Interface from libcurl.
+ */
+
+void Curl_sspi_global_cleanup(void)
+{
+ if(s_hSecDll) {
+ FreeLibrary(s_hSecDll);
+ s_hSecDll = NULL;
+ s_pSecFn = NULL;
+ }
+}
+
+/*
+ * Curl_create_sspi_identity()
+ *
+ * This is used to populate a SSPI identity structure based on the supplied
+ * username and password.
+ *
+ * Parameters:
+ *
+ * userp [in] - The user name in the format User or Domain\User.
+ * passdwp [in] - The user's password.
+ * identity [in/out] - The identity structure.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
+ SEC_WINNT_AUTH_IDENTITY *identity)
+{
+ xcharp_u useranddomain;
+ xcharp_u user, dup_user;
+ xcharp_u domain, dup_domain;
+ xcharp_u passwd, dup_passwd;
+ size_t domlen = 0;
+
+ domain.const_tchar_ptr = TEXT("");
+
+ /* Initialize the identity */
+ memset(identity, 0, sizeof(*identity));
+
+ useranddomain.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)userp);
+ if(!useranddomain.tchar_ptr)
+ return CURLE_OUT_OF_MEMORY;
+
+ user.const_tchar_ptr = _tcschr(useranddomain.const_tchar_ptr, TEXT('\\'));
+ if(!user.const_tchar_ptr)
+ user.const_tchar_ptr = _tcschr(useranddomain.const_tchar_ptr, TEXT('/'));
+
+ if(user.tchar_ptr) {
+ domain.tchar_ptr = useranddomain.tchar_ptr;
+ domlen = user.tchar_ptr - useranddomain.tchar_ptr;
+ user.tchar_ptr++;
+ }
+ else {
+ user.tchar_ptr = useranddomain.tchar_ptr;
+ domain.const_tchar_ptr = TEXT("");
+ domlen = 0;
+ }
+
+ /* Setup the identity's user and length */
+ dup_user.tchar_ptr = _tcsdup(user.tchar_ptr);
+ if(!dup_user.tchar_ptr) {
+ Curl_unicodefree(useranddomain.tchar_ptr);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ identity->User = dup_user.tbyte_ptr;
+ identity->UserLength = curlx_uztoul(_tcslen(dup_user.tchar_ptr));
+ dup_user.tchar_ptr = NULL;
+
+ /* Setup the identity's domain and length */
+ dup_domain.tchar_ptr = malloc(sizeof(TCHAR) * (domlen + 1));
+ if(!dup_domain.tchar_ptr) {
+ Curl_unicodefree(useranddomain.tchar_ptr);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ _tcsncpy(dup_domain.tchar_ptr, domain.tchar_ptr, domlen);
+ *(dup_domain.tchar_ptr + domlen) = TEXT('\0');
+ identity->Domain = dup_domain.tbyte_ptr;
+ identity->DomainLength = curlx_uztoul(domlen);
+ dup_domain.tchar_ptr = NULL;
+
+ Curl_unicodefree(useranddomain.tchar_ptr);
+
+ /* Setup the identity's password and length */
+ passwd.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)passwdp);
+ if(!passwd.tchar_ptr)
+ return CURLE_OUT_OF_MEMORY;
+ dup_passwd.tchar_ptr = _tcsdup(passwd.tchar_ptr);
+ if(!dup_passwd.tchar_ptr) {
+ Curl_unicodefree(passwd.tchar_ptr);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ identity->Password = dup_passwd.tbyte_ptr;
+ identity->PasswordLength = curlx_uztoul(_tcslen(dup_passwd.tchar_ptr));
+ dup_passwd.tchar_ptr = NULL;
+
+ Curl_unicodefree(passwd.tchar_ptr);
+
+ /* Setup the identity's flags */
+ identity->Flags = SECFLAG_WINNT_AUTH_IDENTITY;
+
+ return CURLE_OK;
+}
+
+void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY *identity)
+{
+ if(identity) {
+ Curl_safefree(identity->User);
+ Curl_safefree(identity->Password);
+ Curl_safefree(identity->Domain);
+ }
+}
+
+#endif /* USE_WINDOWS_SSPI */
diff --git a/Utilities/cmcurl/lib/curl_sspi.h b/Utilities/cmcurl/lib/curl_sspi.h
new file mode 100644
index 000000000..8655715e2
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_sspi.h
@@ -0,0 +1,346 @@
+#ifndef HEADER_CURL_SSPI_H
+#define HEADER_CURL_SSPI_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_WINDOWS_SSPI
+
+#include <curl/curl.h>
+
+/*
+ * When including the following three headers, it is mandatory to define either
+ * SECURITY_WIN32 or SECURITY_KERNEL, indicating who is compiling the code.
+ */
+
+#undef SECURITY_WIN32
+#undef SECURITY_KERNEL
+#define SECURITY_WIN32 1
+#include <security.h>
+#include <sspi.h>
+#include <rpc.h>
+
+CURLcode Curl_sspi_global_init(void);
+void Curl_sspi_global_cleanup(void);
+
+/* This is used to populate the domain in a SSPI identity structure */
+CURLcode Curl_override_sspi_http_realm(const char *chlg,
+ SEC_WINNT_AUTH_IDENTITY *identity);
+
+/* This is used to generate an SSPI identity structure */
+CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
+ SEC_WINNT_AUTH_IDENTITY *identity);
+
+/* This is used to free an SSPI identity structure */
+void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY *identity);
+
+/* Forward-declaration of global variables defined in curl_sspi.c */
+extern HMODULE s_hSecDll;
+extern PSecurityFunctionTable s_pSecFn;
+
+/* Provide some definitions missing in old headers */
+#define SP_NAME_DIGEST "WDigest"
+#define SP_NAME_NTLM "NTLM"
+#define SP_NAME_NEGOTIATE "Negotiate"
+#define SP_NAME_KERBEROS "Kerberos"
+
+#ifndef ISC_REQ_USE_HTTP_STYLE
+#define ISC_REQ_USE_HTTP_STYLE 0x01000000
+#endif
+
+#ifndef ISC_RET_REPLAY_DETECT
+#define ISC_RET_REPLAY_DETECT 0x00000004
+#endif
+
+#ifndef ISC_RET_SEQUENCE_DETECT
+#define ISC_RET_SEQUENCE_DETECT 0x00000008
+#endif
+
+#ifndef ISC_RET_CONFIDENTIALITY
+#define ISC_RET_CONFIDENTIALITY 0x00000010
+#endif
+
+#ifndef ISC_RET_ALLOCATED_MEMORY
+#define ISC_RET_ALLOCATED_MEMORY 0x00000100
+#endif
+
+#ifndef ISC_RET_STREAM
+#define ISC_RET_STREAM 0x00008000
+#endif
+
+#ifndef SEC_E_INSUFFICIENT_MEMORY
+# define SEC_E_INSUFFICIENT_MEMORY ((HRESULT)0x80090300L)
+#endif
+#ifndef SEC_E_INVALID_HANDLE
+# define SEC_E_INVALID_HANDLE ((HRESULT)0x80090301L)
+#endif
+#ifndef SEC_E_UNSUPPORTED_FUNCTION
+# define SEC_E_UNSUPPORTED_FUNCTION ((HRESULT)0x80090302L)
+#endif
+#ifndef SEC_E_TARGET_UNKNOWN
+# define SEC_E_TARGET_UNKNOWN ((HRESULT)0x80090303L)
+#endif
+#ifndef SEC_E_INTERNAL_ERROR
+# define SEC_E_INTERNAL_ERROR ((HRESULT)0x80090304L)
+#endif
+#ifndef SEC_E_SECPKG_NOT_FOUND
+# define SEC_E_SECPKG_NOT_FOUND ((HRESULT)0x80090305L)
+#endif
+#ifndef SEC_E_NOT_OWNER
+# define SEC_E_NOT_OWNER ((HRESULT)0x80090306L)
+#endif
+#ifndef SEC_E_CANNOT_INSTALL
+# define SEC_E_CANNOT_INSTALL ((HRESULT)0x80090307L)
+#endif
+#ifndef SEC_E_INVALID_TOKEN
+# define SEC_E_INVALID_TOKEN ((HRESULT)0x80090308L)
+#endif
+#ifndef SEC_E_CANNOT_PACK
+# define SEC_E_CANNOT_PACK ((HRESULT)0x80090309L)
+#endif
+#ifndef SEC_E_QOP_NOT_SUPPORTED
+# define SEC_E_QOP_NOT_SUPPORTED ((HRESULT)0x8009030AL)
+#endif
+#ifndef SEC_E_NO_IMPERSONATION
+# define SEC_E_NO_IMPERSONATION ((HRESULT)0x8009030BL)
+#endif
+#ifndef SEC_E_LOGON_DENIED
+# define SEC_E_LOGON_DENIED ((HRESULT)0x8009030CL)
+#endif
+#ifndef SEC_E_UNKNOWN_CREDENTIALS
+# define SEC_E_UNKNOWN_CREDENTIALS ((HRESULT)0x8009030DL)
+#endif
+#ifndef SEC_E_NO_CREDENTIALS
+# define SEC_E_NO_CREDENTIALS ((HRESULT)0x8009030EL)
+#endif
+#ifndef SEC_E_MESSAGE_ALTERED
+# define SEC_E_MESSAGE_ALTERED ((HRESULT)0x8009030FL)
+#endif
+#ifndef SEC_E_OUT_OF_SEQUENCE
+# define SEC_E_OUT_OF_SEQUENCE ((HRESULT)0x80090310L)
+#endif
+#ifndef SEC_E_NO_AUTHENTICATING_AUTHORITY
+# define SEC_E_NO_AUTHENTICATING_AUTHORITY ((HRESULT)0x80090311L)
+#endif
+#ifndef SEC_E_BAD_PKGID
+# define SEC_E_BAD_PKGID ((HRESULT)0x80090316L)
+#endif
+#ifndef SEC_E_CONTEXT_EXPIRED
+# define SEC_E_CONTEXT_EXPIRED ((HRESULT)0x80090317L)
+#endif
+#ifndef SEC_E_INCOMPLETE_MESSAGE
+# define SEC_E_INCOMPLETE_MESSAGE ((HRESULT)0x80090318L)
+#endif
+#ifndef SEC_E_INCOMPLETE_CREDENTIALS
+# define SEC_E_INCOMPLETE_CREDENTIALS ((HRESULT)0x80090320L)
+#endif
+#ifndef SEC_E_BUFFER_TOO_SMALL
+# define SEC_E_BUFFER_TOO_SMALL ((HRESULT)0x80090321L)
+#endif
+#ifndef SEC_E_WRONG_PRINCIPAL
+# define SEC_E_WRONG_PRINCIPAL ((HRESULT)0x80090322L)
+#endif
+#ifndef SEC_E_TIME_SKEW
+# define SEC_E_TIME_SKEW ((HRESULT)0x80090324L)
+#endif
+#ifndef SEC_E_UNTRUSTED_ROOT
+# define SEC_E_UNTRUSTED_ROOT ((HRESULT)0x80090325L)
+#endif
+#ifndef SEC_E_ILLEGAL_MESSAGE
+# define SEC_E_ILLEGAL_MESSAGE ((HRESULT)0x80090326L)
+#endif
+#ifndef SEC_E_CERT_UNKNOWN
+# define SEC_E_CERT_UNKNOWN ((HRESULT)0x80090327L)
+#endif
+#ifndef SEC_E_CERT_EXPIRED
+# define SEC_E_CERT_EXPIRED ((HRESULT)0x80090328L)
+#endif
+#ifndef SEC_E_ENCRYPT_FAILURE
+# define SEC_E_ENCRYPT_FAILURE ((HRESULT)0x80090329L)
+#endif
+#ifndef SEC_E_DECRYPT_FAILURE
+# define SEC_E_DECRYPT_FAILURE ((HRESULT)0x80090330L)
+#endif
+#ifndef SEC_E_ALGORITHM_MISMATCH
+# define SEC_E_ALGORITHM_MISMATCH ((HRESULT)0x80090331L)
+#endif
+#ifndef SEC_E_SECURITY_QOS_FAILED
+# define SEC_E_SECURITY_QOS_FAILED ((HRESULT)0x80090332L)
+#endif
+#ifndef SEC_E_UNFINISHED_CONTEXT_DELETED
+# define SEC_E_UNFINISHED_CONTEXT_DELETED ((HRESULT)0x80090333L)
+#endif
+#ifndef SEC_E_NO_TGT_REPLY
+# define SEC_E_NO_TGT_REPLY ((HRESULT)0x80090334L)
+#endif
+#ifndef SEC_E_NO_IP_ADDRESSES
+# define SEC_E_NO_IP_ADDRESSES ((HRESULT)0x80090335L)
+#endif
+#ifndef SEC_E_WRONG_CREDENTIAL_HANDLE
+# define SEC_E_WRONG_CREDENTIAL_HANDLE ((HRESULT)0x80090336L)
+#endif
+#ifndef SEC_E_CRYPTO_SYSTEM_INVALID
+# define SEC_E_CRYPTO_SYSTEM_INVALID ((HRESULT)0x80090337L)
+#endif
+#ifndef SEC_E_MAX_REFERRALS_EXCEEDED
+# define SEC_E_MAX_REFERRALS_EXCEEDED ((HRESULT)0x80090338L)
+#endif
+#ifndef SEC_E_MUST_BE_KDC
+# define SEC_E_MUST_BE_KDC ((HRESULT)0x80090339L)
+#endif
+#ifndef SEC_E_STRONG_CRYPTO_NOT_SUPPORTED
+# define SEC_E_STRONG_CRYPTO_NOT_SUPPORTED ((HRESULT)0x8009033AL)
+#endif
+#ifndef SEC_E_TOO_MANY_PRINCIPALS
+# define SEC_E_TOO_MANY_PRINCIPALS ((HRESULT)0x8009033BL)
+#endif
+#ifndef SEC_E_NO_PA_DATA
+# define SEC_E_NO_PA_DATA ((HRESULT)0x8009033CL)
+#endif
+#ifndef SEC_E_PKINIT_NAME_MISMATCH
+# define SEC_E_PKINIT_NAME_MISMATCH ((HRESULT)0x8009033DL)
+#endif
+#ifndef SEC_E_SMARTCARD_LOGON_REQUIRED
+# define SEC_E_SMARTCARD_LOGON_REQUIRED ((HRESULT)0x8009033EL)
+#endif
+#ifndef SEC_E_SHUTDOWN_IN_PROGRESS
+# define SEC_E_SHUTDOWN_IN_PROGRESS ((HRESULT)0x8009033FL)
+#endif
+#ifndef SEC_E_KDC_INVALID_REQUEST
+# define SEC_E_KDC_INVALID_REQUEST ((HRESULT)0x80090340L)
+#endif
+#ifndef SEC_E_KDC_UNABLE_TO_REFER
+# define SEC_E_KDC_UNABLE_TO_REFER ((HRESULT)0x80090341L)
+#endif
+#ifndef SEC_E_KDC_UNKNOWN_ETYPE
+# define SEC_E_KDC_UNKNOWN_ETYPE ((HRESULT)0x80090342L)
+#endif
+#ifndef SEC_E_UNSUPPORTED_PREAUTH
+# define SEC_E_UNSUPPORTED_PREAUTH ((HRESULT)0x80090343L)
+#endif
+#ifndef SEC_E_DELEGATION_REQUIRED
+# define SEC_E_DELEGATION_REQUIRED ((HRESULT)0x80090345L)
+#endif
+#ifndef SEC_E_BAD_BINDINGS
+# define SEC_E_BAD_BINDINGS ((HRESULT)0x80090346L)
+#endif
+#ifndef SEC_E_MULTIPLE_ACCOUNTS
+# define SEC_E_MULTIPLE_ACCOUNTS ((HRESULT)0x80090347L)
+#endif
+#ifndef SEC_E_NO_KERB_KEY
+# define SEC_E_NO_KERB_KEY ((HRESULT)0x80090348L)
+#endif
+#ifndef SEC_E_CERT_WRONG_USAGE
+# define SEC_E_CERT_WRONG_USAGE ((HRESULT)0x80090349L)
+#endif
+#ifndef SEC_E_DOWNGRADE_DETECTED
+# define SEC_E_DOWNGRADE_DETECTED ((HRESULT)0x80090350L)
+#endif
+#ifndef SEC_E_SMARTCARD_CERT_REVOKED
+# define SEC_E_SMARTCARD_CERT_REVOKED ((HRESULT)0x80090351L)
+#endif
+#ifndef SEC_E_ISSUING_CA_UNTRUSTED
+# define SEC_E_ISSUING_CA_UNTRUSTED ((HRESULT)0x80090352L)
+#endif
+#ifndef SEC_E_REVOCATION_OFFLINE_C
+# define SEC_E_REVOCATION_OFFLINE_C ((HRESULT)0x80090353L)
+#endif
+#ifndef SEC_E_PKINIT_CLIENT_FAILURE
+# define SEC_E_PKINIT_CLIENT_FAILURE ((HRESULT)0x80090354L)
+#endif
+#ifndef SEC_E_SMARTCARD_CERT_EXPIRED
+# define SEC_E_SMARTCARD_CERT_EXPIRED ((HRESULT)0x80090355L)
+#endif
+#ifndef SEC_E_NO_S4U_PROT_SUPPORT
+# define SEC_E_NO_S4U_PROT_SUPPORT ((HRESULT)0x80090356L)
+#endif
+#ifndef SEC_E_CROSSREALM_DELEGATION_FAILURE
+# define SEC_E_CROSSREALM_DELEGATION_FAILURE ((HRESULT)0x80090357L)
+#endif
+#ifndef SEC_E_REVOCATION_OFFLINE_KDC
+# define SEC_E_REVOCATION_OFFLINE_KDC ((HRESULT)0x80090358L)
+#endif
+#ifndef SEC_E_ISSUING_CA_UNTRUSTED_KDC
+# define SEC_E_ISSUING_CA_UNTRUSTED_KDC ((HRESULT)0x80090359L)
+#endif
+#ifndef SEC_E_KDC_CERT_EXPIRED
+# define SEC_E_KDC_CERT_EXPIRED ((HRESULT)0x8009035AL)
+#endif
+#ifndef SEC_E_KDC_CERT_REVOKED
+# define SEC_E_KDC_CERT_REVOKED ((HRESULT)0x8009035BL)
+#endif
+#ifndef SEC_E_INVALID_PARAMETER
+# define SEC_E_INVALID_PARAMETER ((HRESULT)0x8009035DL)
+#endif
+#ifndef SEC_E_DELEGATION_POLICY
+# define SEC_E_DELEGATION_POLICY ((HRESULT)0x8009035EL)
+#endif
+#ifndef SEC_E_POLICY_NLTM_ONLY
+# define SEC_E_POLICY_NLTM_ONLY ((HRESULT)0x8009035FL)
+#endif
+
+#ifndef SEC_I_CONTINUE_NEEDED
+# define SEC_I_CONTINUE_NEEDED ((HRESULT)0x00090312L)
+#endif
+#ifndef SEC_I_COMPLETE_NEEDED
+# define SEC_I_COMPLETE_NEEDED ((HRESULT)0x00090313L)
+#endif
+#ifndef SEC_I_COMPLETE_AND_CONTINUE
+# define SEC_I_COMPLETE_AND_CONTINUE ((HRESULT)0x00090314L)
+#endif
+#ifndef SEC_I_LOCAL_LOGON
+# define SEC_I_LOCAL_LOGON ((HRESULT)0x00090315L)
+#endif
+#ifndef SEC_I_CONTEXT_EXPIRED
+# define SEC_I_CONTEXT_EXPIRED ((HRESULT)0x00090317L)
+#endif
+#ifndef SEC_I_INCOMPLETE_CREDENTIALS
+# define SEC_I_INCOMPLETE_CREDENTIALS ((HRESULT)0x00090320L)
+#endif
+#ifndef SEC_I_RENEGOTIATE
+# define SEC_I_RENEGOTIATE ((HRESULT)0x00090321L)
+#endif
+#ifndef SEC_I_NO_LSA_CONTEXT
+# define SEC_I_NO_LSA_CONTEXT ((HRESULT)0x00090323L)
+#endif
+#ifndef SEC_I_SIGNATURE_NEEDED
+# define SEC_I_SIGNATURE_NEEDED ((HRESULT)0x0009035CL)
+#endif
+
+#ifdef UNICODE
+# define SECFLAG_WINNT_AUTH_IDENTITY \
+ (unsigned long)SEC_WINNT_AUTH_IDENTITY_UNICODE
+#else
+# define SECFLAG_WINNT_AUTH_IDENTITY \
+ (unsigned long)SEC_WINNT_AUTH_IDENTITY_ANSI
+#endif
+
+/*
+ * Definitions required from ntsecapi.h are directly provided below this point
+ * to avoid including ntsecapi.h due to a conflict with OpenSSL's safestack.h
+ */
+#define KERB_WRAP_NO_ENCRYPT 0x80000001
+
+#endif /* USE_WINDOWS_SSPI */
+
+#endif /* HEADER_CURL_SSPI_H */
diff --git a/Utilities/cmcurl/lib/curl_threads.c b/Utilities/cmcurl/lib/curl_threads.c
new file mode 100644
index 000000000..f9b812ea0
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_threads.c
@@ -0,0 +1,136 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_THREADS_POSIX)
+# ifdef HAVE_PTHREAD_H
+# include <pthread.h>
+# endif
+#elif defined(USE_THREADS_WIN32)
+# ifdef HAVE_PROCESS_H
+# include <process.h>
+# endif
+#endif
+
+#include "curl_threads.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#if defined(USE_THREADS_POSIX)
+
+struct curl_actual_call {
+ unsigned int (*func)(void *);
+ void *arg;
+};
+
+static void *curl_thread_create_thunk(void *arg)
+{
+ struct curl_actual_call * ac = arg;
+ unsigned int (*func)(void *) = ac->func;
+ void *real_arg = ac->arg;
+
+ free(ac);
+
+ (*func)(real_arg);
+
+ return 0;
+}
+
+curl_thread_t Curl_thread_create(unsigned int (*func) (void*), void *arg)
+{
+ curl_thread_t t = malloc(sizeof(pthread_t));
+ struct curl_actual_call *ac = malloc(sizeof(struct curl_actual_call));
+ if(!(ac && t))
+ goto err;
+
+ ac->func = func;
+ ac->arg = arg;
+
+ if(pthread_create(t, NULL, curl_thread_create_thunk, ac) != 0)
+ goto err;
+
+ return t;
+
+err:
+ free(t);
+ free(ac);
+ return curl_thread_t_null;
+}
+
+void Curl_thread_destroy(curl_thread_t hnd)
+{
+ if(hnd != curl_thread_t_null) {
+ pthread_detach(*hnd);
+ free(hnd);
+ }
+}
+
+int Curl_thread_join(curl_thread_t *hnd)
+{
+ int ret = (pthread_join(**hnd, NULL) == 0);
+
+ free(*hnd);
+ *hnd = curl_thread_t_null;
+
+ return ret;
+}
+
+#elif defined(USE_THREADS_WIN32)
+
+curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void*),
+ void *arg)
+{
+#ifdef _WIN32_WCE
+ return CreateThread(NULL, 0, func, arg, 0, NULL);
+#else
+ curl_thread_t t;
+ t = (curl_thread_t)_beginthreadex(NULL, 0, func, arg, 0, NULL);
+ if((t == 0) || (t == (curl_thread_t)-1L))
+ return curl_thread_t_null;
+ return t;
+#endif
+}
+
+void Curl_thread_destroy(curl_thread_t hnd)
+{
+ CloseHandle(hnd);
+}
+
+int Curl_thread_join(curl_thread_t *hnd)
+{
+#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_VISTA) || \
+ (_WIN32_WINNT < _WIN32_WINNT_VISTA)
+ int ret = (WaitForSingleObject(*hnd, INFINITE) == WAIT_OBJECT_0);
+#else
+ int ret = (WaitForSingleObjectEx(*hnd, INFINITE, FALSE) == WAIT_OBJECT_0);
+#endif
+
+ Curl_thread_destroy(*hnd);
+
+ *hnd = curl_thread_t_null;
+
+ return ret;
+}
+
+#endif /* USE_THREADS_* */
diff --git a/Utilities/cmcurl/lib/curl_threads.h b/Utilities/cmcurl/lib/curl_threads.h
new file mode 100644
index 000000000..0f3191abd
--- /dev/null
+++ b/Utilities/cmcurl/lib/curl_threads.h
@@ -0,0 +1,62 @@
+#ifndef HEADER_CURL_THREADS_H
+#define HEADER_CURL_THREADS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#if defined(USE_THREADS_POSIX)
+# define CURL_STDCALL
+# define curl_mutex_t pthread_mutex_t
+# define curl_thread_t pthread_t *
+# define curl_thread_t_null (pthread_t *)0
+# define Curl_mutex_init(m) pthread_mutex_init(m, NULL)
+# define Curl_mutex_acquire(m) pthread_mutex_lock(m)
+# define Curl_mutex_release(m) pthread_mutex_unlock(m)
+# define Curl_mutex_destroy(m) pthread_mutex_destroy(m)
+#elif defined(USE_THREADS_WIN32)
+# define CURL_STDCALL __stdcall
+# define curl_mutex_t CRITICAL_SECTION
+# define curl_thread_t HANDLE
+# define curl_thread_t_null (HANDLE)0
+# if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_VISTA) || \
+ (_WIN32_WINNT < _WIN32_WINNT_VISTA)
+# define Curl_mutex_init(m) InitializeCriticalSection(m)
+# else
+# define Curl_mutex_init(m) InitializeCriticalSectionEx(m, 0, 1)
+# endif
+# define Curl_mutex_acquire(m) EnterCriticalSection(m)
+# define Curl_mutex_release(m) LeaveCriticalSection(m)
+# define Curl_mutex_destroy(m) DeleteCriticalSection(m)
+#endif
+
+#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
+
+curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void*),
+ void *arg);
+
+void Curl_thread_destroy(curl_thread_t hnd);
+
+int Curl_thread_join(curl_thread_t *hnd);
+
+#endif /* USE_THREADS_POSIX || USE_THREADS_WIN32 */
+
+#endif /* HEADER_CURL_THREADS_H */
diff --git a/Utilities/cmcurl/lib/curlx.h b/Utilities/cmcurl/lib/curlx.h
new file mode 100644
index 000000000..979e7d7a1
--- /dev/null
+++ b/Utilities/cmcurl/lib/curlx.h
@@ -0,0 +1,118 @@
+#ifndef HEADER_CURL_CURLX_H
+#define HEADER_CURL_CURLX_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Defines protos and includes all header files that provide the curlx_*
+ * functions. The curlx_* functions are not part of the libcurl API, but are
+ * stand-alone functions whose sources can be built and linked by apps if need
+ * be.
+ */
+
+#include <curl/mprintf.h>
+/* this is still a public header file that provides the curl_mprintf()
+ functions while they still are offered publicly. They will be made library-
+ private one day */
+
+#include "strequal.h"
+/* "strequal.h" provides the strequal protos */
+
+#include "strtoofft.h"
+/* "strtoofft.h" provides this function: curlx_strtoofft(), returns a
+ curl_off_t number from a given string.
+*/
+
+#include "timeval.h"
+/*
+ "timeval.h" sets up a 'struct timeval' even for platforms that otherwise
+ don't have one and has protos for these functions:
+
+ curlx_tvnow()
+ curlx_tvdiff()
+ curlx_tvdiff_secs()
+*/
+
+#include "nonblock.h"
+/* "nonblock.h" provides curlx_nonblock() */
+
+#include "warnless.h"
+/* "warnless.h" provides functions:
+
+ curlx_ultous()
+ curlx_ultouc()
+ curlx_uztosi()
+*/
+
+/* Now setup curlx_ * names for the functions that are to become curlx_ and
+ be removed from a future libcurl official API:
+ curlx_getenv
+ curlx_mprintf (and its variations)
+ curlx_strequal
+ curlx_strnequal
+
+*/
+
+#define curlx_getenv curl_getenv
+#define curlx_strequal curl_strequal
+#define curlx_strnequal curl_strnequal
+#define curlx_raw_equal Curl_raw_equal
+#define curlx_mvsnprintf curl_mvsnprintf
+#define curlx_msnprintf curl_msnprintf
+#define curlx_maprintf curl_maprintf
+#define curlx_mvaprintf curl_mvaprintf
+#define curlx_msprintf curl_msprintf
+#define curlx_mprintf curl_mprintf
+#define curlx_mfprintf curl_mfprintf
+#define curlx_mvsprintf curl_mvsprintf
+#define curlx_mvprintf curl_mvprintf
+#define curlx_mvfprintf curl_mvfprintf
+
+#ifdef ENABLE_CURLX_PRINTF
+/* If this define is set, we define all "standard" printf() functions to use
+ the curlx_* version instead. It makes the source code transparent and
+ easier to understand/patch. Undefine them first. */
+# undef printf
+# undef fprintf
+# undef sprintf
+# undef snprintf
+# undef vprintf
+# undef vfprintf
+# undef vsprintf
+# undef vsnprintf
+# undef aprintf
+# undef vaprintf
+
+# define printf curlx_mprintf
+# define fprintf curlx_mfprintf
+# define sprintf curlx_msprintf
+# define snprintf curlx_msnprintf
+# define vprintf curlx_mvprintf
+# define vfprintf curlx_mvfprintf
+# define vsprintf curlx_mvsprintf
+# define vsnprintf curlx_mvsnprintf
+# define aprintf curlx_maprintf
+# define vaprintf curlx_mvaprintf
+#endif /* ENABLE_CURLX_PRINTF */
+
+#endif /* HEADER_CURL_CURLX_H */
+
diff --git a/Utilities/cmcurl/lib/dict.c b/Utilities/cmcurl/lib/dict.c
new file mode 100644
index 000000000..06d76992e
--- /dev/null
+++ b/Utilities/cmcurl/lib/dict.c
@@ -0,0 +1,279 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_DICT
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "transfer.h"
+#include "sendf.h"
+
+#include "progress.h"
+#include "strequal.h"
+#include "dict.h"
+#include "rawstr.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ * Forward declarations.
+ */
+
+static CURLcode dict_do(struct connectdata *conn, bool *done);
+
+/*
+ * DICT protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_dict = {
+ "DICT", /* scheme */
+ ZERO_NULL, /* setup_connection */
+ dict_do, /* do_it */
+ ZERO_NULL, /* done */
+ ZERO_NULL, /* do_more */
+ ZERO_NULL, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_getsock */
+ ZERO_NULL, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ ZERO_NULL, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_DICT, /* defport */
+ CURLPROTO_DICT, /* protocol */
+ PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */
+};
+
+static char *unescape_word(struct SessionHandle *data, const char *inputbuff)
+{
+ char *newp;
+ char *dictp;
+ char *ptr;
+ int len;
+ char ch;
+ int olen=0;
+
+ newp = curl_easy_unescape(data, inputbuff, 0, &len);
+ if(!newp)
+ return NULL;
+
+ dictp = malloc(((size_t)len)*2 + 1); /* add one for terminating zero */
+ if(dictp) {
+ /* According to RFC2229 section 2.2, these letters need to be escaped with
+ \[letter] */
+ for(ptr = newp;
+ (ch = *ptr) != 0;
+ ptr++) {
+ if((ch <= 32) || (ch == 127) ||
+ (ch == '\'') || (ch == '\"') || (ch == '\\')) {
+ dictp[olen++] = '\\';
+ }
+ dictp[olen++] = ch;
+ }
+ dictp[olen]=0;
+ }
+ free(newp);
+ return dictp;
+}
+
+static CURLcode dict_do(struct connectdata *conn, bool *done)
+{
+ char *word;
+ char *eword;
+ char *ppath;
+ char *database = NULL;
+ char *strategy = NULL;
+ char *nthdef = NULL; /* This is not part of the protocol, but required
+ by RFC 2229 */
+ CURLcode result=CURLE_OK;
+ struct SessionHandle *data=conn->data;
+ curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
+
+ char *path = data->state.path;
+ curl_off_t *bytecount = &data->req.bytecount;
+
+ *done = TRUE; /* unconditionally */
+
+ if(conn->bits.user_passwd) {
+ /* AUTH is missing */
+ }
+
+ if(Curl_raw_nequal(path, DICT_MATCH, sizeof(DICT_MATCH)-1) ||
+ Curl_raw_nequal(path, DICT_MATCH2, sizeof(DICT_MATCH2)-1) ||
+ Curl_raw_nequal(path, DICT_MATCH3, sizeof(DICT_MATCH3)-1)) {
+
+ word = strchr(path, ':');
+ if(word) {
+ word++;
+ database = strchr(word, ':');
+ if(database) {
+ *database++ = (char)0;
+ strategy = strchr(database, ':');
+ if(strategy) {
+ *strategy++ = (char)0;
+ nthdef = strchr(strategy, ':');
+ if(nthdef) {
+ *nthdef = (char)0;
+ }
+ }
+ }
+ }
+
+ if((word == NULL) || (*word == (char)0)) {
+ infof(data, "lookup word is missing\n");
+ word=(char *)"default";
+ }
+ if((database == NULL) || (*database == (char)0)) {
+ database = (char *)"!";
+ }
+ if((strategy == NULL) || (*strategy == (char)0)) {
+ strategy = (char *)".";
+ }
+
+ eword = unescape_word(data, word);
+ if(!eword)
+ return CURLE_OUT_OF_MEMORY;
+
+ result = Curl_sendf(sockfd, conn,
+ "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
+ "MATCH "
+ "%s " /* database */
+ "%s " /* strategy */
+ "%s\r\n" /* word */
+ "QUIT\r\n",
+
+ database,
+ strategy,
+ eword
+ );
+
+ free(eword);
+
+ if(result) {
+ failf(data, "Failed sending DICT request");
+ return result;
+ }
+ Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
+ -1, NULL); /* no upload */
+ }
+ else if(Curl_raw_nequal(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) ||
+ Curl_raw_nequal(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) ||
+ Curl_raw_nequal(path, DICT_DEFINE3, sizeof(DICT_DEFINE3)-1)) {
+
+ word = strchr(path, ':');
+ if(word) {
+ word++;
+ database = strchr(word, ':');
+ if(database) {
+ *database++ = (char)0;
+ nthdef = strchr(database, ':');
+ if(nthdef) {
+ *nthdef = (char)0;
+ }
+ }
+ }
+
+ if((word == NULL) || (*word == (char)0)) {
+ infof(data, "lookup word is missing\n");
+ word=(char *)"default";
+ }
+ if((database == NULL) || (*database == (char)0)) {
+ database = (char *)"!";
+ }
+
+ eword = unescape_word(data, word);
+ if(!eword)
+ return CURLE_OUT_OF_MEMORY;
+
+ result = Curl_sendf(sockfd, conn,
+ "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
+ "DEFINE "
+ "%s " /* database */
+ "%s\r\n" /* word */
+ "QUIT\r\n",
+ database,
+ eword);
+
+ free(eword);
+
+ if(result) {
+ failf(data, "Failed sending DICT request");
+ return result;
+ }
+ Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
+ -1, NULL); /* no upload */
+ }
+ else {
+
+ ppath = strchr(path, '/');
+ if(ppath) {
+ int i;
+
+ ppath++;
+ for(i = 0; ppath[i]; i++) {
+ if(ppath[i] == ':')
+ ppath[i] = ' ';
+ }
+ result = Curl_sendf(sockfd, conn,
+ "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
+ "%s\r\n"
+ "QUIT\r\n", ppath);
+ if(result) {
+ failf(data, "Failed sending DICT request");
+ return result;
+ }
+
+ Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount, -1, NULL);
+ }
+ }
+
+ return CURLE_OK;
+}
+#endif /*CURL_DISABLE_DICT*/
diff --git a/Utilities/cmcurl/lib/dict.h b/Utilities/cmcurl/lib/dict.h
new file mode 100644
index 000000000..44fd9d49d
--- /dev/null
+++ b/Utilities/cmcurl/lib/dict.h
@@ -0,0 +1,29 @@
+#ifndef HEADER_CURL_DICT_H
+#define HEADER_CURL_DICT_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifndef CURL_DISABLE_DICT
+extern const struct Curl_handler Curl_handler_dict;
+#endif
+
+#endif /* HEADER_CURL_DICT_H */
diff --git a/Utilities/cmcurl/lib/dotdot.c b/Utilities/cmcurl/lib/dotdot.c
new file mode 100644
index 000000000..ae169411d
--- /dev/null
+++ b/Utilities/cmcurl/lib/dotdot.c
@@ -0,0 +1,170 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "dotdot.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ * "Remove Dot Segments"
+ * http://tools.ietf.org/html/rfc3986#section-5.2.4
+ */
+
+/*
+ * Curl_dedotdotify()
+ *
+ * This function gets a zero-terminated path with dot and dotdot sequences
+ * passed in and strips them off according to the rules in RFC 3986 section
+ * 5.2.4.
+ *
+ * The function handles a query part ('?' + stuff) appended but it expects
+ * that fragments ('#' + stuff) have already been cut off.
+ *
+ * RETURNS
+ *
+ * an allocated dedotdotified output string
+ */
+char *Curl_dedotdotify(const char *input)
+{
+ size_t inlen = strlen(input);
+ char *clone;
+ size_t clen = inlen; /* the length of the cloned input */
+ char *out = malloc(inlen+1);
+ char *outptr;
+ char *orgclone;
+ char *queryp;
+ if(!out)
+ return NULL; /* out of memory */
+
+ /* get a cloned copy of the input */
+ clone = strdup(input);
+ if(!clone) {
+ free(out);
+ return NULL;
+ }
+ orgclone = clone;
+ outptr = out;
+
+ /*
+ * To handle query-parts properly, we must find it and remove it during the
+ * dotdot-operation and then append it again at the end to the output
+ * string.
+ */
+ queryp = strchr(clone, '?');
+ if(queryp)
+ *queryp = 0;
+
+ do {
+
+ /* A. If the input buffer begins with a prefix of "../" or "./", then
+ remove that prefix from the input buffer; otherwise, */
+
+ if(!strncmp("./", clone, 2)) {
+ clone+=2;
+ clen-=2;
+ }
+ else if(!strncmp("../", clone, 3)) {
+ clone+=3;
+ clen-=3;
+ }
+
+ /* B. if the input buffer begins with a prefix of "/./" or "/.", where
+ "." is a complete path segment, then replace that prefix with "/" in
+ the input buffer; otherwise, */
+ else if(!strncmp("/./", clone, 3)) {
+ clone+=2;
+ clen-=2;
+ }
+ else if(!strcmp("/.", clone)) {
+ clone[1]='/';
+ clone++;
+ clen-=1;
+ }
+
+ /* C. if the input buffer begins with a prefix of "/../" or "/..", where
+ ".." is a complete path segment, then replace that prefix with "/" in
+ the input buffer and remove the last segment and its preceding "/" (if
+ any) from the output buffer; otherwise, */
+
+ else if(!strncmp("/../", clone, 4)) {
+ clone+=3;
+ clen-=3;
+ /* remove the last segment from the output buffer */
+ while(outptr > out) {
+ outptr--;
+ if(*outptr == '/')
+ break;
+ }
+ *outptr = 0; /* zero-terminate where it stops */
+ }
+ else if(!strcmp("/..", clone)) {
+ clone[2]='/';
+ clone+=2;
+ clen-=2;
+ /* remove the last segment from the output buffer */
+ while(outptr > out) {
+ outptr--;
+ if(*outptr == '/')
+ break;
+ }
+ *outptr = 0; /* zero-terminate where it stops */
+ }
+
+ /* D. if the input buffer consists only of "." or "..", then remove
+ that from the input buffer; otherwise, */
+
+ else if(!strcmp(".", clone) || !strcmp("..", clone)) {
+ *clone=0;
+ }
+
+ else {
+ /* E. move the first path segment in the input buffer to the end of
+ the output buffer, including the initial "/" character (if any) and
+ any subsequent characters up to, but not including, the next "/"
+ character or the end of the input buffer. */
+
+ do {
+ *outptr++ = *clone++;
+ clen--;
+ } while(*clone && (*clone != '/'));
+ *outptr = 0;
+ }
+
+ } while(*clone);
+
+ if(queryp) {
+ size_t qlen;
+ /* There was a query part, append that to the output. The 'clone' string
+ may now have been altered so we copy from the original input string
+ from the correct index. */
+ size_t oindex = queryp - orgclone;
+ qlen = strlen(&input[oindex]);
+ memcpy(outptr, &input[oindex], qlen+1); /* include the ending zero byte */
+ }
+
+ free(orgclone);
+ return out;
+}
diff --git a/Utilities/cmcurl/lib/dotdot.h b/Utilities/cmcurl/lib/dotdot.h
new file mode 100644
index 000000000..cd57822ba
--- /dev/null
+++ b/Utilities/cmcurl/lib/dotdot.h
@@ -0,0 +1,25 @@
+#ifndef HEADER_CURL_DOTDOT_H
+#define HEADER_CURL_DOTDOT_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+char *Curl_dedotdotify(const char *input);
+#endif
diff --git a/Utilities/cmcurl/lib/easy.c b/Utilities/cmcurl/lib/easy.c
new file mode 100644
index 000000000..316acb1d1
--- /dev/null
+++ b/Utilities/cmcurl/lib/easy.c
@@ -0,0 +1,1130 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+/*
+ * See comment in curl_memory.h for the explanation of this sanity check.
+ */
+
+#ifdef CURLX_NO_MEMORY_CALLBACKS
+#error "libcurl shall not ever be built with CURLX_NO_MEMORY_CALLBACKS defined"
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#include "strequal.h"
+#include "urldata.h"
+#include <curl/curl.h>
+#include "transfer.h"
+#include "vtls/vtls.h"
+#include "url.h"
+#include "getinfo.h"
+#include "hostip.h"
+#include "share.h"
+#include "strdup.h"
+#include "progress.h"
+#include "easyif.h"
+#include "select.h"
+#include "sendf.h" /* for failf function prototype */
+#include "curl_ntlm.h"
+#include "connect.h" /* for Curl_getconnectinfo */
+#include "slist.h"
+#include "amigaos.h"
+#include "non-ascii.h"
+#include "warnless.h"
+#include "conncache.h"
+#include "multiif.h"
+#include "sigpipe.h"
+#include "ssh.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* win32_cleanup() is for win32 socket cleanup functionality, the opposite
+ of win32_init() */
+static void win32_cleanup(void)
+{
+#ifdef USE_WINSOCK
+ WSACleanup();
+#endif
+#ifdef USE_WINDOWS_SSPI
+ Curl_sspi_global_cleanup();
+#endif
+}
+
+/* win32_init() performs win32 socket initialization to properly setup the
+ stack to allow networking */
+static CURLcode win32_init(void)
+{
+#ifdef USE_WINSOCK
+ WORD wVersionRequested;
+ WSADATA wsaData;
+ int res;
+
+#if defined(ENABLE_IPV6) && (USE_WINSOCK < 2)
+ Error IPV6_requires_winsock2
+#endif
+
+ wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
+
+ res = WSAStartup(wVersionRequested, &wsaData);
+
+ if(res != 0)
+ /* Tell the user that we couldn't find a useable */
+ /* winsock.dll. */
+ return CURLE_FAILED_INIT;
+
+ /* Confirm that the Windows Sockets DLL supports what we need.*/
+ /* Note that if the DLL supports versions greater */
+ /* than wVersionRequested, it will still return */
+ /* wVersionRequested in wVersion. wHighVersion contains the */
+ /* highest supported version. */
+
+ if(LOBYTE( wsaData.wVersion ) != LOBYTE(wVersionRequested) ||
+ HIBYTE( wsaData.wVersion ) != HIBYTE(wVersionRequested) ) {
+ /* Tell the user that we couldn't find a useable */
+
+ /* winsock.dll. */
+ WSACleanup();
+ return CURLE_FAILED_INIT;
+ }
+ /* The Windows Sockets DLL is acceptable. Proceed. */
+#elif defined(USE_LWIPSOCK)
+ lwip_init();
+#endif
+
+#ifdef USE_WINDOWS_SSPI
+ {
+ CURLcode result = Curl_sspi_global_init();
+ if(result)
+ return result;
+ }
+#endif
+
+ return CURLE_OK;
+}
+
+#ifdef USE_LIBIDN
+/*
+ * Initialise use of IDNA library.
+ * It falls back to ASCII if $CHARSET isn't defined. This doesn't work for
+ * idna_to_ascii_lz().
+ */
+static void idna_init (void)
+{
+#ifdef WIN32
+ char buf[60];
+ UINT cp = GetACP();
+
+ if(!getenv("CHARSET") && cp > 0) {
+ snprintf(buf, sizeof(buf), "CHARSET=cp%u", cp);
+ putenv(buf);
+ }
+#else
+ /* to do? */
+#endif
+}
+#endif /* USE_LIBIDN */
+
+/* true globals -- for curl_global_init() and curl_global_cleanup() */
+static unsigned int initialized;
+static long init_flags;
+
+/*
+ * strdup (and other memory functions) is redefined in complicated
+ * ways, but at this point it must be defined as the system-supplied strdup
+ * so the callback pointer is initialized correctly.
+ */
+#if defined(_WIN32_WCE)
+#define system_strdup _strdup
+#elif !defined(HAVE_STRDUP)
+#define system_strdup curlx_strdup
+#else
+#define system_strdup strdup
+#endif
+
+#if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__)
+# pragma warning(disable:4232) /* MSVC extension, dllimport identity */
+#endif
+
+#ifndef __SYMBIAN32__
+/*
+ * If a memory-using function (like curl_getenv) is used before
+ * curl_global_init() is called, we need to have these pointers set already.
+ */
+curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc;
+curl_free_callback Curl_cfree = (curl_free_callback)free;
+curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc;
+curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)system_strdup;
+curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
+#if defined(WIN32) && defined(UNICODE)
+curl_wcsdup_callback Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
+#endif
+#else
+/*
+ * Symbian OS doesn't support initialization to code in writeable static data.
+ * Initialization will occur in the curl_global_init() call.
+ */
+curl_malloc_callback Curl_cmalloc;
+curl_free_callback Curl_cfree;
+curl_realloc_callback Curl_crealloc;
+curl_strdup_callback Curl_cstrdup;
+curl_calloc_callback Curl_ccalloc;
+#endif
+
+#if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__)
+# pragma warning(default:4232) /* MSVC extension, dllimport identity */
+#endif
+
+/**
+ * curl_global_init() globally initializes cURL given a bitwise set of the
+ * different features of what to initialize.
+ */
+CURLcode curl_global_init(long flags)
+{
+ if(initialized++)
+ return CURLE_OK;
+
+ /* Setup the default memory functions here (again) */
+ Curl_cmalloc = (curl_malloc_callback)malloc;
+ Curl_cfree = (curl_free_callback)free;
+ Curl_crealloc = (curl_realloc_callback)realloc;
+ Curl_cstrdup = (curl_strdup_callback)system_strdup;
+ Curl_ccalloc = (curl_calloc_callback)calloc;
+#if defined(WIN32) && defined(UNICODE)
+ Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
+#endif
+
+ if(flags & CURL_GLOBAL_SSL)
+ if(!Curl_ssl_init()) {
+ DEBUGF(fprintf(stderr, "Error: Curl_ssl_init failed\n"));
+ return CURLE_FAILED_INIT;
+ }
+
+ if(flags & CURL_GLOBAL_WIN32)
+ if(win32_init()) {
+ DEBUGF(fprintf(stderr, "Error: win32_init failed\n"));
+ return CURLE_FAILED_INIT;
+ }
+
+#ifdef __AMIGA__
+ if(!Curl_amiga_init()) {
+ DEBUGF(fprintf(stderr, "Error: Curl_amiga_init failed\n"));
+ return CURLE_FAILED_INIT;
+ }
+#endif
+
+#ifdef NETWARE
+ if(netware_init()) {
+ DEBUGF(fprintf(stderr, "Warning: LONG namespace not available\n"));
+ }
+#endif
+
+#ifdef USE_LIBIDN
+ idna_init();
+#endif
+
+ if(Curl_resolver_global_init()) {
+ DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n"));
+ return CURLE_FAILED_INIT;
+ }
+
+#if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_INIT)
+ if(libssh2_init(0)) {
+ DEBUGF(fprintf(stderr, "Error: libssh2_init failed\n"));
+ return CURLE_FAILED_INIT;
+ }
+#endif
+
+ if(flags & CURL_GLOBAL_ACK_EINTR)
+ Curl_ack_eintr = 1;
+
+ init_flags = flags;
+
+ return CURLE_OK;
+}
+
+/*
+ * curl_global_init_mem() globally initializes cURL and also registers the
+ * user provided callback routines.
+ */
+CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
+ curl_free_callback f, curl_realloc_callback r,
+ curl_strdup_callback s, curl_calloc_callback c)
+{
+ CURLcode result = CURLE_OK;
+
+ /* Invalid input, return immediately */
+ if(!m || !f || !r || !s || !c)
+ return CURLE_FAILED_INIT;
+
+ if(initialized) {
+ /* Already initialized, don't do it again, but bump the variable anyway to
+ work like curl_global_init() and require the same amount of cleanup
+ calls. */
+ initialized++;
+ return CURLE_OK;
+ }
+
+ /* Call the actual init function first */
+ result = curl_global_init(flags);
+ if(!result) {
+ Curl_cmalloc = m;
+ Curl_cfree = f;
+ Curl_cstrdup = s;
+ Curl_crealloc = r;
+ Curl_ccalloc = c;
+ }
+
+ return result;
+}
+
+/**
+ * curl_global_cleanup() globally cleanups cURL, uses the value of
+ * "init_flags" to determine what needs to be cleaned up and what doesn't.
+ */
+void curl_global_cleanup(void)
+{
+ if(!initialized)
+ return;
+
+ if(--initialized)
+ return;
+
+ Curl_global_host_cache_dtor();
+
+ if(init_flags & CURL_GLOBAL_SSL)
+ Curl_ssl_cleanup();
+
+ Curl_resolver_global_cleanup();
+
+ if(init_flags & CURL_GLOBAL_WIN32)
+ win32_cleanup();
+
+ Curl_amiga_cleanup();
+
+#if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_EXIT)
+ (void)libssh2_exit();
+#endif
+
+ init_flags = 0;
+}
+
+/*
+ * curl_easy_init() is the external interface to alloc, setup and init an
+ * easy handle that is returned. If anything goes wrong, NULL is returned.
+ */
+CURL *curl_easy_init(void)
+{
+ CURLcode result;
+ struct SessionHandle *data;
+
+ /* Make sure we inited the global SSL stuff */
+ if(!initialized) {
+ result = curl_global_init(CURL_GLOBAL_DEFAULT);
+ if(result) {
+ /* something in the global init failed, return nothing */
+ DEBUGF(fprintf(stderr, "Error: curl_global_init failed\n"));
+ return NULL;
+ }
+ }
+
+ /* We use curl_open() with undefined URL so far */
+ result = Curl_open(&data);
+ if(result) {
+ DEBUGF(fprintf(stderr, "Error: Curl_open failed\n"));
+ return NULL;
+ }
+
+ return data;
+}
+
+/*
+ * curl_easy_setopt() is the external interface for setting options on an
+ * easy handle.
+ */
+
+#undef curl_easy_setopt
+CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
+{
+ va_list arg;
+ struct SessionHandle *data = curl;
+ CURLcode result;
+
+ if(!curl)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+
+ va_start(arg, tag);
+
+ result = Curl_setopt(data, tag, arg);
+
+ va_end(arg);
+ return result;
+}
+
+#ifdef CURLDEBUG
+
+struct socketmonitor {
+ struct socketmonitor *next; /* the next node in the list or NULL */
+ struct pollfd socket; /* socket info of what to monitor */
+};
+
+struct events {
+ long ms; /* timeout, run the timeout function when reached */
+ bool msbump; /* set TRUE when timeout is set by callback */
+ int num_sockets; /* number of nodes in the monitor list */
+ struct socketmonitor *list; /* list of sockets to monitor */
+ int running_handles; /* store the returned number */
+};
+
+/* events_timer
+ *
+ * Callback that gets called with a new value when the timeout should be
+ * updated.
+ */
+
+static int events_timer(CURLM *multi, /* multi handle */
+ long timeout_ms, /* see above */
+ void *userp) /* private callback pointer */
+{
+ struct events *ev = userp;
+ (void)multi;
+ if(timeout_ms == -1)
+ /* timeout removed */
+ timeout_ms = 0;
+ else if(timeout_ms == 0)
+ /* timeout is already reached! */
+ timeout_ms = 1; /* trigger asap */
+
+ ev->ms = timeout_ms;
+ ev->msbump = TRUE;
+ return 0;
+}
+
+
+/* poll2cselect
+ *
+ * convert from poll() bit definitions to libcurl's CURL_CSELECT_* ones
+ */
+static int poll2cselect(int pollmask)
+{
+ int omask=0;
+ if(pollmask & POLLIN)
+ omask |= CURL_CSELECT_IN;
+ if(pollmask & POLLOUT)
+ omask |= CURL_CSELECT_OUT;
+ if(pollmask & POLLERR)
+ omask |= CURL_CSELECT_ERR;
+ return omask;
+}
+
+
+/* socketcb2poll
+ *
+ * convert from libcurl' CURL_POLL_* bit definitions to poll()'s
+ */
+static short socketcb2poll(int pollmask)
+{
+ short omask=0;
+ if(pollmask & CURL_POLL_IN)
+ omask |= POLLIN;
+ if(pollmask & CURL_POLL_OUT)
+ omask |= POLLOUT;
+ return omask;
+}
+
+/* events_socket
+ *
+ * Callback that gets called with information about socket activity to
+ * monitor.
+ */
+static int events_socket(CURL *easy, /* easy handle */
+ curl_socket_t s, /* socket */
+ int what, /* see above */
+ void *userp, /* private callback
+ pointer */
+ void *socketp) /* private socket
+ pointer */
+{
+ struct events *ev = userp;
+ struct socketmonitor *m;
+ struct socketmonitor *prev=NULL;
+
+#if defined(CURL_DISABLE_VERBOSE_STRINGS)
+ (void) easy;
+#endif
+ (void)socketp;
+
+ m = ev->list;
+ while(m) {
+ if(m->socket.fd == s) {
+
+ if(what == CURL_POLL_REMOVE) {
+ struct socketmonitor *nxt = m->next;
+ /* remove this node from the list of monitored sockets */
+ if(prev)
+ prev->next = nxt;
+ else
+ ev->list = nxt;
+ free(m);
+ m = nxt;
+ infof(easy, "socket cb: socket %d REMOVED\n", s);
+ }
+ else {
+ /* The socket 's' is already being monitored, update the activity
+ mask. Convert from libcurl bitmask to the poll one. */
+ m->socket.events = socketcb2poll(what);
+ infof(easy, "socket cb: socket %d UPDATED as %s%s\n", s,
+ what&CURL_POLL_IN?"IN":"",
+ what&CURL_POLL_OUT?"OUT":"");
+ }
+ break;
+ }
+ prev = m;
+ m = m->next; /* move to next node */
+ }
+ if(!m) {
+ if(what == CURL_POLL_REMOVE) {
+ /* this happens a bit too often, libcurl fix perhaps? */
+ /* fprintf(stderr,
+ "%s: socket %d asked to be REMOVED but not present!\n",
+ __func__, s); */
+ }
+ else {
+ m = malloc(sizeof(struct socketmonitor));
+ m->next = ev->list;
+ m->socket.fd = s;
+ m->socket.events = socketcb2poll(what);
+ m->socket.revents = 0;
+ ev->list = m;
+ infof(easy, "socket cb: socket %d ADDED as %s%s\n", s,
+ what&CURL_POLL_IN?"IN":"",
+ what&CURL_POLL_OUT?"OUT":"");
+ }
+ }
+
+ return 0;
+}
+
+
+/*
+ * events_setup()
+ *
+ * Do the multi handle setups that only event-based transfers need.
+ */
+static void events_setup(CURLM *multi, struct events *ev)
+{
+ /* timer callback */
+ curl_multi_setopt(multi, CURLMOPT_TIMERFUNCTION, events_timer);
+ curl_multi_setopt(multi, CURLMOPT_TIMERDATA, ev);
+
+ /* socket callback */
+ curl_multi_setopt(multi, CURLMOPT_SOCKETFUNCTION, events_socket);
+ curl_multi_setopt(multi, CURLMOPT_SOCKETDATA, ev);
+}
+
+
+/* wait_or_timeout()
+ *
+ * waits for activity on any of the given sockets, or the timeout to trigger.
+ */
+
+static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
+{
+ bool done = FALSE;
+ CURLMcode mcode;
+ CURLcode result = CURLE_OK;
+
+ while(!done) {
+ CURLMsg *msg;
+ struct socketmonitor *m;
+ struct pollfd *f;
+ struct pollfd fds[4];
+ int numfds=0;
+ int pollrc;
+ int i;
+ struct timeval before;
+ struct timeval after;
+
+ /* populate the fds[] array */
+ for(m = ev->list, f=&fds[0]; m; m = m->next) {
+ f->fd = m->socket.fd;
+ f->events = m->socket.events;
+ f->revents = 0;
+ /* fprintf(stderr, "poll() %d check socket %d\n", numfds, f->fd); */
+ f++;
+ numfds++;
+ }
+
+ /* get the time stamp to use to figure out how long poll takes */
+ before = curlx_tvnow();
+
+ /* wait for activity or timeout */
+ pollrc = Curl_poll(fds, numfds, (int)ev->ms);
+
+ after = curlx_tvnow();
+
+ ev->msbump = FALSE; /* reset here */
+
+ if(0 == pollrc) {
+ /* timeout! */
+ ev->ms = 0;
+ /* fprintf(stderr, "call curl_multi_socket_action( TIMEOUT )\n"); */
+ mcode = curl_multi_socket_action(multi, CURL_SOCKET_TIMEOUT, 0,
+ &ev->running_handles);
+ }
+ else if(pollrc > 0) {
+ /* loop over the monitored sockets to see which ones had activity */
+ for(i = 0; i< numfds; i++) {
+ if(fds[i].revents) {
+ /* socket activity, tell libcurl */
+ int act = poll2cselect(fds[i].revents); /* convert */
+ infof(multi->easyp, "call curl_multi_socket_action( socket %d )\n",
+ fds[i].fd);
+ mcode = curl_multi_socket_action(multi, fds[i].fd, act,
+ &ev->running_handles);
+ }
+ }
+
+ if(!ev->msbump)
+ /* If nothing updated the timeout, we decrease it by the spent time.
+ * If it was updated, it has the new timeout time stored already.
+ */
+ ev->ms += curlx_tvdiff(after, before);
+
+ }
+ else
+ return CURLE_RECV_ERROR;
+
+ if(mcode)
+ return CURLE_URL_MALFORMAT; /* TODO: return a proper error! */
+
+ /* we don't really care about the "msgs_in_queue" value returned in the
+ second argument */
+ msg = curl_multi_info_read(multi, &pollrc);
+ if(msg) {
+ result = msg->data.result;
+ done = TRUE;
+ }
+ }
+
+ return result;
+}
+
+
+/* easy_events()
+ *
+ * Runs a transfer in a blocking manner using the events-based API
+ */
+static CURLcode easy_events(CURLM *multi)
+{
+ struct events evs= {2, FALSE, 0, NULL, 0};
+
+ /* if running event-based, do some further multi inits */
+ events_setup(multi, &evs);
+
+ return wait_or_timeout(multi, &evs);
+}
+#else /* CURLDEBUG */
+/* when not built with debug, this function doesn't exist */
+#define easy_events(x) CURLE_NOT_BUILT_IN
+#endif
+
+static CURLcode easy_transfer(CURLM *multi)
+{
+ bool done = FALSE;
+ CURLMcode mcode = CURLM_OK;
+ CURLcode result = CURLE_OK;
+ struct timeval before;
+ int without_fds = 0; /* count number of consecutive returns from
+ curl_multi_wait() without any filedescriptors */
+
+ while(!done && !mcode) {
+ int still_running = 0;
+ int ret;
+
+ before = curlx_tvnow();
+ mcode = curl_multi_wait(multi, NULL, 0, 1000, &ret);
+
+ if(mcode == CURLM_OK) {
+ if(ret == -1) {
+ /* poll() failed not on EINTR, indicate a network problem */
+ result = CURLE_RECV_ERROR;
+ break;
+ }
+ else if(ret == 0) {
+ struct timeval after = curlx_tvnow();
+ /* If it returns without any filedescriptor instantly, we need to
+ avoid busy-looping during periods where it has nothing particular
+ to wait for */
+ if(curlx_tvdiff(after, before) <= 10) {
+ without_fds++;
+ if(without_fds > 2) {
+ int sleep_ms = without_fds < 10 ? (1 << (without_fds-1)): 1000;
+ Curl_wait_ms(sleep_ms);
+ }
+ }
+ else
+ /* it wasn't "instant", restart counter */
+ without_fds = 0;
+ }
+ else
+ /* got file descriptor, restart counter */
+ without_fds = 0;
+
+ mcode = curl_multi_perform(multi, &still_running);
+ }
+
+ /* only read 'still_running' if curl_multi_perform() return OK */
+ if((mcode == CURLM_OK) && !still_running) {
+ int rc;
+ CURLMsg *msg = curl_multi_info_read(multi, &rc);
+ if(msg) {
+ result = msg->data.result;
+ done = TRUE;
+ }
+ }
+ }
+
+ /* Make sure to return some kind of error if there was a multi problem */
+ if(mcode) {
+ return (mcode == CURLM_OUT_OF_MEMORY) ? CURLE_OUT_OF_MEMORY :
+ /* The other multi errors should never happen, so return
+ something suitably generic */
+ CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+
+ return result;
+}
+
+
+/*
+ * easy_perform() is the external interface that performs a blocking
+ * transfer as previously setup.
+ *
+ * CONCEPT: This function creates a multi handle, adds the easy handle to it,
+ * runs curl_multi_perform() until the transfer is done, then detaches the
+ * easy handle, destroys the multi handle and returns the easy handle's return
+ * code.
+ *
+ * REALITY: it can't just create and destroy the multi handle that easily. It
+ * needs to keep it around since if this easy handle is used again by this
+ * function, the same multi handle must be re-used so that the same pools and
+ * caches can be used.
+ *
+ * DEBUG: if 'events' is set TRUE, this function will use a replacement engine
+ * instead of curl_multi_perform() and use curl_multi_socket_action().
+ */
+static CURLcode easy_perform(struct SessionHandle *data, bool events)
+{
+ CURLM *multi;
+ CURLMcode mcode;
+ CURLcode result = CURLE_OK;
+ SIGPIPE_VARIABLE(pipe_st);
+
+ if(!data)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+
+ if(data->multi) {
+ failf(data, "easy handle already used in multi handle");
+ return CURLE_FAILED_INIT;
+ }
+
+ if(data->multi_easy)
+ multi = data->multi_easy;
+ else {
+ /* this multi handle will only ever have a single easy handled attached
+ to it, so make it use minimal hashes */
+ multi = Curl_multi_handle(1, 3);
+ if(!multi)
+ return CURLE_OUT_OF_MEMORY;
+ data->multi_easy = multi;
+ }
+
+ /* Copy the MAXCONNECTS option to the multi handle */
+ curl_multi_setopt(multi, CURLMOPT_MAXCONNECTS, data->set.maxconnects);
+
+ mcode = curl_multi_add_handle(multi, data);
+ if(mcode) {
+ curl_multi_cleanup(multi);
+ if(mcode == CURLM_OUT_OF_MEMORY)
+ return CURLE_OUT_OF_MEMORY;
+ else
+ return CURLE_FAILED_INIT;
+ }
+
+ sigpipe_ignore(data, &pipe_st);
+
+ /* assign this after curl_multi_add_handle() since that function checks for
+ it and rejects this handle otherwise */
+ data->multi = multi;
+
+ /* run the transfer */
+ result = events ? easy_events(multi) : easy_transfer(multi);
+
+ /* ignoring the return code isn't nice, but atm we can't really handle
+ a failure here, room for future improvement! */
+ (void)curl_multi_remove_handle(multi, data);
+
+ sigpipe_restore(&pipe_st);
+
+ /* The multi handle is kept alive, owned by the easy handle */
+ return result;
+}
+
+
+/*
+ * curl_easy_perform() is the external interface that performs a blocking
+ * transfer as previously setup.
+ */
+CURLcode curl_easy_perform(CURL *easy)
+{
+ return easy_perform(easy, FALSE);
+}
+
+#ifdef CURLDEBUG
+/*
+ * curl_easy_perform_ev() is the external interface that performs a blocking
+ * transfer using the event-based API internally.
+ */
+CURLcode curl_easy_perform_ev(CURL *easy)
+{
+ return easy_perform(easy, TRUE);
+}
+
+#endif
+
+/*
+ * curl_easy_cleanup() is the external interface to cleaning/freeing the given
+ * easy handle.
+ */
+void curl_easy_cleanup(CURL *curl)
+{
+ struct SessionHandle *data = (struct SessionHandle *)curl;
+ SIGPIPE_VARIABLE(pipe_st);
+
+ if(!data)
+ return;
+
+ sigpipe_ignore(data, &pipe_st);
+ Curl_close(data);
+ sigpipe_restore(&pipe_st);
+}
+
+/*
+ * curl_easy_getinfo() is an external interface that allows an app to retrieve
+ * information from a performed transfer and similar.
+ */
+#undef curl_easy_getinfo
+CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
+{
+ va_list arg;
+ void *paramp;
+ CURLcode result;
+ struct SessionHandle *data = (struct SessionHandle *)curl;
+
+ va_start(arg, info);
+ paramp = va_arg(arg, void *);
+
+ result = Curl_getinfo(data, info, paramp);
+
+ va_end(arg);
+ return result;
+}
+
+/*
+ * curl_easy_duphandle() is an external interface to allow duplication of a
+ * given input easy handle. The returned handle will be a new working handle
+ * with all options set exactly as the input source handle.
+ */
+CURL *curl_easy_duphandle(CURL *incurl)
+{
+ struct SessionHandle *data=(struct SessionHandle *)incurl;
+
+ struct SessionHandle *outcurl = calloc(1, sizeof(struct SessionHandle));
+ if(NULL == outcurl)
+ goto fail;
+
+ /*
+ * We setup a few buffers we need. We should probably make them
+ * get setup on-demand in the code, as that would probably decrease
+ * the likeliness of us forgetting to init a buffer here in the future.
+ */
+ outcurl->state.headerbuff = malloc(HEADERSIZE);
+ if(!outcurl->state.headerbuff)
+ goto fail;
+ outcurl->state.headersize = HEADERSIZE;
+
+ /* copy all userdefined values */
+ if(Curl_dupset(outcurl, data))
+ goto fail;
+
+ /* the connection cache is setup on demand */
+ outcurl->state.conn_cache = NULL;
+
+ outcurl->state.lastconnect = NULL;
+
+ outcurl->progress.flags = data->progress.flags;
+ outcurl->progress.callback = data->progress.callback;
+
+ if(data->cookies) {
+ /* If cookies are enabled in the parent handle, we enable them
+ in the clone as well! */
+ outcurl->cookies = Curl_cookie_init(data,
+ data->cookies->filename,
+ outcurl->cookies,
+ data->set.cookiesession);
+ if(!outcurl->cookies)
+ goto fail;
+ }
+
+ /* duplicate all values in 'change' */
+ if(data->change.cookielist) {
+ outcurl->change.cookielist =
+ Curl_slist_duplicate(data->change.cookielist);
+ if(!outcurl->change.cookielist)
+ goto fail;
+ }
+
+ if(data->change.url) {
+ outcurl->change.url = strdup(data->change.url);
+ if(!outcurl->change.url)
+ goto fail;
+ outcurl->change.url_alloc = TRUE;
+ }
+
+ if(data->change.referer) {
+ outcurl->change.referer = strdup(data->change.referer);
+ if(!outcurl->change.referer)
+ goto fail;
+ outcurl->change.referer_alloc = TRUE;
+ }
+
+ /* Clone the resolver handle, if present, for the new handle */
+ if(Curl_resolver_duphandle(&outcurl->state.resolver,
+ data->state.resolver))
+ goto fail;
+
+ Curl_convert_setup(outcurl);
+
+ outcurl->magic = CURLEASY_MAGIC_NUMBER;
+
+ /* we reach this point and thus we are OK */
+
+ return outcurl;
+
+ fail:
+
+ if(outcurl) {
+ curl_slist_free_all(outcurl->change.cookielist);
+ outcurl->change.cookielist = NULL;
+ Curl_safefree(outcurl->state.headerbuff);
+ Curl_safefree(outcurl->change.url);
+ Curl_safefree(outcurl->change.referer);
+ Curl_freeset(outcurl);
+ free(outcurl);
+ }
+
+ return NULL;
+}
+
+/*
+ * curl_easy_reset() is an external interface that allows an app to re-
+ * initialize a session handle to the default values.
+ */
+void curl_easy_reset(CURL *curl)
+{
+ struct SessionHandle *data = (struct SessionHandle *)curl;
+
+ Curl_safefree(data->state.pathbuffer);
+
+ data->state.path = NULL;
+
+ Curl_free_request_state(data);
+
+ /* zero out UserDefined data: */
+ Curl_freeset(data);
+ memset(&data->set, 0, sizeof(struct UserDefined));
+ (void)Curl_init_userdefined(&data->set);
+
+ /* zero out Progress data: */
+ memset(&data->progress, 0, sizeof(struct Progress));
+
+ data->progress.flags |= PGRS_HIDE;
+ data->state.current_speed = -1; /* init to negative == impossible */
+}
+
+/*
+ * curl_easy_pause() allows an application to pause or unpause a specific
+ * transfer and direction. This function sets the full new state for the
+ * current connection this easy handle operates on.
+ *
+ * NOTE: if you have the receiving paused and you call this function to remove
+ * the pausing, you may get your write callback called at this point.
+ *
+ * Action is a bitmask consisting of CURLPAUSE_* bits in curl/curl.h
+ */
+CURLcode curl_easy_pause(CURL *curl, int action)
+{
+ struct SessionHandle *data = (struct SessionHandle *)curl;
+ struct SingleRequest *k = &data->req;
+ CURLcode result = CURLE_OK;
+
+ /* first switch off both pause bits */
+ int newstate = k->keepon &~ (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE);
+
+ /* set the new desired pause bits */
+ newstate |= ((action & CURLPAUSE_RECV)?KEEP_RECV_PAUSE:0) |
+ ((action & CURLPAUSE_SEND)?KEEP_SEND_PAUSE:0);
+
+ /* put it back in the keepon */
+ k->keepon = newstate;
+
+ if(!(newstate & KEEP_RECV_PAUSE) && data->state.tempwrite) {
+ /* we have a buffer for sending that we now seem to be able to deliver
+ since the receive pausing is lifted! */
+
+ /* get the pointer in local copy since the function may return PAUSE
+ again and then we'll get a new copy allocted and stored in
+ the tempwrite variables */
+ char *tempwrite = data->state.tempwrite;
+
+ data->state.tempwrite = NULL;
+ result = Curl_client_chop_write(data->easy_conn, data->state.tempwritetype,
+ tempwrite, data->state.tempwritesize);
+ free(tempwrite);
+ }
+
+ /* if there's no error and we're not pausing both directions, we want
+ to have this handle checked soon */
+ if(!result &&
+ ((newstate&(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
+ (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) )
+ Curl_expire(data, 1); /* get this handle going again */
+
+ return result;
+}
+
+
+static CURLcode easy_connection(struct SessionHandle *data,
+ curl_socket_t *sfd,
+ struct connectdata **connp)
+{
+ if(data == NULL)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+
+ /* only allow these to be called on handles with CURLOPT_CONNECT_ONLY */
+ if(!data->set.connect_only) {
+ failf(data, "CONNECT_ONLY is required!");
+ return CURLE_UNSUPPORTED_PROTOCOL;
+ }
+
+ *sfd = Curl_getconnectinfo(data, connp);
+
+ if(*sfd == CURL_SOCKET_BAD) {
+ failf(data, "Failed to get recent socket");
+ return CURLE_UNSUPPORTED_PROTOCOL;
+ }
+
+ return CURLE_OK;
+}
+
+/*
+ * Receives data from the connected socket. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ * Returns CURLE_OK on success, error code on error.
+ */
+CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, size_t *n)
+{
+ curl_socket_t sfd;
+ CURLcode result;
+ ssize_t n1;
+ struct connectdata *c;
+ struct SessionHandle *data = (struct SessionHandle *)curl;
+
+ result = easy_connection(data, &sfd, &c);
+ if(result)
+ return result;
+
+ *n = 0;
+ result = Curl_read(c, sfd, buffer, buflen, &n1);
+
+ if(result)
+ return result;
+
+ *n = (size_t)n1;
+
+ return CURLE_OK;
+}
+
+/*
+ * Sends data over the connected socket. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ */
+CURLcode curl_easy_send(CURL *curl, const void *buffer, size_t buflen,
+ size_t *n)
+{
+ curl_socket_t sfd;
+ CURLcode result;
+ ssize_t n1;
+ struct connectdata *c = NULL;
+ struct SessionHandle *data = (struct SessionHandle *)curl;
+
+ result = easy_connection(data, &sfd, &c);
+ if(result)
+ return result;
+
+ *n = 0;
+ result = Curl_write(c, sfd, buffer, buflen, &n1);
+
+ if(n1 == -1)
+ return CURLE_SEND_ERROR;
+
+ /* detect EAGAIN */
+ if(!result && !n1)
+ return CURLE_AGAIN;
+
+ *n = (size_t)n1;
+
+ return result;
+}
diff --git a/Utilities/cmcurl/lib/easyif.h b/Utilities/cmcurl/lib/easyif.h
new file mode 100644
index 000000000..043ff437d
--- /dev/null
+++ b/Utilities/cmcurl/lib/easyif.h
@@ -0,0 +1,33 @@
+#ifndef HEADER_CURL_EASYIF_H
+#define HEADER_CURL_EASYIF_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Prototypes for library-wide functions provided by easy.c
+ */
+#ifdef CURLDEBUG
+CURL_EXTERN CURLcode curl_easy_perform_ev(CURL *easy);
+#endif
+
+#endif /* HEADER_CURL_EASYIF_H */
+
diff --git a/Utilities/cmcurl/lib/escape.c b/Utilities/cmcurl/lib/escape.c
new file mode 100644
index 000000000..24abb930b
--- /dev/null
+++ b/Utilities/cmcurl/lib/escape.c
@@ -0,0 +1,231 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* Escape and unescape URL encoding in strings. The functions return a new
+ * allocated string or NULL if an error occurred. */
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#include "urldata.h"
+#include "warnless.h"
+#include "non-ascii.h"
+#include "escape.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* Portable character check (remember EBCDIC). Do not use isalnum() because
+ its behavior is altered by the current locale.
+ See http://tools.ietf.org/html/rfc3986#section-2.3
+*/
+static bool Curl_isunreserved(unsigned char in)
+{
+ switch (in) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ case 'a': case 'b': case 'c': case 'd': case 'e':
+ case 'f': case 'g': case 'h': case 'i': case 'j':
+ case 'k': case 'l': case 'm': case 'n': case 'o':
+ case 'p': case 'q': case 'r': case 's': case 't':
+ case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
+ case 'A': case 'B': case 'C': case 'D': case 'E':
+ case 'F': case 'G': case 'H': case 'I': case 'J':
+ case 'K': case 'L': case 'M': case 'N': case 'O':
+ case 'P': case 'Q': case 'R': case 'S': case 'T':
+ case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z':
+ case '-': case '.': case '_': case '~':
+ return TRUE;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+/* for ABI-compatibility with previous versions */
+char *curl_escape(const char *string, int inlength)
+{
+ return curl_easy_escape(NULL, string, inlength);
+}
+
+/* for ABI-compatibility with previous versions */
+char *curl_unescape(const char *string, int length)
+{
+ return curl_easy_unescape(NULL, string, length, NULL);
+}
+
+char *curl_easy_escape(CURL *handle, const char *string, int inlength)
+{
+ size_t alloc = (inlength?(size_t)inlength:strlen(string))+1;
+ char *ns;
+ char *testing_ptr = NULL;
+ unsigned char in; /* we need to treat the characters unsigned */
+ size_t newlen = alloc;
+ size_t strindex=0;
+ size_t length;
+ CURLcode result;
+
+ ns = malloc(alloc);
+ if(!ns)
+ return NULL;
+
+ length = alloc-1;
+ while(length--) {
+ in = *string;
+
+ if(Curl_isunreserved(in))
+ /* just copy this */
+ ns[strindex++]=in;
+ else {
+ /* encode it */
+ newlen += 2; /* the size grows with two, since this'll become a %XX */
+ if(newlen > alloc) {
+ alloc *= 2;
+ testing_ptr = realloc(ns, alloc);
+ if(!testing_ptr) {
+ free( ns );
+ return NULL;
+ }
+ else {
+ ns = testing_ptr;
+ }
+ }
+
+ result = Curl_convert_to_network(handle, &in, 1);
+ if(result) {
+ /* Curl_convert_to_network calls failf if unsuccessful */
+ free(ns);
+ return NULL;
+ }
+
+ snprintf(&ns[strindex], 4, "%%%02X", in);
+
+ strindex+=3;
+ }
+ string++;
+ }
+ ns[strindex]=0; /* terminate it */
+ return ns;
+}
+
+/*
+ * Curl_urldecode() URL decodes the given string.
+ *
+ * Optionally detects control characters (byte codes lower than 32) in the
+ * data and rejects such data.
+ *
+ * Returns a pointer to a malloced string in *ostring with length given in
+ * *olen. If length == 0, the length is assumed to be strlen(string).
+ *
+ */
+CURLcode Curl_urldecode(struct SessionHandle *data,
+ const char *string, size_t length,
+ char **ostring, size_t *olen,
+ bool reject_ctrl)
+{
+ size_t alloc = (length?length:strlen(string))+1;
+ char *ns = malloc(alloc);
+ unsigned char in;
+ size_t strindex=0;
+ unsigned long hex;
+ CURLcode result;
+
+ if(!ns)
+ return CURLE_OUT_OF_MEMORY;
+
+ while(--alloc > 0) {
+ in = *string;
+ if(('%' == in) && (alloc > 2) &&
+ ISXDIGIT(string[1]) && ISXDIGIT(string[2])) {
+ /* this is two hexadecimal digits following a '%' */
+ char hexstr[3];
+ char *ptr;
+ hexstr[0] = string[1];
+ hexstr[1] = string[2];
+ hexstr[2] = 0;
+
+ hex = strtoul(hexstr, &ptr, 16);
+
+ in = curlx_ultouc(hex); /* this long is never bigger than 255 anyway */
+
+ result = Curl_convert_from_network(data, &in, 1);
+ if(result) {
+ /* Curl_convert_from_network calls failf if unsuccessful */
+ free(ns);
+ return result;
+ }
+
+ string+=2;
+ alloc-=2;
+ }
+
+ if(reject_ctrl && (in < 0x20)) {
+ free(ns);
+ return CURLE_URL_MALFORMAT;
+ }
+
+ ns[strindex++] = in;
+ string++;
+ }
+ ns[strindex]=0; /* terminate it */
+
+ if(olen)
+ /* store output size */
+ *olen = strindex;
+
+ /* store output string */
+ *ostring = ns;
+
+ return CURLE_OK;
+}
+
+/*
+ * Unescapes the given URL escaped string of given length. Returns a
+ * pointer to a malloced string with length given in *olen.
+ * If length == 0, the length is assumed to be strlen(string).
+ * If olen == NULL, no output length is stored.
+ */
+char *curl_easy_unescape(CURL *handle, const char *string, int length,
+ int *olen)
+{
+ char *str = NULL;
+ size_t inputlen = length;
+ size_t outputlen;
+ CURLcode res = Curl_urldecode(handle, string, inputlen, &str, &outputlen,
+ FALSE);
+ if(res)
+ return NULL;
+ if(olen)
+ *olen = curlx_uztosi(outputlen);
+ return str;
+}
+
+/* For operating systems/environments that use different malloc/free
+ systems for the app and for this library, we provide a free that uses
+ the library's memory system */
+void curl_free(void *p)
+{
+ free(p);
+}
diff --git a/Utilities/cmcurl/lib/escape.h b/Utilities/cmcurl/lib/escape.h
new file mode 100644
index 000000000..731b13655
--- /dev/null
+++ b/Utilities/cmcurl/lib/escape.h
@@ -0,0 +1,33 @@
+#ifndef HEADER_CURL_ESCAPE_H
+#define HEADER_CURL_ESCAPE_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/* Escape and unescape URL encoding in strings. The functions return a new
+ * allocated string or NULL if an error occurred. */
+
+CURLcode Curl_urldecode(struct SessionHandle *data,
+ const char *string, size_t length,
+ char **ostring, size_t *olen,
+ bool reject_crlf);
+
+#endif /* HEADER_CURL_ESCAPE_H */
+
diff --git a/Utilities/cmcurl/lib/file.c b/Utilities/cmcurl/lib/file.c
new file mode 100644
index 000000000..175b10731
--- /dev/null
+++ b/Utilities/cmcurl/lib/file.c
@@ -0,0 +1,586 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_FILE
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#include "strtoofft.h"
+#include "urldata.h"
+#include <curl/curl.h>
+#include "progress.h"
+#include "sendf.h"
+#include "escape.h"
+#include "file.h"
+#include "speedcheck.h"
+#include "getinfo.h"
+#include "transfer.h"
+#include "url.h"
+#include "parsedate.h" /* for the week day and month names */
+#include "warnless.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#if defined(WIN32) || defined(MSDOS) || defined(__EMX__) || \
+ defined(__SYMBIAN32__)
+#define DOS_FILESYSTEM 1
+#endif
+
+#ifdef OPEN_NEEDS_ARG3
+# define open_readonly(p,f) open((p),(f),(0))
+#else
+# define open_readonly(p,f) open((p),(f))
+#endif
+
+/*
+ * Forward declarations.
+ */
+
+static CURLcode file_do(struct connectdata *, bool *done);
+static CURLcode file_done(struct connectdata *conn,
+ CURLcode status, bool premature);
+static CURLcode file_connect(struct connectdata *conn, bool *done);
+static CURLcode file_disconnect(struct connectdata *conn,
+ bool dead_connection);
+static CURLcode file_setup_connection(struct connectdata *conn);
+
+/*
+ * FILE scheme handler.
+ */
+
+const struct Curl_handler Curl_handler_file = {
+ "FILE", /* scheme */
+ file_setup_connection, /* setup_connection */
+ file_do, /* do_it */
+ file_done, /* done */
+ ZERO_NULL, /* do_more */
+ file_connect, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_getsock */
+ ZERO_NULL, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ file_disconnect, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ 0, /* defport */
+ CURLPROTO_FILE, /* protocol */
+ PROTOPT_NONETWORK | PROTOPT_NOURLQUERY /* flags */
+};
+
+
+static CURLcode file_setup_connection(struct connectdata *conn)
+{
+ /* allocate the FILE specific struct */
+ conn->data->req.protop = calloc(1, sizeof(struct FILEPROTO));
+ if(!conn->data->req.protop)
+ return CURLE_OUT_OF_MEMORY;
+
+ return CURLE_OK;
+}
+
+ /*
+ Check if this is a range download, and if so, set the internal variables
+ properly. This code is copied from the FTP implementation and might as
+ well be factored out.
+ */
+static CURLcode file_range(struct connectdata *conn)
+{
+ curl_off_t from, to;
+ curl_off_t totalsize=-1;
+ char *ptr;
+ char *ptr2;
+ struct SessionHandle *data = conn->data;
+
+ if(data->state.use_range && data->state.range) {
+ from=curlx_strtoofft(data->state.range, &ptr, 0);
+ while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
+ ptr++;
+ to=curlx_strtoofft(ptr, &ptr2, 0);
+ if(ptr == ptr2) {
+ /* we didn't get any digit */
+ to=-1;
+ }
+ if((-1 == to) && (from>=0)) {
+ /* X - */
+ data->state.resume_from = from;
+ DEBUGF(infof(data, "RANGE %" CURL_FORMAT_CURL_OFF_T " to end of file\n",
+ from));
+ }
+ else if(from < 0) {
+ /* -Y */
+ data->req.maxdownload = -from;
+ data->state.resume_from = from;
+ DEBUGF(infof(data, "RANGE the last %" CURL_FORMAT_CURL_OFF_T " bytes\n",
+ -from));
+ }
+ else {
+ /* X-Y */
+ totalsize = to-from;
+ data->req.maxdownload = totalsize+1; /* include last byte */
+ data->state.resume_from = from;
+ DEBUGF(infof(data, "RANGE from %" CURL_FORMAT_CURL_OFF_T
+ " getting %" CURL_FORMAT_CURL_OFF_T " bytes\n",
+ from, data->req.maxdownload));
+ }
+ DEBUGF(infof(data, "range-download from %" CURL_FORMAT_CURL_OFF_T
+ " to %" CURL_FORMAT_CURL_OFF_T ", totally %"
+ CURL_FORMAT_CURL_OFF_T " bytes\n",
+ from, to, data->req.maxdownload));
+ }
+ else
+ data->req.maxdownload = -1;
+ return CURLE_OK;
+}
+
+/*
+ * file_connect() gets called from Curl_protocol_connect() to allow us to
+ * do protocol-specific actions at connect-time. We emulate a
+ * connect-then-transfer protocol and "connect" to the file here
+ */
+static CURLcode file_connect(struct connectdata *conn, bool *done)
+{
+ struct SessionHandle *data = conn->data;
+ char *real_path;
+ struct FILEPROTO *file = data->req.protop;
+ int fd;
+#ifdef DOS_FILESYSTEM
+ int i;
+ char *actual_path;
+#endif
+ int real_path_len;
+
+ real_path = curl_easy_unescape(data, data->state.path, 0, &real_path_len);
+ if(!real_path)
+ return CURLE_OUT_OF_MEMORY;
+
+#ifdef DOS_FILESYSTEM
+ /* If the first character is a slash, and there's
+ something that looks like a drive at the beginning of
+ the path, skip the slash. If we remove the initial
+ slash in all cases, paths without drive letters end up
+ relative to the current directory which isn't how
+ browsers work.
+
+ Some browsers accept | instead of : as the drive letter
+ separator, so we do too.
+
+ On other platforms, we need the slash to indicate an
+ absolute pathname. On Windows, absolute paths start
+ with a drive letter.
+ */
+ actual_path = real_path;
+ if((actual_path[0] == '/') &&
+ actual_path[1] &&
+ (actual_path[2] == ':' || actual_path[2] == '|')) {
+ actual_path[2] = ':';
+ actual_path++;
+ real_path_len--;
+ }
+
+ /* change path separators from '/' to '\\' for DOS, Windows and OS/2 */
+ for(i=0; i < real_path_len; ++i)
+ if(actual_path[i] == '/')
+ actual_path[i] = '\\';
+ else if(!actual_path[i]) /* binary zero */
+ return CURLE_URL_MALFORMAT;
+
+ fd = open_readonly(actual_path, O_RDONLY|O_BINARY);
+ file->path = actual_path;
+#else
+ if(memchr(real_path, 0, real_path_len))
+ /* binary zeroes indicate foul play */
+ return CURLE_URL_MALFORMAT;
+
+ fd = open_readonly(real_path, O_RDONLY);
+ file->path = real_path;
+#endif
+ file->freepath = real_path; /* free this when done */
+
+ file->fd = fd;
+ if(!data->set.upload && (fd == -1)) {
+ failf(data, "Couldn't open file %s", data->state.path);
+ file_done(conn, CURLE_FILE_COULDNT_READ_FILE, FALSE);
+ return CURLE_FILE_COULDNT_READ_FILE;
+ }
+ *done = TRUE;
+
+ return CURLE_OK;
+}
+
+static CURLcode file_done(struct connectdata *conn,
+ CURLcode status, bool premature)
+{
+ struct FILEPROTO *file = conn->data->req.protop;
+ (void)status; /* not used */
+ (void)premature; /* not used */
+
+ if(file) {
+ Curl_safefree(file->freepath);
+ file->path = NULL;
+ if(file->fd != -1)
+ close(file->fd);
+ file->fd = -1;
+ }
+
+ return CURLE_OK;
+}
+
+static CURLcode file_disconnect(struct connectdata *conn,
+ bool dead_connection)
+{
+ struct FILEPROTO *file = conn->data->req.protop;
+ (void)dead_connection; /* not used */
+
+ if(file) {
+ Curl_safefree(file->freepath);
+ file->path = NULL;
+ if(file->fd != -1)
+ close(file->fd);
+ file->fd = -1;
+ }
+
+ return CURLE_OK;
+}
+
+#ifdef DOS_FILESYSTEM
+#define DIRSEP '\\'
+#else
+#define DIRSEP '/'
+#endif
+
+static CURLcode file_upload(struct connectdata *conn)
+{
+ struct FILEPROTO *file = conn->data->req.protop;
+ const char *dir = strchr(file->path, DIRSEP);
+ int fd;
+ int mode;
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ char *buf = data->state.buffer;
+ size_t nread;
+ size_t nwrite;
+ curl_off_t bytecount = 0;
+ struct timeval now = Curl_tvnow();
+ struct_stat file_stat;
+ const char* buf2;
+
+ /*
+ * Since FILE: doesn't do the full init, we need to provide some extra
+ * assignments here.
+ */
+ conn->data->req.upload_fromhere = buf;
+
+ if(!dir)
+ return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
+
+ if(!dir[1])
+ return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
+
+#ifdef O_BINARY
+#define MODE_DEFAULT O_WRONLY|O_CREAT|O_BINARY
+#else
+#define MODE_DEFAULT O_WRONLY|O_CREAT
+#endif
+
+ if(data->state.resume_from)
+ mode = MODE_DEFAULT|O_APPEND;
+ else
+ mode = MODE_DEFAULT|O_TRUNC;
+
+ fd = open(file->path, mode, conn->data->set.new_file_perms);
+ if(fd < 0) {
+ failf(data, "Can't open %s for writing", file->path);
+ return CURLE_WRITE_ERROR;
+ }
+
+ if(-1 != data->state.infilesize)
+ /* known size of data to "upload" */
+ Curl_pgrsSetUploadSize(data, data->state.infilesize);
+
+ /* treat the negative resume offset value as the case of "-" */
+ if(data->state.resume_from < 0) {
+ if(fstat(fd, &file_stat)) {
+ close(fd);
+ failf(data, "Can't get the size of %s", file->path);
+ return CURLE_WRITE_ERROR;
+ }
+ else
+ data->state.resume_from = (curl_off_t)file_stat.st_size;
+ }
+
+ while(!result) {
+ int readcount;
+ result = Curl_fillreadbuffer(conn, BUFSIZE, &readcount);
+ if(result)
+ break;
+
+ if(readcount <= 0) /* fix questionable compare error. curlvms */
+ break;
+
+ nread = (size_t)readcount;
+
+ /*skip bytes before resume point*/
+ if(data->state.resume_from) {
+ if((curl_off_t)nread <= data->state.resume_from ) {
+ data->state.resume_from -= nread;
+ nread = 0;
+ buf2 = buf;
+ }
+ else {
+ buf2 = buf + data->state.resume_from;
+ nread -= (size_t)data->state.resume_from;
+ data->state.resume_from = 0;
+ }
+ }
+ else
+ buf2 = buf;
+
+ /* write the data to the target */
+ nwrite = write(fd, buf2, nread);
+ if(nwrite != nread) {
+ result = CURLE_SEND_ERROR;
+ break;
+ }
+
+ bytecount += nread;
+
+ Curl_pgrsSetUploadCounter(data, bytecount);
+
+ if(Curl_pgrsUpdate(conn))
+ result = CURLE_ABORTED_BY_CALLBACK;
+ else
+ result = Curl_speedcheck(data, now);
+ }
+ if(!result && Curl_pgrsUpdate(conn))
+ result = CURLE_ABORTED_BY_CALLBACK;
+
+ close(fd);
+
+ return result;
+}
+
+/*
+ * file_do() is the protocol-specific function for the do-phase, separated
+ * from the connect-phase above. Other protocols merely setup the transfer in
+ * the do-phase, to have it done in the main transfer loop but since some
+ * platforms we support don't allow select()ing etc on file handles (as
+ * opposed to sockets) we instead perform the whole do-operation in this
+ * function.
+ */
+static CURLcode file_do(struct connectdata *conn, bool *done)
+{
+ /* This implementation ignores the host name in conformance with
+ RFC 1738. Only local files (reachable via the standard file system)
+ are supported. This means that files on remotely mounted directories
+ (via NFS, Samba, NT sharing) can be accessed through a file:// URL
+ */
+ CURLcode result = CURLE_OK;
+ struct_stat statbuf; /* struct_stat instead of struct stat just to allow the
+ Windows version to have a different struct without
+ having to redefine the simple word 'stat' */
+ curl_off_t expected_size=0;
+ bool fstated=FALSE;
+ ssize_t nread;
+ struct SessionHandle *data = conn->data;
+ char *buf = data->state.buffer;
+ curl_off_t bytecount = 0;
+ int fd;
+ struct timeval now = Curl_tvnow();
+ struct FILEPROTO *file;
+
+ *done = TRUE; /* unconditionally */
+
+ Curl_initinfo(data);
+ Curl_pgrsStartNow(data);
+
+ if(data->set.upload)
+ return file_upload(conn);
+
+ file = conn->data->req.protop;
+
+ /* get the fd from the connection phase */
+ fd = file->fd;
+
+ /* VMS: This only works reliable for STREAMLF files */
+ if(-1 != fstat(fd, &statbuf)) {
+ /* we could stat it, then read out the size */
+ expected_size = statbuf.st_size;
+ /* and store the modification time */
+ data->info.filetime = (long)statbuf.st_mtime;
+ fstated = TRUE;
+ }
+
+ if(fstated && !data->state.range && data->set.timecondition) {
+ if(!Curl_meets_timecondition(data, (time_t)data->info.filetime)) {
+ *done = TRUE;
+ return CURLE_OK;
+ }
+ }
+
+ /* If we have selected NOBODY and HEADER, it means that we only want file
+ information. Which for FILE can't be much more than the file size and
+ date. */
+ if(data->set.opt_no_body && data->set.include_header && fstated) {
+ snprintf(buf, sizeof(data->state.buffer),
+ "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", expected_size);
+ result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
+ if(result)
+ return result;
+
+ result = Curl_client_write(conn, CLIENTWRITE_BOTH,
+ (char *)"Accept-ranges: bytes\r\n", 0);
+ if(result)
+ return result;
+
+ if(fstated) {
+ time_t filetime = (time_t)statbuf.st_mtime;
+ struct tm buffer;
+ const struct tm *tm = &buffer;
+ result = Curl_gmtime(filetime, &buffer);
+ if(result)
+ return result;
+
+ /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
+ snprintf(buf, BUFSIZE-1,
+ "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
+ Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
+ tm->tm_mday,
+ Curl_month[tm->tm_mon],
+ tm->tm_year + 1900,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec);
+ result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
+ }
+ /* if we fstat()ed the file, set the file size to make it available post-
+ transfer */
+ if(fstated)
+ Curl_pgrsSetDownloadSize(data, expected_size);
+ return result;
+ }
+
+ /* Check whether file range has been specified */
+ file_range(conn);
+
+ /* Adjust the start offset in case we want to get the N last bytes
+ * of the stream iff the filesize could be determined */
+ if(data->state.resume_from < 0) {
+ if(!fstated) {
+ failf(data, "Can't get the size of file.");
+ return CURLE_READ_ERROR;
+ }
+ else
+ data->state.resume_from += (curl_off_t)statbuf.st_size;
+ }
+
+ if(data->state.resume_from <= expected_size)
+ expected_size -= data->state.resume_from;
+ else {
+ failf(data, "failed to resume file:// transfer");
+ return CURLE_BAD_DOWNLOAD_RESUME;
+ }
+
+ /* A high water mark has been specified so we obey... */
+ if(data->req.maxdownload > 0)
+ expected_size = data->req.maxdownload;
+
+ if(fstated && (expected_size == 0))
+ return CURLE_OK;
+
+ /* The following is a shortcut implementation of file reading
+ this is both more efficient than the former call to download() and
+ it avoids problems with select() and recv() on file descriptors
+ in Winsock */
+ if(fstated)
+ Curl_pgrsSetDownloadSize(data, expected_size);
+
+ if(data->state.resume_from) {
+ if(data->state.resume_from !=
+ lseek(fd, data->state.resume_from, SEEK_SET))
+ return CURLE_BAD_DOWNLOAD_RESUME;
+ }
+
+ Curl_pgrsTime(data, TIMER_STARTTRANSFER);
+
+ while(!result) {
+ /* Don't fill a whole buffer if we want less than all data */
+ size_t bytestoread =
+ (expected_size < CURL_OFF_T_C(BUFSIZE) - CURL_OFF_T_C(1)) ?
+ curlx_sotouz(expected_size) : BUFSIZE - 1;
+
+ nread = read(fd, buf, bytestoread);
+
+ if(nread > 0)
+ buf[nread] = 0;
+
+ if(nread <= 0 || expected_size == 0)
+ break;
+
+ bytecount += nread;
+ expected_size -= nread;
+
+ result = Curl_client_write(conn, CLIENTWRITE_BODY, buf, nread);
+ if(result)
+ return result;
+
+ Curl_pgrsSetDownloadCounter(data, bytecount);
+
+ if(Curl_pgrsUpdate(conn))
+ result = CURLE_ABORTED_BY_CALLBACK;
+ else
+ result = Curl_speedcheck(data, now);
+ }
+ if(Curl_pgrsUpdate(conn))
+ result = CURLE_ABORTED_BY_CALLBACK;
+
+ return result;
+}
+
+#endif
diff --git a/Utilities/cmcurl/lib/file.h b/Utilities/cmcurl/lib/file.h
new file mode 100644
index 000000000..997474bc7
--- /dev/null
+++ b/Utilities/cmcurl/lib/file.h
@@ -0,0 +1,41 @@
+#ifndef HEADER_CURL_FILE_H
+#define HEADER_CURL_FILE_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+
+/****************************************************************************
+ * FILE unique setup
+ ***************************************************************************/
+struct FILEPROTO {
+ char *path; /* the path we operate on */
+ char *freepath; /* pointer to the allocated block we must free, this might
+ differ from the 'path' pointer */
+ int fd; /* open file descriptor to read from! */
+};
+
+#ifndef CURL_DISABLE_FILE
+extern const struct Curl_handler Curl_handler_file;
+#endif
+
+#endif /* HEADER_CURL_FILE_H */
+
diff --git a/Utilities/cmcurl/lib/fileinfo.c b/Utilities/cmcurl/lib/fileinfo.c
new file mode 100644
index 000000000..0904937aa
--- /dev/null
+++ b/Utilities/cmcurl/lib/fileinfo.c
@@ -0,0 +1,50 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2010 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "strdup.h"
+#include "fileinfo.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+struct curl_fileinfo *Curl_fileinfo_alloc(void)
+{
+ struct curl_fileinfo *tmp = malloc(sizeof(struct curl_fileinfo));
+ if(!tmp)
+ return NULL;
+ memset(tmp, 0, sizeof(struct curl_fileinfo));
+ return tmp;
+}
+
+void Curl_fileinfo_dtor(void *user, void *element)
+{
+ struct curl_fileinfo *finfo = element;
+ (void) user;
+ if(!finfo)
+ return;
+
+ Curl_safefree(finfo->b_data);
+
+ free(finfo);
+}
diff --git a/Utilities/cmcurl/lib/fileinfo.h b/Utilities/cmcurl/lib/fileinfo.h
new file mode 100644
index 000000000..b0e5e59e1
--- /dev/null
+++ b/Utilities/cmcurl/lib/fileinfo.h
@@ -0,0 +1,33 @@
+#ifndef HEADER_CURL_FILEINFO_H
+#define HEADER_CURL_FILEINFO_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <curl/curl.h>
+
+struct curl_fileinfo *Curl_fileinfo_alloc(void);
+
+void Curl_fileinfo_dtor(void *, void *);
+
+struct curl_fileinfo *Curl_fileinfo_dup(const struct curl_fileinfo *src);
+
+#endif /* HEADER_CURL_FILEINFO_H */
diff --git a/Utilities/cmcurl/lib/formdata.c b/Utilities/cmcurl/lib/formdata.c
new file mode 100644
index 000000000..9e8ce4ea0
--- /dev/null
+++ b/Utilities/cmcurl/lib/formdata.c
@@ -0,0 +1,1551 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#ifndef CURL_DISABLE_HTTP
+
+#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
+#include <libgen.h>
+#endif
+
+#include "urldata.h" /* for struct SessionHandle */
+#include "formdata.h"
+#include "vtls/vtls.h"
+#include "strequal.h"
+#include "sendf.h"
+#include "strdup.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#ifndef HAVE_BASENAME
+static char *Curl_basename(char *path);
+#define basename(x) Curl_basename((x))
+#endif
+
+static size_t readfromfile(struct Form *form, char *buffer, size_t size);
+static char *formboundary(struct SessionHandle *data);
+
+/* What kind of Content-Type to use on un-specified files with unrecognized
+ extensions. */
+#define HTTPPOST_CONTENTTYPE_DEFAULT "application/octet-stream"
+
+#define FORM_FILE_SEPARATOR ','
+#define FORM_TYPE_SEPARATOR ';'
+
+/***************************************************************************
+ *
+ * AddHttpPost()
+ *
+ * Adds a HttpPost structure to the list, if parent_post is given becomes
+ * a subpost of parent_post instead of a direct list element.
+ *
+ * Returns newly allocated HttpPost on success and NULL if malloc failed.
+ *
+ ***************************************************************************/
+static struct curl_httppost *
+AddHttpPost(char *name, size_t namelength,
+ char *value, size_t contentslength,
+ char *buffer, size_t bufferlength,
+ char *contenttype,
+ long flags,
+ struct curl_slist* contentHeader,
+ char *showfilename, char *userp,
+ struct curl_httppost *parent_post,
+ struct curl_httppost **httppost,
+ struct curl_httppost **last_post)
+{
+ struct curl_httppost *post;
+ post = calloc(1, sizeof(struct curl_httppost));
+ if(post) {
+ post->name = name;
+ post->namelength = (long)(name?(namelength?namelength:strlen(name)):0);
+ post->contents = value;
+ post->contentslength = (long)contentslength;
+ post->buffer = buffer;
+ post->bufferlength = (long)bufferlength;
+ post->contenttype = contenttype;
+ post->contentheader = contentHeader;
+ post->showfilename = showfilename;
+ post->userp = userp,
+ post->flags = flags;
+ }
+ else
+ return NULL;
+
+ if(parent_post) {
+ /* now, point our 'more' to the original 'more' */
+ post->more = parent_post->more;
+
+ /* then move the original 'more' to point to ourselves */
+ parent_post->more = post;
+ }
+ else {
+ /* make the previous point to this */
+ if(*last_post)
+ (*last_post)->next = post;
+ else
+ (*httppost) = post;
+
+ (*last_post) = post;
+ }
+ return post;
+}
+
+/***************************************************************************
+ *
+ * AddFormInfo()
+ *
+ * Adds a FormInfo structure to the list presented by parent_form_info.
+ *
+ * Returns newly allocated FormInfo on success and NULL if malloc failed/
+ * parent_form_info is NULL.
+ *
+ ***************************************************************************/
+static FormInfo * AddFormInfo(char *value,
+ char *contenttype,
+ FormInfo *parent_form_info)
+{
+ FormInfo *form_info;
+ form_info = calloc(1, sizeof(struct FormInfo));
+ if(form_info) {
+ if(value)
+ form_info->value = value;
+ if(contenttype)
+ form_info->contenttype = contenttype;
+ form_info->flags = HTTPPOST_FILENAME;
+ }
+ else
+ return NULL;
+
+ if(parent_form_info) {
+ /* now, point our 'more' to the original 'more' */
+ form_info->more = parent_form_info->more;
+
+ /* then move the original 'more' to point to ourselves */
+ parent_form_info->more = form_info;
+ }
+
+ return form_info;
+}
+
+/***************************************************************************
+ *
+ * ContentTypeForFilename()
+ *
+ * Provides content type for filename if one of the known types (else
+ * (either the prevtype or the default is returned).
+ *
+ * Returns some valid contenttype for filename.
+ *
+ ***************************************************************************/
+static const char *ContentTypeForFilename(const char *filename,
+ const char *prevtype)
+{
+ const char *contenttype = NULL;
+ unsigned int i;
+ /*
+ * No type was specified, we scan through a few well-known
+ * extensions and pick the first we match!
+ */
+ struct ContentType {
+ const char *extension;
+ const char *type;
+ };
+ static const struct ContentType ctts[]={
+ {".gif", "image/gif"},
+ {".jpg", "image/jpeg"},
+ {".jpeg", "image/jpeg"},
+ {".txt", "text/plain"},
+ {".html", "text/html"},
+ {".xml", "application/xml"}
+ };
+
+ if(prevtype)
+ /* default to the previously set/used! */
+ contenttype = prevtype;
+ else
+ contenttype = HTTPPOST_CONTENTTYPE_DEFAULT;
+
+ if(filename) { /* in case a NULL was passed in */
+ for(i=0; i<sizeof(ctts)/sizeof(ctts[0]); i++) {
+ if(strlen(filename) >= strlen(ctts[i].extension)) {
+ if(strequal(filename +
+ strlen(filename) - strlen(ctts[i].extension),
+ ctts[i].extension)) {
+ contenttype = ctts[i].type;
+ break;
+ }
+ }
+ }
+ }
+ /* we have a contenttype by now */
+ return contenttype;
+}
+
+/***************************************************************************
+ *
+ * FormAdd()
+ *
+ * Stores a formpost parameter and builds the appropriate linked list.
+ *
+ * Has two principal functionalities: using files and byte arrays as
+ * post parts. Byte arrays are either copied or just the pointer is stored
+ * (as the user requests) while for files only the filename and not the
+ * content is stored.
+ *
+ * While you may have only one byte array for each name, multiple filenames
+ * are allowed (and because of this feature CURLFORM_END is needed after
+ * using CURLFORM_FILE).
+ *
+ * Examples:
+ *
+ * Simple name/value pair with copied contents:
+ * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
+ * CURLFORM_COPYCONTENTS, "value", CURLFORM_END);
+ *
+ * name/value pair where only the content pointer is remembered:
+ * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
+ * CURLFORM_PTRCONTENTS, ptr, CURLFORM_CONTENTSLENGTH, 10, CURLFORM_END);
+ * (if CURLFORM_CONTENTSLENGTH is missing strlen () is used)
+ *
+ * storing a filename (CONTENTTYPE is optional!):
+ * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
+ * CURLFORM_FILE, "filename1", CURLFORM_CONTENTTYPE, "plain/text",
+ * CURLFORM_END);
+ *
+ * storing multiple filenames:
+ * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
+ * CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", CURLFORM_END);
+ *
+ * Returns:
+ * CURL_FORMADD_OK on success
+ * CURL_FORMADD_MEMORY if the FormInfo allocation fails
+ * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form
+ * CURL_FORMADD_NULL if a null pointer was given for a char
+ * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed
+ * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
+ * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error)
+ * CURL_FORMADD_MEMORY if a HttpPost struct cannot be allocated
+ * CURL_FORMADD_MEMORY if some allocation for string copying failed.
+ * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array
+ *
+ ***************************************************************************/
+
+static
+CURLFORMcode FormAdd(struct curl_httppost **httppost,
+ struct curl_httppost **last_post,
+ va_list params)
+{
+ FormInfo *first_form, *current_form, *form = NULL;
+ CURLFORMcode return_value = CURL_FORMADD_OK;
+ const char *prevtype = NULL;
+ struct curl_httppost *post = NULL;
+ CURLformoption option;
+ struct curl_forms *forms = NULL;
+ char *array_value=NULL; /* value read from an array */
+
+ /* This is a state variable, that if TRUE means that we're parsing an
+ array that we got passed to us. If FALSE we're parsing the input
+ va_list arguments. */
+ bool array_state = FALSE;
+
+ /*
+ * We need to allocate the first struct to fill in.
+ */
+ first_form = calloc(1, sizeof(struct FormInfo));
+ if(!first_form)
+ return CURL_FORMADD_MEMORY;
+
+ current_form = first_form;
+
+ /*
+ * Loop through all the options set. Break if we have an error to report.
+ */
+ while(return_value == CURL_FORMADD_OK) {
+
+ /* first see if we have more parts of the array param */
+ if(array_state && forms) {
+ /* get the upcoming option from the given array */
+ option = forms->option;
+ array_value = (char *)forms->value;
+
+ forms++; /* advance this to next entry */
+ if(CURLFORM_END == option) {
+ /* end of array state */
+ array_state = FALSE;
+ continue;
+ }
+ }
+ else {
+ /* This is not array-state, get next option */
+ option = va_arg(params, CURLformoption);
+ if(CURLFORM_END == option)
+ break;
+ }
+
+ switch (option) {
+ case CURLFORM_ARRAY:
+ if(array_state)
+ /* we don't support an array from within an array */
+ return_value = CURL_FORMADD_ILLEGAL_ARRAY;
+ else {
+ forms = va_arg(params, struct curl_forms *);
+ if(forms)
+ array_state = TRUE;
+ else
+ return_value = CURL_FORMADD_NULL;
+ }
+ break;
+
+ /*
+ * Set the Name property.
+ */
+ case CURLFORM_PTRNAME:
+#ifdef CURL_DOES_CONVERSIONS
+ /* Treat CURLFORM_PTR like CURLFORM_COPYNAME so that libcurl will copy
+ * the data in all cases so that we'll have safe memory for the eventual
+ * conversion.
+ */
+#else
+ current_form->flags |= HTTPPOST_PTRNAME; /* fall through */
+#endif
+ case CURLFORM_COPYNAME:
+ if(current_form->name)
+ return_value = CURL_FORMADD_OPTION_TWICE;
+ else {
+ char *name = array_state?
+ array_value:va_arg(params, char *);
+ if(name)
+ current_form->name = name; /* store for the moment */
+ else
+ return_value = CURL_FORMADD_NULL;
+ }
+ break;
+ case CURLFORM_NAMELENGTH:
+ if(current_form->namelength)
+ return_value = CURL_FORMADD_OPTION_TWICE;
+ else
+ current_form->namelength =
+ array_state?(size_t)array_value:(size_t)va_arg(params, long);
+ break;
+
+ /*
+ * Set the contents property.
+ */
+ case CURLFORM_PTRCONTENTS:
+ current_form->flags |= HTTPPOST_PTRCONTENTS; /* fall through */
+ case CURLFORM_COPYCONTENTS:
+ if(current_form->value)
+ return_value = CURL_FORMADD_OPTION_TWICE;
+ else {
+ char *value =
+ array_state?array_value:va_arg(params, char *);
+ if(value)
+ current_form->value = value; /* store for the moment */
+ else
+ return_value = CURL_FORMADD_NULL;
+ }
+ break;
+ case CURLFORM_CONTENTSLENGTH:
+ if(current_form->contentslength)
+ return_value = CURL_FORMADD_OPTION_TWICE;
+ else
+ current_form->contentslength =
+ array_state?(size_t)array_value:(size_t)va_arg(params, long);
+ break;
+
+ /* Get contents from a given file name */
+ case CURLFORM_FILECONTENT:
+ if(current_form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_READFILE))
+ return_value = CURL_FORMADD_OPTION_TWICE;
+ else {
+ const char *filename = array_state?
+ array_value:va_arg(params, char *);
+ if(filename) {
+ current_form->value = strdup(filename);
+ if(!current_form->value)
+ return_value = CURL_FORMADD_MEMORY;
+ else {
+ current_form->flags |= HTTPPOST_READFILE;
+ current_form->value_alloc = TRUE;
+ }
+ }
+ else
+ return_value = CURL_FORMADD_NULL;
+ }
+ break;
+
+ /* We upload a file */
+ case CURLFORM_FILE:
+ {
+ const char *filename = array_state?array_value:
+ va_arg(params, char *);
+
+ if(current_form->value) {
+ if(current_form->flags & HTTPPOST_FILENAME) {
+ if(filename) {
+ char *fname = strdup(filename);
+ if(!fname)
+ return_value = CURL_FORMADD_MEMORY;
+ else {
+ form = AddFormInfo(fname, NULL, current_form);
+ if(!form) {
+ free(fname);
+ return_value = CURL_FORMADD_MEMORY;
+ }
+ else {
+ form->value_alloc = TRUE;
+ current_form = form;
+ form = NULL;
+ }
+ }
+ }
+ else
+ return_value = CURL_FORMADD_NULL;
+ }
+ else
+ return_value = CURL_FORMADD_OPTION_TWICE;
+ }
+ else {
+ if(filename) {
+ current_form->value = strdup(filename);
+ if(!current_form->value)
+ return_value = CURL_FORMADD_MEMORY;
+ else {
+ current_form->flags |= HTTPPOST_FILENAME;
+ current_form->value_alloc = TRUE;
+ }
+ }
+ else
+ return_value = CURL_FORMADD_NULL;
+ }
+ break;
+ }
+
+ case CURLFORM_BUFFERPTR:
+ current_form->flags |= HTTPPOST_PTRBUFFER|HTTPPOST_BUFFER;
+ if(current_form->buffer)
+ return_value = CURL_FORMADD_OPTION_TWICE;
+ else {
+ char *buffer =
+ array_state?array_value:va_arg(params, char *);
+ if(buffer) {
+ current_form->buffer = buffer; /* store for the moment */
+ current_form->value = buffer; /* make it non-NULL to be accepted
+ as fine */
+ }
+ else
+ return_value = CURL_FORMADD_NULL;
+ }
+ break;
+
+ case CURLFORM_BUFFERLENGTH:
+ if(current_form->bufferlength)
+ return_value = CURL_FORMADD_OPTION_TWICE;
+ else
+ current_form->bufferlength =
+ array_state?(size_t)array_value:(size_t)va_arg(params, long);
+ break;
+
+ case CURLFORM_STREAM:
+ current_form->flags |= HTTPPOST_CALLBACK;
+ if(current_form->userp)
+ return_value = CURL_FORMADD_OPTION_TWICE;
+ else {
+ char *userp =
+ array_state?array_value:va_arg(params, char *);
+ if(userp) {
+ current_form->userp = userp;
+ current_form->value = userp; /* this isn't strictly true but we
+ derive a value from this later on
+ and we need this non-NULL to be
+ accepted as a fine form part */
+ }
+ else
+ return_value = CURL_FORMADD_NULL;
+ }
+ break;
+
+ case CURLFORM_CONTENTTYPE:
+ {
+ const char *contenttype =
+ array_state?array_value:va_arg(params, char *);
+ if(current_form->contenttype) {
+ if(current_form->flags & HTTPPOST_FILENAME) {
+ if(contenttype) {
+ char *type = strdup(contenttype);
+ if(!type)
+ return_value = CURL_FORMADD_MEMORY;
+ else {
+ form = AddFormInfo(NULL, type, current_form);
+ if(!form) {
+ free(type);
+ return_value = CURL_FORMADD_MEMORY;
+ }
+ else {
+ form->contenttype_alloc = TRUE;
+ current_form = form;
+ form = NULL;
+ }
+ }
+ }
+ else
+ return_value = CURL_FORMADD_NULL;
+ }
+ else
+ return_value = CURL_FORMADD_OPTION_TWICE;
+ }
+ else {
+ if(contenttype) {
+ current_form->contenttype = strdup(contenttype);
+ if(!current_form->contenttype)
+ return_value = CURL_FORMADD_MEMORY;
+ else
+ current_form->contenttype_alloc = TRUE;
+ }
+ else
+ return_value = CURL_FORMADD_NULL;
+ }
+ break;
+ }
+ case CURLFORM_CONTENTHEADER:
+ {
+ /* this "cast increases required alignment of target type" but
+ we consider it OK anyway */
+ struct curl_slist* list = array_state?
+ (struct curl_slist*)array_value:
+ va_arg(params, struct curl_slist*);
+
+ if(current_form->contentheader)
+ return_value = CURL_FORMADD_OPTION_TWICE;
+ else
+ current_form->contentheader = list;
+
+ break;
+ }
+ case CURLFORM_FILENAME:
+ case CURLFORM_BUFFER:
+ {
+ const char *filename = array_state?array_value:
+ va_arg(params, char *);
+ if(current_form->showfilename)
+ return_value = CURL_FORMADD_OPTION_TWICE;
+ else {
+ current_form->showfilename = strdup(filename);
+ if(!current_form->showfilename)
+ return_value = CURL_FORMADD_MEMORY;
+ else
+ current_form->showfilename_alloc = TRUE;
+ }
+ break;
+ }
+ default:
+ return_value = CURL_FORMADD_UNKNOWN_OPTION;
+ break;
+ }
+ }
+
+ if(CURL_FORMADD_OK != return_value) {
+ /* On error, free allocated fields for all nodes of the FormInfo linked
+ list without deallocating nodes. List nodes are deallocated later on */
+ FormInfo *ptr;
+ for(ptr = first_form; ptr != NULL; ptr = ptr->more) {
+ if(ptr->name_alloc) {
+ Curl_safefree(ptr->name);
+ ptr->name_alloc = FALSE;
+ }
+ if(ptr->value_alloc) {
+ Curl_safefree(ptr->value);
+ ptr->value_alloc = FALSE;
+ }
+ if(ptr->contenttype_alloc) {
+ Curl_safefree(ptr->contenttype);
+ ptr->contenttype_alloc = FALSE;
+ }
+ if(ptr->showfilename_alloc) {
+ Curl_safefree(ptr->showfilename);
+ ptr->showfilename_alloc = FALSE;
+ }
+ }
+ }
+
+ if(CURL_FORMADD_OK == return_value) {
+ /* go through the list, check for completeness and if everything is
+ * alright add the HttpPost item otherwise set return_value accordingly */
+
+ post = NULL;
+ for(form = first_form;
+ form != NULL;
+ form = form->more) {
+ if(((!form->name || !form->value) && !post) ||
+ ( (form->contentslength) &&
+ (form->flags & HTTPPOST_FILENAME) ) ||
+ ( (form->flags & HTTPPOST_FILENAME) &&
+ (form->flags & HTTPPOST_PTRCONTENTS) ) ||
+
+ ( (!form->buffer) &&
+ (form->flags & HTTPPOST_BUFFER) &&
+ (form->flags & HTTPPOST_PTRBUFFER) ) ||
+
+ ( (form->flags & HTTPPOST_READFILE) &&
+ (form->flags & HTTPPOST_PTRCONTENTS) )
+ ) {
+ return_value = CURL_FORMADD_INCOMPLETE;
+ break;
+ }
+ else {
+ if(((form->flags & HTTPPOST_FILENAME) ||
+ (form->flags & HTTPPOST_BUFFER)) &&
+ !form->contenttype ) {
+ char *f = form->flags & HTTPPOST_BUFFER?
+ form->showfilename : form->value;
+
+ /* our contenttype is missing */
+ form->contenttype = strdup(ContentTypeForFilename(f, prevtype));
+ if(!form->contenttype) {
+ return_value = CURL_FORMADD_MEMORY;
+ break;
+ }
+ form->contenttype_alloc = TRUE;
+ }
+ if(!(form->flags & HTTPPOST_PTRNAME) &&
+ (form == first_form) ) {
+ /* Note that there's small risk that form->name is NULL here if the
+ app passed in a bad combo, so we better check for that first. */
+ if(form->name) {
+ /* copy name (without strdup; possibly contains null characters) */
+ form->name = Curl_memdup(form->name, form->namelength?
+ form->namelength:
+ strlen(form->name)+1);
+ }
+ if(!form->name) {
+ return_value = CURL_FORMADD_MEMORY;
+ break;
+ }
+ form->name_alloc = TRUE;
+ }
+ if(!(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE |
+ HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
+ HTTPPOST_CALLBACK)) && form->value) {
+ /* copy value (without strdup; possibly contains null characters) */
+ form->value = Curl_memdup(form->value, form->contentslength?
+ form->contentslength:
+ strlen(form->value)+1);
+ if(!form->value) {
+ return_value = CURL_FORMADD_MEMORY;
+ break;
+ }
+ form->value_alloc = TRUE;
+ }
+ post = AddHttpPost(form->name, form->namelength,
+ form->value, form->contentslength,
+ form->buffer, form->bufferlength,
+ form->contenttype, form->flags,
+ form->contentheader, form->showfilename,
+ form->userp,
+ post, httppost,
+ last_post);
+
+ if(!post) {
+ return_value = CURL_FORMADD_MEMORY;
+ break;
+ }
+
+ if(form->contenttype)
+ prevtype = form->contenttype;
+ }
+ }
+ if(CURL_FORMADD_OK != return_value) {
+ /* On error, free allocated fields for nodes of the FormInfo linked
+ list which are not already owned by the httppost linked list
+ without deallocating nodes. List nodes are deallocated later on */
+ FormInfo *ptr;
+ for(ptr = form; ptr != NULL; ptr = ptr->more) {
+ if(ptr->name_alloc) {
+ Curl_safefree(ptr->name);
+ ptr->name_alloc = FALSE;
+ }
+ if(ptr->value_alloc) {
+ Curl_safefree(ptr->value);
+ ptr->value_alloc = FALSE;
+ }
+ if(ptr->contenttype_alloc) {
+ Curl_safefree(ptr->contenttype);
+ ptr->contenttype_alloc = FALSE;
+ }
+ if(ptr->showfilename_alloc) {
+ Curl_safefree(ptr->showfilename);
+ ptr->showfilename_alloc = FALSE;
+ }
+ }
+ }
+ }
+
+ /* Always deallocate FormInfo linked list nodes without touching node
+ fields given that these have either been deallocated or are owned
+ now by the httppost linked list */
+ while(first_form) {
+ FormInfo *ptr = first_form->more;
+ free(first_form);
+ first_form = ptr;
+ }
+
+ return return_value;
+}
+
+/*
+ * curl_formadd() is a public API to add a section to the multipart formpost.
+ *
+ * @unittest: 1308
+ */
+
+CURLFORMcode curl_formadd(struct curl_httppost **httppost,
+ struct curl_httppost **last_post,
+ ...)
+{
+ va_list arg;
+ CURLFORMcode result;
+ va_start(arg, last_post);
+ result = FormAdd(httppost, last_post, arg);
+ va_end(arg);
+ return result;
+}
+
+#ifdef __VMS
+#include <fabdef.h>
+/*
+ * get_vms_file_size does what it takes to get the real size of the file
+ *
+ * For fixed files, find out the size of the EOF block and adjust.
+ *
+ * For all others, have to read the entire file in, discarding the contents.
+ * Most posted text files will be small, and binary files like zlib archives
+ * and CD/DVD images should be either a STREAM_LF format or a fixed format.
+ *
+ */
+curl_off_t VmsRealFileSize(const char * name,
+ const struct_stat * stat_buf)
+{
+ char buffer[8192];
+ curl_off_t count;
+ int ret_stat;
+ FILE * file;
+
+ file = fopen(name, "r"); /* VMS */
+ if(file == NULL)
+ return 0;
+
+ count = 0;
+ ret_stat = 1;
+ while(ret_stat > 0) {
+ ret_stat = fread(buffer, 1, sizeof(buffer), file);
+ if(ret_stat != 0)
+ count += ret_stat;
+ }
+ fclose(file);
+
+ return count;
+}
+
+/*
+ *
+ * VmsSpecialSize checks to see if the stat st_size can be trusted and
+ * if not to call a routine to get the correct size.
+ *
+ */
+static curl_off_t VmsSpecialSize(const char * name,
+ const struct_stat * stat_buf)
+{
+ switch(stat_buf->st_fab_rfm) {
+ case FAB$C_VAR:
+ case FAB$C_VFC:
+ return VmsRealFileSize(name, stat_buf);
+ break;
+ default:
+ return stat_buf->st_size;
+ }
+}
+
+#endif
+
+#ifndef __VMS
+#define filesize(name, stat_data) (stat_data.st_size)
+#else
+ /* Getting the expected file size needs help on VMS */
+#define filesize(name, stat_data) VmsSpecialSize(name, &stat_data)
+#endif
+
+/*
+ * AddFormData() adds a chunk of data to the FormData linked list.
+ *
+ * size is incremented by the chunk length, unless it is NULL
+ */
+static CURLcode AddFormData(struct FormData **formp,
+ enum formtype type,
+ const void *line,
+ size_t length,
+ curl_off_t *size)
+{
+ struct FormData *newform = malloc(sizeof(struct FormData));
+ if(!newform)
+ return CURLE_OUT_OF_MEMORY;
+ newform->next = NULL;
+
+ if(type <= FORM_CONTENT) {
+ /* we make it easier for plain strings: */
+ if(!length)
+ length = strlen((char *)line);
+
+ newform->line = malloc(length+1);
+ if(!newform->line) {
+ free(newform);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ memcpy(newform->line, line, length);
+ newform->length = length;
+ newform->line[length]=0; /* zero terminate for easier debugging */
+ }
+ else
+ /* For callbacks and files we don't have any actual data so we just keep a
+ pointer to whatever this points to */
+ newform->line = (char *)line;
+
+ newform->type = type;
+
+ if(*formp) {
+ (*formp)->next = newform;
+ *formp = newform;
+ }
+ else
+ *formp = newform;
+
+ if(size) {
+ if(type != FORM_FILE)
+ /* for static content as well as callback data we add the size given
+ as input argument */
+ *size += length;
+ else {
+ /* Since this is a file to be uploaded here, add the size of the actual
+ file */
+ if(!strequal("-", newform->line)) {
+ struct_stat file;
+ if(!stat(newform->line, &file) && !S_ISDIR(file.st_mode))
+ *size += filesize(newform->line, file);
+ else
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+ }
+ }
+ return CURLE_OK;
+}
+
+/*
+ * AddFormDataf() adds printf()-style formatted data to the formdata chain.
+ */
+
+static CURLcode AddFormDataf(struct FormData **formp,
+ curl_off_t *size,
+ const char *fmt, ...)
+{
+ char s[4096];
+ va_list ap;
+ va_start(ap, fmt);
+ vsnprintf(s, sizeof(s), fmt, ap);
+ va_end(ap);
+
+ return AddFormData(formp, FORM_DATA, s, 0, size);
+}
+
+/*
+ * Curl_formclean() is used from http.c, this cleans a built FormData linked
+ * list
+ */
+void Curl_formclean(struct FormData **form_ptr)
+{
+ struct FormData *next, *form;
+
+ form = *form_ptr;
+ if(!form)
+ return;
+
+ do {
+ next=form->next; /* the following form line */
+ if(form->type <= FORM_CONTENT)
+ free(form->line); /* free the line */
+ free(form); /* free the struct */
+
+ } while((form = next) != NULL); /* continue */
+
+ *form_ptr = NULL;
+}
+
+/*
+ * curl_formget()
+ * Serialize a curl_httppost struct.
+ * Returns 0 on success.
+ *
+ * @unittest: 1308
+ */
+int curl_formget(struct curl_httppost *form, void *arg,
+ curl_formget_callback append)
+{
+ CURLcode result;
+ curl_off_t size;
+ struct FormData *data, *ptr;
+
+ result = Curl_getformdata(NULL, &data, form, NULL, &size);
+ if(result)
+ return (int)result;
+
+ for(ptr = data; ptr; ptr = ptr->next) {
+ if((ptr->type == FORM_FILE) || (ptr->type == FORM_CALLBACK)) {
+ char buffer[8192];
+ size_t nread;
+ struct Form temp;
+
+ Curl_FormInit(&temp, ptr);
+
+ do {
+ nread = readfromfile(&temp, buffer, sizeof(buffer));
+ if((nread == (size_t) -1) ||
+ (nread > sizeof(buffer)) ||
+ (nread != append(arg, buffer, nread))) {
+ if(temp.fp)
+ fclose(temp.fp);
+ Curl_formclean(&data);
+ return -1;
+ }
+ } while(nread);
+ }
+ else {
+ if(ptr->length != append(arg, ptr->line, ptr->length)) {
+ Curl_formclean(&data);
+ return -1;
+ }
+ }
+ }
+ Curl_formclean(&data);
+ return 0;
+}
+
+/*
+ * curl_formfree() is an external function to free up a whole form post
+ * chain
+ */
+void curl_formfree(struct curl_httppost *form)
+{
+ struct curl_httppost *next;
+
+ if(!form)
+ /* no form to free, just get out of this */
+ return;
+
+ do {
+ next=form->next; /* the following form line */
+
+ /* recurse to sub-contents */
+ curl_formfree(form->more);
+
+ if(!(form->flags & HTTPPOST_PTRNAME))
+ free(form->name); /* free the name */
+ if(!(form->flags &
+ (HTTPPOST_PTRCONTENTS|HTTPPOST_BUFFER|HTTPPOST_CALLBACK))
+ )
+ free(form->contents); /* free the contents */
+ free(form->contenttype); /* free the content type */
+ free(form->showfilename); /* free the faked file name */
+ free(form); /* free the struct */
+
+ } while((form = next) != NULL); /* continue */
+}
+
+#ifndef HAVE_BASENAME
+/*
+ (Quote from The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004
+ Edition)
+
+ The basename() function shall take the pathname pointed to by path and
+ return a pointer to the final component of the pathname, deleting any
+ trailing '/' characters.
+
+ If the string pointed to by path consists entirely of the '/' character,
+ basename() shall return a pointer to the string "/". If the string pointed
+ to by path is exactly "//", it is implementation-defined whether '/' or "//"
+ is returned.
+
+ If path is a null pointer or points to an empty string, basename() shall
+ return a pointer to the string ".".
+
+ The basename() function may modify the string pointed to by path, and may
+ return a pointer to static storage that may then be overwritten by a
+ subsequent call to basename().
+
+ The basename() function need not be reentrant. A function that is not
+ required to be reentrant is not required to be thread-safe.
+
+*/
+static char *Curl_basename(char *path)
+{
+ /* Ignore all the details above for now and make a quick and simple
+ implementaion here */
+ char *s1;
+ char *s2;
+
+ s1=strrchr(path, '/');
+ s2=strrchr(path, '\\');
+
+ if(s1 && s2) {
+ path = (s1 > s2? s1 : s2)+1;
+ }
+ else if(s1)
+ path = s1 + 1;
+ else if(s2)
+ path = s2 + 1;
+
+ return path;
+}
+#endif
+
+static char *strippath(const char *fullfile)
+{
+ char *filename;
+ char *base;
+ filename = strdup(fullfile); /* duplicate since basename() may ruin the
+ buffer it works on */
+ if(!filename)
+ return NULL;
+ base = strdup(basename(filename));
+
+ free(filename); /* free temporary buffer */
+
+ return base; /* returns an allocated string or NULL ! */
+}
+
+static CURLcode formdata_add_filename(const struct curl_httppost *file,
+ struct FormData **form,
+ curl_off_t *size)
+{
+ CURLcode result = CURLE_OK;
+ char *filename = file->showfilename;
+ char *filebasename = NULL;
+ char *filename_escaped = NULL;
+
+ if(!filename) {
+ filebasename = strippath(file->contents);
+ if(!filebasename)
+ return CURLE_OUT_OF_MEMORY;
+ filename = filebasename;
+ }
+
+ if(strchr(filename, '\\') || strchr(filename, '"')) {
+ char *p0, *p1;
+
+ /* filename need be escaped */
+ filename_escaped = malloc(strlen(filename)*2+1);
+ if(!filename_escaped) {
+ free(filebasename);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ p0 = filename_escaped;
+ p1 = filename;
+ while(*p1) {
+ if(*p1 == '\\' || *p1 == '"')
+ *p0++ = '\\';
+ *p0++ = *p1++;
+ }
+ *p0 = '\0';
+ filename = filename_escaped;
+ }
+ result = AddFormDataf(form, size,
+ "; filename=\"%s\"",
+ filename);
+ free(filename_escaped);
+ free(filebasename);
+ return result;
+}
+
+/*
+ * Curl_getformdata() converts a linked list of "meta data" into a complete
+ * (possibly huge) multipart formdata. The input list is in 'post', while the
+ * output resulting linked lists gets stored in '*finalform'. *sizep will get
+ * the total size of the whole POST.
+ * A multipart/form_data content-type is built, unless a custom content-type
+ * is passed in 'custom_content_type'.
+ *
+ * This function will not do a failf() for the potential memory failures but
+ * should for all other errors it spots. Just note that this function MAY get
+ * a NULL pointer in the 'data' argument.
+ */
+
+CURLcode Curl_getformdata(struct SessionHandle *data,
+ struct FormData **finalform,
+ struct curl_httppost *post,
+ const char *custom_content_type,
+ curl_off_t *sizep)
+{
+ struct FormData *form = NULL;
+ struct FormData *firstform;
+ struct curl_httppost *file;
+ CURLcode result = CURLE_OK;
+
+ curl_off_t size = 0; /* support potentially ENORMOUS formposts */
+ char *boundary;
+ char *fileboundary = NULL;
+ struct curl_slist* curList;
+
+ *finalform = NULL; /* default form is empty */
+
+ if(!post)
+ return result; /* no input => no output! */
+
+ boundary = formboundary(data);
+ if(!boundary)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Make the first line of the output */
+ result = AddFormDataf(&form, NULL,
+ "%s; boundary=%s\r\n",
+ custom_content_type?custom_content_type:
+ "Content-Type: multipart/form-data",
+ boundary);
+
+ if(result) {
+ free(boundary);
+ return result;
+ }
+ /* we DO NOT include that line in the total size of the POST, since it'll be
+ part of the header! */
+
+ firstform = form;
+
+ do {
+
+ if(size) {
+ result = AddFormDataf(&form, &size, "\r\n");
+ if(result)
+ break;
+ }
+
+ /* boundary */
+ result = AddFormDataf(&form, &size, "--%s\r\n", boundary);
+ if(result)
+ break;
+
+ /* Maybe later this should be disabled when a custom_content_type is
+ passed, since Content-Disposition is not meaningful for all multipart
+ types.
+ */
+ result = AddFormDataf(&form, &size,
+ "Content-Disposition: form-data; name=\"");
+ if(result)
+ break;
+
+ result = AddFormData(&form, FORM_DATA, post->name, post->namelength,
+ &size);
+ if(result)
+ break;
+
+ result = AddFormDataf(&form, &size, "\"");
+ if(result)
+ break;
+
+ if(post->more) {
+ /* If used, this is a link to more file names, we must then do
+ the magic to include several files with the same field name */
+
+ free(fileboundary);
+ fileboundary = formboundary(data);
+ if(!fileboundary) {
+ result = CURLE_OUT_OF_MEMORY;
+ break;
+ }
+
+ result = AddFormDataf(&form, &size,
+ "\r\nContent-Type: multipart/mixed;"
+ " boundary=%s\r\n",
+ fileboundary);
+ if(result)
+ break;
+ }
+
+ file = post;
+
+ do {
+
+ /* If 'showfilename' is set, that is a faked name passed on to us
+ to use to in the formpost. If that is not set, the actually used
+ local file name should be added. */
+
+ if(post->more) {
+ /* if multiple-file */
+ result = AddFormDataf(&form, &size,
+ "\r\n--%s\r\nContent-Disposition: "
+ "attachment",
+ fileboundary);
+ if(result)
+ break;
+ result = formdata_add_filename(file, &form, &size);
+ if(result)
+ break;
+ }
+ else if(post->flags & (HTTPPOST_FILENAME|HTTPPOST_BUFFER|
+ HTTPPOST_CALLBACK)) {
+ /* it should be noted that for the HTTPPOST_FILENAME and
+ HTTPPOST_CALLBACK cases the ->showfilename struct member is always
+ assigned at this point */
+ if(post->showfilename || (post->flags & HTTPPOST_FILENAME)) {
+ result = formdata_add_filename(post, &form, &size);
+ }
+
+ if(result)
+ break;
+ }
+
+ if(file->contenttype) {
+ /* we have a specified type */
+ result = AddFormDataf(&form, &size,
+ "\r\nContent-Type: %s",
+ file->contenttype);
+ if(result)
+ break;
+ }
+
+ curList = file->contentheader;
+ while(curList) {
+ /* Process the additional headers specified for this form */
+ result = AddFormDataf( &form, &size, "\r\n%s", curList->data );
+ if(result)
+ break;
+ curList = curList->next;
+ }
+ if(result)
+ break;
+
+ result = AddFormDataf(&form, &size, "\r\n\r\n");
+ if(result)
+ break;
+
+ if((post->flags & HTTPPOST_FILENAME) ||
+ (post->flags & HTTPPOST_READFILE)) {
+ /* we should include the contents from the specified file */
+ FILE *fileread;
+
+ fileread = strequal("-", file->contents)?
+ stdin:fopen(file->contents, "rb"); /* binary read for win32 */
+
+ /*
+ * VMS: This only allows for stream files on VMS. Stream files are
+ * OK, as are FIXED & VAR files WITHOUT implied CC For implied CC,
+ * every record needs to have a \n appended & 1 added to SIZE
+ */
+
+ if(fileread) {
+ if(fileread != stdin) {
+ /* close the file */
+ fclose(fileread);
+ /* add the file name only - for later reading from this */
+ result = AddFormData(&form, FORM_FILE, file->contents, 0, &size);
+ }
+ else {
+ /* When uploading from stdin, we can't know the size of the file,
+ * thus must read the full file as before. We *could* use chunked
+ * transfer-encoding, but that only works for HTTP 1.1 and we
+ * can't be sure we work with such a server.
+ */
+ size_t nread;
+ char buffer[512];
+ while((nread = fread(buffer, 1, sizeof(buffer), fileread)) != 0) {
+ result = AddFormData(&form, FORM_CONTENT, buffer, nread, &size);
+ if(result)
+ break;
+ }
+ }
+ }
+ else {
+ if(data)
+ failf(data, "couldn't open file \"%s\"", file->contents);
+ *finalform = NULL;
+ result = CURLE_READ_ERROR;
+ }
+ }
+ else if(post->flags & HTTPPOST_BUFFER)
+ /* include contents of buffer */
+ result = AddFormData(&form, FORM_CONTENT, post->buffer,
+ post->bufferlength, &size);
+ else if(post->flags & HTTPPOST_CALLBACK)
+ /* the contents should be read with the callback and the size
+ is set with the contentslength */
+ result = AddFormData(&form, FORM_CALLBACK, post->userp,
+ post->contentslength, &size);
+ else
+ /* include the contents we got */
+ result = AddFormData(&form, FORM_CONTENT, post->contents,
+ post->contentslength, &size);
+
+ file = file->more;
+ } while(file && !result); /* for each specified file for this field */
+
+ if(result)
+ break;
+
+ if(post->more) {
+ /* this was a multiple-file inclusion, make a termination file
+ boundary: */
+ result = AddFormDataf(&form, &size,
+ "\r\n--%s--",
+ fileboundary);
+ if(result)
+ break;
+ }
+
+ } while((post = post->next) != NULL); /* for each field */
+
+ /* end-boundary for everything */
+ if(!result)
+ result = AddFormDataf(&form, &size, "\r\n--%s--\r\n", boundary);
+
+ if(result) {
+ Curl_formclean(&firstform);
+ free(fileboundary);
+ free(boundary);
+ return result;
+ }
+
+ *sizep = size;
+
+ free(fileboundary);
+ free(boundary);
+
+ *finalform = firstform;
+
+ return result;
+}
+
+/*
+ * Curl_FormInit() inits the struct 'form' points to with the 'formdata'
+ * and resets the 'sent' counter.
+ */
+int Curl_FormInit(struct Form *form, struct FormData *formdata )
+{
+ if(!formdata)
+ return 1; /* error */
+
+ form->data = formdata;
+ form->sent = 0;
+ form->fp = NULL;
+ form->fread_func = ZERO_NULL;
+
+ return 0;
+}
+
+#ifndef __VMS
+# define fopen_read fopen
+#else
+ /*
+ * vmsfopenread
+ *
+ * For upload to work as expected on VMS, different optional
+ * parameters must be added to the fopen command based on
+ * record format of the file.
+ *
+ */
+# define fopen_read vmsfopenread
+static FILE * vmsfopenread(const char *file, const char *mode) {
+ struct_stat statbuf;
+ int result;
+
+ result = stat(file, &statbuf);
+
+ switch (statbuf.st_fab_rfm) {
+ case FAB$C_VAR:
+ case FAB$C_VFC:
+ case FAB$C_STMCR:
+ return fopen(file, "r"); /* VMS */
+ break;
+ default:
+ return fopen(file, "r", "rfm=stmlf", "ctx=stm");
+ }
+}
+#endif
+
+/*
+ * readfromfile()
+ *
+ * The read callback that this function may use can return a value larger than
+ * 'size' (which then this function returns) that indicates a problem and it
+ * must be properly dealt with
+ */
+static size_t readfromfile(struct Form *form, char *buffer,
+ size_t size)
+{
+ size_t nread;
+ bool callback = (form->data->type == FORM_CALLBACK)?TRUE:FALSE;
+
+ if(callback) {
+ if(form->fread_func == ZERO_NULL)
+ return 0;
+ else
+ nread = form->fread_func(buffer, 1, size, form->data->line);
+ }
+ else {
+ if(!form->fp) {
+ /* this file hasn't yet been opened */
+ form->fp = fopen_read(form->data->line, "rb"); /* b is for binary */
+ if(!form->fp)
+ return (size_t)-1; /* failure */
+ }
+ nread = fread(buffer, 1, size, form->fp);
+ }
+ if(!nread) {
+ /* this is the last chunk from the file, move on */
+ if(form->fp) {
+ fclose(form->fp);
+ form->fp = NULL;
+ }
+ form->data = form->data->next;
+ }
+
+ return nread;
+}
+
+/*
+ * Curl_FormReader() is the fread() emulation function that will be used to
+ * deliver the formdata to the transfer loop and then sent away to the peer.
+ */
+size_t Curl_FormReader(char *buffer,
+ size_t size,
+ size_t nitems,
+ FILE *mydata)
+{
+ struct Form *form;
+ size_t wantedsize;
+ size_t gotsize = 0;
+
+ form=(struct Form *)mydata;
+
+ wantedsize = size * nitems;
+
+ if(!form->data)
+ return 0; /* nothing, error, empty */
+
+ if((form->data->type == FORM_FILE) ||
+ (form->data->type == FORM_CALLBACK)) {
+ gotsize = readfromfile(form, buffer, wantedsize);
+
+ if(gotsize)
+ /* If positive or -1, return. If zero, continue! */
+ return gotsize;
+ }
+ do {
+
+ if((form->data->length - form->sent ) > wantedsize - gotsize) {
+
+ memcpy(buffer + gotsize , form->data->line + form->sent,
+ wantedsize - gotsize);
+
+ form->sent += wantedsize-gotsize;
+
+ return wantedsize;
+ }
+
+ memcpy(buffer+gotsize,
+ form->data->line + form->sent,
+ (form->data->length - form->sent) );
+ gotsize += form->data->length - form->sent;
+
+ form->sent = 0;
+
+ form->data = form->data->next; /* advance */
+
+ } while(form->data && (form->data->type < FORM_CALLBACK));
+ /* If we got an empty line and we have more data, we proceed to the next
+ line immediately to avoid returning zero before we've reached the end. */
+
+ return gotsize;
+}
+
+/*
+ * Curl_formpostheader() returns the first line of the formpost, the
+ * request-header part (which is not part of the request-body like the rest of
+ * the post).
+ */
+char *Curl_formpostheader(void *formp, size_t *len)
+{
+ char *header;
+ struct Form *form=(struct Form *)formp;
+
+ if(!form->data)
+ return 0; /* nothing, ERROR! */
+
+ header = form->data->line;
+ *len = form->data->length;
+
+ form->data = form->data->next; /* advance */
+
+ return header;
+}
+
+/*
+ * formboundary() creates a suitable boundary string and returns an allocated
+ * one.
+ */
+static char *formboundary(struct SessionHandle *data)
+{
+ /* 24 dashes and 16 hexadecimal digits makes 64 bit (18446744073709551615)
+ combinations */
+ return aprintf("------------------------%08x%08x",
+ Curl_rand(data), Curl_rand(data));
+}
+
+#else /* CURL_DISABLE_HTTP */
+CURLFORMcode curl_formadd(struct curl_httppost **httppost,
+ struct curl_httppost **last_post,
+ ...)
+{
+ (void)httppost;
+ (void)last_post;
+ return CURL_FORMADD_DISABLED;
+}
+
+int curl_formget(struct curl_httppost *form, void *arg,
+ curl_formget_callback append)
+{
+ (void) form;
+ (void) arg;
+ (void) append;
+ return CURL_FORMADD_DISABLED;
+}
+
+void curl_formfree(struct curl_httppost *form)
+{
+ (void)form;
+ /* does nothing HTTP is disabled */
+}
+
+
+#endif /* !defined(CURL_DISABLE_HTTP) */
diff --git a/Utilities/cmcurl/lib/formdata.h b/Utilities/cmcurl/lib/formdata.h
new file mode 100644
index 000000000..22f504bb3
--- /dev/null
+++ b/Utilities/cmcurl/lib/formdata.h
@@ -0,0 +1,98 @@
+#ifndef HEADER_CURL_FORMDATA_H
+#define HEADER_CURL_FORMDATA_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+enum formtype {
+ FORM_DATA, /* form metadata (convert to network encoding if necessary) */
+ FORM_CONTENT, /* form content (never convert) */
+ FORM_CALLBACK, /* 'line' points to the custom pointer we pass to the callback
+ */
+ FORM_FILE /* 'line' points to a file name we should read from
+ to create the form data (never convert) */
+};
+
+/* plain and simple linked list with lines to send */
+struct FormData {
+ struct FormData *next;
+ enum formtype type;
+ char *line;
+ size_t length;
+};
+
+struct Form {
+ struct FormData *data; /* current form line to send */
+ size_t sent; /* number of bytes of the current line that has
+ already been sent in a previous invoke */
+ FILE *fp; /* file to read from */
+ curl_read_callback fread_func; /* fread callback pointer */
+};
+
+/* used by FormAdd for temporary storage */
+typedef struct FormInfo {
+ char *name;
+ bool name_alloc;
+ size_t namelength;
+ char *value;
+ bool value_alloc;
+ size_t contentslength;
+ char *contenttype;
+ bool contenttype_alloc;
+ long flags;
+ char *buffer; /* pointer to existing buffer used for file upload */
+ size_t bufferlength;
+ char *showfilename; /* The file name to show. If not set, the actual
+ file name will be used */
+ bool showfilename_alloc;
+ char *userp; /* pointer for the read callback */
+ struct curl_slist* contentheader;
+ struct FormInfo *more;
+} FormInfo;
+
+int Curl_FormInit(struct Form *form, struct FormData *formdata );
+
+CURLcode Curl_getformdata(struct SessionHandle *data,
+ struct FormData **,
+ struct curl_httppost *post,
+ const char *custom_contenttype,
+ curl_off_t *size);
+
+/* fread() emulation */
+size_t Curl_FormReader(char *buffer,
+ size_t size,
+ size_t nitems,
+ FILE *mydata);
+
+/*
+ * Curl_formpostheader() returns the first line of the formpost, the
+ * request-header part (which is not part of the request-body like the rest of
+ * the post).
+ */
+char *Curl_formpostheader(void *formp, size_t *len);
+
+char *Curl_FormBoundary(void);
+
+void Curl_formclean(struct FormData **);
+
+CURLcode Curl_formconvert(struct SessionHandle *, struct FormData *);
+
+#endif /* HEADER_CURL_FORMDATA_H */
diff --git a/Utilities/cmcurl/lib/ftp.c b/Utilities/cmcurl/lib/ftp.c
new file mode 100644
index 000000000..74c403250
--- /dev/null
+++ b/Utilities/cmcurl/lib/ftp.c
@@ -0,0 +1,4599 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_FTP
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "sendf.h"
+#include "if2ip.h"
+#include "hostip.h"
+#include "progress.h"
+#include "transfer.h"
+#include "escape.h"
+#include "http.h" /* for HTTP proxy tunnel stuff */
+#include "socks.h"
+#include "ftp.h"
+#include "fileinfo.h"
+#include "ftplistparser.h"
+#include "curl_sec.h"
+#include "strtoofft.h"
+#include "strequal.h"
+#include "vtls/vtls.h"
+#include "connect.h"
+#include "strerror.h"
+#include "inet_ntop.h"
+#include "inet_pton.h"
+#include "select.h"
+#include "parsedate.h" /* for the week day and month names */
+#include "sockaddr.h" /* required for Curl_sockaddr_storage */
+#include "multiif.h"
+#include "url.h"
+#include "rawstr.h"
+#include "speedcheck.h"
+#include "warnless.h"
+#include "http_proxy.h"
+#include "non-ascii.h"
+#include "curl_printf.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#ifndef NI_MAXHOST
+#define NI_MAXHOST 1025
+#endif
+#ifndef INET_ADDRSTRLEN
+#define INET_ADDRSTRLEN 16
+#endif
+
+#ifdef CURL_DISABLE_VERBOSE_STRINGS
+#define ftp_pasv_verbose(a,b,c,d) Curl_nop_stmt
+#endif
+
+/* Local API functions */
+#ifndef DEBUGBUILD
+static void _state(struct connectdata *conn,
+ ftpstate newstate);
+#define state(x,y) _state(x,y)
+#else
+static void _state(struct connectdata *conn,
+ ftpstate newstate,
+ int lineno);
+#define state(x,y) _state(x,y,__LINE__)
+#endif
+
+static CURLcode ftp_sendquote(struct connectdata *conn,
+ struct curl_slist *quote);
+static CURLcode ftp_quit(struct connectdata *conn);
+static CURLcode ftp_parse_url_path(struct connectdata *conn);
+static CURLcode ftp_regular_transfer(struct connectdata *conn, bool *done);
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+static void ftp_pasv_verbose(struct connectdata *conn,
+ Curl_addrinfo *ai,
+ char *newhost, /* ascii version */
+ int port);
+#endif
+static CURLcode ftp_state_prepare_transfer(struct connectdata *conn);
+static CURLcode ftp_state_mdtm(struct connectdata *conn);
+static CURLcode ftp_state_quote(struct connectdata *conn,
+ bool init, ftpstate instate);
+static CURLcode ftp_nb_type(struct connectdata *conn,
+ bool ascii, ftpstate newstate);
+static int ftp_need_type(struct connectdata *conn,
+ bool ascii);
+static CURLcode ftp_do(struct connectdata *conn, bool *done);
+static CURLcode ftp_done(struct connectdata *conn,
+ CURLcode, bool premature);
+static CURLcode ftp_connect(struct connectdata *conn, bool *done);
+static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection);
+static CURLcode ftp_do_more(struct connectdata *conn, int *completed);
+static CURLcode ftp_multi_statemach(struct connectdata *conn, bool *done);
+static int ftp_getsock(struct connectdata *conn, curl_socket_t *socks,
+ int numsocks);
+static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks,
+ int numsocks);
+static CURLcode ftp_doing(struct connectdata *conn,
+ bool *dophase_done);
+static CURLcode ftp_setup_connection(struct connectdata * conn);
+
+static CURLcode init_wc_data(struct connectdata *conn);
+static CURLcode wc_statemach(struct connectdata *conn);
+
+static void wc_data_dtor(void *ptr);
+
+static CURLcode ftp_state_retr(struct connectdata *conn, curl_off_t filesize);
+
+static CURLcode ftp_readresp(curl_socket_t sockfd,
+ struct pingpong *pp,
+ int *ftpcode,
+ size_t *size);
+static CURLcode ftp_dophase_done(struct connectdata *conn,
+ bool connected);
+
+/* easy-to-use macro: */
+#define PPSENDF(x,y,z) if((result = Curl_pp_sendf(x,y,z))) \
+ return result
+
+
+/*
+ * FTP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_ftp = {
+ "FTP", /* scheme */
+ ftp_setup_connection, /* setup_connection */
+ ftp_do, /* do_it */
+ ftp_done, /* done */
+ ftp_do_more, /* do_more */
+ ftp_connect, /* connect_it */
+ ftp_multi_statemach, /* connecting */
+ ftp_doing, /* doing */
+ ftp_getsock, /* proto_getsock */
+ ftp_getsock, /* doing_getsock */
+ ftp_domore_getsock, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ ftp_disconnect, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_FTP, /* defport */
+ CURLPROTO_FTP, /* protocol */
+ PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD
+ | PROTOPT_NOURLQUERY /* flags */
+};
+
+
+#ifdef USE_SSL
+/*
+ * FTPS protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_ftps = {
+ "FTPS", /* scheme */
+ ftp_setup_connection, /* setup_connection */
+ ftp_do, /* do_it */
+ ftp_done, /* done */
+ ftp_do_more, /* do_more */
+ ftp_connect, /* connect_it */
+ ftp_multi_statemach, /* connecting */
+ ftp_doing, /* doing */
+ ftp_getsock, /* proto_getsock */
+ ftp_getsock, /* doing_getsock */
+ ftp_domore_getsock, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ ftp_disconnect, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_FTPS, /* defport */
+ CURLPROTO_FTPS, /* protocol */
+ PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION |
+ PROTOPT_NEEDSPWD | PROTOPT_NOURLQUERY /* flags */
+};
+#endif
+
+#ifndef CURL_DISABLE_HTTP
+/*
+ * HTTP-proxyed FTP protocol handler.
+ */
+
+static const struct Curl_handler Curl_handler_ftp_proxy = {
+ "FTP", /* scheme */
+ Curl_http_setup_conn, /* setup_connection */
+ Curl_http, /* do_it */
+ Curl_http_done, /* done */
+ ZERO_NULL, /* do_more */
+ ZERO_NULL, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_getsock */
+ ZERO_NULL, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ ZERO_NULL, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_FTP, /* defport */
+ CURLPROTO_HTTP, /* protocol */
+ PROTOPT_NONE /* flags */
+};
+
+
+#ifdef USE_SSL
+/*
+ * HTTP-proxyed FTPS protocol handler.
+ */
+
+static const struct Curl_handler Curl_handler_ftps_proxy = {
+ "FTPS", /* scheme */
+ Curl_http_setup_conn, /* setup_connection */
+ Curl_http, /* do_it */
+ Curl_http_done, /* done */
+ ZERO_NULL, /* do_more */
+ ZERO_NULL, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_getsock */
+ ZERO_NULL, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ ZERO_NULL, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_FTPS, /* defport */
+ CURLPROTO_HTTP, /* protocol */
+ PROTOPT_NONE /* flags */
+};
+#endif
+#endif
+
+
+/*
+ * NOTE: back in the old days, we added code in the FTP code that made NOBODY
+ * requests on files respond with headers passed to the client/stdout that
+ * looked like HTTP ones.
+ *
+ * This approach is not very elegant, it causes confusion and is error-prone.
+ * It is subject for removal at the next (or at least a future) soname bump.
+ * Until then you can test the effects of the removal by undefining the
+ * following define named CURL_FTP_HTTPSTYLE_HEAD.
+ */
+#define CURL_FTP_HTTPSTYLE_HEAD 1
+
+static void freedirs(struct ftp_conn *ftpc)
+{
+ int i;
+ if(ftpc->dirs) {
+ for(i=0; i < ftpc->dirdepth; i++) {
+ free(ftpc->dirs[i]);
+ ftpc->dirs[i]=NULL;
+ }
+ free(ftpc->dirs);
+ ftpc->dirs = NULL;
+ ftpc->dirdepth = 0;
+ }
+ Curl_safefree(ftpc->file);
+
+ /* no longer of any use */
+ Curl_safefree(ftpc->newhost);
+}
+
+/* Returns non-zero if the given string contains CR (\r) or LF (\n),
+ which are not allowed within RFC 959 <string>.
+ Note: The input string is in the client's encoding which might
+ not be ASCII, so escape sequences \r & \n must be used instead
+ of hex values 0x0d & 0x0a.
+*/
+static bool isBadFtpString(const char *string)
+{
+ return ((NULL != strchr(string, '\r')) ||
+ (NULL != strchr(string, '\n'))) ? TRUE : FALSE;
+}
+
+/***********************************************************************
+ *
+ * AcceptServerConnect()
+ *
+ * After connection request is received from the server this function is
+ * called to accept the connection and close the listening socket
+ *
+ */
+static CURLcode AcceptServerConnect(struct connectdata *conn)
+{
+ struct SessionHandle *data = conn->data;
+ curl_socket_t sock = conn->sock[SECONDARYSOCKET];
+ curl_socket_t s = CURL_SOCKET_BAD;
+#ifdef ENABLE_IPV6
+ struct Curl_sockaddr_storage add;
+#else
+ struct sockaddr_in add;
+#endif
+ curl_socklen_t size = (curl_socklen_t) sizeof(add);
+
+ if(0 == getsockname(sock, (struct sockaddr *) &add, &size)) {
+ size = sizeof(add);
+
+ s=accept(sock, (struct sockaddr *) &add, &size);
+ }
+ Curl_closesocket(conn, sock); /* close the first socket */
+
+ if(CURL_SOCKET_BAD == s) {
+ failf(data, "Error accept()ing server connect");
+ return CURLE_FTP_PORT_FAILED;
+ }
+ infof(data, "Connection accepted from server\n");
+
+ conn->sock[SECONDARYSOCKET] = s;
+ (void)curlx_nonblock(s, TRUE); /* enable non-blocking */
+ conn->sock_accepted[SECONDARYSOCKET] = TRUE;
+
+ if(data->set.fsockopt) {
+ int error = 0;
+
+ /* activate callback for setting socket options */
+ error = data->set.fsockopt(data->set.sockopt_client,
+ s,
+ CURLSOCKTYPE_ACCEPT);
+
+ if(error) {
+ Curl_closesocket(conn, s); /* close the socket and bail out */
+ conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
+ return CURLE_ABORTED_BY_CALLBACK;
+ }
+ }
+
+ return CURLE_OK;
+
+}
+
+/*
+ * ftp_timeleft_accept() returns the amount of milliseconds left allowed for
+ * waiting server to connect. If the value is negative, the timeout time has
+ * already elapsed.
+ *
+ * The start time is stored in progress.t_acceptdata - as set with
+ * Curl_pgrsTime(..., TIMER_STARTACCEPT);
+ *
+ */
+static long ftp_timeleft_accept(struct SessionHandle *data)
+{
+ long timeout_ms = DEFAULT_ACCEPT_TIMEOUT;
+ long other;
+ struct timeval now;
+
+ if(data->set.accepttimeout > 0)
+ timeout_ms = data->set.accepttimeout;
+
+ now = Curl_tvnow();
+
+ /* check if the generic timeout possibly is set shorter */
+ other = Curl_timeleft(data, &now, FALSE);
+ if(other && (other < timeout_ms))
+ /* note that this also works fine for when other happens to be negative
+ due to it already having elapsed */
+ timeout_ms = other;
+ else {
+ /* subtract elapsed time */
+ timeout_ms -= Curl_tvdiff(now, data->progress.t_acceptdata);
+ if(!timeout_ms)
+ /* avoid returning 0 as that means no timeout! */
+ return -1;
+ }
+
+ return timeout_ms;
+}
+
+
+/***********************************************************************
+ *
+ * ReceivedServerConnect()
+ *
+ * After allowing server to connect to us from data port, this function
+ * checks both data connection for connection establishment and ctrl
+ * connection for a negative response regarding a failure in connecting
+ *
+ */
+static CURLcode ReceivedServerConnect(struct connectdata *conn, bool *received)
+{
+ struct SessionHandle *data = conn->data;
+ curl_socket_t ctrl_sock = conn->sock[FIRSTSOCKET];
+ curl_socket_t data_sock = conn->sock[SECONDARYSOCKET];
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+ struct pingpong *pp = &ftpc->pp;
+ int result;
+ long timeout_ms;
+ ssize_t nread;
+ int ftpcode;
+
+ *received = FALSE;
+
+ timeout_ms = ftp_timeleft_accept(data);
+ infof(data, "Checking for server connect\n");
+ if(timeout_ms < 0) {
+ /* if a timeout was already reached, bail out */
+ failf(data, "Accept timeout occurred while waiting server connect");
+ return CURLE_FTP_ACCEPT_TIMEOUT;
+ }
+
+ /* First check whether there is a cached response from server */
+ if(pp->cache_size && pp->cache && pp->cache[0] > '3') {
+ /* Data connection could not be established, let's return */
+ infof(data, "There is negative response in cache while serv connect\n");
+ Curl_GetFTPResponse(&nread, conn, &ftpcode);
+ return CURLE_FTP_ACCEPT_FAILED;
+ }
+
+ result = Curl_socket_check(ctrl_sock, data_sock, CURL_SOCKET_BAD, 0);
+
+ /* see if the connection request is already here */
+ switch (result) {
+ case -1: /* error */
+ /* let's die here */
+ failf(data, "Error while waiting for server connect");
+ return CURLE_FTP_ACCEPT_FAILED;
+ case 0: /* Server connect is not received yet */
+ break; /* loop */
+ default:
+
+ if(result & CURL_CSELECT_IN2) {
+ infof(data, "Ready to accept data connection from server\n");
+ *received = TRUE;
+ }
+ else if(result & CURL_CSELECT_IN) {
+ infof(data, "Ctrl conn has data while waiting for data conn\n");
+ Curl_GetFTPResponse(&nread, conn, &ftpcode);
+
+ if(ftpcode/100 > 3)
+ return CURLE_FTP_ACCEPT_FAILED;
+
+ return CURLE_FTP_WEIRD_SERVER_REPLY;
+ }
+
+ break;
+ } /* switch() */
+
+ return CURLE_OK;
+}
+
+
+/***********************************************************************
+ *
+ * InitiateTransfer()
+ *
+ * After connection from server is accepted this function is called to
+ * setup transfer parameters and initiate the data transfer.
+ *
+ */
+static CURLcode InitiateTransfer(struct connectdata *conn)
+{
+ struct SessionHandle *data = conn->data;
+ struct FTP *ftp = data->req.protop;
+ CURLcode result = CURLE_OK;
+
+ if(conn->ssl[SECONDARYSOCKET].use) {
+ /* since we only have a plaintext TCP connection here, we must now
+ * do the TLS stuff */
+ infof(data, "Doing the SSL/TLS handshake on the data stream\n");
+ result = Curl_ssl_connect(conn, SECONDARYSOCKET);
+ if(result)
+ return result;
+ }
+
+ if(conn->proto.ftpc.state_saved == FTP_STOR) {
+ *(ftp->bytecountp)=0;
+
+ /* When we know we're uploading a specified file, we can get the file
+ size prior to the actual upload. */
+
+ Curl_pgrsSetUploadSize(data, data->state.infilesize);
+
+ /* set the SO_SNDBUF for the secondary socket for those who need it */
+ Curl_sndbufset(conn->sock[SECONDARYSOCKET]);
+
+ Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
+ SECONDARYSOCKET, ftp->bytecountp);
+ }
+ else {
+ /* FTP download: */
+ Curl_setup_transfer(conn, SECONDARYSOCKET,
+ conn->proto.ftpc.retr_size_saved, FALSE,
+ ftp->bytecountp, -1, NULL); /* no upload here */
+ }
+
+ conn->proto.ftpc.pp.pending_resp = TRUE; /* expect server response */
+ state(conn, FTP_STOP);
+
+ return CURLE_OK;
+}
+
+/***********************************************************************
+ *
+ * AllowServerConnect()
+ *
+ * When we've issue the PORT command, we have told the server to connect to
+ * us. This function checks whether data connection is established if so it is
+ * accepted.
+ *
+ */
+static CURLcode AllowServerConnect(struct connectdata *conn, bool *connected)
+{
+ struct SessionHandle *data = conn->data;
+ long timeout_ms;
+ CURLcode result = CURLE_OK;
+
+ *connected = FALSE;
+ infof(data, "Preparing for accepting server on data port\n");
+
+ /* Save the time we start accepting server connect */
+ Curl_pgrsTime(data, TIMER_STARTACCEPT);
+
+ timeout_ms = ftp_timeleft_accept(data);
+ if(timeout_ms < 0) {
+ /* if a timeout was already reached, bail out */
+ failf(data, "Accept timeout occurred while waiting server connect");
+ return CURLE_FTP_ACCEPT_TIMEOUT;
+ }
+
+ /* see if the connection request is already here */
+ result = ReceivedServerConnect(conn, connected);
+ if(result)
+ return result;
+
+ if(*connected) {
+ result = AcceptServerConnect(conn);
+ if(result)
+ return result;
+
+ result = InitiateTransfer(conn);
+ if(result)
+ return result;
+ }
+ else {
+ /* Add timeout to multi handle and break out of the loop */
+ if(!result && *connected == FALSE) {
+ if(data->set.accepttimeout > 0)
+ Curl_expire(data, data->set.accepttimeout);
+ else
+ Curl_expire(data, DEFAULT_ACCEPT_TIMEOUT);
+ }
+ }
+
+ return result;
+}
+
+/* macro to check for a three-digit ftp status code at the start of the
+ given string */
+#define STATUSCODE(line) (ISDIGIT(line[0]) && ISDIGIT(line[1]) && \
+ ISDIGIT(line[2]))
+
+/* macro to check for the last line in an FTP server response */
+#define LASTLINE(line) (STATUSCODE(line) && (' ' == line[3]))
+
+static bool ftp_endofresp(struct connectdata *conn, char *line, size_t len,
+ int *code)
+{
+ (void)conn;
+
+ if((len > 3) && LASTLINE(line)) {
+ *code = curlx_sltosi(strtol(line, NULL, 10));
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static CURLcode ftp_readresp(curl_socket_t sockfd,
+ struct pingpong *pp,
+ int *ftpcode, /* return the ftp-code if done */
+ size_t *size) /* size of the response */
+{
+ struct connectdata *conn = pp->conn;
+ struct SessionHandle *data = conn->data;
+#ifdef HAVE_GSSAPI
+ char * const buf = data->state.buffer;
+#endif
+ CURLcode result = CURLE_OK;
+ int code;
+
+ result = Curl_pp_readresp(sockfd, pp, &code, size);
+
+#if defined(HAVE_GSSAPI)
+ /* handle the security-oriented responses 6xx ***/
+ /* FIXME: some errorchecking perhaps... ***/
+ switch(code) {
+ case 631:
+ code = Curl_sec_read_msg(conn, buf, PROT_SAFE);
+ break;
+ case 632:
+ code = Curl_sec_read_msg(conn, buf, PROT_PRIVATE);
+ break;
+ case 633:
+ code = Curl_sec_read_msg(conn, buf, PROT_CONFIDENTIAL);
+ break;
+ default:
+ /* normal ftp stuff we pass through! */
+ break;
+ }
+#endif
+
+ /* store the latest code for later retrieval */
+ data->info.httpcode=code;
+
+ if(ftpcode)
+ *ftpcode = code;
+
+ if(421 == code) {
+ /* 421 means "Service not available, closing control connection." and FTP
+ * servers use it to signal that idle session timeout has been exceeded.
+ * If we ignored the response, it could end up hanging in some cases.
+ *
+ * This response code can come at any point so having it treated
+ * generically is a good idea.
+ */
+ infof(data, "We got a 421 - timeout!\n");
+ state(conn, FTP_STOP);
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+
+ return result;
+}
+
+/* --- parse FTP server responses --- */
+
+/*
+ * Curl_GetFTPResponse() is a BLOCKING function to read the full response
+ * from a server after a command.
+ *
+ */
+
+CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
+ struct connectdata *conn,
+ int *ftpcode) /* return the ftp-code */
+{
+ /*
+ * We cannot read just one byte per read() and then go back to select() as
+ * the OpenSSL read() doesn't grok that properly.
+ *
+ * Alas, read as much as possible, split up into lines, use the ending
+ * line in a response or continue reading. */
+
+ curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
+ long timeout; /* timeout in milliseconds */
+ long interval_ms;
+ struct SessionHandle *data = conn->data;
+ CURLcode result = CURLE_OK;
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+ struct pingpong *pp = &ftpc->pp;
+ size_t nread;
+ int cache_skip=0;
+ int value_to_be_ignored=0;
+
+ if(ftpcode)
+ *ftpcode = 0; /* 0 for errors */
+ else
+ /* make the pointer point to something for the rest of this function */
+ ftpcode = &value_to_be_ignored;
+
+ *nreadp=0;
+
+ while(!*ftpcode && !result) {
+ /* check and reset timeout value every lap */
+ timeout = Curl_pp_state_timeout(pp);
+
+ if(timeout <=0 ) {
+ failf(data, "FTP response timeout");
+ return CURLE_OPERATION_TIMEDOUT; /* already too little time */
+ }
+
+ interval_ms = 1000; /* use 1 second timeout intervals */
+ if(timeout < interval_ms)
+ interval_ms = timeout;
+
+ /*
+ * Since this function is blocking, we need to wait here for input on the
+ * connection and only then we call the response reading function. We do
+ * timeout at least every second to make the timeout check run.
+ *
+ * A caution here is that the ftp_readresp() function has a cache that may
+ * contain pieces of a response from the previous invoke and we need to
+ * make sure we don't just wait for input while there is unhandled data in
+ * that cache. But also, if the cache is there, we call ftp_readresp() and
+ * the cache wasn't good enough to continue we must not just busy-loop
+ * around this function.
+ *
+ */
+
+ if(pp->cache && (cache_skip < 2)) {
+ /*
+ * There's a cache left since before. We then skipping the wait for
+ * socket action, unless this is the same cache like the previous round
+ * as then the cache was deemed not enough to act on and we then need to
+ * wait for more data anyway.
+ */
+ }
+ else {
+ switch (Curl_socket_ready(sockfd, CURL_SOCKET_BAD, interval_ms)) {
+ case -1: /* select() error, stop reading */
+ failf(data, "FTP response aborted due to select/poll error: %d",
+ SOCKERRNO);
+ return CURLE_RECV_ERROR;
+
+ case 0: /* timeout */
+ if(Curl_pgrsUpdate(conn))
+ return CURLE_ABORTED_BY_CALLBACK;
+ continue; /* just continue in our loop for the timeout duration */
+
+ default: /* for clarity */
+ break;
+ }
+ }
+ result = ftp_readresp(sockfd, pp, ftpcode, &nread);
+ if(result)
+ break;
+
+ if(!nread && pp->cache)
+ /* bump cache skip counter as on repeated skips we must wait for more
+ data */
+ cache_skip++;
+ else
+ /* when we got data or there is no cache left, we reset the cache skip
+ counter */
+ cache_skip=0;
+
+ *nreadp += nread;
+
+ } /* while there's buffer left and loop is requested */
+
+ pp->pending_resp = FALSE;
+
+ return result;
+}
+
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+ /* for debug purposes */
+static const char * const ftp_state_names[]={
+ "STOP",
+ "WAIT220",
+ "AUTH",
+ "USER",
+ "PASS",
+ "ACCT",
+ "PBSZ",
+ "PROT",
+ "CCC",
+ "PWD",
+ "SYST",
+ "NAMEFMT",
+ "QUOTE",
+ "RETR_PREQUOTE",
+ "STOR_PREQUOTE",
+ "POSTQUOTE",
+ "CWD",
+ "MKD",
+ "MDTM",
+ "TYPE",
+ "LIST_TYPE",
+ "RETR_TYPE",
+ "STOR_TYPE",
+ "SIZE",
+ "RETR_SIZE",
+ "STOR_SIZE",
+ "REST",
+ "RETR_REST",
+ "PORT",
+ "PRET",
+ "PASV",
+ "LIST",
+ "RETR",
+ "STOR",
+ "QUIT"
+};
+#endif
+
+/* This is the ONLY way to change FTP state! */
+static void _state(struct connectdata *conn,
+ ftpstate newstate
+#ifdef DEBUGBUILD
+ , int lineno
+#endif
+ )
+{
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+#if defined(DEBUGBUILD)
+
+#if defined(CURL_DISABLE_VERBOSE_STRINGS)
+ (void) lineno;
+#else
+ if(ftpc->state != newstate)
+ infof(conn->data, "FTP %p (line %d) state change from %s to %s\n",
+ (void *)ftpc, lineno, ftp_state_names[ftpc->state],
+ ftp_state_names[newstate]);
+#endif
+#endif
+
+ ftpc->state = newstate;
+}
+
+static CURLcode ftp_state_user(struct connectdata *conn)
+{
+ CURLcode result;
+ struct FTP *ftp = conn->data->req.protop;
+ /* send USER */
+ PPSENDF(&conn->proto.ftpc.pp, "USER %s", ftp->user?ftp->user:"");
+
+ state(conn, FTP_USER);
+ conn->data->state.ftp_trying_alternative = FALSE;
+
+ return CURLE_OK;
+}
+
+static CURLcode ftp_state_pwd(struct connectdata *conn)
+{
+ CURLcode result;
+
+ /* send PWD to discover our entry point */
+ PPSENDF(&conn->proto.ftpc.pp, "%s", "PWD");
+ state(conn, FTP_PWD);
+
+ return CURLE_OK;
+}
+
+/* For the FTP "protocol connect" and "doing" phases only */
+static int ftp_getsock(struct connectdata *conn,
+ curl_socket_t *socks,
+ int numsocks)
+{
+ return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks);
+}
+
+/* For the FTP "DO_MORE" phase only */
+static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks,
+ int numsocks)
+{
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+ if(!numsocks)
+ return GETSOCK_BLANK;
+
+ /* When in DO_MORE state, we could be either waiting for us to connect to a
+ * remote site, or we could wait for that site to connect to us. Or just
+ * handle ordinary commands.
+ */
+
+ if(FTP_STOP == ftpc->state) {
+ int bits = GETSOCK_READSOCK(0);
+
+ /* if stopped and still in this state, then we're also waiting for a
+ connect on the secondary connection */
+ socks[0] = conn->sock[FIRSTSOCKET];
+
+ if(!conn->data->set.ftp_use_port) {
+ int s;
+ int i;
+ /* PORT is used to tell the server to connect to us, and during that we
+ don't do happy eyeballs, but we do if we connect to the server */
+ for(s=1, i=0; i<2; i++) {
+ if(conn->tempsock[i] != CURL_SOCKET_BAD) {
+ socks[s] = conn->tempsock[i];
+ bits |= GETSOCK_WRITESOCK(s++);
+ }
+ }
+ }
+ else {
+ socks[1] = conn->sock[SECONDARYSOCKET];
+ bits |= GETSOCK_WRITESOCK(1);
+ }
+
+ return bits;
+ }
+ else
+ return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks);
+}
+
+/* This is called after the FTP_QUOTE state is passed.
+
+ ftp_state_cwd() sends the range of CWD commands to the server to change to
+ the correct directory. It may also need to send MKD commands to create
+ missing ones, if that option is enabled.
+*/
+static CURLcode ftp_state_cwd(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+ if(ftpc->cwddone)
+ /* already done and fine */
+ result = ftp_state_mdtm(conn);
+ else {
+ ftpc->count2 = 0; /* count2 counts failed CWDs */
+
+ /* count3 is set to allow a MKD to fail once. In the case when first CWD
+ fails and then MKD fails (due to another session raced it to create the
+ dir) this then allows for a second try to CWD to it */
+ ftpc->count3 = (conn->data->set.ftp_create_missing_dirs==2)?1:0;
+
+ if(conn->bits.reuse && ftpc->entrypath) {
+ /* This is a re-used connection. Since we change directory to where the
+ transfer is taking place, we must first get back to the original dir
+ where we ended up after login: */
+ ftpc->count1 = 0; /* we count this as the first path, then we add one
+ for all upcoming ones in the ftp->dirs[] array */
+ PPSENDF(&conn->proto.ftpc.pp, "CWD %s", ftpc->entrypath);
+ state(conn, FTP_CWD);
+ }
+ else {
+ if(ftpc->dirdepth) {
+ ftpc->count1 = 1;
+ /* issue the first CWD, the rest is sent when the CWD responses are
+ received... */
+ PPSENDF(&conn->proto.ftpc.pp, "CWD %s", ftpc->dirs[ftpc->count1 -1]);
+ state(conn, FTP_CWD);
+ }
+ else {
+ /* No CWD necessary */
+ result = ftp_state_mdtm(conn);
+ }
+ }
+ }
+ return result;
+}
+
+typedef enum {
+ EPRT,
+ PORT,
+ DONE
+} ftpport;
+
+static CURLcode ftp_state_use_port(struct connectdata *conn,
+ ftpport fcmd) /* start with this */
+
+{
+ CURLcode result = CURLE_OK;
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+ struct SessionHandle *data=conn->data;
+ curl_socket_t portsock= CURL_SOCKET_BAD;
+ char myhost[256] = "";
+
+ struct Curl_sockaddr_storage ss;
+ Curl_addrinfo *res, *ai;
+ curl_socklen_t sslen;
+ char hbuf[NI_MAXHOST];
+ struct sockaddr *sa=(struct sockaddr *)&ss;
+ struct sockaddr_in * const sa4 = (void *)sa;
+#ifdef ENABLE_IPV6
+ struct sockaddr_in6 * const sa6 = (void *)sa;
+#endif
+ char tmp[1024];
+ static const char mode[][5] = { "EPRT", "PORT" };
+ int rc;
+ int error;
+ char *host = NULL;
+ char *string_ftpport = data->set.str[STRING_FTPPORT];
+ struct Curl_dns_entry *h=NULL;
+ unsigned short port_min = 0;
+ unsigned short port_max = 0;
+ unsigned short port;
+ bool possibly_non_local = TRUE;
+
+ char *addr = NULL;
+
+ /* Step 1, figure out what is requested,
+ * accepted format :
+ * (ipv4|ipv6|domain|interface)?(:port(-range)?)?
+ */
+
+ if(data->set.str[STRING_FTPPORT] &&
+ (strlen(data->set.str[STRING_FTPPORT]) > 1)) {
+
+#ifdef ENABLE_IPV6
+ size_t addrlen = INET6_ADDRSTRLEN > strlen(string_ftpport) ?
+ INET6_ADDRSTRLEN : strlen(string_ftpport);
+#else
+ size_t addrlen = INET_ADDRSTRLEN > strlen(string_ftpport) ?
+ INET_ADDRSTRLEN : strlen(string_ftpport);
+#endif
+ char *ip_start = string_ftpport;
+ char *ip_end = NULL;
+ char *port_start = NULL;
+ char *port_sep = NULL;
+
+ addr = calloc(addrlen+1, 1);
+ if(!addr)
+ return CURLE_OUT_OF_MEMORY;
+
+#ifdef ENABLE_IPV6
+ if(*string_ftpport == '[') {
+ /* [ipv6]:port(-range) */
+ ip_start = string_ftpport + 1;
+ if((ip_end = strchr(string_ftpport, ']')) != NULL )
+ strncpy(addr, ip_start, ip_end - ip_start);
+ }
+ else
+#endif
+ if(*string_ftpport == ':') {
+ /* :port */
+ ip_end = string_ftpport;
+ }
+ else if((ip_end = strchr(string_ftpport, ':')) != NULL) {
+ /* either ipv6 or (ipv4|domain|interface):port(-range) */
+#ifdef ENABLE_IPV6
+ if(Curl_inet_pton(AF_INET6, string_ftpport, sa6) == 1) {
+ /* ipv6 */
+ port_min = port_max = 0;
+ strcpy(addr, string_ftpport);
+ ip_end = NULL; /* this got no port ! */
+ }
+ else
+#endif
+ /* (ipv4|domain|interface):port(-range) */
+ strncpy(addr, string_ftpport, ip_end - ip_start );
+ }
+ else
+ /* ipv4|interface */
+ strcpy(addr, string_ftpport);
+
+ /* parse the port */
+ if(ip_end != NULL) {
+ if((port_start = strchr(ip_end, ':')) != NULL) {
+ port_min = curlx_ultous(strtoul(port_start+1, NULL, 10));
+ if((port_sep = strchr(port_start, '-')) != NULL) {
+ port_max = curlx_ultous(strtoul(port_sep + 1, NULL, 10));
+ }
+ else
+ port_max = port_min;
+ }
+ }
+
+ /* correct errors like:
+ * :1234-1230
+ * :-4711 , in this case port_min is (unsigned)-1,
+ * therefore port_min > port_max for all cases
+ * but port_max = (unsigned)-1
+ */
+ if(port_min > port_max )
+ port_min = port_max = 0;
+
+
+ if(*addr != '\0') {
+ /* attempt to get the address of the given interface name */
+ switch(Curl_if2ip(conn->ip_addr->ai_family,
+ Curl_ipv6_scope(conn->ip_addr->ai_addr),
+ conn->scope_id, addr, hbuf, sizeof(hbuf))) {
+ case IF2IP_NOT_FOUND:
+ /* not an interface, use the given string as host name instead */
+ host = addr;
+ break;
+ case IF2IP_AF_NOT_SUPPORTED:
+ return CURLE_FTP_PORT_FAILED;
+ case IF2IP_FOUND:
+ host = hbuf; /* use the hbuf for host name */
+ }
+ }
+ else
+ /* there was only a port(-range) given, default the host */
+ host = NULL;
+ } /* data->set.ftpport */
+
+ if(!host) {
+ /* not an interface and not a host name, get default by extracting
+ the IP from the control connection */
+
+ sslen = sizeof(ss);
+ if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) {
+ failf(data, "getsockname() failed: %s",
+ Curl_strerror(conn, SOCKERRNO) );
+ free(addr);
+ return CURLE_FTP_PORT_FAILED;
+ }
+ switch(sa->sa_family) {
+#ifdef ENABLE_IPV6
+ case AF_INET6:
+ Curl_inet_ntop(sa->sa_family, &sa6->sin6_addr, hbuf, sizeof(hbuf));
+ break;
+#endif
+ default:
+ Curl_inet_ntop(sa->sa_family, &sa4->sin_addr, hbuf, sizeof(hbuf));
+ break;
+ }
+ host = hbuf; /* use this host name */
+ possibly_non_local = FALSE; /* we know it is local now */
+ }
+
+ /* resolv ip/host to ip */
+ rc = Curl_resolv(conn, host, 0, &h);
+ if(rc == CURLRESOLV_PENDING)
+ (void)Curl_resolver_wait_resolv(conn, &h);
+ if(h) {
+ res = h->addr;
+ /* when we return from this function, we can forget about this entry
+ to we can unlock it now already */
+ Curl_resolv_unlock(data, h);
+ } /* (h) */
+ else
+ res = NULL; /* failure! */
+
+ if(res == NULL) {
+ failf(data, "failed to resolve the address provided to PORT: %s", host);
+ free(addr);
+ return CURLE_FTP_PORT_FAILED;
+ }
+
+ free(addr);
+ host = NULL;
+
+ /* step 2, create a socket for the requested address */
+
+ portsock = CURL_SOCKET_BAD;
+ error = 0;
+ for(ai = res; ai; ai = ai->ai_next) {
+ result = Curl_socket(conn, ai, NULL, &portsock);
+ if(result) {
+ error = SOCKERRNO;
+ continue;
+ }
+ break;
+ }
+ if(!ai) {
+ failf(data, "socket failure: %s", Curl_strerror(conn, error));
+ return CURLE_FTP_PORT_FAILED;
+ }
+
+ /* step 3, bind to a suitable local address */
+
+ memcpy(sa, ai->ai_addr, ai->ai_addrlen);
+ sslen = ai->ai_addrlen;
+
+ for(port = port_min; port <= port_max;) {
+ if(sa->sa_family == AF_INET)
+ sa4->sin_port = htons(port);
+#ifdef ENABLE_IPV6
+ else
+ sa6->sin6_port = htons(port);
+#endif
+ /* Try binding the given address. */
+ if(bind(portsock, sa, sslen) ) {
+ /* It failed. */
+ error = SOCKERRNO;
+ if(possibly_non_local && (error == EADDRNOTAVAIL)) {
+ /* The requested bind address is not local. Use the address used for
+ * the control connection instead and restart the port loop
+ */
+
+ infof(data, "bind(port=%hu) on non-local address failed: %s\n", port,
+ Curl_strerror(conn, error) );
+
+ sslen = sizeof(ss);
+ if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) {
+ failf(data, "getsockname() failed: %s",
+ Curl_strerror(conn, SOCKERRNO) );
+ Curl_closesocket(conn, portsock);
+ return CURLE_FTP_PORT_FAILED;
+ }
+ port = port_min;
+ possibly_non_local = FALSE; /* don't try this again */
+ continue;
+ }
+ else if(error != EADDRINUSE && error != EACCES) {
+ failf(data, "bind(port=%hu) failed: %s", port,
+ Curl_strerror(conn, error) );
+ Curl_closesocket(conn, portsock);
+ return CURLE_FTP_PORT_FAILED;
+ }
+ }
+ else
+ break;
+
+ port++;
+ }
+
+ /* maybe all ports were in use already*/
+ if(port > port_max) {
+ failf(data, "bind() failed, we ran out of ports!");
+ Curl_closesocket(conn, portsock);
+ return CURLE_FTP_PORT_FAILED;
+ }
+
+ /* get the name again after the bind() so that we can extract the
+ port number it uses now */
+ sslen = sizeof(ss);
+ if(getsockname(portsock, (struct sockaddr *)sa, &sslen)) {
+ failf(data, "getsockname() failed: %s",
+ Curl_strerror(conn, SOCKERRNO) );
+ Curl_closesocket(conn, portsock);
+ return CURLE_FTP_PORT_FAILED;
+ }
+
+ /* step 4, listen on the socket */
+
+ if(listen(portsock, 1)) {
+ failf(data, "socket failure: %s", Curl_strerror(conn, SOCKERRNO));
+ Curl_closesocket(conn, portsock);
+ return CURLE_FTP_PORT_FAILED;
+ }
+
+ /* step 5, send the proper FTP command */
+
+ /* get a plain printable version of the numerical address to work with
+ below */
+ Curl_printable_address(ai, myhost, sizeof(myhost));
+
+#ifdef ENABLE_IPV6
+ if(!conn->bits.ftp_use_eprt && conn->bits.ipv6)
+ /* EPRT is disabled but we are connected to a IPv6 host, so we ignore the
+ request and enable EPRT again! */
+ conn->bits.ftp_use_eprt = TRUE;
+#endif
+
+ for(; fcmd != DONE; fcmd++) {
+
+ if(!conn->bits.ftp_use_eprt && (EPRT == fcmd))
+ /* if disabled, goto next */
+ continue;
+
+ if((PORT == fcmd) && sa->sa_family != AF_INET)
+ /* PORT is IPv4 only */
+ continue;
+
+ switch(sa->sa_family) {
+ case AF_INET:
+ port = ntohs(sa4->sin_port);
+ break;
+#ifdef ENABLE_IPV6
+ case AF_INET6:
+ port = ntohs(sa6->sin6_port);
+ break;
+#endif
+ default:
+ continue; /* might as well skip this */
+ }
+
+ if(EPRT == fcmd) {
+ /*
+ * Two fine examples from RFC2428;
+ *
+ * EPRT |1|132.235.1.2|6275|
+ *
+ * EPRT |2|1080::8:800:200C:417A|5282|
+ */
+
+ result = Curl_pp_sendf(&ftpc->pp, "%s |%d|%s|%hu|", mode[fcmd],
+ sa->sa_family == AF_INET?1:2,
+ myhost, port);
+ if(result) {
+ failf(data, "Failure sending EPRT command: %s",
+ curl_easy_strerror(result));
+ Curl_closesocket(conn, portsock);
+ /* don't retry using PORT */
+ ftpc->count1 = PORT;
+ /* bail out */
+ state(conn, FTP_STOP);
+ return result;
+ }
+ break;
+ }
+ else if(PORT == fcmd) {
+ char *source = myhost;
+ char *dest = tmp;
+
+ /* translate x.x.x.x to x,x,x,x */
+ while(source && *source) {
+ if(*source == '.')
+ *dest=',';
+ else
+ *dest = *source;
+ dest++;
+ source++;
+ }
+ *dest = 0;
+ snprintf(dest, 20, ",%d,%d", (int)(port>>8), (int)(port&0xff));
+
+ result = Curl_pp_sendf(&ftpc->pp, "%s %s", mode[fcmd], tmp);
+ if(result) {
+ failf(data, "Failure sending PORT command: %s",
+ curl_easy_strerror(result));
+ Curl_closesocket(conn, portsock);
+ /* bail out */
+ state(conn, FTP_STOP);
+ return result;
+ }
+ break;
+ }
+ }
+
+ /* store which command was sent */
+ ftpc->count1 = fcmd;
+
+ /* we set the secondary socket variable to this for now, it is only so that
+ the cleanup function will close it in case we fail before the true
+ secondary stuff is made */
+ if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
+ Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
+ conn->sock[SECONDARYSOCKET] = portsock;
+
+ /* this tcpconnect assignment below is a hackish work-around to make the
+ multi interface with active FTP work - as it will not wait for a
+ (passive) connect in Curl_is_connected().
+
+ The *proper* fix is to make sure that the active connection from the
+ server is done in a non-blocking way. Currently, it is still BLOCKING.
+ */
+ conn->bits.tcpconnect[SECONDARYSOCKET] = TRUE;
+
+ state(conn, FTP_PORT);
+ return result;
+}
+
+static CURLcode ftp_state_use_pasv(struct connectdata *conn)
+{
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+ CURLcode result = CURLE_OK;
+ /*
+ Here's the excecutive summary on what to do:
+
+ PASV is RFC959, expect:
+ 227 Entering Passive Mode (a1,a2,a3,a4,p1,p2)
+
+ LPSV is RFC1639, expect:
+ 228 Entering Long Passive Mode (4,4,a1,a2,a3,a4,2,p1,p2)
+
+ EPSV is RFC2428, expect:
+ 229 Entering Extended Passive Mode (|||port|)
+
+ */
+
+ static const char mode[][5] = { "EPSV", "PASV" };
+ int modeoff;
+
+#ifdef PF_INET6
+ if(!conn->bits.ftp_use_epsv && conn->bits.ipv6)
+ /* EPSV is disabled but we are connected to a IPv6 host, so we ignore the
+ request and enable EPSV again! */
+ conn->bits.ftp_use_epsv = TRUE;
+#endif
+
+ modeoff = conn->bits.ftp_use_epsv?0:1;
+
+ PPSENDF(&ftpc->pp, "%s", mode[modeoff]);
+
+ ftpc->count1 = modeoff;
+ state(conn, FTP_PASV);
+ infof(conn->data, "Connect data stream passively\n");
+
+ return result;
+}
+
+/*
+ * ftp_state_prepare_transfer() starts PORT, PASV or PRET etc.
+ *
+ * REST is the last command in the chain of commands when a "head"-like
+ * request is made. Thus, if an actual transfer is to be made this is where we
+ * take off for real.
+ */
+static CURLcode ftp_state_prepare_transfer(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct FTP *ftp = conn->data->req.protop;
+ struct SessionHandle *data = conn->data;
+
+ if(ftp->transfer != FTPTRANSFER_BODY) {
+ /* doesn't transfer any data */
+
+ /* still possibly do PRE QUOTE jobs */
+ state(conn, FTP_RETR_PREQUOTE);
+ result = ftp_state_quote(conn, TRUE, FTP_RETR_PREQUOTE);
+ }
+ else if(data->set.ftp_use_port) {
+ /* We have chosen to use the PORT (or similar) command */
+ result = ftp_state_use_port(conn, EPRT);
+ }
+ else {
+ /* We have chosen (this is default) to use the PASV (or similar) command */
+ if(data->set.ftp_use_pret) {
+ /* The user has requested that we send a PRET command
+ to prepare the server for the upcoming PASV */
+ if(!conn->proto.ftpc.file) {
+ PPSENDF(&conn->proto.ftpc.pp, "PRET %s",
+ data->set.str[STRING_CUSTOMREQUEST]?
+ data->set.str[STRING_CUSTOMREQUEST]:
+ (data->set.ftp_list_only?"NLST":"LIST"));
+ }
+ else if(data->set.upload) {
+ PPSENDF(&conn->proto.ftpc.pp, "PRET STOR %s", conn->proto.ftpc.file);
+ }
+ else {
+ PPSENDF(&conn->proto.ftpc.pp, "PRET RETR %s", conn->proto.ftpc.file);
+ }
+ state(conn, FTP_PRET);
+ }
+ else {
+ result = ftp_state_use_pasv(conn);
+ }
+ }
+ return result;
+}
+
+static CURLcode ftp_state_rest(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct FTP *ftp = conn->data->req.protop;
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+ if((ftp->transfer != FTPTRANSFER_BODY) && ftpc->file) {
+ /* if a "head"-like request is being made (on a file) */
+
+ /* Determine if server can respond to REST command and therefore
+ whether it supports range */
+ PPSENDF(&conn->proto.ftpc.pp, "REST %d", 0);
+
+ state(conn, FTP_REST);
+ }
+ else
+ result = ftp_state_prepare_transfer(conn);
+
+ return result;
+}
+
+static CURLcode ftp_state_size(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct FTP *ftp = conn->data->req.protop;
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+ if((ftp->transfer == FTPTRANSFER_INFO) && ftpc->file) {
+ /* if a "head"-like request is being made (on a file) */
+
+ /* we know ftpc->file is a valid pointer to a file name */
+ PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file);
+
+ state(conn, FTP_SIZE);
+ }
+ else
+ result = ftp_state_rest(conn);
+
+ return result;
+}
+
+static CURLcode ftp_state_list(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+
+ /* If this output is to be machine-parsed, the NLST command might be better
+ to use, since the LIST command output is not specified or standard in any
+ way. It has turned out that the NLST list output is not the same on all
+ servers either... */
+
+ /*
+ if FTPFILE_NOCWD was specified, we are currently in
+ the user's home directory, so we should add the path
+ as argument for the LIST / NLST / or custom command.
+ Whether the server will support this, is uncertain.
+
+ The other ftp_filemethods will CWD into dir/dir/ first and
+ then just do LIST (in that case: nothing to do here)
+ */
+ char *cmd, *lstArg, *slashPos;
+
+ lstArg = NULL;
+ if((data->set.ftp_filemethod == FTPFILE_NOCWD) &&
+ data->state.path &&
+ data->state.path[0] &&
+ strchr(data->state.path, '/')) {
+
+ lstArg = strdup(data->state.path);
+ if(!lstArg)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Check if path does not end with /, as then we cut off the file part */
+ if(lstArg[strlen(lstArg) - 1] != '/') {
+
+ /* chop off the file part if format is dir/dir/file */
+ slashPos = strrchr(lstArg, '/');
+ if(slashPos)
+ *(slashPos+1) = '\0';
+ }
+ }
+
+ cmd = aprintf( "%s%s%s",
+ data->set.str[STRING_CUSTOMREQUEST]?
+ data->set.str[STRING_CUSTOMREQUEST]:
+ (data->set.ftp_list_only?"NLST":"LIST"),
+ lstArg? " ": "",
+ lstArg? lstArg: "" );
+
+ if(!cmd) {
+ free(lstArg);
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", cmd);
+
+ free(lstArg);
+ free(cmd);
+
+ if(result)
+ return result;
+
+ state(conn, FTP_LIST);
+
+ return result;
+}
+
+static CURLcode ftp_state_retr_prequote(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+
+ /* We've sent the TYPE, now we must send the list of prequote strings */
+
+ result = ftp_state_quote(conn, TRUE, FTP_RETR_PREQUOTE);
+
+ return result;
+}
+
+static CURLcode ftp_state_stor_prequote(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+
+ /* We've sent the TYPE, now we must send the list of prequote strings */
+
+ result = ftp_state_quote(conn, TRUE, FTP_STOR_PREQUOTE);
+
+ return result;
+}
+
+static CURLcode ftp_state_type(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct FTP *ftp = conn->data->req.protop;
+ struct SessionHandle *data = conn->data;
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+ /* If we have selected NOBODY and HEADER, it means that we only want file
+ information. Which in FTP can't be much more than the file size and
+ date. */
+ if(data->set.opt_no_body && ftpc->file &&
+ ftp_need_type(conn, data->set.prefer_ascii)) {
+ /* The SIZE command is _not_ RFC 959 specified, and therefor many servers
+ may not support it! It is however the only way we have to get a file's
+ size! */
+
+ ftp->transfer = FTPTRANSFER_INFO;
+ /* this means no actual transfer will be made */
+
+ /* Some servers return different sizes for different modes, and thus we
+ must set the proper type before we check the size */
+ result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_TYPE);
+ if(result)
+ return result;
+ }
+ else
+ result = ftp_state_size(conn);
+
+ return result;
+}
+
+/* This is called after the CWD commands have been done in the beginning of
+ the DO phase */
+static CURLcode ftp_state_mdtm(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+ /* Requested time of file or time-depended transfer? */
+ if((data->set.get_filetime || data->set.timecondition) && ftpc->file) {
+
+ /* we have requested to get the modified-time of the file, this is a white
+ spot as the MDTM is not mentioned in RFC959 */
+ PPSENDF(&ftpc->pp, "MDTM %s", ftpc->file);
+
+ state(conn, FTP_MDTM);
+ }
+ else
+ result = ftp_state_type(conn);
+
+ return result;
+}
+
+
+/* This is called after the TYPE and possible quote commands have been sent */
+static CURLcode ftp_state_ul_setup(struct connectdata *conn,
+ bool sizechecked)
+{
+ CURLcode result = CURLE_OK;
+ struct FTP *ftp = conn->data->req.protop;
+ struct SessionHandle *data = conn->data;
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+ int seekerr = CURL_SEEKFUNC_OK;
+
+ if((data->state.resume_from && !sizechecked) ||
+ ((data->state.resume_from > 0) && sizechecked)) {
+ /* we're about to continue the uploading of a file */
+ /* 1. get already existing file's size. We use the SIZE command for this
+ which may not exist in the server! The SIZE command is not in
+ RFC959. */
+
+ /* 2. This used to set REST. But since we can do append, we
+ don't another ftp command. We just skip the source file
+ offset and then we APPEND the rest on the file instead */
+
+ /* 3. pass file-size number of bytes in the source file */
+ /* 4. lower the infilesize counter */
+ /* => transfer as usual */
+
+ if(data->state.resume_from < 0 ) {
+ /* Got no given size to start from, figure it out */
+ PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file);
+ state(conn, FTP_STOR_SIZE);
+ return result;
+ }
+
+ /* enable append */
+ data->set.ftp_append = TRUE;
+
+ /* Let's read off the proper amount of bytes from the input. */
+ if(conn->seek_func) {
+ seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
+ SEEK_SET);
+ }
+
+ if(seekerr != CURL_SEEKFUNC_OK) {
+ if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
+ failf(data, "Could not seek stream");
+ return CURLE_FTP_COULDNT_USE_REST;
+ }
+ /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
+ else {
+ curl_off_t passed=0;
+ do {
+ size_t readthisamountnow =
+ (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
+ BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
+
+ size_t actuallyread =
+ data->set.fread_func(data->state.buffer, 1, readthisamountnow,
+ data->set.in);
+
+ passed += actuallyread;
+ if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
+ /* this checks for greater-than only to make sure that the
+ CURL_READFUNC_ABORT return code still aborts */
+ failf(data, "Failed to read data");
+ return CURLE_FTP_COULDNT_USE_REST;
+ }
+ } while(passed < data->state.resume_from);
+ }
+ }
+ /* now, decrease the size of the read */
+ if(data->state.infilesize>0) {
+ data->state.infilesize -= data->state.resume_from;
+
+ if(data->state.infilesize <= 0) {
+ infof(data, "File already completely uploaded\n");
+
+ /* no data to transfer */
+ Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+
+ /* Set ->transfer so that we won't get any error in
+ * ftp_done() because we didn't transfer anything! */
+ ftp->transfer = FTPTRANSFER_NONE;
+
+ state(conn, FTP_STOP);
+ return CURLE_OK;
+ }
+ }
+ /* we've passed, proceed as normal */
+ } /* resume_from */
+
+ PPSENDF(&ftpc->pp, data->set.ftp_append?"APPE %s":"STOR %s",
+ ftpc->file);
+
+ state(conn, FTP_STOR);
+
+ return result;
+}
+
+static CURLcode ftp_state_quote(struct connectdata *conn,
+ bool init,
+ ftpstate instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct FTP *ftp = data->req.protop;
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+ bool quote=FALSE;
+ struct curl_slist *item;
+
+ switch(instate) {
+ case FTP_QUOTE:
+ default:
+ item = data->set.quote;
+ break;
+ case FTP_RETR_PREQUOTE:
+ case FTP_STOR_PREQUOTE:
+ item = data->set.prequote;
+ break;
+ case FTP_POSTQUOTE:
+ item = data->set.postquote;
+ break;
+ }
+
+ /*
+ * This state uses:
+ * 'count1' to iterate over the commands to send
+ * 'count2' to store wether to allow commands to fail
+ */
+
+ if(init)
+ ftpc->count1 = 0;
+ else
+ ftpc->count1++;
+
+ if(item) {
+ int i = 0;
+
+ /* Skip count1 items in the linked list */
+ while((i< ftpc->count1) && item) {
+ item = item->next;
+ i++;
+ }
+ if(item) {
+ char *cmd = item->data;
+ if(cmd[0] == '*') {
+ cmd++;
+ ftpc->count2 = 1; /* the sent command is allowed to fail */
+ }
+ else
+ ftpc->count2 = 0; /* failure means cancel operation */
+
+ PPSENDF(&ftpc->pp, "%s", cmd);
+ state(conn, instate);
+ quote = TRUE;
+ }
+ }
+
+ if(!quote) {
+ /* No more quote to send, continue to ... */
+ switch(instate) {
+ case FTP_QUOTE:
+ default:
+ result = ftp_state_cwd(conn);
+ break;
+ case FTP_RETR_PREQUOTE:
+ if(ftp->transfer != FTPTRANSFER_BODY)
+ state(conn, FTP_STOP);
+ else {
+ if(ftpc->known_filesize != -1) {
+ Curl_pgrsSetDownloadSize(data, ftpc->known_filesize);
+ result = ftp_state_retr(conn, ftpc->known_filesize);
+ }
+ else {
+ PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file);
+ state(conn, FTP_RETR_SIZE);
+ }
+ }
+ break;
+ case FTP_STOR_PREQUOTE:
+ result = ftp_state_ul_setup(conn, FALSE);
+ break;
+ case FTP_POSTQUOTE:
+ break;
+ }
+ }
+
+ return result;
+}
+
+/* called from ftp_state_pasv_resp to switch to PASV in case of EPSV
+ problems */
+static CURLcode ftp_epsv_disable(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+
+ if(conn->bits.ipv6) {
+ /* We can't disable EPSV when doing IPv6, so this is instead a fail */
+ failf(conn->data, "Failed EPSV attempt, exiting\n");
+ return CURLE_FTP_WEIRD_SERVER_REPLY;
+ }
+
+ infof(conn->data, "Failed EPSV attempt. Disabling EPSV\n");
+ /* disable it for next transfer */
+ conn->bits.ftp_use_epsv = FALSE;
+ conn->data->state.errorbuf = FALSE; /* allow error message to get
+ rewritten */
+ PPSENDF(&conn->proto.ftpc.pp, "%s", "PASV");
+ conn->proto.ftpc.count1++;
+ /* remain in/go to the FTP_PASV state */
+ state(conn, FTP_PASV);
+ return result;
+}
+
+/*
+ * Perform the necessary magic that needs to be done once the TCP connection
+ * to the proxy has completed.
+ */
+static CURLcode proxy_magic(struct connectdata *conn,
+ char *newhost, unsigned short newport,
+ bool *magicdone)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+
+#if defined(CURL_DISABLE_PROXY)
+ (void) newhost;
+ (void) newport;
+#endif
+
+ *magicdone = FALSE;
+
+ switch(conn->proxytype) {
+ case CURLPROXY_SOCKS5:
+ case CURLPROXY_SOCKS5_HOSTNAME:
+ result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, newhost,
+ newport, SECONDARYSOCKET, conn);
+ *magicdone = TRUE;
+ break;
+ case CURLPROXY_SOCKS4:
+ result = Curl_SOCKS4(conn->proxyuser, newhost, newport,
+ SECONDARYSOCKET, conn, FALSE);
+ *magicdone = TRUE;
+ break;
+ case CURLPROXY_SOCKS4A:
+ result = Curl_SOCKS4(conn->proxyuser, newhost, newport,
+ SECONDARYSOCKET, conn, TRUE);
+ *magicdone = TRUE;
+ break;
+ case CURLPROXY_HTTP:
+ case CURLPROXY_HTTP_1_0:
+ /* do nothing here. handled later. */
+ break;
+ default:
+ failf(data, "unknown proxytype option given");
+ result = CURLE_COULDNT_CONNECT;
+ break;
+ }
+
+ if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
+ /* BLOCKING */
+ /* We want "seamless" FTP operations through HTTP proxy tunnel */
+
+ /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the
+ * member conn->proto.http; we want FTP through HTTP and we have to
+ * change the member temporarily for connecting to the HTTP proxy. After
+ * Curl_proxyCONNECT we have to set back the member to the original
+ * struct FTP pointer
+ */
+ struct HTTP http_proxy;
+ struct FTP *ftp_save = data->req.protop;
+ memset(&http_proxy, 0, sizeof(http_proxy));
+ data->req.protop = &http_proxy;
+
+ result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, newhost, newport, TRUE);
+
+ data->req.protop = ftp_save;
+
+ if(result)
+ return result;
+
+ if(conn->tunnel_state[SECONDARYSOCKET] != TUNNEL_COMPLETE) {
+ /* the CONNECT procedure is not complete, the tunnel is not yet up */
+ state(conn, FTP_STOP); /* this phase is completed */
+ return result;
+ }
+ else
+ *magicdone = TRUE;
+ }
+
+ return result;
+}
+
+static char *control_address(struct connectdata *conn)
+{
+ /* Returns the control connection IP address.
+ If a proxy tunnel is used, returns the original host name instead, because
+ the effective control connection address is the proxy address,
+ not the ftp host. */
+ if(conn->bits.tunnel_proxy ||
+ conn->proxytype == CURLPROXY_SOCKS5 ||
+ conn->proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
+ conn->proxytype == CURLPROXY_SOCKS4 ||
+ conn->proxytype == CURLPROXY_SOCKS4A)
+ return conn->host.name;
+
+ return conn->ip_addr_str;
+}
+
+static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
+ int ftpcode)
+{
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+ CURLcode result;
+ struct SessionHandle *data=conn->data;
+ struct Curl_dns_entry *addr=NULL;
+ int rc;
+ unsigned short connectport; /* the local port connect() should use! */
+ char *str=&data->state.buffer[4]; /* start on the first letter */
+
+ /* if we come here again, make sure the former name is cleared */
+ Curl_safefree(ftpc->newhost);
+
+ if((ftpc->count1 == 0) &&
+ (ftpcode == 229)) {
+ /* positive EPSV response */
+ char *ptr = strchr(str, '(');
+ if(ptr) {
+ unsigned int num;
+ char separator[4];
+ ptr++;
+ if(5 == sscanf(ptr, "%c%c%c%u%c",
+ &separator[0],
+ &separator[1],
+ &separator[2],
+ &num,
+ &separator[3])) {
+ const char sep1 = separator[0];
+ int i;
+
+ /* The four separators should be identical, or else this is an oddly
+ formatted reply and we bail out immediately. */
+ for(i=1; i<4; i++) {
+ if(separator[i] != sep1) {
+ ptr=NULL; /* set to NULL to signal error */
+ break;
+ }
+ }
+ if(num > 0xffff) {
+ failf(data, "Illegal port number in EPSV reply");
+ return CURLE_FTP_WEIRD_PASV_REPLY;
+ }
+ if(ptr) {
+ ftpc->newport = (unsigned short)(num & 0xffff);
+ ftpc->newhost = strdup(control_address(conn));
+ if(!ftpc->newhost)
+ return CURLE_OUT_OF_MEMORY;
+ }
+ }
+ else
+ ptr=NULL;
+ }
+ if(!ptr) {
+ failf(data, "Weirdly formatted EPSV reply");
+ return CURLE_FTP_WEIRD_PASV_REPLY;
+ }
+ }
+ else if((ftpc->count1 == 1) &&
+ (ftpcode == 227)) {
+ /* positive PASV response */
+ int ip[4];
+ int port[2];
+
+ /*
+ * Scan for a sequence of six comma-separated numbers and use them as
+ * IP+port indicators.
+ *
+ * Found reply-strings include:
+ * "227 Entering Passive Mode (127,0,0,1,4,51)"
+ * "227 Data transfer will passively listen to 127,0,0,1,4,51"
+ * "227 Entering passive mode. 127,0,0,1,4,51"
+ */
+ while(*str) {
+ if(6 == sscanf(str, "%d,%d,%d,%d,%d,%d",
+ &ip[0], &ip[1], &ip[2], &ip[3],
+ &port[0], &port[1]))
+ break;
+ str++;
+ }
+
+ if(!*str) {
+ failf(data, "Couldn't interpret the 227-response");
+ return CURLE_FTP_WEIRD_227_FORMAT;
+ }
+
+ /* we got OK from server */
+ if(data->set.ftp_skip_ip) {
+ /* told to ignore the remotely given IP but instead use the host we used
+ for the control connection */
+ infof(data, "Skip %d.%d.%d.%d for data connection, re-use %s instead\n",
+ ip[0], ip[1], ip[2], ip[3],
+ conn->host.name);
+ ftpc->newhost = strdup(control_address(conn));
+ }
+ else
+ ftpc->newhost = aprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
+
+ if(!ftpc->newhost)
+ return CURLE_OUT_OF_MEMORY;
+
+ ftpc->newport = (unsigned short)(((port[0]<<8) + port[1]) & 0xffff);
+ }
+ else if(ftpc->count1 == 0) {
+ /* EPSV failed, move on to PASV */
+ return ftp_epsv_disable(conn);
+ }
+ else {
+ failf(data, "Bad PASV/EPSV response: %03d", ftpcode);
+ return CURLE_FTP_WEIRD_PASV_REPLY;
+ }
+
+ if(conn->bits.proxy) {
+ /*
+ * This connection uses a proxy and we need to connect to the proxy again
+ * here. We don't want to rely on a former host lookup that might've
+ * expired now, instead we remake the lookup here and now!
+ */
+ rc = Curl_resolv(conn, conn->proxy.name, (int)conn->port, &addr);
+ if(rc == CURLRESOLV_PENDING)
+ /* BLOCKING, ignores the return code but 'addr' will be NULL in
+ case of failure */
+ (void)Curl_resolver_wait_resolv(conn, &addr);
+
+ connectport =
+ (unsigned short)conn->port; /* we connect to the proxy's port */
+
+ if(!addr) {
+ failf(data, "Can't resolve proxy host %s:%hu",
+ conn->proxy.name, connectport);
+ return CURLE_FTP_CANT_GET_HOST;
+ }
+ }
+ else {
+ /* normal, direct, ftp connection */
+ rc = Curl_resolv(conn, ftpc->newhost, ftpc->newport, &addr);
+ if(rc == CURLRESOLV_PENDING)
+ /* BLOCKING */
+ (void)Curl_resolver_wait_resolv(conn, &addr);
+
+ connectport = ftpc->newport; /* we connect to the remote port */
+
+ if(!addr) {
+ failf(data, "Can't resolve new host %s:%hu", ftpc->newhost, connectport);
+ return CURLE_FTP_CANT_GET_HOST;
+ }
+ }
+
+ conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE;
+ result = Curl_connecthost(conn, addr);
+
+ if(result) {
+ Curl_resolv_unlock(data, addr); /* we're done using this address */
+ if(ftpc->count1 == 0 && ftpcode == 229)
+ return ftp_epsv_disable(conn);
+
+ return result;
+ }
+
+
+ /*
+ * When this is used from the multi interface, this might've returned with
+ * the 'connected' set to FALSE and thus we are now awaiting a non-blocking
+ * connect to connect.
+ */
+
+ if(data->set.verbose)
+ /* this just dumps information about this second connection */
+ ftp_pasv_verbose(conn, addr->addr, ftpc->newhost, connectport);
+
+ Curl_resolv_unlock(data, addr); /* we're done using this address */
+ conn->bits.do_more = TRUE;
+ state(conn, FTP_STOP); /* this phase is completed */
+
+ return result;
+}
+
+static CURLcode ftp_state_port_resp(struct connectdata *conn,
+ int ftpcode)
+{
+ struct SessionHandle *data = conn->data;
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+ ftpport fcmd = (ftpport)ftpc->count1;
+ CURLcode result = CURLE_OK;
+
+ /* The FTP spec tells a positive response should have code 200.
+ Be more permissive here to tolerate deviant servers. */
+ if(ftpcode / 100 != 2) {
+ /* the command failed */
+
+ if(EPRT == fcmd) {
+ infof(data, "disabling EPRT usage\n");
+ conn->bits.ftp_use_eprt = FALSE;
+ }
+ fcmd++;
+
+ if(fcmd == DONE) {
+ failf(data, "Failed to do PORT");
+ result = CURLE_FTP_PORT_FAILED;
+ }
+ else
+ /* try next */
+ result = ftp_state_use_port(conn, fcmd);
+ }
+ else {
+ infof(data, "Connect data stream actively\n");
+ state(conn, FTP_STOP); /* end of DO phase */
+ result = ftp_dophase_done(conn, FALSE);
+ }
+
+ return result;
+}
+
+static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
+ int ftpcode)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data=conn->data;
+ struct FTP *ftp = data->req.protop;
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+ switch(ftpcode) {
+ case 213:
+ {
+ /* we got a time. Format should be: "YYYYMMDDHHMMSS[.sss]" where the
+ last .sss part is optional and means fractions of a second */
+ int year, month, day, hour, minute, second;
+ char *buf = data->state.buffer;
+ if(6 == sscanf(buf+4, "%04d%02d%02d%02d%02d%02d",
+ &year, &month, &day, &hour, &minute, &second)) {
+ /* we have a time, reformat it */
+ time_t secs=time(NULL);
+ /* using the good old yacc/bison yuck */
+ snprintf(buf, sizeof(conn->data->state.buffer),
+ "%04d%02d%02d %02d:%02d:%02d GMT",
+ year, month, day, hour, minute, second);
+ /* now, convert this into a time() value: */
+ data->info.filetime = (long)curl_getdate(buf, &secs);
+ }
+
+#ifdef CURL_FTP_HTTPSTYLE_HEAD
+ /* If we asked for a time of the file and we actually got one as well,
+ we "emulate" a HTTP-style header in our output. */
+
+ if(data->set.opt_no_body &&
+ ftpc->file &&
+ data->set.get_filetime &&
+ (data->info.filetime>=0) ) {
+ time_t filetime = (time_t)data->info.filetime;
+ struct tm buffer;
+ const struct tm *tm = &buffer;
+
+ result = Curl_gmtime(filetime, &buffer);
+ if(result)
+ return result;
+
+ /* format: "Tue, 15 Nov 1994 12:45:26" */
+ snprintf(buf, BUFSIZE-1,
+ "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
+ Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
+ tm->tm_mday,
+ Curl_month[tm->tm_mon],
+ tm->tm_year + 1900,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec);
+ result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
+ if(result)
+ return result;
+ } /* end of a ridiculous amount of conditionals */
+#endif
+ }
+ break;
+ default:
+ infof(data, "unsupported MDTM reply format\n");
+ break;
+ case 550: /* "No such file or directory" */
+ failf(data, "Given file does not exist");
+ result = CURLE_FTP_COULDNT_RETR_FILE;
+ break;
+ }
+
+ if(data->set.timecondition) {
+ if((data->info.filetime > 0) && (data->set.timevalue > 0)) {
+ switch(data->set.timecondition) {
+ case CURL_TIMECOND_IFMODSINCE:
+ default:
+ if(data->info.filetime <= data->set.timevalue) {
+ infof(data, "The requested document is not new enough\n");
+ ftp->transfer = FTPTRANSFER_NONE; /* mark to not transfer data */
+ data->info.timecond = TRUE;
+ state(conn, FTP_STOP);
+ return CURLE_OK;
+ }
+ break;
+ case CURL_TIMECOND_IFUNMODSINCE:
+ if(data->info.filetime > data->set.timevalue) {
+ infof(data, "The requested document is not old enough\n");
+ ftp->transfer = FTPTRANSFER_NONE; /* mark to not transfer data */
+ data->info.timecond = TRUE;
+ state(conn, FTP_STOP);
+ return CURLE_OK;
+ }
+ break;
+ } /* switch */
+ }
+ else {
+ infof(data, "Skipping time comparison\n");
+ }
+ }
+
+ if(!result)
+ result = ftp_state_type(conn);
+
+ return result;
+}
+
+static CURLcode ftp_state_type_resp(struct connectdata *conn,
+ int ftpcode,
+ ftpstate instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data=conn->data;
+
+ if(ftpcode/100 != 2) {
+ /* "sasserftpd" and "(u)r(x)bot ftpd" both responds with 226 after a
+ successful 'TYPE I'. While that is not as RFC959 says, it is still a
+ positive response code and we allow that. */
+ failf(data, "Couldn't set desired mode");
+ return CURLE_FTP_COULDNT_SET_TYPE;
+ }
+ if(ftpcode != 200)
+ infof(data, "Got a %03d response code instead of the assumed 200\n",
+ ftpcode);
+
+ if(instate == FTP_TYPE)
+ result = ftp_state_size(conn);
+ else if(instate == FTP_LIST_TYPE)
+ result = ftp_state_list(conn);
+ else if(instate == FTP_RETR_TYPE)
+ result = ftp_state_retr_prequote(conn);
+ else if(instate == FTP_STOR_TYPE)
+ result = ftp_state_stor_prequote(conn);
+
+ return result;
+}
+
+static CURLcode ftp_state_retr(struct connectdata *conn,
+ curl_off_t filesize)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data=conn->data;
+ struct FTP *ftp = data->req.protop;
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+ if(data->set.max_filesize && (filesize > data->set.max_filesize)) {
+ failf(data, "Maximum file size exceeded");
+ return CURLE_FILESIZE_EXCEEDED;
+ }
+ ftp->downloadsize = filesize;
+
+ if(data->state.resume_from) {
+ /* We always (attempt to) get the size of downloads, so it is done before
+ this even when not doing resumes. */
+ if(filesize == -1) {
+ infof(data, "ftp server doesn't support SIZE\n");
+ /* We couldn't get the size and therefore we can't know if there really
+ is a part of the file left to get, although the server will just
+ close the connection when we start the connection so it won't cause
+ us any harm, just not make us exit as nicely. */
+ }
+ else {
+ /* We got a file size report, so we check that there actually is a
+ part of the file left to get, or else we go home. */
+ if(data->state.resume_from< 0) {
+ /* We're supposed to download the last abs(from) bytes */
+ if(filesize < -data->state.resume_from) {
+ failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
+ ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
+ data->state.resume_from, filesize);
+ return CURLE_BAD_DOWNLOAD_RESUME;
+ }
+ /* convert to size to download */
+ ftp->downloadsize = -data->state.resume_from;
+ /* download from where? */
+ data->state.resume_from = filesize - ftp->downloadsize;
+ }
+ else {
+ if(filesize < data->state.resume_from) {
+ failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
+ ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
+ data->state.resume_from, filesize);
+ return CURLE_BAD_DOWNLOAD_RESUME;
+ }
+ /* Now store the number of bytes we are expected to download */
+ ftp->downloadsize = filesize-data->state.resume_from;
+ }
+ }
+
+ if(ftp->downloadsize == 0) {
+ /* no data to transfer */
+ Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+ infof(data, "File already completely downloaded\n");
+
+ /* Set ->transfer so that we won't get any error in ftp_done()
+ * because we didn't transfer the any file */
+ ftp->transfer = FTPTRANSFER_NONE;
+ state(conn, FTP_STOP);
+ return CURLE_OK;
+ }
+
+ /* Set resume file transfer offset */
+ infof(data, "Instructs server to resume from offset %"
+ CURL_FORMAT_CURL_OFF_T "\n", data->state.resume_from);
+
+ PPSENDF(&ftpc->pp, "REST %" CURL_FORMAT_CURL_OFF_T,
+ data->state.resume_from);
+
+ state(conn, FTP_RETR_REST);
+ }
+ else {
+ /* no resume */
+ PPSENDF(&ftpc->pp, "RETR %s", ftpc->file);
+ state(conn, FTP_RETR);
+ }
+
+ return result;
+}
+
+static CURLcode ftp_state_size_resp(struct connectdata *conn,
+ int ftpcode,
+ ftpstate instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data=conn->data;
+ curl_off_t filesize;
+ char *buf = data->state.buffer;
+
+ /* get the size from the ascii string: */
+ filesize = (ftpcode == 213)?curlx_strtoofft(buf+4, NULL, 0):-1;
+
+ if(instate == FTP_SIZE) {
+#ifdef CURL_FTP_HTTPSTYLE_HEAD
+ if(-1 != filesize) {
+ snprintf(buf, sizeof(data->state.buffer),
+ "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", filesize);
+ result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
+ if(result)
+ return result;
+ }
+#endif
+ Curl_pgrsSetDownloadSize(data, filesize);
+ result = ftp_state_rest(conn);
+ }
+ else if(instate == FTP_RETR_SIZE) {
+ Curl_pgrsSetDownloadSize(data, filesize);
+ result = ftp_state_retr(conn, filesize);
+ }
+ else if(instate == FTP_STOR_SIZE) {
+ data->state.resume_from = filesize;
+ result = ftp_state_ul_setup(conn, TRUE);
+ }
+
+ return result;
+}
+
+static CURLcode ftp_state_rest_resp(struct connectdata *conn,
+ int ftpcode,
+ ftpstate instate)
+{
+ CURLcode result = CURLE_OK;
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+ switch(instate) {
+ case FTP_REST:
+ default:
+#ifdef CURL_FTP_HTTPSTYLE_HEAD
+ if(ftpcode == 350) {
+ char buffer[24]= { "Accept-ranges: bytes\r\n" };
+ result = Curl_client_write(conn, CLIENTWRITE_BOTH, buffer, 0);
+ if(result)
+ return result;
+ }
+#endif
+ result = ftp_state_prepare_transfer(conn);
+ break;
+
+ case FTP_RETR_REST:
+ if(ftpcode != 350) {
+ failf(conn->data, "Couldn't use REST");
+ result = CURLE_FTP_COULDNT_USE_REST;
+ }
+ else {
+ PPSENDF(&ftpc->pp, "RETR %s", ftpc->file);
+ state(conn, FTP_RETR);
+ }
+ break;
+ }
+
+ return result;
+}
+
+static CURLcode ftp_state_stor_resp(struct connectdata *conn,
+ int ftpcode, ftpstate instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+
+ if(ftpcode>=400) {
+ failf(data, "Failed FTP upload: %0d", ftpcode);
+ state(conn, FTP_STOP);
+ /* oops, we never close the sockets! */
+ return CURLE_UPLOAD_FAILED;
+ }
+
+ conn->proto.ftpc.state_saved = instate;
+
+ /* PORT means we are now awaiting the server to connect to us. */
+ if(data->set.ftp_use_port) {
+ bool connected;
+
+ state(conn, FTP_STOP); /* no longer in STOR state */
+
+ result = AllowServerConnect(conn, &connected);
+ if(result)
+ return result;
+
+ if(!connected) {
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+ infof(data, "Data conn was not available immediately\n");
+ ftpc->wait_data_conn = TRUE;
+ }
+
+ return CURLE_OK;
+ }
+ else
+ return InitiateTransfer(conn);
+}
+
+/* for LIST and RETR responses */
+static CURLcode ftp_state_get_resp(struct connectdata *conn,
+ int ftpcode,
+ ftpstate instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct FTP *ftp = data->req.protop;
+ char *buf = data->state.buffer;
+
+ if((ftpcode == 150) || (ftpcode == 125)) {
+
+ /*
+ A;
+ 150 Opening BINARY mode data connection for /etc/passwd (2241
+ bytes). (ok, the file is being transferred)
+
+ B:
+ 150 Opening ASCII mode data connection for /bin/ls
+
+ C:
+ 150 ASCII data connection for /bin/ls (137.167.104.91,37445) (0 bytes).
+
+ D:
+ 150 Opening ASCII mode data connection for [file] (0.0.0.0,0) (545 bytes)
+
+ E:
+ 125 Data connection already open; Transfer starting. */
+
+ curl_off_t size=-1; /* default unknown size */
+
+
+ /*
+ * It appears that there are FTP-servers that return size 0 for files when
+ * SIZE is used on the file while being in BINARY mode. To work around
+ * that (stupid) behavior, we attempt to parse the RETR response even if
+ * the SIZE returned size zero.
+ *
+ * Debugging help from Salvatore Sorrentino on February 26, 2003.
+ */
+
+ if((instate != FTP_LIST) &&
+ !data->set.prefer_ascii &&
+ (ftp->downloadsize < 1)) {
+ /*
+ * It seems directory listings either don't show the size or very
+ * often uses size 0 anyway. ASCII transfers may very well turn out
+ * that the transferred amount of data is not the same as this line
+ * tells, why using this number in those cases only confuses us.
+ *
+ * Example D above makes this parsing a little tricky */
+ char *bytes;
+ bytes=strstr(buf, " bytes");
+ if(bytes--) {
+ long in=(long)(bytes-buf);
+ /* this is a hint there is size information in there! ;-) */
+ while(--in) {
+ /* scan for the left parenthesis and break there */
+ if('(' == *bytes)
+ break;
+ /* skip only digits */
+ if(!ISDIGIT(*bytes)) {
+ bytes=NULL;
+ break;
+ }
+ /* one more estep backwards */
+ bytes--;
+ }
+ /* if we have nothing but digits: */
+ if(bytes++) {
+ /* get the number! */
+ size = curlx_strtoofft(bytes, NULL, 0);
+ }
+ }
+ }
+ else if(ftp->downloadsize > -1)
+ size = ftp->downloadsize;
+
+ if(size > data->req.maxdownload && data->req.maxdownload > 0)
+ size = data->req.size = data->req.maxdownload;
+ else if((instate != FTP_LIST) && (data->set.prefer_ascii))
+ size = -1; /* kludge for servers that understate ASCII mode file size */
+
+ infof(data, "Maxdownload = %" CURL_FORMAT_CURL_OFF_T "\n",
+ data->req.maxdownload);
+
+ if(instate != FTP_LIST)
+ infof(data, "Getting file with size: %" CURL_FORMAT_CURL_OFF_T "\n",
+ size);
+
+ /* FTP download: */
+ conn->proto.ftpc.state_saved = instate;
+ conn->proto.ftpc.retr_size_saved = size;
+
+ if(data->set.ftp_use_port) {
+ bool connected;
+
+ result = AllowServerConnect(conn, &connected);
+ if(result)
+ return result;
+
+ if(!connected) {
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+ infof(data, "Data conn was not available immediately\n");
+ state(conn, FTP_STOP);
+ ftpc->wait_data_conn = TRUE;
+ }
+ }
+ else
+ return InitiateTransfer(conn);
+ }
+ else {
+ if((instate == FTP_LIST) && (ftpcode == 450)) {
+ /* simply no matching files in the dir listing */
+ ftp->transfer = FTPTRANSFER_NONE; /* don't download anything */
+ state(conn, FTP_STOP); /* this phase is over */
+ }
+ else {
+ failf(data, "RETR response: %03d", ftpcode);
+ return instate == FTP_RETR && ftpcode == 550?
+ CURLE_REMOTE_FILE_NOT_FOUND:
+ CURLE_FTP_COULDNT_RETR_FILE;
+ }
+ }
+
+ return result;
+}
+
+/* after USER, PASS and ACCT */
+static CURLcode ftp_state_loggedin(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+
+ if(conn->ssl[FIRSTSOCKET].use) {
+ /* PBSZ = PROTECTION BUFFER SIZE.
+
+ The 'draft-murray-auth-ftp-ssl' (draft 12, page 7) says:
+
+ Specifically, the PROT command MUST be preceded by a PBSZ
+ command and a PBSZ command MUST be preceded by a successful
+ security data exchange (the TLS negotiation in this case)
+
+ ... (and on page 8):
+
+ Thus the PBSZ command must still be issued, but must have a
+ parameter of '0' to indicate that no buffering is taking place
+ and the data connection should not be encapsulated.
+ */
+ PPSENDF(&conn->proto.ftpc.pp, "PBSZ %d", 0);
+ state(conn, FTP_PBSZ);
+ }
+ else {
+ result = ftp_state_pwd(conn);
+ }
+ return result;
+}
+
+/* for USER and PASS responses */
+static CURLcode ftp_state_user_resp(struct connectdata *conn,
+ int ftpcode,
+ ftpstate instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct FTP *ftp = data->req.protop;
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+ (void)instate; /* no use for this yet */
+
+ /* some need password anyway, and others just return 2xx ignored */
+ if((ftpcode == 331) && (ftpc->state == FTP_USER)) {
+ /* 331 Password required for ...
+ (the server requires to send the user's password too) */
+ PPSENDF(&ftpc->pp, "PASS %s", ftp->passwd?ftp->passwd:"");
+ state(conn, FTP_PASS);
+ }
+ else if(ftpcode/100 == 2) {
+ /* 230 User ... logged in.
+ (the user logged in with or without password) */
+ result = ftp_state_loggedin(conn);
+ }
+ else if(ftpcode == 332) {
+ if(data->set.str[STRING_FTP_ACCOUNT]) {
+ PPSENDF(&ftpc->pp, "ACCT %s", data->set.str[STRING_FTP_ACCOUNT]);
+ state(conn, FTP_ACCT);
+ }
+ else {
+ failf(data, "ACCT requested but none available");
+ result = CURLE_LOGIN_DENIED;
+ }
+ }
+ else {
+ /* All other response codes, like:
+
+ 530 User ... access denied
+ (the server denies to log the specified user) */
+
+ if(conn->data->set.str[STRING_FTP_ALTERNATIVE_TO_USER] &&
+ !conn->data->state.ftp_trying_alternative) {
+ /* Ok, USER failed. Let's try the supplied command. */
+ PPSENDF(&conn->proto.ftpc.pp, "%s",
+ conn->data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]);
+ conn->data->state.ftp_trying_alternative = TRUE;
+ state(conn, FTP_USER);
+ result = CURLE_OK;
+ }
+ else {
+ failf(data, "Access denied: %03d", ftpcode);
+ result = CURLE_LOGIN_DENIED;
+ }
+ }
+ return result;
+}
+
+/* for ACCT response */
+static CURLcode ftp_state_acct_resp(struct connectdata *conn,
+ int ftpcode)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ if(ftpcode != 230) {
+ failf(data, "ACCT rejected by server: %03d", ftpcode);
+ result = CURLE_FTP_WEIRD_PASS_REPLY; /* FIX */
+ }
+ else
+ result = ftp_state_loggedin(conn);
+
+ return result;
+}
+
+
+static CURLcode ftp_statemach_act(struct connectdata *conn)
+{
+ CURLcode result;
+ curl_socket_t sock = conn->sock[FIRSTSOCKET];
+ struct SessionHandle *data=conn->data;
+ int ftpcode;
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+ struct pingpong *pp = &ftpc->pp;
+ static const char ftpauth[][4] = { "SSL", "TLS" };
+ size_t nread = 0;
+
+ if(pp->sendleft)
+ return Curl_pp_flushsend(pp);
+
+ result = ftp_readresp(sock, pp, &ftpcode, &nread);
+ if(result)
+ return result;
+
+ if(ftpcode) {
+ /* we have now received a full FTP server response */
+ switch(ftpc->state) {
+ case FTP_WAIT220:
+ if(ftpcode == 230)
+ /* 230 User logged in - already! */
+ return ftp_state_user_resp(conn, ftpcode, ftpc->state);
+ else if(ftpcode != 220) {
+ failf(data, "Got a %03d ftp-server response when 220 was expected",
+ ftpcode);
+ return CURLE_FTP_WEIRD_SERVER_REPLY;
+ }
+
+ /* We have received a 220 response fine, now we proceed. */
+#ifdef HAVE_GSSAPI
+ if(data->set.krb) {
+ /* If not anonymous login, try a secure login. Note that this
+ procedure is still BLOCKING. */
+
+ Curl_sec_request_prot(conn, "private");
+ /* We set private first as default, in case the line below fails to
+ set a valid level */
+ Curl_sec_request_prot(conn, data->set.str[STRING_KRB_LEVEL]);
+
+ if(Curl_sec_login(conn))
+ infof(data, "Logging in with password in cleartext!\n");
+ else
+ infof(data, "Authentication successful\n");
+ }
+#endif
+
+ if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
+ /* We don't have a SSL/TLS connection yet, but FTPS is
+ requested. Try a FTPS connection now */
+
+ ftpc->count3=0;
+ switch(data->set.ftpsslauth) {
+ case CURLFTPAUTH_DEFAULT:
+ case CURLFTPAUTH_SSL:
+ ftpc->count2 = 1; /* add one to get next */
+ ftpc->count1 = 0;
+ break;
+ case CURLFTPAUTH_TLS:
+ ftpc->count2 = -1; /* subtract one to get next */
+ ftpc->count1 = 1;
+ break;
+ default:
+ failf(data, "unsupported parameter to CURLOPT_FTPSSLAUTH: %d",
+ (int)data->set.ftpsslauth);
+ return CURLE_UNKNOWN_OPTION; /* we don't know what to do */
+ }
+ PPSENDF(&ftpc->pp, "AUTH %s", ftpauth[ftpc->count1]);
+ state(conn, FTP_AUTH);
+ }
+ else {
+ result = ftp_state_user(conn);
+ if(result)
+ return result;
+ }
+
+ break;
+
+ case FTP_AUTH:
+ /* we have gotten the response to a previous AUTH command */
+
+ /* RFC2228 (page 5) says:
+ *
+ * If the server is willing to accept the named security mechanism,
+ * and does not require any security data, it must respond with
+ * reply code 234/334.
+ */
+
+ if((ftpcode == 234) || (ftpcode == 334)) {
+ /* Curl_ssl_connect is BLOCKING */
+ result = Curl_ssl_connect(conn, FIRSTSOCKET);
+ if(!result) {
+ conn->ssl[SECONDARYSOCKET].use = FALSE; /* clear-text data */
+ result = ftp_state_user(conn);
+ }
+ }
+ else if(ftpc->count3 < 1) {
+ ftpc->count3++;
+ ftpc->count1 += ftpc->count2; /* get next attempt */
+ result = Curl_pp_sendf(&ftpc->pp, "AUTH %s", ftpauth[ftpc->count1]);
+ /* remain in this same state */
+ }
+ else {
+ if(data->set.use_ssl > CURLUSESSL_TRY)
+ /* we failed and CURLUSESSL_CONTROL or CURLUSESSL_ALL is set */
+ result = CURLE_USE_SSL_FAILED;
+ else
+ /* ignore the failure and continue */
+ result = ftp_state_user(conn);
+ }
+
+ if(result)
+ return result;
+ break;
+
+ case FTP_USER:
+ case FTP_PASS:
+ result = ftp_state_user_resp(conn, ftpcode, ftpc->state);
+ break;
+
+ case FTP_ACCT:
+ result = ftp_state_acct_resp(conn, ftpcode);
+ break;
+
+ case FTP_PBSZ:
+ PPSENDF(&ftpc->pp, "PROT %c",
+ data->set.use_ssl == CURLUSESSL_CONTROL ? 'C' : 'P');
+ state(conn, FTP_PROT);
+
+ break;
+
+ case FTP_PROT:
+ if(ftpcode/100 == 2)
+ /* We have enabled SSL for the data connection! */
+ conn->ssl[SECONDARYSOCKET].use =
+ (data->set.use_ssl != CURLUSESSL_CONTROL) ? TRUE : FALSE;
+ /* FTP servers typically responds with 500 if they decide to reject
+ our 'P' request */
+ else if(data->set.use_ssl > CURLUSESSL_CONTROL)
+ /* we failed and bails out */
+ return CURLE_USE_SSL_FAILED;
+
+ if(data->set.ftp_ccc) {
+ /* CCC - Clear Command Channel
+ */
+ PPSENDF(&ftpc->pp, "%s", "CCC");
+ state(conn, FTP_CCC);
+ }
+ else {
+ result = ftp_state_pwd(conn);
+ if(result)
+ return result;
+ }
+ break;
+
+ case FTP_CCC:
+ if(ftpcode < 500) {
+ /* First shut down the SSL layer (note: this call will block) */
+ result = Curl_ssl_shutdown(conn, FIRSTSOCKET);
+
+ if(result) {
+ failf(conn->data, "Failed to clear the command channel (CCC)");
+ return result;
+ }
+ }
+
+ /* Then continue as normal */
+ result = ftp_state_pwd(conn);
+ if(result)
+ return result;
+ break;
+
+ case FTP_PWD:
+ if(ftpcode == 257) {
+ char *ptr=&data->state.buffer[4]; /* start on the first letter */
+ char *dir;
+ char *store;
+
+ dir = malloc(nread + 1);
+ if(!dir)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Reply format is like
+ 257<space>[rubbish]"<directory-name>"<space><commentary> and the
+ RFC959 says
+
+ The directory name can contain any character; embedded
+ double-quotes should be escaped by double-quotes (the
+ "quote-doubling" convention).
+ */
+
+ /* scan for the first double-quote for non-standard responses */
+ while(ptr < &data->state.buffer[sizeof(data->state.buffer)]
+ && *ptr != '\n' && *ptr != '\0' && *ptr != '"')
+ ptr++;
+
+ if('\"' == *ptr) {
+ /* it started good */
+ ptr++;
+ for(store = dir; *ptr;) {
+ if('\"' == *ptr) {
+ if('\"' == ptr[1]) {
+ /* "quote-doubling" */
+ *store = ptr[1];
+ ptr++;
+ }
+ else {
+ /* end of path */
+ *store = '\0'; /* zero terminate */
+ break; /* get out of this loop */
+ }
+ }
+ else
+ *store = *ptr;
+ store++;
+ ptr++;
+ }
+
+ /* If the path name does not look like an absolute path (i.e.: it
+ does not start with a '/'), we probably need some server-dependent
+ adjustments. For example, this is the case when connecting to
+ an OS400 FTP server: this server supports two name syntaxes,
+ the default one being incompatible with standard pathes. In
+ addition, this server switches automatically to the regular path
+ syntax when one is encountered in a command: this results in
+ having an entrypath in the wrong syntax when later used in CWD.
+ The method used here is to check the server OS: we do it only
+ if the path name looks strange to minimize overhead on other
+ systems. */
+
+ if(!ftpc->server_os && dir[0] != '/') {
+
+ result = Curl_pp_sendf(&ftpc->pp, "%s", "SYST");
+ if(result) {
+ free(dir);
+ return result;
+ }
+ Curl_safefree(ftpc->entrypath);
+ ftpc->entrypath = dir; /* remember this */
+ infof(data, "Entry path is '%s'\n", ftpc->entrypath);
+ /* also save it where getinfo can access it: */
+ data->state.most_recent_ftp_entrypath = ftpc->entrypath;
+ state(conn, FTP_SYST);
+ break;
+ }
+
+ Curl_safefree(ftpc->entrypath);
+ ftpc->entrypath = dir; /* remember this */
+ infof(data, "Entry path is '%s'\n", ftpc->entrypath);
+ /* also save it where getinfo can access it: */
+ data->state.most_recent_ftp_entrypath = ftpc->entrypath;
+ }
+ else {
+ /* couldn't get the path */
+ free(dir);
+ infof(data, "Failed to figure out path\n");
+ }
+ }
+ state(conn, FTP_STOP); /* we are done with the CONNECT phase! */
+ DEBUGF(infof(data, "protocol connect phase DONE\n"));
+ break;
+
+ case FTP_SYST:
+ if(ftpcode == 215) {
+ char *ptr=&data->state.buffer[4]; /* start on the first letter */
+ char *os;
+ char *store;
+
+ os = malloc(nread + 1);
+ if(!os)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Reply format is like
+ 215<space><OS-name><space><commentary>
+ */
+ while(*ptr == ' ')
+ ptr++;
+ for(store = os; *ptr && *ptr != ' ';)
+ *store++ = *ptr++;
+ *store = '\0'; /* zero terminate */
+
+ /* Check for special servers here. */
+
+ if(strequal(os, "OS/400")) {
+ /* Force OS400 name format 1. */
+ result = Curl_pp_sendf(&ftpc->pp, "%s", "SITE NAMEFMT 1");
+ if(result) {
+ free(os);
+ return result;
+ }
+ /* remember target server OS */
+ Curl_safefree(ftpc->server_os);
+ ftpc->server_os = os;
+ state(conn, FTP_NAMEFMT);
+ break;
+ }
+ else {
+ /* Nothing special for the target server. */
+ /* remember target server OS */
+ Curl_safefree(ftpc->server_os);
+ ftpc->server_os = os;
+ }
+ }
+ else {
+ /* Cannot identify server OS. Continue anyway and cross fingers. */
+ }
+
+ state(conn, FTP_STOP); /* we are done with the CONNECT phase! */
+ DEBUGF(infof(data, "protocol connect phase DONE\n"));
+ break;
+
+ case FTP_NAMEFMT:
+ if(ftpcode == 250) {
+ /* Name format change successful: reload initial path. */
+ ftp_state_pwd(conn);
+ break;
+ }
+
+ state(conn, FTP_STOP); /* we are done with the CONNECT phase! */
+ DEBUGF(infof(data, "protocol connect phase DONE\n"));
+ break;
+
+ case FTP_QUOTE:
+ case FTP_POSTQUOTE:
+ case FTP_RETR_PREQUOTE:
+ case FTP_STOR_PREQUOTE:
+ if((ftpcode >= 400) && !ftpc->count2) {
+ /* failure response code, and not allowed to fail */
+ failf(conn->data, "QUOT command failed with %03d", ftpcode);
+ return CURLE_QUOTE_ERROR;
+ }
+ result = ftp_state_quote(conn, FALSE, ftpc->state);
+ if(result)
+ return result;
+
+ break;
+
+ case FTP_CWD:
+ if(ftpcode/100 != 2) {
+ /* failure to CWD there */
+ if(conn->data->set.ftp_create_missing_dirs &&
+ ftpc->count1 && !ftpc->count2) {
+ /* try making it */
+ ftpc->count2++; /* counter to prevent CWD-MKD loops */
+ PPSENDF(&ftpc->pp, "MKD %s", ftpc->dirs[ftpc->count1 - 1]);
+ state(conn, FTP_MKD);
+ }
+ else {
+ /* return failure */
+ failf(data, "Server denied you to change to the given directory");
+ ftpc->cwdfail = TRUE; /* don't remember this path as we failed
+ to enter it */
+ return CURLE_REMOTE_ACCESS_DENIED;
+ }
+ }
+ else {
+ /* success */
+ ftpc->count2=0;
+ if(++ftpc->count1 <= ftpc->dirdepth) {
+ /* send next CWD */
+ PPSENDF(&ftpc->pp, "CWD %s", ftpc->dirs[ftpc->count1 - 1]);
+ }
+ else {
+ result = ftp_state_mdtm(conn);
+ if(result)
+ return result;
+ }
+ }
+ break;
+
+ case FTP_MKD:
+ if((ftpcode/100 != 2) && !ftpc->count3--) {
+ /* failure to MKD the dir */
+ failf(data, "Failed to MKD dir: %03d", ftpcode);
+ return CURLE_REMOTE_ACCESS_DENIED;
+ }
+ state(conn, FTP_CWD);
+ /* send CWD */
+ PPSENDF(&ftpc->pp, "CWD %s", ftpc->dirs[ftpc->count1 - 1]);
+ break;
+
+ case FTP_MDTM:
+ result = ftp_state_mdtm_resp(conn, ftpcode);
+ break;
+
+ case FTP_TYPE:
+ case FTP_LIST_TYPE:
+ case FTP_RETR_TYPE:
+ case FTP_STOR_TYPE:
+ result = ftp_state_type_resp(conn, ftpcode, ftpc->state);
+ break;
+
+ case FTP_SIZE:
+ case FTP_RETR_SIZE:
+ case FTP_STOR_SIZE:
+ result = ftp_state_size_resp(conn, ftpcode, ftpc->state);
+ break;
+
+ case FTP_REST:
+ case FTP_RETR_REST:
+ result = ftp_state_rest_resp(conn, ftpcode, ftpc->state);
+ break;
+
+ case FTP_PRET:
+ if(ftpcode != 200) {
+ /* there only is this one standard OK return code. */
+ failf(data, "PRET command not accepted: %03d", ftpcode);
+ return CURLE_FTP_PRET_FAILED;
+ }
+ result = ftp_state_use_pasv(conn);
+ break;
+
+ case FTP_PASV:
+ result = ftp_state_pasv_resp(conn, ftpcode);
+ break;
+
+ case FTP_PORT:
+ result = ftp_state_port_resp(conn, ftpcode);
+ break;
+
+ case FTP_LIST:
+ case FTP_RETR:
+ result = ftp_state_get_resp(conn, ftpcode, ftpc->state);
+ break;
+
+ case FTP_STOR:
+ result = ftp_state_stor_resp(conn, ftpcode, ftpc->state);
+ break;
+
+ case FTP_QUIT:
+ /* fallthrough, just stop! */
+ default:
+ /* internal error */
+ state(conn, FTP_STOP);
+ break;
+ }
+ } /* if(ftpcode) */
+
+ return result;
+}
+
+
+/* called repeatedly until done from multi.c */
+static CURLcode ftp_multi_statemach(struct connectdata *conn,
+ bool *done)
+{
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+ CURLcode result = Curl_pp_statemach(&ftpc->pp, FALSE);
+
+ /* Check for the state outside of the Curl_socket_ready() return code checks
+ since at times we are in fact already in this state when this function
+ gets called. */
+ *done = (ftpc->state == FTP_STOP) ? TRUE : FALSE;
+
+ return result;
+}
+
+static CURLcode ftp_block_statemach(struct connectdata *conn)
+{
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+ struct pingpong *pp = &ftpc->pp;
+ CURLcode result = CURLE_OK;
+
+ while(ftpc->state != FTP_STOP) {
+ result = Curl_pp_statemach(pp, TRUE);
+ if(result)
+ break;
+ }
+
+ return result;
+}
+
+/*
+ * ftp_connect() should do everything that is to be considered a part of
+ * the connection phase.
+ *
+ * The variable 'done' points to will be TRUE if the protocol-layer connect
+ * phase is done when this function returns, or FALSE if not.
+ *
+ */
+static CURLcode ftp_connect(struct connectdata *conn,
+ bool *done) /* see description above */
+{
+ CURLcode result;
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+ struct pingpong *pp = &ftpc->pp;
+
+ *done = FALSE; /* default to not done yet */
+
+ /* We always support persistent connections on ftp */
+ connkeep(conn, "FTP default");
+
+ pp->response_time = RESP_TIMEOUT; /* set default response time-out */
+ pp->statemach_act = ftp_statemach_act;
+ pp->endofresp = ftp_endofresp;
+ pp->conn = conn;
+
+ if(conn->handler->flags & PROTOPT_SSL) {
+ /* BLOCKING */
+ result = Curl_ssl_connect(conn, FIRSTSOCKET);
+ if(result)
+ return result;
+ }
+
+ Curl_pp_init(pp); /* init the generic pingpong data */
+
+ /* When we connect, we start in the state where we await the 220
+ response */
+ state(conn, FTP_WAIT220);
+
+ result = ftp_multi_statemach(conn, done);
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * ftp_done()
+ *
+ * The DONE function. This does what needs to be done after a single DO has
+ * performed.
+ *
+ * Input argument is already checked for validity.
+ */
+static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
+ bool premature)
+{
+ struct SessionHandle *data = conn->data;
+ struct FTP *ftp = data->req.protop;
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+ struct pingpong *pp = &ftpc->pp;
+ ssize_t nread;
+ int ftpcode;
+ CURLcode result = CURLE_OK;
+ bool was_ctl_valid = ftpc->ctl_valid;
+ char *path;
+ const char *path_to_use = data->state.path;
+
+ if(!ftp)
+ /* When the easy handle is removed from the multi while libcurl is still
+ * trying to resolve the host name, it seems that the ftp struct is not
+ * yet initialized, but the removal action calls Curl_done() which calls
+ * this function. So we simply return success if no ftp pointer is set.
+ */
+ return CURLE_OK;
+
+ switch(status) {
+ case CURLE_BAD_DOWNLOAD_RESUME:
+ case CURLE_FTP_WEIRD_PASV_REPLY:
+ case CURLE_FTP_PORT_FAILED:
+ case CURLE_FTP_ACCEPT_FAILED:
+ case CURLE_FTP_ACCEPT_TIMEOUT:
+ case CURLE_FTP_COULDNT_SET_TYPE:
+ case CURLE_FTP_COULDNT_RETR_FILE:
+ case CURLE_PARTIAL_FILE:
+ case CURLE_UPLOAD_FAILED:
+ case CURLE_REMOTE_ACCESS_DENIED:
+ case CURLE_FILESIZE_EXCEEDED:
+ case CURLE_REMOTE_FILE_NOT_FOUND:
+ case CURLE_WRITE_ERROR:
+ /* the connection stays alive fine even though this happened */
+ /* fall-through */
+ case CURLE_OK: /* doesn't affect the control connection's status */
+ if(!premature) {
+ ftpc->ctl_valid = was_ctl_valid;
+ break;
+ }
+ /* until we cope better with prematurely ended requests, let them
+ * fallback as if in complete failure */
+ default: /* by default, an error means the control connection is
+ wedged and should not be used anymore */
+ ftpc->ctl_valid = FALSE;
+ ftpc->cwdfail = TRUE; /* set this TRUE to prevent us to remember the
+ current path, as this connection is going */
+ connclose(conn, "FTP ended with bad error code");
+ result = status; /* use the already set error code */
+ break;
+ }
+
+ /* now store a copy of the directory we are in */
+ free(ftpc->prevpath);
+
+ if(data->set.wildcardmatch) {
+ if(data->set.chunk_end && ftpc->file) {
+ data->set.chunk_end(data->wildcard.customptr);
+ }
+ ftpc->known_filesize = -1;
+ }
+
+ /* get the "raw" path */
+ path = curl_easy_unescape(data, path_to_use, 0, NULL);
+ if(!path) {
+ /* out of memory, but we can limp along anyway (and should try to
+ * since we may already be in the out of memory cleanup path) */
+ if(!result)
+ result = CURLE_OUT_OF_MEMORY;
+ ftpc->ctl_valid = FALSE; /* mark control connection as bad */
+ connclose(conn, "FTP: out of memory!"); /* mark for connection closure */
+ ftpc->prevpath = NULL; /* no path remembering */
+ }
+ else {
+ size_t flen = ftpc->file?strlen(ftpc->file):0; /* file is "raw" already */
+ size_t dlen = strlen(path)-flen;
+ if(!ftpc->cwdfail) {
+ if(dlen && (data->set.ftp_filemethod != FTPFILE_NOCWD)) {
+ ftpc->prevpath = path;
+ if(flen)
+ /* if 'path' is not the whole string */
+ ftpc->prevpath[dlen]=0; /* terminate */
+ }
+ else {
+ /* we never changed dir */
+ ftpc->prevpath=strdup("");
+ free(path);
+ }
+ if(ftpc->prevpath)
+ infof(data, "Remembering we are in dir \"%s\"\n", ftpc->prevpath);
+ }
+ else {
+ ftpc->prevpath = NULL; /* no path */
+ free(path);
+ }
+ }
+ /* free the dir tree and file parts */
+ freedirs(ftpc);
+
+ /* shut down the socket to inform the server we're done */
+
+#ifdef _WIN32_WCE
+ shutdown(conn->sock[SECONDARYSOCKET], 2); /* SD_BOTH */
+#endif
+
+ if(conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD) {
+ if(!result && ftpc->dont_check && data->req.maxdownload > 0) {
+ /* partial download completed */
+ result = Curl_pp_sendf(pp, "%s", "ABOR");
+ if(result) {
+ failf(data, "Failure sending ABOR command: %s",
+ curl_easy_strerror(result));
+ ftpc->ctl_valid = FALSE; /* mark control connection as bad */
+ connclose(conn, "ABOR command failed"); /* connection closure */
+ }
+ }
+
+ if(conn->ssl[SECONDARYSOCKET].use) {
+ /* The secondary socket is using SSL so we must close down that part
+ first before we close the socket for real */
+ Curl_ssl_close(conn, SECONDARYSOCKET);
+
+ /* Note that we keep "use" set to TRUE since that (next) connection is
+ still requested to use SSL */
+ }
+ if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) {
+ Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
+ conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
+ conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE;
+ }
+ }
+
+ if(!result && (ftp->transfer == FTPTRANSFER_BODY) && ftpc->ctl_valid &&
+ pp->pending_resp && !premature) {
+ /*
+ * Let's see what the server says about the transfer we just performed,
+ * but lower the timeout as sometimes this connection has died while the
+ * data has been transferred. This happens when doing through NATs etc that
+ * abandon old silent connections.
+ */
+ long old_time = pp->response_time;
+
+ pp->response_time = 60*1000; /* give it only a minute for now */
+ pp->response = Curl_tvnow(); /* timeout relative now */
+
+ result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+
+ pp->response_time = old_time; /* set this back to previous value */
+
+ if(!nread && (CURLE_OPERATION_TIMEDOUT == result)) {
+ failf(data, "control connection looks dead");
+ ftpc->ctl_valid = FALSE; /* mark control connection as bad */
+ connclose(conn, "Timeout or similar in FTP DONE operation"); /* close */
+ }
+
+ if(result)
+ return result;
+
+ if(ftpc->dont_check && data->req.maxdownload > 0) {
+ /* we have just sent ABOR and there is no reliable way to check if it was
+ * successful or not; we have to close the connection now */
+ infof(data, "partial download completed, closing connection\n");
+ connclose(conn, "Partial download with no ability to check");
+ return result;
+ }
+
+ if(!ftpc->dont_check) {
+ /* 226 Transfer complete, 250 Requested file action okay, completed. */
+ if((ftpcode != 226) && (ftpcode != 250)) {
+ failf(data, "server did not report OK, got %d", ftpcode);
+ result = CURLE_PARTIAL_FILE;
+ }
+ }
+ }
+
+ if(result || premature)
+ /* the response code from the transfer showed an error already so no
+ use checking further */
+ ;
+ else if(data->set.upload) {
+ if((-1 != data->state.infilesize) &&
+ (data->state.infilesize != *ftp->bytecountp) &&
+ !data->set.crlf &&
+ (ftp->transfer == FTPTRANSFER_BODY)) {
+ failf(data, "Uploaded unaligned file size (%" CURL_FORMAT_CURL_OFF_T
+ " out of %" CURL_FORMAT_CURL_OFF_T " bytes)",
+ *ftp->bytecountp, data->state.infilesize);
+ result = CURLE_PARTIAL_FILE;
+ }
+ }
+ else {
+ if((-1 != data->req.size) &&
+ (data->req.size != *ftp->bytecountp) &&
+#ifdef CURL_DO_LINEEND_CONV
+ /* Most FTP servers don't adjust their file SIZE response for CRLFs, so
+ * we'll check to see if the discrepancy can be explained by the number
+ * of CRLFs we've changed to LFs.
+ */
+ ((data->req.size + data->state.crlf_conversions) !=
+ *ftp->bytecountp) &&
+#endif /* CURL_DO_LINEEND_CONV */
+ (data->req.maxdownload != *ftp->bytecountp)) {
+ failf(data, "Received only partial file: %" CURL_FORMAT_CURL_OFF_T
+ " bytes", *ftp->bytecountp);
+ result = CURLE_PARTIAL_FILE;
+ }
+ else if(!ftpc->dont_check &&
+ !*ftp->bytecountp &&
+ (data->req.size>0)) {
+ failf(data, "No data was received!");
+ result = CURLE_FTP_COULDNT_RETR_FILE;
+ }
+ }
+
+ /* clear these for next connection */
+ ftp->transfer = FTPTRANSFER_BODY;
+ ftpc->dont_check = FALSE;
+
+ /* Send any post-transfer QUOTE strings? */
+ if(!status && !result && !premature && data->set.postquote)
+ result = ftp_sendquote(conn, data->set.postquote);
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * ftp_sendquote()
+ *
+ * Where a 'quote' means a list of custom commands to send to the server.
+ * The quote list is passed as an argument.
+ *
+ * BLOCKING
+ */
+
+static
+CURLcode ftp_sendquote(struct connectdata *conn, struct curl_slist *quote)
+{
+ struct curl_slist *item;
+ ssize_t nread;
+ int ftpcode;
+ CURLcode result;
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+ struct pingpong *pp = &ftpc->pp;
+
+ item = quote;
+ while(item) {
+ if(item->data) {
+ char *cmd = item->data;
+ bool acceptfail = FALSE;
+
+ /* if a command starts with an asterisk, which a legal FTP command never
+ can, the command will be allowed to fail without it causing any
+ aborts or cancels etc. It will cause libcurl to act as if the command
+ is successful, whatever the server reponds. */
+
+ if(cmd[0] == '*') {
+ cmd++;
+ acceptfail = TRUE;
+ }
+
+ PPSENDF(&conn->proto.ftpc.pp, "%s", cmd);
+
+ pp->response = Curl_tvnow(); /* timeout relative now */
+
+ result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+ if(result)
+ return result;
+
+ if(!acceptfail && (ftpcode >= 400)) {
+ failf(conn->data, "QUOT string not accepted: %s", cmd);
+ return CURLE_QUOTE_ERROR;
+ }
+ }
+
+ item = item->next;
+ }
+
+ return CURLE_OK;
+}
+
+/***********************************************************************
+ *
+ * ftp_need_type()
+ *
+ * Returns TRUE if we in the current situation should send TYPE
+ */
+static int ftp_need_type(struct connectdata *conn,
+ bool ascii_wanted)
+{
+ return conn->proto.ftpc.transfertype != (ascii_wanted?'A':'I');
+}
+
+/***********************************************************************
+ *
+ * ftp_nb_type()
+ *
+ * Set TYPE. We only deal with ASCII or BINARY so this function
+ * sets one of them.
+ * If the transfer type is not sent, simulate on OK response in newstate
+ */
+static CURLcode ftp_nb_type(struct connectdata *conn,
+ bool ascii, ftpstate newstate)
+{
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+ CURLcode result;
+ char want = (char)(ascii?'A':'I');
+
+ if(ftpc->transfertype == want) {
+ state(conn, newstate);
+ return ftp_state_type_resp(conn, 200, newstate);
+ }
+
+ PPSENDF(&ftpc->pp, "TYPE %c", want);
+ state(conn, newstate);
+
+ /* keep track of our current transfer type */
+ ftpc->transfertype = want;
+ return CURLE_OK;
+}
+
+/***************************************************************************
+ *
+ * ftp_pasv_verbose()
+ *
+ * This function only outputs some informationals about this second connection
+ * when we've issued a PASV command before and thus we have connected to a
+ * possibly new IP address.
+ *
+ */
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+static void
+ftp_pasv_verbose(struct connectdata *conn,
+ Curl_addrinfo *ai,
+ char *newhost, /* ascii version */
+ int port)
+{
+ char buf[256];
+ Curl_printable_address(ai, buf, sizeof(buf));
+ infof(conn->data, "Connecting to %s (%s) port %d\n", newhost, buf, port);
+}
+#endif
+
+/*
+ Check if this is a range download, and if so, set the internal variables
+ properly.
+ */
+
+static CURLcode ftp_range(struct connectdata *conn)
+{
+ curl_off_t from, to;
+ char *ptr;
+ char *ptr2;
+ struct SessionHandle *data = conn->data;
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+ if(data->state.use_range && data->state.range) {
+ from=curlx_strtoofft(data->state.range, &ptr, 0);
+ while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
+ ptr++;
+ to=curlx_strtoofft(ptr, &ptr2, 0);
+ if(ptr == ptr2) {
+ /* we didn't get any digit */
+ to=-1;
+ }
+ if((-1 == to) && (from>=0)) {
+ /* X - */
+ data->state.resume_from = from;
+ DEBUGF(infof(conn->data, "FTP RANGE %" CURL_FORMAT_CURL_OFF_T
+ " to end of file\n", from));
+ }
+ else if(from < 0) {
+ /* -Y */
+ data->req.maxdownload = -from;
+ data->state.resume_from = from;
+ DEBUGF(infof(conn->data, "FTP RANGE the last %" CURL_FORMAT_CURL_OFF_T
+ " bytes\n", -from));
+ }
+ else {
+ /* X-Y */
+ data->req.maxdownload = (to-from)+1; /* include last byte */
+ data->state.resume_from = from;
+ DEBUGF(infof(conn->data, "FTP RANGE from %" CURL_FORMAT_CURL_OFF_T
+ " getting %" CURL_FORMAT_CURL_OFF_T " bytes\n",
+ from, data->req.maxdownload));
+ }
+ DEBUGF(infof(conn->data, "range-download from %" CURL_FORMAT_CURL_OFF_T
+ " to %" CURL_FORMAT_CURL_OFF_T ", totally %"
+ CURL_FORMAT_CURL_OFF_T " bytes\n",
+ from, to, data->req.maxdownload));
+ ftpc->dont_check = TRUE; /* dont check for successful transfer */
+ }
+ else
+ data->req.maxdownload = -1;
+ return CURLE_OK;
+}
+
+
+/*
+ * ftp_do_more()
+ *
+ * This function shall be called when the second FTP (data) connection is
+ * connected.
+ *
+ * 'complete' can return 0 for incomplete, 1 for done and -1 for go back
+ * (which basically is only for when PASV is being sent to retry a failed
+ * EPSV).
+ */
+
+static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
+{
+ struct SessionHandle *data=conn->data;
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+ CURLcode result = CURLE_OK;
+ bool connected = FALSE;
+ bool complete = FALSE;
+
+ /* the ftp struct is inited in ftp_connect() */
+ struct FTP *ftp = data->req.protop;
+
+ /* if the second connection isn't done yet, wait for it */
+ if(!conn->bits.tcpconnect[SECONDARYSOCKET]) {
+ if(conn->tunnel_state[SECONDARYSOCKET] == TUNNEL_CONNECT) {
+ /* As we're in TUNNEL_CONNECT state now, we know the proxy name and port
+ aren't used so we blank their arguments. TODO: make this nicer */
+ result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, NULL, 0, FALSE);
+
+ return result;
+ }
+
+ result = Curl_is_connected(conn, SECONDARYSOCKET, &connected);
+
+ /* Ready to do more? */
+ if(connected) {
+ DEBUGF(infof(data, "DO-MORE connected phase starts\n"));
+ if(conn->bits.proxy) {
+ infof(data, "Connection to proxy confirmed\n");
+ result = proxy_magic(conn, ftpc->newhost, ftpc->newport, &connected);
+ }
+ }
+ else {
+ if(result && (ftpc->count1 == 0)) {
+ *completep = -1; /* go back to DOING please */
+ /* this is a EPSV connect failing, try PASV instead */
+ return ftp_epsv_disable(conn);
+ }
+ return result;
+ }
+ }
+
+ if(ftpc->state) {
+ /* already in a state so skip the intial commands.
+ They are only done to kickstart the do_more state */
+ result = ftp_multi_statemach(conn, &complete);
+
+ *completep = (int)complete;
+
+ /* if we got an error or if we don't wait for a data connection return
+ immediately */
+ if(result || (ftpc->wait_data_conn != TRUE))
+ return result;
+
+ if(ftpc->wait_data_conn)
+ /* if we reach the end of the FTP state machine here, *complete will be
+ TRUE but so is ftpc->wait_data_conn, which says we need to wait for
+ the data connection and therefore we're not actually complete */
+ *completep = 0;
+ }
+
+ if(ftp->transfer <= FTPTRANSFER_INFO) {
+ /* a transfer is about to take place, or if not a file name was given
+ so we'll do a SIZE on it later and then we need the right TYPE first */
+
+ if(ftpc->wait_data_conn == TRUE) {
+ bool serv_conned;
+
+ result = ReceivedServerConnect(conn, &serv_conned);
+ if(result)
+ return result; /* Failed to accept data connection */
+
+ if(serv_conned) {
+ /* It looks data connection is established */
+ result = AcceptServerConnect(conn);
+ ftpc->wait_data_conn = FALSE;
+ if(!result)
+ result = InitiateTransfer(conn);
+
+ if(result)
+ return result;
+
+ *completep = 1; /* this state is now complete when the server has
+ connected back to us */
+ }
+ }
+ else if(data->set.upload) {
+ result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_STOR_TYPE);
+ if(result)
+ return result;
+
+ result = ftp_multi_statemach(conn, &complete);
+ *completep = (int)complete;
+ }
+ else {
+ /* download */
+ ftp->downloadsize = -1; /* unknown as of yet */
+
+ result = ftp_range(conn);
+ if(result)
+ ;
+ else if(data->set.ftp_list_only || !ftpc->file) {
+ /* The specified path ends with a slash, and therefore we think this
+ is a directory that is requested, use LIST. But before that we
+ need to set ASCII transfer mode. */
+
+ /* But only if a body transfer was requested. */
+ if(ftp->transfer == FTPTRANSFER_BODY) {
+ result = ftp_nb_type(conn, TRUE, FTP_LIST_TYPE);
+ if(result)
+ return result;
+ }
+ /* otherwise just fall through */
+ }
+ else {
+ result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_RETR_TYPE);
+ if(result)
+ return result;
+ }
+
+ result = ftp_multi_statemach(conn, &complete);
+ *completep = (int)complete;
+ }
+ return result;
+ }
+
+ if(!result && (ftp->transfer != FTPTRANSFER_BODY))
+ /* no data to transfer. FIX: it feels like a kludge to have this here
+ too! */
+ Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+
+ if(!ftpc->wait_data_conn) {
+ /* no waiting for the data connection so this is now complete */
+ *completep = 1;
+ DEBUGF(infof(data, "DO-MORE phase ends with %d\n", (int)result));
+ }
+
+ return result;
+}
+
+
+
+/***********************************************************************
+ *
+ * ftp_perform()
+ *
+ * This is the actual DO function for FTP. Get a file/directory according to
+ * the options previously setup.
+ */
+
+static
+CURLcode ftp_perform(struct connectdata *conn,
+ bool *connected, /* connect status after PASV / PORT */
+ bool *dophase_done)
+{
+ /* this is FTP and no proxy */
+ CURLcode result=CURLE_OK;
+
+ DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+ if(conn->data->set.opt_no_body) {
+ /* requested no body means no transfer... */
+ struct FTP *ftp = conn->data->req.protop;
+ ftp->transfer = FTPTRANSFER_INFO;
+ }
+
+ *dophase_done = FALSE; /* not done yet */
+
+ /* start the first command in the DO phase */
+ result = ftp_state_quote(conn, TRUE, FTP_QUOTE);
+ if(result)
+ return result;
+
+ /* run the state-machine */
+ result = ftp_multi_statemach(conn, dophase_done);
+
+ *connected = conn->bits.tcpconnect[SECONDARYSOCKET];
+
+ infof(conn->data, "ftp_perform ends with SECONDARY: %d\n", *connected);
+
+ if(*dophase_done) {
+ DEBUGF(infof(conn->data, "DO phase is complete1\n"));
+ }
+
+ return result;
+}
+
+static void wc_data_dtor(void *ptr)
+{
+ struct ftp_wc_tmpdata *tmp = ptr;
+ if(tmp)
+ Curl_ftp_parselist_data_free(&tmp->parser);
+ free(tmp);
+}
+
+static CURLcode init_wc_data(struct connectdata *conn)
+{
+ char *last_slash;
+ char *path = conn->data->state.path;
+ struct WildcardData *wildcard = &(conn->data->wildcard);
+ CURLcode result = CURLE_OK;
+ struct ftp_wc_tmpdata *ftp_tmp;
+
+ last_slash = strrchr(conn->data->state.path, '/');
+ if(last_slash) {
+ last_slash++;
+ if(last_slash[0] == '\0') {
+ wildcard->state = CURLWC_CLEAN;
+ result = ftp_parse_url_path(conn);
+ return result;
+ }
+ else {
+ wildcard->pattern = strdup(last_slash);
+ if(!wildcard->pattern)
+ return CURLE_OUT_OF_MEMORY;
+ last_slash[0] = '\0'; /* cut file from path */
+ }
+ }
+ else { /* there is only 'wildcard pattern' or nothing */
+ if(path[0]) {
+ wildcard->pattern = strdup(path);
+ if(!wildcard->pattern)
+ return CURLE_OUT_OF_MEMORY;
+ path[0] = '\0';
+ }
+ else { /* only list */
+ wildcard->state = CURLWC_CLEAN;
+ result = ftp_parse_url_path(conn);
+ return result;
+ }
+ }
+
+ /* program continues only if URL is not ending with slash, allocate needed
+ resources for wildcard transfer */
+
+ /* allocate ftp protocol specific temporary wildcard data */
+ ftp_tmp = calloc(1, sizeof(struct ftp_wc_tmpdata));
+ if(!ftp_tmp) {
+ Curl_safefree(wildcard->pattern);
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ /* INITIALIZE parselist structure */
+ ftp_tmp->parser = Curl_ftp_parselist_data_alloc();
+ if(!ftp_tmp->parser) {
+ Curl_safefree(wildcard->pattern);
+ free(ftp_tmp);
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ wildcard->tmp = ftp_tmp; /* put it to the WildcardData tmp pointer */
+ wildcard->tmp_dtor = wc_data_dtor;
+
+ /* wildcard does not support NOCWD option (assert it?) */
+ if(conn->data->set.ftp_filemethod == FTPFILE_NOCWD)
+ conn->data->set.ftp_filemethod = FTPFILE_MULTICWD;
+
+ /* try to parse ftp url */
+ result = ftp_parse_url_path(conn);
+ if(result) {
+ Curl_safefree(wildcard->pattern);
+ wildcard->tmp_dtor(wildcard->tmp);
+ wildcard->tmp_dtor = ZERO_NULL;
+ wildcard->tmp = NULL;
+ return result;
+ }
+
+ wildcard->path = strdup(conn->data->state.path);
+ if(!wildcard->path) {
+ Curl_safefree(wildcard->pattern);
+ wildcard->tmp_dtor(wildcard->tmp);
+ wildcard->tmp_dtor = ZERO_NULL;
+ wildcard->tmp = NULL;
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ /* backup old write_function */
+ ftp_tmp->backup.write_function = conn->data->set.fwrite_func;
+ /* parsing write function */
+ conn->data->set.fwrite_func = Curl_ftp_parselist;
+ /* backup old file descriptor */
+ ftp_tmp->backup.file_descriptor = conn->data->set.out;
+ /* let the writefunc callback know what curl pointer is working with */
+ conn->data->set.out = conn;
+
+ infof(conn->data, "Wildcard - Parsing started\n");
+ return CURLE_OK;
+}
+
+/* This is called recursively */
+static CURLcode wc_statemach(struct connectdata *conn)
+{
+ struct WildcardData * const wildcard = &(conn->data->wildcard);
+ CURLcode result = CURLE_OK;
+
+ switch (wildcard->state) {
+ case CURLWC_INIT:
+ result = init_wc_data(conn);
+ if(wildcard->state == CURLWC_CLEAN)
+ /* only listing! */
+ break;
+ else
+ wildcard->state = result ? CURLWC_ERROR : CURLWC_MATCHING;
+ break;
+
+ case CURLWC_MATCHING: {
+ /* In this state is LIST response successfully parsed, so lets restore
+ previous WRITEFUNCTION callback and WRITEDATA pointer */
+ struct ftp_wc_tmpdata *ftp_tmp = wildcard->tmp;
+ conn->data->set.fwrite_func = ftp_tmp->backup.write_function;
+ conn->data->set.out = ftp_tmp->backup.file_descriptor;
+ ftp_tmp->backup.write_function = ZERO_NULL;
+ ftp_tmp->backup.file_descriptor = NULL;
+ wildcard->state = CURLWC_DOWNLOADING;
+
+ if(Curl_ftp_parselist_geterror(ftp_tmp->parser)) {
+ /* error found in LIST parsing */
+ wildcard->state = CURLWC_CLEAN;
+ return wc_statemach(conn);
+ }
+ else if(wildcard->filelist->size == 0) {
+ /* no corresponding file */
+ wildcard->state = CURLWC_CLEAN;
+ return CURLE_REMOTE_FILE_NOT_FOUND;
+ }
+ return wc_statemach(conn);
+ }
+
+ case CURLWC_DOWNLOADING: {
+ /* filelist has at least one file, lets get first one */
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+ struct curl_fileinfo *finfo = wildcard->filelist->head->ptr;
+
+ char *tmp_path = aprintf("%s%s", wildcard->path, finfo->filename);
+ if(!tmp_path)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* switch default "state.pathbuffer" and tmp_path, good to see
+ ftp_parse_url_path function to understand this trick */
+ Curl_safefree(conn->data->state.pathbuffer);
+ conn->data->state.pathbuffer = tmp_path;
+ conn->data->state.path = tmp_path;
+
+ infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename);
+ if(conn->data->set.chunk_bgn) {
+ long userresponse = conn->data->set.chunk_bgn(
+ finfo, wildcard->customptr, (int)wildcard->filelist->size);
+ switch(userresponse) {
+ case CURL_CHUNK_BGN_FUNC_SKIP:
+ infof(conn->data, "Wildcard - \"%s\" skipped by user\n",
+ finfo->filename);
+ wildcard->state = CURLWC_SKIP;
+ return wc_statemach(conn);
+ case CURL_CHUNK_BGN_FUNC_FAIL:
+ return CURLE_CHUNK_FAILED;
+ }
+ }
+
+ if(finfo->filetype != CURLFILETYPE_FILE) {
+ wildcard->state = CURLWC_SKIP;
+ return wc_statemach(conn);
+ }
+
+ if(finfo->flags & CURLFINFOFLAG_KNOWN_SIZE)
+ ftpc->known_filesize = finfo->size;
+
+ result = ftp_parse_url_path(conn);
+ if(result)
+ return result;
+
+ /* we don't need the Curl_fileinfo of first file anymore */
+ Curl_llist_remove(wildcard->filelist, wildcard->filelist->head, NULL);
+
+ if(wildcard->filelist->size == 0) { /* remains only one file to down. */
+ wildcard->state = CURLWC_CLEAN;
+ /* after that will be ftp_do called once again and no transfer
+ will be done because of CURLWC_CLEAN state */
+ return CURLE_OK;
+ }
+ } break;
+
+ case CURLWC_SKIP: {
+ if(conn->data->set.chunk_end)
+ conn->data->set.chunk_end(conn->data->wildcard.customptr);
+ Curl_llist_remove(wildcard->filelist, wildcard->filelist->head, NULL);
+ wildcard->state = (wildcard->filelist->size == 0) ?
+ CURLWC_CLEAN : CURLWC_DOWNLOADING;
+ return wc_statemach(conn);
+ }
+
+ case CURLWC_CLEAN: {
+ struct ftp_wc_tmpdata *ftp_tmp = wildcard->tmp;
+ result = CURLE_OK;
+ if(ftp_tmp)
+ result = Curl_ftp_parselist_geterror(ftp_tmp->parser);
+
+ wildcard->state = result ? CURLWC_ERROR : CURLWC_DONE;
+ } break;
+
+ case CURLWC_DONE:
+ case CURLWC_ERROR:
+ break;
+ }
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * ftp_do()
+ *
+ * This function is registered as 'curl_do' function. It decodes the path
+ * parts etc as a wrapper to the actual DO function (ftp_perform).
+ *
+ * The input argument is already checked for validity.
+ */
+static CURLcode ftp_do(struct connectdata *conn, bool *done)
+{
+ CURLcode result = CURLE_OK;
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+ *done = FALSE; /* default to false */
+ ftpc->wait_data_conn = FALSE; /* default to no such wait */
+
+ if(conn->data->set.wildcardmatch) {
+ result = wc_statemach(conn);
+ if(conn->data->wildcard.state == CURLWC_SKIP ||
+ conn->data->wildcard.state == CURLWC_DONE) {
+ /* do not call ftp_regular_transfer */
+ return CURLE_OK;
+ }
+ if(result) /* error, loop or skipping the file */
+ return result;
+ }
+ else { /* no wildcard FSM needed */
+ result = ftp_parse_url_path(conn);
+ if(result)
+ return result;
+ }
+
+ result = ftp_regular_transfer(conn, done);
+
+ return result;
+}
+
+
+CURLcode Curl_ftpsendf(struct connectdata *conn,
+ const char *fmt, ...)
+{
+ ssize_t bytes_written;
+#define SBUF_SIZE 1024
+ char s[SBUF_SIZE];
+ size_t write_len;
+ char *sptr=s;
+ CURLcode result = CURLE_OK;
+#ifdef HAVE_GSSAPI
+ enum protection_level data_sec = conn->data_prot;
+#endif
+
+ va_list ap;
+ va_start(ap, fmt);
+ write_len = vsnprintf(s, SBUF_SIZE-3, fmt, ap);
+ va_end(ap);
+
+ strcpy(&s[write_len], "\r\n"); /* append a trailing CRLF */
+ write_len +=2;
+
+ bytes_written=0;
+
+ result = Curl_convert_to_network(conn->data, s, write_len);
+ /* Curl_convert_to_network calls failf if unsuccessful */
+ if(result)
+ return result;
+
+ for(;;) {
+#ifdef HAVE_GSSAPI
+ conn->data_prot = PROT_CMD;
+#endif
+ result = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len,
+ &bytes_written);
+#ifdef HAVE_GSSAPI
+ DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST);
+ conn->data_prot = data_sec;
+#endif
+
+ if(result)
+ break;
+
+ if(conn->data->set.verbose)
+ Curl_debug(conn->data, CURLINFO_HEADER_OUT,
+ sptr, (size_t)bytes_written, conn);
+
+ if(bytes_written != (ssize_t)write_len) {
+ write_len -= bytes_written;
+ sptr += bytes_written;
+ }
+ else
+ break;
+ }
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * ftp_quit()
+ *
+ * This should be called before calling sclose() on an ftp control connection
+ * (not data connections). We should then wait for the response from the
+ * server before returning. The calling code should then try to close the
+ * connection.
+ *
+ */
+static CURLcode ftp_quit(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+
+ if(conn->proto.ftpc.ctl_valid) {
+ result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", "QUIT");
+ if(result) {
+ failf(conn->data, "Failure sending QUIT command: %s",
+ curl_easy_strerror(result));
+ conn->proto.ftpc.ctl_valid = FALSE; /* mark control connection as bad */
+ connclose(conn, "QUIT command failed"); /* mark for connection closure */
+ state(conn, FTP_STOP);
+ return result;
+ }
+
+ state(conn, FTP_QUIT);
+
+ result = ftp_block_statemach(conn);
+ }
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * ftp_disconnect()
+ *
+ * Disconnect from an FTP server. Cleanup protocol-specific per-connection
+ * resources. BLOCKING.
+ */
+static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection)
+{
+ struct ftp_conn *ftpc= &conn->proto.ftpc;
+ struct pingpong *pp = &ftpc->pp;
+
+ /* We cannot send quit unconditionally. If this connection is stale or
+ bad in any way, sending quit and waiting around here will make the
+ disconnect wait in vain and cause more problems than we need to.
+
+ ftp_quit() will check the state of ftp->ctl_valid. If it's ok it
+ will try to send the QUIT command, otherwise it will just return.
+ */
+ if(dead_connection)
+ ftpc->ctl_valid = FALSE;
+
+ /* The FTP session may or may not have been allocated/setup at this point! */
+ (void)ftp_quit(conn); /* ignore errors on the QUIT */
+
+ if(ftpc->entrypath) {
+ struct SessionHandle *data = conn->data;
+ if(data->state.most_recent_ftp_entrypath == ftpc->entrypath) {
+ data->state.most_recent_ftp_entrypath = NULL;
+ }
+ free(ftpc->entrypath);
+ ftpc->entrypath = NULL;
+ }
+
+ freedirs(ftpc);
+ free(ftpc->prevpath);
+ ftpc->prevpath = NULL;
+ free(ftpc->server_os);
+ ftpc->server_os = NULL;
+
+ Curl_pp_disconnect(pp);
+
+#ifdef HAVE_GSSAPI
+ Curl_sec_end(conn);
+#endif
+
+ return CURLE_OK;
+}
+
+/***********************************************************************
+ *
+ * ftp_parse_url_path()
+ *
+ * Parse the URL path into separate path components.
+ *
+ */
+static
+CURLcode ftp_parse_url_path(struct connectdata *conn)
+{
+ struct SessionHandle *data = conn->data;
+ /* the ftp struct is already inited in ftp_connect() */
+ struct FTP *ftp = data->req.protop;
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+ const char *slash_pos; /* position of the first '/' char in curpos */
+ const char *path_to_use = data->state.path;
+ const char *cur_pos;
+ const char *filename = NULL;
+
+ cur_pos = path_to_use; /* current position in path. point at the begin
+ of next path component */
+
+ ftpc->ctl_valid = FALSE;
+ ftpc->cwdfail = FALSE;
+
+ switch(data->set.ftp_filemethod) {
+ case FTPFILE_NOCWD:
+ /* fastest, but less standard-compliant */
+
+ /*
+ The best time to check whether the path is a file or directory is right
+ here. so:
+
+ the first condition in the if() right here, is there just in case
+ someone decides to set path to NULL one day
+ */
+ if(data->state.path &&
+ data->state.path[0] &&
+ (data->state.path[strlen(data->state.path) - 1] != '/') )
+ filename = data->state.path; /* this is a full file path */
+ /*
+ ftpc->file is not used anywhere other than for operations on a file.
+ In other words, never for directory operations.
+ So we can safely leave filename as NULL here and use it as a
+ argument in dir/file decisions.
+ */
+ break;
+
+ case FTPFILE_SINGLECWD:
+ /* get the last slash */
+ if(!path_to_use[0]) {
+ /* no dir, no file */
+ ftpc->dirdepth = 0;
+ break;
+ }
+ slash_pos=strrchr(cur_pos, '/');
+ if(slash_pos || !*cur_pos) {
+ size_t dirlen = slash_pos-cur_pos;
+
+ ftpc->dirs = calloc(1, sizeof(ftpc->dirs[0]));
+ if(!ftpc->dirs)
+ return CURLE_OUT_OF_MEMORY;
+
+ if(!dirlen)
+ dirlen++;
+
+ ftpc->dirs[0] = curl_easy_unescape(conn->data, slash_pos ? cur_pos : "/",
+ slash_pos ? curlx_uztosi(dirlen) : 1,
+ NULL);
+ if(!ftpc->dirs[0]) {
+ freedirs(ftpc);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ ftpc->dirdepth = 1; /* we consider it to be a single dir */
+ filename = slash_pos ? slash_pos+1 : cur_pos; /* rest is file name */
+ }
+ else
+ filename = cur_pos; /* this is a file name only */
+ break;
+
+ default: /* allow pretty much anything */
+ case FTPFILE_MULTICWD:
+ ftpc->dirdepth = 0;
+ ftpc->diralloc = 5; /* default dir depth to allocate */
+ ftpc->dirs = calloc(ftpc->diralloc, sizeof(ftpc->dirs[0]));
+ if(!ftpc->dirs)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* we have a special case for listing the root dir only */
+ if(strequal(path_to_use, "/")) {
+ cur_pos++; /* make it point to the zero byte */
+ ftpc->dirs[0] = strdup("/");
+ ftpc->dirdepth++;
+ }
+ else {
+ /* parse the URL path into separate path components */
+ while((slash_pos = strchr(cur_pos, '/')) != NULL) {
+ /* 1 or 0 pointer offset to indicate absolute directory */
+ ssize_t absolute_dir = ((cur_pos - data->state.path > 0) &&
+ (ftpc->dirdepth == 0))?1:0;
+
+ /* seek out the next path component */
+ if(slash_pos-cur_pos) {
+ /* we skip empty path components, like "x//y" since the FTP command
+ CWD requires a parameter and a non-existent parameter a) doesn't
+ work on many servers and b) has no effect on the others. */
+ int len = curlx_sztosi(slash_pos - cur_pos + absolute_dir);
+ ftpc->dirs[ftpc->dirdepth] =
+ curl_easy_unescape(conn->data, cur_pos - absolute_dir, len, NULL);
+ if(!ftpc->dirs[ftpc->dirdepth]) { /* run out of memory ... */
+ failf(data, "no memory");
+ freedirs(ftpc);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ if(isBadFtpString(ftpc->dirs[ftpc->dirdepth])) {
+ free(ftpc->dirs[ftpc->dirdepth]);
+ freedirs(ftpc);
+ return CURLE_URL_MALFORMAT;
+ }
+ }
+ else {
+ cur_pos = slash_pos + 1; /* jump to the rest of the string */
+ if(!ftpc->dirdepth) {
+ /* path starts with a slash, add that as a directory */
+ ftpc->dirs[ftpc->dirdepth] = strdup("/");
+ if(!ftpc->dirs[ftpc->dirdepth++]) { /* run out of memory ... */
+ failf(data, "no memory");
+ freedirs(ftpc);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ }
+ continue;
+ }
+
+ cur_pos = slash_pos + 1; /* jump to the rest of the string */
+ if(++ftpc->dirdepth >= ftpc->diralloc) {
+ /* enlarge array */
+ char **bigger;
+ ftpc->diralloc *= 2; /* double the size each time */
+ bigger = realloc(ftpc->dirs, ftpc->diralloc * sizeof(ftpc->dirs[0]));
+ if(!bigger) {
+ freedirs(ftpc);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ ftpc->dirs = bigger;
+ }
+ }
+ }
+ filename = cur_pos; /* the rest is the file name */
+ break;
+ } /* switch */
+
+ if(filename && *filename) {
+ ftpc->file = curl_easy_unescape(conn->data, filename, 0, NULL);
+ if(NULL == ftpc->file) {
+ freedirs(ftpc);
+ failf(data, "no memory");
+ return CURLE_OUT_OF_MEMORY;
+ }
+ if(isBadFtpString(ftpc->file)) {
+ freedirs(ftpc);
+ return CURLE_URL_MALFORMAT;
+ }
+ }
+ else
+ ftpc->file=NULL; /* instead of point to a zero byte, we make it a NULL
+ pointer */
+
+ if(data->set.upload && !ftpc->file && (ftp->transfer == FTPTRANSFER_BODY)) {
+ /* We need a file name when uploading. Return error! */
+ failf(data, "Uploading to a URL without a file name!");
+ return CURLE_URL_MALFORMAT;
+ }
+
+ ftpc->cwddone = FALSE; /* default to not done */
+
+ if(ftpc->prevpath) {
+ /* prevpath is "raw" so we convert the input path before we compare the
+ strings */
+ int dlen;
+ char *path = curl_easy_unescape(conn->data, data->state.path, 0, &dlen);
+ if(!path) {
+ freedirs(ftpc);
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ dlen -= ftpc->file?curlx_uztosi(strlen(ftpc->file)):0;
+ if((dlen == curlx_uztosi(strlen(ftpc->prevpath))) &&
+ strnequal(path, ftpc->prevpath, dlen)) {
+ infof(data, "Request has same path as previous transfer\n");
+ ftpc->cwddone = TRUE;
+ }
+ free(path);
+ }
+
+ return CURLE_OK;
+}
+
+/* call this when the DO phase has completed */
+static CURLcode ftp_dophase_done(struct connectdata *conn,
+ bool connected)
+{
+ struct FTP *ftp = conn->data->req.protop;
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+ if(connected) {
+ int completed;
+ CURLcode result = ftp_do_more(conn, &completed);
+
+ if(result) {
+ if(conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD) {
+ /* close the second socket if it was created already */
+ Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
+ conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
+ }
+ return result;
+ }
+ }
+
+ if(ftp->transfer != FTPTRANSFER_BODY)
+ /* no data to transfer */
+ Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+ else if(!connected)
+ /* since we didn't connect now, we want do_more to get called */
+ conn->bits.do_more = TRUE;
+
+ ftpc->ctl_valid = TRUE; /* seems good */
+
+ return CURLE_OK;
+}
+
+/* called from multi.c while DOing */
+static CURLcode ftp_doing(struct connectdata *conn,
+ bool *dophase_done)
+{
+ CURLcode result = ftp_multi_statemach(conn, dophase_done);
+
+ if(result)
+ DEBUGF(infof(conn->data, "DO phase failed\n"));
+ else if(*dophase_done) {
+ result = ftp_dophase_done(conn, FALSE /* not connected */);
+
+ DEBUGF(infof(conn->data, "DO phase is complete2\n"));
+ }
+ return result;
+}
+
+/***********************************************************************
+ *
+ * ftp_regular_transfer()
+ *
+ * The input argument is already checked for validity.
+ *
+ * Performs all commands done before a regular transfer between a local and a
+ * remote host.
+ *
+ * ftp->ctl_valid starts out as FALSE, and gets set to TRUE if we reach the
+ * ftp_done() function without finding any major problem.
+ */
+static
+CURLcode ftp_regular_transfer(struct connectdata *conn,
+ bool *dophase_done)
+{
+ CURLcode result=CURLE_OK;
+ bool connected=FALSE;
+ struct SessionHandle *data = conn->data;
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+ data->req.size = -1; /* make sure this is unknown at this point */
+
+ Curl_pgrsSetUploadCounter(data, 0);
+ Curl_pgrsSetDownloadCounter(data, 0);
+ Curl_pgrsSetUploadSize(data, -1);
+ Curl_pgrsSetDownloadSize(data, -1);
+
+ ftpc->ctl_valid = TRUE; /* starts good */
+
+ result = ftp_perform(conn,
+ &connected, /* have we connected after PASV/PORT */
+ dophase_done); /* all commands in the DO-phase done? */
+
+ if(!result) {
+
+ if(!*dophase_done)
+ /* the DO phase has not completed yet */
+ return CURLE_OK;
+
+ result = ftp_dophase_done(conn, connected);
+
+ if(result)
+ return result;
+ }
+ else
+ freedirs(ftpc);
+
+ return result;
+}
+
+static CURLcode ftp_setup_connection(struct connectdata *conn)
+{
+ struct SessionHandle *data = conn->data;
+ char *type;
+ char command;
+ struct FTP *ftp;
+
+ if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) {
+ /* Unless we have asked to tunnel ftp operations through the proxy, we
+ switch and use HTTP operations only */
+#ifndef CURL_DISABLE_HTTP
+ if(conn->handler == &Curl_handler_ftp)
+ conn->handler = &Curl_handler_ftp_proxy;
+ else {
+#ifdef USE_SSL
+ conn->handler = &Curl_handler_ftps_proxy;
+#else
+ failf(data, "FTPS not supported!");
+ return CURLE_UNSUPPORTED_PROTOCOL;
+#endif
+ }
+ /* set it up as a HTTP connection instead */
+ return conn->handler->setup_connection(conn);
+#else
+ failf(data, "FTP over http proxy requires HTTP support built-in!");
+ return CURLE_UNSUPPORTED_PROTOCOL;
+#endif
+ }
+
+ conn->data->req.protop = ftp = malloc(sizeof(struct FTP));
+ if(NULL == ftp)
+ return CURLE_OUT_OF_MEMORY;
+
+ data->state.path++; /* don't include the initial slash */
+ data->state.slash_removed = TRUE; /* we've skipped the slash */
+
+ /* FTP URLs support an extension like ";type=<typecode>" that
+ * we'll try to get now! */
+ type = strstr(data->state.path, ";type=");
+
+ if(!type)
+ type = strstr(conn->host.rawalloc, ";type=");
+
+ if(type) {
+ *type = 0; /* it was in the middle of the hostname */
+ command = Curl_raw_toupper(type[6]);
+ conn->bits.type_set = TRUE;
+
+ switch (command) {
+ case 'A': /* ASCII mode */
+ data->set.prefer_ascii = TRUE;
+ break;
+
+ case 'D': /* directory mode */
+ data->set.ftp_list_only = TRUE;
+ break;
+
+ case 'I': /* binary mode */
+ default:
+ /* switch off ASCII */
+ data->set.prefer_ascii = FALSE;
+ break;
+ }
+ }
+
+ /* get some initial data into the ftp struct */
+ ftp->bytecountp = &conn->data->req.bytecount;
+ ftp->transfer = FTPTRANSFER_BODY;
+ ftp->downloadsize = 0;
+
+ /* No need to duplicate user+password, the connectdata struct won't change
+ during a session, but we re-init them here since on subsequent inits
+ since the conn struct may have changed or been replaced.
+ */
+ ftp->user = conn->user;
+ ftp->passwd = conn->passwd;
+ if(isBadFtpString(ftp->user))
+ return CURLE_URL_MALFORMAT;
+ if(isBadFtpString(ftp->passwd))
+ return CURLE_URL_MALFORMAT;
+
+ conn->proto.ftpc.known_filesize = -1; /* unknown size for now */
+
+ return CURLE_OK;
+}
+
+#endif /* CURL_DISABLE_FTP */
diff --git a/Utilities/cmcurl/lib/ftp.h b/Utilities/cmcurl/lib/ftp.h
new file mode 100644
index 000000000..833447bcb
--- /dev/null
+++ b/Utilities/cmcurl/lib/ftp.h
@@ -0,0 +1,159 @@
+#ifndef HEADER_CURL_FTP_H
+#define HEADER_CURL_FTP_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "pingpong.h"
+
+#ifndef CURL_DISABLE_FTP
+extern const struct Curl_handler Curl_handler_ftp;
+
+#ifdef USE_SSL
+extern const struct Curl_handler Curl_handler_ftps;
+#endif
+
+CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...);
+CURLcode Curl_GetFTPResponse(ssize_t *nread, struct connectdata *conn,
+ int *ftpcode);
+#endif /* CURL_DISABLE_FTP */
+
+/****************************************************************************
+ * FTP unique setup
+ ***************************************************************************/
+typedef enum {
+ FTP_STOP, /* do nothing state, stops the state machine */
+ FTP_WAIT220, /* waiting for the initial 220 response immediately after
+ a connect */
+ FTP_AUTH,
+ FTP_USER,
+ FTP_PASS,
+ FTP_ACCT,
+ FTP_PBSZ,
+ FTP_PROT,
+ FTP_CCC,
+ FTP_PWD,
+ FTP_SYST,
+ FTP_NAMEFMT,
+ FTP_QUOTE, /* waiting for a response to a command sent in a quote list */
+ FTP_RETR_PREQUOTE,
+ FTP_STOR_PREQUOTE,
+ FTP_POSTQUOTE,
+ FTP_CWD, /* change dir */
+ FTP_MKD, /* if the dir didn't exist */
+ FTP_MDTM, /* to figure out the datestamp */
+ FTP_TYPE, /* to set type when doing a head-like request */
+ FTP_LIST_TYPE, /* set type when about to do a dir list */
+ FTP_RETR_TYPE, /* set type when about to RETR a file */
+ FTP_STOR_TYPE, /* set type when about to STOR a file */
+ FTP_SIZE, /* get the remote file's size for head-like request */
+ FTP_RETR_SIZE, /* get the remote file's size for RETR */
+ FTP_STOR_SIZE, /* get the size for STOR */
+ FTP_REST, /* when used to check if the server supports it in head-like */
+ FTP_RETR_REST, /* when asking for "resume" in for RETR */
+ FTP_PORT, /* generic state for PORT, LPRT and EPRT, check count1 */
+ FTP_PRET, /* generic state for PRET RETR, PRET STOR and PRET LIST/NLST */
+ FTP_PASV, /* generic state for PASV and EPSV, check count1 */
+ FTP_LIST, /* generic state for LIST, NLST or a custom list command */
+ FTP_RETR,
+ FTP_STOR, /* generic state for STOR and APPE */
+ FTP_QUIT,
+ FTP_LAST /* never used */
+} ftpstate;
+
+struct ftp_parselist_data; /* defined later in ftplistparser.c */
+
+struct ftp_wc_tmpdata {
+ struct ftp_parselist_data *parser;
+
+ struct {
+ curl_write_callback write_function;
+ FILE *file_descriptor;
+ } backup;
+};
+
+typedef enum {
+ FTPFILE_MULTICWD = 1, /* as defined by RFC1738 */
+ FTPFILE_NOCWD = 2, /* use SIZE / RETR / STOR on the full path */
+ FTPFILE_SINGLECWD = 3 /* make one CWD, then SIZE / RETR / STOR on the
+ file */
+} curl_ftpfile;
+
+/* This FTP struct is used in the SessionHandle. All FTP data that is
+ connection-oriented must be in FTP_conn to properly deal with the fact that
+ perhaps the SessionHandle is changed between the times the connection is
+ used. */
+struct FTP {
+ curl_off_t *bytecountp;
+ char *user; /* user name string */
+ char *passwd; /* password string */
+
+ /* transfer a file/body or not, done as a typedefed enum just to make
+ debuggers display the full symbol and not just the numerical value */
+ curl_pp_transfer transfer;
+ curl_off_t downloadsize;
+};
+
+
+/* ftp_conn is used for struct connection-oriented data in the connectdata
+ struct */
+struct ftp_conn {
+ struct pingpong pp;
+ char *entrypath; /* the PWD reply when we logged on */
+ char **dirs; /* realloc()ed array for path components */
+ int dirdepth; /* number of entries used in the 'dirs' array */
+ int diralloc; /* number of entries allocated for the 'dirs' array */
+ char *file; /* decoded file */
+ bool dont_check; /* Set to TRUE to prevent the final (post-transfer)
+ file size and 226/250 status check. It should still
+ read the line, just ignore the result. */
+ bool ctl_valid; /* Tells Curl_ftp_quit() whether or not to do anything. If
+ the connection has timed out or been closed, this
+ should be FALSE when it gets to Curl_ftp_quit() */
+ bool cwddone; /* if it has been determined that the proper CWD combo
+ already has been done */
+ bool cwdfail; /* set TRUE if a CWD command fails, as then we must prevent
+ caching the current directory */
+ bool wait_data_conn; /* this is set TRUE if data connection is waited */
+ char *prevpath; /* conn->path from the previous transfer */
+ char transfertype; /* set by ftp_transfertype for use by Curl_client_write()a
+ and others (A/I or zero) */
+ int count1; /* general purpose counter for the state machine */
+ int count2; /* general purpose counter for the state machine */
+ int count3; /* general purpose counter for the state machine */
+ ftpstate state; /* always use ftp.c:state() to change state! */
+ ftpstate state_saved; /* transfer type saved to be reloaded after
+ data connection is established */
+ curl_off_t retr_size_saved; /* Size of retrieved file saved */
+ char * server_os; /* The target server operating system. */
+ curl_off_t known_filesize; /* file size is different from -1, if wildcard
+ LIST parsing was done and wc_statemach set
+ it */
+ /* newhost is the (allocated) IP addr or host name to connect the data
+ connection to */
+ char *newhost; /* this is the pair to connect the DATA... */
+ unsigned short newport; /* connection to */
+
+};
+
+#define DEFAULT_ACCEPT_TIMEOUT 60000 /* milliseconds == one minute */
+
+#endif /* HEADER_CURL_FTP_H */
diff --git a/Utilities/cmcurl/lib/ftplistparser.c b/Utilities/cmcurl/lib/ftplistparser.c
new file mode 100644
index 000000000..17e0a66f8
--- /dev/null
+++ b/Utilities/cmcurl/lib/ftplistparser.c
@@ -0,0 +1,1048 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/**
+ * Now implemented:
+ *
+ * 1) Unix version 1
+ * drwxr-xr-x 1 user01 ftp 512 Jan 29 23:32 prog
+ * 2) Unix version 2
+ * drwxr-xr-x 1 user01 ftp 512 Jan 29 1997 prog
+ * 3) Unix version 3
+ * drwxr-xr-x 1 1 1 512 Jan 29 23:32 prog
+ * 4) Unix symlink
+ * lrwxr-xr-x 1 user01 ftp 512 Jan 29 23:32 prog -> prog2000
+ * 5) DOS style
+ * 01-29-97 11:32PM <DIR> prog
+ */
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_FTP
+
+#include <curl/curl.h>
+
+#include "urldata.h"
+#include "fileinfo.h"
+#include "llist.h"
+#include "strtoofft.h"
+#include "rawstr.h"
+#include "ftp.h"
+#include "ftplistparser.h"
+#include "curl_fnmatch.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* allocs buffer which will contain one line of LIST command response */
+#define FTP_BUFFER_ALLOCSIZE 160
+
+typedef enum {
+ PL_UNIX_TOTALSIZE = 0,
+ PL_UNIX_FILETYPE,
+ PL_UNIX_PERMISSION,
+ PL_UNIX_HLINKS,
+ PL_UNIX_USER,
+ PL_UNIX_GROUP,
+ PL_UNIX_SIZE,
+ PL_UNIX_TIME,
+ PL_UNIX_FILENAME,
+ PL_UNIX_SYMLINK
+} pl_unix_mainstate;
+
+typedef union {
+ enum {
+ PL_UNIX_TOTALSIZE_INIT = 0,
+ PL_UNIX_TOTALSIZE_READING
+ } total_dirsize;
+
+ enum {
+ PL_UNIX_HLINKS_PRESPACE = 0,
+ PL_UNIX_HLINKS_NUMBER
+ } hlinks;
+
+ enum {
+ PL_UNIX_USER_PRESPACE = 0,
+ PL_UNIX_USER_PARSING
+ } user;
+
+ enum {
+ PL_UNIX_GROUP_PRESPACE = 0,
+ PL_UNIX_GROUP_NAME
+ } group;
+
+ enum {
+ PL_UNIX_SIZE_PRESPACE = 0,
+ PL_UNIX_SIZE_NUMBER
+ } size;
+
+ enum {
+ PL_UNIX_TIME_PREPART1 = 0,
+ PL_UNIX_TIME_PART1,
+ PL_UNIX_TIME_PREPART2,
+ PL_UNIX_TIME_PART2,
+ PL_UNIX_TIME_PREPART3,
+ PL_UNIX_TIME_PART3
+ } time;
+
+ enum {
+ PL_UNIX_FILENAME_PRESPACE = 0,
+ PL_UNIX_FILENAME_NAME,
+ PL_UNIX_FILENAME_WINDOWSEOL
+ } filename;
+
+ enum {
+ PL_UNIX_SYMLINK_PRESPACE = 0,
+ PL_UNIX_SYMLINK_NAME,
+ PL_UNIX_SYMLINK_PRETARGET1,
+ PL_UNIX_SYMLINK_PRETARGET2,
+ PL_UNIX_SYMLINK_PRETARGET3,
+ PL_UNIX_SYMLINK_PRETARGET4,
+ PL_UNIX_SYMLINK_TARGET,
+ PL_UNIX_SYMLINK_WINDOWSEOL
+ } symlink;
+} pl_unix_substate;
+
+typedef enum {
+ PL_WINNT_DATE = 0,
+ PL_WINNT_TIME,
+ PL_WINNT_DIRORSIZE,
+ PL_WINNT_FILENAME
+} pl_winNT_mainstate;
+
+typedef union {
+ enum {
+ PL_WINNT_TIME_PRESPACE = 0,
+ PL_WINNT_TIME_TIME
+ } time;
+ enum {
+ PL_WINNT_DIRORSIZE_PRESPACE = 0,
+ PL_WINNT_DIRORSIZE_CONTENT
+ } dirorsize;
+ enum {
+ PL_WINNT_FILENAME_PRESPACE = 0,
+ PL_WINNT_FILENAME_CONTENT,
+ PL_WINNT_FILENAME_WINEOL
+ } filename;
+} pl_winNT_substate;
+
+/* This struct is used in wildcard downloading - for parsing LIST response */
+struct ftp_parselist_data {
+ enum {
+ OS_TYPE_UNKNOWN = 0,
+ OS_TYPE_UNIX,
+ OS_TYPE_WIN_NT
+ } os_type;
+
+ union {
+ struct {
+ pl_unix_mainstate main;
+ pl_unix_substate sub;
+ } UNIX;
+
+ struct {
+ pl_winNT_mainstate main;
+ pl_winNT_substate sub;
+ } NT;
+ } state;
+
+ CURLcode error;
+ struct curl_fileinfo *file_data;
+ unsigned int item_length;
+ size_t item_offset;
+ struct {
+ size_t filename;
+ size_t user;
+ size_t group;
+ size_t time;
+ size_t perm;
+ size_t symlink_target;
+ } offsets;
+};
+
+struct ftp_parselist_data *Curl_ftp_parselist_data_alloc(void)
+{
+ return calloc(1, sizeof(struct ftp_parselist_data));
+}
+
+
+void Curl_ftp_parselist_data_free(struct ftp_parselist_data **pl_data)
+{
+ free(*pl_data);
+ *pl_data = NULL;
+}
+
+
+CURLcode Curl_ftp_parselist_geterror(struct ftp_parselist_data *pl_data)
+{
+ return pl_data->error;
+}
+
+
+#define FTP_LP_MALFORMATED_PERM 0x01000000
+
+static int ftp_pl_get_permission(const char *str)
+{
+ int permissions = 0;
+ /* USER */
+ if(str[0] == 'r')
+ permissions |= 1 << 8;
+ else if(str[0] != '-')
+ permissions |= FTP_LP_MALFORMATED_PERM;
+ if(str[1] == 'w')
+ permissions |= 1 << 7;
+ else if(str[1] != '-')
+ permissions |= FTP_LP_MALFORMATED_PERM;
+
+ if(str[2] == 'x')
+ permissions |= 1 << 6;
+ else if(str[2] == 's') {
+ permissions |= 1 << 6;
+ permissions |= 1 << 11;
+ }
+ else if(str[2] == 'S')
+ permissions |= 1 << 11;
+ else if(str[2] != '-')
+ permissions |= FTP_LP_MALFORMATED_PERM;
+ /* GROUP */
+ if(str[3] == 'r')
+ permissions |= 1 << 5;
+ else if(str[3] != '-')
+ permissions |= FTP_LP_MALFORMATED_PERM;
+ if(str[4] == 'w')
+ permissions |= 1 << 4;
+ else if(str[4] != '-')
+ permissions |= FTP_LP_MALFORMATED_PERM;
+ if(str[5] == 'x')
+ permissions |= 1 << 3;
+ else if(str[5] == 's') {
+ permissions |= 1 << 3;
+ permissions |= 1 << 10;
+ }
+ else if(str[5] == 'S')
+ permissions |= 1 << 10;
+ else if(str[5] != '-')
+ permissions |= FTP_LP_MALFORMATED_PERM;
+ /* others */
+ if(str[6] == 'r')
+ permissions |= 1 << 2;
+ else if(str[6] != '-')
+ permissions |= FTP_LP_MALFORMATED_PERM;
+ if(str[7] == 'w')
+ permissions |= 1 << 1;
+ else if(str[7] != '-')
+ permissions |= FTP_LP_MALFORMATED_PERM;
+ if(str[8] == 'x')
+ permissions |= 1;
+ else if(str[8] == 't') {
+ permissions |= 1;
+ permissions |= 1 << 9;
+ }
+ else if(str[8] == 'T')
+ permissions |= 1 << 9;
+ else if(str[8] != '-')
+ permissions |= FTP_LP_MALFORMATED_PERM;
+
+ return permissions;
+}
+
+static void PL_ERROR(struct connectdata *conn, CURLcode err)
+{
+ struct ftp_wc_tmpdata *tmpdata = conn->data->wildcard.tmp;
+ struct ftp_parselist_data *parser = tmpdata->parser;
+ if(parser->file_data)
+ Curl_fileinfo_dtor(NULL, parser->file_data);
+ parser->file_data = NULL;
+ parser->error = err;
+}
+
+static bool ftp_pl_gettime(struct ftp_parselist_data *parser, char *string)
+{
+ (void)parser;
+ (void)string;
+ /* TODO
+ * There could be possible parse timestamp from server. Leaving unimplemented
+ * for now.
+ * If you want implement this, please add CURLFINFOFLAG_KNOWN_TIME flag to
+ * parser->file_data->flags
+ *
+ * Ftp servers are giving usually these formats:
+ * Apr 11 1998 (unknown time.. set it to 00:00:00?)
+ * Apr 11 12:21 (unknown year -> set it to NOW() time?)
+ * 08-05-09 02:49PM (ms-dos format)
+ * 20100421092538 -> for MLST/MLSD response
+ */
+
+ return FALSE;
+}
+
+static CURLcode ftp_pl_insert_finfo(struct connectdata *conn,
+ struct curl_fileinfo *finfo)
+{
+ curl_fnmatch_callback compare;
+ struct WildcardData *wc = &conn->data->wildcard;
+ struct ftp_wc_tmpdata *tmpdata = wc->tmp;
+ struct curl_llist *llist = wc->filelist;
+ struct ftp_parselist_data *parser = tmpdata->parser;
+ bool add = TRUE;
+
+ /* move finfo pointers to b_data */
+ char *str = finfo->b_data;
+ finfo->filename = str + parser->offsets.filename;
+ finfo->strings.group = parser->offsets.group ?
+ str + parser->offsets.group : NULL;
+ finfo->strings.perm = parser->offsets.perm ?
+ str + parser->offsets.perm : NULL;
+ finfo->strings.target = parser->offsets.symlink_target ?
+ str + parser->offsets.symlink_target : NULL;
+ finfo->strings.time = str + parser->offsets.time;
+ finfo->strings.user = parser->offsets.user ?
+ str + parser->offsets.user : NULL;
+
+ /* get correct fnmatch callback */
+ compare = conn->data->set.fnmatch;
+ if(!compare)
+ compare = Curl_fnmatch;
+
+ /* filter pattern-corresponding filenames */
+ if(compare(conn->data->set.fnmatch_data, wc->pattern,
+ finfo->filename) == 0) {
+ /* discard symlink which is containing multiple " -> " */
+ if((finfo->filetype == CURLFILETYPE_SYMLINK) && finfo->strings.target &&
+ (strstr(finfo->strings.target, " -> "))) {
+ add = FALSE;
+ }
+ }
+ else {
+ add = FALSE;
+ }
+
+ if(add) {
+ if(!Curl_llist_insert_next(llist, llist->tail, finfo)) {
+ Curl_fileinfo_dtor(NULL, finfo);
+ tmpdata->parser->file_data = NULL;
+ return CURLE_OUT_OF_MEMORY;
+ }
+ }
+ else {
+ Curl_fileinfo_dtor(NULL, finfo);
+ }
+
+ tmpdata->parser->file_data = NULL;
+ return CURLE_OK;
+}
+
+size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
+ void *connptr)
+{
+ size_t bufflen = size*nmemb;
+ struct connectdata *conn = (struct connectdata *)connptr;
+ struct ftp_wc_tmpdata *tmpdata = conn->data->wildcard.tmp;
+ struct ftp_parselist_data *parser = tmpdata->parser;
+ struct curl_fileinfo *finfo;
+ unsigned long i = 0;
+ CURLcode result;
+
+ if(parser->error) { /* error in previous call */
+ /* scenario:
+ * 1. call => OK..
+ * 2. call => OUT_OF_MEMORY (or other error)
+ * 3. (last) call => is skipped RIGHT HERE and the error is hadled later
+ * in wc_statemach()
+ */
+ return bufflen;
+ }
+
+ if(parser->os_type == OS_TYPE_UNKNOWN && bufflen > 0) {
+ /* considering info about FILE response format */
+ parser->os_type = (buffer[0] >= '0' && buffer[0] <= '9') ?
+ OS_TYPE_WIN_NT : OS_TYPE_UNIX;
+ }
+
+ while(i < bufflen) { /* FSM */
+
+ char c = buffer[i];
+ if(!parser->file_data) { /* tmp file data is not allocated yet */
+ parser->file_data = Curl_fileinfo_alloc();
+ if(!parser->file_data) {
+ parser->error = CURLE_OUT_OF_MEMORY;
+ return bufflen;
+ }
+ parser->file_data->b_data = malloc(FTP_BUFFER_ALLOCSIZE);
+ if(!parser->file_data->b_data) {
+ PL_ERROR(conn, CURLE_OUT_OF_MEMORY);
+ return bufflen;
+ }
+ parser->file_data->b_size = FTP_BUFFER_ALLOCSIZE;
+ parser->item_offset = 0;
+ parser->item_length = 0;
+ }
+
+ finfo = parser->file_data;
+ finfo->b_data[finfo->b_used++] = c;
+
+ if(finfo->b_used >= finfo->b_size - 1) {
+ /* if it is important, extend buffer space for file data */
+ char *tmp = realloc(finfo->b_data,
+ finfo->b_size + FTP_BUFFER_ALLOCSIZE);
+ if(tmp) {
+ finfo->b_size += FTP_BUFFER_ALLOCSIZE;
+ finfo->b_data = tmp;
+ }
+ else {
+ Curl_fileinfo_dtor(NULL, parser->file_data);
+ parser->file_data = NULL;
+ parser->error = CURLE_OUT_OF_MEMORY;
+ PL_ERROR(conn, CURLE_OUT_OF_MEMORY);
+ return bufflen;
+ }
+ }
+
+ switch (parser->os_type) {
+ case OS_TYPE_UNIX:
+ switch (parser->state.UNIX.main) {
+ case PL_UNIX_TOTALSIZE:
+ switch(parser->state.UNIX.sub.total_dirsize) {
+ case PL_UNIX_TOTALSIZE_INIT:
+ if(c == 't') {
+ parser->state.UNIX.sub.total_dirsize = PL_UNIX_TOTALSIZE_READING;
+ parser->item_length++;
+ }
+ else {
+ parser->state.UNIX.main = PL_UNIX_FILETYPE;
+ /* start FSM again not considering size of directory */
+ finfo->b_used = 0;
+ i--;
+ }
+ break;
+ case PL_UNIX_TOTALSIZE_READING:
+ parser->item_length++;
+ if(c == '\r') {
+ parser->item_length--;
+ finfo->b_used--;
+ }
+ else if(c == '\n') {
+ finfo->b_data[parser->item_length - 1] = 0;
+ if(strncmp("total ", finfo->b_data, 6) == 0) {
+ char *endptr = finfo->b_data+6;
+ /* here we can deal with directory size, pass the leading white
+ spaces and then the digits */
+ while(ISSPACE(*endptr))
+ endptr++;
+ while(ISDIGIT(*endptr))
+ endptr++;
+ if(*endptr != 0) {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ else {
+ parser->state.UNIX.main = PL_UNIX_FILETYPE;
+ finfo->b_used = 0;
+ }
+ }
+ else {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ }
+ break;
+ }
+ break;
+ case PL_UNIX_FILETYPE:
+ switch (c) {
+ case '-':
+ finfo->filetype = CURLFILETYPE_FILE;
+ break;
+ case 'd':
+ finfo->filetype = CURLFILETYPE_DIRECTORY;
+ break;
+ case 'l':
+ finfo->filetype = CURLFILETYPE_SYMLINK;
+ break;
+ case 'p':
+ finfo->filetype = CURLFILETYPE_NAMEDPIPE;
+ break;
+ case 's':
+ finfo->filetype = CURLFILETYPE_SOCKET;
+ break;
+ case 'c':
+ finfo->filetype = CURLFILETYPE_DEVICE_CHAR;
+ break;
+ case 'b':
+ finfo->filetype = CURLFILETYPE_DEVICE_BLOCK;
+ break;
+ case 'D':
+ finfo->filetype = CURLFILETYPE_DOOR;
+ break;
+ default:
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ parser->state.UNIX.main = PL_UNIX_PERMISSION;
+ parser->item_length = 0;
+ parser->item_offset = 1;
+ break;
+ case PL_UNIX_PERMISSION:
+ parser->item_length++;
+ if(parser->item_length <= 9) {
+ if(!strchr("rwx-tTsS", c)) {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ }
+ else if(parser->item_length == 10) {
+ unsigned int perm;
+ if(c != ' ') {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ finfo->b_data[10] = 0; /* terminate permissions */
+ perm = ftp_pl_get_permission(finfo->b_data + parser->item_offset);
+ if(perm & FTP_LP_MALFORMATED_PERM) {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ parser->file_data->flags |= CURLFINFOFLAG_KNOWN_PERM;
+ parser->file_data->perm = perm;
+ parser->offsets.perm = parser->item_offset;
+
+ parser->item_length = 0;
+ parser->state.UNIX.main = PL_UNIX_HLINKS;
+ parser->state.UNIX.sub.hlinks = PL_UNIX_HLINKS_PRESPACE;
+ }
+ break;
+ case PL_UNIX_HLINKS:
+ switch(parser->state.UNIX.sub.hlinks) {
+ case PL_UNIX_HLINKS_PRESPACE:
+ if(c != ' ') {
+ if(c >= '0' && c <= '9') {
+ parser->item_offset = finfo->b_used - 1;
+ parser->item_length = 1;
+ parser->state.UNIX.sub.hlinks = PL_UNIX_HLINKS_NUMBER;
+ }
+ else {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ }
+ break;
+ case PL_UNIX_HLINKS_NUMBER:
+ parser->item_length ++;
+ if(c == ' ') {
+ char *p;
+ long int hlinks;
+ finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
+ hlinks = strtol(finfo->b_data + parser->item_offset, &p, 10);
+ if(p[0] == '\0' && hlinks != LONG_MAX && hlinks != LONG_MIN) {
+ parser->file_data->flags |= CURLFINFOFLAG_KNOWN_HLINKCOUNT;
+ parser->file_data->hardlinks = hlinks;
+ }
+ parser->item_length = 0;
+ parser->item_offset = 0;
+ parser->state.UNIX.main = PL_UNIX_USER;
+ parser->state.UNIX.sub.user = PL_UNIX_USER_PRESPACE;
+ }
+ else if(c < '0' || c > '9') {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ break;
+ }
+ break;
+ case PL_UNIX_USER:
+ switch(parser->state.UNIX.sub.user) {
+ case PL_UNIX_USER_PRESPACE:
+ if(c != ' ') {
+ parser->item_offset = finfo->b_used - 1;
+ parser->item_length = 1;
+ parser->state.UNIX.sub.user = PL_UNIX_USER_PARSING;
+ }
+ break;
+ case PL_UNIX_USER_PARSING:
+ parser->item_length++;
+ if(c == ' ') {
+ finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
+ parser->offsets.user = parser->item_offset;
+ parser->state.UNIX.main = PL_UNIX_GROUP;
+ parser->state.UNIX.sub.group = PL_UNIX_GROUP_PRESPACE;
+ parser->item_offset = 0;
+ parser->item_length = 0;
+ }
+ break;
+ }
+ break;
+ case PL_UNIX_GROUP:
+ switch(parser->state.UNIX.sub.group) {
+ case PL_UNIX_GROUP_PRESPACE:
+ if(c != ' ') {
+ parser->item_offset = finfo->b_used - 1;
+ parser->item_length = 1;
+ parser->state.UNIX.sub.group = PL_UNIX_GROUP_NAME;
+ }
+ break;
+ case PL_UNIX_GROUP_NAME:
+ parser->item_length++;
+ if(c == ' ') {
+ finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
+ parser->offsets.group = parser->item_offset;
+ parser->state.UNIX.main = PL_UNIX_SIZE;
+ parser->state.UNIX.sub.size = PL_UNIX_SIZE_PRESPACE;
+ parser->item_offset = 0;
+ parser->item_length = 0;
+ }
+ break;
+ }
+ break;
+ case PL_UNIX_SIZE:
+ switch(parser->state.UNIX.sub.size) {
+ case PL_UNIX_SIZE_PRESPACE:
+ if(c != ' ') {
+ if(c >= '0' && c <= '9') {
+ parser->item_offset = finfo->b_used - 1;
+ parser->item_length = 1;
+ parser->state.UNIX.sub.size = PL_UNIX_SIZE_NUMBER;
+ }
+ else {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ }
+ break;
+ case PL_UNIX_SIZE_NUMBER:
+ parser->item_length++;
+ if(c == ' ') {
+ char *p;
+ curl_off_t fsize;
+ finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
+ fsize = curlx_strtoofft(finfo->b_data+parser->item_offset, &p, 10);
+ if(p[0] == '\0' && fsize != CURL_OFF_T_MAX &&
+ fsize != CURL_OFF_T_MIN) {
+ parser->file_data->flags |= CURLFINFOFLAG_KNOWN_SIZE;
+ parser->file_data->size = fsize;
+ }
+ parser->item_length = 0;
+ parser->item_offset = 0;
+ parser->state.UNIX.main = PL_UNIX_TIME;
+ parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART1;
+ }
+ else if(!ISDIGIT(c)) {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ break;
+ }
+ break;
+ case PL_UNIX_TIME:
+ switch(parser->state.UNIX.sub.time) {
+ case PL_UNIX_TIME_PREPART1:
+ if(c != ' ') {
+ if(ISALNUM(c)) {
+ parser->item_offset = finfo->b_used -1;
+ parser->item_length = 1;
+ parser->state.UNIX.sub.time = PL_UNIX_TIME_PART1;
+ }
+ else {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ }
+ break;
+ case PL_UNIX_TIME_PART1:
+ parser->item_length++;
+ if(c == ' ') {
+ parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART2;
+ }
+ else if(!ISALNUM(c) && c != '.') {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ break;
+ case PL_UNIX_TIME_PREPART2:
+ parser->item_length++;
+ if(c != ' ') {
+ if(ISALNUM(c)) {
+ parser->state.UNIX.sub.time = PL_UNIX_TIME_PART2;
+ }
+ else {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ }
+ break;
+ case PL_UNIX_TIME_PART2:
+ parser->item_length++;
+ if(c == ' ') {
+ parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART3;
+ }
+ else if(!ISALNUM(c) && c != '.') {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ break;
+ case PL_UNIX_TIME_PREPART3:
+ parser->item_length++;
+ if(c != ' ') {
+ if(ISALNUM(c)) {
+ parser->state.UNIX.sub.time = PL_UNIX_TIME_PART3;
+ }
+ else {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ }
+ break;
+ case PL_UNIX_TIME_PART3:
+ parser->item_length++;
+ if(c == ' ') {
+ finfo->b_data[parser->item_offset + parser->item_length -1] = 0;
+ parser->offsets.time = parser->item_offset;
+ if(ftp_pl_gettime(parser, finfo->b_data + parser->item_offset)) {
+ parser->file_data->flags |= CURLFINFOFLAG_KNOWN_TIME;
+ }
+ if(finfo->filetype == CURLFILETYPE_SYMLINK) {
+ parser->state.UNIX.main = PL_UNIX_SYMLINK;
+ parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRESPACE;
+ }
+ else {
+ parser->state.UNIX.main = PL_UNIX_FILENAME;
+ parser->state.UNIX.sub.filename = PL_UNIX_FILENAME_PRESPACE;
+ }
+ }
+ else if(!ISALNUM(c) && c != '.' && c != ':') {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ break;
+ }
+ break;
+ case PL_UNIX_FILENAME:
+ switch(parser->state.UNIX.sub.filename) {
+ case PL_UNIX_FILENAME_PRESPACE:
+ if(c != ' ') {
+ parser->item_offset = finfo->b_used - 1;
+ parser->item_length = 1;
+ parser->state.UNIX.sub.filename = PL_UNIX_FILENAME_NAME;
+ }
+ break;
+ case PL_UNIX_FILENAME_NAME:
+ parser->item_length++;
+ if(c == '\r') {
+ parser->item_length--;
+ parser->state.UNIX.sub.filename = PL_UNIX_FILENAME_WINDOWSEOL;
+ }
+ else if(c == '\n') {
+ finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
+ parser->offsets.filename = parser->item_offset;
+ parser->state.UNIX.main = PL_UNIX_FILETYPE;
+ result = ftp_pl_insert_finfo(conn, finfo);
+ if(result) {
+ PL_ERROR(conn, result);
+ return bufflen;
+ }
+ }
+ break;
+ case PL_UNIX_FILENAME_WINDOWSEOL:
+ if(c == '\n') {
+ finfo->b_data[parser->item_offset + parser->item_length] = 0;
+ parser->offsets.filename = parser->item_offset;
+ parser->state.UNIX.main = PL_UNIX_FILETYPE;
+ result = ftp_pl_insert_finfo(conn, finfo);
+ if(result) {
+ PL_ERROR(conn, result);
+ return bufflen;
+ }
+ }
+ else {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ break;
+ }
+ break;
+ case PL_UNIX_SYMLINK:
+ switch(parser->state.UNIX.sub.symlink) {
+ case PL_UNIX_SYMLINK_PRESPACE:
+ if(c != ' ') {
+ parser->item_offset = finfo->b_used - 1;
+ parser->item_length = 1;
+ parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME;
+ }
+ break;
+ case PL_UNIX_SYMLINK_NAME:
+ parser->item_length++;
+ if(c == ' ') {
+ parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET1;
+ }
+ else if(c == '\r' || c == '\n') {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ break;
+ case PL_UNIX_SYMLINK_PRETARGET1:
+ parser->item_length++;
+ if(c == '-') {
+ parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET2;
+ }
+ else if(c == '\r' || c == '\n') {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ else {
+ parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME;
+ }
+ break;
+ case PL_UNIX_SYMLINK_PRETARGET2:
+ parser->item_length++;
+ if(c == '>') {
+ parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET3;
+ }
+ else if(c == '\r' || c == '\n') {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ else {
+ parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME;
+ }
+ break;
+ case PL_UNIX_SYMLINK_PRETARGET3:
+ parser->item_length++;
+ if(c == ' ') {
+ parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET4;
+ /* now place where is symlink following */
+ finfo->b_data[parser->item_offset + parser->item_length - 4] = 0;
+ parser->offsets.filename = parser->item_offset;
+ parser->item_length = 0;
+ parser->item_offset = 0;
+ }
+ else if(c == '\r' || c == '\n') {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ else {
+ parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME;
+ }
+ break;
+ case PL_UNIX_SYMLINK_PRETARGET4:
+ if(c != '\r' && c != '\n') {
+ parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_TARGET;
+ parser->item_offset = finfo->b_used - 1;
+ parser->item_length = 1;
+ }
+ else {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ break;
+ case PL_UNIX_SYMLINK_TARGET:
+ parser->item_length ++;
+ if(c == '\r') {
+ parser->item_length --;
+ parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_WINDOWSEOL;
+ }
+ else if(c == '\n') {
+ finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
+ parser->offsets.symlink_target = parser->item_offset;
+ result = ftp_pl_insert_finfo(conn, finfo);
+ if(result) {
+ PL_ERROR(conn, result);
+ return bufflen;
+ }
+ parser->state.UNIX.main = PL_UNIX_FILETYPE;
+ }
+ break;
+ case PL_UNIX_SYMLINK_WINDOWSEOL:
+ if(c == '\n') {
+ finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
+ parser->offsets.symlink_target = parser->item_offset;
+ result = ftp_pl_insert_finfo(conn, finfo);
+ if(result) {
+ PL_ERROR(conn, result);
+ return bufflen;
+ }
+ parser->state.UNIX.main = PL_UNIX_FILETYPE;
+ }
+ else {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ break;
+ }
+ break;
+ }
+ break;
+ case OS_TYPE_WIN_NT:
+ switch(parser->state.NT.main) {
+ case PL_WINNT_DATE:
+ parser->item_length++;
+ if(parser->item_length < 9) {
+ if(!strchr("0123456789-", c)) { /* only simple control */
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ }
+ else if(parser->item_length == 9) {
+ if(c == ' ') {
+ parser->state.NT.main = PL_WINNT_TIME;
+ parser->state.NT.sub.time = PL_WINNT_TIME_PRESPACE;
+ }
+ else {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ }
+ else {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ break;
+ case PL_WINNT_TIME:
+ parser->item_length++;
+ switch(parser->state.NT.sub.time) {
+ case PL_WINNT_TIME_PRESPACE:
+ if(!ISSPACE(c)) {
+ parser->state.NT.sub.time = PL_WINNT_TIME_TIME;
+ }
+ break;
+ case PL_WINNT_TIME_TIME:
+ if(c == ' ') {
+ parser->offsets.time = parser->item_offset;
+ finfo->b_data[parser->item_offset + parser->item_length -1] = 0;
+ parser->state.NT.main = PL_WINNT_DIRORSIZE;
+ parser->state.NT.sub.dirorsize = PL_WINNT_DIRORSIZE_PRESPACE;
+ parser->item_length = 0;
+ }
+ else if(!strchr("APM0123456789:", c)) {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ break;
+ }
+ break;
+ case PL_WINNT_DIRORSIZE:
+ switch(parser->state.NT.sub.dirorsize) {
+ case PL_WINNT_DIRORSIZE_PRESPACE:
+ if(c == ' ') {
+
+ }
+ else {
+ parser->item_offset = finfo->b_used - 1;
+ parser->item_length = 1;
+ parser->state.NT.sub.dirorsize = PL_WINNT_DIRORSIZE_CONTENT;
+ }
+ break;
+ case PL_WINNT_DIRORSIZE_CONTENT:
+ parser->item_length ++;
+ if(c == ' ') {
+ finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
+ if(strcmp("<DIR>", finfo->b_data + parser->item_offset) == 0) {
+ finfo->filetype = CURLFILETYPE_DIRECTORY;
+ finfo->size = 0;
+ }
+ else {
+ char *endptr;
+ finfo->size = curlx_strtoofft(finfo->b_data +
+ parser->item_offset,
+ &endptr, 10);
+ if(!*endptr) {
+ if(finfo->size == CURL_OFF_T_MAX ||
+ finfo->size == CURL_OFF_T_MIN) {
+ if(errno == ERANGE) {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ }
+ }
+ else {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ /* correct file type */
+ parser->file_data->filetype = CURLFILETYPE_FILE;
+ }
+
+ parser->file_data->flags |= CURLFINFOFLAG_KNOWN_SIZE;
+ parser->item_length = 0;
+ parser->state.NT.main = PL_WINNT_FILENAME;
+ parser->state.NT.sub.filename = PL_WINNT_FILENAME_PRESPACE;
+ }
+ break;
+ }
+ break;
+ case PL_WINNT_FILENAME:
+ switch (parser->state.NT.sub.filename) {
+ case PL_WINNT_FILENAME_PRESPACE:
+ if(c != ' ') {
+ parser->item_offset = finfo->b_used -1;
+ parser->item_length = 1;
+ parser->state.NT.sub.filename = PL_WINNT_FILENAME_CONTENT;
+ }
+ break;
+ case PL_WINNT_FILENAME_CONTENT:
+ parser->item_length++;
+ if(c == '\r') {
+ parser->state.NT.sub.filename = PL_WINNT_FILENAME_WINEOL;
+ finfo->b_data[finfo->b_used - 1] = 0;
+ }
+ else if(c == '\n') {
+ parser->offsets.filename = parser->item_offset;
+ finfo->b_data[finfo->b_used - 1] = 0;
+ parser->offsets.filename = parser->item_offset;
+ result = ftp_pl_insert_finfo(conn, finfo);
+ if(result) {
+ PL_ERROR(conn, result);
+ return bufflen;
+ }
+ parser->state.NT.main = PL_WINNT_DATE;
+ parser->state.NT.sub.filename = PL_WINNT_FILENAME_PRESPACE;
+ }
+ break;
+ case PL_WINNT_FILENAME_WINEOL:
+ if(c == '\n') {
+ parser->offsets.filename = parser->item_offset;
+ result = ftp_pl_insert_finfo(conn, finfo);
+ if(result) {
+ PL_ERROR(conn, result);
+ return bufflen;
+ }
+ parser->state.NT.main = PL_WINNT_DATE;
+ parser->state.NT.sub.filename = PL_WINNT_FILENAME_PRESPACE;
+ }
+ else {
+ PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
+ return bufflen;
+ }
+ break;
+ }
+ break;
+ }
+ break;
+ default:
+ return bufflen + 1;
+ }
+
+ i++;
+ }
+
+ return bufflen;
+}
+
+#endif /* CURL_DISABLE_FTP */
diff --git a/Utilities/cmcurl/lib/ftplistparser.h b/Utilities/cmcurl/lib/ftplistparser.h
new file mode 100644
index 000000000..96764e2a4
--- /dev/null
+++ b/Utilities/cmcurl/lib/ftplistparser.h
@@ -0,0 +1,41 @@
+#ifndef HEADER_CURL_FTPLISTPARSER_H
+#define HEADER_CURL_FTPLISTPARSER_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_FTP
+
+/* WRITEFUNCTION callback for parsing LIST responses */
+size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
+ void *connptr);
+
+struct ftp_parselist_data; /* defined inside ftplibparser.c */
+
+CURLcode Curl_ftp_parselist_geterror(struct ftp_parselist_data *pl_data);
+
+struct ftp_parselist_data *Curl_ftp_parselist_data_alloc(void);
+
+void Curl_ftp_parselist_data_free(struct ftp_parselist_data **pl_data);
+
+#endif /* CURL_DISABLE_FTP */
+#endif /* HEADER_CURL_FTPLISTPARSER_H */
diff --git a/Utilities/cmcurl/lib/getenv.c b/Utilities/cmcurl/lib/getenv.c
new file mode 100644
index 000000000..36215aab0
--- /dev/null
+++ b/Utilities/cmcurl/lib/getenv.c
@@ -0,0 +1,53 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+#include "curl_memory.h"
+
+#include "memdebug.h"
+
+static
+char *GetEnv(const char *variable)
+{
+#ifdef _WIN32_WCE
+ return NULL;
+#else
+#ifdef WIN32
+ char env[MAX_PATH]; /* MAX_PATH is from windef.h */
+ char *temp = getenv(variable);
+ env[0] = '\0';
+ if(temp != NULL)
+ ExpandEnvironmentStringsA(temp, env, sizeof(env));
+ return (env[0] != '\0')?strdup(env):NULL;
+#else
+ char *env = getenv(variable);
+ return (env && env[0])?strdup(env):NULL;
+#endif
+#endif
+}
+
+char *curl_getenv(const char *v)
+{
+ return GetEnv(v);
+}
diff --git a/Utilities/cmcurl/lib/getinfo.c b/Utilities/cmcurl/lib/getinfo.c
new file mode 100644
index 000000000..910f520ed
--- /dev/null
+++ b/Utilities/cmcurl/lib/getinfo.c
@@ -0,0 +1,382 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#include "urldata.h"
+#include "getinfo.h"
+
+#include "vtls/vtls.h"
+#include "connect.h" /* Curl_getconnectinfo() */
+#include "progress.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+ * This is supposed to be called in the beginning of a perform() session
+ * and should reset all session-info variables
+ */
+CURLcode Curl_initinfo(struct SessionHandle *data)
+{
+ struct Progress *pro = &data->progress;
+ struct PureInfo *info = &data->info;
+
+ pro->t_nslookup = 0;
+ pro->t_connect = 0;
+ pro->t_appconnect = 0;
+ pro->t_pretransfer = 0;
+ pro->t_starttransfer = 0;
+ pro->timespent = 0;
+ pro->t_redirect = 0;
+
+ info->httpcode = 0;
+ info->httpproxycode = 0;
+ info->httpversion = 0;
+ info->filetime = -1; /* -1 is an illegal time and thus means unknown */
+ info->timecond = FALSE;
+
+ free(info->contenttype);
+ info->contenttype = NULL;
+
+ info->header_size = 0;
+ info->request_size = 0;
+ info->numconnects = 0;
+
+ info->conn_primary_ip[0] = '\0';
+ info->conn_local_ip[0] = '\0';
+ info->conn_primary_port = 0;
+ info->conn_local_port = 0;
+
+ return CURLE_OK;
+}
+
+static CURLcode getinfo_char(struct SessionHandle *data, CURLINFO info,
+ char **param_charp)
+{
+ switch(info) {
+ case CURLINFO_EFFECTIVE_URL:
+ *param_charp = data->change.url?data->change.url:(char *)"";
+ break;
+ case CURLINFO_CONTENT_TYPE:
+ *param_charp = data->info.contenttype;
+ break;
+ case CURLINFO_PRIVATE:
+ *param_charp = (char *) data->set.private_data;
+ break;
+ case CURLINFO_FTP_ENTRY_PATH:
+ /* Return the entrypath string from the most recent connection.
+ This pointer was copied from the connectdata structure by FTP.
+ The actual string may be free()ed by subsequent libcurl calls so
+ it must be copied to a safer area before the next libcurl call.
+ Callers must never free it themselves. */
+ *param_charp = data->state.most_recent_ftp_entrypath;
+ break;
+ case CURLINFO_REDIRECT_URL:
+ /* Return the URL this request would have been redirected to if that
+ option had been enabled! */
+ *param_charp = data->info.wouldredirect;
+ break;
+ case CURLINFO_PRIMARY_IP:
+ /* Return the ip address of the most recent (primary) connection */
+ *param_charp = data->info.conn_primary_ip;
+ break;
+ case CURLINFO_LOCAL_IP:
+ /* Return the source/local ip address of the most recent (primary)
+ connection */
+ *param_charp = data->info.conn_local_ip;
+ break;
+ case CURLINFO_RTSP_SESSION_ID:
+ *param_charp = data->set.str[STRING_RTSP_SESSION_ID];
+ break;
+
+ default:
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+
+ return CURLE_OK;
+}
+
+static CURLcode getinfo_long(struct SessionHandle *data, CURLINFO info,
+ long *param_longp)
+{
+ curl_socket_t sockfd;
+
+ union {
+ unsigned long *to_ulong;
+ long *to_long;
+ } lptr;
+
+ switch(info) {
+ case CURLINFO_RESPONSE_CODE:
+ *param_longp = data->info.httpcode;
+ break;
+ case CURLINFO_HTTP_CONNECTCODE:
+ *param_longp = data->info.httpproxycode;
+ break;
+ case CURLINFO_FILETIME:
+ *param_longp = data->info.filetime;
+ break;
+ case CURLINFO_HEADER_SIZE:
+ *param_longp = data->info.header_size;
+ break;
+ case CURLINFO_REQUEST_SIZE:
+ *param_longp = data->info.request_size;
+ break;
+ case CURLINFO_SSL_VERIFYRESULT:
+ *param_longp = data->set.ssl.certverifyresult;
+ break;
+ case CURLINFO_REDIRECT_COUNT:
+ *param_longp = data->set.followlocation;
+ break;
+ case CURLINFO_HTTPAUTH_AVAIL:
+ lptr.to_long = param_longp;
+ *lptr.to_ulong = data->info.httpauthavail;
+ break;
+ case CURLINFO_PROXYAUTH_AVAIL:
+ lptr.to_long = param_longp;
+ *lptr.to_ulong = data->info.proxyauthavail;
+ break;
+ case CURLINFO_OS_ERRNO:
+ *param_longp = data->state.os_errno;
+ break;
+ case CURLINFO_NUM_CONNECTS:
+ *param_longp = data->info.numconnects;
+ break;
+ case CURLINFO_LASTSOCKET:
+ sockfd = Curl_getconnectinfo(data, NULL);
+
+ /* note: this is not a good conversion for systems with 64 bit sockets and
+ 32 bit longs */
+ if(sockfd != CURL_SOCKET_BAD)
+ *param_longp = (long)sockfd;
+ else
+ /* this interface is documented to return -1 in case of badness, which
+ may not be the same as the CURL_SOCKET_BAD value */
+ *param_longp = -1;
+ break;
+ case CURLINFO_PRIMARY_PORT:
+ /* Return the (remote) port of the most recent (primary) connection */
+ *param_longp = data->info.conn_primary_port;
+ break;
+ case CURLINFO_LOCAL_PORT:
+ /* Return the local port of the most recent (primary) connection */
+ *param_longp = data->info.conn_local_port;
+ break;
+ case CURLINFO_CONDITION_UNMET:
+ /* return if the condition prevented the document to get transferred */
+ *param_longp = data->info.timecond ? 1L : 0L;
+ break;
+ case CURLINFO_RTSP_CLIENT_CSEQ:
+ *param_longp = data->state.rtsp_next_client_CSeq;
+ break;
+ case CURLINFO_RTSP_SERVER_CSEQ:
+ *param_longp = data->state.rtsp_next_server_CSeq;
+ break;
+ case CURLINFO_RTSP_CSEQ_RECV:
+ *param_longp = data->state.rtsp_CSeq_recv;
+ break;
+
+ default:
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+
+ return CURLE_OK;
+}
+
+static CURLcode getinfo_double(struct SessionHandle *data, CURLINFO info,
+ double *param_doublep)
+{
+ switch(info) {
+ case CURLINFO_TOTAL_TIME:
+ *param_doublep = data->progress.timespent;
+ break;
+ case CURLINFO_NAMELOOKUP_TIME:
+ *param_doublep = data->progress.t_nslookup;
+ break;
+ case CURLINFO_CONNECT_TIME:
+ *param_doublep = data->progress.t_connect;
+ break;
+ case CURLINFO_APPCONNECT_TIME:
+ *param_doublep = data->progress.t_appconnect;
+ break;
+ case CURLINFO_PRETRANSFER_TIME:
+ *param_doublep = data->progress.t_pretransfer;
+ break;
+ case CURLINFO_STARTTRANSFER_TIME:
+ *param_doublep = data->progress.t_starttransfer;
+ break;
+ case CURLINFO_SIZE_UPLOAD:
+ *param_doublep = (double)data->progress.uploaded;
+ break;
+ case CURLINFO_SIZE_DOWNLOAD:
+ *param_doublep = (double)data->progress.downloaded;
+ break;
+ case CURLINFO_SPEED_DOWNLOAD:
+ *param_doublep = (double)data->progress.dlspeed;
+ break;
+ case CURLINFO_SPEED_UPLOAD:
+ *param_doublep = (double)data->progress.ulspeed;
+ break;
+ case CURLINFO_CONTENT_LENGTH_DOWNLOAD:
+ *param_doublep = (data->progress.flags & PGRS_DL_SIZE_KNOWN)?
+ (double)data->progress.size_dl:-1;
+ break;
+ case CURLINFO_CONTENT_LENGTH_UPLOAD:
+ *param_doublep = (data->progress.flags & PGRS_UL_SIZE_KNOWN)?
+ (double)data->progress.size_ul:-1;
+ break;
+ case CURLINFO_REDIRECT_TIME:
+ *param_doublep = data->progress.t_redirect;
+ break;
+
+ default:
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+
+ return CURLE_OK;
+}
+
+static CURLcode getinfo_slist(struct SessionHandle *data, CURLINFO info,
+ struct curl_slist **param_slistp)
+{
+ union {
+ struct curl_certinfo *to_certinfo;
+ struct curl_slist *to_slist;
+ } ptr;
+
+ switch(info) {
+ case CURLINFO_SSL_ENGINES:
+ *param_slistp = Curl_ssl_engines_list(data);
+ break;
+ case CURLINFO_COOKIELIST:
+ *param_slistp = Curl_cookie_list(data);
+ break;
+ case CURLINFO_CERTINFO:
+ /* Return the a pointer to the certinfo struct. Not really an slist
+ pointer but we can pretend it is here */
+ ptr.to_certinfo = &data->info.certs;
+ *param_slistp = ptr.to_slist;
+ break;
+ case CURLINFO_TLS_SESSION:
+ {
+ struct curl_tlssessioninfo **tsip = (struct curl_tlssessioninfo **)
+ param_slistp;
+ struct curl_tlssessioninfo *tsi = &data->tsi;
+ struct connectdata *conn = data->easy_conn;
+ unsigned int sockindex = 0;
+ void *internals = NULL;
+
+ *tsip = tsi;
+ tsi->backend = CURLSSLBACKEND_NONE;
+ tsi->internals = NULL;
+
+ if(!conn)
+ break;
+
+ /* Find the active ("in use") SSL connection, if any */
+ while((sockindex < sizeof(conn->ssl) / sizeof(conn->ssl[0])) &&
+ (!conn->ssl[sockindex].use))
+ sockindex++;
+
+ if(sockindex == sizeof(conn->ssl) / sizeof(conn->ssl[0]))
+ break; /* no SSL session found */
+
+ /* Return the TLS session information from the relevant backend */
+#ifdef USE_OPENSSL
+ internals = conn->ssl[sockindex].ctx;
+#endif
+#ifdef USE_GNUTLS
+ internals = conn->ssl[sockindex].session;
+#endif
+#ifdef USE_NSS
+ internals = conn->ssl[sockindex].handle;
+#endif
+#ifdef USE_GSKIT
+ internals = conn->ssl[sockindex].handle;
+#endif
+ if(internals) {
+ tsi->backend = Curl_ssl_backend();
+ tsi->internals = internals;
+ }
+ /* NOTE: For other SSL backends, it is not immediately clear what data
+ to return from 'struct ssl_connect_data'; thus, for now we keep the
+ backend as CURLSSLBACKEND_NONE in those cases, which should be
+ interpreted as "not supported" */
+ }
+ break;
+ default:
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+
+ return CURLE_OK;
+}
+
+CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
+{
+ va_list arg;
+ long *param_longp = NULL;
+ double *param_doublep = NULL;
+ char **param_charp = NULL;
+ struct curl_slist **param_slistp = NULL;
+ int type;
+ /* default return code is to error out! */
+ CURLcode result = CURLE_BAD_FUNCTION_ARGUMENT;
+
+ if(!data)
+ return result;
+
+ va_start(arg, info);
+
+ type = CURLINFO_TYPEMASK & (int)info;
+ switch(type) {
+ case CURLINFO_STRING:
+ param_charp = va_arg(arg, char **);
+ if(param_charp)
+ result = getinfo_char(data, info, param_charp);
+ break;
+ case CURLINFO_LONG:
+ param_longp = va_arg(arg, long *);
+ if(param_longp)
+ result = getinfo_long(data, info, param_longp);
+ break;
+ case CURLINFO_DOUBLE:
+ param_doublep = va_arg(arg, double *);
+ if(param_doublep)
+ result = getinfo_double(data, info, param_doublep);
+ break;
+ case CURLINFO_SLIST:
+ param_slistp = va_arg(arg, struct curl_slist **);
+ if(param_slistp)
+ result = getinfo_slist(data, info, param_slistp);
+ break;
+ default:
+ break;
+ }
+
+ va_end(arg);
+
+ return result;
+}
diff --git a/Utilities/cmcurl/lib/getinfo.h b/Utilities/cmcurl/lib/getinfo.h
new file mode 100644
index 000000000..3879ff73a
--- /dev/null
+++ b/Utilities/cmcurl/lib/getinfo.h
@@ -0,0 +1,27 @@
+#ifndef HEADER_CURL_GETINFO_H
+#define HEADER_CURL_GETINFO_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...);
+CURLcode Curl_initinfo(struct SessionHandle *data);
+
+#endif /* HEADER_CURL_GETINFO_H */
diff --git a/Utilities/cmcurl/lib/gopher.c b/Utilities/cmcurl/lib/gopher.c
new file mode 100644
index 000000000..954cad8e0
--- /dev/null
+++ b/Utilities/cmcurl/lib/gopher.c
@@ -0,0 +1,165 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_GOPHER
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "transfer.h"
+#include "sendf.h"
+
+#include "progress.h"
+#include "strequal.h"
+#include "gopher.h"
+#include "rawstr.h"
+#include "select.h"
+#include "url.h"
+#include "warnless.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ * Forward declarations.
+ */
+
+static CURLcode gopher_do(struct connectdata *conn, bool *done);
+
+/*
+ * Gopher protocol handler.
+ * This is also a nice simple template to build off for simple
+ * connect-command-download protocols.
+ */
+
+const struct Curl_handler Curl_handler_gopher = {
+ "GOPHER", /* scheme */
+ ZERO_NULL, /* setup_connection */
+ gopher_do, /* do_it */
+ ZERO_NULL, /* done */
+ ZERO_NULL, /* do_more */
+ ZERO_NULL, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_getsock */
+ ZERO_NULL, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ ZERO_NULL, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_GOPHER, /* defport */
+ CURLPROTO_GOPHER, /* protocol */
+ PROTOPT_NONE /* flags */
+};
+
+static CURLcode gopher_do(struct connectdata *conn, bool *done)
+{
+ CURLcode result=CURLE_OK;
+ struct SessionHandle *data=conn->data;
+ curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
+
+ curl_off_t *bytecount = &data->req.bytecount;
+ char *path = data->state.path;
+ char *sel;
+ char *sel_org = NULL;
+ ssize_t amount, k;
+
+ *done = TRUE; /* unconditionally */
+
+ /* Create selector. Degenerate cases: / and /1 => convert to "" */
+ if(strlen(path) <= 2)
+ sel = (char *)"";
+ else {
+ char *newp;
+ size_t j, i;
+ int len;
+
+ /* Otherwise, drop / and the first character (i.e., item type) ... */
+ newp = path;
+ newp+=2;
+
+ /* ... then turn ? into TAB for search servers, Veronica, etc. ... */
+ j = strlen(newp);
+ for(i=0; i<j; i++)
+ if(newp[i] == '?')
+ newp[i] = '\x09';
+
+ /* ... and finally unescape */
+ sel = curl_easy_unescape(data, newp, 0, &len);
+ if(!sel)
+ return CURLE_OUT_OF_MEMORY;
+ sel_org = sel;
+ }
+
+ /* We use Curl_write instead of Curl_sendf to make sure the entire buffer is
+ sent, which could be sizeable with long selectors. */
+ k = curlx_uztosz(strlen(sel));
+
+ for(;;) {
+ result = Curl_write(conn, sockfd, sel, k, &amount);
+ if(!result) { /* Which may not have written it all! */
+ result = Curl_client_write(conn, CLIENTWRITE_HEADER, sel, amount);
+ if(result) {
+ free(sel_org);
+ return result;
+ }
+ k -= amount;
+ sel += amount;
+ if(k < 1)
+ break; /* but it did write it all */
+ }
+ else {
+ failf(data, "Failed sending Gopher request");
+ free(sel_org);
+ return result;
+ }
+ /* Don't busyloop. The entire loop thing is a work-around as it causes a
+ BLOCKING behavior which is a NO-NO. This function should rather be
+ split up in a do and a doing piece where the pieces that aren't
+ possible to send now will be sent in the doing function repeatedly
+ until the entire request is sent.
+
+ Wait a while for the socket to be writable. Note that this doesn't
+ acknowledge the timeout.
+ */
+ Curl_socket_ready(CURL_SOCKET_BAD, sockfd, 100);
+ }
+
+ free(sel_org);
+
+ /* We can use Curl_sendf to send the terminal \r\n relatively safely and
+ save allocing another string/doing another _write loop. */
+ result = Curl_sendf(sockfd, conn, "\r\n");
+ if(result) {
+ failf(data, "Failed sending Gopher request");
+ return result;
+ }
+ result = Curl_client_write(conn, CLIENTWRITE_HEADER, (char *)"\r\n", 2);
+ if(result)
+ return result;
+
+ Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
+ -1, NULL); /* no upload */
+ return CURLE_OK;
+}
+#endif /*CURL_DISABLE_GOPHER*/
diff --git a/Utilities/cmcurl/lib/gopher.h b/Utilities/cmcurl/lib/gopher.h
new file mode 100644
index 000000000..38bbc4b73
--- /dev/null
+++ b/Utilities/cmcurl/lib/gopher.h
@@ -0,0 +1,29 @@
+#ifndef HEADER_CURL_GOPHER_H
+#define HEADER_CURL_GOPHER_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifndef CURL_DISABLE_GOPHER
+extern const struct Curl_handler Curl_handler_gopher;
+#endif
+
+#endif /* HEADER_CURL_GOPHER_H */
diff --git a/Utilities/cmcurl/lib/hash.c b/Utilities/cmcurl/lib/hash.c
new file mode 100644
index 000000000..c46760ae1
--- /dev/null
+++ b/Utilities/cmcurl/lib/hash.c
@@ -0,0 +1,368 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "hash.h"
+#include "llist.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+static void
+hash_element_dtor(void *user, void *element)
+{
+ struct curl_hash *h = (struct curl_hash *) user;
+ struct curl_hash_element *e = (struct curl_hash_element *) element;
+
+ Curl_safefree(e->key);
+
+ if(e->ptr) {
+ h->dtor(e->ptr);
+ e->ptr = NULL;
+ }
+
+ e->key_len = 0;
+
+ free(e);
+}
+
+/* return 1 on error, 0 is fine */
+int
+Curl_hash_init(struct curl_hash *h,
+ int slots,
+ hash_function hfunc,
+ comp_function comparator,
+ curl_hash_dtor dtor)
+{
+ int i;
+
+ if(!slots || !hfunc || !comparator ||!dtor) {
+ return 1; /* failure */
+ }
+
+ h->hash_func = hfunc;
+ h->comp_func = comparator;
+ h->dtor = dtor;
+ h->size = 0;
+ h->slots = slots;
+
+ h->table = malloc(slots * sizeof(struct curl_llist *));
+ if(h->table) {
+ for(i = 0; i < slots; ++i) {
+ h->table[i] = Curl_llist_alloc((curl_llist_dtor) hash_element_dtor);
+ if(!h->table[i]) {
+ while(i--) {
+ Curl_llist_destroy(h->table[i], NULL);
+ h->table[i] = NULL;
+ }
+ free(h->table);
+ h->table = NULL;
+ h->slots = 0;
+ return 1; /* failure */
+ }
+ }
+ return 0; /* fine */
+ }
+ else {
+ h->slots = 0;
+ return 1; /* failure */
+ }
+}
+
+static struct curl_hash_element *
+mk_hash_element(const void *key, size_t key_len, const void *p)
+{
+ struct curl_hash_element *he = malloc(sizeof(struct curl_hash_element));
+
+ if(he) {
+ void *dupkey = malloc(key_len);
+ if(dupkey) {
+ /* copy the key */
+ memcpy(dupkey, key, key_len);
+
+ he->key = dupkey;
+ he->key_len = key_len;
+ he->ptr = (void *) p;
+ }
+ else {
+ /* failed to duplicate the key, free memory and fail */
+ free(he);
+ he = NULL;
+ }
+ }
+ return he;
+}
+
+#define FETCH_LIST(x,y,z) x->table[x->hash_func(y, z, x->slots)]
+
+/* Insert the data in the hash. If there already was a match in the hash,
+ * that data is replaced.
+ *
+ * @unittest: 1305
+ */
+void *
+Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p)
+{
+ struct curl_hash_element *he;
+ struct curl_llist_element *le;
+ struct curl_llist *l = FETCH_LIST (h, key, key_len);
+
+ for(le = l->head; le; le = le->next) {
+ he = (struct curl_hash_element *) le->ptr;
+ if(h->comp_func(he->key, he->key_len, key, key_len)) {
+ Curl_llist_remove(l, le, (void *)h);
+ --h->size;
+ break;
+ }
+ }
+
+ he = mk_hash_element(key, key_len, p);
+ if(he) {
+ if(Curl_llist_insert_next(l, l->tail, he)) {
+ ++h->size;
+ return p; /* return the new entry */
+ }
+ /*
+ * Couldn't insert it, destroy the 'he' element and the key again. We
+ * don't call hash_element_dtor() since that would also call the
+ * "destructor" for the actual data 'p'. When we fail, we shall not touch
+ * that data.
+ */
+ free(he->key);
+ free(he);
+ }
+
+ return NULL; /* failure */
+}
+
+/* remove the identified hash entry, returns non-zero on failure */
+int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len)
+{
+ struct curl_llist_element *le;
+ struct curl_hash_element *he;
+ struct curl_llist *l = FETCH_LIST(h, key, key_len);
+
+ for(le = l->head; le; le = le->next) {
+ he = le->ptr;
+ if(h->comp_func(he->key, he->key_len, key, key_len)) {
+ Curl_llist_remove(l, le, (void *) h);
+ --h->size;
+ return 0;
+ }
+ }
+ return 1;
+}
+
+void *
+Curl_hash_pick(struct curl_hash *h, void *key, size_t key_len)
+{
+ struct curl_llist_element *le;
+ struct curl_hash_element *he;
+ struct curl_llist *l;
+
+ if(h) {
+ l = FETCH_LIST(h, key, key_len);
+ for(le = l->head; le; le = le->next) {
+ he = le->ptr;
+ if(h->comp_func(he->key, he->key_len, key, key_len)) {
+ return he->ptr;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+#if defined(DEBUGBUILD) && defined(AGGRESIVE_TEST)
+void
+Curl_hash_apply(curl_hash *h, void *user,
+ void (*cb)(void *user, void *ptr))
+{
+ struct curl_llist_element *le;
+ int i;
+
+ for(i = 0; i < h->slots; ++i) {
+ for(le = (h->table[i])->head;
+ le;
+ le = le->next) {
+ curl_hash_element *el = le->ptr;
+ cb(user, el->ptr);
+ }
+ }
+}
+#endif
+
+/* Destroys all the entries in the given hash and resets its attributes,
+ * prepping the given hash for [static|dynamic] deallocation.
+ */
+void
+Curl_hash_destroy(struct curl_hash *h)
+{
+ int i;
+
+ for(i = 0; i < h->slots; ++i) {
+ Curl_llist_destroy(h->table[i], (void *) h);
+ h->table[i] = NULL;
+ }
+
+ Curl_safefree(h->table);
+ h->size = 0;
+ h->slots = 0;
+}
+
+/* Removes all the entries in the given hash.
+ *
+ * @unittest: 1602
+ */
+void
+Curl_hash_clean(struct curl_hash *h)
+{
+ Curl_hash_clean_with_criterium(h, NULL, NULL);
+}
+
+/* Cleans all entries that pass the comp function criteria. */
+void
+Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
+ int (*comp)(void *, void *))
+{
+ struct curl_llist_element *le;
+ struct curl_llist_element *lnext;
+ struct curl_llist *list;
+ int i;
+
+ if(!h)
+ return;
+
+ for(i = 0; i < h->slots; ++i) {
+ list = h->table[i];
+ le = list->head; /* get first list entry */
+ while(le) {
+ struct curl_hash_element *he = le->ptr;
+ lnext = le->next;
+ /* ask the callback function if we shall remove this entry or not */
+ if(comp == NULL || comp(user, he->ptr)) {
+ Curl_llist_remove(list, le, (void *) h);
+ --h->size; /* one less entry in the hash now */
+ }
+ le = lnext;
+ }
+ }
+}
+
+size_t Curl_hash_str(void* key, size_t key_length, size_t slots_num)
+{
+ const char* key_str = (const char *) key;
+ const char *end = key_str + key_length;
+ unsigned long h = 5381;
+
+ while(key_str < end) {
+ h += h << 5;
+ h ^= (unsigned long) *key_str++;
+ }
+
+ return (h % slots_num);
+}
+
+size_t Curl_str_key_compare(void *k1, size_t key1_len,
+ void *k2, size_t key2_len)
+{
+ if((key1_len == key2_len) && !memcmp(k1, k2, key1_len))
+ return 1;
+
+ return 0;
+}
+
+void Curl_hash_start_iterate(struct curl_hash *hash,
+ struct curl_hash_iterator *iter)
+{
+ iter->hash = hash;
+ iter->slot_index = 0;
+ iter->current_element = NULL;
+}
+
+struct curl_hash_element *
+Curl_hash_next_element(struct curl_hash_iterator *iter)
+{
+ int i;
+ struct curl_hash *h = iter->hash;
+
+ /* Get the next element in the current list, if any */
+ if(iter->current_element)
+ iter->current_element = iter->current_element->next;
+
+ /* If we have reached the end of the list, find the next one */
+ if(!iter->current_element) {
+ for(i = iter->slot_index;i < h->slots;i++) {
+ if(h->table[i]->head) {
+ iter->current_element = h->table[i]->head;
+ iter->slot_index = i+1;
+ break;
+ }
+ }
+ }
+
+ if(iter->current_element) {
+ struct curl_hash_element *he = iter->current_element->ptr;
+ return he;
+ }
+ else {
+ iter->current_element = NULL;
+ return NULL;
+ }
+}
+
+#if 0 /* useful function for debugging hashes and their contents */
+void Curl_hash_print(struct curl_hash *h,
+ void (*func)(void *))
+{
+ struct curl_hash_iterator iter;
+ struct curl_hash_element *he;
+ int last_index = -1;
+
+ if(!h)
+ return;
+
+ fprintf(stderr, "=Hash dump=\n");
+
+ Curl_hash_start_iterate(h, &iter);
+
+ he = Curl_hash_next_element(&iter);
+ while(he) {
+ if(iter.slot_index != last_index) {
+ fprintf(stderr, "index %d:", iter.slot_index);
+ if(last_index >= 0) {
+ fprintf(stderr, "\n");
+ }
+ last_index = iter.slot_index;
+ }
+
+ if(func)
+ func(he->ptr);
+ else
+ fprintf(stderr, " [%p]", (void *)he->ptr);
+
+ he = Curl_hash_next_element(&iter);
+ }
+ fprintf(stderr, "\n");
+}
+#endif
diff --git a/Utilities/cmcurl/lib/hash.h b/Utilities/cmcurl/lib/hash.h
new file mode 100644
index 000000000..b13a236bb
--- /dev/null
+++ b/Utilities/cmcurl/lib/hash.h
@@ -0,0 +1,100 @@
+#ifndef HEADER_CURL_HASH_H
+#define HEADER_CURL_HASH_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <stddef.h>
+
+#include "llist.h"
+
+/* Hash function prototype */
+typedef size_t (*hash_function) (void* key,
+ size_t key_length,
+ size_t slots_num);
+
+/*
+ Comparator function prototype. Compares two keys.
+*/
+typedef size_t (*comp_function) (void* key1,
+ size_t key1_len,
+ void*key2,
+ size_t key2_len);
+
+typedef void (*curl_hash_dtor)(void *);
+
+struct curl_hash {
+ struct curl_llist **table;
+
+ /* Hash function to be used for this hash table */
+ hash_function hash_func;
+
+ /* Comparator function to compare keys */
+ comp_function comp_func;
+ curl_hash_dtor dtor;
+ int slots;
+ size_t size;
+};
+
+struct curl_hash_element {
+ void *ptr;
+ char *key;
+ size_t key_len;
+};
+
+struct curl_hash_iterator {
+ struct curl_hash *hash;
+ int slot_index;
+ struct curl_llist_element *current_element;
+};
+
+int Curl_hash_init(struct curl_hash *h,
+ int slots,
+ hash_function hfunc,
+ comp_function comparator,
+ curl_hash_dtor dtor);
+
+void *Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p);
+int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len);
+void *Curl_hash_pick(struct curl_hash *, void * key, size_t key_len);
+void Curl_hash_apply(struct curl_hash *h, void *user,
+ void (*cb)(void *user, void *ptr));
+int Curl_hash_count(struct curl_hash *h);
+void Curl_hash_destroy(struct curl_hash *h);
+void Curl_hash_clean(struct curl_hash *h);
+void Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
+ int (*comp)(void *, void *));
+size_t Curl_hash_str(void* key, size_t key_length, size_t slots_num);
+size_t Curl_str_key_compare(void*k1, size_t key1_len, void*k2,
+ size_t key2_len);
+
+void Curl_hash_start_iterate(struct curl_hash *hash,
+ struct curl_hash_iterator *iter);
+struct curl_hash_element *
+Curl_hash_next_element(struct curl_hash_iterator *iter);
+
+void Curl_hash_print(struct curl_hash *h,
+ void (*func)(void *));
+
+
+#endif /* HEADER_CURL_HASH_H */
diff --git a/Utilities/cmcurl/lib/hmac.c b/Utilities/cmcurl/lib/hmac.c
new file mode 100644
index 000000000..0d2d5f45d
--- /dev/null
+++ b/Utilities/cmcurl/lib/hmac.c
@@ -0,0 +1,129 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * RFC2104 Keyed-Hashing for Message Authentication
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+
+#include "curl_hmac.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ * Generic HMAC algorithm.
+ *
+ * This module computes HMAC digests based on any hash function. Parameters
+ * and computing procedures are set-up dynamically at HMAC computation
+ * context initialisation.
+ */
+
+static const unsigned char hmac_ipad = 0x36;
+static const unsigned char hmac_opad = 0x5C;
+
+
+
+HMAC_context *
+Curl_HMAC_init(const HMAC_params * hashparams,
+ const unsigned char * key,
+ unsigned int keylen)
+{
+ size_t i;
+ HMAC_context * ctxt;
+ unsigned char * hkey;
+ unsigned char b;
+
+ /* Create HMAC context. */
+ i = sizeof *ctxt + 2 * hashparams->hmac_ctxtsize +
+ hashparams->hmac_resultlen;
+ ctxt = malloc(i);
+
+ if(!ctxt)
+ return ctxt;
+
+ ctxt->hmac_hash = hashparams;
+ ctxt->hmac_hashctxt1 = (void *) (ctxt + 1);
+ ctxt->hmac_hashctxt2 = (void *) ((char *) ctxt->hmac_hashctxt1 +
+ hashparams->hmac_ctxtsize);
+
+ /* If the key is too long, replace it by its hash digest. */
+ if(keylen > hashparams->hmac_maxkeylen) {
+ (*hashparams->hmac_hinit)(ctxt->hmac_hashctxt1);
+ (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt1, key, keylen);
+ hkey = (unsigned char *) ctxt->hmac_hashctxt2 + hashparams->hmac_ctxtsize;
+ (*hashparams->hmac_hfinal)(hkey, ctxt->hmac_hashctxt1);
+ key = hkey;
+ keylen = hashparams->hmac_resultlen;
+ }
+
+ /* Prime the two hash contexts with the modified key. */
+ (*hashparams->hmac_hinit)(ctxt->hmac_hashctxt1);
+ (*hashparams->hmac_hinit)(ctxt->hmac_hashctxt2);
+
+ for(i = 0; i < keylen; i++) {
+ b = (unsigned char)(*key ^ hmac_ipad);
+ (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt1, &b, 1);
+ b = (unsigned char)(*key++ ^ hmac_opad);
+ (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt2, &b, 1);
+ }
+
+ for(; i < hashparams->hmac_maxkeylen; i++) {
+ (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt1, &hmac_ipad, 1);
+ (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt2, &hmac_opad, 1);
+ }
+
+ /* Done, return pointer to HMAC context. */
+ return ctxt;
+}
+
+int Curl_HMAC_update(HMAC_context * ctxt,
+ const unsigned char * data,
+ unsigned int len)
+{
+ /* Update first hash calculation. */
+ (*ctxt->hmac_hash->hmac_hupdate)(ctxt->hmac_hashctxt1, data, len);
+ return 0;
+}
+
+
+int Curl_HMAC_final(HMAC_context * ctxt, unsigned char * result)
+{
+ const HMAC_params * hashparams = ctxt->hmac_hash;
+
+ /* Do not get result if called with a null parameter: only release
+ storage. */
+
+ if(!result)
+ result = (unsigned char *) ctxt->hmac_hashctxt2 +
+ ctxt->hmac_hash->hmac_ctxtsize;
+
+ (*hashparams->hmac_hfinal)(result, ctxt->hmac_hashctxt1);
+ (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt2,
+ result, hashparams->hmac_resultlen);
+ (*hashparams->hmac_hfinal)(result, ctxt->hmac_hashctxt2);
+ free((char *) ctxt);
+ return 0;
+}
+
+#endif /* CURL_DISABLE_CRYPTO_AUTH */
diff --git a/Utilities/cmcurl/lib/hostasyn.c b/Utilities/cmcurl/lib/hostasyn.c
new file mode 100644
index 000000000..17b8be072
--- /dev/null
+++ b/Utilities/cmcurl/lib/hostasyn.c
@@ -0,0 +1,153 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "hash.h"
+#include "share.h"
+#include "strerror.h"
+#include "url.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/***********************************************************************
+ * Only for builds using asynchronous name resolves
+ **********************************************************************/
+#ifdef CURLRES_ASYNCH
+
+/*
+ * Curl_addrinfo_callback() gets called by ares, gethostbyname_thread()
+ * or getaddrinfo_thread() when we got the name resolved (or not!).
+ *
+ * If the status argument is CURL_ASYNC_SUCCESS, this function takes
+ * ownership of the Curl_addrinfo passed, storing the resolved data
+ * in the DNS cache.
+ *
+ * The storage operation locks and unlocks the DNS cache.
+ */
+CURLcode Curl_addrinfo_callback(struct connectdata *conn,
+ int status,
+ struct Curl_addrinfo *ai)
+{
+ struct Curl_dns_entry *dns = NULL;
+ CURLcode result = CURLE_OK;
+
+ conn->async.status = status;
+
+ if(CURL_ASYNC_SUCCESS == status) {
+ if(ai) {
+ struct SessionHandle *data = conn->data;
+
+ if(data->share)
+ Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+ dns = Curl_cache_addr(data, ai,
+ conn->async.hostname,
+ conn->async.port);
+ if(!dns) {
+ /* failed to store, cleanup and return error */
+ Curl_freeaddrinfo(ai);
+ result = CURLE_OUT_OF_MEMORY;
+ }
+
+ if(data->share)
+ Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+ }
+ else {
+ result = CURLE_OUT_OF_MEMORY;
+ }
+ }
+
+ conn->async.dns = dns;
+
+ /* Set async.done TRUE last in this function since it may be used multi-
+ threaded and once this is TRUE the other thread may read fields from the
+ async struct */
+ conn->async.done = TRUE;
+
+ /* IPv4: The input hostent struct will be freed by ares when we return from
+ this function */
+ return result;
+}
+
+/* Call this function after Curl_connect() has returned async=TRUE and
+ then a successful name resolve has been received.
+
+ Note: this function disconnects and frees the conn data in case of
+ resolve failure */
+CURLcode Curl_async_resolved(struct connectdata *conn,
+ bool *protocol_done)
+{
+ CURLcode result;
+
+ if(conn->async.dns) {
+ conn->dns_entry = conn->async.dns;
+ conn->async.dns = NULL;
+ }
+
+ result = Curl_setup_conn(conn, protocol_done);
+
+ if(result)
+ /* We're not allowed to return failure with memory left allocated
+ in the connectdata struct, free those here */
+ Curl_disconnect(conn, FALSE); /* close the connection */
+
+ return result;
+}
+
+/*
+ * Curl_getaddrinfo() is the generic low-level name resolve API within this
+ * source file. There are several versions of this function - for different
+ * name resolve layers (selected at build-time). They all take this same set
+ * of arguments
+ */
+Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
+ const char *hostname,
+ int port,
+ int *waitp)
+{
+ return Curl_resolver_getaddrinfo(conn, hostname, port, waitp);
+}
+
+#endif /* CURLRES_ASYNCH */
diff --git a/Utilities/cmcurl/lib/hostcheck.c b/Utilities/cmcurl/lib/hostcheck.c
new file mode 100644
index 000000000..62a26e4f2
--- /dev/null
+++ b/Utilities/cmcurl/lib/hostcheck.c
@@ -0,0 +1,147 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_OPENSSL) || defined(USE_AXTLS) || defined(USE_GSKIT)
+/* these backends use functions from this file */
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#include "hostcheck.h"
+#include "rawstr.h"
+#include "inet_pton.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ * Match a hostname against a wildcard pattern.
+ * E.g.
+ * "foo.host.com" matches "*.host.com".
+ *
+ * We use the matching rule described in RFC6125, section 6.4.3.
+ * http://tools.ietf.org/html/rfc6125#section-6.4.3
+ *
+ * In addition: ignore trailing dots in the host names and wildcards, so that
+ * the names are used normalized. This is what the browsers do.
+ *
+ * Do not allow wildcard matching on IP numbers. There are apparently
+ * certificates being used with an IP address in the CN field, thus making no
+ * apparent distinction between a name and an IP. We need to detect the use of
+ * an IP address and not wildcard match on such names.
+ *
+ * NOTE: hostmatch() gets called with copied buffers so that it can modify the
+ * contents at will.
+ */
+
+static int hostmatch(char *hostname, char *pattern)
+{
+ const char *pattern_label_end, *pattern_wildcard, *hostname_label_end;
+ int wildcard_enabled;
+ size_t prefixlen, suffixlen;
+ struct in_addr ignored;
+#ifdef ENABLE_IPV6
+ struct sockaddr_in6 si6;
+#endif
+
+ /* normalize pattern and hostname by stripping off trailing dots */
+ size_t len = strlen(hostname);
+ if(hostname[len-1]=='.')
+ hostname[len-1]=0;
+ len = strlen(pattern);
+ if(pattern[len-1]=='.')
+ pattern[len-1]=0;
+
+ pattern_wildcard = strchr(pattern, '*');
+ if(pattern_wildcard == NULL)
+ return Curl_raw_equal(pattern, hostname) ?
+ CURL_HOST_MATCH : CURL_HOST_NOMATCH;
+
+ /* detect IP address as hostname and fail the match if so */
+ if(Curl_inet_pton(AF_INET, hostname, &ignored) > 0)
+ return CURL_HOST_NOMATCH;
+#ifdef ENABLE_IPV6
+ else if(Curl_inet_pton(AF_INET6, hostname, &si6.sin6_addr) > 0)
+ return CURL_HOST_NOMATCH;
+#endif
+
+ /* We require at least 2 dots in pattern to avoid too wide wildcard
+ match. */
+ wildcard_enabled = 1;
+ pattern_label_end = strchr(pattern, '.');
+ if(pattern_label_end == NULL || strchr(pattern_label_end+1, '.') == NULL ||
+ pattern_wildcard > pattern_label_end ||
+ Curl_raw_nequal(pattern, "xn--", 4)) {
+ wildcard_enabled = 0;
+ }
+ if(!wildcard_enabled)
+ return Curl_raw_equal(pattern, hostname) ?
+ CURL_HOST_MATCH : CURL_HOST_NOMATCH;
+
+ hostname_label_end = strchr(hostname, '.');
+ if(hostname_label_end == NULL ||
+ !Curl_raw_equal(pattern_label_end, hostname_label_end))
+ return CURL_HOST_NOMATCH;
+
+ /* The wildcard must match at least one character, so the left-most
+ label of the hostname is at least as large as the left-most label
+ of the pattern. */
+ if(hostname_label_end - hostname < pattern_label_end - pattern)
+ return CURL_HOST_NOMATCH;
+
+ prefixlen = pattern_wildcard - pattern;
+ suffixlen = pattern_label_end - (pattern_wildcard+1);
+ return Curl_raw_nequal(pattern, hostname, prefixlen) &&
+ Curl_raw_nequal(pattern_wildcard+1, hostname_label_end - suffixlen,
+ suffixlen) ?
+ CURL_HOST_MATCH : CURL_HOST_NOMATCH;
+}
+
+int Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
+{
+ char *matchp;
+ char *hostp;
+ int res = 0;
+ if(!match_pattern || !*match_pattern ||
+ !hostname || !*hostname) /* sanity check */
+ ;
+ else {
+ matchp = strdup(match_pattern);
+ if(matchp) {
+ hostp = strdup(hostname);
+ if(hostp) {
+ if(hostmatch(hostp, matchp) == CURL_HOST_MATCH)
+ res= 1;
+ free(hostp);
+ }
+ free(matchp);
+ }
+ }
+
+ return res;
+}
+
+#endif /* OPENSSL or AXTLS or GSKIT */
diff --git a/Utilities/cmcurl/lib/hostcheck.h b/Utilities/cmcurl/lib/hostcheck.h
new file mode 100644
index 000000000..f4a517a8e
--- /dev/null
+++ b/Utilities/cmcurl/lib/hostcheck.h
@@ -0,0 +1,32 @@
+#ifndef HEADER_CURL_HOSTCHECK_H
+#define HEADER_CURL_HOSTCHECK_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <curl/curl.h>
+
+#define CURL_HOST_NOMATCH 0
+#define CURL_HOST_MATCH 1
+int Curl_cert_hostcheck(const char *match_pattern, const char *hostname);
+
+#endif /* HEADER_CURL_HOSTCHECK_H */
+
diff --git a/Utilities/cmcurl/lib/hostip.c b/Utilities/cmcurl/lib/hostip.c
new file mode 100644
index 000000000..82f3897f9
--- /dev/null
+++ b/Utilities/cmcurl/lib/hostip.c
@@ -0,0 +1,880 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#ifdef HAVE_SETJMP_H
+#include <setjmp.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "hash.h"
+#include "share.h"
+#include "strerror.h"
+#include "url.h"
+#include "inet_ntop.h"
+#include "warnless.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#if defined(CURLRES_SYNCH) && \
+ defined(HAVE_ALARM) && defined(SIGALRM) && defined(HAVE_SIGSETJMP)
+/* alarm-based timeouts can only be used with all the dependencies satisfied */
+#define USE_ALARM_TIMEOUT
+#endif
+
+/*
+ * hostip.c explained
+ * ==================
+ *
+ * The main COMPILE-TIME DEFINES to keep in mind when reading the host*.c
+ * source file are these:
+ *
+ * CURLRES_IPV6 - this host has getaddrinfo() and family, and thus we use
+ * that. The host may not be able to resolve IPv6, but we don't really have to
+ * take that into account. Hosts that aren't IPv6-enabled have CURLRES_IPV4
+ * defined.
+ *
+ * CURLRES_ARES - is defined if libcurl is built to use c-ares for
+ * asynchronous name resolves. This can be Windows or *nix.
+ *
+ * CURLRES_THREADED - is defined if libcurl is built to run under (native)
+ * Windows, and then the name resolve will be done in a new thread, and the
+ * supported API will be the same as for ares-builds.
+ *
+ * If any of the two previous are defined, CURLRES_ASYNCH is defined too. If
+ * libcurl is not built to use an asynchronous resolver, CURLRES_SYNCH is
+ * defined.
+ *
+ * The host*.c sources files are split up like this:
+ *
+ * hostip.c - method-independent resolver functions and utility functions
+ * hostasyn.c - functions for asynchronous name resolves
+ * hostsyn.c - functions for synchronous name resolves
+ * hostip4.c - IPv4 specific functions
+ * hostip6.c - IPv6 specific functions
+ *
+ * The two asynchronous name resolver backends are implemented in:
+ * asyn-ares.c - functions for ares-using name resolves
+ * asyn-thread.c - functions for threaded name resolves
+
+ * The hostip.h is the united header file for all this. It defines the
+ * CURLRES_* defines based on the config*.h and curl_setup.h defines.
+ */
+
+/* These two symbols are for the global DNS cache */
+static struct curl_hash hostname_cache;
+static int host_cache_initialized;
+
+static void freednsentry(void *freethis);
+
+/*
+ * Curl_global_host_cache_init() initializes and sets up a global DNS cache.
+ * Global DNS cache is general badness. Do not use. This will be removed in
+ * a future version. Use the share interface instead!
+ *
+ * Returns a struct curl_hash pointer on success, NULL on failure.
+ */
+struct curl_hash *Curl_global_host_cache_init(void)
+{
+ int rc = 0;
+ if(!host_cache_initialized) {
+ rc = Curl_hash_init(&hostname_cache, 7, Curl_hash_str,
+ Curl_str_key_compare, freednsentry);
+ if(!rc)
+ host_cache_initialized = 1;
+ }
+ return rc?NULL:&hostname_cache;
+}
+
+/*
+ * Destroy and cleanup the global DNS cache
+ */
+void Curl_global_host_cache_dtor(void)
+{
+ if(host_cache_initialized) {
+ Curl_hash_destroy(&hostname_cache);
+ host_cache_initialized = 0;
+ }
+}
+
+/*
+ * Return # of adresses in a Curl_addrinfo struct
+ */
+int Curl_num_addresses(const Curl_addrinfo *addr)
+{
+ int i = 0;
+ while(addr) {
+ addr = addr->ai_next;
+ i++;
+ }
+ return i;
+}
+
+/*
+ * Curl_printable_address() returns a printable version of the 1st address
+ * given in the 'ai' argument. The result will be stored in the buf that is
+ * bufsize bytes big.
+ *
+ * If the conversion fails, it returns NULL.
+ */
+const char *
+Curl_printable_address(const Curl_addrinfo *ai, char *buf, size_t bufsize)
+{
+ const struct sockaddr_in *sa4;
+ const struct in_addr *ipaddr4;
+#ifdef ENABLE_IPV6
+ const struct sockaddr_in6 *sa6;
+ const struct in6_addr *ipaddr6;
+#endif
+
+ switch (ai->ai_family) {
+ case AF_INET:
+ sa4 = (const void *)ai->ai_addr;
+ ipaddr4 = &sa4->sin_addr;
+ return Curl_inet_ntop(ai->ai_family, (const void *)ipaddr4, buf,
+ bufsize);
+#ifdef ENABLE_IPV6
+ case AF_INET6:
+ sa6 = (const void *)ai->ai_addr;
+ ipaddr6 = &sa6->sin6_addr;
+ return Curl_inet_ntop(ai->ai_family, (const void *)ipaddr6, buf,
+ bufsize);
+#endif
+ default:
+ break;
+ }
+ return NULL;
+}
+
+/*
+ * Return a hostcache id string for the provided host + port, to be used by
+ * the DNS caching.
+ */
+static char *
+create_hostcache_id(const char *name, int port)
+{
+ /* create and return the new allocated entry */
+ char *id = aprintf("%s:%d", name, port);
+ char *ptr = id;
+ if(ptr) {
+ /* lower case the name part */
+ while(*ptr && (*ptr != ':')) {
+ *ptr = (char)TOLOWER(*ptr);
+ ptr++;
+ }
+ }
+ return id;
+}
+
+struct hostcache_prune_data {
+ long cache_timeout;
+ time_t now;
+};
+
+/*
+ * This function is set as a callback to be called for every entry in the DNS
+ * cache when we want to prune old unused entries.
+ *
+ * Returning non-zero means remove the entry, return 0 to keep it in the
+ * cache.
+ */
+static int
+hostcache_timestamp_remove(void *datap, void *hc)
+{
+ struct hostcache_prune_data *data =
+ (struct hostcache_prune_data *) datap;
+ struct Curl_dns_entry *c = (struct Curl_dns_entry *) hc;
+
+ return (0 != c->timestamp)
+ && (data->now - c->timestamp >= data->cache_timeout);
+}
+
+/*
+ * Prune the DNS cache. This assumes that a lock has already been taken.
+ */
+static void
+hostcache_prune(struct curl_hash *hostcache, long cache_timeout, time_t now)
+{
+ struct hostcache_prune_data user;
+
+ user.cache_timeout = cache_timeout;
+ user.now = now;
+
+ Curl_hash_clean_with_criterium(hostcache,
+ (void *) &user,
+ hostcache_timestamp_remove);
+}
+
+/*
+ * Library-wide function for pruning the DNS cache. This function takes and
+ * returns the appropriate locks.
+ */
+void Curl_hostcache_prune(struct SessionHandle *data)
+{
+ time_t now;
+
+ if((data->set.dns_cache_timeout == -1) || !data->dns.hostcache)
+ /* cache forever means never prune, and NULL hostcache means
+ we can't do it */
+ return;
+
+ if(data->share)
+ Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+ time(&now);
+
+ /* Remove outdated and unused entries from the hostcache */
+ hostcache_prune(data->dns.hostcache,
+ data->set.dns_cache_timeout,
+ now);
+
+ if(data->share)
+ Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+}
+
+#ifdef HAVE_SIGSETJMP
+/* Beware this is a global and unique instance. This is used to store the
+ return address that we can jump back to from inside a signal handler. This
+ is not thread-safe stuff. */
+sigjmp_buf curl_jmpenv;
+#endif
+
+/* lookup address, returns entry if found and not stale */
+static struct Curl_dns_entry *
+fetch_addr(struct connectdata *conn,
+ const char *hostname,
+ int port)
+{
+ char *entry_id = NULL;
+ struct Curl_dns_entry *dns = NULL;
+ size_t entry_len;
+ struct SessionHandle *data = conn->data;
+
+ /* Create an entry id, based upon the hostname and port */
+ entry_id = create_hostcache_id(hostname, port);
+ /* If we can't create the entry id, fail */
+ if(!entry_id)
+ return dns;
+
+ entry_len = strlen(entry_id);
+
+ /* See if its already in our dns cache */
+ dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len+1);
+
+ if(dns && (data->set.dns_cache_timeout != -1)) {
+ /* See whether the returned entry is stale. Done before we release lock */
+ struct hostcache_prune_data user;
+
+ time(&user.now);
+ user.cache_timeout = data->set.dns_cache_timeout;
+
+ if(hostcache_timestamp_remove(&user, dns)) {
+ infof(data, "Hostname in DNS cache was stale, zapped\n");
+ dns = NULL; /* the memory deallocation is being handled by the hash */
+ Curl_hash_delete(data->dns.hostcache, entry_id, entry_len+1);
+ }
+ }
+
+ /* free the allocated entry_id again */
+ free(entry_id);
+
+ return dns;
+}
+
+/*
+ * Curl_fetch_addr() fetches a 'Curl_dns_entry' already in the DNS cache.
+ *
+ * Curl_resolv() checks initially and multi_runsingle() checks each time
+ * it discovers the handle in the state WAITRESOLVE whether the hostname
+ * has already been resolved and the address has already been stored in
+ * the DNS cache. This short circuits waiting for a lot of pending
+ * lookups for the same hostname requested by different handles.
+ *
+ * Returns the Curl_dns_entry entry pointer or NULL if not in the cache.
+ *
+ * The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after
+ * use, or we'll leak memory!
+ */
+struct Curl_dns_entry *
+Curl_fetch_addr(struct connectdata *conn,
+ const char *hostname,
+ int port)
+{
+ struct SessionHandle *data = conn->data;
+ struct Curl_dns_entry *dns = NULL;
+
+ if(data->share)
+ Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+ dns = fetch_addr(conn, hostname, port);
+
+ if(dns) dns->inuse++; /* we use it! */
+
+ if(data->share)
+ Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+
+ return dns;
+}
+
+/*
+ * Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache.
+ *
+ * When calling Curl_resolv() has resulted in a response with a returned
+ * address, we call this function to store the information in the dns
+ * cache etc
+ *
+ * Returns the Curl_dns_entry entry pointer or NULL if the storage failed.
+ */
+struct Curl_dns_entry *
+Curl_cache_addr(struct SessionHandle *data,
+ Curl_addrinfo *addr,
+ const char *hostname,
+ int port)
+{
+ char *entry_id;
+ size_t entry_len;
+ struct Curl_dns_entry *dns;
+ struct Curl_dns_entry *dns2;
+
+ /* Create an entry id, based upon the hostname and port */
+ entry_id = create_hostcache_id(hostname, port);
+ /* If we can't create the entry id, fail */
+ if(!entry_id)
+ return NULL;
+ entry_len = strlen(entry_id);
+
+ /* Create a new cache entry */
+ dns = calloc(1, sizeof(struct Curl_dns_entry));
+ if(!dns) {
+ free(entry_id);
+ return NULL;
+ }
+
+ dns->inuse = 1; /* the cache has the first reference */
+ dns->addr = addr; /* this is the address(es) */
+ time(&dns->timestamp);
+ if(dns->timestamp == 0)
+ dns->timestamp = 1; /* zero indicates CURLOPT_RESOLVE entry */
+
+ /* Store the resolved data in our DNS cache. */
+ dns2 = Curl_hash_add(data->dns.hostcache, entry_id, entry_len+1,
+ (void *)dns);
+ if(!dns2) {
+ free(dns);
+ free(entry_id);
+ return NULL;
+ }
+
+ dns = dns2;
+ dns->inuse++; /* mark entry as in-use */
+
+ /* free the allocated entry_id */
+ free(entry_id);
+
+ return dns;
+}
+
+/*
+ * Curl_resolv() is the main name resolve function within libcurl. It resolves
+ * a name and returns a pointer to the entry in the 'entry' argument (if one
+ * is provided). This function might return immediately if we're using asynch
+ * resolves. See the return codes.
+ *
+ * The cache entry we return will get its 'inuse' counter increased when this
+ * function is used. You MUST call Curl_resolv_unlock() later (when you're
+ * done using this struct) to decrease the counter again.
+ *
+ * In debug mode, we specifically test for an interface name "LocalHost"
+ * and resolve "localhost" instead as a means to permit test cases
+ * to connect to a local test server with any host name.
+ *
+ * Return codes:
+ *
+ * CURLRESOLV_ERROR (-1) = error, no pointer
+ * CURLRESOLV_RESOLVED (0) = OK, pointer provided
+ * CURLRESOLV_PENDING (1) = waiting for response, no pointer
+ */
+
+int Curl_resolv(struct connectdata *conn,
+ const char *hostname,
+ int port,
+ struct Curl_dns_entry **entry)
+{
+ struct Curl_dns_entry *dns = NULL;
+ struct SessionHandle *data = conn->data;
+ CURLcode result;
+ int rc = CURLRESOLV_ERROR; /* default to failure */
+
+ *entry = NULL;
+
+ if(data->share)
+ Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+ dns = fetch_addr(conn, hostname, port);
+
+ if(dns) {
+ infof(data, "Hostname %s was found in DNS cache\n", hostname);
+ dns->inuse++; /* we use it! */
+ rc = CURLRESOLV_RESOLVED;
+ }
+
+ if(data->share)
+ Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+
+ if(!dns) {
+ /* The entry was not in the cache. Resolve it to IP address */
+
+ Curl_addrinfo *addr;
+ int respwait;
+
+ /* Check what IP specifics the app has requested and if we can provide it.
+ * If not, bail out. */
+ if(!Curl_ipvalid(conn))
+ return CURLRESOLV_ERROR;
+
+ /* If Curl_getaddrinfo() returns NULL, 'respwait' might be set to a
+ non-zero value indicating that we need to wait for the response to the
+ resolve call */
+ addr = Curl_getaddrinfo(conn,
+#ifdef DEBUGBUILD
+ (data->set.str[STRING_DEVICE]
+ && !strcmp(data->set.str[STRING_DEVICE],
+ "LocalHost"))?"localhost":
+#endif
+ hostname, port, &respwait);
+
+ if(!addr) {
+ if(respwait) {
+ /* the response to our resolve call will come asynchronously at
+ a later time, good or bad */
+ /* First, check that we haven't received the info by now */
+ result = Curl_resolver_is_resolved(conn, &dns);
+ if(result) /* error detected */
+ return CURLRESOLV_ERROR;
+ if(dns)
+ rc = CURLRESOLV_RESOLVED; /* pointer provided */
+ else
+ rc = CURLRESOLV_PENDING; /* no info yet */
+ }
+ }
+ else {
+ if(data->share)
+ Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+ /* we got a response, store it in the cache */
+ dns = Curl_cache_addr(data, addr, hostname, port);
+
+ if(data->share)
+ Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+
+ if(!dns)
+ /* returned failure, bail out nicely */
+ Curl_freeaddrinfo(addr);
+ else
+ rc = CURLRESOLV_RESOLVED;
+ }
+ }
+
+ *entry = dns;
+
+ return rc;
+}
+
+#ifdef USE_ALARM_TIMEOUT
+/*
+ * This signal handler jumps back into the main libcurl code and continues
+ * execution. This effectively causes the remainder of the application to run
+ * within a signal handler which is nonportable and could lead to problems.
+ */
+static
+RETSIGTYPE alarmfunc(int sig)
+{
+ /* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */
+ (void)sig;
+ siglongjmp(curl_jmpenv, 1);
+ return;
+}
+#endif /* USE_ALARM_TIMEOUT */
+
+/*
+ * Curl_resolv_timeout() is the same as Curl_resolv() but specifies a
+ * timeout. This function might return immediately if we're using asynch
+ * resolves. See the return codes.
+ *
+ * The cache entry we return will get its 'inuse' counter increased when this
+ * function is used. You MUST call Curl_resolv_unlock() later (when you're
+ * done using this struct) to decrease the counter again.
+ *
+ * If built with a synchronous resolver and use of signals is not
+ * disabled by the application, then a nonzero timeout will cause a
+ * timeout after the specified number of milliseconds. Otherwise, timeout
+ * is ignored.
+ *
+ * Return codes:
+ *
+ * CURLRESOLV_TIMEDOUT(-2) = warning, time too short or previous alarm expired
+ * CURLRESOLV_ERROR (-1) = error, no pointer
+ * CURLRESOLV_RESOLVED (0) = OK, pointer provided
+ * CURLRESOLV_PENDING (1) = waiting for response, no pointer
+ */
+
+int Curl_resolv_timeout(struct connectdata *conn,
+ const char *hostname,
+ int port,
+ struct Curl_dns_entry **entry,
+ long timeoutms)
+{
+#ifdef USE_ALARM_TIMEOUT
+#ifdef HAVE_SIGACTION
+ struct sigaction keep_sigact; /* store the old struct here */
+ volatile bool keep_copysig = FALSE; /* wether old sigact has been saved */
+ struct sigaction sigact;
+#else
+#ifdef HAVE_SIGNAL
+ void (*keep_sigact)(int); /* store the old handler here */
+#endif /* HAVE_SIGNAL */
+#endif /* HAVE_SIGACTION */
+ volatile long timeout;
+ volatile unsigned int prev_alarm = 0;
+ struct SessionHandle *data = conn->data;
+#endif /* USE_ALARM_TIMEOUT */
+ int rc;
+
+ *entry = NULL;
+
+ if(timeoutms < 0)
+ /* got an already expired timeout */
+ return CURLRESOLV_TIMEDOUT;
+
+#ifdef USE_ALARM_TIMEOUT
+ if(data->set.no_signal)
+ /* Ignore the timeout when signals are disabled */
+ timeout = 0;
+ else
+ timeout = timeoutms;
+
+ if(!timeout)
+ /* USE_ALARM_TIMEOUT defined, but no timeout actually requested */
+ return Curl_resolv(conn, hostname, port, entry);
+
+ if(timeout < 1000)
+ /* The alarm() function only provides integer second resolution, so if
+ we want to wait less than one second we must bail out already now. */
+ return CURLRESOLV_TIMEDOUT;
+
+ /* This allows us to time-out from the name resolver, as the timeout
+ will generate a signal and we will siglongjmp() from that here.
+ This technique has problems (see alarmfunc).
+ This should be the last thing we do before calling Curl_resolv(),
+ as otherwise we'd have to worry about variables that get modified
+ before we invoke Curl_resolv() (and thus use "volatile"). */
+ if(sigsetjmp(curl_jmpenv, 1)) {
+ /* this is coming from a siglongjmp() after an alarm signal */
+ failf(data, "name lookup timed out");
+ rc = CURLRESOLV_ERROR;
+ goto clean_up;
+ }
+ else {
+ /*************************************************************
+ * Set signal handler to catch SIGALRM
+ * Store the old value to be able to set it back later!
+ *************************************************************/
+#ifdef HAVE_SIGACTION
+ sigaction(SIGALRM, NULL, &sigact);
+ keep_sigact = sigact;
+ keep_copysig = TRUE; /* yes, we have a copy */
+ sigact.sa_handler = alarmfunc;
+#ifdef SA_RESTART
+ /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */
+ sigact.sa_flags &= ~SA_RESTART;
+#endif
+ /* now set the new struct */
+ sigaction(SIGALRM, &sigact, NULL);
+#else /* HAVE_SIGACTION */
+ /* no sigaction(), revert to the much lamer signal() */
+#ifdef HAVE_SIGNAL
+ keep_sigact = signal(SIGALRM, alarmfunc);
+#endif
+#endif /* HAVE_SIGACTION */
+
+ /* alarm() makes a signal get sent when the timeout fires off, and that
+ will abort system calls */
+ prev_alarm = alarm(curlx_sltoui(timeout/1000L));
+ }
+
+#else
+#ifndef CURLRES_ASYNCH
+ if(timeoutms)
+ infof(conn->data, "timeout on name lookup is not supported\n");
+#else
+ (void)timeoutms; /* timeoutms not used with an async resolver */
+#endif
+#endif /* USE_ALARM_TIMEOUT */
+
+ /* Perform the actual name resolution. This might be interrupted by an
+ * alarm if it takes too long.
+ */
+ rc = Curl_resolv(conn, hostname, port, entry);
+
+#ifdef USE_ALARM_TIMEOUT
+clean_up:
+
+ if(!prev_alarm)
+ /* deactivate a possibly active alarm before uninstalling the handler */
+ alarm(0);
+
+#ifdef HAVE_SIGACTION
+ if(keep_copysig) {
+ /* we got a struct as it looked before, now put that one back nice
+ and clean */
+ sigaction(SIGALRM, &keep_sigact, NULL); /* put it back */
+ }
+#else
+#ifdef HAVE_SIGNAL
+ /* restore the previous SIGALRM handler */
+ signal(SIGALRM, keep_sigact);
+#endif
+#endif /* HAVE_SIGACTION */
+
+ /* switch back the alarm() to either zero or to what it was before minus
+ the time we spent until now! */
+ if(prev_alarm) {
+ /* there was an alarm() set before us, now put it back */
+ unsigned long elapsed_ms = Curl_tvdiff(Curl_tvnow(), conn->created);
+
+ /* the alarm period is counted in even number of seconds */
+ unsigned long alarm_set = prev_alarm - elapsed_ms/1000;
+
+ if(!alarm_set ||
+ ((alarm_set >= 0x80000000) && (prev_alarm < 0x80000000)) ) {
+ /* if the alarm time-left reached zero or turned "negative" (counted
+ with unsigned values), we should fire off a SIGALRM here, but we
+ won't, and zero would be to switch it off so we never set it to
+ less than 1! */
+ alarm(1);
+ rc = CURLRESOLV_TIMEDOUT;
+ failf(data, "Previous alarm fired off!");
+ }
+ else
+ alarm((unsigned int)alarm_set);
+ }
+#endif /* USE_ALARM_TIMEOUT */
+
+ return rc;
+}
+
+/*
+ * Curl_resolv_unlock() unlocks the given cached DNS entry. When this has been
+ * made, the struct may be destroyed due to pruning. It is important that only
+ * one unlock is made for each Curl_resolv() call.
+ *
+ * May be called with 'data' == NULL for global cache.
+ */
+void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns)
+{
+ if(data && data->share)
+ Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+ freednsentry(dns);
+
+ if(data && data->share)
+ Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+}
+
+/*
+ * File-internal: release cache dns entry reference, free if inuse drops to 0
+ */
+static void freednsentry(void *freethis)
+{
+ struct Curl_dns_entry *dns = (struct Curl_dns_entry *) freethis;
+ DEBUGASSERT(dns && (dns->inuse>0));
+
+ dns->inuse--;
+ if(dns->inuse == 0) {
+ Curl_freeaddrinfo(dns->addr);
+ free(dns);
+ }
+}
+
+/*
+ * Curl_mk_dnscache() inits a new DNS cache and returns success/failure.
+ */
+int Curl_mk_dnscache(struct curl_hash *hash)
+{
+ return Curl_hash_init(hash, 7, Curl_hash_str, Curl_str_key_compare,
+ freednsentry);
+}
+
+/*
+ * Curl_hostcache_clean()
+ *
+ * This _can_ be called with 'data' == NULL but then of course no locking
+ * can be done!
+ */
+
+void Curl_hostcache_clean(struct SessionHandle *data,
+ struct curl_hash *hash)
+{
+ if(data && data->share)
+ Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+ Curl_hash_clean(hash);
+
+ if(data && data->share)
+ Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+}
+
+
+CURLcode Curl_loadhostpairs(struct SessionHandle *data)
+{
+ struct curl_slist *hostp;
+ char hostname[256];
+ char address[256];
+ int port;
+
+ for(hostp = data->change.resolve; hostp; hostp = hostp->next ) {
+ if(!hostp->data)
+ continue;
+ if(hostp->data[0] == '-') {
+ char *entry_id;
+ size_t entry_len;
+
+ if(2 != sscanf(hostp->data + 1, "%255[^:]:%d", hostname, &port)) {
+ infof(data, "Couldn't parse CURLOPT_RESOLVE removal entry '%s'!\n",
+ hostp->data);
+ continue;
+ }
+
+ /* Create an entry id, based upon the hostname and port */
+ entry_id = create_hostcache_id(hostname, port);
+ /* If we can't create the entry id, fail */
+ if(!entry_id) {
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ entry_len = strlen(entry_id);
+
+ if(data->share)
+ Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+ /* delete entry, ignore if it didn't exist */
+ Curl_hash_delete(data->dns.hostcache, entry_id, entry_len+1);
+
+ if(data->share)
+ Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+
+ /* free the allocated entry_id again */
+ free(entry_id);
+ }
+ else {
+ struct Curl_dns_entry *dns;
+ Curl_addrinfo *addr;
+ char *entry_id;
+ size_t entry_len;
+
+ if(3 != sscanf(hostp->data, "%255[^:]:%d:%255s", hostname, &port,
+ address)) {
+ infof(data, "Couldn't parse CURLOPT_RESOLVE entry '%s'!\n",
+ hostp->data);
+ continue;
+ }
+
+ addr = Curl_str2addr(address, port);
+ if(!addr) {
+ infof(data, "Address in '%s' found illegal!\n", hostp->data);
+ continue;
+ }
+
+ /* Create an entry id, based upon the hostname and port */
+ entry_id = create_hostcache_id(hostname, port);
+ /* If we can't create the entry id, fail */
+ if(!entry_id) {
+ Curl_freeaddrinfo(addr);
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ entry_len = strlen(entry_id);
+
+ if(data->share)
+ Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+ /* See if its already in our dns cache */
+ dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len+1);
+
+ /* free the allocated entry_id again */
+ free(entry_id);
+
+ if(!dns) {
+ /* if not in the cache already, put this host in the cache */
+ dns = Curl_cache_addr(data, addr, hostname, port);
+ if(dns) {
+ dns->timestamp = 0; /* mark as added by CURLOPT_RESOLVE */
+ /* release the returned reference; the cache itself will keep the
+ * entry alive: */
+ dns->inuse--;
+ }
+ }
+ else
+ /* this is a duplicate, free it again */
+ Curl_freeaddrinfo(addr);
+
+ if(data->share)
+ Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+
+ if(!dns) {
+ Curl_freeaddrinfo(addr);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ infof(data, "Added %s:%d:%s to DNS cache\n",
+ hostname, port, address);
+ }
+ }
+ data->change.resolve = NULL; /* dealt with now */
+
+ return CURLE_OK;
+}
diff --git a/Utilities/cmcurl/lib/hostip.h b/Utilities/cmcurl/lib/hostip.h
new file mode 100644
index 000000000..d5b44bc9e
--- /dev/null
+++ b/Utilities/cmcurl/lib/hostip.h
@@ -0,0 +1,250 @@
+#ifndef HEADER_CURL_HOSTIP_H
+#define HEADER_CURL_HOSTIP_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include "hash.h"
+#include "curl_addrinfo.h"
+#include "asyn.h"
+
+#ifdef HAVE_SETJMP_H
+#include <setjmp.h>
+#endif
+
+#ifdef NETWARE
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+/* Allocate enough memory to hold the full name information structs and
+ * everything. OSF1 is known to require at least 8872 bytes. The buffer
+ * required for storing all possible aliases and IP numbers is according to
+ * Stevens' Unix Network Programming 2nd edition, p. 304: 8192 bytes!
+ */
+#define CURL_HOSTENT_SIZE 9000
+
+#define CURL_TIMEOUT_RESOLVE 300 /* when using asynch methods, we allow this
+ many seconds for a name resolve */
+
+#define CURL_ASYNC_SUCCESS CURLE_OK
+
+struct addrinfo;
+struct hostent;
+struct SessionHandle;
+struct connectdata;
+
+/*
+ * Curl_global_host_cache_init() initializes and sets up a global DNS cache.
+ * Global DNS cache is general badness. Do not use. This will be removed in
+ * a future version. Use the share interface instead!
+ *
+ * Returns a struct curl_hash pointer on success, NULL on failure.
+ */
+struct curl_hash *Curl_global_host_cache_init(void);
+void Curl_global_host_cache_dtor(void);
+
+struct Curl_dns_entry {
+ Curl_addrinfo *addr;
+ /* timestamp == 0 -- CURLOPT_RESOLVE entry, doesn't timeout */
+ time_t timestamp;
+ /* use-counter, use Curl_resolv_unlock to release reference */
+ long inuse;
+};
+
+/*
+ * Curl_resolv() returns an entry with the info for the specified host
+ * and port.
+ *
+ * The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after
+ * use, or we'll leak memory!
+ */
+/* return codes */
+#define CURLRESOLV_TIMEDOUT -2
+#define CURLRESOLV_ERROR -1
+#define CURLRESOLV_RESOLVED 0
+#define CURLRESOLV_PENDING 1
+int Curl_resolv(struct connectdata *conn, const char *hostname,
+ int port, struct Curl_dns_entry **dnsentry);
+int Curl_resolv_timeout(struct connectdata *conn, const char *hostname,
+ int port, struct Curl_dns_entry **dnsentry,
+ long timeoutms);
+
+#ifdef CURLRES_IPV6
+/*
+ * Curl_ipv6works() returns TRUE if IPv6 seems to work.
+ */
+bool Curl_ipv6works(void);
+#else
+#define Curl_ipv6works() FALSE
+#endif
+
+/*
+ * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
+ * been set and returns TRUE if they are OK.
+ */
+bool Curl_ipvalid(struct connectdata *conn);
+
+
+/*
+ * Curl_getaddrinfo() is the generic low-level name resolve API within this
+ * source file. There are several versions of this function - for different
+ * name resolve layers (selected at build-time). They all take this same set
+ * of arguments
+ */
+Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
+ const char *hostname,
+ int port,
+ int *waitp);
+
+
+/* unlock a previously resolved dns entry */
+void Curl_resolv_unlock(struct SessionHandle *data,
+ struct Curl_dns_entry *dns);
+
+/* for debugging purposes only: */
+void Curl_scan_cache_used(void *user, void *ptr);
+
+/* init a new dns cache and return success */
+int Curl_mk_dnscache(struct curl_hash *hash);
+
+/* prune old entries from the DNS cache */
+void Curl_hostcache_prune(struct SessionHandle *data);
+
+/* Return # of adresses in a Curl_addrinfo struct */
+int Curl_num_addresses (const Curl_addrinfo *addr);
+
+#if defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO)
+int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
+ GETNAMEINFO_TYPE_ARG2 salen,
+ char *host, GETNAMEINFO_TYPE_ARG46 hostlen,
+ char *serv, GETNAMEINFO_TYPE_ARG46 servlen,
+ GETNAMEINFO_TYPE_ARG7 flags,
+ int line, const char *source);
+#endif
+
+/* IPv4 threadsafe resolve function used for synch and asynch builds */
+Curl_addrinfo *Curl_ipv4_resolve_r(const char * hostname, int port);
+
+CURLcode Curl_async_resolved(struct connectdata *conn,
+ bool *protocol_connect);
+
+#ifndef CURLRES_ASYNCH
+#define Curl_async_resolved(x,y) CURLE_OK
+#endif
+
+/*
+ * Curl_addrinfo_callback() is used when we build with any asynch specialty.
+ * Handles end of async request processing. Inserts ai into hostcache when
+ * status is CURL_ASYNC_SUCCESS. Twiddles fields in conn to indicate async
+ * request completed whether successful or failed.
+ */
+CURLcode Curl_addrinfo_callback(struct connectdata *conn,
+ int status,
+ Curl_addrinfo *ai);
+
+/*
+ * Curl_printable_address() returns a printable version of the 1st address
+ * given in the 'ip' argument. The result will be stored in the buf that is
+ * bufsize bytes big.
+ */
+const char *Curl_printable_address(const Curl_addrinfo *ip,
+ char *buf, size_t bufsize);
+
+/*
+ * Curl_fetch_addr() fetches a 'Curl_dns_entry' already in the DNS cache.
+ *
+ * Returns the Curl_dns_entry entry pointer or NULL if not in the cache.
+ *
+ * The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after
+ * use, or we'll leak memory!
+ */
+struct Curl_dns_entry *
+Curl_fetch_addr(struct connectdata *conn,
+ const char *hostname,
+ int port);
+/*
+ * Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache.
+ *
+ * Returns the Curl_dns_entry entry pointer or NULL if the storage failed.
+ */
+struct Curl_dns_entry *
+Curl_cache_addr(struct SessionHandle *data, Curl_addrinfo *addr,
+ const char *hostname, int port);
+
+#ifndef INADDR_NONE
+#define CURL_INADDR_NONE (in_addr_t) ~0
+#else
+#define CURL_INADDR_NONE INADDR_NONE
+#endif
+
+#ifdef HAVE_SIGSETJMP
+/* Forward-declaration of variable defined in hostip.c. Beware this
+ * is a global and unique instance. This is used to store the return
+ * address that we can jump back to from inside a signal handler.
+ * This is not thread-safe stuff.
+ */
+extern sigjmp_buf curl_jmpenv;
+#endif
+
+/*
+ * Function provided by the resolver backend to set DNS servers to use.
+ */
+CURLcode Curl_set_dns_servers(struct SessionHandle *data, char *servers);
+
+/*
+ * Function provided by the resolver backend to set
+ * outgoing interface to use for DNS requests
+ */
+CURLcode Curl_set_dns_interface(struct SessionHandle *data,
+ const char *interf);
+
+/*
+ * Function provided by the resolver backend to set
+ * local IPv4 address to use as source address for DNS requests
+ */
+CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
+ const char *local_ip4);
+
+/*
+ * Function provided by the resolver backend to set
+ * local IPv6 address to use as source address for DNS requests
+ */
+CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data,
+ const char *local_ip6);
+
+/*
+ * Clean off entries from the cache
+ */
+void Curl_hostcache_clean(struct SessionHandle *data, struct curl_hash *hash);
+
+/*
+ * Destroy the hostcache of this handle.
+ */
+void Curl_hostcache_destroy(struct SessionHandle *data);
+
+/*
+ * Populate the cache with specified entries from CURLOPT_RESOLVE.
+ */
+CURLcode Curl_loadhostpairs(struct SessionHandle *data);
+
+#endif /* HEADER_CURL_HOSTIP_H */
diff --git a/Utilities/cmcurl/lib/hostip4.c b/Utilities/cmcurl/lib/hostip4.c
new file mode 100644
index 000000000..37b036911
--- /dev/null
+++ b/Utilities/cmcurl/lib/hostip4.c
@@ -0,0 +1,307 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "hash.h"
+#include "share.h"
+#include "strerror.h"
+#include "url.h"
+#include "inet_pton.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/***********************************************************************
+ * Only for plain IPv4 builds
+ **********************************************************************/
+#ifdef CURLRES_IPV4 /* plain IPv4 code coming up */
+/*
+ * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
+ * been set and returns TRUE if they are OK.
+ */
+bool Curl_ipvalid(struct connectdata *conn)
+{
+ if(conn->ip_version == CURL_IPRESOLVE_V6)
+ /* An IPv6 address was requested and we can't get/use one */
+ return FALSE;
+
+ return TRUE; /* OK, proceed */
+}
+
+#ifdef CURLRES_SYNCH
+
+/*
+ * Curl_getaddrinfo() - the IPv4 synchronous version.
+ *
+ * The original code to this function was from the Dancer source code, written
+ * by Bjorn Reese, it has since been patched and modified considerably.
+ *
+ * gethostbyname_r() is the thread-safe version of the gethostbyname()
+ * function. When we build for plain IPv4, we attempt to use this
+ * function. There are _three_ different gethostbyname_r() versions, and we
+ * detect which one this platform supports in the configure script and set up
+ * the HAVE_GETHOSTBYNAME_R_3, HAVE_GETHOSTBYNAME_R_5 or
+ * HAVE_GETHOSTBYNAME_R_6 defines accordingly. Note that HAVE_GETADDRBYNAME
+ * has the corresponding rules. This is primarily on *nix. Note that some unix
+ * flavours have thread-safe versions of the plain gethostbyname() etc.
+ *
+ */
+Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
+ const char *hostname,
+ int port,
+ int *waitp)
+{
+ Curl_addrinfo *ai = NULL;
+
+#ifdef CURL_DISABLE_VERBOSE_STRINGS
+ (void)conn;
+#endif
+
+ *waitp = 0; /* synchronous response only */
+
+ ai = Curl_ipv4_resolve_r(hostname, port);
+ if(!ai)
+ infof(conn->data, "Curl_ipv4_resolve_r failed for %s\n", hostname);
+
+ return ai;
+}
+#endif /* CURLRES_SYNCH */
+#endif /* CURLRES_IPV4 */
+
+#if defined(CURLRES_IPV4) && !defined(CURLRES_ARES)
+
+/*
+ * Curl_ipv4_resolve_r() - ipv4 threadsafe resolver function.
+ *
+ * This is used for both synchronous and asynchronous resolver builds,
+ * implying that only threadsafe code and function calls may be used.
+ *
+ */
+Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
+ int port)
+{
+#if !defined(HAVE_GETADDRINFO_THREADSAFE) && defined(HAVE_GETHOSTBYNAME_R_3)
+ int res;
+#endif
+ Curl_addrinfo *ai = NULL;
+ struct hostent *h = NULL;
+ struct in_addr in;
+ struct hostent *buf = NULL;
+
+ if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
+ /* This is a dotted IP address 123.123.123.123-style */
+ return Curl_ip2addr(AF_INET, &in, hostname, port);
+
+#if defined(HAVE_GETADDRINFO_THREADSAFE)
+ else {
+ struct addrinfo hints;
+ char sbuf[12];
+ char *sbufptr = NULL;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_INET;
+ hints.ai_socktype = SOCK_STREAM;
+ if(port) {
+ snprintf(sbuf, sizeof(sbuf), "%d", port);
+ sbufptr = sbuf;
+ }
+
+ (void)Curl_getaddrinfo_ex(hostname, sbufptr, &hints, &ai);
+
+#elif defined(HAVE_GETHOSTBYNAME_R)
+ /*
+ * gethostbyname_r() is the preferred resolve function for many platforms.
+ * Since there are three different versions of it, the following code is
+ * somewhat #ifdef-ridden.
+ */
+ else {
+ int h_errnop;
+
+ buf = calloc(1, CURL_HOSTENT_SIZE);
+ if(!buf)
+ return NULL; /* major failure */
+ /*
+ * The clearing of the buffer is a workaround for a gethostbyname_r bug in
+ * qnx nto and it is also _required_ for some of these functions on some
+ * platforms.
+ */
+
+#if defined(HAVE_GETHOSTBYNAME_R_5)
+ /* Solaris, IRIX and more */
+ h = gethostbyname_r(hostname,
+ (struct hostent *)buf,
+ (char *)buf + sizeof(struct hostent),
+ CURL_HOSTENT_SIZE - sizeof(struct hostent),
+ &h_errnop);
+
+ /* If the buffer is too small, it returns NULL and sets errno to
+ * ERANGE. The errno is thread safe if this is compiled with
+ * -D_REENTRANT as then the 'errno' variable is a macro defined to get
+ * used properly for threads.
+ */
+
+ if(h) {
+ ;
+ }
+ else
+#elif defined(HAVE_GETHOSTBYNAME_R_6)
+ /* Linux */
+
+ (void)gethostbyname_r(hostname,
+ (struct hostent *)buf,
+ (char *)buf + sizeof(struct hostent),
+ CURL_HOSTENT_SIZE - sizeof(struct hostent),
+ &h, /* DIFFERENCE */
+ &h_errnop);
+ /* Redhat 8, using glibc 2.2.93 changed the behavior. Now all of a
+ * sudden this function returns EAGAIN if the given buffer size is too
+ * small. Previous versions are known to return ERANGE for the same
+ * problem.
+ *
+ * This wouldn't be such a big problem if older versions wouldn't
+ * sometimes return EAGAIN on a common failure case. Alas, we can't
+ * assume that EAGAIN *or* ERANGE means ERANGE for any given version of
+ * glibc.
+ *
+ * For now, we do that and thus we may call the function repeatedly and
+ * fail for older glibc versions that return EAGAIN, until we run out of
+ * buffer size (step_size grows beyond CURL_HOSTENT_SIZE).
+ *
+ * If anyone has a better fix, please tell us!
+ *
+ * -------------------------------------------------------------------
+ *
+ * On October 23rd 2003, Dan C dug up more details on the mysteries of
+ * gethostbyname_r() in glibc:
+ *
+ * In glibc 2.2.5 the interface is different (this has also been
+ * discovered in glibc 2.1.1-6 as shipped by Redhat 6). What I can't
+ * explain, is that tests performed on glibc 2.2.4-34 and 2.2.4-32
+ * (shipped/upgraded by Redhat 7.2) don't show this behavior!
+ *
+ * In this "buggy" version, the return code is -1 on error and 'errno'
+ * is set to the ERANGE or EAGAIN code. Note that 'errno' is not a
+ * thread-safe variable.
+ */
+
+ if(!h) /* failure */
+#elif defined(HAVE_GETHOSTBYNAME_R_3)
+ /* AIX, Digital Unix/Tru64, HPUX 10, more? */
+
+ /* For AIX 4.3 or later, we don't use gethostbyname_r() at all, because of
+ * the plain fact that it does not return unique full buffers on each
+ * call, but instead several of the pointers in the hostent structs will
+ * point to the same actual data! This have the unfortunate down-side that
+ * our caching system breaks down horribly. Luckily for us though, AIX 4.3
+ * and more recent versions have a "completely thread-safe"[*] libc where
+ * all the data is stored in thread-specific memory areas making calls to
+ * the plain old gethostbyname() work fine even for multi-threaded
+ * programs.
+ *
+ * This AIX 4.3 or later detection is all made in the configure script.
+ *
+ * Troels Walsted Hansen helped us work this out on March 3rd, 2003.
+ *
+ * [*] = much later we've found out that it isn't at all "completely
+ * thread-safe", but at least the gethostbyname() function is.
+ */
+
+ if(CURL_HOSTENT_SIZE >=
+ (sizeof(struct hostent)+sizeof(struct hostent_data))) {
+
+ /* August 22nd, 2000: Albert Chin-A-Young brought an updated version
+ * that should work! September 20: Richard Prescott worked on the buffer
+ * size dilemma.
+ */
+
+ res = gethostbyname_r(hostname,
+ (struct hostent *)buf,
+ (struct hostent_data *)((char *)buf +
+ sizeof(struct hostent)));
+ h_errnop = SOCKERRNO; /* we don't deal with this, but set it anyway */
+ }
+ else
+ res = -1; /* failure, too smallish buffer size */
+
+ if(!res) { /* success */
+
+ h = buf; /* result expected in h */
+
+ /* This is the worst kind of the different gethostbyname_r() interfaces.
+ * Since we don't know how big buffer this particular lookup required,
+ * we can't realloc down the huge alloc without doing closer analysis of
+ * the returned data. Thus, we always use CURL_HOSTENT_SIZE for every
+ * name lookup. Fixing this would require an extra malloc() and then
+ * calling Curl_addrinfo_copy() that subsequent realloc()s down the new
+ * memory area to the actually used amount.
+ */
+ }
+ else
+#endif /* HAVE_...BYNAME_R_5 || HAVE_...BYNAME_R_6 || HAVE_...BYNAME_R_3 */
+ {
+ h = NULL; /* set return code to NULL */
+ free(buf);
+ }
+#else /* HAVE_GETADDRINFO_THREADSAFE || HAVE_GETHOSTBYNAME_R */
+ /*
+ * Here is code for platforms that don't have a thread safe
+ * getaddrinfo() nor gethostbyname_r() function or for which
+ * gethostbyname() is the preferred one.
+ */
+ else {
+ h = gethostbyname((void*)hostname);
+#endif /* HAVE_GETADDRINFO_THREADSAFE || HAVE_GETHOSTBYNAME_R */
+ }
+
+ if(h) {
+ ai = Curl_he2ai(h, port);
+
+ if(buf) /* used a *_r() function */
+ free(buf);
+ }
+
+ return ai;
+}
+#endif /* defined(CURLRES_IPV4) && !defined(CURLRES_ARES) */
diff --git a/Utilities/cmcurl/lib/hostip6.c b/Utilities/cmcurl/lib/hostip6.c
new file mode 100644
index 000000000..6ab131a8c
--- /dev/null
+++ b/Utilities/cmcurl/lib/hostip6.c
@@ -0,0 +1,221 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "hash.h"
+#include "share.h"
+#include "strerror.h"
+#include "url.h"
+#include "inet_pton.h"
+#include "connect.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/***********************************************************************
+ * Only for IPv6-enabled builds
+ **********************************************************************/
+#ifdef CURLRES_IPV6
+
+
+#if defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO)
+/* These are strictly for memory tracing and are using the same style as the
+ * family otherwise present in memdebug.c. I put these ones here since they
+ * require a bunch of structs I didn't want to include in memdebug.c
+ */
+
+/*
+ * For CURLRES_ARS, this should be written using ares_gethostbyaddr()
+ * (ignoring the fact c-ares doesn't return 'serv').
+ */
+
+int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
+ GETNAMEINFO_TYPE_ARG2 salen,
+ char *host, GETNAMEINFO_TYPE_ARG46 hostlen,
+ char *serv, GETNAMEINFO_TYPE_ARG46 servlen,
+ GETNAMEINFO_TYPE_ARG7 flags,
+ int line, const char *source)
+{
+ int res = (getnameinfo)(sa, salen,
+ host, hostlen,
+ serv, servlen,
+ flags);
+ if(0 == res)
+ /* success */
+ curl_memlog("GETNAME %s:%d getnameinfo()\n",
+ source, line);
+ else
+ curl_memlog("GETNAME %s:%d getnameinfo() failed = %d\n",
+ source, line, res);
+ return res;
+}
+#endif /* defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO) */
+
+/*
+ * Curl_ipv6works() returns TRUE if IPv6 seems to work.
+ */
+bool Curl_ipv6works(void)
+{
+ /* the nature of most system is that IPv6 status doesn't come and go
+ during a program's lifetime so we only probe the first time and then we
+ have the info kept for fast re-use */
+ static int ipv6_works = -1;
+ if(-1 == ipv6_works) {
+ /* probe to see if we have a working IPv6 stack */
+ curl_socket_t s = socket(PF_INET6, SOCK_DGRAM, 0);
+ if(s == CURL_SOCKET_BAD)
+ /* an IPv6 address was requested but we can't get/use one */
+ ipv6_works = 0;
+ else {
+ ipv6_works = 1;
+ Curl_closesocket(NULL, s);
+ }
+ }
+ return (ipv6_works>0)?TRUE:FALSE;
+}
+
+/*
+ * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
+ * been set and returns TRUE if they are OK.
+ */
+bool Curl_ipvalid(struct connectdata *conn)
+{
+ if(conn->ip_version == CURL_IPRESOLVE_V6)
+ return Curl_ipv6works();
+ return TRUE;
+}
+
+#if defined(CURLRES_SYNCH)
+
+#ifdef DEBUG_ADDRINFO
+static void dump_addrinfo(struct connectdata *conn, const Curl_addrinfo *ai)
+{
+ printf("dump_addrinfo:\n");
+ for(; ai; ai = ai->ai_next) {
+ char buf[INET6_ADDRSTRLEN];
+
+ printf(" fam %2d, CNAME %s, ",
+ ai->ai_family, ai->ai_canonname ? ai->ai_canonname : "<none>");
+ if(Curl_printable_address(ai, buf, sizeof(buf)))
+ printf("%s\n", buf);
+ else
+ printf("failed; %s\n", Curl_strerror(conn, SOCKERRNO));
+ }
+}
+#else
+#define dump_addrinfo(x,y) Curl_nop_stmt
+#endif
+
+/*
+ * Curl_getaddrinfo() when built IPv6-enabled (non-threading and
+ * non-ares version).
+ *
+ * Returns name information about the given hostname and port number. If
+ * successful, the 'addrinfo' is returned and the forth argument will point to
+ * memory we need to free after use. That memory *MUST* be freed with
+ * Curl_freeaddrinfo(), nothing else.
+ */
+Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
+ const char *hostname,
+ int port,
+ int *waitp)
+{
+ struct addrinfo hints;
+ Curl_addrinfo *res;
+ int error;
+ char sbuf[12];
+ char *sbufptr = NULL;
+ char addrbuf[128];
+ int pf;
+ struct SessionHandle *data = conn->data;
+
+ *waitp = 0; /* synchronous response only */
+
+ /*
+ * Check if a limited name resolve has been requested.
+ */
+ switch(conn->ip_version) {
+ case CURL_IPRESOLVE_V4:
+ pf = PF_INET;
+ break;
+ case CURL_IPRESOLVE_V6:
+ pf = PF_INET6;
+ break;
+ default:
+ pf = PF_UNSPEC;
+ break;
+ }
+
+ if((pf != PF_INET) && !Curl_ipv6works())
+ /* The stack seems to be a non-IPv6 one */
+ pf = PF_INET;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = pf;
+ hints.ai_socktype = conn->socktype;
+
+ if((1 == Curl_inet_pton(AF_INET, hostname, addrbuf)) ||
+ (1 == Curl_inet_pton(AF_INET6, hostname, addrbuf))) {
+ /* the given address is numerical only, prevent a reverse lookup */
+ hints.ai_flags = AI_NUMERICHOST;
+ }
+
+ if(port) {
+ snprintf(sbuf, sizeof(sbuf), "%d", port);
+ sbufptr=sbuf;
+ }
+ error = Curl_getaddrinfo_ex(hostname, sbufptr, &hints, &res);
+ if(error) {
+ infof(data, "getaddrinfo(3) failed for %s:%d\n", hostname, port);
+ return NULL;
+ }
+
+ dump_addrinfo(conn, res);
+
+ return res;
+}
+#endif /* CURLRES_SYNCH */
+#endif /* CURLRES_IPV6 */
+
diff --git a/Utilities/cmcurl/lib/hostsyn.c b/Utilities/cmcurl/lib/hostsyn.c
new file mode 100644
index 000000000..fb1de35ce
--- /dev/null
+++ b/Utilities/cmcurl/lib/hostsyn.c
@@ -0,0 +1,107 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "hash.h"
+#include "share.h"
+#include "strerror.h"
+#include "url.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/***********************************************************************
+ * Only for builds using synchronous name resolves
+ **********************************************************************/
+#ifdef CURLRES_SYNCH
+
+/*
+ * Function provided by the resolver backend to set DNS servers to use.
+ */
+CURLcode Curl_set_dns_servers(struct SessionHandle *data,
+ char *servers)
+{
+ (void)data;
+ (void)servers;
+ return CURLE_NOT_BUILT_IN;
+
+}
+
+/*
+ * Function provided by the resolver backend to set
+ * outgoing interface to use for DNS requests
+ */
+CURLcode Curl_set_dns_interface(struct SessionHandle *data,
+ const char *interf)
+{
+ (void)data;
+ (void)interf;
+ return CURLE_NOT_BUILT_IN;
+}
+
+/*
+ * Function provided by the resolver backend to set
+ * local IPv4 address to use as source address for DNS requests
+ */
+CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
+ const char *local_ip4)
+{
+ (void)data;
+ (void)local_ip4;
+ return CURLE_NOT_BUILT_IN;
+}
+
+/*
+ * Function provided by the resolver backend to set
+ * local IPv6 address to use as source address for DNS requests
+ */
+CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data,
+ const char *local_ip6)
+{
+ (void)data;
+ (void)local_ip6;
+ return CURLE_NOT_BUILT_IN;
+}
+
+#endif /* truly sync */
diff --git a/Utilities/cmcurl/lib/http.c b/Utilities/cmcurl/lib/http.c
new file mode 100644
index 000000000..9817d72af
--- /dev/null
+++ b/Utilities/cmcurl/lib/http.c
@@ -0,0 +1,3738 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_HTTP
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "transfer.h"
+#include "sendf.h"
+#include "formdata.h"
+#include "progress.h"
+#include "curl_base64.h"
+#include "cookie.h"
+#include "strequal.h"
+#include "vtls/vtls.h"
+#include "http_digest.h"
+#include "curl_ntlm.h"
+#include "curl_ntlm_wb.h"
+#include "http_negotiate.h"
+#include "url.h"
+#include "share.h"
+#include "hostip.h"
+#include "http.h"
+#include "select.h"
+#include "parsedate.h" /* for the week day and month names */
+#include "strtoofft.h"
+#include "multiif.h"
+#include "rawstr.h"
+#include "content_encoding.h"
+#include "http_proxy.h"
+#include "warnless.h"
+#include "non-ascii.h"
+#include "conncache.h"
+#include "pipeline.h"
+#include "http2.h"
+#include "connect.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+ * Forward declarations.
+ */
+
+static int http_getsock_do(struct connectdata *conn,
+ curl_socket_t *socks,
+ int numsocks);
+static int http_should_fail(struct connectdata *conn);
+
+#ifdef USE_SSL
+static CURLcode https_connecting(struct connectdata *conn, bool *done);
+static int https_getsock(struct connectdata *conn,
+ curl_socket_t *socks,
+ int numsocks);
+#else
+#define https_connecting(x,y) CURLE_COULDNT_CONNECT
+#endif
+
+/*
+ * HTTP handler interface.
+ */
+const struct Curl_handler Curl_handler_http = {
+ "HTTP", /* scheme */
+ Curl_http_setup_conn, /* setup_connection */
+ Curl_http, /* do_it */
+ Curl_http_done, /* done */
+ ZERO_NULL, /* do_more */
+ Curl_http_connect, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_getsock */
+ http_getsock_do, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ ZERO_NULL, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_HTTP, /* defport */
+ CURLPROTO_HTTP, /* protocol */
+ PROTOPT_CREDSPERREQUEST /* flags */
+};
+
+#ifdef USE_SSL
+/*
+ * HTTPS handler interface.
+ */
+const struct Curl_handler Curl_handler_https = {
+ "HTTPS", /* scheme */
+ Curl_http_setup_conn, /* setup_connection */
+ Curl_http, /* do_it */
+ Curl_http_done, /* done */
+ ZERO_NULL, /* do_more */
+ Curl_http_connect, /* connect_it */
+ https_connecting, /* connecting */
+ ZERO_NULL, /* doing */
+ https_getsock, /* proto_getsock */
+ http_getsock_do, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ ZERO_NULL, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_HTTPS, /* defport */
+ CURLPROTO_HTTPS, /* protocol */
+ PROTOPT_SSL | PROTOPT_CREDSPERREQUEST /* flags */
+};
+#endif
+
+
+CURLcode Curl_http_setup_conn(struct connectdata *conn)
+{
+ /* allocate the HTTP-specific struct for the SessionHandle, only to survive
+ during this request */
+ struct HTTP *http;
+ DEBUGASSERT(conn->data->req.protop == NULL);
+
+ http = calloc(1, sizeof(struct HTTP));
+ if(!http)
+ return CURLE_OUT_OF_MEMORY;
+
+ conn->data->req.protop = http;
+
+ Curl_http2_setup_conn(conn);
+ Curl_http2_setup_req(conn->data);
+
+ return CURLE_OK;
+}
+
+/*
+ * checkheaders() checks the linked list of custom HTTP headers for a
+ * particular header (prefix).
+ *
+ * Returns a pointer to the first matching header or NULL if none matched.
+ */
+char *Curl_checkheaders(const struct connectdata *conn,
+ const char *thisheader)
+{
+ struct curl_slist *head;
+ size_t thislen = strlen(thisheader);
+ struct SessionHandle *data = conn->data;
+
+ for(head = data->set.headers;head; head=head->next) {
+ if(Curl_raw_nequal(head->data, thisheader, thislen))
+ return head->data;
+ }
+ return NULL;
+}
+
+/*
+ * checkProxyHeaders() checks the linked list of custom proxy headers
+ * if proxy headers are not available, then it will lookup into http header
+ * link list
+ *
+ * It takes a connectdata struct as input instead of the SessionHandle simply
+ * to know if this is a proxy request or not, as it then might check a
+ * different header list.
+ *
+ */
+char *Curl_checkProxyheaders(const struct connectdata *conn,
+ const char *thisheader)
+{
+ struct curl_slist *head;
+ size_t thislen = strlen(thisheader);
+ struct SessionHandle *data = conn->data;
+
+ for(head = (conn->bits.proxy && data->set.sep_headers)?
+ data->set.proxyheaders:data->set.headers;
+ head; head=head->next) {
+ if(Curl_raw_nequal(head->data, thisheader, thislen))
+ return head->data;
+ }
+ return NULL;
+}
+
+/*
+ * Strip off leading and trailing whitespace from the value in the
+ * given HTTP header line and return a strdupped copy. Returns NULL in
+ * case of allocation failure. Returns an empty string if the header value
+ * consists entirely of whitespace.
+ */
+char *Curl_copy_header_value(const char *header)
+{
+ const char *start;
+ const char *end;
+ char *value;
+ size_t len;
+
+ DEBUGASSERT(header);
+
+ /* Find the end of the header name */
+ while(*header && (*header != ':'))
+ ++header;
+
+ if(*header)
+ /* Skip over colon */
+ ++header;
+
+ /* Find the first non-space letter */
+ start = header;
+ while(*start && ISSPACE(*start))
+ start++;
+
+ /* data is in the host encoding so
+ use '\r' and '\n' instead of 0x0d and 0x0a */
+ end = strchr(start, '\r');
+ if(!end)
+ end = strchr(start, '\n');
+ if(!end)
+ end = strchr(start, '\0');
+ if(!end)
+ return NULL;
+
+ /* skip all trailing space letters */
+ while((end > start) && ISSPACE(*end))
+ end--;
+
+ /* get length of the type */
+ len = end - start + 1;
+
+ value = malloc(len + 1);
+ if(!value)
+ return NULL;
+
+ memcpy(value, start, len);
+ value[len] = 0; /* zero terminate */
+
+ return value;
+}
+
+/*
+ * http_output_basic() sets up an Authorization: header (or the proxy version)
+ * for HTTP Basic authentication.
+ *
+ * Returns CURLcode.
+ */
+static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
+{
+ size_t size = 0;
+ char *authorization = NULL;
+ struct SessionHandle *data = conn->data;
+ char **userp;
+ const char *user;
+ const char *pwd;
+ CURLcode result;
+
+ if(proxy) {
+ userp = &conn->allocptr.proxyuserpwd;
+ user = conn->proxyuser;
+ pwd = conn->proxypasswd;
+ }
+ else {
+ userp = &conn->allocptr.userpwd;
+ user = conn->user;
+ pwd = conn->passwd;
+ }
+
+ snprintf(data->state.buffer, sizeof(data->state.buffer), "%s:%s", user, pwd);
+
+ result = Curl_base64_encode(data,
+ data->state.buffer, strlen(data->state.buffer),
+ &authorization, &size);
+ if(result)
+ return result;
+
+ if(!authorization)
+ return CURLE_REMOTE_ACCESS_DENIED;
+
+ free(*userp);
+ *userp = aprintf("%sAuthorization: Basic %s\r\n",
+ proxy?"Proxy-":"",
+ authorization);
+ free(authorization);
+ if(!*userp)
+ return CURLE_OUT_OF_MEMORY;
+
+ return CURLE_OK;
+}
+
+/* pickoneauth() selects the most favourable authentication method from the
+ * ones available and the ones we want.
+ *
+ * return TRUE if one was picked
+ */
+static bool pickoneauth(struct auth *pick)
+{
+ bool picked;
+ /* only deal with authentication we want */
+ unsigned long avail = pick->avail & pick->want;
+ picked = TRUE;
+
+ /* The order of these checks is highly relevant, as this will be the order
+ of preference in case of the existence of multiple accepted types. */
+ if(avail & CURLAUTH_NEGOTIATE)
+ pick->picked = CURLAUTH_NEGOTIATE;
+ else if(avail & CURLAUTH_DIGEST)
+ pick->picked = CURLAUTH_DIGEST;
+ else if(avail & CURLAUTH_NTLM)
+ pick->picked = CURLAUTH_NTLM;
+ else if(avail & CURLAUTH_NTLM_WB)
+ pick->picked = CURLAUTH_NTLM_WB;
+ else if(avail & CURLAUTH_BASIC)
+ pick->picked = CURLAUTH_BASIC;
+ else {
+ pick->picked = CURLAUTH_PICKNONE; /* we select to use nothing */
+ picked = FALSE;
+ }
+ pick->avail = CURLAUTH_NONE; /* clear it here */
+
+ return picked;
+}
+
+/*
+ * Curl_http_perhapsrewind()
+ *
+ * If we are doing POST or PUT {
+ * If we have more data to send {
+ * If we are doing NTLM {
+ * Keep sending since we must not disconnect
+ * }
+ * else {
+ * If there is more than just a little data left to send, close
+ * the current connection by force.
+ * }
+ * }
+ * If we have sent any data {
+ * If we don't have track of all the data {
+ * call app to tell it to rewind
+ * }
+ * else {
+ * rewind internally so that the operation can restart fine
+ * }
+ * }
+ * }
+ */
+static CURLcode http_perhapsrewind(struct connectdata *conn)
+{
+ struct SessionHandle *data = conn->data;
+ struct HTTP *http = data->req.protop;
+ curl_off_t bytessent;
+ curl_off_t expectsend = -1; /* default is unknown */
+
+ if(!http)
+ /* If this is still NULL, we have not reach very far and we can safely
+ skip this rewinding stuff */
+ return CURLE_OK;
+
+ switch(data->set.httpreq) {
+ case HTTPREQ_GET:
+ case HTTPREQ_HEAD:
+ return CURLE_OK;
+ default:
+ break;
+ }
+
+ bytessent = http->writebytecount;
+
+ if(conn->bits.authneg) {
+ /* This is a state where we are known to be negotiating and we don't send
+ any data then. */
+ expectsend = 0;
+ }
+ else if(!conn->bits.protoconnstart) {
+ /* HTTP CONNECT in progress: there is no body */
+ expectsend = 0;
+ }
+ else {
+ /* figure out how much data we are expected to send */
+ switch(data->set.httpreq) {
+ case HTTPREQ_POST:
+ if(data->state.infilesize != -1)
+ expectsend = data->state.infilesize;
+ else if(data->set.postfields)
+ expectsend = (curl_off_t)strlen(data->set.postfields);
+ break;
+ case HTTPREQ_PUT:
+ if(data->state.infilesize != -1)
+ expectsend = data->state.infilesize;
+ break;
+ case HTTPREQ_POST_FORM:
+ expectsend = http->postsize;
+ break;
+ default:
+ break;
+ }
+ }
+
+ conn->bits.rewindaftersend = FALSE; /* default */
+
+ if((expectsend == -1) || (expectsend > bytessent)) {
+#if defined(USE_NTLM)
+ /* There is still data left to send */
+ if((data->state.authproxy.picked == CURLAUTH_NTLM) ||
+ (data->state.authhost.picked == CURLAUTH_NTLM) ||
+ (data->state.authproxy.picked == CURLAUTH_NTLM_WB) ||
+ (data->state.authhost.picked == CURLAUTH_NTLM_WB)) {
+ if(((expectsend - bytessent) < 2000) ||
+ (conn->ntlm.state != NTLMSTATE_NONE) ||
+ (conn->proxyntlm.state != NTLMSTATE_NONE)) {
+ /* The NTLM-negotiation has started *OR* there is just a little (<2K)
+ data left to send, keep on sending. */
+
+ /* rewind data when completely done sending! */
+ if(!conn->bits.authneg) {
+ conn->bits.rewindaftersend = TRUE;
+ infof(data, "Rewind stream after send\n");
+ }
+
+ return CURLE_OK;
+ }
+
+ if(conn->bits.close)
+ /* this is already marked to get closed */
+ return CURLE_OK;
+
+ infof(data, "NTLM send, close instead of sending %"
+ CURL_FORMAT_CURL_OFF_T " bytes\n",
+ (curl_off_t)(expectsend - bytessent));
+ }
+#endif
+
+ /* This is not NTLM or many bytes left to send: close */
+ connclose(conn, "Mid-auth HTTP and much data left to send");
+ data->req.size = 0; /* don't download any more than 0 bytes */
+
+ /* There still is data left to send, but this connection is marked for
+ closure so we can safely do the rewind right now */
+ }
+
+ if(bytessent)
+ /* we rewind now at once since if we already sent something */
+ return Curl_readrewind(conn);
+
+ return CURLE_OK;
+}
+
+/*
+ * Curl_http_auth_act() gets called when all HTTP headers have been received
+ * and it checks what authentication methods that are available and decides
+ * which one (if any) to use. It will set 'newurl' if an auth method was
+ * picked.
+ */
+
+CURLcode Curl_http_auth_act(struct connectdata *conn)
+{
+ struct SessionHandle *data = conn->data;
+ bool pickhost = FALSE;
+ bool pickproxy = FALSE;
+ CURLcode result = CURLE_OK;
+
+ if(100 <= data->req.httpcode && 199 >= data->req.httpcode)
+ /* this is a transient response code, ignore */
+ return CURLE_OK;
+
+ if(data->state.authproblem)
+ return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
+
+ if(conn->bits.user_passwd &&
+ ((data->req.httpcode == 401) ||
+ (conn->bits.authneg && data->req.httpcode < 300))) {
+ pickhost = pickoneauth(&data->state.authhost);
+ if(!pickhost)
+ data->state.authproblem = TRUE;
+ }
+ if(conn->bits.proxy_user_passwd &&
+ ((data->req.httpcode == 407) ||
+ (conn->bits.authneg && data->req.httpcode < 300))) {
+ pickproxy = pickoneauth(&data->state.authproxy);
+ if(!pickproxy)
+ data->state.authproblem = TRUE;
+ }
+
+ if(pickhost || pickproxy) {
+ /* In case this is GSS auth, the newurl field is already allocated so
+ we must make sure to free it before allocating a new one. As figured
+ out in bug #2284386 */
+ Curl_safefree(data->req.newurl);
+ data->req.newurl = strdup(data->change.url); /* clone URL */
+ if(!data->req.newurl)
+ return CURLE_OUT_OF_MEMORY;
+
+ if((data->set.httpreq != HTTPREQ_GET) &&
+ (data->set.httpreq != HTTPREQ_HEAD) &&
+ !conn->bits.rewindaftersend) {
+ result = http_perhapsrewind(conn);
+ if(result)
+ return result;
+ }
+ }
+
+ else if((data->req.httpcode < 300) &&
+ (!data->state.authhost.done) &&
+ conn->bits.authneg) {
+ /* no (known) authentication available,
+ authentication is not "done" yet and
+ no authentication seems to be required and
+ we didn't try HEAD or GET */
+ if((data->set.httpreq != HTTPREQ_GET) &&
+ (data->set.httpreq != HTTPREQ_HEAD)) {
+ data->req.newurl = strdup(data->change.url); /* clone URL */
+ if(!data->req.newurl)
+ return CURLE_OUT_OF_MEMORY;
+ data->state.authhost.done = TRUE;
+ }
+ }
+ if(http_should_fail(conn)) {
+ failf (data, "The requested URL returned error: %d",
+ data->req.httpcode);
+ result = CURLE_HTTP_RETURNED_ERROR;
+ }
+
+ return result;
+}
+
+
+/*
+ * Output the correct authentication header depending on the auth type
+ * and whether or not it is to a proxy.
+ */
+static CURLcode
+output_auth_headers(struct connectdata *conn,
+ struct auth *authstatus,
+ const char *request,
+ const char *path,
+ bool proxy)
+{
+ const char *auth = NULL;
+ CURLcode result = CURLE_OK;
+#if defined(USE_SPNEGO) || !defined(CURL_DISABLE_VERBOSE_STRINGS)
+ struct SessionHandle *data = conn->data;
+#endif
+#ifdef USE_SPNEGO
+ struct negotiatedata *negdata = proxy?
+ &data->state.proxyneg:&data->state.negotiate;
+#endif
+
+#ifdef CURL_DISABLE_CRYPTO_AUTH
+ (void)request;
+ (void)path;
+#endif
+
+#ifdef USE_SPNEGO
+ negdata->state = GSS_AUTHNONE;
+ if((authstatus->picked == CURLAUTH_NEGOTIATE) &&
+ negdata->context && !GSS_ERROR(negdata->status)) {
+ auth="Negotiate";
+ result = Curl_output_negotiate(conn, proxy);
+ if(result)
+ return result;
+ authstatus->done = TRUE;
+ negdata->state = GSS_AUTHSENT;
+ }
+ else
+#endif
+#ifdef USE_NTLM
+ if(authstatus->picked == CURLAUTH_NTLM) {
+ auth="NTLM";
+ result = Curl_output_ntlm(conn, proxy);
+ if(result)
+ return result;
+ }
+ else
+#endif
+#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
+ if(authstatus->picked == CURLAUTH_NTLM_WB) {
+ auth="NTLM_WB";
+ result = Curl_output_ntlm_wb(conn, proxy);
+ if(result)
+ return result;
+ }
+ else
+#endif
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+ if(authstatus->picked == CURLAUTH_DIGEST) {
+ auth="Digest";
+ result = Curl_output_digest(conn,
+ proxy,
+ (const unsigned char *)request,
+ (const unsigned char *)path);
+ if(result)
+ return result;
+ }
+ else
+#endif
+ if(authstatus->picked == CURLAUTH_BASIC) {
+ /* Basic */
+ if((proxy && conn->bits.proxy_user_passwd &&
+ !Curl_checkProxyheaders(conn, "Proxy-authorization:")) ||
+ (!proxy && conn->bits.user_passwd &&
+ !Curl_checkheaders(conn, "Authorization:"))) {
+ auth="Basic";
+ result = http_output_basic(conn, proxy);
+ if(result)
+ return result;
+ }
+ /* NOTE: this function should set 'done' TRUE, as the other auth
+ functions work that way */
+ authstatus->done = TRUE;
+ }
+
+ if(auth) {
+ infof(data, "%s auth using %s with user '%s'\n",
+ proxy?"Proxy":"Server", auth,
+ proxy?(conn->proxyuser?conn->proxyuser:""):
+ (conn->user?conn->user:""));
+ authstatus->multi = (!authstatus->done) ? TRUE : FALSE;
+ }
+ else
+ authstatus->multi = FALSE;
+
+ return CURLE_OK;
+}
+
+/**
+ * Curl_http_output_auth() setups the authentication headers for the
+ * host/proxy and the correct authentication
+ * method. conn->data->state.authdone is set to TRUE when authentication is
+ * done.
+ *
+ * @param conn all information about the current connection
+ * @param request pointer to the request keyword
+ * @param path pointer to the requested path
+ * @param proxytunnel boolean if this is the request setting up a "proxy
+ * tunnel"
+ *
+ * @returns CURLcode
+ */
+CURLcode
+Curl_http_output_auth(struct connectdata *conn,
+ const char *request,
+ const char *path,
+ bool proxytunnel) /* TRUE if this is the request setting
+ up the proxy tunnel */
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct auth *authhost;
+ struct auth *authproxy;
+
+ DEBUGASSERT(data);
+
+ authhost = &data->state.authhost;
+ authproxy = &data->state.authproxy;
+
+ if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
+ conn->bits.user_passwd)
+ /* continue please */;
+ else {
+ authhost->done = TRUE;
+ authproxy->done = TRUE;
+ return CURLE_OK; /* no authentication with no user or password */
+ }
+
+ if(authhost->want && !authhost->picked)
+ /* The app has selected one or more methods, but none has been picked
+ so far by a server round-trip. Then we set the picked one to the
+ want one, and if this is one single bit it'll be used instantly. */
+ authhost->picked = authhost->want;
+
+ if(authproxy->want && !authproxy->picked)
+ /* The app has selected one or more methods, but none has been picked so
+ far by a proxy round-trip. Then we set the picked one to the want one,
+ and if this is one single bit it'll be used instantly. */
+ authproxy->picked = authproxy->want;
+
+#ifndef CURL_DISABLE_PROXY
+ /* Send proxy authentication header if needed */
+ if(conn->bits.httpproxy &&
+ (conn->bits.tunnel_proxy == proxytunnel)) {
+ result = output_auth_headers(conn, authproxy, request, path, TRUE);
+ if(result)
+ return result;
+ }
+ else
+#else
+ (void)proxytunnel;
+#endif /* CURL_DISABLE_PROXY */
+ /* we have no proxy so let's pretend we're done authenticating
+ with it */
+ authproxy->done = TRUE;
+
+ /* To prevent the user+password to get sent to other than the original
+ host due to a location-follow, we do some weirdo checks here */
+ if(!data->state.this_is_a_follow ||
+ conn->bits.netrc ||
+ !data->state.first_host ||
+ data->set.http_disable_hostname_check_before_authentication ||
+ Curl_raw_equal(data->state.first_host, conn->host.name)) {
+ result = output_auth_headers(conn, authhost, request, path, FALSE);
+ }
+ else
+ authhost->done = TRUE;
+
+ return result;
+}
+
+
+/*
+ * Curl_http_input_auth() deals with Proxy-Authenticate: and WWW-Authenticate:
+ * headers. They are dealt with both in the transfer.c main loop and in the
+ * proxy CONNECT loop.
+ */
+
+CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
+ const char *auth) /* the first non-space */
+{
+ /*
+ * This resource requires authentication
+ */
+ struct SessionHandle *data = conn->data;
+
+#ifdef USE_SPNEGO
+ struct negotiatedata *negdata = proxy?
+ &data->state.proxyneg:&data->state.negotiate;
+#endif
+ unsigned long *availp;
+ struct auth *authp;
+
+ if(proxy) {
+ availp = &data->info.proxyauthavail;
+ authp = &data->state.authproxy;
+ }
+ else {
+ availp = &data->info.httpauthavail;
+ authp = &data->state.authhost;
+ }
+
+ /*
+ * Here we check if we want the specific single authentication (using ==) and
+ * if we do, we initiate usage of it.
+ *
+ * If the provided authentication is wanted as one out of several accepted
+ * types (using &), we OR this authentication type to the authavail
+ * variable.
+ *
+ * Note:
+ *
+ * ->picked is first set to the 'want' value (one or more bits) before the
+ * request is sent, and then it is again set _after_ all response 401/407
+ * headers have been received but then only to a single preferred method
+ * (bit).
+ *
+ */
+
+ while(*auth) {
+#ifdef USE_SPNEGO
+ if(checkprefix("Negotiate", auth)) {
+ *availp |= CURLAUTH_NEGOTIATE;
+ authp->avail |= CURLAUTH_NEGOTIATE;
+
+ if(authp->picked == CURLAUTH_NEGOTIATE) {
+ if(negdata->state == GSS_AUTHSENT || negdata->state == GSS_AUTHNONE) {
+ CURLcode result = Curl_input_negotiate(conn, proxy, auth);
+ if(!result) {
+ DEBUGASSERT(!data->req.newurl);
+ data->req.newurl = strdup(data->change.url);
+ if(!data->req.newurl)
+ return CURLE_OUT_OF_MEMORY;
+ data->state.authproblem = FALSE;
+ /* we received a GSS auth token and we dealt with it fine */
+ negdata->state = GSS_AUTHRECV;
+ }
+ else
+ data->state.authproblem = TRUE;
+ }
+ }
+ }
+ else
+#endif
+#ifdef USE_NTLM
+ /* NTLM support requires the SSL crypto libs */
+ if(checkprefix("NTLM", auth)) {
+ *availp |= CURLAUTH_NTLM;
+ authp->avail |= CURLAUTH_NTLM;
+ if(authp->picked == CURLAUTH_NTLM ||
+ authp->picked == CURLAUTH_NTLM_WB) {
+ /* NTLM authentication is picked and activated */
+ CURLcode result = Curl_input_ntlm(conn, proxy, auth);
+ if(!result) {
+ data->state.authproblem = FALSE;
+#ifdef NTLM_WB_ENABLED
+ if(authp->picked == CURLAUTH_NTLM_WB) {
+ *availp &= ~CURLAUTH_NTLM;
+ authp->avail &= ~CURLAUTH_NTLM;
+ *availp |= CURLAUTH_NTLM_WB;
+ authp->avail |= CURLAUTH_NTLM_WB;
+
+ /* Get the challenge-message which will be passed to
+ * ntlm_auth for generating the type 3 message later */
+ while(*auth && ISSPACE(*auth))
+ auth++;
+ if(checkprefix("NTLM", auth)) {
+ auth += strlen("NTLM");
+ while(*auth && ISSPACE(*auth))
+ auth++;
+ if(*auth)
+ if((conn->challenge_header = strdup(auth)) == NULL)
+ return CURLE_OUT_OF_MEMORY;
+ }
+ }
+#endif
+ }
+ else {
+ infof(data, "Authentication problem. Ignoring this.\n");
+ data->state.authproblem = TRUE;
+ }
+ }
+ }
+ else
+#endif
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+ if(checkprefix("Digest", auth)) {
+ if((authp->avail & CURLAUTH_DIGEST) != 0) {
+ infof(data, "Ignoring duplicate digest auth header.\n");
+ }
+ else {
+ CURLcode result;
+ *availp |= CURLAUTH_DIGEST;
+ authp->avail |= CURLAUTH_DIGEST;
+
+ /* We call this function on input Digest headers even if Digest
+ * authentication isn't activated yet, as we need to store the
+ * incoming data from this header in case we are gonna use
+ * Digest. */
+ result = Curl_input_digest(conn, proxy, auth);
+ if(result) {
+ infof(data, "Authentication problem. Ignoring this.\n");
+ data->state.authproblem = TRUE;
+ }
+ }
+ }
+ else
+#endif
+ if(checkprefix("Basic", auth)) {
+ *availp |= CURLAUTH_BASIC;
+ authp->avail |= CURLAUTH_BASIC;
+ if(authp->picked == CURLAUTH_BASIC) {
+ /* We asked for Basic authentication but got a 40X back
+ anyway, which basically means our name+password isn't
+ valid. */
+ authp->avail = CURLAUTH_NONE;
+ infof(data, "Authentication problem. Ignoring this.\n");
+ data->state.authproblem = TRUE;
+ }
+ }
+
+ /* there may be multiple methods on one line, so keep reading */
+ while(*auth && *auth != ',') /* read up to the next comma */
+ auth++;
+ if(*auth == ',') /* if we're on a comma, skip it */
+ auth++;
+ while(*auth && ISSPACE(*auth))
+ auth++;
+ }
+ return CURLE_OK;
+}
+
+/**
+ * http_should_fail() determines whether an HTTP response has gotten us
+ * into an error state or not.
+ *
+ * @param conn all information about the current connection
+ *
+ * @retval 0 communications should continue
+ *
+ * @retval 1 communications should not continue
+ */
+static int http_should_fail(struct connectdata *conn)
+{
+ struct SessionHandle *data;
+ int httpcode;
+
+ DEBUGASSERT(conn);
+ data = conn->data;
+ DEBUGASSERT(data);
+
+ httpcode = data->req.httpcode;
+
+ /*
+ ** If we haven't been asked to fail on error,
+ ** don't fail.
+ */
+ if(!data->set.http_fail_on_error)
+ return 0;
+
+ /*
+ ** Any code < 400 is never terminal.
+ */
+ if(httpcode < 400)
+ return 0;
+
+ /*
+ ** Any code >= 400 that's not 401 or 407 is always
+ ** a terminal error
+ */
+ if((httpcode != 401) &&
+ (httpcode != 407))
+ return 1;
+
+ /*
+ ** All we have left to deal with is 401 and 407
+ */
+ DEBUGASSERT((httpcode == 401) || (httpcode == 407));
+
+ /*
+ ** Examine the current authentication state to see if this
+ ** is an error. The idea is for this function to get
+ ** called after processing all the headers in a response
+ ** message. So, if we've been to asked to authenticate a
+ ** particular stage, and we've done it, we're OK. But, if
+ ** we're already completely authenticated, it's not OK to
+ ** get another 401 or 407.
+ **
+ ** It is possible for authentication to go stale such that
+ ** the client needs to reauthenticate. Once that info is
+ ** available, use it here.
+ */
+
+ /*
+ ** Either we're not authenticating, or we're supposed to
+ ** be authenticating something else. This is an error.
+ */
+ if((httpcode == 401) && !conn->bits.user_passwd)
+ return TRUE;
+ if((httpcode == 407) && !conn->bits.proxy_user_passwd)
+ return TRUE;
+
+ return data->state.authproblem;
+}
+
+/*
+ * readmoredata() is a "fread() emulation" to provide POST and/or request
+ * data. It is used when a huge POST is to be made and the entire chunk wasn't
+ * sent in the first send(). This function will then be called from the
+ * transfer.c loop when more data is to be sent to the peer.
+ *
+ * Returns the amount of bytes it filled the buffer with.
+ */
+static size_t readmoredata(char *buffer,
+ size_t size,
+ size_t nitems,
+ void *userp)
+{
+ struct connectdata *conn = (struct connectdata *)userp;
+ struct HTTP *http = conn->data->req.protop;
+ size_t fullsize = size * nitems;
+
+ if(0 == http->postsize)
+ /* nothing to return */
+ return 0;
+
+ /* make sure that a HTTP request is never sent away chunked! */
+ conn->data->req.forbidchunk = (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE;
+
+ if(http->postsize <= (curl_off_t)fullsize) {
+ memcpy(buffer, http->postdata, (size_t)http->postsize);
+ fullsize = (size_t)http->postsize;
+
+ if(http->backup.postsize) {
+ /* move backup data into focus and continue on that */
+ http->postdata = http->backup.postdata;
+ http->postsize = http->backup.postsize;
+ conn->data->set.fread_func = http->backup.fread_func;
+ conn->data->set.in = http->backup.fread_in;
+
+ http->sending++; /* move one step up */
+
+ http->backup.postsize=0;
+ }
+ else
+ http->postsize = 0;
+
+ return fullsize;
+ }
+
+ memcpy(buffer, http->postdata, fullsize);
+ http->postdata += fullsize;
+ http->postsize -= fullsize;
+
+ return fullsize;
+}
+
+/* ------------------------------------------------------------------------- */
+/* add_buffer functions */
+
+/*
+ * Curl_add_buffer_init() sets up and returns a fine buffer struct
+ */
+Curl_send_buffer *Curl_add_buffer_init(void)
+{
+ return calloc(1, sizeof(Curl_send_buffer));
+}
+
+/*
+ * Curl_add_buffer_free() frees all associated resources.
+ */
+void Curl_add_buffer_free(Curl_send_buffer *buff)
+{
+ if(buff) /* deal with NULL input */
+ free(buff->buffer);
+ free(buff);
+}
+
+/*
+ * Curl_add_buffer_send() sends a header buffer and frees all associated
+ * memory. Body data may be appended to the header data if desired.
+ *
+ * Returns CURLcode
+ */
+CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
+ struct connectdata *conn,
+
+ /* add the number of sent bytes to this
+ counter */
+ long *bytes_written,
+
+ /* how much of the buffer contains body data */
+ size_t included_body_bytes,
+ int socketindex)
+
+{
+ ssize_t amount;
+ CURLcode result;
+ char *ptr;
+ size_t size;
+ struct HTTP *http = conn->data->req.protop;
+ size_t sendsize;
+ curl_socket_t sockfd;
+ size_t headersize;
+
+ DEBUGASSERT(socketindex <= SECONDARYSOCKET);
+
+ sockfd = conn->sock[socketindex];
+
+ /* The looping below is required since we use non-blocking sockets, but due
+ to the circumstances we will just loop and try again and again etc */
+
+ ptr = in->buffer;
+ size = in->size_used;
+
+ headersize = size - included_body_bytes; /* the initial part that isn't body
+ is header */
+
+ DEBUGASSERT(size > included_body_bytes);
+
+ result = Curl_convert_to_network(conn->data, ptr, headersize);
+ /* Curl_convert_to_network calls failf if unsuccessful */
+ if(result) {
+ /* conversion failed, free memory and return to the caller */
+ Curl_add_buffer_free(in);
+ return result;
+ }
+
+
+ if(conn->handler->flags & PROTOPT_SSL) {
+ /* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
+ when we speak HTTPS, as if only a fraction of it is sent now, this data
+ needs to fit into the normal read-callback buffer later on and that
+ buffer is using this size.
+ */
+
+ sendsize= (size > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:size;
+
+ /* OpenSSL is very picky and we must send the SAME buffer pointer to the
+ library when we attempt to re-send this buffer. Sending the same data
+ is not enough, we must use the exact same address. For this reason, we
+ must copy the data to the uploadbuffer first, since that is the buffer
+ we will be using if this send is retried later.
+ */
+ memcpy(conn->data->state.uploadbuffer, ptr, sendsize);
+ ptr = conn->data->state.uploadbuffer;
+ }
+ else
+ sendsize = size;
+
+ result = Curl_write(conn, sockfd, ptr, sendsize, &amount);
+
+ if(!result) {
+ /*
+ * Note that we may not send the entire chunk at once, and we have a set
+ * number of data bytes at the end of the big buffer (out of which we may
+ * only send away a part).
+ */
+ /* how much of the header that was sent */
+ size_t headlen = (size_t)amount>headersize?headersize:(size_t)amount;
+ size_t bodylen = amount - headlen;
+
+ if(conn->data->set.verbose) {
+ /* this data _may_ contain binary stuff */
+ Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, headlen, conn);
+ if(bodylen) {
+ /* there was body data sent beyond the initial header part, pass that
+ on to the debug callback too */
+ Curl_debug(conn->data, CURLINFO_DATA_OUT,
+ ptr+headlen, bodylen, conn);
+ }
+ }
+ if(bodylen)
+ /* since we sent a piece of the body here, up the byte counter for it
+ accordingly */
+ http->writebytecount += bodylen;
+
+ /* 'amount' can never be a very large value here so typecasting it so a
+ signed 31 bit value should not cause problems even if ssize_t is
+ 64bit */
+ *bytes_written += (long)amount;
+
+ if(http) {
+ if((size_t)amount != size) {
+ /* The whole request could not be sent in one system call. We must
+ queue it up and send it later when we get the chance. We must not
+ loop here and wait until it might work again. */
+
+ size -= amount;
+
+ ptr = in->buffer + amount;
+
+ /* backup the currently set pointers */
+ http->backup.fread_func = conn->data->set.fread_func;
+ http->backup.fread_in = conn->data->set.in;
+ http->backup.postdata = http->postdata;
+ http->backup.postsize = http->postsize;
+
+ /* set the new pointers for the request-sending */
+ conn->data->set.fread_func = (curl_read_callback)readmoredata;
+ conn->data->set.in = (void *)conn;
+ http->postdata = ptr;
+ http->postsize = (curl_off_t)size;
+
+ http->send_buffer = in;
+ http->sending = HTTPSEND_REQUEST;
+
+ return CURLE_OK;
+ }
+ http->sending = HTTPSEND_BODY;
+ /* the full buffer was sent, clean up and return */
+ }
+ else {
+ if((size_t)amount != size)
+ /* We have no continue-send mechanism now, fail. This can only happen
+ when this function is used from the CONNECT sending function. We
+ currently (stupidly) assume that the whole request is always sent
+ away in the first single chunk.
+
+ This needs FIXing.
+ */
+ return CURLE_SEND_ERROR;
+ else
+ Curl_pipeline_leave_write(conn);
+ }
+ }
+ Curl_add_buffer_free(in);
+
+ return result;
+}
+
+
+/*
+ * add_bufferf() add the formatted input to the buffer.
+ */
+CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...)
+{
+ char *s;
+ va_list ap;
+ va_start(ap, fmt);
+ s = vaprintf(fmt, ap); /* this allocs a new string to append */
+ va_end(ap);
+
+ if(s) {
+ CURLcode result = Curl_add_buffer(in, s, strlen(s));
+ free(s);
+ return result;
+ }
+ /* If we failed, we cleanup the whole buffer and return error */
+ free(in->buffer);
+ free(in);
+ return CURLE_OUT_OF_MEMORY;
+}
+
+/*
+ * add_buffer() appends a memory chunk to the existing buffer
+ */
+CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
+{
+ char *new_rb;
+ size_t new_size;
+
+ if(~size < in->size_used) {
+ /* If resulting used size of send buffer would wrap size_t, cleanup
+ the whole buffer and return error. Otherwise the required buffer
+ size will fit into a single allocatable memory chunk */
+ Curl_safefree(in->buffer);
+ free(in);
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ if(!in->buffer ||
+ ((in->size_used + size) > (in->size_max - 1))) {
+
+ /* If current buffer size isn't enough to hold the result, use a
+ buffer size that doubles the required size. If this new size
+ would wrap size_t, then just use the largest possible one */
+
+ if((size > (size_t)-1/2) || (in->size_used > (size_t)-1/2) ||
+ (~(size*2) < (in->size_used*2)))
+ new_size = (size_t)-1;
+ else
+ new_size = (in->size_used+size)*2;
+
+ if(in->buffer)
+ /* we have a buffer, enlarge the existing one */
+ new_rb = realloc(in->buffer, new_size);
+ else
+ /* create a new buffer */
+ new_rb = malloc(new_size);
+
+ if(!new_rb) {
+ /* If we failed, we cleanup the whole buffer and return error */
+ Curl_safefree(in->buffer);
+ free(in);
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ in->buffer = new_rb;
+ in->size_max = new_size;
+ }
+ memcpy(&in->buffer[in->size_used], inptr, size);
+
+ in->size_used += size;
+
+ return CURLE_OK;
+}
+
+/* end of the add_buffer functions */
+/* ------------------------------------------------------------------------- */
+
+
+
+/*
+ * Curl_compareheader()
+ *
+ * Returns TRUE if 'headerline' contains the 'header' with given 'content'.
+ * Pass headers WITH the colon.
+ */
+bool
+Curl_compareheader(const char *headerline, /* line to check */
+ const char *header, /* header keyword _with_ colon */
+ const char *content) /* content string to find */
+{
+ /* RFC2616, section 4.2 says: "Each header field consists of a name followed
+ * by a colon (":") and the field value. Field names are case-insensitive.
+ * The field value MAY be preceded by any amount of LWS, though a single SP
+ * is preferred." */
+
+ size_t hlen = strlen(header);
+ size_t clen;
+ size_t len;
+ const char *start;
+ const char *end;
+
+ if(!Curl_raw_nequal(headerline, header, hlen))
+ return FALSE; /* doesn't start with header */
+
+ /* pass the header */
+ start = &headerline[hlen];
+
+ /* pass all white spaces */
+ while(*start && ISSPACE(*start))
+ start++;
+
+ /* find the end of the header line */
+ end = strchr(start, '\r'); /* lines end with CRLF */
+ if(!end) {
+ /* in case there's a non-standard compliant line here */
+ end = strchr(start, '\n');
+
+ if(!end)
+ /* hm, there's no line ending here, use the zero byte! */
+ end = strchr(start, '\0');
+ }
+
+ len = end-start; /* length of the content part of the input line */
+ clen = strlen(content); /* length of the word to find */
+
+ /* find the content string in the rest of the line */
+ for(;len>=clen;len--, start++) {
+ if(Curl_raw_nequal(start, content, clen))
+ return TRUE; /* match! */
+ }
+
+ return FALSE; /* no match */
+}
+
+/*
+ * Curl_http_connect() performs HTTP stuff to do at connect-time, called from
+ * the generic Curl_connect().
+ */
+CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
+{
+ CURLcode result;
+
+ /* We default to persistent connections. We set this already in this connect
+ function to make the re-use checks properly be able to check this bit. */
+ connkeep(conn, "HTTP default");
+
+ /* the CONNECT procedure might not have been completed */
+ result = Curl_proxy_connect(conn);
+ if(result)
+ return result;
+
+ if(conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
+ /* nothing else to do except wait right now - we're not done here. */
+ return CURLE_OK;
+
+ if(conn->given->flags & PROTOPT_SSL) {
+ /* perform SSL initialization */
+ result = https_connecting(conn, done);
+ if(result)
+ return result;
+ }
+ else
+ *done = TRUE;
+
+ return CURLE_OK;
+}
+
+/* this returns the socket to wait for in the DO and DOING state for the multi
+ interface and then we're always _sending_ a request and thus we wait for
+ the single socket to become writable only */
+static int http_getsock_do(struct connectdata *conn,
+ curl_socket_t *socks,
+ int numsocks)
+{
+ /* write mode */
+ (void)numsocks; /* unused, we trust it to be at least 1 */
+ socks[0] = conn->sock[FIRSTSOCKET];
+ return GETSOCK_WRITESOCK(0);
+}
+
+#ifdef USE_SSL
+static CURLcode https_connecting(struct connectdata *conn, bool *done)
+{
+ CURLcode result;
+ DEBUGASSERT((conn) && (conn->handler->flags & PROTOPT_SSL));
+
+ /* perform SSL initialization for this socket */
+ result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
+ if(result)
+ connclose(conn, "Failed HTTPS connection");
+
+ return result;
+}
+#endif
+
+#if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
+ defined(USE_DARWINSSL) || defined(USE_POLARSSL) || defined(USE_NSS)
+/* This function is for OpenSSL, GnuTLS, darwinssl, schannel and polarssl only.
+ It should be made to query the generic SSL layer instead. */
+static int https_getsock(struct connectdata *conn,
+ curl_socket_t *socks,
+ int numsocks)
+{
+ if(conn->handler->flags & PROTOPT_SSL) {
+ struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
+
+ if(!numsocks)
+ return GETSOCK_BLANK;
+
+ if(connssl->connecting_state == ssl_connect_2_writing) {
+ /* write mode */
+ socks[0] = conn->sock[FIRSTSOCKET];
+ return GETSOCK_WRITESOCK(0);
+ }
+ else if(connssl->connecting_state == ssl_connect_2_reading) {
+ /* read mode */
+ socks[0] = conn->sock[FIRSTSOCKET];
+ return GETSOCK_READSOCK(0);
+ }
+ }
+ return CURLE_OK;
+}
+#else
+#ifdef USE_SSL
+static int https_getsock(struct connectdata *conn,
+ curl_socket_t *socks,
+ int numsocks)
+{
+ (void)conn;
+ (void)socks;
+ (void)numsocks;
+ return GETSOCK_BLANK;
+}
+#endif /* USE_SSL */
+#endif /* USE_OPENSSL || USE_GNUTLS || USE_SCHANNEL */
+
+/*
+ * Curl_http_done() gets called from Curl_done() after a single HTTP request
+ * has been performed.
+ */
+
+CURLcode Curl_http_done(struct connectdata *conn,
+ CURLcode status, bool premature)
+{
+ struct SessionHandle *data = conn->data;
+ struct HTTP *http = data->req.protop;
+#ifdef USE_NGHTTP2
+ struct http_conn *httpc = &conn->proto.httpc;
+#endif
+
+ Curl_unencode_cleanup(conn);
+
+#ifdef USE_SPNEGO
+ if(data->state.proxyneg.state == GSS_AUTHSENT ||
+ data->state.negotiate.state == GSS_AUTHSENT) {
+ /* add forbid re-use if http-code != 401/407 as a WA only needed for
+ * 401/407 that signal auth failure (empty) otherwise state will be RECV
+ * with current code */
+ if((data->req.httpcode != 401) && (data->req.httpcode != 407))
+ connclose(conn, "Negotiate transfer completed");
+ Curl_cleanup_negotiate(data);
+ }
+#endif
+
+ /* set the proper values (possibly modified on POST) */
+ conn->seek_func = data->set.seek_func; /* restore */
+ conn->seek_client = data->set.seek_client; /* restore */
+
+ if(http == NULL)
+ return CURLE_OK;
+
+ if(http->send_buffer) {
+ Curl_add_buffer_free(http->send_buffer);
+ http->send_buffer = NULL; /* clear the pointer */
+ }
+
+#ifdef USE_NGHTTP2
+ if(http->header_recvbuf) {
+ DEBUGF(infof(data, "free header_recvbuf!!\n"));
+ Curl_add_buffer_free(http->header_recvbuf);
+ http->header_recvbuf = NULL; /* clear the pointer */
+ for(; http->push_headers_used > 0; --http->push_headers_used) {
+ free(http->push_headers[http->push_headers_used - 1]);
+ }
+ free(http->push_headers);
+ http->push_headers = NULL;
+ }
+ if(http->stream_id) {
+ nghttp2_session_set_stream_user_data(httpc->h2, http->stream_id, 0);
+ http->stream_id = 0;
+ }
+#endif
+
+ if(HTTPREQ_POST_FORM == data->set.httpreq) {
+ data->req.bytecount = http->readbytecount + http->writebytecount;
+
+ Curl_formclean(&http->sendit); /* Now free that whole lot */
+ if(http->form.fp) {
+ /* a file being uploaded was left opened, close it! */
+ fclose(http->form.fp);
+ http->form.fp = NULL;
+ }
+ }
+ else if(HTTPREQ_PUT == data->set.httpreq)
+ data->req.bytecount = http->readbytecount + http->writebytecount;
+
+ if(status)
+ return status;
+
+ if(!premature && /* this check is pointless when DONE is called before the
+ entire operation is complete */
+ !conn->bits.retry &&
+ !data->set.connect_only &&
+ ((http->readbytecount +
+ data->req.headerbytecount -
+ data->req.deductheadercount)) <= 0) {
+ /* If this connection isn't simply closed to be retried, AND nothing was
+ read from the HTTP server (that counts), this can't be right so we
+ return an error here */
+ failf(data, "Empty reply from server");
+ return CURLE_GOT_NOTHING;
+ }
+
+ return CURLE_OK;
+}
+
+
+/*
+ * Determine if we should use HTTP 1.1 (OR BETTER) for this request. Reasons
+ * to avoid it include:
+ *
+ * - if the user specifically requested HTTP 1.0
+ * - if the server we are connected to only supports 1.0
+ * - if any server previously contacted to handle this request only supports
+ * 1.0.
+ */
+static bool use_http_1_1plus(const struct SessionHandle *data,
+ const struct connectdata *conn)
+{
+ return ((data->set.httpversion >= CURL_HTTP_VERSION_1_1) ||
+ ((data->set.httpversion != CURL_HTTP_VERSION_1_0) &&
+ ((conn->httpversion == 11) ||
+ ((conn->httpversion != 10) &&
+ (data->state.httpversion != 10))))) ? TRUE : FALSE;
+}
+
+/* check and possibly add an Expect: header */
+static CURLcode expect100(struct SessionHandle *data,
+ struct connectdata *conn,
+ Curl_send_buffer *req_buffer)
+{
+ CURLcode result = CURLE_OK;
+ const char *ptr;
+ data->state.expect100header = FALSE; /* default to false unless it is set
+ to TRUE below */
+ if(use_http_1_1plus(data, conn) &&
+ (conn->httpversion != 20)) {
+ /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an
+ Expect: 100-continue to the headers which actually speeds up post
+ operations (as there is one packet coming back from the web server) */
+ ptr = Curl_checkheaders(conn, "Expect:");
+ if(ptr) {
+ data->state.expect100header =
+ Curl_compareheader(ptr, "Expect:", "100-continue");
+ }
+ else {
+ result = Curl_add_bufferf(req_buffer,
+ "Expect: 100-continue\r\n");
+ if(!result)
+ data->state.expect100header = TRUE;
+ }
+ }
+ return result;
+}
+
+enum proxy_use {
+ HEADER_SERVER, /* direct to server */
+ HEADER_PROXY, /* regular request to proxy */
+ HEADER_CONNECT /* sending CONNECT to a proxy */
+};
+
+CURLcode Curl_add_custom_headers(struct connectdata *conn,
+ bool is_connect,
+ Curl_send_buffer *req_buffer)
+{
+ char *ptr;
+ struct curl_slist *h[2];
+ struct curl_slist *headers;
+ int numlists=1; /* by default */
+ struct SessionHandle *data = conn->data;
+ int i;
+
+ enum proxy_use proxy;
+
+ if(is_connect)
+ proxy = HEADER_CONNECT;
+ else
+ proxy = conn->bits.httpproxy && !conn->bits.tunnel_proxy?
+ HEADER_PROXY:HEADER_SERVER;
+
+ switch(proxy) {
+ case HEADER_SERVER:
+ h[0] = data->set.headers;
+ break;
+ case HEADER_PROXY:
+ h[0] = data->set.headers;
+ if(data->set.sep_headers) {
+ h[1] = data->set.proxyheaders;
+ numlists++;
+ }
+ break;
+ case HEADER_CONNECT:
+ if(data->set.sep_headers)
+ h[0] = data->set.proxyheaders;
+ else
+ h[0] = data->set.headers;
+ break;
+ }
+
+ /* loop through one or two lists */
+ for(i=0; i < numlists; i++) {
+ headers = h[i];
+
+ while(headers) {
+ ptr = strchr(headers->data, ':');
+ if(ptr) {
+ /* we require a colon for this to be a true header */
+
+ ptr++; /* pass the colon */
+ while(*ptr && ISSPACE(*ptr))
+ ptr++;
+
+ if(*ptr) {
+ /* only send this if the contents was non-blank */
+
+ if(conn->allocptr.host &&
+ /* a Host: header was sent already, don't pass on any custom Host:
+ header as that will produce *two* in the same request! */
+ checkprefix("Host:", headers->data))
+ ;
+ else if(data->set.httpreq == HTTPREQ_POST_FORM &&
+ /* this header (extended by formdata.c) is sent later */
+ checkprefix("Content-Type:", headers->data))
+ ;
+ else if(conn->bits.authneg &&
+ /* while doing auth neg, don't allow the custom length since
+ we will force length zero then */
+ checkprefix("Content-Length", headers->data))
+ ;
+ else if(conn->allocptr.te &&
+ /* when asking for Transfer-Encoding, don't pass on a custom
+ Connection: */
+ checkprefix("Connection", headers->data))
+ ;
+ else {
+ CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n",
+ headers->data);
+ if(result)
+ return result;
+ }
+ }
+ }
+ else {
+ ptr = strchr(headers->data, ';');
+ if(ptr) {
+
+ ptr++; /* pass the semicolon */
+ while(*ptr && ISSPACE(*ptr))
+ ptr++;
+
+ if(*ptr) {
+ /* this may be used for something else in the future */
+ }
+ else {
+ if(*(--ptr) == ';') {
+ CURLcode result;
+
+ /* send no-value custom header if terminated by semicolon */
+ *ptr = ':';
+ result = Curl_add_bufferf(req_buffer, "%s\r\n",
+ headers->data);
+ if(result)
+ return result;
+ }
+ }
+ }
+ }
+ headers = headers->next;
+ }
+ }
+ return CURLE_OK;
+}
+
+CURLcode Curl_add_timecondition(struct SessionHandle *data,
+ Curl_send_buffer *req_buffer)
+{
+ const struct tm *tm;
+ char *buf = data->state.buffer;
+ struct tm keeptime;
+ CURLcode result = Curl_gmtime(data->set.timevalue, &keeptime);
+ if(result) {
+ failf(data, "Invalid TIMEVALUE");
+ return result;
+ }
+ tm = &keeptime;
+
+ /* The If-Modified-Since header family should have their times set in
+ * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be
+ * represented in Greenwich Mean Time (GMT), without exception. For the
+ * purposes of HTTP, GMT is exactly equal to UTC (Coordinated Universal
+ * Time)." (see page 20 of RFC2616).
+ */
+
+ /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
+ snprintf(buf, BUFSIZE-1,
+ "%s, %02d %s %4d %02d:%02d:%02d GMT",
+ Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
+ tm->tm_mday,
+ Curl_month[tm->tm_mon],
+ tm->tm_year + 1900,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec);
+
+ switch(data->set.timecondition) {
+ case CURL_TIMECOND_IFMODSINCE:
+ default:
+ result = Curl_add_bufferf(req_buffer,
+ "If-Modified-Since: %s\r\n", buf);
+ break;
+ case CURL_TIMECOND_IFUNMODSINCE:
+ result = Curl_add_bufferf(req_buffer,
+ "If-Unmodified-Since: %s\r\n", buf);
+ break;
+ case CURL_TIMECOND_LASTMOD:
+ result = Curl_add_bufferf(req_buffer,
+ "Last-Modified: %s\r\n", buf);
+ break;
+ }
+
+ return result;
+}
+
+/*
+ * Curl_http() gets called from the generic Curl_do() function when a HTTP
+ * request is to be performed. This creates and sends a properly constructed
+ * HTTP request.
+ */
+CURLcode Curl_http(struct connectdata *conn, bool *done)
+{
+ struct SessionHandle *data = conn->data;
+ CURLcode result = CURLE_OK;
+ struct HTTP *http;
+ const char *ppath = data->state.path;
+ bool paste_ftp_userpwd = FALSE;
+ char ftp_typecode[sizeof("/;type=?")] = "";
+ const char *host = conn->host.name;
+ const char *te = ""; /* transfer-encoding */
+ const char *ptr;
+ const char *request;
+ Curl_HttpReq httpreq = data->set.httpreq;
+#if !defined(CURL_DISABLE_COOKIES)
+ char *addcookies = NULL;
+#endif
+ curl_off_t included_body = 0;
+ const char *httpstring;
+ Curl_send_buffer *req_buffer;
+ curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */
+ int seekerr = CURL_SEEKFUNC_OK;
+
+ /* Always consider the DO phase done after this function call, even if there
+ may be parts of the request that is not yet sent, since we can deal with
+ the rest of the request in the PERFORM phase. */
+ *done = TRUE;
+
+ if(conn->httpversion < 20) { /* unless the connection is re-used and already
+ http2 */
+ switch(conn->negnpn) {
+ case CURL_HTTP_VERSION_2_0:
+ conn->httpversion = 20; /* we know we're on HTTP/2 now */
+ result = Curl_http2_init(conn);
+ if(result)
+ return result;
+
+ result = Curl_http2_setup(conn);
+ if(result)
+ return result;
+
+ result = Curl_http2_switched(conn, NULL, 0);
+ if(result)
+ return result;
+ break;
+ case CURL_HTTP_VERSION_1_1:
+ /* continue with HTTP/1.1 when explicitly requested */
+ break;
+ default:
+ /* and as fallback */
+ break;
+ }
+ }
+ else {
+ /* prepare for a http2 request */
+ result = Curl_http2_setup(conn);
+ if(result)
+ return result;
+ }
+
+ http = data->req.protop;
+
+ if(!data->state.this_is_a_follow) {
+ /* Free to avoid leaking memory on multiple requests*/
+ free(data->state.first_host);
+
+ data->state.first_host = strdup(conn->host.name);
+ if(!data->state.first_host)
+ return CURLE_OUT_OF_MEMORY;
+ }
+ http->writebytecount = http->readbytecount = 0;
+
+ if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) &&
+ data->set.upload) {
+ httpreq = HTTPREQ_PUT;
+ }
+
+ /* Now set the 'request' pointer to the proper request string */
+ if(data->set.str[STRING_CUSTOMREQUEST])
+ request = data->set.str[STRING_CUSTOMREQUEST];
+ else {
+ if(data->set.opt_no_body)
+ request = "HEAD";
+ else {
+ DEBUGASSERT((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST));
+ switch(httpreq) {
+ case HTTPREQ_POST:
+ case HTTPREQ_POST_FORM:
+ request = "POST";
+ break;
+ case HTTPREQ_PUT:
+ request = "PUT";
+ break;
+ default: /* this should never happen */
+ case HTTPREQ_GET:
+ request = "GET";
+ break;
+ case HTTPREQ_HEAD:
+ request = "HEAD";
+ break;
+ }
+ }
+ }
+
+ /* The User-Agent string might have been allocated in url.c already, because
+ it might have been used in the proxy connect, but if we have got a header
+ with the user-agent string specified, we erase the previously made string
+ here. */
+ if(Curl_checkheaders(conn, "User-Agent:")) {
+ free(conn->allocptr.uagent);
+ conn->allocptr.uagent=NULL;
+ }
+
+ /* setup the authentication headers */
+ result = Curl_http_output_auth(conn, request, ppath, FALSE);
+ if(result)
+ return result;
+
+ if((data->state.authhost.multi || data->state.authproxy.multi) &&
+ (httpreq != HTTPREQ_GET) &&
+ (httpreq != HTTPREQ_HEAD)) {
+ /* Auth is required and we are not authenticated yet. Make a PUT or POST
+ with content-length zero as a "probe". */
+ conn->bits.authneg = TRUE;
+ }
+ else
+ conn->bits.authneg = FALSE;
+
+ Curl_safefree(conn->allocptr.ref);
+ if(data->change.referer && !Curl_checkheaders(conn, "Referer:")) {
+ conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
+ if(!conn->allocptr.ref)
+ return CURLE_OUT_OF_MEMORY;
+ }
+ else
+ conn->allocptr.ref = NULL;
+
+#if !defined(CURL_DISABLE_COOKIES)
+ if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(conn, "Cookie:"))
+ addcookies = data->set.str[STRING_COOKIE];
+#endif
+
+ if(!Curl_checkheaders(conn, "Accept-Encoding:") &&
+ data->set.str[STRING_ENCODING]) {
+ Curl_safefree(conn->allocptr.accept_encoding);
+ conn->allocptr.accept_encoding =
+ aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
+ if(!conn->allocptr.accept_encoding)
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+#ifdef HAVE_LIBZ
+ /* we only consider transfer-encoding magic if libz support is built-in */
+
+ if(!Curl_checkheaders(conn, "TE:") &&
+ data->set.http_transfer_encoding) {
+ /* When we are to insert a TE: header in the request, we must also insert
+ TE in a Connection: header, so we need to merge the custom provided
+ Connection: header and prevent the original to get sent. Note that if
+ the user has inserted his/hers own TE: header we don't do this magic
+ but then assume that the user will handle it all! */
+ char *cptr = Curl_checkheaders(conn, "Connection:");
+#define TE_HEADER "TE: gzip\r\n"
+
+ Curl_safefree(conn->allocptr.te);
+
+ /* Create the (updated) Connection: header */
+ conn->allocptr.te = cptr? aprintf("%s, TE\r\n" TE_HEADER, cptr):
+ strdup("Connection: TE\r\n" TE_HEADER);
+
+ if(!conn->allocptr.te)
+ return CURLE_OUT_OF_MEMORY;
+ }
+#endif
+
+ if(conn->httpversion == 20)
+ /* In HTTP2 forbids Transfer-Encoding: chunked */
+ ptr = NULL;
+ else {
+ ptr = Curl_checkheaders(conn, "Transfer-Encoding:");
+ if(ptr) {
+ /* Some kind of TE is requested, check if 'chunked' is chosen */
+ data->req.upload_chunky =
+ Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
+ }
+ else {
+ if((conn->handler->protocol&PROTO_FAMILY_HTTP) &&
+ data->set.upload &&
+ (data->state.infilesize == -1)) {
+ if(conn->bits.authneg)
+ /* don't enable chunked during auth neg */
+ ;
+ else if(use_http_1_1plus(data, conn)) {
+ /* HTTP, upload, unknown file size and not HTTP 1.0 */
+ data->req.upload_chunky = TRUE;
+ }
+ else {
+ failf(data, "Chunky upload is not supported by HTTP 1.0");
+ return CURLE_UPLOAD_FAILED;
+ }
+ }
+ else {
+ /* else, no chunky upload */
+ data->req.upload_chunky = FALSE;
+ }
+
+ if(data->req.upload_chunky)
+ te = "Transfer-Encoding: chunked\r\n";
+ }
+ }
+
+ Curl_safefree(conn->allocptr.host);
+
+ ptr = Curl_checkheaders(conn, "Host:");
+ if(ptr && (!data->state.this_is_a_follow ||
+ Curl_raw_equal(data->state.first_host, conn->host.name))) {
+#if !defined(CURL_DISABLE_COOKIES)
+ /* If we have a given custom Host: header, we extract the host name in
+ order to possibly use it for cookie reasons later on. We only allow the
+ custom Host: header if this is NOT a redirect, as setting Host: in the
+ redirected request is being out on thin ice. Except if the host name
+ is the same as the first one! */
+ char *cookiehost = Curl_copy_header_value(ptr);
+ if(!cookiehost)
+ return CURLE_OUT_OF_MEMORY;
+ if(!*cookiehost)
+ /* ignore empty data */
+ free(cookiehost);
+ else {
+ /* If the host begins with '[', we start searching for the port after
+ the bracket has been closed */
+ int startsearch = 0;
+ if(*cookiehost == '[') {
+ char *closingbracket;
+ /* since the 'cookiehost' is an allocated memory area that will be
+ freed later we cannot simply increment the pointer */
+ memmove(cookiehost, cookiehost + 1, strlen(cookiehost) - 1);
+ closingbracket = strchr(cookiehost, ']');
+ if(closingbracket)
+ *closingbracket = 0;
+ }
+ else {
+ char *colon = strchr(cookiehost + startsearch, ':');
+ if(colon)
+ *colon = 0; /* The host must not include an embedded port number */
+ }
+ Curl_safefree(conn->allocptr.cookiehost);
+ conn->allocptr.cookiehost = cookiehost;
+ }
+#endif
+
+ if(strcmp("Host:", ptr)) {
+ conn->allocptr.host = aprintf("%s\r\n", ptr);
+ if(!conn->allocptr.host)
+ return CURLE_OUT_OF_MEMORY;
+ }
+ else
+ /* when clearing the header */
+ conn->allocptr.host = NULL;
+ }
+ else {
+ /* When building Host: headers, we must put the host name within
+ [brackets] if the host name is a plain IPv6-address. RFC2732-style. */
+
+ if(((conn->given->protocol&CURLPROTO_HTTPS) &&
+ (conn->remote_port == PORT_HTTPS)) ||
+ ((conn->given->protocol&CURLPROTO_HTTP) &&
+ (conn->remote_port == PORT_HTTP)) )
+ /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include
+ the port number in the host string */
+ conn->allocptr.host = aprintf("Host: %s%s%s\r\n",
+ conn->bits.ipv6_ip?"[":"",
+ host,
+ conn->bits.ipv6_ip?"]":"");
+ else
+ conn->allocptr.host = aprintf("Host: %s%s%s:%hu\r\n",
+ conn->bits.ipv6_ip?"[":"",
+ host,
+ conn->bits.ipv6_ip?"]":"",
+ conn->remote_port);
+
+ if(!conn->allocptr.host)
+ /* without Host: we can't make a nice request */
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+#ifndef CURL_DISABLE_PROXY
+ if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
+ /* Using a proxy but does not tunnel through it */
+
+ /* The path sent to the proxy is in fact the entire URL. But if the remote
+ host is a IDN-name, we must make sure that the request we produce only
+ uses the encoded host name! */
+ if(conn->host.dispname != conn->host.name) {
+ char *url = data->change.url;
+ ptr = strstr(url, conn->host.dispname);
+ if(ptr) {
+ /* This is where the display name starts in the URL, now replace this
+ part with the encoded name. TODO: This method of replacing the host
+ name is rather crude as I believe there's a slight risk that the
+ user has entered a user name or password that contain the host name
+ string. */
+ size_t currlen = strlen(conn->host.dispname);
+ size_t newlen = strlen(conn->host.name);
+ size_t urllen = strlen(url);
+
+ char *newurl;
+
+ newurl = malloc(urllen + newlen - currlen + 1);
+ if(newurl) {
+ /* copy the part before the host name */
+ memcpy(newurl, url, ptr - url);
+ /* append the new host name instead of the old */
+ memcpy(newurl + (ptr - url), conn->host.name, newlen);
+ /* append the piece after the host name */
+ memcpy(newurl + newlen + (ptr - url),
+ ptr + currlen, /* copy the trailing zero byte too */
+ urllen - (ptr-url) - currlen + 1);
+ if(data->change.url_alloc) {
+ Curl_safefree(data->change.url);
+ data->change.url_alloc = FALSE;
+ }
+ data->change.url = newurl;
+ data->change.url_alloc = TRUE;
+ }
+ else
+ return CURLE_OUT_OF_MEMORY;
+ }
+ }
+ ppath = data->change.url;
+ if(checkprefix("ftp://", ppath)) {
+ if(data->set.proxy_transfer_mode) {
+ /* when doing ftp, append ;type=<a|i> if not present */
+ char *type = strstr(ppath, ";type=");
+ if(type && type[6] && type[7] == 0) {
+ switch (Curl_raw_toupper(type[6])) {
+ case 'A':
+ case 'D':
+ case 'I':
+ break;
+ default:
+ type = NULL;
+ }
+ }
+ if(!type) {
+ char *p = ftp_typecode;
+ /* avoid sending invalid URLs like ftp://example.com;type=i if the
+ * user specified ftp://example.com without the slash */
+ if(!*data->state.path && ppath[strlen(ppath) - 1] != '/') {
+ *p++ = '/';
+ }
+ snprintf(p, sizeof(ftp_typecode) - 1, ";type=%c",
+ data->set.prefer_ascii ? 'a' : 'i');
+ }
+ }
+ if(conn->bits.user_passwd && !conn->bits.userpwd_in_url)
+ paste_ftp_userpwd = TRUE;
+ }
+ }
+#endif /* CURL_DISABLE_PROXY */
+
+ if(HTTPREQ_POST_FORM == httpreq) {
+ /* we must build the whole post sequence first, so that we have a size of
+ the whole transfer before we start to send it */
+ result = Curl_getformdata(data, &http->sendit, data->set.httppost,
+ Curl_checkheaders(conn, "Content-Type:"),
+ &http->postsize);
+ if(result)
+ return result;
+ }
+
+ http->p_accept = Curl_checkheaders(conn, "Accept:")?NULL:"Accept: */*\r\n";
+
+ if(( (HTTPREQ_POST == httpreq) ||
+ (HTTPREQ_POST_FORM == httpreq) ||
+ (HTTPREQ_PUT == httpreq) ) &&
+ data->state.resume_from) {
+ /**********************************************************************
+ * Resuming upload in HTTP means that we PUT or POST and that we have
+ * got a resume_from value set. The resume value has already created
+ * a Range: header that will be passed along. We need to "fast forward"
+ * the file the given number of bytes and decrease the assume upload
+ * file size before we continue this venture in the dark lands of HTTP.
+ *********************************************************************/
+
+ if(data->state.resume_from < 0 ) {
+ /*
+ * This is meant to get the size of the present remote-file by itself.
+ * We don't support this now. Bail out!
+ */
+ data->state.resume_from = 0;
+ }
+
+ if(data->state.resume_from && !data->state.this_is_a_follow) {
+ /* do we still game? */
+
+ /* Now, let's read off the proper amount of bytes from the
+ input. */
+ if(conn->seek_func) {
+ seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
+ SEEK_SET);
+ }
+
+ if(seekerr != CURL_SEEKFUNC_OK) {
+ if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
+ failf(data, "Could not seek stream");
+ return CURLE_READ_ERROR;
+ }
+ /* when seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
+ else {
+ curl_off_t passed=0;
+ do {
+ size_t readthisamountnow =
+ (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
+ BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
+
+ size_t actuallyread =
+ data->set.fread_func(data->state.buffer, 1, readthisamountnow,
+ data->set.in);
+
+ passed += actuallyread;
+ if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
+ /* this checks for greater-than only to make sure that the
+ CURL_READFUNC_ABORT return code still aborts */
+ failf(data, "Could only read %" CURL_FORMAT_CURL_OFF_T
+ " bytes from the input", passed);
+ return CURLE_READ_ERROR;
+ }
+ } while(passed < data->state.resume_from);
+ }
+ }
+
+ /* now, decrease the size of the read */
+ if(data->state.infilesize>0) {
+ data->state.infilesize -= data->state.resume_from;
+
+ if(data->state.infilesize <= 0) {
+ failf(data, "File already completely uploaded");
+ return CURLE_PARTIAL_FILE;
+ }
+ }
+ /* we've passed, proceed as normal */
+ }
+ }
+ if(data->state.use_range) {
+ /*
+ * A range is selected. We use different headers whether we're downloading
+ * or uploading and we always let customized headers override our internal
+ * ones if any such are specified.
+ */
+ if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
+ !Curl_checkheaders(conn, "Range:")) {
+ /* if a line like this was already allocated, free the previous one */
+ free(conn->allocptr.rangeline);
+ conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n",
+ data->state.range);
+ }
+ else if((httpreq != HTTPREQ_GET) &&
+ !Curl_checkheaders(conn, "Content-Range:")) {
+
+ /* if a line like this was already allocated, free the previous one */
+ free(conn->allocptr.rangeline);
+
+ if(data->set.set_resume_from < 0) {
+ /* Upload resume was asked for, but we don't know the size of the
+ remote part so we tell the server (and act accordingly) that we
+ upload the whole file (again) */
+ conn->allocptr.rangeline =
+ aprintf("Content-Range: bytes 0-%" CURL_FORMAT_CURL_OFF_T
+ "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
+ data->state.infilesize - 1, data->state.infilesize);
+
+ }
+ else if(data->state.resume_from) {
+ /* This is because "resume" was selected */
+ curl_off_t total_expected_size=
+ data->state.resume_from + data->state.infilesize;
+ conn->allocptr.rangeline =
+ aprintf("Content-Range: bytes %s%" CURL_FORMAT_CURL_OFF_T
+ "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
+ data->state.range, total_expected_size-1,
+ total_expected_size);
+ }
+ else {
+ /* Range was selected and then we just pass the incoming range and
+ append total size */
+ conn->allocptr.rangeline =
+ aprintf("Content-Range: bytes %s/%" CURL_FORMAT_CURL_OFF_T "\r\n",
+ data->state.range, data->state.infilesize);
+ }
+ if(!conn->allocptr.rangeline)
+ return CURLE_OUT_OF_MEMORY;
+ }
+ }
+
+ /* Use 1.1 unless the user specifically asked for 1.0 or the server only
+ supports 1.0 */
+ httpstring= use_http_1_1plus(data, conn)?"1.1":"1.0";
+
+ /* initialize a dynamic send-buffer */
+ req_buffer = Curl_add_buffer_init();
+
+ if(!req_buffer)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* add the main request stuff */
+ /* GET/HEAD/POST/PUT */
+ result = Curl_add_bufferf(req_buffer, "%s ", request);
+ if(result)
+ return result;
+
+ /* url */
+ if(paste_ftp_userpwd)
+ result = Curl_add_bufferf(req_buffer, "ftp://%s:%s@%s",
+ conn->user, conn->passwd,
+ ppath + sizeof("ftp://") - 1);
+ else
+ result = Curl_add_buffer(req_buffer, ppath, strlen(ppath));
+ if(result)
+ return result;
+
+ result =
+ Curl_add_bufferf(req_buffer,
+ "%s" /* ftp typecode (;type=x) */
+ " HTTP/%s\r\n" /* HTTP version */
+ "%s" /* host */
+ "%s" /* proxyuserpwd */
+ "%s" /* userpwd */
+ "%s" /* range */
+ "%s" /* user agent */
+ "%s" /* accept */
+ "%s" /* TE: */
+ "%s" /* accept-encoding */
+ "%s" /* referer */
+ "%s" /* Proxy-Connection */
+ "%s",/* transfer-encoding */
+
+ ftp_typecode,
+ httpstring,
+ (conn->allocptr.host?conn->allocptr.host:""),
+ conn->allocptr.proxyuserpwd?
+ conn->allocptr.proxyuserpwd:"",
+ conn->allocptr.userpwd?conn->allocptr.userpwd:"",
+ (data->state.use_range && conn->allocptr.rangeline)?
+ conn->allocptr.rangeline:"",
+ (data->set.str[STRING_USERAGENT] &&
+ *data->set.str[STRING_USERAGENT] &&
+ conn->allocptr.uagent)?
+ conn->allocptr.uagent:"",
+ http->p_accept?http->p_accept:"",
+ conn->allocptr.te?conn->allocptr.te:"",
+ (data->set.str[STRING_ENCODING] &&
+ *data->set.str[STRING_ENCODING] &&
+ conn->allocptr.accept_encoding)?
+ conn->allocptr.accept_encoding:"",
+ (data->change.referer && conn->allocptr.ref)?
+ conn->allocptr.ref:"" /* Referer: <data> */,
+ (conn->bits.httpproxy &&
+ !conn->bits.tunnel_proxy &&
+ !Curl_checkProxyheaders(conn, "Proxy-Connection:"))?
+ "Proxy-Connection: Keep-Alive\r\n":"",
+ te
+ );
+
+ /* clear userpwd to avoid re-using credentials from re-used connections */
+ Curl_safefree(conn->allocptr.userpwd);
+
+ /*
+ * Free proxyuserpwd for Negotiate/NTLM. Cannot reuse as it is associated
+ * with the connection and shouldn't be repeated over it either.
+ */
+ switch (data->state.authproxy.picked) {
+ case CURLAUTH_NEGOTIATE:
+ case CURLAUTH_NTLM:
+ case CURLAUTH_NTLM_WB:
+ Curl_safefree(conn->allocptr.proxyuserpwd);
+ break;
+ }
+
+ if(result)
+ return result;
+
+ if(!(conn->handler->flags&PROTOPT_SSL) &&
+ conn->httpversion != 20 &&
+ (data->set.httpversion == CURL_HTTP_VERSION_2_0)) {
+ /* append HTTP2 upgrade magic stuff to the HTTP request if it isn't done
+ over SSL */
+ result = Curl_http2_request_upgrade(req_buffer, conn);
+ if(result)
+ return result;
+ }
+
+#if !defined(CURL_DISABLE_COOKIES)
+ if(data->cookies || addcookies) {
+ struct Cookie *co=NULL; /* no cookies from start */
+ int count=0;
+
+ if(data->cookies) {
+ Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
+ co = Curl_cookie_getlist(data->cookies,
+ conn->allocptr.cookiehost?
+ conn->allocptr.cookiehost:host,
+ data->state.path,
+ (conn->handler->protocol&CURLPROTO_HTTPS)?
+ TRUE:FALSE);
+ Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
+ }
+ if(co) {
+ struct Cookie *store=co;
+ /* now loop through all cookies that matched */
+ while(co) {
+ if(co->value) {
+ if(0 == count) {
+ result = Curl_add_bufferf(req_buffer, "Cookie: ");
+ if(result)
+ break;
+ }
+ result = Curl_add_bufferf(req_buffer,
+ "%s%s=%s", count?"; ":"",
+ co->name, co->value);
+ if(result)
+ break;
+ count++;
+ }
+ co = co->next; /* next cookie please */
+ }
+ Curl_cookie_freelist(store, FALSE); /* free the cookie list */
+ }
+ if(addcookies && !result) {
+ if(!count)
+ result = Curl_add_bufferf(req_buffer, "Cookie: ");
+ if(!result) {
+ result = Curl_add_bufferf(req_buffer, "%s%s", count?"; ":"",
+ addcookies);
+ count++;
+ }
+ }
+ if(count && !result)
+ result = Curl_add_buffer(req_buffer, "\r\n", 2);
+
+ if(result)
+ return result;
+ }
+#endif
+
+ if(data->set.timecondition) {
+ result = Curl_add_timecondition(data, req_buffer);
+ if(result)
+ return result;
+ }
+
+ result = Curl_add_custom_headers(conn, FALSE, req_buffer);
+ if(result)
+ return result;
+
+ http->postdata = NULL; /* nothing to post at this point */
+ Curl_pgrsSetUploadSize(data, -1); /* upload size is unknown atm */
+
+ /* If 'authdone' is FALSE, we must not set the write socket index to the
+ Curl_transfer() call below, as we're not ready to actually upload any
+ data yet. */
+
+ switch(httpreq) {
+
+ case HTTPREQ_POST_FORM:
+ if(!http->sendit || conn->bits.authneg) {
+ /* nothing to post! */
+ result = Curl_add_bufferf(req_buffer, "Content-Length: 0\r\n\r\n");
+ if(result)
+ return result;
+
+ result = Curl_add_buffer_send(req_buffer, conn,
+ &data->info.request_size, 0, FIRSTSOCKET);
+ if(result)
+ failf(data, "Failed sending POST request");
+ else
+ /* setup variables for the upcoming transfer */
+ Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
+ -1, NULL);
+ break;
+ }
+
+ if(Curl_FormInit(&http->form, http->sendit)) {
+ failf(data, "Internal HTTP POST error!");
+ return CURLE_HTTP_POST_ERROR;
+ }
+
+ /* Get the currently set callback function pointer and store that in the
+ form struct since we might want the actual user-provided callback later
+ on. The data->set.fread_func pointer itself will be changed for the
+ multipart case to the function that returns a multipart formatted
+ stream. */
+ http->form.fread_func = data->set.fread_func;
+
+ /* Set the read function to read from the generated form data */
+ data->set.fread_func = (curl_read_callback)Curl_FormReader;
+ data->set.in = &http->form;
+
+ http->sending = HTTPSEND_BODY;
+
+ if(!data->req.upload_chunky &&
+ !Curl_checkheaders(conn, "Content-Length:")) {
+ /* only add Content-Length if not uploading chunked */
+ result = Curl_add_bufferf(req_buffer,
+ "Content-Length: %" CURL_FORMAT_CURL_OFF_T
+ "\r\n", http->postsize);
+ if(result)
+ return result;
+ }
+
+ result = expect100(data, conn, req_buffer);
+ if(result)
+ return result;
+
+ {
+
+ /* Get Content-Type: line from Curl_formpostheader.
+ */
+ char *contentType;
+ size_t linelength=0;
+ contentType = Curl_formpostheader((void *)&http->form,
+ &linelength);
+ if(!contentType) {
+ failf(data, "Could not get Content-Type header line!");
+ return CURLE_HTTP_POST_ERROR;
+ }
+
+ result = Curl_add_buffer(req_buffer, contentType, linelength);
+ if(result)
+ return result;
+ }
+
+ /* make the request end in a true CRLF */
+ result = Curl_add_buffer(req_buffer, "\r\n", 2);
+ if(result)
+ return result;
+
+ /* set upload size to the progress meter */
+ Curl_pgrsSetUploadSize(data, http->postsize);
+
+ /* fire away the whole request to the server */
+ result = Curl_add_buffer_send(req_buffer, conn,
+ &data->info.request_size, 0, FIRSTSOCKET);
+ if(result)
+ failf(data, "Failed sending POST request");
+ else
+ /* setup variables for the upcoming transfer */
+ Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
+ &http->readbytecount, FIRSTSOCKET,
+ &http->writebytecount);
+
+ if(result) {
+ Curl_formclean(&http->sendit); /* free that whole lot */
+ return result;
+ }
+
+ /* convert the form data */
+ result = Curl_convert_form(data, http->sendit);
+ if(result) {
+ Curl_formclean(&http->sendit); /* free that whole lot */
+ return result;
+ }
+
+ break;
+
+ case HTTPREQ_PUT: /* Let's PUT the data to the server! */
+
+ if(conn->bits.authneg)
+ postsize = 0;
+ else
+ postsize = data->state.infilesize;
+
+ if((postsize != -1) && !data->req.upload_chunky &&
+ !Curl_checkheaders(conn, "Content-Length:")) {
+ /* only add Content-Length if not uploading chunked */
+ result = Curl_add_bufferf(req_buffer,
+ "Content-Length: %" CURL_FORMAT_CURL_OFF_T
+ "\r\n", postsize);
+ if(result)
+ return result;
+ }
+
+ if(postsize != 0) {
+ result = expect100(data, conn, req_buffer);
+ if(result)
+ return result;
+ }
+
+ result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers */
+ if(result)
+ return result;
+
+ /* set the upload size to the progress meter */
+ Curl_pgrsSetUploadSize(data, postsize);
+
+ /* this sends the buffer and frees all the buffer resources */
+ result = Curl_add_buffer_send(req_buffer, conn,
+ &data->info.request_size, 0, FIRSTSOCKET);
+ if(result)
+ failf(data, "Failed sending PUT request");
+ else
+ /* prepare for transfer */
+ Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
+ &http->readbytecount, postsize?FIRSTSOCKET:-1,
+ postsize?&http->writebytecount:NULL);
+ if(result)
+ return result;
+ break;
+
+ case HTTPREQ_POST:
+ /* this is the simple POST, using x-www-form-urlencoded style */
+
+ if(conn->bits.authneg)
+ postsize = 0;
+ else {
+ /* figure out the size of the postfields */
+ postsize = (data->state.infilesize != -1)?
+ data->state.infilesize:
+ (data->set.postfields? (curl_off_t)strlen(data->set.postfields):-1);
+ }
+
+ /* We only set Content-Length and allow a custom Content-Length if
+ we don't upload data chunked, as RFC2616 forbids us to set both
+ kinds of headers (Transfer-Encoding: chunked and Content-Length) */
+ if((postsize != -1) && !data->req.upload_chunky &&
+ !Curl_checkheaders(conn, "Content-Length:")) {
+ /* we allow replacing this header if not during auth negotiation,
+ although it isn't very wise to actually set your own */
+ result = Curl_add_bufferf(req_buffer,
+ "Content-Length: %" CURL_FORMAT_CURL_OFF_T
+ "\r\n", postsize);
+ if(result)
+ return result;
+ }
+
+ if(!Curl_checkheaders(conn, "Content-Type:")) {
+ result = Curl_add_bufferf(req_buffer,
+ "Content-Type: application/"
+ "x-www-form-urlencoded\r\n");
+ if(result)
+ return result;
+ }
+
+ /* For really small posts we don't use Expect: headers at all, and for
+ the somewhat bigger ones we allow the app to disable it. Just make
+ sure that the expect100header is always set to the preferred value
+ here. */
+ ptr = Curl_checkheaders(conn, "Expect:");
+ if(ptr) {
+ data->state.expect100header =
+ Curl_compareheader(ptr, "Expect:", "100-continue");
+ }
+ else if(postsize > TINY_INITIAL_POST_SIZE || postsize < 0) {
+ result = expect100(data, conn, req_buffer);
+ if(result)
+ return result;
+ }
+ else
+ data->state.expect100header = FALSE;
+
+ if(data->set.postfields) {
+
+ /* In HTTP2, we send request body in DATA frame regardless of
+ its size. */
+ if(conn->httpversion != 20 &&
+ !data->state.expect100header &&
+ (postsize < MAX_INITIAL_POST_SIZE)) {
+ /* if we don't use expect: 100 AND
+ postsize is less than MAX_INITIAL_POST_SIZE
+
+ then append the post data to the HTTP request header. This limit
+ is no magic limit but only set to prevent really huge POSTs to
+ get the data duplicated with malloc() and family. */
+
+ result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
+ if(result)
+ return result;
+
+ if(!data->req.upload_chunky) {
+ /* We're not sending it 'chunked', append it to the request
+ already now to reduce the number if send() calls */
+ result = Curl_add_buffer(req_buffer, data->set.postfields,
+ (size_t)postsize);
+ included_body = postsize;
+ }
+ else {
+ if(postsize) {
+ /* Append the POST data chunky-style */
+ result = Curl_add_bufferf(req_buffer, "%x\r\n", (int)postsize);
+ if(!result) {
+ result = Curl_add_buffer(req_buffer, data->set.postfields,
+ (size_t)postsize);
+ if(!result)
+ result = Curl_add_buffer(req_buffer, "\r\n", 2);
+ included_body = postsize + 2;
+ }
+ }
+ if(!result)
+ result = Curl_add_buffer(req_buffer, "\x30\x0d\x0a\x0d\x0a", 5);
+ /* 0 CR LF CR LF */
+ included_body += 5;
+ }
+ if(result)
+ return result;
+ /* Make sure the progress information is accurate */
+ Curl_pgrsSetUploadSize(data, postsize);
+ }
+ else {
+ /* A huge POST coming up, do data separate from the request */
+ http->postsize = postsize;
+ http->postdata = data->set.postfields;
+
+ http->sending = HTTPSEND_BODY;
+
+ data->set.fread_func = (curl_read_callback)readmoredata;
+ data->set.in = (void *)conn;
+
+ /* set the upload size to the progress meter */
+ Curl_pgrsSetUploadSize(data, http->postsize);
+
+ result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
+ if(result)
+ return result;
+ }
+ }
+ else {
+ result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
+ if(result)
+ return result;
+
+ if(data->req.upload_chunky && conn->bits.authneg) {
+ /* Chunky upload is selected and we're negotiating auth still, send
+ end-of-data only */
+ result = Curl_add_buffer(req_buffer,
+ "\x30\x0d\x0a\x0d\x0a", 5);
+ /* 0 CR LF CR LF */
+ if(result)
+ return result;
+ }
+
+ else if(data->state.infilesize) {
+ /* set the upload size to the progress meter */
+ Curl_pgrsSetUploadSize(data, postsize?postsize:-1);
+
+ /* set the pointer to mark that we will send the post body using the
+ read callback, but only if we're not in authenticate
+ negotiation */
+ if(!conn->bits.authneg) {
+ http->postdata = (char *)&http->postdata;
+ http->postsize = postsize;
+ }
+ }
+ }
+ /* issue the request */
+ result = Curl_add_buffer_send(req_buffer, conn, &data->info.request_size,
+ (size_t)included_body, FIRSTSOCKET);
+
+ if(result)
+ failf(data, "Failed sending HTTP POST request");
+ else
+ Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
+ &http->readbytecount, http->postdata?FIRSTSOCKET:-1,
+ http->postdata?&http->writebytecount:NULL);
+ break;
+
+ default:
+ result = Curl_add_buffer(req_buffer, "\r\n", 2);
+ if(result)
+ return result;
+
+ /* issue the request */
+ result = Curl_add_buffer_send(req_buffer, conn,
+ &data->info.request_size, 0, FIRSTSOCKET);
+
+ if(result)
+ failf(data, "Failed sending HTTP request");
+ else
+ /* HTTP GET/HEAD download: */
+ Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
+ http->postdata?FIRSTSOCKET:-1,
+ http->postdata?&http->writebytecount:NULL);
+ }
+ if(result)
+ return result;
+
+ if(http->writebytecount) {
+ /* if a request-body has been sent off, we make sure this progress is noted
+ properly */
+ Curl_pgrsSetUploadCounter(data, http->writebytecount);
+ if(Curl_pgrsUpdate(conn))
+ result = CURLE_ABORTED_BY_CALLBACK;
+
+ if(http->writebytecount >= postsize) {
+ /* already sent the entire request body, mark the "upload" as
+ complete */
+ infof(data, "upload completely sent off: %" CURL_FORMAT_CURL_OFF_T
+ " out of %" CURL_FORMAT_CURL_OFF_T " bytes\n",
+ http->writebytecount, postsize);
+ data->req.upload_done = TRUE;
+ data->req.keepon &= ~KEEP_SEND; /* we're done writing */
+ data->req.exp100 = EXP100_SEND_DATA; /* already sent */
+ }
+ }
+
+ return result;
+}
+
+/*
+ * checkhttpprefix()
+ *
+ * Returns TRUE if member of the list matches prefix of string
+ */
+static bool
+checkhttpprefix(struct SessionHandle *data,
+ const char *s)
+{
+ struct curl_slist *head = data->set.http200aliases;
+ bool rc = FALSE;
+#ifdef CURL_DOES_CONVERSIONS
+ /* convert from the network encoding using a scratch area */
+ char *scratch = strdup(s);
+ if(NULL == scratch) {
+ failf (data, "Failed to allocate memory for conversion!");
+ return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
+ }
+ if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
+ /* Curl_convert_from_network calls failf if unsuccessful */
+ free(scratch);
+ return FALSE; /* can't return CURLE_foobar so return FALSE */
+ }
+ s = scratch;
+#endif /* CURL_DOES_CONVERSIONS */
+
+ while(head) {
+ if(checkprefix(head->data, s)) {
+ rc = TRUE;
+ break;
+ }
+ head = head->next;
+ }
+
+ if(!rc && (checkprefix("HTTP/", s)))
+ rc = TRUE;
+
+#ifdef CURL_DOES_CONVERSIONS
+ free(scratch);
+#endif /* CURL_DOES_CONVERSIONS */
+ return rc;
+}
+
+#ifndef CURL_DISABLE_RTSP
+static bool
+checkrtspprefix(struct SessionHandle *data,
+ const char *s)
+{
+
+#ifdef CURL_DOES_CONVERSIONS
+ /* convert from the network encoding using a scratch area */
+ char *scratch = strdup(s);
+ if(NULL == scratch) {
+ failf (data, "Failed to allocate memory for conversion!");
+ return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
+ }
+ if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
+ /* Curl_convert_from_network calls failf if unsuccessful */
+ free(scratch);
+ return FALSE; /* can't return CURLE_foobar so return FALSE */
+ }
+ s = scratch;
+#else
+ (void)data; /* unused */
+#endif /* CURL_DOES_CONVERSIONS */
+ if(checkprefix("RTSP/", s))
+ return TRUE;
+ else
+ return FALSE;
+}
+#endif /* CURL_DISABLE_RTSP */
+
+static bool
+checkprotoprefix(struct SessionHandle *data, struct connectdata *conn,
+ const char *s)
+{
+#ifndef CURL_DISABLE_RTSP
+ if(conn->handler->protocol & CURLPROTO_RTSP)
+ return checkrtspprefix(data, s);
+#else
+ (void)conn;
+#endif /* CURL_DISABLE_RTSP */
+
+ return checkhttpprefix(data, s);
+}
+
+/*
+ * header_append() copies a chunk of data to the end of the already received
+ * header. We make sure that the full string fit in the allocated header
+ * buffer, or else we enlarge it.
+ */
+static CURLcode header_append(struct SessionHandle *data,
+ struct SingleRequest *k,
+ size_t length)
+{
+ if(k->hbuflen + length >= data->state.headersize) {
+ /* We enlarge the header buffer as it is too small */
+ char *newbuff;
+ size_t hbufp_index;
+ size_t newsize;
+
+ if(k->hbuflen + length > CURL_MAX_HTTP_HEADER) {
+ /* The reason to have a max limit for this is to avoid the risk of a bad
+ server feeding libcurl with a never-ending header that will cause
+ reallocs infinitely */
+ failf (data, "Avoided giant realloc for header (max is %d)!",
+ CURL_MAX_HTTP_HEADER);
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ newsize=CURLMAX((k->hbuflen+ length)*3/2, data->state.headersize*2);
+ hbufp_index = k->hbufp - data->state.headerbuff;
+ newbuff = realloc(data->state.headerbuff, newsize);
+ if(!newbuff) {
+ failf (data, "Failed to alloc memory for big header!");
+ return CURLE_OUT_OF_MEMORY;
+ }
+ data->state.headersize=newsize;
+ data->state.headerbuff = newbuff;
+ k->hbufp = data->state.headerbuff + hbufp_index;
+ }
+ memcpy(k->hbufp, k->str_start, length);
+ k->hbufp += length;
+ k->hbuflen += length;
+ *k->hbufp = 0;
+
+ return CURLE_OK;
+}
+
+static void print_http_error(struct SessionHandle *data)
+{
+ struct SingleRequest *k = &data->req;
+ char *beg = k->p;
+
+ /* make sure that data->req.p points to the HTTP status line */
+ if(!strncmp(beg, "HTTP", 4)) {
+
+ /* skip to HTTP status code */
+ beg = strchr(beg, ' ');
+ if(beg && *++beg) {
+
+ /* find trailing CR */
+ char end_char = '\r';
+ char *end = strchr(beg, end_char);
+ if(!end) {
+ /* try to find LF (workaround for non-compliant HTTP servers) */
+ end_char = '\n';
+ end = strchr(beg, end_char);
+ }
+
+ if(end) {
+ /* temporarily replace CR or LF by NUL and print the error message */
+ *end = '\0';
+ failf(data, "The requested URL returned error: %s", beg);
+
+ /* restore the previously replaced CR or LF */
+ *end = end_char;
+ return;
+ }
+ }
+ }
+
+ /* fall-back to printing the HTTP status code only */
+ failf(data, "The requested URL returned error: %d", k->httpcode);
+}
+
+/*
+ * Read any HTTP header lines from the server and pass them to the client app.
+ */
+CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
+ struct connectdata *conn,
+ ssize_t *nread,
+ bool *stop_reading)
+{
+ CURLcode result;
+ struct SingleRequest *k = &data->req;
+
+ /* header line within buffer loop */
+ do {
+ size_t rest_length;
+ size_t full_length;
+ int writetype;
+
+ /* str_start is start of line within buf */
+ k->str_start = k->str;
+
+ /* data is in network encoding so use 0x0a instead of '\n' */
+ k->end_ptr = memchr(k->str_start, 0x0a, *nread);
+
+ if(!k->end_ptr) {
+ /* Not a complete header line within buffer, append the data to
+ the end of the headerbuff. */
+ result = header_append(data, k, *nread);
+ if(result)
+ return result;
+
+ if(!k->headerline && (k->hbuflen>5)) {
+ /* make a first check that this looks like a protocol header */
+ if(!checkprotoprefix(data, conn, data->state.headerbuff)) {
+ /* this is not the beginning of a protocol first header line */
+ k->header = FALSE;
+ k->badheader = HEADER_ALLBAD;
+ break;
+ }
+ }
+
+ break; /* read more and try again */
+ }
+
+ /* decrease the size of the remaining (supposed) header line */
+ rest_length = (k->end_ptr - k->str)+1;
+ *nread -= (ssize_t)rest_length;
+
+ k->str = k->end_ptr + 1; /* move past new line */
+
+ full_length = k->str - k->str_start;
+
+ result = header_append(data, k, full_length);
+ if(result)
+ return result;
+
+ k->end_ptr = k->hbufp;
+ k->p = data->state.headerbuff;
+
+ /****
+ * We now have a FULL header line that p points to
+ *****/
+
+ if(!k->headerline) {
+ /* the first read header */
+ if((k->hbuflen>5) &&
+ !checkprotoprefix(data, conn, data->state.headerbuff)) {
+ /* this is not the beginning of a protocol first header line */
+ k->header = FALSE;
+ if(*nread)
+ /* since there's more, this is a partial bad header */
+ k->badheader = HEADER_PARTHEADER;
+ else {
+ /* this was all we read so it's all a bad header */
+ k->badheader = HEADER_ALLBAD;
+ *nread = (ssize_t)rest_length;
+ }
+ break;
+ }
+ }
+
+ /* headers are in network encoding so
+ use 0x0a and 0x0d instead of '\n' and '\r' */
+ if((0x0a == *k->p) || (0x0d == *k->p)) {
+ size_t headerlen;
+ /* Zero-length header line means end of headers! */
+
+#ifdef CURL_DOES_CONVERSIONS
+ if(0x0d == *k->p) {
+ *k->p = '\r'; /* replace with CR in host encoding */
+ k->p++; /* pass the CR byte */
+ }
+ if(0x0a == *k->p) {
+ *k->p = '\n'; /* replace with LF in host encoding */
+ k->p++; /* pass the LF byte */
+ }
+#else
+ if('\r' == *k->p)
+ k->p++; /* pass the \r byte */
+ if('\n' == *k->p)
+ k->p++; /* pass the \n byte */
+#endif /* CURL_DOES_CONVERSIONS */
+
+ if(100 <= k->httpcode && 199 >= k->httpcode) {
+ /*
+ * We have made a HTTP PUT or POST and this is 1.1-lingo
+ * that tells us that the server is OK with this and ready
+ * to receive the data.
+ * However, we'll get more headers now so we must get
+ * back into the header-parsing state!
+ */
+ k->header = TRUE;
+ k->headerline = 0; /* restart the header line counter */
+
+ /* "A user agent MAY ignore unexpected 1xx status responses." */
+ switch(k->httpcode) {
+ case 100:
+ /* if we did wait for this do enable write now! */
+ if(k->exp100) {
+ k->exp100 = EXP100_SEND_DATA;
+ k->keepon |= KEEP_SEND;
+ }
+ break;
+ case 101:
+ /* Switching Protocols */
+ if(k->upgr101 == UPGR101_REQUESTED) {
+ infof(data, "Received 101\n");
+ k->upgr101 = UPGR101_RECEIVED;
+
+ /* switch to http2 now. The bytes after response headers
+ are also processed here, otherwise they are lost. */
+ result = Curl_http2_switched(conn, k->str, *nread);
+ if(result)
+ return result;
+ *nread = 0;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ else {
+ k->header = FALSE; /* no more header to parse! */
+
+ if((k->size == -1) && !k->chunk && !conn->bits.close &&
+ (conn->httpversion == 11) &&
+ !(conn->handler->protocol & CURLPROTO_RTSP) &&
+ data->set.httpreq != HTTPREQ_HEAD) {
+ /* On HTTP 1.1, when connection is not to get closed, but no
+ Content-Length nor Content-Encoding chunked have been
+ received, according to RFC2616 section 4.4 point 5, we
+ assume that the server will close the connection to
+ signal the end of the document. */
+ infof(data, "no chunk, no close, no size. Assume close to "
+ "signal end\n");
+ connclose(conn, "HTTP: No end-of-message indicator");
+ }
+ }
+
+ /* At this point we have some idea about the fate of the connection.
+ If we are closing the connection it may result auth failure. */
+#if defined(USE_NTLM)
+ if(conn->bits.close &&
+ (((data->req.httpcode == 401) &&
+ (conn->ntlm.state == NTLMSTATE_TYPE2)) ||
+ ((data->req.httpcode == 407) &&
+ (conn->proxyntlm.state == NTLMSTATE_TYPE2)))) {
+ infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
+ data->state.authproblem = TRUE;
+ }
+#endif
+
+ /*
+ * When all the headers have been parsed, see if we should give
+ * up and return an error.
+ */
+ if(http_should_fail(conn)) {
+ failf (data, "The requested URL returned error: %d",
+ k->httpcode);
+ return CURLE_HTTP_RETURNED_ERROR;
+ }
+
+ /* now, only output this if the header AND body are requested:
+ */
+ writetype = CLIENTWRITE_HEADER;
+ if(data->set.include_header)
+ writetype |= CLIENTWRITE_BODY;
+
+ headerlen = k->p - data->state.headerbuff;
+
+ result = Curl_client_write(conn, writetype,
+ data->state.headerbuff,
+ headerlen);
+ if(result)
+ return result;
+
+ data->info.header_size += (long)headerlen;
+ data->req.headerbytecount += (long)headerlen;
+
+ data->req.deductheadercount =
+ (100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0;
+
+ if(!*stop_reading) {
+ /* Curl_http_auth_act() checks what authentication methods
+ * that are available and decides which one (if any) to
+ * use. It will set 'newurl' if an auth method was picked. */
+ result = Curl_http_auth_act(conn);
+
+ if(result)
+ return result;
+
+ if(k->httpcode >= 300) {
+ if((!conn->bits.authneg) && !conn->bits.close &&
+ !conn->bits.rewindaftersend) {
+ /*
+ * General treatment of errors when about to send data. Including :
+ * "417 Expectation Failed", while waiting for 100-continue.
+ *
+ * The check for close above is done simply because of something
+ * else has already deemed the connection to get closed then
+ * something else should've considered the big picture and we
+ * avoid this check.
+ *
+ * rewindaftersend indicates that something has told libcurl to
+ * continue sending even if it gets discarded
+ */
+
+ switch(data->set.httpreq) {
+ case HTTPREQ_PUT:
+ case HTTPREQ_POST:
+ case HTTPREQ_POST_FORM:
+ /* We got an error response. If this happened before the whole
+ * request body has been sent we stop sending and mark the
+ * connection for closure after we've read the entire response.
+ */
+ if(!k->upload_done) {
+ infof(data, "HTTP error before end of send, stop sending\n");
+ connclose(conn, "Stop sending data before everything sent");
+ k->upload_done = TRUE;
+ k->keepon &= ~KEEP_SEND; /* don't send */
+ if(data->state.expect100header)
+ k->exp100 = EXP100_FAILED;
+ }
+ break;
+
+ default: /* default label present to avoid compiler warnings */
+ break;
+ }
+ }
+ }
+
+ if(conn->bits.rewindaftersend) {
+ /* We rewind after a complete send, so thus we continue
+ sending now */
+ infof(data, "Keep sending data to get tossed away!\n");
+ k->keepon |= KEEP_SEND;
+ }
+ }
+
+ if(!k->header) {
+ /*
+ * really end-of-headers.
+ *
+ * If we requested a "no body", this is a good time to get
+ * out and return home.
+ */
+ if(data->set.opt_no_body)
+ *stop_reading = TRUE;
+ else {
+ /* If we know the expected size of this document, we set the
+ maximum download size to the size of the expected
+ document or else, we won't know when to stop reading!
+
+ Note that we set the download maximum even if we read a
+ "Connection: close" header, to make sure that
+ "Content-Length: 0" still prevents us from attempting to
+ read the (missing) response-body.
+ */
+ /* According to RFC2616 section 4.4, we MUST ignore
+ Content-Length: headers if we are now receiving data
+ using chunked Transfer-Encoding.
+ */
+ if(k->chunk)
+ k->maxdownload = k->size = -1;
+ }
+ if(-1 != k->size) {
+ /* We do this operation even if no_body is true, since this
+ data might be retrieved later with curl_easy_getinfo()
+ and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
+
+ Curl_pgrsSetDownloadSize(data, k->size);
+ k->maxdownload = k->size;
+ }
+
+ /* If max download size is *zero* (nothing) we already
+ have nothing and can safely return ok now! */
+ if(0 == k->maxdownload)
+ *stop_reading = TRUE;
+
+ if(*stop_reading) {
+ /* we make sure that this socket isn't read more now */
+ k->keepon &= ~KEEP_RECV;
+ }
+
+ if(data->set.verbose)
+ Curl_debug(data, CURLINFO_HEADER_IN,
+ k->str_start, headerlen, conn);
+ break; /* exit header line loop */
+ }
+
+ /* We continue reading headers, so reset the line-based
+ header parsing variables hbufp && hbuflen */
+ k->hbufp = data->state.headerbuff;
+ k->hbuflen = 0;
+ continue;
+ }
+
+ /*
+ * Checks for special headers coming up.
+ */
+
+ if(!k->headerline++) {
+ /* This is the first header, it MUST be the error code line
+ or else we consider this to be the body right away! */
+ int httpversion_major;
+ int rtspversion_major;
+ int nc = 0;
+#ifdef CURL_DOES_CONVERSIONS
+#define HEADER1 scratch
+#define SCRATCHSIZE 21
+ CURLcode res;
+ char scratch[SCRATCHSIZE+1]; /* "HTTP/major.minor 123" */
+ /* We can't really convert this yet because we
+ don't know if it's the 1st header line or the body.
+ So we do a partial conversion into a scratch area,
+ leaving the data at k->p as-is.
+ */
+ strncpy(&scratch[0], k->p, SCRATCHSIZE);
+ scratch[SCRATCHSIZE] = 0; /* null terminate */
+ res = Curl_convert_from_network(data,
+ &scratch[0],
+ SCRATCHSIZE);
+ if(res)
+ /* Curl_convert_from_network calls failf if unsuccessful */
+ return res;
+#else
+#define HEADER1 k->p /* no conversion needed, just use k->p */
+#endif /* CURL_DOES_CONVERSIONS */
+
+ if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
+ /*
+ * https://tools.ietf.org/html/rfc7230#section-3.1.2
+ *
+ * The reponse code is always a three-digit number in HTTP as the spec
+ * says. We try to allow any number here, but we cannot make
+ * guarantees on future behaviors since it isn't within the protocol.
+ */
+ nc = sscanf(HEADER1,
+ " HTTP/%d.%d %d",
+ &httpversion_major,
+ &conn->httpversion,
+ &k->httpcode);
+ if(nc==3) {
+ conn->httpversion += 10 * httpversion_major;
+
+ if(k->upgr101 == UPGR101_RECEIVED) {
+ /* supposedly upgraded to http2 now */
+ if(conn->httpversion != 20)
+ infof(data, "Lying server, not serving HTTP/2\n");
+ }
+ }
+ else {
+ /* this is the real world, not a Nirvana
+ NCSA 1.5.x returns this crap when asked for HTTP/1.1
+ */
+ nc=sscanf(HEADER1, " HTTP %3d", &k->httpcode);
+ conn->httpversion = 10;
+
+ /* If user has set option HTTP200ALIASES,
+ compare header line against list of aliases
+ */
+ if(!nc) {
+ if(checkhttpprefix(data, k->p)) {
+ nc = 1;
+ k->httpcode = 200;
+ conn->httpversion = 10;
+ }
+ }
+ }
+ }
+ else if(conn->handler->protocol & CURLPROTO_RTSP) {
+ nc = sscanf(HEADER1,
+ " RTSP/%d.%d %3d",
+ &rtspversion_major,
+ &conn->rtspversion,
+ &k->httpcode);
+ if(nc==3) {
+ conn->rtspversion += 10 * rtspversion_major;
+ conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */
+ }
+ else {
+ /* TODO: do we care about the other cases here? */
+ nc = 0;
+ }
+ }
+
+ if(nc) {
+ data->info.httpcode = k->httpcode;
+
+ data->info.httpversion = conn->httpversion;
+ if(!data->state.httpversion ||
+ data->state.httpversion > conn->httpversion)
+ /* store the lowest server version we encounter */
+ data->state.httpversion = conn->httpversion;
+
+ /*
+ * This code executes as part of processing the header. As a
+ * result, it's not totally clear how to interpret the
+ * response code yet as that depends on what other headers may
+ * be present. 401 and 407 may be errors, but may be OK
+ * depending on how authentication is working. Other codes
+ * are definitely errors, so give up here.
+ */
+ if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
+ ((k->httpcode != 401) || !conn->bits.user_passwd) &&
+ ((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) {
+
+ if(data->state.resume_from &&
+ (data->set.httpreq==HTTPREQ_GET) &&
+ (k->httpcode == 416)) {
+ /* "Requested Range Not Satisfiable", just proceed and
+ pretend this is no error */
+ }
+ else {
+ /* serious error, go home! */
+ print_http_error(data);
+ return CURLE_HTTP_RETURNED_ERROR;
+ }
+ }
+
+ if(conn->httpversion == 10) {
+ /* Default action for HTTP/1.0 must be to close, unless
+ we get one of those fancy headers that tell us the
+ server keeps it open for us! */
+ infof(data, "HTTP 1.0, assume close after body\n");
+ connclose(conn, "HTTP/1.0 close after body");
+ }
+ else if(conn->httpversion == 20 ||
+ (k->upgr101 == UPGR101_REQUESTED && k->httpcode == 101)) {
+ DEBUGF(infof(data, "HTTP/2 found, allow multiplexing\n"));
+
+ /* HTTP/2 cannot blacklist multiplexing since it is a core
+ functionality of the protocol */
+ conn->bundle->multiuse = BUNDLE_MULTIPLEX;
+ }
+ else if(conn->httpversion >= 11 &&
+ !conn->bits.close) {
+ /* If HTTP version is >= 1.1 and connection is persistent
+ server supports pipelining. */
+ DEBUGF(infof(data,
+ "HTTP 1.1 or later with persistent connection, "
+ "pipelining supported\n"));
+ /* Activate pipelining if needed */
+ if(conn->bundle) {
+ if(!Curl_pipeline_site_blacklisted(data, conn))
+ conn->bundle->multiuse = BUNDLE_PIPELINING;
+ }
+ }
+
+ switch(k->httpcode) {
+ case 204:
+ /* (quote from RFC2616, section 10.2.5): The server has
+ * fulfilled the request but does not need to return an
+ * entity-body ... The 204 response MUST NOT include a
+ * message-body, and thus is always terminated by the first
+ * empty line after the header fields. */
+ /* FALLTHROUGH */
+ case 304:
+ /* (quote from RFC2616, section 10.3.5): The 304 response
+ * MUST NOT contain a message-body, and thus is always
+ * terminated by the first empty line after the header
+ * fields. */
+ if(data->set.timecondition)
+ data->info.timecond = TRUE;
+ k->size=0;
+ k->maxdownload=0;
+ k->ignorecl = TRUE; /* ignore Content-Length headers */
+ break;
+ default:
+ /* nothing */
+ break;
+ }
+ }
+ else {
+ k->header = FALSE; /* this is not a header line */
+ break;
+ }
+ }
+
+ result = Curl_convert_from_network(data, k->p, strlen(k->p));
+ /* Curl_convert_from_network calls failf if unsuccessful */
+ if(result)
+ return result;
+
+ /* Check for Content-Length: header lines to get size */
+ if(!k->ignorecl && !data->set.ignorecl &&
+ checkprefix("Content-Length:", k->p)) {
+ curl_off_t contentlength = curlx_strtoofft(k->p+15, NULL, 10);
+ if(data->set.max_filesize &&
+ contentlength > data->set.max_filesize) {
+ failf(data, "Maximum file size exceeded");
+ return CURLE_FILESIZE_EXCEEDED;
+ }
+ if(contentlength >= 0) {
+ k->size = contentlength;
+ k->maxdownload = k->size;
+ /* we set the progress download size already at this point
+ just to make it easier for apps/callbacks to extract this
+ info as soon as possible */
+ Curl_pgrsSetDownloadSize(data, k->size);
+ }
+ else {
+ /* Negative Content-Length is really odd, and we know it
+ happens for example when older Apache servers send large
+ files */
+ connclose(conn, "negative content-length");
+ infof(data, "Negative content-length: %" CURL_FORMAT_CURL_OFF_T
+ ", closing after transfer\n", contentlength);
+ }
+ }
+ /* check for Content-Type: header lines to get the MIME-type */
+ else if(checkprefix("Content-Type:", k->p)) {
+ char *contenttype = Curl_copy_header_value(k->p);
+ if(!contenttype)
+ return CURLE_OUT_OF_MEMORY;
+ if(!*contenttype)
+ /* ignore empty data */
+ free(contenttype);
+ else {
+ Curl_safefree(data->info.contenttype);
+ data->info.contenttype = contenttype;
+ }
+ }
+ else if(checkprefix("Server:", k->p)) {
+ if(conn->httpversion < 20) {
+ /* only do this for non-h2 servers */
+ char *server_name = Curl_copy_header_value(k->p);
+
+ /* Turn off pipelining if the server version is blacklisted */
+ if(conn->bundle && (conn->bundle->multiuse == BUNDLE_PIPELINING)) {
+ if(Curl_pipeline_server_blacklisted(data, server_name))
+ conn->bundle->multiuse = BUNDLE_NO_MULTIUSE;
+ }
+ free(server_name);
+ }
+ }
+ else if((conn->httpversion == 10) &&
+ conn->bits.httpproxy &&
+ Curl_compareheader(k->p,
+ "Proxy-Connection:", "keep-alive")) {
+ /*
+ * When a HTTP/1.0 reply comes when using a proxy, the
+ * 'Proxy-Connection: keep-alive' line tells us the
+ * connection will be kept alive for our pleasure.
+ * Default action for 1.0 is to close.
+ */
+ connkeep(conn, "Proxy-Connection keep-alive"); /* don't close */
+ infof(data, "HTTP/1.0 proxy connection set to keep alive!\n");
+ }
+ else if((conn->httpversion == 11) &&
+ conn->bits.httpproxy &&
+ Curl_compareheader(k->p,
+ "Proxy-Connection:", "close")) {
+ /*
+ * We get a HTTP/1.1 response from a proxy and it says it'll
+ * close down after this transfer.
+ */
+ connclose(conn, "Proxy-Connection: asked to close after done");
+ infof(data, "HTTP/1.1 proxy connection set close!\n");
+ }
+ else if((conn->httpversion == 10) &&
+ Curl_compareheader(k->p, "Connection:", "keep-alive")) {
+ /*
+ * A HTTP/1.0 reply with the 'Connection: keep-alive' line
+ * tells us the connection will be kept alive for our
+ * pleasure. Default action for 1.0 is to close.
+ *
+ * [RFC2068, section 19.7.1] */
+ connkeep(conn, "Connection keep-alive");
+ infof(data, "HTTP/1.0 connection set to keep alive!\n");
+ }
+ else if(Curl_compareheader(k->p, "Connection:", "close")) {
+ /*
+ * [RFC 2616, section 8.1.2.1]
+ * "Connection: close" is HTTP/1.1 language and means that
+ * the connection will close when this request has been
+ * served.
+ */
+ connclose(conn, "Connection: close used");
+ }
+ else if(checkprefix("Transfer-Encoding:", k->p)) {
+ /* One or more encodings. We check for chunked and/or a compression
+ algorithm. */
+ /*
+ * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
+ * means that the server will send a series of "chunks". Each
+ * chunk starts with line with info (including size of the
+ * coming block) (terminated with CRLF), then a block of data
+ * with the previously mentioned size. There can be any amount
+ * of chunks, and a chunk-data set to zero signals the
+ * end-of-chunks. */
+
+ char *start;
+
+ /* Find the first non-space letter */
+ start = k->p + 18;
+
+ for(;;) {
+ /* skip whitespaces and commas */
+ while(*start && (ISSPACE(*start) || (*start == ',')))
+ start++;
+
+ if(checkprefix("chunked", start)) {
+ k->chunk = TRUE; /* chunks coming our way */
+
+ /* init our chunky engine */
+ Curl_httpchunk_init(conn);
+
+ start += 7;
+ }
+
+ if(k->auto_decoding)
+ /* TODO: we only support the first mentioned compression for now */
+ break;
+
+ if(checkprefix("identity", start)) {
+ k->auto_decoding = IDENTITY;
+ start += 8;
+ }
+ else if(checkprefix("deflate", start)) {
+ k->auto_decoding = DEFLATE;
+ start += 7;
+ }
+ else if(checkprefix("gzip", start)) {
+ k->auto_decoding = GZIP;
+ start += 4;
+ }
+ else if(checkprefix("x-gzip", start)) {
+ k->auto_decoding = GZIP;
+ start += 6;
+ }
+ else
+ /* unknown! */
+ break;
+
+ }
+
+ }
+ else if(checkprefix("Content-Encoding:", k->p) &&
+ (data->set.str[STRING_ENCODING] ||
+ conn->httpversion == 20)) {
+ /*
+ * Process Content-Encoding. Look for the values: identity,
+ * gzip, deflate, compress, x-gzip and x-compress. x-gzip and
+ * x-compress are the same as gzip and compress. (Sec 3.5 RFC
+ * 2616). zlib cannot handle compress. However, errors are
+ * handled further down when the response body is processed
+ */
+ char *start;
+
+ /* Find the first non-space letter */
+ start = k->p + 17;
+ while(*start && ISSPACE(*start))
+ start++;
+
+ /* Record the content-encoding for later use */
+ if(checkprefix("identity", start))
+ k->auto_decoding = IDENTITY;
+ else if(checkprefix("deflate", start))
+ k->auto_decoding = DEFLATE;
+ else if(checkprefix("gzip", start)
+ || checkprefix("x-gzip", start))
+ k->auto_decoding = GZIP;
+ }
+ else if(checkprefix("Content-Range:", k->p)) {
+ /* Content-Range: bytes [num]-
+ Content-Range: bytes: [num]-
+ Content-Range: [num]-
+ Content-Range: [asterisk]/[total]
+
+ The second format was added since Sun's webserver
+ JavaWebServer/1.1.1 obviously sends the header this way!
+ The third added since some servers use that!
+ The forth means the requested range was unsatisfied.
+ */
+
+ char *ptr = k->p + 14;
+
+ /* Move forward until first digit or asterisk */
+ while(*ptr && !ISDIGIT(*ptr) && *ptr != '*')
+ ptr++;
+
+ /* if it truly stopped on a digit */
+ if(ISDIGIT(*ptr)) {
+ k->offset = curlx_strtoofft(ptr, NULL, 10);
+
+ if(data->state.resume_from == k->offset)
+ /* we asked for a resume and we got it */
+ k->content_range = TRUE;
+ }
+ else
+ data->state.resume_from = 0; /* get everything */
+ }
+#if !defined(CURL_DISABLE_COOKIES)
+ else if(data->cookies &&
+ checkprefix("Set-Cookie:", k->p)) {
+ Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
+ CURL_LOCK_ACCESS_SINGLE);
+ Curl_cookie_add(data,
+ data->cookies, TRUE, k->p+11,
+ /* If there is a custom-set Host: name, use it
+ here, or else use real peer host name. */
+ conn->allocptr.cookiehost?
+ conn->allocptr.cookiehost:conn->host.name,
+ data->state.path);
+ Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
+ }
+#endif
+ else if(checkprefix("Last-Modified:", k->p) &&
+ (data->set.timecondition || data->set.get_filetime) ) {
+ time_t secs=time(NULL);
+ k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
+ &secs);
+ if(data->set.get_filetime)
+ data->info.filetime = (long)k->timeofdoc;
+ }
+ else if((checkprefix("WWW-Authenticate:", k->p) &&
+ (401 == k->httpcode)) ||
+ (checkprefix("Proxy-authenticate:", k->p) &&
+ (407 == k->httpcode))) {
+
+ bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
+ char *auth = Curl_copy_header_value(k->p);
+ if(!auth)
+ return CURLE_OUT_OF_MEMORY;
+
+ result = Curl_http_input_auth(conn, proxy, auth);
+
+ free(auth);
+
+ if(result)
+ return result;
+ }
+ else if((k->httpcode >= 300 && k->httpcode < 400) &&
+ checkprefix("Location:", k->p) &&
+ !data->req.location) {
+ /* this is the URL that the server advises us to use instead */
+ char *location = Curl_copy_header_value(k->p);
+ if(!location)
+ return CURLE_OUT_OF_MEMORY;
+ if(!*location)
+ /* ignore empty data */
+ free(location);
+ else {
+ data->req.location = location;
+
+ if(data->set.http_follow_location) {
+ DEBUGASSERT(!data->req.newurl);
+ data->req.newurl = strdup(data->req.location); /* clone */
+ if(!data->req.newurl)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* some cases of POST and PUT etc needs to rewind the data
+ stream at this point */
+ result = http_perhapsrewind(conn);
+ if(result)
+ return result;
+ }
+ }
+ }
+ else if(conn->handler->protocol & CURLPROTO_RTSP) {
+ result = Curl_rtsp_parseheader(conn, k->p);
+ if(result)
+ return result;
+ }
+
+ /*
+ * End of header-checks. Write them to the client.
+ */
+
+ writetype = CLIENTWRITE_HEADER;
+ if(data->set.include_header)
+ writetype |= CLIENTWRITE_BODY;
+
+ if(data->set.verbose)
+ Curl_debug(data, CURLINFO_HEADER_IN,
+ k->p, (size_t)k->hbuflen, conn);
+
+ result = Curl_client_write(conn, writetype, k->p, k->hbuflen);
+ if(result)
+ return result;
+
+ data->info.header_size += (long)k->hbuflen;
+ data->req.headerbytecount += (long)k->hbuflen;
+
+ /* reset hbufp pointer && hbuflen */
+ k->hbufp = data->state.headerbuff;
+ k->hbuflen = 0;
+ }
+ while(!*stop_reading && *k->str); /* header line within buffer */
+
+ /* We might have reached the end of the header part here, but
+ there might be a non-header part left in the end of the read
+ buffer. */
+
+ return CURLE_OK;
+}
+
+#endif /* CURL_DISABLE_HTTP */
diff --git a/Utilities/cmcurl/lib/http.h b/Utilities/cmcurl/lib/http.h
new file mode 100644
index 000000000..fe4f39bc6
--- /dev/null
+++ b/Utilities/cmcurl/lib/http.h
@@ -0,0 +1,251 @@
+#ifndef HEADER_CURL_HTTP_H
+#define HEADER_CURL_HTTP_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_HTTP
+
+#ifdef USE_NGHTTP2
+#include <nghttp2/nghttp2.h>
+#endif
+
+extern const struct Curl_handler Curl_handler_http;
+
+#ifdef USE_SSL
+extern const struct Curl_handler Curl_handler_https;
+#endif
+
+/* Header specific functions */
+bool Curl_compareheader(const char *headerline, /* line to check */
+ const char *header, /* header keyword _with_ colon */
+ const char *content); /* content string to find */
+
+char *Curl_checkheaders(const struct connectdata *conn,
+ const char *thisheader);
+char *Curl_copy_header_value(const char *header);
+
+char *Curl_checkProxyheaders(const struct connectdata *conn,
+ const char *thisheader);
+/* ------------------------------------------------------------------------- */
+/*
+ * The add_buffer series of functions are used to build one large memory chunk
+ * from repeated function invokes. Used so that the entire HTTP request can
+ * be sent in one go.
+ */
+struct Curl_send_buffer {
+ char *buffer;
+ size_t size_max;
+ size_t size_used;
+};
+typedef struct Curl_send_buffer Curl_send_buffer;
+
+Curl_send_buffer *Curl_add_buffer_init(void);
+void Curl_add_buffer_free(Curl_send_buffer *buff);
+CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...);
+CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size);
+CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
+ struct connectdata *conn,
+ long *bytes_written,
+ size_t included_body_bytes,
+ int socketindex);
+
+CURLcode Curl_add_timecondition(struct SessionHandle *data,
+ Curl_send_buffer *buf);
+CURLcode Curl_add_custom_headers(struct connectdata *conn,
+ bool is_connect,
+ Curl_send_buffer *req_buffer);
+
+/* protocol-specific functions set up to be called by the main engine */
+CURLcode Curl_http(struct connectdata *conn, bool *done);
+CURLcode Curl_http_done(struct connectdata *, CURLcode, bool premature);
+CURLcode Curl_http_connect(struct connectdata *conn, bool *done);
+CURLcode Curl_http_setup_conn(struct connectdata *conn);
+
+/* The following functions are defined in http_chunks.c */
+void Curl_httpchunk_init(struct connectdata *conn);
+CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap,
+ ssize_t length, ssize_t *wrote);
+
+/* These functions are in http.c */
+void Curl_http_auth_stage(struct SessionHandle *data, int stage);
+CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
+ const char *auth);
+CURLcode Curl_http_auth_act(struct connectdata *conn);
+CURLcode Curl_http_perhapsrewind(struct connectdata *conn);
+
+/* If only the PICKNONE bit is set, there has been a round-trip and we
+ selected to use no auth at all. Ie, we actively select no auth, as opposed
+ to not having one selected. The other CURLAUTH_* defines are present in the
+ public curl/curl.h header. */
+#define CURLAUTH_PICKNONE (1<<30) /* don't use auth */
+
+/* MAX_INITIAL_POST_SIZE indicates the number of bytes that will make the POST
+ data get included in the initial data chunk sent to the server. If the
+ data is larger than this, it will automatically get split up in multiple
+ system calls.
+
+ This value used to be fairly big (100K), but we must take into account that
+ if the server rejects the POST due for authentication reasons, this data
+ will always be uncondtionally sent and thus it may not be larger than can
+ always be afforded to send twice.
+
+ It must not be greater than 64K to work on VMS.
+*/
+#ifndef MAX_INITIAL_POST_SIZE
+#define MAX_INITIAL_POST_SIZE (64*1024)
+#endif
+
+#ifndef TINY_INITIAL_POST_SIZE
+#define TINY_INITIAL_POST_SIZE 1024
+#endif
+
+#endif /* CURL_DISABLE_HTTP */
+
+/****************************************************************************
+ * HTTP unique setup
+ ***************************************************************************/
+struct HTTP {
+ struct FormData *sendit;
+ curl_off_t postsize; /* off_t to handle large file sizes */
+ const char *postdata;
+
+ const char *p_pragma; /* Pragma: string */
+ const char *p_accept; /* Accept: string */
+ curl_off_t readbytecount;
+ curl_off_t writebytecount;
+
+ /* For FORM posting */
+ struct Form form;
+
+ struct back {
+ curl_read_callback fread_func; /* backup storage for fread pointer */
+ void *fread_in; /* backup storage for fread_in pointer */
+ const char *postdata;
+ curl_off_t postsize;
+ } backup;
+
+ enum {
+ HTTPSEND_NADA, /* init */
+ HTTPSEND_REQUEST, /* sending a request */
+ HTTPSEND_BODY, /* sending body */
+ HTTPSEND_LAST /* never use this */
+ } sending;
+
+ void *send_buffer; /* used if the request couldn't be sent in one chunk,
+ points to an allocated send_buffer struct */
+
+#ifdef USE_NGHTTP2
+ /*********** for HTTP/2 we store stream-local data here *************/
+ int32_t stream_id; /* stream we are interested in */
+
+ bool bodystarted;
+ /* We store non-final and final response headers here, per-stream */
+ Curl_send_buffer *header_recvbuf;
+ size_t nread_header_recvbuf; /* number of bytes in header_recvbuf fed into
+ upper layer */
+ int status_code; /* HTTP status code */
+ const uint8_t *pausedata; /* pointer to data received in on_data_chunk */
+ size_t pauselen; /* the number of bytes left in data */
+ bool closed; /* TRUE on HTTP2 stream close */
+ uint32_t error_code; /* HTTP/2 error code */
+
+ char *mem; /* points to a buffer in memory to store received data */
+ size_t len; /* size of the buffer 'mem' points to */
+ size_t memlen; /* size of data copied to mem */
+
+ const uint8_t *upload_mem; /* points to a buffer to read from */
+ size_t upload_len; /* size of the buffer 'upload_mem' points to */
+ curl_off_t upload_left; /* number of bytes left to upload */
+
+ char **push_headers; /* allocated array */
+ size_t push_headers_used; /* number of entries filled in */
+ size_t push_headers_alloc; /* number of entries allocated */
+#endif
+};
+
+typedef int (*sending)(void); /* Curl_send */
+typedef int (*recving)(void); /* Curl_recv */
+
+#ifdef USE_NGHTTP2
+/* h2 settings for this connection */
+struct h2settings {
+ uint32_t max_concurrent_streams;
+ bool enable_push;
+};
+#endif
+
+
+struct http_conn {
+#ifdef USE_NGHTTP2
+#define H2_BINSETTINGS_LEN 80
+ nghttp2_session *h2;
+ uint8_t binsettings[H2_BINSETTINGS_LEN];
+ size_t binlen; /* length of the binsettings data */
+ sending send_underlying; /* underlying send Curl_send callback */
+ recving recv_underlying; /* underlying recv Curl_recv callback */
+ char *inbuf; /* buffer to receive data from underlying socket */
+ size_t inbuflen; /* number of bytes filled in inbuf */
+ size_t nread_inbuf; /* number of bytes read from in inbuf */
+ /* We need separate buffer for transmission and reception because we
+ may call nghttp2_session_send() after the
+ nghttp2_session_mem_recv() but mem buffer is still not full. In
+ this case, we wrongly sends the content of mem buffer if we share
+ them for both cases. */
+ int32_t pause_stream_id; /* stream ID which paused
+ nghttp2_session_mem_recv */
+
+ /* this is a hash of all individual streams (SessionHandle structs) */
+ struct h2settings settings;
+#else
+ int unused; /* prevent a compiler warning */
+#endif
+};
+
+CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
+ struct connectdata *conn,
+ ssize_t *nread,
+ bool *stop_reading);
+
+/**
+ * Curl_http_output_auth() setups the authentication headers for the
+ * host/proxy and the correct authentication
+ * method. conn->data->state.authdone is set to TRUE when authentication is
+ * done.
+ *
+ * @param conn all information about the current connection
+ * @param request pointer to the request keyword
+ * @param path pointer to the requested path
+ * @param proxytunnel boolean if this is the request setting up a "proxy
+ * tunnel"
+ *
+ * @returns CURLcode
+ */
+CURLcode
+Curl_http_output_auth(struct connectdata *conn,
+ const char *request,
+ const char *path,
+ bool proxytunnel); /* TRUE if this is the request setting
+ up the proxy tunnel */
+
+#endif /* HEADER_CURL_HTTP_H */
+
diff --git a/Utilities/cmcurl/lib/http2.c b/Utilities/cmcurl/lib/http2.c
new file mode 100644
index 000000000..0024add8a
--- /dev/null
+++ b/Utilities/cmcurl/lib/http2.c
@@ -0,0 +1,1562 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_NGHTTP2
+#include "curl_printf.h"
+#include <nghttp2/nghttp2.h>
+#include "urldata.h"
+#include "http2.h"
+#include "http.h"
+#include "sendf.h"
+#include "curl_base64.h"
+#include "rawstr.h"
+#include "multiif.h"
+#include "conncache.h"
+#include "url.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define MIN(x,y) ((x)<(y)?(x):(y))
+
+#if (NGHTTP2_VERSION_NUM < 0x000600)
+#error too old nghttp2 version, upgrade!
+#endif
+
+static int http2_perform_getsock(const struct connectdata *conn,
+ curl_socket_t *sock, /* points to
+ numsocks
+ number of
+ sockets */
+ int numsocks)
+{
+ const struct http_conn *c = &conn->proto.httpc;
+ int bitmap = GETSOCK_BLANK;
+ (void)numsocks;
+
+ /* TODO We should check underlying socket state if it is SSL socket
+ because of renegotiation. */
+ sock[0] = conn->sock[FIRSTSOCKET];
+
+ if(nghttp2_session_want_read(c->h2))
+ bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
+
+ if(nghttp2_session_want_write(c->h2))
+ bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
+
+ return bitmap;
+}
+
+static int http2_getsock(struct connectdata *conn,
+ curl_socket_t *sock, /* points to numsocks
+ number of sockets */
+ int numsocks)
+{
+ return http2_perform_getsock(conn, sock, numsocks);
+}
+
+static CURLcode http2_disconnect(struct connectdata *conn,
+ bool dead_connection)
+{
+ struct HTTP *http = conn->data->req.protop;
+ struct http_conn *c = &conn->proto.httpc;
+ (void)dead_connection;
+
+ DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT starts now\n"));
+
+ nghttp2_session_del(c->h2);
+ Curl_safefree(c->inbuf);
+
+ if(http) {
+ Curl_add_buffer_free(http->header_recvbuf);
+ http->header_recvbuf = NULL; /* clear the pointer */
+ for(; http->push_headers_used > 0; --http->push_headers_used) {
+ free(http->push_headers[http->push_headers_used - 1]);
+ }
+ free(http->push_headers);
+ http->push_headers = NULL;
+ }
+
+ DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT done\n"));
+
+ return CURLE_OK;
+}
+
+/* called from Curl_http_setup_conn */
+void Curl_http2_setup_req(struct SessionHandle *data)
+{
+ struct HTTP *http = data->req.protop;
+
+ http->nread_header_recvbuf = 0;
+ http->bodystarted = FALSE;
+ http->status_code = -1;
+ http->pausedata = NULL;
+ http->pauselen = 0;
+ http->error_code = NGHTTP2_NO_ERROR;
+ http->closed = FALSE;
+ http->mem = data->state.buffer;
+ http->len = BUFSIZE;
+ http->memlen = 0;
+}
+
+/* called from Curl_http_setup_conn */
+void Curl_http2_setup_conn(struct connectdata *conn)
+{
+ conn->proto.httpc.settings.max_concurrent_streams =
+ DEFAULT_MAX_CONCURRENT_STREAMS;
+}
+
+/*
+ * HTTP2 handler interface. This isn't added to the general list of protocols
+ * but will be used at run-time when the protocol is dynamically switched from
+ * HTTP to HTTP2.
+ */
+const struct Curl_handler Curl_handler_http2 = {
+ "HTTP2", /* scheme */
+ ZERO_NULL, /* setup_connection */
+ Curl_http, /* do_it */
+ Curl_http_done, /* done */
+ ZERO_NULL, /* do_more */
+ ZERO_NULL, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ http2_getsock, /* proto_getsock */
+ http2_getsock, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ http2_perform_getsock, /* perform_getsock */
+ http2_disconnect, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_HTTP, /* defport */
+ CURLPROTO_HTTP, /* protocol */
+ PROTOPT_NONE /* flags */
+};
+
+const struct Curl_handler Curl_handler_http2_ssl = {
+ "HTTP2", /* scheme */
+ ZERO_NULL, /* setup_connection */
+ Curl_http, /* do_it */
+ Curl_http_done, /* done */
+ ZERO_NULL, /* do_more */
+ ZERO_NULL, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ http2_getsock, /* proto_getsock */
+ http2_getsock, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ http2_perform_getsock, /* perform_getsock */
+ http2_disconnect, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_HTTP, /* defport */
+ CURLPROTO_HTTPS, /* protocol */
+ PROTOPT_SSL /* flags */
+};
+
+/*
+ * Store nghttp2 version info in this buffer, Prefix with a space. Return
+ * total length written.
+ */
+int Curl_http2_ver(char *p, size_t len)
+{
+ nghttp2_info *h2 = nghttp2_version(0);
+ return snprintf(p, len, " nghttp2/%s", h2->version_str);
+}
+
+/*
+ * The implementation of nghttp2_send_callback type. Here we write |data| with
+ * size |length| to the network and return the number of bytes actually
+ * written. See the documentation of nghttp2_send_callback for the details.
+ */
+static ssize_t send_callback(nghttp2_session *h2,
+ const uint8_t *data, size_t length, int flags,
+ void *userp)
+{
+ struct connectdata *conn = (struct connectdata *)userp;
+ struct http_conn *c = &conn->proto.httpc;
+ ssize_t written;
+ CURLcode result = CURLE_OK;
+
+ (void)h2;
+ (void)flags;
+
+ written = ((Curl_send*)c->send_underlying)(conn, FIRSTSOCKET,
+ data, length, &result);
+
+ if(result == CURLE_AGAIN) {
+ return NGHTTP2_ERR_WOULDBLOCK;
+ }
+
+ if(written == -1) {
+ failf(conn->data, "Failed sending HTTP2 data");
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+ }
+
+ if(!written)
+ return NGHTTP2_ERR_WOULDBLOCK;
+
+ return written;
+}
+
+
+/* We pass a pointer to this struct in the push callback, but the contents of
+ the struct are hidden from the user. */
+struct curl_pushheaders {
+ struct SessionHandle *data;
+ const nghttp2_push_promise *frame;
+};
+
+/*
+ * push header access function. Only to be used from within the push callback
+ */
+char *curl_pushheader_bynum(struct curl_pushheaders *h, size_t num)
+{
+ /* Verify that we got a good easy handle in the push header struct, mostly to
+ detect rubbish input fast(er). */
+ if(!h || !GOOD_EASY_HANDLE(h->data))
+ return NULL;
+ else {
+ struct HTTP *stream = h->data->req.protop;
+ if(num < stream->push_headers_used)
+ return stream->push_headers[num];
+ }
+ return NULL;
+}
+
+/*
+ * push header access function. Only to be used from within the push callback
+ */
+char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header)
+{
+ /* Verify that we got a good easy handle in the push header struct,
+ mostly to detect rubbish input fast(er). Also empty header name
+ is just a rubbish too. We have to allow ":" at the beginning of
+ the header, but header == ":" must be rejected. If we have ':' in
+ the middle of header, it could be matched in middle of the value,
+ this is because we do prefix match.*/
+ if(!h || !GOOD_EASY_HANDLE(h->data) || !header || !header[0] ||
+ Curl_raw_equal(header, ":") || strchr(header + 1, ':'))
+ return NULL;
+ else {
+ struct HTTP *stream = h->data->req.protop;
+ size_t len = strlen(header);
+ size_t i;
+ for(i=0; i<stream->push_headers_used; i++) {
+ if(!strncmp(header, stream->push_headers[i], len)) {
+ /* sub-match, make sure that it us followed by a colon */
+ if(stream->push_headers[i][len] != ':')
+ continue;
+ return &stream->push_headers[i][len+1];
+ }
+ }
+ }
+ return NULL;
+}
+
+static CURL *duphandle(struct SessionHandle *data)
+{
+ struct SessionHandle *second = curl_easy_duphandle(data);
+ if(second) {
+ /* setup the request struct */
+ struct HTTP *http = calloc(1, sizeof(struct HTTP));
+ if(!http) {
+ (void)Curl_close(second);
+ second = NULL;
+ }
+ else {
+ second->req.protop = http;
+ http->header_recvbuf = Curl_add_buffer_init();
+ if(!http->header_recvbuf) {
+ free(http);
+ (void)Curl_close(second);
+ second = NULL;
+ }
+ else
+ Curl_http2_setup_req(second);
+ }
+ }
+ return second;
+}
+
+
+static int push_promise(struct SessionHandle *data,
+ struct connectdata *conn,
+ const nghttp2_push_promise *frame)
+{
+ int rv;
+ DEBUGF(infof(data, "PUSH_PROMISE received, stream %u!\n",
+ frame->promised_stream_id));
+ if(data->multi->push_cb) {
+ struct HTTP *stream;
+ struct curl_pushheaders heads;
+ CURLMcode rc;
+ struct http_conn *httpc;
+ size_t i;
+ /* clone the parent */
+ CURL *newhandle = duphandle(data);
+ if(!newhandle) {
+ infof(data, "failed to duplicate handle\n");
+ rv = 1; /* FAIL HARD */
+ goto fail;
+ }
+
+ heads.data = data;
+ heads.frame = frame;
+ /* ask the application */
+ DEBUGF(infof(data, "Got PUSH_PROMISE, ask application!\n"));
+
+ stream = data->req.protop;
+ if(!stream) {
+ failf(data, "Internal NULL stream!\n");
+ rv = 1;
+ goto fail;
+ }
+
+ rv = data->multi->push_cb(data, newhandle,
+ stream->push_headers_used, &heads,
+ data->multi->push_userp);
+
+ /* free the headers again */
+ for(i=0; i<stream->push_headers_used; i++)
+ free(stream->push_headers[i]);
+ free(stream->push_headers);
+ stream->push_headers = NULL;
+
+ if(rv) {
+ /* denied, kill off the new handle again */
+ (void)Curl_close(newhandle);
+ goto fail;
+ }
+
+ /* approved, add to the multi handle and immediately switch to PERFORM
+ state with the given connection !*/
+ rc = Curl_multi_add_perform(data->multi, newhandle, conn);
+ if(rc) {
+ infof(data, "failed to add handle to multi\n");
+ Curl_close(newhandle);
+ rv = 1;
+ goto fail;
+ }
+
+ httpc = &conn->proto.httpc;
+ nghttp2_session_set_stream_user_data(httpc->h2,
+ frame->promised_stream_id, newhandle);
+ }
+ else {
+ DEBUGF(infof(data, "Got PUSH_PROMISE, ignore it!\n"));
+ rv = 1;
+ }
+ fail:
+ return rv;
+}
+
+static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
+ void *userp)
+{
+ struct connectdata *conn = NULL;
+ struct http_conn *httpc = NULL;
+ struct SessionHandle *data_s = NULL;
+ struct HTTP *stream = NULL;
+ static int lastStream = -1;
+ int rv;
+ size_t left, ncopy;
+ int32_t stream_id = frame->hd.stream_id;
+
+ (void)userp;
+
+ if(!stream_id) {
+ /* stream ID zero is for connection-oriented stuff */
+ return 0;
+ }
+ data_s = nghttp2_session_get_stream_user_data(session,
+ frame->hd.stream_id);
+ if(lastStream != frame->hd.stream_id) {
+ lastStream = frame->hd.stream_id;
+ }
+ if(!data_s) {
+ DEBUGF(infof(conn->data,
+ "No SessionHandle associated with stream: %x\n",
+ stream_id));
+ return 0;
+ }
+
+ stream = data_s->req.protop;
+ if(!stream)
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+ DEBUGF(infof(data_s, "on_frame_recv() header %x stream %x\n",
+ frame->hd.type, stream_id));
+
+ conn = data_s->easy_conn;
+ assert(conn);
+ assert(conn->data == data_s);
+ httpc = &conn->proto.httpc;
+ switch(frame->hd.type) {
+ case NGHTTP2_DATA:
+ /* If body started on this stream, then receiving DATA is illegal. */
+ if(!stream->bodystarted) {
+ rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
+ stream_id, NGHTTP2_PROTOCOL_ERROR);
+
+ if(nghttp2_is_fatal(rv)) {
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+ }
+ }
+ break;
+ case NGHTTP2_HEADERS:
+ if(frame->headers.cat == NGHTTP2_HCAT_REQUEST)
+ break;
+
+ if(stream->bodystarted) {
+ /* Only valid HEADERS after body started is trailer HEADERS. We
+ ignores trailer HEADERS for now. nghttp2 guarantees that it
+ has END_STREAM flag set. */
+ break;
+ }
+
+ /* nghttp2 guarantees that :status is received, and we store it to
+ stream->status_code */
+ DEBUGASSERT(stream->status_code != -1);
+
+ /* Only final status code signals the end of header */
+ if(stream->status_code / 100 != 1) {
+ stream->bodystarted = TRUE;
+ stream->status_code = -1;
+ }
+
+ Curl_add_buffer(stream->header_recvbuf, "\r\n", 2);
+
+ left = stream->header_recvbuf->size_used - stream->nread_header_recvbuf;
+ ncopy = MIN(stream->len, left);
+
+ memcpy(&stream->mem[stream->memlen],
+ stream->header_recvbuf->buffer + stream->nread_header_recvbuf,
+ ncopy);
+ stream->nread_header_recvbuf += ncopy;
+
+ DEBUGF(infof(data_s, "Store %zu bytes headers from stream %u at %p\n",
+ ncopy, stream_id, stream->mem));
+
+ stream->len -= ncopy;
+ stream->memlen += ncopy;
+
+ data_s->state.drain++;
+ Curl_expire(data_s, 1);
+ break;
+ case NGHTTP2_PUSH_PROMISE:
+ rv = push_promise(data_s, conn, &frame->push_promise);
+ if(rv) { /* deny! */
+ rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
+ frame->push_promise.promised_stream_id,
+ NGHTTP2_CANCEL);
+ if(nghttp2_is_fatal(rv)) {
+ return rv;
+ }
+ }
+ break;
+ case NGHTTP2_SETTINGS:
+ {
+ uint32_t max_conn = httpc->settings.max_concurrent_streams;
+ DEBUGF(infof(conn->data, "Got SETTINGS for stream %u!\n", stream_id));
+ httpc->settings.max_concurrent_streams =
+ nghttp2_session_get_remote_settings(
+ session, NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS);
+ httpc->settings.enable_push =
+ nghttp2_session_get_remote_settings(
+ session, NGHTTP2_SETTINGS_ENABLE_PUSH);
+ DEBUGF(infof(conn->data, "MAX_CONCURRENT_STREAMS == %d\n",
+ httpc->settings.max_concurrent_streams));
+ DEBUGF(infof(conn->data, "ENABLE_PUSH == %s\n",
+ httpc->settings.enable_push?"TRUE":"false"));
+ if(max_conn != httpc->settings.max_concurrent_streams) {
+ /* only signal change if the value actually changed */
+ infof(conn->data,
+ "Connection state changed (MAX_CONCURRENT_STREAMS updated)!\n");
+ Curl_multi_connchanged(conn->data->multi);
+ }
+ }
+ break;
+ default:
+ DEBUGF(infof(conn->data, "Got frame type %x for stream %u!\n",
+ frame->hd.type, stream_id));
+ break;
+ }
+ return 0;
+}
+
+static int on_invalid_frame_recv(nghttp2_session *session,
+ const nghttp2_frame *frame,
+ int lib_error_code, void *userp)
+{
+ struct SessionHandle *data_s = NULL;
+ (void)userp;
+
+ data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
+ if(data_s) {
+ DEBUGF(infof(data_s,
+ "on_invalid_frame_recv() was called, error=%d:%s\n",
+ lib_error_code, nghttp2_strerror(lib_error_code)));
+ }
+ return 0;
+}
+
+static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
+ int32_t stream_id,
+ const uint8_t *data, size_t len, void *userp)
+{
+ struct HTTP *stream;
+ struct SessionHandle *data_s;
+ size_t nread;
+ (void)session;
+ (void)flags;
+ (void)data;
+ (void)userp;
+
+ DEBUGASSERT(stream_id); /* should never be a zero stream ID here */
+
+ /* get the stream from the hash based on Stream ID */
+ data_s = nghttp2_session_get_stream_user_data(session, stream_id);
+ if(!data_s)
+ /* Receiving a Stream ID not in the hash should not happen, this is an
+ internal error more than anything else! */
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+ stream = data_s->req.protop;
+ if(!stream)
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+ nread = MIN(stream->len, len);
+ memcpy(&stream->mem[stream->memlen], data, nread);
+
+ stream->len -= nread;
+ stream->memlen += nread;
+
+ data_s->state.drain++;
+ Curl_expire(data_s, 1); /* TODO: fix so that this can be set to 0 for
+ immediately? */
+
+ DEBUGF(infof(data_s, "%zu data received for stream %u "
+ "(%zu left in buffer %p, total %zu)\n",
+ nread, stream_id,
+ stream->len, stream->mem,
+ stream->memlen));
+
+ if(nread < len) {
+ stream->pausedata = data + nread;
+ stream->pauselen = len - nread;
+ DEBUGF(infof(data_s, "NGHTTP2_ERR_PAUSE - %zu bytes out of buffer"
+ ", stream %u\n",
+ len - nread, stream_id));
+ data_s->easy_conn->proto.httpc.pause_stream_id = stream_id;
+ return NGHTTP2_ERR_PAUSE;
+ }
+ return 0;
+}
+
+static int before_frame_send(nghttp2_session *session,
+ const nghttp2_frame *frame,
+ void *userp)
+{
+ struct SessionHandle *data_s;
+ (void)userp;
+
+ data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
+ if(data_s) {
+ DEBUGF(infof(data_s, "before_frame_send() was called\n"));
+ }
+
+ return 0;
+}
+static int on_frame_send(nghttp2_session *session,
+ const nghttp2_frame *frame,
+ void *userp)
+{
+ struct SessionHandle *data_s;
+ (void)userp;
+
+ data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
+ if(data_s) {
+ DEBUGF(infof(data_s, "on_frame_send() was called, length = %zd\n",
+ frame->hd.length));
+ }
+ return 0;
+}
+static int on_frame_not_send(nghttp2_session *session,
+ const nghttp2_frame *frame,
+ int lib_error_code, void *userp)
+{
+ struct SessionHandle *data_s;
+ (void)userp;
+
+ data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
+ if(data_s) {
+ DEBUGF(infof(data_s,
+ "on_frame_not_send() was called, lib_error_code = %d\n",
+ lib_error_code));
+ }
+ return 0;
+}
+static int on_stream_close(nghttp2_session *session, int32_t stream_id,
+ uint32_t error_code, void *userp)
+{
+ struct SessionHandle *data_s;
+ struct HTTP *stream;
+ (void)session;
+ (void)stream_id;
+ (void)userp;
+
+ if(stream_id) {
+ /* get the stream from the hash based on Stream ID, stream ID zero is for
+ connection-oriented stuff */
+ data_s = nghttp2_session_get_stream_user_data(session, stream_id);
+ if(!data_s) {
+ /* We could get stream ID not in the hash. For example, if we
+ decided to reject stream (e.g., PUSH_PROMISE). */
+ return 0;
+ }
+ DEBUGF(infof(data_s, "on_stream_close(), error_code = %d, stream %u\n",
+ error_code, stream_id));
+ stream = data_s->req.protop;
+ if(!stream)
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+ stream->error_code = error_code;
+ stream->closed = TRUE;
+
+ /* remove the entry from the hash as the stream is now gone */
+ nghttp2_session_set_stream_user_data(session, stream_id, 0);
+ DEBUGF(infof(data_s, "Removed stream %u hash!\n", stream_id));
+ }
+ return 0;
+}
+
+static int on_begin_headers(nghttp2_session *session,
+ const nghttp2_frame *frame, void *userp)
+{
+ struct SessionHandle *data_s = NULL;
+ (void)userp;
+
+ data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
+ if(data_s) {
+ DEBUGF(infof(data_s, "on_begin_headers() was called\n"));
+ }
+ return 0;
+}
+
+/* Decode HTTP status code. Returns -1 if no valid status code was
+ decoded. */
+static int decode_status_code(const uint8_t *value, size_t len)
+{
+ int i;
+ int res;
+
+ if(len != 3) {
+ return -1;
+ }
+
+ res = 0;
+
+ for(i = 0; i < 3; ++i) {
+ char c = value[i];
+
+ if(c < '0' || c > '9') {
+ return -1;
+ }
+
+ res *= 10;
+ res += c - '0';
+ }
+
+ return res;
+}
+
+/* frame->hd.type is either NGHTTP2_HEADERS or NGHTTP2_PUSH_PROMISE */
+static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
+ const uint8_t *name, size_t namelen,
+ const uint8_t *value, size_t valuelen,
+ uint8_t flags,
+ void *userp)
+{
+ struct HTTP *stream;
+ struct SessionHandle *data_s;
+ int32_t stream_id = frame->hd.stream_id;
+
+ (void)flags;
+ (void)userp;
+
+ DEBUGASSERT(stream_id); /* should never be a zero stream ID here */
+
+ /* get the stream from the hash based on Stream ID */
+ data_s = nghttp2_session_get_stream_user_data(session, stream_id);
+ if(!data_s)
+ /* Receiving a Stream ID not in the hash should not happen, this is an
+ internal error more than anything else! */
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+ stream = data_s->req.protop;
+ if(!stream) {
+ failf(data_s, "Internal NULL stream! 5\n");
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+ }
+
+ if(stream->bodystarted)
+ /* Ignore trailer or HEADERS not mapped to HTTP semantics. The
+ consequence is handled in on_frame_recv(). */
+ return 0;
+
+ /* Store received PUSH_PROMISE headers to be used when the subsequent
+ PUSH_PROMISE callback comes */
+ if(frame->hd.type == NGHTTP2_PUSH_PROMISE) {
+ char *h;
+
+ if(!stream->push_headers) {
+ stream->push_headers_alloc = 10;
+ stream->push_headers = malloc(stream->push_headers_alloc *
+ sizeof(char *));
+ stream->push_headers_used = 0;
+ }
+ else if(stream->push_headers_used ==
+ stream->push_headers_alloc) {
+ char **headp;
+ stream->push_headers_alloc *= 2;
+ headp = realloc(stream->push_headers,
+ stream->push_headers_alloc * sizeof(char *));
+ if(!headp) {
+ free(stream->push_headers);
+ stream->push_headers = NULL;
+ return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
+ }
+ stream->push_headers = headp;
+ }
+ h = aprintf("%s:%s", name, value);
+ if(h)
+ stream->push_headers[stream->push_headers_used++] = h;
+ return 0;
+ }
+
+ if(namelen == sizeof(":status") - 1 &&
+ memcmp(":status", name, namelen) == 0) {
+ /* nghttp2 guarantees :status is received first and only once, and
+ value is 3 digits status code, and decode_status_code always
+ succeeds. */
+ stream->status_code = decode_status_code(value, valuelen);
+ DEBUGASSERT(stream->status_code != -1);
+
+ Curl_add_buffer(stream->header_recvbuf, "HTTP/2.0 ", 9);
+ Curl_add_buffer(stream->header_recvbuf, value, valuelen);
+ Curl_add_buffer(stream->header_recvbuf, "\r\n", 2);
+ data_s->state.drain++;
+ Curl_expire(data_s, 1);
+
+ DEBUGF(infof(data_s, "h2 status: HTTP/2 %03d\n",
+ stream->status_code));
+ return 0;
+ }
+
+ /* nghttp2 guarantees that namelen > 0, and :status was already
+ received, and this is not pseudo-header field . */
+ /* convert to a HTTP1-style header */
+ Curl_add_buffer(stream->header_recvbuf, name, namelen);
+ Curl_add_buffer(stream->header_recvbuf, ":", 1);
+ Curl_add_buffer(stream->header_recvbuf, value, valuelen);
+ Curl_add_buffer(stream->header_recvbuf, "\r\n", 2);
+ data_s->state.drain++;
+ Curl_expire(data_s, 1);
+
+ DEBUGF(infof(data_s, "h2 header: %.*s: %.*s\n", namelen, name, valuelen,
+ value));
+
+ return 0; /* 0 is successful */
+}
+
+static ssize_t data_source_read_callback(nghttp2_session *session,
+ int32_t stream_id,
+ uint8_t *buf, size_t length,
+ uint32_t *data_flags,
+ nghttp2_data_source *source,
+ void *userp)
+{
+ struct SessionHandle *data_s;
+ struct HTTP *stream = NULL;
+ size_t nread;
+ (void)source;
+ (void)userp;
+
+ if(stream_id) {
+ /* get the stream from the hash based on Stream ID, stream ID zero is for
+ connection-oriented stuff */
+ data_s = nghttp2_session_get_stream_user_data(session, stream_id);
+ if(!data_s)
+ /* Receiving a Stream ID not in the hash should not happen, this is an
+ internal error more than anything else! */
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+ stream = data_s->req.protop;
+ if(!stream)
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+ }
+ else
+ return NGHTTP2_ERR_INVALID_ARGUMENT;
+
+ nread = MIN(stream->upload_len, length);
+ if(nread > 0) {
+ memcpy(buf, stream->upload_mem, nread);
+ stream->upload_mem += nread;
+ stream->upload_len -= nread;
+ stream->upload_left -= nread;
+ }
+
+ if(stream->upload_left == 0)
+ *data_flags = 1;
+ else if(nread == 0)
+ return NGHTTP2_ERR_DEFERRED;
+
+ DEBUGF(infof(data_s, "data_source_read_callback: "
+ "returns %zu bytes stream %u\n",
+ nread, stream_id));
+
+ return nread;
+}
+
+/*
+ * The HTTP2 settings we send in the Upgrade request
+ */
+static nghttp2_settings_entry settings[] = {
+ { NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 100 },
+ { NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, NGHTTP2_INITIAL_WINDOW_SIZE },
+};
+
+#define H2_BUFSIZE 32768
+
+/*
+ * Initialize nghttp2 for a Curl connection
+ */
+CURLcode Curl_http2_init(struct connectdata *conn)
+{
+ if(!conn->proto.httpc.h2) {
+ int rc;
+ nghttp2_session_callbacks *callbacks;
+
+ conn->proto.httpc.inbuf = malloc(H2_BUFSIZE);
+ if(conn->proto.httpc.inbuf == NULL)
+ return CURLE_OUT_OF_MEMORY;
+
+ rc = nghttp2_session_callbacks_new(&callbacks);
+
+ if(rc) {
+ failf(conn->data, "Couldn't initialize nghttp2 callbacks!");
+ return CURLE_OUT_OF_MEMORY; /* most likely at least */
+ }
+
+ /* nghttp2_send_callback */
+ nghttp2_session_callbacks_set_send_callback(callbacks, send_callback);
+ /* nghttp2_on_frame_recv_callback */
+ nghttp2_session_callbacks_set_on_frame_recv_callback
+ (callbacks, on_frame_recv);
+ /* nghttp2_on_invalid_frame_recv_callback */
+ nghttp2_session_callbacks_set_on_invalid_frame_recv_callback
+ (callbacks, on_invalid_frame_recv);
+ /* nghttp2_on_data_chunk_recv_callback */
+ nghttp2_session_callbacks_set_on_data_chunk_recv_callback
+ (callbacks, on_data_chunk_recv);
+ /* nghttp2_before_frame_send_callback */
+ nghttp2_session_callbacks_set_before_frame_send_callback
+ (callbacks, before_frame_send);
+ /* nghttp2_on_frame_send_callback */
+ nghttp2_session_callbacks_set_on_frame_send_callback
+ (callbacks, on_frame_send);
+ /* nghttp2_on_frame_not_send_callback */
+ nghttp2_session_callbacks_set_on_frame_not_send_callback
+ (callbacks, on_frame_not_send);
+ /* nghttp2_on_stream_close_callback */
+ nghttp2_session_callbacks_set_on_stream_close_callback
+ (callbacks, on_stream_close);
+ /* nghttp2_on_begin_headers_callback */
+ nghttp2_session_callbacks_set_on_begin_headers_callback
+ (callbacks, on_begin_headers);
+ /* nghttp2_on_header_callback */
+ nghttp2_session_callbacks_set_on_header_callback(callbacks, on_header);
+
+ /* The nghttp2 session is not yet setup, do it */
+ rc = nghttp2_session_client_new(&conn->proto.httpc.h2, callbacks, conn);
+
+ nghttp2_session_callbacks_del(callbacks);
+
+ if(rc) {
+ failf(conn->data, "Couldn't initialize nghttp2!");
+ return CURLE_OUT_OF_MEMORY; /* most likely at least */
+ }
+
+ if(rc) {
+ failf(conn->data, "Couldn't init stream hash!");
+ return CURLE_OUT_OF_MEMORY; /* most likely at least */
+ }
+ }
+ return CURLE_OK;
+}
+
+/*
+ * Send a request using http2
+ */
+CURLcode Curl_http2_send_request(struct connectdata *conn)
+{
+ (void)conn;
+ return CURLE_OK;
+}
+
+/*
+ * Append headers to ask for a HTTP1.1 to HTTP2 upgrade.
+ */
+CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
+ struct connectdata *conn)
+{
+ CURLcode result;
+ ssize_t binlen;
+ char *base64;
+ size_t blen;
+ struct SingleRequest *k = &conn->data->req;
+ uint8_t *binsettings = conn->proto.httpc.binsettings;
+
+ /* As long as we have a fixed set of settings, we don't have to dynamically
+ * figure out the base64 strings since it'll always be the same. However,
+ * the settings will likely not be fixed every time in the future.
+ */
+
+ /* this returns number of bytes it wrote */
+ binlen = nghttp2_pack_settings_payload(binsettings, H2_BINSETTINGS_LEN,
+ settings,
+ sizeof(settings)/sizeof(settings[0]));
+ if(!binlen) {
+ failf(conn->data, "nghttp2 unexpectedly failed on pack_settings_payload");
+ return CURLE_FAILED_INIT;
+ }
+ conn->proto.httpc.binlen = binlen;
+
+ result = Curl_base64url_encode(conn->data, (const char *)binsettings, binlen,
+ &base64, &blen);
+ if(result)
+ return result;
+
+ result = Curl_add_bufferf(req,
+ "Connection: Upgrade, HTTP2-Settings\r\n"
+ "Upgrade: %s\r\n"
+ "HTTP2-Settings: %s\r\n",
+ NGHTTP2_CLEARTEXT_PROTO_VERSION_ID, base64);
+ free(base64);
+
+ k->upgr101 = UPGR101_REQUESTED;
+
+ return result;
+}
+
+static ssize_t http2_handle_stream_close(struct http_conn *httpc,
+ struct SessionHandle *data,
+ struct HTTP *stream, CURLcode *err) {
+ if(httpc->pause_stream_id == stream->stream_id) {
+ httpc->pause_stream_id = 0;
+ }
+ /* Reset to FALSE to prevent infinite loop in readwrite_data
+ function. */
+ stream->closed = FALSE;
+ if(stream->error_code != NGHTTP2_NO_ERROR) {
+ failf(data, "HTTP/2 stream %u was not closed cleanly: error_code = %d",
+ stream->stream_id, stream->error_code);
+ *err = CURLE_HTTP2;
+ return -1;
+ }
+ DEBUGF(infof(data, "http2_recv returns 0, http2_handle_stream_close\n"));
+ return 0;
+}
+
+/*
+ * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
+ * a regular CURLcode value.
+ */
+static ssize_t http2_recv(struct connectdata *conn, int sockindex,
+ char *mem, size_t len, CURLcode *err)
+{
+ CURLcode result = CURLE_OK;
+ ssize_t rv;
+ ssize_t nread;
+ struct http_conn *httpc = &conn->proto.httpc;
+ struct SessionHandle *data = conn->data;
+ struct HTTP *stream = data->req.protop;
+
+ (void)sockindex; /* we always do HTTP2 on sockindex 0 */
+
+ /* If stream is closed, return 0 to signal the http routine to close
+ the connection. We need to handle stream closure here,
+ otherwise, we may be going to read from underlying connection,
+ and gets EAGAIN, and we will get stuck there. */
+ if(stream->memlen == 0 && stream->closed) {
+ return http2_handle_stream_close(httpc, data, stream, err);
+ }
+
+ /* Nullify here because we call nghttp2_session_send() and they
+ might refer to the old buffer. */
+ stream->upload_mem = NULL;
+ stream->upload_len = 0;
+
+ /*
+ * At this point 'stream' is just in the SessionHandle the connection
+ * identifies as its owner at this time.
+ */
+
+ if(stream->bodystarted &&
+ stream->nread_header_recvbuf < stream->header_recvbuf->size_used) {
+ /* If there is body data pending for this stream to return, do that */
+ size_t left =
+ stream->header_recvbuf->size_used - stream->nread_header_recvbuf;
+ size_t ncopy = MIN(len, left);
+ memcpy(mem, stream->header_recvbuf->buffer + stream->nread_header_recvbuf,
+ ncopy);
+ stream->nread_header_recvbuf += ncopy;
+
+ infof(data, "http2_recv: Got %d bytes from header_recvbuf\n",
+ (int)ncopy);
+ return ncopy;
+ }
+
+ infof(data, "http2_recv: %d bytes buffer at %p (stream %u)\n",
+ len, mem, stream->stream_id);
+
+ if((data->state.drain) && stream->memlen) {
+ DEBUGF(infof(data, "http2_recv: DRAIN %zu bytes stream %u!! (%p => %p)\n",
+ stream->memlen, stream->stream_id,
+ stream->mem, mem));
+ if(mem != stream->mem) {
+ /* if we didn't get the same buffer this time, we must move the data to
+ the beginning */
+ memmove(mem, stream->mem, stream->memlen);
+ stream->len = len - stream->memlen;
+ stream->mem = mem;
+ }
+ }
+ else if(stream->pausedata) {
+ nread = MIN(len, stream->pauselen);
+ memcpy(mem, stream->pausedata, nread);
+
+ stream->pausedata += nread;
+ stream->pauselen -= nread;
+
+ infof(data, "%zu data bytes written\n", nread);
+ if(stream->pauselen == 0) {
+ DEBUGF(infof(data, "Unpaused by stream %u\n", stream->stream_id));
+ assert(httpc->pause_stream_id == stream->stream_id);
+ httpc->pause_stream_id = 0;
+
+ stream->pausedata = NULL;
+ stream->pauselen = 0;
+ }
+ infof(data, "http2_recv: returns unpaused %zd bytes on stream %u\n",
+ nread, stream->stream_id);
+ return nread;
+ }
+ else if(httpc->pause_stream_id) {
+ /* If a stream paused nghttp2_session_mem_recv previously, and has
+ not processed all data, it still refers to the buffer in
+ nghttp2_session. If we call nghttp2_session_mem_recv(), we may
+ overwrite that buffer. To avoid that situation, just return
+ here with CURLE_AGAIN. This could be busy loop since data in
+ socket is not read. But it seems that usually streams are
+ notified with its drain property, and socket is read again
+ quickly. */
+ *err = CURLE_AGAIN;
+ return -1;
+ }
+ else {
+ char *inbuf;
+ /* remember where to store incoming data for this stream and how big the
+ buffer is */
+ stream->mem = mem;
+ stream->len = len;
+ stream->memlen = 0;
+
+ if(httpc->inbuflen == 0) {
+ nread = ((Curl_recv *)httpc->recv_underlying)(
+ conn, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, &result);
+
+ if(result == CURLE_AGAIN) {
+ *err = result;
+ return -1;
+ }
+
+ if(nread == -1) {
+ failf(data, "Failed receiving HTTP2 data");
+ *err = result;
+ return 0;
+ }
+
+ if(nread == 0) {
+ failf(data, "Unexpected EOF");
+ *err = CURLE_RECV_ERROR;
+ return -1;
+ }
+
+ DEBUGF(infof(data, "nread=%zd\n", nread));
+
+ httpc->inbuflen = nread;
+ inbuf = httpc->inbuf;
+ }
+ else {
+ nread = httpc->inbuflen - httpc->nread_inbuf;
+ inbuf = httpc->inbuf + httpc->nread_inbuf;
+
+ DEBUGF(infof(data, "Use data left in connection buffer, nread=%zd\n",
+ nread));
+ }
+ rv = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)inbuf, nread);
+
+ if(nghttp2_is_fatal((int)rv)) {
+ failf(data, "nghttp2_session_mem_recv() returned %d:%s\n",
+ rv, nghttp2_strerror((int)rv));
+ *err = CURLE_RECV_ERROR;
+ return 0;
+ }
+ DEBUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", rv));
+ if(nread == rv) {
+ DEBUGF(infof(data, "All data in connection buffer processed\n"));
+ httpc->inbuflen = 0;
+ httpc->nread_inbuf = 0;
+ }
+ else {
+ httpc->nread_inbuf += rv;
+ DEBUGF(infof(data, "%zu bytes left in connection buffer\n",
+ httpc->inbuflen - httpc->nread_inbuf));
+ }
+ /* Always send pending frames in nghttp2 session, because
+ nghttp2_session_mem_recv() may queue new frame */
+ rv = nghttp2_session_send(httpc->h2);
+ if(rv != 0) {
+ *err = CURLE_SEND_ERROR;
+ return 0;
+ }
+ }
+ if(stream->memlen) {
+ ssize_t retlen = stream->memlen;
+ infof(data, "http2_recv: returns %zd for stream %u\n",
+ retlen, stream->stream_id);
+ stream->memlen = 0;
+
+ if(httpc->pause_stream_id == stream->stream_id) {
+ /* data for this stream is returned now, but this stream caused a pause
+ already so we need it called again asap */
+ DEBUGF(infof(data, "Data returned for PAUSED stream %u\n",
+ stream->stream_id));
+ }
+ else
+ data->state.drain = 0; /* this stream is hereby drained */
+
+ return retlen;
+ }
+ /* If stream is closed, return 0 to signal the http routine to close
+ the connection */
+ if(stream->closed) {
+ return http2_handle_stream_close(httpc, data, stream, err);
+ }
+ *err = CURLE_AGAIN;
+ DEBUGF(infof(data, "http2_recv returns AGAIN for stream %u\n",
+ stream->stream_id));
+ return -1;
+}
+
+/* Index where :authority header field will appear in request header
+ field list. */
+#define AUTHORITY_DST_IDX 3
+
+/* return number of received (decrypted) bytes */
+static ssize_t http2_send(struct connectdata *conn, int sockindex,
+ const void *mem, size_t len, CURLcode *err)
+{
+ /*
+ * BIG TODO: Currently, we send request in this function, but this
+ * function is also used to send request body. It would be nice to
+ * add dedicated function for request.
+ */
+ int rv;
+ struct http_conn *httpc = &conn->proto.httpc;
+ struct HTTP *stream = conn->data->req.protop;
+ nghttp2_nv *nva;
+ size_t nheader;
+ size_t i;
+ size_t authority_idx;
+ char *hdbuf = (char*)mem;
+ char *end;
+ nghttp2_data_provider data_prd;
+ int32_t stream_id;
+ nghttp2_session *h2 = httpc->h2;
+
+ (void)sockindex;
+
+ DEBUGF(infof(conn->data, "http2_send len=%zu\n", len));
+
+ if(stream->stream_id != -1) {
+ /* If stream_id != -1, we have dispatched request HEADERS, and now
+ are going to send or sending request body in DATA frame */
+ stream->upload_mem = mem;
+ stream->upload_len = len;
+ nghttp2_session_resume_data(h2, stream->stream_id);
+ rv = nghttp2_session_send(h2);
+ if(nghttp2_is_fatal(rv)) {
+ *err = CURLE_SEND_ERROR;
+ return -1;
+ }
+ len -= stream->upload_len;
+
+ /* Nullify here because we call nghttp2_session_send() and they
+ might refer to the old buffer. */
+ stream->upload_mem = NULL;
+ stream->upload_len = 0;
+
+ if(stream->upload_left) {
+ /* we are sure that we have more data to send here. Calling the
+ following API will make nghttp2_session_want_write() return
+ nonzero if remote window allows it, which then libcurl checks
+ socket is writable or not. See http2_perform_getsock(). */
+ nghttp2_session_resume_data(h2, stream->stream_id);
+ }
+
+ DEBUGF(infof(conn->data, "http2_send returns %zu for stream %u\n", len,
+ stream->stream_id));
+ return len;
+ }
+
+ /* Calculate number of headers contained in [mem, mem + len) */
+ /* Here, we assume the curl http code generate *correct* HTTP header
+ field block */
+ nheader = 0;
+ for(i = 0; i < len; ++i) {
+ if(hdbuf[i] == 0x0a) {
+ ++nheader;
+ }
+ }
+ /* We counted additional 2 \n in the first and last line. We need 3
+ new headers: :method, :path and :scheme. Therefore we need one
+ more space. */
+ nheader += 1;
+ nva = malloc(sizeof(nghttp2_nv) * nheader);
+ if(nva == NULL) {
+ *err = CURLE_OUT_OF_MEMORY;
+ return -1;
+ }
+ /* Extract :method, :path from request line */
+ end = strchr(hdbuf, ' ');
+ if(!end)
+ goto fail;
+ nva[0].name = (unsigned char *)":method";
+ nva[0].namelen = (uint16_t)strlen((char *)nva[0].name);
+ nva[0].value = (unsigned char *)hdbuf;
+ nva[0].valuelen = (uint16_t)(end - hdbuf);
+ nva[0].flags = NGHTTP2_NV_FLAG_NONE;
+
+ hdbuf = end + 1;
+
+ end = strchr(hdbuf, ' ');
+ if(!end)
+ goto fail;
+ nva[1].name = (unsigned char *)":path";
+ nva[1].namelen = (uint16_t)strlen((char *)nva[1].name);
+ nva[1].value = (unsigned char *)hdbuf;
+ nva[1].valuelen = (uint16_t)(end - hdbuf);
+ nva[1].flags = NGHTTP2_NV_FLAG_NONE;
+
+ nva[2].name = (unsigned char *)":scheme";
+ nva[2].namelen = (uint16_t)strlen((char *)nva[2].name);
+ if(conn->handler->flags & PROTOPT_SSL)
+ nva[2].value = (unsigned char *)"https";
+ else
+ nva[2].value = (unsigned char *)"http";
+ nva[2].valuelen = (uint16_t)strlen((char *)nva[2].value);
+ nva[2].flags = NGHTTP2_NV_FLAG_NONE;
+
+ hdbuf = strchr(hdbuf, 0x0a);
+ if(!hdbuf)
+ goto fail;
+ ++hdbuf;
+
+ authority_idx = 0;
+
+ for(i = 3; i < nheader; ++i) {
+ end = strchr(hdbuf, ':');
+ if(!end)
+ goto fail;
+ if(end - hdbuf == 4 && Curl_raw_nequal("host", hdbuf, 4)) {
+ authority_idx = i;
+ nva[i].name = (unsigned char *)":authority";
+ nva[i].namelen = (uint16_t)strlen((char *)nva[i].name);
+ }
+ else {
+ nva[i].name = (unsigned char *)hdbuf;
+ nva[i].namelen = (uint16_t)(end - hdbuf);
+ }
+ hdbuf = end + 1;
+ for(; *hdbuf == ' '; ++hdbuf);
+ end = strchr(hdbuf, 0x0d);
+ if(!end)
+ goto fail;
+ nva[i].value = (unsigned char *)hdbuf;
+ nva[i].valuelen = (uint16_t)(end - hdbuf);
+ nva[i].flags = NGHTTP2_NV_FLAG_NONE;
+
+ hdbuf = end + 2;
+ /* Inspect Content-Length header field and retrieve the request
+ entity length so that we can set END_STREAM to the last DATA
+ frame. */
+ if(nva[i].namelen == 14 &&
+ Curl_raw_nequal("content-length", (char*)nva[i].name, 14)) {
+ size_t j;
+ stream->upload_left = 0;
+ for(j = 0; j < nva[i].valuelen; ++j) {
+ stream->upload_left *= 10;
+ stream->upload_left += nva[i].value[j] - '0';
+ }
+ DEBUGF(infof(conn->data,
+ "request content-length=%"
+ CURL_FORMAT_CURL_OFF_T
+ "\n", stream->upload_left));
+ }
+ }
+
+ /* :authority must come before non-pseudo header fields */
+ if(authority_idx != 0 && authority_idx != AUTHORITY_DST_IDX) {
+ nghttp2_nv authority = nva[authority_idx];
+ for(i = authority_idx; i > AUTHORITY_DST_IDX; --i) {
+ nva[i] = nva[i - 1];
+ }
+ nva[i] = authority;
+ }
+
+ switch(conn->data->set.httpreq) {
+ case HTTPREQ_POST:
+ case HTTPREQ_POST_FORM:
+ case HTTPREQ_PUT:
+ data_prd.read_callback = data_source_read_callback;
+ data_prd.source.ptr = NULL;
+ stream_id = nghttp2_submit_request(h2, NULL, nva, nheader,
+ &data_prd, conn->data);
+ break;
+ default:
+ stream_id = nghttp2_submit_request(h2, NULL, nva, nheader,
+ NULL, conn->data);
+ }
+
+ Curl_safefree(nva);
+
+ if(stream_id < 0) {
+ DEBUGF(infof(conn->data, "http2_send() send error\n"));
+ *err = CURLE_SEND_ERROR;
+ return -1;
+ }
+
+ infof(conn->data, "Using Stream ID: %x (easy handle %p)\n",
+ stream_id, conn->data);
+ stream->stream_id = stream_id;
+
+ rv = nghttp2_session_send(h2);
+
+ if(rv != 0) {
+ *err = CURLE_SEND_ERROR;
+ return -1;
+ }
+
+ if(stream->stream_id != -1) {
+ /* If whole HEADERS frame was sent off to the underlying socket,
+ the nghttp2 library calls data_source_read_callback. But only
+ it found that no data available, so it deferred the DATA
+ transmission. Which means that nghttp2_session_want_write()
+ returns 0 on http2_perform_getsock(), which results that no
+ writable socket check is performed. To workaround this, we
+ issue nghttp2_session_resume_data() here to bring back DATA
+ transmission from deferred state. */
+ nghttp2_session_resume_data(h2, stream->stream_id);
+ }
+
+ return len;
+
+ fail:
+ free(nva);
+ *err = CURLE_SEND_ERROR;
+ return -1;
+}
+
+CURLcode Curl_http2_setup(struct connectdata *conn)
+{
+ CURLcode result;
+ struct http_conn *httpc = &conn->proto.httpc;
+ struct HTTP *stream = conn->data->req.protop;
+
+ stream->stream_id = -1;
+
+ if(!stream->header_recvbuf)
+ stream->header_recvbuf = Curl_add_buffer_init();
+
+ if((conn->handler == &Curl_handler_http2_ssl) ||
+ (conn->handler == &Curl_handler_http2))
+ return CURLE_OK; /* already done */
+
+ if(conn->handler->flags & PROTOPT_SSL)
+ conn->handler = &Curl_handler_http2_ssl;
+ else
+ conn->handler = &Curl_handler_http2;
+
+ result = Curl_http2_init(conn);
+ if(result)
+ return result;
+
+ infof(conn->data, "Using HTTP2, server supports multi-use\n");
+ stream->upload_left = 0;
+ stream->upload_mem = NULL;
+ stream->upload_len = 0;
+
+ httpc->inbuflen = 0;
+ httpc->nread_inbuf = 0;
+
+ httpc->pause_stream_id = 0;
+
+ conn->bits.multiplex = TRUE; /* at least potentially multiplexed */
+ conn->httpversion = 20;
+ conn->bundle->multiuse = BUNDLE_MULTIPLEX;
+
+ infof(conn->data, "Connection state changed (HTTP/2 confirmed)\n");
+ Curl_multi_connchanged(conn->data->multi);
+
+ return CURLE_OK;
+}
+
+CURLcode Curl_http2_switched(struct connectdata *conn,
+ const char *mem, size_t nread)
+{
+ CURLcode result;
+ struct http_conn *httpc = &conn->proto.httpc;
+ int rv;
+ ssize_t nproc;
+ struct SessionHandle *data = conn->data;
+ struct HTTP *stream = conn->data->req.protop;
+
+ result = Curl_http2_setup(conn);
+ if(result)
+ return result;
+
+ httpc->recv_underlying = (recving)conn->recv[FIRSTSOCKET];
+ httpc->send_underlying = (sending)conn->send[FIRSTSOCKET];
+ conn->recv[FIRSTSOCKET] = http2_recv;
+ conn->send[FIRSTSOCKET] = http2_send;
+
+ if(conn->data->req.upgr101 == UPGR101_RECEIVED) {
+ /* stream 1 is opened implicitly on upgrade */
+ stream->stream_id = 1;
+ /* queue SETTINGS frame (again) */
+ rv = nghttp2_session_upgrade(httpc->h2, httpc->binsettings,
+ httpc->binlen, NULL);
+ if(rv != 0) {
+ failf(data, "nghttp2_session_upgrade() failed: %s(%d)",
+ nghttp2_strerror(rv), rv);
+ return CURLE_HTTP2;
+ }
+
+ nghttp2_session_set_stream_user_data(httpc->h2,
+ stream->stream_id,
+ conn->data);
+ }
+ else {
+ /* stream ID is unknown at this point */
+ stream->stream_id = -1;
+ rv = nghttp2_submit_settings(httpc->h2, NGHTTP2_FLAG_NONE, NULL, 0);
+ if(rv != 0) {
+ failf(data, "nghttp2_submit_settings() failed: %s(%d)",
+ nghttp2_strerror(rv), rv);
+ return CURLE_HTTP2;
+ }
+ }
+
+ /* we are going to copy mem to httpc->inbuf. This is required since
+ mem is part of buffer pointed by stream->mem, and callbacks
+ called by nghttp2_session_mem_recv() will write stream specific
+ data into stream->mem, overwriting data already there. */
+ if(H2_BUFSIZE < nread) {
+ failf(data, "connection buffer size is too small to store data following "
+ "HTTP Upgrade response header: buflen=%zu, datalen=%zu",
+ H2_BUFSIZE, nread);
+ return CURLE_HTTP2;
+ }
+
+ infof(conn->data, "Copying HTTP/2 data in stream buffer to connection buffer"
+ " after upgrade: len=%zu\n",
+ nread);
+
+ memcpy(httpc->inbuf, mem, nread);
+ httpc->inbuflen = nread;
+
+ nproc = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)httpc->inbuf,
+ httpc->inbuflen);
+
+ if(nghttp2_is_fatal((int)nproc)) {
+ failf(data, "nghttp2_session_mem_recv() failed: %s(%d)",
+ nghttp2_strerror((int)nproc), (int)nproc);
+ return CURLE_HTTP2;
+ }
+
+ DEBUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", nproc));
+
+ if((ssize_t)nread == nproc) {
+ httpc->inbuflen = 0;
+ httpc->nread_inbuf = 0;
+ }
+ else {
+ httpc->nread_inbuf += nproc;
+ }
+
+ /* Try to send some frames since we may read SETTINGS already. */
+ rv = nghttp2_session_send(httpc->h2);
+
+ if(rv != 0) {
+ failf(data, "nghttp2_session_send() failed: %s(%d)",
+ nghttp2_strerror(rv), rv);
+ return CURLE_HTTP2;
+ }
+
+ return CURLE_OK;
+}
+
+#else /* !USE_NGHTTP2 */
+
+/* Satisfy external references even if http2 is not compiled in. */
+
+#define CURL_DISABLE_TYPECHECK
+#include <curl/curl.h>
+
+char *curl_pushheader_bynum(struct curl_pushheaders *h, size_t num)
+{
+ (void) h;
+ (void) num;
+ return NULL;
+}
+
+char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header)
+{
+ (void) h;
+ (void) header;
+ return NULL;
+}
+
+#endif /* USE_NGHTTP2 */
diff --git a/Utilities/cmcurl/lib/http2.h b/Utilities/cmcurl/lib/http2.h
new file mode 100644
index 000000000..bb7ad9c4c
--- /dev/null
+++ b/Utilities/cmcurl/lib/http2.h
@@ -0,0 +1,61 @@
+#ifndef HEADER_CURL_HTTP2_H
+#define HEADER_CURL_HTTP2_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_NGHTTP2
+#include "http.h"
+
+/* value for MAX_CONCURRENT_STREAMS we use until we get an updated setting
+ from the peer */
+#define DEFAULT_MAX_CONCURRENT_STREAMS 13
+
+/*
+ * Store nghttp2 version info in this buffer, Prefix with a space. Return
+ * total length written.
+ */
+int Curl_http2_ver(char *p, size_t len);
+
+CURLcode Curl_http2_init(struct connectdata *conn);
+CURLcode Curl_http2_send_request(struct connectdata *conn);
+CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
+ struct connectdata *conn);
+CURLcode Curl_http2_setup(struct connectdata *conn);
+CURLcode Curl_http2_switched(struct connectdata *conn,
+ const char *data, size_t nread);
+/* called from Curl_http_setup_conn */
+void Curl_http2_setup_conn(struct connectdata *conn);
+void Curl_http2_setup_req(struct SessionHandle *data);
+#else /* USE_NGHTTP2 */
+#define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL
+#define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL
+#define Curl_http2_request_upgrade(x,y) CURLE_UNSUPPORTED_PROTOCOL
+#define Curl_http2_setup(x) CURLE_UNSUPPORTED_PROTOCOL
+#define Curl_http2_switched(x,y,z) CURLE_UNSUPPORTED_PROTOCOL
+#define Curl_http2_setup_conn(x)
+#define Curl_http2_setup_req(x)
+#endif
+
+#endif /* HEADER_CURL_HTTP2_H */
+
diff --git a/Utilities/cmcurl/lib/http_chunks.c b/Utilities/cmcurl/lib/http_chunks.c
new file mode 100644
index 000000000..7e91b37dc
--- /dev/null
+++ b/Utilities/cmcurl/lib/http_chunks.c
@@ -0,0 +1,381 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_HTTP
+
+#include "urldata.h" /* it includes http_chunks.h */
+#include "sendf.h" /* for the client write stuff */
+
+#include "content_encoding.h"
+#include "http.h"
+#include "non-ascii.h" /* for Curl_convert_to_network prototype */
+#include "strtoofft.h"
+#include "warnless.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+ * Chunk format (simplified):
+ *
+ * <HEX SIZE>[ chunk extension ] CRLF
+ * <DATA> CRLF
+ *
+ * Highlights from RFC2616 section 3.6 say:
+
+ The chunked encoding modifies the body of a message in order to
+ transfer it as a series of chunks, each with its own size indicator,
+ followed by an OPTIONAL trailer containing entity-header fields. This
+ allows dynamically produced content to be transferred along with the
+ information necessary for the recipient to verify that it has
+ received the full message.
+
+ Chunked-Body = *chunk
+ last-chunk
+ trailer
+ CRLF
+
+ chunk = chunk-size [ chunk-extension ] CRLF
+ chunk-data CRLF
+ chunk-size = 1*HEX
+ last-chunk = 1*("0") [ chunk-extension ] CRLF
+
+ chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
+ chunk-ext-name = token
+ chunk-ext-val = token | quoted-string
+ chunk-data = chunk-size(OCTET)
+ trailer = *(entity-header CRLF)
+
+ The chunk-size field is a string of hex digits indicating the size of
+ the chunk. The chunked encoding is ended by any chunk whose size is
+ zero, followed by the trailer, which is terminated by an empty line.
+
+ */
+
+/* Check for an ASCII hex digit.
+ We avoid the use of isxdigit to accommodate non-ASCII hosts. */
+static bool Curl_isxdigit(char digit)
+{
+ return ( (digit >= 0x30 && digit <= 0x39) /* 0-9 */
+ || (digit >= 0x41 && digit <= 0x46) /* A-F */
+ || (digit >= 0x61 && digit <= 0x66) /* a-f */ ) ? TRUE : FALSE;
+}
+
+void Curl_httpchunk_init(struct connectdata *conn)
+{
+ struct Curl_chunker *chunk = &conn->chunk;
+ chunk->hexindex=0; /* start at 0 */
+ chunk->dataleft=0; /* no data left yet! */
+ chunk->state = CHUNK_HEX; /* we get hex first! */
+}
+
+/*
+ * chunk_read() returns a OK for normal operations, or a positive return code
+ * for errors. STOP means this sequence of chunks is complete. The 'wrote'
+ * argument is set to tell the caller how many bytes we actually passed to the
+ * client (for byte-counting and whatever).
+ *
+ * The states and the state-machine is further explained in the header file.
+ *
+ * This function always uses ASCII hex values to accommodate non-ASCII hosts.
+ * For example, 0x0d and 0x0a are used instead of '\r' and '\n'.
+ */
+CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
+ char *datap,
+ ssize_t datalen,
+ ssize_t *wrotep)
+{
+ CURLcode result=CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct Curl_chunker *ch = &conn->chunk;
+ struct SingleRequest *k = &data->req;
+ size_t piece;
+ curl_off_t length = (curl_off_t)datalen;
+ size_t *wrote = (size_t *)wrotep;
+
+ *wrote = 0; /* nothing's written yet */
+
+ /* the original data is written to the client, but we go on with the
+ chunk read process, to properly calculate the content length*/
+ if(data->set.http_te_skip && !k->ignorebody) {
+ result = Curl_client_write(conn, CLIENTWRITE_BODY, datap, datalen);
+ if(result)
+ return CHUNKE_WRITE_ERROR;
+ }
+
+ while(length) {
+ switch(ch->state) {
+ case CHUNK_HEX:
+ if(Curl_isxdigit(*datap)) {
+ if(ch->hexindex < MAXNUM_SIZE) {
+ ch->hexbuffer[ch->hexindex] = *datap;
+ datap++;
+ length--;
+ ch->hexindex++;
+ }
+ else {
+ return CHUNKE_TOO_LONG_HEX; /* longer hex than we support */
+ }
+ }
+ else {
+ char *endptr;
+ if(0 == ch->hexindex)
+ /* This is illegal data, we received junk where we expected
+ a hexadecimal digit. */
+ return CHUNKE_ILLEGAL_HEX;
+
+ /* length and datap are unmodified */
+ ch->hexbuffer[ch->hexindex]=0;
+
+ /* convert to host encoding before calling strtoul */
+ result = Curl_convert_from_network(conn->data, ch->hexbuffer,
+ ch->hexindex);
+ if(result) {
+ /* Curl_convert_from_network calls failf if unsuccessful */
+ /* Treat it as a bad hex character */
+ return CHUNKE_ILLEGAL_HEX;
+ }
+
+ ch->datasize=curlx_strtoofft(ch->hexbuffer, &endptr, 16);
+ if((ch->datasize == CURL_OFF_T_MAX) && (errno == ERANGE))
+ /* overflow is an error */
+ return CHUNKE_ILLEGAL_HEX;
+ ch->state = CHUNK_LF; /* now wait for the CRLF */
+ }
+ break;
+
+ case CHUNK_LF:
+ /* waiting for the LF after a chunk size */
+ if(*datap == 0x0a) {
+ /* we're now expecting data to come, unless size was zero! */
+ if(0 == ch->datasize) {
+ ch->state = CHUNK_TRAILER; /* now check for trailers */
+ conn->trlPos=0;
+ }
+ else
+ ch->state = CHUNK_DATA;
+ }
+
+ datap++;
+ length--;
+ break;
+
+ case CHUNK_DATA:
+ /* We expect 'datasize' of data. We have 'length' right now, it can be
+ more or less than 'datasize'. Get the smallest piece.
+ */
+ piece = curlx_sotouz((ch->datasize >= length)?length:ch->datasize);
+
+ /* Write the data portion available */
+#ifdef HAVE_LIBZ
+ switch (conn->data->set.http_ce_skip?
+ IDENTITY : data->req.auto_decoding) {
+ case IDENTITY:
+#endif
+ if(!k->ignorebody) {
+ if(!data->set.http_te_skip)
+ result = Curl_client_write(conn, CLIENTWRITE_BODY, datap,
+ piece);
+ else
+ result = CURLE_OK;
+ }
+#ifdef HAVE_LIBZ
+ break;
+
+ case DEFLATE:
+ /* update data->req.keep.str to point to the chunk data. */
+ data->req.str = datap;
+ result = Curl_unencode_deflate_write(conn, &data->req,
+ (ssize_t)piece);
+ break;
+
+ case GZIP:
+ /* update data->req.keep.str to point to the chunk data. */
+ data->req.str = datap;
+ result = Curl_unencode_gzip_write(conn, &data->req,
+ (ssize_t)piece);
+ break;
+
+ default:
+ failf (conn->data,
+ "Unrecognized content encoding type. "
+ "libcurl understands `identity', `deflate' and `gzip' "
+ "content encodings.");
+ return CHUNKE_BAD_ENCODING;
+ }
+#endif
+
+ if(result)
+ return CHUNKE_WRITE_ERROR;
+
+ *wrote += piece;
+
+ ch->datasize -= piece; /* decrease amount left to expect */
+ datap += piece; /* move read pointer forward */
+ length -= piece; /* decrease space left in this round */
+
+ if(0 == ch->datasize)
+ /* end of data this round, we now expect a trailing CRLF */
+ ch->state = CHUNK_POSTLF;
+ break;
+
+ case CHUNK_POSTLF:
+ if(*datap == 0x0a) {
+ /* The last one before we go back to hex state and start all over. */
+ Curl_httpchunk_init(conn); /* sets state back to CHUNK_HEX */
+ }
+ else if(*datap != 0x0d)
+ return CHUNKE_BAD_CHUNK;
+ datap++;
+ length--;
+ break;
+
+ case CHUNK_TRAILER:
+ if((*datap == 0x0d) || (*datap == 0x0a)) {
+ /* this is the end of a trailer, but if the trailer was zero bytes
+ there was no trailer and we move on */
+
+ if(conn->trlPos) {
+ /* we allocate trailer with 3 bytes extra room to fit this */
+ conn->trailer[conn->trlPos++]=0x0d;
+ conn->trailer[conn->trlPos++]=0x0a;
+ conn->trailer[conn->trlPos]=0;
+
+ /* Convert to host encoding before calling Curl_client_write */
+ result = Curl_convert_from_network(conn->data, conn->trailer,
+ conn->trlPos);
+ if(result)
+ /* Curl_convert_from_network calls failf if unsuccessful */
+ /* Treat it as a bad chunk */
+ return CHUNKE_BAD_CHUNK;
+
+ if(!data->set.http_te_skip) {
+ result = Curl_client_write(conn, CLIENTWRITE_HEADER,
+ conn->trailer, conn->trlPos);
+ if(result)
+ return CHUNKE_WRITE_ERROR;
+ }
+ conn->trlPos=0;
+ ch->state = CHUNK_TRAILER_CR;
+ if(*datap == 0x0a)
+ /* already on the LF */
+ break;
+ }
+ else {
+ /* no trailer, we're on the final CRLF pair */
+ ch->state = CHUNK_TRAILER_POSTCR;
+ break; /* don't advance the pointer */
+ }
+ }
+ else {
+ /* conn->trailer is assumed to be freed in url.c on a
+ connection basis */
+ if(conn->trlPos >= conn->trlMax) {
+ /* we always allocate three extra bytes, just because when the full
+ header has been received we append CRLF\0 */
+ char *ptr;
+ if(conn->trlMax) {
+ conn->trlMax *= 2;
+ ptr = realloc(conn->trailer, conn->trlMax + 3);
+ }
+ else {
+ conn->trlMax=128;
+ ptr = malloc(conn->trlMax + 3);
+ }
+ if(!ptr)
+ return CHUNKE_OUT_OF_MEMORY;
+ conn->trailer = ptr;
+ }
+ conn->trailer[conn->trlPos++]=*datap;
+ }
+ datap++;
+ length--;
+ break;
+
+ case CHUNK_TRAILER_CR:
+ if(*datap == 0x0a) {
+ ch->state = CHUNK_TRAILER_POSTCR;
+ datap++;
+ length--;
+ }
+ else
+ return CHUNKE_BAD_CHUNK;
+ break;
+
+ case CHUNK_TRAILER_POSTCR:
+ /* We enter this state when a CR should arrive so we expect to
+ have to first pass a CR before we wait for LF */
+ if((*datap != 0x0d) && (*datap != 0x0a)) {
+ /* not a CR then it must be another header in the trailer */
+ ch->state = CHUNK_TRAILER;
+ break;
+ }
+ if(*datap == 0x0d) {
+ /* skip if CR */
+ datap++;
+ length--;
+ }
+ /* now wait for the final LF */
+ ch->state = CHUNK_STOP;
+ break;
+
+ case CHUNK_STOP:
+ if(*datap == 0x0a) {
+ length--;
+
+ /* Record the length of any data left in the end of the buffer
+ even if there's no more chunks to read */
+ ch->dataleft = curlx_sotouz(length);
+
+ return CHUNKE_STOP; /* return stop */
+ }
+ else
+ return CHUNKE_BAD_CHUNK;
+ }
+ }
+ return CHUNKE_OK;
+}
+
+const char *Curl_chunked_strerror(CHUNKcode code)
+{
+ switch (code) {
+ default:
+ return "OK";
+ case CHUNKE_TOO_LONG_HEX:
+ return "Too long hexadecimal number";
+ case CHUNKE_ILLEGAL_HEX:
+ return "Illegal or missing hexadecimal sequence";
+ case CHUNKE_BAD_CHUNK:
+ return "Malformed encoding found";
+ case CHUNKE_WRITE_ERROR:
+ return "Write error";
+ case CHUNKE_BAD_ENCODING:
+ return "Bad content-encoding found";
+ case CHUNKE_OUT_OF_MEMORY:
+ return "Out of memory";
+ }
+}
+
+#endif /* CURL_DISABLE_HTTP */
diff --git a/Utilities/cmcurl/lib/http_chunks.h b/Utilities/cmcurl/lib/http_chunks.h
new file mode 100644
index 000000000..0489eb859
--- /dev/null
+++ b/Utilities/cmcurl/lib/http_chunks.h
@@ -0,0 +1,91 @@
+#ifndef HEADER_CURL_HTTP_CHUNKS_H
+#define HEADER_CURL_HTTP_CHUNKS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/*
+ * The longest possible hexadecimal number we support in a chunked transfer.
+ * Weird enough, RFC2616 doesn't set a maximum size! Since we use strtoul()
+ * to convert it, we "only" support 2^32 bytes chunk data.
+ */
+#define MAXNUM_SIZE 16
+
+typedef enum {
+ /* await and buffer all hexadecimal digits until we get one that isn't a
+ hexadecimal digit. When done, we go CHUNK_LF */
+ CHUNK_HEX,
+
+ /* wait for LF, ignore all else */
+ CHUNK_LF,
+
+ /* We eat the amount of data specified. When done, we move on to the
+ POST_CR state. */
+ CHUNK_DATA,
+
+ /* POSTLF should get a CR and then a LF and nothing else, then move back to
+ HEX as the CRLF combination marks the end of a chunk. A missing CR is no
+ big deal. */
+ CHUNK_POSTLF,
+
+ /* Used to mark that we're out of the game. NOTE: that there's a 'dataleft'
+ field in the struct that will tell how many bytes that were not passed to
+ the client in the end of the last buffer! */
+ CHUNK_STOP,
+
+ /* At this point optional trailer headers can be found, unless the next line
+ is CRLF */
+ CHUNK_TRAILER,
+
+ /* A trailer CR has been found - next state is CHUNK_TRAILER_POSTCR.
+ Next char must be a LF */
+ CHUNK_TRAILER_CR,
+
+ /* A trailer LF must be found now, otherwise CHUNKE_BAD_CHUNK will be
+ signalled If this is an empty trailer CHUNKE_STOP will be signalled.
+ Otherwise the trailer will be broadcasted via Curl_client_write() and the
+ next state will be CHUNK_TRAILER */
+ CHUNK_TRAILER_POSTCR
+} ChunkyState;
+
+typedef enum {
+ CHUNKE_STOP = -1,
+ CHUNKE_OK = 0,
+ CHUNKE_TOO_LONG_HEX = 1,
+ CHUNKE_ILLEGAL_HEX,
+ CHUNKE_BAD_CHUNK,
+ CHUNKE_WRITE_ERROR,
+ CHUNKE_BAD_ENCODING,
+ CHUNKE_OUT_OF_MEMORY,
+ CHUNKE_LAST
+} CHUNKcode;
+
+const char *Curl_chunked_strerror(CHUNKcode code);
+
+struct Curl_chunker {
+ char hexbuffer[ MAXNUM_SIZE + 1];
+ int hexindex;
+ ChunkyState state;
+ curl_off_t datasize;
+ size_t dataleft; /* untouched data amount at the end of the last buffer */
+};
+
+#endif /* HEADER_CURL_HTTP_CHUNKS_H */
+
diff --git a/Utilities/cmcurl/lib/http_digest.c b/Utilities/cmcurl/lib/http_digest.c
new file mode 100644
index 000000000..929e2c60f
--- /dev/null
+++ b/Utilities/cmcurl/lib/http_digest.c
@@ -0,0 +1,179 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
+
+#include "urldata.h"
+#include "rawstr.h"
+#include "curl_sasl.h"
+#include "http_digest.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* Test example headers:
+
+WWW-Authenticate: Digest realm="testrealm", nonce="1053604598"
+Proxy-Authenticate: Digest realm="testrealm", nonce="1053604598"
+
+*/
+
+CURLcode Curl_input_digest(struct connectdata *conn,
+ bool proxy,
+ const char *header) /* rest of the *-authenticate:
+ header */
+{
+ struct SessionHandle *data = conn->data;
+
+ /* Point to the correct struct with this */
+ struct digestdata *digest;
+
+ if(proxy) {
+ digest = &data->state.proxydigest;
+ }
+ else {
+ digest = &data->state.digest;
+ }
+
+ if(!checkprefix("Digest", header))
+ return CURLE_BAD_CONTENT_ENCODING;
+
+ header += strlen("Digest");
+ while(*header && ISSPACE(*header))
+ header++;
+
+ return Curl_sasl_decode_digest_http_message(header, digest);
+}
+
+CURLcode Curl_output_digest(struct connectdata *conn,
+ bool proxy,
+ const unsigned char *request,
+ const unsigned char *uripath)
+{
+ CURLcode result;
+ struct SessionHandle *data = conn->data;
+ unsigned char *path;
+ char *tmp;
+ char *response;
+ size_t len;
+ bool have_chlg;
+
+ /* Point to the address of the pointer that holds the string to send to the
+ server, which is for a plain host or for a HTTP proxy */
+ char **allocuserpwd;
+
+ /* Point to the name and password for this */
+ const char *userp;
+ const char *passwdp;
+
+ /* Point to the correct struct with this */
+ struct digestdata *digest;
+ struct auth *authp;
+
+ if(proxy) {
+ digest = &data->state.proxydigest;
+ allocuserpwd = &conn->allocptr.proxyuserpwd;
+ userp = conn->proxyuser;
+ passwdp = conn->proxypasswd;
+ authp = &data->state.authproxy;
+ }
+ else {
+ digest = &data->state.digest;
+ allocuserpwd = &conn->allocptr.userpwd;
+ userp = conn->user;
+ passwdp = conn->passwd;
+ authp = &data->state.authhost;
+ }
+
+ Curl_safefree(*allocuserpwd);
+
+ /* not set means empty */
+ if(!userp)
+ userp = "";
+
+ if(!passwdp)
+ passwdp = "";
+
+#if defined(USE_WINDOWS_SSPI)
+ have_chlg = digest->input_token ? TRUE : FALSE;
+#else
+ have_chlg = digest->nonce ? TRUE : FALSE;
+#endif
+
+ if(!have_chlg) {
+ authp->done = FALSE;
+ return CURLE_OK;
+ }
+
+ /* So IE browsers < v7 cut off the URI part at the query part when they
+ evaluate the MD5 and some (IIS?) servers work with them so we may need to
+ do the Digest IE-style. Note that the different ways cause different MD5
+ sums to get sent.
+
+ Apache servers can be set to do the Digest IE-style automatically using
+ the BrowserMatch feature:
+ http://httpd.apache.org/docs/2.2/mod/mod_auth_digest.html#msie
+
+ Further details on Digest implementation differences:
+ http://www.fngtps.com/2006/09/http-authentication
+ */
+
+ if(authp->iestyle && ((tmp = strchr((char *)uripath, '?')) != NULL)) {
+ size_t urilen = tmp - (char *)uripath;
+
+ path = (unsigned char *) aprintf("%.*s", urilen, uripath);
+ }
+ else
+ path = (unsigned char *) strdup((char *) uripath);
+
+ if(!path)
+ return CURLE_OUT_OF_MEMORY;
+
+ result = Curl_sasl_create_digest_http_message(data, userp, passwdp, request,
+ path, digest, &response, &len);
+ free(path);
+ if(result)
+ return result;
+
+ *allocuserpwd = aprintf("%sAuthorization: Digest %s\r\n",
+ proxy ? "Proxy-" : "",
+ response);
+ free(response);
+ if(!*allocuserpwd)
+ return CURLE_OUT_OF_MEMORY;
+
+ authp->done = TRUE;
+
+ return CURLE_OK;
+}
+
+void Curl_digest_cleanup(struct SessionHandle *data)
+{
+ Curl_sasl_digest_cleanup(&data->state.digest);
+ Curl_sasl_digest_cleanup(&data->state.proxydigest);
+}
+
+#endif
diff --git a/Utilities/cmcurl/lib/http_digest.h b/Utilities/cmcurl/lib/http_digest.h
new file mode 100644
index 000000000..d13d56374
--- /dev/null
+++ b/Utilities/cmcurl/lib/http_digest.h
@@ -0,0 +1,42 @@
+#ifndef HEADER_CURL_HTTP_DIGEST_H
+#define HEADER_CURL_HTTP_DIGEST_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+/* this is for digest header input */
+CURLcode Curl_input_digest(struct connectdata *conn,
+ bool proxy, const char *header);
+
+/* this is for creating digest header output */
+CURLcode Curl_output_digest(struct connectdata *conn,
+ bool proxy,
+ const unsigned char *request,
+ const unsigned char *uripath);
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
+void Curl_digest_cleanup(struct SessionHandle *data);
+#else
+#define Curl_digest_cleanup(x) Curl_nop_stmt
+#endif
+
+#endif /* HEADER_CURL_HTTP_DIGEST_H */
diff --git a/Utilities/cmcurl/lib/http_negotiate.c b/Utilities/cmcurl/lib/http_negotiate.c
new file mode 100644
index 000000000..a1baf29c3
--- /dev/null
+++ b/Utilities/cmcurl/lib/http_negotiate.c
@@ -0,0 +1,210 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(HAVE_GSSAPI) && !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO)
+
+#include "urldata.h"
+#include "sendf.h"
+#include "curl_gssapi.h"
+#include "rawstr.h"
+#include "curl_base64.h"
+#include "http_negotiate.h"
+#include "curl_sasl.h"
+#include "url.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
+ const char *header)
+{
+ struct SessionHandle *data = conn->data;
+ struct negotiatedata *neg_ctx = proxy?&data->state.proxyneg:
+ &data->state.negotiate;
+ OM_uint32 major_status, minor_status, discard_st;
+ gss_buffer_desc spn_token = GSS_C_EMPTY_BUFFER;
+ gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
+ gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+ size_t len;
+ size_t rawlen = 0;
+ CURLcode result;
+
+ if(neg_ctx->context && neg_ctx->status == GSS_S_COMPLETE) {
+ /* We finished successfully our part of authentication, but server
+ * rejected it (since we're again here). Exit with an error since we
+ * can't invent anything better */
+ Curl_cleanup_negotiate(data);
+ return CURLE_LOGIN_DENIED;
+ }
+
+ if(!neg_ctx->server_name) {
+ /* Generate our SPN */
+ char *spn = Curl_sasl_build_gssapi_spn(
+ proxy ? data->set.str[STRING_PROXY_SERVICE_NAME] :
+ data->set.str[STRING_SERVICE_NAME],
+ proxy ? conn->proxy.name : conn->host.name);
+ if(!spn)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Populate the SPN structure */
+ spn_token.value = spn;
+ spn_token.length = strlen(spn);
+
+ /* Import the SPN */
+ major_status = gss_import_name(&minor_status, &spn_token,
+ GSS_C_NT_HOSTBASED_SERVICE,
+ &neg_ctx->server_name);
+ if(GSS_ERROR(major_status)) {
+ Curl_gss_log_error(data, minor_status, "gss_import_name() failed: ");
+
+ free(spn);
+
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ free(spn);
+ }
+
+ header += strlen("Negotiate");
+ while(*header && ISSPACE(*header))
+ header++;
+
+ len = strlen(header);
+ if(len > 0) {
+ result = Curl_base64_decode(header, (unsigned char **)&input_token.value,
+ &rawlen);
+ if(result)
+ return result;
+
+ if(!rawlen) {
+ infof(data, "Negotiate handshake failure (empty challenge message)\n");
+
+ return CURLE_BAD_CONTENT_ENCODING;
+ }
+
+ input_token.length = rawlen;
+
+ DEBUGASSERT(input_token.value != NULL);
+ }
+
+ major_status = Curl_gss_init_sec_context(data,
+ &minor_status,
+ &neg_ctx->context,
+ neg_ctx->server_name,
+ &Curl_spnego_mech_oid,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ &input_token,
+ &output_token,
+ TRUE,
+ NULL);
+ Curl_safefree(input_token.value);
+
+ neg_ctx->status = major_status;
+ if(GSS_ERROR(major_status)) {
+ if(output_token.value)
+ gss_release_buffer(&discard_st, &output_token);
+ Curl_gss_log_error(conn->data, minor_status,
+ "gss_init_sec_context() failed: ");
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ if(!output_token.value || !output_token.length) {
+ if(output_token.value)
+ gss_release_buffer(&discard_st, &output_token);
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ neg_ctx->output_token = output_token;
+
+ return CURLE_OK;
+}
+
+CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
+{
+ struct negotiatedata *neg_ctx = proxy?&conn->data->state.proxyneg:
+ &conn->data->state.negotiate;
+ char *encoded = NULL;
+ size_t len = 0;
+ char *userp;
+ CURLcode result;
+ OM_uint32 discard_st;
+
+ result = Curl_base64_encode(conn->data,
+ neg_ctx->output_token.value,
+ neg_ctx->output_token.length,
+ &encoded, &len);
+ if(result) {
+ gss_release_buffer(&discard_st, &neg_ctx->output_token);
+ neg_ctx->output_token.value = NULL;
+ neg_ctx->output_token.length = 0;
+ return result;
+ }
+
+ if(!encoded || !len) {
+ gss_release_buffer(&discard_st, &neg_ctx->output_token);
+ neg_ctx->output_token.value = NULL;
+ neg_ctx->output_token.length = 0;
+ return CURLE_REMOTE_ACCESS_DENIED;
+ }
+
+ userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "",
+ encoded);
+ if(proxy) {
+ Curl_safefree(conn->allocptr.proxyuserpwd);
+ conn->allocptr.proxyuserpwd = userp;
+ }
+ else {
+ Curl_safefree(conn->allocptr.userpwd);
+ conn->allocptr.userpwd = userp;
+ }
+
+ free(encoded);
+
+ return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;
+}
+
+static void cleanup(struct negotiatedata *neg_ctx)
+{
+ OM_uint32 minor_status;
+ if(neg_ctx->context != GSS_C_NO_CONTEXT)
+ gss_delete_sec_context(&minor_status, &neg_ctx->context, GSS_C_NO_BUFFER);
+
+ if(neg_ctx->output_token.value)
+ gss_release_buffer(&minor_status, &neg_ctx->output_token);
+
+ if(neg_ctx->server_name != GSS_C_NO_NAME)
+ gss_release_name(&minor_status, &neg_ctx->server_name);
+
+ memset(neg_ctx, 0, sizeof(*neg_ctx));
+}
+
+void Curl_cleanup_negotiate(struct SessionHandle *data)
+{
+ cleanup(&data->state.negotiate);
+ cleanup(&data->state.proxyneg);
+}
+
+#endif /* HAVE_GSSAPI && !CURL_DISABLE_HTTP && USE_SPNEGO */
diff --git a/Utilities/cmcurl/lib/http_negotiate.h b/Utilities/cmcurl/lib/http_negotiate.h
new file mode 100644
index 000000000..a8eb98016
--- /dev/null
+++ b/Utilities/cmcurl/lib/http_negotiate.h
@@ -0,0 +1,42 @@
+#ifndef HEADER_CURL_HTTP_NEGOTIATE_H
+#define HEADER_CURL_HTTP_NEGOTIATE_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifdef USE_SPNEGO
+
+/* this is for Negotiate header input */
+CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
+ const char *header);
+
+/* this is for creating Negotiate header output */
+CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy);
+
+void Curl_cleanup_negotiate(struct SessionHandle *data);
+
+#ifdef USE_WINDOWS_SSPI
+#define GSS_ERROR(status) (status & 0x80000000)
+#endif
+
+#endif /* USE_SPNEGO */
+
+#endif /* HEADER_CURL_HTTP_NEGOTIATE_H */
diff --git a/Utilities/cmcurl/lib/http_negotiate_sspi.c b/Utilities/cmcurl/lib/http_negotiate_sspi.c
new file mode 100644
index 000000000..a50ea96f1
--- /dev/null
+++ b/Utilities/cmcurl/lib/http_negotiate_sspi.c
@@ -0,0 +1,300 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_WINDOWS_SSPI
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO)
+
+#include "urldata.h"
+#include "sendf.h"
+#include "rawstr.h"
+#include "warnless.h"
+#include "curl_base64.h"
+#include "curl_sasl.h"
+#include "http_negotiate.h"
+#include "curl_multibyte.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
+ const char *header)
+{
+ struct SessionHandle *data = conn->data;
+ BYTE *input_token = NULL;
+ SecBufferDesc out_buff_desc;
+ SecBuffer out_sec_buff;
+ SecBufferDesc in_buff_desc;
+ SecBuffer in_sec_buff;
+ SECURITY_STATUS status;
+ unsigned long attrs;
+ TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */
+ size_t len = 0, input_token_len = 0;
+ CURLcode result;
+
+ /* Point to the username and password */
+ const char *userp;
+ const char *passwdp;
+
+ /* Point to the correct struct with this */
+ struct negotiatedata *neg_ctx;
+
+ if(proxy) {
+ userp = conn->proxyuser;
+ passwdp = conn->proxypasswd;
+ neg_ctx = &data->state.proxyneg;
+ }
+ else {
+ userp = conn->user;
+ passwdp = conn->passwd;
+ neg_ctx = &data->state.negotiate;
+ }
+
+ /* Not set means empty */
+ if(!userp)
+ userp = "";
+
+ if(!passwdp)
+ passwdp = "";
+
+ if(neg_ctx->context && neg_ctx->status == SEC_E_OK) {
+ /* We finished successfully our part of authentication, but server
+ * rejected it (since we're again here). Exit with an error since we
+ * can't invent anything better */
+ Curl_cleanup_negotiate(data);
+ return CURLE_LOGIN_DENIED;
+ }
+
+ if(!neg_ctx->server_name) {
+ /* Check proxy auth requested but no given proxy name */
+ if(proxy && !conn->proxy.name)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+
+ /* Generate our SPN */
+ neg_ctx->server_name = Curl_sasl_build_spn(
+ proxy ? data->set.str[STRING_PROXY_SERVICE_NAME] :
+ data->set.str[STRING_SERVICE_NAME],
+ proxy ? conn->proxy.name : conn->host.name);
+ if(!neg_ctx->server_name)
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ if(!neg_ctx->output_token) {
+ PSecPkgInfo SecurityPackage;
+ status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *)
+ TEXT(SP_NAME_NEGOTIATE),
+ &SecurityPackage);
+ if(status != SEC_E_OK)
+ return CURLE_NOT_BUILT_IN;
+
+ /* Allocate input and output buffers according to the max token size
+ as indicated by the security package */
+ neg_ctx->token_max = SecurityPackage->cbMaxToken;
+ neg_ctx->output_token = malloc(neg_ctx->token_max);
+ s_pSecFn->FreeContextBuffer(SecurityPackage);
+ }
+
+ /* Obtain the input token, if any */
+ header += strlen("Negotiate");
+ while(*header && ISSPACE(*header))
+ header++;
+
+ len = strlen(header);
+ if(!len) {
+ /* Is this the first call in a new negotiation? */
+ if(neg_ctx->context) {
+ /* The server rejected our authentication and hasn't suppled any more
+ negotiation mechanisms */
+ return CURLE_LOGIN_DENIED;
+ }
+
+ /* We have to acquire credentials and allocate memory for the context */
+ neg_ctx->credentials = malloc(sizeof(CredHandle));
+ neg_ctx->context = malloc(sizeof(CtxtHandle));
+
+ if(!neg_ctx->credentials || !neg_ctx->context)
+ return CURLE_OUT_OF_MEMORY;
+
+ if(userp && *userp) {
+ /* Populate our identity structure */
+ result = Curl_create_sspi_identity(userp, passwdp, &neg_ctx->identity);
+ if(result)
+ return result;
+
+ /* Allow proper cleanup of the identity structure */
+ neg_ctx->p_identity = &neg_ctx->identity;
+ }
+ else
+ /* Use the current Windows user */
+ neg_ctx->p_identity = NULL;
+
+ /* Acquire our credientials handle */
+ neg_ctx->status =
+ s_pSecFn->AcquireCredentialsHandle(NULL,
+ (TCHAR *) TEXT(SP_NAME_NEGOTIATE),
+ SECPKG_CRED_OUTBOUND, NULL,
+ neg_ctx->p_identity, NULL, NULL,
+ neg_ctx->credentials, &expiry);
+ if(neg_ctx->status != SEC_E_OK)
+ return CURLE_LOGIN_DENIED;
+ }
+ else {
+ result = Curl_base64_decode(header,
+ (unsigned char **)&input_token,
+ &input_token_len);
+ if(result)
+ return result;
+
+ if(!input_token_len) {
+ infof(data,
+ "Negotiate handshake failure (empty challenge message)\n");
+
+ return CURLE_BAD_CONTENT_ENCODING;
+ }
+ }
+
+ /* Setup the "output" security buffer */
+ out_buff_desc.ulVersion = SECBUFFER_VERSION;
+ out_buff_desc.cBuffers = 1;
+ out_buff_desc.pBuffers = &out_sec_buff;
+ out_sec_buff.BufferType = SECBUFFER_TOKEN;
+ out_sec_buff.pvBuffer = neg_ctx->output_token;
+ out_sec_buff.cbBuffer = curlx_uztoul(neg_ctx->token_max);
+
+ /* Setup the "input" security buffer if present */
+ if(input_token) {
+ in_buff_desc.ulVersion = SECBUFFER_VERSION;
+ in_buff_desc.cBuffers = 1;
+ in_buff_desc.pBuffers = &in_sec_buff;
+ in_sec_buff.BufferType = SECBUFFER_TOKEN;
+ in_sec_buff.pvBuffer = input_token;
+ in_sec_buff.cbBuffer = curlx_uztoul(input_token_len);
+ }
+
+ /* Generate our message */
+ neg_ctx->status = s_pSecFn->InitializeSecurityContext(
+ neg_ctx->credentials,
+ input_token ? neg_ctx->context : NULL,
+ neg_ctx->server_name,
+ ISC_REQ_CONFIDENTIALITY,
+ 0,
+ SECURITY_NATIVE_DREP,
+ input_token ? &in_buff_desc : NULL,
+ 0,
+ neg_ctx->context,
+ &out_buff_desc,
+ &attrs,
+ &expiry);
+
+ free(input_token);
+
+ if(GSS_ERROR(neg_ctx->status))
+ return CURLE_OUT_OF_MEMORY;
+
+ if(neg_ctx->status == SEC_I_COMPLETE_NEEDED ||
+ neg_ctx->status == SEC_I_COMPLETE_AND_CONTINUE) {
+ neg_ctx->status = s_pSecFn->CompleteAuthToken(neg_ctx->context,
+ &out_buff_desc);
+ if(GSS_ERROR(neg_ctx->status))
+ return CURLE_RECV_ERROR;
+ }
+
+ neg_ctx->output_token_length = out_sec_buff.cbBuffer;
+
+ return CURLE_OK;
+}
+
+CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
+{
+ struct negotiatedata *neg_ctx = proxy?&conn->data->state.proxyneg:
+ &conn->data->state.negotiate;
+ char *encoded = NULL;
+ size_t len = 0;
+ char *userp;
+ CURLcode error;
+
+ error = Curl_base64_encode(conn->data,
+ (const char*)neg_ctx->output_token,
+ neg_ctx->output_token_length,
+ &encoded, &len);
+ if(error)
+ return error;
+
+ if(!len)
+ return CURLE_REMOTE_ACCESS_DENIED;
+
+ userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "",
+ encoded);
+
+ if(proxy) {
+ Curl_safefree(conn->allocptr.proxyuserpwd);
+ conn->allocptr.proxyuserpwd = userp;
+ }
+ else {
+ Curl_safefree(conn->allocptr.userpwd);
+ conn->allocptr.userpwd = userp;
+ }
+ free(encoded);
+ return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;
+}
+
+static void cleanup(struct negotiatedata *neg_ctx)
+{
+ /* Free our security context */
+ if(neg_ctx->context) {
+ s_pSecFn->DeleteSecurityContext(neg_ctx->context);
+ free(neg_ctx->context);
+ neg_ctx->context = NULL;
+ }
+
+ /* Free our credentials handle */
+ if(neg_ctx->credentials) {
+ s_pSecFn->FreeCredentialsHandle(neg_ctx->credentials);
+ free(neg_ctx->credentials);
+ neg_ctx->credentials = NULL;
+ }
+
+ /* Free our identity */
+ Curl_sspi_free_identity(neg_ctx->p_identity);
+ neg_ctx->p_identity = NULL;
+
+ /* Free the SPN and output token */
+ Curl_safefree(neg_ctx->server_name);
+ Curl_safefree(neg_ctx->output_token);
+
+ /* Reset any variables */
+ neg_ctx->token_max = 0;
+}
+
+void Curl_cleanup_negotiate(struct SessionHandle *data)
+{
+ cleanup(&data->state.negotiate);
+ cleanup(&data->state.proxyneg);
+}
+
+#endif /* !CURL_DISABLE_HTTP && USE_SPNEGO */
+
+#endif /* USE_WINDOWS_SSPI */
diff --git a/Utilities/cmcurl/lib/http_proxy.c b/Utilities/cmcurl/lib/http_proxy.c
new file mode 100644
index 000000000..4373d6284
--- /dev/null
+++ b/Utilities/cmcurl/lib/http_proxy.c
@@ -0,0 +1,596 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_PROXY) && !defined(CURL_DISABLE_HTTP)
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "http_proxy.h"
+#include "sendf.h"
+#include "http.h"
+#include "url.h"
+#include "select.h"
+#include "rawstr.h"
+#include "progress.h"
+#include "non-ascii.h"
+#include "connect.h"
+#include "curl_printf.h"
+#include "curlx.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+CURLcode Curl_proxy_connect(struct connectdata *conn)
+{
+ if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
+#ifndef CURL_DISABLE_PROXY
+ /* for [protocol] tunneled through HTTP proxy */
+ struct HTTP http_proxy;
+ void *prot_save;
+ CURLcode result;
+
+ /* BLOCKING */
+ /* We want "seamless" operations through HTTP proxy tunnel */
+
+ /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the
+ * member conn->proto.http; we want [protocol] through HTTP and we have
+ * to change the member temporarily for connecting to the HTTP
+ * proxy. After Curl_proxyCONNECT we have to set back the member to the
+ * original pointer
+ *
+ * This function might be called several times in the multi interface case
+ * if the proxy's CONNTECT response is not instant.
+ */
+ prot_save = conn->data->req.protop;
+ memset(&http_proxy, 0, sizeof(http_proxy));
+ conn->data->req.protop = &http_proxy;
+ connkeep(conn, "HTTP proxy CONNECT");
+ result = Curl_proxyCONNECT(conn, FIRSTSOCKET,
+ conn->host.name, conn->remote_port, FALSE);
+ conn->data->req.protop = prot_save;
+ if(CURLE_OK != result)
+ return result;
+ Curl_safefree(conn->allocptr.proxyuserpwd);
+#else
+ return CURLE_NOT_BUILT_IN;
+#endif
+ }
+ /* no HTTP tunnel proxy, just return */
+ return CURLE_OK;
+}
+
+/*
+ * Curl_proxyCONNECT() requires that we're connected to a HTTP proxy. This
+ * function will issue the necessary commands to get a seamless tunnel through
+ * this proxy. After that, the socket can be used just as a normal socket.
+ *
+ * 'blocking' set to TRUE means that this function will do the entire CONNECT
+ * + response in a blocking fashion. Should be avoided!
+ */
+
+CURLcode Curl_proxyCONNECT(struct connectdata *conn,
+ int sockindex,
+ const char *hostname,
+ int remote_port,
+ bool blocking)
+{
+ int subversion=0;
+ struct SessionHandle *data=conn->data;
+ struct SingleRequest *k = &data->req;
+ CURLcode result;
+ curl_socket_t tunnelsocket = conn->sock[sockindex];
+ curl_off_t cl=0;
+ bool closeConnection = FALSE;
+ bool chunked_encoding = FALSE;
+ long check;
+
+#define SELECT_OK 0
+#define SELECT_ERROR 1
+#define SELECT_TIMEOUT 2
+ int error = SELECT_OK;
+
+ if(conn->tunnel_state[sockindex] == TUNNEL_COMPLETE)
+ return CURLE_OK; /* CONNECT is already completed */
+
+ conn->bits.proxy_connect_closed = FALSE;
+
+ do {
+ if(TUNNEL_INIT == conn->tunnel_state[sockindex]) {
+ /* BEGIN CONNECT PHASE */
+ char *host_port;
+ Curl_send_buffer *req_buffer;
+
+ infof(data, "Establish HTTP proxy tunnel to %s:%hu\n",
+ hostname, remote_port);
+
+ /* This only happens if we've looped here due to authentication
+ reasons, and we don't really use the newly cloned URL here
+ then. Just free() it. */
+ free(data->req.newurl);
+ data->req.newurl = NULL;
+
+ /* initialize a dynamic send-buffer */
+ req_buffer = Curl_add_buffer_init();
+
+ if(!req_buffer)
+ return CURLE_OUT_OF_MEMORY;
+
+ host_port = aprintf("%s:%hu", hostname, remote_port);
+ if(!host_port) {
+ Curl_add_buffer_free(req_buffer);
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ /* Setup the proxy-authorization header, if any */
+ result = Curl_http_output_auth(conn, "CONNECT", host_port, TRUE);
+
+ free(host_port);
+
+ if(!result) {
+ char *host=(char *)"";
+ const char *proxyconn="";
+ const char *useragent="";
+ const char *http = (conn->proxytype == CURLPROXY_HTTP_1_0) ?
+ "1.0" : "1.1";
+ char *hostheader= /* host:port with IPv6 support */
+ aprintf("%s%s%s:%hu", conn->bits.ipv6_ip?"[":"",
+ hostname, conn->bits.ipv6_ip?"]":"",
+ remote_port);
+ if(!hostheader) {
+ Curl_add_buffer_free(req_buffer);
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ if(!Curl_checkProxyheaders(conn, "Host:")) {
+ host = aprintf("Host: %s\r\n", hostheader);
+ if(!host) {
+ free(hostheader);
+ Curl_add_buffer_free(req_buffer);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ }
+ if(!Curl_checkProxyheaders(conn, "Proxy-Connection:"))
+ proxyconn = "Proxy-Connection: Keep-Alive\r\n";
+
+ if(!Curl_checkProxyheaders(conn, "User-Agent:") &&
+ data->set.str[STRING_USERAGENT])
+ useragent = conn->allocptr.uagent;
+
+ result =
+ Curl_add_bufferf(req_buffer,
+ "CONNECT %s HTTP/%s\r\n"
+ "%s" /* Host: */
+ "%s" /* Proxy-Authorization */
+ "%s" /* User-Agent */
+ "%s", /* Proxy-Connection */
+ hostheader,
+ http,
+ host,
+ conn->allocptr.proxyuserpwd?
+ conn->allocptr.proxyuserpwd:"",
+ useragent,
+ proxyconn);
+
+ if(host && *host)
+ free(host);
+ free(hostheader);
+
+ if(!result)
+ result = Curl_add_custom_headers(conn, TRUE, req_buffer);
+
+ if(!result)
+ /* CRLF terminate the request */
+ result = Curl_add_bufferf(req_buffer, "\r\n");
+
+ if(!result) {
+ /* Send the connect request to the proxy */
+ /* BLOCKING */
+ result =
+ Curl_add_buffer_send(req_buffer, conn,
+ &data->info.request_size, 0, sockindex);
+ }
+ req_buffer = NULL;
+ if(result)
+ failf(data, "Failed sending CONNECT to proxy");
+ }
+
+ Curl_add_buffer_free(req_buffer);
+ if(result)
+ return result;
+
+ conn->tunnel_state[sockindex] = TUNNEL_CONNECT;
+ } /* END CONNECT PHASE */
+
+ check = Curl_timeleft(data, NULL, TRUE);
+ if(check <= 0) {
+ failf(data, "Proxy CONNECT aborted due to timeout");
+ return CURLE_RECV_ERROR;
+ }
+
+ if(!blocking) {
+ if(0 == Curl_socket_ready(tunnelsocket, CURL_SOCKET_BAD, 0))
+ /* return so we'll be called again polling-style */
+ return CURLE_OK;
+ else {
+ DEBUGF(infof(data,
+ "Read response immediately from proxy CONNECT\n"));
+ }
+ }
+
+ /* at this point, the tunnel_connecting phase is over. */
+
+ { /* READING RESPONSE PHASE */
+ size_t nread; /* total size read */
+ int perline; /* count bytes per line */
+ int keepon=TRUE;
+ ssize_t gotbytes;
+ char *ptr;
+ char *line_start;
+
+ ptr=data->state.buffer;
+ line_start = ptr;
+
+ nread=0;
+ perline=0;
+
+ while((nread<BUFSIZE) && (keepon && !error)) {
+
+ check = Curl_timeleft(data, NULL, TRUE);
+ if(check <= 0) {
+ failf(data, "Proxy CONNECT aborted due to timeout");
+ error = SELECT_TIMEOUT; /* already too little time */
+ break;
+ }
+
+ /* loop every second at least, less if the timeout is near */
+ switch (Curl_socket_ready(tunnelsocket, CURL_SOCKET_BAD,
+ check<1000L?check:1000)) {
+ case -1: /* select() error, stop reading */
+ error = SELECT_ERROR;
+ failf(data, "Proxy CONNECT aborted due to select/poll error");
+ break;
+ case 0: /* timeout */
+ break;
+ default:
+ DEBUGASSERT(ptr+BUFSIZE-nread <= data->state.buffer+BUFSIZE+1);
+ result = Curl_read(conn, tunnelsocket, ptr, BUFSIZE-nread,
+ &gotbytes);
+ if(result==CURLE_AGAIN)
+ continue; /* go loop yourself */
+ else if(result)
+ keepon = FALSE;
+ else if(gotbytes <= 0) {
+ keepon = FALSE;
+ if(data->set.proxyauth && data->state.authproxy.avail) {
+ /* proxy auth was requested and there was proxy auth available,
+ then deem this as "mere" proxy disconnect */
+ conn->bits.proxy_connect_closed = TRUE;
+ infof(data, "Proxy CONNECT connection closed\n");
+ }
+ else {
+ error = SELECT_ERROR;
+ failf(data, "Proxy CONNECT aborted");
+ }
+ }
+ else {
+ /*
+ * We got a whole chunk of data, which can be anything from one
+ * byte to a set of lines and possibly just a piece of the last
+ * line.
+ */
+ int i;
+
+ nread += gotbytes;
+
+ if(keepon > TRUE) {
+ /* This means we are currently ignoring a response-body */
+
+ nread = 0; /* make next read start over in the read buffer */
+ ptr=data->state.buffer;
+ if(cl) {
+ /* A Content-Length based body: simply count down the counter
+ and make sure to break out of the loop when we're done! */
+ cl -= gotbytes;
+ if(cl<=0) {
+ keepon = FALSE;
+ break;
+ }
+ }
+ else {
+ /* chunked-encoded body, so we need to do the chunked dance
+ properly to know when the end of the body is reached */
+ CHUNKcode r;
+ ssize_t tookcareof=0;
+
+ /* now parse the chunked piece of data so that we can
+ properly tell when the stream ends */
+ r = Curl_httpchunk_read(conn, ptr, gotbytes, &tookcareof);
+ if(r == CHUNKE_STOP) {
+ /* we're done reading chunks! */
+ infof(data, "chunk reading DONE\n");
+ keepon = FALSE;
+ /* we did the full CONNECT treatment, go COMPLETE */
+ conn->tunnel_state[sockindex] = TUNNEL_COMPLETE;
+ }
+ else
+ infof(data, "Read %zd bytes of chunk, continue\n",
+ tookcareof);
+ }
+ }
+ else
+ for(i = 0; i < gotbytes; ptr++, i++) {
+ perline++; /* amount of bytes in this line so far */
+ if(*ptr == 0x0a) {
+ char letter;
+ int writetype;
+
+ /* convert from the network encoding */
+ result = Curl_convert_from_network(data, line_start,
+ perline);
+ /* Curl_convert_from_network calls failf if unsuccessful */
+ if(result)
+ return result;
+
+ /* output debug if that is requested */
+ if(data->set.verbose)
+ Curl_debug(data, CURLINFO_HEADER_IN,
+ line_start, (size_t)perline, conn);
+
+ /* send the header to the callback */
+ writetype = CLIENTWRITE_HEADER;
+ if(data->set.include_header)
+ writetype |= CLIENTWRITE_BODY;
+
+ result = Curl_client_write(conn, writetype, line_start,
+ perline);
+
+ data->info.header_size += (long)perline;
+ data->req.headerbytecount += (long)perline;
+
+ if(result)
+ return result;
+
+ /* Newlines are CRLF, so the CR is ignored as the line isn't
+ really terminated until the LF comes. Treat a following CR
+ as end-of-headers as well.*/
+
+ if(('\r' == line_start[0]) ||
+ ('\n' == line_start[0])) {
+ /* end of response-headers from the proxy */
+ nread = 0; /* make next read start over in the read
+ buffer */
+ ptr=data->state.buffer;
+ if((407 == k->httpcode) && !data->state.authproblem) {
+ /* If we get a 407 response code with content length
+ when we have no auth problem, we must ignore the
+ whole response-body */
+ keepon = 2;
+
+ if(cl) {
+ infof(data, "Ignore %" CURL_FORMAT_CURL_OFF_T
+ " bytes of response-body\n", cl);
+
+ /* remove the remaining chunk of what we already
+ read */
+ cl -= (gotbytes - i);
+
+ if(cl<=0)
+ /* if the whole thing was already read, we are done!
+ */
+ keepon=FALSE;
+ }
+ else if(chunked_encoding) {
+ CHUNKcode r;
+ /* We set ignorebody true here since the chunked
+ decoder function will acknowledge that. Pay
+ attention so that this is cleared again when this
+ function returns! */
+ k->ignorebody = TRUE;
+ infof(data, "%zd bytes of chunk left\n", gotbytes-i);
+
+ if(line_start[1] == '\n') {
+ /* this can only be a LF if the letter at index 0
+ was a CR */
+ line_start++;
+ i++;
+ }
+
+ /* now parse the chunked piece of data so that we can
+ properly tell when the stream ends */
+ r = Curl_httpchunk_read(conn, line_start+1,
+ gotbytes -i, &gotbytes);
+ if(r == CHUNKE_STOP) {
+ /* we're done reading chunks! */
+ infof(data, "chunk reading DONE\n");
+ keepon = FALSE;
+ /* we did the full CONNECT treatment, go to
+ COMPLETE */
+ conn->tunnel_state[sockindex] = TUNNEL_COMPLETE;
+ }
+ else
+ infof(data, "Read %zd bytes of chunk, continue\n",
+ gotbytes);
+ }
+ else {
+ /* without content-length or chunked encoding, we
+ can't keep the connection alive since the close is
+ the end signal so we bail out at once instead */
+ keepon=FALSE;
+ }
+ }
+ else {
+ keepon = FALSE;
+ if(200 == data->info.httpproxycode) {
+ if(gotbytes - (i+1))
+ failf(data, "Proxy CONNECT followed by %zd bytes "
+ "of opaque data. Data ignored (known bug #39)",
+ gotbytes - (i+1));
+ }
+ }
+ /* we did the full CONNECT treatment, go to COMPLETE */
+ conn->tunnel_state[sockindex] = TUNNEL_COMPLETE;
+ break; /* breaks out of for-loop, not switch() */
+ }
+
+ /* keep a backup of the position we are about to blank */
+ letter = line_start[perline];
+ line_start[perline]=0; /* zero terminate the buffer */
+ if((checkprefix("WWW-Authenticate:", line_start) &&
+ (401 == k->httpcode)) ||
+ (checkprefix("Proxy-authenticate:", line_start) &&
+ (407 == k->httpcode))) {
+
+ bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
+ char *auth = Curl_copy_header_value(line_start);
+ if(!auth)
+ return CURLE_OUT_OF_MEMORY;
+
+ result = Curl_http_input_auth(conn, proxy, auth);
+
+ free(auth);
+
+ if(result)
+ return result;
+ }
+ else if(checkprefix("Content-Length:", line_start)) {
+ cl = curlx_strtoofft(line_start +
+ strlen("Content-Length:"), NULL, 10);
+ }
+ else if(Curl_compareheader(line_start,
+ "Connection:", "close"))
+ closeConnection = TRUE;
+ else if(Curl_compareheader(line_start,
+ "Transfer-Encoding:",
+ "chunked")) {
+ infof(data, "CONNECT responded chunked\n");
+ chunked_encoding = TRUE;
+ /* init our chunky engine */
+ Curl_httpchunk_init(conn);
+ }
+ else if(Curl_compareheader(line_start,
+ "Proxy-Connection:", "close"))
+ closeConnection = TRUE;
+ else if(2 == sscanf(line_start, "HTTP/1.%d %d",
+ &subversion,
+ &k->httpcode)) {
+ /* store the HTTP code from the proxy */
+ data->info.httpproxycode = k->httpcode;
+ }
+ /* put back the letter we blanked out before */
+ line_start[perline]= letter;
+
+ perline=0; /* line starts over here */
+ line_start = ptr+1; /* this skips the zero byte we wrote */
+ }
+ }
+ }
+ break;
+ } /* switch */
+ if(Curl_pgrsUpdate(conn))
+ return CURLE_ABORTED_BY_CALLBACK;
+ } /* while there's buffer left and loop is requested */
+
+ if(error)
+ return CURLE_RECV_ERROR;
+
+ if(data->info.httpproxycode != 200) {
+ /* Deal with the possibly already received authenticate
+ headers. 'newurl' is set to a new URL if we must loop. */
+ result = Curl_http_auth_act(conn);
+ if(result)
+ return result;
+
+ if(conn->bits.close)
+ /* the connection has been marked for closure, most likely in the
+ Curl_http_auth_act() function and thus we can kill it at once
+ below
+ */
+ closeConnection = TRUE;
+ }
+
+ if(closeConnection && data->req.newurl) {
+ /* Connection closed by server. Don't use it anymore */
+ Curl_closesocket(conn, conn->sock[sockindex]);
+ conn->sock[sockindex] = CURL_SOCKET_BAD;
+ break;
+ }
+ } /* END READING RESPONSE PHASE */
+
+ /* If we are supposed to continue and request a new URL, which basically
+ * means the HTTP authentication is still going on so if the tunnel
+ * is complete we start over in INIT state */
+ if(data->req.newurl &&
+ (TUNNEL_COMPLETE == conn->tunnel_state[sockindex])) {
+ conn->tunnel_state[sockindex] = TUNNEL_INIT;
+ infof(data, "TUNNEL_STATE switched to: %d\n",
+ conn->tunnel_state[sockindex]);
+ }
+
+ } while(data->req.newurl);
+
+ if(200 != data->req.httpcode) {
+ if(closeConnection && data->req.newurl) {
+ conn->bits.proxy_connect_closed = TRUE;
+ infof(data, "Connect me again please\n");
+ }
+ else {
+ free(data->req.newurl);
+ data->req.newurl = NULL;
+ /* failure, close this connection to avoid re-use */
+ connclose(conn, "proxy CONNECT failure");
+ Curl_closesocket(conn, conn->sock[sockindex]);
+ conn->sock[sockindex] = CURL_SOCKET_BAD;
+ }
+
+ /* to back to init state */
+ conn->tunnel_state[sockindex] = TUNNEL_INIT;
+
+ if(conn->bits.proxy_connect_closed)
+ /* this is not an error, just part of the connection negotiation */
+ return CURLE_OK;
+ else {
+ failf(data, "Received HTTP code %d from proxy after CONNECT",
+ data->req.httpcode);
+ return CURLE_RECV_ERROR;
+ }
+ }
+
+ conn->tunnel_state[sockindex] = TUNNEL_COMPLETE;
+
+ /* If a proxy-authorization header was used for the proxy, then we should
+ make sure that it isn't accidentally used for the document request
+ after we've connected. So let's free and clear it here. */
+ Curl_safefree(conn->allocptr.proxyuserpwd);
+ conn->allocptr.proxyuserpwd = NULL;
+
+ data->state.authproxy.done = TRUE;
+
+ infof (data, "Proxy replied OK to CONNECT request\n");
+ data->req.ignorebody = FALSE; /* put it (back) to non-ignore state */
+ conn->bits.rewindaftersend = FALSE; /* make sure this isn't set for the
+ document request */
+ return CURLE_OK;
+}
+#endif /* CURL_DISABLE_PROXY */
diff --git a/Utilities/cmcurl/lib/http_proxy.h b/Utilities/cmcurl/lib/http_proxy.h
new file mode 100644
index 000000000..9c4f0207d
--- /dev/null
+++ b/Utilities/cmcurl/lib/http_proxy.h
@@ -0,0 +1,42 @@
+#ifndef HEADER_CURL_HTTP_PROXY_H
+#define HEADER_CURL_HTTP_PROXY_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#if !defined(CURL_DISABLE_PROXY) && !defined(CURL_DISABLE_HTTP)
+/* ftp can use this as well */
+CURLcode Curl_proxyCONNECT(struct connectdata *conn,
+ int tunnelsocket,
+ const char *hostname, int remote_port,
+ bool blocking);
+
+/* Default proxy timeout in milliseconds */
+#define PROXY_TIMEOUT (3600*1000)
+
+CURLcode Curl_proxy_connect(struct connectdata *conn);
+
+#else
+#define Curl_proxyCONNECT(x,y,z,w,v) CURLE_NOT_BUILT_IN
+#define Curl_proxy_connect(x) CURLE_OK
+#endif
+
+#endif /* HEADER_CURL_HTTP_PROXY_H */
diff --git a/Utilities/cmcurl/lib/idn_win32.c b/Utilities/cmcurl/lib/idn_win32.c
new file mode 100644
index 000000000..b36972340
--- /dev/null
+++ b/Utilities/cmcurl/lib/idn_win32.c
@@ -0,0 +1,108 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+ /*
+ * IDN conversions using Windows kernel32 and normaliz libraries.
+ */
+
+#include "curl_setup.h"
+
+#ifdef USE_WIN32_IDN
+
+#include "curl_multibyte.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#ifdef WANT_IDN_PROTOTYPES
+# if defined(_SAL_VERSION)
+WINNORMALIZEAPI int WINAPI
+IdnToAscii(_In_ DWORD dwFlags,
+ _In_reads_(cchUnicodeChar) LPCWSTR lpUnicodeCharStr,
+ _In_ int cchUnicodeChar,
+ _Out_writes_opt_(cchASCIIChar) LPWSTR lpASCIICharStr,
+ _In_ int cchASCIIChar);
+WINNORMALIZEAPI int WINAPI
+IdnToUnicode(_In_ DWORD dwFlags,
+ _In_reads_(cchASCIIChar) LPCWSTR lpASCIICharStr,
+ _In_ int cchASCIIChar,
+ _Out_writes_opt_(cchUnicodeChar) LPWSTR lpUnicodeCharStr,
+ _In_ int cchUnicodeChar);
+# else
+WINBASEAPI int WINAPI IdnToAscii(DWORD dwFlags,
+ const WCHAR *lpUnicodeCharStr,
+ int cchUnicodeChar,
+ WCHAR *lpASCIICharStr,
+ int cchASCIIChar);
+WINBASEAPI int WINAPI IdnToUnicode(DWORD dwFlags,
+ const WCHAR *lpASCIICharStr,
+ int cchASCIIChar,
+ WCHAR *lpUnicodeCharStr,
+ int cchUnicodeChar);
+# endif
+#endif
+
+#define IDN_MAX_LENGTH 255
+
+int curl_win32_idn_to_ascii(const char *in, char **out);
+int curl_win32_ascii_to_idn(const char *in, size_t in_len, char **out_utf8);
+
+int curl_win32_idn_to_ascii(const char *in, char **out)
+{
+ wchar_t *in_w = Curl_convert_UTF8_to_wchar(in);
+ if(in_w) {
+ wchar_t punycode[IDN_MAX_LENGTH];
+ if(IdnToAscii(0, in_w, -1, punycode, IDN_MAX_LENGTH) == 0) {
+ wprintf(L"ERROR %d converting to Punycode\n", GetLastError());
+ free(in_w);
+ return 0;
+ }
+ free(in_w);
+
+ *out = Curl_convert_wchar_to_UTF8(punycode);
+ if(!*out)
+ return 0;
+ }
+ return 1;
+}
+
+int curl_win32_ascii_to_idn(const char *in, size_t in_len, char **out_utf8)
+{
+ (void)in_len; /* unused */
+ if(in) {
+ WCHAR unicode[IDN_MAX_LENGTH];
+
+ if(IdnToUnicode(0, (wchar_t *)in, -1, unicode, IDN_MAX_LENGTH) == 0) {
+ wprintf(L"ERROR %d converting to Punycode\n", GetLastError());
+ return 0;
+ }
+ else {
+ *out_utf8 = Curl_convert_wchar_to_UTF8(unicode);
+ if(!*out_utf8)
+ return 0;
+ }
+ }
+ return 1;
+}
+
+#endif /* USE_WIN32_IDN */
diff --git a/Utilities/cmcurl/lib/if2ip.c b/Utilities/cmcurl/lib/if2ip.c
new file mode 100644
index 000000000..6e6f9692e
--- /dev/null
+++ b/Utilities/cmcurl/lib/if2ip.c
@@ -0,0 +1,271 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+#ifdef HAVE_NET_IF_H
+# include <net/if.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_SYS_SOCKIO_H
+# include <sys/sockio.h>
+#endif
+#ifdef HAVE_IFADDRS_H
+# include <ifaddrs.h>
+#endif
+#ifdef HAVE_STROPTS_H
+# include <stropts.h>
+#endif
+#ifdef __VMS
+# include <inet.h>
+#endif
+
+#include "inet_ntop.h"
+#include "strequal.h"
+#include "if2ip.h"
+#include "curl_printf.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* ------------------------------------------------------------------ */
+
+/* Return the scope of the given address. */
+unsigned int Curl_ipv6_scope(const struct sockaddr *sa)
+{
+#ifndef ENABLE_IPV6
+ (void) sa;
+#else
+ if(sa->sa_family == AF_INET6) {
+ const struct sockaddr_in6 * sa6 = (const struct sockaddr_in6 *) sa;
+ const unsigned char * b = sa6->sin6_addr.s6_addr;
+ unsigned short w = (unsigned short) ((b[0] << 8) | b[1]);
+
+ switch(w & 0xFFC0) {
+ case 0xFE80:
+ return IPV6_SCOPE_LINKLOCAL;
+ case 0xFEC0:
+ return IPV6_SCOPE_SITELOCAL;
+ case 0x0000:
+ w = b[1] | b[2] | b[3] | b[4] | b[5] | b[6] | b[7] | b[8] | b[9] |
+ b[10] | b[11] | b[12] | b[13] | b[14];
+ if(w || b[15] != 0x01)
+ break;
+ return IPV6_SCOPE_NODELOCAL;
+ default:
+ break;
+ }
+ }
+#endif
+
+ return IPV6_SCOPE_GLOBAL;
+}
+
+
+#if defined(HAVE_GETIFADDRS)
+
+bool Curl_if_is_interface_name(const char *interf)
+{
+ bool result = FALSE;
+
+ struct ifaddrs *iface, *head;
+
+ if(getifaddrs(&head) >= 0) {
+ for(iface=head; iface != NULL; iface=iface->ifa_next) {
+ if(curl_strequal(iface->ifa_name, interf)) {
+ result = TRUE;
+ break;
+ }
+ }
+ freeifaddrs(head);
+ }
+ return result;
+}
+
+if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
+ unsigned int remote_scope_id, const char *interf,
+ char *buf, int buf_size)
+{
+ struct ifaddrs *iface, *head;
+ if2ip_result_t res = IF2IP_NOT_FOUND;
+
+#ifndef ENABLE_IPV6
+ (void) remote_scope;
+
+#ifndef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+ (void) remote_scope_id;
+#endif
+
+#endif
+
+ if(getifaddrs(&head) >= 0) {
+ for(iface = head; iface != NULL; iface=iface->ifa_next) {
+ if(iface->ifa_addr != NULL) {
+ if(iface->ifa_addr->sa_family == af) {
+ if(curl_strequal(iface->ifa_name, interf)) {
+ void *addr;
+ char *ip;
+ char scope[12] = "";
+ char ipstr[64];
+#ifdef ENABLE_IPV6
+ if(af == AF_INET6) {
+ unsigned int scopeid = 0;
+ unsigned int ifscope = Curl_ipv6_scope(iface->ifa_addr);
+
+ if(ifscope != remote_scope) {
+ /* We are interested only in interface addresses whose
+ scope matches the remote address we want to
+ connect to: global for global, link-local for
+ link-local, etc... */
+ if(res == IF2IP_NOT_FOUND) res = IF2IP_AF_NOT_SUPPORTED;
+ continue;
+ }
+
+ addr = &((struct sockaddr_in6 *)iface->ifa_addr)->sin6_addr;
+#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+ /* Include the scope of this interface as part of the address */
+ scopeid =
+ ((struct sockaddr_in6 *)iface->ifa_addr)->sin6_scope_id;
+
+ /* If given, scope id should match. */
+ if(remote_scope_id && scopeid != remote_scope_id) {
+ if(res == IF2IP_NOT_FOUND)
+ res = IF2IP_AF_NOT_SUPPORTED;
+
+ continue;
+ }
+#endif
+ if(scopeid)
+ snprintf(scope, sizeof(scope), "%%%u", scopeid);
+ }
+ else
+#endif
+ addr = &((struct sockaddr_in *)iface->ifa_addr)->sin_addr;
+ res = IF2IP_FOUND;
+ ip = (char *) Curl_inet_ntop(af, addr, ipstr, sizeof(ipstr));
+ snprintf(buf, buf_size, "%s%s", ip, scope);
+ break;
+ }
+ }
+ else if((res == IF2IP_NOT_FOUND) &&
+ curl_strequal(iface->ifa_name, interf)) {
+ res = IF2IP_AF_NOT_SUPPORTED;
+ }
+ }
+ }
+
+ freeifaddrs(head);
+ }
+
+ return res;
+}
+
+#elif defined(HAVE_IOCTL_SIOCGIFADDR)
+
+bool Curl_if_is_interface_name(const char *interf)
+{
+ /* This is here just to support the old interfaces */
+ char buf[256];
+
+ return (Curl_if2ip(AF_INET, 0 /* unused */, 0, interf, buf, sizeof(buf)) ==
+ IF2IP_NOT_FOUND) ? FALSE : TRUE;
+}
+
+if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
+ unsigned int remote_scope_id, const char *interf,
+ char *buf, int buf_size)
+{
+ struct ifreq req;
+ struct in_addr in;
+ struct sockaddr_in *s;
+ curl_socket_t dummy;
+ size_t len;
+
+ (void)remote_scope;
+ (void)remote_scope_id;
+
+ if(!interf || (af != AF_INET))
+ return IF2IP_NOT_FOUND;
+
+ len = strlen(interf);
+ if(len >= sizeof(req.ifr_name))
+ return IF2IP_NOT_FOUND;
+
+ dummy = socket(AF_INET, SOCK_STREAM, 0);
+ if(CURL_SOCKET_BAD == dummy)
+ return IF2IP_NOT_FOUND;
+
+ memset(&req, 0, sizeof(req));
+ memcpy(req.ifr_name, interf, len+1);
+ req.ifr_addr.sa_family = AF_INET;
+
+ if(ioctl(dummy, SIOCGIFADDR, &req) < 0) {
+ sclose(dummy);
+ /* With SIOCGIFADDR, we cannot tell the difference between an interface
+ that does not exist and an interface that has no address of the
+ correct family. Assume the interface does not exist */
+ return IF2IP_NOT_FOUND;
+ }
+
+ s = (struct sockaddr_in *)&req.ifr_addr;
+ memcpy(&in, &s->sin_addr, sizeof(in));
+ Curl_inet_ntop(s->sin_family, &in, buf, buf_size);
+
+ sclose(dummy);
+ return IF2IP_FOUND;
+}
+
+#else
+
+bool Curl_if_is_interface_name(const char *interf)
+{
+ (void) interf;
+
+ return FALSE;
+}
+
+if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
+ unsigned int remote_scope_id, const char *interf,
+ char *buf, int buf_size)
+{
+ (void) af;
+ (void) remote_scope;
+ (void) remote_scope_id;
+ (void) interf;
+ (void) buf;
+ (void) buf_size;
+ return IF2IP_NOT_FOUND;
+}
+
+#endif
diff --git a/Utilities/cmcurl/lib/if2ip.h b/Utilities/cmcurl/lib/if2ip.h
new file mode 100644
index 000000000..78bb0bd59
--- /dev/null
+++ b/Utilities/cmcurl/lib/if2ip.h
@@ -0,0 +1,83 @@
+#ifndef HEADER_CURL_IF2IP_H
+#define HEADER_CURL_IF2IP_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+/* IPv6 address scopes. */
+#define IPV6_SCOPE_GLOBAL 0 /* Global scope. */
+#define IPV6_SCOPE_LINKLOCAL 1 /* Link-local scope. */
+#define IPV6_SCOPE_SITELOCAL 2 /* Site-local scope (deprecated). */
+#define IPV6_SCOPE_NODELOCAL 3 /* Loopback. */
+
+unsigned int Curl_ipv6_scope(const struct sockaddr *sa);
+
+bool Curl_if_is_interface_name(const char *interf);
+
+typedef enum {
+ IF2IP_NOT_FOUND = 0, /* Interface not found */
+ IF2IP_AF_NOT_SUPPORTED = 1, /* Int. exists but has no address for this af */
+ IF2IP_FOUND = 2 /* The address has been stored in "buf" */
+} if2ip_result_t;
+
+if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
+ unsigned int remote_scope_id, const char *interf,
+ char *buf, int buf_size);
+
+#ifdef __INTERIX
+
+/* Nedelcho Stanev's work-around for SFU 3.0 */
+struct ifreq {
+#define IFNAMSIZ 16
+#define IFHWADDRLEN 6
+ union {
+ char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */
+ } ifr_ifrn;
+
+ union {
+ struct sockaddr ifru_addr;
+ struct sockaddr ifru_broadaddr;
+ struct sockaddr ifru_netmask;
+ struct sockaddr ifru_hwaddr;
+ short ifru_flags;
+ int ifru_metric;
+ int ifru_mtu;
+ } ifr_ifru;
+};
+
+/* This define was added by Daniel to avoid an extra #ifdef INTERIX in the
+ C code. */
+
+#define ifr_name ifr_ifrn.ifrn_name /* interface name */
+#define ifr_addr ifr_ifru.ifru_addr /* address */
+#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
+#define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */
+#define ifr_flags ifr_ifru.ifru_flags /* flags */
+#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */
+#define ifr_metric ifr_ifru.ifru_metric /* metric */
+#define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
+
+#define SIOCGIFADDR _IOW('s', 102, struct ifreq) /* Get if addr */
+
+#endif /* __INTERIX */
+
+#endif /* HEADER_CURL_IF2IP_H */
diff --git a/Utilities/cmcurl/lib/imap.c b/Utilities/cmcurl/lib/imap.c
new file mode 100644
index 000000000..e6d83f2cf
--- /dev/null
+++ b/Utilities/cmcurl/lib/imap.c
@@ -0,0 +1,2142 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * RFC2195 CRAM-MD5 authentication
+ * RFC2595 Using TLS with IMAP, POP3 and ACAP
+ * RFC2831 DIGEST-MD5 authentication
+ * RFC3501 IMAPv4 protocol
+ * RFC4422 Simple Authentication and Security Layer (SASL)
+ * RFC4616 PLAIN authentication
+ * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism
+ * RFC4959 IMAP Extension for SASL Initial Client Response
+ * RFC5092 IMAP URL Scheme
+ * RFC6749 OAuth 2.0 Authorization Framework
+ * Draft LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_IMAP
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "progress.h"
+#include "transfer.h"
+#include "escape.h"
+#include "http.h" /* for HTTP proxy tunnel stuff */
+#include "socks.h"
+#include "imap.h"
+
+#include "strtoofft.h"
+#include "strequal.h"
+#include "vtls/vtls.h"
+#include "connect.h"
+#include "strerror.h"
+#include "select.h"
+#include "multiif.h"
+#include "url.h"
+#include "rawstr.h"
+#include "curl_sasl.h"
+#include "warnless.h"
+#include "curl_printf.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* Local API functions */
+static CURLcode imap_regular_transfer(struct connectdata *conn, bool *done);
+static CURLcode imap_do(struct connectdata *conn, bool *done);
+static CURLcode imap_done(struct connectdata *conn, CURLcode status,
+ bool premature);
+static CURLcode imap_connect(struct connectdata *conn, bool *done);
+static CURLcode imap_disconnect(struct connectdata *conn, bool dead);
+static CURLcode imap_multi_statemach(struct connectdata *conn, bool *done);
+static int imap_getsock(struct connectdata *conn, curl_socket_t *socks,
+ int numsocks);
+static CURLcode imap_doing(struct connectdata *conn, bool *dophase_done);
+static CURLcode imap_setup_connection(struct connectdata *conn);
+static char *imap_atom(const char *str);
+static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...);
+static CURLcode imap_parse_url_options(struct connectdata *conn);
+static CURLcode imap_parse_url_path(struct connectdata *conn);
+static CURLcode imap_parse_custom_request(struct connectdata *conn);
+static CURLcode imap_perform_authenticate(struct connectdata *conn,
+ const char *mech,
+ const char *initresp);
+static CURLcode imap_continue_authenticate(struct connectdata *conn,
+ const char *resp);
+static void imap_get_message(char *buffer, char** outptr);
+
+/*
+ * IMAP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_imap = {
+ "IMAP", /* scheme */
+ imap_setup_connection, /* setup_connection */
+ imap_do, /* do_it */
+ imap_done, /* done */
+ ZERO_NULL, /* do_more */
+ imap_connect, /* connect_it */
+ imap_multi_statemach, /* connecting */
+ imap_doing, /* doing */
+ imap_getsock, /* proto_getsock */
+ imap_getsock, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ imap_disconnect, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_IMAP, /* defport */
+ CURLPROTO_IMAP, /* protocol */
+ PROTOPT_CLOSEACTION /* flags */
+};
+
+#ifdef USE_SSL
+/*
+ * IMAPS protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_imaps = {
+ "IMAPS", /* scheme */
+ imap_setup_connection, /* setup_connection */
+ imap_do, /* do_it */
+ imap_done, /* done */
+ ZERO_NULL, /* do_more */
+ imap_connect, /* connect_it */
+ imap_multi_statemach, /* connecting */
+ imap_doing, /* doing */
+ imap_getsock, /* proto_getsock */
+ imap_getsock, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ imap_disconnect, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_IMAPS, /* defport */
+ CURLPROTO_IMAPS, /* protocol */
+ PROTOPT_CLOSEACTION | PROTOPT_SSL /* flags */
+};
+#endif
+
+#ifndef CURL_DISABLE_HTTP
+/*
+ * HTTP-proxyed IMAP protocol handler.
+ */
+
+static const struct Curl_handler Curl_handler_imap_proxy = {
+ "IMAP", /* scheme */
+ Curl_http_setup_conn, /* setup_connection */
+ Curl_http, /* do_it */
+ Curl_http_done, /* done */
+ ZERO_NULL, /* do_more */
+ ZERO_NULL, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_getsock */
+ ZERO_NULL, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ ZERO_NULL, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_IMAP, /* defport */
+ CURLPROTO_HTTP, /* protocol */
+ PROTOPT_NONE /* flags */
+};
+
+#ifdef USE_SSL
+/*
+ * HTTP-proxyed IMAPS protocol handler.
+ */
+
+static const struct Curl_handler Curl_handler_imaps_proxy = {
+ "IMAPS", /* scheme */
+ Curl_http_setup_conn, /* setup_connection */
+ Curl_http, /* do_it */
+ Curl_http_done, /* done */
+ ZERO_NULL, /* do_more */
+ ZERO_NULL, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_getsock */
+ ZERO_NULL, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ ZERO_NULL, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_IMAPS, /* defport */
+ CURLPROTO_HTTP, /* protocol */
+ PROTOPT_NONE /* flags */
+};
+#endif
+#endif
+
+/* SASL parameters for the imap protocol */
+static const struct SASLproto saslimap = {
+ "imap", /* The service name */
+ '+', /* Code received when continuation is expected */
+ 'O', /* Code to receive upon authentication success */
+ 0, /* Maximum initial response length (no max) */
+ imap_perform_authenticate, /* Send authentication command */
+ imap_continue_authenticate, /* Send authentication continuation */
+ imap_get_message /* Get SASL response message */
+};
+
+
+#ifdef USE_SSL
+static void imap_to_imaps(struct connectdata *conn)
+{
+ conn->handler = &Curl_handler_imaps;
+}
+#else
+#define imap_to_imaps(x) Curl_nop_stmt
+#endif
+
+/***********************************************************************
+ *
+ * imap_matchresp()
+ *
+ * Determines whether the untagged response is related to the specified
+ * command by checking if it is in format "* <command-name> ..." or
+ * "* <number> <command-name> ...".
+ *
+ * The "* " marker is assumed to have already been checked by the caller.
+ */
+static bool imap_matchresp(const char *line, size_t len, const char *cmd)
+{
+ const char *end = line + len;
+ size_t cmd_len = strlen(cmd);
+
+ /* Skip the untagged response marker */
+ line += 2;
+
+ /* Do we have a number after the marker? */
+ if(line < end && ISDIGIT(*line)) {
+ /* Skip the number */
+ do
+ line++;
+ while(line < end && ISDIGIT(*line));
+
+ /* Do we have the space character? */
+ if(line == end || *line != ' ')
+ return FALSE;
+
+ line++;
+ }
+
+ /* Does the command name match and is it followed by a space character or at
+ the end of line? */
+ if(line + cmd_len <= end && Curl_raw_nequal(line, cmd, cmd_len) &&
+ (line[cmd_len] == ' ' || line + cmd_len + 2 == end))
+ return TRUE;
+
+ return FALSE;
+}
+
+/***********************************************************************
+ *
+ * imap_endofresp()
+ *
+ * Checks whether the given string is a valid tagged, untagged or continuation
+ * response which can be processed by the response handler.
+ */
+static bool imap_endofresp(struct connectdata *conn, char *line, size_t len,
+ int *resp)
+{
+ struct IMAP *imap = conn->data->req.protop;
+ struct imap_conn *imapc = &conn->proto.imapc;
+ const char *id = imapc->resptag;
+ size_t id_len = strlen(id);
+
+ /* Do we have a tagged command response? */
+ if(len >= id_len + 1 && !memcmp(id, line, id_len) && line[id_len] == ' ') {
+ line += id_len + 1;
+ len -= id_len + 1;
+
+ if(len >= 2 && !memcmp(line, "OK", 2))
+ *resp = 'O';
+ else if(len >= 2 && !memcmp(line, "NO", 2))
+ *resp = 'N';
+ else if(len >= 3 && !memcmp(line, "BAD", 3))
+ *resp = 'B';
+ else {
+ failf(conn->data, "Bad tagged response");
+ *resp = -1;
+ }
+
+ return TRUE;
+ }
+
+ /* Do we have an untagged command response? */
+ if(len >= 2 && !memcmp("* ", line, 2)) {
+ switch(imapc->state) {
+ /* States which are interested in untagged responses */
+ case IMAP_CAPABILITY:
+ if(!imap_matchresp(line, len, "CAPABILITY"))
+ return FALSE;
+ break;
+
+ case IMAP_LIST:
+ if((!imap->custom && !imap_matchresp(line, len, "LIST")) ||
+ (imap->custom && !imap_matchresp(line, len, imap->custom) &&
+ (strcmp(imap->custom, "STORE") ||
+ !imap_matchresp(line, len, "FETCH")) &&
+ strcmp(imap->custom, "SELECT") &&
+ strcmp(imap->custom, "EXAMINE") &&
+ strcmp(imap->custom, "SEARCH") &&
+ strcmp(imap->custom, "EXPUNGE") &&
+ strcmp(imap->custom, "LSUB") &&
+ strcmp(imap->custom, "UID") &&
+ strcmp(imap->custom, "NOOP")))
+ return FALSE;
+ break;
+
+ case IMAP_SELECT:
+ /* SELECT is special in that its untagged responses do not have a
+ common prefix so accept anything! */
+ break;
+
+ case IMAP_FETCH:
+ if(!imap_matchresp(line, len, "FETCH"))
+ return FALSE;
+ break;
+
+ case IMAP_SEARCH:
+ if(!imap_matchresp(line, len, "SEARCH"))
+ return FALSE;
+ break;
+
+ /* Ignore other untagged responses */
+ default:
+ return FALSE;
+ }
+
+ *resp = '*';
+ return TRUE;
+ }
+
+ /* Do we have a continuation response? This should be a + symbol followed by
+ a space and optionally some text as per RFC-3501 for the AUTHENTICATE and
+ APPEND commands and as outlined in Section 4. Examples of RFC-4959 but
+ some e-mail servers ignore this and only send a single + instead. */
+ if((len == 3 && !memcmp("+", line, 1)) ||
+ (len >= 2 && !memcmp("+ ", line, 2))) {
+ switch(imapc->state) {
+ /* States which are interested in continuation responses */
+ case IMAP_AUTHENTICATE:
+ case IMAP_APPEND:
+ *resp = '+';
+ break;
+
+ default:
+ failf(conn->data, "Unexpected continuation response");
+ *resp = -1;
+ break;
+ }
+
+ return TRUE;
+ }
+
+ return FALSE; /* Nothing for us */
+}
+
+/***********************************************************************
+ *
+ * imap_get_message()
+ *
+ * Gets the authentication message from the response buffer.
+ */
+static void imap_get_message(char *buffer, char** outptr)
+{
+ size_t len = 0;
+ char* message = NULL;
+
+ /* Find the start of the message */
+ for(message = buffer + 2; *message == ' ' || *message == '\t'; message++)
+ ;
+
+ /* Find the end of the message */
+ for(len = strlen(message); len--;)
+ if(message[len] != '\r' && message[len] != '\n' && message[len] != ' ' &&
+ message[len] != '\t')
+ break;
+
+ /* Terminate the message */
+ if(++len) {
+ message[len] = '\0';
+ }
+
+ *outptr = message;
+}
+
+/***********************************************************************
+ *
+ * state()
+ *
+ * This is the ONLY way to change IMAP state!
+ */
+static void state(struct connectdata *conn, imapstate newstate)
+{
+ struct imap_conn *imapc = &conn->proto.imapc;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+ /* for debug purposes */
+ static const char * const names[]={
+ "STOP",
+ "SERVERGREET",
+ "CAPABILITY",
+ "STARTTLS",
+ "UPGRADETLS",
+ "AUTHENTICATE",
+ "LOGIN",
+ "LIST",
+ "SELECT",
+ "FETCH",
+ "FETCH_FINAL",
+ "APPEND",
+ "APPEND_FINAL",
+ "SEARCH",
+ "LOGOUT",
+ /* LAST */
+ };
+
+ if(imapc->state != newstate)
+ infof(conn->data, "IMAP %p state change from %s to %s\n",
+ (void *)imapc, names[imapc->state], names[newstate]);
+#endif
+
+ imapc->state = newstate;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_capability()
+ *
+ * Sends the CAPABILITY command in order to obtain a list of server side
+ * supported capabilities.
+ */
+static CURLcode imap_perform_capability(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct imap_conn *imapc = &conn->proto.imapc;
+
+ imapc->sasl.authmechs = SASL_AUTH_NONE; /* No known auth. mechanisms yet */
+ imapc->sasl.authused = SASL_AUTH_NONE; /* Clear the auth. mechanism used */
+ imapc->tls_supported = FALSE; /* Clear the TLS capability */
+
+ /* Send the CAPABILITY command */
+ result = imap_sendf(conn, "CAPABILITY");
+
+ if(!result)
+ state(conn, IMAP_CAPABILITY);
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_starttls()
+ *
+ * Sends the STARTTLS command to start the upgrade to TLS.
+ */
+static CURLcode imap_perform_starttls(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+
+ /* Send the STARTTLS command */
+ result = imap_sendf(conn, "STARTTLS");
+
+ if(!result)
+ state(conn, IMAP_STARTTLS);
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_upgrade_tls()
+ *
+ * Performs the upgrade to TLS.
+ */
+static CURLcode imap_perform_upgrade_tls(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct imap_conn *imapc = &conn->proto.imapc;
+
+ /* Start the SSL connection */
+ result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &imapc->ssldone);
+
+ if(!result) {
+ if(imapc->state != IMAP_UPGRADETLS)
+ state(conn, IMAP_UPGRADETLS);
+
+ if(imapc->ssldone) {
+ imap_to_imaps(conn);
+ result = imap_perform_capability(conn);
+ }
+ }
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_login()
+ *
+ * Sends a clear text LOGIN command to authenticate with.
+ */
+static CURLcode imap_perform_login(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ char *user;
+ char *passwd;
+
+ /* Check we have a username and password to authenticate with and end the
+ connect phase if we don't */
+ if(!conn->bits.user_passwd) {
+ state(conn, IMAP_STOP);
+
+ return result;
+ }
+
+ /* Make sure the username and password are in the correct atom format */
+ user = imap_atom(conn->user);
+ passwd = imap_atom(conn->passwd);
+
+ /* Send the LOGIN command */
+ result = imap_sendf(conn, "LOGIN %s %s", user ? user : "",
+ passwd ? passwd : "");
+
+ free(user);
+ free(passwd);
+
+ if(!result)
+ state(conn, IMAP_LOGIN);
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_authenticate()
+ *
+ * Sends an AUTHENTICATE command allowing the client to login with the given
+ * SASL authentication mechanism.
+ */
+static CURLcode imap_perform_authenticate(struct connectdata *conn,
+ const char *mech,
+ const char *initresp)
+{
+ CURLcode result = CURLE_OK;
+
+ if(initresp) {
+ /* Send the AUTHENTICATE command with the initial response */
+ result = imap_sendf(conn, "AUTHENTICATE %s %s", mech, initresp);
+ }
+ else {
+ /* Send the AUTHENTICATE command */
+ result = imap_sendf(conn, "AUTHENTICATE %s", mech);
+ }
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * imap_continue_authenticate()
+ *
+ * Sends SASL continuation data or cancellation.
+ */
+static CURLcode imap_continue_authenticate(struct connectdata *conn,
+ const char *resp)
+{
+ struct imap_conn *imapc = &conn->proto.imapc;
+
+ return Curl_pp_sendf(&imapc->pp, "%s", resp);
+}
+
+/***********************************************************************
+ *
+ * imap_perform_authentication()
+ *
+ * Initiates the authentication sequence, with the appropriate SASL
+ * authentication mechanism, falling back to clear text should a common
+ * mechanism not be available between the client and server.
+ */
+static CURLcode imap_perform_authentication(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct imap_conn *imapc = &conn->proto.imapc;
+ saslprogress progress;
+
+ /* Check we have enough data to authenticate with and end the
+ connect phase if we don't */
+ if(!Curl_sasl_can_authenticate(&imapc->sasl, conn)) {
+ state(conn, IMAP_STOP);
+ return result;
+ }
+
+ /* Calculate the SASL login details */
+ result = Curl_sasl_start(&imapc->sasl, conn, imapc->ir_supported, &progress);
+
+ if(!result) {
+ if(progress == SASL_INPROGRESS)
+ state(conn, IMAP_AUTHENTICATE);
+ else if(!imapc->login_disabled && (imapc->preftype & IMAP_TYPE_CLEARTEXT))
+ /* Perform clear text authentication */
+ result = imap_perform_login(conn);
+ else {
+ /* Other mechanisms not supported */
+ infof(conn->data, "No known authentication mechanisms supported!\n");
+ result = CURLE_LOGIN_DENIED;
+ }
+ }
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_list()
+ *
+ * Sends a LIST command or an alternative custom request.
+ */
+static CURLcode imap_perform_list(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct IMAP *imap = data->req.protop;
+ char *mailbox;
+
+ if(imap->custom)
+ /* Send the custom request */
+ result = imap_sendf(conn, "%s%s", imap->custom,
+ imap->custom_params ? imap->custom_params : "");
+ else {
+ /* Make sure the mailbox is in the correct atom format */
+ mailbox = imap_atom(imap->mailbox ? imap->mailbox : "");
+ if(!mailbox)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Send the LIST command */
+ result = imap_sendf(conn, "LIST \"%s\" *", mailbox);
+
+ free(mailbox);
+ }
+
+ if(!result)
+ state(conn, IMAP_LIST);
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_select()
+ *
+ * Sends a SELECT command to ask the server to change the selected mailbox.
+ */
+static CURLcode imap_perform_select(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct IMAP *imap = data->req.protop;
+ struct imap_conn *imapc = &conn->proto.imapc;
+ char *mailbox;
+
+ /* Invalidate old information as we are switching mailboxes */
+ Curl_safefree(imapc->mailbox);
+ Curl_safefree(imapc->mailbox_uidvalidity);
+
+ /* Check we have a mailbox */
+ if(!imap->mailbox) {
+ failf(conn->data, "Cannot SELECT without a mailbox.");
+ return CURLE_URL_MALFORMAT;
+ }
+
+ /* Make sure the mailbox is in the correct atom format */
+ mailbox = imap_atom(imap->mailbox);
+ if(!mailbox)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Send the SELECT command */
+ result = imap_sendf(conn, "SELECT %s", mailbox);
+
+ free(mailbox);
+
+ if(!result)
+ state(conn, IMAP_SELECT);
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_fetch()
+ *
+ * Sends a FETCH command to initiate the download of a message.
+ */
+static CURLcode imap_perform_fetch(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct IMAP *imap = conn->data->req.protop;
+
+ /* Check we have a UID */
+ if(!imap->uid) {
+ failf(conn->data, "Cannot FETCH without a UID.");
+ return CURLE_URL_MALFORMAT;
+ }
+
+ /* Send the FETCH command */
+ if(imap->partial)
+ result = imap_sendf(conn, "FETCH %s BODY[%s]<%s>",
+ imap->uid,
+ imap->section ? imap->section : "",
+ imap->partial);
+ else
+ result = imap_sendf(conn, "FETCH %s BODY[%s]",
+ imap->uid,
+ imap->section ? imap->section : "");
+
+ if(!result)
+ state(conn, IMAP_FETCH);
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_append()
+ *
+ * Sends an APPEND command to initiate the upload of a message.
+ */
+static CURLcode imap_perform_append(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct IMAP *imap = conn->data->req.protop;
+ char *mailbox;
+
+ /* Check we have a mailbox */
+ if(!imap->mailbox) {
+ failf(conn->data, "Cannot APPEND without a mailbox.");
+ return CURLE_URL_MALFORMAT;
+ }
+
+ /* Check we know the size of the upload */
+ if(conn->data->state.infilesize < 0) {
+ failf(conn->data, "Cannot APPEND with unknown input file size\n");
+ return CURLE_UPLOAD_FAILED;
+ }
+
+ /* Make sure the mailbox is in the correct atom format */
+ mailbox = imap_atom(imap->mailbox);
+ if(!mailbox)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Send the APPEND command */
+ result = imap_sendf(conn, "APPEND %s (\\Seen) {%" CURL_FORMAT_CURL_OFF_T "}",
+ mailbox, conn->data->state.infilesize);
+
+ free(mailbox);
+
+ if(!result)
+ state(conn, IMAP_APPEND);
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_search()
+ *
+ * Sends a SEARCH command.
+ */
+static CURLcode imap_perform_search(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct IMAP *imap = conn->data->req.protop;
+
+ /* Check we have a query string */
+ if(!imap->query) {
+ failf(conn->data, "Cannot SEARCH without a query string.");
+ return CURLE_URL_MALFORMAT;
+ }
+
+ /* Send the SEARCH command */
+ result = imap_sendf(conn, "SEARCH %s", imap->query);
+
+ if(!result)
+ state(conn, IMAP_SEARCH);
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_logout()
+ *
+ * Performs the logout action prior to sclose() being called.
+ */
+static CURLcode imap_perform_logout(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+
+ /* Send the LOGOUT command */
+ result = imap_sendf(conn, "LOGOUT");
+
+ if(!result)
+ state(conn, IMAP_LOGOUT);
+
+ return result;
+}
+
+/* For the initial server greeting */
+static CURLcode imap_state_servergreet_resp(struct connectdata *conn,
+ int imapcode,
+ imapstate instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+
+ (void)instate; /* no use for this yet */
+
+ if(imapcode != 'O') {
+ failf(data, "Got unexpected imap-server response");
+ result = CURLE_FTP_WEIRD_SERVER_REPLY; /* TODO: fix this code */
+ }
+ else
+ result = imap_perform_capability(conn);
+
+ return result;
+}
+
+/* For CAPABILITY responses */
+static CURLcode imap_state_capability_resp(struct connectdata *conn,
+ int imapcode,
+ imapstate instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct imap_conn *imapc = &conn->proto.imapc;
+ const char *line = data->state.buffer;
+ size_t wordlen;
+
+ (void)instate; /* no use for this yet */
+
+ /* Do we have a untagged response? */
+ if(imapcode == '*') {
+ line += 2;
+
+ /* Loop through the data line */
+ for(;;) {
+ while(*line &&
+ (*line == ' ' || *line == '\t' ||
+ *line == '\r' || *line == '\n')) {
+
+ line++;
+ }
+
+ if(!*line)
+ break;
+
+ /* Extract the word */
+ for(wordlen = 0; line[wordlen] && line[wordlen] != ' ' &&
+ line[wordlen] != '\t' && line[wordlen] != '\r' &&
+ line[wordlen] != '\n';)
+ wordlen++;
+
+ /* Does the server support the STARTTLS capability? */
+ if(wordlen == 8 && !memcmp(line, "STARTTLS", 8))
+ imapc->tls_supported = TRUE;
+
+ /* Has the server explicitly disabled clear text authentication? */
+ else if(wordlen == 13 && !memcmp(line, "LOGINDISABLED", 13))
+ imapc->login_disabled = TRUE;
+
+ /* Does the server support the SASL-IR capability? */
+ else if(wordlen == 7 && !memcmp(line, "SASL-IR", 7))
+ imapc->ir_supported = TRUE;
+
+ /* Do we have a SASL based authentication mechanism? */
+ else if(wordlen > 5 && !memcmp(line, "AUTH=", 5)) {
+ size_t llen;
+ unsigned int mechbit;
+
+ line += 5;
+ wordlen -= 5;
+
+ /* Test the word for a matching authentication mechanism */
+ if((mechbit = Curl_sasl_decode_mech(line, wordlen, &llen)) &&
+ llen == wordlen)
+ imapc->sasl.authmechs |= mechbit;
+ }
+
+ line += wordlen;
+ }
+ }
+ else if(imapcode == 'O') {
+ if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
+ /* We don't have a SSL/TLS connection yet, but SSL is requested */
+ if(imapc->tls_supported)
+ /* Switch to TLS connection now */
+ result = imap_perform_starttls(conn);
+ else if(data->set.use_ssl == CURLUSESSL_TRY)
+ /* Fallback and carry on with authentication */
+ result = imap_perform_authentication(conn);
+ else {
+ failf(data, "STARTTLS not supported.");
+ result = CURLE_USE_SSL_FAILED;
+ }
+ }
+ else
+ result = imap_perform_authentication(conn);
+ }
+ else
+ result = imap_perform_authentication(conn);
+
+ return result;
+}
+
+/* For STARTTLS responses */
+static CURLcode imap_state_starttls_resp(struct connectdata *conn,
+ int imapcode,
+ imapstate instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+
+ (void)instate; /* no use for this yet */
+
+ if(imapcode != 'O') {
+ if(data->set.use_ssl != CURLUSESSL_TRY) {
+ failf(data, "STARTTLS denied. %c", imapcode);
+ result = CURLE_USE_SSL_FAILED;
+ }
+ else
+ result = imap_perform_authentication(conn);
+ }
+ else
+ result = imap_perform_upgrade_tls(conn);
+
+ return result;
+}
+
+/* For SASL authentication responses */
+static CURLcode imap_state_auth_resp(struct connectdata *conn,
+ int imapcode,
+ imapstate instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct imap_conn *imapc = &conn->proto.imapc;
+ saslprogress progress;
+
+ (void)instate; /* no use for this yet */
+
+ result = Curl_sasl_continue(&imapc->sasl, conn, imapcode, &progress);
+ if(!result)
+ switch(progress) {
+ case SASL_DONE:
+ state(conn, IMAP_STOP); /* Authenticated */
+ break;
+ case SASL_IDLE: /* No mechanism left after cancellation */
+ if((!imapc->login_disabled) && (imapc->preftype & IMAP_TYPE_CLEARTEXT))
+ /* Perform clear text authentication */
+ result = imap_perform_login(conn);
+ else {
+ failf(data, "Authentication cancelled");
+ result = CURLE_LOGIN_DENIED;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return result;
+}
+
+/* For LOGIN responses */
+static CURLcode imap_state_login_resp(struct connectdata *conn,
+ int imapcode,
+ imapstate instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+
+ (void)instate; /* no use for this yet */
+
+ if(imapcode != 'O') {
+ failf(data, "Access denied. %c", imapcode);
+ result = CURLE_LOGIN_DENIED;
+ }
+ else
+ /* End of connect phase */
+ state(conn, IMAP_STOP);
+
+ return result;
+}
+
+/* For LIST responses */
+static CURLcode imap_state_list_resp(struct connectdata *conn, int imapcode,
+ imapstate instate)
+{
+ CURLcode result = CURLE_OK;
+ char *line = conn->data->state.buffer;
+ size_t len = strlen(line);
+
+ (void)instate; /* No use for this yet */
+
+ if(imapcode == '*') {
+ /* Temporarily add the LF character back and send as body to the client */
+ line[len] = '\n';
+ result = Curl_client_write(conn, CLIENTWRITE_BODY, line, len + 1);
+ line[len] = '\0';
+ }
+ else if(imapcode != 'O')
+ result = CURLE_QUOTE_ERROR; /* TODO: Fix error code */
+ else
+ /* End of DO phase */
+ state(conn, IMAP_STOP);
+
+ return result;
+}
+
+/* For SELECT responses */
+static CURLcode imap_state_select_resp(struct connectdata *conn, int imapcode,
+ imapstate instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct IMAP *imap = conn->data->req.protop;
+ struct imap_conn *imapc = &conn->proto.imapc;
+ const char *line = data->state.buffer;
+ char tmp[20];
+
+ (void)instate; /* no use for this yet */
+
+ if(imapcode == '*') {
+ /* See if this is an UIDVALIDITY response */
+ if(sscanf(line + 2, "OK [UIDVALIDITY %19[0123456789]]", tmp) == 1) {
+ Curl_safefree(imapc->mailbox_uidvalidity);
+ imapc->mailbox_uidvalidity = strdup(tmp);
+ }
+ }
+ else if(imapcode == 'O') {
+ /* Check if the UIDVALIDITY has been specified and matches */
+ if(imap->uidvalidity && imapc->mailbox_uidvalidity &&
+ strcmp(imap->uidvalidity, imapc->mailbox_uidvalidity)) {
+ failf(conn->data, "Mailbox UIDVALIDITY has changed");
+ result = CURLE_REMOTE_FILE_NOT_FOUND;
+ }
+ else {
+ /* Note the currently opened mailbox on this connection */
+ imapc->mailbox = strdup(imap->mailbox);
+
+ if(imap->custom)
+ result = imap_perform_list(conn);
+ else if(imap->query)
+ result = imap_perform_search(conn);
+ else
+ result = imap_perform_fetch(conn);
+ }
+ }
+ else {
+ failf(data, "Select failed");
+ result = CURLE_LOGIN_DENIED;
+ }
+
+ return result;
+}
+
+/* For the (first line of the) FETCH responses */
+static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode,
+ imapstate instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct imap_conn *imapc = &conn->proto.imapc;
+ struct pingpong *pp = &imapc->pp;
+ const char *ptr = data->state.buffer;
+ bool parsed = FALSE;
+ curl_off_t size;
+
+ (void)instate; /* no use for this yet */
+
+ if(imapcode != '*') {
+ Curl_pgrsSetDownloadSize(data, -1);
+ state(conn, IMAP_STOP);
+ return CURLE_REMOTE_FILE_NOT_FOUND; /* TODO: Fix error code */
+ }
+
+ /* Something like this is received "* 1 FETCH (BODY[TEXT] {2021}\r" so parse
+ the continuation data contained within the curly brackets */
+ while(*ptr && (*ptr != '{'))
+ ptr++;
+
+ if(*ptr == '{') {
+ char *endptr;
+ size = curlx_strtoofft(ptr + 1, &endptr, 10);
+ if(endptr - ptr > 1 && endptr[0] == '}' &&
+ endptr[1] == '\r' && endptr[2] == '\0')
+ parsed = TRUE;
+ }
+
+ if(parsed) {
+ infof(data, "Found %" CURL_FORMAT_CURL_OFF_TU " bytes to download\n",
+ size);
+ Curl_pgrsSetDownloadSize(data, size);
+
+ if(pp->cache) {
+ /* At this point there is a bunch of data in the header "cache" that is
+ actually body content, send it as body and then skip it. Do note
+ that there may even be additional "headers" after the body. */
+ size_t chunk = pp->cache_size;
+
+ if(chunk > (size_t)size)
+ /* The conversion from curl_off_t to size_t is always fine here */
+ chunk = (size_t)size;
+
+ result = Curl_client_write(conn, CLIENTWRITE_BODY, pp->cache, chunk);
+ if(result)
+ return result;
+
+ data->req.bytecount += chunk;
+
+ infof(data, "Written %" CURL_FORMAT_CURL_OFF_TU
+ " bytes, %" CURL_FORMAT_CURL_OFF_TU
+ " bytes are left for transfer\n", (curl_off_t)chunk,
+ size - chunk);
+
+ /* Have we used the entire cache or just part of it?*/
+ if(pp->cache_size > chunk) {
+ /* Only part of it so shrink the cache to fit the trailing data */
+ memmove(pp->cache, pp->cache + chunk, pp->cache_size - chunk);
+ pp->cache_size -= chunk;
+ }
+ else {
+ /* Free the cache */
+ Curl_safefree(pp->cache);
+
+ /* Reset the cache size */
+ pp->cache_size = 0;
+ }
+ }
+
+ if(data->req.bytecount == size)
+ /* The entire data is already transferred! */
+ Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+ else {
+ /* IMAP download */
+ data->req.maxdownload = size;
+ Curl_setup_transfer(conn, FIRSTSOCKET, size, FALSE, NULL, -1, NULL);
+ }
+ }
+ else {
+ /* We don't know how to parse this line */
+ failf(pp->conn->data, "Failed to parse FETCH response.");
+ result = CURLE_FTP_WEIRD_SERVER_REPLY; /* TODO: fix this code */
+ }
+
+ /* End of DO phase */
+ state(conn, IMAP_STOP);
+
+ return result;
+}
+
+/* For final FETCH responses performed after the download */
+static CURLcode imap_state_fetch_final_resp(struct connectdata *conn,
+ int imapcode,
+ imapstate instate)
+{
+ CURLcode result = CURLE_OK;
+
+ (void)instate; /* No use for this yet */
+
+ if(imapcode != 'O')
+ result = CURLE_FTP_WEIRD_SERVER_REPLY; /* TODO: Fix error code */
+ else
+ /* End of DONE phase */
+ state(conn, IMAP_STOP);
+
+ return result;
+}
+
+/* For APPEND responses */
+static CURLcode imap_state_append_resp(struct connectdata *conn, int imapcode,
+ imapstate instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+
+ (void)instate; /* No use for this yet */
+
+ if(imapcode != '+') {
+ result = CURLE_UPLOAD_FAILED;
+ }
+ else {
+ /* Set the progress upload size */
+ Curl_pgrsSetUploadSize(data, data->state.infilesize);
+
+ /* IMAP upload */
+ Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
+
+ /* End of DO phase */
+ state(conn, IMAP_STOP);
+ }
+
+ return result;
+}
+
+/* For final APPEND responses performed after the upload */
+static CURLcode imap_state_append_final_resp(struct connectdata *conn,
+ int imapcode,
+ imapstate instate)
+{
+ CURLcode result = CURLE_OK;
+
+ (void)instate; /* No use for this yet */
+
+ if(imapcode != 'O')
+ result = CURLE_UPLOAD_FAILED;
+ else
+ /* End of DONE phase */
+ state(conn, IMAP_STOP);
+
+ return result;
+}
+
+/* For SEARCH responses */
+static CURLcode imap_state_search_resp(struct connectdata *conn, int imapcode,
+ imapstate instate)
+{
+ CURLcode result = CURLE_OK;
+ char *line = conn->data->state.buffer;
+ size_t len = strlen(line);
+
+ (void)instate; /* No use for this yet */
+
+ if(imapcode == '*') {
+ /* Temporarily add the LF character back and send as body to the client */
+ line[len] = '\n';
+ result = Curl_client_write(conn, CLIENTWRITE_BODY, line, len + 1);
+ line[len] = '\0';
+ }
+ else if(imapcode != 'O')
+ result = CURLE_QUOTE_ERROR; /* TODO: Fix error code */
+ else
+ /* End of DO phase */
+ state(conn, IMAP_STOP);
+
+ return result;
+}
+
+static CURLcode imap_statemach_act(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ curl_socket_t sock = conn->sock[FIRSTSOCKET];
+ int imapcode;
+ struct imap_conn *imapc = &conn->proto.imapc;
+ struct pingpong *pp = &imapc->pp;
+ size_t nread = 0;
+
+ /* Busy upgrading the connection; right now all I/O is SSL/TLS, not IMAP */
+ if(imapc->state == IMAP_UPGRADETLS)
+ return imap_perform_upgrade_tls(conn);
+
+ /* Flush any data that needs to be sent */
+ if(pp->sendleft)
+ return Curl_pp_flushsend(pp);
+
+ do {
+ /* Read the response from the server */
+ result = Curl_pp_readresp(sock, pp, &imapcode, &nread);
+ if(result)
+ return result;
+
+ /* Was there an error parsing the response line? */
+ if(imapcode == -1)
+ return CURLE_FTP_WEIRD_SERVER_REPLY;
+
+ if(!imapcode)
+ break;
+
+ /* We have now received a full IMAP server response */
+ switch(imapc->state) {
+ case IMAP_SERVERGREET:
+ result = imap_state_servergreet_resp(conn, imapcode, imapc->state);
+ break;
+
+ case IMAP_CAPABILITY:
+ result = imap_state_capability_resp(conn, imapcode, imapc->state);
+ break;
+
+ case IMAP_STARTTLS:
+ result = imap_state_starttls_resp(conn, imapcode, imapc->state);
+ break;
+
+ case IMAP_AUTHENTICATE:
+ result = imap_state_auth_resp(conn, imapcode, imapc->state);
+ break;
+
+ case IMAP_LOGIN:
+ result = imap_state_login_resp(conn, imapcode, imapc->state);
+ break;
+
+ case IMAP_LIST:
+ result = imap_state_list_resp(conn, imapcode, imapc->state);
+ break;
+
+ case IMAP_SELECT:
+ result = imap_state_select_resp(conn, imapcode, imapc->state);
+ break;
+
+ case IMAP_FETCH:
+ result = imap_state_fetch_resp(conn, imapcode, imapc->state);
+ break;
+
+ case IMAP_FETCH_FINAL:
+ result = imap_state_fetch_final_resp(conn, imapcode, imapc->state);
+ break;
+
+ case IMAP_APPEND:
+ result = imap_state_append_resp(conn, imapcode, imapc->state);
+ break;
+
+ case IMAP_APPEND_FINAL:
+ result = imap_state_append_final_resp(conn, imapcode, imapc->state);
+ break;
+
+ case IMAP_SEARCH:
+ result = imap_state_search_resp(conn, imapcode, imapc->state);
+ break;
+
+ case IMAP_LOGOUT:
+ /* fallthrough, just stop! */
+ default:
+ /* internal error */
+ state(conn, IMAP_STOP);
+ break;
+ }
+ } while(!result && imapc->state != IMAP_STOP && Curl_pp_moredata(pp));
+
+ return result;
+}
+
+/* Called repeatedly until done from multi.c */
+static CURLcode imap_multi_statemach(struct connectdata *conn, bool *done)
+{
+ CURLcode result = CURLE_OK;
+ struct imap_conn *imapc = &conn->proto.imapc;
+
+ if((conn->handler->flags & PROTOPT_SSL) && !imapc->ssldone) {
+ result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &imapc->ssldone);
+ if(result || !imapc->ssldone)
+ return result;
+ }
+
+ result = Curl_pp_statemach(&imapc->pp, FALSE);
+ *done = (imapc->state == IMAP_STOP) ? TRUE : FALSE;
+
+ return result;
+}
+
+static CURLcode imap_block_statemach(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct imap_conn *imapc = &conn->proto.imapc;
+
+ while(imapc->state != IMAP_STOP && !result)
+ result = Curl_pp_statemach(&imapc->pp, TRUE);
+
+ return result;
+}
+
+/* Allocate and initialize the struct IMAP for the current SessionHandle if
+ required */
+static CURLcode imap_init(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct IMAP *imap;
+
+ imap = data->req.protop = calloc(sizeof(struct IMAP), 1);
+ if(!imap)
+ result = CURLE_OUT_OF_MEMORY;
+
+ return result;
+}
+
+/* For the IMAP "protocol connect" and "doing" phases only */
+static int imap_getsock(struct connectdata *conn, curl_socket_t *socks,
+ int numsocks)
+{
+ return Curl_pp_getsock(&conn->proto.imapc.pp, socks, numsocks);
+}
+
+/***********************************************************************
+ *
+ * imap_connect()
+ *
+ * This function should do everything that is to be considered a part of the
+ * connection phase.
+ *
+ * The variable 'done' points to will be TRUE if the protocol-layer connect
+ * phase is done when this function returns, or FALSE if not.
+ */
+static CURLcode imap_connect(struct connectdata *conn, bool *done)
+{
+ CURLcode result = CURLE_OK;
+ struct imap_conn *imapc = &conn->proto.imapc;
+ struct pingpong *pp = &imapc->pp;
+
+ *done = FALSE; /* default to not done yet */
+
+ /* We always support persistent connections in IMAP */
+ connkeep(conn, "IMAP default");
+
+ /* Set the default response time-out */
+ pp->response_time = RESP_TIMEOUT;
+ pp->statemach_act = imap_statemach_act;
+ pp->endofresp = imap_endofresp;
+ pp->conn = conn;
+
+ /* Set the default preferred authentication type and mechanism */
+ imapc->preftype = IMAP_TYPE_ANY;
+ Curl_sasl_init(&imapc->sasl, &saslimap);
+
+ /* Initialise the pingpong layer */
+ Curl_pp_init(pp);
+
+ /* Parse the URL options */
+ result = imap_parse_url_options(conn);
+ if(result)
+ return result;
+
+ /* Start off waiting for the server greeting response */
+ state(conn, IMAP_SERVERGREET);
+
+ /* Start off with an response id of '*' */
+ strcpy(imapc->resptag, "*");
+
+ result = imap_multi_statemach(conn, done);
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * imap_done()
+ *
+ * The DONE function. This does what needs to be done after a single DO has
+ * performed.
+ *
+ * Input argument is already checked for validity.
+ */
+static CURLcode imap_done(struct connectdata *conn, CURLcode status,
+ bool premature)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct IMAP *imap = data->req.protop;
+
+ (void)premature;
+
+ if(!imap)
+ /* When the easy handle is removed from the multi interface while libcurl
+ is still trying to resolve the host name, the IMAP struct is not yet
+ initialized. However, the removal action calls Curl_done() which in
+ turn calls this function, so we simply return success. */
+ return CURLE_OK;
+
+ if(status) {
+ connclose(conn, "IMAP done with bad status"); /* marked for closure */
+ result = status; /* use the already set error code */
+ }
+ else if(!data->set.connect_only && !imap->custom &&
+ (imap->uid || data->set.upload)) {
+ /* Handle responses after FETCH or APPEND transfer has finished */
+ if(!data->set.upload)
+ state(conn, IMAP_FETCH_FINAL);
+ else {
+ /* End the APPEND command first by sending an empty line */
+ result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", "");
+ if(!result)
+ state(conn, IMAP_APPEND_FINAL);
+ }
+
+ /* Run the state-machine
+
+ TODO: when the multi interface is used, this _really_ should be using
+ the imap_multi_statemach function but we have no general support for
+ non-blocking DONE operations, not in the multi state machine and with
+ Curl_done() invokes on several places in the code!
+ */
+ if(!result)
+ result = imap_block_statemach(conn);
+ }
+
+ /* Cleanup our per-request based variables */
+ Curl_safefree(imap->mailbox);
+ Curl_safefree(imap->uidvalidity);
+ Curl_safefree(imap->uid);
+ Curl_safefree(imap->section);
+ Curl_safefree(imap->partial);
+ Curl_safefree(imap->query);
+ Curl_safefree(imap->custom);
+ Curl_safefree(imap->custom_params);
+
+ /* Clear the transfer mode for the next request */
+ imap->transfer = FTPTRANSFER_BODY;
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform()
+ *
+ * This is the actual DO function for IMAP. Fetch or append a message, or do
+ * other things according to the options previously setup.
+ */
+static CURLcode imap_perform(struct connectdata *conn, bool *connected,
+ bool *dophase_done)
+{
+ /* This is IMAP and no proxy */
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct IMAP *imap = data->req.protop;
+ struct imap_conn *imapc = &conn->proto.imapc;
+ bool selected = FALSE;
+
+ DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+ if(conn->data->set.opt_no_body) {
+ /* Requested no body means no transfer */
+ imap->transfer = FTPTRANSFER_INFO;
+ }
+
+ *dophase_done = FALSE; /* not done yet */
+
+ /* Determine if the requested mailbox (with the same UIDVALIDITY if set)
+ has already been selected on this connection */
+ if(imap->mailbox && imapc->mailbox &&
+ !strcmp(imap->mailbox, imapc->mailbox) &&
+ (!imap->uidvalidity || !imapc->mailbox_uidvalidity ||
+ !strcmp(imap->uidvalidity, imapc->mailbox_uidvalidity)))
+ selected = TRUE;
+
+ /* Start the first command in the DO phase */
+ if(conn->data->set.upload)
+ /* APPEND can be executed directly */
+ result = imap_perform_append(conn);
+ else if(imap->custom && (selected || !imap->mailbox))
+ /* Custom command using the same mailbox or no mailbox */
+ result = imap_perform_list(conn);
+ else if(!imap->custom && selected && imap->uid)
+ /* FETCH from the same mailbox */
+ result = imap_perform_fetch(conn);
+ else if(!imap->custom && selected && imap->query)
+ /* SEARCH the current mailbox */
+ result = imap_perform_search(conn);
+ else if(imap->mailbox && !selected &&
+ (imap->custom || imap->uid || imap->query))
+ /* SELECT the mailbox */
+ result = imap_perform_select(conn);
+ else
+ /* LIST */
+ result = imap_perform_list(conn);
+
+ if(result)
+ return result;
+
+ /* Run the state-machine */
+ result = imap_multi_statemach(conn, dophase_done);
+
+ *connected = conn->bits.tcpconnect[FIRSTSOCKET];
+
+ if(*dophase_done)
+ DEBUGF(infof(conn->data, "DO phase is complete\n"));
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * imap_do()
+ *
+ * This function is registered as 'curl_do' function. It decodes the path
+ * parts etc as a wrapper to the actual DO function (imap_perform).
+ *
+ * The input argument is already checked for validity.
+ */
+static CURLcode imap_do(struct connectdata *conn, bool *done)
+{
+ CURLcode result = CURLE_OK;
+
+ *done = FALSE; /* default to false */
+
+ /* Parse the URL path */
+ result = imap_parse_url_path(conn);
+ if(result)
+ return result;
+
+ /* Parse the custom request */
+ result = imap_parse_custom_request(conn);
+ if(result)
+ return result;
+
+ result = imap_regular_transfer(conn, done);
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * imap_disconnect()
+ *
+ * Disconnect from an IMAP server. Cleanup protocol-specific per-connection
+ * resources. BLOCKING.
+ */
+static CURLcode imap_disconnect(struct connectdata *conn, bool dead_connection)
+{
+ struct imap_conn *imapc = &conn->proto.imapc;
+
+ /* We cannot send quit unconditionally. If this connection is stale or
+ bad in any way, sending quit and waiting around here will make the
+ disconnect wait in vain and cause more problems than we need to. */
+
+ /* The IMAP session may or may not have been allocated/setup at this
+ point! */
+ if(!dead_connection && imapc->pp.conn && imapc->pp.conn->bits.protoconnstart)
+ if(!imap_perform_logout(conn))
+ (void)imap_block_statemach(conn); /* ignore errors on LOGOUT */
+
+ /* Disconnect from the server */
+ Curl_pp_disconnect(&imapc->pp);
+
+ /* Cleanup the SASL module */
+ Curl_sasl_cleanup(conn, imapc->sasl.authused);
+
+ /* Cleanup our connection based variables */
+ Curl_safefree(imapc->mailbox);
+ Curl_safefree(imapc->mailbox_uidvalidity);
+
+ return CURLE_OK;
+}
+
+/* Call this when the DO phase has completed */
+static CURLcode imap_dophase_done(struct connectdata *conn, bool connected)
+{
+ struct IMAP *imap = conn->data->req.protop;
+
+ (void)connected;
+
+ if(imap->transfer != FTPTRANSFER_BODY)
+ /* no data to transfer */
+ Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+
+ return CURLE_OK;
+}
+
+/* Called from multi.c while DOing */
+static CURLcode imap_doing(struct connectdata *conn, bool *dophase_done)
+{
+ CURLcode result = imap_multi_statemach(conn, dophase_done);
+
+ if(result)
+ DEBUGF(infof(conn->data, "DO phase failed\n"));
+ else if(*dophase_done) {
+ result = imap_dophase_done(conn, FALSE /* not connected */);
+
+ DEBUGF(infof(conn->data, "DO phase is complete\n"));
+ }
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * imap_regular_transfer()
+ *
+ * The input argument is already checked for validity.
+ *
+ * Performs all commands done before a regular transfer between a local and a
+ * remote host.
+ */
+static CURLcode imap_regular_transfer(struct connectdata *conn,
+ bool *dophase_done)
+{
+ CURLcode result = CURLE_OK;
+ bool connected = FALSE;
+ struct SessionHandle *data = conn->data;
+
+ /* Make sure size is unknown at this point */
+ data->req.size = -1;
+
+ /* Set the progress data */
+ Curl_pgrsSetUploadCounter(data, 0);
+ Curl_pgrsSetDownloadCounter(data, 0);
+ Curl_pgrsSetUploadSize(data, -1);
+ Curl_pgrsSetDownloadSize(data, -1);
+
+ /* Carry out the perform */
+ result = imap_perform(conn, &connected, dophase_done);
+
+ /* Perform post DO phase operations if necessary */
+ if(!result && *dophase_done)
+ result = imap_dophase_done(conn, connected);
+
+ return result;
+}
+
+static CURLcode imap_setup_connection(struct connectdata *conn)
+{
+ struct SessionHandle *data = conn->data;
+
+ /* Initialise the IMAP layer */
+ CURLcode result = imap_init(conn);
+ if(result)
+ return result;
+
+ if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) {
+ /* Unless we have asked to tunnel IMAP operations through the proxy, we
+ switch and use HTTP operations only */
+#ifndef CURL_DISABLE_HTTP
+ if(conn->handler == &Curl_handler_imap)
+ conn->handler = &Curl_handler_imap_proxy;
+ else {
+#ifdef USE_SSL
+ conn->handler = &Curl_handler_imaps_proxy;
+#else
+ failf(data, "IMAPS not supported!");
+ return CURLE_UNSUPPORTED_PROTOCOL;
+#endif
+ }
+
+ /* set it up as an HTTP connection instead */
+ return conn->handler->setup_connection(conn);
+#else
+ failf(data, "IMAP over http proxy requires HTTP support built-in!");
+ return CURLE_UNSUPPORTED_PROTOCOL;
+#endif
+ }
+
+ data->state.path++; /* don't include the initial slash */
+
+ return CURLE_OK;
+}
+
+/***********************************************************************
+ *
+ * imap_sendf()
+ *
+ * Sends the formated string as an IMAP command to the server.
+ *
+ * Designed to never block.
+ */
+static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...)
+{
+ CURLcode result = CURLE_OK;
+ struct imap_conn *imapc = &conn->proto.imapc;
+ char *taggedfmt;
+ va_list ap;
+
+ DEBUGASSERT(fmt);
+
+ /* Calculate the next command ID wrapping at 3 digits */
+ imapc->cmdid = (imapc->cmdid + 1) % 1000;
+
+ /* Calculate the tag based on the connection ID and command ID */
+ snprintf(imapc->resptag, sizeof(imapc->resptag), "%c%03d",
+ 'A' + curlx_sltosi(conn->connection_id % 26), imapc->cmdid);
+
+ /* Prefix the format with the tag */
+ taggedfmt = aprintf("%s %s", imapc->resptag, fmt);
+ if(!taggedfmt)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Send the data with the tag */
+ va_start(ap, fmt);
+ result = Curl_pp_vsendf(&imapc->pp, taggedfmt, ap);
+ va_end(ap);
+
+ free(taggedfmt);
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * imap_atom()
+ *
+ * Checks the input string for characters that need escaping and returns an
+ * atom ready for sending to the server.
+ *
+ * The returned string needs to be freed.
+ *
+ */
+static char *imap_atom(const char *str)
+{
+ const char *p1;
+ char *p2;
+ size_t backsp_count = 0;
+ size_t quote_count = 0;
+ bool space_exists = FALSE;
+ size_t newlen = 0;
+ char *newstr = NULL;
+
+ if(!str)
+ return NULL;
+
+ /* Count any unescaped characters */
+ p1 = str;
+ while(*p1) {
+ if(*p1 == '\\')
+ backsp_count++;
+ else if(*p1 == '"')
+ quote_count++;
+ else if(*p1 == ' ')
+ space_exists = TRUE;
+
+ p1++;
+ }
+
+ /* Does the input contain any unescaped characters? */
+ if(!backsp_count && !quote_count && !space_exists)
+ return strdup(str);
+
+ /* Calculate the new string length */
+ newlen = strlen(str) + backsp_count + quote_count + (space_exists ? 2 : 0);
+
+ /* Allocate the new string */
+ newstr = (char *) malloc((newlen + 1) * sizeof(char));
+ if(!newstr)
+ return NULL;
+
+ /* Surround the string in quotes if necessary */
+ p2 = newstr;
+ if(space_exists) {
+ newstr[0] = '"';
+ newstr[newlen - 1] = '"';
+ p2++;
+ }
+
+ /* Copy the string, escaping backslash and quote characters along the way */
+ p1 = str;
+ while(*p1) {
+ if(*p1 == '\\' || *p1 == '"') {
+ *p2 = '\\';
+ p2++;
+ }
+
+ *p2 = *p1;
+
+ p1++;
+ p2++;
+ }
+
+ /* Terminate the string */
+ newstr[newlen] = '\0';
+
+ return newstr;
+}
+
+/***********************************************************************
+ *
+ * imap_is_bchar()
+ *
+ * Portable test of whether the specified char is a "bchar" as defined in the
+ * grammar of RFC-5092.
+ */
+static bool imap_is_bchar(char ch)
+{
+ switch(ch) {
+ /* bchar */
+ case ':': case '@': case '/':
+ /* bchar -> achar */
+ case '&': case '=':
+ /* bchar -> achar -> uchar -> unreserved */
+ case '0': case '1': case '2': case '3': case '4': case '5': case '6':
+ case '7': case '8': case '9':
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
+ case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
+ case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
+ case 'V': case 'W': case 'X': case 'Y': case 'Z':
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
+ case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
+ case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
+ case 'v': case 'w': case 'x': case 'y': case 'z':
+ case '-': case '.': case '_': case '~':
+ /* bchar -> achar -> uchar -> sub-delims-sh */
+ case '!': case '$': case '\'': case '(': case ')': case '*':
+ case '+': case ',':
+ /* bchar -> achar -> uchar -> pct-encoded */
+ case '%': /* HEXDIG chars are already included above */
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+/***********************************************************************
+ *
+ * imap_parse_url_options()
+ *
+ * Parse the URL login options.
+ */
+static CURLcode imap_parse_url_options(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct imap_conn *imapc = &conn->proto.imapc;
+ const char *ptr = conn->options;
+
+ imapc->sasl.resetprefs = TRUE;
+
+ while(!result && ptr && *ptr) {
+ const char *key = ptr;
+ const char *value;
+
+ while(*ptr && *ptr != '=')
+ ptr++;
+
+ value = ptr + 1;
+
+ while(*ptr && *ptr != ';')
+ ptr++;
+
+ if(strnequal(key, "AUTH=", 5))
+ result = Curl_sasl_parse_url_auth_option(&imapc->sasl,
+ value, ptr - value);
+ else
+ result = CURLE_URL_MALFORMAT;
+
+ if(*ptr == ';')
+ ptr++;
+ }
+
+ switch(imapc->sasl.prefmech) {
+ case SASL_AUTH_NONE:
+ imapc->preftype = IMAP_TYPE_NONE;
+ break;
+ case SASL_AUTH_DEFAULT:
+ imapc->preftype = IMAP_TYPE_ANY;
+ break;
+ default:
+ imapc->preftype = IMAP_TYPE_SASL;
+ break;
+ }
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * imap_parse_url_path()
+ *
+ * Parse the URL path into separate path components.
+ *
+ */
+static CURLcode imap_parse_url_path(struct connectdata *conn)
+{
+ /* The imap struct is already initialised in imap_connect() */
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct IMAP *imap = data->req.protop;
+ const char *begin = data->state.path;
+ const char *ptr = begin;
+
+ /* See how much of the URL is a valid path and decode it */
+ while(imap_is_bchar(*ptr))
+ ptr++;
+
+ if(ptr != begin) {
+ /* Remove the trailing slash if present */
+ const char *end = ptr;
+ if(end > begin && end[-1] == '/')
+ end--;
+
+ result = Curl_urldecode(data, begin, end - begin, &imap->mailbox, NULL,
+ TRUE);
+ if(result)
+ return result;
+ }
+ else
+ imap->mailbox = NULL;
+
+ /* There can be any number of parameters in the form ";NAME=VALUE" */
+ while(*ptr == ';') {
+ char *name;
+ char *value;
+ size_t valuelen;
+
+ /* Find the length of the name parameter */
+ begin = ++ptr;
+ while(*ptr && *ptr != '=')
+ ptr++;
+
+ if(!*ptr)
+ return CURLE_URL_MALFORMAT;
+
+ /* Decode the name parameter */
+ result = Curl_urldecode(data, begin, ptr - begin, &name, NULL, TRUE);
+ if(result)
+ return result;
+
+ /* Find the length of the value parameter */
+ begin = ++ptr;
+ while(imap_is_bchar(*ptr))
+ ptr++;
+
+ /* Decode the value parameter */
+ result = Curl_urldecode(data, begin, ptr - begin, &value, &valuelen, TRUE);
+ if(result) {
+ free(name);
+ return result;
+ }
+
+ DEBUGF(infof(conn->data, "IMAP URL parameter '%s' = '%s'\n", name, value));
+
+ /* Process the known hierarchical parameters (UIDVALIDITY, UID, SECTION and
+ PARTIAL) stripping of the trailing slash character if it is present.
+
+ Note: Unknown parameters trigger a URL_MALFORMAT error. */
+ if(Curl_raw_equal(name, "UIDVALIDITY") && !imap->uidvalidity) {
+ if(valuelen > 0 && value[valuelen - 1] == '/')
+ value[valuelen - 1] = '\0';
+
+ imap->uidvalidity = value;
+ value = NULL;
+ }
+ else if(Curl_raw_equal(name, "UID") && !imap->uid) {
+ if(valuelen > 0 && value[valuelen - 1] == '/')
+ value[valuelen - 1] = '\0';
+
+ imap->uid = value;
+ value = NULL;
+ }
+ else if(Curl_raw_equal(name, "SECTION") && !imap->section) {
+ if(valuelen > 0 && value[valuelen - 1] == '/')
+ value[valuelen - 1] = '\0';
+
+ imap->section = value;
+ value = NULL;
+ }
+ else if(Curl_raw_equal(name, "PARTIAL") && !imap->partial) {
+ if(valuelen > 0 && value[valuelen - 1] == '/')
+ value[valuelen - 1] = '\0';
+
+ imap->partial = value;
+ value = NULL;
+ }
+ else {
+ free(name);
+ free(value);
+
+ return CURLE_URL_MALFORMAT;
+ }
+
+ free(name);
+ free(value);
+ }
+
+ /* Does the URL contain a query parameter? Only valid when we have a mailbox
+ and no UID as per RFC-5092 */
+ if(imap->mailbox && !imap->uid && *ptr == '?') {
+ /* Find the length of the query parameter */
+ begin = ++ptr;
+ while(imap_is_bchar(*ptr))
+ ptr++;
+
+ /* Decode the query parameter */
+ result = Curl_urldecode(data, begin, ptr - begin, &imap->query, NULL,
+ TRUE);
+ if(result)
+ return result;
+ }
+
+ /* Any extra stuff at the end of the URL is an error */
+ if(*ptr)
+ return CURLE_URL_MALFORMAT;
+
+ return CURLE_OK;
+}
+
+/***********************************************************************
+ *
+ * imap_parse_custom_request()
+ *
+ * Parse the custom request.
+ */
+static CURLcode imap_parse_custom_request(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct IMAP *imap = data->req.protop;
+ const char *custom = data->set.str[STRING_CUSTOMREQUEST];
+
+ if(custom) {
+ /* URL decode the custom request */
+ result = Curl_urldecode(data, custom, 0, &imap->custom, NULL, TRUE);
+
+ /* Extract the parameters if specified */
+ if(!result) {
+ const char *params = imap->custom;
+
+ while(*params && *params != ' ')
+ params++;
+
+ if(*params) {
+ imap->custom_params = strdup(params);
+ imap->custom[params - imap->custom] = '\0';
+
+ if(!imap->custom_params)
+ result = CURLE_OUT_OF_MEMORY;
+ }
+ }
+ }
+
+ return result;
+}
+
+#endif /* CURL_DISABLE_IMAP */
diff --git a/Utilities/cmcurl/lib/imap.h b/Utilities/cmcurl/lib/imap.h
new file mode 100644
index 000000000..3189daa3c
--- /dev/null
+++ b/Utilities/cmcurl/lib/imap.h
@@ -0,0 +1,96 @@
+#ifndef HEADER_CURL_IMAP_H
+#define HEADER_CURL_IMAP_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2009 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "pingpong.h"
+#include "curl_sasl.h"
+
+/****************************************************************************
+ * IMAP unique setup
+ ***************************************************************************/
+typedef enum {
+ IMAP_STOP, /* do nothing state, stops the state machine */
+ IMAP_SERVERGREET, /* waiting for the initial greeting immediately after
+ a connect */
+ IMAP_CAPABILITY,
+ IMAP_STARTTLS,
+ IMAP_UPGRADETLS, /* asynchronously upgrade the connection to SSL/TLS
+ (multi mode only) */
+ IMAP_AUTHENTICATE,
+ IMAP_LOGIN,
+ IMAP_LIST,
+ IMAP_SELECT,
+ IMAP_FETCH,
+ IMAP_FETCH_FINAL,
+ IMAP_APPEND,
+ IMAP_APPEND_FINAL,
+ IMAP_SEARCH,
+ IMAP_LOGOUT,
+ IMAP_LAST /* never used */
+} imapstate;
+
+/* This IMAP struct is used in the SessionHandle. All IMAP data that is
+ connection-oriented must be in imap_conn to properly deal with the fact that
+ perhaps the SessionHandle is changed between the times the connection is
+ used. */
+struct IMAP {
+ curl_pp_transfer transfer;
+ char *mailbox; /* Mailbox to select */
+ char *uidvalidity; /* UIDVALIDITY to check in select */
+ char *uid; /* Message UID to fetch */
+ char *section; /* Message SECTION to fetch */
+ char *partial; /* Message PARTIAL to fetch */
+ char *query; /* Query to search for */
+ char *custom; /* Custom request */
+ char *custom_params; /* Parameters for the custom request */
+};
+
+/* imap_conn is used for struct connection-oriented data in the connectdata
+ struct */
+struct imap_conn {
+ struct pingpong pp;
+ imapstate state; /* Always use imap.c:state() to change state! */
+ bool ssldone; /* Is connect() over SSL done? */
+ struct SASL sasl; /* SASL-related parameters */
+ unsigned int preftype; /* Preferred authentication type */
+ int cmdid; /* Last used command ID */
+ char resptag[5]; /* Response tag to wait for */
+ bool tls_supported; /* StartTLS capability supported by server */
+ bool login_disabled; /* LOGIN command disabled by server */
+ bool ir_supported; /* Initial response supported by server */
+ char *mailbox; /* The last selected mailbox */
+ char *mailbox_uidvalidity; /* UIDVALIDITY parsed from select response */
+};
+
+extern const struct Curl_handler Curl_handler_imap;
+extern const struct Curl_handler Curl_handler_imaps;
+
+/* Authentication type flags */
+#define IMAP_TYPE_CLEARTEXT (1 << 0)
+#define IMAP_TYPE_SASL (1 << 1)
+
+/* Authentication type values */
+#define IMAP_TYPE_NONE 0
+#define IMAP_TYPE_ANY ~0U
+
+#endif /* HEADER_CURL_IMAP_H */
diff --git a/Utilities/cmcurl/lib/inet_ntop.c b/Utilities/cmcurl/lib/inet_ntop.c
new file mode 100644
index 000000000..da9a3ab43
--- /dev/null
+++ b/Utilities/cmcurl/lib/inet_ntop.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 1996-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * Original code by Paul Vixie. "curlified" by Gisle Vanem.
+ */
+
+#include "curl_setup.h"
+
+#ifndef HAVE_INET_NTOP
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include "curl_printf.h"
+
+#include "inet_ntop.h"
+
+#define IN6ADDRSZ 16
+#define INADDRSZ 4
+#define INT16SZ 2
+
+/*
+ * Format an IPv4 address, more or less like inet_ntoa().
+ *
+ * Returns `dst' (as a const)
+ * Note:
+ * - uses no statics
+ * - takes a unsigned char* not an in_addr as input
+ */
+static char *inet_ntop4 (const unsigned char *src, char *dst, size_t size)
+{
+ char tmp[sizeof "255.255.255.255"];
+ size_t len;
+
+ DEBUGASSERT(size >= 16);
+
+ tmp[0] = '\0';
+ (void)snprintf(tmp, sizeof(tmp), "%d.%d.%d.%d",
+ ((int)((unsigned char)src[0])) & 0xff,
+ ((int)((unsigned char)src[1])) & 0xff,
+ ((int)((unsigned char)src[2])) & 0xff,
+ ((int)((unsigned char)src[3])) & 0xff);
+
+ len = strlen(tmp);
+ if(len == 0 || len >= size) {
+ SET_ERRNO(ENOSPC);
+ return (NULL);
+ }
+ strcpy(dst, tmp);
+ return dst;
+}
+
+#ifdef ENABLE_IPV6
+/*
+ * Convert IPv6 binary address into presentation (printable) format.
+ */
+static char *inet_ntop6 (const unsigned char *src, char *dst, size_t size)
+{
+ /*
+ * Note that int32_t and int16_t need only be "at least" large enough
+ * to contain a value of the specified size. On some systems, like
+ * Crays, there is no such thing as an integer variable with 16 bits.
+ * Keep this in mind if you think this function should have been coded
+ * to use pointer overlays. All the world's not a VAX.
+ */
+ char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
+ char *tp;
+ struct {
+ long base;
+ long len;
+ } best, cur;
+ unsigned long words[IN6ADDRSZ / INT16SZ];
+ int i;
+
+ /* Preprocess:
+ * Copy the input (bytewise) array into a wordwise array.
+ * Find the longest run of 0x00's in src[] for :: shorthanding.
+ */
+ memset(words, '\0', sizeof(words));
+ for(i = 0; i < IN6ADDRSZ; i++)
+ words[i/2] |= (src[i] << ((1 - (i % 2)) << 3));
+
+ best.base = -1;
+ cur.base = -1;
+ best.len = 0;
+ cur.len = 0;
+
+ for(i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
+ if(words[i] == 0) {
+ if(cur.base == -1)
+ cur.base = i, cur.len = 1;
+ else
+ cur.len++;
+ }
+ else if(cur.base != -1) {
+ if(best.base == -1 || cur.len > best.len)
+ best = cur;
+ cur.base = -1;
+ }
+ }
+ if((cur.base != -1) && (best.base == -1 || cur.len > best.len))
+ best = cur;
+ if(best.base != -1 && best.len < 2)
+ best.base = -1;
+ /* Format the result. */
+ tp = tmp;
+ for(i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
+ /* Are we inside the best run of 0x00's? */
+ if(best.base != -1 && i >= best.base && i < (best.base + best.len)) {
+ if(i == best.base)
+ *tp++ = ':';
+ continue;
+ }
+
+ /* Are we following an initial run of 0x00s or any real hex?
+ */
+ if(i != 0)
+ *tp++ = ':';
+
+ /* Is this address an encapsulated IPv4?
+ */
+ if(i == 6 && best.base == 0 &&
+ (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
+ if(!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp))) {
+ SET_ERRNO(ENOSPC);
+ return (NULL);
+ }
+ tp += strlen(tp);
+ break;
+ }
+ tp += snprintf(tp, 5, "%lx", words[i]);
+ }
+
+ /* Was it a trailing run of 0x00's?
+ */
+ if(best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
+ *tp++ = ':';
+ *tp++ = '\0';
+
+ /* Check for overflow, copy, and we're done.
+ */
+ if((size_t)(tp - tmp) > size) {
+ SET_ERRNO(ENOSPC);
+ return (NULL);
+ }
+ strcpy(dst, tmp);
+ return dst;
+}
+#endif /* ENABLE_IPV6 */
+
+/*
+ * Convert a network format address to presentation format.
+ *
+ * Returns pointer to presentation format address (`buf').
+ * Returns NULL on error and errno set with the specific
+ * error, EAFNOSUPPORT or ENOSPC.
+ *
+ * On Windows we store the error in the thread errno, not
+ * in the winsock error code. This is to avoid losing the
+ * actual last winsock error. So use macro ERRNO to fetch the
+ * errno this function sets when returning NULL, not SOCKERRNO.
+ */
+char *Curl_inet_ntop(int af, const void *src, char *buf, size_t size)
+{
+ switch (af) {
+ case AF_INET:
+ return inet_ntop4((const unsigned char*)src, buf, size);
+#ifdef ENABLE_IPV6
+ case AF_INET6:
+ return inet_ntop6((const unsigned char*)src, buf, size);
+#endif
+ default:
+ SET_ERRNO(EAFNOSUPPORT);
+ return NULL;
+ }
+}
+#endif /* HAVE_INET_NTOP */
diff --git a/Utilities/cmcurl/lib/inet_ntop.h b/Utilities/cmcurl/lib/inet_ntop.h
new file mode 100644
index 000000000..cc4bdbb89
--- /dev/null
+++ b/Utilities/cmcurl/lib/inet_ntop.h
@@ -0,0 +1,38 @@
+#ifndef HEADER_CURL_INET_NTOP_H
+#define HEADER_CURL_INET_NTOP_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+char *Curl_inet_ntop(int af, const void *addr, char *buf, size_t size);
+
+#ifdef HAVE_INET_NTOP
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#define Curl_inet_ntop(af,addr,buf,size) \
+ inet_ntop(af, addr, buf, (curl_socklen_t)size)
+#endif
+
+#endif /* HEADER_CURL_INET_NTOP_H */
+
diff --git a/Utilities/cmcurl/lib/inet_pton.c b/Utilities/cmcurl/lib/inet_pton.c
new file mode 100644
index 000000000..f50b365da
--- /dev/null
+++ b/Utilities/cmcurl/lib/inet_pton.c
@@ -0,0 +1,234 @@
+/* This is from the BIND 4.9.4 release, modified to compile by itself */
+
+/* Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#include "curl_setup.h"
+
+#ifndef HAVE_INET_PTON
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include "inet_pton.h"
+
+#define IN6ADDRSZ 16
+#define INADDRSZ 4
+#define INT16SZ 2
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static int inet_pton4(const char *src, unsigned char *dst);
+#ifdef ENABLE_IPV6
+static int inet_pton6(const char *src, unsigned char *dst);
+#endif
+
+/* int
+ * inet_pton(af, src, dst)
+ * convert from presentation format (which usually means ASCII printable)
+ * to network format (which is usually some kind of binary format).
+ * return:
+ * 1 if the address was valid for the specified address family
+ * 0 if the address wasn't valid (`dst' is untouched in this case)
+ * -1 if some other error occurred (`dst' is untouched in this case, too)
+ * notice:
+ * On Windows we store the error in the thread errno, not
+ * in the winsock error code. This is to avoid losing the
+ * actual last winsock error. So use macro ERRNO to fetch the
+ * errno this function sets when returning (-1), not SOCKERRNO.
+ * author:
+ * Paul Vixie, 1996.
+ */
+int
+Curl_inet_pton(int af, const char *src, void *dst)
+{
+ switch (af) {
+ case AF_INET:
+ return (inet_pton4(src, (unsigned char *)dst));
+#ifdef ENABLE_IPV6
+ case AF_INET6:
+ return (inet_pton6(src, (unsigned char *)dst));
+#endif
+ default:
+ SET_ERRNO(EAFNOSUPPORT);
+ return (-1);
+ }
+ /* NOTREACHED */
+}
+
+/* int
+ * inet_pton4(src, dst)
+ * like inet_aton() but without all the hexadecimal and shorthand.
+ * return:
+ * 1 if `src' is a valid dotted quad, else 0.
+ * notice:
+ * does not touch `dst' unless it's returning 1.
+ * author:
+ * Paul Vixie, 1996.
+ */
+static int
+inet_pton4(const char *src, unsigned char *dst)
+{
+ static const char digits[] = "0123456789";
+ int saw_digit, octets, ch;
+ unsigned char tmp[INADDRSZ], *tp;
+
+ saw_digit = 0;
+ octets = 0;
+ tp = tmp;
+ *tp = 0;
+ while((ch = *src++) != '\0') {
+ const char *pch;
+
+ if((pch = strchr(digits, ch)) != NULL) {
+ unsigned int val = *tp * 10 + (unsigned int)(pch - digits);
+
+ if(saw_digit && *tp == 0)
+ return (0);
+ if(val > 255)
+ return (0);
+ *tp = (unsigned char)val;
+ if(! saw_digit) {
+ if(++octets > 4)
+ return (0);
+ saw_digit = 1;
+ }
+ }
+ else if(ch == '.' && saw_digit) {
+ if(octets == 4)
+ return (0);
+ *++tp = 0;
+ saw_digit = 0;
+ }
+ else
+ return (0);
+ }
+ if(octets < 4)
+ return (0);
+ memcpy(dst, tmp, INADDRSZ);
+ return (1);
+}
+
+#ifdef ENABLE_IPV6
+/* int
+ * inet_pton6(src, dst)
+ * convert presentation level address to network order binary form.
+ * return:
+ * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
+ * notice:
+ * (1) does not touch `dst' unless it's returning 1.
+ * (2) :: in a full address is silently ignored.
+ * credit:
+ * inspired by Mark Andrews.
+ * author:
+ * Paul Vixie, 1996.
+ */
+static int
+inet_pton6(const char *src, unsigned char *dst)
+{
+ static const char xdigits_l[] = "0123456789abcdef",
+ xdigits_u[] = "0123456789ABCDEF";
+ unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
+ const char *xdigits, *curtok;
+ int ch, saw_xdigit;
+ size_t val;
+
+ memset((tp = tmp), 0, IN6ADDRSZ);
+ endp = tp + IN6ADDRSZ;
+ colonp = NULL;
+ /* Leading :: requires some special handling. */
+ if(*src == ':')
+ if(*++src != ':')
+ return (0);
+ curtok = src;
+ saw_xdigit = 0;
+ val = 0;
+ while((ch = *src++) != '\0') {
+ const char *pch;
+
+ if((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
+ pch = strchr((xdigits = xdigits_u), ch);
+ if(pch != NULL) {
+ val <<= 4;
+ val |= (pch - xdigits);
+ if(++saw_xdigit > 4)
+ return (0);
+ continue;
+ }
+ if(ch == ':') {
+ curtok = src;
+ if(!saw_xdigit) {
+ if(colonp)
+ return (0);
+ colonp = tp;
+ continue;
+ }
+ if(tp + INT16SZ > endp)
+ return (0);
+ *tp++ = (unsigned char) (val >> 8) & 0xff;
+ *tp++ = (unsigned char) val & 0xff;
+ saw_xdigit = 0;
+ val = 0;
+ continue;
+ }
+ if(ch == '.' && ((tp + INADDRSZ) <= endp) &&
+ inet_pton4(curtok, tp) > 0) {
+ tp += INADDRSZ;
+ saw_xdigit = 0;
+ break; /* '\0' was seen by inet_pton4(). */
+ }
+ return (0);
+ }
+ if(saw_xdigit) {
+ if(tp + INT16SZ > endp)
+ return (0);
+ *tp++ = (unsigned char) (val >> 8) & 0xff;
+ *tp++ = (unsigned char) val & 0xff;
+ }
+ if(colonp != NULL) {
+ /*
+ * Since some memmove()'s erroneously fail to handle
+ * overlapping regions, we'll do the shift by hand.
+ */
+ const ssize_t n = tp - colonp;
+ ssize_t i;
+
+ if(tp == endp)
+ return (0);
+ for(i = 1; i <= n; i++) {
+ *(endp - i) = *(colonp + n - i);
+ *(colonp + n - i) = 0;
+ }
+ tp = endp;
+ }
+ if(tp != endp)
+ return (0);
+ memcpy(dst, tmp, IN6ADDRSZ);
+ return (1);
+}
+#endif /* ENABLE_IPV6 */
+
+#endif /* HAVE_INET_PTON */
diff --git a/Utilities/cmcurl/lib/inet_pton.h b/Utilities/cmcurl/lib/inet_pton.h
new file mode 100644
index 000000000..43c549143
--- /dev/null
+++ b/Utilities/cmcurl/lib/inet_pton.h
@@ -0,0 +1,37 @@
+#ifndef HEADER_CURL_INET_PTON_H
+#define HEADER_CURL_INET_PTON_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+int Curl_inet_pton(int, const char *, void *);
+
+#ifdef HAVE_INET_PTON
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#define Curl_inet_pton(x,y,z) inet_pton(x,y,z)
+#endif
+
+#endif /* HEADER_CURL_INET_PTON_H */
+
diff --git a/Utilities/cmcurl/lib/krb5.c b/Utilities/cmcurl/lib/krb5.c
new file mode 100644
index 000000000..ad7dd67af
--- /dev/null
+++ b/Utilities/cmcurl/lib/krb5.c
@@ -0,0 +1,332 @@
+/* GSSAPI/krb5 support for FTP - loosely based on old krb4.c
+ *
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * Copyright (c) 2004 - 2015 Daniel Stenberg
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE. */
+
+#include "curl_setup.h"
+
+#if defined(HAVE_GSSAPI) && !defined(CURL_DISABLE_FTP)
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#include "urldata.h"
+#include "curl_base64.h"
+#include "ftp.h"
+#include "curl_gssapi.h"
+#include "sendf.h"
+#include "curl_sec.h"
+#include "warnless.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define LOCAL_ADDR (&conn->local_addr)
+#define REMOTE_ADDR conn->ip_addr->ai_addr
+
+static int
+krb5_init(void *app_data)
+{
+ gss_ctx_id_t *context = app_data;
+ /* Make sure our context is initialized for krb5_end. */
+ *context = GSS_C_NO_CONTEXT;
+ return 0;
+}
+
+static int
+krb5_check_prot(void *app_data, int level)
+{
+ (void)app_data; /* unused */
+ if(level == PROT_CONFIDENTIAL)
+ return -1;
+ return 0;
+}
+
+static int
+krb5_decode(void *app_data, void *buf, int len,
+ int level UNUSED_PARAM,
+ struct connectdata *conn UNUSED_PARAM)
+{
+ gss_ctx_id_t *context = app_data;
+ OM_uint32 maj, min;
+ gss_buffer_desc enc, dec;
+
+ (void)level;
+ (void)conn;
+
+ enc.value = buf;
+ enc.length = len;
+ maj = gss_unseal(&min, *context, &enc, &dec, NULL, NULL);
+ if(maj != GSS_S_COMPLETE) {
+ if(len >= 4)
+ strcpy(buf, "599 ");
+ return -1;
+ }
+
+ memcpy(buf, dec.value, dec.length);
+ len = curlx_uztosi(dec.length);
+ gss_release_buffer(&min, &dec);
+
+ return len;
+}
+
+static int
+krb5_overhead(void *app_data, int level, int len)
+{
+ /* no arguments are used */
+ (void)app_data;
+ (void)level;
+ (void)len;
+ return 0;
+}
+
+static int
+krb5_encode(void *app_data, const void *from, int length, int level, void **to)
+{
+ gss_ctx_id_t *context = app_data;
+ gss_buffer_desc dec, enc;
+ OM_uint32 maj, min;
+ int state;
+ int len;
+
+ /* NOTE that the cast is safe, neither of the krb5, gnu gss and heimdal
+ * libraries modify the input buffer in gss_seal()
+ */
+ dec.value = (void*)from;
+ dec.length = length;
+ maj = gss_seal(&min, *context,
+ level == PROT_PRIVATE,
+ GSS_C_QOP_DEFAULT,
+ &dec, &state, &enc);
+
+ if(maj != GSS_S_COMPLETE)
+ return -1;
+
+ /* malloc a new buffer, in case gss_release_buffer doesn't work as
+ expected */
+ *to = malloc(enc.length);
+ if(!*to)
+ return -1;
+ memcpy(*to, enc.value, enc.length);
+ len = curlx_uztosi(enc.length);
+ gss_release_buffer(&min, &enc);
+ return len;
+}
+
+static int
+krb5_auth(void *app_data, struct connectdata *conn)
+{
+ int ret = AUTH_OK;
+ char *p;
+ const char *host = conn->host.name;
+ ssize_t nread;
+ curl_socklen_t l = sizeof(conn->local_addr);
+ struct SessionHandle *data = conn->data;
+ CURLcode result;
+ const char *service = "ftp", *srv_host = "host";
+ gss_buffer_desc input_buffer, output_buffer, _gssresp, *gssresp;
+ OM_uint32 maj, min;
+ gss_name_t gssname;
+ gss_ctx_id_t *context = app_data;
+ struct gss_channel_bindings_struct chan;
+ size_t base64_sz = 0;
+
+ if(getsockname(conn->sock[FIRSTSOCKET],
+ (struct sockaddr *)LOCAL_ADDR, &l) < 0)
+ perror("getsockname()");
+
+ chan.initiator_addrtype = GSS_C_AF_INET;
+ chan.initiator_address.length = l - 4;
+ chan.initiator_address.value =
+ &((struct sockaddr_in *)LOCAL_ADDR)->sin_addr.s_addr;
+ chan.acceptor_addrtype = GSS_C_AF_INET;
+ chan.acceptor_address.length = l - 4;
+ chan.acceptor_address.value =
+ &((struct sockaddr_in *)REMOTE_ADDR)->sin_addr.s_addr;
+ chan.application_data.length = 0;
+ chan.application_data.value = NULL;
+
+ /* this loop will execute twice (once for service, once for host) */
+ for(;;) {
+ /* this really shouldn't be repeated here, but can't help it */
+ if(service == srv_host) {
+ result = Curl_ftpsendf(conn, "AUTH GSSAPI");
+
+ if(result)
+ return -2;
+ if(Curl_GetFTPResponse(&nread, conn, NULL))
+ return -1;
+
+ if(data->state.buffer[0] != '3')
+ return -1;
+ }
+
+ input_buffer.value = data->state.buffer;
+ input_buffer.length = snprintf(input_buffer.value, BUFSIZE, "%s@%s",
+ service, host);
+ maj = gss_import_name(&min, &input_buffer, GSS_C_NT_HOSTBASED_SERVICE,
+ &gssname);
+ if(maj != GSS_S_COMPLETE) {
+ gss_release_name(&min, &gssname);
+ if(service == srv_host) {
+ Curl_failf(data, "Error importing service name %s",
+ input_buffer.value);
+ return AUTH_ERROR;
+ }
+ service = srv_host;
+ continue;
+ }
+ /* We pass NULL as |output_name_type| to avoid a leak. */
+ gss_display_name(&min, gssname, &output_buffer, NULL);
+ Curl_infof(data, "Trying against %s\n", output_buffer.value);
+ gssresp = GSS_C_NO_BUFFER;
+ *context = GSS_C_NO_CONTEXT;
+
+ do {
+ /* Release the buffer at each iteration to avoid leaking: the first time
+ we are releasing the memory from gss_display_name. The last item is
+ taken care by a final gss_release_buffer. */
+ gss_release_buffer(&min, &output_buffer);
+ ret = AUTH_OK;
+ maj = Curl_gss_init_sec_context(data,
+ &min,
+ context,
+ gssname,
+ &Curl_krb5_mech_oid,
+ &chan,
+ gssresp,
+ &output_buffer,
+ TRUE,
+ NULL);
+
+ if(gssresp) {
+ free(_gssresp.value);
+ gssresp = NULL;
+ }
+
+ if(GSS_ERROR(maj)) {
+ Curl_infof(data, "Error creating security context\n");
+ ret = AUTH_ERROR;
+ break;
+ }
+
+ if(output_buffer.length != 0) {
+ result = Curl_base64_encode(data, (char *)output_buffer.value,
+ output_buffer.length, &p, &base64_sz);
+ if(result) {
+ Curl_infof(data, "base64-encoding: %s\n",
+ curl_easy_strerror(result));
+ ret = AUTH_CONTINUE;
+ break;
+ }
+
+ result = Curl_ftpsendf(conn, "ADAT %s", p);
+
+ free(p);
+
+ if(result) {
+ ret = -2;
+ break;
+ }
+
+ if(Curl_GetFTPResponse(&nread, conn, NULL)) {
+ ret = -1;
+ break;
+ }
+
+ if(data->state.buffer[0] != '2' && data->state.buffer[0] != '3') {
+ Curl_infof(data, "Server didn't accept auth data\n");
+ ret = AUTH_ERROR;
+ break;
+ }
+
+ p = data->state.buffer + 4;
+ p = strstr(p, "ADAT=");
+ if(p) {
+ result = Curl_base64_decode(p + 5,
+ (unsigned char **)&_gssresp.value,
+ &_gssresp.length);
+ if(result) {
+ Curl_failf(data, "base64-decoding: %s",
+ curl_easy_strerror(result));
+ ret = AUTH_CONTINUE;
+ break;
+ }
+ }
+
+ gssresp = &_gssresp;
+ }
+ } while(maj == GSS_S_CONTINUE_NEEDED);
+
+ gss_release_name(&min, &gssname);
+ gss_release_buffer(&min, &output_buffer);
+
+ if(gssresp)
+ free(_gssresp.value);
+
+ if(ret == AUTH_OK || service == srv_host)
+ return ret;
+
+ service = srv_host;
+ }
+ return ret;
+}
+
+static void krb5_end(void *app_data)
+{
+ OM_uint32 min;
+ gss_ctx_id_t *context = app_data;
+ if(*context != GSS_C_NO_CONTEXT) {
+#ifdef DEBUGBUILD
+ OM_uint32 maj =
+#endif
+ gss_delete_sec_context(&min, context, GSS_C_NO_BUFFER);
+ DEBUGASSERT(maj == GSS_S_COMPLETE);
+ }
+}
+
+struct Curl_sec_client_mech Curl_krb5_client_mech = {
+ "GSSAPI",
+ sizeof(gss_ctx_id_t),
+ krb5_init,
+ krb5_auth,
+ krb5_end,
+ krb5_check_prot,
+ krb5_overhead,
+ krb5_encode,
+ krb5_decode
+};
+
+#endif /* HAVE_GSSAPI && !CURL_DISABLE_FTP */
diff --git a/Utilities/cmcurl/lib/ldap.c b/Utilities/cmcurl/lib/ldap.c
new file mode 100644
index 000000000..4d9128226
--- /dev/null
+++ b/Utilities/cmcurl/lib/ldap.c
@@ -0,0 +1,1013 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_LDAP) && !defined(USE_OPENLDAP)
+
+/*
+ * Notice that USE_OPENLDAP is only a source code selection switch. When
+ * libcurl is built with USE_OPENLDAP defined the libcurl source code that
+ * gets compiled is the code from openldap.c, otherwise the code that gets
+ * compiled is the code from ldap.c.
+ *
+ * When USE_OPENLDAP is defined a recent version of the OpenLDAP library
+ * might be required for compilation and runtime. In order to use ancient
+ * OpenLDAP library versions, USE_OPENLDAP shall not be defined.
+ */
+
+#ifdef USE_WIN32_LDAP /* Use Windows LDAP implementation. */
+# include <winldap.h>
+# ifndef LDAP_VENDOR_NAME
+# error Your Platform SDK is NOT sufficient for LDAP support! \
+ Update your Platform SDK, or disable LDAP support!
+# else
+# include <winber.h>
+# endif
+#else
+# define LDAP_DEPRECATED 1 /* Be sure ldap_init() is defined. */
+# ifdef HAVE_LBER_H
+# include <lber.h>
+# endif
+# include <ldap.h>
+# if (defined(HAVE_LDAP_SSL) && defined(HAVE_LDAP_SSL_H))
+# include <ldap_ssl.h>
+# endif /* HAVE_LDAP_SSL && HAVE_LDAP_SSL_H */
+#endif
+
+/* These are macros in both <wincrypt.h> (in above <winldap.h>) and typedefs
+ * in BoringSSL's <openssl/x509.h>
+ */
+#ifdef HAVE_BORINGSSL
+# undef X509_NAME
+# undef X509_CERT_PAIR
+# undef X509_EXTENSIONS
+#endif
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "sendf.h"
+#include "escape.h"
+#include "progress.h"
+#include "transfer.h"
+#include "strequal.h"
+#include "strtok.h"
+#include "curl_ldap.h"
+#include "curl_multibyte.h"
+#include "curl_base64.h"
+#include "rawstr.h"
+#include "connect.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#ifndef HAVE_LDAP_URL_PARSE
+
+/* Use our own implementation. */
+
+typedef struct {
+ char *lud_host;
+ int lud_port;
+#if defined(USE_WIN32_LDAP)
+ TCHAR *lud_dn;
+ TCHAR **lud_attrs;
+#else
+ char *lud_dn;
+ char **lud_attrs;
+#endif
+ int lud_scope;
+#if defined(USE_WIN32_LDAP)
+ TCHAR *lud_filter;
+#else
+ char *lud_filter;
+#endif
+ char **lud_exts;
+ size_t lud_attrs_dups; /* how many were dup'ed, this field is not in the
+ "real" struct so can only be used in code
+ without HAVE_LDAP_URL_PARSE defined */
+} CURL_LDAPURLDesc;
+
+#undef LDAPURLDesc
+#define LDAPURLDesc CURL_LDAPURLDesc
+
+static int _ldap_url_parse (const struct connectdata *conn,
+ LDAPURLDesc **ludp);
+static void _ldap_free_urldesc (LDAPURLDesc *ludp);
+
+#undef ldap_free_urldesc
+#define ldap_free_urldesc _ldap_free_urldesc
+#endif
+
+#ifdef DEBUG_LDAP
+ #define LDAP_TRACE(x) do { \
+ _ldap_trace ("%u: ", __LINE__); \
+ _ldap_trace x; \
+ } WHILE_FALSE
+
+ static void _ldap_trace (const char *fmt, ...);
+#else
+ #define LDAP_TRACE(x) Curl_nop_stmt
+#endif
+
+
+static CURLcode Curl_ldap(struct connectdata *conn, bool *done);
+
+/*
+ * LDAP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_ldap = {
+ "LDAP", /* scheme */
+ ZERO_NULL, /* setup_connection */
+ Curl_ldap, /* do_it */
+ ZERO_NULL, /* done */
+ ZERO_NULL, /* do_more */
+ ZERO_NULL, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_getsock */
+ ZERO_NULL, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ ZERO_NULL, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_LDAP, /* defport */
+ CURLPROTO_LDAP, /* protocol */
+ PROTOPT_NONE /* flags */
+};
+
+#ifdef HAVE_LDAP_SSL
+/*
+ * LDAPS protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_ldaps = {
+ "LDAPS", /* scheme */
+ ZERO_NULL, /* setup_connection */
+ Curl_ldap, /* do_it */
+ ZERO_NULL, /* done */
+ ZERO_NULL, /* do_more */
+ ZERO_NULL, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_getsock */
+ ZERO_NULL, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ ZERO_NULL, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_LDAPS, /* defport */
+ CURLPROTO_LDAPS, /* protocol */
+ PROTOPT_SSL /* flags */
+};
+#endif
+
+
+static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
+{
+ CURLcode result = CURLE_OK;
+ int rc = 0;
+ LDAP *server = NULL;
+ LDAPURLDesc *ludp = NULL;
+ LDAPMessage *ldapmsg = NULL;
+ LDAPMessage *entryIterator;
+ int num = 0;
+ struct SessionHandle *data=conn->data;
+ int ldap_proto = LDAP_VERSION3;
+ int ldap_ssl = 0;
+ char *val_b64 = NULL;
+ size_t val_b64_sz = 0;
+ curl_off_t dlsize = 0;
+#ifdef LDAP_OPT_NETWORK_TIMEOUT
+ struct timeval ldap_timeout = {10, 0}; /* 10 sec connection/search timeout */
+#endif
+#if defined(USE_WIN32_LDAP)
+ TCHAR *host = NULL;
+ TCHAR *user = NULL;
+ TCHAR *passwd = NULL;
+#else
+ char *host = NULL;
+ char *user = NULL;
+ char *passwd = NULL;
+#endif
+
+ *done = TRUE; /* unconditionally */
+ infof(data, "LDAP local: LDAP Vendor = %s ; LDAP Version = %d\n",
+ LDAP_VENDOR_NAME, LDAP_VENDOR_VERSION);
+ infof(data, "LDAP local: %s\n", data->change.url);
+
+#ifdef HAVE_LDAP_URL_PARSE
+ rc = ldap_url_parse(data->change.url, &ludp);
+#else
+ rc = _ldap_url_parse(conn, &ludp);
+#endif
+ if(rc != 0) {
+ failf(data, "LDAP local: %s", ldap_err2string(rc));
+ result = CURLE_LDAP_INVALID_URL;
+ goto quit;
+ }
+
+ /* Get the URL scheme ( either ldap or ldaps ) */
+ if(conn->given->flags & PROTOPT_SSL)
+ ldap_ssl = 1;
+ infof(data, "LDAP local: trying to establish %s connection\n",
+ ldap_ssl ? "encrypted" : "cleartext");
+
+#if defined(USE_WIN32_LDAP)
+ host = Curl_convert_UTF8_to_tchar(conn->host.name);
+ if(!host) {
+ result = CURLE_OUT_OF_MEMORY;
+
+ goto quit;
+ }
+
+ if(conn->bits.user_passwd) {
+ user = Curl_convert_UTF8_to_tchar(conn->user);
+ passwd = Curl_convert_UTF8_to_tchar(conn->passwd);
+ if(!user || !passwd) {
+ result = CURLE_OUT_OF_MEMORY;
+
+ goto quit;
+ }
+ }
+#else
+ host = conn->host.name;
+
+ if(conn->bits.user_passwd) {
+ user = conn->user;
+ passwd = conn->passwd;
+ }
+#endif
+
+#ifdef LDAP_OPT_NETWORK_TIMEOUT
+ ldap_set_option(NULL, LDAP_OPT_NETWORK_TIMEOUT, &ldap_timeout);
+#endif
+ ldap_set_option(NULL, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
+
+ if(ldap_ssl) {
+#ifdef HAVE_LDAP_SSL
+#ifdef USE_WIN32_LDAP
+ /* Win32 LDAP SDK doesn't support insecure mode without CA! */
+ server = ldap_sslinit(host, (int)conn->port, 1);
+ ldap_set_option(server, LDAP_OPT_SSL, LDAP_OPT_ON);
+#else
+ int ldap_option;
+ char* ldap_ca = data->set.str[STRING_SSL_CAFILE];
+#if defined(CURL_HAS_NOVELL_LDAPSDK)
+ rc = ldapssl_client_init(NULL, NULL);
+ if(rc != LDAP_SUCCESS) {
+ failf(data, "LDAP local: ldapssl_client_init %s", ldap_err2string(rc));
+ result = CURLE_SSL_CERTPROBLEM;
+ goto quit;
+ }
+ if(data->set.ssl.verifypeer) {
+ /* Novell SDK supports DER or BASE64 files. */
+ int cert_type = LDAPSSL_CERT_FILETYPE_B64;
+ if((data->set.str[STRING_CERT_TYPE]) &&
+ (Curl_raw_equal(data->set.str[STRING_CERT_TYPE], "DER")))
+ cert_type = LDAPSSL_CERT_FILETYPE_DER;
+ if(!ldap_ca) {
+ failf(data, "LDAP local: ERROR %s CA cert not set!",
+ (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"));
+ result = CURLE_SSL_CERTPROBLEM;
+ goto quit;
+ }
+ infof(data, "LDAP local: using %s CA cert '%s'\n",
+ (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"),
+ ldap_ca);
+ rc = ldapssl_add_trusted_cert(ldap_ca, cert_type);
+ if(rc != LDAP_SUCCESS) {
+ failf(data, "LDAP local: ERROR setting %s CA cert: %s",
+ (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"),
+ ldap_err2string(rc));
+ result = CURLE_SSL_CERTPROBLEM;
+ goto quit;
+ }
+ ldap_option = LDAPSSL_VERIFY_SERVER;
+ }
+ else
+ ldap_option = LDAPSSL_VERIFY_NONE;
+ rc = ldapssl_set_verify_mode(ldap_option);
+ if(rc != LDAP_SUCCESS) {
+ failf(data, "LDAP local: ERROR setting cert verify mode: %s",
+ ldap_err2string(rc));
+ result = CURLE_SSL_CERTPROBLEM;
+ goto quit;
+ }
+ server = ldapssl_init(host, (int)conn->port, 1);
+ if(server == NULL) {
+ failf(data, "LDAP local: Cannot connect to %s:%ld",
+ conn->host.dispname, conn->port);
+ result = CURLE_COULDNT_CONNECT;
+ goto quit;
+ }
+#elif defined(LDAP_OPT_X_TLS)
+ if(data->set.ssl.verifypeer) {
+ /* OpenLDAP SDK supports BASE64 files. */
+ if((data->set.str[STRING_CERT_TYPE]) &&
+ (!Curl_raw_equal(data->set.str[STRING_CERT_TYPE], "PEM"))) {
+ failf(data, "LDAP local: ERROR OpenLDAP only supports PEM cert-type!");
+ result = CURLE_SSL_CERTPROBLEM;
+ goto quit;
+ }
+ if(!ldap_ca) {
+ failf(data, "LDAP local: ERROR PEM CA cert not set!");
+ result = CURLE_SSL_CERTPROBLEM;
+ goto quit;
+ }
+ infof(data, "LDAP local: using PEM CA cert: %s\n", ldap_ca);
+ rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, ldap_ca);
+ if(rc != LDAP_SUCCESS) {
+ failf(data, "LDAP local: ERROR setting PEM CA cert: %s",
+ ldap_err2string(rc));
+ result = CURLE_SSL_CERTPROBLEM;
+ goto quit;
+ }
+ ldap_option = LDAP_OPT_X_TLS_DEMAND;
+ }
+ else
+ ldap_option = LDAP_OPT_X_TLS_NEVER;
+
+ rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &ldap_option);
+ if(rc != LDAP_SUCCESS) {
+ failf(data, "LDAP local: ERROR setting cert verify mode: %s",
+ ldap_err2string(rc));
+ result = CURLE_SSL_CERTPROBLEM;
+ goto quit;
+ }
+ server = ldap_init(host, (int)conn->port);
+ if(server == NULL) {
+ failf(data, "LDAP local: Cannot connect to %s:%ld",
+ conn->host.dispname, conn->port);
+ result = CURLE_COULDNT_CONNECT;
+ goto quit;
+ }
+ ldap_option = LDAP_OPT_X_TLS_HARD;
+ rc = ldap_set_option(server, LDAP_OPT_X_TLS, &ldap_option);
+ if(rc != LDAP_SUCCESS) {
+ failf(data, "LDAP local: ERROR setting SSL/TLS mode: %s",
+ ldap_err2string(rc));
+ result = CURLE_SSL_CERTPROBLEM;
+ goto quit;
+ }
+/*
+ rc = ldap_start_tls_s(server, NULL, NULL);
+ if(rc != LDAP_SUCCESS) {
+ failf(data, "LDAP local: ERROR starting SSL/TLS mode: %s",
+ ldap_err2string(rc));
+ result = CURLE_SSL_CERTPROBLEM;
+ goto quit;
+ }
+*/
+#else
+ /* we should probably never come up to here since configure
+ should check in first place if we can support LDAP SSL/TLS */
+ failf(data, "LDAP local: SSL/TLS not supported with this version "
+ "of the OpenLDAP toolkit\n");
+ result = CURLE_SSL_CERTPROBLEM;
+ goto quit;
+#endif
+#endif
+#endif /* CURL_LDAP_USE_SSL */
+ }
+ else {
+ server = ldap_init(host, (int)conn->port);
+ if(server == NULL) {
+ failf(data, "LDAP local: Cannot connect to %s:%ld",
+ conn->host.dispname, conn->port);
+ result = CURLE_COULDNT_CONNECT;
+ goto quit;
+ }
+ }
+#ifdef USE_WIN32_LDAP
+ ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
+#endif
+
+ rc = ldap_simple_bind_s(server, user, passwd);
+ if(!ldap_ssl && rc != 0) {
+ ldap_proto = LDAP_VERSION2;
+ ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
+ rc = ldap_simple_bind_s(server, user, passwd);
+ }
+ if(rc != 0) {
+ failf(data, "LDAP local: ldap_simple_bind_s %s", ldap_err2string(rc));
+ result = CURLE_LDAP_CANNOT_BIND;
+ goto quit;
+ }
+
+ rc = ldap_search_s(server, ludp->lud_dn, ludp->lud_scope,
+ ludp->lud_filter, ludp->lud_attrs, 0, &ldapmsg);
+
+ if(rc != 0 && rc != LDAP_SIZELIMIT_EXCEEDED) {
+ failf(data, "LDAP remote: %s", ldap_err2string(rc));
+ result = CURLE_LDAP_SEARCH_FAILED;
+ goto quit;
+ }
+
+ for(num = 0, entryIterator = ldap_first_entry(server, ldapmsg);
+ entryIterator;
+ entryIterator = ldap_next_entry(server, entryIterator), num++) {
+ BerElement *ber = NULL;
+#if defined(USE_WIN32_LDAP)
+ TCHAR *attribute;
+#else
+ char *attribute; /*! suspicious that this isn't 'const' */
+#endif
+ int i;
+
+ /* Get the DN and write it to the client */
+ {
+ char *name;
+ size_t name_len;
+#if defined(USE_WIN32_LDAP)
+ TCHAR *dn = ldap_get_dn(server, entryIterator);
+ name = Curl_convert_tchar_to_UTF8(dn);
+ if(!name) {
+ ldap_memfree(dn);
+
+ result = CURLE_OUT_OF_MEMORY;
+
+ goto quit;
+ }
+#else
+ char *dn = name = ldap_get_dn(server, entryIterator);
+#endif
+ name_len = strlen(name);
+
+ result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
+ if(result) {
+#if defined(USE_WIN32_LDAP)
+ Curl_unicodefree(name);
+#endif
+ ldap_memfree(dn);
+
+ goto quit;
+ }
+
+ result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *) name,
+ name_len);
+ if(result) {
+#if defined(USE_WIN32_LDAP)
+ Curl_unicodefree(name);
+#endif
+ ldap_memfree(dn);
+
+ goto quit;
+ }
+
+ result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
+ if(result) {
+#if defined(USE_WIN32_LDAP)
+ Curl_unicodefree(name);
+#endif
+ ldap_memfree(dn);
+
+ goto quit;
+ }
+
+ dlsize += name_len + 5;
+
+#if defined(USE_WIN32_LDAP)
+ Curl_unicodefree(name);
+#endif
+ ldap_memfree(dn);
+ }
+
+ /* Get the attributes and write them to the client */
+ for(attribute = ldap_first_attribute(server, entryIterator, &ber);
+ attribute;
+ attribute = ldap_next_attribute(server, entryIterator, ber)) {
+ BerValue **vals;
+ size_t attr_len;
+#if defined(USE_WIN32_LDAP)
+ char *attr = Curl_convert_tchar_to_UTF8(attribute);
+ if(!attr) {
+ if(ber)
+ ber_free(ber, 0);
+
+ result = CURLE_OUT_OF_MEMORY;
+
+ goto quit;
+ }
+#else
+ char *attr = attribute;
+#endif
+ attr_len = strlen(attr);
+
+ vals = ldap_get_values_len(server, entryIterator, attribute);
+ if(vals != NULL) {
+ for(i = 0; (vals[i] != NULL); i++) {
+ result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
+ if(result) {
+ ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+ Curl_unicodefree(attr);
+#endif
+ ldap_memfree(attribute);
+ if(ber)
+ ber_free(ber, 0);
+
+ goto quit;
+ }
+
+ result = Curl_client_write(conn, CLIENTWRITE_BODY,
+ (char *) attr, attr_len);
+ if(result) {
+ ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+ Curl_unicodefree(attr);
+#endif
+ ldap_memfree(attribute);
+ if(ber)
+ ber_free(ber, 0);
+
+ goto quit;
+ }
+
+ result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2);
+ if(result) {
+ ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+ Curl_unicodefree(attr);
+#endif
+ ldap_memfree(attribute);
+ if(ber)
+ ber_free(ber, 0);
+
+ goto quit;
+ }
+
+ dlsize += attr_len + 3;
+
+ if((attr_len > 7) &&
+ (strcmp(";binary", (char *) attr + (attr_len - 7)) == 0)) {
+ /* Binary attribute, encode to base64. */
+ result = Curl_base64_encode(data,
+ vals[i]->bv_val,
+ vals[i]->bv_len,
+ &val_b64,
+ &val_b64_sz);
+ if(result) {
+ ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+ Curl_unicodefree(attr);
+#endif
+ ldap_memfree(attribute);
+ if(ber)
+ ber_free(ber, 0);
+
+ goto quit;
+ }
+
+ if(val_b64_sz > 0) {
+ result = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64,
+ val_b64_sz);
+ free(val_b64);
+ if(result) {
+ ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+ Curl_unicodefree(attr);
+#endif
+ ldap_memfree(attribute);
+ if(ber)
+ ber_free(ber, 0);
+
+ goto quit;
+ }
+
+ dlsize += val_b64_sz;
+ }
+ }
+ else {
+ result = Curl_client_write(conn, CLIENTWRITE_BODY, vals[i]->bv_val,
+ vals[i]->bv_len);
+ if(result) {
+ ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+ Curl_unicodefree(attr);
+#endif
+ ldap_memfree(attribute);
+ if(ber)
+ ber_free(ber, 0);
+
+ goto quit;
+ }
+
+ dlsize += vals[i]->bv_len;
+ }
+
+ result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
+ if(result) {
+ ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+ Curl_unicodefree(attr);
+#endif
+ ldap_memfree(attribute);
+ if(ber)
+ ber_free(ber, 0);
+
+ goto quit;
+ }
+
+ dlsize++;
+ }
+
+ /* Free memory used to store values */
+ ldap_value_free_len(vals);
+ }
+
+ /* Free the attribute as we are done with it */
+#if defined(USE_WIN32_LDAP)
+ Curl_unicodefree(attr);
+#endif
+ ldap_memfree(attribute);
+
+ result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
+ if(result)
+ goto quit;
+ dlsize++;
+ Curl_pgrsSetDownloadCounter(data, dlsize);
+ }
+
+ if(ber)
+ ber_free(ber, 0);
+ }
+
+quit:
+ if(ldapmsg) {
+ ldap_msgfree(ldapmsg);
+ LDAP_TRACE (("Received %d entries\n", num));
+ }
+ if(rc == LDAP_SIZELIMIT_EXCEEDED)
+ infof(data, "There are more than %d entries\n", num);
+ if(ludp)
+ ldap_free_urldesc(ludp);
+ if(server)
+ ldap_unbind_s(server);
+#if defined(HAVE_LDAP_SSL) && defined(CURL_HAS_NOVELL_LDAPSDK)
+ if(ldap_ssl)
+ ldapssl_client_deinit();
+#endif /* HAVE_LDAP_SSL && CURL_HAS_NOVELL_LDAPSDK */
+
+#if defined(USE_WIN32_LDAP)
+ Curl_unicodefree(passwd);
+ Curl_unicodefree(user);
+ Curl_unicodefree(host);
+#endif
+
+ /* no data to transfer */
+ Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+ connclose(conn, "LDAP connection always disable re-use");
+
+ return result;
+}
+
+#ifdef DEBUG_LDAP
+static void _ldap_trace (const char *fmt, ...)
+{
+ static int do_trace = -1;
+ va_list args;
+
+ if(do_trace == -1) {
+ const char *env = getenv("CURL_TRACE");
+ do_trace = (env && strtol(env, NULL, 10) > 0);
+ }
+ if(!do_trace)
+ return;
+
+ va_start (args, fmt);
+ vfprintf (stderr, fmt, args);
+ va_end (args);
+}
+#endif
+
+#ifndef HAVE_LDAP_URL_PARSE
+
+/*
+ * Return scope-value for a scope-string.
+ */
+static int str2scope (const char *p)
+{
+ if(strequal(p, "one"))
+ return LDAP_SCOPE_ONELEVEL;
+ if(strequal(p, "onetree"))
+ return LDAP_SCOPE_ONELEVEL;
+ if(strequal(p, "base"))
+ return LDAP_SCOPE_BASE;
+ if(strequal(p, "sub"))
+ return LDAP_SCOPE_SUBTREE;
+ if(strequal( p, "subtree"))
+ return LDAP_SCOPE_SUBTREE;
+ return (-1);
+}
+
+/*
+ * Split 'str' into strings separated by commas.
+ * Note: out[] points into 'str'.
+ */
+static bool split_str(char *str, char ***out, size_t *count)
+{
+ char **res;
+ char *lasts;
+ char *s;
+ size_t i;
+ size_t items = 1;
+
+ s = strchr(str, ',');
+ while(s) {
+ items++;
+ s = strchr(++s, ',');
+ }
+
+ res = calloc(items, sizeof(char *));
+ if(!res)
+ return FALSE;
+
+ for(i = 0, s = strtok_r(str, ",", &lasts); s && i < items;
+ s = strtok_r(NULL, ",", &lasts), i++)
+ res[i] = s;
+
+ *out = res;
+ *count = items;
+
+ return TRUE;
+}
+
+/*
+ * Break apart the pieces of an LDAP URL.
+ * Syntax:
+ * ldap://<hostname>:<port>/<base_dn>?<attributes>?<scope>?<filter>?<ext>
+ *
+ * <hostname> already known from 'conn->host.name'.
+ * <port> already known from 'conn->remote_port'.
+ * extract the rest from 'conn->data->state.path+1'. All fields are optional.
+ * e.g.
+ * ldap://<hostname>:<port>/?<attributes>?<scope>?<filter>
+ * yields ludp->lud_dn = "".
+ *
+ * Defined in RFC4516 section 2.
+ */
+static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp)
+{
+ int rc = LDAP_SUCCESS;
+ char *path;
+ char *p;
+ char *q;
+ size_t i;
+
+ if(!conn->data ||
+ !conn->data->state.path ||
+ conn->data->state.path[0] != '/' ||
+ !checkprefix("LDAP", conn->data->change.url))
+ return LDAP_INVALID_SYNTAX;
+
+ ludp->lud_scope = LDAP_SCOPE_BASE;
+ ludp->lud_port = conn->remote_port;
+ ludp->lud_host = conn->host.name;
+
+ /* Duplicate the path */
+ p = path = strdup(conn->data->state.path + 1);
+ if(!path)
+ return LDAP_NO_MEMORY;
+
+ /* Parse the DN (Distinguished Name) */
+ q = strchr(p, '?');
+ if(q)
+ *q++ = '\0';
+
+ if(*p) {
+ char *dn = p;
+ char *unescaped;
+
+ LDAP_TRACE (("DN '%s'\n", dn));
+
+ /* Unescape the DN */
+ unescaped = curl_easy_unescape(conn->data, dn, 0, NULL);
+ if(!unescaped) {
+ rc = LDAP_NO_MEMORY;
+
+ goto quit;
+ }
+
+#if defined(USE_WIN32_LDAP)
+ /* Convert the unescaped string to a tchar */
+ ludp->lud_dn = Curl_convert_UTF8_to_tchar(unescaped);
+
+ /* Free the unescaped string as we are done with it */
+ Curl_unicodefree(unescaped);
+
+ if(!ludp->lud_dn) {
+ rc = LDAP_NO_MEMORY;
+
+ goto quit;
+ }
+#else
+ ludp->lud_dn = unescaped;
+#endif
+ }
+
+ p = q;
+ if(!p)
+ goto quit;
+
+ /* Parse the attributes. skip "??" */
+ q = strchr(p, '?');
+ if(q)
+ *q++ = '\0';
+
+ if(*p) {
+ char **attributes;
+ size_t count = 0;
+
+ /* Split the string into an array of attributes */
+ if(!split_str(p, &attributes, &count)) {
+ rc = LDAP_NO_MEMORY;
+
+ goto quit;
+ }
+
+ /* Allocate our array (+1 for the NULL entry) */
+#if defined(USE_WIN32_LDAP)
+ ludp->lud_attrs = calloc(count + 1, sizeof(TCHAR *));
+#else
+ ludp->lud_attrs = calloc(count + 1, sizeof(char *));
+#endif
+ if(!ludp->lud_attrs) {
+ free(attributes);
+
+ rc = LDAP_NO_MEMORY;
+
+ goto quit;
+ }
+
+ for(i = 0; i < count; i++) {
+ char *unescaped;
+
+ LDAP_TRACE (("attr[%d] '%s'\n", i, attributes[i]));
+
+ /* Unescape the attribute */
+ unescaped = curl_easy_unescape(conn->data, attributes[i], 0, NULL);
+ if(!unescaped) {
+ free(attributes);
+
+ rc = LDAP_NO_MEMORY;
+
+ goto quit;
+ }
+
+#if defined(USE_WIN32_LDAP)
+ /* Convert the unescaped string to a tchar */
+ ludp->lud_attrs[i] = Curl_convert_UTF8_to_tchar(unescaped);
+
+ /* Free the unescaped string as we are done with it */
+ Curl_unicodefree(unescaped);
+
+ if(!ludp->lud_attrs[i]) {
+ free(attributes);
+
+ rc = LDAP_NO_MEMORY;
+
+ goto quit;
+ }
+#else
+ ludp->lud_attrs[i] = unescaped;
+#endif
+
+ ludp->lud_attrs_dups++;
+ }
+
+ free(attributes);
+ }
+
+ p = q;
+ if(!p)
+ goto quit;
+
+ /* Parse the scope. skip "??" */
+ q = strchr(p, '?');
+ if(q)
+ *q++ = '\0';
+
+ if(*p) {
+ ludp->lud_scope = str2scope(p);
+ if(ludp->lud_scope == -1) {
+ rc = LDAP_INVALID_SYNTAX;
+
+ goto quit;
+ }
+ LDAP_TRACE (("scope %d\n", ludp->lud_scope));
+ }
+
+ p = q;
+ if(!p)
+ goto quit;
+
+ /* Parse the filter */
+ q = strchr(p, '?');
+ if(q)
+ *q++ = '\0';
+
+ if(*p) {
+ char *filter = p;
+ char *unescaped;
+
+ LDAP_TRACE (("filter '%s'\n", filter));
+
+ /* Unescape the filter */
+ unescaped = curl_easy_unescape(conn->data, filter, 0, NULL);
+ if(!unescaped) {
+ rc = LDAP_NO_MEMORY;
+
+ goto quit;
+ }
+
+#if defined(USE_WIN32_LDAP)
+ /* Convert the unescaped string to a tchar */
+ ludp->lud_filter = Curl_convert_UTF8_to_tchar(unescaped);
+
+ /* Free the unescaped string as we are done with it */
+ Curl_unicodefree(unescaped);
+
+ if(!ludp->lud_filter) {
+ rc = LDAP_NO_MEMORY;
+
+ goto quit;
+ }
+#else
+ ludp->lud_filter = unescaped;
+#endif
+ }
+
+ p = q;
+ if(p && !*p) {
+ rc = LDAP_INVALID_SYNTAX;
+
+ goto quit;
+ }
+
+quit:
+ free(path);
+
+ return rc;
+}
+
+static int _ldap_url_parse (const struct connectdata *conn,
+ LDAPURLDesc **ludpp)
+{
+ LDAPURLDesc *ludp = calloc(1, sizeof(*ludp));
+ int rc;
+
+ *ludpp = NULL;
+ if(!ludp)
+ return LDAP_NO_MEMORY;
+
+ rc = _ldap_url_parse2 (conn, ludp);
+ if(rc != LDAP_SUCCESS) {
+ _ldap_free_urldesc(ludp);
+ ludp = NULL;
+ }
+ *ludpp = ludp;
+ return (rc);
+}
+
+static void _ldap_free_urldesc (LDAPURLDesc *ludp)
+{
+ size_t i;
+
+ if(!ludp)
+ return;
+
+ free(ludp->lud_dn);
+ free(ludp->lud_filter);
+
+ if(ludp->lud_attrs) {
+ for(i = 0; i < ludp->lud_attrs_dups; i++)
+ free(ludp->lud_attrs[i]);
+ free(ludp->lud_attrs);
+ }
+
+ free (ludp);
+}
+#endif /* !HAVE_LDAP_URL_PARSE */
+#endif /* !CURL_DISABLE_LDAP && !USE_OPENLDAP */
diff --git a/Utilities/cmcurl/lib/libcurl.rc b/Utilities/cmcurl/lib/libcurl.rc
new file mode 100644
index 000000000..47b944ac8
--- /dev/null
+++ b/Utilities/cmcurl/lib/libcurl.rc
@@ -0,0 +1,63 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <winver.h>
+#include "../include/curl/curlver.h"
+
+LANGUAGE 0x09,0x01
+
+#define RC_VERSION LIBCURL_VERSION_MAJOR, LIBCURL_VERSION_MINOR, LIBCURL_VERSION_PATCH, 0
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION RC_VERSION
+ PRODUCTVERSION RC_VERSION
+ FILEFLAGSMASK 0x3fL
+#if defined(DEBUGBUILD) || defined(_DEBUG)
+ FILEFLAGS 1
+#else
+ FILEFLAGS 0
+#endif
+ FILEOS VOS__WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0x0L
+
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "The cURL library, http://curl.haxx.se/\0"
+ VALUE "FileDescription", "libcurl Shared Library\0"
+ VALUE "FileVersion", LIBCURL_VERSION "\0"
+ VALUE "InternalName", "libcurl\0"
+ VALUE "OriginalFilename", "libcurl.dll\0"
+ VALUE "ProductName", "The cURL library\0"
+ VALUE "ProductVersion", LIBCURL_VERSION "\0"
+ VALUE "LegalCopyright", "© " LIBCURL_COPYRIGHT "\0"
+ VALUE "License", "http://curl.haxx.se/docs/copyright.html\0"
+ END
+ END
+
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/Utilities/cmcurl/lib/llist.c b/Utilities/cmcurl/lib/llist.c
new file mode 100644
index 000000000..40bb62837
--- /dev/null
+++ b/Utilities/cmcurl/lib/llist.c
@@ -0,0 +1,212 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "llist.h"
+#include "curl_memory.h"
+
+/* this must be the last include file */
+#include "memdebug.h"
+
+/*
+ * @unittest: 1300
+ */
+static void
+llist_init(struct curl_llist *l, curl_llist_dtor dtor)
+{
+ l->size = 0;
+ l->dtor = dtor;
+ l->head = NULL;
+ l->tail = NULL;
+}
+
+struct curl_llist *
+Curl_llist_alloc(curl_llist_dtor dtor)
+{
+ struct curl_llist *list;
+
+ list = malloc(sizeof(struct curl_llist));
+ if(!list)
+ return NULL;
+
+ llist_init(list, dtor);
+
+ return list;
+}
+
+/*
+ * Curl_llist_insert_next()
+ *
+ * Inserts a new list element after the given one 'e'. If the given existing
+ * entry is NULL and the list already has elements, the new one will be
+ * inserted first in the list.
+ *
+ * Returns: 1 on success and 0 on failure.
+ *
+ * @unittest: 1300
+ */
+int
+Curl_llist_insert_next(struct curl_llist *list, struct curl_llist_element *e,
+ const void *p)
+{
+ struct curl_llist_element *ne = malloc(sizeof(struct curl_llist_element));
+ if(!ne)
+ return 0;
+
+ ne->ptr = (void *) p;
+ if(list->size == 0) {
+ list->head = ne;
+ list->head->prev = NULL;
+ list->head->next = NULL;
+ list->tail = ne;
+ }
+ else {
+ /* if 'e' is NULL here, we insert the new element first in the list */
+ ne->next = e?e->next:list->head;
+ ne->prev = e;
+ if(!e) {
+ list->head->prev = ne;
+ list->head = ne;
+ }
+ else if(e->next) {
+ e->next->prev = ne;
+ }
+ else {
+ list->tail = ne;
+ }
+ if(e)
+ e->next = ne;
+ }
+
+ ++list->size;
+
+ return 1;
+}
+
+/*
+ * @unittest: 1300
+ */
+int
+Curl_llist_remove(struct curl_llist *list, struct curl_llist_element *e,
+ void *user)
+{
+ if(e == NULL || list->size == 0)
+ return 1;
+
+ if(e == list->head) {
+ list->head = e->next;
+
+ if(list->head == NULL)
+ list->tail = NULL;
+ else
+ e->next->prev = NULL;
+ }
+ else {
+ e->prev->next = e->next;
+ if(!e->next)
+ list->tail = e->prev;
+ else
+ e->next->prev = e->prev;
+ }
+
+ list->dtor(user, e->ptr);
+
+ e->ptr = NULL;
+ e->prev = NULL;
+ e->next = NULL;
+
+ free(e);
+ --list->size;
+
+ return 1;
+}
+
+void
+Curl_llist_destroy(struct curl_llist *list, void *user)
+{
+ if(list) {
+ while(list->size > 0)
+ Curl_llist_remove(list, list->tail, user);
+
+ free(list);
+ }
+}
+
+size_t
+Curl_llist_count(struct curl_llist *list)
+{
+ return list->size;
+}
+
+/*
+ * @unittest: 1300
+ */
+int Curl_llist_move(struct curl_llist *list, struct curl_llist_element *e,
+ struct curl_llist *to_list,
+ struct curl_llist_element *to_e)
+{
+ /* Remove element from list */
+ if(e == NULL || list->size == 0)
+ return 0;
+
+ if(e == list->head) {
+ list->head = e->next;
+
+ if(list->head == NULL)
+ list->tail = NULL;
+ else
+ e->next->prev = NULL;
+ }
+ else {
+ e->prev->next = e->next;
+ if(!e->next)
+ list->tail = e->prev;
+ else
+ e->next->prev = e->prev;
+ }
+
+ --list->size;
+
+ /* Add element to to_list after to_e */
+ if(to_list->size == 0) {
+ to_list->head = e;
+ to_list->head->prev = NULL;
+ to_list->head->next = NULL;
+ to_list->tail = e;
+ }
+ else {
+ e->next = to_e->next;
+ e->prev = to_e;
+ if(to_e->next) {
+ to_e->next->prev = e;
+ }
+ else {
+ to_list->tail = e;
+ }
+ to_e->next = e;
+ }
+
+ ++to_list->size;
+
+ return 1;
+}
diff --git a/Utilities/cmcurl/lib/llist.h b/Utilities/cmcurl/lib/llist.h
new file mode 100644
index 000000000..27ddb719a
--- /dev/null
+++ b/Utilities/cmcurl/lib/llist.h
@@ -0,0 +1,57 @@
+#ifndef HEADER_CURL_LLIST_H
+#define HEADER_CURL_LLIST_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include <stddef.h>
+
+typedef void (*curl_llist_dtor)(void *, void *);
+
+struct curl_llist_element {
+ void *ptr;
+
+ struct curl_llist_element *prev;
+ struct curl_llist_element *next;
+};
+
+struct curl_llist {
+ struct curl_llist_element *head;
+ struct curl_llist_element *tail;
+
+ curl_llist_dtor dtor;
+
+ size_t size;
+};
+
+struct curl_llist *Curl_llist_alloc(curl_llist_dtor);
+int Curl_llist_insert_next(struct curl_llist *, struct curl_llist_element *,
+ const void *);
+int Curl_llist_remove(struct curl_llist *, struct curl_llist_element *,
+ void *);
+size_t Curl_llist_count(struct curl_llist *);
+void Curl_llist_destroy(struct curl_llist *, void *);
+int Curl_llist_move(struct curl_llist *, struct curl_llist_element *,
+ struct curl_llist *, struct curl_llist_element *);
+
+#endif /* HEADER_CURL_LLIST_H */
+
diff --git a/Utilities/cmcurl/lib/md4.c b/Utilities/cmcurl/lib/md4.c
new file mode 100644
index 000000000..60f73a28b
--- /dev/null
+++ b/Utilities/cmcurl/lib/md4.c
@@ -0,0 +1,304 @@
+/*
+ * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
+ * MD4 Message-Digest Algorithm (RFC 1320).
+ *
+ * Homepage:
+ http://openwall.info/wiki/people/solar/software/public-domain-source-code/md4
+ *
+ * Author:
+ * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
+ *
+ * This software was written by Alexander Peslyak in 2001. No copyright is
+ * claimed, and the software is hereby placed in the public domain. In case
+ * this attempt to disclaim copyright and place the software in the public
+ * domain is deemed null and void, then the software is Copyright (c) 2001
+ * Alexander Peslyak and it is hereby released to the general public under the
+ * following terms:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted.
+ *
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
+ *
+ * (This is a heavily cut-down "BSD license".)
+ *
+ * This differs from Colin Plumb's older public domain implementation in that
+ * no exactly 32-bit integer data type is required (any 32-bit or wider
+ * unsigned integer data type will do), there's no compile-time endianness
+ * configuration, and the function prototypes match OpenSSL's. No code from
+ * Colin Plumb's implementation has been reused; this comment merely compares
+ * the properties of the two independent implementations.
+ *
+ * The primary goals of this implementation are portability and ease of use.
+ * It is meant to be fast, but not as fast as possible. Some known
+ * optimizations are not included to reduce source code size and avoid
+ * compile-time configuration.
+ */
+
+#include "curl_setup.h"
+
+/* NSS and OS/400 crypto library do not provide the MD4 hash algorithm, so
+ * that we have a local implementation of it */
+#if defined(USE_NSS) || defined(USE_OS400CRYPTO)
+
+#include "curl_md4.h"
+#include "warnless.h"
+
+#ifndef HAVE_OPENSSL
+
+#include <string.h>
+
+/* Any 32-bit or wider unsigned integer data type will do */
+typedef unsigned int MD4_u32plus;
+
+typedef struct {
+ MD4_u32plus lo, hi;
+ MD4_u32plus a, b, c, d;
+ unsigned char buffer[64];
+ MD4_u32plus block[16];
+} MD4_CTX;
+
+static void MD4_Init(MD4_CTX *ctx);
+static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size);
+static void MD4_Final(unsigned char *result, MD4_CTX *ctx);
+
+/*
+ * The basic MD4 functions.
+ *
+ * F and G are optimized compared to their RFC 1320 definitions, with the
+ * optimization for F borrowed from Colin Plumb's MD5 implementation.
+ */
+#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
+#define G(x, y, z) (((x) & ((y) | (z))) | ((y) & (z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+
+/*
+ * The MD4 transformation for all three rounds.
+ */
+#define STEP(f, a, b, c, d, x, s) \
+ (a) += f((b), (c), (d)) + (x); \
+ (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s))));
+
+/*
+ * SET reads 4 input bytes in little-endian byte order and stores them
+ * in a properly aligned word in host byte order.
+ *
+ * The check for little-endian architectures that tolerate unaligned
+ * memory accesses is just an optimization. Nothing will break if it
+ * doesn't work.
+ */
+#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
+#define SET(n) \
+ (*(MD4_u32plus *)&ptr[(n) * 4])
+#define GET(n) \
+ SET(n)
+#else
+#define SET(n) \
+ (ctx->block[(n)] = \
+ (MD4_u32plus)ptr[(n) * 4] | \
+ ((MD4_u32plus)ptr[(n) * 4 + 1] << 8) | \
+ ((MD4_u32plus)ptr[(n) * 4 + 2] << 16) | \
+ ((MD4_u32plus)ptr[(n) * 4 + 3] << 24))
+#define GET(n) \
+ (ctx->block[(n)])
+#endif
+
+/*
+ * This processes one or more 64-byte data blocks, but does NOT update
+ * the bit counters. There are no alignment requirements.
+ */
+static const void *body(MD4_CTX *ctx, const void *data, unsigned long size)
+{
+ const unsigned char *ptr;
+ MD4_u32plus a, b, c, d;
+ MD4_u32plus saved_a, saved_b, saved_c, saved_d;
+
+ ptr = (const unsigned char *)data;
+
+ a = ctx->a;
+ b = ctx->b;
+ c = ctx->c;
+ d = ctx->d;
+
+ do {
+ saved_a = a;
+ saved_b = b;
+ saved_c = c;
+ saved_d = d;
+
+/* Round 1 */
+ STEP(F, a, b, c, d, SET(0), 3)
+ STEP(F, d, a, b, c, SET(1), 7)
+ STEP(F, c, d, a, b, SET(2), 11)
+ STEP(F, b, c, d, a, SET(3), 19)
+ STEP(F, a, b, c, d, SET(4), 3)
+ STEP(F, d, a, b, c, SET(5), 7)
+ STEP(F, c, d, a, b, SET(6), 11)
+ STEP(F, b, c, d, a, SET(7), 19)
+ STEP(F, a, b, c, d, SET(8), 3)
+ STEP(F, d, a, b, c, SET(9), 7)
+ STEP(F, c, d, a, b, SET(10), 11)
+ STEP(F, b, c, d, a, SET(11), 19)
+ STEP(F, a, b, c, d, SET(12), 3)
+ STEP(F, d, a, b, c, SET(13), 7)
+ STEP(F, c, d, a, b, SET(14), 11)
+ STEP(F, b, c, d, a, SET(15), 19)
+
+/* Round 2 */
+ STEP(G, a, b, c, d, GET(0) + 0x5a827999, 3)
+ STEP(G, d, a, b, c, GET(4) + 0x5a827999, 5)
+ STEP(G, c, d, a, b, GET(8) + 0x5a827999, 9)
+ STEP(G, b, c, d, a, GET(12) + 0x5a827999, 13)
+ STEP(G, a, b, c, d, GET(1) + 0x5a827999, 3)
+ STEP(G, d, a, b, c, GET(5) + 0x5a827999, 5)
+ STEP(G, c, d, a, b, GET(9) + 0x5a827999, 9)
+ STEP(G, b, c, d, a, GET(13) + 0x5a827999, 13)
+ STEP(G, a, b, c, d, GET(2) + 0x5a827999, 3)
+ STEP(G, d, a, b, c, GET(6) + 0x5a827999, 5)
+ STEP(G, c, d, a, b, GET(10) + 0x5a827999, 9)
+ STEP(G, b, c, d, a, GET(14) + 0x5a827999, 13)
+ STEP(G, a, b, c, d, GET(3) + 0x5a827999, 3)
+ STEP(G, d, a, b, c, GET(7) + 0x5a827999, 5)
+ STEP(G, c, d, a, b, GET(11) + 0x5a827999, 9)
+ STEP(G, b, c, d, a, GET(15) + 0x5a827999, 13)
+
+/* Round 3 */
+ STEP(H, a, b, c, d, GET(0) + 0x6ed9eba1, 3)
+ STEP(H, d, a, b, c, GET(8) + 0x6ed9eba1, 9)
+ STEP(H, c, d, a, b, GET(4) + 0x6ed9eba1, 11)
+ STEP(H, b, c, d, a, GET(12) + 0x6ed9eba1, 15)
+ STEP(H, a, b, c, d, GET(2) + 0x6ed9eba1, 3)
+ STEP(H, d, a, b, c, GET(10) + 0x6ed9eba1, 9)
+ STEP(H, c, d, a, b, GET(6) + 0x6ed9eba1, 11)
+ STEP(H, b, c, d, a, GET(14) + 0x6ed9eba1, 15)
+ STEP(H, a, b, c, d, GET(1) + 0x6ed9eba1, 3)
+ STEP(H, d, a, b, c, GET(9) + 0x6ed9eba1, 9)
+ STEP(H, c, d, a, b, GET(5) + 0x6ed9eba1, 11)
+ STEP(H, b, c, d, a, GET(13) + 0x6ed9eba1, 15)
+ STEP(H, a, b, c, d, GET(3) + 0x6ed9eba1, 3)
+ STEP(H, d, a, b, c, GET(11) + 0x6ed9eba1, 9)
+ STEP(H, c, d, a, b, GET(7) + 0x6ed9eba1, 11)
+ STEP(H, b, c, d, a, GET(15) + 0x6ed9eba1, 15)
+
+ a += saved_a;
+ b += saved_b;
+ c += saved_c;
+ d += saved_d;
+
+ ptr += 64;
+ } while(size -= 64);
+
+ ctx->a = a;
+ ctx->b = b;
+ ctx->c = c;
+ ctx->d = d;
+
+ return ptr;
+}
+
+static void MD4_Init(MD4_CTX *ctx)
+{
+ ctx->a = 0x67452301;
+ ctx->b = 0xefcdab89;
+ ctx->c = 0x98badcfe;
+ ctx->d = 0x10325476;
+
+ ctx->lo = 0;
+ ctx->hi = 0;
+}
+
+static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
+{
+ MD4_u32plus saved_lo;
+ unsigned long used, available;
+
+ saved_lo = ctx->lo;
+ if((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
+ ctx->hi++;
+ ctx->hi += (MD4_u32plus)size >> 29;
+
+ used = saved_lo & 0x3f;
+
+ if(used) {
+ available = 64 - used;
+
+ if(size < available) {
+ memcpy(&ctx->buffer[used], data, size);
+ return;
+ }
+
+ memcpy(&ctx->buffer[used], data, available);
+ data = (const unsigned char *)data + available;
+ size -= available;
+ body(ctx, ctx->buffer, 64);
+ }
+
+ if(size >= 64) {
+ data = body(ctx, data, size & ~(unsigned long)0x3f);
+ size &= 0x3f;
+ }
+
+ memcpy(ctx->buffer, data, size);
+}
+
+static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
+{
+ unsigned long used, available;
+
+ used = ctx->lo & 0x3f;
+
+ ctx->buffer[used++] = 0x80;
+
+ available = 64 - used;
+
+ if(available < 8) {
+ memset(&ctx->buffer[used], 0, available);
+ body(ctx, ctx->buffer, 64);
+ used = 0;
+ available = 64;
+ }
+
+ memset(&ctx->buffer[used], 0, available - 8);
+
+ ctx->lo <<= 3;
+ ctx->buffer[56] = curlx_ultouc((ctx->lo)&0xff);
+ ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8)&0xff);
+ ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16)&0xff);
+ ctx->buffer[59] = curlx_ultouc((ctx->lo >> 24)&0xff);
+ ctx->buffer[60] = curlx_ultouc((ctx->hi)&0xff);
+ ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8)&0xff);
+ ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16)&0xff);
+ ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24);
+
+ body(ctx, ctx->buffer, 64);
+
+ result[0] = curlx_ultouc((ctx->a)&0xff);
+ result[1] = curlx_ultouc((ctx->a >> 8)&0xff);
+ result[2] = curlx_ultouc((ctx->a >> 16)&0xff);
+ result[3] = curlx_ultouc(ctx->a >> 24);
+ result[4] = curlx_ultouc((ctx->b)&0xff);
+ result[5] = curlx_ultouc((ctx->b >> 8)&0xff);
+ result[6] = curlx_ultouc((ctx->b >> 16)&0xff);
+ result[7] = curlx_ultouc(ctx->b >> 24);
+ result[8] = curlx_ultouc((ctx->c)&0xff);
+ result[9] = curlx_ultouc((ctx->c >> 8)&0xff);
+ result[10] = curlx_ultouc((ctx->c >> 16)&0xff);
+ result[11] = curlx_ultouc(ctx->c >> 24);
+ result[12] = curlx_ultouc((ctx->d)&0xff);
+ result[13] = curlx_ultouc((ctx->d >> 8)&0xff);
+ result[14] = curlx_ultouc((ctx->d >> 16)&0xff);
+ result[15] = curlx_ultouc(ctx->d >> 24);
+
+ memset(ctx, 0, sizeof(*ctx));
+}
+
+#endif
+
+void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len)
+{
+ MD4_CTX ctx;
+ MD4_Init(&ctx);
+ MD4_Update(&ctx, input, curlx_uztoui(len));
+ MD4_Final(output, &ctx);
+}
+#endif /* defined(USE_NSS) || defined(USE_OS400CRYPTO) */
diff --git a/Utilities/cmcurl/lib/md5.c b/Utilities/cmcurl/lib/md5.c
new file mode 100644
index 000000000..b604c109f
--- /dev/null
+++ b/Utilities/cmcurl/lib/md5.c
@@ -0,0 +1,560 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+
+#include "curl_md5.h"
+#include "curl_hmac.h"
+#include "warnless.h"
+
+#if defined(USE_GNUTLS_NETTLE)
+
+#include <nettle/md5.h>
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef struct md5_ctx MD5_CTX;
+
+static void MD5_Init(MD5_CTX * ctx)
+{
+ md5_init(ctx);
+}
+
+static void MD5_Update(MD5_CTX * ctx,
+ const unsigned char * input,
+ unsigned int inputLen)
+{
+ md5_update(ctx, inputLen, input);
+}
+
+static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
+{
+ md5_digest(ctx, 16, digest);
+}
+
+#elif defined(USE_GNUTLS)
+
+#include <gcrypt.h>
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef gcry_md_hd_t MD5_CTX;
+
+static void MD5_Init(MD5_CTX * ctx)
+{
+ gcry_md_open(ctx, GCRY_MD_MD5, 0);
+}
+
+static void MD5_Update(MD5_CTX * ctx,
+ const unsigned char * input,
+ unsigned int inputLen)
+{
+ gcry_md_write(*ctx, input, inputLen);
+}
+
+static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
+{
+ memcpy(digest, gcry_md_read(*ctx, 0), 16);
+ gcry_md_close(*ctx);
+}
+
+#elif defined(USE_OPENSSL)
+/* When OpenSSL is available we use the MD5-function from OpenSSL */
+#include <openssl/md5.h>
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
+ (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \
+ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
+ (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000))
+
+/* For Apple operating systems: CommonCrypto has the functions we need.
+ These functions are available on Tiger and later, as well as iOS 2.0
+ and later. If you're building for an older cat, well, sorry.
+
+ Declaring the functions as static like this seems to be a bit more
+ reliable than defining COMMON_DIGEST_FOR_OPENSSL on older cats. */
+# include <CommonCrypto/CommonDigest.h>
+# define MD5_CTX CC_MD5_CTX
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+static void MD5_Init(MD5_CTX *ctx)
+{
+ CC_MD5_Init(ctx);
+}
+
+static void MD5_Update(MD5_CTX *ctx,
+ const unsigned char *input,
+ unsigned int inputLen)
+{
+ CC_MD5_Update(ctx, input, inputLen);
+}
+
+static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
+{
+ CC_MD5_Final(digest, ctx);
+}
+
+#elif defined(_WIN32)
+
+#include <wincrypt.h>
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef struct {
+ HCRYPTPROV hCryptProv;
+ HCRYPTHASH hHash;
+} MD5_CTX;
+
+static void MD5_Init(MD5_CTX *ctx)
+{
+ if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL,
+ PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
+ CryptCreateHash(ctx->hCryptProv, CALG_MD5, 0, 0, &ctx->hHash);
+ }
+}
+
+static void MD5_Update(MD5_CTX *ctx,
+ const unsigned char *input,
+ unsigned int inputLen)
+{
+ CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0);
+}
+
+static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
+{
+ unsigned long length = 0;
+ CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
+ if(length == 16)
+ CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0);
+ if(ctx->hHash)
+ CryptDestroyHash(ctx->hHash);
+ if(ctx->hCryptProv)
+ CryptReleaseContext(ctx->hCryptProv, 0);
+}
+
+#elif defined(USE_AXTLS)
+#include <axTLS/config.h>
+#include <axTLS/os_int.h>
+#include <axTLS/crypto.h>
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+#else
+/* When no other crypto library is available we use this code segment */
+/*
+ * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
+ * MD5 Message-Digest Algorithm (RFC 1321).
+ *
+ * Homepage:
+ http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
+ *
+ * Author:
+ * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
+ *
+ * This software was written by Alexander Peslyak in 2001. No copyright is
+ * claimed, and the software is hereby placed in the public domain.
+ * In case this attempt to disclaim copyright and place the software in the
+ * public domain is deemed null and void, then the software is
+ * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
+ * general public under the following terms:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted.
+ *
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
+ *
+ * (This is a heavily cut-down "BSD license".)
+ *
+ * This differs from Colin Plumb's older public domain implementation in that
+ * no exactly 32-bit integer data type is required (any 32-bit or wider
+ * unsigned integer data type will do), there's no compile-time endianness
+ * configuration, and the function prototypes match OpenSSL's. No code from
+ * Colin Plumb's implementation has been reused; this comment merely compares
+ * the properties of the two independent implementations.
+ *
+ * The primary goals of this implementation are portability and ease of use.
+ * It is meant to be fast, but not as fast as possible. Some known
+ * optimizations are not included to reduce source code size and avoid
+ * compile-time configuration.
+ */
+
+#include <string.h>
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* Any 32-bit or wider unsigned integer data type will do */
+typedef unsigned int MD5_u32plus;
+
+typedef struct {
+ MD5_u32plus lo, hi;
+ MD5_u32plus a, b, c, d;
+ unsigned char buffer[64];
+ MD5_u32plus block[16];
+} MD5_CTX;
+
+static void MD5_Init(MD5_CTX *ctx);
+static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size);
+static void MD5_Final(unsigned char *result, MD5_CTX *ctx);
+
+/*
+ * The basic MD5 functions.
+ *
+ * F and G are optimized compared to their RFC 1321 definitions for
+ * architectures that lack an AND-NOT instruction, just like in Colin Plumb's
+ * implementation.
+ */
+#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
+#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
+#define H(x, y, z) (((x) ^ (y)) ^ (z))
+#define H2(x, y, z) ((x) ^ ((y) ^ (z)))
+#define I(x, y, z) ((y) ^ ((x) | ~(z)))
+
+/*
+ * The MD5 transformation for all four rounds.
+ */
+#define STEP(f, a, b, c, d, x, t, s) \
+ (a) += f((b), (c), (d)) + (x) + (t); \
+ (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
+ (a) += (b);
+
+/*
+ * SET reads 4 input bytes in little-endian byte order and stores them
+ * in a properly aligned word in host byte order.
+ *
+ * The check for little-endian architectures that tolerate unaligned
+ * memory accesses is just an optimization. Nothing will break if it
+ * doesn't work.
+ */
+#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
+#define SET(n) \
+ (*(MD5_u32plus *)&ptr[(n) * 4])
+#define GET(n) \
+ SET(n)
+#else
+#define SET(n) \
+ (ctx->block[(n)] = \
+ (MD5_u32plus)ptr[(n) * 4] | \
+ ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
+ ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
+ ((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
+#define GET(n) \
+ (ctx->block[(n)])
+#endif
+
+/*
+ * This processes one or more 64-byte data blocks, but does NOT update
+ * the bit counters. There are no alignment requirements.
+ */
+static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
+{
+ const unsigned char *ptr;
+ MD5_u32plus a, b, c, d;
+ MD5_u32plus saved_a, saved_b, saved_c, saved_d;
+
+ ptr = (const unsigned char *)data;
+
+ a = ctx->a;
+ b = ctx->b;
+ c = ctx->c;
+ d = ctx->d;
+
+ do {
+ saved_a = a;
+ saved_b = b;
+ saved_c = c;
+ saved_d = d;
+
+/* Round 1 */
+ STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
+ STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
+ STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
+ STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
+ STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
+ STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
+ STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
+ STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
+ STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
+ STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
+ STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
+ STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
+ STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
+ STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
+ STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
+ STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
+
+/* Round 2 */
+ STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
+ STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
+ STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
+ STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
+ STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
+ STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
+ STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
+ STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
+ STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
+ STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
+ STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
+ STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
+ STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
+ STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
+ STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
+ STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
+
+/* Round 3 */
+ STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
+ STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11)
+ STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
+ STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23)
+ STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
+ STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11)
+ STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
+ STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23)
+ STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
+ STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11)
+ STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
+ STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23)
+ STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
+ STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11)
+ STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
+ STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23)
+
+/* Round 4 */
+ STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
+ STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
+ STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
+ STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
+ STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
+ STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
+ STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
+ STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
+ STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
+ STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
+ STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
+ STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
+ STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
+ STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
+ STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
+ STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
+
+ a += saved_a;
+ b += saved_b;
+ c += saved_c;
+ d += saved_d;
+
+ ptr += 64;
+ } while(size -= 64);
+
+ ctx->a = a;
+ ctx->b = b;
+ ctx->c = c;
+ ctx->d = d;
+
+ return ptr;
+}
+
+static void MD5_Init(MD5_CTX *ctx)
+{
+ ctx->a = 0x67452301;
+ ctx->b = 0xefcdab89;
+ ctx->c = 0x98badcfe;
+ ctx->d = 0x10325476;
+
+ ctx->lo = 0;
+ ctx->hi = 0;
+}
+
+static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
+{
+ MD5_u32plus saved_lo;
+ unsigned long used, available;
+
+ saved_lo = ctx->lo;
+ if((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
+ ctx->hi++;
+ ctx->hi += (MD5_u32plus)size >> 29;
+
+ used = saved_lo & 0x3f;
+
+ if(used) {
+ available = 64 - used;
+
+ if(size < available) {
+ memcpy(&ctx->buffer[used], data, size);
+ return;
+ }
+
+ memcpy(&ctx->buffer[used], data, available);
+ data = (const unsigned char *)data + available;
+ size -= available;
+ body(ctx, ctx->buffer, 64);
+ }
+
+ if(size >= 64) {
+ data = body(ctx, data, size & ~(unsigned long)0x3f);
+ size &= 0x3f;
+ }
+
+ memcpy(ctx->buffer, data, size);
+}
+
+static void MD5_Final(unsigned char *result, MD5_CTX *ctx)
+{
+ unsigned long used, available;
+
+ used = ctx->lo & 0x3f;
+
+ ctx->buffer[used++] = 0x80;
+
+ available = 64 - used;
+
+ if(available < 8) {
+ memset(&ctx->buffer[used], 0, available);
+ body(ctx, ctx->buffer, 64);
+ used = 0;
+ available = 64;
+ }
+
+ memset(&ctx->buffer[used], 0, available - 8);
+
+ ctx->lo <<= 3;
+ ctx->buffer[56] = curlx_ultouc((ctx->lo)&0xff);
+ ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8)&0xff);
+ ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16)&0xff);
+ ctx->buffer[59] = curlx_ultouc(ctx->lo >> 24);
+ ctx->buffer[60] = curlx_ultouc((ctx->hi)&0xff);
+ ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8)&0xff);
+ ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16)&0xff);
+ ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24);
+
+ body(ctx, ctx->buffer, 64);
+
+ result[0] = curlx_ultouc((ctx->a)&0xff);
+ result[1] = curlx_ultouc((ctx->a >> 8)&0xff);
+ result[2] = curlx_ultouc((ctx->a >> 16)&0xff);
+ result[3] = curlx_ultouc(ctx->a >> 24);
+ result[4] = curlx_ultouc((ctx->b)&0xff);
+ result[5] = curlx_ultouc((ctx->b >> 8)&0xff);
+ result[6] = curlx_ultouc((ctx->b >> 16)&0xff);
+ result[7] = curlx_ultouc(ctx->b >> 24);
+ result[8] = curlx_ultouc((ctx->c)&0xff);
+ result[9] = curlx_ultouc((ctx->c >> 8)&0xff);
+ result[10] = curlx_ultouc((ctx->c >> 16)&0xff);
+ result[11] = curlx_ultouc(ctx->c >> 24);
+ result[12] = curlx_ultouc((ctx->d)&0xff);
+ result[13] = curlx_ultouc((ctx->d >> 8)&0xff);
+ result[14] = curlx_ultouc((ctx->d >> 16)&0xff);
+ result[15] = curlx_ultouc(ctx->d >> 24);
+
+ memset(ctx, 0, sizeof(*ctx));
+}
+
+#endif /* CRYPTO LIBS */
+
+const HMAC_params Curl_HMAC_MD5[] = {
+ {
+ (HMAC_hinit_func) MD5_Init, /* Hash initialization function. */
+ (HMAC_hupdate_func) MD5_Update, /* Hash update function. */
+ (HMAC_hfinal_func) MD5_Final, /* Hash computation end function. */
+ sizeof(MD5_CTX), /* Size of hash context structure. */
+ 64, /* Maximum key length. */
+ 16 /* Result size. */
+ }
+};
+
+const MD5_params Curl_DIGEST_MD5[] = {
+ {
+ (Curl_MD5_init_func) MD5_Init, /* Digest initialization function */
+ (Curl_MD5_update_func) MD5_Update, /* Digest update function */
+ (Curl_MD5_final_func) MD5_Final, /* Digest computation end function */
+ sizeof(MD5_CTX), /* Size of digest context struct */
+ 16 /* Result size */
+ }
+};
+
+/*
+ * @unittest: 1601
+ */
+void Curl_md5it(unsigned char *outbuffer, /* 16 bytes */
+ const unsigned char *input)
+{
+ MD5_CTX ctx;
+ MD5_Init(&ctx);
+ MD5_Update(&ctx, input, curlx_uztoui(strlen((char *)input)));
+ MD5_Final(outbuffer, &ctx);
+}
+
+MD5_context *Curl_MD5_init(const MD5_params *md5params)
+{
+ MD5_context *ctxt;
+
+ /* Create MD5 context */
+ ctxt = malloc(sizeof *ctxt);
+
+ if(!ctxt)
+ return ctxt;
+
+ ctxt->md5_hashctx = malloc(md5params->md5_ctxtsize);
+
+ if(!ctxt->md5_hashctx) {
+ free(ctxt);
+ return NULL;
+ }
+
+ ctxt->md5_hash = md5params;
+
+ (*md5params->md5_init_func)(ctxt->md5_hashctx);
+
+ return ctxt;
+}
+
+int Curl_MD5_update(MD5_context *context,
+ const unsigned char *data,
+ unsigned int len)
+{
+ (*context->md5_hash->md5_update_func)(context->md5_hashctx, data, len);
+
+ return 0;
+}
+
+int Curl_MD5_final(MD5_context *context, unsigned char *result)
+{
+ (*context->md5_hash->md5_final_func)(result, context->md5_hashctx);
+
+ free(context->md5_hashctx);
+ free(context);
+
+ return 0;
+}
+
+#endif /* CURL_DISABLE_CRYPTO_AUTH */
diff --git a/Utilities/cmcurl/lib/memdebug.c b/Utilities/cmcurl/lib/memdebug.c
new file mode 100644
index 000000000..dd8889b2d
--- /dev/null
+++ b/Utilities/cmcurl/lib/memdebug.c
@@ -0,0 +1,489 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef CURLDEBUG
+
+#include <curl/curl.h>
+
+#include "curl_printf.h"
+#include "urldata.h"
+
+#define MEMDEBUG_NODEFINES /* don't redefine the standard functions */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#ifndef HAVE_ASSERT_H
+# define assert(x) Curl_nop_stmt
+#endif
+
+/*
+ * Until 2011-08-17 libcurl's Memory Tracking feature also performed
+ * automatic malloc and free filling operations using 0xA5 and 0x13
+ * values. Our own preinitialization of dynamically allocated memory
+ * might be useful when not using third party memory debuggers, but
+ * on the other hand this would fool memory debuggers into thinking
+ * that all dynamically allocated memory is properly initialized.
+ *
+ * As a default setting, libcurl's Memory Tracking feature no longer
+ * performs preinitialization of dynamically allocated memory on its
+ * own. If you know what you are doing, and really want to retain old
+ * behavior, you can achieve this compiling with preprocessor symbols
+ * CURL_MT_MALLOC_FILL and CURL_MT_FREE_FILL defined with appropriate
+ * values.
+ */
+
+#ifdef CURL_MT_MALLOC_FILL
+# if (CURL_MT_MALLOC_FILL < 0) || (CURL_MT_MALLOC_FILL > 0xff)
+# error "invalid CURL_MT_MALLOC_FILL or out of range"
+# endif
+#endif
+
+#ifdef CURL_MT_FREE_FILL
+# if (CURL_MT_FREE_FILL < 0) || (CURL_MT_FREE_FILL > 0xff)
+# error "invalid CURL_MT_FREE_FILL or out of range"
+# endif
+#endif
+
+#if defined(CURL_MT_MALLOC_FILL) && defined(CURL_MT_FREE_FILL)
+# if (CURL_MT_MALLOC_FILL == CURL_MT_FREE_FILL)
+# error "CURL_MT_MALLOC_FILL same as CURL_MT_FREE_FILL"
+# endif
+#endif
+
+#ifdef CURL_MT_MALLOC_FILL
+# define mt_malloc_fill(buf,len) memset((buf), CURL_MT_MALLOC_FILL, (len))
+#else
+# define mt_malloc_fill(buf,len) Curl_nop_stmt
+#endif
+
+#ifdef CURL_MT_FREE_FILL
+# define mt_free_fill(buf,len) memset((buf), CURL_MT_FREE_FILL, (len))
+#else
+# define mt_free_fill(buf,len) Curl_nop_stmt
+#endif
+
+struct memdebug {
+ size_t size;
+ union {
+ curl_off_t o;
+ double d;
+ void * p;
+ } mem[1];
+ /* I'm hoping this is the thing with the strictest alignment
+ * requirements. That also means we waste some space :-( */
+};
+
+/*
+ * Note that these debug functions are very simple and they are meant to
+ * remain so. For advanced analysis, record a log file and write perl scripts
+ * to analyze them!
+ *
+ * Don't use these with multithreaded test programs!
+ */
+
+#define logfile curl_debuglogfile
+FILE *curl_debuglogfile = NULL;
+static bool memlimit = FALSE; /* enable memory limit */
+static long memsize = 0; /* set number of mallocs allowed */
+
+/* this sets the log file name */
+void curl_memdebug(const char *logname)
+{
+ if(!logfile) {
+ if(logname && *logname)
+ logfile = fopen(logname, FOPEN_WRITETEXT);
+ else
+ logfile = stderr;
+#ifdef MEMDEBUG_LOG_SYNC
+ /* Flush the log file after every line so the log isn't lost in a crash */
+ setvbuf(logfile, (char *)NULL, _IOLBF, 0);
+#endif
+ }
+}
+
+/* This function sets the number of malloc() calls that should return
+ successfully! */
+void curl_memlimit(long limit)
+{
+ if(!memlimit) {
+ memlimit = TRUE;
+ memsize = limit;
+ }
+}
+
+/* returns TRUE if this isn't allowed! */
+static bool countcheck(const char *func, int line, const char *source)
+{
+ /* if source is NULL, then the call is made internally and this check
+ should not be made */
+ if(memlimit && source) {
+ if(!memsize) {
+ if(source) {
+ /* log to file */
+ curl_memlog("LIMIT %s:%d %s reached memlimit\n",
+ source, line, func);
+ /* log to stderr also */
+ fprintf(stderr, "LIMIT %s:%d %s reached memlimit\n",
+ source, line, func);
+ }
+ SET_ERRNO(ENOMEM);
+ return TRUE; /* RETURN ERROR! */
+ }
+ else
+ memsize--; /* countdown */
+
+ /* log the countdown */
+ if(source)
+ curl_memlog("LIMIT %s:%d %ld ALLOCS left\n",
+ source, line, memsize);
+
+ }
+
+ return FALSE; /* allow this */
+}
+
+void *curl_domalloc(size_t wantedsize, int line, const char *source)
+{
+ struct memdebug *mem;
+ size_t size;
+
+ assert(wantedsize != 0);
+
+ if(countcheck("malloc", line, source))
+ return NULL;
+
+ /* alloc at least 64 bytes */
+ size = sizeof(struct memdebug)+wantedsize;
+
+ mem = (Curl_cmalloc)(size);
+ if(mem) {
+ /* fill memory with junk */
+ mt_malloc_fill(mem->mem, wantedsize);
+ mem->size = wantedsize;
+ }
+
+ if(source)
+ curl_memlog("MEM %s:%d malloc(%zu) = %p\n",
+ source, line, wantedsize,
+ mem ? (void *)mem->mem : (void *)0);
+
+ return (mem ? mem->mem : NULL);
+}
+
+void *curl_docalloc(size_t wanted_elements, size_t wanted_size,
+ int line, const char *source)
+{
+ struct memdebug *mem;
+ size_t size, user_size;
+
+ assert(wanted_elements != 0);
+ assert(wanted_size != 0);
+
+ if(countcheck("calloc", line, source))
+ return NULL;
+
+ /* alloc at least 64 bytes */
+ user_size = wanted_size * wanted_elements;
+ size = sizeof(struct memdebug) + user_size;
+
+ mem = (Curl_ccalloc)(1, size);
+ if(mem)
+ mem->size = user_size;
+
+ if(source)
+ curl_memlog("MEM %s:%d calloc(%zu,%zu) = %p\n",
+ source, line, wanted_elements, wanted_size,
+ mem ? (void *)mem->mem : (void *)0);
+
+ return (mem ? mem->mem : NULL);
+}
+
+char *curl_dostrdup(const char *str, int line, const char *source)
+{
+ char *mem;
+ size_t len;
+
+ assert(str != NULL);
+
+ if(countcheck("strdup", line, source))
+ return NULL;
+
+ len=strlen(str)+1;
+
+ mem=curl_domalloc(len, 0, NULL); /* NULL prevents logging */
+ if(mem)
+ memcpy(mem, str, len);
+
+ if(source)
+ curl_memlog("MEM %s:%d strdup(%p) (%zu) = %p\n",
+ source, line, (void *)str, len, (void *)mem);
+
+ return mem;
+}
+
+#if defined(WIN32) && defined(UNICODE)
+wchar_t *curl_dowcsdup(const wchar_t *str, int line, const char *source)
+{
+ wchar_t *mem;
+ size_t wsiz, bsiz;
+
+ assert(str != NULL);
+
+ if(countcheck("wcsdup", line, source))
+ return NULL;
+
+ wsiz = wcslen(str) + 1;
+ bsiz = wsiz * sizeof(wchar_t);
+
+ mem = curl_domalloc(bsiz, 0, NULL); /* NULL prevents logging */
+ if(mem)
+ memcpy(mem, str, bsiz);
+
+ if(source)
+ curl_memlog("MEM %s:%d wcsdup(%p) (%zu) = %p\n",
+ source, line, (void *)str, bsiz, (void *)mem);
+
+ return mem;
+}
+#endif
+
+/* We provide a realloc() that accepts a NULL as pointer, which then
+ performs a malloc(). In order to work with ares. */
+void *curl_dorealloc(void *ptr, size_t wantedsize,
+ int line, const char *source)
+{
+ struct memdebug *mem=NULL;
+
+ size_t size = sizeof(struct memdebug)+wantedsize;
+
+ assert(wantedsize != 0);
+
+ if(countcheck("realloc", line, source))
+ return NULL;
+
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:1684)
+ /* 1684: conversion from pointer to same-sized integral type */
+#endif
+
+ if(ptr)
+ mem = (void *)((char *)ptr - offsetof(struct memdebug, mem));
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+
+ mem = (Curl_crealloc)(mem, size);
+ if(source)
+ curl_memlog("MEM %s:%d realloc(%p, %zu) = %p\n",
+ source, line, (void *)ptr, wantedsize,
+ mem ? (void *)mem->mem : (void *)0);
+
+ if(mem) {
+ mem->size = wantedsize;
+ return mem->mem;
+ }
+
+ return NULL;
+}
+
+void curl_dofree(void *ptr, int line, const char *source)
+{
+ struct memdebug *mem;
+
+ if(ptr) {
+
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:1684)
+ /* 1684: conversion from pointer to same-sized integral type */
+#endif
+
+ mem = (void *)((char *)ptr - offsetof(struct memdebug, mem));
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+
+ /* destroy */
+ mt_free_fill(mem->mem, mem->size);
+
+ /* free for real */
+ (Curl_cfree)(mem);
+ }
+
+ if(source)
+ curl_memlog("MEM %s:%d free(%p)\n", source, line, (void *)ptr);
+}
+
+curl_socket_t curl_socket(int domain, int type, int protocol,
+ int line, const char *source)
+{
+ const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
+ "FD %s:%d socket() = %d\n" :
+ (sizeof(curl_socket_t) == sizeof(long)) ?
+ "FD %s:%d socket() = %ld\n" :
+ "FD %s:%d socket() = %zd\n";
+
+ curl_socket_t sockfd = socket(domain, type, protocol);
+
+ if(source && (sockfd != CURL_SOCKET_BAD))
+ curl_memlog(fmt, source, line, sockfd);
+
+ return sockfd;
+}
+
+#ifdef HAVE_SOCKETPAIR
+int curl_socketpair(int domain, int type, int protocol,
+ curl_socket_t socket_vector[2],
+ int line, const char *source)
+{
+ const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
+ "FD %s:%d socketpair() = %d %d\n" :
+ (sizeof(curl_socket_t) == sizeof(long)) ?
+ "FD %s:%d socketpair() = %ld %ld\n" :
+ "FD %s:%d socketpair() = %zd %zd\n";
+
+ int res = socketpair(domain, type, protocol, socket_vector);
+
+ if(source && (0 == res))
+ curl_memlog(fmt, source, line, socket_vector[0], socket_vector[1]);
+
+ return res;
+}
+#endif
+
+curl_socket_t curl_accept(curl_socket_t s, void *saddr, void *saddrlen,
+ int line, const char *source)
+{
+ const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
+ "FD %s:%d accept() = %d\n" :
+ (sizeof(curl_socket_t) == sizeof(long)) ?
+ "FD %s:%d accept() = %ld\n" :
+ "FD %s:%d accept() = %zd\n";
+
+ struct sockaddr *addr = (struct sockaddr *)saddr;
+ curl_socklen_t *addrlen = (curl_socklen_t *)saddrlen;
+
+ curl_socket_t sockfd = accept(s, addr, addrlen);
+
+ if(source && (sockfd != CURL_SOCKET_BAD))
+ curl_memlog(fmt, source, line, sockfd);
+
+ return sockfd;
+}
+
+/* separate function to allow libcurl to mark a "faked" close */
+void curl_mark_sclose(curl_socket_t sockfd, int line, const char *source)
+{
+ const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
+ "FD %s:%d sclose(%d)\n":
+ (sizeof(curl_socket_t) == sizeof(long)) ?
+ "FD %s:%d sclose(%ld)\n":
+ "FD %s:%d sclose(%zd)\n";
+
+ if(source)
+ curl_memlog(fmt, source, line, sockfd);
+}
+
+/* this is our own defined way to close sockets on *ALL* platforms */
+int curl_sclose(curl_socket_t sockfd, int line, const char *source)
+{
+ int res=sclose(sockfd);
+ curl_mark_sclose(sockfd, line, source);
+ return res;
+}
+
+FILE *curl_fopen(const char *file, const char *mode,
+ int line, const char *source)
+{
+ FILE *res=fopen(file, mode);
+
+ if(source)
+ curl_memlog("FILE %s:%d fopen(\"%s\",\"%s\") = %p\n",
+ source, line, file, mode, (void *)res);
+
+ return res;
+}
+
+#ifdef HAVE_FDOPEN
+FILE *curl_fdopen(int filedes, const char *mode,
+ int line, const char *source)
+{
+ FILE *res=fdopen(filedes, mode);
+
+ if(source)
+ curl_memlog("FILE %s:%d fdopen(\"%d\",\"%s\") = %p\n",
+ source, line, filedes, mode, (void *)res);
+
+ return res;
+}
+#endif
+
+int curl_fclose(FILE *file, int line, const char *source)
+{
+ int res;
+
+ assert(file != NULL);
+
+ res=fclose(file);
+
+ if(source)
+ curl_memlog("FILE %s:%d fclose(%p)\n",
+ source, line, (void *)file);
+
+ return res;
+}
+
+#define LOGLINE_BUFSIZE 1024
+
+/* this does the writting to the memory tracking log file */
+void curl_memlog(const char *format, ...)
+{
+ char *buf;
+ int nchars;
+ va_list ap;
+
+ if(!logfile)
+ return;
+
+ buf = (Curl_cmalloc)(LOGLINE_BUFSIZE);
+ if(!buf)
+ return;
+
+ va_start(ap, format);
+ nchars = vsnprintf(buf, LOGLINE_BUFSIZE, format, ap);
+ va_end(ap);
+
+ if(nchars > LOGLINE_BUFSIZE - 1)
+ nchars = LOGLINE_BUFSIZE - 1;
+
+ if(nchars > 0)
+ fwrite(buf, 1, nchars, logfile);
+
+ (Curl_cfree)(buf);
+}
+
+#endif /* CURLDEBUG */
diff --git a/Utilities/cmcurl/lib/memdebug.h b/Utilities/cmcurl/lib/memdebug.h
new file mode 100644
index 000000000..cfac1e077
--- /dev/null
+++ b/Utilities/cmcurl/lib/memdebug.h
@@ -0,0 +1,176 @@
+#ifndef HEADER_CURL_MEMDEBUG_H
+#define HEADER_CURL_MEMDEBUG_H
+#ifdef CURLDEBUG
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * CAUTION: this header is designed to work when included by the app-side
+ * as well as the library. Do not mix with library internals!
+ */
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#define CURL_MT_LOGFNAME_BUFSIZE 512
+
+#define logfile curl_debuglogfile
+
+extern FILE *logfile;
+
+/* memory functions */
+CURL_EXTERN void *curl_domalloc(size_t size, int line, const char *source);
+CURL_EXTERN void *curl_docalloc(size_t elements, size_t size, int line,
+ const char *source);
+CURL_EXTERN void *curl_dorealloc(void *ptr, size_t size, int line,
+ const char *source);
+CURL_EXTERN void curl_dofree(void *ptr, int line, const char *source);
+CURL_EXTERN char *curl_dostrdup(const char *str, int line, const char *source);
+#if defined(WIN32) && defined(UNICODE)
+CURL_EXTERN wchar_t *curl_dowcsdup(const wchar_t *str, int line,
+ const char *source);
+#endif
+
+CURL_EXTERN void curl_memdebug(const char *logname);
+CURL_EXTERN void curl_memlimit(long limit);
+CURL_EXTERN void curl_memlog(const char *format, ...);
+
+/* file descriptor manipulators */
+CURL_EXTERN curl_socket_t curl_socket(int domain, int type, int protocol,
+ int line , const char *source);
+CURL_EXTERN void curl_mark_sclose(curl_socket_t sockfd,
+ int line , const char *source);
+CURL_EXTERN int curl_sclose(curl_socket_t sockfd,
+ int line , const char *source);
+CURL_EXTERN curl_socket_t curl_accept(curl_socket_t s, void *a, void *alen,
+ int line, const char *source);
+#ifdef HAVE_SOCKETPAIR
+CURL_EXTERN int curl_socketpair(int domain, int type, int protocol,
+ curl_socket_t socket_vector[2],
+ int line , const char *source);
+#endif
+
+/* FILE functions */
+CURL_EXTERN FILE *curl_fopen(const char *file, const char *mode, int line,
+ const char *source);
+#ifdef HAVE_FDOPEN
+CURL_EXTERN FILE *curl_fdopen(int filedes, const char *mode, int line,
+ const char *source);
+#endif
+CURL_EXTERN int curl_fclose(FILE *file, int line, const char *source);
+
+#ifndef MEMDEBUG_NODEFINES
+
+/* Set this symbol on the command-line, recompile all lib-sources */
+#undef strdup
+#define strdup(ptr) curl_dostrdup(ptr, __LINE__, __FILE__)
+#define malloc(size) curl_domalloc(size, __LINE__, __FILE__)
+#define calloc(nbelem,size) curl_docalloc(nbelem, size, __LINE__, __FILE__)
+#define realloc(ptr,size) curl_dorealloc(ptr, size, __LINE__, __FILE__)
+#define free(ptr) curl_dofree(ptr, __LINE__, __FILE__)
+
+#ifdef WIN32
+# ifdef UNICODE
+# undef wcsdup
+# define wcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__)
+# undef _wcsdup
+# define _wcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__)
+# undef _tcsdup
+# define _tcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__)
+# else
+# undef _tcsdup
+# define _tcsdup(ptr) curl_dostrdup(ptr, __LINE__, __FILE__)
+# endif
+#endif
+
+#define socket(domain,type,protocol)\
+ curl_socket(domain, type, protocol, __LINE__, __FILE__)
+#undef accept /* for those with accept as a macro */
+#define accept(sock,addr,len)\
+ curl_accept(sock, addr, len, __LINE__, __FILE__)
+#ifdef HAVE_SOCKETPAIR
+#define socketpair(domain,type,protocol,socket_vector)\
+ curl_socketpair(domain, type, protocol, socket_vector, __LINE__, __FILE__)
+#endif
+
+#ifdef HAVE_GETADDRINFO
+#if defined(getaddrinfo) && defined(__osf__)
+/* OSF/1 and Tru64 have getaddrinfo as a define already, so we cannot define
+ our macro as for other platforms. Instead, we redefine the new name they
+ define getaddrinfo to become! */
+#define ogetaddrinfo(host,serv,hint,res) \
+ curl_dogetaddrinfo(host, serv, hint, res, __LINE__, __FILE__)
+#else
+#undef getaddrinfo
+#define getaddrinfo(host,serv,hint,res) \
+ curl_dogetaddrinfo(host, serv, hint, res, __LINE__, __FILE__)
+#endif
+#endif /* HAVE_GETADDRINFO */
+
+#ifdef HAVE_GETNAMEINFO
+#undef getnameinfo
+#define getnameinfo(sa,salen,host,hostlen,serv,servlen,flags) \
+ curl_dogetnameinfo(sa, salen, host, hostlen, serv, servlen, flags, \
+ __LINE__, __FILE__)
+#endif /* HAVE_GETNAMEINFO */
+
+#ifdef HAVE_FREEADDRINFO
+#undef freeaddrinfo
+#define freeaddrinfo(data) \
+ curl_dofreeaddrinfo(data, __LINE__, __FILE__)
+#endif /* HAVE_FREEADDRINFO */
+
+/* sclose is probably already defined, redefine it! */
+#undef sclose
+#define sclose(sockfd) curl_sclose(sockfd,__LINE__,__FILE__)
+
+#define fake_sclose(sockfd) curl_mark_sclose(sockfd,__LINE__,__FILE__)
+
+#undef fopen
+#define fopen(file,mode) curl_fopen(file,mode,__LINE__,__FILE__)
+#undef fdopen
+#define fdopen(file,mode) curl_fdopen(file,mode,__LINE__,__FILE__)
+#define fclose(file) curl_fclose(file,__LINE__,__FILE__)
+
+#endif /* MEMDEBUG_NODEFINES */
+
+#endif /* CURLDEBUG */
+
+/*
+** Following section applies even when CURLDEBUG is not defined.
+*/
+
+#ifndef fake_sclose
+#define fake_sclose(x) Curl_nop_stmt
+#endif
+
+/*
+ * Curl_safefree defined as a macro to allow MemoryTracking feature
+ * to log free() calls at same location where Curl_safefree is used.
+ * This macro also assigns NULL to given pointer when free'd.
+ */
+
+#define Curl_safefree(ptr) \
+ do { free((ptr)); (ptr) = NULL;} WHILE_FALSE
+
+#endif /* HEADER_CURL_MEMDEBUG_H */
diff --git a/Utilities/cmcurl/lib/mprintf.c b/Utilities/cmcurl/lib/mprintf.c
new file mode 100644
index 000000000..7412dc38b
--- /dev/null
+++ b/Utilities/cmcurl/lib/mprintf.c
@@ -0,0 +1,1138 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1999 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ *
+ * Purpose:
+ * A merge of Bjorn Reese's format() function and Daniel's dsprintf()
+ * 1.0. A full blooded printf() clone with full support for <num>$
+ * everywhere (parameters, widths and precisions) including variabled
+ * sized parameters (like doubles, long longs, long doubles and even
+ * void * in 64-bit architectures).
+ *
+ * Current restrictions:
+ * - Max 128 parameters
+ * - No 'long double' support.
+ *
+ * If you ever want truly portable and good *printf() clones, the project that
+ * took on from here is named 'Trio' and you find more details on the trio web
+ * page at http://daniel.haxx.se/trio/
+ */
+
+#include "curl_setup.h"
+
+#if defined(DJGPP) && (DJGPP_MINOR < 4)
+#undef _MPRINTF_REPLACE /* don't use x_was_used() here */
+#endif
+
+#include <curl/mprintf.h>
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ * If SIZEOF_SIZE_T has not been defined, default to the size of long.
+ */
+
+#ifndef SIZEOF_SIZE_T
+# define SIZEOF_SIZE_T CURL_SIZEOF_LONG
+#endif
+
+#ifdef HAVE_LONGLONG
+# define LONG_LONG_TYPE long long
+# define HAVE_LONG_LONG_TYPE
+#else
+# if defined(_MSC_VER) && (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)
+# define LONG_LONG_TYPE __int64
+# define HAVE_LONG_LONG_TYPE
+# else
+# undef LONG_LONG_TYPE
+# undef HAVE_LONG_LONG_TYPE
+# endif
+#endif
+
+/*
+ * Non-ANSI integer extensions
+ */
+
+#if (defined(__BORLANDC__) && (__BORLANDC__ >= 0x520)) || \
+ (defined(__WATCOMC__) && defined(__386__)) || \
+ (defined(__POCC__) && defined(_MSC_VER)) || \
+ (defined(_WIN32_WCE)) || \
+ (defined(__MINGW32__)) || \
+ (defined(_MSC_VER) && (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64))
+# define MP_HAVE_INT_EXTENSIONS
+#endif
+
+/*
+ * Max integer data types that mprintf.c is capable
+ */
+
+#ifdef HAVE_LONG_LONG_TYPE
+# define mp_intmax_t LONG_LONG_TYPE
+# define mp_uintmax_t unsigned LONG_LONG_TYPE
+#else
+# define mp_intmax_t long
+# define mp_uintmax_t unsigned long
+#endif
+
+#define BUFFSIZE 256 /* buffer for long-to-str and float-to-str calcs */
+#define MAX_PARAMETERS 128 /* lame static limit */
+
+#ifdef __AMIGA__
+# undef FORMAT_INT
+#endif
+
+/* Lower-case digits. */
+static const char lower_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
+
+/* Upper-case digits. */
+static const char upper_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+#define OUTCHAR(x) \
+ do{ \
+ if(stream((unsigned char)(x), (FILE *)data) != -1) \
+ done++; \
+ else \
+ return done; /* return immediately on failure */ \
+ } WHILE_FALSE
+
+/* Data type to read from the arglist */
+typedef enum {
+ FORMAT_UNKNOWN = 0,
+ FORMAT_STRING,
+ FORMAT_PTR,
+ FORMAT_INT,
+ FORMAT_INTPTR,
+ FORMAT_LONG,
+ FORMAT_LONGLONG,
+ FORMAT_DOUBLE,
+ FORMAT_LONGDOUBLE,
+ FORMAT_WIDTH /* For internal use */
+} FormatType;
+
+/* conversion and display flags */
+enum {
+ FLAGS_NEW = 0,
+ FLAGS_SPACE = 1<<0,
+ FLAGS_SHOWSIGN = 1<<1,
+ FLAGS_LEFT = 1<<2,
+ FLAGS_ALT = 1<<3,
+ FLAGS_SHORT = 1<<4,
+ FLAGS_LONG = 1<<5,
+ FLAGS_LONGLONG = 1<<6,
+ FLAGS_LONGDOUBLE = 1<<7,
+ FLAGS_PAD_NIL = 1<<8,
+ FLAGS_UNSIGNED = 1<<9,
+ FLAGS_OCTAL = 1<<10,
+ FLAGS_HEX = 1<<11,
+ FLAGS_UPPER = 1<<12,
+ FLAGS_WIDTH = 1<<13, /* '*' or '*<num>$' used */
+ FLAGS_WIDTHPARAM = 1<<14, /* width PARAMETER was specified */
+ FLAGS_PREC = 1<<15, /* precision was specified */
+ FLAGS_PRECPARAM = 1<<16, /* precision PARAMETER was specified */
+ FLAGS_CHAR = 1<<17, /* %c story */
+ FLAGS_FLOATE = 1<<18, /* %e or %E */
+ FLAGS_FLOATG = 1<<19 /* %g or %G */
+};
+
+typedef struct {
+ FormatType type;
+ int flags;
+ long width; /* width OR width parameter number */
+ long precision; /* precision OR precision parameter number */
+ union {
+ char *str;
+ void *ptr;
+ union {
+ mp_intmax_t as_signed;
+ mp_uintmax_t as_unsigned;
+ } num;
+ double dnum;
+ } data;
+} va_stack_t;
+
+struct nsprintf {
+ char *buffer;
+ size_t length;
+ size_t max;
+};
+
+struct asprintf {
+ char *buffer; /* allocated buffer */
+ size_t len; /* length of string */
+ size_t alloc; /* length of alloc */
+ int fail; /* (!= 0) if an alloc has failed and thus
+ the output is not the complete data */
+};
+
+static long dprintf_DollarString(char *input, char **end)
+{
+ int number=0;
+ while(ISDIGIT(*input)) {
+ number *= 10;
+ number += *input-'0';
+ input++;
+ }
+ if(number && ('$'==*input++)) {
+ *end = input;
+ return number;
+ }
+ return 0;
+}
+
+static bool dprintf_IsQualifierNoDollar(const char *fmt)
+{
+#if defined(MP_HAVE_INT_EXTENSIONS)
+ if(!strncmp(fmt, "I32", 3) || !strncmp(fmt, "I64", 3)) {
+ return TRUE;
+ }
+#endif
+
+ switch(*fmt) {
+ case '-': case '+': case ' ': case '#': case '.':
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ case 'h': case 'l': case 'L': case 'z': case 'q':
+ case '*': case 'O':
+#if defined(MP_HAVE_INT_EXTENSIONS)
+ case 'I':
+#endif
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+}
+
+/******************************************************************
+ *
+ * Pass 1:
+ * Create an index with the type of each parameter entry and its
+ * value (may vary in size)
+ *
+ ******************************************************************/
+
+static long dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos,
+ va_list arglist)
+{
+ char *fmt = (char *)format;
+ int param_num = 0;
+ long this_param;
+ long width;
+ long precision;
+ int flags;
+ long max_param=0;
+ long i;
+
+ while(*fmt) {
+ if(*fmt++ == '%') {
+ if(*fmt == '%') {
+ fmt++;
+ continue; /* while */
+ }
+
+ flags = FLAGS_NEW;
+
+ /* Handle the positional case (N$) */
+
+ param_num++;
+
+ this_param = dprintf_DollarString(fmt, &fmt);
+ if(0 == this_param)
+ /* we got no positional, get the next counter */
+ this_param = param_num;
+
+ if(this_param > max_param)
+ max_param = this_param;
+
+ /*
+ * The parameter with number 'i' should be used. Next, we need
+ * to get SIZE and TYPE of the parameter. Add the information
+ * to our array.
+ */
+
+ width = 0;
+ precision = 0;
+
+ /* Handle the flags */
+
+ while(dprintf_IsQualifierNoDollar(fmt)) {
+#if defined(MP_HAVE_INT_EXTENSIONS)
+ if(!strncmp(fmt, "I32", 3)) {
+ flags |= FLAGS_LONG;
+ fmt += 3;
+ }
+ else if(!strncmp(fmt, "I64", 3)) {
+ flags |= FLAGS_LONGLONG;
+ fmt += 3;
+ }
+ else
+#endif
+
+ switch(*fmt++) {
+ case ' ':
+ flags |= FLAGS_SPACE;
+ break;
+ case '+':
+ flags |= FLAGS_SHOWSIGN;
+ break;
+ case '-':
+ flags |= FLAGS_LEFT;
+ flags &= ~FLAGS_PAD_NIL;
+ break;
+ case '#':
+ flags |= FLAGS_ALT;
+ break;
+ case '.':
+ flags |= FLAGS_PREC;
+ if('*' == *fmt) {
+ /* The precision is picked from a specified parameter */
+
+ flags |= FLAGS_PRECPARAM;
+ fmt++;
+ param_num++;
+
+ i = dprintf_DollarString(fmt, &fmt);
+ if(i)
+ precision = i;
+ else
+ precision = param_num;
+
+ if(precision > max_param)
+ max_param = precision;
+ }
+ else {
+ flags |= FLAGS_PREC;
+ precision = strtol(fmt, &fmt, 10);
+ }
+ break;
+ case 'h':
+ flags |= FLAGS_SHORT;
+ break;
+#if defined(MP_HAVE_INT_EXTENSIONS)
+ case 'I':
+#if (CURL_SIZEOF_CURL_OFF_T > CURL_SIZEOF_LONG)
+ flags |= FLAGS_LONGLONG;
+#else
+ flags |= FLAGS_LONG;
+#endif
+ break;
+#endif
+ case 'l':
+ if(flags & FLAGS_LONG)
+ flags |= FLAGS_LONGLONG;
+ else
+ flags |= FLAGS_LONG;
+ break;
+ case 'L':
+ flags |= FLAGS_LONGDOUBLE;
+ break;
+ case 'q':
+ flags |= FLAGS_LONGLONG;
+ break;
+ case 'z':
+ /* the code below generates a warning if -Wunreachable-code is
+ used */
+#if (SIZEOF_SIZE_T > CURL_SIZEOF_LONG)
+ flags |= FLAGS_LONGLONG;
+#else
+ flags |= FLAGS_LONG;
+#endif
+ break;
+ case 'O':
+#if (CURL_SIZEOF_CURL_OFF_T > CURL_SIZEOF_LONG)
+ flags |= FLAGS_LONGLONG;
+#else
+ flags |= FLAGS_LONG;
+#endif
+ break;
+ case '0':
+ if(!(flags & FLAGS_LEFT))
+ flags |= FLAGS_PAD_NIL;
+ /* FALLTHROUGH */
+ case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ flags |= FLAGS_WIDTH;
+ width = strtol(fmt-1, &fmt, 10);
+ break;
+ case '*': /* Special case */
+ flags |= FLAGS_WIDTHPARAM;
+ param_num++;
+
+ i = dprintf_DollarString(fmt, &fmt);
+ if(i)
+ width = i;
+ else
+ width = param_num;
+ if(width > max_param)
+ max_param=width;
+ break;
+ default:
+ break;
+ }
+ } /* switch */
+
+ /* Handle the specifier */
+
+ i = this_param - 1;
+
+ switch (*fmt) {
+ case 'S':
+ flags |= FLAGS_ALT;
+ /* FALLTHROUGH */
+ case 's':
+ vto[i].type = FORMAT_STRING;
+ break;
+ case 'n':
+ vto[i].type = FORMAT_INTPTR;
+ break;
+ case 'p':
+ vto[i].type = FORMAT_PTR;
+ break;
+ case 'd': case 'i':
+ vto[i].type = FORMAT_INT;
+ break;
+ case 'u':
+ vto[i].type = FORMAT_INT;
+ flags |= FLAGS_UNSIGNED;
+ break;
+ case 'o':
+ vto[i].type = FORMAT_INT;
+ flags |= FLAGS_OCTAL;
+ break;
+ case 'x':
+ vto[i].type = FORMAT_INT;
+ flags |= FLAGS_HEX|FLAGS_UNSIGNED;
+ break;
+ case 'X':
+ vto[i].type = FORMAT_INT;
+ flags |= FLAGS_HEX|FLAGS_UPPER|FLAGS_UNSIGNED;
+ break;
+ case 'c':
+ vto[i].type = FORMAT_INT;
+ flags |= FLAGS_CHAR;
+ break;
+ case 'f':
+ vto[i].type = FORMAT_DOUBLE;
+ break;
+ case 'e':
+ vto[i].type = FORMAT_DOUBLE;
+ flags |= FLAGS_FLOATE;
+ break;
+ case 'E':
+ vto[i].type = FORMAT_DOUBLE;
+ flags |= FLAGS_FLOATE|FLAGS_UPPER;
+ break;
+ case 'g':
+ vto[i].type = FORMAT_DOUBLE;
+ flags |= FLAGS_FLOATG;
+ break;
+ case 'G':
+ vto[i].type = FORMAT_DOUBLE;
+ flags |= FLAGS_FLOATG|FLAGS_UPPER;
+ break;
+ default:
+ vto[i].type = FORMAT_UNKNOWN;
+ break;
+ } /* switch */
+
+ vto[i].flags = flags;
+ vto[i].width = width;
+ vto[i].precision = precision;
+
+ if(flags & FLAGS_WIDTHPARAM) {
+ /* we have the width specified from a parameter, so we make that
+ parameter's info setup properly */
+ vto[i].width = width - 1;
+ i = width - 1;
+ vto[i].type = FORMAT_WIDTH;
+ vto[i].flags = FLAGS_NEW;
+ vto[i].precision = vto[i].width = 0; /* can't use width or precision
+ of width! */
+ }
+ if(flags & FLAGS_PRECPARAM) {
+ /* we have the precision specified from a parameter, so we make that
+ parameter's info setup properly */
+ vto[i].precision = precision - 1;
+ i = precision - 1;
+ vto[i].type = FORMAT_WIDTH;
+ vto[i].flags = FLAGS_NEW;
+ vto[i].precision = vto[i].width = 0; /* can't use width or precision
+ of width! */
+ }
+ *endpos++ = fmt + 1; /* end of this sequence */
+ }
+ }
+
+ /* Read the arg list parameters into our data list */
+ for(i=0; i<max_param; i++) {
+ if((i + 1 < max_param) && (vto[i + 1].type == FORMAT_WIDTH)) {
+ /* Width/precision arguments must be read before the main argument
+ * they are attached to
+ */
+ vto[i + 1].data.num.as_signed = (mp_intmax_t)va_arg(arglist, int);
+ }
+
+ switch (vto[i].type) {
+ case FORMAT_STRING:
+ vto[i].data.str = va_arg(arglist, char *);
+ break;
+
+ case FORMAT_INTPTR:
+ case FORMAT_UNKNOWN:
+ case FORMAT_PTR:
+ vto[i].data.ptr = va_arg(arglist, void *);
+ break;
+
+ case FORMAT_INT:
+#ifdef HAVE_LONG_LONG_TYPE
+ if((vto[i].flags & FLAGS_LONGLONG) && (vto[i].flags & FLAGS_UNSIGNED))
+ vto[i].data.num.as_unsigned =
+ (mp_uintmax_t)va_arg(arglist, mp_uintmax_t);
+ else if(vto[i].flags & FLAGS_LONGLONG)
+ vto[i].data.num.as_signed =
+ (mp_intmax_t)va_arg(arglist, mp_intmax_t);
+ else
+#endif
+ {
+ if((vto[i].flags & FLAGS_LONG) && (vto[i].flags & FLAGS_UNSIGNED))
+ vto[i].data.num.as_unsigned =
+ (mp_uintmax_t)va_arg(arglist, unsigned long);
+ else if(vto[i].flags & FLAGS_LONG)
+ vto[i].data.num.as_signed =
+ (mp_intmax_t)va_arg(arglist, long);
+ else if(vto[i].flags & FLAGS_UNSIGNED)
+ vto[i].data.num.as_unsigned =
+ (mp_uintmax_t)va_arg(arglist, unsigned int);
+ else
+ vto[i].data.num.as_signed =
+ (mp_intmax_t)va_arg(arglist, int);
+ }
+ break;
+
+ case FORMAT_DOUBLE:
+ vto[i].data.dnum = va_arg(arglist, double);
+ break;
+
+ case FORMAT_WIDTH:
+ /* Argument has been read. Silently convert it into an integer
+ * for later use
+ */
+ vto[i].type = FORMAT_INT;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return max_param;
+
+}
+
+static int dprintf_formatf(
+ void *data, /* untouched by format(), just sent to the stream() function in
+ the second argument */
+ /* function pointer called for each output character */
+ int (*stream)(int, FILE *),
+ const char *format, /* %-formatted string */
+ va_list ap_save) /* list of parameters */
+{
+ /* Base-36 digits for numbers. */
+ const char *digits = lower_digits;
+
+ /* Pointer into the format string. */
+ char *f;
+
+ /* Number of characters written. */
+ int done = 0;
+
+ long param; /* current parameter to read */
+ long param_num=0; /* parameter counter */
+
+ va_stack_t vto[MAX_PARAMETERS];
+ char *endpos[MAX_PARAMETERS];
+ char **end;
+
+ char work[BUFFSIZE];
+
+ va_stack_t *p;
+
+ /* Do the actual %-code parsing */
+ dprintf_Pass1(format, vto, endpos, ap_save);
+
+ end = &endpos[0]; /* the initial end-position from the list dprintf_Pass1()
+ created for us */
+
+ f = (char *)format;
+ while(*f != '\0') {
+ /* Format spec modifiers. */
+ int is_alt;
+
+ /* Width of a field. */
+ long width;
+
+ /* Precision of a field. */
+ long prec;
+
+ /* Decimal integer is negative. */
+ int is_neg;
+
+ /* Base of a number to be written. */
+ long base;
+
+ /* Integral values to be written. */
+ mp_uintmax_t num;
+
+ /* Used to convert negative in positive. */
+ mp_intmax_t signed_num;
+
+ if(*f != '%') {
+ /* This isn't a format spec, so write everything out until the next one
+ OR end of string is reached. */
+ do {
+ OUTCHAR(*f);
+ } while(*++f && ('%' != *f));
+ continue;
+ }
+
+ ++f;
+
+ /* Check for "%%". Note that although the ANSI standard lists
+ '%' as a conversion specifier, it says "The complete format
+ specification shall be `%%'," so we can avoid all the width
+ and precision processing. */
+ if(*f == '%') {
+ ++f;
+ OUTCHAR('%');
+ continue;
+ }
+
+ /* If this is a positional parameter, the position must follow immediately
+ after the %, thus create a %<num>$ sequence */
+ param=dprintf_DollarString(f, &f);
+
+ if(!param)
+ param = param_num;
+ else
+ --param;
+
+ param_num++; /* increase this always to allow "%2$s %1$s %s" and then the
+ third %s will pick the 3rd argument */
+
+ p = &vto[param];
+
+ /* pick up the specified width */
+ if(p->flags & FLAGS_WIDTHPARAM)
+ width = (long)vto[p->width].data.num.as_signed;
+ else
+ width = p->width;
+
+ /* pick up the specified precision */
+ if(p->flags & FLAGS_PRECPARAM) {
+ prec = (long)vto[p->precision].data.num.as_signed;
+ param_num++; /* since the precision is extraced from a parameter, we
+ must skip that to get to the next one properly */
+ }
+ else if(p->flags & FLAGS_PREC)
+ prec = p->precision;
+ else
+ prec = -1;
+
+ is_alt = (p->flags & FLAGS_ALT) ? 1 : 0;
+
+ switch (p->type) {
+ case FORMAT_INT:
+ num = p->data.num.as_unsigned;
+ if(p->flags & FLAGS_CHAR) {
+ /* Character. */
+ if(!(p->flags & FLAGS_LEFT))
+ while(--width > 0)
+ OUTCHAR(' ');
+ OUTCHAR((char) num);
+ if(p->flags & FLAGS_LEFT)
+ while(--width > 0)
+ OUTCHAR(' ');
+ break;
+ }
+ if(p->flags & FLAGS_OCTAL) {
+ /* Octal unsigned integer. */
+ base = 8;
+ goto unsigned_number;
+ }
+ else if(p->flags & FLAGS_HEX) {
+ /* Hexadecimal unsigned integer. */
+
+ digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits;
+ base = 16;
+ goto unsigned_number;
+ }
+ else if(p->flags & FLAGS_UNSIGNED) {
+ /* Decimal unsigned integer. */
+ base = 10;
+ goto unsigned_number;
+ }
+
+ /* Decimal integer. */
+ base = 10;
+
+ is_neg = (p->data.num.as_signed < (mp_intmax_t)0) ? 1 : 0;
+ if(is_neg) {
+ /* signed_num might fail to hold absolute negative minimum by 1 */
+ signed_num = p->data.num.as_signed + (mp_intmax_t)1;
+ signed_num = -signed_num;
+ num = (mp_uintmax_t)signed_num;
+ num += (mp_uintmax_t)1;
+ }
+
+ goto number;
+
+ unsigned_number:
+ /* Unsigned number of base BASE. */
+ is_neg = 0;
+
+ number:
+ /* Number of base BASE. */
+ {
+ char *workend = &work[sizeof(work) - 1];
+ char *w;
+
+ /* Supply a default precision if none was given. */
+ if(prec == -1)
+ prec = 1;
+
+ /* Put the number in WORK. */
+ w = workend;
+ while(num > 0) {
+ *w-- = digits[num % base];
+ num /= base;
+ }
+ width -= (long)(workend - w);
+ prec -= (long)(workend - w);
+
+ if(is_alt && base == 8 && prec <= 0) {
+ *w-- = '0';
+ --width;
+ }
+
+ if(prec > 0) {
+ width -= prec;
+ while(prec-- > 0)
+ *w-- = '0';
+ }
+
+ if(is_alt && base == 16)
+ width -= 2;
+
+ if(is_neg || (p->flags & FLAGS_SHOWSIGN) || (p->flags & FLAGS_SPACE))
+ --width;
+
+ if(!(p->flags & FLAGS_LEFT) && !(p->flags & FLAGS_PAD_NIL))
+ while(width-- > 0)
+ OUTCHAR(' ');
+
+ if(is_neg)
+ OUTCHAR('-');
+ else if(p->flags & FLAGS_SHOWSIGN)
+ OUTCHAR('+');
+ else if(p->flags & FLAGS_SPACE)
+ OUTCHAR(' ');
+
+ if(is_alt && base == 16) {
+ OUTCHAR('0');
+ if(p->flags & FLAGS_UPPER)
+ OUTCHAR('X');
+ else
+ OUTCHAR('x');
+ }
+
+ if(!(p->flags & FLAGS_LEFT) && (p->flags & FLAGS_PAD_NIL))
+ while(width-- > 0)
+ OUTCHAR('0');
+
+ /* Write the number. */
+ while(++w <= workend) {
+ OUTCHAR(*w);
+ }
+
+ if(p->flags & FLAGS_LEFT)
+ while(width-- > 0)
+ OUTCHAR(' ');
+ }
+ break;
+
+ case FORMAT_STRING:
+ /* String. */
+ {
+ static const char null[] = "(nil)";
+ const char *str;
+ size_t len;
+
+ str = (char *) p->data.str;
+ if(str == NULL) {
+ /* Write null[] if there's space. */
+ if(prec == -1 || prec >= (long) sizeof(null) - 1) {
+ str = null;
+ len = sizeof(null) - 1;
+ /* Disable quotes around (nil) */
+ p->flags &= (~FLAGS_ALT);
+ }
+ else {
+ str = "";
+ len = 0;
+ }
+ }
+ else if(prec != -1)
+ len = (size_t)prec;
+ else
+ len = strlen(str);
+
+ width -= (long)len;
+
+ if(p->flags & FLAGS_ALT)
+ OUTCHAR('"');
+
+ if(!(p->flags&FLAGS_LEFT))
+ while(width-- > 0)
+ OUTCHAR(' ');
+
+ while((len-- > 0) && *str)
+ OUTCHAR(*str++);
+ if(p->flags&FLAGS_LEFT)
+ while(width-- > 0)
+ OUTCHAR(' ');
+
+ if(p->flags & FLAGS_ALT)
+ OUTCHAR('"');
+ }
+ break;
+
+ case FORMAT_PTR:
+ /* Generic pointer. */
+ {
+ void *ptr;
+ ptr = (void *) p->data.ptr;
+ if(ptr != NULL) {
+ /* If the pointer is not NULL, write it as a %#x spec. */
+ base = 16;
+ digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits;
+ is_alt = 1;
+ num = (size_t) ptr;
+ is_neg = 0;
+ goto number;
+ }
+ else {
+ /* Write "(nil)" for a nil pointer. */
+ static const char strnil[] = "(nil)";
+ const char *point;
+
+ width -= (long)(sizeof(strnil) - 1);
+ if(p->flags & FLAGS_LEFT)
+ while(width-- > 0)
+ OUTCHAR(' ');
+ for(point = strnil; *point != '\0'; ++point)
+ OUTCHAR(*point);
+ if(! (p->flags & FLAGS_LEFT))
+ while(width-- > 0)
+ OUTCHAR(' ');
+ }
+ }
+ break;
+
+ case FORMAT_DOUBLE:
+ {
+ char formatbuf[32]="%";
+ char *fptr = &formatbuf[1];
+ size_t left = sizeof(formatbuf)-strlen(formatbuf);
+ int len;
+
+ width = -1;
+ if(p->flags & FLAGS_WIDTH)
+ width = p->width;
+ else if(p->flags & FLAGS_WIDTHPARAM)
+ width = (long)vto[p->width].data.num.as_signed;
+
+ prec = -1;
+ if(p->flags & FLAGS_PREC)
+ prec = p->precision;
+ else if(p->flags & FLAGS_PRECPARAM)
+ prec = (long)vto[p->precision].data.num.as_signed;
+
+ if(p->flags & FLAGS_LEFT)
+ *fptr++ = '-';
+ if(p->flags & FLAGS_SHOWSIGN)
+ *fptr++ = '+';
+ if(p->flags & FLAGS_SPACE)
+ *fptr++ = ' ';
+ if(p->flags & FLAGS_ALT)
+ *fptr++ = '#';
+
+ *fptr = 0;
+
+ if(width >= 0) {
+ /* RECURSIVE USAGE */
+ len = curl_msnprintf(fptr, left, "%ld", width);
+ fptr += len;
+ left -= len;
+ }
+ if(prec >= 0) {
+ /* RECURSIVE USAGE */
+ len = curl_msnprintf(fptr, left, ".%ld", prec);
+ fptr += len;
+ }
+ if(p->flags & FLAGS_LONG)
+ *fptr++ = 'l';
+
+ if(p->flags & FLAGS_FLOATE)
+ *fptr++ = (char)((p->flags & FLAGS_UPPER) ? 'E':'e');
+ else if(p->flags & FLAGS_FLOATG)
+ *fptr++ = (char)((p->flags & FLAGS_UPPER) ? 'G' : 'g');
+ else
+ *fptr++ = 'f';
+
+ *fptr = 0; /* and a final zero termination */
+
+ /* NOTE NOTE NOTE!! Not all sprintf implementations return number of
+ output characters */
+ (sprintf)(work, formatbuf, p->data.dnum);
+
+ for(fptr=work; *fptr; fptr++)
+ OUTCHAR(*fptr);
+ }
+ break;
+
+ case FORMAT_INTPTR:
+ /* Answer the count of characters written. */
+#ifdef HAVE_LONG_LONG_TYPE
+ if(p->flags & FLAGS_LONGLONG)
+ *(LONG_LONG_TYPE *) p->data.ptr = (LONG_LONG_TYPE)done;
+ else
+#endif
+ if(p->flags & FLAGS_LONG)
+ *(long *) p->data.ptr = (long)done;
+ else if(!(p->flags & FLAGS_SHORT))
+ *(int *) p->data.ptr = (int)done;
+ else
+ *(short *) p->data.ptr = (short)done;
+ break;
+
+ default:
+ break;
+ }
+ f = *end++; /* goto end of %-code */
+
+ }
+ return done;
+}
+
+/* fputc() look-alike */
+static int addbyter(int output, FILE *data)
+{
+ struct nsprintf *infop=(struct nsprintf *)data;
+ unsigned char outc = (unsigned char)output;
+
+ if(infop->length < infop->max) {
+ /* only do this if we haven't reached max length yet */
+ infop->buffer[0] = outc; /* store */
+ infop->buffer++; /* increase pointer */
+ infop->length++; /* we are now one byte larger */
+ return outc; /* fputc() returns like this on success */
+ }
+ return -1;
+}
+
+int curl_mvsnprintf(char *buffer, size_t maxlength, const char *format,
+ va_list ap_save)
+{
+ int retcode;
+ struct nsprintf info;
+
+ info.buffer = buffer;
+ info.length = 0;
+ info.max = maxlength;
+
+ retcode = dprintf_formatf(&info, addbyter, format, ap_save);
+ if(info.max) {
+ /* we terminate this with a zero byte */
+ if(info.max == info.length)
+ /* we're at maximum, scrap the last letter */
+ info.buffer[-1] = 0;
+ else
+ info.buffer[0] = 0;
+ }
+ return retcode;
+}
+
+int curl_msnprintf(char *buffer, size_t maxlength, const char *format, ...)
+{
+ int retcode;
+ va_list ap_save; /* argument pointer */
+ va_start(ap_save, format);
+ retcode = curl_mvsnprintf(buffer, maxlength, format, ap_save);
+ va_end(ap_save);
+ return retcode;
+}
+
+/* fputc() look-alike */
+static int alloc_addbyter(int output, FILE *data)
+{
+ struct asprintf *infop=(struct asprintf *)data;
+ unsigned char outc = (unsigned char)output;
+
+ if(!infop->buffer) {
+ infop->buffer = malloc(32);
+ if(!infop->buffer) {
+ infop->fail = 1;
+ return -1; /* fail */
+ }
+ infop->alloc = 32;
+ infop->len =0;
+ }
+ else if(infop->len+1 >= infop->alloc) {
+ char *newptr;
+
+ newptr = realloc(infop->buffer, infop->alloc*2);
+
+ if(!newptr) {
+ infop->fail = 1;
+ return -1; /* fail */
+ }
+ infop->buffer = newptr;
+ infop->alloc *= 2;
+ }
+
+ infop->buffer[ infop->len ] = outc;
+
+ infop->len++;
+
+ return outc; /* fputc() returns like this on success */
+}
+
+char *curl_maprintf(const char *format, ...)
+{
+ va_list ap_save; /* argument pointer */
+ int retcode;
+ struct asprintf info;
+
+ info.buffer = NULL;
+ info.len = 0;
+ info.alloc = 0;
+ info.fail = 0;
+
+ va_start(ap_save, format);
+ retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
+ va_end(ap_save);
+ if((-1 == retcode) || info.fail) {
+ if(info.alloc)
+ free(info.buffer);
+ return NULL;
+ }
+ if(info.alloc) {
+ info.buffer[info.len] = 0; /* we terminate this with a zero byte */
+ return info.buffer;
+ }
+ else
+ return strdup("");
+}
+
+char *curl_mvaprintf(const char *format, va_list ap_save)
+{
+ int retcode;
+ struct asprintf info;
+
+ info.buffer = NULL;
+ info.len = 0;
+ info.alloc = 0;
+ info.fail = 0;
+
+ retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
+ if((-1 == retcode) || info.fail) {
+ if(info.alloc)
+ free(info.buffer);
+ return NULL;
+ }
+
+ if(info.alloc) {
+ info.buffer[info.len] = 0; /* we terminate this with a zero byte */
+ return info.buffer;
+ }
+ else
+ return strdup("");
+}
+
+static int storebuffer(int output, FILE *data)
+{
+ char **buffer = (char **)data;
+ unsigned char outc = (unsigned char)output;
+ **buffer = outc;
+ (*buffer)++;
+ return outc; /* act like fputc() ! */
+}
+
+int curl_msprintf(char *buffer, const char *format, ...)
+{
+ va_list ap_save; /* argument pointer */
+ int retcode;
+ va_start(ap_save, format);
+ retcode = dprintf_formatf(&buffer, storebuffer, format, ap_save);
+ va_end(ap_save);
+ *buffer=0; /* we terminate this with a zero byte */
+ return retcode;
+}
+
+int curl_mprintf(const char *format, ...)
+{
+ int retcode;
+ va_list ap_save; /* argument pointer */
+ va_start(ap_save, format);
+
+ retcode = dprintf_formatf(stdout, fputc, format, ap_save);
+ va_end(ap_save);
+ return retcode;
+}
+
+int curl_mfprintf(FILE *whereto, const char *format, ...)
+{
+ int retcode;
+ va_list ap_save; /* argument pointer */
+ va_start(ap_save, format);
+ retcode = dprintf_formatf(whereto, fputc, format, ap_save);
+ va_end(ap_save);
+ return retcode;
+}
+
+int curl_mvsprintf(char *buffer, const char *format, va_list ap_save)
+{
+ int retcode;
+ retcode = dprintf_formatf(&buffer, storebuffer, format, ap_save);
+ *buffer=0; /* we terminate this with a zero byte */
+ return retcode;
+}
+
+int curl_mvprintf(const char *format, va_list ap_save)
+{
+ return dprintf_formatf(stdout, fputc, format, ap_save);
+}
+
+int curl_mvfprintf(FILE *whereto, const char *format, va_list ap_save)
+{
+ return dprintf_formatf(whereto, fputc, format, ap_save);
+}
diff --git a/Utilities/cmcurl/lib/multi.c b/Utilities/cmcurl/lib/multi.c
new file mode 100644
index 000000000..00520873c
--- /dev/null
+++ b/Utilities/cmcurl/lib/multi.c
@@ -0,0 +1,2824 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#include "urldata.h"
+#include "transfer.h"
+#include "url.h"
+#include "connect.h"
+#include "progress.h"
+#include "easyif.h"
+#include "share.h"
+#include "multiif.h"
+#include "sendf.h"
+#include "timeval.h"
+#include "http.h"
+#include "select.h"
+#include "warnless.h"
+#include "speedcheck.h"
+#include "conncache.h"
+#include "multihandle.h"
+#include "pipeline.h"
+#include "sigpipe.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ CURL_SOCKET_HASH_TABLE_SIZE should be a prime number. Increasing it from 97
+ to 911 takes on a 32-bit machine 4 x 804 = 3211 more bytes. Still, every
+ CURL handle takes 45-50 K memory, therefore this 3K are not significant.
+*/
+#ifndef CURL_SOCKET_HASH_TABLE_SIZE
+#define CURL_SOCKET_HASH_TABLE_SIZE 911
+#endif
+
+#define CURL_CONNECTION_HASH_SIZE 97
+
+#define CURL_MULTI_HANDLE 0x000bab1e
+
+#define GOOD_MULTI_HANDLE(x) \
+ ((x) && (((struct Curl_multi *)(x))->type == CURL_MULTI_HANDLE))
+
+static void singlesocket(struct Curl_multi *multi,
+ struct SessionHandle *data);
+static int update_timer(struct Curl_multi *multi);
+
+static CURLMcode add_next_timeout(struct timeval now,
+ struct Curl_multi *multi,
+ struct SessionHandle *d);
+static CURLMcode multi_timeout(struct Curl_multi *multi,
+ long *timeout_ms);
+
+#ifdef DEBUGBUILD
+static const char * const statename[]={
+ "INIT",
+ "CONNECT_PEND",
+ "CONNECT",
+ "WAITRESOLVE",
+ "WAITCONNECT",
+ "WAITPROXYCONNECT",
+ "SENDPROTOCONNECT",
+ "PROTOCONNECT",
+ "WAITDO",
+ "DO",
+ "DOING",
+ "DO_MORE",
+ "DO_DONE",
+ "WAITPERFORM",
+ "PERFORM",
+ "TOOFAST",
+ "DONE",
+ "COMPLETED",
+ "MSGSENT",
+};
+#endif
+
+static void multi_freetimeout(void *a, void *b);
+
+/* always use this function to change state, to make debugging easier */
+static void mstate(struct SessionHandle *data, CURLMstate state
+#ifdef DEBUGBUILD
+ , int lineno
+#endif
+)
+{
+ CURLMstate oldstate = data->mstate;
+
+#if defined(DEBUGBUILD) && defined(CURL_DISABLE_VERBOSE_STRINGS)
+ (void) lineno;
+#endif
+
+ if(oldstate == state)
+ /* don't bother when the new state is the same as the old state */
+ return;
+
+ data->mstate = state;
+
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+ if(data->mstate >= CURLM_STATE_CONNECT_PEND &&
+ data->mstate < CURLM_STATE_COMPLETED) {
+ long connection_id = -5000;
+
+ if(data->easy_conn)
+ connection_id = data->easy_conn->connection_id;
+
+ infof(data,
+ "STATE: %s => %s handle %p; line %d (connection #%ld) \n",
+ statename[oldstate], statename[data->mstate],
+ (void *)data, lineno, connection_id);
+ }
+#endif
+
+ if(state == CURLM_STATE_COMPLETED)
+ /* changing to COMPLETED means there's one less easy handle 'alive' */
+ data->multi->num_alive--;
+}
+
+#ifndef DEBUGBUILD
+#define multistate(x,y) mstate(x,y)
+#else
+#define multistate(x,y) mstate(x,y, __LINE__)
+#endif
+
+/*
+ * We add one of these structs to the sockhash for a particular socket
+ */
+
+struct Curl_sh_entry {
+ struct SessionHandle *easy;
+ int action; /* what action READ/WRITE this socket waits for */
+ curl_socket_t socket; /* mainly to ease debugging */
+ void *socketp; /* settable by users with curl_multi_assign() */
+};
+/* bits for 'action' having no bits means this socket is not expecting any
+ action */
+#define SH_READ 1
+#define SH_WRITE 2
+
+/* make sure this socket is present in the hash for this handle */
+static struct Curl_sh_entry *sh_addentry(struct curl_hash *sh,
+ curl_socket_t s,
+ struct SessionHandle *data)
+{
+ struct Curl_sh_entry *there =
+ Curl_hash_pick(sh, (char *)&s, sizeof(curl_socket_t));
+ struct Curl_sh_entry *check;
+
+ if(there)
+ /* it is present, return fine */
+ return there;
+
+ /* not present, add it */
+ check = calloc(1, sizeof(struct Curl_sh_entry));
+ if(!check)
+ return NULL; /* major failure */
+
+ check->easy = data;
+ check->socket = s;
+
+ /* make/add new hash entry */
+ if(!Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) {
+ free(check);
+ return NULL; /* major failure */
+ }
+
+ return check; /* things are good in sockhash land */
+}
+
+
+/* delete the given socket + handle from the hash */
+static void sh_delentry(struct curl_hash *sh, curl_socket_t s)
+{
+ struct Curl_sh_entry *there =
+ Curl_hash_pick(sh, (char *)&s, sizeof(curl_socket_t));
+
+ if(there) {
+ /* this socket is in the hash */
+ /* We remove the hash entry. (This'll end up in a call to
+ sh_freeentry().) */
+ Curl_hash_delete(sh, (char *)&s, sizeof(curl_socket_t));
+ }
+}
+
+/*
+ * free a sockhash entry
+ */
+static void sh_freeentry(void *freethis)
+{
+ struct Curl_sh_entry *p = (struct Curl_sh_entry *) freethis;
+
+ free(p);
+}
+
+static size_t fd_key_compare(void *k1, size_t k1_len, void *k2, size_t k2_len)
+{
+ (void) k1_len; (void) k2_len;
+
+ return (*((int *) k1)) == (*((int *) k2));
+}
+
+static size_t hash_fd(void *key, size_t key_length, size_t slots_num)
+{
+ int fd = *((int *) key);
+ (void) key_length;
+
+ return (fd % (int)slots_num);
+}
+
+/*
+ * sh_init() creates a new socket hash and returns the handle for it.
+ *
+ * Quote from README.multi_socket:
+ *
+ * "Some tests at 7000 and 9000 connections showed that the socket hash lookup
+ * is somewhat of a bottle neck. Its current implementation may be a bit too
+ * limiting. It simply has a fixed-size array, and on each entry in the array
+ * it has a linked list with entries. So the hash only checks which list to
+ * scan through. The code I had used so for used a list with merely 7 slots
+ * (as that is what the DNS hash uses) but with 7000 connections that would
+ * make an average of 1000 nodes in each list to run through. I upped that to
+ * 97 slots (I believe a prime is suitable) and noticed a significant speed
+ * increase. I need to reconsider the hash implementation or use a rather
+ * large default value like this. At 9000 connections I was still below 10us
+ * per call."
+ *
+ */
+static int sh_init(struct curl_hash *hash, int hashsize)
+{
+ return Curl_hash_init(hash, hashsize, hash_fd, fd_key_compare,
+ sh_freeentry);
+}
+
+/*
+ * multi_addmsg()
+ *
+ * Called when a transfer is completed. Adds the given msg pointer to
+ * the list kept in the multi handle.
+ */
+static CURLMcode multi_addmsg(struct Curl_multi *multi,
+ struct Curl_message *msg)
+{
+ if(!Curl_llist_insert_next(multi->msglist, multi->msglist->tail, msg))
+ return CURLM_OUT_OF_MEMORY;
+
+ return CURLM_OK;
+}
+
+/*
+ * multi_freeamsg()
+ *
+ * Callback used by the llist system when a single list entry is destroyed.
+ */
+static void multi_freeamsg(void *a, void *b)
+{
+ (void)a;
+ (void)b;
+}
+
+struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
+ int chashsize) /* connection hash */
+{
+ struct Curl_multi *multi = calloc(1, sizeof(struct Curl_multi));
+
+ if(!multi)
+ return NULL;
+
+ multi->type = CURL_MULTI_HANDLE;
+
+ if(Curl_mk_dnscache(&multi->hostcache))
+ goto error;
+
+ if(sh_init(&multi->sockhash, hashsize))
+ goto error;
+
+ if(Curl_conncache_init(&multi->conn_cache, chashsize))
+ goto error;
+
+ multi->msglist = Curl_llist_alloc(multi_freeamsg);
+ if(!multi->msglist)
+ goto error;
+
+ multi->pending = Curl_llist_alloc(multi_freeamsg);
+ if(!multi->pending)
+ goto error;
+
+ /* allocate a new easy handle to use when closing cached connections */
+ multi->closure_handle = curl_easy_init();
+ if(!multi->closure_handle)
+ goto error;
+
+ multi->closure_handle->multi = multi;
+ multi->closure_handle->state.conn_cache = &multi->conn_cache;
+
+ multi->max_pipeline_length = 5;
+
+ /* -1 means it not set by user, use the default value */
+ multi->maxconnects = -1;
+ return (CURLM *) multi;
+
+ error:
+
+ Curl_hash_destroy(&multi->sockhash);
+ Curl_hash_destroy(&multi->hostcache);
+ Curl_conncache_destroy(&multi->conn_cache);
+ Curl_close(multi->closure_handle);
+ multi->closure_handle = NULL;
+ Curl_llist_destroy(multi->msglist, NULL);
+ Curl_llist_destroy(multi->pending, NULL);
+
+ free(multi);
+ return NULL;
+}
+
+CURLM *curl_multi_init(void)
+{
+ return Curl_multi_handle(CURL_SOCKET_HASH_TABLE_SIZE,
+ CURL_CONNECTION_HASH_SIZE);
+}
+
+CURLMcode curl_multi_add_handle(CURLM *multi_handle,
+ CURL *easy_handle)
+{
+ struct curl_llist *timeoutlist;
+ struct Curl_multi *multi = (struct Curl_multi *)multi_handle;
+ struct SessionHandle *data = (struct SessionHandle *)easy_handle;
+
+ /* First, make some basic checks that the CURLM handle is a good handle */
+ if(!GOOD_MULTI_HANDLE(multi))
+ return CURLM_BAD_HANDLE;
+
+ /* Verify that we got a somewhat good easy handle too */
+ if(!GOOD_EASY_HANDLE(easy_handle))
+ return CURLM_BAD_EASY_HANDLE;
+
+ /* Prevent users from adding same easy handle more than once and prevent
+ adding to more than one multi stack */
+ if(data->multi)
+ return CURLM_ADDED_ALREADY;
+
+ /* Allocate and initialize timeout list for easy handle */
+ timeoutlist = Curl_llist_alloc(multi_freetimeout);
+ if(!timeoutlist)
+ return CURLM_OUT_OF_MEMORY;
+
+ /*
+ * No failure allowed in this function beyond this point. And no
+ * modification of easy nor multi handle allowed before this except for
+ * potential multi's connection cache growing which won't be undone in this
+ * function no matter what.
+ */
+
+ /* Make easy handle use timeout list initialized above */
+ data->state.timeoutlist = timeoutlist;
+ timeoutlist = NULL;
+
+ /* set the easy handle */
+ multistate(data, CURLM_STATE_INIT);
+
+ if((data->set.global_dns_cache) &&
+ (data->dns.hostcachetype != HCACHE_GLOBAL)) {
+ /* global dns cache was requested but still isn't */
+ struct curl_hash *global = Curl_global_host_cache_init();
+ if(global) {
+ /* only do this if the global cache init works */
+ data->dns.hostcache = global;
+ data->dns.hostcachetype = HCACHE_GLOBAL;
+ }
+ }
+ /* for multi interface connections, we share DNS cache automatically if the
+ easy handle's one is currently not set. */
+ else if(!data->dns.hostcache ||
+ (data->dns.hostcachetype == HCACHE_NONE)) {
+ data->dns.hostcache = &multi->hostcache;
+ data->dns.hostcachetype = HCACHE_MULTI;
+ }
+
+ /* Point to the multi's connection cache */
+ data->state.conn_cache = &multi->conn_cache;
+
+ /* This adds the new entry at the 'end' of the doubly-linked circular
+ list of SessionHandle structs to try and maintain a FIFO queue so
+ the pipelined requests are in order. */
+
+ /* We add this new entry last in the list. */
+
+ data->next = NULL; /* end of the line */
+ if(multi->easyp) {
+ struct SessionHandle *last = multi->easylp;
+ last->next = data;
+ data->prev = last;
+ multi->easylp = data; /* the new last node */
+ }
+ else {
+ /* first node, make prev NULL! */
+ data->prev = NULL;
+ multi->easylp = multi->easyp = data; /* both first and last */
+ }
+
+ /* make the SessionHandle refer back to this multi handle */
+ data->multi = multi_handle;
+
+ /* Set the timeout for this handle to expire really soon so that it will
+ be taken care of even when this handle is added in the midst of operation
+ when only the curl_multi_socket() API is used. During that flow, only
+ sockets that time-out or have actions will be dealt with. Since this
+ handle has no action yet, we make sure it times out to get things to
+ happen. */
+ Curl_expire(data, 1);
+
+ /* increase the node-counter */
+ multi->num_easy++;
+
+ /* increase the alive-counter */
+ multi->num_alive++;
+
+ /* A somewhat crude work-around for a little glitch in update_timer() that
+ happens if the lastcall time is set to the same time when the handle is
+ removed as when the next handle is added, as then the check in
+ update_timer() that prevents calling the application multiple times with
+ the same timer infor will not trigger and then the new handle's timeout
+ will not be notified to the app.
+
+ The work-around is thus simply to clear the 'lastcall' variable to force
+ update_timer() to always trigger a callback to the app when a new easy
+ handle is added */
+ memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
+
+ update_timer(multi);
+ return CURLM_OK;
+}
+
+#if 0
+/* Debug-function, used like this:
+ *
+ * Curl_hash_print(multi->sockhash, debug_print_sock_hash);
+ *
+ * Enable the hash print function first by editing hash.c
+ */
+static void debug_print_sock_hash(void *p)
+{
+ struct Curl_sh_entry *sh = (struct Curl_sh_entry *)p;
+
+ fprintf(stderr, " [easy %p/magic %x/socket %d]",
+ (void *)sh->data, sh->data->magic, (int)sh->socket);
+}
+#endif
+
+CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
+ CURL *curl_handle)
+{
+ struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
+ struct SessionHandle *easy = curl_handle;
+ struct SessionHandle *data = easy;
+ bool premature;
+ bool easy_owns_conn;
+ struct curl_llist_element *e;
+
+ /* First, make some basic checks that the CURLM handle is a good handle */
+ if(!GOOD_MULTI_HANDLE(multi))
+ return CURLM_BAD_HANDLE;
+
+ /* Verify that we got a somewhat good easy handle too */
+ if(!GOOD_EASY_HANDLE(curl_handle))
+ return CURLM_BAD_EASY_HANDLE;
+
+ /* Prevent users from trying to remove same easy handle more than once */
+ if(!data->multi)
+ return CURLM_OK; /* it is already removed so let's say it is fine! */
+
+ premature = (data->mstate < CURLM_STATE_COMPLETED) ? TRUE : FALSE;
+ easy_owns_conn = (data->easy_conn && (data->easy_conn->data == easy)) ?
+ TRUE : FALSE;
+
+ /* If the 'state' is not INIT or COMPLETED, we might need to do something
+ nice to put the easy_handle in a good known state when this returns. */
+ if(premature) {
+ /* this handle is "alive" so we need to count down the total number of
+ alive connections when this is removed */
+ multi->num_alive--;
+
+ /* When this handle gets removed, other handles may be able to get the
+ connection */
+ Curl_multi_process_pending_handles(multi);
+ }
+
+ if(data->easy_conn &&
+ data->mstate > CURLM_STATE_DO &&
+ data->mstate < CURLM_STATE_COMPLETED) {
+ /* If the handle is in a pipeline and has started sending off its
+ request but not received its response yet, we need to close
+ connection. */
+ connclose(data->easy_conn, "Removed with partial response");
+ /* Set connection owner so that Curl_done() closes it.
+ We can safely do this here since connection is killed. */
+ data->easy_conn->data = easy;
+ easy_owns_conn = TRUE;
+ }
+
+ /* The timer must be shut down before data->multi is set to NULL,
+ else the timenode will remain in the splay tree after
+ curl_easy_cleanup is called. */
+ Curl_expire(data, 0);
+
+ /* destroy the timeout list that is held in the easy handle */
+ if(data->state.timeoutlist) {
+ Curl_llist_destroy(data->state.timeoutlist, NULL);
+ data->state.timeoutlist = NULL;
+ }
+
+ if(data->dns.hostcachetype == HCACHE_MULTI) {
+ /* stop using the multi handle's DNS cache */
+ data->dns.hostcache = NULL;
+ data->dns.hostcachetype = HCACHE_NONE;
+ }
+
+ if(data->easy_conn) {
+
+ /* we must call Curl_done() here (if we still "own it") so that we don't
+ leave a half-baked one around */
+ if(easy_owns_conn) {
+
+ /* Curl_done() clears the conn->data field to lose the association
+ between the easy handle and the connection
+
+ Note that this ignores the return code simply because there's
+ nothing really useful to do with it anyway! */
+ (void)Curl_done(&data->easy_conn, data->result, premature);
+ }
+ else
+ /* Clear connection pipelines, if Curl_done above was not called */
+ Curl_getoff_all_pipelines(data, data->easy_conn);
+ }
+
+ Curl_wildcard_dtor(&data->wildcard);
+
+ /* as this was using a shared connection cache we clear the pointer to that
+ since we're not part of that multi handle anymore */
+ data->state.conn_cache = NULL;
+
+ /* change state without using multistate(), only to make singlesocket() do
+ what we want */
+ data->mstate = CURLM_STATE_COMPLETED;
+ singlesocket(multi, easy); /* to let the application know what sockets that
+ vanish with this handle */
+
+ /* Remove the association between the connection and the handle */
+ if(data->easy_conn) {
+ data->easy_conn->data = NULL;
+ data->easy_conn = NULL;
+ }
+
+ data->multi = NULL; /* clear the association to this multi handle */
+
+ /* make sure there's no pending message in the queue sent from this easy
+ handle */
+
+ for(e = multi->msglist->head; e; e = e->next) {
+ struct Curl_message *msg = e->ptr;
+
+ if(msg->extmsg.easy_handle == easy) {
+ Curl_llist_remove(multi->msglist, e, NULL);
+ /* there can only be one from this specific handle */
+ break;
+ }
+ }
+
+ /* make the previous node point to our next */
+ if(data->prev)
+ data->prev->next = data->next;
+ else
+ multi->easyp = data->next; /* point to first node */
+
+ /* make our next point to our previous node */
+ if(data->next)
+ data->next->prev = data->prev;
+ else
+ multi->easylp = data->prev; /* point to last node */
+
+ /* NOTE NOTE NOTE
+ We do not touch the easy handle here! */
+ multi->num_easy--; /* one less to care about now */
+
+ update_timer(multi);
+ return CURLM_OK;
+}
+
+/* Return TRUE if the application asked for a certain set of pipelining */
+bool Curl_pipeline_wanted(const struct Curl_multi *multi, int bits)
+{
+ return (multi && (multi->pipelining & bits)) ? TRUE : FALSE;
+}
+
+void Curl_multi_handlePipeBreak(struct SessionHandle *data)
+{
+ data->easy_conn = NULL;
+}
+
+static int waitconnect_getsock(struct connectdata *conn,
+ curl_socket_t *sock,
+ int numsocks)
+{
+ int i;
+ int s=0;
+ int rc=0;
+
+ if(!numsocks)
+ return GETSOCK_BLANK;
+
+ for(i=0; i<2; i++) {
+ if(conn->tempsock[i] != CURL_SOCKET_BAD) {
+ sock[s] = conn->tempsock[i];
+ rc |= GETSOCK_WRITESOCK(s++);
+ }
+ }
+
+ return rc;
+}
+
+static int waitproxyconnect_getsock(struct connectdata *conn,
+ curl_socket_t *sock,
+ int numsocks)
+{
+ if(!numsocks)
+ return GETSOCK_BLANK;
+
+ sock[0] = conn->sock[FIRSTSOCKET];
+
+ /* when we've sent a CONNECT to a proxy, we should rather wait for the
+ socket to become readable to be able to get the response headers */
+ if(conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
+ return GETSOCK_READSOCK(0);
+
+ return GETSOCK_WRITESOCK(0);
+}
+
+static int domore_getsock(struct connectdata *conn,
+ curl_socket_t *socks,
+ int numsocks)
+{
+ if(conn && conn->handler->domore_getsock)
+ return conn->handler->domore_getsock(conn, socks, numsocks);
+ return GETSOCK_BLANK;
+}
+
+/* returns bitmapped flags for this handle and its sockets */
+static int multi_getsock(struct SessionHandle *data,
+ curl_socket_t *socks, /* points to numsocks number
+ of sockets */
+ int numsocks)
+{
+ /* If the pipe broke, or if there's no connection left for this easy handle,
+ then we MUST bail out now with no bitmask set. The no connection case can
+ happen when this is called from curl_multi_remove_handle() =>
+ singlesocket() => multi_getsock().
+ */
+ if(data->state.pipe_broke || !data->easy_conn)
+ return 0;
+
+ if(data->mstate > CURLM_STATE_CONNECT &&
+ data->mstate < CURLM_STATE_COMPLETED) {
+ /* Set up ownership correctly */
+ data->easy_conn->data = data;
+ }
+
+ switch(data->mstate) {
+ default:
+#if 0 /* switch back on these cases to get the compiler to check for all enums
+ to be present */
+ case CURLM_STATE_TOOFAST: /* returns 0, so will not select. */
+ case CURLM_STATE_COMPLETED:
+ case CURLM_STATE_MSGSENT:
+ case CURLM_STATE_INIT:
+ case CURLM_STATE_CONNECT:
+ case CURLM_STATE_WAITDO:
+ case CURLM_STATE_DONE:
+ case CURLM_STATE_LAST:
+ /* this will get called with CURLM_STATE_COMPLETED when a handle is
+ removed */
+#endif
+ return 0;
+
+ case CURLM_STATE_WAITRESOLVE:
+ return Curl_resolver_getsock(data->easy_conn, socks, numsocks);
+
+ case CURLM_STATE_PROTOCONNECT:
+ case CURLM_STATE_SENDPROTOCONNECT:
+ return Curl_protocol_getsock(data->easy_conn, socks, numsocks);
+
+ case CURLM_STATE_DO:
+ case CURLM_STATE_DOING:
+ return Curl_doing_getsock(data->easy_conn, socks, numsocks);
+
+ case CURLM_STATE_WAITPROXYCONNECT:
+ return waitproxyconnect_getsock(data->easy_conn, socks, numsocks);
+
+ case CURLM_STATE_WAITCONNECT:
+ return waitconnect_getsock(data->easy_conn, socks, numsocks);
+
+ case CURLM_STATE_DO_MORE:
+ return domore_getsock(data->easy_conn, socks, numsocks);
+
+ case CURLM_STATE_DO_DONE: /* since is set after DO is completed, we switch
+ to waiting for the same as the *PERFORM
+ states */
+ case CURLM_STATE_PERFORM:
+ case CURLM_STATE_WAITPERFORM:
+ return Curl_single_getsock(data->easy_conn, socks, numsocks);
+ }
+
+}
+
+CURLMcode curl_multi_fdset(CURLM *multi_handle,
+ fd_set *read_fd_set, fd_set *write_fd_set,
+ fd_set *exc_fd_set, int *max_fd)
+{
+ /* Scan through all the easy handles to get the file descriptors set.
+ Some easy handles may not have connected to the remote host yet,
+ and then we must make sure that is done. */
+ struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
+ struct SessionHandle *data;
+ int this_max_fd=-1;
+ curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
+ int bitmap;
+ int i;
+ (void)exc_fd_set; /* not used */
+
+ if(!GOOD_MULTI_HANDLE(multi))
+ return CURLM_BAD_HANDLE;
+
+ data=multi->easyp;
+ while(data) {
+ bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
+
+ for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
+ curl_socket_t s = CURL_SOCKET_BAD;
+
+ if((bitmap & GETSOCK_READSOCK(i)) && VALID_SOCK((sockbunch[i]))) {
+ FD_SET(sockbunch[i], read_fd_set);
+ s = sockbunch[i];
+ }
+ if((bitmap & GETSOCK_WRITESOCK(i)) && VALID_SOCK((sockbunch[i]))) {
+ FD_SET(sockbunch[i], write_fd_set);
+ s = sockbunch[i];
+ }
+ if(s == CURL_SOCKET_BAD)
+ /* this socket is unused, break out of loop */
+ break;
+ else {
+ if((int)s > this_max_fd)
+ this_max_fd = (int)s;
+ }
+ }
+
+ data = data->next; /* check next handle */
+ }
+
+ *max_fd = this_max_fd;
+
+ return CURLM_OK;
+}
+
+CURLMcode curl_multi_wait(CURLM *multi_handle,
+ struct curl_waitfd extra_fds[],
+ unsigned int extra_nfds,
+ int timeout_ms,
+ int *ret)
+{
+ struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
+ struct SessionHandle *data;
+ curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
+ int bitmap;
+ unsigned int i;
+ unsigned int nfds = 0;
+ unsigned int curlfds;
+ struct pollfd *ufds = NULL;
+ long timeout_internal;
+
+ if(!GOOD_MULTI_HANDLE(multi))
+ return CURLM_BAD_HANDLE;
+
+ /* If the internally desired timeout is actually shorter than requested from
+ the outside, then use the shorter time! But only if the internal timer
+ is actually larger than -1! */
+ (void)multi_timeout(multi, &timeout_internal);
+ if((timeout_internal >= 0) && (timeout_internal < (long)timeout_ms))
+ timeout_ms = (int)timeout_internal;
+
+ /* Count up how many fds we have from the multi handle */
+ data=multi->easyp;
+ while(data) {
+ bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
+
+ for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
+ curl_socket_t s = CURL_SOCKET_BAD;
+
+ if(bitmap & GETSOCK_READSOCK(i)) {
+ ++nfds;
+ s = sockbunch[i];
+ }
+ if(bitmap & GETSOCK_WRITESOCK(i)) {
+ ++nfds;
+ s = sockbunch[i];
+ }
+ if(s == CURL_SOCKET_BAD) {
+ break;
+ }
+ }
+
+ data = data->next; /* check next handle */
+ }
+
+ curlfds = nfds; /* number of internal file descriptors */
+ nfds += extra_nfds; /* add the externally provided ones */
+
+ if(nfds || extra_nfds) {
+ ufds = malloc(nfds * sizeof(struct pollfd));
+ if(!ufds)
+ return CURLM_OUT_OF_MEMORY;
+ }
+ nfds = 0;
+
+ /* only do the second loop if we found descriptors in the first stage run
+ above */
+
+ if(curlfds) {
+ /* Add the curl handles to our pollfds first */
+ data=multi->easyp;
+ while(data) {
+ bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
+
+ for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
+ curl_socket_t s = CURL_SOCKET_BAD;
+
+ if(bitmap & GETSOCK_READSOCK(i)) {
+ ufds[nfds].fd = sockbunch[i];
+ ufds[nfds].events = POLLIN;
+ ++nfds;
+ s = sockbunch[i];
+ }
+ if(bitmap & GETSOCK_WRITESOCK(i)) {
+ ufds[nfds].fd = sockbunch[i];
+ ufds[nfds].events = POLLOUT;
+ ++nfds;
+ s = sockbunch[i];
+ }
+ if(s == CURL_SOCKET_BAD) {
+ break;
+ }
+ }
+
+ data = data->next; /* check next handle */
+ }
+ }
+
+ /* Add external file descriptions from poll-like struct curl_waitfd */
+ for(i = 0; i < extra_nfds; i++) {
+ ufds[nfds].fd = extra_fds[i].fd;
+ ufds[nfds].events = 0;
+ if(extra_fds[i].events & CURL_WAIT_POLLIN)
+ ufds[nfds].events |= POLLIN;
+ if(extra_fds[i].events & CURL_WAIT_POLLPRI)
+ ufds[nfds].events |= POLLPRI;
+ if(extra_fds[i].events & CURL_WAIT_POLLOUT)
+ ufds[nfds].events |= POLLOUT;
+ ++nfds;
+ }
+
+ if(nfds) {
+ /* wait... */
+ infof(data, "Curl_poll(%d ds, %d ms)\n", nfds, timeout_ms);
+ i = Curl_poll(ufds, nfds, timeout_ms);
+
+ if(i) {
+ unsigned int j;
+ /* copy revents results from the poll to the curl_multi_wait poll
+ struct, the bit values of the actual underlying poll() implementation
+ may not be the same as the ones in the public libcurl API! */
+ for(j = 0; j < extra_nfds; j++) {
+ unsigned short mask = 0;
+ unsigned r = ufds[curlfds + j].revents;
+
+ if(r & POLLIN)
+ mask |= CURL_WAIT_POLLIN;
+ if(r & POLLOUT)
+ mask |= CURL_WAIT_POLLOUT;
+ if(r & POLLPRI)
+ mask |= CURL_WAIT_POLLPRI;
+
+ extra_fds[j].revents = mask;
+ }
+ }
+ }
+ else
+ i = 0;
+
+ free(ufds);
+ if(ret)
+ *ret = i;
+ return CURLM_OK;
+}
+
+/*
+ * Curl_multi_connchanged() is called to tell that there is a connection in
+ * this multi handle that has changed state (pipelining become possible, the
+ * number of allowed streams changed or similar), and a subsequent use of this
+ * multi handle should move CONNECT_PEND handles back to CONNECT to have them
+ * retry.
+ */
+void Curl_multi_connchanged(struct Curl_multi *multi)
+{
+ multi->recheckstate = TRUE;
+}
+
+/*
+ * multi_ischanged() is called
+ *
+ * Returns TRUE/FALSE whether the state is changed to trigger a CONNECT_PEND
+ * => CONNECT action.
+ *
+ * Set 'clear' to TRUE to have it also clear the state variable.
+ */
+static bool multi_ischanged(struct Curl_multi *multi, bool clear)
+{
+ bool retval = multi->recheckstate;
+ if(clear)
+ multi->recheckstate = FALSE;
+ return retval;
+}
+
+CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
+ struct SessionHandle *data,
+ struct connectdata *conn)
+{
+ CURLMcode rc;
+
+ rc = curl_multi_add_handle(multi, data);
+ if(!rc) {
+ struct SingleRequest *k = &data->req;
+
+ /* pass in NULL for 'conn' here since we don't want to init the
+ connection, only this transfer */
+ Curl_init_do(data, NULL);
+
+ /* take this handle to the perform state right away */
+ multistate(data, CURLM_STATE_PERFORM);
+ data->easy_conn = conn;
+ k->keepon |= KEEP_RECV; /* setup to receive! */
+ }
+ return rc;
+}
+
+static CURLMcode multi_runsingle(struct Curl_multi *multi,
+ struct timeval now,
+ struct SessionHandle *data)
+{
+ struct Curl_message *msg = NULL;
+ bool connected;
+ bool async;
+ bool protocol_connect = FALSE;
+ bool dophase_done = FALSE;
+ bool done = FALSE;
+ CURLMcode rc;
+ CURLcode result = CURLE_OK;
+ struct SingleRequest *k;
+ long timeout_ms;
+ int control;
+
+ if(!GOOD_EASY_HANDLE(data))
+ return CURLM_BAD_EASY_HANDLE;
+
+ do {
+ bool disconnect_conn = FALSE;
+ rc = CURLM_OK;
+
+ /* Handle the case when the pipe breaks, i.e., the connection
+ we're using gets cleaned up and we're left with nothing. */
+ if(data->state.pipe_broke) {
+ infof(data, "Pipe broke: handle %p, url = %s\n",
+ (void *)data, data->state.path);
+
+ if(data->mstate < CURLM_STATE_COMPLETED) {
+ /* Head back to the CONNECT state */
+ multistate(data, CURLM_STATE_CONNECT);
+ rc = CURLM_CALL_MULTI_PERFORM;
+ result = CURLE_OK;
+ }
+
+ data->state.pipe_broke = FALSE;
+ data->easy_conn = NULL;
+ continue;
+ }
+
+ if(!data->easy_conn &&
+ data->mstate > CURLM_STATE_CONNECT &&
+ data->mstate < CURLM_STATE_DONE) {
+ /* In all these states, the code will blindly access 'data->easy_conn'
+ so this is precaution that it isn't NULL. And it silences static
+ analyzers. */
+ failf(data, "In state %d with no easy_conn, bail out!\n", data->mstate);
+ return CURLM_INTERNAL_ERROR;
+ }
+
+ if(multi_ischanged(multi, TRUE)) {
+ DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue!\n"));
+ Curl_multi_process_pending_handles(multi);
+ }
+
+ if(data->easy_conn && data->mstate > CURLM_STATE_CONNECT &&
+ data->mstate < CURLM_STATE_COMPLETED)
+ /* Make sure we set the connection's current owner */
+ data->easy_conn->data = data;
+
+ if(data->easy_conn &&
+ (data->mstate >= CURLM_STATE_CONNECT) &&
+ (data->mstate < CURLM_STATE_COMPLETED)) {
+ /* we need to wait for the connect state as only then is the start time
+ stored, but we must not check already completed handles */
+
+ timeout_ms = Curl_timeleft(data, &now,
+ (data->mstate <= CURLM_STATE_WAITDO)?
+ TRUE:FALSE);
+
+ if(timeout_ms < 0) {
+ /* Handle timed out */
+ if(data->mstate == CURLM_STATE_WAITRESOLVE)
+ failf(data, "Resolving timed out after %ld milliseconds",
+ Curl_tvdiff(now, data->progress.t_startsingle));
+ else if(data->mstate == CURLM_STATE_WAITCONNECT)
+ failf(data, "Connection timed out after %ld milliseconds",
+ Curl_tvdiff(now, data->progress.t_startsingle));
+ else {
+ k = &data->req;
+ if(k->size != -1) {
+ failf(data, "Operation timed out after %ld milliseconds with %"
+ CURL_FORMAT_CURL_OFF_T " out of %"
+ CURL_FORMAT_CURL_OFF_T " bytes received",
+ Curl_tvdiff(k->now, data->progress.t_startsingle),
+ k->bytecount, k->size);
+ }
+ else {
+ failf(data, "Operation timed out after %ld milliseconds with %"
+ CURL_FORMAT_CURL_OFF_T " bytes received",
+ Curl_tvdiff(now, data->progress.t_startsingle),
+ k->bytecount);
+ }
+ }
+
+ /* Force connection closed if the connection has indeed been used */
+ if(data->mstate > CURLM_STATE_DO) {
+ connclose(data->easy_conn, "Disconnected with pending data");
+ disconnect_conn = TRUE;
+ }
+ result = CURLE_OPERATION_TIMEDOUT;
+ (void)Curl_done(&data->easy_conn, result, TRUE);
+ /* Skip the statemachine and go directly to error handling section. */
+ goto statemachine_end;
+ }
+ }
+
+ switch(data->mstate) {
+ case CURLM_STATE_INIT:
+ /* init this transfer. */
+ result=Curl_pretransfer(data);
+
+ if(!result) {
+ /* after init, go CONNECT */
+ multistate(data, CURLM_STATE_CONNECT);
+ Curl_pgrsTime(data, TIMER_STARTOP);
+ rc = CURLM_CALL_MULTI_PERFORM;
+ }
+ break;
+
+ case CURLM_STATE_CONNECT_PEND:
+ /* We will stay here until there is a connection available. Then
+ we try again in the CURLM_STATE_CONNECT state. */
+ break;
+
+ case CURLM_STATE_CONNECT:
+ /* Connect. We want to get a connection identifier filled in. */
+ Curl_pgrsTime(data, TIMER_STARTSINGLE);
+ result = Curl_connect(data, &data->easy_conn,
+ &async, &protocol_connect);
+ if(CURLE_NO_CONNECTION_AVAILABLE == result) {
+ /* There was no connection available. We will go to the pending
+ state and wait for an available connection. */
+ multistate(data, CURLM_STATE_CONNECT_PEND);
+
+ /* add this handle to the list of connect-pending handles */
+ if(!Curl_llist_insert_next(multi->pending, multi->pending->tail, data))
+ result = CURLE_OUT_OF_MEMORY;
+ else
+ result = CURLE_OK;
+ break;
+ }
+
+ if(!result) {
+ /* Add this handle to the send or pend pipeline */
+ result = Curl_add_handle_to_pipeline(data, data->easy_conn);
+ if(result)
+ disconnect_conn = TRUE;
+ else {
+ if(async)
+ /* We're now waiting for an asynchronous name lookup */
+ multistate(data, CURLM_STATE_WAITRESOLVE);
+ else {
+ /* after the connect has been sent off, go WAITCONNECT unless the
+ protocol connect is already done and we can go directly to
+ WAITDO or DO! */
+ rc = CURLM_CALL_MULTI_PERFORM;
+
+ if(protocol_connect)
+ multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
+ CURLM_STATE_WAITDO:CURLM_STATE_DO);
+ else {
+#ifndef CURL_DISABLE_HTTP
+ if(data->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
+ multistate(data, CURLM_STATE_WAITPROXYCONNECT);
+ else
+#endif
+ multistate(data, CURLM_STATE_WAITCONNECT);
+ }
+ }
+ }
+ }
+ break;
+
+ case CURLM_STATE_WAITRESOLVE:
+ /* awaiting an asynch name resolve to complete */
+ {
+ struct Curl_dns_entry *dns = NULL;
+ struct connectdata *conn = data->easy_conn;
+
+ /* check if we have the name resolved by now */
+ dns = Curl_fetch_addr(conn, conn->host.name, (int)conn->port);
+
+ if(dns) {
+#ifdef CURLRES_ASYNCH
+ conn->async.dns = dns;
+ conn->async.done = TRUE;
+#endif
+ result = CURLE_OK;
+ infof(data, "Hostname was found in DNS cache\n");
+ }
+
+ if(!dns)
+ result = Curl_resolver_is_resolved(data->easy_conn, &dns);
+
+ /* Update sockets here, because the socket(s) may have been
+ closed and the application thus needs to be told, even if it
+ is likely that the same socket(s) will again be used further
+ down. If the name has not yet been resolved, it is likely
+ that new sockets have been opened in an attempt to contact
+ another resolver. */
+ singlesocket(multi, data);
+
+ if(dns) {
+ /* Perform the next step in the connection phase, and then move on
+ to the WAITCONNECT state */
+ result = Curl_async_resolved(data->easy_conn, &protocol_connect);
+
+ if(result)
+ /* if Curl_async_resolved() returns failure, the connection struct
+ is already freed and gone */
+ data->easy_conn = NULL; /* no more connection */
+ else {
+ /* call again please so that we get the next socket setup */
+ rc = CURLM_CALL_MULTI_PERFORM;
+ if(protocol_connect)
+ multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
+ CURLM_STATE_WAITDO:CURLM_STATE_DO);
+ else {
+#ifndef CURL_DISABLE_HTTP
+ if(data->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
+ multistate(data, CURLM_STATE_WAITPROXYCONNECT);
+ else
+#endif
+ multistate(data, CURLM_STATE_WAITCONNECT);
+ }
+ }
+ }
+
+ if(result) {
+ /* failure detected */
+ disconnect_conn = TRUE;
+ break;
+ }
+ }
+ break;
+
+#ifndef CURL_DISABLE_HTTP
+ case CURLM_STATE_WAITPROXYCONNECT:
+ /* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */
+ result = Curl_http_connect(data->easy_conn, &protocol_connect);
+
+ rc = CURLM_CALL_MULTI_PERFORM;
+ if(data->easy_conn->bits.proxy_connect_closed) {
+ /* connect back to proxy again */
+ result = CURLE_OK;
+ Curl_done(&data->easy_conn, CURLE_OK, FALSE);
+ multistate(data, CURLM_STATE_CONNECT);
+ }
+ else if(!result) {
+ if(data->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_COMPLETE)
+ /* initiate protocol connect phase */
+ multistate(data, CURLM_STATE_SENDPROTOCONNECT);
+ }
+ break;
+#endif
+
+ case CURLM_STATE_WAITCONNECT:
+ /* awaiting a completion of an asynch TCP connect */
+ result = Curl_is_connected(data->easy_conn, FIRSTSOCKET, &connected);
+ if(connected && !result) {
+ rc = CURLM_CALL_MULTI_PERFORM;
+ multistate(data, data->easy_conn->bits.tunnel_proxy?
+ CURLM_STATE_WAITPROXYCONNECT:
+ CURLM_STATE_SENDPROTOCONNECT);
+ }
+ else if(result) {
+ /* failure detected */
+ /* Just break, the cleaning up is handled all in one place */
+ disconnect_conn = TRUE;
+ break;
+ }
+ break;
+
+ case CURLM_STATE_SENDPROTOCONNECT:
+ result = Curl_protocol_connect(data->easy_conn, &protocol_connect);
+ if(!protocol_connect)
+ /* switch to waiting state */
+ multistate(data, CURLM_STATE_PROTOCONNECT);
+ else if(!result) {
+ /* protocol connect has completed, go WAITDO or DO */
+ multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
+ CURLM_STATE_WAITDO:CURLM_STATE_DO);
+ rc = CURLM_CALL_MULTI_PERFORM;
+ }
+ else if(result) {
+ /* failure detected */
+ Curl_posttransfer(data);
+ Curl_done(&data->easy_conn, result, TRUE);
+ disconnect_conn = TRUE;
+ }
+ break;
+
+ case CURLM_STATE_PROTOCONNECT:
+ /* protocol-specific connect phase */
+ result = Curl_protocol_connecting(data->easy_conn, &protocol_connect);
+ if(!result && protocol_connect) {
+ /* after the connect has completed, go WAITDO or DO */
+ multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
+ CURLM_STATE_WAITDO:CURLM_STATE_DO);
+ rc = CURLM_CALL_MULTI_PERFORM;
+ }
+ else if(result) {
+ /* failure detected */
+ Curl_posttransfer(data);
+ Curl_done(&data->easy_conn, result, TRUE);
+ disconnect_conn = TRUE;
+ }
+ break;
+
+ case CURLM_STATE_WAITDO:
+ /* Wait for our turn to DO when we're pipelining requests */
+ if(Curl_pipeline_checkget_write(data, data->easy_conn)) {
+ /* Grabbed the channel */
+ multistate(data, CURLM_STATE_DO);
+ rc = CURLM_CALL_MULTI_PERFORM;
+ }
+ break;
+
+ case CURLM_STATE_DO:
+ if(data->set.connect_only) {
+ /* keep connection open for application to use the socket */
+ connkeep(data->easy_conn, "CONNECT_ONLY");
+ multistate(data, CURLM_STATE_DONE);
+ result = CURLE_OK;
+ rc = CURLM_CALL_MULTI_PERFORM;
+ }
+ else {
+ /* Perform the protocol's DO action */
+ result = Curl_do(&data->easy_conn, &dophase_done);
+
+ /* When Curl_do() returns failure, data->easy_conn might be NULL! */
+
+ if(!result) {
+ if(!dophase_done) {
+ /* some steps needed for wildcard matching */
+ if(data->set.wildcardmatch) {
+ struct WildcardData *wc = &data->wildcard;
+ if(wc->state == CURLWC_DONE || wc->state == CURLWC_SKIP) {
+ /* skip some states if it is important */
+ Curl_done(&data->easy_conn, CURLE_OK, FALSE);
+ multistate(data, CURLM_STATE_DONE);
+ rc = CURLM_CALL_MULTI_PERFORM;
+ break;
+ }
+ }
+ /* DO was not completed in one function call, we must continue
+ DOING... */
+ multistate(data, CURLM_STATE_DOING);
+ rc = CURLM_OK;
+ }
+
+ /* after DO, go DO_DONE... or DO_MORE */
+ else if(data->easy_conn->bits.do_more) {
+ /* we're supposed to do more, but we need to sit down, relax
+ and wait a little while first */
+ multistate(data, CURLM_STATE_DO_MORE);
+ rc = CURLM_OK;
+ }
+ else {
+ /* we're done with the DO, now DO_DONE */
+ multistate(data, CURLM_STATE_DO_DONE);
+ rc = CURLM_CALL_MULTI_PERFORM;
+ }
+ }
+ else if((CURLE_SEND_ERROR == result) &&
+ data->easy_conn->bits.reuse) {
+ /*
+ * In this situation, a connection that we were trying to use
+ * may have unexpectedly died. If possible, send the connection
+ * back to the CONNECT phase so we can try again.
+ */
+ char *newurl = NULL;
+ followtype follow=FOLLOW_NONE;
+ CURLcode drc;
+ bool retry = FALSE;
+
+ drc = Curl_retry_request(data->easy_conn, &newurl);
+ if(drc) {
+ /* a failure here pretty much implies an out of memory */
+ result = drc;
+ disconnect_conn = TRUE;
+ }
+ else
+ retry = (newurl)?TRUE:FALSE;
+
+ Curl_posttransfer(data);
+ drc = Curl_done(&data->easy_conn, result, FALSE);
+
+ /* When set to retry the connection, we must to go back to
+ * the CONNECT state */
+ if(retry) {
+ if(!drc || (drc == CURLE_SEND_ERROR)) {
+ follow = FOLLOW_RETRY;
+ drc = Curl_follow(data, newurl, follow);
+ if(!drc) {
+ multistate(data, CURLM_STATE_CONNECT);
+ rc = CURLM_CALL_MULTI_PERFORM;
+ result = CURLE_OK;
+ }
+ else {
+ /* Follow failed */
+ result = drc;
+ free(newurl);
+ }
+ }
+ else {
+ /* done didn't return OK or SEND_ERROR */
+ result = drc;
+ free(newurl);
+ }
+ }
+ else {
+ /* Have error handler disconnect conn if we can't retry */
+ disconnect_conn = TRUE;
+ free(newurl);
+ }
+ }
+ else {
+ /* failure detected */
+ Curl_posttransfer(data);
+ if(data->easy_conn)
+ Curl_done(&data->easy_conn, result, FALSE);
+ disconnect_conn = TRUE;
+ }
+ }
+ break;
+
+ case CURLM_STATE_DOING:
+ /* we continue DOING until the DO phase is complete */
+ result = Curl_protocol_doing(data->easy_conn,
+ &dophase_done);
+ if(!result) {
+ if(dophase_done) {
+ /* after DO, go DO_DONE or DO_MORE */
+ multistate(data, data->easy_conn->bits.do_more?
+ CURLM_STATE_DO_MORE:
+ CURLM_STATE_DO_DONE);
+ rc = CURLM_CALL_MULTI_PERFORM;
+ } /* dophase_done */
+ }
+ else {
+ /* failure detected */
+ Curl_posttransfer(data);
+ Curl_done(&data->easy_conn, result, FALSE);
+ disconnect_conn = TRUE;
+ }
+ break;
+
+ case CURLM_STATE_DO_MORE:
+ /*
+ * When we are connected, DO MORE and then go DO_DONE
+ */
+ result = Curl_do_more(data->easy_conn, &control);
+
+ /* No need to remove this handle from the send pipeline here since that
+ is done in Curl_done() */
+ if(!result) {
+ if(control) {
+ /* if positive, advance to DO_DONE
+ if negative, go back to DOING */
+ multistate(data, control==1?
+ CURLM_STATE_DO_DONE:
+ CURLM_STATE_DOING);
+ rc = CURLM_CALL_MULTI_PERFORM;
+ }
+ else
+ /* stay in DO_MORE */
+ rc = CURLM_OK;
+ }
+ else {
+ /* failure detected */
+ Curl_posttransfer(data);
+ Curl_done(&data->easy_conn, result, FALSE);
+ disconnect_conn = TRUE;
+ }
+ break;
+
+ case CURLM_STATE_DO_DONE:
+ /* Move ourselves from the send to recv pipeline */
+ Curl_move_handle_from_send_to_recv_pipe(data, data->easy_conn);
+ /* Check if we can move pending requests to send pipe */
+ Curl_multi_process_pending_handles(multi);
+
+ /* Only perform the transfer if there's a good socket to work with.
+ Having both BAD is a signal to skip immediately to DONE */
+ if((data->easy_conn->sockfd != CURL_SOCKET_BAD) ||
+ (data->easy_conn->writesockfd != CURL_SOCKET_BAD))
+ multistate(data, CURLM_STATE_WAITPERFORM);
+ else
+ multistate(data, CURLM_STATE_DONE);
+ rc = CURLM_CALL_MULTI_PERFORM;
+ break;
+
+ case CURLM_STATE_WAITPERFORM:
+ /* Wait for our turn to PERFORM */
+ if(Curl_pipeline_checkget_read(data, data->easy_conn)) {
+ /* Grabbed the channel */
+ multistate(data, CURLM_STATE_PERFORM);
+ rc = CURLM_CALL_MULTI_PERFORM;
+ }
+ break;
+
+ case CURLM_STATE_TOOFAST: /* limit-rate exceeded in either direction */
+ /* if both rates are within spec, resume transfer */
+ if(Curl_pgrsUpdate(data->easy_conn))
+ result = CURLE_ABORTED_BY_CALLBACK;
+ else
+ result = Curl_speedcheck(data, now);
+
+ if(( (data->set.max_send_speed == 0) ||
+ (data->progress.ulspeed < data->set.max_send_speed )) &&
+ ( (data->set.max_recv_speed == 0) ||
+ (data->progress.dlspeed < data->set.max_recv_speed)))
+ multistate(data, CURLM_STATE_PERFORM);
+ break;
+
+ case CURLM_STATE_PERFORM:
+ {
+ char *newurl = NULL;
+ bool retry = FALSE;
+
+ /* check if over send speed */
+ if((data->set.max_send_speed > 0) &&
+ (data->progress.ulspeed > data->set.max_send_speed)) {
+ int buffersize;
+
+ multistate(data, CURLM_STATE_TOOFAST);
+
+ /* calculate upload rate-limitation timeout. */
+ buffersize = (int)(data->set.buffer_size ?
+ data->set.buffer_size : BUFSIZE);
+ timeout_ms = Curl_sleep_time(data->set.max_send_speed,
+ data->progress.ulspeed, buffersize);
+ Curl_expire_latest(data, timeout_ms);
+ break;
+ }
+
+ /* check if over recv speed */
+ if((data->set.max_recv_speed > 0) &&
+ (data->progress.dlspeed > data->set.max_recv_speed)) {
+ int buffersize;
+
+ multistate(data, CURLM_STATE_TOOFAST);
+
+ /* Calculate download rate-limitation timeout. */
+ buffersize = (int)(data->set.buffer_size ?
+ data->set.buffer_size : BUFSIZE);
+ timeout_ms = Curl_sleep_time(data->set.max_recv_speed,
+ data->progress.dlspeed, buffersize);
+ Curl_expire_latest(data, timeout_ms);
+ break;
+ }
+
+ /* read/write data if it is ready to do so */
+ result = Curl_readwrite(data->easy_conn, data, &done);
+
+ k = &data->req;
+
+ if(!(k->keepon & KEEP_RECV))
+ /* We're done receiving */
+ Curl_pipeline_leave_read(data->easy_conn);
+
+ if(!(k->keepon & KEEP_SEND))
+ /* We're done sending */
+ Curl_pipeline_leave_write(data->easy_conn);
+
+ if(done || (result == CURLE_RECV_ERROR)) {
+ /* If CURLE_RECV_ERROR happens early enough, we assume it was a race
+ * condition and the server closed the re-used connection exactly when
+ * we wanted to use it, so figure out if that is indeed the case.
+ */
+ CURLcode ret = Curl_retry_request(data->easy_conn, &newurl);
+ if(!ret)
+ retry = (newurl)?TRUE:FALSE;
+
+ if(retry) {
+ /* if we are to retry, set the result to OK and consider the
+ request as done */
+ result = CURLE_OK;
+ done = TRUE;
+ }
+ }
+
+ if(result) {
+ /*
+ * The transfer phase returned error, we mark the connection to get
+ * closed to prevent being re-used. This is because we can't possibly
+ * know if the connection is in a good shape or not now. Unless it is
+ * a protocol which uses two "channels" like FTP, as then the error
+ * happened in the data connection.
+ */
+
+ if(!(data->easy_conn->handler->flags & PROTOPT_DUAL))
+ connclose(data->easy_conn, "Transfer returned error");
+
+ Curl_posttransfer(data);
+ Curl_done(&data->easy_conn, result, FALSE);
+ }
+ else if(done) {
+ followtype follow=FOLLOW_NONE;
+
+ /* call this even if the readwrite function returned error */
+ Curl_posttransfer(data);
+
+ /* we're no longer receiving */
+ Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe);
+
+ /* expire the new receiving pipeline head */
+ if(data->easy_conn->recv_pipe->head)
+ Curl_expire_latest(data->easy_conn->recv_pipe->head->ptr, 1);
+
+ /* Check if we can move pending requests to send pipe */
+ Curl_multi_process_pending_handles(multi);
+
+ /* When we follow redirects or is set to retry the connection, we must
+ to go back to the CONNECT state */
+ if(data->req.newurl || retry) {
+ if(!retry) {
+ /* if the URL is a follow-location and not just a retried request
+ then figure out the URL here */
+ free(newurl);
+ newurl = data->req.newurl;
+ data->req.newurl = NULL;
+ follow = FOLLOW_REDIR;
+ }
+ else
+ follow = FOLLOW_RETRY;
+ result = Curl_done(&data->easy_conn, CURLE_OK, FALSE);
+ if(!result) {
+ result = Curl_follow(data, newurl, follow);
+ if(!result) {
+ multistate(data, CURLM_STATE_CONNECT);
+ rc = CURLM_CALL_MULTI_PERFORM;
+ newurl = NULL; /* handed over the memory ownership to
+ Curl_follow(), make sure we don't free() it
+ here */
+ }
+ }
+ }
+ else {
+ /* after the transfer is done, go DONE */
+
+ /* but first check to see if we got a location info even though we're
+ not following redirects */
+ if(data->req.location) {
+ free(newurl);
+ newurl = data->req.location;
+ data->req.location = NULL;
+ result = Curl_follow(data, newurl, FOLLOW_FAKE);
+ if(!result)
+ newurl = NULL; /* allocation was handed over Curl_follow() */
+ else
+ disconnect_conn = TRUE;
+ }
+
+ multistate(data, CURLM_STATE_DONE);
+ rc = CURLM_CALL_MULTI_PERFORM;
+ }
+ }
+
+ free(newurl);
+ break;
+ }
+
+ case CURLM_STATE_DONE:
+ /* this state is highly transient, so run another loop after this */
+ rc = CURLM_CALL_MULTI_PERFORM;
+
+ if(data->easy_conn) {
+ CURLcode res;
+
+ /* Remove ourselves from the receive pipeline, if we are there. */
+ Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe);
+ /* Check if we can move pending requests to send pipe */
+ Curl_multi_process_pending_handles(multi);
+
+ /* post-transfer command */
+ res = Curl_done(&data->easy_conn, result, FALSE);
+
+ /* allow a previously set error code take precedence */
+ if(!result)
+ result = res;
+
+ /*
+ * If there are other handles on the pipeline, Curl_done won't set
+ * easy_conn to NULL. In such a case, curl_multi_remove_handle() can
+ * access free'd data, if the connection is free'd and the handle
+ * removed before we perform the processing in CURLM_STATE_COMPLETED
+ */
+ if(data->easy_conn)
+ data->easy_conn = NULL;
+ }
+
+ if(data->set.wildcardmatch) {
+ if(data->wildcard.state != CURLWC_DONE) {
+ /* if a wildcard is set and we are not ending -> lets start again
+ with CURLM_STATE_INIT */
+ multistate(data, CURLM_STATE_INIT);
+ break;
+ }
+ }
+
+ /* after we have DONE what we're supposed to do, go COMPLETED, and
+ it doesn't matter what the Curl_done() returned! */
+ multistate(data, CURLM_STATE_COMPLETED);
+ break;
+
+ case CURLM_STATE_COMPLETED:
+ /* this is a completed transfer, it is likely to still be connected */
+
+ /* This node should be delinked from the list now and we should post
+ an information message that we are complete. */
+
+ /* Important: reset the conn pointer so that we don't point to memory
+ that could be freed anytime */
+ data->easy_conn = NULL;
+
+ Curl_expire(data, 0); /* stop all timers */
+ break;
+
+ case CURLM_STATE_MSGSENT:
+ data->result = result;
+ return CURLM_OK; /* do nothing */
+
+ default:
+ return CURLM_INTERNAL_ERROR;
+ }
+ statemachine_end:
+
+ if(data->mstate < CURLM_STATE_COMPLETED) {
+ if(result) {
+ /*
+ * If an error was returned, and we aren't in completed state now,
+ * then we go to completed and consider this transfer aborted.
+ */
+
+ /* NOTE: no attempt to disconnect connections must be made
+ in the case blocks above - cleanup happens only here */
+
+ data->state.pipe_broke = FALSE;
+
+ /* Check if we can move pending requests to send pipe */
+ Curl_multi_process_pending_handles(multi);
+
+ if(data->easy_conn) {
+ /* if this has a connection, unsubscribe from the pipelines */
+ Curl_pipeline_leave_write(data->easy_conn);
+ Curl_pipeline_leave_read(data->easy_conn);
+ Curl_removeHandleFromPipeline(data, data->easy_conn->send_pipe);
+ Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe);
+
+ if(disconnect_conn) {
+ /* Don't attempt to send data over a connection that timed out */
+ bool dead_connection = result == CURLE_OPERATION_TIMEDOUT;
+ /* disconnect properly */
+ Curl_disconnect(data->easy_conn, dead_connection);
+
+ /* This is where we make sure that the easy_conn pointer is reset.
+ We don't have to do this in every case block above where a
+ failure is detected */
+ data->easy_conn = NULL;
+ }
+ }
+ else if(data->mstate == CURLM_STATE_CONNECT) {
+ /* Curl_connect() failed */
+ (void)Curl_posttransfer(data);
+ }
+
+ multistate(data, CURLM_STATE_COMPLETED);
+ }
+ /* if there's still a connection to use, call the progress function */
+ else if(data->easy_conn && Curl_pgrsUpdate(data->easy_conn)) {
+ /* aborted due to progress callback return code must close the
+ connection */
+ result = CURLE_ABORTED_BY_CALLBACK;
+ connclose(data->easy_conn, "Aborted by callback");
+
+ /* if not yet in DONE state, go there, otherwise COMPLETED */
+ multistate(data, (data->mstate < CURLM_STATE_DONE)?
+ CURLM_STATE_DONE: CURLM_STATE_COMPLETED);
+ rc = CURLM_CALL_MULTI_PERFORM;
+ }
+ }
+
+ if(CURLM_STATE_COMPLETED == data->mstate) {
+ /* now fill in the Curl_message with this info */
+ msg = &data->msg;
+
+ msg->extmsg.msg = CURLMSG_DONE;
+ msg->extmsg.easy_handle = data;
+ msg->extmsg.data.result = result;
+
+ rc = multi_addmsg(multi, msg);
+
+ multistate(data, CURLM_STATE_MSGSENT);
+ }
+ } while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE));
+
+ data->result = result;
+
+
+ return rc;
+}
+
+
+CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
+{
+ struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
+ struct SessionHandle *data;
+ CURLMcode returncode=CURLM_OK;
+ struct Curl_tree *t;
+ struct timeval now = Curl_tvnow();
+
+ if(!GOOD_MULTI_HANDLE(multi))
+ return CURLM_BAD_HANDLE;
+
+ data=multi->easyp;
+ while(data) {
+ CURLMcode result;
+ struct WildcardData *wc = &data->wildcard;
+ SIGPIPE_VARIABLE(pipe_st);
+
+ if(data->set.wildcardmatch) {
+ if(!wc->filelist) {
+ CURLcode ret = Curl_wildcard_init(wc); /* init wildcard structures */
+ if(ret)
+ return CURLM_OUT_OF_MEMORY;
+ }
+ }
+
+ sigpipe_ignore(data, &pipe_st);
+ result = multi_runsingle(multi, now, data);
+ sigpipe_restore(&pipe_st);
+
+ if(data->set.wildcardmatch) {
+ /* destruct wildcard structures if it is needed */
+ if(wc->state == CURLWC_DONE || result)
+ Curl_wildcard_dtor(wc);
+ }
+
+ if(result)
+ returncode = result;
+
+ data = data->next; /* operate on next handle */
+ }
+
+ /*
+ * Simply remove all expired timers from the splay since handles are dealt
+ * with unconditionally by this function and curl_multi_timeout() requires
+ * that already passed/handled expire times are removed from the splay.
+ *
+ * It is important that the 'now' value is set at the entry of this function
+ * and not for the current time as it may have ticked a little while since
+ * then and then we risk this loop to remove timers that actually have not
+ * been handled!
+ */
+ do {
+ multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
+ if(t)
+ /* the removed may have another timeout in queue */
+ (void)add_next_timeout(now, multi, t->payload);
+
+ } while(t);
+
+ *running_handles = multi->num_alive;
+
+ if(CURLM_OK >= returncode)
+ update_timer(multi);
+
+ return returncode;
+}
+
+static void close_all_connections(struct Curl_multi *multi)
+{
+ struct connectdata *conn;
+
+ conn = Curl_conncache_find_first_connection(&multi->conn_cache);
+ while(conn) {
+ SIGPIPE_VARIABLE(pipe_st);
+ conn->data = multi->closure_handle;
+
+ sigpipe_ignore(conn->data, &pipe_st);
+ /* This will remove the connection from the cache */
+ (void)Curl_disconnect(conn, FALSE);
+ sigpipe_restore(&pipe_st);
+
+ conn = Curl_conncache_find_first_connection(&multi->conn_cache);
+ }
+}
+
+CURLMcode curl_multi_cleanup(CURLM *multi_handle)
+{
+ struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
+ struct SessionHandle *data;
+ struct SessionHandle *nextdata;
+
+ if(GOOD_MULTI_HANDLE(multi)) {
+ bool restore_pipe = FALSE;
+ SIGPIPE_VARIABLE(pipe_st);
+
+ multi->type = 0; /* not good anymore */
+
+ /* Close all the connections in the connection cache */
+ close_all_connections(multi);
+
+ if(multi->closure_handle) {
+ sigpipe_ignore(multi->closure_handle, &pipe_st);
+ restore_pipe = TRUE;
+
+ multi->closure_handle->dns.hostcache = &multi->hostcache;
+ Curl_hostcache_clean(multi->closure_handle,
+ multi->closure_handle->dns.hostcache);
+
+ Curl_close(multi->closure_handle);
+ }
+
+ Curl_hash_destroy(&multi->sockhash);
+ Curl_conncache_destroy(&multi->conn_cache);
+ Curl_llist_destroy(multi->msglist, NULL);
+ Curl_llist_destroy(multi->pending, NULL);
+
+ /* remove all easy handles */
+ data = multi->easyp;
+ while(data) {
+ nextdata=data->next;
+ if(data->dns.hostcachetype == HCACHE_MULTI) {
+ /* clear out the usage of the shared DNS cache */
+ Curl_hostcache_clean(data, data->dns.hostcache);
+ data->dns.hostcache = NULL;
+ data->dns.hostcachetype = HCACHE_NONE;
+ }
+
+ /* Clear the pointer to the connection cache */
+ data->state.conn_cache = NULL;
+ data->multi = NULL; /* clear the association */
+
+ data = nextdata;
+ }
+
+ Curl_hash_destroy(&multi->hostcache);
+
+ /* Free the blacklists by setting them to NULL */
+ Curl_pipeline_set_site_blacklist(NULL, &multi->pipelining_site_bl);
+ Curl_pipeline_set_server_blacklist(NULL, &multi->pipelining_server_bl);
+
+ free(multi);
+ if(restore_pipe)
+ sigpipe_restore(&pipe_st);
+
+ return CURLM_OK;
+ }
+ else
+ return CURLM_BAD_HANDLE;
+}
+
+/*
+ * curl_multi_info_read()
+ *
+ * This function is the primary way for a multi/multi_socket application to
+ * figure out if a transfer has ended. We MUST make this function as fast as
+ * possible as it will be polled frequently and we MUST NOT scan any lists in
+ * here to figure out things. We must scale fine to thousands of handles and
+ * beyond. The current design is fully O(1).
+ */
+
+CURLMsg *curl_multi_info_read(CURLM *multi_handle, int *msgs_in_queue)
+{
+ struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
+ struct Curl_message *msg;
+
+ *msgs_in_queue = 0; /* default to none */
+
+ if(GOOD_MULTI_HANDLE(multi) && Curl_llist_count(multi->msglist)) {
+ /* there is one or more messages in the list */
+ struct curl_llist_element *e;
+
+ /* extract the head of the list to return */
+ e = multi->msglist->head;
+
+ msg = e->ptr;
+
+ /* remove the extracted entry */
+ Curl_llist_remove(multi->msglist, e, NULL);
+
+ *msgs_in_queue = curlx_uztosi(Curl_llist_count(multi->msglist));
+
+ return &msg->extmsg;
+ }
+ else
+ return NULL;
+}
+
+/*
+ * singlesocket() checks what sockets we deal with and their "action state"
+ * and if we have a different state in any of those sockets from last time we
+ * call the callback accordingly.
+ */
+static void singlesocket(struct Curl_multi *multi,
+ struct SessionHandle *data)
+{
+ curl_socket_t socks[MAX_SOCKSPEREASYHANDLE];
+ int i;
+ struct Curl_sh_entry *entry;
+ curl_socket_t s;
+ int num;
+ unsigned int curraction;
+ bool remove_sock_from_hash;
+
+ for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++)
+ socks[i] = CURL_SOCKET_BAD;
+
+ /* Fill in the 'current' struct with the state as it is now: what sockets to
+ supervise and for what actions */
+ curraction = multi_getsock(data, socks, MAX_SOCKSPEREASYHANDLE);
+
+ /* We have 0 .. N sockets already and we get to know about the 0 .. M
+ sockets we should have from now on. Detect the differences, remove no
+ longer supervised ones and add new ones */
+
+ /* walk over the sockets we got right now */
+ for(i=0; (i< MAX_SOCKSPEREASYHANDLE) &&
+ (curraction & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i)));
+ i++) {
+ int action = CURL_POLL_NONE;
+
+ s = socks[i];
+
+ /* get it from the hash */
+ entry = Curl_hash_pick(&multi->sockhash, (char *)&s, sizeof(s));
+
+ if(curraction & GETSOCK_READSOCK(i))
+ action |= CURL_POLL_IN;
+ if(curraction & GETSOCK_WRITESOCK(i))
+ action |= CURL_POLL_OUT;
+
+ if(entry) {
+ /* yeps, already present so check if it has the same action set */
+ if(entry->action == action)
+ /* same, continue */
+ continue;
+ }
+ else {
+ /* this is a socket we didn't have before, add it! */
+ entry = sh_addentry(&multi->sockhash, s, data);
+ if(!entry)
+ /* fatal */
+ return;
+ }
+
+ /* we know (entry != NULL) at this point, see the logic above */
+ if(multi->socket_cb)
+ multi->socket_cb(data,
+ s,
+ action,
+ multi->socket_userp,
+ entry->socketp);
+
+ entry->action = action; /* store the current action state */
+ }
+
+ num = i; /* number of sockets */
+
+ /* when we've walked over all the sockets we should have right now, we must
+ make sure to detect sockets that are removed */
+ for(i=0; i< data->numsocks; i++) {
+ int j;
+ s = data->sockets[i];
+ for(j=0; j<num; j++) {
+ if(s == socks[j]) {
+ /* this is still supervised */
+ s = CURL_SOCKET_BAD;
+ break;
+ }
+ }
+ if(s != CURL_SOCKET_BAD) {
+
+ /* this socket has been removed. Tell the app to remove it */
+ remove_sock_from_hash = TRUE;
+
+ entry = Curl_hash_pick(&multi->sockhash, (char *)&s, sizeof(s));
+ if(entry) {
+ /* check if the socket to be removed serves a connection which has
+ other easy-s in a pipeline. In this case the socket should not be
+ removed. */
+ struct connectdata *easy_conn = data->easy_conn;
+ if(easy_conn) {
+ if(easy_conn->recv_pipe && easy_conn->recv_pipe->size > 1) {
+ /* the handle should not be removed from the pipe yet */
+ remove_sock_from_hash = FALSE;
+
+ /* Update the sockhash entry to instead point to the next in line
+ for the recv_pipe, or the first (in case this particular easy
+ isn't already) */
+ if(entry->easy == data) {
+ if(Curl_recvpipe_head(data, easy_conn))
+ entry->easy = easy_conn->recv_pipe->head->next->ptr;
+ else
+ entry->easy = easy_conn->recv_pipe->head->ptr;
+ }
+ }
+ if(easy_conn->send_pipe && easy_conn->send_pipe->size > 1) {
+ /* the handle should not be removed from the pipe yet */
+ remove_sock_from_hash = FALSE;
+
+ /* Update the sockhash entry to instead point to the next in line
+ for the send_pipe, or the first (in case this particular easy
+ isn't already) */
+ if(entry->easy == data) {
+ if(Curl_sendpipe_head(data, easy_conn))
+ entry->easy = easy_conn->send_pipe->head->next->ptr;
+ else
+ entry->easy = easy_conn->send_pipe->head->ptr;
+ }
+ }
+ /* Don't worry about overwriting recv_pipe head with send_pipe_head,
+ when action will be asked on the socket (see multi_socket()), the
+ head of the correct pipe will be taken according to the
+ action. */
+ }
+ }
+ else
+ /* just a precaution, this socket really SHOULD be in the hash already
+ but in case it isn't, we don't have to tell the app to remove it
+ either since it never got to know about it */
+ remove_sock_from_hash = FALSE;
+
+ if(remove_sock_from_hash) {
+ /* in this case 'entry' is always non-NULL */
+ if(multi->socket_cb)
+ multi->socket_cb(data,
+ s,
+ CURL_POLL_REMOVE,
+ multi->socket_userp,
+ entry->socketp);
+ sh_delentry(&multi->sockhash, s);
+ }
+
+ }
+ }
+
+ memcpy(data->sockets, socks, num*sizeof(curl_socket_t));
+ data->numsocks = num;
+}
+
+/*
+ * Curl_multi_closed()
+ *
+ * Used by the connect code to tell the multi_socket code that one of the
+ * sockets we were using is about to be closed. This function will then
+ * remove it from the sockethash for this handle to make the multi_socket API
+ * behave properly, especially for the case when libcurl will create another
+ * socket again and it gets the same file descriptor number.
+ */
+
+void Curl_multi_closed(struct connectdata *conn, curl_socket_t s)
+{
+ struct Curl_multi *multi = conn->data->multi;
+ if(multi) {
+ /* this is set if this connection is part of a handle that is added to
+ a multi handle, and only then this is necessary */
+ struct Curl_sh_entry *entry =
+ Curl_hash_pick(&multi->sockhash, (char *)&s, sizeof(s));
+
+ if(entry) {
+ if(multi->socket_cb)
+ multi->socket_cb(conn->data, s, CURL_POLL_REMOVE,
+ multi->socket_userp,
+ entry->socketp);
+
+ /* now remove it from the socket hash */
+ sh_delentry(&multi->sockhash, s);
+ }
+ }
+}
+
+
+
+/*
+ * add_next_timeout()
+ *
+ * Each SessionHandle has a list of timeouts. The add_next_timeout() is called
+ * when it has just been removed from the splay tree because the timeout has
+ * expired. This function is then to advance in the list to pick the next
+ * timeout to use (skip the already expired ones) and add this node back to
+ * the splay tree again.
+ *
+ * The splay tree only has each sessionhandle as a single node and the nearest
+ * timeout is used to sort it on.
+ */
+static CURLMcode add_next_timeout(struct timeval now,
+ struct Curl_multi *multi,
+ struct SessionHandle *d)
+{
+ struct timeval *tv = &d->state.expiretime;
+ struct curl_llist *list = d->state.timeoutlist;
+ struct curl_llist_element *e;
+
+ /* move over the timeout list for this specific handle and remove all
+ timeouts that are now passed tense and store the next pending
+ timeout in *tv */
+ for(e = list->head; e; ) {
+ struct curl_llist_element *n = e->next;
+ long diff = curlx_tvdiff(*(struct timeval *)e->ptr, now);
+ if(diff <= 0)
+ /* remove outdated entry */
+ Curl_llist_remove(list, e, NULL);
+ else
+ /* the list is sorted so get out on the first mismatch */
+ break;
+ e = n;
+ }
+ e = list->head;
+ if(!e) {
+ /* clear the expire times within the handles that we remove from the
+ splay tree */
+ tv->tv_sec = 0;
+ tv->tv_usec = 0;
+ }
+ else {
+ /* copy the first entry to 'tv' */
+ memcpy(tv, e->ptr, sizeof(*tv));
+
+ /* remove first entry from list */
+ Curl_llist_remove(list, e, NULL);
+
+ /* insert this node again into the splay */
+ multi->timetree = Curl_splayinsert(*tv, multi->timetree,
+ &d->state.timenode);
+ }
+ return CURLM_OK;
+}
+
+static CURLMcode multi_socket(struct Curl_multi *multi,
+ bool checkall,
+ curl_socket_t s,
+ int ev_bitmask,
+ int *running_handles)
+{
+ CURLMcode result = CURLM_OK;
+ struct SessionHandle *data = NULL;
+ struct Curl_tree *t;
+ struct timeval now = Curl_tvnow();
+
+ if(checkall) {
+ /* *perform() deals with running_handles on its own */
+ result = curl_multi_perform(multi, running_handles);
+
+ /* walk through each easy handle and do the socket state change magic
+ and callbacks */
+ if(result != CURLM_BAD_HANDLE) {
+ data=multi->easyp;
+ while(data) {
+ singlesocket(multi, data);
+ data = data->next;
+ }
+ }
+
+ /* or should we fall-through and do the timer-based stuff? */
+ return result;
+ }
+ else if(s != CURL_SOCKET_TIMEOUT) {
+
+ struct Curl_sh_entry *entry =
+ Curl_hash_pick(&multi->sockhash, (char *)&s, sizeof(s));
+
+ if(!entry)
+ /* Unmatched socket, we can't act on it but we ignore this fact. In
+ real-world tests it has been proved that libevent can in fact give
+ the application actions even though the socket was just previously
+ asked to get removed, so thus we better survive stray socket actions
+ and just move on. */
+ ;
+ else {
+ SIGPIPE_VARIABLE(pipe_st);
+
+ data = entry->easy;
+
+ if(data->magic != CURLEASY_MAGIC_NUMBER)
+ /* bad bad bad bad bad bad bad */
+ return CURLM_INTERNAL_ERROR;
+
+ /* If the pipeline is enabled, take the handle which is in the head of
+ the pipeline. If we should write into the socket, take the send_pipe
+ head. If we should read from the socket, take the recv_pipe head. */
+ if(data->easy_conn) {
+ if((ev_bitmask & CURL_POLL_OUT) &&
+ data->easy_conn->send_pipe &&
+ data->easy_conn->send_pipe->head)
+ data = data->easy_conn->send_pipe->head->ptr;
+ else if((ev_bitmask & CURL_POLL_IN) &&
+ data->easy_conn->recv_pipe &&
+ data->easy_conn->recv_pipe->head)
+ data = data->easy_conn->recv_pipe->head->ptr;
+ }
+
+ if(data->easy_conn &&
+ !(data->easy_conn->handler->flags & PROTOPT_DIRLOCK))
+ /* set socket event bitmask if they're not locked */
+ data->easy_conn->cselect_bits = ev_bitmask;
+
+ sigpipe_ignore(data, &pipe_st);
+ result = multi_runsingle(multi, now, data);
+ sigpipe_restore(&pipe_st);
+
+ if(data->easy_conn &&
+ !(data->easy_conn->handler->flags & PROTOPT_DIRLOCK))
+ /* clear the bitmask only if not locked */
+ data->easy_conn->cselect_bits = 0;
+
+ if(CURLM_OK >= result)
+ /* get the socket(s) and check if the state has been changed since
+ last */
+ singlesocket(multi, data);
+
+ /* Now we fall-through and do the timer-based stuff, since we don't want
+ to force the user to have to deal with timeouts as long as at least
+ one connection in fact has traffic. */
+
+ data = NULL; /* set data to NULL again to avoid calling
+ multi_runsingle() in case there's no need to */
+ now = Curl_tvnow(); /* get a newer time since the multi_runsingle() loop
+ may have taken some time */
+ }
+ }
+ else {
+ /* Asked to run due to time-out. Clear the 'lastcall' variable to force
+ update_timer() to trigger a callback to the app again even if the same
+ timeout is still the one to run after this call. That handles the case
+ when the application asks libcurl to run the timeout prematurely. */
+ memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
+ }
+
+ /*
+ * The loop following here will go on as long as there are expire-times left
+ * to process in the splay and 'data' will be re-assigned for every expired
+ * handle we deal with.
+ */
+ do {
+ /* the first loop lap 'data' can be NULL */
+ if(data) {
+ SIGPIPE_VARIABLE(pipe_st);
+
+ sigpipe_ignore(data, &pipe_st);
+ result = multi_runsingle(multi, now, data);
+ sigpipe_restore(&pipe_st);
+
+ if(CURLM_OK >= result)
+ /* get the socket(s) and check if the state has been changed since
+ last */
+ singlesocket(multi, data);
+ }
+
+ /* Check if there's one (more) expired timer to deal with! This function
+ extracts a matching node if there is one */
+
+ multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
+ if(t) {
+ data = t->payload; /* assign this for next loop */
+ (void)add_next_timeout(now, multi, t->payload);
+ }
+
+ } while(t);
+
+ *running_handles = multi->num_alive;
+ return result;
+}
+
+#undef curl_multi_setopt
+CURLMcode curl_multi_setopt(CURLM *multi_handle,
+ CURLMoption option, ...)
+{
+ struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
+ CURLMcode res = CURLM_OK;
+ va_list param;
+
+ if(!GOOD_MULTI_HANDLE(multi))
+ return CURLM_BAD_HANDLE;
+
+ va_start(param, option);
+
+ switch(option) {
+ case CURLMOPT_SOCKETFUNCTION:
+ multi->socket_cb = va_arg(param, curl_socket_callback);
+ break;
+ case CURLMOPT_SOCKETDATA:
+ multi->socket_userp = va_arg(param, void *);
+ break;
+ case CURLMOPT_PUSHFUNCTION:
+ multi->push_cb = va_arg(param, curl_push_callback);
+ break;
+ case CURLMOPT_PUSHDATA:
+ multi->push_userp = va_arg(param, void *);
+ break;
+ case CURLMOPT_PIPELINING:
+ multi->pipelining = va_arg(param, long);
+ break;
+ case CURLMOPT_TIMERFUNCTION:
+ multi->timer_cb = va_arg(param, curl_multi_timer_callback);
+ break;
+ case CURLMOPT_TIMERDATA:
+ multi->timer_userp = va_arg(param, void *);
+ break;
+ case CURLMOPT_MAXCONNECTS:
+ multi->maxconnects = va_arg(param, long);
+ break;
+ case CURLMOPT_MAX_HOST_CONNECTIONS:
+ multi->max_host_connections = va_arg(param, long);
+ break;
+ case CURLMOPT_MAX_PIPELINE_LENGTH:
+ multi->max_pipeline_length = va_arg(param, long);
+ break;
+ case CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE:
+ multi->content_length_penalty_size = va_arg(param, long);
+ break;
+ case CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE:
+ multi->chunk_length_penalty_size = va_arg(param, long);
+ break;
+ case CURLMOPT_PIPELINING_SITE_BL:
+ res = Curl_pipeline_set_site_blacklist(va_arg(param, char **),
+ &multi->pipelining_site_bl);
+ break;
+ case CURLMOPT_PIPELINING_SERVER_BL:
+ res = Curl_pipeline_set_server_blacklist(va_arg(param, char **),
+ &multi->pipelining_server_bl);
+ break;
+ case CURLMOPT_MAX_TOTAL_CONNECTIONS:
+ multi->max_total_connections = va_arg(param, long);
+ break;
+ default:
+ res = CURLM_UNKNOWN_OPTION;
+ break;
+ }
+ va_end(param);
+ return res;
+}
+
+/* we define curl_multi_socket() in the public multi.h header */
+#undef curl_multi_socket
+
+CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
+ int *running_handles)
+{
+ CURLMcode result = multi_socket((struct Curl_multi *)multi_handle, FALSE, s,
+ 0, running_handles);
+ if(CURLM_OK >= result)
+ update_timer((struct Curl_multi *)multi_handle);
+ return result;
+}
+
+CURLMcode curl_multi_socket_action(CURLM *multi_handle, curl_socket_t s,
+ int ev_bitmask, int *running_handles)
+{
+ CURLMcode result = multi_socket((struct Curl_multi *)multi_handle, FALSE, s,
+ ev_bitmask, running_handles);
+ if(CURLM_OK >= result)
+ update_timer((struct Curl_multi *)multi_handle);
+ return result;
+}
+
+CURLMcode curl_multi_socket_all(CURLM *multi_handle, int *running_handles)
+
+{
+ CURLMcode result = multi_socket((struct Curl_multi *)multi_handle,
+ TRUE, CURL_SOCKET_BAD, 0, running_handles);
+ if(CURLM_OK >= result)
+ update_timer((struct Curl_multi *)multi_handle);
+ return result;
+}
+
+static CURLMcode multi_timeout(struct Curl_multi *multi,
+ long *timeout_ms)
+{
+ static struct timeval tv_zero = {0, 0};
+
+ if(multi->timetree) {
+ /* we have a tree of expire times */
+ struct timeval now = Curl_tvnow();
+
+ /* splay the lowest to the bottom */
+ multi->timetree = Curl_splay(tv_zero, multi->timetree);
+
+ if(Curl_splaycomparekeys(multi->timetree->key, now) > 0) {
+ /* some time left before expiration */
+ *timeout_ms = curlx_tvdiff(multi->timetree->key, now);
+ if(!*timeout_ms)
+ /*
+ * Since we only provide millisecond resolution on the returned value
+ * and the diff might be less than one millisecond here, we don't
+ * return zero as that may cause short bursts of busyloops on fast
+ * processors while the diff is still present but less than one
+ * millisecond! instead we return 1 until the time is ripe.
+ */
+ *timeout_ms=1;
+ }
+ else
+ /* 0 means immediately */
+ *timeout_ms = 0;
+ }
+ else
+ *timeout_ms = -1;
+
+ return CURLM_OK;
+}
+
+CURLMcode curl_multi_timeout(CURLM *multi_handle,
+ long *timeout_ms)
+{
+ struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
+
+ /* First, make some basic checks that the CURLM handle is a good handle */
+ if(!GOOD_MULTI_HANDLE(multi))
+ return CURLM_BAD_HANDLE;
+
+ return multi_timeout(multi, timeout_ms);
+}
+
+/*
+ * Tell the application it should update its timers, if it subscribes to the
+ * update timer callback.
+ */
+static int update_timer(struct Curl_multi *multi)
+{
+ long timeout_ms;
+
+ if(!multi->timer_cb)
+ return 0;
+ if(multi_timeout(multi, &timeout_ms)) {
+ return -1;
+ }
+ if(timeout_ms < 0) {
+ static const struct timeval none={0, 0};
+ if(Curl_splaycomparekeys(none, multi->timer_lastcall)) {
+ multi->timer_lastcall = none;
+ /* there's no timeout now but there was one previously, tell the app to
+ disable it */
+ return multi->timer_cb((CURLM*)multi, -1, multi->timer_userp);
+ }
+ return 0;
+ }
+
+ /* When multi_timeout() is done, multi->timetree points to the node with the
+ * timeout we got the (relative) time-out time for. We can thus easily check
+ * if this is the same (fixed) time as we got in a previous call and then
+ * avoid calling the callback again. */
+ if(Curl_splaycomparekeys(multi->timetree->key, multi->timer_lastcall) == 0)
+ return 0;
+
+ multi->timer_lastcall = multi->timetree->key;
+
+ return multi->timer_cb((CURLM*)multi, timeout_ms, multi->timer_userp);
+}
+
+/*
+ * multi_freetimeout()
+ *
+ * Callback used by the llist system when a single timeout list entry is
+ * destroyed.
+ */
+static void multi_freetimeout(void *user, void *entryptr)
+{
+ (void)user;
+
+ /* the entry was plain malloc()'ed */
+ free(entryptr);
+}
+
+/*
+ * multi_addtimeout()
+ *
+ * Add a timestamp to the list of timeouts. Keep the list sorted so that head
+ * of list is always the timeout nearest in time.
+ *
+ */
+static CURLMcode
+multi_addtimeout(struct curl_llist *timeoutlist,
+ struct timeval *stamp)
+{
+ struct curl_llist_element *e;
+ struct timeval *timedup;
+ struct curl_llist_element *prev = NULL;
+
+ timedup = malloc(sizeof(*timedup));
+ if(!timedup)
+ return CURLM_OUT_OF_MEMORY;
+
+ /* copy the timestamp */
+ memcpy(timedup, stamp, sizeof(*timedup));
+
+ if(Curl_llist_count(timeoutlist)) {
+ /* find the correct spot in the list */
+ for(e = timeoutlist->head; e; e = e->next) {
+ struct timeval *checktime = e->ptr;
+ long diff = curlx_tvdiff(*checktime, *timedup);
+ if(diff > 0)
+ break;
+ prev = e;
+ }
+
+ }
+ /* else
+ this is the first timeout on the list */
+
+ if(!Curl_llist_insert_next(timeoutlist, prev, timedup)) {
+ free(timedup);
+ return CURLM_OUT_OF_MEMORY;
+ }
+
+ return CURLM_OK;
+}
+
+/*
+ * Curl_expire()
+ *
+ * given a number of milliseconds from now to use to set the 'act before
+ * this'-time for the transfer, to be extracted by curl_multi_timeout()
+ *
+ * Note that the timeout will be added to a queue of timeouts if it defines a
+ * moment in time that is later than the current head of queue.
+ *
+ * Pass zero to clear all timeout values for this handle.
+*/
+void Curl_expire(struct SessionHandle *data, long milli)
+{
+ struct Curl_multi *multi = data->multi;
+ struct timeval *nowp = &data->state.expiretime;
+ int rc;
+
+ /* this is only interesting while there is still an associated multi struct
+ remaining! */
+ if(!multi)
+ return;
+
+ if(!milli) {
+ /* No timeout, clear the time data. */
+ if(nowp->tv_sec || nowp->tv_usec) {
+ /* Since this is an cleared time, we must remove the previous entry from
+ the splay tree */
+ struct curl_llist *list = data->state.timeoutlist;
+
+ rc = Curl_splayremovebyaddr(multi->timetree,
+ &data->state.timenode,
+ &multi->timetree);
+ if(rc)
+ infof(data, "Internal error clearing splay node = %d\n", rc);
+
+ /* flush the timeout list too */
+ while(list->size > 0)
+ Curl_llist_remove(list, list->tail, NULL);
+
+#ifdef DEBUGBUILD
+ infof(data, "Expire cleared\n");
+#endif
+ nowp->tv_sec = 0;
+ nowp->tv_usec = 0;
+ }
+ }
+ else {
+ struct timeval set;
+
+ set = Curl_tvnow();
+ set.tv_sec += milli/1000;
+ set.tv_usec += (milli%1000)*1000;
+
+ if(set.tv_usec >= 1000000) {
+ set.tv_sec++;
+ set.tv_usec -= 1000000;
+ }
+
+ if(nowp->tv_sec || nowp->tv_usec) {
+ /* This means that the struct is added as a node in the splay tree.
+ Compare if the new time is earlier, and only remove-old/add-new if it
+ is. */
+ long diff = curlx_tvdiff(set, *nowp);
+ if(diff > 0) {
+ /* the new expire time was later so just add it to the queue
+ and get out */
+ multi_addtimeout(data->state.timeoutlist, &set);
+ return;
+ }
+
+ /* the new time is newer than the presently set one, so add the current
+ to the queue and update the head */
+ multi_addtimeout(data->state.timeoutlist, nowp);
+
+ /* Since this is an updated time, we must remove the previous entry from
+ the splay tree first and then re-add the new value */
+ rc = Curl_splayremovebyaddr(multi->timetree,
+ &data->state.timenode,
+ &multi->timetree);
+ if(rc)
+ infof(data, "Internal error removing splay node = %d\n", rc);
+ }
+
+ *nowp = set;
+ data->state.timenode.payload = data;
+ multi->timetree = Curl_splayinsert(*nowp,
+ multi->timetree,
+ &data->state.timenode);
+ }
+#if 0
+ Curl_splayprint(multi->timetree, 0, TRUE);
+#endif
+}
+
+/*
+ * Curl_expire_latest()
+ *
+ * This is like Curl_expire() but will only add a timeout node to the list of
+ * timers if there is no timeout that will expire before the given time.
+ *
+ * Use this function if the code logic risks calling this function many times
+ * or if there's no particular conditional wait in the code for this specific
+ * time-out period to expire.
+ *
+ */
+void Curl_expire_latest(struct SessionHandle *data, long milli)
+{
+ struct timeval *expire = &data->state.expiretime;
+
+ struct timeval set;
+
+ set = Curl_tvnow();
+ set.tv_sec += milli / 1000;
+ set.tv_usec += (milli % 1000) * 1000;
+
+ if(set.tv_usec >= 1000000) {
+ set.tv_sec++;
+ set.tv_usec -= 1000000;
+ }
+
+ if(expire->tv_sec || expire->tv_usec) {
+ /* This means that the struct is added as a node in the splay tree.
+ Compare if the new time is earlier, and only remove-old/add-new if it
+ is. */
+ long diff = curlx_tvdiff(set, *expire);
+ if(diff > 0)
+ /* the new expire time was later than the top time, so just skip this */
+ return;
+ }
+
+ /* Just add the timeout like normal */
+ Curl_expire(data, milli);
+}
+
+CURLMcode curl_multi_assign(CURLM *multi_handle,
+ curl_socket_t s, void *hashp)
+{
+ struct Curl_sh_entry *there = NULL;
+ struct Curl_multi *multi = (struct Curl_multi *)multi_handle;
+
+ if(s != CURL_SOCKET_BAD)
+ there = Curl_hash_pick(&multi->sockhash, (char *)&s,
+ sizeof(curl_socket_t));
+
+ if(!there)
+ return CURLM_BAD_SOCKET;
+
+ there->socketp = hashp;
+
+ return CURLM_OK;
+}
+
+size_t Curl_multi_max_host_connections(struct Curl_multi *multi)
+{
+ return multi ? multi->max_host_connections : 0;
+}
+
+size_t Curl_multi_max_total_connections(struct Curl_multi *multi)
+{
+ return multi ? multi->max_total_connections : 0;
+}
+
+curl_off_t Curl_multi_content_length_penalty_size(struct Curl_multi *multi)
+{
+ return multi ? multi->content_length_penalty_size : 0;
+}
+
+curl_off_t Curl_multi_chunk_length_penalty_size(struct Curl_multi *multi)
+{
+ return multi ? multi->chunk_length_penalty_size : 0;
+}
+
+struct curl_llist *Curl_multi_pipelining_site_bl(struct Curl_multi *multi)
+{
+ return multi->pipelining_site_bl;
+}
+
+struct curl_llist *Curl_multi_pipelining_server_bl(struct Curl_multi *multi)
+{
+ return multi->pipelining_server_bl;
+}
+
+void Curl_multi_process_pending_handles(struct Curl_multi *multi)
+{
+ struct curl_llist_element *e = multi->pending->head;
+
+ while(e) {
+ struct SessionHandle *data = e->ptr;
+ struct curl_llist_element *next = e->next;
+
+ if(data->mstate == CURLM_STATE_CONNECT_PEND) {
+ multistate(data, CURLM_STATE_CONNECT);
+
+ /* Remove this node from the list */
+ Curl_llist_remove(multi->pending, e, NULL);
+
+ /* Make sure that the handle will be processed soonish. */
+ Curl_expire_latest(data, 1);
+ }
+
+ e = next; /* operate on next handle */
+ }
+}
+
+#ifdef DEBUGBUILD
+void Curl_multi_dump(const struct Curl_multi *multi_handle)
+{
+ struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
+ struct SessionHandle *data;
+ int i;
+ fprintf(stderr, "* Multi status: %d handles, %d alive\n",
+ multi->num_easy, multi->num_alive);
+ for(data=multi->easyp; data; data = data->next) {
+ if(data->mstate < CURLM_STATE_COMPLETED) {
+ /* only display handles that are not completed */
+ fprintf(stderr, "handle %p, state %s, %d sockets\n",
+ (void *)data,
+ statename[data->mstate], data->numsocks);
+ for(i=0; i < data->numsocks; i++) {
+ curl_socket_t s = data->sockets[i];
+ struct Curl_sh_entry *entry =
+ Curl_hash_pick(&multi->sockhash, (char *)&s, sizeof(s));
+
+ fprintf(stderr, "%d ", (int)s);
+ if(!entry) {
+ fprintf(stderr, "INTERNAL CONFUSION\n");
+ continue;
+ }
+ fprintf(stderr, "[%s %s] ",
+ entry->action&CURL_POLL_IN?"RECVING":"",
+ entry->action&CURL_POLL_OUT?"SENDING":"");
+ }
+ if(data->numsocks)
+ fprintf(stderr, "\n");
+ }
+ }
+}
+#endif
diff --git a/Utilities/cmcurl/lib/multihandle.h b/Utilities/cmcurl/lib/multihandle.h
new file mode 100644
index 000000000..6c24f50f1
--- /dev/null
+++ b/Utilities/cmcurl/lib/multihandle.h
@@ -0,0 +1,152 @@
+#ifndef HEADER_CURL_MULTIHANDLE_H
+#define HEADER_CURL_MULTIHANDLE_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "conncache.h"
+
+struct Curl_message {
+ /* the 'CURLMsg' is the part that is visible to the external user */
+ struct CURLMsg extmsg;
+};
+
+/* NOTE: if you add a state here, add the name to the statename[] array as
+ well!
+*/
+typedef enum {
+ CURLM_STATE_INIT, /* 0 - start in this state */
+ CURLM_STATE_CONNECT_PEND, /* 1 - no connections, waiting for one */
+ CURLM_STATE_CONNECT, /* 2 - resolve/connect has been sent off */
+ CURLM_STATE_WAITRESOLVE, /* 3 - awaiting the resolve to finalize */
+ CURLM_STATE_WAITCONNECT, /* 4 - awaiting the TCP connect to finalize */
+ CURLM_STATE_WAITPROXYCONNECT, /* 5 - awaiting proxy CONNECT to finalize */
+ CURLM_STATE_SENDPROTOCONNECT, /* 6 - initiate protocol connect procedure */
+ CURLM_STATE_PROTOCONNECT, /* 7 - completing the protocol-specific connect
+ phase */
+ CURLM_STATE_WAITDO, /* 8 - wait for our turn to send the request */
+ CURLM_STATE_DO, /* 9 - start send off the request (part 1) */
+ CURLM_STATE_DOING, /* 10 - sending off the request (part 1) */
+ CURLM_STATE_DO_MORE, /* 11 - send off the request (part 2) */
+ CURLM_STATE_DO_DONE, /* 12 - done sending off request */
+ CURLM_STATE_WAITPERFORM, /* 13 - wait for our turn to read the response */
+ CURLM_STATE_PERFORM, /* 14 - transfer data */
+ CURLM_STATE_TOOFAST, /* 15 - wait because limit-rate exceeded */
+ CURLM_STATE_DONE, /* 16 - post data transfer operation */
+ CURLM_STATE_COMPLETED, /* 17 - operation complete */
+ CURLM_STATE_MSGSENT, /* 18 - the operation complete message is sent */
+ CURLM_STATE_LAST /* 19 - not a true state, never use this */
+} CURLMstate;
+
+/* we support N sockets per easy handle. Set the corresponding bit to what
+ action we should wait for */
+#define MAX_SOCKSPEREASYHANDLE 5
+#define GETSOCK_READABLE (0x00ff)
+#define GETSOCK_WRITABLE (0xff00)
+
+#define CURLPIPE_ANY (CURLPIPE_HTTP1 | CURLPIPE_MULTIPLEX)
+
+/* This is the struct known as CURLM on the outside */
+struct Curl_multi {
+ /* First a simple identifier to easier detect if a user mix up
+ this multi handle with an easy handle. Set this to CURL_MULTI_HANDLE. */
+ long type;
+
+ /* We have a doubly-linked circular list with easy handles */
+ struct SessionHandle *easyp;
+ struct SessionHandle *easylp; /* last node */
+
+ int num_easy; /* amount of entries in the linked list above. */
+ int num_alive; /* amount of easy handles that are added but have not yet
+ reached COMPLETE state */
+
+ struct curl_llist *msglist; /* a list of messages from completed transfers */
+
+ struct curl_llist *pending; /* SessionHandles that are in the
+ CURLM_STATE_CONNECT_PEND state */
+
+ /* callback function and user data pointer for the *socket() API */
+ curl_socket_callback socket_cb;
+ void *socket_userp;
+
+ /* callback function and user data pointer for server push */
+ curl_push_callback push_cb;
+ void *push_userp;
+
+ /* Hostname cache */
+ struct curl_hash hostcache;
+
+ /* timetree points to the splay-tree of time nodes to figure out expire
+ times of all currently set timers */
+ struct Curl_tree *timetree;
+
+ /* 'sockhash' is the lookup hash for socket descriptor => easy handles (note
+ the pluralis form, there can be more than one easy handle waiting on the
+ same actual socket) */
+ struct curl_hash sockhash;
+
+ /* pipelining wanted bits (CURLPIPE*) */
+ long pipelining;
+
+ bool recheckstate; /* see Curl_multi_connchanged */
+
+ /* Shared connection cache (bundles)*/
+ struct conncache conn_cache;
+
+ /* This handle will be used for closing the cached connections in
+ curl_multi_cleanup() */
+ struct SessionHandle *closure_handle;
+
+ long maxconnects; /* if >0, a fixed limit of the maximum number of entries
+ we're allowed to grow the connection cache to */
+
+ long max_host_connections; /* if >0, a fixed limit of the maximum number
+ of connections per host */
+
+ long max_total_connections; /* if >0, a fixed limit of the maximum number
+ of connections in total */
+
+ long max_pipeline_length; /* if >0, maximum number of requests in a
+ pipeline */
+
+ long content_length_penalty_size; /* a connection with a
+ content-length bigger than
+ this is not considered
+ for pipelining */
+
+ long chunk_length_penalty_size; /* a connection with a chunk length
+ bigger than this is not
+ considered for pipelining */
+
+ struct curl_llist *pipelining_site_bl; /* List of sites that are blacklisted
+ from pipelining */
+
+ struct curl_llist *pipelining_server_bl; /* List of server types that are
+ blacklisted from pipelining */
+
+ /* timer callback and user data pointer for the *socket() API */
+ curl_multi_timer_callback timer_cb;
+ void *timer_userp;
+ struct timeval timer_lastcall; /* the fixed time for the timeout for the
+ previous callback */
+};
+
+#endif /* HEADER_CURL_MULTIHANDLE_H */
diff --git a/Utilities/cmcurl/lib/multiif.h b/Utilities/cmcurl/lib/multiif.h
new file mode 100644
index 000000000..e6323adf5
--- /dev/null
+++ b/Utilities/cmcurl/lib/multiif.h
@@ -0,0 +1,97 @@
+#ifndef HEADER_CURL_MULTIIF_H
+#define HEADER_CURL_MULTIIF_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Prototypes for library-wide functions provided by multi.c
+ */
+void Curl_expire(struct SessionHandle *data, long milli);
+void Curl_expire_latest(struct SessionHandle *data, long milli);
+bool Curl_pipeline_wanted(const struct Curl_multi* multi, int bits);
+void Curl_multi_handlePipeBreak(struct SessionHandle *data);
+
+/* Internal version of curl_multi_init() accepts size parameters for the
+ socket and connection hashes */
+struct Curl_multi *Curl_multi_handle(int hashsize, int chashsize);
+
+/* the write bits start at bit 16 for the *getsock() bitmap */
+#define GETSOCK_WRITEBITSTART 16
+
+#define GETSOCK_BLANK 0 /* no bits set */
+
+/* set the bit for the given sock number to make the bitmap for writable */
+#define GETSOCK_WRITESOCK(x) (1 << (GETSOCK_WRITEBITSTART + (x)))
+
+/* set the bit for the given sock number to make the bitmap for readable */
+#define GETSOCK_READSOCK(x) (1 << (x))
+
+#ifdef DEBUGBUILD
+ /*
+ * Curl_multi_dump is not a stable public function, this is only meant to
+ * allow easier tracking of the internal handle's state and what sockets
+ * they use. Only for research and development DEBUGBUILD enabled builds.
+ */
+void Curl_multi_dump(const struct Curl_multi *multi_handle);
+#endif
+
+void Curl_multi_process_pending_handles(struct Curl_multi *multi);
+
+/* Return the value of the CURLMOPT_MAX_HOST_CONNECTIONS option */
+size_t Curl_multi_max_host_connections(struct Curl_multi *multi);
+
+/* Return the value of the CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE option */
+curl_off_t Curl_multi_content_length_penalty_size(struct Curl_multi *multi);
+
+/* Return the value of the CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE option */
+curl_off_t Curl_multi_chunk_length_penalty_size(struct Curl_multi *multi);
+
+/* Return the value of the CURLMOPT_PIPELINING_SITE_BL option */
+struct curl_llist *Curl_multi_pipelining_site_bl(struct Curl_multi *multi);
+
+/* Return the value of the CURLMOPT_PIPELINING_SERVER_BL option */
+struct curl_llist *Curl_multi_pipelining_server_bl(struct Curl_multi *multi);
+
+/* Return the value of the CURLMOPT_MAX_TOTAL_CONNECTIONS option */
+size_t Curl_multi_max_total_connections(struct Curl_multi *multi);
+
+void Curl_multi_connchanged(struct Curl_multi *multi);
+
+/*
+ * Curl_multi_closed()
+ *
+ * Used by the connect code to tell the multi_socket code that one of the
+ * sockets we were using is about to be closed. This function will then
+ * remove it from the sockethash for this handle to make the multi_socket API
+ * behave properly, especially for the case when libcurl will create another
+ * socket again and it gets the same file descriptor number.
+ */
+
+void Curl_multi_closed(struct connectdata *conn, curl_socket_t s);
+
+/*
+ * Add a handle and move it into PERFORM state at once. For pushed streams.
+ */
+CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
+ struct SessionHandle *data,
+ struct connectdata *conn);
+#endif /* HEADER_CURL_MULTIIF_H */
diff --git a/Utilities/cmcurl/lib/netrc.c b/Utilities/cmcurl/lib/netrc.c
new file mode 100644
index 000000000..06f8ea15a
--- /dev/null
+++ b/Utilities/cmcurl/lib/netrc.c
@@ -0,0 +1,203 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+
+#include <curl/curl.h>
+#include "netrc.h"
+
+#include "strequal.h"
+#include "strtok.h"
+#include "rawstr.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* Get user and password from .netrc when given a machine name */
+
+enum host_lookup_state {
+ NOTHING,
+ HOSTFOUND, /* the 'machine' keyword was found */
+ HOSTVALID /* this is "our" machine! */
+};
+
+/*
+ * @unittest: 1304
+ *
+ * *loginp and *passwordp MUST be allocated if they aren't NULL when passed
+ * in.
+ */
+int Curl_parsenetrc(const char *host,
+ char **loginp,
+ char **passwordp,
+ char *netrcfile)
+{
+ FILE *file;
+ int retcode=1;
+ int specific_login = (*loginp && **loginp != 0);
+ bool netrc_alloc = FALSE;
+ enum host_lookup_state state=NOTHING;
+
+ char state_login=0; /* Found a login keyword */
+ char state_password=0; /* Found a password keyword */
+ int state_our_login=FALSE; /* With specific_login, found *our* login name */
+
+#define NETRC DOT_CHAR "netrc"
+
+ if(!netrcfile) {
+ bool home_alloc = FALSE;
+ char *home = curl_getenv("HOME"); /* portable environment reader */
+ if(home) {
+ home_alloc = TRUE;
+#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
+ }
+ else {
+ struct passwd pw, *pw_res;
+ char pwbuf[1024];
+ if(!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res)
+ && pw_res) {
+ home = strdup(pw.pw_dir);
+ if(!home)
+ return CURLE_OUT_OF_MEMORY;
+ home_alloc = TRUE;
+ }
+#elif defined(HAVE_GETPWUID) && defined(HAVE_GETEUID)
+ }
+ else {
+ struct passwd *pw;
+ pw= getpwuid(geteuid());
+ if(pw) {
+ home = pw->pw_dir;
+ }
+#endif
+ }
+
+ if(!home)
+ return retcode; /* no home directory found (or possibly out of memory) */
+
+ netrcfile = curl_maprintf("%s%s%s", home, DIR_CHAR, NETRC);
+ if(home_alloc)
+ free(home);
+ if(!netrcfile) {
+ return -1;
+ }
+ netrc_alloc = TRUE;
+ }
+
+ file = fopen(netrcfile, FOPEN_READTEXT);
+ if(netrc_alloc)
+ free(netrcfile);
+ if(file) {
+ char *tok;
+ char *tok_buf;
+ bool done=FALSE;
+ char netrcbuffer[256];
+ int netrcbuffsize = (int)sizeof(netrcbuffer);
+
+ while(!done && fgets(netrcbuffer, netrcbuffsize, file)) {
+ tok=strtok_r(netrcbuffer, " \t\n", &tok_buf);
+ while(!done && tok) {
+
+ if((*loginp && **loginp) && (*passwordp && **passwordp)) {
+ done=TRUE;
+ break;
+ }
+
+ switch(state) {
+ case NOTHING:
+ if(Curl_raw_equal("machine", tok)) {
+ /* the next tok is the machine name, this is in itself the
+ delimiter that starts the stuff entered for this machine,
+ after this we need to search for 'login' and
+ 'password'. */
+ state=HOSTFOUND;
+ }
+ else if(Curl_raw_equal("default", tok)) {
+ state=HOSTVALID;
+ retcode=0; /* we did find our host */
+ }
+ break;
+ case HOSTFOUND:
+ if(Curl_raw_equal(host, tok)) {
+ /* and yes, this is our host! */
+ state=HOSTVALID;
+ retcode=0; /* we did find our host */
+ }
+ else
+ /* not our host */
+ state=NOTHING;
+ break;
+ case HOSTVALID:
+ /* we are now parsing sub-keywords concerning "our" host */
+ if(state_login) {
+ if(specific_login) {
+ state_our_login = Curl_raw_equal(*loginp, tok);
+ }
+ else {
+ free(*loginp);
+ *loginp = strdup(tok);
+ if(!*loginp) {
+ retcode = -1; /* allocation failed */
+ goto out;
+ }
+ }
+ state_login=0;
+ }
+ else if(state_password) {
+ if(state_our_login || !specific_login) {
+ free(*passwordp);
+ *passwordp = strdup(tok);
+ if(!*passwordp) {
+ retcode = -1; /* allocation failed */
+ goto out;
+ }
+ }
+ state_password=0;
+ }
+ else if(Curl_raw_equal("login", tok))
+ state_login=1;
+ else if(Curl_raw_equal("password", tok))
+ state_password=1;
+ else if(Curl_raw_equal("machine", tok)) {
+ /* ok, there's machine here go => */
+ state = HOSTFOUND;
+ state_our_login = FALSE;
+ }
+ break;
+ } /* switch (state) */
+
+ tok = strtok_r(NULL, " \t\n", &tok_buf);
+ } /* while(tok) */
+ } /* while fgets() */
+
+ out:
+ fclose(file);
+ }
+
+ return retcode;
+}
diff --git a/Utilities/cmcurl/lib/netrc.h b/Utilities/cmcurl/lib/netrc.h
new file mode 100644
index 000000000..a14560114
--- /dev/null
+++ b/Utilities/cmcurl/lib/netrc.h
@@ -0,0 +1,36 @@
+#ifndef HEADER_CURL_NETRC_H
+#define HEADER_CURL_NETRC_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* returns -1 on failure, 0 if the host is found, 1 is the host isn't found */
+int Curl_parsenetrc(const char *host,
+ char **loginp,
+ char **passwordp,
+ char *filename);
+ /* Assume: (*passwordp)[0]=0, host[0] != 0.
+ * If (*loginp)[0] = 0, search for login and password within a machine
+ * section in the netrc.
+ * If (*loginp)[0] != 0, search for password within machine and login.
+ */
+
+#endif /* HEADER_CURL_NETRC_H */
diff --git a/Utilities/cmcurl/lib/non-ascii.c b/Utilities/cmcurl/lib/non-ascii.c
new file mode 100644
index 000000000..6ccb4499e
--- /dev/null
+++ b/Utilities/cmcurl/lib/non-ascii.c
@@ -0,0 +1,338 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef CURL_DOES_CONVERSIONS
+
+#include <curl/curl.h>
+
+#include "non-ascii.h"
+#include "formdata.h"
+#include "sendf.h"
+#include "urldata.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#ifdef HAVE_ICONV
+#include <iconv.h>
+/* set default codesets for iconv */
+#ifndef CURL_ICONV_CODESET_OF_NETWORK
+#define CURL_ICONV_CODESET_OF_NETWORK "ISO8859-1"
+#endif
+#ifndef CURL_ICONV_CODESET_FOR_UTF8
+#define CURL_ICONV_CODESET_FOR_UTF8 "UTF-8"
+#endif
+#define ICONV_ERROR (size_t)-1
+#endif /* HAVE_ICONV */
+
+/*
+ * Curl_convert_clone() returns a malloced copy of the source string (if
+ * returning CURLE_OK), with the data converted to network format.
+ */
+CURLcode Curl_convert_clone(struct SessionHandle *data,
+ const char *indata,
+ size_t insize,
+ char **outbuf)
+{
+ char *convbuf;
+ CURLcode result;
+
+ convbuf = malloc(insize);
+ if(!convbuf)
+ return CURLE_OUT_OF_MEMORY;
+
+ memcpy(convbuf, indata, insize);
+ result = Curl_convert_to_network(data, convbuf, insize);
+ if(result) {
+ free(convbuf);
+ return result;
+ }
+
+ *outbuf = convbuf; /* return the converted buffer */
+
+ return CURLE_OK;
+}
+
+/*
+ * Curl_convert_to_network() is an internal function for performing ASCII
+ * conversions on non-ASCII platforms. It convers the buffer _in place_.
+ */
+CURLcode Curl_convert_to_network(struct SessionHandle *data,
+ char *buffer, size_t length)
+{
+ if(data->set.convtonetwork) {
+ /* use translation callback */
+ CURLcode result = data->set.convtonetwork(buffer, length);
+ if(result) {
+ failf(data,
+ "CURLOPT_CONV_TO_NETWORK_FUNCTION callback returned %d: %s",
+ (int)result, curl_easy_strerror(result));
+ }
+
+ return result;
+ }
+ else {
+#ifdef HAVE_ICONV
+ /* do the translation ourselves */
+ char *input_ptr, *output_ptr;
+ size_t in_bytes, out_bytes, rc;
+ int error;
+
+ /* open an iconv conversion descriptor if necessary */
+ if(data->outbound_cd == (iconv_t)-1) {
+ data->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
+ CURL_ICONV_CODESET_OF_HOST);
+ if(data->outbound_cd == (iconv_t)-1) {
+ error = ERRNO;
+ failf(data,
+ "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
+ CURL_ICONV_CODESET_OF_NETWORK,
+ CURL_ICONV_CODESET_OF_HOST,
+ error, strerror(error));
+ return CURLE_CONV_FAILED;
+ }
+ }
+ /* call iconv */
+ input_ptr = output_ptr = buffer;
+ in_bytes = out_bytes = length;
+ rc = iconv(data->outbound_cd, (const char**)&input_ptr, &in_bytes,
+ &output_ptr, &out_bytes);
+ if((rc == ICONV_ERROR) || (in_bytes != 0)) {
+ error = ERRNO;
+ failf(data,
+ "The Curl_convert_to_network iconv call failed with errno %i: %s",
+ error, strerror(error));
+ return CURLE_CONV_FAILED;
+ }
+#else
+ failf(data, "CURLOPT_CONV_TO_NETWORK_FUNCTION callback required");
+ return CURLE_CONV_REQD;
+#endif /* HAVE_ICONV */
+ }
+
+ return CURLE_OK;
+}
+
+/*
+ * Curl_convert_from_network() is an internal function for performing ASCII
+ * conversions on non-ASCII platforms. It convers the buffer _in place_.
+ */
+CURLcode Curl_convert_from_network(struct SessionHandle *data,
+ char *buffer, size_t length)
+{
+ if(data->set.convfromnetwork) {
+ /* use translation callback */
+ CURLcode result = data->set.convfromnetwork(buffer, length);
+ if(result) {
+ failf(data,
+ "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback returned %d: %s",
+ (int)result, curl_easy_strerror(result));
+ }
+
+ return result;
+ }
+ else {
+#ifdef HAVE_ICONV
+ /* do the translation ourselves */
+ char *input_ptr, *output_ptr;
+ size_t in_bytes, out_bytes, rc;
+ int error;
+
+ /* open an iconv conversion descriptor if necessary */
+ if(data->inbound_cd == (iconv_t)-1) {
+ data->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
+ CURL_ICONV_CODESET_OF_NETWORK);
+ if(data->inbound_cd == (iconv_t)-1) {
+ error = ERRNO;
+ failf(data,
+ "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
+ CURL_ICONV_CODESET_OF_HOST,
+ CURL_ICONV_CODESET_OF_NETWORK,
+ error, strerror(error));
+ return CURLE_CONV_FAILED;
+ }
+ }
+ /* call iconv */
+ input_ptr = output_ptr = buffer;
+ in_bytes = out_bytes = length;
+ rc = iconv(data->inbound_cd, (const char **)&input_ptr, &in_bytes,
+ &output_ptr, &out_bytes);
+ if((rc == ICONV_ERROR) || (in_bytes != 0)) {
+ error = ERRNO;
+ failf(data,
+ "Curl_convert_from_network iconv call failed with errno %i: %s",
+ error, strerror(error));
+ return CURLE_CONV_FAILED;
+ }
+#else
+ failf(data, "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback required");
+ return CURLE_CONV_REQD;
+#endif /* HAVE_ICONV */
+ }
+
+ return CURLE_OK;
+}
+
+/*
+ * Curl_convert_from_utf8() is an internal function for performing UTF-8
+ * conversions on non-ASCII platforms.
+ */
+CURLcode Curl_convert_from_utf8(struct SessionHandle *data,
+ char *buffer, size_t length)
+{
+ if(data->set.convfromutf8) {
+ /* use translation callback */
+ CURLcode result = data->set.convfromutf8(buffer, length);
+ if(result) {
+ failf(data,
+ "CURLOPT_CONV_FROM_UTF8_FUNCTION callback returned %d: %s",
+ (int)result, curl_easy_strerror(result));
+ }
+
+ return result;
+ }
+ else {
+#ifdef HAVE_ICONV
+ /* do the translation ourselves */
+ const char *input_ptr;
+ char *output_ptr;
+ size_t in_bytes, out_bytes, rc;
+ int error;
+
+ /* open an iconv conversion descriptor if necessary */
+ if(data->utf8_cd == (iconv_t)-1) {
+ data->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
+ CURL_ICONV_CODESET_FOR_UTF8);
+ if(data->utf8_cd == (iconv_t)-1) {
+ error = ERRNO;
+ failf(data,
+ "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
+ CURL_ICONV_CODESET_OF_HOST,
+ CURL_ICONV_CODESET_FOR_UTF8,
+ error, strerror(error));
+ return CURLE_CONV_FAILED;
+ }
+ }
+ /* call iconv */
+ input_ptr = output_ptr = buffer;
+ in_bytes = out_bytes = length;
+ rc = iconv(data->utf8_cd, &input_ptr, &in_bytes,
+ &output_ptr, &out_bytes);
+ if((rc == ICONV_ERROR) || (in_bytes != 0)) {
+ error = ERRNO;
+ failf(data,
+ "The Curl_convert_from_utf8 iconv call failed with errno %i: %s",
+ error, strerror(error));
+ return CURLE_CONV_FAILED;
+ }
+ if(output_ptr < input_ptr) {
+ /* null terminate the now shorter output string */
+ *output_ptr = 0x00;
+ }
+#else
+ failf(data, "CURLOPT_CONV_FROM_UTF8_FUNCTION callback required");
+ return CURLE_CONV_REQD;
+#endif /* HAVE_ICONV */
+ }
+
+ return CURLE_OK;
+}
+
+/*
+ * Init conversion stuff for a SessionHandle
+ */
+void Curl_convert_init(struct SessionHandle *data)
+{
+#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
+ /* conversion descriptors for iconv calls */
+ data->outbound_cd = (iconv_t)-1;
+ data->inbound_cd = (iconv_t)-1;
+ data->utf8_cd = (iconv_t)-1;
+#else
+ (void)data;
+#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
+}
+
+/*
+ * Setup conversion stuff for a SessionHandle
+ */
+void Curl_convert_setup(struct SessionHandle *data)
+{
+ data->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
+ CURL_ICONV_CODESET_OF_NETWORK);
+ data->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
+ CURL_ICONV_CODESET_OF_HOST);
+ data->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
+ CURL_ICONV_CODESET_FOR_UTF8);
+}
+
+/*
+ * Close conversion stuff for a SessionHandle
+ */
+
+void Curl_convert_close(struct SessionHandle *data)
+{
+#ifdef HAVE_ICONV
+ /* close iconv conversion descriptors */
+ if(data->inbound_cd != (iconv_t)-1) {
+ iconv_close(data->inbound_cd);
+ }
+ if(data->outbound_cd != (iconv_t)-1) {
+ iconv_close(data->outbound_cd);
+ }
+ if(data->utf8_cd != (iconv_t)-1) {
+ iconv_close(data->utf8_cd);
+ }
+#else
+ (void)data;
+#endif /* HAVE_ICONV */
+}
+
+/*
+ * Curl_convert_form() is used from http.c, this converts any form items that
+ need to be sent in the network encoding. Returns CURLE_OK on success.
+ */
+CURLcode Curl_convert_form(struct SessionHandle *data, struct FormData *form)
+{
+ CURLcode result;
+
+ if(!data)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+
+ while(form) {
+ if(form->type == FORM_DATA) {
+ result = Curl_convert_to_network(data, form->line, form->length);
+ /* Curl_convert_to_network calls failf if unsuccessful */
+ if(result)
+ return result;
+ }
+
+ form = form->next;
+ }
+
+ return CURLE_OK;
+}
+
+#endif /* CURL_DOES_CONVERSIONS */
diff --git a/Utilities/cmcurl/lib/non-ascii.h b/Utilities/cmcurl/lib/non-ascii.h
new file mode 100644
index 000000000..8b4b7c22e
--- /dev/null
+++ b/Utilities/cmcurl/lib/non-ascii.h
@@ -0,0 +1,63 @@
+#ifndef HEADER_CURL_NON_ASCII_H
+#define HEADER_CURL_NON_ASCII_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef CURL_DOES_CONVERSIONS
+
+#include "urldata.h"
+
+/*
+ * Curl_convert_clone() returns a malloced copy of the source string (if
+ * returning CURLE_OK), with the data converted to network format.
+ *
+ * If no conversion was needed *outbuf may be NULL.
+ */
+CURLcode Curl_convert_clone(struct SessionHandle *data,
+ const char *indata,
+ size_t insize,
+ char **outbuf);
+
+void Curl_convert_init(struct SessionHandle *data);
+void Curl_convert_setup(struct SessionHandle *data);
+void Curl_convert_close(struct SessionHandle *data);
+
+CURLcode Curl_convert_to_network(struct SessionHandle *data,
+ char *buffer, size_t length);
+CURLcode Curl_convert_from_network(struct SessionHandle *data,
+ char *buffer, size_t length);
+CURLcode Curl_convert_from_utf8(struct SessionHandle *data,
+ char *buffer, size_t length);
+CURLcode Curl_convert_form(struct SessionHandle *data, struct FormData *form);
+#else
+#define Curl_convert_clone(a,b,c,d) ((void)a, CURLE_OK)
+#define Curl_convert_init(x) Curl_nop_stmt
+#define Curl_convert_setup(x) Curl_nop_stmt
+#define Curl_convert_close(x) Curl_nop_stmt
+#define Curl_convert_to_network(a,b,c) ((void)a, CURLE_OK)
+#define Curl_convert_from_network(a,b,c) ((void)a, CURLE_OK)
+#define Curl_convert_from_utf8(a,b,c) ((void)a, CURLE_OK)
+#define Curl_convert_form(a,b) CURLE_OK
+#endif
+
+#endif /* HEADER_CURL_NON_ASCII_H */
diff --git a/Utilities/cmcurl/lib/nonblock.c b/Utilities/cmcurl/lib/nonblock.c
new file mode 100644
index 000000000..1447c877d
--- /dev/null
+++ b/Utilities/cmcurl/lib/nonblock.c
@@ -0,0 +1,91 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#if (defined(HAVE_IOCTL_FIONBIO) && defined(NETWARE))
+#include <sys/filio.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#include "nonblock.h"
+
+/*
+ * curlx_nonblock() set the given socket to either blocking or non-blocking
+ * mode based on the 'nonblock' boolean argument. This function is highly
+ * portable.
+ */
+int curlx_nonblock(curl_socket_t sockfd, /* operate on this */
+ int nonblock /* TRUE or FALSE */)
+{
+#if defined(USE_BLOCKING_SOCKETS)
+
+ return 0; /* returns success */
+
+#elif defined(HAVE_FCNTL_O_NONBLOCK)
+
+ /* most recent unix versions */
+ int flags;
+ flags = sfcntl(sockfd, F_GETFL, 0);
+ if(nonblock)
+ return sfcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
+ else
+ return sfcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
+
+#elif defined(HAVE_IOCTL_FIONBIO)
+
+ /* older unix versions */
+ int flags = nonblock ? 1 : 0;
+ return ioctl(sockfd, FIONBIO, &flags);
+
+#elif defined(HAVE_IOCTLSOCKET_FIONBIO)
+
+ /* Windows */
+ unsigned long flags = nonblock ? 1UL : 0UL;
+ return ioctlsocket(sockfd, FIONBIO, &flags);
+
+#elif defined(HAVE_IOCTLSOCKET_CAMEL_FIONBIO)
+
+ /* Amiga */
+ long flags = nonblock ? 1L : 0L;
+ return IoctlSocket(sockfd, FIONBIO, flags);
+
+#elif defined(HAVE_SETSOCKOPT_SO_NONBLOCK)
+
+ /* BeOS */
+ long b = nonblock ? 1L : 0L;
+ return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
+
+#else
+# error "no non-blocking method was found/used/set"
+#endif
+}
diff --git a/Utilities/cmcurl/lib/nonblock.h b/Utilities/cmcurl/lib/nonblock.h
new file mode 100644
index 000000000..b540ae46f
--- /dev/null
+++ b/Utilities/cmcurl/lib/nonblock.h
@@ -0,0 +1,31 @@
+#ifndef HEADER_CURL_NONBLOCK_H
+#define HEADER_CURL_NONBLOCK_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <curl/curl.h> /* for curl_socket_t */
+
+int curlx_nonblock(curl_socket_t sockfd, /* operate on this */
+ int nonblock /* TRUE or FALSE */);
+
+#endif /* HEADER_CURL_NONBLOCK_H */
+
diff --git a/Utilities/cmcurl/lib/nwlib.c b/Utilities/cmcurl/lib/nwlib.c
new file mode 100644
index 000000000..bd3f27eac
--- /dev/null
+++ b/Utilities/cmcurl/lib/nwlib.c
@@ -0,0 +1,325 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef NETWARE /* Novell NetWare */
+
+#ifdef __NOVELL_LIBC__
+/* For native LibC-based NLM we need to register as a real lib. */
+#include <library.h>
+#include <netware.h>
+#include <screen.h>
+#include <nks/thread.h>
+#include <nks/synch.h>
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef struct
+{
+ int _errno;
+ void *twentybytes;
+} libthreaddata_t;
+
+typedef struct
+{
+ int x;
+ int y;
+ int z;
+ void *tenbytes;
+ NXKey_t perthreadkey; /* if -1, no key obtained... */
+ NXMutex_t *lock;
+} libdata_t;
+
+int gLibId = -1;
+void *gLibHandle = (void *) NULL;
+rtag_t gAllocTag = (rtag_t) NULL;
+NXMutex_t *gLibLock = (NXMutex_t *) NULL;
+
+/* internal library function prototypes... */
+int DisposeLibraryData( void * );
+void DisposeThreadData( void * );
+int GetOrSetUpData( int id, libdata_t **data, libthreaddata_t **threaddata );
+
+
+int _NonAppStart( void *NLMHandle,
+ void *errorScreen,
+ const char *cmdLine,
+ const char *loadDirPath,
+ size_t uninitializedDataLength,
+ void *NLMFileHandle,
+ int (*readRoutineP)( int conn,
+ void *fileHandle, size_t offset,
+ size_t nbytes,
+ size_t *bytesRead,
+ void *buffer ),
+ size_t customDataOffset,
+ size_t customDataSize,
+ int messageCount,
+ const char **messages )
+{
+ NX_LOCK_INFO_ALLOC(liblock, "Per-Application Data Lock", 0);
+
+#ifndef __GNUC__
+#pragma unused(cmdLine)
+#pragma unused(loadDirPath)
+#pragma unused(uninitializedDataLength)
+#pragma unused(NLMFileHandle)
+#pragma unused(readRoutineP)
+#pragma unused(customDataOffset)
+#pragma unused(customDataSize)
+#pragma unused(messageCount)
+#pragma unused(messages)
+#endif
+
+ /*
+ * Here we process our command line, post errors (to the error screen),
+ * perform initializations and anything else we need to do before being able
+ * to accept calls into us. If we succeed, we return non-zero and the NetWare
+ * Loader will leave us up, otherwise we fail to load and get dumped.
+ */
+ gAllocTag = AllocateResourceTag(NLMHandle,
+ "<library-name> memory allocations",
+ AllocSignature);
+
+ if(!gAllocTag) {
+ OutputToScreen(errorScreen, "Unable to allocate resource tag for "
+ "library memory allocations.\n");
+ return -1;
+ }
+
+ gLibId = register_library(DisposeLibraryData);
+
+ if(gLibId < -1) {
+ OutputToScreen(errorScreen, "Unable to register library with kernel.\n");
+ return -1;
+ }
+
+ gLibHandle = NLMHandle;
+
+ gLibLock = NXMutexAlloc(0, 0, &liblock);
+
+ if(!gLibLock) {
+ OutputToScreen(errorScreen, "Unable to allocate library data lock.\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Here we clean up any resources we allocated. Resource tags is a big part
+ * of what we created, but NetWare doesn't ask us to free those.
+ */
+void _NonAppStop( void )
+{
+ (void) unregister_library(gLibId);
+ NXMutexFree(gLibLock);
+}
+
+/*
+ * This function cannot be the first in the file for if the file is linked
+ * first, then the check-unload function's offset will be nlmname.nlm+0
+ * which is how to tell that there isn't one. When the check function is
+ * first in the linked objects, it is ambiguous. For this reason, we will
+ * put it inside this file after the stop function.
+ *
+ * Here we check to see if it's alright to ourselves to be unloaded. If not,
+ * we return a non-zero value. Right now, there isn't any reason not to allow
+ * it.
+ */
+int _NonAppCheckUnload( void )
+{
+ return 0;
+}
+
+int GetOrSetUpData(int id, libdata_t **appData,
+ libthreaddata_t **threadData )
+{
+ int err;
+ libdata_t *app_data;
+ libthreaddata_t *thread_data;
+ NXKey_t key;
+ NX_LOCK_INFO_ALLOC(liblock, "Application Data Lock", 0);
+
+ err = 0;
+ thread_data = (libthreaddata_t *) NULL;
+
+ /*
+ * Attempt to get our data for the application calling us. This is where we
+ * store whatever application-specific information we need to carry in
+ * support of calling applications.
+ */
+ app_data = (libdata_t *) get_app_data(id);
+
+ if(!app_data) {
+ /*
+ * This application hasn't called us before; set up application AND
+ * per-thread data. Of course, just in case a thread from this same
+ * application is calling us simultaneously, we better lock our application
+ * data-creation mutex. We also need to recheck for data after we acquire
+ * the lock because WE might be that other thread that was too late to
+ * create the data and the first thread in will have created it.
+ */
+ NXLock(gLibLock);
+
+ if(!(app_data = (libdata_t *) get_app_data(id))) {
+ app_data = malloc(sizeof(libdata_t));
+
+ if(app_data) {
+ memset(app_data, 0, sizeof(libdata_t));
+
+ app_data->tenbytes = malloc(10);
+ app_data->lock = NXMutexAlloc(0, 0, &liblock);
+
+ if(!app_data->tenbytes || !app_data->lock) {
+ if(app_data->lock)
+ NXMutexFree(app_data->lock);
+
+ free(app_data);
+ app_data = (libdata_t *) NULL;
+ err = ENOMEM;
+ }
+
+ if(app_data) {
+ /*
+ * Here we burn in the application data that we were trying to get
+ * by calling get_app_data(). Next time we call the first function,
+ * we'll get this data we're just now setting. We also go on here to
+ * establish the per-thread data for the calling thread, something
+ * we'll have to do on each application thread the first time
+ * it calls us.
+ */
+ err = set_app_data(gLibId, app_data);
+
+ if(err) {
+ free(app_data);
+ app_data = (libdata_t *) NULL;
+ err = ENOMEM;
+ }
+ else {
+ /* create key for thread-specific data... */
+ err = NXKeyCreate(DisposeThreadData, (void *) NULL, &key);
+
+ if(err) /* (no more keys left?) */
+ key = -1;
+
+ app_data->perthreadkey = key;
+ }
+ }
+ }
+ }
+
+ NXUnlock(gLibLock);
+ }
+
+ if(app_data) {
+ key = app_data->perthreadkey;
+
+ if(key != -1 /* couldn't create a key? no thread data */
+ && !(err = NXKeyGetValue(key, (void **) &thread_data))
+ && !thread_data) {
+ /*
+ * Allocate the per-thread data for the calling thread. Regardless of
+ * whether there was already application data or not, this may be the
+ * first call by a new thread. The fact that we allocation 20 bytes on
+ * a pointer is not very important, this just helps to demonstrate that
+ * we can have arbitrarily complex per-thread data.
+ */
+ thread_data = malloc(sizeof(libthreaddata_t));
+
+ if(thread_data) {
+ thread_data->_errno = 0;
+ thread_data->twentybytes = malloc(20);
+
+ if(!thread_data->twentybytes) {
+ free(thread_data);
+ thread_data = (libthreaddata_t *) NULL;
+ err = ENOMEM;
+ }
+
+ if((err = NXKeySetValue(key, thread_data))) {
+ free(thread_data->twentybytes);
+ free(thread_data);
+ thread_data = (libthreaddata_t *) NULL;
+ }
+ }
+ }
+ }
+
+ if(appData)
+ *appData = app_data;
+
+ if(threadData)
+ *threadData = thread_data;
+
+ return err;
+}
+
+int DisposeLibraryData( void *data )
+{
+ if(data) {
+ void *tenbytes = ((libdata_t *) data)->tenbytes;
+
+ free(tenbytes);
+ free(data);
+ }
+
+ return 0;
+}
+
+void DisposeThreadData( void *data )
+{
+ if(data) {
+ void *twentybytes = ((libthreaddata_t *) data)->twentybytes;
+
+ free(twentybytes);
+ free(data);
+ }
+}
+
+#else /* __NOVELL_LIBC__ */
+/* For native CLib-based NLM seems we can do a bit more simple. */
+#include <nwthread.h>
+
+int main ( void )
+{
+ /* initialize any globals here... */
+
+ /* do this if any global initializing was done
+ SynchronizeStart();
+ */
+ ExitThread (TSR_THREAD, 0);
+ return 0;
+}
+
+#endif /* __NOVELL_LIBC__ */
+
+#else /* NETWARE */
+
+#ifdef __POCC__
+# pragma warn(disable:2024) /* Disable warning #2024: Empty input file */
+#endif
+
+#endif /* NETWARE */
diff --git a/Utilities/cmcurl/lib/nwos.c b/Utilities/cmcurl/lib/nwos.c
new file mode 100644
index 000000000..23ff2a717
--- /dev/null
+++ b/Utilities/cmcurl/lib/nwos.c
@@ -0,0 +1,88 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef NETWARE /* Novell NetWare */
+
+#ifdef __NOVELL_LIBC__
+/* For native LibC-based NLM we need to do nothing. */
+int netware_init ( void )
+{
+ return 0;
+}
+
+#else /* __NOVELL_LIBC__ */
+
+/* For native CLib-based NLM we need to initialize the LONG namespace. */
+#include <nwnspace.h>
+#include <nwthread.h>
+#include <nwadv.h>
+/* Make the CLIB Ctx stuff link */
+#include <netdb.h>
+NETDB_DEFINE_CONTEXT
+/* Make the CLIB Inet stuff link */
+#include <netinet/in.h>
+#include <arpa/inet.h>
+NETINET_DEFINE_CONTEXT
+
+int netware_init ( void )
+{
+ int rc = 0;
+ unsigned int myHandle = GetNLMHandle();
+ /* import UnAugmentAsterisk dynamically for NW4.x compatibility */
+ void (*pUnAugmentAsterisk)(int) = (void(*)(int))
+ ImportSymbol(myHandle, "UnAugmentAsterisk");
+ /* import UseAccurateCaseForPaths dynamically for NW3.x compatibility */
+ void (*pUseAccurateCaseForPaths)(int) = (void(*)(int))
+ ImportSymbol(myHandle, "UseAccurateCaseForPaths");
+ if(pUnAugmentAsterisk)
+ pUnAugmentAsterisk(1);
+ if(pUseAccurateCaseForPaths)
+ pUseAccurateCaseForPaths(1);
+ UnimportSymbol(myHandle, "UnAugmentAsterisk");
+ UnimportSymbol(myHandle, "UseAccurateCaseForPaths");
+ /* set long name space */
+ if((SetCurrentNameSpace(4) == 255)) {
+ rc = 1;
+ }
+ if((SetTargetNameSpace(4) == 255)) {
+ rc = rc + 2;
+ }
+ return rc;
+}
+
+/* dummy function to satisfy newer prelude */
+int __init_environment ( void )
+{
+ return 0;
+}
+
+/* dummy function to satisfy newer prelude */
+int __deinit_environment ( void )
+{
+ return 0;
+}
+
+#endif /* __NOVELL_LIBC__ */
+
+#endif /* NETWARE */
diff --git a/Utilities/cmcurl/lib/openldap.c b/Utilities/cmcurl/lib/openldap.c
new file mode 100644
index 000000000..bee552f33
--- /dev/null
+++ b/Utilities/cmcurl/lib/openldap.c
@@ -0,0 +1,684 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2010, Howard Chu, <hyc@openldap.org>
+ * Copyright (C) 2011 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_LDAP) && defined(USE_OPENLDAP)
+
+/*
+ * Notice that USE_OPENLDAP is only a source code selection switch. When
+ * libcurl is built with USE_OPENLDAP defined the libcurl source code that
+ * gets compiled is the code from openldap.c, otherwise the code that gets
+ * compiled is the code from ldap.c.
+ *
+ * When USE_OPENLDAP is defined a recent version of the OpenLDAP library
+ * might be required for compilation and runtime. In order to use ancient
+ * OpenLDAP library versions, USE_OPENLDAP shall not be defined.
+ */
+
+#include <ldap.h>
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "sendf.h"
+#include "vtls/vtls.h"
+#include "transfer.h"
+#include "curl_ldap.h"
+#include "curl_base64.h"
+#include "connect.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#ifndef _LDAP_PVT_H
+extern int ldap_pvt_url_scheme2proto(const char *);
+extern int ldap_init_fd(ber_socket_t fd, int proto, const char *url,
+ LDAP **ld);
+#endif
+
+static CURLcode ldap_setup_connection(struct connectdata *conn);
+static CURLcode ldap_do(struct connectdata *conn, bool *done);
+static CURLcode ldap_done(struct connectdata *conn, CURLcode, bool);
+static CURLcode ldap_connect(struct connectdata *conn, bool *done);
+static CURLcode ldap_connecting(struct connectdata *conn, bool *done);
+static CURLcode ldap_disconnect(struct connectdata *conn, bool dead);
+
+static Curl_recv ldap_recv;
+
+/*
+ * LDAP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_ldap = {
+ "LDAP", /* scheme */
+ ldap_setup_connection, /* setup_connection */
+ ldap_do, /* do_it */
+ ldap_done, /* done */
+ ZERO_NULL, /* do_more */
+ ldap_connect, /* connect_it */
+ ldap_connecting, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_getsock */
+ ZERO_NULL, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ ldap_disconnect, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_LDAP, /* defport */
+ CURLPROTO_LDAP, /* protocol */
+ PROTOPT_NONE /* flags */
+};
+
+#ifdef USE_SSL
+/*
+ * LDAPS protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_ldaps = {
+ "LDAPS", /* scheme */
+ ldap_setup_connection, /* setup_connection */
+ ldap_do, /* do_it */
+ ldap_done, /* done */
+ ZERO_NULL, /* do_more */
+ ldap_connect, /* connect_it */
+ ldap_connecting, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_getsock */
+ ZERO_NULL, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ ldap_disconnect, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_LDAPS, /* defport */
+ CURLPROTO_LDAP, /* protocol */
+ PROTOPT_SSL /* flags */
+};
+#endif
+
+static const char *url_errs[] = {
+ "success",
+ "out of memory",
+ "bad parameter",
+ "unrecognized scheme",
+ "unbalanced delimiter",
+ "bad URL",
+ "bad host or port",
+ "bad or missing attributes",
+ "bad or missing scope",
+ "bad or missing filter",
+ "bad or missing extensions"
+};
+
+typedef struct ldapconninfo {
+ LDAP *ld;
+ Curl_recv *recv; /* for stacking SSL handler */
+ Curl_send *send;
+ int proto;
+ int msgid;
+ bool ssldone;
+ bool sslinst;
+ bool didbind;
+} ldapconninfo;
+
+typedef struct ldapreqinfo {
+ int msgid;
+ int nument;
+} ldapreqinfo;
+
+static CURLcode ldap_setup_connection(struct connectdata *conn)
+{
+ ldapconninfo *li;
+ LDAPURLDesc *lud;
+ struct SessionHandle *data=conn->data;
+ int rc, proto;
+ CURLcode status;
+
+ rc = ldap_url_parse(data->change.url, &lud);
+ if(rc != LDAP_URL_SUCCESS) {
+ const char *msg = "url parsing problem";
+ status = CURLE_URL_MALFORMAT;
+ if(rc > LDAP_URL_SUCCESS && rc <= LDAP_URL_ERR_BADEXTS) {
+ if(rc == LDAP_URL_ERR_MEM)
+ status = CURLE_OUT_OF_MEMORY;
+ msg = url_errs[rc];
+ }
+ failf(conn->data, "LDAP local: %s", msg);
+ return status;
+ }
+ proto = ldap_pvt_url_scheme2proto(lud->lud_scheme);
+ ldap_free_urldesc(lud);
+
+ li = calloc(1, sizeof(ldapconninfo));
+ if(!li)
+ return CURLE_OUT_OF_MEMORY;
+ li->proto = proto;
+ conn->proto.generic = li;
+ connkeep(conn, "OpenLDAP default");
+ /* TODO:
+ * - provide option to choose SASL Binds instead of Simple
+ */
+ return CURLE_OK;
+}
+
+#ifdef USE_SSL
+static Sockbuf_IO ldapsb_tls;
+#endif
+
+static CURLcode ldap_connect(struct connectdata *conn, bool *done)
+{
+ ldapconninfo *li = conn->proto.generic;
+ struct SessionHandle *data = conn->data;
+ int rc, proto = LDAP_VERSION3;
+ char hosturl[1024];
+ char *ptr;
+
+ (void)done;
+
+ strcpy(hosturl, "ldap");
+ ptr = hosturl+4;
+ if(conn->handler->flags & PROTOPT_SSL)
+ *ptr++ = 's';
+ snprintf(ptr, sizeof(hosturl)-(ptr-hosturl), "://%s:%d",
+ conn->host.name, conn->remote_port);
+
+ rc = ldap_init_fd(conn->sock[FIRSTSOCKET], li->proto, hosturl, &li->ld);
+ if(rc) {
+ failf(data, "LDAP local: Cannot connect to %s, %s",
+ hosturl, ldap_err2string(rc));
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
+
+#ifdef USE_SSL
+ if(conn->handler->flags & PROTOPT_SSL) {
+ CURLcode result;
+ result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &li->ssldone);
+ if(result)
+ return result;
+ }
+#endif
+
+ return CURLE_OK;
+}
+
+static CURLcode ldap_connecting(struct connectdata *conn, bool *done)
+{
+ ldapconninfo *li = conn->proto.generic;
+ struct SessionHandle *data = conn->data;
+ LDAPMessage *msg = NULL;
+ struct timeval tv = {0, 1}, *tvp;
+ int rc, err;
+ char *info = NULL;
+
+#ifdef USE_SSL
+ if(conn->handler->flags & PROTOPT_SSL) {
+ /* Is the SSL handshake complete yet? */
+ if(!li->ssldone) {
+ CURLcode result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET,
+ &li->ssldone);
+ if(result || !li->ssldone)
+ return result;
+ }
+
+ /* Have we installed the libcurl SSL handlers into the sockbuf yet? */
+ if(!li->sslinst) {
+ Sockbuf *sb;
+ ldap_get_option(li->ld, LDAP_OPT_SOCKBUF, &sb);
+ ber_sockbuf_add_io(sb, &ldapsb_tls, LBER_SBIOD_LEVEL_TRANSPORT, conn);
+ li->sslinst = TRUE;
+ li->recv = conn->recv[FIRSTSOCKET];
+ li->send = conn->send[FIRSTSOCKET];
+ }
+ }
+#endif
+
+ tvp = &tv;
+
+retry:
+ if(!li->didbind) {
+ char *binddn;
+ struct berval passwd;
+
+ if(conn->bits.user_passwd) {
+ binddn = conn->user;
+ passwd.bv_val = conn->passwd;
+ passwd.bv_len = strlen(passwd.bv_val);
+ }
+ else {
+ binddn = NULL;
+ passwd.bv_val = NULL;
+ passwd.bv_len = 0;
+ }
+ rc = ldap_sasl_bind(li->ld, binddn, LDAP_SASL_SIMPLE, &passwd,
+ NULL, NULL, &li->msgid);
+ if(rc)
+ return CURLE_LDAP_CANNOT_BIND;
+ li->didbind = TRUE;
+ if(tvp)
+ return CURLE_OK;
+ }
+
+ rc = ldap_result(li->ld, li->msgid, LDAP_MSG_ONE, tvp, &msg);
+ if(rc < 0) {
+ failf(data, "LDAP local: bind ldap_result %s", ldap_err2string(rc));
+ return CURLE_LDAP_CANNOT_BIND;
+ }
+ if(rc == 0) {
+ /* timed out */
+ return CURLE_OK;
+ }
+
+ rc = ldap_parse_result(li->ld, msg, &err, NULL, &info, NULL, NULL, 1);
+ if(rc) {
+ failf(data, "LDAP local: bind ldap_parse_result %s", ldap_err2string(rc));
+ return CURLE_LDAP_CANNOT_BIND;
+ }
+
+ /* Try to fallback to LDAPv2? */
+ if(err == LDAP_PROTOCOL_ERROR) {
+ int proto;
+ ldap_get_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
+ if(proto == LDAP_VERSION3) {
+ if(info) {
+ ldap_memfree(info);
+ info = NULL;
+ }
+ proto = LDAP_VERSION2;
+ ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
+ li->didbind = FALSE;
+ goto retry;
+ }
+ }
+
+ if(err) {
+ failf(data, "LDAP remote: bind failed %s %s", ldap_err2string(rc),
+ info ? info : "");
+ if(info)
+ ldap_memfree(info);
+ return CURLE_LOGIN_DENIED;
+ }
+
+ if(info)
+ ldap_memfree(info);
+ conn->recv[FIRSTSOCKET] = ldap_recv;
+ *done = TRUE;
+
+ return CURLE_OK;
+}
+
+static CURLcode ldap_disconnect(struct connectdata *conn, bool dead_connection)
+{
+ ldapconninfo *li = conn->proto.generic;
+ (void) dead_connection;
+
+ if(li) {
+ if(li->ld) {
+ ldap_unbind_ext(li->ld, NULL, NULL);
+ li->ld = NULL;
+ }
+ conn->proto.generic = NULL;
+ free(li);
+ }
+ return CURLE_OK;
+}
+
+static CURLcode ldap_do(struct connectdata *conn, bool *done)
+{
+ ldapconninfo *li = conn->proto.generic;
+ ldapreqinfo *lr;
+ CURLcode status = CURLE_OK;
+ int rc = 0;
+ LDAPURLDesc *ludp = NULL;
+ int msgid;
+ struct SessionHandle *data=conn->data;
+
+ connkeep(conn, "OpenLDAP do");
+
+ infof(data, "LDAP local: %s\n", data->change.url);
+
+ rc = ldap_url_parse(data->change.url, &ludp);
+ if(rc != LDAP_URL_SUCCESS) {
+ const char *msg = "url parsing problem";
+ status = CURLE_URL_MALFORMAT;
+ if(rc > LDAP_URL_SUCCESS && rc <= LDAP_URL_ERR_BADEXTS) {
+ if(rc == LDAP_URL_ERR_MEM)
+ status = CURLE_OUT_OF_MEMORY;
+ msg = url_errs[rc];
+ }
+ failf(conn->data, "LDAP local: %s", msg);
+ return status;
+ }
+
+ rc = ldap_search_ext(li->ld, ludp->lud_dn, ludp->lud_scope,
+ ludp->lud_filter, ludp->lud_attrs, 0,
+ NULL, NULL, NULL, 0, &msgid);
+ ldap_free_urldesc(ludp);
+ if(rc != LDAP_SUCCESS) {
+ failf(data, "LDAP local: ldap_search_ext %s", ldap_err2string(rc));
+ return CURLE_LDAP_SEARCH_FAILED;
+ }
+ lr = calloc(1, sizeof(ldapreqinfo));
+ if(!lr)
+ return CURLE_OUT_OF_MEMORY;
+ lr->msgid = msgid;
+ data->req.protop = lr;
+ Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL);
+ *done = TRUE;
+ return CURLE_OK;
+}
+
+static CURLcode ldap_done(struct connectdata *conn, CURLcode res,
+ bool premature)
+{
+ ldapreqinfo *lr = conn->data->req.protop;
+
+ (void)res;
+ (void)premature;
+
+ if(lr) {
+ /* if there was a search in progress, abandon it */
+ if(lr->msgid) {
+ ldapconninfo *li = conn->proto.generic;
+ ldap_abandon_ext(li->ld, lr->msgid, NULL, NULL);
+ lr->msgid = 0;
+ }
+ conn->data->req.protop = NULL;
+ free(lr);
+ }
+
+ return CURLE_OK;
+}
+
+static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
+ size_t len, CURLcode *err)
+{
+ ldapconninfo *li = conn->proto.generic;
+ struct SessionHandle *data = conn->data;
+ ldapreqinfo *lr = data->req.protop;
+ int rc, ret;
+ LDAPMessage *msg = NULL;
+ LDAPMessage *ent;
+ BerElement *ber = NULL;
+ struct timeval tv = {0, 1};
+
+ (void)len;
+ (void)buf;
+ (void)sockindex;
+
+ rc = ldap_result(li->ld, lr->msgid, LDAP_MSG_RECEIVED, &tv, &msg);
+ if(rc < 0) {
+ failf(data, "LDAP local: search ldap_result %s", ldap_err2string(rc));
+ *err = CURLE_RECV_ERROR;
+ return -1;
+ }
+
+ *err = CURLE_AGAIN;
+ ret = -1;
+
+ /* timed out */
+ if(!msg)
+ return ret;
+
+ for(ent = ldap_first_message(li->ld, msg); ent;
+ ent = ldap_next_message(li->ld, ent)) {
+ struct berval bv, *bvals, **bvp = &bvals;
+ int binary = 0, msgtype;
+
+ msgtype = ldap_msgtype(ent);
+ if(msgtype == LDAP_RES_SEARCH_RESULT) {
+ int code;
+ char *info = NULL;
+ rc = ldap_parse_result(li->ld, ent, &code, NULL, &info, NULL, NULL, 0);
+ if(rc) {
+ failf(data, "LDAP local: search ldap_parse_result %s",
+ ldap_err2string(rc));
+ *err = CURLE_LDAP_SEARCH_FAILED;
+ }
+ else if(code && code != LDAP_SIZELIMIT_EXCEEDED) {
+ failf(data, "LDAP remote: search failed %s %s", ldap_err2string(rc),
+ info ? info : "");
+ *err = CURLE_LDAP_SEARCH_FAILED;
+ }
+ else {
+ /* successful */
+ if(code == LDAP_SIZELIMIT_EXCEEDED)
+ infof(data, "There are more than %d entries\n", lr->nument);
+ data->req.size = data->req.bytecount;
+ *err = CURLE_OK;
+ ret = 0;
+ }
+ lr->msgid = 0;
+ ldap_memfree(info);
+ break;
+ }
+ else if(msgtype != LDAP_RES_SEARCH_ENTRY)
+ continue;
+
+ lr->nument++;
+ rc = ldap_get_dn_ber(li->ld, ent, &ber, &bv);
+ if(rc < 0) {
+ /* TODO: verify that this is really how this return code should be
+ handled */
+ *err = CURLE_RECV_ERROR;
+ return -1;
+ }
+ *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
+ if(*err)
+ return -1;
+
+ *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
+ bv.bv_len);
+ if(*err)
+ return -1;
+
+ *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
+ if(*err)
+ return -1;
+ data->req.bytecount += bv.bv_len + 5;
+
+ for(rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp);
+ rc == LDAP_SUCCESS;
+ rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp)) {
+ int i;
+
+ if(bv.bv_val == NULL) break;
+
+ if(bv.bv_len > 7 && !strncmp(bv.bv_val + bv.bv_len - 7, ";binary", 7))
+ binary = 1;
+ else
+ binary = 0;
+
+ for(i=0; bvals[i].bv_val != NULL; i++) {
+ int binval = 0;
+ *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
+ if(*err)
+ return -1;
+
+ *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
+ bv.bv_len);
+ if(*err)
+ return -1;
+
+ *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)":", 1);
+ if(*err)
+ return -1;
+ data->req.bytecount += bv.bv_len + 2;
+
+ if(!binary) {
+ /* check for leading or trailing whitespace */
+ if(ISSPACE(bvals[i].bv_val[0]) ||
+ ISSPACE(bvals[i].bv_val[bvals[i].bv_len-1]))
+ binval = 1;
+ else {
+ /* check for unprintable characters */
+ unsigned int j;
+ for(j=0; j<bvals[i].bv_len; j++)
+ if(!ISPRINT(bvals[i].bv_val[j])) {
+ binval = 1;
+ break;
+ }
+ }
+ }
+ if(binary || binval) {
+ char *val_b64 = NULL;
+ size_t val_b64_sz = 0;
+ /* Binary value, encode to base64. */
+ CURLcode error = Curl_base64_encode(data,
+ bvals[i].bv_val,
+ bvals[i].bv_len,
+ &val_b64,
+ &val_b64_sz);
+ if(error) {
+ ber_memfree(bvals);
+ ber_free(ber, 0);
+ ldap_msgfree(msg);
+ *err = error;
+ return -1;
+ }
+ *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2);
+ if(*err)
+ return -1;
+
+ data->req.bytecount += 2;
+ if(val_b64_sz > 0) {
+ *err = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64,
+ val_b64_sz);
+ if(*err)
+ return -1;
+ free(val_b64);
+ data->req.bytecount += val_b64_sz;
+ }
+ }
+ else {
+ *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)" ", 1);
+ if(*err)
+ return -1;
+
+ *err = Curl_client_write(conn, CLIENTWRITE_BODY, bvals[i].bv_val,
+ bvals[i].bv_len);
+ if(*err)
+ return -1;
+
+ data->req.bytecount += bvals[i].bv_len + 1;
+ }
+ *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
+ if(*err)
+ return -1;
+
+ data->req.bytecount++;
+ }
+ ber_memfree(bvals);
+ *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
+ if(*err)
+ return -1;
+ data->req.bytecount++;
+ }
+ *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
+ if(*err)
+ return -1;
+ data->req.bytecount++;
+ ber_free(ber, 0);
+ }
+ ldap_msgfree(msg);
+ return ret;
+}
+
+#ifdef USE_SSL
+static int
+ldapsb_tls_setup(Sockbuf_IO_Desc *sbiod, void *arg)
+{
+ sbiod->sbiod_pvt = arg;
+ return 0;
+}
+
+static int
+ldapsb_tls_remove(Sockbuf_IO_Desc *sbiod)
+{
+ sbiod->sbiod_pvt = NULL;
+ return 0;
+}
+
+/* We don't need to do anything because libcurl does it already */
+static int
+ldapsb_tls_close(Sockbuf_IO_Desc *sbiod)
+{
+ (void)sbiod;
+ return 0;
+}
+
+static int
+ldapsb_tls_ctrl(Sockbuf_IO_Desc *sbiod, int opt, void *arg)
+{
+ (void)arg;
+ if(opt == LBER_SB_OPT_DATA_READY) {
+ struct connectdata *conn = sbiod->sbiod_pvt;
+ return Curl_ssl_data_pending(conn, FIRSTSOCKET);
+ }
+ return 0;
+}
+
+static ber_slen_t
+ldapsb_tls_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
+{
+ struct connectdata *conn = sbiod->sbiod_pvt;
+ ldapconninfo *li = conn->proto.generic;
+ ber_slen_t ret;
+ CURLcode err = CURLE_RECV_ERROR;
+
+ ret = li->recv(conn, FIRSTSOCKET, buf, len, &err);
+ if(ret < 0 && err == CURLE_AGAIN) {
+ SET_SOCKERRNO(EWOULDBLOCK);
+ }
+ return ret;
+}
+
+static ber_slen_t
+ldapsb_tls_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
+{
+ struct connectdata *conn = sbiod->sbiod_pvt;
+ ldapconninfo *li = conn->proto.generic;
+ ber_slen_t ret;
+ CURLcode err = CURLE_SEND_ERROR;
+
+ ret = li->send(conn, FIRSTSOCKET, buf, len, &err);
+ if(ret < 0 && err == CURLE_AGAIN) {
+ SET_SOCKERRNO(EWOULDBLOCK);
+ }
+ return ret;
+}
+
+static Sockbuf_IO ldapsb_tls =
+{
+ ldapsb_tls_setup,
+ ldapsb_tls_remove,
+ ldapsb_tls_ctrl,
+ ldapsb_tls_read,
+ ldapsb_tls_write,
+ ldapsb_tls_close
+};
+#endif /* USE_SSL */
+
+#endif /* !CURL_DISABLE_LDAP && USE_OPENLDAP */
diff --git a/Utilities/cmcurl/lib/parsedate.c b/Utilities/cmcurl/lib/parsedate.c
new file mode 100644
index 000000000..3e168f5ab
--- /dev/null
+++ b/Utilities/cmcurl/lib/parsedate.c
@@ -0,0 +1,583 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/*
+ A brief summary of the date string formats this parser groks:
+
+ RFC 2616 3.3.1
+
+ Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123
+ Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
+ Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format
+
+ we support dates without week day name:
+
+ 06 Nov 1994 08:49:37 GMT
+ 06-Nov-94 08:49:37 GMT
+ Nov 6 08:49:37 1994
+
+ without the time zone:
+
+ 06 Nov 1994 08:49:37
+ 06-Nov-94 08:49:37
+
+ weird order:
+
+ 1994 Nov 6 08:49:37 (GNU date fails)
+ GMT 08:49:37 06-Nov-94 Sunday
+ 94 6 Nov 08:49:37 (GNU date fails)
+
+ time left out:
+
+ 1994 Nov 6
+ 06-Nov-94
+ Sun Nov 6 94
+
+ unusual separators:
+
+ 1994.Nov.6
+ Sun/Nov/6/94/GMT
+
+ commonly used time zone names:
+
+ Sun, 06 Nov 1994 08:49:37 CET
+ 06 Nov 1994 08:49:37 EST
+
+ time zones specified using RFC822 style:
+
+ Sun, 12 Sep 2004 15:05:58 -0700
+ Sat, 11 Sep 2004 21:32:11 +0200
+
+ compact numerical date strings:
+
+ 20040912 15:05:58 -0700
+ 20040911 +0200
+
+*/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include <curl/curl.h>
+#include "rawstr.h"
+#include "warnless.h"
+#include "parsedate.h"
+
+const char * const Curl_wkday[] =
+{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
+static const char * const weekday[] =
+{ "Monday", "Tuesday", "Wednesday", "Thursday",
+ "Friday", "Saturday", "Sunday" };
+const char * const Curl_month[]=
+{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+
+struct tzinfo {
+ char name[5];
+ int offset; /* +/- in minutes */
+};
+
+/*
+ * parsedate()
+ *
+ * Returns:
+ *
+ * PARSEDATE_OK - a fine conversion
+ * PARSEDATE_FAIL - failed to convert
+ * PARSEDATE_LATER - time overflow at the far end of time_t
+ * PARSEDATE_SOONER - time underflow at the low end of time_t
+ */
+
+static int parsedate(const char *date, time_t *output);
+
+#define PARSEDATE_OK 0
+#define PARSEDATE_FAIL -1
+#define PARSEDATE_LATER 1
+#define PARSEDATE_SOONER 2
+
+/* Here's a bunch of frequently used time zone names. These were supported
+ by the old getdate parser. */
+#define tDAYZONE -60 /* offset for daylight savings time */
+static const struct tzinfo tz[]= {
+ {"GMT", 0}, /* Greenwich Mean */
+ {"UTC", 0}, /* Universal (Coordinated) */
+ {"WET", 0}, /* Western European */
+ {"BST", 0 tDAYZONE}, /* British Summer */
+ {"WAT", 60}, /* West Africa */
+ {"AST", 240}, /* Atlantic Standard */
+ {"ADT", 240 tDAYZONE}, /* Atlantic Daylight */
+ {"EST", 300}, /* Eastern Standard */
+ {"EDT", 300 tDAYZONE}, /* Eastern Daylight */
+ {"CST", 360}, /* Central Standard */
+ {"CDT", 360 tDAYZONE}, /* Central Daylight */
+ {"MST", 420}, /* Mountain Standard */
+ {"MDT", 420 tDAYZONE}, /* Mountain Daylight */
+ {"PST", 480}, /* Pacific Standard */
+ {"PDT", 480 tDAYZONE}, /* Pacific Daylight */
+ {"YST", 540}, /* Yukon Standard */
+ {"YDT", 540 tDAYZONE}, /* Yukon Daylight */
+ {"HST", 600}, /* Hawaii Standard */
+ {"HDT", 600 tDAYZONE}, /* Hawaii Daylight */
+ {"CAT", 600}, /* Central Alaska */
+ {"AHST", 600}, /* Alaska-Hawaii Standard */
+ {"NT", 660}, /* Nome */
+ {"IDLW", 720}, /* International Date Line West */
+ {"CET", -60}, /* Central European */
+ {"MET", -60}, /* Middle European */
+ {"MEWT", -60}, /* Middle European Winter */
+ {"MEST", -60 tDAYZONE}, /* Middle European Summer */
+ {"CEST", -60 tDAYZONE}, /* Central European Summer */
+ {"MESZ", -60 tDAYZONE}, /* Middle European Summer */
+ {"FWT", -60}, /* French Winter */
+ {"FST", -60 tDAYZONE}, /* French Summer */
+ {"EET", -120}, /* Eastern Europe, USSR Zone 1 */
+ {"WAST", -420}, /* West Australian Standard */
+ {"WADT", -420 tDAYZONE}, /* West Australian Daylight */
+ {"CCT", -480}, /* China Coast, USSR Zone 7 */
+ {"JST", -540}, /* Japan Standard, USSR Zone 8 */
+ {"EAST", -600}, /* Eastern Australian Standard */
+ {"EADT", -600 tDAYZONE}, /* Eastern Australian Daylight */
+ {"GST", -600}, /* Guam Standard, USSR Zone 9 */
+ {"NZT", -720}, /* New Zealand */
+ {"NZST", -720}, /* New Zealand Standard */
+ {"NZDT", -720 tDAYZONE}, /* New Zealand Daylight */
+ {"IDLE", -720}, /* International Date Line East */
+ /* Next up: Military timezone names. RFC822 allowed these, but (as noted in
+ RFC 1123) had their signs wrong. Here we use the correct signs to match
+ actual military usage.
+ */
+ {"A", +1 * 60}, /* Alpha */
+ {"B", +2 * 60}, /* Bravo */
+ {"C", +3 * 60}, /* Charlie */
+ {"D", +4 * 60}, /* Delta */
+ {"E", +5 * 60}, /* Echo */
+ {"F", +6 * 60}, /* Foxtrot */
+ {"G", +7 * 60}, /* Golf */
+ {"H", +8 * 60}, /* Hotel */
+ {"I", +9 * 60}, /* India */
+ /* "J", Juliet is not used as a timezone, to indicate the observer's local
+ time */
+ {"K", +10 * 60}, /* Kilo */
+ {"L", +11 * 60}, /* Lima */
+ {"M", +12 * 60}, /* Mike */
+ {"N", -1 * 60}, /* November */
+ {"O", -2 * 60}, /* Oscar */
+ {"P", -3 * 60}, /* Papa */
+ {"Q", -4 * 60}, /* Quebec */
+ {"R", -5 * 60}, /* Romeo */
+ {"S", -6 * 60}, /* Sierra */
+ {"T", -7 * 60}, /* Tango */
+ {"U", -8 * 60}, /* Uniform */
+ {"V", -9 * 60}, /* Victor */
+ {"W", -10 * 60}, /* Whiskey */
+ {"X", -11 * 60}, /* X-ray */
+ {"Y", -12 * 60}, /* Yankee */
+ {"Z", 0}, /* Zulu, zero meridian, a.k.a. UTC */
+};
+
+/* returns:
+ -1 no day
+ 0 monday - 6 sunday
+*/
+
+static int checkday(const char *check, size_t len)
+{
+ int i;
+ const char * const *what;
+ bool found= FALSE;
+ if(len > 3)
+ what = &weekday[0];
+ else
+ what = &Curl_wkday[0];
+ for(i=0; i<7; i++) {
+ if(Curl_raw_equal(check, what[0])) {
+ found=TRUE;
+ break;
+ }
+ what++;
+ }
+ return found?i:-1;
+}
+
+static int checkmonth(const char *check)
+{
+ int i;
+ const char * const *what;
+ bool found= FALSE;
+
+ what = &Curl_month[0];
+ for(i=0; i<12; i++) {
+ if(Curl_raw_equal(check, what[0])) {
+ found=TRUE;
+ break;
+ }
+ what++;
+ }
+ return found?i:-1; /* return the offset or -1, no real offset is -1 */
+}
+
+/* return the time zone offset between GMT and the input one, in number
+ of seconds or -1 if the timezone wasn't found/legal */
+
+static int checktz(const char *check)
+{
+ unsigned int i;
+ const struct tzinfo *what;
+ bool found= FALSE;
+
+ what = tz;
+ for(i=0; i< sizeof(tz)/sizeof(tz[0]); i++) {
+ if(Curl_raw_equal(check, what->name)) {
+ found=TRUE;
+ break;
+ }
+ what++;
+ }
+ return found?what->offset*60:-1;
+}
+
+static void skip(const char **date)
+{
+ /* skip everything that aren't letters or digits */
+ while(**date && !ISALNUM(**date))
+ (*date)++;
+}
+
+enum assume {
+ DATE_MDAY,
+ DATE_YEAR,
+ DATE_TIME
+};
+
+/* this is a clone of 'struct tm' but with all fields we don't need or use
+ cut out */
+struct my_tm {
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+};
+
+/* struct tm to time since epoch in GMT time zone.
+ * This is similar to the standard mktime function but for GMT only, and
+ * doesn't suffer from the various bugs and portability problems that
+ * some systems' implementations have.
+ */
+static time_t my_timegm(struct my_tm *tm)
+{
+ static const int month_days_cumulative [12] =
+ { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+ int month, year, leap_days;
+
+ if(tm->tm_year < 70)
+ /* we don't support years before 1970 as they will cause this function
+ to return a negative value */
+ return -1;
+
+ year = tm->tm_year + 1900;
+ month = tm->tm_mon;
+ if(month < 0) {
+ year += (11 - month) / 12;
+ month = 11 - (11 - month) % 12;
+ }
+ else if(month >= 12) {
+ year -= month / 12;
+ month = month % 12;
+ }
+
+ leap_days = year - (tm->tm_mon <= 1);
+ leap_days = ((leap_days / 4) - (leap_days / 100) + (leap_days / 400)
+ - (1969 / 4) + (1969 / 100) - (1969 / 400));
+
+ return ((((time_t) (year - 1970) * 365
+ + leap_days + month_days_cumulative [month] + tm->tm_mday - 1) * 24
+ + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec;
+}
+
+/*
+ * parsedate()
+ *
+ * Returns:
+ *
+ * PARSEDATE_OK - a fine conversion
+ * PARSEDATE_FAIL - failed to convert
+ * PARSEDATE_LATER - time overflow at the far end of time_t
+ * PARSEDATE_SOONER - time underflow at the low end of time_t
+ */
+
+static int parsedate(const char *date, time_t *output)
+{
+ time_t t = 0;
+ int wdaynum=-1; /* day of the week number, 0-6 (mon-sun) */
+ int monnum=-1; /* month of the year number, 0-11 */
+ int mdaynum=-1; /* day of month, 1 - 31 */
+ int hournum=-1;
+ int minnum=-1;
+ int secnum=-1;
+ int yearnum=-1;
+ int tzoff=-1;
+ struct my_tm tm;
+ enum assume dignext = DATE_MDAY;
+ const char *indate = date; /* save the original pointer */
+ int part = 0; /* max 6 parts */
+
+ while(*date && (part < 6)) {
+ bool found=FALSE;
+
+ skip(&date);
+
+ if(ISALPHA(*date)) {
+ /* a name coming up */
+ char buf[32]="";
+ size_t len;
+ if(sscanf(date, "%31[ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz]", buf))
+ len = strlen(buf);
+ else
+ len = 0;
+
+ if(wdaynum == -1) {
+ wdaynum = checkday(buf, len);
+ if(wdaynum != -1)
+ found = TRUE;
+ }
+ if(!found && (monnum == -1)) {
+ monnum = checkmonth(buf);
+ if(monnum != -1)
+ found = TRUE;
+ }
+
+ if(!found && (tzoff == -1)) {
+ /* this just must be a time zone string */
+ tzoff = checktz(buf);
+ if(tzoff != -1)
+ found = TRUE;
+ }
+
+ if(!found)
+ return PARSEDATE_FAIL; /* bad string */
+
+ date += len;
+ }
+ else if(ISDIGIT(*date)) {
+ /* a digit */
+ int val;
+ char *end;
+ if((secnum == -1) &&
+ (3 == sscanf(date, "%02d:%02d:%02d", &hournum, &minnum, &secnum))) {
+ /* time stamp! */
+ date += 8;
+ }
+ else if((secnum == -1) &&
+ (2 == sscanf(date, "%02d:%02d", &hournum, &minnum))) {
+ /* time stamp without seconds */
+ date += 5;
+ secnum = 0;
+ }
+ else {
+ long lval;
+ int error;
+ int old_errno;
+
+ old_errno = ERRNO;
+ SET_ERRNO(0);
+ lval = strtol(date, &end, 10);
+ error = ERRNO;
+ if(error != old_errno)
+ SET_ERRNO(old_errno);
+
+ if(error)
+ return PARSEDATE_FAIL;
+
+#if LONG_MAX != INT_MAX
+ if((lval > (long)INT_MAX) || (lval < (long)INT_MIN))
+ return PARSEDATE_FAIL;
+#endif
+
+ val = curlx_sltosi(lval);
+
+ if((tzoff == -1) &&
+ ((end - date) == 4) &&
+ (val <= 1400) &&
+ (indate< date) &&
+ ((date[-1] == '+' || date[-1] == '-'))) {
+ /* four digits and a value less than or equal to 1400 (to take into
+ account all sorts of funny time zone diffs) and it is preceded
+ with a plus or minus. This is a time zone indication. 1400 is
+ picked since +1300 is frequently used and +1400 is mentioned as
+ an edge number in the document "ISO C 200X Proposal: Timezone
+ Functions" at http://david.tribble.com/text/c0xtimezone.html If
+ anyone has a more authoritative source for the exact maximum time
+ zone offsets, please speak up! */
+ found = TRUE;
+ tzoff = (val/100 * 60 + val%100)*60;
+
+ /* the + and - prefix indicates the local time compared to GMT,
+ this we need ther reversed math to get what we want */
+ tzoff = date[-1]=='+'?-tzoff:tzoff;
+ }
+
+ if(((end - date) == 8) &&
+ (yearnum == -1) &&
+ (monnum == -1) &&
+ (mdaynum == -1)) {
+ /* 8 digits, no year, month or day yet. This is YYYYMMDD */
+ found = TRUE;
+ yearnum = val/10000;
+ monnum = (val%10000)/100-1; /* month is 0 - 11 */
+ mdaynum = val%100;
+ }
+
+ if(!found && (dignext == DATE_MDAY) && (mdaynum == -1)) {
+ if((val > 0) && (val<32)) {
+ mdaynum = val;
+ found = TRUE;
+ }
+ dignext = DATE_YEAR;
+ }
+
+ if(!found && (dignext == DATE_YEAR) && (yearnum == -1)) {
+ yearnum = val;
+ found = TRUE;
+ if(yearnum < 1900) {
+ if(yearnum > 70)
+ yearnum += 1900;
+ else
+ yearnum += 2000;
+ }
+ if(mdaynum == -1)
+ dignext = DATE_MDAY;
+ }
+
+ if(!found)
+ return PARSEDATE_FAIL;
+
+ date = end;
+ }
+ }
+
+ part++;
+ }
+
+ if(-1 == secnum)
+ secnum = minnum = hournum = 0; /* no time, make it zero */
+
+ if((-1 == mdaynum) ||
+ (-1 == monnum) ||
+ (-1 == yearnum))
+ /* lacks vital info, fail */
+ return PARSEDATE_FAIL;
+
+#if SIZEOF_TIME_T < 5
+ /* 32 bit time_t can only hold dates to the beginning of 2038 */
+ if(yearnum > 2037) {
+ *output = 0x7fffffff;
+ return PARSEDATE_LATER;
+ }
+#endif
+
+ if(yearnum < 1970) {
+ *output = 0;
+ return PARSEDATE_SOONER;
+ }
+
+ if((mdaynum > 31) || (monnum > 11) ||
+ (hournum > 23) || (minnum > 59) || (secnum > 60))
+ return PARSEDATE_FAIL; /* clearly an illegal date */
+
+ tm.tm_sec = secnum;
+ tm.tm_min = minnum;
+ tm.tm_hour = hournum;
+ tm.tm_mday = mdaynum;
+ tm.tm_mon = monnum;
+ tm.tm_year = yearnum - 1900;
+
+ /* my_timegm() returns a time_t. time_t is often 32 bits, even on many
+ architectures that feature 64 bit 'long'.
+
+ Some systems have 64 bit time_t and deal with years beyond 2038. However,
+ even on some of the systems with 64 bit time_t mktime() returns -1 for
+ dates beyond 03:14:07 UTC, January 19, 2038. (Such as AIX 5100-06)
+ */
+ t = my_timegm(&tm);
+
+ /* time zone adjust (cast t to int to compare to negative one) */
+ if(-1 != (int)t) {
+
+ /* Add the time zone diff between local time zone and GMT. */
+ long delta = (long)(tzoff!=-1?tzoff:0);
+
+ if((delta>0) && (t > LONG_MAX - delta)) {
+ *output = 0x7fffffff;
+ return PARSEDATE_LATER; /* time_t overflow */
+ }
+
+ t += delta;
+ }
+
+ *output = t;
+
+ return PARSEDATE_OK;
+}
+
+time_t curl_getdate(const char *p, const time_t *now)
+{
+ time_t parsed = -1;
+ int rc = parsedate(p, &parsed);
+ (void)now; /* legacy argument from the past that we ignore */
+
+ switch(rc) {
+ case PARSEDATE_OK:
+ case PARSEDATE_LATER:
+ case PARSEDATE_SOONER:
+ return parsed;
+ }
+ /* everything else is fail */
+ return -1;
+}
+
+/*
+ * Curl_gmtime() is a gmtime() replacement for portability. Do not use the
+ * gmtime_r() or gmtime() functions anywhere else but here.
+ *
+ */
+
+CURLcode Curl_gmtime(time_t intime, struct tm *store)
+{
+ const struct tm *tm;
+#ifdef HAVE_GMTIME_R
+ /* thread-safe version */
+ tm = (struct tm *)gmtime_r(&intime, store);
+#else
+ tm = gmtime(&intime);
+ if(tm)
+ *store = *tm; /* copy the pointed struct to the local copy */
+#endif
+
+ if(!tm)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ return CURLE_OK;
+}
diff --git a/Utilities/cmcurl/lib/parsedate.h b/Utilities/cmcurl/lib/parsedate.h
new file mode 100644
index 000000000..ade0f4f60
--- /dev/null
+++ b/Utilities/cmcurl/lib/parsedate.h
@@ -0,0 +1,31 @@
+#ifndef HEADER_CURL_PARSEDATE_H
+#define HEADER_CURL_PARSEDATE_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+extern const char * const Curl_wkday[7];
+extern const char * const Curl_month[12];
+
+CURLcode Curl_gmtime(time_t intime, struct tm *store);
+
+#endif /* HEADER_CURL_PARSEDATE_H */
+
diff --git a/Utilities/cmcurl/lib/pingpong.c b/Utilities/cmcurl/lib/pingpong.c
new file mode 100644
index 000000000..167079272
--- /dev/null
+++ b/Utilities/cmcurl/lib/pingpong.c
@@ -0,0 +1,507 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * 'pingpong' is for generic back-and-forth support functions used by FTP,
+ * IMAP, POP3, SMTP and whatever more that likes them.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "urldata.h"
+#include "sendf.h"
+#include "select.h"
+#include "progress.h"
+#include "speedcheck.h"
+#include "pingpong.h"
+#include "multiif.h"
+#include "non-ascii.h"
+#include "vtls/vtls.h"
+#include "curl_printf.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#ifdef USE_PINGPONG
+
+/* Returns timeout in ms. 0 or negative number means the timeout has already
+ triggered */
+long Curl_pp_state_timeout(struct pingpong *pp)
+{
+ struct connectdata *conn = pp->conn;
+ struct SessionHandle *data=conn->data;
+ long timeout_ms; /* in milliseconds */
+ long timeout2_ms; /* in milliseconds */
+ long response_time= (data->set.server_response_timeout)?
+ data->set.server_response_timeout: pp->response_time;
+
+ /* if CURLOPT_SERVER_RESPONSE_TIMEOUT is set, use that to determine
+ remaining time, or use pp->response because SERVER_RESPONSE_TIMEOUT is
+ supposed to govern the response for any given server response, not for
+ the time from connect to the given server response. */
+
+ /* Without a requested timeout, we only wait 'response_time' seconds for the
+ full response to arrive before we bail out */
+ timeout_ms = response_time -
+ Curl_tvdiff(Curl_tvnow(), pp->response); /* spent time */
+
+ if(data->set.timeout) {
+ /* if timeout is requested, find out how much remaining time we have */
+ timeout2_ms = data->set.timeout - /* timeout time */
+ Curl_tvdiff(Curl_tvnow(), conn->now); /* spent time */
+
+ /* pick the lowest number */
+ timeout_ms = CURLMIN(timeout_ms, timeout2_ms);
+ }
+
+ return timeout_ms;
+}
+
+/*
+ * Curl_pp_statemach()
+ */
+CURLcode Curl_pp_statemach(struct pingpong *pp, bool block)
+{
+ struct connectdata *conn = pp->conn;
+ curl_socket_t sock = conn->sock[FIRSTSOCKET];
+ int rc;
+ long interval_ms;
+ long timeout_ms = Curl_pp_state_timeout(pp);
+ struct SessionHandle *data=conn->data;
+ CURLcode result = CURLE_OK;
+
+ if(timeout_ms <=0 ) {
+ failf(data, "server response timeout");
+ return CURLE_OPERATION_TIMEDOUT; /* already too little time */
+ }
+
+ if(block) {
+ interval_ms = 1000; /* use 1 second timeout intervals */
+ if(timeout_ms < interval_ms)
+ interval_ms = timeout_ms;
+ }
+ else
+ interval_ms = 0; /* immediate */
+
+ if(Curl_pp_moredata(pp))
+ /* We are receiving and there is data in the cache so just read it */
+ rc = 1;
+ else if(!pp->sendleft && Curl_ssl_data_pending(conn, FIRSTSOCKET))
+ /* We are receiving and there is data ready in the SSL library */
+ rc = 1;
+ else
+ rc = Curl_socket_ready(pp->sendleft?CURL_SOCKET_BAD:sock, /* reading */
+ pp->sendleft?sock:CURL_SOCKET_BAD, /* writing */
+ interval_ms);
+
+ if(block) {
+ /* if we didn't wait, we don't have to spend time on this now */
+ if(Curl_pgrsUpdate(conn))
+ result = CURLE_ABORTED_BY_CALLBACK;
+ else
+ result = Curl_speedcheck(data, Curl_tvnow());
+
+ if(result)
+ return result;
+ }
+
+ if(rc == -1) {
+ failf(data, "select/poll error");
+ result = CURLE_OUT_OF_MEMORY;
+ }
+ else if(rc)
+ result = pp->statemach_act(conn);
+
+ return result;
+}
+
+/* initialize stuff to prepare for reading a fresh new response */
+void Curl_pp_init(struct pingpong *pp)
+{
+ struct connectdata *conn = pp->conn;
+ pp->nread_resp = 0;
+ pp->linestart_resp = conn->data->state.buffer;
+ pp->pending_resp = TRUE;
+ pp->response = Curl_tvnow(); /* start response time-out now! */
+}
+
+
+
+/***********************************************************************
+ *
+ * Curl_pp_vsendf()
+ *
+ * Send the formated string as a command to a pingpong server. Note that
+ * the string should not have any CRLF appended, as this function will
+ * append the necessary things itself.
+ *
+ * made to never block
+ */
+CURLcode Curl_pp_vsendf(struct pingpong *pp,
+ const char *fmt,
+ va_list args)
+{
+ ssize_t bytes_written;
+ size_t write_len;
+ char *fmt_crlf;
+ char *s;
+ CURLcode result;
+ struct connectdata *conn = pp->conn;
+ struct SessionHandle *data = conn->data;
+
+#ifdef HAVE_GSSAPI
+ enum protection_level data_sec = conn->data_prot;
+#endif
+
+ DEBUGASSERT(pp->sendleft == 0);
+ DEBUGASSERT(pp->sendsize == 0);
+ DEBUGASSERT(pp->sendthis == NULL);
+
+ fmt_crlf = aprintf("%s\r\n", fmt); /* append a trailing CRLF */
+ if(!fmt_crlf)
+ return CURLE_OUT_OF_MEMORY;
+
+ s = vaprintf(fmt_crlf, args); /* trailing CRLF appended */
+ free(fmt_crlf);
+ if(!s)
+ return CURLE_OUT_OF_MEMORY;
+
+ bytes_written = 0;
+ write_len = strlen(s);
+
+ Curl_pp_init(pp);
+
+ result = Curl_convert_to_network(data, s, write_len);
+ /* Curl_convert_to_network calls failf if unsuccessful */
+ if(result) {
+ free(s);
+ return result;
+ }
+
+#ifdef HAVE_GSSAPI
+ conn->data_prot = PROT_CMD;
+#endif
+ result = Curl_write(conn, conn->sock[FIRSTSOCKET], s, write_len,
+ &bytes_written);
+#ifdef HAVE_GSSAPI
+ DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST);
+ conn->data_prot = data_sec;
+#endif
+
+ if(result) {
+ free(s);
+ return result;
+ }
+
+ if(conn->data->set.verbose)
+ Curl_debug(conn->data, CURLINFO_HEADER_OUT,
+ s, (size_t)bytes_written, conn);
+
+ if(bytes_written != (ssize_t)write_len) {
+ /* the whole chunk was not sent, keep it around and adjust sizes */
+ pp->sendthis = s;
+ pp->sendsize = write_len;
+ pp->sendleft = write_len - bytes_written;
+ }
+ else {
+ free(s);
+ pp->sendthis = NULL;
+ pp->sendleft = pp->sendsize = 0;
+ pp->response = Curl_tvnow();
+ }
+
+ return CURLE_OK;
+}
+
+
+/***********************************************************************
+ *
+ * Curl_pp_sendf()
+ *
+ * Send the formated string as a command to a pingpong server. Note that
+ * the string should not have any CRLF appended, as this function will
+ * append the necessary things itself.
+ *
+ * made to never block
+ */
+CURLcode Curl_pp_sendf(struct pingpong *pp,
+ const char *fmt, ...)
+{
+ CURLcode result;
+ va_list ap;
+ va_start(ap, fmt);
+
+ result = Curl_pp_vsendf(pp, fmt, ap);
+
+ va_end(ap);
+
+ return result;
+}
+
+/*
+ * Curl_pp_readresp()
+ *
+ * Reads a piece of a server response.
+ */
+CURLcode Curl_pp_readresp(curl_socket_t sockfd,
+ struct pingpong *pp,
+ int *code, /* return the server code if done */
+ size_t *size) /* size of the response */
+{
+ ssize_t perline; /* count bytes per line */
+ bool keepon=TRUE;
+ ssize_t gotbytes;
+ char *ptr;
+ struct connectdata *conn = pp->conn;
+ struct SessionHandle *data = conn->data;
+ char * const buf = data->state.buffer;
+ CURLcode result = CURLE_OK;
+
+ *code = 0; /* 0 for errors or not done */
+ *size = 0;
+
+ ptr=buf + pp->nread_resp;
+
+ /* number of bytes in the current line, so far */
+ perline = (ssize_t)(ptr-pp->linestart_resp);
+
+ while((pp->nread_resp<BUFSIZE) && (keepon && !result)) {
+
+ if(pp->cache) {
+ /* we had data in the "cache", copy that instead of doing an actual
+ * read
+ *
+ * pp->cache_size is cast to ssize_t here. This should be safe, because
+ * it would have been populated with something of size int to begin
+ * with, even though its datatype may be larger than an int.
+ */
+ DEBUGASSERT((ptr+pp->cache_size) <= (buf+BUFSIZE+1));
+ memcpy(ptr, pp->cache, pp->cache_size);
+ gotbytes = (ssize_t)pp->cache_size;
+ free(pp->cache); /* free the cache */
+ pp->cache = NULL; /* clear the pointer */
+ pp->cache_size = 0; /* zero the size just in case */
+ }
+ else {
+#ifdef HAVE_GSSAPI
+ enum protection_level prot = conn->data_prot;
+ conn->data_prot = PROT_CLEAR;
+#endif
+ DEBUGASSERT((ptr+BUFSIZE-pp->nread_resp) <= (buf+BUFSIZE+1));
+ result = Curl_read(conn, sockfd, ptr, BUFSIZE-pp->nread_resp,
+ &gotbytes);
+#ifdef HAVE_GSSAPI
+ DEBUGASSERT(prot > PROT_NONE && prot < PROT_LAST);
+ conn->data_prot = prot;
+#endif
+ if(result == CURLE_AGAIN)
+ return CURLE_OK; /* return */
+
+ if(!result && (gotbytes > 0))
+ /* convert from the network encoding */
+ result = Curl_convert_from_network(data, ptr, gotbytes);
+ /* Curl_convert_from_network calls failf if unsuccessful */
+
+ if(result)
+ /* Set outer result variable to this error. */
+ keepon = FALSE;
+ }
+
+ if(!keepon)
+ ;
+ else if(gotbytes <= 0) {
+ keepon = FALSE;
+ result = CURLE_RECV_ERROR;
+ failf(data, "response reading failed");
+ }
+ else {
+ /* we got a whole chunk of data, which can be anything from one
+ * byte to a set of lines and possible just a piece of the last
+ * line */
+ ssize_t i;
+ ssize_t clipamount = 0;
+ bool restart = FALSE;
+
+ data->req.headerbytecount += (long)gotbytes;
+
+ pp->nread_resp += gotbytes;
+ for(i = 0; i < gotbytes; ptr++, i++) {
+ perline++;
+ if(*ptr=='\n') {
+ /* a newline is CRLF in pp-talk, so the CR is ignored as
+ the line isn't really terminated until the LF comes */
+
+ /* output debug output if that is requested */
+#ifdef HAVE_GSSAPI
+ if(!conn->sec_complete)
+#endif
+ if(data->set.verbose)
+ Curl_debug(data, CURLINFO_HEADER_IN,
+ pp->linestart_resp, (size_t)perline, conn);
+
+ /*
+ * We pass all response-lines to the callback function registered
+ * for "headers". The response lines can be seen as a kind of
+ * headers.
+ */
+ result = Curl_client_write(conn, CLIENTWRITE_HEADER,
+ pp->linestart_resp, perline);
+ if(result)
+ return result;
+
+ if(pp->endofresp(conn, pp->linestart_resp, perline, code)) {
+ /* This is the end of the last line, copy the last line to the
+ start of the buffer and zero terminate, for old times sake */
+ size_t n = ptr - pp->linestart_resp;
+ memmove(buf, pp->linestart_resp, n);
+ buf[n]=0; /* zero terminate */
+ keepon=FALSE;
+ pp->linestart_resp = ptr+1; /* advance pointer */
+ i++; /* skip this before getting out */
+
+ *size = pp->nread_resp; /* size of the response */
+ pp->nread_resp = 0; /* restart */
+ break;
+ }
+ perline=0; /* line starts over here */
+ pp->linestart_resp = ptr+1;
+ }
+ }
+
+ if(!keepon && (i != gotbytes)) {
+ /* We found the end of the response lines, but we didn't parse the
+ full chunk of data we have read from the server. We therefore need
+ to store the rest of the data to be checked on the next invoke as
+ it may actually contain another end of response already! */
+ clipamount = gotbytes - i;
+ restart = TRUE;
+ DEBUGF(infof(data, "Curl_pp_readresp_ %d bytes of trailing "
+ "server response left\n",
+ (int)clipamount));
+ }
+ else if(keepon) {
+
+ if((perline == gotbytes) && (gotbytes > BUFSIZE/2)) {
+ /* We got an excessive line without newlines and we need to deal
+ with it. We keep the first bytes of the line then we throw
+ away the rest. */
+ infof(data, "Excessive server response line length received, "
+ "%zd bytes. Stripping\n", gotbytes);
+ restart = TRUE;
+
+ /* we keep 40 bytes since all our pingpong protocols are only
+ interested in the first piece */
+ clipamount = 40;
+ }
+ else if(pp->nread_resp > BUFSIZE/2) {
+ /* We got a large chunk of data and there's potentially still
+ trailing data to take care of, so we put any such part in the
+ "cache", clear the buffer to make space and restart. */
+ clipamount = perline;
+ restart = TRUE;
+ }
+ }
+ else if(i == gotbytes)
+ restart = TRUE;
+
+ if(clipamount) {
+ pp->cache_size = clipamount;
+ pp->cache = malloc(pp->cache_size);
+ if(pp->cache)
+ memcpy(pp->cache, pp->linestart_resp, pp->cache_size);
+ else
+ return CURLE_OUT_OF_MEMORY;
+ }
+ if(restart) {
+ /* now reset a few variables to start over nicely from the start of
+ the big buffer */
+ pp->nread_resp = 0; /* start over from scratch in the buffer */
+ ptr = pp->linestart_resp = buf;
+ perline = 0;
+ }
+
+ } /* there was data */
+
+ } /* while there's buffer left and loop is requested */
+
+ pp->pending_resp = FALSE;
+
+ return result;
+}
+
+int Curl_pp_getsock(struct pingpong *pp,
+ curl_socket_t *socks,
+ int numsocks)
+{
+ struct connectdata *conn = pp->conn;
+
+ if(!numsocks)
+ return GETSOCK_BLANK;
+
+ socks[0] = conn->sock[FIRSTSOCKET];
+
+ if(pp->sendleft) {
+ /* write mode */
+ return GETSOCK_WRITESOCK(0);
+ }
+
+ /* read mode */
+ return GETSOCK_READSOCK(0);
+}
+
+CURLcode Curl_pp_flushsend(struct pingpong *pp)
+{
+ /* we have a piece of a command still left to send */
+ struct connectdata *conn = pp->conn;
+ ssize_t written;
+ curl_socket_t sock = conn->sock[FIRSTSOCKET];
+ CURLcode result = Curl_write(conn, sock, pp->sendthis + pp->sendsize -
+ pp->sendleft, pp->sendleft, &written);
+ if(result)
+ return result;
+
+ if(written != (ssize_t)pp->sendleft) {
+ /* only a fraction was sent */
+ pp->sendleft -= written;
+ }
+ else {
+ free(pp->sendthis);
+ pp->sendthis=NULL;
+ pp->sendleft = pp->sendsize = 0;
+ pp->response = Curl_tvnow();
+ }
+ return CURLE_OK;
+}
+
+CURLcode Curl_pp_disconnect(struct pingpong *pp)
+{
+ free(pp->cache);
+ pp->cache = NULL;
+ return CURLE_OK;
+}
+
+bool Curl_pp_moredata(struct pingpong *pp)
+{
+ return (!pp->sendleft && pp->cache && pp->nread_resp < pp->cache_size) ?
+ TRUE : FALSE;
+}
+
+#endif
diff --git a/Utilities/cmcurl/lib/pingpong.h b/Utilities/cmcurl/lib/pingpong.h
new file mode 100644
index 000000000..b925ab98e
--- /dev/null
+++ b/Utilities/cmcurl/lib/pingpong.h
@@ -0,0 +1,150 @@
+#ifndef HEADER_CURL_PINGPONG_H
+#define HEADER_CURL_PINGPONG_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_IMAP) || !defined(CURL_DISABLE_FTP) || \
+ !defined(CURL_DISABLE_POP3) || !defined(CURL_DISABLE_SMTP)
+#define USE_PINGPONG
+#endif
+
+/* forward-declaration, this is defined in urldata.h */
+struct connectdata;
+
+typedef enum {
+ FTPTRANSFER_BODY, /* yes do transfer a body */
+ FTPTRANSFER_INFO, /* do still go through to get info/headers */
+ FTPTRANSFER_NONE, /* don't get anything and don't get info */
+ FTPTRANSFER_LAST /* end of list marker, never used */
+} curl_pp_transfer;
+
+/*
+ * 'pingpong' is the generic struct used for protocols doing server<->client
+ * conversations in a back-and-forth style such as FTP, IMAP, POP3, SMTP etc.
+ *
+ * It holds response cache and non-blocking sending data.
+ */
+struct pingpong {
+ char *cache; /* data cache between getresponse()-calls */
+ size_t cache_size; /* size of cache in bytes */
+ size_t nread_resp; /* number of bytes currently read of a server response */
+ char *linestart_resp; /* line start pointer for the server response
+ reader function */
+ bool pending_resp; /* set TRUE when a server response is pending or in
+ progress, and is cleared once the last response is
+ read */
+ char *sendthis; /* allocated pointer to a buffer that is to be sent to the
+ server */
+ size_t sendleft; /* number of bytes left to send from the sendthis buffer */
+ size_t sendsize; /* total size of the sendthis buffer */
+ struct timeval response; /* set to Curl_tvnow() when a command has been sent
+ off, used to time-out response reading */
+ long response_time; /* When no timeout is given, this is the amount of
+ milliseconds we await for a server response. */
+
+ struct connectdata *conn; /* points to the connectdata struct that this
+ belongs to */
+
+ /* Function pointers the protocols MUST implement and provide for the
+ pingpong layer to function */
+
+ CURLcode (*statemach_act)(struct connectdata *conn);
+
+ bool (*endofresp)(struct connectdata *conn, char *ptr, size_t len,
+ int *code);
+};
+
+/*
+ * Curl_pp_statemach()
+ *
+ * called repeatedly until done. Set 'wait' to make it wait a while on the
+ * socket if there's no traffic.
+ */
+CURLcode Curl_pp_statemach(struct pingpong *pp, bool block);
+
+/* initialize stuff to prepare for reading a fresh new response */
+void Curl_pp_init(struct pingpong *pp);
+
+/* Returns timeout in ms. 0 or negative number means the timeout has already
+ triggered */
+long Curl_pp_state_timeout(struct pingpong *pp);
+
+
+/***********************************************************************
+ *
+ * Curl_pp_sendf()
+ *
+ * Send the formated string as a command to a pingpong server. Note that
+ * the string should not have any CRLF appended, as this function will
+ * append the necessary things itself.
+ *
+ * made to never block
+ */
+CURLcode Curl_pp_sendf(struct pingpong *pp,
+ const char *fmt, ...);
+
+/***********************************************************************
+ *
+ * Curl_pp_vsendf()
+ *
+ * Send the formated string as a command to a pingpong server. Note that
+ * the string should not have any CRLF appended, as this function will
+ * append the necessary things itself.
+ *
+ * made to never block
+ */
+CURLcode Curl_pp_vsendf(struct pingpong *pp,
+ const char *fmt,
+ va_list args);
+
+/*
+ * Curl_pp_readresp()
+ *
+ * Reads a piece of a server response.
+ */
+CURLcode Curl_pp_readresp(curl_socket_t sockfd,
+ struct pingpong *pp,
+ int *code, /* return the server code if done */
+ size_t *size); /* size of the response */
+
+
+CURLcode Curl_pp_flushsend(struct pingpong *pp);
+
+/* call this when a pingpong connection is disconnected */
+CURLcode Curl_pp_disconnect(struct pingpong *pp);
+
+int Curl_pp_getsock(struct pingpong *pp, curl_socket_t *socks,
+ int numsocks);
+
+
+/***********************************************************************
+ *
+ * Curl_pp_moredata()
+ *
+ * Returns whether there are still more data in the cache and so a call
+ * to Curl_pp_readresp() will not block.
+ */
+bool Curl_pp_moredata(struct pingpong *pp);
+
+#endif /* HEADER_CURL_PINGPONG_H */
diff --git a/Utilities/cmcurl/lib/pipeline.c b/Utilities/cmcurl/lib/pipeline.c
new file mode 100644
index 000000000..1b38836cb
--- /dev/null
+++ b/Utilities/cmcurl/lib/pipeline.c
@@ -0,0 +1,433 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2013, Linus Nielsen Feltzing, <linus@haxx.se>
+ * Copyright (C) 2013-2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#include "urldata.h"
+#include "url.h"
+#include "progress.h"
+#include "multiif.h"
+#include "pipeline.h"
+#include "sendf.h"
+#include "rawstr.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+struct site_blacklist_entry {
+ char *hostname;
+ unsigned short port;
+};
+
+static void site_blacklist_llist_dtor(void *user, void *element)
+{
+ struct site_blacklist_entry *entry = element;
+ (void)user;
+
+ Curl_safefree(entry->hostname);
+ free(entry);
+}
+
+static void server_blacklist_llist_dtor(void *user, void *element)
+{
+ (void)user;
+ free(element);
+}
+
+bool Curl_pipeline_penalized(struct SessionHandle *data,
+ struct connectdata *conn)
+{
+ if(data) {
+ bool penalized = FALSE;
+ curl_off_t penalty_size =
+ Curl_multi_content_length_penalty_size(data->multi);
+ curl_off_t chunk_penalty_size =
+ Curl_multi_chunk_length_penalty_size(data->multi);
+ curl_off_t recv_size = -2; /* Make it easy to spot in the log */
+
+ /* Find the head of the recv pipe, if any */
+ if(conn->recv_pipe && conn->recv_pipe->head) {
+ struct SessionHandle *recv_handle = conn->recv_pipe->head->ptr;
+
+ recv_size = recv_handle->req.size;
+
+ if(penalty_size > 0 && recv_size > penalty_size)
+ penalized = TRUE;
+ }
+
+ if(chunk_penalty_size > 0 &&
+ (curl_off_t)conn->chunk.datasize > chunk_penalty_size)
+ penalized = TRUE;
+
+ infof(data, "Conn: %ld (%p) Receive pipe weight: (%"
+ CURL_FORMAT_CURL_OFF_T "/%zu), penalized: %s\n",
+ conn->connection_id, (void *)conn, recv_size,
+ conn->chunk.datasize, penalized?"TRUE":"FALSE");
+ return penalized;
+ }
+ return FALSE;
+}
+
+static CURLcode addHandleToPipeline(struct SessionHandle *data,
+ struct curl_llist *pipeline)
+{
+ if(!Curl_llist_insert_next(pipeline, pipeline->tail, data))
+ return CURLE_OUT_OF_MEMORY;
+ return CURLE_OK;
+}
+
+
+CURLcode Curl_add_handle_to_pipeline(struct SessionHandle *handle,
+ struct connectdata *conn)
+{
+ struct curl_llist_element *sendhead = conn->send_pipe->head;
+ struct curl_llist *pipeline;
+ CURLcode result;
+
+ pipeline = conn->send_pipe;
+
+ result = addHandleToPipeline(handle, pipeline);
+
+ if(pipeline == conn->send_pipe && sendhead != conn->send_pipe->head) {
+ /* this is a new one as head, expire it */
+ Curl_pipeline_leave_write(conn); /* not in use yet */
+ Curl_expire(conn->send_pipe->head->ptr, 1);
+ }
+
+#if 0 /* enable for pipeline debugging */
+ print_pipeline(conn);
+#endif
+
+ return result;
+}
+
+/* Move this transfer from the sending list to the receiving list.
+
+ Pay special attention to the new sending list "leader" as it needs to get
+ checked to update what sockets it acts on.
+
+*/
+void Curl_move_handle_from_send_to_recv_pipe(struct SessionHandle *handle,
+ struct connectdata *conn)
+{
+ struct curl_llist_element *curr;
+
+ curr = conn->send_pipe->head;
+ while(curr) {
+ if(curr->ptr == handle) {
+ Curl_llist_move(conn->send_pipe, curr,
+ conn->recv_pipe, conn->recv_pipe->tail);
+
+ if(conn->send_pipe->head) {
+ /* Since there's a new easy handle at the start of the send pipeline,
+ set its timeout value to 1ms to make it trigger instantly */
+ Curl_pipeline_leave_write(conn); /* not used now */
+#ifdef DEBUGBUILD
+ infof(conn->data, "%p is at send pipe head B!\n",
+ (void *)conn->send_pipe->head->ptr);
+#endif
+ Curl_expire(conn->send_pipe->head->ptr, 1);
+ }
+
+ /* The receiver's list is not really interesting here since either this
+ handle is now first in the list and we'll deal with it soon, or
+ another handle is already first and thus is already taken care of */
+
+ break; /* we're done! */
+ }
+ curr = curr->next;
+ }
+}
+
+bool Curl_pipeline_site_blacklisted(struct SessionHandle *handle,
+ struct connectdata *conn)
+{
+ if(handle->multi) {
+ struct curl_llist *blacklist =
+ Curl_multi_pipelining_site_bl(handle->multi);
+
+ if(blacklist) {
+ struct curl_llist_element *curr;
+
+ curr = blacklist->head;
+ while(curr) {
+ struct site_blacklist_entry *site;
+
+ site = curr->ptr;
+ if(Curl_raw_equal(site->hostname, conn->host.name) &&
+ site->port == conn->remote_port) {
+ infof(handle, "Site %s:%d is pipeline blacklisted\n",
+ conn->host.name, conn->remote_port);
+ return TRUE;
+ }
+ curr = curr->next;
+ }
+ }
+ }
+ return FALSE;
+}
+
+CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
+ struct curl_llist **list_ptr)
+{
+ struct curl_llist *old_list = *list_ptr;
+ struct curl_llist *new_list = NULL;
+
+ if(sites) {
+ new_list = Curl_llist_alloc((curl_llist_dtor) site_blacklist_llist_dtor);
+ if(!new_list)
+ return CURLM_OUT_OF_MEMORY;
+
+ /* Parse the URLs and populate the list */
+ while(*sites) {
+ char *hostname;
+ char *port;
+ struct site_blacklist_entry *entry;
+
+ hostname = strdup(*sites);
+ if(!hostname) {
+ Curl_llist_destroy(new_list, NULL);
+ return CURLM_OUT_OF_MEMORY;
+ }
+
+ entry = malloc(sizeof(struct site_blacklist_entry));
+ if(!entry) {
+ free(hostname);
+ Curl_llist_destroy(new_list, NULL);
+ return CURLM_OUT_OF_MEMORY;
+ }
+
+ port = strchr(hostname, ':');
+ if(port) {
+ *port = '\0';
+ port++;
+ entry->port = (unsigned short)strtol(port, NULL, 10);
+ }
+ else {
+ /* Default port number for HTTP */
+ entry->port = 80;
+ }
+
+ entry->hostname = hostname;
+
+ if(!Curl_llist_insert_next(new_list, new_list->tail, entry)) {
+ site_blacklist_llist_dtor(NULL, entry);
+ Curl_llist_destroy(new_list, NULL);
+ return CURLM_OUT_OF_MEMORY;
+ }
+
+ sites++;
+ }
+ }
+
+ /* Free the old list */
+ if(old_list) {
+ Curl_llist_destroy(old_list, NULL);
+ }
+
+ /* This might be NULL if sites == NULL, i.e the blacklist is cleared */
+ *list_ptr = new_list;
+
+ return CURLM_OK;
+}
+
+bool Curl_pipeline_server_blacklisted(struct SessionHandle *handle,
+ char *server_name)
+{
+ if(handle->multi && server_name) {
+ struct curl_llist *blacklist =
+ Curl_multi_pipelining_server_bl(handle->multi);
+
+ if(blacklist) {
+ struct curl_llist_element *curr;
+
+ curr = blacklist->head;
+ while(curr) {
+ char *bl_server_name;
+
+ bl_server_name = curr->ptr;
+ if(Curl_raw_nequal(bl_server_name, server_name,
+ strlen(bl_server_name))) {
+ infof(handle, "Server %s is blacklisted\n", server_name);
+ return TRUE;
+ }
+ curr = curr->next;
+ }
+ }
+
+ DEBUGF(infof(handle, "Server %s is not blacklisted\n", server_name));
+ }
+ return FALSE;
+}
+
+CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
+ struct curl_llist **list_ptr)
+{
+ struct curl_llist *old_list = *list_ptr;
+ struct curl_llist *new_list = NULL;
+
+ if(servers) {
+ new_list = Curl_llist_alloc((curl_llist_dtor) server_blacklist_llist_dtor);
+ if(!new_list)
+ return CURLM_OUT_OF_MEMORY;
+
+ /* Parse the URLs and populate the list */
+ while(*servers) {
+ char *server_name;
+
+ server_name = strdup(*servers);
+ if(!server_name)
+ return CURLM_OUT_OF_MEMORY;
+
+ if(!Curl_llist_insert_next(new_list, new_list->tail, server_name))
+ return CURLM_OUT_OF_MEMORY;
+
+ servers++;
+ }
+ }
+
+ /* Free the old list */
+ if(old_list) {
+ Curl_llist_destroy(old_list, NULL);
+ }
+
+ /* This might be NULL if sites == NULL, i.e the blacklist is cleared */
+ *list_ptr = new_list;
+
+ return CURLM_OK;
+}
+
+static bool pipe_head(struct SessionHandle *data,
+ struct curl_llist *pipeline)
+{
+ struct curl_llist_element *curr = pipeline->head;
+ if(curr)
+ return (curr->ptr == data) ? TRUE : FALSE;
+
+ return FALSE;
+}
+
+/* returns TRUE if the given handle is head of the recv pipe */
+bool Curl_recvpipe_head(struct SessionHandle *data,
+ struct connectdata *conn)
+{
+ return pipe_head(data, conn->recv_pipe);
+}
+
+/* returns TRUE if the given handle is head of the send pipe */
+bool Curl_sendpipe_head(struct SessionHandle *data,
+ struct connectdata *conn)
+{
+ return pipe_head(data, conn->send_pipe);
+}
+
+
+/*
+ * Check if the write channel is available and this handle as at the head,
+ * then grab the channel and return TRUE.
+ *
+ * If not available, return FALSE.
+ */
+
+bool Curl_pipeline_checkget_write(struct SessionHandle *data,
+ struct connectdata *conn)
+{
+ if(conn->bits.multiplex)
+ /* when multiplexing, we can use it at once */
+ return TRUE;
+
+ if(!conn->writechannel_inuse && Curl_sendpipe_head(data, conn)) {
+ /* Grab the channel */
+ conn->writechannel_inuse = TRUE;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*
+ * Check if the read channel is available and this handle as at the head, then
+ * grab the channel and return TRUE.
+ *
+ * If not available, return FALSE.
+ */
+
+bool Curl_pipeline_checkget_read(struct SessionHandle *data,
+ struct connectdata *conn)
+{
+ if(conn->bits.multiplex)
+ /* when multiplexing, we can use it at once */
+ return TRUE;
+
+ if(!conn->readchannel_inuse && Curl_recvpipe_head(data, conn)) {
+ /* Grab the channel */
+ conn->readchannel_inuse = TRUE;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * The current user of the pipeline write channel gives it up.
+ */
+void Curl_pipeline_leave_write(struct connectdata *conn)
+{
+ conn->writechannel_inuse = FALSE;
+}
+
+/*
+ * The current user of the pipeline read channel gives it up.
+ */
+void Curl_pipeline_leave_read(struct connectdata *conn)
+{
+ conn->readchannel_inuse = FALSE;
+}
+
+
+#if 0
+void print_pipeline(struct connectdata *conn)
+{
+ struct curl_llist_element *curr;
+ struct connectbundle *cb_ptr;
+ struct SessionHandle *data = conn->data;
+
+ cb_ptr = conn->bundle;
+
+ if(cb_ptr) {
+ curr = cb_ptr->conn_list->head;
+ while(curr) {
+ conn = curr->ptr;
+ infof(data, "- Conn %ld (%p) send_pipe: %zu, recv_pipe: %zu\n",
+ conn->connection_id,
+ (void *)conn,
+ conn->send_pipe->size,
+ conn->recv_pipe->size);
+ curr = curr->next;
+ }
+ }
+}
+
+#endif
diff --git a/Utilities/cmcurl/lib/pipeline.h b/Utilities/cmcurl/lib/pipeline.h
new file mode 100644
index 000000000..bf229f199
--- /dev/null
+++ b/Utilities/cmcurl/lib/pipeline.h
@@ -0,0 +1,56 @@
+#ifndef HEADER_CURL_PIPELINE_H
+#define HEADER_CURL_PIPELINE_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2013 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+CURLcode Curl_add_handle_to_pipeline(struct SessionHandle *handle,
+ struct connectdata *conn);
+void Curl_move_handle_from_send_to_recv_pipe(struct SessionHandle *handle,
+ struct connectdata *conn);
+bool Curl_pipeline_penalized(struct SessionHandle *data,
+ struct connectdata *conn);
+
+bool Curl_pipeline_site_blacklisted(struct SessionHandle *handle,
+ struct connectdata *conn);
+
+CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
+ struct curl_llist **list_ptr);
+
+bool Curl_pipeline_server_blacklisted(struct SessionHandle *handle,
+ char *server_name);
+
+CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
+ struct curl_llist **list_ptr);
+
+bool Curl_pipeline_checkget_write(struct SessionHandle *data,
+ struct connectdata *conn);
+bool Curl_pipeline_checkget_read(struct SessionHandle *data,
+ struct connectdata *conn);
+void Curl_pipeline_leave_write(struct connectdata *conn);
+void Curl_pipeline_leave_read(struct connectdata *conn);
+bool Curl_recvpipe_head(struct SessionHandle *data,
+ struct connectdata *conn);
+bool Curl_sendpipe_head(struct SessionHandle *data,
+ struct connectdata *conn);
+
+#endif /* HEADER_CURL_PIPELINE_H */
diff --git a/Utilities/cmcurl/lib/pop3.c b/Utilities/cmcurl/lib/pop3.c
new file mode 100644
index 000000000..53510a210
--- /dev/null
+++ b/Utilities/cmcurl/lib/pop3.c
@@ -0,0 +1,1601 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * RFC1734 POP3 Authentication
+ * RFC1939 POP3 protocol
+ * RFC2195 CRAM-MD5 authentication
+ * RFC2384 POP URL Scheme
+ * RFC2449 POP3 Extension Mechanism
+ * RFC2595 Using TLS with IMAP, POP3 and ACAP
+ * RFC2831 DIGEST-MD5 authentication
+ * RFC4422 Simple Authentication and Security Layer (SASL)
+ * RFC4616 PLAIN authentication
+ * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism
+ * RFC5034 POP3 SASL Authentication Mechanism
+ * RFC6749 OAuth 2.0 Authorization Framework
+ * Draft LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_POP3
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "progress.h"
+#include "transfer.h"
+#include "escape.h"
+#include "http.h" /* for HTTP proxy tunnel stuff */
+#include "socks.h"
+#include "pop3.h"
+
+#include "strtoofft.h"
+#include "strequal.h"
+#include "vtls/vtls.h"
+#include "connect.h"
+#include "strerror.h"
+#include "select.h"
+#include "multiif.h"
+#include "url.h"
+#include "rawstr.h"
+#include "curl_sasl.h"
+#include "curl_md5.h"
+#include "warnless.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* Local API functions */
+static CURLcode pop3_regular_transfer(struct connectdata *conn, bool *done);
+static CURLcode pop3_do(struct connectdata *conn, bool *done);
+static CURLcode pop3_done(struct connectdata *conn, CURLcode status,
+ bool premature);
+static CURLcode pop3_connect(struct connectdata *conn, bool *done);
+static CURLcode pop3_disconnect(struct connectdata *conn, bool dead);
+static CURLcode pop3_multi_statemach(struct connectdata *conn, bool *done);
+static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks,
+ int numsocks);
+static CURLcode pop3_doing(struct connectdata *conn, bool *dophase_done);
+static CURLcode pop3_setup_connection(struct connectdata *conn);
+static CURLcode pop3_parse_url_options(struct connectdata *conn);
+static CURLcode pop3_parse_url_path(struct connectdata *conn);
+static CURLcode pop3_parse_custom_request(struct connectdata *conn);
+static CURLcode pop3_perform_auth(struct connectdata *conn, const char *mech,
+ const char *initresp);
+static CURLcode pop3_continue_auth(struct connectdata *conn, const char *resp);
+static void pop3_get_message(char *buffer, char** outptr);
+
+/*
+ * POP3 protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_pop3 = {
+ "POP3", /* scheme */
+ pop3_setup_connection, /* setup_connection */
+ pop3_do, /* do_it */
+ pop3_done, /* done */
+ ZERO_NULL, /* do_more */
+ pop3_connect, /* connect_it */
+ pop3_multi_statemach, /* connecting */
+ pop3_doing, /* doing */
+ pop3_getsock, /* proto_getsock */
+ pop3_getsock, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ pop3_disconnect, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_POP3, /* defport */
+ CURLPROTO_POP3, /* protocol */
+ PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY /* flags */
+};
+
+#ifdef USE_SSL
+/*
+ * POP3S protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_pop3s = {
+ "POP3S", /* scheme */
+ pop3_setup_connection, /* setup_connection */
+ pop3_do, /* do_it */
+ pop3_done, /* done */
+ ZERO_NULL, /* do_more */
+ pop3_connect, /* connect_it */
+ pop3_multi_statemach, /* connecting */
+ pop3_doing, /* doing */
+ pop3_getsock, /* proto_getsock */
+ pop3_getsock, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ pop3_disconnect, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_POP3S, /* defport */
+ CURLPROTO_POP3S, /* protocol */
+ PROTOPT_CLOSEACTION | PROTOPT_SSL
+ | PROTOPT_NOURLQUERY /* flags */
+};
+#endif
+
+#ifndef CURL_DISABLE_HTTP
+/*
+ * HTTP-proxyed POP3 protocol handler.
+ */
+
+static const struct Curl_handler Curl_handler_pop3_proxy = {
+ "POP3", /* scheme */
+ Curl_http_setup_conn, /* setup_connection */
+ Curl_http, /* do_it */
+ Curl_http_done, /* done */
+ ZERO_NULL, /* do_more */
+ ZERO_NULL, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_getsock */
+ ZERO_NULL, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ ZERO_NULL, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_POP3, /* defport */
+ CURLPROTO_HTTP, /* protocol */
+ PROTOPT_NONE /* flags */
+};
+
+#ifdef USE_SSL
+/*
+ * HTTP-proxyed POP3S protocol handler.
+ */
+
+static const struct Curl_handler Curl_handler_pop3s_proxy = {
+ "POP3S", /* scheme */
+ Curl_http_setup_conn, /* setup_connection */
+ Curl_http, /* do_it */
+ Curl_http_done, /* done */
+ ZERO_NULL, /* do_more */
+ ZERO_NULL, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_getsock */
+ ZERO_NULL, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ ZERO_NULL, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_POP3S, /* defport */
+ CURLPROTO_HTTP, /* protocol */
+ PROTOPT_NONE /* flags */
+};
+#endif
+#endif
+
+/* SASL parameters for the pop3 protocol */
+static const struct SASLproto saslpop3 = {
+ "pop", /* The service name */
+ '+', /* Code received when continuation is expected */
+ '+', /* Code to receive upon authentication success */
+ 255 - 8, /* Maximum initial response length (no max) */
+ pop3_perform_auth, /* Send authentication command */
+ pop3_continue_auth, /* Send authentication continuation */
+ pop3_get_message /* Get SASL response message */
+};
+
+#ifdef USE_SSL
+static void pop3_to_pop3s(struct connectdata *conn)
+{
+ conn->handler = &Curl_handler_pop3s;
+}
+#else
+#define pop3_to_pop3s(x) Curl_nop_stmt
+#endif
+
+/***********************************************************************
+ *
+ * pop3_endofresp()
+ *
+ * Checks for an ending POP3 status code at the start of the given string, but
+ * also detects the APOP timestamp from the server greeting and various
+ * capabilities from the CAPA response including the supported authentication
+ * types and allowed SASL mechanisms.
+ */
+static bool pop3_endofresp(struct connectdata *conn, char *line, size_t len,
+ int *resp)
+{
+ struct pop3_conn *pop3c = &conn->proto.pop3c;
+
+ /* Do we have an error response? */
+ if(len >= 4 && !memcmp("-ERR", line, 4)) {
+ *resp = '-';
+
+ return TRUE;
+ }
+
+ /* Are we processing CAPA command responses? */
+ if(pop3c->state == POP3_CAPA) {
+ /* Do we have the terminating line? */
+ if(len >= 1 && !memcmp(line, ".", 1))
+ *resp = '+';
+ else
+ *resp = '*';
+
+ return TRUE;
+ }
+
+ /* Do we have a command or continuation response? */
+ if((len >= 3 && !memcmp("+OK", line, 3)) ||
+ (len >= 1 && !memcmp("+", line, 1))) {
+ *resp = '+';
+
+ return TRUE;
+ }
+
+ return FALSE; /* Nothing for us */
+}
+
+/***********************************************************************
+ *
+ * pop3_get_message()
+ *
+ * Gets the authentication message from the response buffer.
+ */
+static void pop3_get_message(char *buffer, char** outptr)
+{
+ size_t len = 0;
+ char* message = NULL;
+
+ /* Find the start of the message */
+ for(message = buffer + 2; *message == ' ' || *message == '\t'; message++)
+ ;
+
+ /* Find the end of the message */
+ for(len = strlen(message); len--;)
+ if(message[len] != '\r' && message[len] != '\n' && message[len] != ' ' &&
+ message[len] != '\t')
+ break;
+
+ /* Terminate the message */
+ if(++len) {
+ message[len] = '\0';
+ }
+
+ *outptr = message;
+}
+
+/***********************************************************************
+ *
+ * state()
+ *
+ * This is the ONLY way to change POP3 state!
+ */
+static void state(struct connectdata *conn, pop3state newstate)
+{
+ struct pop3_conn *pop3c = &conn->proto.pop3c;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+ /* for debug purposes */
+ static const char * const names[] = {
+ "STOP",
+ "SERVERGREET",
+ "CAPA",
+ "STARTTLS",
+ "UPGRADETLS",
+ "AUTH",
+ "APOP",
+ "USER",
+ "PASS",
+ "COMMAND",
+ "QUIT",
+ /* LAST */
+ };
+
+ if(pop3c->state != newstate)
+ infof(conn->data, "POP3 %p state change from %s to %s\n",
+ (void *)pop3c, names[pop3c->state], names[newstate]);
+#endif
+
+ pop3c->state = newstate;
+}
+
+/***********************************************************************
+ *
+ * pop3_perform_capa()
+ *
+ * Sends the CAPA command in order to obtain a list of server side supported
+ * capabilities.
+ */
+static CURLcode pop3_perform_capa(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct pop3_conn *pop3c = &conn->proto.pop3c;
+
+ pop3c->sasl.authmechs = SASL_AUTH_NONE; /* No known auth. mechanisms yet */
+ pop3c->sasl.authused = SASL_AUTH_NONE; /* Clear the auth. mechanism used */
+ pop3c->tls_supported = FALSE; /* Clear the TLS capability */
+
+ /* Send the CAPA command */
+ result = Curl_pp_sendf(&pop3c->pp, "%s", "CAPA");
+
+ if(!result)
+ state(conn, POP3_CAPA);
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_perform_starttls()
+ *
+ * Sends the STLS command to start the upgrade to TLS.
+ */
+static CURLcode pop3_perform_starttls(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+
+ /* Send the STLS command */
+ result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "STLS");
+
+ if(!result)
+ state(conn, POP3_STARTTLS);
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_perform_upgrade_tls()
+ *
+ * Performs the upgrade to TLS.
+ */
+static CURLcode pop3_perform_upgrade_tls(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct pop3_conn *pop3c = &conn->proto.pop3c;
+
+ /* Start the SSL connection */
+ result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &pop3c->ssldone);
+
+ if(!result) {
+ if(pop3c->state != POP3_UPGRADETLS)
+ state(conn, POP3_UPGRADETLS);
+
+ if(pop3c->ssldone) {
+ pop3_to_pop3s(conn);
+ result = pop3_perform_capa(conn);
+ }
+ }
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_perform_user()
+ *
+ * Sends a clear text USER command to authenticate with.
+ */
+static CURLcode pop3_perform_user(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+
+ /* Check we have a username and password to authenticate with and end the
+ connect phase if we don't */
+ if(!conn->bits.user_passwd) {
+ state(conn, POP3_STOP);
+
+ return result;
+ }
+
+ /* Send the USER command */
+ result = Curl_pp_sendf(&conn->proto.pop3c.pp, "USER %s",
+ conn->user ? conn->user : "");
+ if(!result)
+ state(conn, POP3_USER);
+
+ return result;
+}
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+/***********************************************************************
+ *
+ * pop3_perform_apop()
+ *
+ * Sends an APOP command to authenticate with.
+ */
+static CURLcode pop3_perform_apop(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct pop3_conn *pop3c = &conn->proto.pop3c;
+ size_t i;
+ MD5_context *ctxt;
+ unsigned char digest[MD5_DIGEST_LEN];
+ char secret[2 * MD5_DIGEST_LEN + 1];
+
+ /* Check we have a username and password to authenticate with and end the
+ connect phase if we don't */
+ if(!conn->bits.user_passwd) {
+ state(conn, POP3_STOP);
+
+ return result;
+ }
+
+ /* Create the digest */
+ ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
+ if(!ctxt)
+ return CURLE_OUT_OF_MEMORY;
+
+ Curl_MD5_update(ctxt, (const unsigned char *) pop3c->apoptimestamp,
+ curlx_uztoui(strlen(pop3c->apoptimestamp)));
+
+ Curl_MD5_update(ctxt, (const unsigned char *) conn->passwd,
+ curlx_uztoui(strlen(conn->passwd)));
+
+ /* Finalise the digest */
+ Curl_MD5_final(ctxt, digest);
+
+ /* Convert the calculated 16 octet digest into a 32 byte hex string */
+ for(i = 0; i < MD5_DIGEST_LEN; i++)
+ snprintf(&secret[2 * i], 3, "%02x", digest[i]);
+
+ result = Curl_pp_sendf(&pop3c->pp, "APOP %s %s", conn->user, secret);
+
+ if(!result)
+ state(conn, POP3_APOP);
+
+ return result;
+}
+#endif
+
+/***********************************************************************
+ *
+ * pop3_perform_auth()
+ *
+ * Sends an AUTH command allowing the client to login with the given SASL
+ * authentication mechanism.
+ */
+static CURLcode pop3_perform_auth(struct connectdata *conn,
+ const char *mech,
+ const char *initresp)
+{
+ CURLcode result = CURLE_OK;
+ struct pop3_conn *pop3c = &conn->proto.pop3c;
+
+ if(initresp) { /* AUTH <mech> ...<crlf> */
+ /* Send the AUTH command with the initial response */
+ result = Curl_pp_sendf(&pop3c->pp, "AUTH %s %s", mech, initresp);
+ }
+ else {
+ /* Send the AUTH command */
+ result = Curl_pp_sendf(&pop3c->pp, "AUTH %s", mech);
+ }
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_continue_auth()
+ *
+ * Sends SASL continuation data or cancellation.
+ */
+static CURLcode pop3_continue_auth(struct connectdata *conn,
+ const char *resp)
+{
+ struct pop3_conn *pop3c = &conn->proto.pop3c;
+
+ return Curl_pp_sendf(&pop3c->pp, "%s", resp);
+}
+
+/***********************************************************************
+ *
+ * pop3_perform_authentication()
+ *
+ * Initiates the authentication sequence, with the appropriate SASL
+ * authentication mechanism, falling back to APOP and clear text should a
+ * common mechanism not be available between the client and server.
+ */
+static CURLcode pop3_perform_authentication(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct pop3_conn *pop3c = &conn->proto.pop3c;
+ saslprogress progress = SASL_IDLE;
+
+ /* Check we have enough data to authenticate with and end the
+ connect phase if we don't */
+ if(!Curl_sasl_can_authenticate(&pop3c->sasl, conn)) {
+ state(conn, POP3_STOP);
+ return result;
+ }
+
+ if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_SASL) {
+ /* Calculate the SASL login details */
+ result = Curl_sasl_start(&pop3c->sasl, conn, FALSE, &progress);
+
+ if(!result)
+ if(progress == SASL_INPROGRESS)
+ state(conn, POP3_AUTH);
+ }
+
+ if(!result && progress == SASL_IDLE) {
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+ if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_APOP)
+ /* Perform APOP authentication */
+ result = pop3_perform_apop(conn);
+ else
+#endif
+ if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_CLEARTEXT)
+ /* Perform clear text authentication */
+ result = pop3_perform_user(conn);
+ else {
+ /* Other mechanisms not supported */
+ infof(conn->data, "No known authentication mechanisms supported!\n");
+ result = CURLE_LOGIN_DENIED;
+ }
+ }
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_perform_command()
+ *
+ * Sends a POP3 based command.
+ */
+static CURLcode pop3_perform_command(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct POP3 *pop3 = data->req.protop;
+ const char *command = NULL;
+
+ /* Calculate the default command */
+ if(pop3->id[0] == '\0' || conn->data->set.ftp_list_only) {
+ command = "LIST";
+
+ if(pop3->id[0] != '\0')
+ /* Message specific LIST so skip the BODY transfer */
+ pop3->transfer = FTPTRANSFER_INFO;
+ }
+ else
+ command = "RETR";
+
+ /* Send the command */
+ if(pop3->id[0] != '\0')
+ result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s %s",
+ (pop3->custom && pop3->custom[0] != '\0' ?
+ pop3->custom : command), pop3->id);
+ else
+ result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s",
+ (pop3->custom && pop3->custom[0] != '\0' ?
+ pop3->custom : command));
+
+ if(!result)
+ state(conn, POP3_COMMAND);
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_perform_quit()
+ *
+ * Performs the quit action prior to sclose() be called.
+ */
+static CURLcode pop3_perform_quit(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+
+ /* Send the QUIT command */
+ result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "QUIT");
+
+ if(!result)
+ state(conn, POP3_QUIT);
+
+ return result;
+}
+
+/* For the initial server greeting */
+static CURLcode pop3_state_servergreet_resp(struct connectdata *conn,
+ int pop3code,
+ pop3state instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct pop3_conn *pop3c = &conn->proto.pop3c;
+ const char *line = data->state.buffer;
+ size_t len = strlen(line);
+ size_t i;
+
+ (void)instate; /* no use for this yet */
+
+ if(pop3code != '+') {
+ failf(data, "Got unexpected pop3-server response");
+ result = CURLE_FTP_WEIRD_SERVER_REPLY;
+ }
+ else {
+ /* Does the server support APOP authentication? */
+ if(len >= 4 && line[len - 2] == '>') {
+ /* Look for the APOP timestamp */
+ for(i = 3; i < len - 2; ++i) {
+ if(line[i] == '<') {
+ /* Calculate the length of the timestamp */
+ size_t timestamplen = len - 1 - i;
+ if(!timestamplen)
+ break;
+
+ /* Allocate some memory for the timestamp */
+ pop3c->apoptimestamp = (char *)calloc(1, timestamplen + 1);
+
+ if(!pop3c->apoptimestamp)
+ break;
+
+ /* Copy the timestamp */
+ memcpy(pop3c->apoptimestamp, line + i, timestamplen);
+ pop3c->apoptimestamp[timestamplen] = '\0';
+
+ /* Store the APOP capability */
+ pop3c->authtypes |= POP3_TYPE_APOP;
+ break;
+ }
+ }
+ }
+
+ result = pop3_perform_capa(conn);
+ }
+
+ return result;
+}
+
+/* For CAPA responses */
+static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code,
+ pop3state instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct pop3_conn *pop3c = &conn->proto.pop3c;
+ const char *line = data->state.buffer;
+ size_t len = strlen(line);
+ size_t wordlen;
+
+ (void)instate; /* no use for this yet */
+
+ /* Do we have a untagged response? */
+ if(pop3code == '*') {
+ /* Does the server support the STLS capability? */
+ if(len >= 4 && !memcmp(line, "STLS", 4))
+ pop3c->tls_supported = TRUE;
+
+ /* Does the server support clear text authentication? */
+ else if(len >= 4 && !memcmp(line, "USER", 4))
+ pop3c->authtypes |= POP3_TYPE_CLEARTEXT;
+
+ /* Does the server support SASL based authentication? */
+ else if(len >= 5 && !memcmp(line, "SASL ", 5)) {
+ pop3c->authtypes |= POP3_TYPE_SASL;
+
+ /* Advance past the SASL keyword */
+ line += 5;
+ len -= 5;
+
+ /* Loop through the data line */
+ for(;;) {
+ size_t llen;
+ unsigned int mechbit;
+
+ while(len &&
+ (*line == ' ' || *line == '\t' ||
+ *line == '\r' || *line == '\n')) {
+
+ line++;
+ len--;
+ }
+
+ if(!len)
+ break;
+
+ /* Extract the word */
+ for(wordlen = 0; wordlen < len && line[wordlen] != ' ' &&
+ line[wordlen] != '\t' && line[wordlen] != '\r' &&
+ line[wordlen] != '\n';)
+ wordlen++;
+
+ /* Test the word for a matching authentication mechanism */
+ if((mechbit = Curl_sasl_decode_mech(line, wordlen, &llen)) &&
+ llen == wordlen)
+ pop3c->sasl.authmechs |= mechbit;
+
+ line += wordlen;
+ len -= wordlen;
+ }
+ }
+ }
+ else if(pop3code == '+') {
+ if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
+ /* We don't have a SSL/TLS connection yet, but SSL is requested */
+ if(pop3c->tls_supported)
+ /* Switch to TLS connection now */
+ result = pop3_perform_starttls(conn);
+ else if(data->set.use_ssl == CURLUSESSL_TRY)
+ /* Fallback and carry on with authentication */
+ result = pop3_perform_authentication(conn);
+ else {
+ failf(data, "STLS not supported.");
+ result = CURLE_USE_SSL_FAILED;
+ }
+ }
+ else
+ result = pop3_perform_authentication(conn);
+ }
+ else {
+ /* Clear text is supported when CAPA isn't recognised */
+ pop3c->authtypes |= POP3_TYPE_CLEARTEXT;
+
+ result = pop3_perform_authentication(conn);
+ }
+
+ return result;
+}
+
+/* For STARTTLS responses */
+static CURLcode pop3_state_starttls_resp(struct connectdata *conn,
+ int pop3code,
+ pop3state instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+
+ (void)instate; /* no use for this yet */
+
+ if(pop3code != '+') {
+ if(data->set.use_ssl != CURLUSESSL_TRY) {
+ failf(data, "STARTTLS denied. %c", pop3code);
+ result = CURLE_USE_SSL_FAILED;
+ }
+ else
+ result = pop3_perform_authentication(conn);
+ }
+ else
+ result = pop3_perform_upgrade_tls(conn);
+
+ return result;
+}
+
+/* For SASL authentication responses */
+static CURLcode pop3_state_auth_resp(struct connectdata *conn,
+ int pop3code,
+ pop3state instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct pop3_conn *pop3c = &conn->proto.pop3c;
+ saslprogress progress;
+
+ (void)instate; /* no use for this yet */
+
+ result = Curl_sasl_continue(&pop3c->sasl, conn, pop3code, &progress);
+ if(!result)
+ switch(progress) {
+ case SASL_DONE:
+ state(conn, POP3_STOP); /* Authenticated */
+ break;
+ case SASL_IDLE: /* No mechanism left after cancellation */
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+ if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_APOP)
+ /* Perform APOP authentication */
+ result = pop3_perform_apop(conn);
+ else
+#endif
+ if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_CLEARTEXT)
+ /* Perform clear text authentication */
+ result = pop3_perform_user(conn);
+ else {
+ failf(data, "Authentication cancelled");
+ result = CURLE_LOGIN_DENIED;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return result;
+}
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+/* For APOP responses */
+static CURLcode pop3_state_apop_resp(struct connectdata *conn, int pop3code,
+ pop3state instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+
+ (void)instate; /* no use for this yet */
+
+ if(pop3code != '+') {
+ failf(data, "Authentication failed: %d", pop3code);
+ result = CURLE_LOGIN_DENIED;
+ }
+ else
+ /* End of connect phase */
+ state(conn, POP3_STOP);
+
+ return result;
+}
+#endif
+
+/* For USER responses */
+static CURLcode pop3_state_user_resp(struct connectdata *conn, int pop3code,
+ pop3state instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+
+ (void)instate; /* no use for this yet */
+
+ if(pop3code != '+') {
+ failf(data, "Access denied. %c", pop3code);
+ result = CURLE_LOGIN_DENIED;
+ }
+ else
+ /* Send the PASS command */
+ result = Curl_pp_sendf(&conn->proto.pop3c.pp, "PASS %s",
+ conn->passwd ? conn->passwd : "");
+ if(!result)
+ state(conn, POP3_PASS);
+
+ return result;
+}
+
+/* For PASS responses */
+static CURLcode pop3_state_pass_resp(struct connectdata *conn, int pop3code,
+ pop3state instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+
+ (void)instate; /* no use for this yet */
+
+ if(pop3code != '+') {
+ failf(data, "Access denied. %c", pop3code);
+ result = CURLE_LOGIN_DENIED;
+ }
+ else
+ /* End of connect phase */
+ state(conn, POP3_STOP);
+
+ return result;
+}
+
+/* For command responses */
+static CURLcode pop3_state_command_resp(struct connectdata *conn,
+ int pop3code,
+ pop3state instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct POP3 *pop3 = data->req.protop;
+ struct pop3_conn *pop3c = &conn->proto.pop3c;
+ struct pingpong *pp = &pop3c->pp;
+
+ (void)instate; /* no use for this yet */
+
+ if(pop3code != '+') {
+ state(conn, POP3_STOP);
+ return CURLE_RECV_ERROR;
+ }
+
+ /* This 'OK' line ends with a CR LF pair which is the two first bytes of the
+ EOB string so count this is two matching bytes. This is necessary to make
+ the code detect the EOB if the only data than comes now is %2e CR LF like
+ when there is no body to return. */
+ pop3c->eob = 2;
+
+ /* But since this initial CR LF pair is not part of the actual body, we set
+ the strip counter here so that these bytes won't be delivered. */
+ pop3c->strip = 2;
+
+ if(pop3->transfer == FTPTRANSFER_BODY) {
+ /* POP3 download */
+ Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL);
+
+ if(pp->cache) {
+ /* The header "cache" contains a bunch of data that is actually body
+ content so send it as such. Note that there may even be additional
+ "headers" after the body */
+
+ if(!data->set.opt_no_body) {
+ result = Curl_pop3_write(conn, pp->cache, pp->cache_size);
+ if(result)
+ return result;
+ }
+
+ /* Free the cache */
+ Curl_safefree(pp->cache);
+
+ /* Reset the cache size */
+ pp->cache_size = 0;
+ }
+ }
+
+ /* End of DO phase */
+ state(conn, POP3_STOP);
+
+ return result;
+}
+
+static CURLcode pop3_statemach_act(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ curl_socket_t sock = conn->sock[FIRSTSOCKET];
+ int pop3code;
+ struct pop3_conn *pop3c = &conn->proto.pop3c;
+ struct pingpong *pp = &pop3c->pp;
+ size_t nread = 0;
+
+ /* Busy upgrading the connection; right now all I/O is SSL/TLS, not POP3 */
+ if(pop3c->state == POP3_UPGRADETLS)
+ return pop3_perform_upgrade_tls(conn);
+
+ /* Flush any data that needs to be sent */
+ if(pp->sendleft)
+ return Curl_pp_flushsend(pp);
+
+ do {
+ /* Read the response from the server */
+ result = Curl_pp_readresp(sock, pp, &pop3code, &nread);
+ if(result)
+ return result;
+
+ if(!pop3code)
+ break;
+
+ /* We have now received a full POP3 server response */
+ switch(pop3c->state) {
+ case POP3_SERVERGREET:
+ result = pop3_state_servergreet_resp(conn, pop3code, pop3c->state);
+ break;
+
+ case POP3_CAPA:
+ result = pop3_state_capa_resp(conn, pop3code, pop3c->state);
+ break;
+
+ case POP3_STARTTLS:
+ result = pop3_state_starttls_resp(conn, pop3code, pop3c->state);
+ break;
+
+ case POP3_AUTH:
+ result = pop3_state_auth_resp(conn, pop3code, pop3c->state);
+ break;
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+ case POP3_APOP:
+ result = pop3_state_apop_resp(conn, pop3code, pop3c->state);
+ break;
+#endif
+
+ case POP3_USER:
+ result = pop3_state_user_resp(conn, pop3code, pop3c->state);
+ break;
+
+ case POP3_PASS:
+ result = pop3_state_pass_resp(conn, pop3code, pop3c->state);
+ break;
+
+ case POP3_COMMAND:
+ result = pop3_state_command_resp(conn, pop3code, pop3c->state);
+ break;
+
+ case POP3_QUIT:
+ /* fallthrough, just stop! */
+ default:
+ /* internal error */
+ state(conn, POP3_STOP);
+ break;
+ }
+ } while(!result && pop3c->state != POP3_STOP && Curl_pp_moredata(pp));
+
+ return result;
+}
+
+/* Called repeatedly until done from multi.c */
+static CURLcode pop3_multi_statemach(struct connectdata *conn, bool *done)
+{
+ CURLcode result = CURLE_OK;
+ struct pop3_conn *pop3c = &conn->proto.pop3c;
+
+ if((conn->handler->flags & PROTOPT_SSL) && !pop3c->ssldone) {
+ result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &pop3c->ssldone);
+ if(result || !pop3c->ssldone)
+ return result;
+ }
+
+ result = Curl_pp_statemach(&pop3c->pp, FALSE);
+ *done = (pop3c->state == POP3_STOP) ? TRUE : FALSE;
+
+ return result;
+}
+
+static CURLcode pop3_block_statemach(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct pop3_conn *pop3c = &conn->proto.pop3c;
+
+ while(pop3c->state != POP3_STOP && !result)
+ result = Curl_pp_statemach(&pop3c->pp, TRUE);
+
+ return result;
+}
+
+/* Allocate and initialize the POP3 struct for the current SessionHandle if
+ required */
+static CURLcode pop3_init(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct POP3 *pop3;
+
+ pop3 = data->req.protop = calloc(sizeof(struct POP3), 1);
+ if(!pop3)
+ result = CURLE_OUT_OF_MEMORY;
+
+ return result;
+}
+
+/* For the POP3 "protocol connect" and "doing" phases only */
+static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks,
+ int numsocks)
+{
+ return Curl_pp_getsock(&conn->proto.pop3c.pp, socks, numsocks);
+}
+
+/***********************************************************************
+ *
+ * pop3_connect()
+ *
+ * This function should do everything that is to be considered a part of the
+ * connection phase.
+ *
+ * The variable 'done' points to will be TRUE if the protocol-layer connect
+ * phase is done when this function returns, or FALSE if not.
+ */
+static CURLcode pop3_connect(struct connectdata *conn, bool *done)
+{
+ CURLcode result = CURLE_OK;
+ struct pop3_conn *pop3c = &conn->proto.pop3c;
+ struct pingpong *pp = &pop3c->pp;
+
+ *done = FALSE; /* default to not done yet */
+
+ /* We always support persistent connections in POP3 */
+ connkeep(conn, "POP3 default");
+
+ /* Set the default response time-out */
+ pp->response_time = RESP_TIMEOUT;
+ pp->statemach_act = pop3_statemach_act;
+ pp->endofresp = pop3_endofresp;
+ pp->conn = conn;
+
+ /* Set the default preferred authentication type and mechanism */
+ pop3c->preftype = POP3_TYPE_ANY;
+ Curl_sasl_init(&pop3c->sasl, &saslpop3);
+
+ /* Initialise the pingpong layer */
+ Curl_pp_init(pp);
+
+ /* Parse the URL options */
+ result = pop3_parse_url_options(conn);
+ if(result)
+ return result;
+
+ /* Start off waiting for the server greeting response */
+ state(conn, POP3_SERVERGREET);
+
+ result = pop3_multi_statemach(conn, done);
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_done()
+ *
+ * The DONE function. This does what needs to be done after a single DO has
+ * performed.
+ *
+ * Input argument is already checked for validity.
+ */
+static CURLcode pop3_done(struct connectdata *conn, CURLcode status,
+ bool premature)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct POP3 *pop3 = data->req.protop;
+
+ (void)premature;
+
+ if(!pop3)
+ /* When the easy handle is removed from the multi interface while libcurl
+ is still trying to resolve the host name, the POP3 struct is not yet
+ initialized. However, the removal action calls Curl_done() which in
+ turn calls this function, so we simply return success. */
+ return CURLE_OK;
+
+ if(status) {
+ connclose(conn, "POP3 done with bad status");
+ result = status; /* use the already set error code */
+ }
+
+ /* Cleanup our per-request based variables */
+ Curl_safefree(pop3->id);
+ Curl_safefree(pop3->custom);
+
+ /* Clear the transfer mode for the next request */
+ pop3->transfer = FTPTRANSFER_BODY;
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_perform()
+ *
+ * This is the actual DO function for POP3. Get a message/listing according to
+ * the options previously setup.
+ */
+static CURLcode pop3_perform(struct connectdata *conn, bool *connected,
+ bool *dophase_done)
+{
+ /* This is POP3 and no proxy */
+ CURLcode result = CURLE_OK;
+ struct POP3 *pop3 = conn->data->req.protop;
+
+ DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+ if(conn->data->set.opt_no_body) {
+ /* Requested no body means no transfer */
+ pop3->transfer = FTPTRANSFER_INFO;
+ }
+
+ *dophase_done = FALSE; /* not done yet */
+
+ /* Start the first command in the DO phase */
+ result = pop3_perform_command(conn);
+ if(result)
+ return result;
+
+ /* Run the state-machine */
+ result = pop3_multi_statemach(conn, dophase_done);
+
+ *connected = conn->bits.tcpconnect[FIRSTSOCKET];
+
+ if(*dophase_done)
+ DEBUGF(infof(conn->data, "DO phase is complete\n"));
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_do()
+ *
+ * This function is registered as 'curl_do' function. It decodes the path
+ * parts etc as a wrapper to the actual DO function (pop3_perform).
+ *
+ * The input argument is already checked for validity.
+ */
+static CURLcode pop3_do(struct connectdata *conn, bool *done)
+{
+ CURLcode result = CURLE_OK;
+
+ *done = FALSE; /* default to false */
+
+ /* Parse the URL path */
+ result = pop3_parse_url_path(conn);
+ if(result)
+ return result;
+
+ /* Parse the custom request */
+ result = pop3_parse_custom_request(conn);
+ if(result)
+ return result;
+
+ result = pop3_regular_transfer(conn, done);
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_disconnect()
+ *
+ * Disconnect from an POP3 server. Cleanup protocol-specific per-connection
+ * resources. BLOCKING.
+ */
+static CURLcode pop3_disconnect(struct connectdata *conn, bool dead_connection)
+{
+ struct pop3_conn *pop3c = &conn->proto.pop3c;
+
+ /* We cannot send quit unconditionally. If this connection is stale or
+ bad in any way, sending quit and waiting around here will make the
+ disconnect wait in vain and cause more problems than we need to. */
+
+ /* The POP3 session may or may not have been allocated/setup at this
+ point! */
+ if(!dead_connection && pop3c->pp.conn && pop3c->pp.conn->bits.protoconnstart)
+ if(!pop3_perform_quit(conn))
+ (void)pop3_block_statemach(conn); /* ignore errors on QUIT */
+
+ /* Disconnect from the server */
+ Curl_pp_disconnect(&pop3c->pp);
+
+ /* Cleanup the SASL module */
+ Curl_sasl_cleanup(conn, pop3c->sasl.authused);
+
+ /* Cleanup our connection based variables */
+ Curl_safefree(pop3c->apoptimestamp);
+
+ return CURLE_OK;
+}
+
+/* Call this when the DO phase has completed */
+static CURLcode pop3_dophase_done(struct connectdata *conn, bool connected)
+{
+ (void)conn;
+ (void)connected;
+
+ return CURLE_OK;
+}
+
+/* Called from multi.c while DOing */
+static CURLcode pop3_doing(struct connectdata *conn, bool *dophase_done)
+{
+ CURLcode result = pop3_multi_statemach(conn, dophase_done);
+
+ if(result)
+ DEBUGF(infof(conn->data, "DO phase failed\n"));
+ else if(*dophase_done) {
+ result = pop3_dophase_done(conn, FALSE /* not connected */);
+
+ DEBUGF(infof(conn->data, "DO phase is complete\n"));
+ }
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_regular_transfer()
+ *
+ * The input argument is already checked for validity.
+ *
+ * Performs all commands done before a regular transfer between a local and a
+ * remote host.
+ */
+static CURLcode pop3_regular_transfer(struct connectdata *conn,
+ bool *dophase_done)
+{
+ CURLcode result = CURLE_OK;
+ bool connected = FALSE;
+ struct SessionHandle *data = conn->data;
+
+ /* Make sure size is unknown at this point */
+ data->req.size = -1;
+
+ /* Set the progress data */
+ Curl_pgrsSetUploadCounter(data, 0);
+ Curl_pgrsSetDownloadCounter(data, 0);
+ Curl_pgrsSetUploadSize(data, -1);
+ Curl_pgrsSetDownloadSize(data, -1);
+
+ /* Carry out the perform */
+ result = pop3_perform(conn, &connected, dophase_done);
+
+ /* Perform post DO phase operations if necessary */
+ if(!result && *dophase_done)
+ result = pop3_dophase_done(conn, connected);
+
+ return result;
+}
+
+static CURLcode pop3_setup_connection(struct connectdata *conn)
+{
+ struct SessionHandle *data = conn->data;
+
+ /* Initialise the POP3 layer */
+ CURLcode result = pop3_init(conn);
+ if(result)
+ return result;
+
+ if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) {
+ /* Unless we have asked to tunnel POP3 operations through the proxy, we
+ switch and use HTTP operations only */
+#ifndef CURL_DISABLE_HTTP
+ if(conn->handler == &Curl_handler_pop3)
+ conn->handler = &Curl_handler_pop3_proxy;
+ else {
+#ifdef USE_SSL
+ conn->handler = &Curl_handler_pop3s_proxy;
+#else
+ failf(data, "POP3S not supported!");
+ return CURLE_UNSUPPORTED_PROTOCOL;
+#endif
+ }
+
+ /* set it up as an HTTP connection instead */
+ return conn->handler->setup_connection(conn);
+#else
+ failf(data, "POP3 over http proxy requires HTTP support built-in!");
+ return CURLE_UNSUPPORTED_PROTOCOL;
+#endif
+ }
+
+ data->state.path++; /* don't include the initial slash */
+
+ return CURLE_OK;
+}
+
+/***********************************************************************
+ *
+ * pop3_parse_url_options()
+ *
+ * Parse the URL login options.
+ */
+static CURLcode pop3_parse_url_options(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct pop3_conn *pop3c = &conn->proto.pop3c;
+ const char *ptr = conn->options;
+
+ pop3c->sasl.resetprefs = TRUE;
+
+ while(!result && ptr && *ptr) {
+ const char *key = ptr;
+ const char *value;
+
+ while(*ptr && *ptr != '=')
+ ptr++;
+
+ value = ptr + 1;
+
+ while(*ptr && *ptr != ';')
+ ptr++;
+
+ if(strnequal(key, "AUTH=", 5)) {
+ result = Curl_sasl_parse_url_auth_option(&pop3c->sasl,
+ value, ptr - value);
+
+ if(result && strnequal(value, "+APOP", ptr - value)) {
+ pop3c->preftype = POP3_TYPE_APOP;
+ pop3c->sasl.prefmech = SASL_AUTH_NONE;
+ result = CURLE_OK;
+ }
+ }
+ else
+ result = CURLE_URL_MALFORMAT;
+
+ if(*ptr == ';')
+ ptr++;
+ }
+
+ if(pop3c->preftype != POP3_TYPE_APOP)
+ switch(pop3c->sasl.prefmech) {
+ case SASL_AUTH_NONE:
+ pop3c->preftype = POP3_TYPE_NONE;
+ break;
+ case SASL_AUTH_DEFAULT:
+ pop3c->preftype = POP3_TYPE_ANY;
+ break;
+ default:
+ pop3c->preftype = POP3_TYPE_SASL;
+ break;
+ }
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_parse_url_path()
+ *
+ * Parse the URL path into separate path components.
+ */
+static CURLcode pop3_parse_url_path(struct connectdata *conn)
+{
+ /* The POP3 struct is already initialised in pop3_connect() */
+ struct SessionHandle *data = conn->data;
+ struct POP3 *pop3 = data->req.protop;
+ const char *path = data->state.path;
+
+ /* URL decode the path for the message ID */
+ return Curl_urldecode(data, path, 0, &pop3->id, NULL, TRUE);
+}
+
+/***********************************************************************
+ *
+ * pop3_parse_custom_request()
+ *
+ * Parse the custom request.
+ */
+static CURLcode pop3_parse_custom_request(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct POP3 *pop3 = data->req.protop;
+ const char *custom = data->set.str[STRING_CUSTOMREQUEST];
+
+ /* URL decode the custom request */
+ if(custom)
+ result = Curl_urldecode(data, custom, 0, &pop3->custom, NULL, TRUE);
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * Curl_pop3_write()
+ *
+ * This function scans the body after the end-of-body and writes everything
+ * until the end is found.
+ */
+CURLcode Curl_pop3_write(struct connectdata *conn, char *str, size_t nread)
+{
+ /* This code could be made into a special function in the handler struct */
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct SingleRequest *k = &data->req;
+
+ struct pop3_conn *pop3c = &conn->proto.pop3c;
+ bool strip_dot = FALSE;
+ size_t last = 0;
+ size_t i;
+
+ /* Search through the buffer looking for the end-of-body marker which is
+ 5 bytes (0d 0a 2e 0d 0a). Note that a line starting with a dot matches
+ the eob so the server will have prefixed it with an extra dot which we
+ need to strip out. Additionally the marker could of course be spread out
+ over 5 different data chunks. */
+ for(i = 0; i < nread; i++) {
+ size_t prev = pop3c->eob;
+
+ switch(str[i]) {
+ case 0x0d:
+ if(pop3c->eob == 0) {
+ pop3c->eob++;
+
+ if(i) {
+ /* Write out the body part that didn't match */
+ result = Curl_client_write(conn, CLIENTWRITE_BODY, &str[last],
+ i - last);
+
+ if(result)
+ return result;
+
+ last = i;
+ }
+ }
+ else if(pop3c->eob == 3)
+ pop3c->eob++;
+ else
+ /* If the character match wasn't at position 0 or 3 then restart the
+ pattern matching */
+ pop3c->eob = 1;
+ break;
+
+ case 0x0a:
+ if(pop3c->eob == 1 || pop3c->eob == 4)
+ pop3c->eob++;
+ else
+ /* If the character match wasn't at position 1 or 4 then start the
+ search again */
+ pop3c->eob = 0;
+ break;
+
+ case 0x2e:
+ if(pop3c->eob == 2)
+ pop3c->eob++;
+ else if(pop3c->eob == 3) {
+ /* We have an extra dot after the CRLF which we need to strip off */
+ strip_dot = TRUE;
+ pop3c->eob = 0;
+ }
+ else
+ /* If the character match wasn't at position 2 then start the search
+ again */
+ pop3c->eob = 0;
+ break;
+
+ default:
+ pop3c->eob = 0;
+ break;
+ }
+
+ /* Did we have a partial match which has subsequently failed? */
+ if(prev && prev >= pop3c->eob) {
+ /* Strip can only be non-zero for the very first mismatch after CRLF
+ and then both prev and strip are equal and nothing will be output
+ below */
+ while(prev && pop3c->strip) {
+ prev--;
+ pop3c->strip--;
+ }
+
+ if(prev) {
+ /* If the partial match was the CRLF and dot then only write the CRLF
+ as the server would have inserted the dot */
+ result = Curl_client_write(conn, CLIENTWRITE_BODY, (char*)POP3_EOB,
+ strip_dot ? prev - 1 : prev);
+
+ if(result)
+ return result;
+
+ last = i;
+ strip_dot = FALSE;
+ }
+ }
+ }
+
+ if(pop3c->eob == POP3_EOB_LEN) {
+ /* We have a full match so the transfer is done, however we must transfer
+ the CRLF at the start of the EOB as this is considered to be part of the
+ message as per RFC-1939, sect. 3 */
+ result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)POP3_EOB, 2);
+
+ k->keepon &= ~KEEP_RECV;
+ pop3c->eob = 0;
+
+ return result;
+ }
+
+ if(pop3c->eob)
+ /* While EOB is matching nothing should be output */
+ return CURLE_OK;
+
+ if(nread - last) {
+ result = Curl_client_write(conn, CLIENTWRITE_BODY, &str[last],
+ nread - last);
+ }
+
+ return result;
+}
+
+#endif /* CURL_DISABLE_POP3 */
diff --git a/Utilities/cmcurl/lib/pop3.h b/Utilities/cmcurl/lib/pop3.h
new file mode 100644
index 000000000..7bc53aaf5
--- /dev/null
+++ b/Utilities/cmcurl/lib/pop3.h
@@ -0,0 +1,95 @@
+#ifndef HEADER_CURL_POP3_H
+#define HEADER_CURL_POP3_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2009 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "pingpong.h"
+#include "curl_sasl.h"
+
+/****************************************************************************
+ * POP3 unique setup
+ ***************************************************************************/
+typedef enum {
+ POP3_STOP, /* do nothing state, stops the state machine */
+ POP3_SERVERGREET, /* waiting for the initial greeting immediately after
+ a connect */
+ POP3_CAPA,
+ POP3_STARTTLS,
+ POP3_UPGRADETLS, /* asynchronously upgrade the connection to SSL/TLS
+ (multi mode only) */
+ POP3_AUTH,
+ POP3_APOP,
+ POP3_USER,
+ POP3_PASS,
+ POP3_COMMAND,
+ POP3_QUIT,
+ POP3_LAST /* never used */
+} pop3state;
+
+/* This POP3 struct is used in the SessionHandle. All POP3 data that is
+ connection-oriented must be in pop3_conn to properly deal with the fact that
+ perhaps the SessionHandle is changed between the times the connection is
+ used. */
+struct POP3 {
+ curl_pp_transfer transfer;
+ char *id; /* Message ID */
+ char *custom; /* Custom Request */
+};
+
+/* pop3_conn is used for struct connection-oriented data in the connectdata
+ struct */
+struct pop3_conn {
+ struct pingpong pp;
+ pop3state state; /* Always use pop3.c:state() to change state! */
+ bool ssldone; /* Is connect() over SSL done? */
+ size_t eob; /* Number of bytes of the EOB (End Of Body) that
+ have been received so far */
+ size_t strip; /* Number of bytes from the start to ignore as
+ non-body */
+ struct SASL sasl; /* SASL-related storage */
+ unsigned int authtypes; /* Accepted authentication types */
+ unsigned int preftype; /* Preferred authentication type */
+ char *apoptimestamp; /* APOP timestamp from the server greeting */
+ bool tls_supported; /* StartTLS capability supported by server */
+};
+
+extern const struct Curl_handler Curl_handler_pop3;
+extern const struct Curl_handler Curl_handler_pop3s;
+
+/* Authentication type flags */
+#define POP3_TYPE_CLEARTEXT (1 << 0)
+#define POP3_TYPE_APOP (1 << 1)
+#define POP3_TYPE_SASL (1 << 2)
+
+/* Authentication type values */
+#define POP3_TYPE_NONE 0
+#define POP3_TYPE_ANY ~0U
+
+/* This is the 5-bytes End-Of-Body marker for POP3 */
+#define POP3_EOB "\x0d\x0a\x2e\x0d\x0a"
+#define POP3_EOB_LEN 5
+
+/* This function scans the body after the end-of-body and writes everything
+ * until the end is found */
+CURLcode Curl_pop3_write(struct connectdata *conn, char *str, size_t nread);
+
+#endif /* HEADER_CURL_POP3_H */
diff --git a/Utilities/cmcurl/lib/progress.c b/Utilities/cmcurl/lib/progress.c
new file mode 100644
index 000000000..b46e27405
--- /dev/null
+++ b/Utilities/cmcurl/lib/progress.c
@@ -0,0 +1,492 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "urldata.h"
+#include "sendf.h"
+#include "progress.h"
+#include "curl_printf.h"
+
+/* Provide a string that is 2 + 1 + 2 + 1 + 2 = 8 letters long (plus the zero
+ byte) */
+static void time2str(char *r, curl_off_t seconds)
+{
+ curl_off_t d, h, m, s;
+ if(seconds <= 0) {
+ strcpy(r, "--:--:--");
+ return;
+ }
+ h = seconds / CURL_OFF_T_C(3600);
+ if(h <= CURL_OFF_T_C(99)) {
+ m = (seconds - (h*CURL_OFF_T_C(3600))) / CURL_OFF_T_C(60);
+ s = (seconds - (h*CURL_OFF_T_C(3600))) - (m*CURL_OFF_T_C(60));
+ snprintf(r, 9, "%2" CURL_FORMAT_CURL_OFF_T ":%02" CURL_FORMAT_CURL_OFF_T
+ ":%02" CURL_FORMAT_CURL_OFF_T, h, m, s);
+ }
+ else {
+ /* this equals to more than 99 hours, switch to a more suitable output
+ format to fit within the limits. */
+ d = seconds / CURL_OFF_T_C(86400);
+ h = (seconds - (d*CURL_OFF_T_C(86400))) / CURL_OFF_T_C(3600);
+ if(d <= CURL_OFF_T_C(999))
+ snprintf(r, 9, "%3" CURL_FORMAT_CURL_OFF_T
+ "d %02" CURL_FORMAT_CURL_OFF_T "h", d, h);
+ else
+ snprintf(r, 9, "%7" CURL_FORMAT_CURL_OFF_T "d", d);
+ }
+}
+
+/* The point of this function would be to return a string of the input data,
+ but never longer than 5 columns (+ one zero byte).
+ Add suffix k, M, G when suitable... */
+static char *max5data(curl_off_t bytes, char *max5)
+{
+#define ONE_KILOBYTE CURL_OFF_T_C(1024)
+#define ONE_MEGABYTE (CURL_OFF_T_C(1024) * ONE_KILOBYTE)
+#define ONE_GIGABYTE (CURL_OFF_T_C(1024) * ONE_MEGABYTE)
+#define ONE_TERABYTE (CURL_OFF_T_C(1024) * ONE_GIGABYTE)
+#define ONE_PETABYTE (CURL_OFF_T_C(1024) * ONE_TERABYTE)
+
+ if(bytes < CURL_OFF_T_C(100000))
+ snprintf(max5, 6, "%5" CURL_FORMAT_CURL_OFF_T, bytes);
+
+ else if(bytes < CURL_OFF_T_C(10000) * ONE_KILOBYTE)
+ snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "k", bytes/ONE_KILOBYTE);
+
+ else if(bytes < CURL_OFF_T_C(100) * ONE_MEGABYTE)
+ /* 'XX.XM' is good as long as we're less than 100 megs */
+ snprintf(max5, 6, "%2" CURL_FORMAT_CURL_OFF_T ".%0"
+ CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE,
+ (bytes%ONE_MEGABYTE) / (ONE_MEGABYTE/CURL_OFF_T_C(10)) );
+
+#if (CURL_SIZEOF_CURL_OFF_T > 4)
+
+ else if(bytes < CURL_OFF_T_C(10000) * ONE_MEGABYTE)
+ /* 'XXXXM' is good until we're at 10000MB or above */
+ snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE);
+
+ else if(bytes < CURL_OFF_T_C(100) * ONE_GIGABYTE)
+ /* 10000 MB - 100 GB, we show it as XX.XG */
+ snprintf(max5, 6, "%2" CURL_FORMAT_CURL_OFF_T ".%0"
+ CURL_FORMAT_CURL_OFF_T "G", bytes/ONE_GIGABYTE,
+ (bytes%ONE_GIGABYTE) / (ONE_GIGABYTE/CURL_OFF_T_C(10)) );
+
+ else if(bytes < CURL_OFF_T_C(10000) * ONE_GIGABYTE)
+ /* up to 10000GB, display without decimal: XXXXG */
+ snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "G", bytes/ONE_GIGABYTE);
+
+ else if(bytes < CURL_OFF_T_C(10000) * ONE_TERABYTE)
+ /* up to 10000TB, display without decimal: XXXXT */
+ snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "T", bytes/ONE_TERABYTE);
+
+ else
+ /* up to 10000PB, display without decimal: XXXXP */
+ snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "P", bytes/ONE_PETABYTE);
+
+ /* 16384 petabytes (16 exabytes) is the maximum a 64 bit unsigned number
+ can hold, but our data type is signed so 8192PB will be the maximum. */
+
+#else
+
+ else
+ snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE);
+
+#endif
+
+ return max5;
+}
+
+/*
+
+ New proposed interface, 9th of February 2000:
+
+ pgrsStartNow() - sets start time
+ pgrsSetDownloadSize(x) - known expected download size
+ pgrsSetUploadSize(x) - known expected upload size
+ pgrsSetDownloadCounter() - amount of data currently downloaded
+ pgrsSetUploadCounter() - amount of data currently uploaded
+ pgrsUpdate() - show progress
+ pgrsDone() - transfer complete
+
+*/
+
+int Curl_pgrsDone(struct connectdata *conn)
+{
+ int rc;
+ struct SessionHandle *data = conn->data;
+ data->progress.lastshow=0;
+ rc = Curl_pgrsUpdate(conn); /* the final (forced) update */
+ if(rc)
+ return rc;
+
+ if(!(data->progress.flags & PGRS_HIDE) &&
+ !data->progress.callback)
+ /* only output if we don't use a progress callback and we're not
+ * hidden */
+ fprintf(data->set.err, "\n");
+
+ data->progress.speeder_c = 0; /* reset the progress meter display */
+ return 0;
+}
+
+/* reset all times except redirect, and reset the known transfer sizes */
+void Curl_pgrsResetTimesSizes(struct SessionHandle *data)
+{
+ data->progress.t_nslookup = 0.0;
+ data->progress.t_connect = 0.0;
+ data->progress.t_pretransfer = 0.0;
+ data->progress.t_starttransfer = 0.0;
+
+ Curl_pgrsSetDownloadSize(data, -1);
+ Curl_pgrsSetUploadSize(data, -1);
+}
+
+void Curl_pgrsTime(struct SessionHandle *data, timerid timer)
+{
+ struct timeval now = Curl_tvnow();
+
+ switch(timer) {
+ default:
+ case TIMER_NONE:
+ /* mistake filter */
+ break;
+ case TIMER_STARTOP:
+ /* This is set at the start of a transfer */
+ data->progress.t_startop = now;
+ break;
+ case TIMER_STARTSINGLE:
+ /* This is set at the start of each single fetch */
+ data->progress.t_startsingle = now;
+ break;
+
+ case TIMER_STARTACCEPT:
+ data->progress.t_acceptdata = Curl_tvnow();
+ break;
+
+ case TIMER_NAMELOOKUP:
+ data->progress.t_nslookup =
+ Curl_tvdiff_secs(now, data->progress.t_startsingle);
+ break;
+ case TIMER_CONNECT:
+ data->progress.t_connect =
+ Curl_tvdiff_secs(now, data->progress.t_startsingle);
+ break;
+ case TIMER_APPCONNECT:
+ data->progress.t_appconnect =
+ Curl_tvdiff_secs(now, data->progress.t_startsingle);
+ break;
+ case TIMER_PRETRANSFER:
+ data->progress.t_pretransfer =
+ Curl_tvdiff_secs(now, data->progress.t_startsingle);
+ break;
+ case TIMER_STARTTRANSFER:
+ data->progress.t_starttransfer =
+ Curl_tvdiff_secs(now, data->progress.t_startsingle);
+ break;
+ case TIMER_POSTRANSFER:
+ /* this is the normal end-of-transfer thing */
+ break;
+ case TIMER_REDIRECT:
+ data->progress.t_redirect = Curl_tvdiff_secs(now, data->progress.start);
+ break;
+ }
+}
+
+void Curl_pgrsStartNow(struct SessionHandle *data)
+{
+ data->progress.speeder_c = 0; /* reset the progress meter display */
+ data->progress.start = Curl_tvnow();
+ /* clear all bits except HIDE and HEADERS_OUT */
+ data->progress.flags &= PGRS_HIDE|PGRS_HEADERS_OUT;
+}
+
+void Curl_pgrsSetDownloadCounter(struct SessionHandle *data, curl_off_t size)
+{
+ data->progress.downloaded = size;
+}
+
+void Curl_pgrsSetUploadCounter(struct SessionHandle *data, curl_off_t size)
+{
+ data->progress.uploaded = size;
+}
+
+void Curl_pgrsSetDownloadSize(struct SessionHandle *data, curl_off_t size)
+{
+ if(size >= 0) {
+ data->progress.size_dl = size;
+ data->progress.flags |= PGRS_DL_SIZE_KNOWN;
+ }
+ else {
+ data->progress.size_dl = 0;
+ data->progress.flags &= ~PGRS_DL_SIZE_KNOWN;
+ }
+}
+
+void Curl_pgrsSetUploadSize(struct SessionHandle *data, curl_off_t size)
+{
+ if(size >= 0) {
+ data->progress.size_ul = size;
+ data->progress.flags |= PGRS_UL_SIZE_KNOWN;
+ }
+ else {
+ data->progress.size_ul = 0;
+ data->progress.flags &= ~PGRS_UL_SIZE_KNOWN;
+ }
+}
+
+/*
+ * Curl_pgrsUpdate() returns 0 for success or the value returned by the
+ * progress callback!
+ */
+int Curl_pgrsUpdate(struct connectdata *conn)
+{
+ struct timeval now;
+ int result;
+ char max5[6][10];
+ curl_off_t dlpercen=0;
+ curl_off_t ulpercen=0;
+ curl_off_t total_percen=0;
+ curl_off_t total_transfer;
+ curl_off_t total_expected_transfer;
+ curl_off_t timespent;
+ struct SessionHandle *data = conn->data;
+ int nowindex = data->progress.speeder_c% CURR_TIME;
+ int checkindex;
+ int countindex; /* amount of seconds stored in the speeder array */
+ char time_left[10];
+ char time_total[10];
+ char time_spent[10];
+ curl_off_t ulestimate=0;
+ curl_off_t dlestimate=0;
+ curl_off_t total_estimate;
+ bool shownow=FALSE;
+
+ now = Curl_tvnow(); /* what time is it */
+
+ /* The time spent so far (from the start) */
+ data->progress.timespent =
+ (double)(now.tv_sec - data->progress.start.tv_sec) +
+ (double)(now.tv_usec - data->progress.start.tv_usec)/1000000.0;
+ timespent = (curl_off_t)data->progress.timespent;
+
+ /* The average download speed this far */
+ data->progress.dlspeed = (curl_off_t)
+ ((double)data->progress.downloaded/
+ (data->progress.timespent>0?data->progress.timespent:1));
+
+ /* The average upload speed this far */
+ data->progress.ulspeed = (curl_off_t)
+ ((double)data->progress.uploaded/
+ (data->progress.timespent>0?data->progress.timespent:1));
+
+ /* Calculations done at most once a second, unless end is reached */
+ if(data->progress.lastshow != (long)now.tv_sec) {
+ shownow = TRUE;
+
+ data->progress.lastshow = now.tv_sec;
+
+ /* Let's do the "current speed" thing, which should use the fastest
+ of the dl/ul speeds. Store the faster speed at entry 'nowindex'. */
+ data->progress.speeder[ nowindex ] =
+ data->progress.downloaded>data->progress.uploaded?
+ data->progress.downloaded:data->progress.uploaded;
+
+ /* remember the exact time for this moment */
+ data->progress.speeder_time [ nowindex ] = now;
+
+ /* advance our speeder_c counter, which is increased every time we get
+ here and we expect it to never wrap as 2^32 is a lot of seconds! */
+ data->progress.speeder_c++;
+
+ /* figure out how many index entries of data we have stored in our speeder
+ array. With N_ENTRIES filled in, we have about N_ENTRIES-1 seconds of
+ transfer. Imagine, after one second we have filled in two entries,
+ after two seconds we've filled in three entries etc. */
+ countindex = ((data->progress.speeder_c>=CURR_TIME)?
+ CURR_TIME:data->progress.speeder_c) - 1;
+
+ /* first of all, we don't do this if there's no counted seconds yet */
+ if(countindex) {
+ long span_ms;
+
+ /* Get the index position to compare with the 'nowindex' position.
+ Get the oldest entry possible. While we have less than CURR_TIME
+ entries, the first entry will remain the oldest. */
+ checkindex = (data->progress.speeder_c>=CURR_TIME)?
+ data->progress.speeder_c%CURR_TIME:0;
+
+ /* Figure out the exact time for the time span */
+ span_ms = Curl_tvdiff(now,
+ data->progress.speeder_time[checkindex]);
+ if(0 == span_ms)
+ span_ms=1; /* at least one millisecond MUST have passed */
+
+ /* Calculate the average speed the last 'span_ms' milliseconds */
+ {
+ curl_off_t amount = data->progress.speeder[nowindex]-
+ data->progress.speeder[checkindex];
+
+ if(amount > CURL_OFF_T_C(4294967) /* 0xffffffff/1000 */)
+ /* the 'amount' value is bigger than would fit in 32 bits if
+ multiplied with 1000, so we use the double math for this */
+ data->progress.current_speed = (curl_off_t)
+ ((double)amount/((double)span_ms/1000.0));
+ else
+ /* the 'amount' value is small enough to fit within 32 bits even
+ when multiplied with 1000 */
+ data->progress.current_speed = amount*CURL_OFF_T_C(1000)/span_ms;
+ }
+ }
+ else
+ /* the first second we use the main average */
+ data->progress.current_speed =
+ (data->progress.ulspeed>data->progress.dlspeed)?
+ data->progress.ulspeed:data->progress.dlspeed;
+
+ } /* Calculations end */
+
+ if(!(data->progress.flags & PGRS_HIDE)) {
+ /* progress meter has not been shut off */
+
+ if(data->set.fxferinfo) {
+ /* There's a callback set, call that */
+ result= data->set.fxferinfo(data->set.progress_client,
+ data->progress.size_dl,
+ data->progress.downloaded,
+ data->progress.size_ul,
+ data->progress.uploaded);
+ if(result)
+ failf(data, "Callback aborted");
+ return result;
+ }
+ else if(data->set.fprogress) {
+ /* The older deprecated callback is set, call that */
+ result= data->set.fprogress(data->set.progress_client,
+ (double)data->progress.size_dl,
+ (double)data->progress.downloaded,
+ (double)data->progress.size_ul,
+ (double)data->progress.uploaded);
+ if(result)
+ failf(data, "Callback aborted");
+ return result;
+ }
+
+ if(!shownow)
+ /* only show the internal progress meter once per second */
+ return 0;
+
+ /* If there's no external callback set, use internal code to show
+ progress */
+
+ if(!(data->progress.flags & PGRS_HEADERS_OUT)) {
+ if(data->state.resume_from) {
+ fprintf(data->set.err,
+ "** Resuming transfer from byte position %"
+ CURL_FORMAT_CURL_OFF_T "\n", data->state.resume_from);
+ }
+ fprintf(data->set.err,
+ " %% Total %% Received %% Xferd Average Speed "
+ "Time Time Time Current\n"
+ " Dload Upload "
+ "Total Spent Left Speed\n");
+ data->progress.flags |= PGRS_HEADERS_OUT; /* headers are shown */
+ }
+
+ /* Figure out the estimated time of arrival for the upload */
+ if((data->progress.flags & PGRS_UL_SIZE_KNOWN) &&
+ (data->progress.ulspeed > CURL_OFF_T_C(0))) {
+ ulestimate = data->progress.size_ul / data->progress.ulspeed;
+
+ if(data->progress.size_ul > CURL_OFF_T_C(10000))
+ ulpercen = data->progress.uploaded /
+ (data->progress.size_ul/CURL_OFF_T_C(100));
+ else if(data->progress.size_ul > CURL_OFF_T_C(0))
+ ulpercen = (data->progress.uploaded*100) /
+ data->progress.size_ul;
+ }
+
+ /* ... and the download */
+ if((data->progress.flags & PGRS_DL_SIZE_KNOWN) &&
+ (data->progress.dlspeed > CURL_OFF_T_C(0))) {
+ dlestimate = data->progress.size_dl / data->progress.dlspeed;
+
+ if(data->progress.size_dl > CURL_OFF_T_C(10000))
+ dlpercen = data->progress.downloaded /
+ (data->progress.size_dl/CURL_OFF_T_C(100));
+ else if(data->progress.size_dl > CURL_OFF_T_C(0))
+ dlpercen = (data->progress.downloaded*100) /
+ data->progress.size_dl;
+ }
+
+ /* Now figure out which of them is slower and use that one for the
+ total estimate! */
+ total_estimate = ulestimate>dlestimate?ulestimate:dlestimate;
+
+ /* create the three time strings */
+ time2str(time_left, total_estimate > 0?(total_estimate - timespent):0);
+ time2str(time_total, total_estimate);
+ time2str(time_spent, timespent);
+
+ /* Get the total amount of data expected to get transferred */
+ total_expected_transfer =
+ (data->progress.flags & PGRS_UL_SIZE_KNOWN?
+ data->progress.size_ul:data->progress.uploaded)+
+ (data->progress.flags & PGRS_DL_SIZE_KNOWN?
+ data->progress.size_dl:data->progress.downloaded);
+
+ /* We have transferred this much so far */
+ total_transfer = data->progress.downloaded + data->progress.uploaded;
+
+ /* Get the percentage of data transferred so far */
+ if(total_expected_transfer > CURL_OFF_T_C(10000))
+ total_percen = total_transfer /
+ (total_expected_transfer/CURL_OFF_T_C(100));
+ else if(total_expected_transfer > CURL_OFF_T_C(0))
+ total_percen = (total_transfer*100) / total_expected_transfer;
+
+ fprintf(data->set.err,
+ "\r"
+ "%3" CURL_FORMAT_CURL_OFF_T " %s "
+ "%3" CURL_FORMAT_CURL_OFF_T " %s "
+ "%3" CURL_FORMAT_CURL_OFF_T " %s %s %s %s %s %s %s",
+ total_percen, /* 3 letters */ /* total % */
+ max5data(total_expected_transfer, max5[2]), /* total size */
+ dlpercen, /* 3 letters */ /* rcvd % */
+ max5data(data->progress.downloaded, max5[0]), /* rcvd size */
+ ulpercen, /* 3 letters */ /* xfer % */
+ max5data(data->progress.uploaded, max5[1]), /* xfer size */
+ max5data(data->progress.dlspeed, max5[3]), /* avrg dl speed */
+ max5data(data->progress.ulspeed, max5[4]), /* avrg ul speed */
+ time_total, /* 8 letters */ /* total time */
+ time_spent, /* 8 letters */ /* time spent */
+ time_left, /* 8 letters */ /* time left */
+ max5data(data->progress.current_speed, max5[5]) /* current speed */
+ );
+
+ /* we flush the output stream to make it appear as soon as possible */
+ fflush(data->set.err);
+
+ } /* !(data->progress.flags & PGRS_HIDE) */
+
+ return 0;
+}
diff --git a/Utilities/cmcurl/lib/progress.h b/Utilities/cmcurl/lib/progress.h
new file mode 100644
index 000000000..a1e6f1a23
--- /dev/null
+++ b/Utilities/cmcurl/lib/progress.h
@@ -0,0 +1,73 @@
+#ifndef HEADER_CURL_PROGRESS_H
+#define HEADER_CURL_PROGRESS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "timeval.h"
+
+
+typedef enum {
+ TIMER_NONE,
+ TIMER_STARTOP,
+ TIMER_STARTSINGLE,
+ TIMER_NAMELOOKUP,
+ TIMER_CONNECT,
+ TIMER_APPCONNECT,
+ TIMER_PRETRANSFER,
+ TIMER_STARTTRANSFER,
+ TIMER_POSTRANSFER,
+ TIMER_STARTACCEPT,
+ TIMER_REDIRECT,
+ TIMER_LAST /* must be last */
+} timerid;
+
+int Curl_pgrsDone(struct connectdata *);
+void Curl_pgrsStartNow(struct SessionHandle *data);
+void Curl_pgrsSetDownloadSize(struct SessionHandle *data, curl_off_t size);
+void Curl_pgrsSetUploadSize(struct SessionHandle *data, curl_off_t size);
+void Curl_pgrsSetDownloadCounter(struct SessionHandle *data, curl_off_t size);
+void Curl_pgrsSetUploadCounter(struct SessionHandle *data, curl_off_t size);
+int Curl_pgrsUpdate(struct connectdata *);
+void Curl_pgrsResetTimesSizes(struct SessionHandle *data);
+void Curl_pgrsTime(struct SessionHandle *data, timerid timer);
+
+
+/* Don't show progress for sizes smaller than: */
+#define LEAST_SIZE_PROGRESS BUFSIZE
+
+#define PROGRESS_DOWNLOAD (1<<0)
+#define PROGRESS_UPLOAD (1<<1)
+#define PROGRESS_DOWN_AND_UP (PROGRESS_UPLOAD | PROGRESS_DOWNLOAD)
+
+#define PGRS_SHOW_DL (1<<0)
+#define PGRS_SHOW_UL (1<<1)
+#define PGRS_DONE_DL (1<<2)
+#define PGRS_DONE_UL (1<<3)
+#define PGRS_HIDE (1<<4)
+#define PGRS_UL_SIZE_KNOWN (1<<5)
+#define PGRS_DL_SIZE_KNOWN (1<<6)
+
+#define PGRS_HEADERS_OUT (1<<7) /* set when the headers have been written */
+
+
+#endif /* HEADER_CURL_PROGRESS_H */
+
diff --git a/Utilities/cmcurl/lib/rawstr.c b/Utilities/cmcurl/lib/rawstr.c
new file mode 100644
index 000000000..e27dac4a8
--- /dev/null
+++ b/Utilities/cmcurl/lib/rawstr.c
@@ -0,0 +1,142 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "rawstr.h"
+
+/* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because
+ its behavior is altered by the current locale. */
+char Curl_raw_toupper(char in)
+{
+ switch (in) {
+ case 'a':
+ return 'A';
+ case 'b':
+ return 'B';
+ case 'c':
+ return 'C';
+ case 'd':
+ return 'D';
+ case 'e':
+ return 'E';
+ case 'f':
+ return 'F';
+ case 'g':
+ return 'G';
+ case 'h':
+ return 'H';
+ case 'i':
+ return 'I';
+ case 'j':
+ return 'J';
+ case 'k':
+ return 'K';
+ case 'l':
+ return 'L';
+ case 'm':
+ return 'M';
+ case 'n':
+ return 'N';
+ case 'o':
+ return 'O';
+ case 'p':
+ return 'P';
+ case 'q':
+ return 'Q';
+ case 'r':
+ return 'R';
+ case 's':
+ return 'S';
+ case 't':
+ return 'T';
+ case 'u':
+ return 'U';
+ case 'v':
+ return 'V';
+ case 'w':
+ return 'W';
+ case 'x':
+ return 'X';
+ case 'y':
+ return 'Y';
+ case 'z':
+ return 'Z';
+ }
+ return in;
+}
+
+/*
+ * Curl_raw_equal() is for doing "raw" case insensitive strings. This is meant
+ * to be locale independent and only compare strings we know are safe for
+ * this. See http://daniel.haxx.se/blog/2008/10/15/strcasecmp-in-turkish/ for
+ * some further explanation to why this function is necessary.
+ *
+ * The function is capable of comparing a-z case insensitively even for
+ * non-ascii.
+ */
+
+int Curl_raw_equal(const char *first, const char *second)
+{
+ while(*first && *second) {
+ if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second))
+ /* get out of the loop as soon as they don't match */
+ break;
+ first++;
+ second++;
+ }
+ /* we do the comparison here (possibly again), just to make sure that if the
+ loop above is skipped because one of the strings reached zero, we must not
+ return this as a successful match */
+ return (Curl_raw_toupper(*first) == Curl_raw_toupper(*second));
+}
+
+int Curl_raw_nequal(const char *first, const char *second, size_t max)
+{
+ while(*first && *second && max) {
+ if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second)) {
+ break;
+ }
+ max--;
+ first++;
+ second++;
+ }
+ if(0 == max)
+ return 1; /* they are equal this far */
+
+ return Curl_raw_toupper(*first) == Curl_raw_toupper(*second);
+}
+
+/* Copy an upper case version of the string from src to dest. The
+ * strings may overlap. No more than n characters of the string are copied
+ * (including any NUL) and the destination string will NOT be
+ * NUL-terminated if that limit is reached.
+ */
+void Curl_strntoupper(char *dest, const char *src, size_t n)
+{
+ if(n < 1)
+ return;
+
+ do {
+ *dest++ = Curl_raw_toupper(*src);
+ } while(*src++ && --n);
+}
diff --git a/Utilities/cmcurl/lib/rawstr.h b/Utilities/cmcurl/lib/rawstr.h
new file mode 100644
index 000000000..b491460d0
--- /dev/null
+++ b/Utilities/cmcurl/lib/rawstr.h
@@ -0,0 +1,47 @@
+#ifndef HEADER_CURL_RAWSTR_H
+#define HEADER_CURL_RAWSTR_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <curl/curl.h>
+
+/*
+ * Curl_raw_equal() is for doing "raw" case insensitive strings. This is meant
+ * to be locale independent and only compare strings we know are safe for
+ * this.
+ *
+ * The function is capable of comparing a-z case insensitively even for
+ * non-ascii.
+ */
+int Curl_raw_equal(const char *first, const char *second);
+int Curl_raw_nequal(const char *first, const char *second, size_t max);
+
+char Curl_raw_toupper(char in);
+
+/* checkprefix() is a shorter version of the above, used when the first
+ argument is zero-byte terminated */
+#define checkprefix(a,b) Curl_raw_nequal(a,b,strlen(a))
+
+void Curl_strntoupper(char *dest, const char *src, size_t n);
+
+#endif /* HEADER_CURL_RAWSTR_H */
+
diff --git a/Utilities/cmcurl/lib/rtsp.c b/Utilities/cmcurl/lib/rtsp.c
new file mode 100644
index 000000000..c30afd39d
--- /dev/null
+++ b/Utilities/cmcurl/lib/rtsp.c
@@ -0,0 +1,805 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_RTSP
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "transfer.h"
+#include "sendf.h"
+#include "multiif.h"
+#include "http.h"
+#include "url.h"
+#include "progress.h"
+#include "rtsp.h"
+#include "rawstr.h"
+#include "select.h"
+#include "connect.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+ * TODO (general)
+ * -incoming server requests
+ * -server CSeq counter
+ * -digest authentication
+ * -connect thru proxy
+ * -pipelining?
+ */
+
+
+#define RTP_PKT_CHANNEL(p) ((int)((unsigned char)((p)[1])))
+
+#define RTP_PKT_LENGTH(p) ((((int)((unsigned char)((p)[2]))) << 8) | \
+ ((int)((unsigned char)((p)[3]))))
+
+/* protocol-specific functions set up to be called by the main engine */
+static CURLcode rtsp_do(struct connectdata *conn, bool *done);
+static CURLcode rtsp_done(struct connectdata *conn, CURLcode, bool premature);
+static CURLcode rtsp_connect(struct connectdata *conn, bool *done);
+static CURLcode rtsp_disconnect(struct connectdata *conn, bool dead);
+
+static int rtsp_getsock_do(struct connectdata *conn,
+ curl_socket_t *socks,
+ int numsocks);
+
+/*
+ * Parse and write out any available RTP data.
+ *
+ * nread: amount of data left after k->str. will be modified if RTP
+ * data is parsed and k->str is moved up
+ * readmore: whether or not the RTP parser needs more data right away
+ */
+static CURLcode rtsp_rtp_readwrite(struct SessionHandle *data,
+ struct connectdata *conn,
+ ssize_t *nread,
+ bool *readmore);
+
+static CURLcode rtsp_setup_connection(struct connectdata *conn);
+
+
+/* this returns the socket to wait for in the DO and DOING state for the multi
+ interface and then we're always _sending_ a request and thus we wait for
+ the single socket to become writable only */
+static int rtsp_getsock_do(struct connectdata *conn,
+ curl_socket_t *socks,
+ int numsocks)
+{
+ /* write mode */
+ (void)numsocks; /* unused, we trust it to be at least 1 */
+ socks[0] = conn->sock[FIRSTSOCKET];
+ return GETSOCK_WRITESOCK(0);
+}
+
+static
+CURLcode rtp_client_write(struct connectdata *conn, char *ptr, size_t len);
+
+
+/*
+ * RTSP handler interface.
+ */
+const struct Curl_handler Curl_handler_rtsp = {
+ "RTSP", /* scheme */
+ rtsp_setup_connection, /* setup_connection */
+ rtsp_do, /* do_it */
+ rtsp_done, /* done */
+ ZERO_NULL, /* do_more */
+ rtsp_connect, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_getsock */
+ rtsp_getsock_do, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ rtsp_disconnect, /* disconnect */
+ rtsp_rtp_readwrite, /* readwrite */
+ PORT_RTSP, /* defport */
+ CURLPROTO_RTSP, /* protocol */
+ PROTOPT_NONE /* flags */
+};
+
+
+static CURLcode rtsp_setup_connection(struct connectdata *conn)
+{
+ struct RTSP *rtsp;
+
+ conn->data->req.protop = rtsp = calloc(1, sizeof(struct RTSP));
+ if(!rtsp)
+ return CURLE_OUT_OF_MEMORY;
+
+ return CURLE_OK;
+}
+
+
+/*
+ * The server may send us RTP data at any point, and RTSPREQ_RECEIVE does not
+ * want to block the application forever while receiving a stream. Therefore,
+ * we cannot assume that an RTSP socket is dead just because it is readable.
+ *
+ * Instead, if it is readable, run Curl_getconnectinfo() to peek at the socket
+ * and distinguish between closed and data.
+ */
+bool Curl_rtsp_connisdead(struct connectdata *check)
+{
+ int sval;
+ bool ret_val = TRUE;
+
+ sval = Curl_socket_ready(check->sock[FIRSTSOCKET], CURL_SOCKET_BAD, 0);
+ if(sval == 0) {
+ /* timeout */
+ ret_val = FALSE;
+ }
+ else if(sval & CURL_CSELECT_ERR) {
+ /* socket is in an error state */
+ ret_val = TRUE;
+ }
+ else if((sval & CURL_CSELECT_IN) && check->data) {
+ /* readable with no error. could be closed or could be alive but we can
+ only check if we have a proper SessionHandle for the connection */
+ curl_socket_t connectinfo = Curl_getconnectinfo(check->data, &check);
+ if(connectinfo != CURL_SOCKET_BAD)
+ ret_val = FALSE;
+ }
+
+ return ret_val;
+}
+
+static CURLcode rtsp_connect(struct connectdata *conn, bool *done)
+{
+ CURLcode httpStatus;
+ struct SessionHandle *data = conn->data;
+
+ httpStatus = Curl_http_connect(conn, done);
+
+ /* Initialize the CSeq if not already done */
+ if(data->state.rtsp_next_client_CSeq == 0)
+ data->state.rtsp_next_client_CSeq = 1;
+ if(data->state.rtsp_next_server_CSeq == 0)
+ data->state.rtsp_next_server_CSeq = 1;
+
+ conn->proto.rtspc.rtp_channel = -1;
+
+ return httpStatus;
+}
+
+static CURLcode rtsp_disconnect(struct connectdata *conn, bool dead)
+{
+ (void) dead;
+ Curl_safefree(conn->proto.rtspc.rtp_buf);
+ return CURLE_OK;
+}
+
+
+static CURLcode rtsp_done(struct connectdata *conn,
+ CURLcode status, bool premature)
+{
+ struct SessionHandle *data = conn->data;
+ struct RTSP *rtsp = data->req.protop;
+ CURLcode httpStatus;
+ long CSeq_sent;
+ long CSeq_recv;
+
+ /* Bypass HTTP empty-reply checks on receive */
+ if(data->set.rtspreq == RTSPREQ_RECEIVE)
+ premature = TRUE;
+
+ httpStatus = Curl_http_done(conn, status, premature);
+
+ if(rtsp) {
+ /* Check the sequence numbers */
+ CSeq_sent = rtsp->CSeq_sent;
+ CSeq_recv = rtsp->CSeq_recv;
+ if((data->set.rtspreq != RTSPREQ_RECEIVE) && (CSeq_sent != CSeq_recv)) {
+ failf(data,
+ "The CSeq of this request %ld did not match the response %ld",
+ CSeq_sent, CSeq_recv);
+ return CURLE_RTSP_CSEQ_ERROR;
+ }
+ else if(data->set.rtspreq == RTSPREQ_RECEIVE &&
+ (conn->proto.rtspc.rtp_channel == -1)) {
+ infof(data, "Got an RTP Receive with a CSeq of %ld\n", CSeq_recv);
+ /* TODO CPC: Server -> Client logic here */
+ }
+ }
+
+ return httpStatus;
+}
+
+static CURLcode rtsp_do(struct connectdata *conn, bool *done)
+{
+ struct SessionHandle *data = conn->data;
+ CURLcode result=CURLE_OK;
+ Curl_RtspReq rtspreq = data->set.rtspreq;
+ struct RTSP *rtsp = data->req.protop;
+ struct HTTP *http;
+ Curl_send_buffer *req_buffer;
+ curl_off_t postsize = 0; /* for ANNOUNCE and SET_PARAMETER */
+ curl_off_t putsize = 0; /* for ANNOUNCE and SET_PARAMETER */
+
+ const char *p_request = NULL;
+ const char *p_session_id = NULL;
+ const char *p_accept = NULL;
+ const char *p_accept_encoding = NULL;
+ const char *p_range = NULL;
+ const char *p_referrer = NULL;
+ const char *p_stream_uri = NULL;
+ const char *p_transport = NULL;
+ const char *p_uagent = NULL;
+
+ *done = TRUE;
+
+ http = &(rtsp->http_wrapper);
+ /* Assert that no one has changed the RTSP struct in an evil way */
+ DEBUGASSERT((void *)http == (void *)rtsp);
+
+ rtsp->CSeq_sent = data->state.rtsp_next_client_CSeq;
+ rtsp->CSeq_recv = 0;
+
+ /* Setup the 'p_request' pointer to the proper p_request string
+ * Since all RTSP requests are included here, there is no need to
+ * support custom requests like HTTP.
+ **/
+ data->set.opt_no_body = TRUE; /* most requests don't contain a body */
+ switch(rtspreq) {
+ default:
+ failf(data, "Got invalid RTSP request");
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ case RTSPREQ_OPTIONS:
+ p_request = "OPTIONS";
+ break;
+ case RTSPREQ_DESCRIBE:
+ p_request = "DESCRIBE";
+ data->set.opt_no_body = FALSE;
+ break;
+ case RTSPREQ_ANNOUNCE:
+ p_request = "ANNOUNCE";
+ break;
+ case RTSPREQ_SETUP:
+ p_request = "SETUP";
+ break;
+ case RTSPREQ_PLAY:
+ p_request = "PLAY";
+ break;
+ case RTSPREQ_PAUSE:
+ p_request = "PAUSE";
+ break;
+ case RTSPREQ_TEARDOWN:
+ p_request = "TEARDOWN";
+ break;
+ case RTSPREQ_GET_PARAMETER:
+ /* GET_PARAMETER's no_body status is determined later */
+ p_request = "GET_PARAMETER";
+ data->set.opt_no_body = FALSE;
+ break;
+ case RTSPREQ_SET_PARAMETER:
+ p_request = "SET_PARAMETER";
+ break;
+ case RTSPREQ_RECORD:
+ p_request = "RECORD";
+ break;
+ case RTSPREQ_RECEIVE:
+ p_request = "";
+ /* Treat interleaved RTP as body*/
+ data->set.opt_no_body = FALSE;
+ break;
+ case RTSPREQ_LAST:
+ failf(data, "Got invalid RTSP request: RTSPREQ_LAST");
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+
+ if(rtspreq == RTSPREQ_RECEIVE) {
+ Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
+ &http->readbytecount, -1, NULL);
+
+ return result;
+ }
+
+ p_session_id = data->set.str[STRING_RTSP_SESSION_ID];
+ if(!p_session_id &&
+ (rtspreq & ~(RTSPREQ_OPTIONS | RTSPREQ_DESCRIBE | RTSPREQ_SETUP))) {
+ failf(data, "Refusing to issue an RTSP request [%s] without a session ID.",
+ p_request);
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+
+ /* TODO: auth? */
+ /* TODO: proxy? */
+
+ /* Stream URI. Default to server '*' if not specified */
+ if(data->set.str[STRING_RTSP_STREAM_URI]) {
+ p_stream_uri = data->set.str[STRING_RTSP_STREAM_URI];
+ }
+ else {
+ p_stream_uri = "*";
+ }
+
+ /* Transport Header for SETUP requests */
+ p_transport = Curl_checkheaders(conn, "Transport:");
+ if(rtspreq == RTSPREQ_SETUP && !p_transport) {
+ /* New Transport: setting? */
+ if(data->set.str[STRING_RTSP_TRANSPORT]) {
+ Curl_safefree(conn->allocptr.rtsp_transport);
+
+ conn->allocptr.rtsp_transport =
+ aprintf("Transport: %s\r\n",
+ data->set.str[STRING_RTSP_TRANSPORT]);
+ if(!conn->allocptr.rtsp_transport)
+ return CURLE_OUT_OF_MEMORY;
+ }
+ else {
+ failf(data,
+ "Refusing to issue an RTSP SETUP without a Transport: header.");
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+
+ p_transport = conn->allocptr.rtsp_transport;
+ }
+
+ /* Accept Headers for DESCRIBE requests */
+ if(rtspreq == RTSPREQ_DESCRIBE) {
+ /* Accept Header */
+ p_accept = Curl_checkheaders(conn, "Accept:")?
+ NULL:"Accept: application/sdp\r\n";
+
+ /* Accept-Encoding header */
+ if(!Curl_checkheaders(conn, "Accept-Encoding:") &&
+ data->set.str[STRING_ENCODING]) {
+ Curl_safefree(conn->allocptr.accept_encoding);
+ conn->allocptr.accept_encoding =
+ aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
+
+ if(!conn->allocptr.accept_encoding)
+ return CURLE_OUT_OF_MEMORY;
+
+ p_accept_encoding = conn->allocptr.accept_encoding;
+ }
+ }
+
+ /* The User-Agent string might have been allocated in url.c already, because
+ it might have been used in the proxy connect, but if we have got a header
+ with the user-agent string specified, we erase the previously made string
+ here. */
+ if(Curl_checkheaders(conn, "User-Agent:") && conn->allocptr.uagent) {
+ Curl_safefree(conn->allocptr.uagent);
+ conn->allocptr.uagent = NULL;
+ }
+ else if(!Curl_checkheaders(conn, "User-Agent:") &&
+ data->set.str[STRING_USERAGENT]) {
+ p_uagent = conn->allocptr.uagent;
+ }
+
+ /* Referrer */
+ Curl_safefree(conn->allocptr.ref);
+ if(data->change.referer && !Curl_checkheaders(conn, "Referer:"))
+ conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
+ else
+ conn->allocptr.ref = NULL;
+
+ p_referrer = conn->allocptr.ref;
+
+ /*
+ * Range Header
+ * Only applies to PLAY, PAUSE, RECORD
+ *
+ * Go ahead and use the Range stuff supplied for HTTP
+ */
+ if(data->state.use_range &&
+ (rtspreq & (RTSPREQ_PLAY | RTSPREQ_PAUSE | RTSPREQ_RECORD))) {
+
+ /* Check to see if there is a range set in the custom headers */
+ if(!Curl_checkheaders(conn, "Range:") && data->state.range) {
+ Curl_safefree(conn->allocptr.rangeline);
+ conn->allocptr.rangeline = aprintf("Range: %s\r\n", data->state.range);
+ p_range = conn->allocptr.rangeline;
+ }
+ }
+
+ /*
+ * Sanity check the custom headers
+ */
+ if(Curl_checkheaders(conn, "CSeq:")) {
+ failf(data, "CSeq cannot be set as a custom header.");
+ return CURLE_RTSP_CSEQ_ERROR;
+ }
+ if(Curl_checkheaders(conn, "Session:")) {
+ failf(data, "Session ID cannot be set as a custom header.");
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+
+ /* Initialize a dynamic send buffer */
+ req_buffer = Curl_add_buffer_init();
+
+ if(!req_buffer)
+ return CURLE_OUT_OF_MEMORY;
+
+ result =
+ Curl_add_bufferf(req_buffer,
+ "%s %s RTSP/1.0\r\n" /* Request Stream-URI RTSP/1.0 */
+ "CSeq: %ld\r\n", /* CSeq */
+ p_request, p_stream_uri, rtsp->CSeq_sent);
+ if(result)
+ return result;
+
+ /*
+ * Rather than do a normal alloc line, keep the session_id unformatted
+ * to make comparison easier
+ */
+ if(p_session_id) {
+ result = Curl_add_bufferf(req_buffer, "Session: %s\r\n", p_session_id);
+ if(result)
+ return result;
+ }
+
+ /*
+ * Shared HTTP-like options
+ */
+ result = Curl_add_bufferf(req_buffer,
+ "%s" /* transport */
+ "%s" /* accept */
+ "%s" /* accept-encoding */
+ "%s" /* range */
+ "%s" /* referrer */
+ "%s" /* user-agent */
+ ,
+ p_transport ? p_transport : "",
+ p_accept ? p_accept : "",
+ p_accept_encoding ? p_accept_encoding : "",
+ p_range ? p_range : "",
+ p_referrer ? p_referrer : "",
+ p_uagent ? p_uagent : "");
+ if(result)
+ return result;
+
+ if((rtspreq == RTSPREQ_SETUP) || (rtspreq == RTSPREQ_DESCRIBE)) {
+ result = Curl_add_timecondition(data, req_buffer);
+ if(result)
+ return result;
+ }
+
+ result = Curl_add_custom_headers(conn, FALSE, req_buffer);
+ if(result)
+ return result;
+
+ if(rtspreq == RTSPREQ_ANNOUNCE ||
+ rtspreq == RTSPREQ_SET_PARAMETER ||
+ rtspreq == RTSPREQ_GET_PARAMETER) {
+
+ if(data->set.upload) {
+ putsize = data->state.infilesize;
+ data->set.httpreq = HTTPREQ_PUT;
+
+ }
+ else {
+ postsize = (data->state.infilesize != -1)?
+ data->state.infilesize:
+ (data->set.postfields? (curl_off_t)strlen(data->set.postfields):0);
+ data->set.httpreq = HTTPREQ_POST;
+ }
+
+ if(putsize > 0 || postsize > 0) {
+ /* As stated in the http comments, it is probably not wise to
+ * actually set a custom Content-Length in the headers */
+ if(!Curl_checkheaders(conn, "Content-Length:")) {
+ result = Curl_add_bufferf(req_buffer,
+ "Content-Length: %" CURL_FORMAT_CURL_OFF_T"\r\n",
+ (data->set.upload ? putsize : postsize));
+ if(result)
+ return result;
+ }
+
+ if(rtspreq == RTSPREQ_SET_PARAMETER ||
+ rtspreq == RTSPREQ_GET_PARAMETER) {
+ if(!Curl_checkheaders(conn, "Content-Type:")) {
+ result = Curl_add_bufferf(req_buffer,
+ "Content-Type: text/parameters\r\n");
+ if(result)
+ return result;
+ }
+ }
+
+ if(rtspreq == RTSPREQ_ANNOUNCE) {
+ if(!Curl_checkheaders(conn, "Content-Type:")) {
+ result = Curl_add_bufferf(req_buffer,
+ "Content-Type: application/sdp\r\n");
+ if(result)
+ return result;
+ }
+ }
+
+ data->state.expect100header = FALSE; /* RTSP posts are simple/small */
+ }
+ else if(rtspreq == RTSPREQ_GET_PARAMETER) {
+ /* Check for an empty GET_PARAMETER (heartbeat) request */
+ data->set.httpreq = HTTPREQ_HEAD;
+ data->set.opt_no_body = TRUE;
+ }
+ }
+
+ /* RTSP never allows chunked transfer */
+ data->req.forbidchunk = TRUE;
+ /* Finish the request buffer */
+ result = Curl_add_buffer(req_buffer, "\r\n", 2);
+ if(result)
+ return result;
+
+ if(postsize > 0) {
+ result = Curl_add_buffer(req_buffer, data->set.postfields,
+ (size_t)postsize);
+ if(result)
+ return result;
+ }
+
+ /* issue the request */
+ result = Curl_add_buffer_send(req_buffer, conn,
+ &data->info.request_size, 0, FIRSTSOCKET);
+ if(result) {
+ failf(data, "Failed sending RTSP request");
+ return result;
+ }
+
+ Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
+ putsize?FIRSTSOCKET:-1,
+ putsize?&http->writebytecount:NULL);
+
+ /* Increment the CSeq on success */
+ data->state.rtsp_next_client_CSeq++;
+
+ if(http->writebytecount) {
+ /* if a request-body has been sent off, we make sure this progress is
+ noted properly */
+ Curl_pgrsSetUploadCounter(data, http->writebytecount);
+ if(Curl_pgrsUpdate(conn))
+ result = CURLE_ABORTED_BY_CALLBACK;
+ }
+
+ return result;
+}
+
+
+static CURLcode rtsp_rtp_readwrite(struct SessionHandle *data,
+ struct connectdata *conn,
+ ssize_t *nread,
+ bool *readmore) {
+ struct SingleRequest *k = &data->req;
+ struct rtsp_conn *rtspc = &(conn->proto.rtspc);
+
+ char *rtp; /* moving pointer to rtp data */
+ ssize_t rtp_dataleft; /* how much data left to parse in this round */
+ char *scratch;
+ CURLcode result;
+
+ if(rtspc->rtp_buf) {
+ /* There was some leftover data the last time. Merge buffers */
+ char *newptr = realloc(rtspc->rtp_buf, rtspc->rtp_bufsize + *nread);
+ if(!newptr) {
+ Curl_safefree(rtspc->rtp_buf);
+ rtspc->rtp_buf = NULL;
+ rtspc->rtp_bufsize = 0;
+ return CURLE_OUT_OF_MEMORY;
+ }
+ rtspc->rtp_buf = newptr;
+ memcpy(rtspc->rtp_buf + rtspc->rtp_bufsize, k->str, *nread);
+ rtspc->rtp_bufsize += *nread;
+ rtp = rtspc->rtp_buf;
+ rtp_dataleft = rtspc->rtp_bufsize;
+ }
+ else {
+ /* Just parse the request buffer directly */
+ rtp = k->str;
+ rtp_dataleft = *nread;
+ }
+
+ while((rtp_dataleft > 0) &&
+ (rtp[0] == '$')) {
+ if(rtp_dataleft > 4) {
+ int rtp_length;
+
+ /* Parse the header */
+ /* The channel identifier immediately follows and is 1 byte */
+ rtspc->rtp_channel = RTP_PKT_CHANNEL(rtp);
+
+ /* The length is two bytes */
+ rtp_length = RTP_PKT_LENGTH(rtp);
+
+ if(rtp_dataleft < rtp_length + 4) {
+ /* Need more - incomplete payload*/
+ *readmore = TRUE;
+ break;
+ }
+ else {
+ /* We have the full RTP interleaved packet
+ * Write out the header including the leading '$' */
+ DEBUGF(infof(data, "RTP write channel %d rtp_length %d\n",
+ rtspc->rtp_channel, rtp_length));
+ result = rtp_client_write(conn, &rtp[0], rtp_length + 4);
+ if(result) {
+ failf(data, "Got an error writing an RTP packet");
+ *readmore = FALSE;
+ Curl_safefree(rtspc->rtp_buf);
+ rtspc->rtp_buf = NULL;
+ rtspc->rtp_bufsize = 0;
+ return result;
+ }
+
+ /* Move forward in the buffer */
+ rtp_dataleft -= rtp_length + 4;
+ rtp += rtp_length + 4;
+
+ if(data->set.rtspreq == RTSPREQ_RECEIVE) {
+ /* If we are in a passive receive, give control back
+ * to the app as often as we can.
+ */
+ k->keepon &= ~KEEP_RECV;
+ }
+ }
+ }
+ else {
+ /* Need more - incomplete header */
+ *readmore = TRUE;
+ break;
+ }
+ }
+
+ if(rtp_dataleft != 0 && rtp[0] == '$') {
+ DEBUGF(infof(data, "RTP Rewinding %zd %s\n", rtp_dataleft,
+ *readmore ? "(READMORE)" : ""));
+
+ /* Store the incomplete RTP packet for a "rewind" */
+ scratch = malloc(rtp_dataleft);
+ if(!scratch) {
+ Curl_safefree(rtspc->rtp_buf);
+ rtspc->rtp_buf = NULL;
+ rtspc->rtp_bufsize = 0;
+ return CURLE_OUT_OF_MEMORY;
+ }
+ memcpy(scratch, rtp, rtp_dataleft);
+ Curl_safefree(rtspc->rtp_buf);
+ rtspc->rtp_buf = scratch;
+ rtspc->rtp_bufsize = rtp_dataleft;
+
+ /* As far as the transfer is concerned, this data is consumed */
+ *nread = 0;
+ return CURLE_OK;
+ }
+ else {
+ /* Fix up k->str to point just after the last RTP packet */
+ k->str += *nread - rtp_dataleft;
+
+ /* either all of the data has been read or...
+ * rtp now points at the next byte to parse
+ */
+ if(rtp_dataleft > 0)
+ DEBUGASSERT(k->str[0] == rtp[0]);
+
+ DEBUGASSERT(rtp_dataleft <= *nread); /* sanity check */
+
+ *nread = rtp_dataleft;
+ }
+
+ /* If we get here, we have finished with the leftover/merge buffer */
+ Curl_safefree(rtspc->rtp_buf);
+ rtspc->rtp_buf = NULL;
+ rtspc->rtp_bufsize = 0;
+
+ return CURLE_OK;
+}
+
+static
+CURLcode rtp_client_write(struct connectdata *conn, char *ptr, size_t len)
+{
+ struct SessionHandle *data = conn->data;
+ size_t wrote;
+ curl_write_callback writeit;
+
+ if(len == 0) {
+ failf (data, "Cannot write a 0 size RTP packet.");
+ return CURLE_WRITE_ERROR;
+ }
+
+ writeit = data->set.fwrite_rtp?data->set.fwrite_rtp:data->set.fwrite_func;
+ wrote = writeit(ptr, 1, len, data->set.rtp_out);
+
+ if(CURL_WRITEFUNC_PAUSE == wrote) {
+ failf (data, "Cannot pause RTP");
+ return CURLE_WRITE_ERROR;
+ }
+
+ if(wrote != len) {
+ failf (data, "Failed writing RTP data");
+ return CURLE_WRITE_ERROR;
+ }
+
+ return CURLE_OK;
+}
+
+CURLcode Curl_rtsp_parseheader(struct connectdata *conn,
+ char *header)
+{
+ struct SessionHandle *data = conn->data;
+ long CSeq = 0;
+
+ if(checkprefix("CSeq:", header)) {
+ /* Store the received CSeq. Match is verified in rtsp_done */
+ int nc = sscanf(&header[4], ": %ld", &CSeq);
+ if(nc == 1) {
+ struct RTSP *rtsp = data->req.protop;
+ rtsp->CSeq_recv = CSeq; /* mark the request */
+ data->state.rtsp_CSeq_recv = CSeq; /* update the handle */
+ }
+ else {
+ failf(data, "Unable to read the CSeq header: [%s]", header);
+ return CURLE_RTSP_CSEQ_ERROR;
+ }
+ }
+ else if(checkprefix("Session:", header)) {
+ char *start;
+
+ /* Find the first non-space letter */
+ start = header + 8;
+ while(*start && ISSPACE(*start))
+ start++;
+
+ if(!*start) {
+ failf(data, "Got a blank Session ID");
+ }
+ else if(data->set.str[STRING_RTSP_SESSION_ID]) {
+ /* If the Session ID is set, then compare */
+ if(strncmp(start, data->set.str[STRING_RTSP_SESSION_ID],
+ strlen(data->set.str[STRING_RTSP_SESSION_ID])) != 0) {
+ failf(data, "Got RTSP Session ID Line [%s], but wanted ID [%s]",
+ start, data->set.str[STRING_RTSP_SESSION_ID]);
+ return CURLE_RTSP_SESSION_ERROR;
+ }
+ }
+ else {
+ /* If the Session ID is not set, and we find it in a response, then
+ set it */
+
+ /* The session ID can be an alphanumeric or a 'safe' character
+ *
+ * RFC 2326 15.1 Base Syntax:
+ * safe = "\$" | "-" | "_" | "." | "+"
+ * */
+ char *end = start;
+ while(*end &&
+ (ISALNUM(*end) || *end == '-' || *end == '_' || *end == '.' ||
+ *end == '+' ||
+ (*end == '\\' && *(end + 1) && *(end + 1) == '$' && (++end, 1))))
+ end++;
+
+ /* Copy the id substring into a new buffer */
+ data->set.str[STRING_RTSP_SESSION_ID] = malloc(end - start + 1);
+ if(data->set.str[STRING_RTSP_SESSION_ID] == NULL)
+ return CURLE_OUT_OF_MEMORY;
+ memcpy(data->set.str[STRING_RTSP_SESSION_ID], start, end - start);
+ (data->set.str[STRING_RTSP_SESSION_ID])[end - start] = '\0';
+ }
+ }
+ return CURLE_OK;
+}
+
+#endif /* CURL_DISABLE_RTSP */
diff --git a/Utilities/cmcurl/lib/rtsp.h b/Utilities/cmcurl/lib/rtsp.h
new file mode 100644
index 000000000..3ffa70cc6
--- /dev/null
+++ b/Utilities/cmcurl/lib/rtsp.h
@@ -0,0 +1,69 @@
+#ifndef HEADER_CURL_RTSP_H
+#define HEADER_CURL_RTSP_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#ifndef CURL_DISABLE_RTSP
+
+extern const struct Curl_handler Curl_handler_rtsp;
+
+bool Curl_rtsp_connisdead(struct connectdata *check);
+CURLcode Curl_rtsp_parseheader(struct connectdata *conn, char *header);
+
+#else
+/* disabled */
+#define Curl_rtsp_parseheader(x,y) CURLE_NOT_BUILT_IN
+#define Curl_rtsp_connisdead(x) TRUE
+
+#endif /* CURL_DISABLE_RTSP */
+
+/*
+ * RTSP Connection data
+ *
+ * Currently, only used for tracking incomplete RTP data reads
+ */
+struct rtsp_conn {
+ char *rtp_buf;
+ ssize_t rtp_bufsize;
+ int rtp_channel;
+};
+
+/****************************************************************************
+ * RTSP unique setup
+ ***************************************************************************/
+struct RTSP {
+ /*
+ * http_wrapper MUST be the first element of this structure for the wrap
+ * logic to work. In this way, we get a cheap polymorphism because
+ * &(data->state.proto.rtsp) == &(data->state.proto.http) per the C spec
+ *
+ * HTTP functions can safely treat this as an HTTP struct, but RTSP aware
+ * functions can also index into the later elements.
+ */
+ struct HTTP http_wrapper; /*wrap HTTP to do the heavy lifting */
+
+ long CSeq_sent; /* CSeq of this request */
+ long CSeq_recv; /* CSeq received */
+};
+
+
+#endif /* HEADER_CURL_RTSP_H */
+
diff --git a/Utilities/cmcurl/lib/security.c b/Utilities/cmcurl/lib/security.c
new file mode 100644
index 000000000..014bbf1b8
--- /dev/null
+++ b/Utilities/cmcurl/lib/security.c
@@ -0,0 +1,580 @@
+/* This source code was modified by Martin Hedenfalk <mhe@stacken.kth.se> for
+ * use in Curl. His latest changes were done 2000-09-18.
+ *
+ * It has since been patched and modified a lot by Daniel Stenberg
+ * <daniel@haxx.se> to make it better applied to curl conditions, and to make
+ * it not use globals, pollute name space and more. This source code awaits a
+ * rewrite to work around the paragraph 2 in the BSD licenses as explained
+ * below.
+ *
+ * Copyright (c) 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ *
+ * Copyright (C) 2001 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE. */
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_FTP
+#ifdef HAVE_GSSAPI
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include "urldata.h"
+#include "curl_base64.h"
+#include "curl_memory.h"
+#include "curl_sec.h"
+#include "ftp.h"
+#include "sendf.h"
+#include "rawstr.h"
+#include "warnless.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+static const struct {
+ enum protection_level level;
+ const char *name;
+} level_names[] = {
+ { PROT_CLEAR, "clear" },
+ { PROT_SAFE, "safe" },
+ { PROT_CONFIDENTIAL, "confidential" },
+ { PROT_PRIVATE, "private" }
+};
+
+static enum protection_level
+name_to_level(const char *name)
+{
+ int i;
+ for(i = 0; i < (int)sizeof(level_names)/(int)sizeof(level_names[0]); i++)
+ if(checkprefix(name, level_names[i].name))
+ return level_names[i].level;
+ return PROT_NONE;
+}
+
+/* Convert a protocol |level| to its char representation.
+ We take an int to catch programming mistakes. */
+static char level_to_char(int level) {
+ switch(level) {
+ case PROT_CLEAR:
+ return 'C';
+ case PROT_SAFE:
+ return 'S';
+ case PROT_CONFIDENTIAL:
+ return 'E';
+ case PROT_PRIVATE:
+ return 'P';
+ case PROT_CMD:
+ /* Fall through */
+ default:
+ /* Those 2 cases should not be reached! */
+ break;
+ }
+ DEBUGASSERT(0);
+ /* Default to the most secure alternative. */
+ return 'P';
+}
+
+/* Send an FTP command defined by |message| and the optional arguments. The
+ function returns the ftp_code. If an error occurs, -1 is returned. */
+static int ftp_send_command(struct connectdata *conn, const char *message, ...)
+{
+ int ftp_code;
+ ssize_t nread=0;
+ va_list args;
+ char print_buffer[50];
+
+ va_start(args, message);
+ vsnprintf(print_buffer, sizeof(print_buffer), message, args);
+ va_end(args);
+
+ if(Curl_ftpsendf(conn, print_buffer)) {
+ ftp_code = -1;
+ }
+ else {
+ if(Curl_GetFTPResponse(&nread, conn, &ftp_code))
+ ftp_code = -1;
+ }
+
+ (void)nread; /* Unused */
+ return ftp_code;
+}
+
+/* Read |len| from the socket |fd| and store it in |to|. Return a CURLcode
+ saying whether an error occurred or CURLE_OK if |len| was read. */
+static CURLcode
+socket_read(curl_socket_t fd, void *to, size_t len)
+{
+ char *to_p = to;
+ CURLcode result;
+ ssize_t nread;
+
+ while(len > 0) {
+ result = Curl_read_plain(fd, to_p, len, &nread);
+ if(!result) {
+ len -= nread;
+ to_p += nread;
+ }
+ else {
+ /* FIXME: We are doing a busy wait */
+ if(result == CURLE_AGAIN)
+ continue;
+ return result;
+ }
+ }
+ return CURLE_OK;
+}
+
+
+/* Write |len| bytes from the buffer |to| to the socket |fd|. Return a
+ CURLcode saying whether an error occurred or CURLE_OK if |len| was
+ written. */
+static CURLcode
+socket_write(struct connectdata *conn, curl_socket_t fd, const void *to,
+ size_t len)
+{
+ const char *to_p = to;
+ CURLcode result;
+ ssize_t written;
+
+ while(len > 0) {
+ result = Curl_write_plain(conn, fd, to_p, len, &written);
+ if(!result) {
+ len -= written;
+ to_p += written;
+ }
+ else {
+ /* FIXME: We are doing a busy wait */
+ if(result == CURLE_AGAIN)
+ continue;
+ return result;
+ }
+ }
+ return CURLE_OK;
+}
+
+static CURLcode read_data(struct connectdata *conn,
+ curl_socket_t fd,
+ struct krb5buffer *buf)
+{
+ int len;
+ void* tmp;
+ CURLcode result;
+
+ result = socket_read(fd, &len, sizeof(len));
+ if(result)
+ return result;
+
+ len = ntohl(len);
+ tmp = realloc(buf->data, len);
+ if(tmp == NULL)
+ return CURLE_OUT_OF_MEMORY;
+
+ buf->data = tmp;
+ result = socket_read(fd, buf->data, len);
+ if(result)
+ return result;
+ buf->size = conn->mech->decode(conn->app_data, buf->data, len,
+ conn->data_prot, conn);
+ buf->index = 0;
+ return CURLE_OK;
+}
+
+static size_t
+buffer_read(struct krb5buffer *buf, void *data, size_t len)
+{
+ if(buf->size - buf->index < len)
+ len = buf->size - buf->index;
+ memcpy(data, (char*)buf->data + buf->index, len);
+ buf->index += len;
+ return len;
+}
+
+/* Matches Curl_recv signature */
+static ssize_t sec_recv(struct connectdata *conn, int sockindex,
+ char *buffer, size_t len, CURLcode *err)
+{
+ size_t bytes_read;
+ size_t total_read = 0;
+ curl_socket_t fd = conn->sock[sockindex];
+
+ *err = CURLE_OK;
+
+ /* Handle clear text response. */
+ if(conn->sec_complete == 0 || conn->data_prot == PROT_CLEAR)
+ return read(fd, buffer, len);
+
+ if(conn->in_buffer.eof_flag) {
+ conn->in_buffer.eof_flag = 0;
+ return 0;
+ }
+
+ bytes_read = buffer_read(&conn->in_buffer, buffer, len);
+ len -= bytes_read;
+ total_read += bytes_read;
+ buffer += bytes_read;
+
+ while(len > 0) {
+ if(read_data(conn, fd, &conn->in_buffer))
+ return -1;
+ if(conn->in_buffer.size == 0) {
+ if(bytes_read > 0)
+ conn->in_buffer.eof_flag = 1;
+ return bytes_read;
+ }
+ bytes_read = buffer_read(&conn->in_buffer, buffer, len);
+ len -= bytes_read;
+ total_read += bytes_read;
+ buffer += bytes_read;
+ }
+ /* FIXME: Check for overflow */
+ return total_read;
+}
+
+/* Send |length| bytes from |from| to the |fd| socket taking care of encoding
+ and negociating with the server. |from| can be NULL. */
+/* FIXME: We don't check for errors nor report any! */
+static void do_sec_send(struct connectdata *conn, curl_socket_t fd,
+ const char *from, int length)
+{
+ int bytes, htonl_bytes; /* 32-bit integers for htonl */
+ char *buffer = NULL;
+ char *cmd_buffer;
+ size_t cmd_size = 0;
+ CURLcode error;
+ enum protection_level prot_level = conn->data_prot;
+ bool iscmd = (prot_level == PROT_CMD)?TRUE:FALSE;
+
+ DEBUGASSERT(prot_level > PROT_NONE && prot_level < PROT_LAST);
+
+ if(iscmd) {
+ if(!strncmp(from, "PASS ", 5) || !strncmp(from, "ACCT ", 5))
+ prot_level = PROT_PRIVATE;
+ else
+ prot_level = conn->command_prot;
+ }
+ bytes = conn->mech->encode(conn->app_data, from, length, prot_level,
+ (void**)&buffer);
+ if(!buffer || bytes <= 0)
+ return; /* error */
+
+ if(iscmd) {
+ error = Curl_base64_encode(conn->data, buffer, curlx_sitouz(bytes),
+ &cmd_buffer, &cmd_size);
+ if(error) {
+ free(buffer);
+ return; /* error */
+ }
+ if(cmd_size > 0) {
+ static const char *enc = "ENC ";
+ static const char *mic = "MIC ";
+ if(prot_level == PROT_PRIVATE)
+ socket_write(conn, fd, enc, 4);
+ else
+ socket_write(conn, fd, mic, 4);
+
+ socket_write(conn, fd, cmd_buffer, cmd_size);
+ socket_write(conn, fd, "\r\n", 2);
+ infof(conn->data, "Send: %s%s\n", prot_level == PROT_PRIVATE?enc:mic,
+ cmd_buffer);
+ free(cmd_buffer);
+ }
+ }
+ else {
+ htonl_bytes = htonl(bytes);
+ socket_write(conn, fd, &htonl_bytes, sizeof(htonl_bytes));
+ socket_write(conn, fd, buffer, curlx_sitouz(bytes));
+ }
+ free(buffer);
+}
+
+static ssize_t sec_write(struct connectdata *conn, curl_socket_t fd,
+ const char *buffer, size_t length)
+{
+ ssize_t tx = 0, len = conn->buffer_size;
+
+ len -= conn->mech->overhead(conn->app_data, conn->data_prot,
+ curlx_sztosi(len));
+ if(len <= 0)
+ len = length;
+ while(length) {
+ if(length < (size_t)len)
+ len = length;
+
+ do_sec_send(conn, fd, buffer, curlx_sztosi(len));
+ length -= len;
+ buffer += len;
+ tx += len;
+ }
+ return tx;
+}
+
+/* Matches Curl_send signature */
+static ssize_t sec_send(struct connectdata *conn, int sockindex,
+ const void *buffer, size_t len, CURLcode *err)
+{
+ curl_socket_t fd = conn->sock[sockindex];
+ *err = CURLE_OK;
+ return sec_write(conn, fd, buffer, len);
+}
+
+int Curl_sec_read_msg(struct connectdata *conn, char *buffer,
+ enum protection_level level)
+{
+ /* decoded_len should be size_t or ssize_t but conn->mech->decode returns an
+ int */
+ int decoded_len;
+ char *buf;
+ int ret_code = 0;
+ size_t decoded_sz = 0;
+ CURLcode error;
+
+ DEBUGASSERT(level > PROT_NONE && level < PROT_LAST);
+
+ error = Curl_base64_decode(buffer + 4, (unsigned char **)&buf, &decoded_sz);
+ if(error || decoded_sz == 0)
+ return -1;
+
+ if(decoded_sz > (size_t)INT_MAX) {
+ free(buf);
+ return -1;
+ }
+ decoded_len = curlx_uztosi(decoded_sz);
+
+ decoded_len = conn->mech->decode(conn->app_data, buf, decoded_len,
+ level, conn);
+ if(decoded_len <= 0) {
+ free(buf);
+ return -1;
+ }
+
+ if(conn->data->set.verbose) {
+ buf[decoded_len] = '\n';
+ Curl_debug(conn->data, CURLINFO_HEADER_IN, buf, decoded_len + 1, conn);
+ }
+
+ buf[decoded_len] = '\0';
+ if(decoded_len <= 3)
+ /* suspiciously short */
+ return 0;
+
+ if(buf[3] != '-')
+ /* safe to ignore return code */
+ (void)sscanf(buf, "%d", &ret_code);
+
+ if(buf[decoded_len - 1] == '\n')
+ buf[decoded_len - 1] = '\0';
+ /* FIXME: Is |buffer| length always greater than |decoded_len|? */
+ strcpy(buffer, buf);
+ free(buf);
+ return ret_code;
+}
+
+/* FIXME: The error code returned here is never checked. */
+static int sec_set_protection_level(struct connectdata *conn)
+{
+ int code;
+ char* pbsz;
+ static unsigned int buffer_size = 1 << 20; /* 1048576 */
+ enum protection_level level = conn->request_data_prot;
+
+ DEBUGASSERT(level > PROT_NONE && level < PROT_LAST);
+
+ if(!conn->sec_complete) {
+ infof(conn->data, "Trying to change the protection level after the"
+ "completion of the data exchange.\n");
+ return -1;
+ }
+
+ /* Bail out if we try to set up the same level */
+ if(conn->data_prot == level)
+ return 0;
+
+ if(level) {
+ code = ftp_send_command(conn, "PBSZ %u", buffer_size);
+ if(code < 0)
+ return -1;
+
+ if(code/100 != 2) {
+ failf(conn->data, "Failed to set the protection's buffer size.");
+ return -1;
+ }
+ conn->buffer_size = buffer_size;
+
+ pbsz = strstr(conn->data->state.buffer, "PBSZ=");
+ if(pbsz) {
+ /* ignore return code, use default value if it fails */
+ (void)sscanf(pbsz, "PBSZ=%u", &buffer_size);
+ if(buffer_size < conn->buffer_size)
+ conn->buffer_size = buffer_size;
+ }
+ }
+
+ /* Now try to negiociate the protection level. */
+ code = ftp_send_command(conn, "PROT %c", level_to_char(level));
+
+ if(code < 0)
+ return -1;
+
+ if(code/100 != 2) {
+ failf(conn->data, "Failed to set the protection level.");
+ return -1;
+ }
+
+ conn->data_prot = level;
+ if(level == PROT_PRIVATE)
+ conn->command_prot = level;
+
+ return 0;
+}
+
+int
+Curl_sec_request_prot(struct connectdata *conn, const char *level)
+{
+ enum protection_level l = name_to_level(level);
+ if(l == PROT_NONE)
+ return -1;
+ DEBUGASSERT(l > PROT_NONE && l < PROT_LAST);
+ conn->request_data_prot = l;
+ return 0;
+}
+
+static CURLcode choose_mech(struct connectdata *conn)
+{
+ int ret;
+ struct SessionHandle *data = conn->data;
+ void *tmp_allocation;
+ const struct Curl_sec_client_mech *mech = &Curl_krb5_client_mech;
+
+ tmp_allocation = realloc(conn->app_data, mech->size);
+ if(tmp_allocation == NULL) {
+ failf(data, "Failed realloc of size %u", mech->size);
+ mech = NULL;
+ return CURLE_OUT_OF_MEMORY;
+ }
+ conn->app_data = tmp_allocation;
+
+ if(mech->init) {
+ ret = mech->init(conn->app_data);
+ if(ret) {
+ infof(data, "Failed initialization for %s. Skipping it.\n",
+ mech->name);
+ return CURLE_FAILED_INIT;
+ }
+ }
+
+ infof(data, "Trying mechanism %s...\n", mech->name);
+ ret = ftp_send_command(conn, "AUTH %s", mech->name);
+ if(ret < 0)
+ /* FIXME: This error is too generic but it is OK for now. */
+ return CURLE_COULDNT_CONNECT;
+
+ if(ret/100 != 3) {
+ switch(ret) {
+ case 504:
+ infof(data, "Mechanism %s is not supported by the server (server "
+ "returned ftp code: 504).\n", mech->name);
+ break;
+ case 534:
+ infof(data, "Mechanism %s was rejected by the server (server returned "
+ "ftp code: 534).\n", mech->name);
+ break;
+ default:
+ if(ret/100 == 5) {
+ infof(data, "server does not support the security extensions\n");
+ return CURLE_USE_SSL_FAILED;
+ }
+ break;
+ }
+ return CURLE_LOGIN_DENIED;
+ }
+
+ /* Authenticate */
+ ret = mech->auth(conn->app_data, conn);
+
+ if(ret != AUTH_CONTINUE) {
+ if(ret != AUTH_OK) {
+ /* Mechanism has dumped the error to stderr, don't error here. */
+ return -1;
+ }
+ DEBUGASSERT(ret == AUTH_OK);
+
+ conn->mech = mech;
+ conn->sec_complete = 1;
+ conn->recv[FIRSTSOCKET] = sec_recv;
+ conn->send[FIRSTSOCKET] = sec_send;
+ conn->recv[SECONDARYSOCKET] = sec_recv;
+ conn->send[SECONDARYSOCKET] = sec_send;
+ conn->command_prot = PROT_SAFE;
+ /* Set the requested protection level */
+ /* BLOCKING */
+ (void)sec_set_protection_level(conn);
+ }
+
+ return CURLE_OK;
+}
+
+CURLcode
+Curl_sec_login(struct connectdata *conn)
+{
+ return choose_mech(conn);
+}
+
+
+void
+Curl_sec_end(struct connectdata *conn)
+{
+ if(conn->mech != NULL && conn->mech->end)
+ conn->mech->end(conn->app_data);
+ free(conn->app_data);
+ conn->app_data = NULL;
+ if(conn->in_buffer.data) {
+ free(conn->in_buffer.data);
+ conn->in_buffer.data = NULL;
+ conn->in_buffer.size = 0;
+ conn->in_buffer.index = 0;
+ /* FIXME: Is this really needed? */
+ conn->in_buffer.eof_flag = 0;
+ }
+ conn->sec_complete = 0;
+ conn->data_prot = PROT_CLEAR;
+ conn->mech = NULL;
+}
+
+#endif /* HAVE_GSSAPI */
+
+#endif /* CURL_DISABLE_FTP */
diff --git a/Utilities/cmcurl/lib/select.c b/Utilities/cmcurl/lib/select.c
new file mode 100644
index 000000000..6eff07024
--- /dev/null
+++ b/Utilities/cmcurl/lib/select.c
@@ -0,0 +1,578 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+#if !defined(HAVE_SELECT) && !defined(HAVE_POLL_FINE)
+#error "We can't compile without select() or poll() support."
+#endif
+
+#if defined(__BEOS__)
+/* BeOS has FD_SET defined in socket.h */
+#include <socket.h>
+#endif
+
+#ifdef MSDOS
+#include <dos.h> /* delay() */
+#endif
+
+#ifdef __VXWORKS__
+#include <strings.h> /* bzero() in FD_SET */
+#endif
+
+#include <curl/curl.h>
+
+#include "urldata.h"
+#include "connect.h"
+#include "select.h"
+#include "warnless.h"
+
+/* Convenience local macros */
+
+#define elapsed_ms (int)curlx_tvdiff(curlx_tvnow(), initial_tv)
+
+int Curl_ack_eintr = 0;
+#define error_not_EINTR (Curl_ack_eintr || error != EINTR)
+
+/*
+ * Internal function used for waiting a specific amount of ms
+ * in Curl_socket_ready() and Curl_poll() when no file descriptor
+ * is provided to wait on, just being used to delay execution.
+ * WinSock select() and poll() timeout mechanisms need a valid
+ * socket descriptor in a not null file descriptor set to work.
+ * Waiting indefinitely with this function is not allowed, a
+ * zero or negative timeout value will return immediately.
+ * Timeout resolution, accuracy, as well as maximum supported
+ * value is system dependent, neither factor is a citical issue
+ * for the intended use of this function in the library.
+ *
+ * Return values:
+ * -1 = system call error, invalid timeout value, or interrupted
+ * 0 = specified timeout has elapsed
+ */
+int Curl_wait_ms(int timeout_ms)
+{
+#if !defined(MSDOS) && !defined(USE_WINSOCK)
+#ifndef HAVE_POLL_FINE
+ struct timeval pending_tv;
+#endif
+ struct timeval initial_tv;
+ int pending_ms;
+ int error;
+#endif
+ int r = 0;
+
+ if(!timeout_ms)
+ return 0;
+ if(timeout_ms < 0) {
+ SET_SOCKERRNO(EINVAL);
+ return -1;
+ }
+#if defined(MSDOS)
+ delay(timeout_ms);
+#elif defined(USE_WINSOCK)
+ Sleep(timeout_ms);
+#else
+ pending_ms = timeout_ms;
+ initial_tv = curlx_tvnow();
+ do {
+#if defined(HAVE_POLL_FINE)
+ r = poll(NULL, 0, pending_ms);
+#else
+ pending_tv.tv_sec = pending_ms / 1000;
+ pending_tv.tv_usec = (pending_ms % 1000) * 1000;
+ r = select(0, NULL, NULL, NULL, &pending_tv);
+#endif /* HAVE_POLL_FINE */
+ if(r != -1)
+ break;
+ error = SOCKERRNO;
+ if(error && error_not_EINTR)
+ break;
+ pending_ms = timeout_ms - elapsed_ms;
+ if(pending_ms <= 0) {
+ r = 0; /* Simulate a "call timed out" case */
+ break;
+ }
+ } while(r == -1);
+#endif /* USE_WINSOCK */
+ if(r)
+ r = -1;
+ return r;
+}
+
+/*
+ * Wait for read or write events on a set of file descriptors. It uses poll()
+ * when a fine poll() is available, in order to avoid limits with FD_SETSIZE,
+ * otherwise select() is used. An error is returned if select() is being used
+ * and a file descriptor is too large for FD_SETSIZE.
+ *
+ * A negative timeout value makes this function wait indefinitely,
+ * unles no valid file descriptor is given, when this happens the
+ * negative timeout is ignored and the function times out immediately.
+ *
+ * Return values:
+ * -1 = system call error or fd >= FD_SETSIZE
+ * 0 = timeout
+ * [bitmask] = action as described below
+ *
+ * CURL_CSELECT_IN - first socket is readable
+ * CURL_CSELECT_IN2 - second socket is readable
+ * CURL_CSELECT_OUT - write socket is writable
+ * CURL_CSELECT_ERR - an error condition occurred
+ */
+int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
+ curl_socket_t readfd1,
+ curl_socket_t writefd, /* socket to write to */
+ long timeout_ms) /* milliseconds to wait */
+{
+#ifdef HAVE_POLL_FINE
+ struct pollfd pfd[3];
+ int num;
+#else
+ struct timeval pending_tv;
+ struct timeval *ptimeout;
+ fd_set fds_read;
+ fd_set fds_write;
+ fd_set fds_err;
+ curl_socket_t maxfd;
+#endif
+ struct timeval initial_tv = {0, 0};
+ int pending_ms = 0;
+ int error;
+ int r;
+ int ret;
+
+ if((readfd0 == CURL_SOCKET_BAD) && (readfd1 == CURL_SOCKET_BAD) &&
+ (writefd == CURL_SOCKET_BAD)) {
+ /* no sockets, just wait */
+ r = Curl_wait_ms((int)timeout_ms);
+ return r;
+ }
+
+ /* Avoid initial timestamp, avoid curlx_tvnow() call, when elapsed
+ time in this function does not need to be measured. This happens
+ when function is called with a zero timeout or a negative timeout
+ value indicating a blocking call should be performed. */
+
+ if(timeout_ms > 0) {
+ pending_ms = (int)timeout_ms;
+ initial_tv = curlx_tvnow();
+ }
+
+#ifdef HAVE_POLL_FINE
+
+ num = 0;
+ if(readfd0 != CURL_SOCKET_BAD) {
+ pfd[num].fd = readfd0;
+ pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
+ pfd[num].revents = 0;
+ num++;
+ }
+ if(readfd1 != CURL_SOCKET_BAD) {
+ pfd[num].fd = readfd1;
+ pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
+ pfd[num].revents = 0;
+ num++;
+ }
+ if(writefd != CURL_SOCKET_BAD) {
+ pfd[num].fd = writefd;
+ pfd[num].events = POLLWRNORM|POLLOUT;
+ pfd[num].revents = 0;
+ num++;
+ }
+
+ do {
+ if(timeout_ms < 0)
+ pending_ms = -1;
+ else if(!timeout_ms)
+ pending_ms = 0;
+ r = poll(pfd, num, pending_ms);
+ if(r != -1)
+ break;
+ error = SOCKERRNO;
+ if(error && error_not_EINTR)
+ break;
+ if(timeout_ms > 0) {
+ pending_ms = (int)(timeout_ms - elapsed_ms);
+ if(pending_ms <= 0) {
+ r = 0; /* Simulate a "call timed out" case */
+ break;
+ }
+ }
+ } while(r == -1);
+
+ if(r < 0)
+ return -1;
+ if(r == 0)
+ return 0;
+
+ ret = 0;
+ num = 0;
+ if(readfd0 != CURL_SOCKET_BAD) {
+ if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
+ ret |= CURL_CSELECT_IN;
+ if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
+ ret |= CURL_CSELECT_ERR;
+ num++;
+ }
+ if(readfd1 != CURL_SOCKET_BAD) {
+ if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
+ ret |= CURL_CSELECT_IN2;
+ if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
+ ret |= CURL_CSELECT_ERR;
+ num++;
+ }
+ if(writefd != CURL_SOCKET_BAD) {
+ if(pfd[num].revents & (POLLWRNORM|POLLOUT))
+ ret |= CURL_CSELECT_OUT;
+ if(pfd[num].revents & (POLLERR|POLLHUP|POLLNVAL))
+ ret |= CURL_CSELECT_ERR;
+ }
+
+ return ret;
+
+#else /* HAVE_POLL_FINE */
+
+ FD_ZERO(&fds_err);
+ maxfd = (curl_socket_t)-1;
+
+ FD_ZERO(&fds_read);
+ if(readfd0 != CURL_SOCKET_BAD) {
+ VERIFY_SOCK(readfd0);
+ FD_SET(readfd0, &fds_read);
+ FD_SET(readfd0, &fds_err);
+ maxfd = readfd0;
+ }
+ if(readfd1 != CURL_SOCKET_BAD) {
+ VERIFY_SOCK(readfd1);
+ FD_SET(readfd1, &fds_read);
+ FD_SET(readfd1, &fds_err);
+ if(readfd1 > maxfd)
+ maxfd = readfd1;
+ }
+
+ FD_ZERO(&fds_write);
+ if(writefd != CURL_SOCKET_BAD) {
+ VERIFY_SOCK(writefd);
+ FD_SET(writefd, &fds_write);
+ FD_SET(writefd, &fds_err);
+ if(writefd > maxfd)
+ maxfd = writefd;
+ }
+
+ ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
+
+ do {
+ if(timeout_ms > 0) {
+ pending_tv.tv_sec = pending_ms / 1000;
+ pending_tv.tv_usec = (pending_ms % 1000) * 1000;
+ }
+ else if(!timeout_ms) {
+ pending_tv.tv_sec = 0;
+ pending_tv.tv_usec = 0;
+ }
+
+ /* WinSock select() must not be called with an fd_set that contains zero
+ fd flags, or it will return WSAEINVAL. But, it also can't be called
+ with no fd_sets at all! From the documentation:
+
+ Any two of the parameters, readfds, writefds, or exceptfds, can be
+ given as null. At least one must be non-null, and any non-null
+ descriptor set must contain at least one handle to a socket.
+
+ We know that we have at least one bit set in at least two fd_sets in
+ this case, but we may have no bits set in either fds_read or fd_write,
+ so check for that and handle it. Luckily, with WinSock, we can _also_
+ ask how many bits are set on an fd_set.
+
+ It is unclear why WinSock doesn't just handle this for us instead of
+ calling this an error.
+
+ Note also that WinSock ignores the first argument, so we don't worry
+ about the fact that maxfd is computed incorrectly with WinSock (since
+ curl_socket_t is unsigned in such cases and thus -1 is the largest
+ value).
+ */
+ r = select((int)maxfd + 1,
+#ifndef USE_WINSOCK
+ &fds_read,
+ &fds_write,
+#else
+ fds_read.fd_count ? &fds_read : NULL,
+ fds_write.fd_count ? &fds_write : NULL,
+#endif
+ &fds_err, ptimeout);
+ if(r != -1)
+ break;
+ error = SOCKERRNO;
+ if(error && error_not_EINTR)
+ break;
+ if(timeout_ms > 0) {
+ pending_ms = timeout_ms - elapsed_ms;
+ if(pending_ms <= 0) {
+ r = 0; /* Simulate a "call timed out" case */
+ break;
+ }
+ }
+ } while(r == -1);
+
+ if(r < 0)
+ return -1;
+ if(r == 0)
+ return 0;
+
+ ret = 0;
+ if(readfd0 != CURL_SOCKET_BAD) {
+ if(FD_ISSET(readfd0, &fds_read))
+ ret |= CURL_CSELECT_IN;
+ if(FD_ISSET(readfd0, &fds_err))
+ ret |= CURL_CSELECT_ERR;
+ }
+ if(readfd1 != CURL_SOCKET_BAD) {
+ if(FD_ISSET(readfd1, &fds_read))
+ ret |= CURL_CSELECT_IN2;
+ if(FD_ISSET(readfd1, &fds_err))
+ ret |= CURL_CSELECT_ERR;
+ }
+ if(writefd != CURL_SOCKET_BAD) {
+ if(FD_ISSET(writefd, &fds_write))
+ ret |= CURL_CSELECT_OUT;
+ if(FD_ISSET(writefd, &fds_err))
+ ret |= CURL_CSELECT_ERR;
+ }
+
+ return ret;
+
+#endif /* HAVE_POLL_FINE */
+
+}
+
+/*
+ * This is a wrapper around poll(). If poll() does not exist, then
+ * select() is used instead. An error is returned if select() is
+ * being used and a file descriptor is too large for FD_SETSIZE.
+ * A negative timeout value makes this function wait indefinitely,
+ * unles no valid file descriptor is given, when this happens the
+ * negative timeout is ignored and the function times out immediately.
+ *
+ * Return values:
+ * -1 = system call error or fd >= FD_SETSIZE
+ * 0 = timeout
+ * N = number of structures with non zero revent fields
+ */
+int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
+{
+#ifndef HAVE_POLL_FINE
+ struct timeval pending_tv;
+ struct timeval *ptimeout;
+ fd_set fds_read;
+ fd_set fds_write;
+ fd_set fds_err;
+ curl_socket_t maxfd;
+#endif
+ struct timeval initial_tv = {0, 0};
+ bool fds_none = TRUE;
+ unsigned int i;
+ int pending_ms = 0;
+ int error;
+ int r;
+
+ if(ufds) {
+ for(i = 0; i < nfds; i++) {
+ if(ufds[i].fd != CURL_SOCKET_BAD) {
+ fds_none = FALSE;
+ break;
+ }
+ }
+ }
+ if(fds_none) {
+ r = Curl_wait_ms(timeout_ms);
+ return r;
+ }
+
+ /* Avoid initial timestamp, avoid curlx_tvnow() call, when elapsed
+ time in this function does not need to be measured. This happens
+ when function is called with a zero timeout or a negative timeout
+ value indicating a blocking call should be performed. */
+
+ if(timeout_ms > 0) {
+ pending_ms = timeout_ms;
+ initial_tv = curlx_tvnow();
+ }
+
+#ifdef HAVE_POLL_FINE
+
+ do {
+ if(timeout_ms < 0)
+ pending_ms = -1;
+ else if(!timeout_ms)
+ pending_ms = 0;
+ r = poll(ufds, nfds, pending_ms);
+ if(r != -1)
+ break;
+ error = SOCKERRNO;
+ if(error && error_not_EINTR)
+ break;
+ if(timeout_ms > 0) {
+ pending_ms = timeout_ms - elapsed_ms;
+ if(pending_ms <= 0) {
+ r = 0; /* Simulate a "call timed out" case */
+ break;
+ }
+ }
+ } while(r == -1);
+
+ if(r < 0)
+ return -1;
+ if(r == 0)
+ return 0;
+
+ for(i = 0; i < nfds; i++) {
+ if(ufds[i].fd == CURL_SOCKET_BAD)
+ continue;
+ if(ufds[i].revents & POLLHUP)
+ ufds[i].revents |= POLLIN;
+ if(ufds[i].revents & POLLERR)
+ ufds[i].revents |= (POLLIN|POLLOUT);
+ }
+
+#else /* HAVE_POLL_FINE */
+
+ FD_ZERO(&fds_read);
+ FD_ZERO(&fds_write);
+ FD_ZERO(&fds_err);
+ maxfd = (curl_socket_t)-1;
+
+ for(i = 0; i < nfds; i++) {
+ ufds[i].revents = 0;
+ if(ufds[i].fd == CURL_SOCKET_BAD)
+ continue;
+ VERIFY_SOCK(ufds[i].fd);
+ if(ufds[i].events & (POLLIN|POLLOUT|POLLPRI|
+ POLLRDNORM|POLLWRNORM|POLLRDBAND)) {
+ if(ufds[i].fd > maxfd)
+ maxfd = ufds[i].fd;
+ if(ufds[i].events & (POLLRDNORM|POLLIN))
+ FD_SET(ufds[i].fd, &fds_read);
+ if(ufds[i].events & (POLLWRNORM|POLLOUT))
+ FD_SET(ufds[i].fd, &fds_write);
+ if(ufds[i].events & (POLLRDBAND|POLLPRI))
+ FD_SET(ufds[i].fd, &fds_err);
+ }
+ }
+
+#ifdef USE_WINSOCK
+ /* WinSock select() can't handle zero events. See the comment about this in
+ Curl_check_socket(). */
+ if(fds_read.fd_count == 0 && fds_write.fd_count == 0
+ && fds_err.fd_count == 0) {
+ r = Curl_wait_ms(timeout_ms);
+ return r;
+ }
+#endif
+
+ ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
+
+ do {
+ if(timeout_ms > 0) {
+ pending_tv.tv_sec = pending_ms / 1000;
+ pending_tv.tv_usec = (pending_ms % 1000) * 1000;
+ }
+ else if(!timeout_ms) {
+ pending_tv.tv_sec = 0;
+ pending_tv.tv_usec = 0;
+ }
+ r = select((int)maxfd + 1,
+#ifndef USE_WINSOCK
+ &fds_read, &fds_write, &fds_err,
+#else
+ /* WinSock select() can't handle fd_sets with zero bits set, so
+ don't give it such arguments. See the comment about this in
+ Curl_check_socket().
+ */
+ fds_read.fd_count ? &fds_read : NULL,
+ fds_write.fd_count ? &fds_write : NULL,
+ fds_err.fd_count ? &fds_err : NULL,
+#endif
+ ptimeout);
+ if(r != -1)
+ break;
+ error = SOCKERRNO;
+ if(error && error_not_EINTR)
+ break;
+ if(timeout_ms > 0) {
+ pending_ms = timeout_ms - elapsed_ms;
+ if(pending_ms <= 0) {
+ r = 0; /* Simulate a "call timed out" case */
+ break;
+ }
+ }
+ } while(r == -1);
+
+ if(r < 0)
+ return -1;
+ if(r == 0)
+ return 0;
+
+ r = 0;
+ for(i = 0; i < nfds; i++) {
+ ufds[i].revents = 0;
+ if(ufds[i].fd == CURL_SOCKET_BAD)
+ continue;
+ if(FD_ISSET(ufds[i].fd, &fds_read))
+ ufds[i].revents |= POLLIN;
+ if(FD_ISSET(ufds[i].fd, &fds_write))
+ ufds[i].revents |= POLLOUT;
+ if(FD_ISSET(ufds[i].fd, &fds_err))
+ ufds[i].revents |= POLLPRI;
+ if(ufds[i].revents != 0)
+ r++;
+ }
+
+#endif /* HAVE_POLL_FINE */
+
+ return r;
+}
+
+#ifdef TPF
+/*
+ * This is a replacement for select() on the TPF platform.
+ * It is used whenever libcurl calls select().
+ * The call below to tpf_process_signals() is required because
+ * TPF's select calls are not signal interruptible.
+ *
+ * Return values are the same as select's.
+ */
+int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
+ fd_set* excepts, struct timeval* tv)
+{
+ int rc;
+
+ rc = tpf_select_bsd(maxfds, reads, writes, excepts, tv);
+ tpf_process_signals();
+ return rc;
+}
+#endif /* TPF */
diff --git a/Utilities/cmcurl/lib/select.h b/Utilities/cmcurl/lib/select.h
new file mode 100644
index 000000000..c00afe166
--- /dev/null
+++ b/Utilities/cmcurl/lib/select.h
@@ -0,0 +1,114 @@
+#ifndef HEADER_CURL_SELECT_H
+#define HEADER_CURL_SELECT_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_SYS_POLL_H
+#include <sys/poll.h>
+#elif defined(HAVE_POLL_H)
+#include <poll.h>
+#endif
+
+/*
+ * Definition of pollfd struct and constants for platforms lacking them.
+ */
+
+#if !defined(HAVE_STRUCT_POLLFD) && \
+ !defined(HAVE_SYS_POLL_H) && \
+ !defined(HAVE_POLL_H)
+
+#define POLLIN 0x01
+#define POLLPRI 0x02
+#define POLLOUT 0x04
+#define POLLERR 0x08
+#define POLLHUP 0x10
+#define POLLNVAL 0x20
+
+struct pollfd
+{
+ curl_socket_t fd;
+ short events;
+ short revents;
+};
+
+#endif
+
+#ifndef POLLRDNORM
+#define POLLRDNORM POLLIN
+#endif
+
+#ifndef POLLWRNORM
+#define POLLWRNORM POLLOUT
+#endif
+
+#ifndef POLLRDBAND
+#define POLLRDBAND POLLPRI
+#endif
+
+/* there are three CSELECT defines that are defined in the public header that
+ are exposed to users, but this *IN2 bit is only ever used internally and
+ therefore defined here */
+#define CURL_CSELECT_IN2 (CURL_CSELECT_ERR << 1)
+
+int Curl_socket_check(curl_socket_t readfd, curl_socket_t readfd2,
+ curl_socket_t writefd,
+ long timeout_ms);
+
+/* provide the former API internally */
+#define Curl_socket_ready(x,y,z) \
+ Curl_socket_check(x, CURL_SOCKET_BAD, y, z)
+
+int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms);
+
+/* On non-DOS and non-Winsock platforms, when Curl_ack_eintr is set,
+ * EINTR condition is honored and function might exit early without
+ * awaiting full timeout. Otherwise EINTR will be ignored and full
+ * timeout will elapse. */
+extern int Curl_ack_eintr;
+
+int Curl_wait_ms(int timeout_ms);
+
+#ifdef TPF
+int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
+ fd_set* excepts, struct timeval* tv);
+#endif
+
+/* Winsock and TPF sockets are not in range [0..FD_SETSIZE-1], which
+ unfortunately makes it impossible for us to easily check if they're valid
+*/
+#if defined(USE_WINSOCK) || defined(TPF)
+#define VALID_SOCK(x) 1
+#define VERIFY_SOCK(x) Curl_nop_stmt
+#else
+#define VALID_SOCK(s) (((s) >= 0) && ((s) < FD_SETSIZE))
+#define VERIFY_SOCK(x) do { \
+ if(!VALID_SOCK(x)) { \
+ SET_SOCKERRNO(EINVAL); \
+ return -1; \
+ } \
+} WHILE_FALSE
+#endif
+
+#endif /* HEADER_CURL_SELECT_H */
+
diff --git a/Utilities/cmcurl/lib/sendf.c b/Utilities/cmcurl/lib/sendf.c
new file mode 100644
index 000000000..5f39d1f2d
--- /dev/null
+++ b/Utilities/cmcurl/lib/sendf.c
@@ -0,0 +1,710 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#include "urldata.h"
+#include "sendf.h"
+#include "connect.h"
+#include "vtls/vtls.h"
+#include "ssh.h"
+#include "multiif.h"
+#include "non-ascii.h"
+#include "curl_printf.h"
+#include "strerror.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#ifdef CURL_DO_LINEEND_CONV
+/*
+ * convert_lineends() changes CRLF (\r\n) end-of-line markers to a single LF
+ * (\n), with special processing for CRLF sequences that are split between two
+ * blocks of data. Remaining, bare CRs are changed to LFs. The possibly new
+ * size of the data is returned.
+ */
+static size_t convert_lineends(struct SessionHandle *data,
+ char *startPtr, size_t size)
+{
+ char *inPtr, *outPtr;
+
+ /* sanity check */
+ if((startPtr == NULL) || (size < 1)) {
+ return size;
+ }
+
+ if(data->state.prev_block_had_trailing_cr) {
+ /* The previous block of incoming data
+ had a trailing CR, which was turned into a LF. */
+ if(*startPtr == '\n') {
+ /* This block of incoming data starts with the
+ previous block's LF so get rid of it */
+ memmove(startPtr, startPtr+1, size-1);
+ size--;
+ /* and it wasn't a bare CR but a CRLF conversion instead */
+ data->state.crlf_conversions++;
+ }
+ data->state.prev_block_had_trailing_cr = FALSE; /* reset the flag */
+ }
+
+ /* find 1st CR, if any */
+ inPtr = outPtr = memchr(startPtr, '\r', size);
+ if(inPtr) {
+ /* at least one CR, now look for CRLF */
+ while(inPtr < (startPtr+size-1)) {
+ /* note that it's size-1, so we'll never look past the last byte */
+ if(memcmp(inPtr, "\r\n", 2) == 0) {
+ /* CRLF found, bump past the CR and copy the NL */
+ inPtr++;
+ *outPtr = *inPtr;
+ /* keep track of how many CRLFs we converted */
+ data->state.crlf_conversions++;
+ }
+ else {
+ if(*inPtr == '\r') {
+ /* lone CR, move LF instead */
+ *outPtr = '\n';
+ }
+ else {
+ /* not a CRLF nor a CR, just copy whatever it is */
+ *outPtr = *inPtr;
+ }
+ }
+ outPtr++;
+ inPtr++;
+ } /* end of while loop */
+
+ if(inPtr < startPtr+size) {
+ /* handle last byte */
+ if(*inPtr == '\r') {
+ /* deal with a CR at the end of the buffer */
+ *outPtr = '\n'; /* copy a NL instead */
+ /* note that a CRLF might be split across two blocks */
+ data->state.prev_block_had_trailing_cr = TRUE;
+ }
+ else {
+ /* copy last byte */
+ *outPtr = *inPtr;
+ }
+ outPtr++;
+ }
+ if(outPtr < startPtr+size)
+ /* tidy up by null terminating the now shorter data */
+ *outPtr = '\0';
+
+ return (outPtr - startPtr);
+ }
+ return size;
+}
+#endif /* CURL_DO_LINEEND_CONV */
+
+/* Curl_infof() is for info message along the way */
+
+void Curl_infof(struct SessionHandle *data, const char *fmt, ...)
+{
+ if(data && data->set.verbose) {
+ va_list ap;
+ size_t len;
+ char print_buffer[2048 + 1];
+ va_start(ap, fmt);
+ vsnprintf(print_buffer, sizeof(print_buffer), fmt, ap);
+ va_end(ap);
+ len = strlen(print_buffer);
+ Curl_debug(data, CURLINFO_TEXT, print_buffer, len, NULL);
+ }
+}
+
+/* Curl_failf() is for messages stating why we failed.
+ * The message SHALL NOT include any LF or CR.
+ */
+
+void Curl_failf(struct SessionHandle *data, const char *fmt, ...)
+{
+ va_list ap;
+ size_t len;
+ va_start(ap, fmt);
+
+ vsnprintf(data->state.buffer, BUFSIZE, fmt, ap);
+
+ if(data->set.errorbuffer && !data->state.errorbuf) {
+ snprintf(data->set.errorbuffer, CURL_ERROR_SIZE, "%s", data->state.buffer);
+ data->state.errorbuf = TRUE; /* wrote error string */
+ }
+ if(data->set.verbose) {
+ len = strlen(data->state.buffer);
+ if(len < BUFSIZE - 1) {
+ data->state.buffer[len] = '\n';
+ data->state.buffer[++len] = '\0';
+ }
+ Curl_debug(data, CURLINFO_TEXT, data->state.buffer, len, NULL);
+ }
+
+ va_end(ap);
+}
+
+/* Curl_sendf() sends formated data to the server */
+CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn,
+ const char *fmt, ...)
+{
+ struct SessionHandle *data = conn->data;
+ ssize_t bytes_written;
+ size_t write_len;
+ CURLcode result = CURLE_OK;
+ char *s;
+ char *sptr;
+ va_list ap;
+ va_start(ap, fmt);
+ s = vaprintf(fmt, ap); /* returns an allocated string */
+ va_end(ap);
+ if(!s)
+ return CURLE_OUT_OF_MEMORY; /* failure */
+
+ bytes_written=0;
+ write_len = strlen(s);
+ sptr = s;
+
+ for(;;) {
+ /* Write the buffer to the socket */
+ result = Curl_write(conn, sockfd, sptr, write_len, &bytes_written);
+
+ if(result)
+ break;
+
+ if(data->set.verbose)
+ Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written, conn);
+
+ if((size_t)bytes_written != write_len) {
+ /* if not all was written at once, we must advance the pointer, decrease
+ the size left and try again! */
+ write_len -= bytes_written;
+ sptr += bytes_written;
+ }
+ else
+ break;
+ }
+
+ free(s); /* free the output string */
+
+ return result;
+}
+
+/*
+ * Curl_write() is an internal write function that sends data to the
+ * server. Works with plain sockets, SCP, SSL or kerberos.
+ *
+ * If the write would block (CURLE_AGAIN), we return CURLE_OK and
+ * (*written == 0). Otherwise we return regular CURLcode value.
+ */
+CURLcode Curl_write(struct connectdata *conn,
+ curl_socket_t sockfd,
+ const void *mem,
+ size_t len,
+ ssize_t *written)
+{
+ ssize_t bytes_written;
+ CURLcode result = CURLE_OK;
+ int num = (sockfd == conn->sock[SECONDARYSOCKET]);
+
+ bytes_written = conn->send[num](conn, num, mem, len, &result);
+
+ *written = bytes_written;
+ if(bytes_written >= 0)
+ /* we completely ignore the curlcode value when subzero is not returned */
+ return CURLE_OK;
+
+ /* handle CURLE_AGAIN or a send failure */
+ switch(result) {
+ case CURLE_AGAIN:
+ *written = 0;
+ return CURLE_OK;
+
+ case CURLE_OK:
+ /* general send failure */
+ return CURLE_SEND_ERROR;
+
+ default:
+ /* we got a specific curlcode, forward it */
+ return result;
+ }
+}
+
+ssize_t Curl_send_plain(struct connectdata *conn, int num,
+ const void *mem, size_t len, CURLcode *code)
+{
+ curl_socket_t sockfd = conn->sock[num];
+ ssize_t bytes_written = swrite(sockfd, mem, len);
+
+ *code = CURLE_OK;
+ if(-1 == bytes_written) {
+ int err = SOCKERRNO;
+
+ if(
+#ifdef WSAEWOULDBLOCK
+ /* This is how Windows does it */
+ (WSAEWOULDBLOCK == err)
+#else
+ /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
+ due to its inability to send off data without blocking. We therefor
+ treat both error codes the same here */
+ (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
+#endif
+ ) {
+ /* this is just a case of EWOULDBLOCK */
+ bytes_written=0;
+ *code = CURLE_AGAIN;
+ }
+ else {
+ failf(conn->data, "Send failure: %s",
+ Curl_strerror(conn, err));
+ conn->data->state.os_errno = err;
+ *code = CURLE_SEND_ERROR;
+ }
+ }
+ return bytes_written;
+}
+
+/*
+ * Curl_write_plain() is an internal write function that sends data to the
+ * server using plain sockets only. Otherwise meant to have the exact same
+ * proto as Curl_write()
+ */
+CURLcode Curl_write_plain(struct connectdata *conn,
+ curl_socket_t sockfd,
+ const void *mem,
+ size_t len,
+ ssize_t *written)
+{
+ ssize_t bytes_written;
+ CURLcode result;
+ int num = (sockfd == conn->sock[SECONDARYSOCKET]);
+
+ bytes_written = Curl_send_plain(conn, num, mem, len, &result);
+
+ *written = bytes_written;
+
+ return result;
+}
+
+ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf,
+ size_t len, CURLcode *code)
+{
+ curl_socket_t sockfd = conn->sock[num];
+ ssize_t nread = sread(sockfd, buf, len);
+
+ *code = CURLE_OK;
+ if(-1 == nread) {
+ int err = SOCKERRNO;
+
+ if(
+#ifdef WSAEWOULDBLOCK
+ /* This is how Windows does it */
+ (WSAEWOULDBLOCK == err)
+#else
+ /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
+ due to its inability to send off data without blocking. We therefor
+ treat both error codes the same here */
+ (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
+#endif
+ ) {
+ /* this is just a case of EWOULDBLOCK */
+ *code = CURLE_AGAIN;
+ }
+ else {
+ failf(conn->data, "Recv failure: %s",
+ Curl_strerror(conn, err));
+ conn->data->state.os_errno = err;
+ *code = CURLE_RECV_ERROR;
+ }
+ }
+ return nread;
+}
+
+static CURLcode pausewrite(struct SessionHandle *data,
+ int type, /* what type of data */
+ const char *ptr,
+ size_t len)
+{
+ /* signalled to pause sending on this connection, but since we have data
+ we want to send we need to dup it to save a copy for when the sending
+ is again enabled */
+ struct SingleRequest *k = &data->req;
+ char *dupl = malloc(len);
+ if(!dupl)
+ return CURLE_OUT_OF_MEMORY;
+
+ memcpy(dupl, ptr, len);
+
+ /* store this information in the state struct for later use */
+ data->state.tempwrite = dupl;
+ data->state.tempwritesize = len;
+ data->state.tempwritetype = type;
+
+ /* mark the connection as RECV paused */
+ k->keepon |= KEEP_RECV_PAUSE;
+
+ DEBUGF(infof(data, "Pausing with %zu bytes in buffer for type %02x\n",
+ len, type));
+
+ return CURLE_OK;
+}
+
+
+/* Curl_client_chop_write() writes chunks of data not larger than
+ * CURL_MAX_WRITE_SIZE via client write callback(s) and
+ * takes care of pause requests from the callbacks.
+ */
+CURLcode Curl_client_chop_write(struct connectdata *conn,
+ int type,
+ char * ptr,
+ size_t len)
+{
+ struct SessionHandle *data = conn->data;
+ curl_write_callback writeheader = NULL;
+ curl_write_callback writebody = NULL;
+
+ if(!len)
+ return CURLE_OK;
+
+ /* If reading is actually paused, we're forced to append this chunk of data
+ to the already held data, but only if it is the same type as otherwise it
+ can't work and it'll return error instead. */
+ if(data->req.keepon & KEEP_RECV_PAUSE) {
+ size_t newlen;
+ char *newptr;
+ if(type != data->state.tempwritetype)
+ /* major internal confusion */
+ return CURLE_RECV_ERROR;
+
+ DEBUGASSERT(data->state.tempwrite);
+
+ /* figure out the new size of the data to save */
+ newlen = len + data->state.tempwritesize;
+ /* allocate the new memory area */
+ newptr = realloc(data->state.tempwrite, newlen);
+ if(!newptr)
+ return CURLE_OUT_OF_MEMORY;
+ /* copy the new data to the end of the new area */
+ memcpy(newptr + data->state.tempwritesize, ptr, len);
+ /* update the pointer and the size */
+ data->state.tempwrite = newptr;
+ data->state.tempwritesize = newlen;
+ return CURLE_OK;
+ }
+
+ /* Determine the callback(s) to use. */
+ if(type & CLIENTWRITE_BODY)
+ writebody = data->set.fwrite_func;
+ if((type & CLIENTWRITE_HEADER) &&
+ (data->set.fwrite_header || data->set.writeheader)) {
+ /*
+ * Write headers to the same callback or to the especially setup
+ * header callback function (added after version 7.7.1).
+ */
+ writeheader =
+ data->set.fwrite_header? data->set.fwrite_header: data->set.fwrite_func;
+ }
+
+ /* Chop data, write chunks. */
+ while(len) {
+ size_t chunklen = len <= CURL_MAX_WRITE_SIZE? len: CURL_MAX_WRITE_SIZE;
+
+ if(writebody) {
+ size_t wrote = writebody(ptr, 1, chunklen, data->set.out);
+
+ if(CURL_WRITEFUNC_PAUSE == wrote) {
+ if(conn->handler->flags & PROTOPT_NONETWORK) {
+ /* Protocols that work without network cannot be paused. This is
+ actually only FILE:// just now, and it can't pause since the
+ transfer isn't done using the "normal" procedure. */
+ failf(data, "Write callback asked for PAUSE when not supported!");
+ return CURLE_WRITE_ERROR;
+ }
+ else
+ return pausewrite(data, type, ptr, len);
+ }
+ else if(wrote != chunklen) {
+ failf(data, "Failed writing body (%zu != %zu)", wrote, chunklen);
+ return CURLE_WRITE_ERROR;
+ }
+ }
+
+ if(writeheader) {
+ size_t wrote = writeheader(ptr, 1, chunklen, data->set.writeheader);
+
+ if(CURL_WRITEFUNC_PAUSE == wrote)
+ /* here we pass in the HEADER bit only since if this was body as well
+ then it was passed already and clearly that didn't trigger the
+ pause, so this is saved for later with the HEADER bit only */
+ return pausewrite(data, CLIENTWRITE_HEADER, ptr, len);
+
+ if(wrote != chunklen) {
+ failf (data, "Failed writing header");
+ return CURLE_WRITE_ERROR;
+ }
+ }
+
+ ptr += chunklen;
+ len -= chunklen;
+ }
+
+ return CURLE_OK;
+}
+
+
+/* Curl_client_write() sends data to the write callback(s)
+
+ The bit pattern defines to what "streams" to write to. Body and/or header.
+ The defines are in sendf.h of course.
+
+ If CURL_DO_LINEEND_CONV is enabled, data is converted IN PLACE to the
+ local character encoding. This is a problem and should be changed in
+ the future to leave the original data alone.
+ */
+CURLcode Curl_client_write(struct connectdata *conn,
+ int type,
+ char *ptr,
+ size_t len)
+{
+ struct SessionHandle *data = conn->data;
+
+ if(0 == len)
+ len = strlen(ptr);
+
+ /* FTP data may need conversion. */
+ if((type & CLIENTWRITE_BODY) &&
+ (conn->handler->protocol & PROTO_FAMILY_FTP) &&
+ conn->proto.ftpc.transfertype == 'A') {
+ /* convert from the network encoding */
+ CURLcode result = Curl_convert_from_network(data, ptr, len);
+ /* Curl_convert_from_network calls failf if unsuccessful */
+ if(result)
+ return result;
+
+#ifdef CURL_DO_LINEEND_CONV
+ /* convert end-of-line markers */
+ len = convert_lineends(data, ptr, len);
+#endif /* CURL_DO_LINEEND_CONV */
+ }
+
+ return Curl_client_chop_write(conn, type, ptr, len);
+}
+
+CURLcode Curl_read_plain(curl_socket_t sockfd,
+ char *buf,
+ size_t bytesfromsocket,
+ ssize_t *n)
+{
+ ssize_t nread = sread(sockfd, buf, bytesfromsocket);
+
+ if(-1 == nread) {
+ int err = SOCKERRNO;
+#ifdef USE_WINSOCK
+ if(WSAEWOULDBLOCK == err)
+#else
+ if((EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err))
+#endif
+ return CURLE_AGAIN;
+ else
+ return CURLE_RECV_ERROR;
+ }
+
+ /* we only return number of bytes read when we return OK */
+ *n = nread;
+ return CURLE_OK;
+}
+
+/*
+ * Internal read-from-socket function. This is meant to deal with plain
+ * sockets, SSL sockets and kerberos sockets.
+ *
+ * Returns a regular CURLcode value.
+ */
+CURLcode Curl_read(struct connectdata *conn, /* connection data */
+ curl_socket_t sockfd, /* read from this socket */
+ char *buf, /* store read data here */
+ size_t sizerequested, /* max amount to read */
+ ssize_t *n) /* amount bytes read */
+{
+ CURLcode result = CURLE_RECV_ERROR;
+ ssize_t nread = 0;
+ size_t bytesfromsocket = 0;
+ char *buffertofill = NULL;
+ bool pipelining = Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1);
+
+ /* Set 'num' to 0 or 1, depending on which socket that has been sent here.
+ If it is the second socket, we set num to 1. Otherwise to 0. This lets
+ us use the correct ssl handle. */
+ int num = (sockfd == conn->sock[SECONDARYSOCKET]);
+
+ *n=0; /* reset amount to zero */
+
+ /* If session can pipeline, check connection buffer */
+ if(pipelining) {
+ size_t bytestocopy = CURLMIN(conn->buf_len - conn->read_pos,
+ sizerequested);
+
+ /* Copy from our master buffer first if we have some unread data there*/
+ if(bytestocopy > 0) {
+ memcpy(buf, conn->master_buffer + conn->read_pos, bytestocopy);
+ conn->read_pos += bytestocopy;
+ conn->bits.stream_was_rewound = FALSE;
+
+ *n = (ssize_t)bytestocopy;
+ return CURLE_OK;
+ }
+ /* If we come here, it means that there is no data to read from the buffer,
+ * so we read from the socket */
+ bytesfromsocket = CURLMIN(sizerequested, BUFSIZE * sizeof (char));
+ buffertofill = conn->master_buffer;
+ }
+ else {
+ bytesfromsocket = CURLMIN((long)sizerequested,
+ conn->data->set.buffer_size ?
+ conn->data->set.buffer_size : BUFSIZE);
+ buffertofill = buf;
+ }
+
+ nread = conn->recv[num](conn, num, buffertofill, bytesfromsocket, &result);
+ if(nread < 0)
+ return result;
+
+ if(pipelining) {
+ memcpy(buf, conn->master_buffer, nread);
+ conn->buf_len = nread;
+ conn->read_pos = nread;
+ }
+
+ *n += nread;
+
+ return CURLE_OK;
+}
+
+/* return 0 on success */
+static int showit(struct SessionHandle *data, curl_infotype type,
+ char *ptr, size_t size)
+{
+ static const char s_infotype[CURLINFO_END][3] = {
+ "* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
+
+#ifdef CURL_DOES_CONVERSIONS
+ char buf[BUFSIZE+1];
+ size_t conv_size = 0;
+
+ switch(type) {
+ case CURLINFO_HEADER_OUT:
+ /* assume output headers are ASCII */
+ /* copy the data into my buffer so the original is unchanged */
+ if(size > BUFSIZE) {
+ size = BUFSIZE; /* truncate if necessary */
+ buf[BUFSIZE] = '\0';
+ }
+ conv_size = size;
+ memcpy(buf, ptr, size);
+ /* Special processing is needed for this block if it
+ * contains both headers and data (separated by CRLFCRLF).
+ * We want to convert just the headers, leaving the data as-is.
+ */
+ if(size > 4) {
+ size_t i;
+ for(i = 0; i < size-4; i++) {
+ if(memcmp(&buf[i], "\x0d\x0a\x0d\x0a", 4) == 0) {
+ /* convert everything through this CRLFCRLF but no further */
+ conv_size = i + 4;
+ break;
+ }
+ }
+ }
+
+ Curl_convert_from_network(data, buf, conv_size);
+ /* Curl_convert_from_network calls failf if unsuccessful */
+ /* we might as well continue even if it fails... */
+ ptr = buf; /* switch pointer to use my buffer instead */
+ break;
+ default:
+ /* leave everything else as-is */
+ break;
+ }
+#endif /* CURL_DOES_CONVERSIONS */
+
+ if(data->set.fdebug)
+ return (*data->set.fdebug)(data, type, ptr, size,
+ data->set.debugdata);
+
+ switch(type) {
+ case CURLINFO_TEXT:
+ case CURLINFO_HEADER_OUT:
+ case CURLINFO_HEADER_IN:
+ fwrite(s_infotype[type], 2, 1, data->set.err);
+ fwrite(ptr, size, 1, data->set.err);
+#ifdef CURL_DOES_CONVERSIONS
+ if(size != conv_size) {
+ /* we had untranslated data so we need an explicit newline */
+ fwrite("\n", 1, 1, data->set.err);
+ }
+#endif
+ break;
+ default: /* nada */
+ break;
+ }
+ return 0;
+}
+
+int Curl_debug(struct SessionHandle *data, curl_infotype type,
+ char *ptr, size_t size,
+ struct connectdata *conn)
+{
+ int rc;
+ if(data->set.printhost && conn && conn->host.dispname) {
+ char buffer[160];
+ const char *t=NULL;
+ const char *w="Data";
+ switch (type) {
+ case CURLINFO_HEADER_IN:
+ w = "Header";
+ /* FALLTHROUGH */
+ case CURLINFO_DATA_IN:
+ t = "from";
+ break;
+ case CURLINFO_HEADER_OUT:
+ w = "Header";
+ /* FALLTHROUGH */
+ case CURLINFO_DATA_OUT:
+ t = "to";
+ break;
+ default:
+ break;
+ }
+
+ if(t) {
+ snprintf(buffer, sizeof(buffer), "[%s %s %s]", w, t,
+ conn->host.dispname);
+ rc = showit(data, CURLINFO_TEXT, buffer, strlen(buffer));
+ if(rc)
+ return rc;
+ }
+ }
+ rc = showit(data, type, ptr, size);
+ return rc;
+}
diff --git a/Utilities/cmcurl/lib/sendf.h b/Utilities/cmcurl/lib/sendf.h
new file mode 100644
index 000000000..86f06cf9b
--- /dev/null
+++ b/Utilities/cmcurl/lib/sendf.h
@@ -0,0 +1,92 @@
+#ifndef HEADER_CURL_SENDF_H
+#define HEADER_CURL_SENDF_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *,
+ const char *fmt, ...);
+void Curl_infof(struct SessionHandle *, const char *fmt, ...);
+void Curl_failf(struct SessionHandle *, const char *fmt, ...);
+
+#if defined(CURL_DISABLE_VERBOSE_STRINGS)
+
+#if defined(HAVE_VARIADIC_MACROS_C99)
+#define infof(...) Curl_nop_stmt
+#elif defined(HAVE_VARIADIC_MACROS_GCC)
+#define infof(x...) Curl_nop_stmt
+#else
+#define infof (void)
+#endif
+
+#else /* CURL_DISABLE_VERBOSE_STRINGS */
+
+#define infof Curl_infof
+
+#endif /* CURL_DISABLE_VERBOSE_STRINGS */
+
+#define failf Curl_failf
+
+#define CLIENTWRITE_BODY (1<<0)
+#define CLIENTWRITE_HEADER (1<<1)
+#define CLIENTWRITE_BOTH (CLIENTWRITE_BODY|CLIENTWRITE_HEADER)
+
+CURLcode Curl_client_chop_write(struct connectdata *conn, int type, char *ptr,
+ size_t len) WARN_UNUSED_RESULT;
+CURLcode Curl_client_write(struct connectdata *conn, int type, char *ptr,
+ size_t len) WARN_UNUSED_RESULT;
+
+/* internal read-function, does plain socket only */
+CURLcode Curl_read_plain(curl_socket_t sockfd,
+ char *buf,
+ size_t bytesfromsocket,
+ ssize_t *n);
+
+ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf,
+ size_t len, CURLcode *code);
+ssize_t Curl_send_plain(struct connectdata *conn, int num,
+ const void *mem, size_t len, CURLcode *code);
+
+/* internal read-function, does plain socket, SSL and krb4 */
+CURLcode Curl_read(struct connectdata *conn, curl_socket_t sockfd,
+ char *buf, size_t buffersize,
+ ssize_t *n);
+/* internal write-function, does plain socket, SSL, SCP, SFTP and krb4 */
+CURLcode Curl_write(struct connectdata *conn,
+ curl_socket_t sockfd,
+ const void *mem, size_t len,
+ ssize_t *written);
+
+/* internal write-function, does plain sockets ONLY */
+CURLcode Curl_write_plain(struct connectdata *conn,
+ curl_socket_t sockfd,
+ const void *mem, size_t len,
+ ssize_t *written);
+
+/* the function used to output verbose information */
+int Curl_debug(struct SessionHandle *handle, curl_infotype type,
+ char *data, size_t size,
+ struct connectdata *conn);
+
+
+#endif /* HEADER_CURL_SENDF_H */
diff --git a/Utilities/cmcurl/lib/setup-os400.h b/Utilities/cmcurl/lib/setup-os400.h
new file mode 100644
index 000000000..fae8567df
--- /dev/null
+++ b/Utilities/cmcurl/lib/setup-os400.h
@@ -0,0 +1,223 @@
+#ifndef HEADER_CURL_SETUP_OS400_H
+#define HEADER_CURL_SETUP_OS400_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+
+/* OS/400 netdb.h does not define NI_MAXHOST. */
+#define NI_MAXHOST 1025
+
+/* OS/400 netdb.h does not define NI_MAXSERV. */
+#define NI_MAXSERV 32
+
+/* No OS/400 header file defines u_int32_t. */
+typedef unsigned long u_int32_t;
+
+
+/* System API wrapper prototypes & definitions to support ASCII parameters. */
+
+#include <sys/socket.h>
+#include <netdb.h>
+#include <gskssl.h>
+#include <qsoasync.h>
+#include <gssapi.h>
+
+extern int Curl_getaddrinfo_a(const char * nodename,
+ const char * servname,
+ const struct addrinfo * hints,
+ struct addrinfo * * res);
+#define getaddrinfo Curl_getaddrinfo_a
+
+
+extern int Curl_getnameinfo_a(const struct sockaddr * sa,
+ curl_socklen_t salen,
+ char * nodename, curl_socklen_t nodenamelen,
+ char * servname, curl_socklen_t servnamelen,
+ int flags);
+#define getnameinfo Curl_getnameinfo_a
+
+
+/* GSKit wrappers. */
+
+extern int Curl_gsk_environment_open(gsk_handle * my_env_handle);
+#define gsk_environment_open Curl_gsk_environment_open
+
+extern int Curl_gsk_secure_soc_open(gsk_handle my_env_handle,
+ gsk_handle * my_session_handle);
+#define gsk_secure_soc_open Curl_gsk_secure_soc_open
+
+extern int Curl_gsk_environment_close(gsk_handle * my_env_handle);
+#define gsk_environment_close Curl_gsk_environment_close
+
+extern int Curl_gsk_secure_soc_close(gsk_handle * my_session_handle);
+#define gsk_secure_soc_close Curl_gsk_secure_soc_close
+
+extern int Curl_gsk_environment_init(gsk_handle my_env_handle);
+#define gsk_environment_init Curl_gsk_environment_init
+
+extern int Curl_gsk_secure_soc_init(gsk_handle my_session_handle);
+#define gsk_secure_soc_init Curl_gsk_secure_soc_init
+
+extern int Curl_gsk_attribute_set_buffer_a(gsk_handle my_gsk_handle,
+ GSK_BUF_ID bufID,
+ const char * buffer,
+ int bufSize);
+#define gsk_attribute_set_buffer Curl_gsk_attribute_set_buffer_a
+
+extern int Curl_gsk_attribute_set_enum(gsk_handle my_gsk_handle,
+ GSK_ENUM_ID enumID,
+ GSK_ENUM_VALUE enumValue);
+#define gsk_attribute_set_enum Curl_gsk_attribute_set_enum
+
+extern int Curl_gsk_attribute_set_numeric_value(gsk_handle my_gsk_handle,
+ GSK_NUM_ID numID,
+ int numValue);
+#define gsk_attribute_set_numeric_value Curl_gsk_attribute_set_numeric_value
+
+extern int Curl_gsk_attribute_set_callback(gsk_handle my_gsk_handle,
+ GSK_CALLBACK_ID callBackID,
+ void * callBackAreaPtr);
+#define gsk_attribute_set_callback Curl_gsk_attribute_set_callback
+
+extern int Curl_gsk_attribute_get_buffer_a(gsk_handle my_gsk_handle,
+ GSK_BUF_ID bufID,
+ const char * * buffer,
+ int * bufSize);
+#define gsk_attribute_get_buffer Curl_gsk_attribute_get_buffer_a
+
+extern int Curl_gsk_attribute_get_enum(gsk_handle my_gsk_handle,
+ GSK_ENUM_ID enumID,
+ GSK_ENUM_VALUE * enumValue);
+#define gsk_attribute_get_enum Curl_gsk_attribute_get_enum
+
+extern int Curl_gsk_attribute_get_numeric_value(gsk_handle my_gsk_handle,
+ GSK_NUM_ID numID,
+ int * numValue);
+#define gsk_attribute_get_numeric_value Curl_gsk_attribute_get_numeric_value
+
+extern int Curl_gsk_attribute_get_cert_info(gsk_handle my_gsk_handle,
+ GSK_CERT_ID certID,
+ const gsk_cert_data_elem * * certDataElem,
+ int * certDataElementCount);
+#define gsk_attribute_get_cert_info Curl_gsk_attribute_get_cert_info
+
+extern int Curl_gsk_secure_soc_misc(gsk_handle my_session_handle,
+ GSK_MISC_ID miscID);
+#define gsk_secure_soc_misc Curl_gsk_secure_soc_misc
+
+extern int Curl_gsk_secure_soc_read(gsk_handle my_session_handle,
+ char * readBuffer,
+ int readBufSize, int * amtRead);
+#define gsk_secure_soc_read Curl_gsk_secure_soc_read
+
+extern int Curl_gsk_secure_soc_write(gsk_handle my_session_handle,
+ char * writeBuffer,
+ int writeBufSize, int * amtWritten);
+#define gsk_secure_soc_write Curl_gsk_secure_soc_write
+
+extern const char * Curl_gsk_strerror_a(int gsk_return_value);
+#define gsk_strerror Curl_gsk_strerror_a
+
+extern int Curl_gsk_secure_soc_startInit(gsk_handle my_session_handle,
+ int IOCompletionPort,
+ Qso_OverlappedIO_t * communicationsArea);
+#define gsk_secure_soc_startInit Curl_gsk_secure_soc_startInit
+
+
+/* GSSAPI wrappers. */
+
+extern OM_uint32 Curl_gss_import_name_a(OM_uint32 * minor_status,
+ gss_buffer_t in_name,
+ gss_OID in_name_type,
+ gss_name_t * out_name);
+#define gss_import_name Curl_gss_import_name_a
+
+
+extern OM_uint32 Curl_gss_display_status_a(OM_uint32 * minor_status,
+ OM_uint32 status_value,
+ int status_type, gss_OID mech_type,
+ gss_msg_ctx_t * message_context,
+ gss_buffer_t status_string);
+#define gss_display_status Curl_gss_display_status_a
+
+
+extern OM_uint32 Curl_gss_init_sec_context_a(OM_uint32 * minor_status,
+ gss_cred_id_t cred_handle,
+ gss_ctx_id_t * context_handle,
+ gss_name_t target_name,
+ gss_OID mech_type,
+ gss_flags_t req_flags,
+ OM_uint32 time_req,
+ gss_channel_bindings_t
+ input_chan_bindings,
+ gss_buffer_t input_token,
+ gss_OID * actual_mech_type,
+ gss_buffer_t output_token,
+ gss_flags_t * ret_flags,
+ OM_uint32 * time_rec);
+#define gss_init_sec_context Curl_gss_init_sec_context_a
+
+
+extern OM_uint32 Curl_gss_delete_sec_context_a(OM_uint32 * minor_status,
+ gss_ctx_id_t * context_handle,
+ gss_buffer_t output_token);
+#define gss_delete_sec_context Curl_gss_delete_sec_context_a
+
+
+/* LDAP wrappers. */
+
+#define BerValue struct berval
+
+#define ldap_url_parse ldap_url_parse_utf8
+#define ldap_init Curl_ldap_init_a
+#define ldap_simple_bind_s Curl_ldap_simple_bind_s_a
+#define ldap_search_s Curl_ldap_search_s_a
+#define ldap_get_values_len Curl_ldap_get_values_len_a
+#define ldap_err2string Curl_ldap_err2string_a
+#define ldap_get_dn Curl_ldap_get_dn_a
+#define ldap_first_attribute Curl_ldap_first_attribute_a
+#define ldap_next_attribute Curl_ldap_next_attribute_a
+
+/* Some socket functions must be wrapped to process textual addresses
+ like AF_UNIX. */
+
+extern int Curl_os400_connect(int sd, struct sockaddr * destaddr, int addrlen);
+extern int Curl_os400_bind(int sd, struct sockaddr * localaddr, int addrlen);
+extern int Curl_os400_sendto(int sd, char * buffer, int buflen, int flags,
+ struct sockaddr * dstaddr, int addrlen);
+extern int Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
+ struct sockaddr * fromaddr, int * addrlen);
+
+#define connect Curl_os400_connect
+#define bind Curl_os400_bind
+#define sendto Curl_os400_sendto
+#define recvfrom Curl_os400_recvfrom
+
+#ifdef HAVE_LIBZ
+#define zlibVersion Curl_os400_zlibVersion
+#define inflateInit_ Curl_os400_inflateInit_
+#define inflateInit2_ Curl_os400_inflateInit2_
+#define inflate Curl_os400_inflate
+#define inflateEnd Curl_os400_inflateEnd
+#endif
+
+#endif /* HEADER_CURL_SETUP_OS400_H */
diff --git a/Utilities/cmcurl/lib/setup-vms.h b/Utilities/cmcurl/lib/setup-vms.h
new file mode 100644
index 000000000..520a35daa
--- /dev/null
+++ b/Utilities/cmcurl/lib/setup-vms.h
@@ -0,0 +1,442 @@
+#ifndef HEADER_CURL_SETUP_VMS_H
+#define HEADER_CURL_SETUP_VMS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* */
+/* JEM, 12/30/12, VMS now generates config.h, so only define wrappers for */
+/* getenv(), getpwuid() and provide is_vms_shell() */
+/* Also need upper case symbols for system services, and */
+/* OpenSSL, and some Kerberos image */
+
+#ifdef __DECC
+#pragma message save
+#pragma message disable dollarid
+#endif
+
+/* Hide the stuff we are overriding */
+#define getenv decc_getenv
+#ifdef __DECC
+# if __INITIAL_POINTER_SIZE != 64
+# define getpwuid decc_getpwuid
+# endif
+#endif
+#include <stdlib.h>
+ char * decc$getenv(const char * __name);
+#include <pwd.h>
+
+#include <string.h>
+#include <unixlib.h>
+
+#undef getenv
+#undef getpwuid
+#define getenv vms_getenv
+#define getpwuid vms_getpwuid
+
+/* VAX needs these in upper case when compiling exact case */
+#define sys$assign SYS$ASSIGN
+#define sys$dassgn SYS$DASSGN
+#define sys$qiow SYS$QIOW
+
+#ifdef __DECC
+# if __INITIAL_POINTER_SIZE
+# pragma __pointer_size __save
+# endif
+#endif
+
+#if __USE_LONG_GID_T
+# define decc_getpwuid DECC$__LONG_GID_GETPWUID
+#else
+# if __INITIAL_POINTER_SIZE
+# define decc_getpwuid decc$__32_getpwuid
+# else
+# define decc_getpwuid decc$getpwuid
+# endif
+#endif
+
+ struct passwd * decc_getpwuid(uid_t uid);
+
+#ifdef __DECC
+# if __INITIAL_POINTER_SIZE == 32
+/* Translate the path, but only if the path is a VMS file specification */
+/* The translation is usually only needed for older versions of VMS */
+static char * vms_translate_path(const char * path) {
+char * unix_path;
+char * test_str;
+
+ /* See if the result is in VMS format, if not, we are done */
+ /* Assume that this is a PATH, not just some data */
+ test_str = strpbrk(path, ":[<^");
+ if(test_str == NULL) {
+ return (char *)path;
+ }
+
+ unix_path = decc$translate_vms(path);
+
+ if((int)unix_path <= 0) {
+ /* We can not translate it, so return the original string */
+ return (char *)path;
+ }
+}
+# else
+ /* VMS translate path is actually not needed on the current 64 bit */
+ /* VMS platforms, so instead of figuring out the pointer settings */
+ /* Change it to a noop */
+# define vms_translate_path(__path) __path
+# endif
+#endif
+
+#ifdef __DECC
+# if __INITIAL_POINTER_SIZE
+# pragma __pointer_size __restore
+# endif
+#endif
+
+static char * vms_getenv(const char * envvar) {
+
+char * result;
+char * vms_path;
+
+ /* first use the DECC getenv() function */
+ result = decc$getenv(envvar);
+ if(result == NULL) {
+ return result;
+ }
+
+ vms_path = result;
+ result = vms_translate_path(vms_path);
+
+ /* note that if you backport this to use VAX C RTL, that the VAX C RTL */
+ /* may do a malloc(2048) for each call to getenv(), so you will need */
+ /* to add a free(vms_path) */
+ /* Do not do a free() for DEC C RTL builds, which should be used for */
+ /* VMS 5.5-2 and later, even if using GCC */
+
+ return result;
+}
+
+
+static struct passwd vms_passwd_cache;
+
+static struct passwd * vms_getpwuid(uid_t uid) {
+
+struct passwd * my_passwd;
+
+/* Hack needed to support 64 bit builds, decc_getpwnam is 32 bit only */
+#ifdef __DECC
+# if __INITIAL_POINTER_SIZE
+__char_ptr32 unix_path;
+# else
+char * unix_path;
+# endif
+#else
+char * unix_path;
+#endif
+
+ my_passwd = decc_getpwuid(uid);
+ if(my_passwd == NULL) {
+ return my_passwd;
+ }
+
+ unix_path = vms_translate_path(my_passwd->pw_dir);
+
+ if((long)unix_path <= 0) {
+ /* We can not translate it, so return the original string */
+ return my_passwd;
+ }
+
+ /* If no changes needed just return it */
+ if(unix_path == my_passwd->pw_dir) {
+ return my_passwd;
+ }
+
+ /* Need to copy the structure returned */
+ /* Since curl is only using pw_dir, no need to fix up *
+ /* the pw_shell when running under Bash */
+ vms_passwd_cache.pw_name = my_passwd->pw_name;
+ vms_passwd_cache.pw_uid = my_passwd->pw_uid;
+ vms_passwd_cache.pw_gid = my_passwd->pw_uid;
+ vms_passwd_cache.pw_dir = unix_path;
+ vms_passwd_cache.pw_shell = my_passwd->pw_shell;
+
+ return &vms_passwd_cache;
+}
+
+#ifdef __DECC
+#pragma message restore
+#endif
+
+/* Bug - VMS OpenSSL and Kerberos universal symbols are in uppercase only */
+/* VMS libraries should have universal symbols in exact and uppercase */
+
+#define ASN1_INTEGER_get ASN1_INTEGER_GET
+#define ASN1_STRING_data ASN1_STRING_DATA
+#define ASN1_STRING_length ASN1_STRING_LENGTH
+#define ASN1_STRING_print ASN1_STRING_PRINT
+#define ASN1_STRING_to_UTF8 ASN1_STRING_TO_UTF8
+#define ASN1_STRING_type ASN1_STRING_TYPE
+#define BIO_ctrl BIO_CTRL
+#define BIO_free BIO_FREE
+#define BIO_new BIO_NEW
+#define BIO_s_mem BIO_S_MEM
+#define BN_bn2bin BN_BN2BIN
+#define BN_num_bits BN_NUM_BITS
+#define CRYPTO_cleanup_all_ex_data CRYPTO_CLEANUP_ALL_EX_DATA
+#define CRYPTO_free CRYPTO_FREE
+#define CRYPTO_malloc CRYPTO_MALLOC
+#define CONF_modules_load_file CONF_MODULES_LOAD_FILE
+#ifdef __VAX
+# ifdef VMS_OLD_SSL
+ /* Ancient OpenSSL on VAX/VMS missing this constant */
+# define CONF_MFLAGS_IGNORE_MISSING_FILE 0x10
+# undef CONF_modules_load_file
+ static int CONF_modules_load_file(const char *filename,
+ const char *appname,
+ unsigned long flags) {
+ return 1;
+ }
+# endif
+#endif
+#define DES_ecb_encrypt DES_ECB_ENCRYPT
+#define DES_set_key DES_SET_KEY
+#define DES_set_odd_parity DES_SET_ODD_PARITY
+#define ENGINE_ctrl ENGINE_CTRL
+#define ENGINE_ctrl_cmd ENGINE_CTRL_CMD
+#define ENGINE_finish ENGINE_FINISH
+#define ENGINE_free ENGINE_FREE
+#define ENGINE_get_first ENGINE_GET_FIRST
+#define ENGINE_get_id ENGINE_GET_ID
+#define ENGINE_get_next ENGINE_GET_NEXT
+#define ENGINE_init ENGINE_INIT
+#define ENGINE_load_builtin_engines ENGINE_LOAD_BUILTIN_ENGINES
+#define ENGINE_load_private_key ENGINE_LOAD_PRIVATE_KEY
+#define ENGINE_set_default ENGINE_SET_DEFAULT
+#define ERR_clear_error ERR_CLEAR_ERROR
+#define ERR_error_string ERR_ERROR_STRING
+#define ERR_error_string_n ERR_ERROR_STRING_N
+#define ERR_free_strings ERR_FREE_STRINGS
+#define ERR_get_error ERR_GET_ERROR
+#define ERR_peek_error ERR_PEEK_ERROR
+#define ERR_remove_state ERR_REMOVE_STATE
+#define EVP_PKEY_copy_parameters EVP_PKEY_COPY_PARAMETERS
+#define EVP_PKEY_free EVP_PKEY_FREE
+#define EVP_cleanup EVP_CLEANUP
+#define GENERAL_NAMES_free GENERAL_NAMES_FREE
+#define i2d_X509_PUBKEY I2D_X509_PUBKEY
+#define MD4_Final MD4_FINAL
+#define MD4_Init MD4_INIT
+#define MD4_Update MD4_UPDATE
+#define MD5_Final MD5_FINAL
+#define MD5_Init MD5_INIT
+#define MD5_Update MD5_UPDATE
+#define OPENSSL_add_all_algo_noconf OPENSSL_ADD_ALL_ALGO_NOCONF
+#ifndef __VAX
+#define OPENSSL_load_builtin_modules OPENSSL_LOAD_BUILTIN_MODULES
+#endif
+#define PEM_read_X509 PEM_READ_X509
+#define PEM_write_bio_X509 PEM_WRITE_BIO_X509
+#define PKCS12_PBE_add PKCS12_PBE_ADD
+#define PKCS12_free PKCS12_FREE
+#define PKCS12_parse PKCS12_PARSE
+#define RAND_add RAND_ADD
+#define RAND_bytes RAND_BYTES
+#define RAND_egd RAND_EGD
+#define RAND_file_name RAND_FILE_NAME
+#define RAND_load_file RAND_LOAD_FILE
+#define RAND_status RAND_STATUS
+#define SSL_CIPHER_get_name SSL_CIPHER_GET_NAME
+#define SSL_CTX_add_client_CA SSL_CTX_ADD_CLIENT_CA
+#define SSL_CTX_callback_ctrl SSL_CTX_CALLBACK_CTRL
+#define SSL_CTX_check_private_key SSL_CTX_CHECK_PRIVATE_KEY
+#define SSL_CTX_ctrl SSL_CTX_CTRL
+#define SSL_CTX_free SSL_CTX_FREE
+#define SSL_CTX_get_cert_store SSL_CTX_GET_CERT_STORE
+#define SSL_CTX_load_verify_locations SSL_CTX_LOAD_VERIFY_LOCATIONS
+#define SSL_CTX_new SSL_CTX_NEW
+#define SSL_CTX_set_cipher_list SSL_CTX_SET_CIPHER_LIST
+#define SSL_CTX_set_def_passwd_cb_ud SSL_CTX_SET_DEF_PASSWD_CB_UD
+#define SSL_CTX_set_default_passwd_cb SSL_CTX_SET_DEFAULT_PASSWD_CB
+#define SSL_CTX_set_msg_callback SSL_CTX_SET_MSG_CALLBACK
+#define SSL_CTX_set_verify SSL_CTX_SET_VERIFY
+#define SSL_CTX_use_PrivateKey SSL_CTX_USE_PRIVATEKEY
+#define SSL_CTX_use_PrivateKey_file SSL_CTX_USE_PRIVATEKEY_FILE
+#define SSL_CTX_use_cert_chain_file SSL_CTX_USE_CERT_CHAIN_FILE
+#define SSL_CTX_use_certificate SSL_CTX_USE_CERTIFICATE
+#define SSL_CTX_use_certificate_file SSL_CTX_USE_CERTIFICATE_FILE
+#define SSL_SESSION_free SSL_SESSION_FREE
+#define SSL_connect SSL_CONNECT
+#define SSL_free SSL_FREE
+#define SSL_get1_session SSL_GET1_SESSION
+#define SSL_get_certificate SSL_GET_CERTIFICATE
+#define SSL_get_current_cipher SSL_GET_CURRENT_CIPHER
+#define SSL_get_error SSL_GET_ERROR
+#define SSL_get_peer_cert_chain SSL_GET_PEER_CERT_CHAIN
+#define SSL_get_peer_certificate SSL_GET_PEER_CERTIFICATE
+#define SSL_get_privatekey SSL_GET_PRIVATEKEY
+#define SSL_get_session SSL_GET_SESSION
+#define SSL_get_shutdown SSL_GET_SHUTDOWN
+#define SSL_get_verify_result SSL_GET_VERIFY_RESULT
+#define SSL_library_init SSL_LIBRARY_INIT
+#define SSL_load_error_strings SSL_LOAD_ERROR_STRINGS
+#define SSL_new SSL_NEW
+#define SSL_peek SSL_PEEK
+#define SSL_pending SSL_PENDING
+#define SSL_read SSL_READ
+#define SSL_set_connect_state SSL_SET_CONNECT_STATE
+#define SSL_set_fd SSL_SET_FD
+#define SSL_set_session SSL_SET_SESSION
+#define SSL_shutdown SSL_SHUTDOWN
+#define SSL_version SSL_VERSION
+#define SSL_write SSL_WRITE
+#define SSLeay SSLEAY
+#define SSLv23_client_method SSLV23_CLIENT_METHOD
+#define SSLv3_client_method SSLV3_CLIENT_METHOD
+#define TLSv1_client_method TLSV1_CLIENT_METHOD
+#define UI_create_method UI_CREATE_METHOD
+#define UI_destroy_method UI_DESTROY_METHOD
+#define UI_get0_user_data UI_GET0_USER_DATA
+#define UI_get_input_flags UI_GET_INPUT_FLAGS
+#define UI_get_string_type UI_GET_STRING_TYPE
+#define UI_create_method UI_CREATE_METHOD
+#define UI_destroy_method UI_DESTROY_METHOD
+#define UI_method_get_closer UI_METHOD_GET_CLOSER
+#define UI_method_get_opener UI_METHOD_GET_OPENER
+#define UI_method_get_reader UI_METHOD_GET_READER
+#define UI_method_get_writer UI_METHOD_GET_WRITER
+#define UI_method_set_closer UI_METHOD_SET_CLOSER
+#define UI_method_set_opener UI_METHOD_SET_OPENER
+#define UI_method_set_reader UI_METHOD_SET_READER
+#define UI_method_set_writer UI_METHOD_SET_WRITER
+#define UI_OpenSSL UI_OPENSSL
+#define UI_set_result UI_SET_RESULT
+#define X509V3_EXT_print X509V3_EXT_PRINT
+#define X509_EXTENSION_get_critical X509_EXTENSION_GET_CRITICAL
+#define X509_EXTENSION_get_data X509_EXTENSION_GET_DATA
+#define X509_EXTENSION_get_object X509_EXTENSION_GET_OBJECT
+#define X509_LOOKUP_file X509_LOOKUP_FILE
+#define X509_NAME_ENTRY_get_data X509_NAME_ENTRY_GET_DATA
+#define X509_NAME_get_entry X509_NAME_GET_ENTRY
+#define X509_NAME_get_index_by_NID X509_NAME_GET_INDEX_BY_NID
+#define X509_NAME_print_ex X509_NAME_PRINT_EX
+#define X509_STORE_CTX_get_current_cert X509_STORE_CTX_GET_CURRENT_CERT
+#define X509_STORE_add_lookup X509_STORE_ADD_LOOKUP
+#define X509_STORE_set_flags X509_STORE_SET_FLAGS
+#define X509_check_issued X509_CHECK_ISSUED
+#define X509_free X509_FREE
+#define X509_get_ext_d2i X509_GET_EXT_D2I
+#define X509_get_issuer_name X509_GET_ISSUER_NAME
+#define X509_get_pubkey X509_GET_PUBKEY
+#define X509_get_serialNumber X509_GET_SERIALNUMBER
+#define X509_get_subject_name X509_GET_SUBJECT_NAME
+#define X509_load_crl_file X509_LOAD_CRL_FILE
+#define X509_verify_cert_error_string X509_VERIFY_CERT_ERROR_STRING
+#define d2i_PKCS12_fp D2I_PKCS12_FP
+#define i2t_ASN1_OBJECT I2T_ASN1_OBJECT
+#define sk_num SK_NUM
+#define sk_pop SK_POP
+#define sk_pop_free SK_POP_FREE
+#define sk_value SK_VALUE
+#ifdef __VAX
+#define OPENSSL_NO_SHA256
+#endif
+#define SHA256_Final SHA256_FINAL
+#define SHA256_Init SHA256_INIT
+#define SHA256_Update SHA256_UPDATE
+
+#define USE_UPPERCASE_GSSAPI 1
+#define gss_seal GSS_SEAL
+#define gss_unseal GSS_UNSEAL
+
+#define USE_UPPERCASE_KRBAPI 1
+
+/* AI_NUMERICHOST needed for IP V6 support in Curl */
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#ifndef AI_NUMERICHOST
+#ifdef ENABLE_IPV6
+#undef ENABLE_IPV6
+#endif
+#endif
+#endif
+
+/* VAX symbols are always in uppercase */
+#ifdef __VAX
+#define inflate INFLATE
+#define inflateEnd INFLATEEND
+#define inflateInit2_ INFLATEINIT2_
+#define inflateInit_ INFLATEINIT_
+#define zlibVersion ZLIBVERSION
+#endif
+
+/* Older VAX OpenSSL port defines these as Macros */
+/* Need to include the headers first and then redefine */
+/* that way a newer port will also work if some one has one */
+#ifdef __VAX
+
+# if (OPENSSL_VERSION_NUMBER < 0x00907001L)
+# define des_set_odd_parity DES_SET_ODD_PARITY
+# define des_set_key DES_SET_KEY
+# define des_ecb_encrypt DES_ECB_ENCRYPT
+
+# endif
+# include <openssl/evp.h>
+# ifndef OpenSSL_add_all_algorithms
+# define OpenSSL_add_all_algorithms OPENSSL_ADD_ALL_ALGORITHMS
+ void OPENSSL_ADD_ALL_ALGORITHMS(void);
+# endif
+
+ /* Curl defines these to lower case and VAX needs them in upper case */
+ /* So we need static routines */
+# if (OPENSSL_VERSION_NUMBER < 0x00907001L)
+
+# undef des_set_odd_parity
+# undef DES_set_odd_parity
+# undef des_set_key
+# undef DES_set_key
+# undef des_ecb_encrypt
+# undef DES_ecb_encrypt
+
+ static void des_set_odd_parity(des_cblock *key) {
+ DES_SET_ODD_PARITY(key);
+ }
+
+ static int des_set_key(const_des_cblock *key,
+ des_key_schedule schedule) {
+ return DES_SET_KEY(key, schedule);
+ }
+
+ static void des_ecb_encrypt(const_des_cblock *input,
+ des_cblock *output,
+ des_key_schedule ks, int enc) {
+ DES_ECB_ENCRYPT(input, output, ks, enc);
+ }
+#endif
+/* Need this to stop a macro redefinition error */
+#if OPENSSL_VERSION_NUMBER < 0x00907000L
+# ifdef X509_STORE_set_flags
+# undef X509_STORE_set_flags
+# define X509_STORE_set_flags(x,y) Curl_nop_stmt
+# endif
+#endif
+#endif
+
+#endif /* HEADER_CURL_SETUP_VMS_H */
diff --git a/Utilities/cmcurl/lib/share.c b/Utilities/cmcurl/lib/share.c
new file mode 100644
index 000000000..17202486c
--- /dev/null
+++ b/Utilities/cmcurl/lib/share.c
@@ -0,0 +1,247 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "share.h"
+#include "vtls/vtls.h"
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+CURLSH *
+curl_share_init(void)
+{
+ struct Curl_share *share = calloc(1, sizeof(struct Curl_share));
+ if(share) {
+ share->specifier |= (1<<CURL_LOCK_DATA_SHARE);
+
+ if(Curl_mk_dnscache(&share->hostcache)) {
+ free(share);
+ return NULL;
+ }
+ }
+
+ return share;
+}
+
+#undef curl_share_setopt
+CURLSHcode
+curl_share_setopt(CURLSH *sh, CURLSHoption option, ...)
+{
+ struct Curl_share *share = (struct Curl_share *)sh;
+ va_list param;
+ int type;
+ curl_lock_function lockfunc;
+ curl_unlock_function unlockfunc;
+ void *ptr;
+ CURLSHcode res = CURLSHE_OK;
+
+ if(share->dirty)
+ /* don't allow setting options while one or more handles are already
+ using this share */
+ return CURLSHE_IN_USE;
+
+ va_start(param, option);
+
+ switch(option) {
+ case CURLSHOPT_SHARE:
+ /* this is a type this share will share */
+ type = va_arg(param, int);
+ share->specifier |= (1<<type);
+ switch( type ) {
+ case CURL_LOCK_DATA_DNS:
+ break;
+
+ case CURL_LOCK_DATA_COOKIE:
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
+ if(!share->cookies) {
+ share->cookies = Curl_cookie_init(NULL, NULL, NULL, TRUE );
+ if(!share->cookies)
+ res = CURLSHE_NOMEM;
+ }
+#else /* CURL_DISABLE_HTTP */
+ res = CURLSHE_NOT_BUILT_IN;
+#endif
+ break;
+
+ case CURL_LOCK_DATA_SSL_SESSION:
+#ifdef USE_SSL
+ if(!share->sslsession) {
+ share->max_ssl_sessions = 8;
+ share->sslsession = calloc(share->max_ssl_sessions,
+ sizeof(struct curl_ssl_session));
+ share->sessionage = 0;
+ if(!share->sslsession)
+ res = CURLSHE_NOMEM;
+ }
+#else
+ res = CURLSHE_NOT_BUILT_IN;
+#endif
+ break;
+
+ case CURL_LOCK_DATA_CONNECT: /* not supported (yet) */
+ break;
+
+ default:
+ res = CURLSHE_BAD_OPTION;
+ }
+ break;
+
+ case CURLSHOPT_UNSHARE:
+ /* this is a type this share will no longer share */
+ type = va_arg(param, int);
+ share->specifier &= ~(1<<type);
+ switch( type ) {
+ case CURL_LOCK_DATA_DNS:
+ break;
+
+ case CURL_LOCK_DATA_COOKIE:
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
+ if(share->cookies) {
+ Curl_cookie_cleanup(share->cookies);
+ share->cookies = NULL;
+ }
+#else /* CURL_DISABLE_HTTP */
+ res = CURLSHE_NOT_BUILT_IN;
+#endif
+ break;
+
+ case CURL_LOCK_DATA_SSL_SESSION:
+#ifdef USE_SSL
+ Curl_safefree(share->sslsession);
+#else
+ res = CURLSHE_NOT_BUILT_IN;
+#endif
+ break;
+
+ case CURL_LOCK_DATA_CONNECT:
+ break;
+
+ default:
+ res = CURLSHE_BAD_OPTION;
+ break;
+ }
+ break;
+
+ case CURLSHOPT_LOCKFUNC:
+ lockfunc = va_arg(param, curl_lock_function);
+ share->lockfunc = lockfunc;
+ break;
+
+ case CURLSHOPT_UNLOCKFUNC:
+ unlockfunc = va_arg(param, curl_unlock_function);
+ share->unlockfunc = unlockfunc;
+ break;
+
+ case CURLSHOPT_USERDATA:
+ ptr = va_arg(param, void *);
+ share->clientdata = ptr;
+ break;
+
+ default:
+ res = CURLSHE_BAD_OPTION;
+ break;
+ }
+
+ va_end(param);
+
+ return res;
+}
+
+CURLSHcode
+curl_share_cleanup(CURLSH *sh)
+{
+ struct Curl_share *share = (struct Curl_share *)sh;
+
+ if(share == NULL)
+ return CURLSHE_INVALID;
+
+ if(share->lockfunc)
+ share->lockfunc(NULL, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE,
+ share->clientdata);
+
+ if(share->dirty) {
+ if(share->unlockfunc)
+ share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata);
+ return CURLSHE_IN_USE;
+ }
+
+ Curl_hash_destroy(&share->hostcache);
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
+ Curl_cookie_cleanup(share->cookies);
+#endif
+
+#ifdef USE_SSL
+ if(share->sslsession) {
+ size_t i;
+ for(i = 0; i < share->max_ssl_sessions; i++)
+ Curl_ssl_kill_session(&(share->sslsession[i]));
+ free(share->sslsession);
+ }
+#endif
+
+ if(share->unlockfunc)
+ share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata);
+ free(share);
+
+ return CURLSHE_OK;
+}
+
+
+CURLSHcode
+Curl_share_lock(struct SessionHandle *data, curl_lock_data type,
+ curl_lock_access accesstype)
+{
+ struct Curl_share *share = data->share;
+
+ if(share == NULL)
+ return CURLSHE_INVALID;
+
+ if(share->specifier & (1<<type)) {
+ if(share->lockfunc) /* only call this if set! */
+ share->lockfunc(data, type, accesstype, share->clientdata);
+ }
+ /* else if we don't share this, pretend successful lock */
+
+ return CURLSHE_OK;
+}
+
+CURLSHcode
+Curl_share_unlock(struct SessionHandle *data, curl_lock_data type)
+{
+ struct Curl_share *share = data->share;
+
+ if(share == NULL)
+ return CURLSHE_INVALID;
+
+ if(share->specifier & (1<<type)) {
+ if(share->unlockfunc) /* only call this if set! */
+ share->unlockfunc (data, type, share->clientdata);
+ }
+
+ return CURLSHE_OK;
+}
diff --git a/Utilities/cmcurl/lib/share.h b/Utilities/cmcurl/lib/share.h
new file mode 100644
index 000000000..8e6629b7b
--- /dev/null
+++ b/Utilities/cmcurl/lib/share.h
@@ -0,0 +1,61 @@
+#ifndef HEADER_CURL_SHARE_H
+#define HEADER_CURL_SHARE_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include <curl/curl.h>
+#include "cookie.h"
+#include "urldata.h"
+
+/* SalfordC says "A structure member may not be volatile". Hence:
+ */
+#ifdef __SALFORDC__
+#define CURL_VOLATILE
+#else
+#define CURL_VOLATILE volatile
+#endif
+
+/* this struct is libcurl-private, don't export details */
+struct Curl_share {
+ unsigned int specifier;
+ CURL_VOLATILE unsigned int dirty;
+
+ curl_lock_function lockfunc;
+ curl_unlock_function unlockfunc;
+ void *clientdata;
+
+ struct curl_hash hostcache;
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
+ struct CookieInfo *cookies;
+#endif
+
+ struct curl_ssl_session *sslsession;
+ size_t max_ssl_sessions;
+ long sessionage;
+};
+
+CURLSHcode Curl_share_lock (struct SessionHandle *, curl_lock_data,
+ curl_lock_access);
+CURLSHcode Curl_share_unlock (struct SessionHandle *, curl_lock_data);
+
+#endif /* HEADER_CURL_SHARE_H */
diff --git a/Utilities/cmcurl/lib/sigpipe.h b/Utilities/cmcurl/lib/sigpipe.h
new file mode 100644
index 000000000..e8d2acd6e
--- /dev/null
+++ b/Utilities/cmcurl/lib/sigpipe.h
@@ -0,0 +1,78 @@
+#ifndef HEADER_CURL_SIGPIPE_H
+#define HEADER_CURL_SIGPIPE_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#if defined(HAVE_SIGNAL_H) && defined(HAVE_SIGACTION) && defined(USE_OPENSSL)
+#include <signal.h>
+
+struct sigpipe_ignore {
+ struct sigaction old_pipe_act;
+ bool no_signal;
+};
+
+#define SIGPIPE_VARIABLE(x) struct sigpipe_ignore x
+
+/*
+ * sigpipe_ignore() makes sure we ignore SIGPIPE while running libcurl
+ * internals, and then sigpipe_restore() will restore the situation when we
+ * return from libcurl again.
+ */
+static void sigpipe_ignore(struct SessionHandle *data,
+ struct sigpipe_ignore *ig)
+{
+ /* get a local copy of no_signal because the SessionHandle might not be
+ around when we restore */
+ ig->no_signal = data->set.no_signal;
+ if(!data->set.no_signal) {
+ struct sigaction action;
+ /* first, extract the existing situation */
+ memset(&ig->old_pipe_act, 0, sizeof(struct sigaction));
+ sigaction(SIGPIPE, NULL, &ig->old_pipe_act);
+ action = ig->old_pipe_act;
+ /* ignore this signal */
+ action.sa_handler = SIG_IGN;
+ sigaction(SIGPIPE, &action, NULL);
+ }
+}
+
+/*
+ * sigpipe_restore() puts back the outside world's opinion of signal handler
+ * and SIGPIPE handling. It MUST only be called after a corresponding
+ * sigpipe_ignore() was used.
+ */
+static void sigpipe_restore(struct sigpipe_ignore *ig)
+{
+ if(!ig->no_signal)
+ /* restore the outside state */
+ sigaction(SIGPIPE, &ig->old_pipe_act, NULL);
+}
+
+#else
+/* for systems without sigaction */
+#define sigpipe_ignore(x,y) Curl_nop_stmt
+#define sigpipe_restore(x) Curl_nop_stmt
+#define SIGPIPE_VARIABLE(x)
+#endif
+
+#endif /* HEADER_CURL_SIGPIPE_H */
diff --git a/Utilities/cmcurl/lib/slist.c b/Utilities/cmcurl/lib/slist.c
new file mode 100644
index 000000000..9c0b2a58a
--- /dev/null
+++ b/Utilities/cmcurl/lib/slist.c
@@ -0,0 +1,143 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "slist.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* returns last node in linked list */
+static struct curl_slist *slist_get_last(struct curl_slist *list)
+{
+ struct curl_slist *item;
+
+ /* if caller passed us a NULL, return now */
+ if(!list)
+ return NULL;
+
+ /* loop through to find the last item */
+ item = list;
+ while(item->next) {
+ item = item->next;
+ }
+ return item;
+}
+
+/*
+ * Curl_slist_append_nodup() appends a string to the linked list. Rather than
+ * copying the string in dynamic storage, it takes its ownership. The string
+ * should have been malloc()ated. Curl_slist_append_nodup always returns
+ * the address of the first record, so that you can use this function as an
+ * initialization function as well as an append function.
+ * If an error occurs, NULL is returned and the string argument is NOT
+ * released.
+ */
+struct curl_slist *Curl_slist_append_nodup(struct curl_slist *list, char *data)
+{
+ struct curl_slist *last;
+ struct curl_slist *new_item;
+
+ DEBUGASSERT(data);
+
+ new_item = malloc(sizeof(struct curl_slist));
+ if(!new_item)
+ return NULL;
+
+ new_item->next = NULL;
+ new_item->data = data;
+
+ /* if this is the first item, then new_item *is* the list */
+ if(!list)
+ return new_item;
+
+ last = slist_get_last(list);
+ last->next = new_item;
+ return list;
+}
+
+/*
+ * curl_slist_append() appends a string to the linked list. It always returns
+ * the address of the first record, so that you can use this function as an
+ * initialization function as well as an append function. If you find this
+ * bothersome, then simply create a separate _init function and call it
+ * appropriately from within the program.
+ */
+struct curl_slist *curl_slist_append(struct curl_slist *list,
+ const char *data)
+{
+ char *dupdata = strdup(data);
+
+ if(!dupdata)
+ return NULL;
+
+ list = Curl_slist_append_nodup(list, dupdata);
+ if(!list)
+ free(dupdata);
+
+ return list;
+}
+
+/*
+ * Curl_slist_duplicate() duplicates a linked list. It always returns the
+ * address of the first record of the cloned list or NULL in case of an
+ * error (or if the input list was NULL).
+ */
+struct curl_slist *Curl_slist_duplicate(struct curl_slist *inlist)
+{
+ struct curl_slist *outlist = NULL;
+ struct curl_slist *tmp;
+
+ while(inlist) {
+ tmp = curl_slist_append(outlist, inlist->data);
+
+ if(!tmp) {
+ curl_slist_free_all(outlist);
+ return NULL;
+ }
+
+ outlist = tmp;
+ inlist = inlist->next;
+ }
+ return outlist;
+}
+
+/* be nice and clean up resources */
+void curl_slist_free_all(struct curl_slist *list)
+{
+ struct curl_slist *next;
+ struct curl_slist *item;
+
+ if(!list)
+ return;
+
+ item = list;
+ do {
+ next = item->next;
+ Curl_safefree(item->data);
+ free(item);
+ item = next;
+ } while(next);
+}
+
diff --git a/Utilities/cmcurl/lib/slist.h b/Utilities/cmcurl/lib/slist.h
new file mode 100644
index 000000000..ea7dcc48b
--- /dev/null
+++ b/Utilities/cmcurl/lib/slist.h
@@ -0,0 +1,40 @@
+#ifndef HEADER_CURL_SLIST_H
+#define HEADER_CURL_SLIST_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Curl_slist_duplicate() duplicates a linked list. It always returns the
+ * address of the first record of the cloned list or NULL in case of an
+ * error (or if the input list was NULL).
+ */
+struct curl_slist *Curl_slist_duplicate(struct curl_slist *inlist);
+
+/*
+ * Curl_slist_append_nodup() takes ownership of the given string and appends
+ * it to the list.
+ */
+struct curl_slist *Curl_slist_append_nodup(struct curl_slist *list,
+ char *data);
+
+#endif /* HEADER_CURL_SLIST_H */
+
diff --git a/Utilities/cmcurl/lib/smb.c b/Utilities/cmcurl/lib/smb.c
new file mode 100644
index 000000000..d461a712c
--- /dev/null
+++ b/Utilities/cmcurl/lib/smb.c
@@ -0,0 +1,976 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2014, Bill Nagel <wnagel@tycoint.com>, Exacq Technologies
+ * Copyright (C) 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
+ (CURL_SIZEOF_CURL_OFF_T > 4)
+
+#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
+
+#define BUILDING_CURL_SMB_C
+
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#define getpid _getpid
+#endif
+
+#include "smb.h"
+#include "urldata.h"
+#include "sendf.h"
+#include "multiif.h"
+#include "connect.h"
+#include "progress.h"
+#include "transfer.h"
+#include "vtls/vtls.h"
+#include "curl_ntlm_core.h"
+#include "escape.h"
+#include "curl_endian.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* Local API functions */
+static CURLcode smb_setup_connection(struct connectdata *conn);
+static CURLcode smb_connect(struct connectdata *conn, bool *done);
+static CURLcode smb_connection_state(struct connectdata *conn, bool *done);
+static CURLcode smb_request_state(struct connectdata *conn, bool *done);
+static CURLcode smb_done(struct connectdata *conn, CURLcode status,
+ bool premature);
+static CURLcode smb_disconnect(struct connectdata *conn, bool dead);
+static int smb_getsock(struct connectdata *conn, curl_socket_t *socks,
+ int numsocks);
+static CURLcode smb_parse_url_path(struct connectdata *conn);
+
+/*
+ * SMB handler interface
+ */
+const struct Curl_handler Curl_handler_smb = {
+ "SMB", /* scheme */
+ smb_setup_connection, /* setup_connection */
+ ZERO_NULL, /* do_it */
+ smb_done, /* done */
+ ZERO_NULL, /* do_more */
+ smb_connect, /* connect_it */
+ smb_connection_state, /* connecting */
+ smb_request_state, /* doing */
+ smb_getsock, /* proto_getsock */
+ smb_getsock, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ smb_disconnect, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_SMB, /* defport */
+ CURLPROTO_SMB, /* protocol */
+ PROTOPT_NONE /* flags */
+};
+
+#ifdef USE_SSL
+/*
+ * SMBS handler interface
+ */
+const struct Curl_handler Curl_handler_smbs = {
+ "SMBS", /* scheme */
+ smb_setup_connection, /* setup_connection */
+ ZERO_NULL, /* do_it */
+ smb_done, /* done */
+ ZERO_NULL, /* do_more */
+ smb_connect, /* connect_it */
+ smb_connection_state, /* connecting */
+ smb_request_state, /* doing */
+ smb_getsock, /* proto_getsock */
+ smb_getsock, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ smb_disconnect, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_SMBS, /* defport */
+ CURLPROTO_SMBS, /* protocol */
+ PROTOPT_SSL /* flags */
+};
+#endif
+
+#define MAX_PAYLOAD_SIZE 0x8000
+#define MAX_MESSAGE_SIZE (MAX_PAYLOAD_SIZE + 0x1000)
+#define CLIENTNAME "curl"
+#define SERVICENAME "?????"
+
+/* Append a string to an SMB message */
+#define MSGCAT(str) \
+ strcpy(p, (str)); \
+ p += strlen(str);
+
+/* Append a null-terminated string to an SMB message */
+#define MSGCATNULL(str) \
+ strcpy(p, (str)); \
+ p += strlen(str) + 1;
+
+/* SMB is mostly little endian */
+#if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \
+ defined(__OS400__)
+static unsigned short smb_swap16(unsigned short x)
+{
+ return (x << 8) | ((x >> 8) & 0xff);
+}
+
+static unsigned int smb_swap32(unsigned int x)
+{
+ return (x << 24) | ((x << 8) & 0xff0000) | ((x >> 8) & 0xff00) |
+ ((x >> 24) & 0xff);
+}
+
+#ifdef HAVE_LONGLONG
+static unsigned long long smb_swap64(unsigned long long x)
+{
+ return ((unsigned long long)smb_swap32(x) << 32) | smb_swap32(x >> 32);
+}
+#else
+static unsigned __int64 smb_swap64(unsigned __int64 x)
+{
+ return ((unsigned __int64)smb_swap32(x) << 32) | smb_swap32(x >> 32);
+}
+#endif
+#else
+# define smb_swap16(x) (x)
+# define smb_swap32(x) (x)
+# define smb_swap64(x) (x)
+#endif
+
+/* SMB request state */
+enum smb_req_state {
+ SMB_REQUESTING,
+ SMB_TREE_CONNECT,
+ SMB_OPEN,
+ SMB_DOWNLOAD,
+ SMB_UPLOAD,
+ SMB_CLOSE,
+ SMB_TREE_DISCONNECT,
+ SMB_DONE
+};
+
+/* SMB request data */
+struct smb_request {
+ enum smb_req_state state;
+ char *share;
+ char *path;
+ unsigned short tid; /* Even if we connect to the same tree as another */
+ unsigned short fid; /* request, the tid will be different */
+ CURLcode result;
+};
+
+static void conn_state(struct connectdata *conn, enum smb_conn_state newstate)
+{
+ struct smb_conn *smb = &conn->proto.smbc;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+ /* For debug purposes */
+ static const char * const names[] = {
+ "SMB_NOT_CONNECTED",
+ "SMB_CONNECTING",
+ "SMB_NEGOTIATE",
+ "SMB_SETUP",
+ "SMB_CONNECTED",
+ /* LAST */
+ };
+
+ if(smb->state != newstate)
+ infof(conn->data, "SMB conn %p state change from %s to %s\n",
+ (void *)smb, names[smb->state], names[newstate]);
+#endif
+
+ smb->state = newstate;
+}
+
+static void request_state(struct connectdata *conn,
+ enum smb_req_state newstate)
+{
+ struct smb_request *req = conn->data->req.protop;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+ /* For debug purposes */
+ static const char * const names[] = {
+ "SMB_REQUESTING",
+ "SMB_TREE_CONNECT",
+ "SMB_OPEN",
+ "SMB_DOWNLOAD",
+ "SMB_UPLOAD",
+ "SMB_CLOSE",
+ "SMB_TREE_DISCONNECT",
+ "SMB_DONE",
+ /* LAST */
+ };
+
+ if(req->state != newstate)
+ infof(conn->data, "SMB request %p state change from %s to %s\n",
+ (void *)req, names[req->state], names[newstate]);
+#endif
+
+ req->state = newstate;
+}
+
+static CURLcode smb_setup_connection(struct connectdata *conn)
+{
+ struct smb_request *req;
+
+ /* Initialize the request state */
+ conn->data->req.protop = req = calloc(1, sizeof(struct smb_request));
+ if(!req)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Parse the URL path */
+ return smb_parse_url_path(conn);
+}
+
+static CURLcode smb_connect(struct connectdata *conn, bool *done)
+{
+ struct smb_conn *smbc = &conn->proto.smbc;
+ char *slash;
+
+ (void) done;
+
+ /* Check we have a username and password to authenticate with */
+ if(!conn->bits.user_passwd)
+ return CURLE_LOGIN_DENIED;
+
+ /* Initialize the connection state */
+ memset(smbc, 0, sizeof(*smbc));
+ smbc->state = SMB_CONNECTING;
+ smbc->recv_buf = malloc(MAX_MESSAGE_SIZE);
+ if(!smbc->recv_buf)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Multiple requests are allowed with this connection */
+ connkeep(conn, "SMB default");
+
+ /* Parse the username, domain, and password */
+ slash = strchr(conn->user, '/');
+ if(!slash)
+ slash = strchr(conn->user, '\\');
+
+ if(slash) {
+ smbc->user = slash + 1;
+ smbc->domain = strdup(conn->user);
+ if(!smbc->domain)
+ return CURLE_OUT_OF_MEMORY;
+ smbc->domain[slash - conn->user] = 0;
+ }
+ else {
+ smbc->user = conn->user;
+ smbc->domain = strdup(conn->host.name);
+ if(!smbc->domain)
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ return CURLE_OK;
+}
+
+static CURLcode smb_recv_message(struct connectdata *conn, void **msg)
+{
+ struct smb_conn *smbc = &conn->proto.smbc;
+ char *buf = smbc->recv_buf;
+ ssize_t bytes_read;
+ size_t nbt_size;
+ size_t msg_size;
+ size_t len = MAX_MESSAGE_SIZE - smbc->got;
+ CURLcode result;
+
+ result = Curl_read(conn, FIRSTSOCKET, buf + smbc->got, len, &bytes_read);
+ if(result)
+ return result;
+
+ if(!bytes_read)
+ return CURLE_OK;
+
+ smbc->got += bytes_read;
+
+ /* Check for a 32-bit nbt header */
+ if(smbc->got < sizeof(unsigned int))
+ return CURLE_OK;
+
+ nbt_size = Curl_read16_be((unsigned char *)(buf + sizeof(unsigned short))) +
+ sizeof(unsigned int);
+ if(smbc->got < nbt_size)
+ return CURLE_OK;
+
+ msg_size = sizeof(struct smb_header);
+ if(nbt_size >= msg_size + 1) {
+ /* Add the word count */
+ msg_size += 1 + ((unsigned char) buf[msg_size]) * sizeof(unsigned short);
+ if(nbt_size >= msg_size + sizeof(unsigned short)) {
+ /* Add the byte count */
+ msg_size += sizeof(unsigned short) +
+ Curl_read16_le((unsigned char *)&buf[msg_size]);
+ if(nbt_size < msg_size)
+ return CURLE_READ_ERROR;
+ }
+ }
+
+ *msg = buf;
+
+ return CURLE_OK;
+}
+
+static void smb_pop_message(struct connectdata *conn)
+{
+ struct smb_conn *smbc = &conn->proto.smbc;
+
+ smbc->got = 0;
+}
+
+static void smb_format_message(struct connectdata *conn, struct smb_header *h,
+ unsigned char cmd, size_t len)
+{
+ struct smb_conn *smbc = &conn->proto.smbc;
+ struct smb_request *req = conn->data->req.protop;
+ unsigned int pid;
+
+ memset(h, 0, sizeof(*h));
+ h->nbt_length = htons((unsigned short) (sizeof(*h) - sizeof(unsigned int) +
+ len));
+ memcpy((char *)h->magic, "\xffSMB", 4);
+ h->command = cmd;
+ h->flags = SMB_FLAGS_CANONICAL_PATHNAMES | SMB_FLAGS_CASELESS_PATHNAMES;
+ h->flags2 = smb_swap16(SMB_FLAGS2_IS_LONG_NAME | SMB_FLAGS2_KNOWS_LONG_NAME);
+ h->uid = smb_swap16(smbc->uid);
+ h->tid = smb_swap16(req->tid);
+ pid = getpid();
+ h->pid_high = smb_swap16((unsigned short)(pid >> 16));
+ h->pid = smb_swap16((unsigned short) pid);
+}
+
+static CURLcode smb_send(struct connectdata *conn, ssize_t len,
+ size_t upload_size)
+{
+ struct smb_conn *smbc = &conn->proto.smbc;
+ ssize_t bytes_written;
+ CURLcode result;
+
+ result = Curl_write(conn, FIRSTSOCKET, conn->data->state.uploadbuffer,
+ len, &bytes_written);
+ if(result)
+ return result;
+
+ if(bytes_written != len) {
+ smbc->send_size = len;
+ smbc->sent = bytes_written;
+ }
+
+ smbc->upload_size = upload_size;
+
+ return CURLE_OK;
+}
+
+static CURLcode smb_flush(struct connectdata *conn)
+{
+ struct smb_conn *smbc = &conn->proto.smbc;
+ ssize_t bytes_written;
+ ssize_t len = smbc->send_size - smbc->sent;
+ CURLcode result;
+
+ if(!smbc->send_size)
+ return CURLE_OK;
+
+ result = Curl_write(conn, FIRSTSOCKET,
+ conn->data->state.uploadbuffer + smbc->sent,
+ len, &bytes_written);
+ if(result)
+ return result;
+
+ if(bytes_written != len)
+ smbc->sent += bytes_written;
+ else
+ smbc->send_size = 0;
+
+ return CURLE_OK;
+}
+
+static CURLcode smb_send_message(struct connectdata *conn, unsigned char cmd,
+ const void *msg, size_t msg_len)
+{
+ smb_format_message(conn, (struct smb_header *)conn->data->state.uploadbuffer,
+ cmd, msg_len);
+ memcpy(conn->data->state.uploadbuffer + sizeof(struct smb_header),
+ msg, msg_len);
+
+ return smb_send(conn, sizeof(struct smb_header) + msg_len, 0);
+}
+
+static CURLcode smb_send_negotiate(struct connectdata *conn)
+{
+ const char *msg = "\x00\x0c\x00\x02NT LM 0.12";
+
+ return smb_send_message(conn, SMB_COM_NEGOTIATE, msg, 15);
+}
+
+static CURLcode smb_send_setup(struct connectdata *conn)
+{
+ struct smb_conn *smbc = &conn->proto.smbc;
+ struct smb_setup msg;
+ char *p = msg.bytes;
+ unsigned char lm_hash[21];
+ unsigned char lm[24];
+ unsigned char nt_hash[21];
+ unsigned char nt[24];
+
+ size_t byte_count = sizeof(lm) + sizeof(nt);
+ byte_count += strlen(smbc->user) + strlen(smbc->domain);
+ byte_count += strlen(OS) + strlen(CLIENTNAME) + 4; /* 4 null chars */
+ if(byte_count > sizeof(msg.bytes))
+ return CURLE_FILESIZE_EXCEEDED;
+
+ Curl_ntlm_core_mk_lm_hash(conn->data, conn->passwd, lm_hash);
+ Curl_ntlm_core_lm_resp(lm_hash, smbc->challenge, lm);
+#if USE_NTRESPONSES
+ Curl_ntlm_core_mk_nt_hash(conn->data, conn->passwd, nt_hash);
+ Curl_ntlm_core_lm_resp(nt_hash, smbc->challenge, nt);
+#else
+ memset(nt, 0, sizeof(nt));
+#endif
+
+ memset(&msg, 0, sizeof(msg));
+ msg.word_count = SMB_WC_SETUP_ANDX;
+ msg.andx.command = SMB_COM_NO_ANDX_COMMAND;
+ msg.max_buffer_size = smb_swap16(MAX_MESSAGE_SIZE);
+ msg.max_mpx_count = smb_swap16(1);
+ msg.vc_number = smb_swap16(1);
+ msg.session_key = smb_swap32(smbc->session_key);
+ msg.capabilities = smb_swap32(SMB_CAP_LARGE_FILES);
+ msg.lengths[0] = smb_swap16(sizeof(lm));
+ msg.lengths[1] = smb_swap16(sizeof(nt));
+ memcpy(p, lm, sizeof(lm));
+ p += sizeof(lm);
+ memcpy(p, nt, sizeof(nt));
+ p += sizeof(nt);
+ MSGCATNULL(smbc->user);
+ MSGCATNULL(smbc->domain);
+ MSGCATNULL(OS);
+ MSGCATNULL(CLIENTNAME);
+ byte_count = p - msg.bytes;
+ msg.byte_count = smb_swap16((unsigned short)byte_count);
+
+ return smb_send_message(conn, SMB_COM_SETUP_ANDX, &msg,
+ sizeof(msg) - sizeof(msg.bytes) + byte_count);
+}
+
+static CURLcode smb_send_tree_connect(struct connectdata *conn)
+{
+ struct smb_request *req = conn->data->req.protop;
+ struct smb_tree_connect msg;
+ char *p = msg.bytes;
+
+ size_t byte_count = strlen(conn->host.name) + strlen(req->share);
+ byte_count += strlen(SERVICENAME) + 5; /* 2 nulls and 3 backslashes */
+ if(byte_count > sizeof(msg.bytes))
+ return CURLE_FILESIZE_EXCEEDED;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.word_count = SMB_WC_TREE_CONNECT_ANDX;
+ msg.andx.command = SMB_COM_NO_ANDX_COMMAND;
+ msg.pw_len = 0;
+ MSGCAT("\\\\");
+ MSGCAT(conn->host.name);
+ MSGCAT("\\");
+ MSGCATNULL(req->share);
+ MSGCATNULL(SERVICENAME); /* Match any type of service */
+ byte_count = p - msg.bytes;
+ msg.byte_count = smb_swap16((unsigned short)byte_count);
+
+ return smb_send_message(conn, SMB_COM_TREE_CONNECT_ANDX, &msg,
+ sizeof(msg) - sizeof(msg.bytes) + byte_count);
+}
+
+static CURLcode smb_send_open(struct connectdata *conn)
+{
+ struct smb_request *req = conn->data->req.protop;
+ struct smb_nt_create msg;
+ size_t byte_count;
+
+ if((strlen(req->path) + 1) > sizeof(msg.bytes))
+ return CURLE_FILESIZE_EXCEEDED;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.word_count = SMB_WC_NT_CREATE_ANDX;
+ msg.andx.command = SMB_COM_NO_ANDX_COMMAND;
+ byte_count = strlen(req->path);
+ msg.name_length = smb_swap16((unsigned short)byte_count);
+ msg.share_access = smb_swap32(SMB_FILE_SHARE_ALL);
+ if(conn->data->set.upload) {
+ msg.access = smb_swap32(SMB_GENERIC_READ | SMB_GENERIC_WRITE);
+ msg.create_disposition = smb_swap32(SMB_FILE_OVERWRITE_IF);
+ }
+ else {
+ msg.access = smb_swap32(SMB_GENERIC_READ);
+ msg.create_disposition = smb_swap32(SMB_FILE_OPEN);
+ }
+ msg.byte_count = smb_swap16((unsigned short) ++byte_count);
+ strcpy(msg.bytes, req->path);
+
+ return smb_send_message(conn, SMB_COM_NT_CREATE_ANDX, &msg,
+ sizeof(msg) - sizeof(msg.bytes) + byte_count);
+}
+
+static CURLcode smb_send_close(struct connectdata *conn)
+{
+ struct smb_request *req = conn->data->req.protop;
+ struct smb_close msg;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.word_count = SMB_WC_CLOSE;
+ msg.fid = smb_swap16(req->fid);
+
+ return smb_send_message(conn, SMB_COM_CLOSE, &msg, sizeof(msg));
+}
+
+static CURLcode smb_send_tree_disconnect(struct connectdata *conn)
+{
+ struct smb_tree_disconnect msg;
+
+ memset(&msg, 0, sizeof(msg));
+
+ return smb_send_message(conn, SMB_COM_TREE_DISCONNECT, &msg, sizeof(msg));
+}
+
+static CURLcode smb_send_read(struct connectdata *conn)
+{
+ struct smb_request *req = conn->data->req.protop;
+ curl_off_t offset = conn->data->req.offset;
+ struct smb_read msg;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.word_count = SMB_WC_READ_ANDX;
+ msg.andx.command = SMB_COM_NO_ANDX_COMMAND;
+ msg.fid = smb_swap16(req->fid);
+ msg.offset = smb_swap32((unsigned int) offset);
+ msg.offset_high = smb_swap32((unsigned int) (offset >> 32));
+ msg.min_bytes = smb_swap16(MAX_PAYLOAD_SIZE);
+ msg.max_bytes = smb_swap16(MAX_PAYLOAD_SIZE);
+
+ return smb_send_message(conn, SMB_COM_READ_ANDX, &msg, sizeof(msg));
+}
+
+static CURLcode smb_send_write(struct connectdata *conn)
+{
+ struct smb_write *msg = (struct smb_write *)conn->data->state.uploadbuffer;
+ struct smb_request *req = conn->data->req.protop;
+ curl_off_t offset = conn->data->req.offset;
+
+ curl_off_t upload_size = conn->data->req.size - conn->data->req.bytecount;
+ if(upload_size >= MAX_PAYLOAD_SIZE - 1) /* There is one byte of padding */
+ upload_size = MAX_PAYLOAD_SIZE - 1;
+
+ memset(msg, 0, sizeof(*msg));
+ msg->word_count = SMB_WC_WRITE_ANDX;
+ msg->andx.command = SMB_COM_NO_ANDX_COMMAND;
+ msg->fid = smb_swap16(req->fid);
+ msg->offset = smb_swap32((unsigned int) offset);
+ msg->offset_high = smb_swap32((unsigned int) (offset >> 32));
+ msg->data_length = smb_swap16((unsigned short) upload_size);
+ msg->data_offset = smb_swap16(sizeof(*msg) - sizeof(unsigned int));
+ msg->byte_count = smb_swap16((unsigned short) (upload_size + 1));
+
+ smb_format_message(conn, &msg->h, SMB_COM_WRITE_ANDX,
+ sizeof(*msg) - sizeof(msg->h) + (size_t) upload_size);
+
+ return smb_send(conn, sizeof(*msg), (size_t) upload_size);
+}
+
+static CURLcode smb_send_and_recv(struct connectdata *conn, void **msg)
+{
+ struct smb_conn *smbc = &conn->proto.smbc;
+ CURLcode result;
+
+ /* Check if there is data in the transfer buffer */
+ if(!smbc->send_size && smbc->upload_size) {
+ int nread = smbc->upload_size > BUFSIZE ? BUFSIZE :
+ (int) smbc->upload_size;
+ conn->data->req.upload_fromhere = conn->data->state.uploadbuffer;
+ result = Curl_fillreadbuffer(conn, nread, &nread);
+ if(result && result != CURLE_AGAIN)
+ return result;
+ if(!nread)
+ return CURLE_OK;
+
+ smbc->upload_size -= nread;
+ smbc->send_size = nread;
+ smbc->sent = 0;
+ }
+
+ /* Check if there is data to send */
+ if(smbc->send_size) {
+ result = smb_flush(conn);
+ if(result)
+ return result;
+ }
+
+ /* Check if there is still data to be sent */
+ if(smbc->send_size || smbc->upload_size)
+ return CURLE_AGAIN;
+
+ return smb_recv_message(conn, msg);
+}
+
+static CURLcode smb_connection_state(struct connectdata *conn, bool *done)
+{
+ struct smb_conn *smbc = &conn->proto.smbc;
+ struct smb_negotiate_response *nrsp;
+ struct smb_header *h;
+ CURLcode result;
+ void *msg = NULL;
+
+ if(smbc->state == SMB_CONNECTING) {
+#ifdef USE_SSL
+ if((conn->handler->flags & PROTOPT_SSL)) {
+ bool ssl_done;
+ result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &ssl_done);
+ if(result && result != CURLE_AGAIN)
+ return result;
+ if(!ssl_done)
+ return CURLE_OK;
+ }
+#endif
+
+ result = smb_send_negotiate(conn);
+ if(result) {
+ connclose(conn, "SMB: failed to send negotiate message");
+ return result;
+ }
+
+ conn_state(conn, SMB_NEGOTIATE);
+ }
+
+ /* Send the previous message and check for a response */
+ result = smb_send_and_recv(conn, &msg);
+ if(result && result != CURLE_AGAIN) {
+ connclose(conn, "SMB: failed to communicate");
+ return result;
+ }
+
+ if(!msg)
+ return CURLE_OK;
+
+ h = msg;
+
+ switch(smbc->state) {
+ case SMB_NEGOTIATE:
+ if(h->status) {
+ connclose(conn, "SMB: negotiation failed");
+ return CURLE_COULDNT_CONNECT;
+ }
+ nrsp = msg;
+ memcpy(smbc->challenge, nrsp->bytes, sizeof(smbc->challenge));
+ smbc->session_key = smb_swap32(nrsp->session_key);
+ result = smb_send_setup(conn);
+ if(result) {
+ connclose(conn, "SMB: failed to send setup message");
+ return result;
+ }
+ conn_state(conn, SMB_SETUP);
+ break;
+
+ case SMB_SETUP:
+ if(h->status) {
+ connclose(conn, "SMB: authentication failed");
+ return CURLE_LOGIN_DENIED;
+ }
+ smbc->uid = smb_swap16(h->uid);
+ conn_state(conn, SMB_CONNECTED);
+ *done = true;
+ break;
+
+ default:
+ smb_pop_message(conn);
+ return CURLE_OK; /* ignore */
+ }
+
+ smb_pop_message(conn);
+
+ return CURLE_OK;
+}
+
+static CURLcode smb_request_state(struct connectdata *conn, bool *done)
+{
+ struct smb_request *req = conn->data->req.protop;
+ struct smb_header *h;
+ enum smb_req_state next_state = SMB_DONE;
+ unsigned short len;
+ unsigned short off;
+ CURLcode result;
+ void *msg = NULL;
+
+ /* Start the request */
+ if(req->state == SMB_REQUESTING) {
+ result = smb_send_tree_connect(conn);
+ if(result) {
+ connclose(conn, "SMB: failed to send tree connect message");
+ return result;
+ }
+
+ request_state(conn, SMB_TREE_CONNECT);
+ }
+
+ /* Send the previous message and check for a response */
+ result = smb_send_and_recv(conn, &msg);
+ if(result && result != CURLE_AGAIN) {
+ connclose(conn, "SMB: failed to communicate");
+ return result;
+ }
+
+ if(!msg)
+ return CURLE_OK;
+
+ h = msg;
+
+ switch(req->state) {
+ case SMB_TREE_CONNECT:
+ if(h->status) {
+ req->result = CURLE_REMOTE_FILE_NOT_FOUND;
+ if(h->status == smb_swap32(SMB_ERR_NOACCESS))
+ req->result = CURLE_REMOTE_ACCESS_DENIED;
+ break;
+ }
+ req->tid = smb_swap16(h->tid);
+ next_state = SMB_OPEN;
+ break;
+
+ case SMB_OPEN:
+ if(h->status) {
+ req->result = CURLE_REMOTE_FILE_NOT_FOUND;
+ next_state = SMB_TREE_DISCONNECT;
+ break;
+ }
+ req->fid = smb_swap16(((struct smb_nt_create_response *)msg)->fid);
+ conn->data->req.offset = 0;
+ if(conn->data->set.upload) {
+ conn->data->req.size = conn->data->state.infilesize;
+ Curl_pgrsSetUploadSize(conn->data, conn->data->req.size);
+ next_state = SMB_UPLOAD;
+ }
+ else {
+ conn->data->req.size =
+ smb_swap64(((struct smb_nt_create_response *)msg)->end_of_file);
+ Curl_pgrsSetDownloadSize(conn->data, conn->data->req.size);
+ next_state = SMB_DOWNLOAD;
+ }
+ break;
+
+ case SMB_DOWNLOAD:
+ if(h->status) {
+ req->result = CURLE_RECV_ERROR;
+ next_state = SMB_CLOSE;
+ break;
+ }
+ len = Curl_read16_le(((unsigned char *) msg) +
+ sizeof(struct smb_header) + 11);
+ off = Curl_read16_le(((unsigned char *) msg) +
+ sizeof(struct smb_header) + 13);
+ if(len > 0) {
+ struct smb_conn *smbc = &conn->proto.smbc;
+ if(off + sizeof(unsigned int) + len > smbc->got) {
+ failf(conn->data, "Invalid input packet");
+ result = CURLE_RECV_ERROR;
+ }
+ else
+ result = Curl_client_write(conn, CLIENTWRITE_BODY,
+ (char *)msg + off + sizeof(unsigned int),
+ len);
+ if(result) {
+ req->result = result;
+ next_state = SMB_CLOSE;
+ break;
+ }
+ }
+ conn->data->req.bytecount += len;
+ conn->data->req.offset += len;
+ Curl_pgrsSetDownloadCounter(conn->data, conn->data->req.bytecount);
+ next_state = (len < MAX_PAYLOAD_SIZE) ? SMB_CLOSE : SMB_DOWNLOAD;
+ break;
+
+ case SMB_UPLOAD:
+ if(h->status) {
+ req->result = CURLE_UPLOAD_FAILED;
+ next_state = SMB_CLOSE;
+ break;
+ }
+ len = Curl_read16_le(((unsigned char *) msg) +
+ sizeof(struct smb_header) + 5);
+ conn->data->req.bytecount += len;
+ conn->data->req.offset += len;
+ Curl_pgrsSetUploadCounter(conn->data, conn->data->req.bytecount);
+ if(conn->data->req.bytecount >= conn->data->req.size)
+ next_state = SMB_CLOSE;
+ else
+ next_state = SMB_UPLOAD;
+ break;
+
+ case SMB_CLOSE:
+ /* We don't care if the close failed, proceed to tree disconnect anyway */
+ next_state = SMB_TREE_DISCONNECT;
+ break;
+
+ case SMB_TREE_DISCONNECT:
+ next_state = SMB_DONE;
+ break;
+
+ default:
+ smb_pop_message(conn);
+ return CURLE_OK; /* ignore */
+ }
+
+ smb_pop_message(conn);
+
+ switch(next_state) {
+ case SMB_OPEN:
+ result = smb_send_open(conn);
+ break;
+
+ case SMB_DOWNLOAD:
+ result = smb_send_read(conn);
+ break;
+
+ case SMB_UPLOAD:
+ result = smb_send_write(conn);
+ break;
+
+ case SMB_CLOSE:
+ result = smb_send_close(conn);
+ break;
+
+ case SMB_TREE_DISCONNECT:
+ result = smb_send_tree_disconnect(conn);
+ break;
+
+ case SMB_DONE:
+ result = req->result;
+ *done = true;
+ break;
+
+ default:
+ break;
+ }
+
+ if(result) {
+ connclose(conn, "SMB: failed to send message");
+ return result;
+ }
+
+ request_state(conn, next_state);
+
+ return CURLE_OK;
+}
+
+static CURLcode smb_done(struct connectdata *conn, CURLcode status,
+ bool premature)
+{
+ struct smb_request *req = conn->data->req.protop;
+
+ (void) premature;
+
+ Curl_safefree(req->share);
+ Curl_safefree(conn->data->req.protop);
+
+ return status;
+}
+
+static CURLcode smb_disconnect(struct connectdata *conn, bool dead)
+{
+ struct smb_conn *smbc = &conn->proto.smbc;
+ struct smb_request *req = conn->data->req.protop;
+
+ (void) dead;
+
+ Curl_safefree(smbc->domain);
+ Curl_safefree(smbc->recv_buf);
+
+ /* smb_done is not always called, so cleanup the request */
+ if(req) {
+ Curl_safefree(req->share);
+ Curl_safefree(conn->data->req.protop);
+ }
+
+ return CURLE_OK;
+}
+
+static int smb_getsock(struct connectdata *conn, curl_socket_t *socks,
+ int numsocks)
+{
+ struct smb_conn *smbc = &conn->proto.smbc;
+
+ if(!numsocks)
+ return GETSOCK_BLANK;
+
+ socks[0] = conn->sock[FIRSTSOCKET];
+
+ if(smbc->send_size || smbc->upload_size)
+ return GETSOCK_WRITESOCK(0);
+
+ return GETSOCK_READSOCK(0);
+}
+
+static CURLcode smb_parse_url_path(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct smb_request *req = data->req.protop;
+ char *path;
+ char *slash;
+
+ /* URL decode the path */
+ result = Curl_urldecode(data, data->state.path, 0, &path, NULL, TRUE);
+ if(result)
+ return result;
+
+ /* Parse the path for the share */
+ req->share = strdup((*path == '/' || *path == '\\') ? path + 1 : path);
+ if(!req->share) {
+ free(path);
+
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ slash = strchr(req->share, '/');
+ if(!slash)
+ slash = strchr(req->share, '\\');
+
+ /* The share must be present */
+ if(!slash) {
+ free(path);
+
+ return CURLE_URL_MALFORMAT;
+ }
+
+ /* Parse the path for the file path converting any forward slashes into
+ backslashes */
+ *slash++ = 0;
+ req->path = slash;
+ for(; *slash; slash++) {
+ if(*slash == '/')
+ *slash = '\\';
+ }
+
+ free(path);
+
+ return CURLE_OK;
+}
+
+#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
+
+#endif /* CURL_DISABLE_SMB && USE_NTLM && CURL_SIZEOF_CURL_OFF_T > 4 */
diff --git a/Utilities/cmcurl/lib/smb.h b/Utilities/cmcurl/lib/smb.h
new file mode 100644
index 000000000..7852fa1de
--- /dev/null
+++ b/Utilities/cmcurl/lib/smb.h
@@ -0,0 +1,271 @@
+#ifndef HEADER_CURL_SMB_H
+#define HEADER_CURL_SMB_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2014, Bill Nagel <wnagel@tycoint.com>, Exacq Technologies
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+enum smb_conn_state {
+ SMB_NOT_CONNECTED = 0,
+ SMB_CONNECTING,
+ SMB_NEGOTIATE,
+ SMB_SETUP,
+ SMB_CONNECTED
+};
+
+struct smb_conn {
+ enum smb_conn_state state;
+ char *user;
+ char *domain;
+ unsigned char challenge[8];
+ unsigned int session_key;
+ unsigned short uid;
+ char *recv_buf;
+ size_t upload_size;
+ size_t send_size;
+ size_t sent;
+ size_t got;
+};
+
+/*
+ * Definitions for SMB protocol data structures
+ */
+#ifdef BUILDING_CURL_SMB_C
+
+#if defined(_MSC_VER) || defined(__ILEC400__)
+# define PACK
+# pragma pack(push)
+# pragma pack(1)
+#elif defined(__GNUC__)
+# define PACK __attribute__((packed))
+#else
+# define PACK
+#endif
+
+#define SMB_COM_CLOSE 0x04
+#define SMB_COM_READ_ANDX 0x2e
+#define SMB_COM_WRITE_ANDX 0x2f
+#define SMB_COM_TREE_DISCONNECT 0x71
+#define SMB_COM_NEGOTIATE 0x72
+#define SMB_COM_SETUP_ANDX 0x73
+#define SMB_COM_TREE_CONNECT_ANDX 0x75
+#define SMB_COM_NT_CREATE_ANDX 0xa2
+#define SMB_COM_NO_ANDX_COMMAND 0xff
+
+#define SMB_WC_CLOSE 0x03
+#define SMB_WC_READ_ANDX 0x0c
+#define SMB_WC_WRITE_ANDX 0x0e
+#define SMB_WC_SETUP_ANDX 0x0d
+#define SMB_WC_TREE_CONNECT_ANDX 0x04
+#define SMB_WC_NT_CREATE_ANDX 0x18
+
+#define SMB_FLAGS_CANONICAL_PATHNAMES 0x10
+#define SMB_FLAGS_CASELESS_PATHNAMES 0x08
+#define SMB_FLAGS2_UNICODE_STRINGS 0x8000
+#define SMB_FLAGS2_IS_LONG_NAME 0x0040
+#define SMB_FLAGS2_KNOWS_LONG_NAME 0x0001
+
+#define SMB_CAP_LARGE_FILES 0x08
+#define SMB_GENERIC_WRITE 0x40000000
+#define SMB_GENERIC_READ 0x80000000
+#define SMB_FILE_SHARE_ALL 0x07
+#define SMB_FILE_OPEN 0x01
+#define SMB_FILE_OVERWRITE_IF 0x05
+
+#define SMB_ERR_NOACCESS 0x00050001
+
+struct smb_header {
+ unsigned char nbt_type;
+ unsigned char nbt_flags;
+ unsigned short nbt_length;
+ unsigned char magic[4];
+ unsigned char command;
+ unsigned int status;
+ unsigned char flags;
+ unsigned short flags2;
+ unsigned short pid_high;
+ unsigned char signature[8];
+ unsigned short pad;
+ unsigned short tid;
+ unsigned short pid;
+ unsigned short uid;
+ unsigned short mid;
+} PACK;
+
+struct smb_negotiate_response {
+ struct smb_header h;
+ unsigned char word_count;
+ unsigned short dialect_index;
+ unsigned char security_mode;
+ unsigned short max_mpx_count;
+ unsigned short max_number_vcs;
+ unsigned int max_buffer_size;
+ unsigned int max_raw_size;
+ unsigned int session_key;
+ unsigned int capabilities;
+ unsigned int system_time_low;
+ unsigned int system_time_high;
+ unsigned short server_time_zone;
+ unsigned char encryption_key_length;
+ unsigned short byte_count;
+ char bytes[1];
+} PACK;
+
+struct andx {
+ unsigned char command;
+ unsigned char pad;
+ unsigned short offset;
+} PACK;
+
+struct smb_setup {
+ unsigned char word_count;
+ struct andx andx;
+ unsigned short max_buffer_size;
+ unsigned short max_mpx_count;
+ unsigned short vc_number;
+ unsigned int session_key;
+ unsigned short lengths[2];
+ unsigned int pad;
+ unsigned int capabilities;
+ unsigned short byte_count;
+ char bytes[1024];
+} PACK;
+
+struct smb_tree_connect {
+ unsigned char word_count;
+ struct andx andx;
+ unsigned short flags;
+ unsigned short pw_len;
+ unsigned short byte_count;
+ char bytes[1024];
+} PACK;
+
+struct smb_nt_create {
+ unsigned char word_count;
+ struct andx andx;
+ unsigned char pad;
+ unsigned short name_length;
+ unsigned int flags;
+ unsigned int root_fid;
+ unsigned int access;
+#ifdef HAVE_LONGLONG
+ unsigned long long allocation_size;
+#else
+ unsigned __int64 allocation_size;
+#endif
+ unsigned int ext_file_attributes;
+ unsigned int share_access;
+ unsigned int create_disposition;
+ unsigned int create_options;
+ unsigned int impersonation_level;
+ unsigned char security_flags;
+ unsigned short byte_count;
+ char bytes[1024];
+} PACK;
+
+struct smb_nt_create_response {
+ struct smb_header h;
+ unsigned char word_count;
+ struct andx andx;
+ unsigned char op_lock_level;
+ unsigned short fid;
+ unsigned int create_disposition;
+#ifdef HAVE_LONGLONG
+ unsigned long long create_time;
+ unsigned long long last_access_time;
+ unsigned long long last_write_time;
+ unsigned long long last_change_time;
+#else
+ unsigned __int64 create_time;
+ unsigned __int64 last_access_time;
+ unsigned __int64 last_write_time;
+ unsigned __int64 last_change_time;
+#endif
+ unsigned int ext_file_attributes;
+#ifdef HAVE_LONGLONG
+ unsigned long long allocation_size;
+ unsigned long long end_of_file;
+#else
+ unsigned __int64 allocation_size;
+ unsigned __int64 end_of_file;
+#endif
+} PACK;
+
+struct smb_read {
+ unsigned char word_count;
+ struct andx andx;
+ unsigned short fid;
+ unsigned int offset;
+ unsigned short max_bytes;
+ unsigned short min_bytes;
+ unsigned int timeout;
+ unsigned short remaining;
+ unsigned int offset_high;
+ unsigned short byte_count;
+} PACK;
+
+struct smb_write {
+ struct smb_header h;
+ unsigned char word_count;
+ struct andx andx;
+ unsigned short fid;
+ unsigned int offset;
+ unsigned int timeout;
+ unsigned short write_mode;
+ unsigned short remaining;
+ unsigned short pad;
+ unsigned short data_length;
+ unsigned short data_offset;
+ unsigned int offset_high;
+ unsigned short byte_count;
+ unsigned char pad2;
+} PACK;
+
+struct smb_close {
+ unsigned char word_count;
+ unsigned short fid;
+ unsigned int last_mtime;
+ unsigned short byte_count;
+} PACK;
+
+struct smb_tree_disconnect {
+ unsigned char word_count;
+ unsigned short byte_count;
+} PACK;
+
+#if defined(_MSC_VER) || defined(__ILEC400__)
+# pragma pack(pop)
+#endif
+
+#endif /* BUILDING_CURL_SMB_C */
+
+#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
+ (CURL_SIZEOF_CURL_OFF_T > 4)
+
+#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
+
+extern const struct Curl_handler Curl_handler_smb;
+extern const struct Curl_handler Curl_handler_smbs;
+
+#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
+
+#endif /* CURL_DISABLE_SMB && USE_NTLM && CURL_SIZEOF_CURL_OFF_T > 4 */
+
+#endif /* HEADER_CURL_SMB_H */
diff --git a/Utilities/cmcurl/lib/smtp.c b/Utilities/cmcurl/lib/smtp.c
new file mode 100644
index 000000000..dada087a9
--- /dev/null
+++ b/Utilities/cmcurl/lib/smtp.c
@@ -0,0 +1,1671 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * RFC1870 SMTP Service Extension for Message Size
+ * RFC2195 CRAM-MD5 authentication
+ * RFC2831 DIGEST-MD5 authentication
+ * RFC3207 SMTP over TLS
+ * RFC4422 Simple Authentication and Security Layer (SASL)
+ * RFC4616 PLAIN authentication
+ * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism
+ * RFC4954 SMTP Authentication
+ * RFC5321 SMTP protocol
+ * RFC6749 OAuth 2.0 Authorization Framework
+ * Draft SMTP URL Interface <draft-earhart-url-smtp-00.txt>
+ * Draft LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_SMTP
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "progress.h"
+#include "transfer.h"
+#include "escape.h"
+#include "http.h" /* for HTTP proxy tunnel stuff */
+#include "socks.h"
+#include "smtp.h"
+
+#include "strtoofft.h"
+#include "strequal.h"
+#include "vtls/vtls.h"
+#include "connect.h"
+#include "strerror.h"
+#include "select.h"
+#include "multiif.h"
+#include "url.h"
+#include "rawstr.h"
+#include "curl_gethostname.h"
+#include "curl_sasl.h"
+#include "warnless.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* Local API functions */
+static CURLcode smtp_regular_transfer(struct connectdata *conn, bool *done);
+static CURLcode smtp_do(struct connectdata *conn, bool *done);
+static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
+ bool premature);
+static CURLcode smtp_connect(struct connectdata *conn, bool *done);
+static CURLcode smtp_disconnect(struct connectdata *conn, bool dead);
+static CURLcode smtp_multi_statemach(struct connectdata *conn, bool *done);
+static int smtp_getsock(struct connectdata *conn, curl_socket_t *socks,
+ int numsocks);
+static CURLcode smtp_doing(struct connectdata *conn, bool *dophase_done);
+static CURLcode smtp_setup_connection(struct connectdata *conn);
+static CURLcode smtp_parse_url_options(struct connectdata *conn);
+static CURLcode smtp_parse_url_path(struct connectdata *conn);
+static CURLcode smtp_parse_custom_request(struct connectdata *conn);
+static CURLcode smtp_perform_auth(struct connectdata *conn, const char *mech,
+ const char *initresp);
+static CURLcode smtp_continue_auth(struct connectdata *conn, const char *resp);
+static void smtp_get_message(char *buffer, char** outptr);
+
+/*
+ * SMTP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_smtp = {
+ "SMTP", /* scheme */
+ smtp_setup_connection, /* setup_connection */
+ smtp_do, /* do_it */
+ smtp_done, /* done */
+ ZERO_NULL, /* do_more */
+ smtp_connect, /* connect_it */
+ smtp_multi_statemach, /* connecting */
+ smtp_doing, /* doing */
+ smtp_getsock, /* proto_getsock */
+ smtp_getsock, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ smtp_disconnect, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_SMTP, /* defport */
+ CURLPROTO_SMTP, /* protocol */
+ PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY /* flags */
+};
+
+#ifdef USE_SSL
+/*
+ * SMTPS protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_smtps = {
+ "SMTPS", /* scheme */
+ smtp_setup_connection, /* setup_connection */
+ smtp_do, /* do_it */
+ smtp_done, /* done */
+ ZERO_NULL, /* do_more */
+ smtp_connect, /* connect_it */
+ smtp_multi_statemach, /* connecting */
+ smtp_doing, /* doing */
+ smtp_getsock, /* proto_getsock */
+ smtp_getsock, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ smtp_disconnect, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_SMTPS, /* defport */
+ CURLPROTO_SMTPS, /* protocol */
+ PROTOPT_CLOSEACTION | PROTOPT_SSL
+ | PROTOPT_NOURLQUERY /* flags */
+};
+#endif
+
+#ifndef CURL_DISABLE_HTTP
+/*
+ * HTTP-proxyed SMTP protocol handler.
+ */
+
+static const struct Curl_handler Curl_handler_smtp_proxy = {
+ "SMTP", /* scheme */
+ Curl_http_setup_conn, /* setup_connection */
+ Curl_http, /* do_it */
+ Curl_http_done, /* done */
+ ZERO_NULL, /* do_more */
+ ZERO_NULL, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_getsock */
+ ZERO_NULL, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ ZERO_NULL, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_SMTP, /* defport */
+ CURLPROTO_HTTP, /* protocol */
+ PROTOPT_NONE /* flags */
+};
+
+#ifdef USE_SSL
+/*
+ * HTTP-proxyed SMTPS protocol handler.
+ */
+
+static const struct Curl_handler Curl_handler_smtps_proxy = {
+ "SMTPS", /* scheme */
+ Curl_http_setup_conn, /* setup_connection */
+ Curl_http, /* do_it */
+ Curl_http_done, /* done */
+ ZERO_NULL, /* do_more */
+ ZERO_NULL, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_getsock */
+ ZERO_NULL, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ ZERO_NULL, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_SMTPS, /* defport */
+ CURLPROTO_HTTP, /* protocol */
+ PROTOPT_NONE /* flags */
+};
+#endif
+#endif
+
+/* SASL parameters for the smtp protocol */
+static const struct SASLproto saslsmtp = {
+ "smtp", /* The service name */
+ 334, /* Code received when continuation is expected */
+ 235, /* Code to receive upon authentication success */
+ 512 - 8, /* Maximum initial response length (no max) */
+ smtp_perform_auth, /* Send authentication command */
+ smtp_continue_auth, /* Send authentication continuation */
+ smtp_get_message /* Get SASL response message */
+};
+
+#ifdef USE_SSL
+static void smtp_to_smtps(struct connectdata *conn)
+{
+ conn->handler = &Curl_handler_smtps;
+}
+#else
+#define smtp_to_smtps(x) Curl_nop_stmt
+#endif
+
+/***********************************************************************
+ *
+ * smtp_endofresp()
+ *
+ * Checks for an ending SMTP status code at the start of the given string, but
+ * also detects various capabilities from the EHLO response including the
+ * supported authentication mechanisms.
+ */
+static bool smtp_endofresp(struct connectdata *conn, char *line, size_t len,
+ int *resp)
+{
+ struct smtp_conn *smtpc = &conn->proto.smtpc;
+ bool result = FALSE;
+
+ /* Nothing for us */
+ if(len < 4 || !ISDIGIT(line[0]) || !ISDIGIT(line[1]) || !ISDIGIT(line[2]))
+ return FALSE;
+
+ /* Do we have a command response? This should be the response code followed
+ by a space and optionally some text as per RFC-5321 and as outlined in
+ Section 4. Examples of RFC-4954 but some e-mail servers ignore this and
+ only send the response code instead as per Section 4.2. */
+ if(line[3] == ' ' || len == 5) {
+ result = TRUE;
+ *resp = curlx_sltosi(strtol(line, NULL, 10));
+
+ /* Make sure real server never sends internal value */
+ if(*resp == 1)
+ *resp = 0;
+ }
+ /* Do we have a multiline (continuation) response? */
+ else if(line[3] == '-' &&
+ (smtpc->state == SMTP_EHLO || smtpc->state == SMTP_COMMAND)) {
+ result = TRUE;
+ *resp = 1; /* Internal response code */
+ }
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_get_message()
+ *
+ * Gets the authentication message from the response buffer.
+ */
+static void smtp_get_message(char *buffer, char** outptr)
+{
+ size_t len = 0;
+ char* message = NULL;
+
+ /* Find the start of the message */
+ for(message = buffer + 4; *message == ' ' || *message == '\t'; message++)
+ ;
+
+ /* Find the end of the message */
+ for(len = strlen(message); len--;)
+ if(message[len] != '\r' && message[len] != '\n' && message[len] != ' ' &&
+ message[len] != '\t')
+ break;
+
+ /* Terminate the message */
+ if(++len) {
+ message[len] = '\0';
+ }
+
+ *outptr = message;
+}
+
+/***********************************************************************
+ *
+ * state()
+ *
+ * This is the ONLY way to change SMTP state!
+ */
+static void state(struct connectdata *conn, smtpstate newstate)
+{
+ struct smtp_conn *smtpc = &conn->proto.smtpc;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+ /* for debug purposes */
+ static const char * const names[] = {
+ "STOP",
+ "SERVERGREET",
+ "EHLO",
+ "HELO",
+ "STARTTLS",
+ "UPGRADETLS",
+ "AUTH",
+ "COMMAND",
+ "MAIL",
+ "RCPT",
+ "DATA",
+ "POSTDATA",
+ "QUIT",
+ /* LAST */
+ };
+
+ if(smtpc->state != newstate)
+ infof(conn->data, "SMTP %p state change from %s to %s\n",
+ (void *)smtpc, names[smtpc->state], names[newstate]);
+#endif
+
+ smtpc->state = newstate;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_ehlo()
+ *
+ * Sends the EHLO command to not only initialise communication with the ESMTP
+ * server but to also obtain a list of server side supported capabilities.
+ */
+static CURLcode smtp_perform_ehlo(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct smtp_conn *smtpc = &conn->proto.smtpc;
+
+ smtpc->sasl.authmechs = SASL_AUTH_NONE; /* No known auth. mechanism yet */
+ smtpc->sasl.authused = SASL_AUTH_NONE; /* Clear the authentication mechanism
+ used for esmtp connections */
+ smtpc->tls_supported = FALSE; /* Clear the TLS capability */
+ smtpc->auth_supported = FALSE; /* Clear the AUTH capability */
+
+ /* Send the EHLO command */
+ result = Curl_pp_sendf(&smtpc->pp, "EHLO %s", smtpc->domain);
+
+ if(!result)
+ state(conn, SMTP_EHLO);
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_helo()
+ *
+ * Sends the HELO command to initialise communication with the SMTP server.
+ */
+static CURLcode smtp_perform_helo(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct smtp_conn *smtpc = &conn->proto.smtpc;
+
+ smtpc->sasl.authused = SASL_AUTH_NONE; /* No authentication mechanism used
+ in smtp connections */
+
+ /* Send the HELO command */
+ result = Curl_pp_sendf(&smtpc->pp, "HELO %s", smtpc->domain);
+
+ if(!result)
+ state(conn, SMTP_HELO);
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_starttls()
+ *
+ * Sends the STLS command to start the upgrade to TLS.
+ */
+static CURLcode smtp_perform_starttls(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+
+ /* Send the STARTTLS command */
+ result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "STARTTLS");
+
+ if(!result)
+ state(conn, SMTP_STARTTLS);
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_upgrade_tls()
+ *
+ * Performs the upgrade to TLS.
+ */
+static CURLcode smtp_perform_upgrade_tls(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct smtp_conn *smtpc = &conn->proto.smtpc;
+
+ /* Start the SSL connection */
+ result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &smtpc->ssldone);
+
+ if(!result) {
+ if(smtpc->state != SMTP_UPGRADETLS)
+ state(conn, SMTP_UPGRADETLS);
+
+ if(smtpc->ssldone) {
+ smtp_to_smtps(conn);
+ result = smtp_perform_ehlo(conn);
+ }
+ }
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_auth()
+ *
+ * Sends an AUTH command allowing the client to login with the given SASL
+ * authentication mechanism.
+ */
+static CURLcode smtp_perform_auth(struct connectdata *conn,
+ const char *mech,
+ const char *initresp)
+{
+ CURLcode result = CURLE_OK;
+ struct smtp_conn *smtpc = &conn->proto.smtpc;
+
+ if(initresp) { /* AUTH <mech> ...<crlf> */
+ /* Send the AUTH command with the initial response */
+ result = Curl_pp_sendf(&smtpc->pp, "AUTH %s %s", mech, initresp);
+ }
+ else {
+ /* Send the AUTH command */
+ result = Curl_pp_sendf(&smtpc->pp, "AUTH %s", mech);
+ }
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_continue_auth()
+ *
+ * Sends SASL continuation data or cancellation.
+ */
+static CURLcode smtp_continue_auth(struct connectdata *conn, const char *resp)
+{
+ struct smtp_conn *smtpc = &conn->proto.smtpc;
+
+ return Curl_pp_sendf(&smtpc->pp, "%s", resp);
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_authentication()
+ *
+ * Initiates the authentication sequence, with the appropriate SASL
+ * authentication mechanism.
+ */
+static CURLcode smtp_perform_authentication(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct smtp_conn *smtpc = &conn->proto.smtpc;
+ saslprogress progress;
+
+ /* Check we have enough data to authenticate with, and the
+ server supports authentiation, and end the connect phase if not */
+ if(!smtpc->auth_supported ||
+ !Curl_sasl_can_authenticate(&smtpc->sasl, conn)) {
+ state(conn, SMTP_STOP);
+ return result;
+ }
+
+ /* Calculate the SASL login details */
+ result = Curl_sasl_start(&smtpc->sasl, conn, FALSE, &progress);
+
+ if(!result) {
+ if(progress == SASL_INPROGRESS)
+ state(conn, SMTP_AUTH);
+ else {
+ /* Other mechanisms not supported */
+ infof(conn->data, "No known authentication mechanisms supported!\n");
+ result = CURLE_LOGIN_DENIED;
+ }
+ }
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_command()
+ *
+ * Sends a SMTP based command.
+ */
+static CURLcode smtp_perform_command(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct SMTP *smtp = data->req.protop;
+
+ /* Send the command */
+ if(smtp->rcpt)
+ result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s %s",
+ smtp->custom && smtp->custom[0] != '\0' ?
+ smtp->custom : "VRFY",
+ smtp->rcpt->data);
+ else
+ result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s",
+ smtp->custom && smtp->custom[0] != '\0' ?
+ smtp->custom : "HELP");
+
+ if(!result)
+ state(conn, SMTP_COMMAND);
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_mail()
+ *
+ * Sends an MAIL command to initiate the upload of a message.
+ */
+static CURLcode smtp_perform_mail(struct connectdata *conn)
+{
+ char *from = NULL;
+ char *auth = NULL;
+ char *size = NULL;
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+
+ /* Calculate the FROM parameter */
+ if(!data->set.str[STRING_MAIL_FROM])
+ /* Null reverse-path, RFC-5321, sect. 3.6.3 */
+ from = strdup("<>");
+ else if(data->set.str[STRING_MAIL_FROM][0] == '<')
+ from = aprintf("%s", data->set.str[STRING_MAIL_FROM]);
+ else
+ from = aprintf("<%s>", data->set.str[STRING_MAIL_FROM]);
+
+ if(!from)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Calculate the optional AUTH parameter */
+ if(data->set.str[STRING_MAIL_AUTH] && conn->proto.smtpc.sasl.authused) {
+ if(data->set.str[STRING_MAIL_AUTH][0] != '\0')
+ auth = aprintf("%s", data->set.str[STRING_MAIL_AUTH]);
+ else
+ /* Empty AUTH, RFC-2554, sect. 5 */
+ auth = strdup("<>");
+
+ if(!auth) {
+ free(from);
+
+ return CURLE_OUT_OF_MEMORY;
+ }
+ }
+
+ /* Calculate the optional SIZE parameter */
+ if(conn->proto.smtpc.size_supported && conn->data->state.infilesize > 0) {
+ size = aprintf("%" CURL_FORMAT_CURL_OFF_T, data->state.infilesize);
+
+ if(!size) {
+ free(from);
+ free(auth);
+
+ return CURLE_OUT_OF_MEMORY;
+ }
+ }
+
+ /* Send the MAIL command */
+ if(!auth && !size)
+ result = Curl_pp_sendf(&conn->proto.smtpc.pp,
+ "MAIL FROM:%s", from);
+ else if(auth && !size)
+ result = Curl_pp_sendf(&conn->proto.smtpc.pp,
+ "MAIL FROM:%s AUTH=%s", from, auth);
+ else if(auth && size)
+ result = Curl_pp_sendf(&conn->proto.smtpc.pp,
+ "MAIL FROM:%s AUTH=%s SIZE=%s", from, auth, size);
+ else
+ result = Curl_pp_sendf(&conn->proto.smtpc.pp,
+ "MAIL FROM:%s SIZE=%s", from, size);
+
+ free(from);
+ free(auth);
+ free(size);
+
+ if(!result)
+ state(conn, SMTP_MAIL);
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_rcpt_to()
+ *
+ * Sends a RCPT TO command for a given recipient as part of the message upload
+ * process.
+ */
+static CURLcode smtp_perform_rcpt_to(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct SMTP *smtp = data->req.protop;
+
+ /* Send the RCPT TO command */
+ if(smtp->rcpt->data[0] == '<')
+ result = Curl_pp_sendf(&conn->proto.smtpc.pp, "RCPT TO:%s",
+ smtp->rcpt->data);
+ else
+ result = Curl_pp_sendf(&conn->proto.smtpc.pp, "RCPT TO:<%s>",
+ smtp->rcpt->data);
+ if(!result)
+ state(conn, SMTP_RCPT);
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_quit()
+ *
+ * Performs the quit action prior to sclose() being called.
+ */
+static CURLcode smtp_perform_quit(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+
+ /* Send the QUIT command */
+ result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "QUIT");
+
+ if(!result)
+ state(conn, SMTP_QUIT);
+
+ return result;
+}
+
+/* For the initial server greeting */
+static CURLcode smtp_state_servergreet_resp(struct connectdata *conn,
+ int smtpcode,
+ smtpstate instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+
+ (void)instate; /* no use for this yet */
+
+ if(smtpcode/100 != 2) {
+ failf(data, "Got unexpected smtp-server response: %d", smtpcode);
+ result = CURLE_FTP_WEIRD_SERVER_REPLY;
+ }
+ else
+ result = smtp_perform_ehlo(conn);
+
+ return result;
+}
+
+/* For STARTTLS responses */
+static CURLcode smtp_state_starttls_resp(struct connectdata *conn,
+ int smtpcode,
+ smtpstate instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+
+ (void)instate; /* no use for this yet */
+
+ if(smtpcode != 220) {
+ if(data->set.use_ssl != CURLUSESSL_TRY) {
+ failf(data, "STARTTLS denied. %c", smtpcode);
+ result = CURLE_USE_SSL_FAILED;
+ }
+ else
+ result = smtp_perform_authentication(conn);
+ }
+ else
+ result = smtp_perform_upgrade_tls(conn);
+
+ return result;
+}
+
+/* For EHLO responses */
+static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode,
+ smtpstate instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct smtp_conn *smtpc = &conn->proto.smtpc;
+ const char *line = data->state.buffer;
+ size_t len = strlen(line);
+ size_t wordlen;
+
+ (void)instate; /* no use for this yet */
+
+ if(smtpcode/100 != 2 && smtpcode != 1) {
+ if(data->set.use_ssl <= CURLUSESSL_TRY || conn->ssl[FIRSTSOCKET].use)
+ result = smtp_perform_helo(conn);
+ else {
+ failf(data, "Remote access denied: %d", smtpcode);
+ result = CURLE_REMOTE_ACCESS_DENIED;
+ }
+ }
+ else {
+ line += 4;
+ len -= 4;
+
+ /* Does the server support the STARTTLS capability? */
+ if(len >= 8 && !memcmp(line, "STARTTLS", 8))
+ smtpc->tls_supported = TRUE;
+
+ /* Does the server support the SIZE capability? */
+ else if(len >= 4 && !memcmp(line, "SIZE", 4))
+ smtpc->size_supported = TRUE;
+
+ /* Does the server support authentication? */
+ else if(len >= 5 && !memcmp(line, "AUTH ", 5)) {
+ smtpc->auth_supported = TRUE;
+
+ /* Advance past the AUTH keyword */
+ line += 5;
+ len -= 5;
+
+ /* Loop through the data line */
+ for(;;) {
+ size_t llen;
+ unsigned int mechbit;
+
+ while(len &&
+ (*line == ' ' || *line == '\t' ||
+ *line == '\r' || *line == '\n')) {
+
+ line++;
+ len--;
+ }
+
+ if(!len)
+ break;
+
+ /* Extract the word */
+ for(wordlen = 0; wordlen < len && line[wordlen] != ' ' &&
+ line[wordlen] != '\t' && line[wordlen] != '\r' &&
+ line[wordlen] != '\n';)
+ wordlen++;
+
+ /* Test the word for a matching authentication mechanism */
+ if((mechbit = Curl_sasl_decode_mech(line, wordlen, &llen)) &&
+ llen == wordlen)
+ smtpc->sasl.authmechs |= mechbit;
+
+ line += wordlen;
+ len -= wordlen;
+ }
+ }
+
+ if(smtpcode != 1) {
+ if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
+ /* We don't have a SSL/TLS connection yet, but SSL is requested */
+ if(smtpc->tls_supported)
+ /* Switch to TLS connection now */
+ result = smtp_perform_starttls(conn);
+ else if(data->set.use_ssl == CURLUSESSL_TRY)
+ /* Fallback and carry on with authentication */
+ result = smtp_perform_authentication(conn);
+ else {
+ failf(data, "STARTTLS not supported.");
+ result = CURLE_USE_SSL_FAILED;
+ }
+ }
+ else
+ result = smtp_perform_authentication(conn);
+ }
+ }
+
+ return result;
+}
+
+/* For HELO responses */
+static CURLcode smtp_state_helo_resp(struct connectdata *conn, int smtpcode,
+ smtpstate instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+
+ (void)instate; /* no use for this yet */
+
+ if(smtpcode/100 != 2) {
+ failf(data, "Remote access denied: %d", smtpcode);
+ result = CURLE_REMOTE_ACCESS_DENIED;
+ }
+ else
+ /* End of connect phase */
+ state(conn, SMTP_STOP);
+
+ return result;
+}
+
+/* For SASL authentication responses */
+static CURLcode smtp_state_auth_resp(struct connectdata *conn,
+ int smtpcode,
+ smtpstate instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct smtp_conn *smtpc = &conn->proto.smtpc;
+ saslprogress progress;
+
+ (void)instate; /* no use for this yet */
+
+ result = Curl_sasl_continue(&smtpc->sasl, conn, smtpcode, &progress);
+ if(!result)
+ switch(progress) {
+ case SASL_DONE:
+ state(conn, SMTP_STOP); /* Authenticated */
+ break;
+ case SASL_IDLE: /* No mechanism left after cancellation */
+ failf(data, "Authentication cancelled");
+ result = CURLE_LOGIN_DENIED;
+ break;
+ default:
+ break;
+ }
+
+ return result;
+}
+
+/* For command responses */
+static CURLcode smtp_state_command_resp(struct connectdata *conn, int smtpcode,
+ smtpstate instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct SMTP *smtp = data->req.protop;
+ char *line = data->state.buffer;
+ size_t len = strlen(line);
+
+ (void)instate; /* no use for this yet */
+
+ if((smtp->rcpt && smtpcode/100 != 2 && smtpcode != 553 && smtpcode != 1) ||
+ (!smtp->rcpt && smtpcode/100 != 2 && smtpcode != 1)) {
+ failf(data, "Command failed: %d", smtpcode);
+ result = CURLE_RECV_ERROR;
+ }
+ else {
+ /* Temporarily add the LF character back and send as body to the client */
+ if(!data->set.opt_no_body) {
+ line[len] = '\n';
+ result = Curl_client_write(conn, CLIENTWRITE_BODY, line, len + 1);
+ line[len] = '\0';
+ }
+
+ if(smtpcode != 1) {
+ if(smtp->rcpt) {
+ smtp->rcpt = smtp->rcpt->next;
+
+ if(smtp->rcpt) {
+ /* Send the next command */
+ result = smtp_perform_command(conn);
+ }
+ else
+ /* End of DO phase */
+ state(conn, SMTP_STOP);
+ }
+ else
+ /* End of DO phase */
+ state(conn, SMTP_STOP);
+ }
+ }
+
+ return result;
+}
+
+/* For MAIL responses */
+static CURLcode smtp_state_mail_resp(struct connectdata *conn, int smtpcode,
+ smtpstate instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+
+ (void)instate; /* no use for this yet */
+
+ if(smtpcode/100 != 2) {
+ failf(data, "MAIL failed: %d", smtpcode);
+ result = CURLE_SEND_ERROR;
+ }
+ else
+ /* Start the RCPT TO command */
+ result = smtp_perform_rcpt_to(conn);
+
+ return result;
+}
+
+/* For RCPT responses */
+static CURLcode smtp_state_rcpt_resp(struct connectdata *conn, int smtpcode,
+ smtpstate instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct SMTP *smtp = data->req.protop;
+
+ (void)instate; /* no use for this yet */
+
+ if(smtpcode/100 != 2) {
+ failf(data, "RCPT failed: %d", smtpcode);
+ result = CURLE_SEND_ERROR;
+ }
+ else {
+ smtp->rcpt = smtp->rcpt->next;
+
+ if(smtp->rcpt)
+ /* Send the next RCPT TO command */
+ result = smtp_perform_rcpt_to(conn);
+ else {
+ /* Send the DATA command */
+ result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "DATA");
+
+ if(!result)
+ state(conn, SMTP_DATA);
+ }
+ }
+
+ return result;
+}
+
+/* For DATA response */
+static CURLcode smtp_state_data_resp(struct connectdata *conn, int smtpcode,
+ smtpstate instate)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+
+ (void)instate; /* no use for this yet */
+
+ if(smtpcode != 354) {
+ failf(data, "DATA failed: %d", smtpcode);
+ result = CURLE_SEND_ERROR;
+ }
+ else {
+ /* Set the progress upload size */
+ Curl_pgrsSetUploadSize(data, data->state.infilesize);
+
+ /* SMTP upload */
+ Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
+
+ /* End of DO phase */
+ state(conn, SMTP_STOP);
+ }
+
+ return result;
+}
+
+/* For POSTDATA responses, which are received after the entire DATA
+ part has been sent to the server */
+static CURLcode smtp_state_postdata_resp(struct connectdata *conn,
+ int smtpcode,
+ smtpstate instate)
+{
+ CURLcode result = CURLE_OK;
+
+ (void)instate; /* no use for this yet */
+
+ if(smtpcode != 250)
+ result = CURLE_RECV_ERROR;
+
+ /* End of DONE phase */
+ state(conn, SMTP_STOP);
+
+ return result;
+}
+
+static CURLcode smtp_statemach_act(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ curl_socket_t sock = conn->sock[FIRSTSOCKET];
+ struct SessionHandle *data = conn->data;
+ int smtpcode;
+ struct smtp_conn *smtpc = &conn->proto.smtpc;
+ struct pingpong *pp = &smtpc->pp;
+ size_t nread = 0;
+
+ /* Busy upgrading the connection; right now all I/O is SSL/TLS, not SMTP */
+ if(smtpc->state == SMTP_UPGRADETLS)
+ return smtp_perform_upgrade_tls(conn);
+
+ /* Flush any data that needs to be sent */
+ if(pp->sendleft)
+ return Curl_pp_flushsend(pp);
+
+ do {
+ /* Read the response from the server */
+ result = Curl_pp_readresp(sock, pp, &smtpcode, &nread);
+ if(result)
+ return result;
+
+ /* Store the latest response for later retrieval if necessary */
+ if(smtpc->state != SMTP_QUIT && smtpcode != 1)
+ data->info.httpcode = smtpcode;
+
+ if(!smtpcode)
+ break;
+
+ /* We have now received a full SMTP server response */
+ switch(smtpc->state) {
+ case SMTP_SERVERGREET:
+ result = smtp_state_servergreet_resp(conn, smtpcode, smtpc->state);
+ break;
+
+ case SMTP_EHLO:
+ result = smtp_state_ehlo_resp(conn, smtpcode, smtpc->state);
+ break;
+
+ case SMTP_HELO:
+ result = smtp_state_helo_resp(conn, smtpcode, smtpc->state);
+ break;
+
+ case SMTP_STARTTLS:
+ result = smtp_state_starttls_resp(conn, smtpcode, smtpc->state);
+ break;
+
+ case SMTP_AUTH:
+ result = smtp_state_auth_resp(conn, smtpcode, smtpc->state);
+ break;
+
+ case SMTP_COMMAND:
+ result = smtp_state_command_resp(conn, smtpcode, smtpc->state);
+ break;
+
+ case SMTP_MAIL:
+ result = smtp_state_mail_resp(conn, smtpcode, smtpc->state);
+ break;
+
+ case SMTP_RCPT:
+ result = smtp_state_rcpt_resp(conn, smtpcode, smtpc->state);
+ break;
+
+ case SMTP_DATA:
+ result = smtp_state_data_resp(conn, smtpcode, smtpc->state);
+ break;
+
+ case SMTP_POSTDATA:
+ result = smtp_state_postdata_resp(conn, smtpcode, smtpc->state);
+ break;
+
+ case SMTP_QUIT:
+ /* fallthrough, just stop! */
+ default:
+ /* internal error */
+ state(conn, SMTP_STOP);
+ break;
+ }
+ } while(!result && smtpc->state != SMTP_STOP && Curl_pp_moredata(pp));
+
+ return result;
+}
+
+/* Called repeatedly until done from multi.c */
+static CURLcode smtp_multi_statemach(struct connectdata *conn, bool *done)
+{
+ CURLcode result = CURLE_OK;
+ struct smtp_conn *smtpc = &conn->proto.smtpc;
+
+ if((conn->handler->flags & PROTOPT_SSL) && !smtpc->ssldone) {
+ result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &smtpc->ssldone);
+ if(result || !smtpc->ssldone)
+ return result;
+ }
+
+ result = Curl_pp_statemach(&smtpc->pp, FALSE);
+ *done = (smtpc->state == SMTP_STOP) ? TRUE : FALSE;
+
+ return result;
+}
+
+static CURLcode smtp_block_statemach(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct smtp_conn *smtpc = &conn->proto.smtpc;
+
+ while(smtpc->state != SMTP_STOP && !result)
+ result = Curl_pp_statemach(&smtpc->pp, TRUE);
+
+ return result;
+}
+
+/* Allocate and initialize the SMTP struct for the current SessionHandle if
+ required */
+static CURLcode smtp_init(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct SMTP *smtp;
+
+ smtp = data->req.protop = calloc(sizeof(struct SMTP), 1);
+ if(!smtp)
+ result = CURLE_OUT_OF_MEMORY;
+
+ return result;
+}
+
+/* For the SMTP "protocol connect" and "doing" phases only */
+static int smtp_getsock(struct connectdata *conn, curl_socket_t *socks,
+ int numsocks)
+{
+ return Curl_pp_getsock(&conn->proto.smtpc.pp, socks, numsocks);
+}
+
+/***********************************************************************
+ *
+ * smtp_connect()
+ *
+ * This function should do everything that is to be considered a part of
+ * the connection phase.
+ *
+ * The variable pointed to by 'done' will be TRUE if the protocol-layer
+ * connect phase is done when this function returns, or FALSE if not.
+ */
+static CURLcode smtp_connect(struct connectdata *conn, bool *done)
+{
+ CURLcode result = CURLE_OK;
+ struct smtp_conn *smtpc = &conn->proto.smtpc;
+ struct pingpong *pp = &smtpc->pp;
+
+ *done = FALSE; /* default to not done yet */
+
+ /* We always support persistent connections in SMTP */
+ connkeep(conn, "SMTP default");
+
+ /* Set the default response time-out */
+ pp->response_time = RESP_TIMEOUT;
+ pp->statemach_act = smtp_statemach_act;
+ pp->endofresp = smtp_endofresp;
+ pp->conn = conn;
+
+ /* Initialize the SASL storage */
+ Curl_sasl_init(&smtpc->sasl, &saslsmtp);
+
+ /* Initialise the pingpong layer */
+ Curl_pp_init(pp);
+
+ /* Parse the URL options */
+ result = smtp_parse_url_options(conn);
+ if(result)
+ return result;
+
+ /* Parse the URL path */
+ result = smtp_parse_url_path(conn);
+ if(result)
+ return result;
+
+ /* Start off waiting for the server greeting response */
+ state(conn, SMTP_SERVERGREET);
+
+ result = smtp_multi_statemach(conn, done);
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_done()
+ *
+ * The DONE function. This does what needs to be done after a single DO has
+ * performed.
+ *
+ * Input argument is already checked for validity.
+ */
+static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
+ bool premature)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct SMTP *smtp = data->req.protop;
+ struct pingpong *pp = &conn->proto.smtpc.pp;
+ char *eob;
+ ssize_t len;
+ ssize_t bytes_written;
+
+ (void)premature;
+
+ if(!smtp || !pp->conn)
+ /* When the easy handle is removed from the multi interface while libcurl
+ is still trying to resolve the host name, the SMTP struct is not yet
+ initialized. However, the removal action calls Curl_done() which in
+ turn calls this function, so we simply return success. */
+ return CURLE_OK;
+
+ if(status) {
+ connclose(conn, "SMTP done with bad status"); /* marked for closure */
+ result = status; /* use the already set error code */
+ }
+ else if(!data->set.connect_only && data->set.upload && data->set.mail_rcpt) {
+ /* Calculate the EOB taking into account any terminating CRLF from the
+ previous line of the email or the CRLF of the DATA command when there
+ is "no mail data". RFC-5321, sect. 4.1.1.4.
+
+ Note: As some SSL backends, such as OpenSSL, will cause Curl_write() to
+ fail when using a different pointer following a previous write, that
+ returned CURLE_AGAIN, we duplicate the EOB now rather than when the
+ bytes written doesn't equal len. */
+ if(smtp->trailing_crlf || !conn->data->state.infilesize) {
+ eob = strdup(SMTP_EOB + 2);
+ len = SMTP_EOB_LEN - 2;
+ }
+ else {
+ eob = strdup(SMTP_EOB);
+ len = SMTP_EOB_LEN;
+ }
+
+ if(!eob)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Send the end of block data */
+ result = Curl_write(conn, conn->writesockfd, eob, len, &bytes_written);
+ if(result) {
+ free(eob);
+ return result;
+ }
+
+ if(bytes_written != len) {
+ /* The whole chunk was not sent so keep it around and adjust the
+ pingpong structure accordingly */
+ pp->sendthis = eob;
+ pp->sendsize = len;
+ pp->sendleft = len - bytes_written;
+ }
+ else {
+ /* Successfully sent so adjust the response timeout relative to now */
+ pp->response = Curl_tvnow();
+
+ free(eob);
+ }
+
+ state(conn, SMTP_POSTDATA);
+
+ /* Run the state-machine
+
+ TODO: when the multi interface is used, this _really_ should be using
+ the smtp_multi_statemach function but we have no general support for
+ non-blocking DONE operations, not in the multi state machine and with
+ Curl_done() invokes on several places in the code!
+ */
+ result = smtp_block_statemach(conn);
+ }
+
+ /* Cleanup our per-request based variables */
+ Curl_safefree(smtp->custom);
+
+ /* Clear the transfer mode for the next request */
+ smtp->transfer = FTPTRANSFER_BODY;
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform()
+ *
+ * This is the actual DO function for SMTP. Transfer a mail, send a command
+ * or get some data according to the options previously setup.
+ */
+static CURLcode smtp_perform(struct connectdata *conn, bool *connected,
+ bool *dophase_done)
+{
+ /* This is SMTP and no proxy */
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct SMTP *smtp = data->req.protop;
+
+ DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+ if(data->set.opt_no_body) {
+ /* Requested no body means no transfer */
+ smtp->transfer = FTPTRANSFER_INFO;
+ }
+
+ *dophase_done = FALSE; /* not done yet */
+
+ /* Store the first recipient (or NULL if not specified) */
+ smtp->rcpt = data->set.mail_rcpt;
+
+ /* Start the first command in the DO phase */
+ if(data->set.upload && data->set.mail_rcpt)
+ /* MAIL transfer */
+ result = smtp_perform_mail(conn);
+ else
+ /* SMTP based command (VRFY, EXPN, NOOP, RSET or HELP) */
+ result = smtp_perform_command(conn);
+
+ if(result)
+ return result;
+
+ /* Run the state-machine */
+ result = smtp_multi_statemach(conn, dophase_done);
+
+ *connected = conn->bits.tcpconnect[FIRSTSOCKET];
+
+ if(*dophase_done)
+ DEBUGF(infof(conn->data, "DO phase is complete\n"));
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_do()
+ *
+ * This function is registered as 'curl_do' function. It decodes the path
+ * parts etc as a wrapper to the actual DO function (smtp_perform).
+ *
+ * The input argument is already checked for validity.
+ */
+static CURLcode smtp_do(struct connectdata *conn, bool *done)
+{
+ CURLcode result = CURLE_OK;
+
+ *done = FALSE; /* default to false */
+
+ /* Parse the custom request */
+ result = smtp_parse_custom_request(conn);
+ if(result)
+ return result;
+
+ result = smtp_regular_transfer(conn, done);
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_disconnect()
+ *
+ * Disconnect from an SMTP server. Cleanup protocol-specific per-connection
+ * resources. BLOCKING.
+ */
+static CURLcode smtp_disconnect(struct connectdata *conn, bool dead_connection)
+{
+ struct smtp_conn *smtpc = &conn->proto.smtpc;
+
+ /* We cannot send quit unconditionally. If this connection is stale or
+ bad in any way, sending quit and waiting around here will make the
+ disconnect wait in vain and cause more problems than we need to. */
+
+ /* The SMTP session may or may not have been allocated/setup at this
+ point! */
+ if(!dead_connection && smtpc->pp.conn && smtpc->pp.conn->bits.protoconnstart)
+ if(!smtp_perform_quit(conn))
+ (void)smtp_block_statemach(conn); /* ignore errors on QUIT */
+
+ /* Disconnect from the server */
+ Curl_pp_disconnect(&smtpc->pp);
+
+ /* Cleanup the SASL module */
+ Curl_sasl_cleanup(conn, smtpc->sasl.authused);
+
+ /* Cleanup our connection based variables */
+ Curl_safefree(smtpc->domain);
+
+ return CURLE_OK;
+}
+
+/* Call this when the DO phase has completed */
+static CURLcode smtp_dophase_done(struct connectdata *conn, bool connected)
+{
+ struct SMTP *smtp = conn->data->req.protop;
+
+ (void)connected;
+
+ if(smtp->transfer != FTPTRANSFER_BODY)
+ /* no data to transfer */
+ Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+
+ return CURLE_OK;
+}
+
+/* Called from multi.c while DOing */
+static CURLcode smtp_doing(struct connectdata *conn, bool *dophase_done)
+{
+ CURLcode result = smtp_multi_statemach(conn, dophase_done);
+
+ if(result)
+ DEBUGF(infof(conn->data, "DO phase failed\n"));
+ else if(*dophase_done) {
+ result = smtp_dophase_done(conn, FALSE /* not connected */);
+
+ DEBUGF(infof(conn->data, "DO phase is complete\n"));
+ }
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_regular_transfer()
+ *
+ * The input argument is already checked for validity.
+ *
+ * Performs all commands done before a regular transfer between a local and a
+ * remote host.
+ */
+static CURLcode smtp_regular_transfer(struct connectdata *conn,
+ bool *dophase_done)
+{
+ CURLcode result = CURLE_OK;
+ bool connected = FALSE;
+ struct SessionHandle *data = conn->data;
+
+ /* Make sure size is unknown at this point */
+ data->req.size = -1;
+
+ /* Set the progress data */
+ Curl_pgrsSetUploadCounter(data, 0);
+ Curl_pgrsSetDownloadCounter(data, 0);
+ Curl_pgrsSetUploadSize(data, -1);
+ Curl_pgrsSetDownloadSize(data, -1);
+
+ /* Carry out the perform */
+ result = smtp_perform(conn, &connected, dophase_done);
+
+ /* Perform post DO phase operations if necessary */
+ if(!result && *dophase_done)
+ result = smtp_dophase_done(conn, connected);
+
+ return result;
+}
+
+static CURLcode smtp_setup_connection(struct connectdata *conn)
+{
+ struct SessionHandle *data = conn->data;
+ CURLcode result;
+
+ if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) {
+ /* Unless we have asked to tunnel SMTP operations through the proxy, we
+ switch and use HTTP operations only */
+#ifndef CURL_DISABLE_HTTP
+ if(conn->handler == &Curl_handler_smtp)
+ conn->handler = &Curl_handler_smtp_proxy;
+ else {
+#ifdef USE_SSL
+ conn->handler = &Curl_handler_smtps_proxy;
+#else
+ failf(data, "SMTPS not supported!");
+ return CURLE_UNSUPPORTED_PROTOCOL;
+#endif
+ }
+ /* set it up as a HTTP connection instead */
+ return conn->handler->setup_connection(conn);
+
+#else
+ failf(data, "SMTP over http proxy requires HTTP support built-in!");
+ return CURLE_UNSUPPORTED_PROTOCOL;
+#endif
+ }
+
+ /* Initialise the SMTP layer */
+ result = smtp_init(conn);
+ if(result)
+ return result;
+
+ data->state.path++; /* don't include the initial slash */
+
+ return CURLE_OK;
+}
+
+/***********************************************************************
+ *
+ * smtp_parse_url_options()
+ *
+ * Parse the URL login options.
+ */
+static CURLcode smtp_parse_url_options(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct smtp_conn *smtpc = &conn->proto.smtpc;
+ const char *ptr = conn->options;
+
+ smtpc->sasl.resetprefs = TRUE;
+
+ while(!result && ptr && *ptr) {
+ const char *key = ptr;
+ const char *value;
+
+ while(*ptr && *ptr != '=')
+ ptr++;
+
+ value = ptr + 1;
+
+ while(*ptr && *ptr != ';')
+ ptr++;
+
+ if(strnequal(key, "AUTH=", 5))
+ result = Curl_sasl_parse_url_auth_option(&smtpc->sasl,
+ value, ptr - value);
+ else
+ result = CURLE_URL_MALFORMAT;
+
+ if(*ptr == ';')
+ ptr++;
+ }
+
+ return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_parse_url_path()
+ *
+ * Parse the URL path into separate path components.
+ */
+static CURLcode smtp_parse_url_path(struct connectdata *conn)
+{
+ /* The SMTP struct is already initialised in smtp_connect() */
+ struct SessionHandle *data = conn->data;
+ struct smtp_conn *smtpc = &conn->proto.smtpc;
+ const char *path = data->state.path;
+ char localhost[HOSTNAME_MAX + 1];
+
+ /* Calculate the path if necessary */
+ if(!*path) {
+ if(!Curl_gethostname(localhost, sizeof(localhost)))
+ path = localhost;
+ else
+ path = "localhost";
+ }
+
+ /* URL decode the path and use it as the domain in our EHLO */
+ return Curl_urldecode(conn->data, path, 0, &smtpc->domain, NULL, TRUE);
+}
+
+/***********************************************************************
+ *
+ * smtp_parse_custom_request()
+ *
+ * Parse the custom request.
+ */
+static CURLcode smtp_parse_custom_request(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct SMTP *smtp = data->req.protop;
+ const char *custom = data->set.str[STRING_CUSTOMREQUEST];
+
+ /* URL decode the custom request */
+ if(custom)
+ result = Curl_urldecode(data, custom, 0, &smtp->custom, NULL, TRUE);
+
+ return result;
+}
+
+CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread)
+{
+ /* When sending a SMTP payload we must detect CRLF. sequences making sure
+ they are sent as CRLF.. instead, as a . on the beginning of a line will
+ be deleted by the server when not part of an EOB terminator and a
+ genuine CRLF.CRLF which isn't escaped will wrongly be detected as end of
+ data by the server
+ */
+ ssize_t i;
+ ssize_t si;
+ struct SessionHandle *data = conn->data;
+ struct SMTP *smtp = data->req.protop;
+ char *scratch = data->state.scratch;
+ char *newscratch = NULL;
+ char *oldscratch = NULL;
+ size_t eob_sent;
+
+ /* Do we need to allocate a scratch buffer? */
+ if(!scratch || data->set.crlf) {
+ oldscratch = scratch;
+
+ scratch = newscratch = malloc(2 * BUFSIZE);
+ if(!newscratch) {
+ failf(data, "Failed to alloc scratch buffer!");
+
+ return CURLE_OUT_OF_MEMORY;
+ }
+ }
+
+ /* Have we already sent part of the EOB? */
+ eob_sent = smtp->eob;
+
+ /* This loop can be improved by some kind of Boyer-Moore style of
+ approach but that is saved for later... */
+ for(i = 0, si = 0; i < nread; i++) {
+ if(SMTP_EOB[smtp->eob] == data->req.upload_fromhere[i]) {
+ smtp->eob++;
+
+ /* Is the EOB potentially the terminating CRLF? */
+ if(2 == smtp->eob || SMTP_EOB_LEN == smtp->eob)
+ smtp->trailing_crlf = TRUE;
+ else
+ smtp->trailing_crlf = FALSE;
+ }
+ else if(smtp->eob) {
+ /* A previous substring matched so output that first */
+ memcpy(&scratch[si], &SMTP_EOB[eob_sent], smtp->eob - eob_sent);
+ si += smtp->eob - eob_sent;
+
+ /* Then compare the first byte */
+ if(SMTP_EOB[0] == data->req.upload_fromhere[i])
+ smtp->eob = 1;
+ else
+ smtp->eob = 0;
+
+ eob_sent = 0;
+
+ /* Reset the trailing CRLF flag as there was more data */
+ smtp->trailing_crlf = FALSE;
+ }
+
+ /* Do we have a match for CRLF. as per RFC-5321, sect. 4.5.2 */
+ if(SMTP_EOB_FIND_LEN == smtp->eob) {
+ /* Copy the replacement data to the target buffer */
+ memcpy(&scratch[si], &SMTP_EOB_REPL[eob_sent],
+ SMTP_EOB_REPL_LEN - eob_sent);
+ si += SMTP_EOB_REPL_LEN - eob_sent;
+ smtp->eob = 0;
+ eob_sent = 0;
+ }
+ else if(!smtp->eob)
+ scratch[si++] = data->req.upload_fromhere[i];
+ }
+
+ if(smtp->eob - eob_sent) {
+ /* A substring matched before processing ended so output that now */
+ memcpy(&scratch[si], &SMTP_EOB[eob_sent], smtp->eob - eob_sent);
+ si += smtp->eob - eob_sent;
+ }
+
+ /* Only use the new buffer if we replaced something */
+ if(si != nread) {
+ /* Upload from the new (replaced) buffer instead */
+ data->req.upload_fromhere = scratch;
+
+ /* Save the buffer so it can be freed later */
+ data->state.scratch = scratch;
+
+ /* Free the old scratch buffer */
+ free(oldscratch);
+
+ /* Set the new amount too */
+ data->req.upload_present = si;
+ }
+ else
+ free(newscratch);
+
+ return CURLE_OK;
+}
+
+#endif /* CURL_DISABLE_SMTP */
diff --git a/Utilities/cmcurl/lib/smtp.h b/Utilities/cmcurl/lib/smtp.h
new file mode 100644
index 000000000..9fbe0c5bf
--- /dev/null
+++ b/Utilities/cmcurl/lib/smtp.h
@@ -0,0 +1,91 @@
+#ifndef HEADER_CURL_SMTP_H
+#define HEADER_CURL_SMTP_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2009 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "pingpong.h"
+#include "curl_sasl.h"
+
+/****************************************************************************
+ * SMTP unique setup
+ ***************************************************************************/
+typedef enum {
+ SMTP_STOP, /* do nothing state, stops the state machine */
+ SMTP_SERVERGREET, /* waiting for the initial greeting immediately after
+ a connect */
+ SMTP_EHLO,
+ SMTP_HELO,
+ SMTP_STARTTLS,
+ SMTP_UPGRADETLS, /* asynchronously upgrade the connection to SSL/TLS
+ (multi mode only) */
+ SMTP_AUTH,
+ SMTP_COMMAND, /* VRFY, EXPN, NOOP, RSET and HELP */
+ SMTP_MAIL, /* MAIL FROM */
+ SMTP_RCPT, /* RCPT TO */
+ SMTP_DATA,
+ SMTP_POSTDATA,
+ SMTP_QUIT,
+ SMTP_LAST /* never used */
+} smtpstate;
+
+/* This SMTP struct is used in the SessionHandle. All SMTP data that is
+ connection-oriented must be in smtp_conn to properly deal with the fact that
+ perhaps the SessionHandle is changed between the times the connection is
+ used. */
+struct SMTP {
+ curl_pp_transfer transfer;
+ char *custom; /* Custom Request */
+ struct curl_slist *rcpt; /* Recipient list */
+ size_t eob; /* Number of bytes of the EOB (End Of Body) that
+ have been received so far */
+ bool trailing_crlf; /* Specifies if the tailing CRLF is present */
+};
+
+/* smtp_conn is used for struct connection-oriented data in the connectdata
+ struct */
+struct smtp_conn {
+ struct pingpong pp;
+ smtpstate state; /* Always use smtp.c:state() to change state! */
+ bool ssldone; /* Is connect() over SSL done? */
+ char *domain; /* Client address/name to send in the EHLO */
+ struct SASL sasl; /* SASL-related storage */
+ bool tls_supported; /* StartTLS capability supported by server */
+ bool size_supported; /* If server supports SIZE extension according to
+ RFC 1870 */
+ bool auth_supported; /* AUTH capability supported by server */
+};
+
+extern const struct Curl_handler Curl_handler_smtp;
+extern const struct Curl_handler Curl_handler_smtps;
+
+/* this is the 5-bytes End-Of-Body marker for SMTP */
+#define SMTP_EOB "\x0d\x0a\x2e\x0d\x0a"
+#define SMTP_EOB_LEN 5
+#define SMTP_EOB_FIND_LEN 3
+
+/* if found in data, replace it with this string instead */
+#define SMTP_EOB_REPL "\x0d\x0a\x2e\x2e"
+#define SMTP_EOB_REPL_LEN 4
+
+CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread);
+
+#endif /* HEADER_CURL_SMTP_H */
diff --git a/Utilities/cmcurl/lib/sockaddr.h b/Utilities/cmcurl/lib/sockaddr.h
new file mode 100644
index 000000000..6a2151c9d
--- /dev/null
+++ b/Utilities/cmcurl/lib/sockaddr.h
@@ -0,0 +1,43 @@
+#ifndef HEADER_CURL_SOCKADDR_H
+#define HEADER_CURL_SOCKADDR_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+struct Curl_sockaddr_storage {
+ union {
+ struct sockaddr sa;
+ struct sockaddr_in sa_in;
+#ifdef ENABLE_IPV6
+ struct sockaddr_in6 sa_in6;
+#endif
+#ifdef HAVE_STRUCT_SOCKADDR_STORAGE
+ struct sockaddr_storage sa_stor;
+#else
+ char cbuf[256]; /* this should be big enough to fit a lot */
+#endif
+ } buffer;
+};
+
+#endif /* HEADER_CURL_SOCKADDR_H */
+
diff --git a/Utilities/cmcurl/lib/socks.c b/Utilities/cmcurl/lib/socks.c
new file mode 100644
index 000000000..7d3f782b4
--- /dev/null
+++ b/Utilities/cmcurl/lib/socks.c
@@ -0,0 +1,755 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_PROXY)
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "strequal.h"
+#include "select.h"
+#include "connect.h"
+#include "timeval.h"
+#include "socks.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ * Helper read-from-socket functions. Does the same as Curl_read() but it
+ * blocks until all bytes amount of buffersize will be read. No more, no less.
+ *
+ * This is STUPID BLOCKING behaviour which we frown upon, but right now this
+ * is what we have...
+ */
+int Curl_blockread_all(struct connectdata *conn, /* connection data */
+ curl_socket_t sockfd, /* read from this socket */
+ char *buf, /* store read data here */
+ ssize_t buffersize, /* max amount to read */
+ ssize_t *n) /* amount bytes read */
+{
+ ssize_t nread;
+ ssize_t allread = 0;
+ int result;
+ long timeleft;
+ *n = 0;
+ for(;;) {
+ timeleft = Curl_timeleft(conn->data, NULL, TRUE);
+ if(timeleft < 0) {
+ /* we already got the timeout */
+ result = CURLE_OPERATION_TIMEDOUT;
+ break;
+ }
+ if(Curl_socket_ready(sockfd, CURL_SOCKET_BAD, timeleft) <= 0) {
+ result = ~CURLE_OK;
+ break;
+ }
+ result = Curl_read_plain(sockfd, buf, buffersize, &nread);
+ if(CURLE_AGAIN == result)
+ continue;
+ else if(result)
+ break;
+
+ if(buffersize == nread) {
+ allread += nread;
+ *n = allread;
+ result = CURLE_OK;
+ break;
+ }
+ if(!nread) {
+ result = ~CURLE_OK;
+ break;
+ }
+
+ buffersize -= nread;
+ buf += nread;
+ allread += nread;
+ }
+ return result;
+}
+
+/*
+* This function logs in to a SOCKS4 proxy and sends the specifics to the final
+* destination server.
+*
+* Reference :
+* http://socks.permeo.com/protocol/socks4.protocol
+*
+* Note :
+* Set protocol4a=true for "SOCKS 4A (Simple Extension to SOCKS 4 Protocol)"
+* Nonsupport "Identification Protocol (RFC1413)"
+*/
+CURLcode Curl_SOCKS4(const char *proxy_name,
+ const char *hostname,
+ int remote_port,
+ int sockindex,
+ struct connectdata *conn,
+ bool protocol4a)
+{
+#define SOCKS4REQLEN 262
+ unsigned char socksreq[SOCKS4REQLEN]; /* room for SOCKS4 request incl. user
+ id */
+ int result;
+ CURLcode code;
+ curl_socket_t sock = conn->sock[sockindex];
+ struct SessionHandle *data = conn->data;
+
+ if(Curl_timeleft(data, NULL, TRUE) < 0) {
+ /* time-out, bail out, go home */
+ failf(data, "Connection time-out");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+
+ (void)curlx_nonblock(sock, FALSE);
+
+ infof(data, "SOCKS4 communication to %s:%d\n", hostname, remote_port);
+
+ /*
+ * Compose socks4 request
+ *
+ * Request format
+ *
+ * +----+----+----+----+----+----+----+----+----+----+....+----+
+ * | VN | CD | DSTPORT | DSTIP | USERID |NULL|
+ * +----+----+----+----+----+----+----+----+----+----+....+----+
+ * # of bytes: 1 1 2 4 variable 1
+ */
+
+ socksreq[0] = 4; /* version (SOCKS4) */
+ socksreq[1] = 1; /* connect */
+ socksreq[2] = (unsigned char)((remote_port >> 8) & 0xff); /* PORT MSB */
+ socksreq[3] = (unsigned char)(remote_port & 0xff); /* PORT LSB */
+
+ /* DNS resolve only for SOCKS4, not SOCKS4a */
+ if(!protocol4a) {
+ struct Curl_dns_entry *dns;
+ Curl_addrinfo *hp=NULL;
+ int rc;
+
+ rc = Curl_resolv(conn, hostname, remote_port, &dns);
+
+ if(rc == CURLRESOLV_ERROR)
+ return CURLE_COULDNT_RESOLVE_PROXY;
+
+ if(rc == CURLRESOLV_PENDING)
+ /* ignores the return code, but 'dns' remains NULL on failure */
+ (void)Curl_resolver_wait_resolv(conn, &dns);
+
+ /*
+ * We cannot use 'hostent' as a struct that Curl_resolv() returns. It
+ * returns a Curl_addrinfo pointer that may not always look the same.
+ */
+ if(dns)
+ hp=dns->addr;
+ if(hp) {
+ char buf[64];
+ unsigned short ip[4];
+ Curl_printable_address(hp, buf, sizeof(buf));
+
+ if(4 == sscanf( buf, "%hu.%hu.%hu.%hu",
+ &ip[0], &ip[1], &ip[2], &ip[3])) {
+ /* Set DSTIP */
+ socksreq[4] = (unsigned char)ip[0];
+ socksreq[5] = (unsigned char)ip[1];
+ socksreq[6] = (unsigned char)ip[2];
+ socksreq[7] = (unsigned char)ip[3];
+ }
+ else
+ hp = NULL; /* fail! */
+
+ infof(data, "SOCKS4 connect to %s (locally resolved)\n", buf);
+
+ Curl_resolv_unlock(data, dns); /* not used anymore from now on */
+
+ }
+ if(!hp) {
+ failf(data, "Failed to resolve \"%s\" for SOCKS4 connect.",
+ hostname);
+ return CURLE_COULDNT_RESOLVE_HOST;
+ }
+ }
+
+ /*
+ * This is currently not supporting "Identification Protocol (RFC1413)".
+ */
+ socksreq[8] = 0; /* ensure empty userid is NUL-terminated */
+ if(proxy_name) {
+ size_t plen = strlen(proxy_name);
+ if(plen >= sizeof(socksreq) - 8) {
+ failf(data, "Too long SOCKS proxy name, can't use!\n");
+ return CURLE_COULDNT_CONNECT;
+ }
+ /* copy the proxy name WITH trailing zero */
+ memcpy(socksreq + 8, proxy_name, plen+1);
+ }
+
+ /*
+ * Make connection
+ */
+ {
+ ssize_t actualread;
+ ssize_t written;
+ ssize_t hostnamelen = 0;
+ int packetsize = 9 +
+ (int)strlen((char*)socksreq + 8); /* size including NUL */
+
+ /* If SOCKS4a, set special invalid IP address 0.0.0.x */
+ if(protocol4a) {
+ socksreq[4] = 0;
+ socksreq[5] = 0;
+ socksreq[6] = 0;
+ socksreq[7] = 1;
+ /* If still enough room in buffer, also append hostname */
+ hostnamelen = (ssize_t)strlen(hostname) + 1; /* length including NUL */
+ if(packetsize + hostnamelen <= SOCKS4REQLEN)
+ strcpy((char*)socksreq + packetsize, hostname);
+ else
+ hostnamelen = 0; /* Flag: hostname did not fit in buffer */
+ }
+
+ /* Send request */
+ code = Curl_write_plain(conn, sock, (char *)socksreq,
+ packetsize + hostnamelen,
+ &written);
+ if(code || (written != packetsize + hostnamelen)) {
+ failf(data, "Failed to send SOCKS4 connect request.");
+ return CURLE_COULDNT_CONNECT;
+ }
+ if(protocol4a && hostnamelen == 0) {
+ /* SOCKS4a with very long hostname - send that name separately */
+ hostnamelen = (ssize_t)strlen(hostname) + 1;
+ code = Curl_write_plain(conn, sock, (char *)hostname, hostnamelen,
+ &written);
+ if(code || (written != hostnamelen)) {
+ failf(data, "Failed to send SOCKS4 connect request.");
+ return CURLE_COULDNT_CONNECT;
+ }
+ }
+
+ packetsize = 8; /* receive data size */
+
+ /* Receive response */
+ result = Curl_blockread_all(conn, sock, (char *)socksreq, packetsize,
+ &actualread);
+ if(result || (actualread != packetsize)) {
+ failf(data, "Failed to receive SOCKS4 connect request ack.");
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ /*
+ * Response format
+ *
+ * +----+----+----+----+----+----+----+----+
+ * | VN | CD | DSTPORT | DSTIP |
+ * +----+----+----+----+----+----+----+----+
+ * # of bytes: 1 1 2 4
+ *
+ * VN is the version of the reply code and should be 0. CD is the result
+ * code with one of the following values:
+ *
+ * 90: request granted
+ * 91: request rejected or failed
+ * 92: request rejected because SOCKS server cannot connect to
+ * identd on the client
+ * 93: request rejected because the client program and identd
+ * report different user-ids
+ */
+
+ /* wrong version ? */
+ if(socksreq[0] != 0) {
+ failf(data,
+ "SOCKS4 reply has wrong version, version should be 4.");
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ /* Result */
+ switch(socksreq[1]) {
+ case 90:
+ infof(data, "SOCKS4%s request granted.\n", protocol4a?"a":"");
+ break;
+ case 91:
+ failf(data,
+ "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
+ ", request rejected or failed.",
+ (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+ (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+ ((socksreq[8] << 8) | socksreq[9]),
+ socksreq[1]);
+ return CURLE_COULDNT_CONNECT;
+ case 92:
+ failf(data,
+ "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
+ ", request rejected because SOCKS server cannot connect to "
+ "identd on the client.",
+ (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+ (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+ ((socksreq[8] << 8) | socksreq[9]),
+ socksreq[1]);
+ return CURLE_COULDNT_CONNECT;
+ case 93:
+ failf(data,
+ "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
+ ", request rejected because the client program and identd "
+ "report different user-ids.",
+ (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+ (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+ ((socksreq[8] << 8) | socksreq[9]),
+ socksreq[1]);
+ return CURLE_COULDNT_CONNECT;
+ default:
+ failf(data,
+ "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
+ ", Unknown.",
+ (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+ (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+ ((socksreq[8] << 8) | socksreq[9]),
+ socksreq[1]);
+ return CURLE_COULDNT_CONNECT;
+ }
+ }
+
+ (void)curlx_nonblock(sock, TRUE);
+
+ return CURLE_OK; /* Proxy was successful! */
+}
+
+/*
+ * This function logs in to a SOCKS5 proxy and sends the specifics to the final
+ * destination server.
+ */
+CURLcode Curl_SOCKS5(const char *proxy_name,
+ const char *proxy_password,
+ const char *hostname,
+ int remote_port,
+ int sockindex,
+ struct connectdata *conn)
+{
+ /*
+ According to the RFC1928, section "6. Replies". This is what a SOCK5
+ replies:
+
+ +----+-----+-------+------+----------+----------+
+ |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
+ +----+-----+-------+------+----------+----------+
+ | 1 | 1 | X'00' | 1 | Variable | 2 |
+ +----+-----+-------+------+----------+----------+
+
+ Where:
+
+ o VER protocol version: X'05'
+ o REP Reply field:
+ o X'00' succeeded
+ */
+
+ unsigned char socksreq[600]; /* room for large user/pw (255 max each) */
+ ssize_t actualread;
+ ssize_t written;
+ int result;
+ CURLcode code;
+ curl_socket_t sock = conn->sock[sockindex];
+ struct SessionHandle *data = conn->data;
+ long timeout;
+ bool socks5_resolve_local = (conn->proxytype == CURLPROXY_SOCKS5)?TRUE:FALSE;
+ const size_t hostname_len = strlen(hostname);
+ ssize_t len = 0;
+
+ /* RFC1928 chapter 5 specifies max 255 chars for domain name in packet */
+ if(!socks5_resolve_local && hostname_len > 255) {
+ infof(conn->data, "SOCKS5: server resolving disabled for hostnames of "
+ "length > 255 [actual len=%zu]\n", hostname_len);
+ socks5_resolve_local = TRUE;
+ }
+
+ /* get timeout */
+ timeout = Curl_timeleft(data, NULL, TRUE);
+
+ if(timeout < 0) {
+ /* time-out, bail out, go home */
+ failf(data, "Connection time-out");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+
+ (void)curlx_nonblock(sock, TRUE);
+
+ /* wait until socket gets connected */
+ result = Curl_socket_ready(CURL_SOCKET_BAD, sock, timeout);
+
+ if(-1 == result) {
+ failf(conn->data, "SOCKS5: no connection here");
+ return CURLE_COULDNT_CONNECT;
+ }
+ else if(0 == result) {
+ failf(conn->data, "SOCKS5: connection timeout");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+
+ if(result & CURL_CSELECT_ERR) {
+ failf(conn->data, "SOCKS5: error occurred during connection");
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ socksreq[0] = 5; /* version */
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+ socksreq[1] = (char)(proxy_name ? 3 : 2); /* number of methods (below) */
+ socksreq[2] = 0; /* no authentication */
+ socksreq[3] = 1; /* GSS-API */
+ socksreq[4] = 2; /* username/password */
+#else
+ socksreq[1] = (char)(proxy_name ? 2 : 1); /* number of methods (below) */
+ socksreq[2] = 0; /* no authentication */
+ socksreq[3] = 2; /* username/password */
+#endif
+
+ (void)curlx_nonblock(sock, FALSE);
+
+ code = Curl_write_plain(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]),
+ &written);
+ if(code || (written != (2 + (int)socksreq[1]))) {
+ failf(data, "Unable to send initial SOCKS5 request.");
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ (void)curlx_nonblock(sock, TRUE);
+
+ result = Curl_socket_ready(sock, CURL_SOCKET_BAD, timeout);
+
+ if(-1 == result) {
+ failf(conn->data, "SOCKS5 nothing to read");
+ return CURLE_COULDNT_CONNECT;
+ }
+ else if(0 == result) {
+ failf(conn->data, "SOCKS5 read timeout");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+
+ if(result & CURL_CSELECT_ERR) {
+ failf(conn->data, "SOCKS5 read error occurred");
+ return CURLE_RECV_ERROR;
+ }
+
+ (void)curlx_nonblock(sock, FALSE);
+
+ result=Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread);
+ if(result || (actualread != 2)) {
+ failf(data, "Unable to receive initial SOCKS5 response.");
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ if(socksreq[0] != 5) {
+ failf(data, "Received invalid version in initial SOCKS5 response.");
+ return CURLE_COULDNT_CONNECT;
+ }
+ if(socksreq[1] == 0) {
+ /* Nothing to do, no authentication needed */
+ ;
+ }
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+ else if(socksreq[1] == 1) {
+ code = Curl_SOCKS5_gssapi_negotiate(sockindex, conn);
+ if(code) {
+ failf(data, "Unable to negotiate SOCKS5 GSS-API context.");
+ return CURLE_COULDNT_CONNECT;
+ }
+ }
+#endif
+ else if(socksreq[1] == 2) {
+ /* Needs user name and password */
+ size_t proxy_name_len, proxy_password_len;
+ if(proxy_name && proxy_password) {
+ proxy_name_len = strlen(proxy_name);
+ proxy_password_len = strlen(proxy_password);
+ }
+ else {
+ proxy_name_len = 0;
+ proxy_password_len = 0;
+ }
+
+ /* username/password request looks like
+ * +----+------+----------+------+----------+
+ * |VER | ULEN | UNAME | PLEN | PASSWD |
+ * +----+------+----------+------+----------+
+ * | 1 | 1 | 1 to 255 | 1 | 1 to 255 |
+ * +----+------+----------+------+----------+
+ */
+ len = 0;
+ socksreq[len++] = 1; /* username/pw subnegotiation version */
+ socksreq[len++] = (unsigned char) proxy_name_len;
+ if(proxy_name && proxy_name_len)
+ memcpy(socksreq + len, proxy_name, proxy_name_len);
+ len += proxy_name_len;
+ socksreq[len++] = (unsigned char) proxy_password_len;
+ if(proxy_password && proxy_password_len)
+ memcpy(socksreq + len, proxy_password, proxy_password_len);
+ len += proxy_password_len;
+
+ code = Curl_write_plain(conn, sock, (char *)socksreq, len, &written);
+ if(code || (len != written)) {
+ failf(data, "Failed to send SOCKS5 sub-negotiation request.");
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ result=Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread);
+ if(result || (actualread != 2)) {
+ failf(data, "Unable to receive SOCKS5 sub-negotiation response.");
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ /* ignore the first (VER) byte */
+ if(socksreq[1] != 0) { /* status */
+ failf(data, "User was rejected by the SOCKS5 server (%d %d).",
+ socksreq[0], socksreq[1]);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ /* Everything is good so far, user was authenticated! */
+ }
+ else {
+ /* error */
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+ if(socksreq[1] == 255) {
+#else
+ if(socksreq[1] == 1) {
+ failf(data,
+ "SOCKS5 GSSAPI per-message authentication is not supported.");
+ return CURLE_COULDNT_CONNECT;
+ }
+ else if(socksreq[1] == 255) {
+#endif
+ if(!proxy_name || !*proxy_name) {
+ failf(data,
+ "No authentication method was acceptable. (It is quite likely"
+ " that the SOCKS5 server wanted a username/password, since none"
+ " was supplied to the server on this connection.)");
+ }
+ else {
+ failf(data, "No authentication method was acceptable.");
+ }
+ return CURLE_COULDNT_CONNECT;
+ }
+ else {
+ failf(data,
+ "Undocumented SOCKS5 mode attempted to be used by server.");
+ return CURLE_COULDNT_CONNECT;
+ }
+ }
+
+ /* Authentication is complete, now specify destination to the proxy */
+ len = 0;
+ socksreq[len++] = 5; /* version (SOCKS5) */
+ socksreq[len++] = 1; /* connect */
+ socksreq[len++] = 0; /* must be zero */
+
+ if(!socks5_resolve_local) {
+ socksreq[len++] = 3; /* ATYP: domain name = 3 */
+ socksreq[len++] = (char) hostname_len; /* address length */
+ memcpy(&socksreq[len], hostname, hostname_len); /* address str w/o NULL */
+ len += hostname_len;
+ }
+ else {
+ struct Curl_dns_entry *dns;
+ Curl_addrinfo *hp = NULL;
+ int rc = Curl_resolv(conn, hostname, remote_port, &dns);
+
+ if(rc == CURLRESOLV_ERROR)
+ return CURLE_COULDNT_RESOLVE_HOST;
+
+ if(rc == CURLRESOLV_PENDING) {
+ /* this requires that we're in "wait for resolve" state */
+ code = Curl_resolver_wait_resolv(conn, &dns);
+ if(code)
+ return code;
+ }
+
+ /*
+ * We cannot use 'hostent' as a struct that Curl_resolv() returns. It
+ * returns a Curl_addrinfo pointer that may not always look the same.
+ */
+ if(dns)
+ hp=dns->addr;
+ if(hp) {
+ struct sockaddr_in *saddr_in;
+#ifdef ENABLE_IPV6
+ struct sockaddr_in6 *saddr_in6;
+#endif
+ int i;
+
+ if(hp->ai_family == AF_INET) {
+ socksreq[len++] = 1; /* ATYP: IPv4 = 1 */
+
+ saddr_in = (struct sockaddr_in*)hp->ai_addr;
+ for(i = 0; i < 4; i++) {
+ socksreq[len++] = ((unsigned char*)&saddr_in->sin_addr.s_addr)[i];
+ infof(data, "%d\n", socksreq[len-1]);
+ }
+ }
+#ifdef ENABLE_IPV6
+ else if(hp->ai_family == AF_INET6) {
+ socksreq[len++] = 4; /* ATYP: IPv6 = 4 */
+
+ saddr_in6 = (struct sockaddr_in6*)hp->ai_addr;
+ for(i = 0; i < 16; i++) {
+ socksreq[len++] = ((unsigned char*)&saddr_in6->sin6_addr.s6_addr)[i];
+ }
+ }
+#endif
+ else
+ hp = NULL; /* fail! */
+
+ Curl_resolv_unlock(data, dns); /* not used anymore from now on */
+ }
+ if(!hp) {
+ failf(data, "Failed to resolve \"%s\" for SOCKS5 connect.",
+ hostname);
+ return CURLE_COULDNT_RESOLVE_HOST;
+ }
+ }
+
+ socksreq[len++] = (unsigned char)((remote_port >> 8) & 0xff); /* PORT MSB */
+ socksreq[len++] = (unsigned char)(remote_port & 0xff); /* PORT LSB */
+
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+ if(conn->socks5_gssapi_enctype) {
+ failf(data, "SOCKS5 GSS-API protection not yet implemented.");
+ }
+ else
+#endif
+ code = Curl_write_plain(conn, sock, (char *)socksreq, len, &written);
+
+ if(code || (len != written)) {
+ failf(data, "Failed to send SOCKS5 connect request.");
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ len = 10; /* minimum packet size is 10 */
+
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+ if(conn->socks5_gssapi_enctype) {
+ failf(data, "SOCKS5 GSS-API protection not yet implemented.");
+ }
+ else
+#endif
+ result = Curl_blockread_all(conn, sock, (char *)socksreq,
+ len, &actualread);
+
+ if(result || (len != actualread)) {
+ failf(data, "Failed to receive SOCKS5 connect request ack.");
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ if(socksreq[0] != 5) { /* version */
+ failf(data,
+ "SOCKS5 reply has wrong version, version should be 5.");
+ return CURLE_COULDNT_CONNECT;
+ }
+ if(socksreq[1] != 0) { /* Anything besides 0 is an error */
+ if(socksreq[3] == 1) {
+ failf(data,
+ "Can't complete SOCKS5 connection to %d.%d.%d.%d:%d. (%d)",
+ (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+ (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+ ((socksreq[8] << 8) | socksreq[9]),
+ socksreq[1]);
+ }
+ else if(socksreq[3] == 3) {
+ failf(data,
+ "Can't complete SOCKS5 connection to %s:%d. (%d)",
+ hostname,
+ ((socksreq[8] << 8) | socksreq[9]),
+ socksreq[1]);
+ }
+ else if(socksreq[3] == 4) {
+ failf(data,
+ "Can't complete SOCKS5 connection to %02x%02x:%02x%02x:"
+ "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%d. (%d)",
+ (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+ (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+ (unsigned char)socksreq[8], (unsigned char)socksreq[9],
+ (unsigned char)socksreq[10], (unsigned char)socksreq[11],
+ (unsigned char)socksreq[12], (unsigned char)socksreq[13],
+ (unsigned char)socksreq[14], (unsigned char)socksreq[15],
+ (unsigned char)socksreq[16], (unsigned char)socksreq[17],
+ (unsigned char)socksreq[18], (unsigned char)socksreq[19],
+ ((socksreq[8] << 8) | socksreq[9]),
+ socksreq[1]);
+ }
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ /* Fix: in general, returned BND.ADDR is variable length parameter by RFC
+ 1928, so the reply packet should be read until the end to avoid errors at
+ subsequent protocol level.
+
+ +----+-----+-------+------+----------+----------+
+ |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
+ +----+-----+-------+------+----------+----------+
+ | 1 | 1 | X'00' | 1 | Variable | 2 |
+ +----+-----+-------+------+----------+----------+
+
+ ATYP:
+ o IP v4 address: X'01', BND.ADDR = 4 byte
+ o domain name: X'03', BND.ADDR = [ 1 byte length, string ]
+ o IP v6 address: X'04', BND.ADDR = 16 byte
+ */
+
+ /* Calculate real packet size */
+ if(socksreq[3] == 3) {
+ /* domain name */
+ int addrlen = (int) socksreq[4];
+ len = 5 + addrlen + 2;
+ }
+ else if(socksreq[3] == 4) {
+ /* IPv6 */
+ len = 4 + 16 + 2;
+ }
+
+ /* At this point we already read first 10 bytes */
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+ if(!conn->socks5_gssapi_enctype) {
+ /* decrypt_gssapi_blockread already read the whole packet */
+#endif
+ if(len > 10) {
+ len -= 10;
+ result = Curl_blockread_all(conn, sock, (char *)&socksreq[10],
+ len, &actualread);
+ if(result || (len != actualread)) {
+ failf(data, "Failed to receive SOCKS5 connect request ack.");
+ return CURLE_COULDNT_CONNECT;
+ }
+ }
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+ }
+#endif
+
+ (void)curlx_nonblock(sock, TRUE);
+ return CURLE_OK; /* Proxy was successful! */
+}
+
+#endif /* CURL_DISABLE_PROXY */
+
diff --git a/Utilities/cmcurl/lib/socks.h b/Utilities/cmcurl/lib/socks.h
new file mode 100644
index 000000000..29e3bf03f
--- /dev/null
+++ b/Utilities/cmcurl/lib/socks.h
@@ -0,0 +1,77 @@
+#ifndef HEADER_CURL_SOCKS_H
+#define HEADER_CURL_SOCKS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef CURL_DISABLE_PROXY
+#define Curl_SOCKS4(a,b,c,d,e,f) CURLE_NOT_BUILT_IN
+#define Curl_SOCKS5(a,b,c,d,e,f) CURLE_NOT_BUILT_IN
+#else
+/*
+ * Helper read-from-socket functions. Does the same as Curl_read() but it
+ * blocks until all bytes amount of buffersize will be read. No more, no less.
+ *
+ * This is STUPID BLOCKING behaviour which we frown upon, but right now this
+ * is what we have...
+ */
+int Curl_blockread_all(struct connectdata *conn,
+ curl_socket_t sockfd,
+ char *buf,
+ ssize_t buffersize,
+ ssize_t *n);
+
+/*
+ * This function logs in to a SOCKS4(a) proxy and sends the specifics to the
+ * final destination server.
+ */
+CURLcode Curl_SOCKS4(const char *proxy_name,
+ const char *hostname,
+ int remote_port,
+ int sockindex,
+ struct connectdata *conn,
+ bool protocol4a);
+
+/*
+ * This function logs in to a SOCKS5 proxy and sends the specifics to the
+ * final destination server.
+ */
+CURLcode Curl_SOCKS5(const char *proxy_name,
+ const char *proxy_password,
+ const char *hostname,
+ int remote_port,
+ int sockindex,
+ struct connectdata *conn);
+
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+/*
+ * This function handles the SOCKS5 GSS-API negotiation and initialisation
+ */
+CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
+ struct connectdata *conn);
+#endif
+
+#endif /* CURL_DISABLE_PROXY */
+
+#endif /* HEADER_CURL_SOCKS_H */
+
diff --git a/Utilities/cmcurl/lib/socks_gssapi.c b/Utilities/cmcurl/lib/socks_gssapi.c
new file mode 100644
index 000000000..8e575c279
--- /dev/null
+++ b/Utilities/cmcurl/lib/socks_gssapi.c
@@ -0,0 +1,522 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2009, 2011, Markus Moeller, <markus_moeller@compuserve.com>
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(HAVE_GSSAPI) && !defined(CURL_DISABLE_PROXY)
+
+#include "curl_gssapi.h"
+#include "urldata.h"
+#include "sendf.h"
+#include "connect.h"
+#include "timeval.h"
+#include "socks.h"
+#include "warnless.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+static gss_ctx_id_t gss_context = GSS_C_NO_CONTEXT;
+
+/*
+ * Helper GSS-API error functions.
+ */
+static int check_gss_err(struct SessionHandle *data,
+ OM_uint32 major_status,
+ OM_uint32 minor_status,
+ const char* function)
+{
+ if(GSS_ERROR(major_status)) {
+ OM_uint32 maj_stat, min_stat;
+ OM_uint32 msg_ctx = 0;
+ gss_buffer_desc status_string;
+ char buf[1024];
+ size_t len;
+
+ len = 0;
+ msg_ctx = 0;
+ while(!msg_ctx) {
+ /* convert major status code (GSS-API error) to text */
+ maj_stat = gss_display_status(&min_stat, major_status,
+ GSS_C_GSS_CODE,
+ GSS_C_NULL_OID,
+ &msg_ctx, &status_string);
+ if(maj_stat == GSS_S_COMPLETE) {
+ if(sizeof(buf) > len + status_string.length + 1) {
+ strcpy(buf+len, (char*) status_string.value);
+ len += status_string.length;
+ }
+ gss_release_buffer(&min_stat, &status_string);
+ break;
+ }
+ gss_release_buffer(&min_stat, &status_string);
+ }
+ if(sizeof(buf) > len + 3) {
+ strcpy(buf+len, ".\n");
+ len += 2;
+ }
+ msg_ctx = 0;
+ while(!msg_ctx) {
+ /* convert minor status code (underlying routine error) to text */
+ maj_stat = gss_display_status(&min_stat, minor_status,
+ GSS_C_MECH_CODE,
+ GSS_C_NULL_OID,
+ &msg_ctx, &status_string);
+ if(maj_stat == GSS_S_COMPLETE) {
+ if(sizeof(buf) > len + status_string.length)
+ strcpy(buf+len, (char*) status_string.value);
+ gss_release_buffer(&min_stat, &status_string);
+ break;
+ }
+ gss_release_buffer(&min_stat, &status_string);
+ }
+ failf(data, "GSS-API error: %s failed:\n%s", function, buf);
+ return 1;
+ }
+
+ return 0;
+}
+
+CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
+ struct connectdata *conn)
+{
+ struct SessionHandle *data = conn->data;
+ curl_socket_t sock = conn->sock[sockindex];
+ CURLcode code;
+ ssize_t actualread;
+ ssize_t written;
+ int result;
+ OM_uint32 gss_major_status, gss_minor_status, gss_status;
+ OM_uint32 gss_ret_flags;
+ int gss_conf_state, gss_enc;
+ gss_buffer_desc service = GSS_C_EMPTY_BUFFER;
+ gss_buffer_desc gss_send_token = GSS_C_EMPTY_BUFFER;
+ gss_buffer_desc gss_recv_token = GSS_C_EMPTY_BUFFER;
+ gss_buffer_desc gss_w_token = GSS_C_EMPTY_BUFFER;
+ gss_buffer_desc* gss_token = GSS_C_NO_BUFFER;
+ gss_name_t server = GSS_C_NO_NAME;
+ gss_name_t gss_client_name = GSS_C_NO_NAME;
+ unsigned short us_length;
+ char *user=NULL;
+ unsigned char socksreq[4]; /* room for GSS-API exchange header only */
+ char *serviceptr = data->set.str[STRING_SOCKS5_GSSAPI_SERVICE];
+
+ /* GSS-API request looks like
+ * +----+------+-----+----------------+
+ * |VER | MTYP | LEN | TOKEN |
+ * +----+------+----------------------+
+ * | 1 | 1 | 2 | up to 2^16 - 1 |
+ * +----+------+-----+----------------+
+ */
+
+ /* prepare service name */
+ if(strchr(serviceptr, '/')) {
+ service.value = malloc(strlen(serviceptr));
+ if(!service.value)
+ return CURLE_OUT_OF_MEMORY;
+ service.length = strlen(serviceptr);
+ memcpy(service.value, serviceptr, service.length);
+
+ gss_major_status = gss_import_name(&gss_minor_status, &service,
+ (gss_OID) GSS_C_NULL_OID, &server);
+ }
+ else {
+ service.value = malloc(strlen(serviceptr) +strlen(conn->proxy.name)+2);
+ if(!service.value)
+ return CURLE_OUT_OF_MEMORY;
+ service.length = strlen(serviceptr) +strlen(conn->proxy.name)+1;
+ snprintf(service.value, service.length+1, "%s@%s",
+ serviceptr, conn->proxy.name);
+
+ gss_major_status = gss_import_name(&gss_minor_status, &service,
+ GSS_C_NT_HOSTBASED_SERVICE, &server);
+ }
+
+ gss_release_buffer(&gss_status, &service); /* clear allocated memory */
+
+ if(check_gss_err(data, gss_major_status,
+ gss_minor_status, "gss_import_name()")) {
+ failf(data, "Failed to create service name.");
+ gss_release_name(&gss_status, &server);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ /* As long as we need to keep sending some context info, and there's no */
+ /* errors, keep sending it... */
+ for(;;) {
+ gss_major_status = Curl_gss_init_sec_context(data,
+ &gss_minor_status,
+ &gss_context,
+ server,
+ &Curl_krb5_mech_oid,
+ NULL,
+ gss_token,
+ &gss_send_token,
+ TRUE,
+ &gss_ret_flags);
+
+ if(gss_token != GSS_C_NO_BUFFER)
+ gss_release_buffer(&gss_status, &gss_recv_token);
+ if(check_gss_err(data, gss_major_status,
+ gss_minor_status, "gss_init_sec_context")) {
+ gss_release_name(&gss_status, &server);
+ gss_release_buffer(&gss_status, &gss_recv_token);
+ gss_release_buffer(&gss_status, &gss_send_token);
+ gss_delete_sec_context(&gss_status, &gss_context, NULL);
+ failf(data, "Failed to initial GSS-API token.");
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ if(gss_send_token.length != 0) {
+ socksreq[0] = 1; /* GSS-API subnegotiation version */
+ socksreq[1] = 1; /* authentication message type */
+ us_length = htons((short)gss_send_token.length);
+ memcpy(socksreq+2, &us_length, sizeof(short));
+
+ code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
+ if(code || (4 != written)) {
+ failf(data, "Failed to send GSS-API authentication request.");
+ gss_release_name(&gss_status, &server);
+ gss_release_buffer(&gss_status, &gss_recv_token);
+ gss_release_buffer(&gss_status, &gss_send_token);
+ gss_delete_sec_context(&gss_status, &gss_context, NULL);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ code = Curl_write_plain(conn, sock, (char *)gss_send_token.value,
+ gss_send_token.length, &written);
+
+ if(code || ((ssize_t)gss_send_token.length != written)) {
+ failf(data, "Failed to send GSS-API authentication token.");
+ gss_release_name(&gss_status, &server);
+ gss_release_buffer(&gss_status, &gss_recv_token);
+ gss_release_buffer(&gss_status, &gss_send_token);
+ gss_delete_sec_context(&gss_status, &gss_context, NULL);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ }
+
+ gss_release_buffer(&gss_status, &gss_send_token);
+ gss_release_buffer(&gss_status, &gss_recv_token);
+ if(gss_major_status != GSS_S_CONTINUE_NEEDED) break;
+
+ /* analyse response */
+
+ /* GSS-API response looks like
+ * +----+------+-----+----------------+
+ * |VER | MTYP | LEN | TOKEN |
+ * +----+------+----------------------+
+ * | 1 | 1 | 2 | up to 2^16 - 1 |
+ * +----+------+-----+----------------+
+ */
+
+ result=Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
+ if(result || (actualread != 4)) {
+ failf(data, "Failed to receive GSS-API authentication response.");
+ gss_release_name(&gss_status, &server);
+ gss_delete_sec_context(&gss_status, &gss_context, NULL);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ /* ignore the first (VER) byte */
+ if(socksreq[1] == 255) { /* status / message type */
+ failf(data, "User was rejected by the SOCKS5 server (%d %d).",
+ socksreq[0], socksreq[1]);
+ gss_release_name(&gss_status, &server);
+ gss_delete_sec_context(&gss_status, &gss_context, NULL);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ if(socksreq[1] != 1) { /* status / messgae type */
+ failf(data, "Invalid GSS-API authentication response type (%d %d).",
+ socksreq[0], socksreq[1]);
+ gss_release_name(&gss_status, &server);
+ gss_delete_sec_context(&gss_status, &gss_context, NULL);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ memcpy(&us_length, socksreq+2, sizeof(short));
+ us_length = ntohs(us_length);
+
+ gss_recv_token.length=us_length;
+ gss_recv_token.value=malloc(us_length);
+ if(!gss_recv_token.value) {
+ failf(data,
+ "Could not allocate memory for GSS-API authentication "
+ "response token.");
+ gss_release_name(&gss_status, &server);
+ gss_delete_sec_context(&gss_status, &gss_context, NULL);
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ result=Curl_blockread_all(conn, sock, (char *)gss_recv_token.value,
+ gss_recv_token.length, &actualread);
+
+ if(result || (actualread != us_length)) {
+ failf(data, "Failed to receive GSS-API authentication token.");
+ gss_release_name(&gss_status, &server);
+ gss_release_buffer(&gss_status, &gss_recv_token);
+ gss_delete_sec_context(&gss_status, &gss_context, NULL);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ gss_token = &gss_recv_token;
+ }
+
+ gss_release_name(&gss_status, &server);
+
+ /* Everything is good so far, user was authenticated! */
+ gss_major_status = gss_inquire_context (&gss_minor_status, gss_context,
+ &gss_client_name, NULL, NULL, NULL,
+ NULL, NULL, NULL);
+ if(check_gss_err(data, gss_major_status,
+ gss_minor_status, "gss_inquire_context")) {
+ gss_delete_sec_context(&gss_status, &gss_context, NULL);
+ gss_release_name(&gss_status, &gss_client_name);
+ failf(data, "Failed to determine user name.");
+ return CURLE_COULDNT_CONNECT;
+ }
+ gss_major_status = gss_display_name(&gss_minor_status, gss_client_name,
+ &gss_send_token, NULL);
+ if(check_gss_err(data, gss_major_status,
+ gss_minor_status, "gss_display_name")) {
+ gss_delete_sec_context(&gss_status, &gss_context, NULL);
+ gss_release_name(&gss_status, &gss_client_name);
+ gss_release_buffer(&gss_status, &gss_send_token);
+ failf(data, "Failed to determine user name.");
+ return CURLE_COULDNT_CONNECT;
+ }
+ user=malloc(gss_send_token.length+1);
+ if(!user) {
+ gss_delete_sec_context(&gss_status, &gss_context, NULL);
+ gss_release_name(&gss_status, &gss_client_name);
+ gss_release_buffer(&gss_status, &gss_send_token);
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ memcpy(user, gss_send_token.value, gss_send_token.length);
+ user[gss_send_token.length] = '\0';
+ gss_release_name(&gss_status, &gss_client_name);
+ gss_release_buffer(&gss_status, &gss_send_token);
+ infof(data, "SOCKS5 server authencticated user %s with GSS-API.\n",user);
+ free(user);
+ user=NULL;
+
+ /* Do encryption */
+ socksreq[0] = 1; /* GSS-API subnegotiation version */
+ socksreq[1] = 2; /* encryption message type */
+
+ gss_enc = 0; /* no data protection */
+ /* do confidentiality protection if supported */
+ if(gss_ret_flags & GSS_C_CONF_FLAG)
+ gss_enc = 2;
+ /* else do integrity protection */
+ else if(gss_ret_flags & GSS_C_INTEG_FLAG)
+ gss_enc = 1;
+
+ infof(data, "SOCKS5 server supports GSS-API %s data protection.\n",
+ (gss_enc==0)?"no":((gss_enc==1)?"integrity":"confidentiality"));
+ /* force for the moment to no data protection */
+ gss_enc = 0;
+ /*
+ * Sending the encryption type in clear seems wrong. It should be
+ * protected with gss_seal()/gss_wrap(). See RFC1961 extract below
+ * The NEC reference implementations on which this is based is
+ * therefore at fault
+ *
+ * +------+------+------+.......................+
+ * + ver | mtyp | len | token |
+ * +------+------+------+.......................+
+ * + 0x01 | 0x02 | 0x02 | up to 2^16 - 1 octets |
+ * +------+------+------+.......................+
+ *
+ * Where:
+ *
+ * - "ver" is the protocol version number, here 1 to represent the
+ * first version of the SOCKS/GSS-API protocol
+ *
+ * - "mtyp" is the message type, here 2 to represent a protection
+ * -level negotiation message
+ *
+ * - "len" is the length of the "token" field in octets
+ *
+ * - "token" is the GSS-API encapsulated protection level
+ *
+ * The token is produced by encapsulating an octet containing the
+ * required protection level using gss_seal()/gss_wrap() with conf_req
+ * set to FALSE. The token is verified using gss_unseal()/
+ * gss_unwrap().
+ *
+ */
+ if(data->set.socks5_gssapi_nec) {
+ us_length = htons((short)1);
+ memcpy(socksreq+2, &us_length, sizeof(short));
+ }
+ else {
+ gss_send_token.length = 1;
+ gss_send_token.value = malloc(1);
+ if(!gss_send_token.value) {
+ gss_delete_sec_context(&gss_status, &gss_context, NULL);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ memcpy(gss_send_token.value, &gss_enc, 1);
+
+ gss_major_status = gss_wrap(&gss_minor_status, gss_context, 0,
+ GSS_C_QOP_DEFAULT, &gss_send_token,
+ &gss_conf_state, &gss_w_token);
+
+ if(check_gss_err(data, gss_major_status, gss_minor_status, "gss_wrap")) {
+ gss_release_buffer(&gss_status, &gss_send_token);
+ gss_release_buffer(&gss_status, &gss_w_token);
+ gss_delete_sec_context(&gss_status, &gss_context, NULL);
+ failf(data, "Failed to wrap GSS-API encryption value into token.");
+ return CURLE_COULDNT_CONNECT;
+ }
+ gss_release_buffer(&gss_status, &gss_send_token);
+
+ us_length = htons((short)gss_w_token.length);
+ memcpy(socksreq+2, &us_length, sizeof(short));
+ }
+
+ code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
+ if(code || (4 != written)) {
+ failf(data, "Failed to send GSS-API encryption request.");
+ gss_release_buffer(&gss_status, &gss_w_token);
+ gss_delete_sec_context(&gss_status, &gss_context, NULL);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ if(data->set.socks5_gssapi_nec) {
+ memcpy(socksreq, &gss_enc, 1);
+ code = Curl_write_plain(conn, sock, socksreq, 1, &written);
+ if(code || ( 1 != written)) {
+ failf(data, "Failed to send GSS-API encryption type.");
+ gss_delete_sec_context(&gss_status, &gss_context, NULL);
+ return CURLE_COULDNT_CONNECT;
+ }
+ }
+ else {
+ code = Curl_write_plain(conn, sock, (char *)gss_w_token.value,
+ gss_w_token.length, &written);
+ if(code || ((ssize_t)gss_w_token.length != written)) {
+ failf(data, "Failed to send GSS-API encryption type.");
+ gss_release_buffer(&gss_status, &gss_w_token);
+ gss_delete_sec_context(&gss_status, &gss_context, NULL);
+ return CURLE_COULDNT_CONNECT;
+ }
+ gss_release_buffer(&gss_status, &gss_w_token);
+ }
+
+ result=Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
+ if(result || (actualread != 4)) {
+ failf(data, "Failed to receive GSS-API encryption response.");
+ gss_delete_sec_context(&gss_status, &gss_context, NULL);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ /* ignore the first (VER) byte */
+ if(socksreq[1] == 255) { /* status / message type */
+ failf(data, "User was rejected by the SOCKS5 server (%d %d).",
+ socksreq[0], socksreq[1]);
+ gss_delete_sec_context(&gss_status, &gss_context, NULL);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ if(socksreq[1] != 2) { /* status / messgae type */
+ failf(data, "Invalid GSS-API encryption response type (%d %d).",
+ socksreq[0], socksreq[1]);
+ gss_delete_sec_context(&gss_status, &gss_context, NULL);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ memcpy(&us_length, socksreq+2, sizeof(short));
+ us_length = ntohs(us_length);
+
+ gss_recv_token.length= us_length;
+ gss_recv_token.value=malloc(gss_recv_token.length);
+ if(!gss_recv_token.value) {
+ gss_delete_sec_context(&gss_status, &gss_context, NULL);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ result=Curl_blockread_all(conn, sock, (char *)gss_recv_token.value,
+ gss_recv_token.length, &actualread);
+
+ if(result || (actualread != us_length)) {
+ failf(data, "Failed to receive GSS-API encryptrion type.");
+ gss_release_buffer(&gss_status, &gss_recv_token);
+ gss_delete_sec_context(&gss_status, &gss_context, NULL);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ if(!data->set.socks5_gssapi_nec) {
+ gss_major_status = gss_unwrap(&gss_minor_status, gss_context,
+ &gss_recv_token, &gss_w_token,
+ 0, GSS_C_QOP_DEFAULT);
+
+ if(check_gss_err(data, gss_major_status, gss_minor_status, "gss_unwrap")) {
+ gss_release_buffer(&gss_status, &gss_recv_token);
+ gss_release_buffer(&gss_status, &gss_w_token);
+ gss_delete_sec_context(&gss_status, &gss_context, NULL);
+ failf(data, "Failed to unwrap GSS-API encryption value into token.");
+ return CURLE_COULDNT_CONNECT;
+ }
+ gss_release_buffer(&gss_status, &gss_recv_token);
+
+ if(gss_w_token.length != 1) {
+ failf(data, "Invalid GSS-API encryption response length (%d).",
+ gss_w_token.length);
+ gss_release_buffer(&gss_status, &gss_w_token);
+ gss_delete_sec_context(&gss_status, &gss_context, NULL);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ memcpy(socksreq, gss_w_token.value, gss_w_token.length);
+ gss_release_buffer(&gss_status, &gss_w_token);
+ }
+ else {
+ if(gss_recv_token.length != 1) {
+ failf(data, "Invalid GSS-API encryption response length (%d).",
+ gss_recv_token.length);
+ gss_release_buffer(&gss_status, &gss_recv_token);
+ gss_delete_sec_context(&gss_status, &gss_context, NULL);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ memcpy(socksreq, gss_recv_token.value, gss_recv_token.length);
+ gss_release_buffer(&gss_status, &gss_recv_token);
+ }
+
+ infof(data, "SOCKS5 access with%s protection granted.\n",
+ (socksreq[0]==0)?"out GSS-API data":
+ ((socksreq[0]==1)?" GSS-API integrity":" GSS-API confidentiality"));
+
+ conn->socks5_gssapi_enctype = socksreq[0];
+ if(socksreq[0] == 0)
+ gss_delete_sec_context(&gss_status, &gss_context, NULL);
+
+ return CURLE_OK;
+}
+
+#endif /* HAVE_GSSAPI && !CURL_DISABLE_PROXY */
diff --git a/Utilities/cmcurl/lib/socks_sspi.c b/Utilities/cmcurl/lib/socks_sspi.c
new file mode 100644
index 000000000..a7708b2d4
--- /dev/null
+++ b/Utilities/cmcurl/lib/socks_sspi.c
@@ -0,0 +1,601 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2009, 2011, Markus Moeller, <markus_moeller@compuserve.com>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_WINDOWS_SSPI) && !defined(CURL_DISABLE_PROXY)
+
+#include "urldata.h"
+#include "sendf.h"
+#include "connect.h"
+#include "strerror.h"
+#include "timeval.h"
+#include "socks.h"
+#include "curl_sspi.h"
+#include "curl_multibyte.h"
+#include "warnless.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ * Helper sspi error functions.
+ */
+static int check_sspi_err(struct connectdata *conn,
+ SECURITY_STATUS status,
+ const char* function)
+{
+ if(status != SEC_E_OK &&
+ status != SEC_I_COMPLETE_AND_CONTINUE &&
+ status != SEC_I_COMPLETE_NEEDED &&
+ status != SEC_I_CONTINUE_NEEDED) {
+ failf(conn->data, "SSPI error: %s failed: %s", function,
+ Curl_sspi_strerror(conn, status));
+ return 1;
+ }
+ return 0;
+}
+
+/* This is the SSPI-using version of this function */
+CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
+ struct connectdata *conn)
+{
+ struct SessionHandle *data = conn->data;
+ curl_socket_t sock = conn->sock[sockindex];
+ CURLcode code;
+ ssize_t actualread;
+ ssize_t written;
+ int result;
+ /* Needs GSS-API authentication */
+ SECURITY_STATUS status;
+ unsigned long sspi_ret_flags = 0;
+ int gss_enc;
+ SecBuffer sspi_send_token, sspi_recv_token, sspi_w_token[3];
+ SecBufferDesc input_desc, output_desc, wrap_desc;
+ SecPkgContext_Sizes sspi_sizes;
+ CredHandle cred_handle;
+ CtxtHandle sspi_context;
+ PCtxtHandle context_handle = NULL;
+ SecPkgCredentials_Names names;
+ TimeStamp expiry;
+ char *service_name = NULL;
+ unsigned short us_length;
+ unsigned long qop;
+ unsigned char socksreq[4]; /* room for GSS-API exchange header only */
+ char *service = data->set.str[STRING_SOCKS5_GSSAPI_SERVICE];
+
+ /* GSS-API request looks like
+ * +----+------+-----+----------------+
+ * |VER | MTYP | LEN | TOKEN |
+ * +----+------+----------------------+
+ * | 1 | 1 | 2 | up to 2^16 - 1 |
+ * +----+------+-----+----------------+
+ */
+
+ /* prepare service name */
+ if(strchr(service, '/')) {
+ service_name = malloc(strlen(service));
+ if(!service_name)
+ return CURLE_OUT_OF_MEMORY;
+ memcpy(service_name, service, strlen(service));
+ }
+ else {
+ service_name = malloc(strlen(service) + strlen(conn->proxy.name) + 2);
+ if(!service_name)
+ return CURLE_OUT_OF_MEMORY;
+ snprintf(service_name, strlen(service) +strlen(conn->proxy.name)+2,
+ "%s/%s", service, conn->proxy.name);
+ }
+
+ input_desc.cBuffers = 1;
+ input_desc.pBuffers = &sspi_recv_token;
+ input_desc.ulVersion = SECBUFFER_VERSION;
+
+ sspi_recv_token.BufferType = SECBUFFER_TOKEN;
+ sspi_recv_token.cbBuffer = 0;
+ sspi_recv_token.pvBuffer = NULL;
+
+ output_desc.cBuffers = 1;
+ output_desc.pBuffers = &sspi_send_token;
+ output_desc.ulVersion = SECBUFFER_VERSION;
+
+ sspi_send_token.BufferType = SECBUFFER_TOKEN;
+ sspi_send_token.cbBuffer = 0;
+ sspi_send_token.pvBuffer = NULL;
+
+ wrap_desc.cBuffers = 3;
+ wrap_desc.pBuffers = sspi_w_token;
+ wrap_desc.ulVersion = SECBUFFER_VERSION;
+
+ cred_handle.dwLower = 0;
+ cred_handle.dwUpper = 0;
+
+ status = s_pSecFn->AcquireCredentialsHandle(NULL,
+ (TCHAR *) TEXT("Kerberos"),
+ SECPKG_CRED_OUTBOUND,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &cred_handle,
+ &expiry);
+
+ if(check_sspi_err(conn, status, "AcquireCredentialsHandle")) {
+ failf(data, "Failed to acquire credentials.");
+ free(service_name);
+ s_pSecFn->FreeCredentialsHandle(&cred_handle);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ /* As long as we need to keep sending some context info, and there's no */
+ /* errors, keep sending it... */
+ for(;;) {
+ TCHAR *sname;
+
+ sname = Curl_convert_UTF8_to_tchar(service_name);
+ if(!sname)
+ return CURLE_OUT_OF_MEMORY;
+
+ status = s_pSecFn->InitializeSecurityContext(&cred_handle,
+ context_handle,
+ sname,
+ ISC_REQ_MUTUAL_AUTH |
+ ISC_REQ_ALLOCATE_MEMORY |
+ ISC_REQ_CONFIDENTIALITY |
+ ISC_REQ_REPLAY_DETECT,
+ 0,
+ SECURITY_NATIVE_DREP,
+ &input_desc,
+ 0,
+ &sspi_context,
+ &output_desc,
+ &sspi_ret_flags,
+ &expiry);
+
+ Curl_unicodefree(sname);
+
+ if(sspi_recv_token.pvBuffer) {
+ s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
+ sspi_recv_token.pvBuffer = NULL;
+ sspi_recv_token.cbBuffer = 0;
+ }
+
+ if(check_sspi_err(conn, status, "InitializeSecurityContext")) {
+ free(service_name);
+ s_pSecFn->FreeCredentialsHandle(&cred_handle);
+ s_pSecFn->DeleteSecurityContext(&sspi_context);
+ if(sspi_recv_token.pvBuffer)
+ s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
+ failf(data, "Failed to initialise security context.");
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ if(sspi_send_token.cbBuffer != 0) {
+ socksreq[0] = 1; /* GSS-API subnegotiation version */
+ socksreq[1] = 1; /* authentication message type */
+ us_length = htons((short)sspi_send_token.cbBuffer);
+ memcpy(socksreq+2, &us_length, sizeof(short));
+
+ code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
+ if(code || (4 != written)) {
+ failf(data, "Failed to send SSPI authentication request.");
+ free(service_name);
+ if(sspi_send_token.pvBuffer)
+ s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
+ if(sspi_recv_token.pvBuffer)
+ s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
+ s_pSecFn->FreeCredentialsHandle(&cred_handle);
+ s_pSecFn->DeleteSecurityContext(&sspi_context);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ code = Curl_write_plain(conn, sock, (char *)sspi_send_token.pvBuffer,
+ sspi_send_token.cbBuffer, &written);
+ if(code || (sspi_send_token.cbBuffer != (size_t)written)) {
+ failf(data, "Failed to send SSPI authentication token.");
+ free(service_name);
+ if(sspi_send_token.pvBuffer)
+ s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
+ if(sspi_recv_token.pvBuffer)
+ s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
+ s_pSecFn->FreeCredentialsHandle(&cred_handle);
+ s_pSecFn->DeleteSecurityContext(&sspi_context);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ }
+
+ if(sspi_send_token.pvBuffer) {
+ s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
+ sspi_send_token.pvBuffer = NULL;
+ }
+ sspi_send_token.cbBuffer = 0;
+
+ if(sspi_recv_token.pvBuffer) {
+ s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
+ sspi_recv_token.pvBuffer = NULL;
+ }
+ sspi_recv_token.cbBuffer = 0;
+
+ if(status != SEC_I_CONTINUE_NEEDED)
+ break;
+
+ /* analyse response */
+
+ /* GSS-API response looks like
+ * +----+------+-----+----------------+
+ * |VER | MTYP | LEN | TOKEN |
+ * +----+------+----------------------+
+ * | 1 | 1 | 2 | up to 2^16 - 1 |
+ * +----+------+-----+----------------+
+ */
+
+ result = Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
+ if(result || (actualread != 4)) {
+ failf(data, "Failed to receive SSPI authentication response.");
+ free(service_name);
+ s_pSecFn->FreeCredentialsHandle(&cred_handle);
+ s_pSecFn->DeleteSecurityContext(&sspi_context);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ /* ignore the first (VER) byte */
+ if(socksreq[1] == 255) { /* status / message type */
+ failf(data, "User was rejected by the SOCKS5 server (%u %u).",
+ (unsigned int)socksreq[0], (unsigned int)socksreq[1]);
+ free(service_name);
+ s_pSecFn->FreeCredentialsHandle(&cred_handle);
+ s_pSecFn->DeleteSecurityContext(&sspi_context);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ if(socksreq[1] != 1) { /* status / messgae type */
+ failf(data, "Invalid SSPI authentication response type (%u %u).",
+ (unsigned int)socksreq[0], (unsigned int)socksreq[1]);
+ free(service_name);
+ s_pSecFn->FreeCredentialsHandle(&cred_handle);
+ s_pSecFn->DeleteSecurityContext(&sspi_context);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ memcpy(&us_length, socksreq+2, sizeof(short));
+ us_length = ntohs(us_length);
+
+ sspi_recv_token.cbBuffer = us_length;
+ sspi_recv_token.pvBuffer = malloc(us_length);
+
+ if(!sspi_recv_token.pvBuffer) {
+ free(service_name);
+ s_pSecFn->FreeCredentialsHandle(&cred_handle);
+ s_pSecFn->DeleteSecurityContext(&sspi_context);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ result = Curl_blockread_all(conn, sock, (char *)sspi_recv_token.pvBuffer,
+ sspi_recv_token.cbBuffer, &actualread);
+
+ if(result || (actualread != us_length)) {
+ failf(data, "Failed to receive SSPI authentication token.");
+ free(service_name);
+ if(sspi_recv_token.pvBuffer)
+ s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
+ s_pSecFn->FreeCredentialsHandle(&cred_handle);
+ s_pSecFn->DeleteSecurityContext(&sspi_context);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ context_handle = &sspi_context;
+ }
+
+ free(service_name);
+
+ /* Everything is good so far, user was authenticated! */
+ status = s_pSecFn->QueryCredentialsAttributes(&cred_handle,
+ SECPKG_CRED_ATTR_NAMES,
+ &names);
+ s_pSecFn->FreeCredentialsHandle(&cred_handle);
+ if(check_sspi_err(conn, status, "QueryCredentialAttributes")) {
+ s_pSecFn->DeleteSecurityContext(&sspi_context);
+ s_pSecFn->FreeContextBuffer(names.sUserName);
+ failf(data, "Failed to determine user name.");
+ return CURLE_COULDNT_CONNECT;
+ }
+ infof(data, "SOCKS5 server authencticated user %s with GSS-API.\n",
+ names.sUserName);
+ s_pSecFn->FreeContextBuffer(names.sUserName);
+
+ /* Do encryption */
+ socksreq[0] = 1; /* GSS-API subnegotiation version */
+ socksreq[1] = 2; /* encryption message type */
+
+ gss_enc = 0; /* no data protection */
+ /* do confidentiality protection if supported */
+ if(sspi_ret_flags & ISC_REQ_CONFIDENTIALITY)
+ gss_enc = 2;
+ /* else do integrity protection */
+ else if(sspi_ret_flags & ISC_REQ_INTEGRITY)
+ gss_enc = 1;
+
+ infof(data, "SOCKS5 server supports GSS-API %s data protection.\n",
+ (gss_enc==0)?"no":((gss_enc==1)?"integrity":"confidentiality") );
+ /* force to no data protection, avoid encryption/decryption for now */
+ gss_enc = 0;
+ /*
+ * Sending the encryption type in clear seems wrong. It should be
+ * protected with gss_seal()/gss_wrap(). See RFC1961 extract below
+ * The NEC reference implementations on which this is based is
+ * therefore at fault
+ *
+ * +------+------+------+.......................+
+ * + ver | mtyp | len | token |
+ * +------+------+------+.......................+
+ * + 0x01 | 0x02 | 0x02 | up to 2^16 - 1 octets |
+ * +------+------+------+.......................+
+ *
+ * Where:
+ *
+ * - "ver" is the protocol version number, here 1 to represent the
+ * first version of the SOCKS/GSS-API protocol
+ *
+ * - "mtyp" is the message type, here 2 to represent a protection
+ * -level negotiation message
+ *
+ * - "len" is the length of the "token" field in octets
+ *
+ * - "token" is the GSS-API encapsulated protection level
+ *
+ * The token is produced by encapsulating an octet containing the
+ * required protection level using gss_seal()/gss_wrap() with conf_req
+ * set to FALSE. The token is verified using gss_unseal()/
+ * gss_unwrap().
+ *
+ */
+
+ if(data->set.socks5_gssapi_nec) {
+ us_length = htons((short)1);
+ memcpy(socksreq+2, &us_length, sizeof(short));
+ }
+ else {
+ status = s_pSecFn->QueryContextAttributes(&sspi_context,
+ SECPKG_ATTR_SIZES,
+ &sspi_sizes);
+ if(check_sspi_err(conn, status, "QueryContextAttributes")) {
+ s_pSecFn->DeleteSecurityContext(&sspi_context);
+ failf(data, "Failed to query security context attributes.");
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ sspi_w_token[0].cbBuffer = sspi_sizes.cbSecurityTrailer;
+ sspi_w_token[0].BufferType = SECBUFFER_TOKEN;
+ sspi_w_token[0].pvBuffer = malloc(sspi_sizes.cbSecurityTrailer);
+
+ if(!sspi_w_token[0].pvBuffer) {
+ s_pSecFn->DeleteSecurityContext(&sspi_context);
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ sspi_w_token[1].cbBuffer = 1;
+ sspi_w_token[1].pvBuffer = malloc(1);
+ if(!sspi_w_token[1].pvBuffer) {
+ s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+ s_pSecFn->DeleteSecurityContext(&sspi_context);
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ memcpy(sspi_w_token[1].pvBuffer, &gss_enc, 1);
+ sspi_w_token[2].BufferType = SECBUFFER_PADDING;
+ sspi_w_token[2].cbBuffer = sspi_sizes.cbBlockSize;
+ sspi_w_token[2].pvBuffer = malloc(sspi_sizes.cbBlockSize);
+ if(!sspi_w_token[2].pvBuffer) {
+ s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+ s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
+ s_pSecFn->DeleteSecurityContext(&sspi_context);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ status = s_pSecFn->EncryptMessage(&sspi_context,
+ KERB_WRAP_NO_ENCRYPT,
+ &wrap_desc,
+ 0);
+ if(check_sspi_err(conn, status, "EncryptMessage")) {
+ s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+ s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
+ s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer);
+ s_pSecFn->DeleteSecurityContext(&sspi_context);
+ failf(data, "Failed to query security context attributes.");
+ return CURLE_COULDNT_CONNECT;
+ }
+ sspi_send_token.cbBuffer = sspi_w_token[0].cbBuffer
+ + sspi_w_token[1].cbBuffer
+ + sspi_w_token[2].cbBuffer;
+ sspi_send_token.pvBuffer = malloc(sspi_send_token.cbBuffer);
+ if(!sspi_send_token.pvBuffer) {
+ s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+ s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
+ s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer);
+ s_pSecFn->DeleteSecurityContext(&sspi_context);
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ memcpy(sspi_send_token.pvBuffer, sspi_w_token[0].pvBuffer,
+ sspi_w_token[0].cbBuffer);
+ memcpy((PUCHAR) sspi_send_token.pvBuffer +(int)sspi_w_token[0].cbBuffer,
+ sspi_w_token[1].pvBuffer, sspi_w_token[1].cbBuffer);
+ memcpy((PUCHAR) sspi_send_token.pvBuffer
+ +sspi_w_token[0].cbBuffer
+ +sspi_w_token[1].cbBuffer,
+ sspi_w_token[2].pvBuffer, sspi_w_token[2].cbBuffer);
+
+ s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+ sspi_w_token[0].pvBuffer = NULL;
+ sspi_w_token[0].cbBuffer = 0;
+ s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
+ sspi_w_token[1].pvBuffer = NULL;
+ sspi_w_token[1].cbBuffer = 0;
+ s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer);
+ sspi_w_token[2].pvBuffer = NULL;
+ sspi_w_token[2].cbBuffer = 0;
+
+ us_length = htons((short)sspi_send_token.cbBuffer);
+ memcpy(socksreq+2, &us_length, sizeof(short));
+ }
+
+ code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
+ if(code || (4 != written)) {
+ failf(data, "Failed to send SSPI encryption request.");
+ if(sspi_send_token.pvBuffer)
+ s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
+ s_pSecFn->DeleteSecurityContext(&sspi_context);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ if(data->set.socks5_gssapi_nec) {
+ memcpy(socksreq, &gss_enc, 1);
+ code = Curl_write_plain(conn, sock, (char *)socksreq, 1, &written);
+ if(code || (1 != written)) {
+ failf(data, "Failed to send SSPI encryption type.");
+ s_pSecFn->DeleteSecurityContext(&sspi_context);
+ return CURLE_COULDNT_CONNECT;
+ }
+ }
+ else {
+ code = Curl_write_plain(conn, sock, (char *)sspi_send_token.pvBuffer,
+ sspi_send_token.cbBuffer, &written);
+ if(code || (sspi_send_token.cbBuffer != (size_t)written)) {
+ failf(data, "Failed to send SSPI encryption type.");
+ if(sspi_send_token.pvBuffer)
+ s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
+ s_pSecFn->DeleteSecurityContext(&sspi_context);
+ return CURLE_COULDNT_CONNECT;
+ }
+ if(sspi_send_token.pvBuffer)
+ s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
+ }
+
+ result = Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
+ if(result || (actualread != 4)) {
+ failf(data, "Failed to receive SSPI encryption response.");
+ s_pSecFn->DeleteSecurityContext(&sspi_context);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ /* ignore the first (VER) byte */
+ if(socksreq[1] == 255) { /* status / message type */
+ failf(data, "User was rejected by the SOCKS5 server (%u %u).",
+ (unsigned int)socksreq[0], (unsigned int)socksreq[1]);
+ s_pSecFn->DeleteSecurityContext(&sspi_context);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ if(socksreq[1] != 2) { /* status / message type */
+ failf(data, "Invalid SSPI encryption response type (%u %u).",
+ (unsigned int)socksreq[0], (unsigned int)socksreq[1]);
+ s_pSecFn->DeleteSecurityContext(&sspi_context);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ memcpy(&us_length, socksreq+2, sizeof(short));
+ us_length = ntohs(us_length);
+
+ sspi_w_token[0].cbBuffer = us_length;
+ sspi_w_token[0].pvBuffer = malloc(us_length);
+ if(!sspi_w_token[0].pvBuffer) {
+ s_pSecFn->DeleteSecurityContext(&sspi_context);
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ result = Curl_blockread_all(conn, sock, (char *)sspi_w_token[0].pvBuffer,
+ sspi_w_token[0].cbBuffer, &actualread);
+
+ if(result || (actualread != us_length)) {
+ failf(data, "Failed to receive SSPI encryption type.");
+ s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+ s_pSecFn->DeleteSecurityContext(&sspi_context);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+
+ if(!data->set.socks5_gssapi_nec) {
+ wrap_desc.cBuffers = 2;
+ sspi_w_token[0].BufferType = SECBUFFER_STREAM;
+ sspi_w_token[1].BufferType = SECBUFFER_DATA;
+ sspi_w_token[1].cbBuffer = 0;
+ sspi_w_token[1].pvBuffer = NULL;
+
+ status = s_pSecFn->DecryptMessage(&sspi_context,
+ &wrap_desc,
+ 0,
+ &qop);
+
+ if(check_sspi_err(conn, status, "DecryptMessage")) {
+ if(sspi_w_token[0].pvBuffer)
+ s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+ if(sspi_w_token[1].pvBuffer)
+ s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
+ s_pSecFn->DeleteSecurityContext(&sspi_context);
+ failf(data, "Failed to query security context attributes.");
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ if(sspi_w_token[1].cbBuffer != 1) {
+ failf(data, "Invalid SSPI encryption response length (%lu).",
+ (unsigned long)sspi_w_token[1].cbBuffer);
+ if(sspi_w_token[0].pvBuffer)
+ s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+ if(sspi_w_token[1].pvBuffer)
+ s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
+ s_pSecFn->DeleteSecurityContext(&sspi_context);
+ return CURLE_COULDNT_CONNECT;
+ }
+
+ memcpy(socksreq, sspi_w_token[1].pvBuffer, sspi_w_token[1].cbBuffer);
+ s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+ s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
+ }
+ else {
+ if(sspi_w_token[0].cbBuffer != 1) {
+ failf(data, "Invalid SSPI encryption response length (%lu).",
+ (unsigned long)sspi_w_token[0].cbBuffer);
+ s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+ s_pSecFn->DeleteSecurityContext(&sspi_context);
+ return CURLE_COULDNT_CONNECT;
+ }
+ memcpy(socksreq, sspi_w_token[0].pvBuffer, sspi_w_token[0].cbBuffer);
+ s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+ }
+
+ infof(data, "SOCKS5 access with%s protection granted.\n",
+ (socksreq[0]==0)?"out GSS-API data":
+ ((socksreq[0]==1)?" GSS-API integrity":" GSS-API confidentiality"));
+
+ /* For later use if encryption is required
+ conn->socks5_gssapi_enctype = socksreq[0];
+ if(socksreq[0] != 0)
+ conn->socks5_sspi_context = sspi_context;
+ else {
+ s_pSecFn->DeleteSecurityContext(&sspi_context);
+ conn->socks5_sspi_context = sspi_context;
+ }
+ */
+ return CURLE_OK;
+}
+#endif
diff --git a/Utilities/cmcurl/lib/speedcheck.c b/Utilities/cmcurl/lib/speedcheck.c
new file mode 100644
index 000000000..ac7447c41
--- /dev/null
+++ b/Utilities/cmcurl/lib/speedcheck.c
@@ -0,0 +1,74 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "sendf.h"
+#include "multiif.h"
+#include "speedcheck.h"
+
+void Curl_speedinit(struct SessionHandle *data)
+{
+ memset(&data->state.keeps_speed, 0, sizeof(struct timeval));
+}
+
+CURLcode Curl_speedcheck(struct SessionHandle *data,
+ struct timeval now)
+{
+ if((data->progress.current_speed >= 0) &&
+ data->set.low_speed_time &&
+ (Curl_tvlong(data->state.keeps_speed) != 0) &&
+ (data->progress.current_speed < data->set.low_speed_limit)) {
+ long howlong = Curl_tvdiff(now, data->state.keeps_speed);
+ long nextcheck = (data->set.low_speed_time * 1000) - howlong;
+
+ /* We are now below the "low speed limit". If we are below it
+ for "low speed time" seconds we consider that enough reason
+ to abort the download. */
+ if(nextcheck <= 0) {
+ /* we have been this slow for long enough, now die */
+ failf(data,
+ "Operation too slow. "
+ "Less than %ld bytes/sec transferred the last %ld seconds",
+ data->set.low_speed_limit,
+ data->set.low_speed_time);
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+ else {
+ /* wait complete low_speed_time */
+ Curl_expire_latest(data, nextcheck);
+ }
+ }
+ else {
+ /* we keep up the required speed all right */
+ data->state.keeps_speed = now;
+
+ if(data->set.low_speed_limit)
+ /* if there is a low speed limit enabled, we set the expire timer to
+ make this connection's speed get checked again no later than when
+ this time is up */
+ Curl_expire_latest(data, data->set.low_speed_time*1000);
+ }
+ return CURLE_OK;
+}
diff --git a/Utilities/cmcurl/lib/speedcheck.h b/Utilities/cmcurl/lib/speedcheck.h
new file mode 100644
index 000000000..786cd1215
--- /dev/null
+++ b/Utilities/cmcurl/lib/speedcheck.h
@@ -0,0 +1,33 @@
+#ifndef HEADER_CURL_SPEEDCHECK_H
+#define HEADER_CURL_SPEEDCHECK_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "timeval.h"
+
+void Curl_speedinit(struct SessionHandle *data);
+CURLcode Curl_speedcheck(struct SessionHandle *data,
+ struct timeval now);
+
+#endif /* HEADER_CURL_SPEEDCHECK_H */
diff --git a/Utilities/cmcurl/lib/splay.c b/Utilities/cmcurl/lib/splay.c
new file mode 100644
index 000000000..b87b6cfe2
--- /dev/null
+++ b/Utilities/cmcurl/lib/splay.c
@@ -0,0 +1,288 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1997 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "splay.h"
+
+/*
+ * This macro compares two node keys i and j and returns:
+ *
+ * negative value: when i is smaller than j
+ * zero : when i is equal to j
+ * positive when : when i is larger than j
+ */
+#define compare(i,j) Curl_splaycomparekeys((i),(j))
+
+/*
+ * Splay using the key i (which may or may not be in the tree.) The starting
+ * root is t.
+ */
+struct Curl_tree *Curl_splay(struct timeval i,
+ struct Curl_tree *t)
+{
+ struct Curl_tree N, *l, *r, *y;
+ long comp;
+
+ if(t == NULL)
+ return t;
+ N.smaller = N.larger = NULL;
+ l = r = &N;
+
+ for(;;) {
+ comp = compare(i, t->key);
+ if(comp < 0) {
+ if(t->smaller == NULL)
+ break;
+ if(compare(i, t->smaller->key) < 0) {
+ y = t->smaller; /* rotate smaller */
+ t->smaller = y->larger;
+ y->larger = t;
+ t = y;
+ if(t->smaller == NULL)
+ break;
+ }
+ r->smaller = t; /* link smaller */
+ r = t;
+ t = t->smaller;
+ }
+ else if(comp > 0) {
+ if(t->larger == NULL)
+ break;
+ if(compare(i, t->larger->key) > 0) {
+ y = t->larger; /* rotate larger */
+ t->larger = y->smaller;
+ y->smaller = t;
+ t = y;
+ if(t->larger == NULL)
+ break;
+ }
+ l->larger = t; /* link larger */
+ l = t;
+ t = t->larger;
+ }
+ else
+ break;
+ }
+
+ l->larger = t->smaller; /* assemble */
+ r->smaller = t->larger;
+ t->smaller = N.larger;
+ t->larger = N.smaller;
+
+ return t;
+}
+
+/* Insert key i into the tree t. Return a pointer to the resulting tree or
+ * NULL if something went wrong.
+ *
+ * @unittest: 1309
+ */
+struct Curl_tree *Curl_splayinsert(struct timeval i,
+ struct Curl_tree *t,
+ struct Curl_tree *node)
+{
+ static const struct timeval KEY_NOTUSED = {-1, -1}; /* will *NEVER* appear */
+
+ if(node == NULL)
+ return t;
+
+ if(t != NULL) {
+ t = Curl_splay(i, t);
+ if(compare(i, t->key)==0) {
+ /* There already exists a node in the tree with the very same key. Build
+ a linked list of nodes. We make the new 'node' struct the new master
+ node and make the previous node the first one in the 'same' list. */
+
+ node->same = t;
+ node->key = i;
+ node->smaller = t->smaller;
+ node->larger = t->larger;
+
+ t->smaller = node; /* in the sub node for this same key, we use the
+ smaller pointer to point back to the master
+ node */
+
+ t->key = KEY_NOTUSED; /* and we set the key in the sub node to NOTUSED
+ to quickly identify this node as a subnode */
+
+ return node; /* new root node */
+ }
+ }
+
+ if(t == NULL) {
+ node->smaller = node->larger = NULL;
+ }
+ else if(compare(i, t->key) < 0) {
+ node->smaller = t->smaller;
+ node->larger = t;
+ t->smaller = NULL;
+
+ }
+ else {
+ node->larger = t->larger;
+ node->smaller = t;
+ t->larger = NULL;
+ }
+ node->key = i;
+
+ node->same = NULL; /* no identical node (yet) */
+ return node;
+}
+
+/* Finds and deletes the best-fit node from the tree. Return a pointer to the
+ resulting tree. best-fit means the node with the given or lower key */
+struct Curl_tree *Curl_splaygetbest(struct timeval i,
+ struct Curl_tree *t,
+ struct Curl_tree **removed)
+{
+ struct Curl_tree *x;
+
+ if(!t) {
+ *removed = NULL; /* none removed since there was no root */
+ return NULL;
+ }
+
+ t = Curl_splay(i, t);
+ if(compare(i, t->key) < 0) {
+ /* too big node, try the smaller chain */
+ if(t->smaller)
+ t=Curl_splay(t->smaller->key, t);
+ else {
+ /* fail */
+ *removed = NULL;
+ return t;
+ }
+ }
+
+ if(compare(i, t->key) >= 0) { /* found it */
+ /* FIRST! Check if there is a list with identical keys */
+ x = t->same;
+ if(x) {
+ /* there is, pick one from the list */
+
+ /* 'x' is the new root node */
+
+ x->key = t->key;
+ x->larger = t->larger;
+ x->smaller = t->smaller;
+
+ *removed = t;
+ return x; /* new root */
+ }
+
+ if(t->smaller == NULL) {
+ x = t->larger;
+ }
+ else {
+ x = Curl_splay(i, t->smaller);
+ x->larger = t->larger;
+ }
+ *removed = t;
+
+ return x;
+ }
+ else {
+ *removed = NULL; /* no match */
+ return t; /* It wasn't there */
+ }
+}
+
+
+/* Deletes the very node we point out from the tree if it's there. Stores a
+ * pointer to the new resulting tree in 'newroot'.
+ *
+ * Returns zero on success and non-zero on errors! TODO: document error codes.
+ * When returning error, it does not touch the 'newroot' pointer.
+ *
+ * NOTE: when the last node of the tree is removed, there's no tree left so
+ * 'newroot' will be made to point to NULL.
+ *
+ * @unittest: 1309
+ */
+int Curl_splayremovebyaddr(struct Curl_tree *t,
+ struct Curl_tree *removenode,
+ struct Curl_tree **newroot)
+{
+ static const struct timeval KEY_NOTUSED = {-1, -1}; /* will *NEVER* appear */
+ struct Curl_tree *x;
+
+ if(!t || !removenode)
+ return 1;
+
+ if(compare(KEY_NOTUSED, removenode->key) == 0) {
+ /* Key set to NOTUSED means it is a subnode within a 'same' linked list
+ and thus we can unlink it easily. The 'smaller' link of a subnode
+ links to the parent node. */
+ if(removenode->smaller == NULL)
+ return 3;
+
+ removenode->smaller->same = removenode->same;
+ if(removenode->same)
+ removenode->same->smaller = removenode->smaller;
+
+ /* Ensures that double-remove gets caught. */
+ removenode->smaller = NULL;
+
+ /* voila, we're done! */
+ *newroot = t; /* return the same root */
+ return 0;
+ }
+
+ t = Curl_splay(removenode->key, t);
+
+ /* First make sure that we got the same root node as the one we want
+ to remove, as otherwise we might be trying to remove a node that
+ isn't actually in the tree.
+
+ We cannot just compare the keys here as a double remove in quick
+ succession of a node with key != KEY_NOTUSED && same != NULL
+ could return the same key but a different node. */
+ if(t != removenode)
+ return 2;
+
+ /* Check if there is a list with identical sizes, as then we're trying to
+ remove the root node of a list of nodes with identical keys. */
+ x = t->same;
+ if(x) {
+ /* 'x' is the new root node, we just make it use the root node's
+ smaller/larger links */
+
+ x->key = t->key;
+ x->larger = t->larger;
+ x->smaller = t->smaller;
+ }
+ else {
+ /* Remove the root node */
+ if(t->smaller == NULL)
+ x = t->larger;
+ else {
+ x = Curl_splay(removenode->key, t->smaller);
+ x->larger = t->larger;
+ }
+ }
+
+ *newroot = x; /* store new root pointer */
+
+ return 0;
+}
+
diff --git a/Utilities/cmcurl/lib/splay.h b/Utilities/cmcurl/lib/splay.h
new file mode 100644
index 000000000..5f9ef24cc
--- /dev/null
+++ b/Utilities/cmcurl/lib/splay.h
@@ -0,0 +1,66 @@
+#ifndef HEADER_CURL_SPLAY_H
+#define HEADER_CURL_SPLAY_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1997 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+struct Curl_tree {
+ struct Curl_tree *smaller; /* smaller node */
+ struct Curl_tree *larger; /* larger node */
+ struct Curl_tree *same; /* points to a node with identical key */
+ struct timeval key; /* this node's "sort" key */
+ void *payload; /* data the splay code doesn't care about */
+};
+
+struct Curl_tree *Curl_splay(struct timeval i,
+ struct Curl_tree *t);
+
+struct Curl_tree *Curl_splayinsert(struct timeval key,
+ struct Curl_tree *t,
+ struct Curl_tree *newnode);
+
+#if 0
+struct Curl_tree *Curl_splayremove(struct timeval key,
+ struct Curl_tree *t,
+ struct Curl_tree **removed);
+#endif
+
+struct Curl_tree *Curl_splaygetbest(struct timeval key,
+ struct Curl_tree *t,
+ struct Curl_tree **removed);
+
+int Curl_splayremovebyaddr(struct Curl_tree *t,
+ struct Curl_tree *removenode,
+ struct Curl_tree **newroot);
+
+#define Curl_splaycomparekeys(i,j) ( ((i.tv_sec) < (j.tv_sec)) ? -1 : \
+ ( ((i.tv_sec) > (j.tv_sec)) ? 1 : \
+ ( ((i.tv_usec) < (j.tv_usec)) ? -1 : \
+ ( ((i.tv_usec) > (j.tv_usec)) ? 1 : 0 ))))
+
+#ifdef DEBUGBUILD
+void Curl_splayprint(struct Curl_tree * t, int d, char output);
+#else
+#define Curl_splayprint(x,y,z) Curl_nop_stmt
+#endif
+
+#endif /* HEADER_CURL_SPLAY_H */
diff --git a/Utilities/cmcurl/lib/ssh.c b/Utilities/cmcurl/lib/ssh.c
new file mode 100644
index 000000000..94195a7b6
--- /dev/null
+++ b/Utilities/cmcurl/lib/ssh.c
@@ -0,0 +1,3344 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* #define CURL_LIBSSH2_DEBUG */
+
+#include "curl_setup.h"
+
+#ifdef USE_LIBSSH2
+
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+
+#include <libssh2.h>
+#include <libssh2_sftp.h>
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "progress.h"
+#include "transfer.h"
+#include "escape.h"
+#include "http.h" /* for HTTP proxy tunnel stuff */
+#include "ssh.h"
+#include "url.h"
+#include "speedcheck.h"
+#include "getinfo.h"
+
+#include "strequal.h"
+#include "vtls/vtls.h"
+#include "connect.h"
+#include "strerror.h"
+#include "inet_ntop.h"
+#include "parsedate.h" /* for the week day and month names */
+#include "sockaddr.h" /* required for Curl_sockaddr_storage */
+#include "strtoofft.h"
+#include "multiif.h"
+#include "select.h"
+#include "warnless.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#ifdef WIN32
+# undef PATH_MAX
+# define PATH_MAX MAX_PATH
+# ifndef R_OK
+# define R_OK 4
+# endif
+#endif
+
+#ifndef PATH_MAX
+#define PATH_MAX 1024 /* just an extra precaution since there are systems that
+ have their definition hidden well */
+#endif
+
+#define sftp_libssh2_last_error(s) curlx_ultosi(libssh2_sftp_last_error(s))
+
+#define sftp_libssh2_realpath(s,p,t,m) \
+ libssh2_sftp_symlink_ex((s), (p), curlx_uztoui(strlen(p)), \
+ (t), (m), LIBSSH2_SFTP_REALPATH)
+
+/* Local functions: */
+static const char *sftp_libssh2_strerror(int err);
+static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
+static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
+static LIBSSH2_FREE_FUNC(my_libssh2_free);
+
+static CURLcode get_pathname(const char **cpp, char **path);
+
+static CURLcode ssh_connect(struct connectdata *conn, bool *done);
+static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
+static CURLcode ssh_do(struct connectdata *conn, bool *done);
+
+static CURLcode ssh_getworkingpath(struct connectdata *conn,
+ char *homedir, /* when SFTP is used */
+ char **path);
+
+static CURLcode scp_done(struct connectdata *conn,
+ CURLcode, bool premature);
+static CURLcode scp_doing(struct connectdata *conn,
+ bool *dophase_done);
+static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection);
+
+static CURLcode sftp_done(struct connectdata *conn,
+ CURLcode, bool premature);
+static CURLcode sftp_doing(struct connectdata *conn,
+ bool *dophase_done);
+static CURLcode sftp_disconnect(struct connectdata *conn, bool dead);
+static
+CURLcode sftp_perform(struct connectdata *conn,
+ bool *connected,
+ bool *dophase_done);
+
+static int ssh_getsock(struct connectdata *conn,
+ curl_socket_t *sock, /* points to numsocks number
+ of sockets */
+ int numsocks);
+
+static int ssh_perform_getsock(const struct connectdata *conn,
+ curl_socket_t *sock, /* points to numsocks
+ number of sockets */
+ int numsocks);
+
+static CURLcode ssh_setup_connection(struct connectdata *conn);
+
+/*
+ * SCP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_scp = {
+ "SCP", /* scheme */
+ ssh_setup_connection, /* setup_connection */
+ ssh_do, /* do_it */
+ scp_done, /* done */
+ ZERO_NULL, /* do_more */
+ ssh_connect, /* connect_it */
+ ssh_multi_statemach, /* connecting */
+ scp_doing, /* doing */
+ ssh_getsock, /* proto_getsock */
+ ssh_getsock, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ssh_perform_getsock, /* perform_getsock */
+ scp_disconnect, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_SSH, /* defport */
+ CURLPROTO_SCP, /* protocol */
+ PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
+ | PROTOPT_NOURLQUERY /* flags */
+};
+
+
+/*
+ * SFTP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_sftp = {
+ "SFTP", /* scheme */
+ ssh_setup_connection, /* setup_connection */
+ ssh_do, /* do_it */
+ sftp_done, /* done */
+ ZERO_NULL, /* do_more */
+ ssh_connect, /* connect_it */
+ ssh_multi_statemach, /* connecting */
+ sftp_doing, /* doing */
+ ssh_getsock, /* proto_getsock */
+ ssh_getsock, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ssh_perform_getsock, /* perform_getsock */
+ sftp_disconnect, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_SSH, /* defport */
+ CURLPROTO_SFTP, /* protocol */
+ PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
+ | PROTOPT_NOURLQUERY /* flags */
+};
+
+static void
+kbd_callback(const char *name, int name_len, const char *instruction,
+ int instruction_len, int num_prompts,
+ const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
+ LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
+ void **abstract)
+{
+ struct connectdata *conn = (struct connectdata *)*abstract;
+
+#ifdef CURL_LIBSSH2_DEBUG
+ fprintf(stderr, "name=%s\n", name);
+ fprintf(stderr, "name_len=%d\n", name_len);
+ fprintf(stderr, "instruction=%s\n", instruction);
+ fprintf(stderr, "instruction_len=%d\n", instruction_len);
+ fprintf(stderr, "num_prompts=%d\n", num_prompts);
+#else
+ (void)name;
+ (void)name_len;
+ (void)instruction;
+ (void)instruction_len;
+#endif /* CURL_LIBSSH2_DEBUG */
+ if(num_prompts == 1) {
+ responses[0].text = strdup(conn->passwd);
+ responses[0].length = curlx_uztoui(strlen(conn->passwd));
+ }
+ (void)prompts;
+ (void)abstract;
+} /* kbd_callback */
+
+static CURLcode sftp_libssh2_error_to_CURLE(int err)
+{
+ switch (err) {
+ case LIBSSH2_FX_OK:
+ return CURLE_OK;
+
+ case LIBSSH2_FX_NO_SUCH_FILE:
+ case LIBSSH2_FX_NO_SUCH_PATH:
+ return CURLE_REMOTE_FILE_NOT_FOUND;
+
+ case LIBSSH2_FX_PERMISSION_DENIED:
+ case LIBSSH2_FX_WRITE_PROTECT:
+ case LIBSSH2_FX_LOCK_CONFlICT:
+ return CURLE_REMOTE_ACCESS_DENIED;
+
+ case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
+ case LIBSSH2_FX_QUOTA_EXCEEDED:
+ return CURLE_REMOTE_DISK_FULL;
+
+ case LIBSSH2_FX_FILE_ALREADY_EXISTS:
+ return CURLE_REMOTE_FILE_EXISTS;
+
+ case LIBSSH2_FX_DIR_NOT_EMPTY:
+ return CURLE_QUOTE_ERROR;
+
+ default:
+ break;
+ }
+
+ return CURLE_SSH;
+}
+
+static CURLcode libssh2_session_error_to_CURLE(int err)
+{
+ switch (err) {
+ /* Ordered by order of appearance in libssh2.h */
+ case LIBSSH2_ERROR_NONE:
+ return CURLE_OK;
+
+ case LIBSSH2_ERROR_SOCKET_NONE:
+ return CURLE_COULDNT_CONNECT;
+
+ case LIBSSH2_ERROR_ALLOC:
+ return CURLE_OUT_OF_MEMORY;
+
+ case LIBSSH2_ERROR_SOCKET_SEND:
+ return CURLE_SEND_ERROR;
+
+ case LIBSSH2_ERROR_HOSTKEY_INIT:
+ case LIBSSH2_ERROR_HOSTKEY_SIGN:
+ case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
+ case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
+ return CURLE_PEER_FAILED_VERIFICATION;
+
+ case LIBSSH2_ERROR_PASSWORD_EXPIRED:
+ return CURLE_LOGIN_DENIED;
+
+ case LIBSSH2_ERROR_SOCKET_TIMEOUT:
+ case LIBSSH2_ERROR_TIMEOUT:
+ return CURLE_OPERATION_TIMEDOUT;
+
+ case LIBSSH2_ERROR_EAGAIN:
+ return CURLE_AGAIN;
+ }
+
+ /* TODO: map some more of the libssh2 errors to the more appropriate CURLcode
+ error code, and possibly add a few new SSH-related one. We must however
+ not return or even depend on libssh2 errors in the public libcurl API */
+
+ return CURLE_SSH;
+}
+
+static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
+{
+ (void)abstract; /* arg not used */
+ return malloc(count);
+}
+
+static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)
+{
+ (void)abstract; /* arg not used */
+ return realloc(ptr, count);
+}
+
+static LIBSSH2_FREE_FUNC(my_libssh2_free)
+{
+ (void)abstract; /* arg not used */
+ if(ptr) /* ssh2 agent sometimes call free with null ptr */
+ free(ptr);
+}
+
+/*
+ * SSH State machine related code
+ */
+/* This is the ONLY way to change SSH state! */
+static void state(struct connectdata *conn, sshstate nowstate)
+{
+ struct ssh_conn *sshc = &conn->proto.sshc;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+ /* for debug purposes */
+ static const char * const names[] = {
+ "SSH_STOP",
+ "SSH_INIT",
+ "SSH_S_STARTUP",
+ "SSH_HOSTKEY",
+ "SSH_AUTHLIST",
+ "SSH_AUTH_PKEY_INIT",
+ "SSH_AUTH_PKEY",
+ "SSH_AUTH_PASS_INIT",
+ "SSH_AUTH_PASS",
+ "SSH_AUTH_AGENT_INIT",
+ "SSH_AUTH_AGENT_LIST",
+ "SSH_AUTH_AGENT",
+ "SSH_AUTH_HOST_INIT",
+ "SSH_AUTH_HOST",
+ "SSH_AUTH_KEY_INIT",
+ "SSH_AUTH_KEY",
+ "SSH_AUTH_DONE",
+ "SSH_SFTP_INIT",
+ "SSH_SFTP_REALPATH",
+ "SSH_SFTP_QUOTE_INIT",
+ "SSH_SFTP_POSTQUOTE_INIT",
+ "SSH_SFTP_QUOTE",
+ "SSH_SFTP_NEXT_QUOTE",
+ "SSH_SFTP_QUOTE_STAT",
+ "SSH_SFTP_QUOTE_SETSTAT",
+ "SSH_SFTP_QUOTE_SYMLINK",
+ "SSH_SFTP_QUOTE_MKDIR",
+ "SSH_SFTP_QUOTE_RENAME",
+ "SSH_SFTP_QUOTE_RMDIR",
+ "SSH_SFTP_QUOTE_UNLINK",
+ "SSH_SFTP_TRANS_INIT",
+ "SSH_SFTP_UPLOAD_INIT",
+ "SSH_SFTP_CREATE_DIRS_INIT",
+ "SSH_SFTP_CREATE_DIRS",
+ "SSH_SFTP_CREATE_DIRS_MKDIR",
+ "SSH_SFTP_READDIR_INIT",
+ "SSH_SFTP_READDIR",
+ "SSH_SFTP_READDIR_LINK",
+ "SSH_SFTP_READDIR_BOTTOM",
+ "SSH_SFTP_READDIR_DONE",
+ "SSH_SFTP_DOWNLOAD_INIT",
+ "SSH_SFTP_DOWNLOAD_STAT",
+ "SSH_SFTP_CLOSE",
+ "SSH_SFTP_SHUTDOWN",
+ "SSH_SCP_TRANS_INIT",
+ "SSH_SCP_UPLOAD_INIT",
+ "SSH_SCP_DOWNLOAD_INIT",
+ "SSH_SCP_DONE",
+ "SSH_SCP_SEND_EOF",
+ "SSH_SCP_WAIT_EOF",
+ "SSH_SCP_WAIT_CLOSE",
+ "SSH_SCP_CHANNEL_FREE",
+ "SSH_SESSION_DISCONNECT",
+ "SSH_SESSION_FREE",
+ "QUIT"
+ };
+
+ if(sshc->state != nowstate) {
+ infof(conn->data, "SFTP %p state change from %s to %s\n",
+ (void *)sshc, names[sshc->state], names[nowstate]);
+ }
+#endif
+
+ sshc->state = nowstate;
+}
+
+/* figure out the path to work with in this particular request */
+static CURLcode ssh_getworkingpath(struct connectdata *conn,
+ char *homedir, /* when SFTP is used */
+ char **path) /* returns the allocated
+ real path to work with */
+{
+ struct SessionHandle *data = conn->data;
+ char *real_path = NULL;
+ char *working_path;
+ int working_path_len;
+
+ working_path = curl_easy_unescape(data, data->state.path, 0,
+ &working_path_len);
+ if(!working_path)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Check for /~/ , indicating relative to the user's home directory */
+ if(conn->handler->protocol & CURLPROTO_SCP) {
+ real_path = malloc(working_path_len+1);
+ if(real_path == NULL) {
+ free(working_path);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ if((working_path_len > 3) && (!memcmp(working_path, "/~/", 3)))
+ /* It is referenced to the home directory, so strip the leading '/~/' */
+ memcpy(real_path, working_path+3, 4 + working_path_len-3);
+ else
+ memcpy(real_path, working_path, 1 + working_path_len);
+ }
+ else if(conn->handler->protocol & CURLPROTO_SFTP) {
+ if((working_path_len > 1) && (working_path[1] == '~')) {
+ size_t homelen = strlen(homedir);
+ real_path = malloc(homelen + working_path_len + 1);
+ if(real_path == NULL) {
+ free(working_path);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ /* It is referenced to the home directory, so strip the
+ leading '/' */
+ memcpy(real_path, homedir, homelen);
+ real_path[homelen] = '/';
+ real_path[homelen+1] = '\0';
+ if(working_path_len > 3) {
+ memcpy(real_path+homelen+1, working_path + 3,
+ 1 + working_path_len -3);
+ }
+ }
+ else {
+ real_path = malloc(working_path_len+1);
+ if(real_path == NULL) {
+ free(working_path);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ memcpy(real_path, working_path, 1+working_path_len);
+ }
+ }
+
+ free(working_path);
+
+ /* store the pointer for the caller to receive */
+ *path = real_path;
+
+ return CURLE_OK;
+}
+
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+static int sshkeycallback(CURL *easy,
+ const struct curl_khkey *knownkey, /* known */
+ const struct curl_khkey *foundkey, /* found */
+ enum curl_khmatch match,
+ void *clientp)
+{
+ (void)easy;
+ (void)knownkey;
+ (void)foundkey;
+ (void)clientp;
+
+ /* we only allow perfect matches, and we reject everything else */
+ return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
+}
+#endif
+
+/*
+ * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
+ * with 32bit size_t.
+ */
+#ifdef HAVE_LIBSSH2_SFTP_SEEK64
+#define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
+#else
+#define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
+#endif
+
+/*
+ * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit
+ * architectures so we check of the necessary function is present.
+ */
+#ifndef HAVE_LIBSSH2_SCP_SEND64
+#define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
+#else
+#define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c), \
+ (libssh2_uint64_t)d, 0, 0)
+#endif
+
+/*
+ * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64.
+ */
+#ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE
+#define libssh2_session_startup(x,y) libssh2_session_handshake(x,y)
+#endif
+
+static CURLcode ssh_knownhost(struct connectdata *conn)
+{
+ CURLcode result = CURLE_OK;
+
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+ struct SessionHandle *data = conn->data;
+
+ if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
+ /* we're asked to verify the host against a file */
+ struct ssh_conn *sshc = &conn->proto.sshc;
+ int rc;
+ int keytype;
+ size_t keylen;
+ const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
+ &keylen, &keytype);
+ int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE;
+ int keybit = 0;
+
+ if(remotekey) {
+ /*
+ * A subject to figure out is what host name we need to pass in here.
+ * What host name does OpenSSH store in its file if an IDN name is
+ * used?
+ */
+ struct libssh2_knownhost *host;
+ enum curl_khmatch keymatch;
+ curl_sshkeycallback func =
+ data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
+ struct curl_khkey knownkey;
+ struct curl_khkey *knownkeyp = NULL;
+ struct curl_khkey foundkey;
+
+ keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
+ LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
+
+#ifdef HAVE_LIBSSH2_KNOWNHOST_CHECKP
+ keycheck = libssh2_knownhost_checkp(sshc->kh,
+ conn->host.name,
+ (conn->remote_port != PORT_SSH)?
+ conn->remote_port:-1,
+ remotekey, keylen,
+ LIBSSH2_KNOWNHOST_TYPE_PLAIN|
+ LIBSSH2_KNOWNHOST_KEYENC_RAW|
+ keybit,
+ &host);
+#else
+ keycheck = libssh2_knownhost_check(sshc->kh,
+ conn->host.name,
+ remotekey, keylen,
+ LIBSSH2_KNOWNHOST_TYPE_PLAIN|
+ LIBSSH2_KNOWNHOST_KEYENC_RAW|
+ keybit,
+ &host);
+#endif
+
+ infof(data, "SSH host check: %d, key: %s\n", keycheck,
+ (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
+ host->key:"<none>");
+
+ /* setup 'knownkey' */
+ if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
+ knownkey.key = host->key;
+ knownkey.len = 0;
+ knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
+ CURLKHTYPE_RSA : CURLKHTYPE_DSS;
+ knownkeyp = &knownkey;
+ }
+
+ /* setup 'foundkey' */
+ foundkey.key = remotekey;
+ foundkey.len = keylen;
+ foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
+ CURLKHTYPE_RSA : CURLKHTYPE_DSS;
+
+ /*
+ * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
+ * curl_khmatch enum are ever modified, we need to introduce a
+ * translation table here!
+ */
+ keymatch = (enum curl_khmatch)keycheck;
+
+ /* Ask the callback how to behave */
+ rc = func(data, knownkeyp, /* from the knownhosts file */
+ &foundkey, /* from the remote host */
+ keymatch, data->set.ssh_keyfunc_userp);
+ }
+ else
+ /* no remotekey means failure! */
+ rc = CURLKHSTAT_REJECT;
+
+ switch(rc) {
+ default: /* unknown return codes will equal reject */
+ /* FALLTHROUGH */
+ case CURLKHSTAT_REJECT:
+ state(conn, SSH_SESSION_FREE);
+ /* FALLTHROUGH */
+ case CURLKHSTAT_DEFER:
+ /* DEFER means bail out but keep the SSH_HOSTKEY state */
+ result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
+ break;
+ case CURLKHSTAT_FINE:
+ case CURLKHSTAT_FINE_ADD_TO_FILE:
+ /* proceed */
+ if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
+ /* the found host+key didn't match but has been told to be fine
+ anyway so we add it in memory */
+ int addrc = libssh2_knownhost_add(sshc->kh,
+ conn->host.name, NULL,
+ remotekey, keylen,
+ LIBSSH2_KNOWNHOST_TYPE_PLAIN|
+ LIBSSH2_KNOWNHOST_KEYENC_RAW|
+ keybit, NULL);
+ if(addrc)
+ infof(data, "Warning adding the known host %s failed!\n",
+ conn->host.name);
+ else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
+ /* now we write the entire in-memory list of known hosts to the
+ known_hosts file */
+ int wrc =
+ libssh2_knownhost_writefile(sshc->kh,
+ data->set.str[STRING_SSH_KNOWNHOSTS],
+ LIBSSH2_KNOWNHOST_FILE_OPENSSH);
+ if(wrc) {
+ infof(data, "Warning, writing %s failed!\n",
+ data->set.str[STRING_SSH_KNOWNHOSTS]);
+ }
+ }
+ }
+ break;
+ }
+ }
+#else /* HAVE_LIBSSH2_KNOWNHOST_API */
+ (void)conn;
+#endif
+ return result;
+}
+
+static CURLcode ssh_check_fingerprint(struct connectdata *conn)
+{
+ struct ssh_conn *sshc = &conn->proto.sshc;
+ struct SessionHandle *data = conn->data;
+ const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5];
+ char md5buffer[33];
+ int i;
+
+ const char *fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
+ LIBSSH2_HOSTKEY_HASH_MD5);
+
+ if(fingerprint) {
+ /* The fingerprint points to static storage (!), don't free() it. */
+ for(i = 0; i < 16; i++)
+ snprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
+ infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);
+ }
+
+ /* Before we authenticate we check the hostkey's MD5 fingerprint
+ * against a known fingerprint, if available.
+ */
+ if(pubkey_md5 && strlen(pubkey_md5) == 32) {
+ if(!fingerprint || !strequal(md5buffer, pubkey_md5)) {
+ if(fingerprint)
+ failf(data,
+ "Denied establishing ssh session: mismatch md5 fingerprint. "
+ "Remote %s is not equal to %s", md5buffer, pubkey_md5);
+ else
+ failf(data,
+ "Denied establishing ssh session: md5 fingerprint not available");
+ state(conn, SSH_SESSION_FREE);
+ sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
+ return sshc->actualcode;
+ }
+ else {
+ infof(data, "MD5 checksum match!\n");
+ /* as we already matched, we skip the check for known hosts */
+ return CURLE_OK;
+ }
+ }
+ else
+ return ssh_knownhost(conn);
+}
+
+/*
+ * ssh_statemach_act() runs the SSH state machine as far as it can without
+ * blocking and without reaching the end. The data the pointer 'block' points
+ * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
+ * meaning it wants to be called again when the socket is ready
+ */
+
+static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct SSHPROTO *sftp_scp = data->req.protop;
+ struct ssh_conn *sshc = &conn->proto.sshc;
+ curl_socket_t sock = conn->sock[FIRSTSOCKET];
+ char *new_readdir_line;
+ int rc = LIBSSH2_ERROR_NONE;
+ int err;
+ int seekerr = CURL_SEEKFUNC_OK;
+ *block = 0; /* we're not blocking by default */
+
+ do {
+
+ switch(sshc->state) {
+ case SSH_INIT:
+ sshc->secondCreateDirs = 0;
+ sshc->nextstate = SSH_NO_STATE;
+ sshc->actualcode = CURLE_OK;
+
+ /* Set libssh2 to non-blocking, since everything internally is
+ non-blocking */
+ libssh2_session_set_blocking(sshc->ssh_session, 0);
+
+ state(conn, SSH_S_STARTUP);
+ /* fall-through */
+
+ case SSH_S_STARTUP:
+ rc = libssh2_session_startup(sshc->ssh_session, (int)sock);
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
+ break;
+ }
+ else if(rc) {
+ failf(data, "Failure establishing ssh session");
+ state(conn, SSH_SESSION_FREE);
+ sshc->actualcode = CURLE_FAILED_INIT;
+ break;
+ }
+
+ state(conn, SSH_HOSTKEY);
+
+ /* fall-through */
+ case SSH_HOSTKEY:
+ /*
+ * Before we authenticate we should check the hostkey's fingerprint
+ * against our known hosts. How that is handled (reading from file,
+ * whatever) is up to us.
+ */
+ result = ssh_check_fingerprint(conn);
+ if(!result)
+ state(conn, SSH_AUTHLIST);
+ /* ssh_check_fingerprint sets state appropriately on error */
+ break;
+
+ case SSH_AUTHLIST:
+ /*
+ * Figure out authentication methods
+ * NB: As soon as we have provided a username to an openssh server we
+ * must never change it later. Thus, always specify the correct username
+ * here, even though the libssh2 docs kind of indicate that it should be
+ * possible to get a 'generic' list (not user-specific) of authentication
+ * methods, presumably with a blank username. That won't work in my
+ * experience.
+ * So always specify it here.
+ */
+ sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
+ conn->user,
+ curlx_uztoui(strlen(conn->user)));
+
+ if(!sshc->authlist) {
+ if(libssh2_userauth_authenticated(sshc->ssh_session)) {
+ sshc->authed = TRUE;
+ infof(data, "SSH user accepted with no authentication\n");
+ state(conn, SSH_AUTH_DONE);
+ break;
+ }
+ else if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
+ LIBSSH2_ERROR_EAGAIN) {
+ rc = LIBSSH2_ERROR_EAGAIN;
+ break;
+ }
+ else {
+ state(conn, SSH_SESSION_FREE);
+ sshc->actualcode = libssh2_session_error_to_CURLE(err);
+ break;
+ }
+ }
+ infof(data, "SSH authentication methods available: %s\n",
+ sshc->authlist);
+
+ state(conn, SSH_AUTH_PKEY_INIT);
+ break;
+
+ case SSH_AUTH_PKEY_INIT:
+ /*
+ * Check the supported auth types in the order I feel is most secure
+ * with the requested type of authentication
+ */
+ sshc->authed = FALSE;
+
+ if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
+ (strstr(sshc->authlist, "publickey") != NULL)) {
+ char *home = NULL;
+ bool out_of_memory = FALSE;
+
+ sshc->rsa_pub = sshc->rsa = NULL;
+
+ /* To ponder about: should really the lib be messing about with the
+ HOME environment variable etc? */
+ home = curl_getenv("HOME");
+
+ if(data->set.str[STRING_SSH_PRIVATE_KEY])
+ sshc->rsa = strdup(data->set.str[STRING_SSH_PRIVATE_KEY]);
+ else {
+ /* If no private key file is specified, try some common paths. */
+ if(home) {
+ /* Try ~/.ssh first. */
+ sshc->rsa = aprintf("%s/.ssh/id_rsa", home);
+ if(!sshc->rsa)
+ out_of_memory = TRUE;
+ else if(access(sshc->rsa, R_OK) != 0) {
+ Curl_safefree(sshc->rsa);
+ sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
+ if(!sshc->rsa)
+ out_of_memory = TRUE;
+ else if(access(sshc->rsa, R_OK) != 0) {
+ Curl_safefree(sshc->rsa);
+ }
+ }
+ }
+ if(!out_of_memory && !sshc->rsa) {
+ /* Nothing found; try the current dir. */
+ sshc->rsa = strdup("id_rsa");
+ if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
+ Curl_safefree(sshc->rsa);
+ sshc->rsa = strdup("id_dsa");
+ if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
+ Curl_safefree(sshc->rsa);
+ /* Out of guesses. Set to the empty string to avoid
+ * surprising info messages. */
+ sshc->rsa = strdup("");
+ }
+ }
+ }
+ }
+
+ /*
+ * Unless the user explicitly specifies a public key file, let
+ * libssh2 extract the public key from the private key file.
+ * This is done by simply passing sshc->rsa_pub = NULL.
+ */
+ if(data->set.str[STRING_SSH_PUBLIC_KEY]) {
+ sshc->rsa_pub = strdup(data->set.str[STRING_SSH_PUBLIC_KEY]);
+ if(!sshc->rsa_pub)
+ out_of_memory = TRUE;
+ }
+
+ if(out_of_memory || sshc->rsa == NULL) {
+ free(home);
+ Curl_safefree(sshc->rsa);
+ Curl_safefree(sshc->rsa_pub);
+ state(conn, SSH_SESSION_FREE);
+ sshc->actualcode = CURLE_OUT_OF_MEMORY;
+ break;
+ }
+
+ sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
+ if(!sshc->passphrase)
+ sshc->passphrase = "";
+
+ free(home);
+
+ infof(data, "Using SSH public key file '%s'\n", sshc->rsa_pub);
+ infof(data, "Using SSH private key file '%s'\n", sshc->rsa);
+
+ state(conn, SSH_AUTH_PKEY);
+ }
+ else {
+ state(conn, SSH_AUTH_PASS_INIT);
+ }
+ break;
+
+ case SSH_AUTH_PKEY:
+ /* The function below checks if the files exists, no need to stat() here.
+ */
+ rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
+ conn->user,
+ curlx_uztoui(
+ strlen(conn->user)),
+ sshc->rsa_pub,
+ sshc->rsa, sshc->passphrase);
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
+ break;
+ }
+
+ Curl_safefree(sshc->rsa_pub);
+ Curl_safefree(sshc->rsa);
+
+ if(rc == 0) {
+ sshc->authed = TRUE;
+ infof(data, "Initialized SSH public key authentication\n");
+ state(conn, SSH_AUTH_DONE);
+ }
+ else {
+ char *err_msg;
+ (void)libssh2_session_last_error(sshc->ssh_session,
+ &err_msg, NULL, 0);
+ infof(data, "SSH public key authentication failed: %s\n", err_msg);
+ state(conn, SSH_AUTH_PASS_INIT);
+ }
+ break;
+
+ case SSH_AUTH_PASS_INIT:
+ if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
+ (strstr(sshc->authlist, "password") != NULL)) {
+ state(conn, SSH_AUTH_PASS);
+ }
+ else {
+ state(conn, SSH_AUTH_HOST_INIT);
+ }
+ break;
+
+ case SSH_AUTH_PASS:
+ rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
+ curlx_uztoui(strlen(conn->user)),
+ conn->passwd,
+ curlx_uztoui(strlen(conn->passwd)),
+ NULL);
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
+ break;
+ }
+ else if(rc == 0) {
+ sshc->authed = TRUE;
+ infof(data, "Initialized password authentication\n");
+ state(conn, SSH_AUTH_DONE);
+ }
+ else {
+ state(conn, SSH_AUTH_HOST_INIT);
+ rc = 0; /* clear rc and continue */
+ }
+ break;
+
+ case SSH_AUTH_HOST_INIT:
+ if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
+ (strstr(sshc->authlist, "hostbased") != NULL)) {
+ state(conn, SSH_AUTH_HOST);
+ }
+ else {
+ state(conn, SSH_AUTH_AGENT_INIT);
+ }
+ break;
+
+ case SSH_AUTH_HOST:
+ state(conn, SSH_AUTH_AGENT_INIT);
+ break;
+
+ case SSH_AUTH_AGENT_INIT:
+#ifdef HAVE_LIBSSH2_AGENT_API
+ if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT)
+ && (strstr(sshc->authlist, "publickey") != NULL)) {
+
+ /* Connect to the ssh-agent */
+ /* The agent could be shared by a curl thread i believe
+ but nothing obvious as keys can be added/removed at any time */
+ if(!sshc->ssh_agent) {
+ sshc->ssh_agent = libssh2_agent_init(sshc->ssh_session);
+ if(!sshc->ssh_agent) {
+ infof(data, "Could not create agent object\n");
+
+ state(conn, SSH_AUTH_KEY_INIT);
+ break;
+ }
+ }
+
+ rc = libssh2_agent_connect(sshc->ssh_agent);
+ if(rc == LIBSSH2_ERROR_EAGAIN)
+ break;
+ if(rc < 0) {
+ infof(data, "Failure connecting to agent\n");
+ state(conn, SSH_AUTH_KEY_INIT);
+ }
+ else {
+ state(conn, SSH_AUTH_AGENT_LIST);
+ }
+ }
+ else
+#endif /* HAVE_LIBSSH2_AGENT_API */
+ state(conn, SSH_AUTH_KEY_INIT);
+ break;
+
+ case SSH_AUTH_AGENT_LIST:
+#ifdef HAVE_LIBSSH2_AGENT_API
+ rc = libssh2_agent_list_identities(sshc->ssh_agent);
+
+ if(rc == LIBSSH2_ERROR_EAGAIN)
+ break;
+ if(rc < 0) {
+ infof(data, "Failure requesting identities to agent\n");
+ state(conn, SSH_AUTH_KEY_INIT);
+ }
+ else {
+ state(conn, SSH_AUTH_AGENT);
+ sshc->sshagent_prev_identity = NULL;
+ }
+#endif
+ break;
+
+ case SSH_AUTH_AGENT:
+#ifdef HAVE_LIBSSH2_AGENT_API
+ /* as prev_identity evolves only after an identity user auth finished we
+ can safely request it again as long as EAGAIN is returned here or by
+ libssh2_agent_userauth */
+ rc = libssh2_agent_get_identity(sshc->ssh_agent,
+ &sshc->sshagent_identity,
+ sshc->sshagent_prev_identity);
+ if(rc == LIBSSH2_ERROR_EAGAIN)
+ break;
+
+ if(rc == 0) {
+ rc = libssh2_agent_userauth(sshc->ssh_agent, conn->user,
+ sshc->sshagent_identity);
+
+ if(rc < 0) {
+ if(rc != LIBSSH2_ERROR_EAGAIN)
+ /* tried and failed? go to next identity */
+ sshc->sshagent_prev_identity = sshc->sshagent_identity;
+ else
+ break;
+ }
+ }
+
+ if(rc < 0)
+ infof(data, "Failure requesting identities to agent\n");
+ else if(rc == 1)
+ infof(data, "No identity would match\n");
+
+ if(rc == LIBSSH2_ERROR_NONE) {
+ sshc->authed = TRUE;
+ infof(data, "Agent based authentication successful\n");
+ state(conn, SSH_AUTH_DONE);
+ }
+ else {
+ state(conn, SSH_AUTH_KEY_INIT);
+ rc = 0; /* clear rc and continue */
+ }
+#endif
+ break;
+
+ case SSH_AUTH_KEY_INIT:
+ if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
+ && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
+ state(conn, SSH_AUTH_KEY);
+ }
+ else {
+ state(conn, SSH_AUTH_DONE);
+ }
+ break;
+
+ case SSH_AUTH_KEY:
+ /* Authentication failed. Continue with keyboard-interactive now. */
+ rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
+ conn->user,
+ curlx_uztoui(
+ strlen(conn->user)),
+ &kbd_callback);
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
+ break;
+ }
+ else if(rc == 0) {
+ sshc->authed = TRUE;
+ infof(data, "Initialized keyboard interactive authentication\n");
+ }
+ state(conn, SSH_AUTH_DONE);
+ break;
+
+ case SSH_AUTH_DONE:
+ if(!sshc->authed) {
+ failf(data, "Authentication failure");
+ state(conn, SSH_SESSION_FREE);
+ sshc->actualcode = CURLE_LOGIN_DENIED;
+ break;
+ }
+
+ /*
+ * At this point we have an authenticated ssh session.
+ */
+ infof(data, "Authentication complete\n");
+
+ Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
+
+ conn->sockfd = sock;
+ conn->writesockfd = CURL_SOCKET_BAD;
+
+ if(conn->handler->protocol == CURLPROTO_SFTP) {
+ state(conn, SSH_SFTP_INIT);
+ break;
+ }
+ infof(data, "SSH CONNECT phase done\n");
+ state(conn, SSH_STOP);
+ break;
+
+ case SSH_SFTP_INIT:
+ /*
+ * Start the libssh2 sftp session
+ */
+ sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
+ if(!sshc->sftp_session) {
+ if(libssh2_session_last_errno(sshc->ssh_session) ==
+ LIBSSH2_ERROR_EAGAIN) {
+ rc = LIBSSH2_ERROR_EAGAIN;
+ break;
+ }
+ else {
+ char *err_msg;
+
+ (void)libssh2_session_last_error(sshc->ssh_session,
+ &err_msg, NULL, 0);
+ failf(data, "Failure initializing sftp session: %s", err_msg);
+ state(conn, SSH_SESSION_FREE);
+ sshc->actualcode = CURLE_FAILED_INIT;
+ break;
+ }
+ }
+ state(conn, SSH_SFTP_REALPATH);
+ break;
+
+ case SSH_SFTP_REALPATH:
+ {
+ char tempHome[PATH_MAX];
+
+ /*
+ * Get the "home" directory
+ */
+ rc = sftp_libssh2_realpath(sshc->sftp_session, ".",
+ tempHome, PATH_MAX-1);
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
+ break;
+ }
+ else if(rc > 0) {
+ /* It seems that this string is not always NULL terminated */
+ tempHome[rc] = '\0';
+ sshc->homedir = strdup(tempHome);
+ if(!sshc->homedir) {
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->actualcode = CURLE_OUT_OF_MEMORY;
+ break;
+ }
+ conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
+ }
+ else {
+ /* Return the error type */
+ err = sftp_libssh2_last_error(sshc->sftp_session);
+ result = sftp_libssh2_error_to_CURLE(err);
+ sshc->actualcode = result?result:CURLE_SSH;
+ DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
+ err, (int)result));
+ state(conn, SSH_STOP);
+ break;
+ }
+ }
+ /* This is the last step in the SFTP connect phase. Do note that while
+ we get the homedir here, we get the "workingpath" in the DO action
+ since the homedir will remain the same between request but the
+ working path will not. */
+ DEBUGF(infof(data, "SSH CONNECT phase done\n"));
+ state(conn, SSH_STOP);
+ break;
+
+ case SSH_SFTP_QUOTE_INIT:
+
+ result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
+ if(result) {
+ sshc->actualcode = result;
+ state(conn, SSH_STOP);
+ break;
+ }
+
+ if(data->set.quote) {
+ infof(data, "Sending quote commands\n");
+ sshc->quote_item = data->set.quote;
+ state(conn, SSH_SFTP_QUOTE);
+ }
+ else {
+ state(conn, SSH_SFTP_TRANS_INIT);
+ }
+ break;
+
+ case SSH_SFTP_POSTQUOTE_INIT:
+ if(data->set.postquote) {
+ infof(data, "Sending quote commands\n");
+ sshc->quote_item = data->set.postquote;
+ state(conn, SSH_SFTP_QUOTE);
+ }
+ else {
+ state(conn, SSH_STOP);
+ }
+ break;
+
+ case SSH_SFTP_QUOTE:
+ /* Send any quote commands */
+ {
+ const char *cp;
+
+ /*
+ * Support some of the "FTP" commands
+ */
+ char *cmd = sshc->quote_item->data;
+ sshc->acceptfail = FALSE;
+
+ /* if a command starts with an asterisk, which a legal SFTP command never
+ can, the command will be allowed to fail without it causing any
+ aborts or cancels etc. It will cause libcurl to act as if the command
+ is successful, whatever the server reponds. */
+
+ if(cmd[0] == '*') {
+ cmd++;
+ sshc->acceptfail = TRUE;
+ }
+
+ if(curl_strequal("pwd", cmd)) {
+ /* output debug output if that is requested */
+ char *tmp = aprintf("257 \"%s\" is current directory.\n",
+ sftp_scp->path);
+ if(!tmp) {
+ result = CURLE_OUT_OF_MEMORY;
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->nextstate = SSH_NO_STATE;
+ break;
+ }
+ if(data->set.verbose) {
+ Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
+ Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
+ }
+ /* this sends an FTP-like "header" to the header callback so that the
+ current directory can be read very similar to how it is read when
+ using ordinary FTP. */
+ result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
+ free(tmp);
+ if(result) {
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->nextstate = SSH_NO_STATE;
+ sshc->actualcode = result;
+ }
+ else
+ state(conn, SSH_SFTP_NEXT_QUOTE);
+ break;
+ }
+ else if(cmd) {
+ /*
+ * the arguments following the command must be separated from the
+ * command with a space so we can check for it unconditionally
+ */
+ cp = strchr(cmd, ' ');
+ if(cp == NULL) {
+ failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->nextstate = SSH_NO_STATE;
+ sshc->actualcode = CURLE_QUOTE_ERROR;
+ break;
+ }
+
+ /*
+ * also, every command takes at least one argument so we get that
+ * first argument right now
+ */
+ result = get_pathname(&cp, &sshc->quote_path1);
+ if(result) {
+ if(result == CURLE_OUT_OF_MEMORY)
+ failf(data, "Out of memory");
+ else
+ failf(data, "Syntax error: Bad first parameter");
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->nextstate = SSH_NO_STATE;
+ sshc->actualcode = result;
+ break;
+ }
+
+ /*
+ * SFTP is a binary protocol, so we don't send text commands
+ * to the server. Instead, we scan for commands used by
+ * OpenSSH's sftp program and call the appropriate libssh2
+ * functions.
+ */
+ if(curl_strnequal(cmd, "chgrp ", 6) ||
+ curl_strnequal(cmd, "chmod ", 6) ||
+ curl_strnequal(cmd, "chown ", 6) ) {
+ /* attribute change */
+
+ /* sshc->quote_path1 contains the mode to set */
+ /* get the destination */
+ result = get_pathname(&cp, &sshc->quote_path2);
+ if(result) {
+ if(result == CURLE_OUT_OF_MEMORY)
+ failf(data, "Out of memory");
+ else
+ failf(data, "Syntax error in chgrp/chmod/chown: "
+ "Bad second parameter");
+ Curl_safefree(sshc->quote_path1);
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->nextstate = SSH_NO_STATE;
+ sshc->actualcode = result;
+ break;
+ }
+ memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
+ state(conn, SSH_SFTP_QUOTE_STAT);
+ break;
+ }
+ else if(curl_strnequal(cmd, "ln ", 3) ||
+ curl_strnequal(cmd, "symlink ", 8)) {
+ /* symbolic linking */
+ /* sshc->quote_path1 is the source */
+ /* get the destination */
+ result = get_pathname(&cp, &sshc->quote_path2);
+ if(result) {
+ if(result == CURLE_OUT_OF_MEMORY)
+ failf(data, "Out of memory");
+ else
+ failf(data,
+ "Syntax error in ln/symlink: Bad second parameter");
+ Curl_safefree(sshc->quote_path1);
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->nextstate = SSH_NO_STATE;
+ sshc->actualcode = result;
+ break;
+ }
+ state(conn, SSH_SFTP_QUOTE_SYMLINK);
+ break;
+ }
+ else if(curl_strnequal(cmd, "mkdir ", 6)) {
+ /* create dir */
+ state(conn, SSH_SFTP_QUOTE_MKDIR);
+ break;
+ }
+ else if(curl_strnequal(cmd, "rename ", 7)) {
+ /* rename file */
+ /* first param is the source path */
+ /* second param is the dest. path */
+ result = get_pathname(&cp, &sshc->quote_path2);
+ if(result) {
+ if(result == CURLE_OUT_OF_MEMORY)
+ failf(data, "Out of memory");
+ else
+ failf(data, "Syntax error in rename: Bad second parameter");
+ Curl_safefree(sshc->quote_path1);
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->nextstate = SSH_NO_STATE;
+ sshc->actualcode = result;
+ break;
+ }
+ state(conn, SSH_SFTP_QUOTE_RENAME);
+ break;
+ }
+ else if(curl_strnequal(cmd, "rmdir ", 6)) {
+ /* delete dir */
+ state(conn, SSH_SFTP_QUOTE_RMDIR);
+ break;
+ }
+ else if(curl_strnequal(cmd, "rm ", 3)) {
+ state(conn, SSH_SFTP_QUOTE_UNLINK);
+ break;
+ }
+
+ failf(data, "Unknown SFTP command");
+ Curl_safefree(sshc->quote_path1);
+ Curl_safefree(sshc->quote_path2);
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->nextstate = SSH_NO_STATE;
+ sshc->actualcode = CURLE_QUOTE_ERROR;
+ break;
+ }
+ }
+ if(!sshc->quote_item) {
+ state(conn, SSH_SFTP_TRANS_INIT);
+ }
+ break;
+
+ case SSH_SFTP_NEXT_QUOTE:
+ Curl_safefree(sshc->quote_path1);
+ Curl_safefree(sshc->quote_path2);
+
+ sshc->quote_item = sshc->quote_item->next;
+
+ if(sshc->quote_item) {
+ state(conn, SSH_SFTP_QUOTE);
+ }
+ else {
+ if(sshc->nextstate != SSH_NO_STATE) {
+ state(conn, sshc->nextstate);
+ sshc->nextstate = SSH_NO_STATE;
+ }
+ else {
+ state(conn, SSH_SFTP_TRANS_INIT);
+ }
+ }
+ break;
+
+ case SSH_SFTP_QUOTE_STAT:
+ {
+ char *cmd = sshc->quote_item->data;
+ sshc->acceptfail = FALSE;
+
+ /* if a command starts with an asterisk, which a legal SFTP command never
+ can, the command will be allowed to fail without it causing any
+ aborts or cancels etc. It will cause libcurl to act as if the command
+ is successful, whatever the server reponds. */
+
+ if(cmd[0] == '*') {
+ cmd++;
+ sshc->acceptfail = TRUE;
+ }
+
+ if(!curl_strnequal(cmd, "chmod", 5)) {
+ /* Since chown and chgrp only set owner OR group but libssh2 wants to
+ * set them both at once, we need to obtain the current ownership
+ * first. This takes an extra protocol round trip.
+ */
+ rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
+ curlx_uztoui(strlen(sshc->quote_path2)),
+ LIBSSH2_SFTP_STAT,
+ &sshc->quote_attrs);
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
+ break;
+ }
+ else if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
+ err = sftp_libssh2_last_error(sshc->sftp_session);
+ Curl_safefree(sshc->quote_path1);
+ Curl_safefree(sshc->quote_path2);
+ failf(data, "Attempt to get SFTP stats failed: %s",
+ sftp_libssh2_strerror(err));
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->nextstate = SSH_NO_STATE;
+ sshc->actualcode = CURLE_QUOTE_ERROR;
+ break;
+ }
+ }
+
+ /* Now set the new attributes... */
+ if(curl_strnequal(cmd, "chgrp", 5)) {
+ sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
+ sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
+ if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
+ !sshc->acceptfail) {
+ Curl_safefree(sshc->quote_path1);
+ Curl_safefree(sshc->quote_path2);
+ failf(data, "Syntax error: chgrp gid not a number");
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->nextstate = SSH_NO_STATE;
+ sshc->actualcode = CURLE_QUOTE_ERROR;
+ break;
+ }
+ }
+ else if(curl_strnequal(cmd, "chmod", 5)) {
+ sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
+ sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
+ /* permissions are octal */
+ if(sshc->quote_attrs.permissions == 0 &&
+ !ISDIGIT(sshc->quote_path1[0])) {
+ Curl_safefree(sshc->quote_path1);
+ Curl_safefree(sshc->quote_path2);
+ failf(data, "Syntax error: chmod permissions not a number");
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->nextstate = SSH_NO_STATE;
+ sshc->actualcode = CURLE_QUOTE_ERROR;
+ break;
+ }
+ }
+ else if(curl_strnequal(cmd, "chown", 5)) {
+ sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
+ sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
+ if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
+ !sshc->acceptfail) {
+ Curl_safefree(sshc->quote_path1);
+ Curl_safefree(sshc->quote_path2);
+ failf(data, "Syntax error: chown uid not a number");
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->nextstate = SSH_NO_STATE;
+ sshc->actualcode = CURLE_QUOTE_ERROR;
+ break;
+ }
+ }
+
+ /* Now send the completed structure... */
+ state(conn, SSH_SFTP_QUOTE_SETSTAT);
+ break;
+ }
+
+ case SSH_SFTP_QUOTE_SETSTAT:
+ rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
+ curlx_uztoui(strlen(sshc->quote_path2)),
+ LIBSSH2_SFTP_SETSTAT,
+ &sshc->quote_attrs);
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
+ break;
+ }
+ else if(rc != 0 && !sshc->acceptfail) {
+ err = sftp_libssh2_last_error(sshc->sftp_session);
+ Curl_safefree(sshc->quote_path1);
+ Curl_safefree(sshc->quote_path2);
+ failf(data, "Attempt to set SFTP stats failed: %s",
+ sftp_libssh2_strerror(err));
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->nextstate = SSH_NO_STATE;
+ sshc->actualcode = CURLE_QUOTE_ERROR;
+ break;
+ }
+ state(conn, SSH_SFTP_NEXT_QUOTE);
+ break;
+
+ case SSH_SFTP_QUOTE_SYMLINK:
+ rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
+ curlx_uztoui(strlen(sshc->quote_path1)),
+ sshc->quote_path2,
+ curlx_uztoui(strlen(sshc->quote_path2)),
+ LIBSSH2_SFTP_SYMLINK);
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
+ break;
+ }
+ else if(rc != 0 && !sshc->acceptfail) {
+ err = sftp_libssh2_last_error(sshc->sftp_session);
+ Curl_safefree(sshc->quote_path1);
+ Curl_safefree(sshc->quote_path2);
+ failf(data, "symlink command failed: %s",
+ sftp_libssh2_strerror(err));
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->nextstate = SSH_NO_STATE;
+ sshc->actualcode = CURLE_QUOTE_ERROR;
+ break;
+ }
+ state(conn, SSH_SFTP_NEXT_QUOTE);
+ break;
+
+ case SSH_SFTP_QUOTE_MKDIR:
+ rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
+ curlx_uztoui(strlen(sshc->quote_path1)),
+ data->set.new_directory_perms);
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
+ break;
+ }
+ else if(rc != 0 && !sshc->acceptfail) {
+ err = sftp_libssh2_last_error(sshc->sftp_session);
+ Curl_safefree(sshc->quote_path1);
+ failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->nextstate = SSH_NO_STATE;
+ sshc->actualcode = CURLE_QUOTE_ERROR;
+ break;
+ }
+ state(conn, SSH_SFTP_NEXT_QUOTE);
+ break;
+
+ case SSH_SFTP_QUOTE_RENAME:
+ rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
+ curlx_uztoui(strlen(sshc->quote_path1)),
+ sshc->quote_path2,
+ curlx_uztoui(strlen(sshc->quote_path2)),
+ LIBSSH2_SFTP_RENAME_OVERWRITE |
+ LIBSSH2_SFTP_RENAME_ATOMIC |
+ LIBSSH2_SFTP_RENAME_NATIVE);
+
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
+ break;
+ }
+ else if(rc != 0 && !sshc->acceptfail) {
+ err = sftp_libssh2_last_error(sshc->sftp_session);
+ Curl_safefree(sshc->quote_path1);
+ Curl_safefree(sshc->quote_path2);
+ failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->nextstate = SSH_NO_STATE;
+ sshc->actualcode = CURLE_QUOTE_ERROR;
+ break;
+ }
+ state(conn, SSH_SFTP_NEXT_QUOTE);
+ break;
+
+ case SSH_SFTP_QUOTE_RMDIR:
+ rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
+ curlx_uztoui(strlen(sshc->quote_path1)));
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
+ break;
+ }
+ else if(rc != 0 && !sshc->acceptfail) {
+ err = sftp_libssh2_last_error(sshc->sftp_session);
+ Curl_safefree(sshc->quote_path1);
+ failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->nextstate = SSH_NO_STATE;
+ sshc->actualcode = CURLE_QUOTE_ERROR;
+ break;
+ }
+ state(conn, SSH_SFTP_NEXT_QUOTE);
+ break;
+
+ case SSH_SFTP_QUOTE_UNLINK:
+ rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
+ curlx_uztoui(strlen(sshc->quote_path1)));
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
+ break;
+ }
+ else if(rc != 0 && !sshc->acceptfail) {
+ err = sftp_libssh2_last_error(sshc->sftp_session);
+ Curl_safefree(sshc->quote_path1);
+ failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->nextstate = SSH_NO_STATE;
+ sshc->actualcode = CURLE_QUOTE_ERROR;
+ break;
+ }
+ state(conn, SSH_SFTP_NEXT_QUOTE);
+ break;
+
+ case SSH_SFTP_TRANS_INIT:
+ if(data->set.upload)
+ state(conn, SSH_SFTP_UPLOAD_INIT);
+ else {
+ if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
+ state(conn, SSH_SFTP_READDIR_INIT);
+ else
+ state(conn, SSH_SFTP_DOWNLOAD_INIT);
+ }
+ break;
+
+ case SSH_SFTP_UPLOAD_INIT:
+ {
+ unsigned long flags;
+ /*
+ * NOTE!!! libssh2 requires that the destination path is a full path
+ * that includes the destination file and name OR ends in a "/"
+ * If this is not done the destination file will be named the
+ * same name as the last directory in the path.
+ */
+
+ if(data->state.resume_from != 0) {
+ LIBSSH2_SFTP_ATTRIBUTES attrs;
+ if(data->state.resume_from < 0) {
+ rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
+ curlx_uztoui(strlen(sftp_scp->path)),
+ LIBSSH2_SFTP_STAT, &attrs);
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
+ break;
+ }
+ else if(rc) {
+ data->state.resume_from = 0;
+ }
+ else {
+ curl_off_t size = attrs.filesize;
+ if(size < 0) {
+ failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
+ return CURLE_BAD_DOWNLOAD_RESUME;
+ }
+ data->state.resume_from = attrs.filesize;
+ }
+ }
+ }
+
+ if(data->set.ftp_append)
+ /* Try to open for append, but create if nonexisting */
+ flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
+ else if(data->state.resume_from > 0)
+ /* If we have restart position then open for append */
+ flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
+ else
+ /* Clear file before writing (normal behaviour) */
+ flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
+
+ sshc->sftp_handle =
+ libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
+ curlx_uztoui(strlen(sftp_scp->path)),
+ flags, data->set.new_file_perms,
+ LIBSSH2_SFTP_OPENFILE);
+
+ if(!sshc->sftp_handle) {
+ rc = libssh2_session_last_errno(sshc->ssh_session);
+
+ if(LIBSSH2_ERROR_EAGAIN == rc)
+ break;
+ else {
+ if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
+ /* only when there was an SFTP protocol error can we extract
+ the sftp error! */
+ err = sftp_libssh2_last_error(sshc->sftp_session);
+ else
+ err = -1; /* not an sftp error at all */
+
+ if(sshc->secondCreateDirs) {
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->actualcode = err>= LIBSSH2_FX_OK?
+ sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
+ failf(data, "Creating the dir/file failed: %s",
+ sftp_libssh2_strerror(err));
+ break;
+ }
+ else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
+ (err == LIBSSH2_FX_FAILURE) ||
+ (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
+ (data->set.ftp_create_missing_dirs &&
+ (strlen(sftp_scp->path) > 1))) {
+ /* try to create the path remotely */
+ sshc->secondCreateDirs = 1;
+ state(conn, SSH_SFTP_CREATE_DIRS_INIT);
+ break;
+ }
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->actualcode = err>= LIBSSH2_FX_OK?
+ sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
+ if(!sshc->actualcode) {
+ /* Sometimes, for some reason libssh2_sftp_last_error() returns
+ zero even though libssh2_sftp_open() failed previously! We need
+ to work around that! */
+ sshc->actualcode = CURLE_SSH;
+ err=-1;
+ }
+ failf(data, "Upload failed: %s (%d/%d)",
+ err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
+ err, rc);
+ break;
+ }
+ }
+
+ /* If we have a restart point then we need to seek to the correct
+ position. */
+ if(data->state.resume_from > 0) {
+ /* Let's read off the proper amount of bytes from the input. */
+ if(conn->seek_func) {
+ seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
+ SEEK_SET);
+ }
+
+ if(seekerr != CURL_SEEKFUNC_OK) {
+
+ if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
+ failf(data, "Could not seek stream");
+ return CURLE_FTP_COULDNT_USE_REST;
+ }
+ /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
+ else {
+ curl_off_t passed=0;
+ do {
+ size_t readthisamountnow =
+ (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
+ BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
+
+ size_t actuallyread =
+ data->set.fread_func(data->state.buffer, 1, readthisamountnow,
+ data->set.in);
+
+ passed += actuallyread;
+ if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
+ /* this checks for greater-than only to make sure that the
+ CURL_READFUNC_ABORT return code still aborts */
+ failf(data, "Failed to read data");
+ return CURLE_FTP_COULDNT_USE_REST;
+ }
+ } while(passed < data->state.resume_from);
+ }
+ }
+
+ /* now, decrease the size of the read */
+ if(data->state.infilesize > 0) {
+ data->state.infilesize -= data->state.resume_from;
+ data->req.size = data->state.infilesize;
+ Curl_pgrsSetUploadSize(data, data->state.infilesize);
+ }
+
+ SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
+ }
+ if(data->state.infilesize > 0) {
+ data->req.size = data->state.infilesize;
+ Curl_pgrsSetUploadSize(data, data->state.infilesize);
+ }
+ /* upload data */
+ Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
+
+ /* not set by Curl_setup_transfer to preserve keepon bits */
+ conn->sockfd = conn->writesockfd;
+
+ if(result) {
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->actualcode = result;
+ }
+ else {
+ /* store this original bitmask setup to use later on if we can't
+ figure out a "real" bitmask */
+ sshc->orig_waitfor = data->req.keepon;
+
+ /* we want to use the _sending_ function even when the socket turns
+ out readable as the underlying libssh2 sftp send function will deal
+ with both accordingly */
+ conn->cselect_bits = CURL_CSELECT_OUT;
+
+ /* since we don't really wait for anything at this point, we want the
+ state machine to move on as soon as possible so we set a very short
+ timeout here */
+ Curl_expire(data, 1);
+
+ state(conn, SSH_STOP);
+ }
+ break;
+ }
+
+ case SSH_SFTP_CREATE_DIRS_INIT:
+ if(strlen(sftp_scp->path) > 1) {
+ sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
+ state(conn, SSH_SFTP_CREATE_DIRS);
+ }
+ else {
+ state(conn, SSH_SFTP_UPLOAD_INIT);
+ }
+ break;
+
+ case SSH_SFTP_CREATE_DIRS:
+ sshc->slash_pos = strchr(sshc->slash_pos, '/');
+ if(sshc->slash_pos) {
+ *sshc->slash_pos = 0;
+
+ infof(data, "Creating directory '%s'\n", sftp_scp->path);
+ state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
+ break;
+ }
+ else {
+ state(conn, SSH_SFTP_UPLOAD_INIT);
+ }
+ break;
+
+ case SSH_SFTP_CREATE_DIRS_MKDIR:
+ /* 'mode' - parameter is preliminary - default to 0644 */
+ rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
+ curlx_uztoui(strlen(sftp_scp->path)),
+ data->set.new_directory_perms);
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
+ break;
+ }
+ *sshc->slash_pos = '/';
+ ++sshc->slash_pos;
+ if(rc == -1) {
+ /*
+ * Abort if failure wasn't that the dir already exists or the
+ * permission was denied (creation might succeed further down the
+ * path) - retry on unspecific FAILURE also
+ */
+ err = sftp_libssh2_last_error(sshc->sftp_session);
+ if((err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
+ (err != LIBSSH2_FX_FAILURE) &&
+ (err != LIBSSH2_FX_PERMISSION_DENIED)) {
+ result = sftp_libssh2_error_to_CURLE(err);
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->actualcode = result?result:CURLE_SSH;
+ break;
+ }
+ }
+ state(conn, SSH_SFTP_CREATE_DIRS);
+ break;
+
+ case SSH_SFTP_READDIR_INIT:
+ Curl_pgrsSetDownloadSize(data, -1);
+ if(data->set.opt_no_body) {
+ state(conn, SSH_STOP);
+ break;
+ }
+
+ /*
+ * This is a directory that we are trying to get, so produce a directory
+ * listing
+ */
+ sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
+ sftp_scp->path,
+ curlx_uztoui(
+ strlen(sftp_scp->path)),
+ 0, 0, LIBSSH2_SFTP_OPENDIR);
+ if(!sshc->sftp_handle) {
+ if(libssh2_session_last_errno(sshc->ssh_session) ==
+ LIBSSH2_ERROR_EAGAIN) {
+ rc = LIBSSH2_ERROR_EAGAIN;
+ break;
+ }
+ else {
+ err = sftp_libssh2_last_error(sshc->sftp_session);
+ failf(data, "Could not open directory for reading: %s",
+ sftp_libssh2_strerror(err));
+ state(conn, SSH_SFTP_CLOSE);
+ result = sftp_libssh2_error_to_CURLE(err);
+ sshc->actualcode = result?result:CURLE_SSH;
+ break;
+ }
+ }
+ if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) {
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->actualcode = CURLE_OUT_OF_MEMORY;
+ break;
+ }
+ if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) {
+ Curl_safefree(sshc->readdir_filename);
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->actualcode = CURLE_OUT_OF_MEMORY;
+ break;
+ }
+ state(conn, SSH_SFTP_READDIR);
+ break;
+
+ case SSH_SFTP_READDIR:
+ sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
+ sshc->readdir_filename,
+ PATH_MAX,
+ sshc->readdir_longentry,
+ PATH_MAX,
+ &sshc->readdir_attrs);
+ if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
+ rc = LIBSSH2_ERROR_EAGAIN;
+ break;
+ }
+ if(sshc->readdir_len > 0) {
+ sshc->readdir_filename[sshc->readdir_len] = '\0';
+
+ if(data->set.ftp_list_only) {
+ char *tmpLine;
+
+ tmpLine = aprintf("%s\n", sshc->readdir_filename);
+ if(tmpLine == NULL) {
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->actualcode = CURLE_OUT_OF_MEMORY;
+ break;
+ }
+ result = Curl_client_write(conn, CLIENTWRITE_BODY,
+ tmpLine, sshc->readdir_len+1);
+ free(tmpLine);
+
+ if(result) {
+ state(conn, SSH_STOP);
+ break;
+ }
+ /* since this counts what we send to the client, we include the
+ newline in this counter */
+ data->req.bytecount += sshc->readdir_len+1;
+
+ /* output debug output if that is requested */
+ if(data->set.verbose) {
+ Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
+ sshc->readdir_len, conn);
+ }
+ }
+ else {
+ sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
+ sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
+ sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
+ if(!sshc->readdir_line) {
+ Curl_safefree(sshc->readdir_filename);
+ Curl_safefree(sshc->readdir_longentry);
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->actualcode = CURLE_OUT_OF_MEMORY;
+ break;
+ }
+
+ memcpy(sshc->readdir_line, sshc->readdir_longentry,
+ sshc->readdir_currLen);
+ if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
+ ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
+ LIBSSH2_SFTP_S_IFLNK)) {
+ sshc->readdir_linkPath = malloc(PATH_MAX + 1);
+ if(sshc->readdir_linkPath == NULL) {
+ Curl_safefree(sshc->readdir_filename);
+ Curl_safefree(sshc->readdir_longentry);
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->actualcode = CURLE_OUT_OF_MEMORY;
+ break;
+ }
+
+ snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
+ sshc->readdir_filename);
+ state(conn, SSH_SFTP_READDIR_LINK);
+ break;
+ }
+ state(conn, SSH_SFTP_READDIR_BOTTOM);
+ break;
+ }
+ }
+ else if(sshc->readdir_len == 0) {
+ Curl_safefree(sshc->readdir_filename);
+ Curl_safefree(sshc->readdir_longentry);
+ state(conn, SSH_SFTP_READDIR_DONE);
+ break;
+ }
+ else if(sshc->readdir_len <= 0) {
+ err = sftp_libssh2_last_error(sshc->sftp_session);
+ result = sftp_libssh2_error_to_CURLE(err);
+ sshc->actualcode = result?result:CURLE_SSH;
+ failf(data, "Could not open remote file for reading: %s :: %d",
+ sftp_libssh2_strerror(err),
+ libssh2_session_last_errno(sshc->ssh_session));
+ Curl_safefree(sshc->readdir_filename);
+ Curl_safefree(sshc->readdir_longentry);
+ state(conn, SSH_SFTP_CLOSE);
+ break;
+ }
+ break;
+
+ case SSH_SFTP_READDIR_LINK:
+ sshc->readdir_len =
+ libssh2_sftp_symlink_ex(sshc->sftp_session,
+ sshc->readdir_linkPath,
+ curlx_uztoui(strlen(sshc->readdir_linkPath)),
+ sshc->readdir_filename,
+ PATH_MAX, LIBSSH2_SFTP_READLINK);
+ if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
+ rc = LIBSSH2_ERROR_EAGAIN;
+ break;
+ }
+ Curl_safefree(sshc->readdir_linkPath);
+
+ /* get room for the filename and extra output */
+ sshc->readdir_totalLen += 4 + sshc->readdir_len;
+ new_readdir_line = realloc(sshc->readdir_line, sshc->readdir_totalLen);
+ if(!new_readdir_line) {
+ Curl_safefree(sshc->readdir_line);
+ Curl_safefree(sshc->readdir_filename);
+ Curl_safefree(sshc->readdir_longentry);
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->actualcode = CURLE_OUT_OF_MEMORY;
+ break;
+ }
+ sshc->readdir_line = new_readdir_line;
+
+ sshc->readdir_currLen += snprintf(sshc->readdir_line +
+ sshc->readdir_currLen,
+ sshc->readdir_totalLen -
+ sshc->readdir_currLen,
+ " -> %s",
+ sshc->readdir_filename);
+
+ state(conn, SSH_SFTP_READDIR_BOTTOM);
+ break;
+
+ case SSH_SFTP_READDIR_BOTTOM:
+ sshc->readdir_currLen += snprintf(sshc->readdir_line +
+ sshc->readdir_currLen,
+ sshc->readdir_totalLen -
+ sshc->readdir_currLen, "\n");
+ result = Curl_client_write(conn, CLIENTWRITE_BODY,
+ sshc->readdir_line,
+ sshc->readdir_currLen);
+
+ if(!result) {
+
+ /* output debug output if that is requested */
+ if(data->set.verbose) {
+ Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
+ sshc->readdir_currLen, conn);
+ }
+ data->req.bytecount += sshc->readdir_currLen;
+ }
+ Curl_safefree(sshc->readdir_line);
+ if(result) {
+ state(conn, SSH_STOP);
+ }
+ else
+ state(conn, SSH_SFTP_READDIR);
+ break;
+
+ case SSH_SFTP_READDIR_DONE:
+ if(libssh2_sftp_closedir(sshc->sftp_handle) ==
+ LIBSSH2_ERROR_EAGAIN) {
+ rc = LIBSSH2_ERROR_EAGAIN;
+ break;
+ }
+ sshc->sftp_handle = NULL;
+ Curl_safefree(sshc->readdir_filename);
+ Curl_safefree(sshc->readdir_longentry);
+
+ /* no data to transfer */
+ Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+ state(conn, SSH_STOP);
+ break;
+
+ case SSH_SFTP_DOWNLOAD_INIT:
+ /*
+ * Work on getting the specified file
+ */
+ sshc->sftp_handle =
+ libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
+ curlx_uztoui(strlen(sftp_scp->path)),
+ LIBSSH2_FXF_READ, data->set.new_file_perms,
+ LIBSSH2_SFTP_OPENFILE);
+ if(!sshc->sftp_handle) {
+ if(libssh2_session_last_errno(sshc->ssh_session) ==
+ LIBSSH2_ERROR_EAGAIN) {
+ rc = LIBSSH2_ERROR_EAGAIN;
+ break;
+ }
+ else {
+ err = sftp_libssh2_last_error(sshc->sftp_session);
+ failf(data, "Could not open remote file for reading: %s",
+ sftp_libssh2_strerror(err));
+ state(conn, SSH_SFTP_CLOSE);
+ result = sftp_libssh2_error_to_CURLE(err);
+ sshc->actualcode = result?result:CURLE_SSH;
+ break;
+ }
+ }
+ state(conn, SSH_SFTP_DOWNLOAD_STAT);
+ break;
+
+ case SSH_SFTP_DOWNLOAD_STAT:
+ {
+ LIBSSH2_SFTP_ATTRIBUTES attrs;
+
+ rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
+ curlx_uztoui(strlen(sftp_scp->path)),
+ LIBSSH2_SFTP_STAT, &attrs);
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
+ break;
+ }
+ else if(rc ||
+ !(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) ||
+ (attrs.filesize == 0)) {
+ /*
+ * libssh2_sftp_open() didn't return an error, so maybe the server
+ * just doesn't support stat()
+ * OR the server doesn't return a file size with a stat()
+ * OR file size is 0
+ */
+ data->req.size = -1;
+ data->req.maxdownload = -1;
+ Curl_pgrsSetDownloadSize(data, -1);
+ }
+ else {
+ curl_off_t size = attrs.filesize;
+
+ if(size < 0) {
+ failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
+ return CURLE_BAD_DOWNLOAD_RESUME;
+ }
+ if(conn->data->state.use_range) {
+ curl_off_t from, to;
+ char *ptr;
+ char *ptr2;
+
+ from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
+ while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
+ ptr++;
+ to=curlx_strtoofft(ptr, &ptr2, 0);
+ if((ptr == ptr2) /* no "to" value given */
+ || (to >= size)) {
+ to = size - 1;
+ }
+ if(from < 0) {
+ /* from is relative to end of file */
+ from += size;
+ }
+ if(from > size) {
+ failf(data, "Offset (%"
+ CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
+ CURL_FORMAT_CURL_OFF_T ")", from, attrs.filesize);
+ return CURLE_BAD_DOWNLOAD_RESUME;
+ }
+ if(from > to) {
+ from = to;
+ size = 0;
+ }
+ else {
+ size = to - from + 1;
+ }
+
+ SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
+ }
+ data->req.size = size;
+ data->req.maxdownload = size;
+ Curl_pgrsSetDownloadSize(data, size);
+ }
+
+ /* We can resume if we can seek to the resume position */
+ if(data->state.resume_from) {
+ if(data->state.resume_from < 0) {
+ /* We're supposed to download the last abs(from) bytes */
+ if((curl_off_t)attrs.filesize < -data->state.resume_from) {
+ failf(data, "Offset (%"
+ CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
+ CURL_FORMAT_CURL_OFF_T ")",
+ data->state.resume_from, attrs.filesize);
+ return CURLE_BAD_DOWNLOAD_RESUME;
+ }
+ /* download from where? */
+ data->state.resume_from += attrs.filesize;
+ }
+ else {
+ if((curl_off_t)attrs.filesize < data->state.resume_from) {
+ failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
+ ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
+ data->state.resume_from, attrs.filesize);
+ return CURLE_BAD_DOWNLOAD_RESUME;
+ }
+ }
+ /* Does a completed file need to be seeked and started or closed ? */
+ /* Now store the number of bytes we are expected to download */
+ data->req.size = attrs.filesize - data->state.resume_from;
+ data->req.maxdownload = attrs.filesize - data->state.resume_from;
+ Curl_pgrsSetDownloadSize(data,
+ attrs.filesize - data->state.resume_from);
+ SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
+ }
+ }
+
+ /* Setup the actual download */
+ if(data->req.size == 0) {
+ /* no data to transfer */
+ Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+ infof(data, "File already completely downloaded\n");
+ state(conn, SSH_STOP);
+ break;
+ }
+ else {
+ Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
+ FALSE, NULL, -1, NULL);
+
+ /* not set by Curl_setup_transfer to preserve keepon bits */
+ conn->writesockfd = conn->sockfd;
+
+ /* we want to use the _receiving_ function even when the socket turns
+ out writableable as the underlying libssh2 recv function will deal
+ with both accordingly */
+ conn->cselect_bits = CURL_CSELECT_IN;
+ }
+ if(result) {
+ /* this should never occur; the close state should be entered
+ at the time the error occurs */
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->actualcode = result;
+ }
+ else {
+ state(conn, SSH_STOP);
+ }
+ break;
+
+ case SSH_SFTP_CLOSE:
+ if(sshc->sftp_handle) {
+ rc = libssh2_sftp_close(sshc->sftp_handle);
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
+ break;
+ }
+ else if(rc < 0) {
+ infof(data, "Failed to close libssh2 file\n");
+ }
+ sshc->sftp_handle = NULL;
+ }
+ if(sftp_scp)
+ Curl_safefree(sftp_scp->path);
+
+ DEBUGF(infof(data, "SFTP DONE done\n"));
+
+ /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
+ After nextstate is executed, the control should come back to
+ SSH_SFTP_CLOSE to pass the correct result back */
+ if(sshc->nextstate != SSH_NO_STATE &&
+ sshc->nextstate != SSH_SFTP_CLOSE) {
+ state(conn, sshc->nextstate);
+ sshc->nextstate = SSH_SFTP_CLOSE;
+ }
+ else {
+ state(conn, SSH_STOP);
+ result = sshc->actualcode;
+ }
+ break;
+
+ case SSH_SFTP_SHUTDOWN:
+ /* during times we get here due to a broken transfer and then the
+ sftp_handle might not have been taken down so make sure that is done
+ before we proceed */
+
+ if(sshc->sftp_handle) {
+ rc = libssh2_sftp_close(sshc->sftp_handle);
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
+ break;
+ }
+ else if(rc < 0) {
+ infof(data, "Failed to close libssh2 file\n");
+ }
+ sshc->sftp_handle = NULL;
+ }
+ if(sshc->sftp_session) {
+ rc = libssh2_sftp_shutdown(sshc->sftp_session);
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
+ break;
+ }
+ else if(rc < 0) {
+ infof(data, "Failed to stop libssh2 sftp subsystem\n");
+ }
+ sshc->sftp_session = NULL;
+ }
+
+ Curl_safefree(sshc->homedir);
+ conn->data->state.most_recent_ftp_entrypath = NULL;
+
+ state(conn, SSH_SESSION_DISCONNECT);
+ break;
+
+ case SSH_SCP_TRANS_INIT:
+ result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
+ if(result) {
+ sshc->actualcode = result;
+ state(conn, SSH_STOP);
+ break;
+ }
+
+ if(data->set.upload) {
+ if(data->state.infilesize < 0) {
+ failf(data, "SCP requires a known file size for upload");
+ sshc->actualcode = CURLE_UPLOAD_FAILED;
+ state(conn, SSH_SCP_CHANNEL_FREE);
+ break;
+ }
+ state(conn, SSH_SCP_UPLOAD_INIT);
+ }
+ else {
+ state(conn, SSH_SCP_DOWNLOAD_INIT);
+ }
+ break;
+
+ case SSH_SCP_UPLOAD_INIT:
+ /*
+ * libssh2 requires that the destination path is a full path that
+ * includes the destination file and name OR ends in a "/" . If this is
+ * not done the destination file will be named the same name as the last
+ * directory in the path.
+ */
+ sshc->ssh_channel =
+ SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
+ data->state.infilesize);
+ if(!sshc->ssh_channel) {
+ if(libssh2_session_last_errno(sshc->ssh_session) ==
+ LIBSSH2_ERROR_EAGAIN) {
+ rc = LIBSSH2_ERROR_EAGAIN;
+ break;
+ }
+ else {
+ int ssh_err;
+ char *err_msg;
+
+ ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
+ &err_msg, NULL, 0));
+ failf(conn->data, "%s", err_msg);
+ state(conn, SSH_SCP_CHANNEL_FREE);
+ sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
+ break;
+ }
+ }
+
+ /* upload data */
+ Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
+ FIRSTSOCKET, NULL);
+
+ /* not set by Curl_setup_transfer to preserve keepon bits */
+ conn->sockfd = conn->writesockfd;
+
+ if(result) {
+ state(conn, SSH_SCP_CHANNEL_FREE);
+ sshc->actualcode = result;
+ }
+ else {
+ /* store this original bitmask setup to use later on if we can't
+ figure out a "real" bitmask */
+ sshc->orig_waitfor = data->req.keepon;
+
+ /* we want to use the _sending_ function even when the socket turns
+ out readable as the underlying libssh2 scp send function will deal
+ with both accordingly */
+ conn->cselect_bits = CURL_CSELECT_OUT;
+
+ state(conn, SSH_STOP);
+ }
+ break;
+
+ case SSH_SCP_DOWNLOAD_INIT:
+ {
+ /*
+ * We must check the remote file; if it is a directory no values will
+ * be set in sb
+ */
+ struct stat sb;
+ curl_off_t bytecount;
+
+ /* clear the struct scp recv will fill in */
+ memset(&sb, 0, sizeof(struct stat));
+
+ /* get a fresh new channel from the ssh layer */
+ sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
+ sftp_scp->path, &sb);
+ if(!sshc->ssh_channel) {
+ if(libssh2_session_last_errno(sshc->ssh_session) ==
+ LIBSSH2_ERROR_EAGAIN) {
+ rc = LIBSSH2_ERROR_EAGAIN;
+ break;
+ }
+ else {
+ int ssh_err;
+ char *err_msg;
+
+ ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
+ &err_msg, NULL, 0));
+ failf(conn->data, "%s", err_msg);
+ state(conn, SSH_SCP_CHANNEL_FREE);
+ sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
+ break;
+ }
+ }
+
+ /* download data */
+ bytecount = (curl_off_t)sb.st_size;
+ data->req.maxdownload = (curl_off_t)sb.st_size;
+ Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
+
+ /* not set by Curl_setup_transfer to preserve keepon bits */
+ conn->writesockfd = conn->sockfd;
+
+ /* we want to use the _receiving_ function even when the socket turns
+ out writableable as the underlying libssh2 recv function will deal
+ with both accordingly */
+ conn->cselect_bits = CURL_CSELECT_IN;
+
+ if(result) {
+ state(conn, SSH_SCP_CHANNEL_FREE);
+ sshc->actualcode = result;
+ }
+ else
+ state(conn, SSH_STOP);
+ }
+ break;
+
+ case SSH_SCP_DONE:
+ if(data->set.upload)
+ state(conn, SSH_SCP_SEND_EOF);
+ else
+ state(conn, SSH_SCP_CHANNEL_FREE);
+ break;
+
+ case SSH_SCP_SEND_EOF:
+ if(sshc->ssh_channel) {
+ rc = libssh2_channel_send_eof(sshc->ssh_channel);
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
+ break;
+ }
+ else if(rc) {
+ infof(data, "Failed to send libssh2 channel EOF\n");
+ }
+ }
+ state(conn, SSH_SCP_WAIT_EOF);
+ break;
+
+ case SSH_SCP_WAIT_EOF:
+ if(sshc->ssh_channel) {
+ rc = libssh2_channel_wait_eof(sshc->ssh_channel);
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
+ break;
+ }
+ else if(rc) {
+ infof(data, "Failed to get channel EOF: %d\n", rc);
+ }
+ }
+ state(conn, SSH_SCP_WAIT_CLOSE);
+ break;
+
+ case SSH_SCP_WAIT_CLOSE:
+ if(sshc->ssh_channel) {
+ rc = libssh2_channel_wait_closed(sshc->ssh_channel);
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
+ break;
+ }
+ else if(rc) {
+ infof(data, "Channel failed to close: %d\n", rc);
+ }
+ }
+ state(conn, SSH_SCP_CHANNEL_FREE);
+ break;
+
+ case SSH_SCP_CHANNEL_FREE:
+ if(sshc->ssh_channel) {
+ rc = libssh2_channel_free(sshc->ssh_channel);
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
+ break;
+ }
+ else if(rc < 0) {
+ infof(data, "Failed to free libssh2 scp subsystem\n");
+ }
+ sshc->ssh_channel = NULL;
+ }
+ DEBUGF(infof(data, "SCP DONE phase complete\n"));
+#if 0 /* PREV */
+ state(conn, SSH_SESSION_DISCONNECT);
+#endif
+ state(conn, SSH_STOP);
+ result = sshc->actualcode;
+ break;
+
+ case SSH_SESSION_DISCONNECT:
+ /* during weird times when we've been prematurely aborted, the channel
+ is still alive when we reach this state and we MUST kill the channel
+ properly first */
+ if(sshc->ssh_channel) {
+ rc = libssh2_channel_free(sshc->ssh_channel);
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
+ break;
+ }
+ else if(rc < 0) {
+ infof(data, "Failed to free libssh2 scp subsystem\n");
+ }
+ sshc->ssh_channel = NULL;
+ }
+
+ if(sshc->ssh_session) {
+ rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
+ break;
+ }
+ else if(rc < 0) {
+ infof(data, "Failed to disconnect libssh2 session\n");
+ }
+ }
+
+ Curl_safefree(sshc->homedir);
+ conn->data->state.most_recent_ftp_entrypath = NULL;
+
+ state(conn, SSH_SESSION_FREE);
+ break;
+
+ case SSH_SESSION_FREE:
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+ if(sshc->kh) {
+ libssh2_knownhost_free(sshc->kh);
+ sshc->kh = NULL;
+ }
+#endif
+
+#ifdef HAVE_LIBSSH2_AGENT_API
+ if(sshc->ssh_agent) {
+ rc = libssh2_agent_disconnect(sshc->ssh_agent);
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
+ break;
+ }
+ else if(rc < 0) {
+ infof(data, "Failed to disconnect from libssh2 agent\n");
+ }
+ libssh2_agent_free (sshc->ssh_agent);
+ sshc->ssh_agent = NULL;
+
+ /* NB: there is no need to free identities, they are part of internal
+ agent stuff */
+ sshc->sshagent_identity = NULL;
+ sshc->sshagent_prev_identity = NULL;
+ }
+#endif
+
+ if(sshc->ssh_session) {
+ rc = libssh2_session_free(sshc->ssh_session);
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
+ break;
+ }
+ else if(rc < 0) {
+ infof(data, "Failed to free libssh2 session\n");
+ }
+ sshc->ssh_session = NULL;
+ }
+
+ /* worst-case scenario cleanup */
+
+ DEBUGASSERT(sshc->ssh_session == NULL);
+ DEBUGASSERT(sshc->ssh_channel == NULL);
+ DEBUGASSERT(sshc->sftp_session == NULL);
+ DEBUGASSERT(sshc->sftp_handle == NULL);
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+ DEBUGASSERT(sshc->kh == NULL);
+#endif
+#ifdef HAVE_LIBSSH2_AGENT_API
+ DEBUGASSERT(sshc->ssh_agent == NULL);
+#endif
+
+ Curl_safefree(sshc->rsa_pub);
+ Curl_safefree(sshc->rsa);
+
+ Curl_safefree(sshc->quote_path1);
+ Curl_safefree(sshc->quote_path2);
+
+ Curl_safefree(sshc->homedir);
+
+ Curl_safefree(sshc->readdir_filename);
+ Curl_safefree(sshc->readdir_longentry);
+ Curl_safefree(sshc->readdir_line);
+ Curl_safefree(sshc->readdir_linkPath);
+
+ /* the code we are about to return */
+ result = sshc->actualcode;
+
+ memset(sshc, 0, sizeof(struct ssh_conn));
+
+ connclose(conn, "SSH session free");
+ sshc->state = SSH_SESSION_FREE; /* current */
+ sshc->nextstate = SSH_NO_STATE;
+ state(conn, SSH_STOP);
+ break;
+
+ case SSH_QUIT:
+ /* fallthrough, just stop! */
+ default:
+ /* internal error */
+ sshc->nextstate = SSH_NO_STATE;
+ state(conn, SSH_STOP);
+ break;
+ }
+
+ } while(!rc && (sshc->state != SSH_STOP));
+
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
+ /* we would block, we need to wait for the socket to be ready (in the
+ right direction too)! */
+ *block = TRUE;
+ }
+
+ return result;
+}
+
+/* called by the multi interface to figure out what socket(s) to wait for and
+ for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
+static int ssh_perform_getsock(const struct connectdata *conn,
+ curl_socket_t *sock, /* points to numsocks
+ number of sockets */
+ int numsocks)
+{
+#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
+ int bitmap = GETSOCK_BLANK;
+ (void)numsocks;
+
+ sock[0] = conn->sock[FIRSTSOCKET];
+
+ if(conn->waitfor & KEEP_RECV)
+ bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
+
+ if(conn->waitfor & KEEP_SEND)
+ bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
+
+ return bitmap;
+#else
+ /* if we don't know the direction we can use the generic *_getsock()
+ function even for the protocol_connect and doing states */
+ return Curl_single_getsock(conn, sock, numsocks);
+#endif
+}
+
+/* Generic function called by the multi interface to figure out what socket(s)
+ to wait for and for what actions during the DOING and PROTOCONNECT states*/
+static int ssh_getsock(struct connectdata *conn,
+ curl_socket_t *sock, /* points to numsocks number
+ of sockets */
+ int numsocks)
+{
+#ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
+ (void)conn;
+ (void)sock;
+ (void)numsocks;
+ /* if we don't know any direction we can just play along as we used to and
+ not provide any sensible info */
+ return GETSOCK_BLANK;
+#else
+ /* if we know the direction we can use the generic *_getsock() function even
+ for the protocol_connect and doing states */
+ return ssh_perform_getsock(conn, sock, numsocks);
+#endif
+}
+
+#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
+/*
+ * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
+ * function is used to figure out in what direction and stores this info so
+ * that the multi interface can take advantage of it. Make sure to call this
+ * function in all cases so that when it _doesn't_ return EAGAIN we can
+ * restore the default wait bits.
+ */
+static void ssh_block2waitfor(struct connectdata *conn, bool block)
+{
+ struct ssh_conn *sshc = &conn->proto.sshc;
+ int dir;
+ if(block && (dir = libssh2_session_block_directions(sshc->ssh_session))) {
+ /* translate the libssh2 define bits into our own bit defines */
+ conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
+ ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
+ }
+ else
+ /* It didn't block or libssh2 didn't reveal in which direction, put back
+ the original set */
+ conn->waitfor = sshc->orig_waitfor;
+}
+#else
+ /* no libssh2 directional support so we simply don't know */
+#define ssh_block2waitfor(x,y) Curl_nop_stmt
+#endif
+
+/* called repeatedly until done from multi.c */
+static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
+{
+ struct ssh_conn *sshc = &conn->proto.sshc;
+ CURLcode result = CURLE_OK;
+ bool block; /* we store the status and use that to provide a ssh_getsock()
+ implementation */
+
+ result = ssh_statemach_act(conn, &block);
+ *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
+ ssh_block2waitfor(conn, block);
+
+ return result;
+}
+
+static CURLcode ssh_block_statemach(struct connectdata *conn,
+ bool duringconnect)
+{
+ struct ssh_conn *sshc = &conn->proto.sshc;
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+
+ while((sshc->state != SSH_STOP) && !result) {
+ bool block;
+ long left;
+
+ result = ssh_statemach_act(conn, &block);
+ if(result)
+ break;
+
+ if(Curl_pgrsUpdate(conn))
+ return CURLE_ABORTED_BY_CALLBACK;
+ else {
+ struct timeval now = Curl_tvnow();
+ result = Curl_speedcheck(data, now);
+ if(result)
+ break;
+ }
+
+ left = Curl_timeleft(data, NULL, duringconnect);
+ if(left < 0) {
+ failf(data, "Operation timed out");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+
+#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
+ if(!result && block) {
+ int dir = libssh2_session_block_directions(sshc->ssh_session);
+ curl_socket_t sock = conn->sock[FIRSTSOCKET];
+ curl_socket_t fd_read = CURL_SOCKET_BAD;
+ curl_socket_t fd_write = CURL_SOCKET_BAD;
+ if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
+ fd_read = sock;
+ if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
+ fd_write = sock;
+ /* wait for the socket to become ready */
+ Curl_socket_ready(fd_read, fd_write,
+ left>1000?1000:left); /* ignore result */
+ }
+#endif
+
+ }
+
+ return result;
+}
+
+/*
+ * SSH setup and connection
+ */
+static CURLcode ssh_setup_connection(struct connectdata *conn)
+{
+ struct SSHPROTO *ssh;
+
+ conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO));
+ if(!ssh)
+ return CURLE_OUT_OF_MEMORY;
+
+ return CURLE_OK;
+}
+
+static Curl_recv scp_recv, sftp_recv;
+static Curl_send scp_send, sftp_send;
+
+/*
+ * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
+ * do protocol-specific actions at connect-time.
+ */
+static CURLcode ssh_connect(struct connectdata *conn, bool *done)
+{
+#ifdef CURL_LIBSSH2_DEBUG
+ curl_socket_t sock;
+#endif
+ struct ssh_conn *ssh;
+ CURLcode result;
+ struct SessionHandle *data = conn->data;
+
+ /* initialize per-handle data if not already */
+ if(!data->req.protop)
+ ssh_setup_connection(conn);
+
+ /* We default to persistent connections. We set this already in this connect
+ function to make the re-use checks properly be able to check this bit. */
+ connkeep(conn, "SSH default");
+
+ if(conn->handler->protocol & CURLPROTO_SCP) {
+ conn->recv[FIRSTSOCKET] = scp_recv;
+ conn->send[FIRSTSOCKET] = scp_send;
+ }
+ else {
+ conn->recv[FIRSTSOCKET] = sftp_recv;
+ conn->send[FIRSTSOCKET] = sftp_send;
+ }
+ ssh = &conn->proto.sshc;
+
+#ifdef CURL_LIBSSH2_DEBUG
+ if(conn->user) {
+ infof(data, "User: %s\n", conn->user);
+ }
+ if(conn->passwd) {
+ infof(data, "Password: %s\n", conn->passwd);
+ }
+ sock = conn->sock[FIRSTSOCKET];
+#endif /* CURL_LIBSSH2_DEBUG */
+
+ ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
+ my_libssh2_free,
+ my_libssh2_realloc, conn);
+ if(ssh->ssh_session == NULL) {
+ failf(data, "Failure initialising ssh session");
+ return CURLE_FAILED_INIT;
+ }
+
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+ if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
+ int rc;
+ ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
+ if(!ssh->kh) {
+ /* eeek. TODO: free the ssh_session! */
+ return CURLE_FAILED_INIT;
+ }
+
+ /* read all known hosts from there */
+ rc = libssh2_knownhost_readfile(ssh->kh,
+ data->set.str[STRING_SSH_KNOWNHOSTS],
+ LIBSSH2_KNOWNHOST_FILE_OPENSSH);
+ if(rc < 0)
+ infof(data, "Failed to read known hosts from %s\n",
+ data->set.str[STRING_SSH_KNOWNHOSTS]);
+ }
+#endif /* HAVE_LIBSSH2_KNOWNHOST_API */
+
+#ifdef CURL_LIBSSH2_DEBUG
+ libssh2_trace(ssh->ssh_session, ~0);
+ infof(data, "SSH socket: %d\n", (int)sock);
+#endif /* CURL_LIBSSH2_DEBUG */
+
+ state(conn, SSH_INIT);
+
+ result = ssh_multi_statemach(conn, done);
+
+ return result;
+}
+
+/*
+ ***********************************************************************
+ *
+ * scp_perform()
+ *
+ * This is the actual DO function for SCP. Get a file according to
+ * the options previously setup.
+ */
+
+static
+CURLcode scp_perform(struct connectdata *conn,
+ bool *connected,
+ bool *dophase_done)
+{
+ CURLcode result = CURLE_OK;
+
+ DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+ *dophase_done = FALSE; /* not done yet */
+
+ /* start the first command in the DO phase */
+ state(conn, SSH_SCP_TRANS_INIT);
+
+ /* run the state-machine */
+ result = ssh_multi_statemach(conn, dophase_done);
+
+ *connected = conn->bits.tcpconnect[FIRSTSOCKET];
+
+ if(*dophase_done) {
+ DEBUGF(infof(conn->data, "DO phase is complete\n"));
+ }
+
+ return result;
+}
+
+/* called from multi.c while DOing */
+static CURLcode scp_doing(struct connectdata *conn,
+ bool *dophase_done)
+{
+ CURLcode result;
+ result = ssh_multi_statemach(conn, dophase_done);
+
+ if(*dophase_done) {
+ DEBUGF(infof(conn->data, "DO phase is complete\n"));
+ }
+ return result;
+}
+
+/*
+ * The DO function is generic for both protocols. There was previously two
+ * separate ones but this way means less duplicated code.
+ */
+
+static CURLcode ssh_do(struct connectdata *conn, bool *done)
+{
+ CURLcode result;
+ bool connected = 0;
+ struct SessionHandle *data = conn->data;
+ struct ssh_conn *sshc = &conn->proto.sshc;
+
+ *done = FALSE; /* default to false */
+
+ data->req.size = -1; /* make sure this is unknown at this point */
+
+ sshc->actualcode = CURLE_OK; /* reset error code */
+ sshc->secondCreateDirs =0; /* reset the create dir attempt state
+ variable */
+
+ Curl_pgrsSetUploadCounter(data, 0);
+ Curl_pgrsSetDownloadCounter(data, 0);
+ Curl_pgrsSetUploadSize(data, -1);
+ Curl_pgrsSetDownloadSize(data, -1);
+
+ if(conn->handler->protocol & CURLPROTO_SCP)
+ result = scp_perform(conn, &connected, done);
+ else
+ result = sftp_perform(conn, &connected, done);
+
+ return result;
+}
+
+/* BLOCKING, but the function is using the state machine so the only reason
+ this is still blocking is that the multi interface code has no support for
+ disconnecting operations that takes a while */
+static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
+{
+ CURLcode result = CURLE_OK;
+ struct ssh_conn *ssh = &conn->proto.sshc;
+ (void) dead_connection;
+
+ Curl_safefree(conn->data->req.protop);
+
+ if(ssh->ssh_session) {
+ /* only if there's a session still around to use! */
+
+ state(conn, SSH_SESSION_DISCONNECT);
+
+ result = ssh_block_statemach(conn, FALSE);
+ }
+
+ return result;
+}
+
+/* generic done function for both SCP and SFTP called from their specific
+ done functions */
+static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
+{
+ CURLcode result = CURLE_OK;
+ struct SSHPROTO *sftp_scp = conn->data->req.protop;
+
+ if(!status) {
+ /* run the state-machine
+
+ TODO: when the multi interface is used, this _really_ should be using
+ the ssh_multi_statemach function but we have no general support for
+ non-blocking DONE operations, not in the multi state machine and with
+ Curl_done() invokes on several places in the code!
+ */
+ result = ssh_block_statemach(conn, FALSE);
+ }
+ else
+ result = status;
+
+ if(sftp_scp)
+ Curl_safefree(sftp_scp->path);
+ if(Curl_pgrsDone(conn))
+ return CURLE_ABORTED_BY_CALLBACK;
+
+ conn->data->req.keepon = 0; /* clear all bits */
+ return result;
+}
+
+
+static CURLcode scp_done(struct connectdata *conn, CURLcode status,
+ bool premature)
+{
+ (void)premature; /* not used */
+
+ if(!status)
+ state(conn, SSH_SCP_DONE);
+
+ return ssh_done(conn, status);
+
+}
+
+/* return number of received (decrypted) bytes */
+static ssize_t scp_send(struct connectdata *conn, int sockindex,
+ const void *mem, size_t len, CURLcode *err)
+{
+ ssize_t nwrite;
+ (void)sockindex; /* we only support SCP on the fixed known primary socket */
+
+ /* libssh2_channel_write() returns int! */
+ nwrite = (ssize_t)
+ libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
+
+ ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
+
+ if(nwrite == LIBSSH2_ERROR_EAGAIN) {
+ *err = CURLE_AGAIN;
+ nwrite = 0;
+ }
+ else if(nwrite < LIBSSH2_ERROR_NONE) {
+ *err = libssh2_session_error_to_CURLE((int)nwrite);
+ nwrite = -1;
+ }
+
+ return nwrite;
+}
+
+/*
+ * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
+ * a regular CURLcode value.
+ */
+static ssize_t scp_recv(struct connectdata *conn, int sockindex,
+ char *mem, size_t len, CURLcode *err)
+{
+ ssize_t nread;
+ (void)sockindex; /* we only support SCP on the fixed known primary socket */
+
+ /* libssh2_channel_read() returns int */
+ nread = (ssize_t)
+ libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
+
+ ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
+ if(nread == LIBSSH2_ERROR_EAGAIN) {
+ *err = CURLE_AGAIN;
+ nread = -1;
+ }
+
+ return nread;
+}
+
+/*
+ * =============== SFTP ===============
+ */
+
+/*
+ ***********************************************************************
+ *
+ * sftp_perform()
+ *
+ * This is the actual DO function for SFTP. Get a file/directory according to
+ * the options previously setup.
+ */
+
+static
+CURLcode sftp_perform(struct connectdata *conn,
+ bool *connected,
+ bool *dophase_done)
+{
+ CURLcode result = CURLE_OK;
+
+ DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+ *dophase_done = FALSE; /* not done yet */
+
+ /* start the first command in the DO phase */
+ state(conn, SSH_SFTP_QUOTE_INIT);
+
+ /* run the state-machine */
+ result = ssh_multi_statemach(conn, dophase_done);
+
+ *connected = conn->bits.tcpconnect[FIRSTSOCKET];
+
+ if(*dophase_done) {
+ DEBUGF(infof(conn->data, "DO phase is complete\n"));
+ }
+
+ return result;
+}
+
+/* called from multi.c while DOing */
+static CURLcode sftp_doing(struct connectdata *conn,
+ bool *dophase_done)
+{
+ CURLcode result = ssh_multi_statemach(conn, dophase_done);
+
+ if(*dophase_done) {
+ DEBUGF(infof(conn->data, "DO phase is complete\n"));
+ }
+ return result;
+}
+
+/* BLOCKING, but the function is using the state machine so the only reason
+ this is still blocking is that the multi interface code has no support for
+ disconnecting operations that takes a while */
+static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
+{
+ CURLcode result = CURLE_OK;
+ (void) dead_connection;
+
+ DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
+
+ Curl_safefree(conn->data->req.protop);
+
+ if(conn->proto.sshc.ssh_session) {
+ /* only if there's a session still around to use! */
+ state(conn, SSH_SFTP_SHUTDOWN);
+ result = ssh_block_statemach(conn, FALSE);
+ }
+
+ DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
+
+ return result;
+
+}
+
+static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
+ bool premature)
+{
+ struct ssh_conn *sshc = &conn->proto.sshc;
+
+ if(!status) {
+ /* Post quote commands are executed after the SFTP_CLOSE state to avoid
+ errors that could happen due to open file handles during POSTQUOTE
+ operation */
+ if(!status && !premature && conn->data->set.postquote) {
+ sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
+ state(conn, SSH_SFTP_CLOSE);
+ }
+ else
+ state(conn, SSH_SFTP_CLOSE);
+ }
+ return ssh_done(conn, status);
+}
+
+/* return number of sent bytes */
+static ssize_t sftp_send(struct connectdata *conn, int sockindex,
+ const void *mem, size_t len, CURLcode *err)
+{
+ ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
+ but is changed to ssize_t in 0.15. These days we don't
+ support libssh2 0.15*/
+ (void)sockindex;
+
+ nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
+
+ ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
+
+ if(nwrite == LIBSSH2_ERROR_EAGAIN) {
+ *err = CURLE_AGAIN;
+ nwrite = 0;
+ }
+ else if(nwrite < LIBSSH2_ERROR_NONE) {
+ *err = libssh2_session_error_to_CURLE((int)nwrite);
+ nwrite = -1;
+ }
+
+ return nwrite;
+}
+
+/*
+ * Return number of received (decrypted) bytes
+ * or <0 on error
+ */
+static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
+ char *mem, size_t len, CURLcode *err)
+{
+ ssize_t nread;
+ (void)sockindex;
+
+ nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
+
+ ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
+
+ if(nread == LIBSSH2_ERROR_EAGAIN) {
+ *err = CURLE_AGAIN;
+ nread = -1;
+
+ }
+ else if(nread < 0) {
+ *err = libssh2_session_error_to_CURLE((int)nread);
+ }
+ return nread;
+}
+
+/* The get_pathname() function is being borrowed from OpenSSH sftp.c
+ version 4.6p1. */
+/*
+ * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+static CURLcode
+get_pathname(const char **cpp, char **path)
+{
+ const char *cp = *cpp, *end;
+ char quot;
+ unsigned int i, j;
+ static const char WHITESPACE[] = " \t\r\n";
+
+ cp += strspn(cp, WHITESPACE);
+ if(!*cp) {
+ *cpp = cp;
+ *path = NULL;
+ return CURLE_QUOTE_ERROR;
+ }
+
+ *path = malloc(strlen(cp) + 1);
+ if(*path == NULL)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* Check for quoted filenames */
+ if(*cp == '\"' || *cp == '\'') {
+ quot = *cp++;
+
+ /* Search for terminating quote, unescape some chars */
+ for(i = j = 0; i <= strlen(cp); i++) {
+ if(cp[i] == quot) { /* Found quote */
+ i++;
+ (*path)[j] = '\0';
+ break;
+ }
+ if(cp[i] == '\0') { /* End of string */
+ /*error("Unterminated quote");*/
+ goto fail;
+ }
+ if(cp[i] == '\\') { /* Escaped characters */
+ i++;
+ if(cp[i] != '\'' && cp[i] != '\"' &&
+ cp[i] != '\\') {
+ /*error("Bad escaped character '\\%c'",
+ cp[i]);*/
+ goto fail;
+ }
+ }
+ (*path)[j++] = cp[i];
+ }
+
+ if(j == 0) {
+ /*error("Empty quotes");*/
+ goto fail;
+ }
+ *cpp = cp + i + strspn(cp + i, WHITESPACE);
+ }
+ else {
+ /* Read to end of filename */
+ end = strpbrk(cp, WHITESPACE);
+ if(end == NULL)
+ end = strchr(cp, '\0');
+ *cpp = end + strspn(end, WHITESPACE);
+
+ memcpy(*path, cp, end - cp);
+ (*path)[end - cp] = '\0';
+ }
+ return CURLE_OK;
+
+ fail:
+ Curl_safefree(*path);
+ return CURLE_QUOTE_ERROR;
+}
+
+
+static const char *sftp_libssh2_strerror(int err)
+{
+ switch (err) {
+ case LIBSSH2_FX_NO_SUCH_FILE:
+ return "No such file or directory";
+
+ case LIBSSH2_FX_PERMISSION_DENIED:
+ return "Permission denied";
+
+ case LIBSSH2_FX_FAILURE:
+ return "Operation failed";
+
+ case LIBSSH2_FX_BAD_MESSAGE:
+ return "Bad message from SFTP server";
+
+ case LIBSSH2_FX_NO_CONNECTION:
+ return "Not connected to SFTP server";
+
+ case LIBSSH2_FX_CONNECTION_LOST:
+ return "Connection to SFTP server lost";
+
+ case LIBSSH2_FX_OP_UNSUPPORTED:
+ return "Operation not supported by SFTP server";
+
+ case LIBSSH2_FX_INVALID_HANDLE:
+ return "Invalid handle";
+
+ case LIBSSH2_FX_NO_SUCH_PATH:
+ return "No such file or directory";
+
+ case LIBSSH2_FX_FILE_ALREADY_EXISTS:
+ return "File already exists";
+
+ case LIBSSH2_FX_WRITE_PROTECT:
+ return "File is write protected";
+
+ case LIBSSH2_FX_NO_MEDIA:
+ return "No media";
+
+ case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
+ return "Disk full";
+
+ case LIBSSH2_FX_QUOTA_EXCEEDED:
+ return "User quota exceeded";
+
+ case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
+ return "Unknown principle";
+
+ case LIBSSH2_FX_LOCK_CONFlICT:
+ return "File lock conflict";
+
+ case LIBSSH2_FX_DIR_NOT_EMPTY:
+ return "Directory not empty";
+
+ case LIBSSH2_FX_NOT_A_DIRECTORY:
+ return "Not a directory";
+
+ case LIBSSH2_FX_INVALID_FILENAME:
+ return "Invalid filename";
+
+ case LIBSSH2_FX_LINK_LOOP:
+ return "Link points to itself";
+ }
+ return "Unknown error in libssh2";
+}
+
+#endif /* USE_LIBSSH2 */
diff --git a/Utilities/cmcurl/lib/ssh.h b/Utilities/cmcurl/lib/ssh.h
new file mode 100644
index 000000000..b3cc54cca
--- /dev/null
+++ b/Utilities/cmcurl/lib/ssh.h
@@ -0,0 +1,195 @@
+#ifndef HEADER_CURL_SSH_H
+#define HEADER_CURL_SSH_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_LIBSSH2_H
+#include <libssh2.h>
+#include <libssh2_sftp.h>
+#endif /* HAVE_LIBSSH2_H */
+
+/****************************************************************************
+ * SSH unique setup
+ ***************************************************************************/
+typedef enum {
+ SSH_NO_STATE = -1, /* Used for "nextState" so say there is none */
+ SSH_STOP = 0, /* do nothing state, stops the state machine */
+
+ SSH_INIT, /* First state in SSH-CONNECT */
+ SSH_S_STARTUP, /* Session startup */
+ SSH_HOSTKEY, /* verify hostkey */
+ SSH_AUTHLIST,
+ SSH_AUTH_PKEY_INIT,
+ SSH_AUTH_PKEY,
+ SSH_AUTH_PASS_INIT,
+ SSH_AUTH_PASS,
+ SSH_AUTH_AGENT_INIT, /* initialize then wait for connection to agent */
+ SSH_AUTH_AGENT_LIST, /* ask for list then wait for entire list to come */
+ SSH_AUTH_AGENT, /* attempt one key at a time */
+ SSH_AUTH_HOST_INIT,
+ SSH_AUTH_HOST,
+ SSH_AUTH_KEY_INIT,
+ SSH_AUTH_KEY,
+ SSH_AUTH_DONE,
+ SSH_SFTP_INIT,
+ SSH_SFTP_REALPATH, /* Last state in SSH-CONNECT */
+
+ SSH_SFTP_QUOTE_INIT, /* First state in SFTP-DO */
+ SSH_SFTP_POSTQUOTE_INIT, /* (Possibly) First state in SFTP-DONE */
+ SSH_SFTP_QUOTE,
+ SSH_SFTP_NEXT_QUOTE,
+ SSH_SFTP_QUOTE_STAT,
+ SSH_SFTP_QUOTE_SETSTAT,
+ SSH_SFTP_QUOTE_SYMLINK,
+ SSH_SFTP_QUOTE_MKDIR,
+ SSH_SFTP_QUOTE_RENAME,
+ SSH_SFTP_QUOTE_RMDIR,
+ SSH_SFTP_QUOTE_UNLINK,
+ SSH_SFTP_TRANS_INIT,
+ SSH_SFTP_UPLOAD_INIT,
+ SSH_SFTP_CREATE_DIRS_INIT,
+ SSH_SFTP_CREATE_DIRS,
+ SSH_SFTP_CREATE_DIRS_MKDIR,
+ SSH_SFTP_READDIR_INIT,
+ SSH_SFTP_READDIR,
+ SSH_SFTP_READDIR_LINK,
+ SSH_SFTP_READDIR_BOTTOM,
+ SSH_SFTP_READDIR_DONE,
+ SSH_SFTP_DOWNLOAD_INIT,
+ SSH_SFTP_DOWNLOAD_STAT, /* Last state in SFTP-DO */
+ SSH_SFTP_CLOSE, /* Last state in SFTP-DONE */
+ SSH_SFTP_SHUTDOWN, /* First state in SFTP-DISCONNECT */
+ SSH_SCP_TRANS_INIT, /* First state in SCP-DO */
+ SSH_SCP_UPLOAD_INIT,
+ SSH_SCP_DOWNLOAD_INIT,
+ SSH_SCP_DONE,
+ SSH_SCP_SEND_EOF,
+ SSH_SCP_WAIT_EOF,
+ SSH_SCP_WAIT_CLOSE,
+ SSH_SCP_CHANNEL_FREE, /* Last state in SCP-DONE */
+ SSH_SESSION_DISCONNECT, /* First state in SCP-DISCONNECT */
+ SSH_SESSION_FREE, /* Last state in SCP/SFTP-DISCONNECT */
+ SSH_QUIT,
+ SSH_LAST /* never used */
+} sshstate;
+
+/* this struct is used in the HandleData struct which is part of the
+ SessionHandle, which means this is used on a per-easy handle basis.
+ Everything that is strictly related to a connection is banned from this
+ struct. */
+struct SSHPROTO {
+ char *path; /* the path we operate on */
+};
+
+/* ssh_conn is used for struct connection-oriented data in the connectdata
+ struct */
+struct ssh_conn {
+ const char *authlist; /* List of auth. methods, managed by libssh2 */
+#ifdef USE_LIBSSH2
+ const char *passphrase; /* pass-phrase to use */
+ char *rsa_pub; /* path name */
+ char *rsa; /* path name */
+ bool authed; /* the connection has been authenticated fine */
+ sshstate state; /* always use ssh.c:state() to change state! */
+ sshstate nextstate; /* the state to goto after stopping */
+ CURLcode actualcode; /* the actual error code */
+ struct curl_slist *quote_item; /* for the quote option */
+ char *quote_path1; /* two generic pointers for the QUOTE stuff */
+ char *quote_path2;
+ LIBSSH2_SFTP_ATTRIBUTES quote_attrs; /* used by the SFTP_QUOTE state */
+ bool acceptfail; /* used by the SFTP_QUOTE (continue if
+ quote command fails) */
+ char *homedir; /* when doing SFTP we figure out home dir in the
+ connect phase */
+
+ /* Here's a set of struct members used by the SFTP_READDIR state */
+ LIBSSH2_SFTP_ATTRIBUTES readdir_attrs;
+ char *readdir_filename;
+ char *readdir_longentry;
+ int readdir_len, readdir_totalLen, readdir_currLen;
+ char *readdir_line;
+ char *readdir_linkPath;
+ /* end of READDIR stuff */
+
+ int secondCreateDirs; /* counter use by the code to see if the
+ second attempt has been made to change
+ to/create a directory */
+ char *slash_pos; /* used by the SFTP_CREATE_DIRS state */
+ LIBSSH2_SESSION *ssh_session; /* Secure Shell session */
+ LIBSSH2_CHANNEL *ssh_channel; /* Secure Shell channel handle */
+ LIBSSH2_SFTP *sftp_session; /* SFTP handle */
+ LIBSSH2_SFTP_HANDLE *sftp_handle;
+ int orig_waitfor; /* default READ/WRITE bits wait for */
+
+#ifdef HAVE_LIBSSH2_AGENT_API
+ LIBSSH2_AGENT *ssh_agent; /* proxy to ssh-agent/pageant */
+ struct libssh2_agent_publickey *sshagent_identity,
+ *sshagent_prev_identity;
+#endif
+
+ /* note that HAVE_LIBSSH2_KNOWNHOST_API is a define set in the libssh2.h
+ header */
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+ LIBSSH2_KNOWNHOSTS *kh;
+#endif
+#endif /* USE_LIBSSH2 */
+};
+
+#ifdef USE_LIBSSH2
+
+/* Feature detection based on version numbers to better work with
+ non-configure platforms */
+
+#if !defined(LIBSSH2_VERSION_NUM) || (LIBSSH2_VERSION_NUM < 0x001000)
+# error "SCP/SFTP protocols require libssh2 0.16 or later"
+#endif
+
+#if LIBSSH2_VERSION_NUM >= 0x010000
+#define HAVE_LIBSSH2_SFTP_SEEK64 1
+#endif
+
+#if LIBSSH2_VERSION_NUM >= 0x010100
+#define HAVE_LIBSSH2_VERSION 1
+#endif
+
+#if LIBSSH2_VERSION_NUM >= 0x010205
+#define HAVE_LIBSSH2_INIT 1
+#define HAVE_LIBSSH2_EXIT 1
+#endif
+
+#if LIBSSH2_VERSION_NUM >= 0x010206
+#define HAVE_LIBSSH2_KNOWNHOST_CHECKP 1
+#define HAVE_LIBSSH2_SCP_SEND64 1
+#endif
+
+#if LIBSSH2_VERSION_NUM >= 0x010208
+#define HAVE_LIBSSH2_SESSION_HANDSHAKE 1
+#endif
+
+extern const struct Curl_handler Curl_handler_scp;
+extern const struct Curl_handler Curl_handler_sftp;
+
+#endif /* USE_LIBSSH2 */
+
+#endif /* HEADER_CURL_SSH_H */
diff --git a/Utilities/cmcurl/lib/strdup.c b/Utilities/cmcurl/lib/strdup.c
new file mode 100644
index 000000000..5685b8138
--- /dev/null
+++ b/Utilities/cmcurl/lib/strdup.c
@@ -0,0 +1,73 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+#include "strdup.h"
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#ifndef HAVE_STRDUP
+char *curlx_strdup(const char *str)
+{
+ size_t len;
+ char *newstr;
+
+ if(!str)
+ return (char *)NULL;
+
+ len = strlen(str);
+
+ if(len >= ((size_t)-1) / sizeof(char))
+ return (char *)NULL;
+
+ newstr = malloc((len+1)*sizeof(char));
+ if(!newstr)
+ return (char *)NULL;
+
+ memcpy(newstr, str, (len+1)*sizeof(char));
+
+ return newstr;
+
+}
+#endif
+
+/***************************************************************************
+ *
+ * Curl_memdup(source, length)
+ *
+ * Copies the 'source' data to a newly allocated buffer (that is
+ * returned). Copies 'length' bytes.
+ *
+ * Returns the new pointer or NULL on failure.
+ *
+ ***************************************************************************/
+char *Curl_memdup(const char *src, size_t length)
+{
+ char *buffer = malloc(length);
+ if(!buffer)
+ return NULL; /* fail */
+
+ memcpy(buffer, src, length);
+
+ return buffer;
+}
diff --git a/Utilities/cmcurl/lib/strdup.h b/Utilities/cmcurl/lib/strdup.h
new file mode 100644
index 000000000..23a71f863
--- /dev/null
+++ b/Utilities/cmcurl/lib/strdup.h
@@ -0,0 +1,31 @@
+#ifndef HEADER_CURL_STRDUP_H
+#define HEADER_CURL_STRDUP_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifndef HAVE_STRDUP
+extern char *curlx_strdup(const char *str);
+#endif
+char *Curl_memdup(const char *src, size_t buffer_length);
+
+#endif /* HEADER_CURL_STRDUP_H */
diff --git a/Utilities/cmcurl/lib/strequal.c b/Utilities/cmcurl/lib/strequal.c
new file mode 100644
index 000000000..5f2f508e2
--- /dev/null
+++ b/Utilities/cmcurl/lib/strequal.c
@@ -0,0 +1,79 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#include "strequal.h"
+
+/*
+ * @unittest: 1301
+ */
+int curl_strequal(const char *first, const char *second)
+{
+#if defined(HAVE_STRCASECMP)
+ return !(strcasecmp)(first, second);
+#elif defined(HAVE_STRCMPI)
+ return !(strcmpi)(first, second);
+#elif defined(HAVE_STRICMP)
+ return !(stricmp)(first, second);
+#else
+ while(*first && *second) {
+ if(toupper(*first) != toupper(*second)) {
+ break;
+ }
+ first++;
+ second++;
+ }
+ return toupper(*first) == toupper(*second);
+#endif
+}
+
+/*
+ * @unittest: 1301
+ */
+int curl_strnequal(const char *first, const char *second, size_t max)
+{
+#if defined(HAVE_STRNCASECMP)
+ return !strncasecmp(first, second, max);
+#elif defined(HAVE_STRNCMPI)
+ return !strncmpi(first, second, max);
+#elif defined(HAVE_STRNICMP)
+ return !strnicmp(first, second, max);
+#else
+ while(*first && *second && max) {
+ if(toupper(*first) != toupper(*second)) {
+ break;
+ }
+ max--;
+ first++;
+ second++;
+ }
+ if(0 == max)
+ return 1; /* they are equal this far */
+
+ return toupper(*first) == toupper(*second);
+#endif
+}
diff --git a/Utilities/cmcurl/lib/strequal.h b/Utilities/cmcurl/lib/strequal.h
new file mode 100644
index 000000000..117a305b7
--- /dev/null
+++ b/Utilities/cmcurl/lib/strequal.h
@@ -0,0 +1,31 @@
+#ifndef HEADER_CURL_STREQUAL_H
+#define HEADER_CURL_STREQUAL_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <curl/curl.h>
+
+#define strequal(a,b) curl_strequal(a,b)
+#define strnequal(a,b,c) curl_strnequal(a,b,c)
+
+#endif /* HEADER_CURL_STREQUAL_H */
+
diff --git a/Utilities/cmcurl/lib/strerror.c b/Utilities/cmcurl/lib/strerror.c
new file mode 100644
index 000000000..565714188
--- /dev/null
+++ b/Utilities/cmcurl/lib/strerror.c
@@ -0,0 +1,1139 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2004 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_STRERROR_R
+# if (!defined(HAVE_POSIX_STRERROR_R) && \
+ !defined(HAVE_GLIBC_STRERROR_R) && \
+ !defined(HAVE_VXWORKS_STRERROR_R)) || \
+ (defined(HAVE_POSIX_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R)) || \
+ (defined(HAVE_GLIBC_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R)) || \
+ (defined(HAVE_POSIX_STRERROR_R) && defined(HAVE_GLIBC_STRERROR_R))
+# error "strerror_r MUST be either POSIX, glibc or vxworks-style"
+# endif
+#endif
+
+#include <curl/curl.h>
+
+#ifdef USE_LIBIDN
+#include <idna.h>
+#endif
+
+#include "strerror.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+const char *
+curl_easy_strerror(CURLcode error)
+{
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+ switch (error) {
+ case CURLE_OK:
+ return "No error";
+
+ case CURLE_UNSUPPORTED_PROTOCOL:
+ return "Unsupported protocol";
+
+ case CURLE_FAILED_INIT:
+ return "Failed initialization";
+
+ case CURLE_URL_MALFORMAT:
+ return "URL using bad/illegal format or missing URL";
+
+ case CURLE_NOT_BUILT_IN:
+ return "A requested feature, protocol or option was not found built-in in"
+ " this libcurl due to a build-time decision.";
+
+ case CURLE_COULDNT_RESOLVE_PROXY:
+ return "Couldn't resolve proxy name";
+
+ case CURLE_COULDNT_RESOLVE_HOST:
+ return "Couldn't resolve host name";
+
+ case CURLE_COULDNT_CONNECT:
+ return "Couldn't connect to server";
+
+ case CURLE_FTP_WEIRD_SERVER_REPLY:
+ return "FTP: weird server reply";
+
+ case CURLE_REMOTE_ACCESS_DENIED:
+ return "Access denied to remote resource";
+
+ case CURLE_FTP_ACCEPT_FAILED:
+ return "FTP: The server failed to connect to data port";
+
+ case CURLE_FTP_ACCEPT_TIMEOUT:
+ return "FTP: Accepting server connect has timed out";
+
+ case CURLE_FTP_PRET_FAILED:
+ return "FTP: The server did not accept the PRET command.";
+
+ case CURLE_FTP_WEIRD_PASS_REPLY:
+ return "FTP: unknown PASS reply";
+
+ case CURLE_FTP_WEIRD_PASV_REPLY:
+ return "FTP: unknown PASV reply";
+
+ case CURLE_FTP_WEIRD_227_FORMAT:
+ return "FTP: unknown 227 response format";
+
+ case CURLE_FTP_CANT_GET_HOST:
+ return "FTP: can't figure out the host in the PASV response";
+
+ case CURLE_HTTP2:
+ return "Error in the HTTP2 framing layer";
+
+ case CURLE_FTP_COULDNT_SET_TYPE:
+ return "FTP: couldn't set file type";
+
+ case CURLE_PARTIAL_FILE:
+ return "Transferred a partial file";
+
+ case CURLE_FTP_COULDNT_RETR_FILE:
+ return "FTP: couldn't retrieve (RETR failed) the specified file";
+
+ case CURLE_QUOTE_ERROR:
+ return "Quote command returned error";
+
+ case CURLE_HTTP_RETURNED_ERROR:
+ return "HTTP response code said error";
+
+ case CURLE_WRITE_ERROR:
+ return "Failed writing received data to disk/application";
+
+ case CURLE_UPLOAD_FAILED:
+ return "Upload failed (at start/before it took off)";
+
+ case CURLE_READ_ERROR:
+ return "Failed to open/read local data from file/application";
+
+ case CURLE_OUT_OF_MEMORY:
+ return "Out of memory";
+
+ case CURLE_OPERATION_TIMEDOUT:
+ return "Timeout was reached";
+
+ case CURLE_FTP_PORT_FAILED:
+ return "FTP: command PORT failed";
+
+ case CURLE_FTP_COULDNT_USE_REST:
+ return "FTP: command REST failed";
+
+ case CURLE_RANGE_ERROR:
+ return "Requested range was not delivered by the server";
+
+ case CURLE_HTTP_POST_ERROR:
+ return "Internal problem setting up the POST";
+
+ case CURLE_SSL_CONNECT_ERROR:
+ return "SSL connect error";
+
+ case CURLE_BAD_DOWNLOAD_RESUME:
+ return "Couldn't resume download";
+
+ case CURLE_FILE_COULDNT_READ_FILE:
+ return "Couldn't read a file:// file";
+
+ case CURLE_LDAP_CANNOT_BIND:
+ return "LDAP: cannot bind";
+
+ case CURLE_LDAP_SEARCH_FAILED:
+ return "LDAP: search failed";
+
+ case CURLE_FUNCTION_NOT_FOUND:
+ return "A required function in the library was not found";
+
+ case CURLE_ABORTED_BY_CALLBACK:
+ return "Operation was aborted by an application callback";
+
+ case CURLE_BAD_FUNCTION_ARGUMENT:
+ return "A libcurl function was given a bad argument";
+
+ case CURLE_INTERFACE_FAILED:
+ return "Failed binding local connection end";
+
+ case CURLE_TOO_MANY_REDIRECTS :
+ return "Number of redirects hit maximum amount";
+
+ case CURLE_UNKNOWN_OPTION:
+ return "An unknown option was passed in to libcurl";
+
+ case CURLE_TELNET_OPTION_SYNTAX :
+ return "Malformed telnet option";
+
+ case CURLE_PEER_FAILED_VERIFICATION:
+ return "SSL peer certificate or SSH remote key was not OK";
+
+ case CURLE_GOT_NOTHING:
+ return "Server returned nothing (no headers, no data)";
+
+ case CURLE_SSL_ENGINE_NOTFOUND:
+ return "SSL crypto engine not found";
+
+ case CURLE_SSL_ENGINE_SETFAILED:
+ return "Can not set SSL crypto engine as default";
+
+ case CURLE_SSL_ENGINE_INITFAILED:
+ return "Failed to initialise SSL crypto engine";
+
+ case CURLE_SEND_ERROR:
+ return "Failed sending data to the peer";
+
+ case CURLE_RECV_ERROR:
+ return "Failure when receiving data from the peer";
+
+ case CURLE_SSL_CERTPROBLEM:
+ return "Problem with the local SSL certificate";
+
+ case CURLE_SSL_CIPHER:
+ return "Couldn't use specified SSL cipher";
+
+ case CURLE_SSL_CACERT:
+ return "Peer certificate cannot be authenticated with given CA "
+ "certificates";
+
+ case CURLE_SSL_CACERT_BADFILE:
+ return "Problem with the SSL CA cert (path? access rights?)";
+
+ case CURLE_BAD_CONTENT_ENCODING:
+ return "Unrecognized or bad HTTP Content or Transfer-Encoding";
+
+ case CURLE_LDAP_INVALID_URL:
+ return "Invalid LDAP URL";
+
+ case CURLE_FILESIZE_EXCEEDED:
+ return "Maximum file size exceeded";
+
+ case CURLE_USE_SSL_FAILED:
+ return "Requested SSL level failed";
+
+ case CURLE_SSL_SHUTDOWN_FAILED:
+ return "Failed to shut down the SSL connection";
+
+ case CURLE_SSL_CRL_BADFILE:
+ return "Failed to load CRL file (path? access rights?, format?)";
+
+ case CURLE_SSL_ISSUER_ERROR:
+ return "Issuer check against peer certificate failed";
+
+ case CURLE_SEND_FAIL_REWIND:
+ return "Send failed since rewinding of the data stream failed";
+
+ case CURLE_LOGIN_DENIED:
+ return "Login denied";
+
+ case CURLE_TFTP_NOTFOUND:
+ return "TFTP: File Not Found";
+
+ case CURLE_TFTP_PERM:
+ return "TFTP: Access Violation";
+
+ case CURLE_REMOTE_DISK_FULL:
+ return "Disk full or allocation exceeded";
+
+ case CURLE_TFTP_ILLEGAL:
+ return "TFTP: Illegal operation";
+
+ case CURLE_TFTP_UNKNOWNID:
+ return "TFTP: Unknown transfer ID";
+
+ case CURLE_REMOTE_FILE_EXISTS:
+ return "Remote file already exists";
+
+ case CURLE_TFTP_NOSUCHUSER:
+ return "TFTP: No such user";
+
+ case CURLE_CONV_FAILED:
+ return "Conversion failed";
+
+ case CURLE_CONV_REQD:
+ return "Caller must register CURLOPT_CONV_ callback options";
+
+ case CURLE_REMOTE_FILE_NOT_FOUND:
+ return "Remote file not found";
+
+ case CURLE_SSH:
+ return "Error in the SSH layer";
+
+ case CURLE_AGAIN:
+ return "Socket not ready for send/recv";
+
+ case CURLE_RTSP_CSEQ_ERROR:
+ return "RTSP CSeq mismatch or invalid CSeq";
+
+ case CURLE_RTSP_SESSION_ERROR:
+ return "RTSP session error";
+
+ case CURLE_FTP_BAD_FILE_LIST:
+ return "Unable to parse FTP file list";
+
+ case CURLE_CHUNK_FAILED:
+ return "Chunk callback failed";
+
+ case CURLE_NO_CONNECTION_AVAILABLE:
+ return "The max connection limit is reached";
+
+ case CURLE_SSL_PINNEDPUBKEYNOTMATCH:
+ return "SSL public key does not match pinned public key";
+
+ case CURLE_SSL_INVALIDCERTSTATUS:
+ return "SSL server certificate status verification FAILED";
+
+ /* error codes not used by current libcurl */
+ case CURLE_OBSOLETE20:
+ case CURLE_OBSOLETE24:
+ case CURLE_OBSOLETE29:
+ case CURLE_OBSOLETE32:
+ case CURLE_OBSOLETE40:
+ case CURLE_OBSOLETE44:
+ case CURLE_OBSOLETE46:
+ case CURLE_OBSOLETE50:
+ case CURLE_OBSOLETE57:
+ case CURL_LAST:
+ break;
+ }
+ /*
+ * By using a switch, gcc -Wall will complain about enum values
+ * which do not appear, helping keep this function up-to-date.
+ * By using gcc -Wall -Werror, you can't forget.
+ *
+ * A table would not have the same benefit. Most compilers will
+ * generate code very similar to a table in any case, so there
+ * is little performance gain from a table. And something is broken
+ * for the user's application, anyways, so does it matter how fast
+ * it _doesn't_ work?
+ *
+ * The line number for the error will be near this comment, which
+ * is why it is here, and not at the start of the switch.
+ */
+ return "Unknown error";
+#else
+ if(!error)
+ return "No error";
+ else
+ return "Error";
+#endif
+}
+
+const char *
+curl_multi_strerror(CURLMcode error)
+{
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+ switch (error) {
+ case CURLM_CALL_MULTI_PERFORM:
+ return "Please call curl_multi_perform() soon";
+
+ case CURLM_OK:
+ return "No error";
+
+ case CURLM_BAD_HANDLE:
+ return "Invalid multi handle";
+
+ case CURLM_BAD_EASY_HANDLE:
+ return "Invalid easy handle";
+
+ case CURLM_OUT_OF_MEMORY:
+ return "Out of memory";
+
+ case CURLM_INTERNAL_ERROR:
+ return "Internal error";
+
+ case CURLM_BAD_SOCKET:
+ return "Invalid socket argument";
+
+ case CURLM_UNKNOWN_OPTION:
+ return "Unknown option";
+
+ case CURLM_ADDED_ALREADY:
+ return "The easy handle is already added to a multi handle";
+
+ case CURLM_LAST:
+ break;
+ }
+
+ return "Unknown error";
+#else
+ if(error == CURLM_OK)
+ return "No error";
+ else
+ return "Error";
+#endif
+}
+
+const char *
+curl_share_strerror(CURLSHcode error)
+{
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+ switch (error) {
+ case CURLSHE_OK:
+ return "No error";
+
+ case CURLSHE_BAD_OPTION:
+ return "Unknown share option";
+
+ case CURLSHE_IN_USE:
+ return "Share currently in use";
+
+ case CURLSHE_INVALID:
+ return "Invalid share handle";
+
+ case CURLSHE_NOMEM:
+ return "Out of memory";
+
+ case CURLSHE_NOT_BUILT_IN:
+ return "Feature not enabled in this library";
+
+ case CURLSHE_LAST:
+ break;
+ }
+
+ return "CURLSHcode unknown";
+#else
+ if(error == CURLSHE_OK)
+ return "No error";
+ else
+ return "Error";
+#endif
+}
+
+#ifdef USE_WINSOCK
+
+/* This function handles most / all (?) Winsock errors cURL is able to produce.
+ */
+static const char *
+get_winsock_error (int err, char *buf, size_t len)
+{
+ const char *p;
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+ switch (err) {
+ case WSAEINTR:
+ p = "Call interrupted";
+ break;
+ case WSAEBADF:
+ p = "Bad file";
+ break;
+ case WSAEACCES:
+ p = "Bad access";
+ break;
+ case WSAEFAULT:
+ p = "Bad argument";
+ break;
+ case WSAEINVAL:
+ p = "Invalid arguments";
+ break;
+ case WSAEMFILE:
+ p = "Out of file descriptors";
+ break;
+ case WSAEWOULDBLOCK:
+ p = "Call would block";
+ break;
+ case WSAEINPROGRESS:
+ case WSAEALREADY:
+ p = "Blocking call in progress";
+ break;
+ case WSAENOTSOCK:
+ p = "Descriptor is not a socket";
+ break;
+ case WSAEDESTADDRREQ:
+ p = "Need destination address";
+ break;
+ case WSAEMSGSIZE:
+ p = "Bad message size";
+ break;
+ case WSAEPROTOTYPE:
+ p = "Bad protocol";
+ break;
+ case WSAENOPROTOOPT:
+ p = "Protocol option is unsupported";
+ break;
+ case WSAEPROTONOSUPPORT:
+ p = "Protocol is unsupported";
+ break;
+ case WSAESOCKTNOSUPPORT:
+ p = "Socket is unsupported";
+ break;
+ case WSAEOPNOTSUPP:
+ p = "Operation not supported";
+ break;
+ case WSAEAFNOSUPPORT:
+ p = "Address family not supported";
+ break;
+ case WSAEPFNOSUPPORT:
+ p = "Protocol family not supported";
+ break;
+ case WSAEADDRINUSE:
+ p = "Address already in use";
+ break;
+ case WSAEADDRNOTAVAIL:
+ p = "Address not available";
+ break;
+ case WSAENETDOWN:
+ p = "Network down";
+ break;
+ case WSAENETUNREACH:
+ p = "Network unreachable";
+ break;
+ case WSAENETRESET:
+ p = "Network has been reset";
+ break;
+ case WSAECONNABORTED:
+ p = "Connection was aborted";
+ break;
+ case WSAECONNRESET:
+ p = "Connection was reset";
+ break;
+ case WSAENOBUFS:
+ p = "No buffer space";
+ break;
+ case WSAEISCONN:
+ p = "Socket is already connected";
+ break;
+ case WSAENOTCONN:
+ p = "Socket is not connected";
+ break;
+ case WSAESHUTDOWN:
+ p = "Socket has been shut down";
+ break;
+ case WSAETOOMANYREFS:
+ p = "Too many references";
+ break;
+ case WSAETIMEDOUT:
+ p = "Timed out";
+ break;
+ case WSAECONNREFUSED:
+ p = "Connection refused";
+ break;
+ case WSAELOOP:
+ p = "Loop??";
+ break;
+ case WSAENAMETOOLONG:
+ p = "Name too long";
+ break;
+ case WSAEHOSTDOWN:
+ p = "Host down";
+ break;
+ case WSAEHOSTUNREACH:
+ p = "Host unreachable";
+ break;
+ case WSAENOTEMPTY:
+ p = "Not empty";
+ break;
+ case WSAEPROCLIM:
+ p = "Process limit reached";
+ break;
+ case WSAEUSERS:
+ p = "Too many users";
+ break;
+ case WSAEDQUOT:
+ p = "Bad quota";
+ break;
+ case WSAESTALE:
+ p = "Something is stale";
+ break;
+ case WSAEREMOTE:
+ p = "Remote error";
+ break;
+#ifdef WSAEDISCON /* missing in SalfordC! */
+ case WSAEDISCON:
+ p = "Disconnected";
+ break;
+#endif
+ /* Extended Winsock errors */
+ case WSASYSNOTREADY:
+ p = "Winsock library is not ready";
+ break;
+ case WSANOTINITIALISED:
+ p = "Winsock library not initialised";
+ break;
+ case WSAVERNOTSUPPORTED:
+ p = "Winsock version not supported";
+ break;
+
+ /* getXbyY() errors (already handled in herrmsg):
+ * Authoritative Answer: Host not found */
+ case WSAHOST_NOT_FOUND:
+ p = "Host not found";
+ break;
+
+ /* Non-Authoritative: Host not found, or SERVERFAIL */
+ case WSATRY_AGAIN:
+ p = "Host not found, try again";
+ break;
+
+ /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
+ case WSANO_RECOVERY:
+ p = "Unrecoverable error in call to nameserver";
+ break;
+
+ /* Valid name, no data record of requested type */
+ case WSANO_DATA:
+ p = "No data record of requested type";
+ break;
+
+ default:
+ return NULL;
+ }
+#else
+ if(!err)
+ return NULL;
+ else
+ p = "error";
+#endif
+ strncpy (buf, p, len);
+ buf [len-1] = '\0';
+ return buf;
+}
+#endif /* USE_WINSOCK */
+
+/*
+ * Our thread-safe and smart strerror() replacement.
+ *
+ * The 'err' argument passed in to this function MUST be a true errno number
+ * as reported on this system. We do no range checking on the number before
+ * we pass it to the "number-to-message" conversion function and there might
+ * be systems that don't do proper range checking in there themselves.
+ *
+ * We don't do range checking (on systems other than Windows) since there is
+ * no good reliable and portable way to do it.
+ */
+const char *Curl_strerror(struct connectdata *conn, int err)
+{
+ char *buf, *p;
+ size_t max;
+ int old_errno = ERRNO;
+
+ DEBUGASSERT(conn);
+ DEBUGASSERT(err >= 0);
+
+ buf = conn->syserr_buf;
+ max = sizeof(conn->syserr_buf)-1;
+ *buf = '\0';
+
+#ifdef USE_WINSOCK
+
+#ifdef _WIN32_WCE
+ {
+ wchar_t wbuf[256];
+ wbuf[0] = L'\0';
+
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
+ LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL);
+ wcstombs(buf, wbuf, max);
+ }
+#else
+ /* 'sys_nerr' is the maximum errno number, it is not widely portable */
+ if(err >= 0 && err < sys_nerr)
+ strncpy(buf, strerror(err), max);
+ else {
+ if(!get_winsock_error(err, buf, max) &&
+ !FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
+ LANG_NEUTRAL, buf, (DWORD)max, NULL))
+ snprintf(buf, max, "Unknown error %d (%#x)", err, err);
+ }
+#endif
+
+#else /* not USE_WINSOCK coming up */
+
+#if defined(HAVE_STRERROR_R) && defined(HAVE_POSIX_STRERROR_R)
+ /*
+ * The POSIX-style strerror_r() may set errno to ERANGE if insufficient
+ * storage is supplied via 'strerrbuf' and 'buflen' to hold the generated
+ * message string, or EINVAL if 'errnum' is not a valid error number.
+ */
+ if(0 != strerror_r(err, buf, max)) {
+ if('\0' == buf[0])
+ snprintf(buf, max, "Unknown error %d", err);
+ }
+#elif defined(HAVE_STRERROR_R) && defined(HAVE_GLIBC_STRERROR_R)
+ /*
+ * The glibc-style strerror_r() only *might* use the buffer we pass to
+ * the function, but it always returns the error message as a pointer,
+ * so we must copy that string unconditionally (if non-NULL).
+ */
+ {
+ char buffer[256];
+ char *msg = strerror_r(err, buffer, sizeof(buffer));
+ if(msg)
+ strncpy(buf, msg, max);
+ else
+ snprintf(buf, max, "Unknown error %d", err);
+ }
+#elif defined(HAVE_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R)
+ /*
+ * The vxworks-style strerror_r() does use the buffer we pass to the function.
+ * The buffer size should be at least NAME_MAX (256)
+ */
+ {
+ char buffer[256];
+ if(OK == strerror_r(err, buffer))
+ strncpy(buf, buffer, max);
+ else
+ snprintf(buf, max, "Unknown error %d", err);
+ }
+#else
+ {
+ char *msg = strerror(err);
+ if(msg)
+ strncpy(buf, msg, max);
+ else
+ snprintf(buf, max, "Unknown error %d", err);
+ }
+#endif
+
+#endif /* end of ! USE_WINSOCK */
+
+ buf[max] = '\0'; /* make sure the string is zero terminated */
+
+ /* strip trailing '\r\n' or '\n'. */
+ if((p = strrchr(buf, '\n')) != NULL && (p - buf) >= 2)
+ *p = '\0';
+ if((p = strrchr(buf, '\r')) != NULL && (p - buf) >= 1)
+ *p = '\0';
+
+ if(old_errno != ERRNO)
+ SET_ERRNO(old_errno);
+
+ return buf;
+}
+
+#ifdef USE_LIBIDN
+/*
+ * Return error-string for libidn status as returned from idna_to_ascii_lz().
+ */
+const char *Curl_idn_strerror (struct connectdata *conn, int err)
+{
+#ifdef HAVE_IDNA_STRERROR
+ (void)conn;
+ return idna_strerror((Idna_rc) err);
+#else
+ const char *str;
+ char *buf;
+ size_t max;
+
+ DEBUGASSERT(conn);
+
+ buf = conn->syserr_buf;
+ max = sizeof(conn->syserr_buf)-1;
+ *buf = '\0';
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+ switch ((Idna_rc)err) {
+ case IDNA_SUCCESS:
+ str = "No error";
+ break;
+ case IDNA_STRINGPREP_ERROR:
+ str = "Error in string preparation";
+ break;
+ case IDNA_PUNYCODE_ERROR:
+ str = "Error in Punycode operation";
+ break;
+ case IDNA_CONTAINS_NON_LDH:
+ str = "Illegal ASCII characters";
+ break;
+ case IDNA_CONTAINS_MINUS:
+ str = "Contains minus";
+ break;
+ case IDNA_INVALID_LENGTH:
+ str = "Invalid output length";
+ break;
+ case IDNA_NO_ACE_PREFIX:
+ str = "No ACE prefix (\"xn--\")";
+ break;
+ case IDNA_ROUNDTRIP_VERIFY_ERROR:
+ str = "Round trip verify error";
+ break;
+ case IDNA_CONTAINS_ACE_PREFIX:
+ str = "Already have ACE prefix (\"xn--\")";
+ break;
+ case IDNA_ICONV_ERROR:
+ str = "Locale conversion failed";
+ break;
+ case IDNA_MALLOC_ERROR:
+ str = "Allocation failed";
+ break;
+ case IDNA_DLOPEN_ERROR:
+ str = "dlopen() error";
+ break;
+ default:
+ snprintf(buf, max, "error %d", err);
+ str = NULL;
+ break;
+ }
+#else
+ if((Idna_rc)err == IDNA_SUCCESS)
+ str = "No error";
+ else
+ str = "Error";
+#endif
+ if(str)
+ strncpy(buf, str, max);
+ buf[max] = '\0';
+ return (buf);
+#endif
+}
+#endif /* USE_LIBIDN */
+
+#ifdef USE_WINDOWS_SSPI
+const char *Curl_sspi_strerror (struct connectdata *conn, int err)
+{
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+ char txtbuf[80];
+ char msgbuf[sizeof(conn->syserr_buf)];
+ char *p, *str, *msg = NULL;
+ bool msg_formatted = FALSE;
+ int old_errno;
+#endif
+ const char *txt;
+ char *outbuf;
+ size_t outmax;
+
+ DEBUGASSERT(conn);
+
+ outbuf = conn->syserr_buf;
+ outmax = sizeof(conn->syserr_buf)-1;
+ *outbuf = '\0';
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+
+ old_errno = ERRNO;
+
+ switch (err) {
+ case SEC_E_OK:
+ txt = "No error";
+ break;
+ case CRYPT_E_REVOKED:
+ txt = "CRYPT_E_REVOKED";
+ break;
+ case SEC_E_ALGORITHM_MISMATCH:
+ txt = "SEC_E_ALGORITHM_MISMATCH";
+ break;
+ case SEC_E_BAD_BINDINGS:
+ txt = "SEC_E_BAD_BINDINGS";
+ break;
+ case SEC_E_BAD_PKGID:
+ txt = "SEC_E_BAD_PKGID";
+ break;
+ case SEC_E_BUFFER_TOO_SMALL:
+ txt = "SEC_E_BUFFER_TOO_SMALL";
+ break;
+ case SEC_E_CANNOT_INSTALL:
+ txt = "SEC_E_CANNOT_INSTALL";
+ break;
+ case SEC_E_CANNOT_PACK:
+ txt = "SEC_E_CANNOT_PACK";
+ break;
+ case SEC_E_CERT_EXPIRED:
+ txt = "SEC_E_CERT_EXPIRED";
+ break;
+ case SEC_E_CERT_UNKNOWN:
+ txt = "SEC_E_CERT_UNKNOWN";
+ break;
+ case SEC_E_CERT_WRONG_USAGE:
+ txt = "SEC_E_CERT_WRONG_USAGE";
+ break;
+ case SEC_E_CONTEXT_EXPIRED:
+ txt = "SEC_E_CONTEXT_EXPIRED";
+ break;
+ case SEC_E_CROSSREALM_DELEGATION_FAILURE:
+ txt = "SEC_E_CROSSREALM_DELEGATION_FAILURE";
+ break;
+ case SEC_E_CRYPTO_SYSTEM_INVALID:
+ txt = "SEC_E_CRYPTO_SYSTEM_INVALID";
+ break;
+ case SEC_E_DECRYPT_FAILURE:
+ txt = "SEC_E_DECRYPT_FAILURE";
+ break;
+ case SEC_E_DELEGATION_POLICY:
+ txt = "SEC_E_DELEGATION_POLICY";
+ break;
+ case SEC_E_DELEGATION_REQUIRED:
+ txt = "SEC_E_DELEGATION_REQUIRED";
+ break;
+ case SEC_E_DOWNGRADE_DETECTED:
+ txt = "SEC_E_DOWNGRADE_DETECTED";
+ break;
+ case SEC_E_ENCRYPT_FAILURE:
+ txt = "SEC_E_ENCRYPT_FAILURE";
+ break;
+ case SEC_E_ILLEGAL_MESSAGE:
+ txt = "SEC_E_ILLEGAL_MESSAGE";
+ break;
+ case SEC_E_INCOMPLETE_CREDENTIALS:
+ txt = "SEC_E_INCOMPLETE_CREDENTIALS";
+ break;
+ case SEC_E_INCOMPLETE_MESSAGE:
+ txt = "SEC_E_INCOMPLETE_MESSAGE";
+ break;
+ case SEC_E_INSUFFICIENT_MEMORY:
+ txt = "SEC_E_INSUFFICIENT_MEMORY";
+ break;
+ case SEC_E_INTERNAL_ERROR:
+ txt = "SEC_E_INTERNAL_ERROR";
+ break;
+ case SEC_E_INVALID_HANDLE:
+ txt = "SEC_E_INVALID_HANDLE";
+ break;
+ case SEC_E_INVALID_PARAMETER:
+ txt = "SEC_E_INVALID_PARAMETER";
+ break;
+ case SEC_E_INVALID_TOKEN:
+ txt = "SEC_E_INVALID_TOKEN";
+ break;
+ case SEC_E_ISSUING_CA_UNTRUSTED:
+ txt = "SEC_E_ISSUING_CA_UNTRUSTED";
+ break;
+ case SEC_E_ISSUING_CA_UNTRUSTED_KDC:
+ txt = "SEC_E_ISSUING_CA_UNTRUSTED_KDC";
+ break;
+ case SEC_E_KDC_CERT_EXPIRED:
+ txt = "SEC_E_KDC_CERT_EXPIRED";
+ break;
+ case SEC_E_KDC_CERT_REVOKED:
+ txt = "SEC_E_KDC_CERT_REVOKED";
+ break;
+ case SEC_E_KDC_INVALID_REQUEST:
+ txt = "SEC_E_KDC_INVALID_REQUEST";
+ break;
+ case SEC_E_KDC_UNABLE_TO_REFER:
+ txt = "SEC_E_KDC_UNABLE_TO_REFER";
+ break;
+ case SEC_E_KDC_UNKNOWN_ETYPE:
+ txt = "SEC_E_KDC_UNKNOWN_ETYPE";
+ break;
+ case SEC_E_LOGON_DENIED:
+ txt = "SEC_E_LOGON_DENIED";
+ break;
+ case SEC_E_MAX_REFERRALS_EXCEEDED:
+ txt = "SEC_E_MAX_REFERRALS_EXCEEDED";
+ break;
+ case SEC_E_MESSAGE_ALTERED:
+ txt = "SEC_E_MESSAGE_ALTERED";
+ break;
+ case SEC_E_MULTIPLE_ACCOUNTS:
+ txt = "SEC_E_MULTIPLE_ACCOUNTS";
+ break;
+ case SEC_E_MUST_BE_KDC:
+ txt = "SEC_E_MUST_BE_KDC";
+ break;
+ case SEC_E_NOT_OWNER:
+ txt = "SEC_E_NOT_OWNER";
+ break;
+ case SEC_E_NO_AUTHENTICATING_AUTHORITY:
+ txt = "SEC_E_NO_AUTHENTICATING_AUTHORITY";
+ break;
+ case SEC_E_NO_CREDENTIALS:
+ txt = "SEC_E_NO_CREDENTIALS";
+ break;
+ case SEC_E_NO_IMPERSONATION:
+ txt = "SEC_E_NO_IMPERSONATION";
+ break;
+ case SEC_E_NO_IP_ADDRESSES:
+ txt = "SEC_E_NO_IP_ADDRESSES";
+ break;
+ case SEC_E_NO_KERB_KEY:
+ txt = "SEC_E_NO_KERB_KEY";
+ break;
+ case SEC_E_NO_PA_DATA:
+ txt = "SEC_E_NO_PA_DATA";
+ break;
+ case SEC_E_NO_S4U_PROT_SUPPORT:
+ txt = "SEC_E_NO_S4U_PROT_SUPPORT";
+ break;
+ case SEC_E_NO_TGT_REPLY:
+ txt = "SEC_E_NO_TGT_REPLY";
+ break;
+ case SEC_E_OUT_OF_SEQUENCE:
+ txt = "SEC_E_OUT_OF_SEQUENCE";
+ break;
+ case SEC_E_PKINIT_CLIENT_FAILURE:
+ txt = "SEC_E_PKINIT_CLIENT_FAILURE";
+ break;
+ case SEC_E_PKINIT_NAME_MISMATCH:
+ txt = "SEC_E_PKINIT_NAME_MISMATCH";
+ break;
+ case SEC_E_POLICY_NLTM_ONLY:
+ txt = "SEC_E_POLICY_NLTM_ONLY";
+ break;
+ case SEC_E_QOP_NOT_SUPPORTED:
+ txt = "SEC_E_QOP_NOT_SUPPORTED";
+ break;
+ case SEC_E_REVOCATION_OFFLINE_C:
+ txt = "SEC_E_REVOCATION_OFFLINE_C";
+ break;
+ case SEC_E_REVOCATION_OFFLINE_KDC:
+ txt = "SEC_E_REVOCATION_OFFLINE_KDC";
+ break;
+ case SEC_E_SECPKG_NOT_FOUND:
+ txt = "SEC_E_SECPKG_NOT_FOUND";
+ break;
+ case SEC_E_SECURITY_QOS_FAILED:
+ txt = "SEC_E_SECURITY_QOS_FAILED";
+ break;
+ case SEC_E_SHUTDOWN_IN_PROGRESS:
+ txt = "SEC_E_SHUTDOWN_IN_PROGRESS";
+ break;
+ case SEC_E_SMARTCARD_CERT_EXPIRED:
+ txt = "SEC_E_SMARTCARD_CERT_EXPIRED";
+ break;
+ case SEC_E_SMARTCARD_CERT_REVOKED:
+ txt = "SEC_E_SMARTCARD_CERT_REVOKED";
+ break;
+ case SEC_E_SMARTCARD_LOGON_REQUIRED:
+ txt = "SEC_E_SMARTCARD_LOGON_REQUIRED";
+ break;
+ case SEC_E_STRONG_CRYPTO_NOT_SUPPORTED:
+ txt = "SEC_E_STRONG_CRYPTO_NOT_SUPPORTED";
+ break;
+ case SEC_E_TARGET_UNKNOWN:
+ txt = "SEC_E_TARGET_UNKNOWN";
+ break;
+ case SEC_E_TIME_SKEW:
+ txt = "SEC_E_TIME_SKEW";
+ break;
+ case SEC_E_TOO_MANY_PRINCIPALS:
+ txt = "SEC_E_TOO_MANY_PRINCIPALS";
+ break;
+ case SEC_E_UNFINISHED_CONTEXT_DELETED:
+ txt = "SEC_E_UNFINISHED_CONTEXT_DELETED";
+ break;
+ case SEC_E_UNKNOWN_CREDENTIALS:
+ txt = "SEC_E_UNKNOWN_CREDENTIALS";
+ break;
+ case SEC_E_UNSUPPORTED_FUNCTION:
+ txt = "SEC_E_UNSUPPORTED_FUNCTION";
+ break;
+ case SEC_E_UNSUPPORTED_PREAUTH:
+ txt = "SEC_E_UNSUPPORTED_PREAUTH";
+ break;
+ case SEC_E_UNTRUSTED_ROOT:
+ txt = "SEC_E_UNTRUSTED_ROOT";
+ break;
+ case SEC_E_WRONG_CREDENTIAL_HANDLE:
+ txt = "SEC_E_WRONG_CREDENTIAL_HANDLE";
+ break;
+ case SEC_E_WRONG_PRINCIPAL:
+ txt = "SEC_E_WRONG_PRINCIPAL";
+ break;
+ case SEC_I_COMPLETE_AND_CONTINUE:
+ txt = "SEC_I_COMPLETE_AND_CONTINUE";
+ break;
+ case SEC_I_COMPLETE_NEEDED:
+ txt = "SEC_I_COMPLETE_NEEDED";
+ break;
+ case SEC_I_CONTEXT_EXPIRED:
+ txt = "SEC_I_CONTEXT_EXPIRED";
+ break;
+ case SEC_I_CONTINUE_NEEDED:
+ txt = "SEC_I_CONTINUE_NEEDED";
+ break;
+ case SEC_I_INCOMPLETE_CREDENTIALS:
+ txt = "SEC_I_INCOMPLETE_CREDENTIALS";
+ break;
+ case SEC_I_LOCAL_LOGON:
+ txt = "SEC_I_LOCAL_LOGON";
+ break;
+ case SEC_I_NO_LSA_CONTEXT:
+ txt = "SEC_I_NO_LSA_CONTEXT";
+ break;
+ case SEC_I_RENEGOTIATE:
+ txt = "SEC_I_RENEGOTIATE";
+ break;
+ case SEC_I_SIGNATURE_NEEDED:
+ txt = "SEC_I_SIGNATURE_NEEDED";
+ break;
+ default:
+ txt = "Unknown error";
+ }
+
+ if(err == SEC_E_OK)
+ strncpy(outbuf, txt, outmax);
+ else if(err == SEC_E_ILLEGAL_MESSAGE)
+ snprintf(outbuf, outmax,
+ "SEC_E_ILLEGAL_MESSAGE (0x%04X%04X) - This error usually occurs "
+ "when a fatal SSL/TLS alert is received (e.g. handshake failed). "
+ "More detail may be available in the Windows System event log.",
+ (err >> 16) & 0xffff, err & 0xffff);
+ else {
+ str = txtbuf;
+ snprintf(txtbuf, sizeof(txtbuf), "%s (0x%04X%04X)",
+ txt, (err >> 16) & 0xffff, err & 0xffff);
+ txtbuf[sizeof(txtbuf)-1] = '\0';
+
+#ifdef _WIN32_WCE
+ {
+ wchar_t wbuf[256];
+ wbuf[0] = L'\0';
+
+ if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, err, LANG_NEUTRAL,
+ wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) {
+ wcstombs(msgbuf, wbuf, sizeof(msgbuf)-1);
+ msg_formatted = TRUE;
+ }
+ }
+#else
+ if(FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, err, LANG_NEUTRAL,
+ msgbuf, sizeof(msgbuf)-1, NULL)) {
+ msg_formatted = TRUE;
+ }
+#endif
+ if(msg_formatted) {
+ msgbuf[sizeof(msgbuf)-1] = '\0';
+ /* strip trailing '\r\n' or '\n' */
+ if((p = strrchr(msgbuf, '\n')) != NULL && (p - msgbuf) >= 2)
+ *p = '\0';
+ if((p = strrchr(msgbuf, '\r')) != NULL && (p - msgbuf) >= 1)
+ *p = '\0';
+ msg = msgbuf;
+ }
+ if(msg)
+ snprintf(outbuf, outmax, "%s - %s", str, msg);
+ else
+ strncpy(outbuf, str, outmax);
+ }
+
+ if(old_errno != ERRNO)
+ SET_ERRNO(old_errno);
+
+#else
+
+ if(err == SEC_E_OK)
+ txt = "No error";
+ else
+ txt = "Error";
+
+ strncpy(outbuf, txt, outmax);
+
+#endif
+
+ outbuf[outmax] = '\0';
+
+ return outbuf;
+}
+#endif /* USE_WINDOWS_SSPI */
diff --git a/Utilities/cmcurl/lib/strerror.h b/Utilities/cmcurl/lib/strerror.h
new file mode 100644
index 000000000..f1b22210a
--- /dev/null
+++ b/Utilities/cmcurl/lib/strerror.h
@@ -0,0 +1,37 @@
+#ifndef HEADER_CURL_STRERROR_H
+#define HEADER_CURL_STRERROR_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "urldata.h"
+
+const char *Curl_strerror (struct connectdata *conn, int err);
+
+#ifdef USE_LIBIDN
+const char *Curl_idn_strerror (struct connectdata *conn, int err);
+#endif
+
+#ifdef USE_WINDOWS_SSPI
+const char *Curl_sspi_strerror (struct connectdata *conn, int err);
+#endif
+
+#endif /* HEADER_CURL_STRERROR_H */
diff --git a/Utilities/cmcurl/lib/strtok.c b/Utilities/cmcurl/lib/strtok.c
new file mode 100644
index 000000000..0d31351f4
--- /dev/null
+++ b/Utilities/cmcurl/lib/strtok.c
@@ -0,0 +1,66 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef HAVE_STRTOK_R
+#include <stddef.h>
+
+#include "strtok.h"
+
+char *
+Curl_strtok_r(char *ptr, const char *sep, char **end)
+{
+ if(!ptr)
+ /* we got NULL input so then we get our last position instead */
+ ptr = *end;
+
+ /* pass all letters that are including in the separator string */
+ while(*ptr && strchr(sep, *ptr))
+ ++ptr;
+
+ if(*ptr) {
+ /* so this is where the next piece of string starts */
+ char *start = ptr;
+
+ /* set the end pointer to the first byte after the start */
+ *end = start + 1;
+
+ /* scan through the string to find where it ends, it ends on a
+ null byte or a character that exists in the separator string */
+ while(**end && !strchr(sep, **end))
+ ++*end;
+
+ if(**end) {
+ /* the end is not a null byte */
+ **end = '\0'; /* zero terminate it! */
+ ++*end; /* advance the last pointer to beyond the null byte */
+ }
+
+ return start; /* return the position where the string starts */
+ }
+
+ /* we ended up on a null byte, there are no more strings to find! */
+ return NULL;
+}
+
+#endif /* this was only compiled if strtok_r wasn't present */
diff --git a/Utilities/cmcurl/lib/strtok.h b/Utilities/cmcurl/lib/strtok.h
new file mode 100644
index 000000000..1147d70d3
--- /dev/null
+++ b/Utilities/cmcurl/lib/strtok.h
@@ -0,0 +1,34 @@
+#ifndef HEADER_CURL_STRTOK_H
+#define HEADER_CURL_STRTOK_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+#include <stddef.h>
+
+#ifndef HAVE_STRTOK_R
+char *Curl_strtok_r(char *s, const char *delim, char **last);
+#define strtok_r Curl_strtok_r
+#else
+#include <string.h>
+#endif
+
+#endif /* HEADER_CURL_STRTOK_H */
diff --git a/Utilities/cmcurl/lib/strtoofft.c b/Utilities/cmcurl/lib/strtoofft.c
new file mode 100644
index 000000000..03a97e8c4
--- /dev/null
+++ b/Utilities/cmcurl/lib/strtoofft.c
@@ -0,0 +1,188 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "strtoofft.h"
+
+/*
+ * NOTE:
+ *
+ * In the ISO C standard (IEEE Std 1003.1), there is a strtoimax() function we
+ * could use in case strtoll() doesn't exist... See
+ * http://www.opengroup.org/onlinepubs/009695399/functions/strtoimax.html
+ */
+
+#ifdef NEED_CURL_STRTOLL
+
+/* Range tests can be used for alphanum decoding if characters are consecutive,
+ like in ASCII. Else an array is scanned. Determine this condition now. */
+
+#if('9' - '0') != 9 || ('Z' - 'A') != 25 || ('z' - 'a') != 25
+
+#define NO_RANGE_TEST
+
+static const char valchars[] =
+ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+#endif
+
+static int get_char(char c, int base);
+
+/**
+ * Emulated version of the strtoll function. This extracts a long long
+ * value from the given input string and returns it.
+ */
+curl_off_t
+curlx_strtoll(const char *nptr, char **endptr, int base)
+{
+ char *end;
+ int is_negative = 0;
+ int overflow;
+ int i;
+ curl_off_t value = 0;
+ curl_off_t newval;
+
+ /* Skip leading whitespace. */
+ end = (char *)nptr;
+ while(ISSPACE(end[0])) {
+ end++;
+ }
+
+ /* Handle the sign, if any. */
+ if(end[0] == '-') {
+ is_negative = 1;
+ end++;
+ }
+ else if(end[0] == '+') {
+ end++;
+ }
+ else if(end[0] == '\0') {
+ /* We had nothing but perhaps some whitespace -- there was no number. */
+ if(endptr) {
+ *endptr = end;
+ }
+ return 0;
+ }
+
+ /* Handle special beginnings, if present and allowed. */
+ if(end[0] == '0' && end[1] == 'x') {
+ if(base == 16 || base == 0) {
+ end += 2;
+ base = 16;
+ }
+ }
+ else if(end[0] == '0') {
+ if(base == 8 || base == 0) {
+ end++;
+ base = 8;
+ }
+ }
+
+ /* Matching strtol, if the base is 0 and it doesn't look like
+ * the number is octal or hex, we assume it's base 10.
+ */
+ if(base == 0) {
+ base = 10;
+ }
+
+ /* Loop handling digits. */
+ value = 0;
+ overflow = 0;
+ for(i = get_char(end[0], base);
+ i != -1;
+ end++, i = get_char(end[0], base)) {
+ newval = base * value + i;
+ if(newval < value) {
+ /* We've overflowed. */
+ overflow = 1;
+ break;
+ }
+ else
+ value = newval;
+ }
+
+ if(!overflow) {
+ if(is_negative) {
+ /* Fix the sign. */
+ value *= -1;
+ }
+ }
+ else {
+ if(is_negative)
+ value = CURL_OFF_T_MIN;
+ else
+ value = CURL_OFF_T_MAX;
+
+ SET_ERRNO(ERANGE);
+ }
+
+ if(endptr)
+ *endptr = end;
+
+ return value;
+}
+
+/**
+ * Returns the value of c in the given base, or -1 if c cannot
+ * be interpreted properly in that base (i.e., is out of range,
+ * is a null, etc.).
+ *
+ * @param c the character to interpret according to base
+ * @param base the base in which to interpret c
+ *
+ * @return the value of c in base, or -1 if c isn't in range
+ */
+static int get_char(char c, int base)
+{
+#ifndef NO_RANGE_TEST
+ int value = -1;
+ if(c <= '9' && c >= '0') {
+ value = c - '0';
+ }
+ else if(c <= 'Z' && c >= 'A') {
+ value = c - 'A' + 10;
+ }
+ else if(c <= 'z' && c >= 'a') {
+ value = c - 'a' + 10;
+ }
+#else
+ const char * cp;
+ int value;
+
+ cp = memchr(valchars, c, 10 + 26 + 26);
+
+ if(!cp)
+ return -1;
+
+ value = cp - valchars;
+
+ if(value >= 10 + 26)
+ value -= 26; /* Lowercase. */
+#endif
+
+ if(value >= base) {
+ value = -1;
+ }
+
+ return value;
+}
+#endif /* Only present if we need strtoll, but don't have it. */
diff --git a/Utilities/cmcurl/lib/strtoofft.h b/Utilities/cmcurl/lib/strtoofft.h
new file mode 100644
index 000000000..75c73d483
--- /dev/null
+++ b/Utilities/cmcurl/lib/strtoofft.h
@@ -0,0 +1,75 @@
+#ifndef HEADER_CURL_STRTOOFFT_H
+#define HEADER_CURL_STRTOOFFT_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+/*
+ * Determine which string to integral data type conversion function we use
+ * to implement string conversion to our curl_off_t integral data type.
+ *
+ * Notice that curl_off_t might be 64 or 32 bit wide, and that it might use
+ * an underlying data type which might be 'long', 'int64_t', 'long long' or
+ * '__int64' and more remotely other data types.
+ *
+ * On systems where the size of curl_off_t is greater than the size of 'long'
+ * the conversion function to use is strtoll() if it is available, otherwise,
+ * we emulate its functionality with our own clone.
+ *
+ * On systems where the size of curl_off_t is smaller or equal than the size
+ * of 'long' the conversion function to use is strtol().
+ */
+
+#if (CURL_SIZEOF_CURL_OFF_T > CURL_SIZEOF_LONG)
+# ifdef HAVE_STRTOLL
+# define curlx_strtoofft strtoll
+# else
+# if defined(_MSC_VER) && (_MSC_VER >= 1300) && (_INTEGRAL_MAX_BITS >= 64)
+# if defined(_SAL_VERSION)
+ _Check_return_ _CRTIMP __int64 __cdecl _strtoi64(
+ _In_z_ const char *_String,
+ _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix);
+# else
+ _CRTIMP __int64 __cdecl _strtoi64(const char *_String,
+ char **_EndPtr, int _Radix);
+# endif
+# define curlx_strtoofft _strtoi64
+# else
+ curl_off_t curlx_strtoll(const char *nptr, char **endptr, int base);
+# define curlx_strtoofft curlx_strtoll
+# define NEED_CURL_STRTOLL 1
+# endif
+# endif
+#else
+# define curlx_strtoofft strtol
+#endif
+
+#if (CURL_SIZEOF_CURL_OFF_T == 4)
+# define CURL_OFF_T_MAX CURL_OFF_T_C(0x7FFFFFFF)
+#else
+ /* assume CURL_SIZEOF_CURL_OFF_T == 8 */
+# define CURL_OFF_T_MAX CURL_OFF_T_C(0x7FFFFFFFFFFFFFFF)
+#endif
+#define CURL_OFF_T_MIN (-CURL_OFF_T_MAX - CURL_OFF_T_C(1))
+
+#endif /* HEADER_CURL_STRTOOFFT_H */
diff --git a/Utilities/cmcurl/lib/telnet.c b/Utilities/cmcurl/lib/telnet.c
new file mode 100644
index 000000000..aabf99d48
--- /dev/null
+++ b/Utilities/cmcurl/lib/telnet.c
@@ -0,0 +1,1675 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_TELNET
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "transfer.h"
+#include "sendf.h"
+#include "telnet.h"
+#include "connect.h"
+#include "progress.h"
+#include "curl_printf.h"
+
+#define TELOPTS
+#define TELCMDS
+
+#include "arpa_telnet.h"
+#include "select.h"
+#include "strequal.h"
+#include "rawstr.h"
+#include "warnless.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define SUBBUFSIZE 512
+
+#define CURL_SB_CLEAR(x) x->subpointer = x->subbuffer
+#define CURL_SB_TERM(x) \
+ do { \
+ x->subend = x->subpointer; \
+ CURL_SB_CLEAR(x); \
+ } WHILE_FALSE
+#define CURL_SB_ACCUM(x,c) \
+ do { \
+ if(x->subpointer < (x->subbuffer+sizeof x->subbuffer)) \
+ *x->subpointer++ = (c); \
+ } WHILE_FALSE
+
+#define CURL_SB_GET(x) ((*x->subpointer++)&0xff)
+#define CURL_SB_PEEK(x) ((*x->subpointer)&0xff)
+#define CURL_SB_EOF(x) (x->subpointer >= x->subend)
+#define CURL_SB_LEN(x) (x->subend - x->subpointer)
+
+#ifdef CURL_DISABLE_VERBOSE_STRINGS
+#define printoption(a,b,c,d) Curl_nop_stmt
+#endif
+
+#ifdef USE_WINSOCK
+typedef FARPROC WSOCK2_FUNC;
+static CURLcode check_wsock2 ( struct SessionHandle *data );
+#endif
+
+static
+CURLcode telrcv(struct connectdata *,
+ const unsigned char *inbuf, /* Data received from socket */
+ ssize_t count); /* Number of bytes received */
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+static void printoption(struct SessionHandle *data,
+ const char *direction,
+ int cmd, int option);
+#endif
+
+static void negotiate(struct connectdata *);
+static void send_negotiation(struct connectdata *, int cmd, int option);
+static void set_local_option(struct connectdata *, int cmd, int option);
+static void set_remote_option(struct connectdata *, int cmd, int option);
+
+static void printsub(struct SessionHandle *data,
+ int direction, unsigned char *pointer,
+ size_t length);
+static void suboption(struct connectdata *);
+static void sendsuboption(struct connectdata *conn, int option);
+
+static CURLcode telnet_do(struct connectdata *conn, bool *done);
+static CURLcode telnet_done(struct connectdata *conn,
+ CURLcode, bool premature);
+static CURLcode send_telnet_data(struct connectdata *conn,
+ char *buffer, ssize_t nread);
+
+/* For negotiation compliant to RFC 1143 */
+#define CURL_NO 0
+#define CURL_YES 1
+#define CURL_WANTYES 2
+#define CURL_WANTNO 3
+
+#define CURL_EMPTY 0
+#define CURL_OPPOSITE 1
+
+/*
+ * Telnet receiver states for fsm
+ */
+typedef enum
+{
+ CURL_TS_DATA = 0,
+ CURL_TS_IAC,
+ CURL_TS_WILL,
+ CURL_TS_WONT,
+ CURL_TS_DO,
+ CURL_TS_DONT,
+ CURL_TS_CR,
+ CURL_TS_SB, /* sub-option collection */
+ CURL_TS_SE /* looking for sub-option end */
+} TelnetReceive;
+
+struct TELNET {
+ int please_negotiate;
+ int already_negotiated;
+ int us[256];
+ int usq[256];
+ int us_preferred[256];
+ int him[256];
+ int himq[256];
+ int him_preferred[256];
+ int subnegotiation[256];
+ char subopt_ttype[32]; /* Set with suboption TTYPE */
+ char subopt_xdisploc[128]; /* Set with suboption XDISPLOC */
+ unsigned short subopt_wsx; /* Set with suboption NAWS */
+ unsigned short subopt_wsy; /* Set with suboption NAWS */
+ struct curl_slist *telnet_vars; /* Environment variables */
+
+ /* suboptions */
+ unsigned char subbuffer[SUBBUFSIZE];
+ unsigned char *subpointer, *subend; /* buffer for sub-options */
+
+ TelnetReceive telrcv_state;
+};
+
+
+/*
+ * TELNET protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_telnet = {
+ "TELNET", /* scheme */
+ ZERO_NULL, /* setup_connection */
+ telnet_do, /* do_it */
+ telnet_done, /* done */
+ ZERO_NULL, /* do_more */
+ ZERO_NULL, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_getsock */
+ ZERO_NULL, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ ZERO_NULL, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_TELNET, /* defport */
+ CURLPROTO_TELNET, /* protocol */
+ PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */
+};
+
+
+#ifdef USE_WINSOCK
+static CURLcode
+check_wsock2 ( struct SessionHandle *data )
+{
+ int err;
+ WORD wVersionRequested;
+ WSADATA wsaData;
+
+ DEBUGASSERT(data);
+
+ /* telnet requires at least WinSock 2.0 so ask for it. */
+ wVersionRequested = MAKEWORD(2, 0);
+
+ err = WSAStartup(wVersionRequested, &wsaData);
+
+ /* We must've called this once already, so this call */
+ /* should always succeed. But, just in case... */
+ if(err != 0) {
+ failf(data,"WSAStartup failed (%d)",err);
+ return CURLE_FAILED_INIT;
+ }
+
+ /* We have to have a WSACleanup call for every successful */
+ /* WSAStartup call. */
+ WSACleanup();
+
+ /* Check that our version is supported */
+ if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) ||
+ HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested)) {
+ /* Our version isn't supported */
+ failf(data, "insufficient winsock version to support "
+ "telnet");
+ return CURLE_FAILED_INIT;
+ }
+
+ /* Our version is supported */
+ return CURLE_OK;
+}
+#endif
+
+static
+CURLcode init_telnet(struct connectdata *conn)
+{
+ struct TELNET *tn;
+
+ tn = calloc(1, sizeof(struct TELNET));
+ if(!tn)
+ return CURLE_OUT_OF_MEMORY;
+
+ conn->data->req.protop = tn; /* make us known */
+
+ tn->telrcv_state = CURL_TS_DATA;
+
+ /* Init suboptions */
+ CURL_SB_CLEAR(tn);
+
+ /* Set the options we want by default */
+ tn->us_preferred[CURL_TELOPT_SGA] = CURL_YES;
+ tn->him_preferred[CURL_TELOPT_SGA] = CURL_YES;
+
+ /* To be compliant with previous releases of libcurl
+ we enable this option by default. This behaviour
+ can be changed thanks to the "BINARY" option in
+ CURLOPT_TELNETOPTIONS
+ */
+ tn->us_preferred[CURL_TELOPT_BINARY] = CURL_YES;
+ tn->him_preferred[CURL_TELOPT_BINARY] = CURL_YES;
+
+ /* We must allow the server to echo what we sent
+ but it is not necessary to request the server
+ to do so (it might forces the server to close
+ the connection). Hence, we ignore ECHO in the
+ negotiate function
+ */
+ tn->him_preferred[CURL_TELOPT_ECHO] = CURL_YES;
+
+ /* Set the subnegotiation fields to send information
+ just after negotiation passed (do/will)
+
+ Default values are (0,0) initialized by calloc.
+ According to the RFC1013 it is valid:
+ A value equal to zero is acceptable for the width (or height),
+ and means that no character width (or height) is being sent.
+ In this case, the width (or height) that will be assumed by the
+ Telnet server is operating system specific (it will probably be
+ based upon the terminal type information that may have been sent
+ using the TERMINAL TYPE Telnet option). */
+ tn->subnegotiation[CURL_TELOPT_NAWS] = CURL_YES;
+ return CURLE_OK;
+}
+
+static void negotiate(struct connectdata *conn)
+{
+ int i;
+ struct TELNET *tn = (struct TELNET *) conn->data->req.protop;
+
+ for(i = 0;i < CURL_NTELOPTS;i++) {
+ if(i==CURL_TELOPT_ECHO)
+ continue;
+
+ if(tn->us_preferred[i] == CURL_YES)
+ set_local_option(conn, i, CURL_YES);
+
+ if(tn->him_preferred[i] == CURL_YES)
+ set_remote_option(conn, i, CURL_YES);
+ }
+}
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+static void printoption(struct SessionHandle *data,
+ const char *direction, int cmd, int option)
+{
+ const char *fmt;
+ const char *opt;
+
+ if(data->set.verbose) {
+ if(cmd == CURL_IAC) {
+ if(CURL_TELCMD_OK(option))
+ infof(data, "%s IAC %s\n", direction, CURL_TELCMD(option));
+ else
+ infof(data, "%s IAC %d\n", direction, option);
+ }
+ else {
+ fmt = (cmd == CURL_WILL) ? "WILL" : (cmd == CURL_WONT) ? "WONT" :
+ (cmd == CURL_DO) ? "DO" : (cmd == CURL_DONT) ? "DONT" : 0;
+ if(fmt) {
+ if(CURL_TELOPT_OK(option))
+ opt = CURL_TELOPT(option);
+ else if(option == CURL_TELOPT_EXOPL)
+ opt = "EXOPL";
+ else
+ opt = NULL;
+
+ if(opt)
+ infof(data, "%s %s %s\n", direction, fmt, opt);
+ else
+ infof(data, "%s %s %d\n", direction, fmt, option);
+ }
+ else
+ infof(data, "%s %d %d\n", direction, cmd, option);
+ }
+ }
+}
+#endif
+
+static void send_negotiation(struct connectdata *conn, int cmd, int option)
+{
+ unsigned char buf[3];
+ ssize_t bytes_written;
+ int err;
+ struct SessionHandle *data = conn->data;
+
+ buf[0] = CURL_IAC;
+ buf[1] = (unsigned char)cmd;
+ buf[2] = (unsigned char)option;
+
+ bytes_written = swrite(conn->sock[FIRSTSOCKET], buf, 3);
+ if(bytes_written < 0) {
+ err = SOCKERRNO;
+ failf(data,"Sending data failed (%d)",err);
+ }
+
+ printoption(conn->data, "SENT", cmd, option);
+}
+
+static
+void set_remote_option(struct connectdata *conn, int option, int newstate)
+{
+ struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+ if(newstate == CURL_YES) {
+ switch(tn->him[option]) {
+ case CURL_NO:
+ tn->him[option] = CURL_WANTYES;
+ send_negotiation(conn, CURL_DO, option);
+ break;
+
+ case CURL_YES:
+ /* Already enabled */
+ break;
+
+ case CURL_WANTNO:
+ switch(tn->himq[option]) {
+ case CURL_EMPTY:
+ /* Already negotiating for CURL_YES, queue the request */
+ tn->himq[option] = CURL_OPPOSITE;
+ break;
+ case CURL_OPPOSITE:
+ /* Error: already queued an enable request */
+ break;
+ }
+ break;
+
+ case CURL_WANTYES:
+ switch(tn->himq[option]) {
+ case CURL_EMPTY:
+ /* Error: already negotiating for enable */
+ break;
+ case CURL_OPPOSITE:
+ tn->himq[option] = CURL_EMPTY;
+ break;
+ }
+ break;
+ }
+ }
+ else { /* NO */
+ switch(tn->him[option]) {
+ case CURL_NO:
+ /* Already disabled */
+ break;
+
+ case CURL_YES:
+ tn->him[option] = CURL_WANTNO;
+ send_negotiation(conn, CURL_DONT, option);
+ break;
+
+ case CURL_WANTNO:
+ switch(tn->himq[option]) {
+ case CURL_EMPTY:
+ /* Already negotiating for NO */
+ break;
+ case CURL_OPPOSITE:
+ tn->himq[option] = CURL_EMPTY;
+ break;
+ }
+ break;
+
+ case CURL_WANTYES:
+ switch(tn->himq[option]) {
+ case CURL_EMPTY:
+ tn->himq[option] = CURL_OPPOSITE;
+ break;
+ case CURL_OPPOSITE:
+ break;
+ }
+ break;
+ }
+ }
+}
+
+static
+void rec_will(struct connectdata *conn, int option)
+{
+ struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+ switch(tn->him[option]) {
+ case CURL_NO:
+ if(tn->him_preferred[option] == CURL_YES) {
+ tn->him[option] = CURL_YES;
+ send_negotiation(conn, CURL_DO, option);
+ }
+ else
+ send_negotiation(conn, CURL_DONT, option);
+
+ break;
+
+ case CURL_YES:
+ /* Already enabled */
+ break;
+
+ case CURL_WANTNO:
+ switch(tn->himq[option]) {
+ case CURL_EMPTY:
+ /* Error: DONT answered by WILL */
+ tn->him[option] = CURL_NO;
+ break;
+ case CURL_OPPOSITE:
+ /* Error: DONT answered by WILL */
+ tn->him[option] = CURL_YES;
+ tn->himq[option] = CURL_EMPTY;
+ break;
+ }
+ break;
+
+ case CURL_WANTYES:
+ switch(tn->himq[option]) {
+ case CURL_EMPTY:
+ tn->him[option] = CURL_YES;
+ break;
+ case CURL_OPPOSITE:
+ tn->him[option] = CURL_WANTNO;
+ tn->himq[option] = CURL_EMPTY;
+ send_negotiation(conn, CURL_DONT, option);
+ break;
+ }
+ break;
+ }
+}
+
+static
+void rec_wont(struct connectdata *conn, int option)
+{
+ struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+ switch(tn->him[option]) {
+ case CURL_NO:
+ /* Already disabled */
+ break;
+
+ case CURL_YES:
+ tn->him[option] = CURL_NO;
+ send_negotiation(conn, CURL_DONT, option);
+ break;
+
+ case CURL_WANTNO:
+ switch(tn->himq[option]) {
+ case CURL_EMPTY:
+ tn->him[option] = CURL_NO;
+ break;
+
+ case CURL_OPPOSITE:
+ tn->him[option] = CURL_WANTYES;
+ tn->himq[option] = CURL_EMPTY;
+ send_negotiation(conn, CURL_DO, option);
+ break;
+ }
+ break;
+
+ case CURL_WANTYES:
+ switch(tn->himq[option]) {
+ case CURL_EMPTY:
+ tn->him[option] = CURL_NO;
+ break;
+ case CURL_OPPOSITE:
+ tn->him[option] = CURL_NO;
+ tn->himq[option] = CURL_EMPTY;
+ break;
+ }
+ break;
+ }
+}
+
+static void
+set_local_option(struct connectdata *conn, int option, int newstate)
+{
+ struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+ if(newstate == CURL_YES) {
+ switch(tn->us[option]) {
+ case CURL_NO:
+ tn->us[option] = CURL_WANTYES;
+ send_negotiation(conn, CURL_WILL, option);
+ break;
+
+ case CURL_YES:
+ /* Already enabled */
+ break;
+
+ case CURL_WANTNO:
+ switch(tn->usq[option]) {
+ case CURL_EMPTY:
+ /* Already negotiating for CURL_YES, queue the request */
+ tn->usq[option] = CURL_OPPOSITE;
+ break;
+ case CURL_OPPOSITE:
+ /* Error: already queued an enable request */
+ break;
+ }
+ break;
+
+ case CURL_WANTYES:
+ switch(tn->usq[option]) {
+ case CURL_EMPTY:
+ /* Error: already negotiating for enable */
+ break;
+ case CURL_OPPOSITE:
+ tn->usq[option] = CURL_EMPTY;
+ break;
+ }
+ break;
+ }
+ }
+ else { /* NO */
+ switch(tn->us[option]) {
+ case CURL_NO:
+ /* Already disabled */
+ break;
+
+ case CURL_YES:
+ tn->us[option] = CURL_WANTNO;
+ send_negotiation(conn, CURL_WONT, option);
+ break;
+
+ case CURL_WANTNO:
+ switch(tn->usq[option]) {
+ case CURL_EMPTY:
+ /* Already negotiating for NO */
+ break;
+ case CURL_OPPOSITE:
+ tn->usq[option] = CURL_EMPTY;
+ break;
+ }
+ break;
+
+ case CURL_WANTYES:
+ switch(tn->usq[option]) {
+ case CURL_EMPTY:
+ tn->usq[option] = CURL_OPPOSITE;
+ break;
+ case CURL_OPPOSITE:
+ break;
+ }
+ break;
+ }
+ }
+}
+
+static
+void rec_do(struct connectdata *conn, int option)
+{
+ struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+ switch(tn->us[option]) {
+ case CURL_NO:
+ if(tn->us_preferred[option] == CURL_YES) {
+ tn->us[option] = CURL_YES;
+ send_negotiation(conn, CURL_WILL, option);
+ if(tn->subnegotiation[option] == CURL_YES)
+ /* transmission of data option */
+ sendsuboption(conn, option);
+ }
+ else if(tn->subnegotiation[option] == CURL_YES) {
+ /* send information to achieve this option*/
+ tn->us[option] = CURL_YES;
+ send_negotiation(conn, CURL_WILL, option);
+ sendsuboption(conn, option);
+ }
+ else
+ send_negotiation(conn, CURL_WONT, option);
+ break;
+
+ case CURL_YES:
+ /* Already enabled */
+ break;
+
+ case CURL_WANTNO:
+ switch(tn->usq[option]) {
+ case CURL_EMPTY:
+ /* Error: DONT answered by WILL */
+ tn->us[option] = CURL_NO;
+ break;
+ case CURL_OPPOSITE:
+ /* Error: DONT answered by WILL */
+ tn->us[option] = CURL_YES;
+ tn->usq[option] = CURL_EMPTY;
+ break;
+ }
+ break;
+
+ case CURL_WANTYES:
+ switch(tn->usq[option]) {
+ case CURL_EMPTY:
+ tn->us[option] = CURL_YES;
+ if(tn->subnegotiation[option] == CURL_YES) {
+ /* transmission of data option */
+ sendsuboption(conn, option);
+ }
+ break;
+ case CURL_OPPOSITE:
+ tn->us[option] = CURL_WANTNO;
+ tn->himq[option] = CURL_EMPTY;
+ send_negotiation(conn, CURL_WONT, option);
+ break;
+ }
+ break;
+ }
+}
+
+static
+void rec_dont(struct connectdata *conn, int option)
+{
+ struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+ switch(tn->us[option]) {
+ case CURL_NO:
+ /* Already disabled */
+ break;
+
+ case CURL_YES:
+ tn->us[option] = CURL_NO;
+ send_negotiation(conn, CURL_WONT, option);
+ break;
+
+ case CURL_WANTNO:
+ switch(tn->usq[option]) {
+ case CURL_EMPTY:
+ tn->us[option] = CURL_NO;
+ break;
+
+ case CURL_OPPOSITE:
+ tn->us[option] = CURL_WANTYES;
+ tn->usq[option] = CURL_EMPTY;
+ send_negotiation(conn, CURL_WILL, option);
+ break;
+ }
+ break;
+
+ case CURL_WANTYES:
+ switch(tn->usq[option]) {
+ case CURL_EMPTY:
+ tn->us[option] = CURL_NO;
+ break;
+ case CURL_OPPOSITE:
+ tn->us[option] = CURL_NO;
+ tn->usq[option] = CURL_EMPTY;
+ break;
+ }
+ break;
+ }
+}
+
+
+static void printsub(struct SessionHandle *data,
+ int direction, /* '<' or '>' */
+ unsigned char *pointer, /* where suboption data is */
+ size_t length) /* length of suboption data */
+{
+ unsigned int i = 0;
+
+ if(data->set.verbose) {
+ if(direction) {
+ infof(data, "%s IAC SB ", (direction == '<')? "RCVD":"SENT");
+ if(length >= 3) {
+ int j;
+
+ i = pointer[length-2];
+ j = pointer[length-1];
+
+ if(i != CURL_IAC || j != CURL_SE) {
+ infof(data, "(terminated by ");
+ if(CURL_TELOPT_OK(i))
+ infof(data, "%s ", CURL_TELOPT(i));
+ else if(CURL_TELCMD_OK(i))
+ infof(data, "%s ", CURL_TELCMD(i));
+ else
+ infof(data, "%u ", i);
+ if(CURL_TELOPT_OK(j))
+ infof(data, "%s", CURL_TELOPT(j));
+ else if(CURL_TELCMD_OK(j))
+ infof(data, "%s", CURL_TELCMD(j));
+ else
+ infof(data, "%d", j);
+ infof(data, ", not IAC SE!) ");
+ }
+ }
+ length -= 2;
+ }
+ if(length < 1) {
+ infof(data, "(Empty suboption?)");
+ return;
+ }
+
+ if(CURL_TELOPT_OK(pointer[0])) {
+ switch(pointer[0]) {
+ case CURL_TELOPT_TTYPE:
+ case CURL_TELOPT_XDISPLOC:
+ case CURL_TELOPT_NEW_ENVIRON:
+ case CURL_TELOPT_NAWS:
+ infof(data, "%s", CURL_TELOPT(pointer[0]));
+ break;
+ default:
+ infof(data, "%s (unsupported)", CURL_TELOPT(pointer[0]));
+ break;
+ }
+ }
+ else
+ infof(data, "%d (unknown)", pointer[i]);
+
+ switch(pointer[0]) {
+ case CURL_TELOPT_NAWS:
+ if(length > 4)
+ infof(data, "Width: %hu ; Height: %hu", (pointer[1]<<8) | pointer[2],
+ (pointer[3]<<8) | pointer[4]);
+ break;
+ default:
+ switch(pointer[1]) {
+ case CURL_TELQUAL_IS:
+ infof(data, " IS");
+ break;
+ case CURL_TELQUAL_SEND:
+ infof(data, " SEND");
+ break;
+ case CURL_TELQUAL_INFO:
+ infof(data, " INFO/REPLY");
+ break;
+ case CURL_TELQUAL_NAME:
+ infof(data, " NAME");
+ break;
+ }
+
+ switch(pointer[0]) {
+ case CURL_TELOPT_TTYPE:
+ case CURL_TELOPT_XDISPLOC:
+ pointer[length] = 0;
+ infof(data, " \"%s\"", &pointer[2]);
+ break;
+ case CURL_TELOPT_NEW_ENVIRON:
+ if(pointer[1] == CURL_TELQUAL_IS) {
+ infof(data, " ");
+ for(i = 3;i < length;i++) {
+ switch(pointer[i]) {
+ case CURL_NEW_ENV_VAR:
+ infof(data, ", ");
+ break;
+ case CURL_NEW_ENV_VALUE:
+ infof(data, " = ");
+ break;
+ default:
+ infof(data, "%c", pointer[i]);
+ break;
+ }
+ }
+ }
+ break;
+ default:
+ for(i = 2; i < length; i++)
+ infof(data, " %.2x", pointer[i]);
+ break;
+ }
+ }
+ if(direction)
+ infof(data, "\n");
+ }
+}
+
+static CURLcode check_telnet_options(struct connectdata *conn)
+{
+ struct curl_slist *head;
+ struct curl_slist *beg;
+ char option_keyword[128] = "";
+ char option_arg[256] = "";
+ struct SessionHandle *data = conn->data;
+ struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+ CURLcode result = CURLE_OK;
+ int binary_option;
+
+ /* Add the user name as an environment variable if it
+ was given on the command line */
+ if(conn->bits.user_passwd) {
+ snprintf(option_arg, sizeof(option_arg), "USER,%s", conn->user);
+ beg = curl_slist_append(tn->telnet_vars, option_arg);
+ if(!beg) {
+ curl_slist_free_all(tn->telnet_vars);
+ tn->telnet_vars = NULL;
+ return CURLE_OUT_OF_MEMORY;
+ }
+ tn->telnet_vars = beg;
+ tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES;
+ }
+
+ for(head = data->set.telnet_options; head; head=head->next) {
+ if(sscanf(head->data, "%127[^= ]%*[ =]%255s",
+ option_keyword, option_arg) == 2) {
+
+ /* Terminal type */
+ if(Curl_raw_equal(option_keyword, "TTYPE")) {
+ strncpy(tn->subopt_ttype, option_arg, 31);
+ tn->subopt_ttype[31] = 0; /* String termination */
+ tn->us_preferred[CURL_TELOPT_TTYPE] = CURL_YES;
+ continue;
+ }
+
+ /* Display variable */
+ if(Curl_raw_equal(option_keyword, "XDISPLOC")) {
+ strncpy(tn->subopt_xdisploc, option_arg, 127);
+ tn->subopt_xdisploc[127] = 0; /* String termination */
+ tn->us_preferred[CURL_TELOPT_XDISPLOC] = CURL_YES;
+ continue;
+ }
+
+ /* Environment variable */
+ if(Curl_raw_equal(option_keyword, "NEW_ENV")) {
+ beg = curl_slist_append(tn->telnet_vars, option_arg);
+ if(!beg) {
+ result = CURLE_OUT_OF_MEMORY;
+ break;
+ }
+ tn->telnet_vars = beg;
+ tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES;
+ continue;
+ }
+
+ /* Window Size */
+ if(Curl_raw_equal(option_keyword, "WS")) {
+ if(sscanf(option_arg, "%hu%*[xX]%hu",
+ &tn->subopt_wsx, &tn->subopt_wsy) == 2)
+ tn->us_preferred[CURL_TELOPT_NAWS] = CURL_YES;
+ else {
+ failf(data, "Syntax error in telnet option: %s", head->data);
+ result = CURLE_TELNET_OPTION_SYNTAX;
+ break;
+ }
+ continue;
+ }
+
+ /* To take care or not of the 8th bit in data exchange */
+ if(Curl_raw_equal(option_keyword, "BINARY")) {
+ binary_option=atoi(option_arg);
+ if(binary_option!=1) {
+ tn->us_preferred[CURL_TELOPT_BINARY] = CURL_NO;
+ tn->him_preferred[CURL_TELOPT_BINARY] = CURL_NO;
+ }
+ continue;
+ }
+
+ failf(data, "Unknown telnet option %s", head->data);
+ result = CURLE_UNKNOWN_TELNET_OPTION;
+ break;
+ }
+ else {
+ failf(data, "Syntax error in telnet option: %s", head->data);
+ result = CURLE_TELNET_OPTION_SYNTAX;
+ break;
+ }
+ }
+
+ if(result) {
+ curl_slist_free_all(tn->telnet_vars);
+ tn->telnet_vars = NULL;
+ }
+
+ return result;
+}
+
+/*
+ * suboption()
+ *
+ * Look at the sub-option buffer, and try to be helpful to the other
+ * side.
+ */
+
+static void suboption(struct connectdata *conn)
+{
+ struct curl_slist *v;
+ unsigned char temp[2048];
+ ssize_t bytes_written;
+ size_t len;
+ size_t tmplen;
+ int err;
+ char varname[128] = "";
+ char varval[128] = "";
+ struct SessionHandle *data = conn->data;
+ struct TELNET *tn = (struct TELNET *)data->req.protop;
+
+ printsub(data, '<', (unsigned char *)tn->subbuffer, CURL_SB_LEN(tn)+2);
+ switch (CURL_SB_GET(tn)) {
+ case CURL_TELOPT_TTYPE:
+ len = strlen(tn->subopt_ttype) + 4 + 2;
+ snprintf((char *)temp, sizeof(temp),
+ "%c%c%c%c%s%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_TTYPE,
+ CURL_TELQUAL_IS, tn->subopt_ttype, CURL_IAC, CURL_SE);
+ bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len);
+ if(bytes_written < 0) {
+ err = SOCKERRNO;
+ failf(data,"Sending data failed (%d)",err);
+ }
+ printsub(data, '>', &temp[2], len-2);
+ break;
+ case CURL_TELOPT_XDISPLOC:
+ len = strlen(tn->subopt_xdisploc) + 4 + 2;
+ snprintf((char *)temp, sizeof(temp),
+ "%c%c%c%c%s%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_XDISPLOC,
+ CURL_TELQUAL_IS, tn->subopt_xdisploc, CURL_IAC, CURL_SE);
+ bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len);
+ if(bytes_written < 0) {
+ err = SOCKERRNO;
+ failf(data,"Sending data failed (%d)",err);
+ }
+ printsub(data, '>', &temp[2], len-2);
+ break;
+ case CURL_TELOPT_NEW_ENVIRON:
+ snprintf((char *)temp, sizeof(temp),
+ "%c%c%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_NEW_ENVIRON,
+ CURL_TELQUAL_IS);
+ len = 4;
+
+ for(v = tn->telnet_vars;v;v = v->next) {
+ tmplen = (strlen(v->data) + 1);
+ /* Add the variable only if it fits */
+ if(len + tmplen < (int)sizeof(temp)-6) {
+ if(sscanf(v->data, "%127[^,],%127s", varname, varval)) {
+ snprintf((char *)&temp[len], sizeof(temp) - len,
+ "%c%s%c%s", CURL_NEW_ENV_VAR, varname,
+ CURL_NEW_ENV_VALUE, varval);
+ len += tmplen;
+ }
+ }
+ }
+ snprintf((char *)&temp[len], sizeof(temp) - len,
+ "%c%c", CURL_IAC, CURL_SE);
+ len += 2;
+ bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len);
+ if(bytes_written < 0) {
+ err = SOCKERRNO;
+ failf(data,"Sending data failed (%d)",err);
+ }
+ printsub(data, '>', &temp[2], len-2);
+ break;
+ }
+ return;
+}
+
+
+/*
+ * sendsuboption()
+ *
+ * Send suboption information to the server side.
+ */
+
+static void sendsuboption(struct connectdata *conn, int option)
+{
+ ssize_t bytes_written;
+ int err;
+ unsigned short x, y;
+ unsigned char*uc1, *uc2;
+
+ struct SessionHandle *data = conn->data;
+ struct TELNET *tn = (struct TELNET *)data->req.protop;
+
+ switch (option) {
+ case CURL_TELOPT_NAWS:
+ /* We prepare data to be sent */
+ CURL_SB_CLEAR(tn);
+ CURL_SB_ACCUM(tn, CURL_IAC);
+ CURL_SB_ACCUM(tn, CURL_SB);
+ CURL_SB_ACCUM(tn, CURL_TELOPT_NAWS);
+ /* We must deal either with litte or big endien processors */
+ /* Window size must be sent according to the 'network order' */
+ x=htons(tn->subopt_wsx);
+ y=htons(tn->subopt_wsy);
+ uc1 = (unsigned char*)&x;
+ uc2 = (unsigned char*)&y;
+ CURL_SB_ACCUM(tn, uc1[0]);
+ CURL_SB_ACCUM(tn, uc1[1]);
+ CURL_SB_ACCUM(tn, uc2[0]);
+ CURL_SB_ACCUM(tn, uc2[1]);
+
+ CURL_SB_ACCUM(tn, CURL_IAC);
+ CURL_SB_ACCUM(tn, CURL_SE);
+ CURL_SB_TERM(tn);
+ /* data suboption is now ready */
+
+ printsub(data, '>', (unsigned char *)tn->subbuffer+2,
+ CURL_SB_LEN(tn)-2);
+
+ /* we send the header of the suboption... */
+ bytes_written = swrite(conn->sock[FIRSTSOCKET], tn->subbuffer, 3);
+ if(bytes_written < 0) {
+ err = SOCKERRNO;
+ failf(data, "Sending data failed (%d)", err);
+ }
+ /* ... then the window size with the send_telnet_data() function
+ to deal with 0xFF cases ... */
+ send_telnet_data(conn, (char *)tn->subbuffer+3, 4);
+ /* ... and the footer */
+ bytes_written = swrite(conn->sock[FIRSTSOCKET], tn->subbuffer+7, 2);
+ if(bytes_written < 0) {
+ err = SOCKERRNO;
+ failf(data, "Sending data failed (%d)", err);
+ }
+ break;
+ }
+}
+
+
+static
+CURLcode telrcv(struct connectdata *conn,
+ const unsigned char *inbuf, /* Data received from socket */
+ ssize_t count) /* Number of bytes received */
+{
+ unsigned char c;
+ CURLcode result;
+ int in = 0;
+ int startwrite=-1;
+ struct SessionHandle *data = conn->data;
+ struct TELNET *tn = (struct TELNET *)data->req.protop;
+
+#define startskipping() \
+ if(startwrite >= 0) { \
+ result = Curl_client_write(conn, \
+ CLIENTWRITE_BODY, \
+ (char *)&inbuf[startwrite], \
+ in-startwrite); \
+ if(result) \
+ return result; \
+ } \
+ startwrite = -1
+
+#define writebyte() \
+ if(startwrite < 0) \
+ startwrite = in
+
+#define bufferflush() startskipping()
+
+ while(count--) {
+ c = inbuf[in];
+
+ switch (tn->telrcv_state) {
+ case CURL_TS_CR:
+ tn->telrcv_state = CURL_TS_DATA;
+ if(c == '\0') {
+ startskipping();
+ break; /* Ignore \0 after CR */
+ }
+ writebyte();
+ break;
+
+ case CURL_TS_DATA:
+ if(c == CURL_IAC) {
+ tn->telrcv_state = CURL_TS_IAC;
+ startskipping();
+ break;
+ }
+ else if(c == '\r')
+ tn->telrcv_state = CURL_TS_CR;
+ writebyte();
+ break;
+
+ case CURL_TS_IAC:
+ process_iac:
+ DEBUGASSERT(startwrite < 0);
+ switch (c) {
+ case CURL_WILL:
+ tn->telrcv_state = CURL_TS_WILL;
+ break;
+ case CURL_WONT:
+ tn->telrcv_state = CURL_TS_WONT;
+ break;
+ case CURL_DO:
+ tn->telrcv_state = CURL_TS_DO;
+ break;
+ case CURL_DONT:
+ tn->telrcv_state = CURL_TS_DONT;
+ break;
+ case CURL_SB:
+ CURL_SB_CLEAR(tn);
+ tn->telrcv_state = CURL_TS_SB;
+ break;
+ case CURL_IAC:
+ tn->telrcv_state = CURL_TS_DATA;
+ writebyte();
+ break;
+ case CURL_DM:
+ case CURL_NOP:
+ case CURL_GA:
+ default:
+ tn->telrcv_state = CURL_TS_DATA;
+ printoption(data, "RCVD", CURL_IAC, c);
+ break;
+ }
+ break;
+
+ case CURL_TS_WILL:
+ printoption(data, "RCVD", CURL_WILL, c);
+ tn->please_negotiate = 1;
+ rec_will(conn, c);
+ tn->telrcv_state = CURL_TS_DATA;
+ break;
+
+ case CURL_TS_WONT:
+ printoption(data, "RCVD", CURL_WONT, c);
+ tn->please_negotiate = 1;
+ rec_wont(conn, c);
+ tn->telrcv_state = CURL_TS_DATA;
+ break;
+
+ case CURL_TS_DO:
+ printoption(data, "RCVD", CURL_DO, c);
+ tn->please_negotiate = 1;
+ rec_do(conn, c);
+ tn->telrcv_state = CURL_TS_DATA;
+ break;
+
+ case CURL_TS_DONT:
+ printoption(data, "RCVD", CURL_DONT, c);
+ tn->please_negotiate = 1;
+ rec_dont(conn, c);
+ tn->telrcv_state = CURL_TS_DATA;
+ break;
+
+ case CURL_TS_SB:
+ if(c == CURL_IAC)
+ tn->telrcv_state = CURL_TS_SE;
+ else
+ CURL_SB_ACCUM(tn, c);
+ break;
+
+ case CURL_TS_SE:
+ if(c != CURL_SE) {
+ if(c != CURL_IAC) {
+ /*
+ * This is an error. We only expect to get "IAC IAC" or "IAC SE".
+ * Several things may have happened. An IAC was not doubled, the
+ * IAC SE was left off, or another option got inserted into the
+ * suboption are all possibilities. If we assume that the IAC was
+ * not doubled, and really the IAC SE was left off, we could get
+ * into an infinate loop here. So, instead, we terminate the
+ * suboption, and process the partial suboption if we can.
+ */
+ CURL_SB_ACCUM(tn, CURL_IAC);
+ CURL_SB_ACCUM(tn, c);
+ tn->subpointer -= 2;
+ CURL_SB_TERM(tn);
+
+ printoption(data, "In SUBOPTION processing, RCVD", CURL_IAC, c);
+ suboption(conn); /* handle sub-option */
+ tn->telrcv_state = CURL_TS_IAC;
+ goto process_iac;
+ }
+ CURL_SB_ACCUM(tn, c);
+ tn->telrcv_state = CURL_TS_SB;
+ }
+ else
+ {
+ CURL_SB_ACCUM(tn, CURL_IAC);
+ CURL_SB_ACCUM(tn, CURL_SE);
+ tn->subpointer -= 2;
+ CURL_SB_TERM(tn);
+ suboption(conn); /* handle sub-option */
+ tn->telrcv_state = CURL_TS_DATA;
+ }
+ break;
+ }
+ ++in;
+ }
+ bufferflush();
+ return CURLE_OK;
+}
+
+/* Escape and send a telnet data block */
+/* TODO: write large chunks of data instead of one byte at a time */
+static CURLcode send_telnet_data(struct connectdata *conn,
+ char *buffer, ssize_t nread)
+{
+ unsigned char outbuf[2];
+ ssize_t bytes_written, total_written;
+ int out_count;
+ CURLcode result = CURLE_OK;
+
+ while(!result && nread--) {
+ outbuf[0] = *buffer++;
+ out_count = 1;
+ if(outbuf[0] == CURL_IAC)
+ outbuf[out_count++] = CURL_IAC;
+
+ total_written = 0;
+ do {
+ /* Make sure socket is writable to avoid EWOULDBLOCK condition */
+ struct pollfd pfd[1];
+ pfd[0].fd = conn->sock[FIRSTSOCKET];
+ pfd[0].events = POLLOUT;
+ switch (Curl_poll(pfd, 1, -1)) {
+ case -1: /* error, abort writing */
+ case 0: /* timeout (will never happen) */
+ result = CURLE_SEND_ERROR;
+ break;
+ default: /* write! */
+ bytes_written = 0;
+ result = Curl_write(conn, conn->sock[FIRSTSOCKET],
+ outbuf+total_written, out_count-total_written,
+ &bytes_written);
+ total_written += bytes_written;
+ break;
+ }
+ /* handle partial write */
+ } while(!result && total_written < out_count);
+ }
+ return result;
+}
+
+static CURLcode telnet_done(struct connectdata *conn,
+ CURLcode status, bool premature)
+{
+ struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+ (void)status; /* unused */
+ (void)premature; /* not used */
+
+ if(!tn)
+ return CURLE_OK;
+
+ curl_slist_free_all(tn->telnet_vars);
+ tn->telnet_vars = NULL;
+
+ Curl_safefree(conn->data->req.protop);
+
+ return CURLE_OK;
+}
+
+static CURLcode telnet_do(struct connectdata *conn, bool *done)
+{
+ CURLcode result;
+ struct SessionHandle *data = conn->data;
+ curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
+#ifdef USE_WINSOCK
+ HMODULE wsock2;
+ WSOCK2_FUNC close_event_func;
+ WSOCK2_FUNC create_event_func;
+ WSOCK2_FUNC event_select_func;
+ WSOCK2_FUNC enum_netevents_func;
+ WSAEVENT event_handle;
+ WSANETWORKEVENTS events;
+ HANDLE stdin_handle;
+ HANDLE objs[2];
+ DWORD obj_count;
+ DWORD wait_timeout;
+ DWORD waitret;
+ DWORD readfile_read;
+ int err;
+#else
+ int interval_ms;
+ struct pollfd pfd[2];
+ int poll_cnt;
+ curl_off_t total_dl = 0;
+ curl_off_t total_ul = 0;
+#endif
+ ssize_t nread;
+ struct timeval now;
+ bool keepon = TRUE;
+ char *buf = data->state.buffer;
+ struct TELNET *tn;
+
+ *done = TRUE; /* unconditionally */
+
+ result = init_telnet(conn);
+ if(result)
+ return result;
+
+ tn = (struct TELNET *)data->req.protop;
+
+ result = check_telnet_options(conn);
+ if(result)
+ return result;
+
+#ifdef USE_WINSOCK
+ /*
+ ** This functionality only works with WinSock >= 2.0. So,
+ ** make sure have it.
+ */
+ result = check_wsock2(data);
+ if(result)
+ return result;
+
+ /* OK, so we have WinSock 2.0. We need to dynamically */
+ /* load ws2_32.dll and get the function pointers we need. */
+ wsock2 = LoadLibrary(TEXT("WS2_32.DLL"));
+ if(wsock2 == NULL) {
+ failf(data, "failed to load WS2_32.DLL (%d)", ERRNO);
+ return CURLE_FAILED_INIT;
+ }
+
+ /* Grab a pointer to WSACreateEvent */
+ create_event_func = GetProcAddress(wsock2, "WSACreateEvent");
+ if(create_event_func == NULL) {
+ failf(data, "failed to find WSACreateEvent function (%d)", ERRNO);
+ FreeLibrary(wsock2);
+ return CURLE_FAILED_INIT;
+ }
+
+ /* And WSACloseEvent */
+ close_event_func = GetProcAddress(wsock2, "WSACloseEvent");
+ if(close_event_func == NULL) {
+ failf(data, "failed to find WSACloseEvent function (%d)", ERRNO);
+ FreeLibrary(wsock2);
+ return CURLE_FAILED_INIT;
+ }
+
+ /* And WSAEventSelect */
+ event_select_func = GetProcAddress(wsock2, "WSAEventSelect");
+ if(event_select_func == NULL) {
+ failf(data, "failed to find WSAEventSelect function (%d)", ERRNO);
+ FreeLibrary(wsock2);
+ return CURLE_FAILED_INIT;
+ }
+
+ /* And WSAEnumNetworkEvents */
+ enum_netevents_func = GetProcAddress(wsock2, "WSAEnumNetworkEvents");
+ if(enum_netevents_func == NULL) {
+ failf(data, "failed to find WSAEnumNetworkEvents function (%d)", ERRNO);
+ FreeLibrary(wsock2);
+ return CURLE_FAILED_INIT;
+ }
+
+ /* We want to wait for both stdin and the socket. Since
+ ** the select() function in winsock only works on sockets
+ ** we have to use the WaitForMultipleObjects() call.
+ */
+
+ /* First, create a sockets event object */
+ event_handle = (WSAEVENT)create_event_func();
+ if(event_handle == WSA_INVALID_EVENT) {
+ failf(data, "WSACreateEvent failed (%d)", SOCKERRNO);
+ FreeLibrary(wsock2);
+ return CURLE_FAILED_INIT;
+ }
+
+ /* Tell winsock what events we want to listen to */
+ if(event_select_func(sockfd, event_handle, FD_READ|FD_CLOSE) ==
+ SOCKET_ERROR) {
+ close_event_func(event_handle);
+ FreeLibrary(wsock2);
+ return CURLE_OK;
+ }
+
+ /* The get the Windows file handle for stdin */
+ stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
+
+ /* Create the list of objects to wait for */
+ objs[0] = event_handle;
+ objs[1] = stdin_handle;
+
+ /* If stdin_handle is a pipe, use PeekNamedPipe() method to check it,
+ else use the old WaitForMultipleObjects() way */
+ if(GetFileType(stdin_handle) == FILE_TYPE_PIPE ||
+ data->set.is_fread_set) {
+ /* Don't wait for stdin_handle, just wait for event_handle */
+ obj_count = 1;
+ /* Check stdin_handle per 100 milliseconds */
+ wait_timeout = 100;
+ }
+ else {
+ obj_count = 2;
+ wait_timeout = 1000;
+ }
+
+ /* Keep on listening and act on events */
+ while(keepon) {
+ waitret = WaitForMultipleObjects(obj_count, objs, FALSE, wait_timeout);
+ switch(waitret) {
+ case WAIT_TIMEOUT:
+ {
+ for(;;) {
+ if(data->set.is_fread_set) {
+ /* read from user-supplied method */
+ result = (int)data->set.fread_func(buf, 1, BUFSIZE - 1,
+ data->set.in);
+ if(result == CURL_READFUNC_ABORT) {
+ keepon = FALSE;
+ result = CURLE_READ_ERROR;
+ break;
+ }
+
+ if(result == CURL_READFUNC_PAUSE)
+ break;
+
+ if(result == 0) /* no bytes */
+ break;
+
+ readfile_read = result; /* fall thru with number of bytes read */
+ }
+ else {
+ /* read from stdin */
+ if(!PeekNamedPipe(stdin_handle, NULL, 0, NULL,
+ &readfile_read, NULL)) {
+ keepon = FALSE;
+ result = CURLE_READ_ERROR;
+ break;
+ }
+
+ if(!readfile_read)
+ break;
+
+ if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
+ &readfile_read, NULL)) {
+ keepon = FALSE;
+ result = CURLE_READ_ERROR;
+ break;
+ }
+ }
+
+ result = send_telnet_data(conn, buf, readfile_read);
+ if(result) {
+ keepon = FALSE;
+ break;
+ }
+ }
+ }
+ break;
+
+ case WAIT_OBJECT_0 + 1:
+ {
+ if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
+ &readfile_read, NULL)) {
+ keepon = FALSE;
+ result = CURLE_READ_ERROR;
+ break;
+ }
+
+ result = send_telnet_data(conn, buf, readfile_read);
+ if(result) {
+ keepon = FALSE;
+ break;
+ }
+ }
+ break;
+
+ case WAIT_OBJECT_0:
+
+ events.lNetworkEvents = 0;
+ if(SOCKET_ERROR == enum_netevents_func(sockfd, event_handle, &events)) {
+ if((err = SOCKERRNO) != EINPROGRESS) {
+ infof(data, "WSAEnumNetworkEvents failed (%d)", err);
+ keepon = FALSE;
+ result = CURLE_READ_ERROR;
+ }
+ break;
+ }
+ if(events.lNetworkEvents & FD_READ) {
+ /* read data from network */
+ result = Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread);
+ /* read would've blocked. Loop again */
+ if(result == CURLE_AGAIN)
+ break;
+ /* returned not-zero, this an error */
+ else if(result) {
+ keepon = FALSE;
+ break;
+ }
+ /* returned zero but actually received 0 or less here,
+ the server closed the connection and we bail out */
+ else if(nread <= 0) {
+ keepon = FALSE;
+ break;
+ }
+
+ result = telrcv(conn, (unsigned char *) buf, nread);
+ if(result) {
+ keepon = FALSE;
+ break;
+ }
+
+ /* Negotiate if the peer has started negotiating,
+ otherwise don't. We don't want to speak telnet with
+ non-telnet servers, like POP or SMTP. */
+ if(tn->please_negotiate && !tn->already_negotiated) {
+ negotiate(conn);
+ tn->already_negotiated = 1;
+ }
+ }
+ if(events.lNetworkEvents & FD_CLOSE) {
+ keepon = FALSE;
+ }
+ break;
+
+ }
+
+ if(data->set.timeout) {
+ now = Curl_tvnow();
+ if(Curl_tvdiff(now, conn->created) >= data->set.timeout) {
+ failf(data, "Time-out");
+ result = CURLE_OPERATION_TIMEDOUT;
+ keepon = FALSE;
+ }
+ }
+ }
+
+ /* We called WSACreateEvent, so call WSACloseEvent */
+ if(!close_event_func(event_handle)) {
+ infof(data, "WSACloseEvent failed (%d)", SOCKERRNO);
+ }
+
+ /* "Forget" pointers into the library we're about to free */
+ create_event_func = NULL;
+ close_event_func = NULL;
+ event_select_func = NULL;
+ enum_netevents_func = NULL;
+
+ /* We called LoadLibrary, so call FreeLibrary */
+ if(!FreeLibrary(wsock2))
+ infof(data, "FreeLibrary(wsock2) failed (%d)", ERRNO);
+#else
+ pfd[0].fd = sockfd;
+ pfd[0].events = POLLIN;
+
+ if(data->set.fread_func != (curl_read_callback)fread) {
+ poll_cnt = 1;
+ interval_ms = 100; /* poll user-supplied read function */
+ }
+ else {
+ /* really using fread, so infile is a FILE* */
+ pfd[1].fd = fileno((FILE *)data->set.in);
+ pfd[1].events = POLLIN;
+ poll_cnt = 2;
+ interval_ms = 1 * 1000;
+ }
+
+ while(keepon) {
+ switch (Curl_poll(pfd, poll_cnt, interval_ms)) {
+ case -1: /* error, stop reading */
+ keepon = FALSE;
+ continue;
+ case 0: /* timeout */
+ pfd[0].revents = 0;
+ pfd[1].revents = 0;
+ /* fall through */
+ default: /* read! */
+ if(pfd[0].revents & POLLIN) {
+ /* read data from network */
+ result = Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread);
+ /* read would've blocked. Loop again */
+ if(result == CURLE_AGAIN)
+ break;
+ /* returned not-zero, this an error */
+ else if(result) {
+ keepon = FALSE;
+ break;
+ }
+ /* returned zero but actually received 0 or less here,
+ the server closed the connection and we bail out */
+ else if(nread <= 0) {
+ keepon = FALSE;
+ break;
+ }
+
+ total_dl += nread;
+ Curl_pgrsSetDownloadCounter(data, total_dl);
+ result = telrcv(conn, (unsigned char *)buf, nread);
+ if(result) {
+ keepon = FALSE;
+ break;
+ }
+
+ /* Negotiate if the peer has started negotiating,
+ otherwise don't. We don't want to speak telnet with
+ non-telnet servers, like POP or SMTP. */
+ if(tn->please_negotiate && !tn->already_negotiated) {
+ negotiate(conn);
+ tn->already_negotiated = 1;
+ }
+ }
+
+ nread = 0;
+ if(poll_cnt == 2) {
+ if(pfd[1].revents & POLLIN) { /* read from in file */
+ nread = read(pfd[1].fd, buf, BUFSIZE - 1);
+ }
+ }
+ else {
+ /* read from user-supplied method */
+ nread = (int)data->set.fread_func(buf, 1, BUFSIZE - 1, data->set.in);
+ if(nread == CURL_READFUNC_ABORT) {
+ keepon = FALSE;
+ break;
+ }
+ if(nread == CURL_READFUNC_PAUSE)
+ break;
+ }
+
+ if(nread > 0) {
+ result = send_telnet_data(conn, buf, nread);
+ if(result) {
+ keepon = FALSE;
+ break;
+ }
+ total_ul += nread;
+ Curl_pgrsSetUploadCounter(data, total_ul);
+ }
+ else if(nread < 0)
+ keepon = FALSE;
+
+ break;
+ } /* poll switch statement */
+
+ if(data->set.timeout) {
+ now = Curl_tvnow();
+ if(Curl_tvdiff(now, conn->created) >= data->set.timeout) {
+ failf(data, "Time-out");
+ result = CURLE_OPERATION_TIMEDOUT;
+ keepon = FALSE;
+ }
+ }
+
+ if(Curl_pgrsUpdate(conn)) {
+ result = CURLE_ABORTED_BY_CALLBACK;
+ break;
+ }
+ }
+#endif
+ /* mark this as "no further transfer wanted" */
+ Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+
+ return result;
+}
+#endif
diff --git a/Utilities/cmcurl/lib/telnet.h b/Utilities/cmcurl/lib/telnet.h
new file mode 100644
index 000000000..ddb9e5473
--- /dev/null
+++ b/Utilities/cmcurl/lib/telnet.h
@@ -0,0 +1,29 @@
+#ifndef HEADER_CURL_TELNET_H
+#define HEADER_CURL_TELNET_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#ifndef CURL_DISABLE_TELNET
+extern const struct Curl_handler Curl_handler_telnet;
+#endif
+
+#endif /* HEADER_CURL_TELNET_H */
+
diff --git a/Utilities/cmcurl/lib/tftp.c b/Utilities/cmcurl/lib/tftp.c
new file mode 100644
index 000000000..4c5796f55
--- /dev/null
+++ b/Utilities/cmcurl/lib/tftp.c
@@ -0,0 +1,1376 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_TFTP
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "transfer.h"
+#include "sendf.h"
+#include "tftp.h"
+#include "progress.h"
+#include "connect.h"
+#include "strerror.h"
+#include "sockaddr.h" /* required for Curl_sockaddr_storage */
+#include "multiif.h"
+#include "url.h"
+#include "rawstr.h"
+#include "speedcheck.h"
+#include "curl_printf.h"
+#include "select.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* RFC2348 allows the block size to be negotiated */
+#define TFTP_BLKSIZE_DEFAULT 512
+#define TFTP_BLKSIZE_MIN 8
+#define TFTP_BLKSIZE_MAX 65464
+#define TFTP_OPTION_BLKSIZE "blksize"
+
+/* from RFC2349: */
+#define TFTP_OPTION_TSIZE "tsize"
+#define TFTP_OPTION_INTERVAL "timeout"
+
+typedef enum {
+ TFTP_MODE_NETASCII=0,
+ TFTP_MODE_OCTET
+} tftp_mode_t;
+
+typedef enum {
+ TFTP_STATE_START=0,
+ TFTP_STATE_RX,
+ TFTP_STATE_TX,
+ TFTP_STATE_FIN
+} tftp_state_t;
+
+typedef enum {
+ TFTP_EVENT_NONE = -1,
+ TFTP_EVENT_INIT = 0,
+ TFTP_EVENT_RRQ = 1,
+ TFTP_EVENT_WRQ = 2,
+ TFTP_EVENT_DATA = 3,
+ TFTP_EVENT_ACK = 4,
+ TFTP_EVENT_ERROR = 5,
+ TFTP_EVENT_OACK = 6,
+ TFTP_EVENT_TIMEOUT
+} tftp_event_t;
+
+typedef enum {
+ TFTP_ERR_UNDEF=0,
+ TFTP_ERR_NOTFOUND,
+ TFTP_ERR_PERM,
+ TFTP_ERR_DISKFULL,
+ TFTP_ERR_ILLEGAL,
+ TFTP_ERR_UNKNOWNID,
+ TFTP_ERR_EXISTS,
+ TFTP_ERR_NOSUCHUSER, /* This will never be triggered by this code */
+
+ /* The remaining error codes are internal to curl */
+ TFTP_ERR_NONE = -100,
+ TFTP_ERR_TIMEOUT,
+ TFTP_ERR_NORESPONSE
+} tftp_error_t;
+
+typedef struct tftp_packet {
+ unsigned char *data;
+} tftp_packet_t;
+
+typedef struct tftp_state_data {
+ tftp_state_t state;
+ tftp_mode_t mode;
+ tftp_error_t error;
+ tftp_event_t event;
+ struct connectdata *conn;
+ curl_socket_t sockfd;
+ int retries;
+ int retry_time;
+ int retry_max;
+ time_t start_time;
+ time_t max_time;
+ time_t rx_time;
+ unsigned short block;
+ struct Curl_sockaddr_storage local_addr;
+ struct Curl_sockaddr_storage remote_addr;
+ curl_socklen_t remote_addrlen;
+ int rbytes;
+ int sbytes;
+ int blksize;
+ int requested_blksize;
+ tftp_packet_t rpacket;
+ tftp_packet_t spacket;
+} tftp_state_data_t;
+
+
+/* Forward declarations */
+static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event);
+static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event);
+static CURLcode tftp_connect(struct connectdata *conn, bool *done);
+static CURLcode tftp_disconnect(struct connectdata *conn,
+ bool dead_connection);
+static CURLcode tftp_do(struct connectdata *conn, bool *done);
+static CURLcode tftp_done(struct connectdata *conn,
+ CURLcode, bool premature);
+static CURLcode tftp_setup_connection(struct connectdata * conn);
+static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done);
+static CURLcode tftp_doing(struct connectdata *conn, bool *dophase_done);
+static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks,
+ int numsocks);
+static CURLcode tftp_translate_code(tftp_error_t error);
+
+
+/*
+ * TFTP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_tftp = {
+ "TFTP", /* scheme */
+ tftp_setup_connection, /* setup_connection */
+ tftp_do, /* do_it */
+ tftp_done, /* done */
+ ZERO_NULL, /* do_more */
+ tftp_connect, /* connect_it */
+ tftp_multi_statemach, /* connecting */
+ tftp_doing, /* doing */
+ tftp_getsock, /* proto_getsock */
+ tftp_getsock, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ tftp_disconnect, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ PORT_TFTP, /* defport */
+ CURLPROTO_TFTP, /* protocol */
+ PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */
+};
+
+/**********************************************************
+ *
+ * tftp_set_timeouts -
+ *
+ * Set timeouts based on state machine state.
+ * Use user provided connect timeouts until DATA or ACK
+ * packet is received, then use user-provided transfer timeouts
+ *
+ *
+ **********************************************************/
+static CURLcode tftp_set_timeouts(tftp_state_data_t *state)
+{
+ time_t maxtime, timeout;
+ long timeout_ms;
+ bool start = (state->state == TFTP_STATE_START) ? TRUE : FALSE;
+
+ time(&state->start_time);
+
+ /* Compute drop-dead time */
+ timeout_ms = Curl_timeleft(state->conn->data, NULL, start);
+
+ if(timeout_ms < 0) {
+ /* time-out, bail out, go home */
+ failf(state->conn->data, "Connection time-out");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+
+ if(start) {
+
+ maxtime = (time_t)(timeout_ms + 500) / 1000;
+ state->max_time = state->start_time+maxtime;
+
+ /* Set per-block timeout to total */
+ timeout = maxtime;
+
+ /* Average restart after 5 seconds */
+ state->retry_max = (int)timeout/5;
+
+ if(state->retry_max < 1)
+ /* avoid division by zero below */
+ state->retry_max = 1;
+
+ /* Compute the re-start interval to suit the timeout */
+ state->retry_time = (int)timeout/state->retry_max;
+ if(state->retry_time<1)
+ state->retry_time=1;
+
+ }
+ else {
+ if(timeout_ms > 0)
+ maxtime = (time_t)(timeout_ms + 500) / 1000;
+ else
+ maxtime = 3600;
+
+ state->max_time = state->start_time+maxtime;
+
+ /* Set per-block timeout to total */
+ timeout = maxtime;
+
+ /* Average reposting an ACK after 5 seconds */
+ state->retry_max = (int)timeout/5;
+ }
+ /* But bound the total number */
+ if(state->retry_max<3)
+ state->retry_max=3;
+
+ if(state->retry_max>50)
+ state->retry_max=50;
+
+ /* Compute the re-ACK interval to suit the timeout */
+ state->retry_time = (int)(timeout/state->retry_max);
+ if(state->retry_time<1)
+ state->retry_time=1;
+
+ infof(state->conn->data,
+ "set timeouts for state %d; Total %ld, retry %d maxtry %d\n",
+ (int)state->state, (long)(state->max_time-state->start_time),
+ state->retry_time, state->retry_max);
+
+ /* init RX time */
+ time(&state->rx_time);
+
+ return CURLE_OK;
+}
+
+/**********************************************************
+ *
+ * tftp_set_send_first
+ *
+ * Event handler for the START state
+ *
+ **********************************************************/
+
+static void setpacketevent(tftp_packet_t *packet, unsigned short num)
+{
+ packet->data[0] = (unsigned char)(num >> 8);
+ packet->data[1] = (unsigned char)(num & 0xff);
+}
+
+
+static void setpacketblock(tftp_packet_t *packet, unsigned short num)
+{
+ packet->data[2] = (unsigned char)(num >> 8);
+ packet->data[3] = (unsigned char)(num & 0xff);
+}
+
+static unsigned short getrpacketevent(const tftp_packet_t *packet)
+{
+ return (unsigned short)((packet->data[0] << 8) | packet->data[1]);
+}
+
+static unsigned short getrpacketblock(const tftp_packet_t *packet)
+{
+ return (unsigned short)((packet->data[2] << 8) | packet->data[3]);
+}
+
+static size_t Curl_strnlen(const char *string, size_t maxlen)
+{
+ const char *end = memchr (string, '\0', maxlen);
+ return end ? (size_t) (end - string) : maxlen;
+}
+
+static const char *tftp_option_get(const char *buf, size_t len,
+ const char **option, const char **value)
+{
+ size_t loc;
+
+ loc = Curl_strnlen( buf, len );
+ loc++; /* NULL term */
+
+ if(loc >= len)
+ return NULL;
+ *option = buf;
+
+ loc += Curl_strnlen( buf+loc, len-loc );
+ loc++; /* NULL term */
+
+ if(loc > len)
+ return NULL;
+ *value = &buf[strlen(*option) + 1];
+
+ return &buf[loc];
+}
+
+static CURLcode tftp_parse_option_ack(tftp_state_data_t *state,
+ const char *ptr, int len)
+{
+ const char *tmp = ptr;
+ struct SessionHandle *data = state->conn->data;
+
+ /* if OACK doesn't contain blksize option, the default (512) must be used */
+ state->blksize = TFTP_BLKSIZE_DEFAULT;
+
+ while(tmp < ptr + len) {
+ const char *option, *value;
+
+ tmp = tftp_option_get(tmp, ptr + len - tmp, &option, &value);
+ if(tmp == NULL) {
+ failf(data, "Malformed ACK packet, rejecting");
+ return CURLE_TFTP_ILLEGAL;
+ }
+
+ infof(data, "got option=(%s) value=(%s)\n", option, value);
+
+ if(checkprefix(option, TFTP_OPTION_BLKSIZE)) {
+ long blksize;
+
+ blksize = strtol( value, NULL, 10 );
+
+ if(!blksize) {
+ failf(data, "invalid blocksize value in OACK packet");
+ return CURLE_TFTP_ILLEGAL;
+ }
+ else if(blksize > TFTP_BLKSIZE_MAX) {
+ failf(data, "%s (%d)", "blksize is larger than max supported",
+ TFTP_BLKSIZE_MAX);
+ return CURLE_TFTP_ILLEGAL;
+ }
+ else if(blksize < TFTP_BLKSIZE_MIN) {
+ failf(data, "%s (%d)", "blksize is smaller than min supported",
+ TFTP_BLKSIZE_MIN);
+ return CURLE_TFTP_ILLEGAL;
+ }
+ else if(blksize > state->requested_blksize) {
+ /* could realloc pkt buffers here, but the spec doesn't call out
+ * support for the server requesting a bigger blksize than the client
+ * requests */
+ failf(data, "%s (%ld)",
+ "server requested blksize larger than allocated", blksize);
+ return CURLE_TFTP_ILLEGAL;
+ }
+
+ state->blksize = (int)blksize;
+ infof(data, "%s (%d) %s (%d)\n", "blksize parsed from OACK",
+ state->blksize, "requested", state->requested_blksize);
+ }
+ else if(checkprefix(option, TFTP_OPTION_TSIZE)) {
+ long tsize = 0;
+
+ tsize = strtol( value, NULL, 10 );
+ infof(data, "%s (%ld)\n", "tsize parsed from OACK", tsize);
+
+ /* tsize should be ignored on upload: Who cares about the size of the
+ remote file? */
+ if(!data->set.upload) {
+ if(!tsize) {
+ failf(data, "invalid tsize -:%s:- value in OACK packet", value);
+ return CURLE_TFTP_ILLEGAL;
+ }
+ Curl_pgrsSetDownloadSize(data, tsize);
+ }
+ }
+ }
+
+ return CURLE_OK;
+}
+
+static size_t tftp_option_add(tftp_state_data_t *state, size_t csize,
+ char *buf, const char *option)
+{
+ if(( strlen(option) + csize + 1 ) > (size_t)state->blksize)
+ return 0;
+ strcpy(buf, option);
+ return strlen(option) + 1;
+}
+
+static CURLcode tftp_connect_for_tx(tftp_state_data_t *state,
+ tftp_event_t event)
+{
+ CURLcode result;
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+ struct SessionHandle *data = state->conn->data;
+
+ infof(data, "%s\n", "Connected for transmit");
+#endif
+ state->state = TFTP_STATE_TX;
+ result = tftp_set_timeouts(state);
+ if(result)
+ return result;
+ return tftp_tx(state, event);
+}
+
+static CURLcode tftp_connect_for_rx(tftp_state_data_t *state,
+ tftp_event_t event)
+{
+ CURLcode result;
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+ struct SessionHandle *data = state->conn->data;
+
+ infof(data, "%s\n", "Connected for receive");
+#endif
+ state->state = TFTP_STATE_RX;
+ result = tftp_set_timeouts(state);
+ if(result)
+ return result;
+ return tftp_rx(state, event);
+}
+
+static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
+{
+ size_t sbytes;
+ ssize_t senddata;
+ const char *mode = "octet";
+ char *filename;
+ char buf[64];
+ struct SessionHandle *data = state->conn->data;
+ CURLcode result = CURLE_OK;
+
+ /* Set ascii mode if -B flag was used */
+ if(data->set.prefer_ascii)
+ mode = "netascii";
+
+ switch(event) {
+
+ case TFTP_EVENT_INIT: /* Send the first packet out */
+ case TFTP_EVENT_TIMEOUT: /* Resend the first packet out */
+ /* Increment the retry counter, quit if over the limit */
+ state->retries++;
+ if(state->retries>state->retry_max) {
+ state->error = TFTP_ERR_NORESPONSE;
+ state->state = TFTP_STATE_FIN;
+ return result;
+ }
+
+ if(data->set.upload) {
+ /* If we are uploading, send an WRQ */
+ setpacketevent(&state->spacket, TFTP_EVENT_WRQ);
+ state->conn->data->req.upload_fromhere =
+ (char *)state->spacket.data+4;
+ if(data->state.infilesize != -1)
+ Curl_pgrsSetUploadSize(data, data->state.infilesize);
+ }
+ else {
+ /* If we are downloading, send an RRQ */
+ setpacketevent(&state->spacket, TFTP_EVENT_RRQ);
+ }
+ /* As RFC3617 describes the separator slash is not actually part of the
+ file name so we skip the always-present first letter of the path
+ string. */
+ filename = curl_easy_unescape(data, &state->conn->data->state.path[1], 0,
+ NULL);
+ if(!filename)
+ return CURLE_OUT_OF_MEMORY;
+
+ snprintf((char *)state->spacket.data+2,
+ state->blksize,
+ "%s%c%s%c", filename, '\0', mode, '\0');
+ sbytes = 4 + strlen(filename) + strlen(mode);
+
+ /* add tsize option */
+ if(data->set.upload && (data->state.infilesize != -1))
+ snprintf(buf, sizeof(buf), "%" CURL_FORMAT_CURL_OFF_T,
+ data->state.infilesize);
+ else
+ strcpy(buf, "0"); /* the destination is large enough */
+
+ sbytes += tftp_option_add(state, sbytes,
+ (char *)state->spacket.data+sbytes,
+ TFTP_OPTION_TSIZE);
+ sbytes += tftp_option_add(state, sbytes,
+ (char *)state->spacket.data+sbytes, buf);
+ /* add blksize option */
+ snprintf( buf, sizeof(buf), "%d", state->requested_blksize );
+ sbytes += tftp_option_add(state, sbytes,
+ (char *)state->spacket.data+sbytes,
+ TFTP_OPTION_BLKSIZE);
+ sbytes += tftp_option_add(state, sbytes,
+ (char *)state->spacket.data+sbytes, buf );
+
+ /* add timeout option */
+ snprintf( buf, sizeof(buf), "%d", state->retry_time);
+ sbytes += tftp_option_add(state, sbytes,
+ (char *)state->spacket.data+sbytes,
+ TFTP_OPTION_INTERVAL);
+ sbytes += tftp_option_add(state, sbytes,
+ (char *)state->spacket.data+sbytes, buf );
+
+ /* the typecase for the 3rd argument is mostly for systems that do
+ not have a size_t argument, like older unixes that want an 'int' */
+ senddata = sendto(state->sockfd, (void *)state->spacket.data,
+ (SEND_TYPE_ARG3)sbytes, 0,
+ state->conn->ip_addr->ai_addr,
+ state->conn->ip_addr->ai_addrlen);
+ if(senddata != (ssize_t)sbytes) {
+ failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+ }
+ free(filename);
+ break;
+
+ case TFTP_EVENT_OACK:
+ if(data->set.upload) {
+ result = tftp_connect_for_tx(state, event);
+ }
+ else {
+ result = tftp_connect_for_rx(state, event);
+ }
+ break;
+
+ case TFTP_EVENT_ACK: /* Connected for transmit */
+ result = tftp_connect_for_tx(state, event);
+ break;
+
+ case TFTP_EVENT_DATA: /* Connected for receive */
+ result = tftp_connect_for_rx(state, event);
+ break;
+
+ case TFTP_EVENT_ERROR:
+ state->state = TFTP_STATE_FIN;
+ break;
+
+ default:
+ failf(state->conn->data, "tftp_send_first: internal error");
+ break;
+ }
+
+ return result;
+}
+
+/* the next blocknum is x + 1 but it needs to wrap at an unsigned 16bit
+ boundary */
+#define NEXT_BLOCKNUM(x) (((x)+1)&0xffff)
+
+/**********************************************************
+ *
+ * tftp_rx
+ *
+ * Event handler for the RX state
+ *
+ **********************************************************/
+static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event)
+{
+ ssize_t sbytes;
+ int rblock;
+ struct SessionHandle *data = state->conn->data;
+
+ switch(event) {
+
+ case TFTP_EVENT_DATA:
+ /* Is this the block we expect? */
+ rblock = getrpacketblock(&state->rpacket);
+ if(NEXT_BLOCKNUM(state->block) == rblock) {
+ /* This is the expected block. Reset counters and ACK it. */
+ state->retries = 0;
+ }
+ else if(state->block == rblock) {
+ /* This is the last recently received block again. Log it and ACK it
+ again. */
+ infof(data, "Received last DATA packet block %d again.\n", rblock);
+ }
+ else {
+ /* totally unexpected, just log it */
+ infof(data,
+ "Received unexpected DATA packet block %d, expecting block %d\n",
+ rblock, NEXT_BLOCKNUM(state->block));
+ break;
+ }
+
+ /* ACK this block. */
+ state->block = (unsigned short)rblock;
+ setpacketevent(&state->spacket, TFTP_EVENT_ACK);
+ setpacketblock(&state->spacket, state->block);
+ sbytes = sendto(state->sockfd, (void *)state->spacket.data,
+ 4, SEND_4TH_ARG,
+ (struct sockaddr *)&state->remote_addr,
+ state->remote_addrlen);
+ if(sbytes < 0) {
+ failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+ return CURLE_SEND_ERROR;
+ }
+
+ /* Check if completed (That is, a less than full packet is received) */
+ if(state->rbytes < (ssize_t)state->blksize+4) {
+ state->state = TFTP_STATE_FIN;
+ }
+ else {
+ state->state = TFTP_STATE_RX;
+ }
+ time(&state->rx_time);
+ break;
+
+ case TFTP_EVENT_OACK:
+ /* ACK option acknowledgement so we can move on to data */
+ state->block = 0;
+ state->retries = 0;
+ setpacketevent(&state->spacket, TFTP_EVENT_ACK);
+ setpacketblock(&state->spacket, state->block);
+ sbytes = sendto(state->sockfd, (void *)state->spacket.data,
+ 4, SEND_4TH_ARG,
+ (struct sockaddr *)&state->remote_addr,
+ state->remote_addrlen);
+ if(sbytes < 0) {
+ failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+ return CURLE_SEND_ERROR;
+ }
+
+ /* we're ready to RX data */
+ state->state = TFTP_STATE_RX;
+ time(&state->rx_time);
+ break;
+
+ case TFTP_EVENT_TIMEOUT:
+ /* Increment the retry count and fail if over the limit */
+ state->retries++;
+ infof(data,
+ "Timeout waiting for block %d ACK. Retries = %d\n",
+ NEXT_BLOCKNUM(state->block), state->retries);
+ if(state->retries > state->retry_max) {
+ state->error = TFTP_ERR_TIMEOUT;
+ state->state = TFTP_STATE_FIN;
+ }
+ else {
+ /* Resend the previous ACK */
+ sbytes = sendto(state->sockfd, (void *)state->spacket.data,
+ 4, SEND_4TH_ARG,
+ (struct sockaddr *)&state->remote_addr,
+ state->remote_addrlen);
+ if(sbytes<0) {
+ failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+ return CURLE_SEND_ERROR;
+ }
+ }
+ break;
+
+ case TFTP_EVENT_ERROR:
+ setpacketevent(&state->spacket, TFTP_EVENT_ERROR);
+ setpacketblock(&state->spacket, state->block);
+ (void)sendto(state->sockfd, (void *)state->spacket.data,
+ 4, SEND_4TH_ARG,
+ (struct sockaddr *)&state->remote_addr,
+ state->remote_addrlen);
+ /* don't bother with the return code, but if the socket is still up we
+ * should be a good TFTP client and let the server know we're done */
+ state->state = TFTP_STATE_FIN;
+ break;
+
+ default:
+ failf(data, "%s", "tftp_rx: internal error");
+ return CURLE_TFTP_ILLEGAL; /* not really the perfect return code for
+ this */
+ }
+ return CURLE_OK;
+}
+
+/**********************************************************
+ *
+ * tftp_tx
+ *
+ * Event handler for the TX state
+ *
+ **********************************************************/
+static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
+{
+ struct SessionHandle *data = state->conn->data;
+ ssize_t sbytes;
+ int rblock;
+ CURLcode result = CURLE_OK;
+ struct SingleRequest *k = &data->req;
+
+ switch(event) {
+
+ case TFTP_EVENT_ACK:
+ case TFTP_EVENT_OACK:
+ if(event == TFTP_EVENT_ACK) {
+ /* Ack the packet */
+ rblock = getrpacketblock(&state->rpacket);
+
+ if(rblock != state->block &&
+ /* There's a bug in tftpd-hpa that causes it to send us an ack for
+ * 65535 when the block number wraps to 0. So when we're expecting
+ * 0, also accept 65535. See
+ * http://syslinux.zytor.com/archives/2010-September/015253.html
+ * */
+ !(state->block == 0 && rblock == 65535)) {
+ /* This isn't the expected block. Log it and up the retry counter */
+ infof(data, "Received ACK for block %d, expecting %d\n",
+ rblock, state->block);
+ state->retries++;
+ /* Bail out if over the maximum */
+ if(state->retries>state->retry_max) {
+ failf(data, "tftp_tx: giving up waiting for block %d ack",
+ state->block);
+ result = CURLE_SEND_ERROR;
+ }
+ else {
+ /* Re-send the data packet */
+ sbytes = sendto(state->sockfd, (void *)state->spacket.data,
+ 4+state->sbytes, SEND_4TH_ARG,
+ (struct sockaddr *)&state->remote_addr,
+ state->remote_addrlen);
+ /* Check all sbytes were sent */
+ if(sbytes<0) {
+ failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+ result = CURLE_SEND_ERROR;
+ }
+ }
+
+ return result;
+ }
+ /* This is the expected packet. Reset the counters and send the next
+ block */
+ time(&state->rx_time);
+ state->block++;
+ }
+ else
+ state->block = 1; /* first data block is 1 when using OACK */
+
+ state->retries = 0;
+ setpacketevent(&state->spacket, TFTP_EVENT_DATA);
+ setpacketblock(&state->spacket, state->block);
+ if(state->block > 1 && state->sbytes < (int)state->blksize) {
+ state->state = TFTP_STATE_FIN;
+ return CURLE_OK;
+ }
+
+ result = Curl_fillreadbuffer(state->conn, state->blksize, &state->sbytes);
+ if(result)
+ return result;
+
+ sbytes = sendto(state->sockfd, (void *) state->spacket.data,
+ 4 + state->sbytes, SEND_4TH_ARG,
+ (struct sockaddr *)&state->remote_addr,
+ state->remote_addrlen);
+ /* Check all sbytes were sent */
+ if(sbytes<0) {
+ failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+ return CURLE_SEND_ERROR;
+ }
+ /* Update the progress meter */
+ k->writebytecount += state->sbytes;
+ Curl_pgrsSetUploadCounter(data, k->writebytecount);
+ break;
+
+ case TFTP_EVENT_TIMEOUT:
+ /* Increment the retry counter and log the timeout */
+ state->retries++;
+ infof(data, "Timeout waiting for block %d ACK. "
+ " Retries = %d\n", NEXT_BLOCKNUM(state->block), state->retries);
+ /* Decide if we've had enough */
+ if(state->retries > state->retry_max) {
+ state->error = TFTP_ERR_TIMEOUT;
+ state->state = TFTP_STATE_FIN;
+ }
+ else {
+ /* Re-send the data packet */
+ sbytes = sendto(state->sockfd, (void *)state->spacket.data,
+ 4+state->sbytes, SEND_4TH_ARG,
+ (struct sockaddr *)&state->remote_addr,
+ state->remote_addrlen);
+ /* Check all sbytes were sent */
+ if(sbytes<0) {
+ failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+ return CURLE_SEND_ERROR;
+ }
+ /* since this was a re-send, we remain at the still byte position */
+ Curl_pgrsSetUploadCounter(data, k->writebytecount);
+ }
+ break;
+
+ case TFTP_EVENT_ERROR:
+ state->state = TFTP_STATE_FIN;
+ setpacketevent(&state->spacket, TFTP_EVENT_ERROR);
+ setpacketblock(&state->spacket, state->block);
+ (void)sendto(state->sockfd, (void *)state->spacket.data, 4, SEND_4TH_ARG,
+ (struct sockaddr *)&state->remote_addr,
+ state->remote_addrlen);
+ /* don't bother with the return code, but if the socket is still up we
+ * should be a good TFTP client and let the server know we're done */
+ state->state = TFTP_STATE_FIN;
+ break;
+
+ default:
+ failf(data, "tftp_tx: internal error, event: %i", (int)(event));
+ break;
+ }
+
+ return result;
+}
+
+/**********************************************************
+ *
+ * tftp_translate_code
+ *
+ * Translate internal error codes to CURL error codes
+ *
+ **********************************************************/
+static CURLcode tftp_translate_code(tftp_error_t error)
+{
+ CURLcode result = CURLE_OK;
+
+ if(error != TFTP_ERR_NONE) {
+ switch(error) {
+ case TFTP_ERR_NOTFOUND:
+ result = CURLE_TFTP_NOTFOUND;
+ break;
+ case TFTP_ERR_PERM:
+ result = CURLE_TFTP_PERM;
+ break;
+ case TFTP_ERR_DISKFULL:
+ result = CURLE_REMOTE_DISK_FULL;
+ break;
+ case TFTP_ERR_UNDEF:
+ case TFTP_ERR_ILLEGAL:
+ result = CURLE_TFTP_ILLEGAL;
+ break;
+ case TFTP_ERR_UNKNOWNID:
+ result = CURLE_TFTP_UNKNOWNID;
+ break;
+ case TFTP_ERR_EXISTS:
+ result = CURLE_REMOTE_FILE_EXISTS;
+ break;
+ case TFTP_ERR_NOSUCHUSER:
+ result = CURLE_TFTP_NOSUCHUSER;
+ break;
+ case TFTP_ERR_TIMEOUT:
+ result = CURLE_OPERATION_TIMEDOUT;
+ break;
+ case TFTP_ERR_NORESPONSE:
+ result = CURLE_COULDNT_CONNECT;
+ break;
+ default:
+ result = CURLE_ABORTED_BY_CALLBACK;
+ break;
+ }
+ }
+ else
+ result = CURLE_OK;
+
+ return result;
+}
+
+/**********************************************************
+ *
+ * tftp_state_machine
+ *
+ * The tftp state machine event dispatcher
+ *
+ **********************************************************/
+static CURLcode tftp_state_machine(tftp_state_data_t *state,
+ tftp_event_t event)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = state->conn->data;
+
+ switch(state->state) {
+ case TFTP_STATE_START:
+ DEBUGF(infof(data, "TFTP_STATE_START\n"));
+ result = tftp_send_first(state, event);
+ break;
+ case TFTP_STATE_RX:
+ DEBUGF(infof(data, "TFTP_STATE_RX\n"));
+ result = tftp_rx(state, event);
+ break;
+ case TFTP_STATE_TX:
+ DEBUGF(infof(data, "TFTP_STATE_TX\n"));
+ result = tftp_tx(state, event);
+ break;
+ case TFTP_STATE_FIN:
+ infof(data, "%s\n", "TFTP finished");
+ break;
+ default:
+ DEBUGF(infof(data, "STATE: %d\n", state->state));
+ failf(data, "%s", "Internal state machine error");
+ result = CURLE_TFTP_ILLEGAL;
+ break;
+ }
+
+ return result;
+}
+
+/**********************************************************
+ *
+ * tftp_disconnect
+ *
+ * The disconnect callback
+ *
+ **********************************************************/
+static CURLcode tftp_disconnect(struct connectdata *conn, bool dead_connection)
+{
+ tftp_state_data_t *state = conn->proto.tftpc;
+ (void) dead_connection;
+
+ /* done, free dynamically allocated pkt buffers */
+ if(state) {
+ Curl_safefree(state->rpacket.data);
+ Curl_safefree(state->spacket.data);
+ free(state);
+ }
+
+ return CURLE_OK;
+}
+
+/**********************************************************
+ *
+ * tftp_connect
+ *
+ * The connect callback
+ *
+ **********************************************************/
+static CURLcode tftp_connect(struct connectdata *conn, bool *done)
+{
+ tftp_state_data_t *state;
+ int blksize, rc;
+
+ blksize = TFTP_BLKSIZE_DEFAULT;
+
+ state = conn->proto.tftpc = calloc(1, sizeof(tftp_state_data_t));
+ if(!state)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* alloc pkt buffers based on specified blksize */
+ if(conn->data->set.tftp_blksize) {
+ blksize = (int)conn->data->set.tftp_blksize;
+ if(blksize > TFTP_BLKSIZE_MAX || blksize < TFTP_BLKSIZE_MIN )
+ return CURLE_TFTP_ILLEGAL;
+ }
+
+ if(!state->rpacket.data) {
+ state->rpacket.data = calloc(1, blksize + 2 + 2);
+
+ if(!state->rpacket.data)
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ if(!state->spacket.data) {
+ state->spacket.data = calloc(1, blksize + 2 + 2);
+
+ if(!state->spacket.data)
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ /* we don't keep TFTP connections up bascially because there's none or very
+ * little gain for UDP */
+ connclose(conn, "TFTP");
+
+ state->conn = conn;
+ state->sockfd = state->conn->sock[FIRSTSOCKET];
+ state->state = TFTP_STATE_START;
+ state->error = TFTP_ERR_NONE;
+ state->blksize = TFTP_BLKSIZE_DEFAULT;
+ state->requested_blksize = blksize;
+
+ ((struct sockaddr *)&state->local_addr)->sa_family =
+ (unsigned short)(conn->ip_addr->ai_family);
+
+ tftp_set_timeouts(state);
+
+ if(!conn->bits.bound) {
+ /* If not already bound, bind to any interface, random UDP port. If it is
+ * reused or a custom local port was desired, this has already been done!
+ *
+ * We once used the size of the local_addr struct as the third argument
+ * for bind() to better work with IPv6 or whatever size the struct could
+ * have, but we learned that at least Tru64, AIX and IRIX *requires* the
+ * size of that argument to match the exact size of a 'sockaddr_in' struct
+ * when running IPv4-only.
+ *
+ * Therefore we use the size from the address we connected to, which we
+ * assume uses the same IP version and thus hopefully this works for both
+ * IPv4 and IPv6...
+ */
+ rc = bind(state->sockfd, (struct sockaddr *)&state->local_addr,
+ conn->ip_addr->ai_addrlen);
+ if(rc) {
+ failf(conn->data, "bind() failed; %s",
+ Curl_strerror(conn, SOCKERRNO));
+ return CURLE_COULDNT_CONNECT;
+ }
+ conn->bits.bound = TRUE;
+ }
+
+ Curl_pgrsStartNow(conn->data);
+
+ *done = TRUE;
+
+ return CURLE_OK;
+}
+
+/**********************************************************
+ *
+ * tftp_done
+ *
+ * The done callback
+ *
+ **********************************************************/
+static CURLcode tftp_done(struct connectdata *conn, CURLcode status,
+ bool premature)
+{
+ CURLcode result = CURLE_OK;
+ tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc;
+
+ (void)status; /* unused */
+ (void)premature; /* not used */
+
+ if(Curl_pgrsDone(conn))
+ return CURLE_ABORTED_BY_CALLBACK;
+
+ /* If we have encountered an error */
+ if(state)
+ result = tftp_translate_code(state->error);
+
+ return result;
+}
+
+/**********************************************************
+ *
+ * tftp_getsock
+ *
+ * The getsock callback
+ *
+ **********************************************************/
+static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks,
+ int numsocks)
+{
+ if(!numsocks)
+ return GETSOCK_BLANK;
+
+ socks[0] = conn->sock[FIRSTSOCKET];
+
+ return GETSOCK_READSOCK(0);
+}
+
+/**********************************************************
+ *
+ * tftp_receive_packet
+ *
+ * Called once select fires and data is ready on the socket
+ *
+ **********************************************************/
+static CURLcode tftp_receive_packet(struct connectdata *conn)
+{
+ struct Curl_sockaddr_storage fromaddr;
+ curl_socklen_t fromlen;
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc;
+ struct SingleRequest *k = &data->req;
+
+ /* Receive the packet */
+ fromlen = sizeof(fromaddr);
+ state->rbytes = (int)recvfrom(state->sockfd,
+ (void *)state->rpacket.data,
+ state->blksize+4,
+ 0,
+ (struct sockaddr *)&fromaddr,
+ &fromlen);
+ if(state->remote_addrlen==0) {
+ memcpy(&state->remote_addr, &fromaddr, fromlen);
+ state->remote_addrlen = fromlen;
+ }
+
+ /* Sanity check packet length */
+ if(state->rbytes < 4) {
+ failf(data, "Received too short packet");
+ /* Not a timeout, but how best to handle it? */
+ state->event = TFTP_EVENT_TIMEOUT;
+ }
+ else {
+ /* The event is given by the TFTP packet time */
+ state->event = (tftp_event_t)getrpacketevent(&state->rpacket);
+
+ switch(state->event) {
+ case TFTP_EVENT_DATA:
+ /* Don't pass to the client empty or retransmitted packets */
+ if(state->rbytes > 4 &&
+ (NEXT_BLOCKNUM(state->block) == getrpacketblock(&state->rpacket))) {
+ result = Curl_client_write(conn, CLIENTWRITE_BODY,
+ (char *)state->rpacket.data+4,
+ state->rbytes-4);
+ if(result) {
+ tftp_state_machine(state, TFTP_EVENT_ERROR);
+ return result;
+ }
+ k->bytecount += state->rbytes-4;
+ Curl_pgrsSetDownloadCounter(data, (curl_off_t) k->bytecount);
+ }
+ break;
+ case TFTP_EVENT_ERROR:
+ state->error = (tftp_error_t)getrpacketblock(&state->rpacket);
+ infof(data, "%s\n", (const char *)state->rpacket.data+4);
+ break;
+ case TFTP_EVENT_ACK:
+ break;
+ case TFTP_EVENT_OACK:
+ result = tftp_parse_option_ack(state,
+ (const char *)state->rpacket.data+2,
+ state->rbytes-2);
+ if(result)
+ return result;
+ break;
+ case TFTP_EVENT_RRQ:
+ case TFTP_EVENT_WRQ:
+ default:
+ failf(data, "%s", "Internal error: Unexpected packet");
+ break;
+ }
+
+ /* Update the progress meter */
+ if(Curl_pgrsUpdate(conn)) {
+ tftp_state_machine(state, TFTP_EVENT_ERROR);
+ return CURLE_ABORTED_BY_CALLBACK;
+ }
+ }
+ return result;
+}
+
+/**********************************************************
+ *
+ * tftp_state_timeout
+ *
+ * Check if timeouts have been reached
+ *
+ **********************************************************/
+static long tftp_state_timeout(struct connectdata *conn, tftp_event_t *event)
+{
+ time_t current;
+ tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc;
+
+ if(event)
+ *event = TFTP_EVENT_NONE;
+
+ time(&current);
+ if(current > state->max_time) {
+ DEBUGF(infof(conn->data, "timeout: %ld > %ld\n",
+ (long)current, (long)state->max_time));
+ state->error = TFTP_ERR_TIMEOUT;
+ state->state = TFTP_STATE_FIN;
+ return 0;
+ }
+ else if(current > state->rx_time+state->retry_time) {
+ if(event)
+ *event = TFTP_EVENT_TIMEOUT;
+ time(&state->rx_time); /* update even though we received nothing */
+ }
+
+ /* there's a typecast below here since 'time_t' may in fact be larger than
+ 'long', but we estimate that a 'long' will still be able to hold number
+ of seconds even if "only" 32 bit */
+ return (long)(state->max_time - current);
+}
+
+/**********************************************************
+ *
+ * tftp_multi_statemach
+ *
+ * Handle single RX socket event and return
+ *
+ **********************************************************/
+static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done)
+{
+ int rc;
+ tftp_event_t event;
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc;
+ long timeout_ms = tftp_state_timeout(conn, &event);
+
+ *done = FALSE;
+
+ if(timeout_ms <= 0) {
+ failf(data, "TFTP response timeout");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+ else if(event != TFTP_EVENT_NONE) {
+ result = tftp_state_machine(state, event);
+ if(result)
+ return result;
+ *done = (state->state == TFTP_STATE_FIN) ? TRUE : FALSE;
+ if(*done)
+ /* Tell curl we're done */
+ Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+ }
+ else {
+ /* no timeouts to handle, check our socket */
+ rc = Curl_socket_ready(state->sockfd, CURL_SOCKET_BAD, 0);
+
+ if(rc == -1) {
+ /* bail out */
+ int error = SOCKERRNO;
+ failf(data, "%s", Curl_strerror(conn, error));
+ state->event = TFTP_EVENT_ERROR;
+ }
+ else if(rc != 0) {
+ result = tftp_receive_packet(conn);
+ if(result)
+ return result;
+ result = tftp_state_machine(state, state->event);
+ if(result)
+ return result;
+ *done = (state->state == TFTP_STATE_FIN) ? TRUE : FALSE;
+ if(*done)
+ /* Tell curl we're done */
+ Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+ }
+ /* if rc == 0, then select() timed out */
+ }
+
+ return result;
+}
+
+/**********************************************************
+ *
+ * tftp_doing
+ *
+ * Called from multi.c while DOing
+ *
+ **********************************************************/
+static CURLcode tftp_doing(struct connectdata *conn, bool *dophase_done)
+{
+ CURLcode result;
+ result = tftp_multi_statemach(conn, dophase_done);
+
+ if(*dophase_done) {
+ DEBUGF(infof(conn->data, "DO phase is complete\n"));
+ }
+ else if(!result) {
+ /* The multi code doesn't have this logic for the DOING state so we
+ provide it for TFTP since it may do the entire transfer in this
+ state. */
+ if(Curl_pgrsUpdate(conn))
+ result = CURLE_ABORTED_BY_CALLBACK;
+ else
+ result = Curl_speedcheck(conn->data, Curl_tvnow());
+ }
+ return result;
+}
+
+/**********************************************************
+ *
+ * tftp_peform
+ *
+ * Entry point for transfer from tftp_do, sarts state mach
+ *
+ **********************************************************/
+static CURLcode tftp_perform(struct connectdata *conn, bool *dophase_done)
+{
+ CURLcode result = CURLE_OK;
+ tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc;
+
+ *dophase_done = FALSE;
+
+ result = tftp_state_machine(state, TFTP_EVENT_INIT);
+
+ if((state->state == TFTP_STATE_FIN) || result)
+ return result;
+
+ tftp_multi_statemach(conn, dophase_done);
+
+ if(*dophase_done)
+ DEBUGF(infof(conn->data, "DO phase is complete\n"));
+
+ return result;
+}
+
+
+/**********************************************************
+ *
+ * tftp_do
+ *
+ * The do callback
+ *
+ * This callback initiates the TFTP transfer
+ *
+ **********************************************************/
+
+static CURLcode tftp_do(struct connectdata *conn, bool *done)
+{
+ tftp_state_data_t *state;
+ CURLcode result;
+
+ *done = FALSE;
+
+ if(!conn->proto.tftpc) {
+ result = tftp_connect(conn, done);
+ if(result)
+ return result;
+ }
+
+ state = (tftp_state_data_t *)conn->proto.tftpc;
+ if(!state)
+ return CURLE_BAD_CALLING_ORDER;
+
+ result = tftp_perform(conn, done);
+
+ /* If tftp_perform() returned an error, use that for return code. If it
+ was OK, see if tftp_translate_code() has an error. */
+ if(!result)
+ /* If we have encountered an internal tftp error, translate it. */
+ result = tftp_translate_code(state->error);
+
+ return result;
+}
+
+static CURLcode tftp_setup_connection(struct connectdata * conn)
+{
+ struct SessionHandle *data = conn->data;
+ char * type;
+ char command;
+
+ conn->socktype = SOCK_DGRAM; /* UDP datagram based */
+
+ /* TFTP URLs support an extension like ";mode=<typecode>" that
+ * we'll try to get now! */
+ type = strstr(data->state.path, ";mode=");
+
+ if(!type)
+ type = strstr(conn->host.rawalloc, ";mode=");
+
+ if(type) {
+ *type = 0; /* it was in the middle of the hostname */
+ command = Curl_raw_toupper(type[6]);
+
+ switch (command) {
+ case 'A': /* ASCII mode */
+ case 'N': /* NETASCII mode */
+ data->set.prefer_ascii = TRUE;
+ break;
+
+ case 'O': /* octet mode */
+ case 'I': /* binary mode */
+ default:
+ /* switch off ASCII */
+ data->set.prefer_ascii = FALSE;
+ break;
+ }
+ }
+
+ return CURLE_OK;
+}
+#endif
diff --git a/Utilities/cmcurl/lib/tftp.h b/Utilities/cmcurl/lib/tftp.h
new file mode 100644
index 000000000..117b40f62
--- /dev/null
+++ b/Utilities/cmcurl/lib/tftp.h
@@ -0,0 +1,29 @@
+#ifndef HEADER_CURL_TFTP_H
+#define HEADER_CURL_TFTP_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#ifndef CURL_DISABLE_TFTP
+extern const struct Curl_handler Curl_handler_tftp;
+#endif
+
+#endif /* HEADER_CURL_TFTP_H */
+
diff --git a/Utilities/cmcurl/lib/timeval.c b/Utilities/cmcurl/lib/timeval.c
new file mode 100644
index 000000000..45731ac59
--- /dev/null
+++ b/Utilities/cmcurl/lib/timeval.c
@@ -0,0 +1,142 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "timeval.h"
+
+#if defined(WIN32) && !defined(MSDOS)
+
+struct timeval curlx_tvnow(void)
+{
+ /*
+ ** GetTickCount() is available on _all_ Windows versions from W95 up
+ ** to nowadays. Returns milliseconds elapsed since last system boot,
+ ** increases monotonically and wraps once 49.7 days have elapsed.
+ */
+ struct timeval now;
+#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_VISTA) || \
+ (_WIN32_WINNT < _WIN32_WINNT_VISTA)
+ DWORD milliseconds = GetTickCount();
+ now.tv_sec = milliseconds / 1000;
+ now.tv_usec = (milliseconds % 1000) * 1000;
+#else
+ ULONGLONG milliseconds = GetTickCount64();
+ now.tv_sec = (long) (milliseconds / 1000);
+ now.tv_usec = (long) (milliseconds % 1000) * 1000;
+#endif
+
+ return now;
+}
+
+#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC)
+
+struct timeval curlx_tvnow(void)
+{
+ /*
+ ** clock_gettime() is granted to be increased monotonically when the
+ ** monotonic clock is queried. Time starting point is unspecified, it
+ ** could be the system start-up time, the Epoch, or something else,
+ ** in any case the time starting point does not change once that the
+ ** system has started up.
+ */
+ struct timeval now;
+ struct timespec tsnow;
+ if(0 == clock_gettime(CLOCK_MONOTONIC, &tsnow)) {
+ now.tv_sec = tsnow.tv_sec;
+ now.tv_usec = tsnow.tv_nsec / 1000;
+ }
+ /*
+ ** Even when the configure process has truly detected monotonic clock
+ ** availability, it might happen that it is not actually available at
+ ** run-time. When this occurs simply fallback to other time source.
+ */
+#ifdef HAVE_GETTIMEOFDAY
+ else
+ (void)gettimeofday(&now, NULL);
+#else
+ else {
+ now.tv_sec = (long)time(NULL);
+ now.tv_usec = 0;
+ }
+#endif
+ return now;
+}
+
+#elif defined(HAVE_GETTIMEOFDAY)
+
+struct timeval curlx_tvnow(void)
+{
+ /*
+ ** gettimeofday() is not granted to be increased monotonically, due to
+ ** clock drifting and external source time synchronization it can jump
+ ** forward or backward in time.
+ */
+ struct timeval now;
+ (void)gettimeofday(&now, NULL);
+ return now;
+}
+
+#else
+
+struct timeval curlx_tvnow(void)
+{
+ /*
+ ** time() returns the value of time in seconds since the Epoch.
+ */
+ struct timeval now;
+ now.tv_sec = (long)time(NULL);
+ now.tv_usec = 0;
+ return now;
+}
+
+#endif
+
+/*
+ * Make sure that the first argument is the more recent time, as otherwise
+ * we'll get a weird negative time-diff back...
+ *
+ * Returns: the time difference in number of milliseconds.
+ */
+long curlx_tvdiff(struct timeval newer, struct timeval older)
+{
+ return (newer.tv_sec-older.tv_sec)*1000+
+ (long)(newer.tv_usec-older.tv_usec)/1000;
+}
+
+/*
+ * Same as curlx_tvdiff but with full usec resolution.
+ *
+ * Returns: the time difference in seconds with subsecond resolution.
+ */
+double curlx_tvdiff_secs(struct timeval newer, struct timeval older)
+{
+ if(newer.tv_sec != older.tv_sec)
+ return (double)(newer.tv_sec-older.tv_sec)+
+ (double)(newer.tv_usec-older.tv_usec)/1000000.0;
+ else
+ return (double)(newer.tv_usec-older.tv_usec)/1000000.0;
+}
+
+/* return the number of seconds in the given input timeval struct */
+long Curl_tvlong(struct timeval t1)
+{
+ return t1.tv_sec;
+}
diff --git a/Utilities/cmcurl/lib/timeval.h b/Utilities/cmcurl/lib/timeval.h
new file mode 100644
index 000000000..3f1b9ea70
--- /dev/null
+++ b/Utilities/cmcurl/lib/timeval.h
@@ -0,0 +1,58 @@
+#ifndef HEADER_CURL_TIMEVAL_H
+#define HEADER_CURL_TIMEVAL_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * CAUTION: this header is designed to work when included by the app-side
+ * as well as the library. Do not mix with library internals!
+ */
+
+#include "curl_setup.h"
+
+struct timeval curlx_tvnow(void);
+
+/*
+ * Make sure that the first argument (t1) is the more recent time and t2 is
+ * the older time, as otherwise you get a weird negative time-diff back...
+ *
+ * Returns: the time difference in number of milliseconds.
+ */
+long curlx_tvdiff(struct timeval t1, struct timeval t2);
+
+/*
+ * Same as curlx_tvdiff but with full usec resolution.
+ *
+ * Returns: the time difference in seconds with subsecond resolution.
+ */
+double curlx_tvdiff_secs(struct timeval t1, struct timeval t2);
+
+long Curl_tvlong(struct timeval t1);
+
+/* These two defines below exist to provide the older API for library
+ internals only. */
+#define Curl_tvnow() curlx_tvnow()
+#define Curl_tvdiff(x,y) curlx_tvdiff(x,y)
+#define Curl_tvdiff_secs(x,y) curlx_tvdiff_secs(x,y)
+
+#endif /* HEADER_CURL_TIMEVAL_H */
+
diff --git a/Utilities/cmcurl/lib/transfer.c b/Utilities/cmcurl/lib/transfer.c
new file mode 100644
index 000000000..718139b32
--- /dev/null
+++ b/Utilities/cmcurl/lib/transfer.c
@@ -0,0 +1,2006 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "strtoofft.h"
+#include "strequal.h"
+#include "rawstr.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+#ifndef HAVE_SOCKET
+#error "We can't compile without socket() support!"
+#endif
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "netrc.h"
+
+#include "content_encoding.h"
+#include "hostip.h"
+#include "transfer.h"
+#include "sendf.h"
+#include "speedcheck.h"
+#include "progress.h"
+#include "http.h"
+#include "url.h"
+#include "getinfo.h"
+#include "vtls/vtls.h"
+#include "http_digest.h"
+#include "curl_ntlm.h"
+#include "http_negotiate.h"
+#include "share.h"
+#include "select.h"
+#include "multiif.h"
+#include "connect.h"
+#include "non-ascii.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+ * This function will call the read callback to fill our buffer with data
+ * to upload.
+ */
+CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
+{
+ struct SessionHandle *data = conn->data;
+ size_t buffersize = (size_t)bytes;
+ int nread;
+#ifdef CURL_DOES_CONVERSIONS
+ bool sending_http_headers = FALSE;
+
+ if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) {
+ const struct HTTP *http = data->req.protop;
+
+ if(http->sending == HTTPSEND_REQUEST)
+ /* We're sending the HTTP request headers, not the data.
+ Remember that so we don't re-translate them into garbage. */
+ sending_http_headers = TRUE;
+ }
+#endif
+
+ if(data->req.upload_chunky) {
+ /* if chunked Transfer-Encoding */
+ buffersize -= (8 + 2 + 2); /* 32bit hex + CRLF + CRLF */
+ data->req.upload_fromhere += (8 + 2); /* 32bit hex + CRLF */
+ }
+
+ /* this function returns a size_t, so we typecast to int to prevent warnings
+ with picky compilers */
+ nread = (int)data->set.fread_func(data->req.upload_fromhere, 1,
+ buffersize, data->set.in);
+
+ if(nread == CURL_READFUNC_ABORT) {
+ failf(data, "operation aborted by callback");
+ *nreadp = 0;
+ return CURLE_ABORTED_BY_CALLBACK;
+ }
+ else if(nread == CURL_READFUNC_PAUSE) {
+
+ if(conn->handler->flags & PROTOPT_NONETWORK) {
+ /* protocols that work without network cannot be paused. This is
+ actually only FILE:// just now, and it can't pause since the transfer
+ isn't done using the "normal" procedure. */
+ failf(data, "Read callback asked for PAUSE when not supported!");
+ return CURLE_READ_ERROR;
+ }
+ else {
+ struct SingleRequest *k = &data->req;
+ /* CURL_READFUNC_PAUSE pauses read callbacks that feed socket writes */
+ k->keepon |= KEEP_SEND_PAUSE; /* mark socket send as paused */
+ if(data->req.upload_chunky) {
+ /* Back out the preallocation done above */
+ data->req.upload_fromhere -= (8 + 2);
+ }
+ *nreadp = 0;
+ }
+ return CURLE_OK; /* nothing was read */
+ }
+ else if((size_t)nread > buffersize) {
+ /* the read function returned a too large value */
+ *nreadp = 0;
+ failf(data, "read function returned funny value");
+ return CURLE_READ_ERROR;
+ }
+
+ if(!data->req.forbidchunk && data->req.upload_chunky) {
+ /* if chunked Transfer-Encoding
+ * build chunk:
+ *
+ * <HEX SIZE> CRLF
+ * <DATA> CRLF
+ */
+ /* On non-ASCII platforms the <DATA> may or may not be
+ translated based on set.prefer_ascii while the protocol
+ portion must always be translated to the network encoding.
+ To further complicate matters, line end conversion might be
+ done later on, so we need to prevent CRLFs from becoming
+ CRCRLFs if that's the case. To do this we use bare LFs
+ here, knowing they'll become CRLFs later on.
+ */
+
+ char hexbuffer[11];
+ const char *endofline_native;
+ const char *endofline_network;
+ int hexlen;
+
+ if(
+#ifdef CURL_DO_LINEEND_CONV
+ (data->set.prefer_ascii) ||
+#endif
+ (data->set.crlf)) {
+ /* \n will become \r\n later on */
+ endofline_native = "\n";
+ endofline_network = "\x0a";
+ }
+ else {
+ endofline_native = "\r\n";
+ endofline_network = "\x0d\x0a";
+ }
+ hexlen = snprintf(hexbuffer, sizeof(hexbuffer),
+ "%x%s", nread, endofline_native);
+
+ /* move buffer pointer */
+ data->req.upload_fromhere -= hexlen;
+ nread += hexlen;
+
+ /* copy the prefix to the buffer, leaving out the NUL */
+ memcpy(data->req.upload_fromhere, hexbuffer, hexlen);
+
+ /* always append ASCII CRLF to the data */
+ memcpy(data->req.upload_fromhere + nread,
+ endofline_network,
+ strlen(endofline_network));
+
+#ifdef CURL_DOES_CONVERSIONS
+ CURLcode result;
+ int length;
+ if(data->set.prefer_ascii) {
+ /* translate the protocol and data */
+ length = nread;
+ }
+ else {
+ /* just translate the protocol portion */
+ length = strlen(hexbuffer);
+ }
+ result = Curl_convert_to_network(data, data->req.upload_fromhere, length);
+ /* Curl_convert_to_network calls failf if unsuccessful */
+ if(result)
+ return result;
+#endif /* CURL_DOES_CONVERSIONS */
+
+ if((nread - hexlen) == 0)
+ /* mark this as done once this chunk is transferred */
+ data->req.upload_done = TRUE;
+
+ nread+=(int)strlen(endofline_native); /* for the added end of line */
+ }
+#ifdef CURL_DOES_CONVERSIONS
+ else if((data->set.prefer_ascii) && (!sending_http_headers)) {
+ CURLcode result;
+ result = Curl_convert_to_network(data, data->req.upload_fromhere, nread);
+ /* Curl_convert_to_network calls failf if unsuccessful */
+ if(result)
+ return result;
+ }
+#endif /* CURL_DOES_CONVERSIONS */
+
+ *nreadp = nread;
+
+ return CURLE_OK;
+}
+
+
+/*
+ * Curl_readrewind() rewinds the read stream. This is typically used for HTTP
+ * POST/PUT with multi-pass authentication when a sending was denied and a
+ * resend is necessary.
+ */
+CURLcode Curl_readrewind(struct connectdata *conn)
+{
+ struct SessionHandle *data = conn->data;
+
+ conn->bits.rewindaftersend = FALSE; /* we rewind now */
+
+ /* explicitly switch off sending data on this connection now since we are
+ about to restart a new transfer and thus we want to avoid inadvertently
+ sending more data on the existing connection until the next transfer
+ starts */
+ data->req.keepon &= ~KEEP_SEND;
+
+ /* We have sent away data. If not using CURLOPT_POSTFIELDS or
+ CURLOPT_HTTPPOST, call app to rewind
+ */
+ if(data->set.postfields ||
+ (data->set.httpreq == HTTPREQ_POST_FORM))
+ ; /* do nothing */
+ else {
+ if(data->set.seek_func) {
+ int err;
+
+ err = (data->set.seek_func)(data->set.seek_client, 0, SEEK_SET);
+ if(err) {
+ failf(data, "seek callback returned error %d", (int)err);
+ return CURLE_SEND_FAIL_REWIND;
+ }
+ }
+ else if(data->set.ioctl_func) {
+ curlioerr err;
+
+ err = (data->set.ioctl_func)(data, CURLIOCMD_RESTARTREAD,
+ data->set.ioctl_client);
+ infof(data, "the ioctl callback returned %d\n", (int)err);
+
+ if(err) {
+ /* FIXME: convert to a human readable error message */
+ failf(data, "ioctl callback returned error %d", (int)err);
+ return CURLE_SEND_FAIL_REWIND;
+ }
+ }
+ else {
+ /* If no CURLOPT_READFUNCTION is used, we know that we operate on a
+ given FILE * stream and we can actually attempt to rewind that
+ ourselves with fseek() */
+ if(data->set.fread_func == (curl_read_callback)fread) {
+ if(-1 != fseek(data->set.in, 0, SEEK_SET))
+ /* successful rewind */
+ return CURLE_OK;
+ }
+
+ /* no callback set or failure above, makes us fail at once */
+ failf(data, "necessary data rewind wasn't possible");
+ return CURLE_SEND_FAIL_REWIND;
+ }
+ }
+ return CURLE_OK;
+}
+
+static int data_pending(const struct connectdata *conn)
+{
+ /* in the case of libssh2, we can never be really sure that we have emptied
+ its internal buffers so we MUST always try until we get EAGAIN back */
+ return conn->handler->protocol&(CURLPROTO_SCP|CURLPROTO_SFTP) ||
+#if defined(USE_NGHTTP2)
+ Curl_ssl_data_pending(conn, FIRSTSOCKET) ||
+ /* For HTTP/2, we may read up everything including responde body
+ with header fields in Curl_http_readwrite_headers. If no
+ content-length is provided, curl waits for the connection
+ close, which we emulate it using conn->proto.httpc.closed =
+ TRUE. The thing is if we read everything, then http2_recv won't
+ be called and we cannot signal the HTTP/2 stream has closed. As
+ a workaround, we return nonzero here to call http2_recv. */
+ ((conn->handler->protocol&PROTO_FAMILY_HTTP) && conn->httpversion == 20);
+#else
+ Curl_ssl_data_pending(conn, FIRSTSOCKET);
+#endif
+}
+
+static void read_rewind(struct connectdata *conn,
+ size_t thismuch)
+{
+ DEBUGASSERT(conn->read_pos >= thismuch);
+
+ conn->read_pos -= thismuch;
+ conn->bits.stream_was_rewound = TRUE;
+
+#ifdef DEBUGBUILD
+ {
+ char buf[512 + 1];
+ size_t show;
+
+ show = CURLMIN(conn->buf_len - conn->read_pos, sizeof(buf)-1);
+ if(conn->master_buffer) {
+ memcpy(buf, conn->master_buffer + conn->read_pos, show);
+ buf[show] = '\0';
+ }
+ else {
+ buf[0] = '\0';
+ }
+
+ DEBUGF(infof(conn->data,
+ "Buffer after stream rewind (read_pos = %zu): [%s]\n",
+ conn->read_pos, buf));
+ }
+#endif
+}
+
+/*
+ * Check to see if CURLOPT_TIMECONDITION was met by comparing the time of the
+ * remote document with the time provided by CURLOPT_TIMEVAL
+ */
+bool Curl_meets_timecondition(struct SessionHandle *data, time_t timeofdoc)
+{
+ if((timeofdoc == 0) || (data->set.timevalue == 0))
+ return TRUE;
+
+ switch(data->set.timecondition) {
+ case CURL_TIMECOND_IFMODSINCE:
+ default:
+ if(timeofdoc <= data->set.timevalue) {
+ infof(data,
+ "The requested document is not new enough\n");
+ data->info.timecond = TRUE;
+ return FALSE;
+ }
+ break;
+ case CURL_TIMECOND_IFUNMODSINCE:
+ if(timeofdoc >= data->set.timevalue) {
+ infof(data,
+ "The requested document is not old enough\n");
+ data->info.timecond = TRUE;
+ return FALSE;
+ }
+ break;
+ }
+
+ return TRUE;
+}
+
+/*
+ * Go ahead and do a read if we have a readable socket or if
+ * the stream was rewound (in which case we have data in a
+ * buffer)
+ */
+static CURLcode readwrite_data(struct SessionHandle *data,
+ struct connectdata *conn,
+ struct SingleRequest *k,
+ int *didwhat, bool *done)
+{
+ CURLcode result = CURLE_OK;
+ ssize_t nread; /* number of bytes read */
+ size_t excess = 0; /* excess bytes read */
+ bool is_empty_data = FALSE;
+ bool readmore = FALSE; /* used by RTP to signal for more data */
+
+ *done = FALSE;
+
+ /* This is where we loop until we have read everything there is to
+ read or we get a CURLE_AGAIN */
+ do {
+ size_t buffersize = data->set.buffer_size?
+ data->set.buffer_size : BUFSIZE;
+ size_t bytestoread = buffersize;
+
+ if(k->size != -1 && !k->header) {
+ /* make sure we don't read "too much" if we can help it since we
+ might be pipelining and then someone else might want to read what
+ follows! */
+ curl_off_t totalleft = k->size - k->bytecount;
+ if(totalleft < (curl_off_t)bytestoread)
+ bytestoread = (size_t)totalleft;
+ }
+
+ if(bytestoread) {
+ /* receive data from the network! */
+ result = Curl_read(conn, conn->sockfd, k->buf, bytestoread, &nread);
+
+ /* read would've blocked */
+ if(CURLE_AGAIN == result)
+ break; /* get out of loop */
+
+ if(result>0)
+ return result;
+ }
+ else {
+ /* read nothing but since we wanted nothing we consider this an OK
+ situation to proceed from */
+ DEBUGF(infof(data, "readwrite_data: we're done!\n"));
+ nread = 0;
+ }
+
+ if((k->bytecount == 0) && (k->writebytecount == 0)) {
+ Curl_pgrsTime(data, TIMER_STARTTRANSFER);
+ if(k->exp100 > EXP100_SEND_DATA)
+ /* set time stamp to compare with when waiting for the 100 */
+ k->start100 = Curl_tvnow();
+ }
+
+ *didwhat |= KEEP_RECV;
+ /* indicates data of zero size, i.e. empty file */
+ is_empty_data = ((nread == 0) && (k->bodywrites == 0)) ? TRUE : FALSE;
+
+ /* NUL terminate, allowing string ops to be used */
+ if(0 < nread || is_empty_data) {
+ k->buf[nread] = 0;
+ }
+ else if(0 >= nread) {
+ /* if we receive 0 or less here, the server closed the connection
+ and we bail out from this! */
+ DEBUGF(infof(data, "nread <= 0, server closed connection, bailing\n"));
+ k->keepon &= ~KEEP_RECV;
+ break;
+ }
+
+ /* Default buffer to use when we write the buffer, it may be changed
+ in the flow below before the actual storing is done. */
+ k->str = k->buf;
+
+ if(conn->handler->readwrite) {
+ result = conn->handler->readwrite(data, conn, &nread, &readmore);
+ if(result)
+ return result;
+ if(readmore)
+ break;
+ }
+
+#ifndef CURL_DISABLE_HTTP
+ /* Since this is a two-state thing, we check if we are parsing
+ headers at the moment or not. */
+ if(k->header) {
+ /* we are in parse-the-header-mode */
+ bool stop_reading = FALSE;
+ result = Curl_http_readwrite_headers(data, conn, &nread, &stop_reading);
+ if(result)
+ return result;
+
+ if(conn->handler->readwrite &&
+ (k->maxdownload <= 0 && nread > 0)) {
+ result = conn->handler->readwrite(data, conn, &nread, &readmore);
+ if(result)
+ return result;
+ if(readmore)
+ break;
+ }
+
+ if(stop_reading) {
+ /* We've stopped dealing with input, get out of the do-while loop */
+
+ if(nread > 0) {
+ if(Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1)) {
+ infof(data,
+ "Rewinding stream by : %zd"
+ " bytes on url %s (zero-length body)\n",
+ nread, data->state.path);
+ read_rewind(conn, (size_t)nread);
+ }
+ else {
+ infof(data,
+ "Excess found in a non pipelined read:"
+ " excess = %zd"
+ " url = %s (zero-length body)\n",
+ nread, data->state.path);
+ }
+ }
+
+ break;
+ }
+ }
+#endif /* CURL_DISABLE_HTTP */
+
+
+ /* This is not an 'else if' since it may be a rest from the header
+ parsing, where the beginning of the buffer is headers and the end
+ is non-headers. */
+ if(k->str && !k->header && (nread > 0 || is_empty_data)) {
+
+#ifndef CURL_DISABLE_HTTP
+ if(0 == k->bodywrites && !is_empty_data) {
+ /* These checks are only made the first time we are about to
+ write a piece of the body */
+ if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) {
+ /* HTTP-only checks */
+
+ if(data->req.newurl) {
+ if(conn->bits.close) {
+ /* Abort after the headers if "follow Location" is set
+ and we're set to close anyway. */
+ k->keepon &= ~KEEP_RECV;
+ *done = TRUE;
+ return CURLE_OK;
+ }
+ /* We have a new url to load, but since we want to be able
+ to re-use this connection properly, we read the full
+ response in "ignore more" */
+ k->ignorebody = TRUE;
+ infof(data, "Ignoring the response-body\n");
+ }
+ if(data->state.resume_from && !k->content_range &&
+ (data->set.httpreq==HTTPREQ_GET) &&
+ !k->ignorebody) {
+
+ if(k->size == data->state.resume_from) {
+ /* The resume point is at the end of file, consider this fine
+ even if it doesn't allow resume from here. */
+ infof(data, "The entire document is already downloaded");
+ connclose(conn, "already downloaded");
+ /* Abort download */
+ k->keepon &= ~KEEP_RECV;
+ *done = TRUE;
+ return CURLE_OK;
+ }
+
+ /* we wanted to resume a download, although the server doesn't
+ * seem to support this and we did this with a GET (if it
+ * wasn't a GET we did a POST or PUT resume) */
+ failf(data, "HTTP server doesn't seem to support "
+ "byte ranges. Cannot resume.");
+ return CURLE_RANGE_ERROR;
+ }
+
+ if(data->set.timecondition && !data->state.range) {
+ /* A time condition has been set AND no ranges have been
+ requested. This seems to be what chapter 13.3.4 of
+ RFC 2616 defines to be the correct action for a
+ HTTP/1.1 client */
+
+ if(!Curl_meets_timecondition(data, k->timeofdoc)) {
+ *done = TRUE;
+ /* We're simulating a http 304 from server so we return
+ what should have been returned from the server */
+ data->info.httpcode = 304;
+ infof(data, "Simulate a HTTP 304 response!\n");
+ /* we abort the transfer before it is completed == we ruin the
+ re-use ability. Close the connection */
+ connclose(conn, "Simulated 304 handling");
+ return CURLE_OK;
+ }
+ } /* we have a time condition */
+
+ } /* this is HTTP or RTSP */
+ } /* this is the first time we write a body part */
+#endif /* CURL_DISABLE_HTTP */
+
+ k->bodywrites++;
+
+ /* pass data to the debug function before it gets "dechunked" */
+ if(data->set.verbose) {
+ if(k->badheader) {
+ Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff,
+ (size_t)k->hbuflen, conn);
+ if(k->badheader == HEADER_PARTHEADER)
+ Curl_debug(data, CURLINFO_DATA_IN,
+ k->str, (size_t)nread, conn);
+ }
+ else
+ Curl_debug(data, CURLINFO_DATA_IN,
+ k->str, (size_t)nread, conn);
+ }
+
+#ifndef CURL_DISABLE_HTTP
+ if(k->chunk) {
+ /*
+ * Here comes a chunked transfer flying and we need to decode this
+ * properly. While the name says read, this function both reads
+ * and writes away the data. The returned 'nread' holds the number
+ * of actual data it wrote to the client.
+ */
+
+ CHUNKcode res =
+ Curl_httpchunk_read(conn, k->str, nread, &nread);
+
+ if(CHUNKE_OK < res) {
+ if(CHUNKE_WRITE_ERROR == res) {
+ failf(data, "Failed writing data");
+ return CURLE_WRITE_ERROR;
+ }
+ failf(data, "%s in chunked-encoding", Curl_chunked_strerror(res));
+ return CURLE_RECV_ERROR;
+ }
+ else if(CHUNKE_STOP == res) {
+ size_t dataleft;
+ /* we're done reading chunks! */
+ k->keepon &= ~KEEP_RECV; /* read no more */
+
+ /* There are now possibly N number of bytes at the end of the
+ str buffer that weren't written to the client.
+
+ We DO care about this data if we are pipelining.
+ Push it back to be read on the next pass. */
+
+ dataleft = conn->chunk.dataleft;
+ if(dataleft != 0) {
+ infof(conn->data, "Leftovers after chunking: %zu bytes\n",
+ dataleft);
+ if(Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1)) {
+ /* only attempt the rewind if we truly are pipelining */
+ infof(conn->data, "Rewinding %zu bytes\n",dataleft);
+ read_rewind(conn, dataleft);
+ }
+ }
+ }
+ /* If it returned OK, we just keep going */
+ }
+#endif /* CURL_DISABLE_HTTP */
+
+ /* Account for body content stored in the header buffer */
+ if(k->badheader && !k->ignorebody) {
+ DEBUGF(infof(data, "Increasing bytecount by %zu from hbuflen\n",
+ k->hbuflen));
+ k->bytecount += k->hbuflen;
+ }
+
+ if((-1 != k->maxdownload) &&
+ (k->bytecount + nread >= k->maxdownload)) {
+
+ excess = (size_t)(k->bytecount + nread - k->maxdownload);
+ if(excess > 0 && !k->ignorebody) {
+ if(Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1)) {
+ /* The 'excess' amount below can't be more than BUFSIZE which
+ always will fit in a size_t */
+ infof(data,
+ "Rewinding stream by : %zu"
+ " bytes on url %s (size = %" CURL_FORMAT_CURL_OFF_T
+ ", maxdownload = %" CURL_FORMAT_CURL_OFF_T
+ ", bytecount = %" CURL_FORMAT_CURL_OFF_T ", nread = %zd)\n",
+ excess, data->state.path,
+ k->size, k->maxdownload, k->bytecount, nread);
+ read_rewind(conn, excess);
+ }
+ else {
+ infof(data,
+ "Excess found in a non pipelined read:"
+ " excess = %zu"
+ ", size = %" CURL_FORMAT_CURL_OFF_T
+ ", maxdownload = %" CURL_FORMAT_CURL_OFF_T
+ ", bytecount = %" CURL_FORMAT_CURL_OFF_T "\n",
+ excess, k->size, k->maxdownload, k->bytecount);
+ }
+ }
+
+ nread = (ssize_t) (k->maxdownload - k->bytecount);
+ if(nread < 0 ) /* this should be unusual */
+ nread = 0;
+
+ k->keepon &= ~KEEP_RECV; /* we're done reading */
+ }
+
+ k->bytecount += nread;
+
+ Curl_pgrsSetDownloadCounter(data, k->bytecount);
+
+ if(!k->chunk && (nread || k->badheader || is_empty_data)) {
+ /* If this is chunky transfer, it was already written */
+
+ if(k->badheader && !k->ignorebody) {
+ /* we parsed a piece of data wrongly assuming it was a header
+ and now we output it as body instead */
+
+ /* Don't let excess data pollute body writes */
+ if(k->maxdownload == -1 || (curl_off_t)k->hbuflen <= k->maxdownload)
+ result = Curl_client_write(conn, CLIENTWRITE_BODY,
+ data->state.headerbuff,
+ k->hbuflen);
+ else
+ result = Curl_client_write(conn, CLIENTWRITE_BODY,
+ data->state.headerbuff,
+ (size_t)k->maxdownload);
+
+ if(result)
+ return result;
+ }
+ if(k->badheader < HEADER_ALLBAD) {
+ /* This switch handles various content encodings. If there's an
+ error here, be sure to check over the almost identical code
+ in http_chunks.c.
+ Make sure that ALL_CONTENT_ENCODINGS contains all the
+ encodings handled here. */
+#ifdef HAVE_LIBZ
+ switch (conn->data->set.http_ce_skip ?
+ IDENTITY : k->auto_decoding) {
+ case IDENTITY:
+#endif
+ /* This is the default when the server sends no
+ Content-Encoding header. See Curl_readwrite_init; the
+ memset() call initializes k->auto_decoding to zero. */
+ if(!k->ignorebody) {
+
+#ifndef CURL_DISABLE_POP3
+ if(conn->handler->protocol&PROTO_FAMILY_POP3)
+ result = Curl_pop3_write(conn, k->str, nread);
+ else
+#endif /* CURL_DISABLE_POP3 */
+
+ result = Curl_client_write(conn, CLIENTWRITE_BODY, k->str,
+ nread);
+ }
+#ifdef HAVE_LIBZ
+ break;
+
+ case DEFLATE:
+ /* Assume CLIENTWRITE_BODY; headers are not encoded. */
+ if(!k->ignorebody)
+ result = Curl_unencode_deflate_write(conn, k, nread);
+ break;
+
+ case GZIP:
+ /* Assume CLIENTWRITE_BODY; headers are not encoded. */
+ if(!k->ignorebody)
+ result = Curl_unencode_gzip_write(conn, k, nread);
+ break;
+
+ default:
+ failf (data, "Unrecognized content encoding type. "
+ "libcurl understands `identity', `deflate' and `gzip' "
+ "content encodings.");
+ result = CURLE_BAD_CONTENT_ENCODING;
+ break;
+ }
+#endif
+ }
+ k->badheader = HEADER_NORMAL; /* taken care of now */
+
+ if(result)
+ return result;
+ }
+
+ } /* if(! header and data to read ) */
+
+ if(conn->handler->readwrite &&
+ (excess > 0 && !conn->bits.stream_was_rewound)) {
+ /* Parse the excess data */
+ k->str += nread;
+ nread = (ssize_t)excess;
+
+ result = conn->handler->readwrite(data, conn, &nread, &readmore);
+ if(result)
+ return result;
+
+ if(readmore)
+ k->keepon |= KEEP_RECV; /* we're not done reading */
+ break;
+ }
+
+ if(is_empty_data) {
+ /* if we received nothing, the server closed the connection and we
+ are done */
+ k->keepon &= ~KEEP_RECV;
+ }
+
+ } while(data_pending(conn));
+
+ if(((k->keepon & (KEEP_RECV|KEEP_SEND)) == KEEP_SEND) &&
+ conn->bits.close ) {
+ /* When we've read the entire thing and the close bit is set, the server
+ may now close the connection. If there's now any kind of sending going
+ on from our side, we need to stop that immediately. */
+ infof(data, "we are done reading and this is set to close, stop send\n");
+ k->keepon &= ~KEEP_SEND; /* no writing anymore either */
+ }
+
+ return CURLE_OK;
+}
+
+/*
+ * Send data to upload to the server, when the socket is writable.
+ */
+static CURLcode readwrite_upload(struct SessionHandle *data,
+ struct connectdata *conn,
+ struct SingleRequest *k,
+ int *didwhat)
+{
+ ssize_t i, si;
+ ssize_t bytes_written;
+ CURLcode result;
+ ssize_t nread; /* number of bytes read */
+ bool sending_http_headers = FALSE;
+
+ if((k->bytecount == 0) && (k->writebytecount == 0))
+ Curl_pgrsTime(data, TIMER_STARTTRANSFER);
+
+ *didwhat |= KEEP_SEND;
+
+ do {
+
+ /* only read more data if there's no upload data already
+ present in the upload buffer */
+ if(0 == data->req.upload_present) {
+ /* init the "upload from here" pointer */
+ data->req.upload_fromhere = k->uploadbuf;
+
+ if(!k->upload_done) {
+ /* HTTP pollution, this should be written nicer to become more
+ protocol agnostic. */
+ int fillcount;
+ struct HTTP *http = data->req.protop;
+
+ if((k->exp100 == EXP100_SENDING_REQUEST) &&
+ (http->sending == HTTPSEND_BODY)) {
+ /* If this call is to send body data, we must take some action:
+ We have sent off the full HTTP 1.1 request, and we shall now
+ go into the Expect: 100 state and await such a header */
+ k->exp100 = EXP100_AWAITING_CONTINUE; /* wait for the header */
+ k->keepon &= ~KEEP_SEND; /* disable writing */
+ k->start100 = Curl_tvnow(); /* timeout count starts now */
+ *didwhat &= ~KEEP_SEND; /* we didn't write anything actually */
+
+ /* set a timeout for the multi interface */
+ Curl_expire(data, data->set.expect_100_timeout);
+ break;
+ }
+
+ if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) {
+ if(http->sending == HTTPSEND_REQUEST)
+ /* We're sending the HTTP request headers, not the data.
+ Remember that so we don't change the line endings. */
+ sending_http_headers = TRUE;
+ else
+ sending_http_headers = FALSE;
+ }
+
+ result = Curl_fillreadbuffer(conn, BUFSIZE, &fillcount);
+ if(result)
+ return result;
+
+ nread = (ssize_t)fillcount;
+ }
+ else
+ nread = 0; /* we're done uploading/reading */
+
+ if(!nread && (k->keepon & KEEP_SEND_PAUSE)) {
+ /* this is a paused transfer */
+ break;
+ }
+ else if(nread<=0) {
+ /* done */
+ k->keepon &= ~KEEP_SEND; /* we're done writing */
+
+ if(conn->bits.rewindaftersend) {
+ result = Curl_readrewind(conn);
+ if(result)
+ return result;
+ }
+ break;
+ }
+
+ /* store number of bytes available for upload */
+ data->req.upload_present = nread;
+
+ /* convert LF to CRLF if so asked */
+ if((!sending_http_headers) && (
+#ifdef CURL_DO_LINEEND_CONV
+ /* always convert if we're FTPing in ASCII mode */
+ (data->set.prefer_ascii) ||
+#endif
+ (data->set.crlf))) {
+ /* Do we need to allocate a scratch buffer? */
+ if(!data->state.scratch) {
+ data->state.scratch = malloc(2 * BUFSIZE);
+ if(!data->state.scratch) {
+ failf(data, "Failed to alloc scratch buffer!");
+
+ return CURLE_OUT_OF_MEMORY;
+ }
+ }
+
+ /*
+ * ASCII/EBCDIC Note: This is presumably a text (not binary)
+ * transfer so the data should already be in ASCII.
+ * That means the hex values for ASCII CR (0x0d) & LF (0x0a)
+ * must be used instead of the escape sequences \r & \n.
+ */
+ for(i = 0, si = 0; i < nread; i++, si++) {
+ if(data->req.upload_fromhere[i] == 0x0a) {
+ data->state.scratch[si++] = 0x0d;
+ data->state.scratch[si] = 0x0a;
+ if(!data->set.crlf) {
+ /* we're here only because FTP is in ASCII mode...
+ bump infilesize for the LF we just added */
+ data->state.infilesize++;
+ }
+ }
+ else
+ data->state.scratch[si] = data->req.upload_fromhere[i];
+ }
+
+ if(si != nread) {
+ /* only perform the special operation if we really did replace
+ anything */
+ nread = si;
+
+ /* upload from the new (replaced) buffer instead */
+ data->req.upload_fromhere = data->state.scratch;
+
+ /* set the new amount too */
+ data->req.upload_present = nread;
+ }
+ }
+
+#ifndef CURL_DISABLE_SMTP
+ if(conn->handler->protocol & PROTO_FAMILY_SMTP) {
+ result = Curl_smtp_escape_eob(conn, nread);
+ if(result)
+ return result;
+ }
+#endif /* CURL_DISABLE_SMTP */
+ } /* if 0 == data->req.upload_present */
+ else {
+ /* We have a partial buffer left from a previous "round". Use
+ that instead of reading more data */
+ }
+
+ /* write to socket (send away data) */
+ result = Curl_write(conn,
+ conn->writesockfd, /* socket to send to */
+ data->req.upload_fromhere, /* buffer pointer */
+ data->req.upload_present, /* buffer size */
+ &bytes_written); /* actually sent */
+
+ if(result)
+ return result;
+
+ if(data->set.verbose)
+ /* show the data before we change the pointer upload_fromhere */
+ Curl_debug(data, CURLINFO_DATA_OUT, data->req.upload_fromhere,
+ (size_t)bytes_written, conn);
+
+ k->writebytecount += bytes_written;
+
+ if(k->writebytecount == data->state.infilesize) {
+ /* we have sent all data we were supposed to */
+ k->upload_done = TRUE;
+ infof(data, "We are completely uploaded and fine\n");
+ }
+
+ if(data->req.upload_present != bytes_written) {
+ /* we only wrote a part of the buffer (if anything), deal with it! */
+
+ /* store the amount of bytes left in the buffer to write */
+ data->req.upload_present -= bytes_written;
+
+ /* advance the pointer where to find the buffer when the next send
+ is to happen */
+ data->req.upload_fromhere += bytes_written;
+ }
+ else {
+ /* we've uploaded that buffer now */
+ data->req.upload_fromhere = k->uploadbuf;
+ data->req.upload_present = 0; /* no more bytes left */
+
+ if(k->upload_done) {
+ /* switch off writing, we're done! */
+ k->keepon &= ~KEEP_SEND; /* we're done writing */
+ }
+ }
+
+ Curl_pgrsSetUploadCounter(data, k->writebytecount);
+
+ } WHILE_FALSE; /* just to break out from! */
+
+ return CURLE_OK;
+}
+
+/*
+ * Curl_readwrite() is the low-level function to be called when data is to
+ * be read and written to/from the connection.
+ */
+CURLcode Curl_readwrite(struct connectdata *conn,
+ struct SessionHandle *data,
+ bool *done)
+{
+ struct SingleRequest *k = &data->req;
+ CURLcode result;
+ int didwhat=0;
+
+ curl_socket_t fd_read;
+ curl_socket_t fd_write;
+ int select_res = conn->cselect_bits;
+
+ conn->cselect_bits = 0;
+
+ /* only use the proper socket if the *_HOLD bit is not set simultaneously as
+ then we are in rate limiting state in that transfer direction */
+
+ if((k->keepon & KEEP_RECVBITS) == KEEP_RECV)
+ fd_read = conn->sockfd;
+ else
+ fd_read = CURL_SOCKET_BAD;
+
+ if((k->keepon & KEEP_SENDBITS) == KEEP_SEND)
+ fd_write = conn->writesockfd;
+ else
+ fd_write = CURL_SOCKET_BAD;
+
+ if(conn->data->state.drain) {
+ select_res |= CURL_CSELECT_IN;
+ DEBUGF(infof(data, "Curl_readwrite: forcibly told to drain data\n"));
+ }
+
+ if(!select_res) /* Call for select()/poll() only, if read/write/error
+ status is not known. */
+ select_res = Curl_socket_ready(fd_read, fd_write, 0);
+
+ if(select_res == CURL_CSELECT_ERR) {
+ failf(data, "select/poll returned error");
+ return CURLE_SEND_ERROR;
+ }
+
+ /* We go ahead and do a read if we have a readable socket or if
+ the stream was rewound (in which case we have data in a
+ buffer) */
+ if((k->keepon & KEEP_RECV) &&
+ ((select_res & CURL_CSELECT_IN) || conn->bits.stream_was_rewound)) {
+
+ result = readwrite_data(data, conn, k, &didwhat, done);
+ if(result || *done)
+ return result;
+ }
+
+ /* If we still have writing to do, we check if we have a writable socket. */
+ if((k->keepon & KEEP_SEND) && (select_res & CURL_CSELECT_OUT)) {
+ /* write */
+
+ result = readwrite_upload(data, conn, k, &didwhat);
+ if(result)
+ return result;
+ }
+
+ k->now = Curl_tvnow();
+ if(didwhat) {
+ /* Update read/write counters */
+ if(k->bytecountp)
+ *k->bytecountp = k->bytecount; /* read count */
+ if(k->writebytecountp)
+ *k->writebytecountp = k->writebytecount; /* write count */
+ }
+ else {
+ /* no read no write, this is a timeout? */
+ if(k->exp100 == EXP100_AWAITING_CONTINUE) {
+ /* This should allow some time for the header to arrive, but only a
+ very short time as otherwise it'll be too much wasted time too
+ often. */
+
+ /* Quoting RFC2616, section "8.2.3 Use of the 100 (Continue) Status":
+
+ Therefore, when a client sends this header field to an origin server
+ (possibly via a proxy) from which it has never seen a 100 (Continue)
+ status, the client SHOULD NOT wait for an indefinite period before
+ sending the request body.
+
+ */
+
+ long ms = Curl_tvdiff(k->now, k->start100);
+ if(ms >= data->set.expect_100_timeout) {
+ /* we've waited long enough, continue anyway */
+ k->exp100 = EXP100_SEND_DATA;
+ k->keepon |= KEEP_SEND;
+ infof(data, "Done waiting for 100-continue\n");
+ }
+ }
+ }
+
+ if(Curl_pgrsUpdate(conn))
+ result = CURLE_ABORTED_BY_CALLBACK;
+ else
+ result = Curl_speedcheck(data, k->now);
+ if(result)
+ return result;
+
+ if(k->keepon) {
+ if(0 > Curl_timeleft(data, &k->now, FALSE)) {
+ if(k->size != -1) {
+ failf(data, "Operation timed out after %ld milliseconds with %"
+ CURL_FORMAT_CURL_OFF_T " out of %"
+ CURL_FORMAT_CURL_OFF_T " bytes received",
+ Curl_tvdiff(k->now, data->progress.t_startsingle), k->bytecount,
+ k->size);
+ }
+ else {
+ failf(data, "Operation timed out after %ld milliseconds with %"
+ CURL_FORMAT_CURL_OFF_T " bytes received",
+ Curl_tvdiff(k->now, data->progress.t_startsingle), k->bytecount);
+ }
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+ }
+ else {
+ /*
+ * The transfer has been performed. Just make some general checks before
+ * returning.
+ */
+
+ if(!(data->set.opt_no_body) && (k->size != -1) &&
+ (k->bytecount != k->size) &&
+#ifdef CURL_DO_LINEEND_CONV
+ /* Most FTP servers don't adjust their file SIZE response for CRLFs,
+ so we'll check to see if the discrepancy can be explained
+ by the number of CRLFs we've changed to LFs.
+ */
+ (k->bytecount != (k->size + data->state.crlf_conversions)) &&
+#endif /* CURL_DO_LINEEND_CONV */
+ !data->req.newurl) {
+ failf(data, "transfer closed with %" CURL_FORMAT_CURL_OFF_T
+ " bytes remaining to read",
+ k->size - k->bytecount);
+ return CURLE_PARTIAL_FILE;
+ }
+ else if(!(data->set.opt_no_body) &&
+ k->chunk &&
+ (conn->chunk.state != CHUNK_STOP)) {
+ /*
+ * In chunked mode, return an error if the connection is closed prior to
+ * the empty (terminating) chunk is read.
+ *
+ * The condition above used to check for
+ * conn->proto.http->chunk.datasize != 0 which is true after reading
+ * *any* chunk, not just the empty chunk.
+ *
+ */
+ failf(data, "transfer closed with outstanding read data remaining");
+ return CURLE_PARTIAL_FILE;
+ }
+ if(Curl_pgrsUpdate(conn))
+ return CURLE_ABORTED_BY_CALLBACK;
+ }
+
+ /* Now update the "done" boolean we return */
+ *done = (0 == (k->keepon&(KEEP_RECV|KEEP_SEND|
+ KEEP_RECV_PAUSE|KEEP_SEND_PAUSE))) ? TRUE : FALSE;
+
+ return CURLE_OK;
+}
+
+/*
+ * Curl_single_getsock() gets called by the multi interface code when the app
+ * has requested to get the sockets for the current connection. This function
+ * will then be called once for every connection that the multi interface
+ * keeps track of. This function will only be called for connections that are
+ * in the proper state to have this information available.
+ */
+int Curl_single_getsock(const struct connectdata *conn,
+ curl_socket_t *sock, /* points to numsocks number
+ of sockets */
+ int numsocks)
+{
+ const struct SessionHandle *data = conn->data;
+ int bitmap = GETSOCK_BLANK;
+ unsigned sockindex = 0;
+
+ if(conn->handler->perform_getsock)
+ return conn->handler->perform_getsock(conn, sock, numsocks);
+
+ if(numsocks < 2)
+ /* simple check but we might need two slots */
+ return GETSOCK_BLANK;
+
+ /* don't include HOLD and PAUSE connections */
+ if((data->req.keepon & KEEP_RECVBITS) == KEEP_RECV) {
+
+ DEBUGASSERT(conn->sockfd != CURL_SOCKET_BAD);
+
+ bitmap |= GETSOCK_READSOCK(sockindex);
+ sock[sockindex] = conn->sockfd;
+ }
+
+ /* don't include HOLD and PAUSE connections */
+ if((data->req.keepon & KEEP_SENDBITS) == KEEP_SEND) {
+
+ if((conn->sockfd != conn->writesockfd) ||
+ bitmap == GETSOCK_BLANK) {
+ /* only if they are not the same socket and we have a readable
+ one, we increase index */
+ if(bitmap != GETSOCK_BLANK)
+ sockindex++; /* increase index if we need two entries */
+
+ DEBUGASSERT(conn->writesockfd != CURL_SOCKET_BAD);
+
+ sock[sockindex] = conn->writesockfd;
+ }
+
+ bitmap |= GETSOCK_WRITESOCK(sockindex);
+ }
+
+ return bitmap;
+}
+
+/*
+ * Determine optimum sleep time based on configured rate, current rate,
+ * and packet size.
+ * Returns value in milliseconds.
+ *
+ * The basic idea is to adjust the desired rate up/down in this method
+ * based on whether we are running too slow or too fast. Then, calculate
+ * how many milliseconds to wait for the next packet to achieve this new
+ * rate.
+ */
+long Curl_sleep_time(curl_off_t rate_bps, curl_off_t cur_rate_bps,
+ int pkt_size)
+{
+ curl_off_t min_sleep = 0;
+ curl_off_t rv = 0;
+
+ if(rate_bps == 0)
+ return 0;
+
+ /* If running faster than about .1% of the desired speed, slow
+ * us down a bit. Use shift instead of division as the 0.1%
+ * cutoff is arbitrary anyway.
+ */
+ if(cur_rate_bps > (rate_bps + (rate_bps >> 10))) {
+ /* running too fast, decrease target rate by 1/64th of rate */
+ rate_bps -= rate_bps >> 6;
+ min_sleep = 1;
+ }
+ else if(cur_rate_bps < (rate_bps - (rate_bps >> 10))) {
+ /* running too slow, increase target rate by 1/64th of rate */
+ rate_bps += rate_bps >> 6;
+ }
+
+ /* Determine number of milliseconds to wait until we do
+ * the next packet at the adjusted rate. We should wait
+ * longer when using larger packets, for instance.
+ */
+ rv = ((curl_off_t)(pkt_size * 1000) / rate_bps);
+
+ /* Catch rounding errors and always slow down at least 1ms if
+ * we are running too fast.
+ */
+ if(rv < min_sleep)
+ rv = min_sleep;
+
+ /* Bound value to fit in 'long' on 32-bit platform. That's
+ * plenty long enough anyway!
+ */
+ if(rv > 0x7fffffff)
+ rv = 0x7fffffff;
+
+ return (long)rv;
+}
+
+/*
+ * Curl_pretransfer() is called immediately before a transfer starts.
+ */
+CURLcode Curl_pretransfer(struct SessionHandle *data)
+{
+ CURLcode result;
+ if(!data->change.url) {
+ /* we can't do anything without URL */
+ failf(data, "No URL set!");
+ return CURLE_URL_MALFORMAT;
+ }
+
+ /* Init the SSL session ID cache here. We do it here since we want to do it
+ after the *_setopt() calls (that could specify the size of the cache) but
+ before any transfer takes place. */
+ result = Curl_ssl_initsessions(data, data->set.ssl.max_ssl_sessions);
+ if(result)
+ return result;
+
+ data->set.followlocation=0; /* reset the location-follow counter */
+ data->state.this_is_a_follow = FALSE; /* reset this */
+ data->state.errorbuf = FALSE; /* no error has occurred */
+ data->state.httpversion = 0; /* don't assume any particular server version */
+
+ data->state.authproblem = FALSE;
+ data->state.authhost.want = data->set.httpauth;
+ data->state.authproxy.want = data->set.proxyauth;
+ Curl_safefree(data->info.wouldredirect);
+ data->info.wouldredirect = NULL;
+
+ if(data->set.httpreq == HTTPREQ_PUT)
+ data->state.infilesize = data->set.filesize;
+ else
+ data->state.infilesize = data->set.postfieldsize;
+
+ /* If there is a list of cookie files to read, do it now! */
+ if(data->change.cookielist)
+ Curl_cookie_loadfiles(data);
+
+ /* If there is a list of host pairs to deal with */
+ if(data->change.resolve)
+ result = Curl_loadhostpairs(data);
+
+ if(!result) {
+ /* Allow data->set.use_port to set which port to use. This needs to be
+ * disabled for example when we follow Location: headers to URLs using
+ * different ports! */
+ data->state.allow_port = TRUE;
+
+#if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL)
+ /*************************************************************
+ * Tell signal handler to ignore SIGPIPE
+ *************************************************************/
+ if(!data->set.no_signal)
+ data->state.prev_signal = signal(SIGPIPE, SIG_IGN);
+#endif
+
+ Curl_initinfo(data); /* reset session-specific information "variables" */
+ Curl_pgrsResetTimesSizes(data);
+ Curl_pgrsStartNow(data);
+
+ if(data->set.timeout)
+ Curl_expire(data, data->set.timeout);
+
+ if(data->set.connecttimeout)
+ Curl_expire(data, data->set.connecttimeout);
+
+ /* In case the handle is re-used and an authentication method was picked
+ in the session we need to make sure we only use the one(s) we now
+ consider to be fine */
+ data->state.authhost.picked &= data->state.authhost.want;
+ data->state.authproxy.picked &= data->state.authproxy.want;
+ }
+
+ return result;
+}
+
+/*
+ * Curl_posttransfer() is called immediately after a transfer ends
+ */
+CURLcode Curl_posttransfer(struct SessionHandle *data)
+{
+#if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL)
+ /* restore the signal handler for SIGPIPE before we get back */
+ if(!data->set.no_signal)
+ signal(SIGPIPE, data->state.prev_signal);
+#else
+ (void)data; /* unused parameter */
+#endif
+
+ return CURLE_OK;
+}
+
+#ifndef CURL_DISABLE_HTTP
+/*
+ * strlen_url() returns the length of the given URL if the spaces within the
+ * URL were properly URL encoded.
+ */
+static size_t strlen_url(const char *url)
+{
+ const char *ptr;
+ size_t newlen=0;
+ bool left=TRUE; /* left side of the ? */
+
+ for(ptr=url; *ptr; ptr++) {
+ switch(*ptr) {
+ case '?':
+ left=FALSE;
+ /* fall through */
+ default:
+ newlen++;
+ break;
+ case ' ':
+ if(left)
+ newlen+=3;
+ else
+ newlen++;
+ break;
+ }
+ }
+ return newlen;
+}
+
+/* strcpy_url() copies a url to a output buffer and URL-encodes the spaces in
+ * the source URL accordingly.
+ */
+static void strcpy_url(char *output, const char *url)
+{
+ /* we must add this with whitespace-replacing */
+ bool left=TRUE;
+ const char *iptr;
+ char *optr = output;
+ for(iptr = url; /* read from here */
+ *iptr; /* until zero byte */
+ iptr++) {
+ switch(*iptr) {
+ case '?':
+ left=FALSE;
+ /* fall through */
+ default:
+ *optr++=*iptr;
+ break;
+ case ' ':
+ if(left) {
+ *optr++='%'; /* add a '%' */
+ *optr++='2'; /* add a '2' */
+ *optr++='0'; /* add a '0' */
+ }
+ else
+ *optr++='+'; /* add a '+' here */
+ break;
+ }
+ }
+ *optr=0; /* zero terminate output buffer */
+
+}
+
+/*
+ * Returns true if the given URL is absolute (as opposed to relative)
+ */
+static bool is_absolute_url(const char *url)
+{
+ char prot[16]; /* URL protocol string storage */
+ char letter; /* used for a silly sscanf */
+
+ return (2 == sscanf(url, "%15[^?&/:]://%c", prot, &letter)) ? TRUE : FALSE;
+}
+
+/*
+ * Concatenate a relative URL to a base URL making it absolute.
+ * URL-encodes any spaces.
+ * The returned pointer must be freed by the caller unless NULL
+ * (returns NULL on out of memory).
+ */
+static char *concat_url(const char *base, const char *relurl)
+{
+ /***
+ TRY to append this new path to the old URL
+ to the right of the host part. Oh crap, this is doomed to cause
+ problems in the future...
+ */
+ char *newest;
+ char *protsep;
+ char *pathsep;
+ size_t newlen;
+
+ const char *useurl = relurl;
+ size_t urllen;
+
+ /* we must make our own copy of the URL to play with, as it may
+ point to read-only data */
+ char *url_clone=strdup(base);
+
+ if(!url_clone)
+ return NULL; /* skip out of this NOW */
+
+ /* protsep points to the start of the host name */
+ protsep=strstr(url_clone, "//");
+ if(!protsep)
+ protsep=url_clone;
+ else
+ protsep+=2; /* pass the slashes */
+
+ if('/' != relurl[0]) {
+ int level=0;
+
+ /* First we need to find out if there's a ?-letter in the URL,
+ and cut it and the right-side of that off */
+ pathsep = strchr(protsep, '?');
+ if(pathsep)
+ *pathsep=0;
+
+ /* we have a relative path to append to the last slash if there's one
+ available, or if the new URL is just a query string (starts with a
+ '?') we append the new one at the end of the entire currently worked
+ out URL */
+ if(useurl[0] != '?') {
+ pathsep = strrchr(protsep, '/');
+ if(pathsep)
+ *pathsep=0;
+ }
+
+ /* Check if there's any slash after the host name, and if so, remember
+ that position instead */
+ pathsep = strchr(protsep, '/');
+ if(pathsep)
+ protsep = pathsep+1;
+ else
+ protsep = NULL;
+
+ /* now deal with one "./" or any amount of "../" in the newurl
+ and act accordingly */
+
+ if((useurl[0] == '.') && (useurl[1] == '/'))
+ useurl+=2; /* just skip the "./" */
+
+ while((useurl[0] == '.') &&
+ (useurl[1] == '.') &&
+ (useurl[2] == '/')) {
+ level++;
+ useurl+=3; /* pass the "../" */
+ }
+
+ if(protsep) {
+ while(level--) {
+ /* cut off one more level from the right of the original URL */
+ pathsep = strrchr(protsep, '/');
+ if(pathsep)
+ *pathsep=0;
+ else {
+ *protsep=0;
+ break;
+ }
+ }
+ }
+ }
+ else {
+ /* We got a new absolute path for this server */
+
+ if((relurl[0] == '/') && (relurl[1] == '/')) {
+ /* the new URL starts with //, just keep the protocol part from the
+ original one */
+ *protsep=0;
+ useurl = &relurl[2]; /* we keep the slashes from the original, so we
+ skip the new ones */
+ }
+ else {
+ /* cut off the original URL from the first slash, or deal with URLs
+ without slash */
+ pathsep = strchr(protsep, '/');
+ if(pathsep) {
+ /* When people use badly formatted URLs, such as
+ "http://www.url.com?dir=/home/daniel" we must not use the first
+ slash, if there's a ?-letter before it! */
+ char *sep = strchr(protsep, '?');
+ if(sep && (sep < pathsep))
+ pathsep = sep;
+ *pathsep=0;
+ }
+ else {
+ /* There was no slash. Now, since we might be operating on a badly
+ formatted URL, such as "http://www.url.com?id=2380" which doesn't
+ use a slash separator as it is supposed to, we need to check for a
+ ?-letter as well! */
+ pathsep = strchr(protsep, '?');
+ if(pathsep)
+ *pathsep=0;
+ }
+ }
+ }
+
+ /* If the new part contains a space, this is a mighty stupid redirect
+ but we still make an effort to do "right". To the left of a '?'
+ letter we replace each space with %20 while it is replaced with '+'
+ on the right side of the '?' letter.
+ */
+ newlen = strlen_url(useurl);
+
+ urllen = strlen(url_clone);
+
+ newest = malloc(urllen + 1 + /* possible slash */
+ newlen + 1 /* zero byte */);
+
+ if(!newest) {
+ free(url_clone); /* don't leak this */
+ return NULL;
+ }
+
+ /* copy over the root url part */
+ memcpy(newest, url_clone, urllen);
+
+ /* check if we need to append a slash */
+ if(('/' == useurl[0]) || (protsep && !*protsep) || ('?' == useurl[0]))
+ ;
+ else
+ newest[urllen++]='/';
+
+ /* then append the new piece on the right side */
+ strcpy_url(&newest[urllen], useurl);
+
+ free(url_clone);
+
+ return newest;
+}
+#endif /* CURL_DISABLE_HTTP */
+
+/*
+ * Curl_follow() handles the URL redirect magic. Pass in the 'newurl' string
+ * as given by the remote server and set up the new URL to request.
+ */
+CURLcode Curl_follow(struct SessionHandle *data,
+ char *newurl, /* this 'newurl' is the Location: string,
+ and it must be malloc()ed before passed
+ here */
+ followtype type) /* see transfer.h */
+{
+#ifdef CURL_DISABLE_HTTP
+ (void)data;
+ (void)newurl;
+ (void)type;
+ /* Location: following will not happen when HTTP is disabled */
+ return CURLE_TOO_MANY_REDIRECTS;
+#else
+
+ /* Location: redirect */
+ bool disallowport = FALSE;
+
+ if(type == FOLLOW_REDIR) {
+ if((data->set.maxredirs != -1) &&
+ (data->set.followlocation >= data->set.maxredirs)) {
+ failf(data, "Maximum (%ld) redirects followed", data->set.maxredirs);
+ return CURLE_TOO_MANY_REDIRECTS;
+ }
+
+ /* mark the next request as a followed location: */
+ data->state.this_is_a_follow = TRUE;
+
+ data->set.followlocation++; /* count location-followers */
+
+ if(data->set.http_auto_referer) {
+ /* We are asked to automatically set the previous URL as the referer
+ when we get the next URL. We pick the ->url field, which may or may
+ not be 100% correct */
+
+ if(data->change.referer_alloc) {
+ Curl_safefree(data->change.referer);
+ data->change.referer_alloc = FALSE;
+ }
+
+ data->change.referer = strdup(data->change.url);
+ if(!data->change.referer)
+ return CURLE_OUT_OF_MEMORY;
+ data->change.referer_alloc = TRUE; /* yes, free this later */
+ }
+ }
+
+ if(!is_absolute_url(newurl)) {
+ /***
+ *DANG* this is an RFC 2068 violation. The URL is supposed
+ to be absolute and this doesn't seem to be that!
+ */
+ char *absolute = concat_url(data->change.url, newurl);
+ if(!absolute)
+ return CURLE_OUT_OF_MEMORY;
+ free(newurl);
+ newurl = absolute;
+ }
+ else {
+ /* This is an absolute URL, don't allow the custom port number */
+ disallowport = TRUE;
+
+ if(strchr(newurl, ' ')) {
+ /* This new URL contains at least one space, this is a mighty stupid
+ redirect but we still make an effort to do "right". */
+ char *newest;
+ size_t newlen = strlen_url(newurl);
+
+ newest = malloc(newlen+1); /* get memory for this */
+ if(!newest)
+ return CURLE_OUT_OF_MEMORY;
+ strcpy_url(newest, newurl); /* create a space-free URL */
+
+ free(newurl); /* that was no good */
+ newurl = newest; /* use this instead now */
+ }
+
+ }
+
+ if(type == FOLLOW_FAKE) {
+ /* we're only figuring out the new url if we would've followed locations
+ but now we're done so we can get out! */
+ data->info.wouldredirect = newurl;
+ return CURLE_OK;
+ }
+
+ if(disallowport)
+ data->state.allow_port = FALSE;
+
+ if(data->change.url_alloc) {
+ Curl_safefree(data->change.url);
+ data->change.url_alloc = FALSE;
+ }
+
+ data->change.url = newurl;
+ data->change.url_alloc = TRUE;
+ newurl = NULL; /* don't free! */
+
+ infof(data, "Issue another request to this URL: '%s'\n", data->change.url);
+
+ /*
+ * We get here when the HTTP code is 300-399 (and 401). We need to perform
+ * differently based on exactly what return code there was.
+ *
+ * News from 7.10.6: we can also get here on a 401 or 407, in case we act on
+ * a HTTP (proxy-) authentication scheme other than Basic.
+ */
+ switch(data->info.httpcode) {
+ /* 401 - Act on a WWW-Authenticate, we keep on moving and do the
+ Authorization: XXXX header in the HTTP request code snippet */
+ /* 407 - Act on a Proxy-Authenticate, we keep on moving and do the
+ Proxy-Authorization: XXXX header in the HTTP request code snippet */
+ /* 300 - Multiple Choices */
+ /* 306 - Not used */
+ /* 307 - Temporary Redirect */
+ default: /* for all above (and the unknown ones) */
+ /* Some codes are explicitly mentioned since I've checked RFC2616 and they
+ * seem to be OK to POST to.
+ */
+ break;
+ case 301: /* Moved Permanently */
+ /* (quote from RFC7231, section 6.4.2)
+ *
+ * Note: For historical reasons, a user agent MAY change the request
+ * method from POST to GET for the subsequent request. If this
+ * behavior is undesired, the 307 (Temporary Redirect) status code
+ * can be used instead.
+ *
+ * ----
+ *
+ * Many webservers expect this, so these servers often answers to a POST
+ * request with an error page. To be sure that libcurl gets the page that
+ * most user agents would get, libcurl has to force GET.
+ *
+ * This behaviour is forbidden by RFC1945 and the obsolete RFC2616, and
+ * can be overridden with CURLOPT_POSTREDIR.
+ */
+ if((data->set.httpreq == HTTPREQ_POST
+ || data->set.httpreq == HTTPREQ_POST_FORM)
+ && !(data->set.keep_post & CURL_REDIR_POST_301)) {
+ infof(data, "Switch from POST to GET\n");
+ data->set.httpreq = HTTPREQ_GET;
+ }
+ break;
+ case 302: /* Found */
+ /* (quote from RFC7231, section 6.4.3)
+ *
+ * Note: For historical reasons, a user agent MAY change the request
+ * method from POST to GET for the subsequent request. If this
+ * behavior is undesired, the 307 (Temporary Redirect) status code
+ * can be used instead.
+ *
+ * ----
+ *
+ * Many webservers expect this, so these servers often answers to a POST
+ * request with an error page. To be sure that libcurl gets the page that
+ * most user agents would get, libcurl has to force GET.
+ *
+ * This behaviour is forbidden by RFC1945 and the obsolete RFC2616, and
+ * can be overridden with CURLOPT_POSTREDIR.
+ */
+ if((data->set.httpreq == HTTPREQ_POST
+ || data->set.httpreq == HTTPREQ_POST_FORM)
+ && !(data->set.keep_post & CURL_REDIR_POST_302)) {
+ infof(data, "Switch from POST to GET\n");
+ data->set.httpreq = HTTPREQ_GET;
+ }
+ break;
+
+ case 303: /* See Other */
+ /* Disable both types of POSTs, unless the user explicitely
+ asks for POST after POST */
+ if(data->set.httpreq != HTTPREQ_GET
+ && !(data->set.keep_post & CURL_REDIR_POST_303)) {
+ data->set.httpreq = HTTPREQ_GET; /* enforce GET request */
+ infof(data, "Disables POST, goes with %s\n",
+ data->set.opt_no_body?"HEAD":"GET");
+ }
+ break;
+ case 304: /* Not Modified */
+ /* 304 means we did a conditional request and it was "Not modified".
+ * We shouldn't get any Location: header in this response!
+ */
+ break;
+ case 305: /* Use Proxy */
+ /* (quote from RFC2616, section 10.3.6):
+ * "The requested resource MUST be accessed through the proxy given
+ * by the Location field. The Location field gives the URI of the
+ * proxy. The recipient is expected to repeat this single request
+ * via the proxy. 305 responses MUST only be generated by origin
+ * servers."
+ */
+ break;
+ }
+ Curl_pgrsTime(data, TIMER_REDIRECT);
+ Curl_pgrsResetTimesSizes(data);
+
+ return CURLE_OK;
+#endif /* CURL_DISABLE_HTTP */
+}
+
+CURLcode
+Curl_reconnect_request(struct connectdata **connp)
+{
+ CURLcode result = CURLE_OK;
+ struct connectdata *conn = *connp;
+ struct SessionHandle *data = conn->data;
+
+ /* This was a re-use of a connection and we got a write error in the
+ * DO-phase. Then we DISCONNECT this connection and have another attempt to
+ * CONNECT and then DO again! The retry cannot possibly find another
+ * connection to re-use, since we only keep one possible connection for
+ * each. */
+
+ infof(data, "Re-used connection seems dead, get a new one\n");
+
+ connclose(conn, "Reconnect dead connection"); /* enforce close */
+ result = Curl_done(&conn, result, FALSE); /* we are so done with this */
+
+ /* conn may no longer be a good pointer, clear it to avoid mistakes by
+ parent functions */
+ *connp = NULL;
+
+ /*
+ * According to bug report #1330310. We need to check for CURLE_SEND_ERROR
+ * here as well. I figure this could happen when the request failed on a FTP
+ * connection and thus Curl_done() itself tried to use the connection
+ * (again). Slight Lack of feedback in the report, but I don't think this
+ * extra check can do much harm.
+ */
+ if(!result || (CURLE_SEND_ERROR == result)) {
+ bool async;
+ bool protocol_done = TRUE;
+
+ /* Now, redo the connect and get a new connection */
+ result = Curl_connect(data, connp, &async, &protocol_done);
+ if(!result) {
+ /* We have connected or sent away a name resolve query fine */
+
+ conn = *connp; /* setup conn to again point to something nice */
+ if(async) {
+ /* Now, if async is TRUE here, we need to wait for the name
+ to resolve */
+ result = Curl_resolver_wait_resolv(conn, NULL);
+ if(result)
+ return result;
+
+ /* Resolved, continue with the connection */
+ result = Curl_async_resolved(conn, &protocol_done);
+ if(result)
+ return result;
+ }
+ }
+ }
+
+ return result;
+}
+
+/* Returns CURLE_OK *and* sets '*url' if a request retry is wanted.
+
+ NOTE: that the *url is malloc()ed. */
+CURLcode Curl_retry_request(struct connectdata *conn,
+ char **url)
+{
+ struct SessionHandle *data = conn->data;
+
+ *url = NULL;
+
+ /* if we're talking upload, we can't do the checks below, unless the protocol
+ is HTTP as when uploading over HTTP we will still get a response */
+ if(data->set.upload &&
+ !(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)))
+ return CURLE_OK;
+
+ if((data->req.bytecount + data->req.headerbytecount == 0) &&
+ conn->bits.reuse &&
+ !data->set.opt_no_body &&
+ (data->set.rtspreq != RTSPREQ_RECEIVE)) {
+ /* We got no data, we attempted to re-use a connection and yet we want a
+ "body". This might happen if the connection was left alive when we were
+ done using it before, but that was closed when we wanted to read from
+ it again. Bad luck. Retry the same request on a fresh connect! */
+ infof(conn->data, "Connection died, retrying a fresh connect\n");
+ *url = strdup(conn->data->change.url);
+ if(!*url)
+ return CURLE_OUT_OF_MEMORY;
+
+ connclose(conn, "retry"); /* close this connection */
+ conn->bits.retry = TRUE; /* mark this as a connection we're about
+ to retry. Marking it this way should
+ prevent i.e HTTP transfers to return
+ error just because nothing has been
+ transferred! */
+
+
+ if(conn->handler->protocol&PROTO_FAMILY_HTTP) {
+ struct HTTP *http = data->req.protop;
+ if(http->writebytecount)
+ return Curl_readrewind(conn);
+ }
+ }
+ return CURLE_OK;
+}
+
+/*
+ * Curl_setup_transfer() is called to setup some basic properties for the
+ * upcoming transfer.
+ */
+void
+Curl_setup_transfer(
+ struct connectdata *conn, /* connection data */
+ int sockindex, /* socket index to read from or -1 */
+ curl_off_t size, /* -1 if unknown at this point */
+ bool getheader, /* TRUE if header parsing is wanted */
+ curl_off_t *bytecountp, /* return number of bytes read or NULL */
+ int writesockindex, /* socket index to write to, it may very well be
+ the same we read from. -1 disables */
+ curl_off_t *writecountp /* return number of bytes written or NULL */
+ )
+{
+ struct SessionHandle *data;
+ struct SingleRequest *k;
+
+ DEBUGASSERT(conn != NULL);
+
+ data = conn->data;
+ k = &data->req;
+
+ DEBUGASSERT((sockindex <= 1) && (sockindex >= -1));
+
+ /* now copy all input parameters */
+ conn->sockfd = sockindex == -1 ?
+ CURL_SOCKET_BAD : conn->sock[sockindex];
+ conn->writesockfd = writesockindex == -1 ?
+ CURL_SOCKET_BAD:conn->sock[writesockindex];
+ k->getheader = getheader;
+
+ k->size = size;
+ k->bytecountp = bytecountp;
+ k->writebytecountp = writecountp;
+
+ /* The code sequence below is placed in this function just because all
+ necessary input is not always known in do_complete() as this function may
+ be called after that */
+
+ if(!k->getheader) {
+ k->header = FALSE;
+ if(size > 0)
+ Curl_pgrsSetDownloadSize(data, size);
+ }
+ /* we want header and/or body, if neither then don't do this! */
+ if(k->getheader || !data->set.opt_no_body) {
+
+ if(conn->sockfd != CURL_SOCKET_BAD)
+ k->keepon |= KEEP_RECV;
+
+ if(conn->writesockfd != CURL_SOCKET_BAD) {
+ struct HTTP *http = data->req.protop;
+ /* HTTP 1.1 magic:
+
+ Even if we require a 100-return code before uploading data, we might
+ need to write data before that since the REQUEST may not have been
+ finished sent off just yet.
+
+ Thus, we must check if the request has been sent before we set the
+ state info where we wait for the 100-return code
+ */
+ if((data->state.expect100header) &&
+ (conn->handler->protocol&PROTO_FAMILY_HTTP) &&
+ (http->sending == HTTPSEND_BODY)) {
+ /* wait with write until we either got 100-continue or a timeout */
+ k->exp100 = EXP100_AWAITING_CONTINUE;
+ k->start100 = Curl_tvnow();
+
+ /* Set a timeout for the multi interface. Add the inaccuracy margin so
+ that we don't fire slightly too early and get denied to run. */
+ Curl_expire(data, data->set.expect_100_timeout);
+ }
+ else {
+ if(data->state.expect100header)
+ /* when we've sent off the rest of the headers, we must await a
+ 100-continue but first finish sending the request */
+ k->exp100 = EXP100_SENDING_REQUEST;
+
+ /* enable the write bit when we're not waiting for continue */
+ k->keepon |= KEEP_SEND;
+ }
+ } /* if(conn->writesockfd != CURL_SOCKET_BAD) */
+ } /* if(k->getheader || !data->set.opt_no_body) */
+
+}
diff --git a/Utilities/cmcurl/lib/transfer.h b/Utilities/cmcurl/lib/transfer.h
new file mode 100644
index 000000000..316aeaebc
--- /dev/null
+++ b/Utilities/cmcurl/lib/transfer.h
@@ -0,0 +1,71 @@
+#ifndef HEADER_CURL_TRANSFER_H
+#define HEADER_CURL_TRANSFER_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+CURLcode Curl_pretransfer(struct SessionHandle *data);
+CURLcode Curl_second_connect(struct connectdata *conn);
+CURLcode Curl_posttransfer(struct SessionHandle *data);
+
+typedef enum {
+ FOLLOW_NONE, /* not used within the function, just a placeholder to
+ allow initing to this */
+ FOLLOW_FAKE, /* only records stuff, not actually following */
+ FOLLOW_RETRY, /* set if this is a request retry as opposed to a real
+ redirect following */
+ FOLLOW_REDIR, /* a full true redirect */
+ FOLLOW_LAST /* never used */
+} followtype;
+
+CURLcode Curl_follow(struct SessionHandle *data, char *newurl,
+ followtype type);
+
+
+CURLcode Curl_readwrite(struct connectdata *conn,
+ struct SessionHandle *data, bool *done);
+int Curl_single_getsock(const struct connectdata *conn,
+ curl_socket_t *socks,
+ int numsocks);
+CURLcode Curl_readrewind(struct connectdata *conn);
+CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp);
+CURLcode Curl_reconnect_request(struct connectdata **connp);
+CURLcode Curl_retry_request(struct connectdata *conn, char **url);
+bool Curl_meets_timecondition(struct SessionHandle *data, time_t timeofdoc);
+
+/* This sets up a forthcoming transfer */
+void
+Curl_setup_transfer (struct connectdata *data,
+ int sockindex, /* socket index to read from or -1 */
+ curl_off_t size, /* -1 if unknown at this point */
+ bool getheader, /* TRUE if header parsing is wanted */
+ curl_off_t *bytecountp, /* return number of bytes read */
+ int writesockindex, /* socket index to write to, it may
+ very well be the same we read from.
+ -1 disables */
+ curl_off_t *writecountp /* return number of bytes written */
+);
+
+long Curl_sleep_time(curl_off_t rate_bps, curl_off_t cur_rate_bps,
+ int pkt_size);
+
+#endif /* HEADER_CURL_TRANSFER_H */
+
diff --git a/Utilities/cmcurl/lib/url.c b/Utilities/cmcurl/lib/url.c
new file mode 100644
index 000000000..406c1f02c
--- /dev/null
+++ b/Utilities/cmcurl/lib/url.c
@@ -0,0 +1,6242 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#ifdef HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+
+#ifndef HAVE_SOCKET
+#error "We can't compile without socket() support!"
+#endif
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#ifdef USE_LIBIDN
+#include <idna.h>
+#include <tld.h>
+#include <stringprep.h>
+#ifdef HAVE_IDN_FREE_H
+#include <idn-free.h>
+#else
+/* prototype from idn-free.h, not provided by libidn 0.4.5's make install! */
+void idn_free (void *ptr);
+#endif
+#ifndef HAVE_IDN_FREE
+/* if idn_free() was not found in this version of libidn use free() instead */
+#define idn_free(x) (free)(x)
+#endif
+#elif defined(USE_WIN32_IDN)
+/* prototype for curl_win32_idn_to_ascii() */
+int curl_win32_idn_to_ascii(const char *in, char **out);
+#endif /* USE_LIBIDN */
+
+#include "urldata.h"
+#include "netrc.h"
+
+#include "formdata.h"
+#include "vtls/vtls.h"
+#include "hostip.h"
+#include "transfer.h"
+#include "sendf.h"
+#include "progress.h"
+#include "cookie.h"
+#include "strequal.h"
+#include "strerror.h"
+#include "escape.h"
+#include "strtok.h"
+#include "share.h"
+#include "content_encoding.h"
+#include "http_digest.h"
+#include "http_negotiate.h"
+#include "select.h"
+#include "multiif.h"
+#include "easyif.h"
+#include "speedcheck.h"
+#include "rawstr.h"
+#include "warnless.h"
+#include "non-ascii.h"
+#include "inet_pton.h"
+
+/* And now for the protocols */
+#include "ftp.h"
+#include "dict.h"
+#include "telnet.h"
+#include "tftp.h"
+#include "http.h"
+#include "file.h"
+#include "curl_ldap.h"
+#include "ssh.h"
+#include "imap.h"
+#include "url.h"
+#include "connect.h"
+#include "inet_ntop.h"
+#include "curl_ntlm.h"
+#include "curl_ntlm_wb.h"
+#include "socks.h"
+#include "curl_rtmp.h"
+#include "gopher.h"
+#include "http_proxy.h"
+#include "conncache.h"
+#include "multihandle.h"
+#include "pipeline.h"
+#include "dotdot.h"
+#include "strdup.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* Local static prototypes */
+static struct connectdata *
+find_oldest_idle_connection(struct SessionHandle *data);
+static struct connectdata *
+find_oldest_idle_connection_in_bundle(struct SessionHandle *data,
+ struct connectbundle *bundle);
+static void conn_free(struct connectdata *conn);
+static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke);
+static CURLcode parse_url_login(struct SessionHandle *data,
+ struct connectdata *conn,
+ char **userptr, char **passwdptr,
+ char **optionsptr);
+static CURLcode parse_login_details(const char *login, const size_t len,
+ char **userptr, char **passwdptr,
+ char **optionsptr);
+/*
+ * Protocol table.
+ */
+
+static const struct Curl_handler * const protocols[] = {
+
+#ifndef CURL_DISABLE_HTTP
+ &Curl_handler_http,
+#endif
+
+#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
+ &Curl_handler_https,
+#endif
+
+#ifndef CURL_DISABLE_FTP
+ &Curl_handler_ftp,
+#endif
+
+#if defined(USE_SSL) && !defined(CURL_DISABLE_FTP)
+ &Curl_handler_ftps,
+#endif
+
+#ifndef CURL_DISABLE_TELNET
+ &Curl_handler_telnet,
+#endif
+
+#ifndef CURL_DISABLE_DICT
+ &Curl_handler_dict,
+#endif
+
+#ifndef CURL_DISABLE_LDAP
+ &Curl_handler_ldap,
+#if !defined(CURL_DISABLE_LDAPS) && \
+ ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \
+ (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))
+ &Curl_handler_ldaps,
+#endif
+#endif
+
+#ifndef CURL_DISABLE_FILE
+ &Curl_handler_file,
+#endif
+
+#ifndef CURL_DISABLE_TFTP
+ &Curl_handler_tftp,
+#endif
+
+#ifdef USE_LIBSSH2
+ &Curl_handler_scp,
+ &Curl_handler_sftp,
+#endif
+
+#ifndef CURL_DISABLE_IMAP
+ &Curl_handler_imap,
+#ifdef USE_SSL
+ &Curl_handler_imaps,
+#endif
+#endif
+
+#ifndef CURL_DISABLE_POP3
+ &Curl_handler_pop3,
+#ifdef USE_SSL
+ &Curl_handler_pop3s,
+#endif
+#endif
+
+#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
+ (CURL_SIZEOF_CURL_OFF_T > 4) && \
+ (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO))
+ &Curl_handler_smb,
+#ifdef USE_SSL
+ &Curl_handler_smbs,
+#endif
+#endif
+
+#ifndef CURL_DISABLE_SMTP
+ &Curl_handler_smtp,
+#ifdef USE_SSL
+ &Curl_handler_smtps,
+#endif
+#endif
+
+#ifndef CURL_DISABLE_RTSP
+ &Curl_handler_rtsp,
+#endif
+
+#ifndef CURL_DISABLE_GOPHER
+ &Curl_handler_gopher,
+#endif
+
+#ifdef USE_LIBRTMP
+ &Curl_handler_rtmp,
+ &Curl_handler_rtmpt,
+ &Curl_handler_rtmpe,
+ &Curl_handler_rtmpte,
+ &Curl_handler_rtmps,
+ &Curl_handler_rtmpts,
+#endif
+
+ (struct Curl_handler *) NULL
+};
+
+/*
+ * Dummy handler for undefined protocol schemes.
+ */
+
+static const struct Curl_handler Curl_handler_dummy = {
+ "<no protocol>", /* scheme */
+ ZERO_NULL, /* setup_connection */
+ ZERO_NULL, /* do_it */
+ ZERO_NULL, /* done */
+ ZERO_NULL, /* do_more */
+ ZERO_NULL, /* connect_it */
+ ZERO_NULL, /* connecting */
+ ZERO_NULL, /* doing */
+ ZERO_NULL, /* proto_getsock */
+ ZERO_NULL, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
+ ZERO_NULL, /* perform_getsock */
+ ZERO_NULL, /* disconnect */
+ ZERO_NULL, /* readwrite */
+ 0, /* defport */
+ 0, /* protocol */
+ PROTOPT_NONE /* flags */
+};
+
+void Curl_freeset(struct SessionHandle *data)
+{
+ /* Free all dynamic strings stored in the data->set substructure. */
+ enum dupstring i;
+ for(i=(enum dupstring)0; i < STRING_LAST; i++) {
+ Curl_safefree(data->set.str[i]);
+ }
+
+ if(data->change.referer_alloc) {
+ Curl_safefree(data->change.referer);
+ data->change.referer_alloc = FALSE;
+ }
+ data->change.referer = NULL;
+ if(data->change.url_alloc) {
+ Curl_safefree(data->change.url);
+ data->change.url_alloc = FALSE;
+ }
+ data->change.url = NULL;
+}
+
+static CURLcode setstropt(char **charp, char *s)
+{
+ /* Release the previous storage at `charp' and replace by a dynamic storage
+ copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */
+
+ Curl_safefree(*charp);
+
+ if(s) {
+ s = strdup(s);
+
+ if(!s)
+ return CURLE_OUT_OF_MEMORY;
+
+ *charp = s;
+ }
+
+ return CURLE_OK;
+}
+
+static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp)
+{
+ CURLcode result = CURLE_OK;
+ char *user = NULL;
+ char *passwd = NULL;
+
+ /* Parse the login details if specified. It not then we treat NULL as a hint
+ to clear the existing data */
+ if(option) {
+ result = parse_login_details(option, strlen(option),
+ (userp ? &user : NULL),
+ (passwdp ? &passwd : NULL),
+ NULL);
+ }
+
+ if(!result) {
+ /* Store the username part of option if required */
+ if(userp) {
+ if(!user && option && option[0] == ':') {
+ /* Allocate an empty string instead of returning NULL as user name */
+ user = strdup("");
+ if(!user)
+ result = CURLE_OUT_OF_MEMORY;
+ }
+
+ Curl_safefree(*userp);
+ *userp = user;
+ }
+
+ /* Store the password part of option if required */
+ if(passwdp) {
+ Curl_safefree(*passwdp);
+ *passwdp = passwd;
+ }
+ }
+
+ return result;
+}
+
+CURLcode Curl_dupset(struct SessionHandle *dst, struct SessionHandle *src)
+{
+ CURLcode result = CURLE_OK;
+ enum dupstring i;
+
+ /* Copy src->set into dst->set first, then deal with the strings
+ afterwards */
+ dst->set = src->set;
+
+ /* clear all string pointers first */
+ memset(dst->set.str, 0, STRING_LAST * sizeof(char *));
+
+ /* duplicate all strings */
+ for(i=(enum dupstring)0; i< STRING_LASTZEROTERMINATED; i++) {
+ result = setstropt(&dst->set.str[i], src->set.str[i]);
+ if(result)
+ return result;
+ }
+
+ /* duplicate memory areas pointed to */
+ i = STRING_COPYPOSTFIELDS;
+ if(src->set.postfieldsize && src->set.str[i]) {
+ /* postfieldsize is curl_off_t, Curl_memdup() takes a size_t ... */
+ dst->set.str[i] = Curl_memdup(src->set.str[i],
+ curlx_sotouz(src->set.postfieldsize));
+ if(!dst->set.str[i])
+ return CURLE_OUT_OF_MEMORY;
+ /* point to the new copy */
+ dst->set.postfields = dst->set.str[i];
+ }
+
+ return CURLE_OK;
+}
+
+/*
+ * This is the internal function curl_easy_cleanup() calls. This should
+ * cleanup and free all resources associated with this sessionhandle.
+ *
+ * NOTE: if we ever add something that attempts to write to a socket or
+ * similar here, we must ignore SIGPIPE first. It is currently only done
+ * when curl_easy_perform() is invoked.
+ */
+
+CURLcode Curl_close(struct SessionHandle *data)
+{
+ struct Curl_multi *m;
+
+ if(!data)
+ return CURLE_OK;
+
+ Curl_expire(data, 0); /* shut off timers */
+
+ m = data->multi;
+
+ if(m)
+ /* This handle is still part of a multi handle, take care of this first
+ and detach this handle from there. */
+ curl_multi_remove_handle(data->multi, data);
+
+ if(data->multi_easy)
+ /* when curl_easy_perform() is used, it creates its own multi handle to
+ use and this is the one */
+ curl_multi_cleanup(data->multi_easy);
+
+ /* Destroy the timeout list that is held in the easy handle. It is
+ /normally/ done by curl_multi_remove_handle() but this is "just in
+ case" */
+ if(data->state.timeoutlist) {
+ Curl_llist_destroy(data->state.timeoutlist, NULL);
+ data->state.timeoutlist = NULL;
+ }
+
+ data->magic = 0; /* force a clear AFTER the possibly enforced removal from
+ the multi handle, since that function uses the magic
+ field! */
+
+ if(data->state.rangestringalloc)
+ free(data->state.range);
+
+ /* Free the pathbuffer */
+ Curl_safefree(data->state.pathbuffer);
+ data->state.path = NULL;
+
+ /* freed here just in case DONE wasn't called */
+ Curl_free_request_state(data);
+
+ /* Close down all open SSL info and sessions */
+ Curl_ssl_close_all(data);
+ Curl_safefree(data->state.first_host);
+ Curl_safefree(data->state.scratch);
+ Curl_ssl_free_certinfo(data);
+
+ /* Cleanup possible redirect junk */
+ free(data->req.newurl);
+ data->req.newurl = NULL;
+
+ if(data->change.referer_alloc) {
+ Curl_safefree(data->change.referer);
+ data->change.referer_alloc = FALSE;
+ }
+ data->change.referer = NULL;
+
+ if(data->change.url_alloc) {
+ Curl_safefree(data->change.url);
+ data->change.url_alloc = FALSE;
+ }
+ data->change.url = NULL;
+
+ Curl_safefree(data->state.headerbuff);
+
+ Curl_flush_cookies(data, 1);
+
+ Curl_digest_cleanup(data);
+
+ Curl_safefree(data->info.contenttype);
+ Curl_safefree(data->info.wouldredirect);
+
+ /* this destroys the channel and we cannot use it anymore after this */
+ Curl_resolver_cleanup(data->state.resolver);
+
+ Curl_convert_close(data);
+
+ /* No longer a dirty share, if it exists */
+ if(data->share) {
+ Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
+ data->share->dirty--;
+ Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
+ }
+
+ Curl_freeset(data);
+ free(data);
+ return CURLE_OK;
+}
+
+/*
+ * Initialize the UserDefined fields within a SessionHandle.
+ * This may be safely called on a new or existing SessionHandle.
+ */
+CURLcode Curl_init_userdefined(struct UserDefined *set)
+{
+ CURLcode result = CURLE_OK;
+
+ set->out = stdout; /* default output to stdout */
+ set->in = stdin; /* default input from stdin */
+ set->err = stderr; /* default stderr to stderr */
+
+ /* use fwrite as default function to store output */
+ set->fwrite_func = (curl_write_callback)fwrite;
+
+ /* use fread as default function to read input */
+ set->fread_func = (curl_read_callback)fread;
+ set->is_fread_set = 0;
+ set->is_fwrite_set = 0;
+
+ set->seek_func = ZERO_NULL;
+ set->seek_client = ZERO_NULL;
+
+ /* conversion callbacks for non-ASCII hosts */
+ set->convfromnetwork = ZERO_NULL;
+ set->convtonetwork = ZERO_NULL;
+ set->convfromutf8 = ZERO_NULL;
+
+ set->filesize = -1; /* we don't know the size */
+ set->postfieldsize = -1; /* unknown size */
+ set->maxredirs = -1; /* allow any amount by default */
+
+ set->httpreq = HTTPREQ_GET; /* Default HTTP request */
+ set->rtspreq = RTSPREQ_OPTIONS; /* Default RTSP request */
+ set->ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */
+ set->ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */
+ set->ftp_use_pret = FALSE; /* mainly useful for drftpd servers */
+ set->ftp_filemethod = FTPFILE_MULTICWD;
+
+ set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
+
+ /* Set the default size of the SSL session ID cache */
+ set->ssl.max_ssl_sessions = 5;
+
+ set->proxyport = CURL_DEFAULT_PROXY_PORT; /* from url.h */
+ set->proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
+ set->httpauth = CURLAUTH_BASIC; /* defaults to basic */
+ set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */
+
+ /* make libcurl quiet by default: */
+ set->hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */
+
+ /*
+ * libcurl 7.10 introduced SSL verification *by default*! This needs to be
+ * switched off unless wanted.
+ */
+ set->ssl.verifypeer = TRUE;
+ set->ssl.verifyhost = TRUE;
+#ifdef USE_TLS_SRP
+ set->ssl.authtype = CURL_TLSAUTH_NONE;
+#endif
+ set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
+ type */
+ set->ssl.sessionid = TRUE; /* session ID caching enabled by default */
+
+ set->new_file_perms = 0644; /* Default permissions */
+ set->new_directory_perms = 0755; /* Default permissions */
+
+ /* for the *protocols fields we don't use the CURLPROTO_ALL convenience
+ define since we internally only use the lower 16 bits for the passed
+ in bitmask to not conflict with the private bits */
+ set->allowed_protocols = CURLPROTO_ALL;
+ set->redir_protocols = CURLPROTO_ALL & /* All except FILE, SCP and SMB */
+ ~(CURLPROTO_FILE | CURLPROTO_SCP | CURLPROTO_SMB |
+ CURLPROTO_SMBS);
+
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+ /*
+ * disallow unprotected protection negotiation NEC reference implementation
+ * seem not to follow rfc1961 section 4.3/4.4
+ */
+ set->socks5_gssapi_nec = FALSE;
+ /* set default GSS-API service name */
+ result = setstropt(&set->str[STRING_SOCKS5_GSSAPI_SERVICE],
+ (char *) CURL_DEFAULT_SOCKS5_GSSAPI_SERVICE);
+ if(result)
+ return result;
+
+ /* set default negotiate proxy service name */
+ result = setstropt(&set->str[STRING_PROXY_SERVICE_NAME],
+ (char *) CURL_DEFAULT_PROXY_SERVICE_NAME);
+ if(result)
+ return result;
+
+ /* set default negotiate service name */
+ result = setstropt(&set->str[STRING_SERVICE_NAME],
+ (char *) CURL_DEFAULT_SERVICE_NAME);
+ if(result)
+ return result;
+#endif
+
+ /* This is our preferred CA cert bundle/path since install time */
+#if defined(CURL_CA_BUNDLE)
+ result = setstropt(&set->str[STRING_SSL_CAFILE], (char *) CURL_CA_BUNDLE);
+ if(result)
+ return result;
+#endif
+#if defined(CURL_CA_PATH)
+ result = setstropt(&set->str[STRING_SSL_CAPATH], (char *) CURL_CA_PATH);
+ if(result)
+ return result;
+#endif
+
+ set->wildcardmatch = FALSE;
+ set->chunk_bgn = ZERO_NULL;
+ set->chunk_end = ZERO_NULL;
+
+ /* tcp keepalives are disabled by default, but provide reasonable values for
+ * the interval and idle times.
+ */
+ set->tcp_keepalive = FALSE;
+ set->tcp_keepintvl = 60;
+ set->tcp_keepidle = 60;
+
+ set->ssl_enable_npn = TRUE;
+ set->ssl_enable_alpn = TRUE;
+
+ set->expect_100_timeout = 1000L; /* Wait for a second by default. */
+ set->sep_headers = TRUE; /* separated header lists by default */
+ return result;
+}
+
+/**
+ * Curl_open()
+ *
+ * @param curl is a pointer to a sessionhandle pointer that gets set by this
+ * function.
+ * @return CURLcode
+ */
+
+CURLcode Curl_open(struct SessionHandle **curl)
+{
+ CURLcode result;
+ struct SessionHandle *data;
+
+ /* Very simple start-up: alloc the struct, init it with zeroes and return */
+ data = calloc(1, sizeof(struct SessionHandle));
+ if(!data) {
+ /* this is a very serious error */
+ DEBUGF(fprintf(stderr, "Error: calloc of SessionHandle failed\n"));
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ data->magic = CURLEASY_MAGIC_NUMBER;
+
+ result = Curl_resolver_init(&data->state.resolver);
+ if(result) {
+ DEBUGF(fprintf(stderr, "Error: resolver_init failed\n"));
+ free(data);
+ return result;
+ }
+
+ /* We do some initial setup here, all those fields that can't be just 0 */
+
+ data->state.headerbuff = malloc(HEADERSIZE);
+ if(!data->state.headerbuff) {
+ DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n"));
+ result = CURLE_OUT_OF_MEMORY;
+ }
+ else {
+ result = Curl_init_userdefined(&data->set);
+
+ data->state.headersize=HEADERSIZE;
+
+ Curl_convert_init(data);
+
+ /* most recent connection is not yet defined */
+ data->state.lastconnect = NULL;
+
+ data->progress.flags |= PGRS_HIDE;
+ data->state.current_speed = -1; /* init to negative == impossible */
+
+ data->wildcard.state = CURLWC_INIT;
+ data->wildcard.filelist = NULL;
+ data->set.fnmatch = ZERO_NULL;
+ data->set.maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */
+ }
+
+ if(result) {
+ Curl_resolver_cleanup(data->state.resolver);
+ free(data->state.headerbuff);
+ Curl_freeset(data);
+ free(data);
+ data = NULL;
+ }
+ else
+ *curl = data;
+
+ return result;
+}
+
+CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
+ va_list param)
+{
+ char *argptr;
+ CURLcode result = CURLE_OK;
+ long arg;
+#ifndef CURL_DISABLE_HTTP
+ curl_off_t bigsize;
+#endif
+
+ switch(option) {
+ case CURLOPT_DNS_CACHE_TIMEOUT:
+ data->set.dns_cache_timeout = va_arg(param, long);
+ break;
+ case CURLOPT_DNS_USE_GLOBAL_CACHE:
+ /* remember we want this enabled */
+ arg = va_arg(param, long);
+ data->set.global_dns_cache = (0 != arg)?TRUE:FALSE;
+ break;
+ case CURLOPT_SSL_CIPHER_LIST:
+ /* set a list of cipher we want to use in the SSL connection */
+ result = setstropt(&data->set.str[STRING_SSL_CIPHER_LIST],
+ va_arg(param, char *));
+ break;
+
+ case CURLOPT_RANDOM_FILE:
+ /*
+ * This is the path name to a file that contains random data to seed
+ * the random SSL stuff with. The file is only used for reading.
+ */
+ result = setstropt(&data->set.str[STRING_SSL_RANDOM_FILE],
+ va_arg(param, char *));
+ break;
+ case CURLOPT_EGDSOCKET:
+ /*
+ * The Entropy Gathering Daemon socket pathname
+ */
+ result = setstropt(&data->set.str[STRING_SSL_EGDSOCKET],
+ va_arg(param, char *));
+ break;
+ case CURLOPT_MAXCONNECTS:
+ /*
+ * Set the absolute number of maximum simultaneous alive connection that
+ * libcurl is allowed to have.
+ */
+ data->set.maxconnects = va_arg(param, long);
+ break;
+ case CURLOPT_FORBID_REUSE:
+ /*
+ * When this transfer is done, it must not be left to be reused by a
+ * subsequent transfer but shall be closed immediately.
+ */
+ data->set.reuse_forbid = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+ case CURLOPT_FRESH_CONNECT:
+ /*
+ * This transfer shall not use a previously cached connection but
+ * should be made with a fresh new connect!
+ */
+ data->set.reuse_fresh = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+ case CURLOPT_VERBOSE:
+ /*
+ * Verbose means infof() calls that give a lot of information about
+ * the connection and transfer procedures as well as internal choices.
+ */
+ data->set.verbose = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+ case CURLOPT_HEADER:
+ /*
+ * Set to include the header in the general data output stream.
+ */
+ data->set.include_header = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+ case CURLOPT_NOPROGRESS:
+ /*
+ * Shut off the internal supported progress meter
+ */
+ data->set.hide_progress = (0 != va_arg(param, long))?TRUE:FALSE;
+ if(data->set.hide_progress)
+ data->progress.flags |= PGRS_HIDE;
+ else
+ data->progress.flags &= ~PGRS_HIDE;
+ break;
+ case CURLOPT_NOBODY:
+ /*
+ * Do not include the body part in the output data stream.
+ */
+ data->set.opt_no_body = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+ case CURLOPT_FAILONERROR:
+ /*
+ * Don't output the >=400 error code HTML-page, but instead only
+ * return error.
+ */
+ data->set.http_fail_on_error = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+ case CURLOPT_UPLOAD:
+ case CURLOPT_PUT:
+ /*
+ * We want to sent data to the remote host. If this is HTTP, that equals
+ * using the PUT request.
+ */
+ data->set.upload = (0 != va_arg(param, long))?TRUE:FALSE;
+ if(data->set.upload) {
+ /* If this is HTTP, PUT is what's needed to "upload" */
+ data->set.httpreq = HTTPREQ_PUT;
+ data->set.opt_no_body = FALSE; /* this is implied */
+ }
+ else
+ /* In HTTP, the opposite of upload is GET (unless NOBODY is true as
+ then this can be changed to HEAD later on) */
+ data->set.httpreq = HTTPREQ_GET;
+ break;
+ case CURLOPT_FILETIME:
+ /*
+ * Try to get the file time of the remote document. The time will
+ * later (possibly) become available using curl_easy_getinfo().
+ */
+ data->set.get_filetime = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+ case CURLOPT_FTP_CREATE_MISSING_DIRS:
+ /*
+ * An FTP option that modifies an upload to create missing directories on
+ * the server.
+ */
+ switch(va_arg(param, long)) {
+ case 0:
+ data->set.ftp_create_missing_dirs = 0;
+ break;
+ case 1:
+ data->set.ftp_create_missing_dirs = 1;
+ break;
+ case 2:
+ data->set.ftp_create_missing_dirs = 2;
+ break;
+ default:
+ /* reserve other values for future use */
+ result = CURLE_UNKNOWN_OPTION;
+ break;
+ }
+ break;
+ case CURLOPT_SERVER_RESPONSE_TIMEOUT:
+ /*
+ * Option that specifies how quickly an server response must be obtained
+ * before it is considered failure. For pingpong protocols.
+ */
+ data->set.server_response_timeout = va_arg( param , long ) * 1000;
+ break;
+ case CURLOPT_TFTP_BLKSIZE:
+ /*
+ * TFTP option that specifies the block size to use for data transmission
+ */
+ data->set.tftp_blksize = va_arg(param, long);
+ break;
+ case CURLOPT_DIRLISTONLY:
+ /*
+ * An option that changes the command to one that asks for a list
+ * only, no file info details.
+ */
+ data->set.ftp_list_only = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+ case CURLOPT_APPEND:
+ /*
+ * We want to upload and append to an existing file.
+ */
+ data->set.ftp_append = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+ case CURLOPT_FTP_FILEMETHOD:
+ /*
+ * How do access files over FTP.
+ */
+ data->set.ftp_filemethod = (curl_ftpfile)va_arg(param, long);
+ break;
+ case CURLOPT_NETRC:
+ /*
+ * Parse the $HOME/.netrc file
+ */
+ data->set.use_netrc = (enum CURL_NETRC_OPTION)va_arg(param, long);
+ break;
+ case CURLOPT_NETRC_FILE:
+ /*
+ * Use this file instead of the $HOME/.netrc file
+ */
+ result = setstropt(&data->set.str[STRING_NETRC_FILE],
+ va_arg(param, char *));
+ break;
+ case CURLOPT_TRANSFERTEXT:
+ /*
+ * This option was previously named 'FTPASCII'. Renamed to work with
+ * more protocols than merely FTP.
+ *
+ * Transfer using ASCII (instead of BINARY).
+ */
+ data->set.prefer_ascii = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+ case CURLOPT_TIMECONDITION:
+ /*
+ * Set HTTP time condition. This must be one of the defines in the
+ * curl/curl.h header file.
+ */
+ data->set.timecondition = (curl_TimeCond)va_arg(param, long);
+ break;
+ case CURLOPT_TIMEVALUE:
+ /*
+ * This is the value to compare with the remote document with the
+ * method set with CURLOPT_TIMECONDITION
+ */
+ data->set.timevalue = (time_t)va_arg(param, long);
+ break;
+ case CURLOPT_SSLVERSION:
+ /*
+ * Set explicit SSL version to try to connect with, as some SSL
+ * implementations are lame.
+ */
+#ifdef USE_SSL
+ data->set.ssl.version = va_arg(param, long);
+#else
+ result = CURLE_UNKNOWN_OPTION;
+#endif
+ break;
+
+#ifndef CURL_DISABLE_HTTP
+ case CURLOPT_AUTOREFERER:
+ /*
+ * Switch on automatic referer that gets set if curl follows locations.
+ */
+ data->set.http_auto_referer = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+
+ case CURLOPT_ACCEPT_ENCODING:
+ /*
+ * String to use at the value of Accept-Encoding header.
+ *
+ * If the encoding is set to "" we use an Accept-Encoding header that
+ * encompasses all the encodings we support.
+ * If the encoding is set to NULL we don't send an Accept-Encoding header
+ * and ignore an received Content-Encoding header.
+ *
+ */
+ argptr = va_arg(param, char *);
+ result = setstropt(&data->set.str[STRING_ENCODING],
+ (argptr && !*argptr)?
+ (char *) ALL_CONTENT_ENCODINGS: argptr);
+ break;
+
+ case CURLOPT_TRANSFER_ENCODING:
+ data->set.http_transfer_encoding = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+
+ case CURLOPT_FOLLOWLOCATION:
+ /*
+ * Follow Location: header hints on a HTTP-server.
+ */
+ data->set.http_follow_location = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+
+ case CURLOPT_UNRESTRICTED_AUTH:
+ /*
+ * Send authentication (user+password) when following locations, even when
+ * hostname changed.
+ */
+ data->set.http_disable_hostname_check_before_authentication =
+ (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+
+ case CURLOPT_MAXREDIRS:
+ /*
+ * The maximum amount of hops you allow curl to follow Location:
+ * headers. This should mostly be used to detect never-ending loops.
+ */
+ data->set.maxredirs = va_arg(param, long);
+ break;
+
+ case CURLOPT_POSTREDIR:
+ {
+ /*
+ * Set the behaviour of POST when redirecting
+ * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302
+ * CURL_REDIR_POST_301 - POST is kept as POST after 301
+ * CURL_REDIR_POST_302 - POST is kept as POST after 302
+ * CURL_REDIR_POST_303 - POST is kept as POST after 303
+ * CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303
+ * other - POST is kept as POST after 301 and 302
+ */
+ int postRedir = curlx_sltosi(va_arg(param, long));
+ data->set.keep_post = postRedir & CURL_REDIR_POST_ALL;
+ }
+ break;
+
+ case CURLOPT_POST:
+ /* Does this option serve a purpose anymore? Yes it does, when
+ CURLOPT_POSTFIELDS isn't used and the POST data is read off the
+ callback! */
+ if(va_arg(param, long)) {
+ data->set.httpreq = HTTPREQ_POST;
+ data->set.opt_no_body = FALSE; /* this is implied */
+ }
+ else
+ data->set.httpreq = HTTPREQ_GET;
+ break;
+
+ case CURLOPT_COPYPOSTFIELDS:
+ /*
+ * A string with POST data. Makes curl HTTP POST. Even if it is NULL.
+ * If needed, CURLOPT_POSTFIELDSIZE must have been set prior to
+ * CURLOPT_COPYPOSTFIELDS and not altered later.
+ */
+ argptr = va_arg(param, char *);
+
+ if(!argptr || data->set.postfieldsize == -1)
+ result = setstropt(&data->set.str[STRING_COPYPOSTFIELDS], argptr);
+ else {
+ /*
+ * Check that requested length does not overflow the size_t type.
+ */
+
+ if((data->set.postfieldsize < 0) ||
+ ((sizeof(curl_off_t) != sizeof(size_t)) &&
+ (data->set.postfieldsize > (curl_off_t)((size_t)-1))))
+ result = CURLE_OUT_OF_MEMORY;
+ else {
+ char * p;
+
+ (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
+
+ /* Allocate even when size == 0. This satisfies the need of possible
+ later address compare to detect the COPYPOSTFIELDS mode, and
+ to mark that postfields is used rather than read function or
+ form data.
+ */
+ p = malloc((size_t)(data->set.postfieldsize?
+ data->set.postfieldsize:1));
+
+ if(!p)
+ result = CURLE_OUT_OF_MEMORY;
+ else {
+ if(data->set.postfieldsize)
+ memcpy(p, argptr, (size_t)data->set.postfieldsize);
+
+ data->set.str[STRING_COPYPOSTFIELDS] = p;
+ }
+ }
+ }
+
+ data->set.postfields = data->set.str[STRING_COPYPOSTFIELDS];
+ data->set.httpreq = HTTPREQ_POST;
+ break;
+
+ case CURLOPT_POSTFIELDS:
+ /*
+ * Like above, but use static data instead of copying it.
+ */
+ data->set.postfields = va_arg(param, void *);
+ /* Release old copied data. */
+ (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
+ data->set.httpreq = HTTPREQ_POST;
+ break;
+
+ case CURLOPT_POSTFIELDSIZE:
+ /*
+ * The size of the POSTFIELD data to prevent libcurl to do strlen() to
+ * figure it out. Enables binary posts.
+ */
+ bigsize = va_arg(param, long);
+
+ if(data->set.postfieldsize < bigsize &&
+ data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
+ /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
+ (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
+ data->set.postfields = NULL;
+ }
+
+ data->set.postfieldsize = bigsize;
+ break;
+
+ case CURLOPT_POSTFIELDSIZE_LARGE:
+ /*
+ * The size of the POSTFIELD data to prevent libcurl to do strlen() to
+ * figure it out. Enables binary posts.
+ */
+ bigsize = va_arg(param, curl_off_t);
+
+ if(data->set.postfieldsize < bigsize &&
+ data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
+ /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
+ (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
+ data->set.postfields = NULL;
+ }
+
+ data->set.postfieldsize = bigsize;
+ break;
+
+ case CURLOPT_HTTPPOST:
+ /*
+ * Set to make us do HTTP POST
+ */
+ data->set.httppost = va_arg(param, struct curl_httppost *);
+ data->set.httpreq = HTTPREQ_POST_FORM;
+ data->set.opt_no_body = FALSE; /* this is implied */
+ break;
+
+ case CURLOPT_REFERER:
+ /*
+ * String to set in the HTTP Referer: field.
+ */
+ if(data->change.referer_alloc) {
+ Curl_safefree(data->change.referer);
+ data->change.referer_alloc = FALSE;
+ }
+ result = setstropt(&data->set.str[STRING_SET_REFERER],
+ va_arg(param, char *));
+ data->change.referer = data->set.str[STRING_SET_REFERER];
+ break;
+
+ case CURLOPT_USERAGENT:
+ /*
+ * String to use in the HTTP User-Agent field
+ */
+ result = setstropt(&data->set.str[STRING_USERAGENT],
+ va_arg(param, char *));
+ break;
+
+ case CURLOPT_HTTPHEADER:
+ /*
+ * Set a list with HTTP headers to use (or replace internals with)
+ */
+ data->set.headers = va_arg(param, struct curl_slist *);
+ break;
+
+ case CURLOPT_PROXYHEADER:
+ /*
+ * Set a list with proxy headers to use (or replace internals with)
+ *
+ * Since CURLOPT_HTTPHEADER was the only way to set HTTP headers for a
+ * long time we remain doing it this way until CURLOPT_PROXYHEADER is
+ * used. As soon as this option has been used, if set to anything but
+ * NULL, custom headers for proxies are only picked from this list.
+ *
+ * Set this option to NULL to restore the previous behavior.
+ */
+ data->set.proxyheaders = va_arg(param, struct curl_slist *);
+ break;
+
+ case CURLOPT_HEADEROPT:
+ /*
+ * Set header option.
+ */
+ arg = va_arg(param, long);
+ data->set.sep_headers = (arg & CURLHEADER_SEPARATE)? TRUE: FALSE;
+ break;
+
+ case CURLOPT_HTTP200ALIASES:
+ /*
+ * Set a list of aliases for HTTP 200 in response header
+ */
+ data->set.http200aliases = va_arg(param, struct curl_slist *);
+ break;
+
+#if !defined(CURL_DISABLE_COOKIES)
+ case CURLOPT_COOKIE:
+ /*
+ * Cookie string to send to the remote server in the request.
+ */
+ result = setstropt(&data->set.str[STRING_COOKIE],
+ va_arg(param, char *));
+ break;
+
+ case CURLOPT_COOKIEFILE:
+ /*
+ * Set cookie file to read and parse. Can be used multiple times.
+ */
+ argptr = (char *)va_arg(param, void *);
+ if(argptr) {
+ struct curl_slist *cl;
+ /* append the cookie file name to the list of file names, and deal with
+ them later */
+ cl = curl_slist_append(data->change.cookielist, argptr);
+ if(!cl) {
+ curl_slist_free_all(data->change.cookielist);
+ data->change.cookielist = NULL;
+ return CURLE_OUT_OF_MEMORY;
+ }
+ data->change.cookielist = cl; /* store the list for later use */
+ }
+ break;
+
+ case CURLOPT_COOKIEJAR:
+ /*
+ * Set cookie file name to dump all cookies to when we're done.
+ */
+ {
+ struct CookieInfo *newcookies;
+ result = setstropt(&data->set.str[STRING_COOKIEJAR],
+ va_arg(param, char *));
+
+ /*
+ * Activate the cookie parser. This may or may not already
+ * have been made.
+ */
+ newcookies = Curl_cookie_init(data, NULL, data->cookies,
+ data->set.cookiesession);
+ if(!newcookies)
+ result = CURLE_OUT_OF_MEMORY;
+ data->cookies = newcookies;
+ }
+ break;
+
+ case CURLOPT_COOKIESESSION:
+ /*
+ * Set this option to TRUE to start a new "cookie session". It will
+ * prevent the forthcoming read-cookies-from-file actions to accept
+ * cookies that are marked as being session cookies, as they belong to a
+ * previous session.
+ *
+ * In the original Netscape cookie spec, "session cookies" are cookies
+ * with no expire date set. RFC2109 describes the same action if no
+ * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds
+ * a 'Discard' action that can enforce the discard even for cookies that
+ * have a Max-Age.
+ *
+ * We run mostly with the original cookie spec, as hardly anyone implements
+ * anything else.
+ */
+ data->set.cookiesession = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+
+ case CURLOPT_COOKIELIST:
+ argptr = va_arg(param, char *);
+
+ if(argptr == NULL)
+ break;
+
+ if(Curl_raw_equal(argptr, "ALL")) {
+ /* clear all cookies */
+ Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
+ Curl_cookie_clearall(data->cookies);
+ Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
+ }
+ else if(Curl_raw_equal(argptr, "SESS")) {
+ /* clear session cookies */
+ Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
+ Curl_cookie_clearsess(data->cookies);
+ Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
+ }
+ else if(Curl_raw_equal(argptr, "FLUSH")) {
+ /* flush cookies to file, takes care of the locking */
+ Curl_flush_cookies(data, 0);
+ }
+ else if(Curl_raw_equal(argptr, "RELOAD")) {
+ /* reload cookies from file */
+ Curl_cookie_loadfiles(data);
+ break;
+ }
+ else {
+ if(!data->cookies)
+ /* if cookie engine was not running, activate it */
+ data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE);
+
+ argptr = strdup(argptr);
+ if(!argptr || !data->cookies) {
+ result = CURLE_OUT_OF_MEMORY;
+ free(argptr);
+ }
+ else {
+ Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
+
+ if(checkprefix("Set-Cookie:", argptr))
+ /* HTTP Header format line */
+ Curl_cookie_add(data, data->cookies, TRUE, argptr + 11, NULL, NULL);
+
+ else
+ /* Netscape format line */
+ Curl_cookie_add(data, data->cookies, FALSE, argptr, NULL, NULL);
+
+ Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
+ free(argptr);
+ }
+ }
+
+ break;
+#endif /* CURL_DISABLE_COOKIES */
+
+ case CURLOPT_HTTPGET:
+ /*
+ * Set to force us do HTTP GET
+ */
+ if(va_arg(param, long)) {
+ data->set.httpreq = HTTPREQ_GET;
+ data->set.upload = FALSE; /* switch off upload */
+ data->set.opt_no_body = FALSE; /* this is implied */
+ }
+ break;
+
+ case CURLOPT_HTTP_VERSION:
+ /*
+ * This sets a requested HTTP version to be used. The value is one of
+ * the listed enums in curl/curl.h.
+ */
+ arg = va_arg(param, long);
+#ifndef USE_NGHTTP2
+ if(arg == CURL_HTTP_VERSION_2_0)
+ return CURLE_UNSUPPORTED_PROTOCOL;
+#endif
+ data->set.httpversion = arg;
+ break;
+
+ case CURLOPT_HTTPAUTH:
+ /*
+ * Set HTTP Authentication type BITMASK.
+ */
+ {
+ int bitcheck;
+ bool authbits;
+ unsigned long auth = va_arg(param, unsigned long);
+
+ if(auth == CURLAUTH_NONE) {
+ data->set.httpauth = auth;
+ break;
+ }
+
+ /* the DIGEST_IE bit is only used to set a special marker, for all the
+ rest we need to handle it as normal DIGEST */
+ data->state.authhost.iestyle = (auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE;
+
+ if(auth & CURLAUTH_DIGEST_IE) {
+ auth |= CURLAUTH_DIGEST; /* set standard digest bit */
+ auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
+ }
+
+ /* switch off bits we can't support */
+#ifndef USE_NTLM
+ auth &= ~CURLAUTH_NTLM; /* no NTLM support */
+ auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
+#elif !defined(NTLM_WB_ENABLED)
+ auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
+#endif
+#ifndef USE_SPNEGO
+ auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without
+ GSS-API or SSPI */
+#endif
+
+ /* check if any auth bit lower than CURLAUTH_ONLY is still set */
+ bitcheck = 0;
+ authbits = FALSE;
+ while(bitcheck < 31) {
+ if(auth & (1UL << bitcheck++)) {
+ authbits = TRUE;
+ break;
+ }
+ }
+ if(!authbits)
+ return CURLE_NOT_BUILT_IN; /* no supported types left! */
+
+ data->set.httpauth = auth;
+ }
+ break;
+
+ case CURLOPT_EXPECT_100_TIMEOUT_MS:
+ /*
+ * Time to wait for a response to a HTTP request containing an
+ * Expect: 100-continue header before sending the data anyway.
+ */
+ data->set.expect_100_timeout = va_arg(param, long);
+ break;
+
+#endif /* CURL_DISABLE_HTTP */
+
+ case CURLOPT_CUSTOMREQUEST:
+ /*
+ * Set a custom string to use as request
+ */
+ result = setstropt(&data->set.str[STRING_CUSTOMREQUEST],
+ va_arg(param, char *));
+
+ /* we don't set
+ data->set.httpreq = HTTPREQ_CUSTOM;
+ here, we continue as if we were using the already set type
+ and this just changes the actual request keyword */
+ break;
+
+#ifndef CURL_DISABLE_PROXY
+ case CURLOPT_HTTPPROXYTUNNEL:
+ /*
+ * Tunnel operations through the proxy instead of normal proxy use
+ */
+ data->set.tunnel_thru_httpproxy = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+
+ case CURLOPT_PROXYPORT:
+ /*
+ * Explicitly set HTTP proxy port number.
+ */
+ data->set.proxyport = va_arg(param, long);
+ break;
+
+ case CURLOPT_PROXYAUTH:
+ /*
+ * Set HTTP Authentication type BITMASK.
+ */
+ {
+ int bitcheck;
+ bool authbits;
+ unsigned long auth = va_arg(param, unsigned long);
+
+ if(auth == CURLAUTH_NONE) {
+ data->set.proxyauth = auth;
+ break;
+ }
+
+ /* the DIGEST_IE bit is only used to set a special marker, for all the
+ rest we need to handle it as normal DIGEST */
+ data->state.authproxy.iestyle = (auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE;
+
+ if(auth & CURLAUTH_DIGEST_IE) {
+ auth |= CURLAUTH_DIGEST; /* set standard digest bit */
+ auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
+ }
+ /* switch off bits we can't support */
+#ifndef USE_NTLM
+ auth &= ~CURLAUTH_NTLM; /* no NTLM support */
+ auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
+#elif !defined(NTLM_WB_ENABLED)
+ auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
+#endif
+#ifndef USE_SPNEGO
+ auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without
+ GSS-API or SSPI */
+#endif
+
+ /* check if any auth bit lower than CURLAUTH_ONLY is still set */
+ bitcheck = 0;
+ authbits = FALSE;
+ while(bitcheck < 31) {
+ if(auth & (1UL << bitcheck++)) {
+ authbits = TRUE;
+ break;
+ }
+ }
+ if(!authbits)
+ return CURLE_NOT_BUILT_IN; /* no supported types left! */
+
+ data->set.proxyauth = auth;
+ }
+ break;
+
+ case CURLOPT_PROXY:
+ /*
+ * Set proxy server:port to use as HTTP proxy.
+ *
+ * If the proxy is set to "" we explicitly say that we don't want to use a
+ * proxy (even though there might be environment variables saying so).
+ *
+ * Setting it to NULL, means no proxy but allows the environment variables
+ * to decide for us.
+ */
+ result = setstropt(&data->set.str[STRING_PROXY],
+ va_arg(param, char *));
+ break;
+
+ case CURLOPT_PROXYTYPE:
+ /*
+ * Set proxy type. HTTP/HTTP_1_0/SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME
+ */
+ data->set.proxytype = (curl_proxytype)va_arg(param, long);
+ break;
+
+ case CURLOPT_PROXY_TRANSFER_MODE:
+ /*
+ * set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy
+ */
+ switch (va_arg(param, long)) {
+ case 0:
+ data->set.proxy_transfer_mode = FALSE;
+ break;
+ case 1:
+ data->set.proxy_transfer_mode = TRUE;
+ break;
+ default:
+ /* reserve other values for future use */
+ result = CURLE_UNKNOWN_OPTION;
+ break;
+ }
+ break;
+#endif /* CURL_DISABLE_PROXY */
+
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+ case CURLOPT_SOCKS5_GSSAPI_SERVICE:
+ /*
+ * Set GSS-API service name
+ */
+ result = setstropt(&data->set.str[STRING_SOCKS5_GSSAPI_SERVICE],
+ va_arg(param, char *));
+ break;
+
+ case CURLOPT_PROXY_SERVICE_NAME:
+ /*
+ * Set negotiate proxy service name
+ */
+ result = setstropt(&data->set.str[STRING_PROXY_SERVICE_NAME],
+ va_arg(param, char *));
+ break;
+
+ case CURLOPT_SOCKS5_GSSAPI_NEC:
+ /*
+ * set flag for nec socks5 support
+ */
+ data->set.socks5_gssapi_nec = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+
+ case CURLOPT_SERVICE_NAME:
+ /*
+ * Set negotiate service identity
+ */
+ result = setstropt(&data->set.str[STRING_SERVICE_NAME],
+ va_arg(param, char *));
+ break;
+
+#endif
+
+ case CURLOPT_HEADERDATA:
+ /*
+ * Custom pointer to pass the header write callback function
+ */
+ data->set.writeheader = (void *)va_arg(param, void *);
+ break;
+ case CURLOPT_ERRORBUFFER:
+ /*
+ * Error buffer provided by the caller to get the human readable
+ * error string in.
+ */
+ data->set.errorbuffer = va_arg(param, char *);
+ break;
+ case CURLOPT_WRITEDATA:
+ /*
+ * FILE pointer to write to. Or possibly
+ * used as argument to the write callback.
+ */
+ data->set.out = va_arg(param, void *);
+ break;
+ case CURLOPT_FTPPORT:
+ /*
+ * Use FTP PORT, this also specifies which IP address to use
+ */
+ result = setstropt(&data->set.str[STRING_FTPPORT],
+ va_arg(param, char *));
+ data->set.ftp_use_port = (NULL != data->set.str[STRING_FTPPORT]) ?
+ TRUE:FALSE;
+ break;
+
+ case CURLOPT_FTP_USE_EPRT:
+ data->set.ftp_use_eprt = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+
+ case CURLOPT_FTP_USE_EPSV:
+ data->set.ftp_use_epsv = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+
+ case CURLOPT_FTP_USE_PRET:
+ data->set.ftp_use_pret = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+
+ case CURLOPT_FTP_SSL_CCC:
+ data->set.ftp_ccc = (curl_ftpccc)va_arg(param, long);
+ break;
+
+ case CURLOPT_FTP_SKIP_PASV_IP:
+ /*
+ * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the
+ * bypass of the IP address in PASV responses.
+ */
+ data->set.ftp_skip_ip = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+
+ case CURLOPT_READDATA:
+ /*
+ * FILE pointer to read the file to be uploaded from. Or possibly
+ * used as argument to the read callback.
+ */
+ data->set.in = va_arg(param, void *);
+ break;
+ case CURLOPT_INFILESIZE:
+ /*
+ * If known, this should inform curl about the file size of the
+ * to-be-uploaded file.
+ */
+ data->set.filesize = va_arg(param, long);
+ break;
+ case CURLOPT_INFILESIZE_LARGE:
+ /*
+ * If known, this should inform curl about the file size of the
+ * to-be-uploaded file.
+ */
+ data->set.filesize = va_arg(param, curl_off_t);
+ break;
+ case CURLOPT_LOW_SPEED_LIMIT:
+ /*
+ * The low speed limit that if transfers are below this for
+ * CURLOPT_LOW_SPEED_TIME, the transfer is aborted.
+ */
+ data->set.low_speed_limit=va_arg(param, long);
+ break;
+ case CURLOPT_MAX_SEND_SPEED_LARGE:
+ /*
+ * When transfer uploads are faster then CURLOPT_MAX_SEND_SPEED_LARGE
+ * bytes per second the transfer is throttled..
+ */
+ data->set.max_send_speed=va_arg(param, curl_off_t);
+ break;
+ case CURLOPT_MAX_RECV_SPEED_LARGE:
+ /*
+ * When receiving data faster than CURLOPT_MAX_RECV_SPEED_LARGE bytes per
+ * second the transfer is throttled..
+ */
+ data->set.max_recv_speed=va_arg(param, curl_off_t);
+ break;
+ case CURLOPT_LOW_SPEED_TIME:
+ /*
+ * The low speed time that if transfers are below the set
+ * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted.
+ */
+ data->set.low_speed_time=va_arg(param, long);
+ break;
+ case CURLOPT_URL:
+ /*
+ * The URL to fetch.
+ */
+ if(data->change.url_alloc) {
+ /* the already set URL is allocated, free it first! */
+ Curl_safefree(data->change.url);
+ data->change.url_alloc = FALSE;
+ }
+ result = setstropt(&data->set.str[STRING_SET_URL],
+ va_arg(param, char *));
+ data->change.url = data->set.str[STRING_SET_URL];
+ break;
+ case CURLOPT_PORT:
+ /*
+ * The port number to use when getting the URL
+ */
+ data->set.use_port = va_arg(param, long);
+ break;
+ case CURLOPT_TIMEOUT:
+ /*
+ * The maximum time you allow curl to use for a single transfer
+ * operation.
+ */
+ data->set.timeout = va_arg(param, long) * 1000L;
+ break;
+
+ case CURLOPT_TIMEOUT_MS:
+ data->set.timeout = va_arg(param, long);
+ break;
+
+ case CURLOPT_CONNECTTIMEOUT:
+ /*
+ * The maximum time you allow curl to use to connect.
+ */
+ data->set.connecttimeout = va_arg(param, long) * 1000L;
+ break;
+
+ case CURLOPT_CONNECTTIMEOUT_MS:
+ data->set.connecttimeout = va_arg(param, long);
+ break;
+
+ case CURLOPT_ACCEPTTIMEOUT_MS:
+ /*
+ * The maximum time you allow curl to wait for server connect
+ */
+ data->set.accepttimeout = va_arg(param, long);
+ break;
+
+ case CURLOPT_USERPWD:
+ /*
+ * user:password to use in the operation
+ */
+ result = setstropt_userpwd(va_arg(param, char *),
+ &data->set.str[STRING_USERNAME],
+ &data->set.str[STRING_PASSWORD]);
+ break;
+
+ case CURLOPT_USERNAME:
+ /*
+ * authentication user name to use in the operation
+ */
+ result = setstropt(&data->set.str[STRING_USERNAME],
+ va_arg(param, char *));
+ break;
+
+ case CURLOPT_PASSWORD:
+ /*
+ * authentication password to use in the operation
+ */
+ result = setstropt(&data->set.str[STRING_PASSWORD],
+ va_arg(param, char *));
+ break;
+
+ case CURLOPT_LOGIN_OPTIONS:
+ /*
+ * authentication options to use in the operation
+ */
+ result = setstropt(&data->set.str[STRING_OPTIONS],
+ va_arg(param, char *));
+ break;
+
+ case CURLOPT_XOAUTH2_BEARER:
+ /*
+ * XOAUTH2 bearer token to use in the operation
+ */
+ result = setstropt(&data->set.str[STRING_BEARER],
+ va_arg(param, char *));
+ break;
+
+ case CURLOPT_POSTQUOTE:
+ /*
+ * List of RAW FTP commands to use after a transfer
+ */
+ data->set.postquote = va_arg(param, struct curl_slist *);
+ break;
+ case CURLOPT_PREQUOTE:
+ /*
+ * List of RAW FTP commands to use prior to RETR (Wesley Laxton)
+ */
+ data->set.prequote = va_arg(param, struct curl_slist *);
+ break;
+ case CURLOPT_QUOTE:
+ /*
+ * List of RAW FTP commands to use before a transfer
+ */
+ data->set.quote = va_arg(param, struct curl_slist *);
+ break;
+ case CURLOPT_RESOLVE:
+ /*
+ * List of NAME:[address] names to populate the DNS cache with
+ * Prefix the NAME with dash (-) to _remove_ the name from the cache.
+ *
+ * Names added with this API will remain in the cache until explicitly
+ * removed or the handle is cleaned up.
+ *
+ * This API can remove any name from the DNS cache, but only entries
+ * that aren't actually in use right now will be pruned immediately.
+ */
+ data->set.resolve = va_arg(param, struct curl_slist *);
+ data->change.resolve = data->set.resolve;
+ break;
+ case CURLOPT_PROGRESSFUNCTION:
+ /*
+ * Progress callback function
+ */
+ data->set.fprogress = va_arg(param, curl_progress_callback);
+ if(data->set.fprogress)
+ data->progress.callback = TRUE; /* no longer internal */
+ else
+ data->progress.callback = FALSE; /* NULL enforces internal */
+ break;
+
+ case CURLOPT_XFERINFOFUNCTION:
+ /*
+ * Transfer info callback function
+ */
+ data->set.fxferinfo = va_arg(param, curl_xferinfo_callback);
+ if(data->set.fxferinfo)
+ data->progress.callback = TRUE; /* no longer internal */
+ else
+ data->progress.callback = FALSE; /* NULL enforces internal */
+
+ break;
+
+ case CURLOPT_PROGRESSDATA:
+ /*
+ * Custom client data to pass to the progress callback
+ */
+ data->set.progress_client = va_arg(param, void *);
+ break;
+
+#ifndef CURL_DISABLE_PROXY
+ case CURLOPT_PROXYUSERPWD:
+ /*
+ * user:password needed to use the proxy
+ */
+ result = setstropt_userpwd(va_arg(param, char *),
+ &data->set.str[STRING_PROXYUSERNAME],
+ &data->set.str[STRING_PROXYPASSWORD]);
+ break;
+ case CURLOPT_PROXYUSERNAME:
+ /*
+ * authentication user name to use in the operation
+ */
+ result = setstropt(&data->set.str[STRING_PROXYUSERNAME],
+ va_arg(param, char *));
+ break;
+ case CURLOPT_PROXYPASSWORD:
+ /*
+ * authentication password to use in the operation
+ */
+ result = setstropt(&data->set.str[STRING_PROXYPASSWORD],
+ va_arg(param, char *));
+ break;
+ case CURLOPT_NOPROXY:
+ /*
+ * proxy exception list
+ */
+ result = setstropt(&data->set.str[STRING_NOPROXY],
+ va_arg(param, char *));
+ break;
+#endif
+
+ case CURLOPT_RANGE:
+ /*
+ * What range of the file you want to transfer
+ */
+ result = setstropt(&data->set.str[STRING_SET_RANGE],
+ va_arg(param, char *));
+ break;
+ case CURLOPT_RESUME_FROM:
+ /*
+ * Resume transfer at the give file position
+ */
+ data->set.set_resume_from = va_arg(param, long);
+ break;
+ case CURLOPT_RESUME_FROM_LARGE:
+ /*
+ * Resume transfer at the give file position
+ */
+ data->set.set_resume_from = va_arg(param, curl_off_t);
+ break;
+ case CURLOPT_DEBUGFUNCTION:
+ /*
+ * stderr write callback.
+ */
+ data->set.fdebug = va_arg(param, curl_debug_callback);
+ /*
+ * if the callback provided is NULL, it'll use the default callback
+ */
+ break;
+ case CURLOPT_DEBUGDATA:
+ /*
+ * Set to a void * that should receive all error writes. This
+ * defaults to CURLOPT_STDERR for normal operations.
+ */
+ data->set.debugdata = va_arg(param, void *);
+ break;
+ case CURLOPT_STDERR:
+ /*
+ * Set to a FILE * that should receive all error writes. This
+ * defaults to stderr for normal operations.
+ */
+ data->set.err = va_arg(param, FILE *);
+ if(!data->set.err)
+ data->set.err = stderr;
+ break;
+ case CURLOPT_HEADERFUNCTION:
+ /*
+ * Set header write callback
+ */
+ data->set.fwrite_header = va_arg(param, curl_write_callback);
+ break;
+ case CURLOPT_WRITEFUNCTION:
+ /*
+ * Set data write callback
+ */
+ data->set.fwrite_func = va_arg(param, curl_write_callback);
+ if(!data->set.fwrite_func) {
+ data->set.is_fwrite_set = 0;
+ /* When set to NULL, reset to our internal default function */
+ data->set.fwrite_func = (curl_write_callback)fwrite;
+ }
+ else
+ data->set.is_fwrite_set = 1;
+ break;
+ case CURLOPT_READFUNCTION:
+ /*
+ * Read data callback
+ */
+ data->set.fread_func = va_arg(param, curl_read_callback);
+ if(!data->set.fread_func) {
+ data->set.is_fread_set = 0;
+ /* When set to NULL, reset to our internal default function */
+ data->set.fread_func = (curl_read_callback)fread;
+ }
+ else
+ data->set.is_fread_set = 1;
+ break;
+ case CURLOPT_SEEKFUNCTION:
+ /*
+ * Seek callback. Might be NULL.
+ */
+ data->set.seek_func = va_arg(param, curl_seek_callback);
+ break;
+ case CURLOPT_SEEKDATA:
+ /*
+ * Seek control callback. Might be NULL.
+ */
+ data->set.seek_client = va_arg(param, void *);
+ break;
+ case CURLOPT_CONV_FROM_NETWORK_FUNCTION:
+ /*
+ * "Convert from network encoding" callback
+ */
+ data->set.convfromnetwork = va_arg(param, curl_conv_callback);
+ break;
+ case CURLOPT_CONV_TO_NETWORK_FUNCTION:
+ /*
+ * "Convert to network encoding" callback
+ */
+ data->set.convtonetwork = va_arg(param, curl_conv_callback);
+ break;
+ case CURLOPT_CONV_FROM_UTF8_FUNCTION:
+ /*
+ * "Convert from UTF-8 encoding" callback
+ */
+ data->set.convfromutf8 = va_arg(param, curl_conv_callback);
+ break;
+ case CURLOPT_IOCTLFUNCTION:
+ /*
+ * I/O control callback. Might be NULL.
+ */
+ data->set.ioctl_func = va_arg(param, curl_ioctl_callback);
+ break;
+ case CURLOPT_IOCTLDATA:
+ /*
+ * I/O control data pointer. Might be NULL.
+ */
+ data->set.ioctl_client = va_arg(param, void *);
+ break;
+ case CURLOPT_SSLCERT:
+ /*
+ * String that holds file name of the SSL certificate to use
+ */
+ result = setstropt(&data->set.str[STRING_CERT],
+ va_arg(param, char *));
+ break;
+ case CURLOPT_SSLCERTTYPE:
+ /*
+ * String that holds file type of the SSL certificate to use
+ */
+ result = setstropt(&data->set.str[STRING_CERT_TYPE],
+ va_arg(param, char *));
+ break;
+ case CURLOPT_SSLKEY:
+ /*
+ * String that holds file name of the SSL key to use
+ */
+ result = setstropt(&data->set.str[STRING_KEY],
+ va_arg(param, char *));
+ break;
+ case CURLOPT_SSLKEYTYPE:
+ /*
+ * String that holds file type of the SSL key to use
+ */
+ result = setstropt(&data->set.str[STRING_KEY_TYPE],
+ va_arg(param, char *));
+ break;
+ case CURLOPT_KEYPASSWD:
+ /*
+ * String that holds the SSL or SSH private key password.
+ */
+ result = setstropt(&data->set.str[STRING_KEY_PASSWD],
+ va_arg(param, char *));
+ break;
+ case CURLOPT_SSLENGINE:
+ /*
+ * String that holds the SSL crypto engine.
+ */
+ argptr = va_arg(param, char *);
+ if(argptr && argptr[0])
+ result = Curl_ssl_set_engine(data, argptr);
+ break;
+
+ case CURLOPT_SSLENGINE_DEFAULT:
+ /*
+ * flag to set engine as default.
+ */
+ result = Curl_ssl_set_engine_default(data);
+ break;
+ case CURLOPT_CRLF:
+ /*
+ * Kludgy option to enable CRLF conversions. Subject for removal.
+ */
+ data->set.crlf = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+
+ case CURLOPT_INTERFACE:
+ /*
+ * Set what interface or address/hostname to bind the socket to when
+ * performing an operation and thus what from-IP your connection will use.
+ */
+ result = setstropt(&data->set.str[STRING_DEVICE],
+ va_arg(param, char *));
+ break;
+ case CURLOPT_LOCALPORT:
+ /*
+ * Set what local port to bind the socket to when performing an operation.
+ */
+ data->set.localport = curlx_sltous(va_arg(param, long));
+ break;
+ case CURLOPT_LOCALPORTRANGE:
+ /*
+ * Set number of local ports to try, starting with CURLOPT_LOCALPORT.
+ */
+ data->set.localportrange = curlx_sltosi(va_arg(param, long));
+ break;
+ case CURLOPT_KRBLEVEL:
+ /*
+ * A string that defines the kerberos security level.
+ */
+ result = setstropt(&data->set.str[STRING_KRB_LEVEL],
+ va_arg(param, char *));
+ data->set.krb = (NULL != data->set.str[STRING_KRB_LEVEL])?TRUE:FALSE;
+ break;
+ case CURLOPT_GSSAPI_DELEGATION:
+ /*
+ * GSS-API credential delegation
+ */
+ data->set.gssapi_delegation = va_arg(param, long);
+ break;
+ case CURLOPT_SSL_VERIFYPEER:
+ /*
+ * Enable peer SSL verifying.
+ */
+ data->set.ssl.verifypeer = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+ case CURLOPT_SSL_VERIFYHOST:
+ /*
+ * Enable verification of the host name in the peer certificate
+ */
+ arg = va_arg(param, long);
+
+ /* Obviously people are not reading documentation and too many thought
+ this argument took a boolean when it wasn't and misused it. We thus ban
+ 1 as a sensible input and we warn about its use. Then we only have the
+ 2 action internally stored as TRUE. */
+
+ if(1 == arg) {
+ failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!");
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+
+ data->set.ssl.verifyhost = (0 != arg)?TRUE:FALSE;
+ break;
+ case CURLOPT_SSL_VERIFYSTATUS:
+ /*
+ * Enable certificate status verifying.
+ */
+ if(!Curl_ssl_cert_status_request()) {
+ result = CURLE_NOT_BUILT_IN;
+ break;
+ }
+
+ data->set.ssl.verifystatus = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+ case CURLOPT_SSL_CTX_FUNCTION:
+#ifdef have_curlssl_ssl_ctx
+ /*
+ * Set a SSL_CTX callback
+ */
+ data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
+#else
+ result = CURLE_NOT_BUILT_IN;
+#endif
+ break;
+ case CURLOPT_SSL_CTX_DATA:
+#ifdef have_curlssl_ssl_ctx
+ /*
+ * Set a SSL_CTX callback parameter pointer
+ */
+ data->set.ssl.fsslctxp = va_arg(param, void *);
+#else
+ result = CURLE_NOT_BUILT_IN;
+#endif
+ break;
+ case CURLOPT_SSL_FALSESTART:
+ /*
+ * Enable TLS false start.
+ */
+ if(!Curl_ssl_false_start()) {
+ result = CURLE_NOT_BUILT_IN;
+ break;
+ }
+
+ data->set.ssl.falsestart = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+ case CURLOPT_CERTINFO:
+#ifdef have_curlssl_certinfo
+ data->set.ssl.certinfo = (0 != va_arg(param, long))?TRUE:FALSE;
+#else
+ result = CURLE_NOT_BUILT_IN;
+#endif
+ break;
+ case CURLOPT_PINNEDPUBLICKEY:
+ /*
+ * Set pinned public key for SSL connection.
+ * Specify file name of the public key in DER format.
+ */
+ result = setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY],
+ va_arg(param, char *));
+ break;
+ case CURLOPT_CAINFO:
+ /*
+ * Set CA info for SSL connection. Specify file name of the CA certificate
+ */
+ result = setstropt(&data->set.str[STRING_SSL_CAFILE],
+ va_arg(param, char *));
+ break;
+ case CURLOPT_CAPATH:
+#ifdef have_curlssl_ca_path /* not supported by all backends */
+ /*
+ * Set CA path info for SSL connection. Specify directory name of the CA
+ * certificates which have been prepared using openssl c_rehash utility.
+ */
+ /* This does not work on windows. */
+ result = setstropt(&data->set.str[STRING_SSL_CAPATH],
+ va_arg(param, char *));
+#else
+ result = CURLE_NOT_BUILT_IN;
+#endif
+ break;
+ case CURLOPT_CRLFILE:
+ /*
+ * Set CRL file info for SSL connection. Specify file name of the CRL
+ * to check certificates revocation
+ */
+ result = setstropt(&data->set.str[STRING_SSL_CRLFILE],
+ va_arg(param, char *));
+ break;
+ case CURLOPT_ISSUERCERT:
+ /*
+ * Set Issuer certificate file
+ * to check certificates issuer
+ */
+ result = setstropt(&data->set.str[STRING_SSL_ISSUERCERT],
+ va_arg(param, char *));
+ break;
+ case CURLOPT_TELNETOPTIONS:
+ /*
+ * Set a linked list of telnet options
+ */
+ data->set.telnet_options = va_arg(param, struct curl_slist *);
+ break;
+
+ case CURLOPT_BUFFERSIZE:
+ /*
+ * The application kindly asks for a differently sized receive buffer.
+ * If it seems reasonable, we'll use it.
+ */
+ data->set.buffer_size = va_arg(param, long);
+
+ if((data->set.buffer_size> (BUFSIZE -1 )) ||
+ (data->set.buffer_size < 1))
+ data->set.buffer_size = 0; /* huge internal default */
+
+ break;
+
+ case CURLOPT_NOSIGNAL:
+ /*
+ * The application asks not to set any signal() or alarm() handlers,
+ * even when using a timeout.
+ */
+ data->set.no_signal = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+
+ case CURLOPT_SHARE:
+ {
+ struct Curl_share *set;
+ set = va_arg(param, struct Curl_share *);
+
+ /* disconnect from old share, if any */
+ if(data->share) {
+ Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
+
+ if(data->dns.hostcachetype == HCACHE_SHARED) {
+ data->dns.hostcache = NULL;
+ data->dns.hostcachetype = HCACHE_NONE;
+ }
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
+ if(data->share->cookies == data->cookies)
+ data->cookies = NULL;
+#endif
+
+ if(data->share->sslsession == data->state.session)
+ data->state.session = NULL;
+
+ data->share->dirty--;
+
+ Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
+ data->share = NULL;
+ }
+
+ /* use new share if it set */
+ data->share = set;
+ if(data->share) {
+
+ Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
+
+ data->share->dirty++;
+
+ if(data->share->specifier & (1<< CURL_LOCK_DATA_DNS)) {
+ /* use shared host cache */
+ data->dns.hostcache = &data->share->hostcache;
+ data->dns.hostcachetype = HCACHE_SHARED;
+ }
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
+ if(data->share->cookies) {
+ /* use shared cookie list, first free own one if any */
+ Curl_cookie_cleanup(data->cookies);
+ /* enable cookies since we now use a share that uses cookies! */
+ data->cookies = data->share->cookies;
+ }
+#endif /* CURL_DISABLE_HTTP */
+ if(data->share->sslsession) {
+ data->set.ssl.max_ssl_sessions = data->share->max_ssl_sessions;
+ data->state.session = data->share->sslsession;
+ }
+ Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
+
+ }
+ /* check for host cache not needed,
+ * it will be done by curl_easy_perform */
+ }
+ break;
+
+ case CURLOPT_PRIVATE:
+ /*
+ * Set private data pointer.
+ */
+ data->set.private_data = va_arg(param, void *);
+ break;
+
+ case CURLOPT_MAXFILESIZE:
+ /*
+ * Set the maximum size of a file to download.
+ */
+ data->set.max_filesize = va_arg(param, long);
+ break;
+
+#ifdef USE_SSL
+ case CURLOPT_USE_SSL:
+ /*
+ * Make transfers attempt to use SSL/TLS.
+ */
+ data->set.use_ssl = (curl_usessl)va_arg(param, long);
+ break;
+
+ case CURLOPT_SSL_OPTIONS:
+ arg = va_arg(param, long);
+ data->set.ssl_enable_beast = !!(arg & CURLSSLOPT_ALLOW_BEAST);
+ data->set.ssl_no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
+ break;
+
+#endif
+ case CURLOPT_FTPSSLAUTH:
+ /*
+ * Set a specific auth for FTP-SSL transfers.
+ */
+ data->set.ftpsslauth = (curl_ftpauth)va_arg(param, long);
+ break;
+
+ case CURLOPT_IPRESOLVE:
+ data->set.ipver = va_arg(param, long);
+ break;
+
+ case CURLOPT_MAXFILESIZE_LARGE:
+ /*
+ * Set the maximum size of a file to download.
+ */
+ data->set.max_filesize = va_arg(param, curl_off_t);
+ break;
+
+ case CURLOPT_TCP_NODELAY:
+ /*
+ * Enable or disable TCP_NODELAY, which will disable/enable the Nagle
+ * algorithm
+ */
+ data->set.tcp_nodelay = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+
+ case CURLOPT_FTP_ACCOUNT:
+ result = setstropt(&data->set.str[STRING_FTP_ACCOUNT],
+ va_arg(param, char *));
+ break;
+
+ case CURLOPT_IGNORE_CONTENT_LENGTH:
+ data->set.ignorecl = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+
+ case CURLOPT_CONNECT_ONLY:
+ /*
+ * No data transfer, set up connection and let application use the socket
+ */
+ data->set.connect_only = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+
+ case CURLOPT_FTP_ALTERNATIVE_TO_USER:
+ result = setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER],
+ va_arg(param, char *));
+ break;
+
+ case CURLOPT_SOCKOPTFUNCTION:
+ /*
+ * socket callback function: called after socket() but before connect()
+ */
+ data->set.fsockopt = va_arg(param, curl_sockopt_callback);
+ break;
+
+ case CURLOPT_SOCKOPTDATA:
+ /*
+ * socket callback data pointer. Might be NULL.
+ */
+ data->set.sockopt_client = va_arg(param, void *);
+ break;
+
+ case CURLOPT_OPENSOCKETFUNCTION:
+ /*
+ * open/create socket callback function: called instead of socket(),
+ * before connect()
+ */
+ data->set.fopensocket = va_arg(param, curl_opensocket_callback);
+ break;
+
+ case CURLOPT_OPENSOCKETDATA:
+ /*
+ * socket callback data pointer. Might be NULL.
+ */
+ data->set.opensocket_client = va_arg(param, void *);
+ break;
+
+ case CURLOPT_CLOSESOCKETFUNCTION:
+ /*
+ * close socket callback function: called instead of close()
+ * when shutting down a connection
+ */
+ data->set.fclosesocket = va_arg(param, curl_closesocket_callback);
+ break;
+
+ case CURLOPT_CLOSESOCKETDATA:
+ /*
+ * socket callback data pointer. Might be NULL.
+ */
+ data->set.closesocket_client = va_arg(param, void *);
+ break;
+
+ case CURLOPT_SSL_SESSIONID_CACHE:
+ data->set.ssl.sessionid = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+
+#ifdef USE_LIBSSH2
+ /* we only include SSH options if explicitly built to support SSH */
+ case CURLOPT_SSH_AUTH_TYPES:
+ data->set.ssh_auth_types = va_arg(param, long);
+ break;
+
+ case CURLOPT_SSH_PUBLIC_KEYFILE:
+ /*
+ * Use this file instead of the $HOME/.ssh/id_dsa.pub file
+ */
+ result = setstropt(&data->set.str[STRING_SSH_PUBLIC_KEY],
+ va_arg(param, char *));
+ break;
+
+ case CURLOPT_SSH_PRIVATE_KEYFILE:
+ /*
+ * Use this file instead of the $HOME/.ssh/id_dsa file
+ */
+ result = setstropt(&data->set.str[STRING_SSH_PRIVATE_KEY],
+ va_arg(param, char *));
+ break;
+ case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5:
+ /*
+ * Option to allow for the MD5 of the host public key to be checked
+ * for validation purposes.
+ */
+ result = setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5],
+ va_arg(param, char *));
+ break;
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+ case CURLOPT_SSH_KNOWNHOSTS:
+ /*
+ * Store the file name to read known hosts from.
+ */
+ result = setstropt(&data->set.str[STRING_SSH_KNOWNHOSTS],
+ va_arg(param, char *));
+ break;
+
+ case CURLOPT_SSH_KEYFUNCTION:
+ /* setting to NULL is fine since the ssh.c functions themselves will
+ then rever to use the internal default */
+ data->set.ssh_keyfunc = va_arg(param, curl_sshkeycallback);
+ break;
+
+ case CURLOPT_SSH_KEYDATA:
+ /*
+ * Custom client data to pass to the SSH keyfunc callback
+ */
+ data->set.ssh_keyfunc_userp = va_arg(param, void *);
+ break;
+#endif /* HAVE_LIBSSH2_KNOWNHOST_API */
+
+#endif /* USE_LIBSSH2 */
+
+ case CURLOPT_HTTP_TRANSFER_DECODING:
+ /*
+ * disable libcurl transfer encoding is used
+ */
+ data->set.http_te_skip = (0 == va_arg(param, long))?TRUE:FALSE;
+ break;
+
+ case CURLOPT_HTTP_CONTENT_DECODING:
+ /*
+ * raw data passed to the application when content encoding is used
+ */
+ data->set.http_ce_skip = (0 == va_arg(param, long))?TRUE:FALSE;
+ break;
+
+ case CURLOPT_NEW_FILE_PERMS:
+ /*
+ * Uses these permissions instead of 0644
+ */
+ data->set.new_file_perms = va_arg(param, long);
+ break;
+
+ case CURLOPT_NEW_DIRECTORY_PERMS:
+ /*
+ * Uses these permissions instead of 0755
+ */
+ data->set.new_directory_perms = va_arg(param, long);
+ break;
+
+ case CURLOPT_ADDRESS_SCOPE:
+ /*
+ * We always get longs when passed plain numericals, but for this value we
+ * know that an unsigned int will always hold the value so we blindly
+ * typecast to this type
+ */
+ data->set.scope_id = curlx_sltoui(va_arg(param, long));
+ break;
+
+ case CURLOPT_PROTOCOLS:
+ /* set the bitmask for the protocols that are allowed to be used for the
+ transfer, which thus helps the app which takes URLs from users or other
+ external inputs and want to restrict what protocol(s) to deal
+ with. Defaults to CURLPROTO_ALL. */
+ data->set.allowed_protocols = va_arg(param, long);
+ break;
+
+ case CURLOPT_REDIR_PROTOCOLS:
+ /* set the bitmask for the protocols that libcurl is allowed to follow to,
+ as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
+ to be set in both bitmasks to be allowed to get redirected to. Defaults
+ to all protocols except FILE and SCP. */
+ data->set.redir_protocols = va_arg(param, long);
+ break;
+
+ case CURLOPT_MAIL_FROM:
+ /* Set the SMTP mail originator */
+ result = setstropt(&data->set.str[STRING_MAIL_FROM],
+ va_arg(param, char *));
+ break;
+
+ case CURLOPT_MAIL_AUTH:
+ /* Set the SMTP auth originator */
+ result = setstropt(&data->set.str[STRING_MAIL_AUTH],
+ va_arg(param, char *));
+ break;
+
+ case CURLOPT_MAIL_RCPT:
+ /* Set the list of mail recipients */
+ data->set.mail_rcpt = va_arg(param, struct curl_slist *);
+ break;
+
+ case CURLOPT_SASL_IR:
+ /* Enable/disable SASL initial response */
+ data->set.sasl_ir = (0 != va_arg(param, long)) ? TRUE : FALSE;
+ break;
+
+ case CURLOPT_RTSP_REQUEST:
+ {
+ /*
+ * Set the RTSP request method (OPTIONS, SETUP, PLAY, etc...)
+ * Would this be better if the RTSPREQ_* were just moved into here?
+ */
+ long curl_rtspreq = va_arg(param, long);
+ Curl_RtspReq rtspreq = RTSPREQ_NONE;
+ switch(curl_rtspreq) {
+ case CURL_RTSPREQ_OPTIONS:
+ rtspreq = RTSPREQ_OPTIONS;
+ break;
+
+ case CURL_RTSPREQ_DESCRIBE:
+ rtspreq = RTSPREQ_DESCRIBE;
+ break;
+
+ case CURL_RTSPREQ_ANNOUNCE:
+ rtspreq = RTSPREQ_ANNOUNCE;
+ break;
+
+ case CURL_RTSPREQ_SETUP:
+ rtspreq = RTSPREQ_SETUP;
+ break;
+
+ case CURL_RTSPREQ_PLAY:
+ rtspreq = RTSPREQ_PLAY;
+ break;
+
+ case CURL_RTSPREQ_PAUSE:
+ rtspreq = RTSPREQ_PAUSE;
+ break;
+
+ case CURL_RTSPREQ_TEARDOWN:
+ rtspreq = RTSPREQ_TEARDOWN;
+ break;
+
+ case CURL_RTSPREQ_GET_PARAMETER:
+ rtspreq = RTSPREQ_GET_PARAMETER;
+ break;
+
+ case CURL_RTSPREQ_SET_PARAMETER:
+ rtspreq = RTSPREQ_SET_PARAMETER;
+ break;
+
+ case CURL_RTSPREQ_RECORD:
+ rtspreq = RTSPREQ_RECORD;
+ break;
+
+ case CURL_RTSPREQ_RECEIVE:
+ rtspreq = RTSPREQ_RECEIVE;
+ break;
+ default:
+ rtspreq = RTSPREQ_NONE;
+ }
+
+ data->set.rtspreq = rtspreq;
+ break;
+ }
+
+
+ case CURLOPT_RTSP_SESSION_ID:
+ /*
+ * Set the RTSP Session ID manually. Useful if the application is
+ * resuming a previously established RTSP session
+ */
+ result = setstropt(&data->set.str[STRING_RTSP_SESSION_ID],
+ va_arg(param, char *));
+ break;
+
+ case CURLOPT_RTSP_STREAM_URI:
+ /*
+ * Set the Stream URI for the RTSP request. Unless the request is
+ * for generic server options, the application will need to set this.
+ */
+ result = setstropt(&data->set.str[STRING_RTSP_STREAM_URI],
+ va_arg(param, char *));
+ break;
+
+ case CURLOPT_RTSP_TRANSPORT:
+ /*
+ * The content of the Transport: header for the RTSP request
+ */
+ result = setstropt(&data->set.str[STRING_RTSP_TRANSPORT],
+ va_arg(param, char *));
+ break;
+
+ case CURLOPT_RTSP_CLIENT_CSEQ:
+ /*
+ * Set the CSEQ number to issue for the next RTSP request. Useful if the
+ * application is resuming a previously broken connection. The CSEQ
+ * will increment from this new number henceforth.
+ */
+ data->state.rtsp_next_client_CSeq = va_arg(param, long);
+ break;
+
+ case CURLOPT_RTSP_SERVER_CSEQ:
+ /* Same as the above, but for server-initiated requests */
+ data->state.rtsp_next_client_CSeq = va_arg(param, long);
+ break;
+
+ case CURLOPT_INTERLEAVEDATA:
+ data->set.rtp_out = va_arg(param, void *);
+ break;
+ case CURLOPT_INTERLEAVEFUNCTION:
+ /* Set the user defined RTP write function */
+ data->set.fwrite_rtp = va_arg(param, curl_write_callback);
+ break;
+
+ case CURLOPT_WILDCARDMATCH:
+ data->set.wildcardmatch = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+ case CURLOPT_CHUNK_BGN_FUNCTION:
+ data->set.chunk_bgn = va_arg(param, curl_chunk_bgn_callback);
+ break;
+ case CURLOPT_CHUNK_END_FUNCTION:
+ data->set.chunk_end = va_arg(param, curl_chunk_end_callback);
+ break;
+ case CURLOPT_FNMATCH_FUNCTION:
+ data->set.fnmatch = va_arg(param, curl_fnmatch_callback);
+ break;
+ case CURLOPT_CHUNK_DATA:
+ data->wildcard.customptr = va_arg(param, void *);
+ break;
+ case CURLOPT_FNMATCH_DATA:
+ data->set.fnmatch_data = va_arg(param, void *);
+ break;
+#ifdef USE_TLS_SRP
+ case CURLOPT_TLSAUTH_USERNAME:
+ result = setstropt(&data->set.str[STRING_TLSAUTH_USERNAME],
+ va_arg(param, char *));
+ if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
+ data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
+ break;
+ case CURLOPT_TLSAUTH_PASSWORD:
+ result = setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD],
+ va_arg(param, char *));
+ if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
+ data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
+ break;
+ case CURLOPT_TLSAUTH_TYPE:
+ if(strnequal((char *)va_arg(param, char *), "SRP", strlen("SRP")))
+ data->set.ssl.authtype = CURL_TLSAUTH_SRP;
+ else
+ data->set.ssl.authtype = CURL_TLSAUTH_NONE;
+ break;
+#endif
+ case CURLOPT_DNS_SERVERS:
+ result = Curl_set_dns_servers(data, va_arg(param, char *));
+ break;
+ case CURLOPT_DNS_INTERFACE:
+ result = Curl_set_dns_interface(data, va_arg(param, char *));
+ break;
+ case CURLOPT_DNS_LOCAL_IP4:
+ result = Curl_set_dns_local_ip4(data, va_arg(param, char *));
+ break;
+ case CURLOPT_DNS_LOCAL_IP6:
+ result = Curl_set_dns_local_ip6(data, va_arg(param, char *));
+ break;
+
+ case CURLOPT_TCP_KEEPALIVE:
+ data->set.tcp_keepalive = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+ case CURLOPT_TCP_KEEPIDLE:
+ data->set.tcp_keepidle = va_arg(param, long);
+ break;
+ case CURLOPT_TCP_KEEPINTVL:
+ data->set.tcp_keepintvl = va_arg(param, long);
+ break;
+ case CURLOPT_SSL_ENABLE_NPN:
+ data->set.ssl_enable_npn = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+ case CURLOPT_SSL_ENABLE_ALPN:
+ data->set.ssl_enable_alpn = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+
+#ifdef USE_UNIX_SOCKETS
+ case CURLOPT_UNIX_SOCKET_PATH:
+ result = setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH],
+ va_arg(param, char *));
+ break;
+#endif
+
+ case CURLOPT_PATH_AS_IS:
+ data->set.path_as_is = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+ case CURLOPT_PIPEWAIT:
+ data->set.pipewait = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
+ default:
+ /* unknown tag and its companion, just ignore: */
+ result = CURLE_UNKNOWN_OPTION;
+ break;
+ }
+
+ return result;
+}
+
+static void conn_free(struct connectdata *conn)
+{
+ if(!conn)
+ return;
+
+ /* possible left-overs from the async name resolvers */
+ Curl_resolver_cancel(conn);
+
+ /* close the SSL stuff before we close any sockets since they will/may
+ write to the sockets */
+ Curl_ssl_close(conn, FIRSTSOCKET);
+ Curl_ssl_close(conn, SECONDARYSOCKET);
+
+ /* close possibly still open sockets */
+ if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
+ Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
+ if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
+ Curl_closesocket(conn, conn->sock[FIRSTSOCKET]);
+ if(CURL_SOCKET_BAD != conn->tempsock[0])
+ Curl_closesocket(conn, conn->tempsock[0]);
+ if(CURL_SOCKET_BAD != conn->tempsock[1])
+ Curl_closesocket(conn, conn->tempsock[1]);
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
+ defined(NTLM_WB_ENABLED)
+ Curl_ntlm_wb_cleanup(conn);
+#endif
+
+ Curl_safefree(conn->user);
+ Curl_safefree(conn->passwd);
+ Curl_safefree(conn->xoauth2_bearer);
+ Curl_safefree(conn->options);
+ Curl_safefree(conn->proxyuser);
+ Curl_safefree(conn->proxypasswd);
+ Curl_safefree(conn->allocptr.proxyuserpwd);
+ Curl_safefree(conn->allocptr.uagent);
+ Curl_safefree(conn->allocptr.userpwd);
+ Curl_safefree(conn->allocptr.accept_encoding);
+ Curl_safefree(conn->allocptr.te);
+ Curl_safefree(conn->allocptr.rangeline);
+ Curl_safefree(conn->allocptr.ref);
+ Curl_safefree(conn->allocptr.host);
+ Curl_safefree(conn->allocptr.cookiehost);
+ Curl_safefree(conn->allocptr.rtsp_transport);
+ Curl_safefree(conn->trailer);
+ Curl_safefree(conn->host.rawalloc); /* host name buffer */
+ Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */
+ Curl_safefree(conn->master_buffer);
+
+ Curl_llist_destroy(conn->send_pipe, NULL);
+ Curl_llist_destroy(conn->recv_pipe, NULL);
+
+ conn->send_pipe = NULL;
+ conn->recv_pipe = NULL;
+
+ Curl_safefree(conn->localdev);
+ Curl_free_ssl_config(&conn->ssl_config);
+
+ free(conn); /* free all the connection oriented data */
+}
+
+/*
+ * Disconnects the given connection. Note the connection may not be the
+ * primary connection, like when freeing room in the connection cache or
+ * killing of a dead old connection.
+ *
+ * This function MUST NOT reset state in the SessionHandle struct if that
+ * isn't strictly bound to the life-time of *this* particular connection.
+ *
+ */
+
+CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
+{
+ struct SessionHandle *data;
+ if(!conn)
+ return CURLE_OK; /* this is closed and fine already */
+ data = conn->data;
+
+ if(!data) {
+ DEBUGF(fprintf(stderr, "DISCONNECT without easy handle, ignoring\n"));
+ return CURLE_OK;
+ }
+
+ if(conn->dns_entry != NULL) {
+ Curl_resolv_unlock(data, conn->dns_entry);
+ conn->dns_entry = NULL;
+ }
+
+ Curl_hostcache_prune(data); /* kill old DNS cache entries */
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM)
+ /* Cleanup NTLM connection-related data */
+ Curl_http_ntlm_cleanup(conn);
+#endif
+
+ if(conn->handler->disconnect)
+ /* This is set if protocol-specific cleanups should be made */
+ conn->handler->disconnect(conn, dead_connection);
+
+ /* unlink ourselves! */
+ infof(data, "Closing connection %ld\n", conn->connection_id);
+ Curl_conncache_remove_conn(data->state.conn_cache, conn);
+
+#if defined(USE_LIBIDN)
+ if(conn->host.encalloc)
+ idn_free(conn->host.encalloc); /* encoded host name buffer, must be freed
+ with idn_free() since this was allocated
+ by libidn */
+ if(conn->proxy.encalloc)
+ idn_free(conn->proxy.encalloc); /* encoded proxy name buffer, must be
+ freed with idn_free() since this was
+ allocated by libidn */
+#elif defined(USE_WIN32_IDN)
+ free(conn->host.encalloc); /* encoded host name buffer, must be freed with
+ idn_free() since this was allocated by
+ curl_win32_idn_to_ascii */
+ free(conn->proxy.encalloc); /* encoded proxy name buffer, must be freed
+ with idn_free() since this was allocated by
+ curl_win32_idn_to_ascii */
+#endif
+
+ Curl_ssl_close(conn, FIRSTSOCKET);
+
+ /* Indicate to all handles on the pipe that we're dead */
+ if(Curl_pipeline_wanted(data->multi, CURLPIPE_ANY)) {
+ signalPipeClose(conn->send_pipe, TRUE);
+ signalPipeClose(conn->recv_pipe, TRUE);
+ }
+
+ conn_free(conn);
+
+ return CURLE_OK;
+}
+
+/*
+ * This function should return TRUE if the socket is to be assumed to
+ * be dead. Most commonly this happens when the server has closed the
+ * connection due to inactivity.
+ */
+static bool SocketIsDead(curl_socket_t sock)
+{
+ int sval;
+ bool ret_val = TRUE;
+
+ sval = Curl_socket_ready(sock, CURL_SOCKET_BAD, 0);
+ if(sval == 0)
+ /* timeout */
+ ret_val = FALSE;
+
+ return ret_val;
+}
+
+/*
+ * IsPipeliningPossible() returns TRUE if the options set would allow
+ * pipelining/multiplexing and the connection is using a HTTP protocol.
+ */
+static bool IsPipeliningPossible(const struct SessionHandle *handle,
+ const struct connectdata *conn)
+{
+ /* If a HTTP protocol and pipelining is enabled */
+ if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
+
+ if(Curl_pipeline_wanted(handle->multi, CURLPIPE_HTTP1) &&
+ (handle->set.httpversion != CURL_HTTP_VERSION_1_0) &&
+ (handle->set.httpreq == HTTPREQ_GET ||
+ handle->set.httpreq == HTTPREQ_HEAD))
+ /* didn't ask for HTTP/1.0 and a GET or HEAD */
+ return TRUE;
+
+ if(Curl_pipeline_wanted(handle->multi, CURLPIPE_MULTIPLEX) &&
+ (handle->set.httpversion == CURL_HTTP_VERSION_2_0))
+ /* allows HTTP/2 */
+ return TRUE;
+ }
+ return FALSE;
+}
+
+int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
+ struct curl_llist *pipeline)
+{
+ struct curl_llist_element *curr;
+
+ curr = pipeline->head;
+ while(curr) {
+ if(curr->ptr == handle) {
+ Curl_llist_remove(pipeline, curr, NULL);
+ return 1; /* we removed a handle */
+ }
+ curr = curr->next;
+ }
+
+ return 0;
+}
+
+#if 0 /* this code is saved here as it is useful for debugging purposes */
+static void Curl_printPipeline(struct curl_llist *pipeline)
+{
+ struct curl_llist_element *curr;
+
+ curr = pipeline->head;
+ while(curr) {
+ struct SessionHandle *data = (struct SessionHandle *) curr->ptr;
+ infof(data, "Handle in pipeline: %s\n", data->state.path);
+ curr = curr->next;
+ }
+}
+#endif
+
+static struct SessionHandle* gethandleathead(struct curl_llist *pipeline)
+{
+ struct curl_llist_element *curr = pipeline->head;
+ if(curr) {
+ return (struct SessionHandle *) curr->ptr;
+ }
+
+ return NULL;
+}
+
+/* remove the specified connection from all (possible) pipelines and related
+ queues */
+void Curl_getoff_all_pipelines(struct SessionHandle *data,
+ struct connectdata *conn)
+{
+ bool recv_head = (conn->readchannel_inuse &&
+ Curl_recvpipe_head(data, conn));
+ bool send_head = (conn->writechannel_inuse &&
+ Curl_sendpipe_head(data, conn));
+
+ if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && recv_head)
+ Curl_pipeline_leave_read(conn);
+ if(Curl_removeHandleFromPipeline(data, conn->send_pipe) && send_head)
+ Curl_pipeline_leave_write(conn);
+}
+
+static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke)
+{
+ struct curl_llist_element *curr;
+
+ if(!pipeline)
+ return;
+
+ curr = pipeline->head;
+ while(curr) {
+ struct curl_llist_element *next = curr->next;
+ struct SessionHandle *data = (struct SessionHandle *) curr->ptr;
+
+#ifdef DEBUGBUILD /* debug-only code */
+ if(data->magic != CURLEASY_MAGIC_NUMBER) {
+ /* MAJOR BADNESS */
+ infof(data, "signalPipeClose() found BAAD easy handle\n");
+ }
+#endif
+
+ if(pipe_broke)
+ data->state.pipe_broke = TRUE;
+ Curl_multi_handlePipeBreak(data);
+ Curl_llist_remove(pipeline, curr, NULL);
+ curr = next;
+ }
+}
+
+/*
+ * This function finds the connection in the connection
+ * cache that has been unused for the longest time.
+ *
+ * Returns the pointer to the oldest idle connection, or NULL if none was
+ * found.
+ */
+static struct connectdata *
+find_oldest_idle_connection(struct SessionHandle *data)
+{
+ struct conncache *bc = data->state.conn_cache;
+ struct curl_hash_iterator iter;
+ struct curl_llist_element *curr;
+ struct curl_hash_element *he;
+ long highscore=-1;
+ long score;
+ struct timeval now;
+ struct connectdata *conn_candidate = NULL;
+ struct connectbundle *bundle;
+
+ now = Curl_tvnow();
+
+ Curl_hash_start_iterate(&bc->hash, &iter);
+
+ he = Curl_hash_next_element(&iter);
+ while(he) {
+ struct connectdata *conn;
+
+ bundle = he->ptr;
+
+ curr = bundle->conn_list->head;
+ while(curr) {
+ conn = curr->ptr;
+
+ if(!conn->inuse) {
+ /* Set higher score for the age passed since the connection was used */
+ score = Curl_tvdiff(now, conn->now);
+
+ if(score > highscore) {
+ highscore = score;
+ conn_candidate = conn;
+ }
+ }
+ curr = curr->next;
+ }
+
+ he = Curl_hash_next_element(&iter);
+ }
+
+ return conn_candidate;
+}
+
+/*
+ * This function finds the connection in the connection
+ * bundle that has been unused for the longest time.
+ *
+ * Returns the pointer to the oldest idle connection, or NULL if none was
+ * found.
+ */
+static struct connectdata *
+find_oldest_idle_connection_in_bundle(struct SessionHandle *data,
+ struct connectbundle *bundle)
+{
+ struct curl_llist_element *curr;
+ long highscore=-1;
+ long score;
+ struct timeval now;
+ struct connectdata *conn_candidate = NULL;
+ struct connectdata *conn;
+
+ (void)data;
+
+ now = Curl_tvnow();
+
+ curr = bundle->conn_list->head;
+ while(curr) {
+ conn = curr->ptr;
+
+ if(!conn->inuse) {
+ /* Set higher score for the age passed since the connection was used */
+ score = Curl_tvdiff(now, conn->now);
+
+ if(score > highscore) {
+ highscore = score;
+ conn_candidate = conn;
+ }
+ }
+ curr = curr->next;
+ }
+
+ return conn_candidate;
+}
+
+/*
+ * This function checks if given connection is dead and disconnects if so.
+ * (That also removes it from the connection cache.)
+ *
+ * Returns TRUE if the connection actually was dead and disconnected.
+ */
+static bool disconnect_if_dead(struct connectdata *conn,
+ struct SessionHandle *data)
+{
+ size_t pipeLen = conn->send_pipe->size + conn->recv_pipe->size;
+ if(!pipeLen && !conn->inuse) {
+ /* The check for a dead socket makes sense only if there are no
+ handles in pipeline and the connection isn't already marked in
+ use */
+ bool dead;
+ if(conn->handler->protocol & CURLPROTO_RTSP)
+ /* RTSP is a special case due to RTP interleaving */
+ dead = Curl_rtsp_connisdead(conn);
+ else
+ dead = SocketIsDead(conn->sock[FIRSTSOCKET]);
+
+ if(dead) {
+ conn->data = data;
+ infof(data, "Connection %ld seems to be dead!\n", conn->connection_id);
+
+ /* disconnect resources */
+ Curl_disconnect(conn, /* dead_connection */TRUE);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*
+ * Wrapper to use disconnect_if_dead() function in Curl_conncache_foreach()
+ *
+ * Returns always 0.
+ */
+static int call_disconnect_if_dead(struct connectdata *conn,
+ void *param)
+{
+ struct SessionHandle* data = (struct SessionHandle*)param;
+ disconnect_if_dead(conn, data);
+ return 0; /* continue iteration */
+}
+
+/*
+ * This function scans the connection cache for half-open/dead connections,
+ * closes and removes them.
+ * The cleanup is done at most once per second.
+ */
+static void prune_dead_connections(struct SessionHandle *data)
+{
+ struct timeval now = Curl_tvnow();
+ long elapsed = Curl_tvdiff(now, data->state.conn_cache->last_cleanup);
+
+ if(elapsed >= 1000L) {
+ Curl_conncache_foreach(data->state.conn_cache, data,
+ call_disconnect_if_dead);
+ data->state.conn_cache->last_cleanup = now;
+ }
+}
+
+
+static size_t max_pipeline_length(struct Curl_multi *multi)
+{
+ return multi ? multi->max_pipeline_length : 0;
+}
+
+
+/*
+ * Given one filled in connection struct (named needle), this function should
+ * detect if there already is one that has all the significant details
+ * exactly the same and thus should be used instead.
+ *
+ * If there is a match, this function returns TRUE - and has marked the
+ * connection as 'in-use'. It must later be called with ConnectionDone() to
+ * return back to 'idle' (unused) state.
+ *
+ * The force_reuse flag is set if the connection must be used, even if
+ * the pipelining strategy wants to open a new connection instead of reusing.
+ */
+static bool
+ConnectionExists(struct SessionHandle *data,
+ struct connectdata *needle,
+ struct connectdata **usethis,
+ bool *force_reuse,
+ bool *waitpipe)
+{
+ struct connectdata *check;
+ struct connectdata *chosen = 0;
+ bool canPipeline = IsPipeliningPossible(data, needle);
+#ifdef USE_NTLM
+ bool wantNTLMhttp = ((data->state.authhost.want & CURLAUTH_NTLM) ||
+ (data->state.authhost.want & CURLAUTH_NTLM_WB)) &&
+ (needle->handler->protocol & PROTO_FAMILY_HTTP) ? TRUE : FALSE;
+#endif
+ struct connectbundle *bundle;
+
+ *force_reuse = FALSE;
+ *waitpipe = FALSE;
+
+ /* We can't pipe if the site is blacklisted */
+ if(canPipeline && Curl_pipeline_site_blacklisted(data, needle)) {
+ canPipeline = FALSE;
+ }
+
+ /* Look up the bundle with all the connections to this
+ particular host */
+ bundle = Curl_conncache_find_bundle(needle, data->state.conn_cache);
+ if(bundle) {
+ /* Max pipe length is zero (unlimited) for multiplexed connections */
+ size_t max_pipe_len = (bundle->multiuse != BUNDLE_MULTIPLEX)?
+ max_pipeline_length(data->multi):0;
+ size_t best_pipe_len = max_pipe_len;
+ struct curl_llist_element *curr;
+
+ infof(data, "Found bundle for host %s: %p\n",
+ needle->host.name, (void *)bundle);
+
+ /* We can't pipe if we don't know anything about the server */
+ if(canPipeline) {
+ if(bundle->multiuse <= BUNDLE_UNKNOWN) {
+ if((bundle->multiuse == BUNDLE_UNKNOWN) && data->set.pipewait) {
+ infof(data, "Server doesn't support multi-use yet, wait\n");
+ *waitpipe = TRUE;
+ return FALSE; /* no re-use */
+ }
+
+ infof(data, "Server doesn't support multi-use (yet)\n");
+ canPipeline = FALSE;
+ }
+ }
+
+ curr = bundle->conn_list->head;
+ while(curr) {
+ bool match = FALSE;
+#if defined(USE_NTLM)
+ bool credentialsMatch = FALSE;
+#endif
+ size_t pipeLen;
+
+ /*
+ * Note that if we use a HTTP proxy, we check connections to that
+ * proxy and not to the actual remote server.
+ */
+ check = curr->ptr;
+ curr = curr->next;
+
+ if(disconnect_if_dead(check, data))
+ continue;
+
+ pipeLen = check->send_pipe->size + check->recv_pipe->size;
+
+ if(canPipeline) {
+
+ if(!check->bits.multiplex) {
+ /* If not multiplexing, make sure the pipe has only GET requests */
+ struct SessionHandle* sh = gethandleathead(check->send_pipe);
+ struct SessionHandle* rh = gethandleathead(check->recv_pipe);
+ if(sh) {
+ if(!IsPipeliningPossible(sh, check))
+ continue;
+ }
+ else if(rh) {
+ if(!IsPipeliningPossible(rh, check))
+ continue;
+ }
+ }
+ }
+ else {
+ if(pipeLen > 0) {
+ /* can only happen within multi handles, and means that another easy
+ handle is using this connection */
+ continue;
+ }
+
+ if(Curl_resolver_asynch()) {
+ /* ip_addr_str[0] is NUL only if the resolving of the name hasn't
+ completed yet and until then we don't re-use this connection */
+ if(!check->ip_addr_str[0]) {
+ infof(data,
+ "Connection #%ld is still name resolving, can't reuse\n",
+ check->connection_id);
+ continue;
+ }
+ }
+
+ if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) ||
+ check->bits.close) {
+ /* Don't pick a connection that hasn't connected yet or that is going
+ to get closed. */
+ infof(data, "Connection #%ld isn't open enough, can't reuse\n",
+ check->connection_id);
+#ifdef DEBUGBUILD
+ if(check->recv_pipe->size > 0) {
+ infof(data,
+ "BAD! Unconnected #%ld has a non-empty recv pipeline!\n",
+ check->connection_id);
+ }
+#endif
+ continue;
+ }
+ }
+
+ if((needle->handler->flags&PROTOPT_SSL) !=
+ (check->handler->flags&PROTOPT_SSL))
+ /* don't do mixed SSL and non-SSL connections */
+ if(!(needle->handler->protocol & check->handler->protocol))
+ /* except protocols that have been upgraded via TLS */
+ continue;
+
+ if(needle->handler->flags&PROTOPT_SSL) {
+ if((data->set.ssl.verifypeer != check->verifypeer) ||
+ (data->set.ssl.verifyhost != check->verifyhost))
+ continue;
+ }
+
+ if(needle->bits.proxy != check->bits.proxy)
+ /* don't do mixed proxy and non-proxy connections */
+ continue;
+
+ if(!canPipeline && check->inuse)
+ /* this request can't be pipelined but the checked connection is
+ already in use so we skip it */
+ continue;
+
+ if(needle->localdev || needle->localport) {
+ /* If we are bound to a specific local end (IP+port), we must not
+ re-use a random other one, although if we didn't ask for a
+ particular one we can reuse one that was bound.
+
+ This comparison is a bit rough and too strict. Since the input
+ parameters can be specified in numerous ways and still end up the
+ same it would take a lot of processing to make it really accurate.
+ Instead, this matching will assume that re-uses of bound connections
+ will most likely also re-use the exact same binding parameters and
+ missing out a few edge cases shouldn't hurt anyone very much.
+ */
+ if((check->localport != needle->localport) ||
+ (check->localportrange != needle->localportrange) ||
+ !check->localdev ||
+ !needle->localdev ||
+ strcmp(check->localdev, needle->localdev))
+ continue;
+ }
+
+ if((!(needle->handler->flags & PROTOPT_CREDSPERREQUEST))
+#ifdef USE_NTLM
+ || (wantNTLMhttp || check->ntlm.state != NTLMSTATE_NONE)
+#endif
+ ) {
+ /* This protocol requires credentials per connection or is HTTP+NTLM,
+ so verify that we're using the same name and password as well */
+ if(!strequal(needle->user, check->user) ||
+ !strequal(needle->passwd, check->passwd)) {
+ /* one of them was different */
+ continue;
+ }
+#if defined(USE_NTLM)
+ credentialsMatch = TRUE;
+#endif
+ }
+
+ if(!needle->bits.httpproxy || needle->handler->flags&PROTOPT_SSL ||
+ (needle->bits.httpproxy && check->bits.httpproxy &&
+ needle->bits.tunnel_proxy && check->bits.tunnel_proxy &&
+ Curl_raw_equal(needle->proxy.name, check->proxy.name) &&
+ (needle->port == check->port))) {
+ /* The requested connection does not use a HTTP proxy or it uses SSL or
+ it is a non-SSL protocol tunneled over the same http proxy name and
+ port number or it is a non-SSL protocol which is allowed to be
+ upgraded via TLS */
+
+ if((Curl_raw_equal(needle->handler->scheme, check->handler->scheme) ||
+ needle->handler->protocol & check->handler->protocol) &&
+ Curl_raw_equal(needle->host.name, check->host.name) &&
+ needle->remote_port == check->remote_port) {
+ if(needle->handler->flags & PROTOPT_SSL) {
+ /* This is a SSL connection so verify that we're using the same
+ SSL options as well */
+ if(!Curl_ssl_config_matches(&needle->ssl_config,
+ &check->ssl_config)) {
+ DEBUGF(infof(data,
+ "Connection #%ld has different SSL parameters, "
+ "can't reuse\n",
+ check->connection_id));
+ continue;
+ }
+ else if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete) {
+ DEBUGF(infof(data,
+ "Connection #%ld has not started SSL connect, "
+ "can't reuse\n",
+ check->connection_id));
+ continue;
+ }
+ }
+ match = TRUE;
+ }
+ }
+ else { /* The requested needle connection is using a proxy,
+ is the checked one using the same host, port and type? */
+ if(check->bits.proxy &&
+ (needle->proxytype == check->proxytype) &&
+ (needle->bits.tunnel_proxy == check->bits.tunnel_proxy) &&
+ Curl_raw_equal(needle->proxy.name, check->proxy.name) &&
+ needle->port == check->port) {
+ /* This is the same proxy connection, use it! */
+ match = TRUE;
+ }
+ }
+
+ if(match) {
+#if defined(USE_NTLM)
+ /* If we are looking for an HTTP+NTLM connection, check if this is
+ already authenticating with the right credentials. If not, keep
+ looking so that we can reuse NTLM connections if
+ possible. (Especially we must not reuse the same connection if
+ partway through a handshake!) */
+ if(wantNTLMhttp) {
+ if(credentialsMatch && check->ntlm.state != NTLMSTATE_NONE) {
+ chosen = check;
+
+ /* We must use this connection, no other */
+ *force_reuse = TRUE;
+ break;
+ }
+ else if(credentialsMatch)
+ /* this is a backup choice */
+ chosen = check;
+ continue;
+ }
+#endif
+
+ if(canPipeline) {
+ /* We can pipeline if we want to. Let's continue looking for
+ the optimal connection to use, i.e the shortest pipe that is not
+ blacklisted. */
+
+ if(pipeLen == 0) {
+ /* We have the optimal connection. Let's stop looking. */
+ chosen = check;
+ break;
+ }
+
+ /* We can't use the connection if the pipe is full */
+ if(max_pipe_len && (pipeLen >= max_pipe_len)) {
+ infof(data, "Pipe is full, skip (%zu)\n", pipeLen);
+ continue;
+ }
+#ifdef USE_NGHTTP2
+ /* If multiplexed, make sure we don't go over concurrency limit */
+ if(check->bits.multiplex) {
+ /* Multiplexed connections can only be HTTP/2 for now */
+ struct http_conn *httpc = &check->proto.httpc;
+ if(pipeLen >= httpc->settings.max_concurrent_streams) {
+ infof(data, "MAX_CONCURRENT_STREAMS reached, skip (%zu)\n",
+ pipeLen);
+ continue;
+ }
+ }
+#endif
+ /* We can't use the connection if the pipe is penalized */
+ if(Curl_pipeline_penalized(data, check)) {
+ infof(data, "Penalized, skip\n");
+ continue;
+ }
+
+ if(max_pipe_len) {
+ if(pipeLen < best_pipe_len) {
+ /* This connection has a shorter pipe so far. We'll pick this
+ and continue searching */
+ chosen = check;
+ best_pipe_len = pipeLen;
+ continue;
+ }
+ }
+ else {
+ /* When not pipelining (== multiplexed), we have a match here! */
+ chosen = check;
+ infof(data, "Multiplexed connection found!\n");
+ break;
+ }
+ }
+ else {
+ /* We have found a connection. Let's stop searching. */
+ chosen = check;
+ break;
+ }
+ }
+ }
+ }
+
+ if(chosen) {
+ *usethis = chosen;
+ return TRUE; /* yes, we found one to use! */
+ }
+
+ return FALSE; /* no matching connecting exists */
+}
+
+/* Mark the connection as 'idle', or close it if the cache is full.
+ Returns TRUE if the connection is kept, or FALSE if it was closed. */
+static bool
+ConnectionDone(struct SessionHandle *data, struct connectdata *conn)
+{
+ /* data->multi->maxconnects can be negative, deal with it. */
+ size_t maxconnects =
+ (data->multi->maxconnects < 0) ? data->multi->num_easy * 4:
+ data->multi->maxconnects;
+ struct connectdata *conn_candidate = NULL;
+
+ /* Mark the current connection as 'unused' */
+ conn->inuse = FALSE;
+
+ if(maxconnects > 0 &&
+ data->state.conn_cache->num_connections > maxconnects) {
+ infof(data, "Connection cache is full, closing the oldest one.\n");
+
+ conn_candidate = find_oldest_idle_connection(data);
+
+ if(conn_candidate) {
+ /* Set the connection's owner correctly */
+ conn_candidate->data = data;
+
+ /* the winner gets the honour of being disconnected */
+ (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
+ }
+ }
+
+ return (conn_candidate == conn) ? FALSE : TRUE;
+}
+
+/* after a TCP connection to the proxy has been verified, this function does
+ the next magic step.
+
+ Note: this function's sub-functions call failf()
+
+*/
+CURLcode Curl_connected_proxy(struct connectdata *conn,
+ int sockindex)
+{
+ if(!conn->bits.proxy || sockindex)
+ /* this magic only works for the primary socket as the secondary is used
+ for FTP only and it has FTP specific magic in ftp.c */
+ return CURLE_OK;
+
+ switch(conn->proxytype) {
+#ifndef CURL_DISABLE_PROXY
+ case CURLPROXY_SOCKS5:
+ case CURLPROXY_SOCKS5_HOSTNAME:
+ return Curl_SOCKS5(conn->proxyuser, conn->proxypasswd,
+ conn->host.name, conn->remote_port,
+ FIRSTSOCKET, conn);
+
+ case CURLPROXY_SOCKS4:
+ return Curl_SOCKS4(conn->proxyuser, conn->host.name,
+ conn->remote_port, FIRSTSOCKET, conn, FALSE);
+
+ case CURLPROXY_SOCKS4A:
+ return Curl_SOCKS4(conn->proxyuser, conn->host.name,
+ conn->remote_port, FIRSTSOCKET, conn, TRUE);
+
+#endif /* CURL_DISABLE_PROXY */
+ case CURLPROXY_HTTP:
+ case CURLPROXY_HTTP_1_0:
+ /* do nothing here. handled later. */
+ break;
+ default:
+ break;
+ } /* switch proxytype */
+
+ return CURLE_OK;
+}
+
+/*
+ * verboseconnect() displays verbose information after a connect
+ */
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+void Curl_verboseconnect(struct connectdata *conn)
+{
+ if(conn->data->set.verbose)
+ infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n",
+ conn->bits.proxy ? conn->proxy.dispname : conn->host.dispname,
+ conn->ip_addr_str, conn->port, conn->connection_id);
+}
+#endif
+
+int Curl_protocol_getsock(struct connectdata *conn,
+ curl_socket_t *socks,
+ int numsocks)
+{
+ if(conn->handler->proto_getsock)
+ return conn->handler->proto_getsock(conn, socks, numsocks);
+ return GETSOCK_BLANK;
+}
+
+int Curl_doing_getsock(struct connectdata *conn,
+ curl_socket_t *socks,
+ int numsocks)
+{
+ if(conn && conn->handler->doing_getsock)
+ return conn->handler->doing_getsock(conn, socks, numsocks);
+ return GETSOCK_BLANK;
+}
+
+/*
+ * We are doing protocol-specific connecting and this is being called over and
+ * over from the multi interface until the connection phase is done on
+ * protocol layer.
+ */
+
+CURLcode Curl_protocol_connecting(struct connectdata *conn,
+ bool *done)
+{
+ CURLcode result=CURLE_OK;
+
+ if(conn && conn->handler->connecting) {
+ *done = FALSE;
+ result = conn->handler->connecting(conn, done);
+ }
+ else
+ *done = TRUE;
+
+ return result;
+}
+
+/*
+ * We are DOING this is being called over and over from the multi interface
+ * until the DOING phase is done on protocol layer.
+ */
+
+CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done)
+{
+ CURLcode result=CURLE_OK;
+
+ if(conn && conn->handler->doing) {
+ *done = FALSE;
+ result = conn->handler->doing(conn, done);
+ }
+ else
+ *done = TRUE;
+
+ return result;
+}
+
+/*
+ * We have discovered that the TCP connection has been successful, we can now
+ * proceed with some action.
+ *
+ */
+CURLcode Curl_protocol_connect(struct connectdata *conn,
+ bool *protocol_done)
+{
+ CURLcode result=CURLE_OK;
+
+ *protocol_done = FALSE;
+
+ if(conn->bits.tcpconnect[FIRSTSOCKET] && conn->bits.protoconnstart) {
+ /* We already are connected, get back. This may happen when the connect
+ worked fine in the first call, like when we connect to a local server
+ or proxy. Note that we don't know if the protocol is actually done.
+
+ Unless this protocol doesn't have any protocol-connect callback, as
+ then we know we're done. */
+ if(!conn->handler->connecting)
+ *protocol_done = TRUE;
+
+ return CURLE_OK;
+ }
+
+ if(!conn->bits.protoconnstart) {
+
+ result = Curl_proxy_connect(conn);
+ if(result)
+ return result;
+
+ if(conn->bits.tunnel_proxy && conn->bits.httpproxy &&
+ (conn->tunnel_state[FIRSTSOCKET] != TUNNEL_COMPLETE))
+ /* when using an HTTP tunnel proxy, await complete tunnel establishment
+ before proceeding further. Return CURLE_OK so we'll be called again */
+ return CURLE_OK;
+
+ if(conn->handler->connect_it) {
+ /* is there a protocol-specific connect() procedure? */
+
+ /* Call the protocol-specific connect function */
+ result = conn->handler->connect_it(conn, protocol_done);
+ }
+ else
+ *protocol_done = TRUE;
+
+ /* it has started, possibly even completed but that knowledge isn't stored
+ in this bit! */
+ if(!result)
+ conn->bits.protoconnstart = TRUE;
+ }
+
+ return result; /* pass back status */
+}
+
+/*
+ * Helpers for IDNA convertions.
+ */
+static bool is_ASCII_name(const char *hostname)
+{
+ const unsigned char *ch = (const unsigned char*)hostname;
+
+ while(*ch) {
+ if(*ch++ & 0x80)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+#ifdef USE_LIBIDN
+/*
+ * Check if characters in hostname is allowed in Top Level Domain.
+ */
+static bool tld_check_name(struct SessionHandle *data,
+ const char *ace_hostname)
+{
+ size_t err_pos;
+ char *uc_name = NULL;
+ int rc;
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+ const char *tld_errmsg = "<no msg>";
+#else
+ (void)data;
+#endif
+
+ /* Convert (and downcase) ACE-name back into locale's character set */
+ rc = idna_to_unicode_lzlz(ace_hostname, &uc_name, 0);
+ if(rc != IDNA_SUCCESS)
+ return FALSE;
+
+ rc = tld_check_lz(uc_name, &err_pos, NULL);
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+#ifdef HAVE_TLD_STRERROR
+ if(rc != TLD_SUCCESS)
+ tld_errmsg = tld_strerror((Tld_rc)rc);
+#endif
+ if(rc == TLD_INVALID)
+ infof(data, "WARNING: %s; pos %u = `%c'/0x%02X\n",
+ tld_errmsg, err_pos, uc_name[err_pos],
+ uc_name[err_pos] & 255);
+ else if(rc != TLD_SUCCESS)
+ infof(data, "WARNING: TLD check for %s failed; %s\n",
+ uc_name, tld_errmsg);
+#endif /* CURL_DISABLE_VERBOSE_STRINGS */
+ if(uc_name)
+ idn_free(uc_name);
+ if(rc != TLD_SUCCESS)
+ return FALSE;
+
+ return TRUE;
+}
+#endif
+
+/*
+ * Perform any necessary IDN conversion of hostname
+ */
+static void fix_hostname(struct SessionHandle *data,
+ struct connectdata *conn, struct hostname *host)
+{
+ size_t len;
+
+#ifndef USE_LIBIDN
+ (void)data;
+ (void)conn;
+#elif defined(CURL_DISABLE_VERBOSE_STRINGS)
+ (void)conn;
+#endif
+
+ /* set the name we use to display the host name */
+ host->dispname = host->name;
+
+ len = strlen(host->name);
+ if(len && (host->name[len-1] == '.'))
+ /* strip off a single trailing dot if present, primarily for SNI but
+ there's no use for it */
+ host->name[len-1]=0;
+
+ if(!is_ASCII_name(host->name)) {
+#ifdef USE_LIBIDN
+ /*************************************************************
+ * Check name for non-ASCII and convert hostname to ACE form.
+ *************************************************************/
+ if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
+ char *ace_hostname = NULL;
+ int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0);
+ infof (data, "Input domain encoded as `%s'\n",
+ stringprep_locale_charset ());
+ if(rc != IDNA_SUCCESS)
+ infof(data, "Failed to convert %s to ACE; %s\n",
+ host->name, Curl_idn_strerror(conn, rc));
+ else {
+ /* tld_check_name() displays a warning if the host name contains
+ "illegal" characters for this TLD */
+ (void)tld_check_name(data, ace_hostname);
+
+ host->encalloc = ace_hostname;
+ /* change the name pointer to point to the encoded hostname */
+ host->name = host->encalloc;
+ }
+ }
+#elif defined(USE_WIN32_IDN)
+ /*************************************************************
+ * Check name for non-ASCII and convert hostname to ACE form.
+ *************************************************************/
+ char *ace_hostname = NULL;
+ int rc = curl_win32_idn_to_ascii(host->name, &ace_hostname);
+ if(rc == 0)
+ infof(data, "Failed to convert %s to ACE;\n",
+ host->name);
+ else {
+ host->encalloc = ace_hostname;
+ /* change the name pointer to point to the encoded hostname */
+ host->name = host->encalloc;
+ }
+#else
+ infof(data, "IDN support not present, can't parse Unicode domains\n");
+#endif
+ }
+}
+
+static void llist_dtor(void *user, void *element)
+{
+ (void)user;
+ (void)element;
+ /* Do nothing */
+}
+
+/*
+ * Allocate and initialize a new connectdata object.
+ */
+static struct connectdata *allocate_conn(struct SessionHandle *data)
+{
+ struct connectdata *conn = calloc(1, sizeof(struct connectdata));
+ if(!conn)
+ return NULL;
+
+ conn->handler = &Curl_handler_dummy; /* Be sure we have a handler defined
+ already from start to avoid NULL
+ situations and checks */
+
+ /* and we setup a few fields in case we end up actually using this struct */
+
+ conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
+ conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
+ conn->tempsock[0] = CURL_SOCKET_BAD; /* no file descriptor */
+ conn->tempsock[1] = CURL_SOCKET_BAD; /* no file descriptor */
+ conn->connection_id = -1; /* no ID */
+ conn->port = -1; /* unknown at this point */
+ conn->remote_port = -1; /* unknown */
+
+ /* Default protocol-independent behavior doesn't support persistent
+ connections, so we set this to force-close. Protocols that support
+ this need to set this to FALSE in their "curl_do" functions. */
+ connclose(conn, "Default to force-close");
+
+ /* Store creation time to help future close decision making */
+ conn->created = Curl_tvnow();
+
+ conn->data = data; /* Setup the association between this connection
+ and the SessionHandle */
+
+ conn->proxytype = data->set.proxytype; /* type */
+
+#ifdef CURL_DISABLE_PROXY
+
+ conn->bits.proxy = FALSE;
+ conn->bits.httpproxy = FALSE;
+ conn->bits.proxy_user_passwd = FALSE;
+ conn->bits.tunnel_proxy = FALSE;
+
+#else /* CURL_DISABLE_PROXY */
+
+ /* note that these two proxy bits are now just on what looks to be
+ requested, they may be altered down the road */
+ conn->bits.proxy = (data->set.str[STRING_PROXY] &&
+ *data->set.str[STRING_PROXY])?TRUE:FALSE;
+ conn->bits.httpproxy = (conn->bits.proxy &&
+ (conn->proxytype == CURLPROXY_HTTP ||
+ conn->proxytype == CURLPROXY_HTTP_1_0))?TRUE:FALSE;
+ conn->bits.proxy_user_passwd =
+ (NULL != data->set.str[STRING_PROXYUSERNAME])?TRUE:FALSE;
+ conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
+
+#endif /* CURL_DISABLE_PROXY */
+
+ conn->bits.user_passwd = (NULL != data->set.str[STRING_USERNAME])?TRUE:FALSE;
+ conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
+ conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
+
+ conn->verifypeer = data->set.ssl.verifypeer;
+ conn->verifyhost = data->set.ssl.verifyhost;
+
+ conn->ip_version = data->set.ipver;
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
+ defined(NTLM_WB_ENABLED)
+ conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
+ conn->ntlm_auth_hlpr_pid = 0;
+ conn->challenge_header = NULL;
+ conn->response_header = NULL;
+#endif
+
+ if(Curl_pipeline_wanted(data->multi, CURLPIPE_HTTP1) &&
+ !conn->master_buffer) {
+ /* Allocate master_buffer to be used for HTTP/1 pipelining */
+ conn->master_buffer = calloc(BUFSIZE, sizeof (char));
+ if(!conn->master_buffer)
+ goto error;
+ }
+
+ /* Initialize the pipeline lists */
+ conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
+ conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
+ if(!conn->send_pipe || !conn->recv_pipe)
+ goto error;
+
+#ifdef HAVE_GSSAPI
+ conn->data_prot = PROT_CLEAR;
+#endif
+
+ /* Store the local bind parameters that will be used for this connection */
+ if(data->set.str[STRING_DEVICE]) {
+ conn->localdev = strdup(data->set.str[STRING_DEVICE]);
+ if(!conn->localdev)
+ goto error;
+ }
+ conn->localportrange = data->set.localportrange;
+ conn->localport = data->set.localport;
+
+ /* the close socket stuff needs to be copied to the connection struct as
+ it may live on without (this specific) SessionHandle */
+ conn->fclosesocket = data->set.fclosesocket;
+ conn->closesocket_client = data->set.closesocket_client;
+
+ return conn;
+ error:
+
+ Curl_llist_destroy(conn->send_pipe, NULL);
+ Curl_llist_destroy(conn->recv_pipe, NULL);
+
+ conn->send_pipe = NULL;
+ conn->recv_pipe = NULL;
+
+ free(conn->master_buffer);
+ free(conn->localdev);
+ free(conn);
+ return NULL;
+}
+
+static CURLcode findprotocol(struct SessionHandle *data,
+ struct connectdata *conn,
+ const char *protostr)
+{
+ const struct Curl_handler * const *pp;
+ const struct Curl_handler *p;
+
+ /* Scan protocol handler table and match against 'protostr' to set a few
+ variables based on the URL. Now that the handler may be changed later
+ when the protocol specific setup function is called. */
+ for(pp = protocols; (p = *pp) != NULL; pp++) {
+ if(Curl_raw_equal(p->scheme, protostr)) {
+ /* Protocol found in table. Check if allowed */
+ if(!(data->set.allowed_protocols & p->protocol))
+ /* nope, get out */
+ break;
+
+ /* it is allowed for "normal" request, now do an extra check if this is
+ the result of a redirect */
+ if(data->state.this_is_a_follow &&
+ !(data->set.redir_protocols & p->protocol))
+ /* nope, get out */
+ break;
+
+ /* Perform setup complement if some. */
+ conn->handler = conn->given = p;
+
+ /* 'port' and 'remote_port' are set in setup_connection_internals() */
+ return CURLE_OK;
+ }
+ }
+
+
+ /* The protocol was not found in the table, but we don't have to assign it
+ to anything since it is already assigned to a dummy-struct in the
+ create_conn() function when the connectdata struct is allocated. */
+ failf(data, "Protocol \"%s\" not supported or disabled in " LIBCURL_NAME,
+ protostr);
+
+ return CURLE_UNSUPPORTED_PROTOCOL;
+}
+
+/*
+ * Parse URL and fill in the relevant members of the connection struct.
+ */
+static CURLcode parseurlandfillconn(struct SessionHandle *data,
+ struct connectdata *conn,
+ bool *prot_missing,
+ char **userp, char **passwdp,
+ char **optionsp)
+{
+ char *at;
+ char *fragment;
+ char *path = data->state.path;
+ char *query;
+ int rc;
+ char protobuf[16] = "";
+ const char *protop = "";
+ CURLcode result;
+ bool rebuild_url = FALSE;
+
+ *prot_missing = FALSE;
+
+ /* We might pass the entire URL into the request so we need to make sure
+ * there are no bad characters in there.*/
+ if(strpbrk(data->change.url, "\r\n")) {
+ failf(data, "Illegal characters found in URL");
+ return CURLE_URL_MALFORMAT;
+ }
+
+ /*************************************************************
+ * Parse the URL.
+ *
+ * We need to parse the url even when using the proxy, because we will need
+ * the hostname and port in case we are trying to SSL connect through the
+ * proxy -- and we don't know if we will need to use SSL until we parse the
+ * url ...
+ ************************************************************/
+ if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]",
+ protobuf, path)) &&
+ Curl_raw_equal(protobuf, "file")) {
+ if(path[0] == '/' && path[1] == '/') {
+ /* Allow omitted hostname (e.g. file:/<path>). This is not strictly
+ * speaking a valid file: URL by RFC 1738, but treating file:/<path> as
+ * file://localhost/<path> is similar to how other schemes treat missing
+ * hostnames. See RFC 1808. */
+
+ /* This cannot be done with strcpy() in a portable manner, since the
+ memory areas overlap! */
+ memmove(path, path + 2, strlen(path + 2)+1);
+ }
+ /*
+ * we deal with file://<host>/<path> differently since it supports no
+ * hostname other than "localhost" and "127.0.0.1", which is unique among
+ * the URL protocols specified in RFC 1738
+ */
+ if(path[0] != '/') {
+ /* the URL included a host name, we ignore host names in file:// URLs
+ as the standards don't define what to do with them */
+ char *ptr=strchr(path, '/');
+ if(ptr) {
+ /* there was a slash present
+
+ RFC1738 (section 3.1, page 5) says:
+
+ The rest of the locator consists of data specific to the scheme,
+ and is known as the "url-path". It supplies the details of how the
+ specified resource can be accessed. Note that the "/" between the
+ host (or port) and the url-path is NOT part of the url-path.
+
+ As most agents use file://localhost/foo to get '/foo' although the
+ slash preceding foo is a separator and not a slash for the path,
+ a URL as file://localhost//foo must be valid as well, to refer to
+ the same file with an absolute path.
+ */
+
+ if(ptr[1] && ('/' == ptr[1]))
+ /* if there was two slashes, we skip the first one as that is then
+ used truly as a separator */
+ ptr++;
+
+ /* This cannot be made with strcpy, as the memory chunks overlap! */
+ memmove(path, ptr, strlen(ptr)+1);
+ }
+ }
+
+ protop = "file"; /* protocol string */
+ }
+ else {
+ /* clear path */
+ path[0]=0;
+
+ if(2 > sscanf(data->change.url,
+ "%15[^\n:]://%[^\n/?]%[^\n]",
+ protobuf,
+ conn->host.name, path)) {
+
+ /*
+ * The URL was badly formatted, let's try the browser-style _without_
+ * protocol specified like 'http://'.
+ */
+ rc = sscanf(data->change.url, "%[^\n/?]%[^\n]", conn->host.name, path);
+ if(1 > rc) {
+ /*
+ * We couldn't even get this format.
+ * djgpp 2.04 has a sscanf() bug where 'conn->host.name' is
+ * assigned, but the return value is EOF!
+ */
+#if defined(__DJGPP__) && (DJGPP_MINOR == 4)
+ if(!(rc == -1 && *conn->host.name))
+#endif
+ {
+ failf(data, "<url> malformed");
+ return CURLE_URL_MALFORMAT;
+ }
+ }
+
+ /*
+ * Since there was no protocol part specified, we guess what protocol it
+ * is based on the first letters of the server name.
+ */
+
+ /* Note: if you add a new protocol, please update the list in
+ * lib/version.c too! */
+
+ if(checkprefix("FTP.", conn->host.name))
+ protop = "ftp";
+ else if(checkprefix("DICT.", conn->host.name))
+ protop = "DICT";
+ else if(checkprefix("LDAP.", conn->host.name))
+ protop = "LDAP";
+ else if(checkprefix("IMAP.", conn->host.name))
+ protop = "IMAP";
+ else if(checkprefix("SMTP.", conn->host.name))
+ protop = "smtp";
+ else if(checkprefix("POP3.", conn->host.name))
+ protop = "pop3";
+ else {
+ protop = "http";
+ }
+
+ *prot_missing = TRUE; /* not given in URL */
+ }
+ else
+ protop = protobuf;
+ }
+
+ /* We search for '?' in the host name (but only on the right side of a
+ * @-letter to allow ?-letters in username and password) to handle things
+ * like http://example.com?param= (notice the missing '/').
+ */
+ at = strchr(conn->host.name, '@');
+ if(at)
+ query = strchr(at+1, '?');
+ else
+ query = strchr(conn->host.name, '?');
+
+ if(query) {
+ /* We must insert a slash before the '?'-letter in the URL. If the URL had
+ a slash after the '?', that is where the path currently begins and the
+ '?string' is still part of the host name.
+
+ We must move the trailing part from the host name and put it first in
+ the path. And have it all prefixed with a slash.
+ */
+
+ size_t hostlen = strlen(query);
+ size_t pathlen = strlen(path);
+
+ /* move the existing path plus the zero byte forward, to make room for
+ the host-name part */
+ memmove(path+hostlen+1, path, pathlen+1);
+
+ /* now copy the trailing host part in front of the existing path */
+ memcpy(path+1, query, hostlen);
+
+ path[0]='/'; /* prepend the missing slash */
+ rebuild_url = TRUE;
+
+ *query=0; /* now cut off the hostname at the ? */
+ }
+ else if(!path[0]) {
+ /* if there's no path set, use a single slash */
+ strcpy(path, "/");
+ rebuild_url = TRUE;
+ }
+
+ /* If the URL is malformatted (missing a '/' after hostname before path) we
+ * insert a slash here. The only letter except '/' we accept to start a path
+ * is '?'.
+ */
+ if(path[0] == '?') {
+ /* We need this function to deal with overlapping memory areas. We know
+ that the memory area 'path' points to is 'urllen' bytes big and that
+ is bigger than the path. Use +1 to move the zero byte too. */
+ memmove(&path[1], path, strlen(path)+1);
+ path[0] = '/';
+ rebuild_url = TRUE;
+ }
+ else if(!data->set.path_as_is) {
+ /* sanitise paths and remove ../ and ./ sequences according to RFC3986 */
+ char *newp = Curl_dedotdotify(path);
+ if(!newp)
+ return CURLE_OUT_OF_MEMORY;
+
+ if(strcmp(newp, path)) {
+ rebuild_url = TRUE;
+ free(data->state.pathbuffer);
+ data->state.pathbuffer = newp;
+ data->state.path = newp;
+ path = newp;
+ }
+ else
+ free(newp);
+ }
+
+ /*
+ * "rebuild_url" means that one or more URL components have been modified so
+ * we need to generate an updated full version. We need the corrected URL
+ * when communicating over HTTP proxy and we don't know at this point if
+ * we're using a proxy or not.
+ */
+ if(rebuild_url) {
+ char *reurl;
+
+ size_t plen = strlen(path); /* new path, should be 1 byte longer than
+ the original */
+ size_t urllen = strlen(data->change.url); /* original URL length */
+
+ size_t prefixlen = strlen(conn->host.name);
+
+ if(!*prot_missing)
+ prefixlen += strlen(protop) + strlen("://");
+
+ reurl = malloc(urllen + 2); /* 2 for zerobyte + slash */
+ if(!reurl)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* copy the prefix */
+ memcpy(reurl, data->change.url, prefixlen);
+
+ /* append the trailing piece + zerobyte */
+ memcpy(&reurl[prefixlen], path, plen + 1);
+
+ /* possible free the old one */
+ if(data->change.url_alloc) {
+ Curl_safefree(data->change.url);
+ data->change.url_alloc = FALSE;
+ }
+
+ infof(data, "Rebuilt URL to: %s\n", reurl);
+
+ data->change.url = reurl;
+ data->change.url_alloc = TRUE; /* free this later */
+ }
+
+ /*
+ * Parse the login details from the URL and strip them out of
+ * the host name
+ */
+ result = parse_url_login(data, conn, userp, passwdp, optionsp);
+ if(result)
+ return result;
+
+ if(conn->host.name[0] == '[') {
+ /* This looks like an IPv6 address literal. See if there is an address
+ scope if there is no location header */
+ char *percent = strchr(conn->host.name, '%');
+ if(percent) {
+ unsigned int identifier_offset = 3;
+ char *endp;
+ unsigned long scope;
+ if(strncmp("%25", percent, 3) != 0) {
+ infof(data,
+ "Please URL encode %% as %%25, see RFC 6874.\n");
+ identifier_offset = 1;
+ }
+ scope = strtoul(percent + identifier_offset, &endp, 10);
+ if(*endp == ']') {
+ /* The address scope was well formed. Knock it out of the
+ hostname. */
+ memmove(percent, endp, strlen(endp)+1);
+ conn->scope_id = (unsigned int)scope;
+ }
+ else {
+ /* Zone identifier is not numeric */
+#if defined(HAVE_NET_IF_H) && defined(IFNAMSIZ) && defined(HAVE_IF_NAMETOINDEX)
+ char ifname[IFNAMSIZ + 2];
+ char *square_bracket;
+ unsigned int scopeidx = 0;
+ strncpy(ifname, percent + identifier_offset, IFNAMSIZ + 2);
+ /* Ensure nullbyte termination */
+ ifname[IFNAMSIZ + 1] = '\0';
+ square_bracket = strchr(ifname, ']');
+ if(square_bracket) {
+ /* Remove ']' */
+ *square_bracket = '\0';
+ scopeidx = if_nametoindex(ifname);
+ if(scopeidx == 0) {
+ infof(data, "Invalid network interface: %s; %s\n", ifname,
+ strerror(errno));
+ }
+ }
+ if(scopeidx > 0) {
+ char *p = percent + identifier_offset + strlen(ifname);
+
+ /* Remove zone identifier from hostname */
+ memmove(percent, p, strlen(p) + 1);
+ conn->scope_id = scopeidx;
+ }
+ else
+#endif /* HAVE_NET_IF_H && IFNAMSIZ */
+ infof(data, "Invalid IPv6 address format\n");
+ }
+ }
+ }
+
+ if(data->set.scope_id)
+ /* Override any scope that was set above. */
+ conn->scope_id = data->set.scope_id;
+
+ /* Remove the fragment part of the path. Per RFC 2396, this is always the
+ last part of the URI. We are looking for the first '#' so that we deal
+ gracefully with non conformant URI such as http://example.com#foo#bar. */
+ fragment = strchr(path, '#');
+ if(fragment) {
+ *fragment = 0;
+
+ /* we know the path part ended with a fragment, so we know the full URL
+ string does too and we need to cut it off from there so it isn't used
+ over proxy */
+ fragment = strchr(data->change.url, '#');
+ if(fragment)
+ *fragment = 0;
+ }
+
+ /*
+ * So if the URL was A://B/C#D,
+ * protop is A
+ * conn->host.name is B
+ * data->state.path is /C
+ */
+
+ return findprotocol(data, conn, protop);
+}
+
+/*
+ * If we're doing a resumed transfer, we need to setup our stuff
+ * properly.
+ */
+static CURLcode setup_range(struct SessionHandle *data)
+{
+ struct UrlState *s = &data->state;
+ s->resume_from = data->set.set_resume_from;
+ if(s->resume_from || data->set.str[STRING_SET_RANGE]) {
+ if(s->rangestringalloc)
+ free(s->range);
+
+ if(s->resume_from)
+ s->range = aprintf("%" CURL_FORMAT_CURL_OFF_TU "-", s->resume_from);
+ else
+ s->range = strdup(data->set.str[STRING_SET_RANGE]);
+
+ s->rangestringalloc = (s->range)?TRUE:FALSE;
+
+ if(!s->range)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* tell ourselves to fetch this range */
+ s->use_range = TRUE; /* enable range download */
+ }
+ else
+ s->use_range = FALSE; /* disable range download */
+
+ return CURLE_OK;
+}
+
+
+/*
+ * setup_connection_internals() -
+ *
+ * Setup connection internals specific to the requested protocol in the
+ * SessionHandle. This is inited and setup before the connection is made but
+ * is about the particular protocol that is to be used.
+ *
+ * This MUST get called after proxy magic has been figured out.
+ */
+static CURLcode setup_connection_internals(struct connectdata *conn)
+{
+ const struct Curl_handler * p;
+ CURLcode result;
+ struct SessionHandle *data = conn->data;
+
+ /* in some case in the multi state-machine, we go back to the CONNECT state
+ and then a second (or third or...) call to this function will be made
+ without doing a DISCONNECT or DONE in between (since the connection is
+ yet in place) and therefore this function needs to first make sure
+ there's no lingering previous data allocated. */
+ Curl_free_request_state(data);
+
+ memset(&data->req, 0, sizeof(struct SingleRequest));
+ data->req.maxdownload = -1;
+
+ conn->socktype = SOCK_STREAM; /* most of them are TCP streams */
+
+ /* Perform setup complement if some. */
+ p = conn->handler;
+
+ if(p->setup_connection) {
+ result = (*p->setup_connection)(conn);
+
+ if(result)
+ return result;
+
+ p = conn->handler; /* May have changed. */
+ }
+
+ if(conn->port < 0)
+ /* we check for -1 here since if proxy was detected already, this
+ was very likely already set to the proxy port */
+ conn->port = p->defport;
+
+ /* only if remote_port was not already parsed off the URL we use the
+ default port number */
+ if(conn->remote_port < 0)
+ conn->remote_port = (unsigned short)conn->given->defport;
+
+ return CURLE_OK;
+}
+
+/*
+ * Curl_free_request_state() should free temp data that was allocated in the
+ * SessionHandle for this single request.
+ */
+
+void Curl_free_request_state(struct SessionHandle *data)
+{
+ Curl_safefree(data->req.protop);
+ Curl_safefree(data->req.newurl);
+}
+
+
+#ifndef CURL_DISABLE_PROXY
+/****************************************************************
+* Checks if the host is in the noproxy list. returns true if it matches
+* and therefore the proxy should NOT be used.
+****************************************************************/
+static bool check_noproxy(const char* name, const char* no_proxy)
+{
+ /* no_proxy=domain1.dom,host.domain2.dom
+ * (a comma-separated list of hosts which should
+ * not be proxied, or an asterisk to override
+ * all proxy variables)
+ */
+ size_t tok_start;
+ size_t tok_end;
+ const char* separator = ", ";
+ size_t no_proxy_len;
+ size_t namelen;
+ char *endptr;
+
+ if(no_proxy && no_proxy[0]) {
+ if(Curl_raw_equal("*", no_proxy)) {
+ return TRUE;
+ }
+
+ /* NO_PROXY was specified and it wasn't just an asterisk */
+
+ no_proxy_len = strlen(no_proxy);
+ endptr = strchr(name, ':');
+ if(endptr)
+ namelen = endptr - name;
+ else
+ namelen = strlen(name);
+
+ for(tok_start = 0; tok_start < no_proxy_len; tok_start = tok_end + 1) {
+ while(tok_start < no_proxy_len &&
+ strchr(separator, no_proxy[tok_start]) != NULL) {
+ /* Look for the beginning of the token. */
+ ++tok_start;
+ }
+
+ if(tok_start == no_proxy_len)
+ break; /* It was all trailing separator chars, no more tokens. */
+
+ for(tok_end = tok_start; tok_end < no_proxy_len &&
+ strchr(separator, no_proxy[tok_end]) == NULL; ++tok_end)
+ /* Look for the end of the token. */
+ ;
+
+ /* To match previous behaviour, where it was necessary to specify
+ * ".local.com" to prevent matching "notlocal.com", we will leave
+ * the '.' off.
+ */
+ if(no_proxy[tok_start] == '.')
+ ++tok_start;
+
+ if((tok_end - tok_start) <= namelen) {
+ /* Match the last part of the name to the domain we are checking. */
+ const char *checkn = name + namelen - (tok_end - tok_start);
+ if(Curl_raw_nequal(no_proxy + tok_start, checkn,
+ tok_end - tok_start)) {
+ if((tok_end - tok_start) == namelen || *(checkn - 1) == '.') {
+ /* We either have an exact match, or the previous character is a .
+ * so it is within the same domain, so no proxy for this host.
+ */
+ return TRUE;
+ }
+ }
+ } /* if((tok_end - tok_start) <= namelen) */
+ } /* for(tok_start = 0; tok_start < no_proxy_len;
+ tok_start = tok_end + 1) */
+ } /* NO_PROXY was specified and it wasn't just an asterisk */
+
+ return FALSE;
+}
+
+/****************************************************************
+* Detect what (if any) proxy to use. Remember that this selects a host
+* name and is not limited to HTTP proxies only.
+* The returned pointer must be freed by the caller (unless NULL)
+****************************************************************/
+static char *detect_proxy(struct connectdata *conn)
+{
+ char *proxy = NULL;
+
+#ifndef CURL_DISABLE_HTTP
+ /* If proxy was not specified, we check for default proxy environment
+ * variables, to enable i.e Lynx compliance:
+ *
+ * http_proxy=http://some.server.dom:port/
+ * https_proxy=http://some.server.dom:port/
+ * ftp_proxy=http://some.server.dom:port/
+ * no_proxy=domain1.dom,host.domain2.dom
+ * (a comma-separated list of hosts which should
+ * not be proxied, or an asterisk to override
+ * all proxy variables)
+ * all_proxy=http://some.server.dom:port/
+ * (seems to exist for the CERN www lib. Probably
+ * the first to check for.)
+ *
+ * For compatibility, the all-uppercase versions of these variables are
+ * checked if the lowercase versions don't exist.
+ */
+ char *no_proxy=NULL;
+ char proxy_env[128];
+
+ no_proxy=curl_getenv("no_proxy");
+ if(!no_proxy)
+ no_proxy=curl_getenv("NO_PROXY");
+
+ if(!check_noproxy(conn->host.name, no_proxy)) {
+ /* It was not listed as without proxy */
+ const char *protop = conn->handler->scheme;
+ char *envp = proxy_env;
+ char *prox;
+
+ /* Now, build <protocol>_proxy and check for such a one to use */
+ while(*protop)
+ *envp++ = (char)tolower((int)*protop++);
+
+ /* append _proxy */
+ strcpy(envp, "_proxy");
+
+ /* read the protocol proxy: */
+ prox=curl_getenv(proxy_env);
+
+ /*
+ * We don't try the uppercase version of HTTP_PROXY because of
+ * security reasons:
+ *
+ * When curl is used in a webserver application
+ * environment (cgi or php), this environment variable can
+ * be controlled by the web server user by setting the
+ * http header 'Proxy:' to some value.
+ *
+ * This can cause 'internal' http/ftp requests to be
+ * arbitrarily redirected by any external attacker.
+ */
+ if(!prox && !Curl_raw_equal("http_proxy", proxy_env)) {
+ /* There was no lowercase variable, try the uppercase version: */
+ Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env));
+ prox=curl_getenv(proxy_env);
+ }
+
+ if(prox)
+ proxy = prox; /* use this */
+ else {
+ proxy = curl_getenv("all_proxy"); /* default proxy to use */
+ if(!proxy)
+ proxy=curl_getenv("ALL_PROXY");
+ }
+ } /* if(!check_noproxy(conn->host.name, no_proxy)) - it wasn't specified
+ non-proxy */
+ free(no_proxy);
+
+#else /* !CURL_DISABLE_HTTP */
+
+ (void)conn;
+#endif /* CURL_DISABLE_HTTP */
+
+ return proxy;
+}
+
+/*
+ * If this is supposed to use a proxy, we need to figure out the proxy
+ * host name, so that we can re-use an existing connection
+ * that may exist registered to the same proxy host.
+ */
+static CURLcode parse_proxy(struct SessionHandle *data,
+ struct connectdata *conn, char *proxy)
+{
+ char *prox_portno;
+ char *endofprot;
+
+ /* We use 'proxyptr' to point to the proxy name from now on... */
+ char *proxyptr;
+ char *portptr;
+ char *atsign;
+
+ /* We do the proxy host string parsing here. We want the host name and the
+ * port name. Accept a protocol:// prefix
+ */
+
+ /* Parse the protocol part if present */
+ endofprot = strstr(proxy, "://");
+ if(endofprot) {
+ proxyptr = endofprot+3;
+ if(checkprefix("socks5h", proxy))
+ conn->proxytype = CURLPROXY_SOCKS5_HOSTNAME;
+ else if(checkprefix("socks5", proxy))
+ conn->proxytype = CURLPROXY_SOCKS5;
+ else if(checkprefix("socks4a", proxy))
+ conn->proxytype = CURLPROXY_SOCKS4A;
+ else if(checkprefix("socks4", proxy) || checkprefix("socks", proxy))
+ conn->proxytype = CURLPROXY_SOCKS4;
+ /* Any other xxx:// : change to http proxy */
+ }
+ else
+ proxyptr = proxy; /* No xxx:// head: It's a HTTP proxy */
+
+ /* Is there a username and password given in this proxy url? */
+ atsign = strchr(proxyptr, '@');
+ if(atsign) {
+ char *proxyuser = NULL;
+ char *proxypasswd = NULL;
+ CURLcode result =
+ parse_login_details(proxyptr, atsign - proxyptr,
+ &proxyuser, &proxypasswd, NULL);
+ if(!result) {
+ /* found user and password, rip them out. note that we are
+ unescaping them, as there is otherwise no way to have a
+ username or password with reserved characters like ':' in
+ them. */
+ Curl_safefree(conn->proxyuser);
+ if(proxyuser && strlen(proxyuser) < MAX_CURL_USER_LENGTH)
+ conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
+ else
+ conn->proxyuser = strdup("");
+
+ if(!conn->proxyuser)
+ result = CURLE_OUT_OF_MEMORY;
+ else {
+ Curl_safefree(conn->proxypasswd);
+ if(proxypasswd && strlen(proxypasswd) < MAX_CURL_PASSWORD_LENGTH)
+ conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
+ else
+ conn->proxypasswd = strdup("");
+
+ if(!conn->proxypasswd)
+ result = CURLE_OUT_OF_MEMORY;
+ }
+
+ if(!result) {
+ conn->bits.proxy_user_passwd = TRUE; /* enable it */
+ atsign++; /* the right side of the @-letter */
+
+ proxyptr = atsign; /* now use this instead */
+ }
+ }
+
+ free(proxyuser);
+ free(proxypasswd);
+
+ if(result)
+ return result;
+ }
+
+ /* start scanning for port number at this point */
+ portptr = proxyptr;
+
+ /* detect and extract RFC6874-style IPv6-addresses */
+ if(*proxyptr == '[') {
+ char *ptr = ++proxyptr; /* advance beyond the initial bracket */
+ while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '.')))
+ ptr++;
+ if(*ptr == '%') {
+ /* There might be a zone identifier */
+ if(strncmp("%25", ptr, 3))
+ infof(data, "Please URL encode %% as %%25, see RFC 6874.\n");
+ ptr++;
+ /* Allow unresered characters as defined in RFC 3986 */
+ while(*ptr && (ISALPHA(*ptr) || ISXDIGIT(*ptr) || (*ptr == '-') ||
+ (*ptr == '.') || (*ptr == '_') || (*ptr == '~')))
+ ptr++;
+ }
+ if(*ptr == ']')
+ /* yeps, it ended nicely with a bracket as well */
+ *ptr++ = 0;
+ else
+ infof(data, "Invalid IPv6 address format\n");
+ portptr = ptr;
+ /* Note that if this didn't end with a bracket, we still advanced the
+ * proxyptr first, but I can't see anything wrong with that as no host
+ * name nor a numeric can legally start with a bracket.
+ */
+ }
+
+ /* Get port number off proxy.server.com:1080 */
+ prox_portno = strchr(portptr, ':');
+ if(prox_portno) {
+ *prox_portno = 0x0; /* cut off number from host name */
+ prox_portno ++;
+ /* now set the local port number */
+ conn->port = strtol(prox_portno, NULL, 10);
+ }
+ else {
+ if(proxyptr[0]=='/')
+ /* If the first character in the proxy string is a slash, fail
+ immediately. The following code will otherwise clear the string which
+ will lead to code running as if no proxy was set! */
+ return CURLE_COULDNT_RESOLVE_PROXY;
+
+ /* without a port number after the host name, some people seem to use
+ a slash so we strip everything from the first slash */
+ atsign = strchr(proxyptr, '/');
+ if(atsign)
+ *atsign = 0x0; /* cut off path part from host name */
+
+ if(data->set.proxyport)
+ /* None given in the proxy string, then get the default one if it is
+ given */
+ conn->port = data->set.proxyport;
+ }
+
+ /* now, clone the cleaned proxy host name */
+ conn->proxy.rawalloc = strdup(proxyptr);
+ conn->proxy.name = conn->proxy.rawalloc;
+
+ if(!conn->proxy.rawalloc)
+ return CURLE_OUT_OF_MEMORY;
+
+ return CURLE_OK;
+}
+
+/*
+ * Extract the user and password from the authentication string
+ */
+static CURLcode parse_proxy_auth(struct SessionHandle *data,
+ struct connectdata *conn)
+{
+ char proxyuser[MAX_CURL_USER_LENGTH]="";
+ char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
+
+ if(data->set.str[STRING_PROXYUSERNAME] != NULL) {
+ strncpy(proxyuser, data->set.str[STRING_PROXYUSERNAME],
+ MAX_CURL_USER_LENGTH);
+ proxyuser[MAX_CURL_USER_LENGTH-1] = '\0'; /*To be on safe side*/
+ }
+ if(data->set.str[STRING_PROXYPASSWORD] != NULL) {
+ strncpy(proxypasswd, data->set.str[STRING_PROXYPASSWORD],
+ MAX_CURL_PASSWORD_LENGTH);
+ proxypasswd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/
+ }
+
+ conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
+ if(!conn->proxyuser)
+ return CURLE_OUT_OF_MEMORY;
+
+ conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
+ if(!conn->proxypasswd)
+ return CURLE_OUT_OF_MEMORY;
+
+ return CURLE_OK;
+}
+#endif /* CURL_DISABLE_PROXY */
+
+/*
+ * parse_url_login()
+ *
+ * Parse the login details (user name, password and options) from the URL and
+ * strip them out of the host name
+ *
+ * Inputs: data->set.use_netrc (CURLOPT_NETRC)
+ * conn->host.name
+ *
+ * Outputs: (almost :- all currently undefined)
+ * conn->bits.user_passwd - non-zero if non-default passwords exist
+ * user - non-zero length if defined
+ * passwd - non-zero length if defined
+ * options - non-zero length if defined
+ * conn->host.name - remove user name and password
+ */
+static CURLcode parse_url_login(struct SessionHandle *data,
+ struct connectdata *conn,
+ char **user, char **passwd, char **options)
+{
+ CURLcode result = CURLE_OK;
+ char *userp = NULL;
+ char *passwdp = NULL;
+ char *optionsp = NULL;
+
+ /* At this point, we're hoping all the other special cases have
+ * been taken care of, so conn->host.name is at most
+ * [user[:password][;options]]@]hostname
+ *
+ * We need somewhere to put the embedded details, so do that first.
+ */
+
+ char *ptr = strchr(conn->host.name, '@');
+ char *login = conn->host.name;
+
+ DEBUGASSERT(!**user);
+ DEBUGASSERT(!**passwd);
+ DEBUGASSERT(!**options);
+
+ if(!ptr)
+ goto out;
+
+ /* We will now try to extract the
+ * possible login information in a string like:
+ * ftp://user:password@ftp.my.site:8021/README */
+ conn->host.name = ++ptr;
+
+ /* So the hostname is sane. Only bother interpreting the
+ * results if we could care. It could still be wasted
+ * work because it might be overtaken by the programmatically
+ * set user/passwd, but doing that first adds more cases here :-(
+ */
+
+ if(data->set.use_netrc == CURL_NETRC_REQUIRED)
+ goto out;
+
+ /* We could use the login information in the URL so extract it */
+ result = parse_login_details(login, ptr - login - 1,
+ &userp, &passwdp, &optionsp);
+ if(result)
+ goto out;
+
+ if(userp) {
+ char *newname;
+
+ /* We have a user in the URL */
+ conn->bits.userpwd_in_url = TRUE;
+ conn->bits.user_passwd = TRUE; /* enable user+password */
+
+ /* Decode the user */
+ newname = curl_easy_unescape(data, userp, 0, NULL);
+ if(!newname) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto out;
+ }
+
+ free(*user);
+ *user = newname;
+ }
+
+ if(passwdp) {
+ /* We have a password in the URL so decode it */
+ char *newpasswd = curl_easy_unescape(data, passwdp, 0, NULL);
+ if(!newpasswd) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto out;
+ }
+
+ free(*passwd);
+ *passwd = newpasswd;
+ }
+
+ if(optionsp) {
+ /* We have an options list in the URL so decode it */
+ char *newoptions = curl_easy_unescape(data, optionsp, 0, NULL);
+ if(!newoptions) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto out;
+ }
+
+ free(*options);
+ *options = newoptions;
+ }
+
+
+ out:
+
+ free(userp);
+ free(passwdp);
+ free(optionsp);
+
+ return result;
+}
+
+/*
+ * parse_login_details()
+ *
+ * This is used to parse a login string for user name, password and options in
+ * the following formats:
+ *
+ * user
+ * user:password
+ * user:password;options
+ * user;options
+ * user;options:password
+ * :password
+ * :password;options
+ * ;options
+ * ;options:password
+ *
+ * Parameters:
+ *
+ * login [in] - The login string.
+ * len [in] - The length of the login string.
+ * userp [in/out] - The address where a pointer to newly allocated memory
+ * holding the user will be stored upon completion.
+ * passdwp [in/out] - The address where a pointer to newly allocated memory
+ * holding the password will be stored upon completion.
+ * optionsp [in/out] - The address where a pointer to newly allocated memory
+ * holding the options will be stored upon completion.
+ *
+ * Returns CURLE_OK on success.
+ */
+static CURLcode parse_login_details(const char *login, const size_t len,
+ char **userp, char **passwdp,
+ char **optionsp)
+{
+ CURLcode result = CURLE_OK;
+ char *ubuf = NULL;
+ char *pbuf = NULL;
+ char *obuf = NULL;
+ const char *psep = NULL;
+ const char *osep = NULL;
+ size_t ulen;
+ size_t plen;
+ size_t olen;
+
+ /* Attempt to find the password separator */
+ if(passwdp) {
+ psep = strchr(login, ':');
+
+ /* Within the constraint of the login string */
+ if(psep >= login + len)
+ psep = NULL;
+ }
+
+ /* Attempt to find the options separator */
+ if(optionsp) {
+ osep = strchr(login, ';');
+
+ /* Within the constraint of the login string */
+ if(osep >= login + len)
+ osep = NULL;
+ }
+
+ /* Calculate the portion lengths */
+ ulen = (psep ?
+ (size_t)(osep && psep > osep ? osep - login : psep - login) :
+ (osep ? (size_t)(osep - login) : len));
+ plen = (psep ?
+ (osep && osep > psep ? (size_t)(osep - psep) :
+ (size_t)(login + len - psep)) - 1 : 0);
+ olen = (osep ?
+ (psep && psep > osep ? (size_t)(psep - osep) :
+ (size_t)(login + len - osep)) - 1 : 0);
+
+ /* Allocate the user portion buffer */
+ if(userp && ulen) {
+ ubuf = malloc(ulen + 1);
+ if(!ubuf)
+ result = CURLE_OUT_OF_MEMORY;
+ }
+
+ /* Allocate the password portion buffer */
+ if(!result && passwdp && plen) {
+ pbuf = malloc(plen + 1);
+ if(!pbuf) {
+ free(ubuf);
+ result = CURLE_OUT_OF_MEMORY;
+ }
+ }
+
+ /* Allocate the options portion buffer */
+ if(!result && optionsp && olen) {
+ obuf = malloc(olen + 1);
+ if(!obuf) {
+ free(pbuf);
+ free(ubuf);
+ result = CURLE_OUT_OF_MEMORY;
+ }
+ }
+
+ if(!result) {
+ /* Store the user portion if necessary */
+ if(ubuf) {
+ memcpy(ubuf, login, ulen);
+ ubuf[ulen] = '\0';
+ Curl_safefree(*userp);
+ *userp = ubuf;
+ }
+
+ /* Store the password portion if necessary */
+ if(pbuf) {
+ memcpy(pbuf, psep + 1, plen);
+ pbuf[plen] = '\0';
+ Curl_safefree(*passwdp);
+ *passwdp = pbuf;
+ }
+
+ /* Store the options portion if necessary */
+ if(obuf) {
+ memcpy(obuf, osep + 1, olen);
+ obuf[olen] = '\0';
+ Curl_safefree(*optionsp);
+ *optionsp = obuf;
+ }
+ }
+
+ return result;
+}
+
+/*************************************************************
+ * Figure out the remote port number and fix it in the URL
+ *
+ * No matter if we use a proxy or not, we have to figure out the remote
+ * port number of various reasons.
+ *
+ * To be able to detect port number flawlessly, we must not confuse them
+ * IPv6-specified addresses in the [0::1] style. (RFC2732)
+ *
+ * The conn->host.name is currently [user:passwd@]host[:port] where host
+ * could be a hostname, IPv4 address or IPv6 address.
+ *
+ * The port number embedded in the URL is replaced, if necessary.
+ *************************************************************/
+static CURLcode parse_remote_port(struct SessionHandle *data,
+ struct connectdata *conn)
+{
+ char *portptr;
+ char endbracket;
+
+ /* Note that at this point, the IPv6 address cannot contain any scope
+ suffix as that has already been removed in the parseurlandfillconn()
+ function */
+ if((1 == sscanf(conn->host.name, "[%*45[0123456789abcdefABCDEF:.]%c",
+ &endbracket)) &&
+ (']' == endbracket)) {
+ /* this is a RFC2732-style specified IP-address */
+ conn->bits.ipv6_ip = TRUE;
+
+ conn->host.name++; /* skip over the starting bracket */
+ portptr = strchr(conn->host.name, ']');
+ if(portptr) {
+ *portptr++ = '\0'; /* zero terminate, killing the bracket */
+ if(':' != *portptr)
+ portptr = NULL; /* no port number available */
+ }
+ }
+ else {
+#ifdef ENABLE_IPV6
+ struct in6_addr in6;
+ if(Curl_inet_pton(AF_INET6, conn->host.name, &in6) > 0) {
+ /* This is a numerical IPv6 address, meaning this is a wrongly formatted
+ URL */
+ failf(data, "IPv6 numerical address used in URL without brackets");
+ return CURLE_URL_MALFORMAT;
+ }
+#endif
+
+ portptr = strrchr(conn->host.name, ':');
+ }
+
+ if(data->set.use_port && data->state.allow_port) {
+ /* if set, we use this and ignore the port possibly given in the URL */
+ conn->remote_port = (unsigned short)data->set.use_port;
+ if(portptr)
+ *portptr = '\0'; /* cut off the name there anyway - if there was a port
+ number - since the port number is to be ignored! */
+ if(conn->bits.httpproxy) {
+ /* we need to create new URL with the new port number */
+ char *url;
+ char type[12]="";
+
+ if(conn->bits.type_set)
+ snprintf(type, sizeof(type), ";type=%c",
+ data->set.prefer_ascii?'A':
+ (data->set.ftp_list_only?'D':'I'));
+
+ /*
+ * This synthesized URL isn't always right--suffixes like ;type=A are
+ * stripped off. It would be better to work directly from the original
+ * URL and simply replace the port part of it.
+ */
+ url = aprintf("%s://%s%s%s:%hu%s%s%s", conn->given->scheme,
+ conn->bits.ipv6_ip?"[":"", conn->host.name,
+ conn->bits.ipv6_ip?"]":"", conn->remote_port,
+ data->state.slash_removed?"/":"", data->state.path,
+ type);
+ if(!url)
+ return CURLE_OUT_OF_MEMORY;
+
+ if(data->change.url_alloc) {
+ Curl_safefree(data->change.url);
+ data->change.url_alloc = FALSE;
+ }
+
+ data->change.url = url;
+ data->change.url_alloc = TRUE;
+ }
+ }
+ else if(portptr) {
+ /* no CURLOPT_PORT given, extract the one from the URL */
+
+ char *rest;
+ long port;
+
+ port=strtol(portptr+1, &rest, 10); /* Port number must be decimal */
+
+ if((port < 0) || (port > 0xffff)) {
+ /* Single unix standard says port numbers are 16 bits long */
+ failf(data, "Port number out of range");
+ return CURLE_URL_MALFORMAT;
+ }
+
+ else if(rest != &portptr[1]) {
+ *portptr = '\0'; /* cut off the name there */
+ conn->remote_port = curlx_ultous(port);
+ }
+ else
+ /* Browser behavior adaptation. If there's a colon with no digits after,
+ just cut off the name there which makes us ignore the colon and just
+ use the default port. Firefox and Chrome both do that. */
+ *portptr = '\0';
+ }
+ return CURLE_OK;
+}
+
+/*
+ * Override the login details from the URL with that in the CURLOPT_USERPWD
+ * option or a .netrc file, if applicable.
+ */
+static CURLcode override_login(struct SessionHandle *data,
+ struct connectdata *conn,
+ char **userp, char **passwdp, char **optionsp)
+{
+ if(data->set.str[STRING_USERNAME]) {
+ free(*userp);
+ *userp = strdup(data->set.str[STRING_USERNAME]);
+ if(!*userp)
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ if(data->set.str[STRING_PASSWORD]) {
+ free(*passwdp);
+ *passwdp = strdup(data->set.str[STRING_PASSWORD]);
+ if(!*passwdp)
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ if(data->set.str[STRING_OPTIONS]) {
+ free(*optionsp);
+ *optionsp = strdup(data->set.str[STRING_OPTIONS]);
+ if(!*optionsp)
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ conn->bits.netrc = FALSE;
+ if(data->set.use_netrc != CURL_NETRC_IGNORED) {
+ int ret = Curl_parsenetrc(conn->host.name,
+ userp, passwdp,
+ data->set.str[STRING_NETRC_FILE]);
+ if(ret > 0) {
+ infof(data, "Couldn't find host %s in the "
+ DOT_CHAR "netrc file; using defaults\n",
+ conn->host.name);
+ }
+ else if(ret < 0 ) {
+ return CURLE_OUT_OF_MEMORY;
+ }
+ else {
+ /* set bits.netrc TRUE to remember that we got the name from a .netrc
+ file, so that it is safe to use even if we followed a Location: to a
+ different host or similar. */
+ conn->bits.netrc = TRUE;
+
+ conn->bits.user_passwd = TRUE; /* enable user+password */
+ }
+ }
+
+ return CURLE_OK;
+}
+
+/*
+ * Set the login details so they're available in the connection
+ */
+static CURLcode set_login(struct connectdata *conn,
+ const char *user, const char *passwd,
+ const char *options)
+{
+ CURLcode result = CURLE_OK;
+
+ /* If our protocol needs a password and we have none, use the defaults */
+ if((conn->handler->flags & PROTOPT_NEEDSPWD) && !conn->bits.user_passwd) {
+ /* Store the default user */
+ conn->user = strdup(CURL_DEFAULT_USER);
+
+ /* Store the default password */
+ if(conn->user)
+ conn->passwd = strdup(CURL_DEFAULT_PASSWORD);
+ else
+ conn->passwd = NULL;
+
+ /* This is the default password, so DON'T set conn->bits.user_passwd */
+ }
+ else {
+ /* Store the user, zero-length if not set */
+ conn->user = strdup(user);
+
+ /* Store the password (only if user is present), zero-length if not set */
+ if(conn->user)
+ conn->passwd = strdup(passwd);
+ else
+ conn->passwd = NULL;
+ }
+
+ if(!conn->user || !conn->passwd)
+ result = CURLE_OUT_OF_MEMORY;
+
+ /* Store the options, null if not set */
+ if(!result && options[0]) {
+ conn->options = strdup(options);
+
+ if(!conn->options)
+ result = CURLE_OUT_OF_MEMORY;
+ }
+
+ return result;
+}
+
+/*************************************************************
+ * Resolve the address of the server or proxy
+ *************************************************************/
+static CURLcode resolve_server(struct SessionHandle *data,
+ struct connectdata *conn,
+ bool *async)
+{
+ CURLcode result=CURLE_OK;
+ long timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+ /*************************************************************
+ * Resolve the name of the server or proxy
+ *************************************************************/
+ if(conn->bits.reuse)
+ /* We're reusing the connection - no need to resolve anything, and
+ fix_hostname() was called already in create_conn() for the re-use
+ case. */
+ *async = FALSE;
+
+ else {
+ /* this is a fresh connect */
+ int rc;
+ struct Curl_dns_entry *hostaddr;
+
+ /* set a pointer to the hostname we display */
+ fix_hostname(data, conn, &conn->host);
+
+#ifdef USE_UNIX_SOCKETS
+ if(data->set.str[STRING_UNIX_SOCKET_PATH]) {
+ /* Unix domain sockets are local. The host gets ignored, just use the
+ * specified domain socket address. Do not cache "DNS entries". There is
+ * no DNS involved and we already have the filesystem path available */
+ const char *path = data->set.str[STRING_UNIX_SOCKET_PATH];
+
+ hostaddr = calloc(1, sizeof(struct Curl_dns_entry));
+ if(!hostaddr)
+ result = CURLE_OUT_OF_MEMORY;
+ else if((hostaddr->addr = Curl_unix2addr(path)) != NULL)
+ hostaddr->inuse++;
+ else {
+ /* Long paths are not supported for now */
+ if(strlen(path) >= sizeof(((struct sockaddr_un *)0)->sun_path)) {
+ failf(data, "Unix socket path too long: '%s'", path);
+ result = CURLE_COULDNT_RESOLVE_HOST;
+ }
+ else
+ result = CURLE_OUT_OF_MEMORY;
+ free(hostaddr);
+ hostaddr = NULL;
+ }
+ }
+ else
+#endif
+ if(!conn->proxy.name || !*conn->proxy.name) {
+ /* If not connecting via a proxy, extract the port from the URL, if it is
+ * there, thus overriding any defaults that might have been set above. */
+ conn->port = conn->remote_port; /* it is the same port */
+
+ /* Resolve target host right on */
+ rc = Curl_resolv_timeout(conn, conn->host.name, (int)conn->port,
+ &hostaddr, timeout_ms);
+ if(rc == CURLRESOLV_PENDING)
+ *async = TRUE;
+
+ else if(rc == CURLRESOLV_TIMEDOUT)
+ result = CURLE_OPERATION_TIMEDOUT;
+
+ else if(!hostaddr) {
+ failf(data, "Couldn't resolve host '%s'", conn->host.dispname);
+ result = CURLE_COULDNT_RESOLVE_HOST;
+ /* don't return yet, we need to clean up the timeout first */
+ }
+ }
+ else {
+ /* This is a proxy that hasn't been resolved yet. */
+
+ /* IDN-fix the proxy name */
+ fix_hostname(data, conn, &conn->proxy);
+
+ /* resolve proxy */
+ rc = Curl_resolv_timeout(conn, conn->proxy.name, (int)conn->port,
+ &hostaddr, timeout_ms);
+
+ if(rc == CURLRESOLV_PENDING)
+ *async = TRUE;
+
+ else if(rc == CURLRESOLV_TIMEDOUT)
+ result = CURLE_OPERATION_TIMEDOUT;
+
+ else if(!hostaddr) {
+ failf(data, "Couldn't resolve proxy '%s'", conn->proxy.dispname);
+ result = CURLE_COULDNT_RESOLVE_PROXY;
+ /* don't return yet, we need to clean up the timeout first */
+ }
+ }
+ DEBUGASSERT(conn->dns_entry == NULL);
+ conn->dns_entry = hostaddr;
+ }
+
+ return result;
+}
+
+/*
+ * Cleanup the connection just allocated before we can move along and use the
+ * previously existing one. All relevant data is copied over and old_conn is
+ * ready for freeing once this function returns.
+ */
+static void reuse_conn(struct connectdata *old_conn,
+ struct connectdata *conn)
+{
+ free(old_conn->proxy.rawalloc);
+
+ /* free the SSL config struct from this connection struct as this was
+ allocated in vain and is targeted for destruction */
+ Curl_free_ssl_config(&old_conn->ssl_config);
+
+ conn->data = old_conn->data;
+
+ /* get the user+password information from the old_conn struct since it may
+ * be new for this request even when we re-use an existing connection */
+ conn->bits.user_passwd = old_conn->bits.user_passwd;
+ if(conn->bits.user_passwd) {
+ /* use the new user name and password though */
+ Curl_safefree(conn->user);
+ Curl_safefree(conn->passwd);
+ conn->user = old_conn->user;
+ conn->passwd = old_conn->passwd;
+ old_conn->user = NULL;
+ old_conn->passwd = NULL;
+ }
+
+ conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
+ if(conn->bits.proxy_user_passwd) {
+ /* use the new proxy user name and proxy password though */
+ Curl_safefree(conn->proxyuser);
+ Curl_safefree(conn->proxypasswd);
+ conn->proxyuser = old_conn->proxyuser;
+ conn->proxypasswd = old_conn->proxypasswd;
+ old_conn->proxyuser = NULL;
+ old_conn->proxypasswd = NULL;
+ }
+
+ /* host can change, when doing keepalive with a proxy or if the case is
+ different this time etc */
+ Curl_safefree(conn->host.rawalloc);
+ conn->host=old_conn->host;
+
+ /* persist connection info in session handle */
+ Curl_persistconninfo(conn);
+
+ /* re-use init */
+ conn->bits.reuse = TRUE; /* yes, we're re-using here */
+
+ Curl_safefree(old_conn->user);
+ Curl_safefree(old_conn->passwd);
+ Curl_safefree(old_conn->proxyuser);
+ Curl_safefree(old_conn->proxypasswd);
+ Curl_safefree(old_conn->localdev);
+
+ Curl_llist_destroy(old_conn->send_pipe, NULL);
+ Curl_llist_destroy(old_conn->recv_pipe, NULL);
+
+ old_conn->send_pipe = NULL;
+ old_conn->recv_pipe = NULL;
+
+ Curl_safefree(old_conn->master_buffer);
+}
+
+/**
+ * create_conn() sets up a new connectdata struct, or re-uses an already
+ * existing one, and resolves host name.
+ *
+ * if this function returns CURLE_OK and *async is set to TRUE, the resolve
+ * response will be coming asynchronously. If *async is FALSE, the name is
+ * already resolved.
+ *
+ * @param data The sessionhandle pointer
+ * @param in_connect is set to the next connection data pointer
+ * @param async is set TRUE when an async DNS resolution is pending
+ * @see Curl_setup_conn()
+ *
+ * *NOTE* this function assigns the conn->data pointer!
+ */
+
+static CURLcode create_conn(struct SessionHandle *data,
+ struct connectdata **in_connect,
+ bool *async)
+{
+ CURLcode result = CURLE_OK;
+ struct connectdata *conn;
+ struct connectdata *conn_temp = NULL;
+ size_t urllen;
+ char *user = NULL;
+ char *passwd = NULL;
+ char *options = NULL;
+ bool reuse;
+ char *proxy = NULL;
+ bool prot_missing = FALSE;
+ bool connections_available = TRUE;
+ bool force_reuse = FALSE;
+ bool waitpipe = FALSE;
+ size_t max_host_connections = Curl_multi_max_host_connections(data->multi);
+ size_t max_total_connections = Curl_multi_max_total_connections(data->multi);
+
+ *async = FALSE;
+
+ /*************************************************************
+ * Check input data
+ *************************************************************/
+
+ if(!data->change.url) {
+ result = CURLE_URL_MALFORMAT;
+ goto out;
+ }
+
+ /* First, split up the current URL in parts so that we can use the
+ parts for checking against the already present connections. In order
+ to not have to modify everything at once, we allocate a temporary
+ connection data struct and fill in for comparison purposes. */
+ conn = allocate_conn(data);
+
+ if(!conn) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto out;
+ }
+
+ /* We must set the return variable as soon as possible, so that our
+ parent can cleanup any possible allocs we may have done before
+ any failure */
+ *in_connect = conn;
+
+ /* This initing continues below, see the comment "Continue connectdata
+ * initialization here" */
+
+ /***********************************************************
+ * We need to allocate memory to store the path in. We get the size of the
+ * full URL to be sure, and we need to make it at least 256 bytes since
+ * other parts of the code will rely on this fact
+ ***********************************************************/
+#define LEAST_PATH_ALLOC 256
+ urllen=strlen(data->change.url);
+ if(urllen < LEAST_PATH_ALLOC)
+ urllen=LEAST_PATH_ALLOC;
+
+ /*
+ * We malloc() the buffers below urllen+2 to make room for 2 possibilities:
+ * 1 - an extra terminating zero
+ * 2 - an extra slash (in case a syntax like "www.host.com?moo" is used)
+ */
+
+ Curl_safefree(data->state.pathbuffer);
+ data->state.path = NULL;
+
+ data->state.pathbuffer = malloc(urllen+2);
+ if(NULL == data->state.pathbuffer) {
+ result = CURLE_OUT_OF_MEMORY; /* really bad error */
+ goto out;
+ }
+ data->state.path = data->state.pathbuffer;
+
+ conn->host.rawalloc = malloc(urllen+2);
+ if(NULL == conn->host.rawalloc) {
+ Curl_safefree(data->state.pathbuffer);
+ data->state.path = NULL;
+ result = CURLE_OUT_OF_MEMORY;
+ goto out;
+ }
+
+ conn->host.name = conn->host.rawalloc;
+ conn->host.name[0] = 0;
+
+ user = strdup("");
+ passwd = strdup("");
+ options = strdup("");
+ if(!user || !passwd || !options) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto out;
+ }
+
+ result = parseurlandfillconn(data, conn, &prot_missing, &user, &passwd,
+ &options);
+ if(result)
+ goto out;
+
+ /*************************************************************
+ * No protocol part in URL was used, add it!
+ *************************************************************/
+ if(prot_missing) {
+ /* We're guessing prefixes here and if we're told to use a proxy or if
+ we're gonna follow a Location: later or... then we need the protocol
+ part added so that we have a valid URL. */
+ char *reurl;
+
+ reurl = aprintf("%s://%s", conn->handler->scheme, data->change.url);
+
+ if(!reurl) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto out;
+ }
+
+ if(data->change.url_alloc) {
+ Curl_safefree(data->change.url);
+ data->change.url_alloc = FALSE;
+ }
+
+ data->change.url = reurl;
+ data->change.url_alloc = TRUE; /* free this later */
+ }
+
+ /*************************************************************
+ * If the protocol can't handle url query strings, then cut
+ * off the unhandable part
+ *************************************************************/
+ if((conn->given->flags&PROTOPT_NOURLQUERY)) {
+ char *path_q_sep = strchr(conn->data->state.path, '?');
+ if(path_q_sep) {
+ /* according to rfc3986, allow the query (?foo=bar)
+ also on protocols that can't handle it.
+
+ cut the string-part after '?'
+ */
+
+ /* terminate the string */
+ path_q_sep[0] = 0;
+ }
+ }
+
+ if(data->set.str[STRING_BEARER]) {
+ conn->xoauth2_bearer = strdup(data->set.str[STRING_BEARER]);
+ if(!conn->xoauth2_bearer) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto out;
+ }
+ }
+
+#ifndef CURL_DISABLE_PROXY
+ /*************************************************************
+ * Extract the user and password from the authentication string
+ *************************************************************/
+ if(conn->bits.proxy_user_passwd) {
+ result = parse_proxy_auth(data, conn);
+ if(result)
+ goto out;
+ }
+
+ /*************************************************************
+ * Detect what (if any) proxy to use
+ *************************************************************/
+ if(data->set.str[STRING_PROXY]) {
+ proxy = strdup(data->set.str[STRING_PROXY]);
+ /* if global proxy is set, this is it */
+ if(NULL == proxy) {
+ failf(data, "memory shortage");
+ result = CURLE_OUT_OF_MEMORY;
+ goto out;
+ }
+ }
+
+ if(data->set.str[STRING_NOPROXY] &&
+ check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY])) {
+ free(proxy); /* proxy is in exception list */
+ proxy = NULL;
+ }
+ else if(!proxy)
+ proxy = detect_proxy(conn);
+
+#ifdef USE_UNIX_SOCKETS
+ if(proxy && data->set.str[STRING_UNIX_SOCKET_PATH]) {
+ free(proxy); /* Unix domain sockets cannot be proxied, so disable it */
+ proxy = NULL;
+ }
+#endif
+
+ if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_NONETWORK))) {
+ free(proxy); /* Don't bother with an empty proxy string or if the
+ protocol doesn't work with network */
+ proxy = NULL;
+ }
+
+ /***********************************************************************
+ * If this is supposed to use a proxy, we need to figure out the proxy host
+ * name, proxy type and port number, so that we can re-use an existing
+ * connection that may exist registered to the same proxy host.
+ ***********************************************************************/
+ if(proxy) {
+ result = parse_proxy(data, conn, proxy);
+
+ free(proxy); /* parse_proxy copies the proxy string */
+ proxy = NULL;
+
+ if(result)
+ goto out;
+
+ if((conn->proxytype == CURLPROXY_HTTP) ||
+ (conn->proxytype == CURLPROXY_HTTP_1_0)) {
+#ifdef CURL_DISABLE_HTTP
+ /* asking for a HTTP proxy is a bit funny when HTTP is disabled... */
+ result = CURLE_UNSUPPORTED_PROTOCOL;
+ goto out;
+#else
+ /* force this connection's protocol to become HTTP if not already
+ compatible - if it isn't tunneling through */
+ if(!(conn->handler->protocol & PROTO_FAMILY_HTTP) &&
+ !conn->bits.tunnel_proxy)
+ conn->handler = &Curl_handler_http;
+
+ conn->bits.httpproxy = TRUE;
+#endif
+ }
+ else {
+ conn->bits.httpproxy = FALSE; /* not a HTTP proxy */
+ conn->bits.tunnel_proxy = FALSE; /* no tunneling if not HTTP */
+ }
+ conn->bits.proxy = TRUE;
+ }
+ else {
+ /* we aren't using the proxy after all... */
+ conn->bits.proxy = FALSE;
+ conn->bits.httpproxy = FALSE;
+ conn->bits.proxy_user_passwd = FALSE;
+ conn->bits.tunnel_proxy = FALSE;
+ }
+
+#endif /* CURL_DISABLE_PROXY */
+
+ /*************************************************************
+ * If the protocol is using SSL and HTTP proxy is used, we set
+ * the tunnel_proxy bit.
+ *************************************************************/
+ if((conn->given->flags&PROTOPT_SSL) && conn->bits.httpproxy)
+ conn->bits.tunnel_proxy = TRUE;
+
+ /*************************************************************
+ * Figure out the remote port number and fix it in the URL
+ *************************************************************/
+ result = parse_remote_port(data, conn);
+ if(result)
+ goto out;
+
+ /* Check for overridden login details and set them accordingly so they
+ they are known when protocol->setup_connection is called! */
+ result = override_login(data, conn, &user, &passwd, &options);
+ if(result)
+ goto out;
+ result = set_login(conn, user, passwd, options);
+ if(result)
+ goto out;
+
+ /*************************************************************
+ * Setup internals depending on protocol. Needs to be done after
+ * we figured out what/if proxy to use.
+ *************************************************************/
+ result = setup_connection_internals(conn);
+ if(result)
+ goto out;
+
+ conn->recv[FIRSTSOCKET] = Curl_recv_plain;
+ conn->send[FIRSTSOCKET] = Curl_send_plain;
+ conn->recv[SECONDARYSOCKET] = Curl_recv_plain;
+ conn->send[SECONDARYSOCKET] = Curl_send_plain;
+
+ /***********************************************************************
+ * file: is a special case in that it doesn't need a network connection
+ ***********************************************************************/
+#ifndef CURL_DISABLE_FILE
+ if(conn->handler->flags & PROTOPT_NONETWORK) {
+ bool done;
+ /* this is supposed to be the connect function so we better at least check
+ that the file is present here! */
+ DEBUGASSERT(conn->handler->connect_it);
+ result = conn->handler->connect_it(conn, &done);
+
+ /* Setup a "faked" transfer that'll do nothing */
+ if(!result) {
+ conn->data = data;
+ conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; /* we are "connected */
+
+ Curl_conncache_add_conn(data->state.conn_cache, conn);
+
+ /*
+ * Setup whatever necessary for a resumed transfer
+ */
+ result = setup_range(data);
+ if(result) {
+ DEBUGASSERT(conn->handler->done);
+ /* we ignore the return code for the protocol-specific DONE */
+ (void)conn->handler->done(conn, result, FALSE);
+ goto out;
+ }
+
+ Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
+ -1, NULL); /* no upload */
+ }
+
+ /* since we skip do_init() */
+ Curl_init_do(data, conn);
+
+ goto out;
+ }
+#endif
+
+ /* Get a cloned copy of the SSL config situation stored in the
+ connection struct. But to get this going nicely, we must first make
+ sure that the strings in the master copy are pointing to the correct
+ strings in the session handle strings array!
+
+ Keep in mind that the pointers in the master copy are pointing to strings
+ that will be freed as part of the SessionHandle struct, but all cloned
+ copies will be separately allocated.
+ */
+ data->set.ssl.CApath = data->set.str[STRING_SSL_CAPATH];
+ data->set.ssl.CAfile = data->set.str[STRING_SSL_CAFILE];
+ data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE];
+ data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT];
+ data->set.ssl.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
+ data->set.ssl.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
+ data->set.ssl.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST];
+#ifdef USE_TLS_SRP
+ data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME];
+ data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD];
+#endif
+
+ if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config)) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto out;
+ }
+
+ prune_dead_connections(data);
+
+ /*************************************************************
+ * Check the current list of connections to see if we can
+ * re-use an already existing one or if we have to create a
+ * new one.
+ *************************************************************/
+
+ /* reuse_fresh is TRUE if we are told to use a new connection by force, but
+ we only acknowledge this option if this is not a re-used connection
+ already (which happens due to follow-location or during a HTTP
+ authentication phase). */
+ if(data->set.reuse_fresh && !data->state.this_is_a_follow)
+ reuse = FALSE;
+ else
+ reuse = ConnectionExists(data, conn, &conn_temp, &force_reuse, &waitpipe);
+
+ /* If we found a reusable connection, we may still want to
+ open a new connection if we are pipelining. */
+ if(reuse && !force_reuse && IsPipeliningPossible(data, conn_temp)) {
+ size_t pipelen = conn_temp->send_pipe->size + conn_temp->recv_pipe->size;
+ if(pipelen > 0) {
+ infof(data, "Found connection %ld, with requests in the pipe (%zu)\n",
+ conn_temp->connection_id, pipelen);
+
+ if(conn_temp->bundle->num_connections < max_host_connections &&
+ data->state.conn_cache->num_connections < max_total_connections) {
+ /* We want a new connection anyway */
+ reuse = FALSE;
+
+ infof(data, "We can reuse, but we want a new connection anyway\n");
+ }
+ }
+ }
+
+ if(reuse) {
+ /*
+ * We already have a connection for this, we got the former connection
+ * in the conn_temp variable and thus we need to cleanup the one we
+ * just allocated before we can move along and use the previously
+ * existing one.
+ */
+ conn_temp->inuse = TRUE; /* mark this as being in use so that no other
+ handle in a multi stack may nick it */
+ reuse_conn(conn, conn_temp);
+ free(conn); /* we don't need this anymore */
+ conn = conn_temp;
+ *in_connect = conn;
+
+ /* set a pointer to the hostname we display */
+ fix_hostname(data, conn, &conn->host);
+
+ infof(data, "Re-using existing connection! (#%ld) with %s %s\n",
+ conn->connection_id,
+ conn->bits.proxy?"proxy":"host",
+ conn->proxy.name?conn->proxy.dispname:conn->host.dispname);
+ }
+ else {
+ /* We have decided that we want a new connection. However, we may not
+ be able to do that if we have reached the limit of how many
+ connections we are allowed to open. */
+ struct connectbundle *bundle = NULL;
+
+ if(waitpipe)
+ /* There is a connection that *might* become usable for pipelining
+ "soon", and we wait for that */
+ connections_available = FALSE;
+ else
+ bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache);
+
+ if(max_host_connections > 0 && bundle &&
+ (bundle->num_connections >= max_host_connections)) {
+ struct connectdata *conn_candidate;
+
+ /* The bundle is full. Let's see if we can kill a connection. */
+ conn_candidate = find_oldest_idle_connection_in_bundle(data, bundle);
+
+ if(conn_candidate) {
+ /* Set the connection's owner correctly, then kill it */
+ conn_candidate->data = data;
+ (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
+ }
+ else {
+ infof(data, "No more connections allowed to host: %d\n",
+ max_host_connections);
+ connections_available = FALSE;
+ }
+ }
+
+ if(connections_available &&
+ (max_total_connections > 0) &&
+ (data->state.conn_cache->num_connections >= max_total_connections)) {
+ struct connectdata *conn_candidate;
+
+ /* The cache is full. Let's see if we can kill a connection. */
+ conn_candidate = find_oldest_idle_connection(data);
+
+ if(conn_candidate) {
+ /* Set the connection's owner correctly, then kill it */
+ conn_candidate->data = data;
+ (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
+ }
+ else {
+ infof(data, "No connections available in cache\n");
+ connections_available = FALSE;
+ }
+ }
+
+ if(!connections_available) {
+ infof(data, "No connections available.\n");
+
+ conn_free(conn);
+ *in_connect = NULL;
+
+ result = CURLE_NO_CONNECTION_AVAILABLE;
+ goto out;
+ }
+ else {
+ /*
+ * This is a brand new connection, so let's store it in the connection
+ * cache of ours!
+ */
+ Curl_conncache_add_conn(data->state.conn_cache, conn);
+ }
+
+#if defined(USE_NTLM)
+ /* If NTLM is requested in a part of this connection, make sure we don't
+ assume the state is fine as this is a fresh connection and NTLM is
+ connection based. */
+ if((data->state.authhost.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
+ data->state.authhost.done) {
+ infof(data, "NTLM picked AND auth done set, clear picked!\n");
+ data->state.authhost.picked = CURLAUTH_NONE;
+ }
+
+ if((data->state.authproxy.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
+ data->state.authproxy.done) {
+ infof(data, "NTLM-proxy picked AND auth done set, clear picked!\n");
+ data->state.authproxy.picked = CURLAUTH_NONE;
+ }
+#endif
+ }
+
+ /* Mark the connection as used */
+ conn->inuse = TRUE;
+
+ /* Setup and init stuff before DO starts, in preparing for the transfer. */
+ Curl_init_do(data, conn);
+
+ /*
+ * Setup whatever necessary for a resumed transfer
+ */
+ result = setup_range(data);
+ if(result)
+ goto out;
+
+ /* Continue connectdata initialization here. */
+
+ /*
+ * Inherit the proper values from the urldata struct AFTER we have arranged
+ * the persistent connection stuff
+ */
+ conn->seek_func = data->set.seek_func;
+ conn->seek_client = data->set.seek_client;
+
+ /*************************************************************
+ * Resolve the address of the server or proxy
+ *************************************************************/
+ result = resolve_server(data, conn, async);
+
+ out:
+
+ free(options);
+ free(passwd);
+ free(user);
+ free(proxy);
+ return result;
+}
+
+/* Curl_setup_conn() is called after the name resolve initiated in
+ * create_conn() is all done.
+ *
+ * Curl_setup_conn() also handles reused connections
+ *
+ * conn->data MUST already have been setup fine (in create_conn)
+ */
+
+CURLcode Curl_setup_conn(struct connectdata *conn,
+ bool *protocol_done)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+
+ Curl_pgrsTime(data, TIMER_NAMELOOKUP);
+
+ if(conn->handler->flags & PROTOPT_NONETWORK) {
+ /* nothing to setup when not using a network */
+ *protocol_done = TRUE;
+ return result;
+ }
+ *protocol_done = FALSE; /* default to not done */
+
+ /* set proxy_connect_closed to false unconditionally already here since it
+ is used strictly to provide extra information to a parent function in the
+ case of proxy CONNECT failures and we must make sure we don't have it
+ lingering set from a previous invoke */
+ conn->bits.proxy_connect_closed = FALSE;
+
+ /*
+ * Set user-agent. Used for HTTP, but since we can attempt to tunnel
+ * basically anything through a http proxy we can't limit this based on
+ * protocol.
+ */
+ if(data->set.str[STRING_USERAGENT]) {
+ Curl_safefree(conn->allocptr.uagent);
+ conn->allocptr.uagent =
+ aprintf("User-Agent: %s\r\n", data->set.str[STRING_USERAGENT]);
+ if(!conn->allocptr.uagent)
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ data->req.headerbytecount = 0;
+
+#ifdef CURL_DO_LINEEND_CONV
+ data->state.crlf_conversions = 0; /* reset CRLF conversion counter */
+#endif /* CURL_DO_LINEEND_CONV */
+
+ /* set start time here for timeout purposes in the connect procedure, it
+ is later set again for the progress meter purpose */
+ conn->now = Curl_tvnow();
+
+ if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
+ conn->bits.tcpconnect[FIRSTSOCKET] = FALSE;
+ result = Curl_connecthost(conn, conn->dns_entry);
+ if(result)
+ return result;
+ }
+ else {
+ Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
+ Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */
+ conn->bits.tcpconnect[FIRSTSOCKET] = TRUE;
+ *protocol_done = TRUE;
+ Curl_updateconninfo(conn, conn->sock[FIRSTSOCKET]);
+ Curl_verboseconnect(conn);
+ }
+
+ conn->now = Curl_tvnow(); /* time this *after* the connect is done, we
+ set this here perhaps a second time */
+
+#ifdef __EMX__
+ /*
+ * This check is quite a hack. We're calling _fsetmode to fix the problem
+ * with fwrite converting newline characters (you get mangled text files,
+ * and corrupted binary files when you download to stdout and redirect it to
+ * a file).
+ */
+
+ if((data->set.out)->_handle == NULL) {
+ _fsetmode(stdout, "b");
+ }
+#endif
+
+ return result;
+}
+
+CURLcode Curl_connect(struct SessionHandle *data,
+ struct connectdata **in_connect,
+ bool *asyncp,
+ bool *protocol_done)
+{
+ CURLcode result;
+
+ *asyncp = FALSE; /* assume synchronous resolves by default */
+
+ /* call the stuff that needs to be called */
+ result = create_conn(data, in_connect, asyncp);
+
+ if(!result) {
+ /* no error */
+ if((*in_connect)->send_pipe->size || (*in_connect)->recv_pipe->size)
+ /* pipelining */
+ *protocol_done = TRUE;
+ else if(!*asyncp) {
+ /* DNS resolution is done: that's either because this is a reused
+ connection, in which case DNS was unnecessary, or because DNS
+ really did finish already (synch resolver/fast async resolve) */
+ result = Curl_setup_conn(*in_connect, protocol_done);
+ }
+ }
+
+ if(result == CURLE_NO_CONNECTION_AVAILABLE) {
+ *in_connect = NULL;
+ return result;
+ }
+
+ if(result && *in_connect) {
+ /* We're not allowed to return failure with memory left allocated
+ in the connectdata struct, free those here */
+ Curl_disconnect(*in_connect, FALSE); /* close the connection */
+ *in_connect = NULL; /* return a NULL */
+ }
+
+ return result;
+}
+
+CURLcode Curl_done(struct connectdata **connp,
+ CURLcode status, /* an error if this is called after an
+ error was detected */
+ bool premature)
+{
+ CURLcode result;
+ struct connectdata *conn;
+ struct SessionHandle *data;
+
+ DEBUGASSERT(*connp);
+
+ conn = *connp;
+ data = conn->data;
+
+ DEBUGF(infof(data, "Curl_done\n"));
+
+ if(data->state.done)
+ /* Stop if Curl_done() has already been called */
+ return CURLE_OK;
+
+ Curl_getoff_all_pipelines(data, conn);
+
+ /* Cleanup possible redirect junk */
+ free(data->req.newurl);
+ data->req.newurl = NULL;
+ free(data->req.location);
+ data->req.location = NULL;
+
+ switch(status) {
+ case CURLE_ABORTED_BY_CALLBACK:
+ case CURLE_READ_ERROR:
+ case CURLE_WRITE_ERROR:
+ /* When we're aborted due to a callback return code it basically have to
+ be counted as premature as there is trouble ahead if we don't. We have
+ many callbacks and protocols work differently, we could potentially do
+ this more fine-grained in the future. */
+ premature = TRUE;
+ default:
+ break;
+ }
+
+ /* this calls the protocol-specific function pointer previously set */
+ if(conn->handler->done)
+ result = conn->handler->done(conn, status, premature);
+ else
+ result = status;
+
+ if(!result && Curl_pgrsDone(conn))
+ result = CURLE_ABORTED_BY_CALLBACK;
+
+ if((conn->send_pipe->size + conn->recv_pipe->size != 0 &&
+ !data->set.reuse_forbid &&
+ !conn->bits.close)) {
+ /* Stop if pipeline is not empty and we do not have to close
+ connection. */
+ DEBUGF(infof(data, "Connection still in use, no more Curl_done now!\n"));
+ return CURLE_OK;
+ }
+
+ data->state.done = TRUE; /* called just now! */
+ Curl_resolver_cancel(conn);
+
+ if(conn->dns_entry) {
+ Curl_resolv_unlock(data, conn->dns_entry); /* done with this */
+ conn->dns_entry = NULL;
+ }
+
+ /* if the transfer was completed in a paused state there can be buffered
+ data left to write and then kill */
+ free(data->state.tempwrite);
+ data->state.tempwrite = NULL;
+
+ /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
+ forced us to close this connection. This is ignored for requests taking
+ place in a NTLM authentication handshake
+
+ if conn->bits.close is TRUE, it means that the connection should be
+ closed in spite of all our efforts to be nice, due to protocol
+ restrictions in our or the server's end
+
+ if premature is TRUE, it means this connection was said to be DONE before
+ the entire request operation is complete and thus we can't know in what
+ state it is for re-using, so we're forced to close it. In a perfect world
+ we can add code that keep track of if we really must close it here or not,
+ but currently we have no such detail knowledge.
+ */
+
+ if((data->set.reuse_forbid
+#if defined(USE_NTLM)
+ && !(conn->ntlm.state == NTLMSTATE_TYPE2 ||
+ conn->proxyntlm.state == NTLMSTATE_TYPE2)
+#endif
+ ) || conn->bits.close || premature) {
+ CURLcode res2 = Curl_disconnect(conn, premature); /* close connection */
+
+ /* If we had an error already, make sure we return that one. But
+ if we got a new error, return that. */
+ if(!result && res2)
+ result = res2;
+ }
+ else {
+ /* the connection is no longer in use */
+ if(ConnectionDone(data, conn)) {
+ /* remember the most recently used connection */
+ data->state.lastconnect = conn;
+
+ infof(data, "Connection #%ld to host %s left intact\n",
+ conn->connection_id,
+ conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
+ }
+ else
+ data->state.lastconnect = NULL;
+ }
+
+ *connp = NULL; /* to make the caller of this function better detect that
+ this was either closed or handed over to the connection
+ cache here, and therefore cannot be used from this point on
+ */
+ Curl_free_request_state(data);
+
+ return result;
+}
+
+/*
+ * Curl_init_do() inits the readwrite session. This is inited each time (in
+ * the DO function before the protocol-specific DO functions are invoked) for
+ * a transfer, sometimes multiple times on the same SessionHandle. Make sure
+ * nothing in here depends on stuff that are setup dynamically for the
+ * transfer.
+ *
+ * Allow this function to get called with 'conn' set to NULL.
+ */
+
+CURLcode Curl_init_do(struct SessionHandle *data, struct connectdata *conn)
+{
+ struct SingleRequest *k = &data->req;
+
+ if(conn)
+ conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to
+ * use */
+
+ data->state.done = FALSE; /* Curl_done() is not called yet */
+ data->state.expect100header = FALSE;
+
+ if(data->set.opt_no_body)
+ /* in HTTP lingo, no body means using the HEAD request... */
+ data->set.httpreq = HTTPREQ_HEAD;
+ else if(HTTPREQ_HEAD == data->set.httpreq)
+ /* ... but if unset there really is no perfect method that is the
+ "opposite" of HEAD but in reality most people probably think GET
+ then. The important thing is that we can't let it remain HEAD if the
+ opt_no_body is set FALSE since then we'll behave wrong when getting
+ HTTP. */
+ data->set.httpreq = HTTPREQ_GET;
+
+ k->start = Curl_tvnow(); /* start time */
+ k->now = k->start; /* current time is now */
+ k->header = TRUE; /* assume header */
+
+ k->bytecount = 0;
+
+ k->buf = data->state.buffer;
+ k->uploadbuf = data->state.uploadbuffer;
+ k->hbufp = data->state.headerbuff;
+ k->ignorebody=FALSE;
+
+ Curl_speedinit(data);
+
+ Curl_pgrsSetUploadCounter(data, 0);
+ Curl_pgrsSetDownloadCounter(data, 0);
+
+ return CURLE_OK;
+}
+
+/*
+ * do_complete is called when the DO actions are complete.
+ *
+ * We init chunking and trailer bits to their default values here immediately
+ * before receiving any header data for the current request in the pipeline.
+ */
+static void do_complete(struct connectdata *conn)
+{
+ conn->data->req.chunk=FALSE;
+ conn->data->req.maxfd = (conn->sockfd>conn->writesockfd?
+ conn->sockfd:conn->writesockfd)+1;
+ Curl_pgrsTime(conn->data, TIMER_PRETRANSFER);
+}
+
+CURLcode Curl_do(struct connectdata **connp, bool *done)
+{
+ CURLcode result=CURLE_OK;
+ struct connectdata *conn = *connp;
+ struct SessionHandle *data = conn->data;
+
+ if(conn->handler->do_it) {
+ /* generic protocol-specific function pointer set in curl_connect() */
+ result = conn->handler->do_it(conn, done);
+
+ /* This was formerly done in transfer.c, but we better do it here */
+ if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
+ /*
+ * If the connection is using an easy handle, call reconnect
+ * to re-establish the connection. Otherwise, let the multi logic
+ * figure out how to re-establish the connection.
+ */
+ if(!data->multi) {
+ result = Curl_reconnect_request(connp);
+
+ if(!result) {
+ /* ... finally back to actually retry the DO phase */
+ conn = *connp; /* re-assign conn since Curl_reconnect_request
+ creates a new connection */
+ result = conn->handler->do_it(conn, done);
+ }
+ }
+ else
+ return result;
+ }
+
+ if(!result && *done)
+ /* do_complete must be called after the protocol-specific DO function */
+ do_complete(conn);
+ }
+ return result;
+}
+
+/*
+ * Curl_do_more() is called during the DO_MORE multi state. It is basically a
+ * second stage DO state which (wrongly) was introduced to support FTP's
+ * second connection.
+ *
+ * TODO: A future libcurl should be able to work away this state.
+ *
+ * 'complete' can return 0 for incomplete, 1 for done and -1 for go back to
+ * DOING state there's more work to do!
+ */
+
+CURLcode Curl_do_more(struct connectdata *conn, int *complete)
+{
+ CURLcode result=CURLE_OK;
+
+ *complete = 0;
+
+ if(conn->handler->do_more)
+ result = conn->handler->do_more(conn, complete);
+
+ if(!result && (*complete == 1))
+ /* do_complete must be called after the protocol-specific DO function */
+ do_complete(conn);
+
+ return result;
+}
diff --git a/Utilities/cmcurl/lib/url.h b/Utilities/cmcurl/lib/url.h
new file mode 100644
index 000000000..f9667cbc3
--- /dev/null
+++ b/Utilities/cmcurl/lib/url.h
@@ -0,0 +1,86 @@
+#ifndef HEADER_CURL_URL_H
+#define HEADER_CURL_URL_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+/*
+ * Prototypes for library-wide functions provided by url.c
+ */
+
+CURLcode Curl_init_do(struct SessionHandle *data, struct connectdata *conn);
+CURLcode Curl_open(struct SessionHandle **curl);
+CURLcode Curl_init_userdefined(struct UserDefined *set);
+CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
+ va_list arg);
+CURLcode Curl_dupset(struct SessionHandle * dst, struct SessionHandle * src);
+void Curl_freeset(struct SessionHandle * data);
+CURLcode Curl_close(struct SessionHandle *data); /* opposite of curl_open() */
+CURLcode Curl_connect(struct SessionHandle *, struct connectdata **,
+ bool *async, bool *protocol_connect);
+CURLcode Curl_do(struct connectdata **, bool *done);
+CURLcode Curl_do_more(struct connectdata *, int *completed);
+CURLcode Curl_done(struct connectdata **, CURLcode, bool premature);
+CURLcode Curl_disconnect(struct connectdata *, bool dead_connection);
+CURLcode Curl_protocol_connect(struct connectdata *conn, bool *done);
+CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done);
+CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done);
+CURLcode Curl_setup_conn(struct connectdata *conn,
+ bool *protocol_done);
+void Curl_free_request_state(struct SessionHandle *data);
+
+int Curl_protocol_getsock(struct connectdata *conn,
+ curl_socket_t *socks,
+ int numsocks);
+int Curl_doing_getsock(struct connectdata *conn,
+ curl_socket_t *socks,
+ int numsocks);
+
+bool Curl_isPipeliningEnabled(const struct SessionHandle *handle);
+CURLcode Curl_addHandleToPipeline(struct SessionHandle *handle,
+ struct curl_llist *pipeline);
+int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
+ struct curl_llist *pipeline);
+/* remove the specified connection from all (possible) pipelines and related
+ queues */
+void Curl_getoff_all_pipelines(struct SessionHandle *data,
+ struct connectdata *conn);
+
+void Curl_close_connections(struct SessionHandle *data);
+
+#define CURL_DEFAULT_PROXY_PORT 1080 /* default proxy port unless specified */
+#define CURL_DEFAULT_SOCKS5_GSSAPI_SERVICE "rcmd" /* default socks5 gssapi
+ service */
+#define CURL_DEFAULT_PROXY_SERVICE_NAME "HTTP" /* default negotiate proxy
+ service */
+#define CURL_DEFAULT_SERVICE_NAME "HTTP" /* default negotiate service */
+
+CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex);
+
+#ifdef CURL_DISABLE_VERBOSE_STRINGS
+#define Curl_verboseconnect(x) Curl_nop_stmt
+#else
+void Curl_verboseconnect(struct connectdata *conn);
+#endif
+
+
+#endif /* HEADER_CURL_URL_H */
diff --git a/Utilities/cmcurl/lib/urldata.h b/Utilities/cmcurl/lib/urldata.h
new file mode 100644
index 000000000..b1c2056c5
--- /dev/null
+++ b/Utilities/cmcurl/lib/urldata.h
@@ -0,0 +1,1703 @@
+#ifndef HEADER_CURL_URLDATA_H
+#define HEADER_CURL_URLDATA_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* This file is for lib internal stuff */
+
+#include "curl_setup.h"
+
+#define PORT_FTP 21
+#define PORT_FTPS 990
+#define PORT_TELNET 23
+#define PORT_HTTP 80
+#define PORT_HTTPS 443
+#define PORT_DICT 2628
+#define PORT_LDAP 389
+#define PORT_LDAPS 636
+#define PORT_TFTP 69
+#define PORT_SSH 22
+#define PORT_IMAP 143
+#define PORT_IMAPS 993
+#define PORT_POP3 110
+#define PORT_POP3S 995
+#define PORT_SMB 445
+#define PORT_SMBS 445
+#define PORT_SMTP 25
+#define PORT_SMTPS 465 /* sometimes called SSMTP */
+#define PORT_RTSP 554
+#define PORT_RTMP 1935
+#define PORT_RTMPT PORT_HTTP
+#define PORT_RTMPS PORT_HTTPS
+#define PORT_GOPHER 70
+
+#define DICT_MATCH "/MATCH:"
+#define DICT_MATCH2 "/M:"
+#define DICT_MATCH3 "/FIND:"
+#define DICT_DEFINE "/DEFINE:"
+#define DICT_DEFINE2 "/D:"
+#define DICT_DEFINE3 "/LOOKUP:"
+
+#define CURL_DEFAULT_USER "anonymous"
+#define CURL_DEFAULT_PASSWORD "ftp@example.com"
+
+/* Convenience defines for checking protocols or their SSL based version. Each
+ protocol handler should only ever have a single CURLPROTO_ in its protocol
+ field. */
+#define PROTO_FAMILY_HTTP (CURLPROTO_HTTP|CURLPROTO_HTTPS)
+#define PROTO_FAMILY_FTP (CURLPROTO_FTP|CURLPROTO_FTPS)
+#define PROTO_FAMILY_POP3 (CURLPROTO_POP3|CURLPROTO_POP3S)
+#define PROTO_FAMILY_SMB (CURLPROTO_SMB|CURLPROTO_SMBS)
+#define PROTO_FAMILY_SMTP (CURLPROTO_SMTP|CURLPROTO_SMTPS)
+
+#define DEFAULT_CONNCACHE_SIZE 5
+
+/* length of longest IPv6 address string including the trailing null */
+#define MAX_IPADR_LEN sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")
+
+/* Default FTP/IMAP etc response timeout in milliseconds.
+ Symbian OS panics when given a timeout much greater than 1/2 hour.
+*/
+#define RESP_TIMEOUT (1800*1000)
+
+#include "cookie.h"
+#include "formdata.h"
+
+#ifdef USE_OPENSSL
+#include <openssl/ssl.h>
+#ifdef HAVE_OPENSSL_ENGINE_H
+#include <openssl/engine.h>
+#endif
+#endif /* USE_OPENSSL */
+
+#ifdef USE_GNUTLS
+#include <gnutls/gnutls.h>
+#endif
+
+#ifdef USE_POLARSSL
+#include <polarssl/ssl.h>
+#include <polarssl/version.h>
+#if POLARSSL_VERSION_NUMBER<0x01010000
+#include <polarssl/havege.h>
+#else
+#include <polarssl/entropy.h>
+#include <polarssl/ctr_drbg.h>
+#endif /* POLARSSL_VERSION_NUMBER<0x01010000 */
+#endif /* USE_POLARSSL */
+
+#ifdef USE_CYASSL
+#undef OCSP_REQUEST /* avoid cyassl/openssl/ssl.h clash with wincrypt.h */
+#undef OCSP_RESPONSE /* avoid cyassl/openssl/ssl.h clash with wincrypt.h */
+#include <cyassl/openssl/ssl.h>
+#endif
+
+#ifdef USE_NSS
+#include <nspr.h>
+#include <pk11pub.h>
+#endif
+
+#ifdef USE_GSKIT
+#include <gskssl.h>
+#endif
+
+#ifdef USE_AXTLS
+#include <axTLS/config.h>
+#include <axTLS/ssl.h>
+#undef malloc
+#undef calloc
+#undef realloc
+#endif /* USE_AXTLS */
+
+#ifdef USE_SCHANNEL
+#include "curl_sspi.h"
+#include <schnlsp.h>
+#include <schannel.h>
+#endif
+
+#ifdef USE_DARWINSSL
+#include <Security/Security.h>
+/* For some reason, when building for iOS, the omnibus header above does
+ * not include SecureTransport.h as of iOS SDK 5.1. */
+#include <Security/SecureTransport.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#include "timeval.h"
+
+#ifdef HAVE_ZLIB_H
+#include <zlib.h> /* for content-encoding */
+#ifdef __SYMBIAN32__
+/* zlib pollutes the namespace with this definition */
+#undef WIN32
+#endif
+#endif
+
+#include <curl/curl.h>
+
+#include "http_chunks.h" /* for the structs and enum stuff */
+#include "hostip.h"
+#include "hash.h"
+#include "splay.h"
+
+#include "imap.h"
+#include "pop3.h"
+#include "smtp.h"
+#include "ftp.h"
+#include "file.h"
+#include "ssh.h"
+#include "http.h"
+#include "rtsp.h"
+#include "smb.h"
+#include "wildcard.h"
+#include "multihandle.h"
+
+#ifdef HAVE_GSSAPI
+# ifdef HAVE_GSSGNU
+# include <gss.h>
+# elif defined HAVE_GSSMIT
+# include <gssapi/gssapi.h>
+# include <gssapi/gssapi_generic.h>
+# else
+# include <gssapi.h>
+# endif
+#endif
+
+#ifdef HAVE_LIBSSH2_H
+#include <libssh2.h>
+#include <libssh2_sftp.h>
+#endif /* HAVE_LIBSSH2_H */
+
+/* Download buffer size, keep it fairly big for speed reasons */
+#undef BUFSIZE
+#define BUFSIZE CURL_MAX_WRITE_SIZE
+
+/* Initial size of the buffer to store headers in, it'll be enlarged in case
+ of need. */
+#define HEADERSIZE 256
+
+#define CURLEASY_MAGIC_NUMBER 0xc0dedbadU
+#define GOOD_EASY_HANDLE(x) \
+ ((x) && (((struct SessionHandle *)(x))->magic == CURLEASY_MAGIC_NUMBER))
+
+/* Some convenience macros to get the larger/smaller value out of two given.
+ We prefix with CURL to prevent name collisions. */
+#define CURLMAX(x,y) ((x)>(y)?(x):(y))
+#define CURLMIN(x,y) ((x)<(y)?(x):(y))
+
+
+#ifdef HAVE_GSSAPI
+/* Types needed for krb5-ftp connections */
+struct krb5buffer {
+ void *data;
+ size_t size;
+ size_t index;
+ int eof_flag;
+};
+
+enum protection_level {
+ PROT_NONE, /* first in list */
+ PROT_CLEAR,
+ PROT_SAFE,
+ PROT_CONFIDENTIAL,
+ PROT_PRIVATE,
+ PROT_CMD,
+ PROT_LAST /* last in list */
+};
+#endif
+
+#ifdef USE_SCHANNEL
+/* Structs to store Schannel handles */
+struct curl_schannel_cred {
+ CredHandle cred_handle;
+ TimeStamp time_stamp;
+ int refcount;
+ bool cached;
+};
+
+struct curl_schannel_ctxt {
+ CtxtHandle ctxt_handle;
+ TimeStamp time_stamp;
+};
+#endif
+
+/* enum for the nonblocking SSL connection state machine */
+typedef enum {
+ ssl_connect_1,
+ ssl_connect_2,
+ ssl_connect_2_reading,
+ ssl_connect_2_writing,
+ ssl_connect_3,
+ ssl_connect_done
+} ssl_connect_state;
+
+typedef enum {
+ ssl_connection_none,
+ ssl_connection_negotiating,
+ ssl_connection_complete
+} ssl_connection_state;
+
+/* struct for data related to each SSL connection */
+struct ssl_connect_data {
+ /* Use ssl encrypted communications TRUE/FALSE, not necessarily using it atm
+ but at least asked to or meaning to use it. See 'state' for the exact
+ current state of the connection. */
+ bool use;
+ ssl_connection_state state;
+#ifdef USE_OPENSSL
+ /* these ones requires specific SSL-types */
+ SSL_CTX* ctx;
+ SSL* handle;
+ X509* server_cert;
+ ssl_connect_state connecting_state;
+#endif /* USE_OPENSSL */
+#ifdef USE_GNUTLS
+ gnutls_session_t session;
+ gnutls_certificate_credentials_t cred;
+#ifdef USE_TLS_SRP
+ gnutls_srp_client_credentials_t srp_client_cred;
+#endif
+ ssl_connect_state connecting_state;
+#endif /* USE_GNUTLS */
+#ifdef USE_POLARSSL
+ ctr_drbg_context ctr_drbg;
+ entropy_context entropy;
+ ssl_context ssl;
+ ssl_session ssn;
+ int server_fd;
+ x509_crt cacert;
+ x509_crt clicert;
+ x509_crl crl;
+ rsa_context rsa;
+ ssl_connect_state connecting_state;
+#endif /* USE_POLARSSL */
+#ifdef USE_CYASSL
+ SSL_CTX* ctx;
+ SSL* handle;
+ ssl_connect_state connecting_state;
+#endif /* USE_CYASSL */
+#ifdef USE_NSS
+ PRFileDesc *handle;
+ char *client_nickname;
+ struct SessionHandle *data;
+ struct curl_llist *obj_list;
+ PK11GenericObject *obj_clicert;
+ ssl_connect_state connecting_state;
+#endif /* USE_NSS */
+#ifdef USE_GSKIT
+ gsk_handle handle;
+ int iocport;
+ ssl_connect_state connecting_state;
+#endif
+#ifdef USE_AXTLS
+ SSL_CTX* ssl_ctx;
+ SSL* ssl;
+ ssl_connect_state connecting_state;
+#endif /* USE_AXTLS */
+#ifdef USE_SCHANNEL
+ struct curl_schannel_cred *cred;
+ struct curl_schannel_ctxt *ctxt;
+ SecPkgContext_StreamSizes stream_sizes;
+ ssl_connect_state connecting_state;
+ size_t encdata_length, decdata_length;
+ size_t encdata_offset, decdata_offset;
+ unsigned char *encdata_buffer, *decdata_buffer;
+ unsigned long req_flags, ret_flags;
+ CURLcode recv_unrecoverable_err; /* schannel_recv had an unrecoverable err */
+ bool recv_sspi_close_notify; /* true if connection closed by close_notify */
+ bool recv_connection_closed; /* true if connection closed, regardless how */
+#endif /* USE_SCHANNEL */
+#ifdef USE_DARWINSSL
+ SSLContextRef ssl_ctx;
+ curl_socket_t ssl_sockfd;
+ ssl_connect_state connecting_state;
+ bool ssl_direction; /* true if writing, false if reading */
+ size_t ssl_write_buffered_length;
+#endif /* USE_DARWINSSL */
+};
+
+struct ssl_config_data {
+ long version; /* what version the client wants to use */
+ long certverifyresult; /* result from the certificate verification */
+
+ bool verifypeer; /* set TRUE if this is desired */
+ bool verifyhost; /* set TRUE if CN/SAN must match hostname */
+ bool verifystatus; /* set TRUE if certificate status must be checked */
+ char *CApath; /* certificate dir (doesn't work on windows) */
+ char *CAfile; /* certificate to verify peer against */
+ const char *CRLfile; /* CRL to check certificate revocation */
+ const char *issuercert;/* optional issuer certificate filename */
+ char *random_file; /* path to file containing "random" data */
+ char *egdsocket; /* path to file containing the EGD daemon socket */
+ char *cipher_list; /* list of ciphers to use */
+ size_t max_ssl_sessions; /* SSL session id cache size */
+ curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */
+ void *fsslctxp; /* parameter for call back */
+ bool sessionid; /* cache session IDs or not */
+ bool certinfo; /* gather lots of certificate info */
+ bool falsestart;
+
+#ifdef USE_TLS_SRP
+ char *username; /* TLS username (for, e.g., SRP) */
+ char *password; /* TLS password (for, e.g., SRP) */
+ enum CURL_TLSAUTH authtype; /* TLS authentication type (default SRP) */
+#endif
+};
+
+/* information stored about one single SSL session */
+struct curl_ssl_session {
+ char *name; /* host name for which this ID was used */
+ void *sessionid; /* as returned from the SSL layer */
+ size_t idsize; /* if known, otherwise 0 */
+ long age; /* just a number, the higher the more recent */
+ int remote_port; /* remote port to connect to */
+ struct ssl_config_data ssl_config; /* setup for this session */
+};
+
+/* Struct used for Digest challenge-response authentication */
+struct digestdata {
+#if defined(USE_WINDOWS_SSPI)
+ BYTE *input_token;
+ size_t input_token_len;
+#else
+ char *nonce;
+ char *cnonce;
+ char *realm;
+ int algo;
+ bool stale; /* set true for re-negotiation */
+ char *opaque;
+ char *qop;
+ char *algorithm;
+ int nc; /* nounce count */
+#endif
+};
+
+typedef enum {
+ NTLMSTATE_NONE,
+ NTLMSTATE_TYPE1,
+ NTLMSTATE_TYPE2,
+ NTLMSTATE_TYPE3,
+ NTLMSTATE_LAST
+} curlntlm;
+
+#ifdef USE_WINDOWS_SSPI
+#include "curl_sspi.h"
+#endif
+
+#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
+#include <iconv.h>
+#endif
+
+/* Struct used for GSSAPI (Kerberos V5) authentication */
+#if defined(USE_KERBEROS5)
+struct kerberos5data {
+#if defined(USE_WINDOWS_SSPI)
+ CredHandle *credentials;
+ CtxtHandle *context;
+ TCHAR *spn;
+ SEC_WINNT_AUTH_IDENTITY identity;
+ SEC_WINNT_AUTH_IDENTITY *p_identity;
+ size_t token_max;
+ BYTE *output_token;
+#else
+ gss_ctx_id_t context;
+ gss_name_t spn;
+#endif
+};
+#endif
+
+/* Struct used for NTLM challenge-response authentication */
+#if defined(USE_NTLM)
+struct ntlmdata {
+ curlntlm state;
+#ifdef USE_WINDOWS_SSPI
+ CredHandle *credentials;
+ CtxtHandle *context;
+ SEC_WINNT_AUTH_IDENTITY identity;
+ SEC_WINNT_AUTH_IDENTITY *p_identity;
+ size_t token_max;
+ BYTE *output_token;
+ BYTE *input_token;
+ size_t input_token_len;
+#else
+ unsigned int flags;
+ unsigned char nonce[8];
+ void* target_info; /* TargetInfo received in the ntlm type-2 message */
+ unsigned int target_info_len;
+#endif
+};
+#endif
+
+#ifdef USE_SPNEGO
+struct negotiatedata {
+ /* When doing Negotiate (SPNEGO) auth, we first need to send a token
+ and then validate the received one. */
+ enum { GSS_AUTHNONE, GSS_AUTHRECV, GSS_AUTHSENT } state;
+#ifdef HAVE_GSSAPI
+ OM_uint32 status;
+ gss_ctx_id_t context;
+ gss_name_t server_name;
+ gss_buffer_desc output_token;
+#else
+#ifdef USE_WINDOWS_SSPI
+ DWORD status;
+ CredHandle *credentials;
+ CtxtHandle *context;
+ SEC_WINNT_AUTH_IDENTITY identity;
+ SEC_WINNT_AUTH_IDENTITY *p_identity;
+ TCHAR *server_name;
+ size_t token_max;
+ BYTE *output_token;
+ size_t output_token_length;
+#endif
+#endif
+};
+#endif
+
+
+/*
+ * Boolean values that concerns this connection.
+ */
+struct ConnectBits {
+ /* always modify bits.close with the connclose() and connkeep() macros! */
+ bool close; /* if set, we close the connection after this request */
+ bool reuse; /* if set, this is a re-used connection */
+ bool proxy; /* if set, this transfer is done through a proxy - any type */
+ bool httpproxy; /* if set, this transfer is done through a http proxy */
+ bool user_passwd; /* do we use user+password for this connection? */
+ bool proxy_user_passwd; /* user+password for the proxy? */
+ bool ipv6_ip; /* we communicate with a remote site specified with pure IPv6
+ IP address */
+ bool ipv6; /* we communicate with a site using an IPv6 address */
+
+ bool do_more; /* this is set TRUE if the ->curl_do_more() function is
+ supposed to be called, after ->curl_do() */
+ bool tcpconnect[2]; /* the TCP layer (or similar) is connected, this is set
+ the first time on the first connect function call */
+ bool protoconnstart;/* the protocol layer has STARTED its operation after
+ the TCP layer connect */
+
+ bool retry; /* this connection is about to get closed and then
+ re-attempted at another connection. */
+ bool tunnel_proxy; /* if CONNECT is used to "tunnel" through the proxy.
+ This is implicit when SSL-protocols are used through
+ proxies, but can also be enabled explicitly by
+ apps */
+ bool authneg; /* TRUE when the auth phase has started, which means
+ that we are creating a request with an auth header,
+ but it is not the final request in the auth
+ negotiation. */
+ bool rewindaftersend;/* TRUE when the sending couldn't be stopped even
+ though it will be discarded. When the whole send
+ operation is done, we must call the data rewind
+ callback. */
+ bool ftp_use_epsv; /* As set with CURLOPT_FTP_USE_EPSV, but if we find out
+ EPSV doesn't work we disable it for the forthcoming
+ requests */
+
+ bool ftp_use_eprt; /* As set with CURLOPT_FTP_USE_EPRT, but if we find out
+ EPRT doesn't work we disable it for the forthcoming
+ requests */
+ bool netrc; /* name+password provided by netrc */
+ bool userpwd_in_url; /* name+password found in url */
+ bool stream_was_rewound; /* Indicates that the stream was rewound after a
+ request read past the end of its response byte
+ boundary */
+ bool proxy_connect_closed; /* set true if a proxy disconnected the
+ connection in a CONNECT request with auth, so
+ that libcurl should reconnect and continue. */
+ bool bound; /* set true if bind() has already been done on this socket/
+ connection */
+ bool type_set; /* type= was used in the URL */
+ bool multiplex; /* connection is multiplexed */
+};
+
+struct hostname {
+ char *rawalloc; /* allocated "raw" version of the name */
+ char *encalloc; /* allocated IDN-encoded version of the name */
+ char *name; /* name to use internally, might be encoded, might be raw */
+ const char *dispname; /* name to display, as 'name' might be encoded */
+};
+
+/*
+ * Flags on the keepon member of the Curl_transfer_keeper
+ */
+
+#define KEEP_NONE 0
+#define KEEP_RECV (1<<0) /* there is or may be data to read */
+#define KEEP_SEND (1<<1) /* there is or may be data to write */
+#define KEEP_RECV_HOLD (1<<2) /* when set, no reading should be done but there
+ might still be data to read */
+#define KEEP_SEND_HOLD (1<<3) /* when set, no writing should be done but there
+ might still be data to write */
+#define KEEP_RECV_PAUSE (1<<4) /* reading is paused */
+#define KEEP_SEND_PAUSE (1<<5) /* writing is paused */
+
+#define KEEP_RECVBITS (KEEP_RECV | KEEP_RECV_HOLD | KEEP_RECV_PAUSE)
+#define KEEP_SENDBITS (KEEP_SEND | KEEP_SEND_HOLD | KEEP_SEND_PAUSE)
+
+
+#ifdef HAVE_LIBZ
+typedef enum {
+ ZLIB_UNINIT, /* uninitialized */
+ ZLIB_INIT, /* initialized */
+ ZLIB_GZIP_HEADER, /* reading gzip header */
+ ZLIB_GZIP_INFLATING, /* inflating gzip stream */
+ ZLIB_INIT_GZIP /* initialized in transparent gzip mode */
+} zlibInitState;
+#endif
+
+#ifdef CURLRES_ASYNCH
+struct Curl_async {
+ char *hostname;
+ int port;
+ struct Curl_dns_entry *dns;
+ bool done; /* set TRUE when the lookup is complete */
+ int status; /* if done is TRUE, this is the status from the callback */
+ void *os_specific; /* 'struct thread_data' for Windows */
+};
+#endif
+
+#define FIRSTSOCKET 0
+#define SECONDARYSOCKET 1
+
+/* These function pointer types are here only to allow easier typecasting
+ within the source when we need to cast between data pointers (such as NULL)
+ and function pointers. */
+typedef CURLcode (*Curl_do_more_func)(struct connectdata *, int *);
+typedef CURLcode (*Curl_done_func)(struct connectdata *, CURLcode, bool);
+
+enum expect100 {
+ EXP100_SEND_DATA, /* enough waiting, just send the body now */
+ EXP100_AWAITING_CONTINUE, /* waiting for the 100 Continue header */
+ EXP100_SENDING_REQUEST, /* still sending the request but will wait for
+ the 100 header once done with the request */
+ EXP100_FAILED /* used on 417 Expectation Failed */
+};
+
+enum upgrade101 {
+ UPGR101_INIT, /* default state */
+ UPGR101_REQUESTED, /* upgrade requested */
+ UPGR101_RECEIVED, /* response received */
+ UPGR101_WORKING /* talking upgraded protocol */
+};
+
+/*
+ * Request specific data in the easy handle (SessionHandle). Previously,
+ * these members were on the connectdata struct but since a conn struct may
+ * now be shared between different SessionHandles, we store connection-specific
+ * data here. This struct only keeps stuff that's interesting for *this*
+ * request, as it will be cleared between multiple ones
+ */
+struct SingleRequest {
+ curl_off_t size; /* -1 if unknown at this point */
+ curl_off_t *bytecountp; /* return number of bytes read or NULL */
+
+ curl_off_t maxdownload; /* in bytes, the maximum amount of data to fetch,
+ -1 means unlimited */
+ curl_off_t *writebytecountp; /* return number of bytes written or NULL */
+
+ curl_off_t bytecount; /* total number of bytes read */
+ curl_off_t writebytecount; /* number of bytes written */
+
+ long headerbytecount; /* only count received headers */
+ long deductheadercount; /* this amount of bytes doesn't count when we check
+ if anything has been transferred at the end of a
+ connection. We use this counter to make only a
+ 100 reply (without a following second response
+ code) result in a CURLE_GOT_NOTHING error code */
+
+ struct timeval start; /* transfer started at this time */
+ struct timeval now; /* current time */
+ bool header; /* incoming data has HTTP header */
+ enum {
+ HEADER_NORMAL, /* no bad header at all */
+ HEADER_PARTHEADER, /* part of the chunk is a bad header, the rest
+ is normal data */
+ HEADER_ALLBAD /* all was believed to be header */
+ } badheader; /* the header was deemed bad and will be
+ written as body */
+ int headerline; /* counts header lines to better track the
+ first one */
+ char *hbufp; /* points at *end* of header line */
+ size_t hbuflen;
+ char *str; /* within buf */
+ char *str_start; /* within buf */
+ char *end_ptr; /* within buf */
+ char *p; /* within headerbuff */
+ bool content_range; /* set TRUE if Content-Range: was found */
+ curl_off_t offset; /* possible resume offset read from the
+ Content-Range: header */
+ int httpcode; /* error code from the 'HTTP/1.? XXX' or
+ 'RTSP/1.? XXX' line */
+ struct timeval start100; /* time stamp to wait for the 100 code from */
+ enum expect100 exp100; /* expect 100 continue state */
+ enum upgrade101 upgr101; /* 101 upgrade state */
+
+ int auto_decoding; /* What content encoding. sec 3.5, RFC2616. */
+
+#define IDENTITY 0 /* No encoding */
+#define DEFLATE 1 /* zlib deflate [RFC 1950 & 1951] */
+#define GZIP 2 /* gzip algorithm [RFC 1952] */
+
+#ifdef HAVE_LIBZ
+ zlibInitState zlib_init; /* possible zlib init state;
+ undefined if Content-Encoding header. */
+ z_stream z; /* State structure for zlib. */
+#endif
+
+ time_t timeofdoc;
+ long bodywrites;
+
+ char *buf;
+ char *uploadbuf;
+ curl_socket_t maxfd;
+
+ int keepon;
+
+ bool upload_done; /* set to TRUE when doing chunked transfer-encoding upload
+ and we're uploading the last chunk */
+
+ bool ignorebody; /* we read a response-body but we ignore it! */
+ bool ignorecl; /* This HTTP response has no body so we ignore the Content-
+ Length: header */
+
+ char *location; /* This points to an allocated version of the Location:
+ header data */
+ char *newurl; /* Set to the new URL to use when a redirect or a retry is
+ wanted */
+
+ /* 'upload_present' is used to keep a byte counter of how much data there is
+ still left in the buffer, aimed for upload. */
+ ssize_t upload_present;
+
+ /* 'upload_fromhere' is used as a read-pointer when we uploaded parts of a
+ buffer, so the next read should read from where this pointer points to,
+ and the 'upload_present' contains the number of bytes available at this
+ position */
+ char *upload_fromhere;
+
+ bool chunk; /* if set, this is a chunked transfer-encoding */
+ bool upload_chunky; /* set TRUE if we are doing chunked transfer-encoding
+ on upload */
+ bool getheader; /* TRUE if header parsing is wanted */
+
+ bool forbidchunk; /* used only to explicitly forbid chunk-upload for
+ specific upload buffers. See readmoredata() in
+ http.c for details. */
+
+ void *protop; /* Allocated protocol-specific data. Each protocol
+ handler makes sure this points to data it needs. */
+};
+
+/*
+ * Specific protocol handler.
+ */
+
+struct Curl_handler {
+ const char * scheme; /* URL scheme name. */
+
+ /* Complement to setup_connection_internals(). */
+ CURLcode (*setup_connection)(struct connectdata *);
+
+ /* These two functions MUST be set to be protocol dependent */
+ CURLcode (*do_it)(struct connectdata *, bool *done);
+ Curl_done_func done;
+
+ /* If the curl_do() function is better made in two halves, this
+ * curl_do_more() function will be called afterwards, if set. For example
+ * for doing the FTP stuff after the PASV/PORT command.
+ */
+ Curl_do_more_func do_more;
+
+ /* This function *MAY* be set to a protocol-dependent function that is run
+ * after the connect() and everything is done, as a step in the connection.
+ * The 'done' pointer points to a bool that should be set to TRUE if the
+ * function completes before return. If it doesn't complete, the caller
+ * should call the curl_connecting() function until it is.
+ */
+ CURLcode (*connect_it)(struct connectdata *, bool *done);
+
+ /* See above. Currently only used for FTP. */
+ CURLcode (*connecting)(struct connectdata *, bool *done);
+ CURLcode (*doing)(struct connectdata *, bool *done);
+
+ /* Called from the multi interface during the PROTOCONNECT phase, and it
+ should then return a proper fd set */
+ int (*proto_getsock)(struct connectdata *conn,
+ curl_socket_t *socks,
+ int numsocks);
+
+ /* Called from the multi interface during the DOING phase, and it should
+ then return a proper fd set */
+ int (*doing_getsock)(struct connectdata *conn,
+ curl_socket_t *socks,
+ int numsocks);
+
+ /* Called from the multi interface during the DO_MORE phase, and it should
+ then return a proper fd set */
+ int (*domore_getsock)(struct connectdata *conn,
+ curl_socket_t *socks,
+ int numsocks);
+
+ /* Called from the multi interface during the DO_DONE, PERFORM and
+ WAITPERFORM phases, and it should then return a proper fd set. Not setting
+ this will make libcurl use the generic default one. */
+ int (*perform_getsock)(const struct connectdata *conn,
+ curl_socket_t *socks,
+ int numsocks);
+
+ /* This function *MAY* be set to a protocol-dependent function that is run
+ * by the curl_disconnect(), as a step in the disconnection. If the handler
+ * is called because the connection has been considered dead, dead_connection
+ * is set to TRUE.
+ */
+ CURLcode (*disconnect)(struct connectdata *, bool dead_connection);
+
+ /* If used, this function gets called from transfer.c:readwrite_data() to
+ allow the protocol to do extra reads/writes */
+ CURLcode (*readwrite)(struct SessionHandle *data, struct connectdata *conn,
+ ssize_t *nread, bool *readmore);
+
+ long defport; /* Default port. */
+ unsigned int protocol; /* See CURLPROTO_* - this needs to be the single
+ specific protocol bit */
+ unsigned int flags; /* Extra particular characteristics, see PROTOPT_* */
+};
+
+#define PROTOPT_NONE 0 /* nothing extra */
+#define PROTOPT_SSL (1<<0) /* uses SSL */
+#define PROTOPT_DUAL (1<<1) /* this protocol uses two connections */
+#define PROTOPT_CLOSEACTION (1<<2) /* need action before socket close */
+/* some protocols will have to call the underlying functions without regard to
+ what exact state the socket signals. IE even if the socket says "readable",
+ the send function might need to be called while uploading, or vice versa.
+*/
+#define PROTOPT_DIRLOCK (1<<3)
+#define PROTOPT_NONETWORK (1<<4) /* protocol doesn't use the network! */
+#define PROTOPT_NEEDSPWD (1<<5) /* needs a password, and if none is set it
+ gets a default */
+#define PROTOPT_NOURLQUERY (1<<6) /* protocol can't handle
+ url query strings (?foo=bar) ! */
+#define PROTOPT_CREDSPERREQUEST (1<<7) /* requires login credentials per
+ request instead of per connection */
+
+
+/* return the count of bytes sent, or -1 on error */
+typedef ssize_t (Curl_send)(struct connectdata *conn, /* connection data */
+ int sockindex, /* socketindex */
+ const void *buf, /* data to write */
+ size_t len, /* max amount to write */
+ CURLcode *err); /* error to return */
+
+/* return the count of bytes read, or -1 on error */
+typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */
+ int sockindex, /* socketindex */
+ char *buf, /* store data here */
+ size_t len, /* max amount to read */
+ CURLcode *err); /* error to return */
+
+/*
+ * The connectdata struct contains all fields and variables that should be
+ * unique for an entire connection.
+ */
+struct connectdata {
+ /* 'data' is the CURRENT SessionHandle using this connection -- take great
+ caution that this might very well vary between different times this
+ connection is used! */
+ struct SessionHandle *data;
+
+ /* chunk is for HTTP chunked encoding, but is in the general connectdata
+ struct only because we can do just about any protocol through a HTTP proxy
+ and a HTTP proxy may in fact respond using chunked encoding */
+ struct Curl_chunker chunk;
+
+ curl_closesocket_callback fclosesocket; /* function closing the socket(s) */
+ void *closesocket_client;
+
+ bool inuse; /* This is a marker for the connection cache logic. If this is
+ TRUE this handle is being used by an easy handle and cannot
+ be used by any other easy handle without careful
+ consideration (== only for pipelining). */
+
+ /**** Fields set when inited and not modified again */
+ long connection_id; /* Contains a unique number to make it easier to
+ track the connections in the log output */
+
+ /* 'dns_entry' is the particular host we use. This points to an entry in the
+ DNS cache and it will not get pruned while locked. It gets unlocked in
+ Curl_done(). This entry will be NULL if the connection is re-used as then
+ there is no name resolve done. */
+ struct Curl_dns_entry *dns_entry;
+
+ /* 'ip_addr' is the particular IP we connected to. It points to a struct
+ within the DNS cache, so this pointer is only valid as long as the DNS
+ cache entry remains locked. It gets unlocked in Curl_done() */
+ Curl_addrinfo *ip_addr;
+ Curl_addrinfo *tempaddr[2]; /* for happy eyeballs */
+
+ /* 'ip_addr_str' is the ip_addr data as a human readable string.
+ It remains available as long as the connection does, which is longer than
+ the ip_addr itself. */
+ char ip_addr_str[MAX_IPADR_LEN];
+
+ unsigned int scope_id; /* Scope id for IPv6 */
+
+ int socktype; /* SOCK_STREAM or SOCK_DGRAM */
+
+ struct hostname host;
+ struct hostname proxy;
+
+ long port; /* which port to use locally */
+ int remote_port; /* what remote port to connect to, not the proxy port! */
+
+ /* 'primary_ip' and 'primary_port' get filled with peer's numerical
+ ip address and port number whenever an outgoing connection is
+ *attempted* from the primary socket to a remote address. When more
+ than one address is tried for a connection these will hold data
+ for the last attempt. When the connection is actually established
+ these are updated with data which comes directly from the socket. */
+
+ char primary_ip[MAX_IPADR_LEN];
+ long primary_port;
+
+ /* 'local_ip' and 'local_port' get filled with local's numerical
+ ip address and port number whenever an outgoing connection is
+ **established** from the primary socket to a remote address. */
+
+ char local_ip[MAX_IPADR_LEN];
+ long local_port;
+
+ char *user; /* user name string, allocated */
+ char *passwd; /* password string, allocated */
+ char *options; /* options string, allocated */
+
+ char *xoauth2_bearer; /* bearer token for xoauth2, allocated */
+
+ char *proxyuser; /* proxy user name string, allocated */
+ char *proxypasswd; /* proxy password string, allocated */
+ curl_proxytype proxytype; /* what kind of proxy that is in use */
+
+ int httpversion; /* the HTTP version*10 reported by the server */
+ int rtspversion; /* the RTSP version*10 reported by the server */
+
+ struct timeval now; /* "current" time */
+ struct timeval created; /* creation time */
+ curl_socket_t sock[2]; /* two sockets, the second is used for the data
+ transfer when doing FTP */
+ curl_socket_t tempsock[2]; /* temporary sockets for happy eyeballs */
+ bool sock_accepted[2]; /* TRUE if the socket on this index was created with
+ accept() */
+ Curl_recv *recv[2];
+ Curl_send *send[2];
+
+ struct ssl_connect_data ssl[2]; /* this is for ssl-stuff */
+ struct ssl_config_data ssl_config;
+
+ struct ConnectBits bits; /* various state-flags for this connection */
+
+ /* connecttime: when connect() is called on the current IP address. Used to
+ be able to track when to move on to try next IP - but only when the multi
+ interface is used. */
+ struct timeval connecttime;
+ /* The two fields below get set in Curl_connecthost */
+ int num_addr; /* number of addresses to try to connect to */
+ long timeoutms_per_addr; /* how long time in milliseconds to spend on
+ trying to connect to each IP address */
+
+ const struct Curl_handler *handler; /* Connection's protocol handler */
+ const struct Curl_handler *given; /* The protocol first given */
+
+ long ip_version; /* copied from the SessionHandle at creation time */
+
+ /**** curl_get() phase fields */
+
+ curl_socket_t sockfd; /* socket to read from or CURL_SOCKET_BAD */
+ curl_socket_t writesockfd; /* socket to write to, it may very
+ well be the same we read from.
+ CURL_SOCKET_BAD disables */
+
+ /** Dynamicly allocated strings, MUST be freed before this **/
+ /** struct is killed. **/
+ struct dynamically_allocated_data {
+ char *proxyuserpwd;
+ char *uagent;
+ char *accept_encoding;
+ char *userpwd;
+ char *rangeline;
+ char *ref;
+ char *host;
+ char *cookiehost;
+ char *rtsp_transport;
+ char *te; /* TE: request header */
+ } allocptr;
+
+#ifdef HAVE_GSSAPI
+ int sec_complete; /* if Kerberos is enabled for this connection */
+ enum protection_level command_prot;
+ enum protection_level data_prot;
+ enum protection_level request_data_prot;
+ size_t buffer_size;
+ struct krb5buffer in_buffer;
+ void *app_data;
+ const struct Curl_sec_client_mech *mech;
+ struct sockaddr_in local_addr;
+#endif
+
+#if defined(USE_KERBEROS5) /* Consider moving some of the above GSS-API */
+ struct kerberos5data krb5; /* variables into the structure definition, */
+#endif /* however, some of them are ftp specific. */
+
+ /* the two following *_inuse fields are only flags, not counters in any way.
+ If TRUE it means the channel is in use, and if FALSE it means the channel
+ is up for grabs by one. */
+
+ bool readchannel_inuse; /* whether the read channel is in use by an easy
+ handle */
+ bool writechannel_inuse; /* whether the write channel is in use by an easy
+ handle */
+ struct curl_llist *send_pipe; /* List of handles waiting to
+ send on this pipeline */
+ struct curl_llist *recv_pipe; /* List of handles waiting to read
+ their responses on this pipeline */
+ char* master_buffer; /* The master buffer allocated on-demand;
+ used for pipelining. */
+ size_t read_pos; /* Current read position in the master buffer */
+ size_t buf_len; /* Length of the buffer?? */
+
+
+ curl_seek_callback seek_func; /* function that seeks the input */
+ void *seek_client; /* pointer to pass to the seek() above */
+
+ /*************** Request - specific items ************/
+
+#if defined(USE_NTLM)
+ struct ntlmdata ntlm; /* NTLM differs from other authentication schemes
+ because it authenticates connections, not
+ single requests! */
+ struct ntlmdata proxyntlm; /* NTLM data for proxy */
+
+#if defined(NTLM_WB_ENABLED)
+ /* used for communication with Samba's winbind daemon helper ntlm_auth */
+ curl_socket_t ntlm_auth_hlpr_socket;
+ pid_t ntlm_auth_hlpr_pid;
+ char* challenge_header;
+ char* response_header;
+#endif
+#endif
+
+ char syserr_buf [256]; /* buffer for Curl_strerror() */
+
+#ifdef CURLRES_ASYNCH
+ /* data used for the asynch name resolve callback */
+ struct Curl_async async;
+#endif
+
+ /* These three are used for chunked-encoding trailer support */
+ char *trailer; /* allocated buffer to store trailer in */
+ int trlMax; /* allocated buffer size */
+ int trlPos; /* index of where to store data */
+
+ union {
+ struct ftp_conn ftpc;
+ struct http_conn httpc;
+ struct ssh_conn sshc;
+ struct tftp_state_data *tftpc;
+ struct imap_conn imapc;
+ struct pop3_conn pop3c;
+ struct smtp_conn smtpc;
+ struct rtsp_conn rtspc;
+ struct smb_conn smbc;
+ void *generic; /* RTMP and LDAP use this */
+ } proto;
+
+ int cselect_bits; /* bitmask of socket events */
+ int waitfor; /* current READ/WRITE bits to wait for */
+
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+ int socks5_gssapi_enctype;
+#endif
+
+ bool verifypeer;
+ bool verifyhost;
+
+ /* When this connection is created, store the conditions for the local end
+ bind. This is stored before the actual bind and before any connection is
+ made and will serve the purpose of being used for comparison reasons so
+ that subsequent bound-requested connections aren't accidentally re-using
+ wrong connections. */
+ char *localdev;
+ unsigned short localport;
+ int localportrange;
+
+ /* tunnel as in tunnel through a HTTP proxy with CONNECT */
+ enum {
+ TUNNEL_INIT, /* init/default/no tunnel state */
+ TUNNEL_CONNECT, /* CONNECT has been sent off */
+ TUNNEL_COMPLETE /* CONNECT response received completely */
+ } tunnel_state[2]; /* two separate ones to allow FTP */
+ struct connectbundle *bundle; /* The bundle we are member of */
+
+ int negnpn; /* APLN or NPN TLS negotiated protocol, CURL_HTTP_VERSION* */
+};
+
+/* The end of connectdata. */
+
+/*
+ * Struct to keep statistical and informational data.
+ */
+struct PureInfo {
+ int httpcode; /* Recent HTTP, FTP, or RTSP response code */
+ int httpproxycode; /* response code from proxy when received separate */
+ int httpversion; /* the http version number X.Y = X*10+Y */
+ long filetime; /* If requested, this is might get set. Set to -1 if the time
+ was unretrievable. We cannot have this of type time_t,
+ since time_t is unsigned on several platforms such as
+ OpenVMS. */
+ bool timecond; /* set to TRUE if the time condition didn't match, which
+ thus made the document NOT get fetched */
+ long header_size; /* size of read header(s) in bytes */
+ long request_size; /* the amount of bytes sent in the request(s) */
+ unsigned long proxyauthavail; /* what proxy auth types were announced */
+ unsigned long httpauthavail; /* what host auth types were announced */
+ long numconnects; /* how many new connection did libcurl created */
+ char *contenttype; /* the content type of the object */
+ char *wouldredirect; /* URL this would've been redirected to if asked to */
+
+ /* PureInfo members 'conn_primary_ip', 'conn_primary_port', 'conn_local_ip'
+ and, 'conn_local_port' are copied over from the connectdata struct in
+ order to allow curl_easy_getinfo() to return this information even when
+ the session handle is no longer associated with a connection, and also
+ allow curl_easy_reset() to clear this information from the session handle
+ without disturbing information which is still alive, and that might be
+ reused, in the connection cache. */
+
+ char conn_primary_ip[MAX_IPADR_LEN];
+ long conn_primary_port;
+
+ char conn_local_ip[MAX_IPADR_LEN];
+ long conn_local_port;
+
+ struct curl_certinfo certs; /* info about the certs, only populated in
+ OpenSSL builds. Asked for with
+ CURLOPT_CERTINFO / CURLINFO_CERTINFO */
+};
+
+
+struct Progress {
+ long lastshow; /* time() of the last displayed progress meter or NULL to
+ force redraw at next call */
+ curl_off_t size_dl; /* total expected size */
+ curl_off_t size_ul; /* total expected size */
+ curl_off_t downloaded; /* transferred so far */
+ curl_off_t uploaded; /* transferred so far */
+
+ curl_off_t current_speed; /* uses the currently fastest transfer */
+
+ bool callback; /* set when progress callback is used */
+ int width; /* screen width at download start */
+ int flags; /* see progress.h */
+
+ double timespent;
+
+ curl_off_t dlspeed;
+ curl_off_t ulspeed;
+
+ double t_nslookup;
+ double t_connect;
+ double t_appconnect;
+ double t_pretransfer;
+ double t_starttransfer;
+ double t_redirect;
+
+ struct timeval start;
+ struct timeval t_startsingle;
+ struct timeval t_startop;
+ struct timeval t_acceptdata;
+#define CURR_TIME (5+1) /* 6 entries for 5 seconds */
+
+ curl_off_t speeder[ CURR_TIME ];
+ struct timeval speeder_time[ CURR_TIME ];
+ int speeder_c;
+};
+
+typedef enum {
+ HTTPREQ_NONE, /* first in list */
+ HTTPREQ_GET,
+ HTTPREQ_POST,
+ HTTPREQ_POST_FORM, /* we make a difference internally */
+ HTTPREQ_PUT,
+ HTTPREQ_HEAD,
+ HTTPREQ_CUSTOM,
+ HTTPREQ_LAST /* last in list */
+} Curl_HttpReq;
+
+typedef enum {
+ RTSPREQ_NONE, /* first in list */
+ RTSPREQ_OPTIONS,
+ RTSPREQ_DESCRIBE,
+ RTSPREQ_ANNOUNCE,
+ RTSPREQ_SETUP,
+ RTSPREQ_PLAY,
+ RTSPREQ_PAUSE,
+ RTSPREQ_TEARDOWN,
+ RTSPREQ_GET_PARAMETER,
+ RTSPREQ_SET_PARAMETER,
+ RTSPREQ_RECORD,
+ RTSPREQ_RECEIVE,
+ RTSPREQ_LAST /* last in list */
+} Curl_RtspReq;
+
+/*
+ * Values that are generated, temporary or calculated internally for a
+ * "session handle" must be defined within the 'struct UrlState'. This struct
+ * will be used within the SessionHandle struct. When the 'SessionHandle'
+ * struct is cloned, this data MUST NOT be copied.
+ *
+ * Remember that any "state" information goes globally for the curl handle.
+ * Session-data MUST be put in the connectdata struct and here. */
+#define MAX_CURL_USER_LENGTH 256
+#define MAX_CURL_PASSWORD_LENGTH 256
+
+struct auth {
+ unsigned long want; /* Bitmask set to the authentication methods wanted by
+ app (with CURLOPT_HTTPAUTH or CURLOPT_PROXYAUTH). */
+ unsigned long picked;
+ unsigned long avail; /* Bitmask for what the server reports to support for
+ this resource */
+ bool done; /* TRUE when the auth phase is done and ready to do the *actual*
+ request */
+ bool multi; /* TRUE if this is not yet authenticated but within the auth
+ multipass negotiation */
+ bool iestyle; /* TRUE if digest should be done IE-style or FALSE if it should
+ be RFC compliant */
+};
+
+struct UrlState {
+
+ /* Points to the connection cache */
+ struct conncache *conn_cache;
+
+ /* when curl_easy_perform() is called, the multi handle is "owned" by
+ the easy handle so curl_easy_cleanup() on such an easy handle will
+ also close the multi handle! */
+ bool multi_owned_by_easy;
+
+ /* buffers to store authentication data in, as parsed from input options */
+ struct timeval keeps_speed; /* for the progress meter really */
+
+ struct connectdata *lastconnect; /* The last connection, NULL if undefined */
+
+ char *headerbuff; /* allocated buffer to store headers in */
+ size_t headersize; /* size of the allocation */
+
+ char buffer[BUFSIZE+1]; /* download buffer */
+ char uploadbuffer[BUFSIZE+1]; /* upload buffer */
+ curl_off_t current_speed; /* the ProgressShow() funcion sets this,
+ bytes / second */
+ bool this_is_a_follow; /* this is a followed Location: request */
+
+ char *first_host; /* if set, this should be the host name that we will
+ sent authorization to, no else. Used to make Location:
+ following not keep sending user+password... This is
+ strdup() data.
+ */
+ struct curl_ssl_session *session; /* array of 'max_ssl_sessions' size */
+ long sessionage; /* number of the most recent session */
+ char *tempwrite; /* allocated buffer to keep data in when a write
+ callback returns to make the connection paused */
+ size_t tempwritesize; /* size of the 'tempwrite' allocated buffer */
+ int tempwritetype; /* type of the 'tempwrite' buffer as a bitmask that is
+ used with Curl_client_write() */
+ char *scratch; /* huge buffer[BUFSIZE*2] when doing upload CRLF replacing */
+ bool errorbuf; /* Set to TRUE if the error buffer is already filled in.
+ This must be set to FALSE every time _easy_perform() is
+ called. */
+ int os_errno; /* filled in with errno whenever an error occurs */
+#ifdef HAVE_SIGNAL
+ /* storage for the previous bag^H^H^HSIGPIPE signal handler :-) */
+ void (*prev_signal)(int sig);
+#endif
+ bool allow_port; /* Is set.use_port allowed to take effect or not. This
+ is always set TRUE when curl_easy_perform() is called. */
+ struct digestdata digest; /* state data for host Digest auth */
+ struct digestdata proxydigest; /* state data for proxy Digest auth */
+
+#ifdef USE_SPNEGO
+ struct negotiatedata negotiate; /* state data for host Negotiate auth */
+ struct negotiatedata proxyneg; /* state data for proxy Negotiate auth */
+#endif
+
+ struct auth authhost; /* auth details for host */
+ struct auth authproxy; /* auth details for proxy */
+
+ bool authproblem; /* TRUE if there's some problem authenticating */
+
+ void *resolver; /* resolver state, if it is used in the URL state -
+ ares_channel f.e. */
+
+#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_ENGINE_H)
+ ENGINE *engine;
+#endif /* USE_OPENSSL */
+ struct timeval expiretime; /* set this with Curl_expire() only */
+ struct Curl_tree timenode; /* for the splay stuff */
+ struct curl_llist *timeoutlist; /* list of pending timeouts */
+
+ /* a place to store the most recently set FTP entrypath */
+ char *most_recent_ftp_entrypath;
+
+ /* set after initial USER failure, to prevent an authentication loop */
+ bool ftp_trying_alternative;
+
+ int httpversion; /* the lowest HTTP version*10 reported by any server
+ involved in this request */
+ bool expect100header; /* TRUE if we added Expect: 100-continue */
+
+ bool pipe_broke; /* TRUE if the connection we were pipelined on broke
+ and we need to restart from the beginning */
+
+#if !defined(WIN32) && !defined(MSDOS) && !defined(__EMX__) && \
+ !defined(__SYMBIAN32__)
+/* do FTP line-end conversions on most platforms */
+#define CURL_DO_LINEEND_CONV
+ /* for FTP downloads: track CRLF sequences that span blocks */
+ bool prev_block_had_trailing_cr;
+ /* for FTP downloads: how many CRLFs did we converted to LFs? */
+ curl_off_t crlf_conversions;
+#endif
+ char *pathbuffer;/* allocated buffer to store the URL's path part in */
+ char *path; /* path to use, points to somewhere within the pathbuffer
+ area */
+ bool slash_removed; /* set TRUE if the 'path' points to a path where the
+ initial URL slash separator has been taken off */
+ bool use_range;
+ bool rangestringalloc; /* the range string is malloc()'ed */
+
+ char *range; /* range, if used. See README for detailed specification on
+ this syntax. */
+ curl_off_t resume_from; /* continue [ftp] transfer from here */
+
+ /* This RTSP state information survives requests and connections */
+ long rtsp_next_client_CSeq; /* the session's next client CSeq */
+ long rtsp_next_server_CSeq; /* the session's next server CSeq */
+ long rtsp_CSeq_recv; /* most recent CSeq received */
+
+ curl_off_t infilesize; /* size of file to upload, -1 means unknown.
+ Copied from set.filesize at start of operation */
+
+ int drain; /* Increased when this stream has data to read, even if its
+ socket not necessarily is readable. Decreased when
+ checked. */
+ bool done; /* set to FALSE when Curl_do() is called and set to TRUE when
+ Curl_done() is called, to prevent Curl_done() to get invoked
+ twice when the multi interface is used. */
+};
+
+
+/*
+ * This 'DynamicStatic' struct defines dynamic states that actually change
+ * values in the 'UserDefined' area, which MUST be taken into consideration
+ * if the UserDefined struct is cloned or similar. You can probably just
+ * copy these, but each one indicate a special action on other data.
+ */
+
+struct DynamicStatic {
+ char *url; /* work URL, copied from UserDefined */
+ bool url_alloc; /* URL string is malloc()'ed */
+ char *referer; /* referer string */
+ bool referer_alloc; /* referer sting is malloc()ed */
+ struct curl_slist *cookielist; /* list of cookie files set by
+ curl_easy_setopt(COOKIEFILE) calls */
+ struct curl_slist *resolve; /* set to point to the set.resolve list when
+ this should be dealt with in pretransfer */
+};
+
+/*
+ * This 'UserDefined' struct must only contain data that is set once to go
+ * for many (perhaps) independent connections. Values that are generated or
+ * calculated internally for the "session handle" MUST be defined within the
+ * 'struct UrlState' instead. The only exceptions MUST note the changes in
+ * the 'DynamicStatic' struct.
+ * Character pointer fields point to dynamic storage, unless otherwise stated.
+ */
+
+struct Curl_multi; /* declared and used only in multi.c */
+
+enum dupstring {
+ STRING_CERT, /* client certificate file name */
+ STRING_CERT_TYPE, /* format for certificate (default: PEM)*/
+ STRING_COOKIE, /* HTTP cookie string to send */
+ STRING_COOKIEJAR, /* dump all cookies to this file */
+ STRING_CUSTOMREQUEST, /* HTTP/FTP/RTSP request/method to use */
+ STRING_DEVICE, /* local network interface/address to use */
+ STRING_ENCODING, /* Accept-Encoding string */
+ STRING_FTP_ACCOUNT, /* ftp account data */
+ STRING_FTP_ALTERNATIVE_TO_USER, /* command to send if USER/PASS fails */
+ STRING_FTPPORT, /* port to send with the FTP PORT command */
+ STRING_KEY, /* private key file name */
+ STRING_KEY_PASSWD, /* plain text private key password */
+ STRING_KEY_TYPE, /* format for private key (default: PEM) */
+ STRING_KRB_LEVEL, /* krb security level */
+ STRING_NETRC_FILE, /* if not NULL, use this instead of trying to find
+ $HOME/.netrc */
+ STRING_PROXY, /* proxy to use */
+ STRING_SET_RANGE, /* range, if used */
+ STRING_SET_REFERER, /* custom string for the HTTP referer field */
+ STRING_SET_URL, /* what original URL to work on */
+ STRING_SSL_CAPATH, /* CA directory name (doesn't work on windows) */
+ STRING_SSL_CAFILE, /* certificate file to verify peer against */
+ STRING_SSL_PINNEDPUBLICKEY, /* public key file to verify peer against */
+ STRING_SSL_CIPHER_LIST, /* list of ciphers to use */
+ STRING_SSL_EGDSOCKET, /* path to file containing the EGD daemon socket */
+ STRING_SSL_RANDOM_FILE, /* path to file containing "random" data */
+ STRING_USERAGENT, /* User-Agent string */
+ STRING_SSL_CRLFILE, /* crl file to check certificate */
+ STRING_SSL_ISSUERCERT, /* issuer cert file to check certificate */
+ STRING_USERNAME, /* <username>, if used */
+ STRING_PASSWORD, /* <password>, if used */
+ STRING_OPTIONS, /* <options>, if used */
+ STRING_PROXYUSERNAME, /* Proxy <username>, if used */
+ STRING_PROXYPASSWORD, /* Proxy <password>, if used */
+ STRING_NOPROXY, /* List of hosts which should not use the proxy, if
+ used */
+ STRING_RTSP_SESSION_ID, /* Session ID to use */
+ STRING_RTSP_STREAM_URI, /* Stream URI for this request */
+ STRING_RTSP_TRANSPORT, /* Transport for this session */
+#ifdef USE_LIBSSH2
+ STRING_SSH_PRIVATE_KEY, /* path to the private key file for auth */
+ STRING_SSH_PUBLIC_KEY, /* path to the public key file for auth */
+ STRING_SSH_HOST_PUBLIC_KEY_MD5, /* md5 of host public key in ascii hex */
+ STRING_SSH_KNOWNHOSTS, /* file name of knownhosts file */
+#endif
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+ STRING_SOCKS5_GSSAPI_SERVICE, /* GSSAPI service name */
+ STRING_PROXY_SERVICE_NAME, /* Proxy service name */
+ STRING_SERVICE_NAME, /* Service name */
+#endif
+ STRING_MAIL_FROM,
+ STRING_MAIL_AUTH,
+
+#ifdef USE_TLS_SRP
+ STRING_TLSAUTH_USERNAME, /* TLS auth <username> */
+ STRING_TLSAUTH_PASSWORD, /* TLS auth <password> */
+#endif
+ STRING_BEARER, /* <bearer>, if used */
+#ifdef USE_UNIX_SOCKETS
+ STRING_UNIX_SOCKET_PATH, /* path to Unix socket, if used */
+#endif
+
+ /* -- end of zero-terminated strings -- */
+
+ STRING_LASTZEROTERMINATED,
+
+ /* -- below this are pointers to binary data that cannot be strdup'ed.
+ Each such pointer must be added manually to Curl_dupset() --- */
+
+ STRING_COPYPOSTFIELDS, /* if POST, set the fields' values here */
+
+ STRING_LAST /* not used, just an end-of-list marker */
+};
+
+struct UserDefined {
+ FILE *err; /* the stderr user data goes here */
+ void *debugdata; /* the data that will be passed to fdebug */
+ char *errorbuffer; /* (Static) store failure messages in here */
+ long proxyport; /* If non-zero, use this port number by default. If the
+ proxy string features a ":[port]" that one will override
+ this. */
+ void *out; /* CURLOPT_WRITEDATA */
+ void *in; /* CURLOPT_READDATA */
+ void *writeheader; /* write the header to this if non-NULL */
+ void *rtp_out; /* write RTP to this if non-NULL */
+ long use_port; /* which port to use (when not using default) */
+ unsigned long httpauth; /* kind of HTTP authentication to use (bitmask) */
+ unsigned long proxyauth; /* kind of proxy authentication to use (bitmask) */
+ long followlocation; /* as in HTTP Location: */
+ long maxredirs; /* maximum no. of http(s) redirects to follow, set to -1
+ for infinity */
+
+ int keep_post; /* keep POSTs as POSTs after a 30x request; each
+ bit represents a request, from 301 to 303 */
+ bool free_referer; /* set TRUE if 'referer' points to a string we
+ allocated */
+ void *postfields; /* if POST, set the fields' values here */
+ curl_seek_callback seek_func; /* function that seeks the input */
+ curl_off_t postfieldsize; /* if POST, this might have a size to use instead
+ of strlen(), and then the data *may* be binary
+ (contain zero bytes) */
+ unsigned short localport; /* local port number to bind to */
+ int localportrange; /* number of additional port numbers to test in case the
+ 'localport' one can't be bind()ed */
+ curl_write_callback fwrite_func; /* function that stores the output */
+ curl_write_callback fwrite_header; /* function that stores headers */
+ curl_write_callback fwrite_rtp; /* function that stores interleaved RTP */
+ curl_read_callback fread_func; /* function that reads the input */
+ int is_fread_set; /* boolean, has read callback been set to non-NULL? */
+ int is_fwrite_set; /* boolean, has write callback been set to non-NULL? */
+ curl_progress_callback fprogress; /* OLD and deprecated progress callback */
+ curl_xferinfo_callback fxferinfo; /* progress callback */
+ curl_debug_callback fdebug; /* function that write informational data */
+ curl_ioctl_callback ioctl_func; /* function for I/O control */
+ curl_sockopt_callback fsockopt; /* function for setting socket options */
+ void *sockopt_client; /* pointer to pass to the socket options callback */
+ curl_opensocket_callback fopensocket; /* function for checking/translating
+ the address and opening the
+ socket */
+ void* opensocket_client;
+ curl_closesocket_callback fclosesocket; /* function for closing the
+ socket */
+ void* closesocket_client;
+
+ void *seek_client; /* pointer to pass to the seek callback */
+ /* the 3 curl_conv_callback functions below are used on non-ASCII hosts */
+ /* function to convert from the network encoding: */
+ curl_conv_callback convfromnetwork;
+ /* function to convert to the network encoding: */
+ curl_conv_callback convtonetwork;
+ /* function to convert from UTF-8 encoding: */
+ curl_conv_callback convfromutf8;
+
+ void *progress_client; /* pointer to pass to the progress callback */
+ void *ioctl_client; /* pointer to pass to the ioctl callback */
+ long timeout; /* in milliseconds, 0 means no timeout */
+ long connecttimeout; /* in milliseconds, 0 means no timeout */
+ long accepttimeout; /* in milliseconds, 0 means no timeout */
+ long server_response_timeout; /* in milliseconds, 0 means no timeout */
+ long tftp_blksize ; /* in bytes, 0 means use default */
+ curl_off_t filesize; /* size of file to upload, -1 means unknown */
+ long low_speed_limit; /* bytes/second */
+ long low_speed_time; /* number of seconds */
+ curl_off_t max_send_speed; /* high speed limit in bytes/second for upload */
+ curl_off_t max_recv_speed; /* high speed limit in bytes/second for
+ download */
+ curl_off_t set_resume_from; /* continue [ftp] transfer from here */
+ struct curl_slist *headers; /* linked list of extra headers */
+ struct curl_slist *proxyheaders; /* linked list of extra CONNECT headers */
+ struct curl_httppost *httppost; /* linked list of POST data */
+ bool sep_headers; /* handle host and proxy headers separately */
+ bool cookiesession; /* new cookie session? */
+ bool crlf; /* convert crlf on ftp upload(?) */
+ struct curl_slist *quote; /* after connection is established */
+ struct curl_slist *postquote; /* after the transfer */
+ struct curl_slist *prequote; /* before the transfer, after type */
+ struct curl_slist *source_quote; /* 3rd party quote */
+ struct curl_slist *source_prequote; /* in 3rd party transfer mode - before
+ the transfer on source host */
+ struct curl_slist *source_postquote; /* in 3rd party transfer mode - after
+ the transfer on source host */
+ struct curl_slist *telnet_options; /* linked list of telnet options */
+ struct curl_slist *resolve; /* list of names to add/remove from
+ DNS cache */
+ curl_TimeCond timecondition; /* kind of time/date comparison */
+ time_t timevalue; /* what time to compare with */
+ Curl_HttpReq httpreq; /* what kind of HTTP request (if any) is this */
+ long httpversion; /* when non-zero, a specific HTTP version requested to
+ be used in the library's request(s) */
+ struct ssl_config_data ssl; /* user defined SSL stuff */
+ curl_proxytype proxytype; /* what kind of proxy that is in use */
+ long dns_cache_timeout; /* DNS cache timeout */
+ long buffer_size; /* size of receive buffer to use */
+ void *private_data; /* application-private data */
+
+ struct curl_slist *http200aliases; /* linked list of aliases for http200 */
+
+ long ipver; /* the CURL_IPRESOLVE_* defines in the public header file
+ 0 - whatever, 1 - v2, 2 - v6 */
+
+ curl_off_t max_filesize; /* Maximum file size to download */
+
+ curl_ftpfile ftp_filemethod; /* how to get to a file when FTP is used */
+
+ int ftp_create_missing_dirs; /* 1 - create directories that don't exist
+ 2 - the same but also allow MKD to fail once
+ */
+
+ curl_sshkeycallback ssh_keyfunc; /* key matching callback */
+ void *ssh_keyfunc_userp; /* custom pointer to callback */
+
+/* Here follows boolean settings that define how to behave during
+ this session. They are STATIC, set by libcurl users or at least initially
+ and they don't change during operations. */
+
+ bool printhost; /* printing host name in debug info */
+ bool get_filetime; /* get the time and get of the remote file */
+ bool tunnel_thru_httpproxy; /* use CONNECT through a HTTP proxy */
+ bool prefer_ascii; /* ASCII rather than binary */
+ bool ftp_append; /* append, not overwrite, on upload */
+ bool ftp_list_only; /* switch FTP command for listing directories */
+ bool ftp_use_port; /* use the FTP PORT command */
+ bool hide_progress; /* don't use the progress meter */
+ bool http_fail_on_error; /* fail on HTTP error codes >= 400 */
+ bool http_follow_location; /* follow HTTP redirects */
+ bool http_transfer_encoding; /* request compressed HTTP transfer-encoding */
+ bool http_disable_hostname_check_before_authentication;
+ bool include_header; /* include received protocol headers in data output */
+ bool http_set_referer; /* is a custom referer used */
+ bool http_auto_referer; /* set "correct" referer when following location: */
+ bool opt_no_body; /* as set with CURLOPT_NOBODY */
+ bool set_port; /* custom port number used */
+ bool upload; /* upload request */
+ enum CURL_NETRC_OPTION
+ use_netrc; /* defined in include/curl.h */
+ bool verbose; /* output verbosity */
+ bool krb; /* Kerberos connection requested */
+ bool reuse_forbid; /* forbidden to be reused, close after use */
+ bool reuse_fresh; /* do not re-use an existing connection */
+ bool ftp_use_epsv; /* if EPSV is to be attempted or not */
+ bool ftp_use_eprt; /* if EPRT is to be attempted or not */
+ bool ftp_use_pret; /* if PRET is to be used before PASV or not */
+
+ curl_usessl use_ssl; /* if AUTH TLS is to be attempted etc, for FTP or
+ IMAP or POP3 or others! */
+ curl_ftpauth ftpsslauth; /* what AUTH XXX to be attempted */
+ curl_ftpccc ftp_ccc; /* FTP CCC options */
+ bool no_signal; /* do not use any signal/alarm handler */
+ bool global_dns_cache; /* subject for future removal */
+ bool tcp_nodelay; /* whether to enable TCP_NODELAY or not */
+ bool ignorecl; /* ignore content length */
+ bool ftp_skip_ip; /* skip the IP address the FTP server passes on to
+ us */
+ bool connect_only; /* make connection, let application use the socket */
+ bool ssl_enable_beast; /* especially allow this flaw for interoperability's
+ sake*/
+ bool ssl_no_revoke; /* disable SSL certificate revocation checks */
+ long ssh_auth_types; /* allowed SSH auth types */
+ bool http_te_skip; /* pass the raw body data to the user, even when
+ transfer-encoded (chunked, compressed) */
+ bool http_ce_skip; /* pass the raw body data to the user, even when
+ content-encoded (chunked, compressed) */
+ long new_file_perms; /* Permissions to use when creating remote files */
+ long new_directory_perms; /* Permissions to use when creating remote dirs */
+ bool proxy_transfer_mode; /* set transfer mode (;type=<a|i>) when doing FTP
+ via an HTTP proxy */
+ char *str[STRING_LAST]; /* array of strings, pointing to allocated memory */
+ unsigned int scope_id; /* Scope id for IPv6 */
+ long allowed_protocols;
+ long redir_protocols;
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+ long socks5_gssapi_nec; /* flag to support nec socks5 server */
+#endif
+ struct curl_slist *mail_rcpt; /* linked list of mail recipients */
+ bool sasl_ir; /* Enable/disable SASL initial response */
+ /* Common RTSP header options */
+ Curl_RtspReq rtspreq; /* RTSP request type */
+ long rtspversion; /* like httpversion, for RTSP */
+ bool wildcardmatch; /* enable wildcard matching */
+ curl_chunk_bgn_callback chunk_bgn; /* called before part of transfer
+ starts */
+ curl_chunk_end_callback chunk_end; /* called after part transferring
+ stopped */
+ curl_fnmatch_callback fnmatch; /* callback to decide which file corresponds
+ to pattern (e.g. if WILDCARDMATCH is on) */
+ void *fnmatch_data;
+
+ long gssapi_delegation; /* GSS-API credential delegation, see the
+ documentation of CURLOPT_GSSAPI_DELEGATION */
+
+ bool tcp_keepalive; /* use TCP keepalives */
+ long tcp_keepidle; /* seconds in idle before sending keepalive probe */
+ long tcp_keepintvl; /* seconds between TCP keepalive probes */
+
+ size_t maxconnects; /* Max idle connections in the connection cache */
+
+ bool ssl_enable_npn; /* TLS NPN extension? */
+ bool ssl_enable_alpn; /* TLS ALPN extension? */
+ bool path_as_is; /* allow dotdots? */
+ bool pipewait; /* wait for pipe/multiplex status before starting a
+ new connection */
+ long expect_100_timeout; /* in milliseconds */
+};
+
+struct Names {
+ struct curl_hash *hostcache;
+ enum {
+ HCACHE_NONE, /* not pointing to anything */
+ HCACHE_GLOBAL, /* points to the (shrug) global one */
+ HCACHE_MULTI, /* points to a shared one in the multi handle */
+ HCACHE_SHARED /* points to a shared one in a shared object */
+ } hostcachetype;
+};
+
+/*
+ * The 'connectdata' struct MUST have all the connection oriented stuff as we
+ * may have several simultaneous connections and connection structs in memory.
+ *
+ * The 'struct UserDefined' must only contain data that is set once to go for
+ * many (perhaps) independent connections. Values that are generated or
+ * calculated internally for the "session handle" must be defined within the
+ * 'struct UrlState' instead.
+ */
+
+struct SessionHandle {
+ /* first, two fields for the linked list of these */
+ struct SessionHandle *next;
+ struct SessionHandle *prev;
+
+ struct connectdata *easy_conn; /* the "unit's" connection */
+
+ CURLMstate mstate; /* the handle's state */
+ CURLcode result; /* previous result */
+
+ struct Curl_message msg; /* A single posted message. */
+
+ /* Array with the plain socket numbers this handle takes care of, in no
+ particular order. Note that all sockets are added to the sockhash, where
+ the state etc are also kept. This array is mostly used to detect when a
+ socket is to be removed from the hash. See singlesocket(). */
+ curl_socket_t sockets[MAX_SOCKSPEREASYHANDLE];
+ int numsocks;
+
+ struct Names dns;
+ struct Curl_multi *multi; /* if non-NULL, points to the multi handle
+ struct to which this "belongs" when used by
+ the multi interface */
+ struct Curl_multi *multi_easy; /* if non-NULL, points to the multi handle
+ struct to which this "belongs" when used
+ by the easy interface */
+ struct Curl_share *share; /* Share, handles global variable mutexing */
+ struct SingleRequest req; /* Request-specific data */
+ struct UserDefined set; /* values set by the libcurl user */
+ struct DynamicStatic change; /* possibly modified userdefined data */
+ struct CookieInfo *cookies; /* the cookies, read from files and servers.
+ NOTE that the 'cookie' field in the
+ UserDefined struct defines if the "engine"
+ is to be used or not. */
+ struct Progress progress; /* for all the progress meter data */
+ struct UrlState state; /* struct for fields used for state info and
+ other dynamic purposes */
+ struct WildcardData wildcard; /* wildcard download state info */
+ struct PureInfo info; /* stats, reports and info data */
+ struct curl_tlssessioninfo tsi; /* Information about the TLS session, only
+ valid after a client has asked for it */
+#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
+ iconv_t outbound_cd; /* for translating to the network encoding */
+ iconv_t inbound_cd; /* for translating from the network encoding */
+ iconv_t utf8_cd; /* for translating to UTF8 */
+#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
+ unsigned int magic; /* set to a CURLEASY_MAGIC_NUMBER */
+};
+
+#define LIBCURL_NAME "libcurl"
+
+#endif /* HEADER_CURL_URLDATA_H */
diff --git a/Utilities/cmcurl/lib/version.c b/Utilities/cmcurl/lib/version.c
new file mode 100644
index 000000000..1727c5a7d
--- /dev/null
+++ b/Utilities/cmcurl/lib/version.c
@@ -0,0 +1,362 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "vtls/vtls.h"
+#include "http2.h"
+#include "curl_printf.h"
+
+#ifdef USE_ARES
+# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
+ (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__))
+# define CARES_STATICLIB
+# endif
+# include <ares.h>
+#endif
+
+#ifdef USE_LIBIDN
+#include <stringprep.h>
+#endif
+
+#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
+#include <iconv.h>
+#endif
+
+#ifdef USE_LIBRTMP
+#include <librtmp/rtmp.h>
+#endif
+
+#ifdef USE_LIBSSH2
+#include <libssh2.h>
+#endif
+
+#ifdef HAVE_LIBSSH2_VERSION
+/* get it run-time if possible */
+#define CURL_LIBSSH2_VERSION libssh2_version(0)
+#else
+/* use build-time if run-time not possible */
+#define CURL_LIBSSH2_VERSION LIBSSH2_VERSION
+#endif
+
+char *curl_version(void)
+{
+ static char version[200];
+ char *ptr = version;
+ size_t len;
+ size_t left = sizeof(version);
+
+ strcpy(ptr, LIBCURL_NAME "/" LIBCURL_VERSION);
+ len = strlen(ptr);
+ left -= len;
+ ptr += len;
+
+ if(left > 1) {
+ len = Curl_ssl_version(ptr + 1, left - 1);
+
+ if(len > 0) {
+ *ptr = ' ';
+ left -= ++len;
+ ptr += len;
+ }
+ }
+
+#ifdef HAVE_LIBZ
+ len = snprintf(ptr, left, " zlib/%s", zlibVersion());
+ left -= len;
+ ptr += len;
+#endif
+#ifdef USE_ARES
+ /* this function is only present in c-ares, not in the original ares */
+ len = snprintf(ptr, left, " c-ares/%s", ares_version(NULL));
+ left -= len;
+ ptr += len;
+#endif
+#ifdef USE_LIBIDN
+ if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
+ len = snprintf(ptr, left, " libidn/%s", stringprep_check_version(NULL));
+ left -= len;
+ ptr += len;
+ }
+#endif
+#ifdef USE_WIN32_IDN
+ len = snprintf(ptr, left, " WinIDN");
+ left -= len;
+ ptr += len;
+#endif
+#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
+#ifdef _LIBICONV_VERSION
+ len = snprintf(ptr, left, " iconv/%d.%d",
+ _LIBICONV_VERSION >> 8, _LIBICONV_VERSION & 255);
+#else
+ /* version unknown */
+ len = snprintf(ptr, left, " iconv");
+#endif /* _LIBICONV_VERSION */
+ left -= len;
+ ptr += len;
+#endif
+#ifdef USE_LIBSSH2
+ len = snprintf(ptr, left, " libssh2/%s", CURL_LIBSSH2_VERSION);
+ left -= len;
+ ptr += len;
+#endif
+#ifdef USE_NGHTTP2
+ len = Curl_http2_ver(ptr, left);
+ left -= len;
+ ptr += len;
+#endif
+#ifdef USE_LIBRTMP
+ {
+ char suff[2];
+ if(RTMP_LIB_VERSION & 0xff) {
+ suff[0] = (RTMP_LIB_VERSION & 0xff) + 'a' - 1;
+ suff[1] = '\0';
+ }
+ else
+ suff[0] = '\0';
+
+ snprintf(ptr, left, " librtmp/%d.%d%s",
+ RTMP_LIB_VERSION >> 16, (RTMP_LIB_VERSION >> 8) & 0xff,
+ suff);
+/*
+ If another lib version is added below this one, this code would
+ also have to do:
+
+ len = what snprintf() returned
+
+ left -= len;
+ ptr += len;
+*/
+ }
+#endif
+
+ return version;
+}
+
+/* data for curl_version_info
+
+ Keep the list sorted alphabetically. It is also written so that each
+ protocol line has its own #if line to make things easier on the eye.
+ */
+
+static const char * const protocols[] = {
+#ifndef CURL_DISABLE_DICT
+ "dict",
+#endif
+#ifndef CURL_DISABLE_FILE
+ "file",
+#endif
+#ifndef CURL_DISABLE_FTP
+ "ftp",
+#endif
+#if defined(USE_SSL) && !defined(CURL_DISABLE_FTP)
+ "ftps",
+#endif
+#ifndef CURL_DISABLE_GOPHER
+ "gopher",
+#endif
+#ifndef CURL_DISABLE_HTTP
+ "http",
+#endif
+#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
+ "https",
+#endif
+#ifndef CURL_DISABLE_IMAP
+ "imap",
+#endif
+#if defined(USE_SSL) && !defined(CURL_DISABLE_IMAP)
+ "imaps",
+#endif
+#ifndef CURL_DISABLE_LDAP
+ "ldap",
+#if !defined(CURL_DISABLE_LDAPS) && \
+ ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \
+ (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))
+ "ldaps",
+#endif
+#endif
+#ifndef CURL_DISABLE_POP3
+ "pop3",
+#endif
+#if defined(USE_SSL) && !defined(CURL_DISABLE_POP3)
+ "pop3s",
+#endif
+#ifdef USE_LIBRTMP
+ "rtmp",
+#endif
+#ifndef CURL_DISABLE_RTSP
+ "rtsp",
+#endif
+#ifdef USE_LIBSSH2
+ "scp",
+#endif
+#ifdef USE_LIBSSH2
+ "sftp",
+#endif
+#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
+ (CURL_SIZEOF_CURL_OFF_T > 4) && \
+ (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO))
+ "smb",
+# ifdef USE_SSL
+ "smbs",
+# endif
+#endif
+#ifndef CURL_DISABLE_SMTP
+ "smtp",
+#endif
+#if defined(USE_SSL) && !defined(CURL_DISABLE_SMTP)
+ "smtps",
+#endif
+#ifndef CURL_DISABLE_TELNET
+ "telnet",
+#endif
+#ifndef CURL_DISABLE_TFTP
+ "tftp",
+#endif
+
+ NULL
+};
+
+static curl_version_info_data version_info = {
+ CURLVERSION_NOW,
+ LIBCURL_VERSION,
+ LIBCURL_VERSION_NUM,
+ OS, /* as found by configure or set by hand at build-time */
+ 0 /* features is 0 by default */
+#ifdef ENABLE_IPV6
+ | CURL_VERSION_IPV6
+#endif
+#ifdef USE_SSL
+ | CURL_VERSION_SSL
+#endif
+#ifdef USE_NTLM
+ | CURL_VERSION_NTLM
+#endif
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
+ defined(NTLM_WB_ENABLED)
+ | CURL_VERSION_NTLM_WB
+#endif
+#ifdef USE_SPNEGO
+ | CURL_VERSION_SPNEGO
+#endif
+#ifdef USE_KERBEROS5
+ | CURL_VERSION_KERBEROS5
+#endif
+#ifdef HAVE_GSSAPI
+ | CURL_VERSION_GSSAPI
+#endif
+#ifdef USE_WINDOWS_SSPI
+ | CURL_VERSION_SSPI
+#endif
+#ifdef HAVE_LIBZ
+ | CURL_VERSION_LIBZ
+#endif
+#ifdef DEBUGBUILD
+ | CURL_VERSION_DEBUG
+#endif
+#ifdef CURLDEBUG
+ | CURL_VERSION_CURLDEBUG
+#endif
+#ifdef CURLRES_ASYNCH
+ | CURL_VERSION_ASYNCHDNS
+#endif
+#if (CURL_SIZEOF_CURL_OFF_T > 4) && \
+ ( (SIZEOF_OFF_T > 4) || defined(USE_WIN32_LARGE_FILES) )
+ | CURL_VERSION_LARGEFILE
+#endif
+#if defined(CURL_DOES_CONVERSIONS)
+ | CURL_VERSION_CONV
+#endif
+#if defined(USE_TLS_SRP)
+ | CURL_VERSION_TLSAUTH_SRP
+#endif
+#if defined(USE_NGHTTP2)
+ | CURL_VERSION_HTTP2
+#endif
+#if defined(USE_UNIX_SOCKETS)
+ | CURL_VERSION_UNIX_SOCKETS
+#endif
+ ,
+ NULL, /* ssl_version */
+ 0, /* ssl_version_num, this is kept at zero */
+ NULL, /* zlib_version */
+ protocols,
+ NULL, /* c-ares version */
+ 0, /* c-ares version numerical */
+ NULL, /* libidn version */
+ 0, /* iconv version */
+ NULL, /* ssh lib version */
+};
+
+curl_version_info_data *curl_version_info(CURLversion stamp)
+{
+#ifdef USE_LIBSSH2
+ static char ssh_buffer[80];
+#endif
+
+#ifdef USE_SSL
+ static char ssl_buffer[80];
+ Curl_ssl_version(ssl_buffer, sizeof(ssl_buffer));
+ version_info.ssl_version = ssl_buffer;
+#endif
+
+#ifdef HAVE_LIBZ
+ version_info.libz_version = zlibVersion();
+ /* libz left NULL if non-existing */
+#endif
+#ifdef USE_ARES
+ {
+ int aresnum;
+ version_info.ares = ares_version(&aresnum);
+ version_info.ares_num = aresnum;
+ }
+#endif
+#ifdef USE_LIBIDN
+ /* This returns a version string if we use the given version or later,
+ otherwise it returns NULL */
+ version_info.libidn = stringprep_check_version(LIBIDN_REQUIRED_VERSION);
+ if(version_info.libidn)
+ version_info.features |= CURL_VERSION_IDN;
+#elif defined(USE_WIN32_IDN)
+ version_info.features |= CURL_VERSION_IDN;
+#endif
+
+#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
+#ifdef _LIBICONV_VERSION
+ version_info.iconv_ver_num = _LIBICONV_VERSION;
+#else
+ /* version unknown */
+ version_info.iconv_ver_num = -1;
+#endif /* _LIBICONV_VERSION */
+#endif
+
+#ifdef USE_LIBSSH2
+ snprintf(ssh_buffer, sizeof(ssh_buffer), "libssh2/%s", LIBSSH2_VERSION);
+ version_info.libssh_version = ssh_buffer;
+#endif
+
+ (void)stamp; /* avoid compiler warnings, we don't use this */
+
+ return &version_info;
+}
diff --git a/Utilities/cmcurl/lib/vtls/axtls.c b/Utilities/cmcurl/lib/vtls/axtls.c
new file mode 100644
index 000000000..1038432b9
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/axtls.c
@@ -0,0 +1,690 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2010, DirecTV, Contact: Eric Hu, <ehu@directv.com>.
+ * Copyright (C) 2010 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all axTLS-specific code for the TLS/SSL layer. No code
+ * but vtls.c should ever call or use these functions.
+ */
+
+#include "curl_setup.h"
+
+#ifdef USE_AXTLS
+#include <axTLS/config.h>
+#include <axTLS/ssl.h>
+#include "axtls.h"
+
+#include "sendf.h"
+#include "inet_pton.h"
+#include "vtls.h"
+#include "parsedate.h"
+#include "connect.h" /* for the connect timeout */
+#include "select.h"
+#include "curl_printf.h"
+#include "hostcheck.h"
+#include <unistd.h>
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+
+/* Global axTLS init, called from Curl_ssl_init() */
+int Curl_axtls_init(void)
+{
+/* axTLS has no global init. Everything is done through SSL and SSL_CTX
+ * structs stored in connectdata structure. Perhaps can move to axtls.h.
+ */
+ return 1;
+}
+
+int Curl_axtls_cleanup(void)
+{
+ /* axTLS has no global cleanup. Perhaps can move this to axtls.h. */
+ return 1;
+}
+
+static CURLcode map_error_to_curl(int axtls_err)
+{
+ switch (axtls_err) {
+ case SSL_ERROR_NOT_SUPPORTED:
+ case SSL_ERROR_INVALID_VERSION:
+ case -70: /* protocol version alert from server */
+ return CURLE_UNSUPPORTED_PROTOCOL;
+ break;
+ case SSL_ERROR_NO_CIPHER:
+ return CURLE_SSL_CIPHER;
+ break;
+ case SSL_ERROR_BAD_CERTIFICATE: /* this may be bad server cert too */
+ case SSL_ERROR_NO_CERT_DEFINED:
+ case -42: /* bad certificate alert from server */
+ case -43: /* unsupported cert alert from server */
+ case -44: /* cert revoked alert from server */
+ case -45: /* cert expired alert from server */
+ case -46: /* cert unknown alert from server */
+ return CURLE_SSL_CERTPROBLEM;
+ break;
+ case SSL_X509_ERROR(X509_NOT_OK):
+ case SSL_X509_ERROR(X509_VFY_ERROR_NO_TRUSTED_CERT):
+ case SSL_X509_ERROR(X509_VFY_ERROR_BAD_SIGNATURE):
+ case SSL_X509_ERROR(X509_VFY_ERROR_NOT_YET_VALID):
+ case SSL_X509_ERROR(X509_VFY_ERROR_EXPIRED):
+ case SSL_X509_ERROR(X509_VFY_ERROR_SELF_SIGNED):
+ case SSL_X509_ERROR(X509_VFY_ERROR_INVALID_CHAIN):
+ case SSL_X509_ERROR(X509_VFY_ERROR_UNSUPPORTED_DIGEST):
+ case SSL_X509_ERROR(X509_INVALID_PRIV_KEY):
+ return CURLE_PEER_FAILED_VERIFICATION;
+ break;
+ case -48: /* unknown ca alert from server */
+ return CURLE_SSL_CACERT;
+ break;
+ case -49: /* access denied alert from server */
+ return CURLE_REMOTE_ACCESS_DENIED;
+ break;
+ case SSL_ERROR_CONN_LOST:
+ case SSL_ERROR_SOCK_SETUP_FAILURE:
+ case SSL_ERROR_INVALID_HANDSHAKE:
+ case SSL_ERROR_INVALID_PROT_MSG:
+ case SSL_ERROR_INVALID_HMAC:
+ case SSL_ERROR_INVALID_SESSION:
+ case SSL_ERROR_INVALID_KEY: /* it's too bad this doesn't map better */
+ case SSL_ERROR_FINISHED_INVALID:
+ case SSL_ERROR_NO_CLIENT_RENOG:
+ default:
+ return CURLE_SSL_CONNECT_ERROR;
+ break;
+ }
+}
+
+static Curl_recv axtls_recv;
+static Curl_send axtls_send;
+
+static void free_ssl_structs(struct ssl_connect_data *connssl)
+{
+ if(connssl->ssl) {
+ ssl_free (connssl->ssl);
+ connssl->ssl = NULL;
+ }
+ if(connssl->ssl_ctx) {
+ ssl_ctx_free(connssl->ssl_ctx);
+ connssl->ssl_ctx = NULL;
+ }
+}
+
+/*
+ * For both blocking and non-blocking connects, this function sets up the
+ * ssl context and state. This function is called after the TCP connect
+ * has completed.
+ */
+static CURLcode connect_prep(struct connectdata *conn, int sockindex)
+{
+ struct SessionHandle *data = conn->data;
+ SSL_CTX *ssl_ctx;
+ SSL *ssl = NULL;
+ int cert_types[] = {SSL_OBJ_X509_CERT, SSL_OBJ_PKCS12, 0};
+ int key_types[] = {SSL_OBJ_RSA_KEY, SSL_OBJ_PKCS8, SSL_OBJ_PKCS12, 0};
+ int i, ssl_fcn_return;
+ const uint8_t *ssl_sessionid;
+ size_t ssl_idsize;
+
+ /* Assuming users will not compile in custom key/cert to axTLS.
+ * Also, even for blocking connects, use axTLS non-blocking feature.
+ */
+ uint32_t client_option = SSL_NO_DEFAULT_KEY |
+ SSL_SERVER_VERIFY_LATER |
+ SSL_CONNECT_IN_PARTS;
+
+ if(conn->ssl[sockindex].state == ssl_connection_complete)
+ /* to make us tolerant against being called more than once for the
+ same connection */
+ return CURLE_OK;
+
+ /* axTLS only supports TLSv1 */
+ /* check to see if we've been told to use an explicit SSL/TLS version */
+ switch(data->set.ssl.version) {
+ case CURL_SSLVERSION_DEFAULT:
+ case CURL_SSLVERSION_TLSv1:
+ break;
+ default:
+ failf(data, "axTLS only supports TLS 1.0 and 1.1, "
+ "and it cannot be specified which one to use");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
+#ifdef AXTLSDEBUG
+ client_option |= SSL_DISPLAY_STATES | SSL_DISPLAY_RSA | SSL_DISPLAY_CERTS;
+#endif /* AXTLSDEBUG */
+
+ /* Allocate an SSL_CTX struct */
+ ssl_ctx = ssl_ctx_new(client_option, SSL_DEFAULT_CLNT_SESS);
+ if(ssl_ctx == NULL) {
+ failf(data, "unable to create client SSL context");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
+ conn->ssl[sockindex].ssl_ctx = ssl_ctx;
+ conn->ssl[sockindex].ssl = NULL;
+
+ /* Load the trusted CA cert bundle file */
+ if(data->set.ssl.CAfile) {
+ if(ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT, data->set.ssl.CAfile, NULL)
+ != SSL_OK) {
+ infof(data, "error reading ca cert file %s \n",
+ data->set.ssl.CAfile);
+ if(data->set.ssl.verifypeer) {
+ return CURLE_SSL_CACERT_BADFILE;
+ }
+ }
+ else
+ infof(data, "found certificates in %s\n", data->set.ssl.CAfile);
+ }
+
+ /* gtls.c tasks we're skipping for now:
+ * 1) certificate revocation list checking
+ * 2) dns name assignment to host
+ * 3) set protocol priority. axTLS is TLSv1 only, so can probably ignore
+ * 4) set certificate priority. axTLS ignores type and sends certs in
+ * order added. can probably ignore this.
+ */
+
+ /* Load client certificate */
+ if(data->set.str[STRING_CERT]) {
+ i=0;
+ /* Instead of trying to analyze cert type here, let axTLS try them all. */
+ while(cert_types[i] != 0) {
+ ssl_fcn_return = ssl_obj_load(ssl_ctx, cert_types[i],
+ data->set.str[STRING_CERT], NULL);
+ if(ssl_fcn_return == SSL_OK) {
+ infof(data, "successfully read cert file %s \n",
+ data->set.str[STRING_CERT]);
+ break;
+ }
+ i++;
+ }
+ /* Tried all cert types, none worked. */
+ if(cert_types[i] == 0) {
+ failf(data, "%s is not x509 or pkcs12 format",
+ data->set.str[STRING_CERT]);
+ return CURLE_SSL_CERTPROBLEM;
+ }
+ }
+
+ /* Load client key.
+ If a pkcs12 file successfully loaded a cert, then there's nothing to do
+ because the key has already been loaded. */
+ if(data->set.str[STRING_KEY] && cert_types[i] != SSL_OBJ_PKCS12) {
+ i=0;
+ /* Instead of trying to analyze key type here, let axTLS try them all. */
+ while(key_types[i] != 0) {
+ ssl_fcn_return = ssl_obj_load(ssl_ctx, key_types[i],
+ data->set.str[STRING_KEY], NULL);
+ if(ssl_fcn_return == SSL_OK) {
+ infof(data, "successfully read key file %s \n",
+ data->set.str[STRING_KEY]);
+ break;
+ }
+ i++;
+ }
+ /* Tried all key types, none worked. */
+ if(key_types[i] == 0) {
+ failf(data, "Failure: %s is not a supported key file",
+ data->set.str[STRING_KEY]);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ }
+
+ /* gtls.c does more here that is being left out for now
+ * 1) set session credentials. can probably ignore since axtls puts this
+ * info in the ssl_ctx struct
+ * 2) setting up callbacks. these seem gnutls specific
+ */
+
+ /* In axTLS, handshaking happens inside ssl_client_new. */
+ if(!Curl_ssl_getsessionid(conn, (void **) &ssl_sessionid, &ssl_idsize)) {
+ /* we got a session id, use it! */
+ infof (data, "SSL re-using session ID\n");
+ ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex],
+ ssl_sessionid, (uint8_t)ssl_idsize);
+ }
+ else
+ ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], NULL, 0);
+
+ conn->ssl[sockindex].ssl = ssl;
+ return CURLE_OK;
+}
+
+/*
+ * For both blocking and non-blocking connects, this function finalizes the
+ * SSL connection.
+ */
+static CURLcode connect_finish(struct connectdata *conn, int sockindex)
+{
+ struct SessionHandle *data = conn->data;
+ SSL *ssl = conn->ssl[sockindex].ssl;
+ const uint8_t *ssl_sessionid;
+ size_t ssl_idsize;
+ const char *peer_CN;
+ uint32_t dns_altname_index;
+ const char *dns_altname;
+ int8_t found_subject_alt_names = 0;
+ int8_t found_subject_alt_name_matching_conn = 0;
+
+ /* Here, gtls.c gets the peer certificates and fails out depending on
+ * settings in "data." axTLS api doesn't have get cert chain fcn, so omit?
+ */
+
+ /* Verify server's certificate */
+ if(data->set.ssl.verifypeer) {
+ if(ssl_verify_cert(ssl) != SSL_OK) {
+ Curl_axtls_close(conn, sockindex);
+ failf(data, "server cert verify failed");
+ return CURLE_PEER_FAILED_VERIFICATION;
+ }
+ }
+ else
+ infof(data, "\t server certificate verification SKIPPED\n");
+
+ /* Here, gtls.c does issuer verification. axTLS has no straightforward
+ * equivalent, so omitting for now.*/
+
+ /* Here, gtls.c does the following
+ * 1) x509 hostname checking per RFC2818. axTLS doesn't support this, but
+ * it seems useful. This is now implemented, by Oscar Koeroo
+ * 2) checks cert validity based on time. axTLS does this in ssl_verify_cert
+ * 3) displays a bunch of cert information. axTLS doesn't support most of
+ * this, but a couple fields are available.
+ */
+
+ /* There is no (DNS) Altnames count in the version 1.4.8 API. There is a
+ risk of an inifite loop */
+ for(dns_altname_index = 0; ; dns_altname_index++) {
+ dns_altname = ssl_get_cert_subject_alt_dnsname(ssl, dns_altname_index);
+ if(dns_altname == NULL) {
+ break;
+ }
+ found_subject_alt_names = 1;
+
+ infof(data, "\tComparing subject alt name DNS with hostname: %s <-> %s\n",
+ dns_altname, conn->host.name);
+ if(Curl_cert_hostcheck(dns_altname, conn->host.name)) {
+ found_subject_alt_name_matching_conn = 1;
+ break;
+ }
+ }
+
+ /* RFC2818 checks */
+ if(found_subject_alt_names && !found_subject_alt_name_matching_conn) {
+ if(data->set.ssl.verifyhost) {
+ /* Break connection ! */
+ Curl_axtls_close(conn, sockindex);
+ failf(data, "\tsubjectAltName(s) do not match %s\n",
+ conn->host.dispname);
+ return CURLE_PEER_FAILED_VERIFICATION;
+ }
+ else
+ infof(data, "\tsubjectAltName(s) do not match %s\n",
+ conn->host.dispname);
+ }
+ else if(found_subject_alt_names == 0) {
+ /* Per RFC2818, when no Subject Alt Names were available, examine the peer
+ CN as a legacy fallback */
+ peer_CN = ssl_get_cert_dn(ssl, SSL_X509_CERT_COMMON_NAME);
+ if(peer_CN == NULL) {
+ if(data->set.ssl.verifyhost) {
+ Curl_axtls_close(conn, sockindex);
+ failf(data, "unable to obtain common name from peer certificate");
+ return CURLE_PEER_FAILED_VERIFICATION;
+ }
+ else
+ infof(data, "unable to obtain common name from peer certificate");
+ }
+ else {
+ if(!Curl_cert_hostcheck((const char *)peer_CN, conn->host.name)) {
+ if(data->set.ssl.verifyhost) {
+ /* Break connection ! */
+ Curl_axtls_close(conn, sockindex);
+ failf(data, "\tcommon name \"%s\" does not match \"%s\"\n",
+ peer_CN, conn->host.dispname);
+ return CURLE_PEER_FAILED_VERIFICATION;
+ }
+ else
+ infof(data, "\tcommon name \"%s\" does not match \"%s\"\n",
+ peer_CN, conn->host.dispname);
+ }
+ }
+ }
+
+ /* General housekeeping */
+ conn->ssl[sockindex].state = ssl_connection_complete;
+ conn->recv[sockindex] = axtls_recv;
+ conn->send[sockindex] = axtls_send;
+
+ /* Put our freshly minted SSL session in cache */
+ ssl_idsize = ssl_get_session_id_size(ssl);
+ ssl_sessionid = ssl_get_session_id(ssl);
+ if(Curl_ssl_addsessionid(conn, (void *) ssl_sessionid, ssl_idsize)
+ != CURLE_OK)
+ infof (data, "failed to add session to cache\n");
+
+ return CURLE_OK;
+}
+
+/*
+ * Use axTLS's non-blocking connection feature to open an SSL connection.
+ * This is called after a TCP connection is already established.
+ */
+CURLcode Curl_axtls_connect_nonblocking(
+ struct connectdata *conn,
+ int sockindex,
+ bool *done)
+{
+ CURLcode conn_step;
+ int ssl_fcn_return;
+ int i;
+
+ *done = FALSE;
+ /* connectdata is calloc'd and connecting_state is only changed in this
+ function, so this is safe, as the state is effectively initialized. */
+ if(conn->ssl[sockindex].connecting_state == ssl_connect_1) {
+ conn_step = connect_prep(conn, sockindex);
+ if(conn_step != CURLE_OK) {
+ Curl_axtls_close(conn, sockindex);
+ return conn_step;
+ }
+ conn->ssl[sockindex].connecting_state = ssl_connect_2;
+ }
+
+ if(conn->ssl[sockindex].connecting_state == ssl_connect_2) {
+ /* Check to make sure handshake was ok. */
+ if(ssl_handshake_status(conn->ssl[sockindex].ssl) != SSL_OK) {
+ /* Loop to perform more work in between sleeps. This is work around the
+ fact that axtls does not expose any knowledge about when work needs
+ to be performed. This can save ~25% of time on SSL handshakes. */
+ for(i=0; i<5; i++) {
+ ssl_fcn_return = ssl_read(conn->ssl[sockindex].ssl, NULL);
+ if(ssl_fcn_return < 0) {
+ Curl_axtls_close(conn, sockindex);
+ ssl_display_error(ssl_fcn_return); /* goes to stdout. */
+ return map_error_to_curl(ssl_fcn_return);
+ }
+ return CURLE_OK;
+ }
+ }
+ infof (conn->data, "handshake completed successfully\n");
+ conn->ssl[sockindex].connecting_state = ssl_connect_3;
+ }
+
+ if(conn->ssl[sockindex].connecting_state == ssl_connect_3) {
+ conn_step = connect_finish(conn, sockindex);
+ if(conn_step != CURLE_OK) {
+ Curl_axtls_close(conn, sockindex);
+ return conn_step;
+ }
+
+ /* Reset connect state */
+ conn->ssl[sockindex].connecting_state = ssl_connect_1;
+
+ *done = TRUE;
+ return CURLE_OK;
+ }
+
+ /* Unrecognized state. Things are very bad. */
+ conn->ssl[sockindex].state = ssl_connection_none;
+ conn->ssl[sockindex].connecting_state = ssl_connect_1;
+ /* Return value perhaps not strictly correct, but distinguishes the issue.*/
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+}
+
+
+/*
+ * This function is called after the TCP connect has completed. Setup the TLS
+ * layer and do all necessary magic for a blocking connect.
+ */
+CURLcode
+Curl_axtls_connect(struct connectdata *conn,
+ int sockindex)
+
+{
+ struct SessionHandle *data = conn->data;
+ CURLcode conn_step = connect_prep(conn, sockindex);
+ int ssl_fcn_return;
+ SSL *ssl = conn->ssl[sockindex].ssl;
+ long timeout_ms;
+
+ if(conn_step != CURLE_OK) {
+ Curl_axtls_close(conn, sockindex);
+ return conn_step;
+ }
+
+ /* Check to make sure handshake was ok. */
+ while(ssl_handshake_status(ssl) != SSL_OK) {
+ /* check allowed time left */
+ timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+ if(timeout_ms < 0) {
+ /* no need to continue if time already is up */
+ failf(data, "SSL connection timeout");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+
+ ssl_fcn_return = ssl_read(ssl, NULL);
+ if(ssl_fcn_return < 0) {
+ Curl_axtls_close(conn, sockindex);
+ ssl_display_error(ssl_fcn_return); /* goes to stdout. */
+ return map_error_to_curl(ssl_fcn_return);
+ }
+ /* TODO: avoid polling */
+ usleep(10000);
+ }
+ infof (conn->data, "handshake completed successfully\n");
+
+ conn_step = connect_finish(conn, sockindex);
+ if(conn_step != CURLE_OK) {
+ Curl_axtls_close(conn, sockindex);
+ return conn_step;
+ }
+
+ return CURLE_OK;
+}
+
+/* return number of sent (non-SSL) bytes */
+static ssize_t axtls_send(struct connectdata *conn,
+ int sockindex,
+ const void *mem,
+ size_t len,
+ CURLcode *err)
+{
+ /* ssl_write() returns 'int' while write() and send() returns 'size_t' */
+ int rc = ssl_write(conn->ssl[sockindex].ssl, mem, (int)len);
+
+ infof(conn->data, " axtls_send\n");
+
+ if(rc < 0 ) {
+ *err = map_error_to_curl(rc);
+ rc = -1; /* generic error code for send failure */
+ }
+
+ *err = CURLE_OK;
+ return rc;
+}
+
+void Curl_axtls_close(struct connectdata *conn, int sockindex)
+{
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+ infof(conn->data, " Curl_axtls_close\n");
+
+ /* line from openssl.c: (void)SSL_shutdown(connssl->ssl);
+ axTLS compat layer does nothing for SSL_shutdown */
+
+ /* The following line is from openssl.c. There seems to be no axTLS
+ equivalent. ssl_free and ssl_ctx_free close things.
+ SSL_set_connect_state(connssl->handle); */
+
+ free_ssl_structs(connssl);
+}
+
+/*
+ * This function is called to shut down the SSL layer but keep the
+ * socket open (CCC - Clear Command Channel)
+ */
+int Curl_axtls_shutdown(struct connectdata *conn, int sockindex)
+{
+ /* Outline taken from openssl.c since functions are in axTLS compat layer.
+ axTLS's error set is much smaller, so a lot of error-handling was removed.
+ */
+ int retval = 0;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct SessionHandle *data = conn->data;
+ uint8_t *buf;
+ ssize_t nread;
+
+ infof(conn->data, " Curl_axtls_shutdown\n");
+
+ /* This has only been tested on the proftpd server, and the mod_tls code
+ sends a close notify alert without waiting for a close notify alert in
+ response. Thus we wait for a close notify alert from the server, but
+ we do not send one. Let's hope other servers do the same... */
+
+ /* axTLS compat layer does nothing for SSL_shutdown, so we do nothing too
+ if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
+ (void)SSL_shutdown(connssl->ssl);
+ */
+
+ if(connssl->ssl) {
+ int what = Curl_socket_ready(conn->sock[sockindex],
+ CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
+ if(what > 0) {
+ /* Something to read, let's do it and hope that it is the close
+ notify alert from the server. buf is managed internally by
+ axTLS and will be released upon calling ssl_free via
+ free_ssl_structs. */
+ nread = (ssize_t)ssl_read(connssl->ssl, &buf);
+
+ if(nread < SSL_OK) {
+ failf(data, "close notify alert not received during shutdown");
+ retval = -1;
+ }
+ }
+ else if(0 == what) {
+ /* timeout */
+ failf(data, "SSL shutdown timeout");
+ }
+ else {
+ /* anything that gets here is fatally bad */
+ failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+ retval = -1;
+ }
+
+ free_ssl_structs(connssl);
+ }
+ return retval;
+}
+
+static ssize_t axtls_recv(struct connectdata *conn, /* connection data */
+ int num, /* socketindex */
+ char *buf, /* store read data here */
+ size_t buffersize, /* max amount to read */
+ CURLcode *err)
+{
+ struct ssl_connect_data *connssl = &conn->ssl[num];
+ ssize_t ret = 0;
+ uint8_t *read_buf;
+
+ infof(conn->data, " axtls_recv\n");
+
+ *err = CURLE_OK;
+ if(connssl) {
+ ret = ssl_read(connssl->ssl, &read_buf);
+ if(ret > SSL_OK) {
+ /* ssl_read returns SSL_OK if there is more data to read, so if it is
+ larger, then all data has been read already. */
+ memcpy(buf, read_buf,
+ (size_t)ret > buffersize ? buffersize : (size_t)ret);
+ }
+ else if(ret == SSL_OK) {
+ /* more data to be read, signal caller to call again */
+ *err = CURLE_AGAIN;
+ ret = -1;
+ }
+ else if(ret == -3) {
+ /* With patched axTLS, SSL_CLOSE_NOTIFY=-3. Hard-coding until axTLS
+ team approves proposed fix. */
+ Curl_axtls_close(conn, num);
+ }
+ else {
+ failf(conn->data, "axTLS recv error (%d)", ret);
+ *err = map_error_to_curl((int) ret);
+ ret = -1;
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * Return codes:
+ * 1 means the connection is still in place
+ * 0 means the connection has been closed
+ * -1 means the connection status is unknown
+ */
+int Curl_axtls_check_cxn(struct connectdata *conn)
+{
+ /* openssl.c line: rc = SSL_peek(conn->ssl[FIRSTSOCKET].ssl, (void*)&buf, 1);
+ axTLS compat layer always returns the last argument, so connection is
+ always alive? */
+
+ infof(conn->data, " Curl_axtls_check_cxn\n");
+ return 1; /* connection still in place */
+}
+
+void Curl_axtls_session_free(void *ptr)
+{
+ (void)ptr;
+ /* free the ID */
+ /* both openssl.c and gtls.c do something here, but axTLS's OpenSSL
+ compatibility layer does nothing, so we do nothing too. */
+}
+
+size_t Curl_axtls_version(char *buffer, size_t size)
+{
+ return snprintf(buffer, size, "axTLS/%s", ssl_version());
+}
+
+int Curl_axtls_random(struct SessionHandle *data,
+ unsigned char *entropy,
+ size_t length)
+{
+ static bool ssl_seeded = FALSE;
+ (void)data;
+ if(!ssl_seeded) {
+ ssl_seeded = TRUE;
+ /* Initialize the seed if not already done. This call is not exactly thread
+ * safe (and neither is the ssl_seeded check), but the worst effect of a
+ * race condition is that some global resources will leak. */
+ RNG_initialize();
+ }
+ get_random((int)length, entropy);
+ return 0;
+}
+
+#endif /* USE_AXTLS */
diff --git a/Utilities/cmcurl/lib/vtls/axtls.h b/Utilities/cmcurl/lib/vtls/axtls.h
new file mode 100644
index 000000000..223ecb8c9
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/axtls.h
@@ -0,0 +1,71 @@
+#ifndef HEADER_CURL_AXTLS_H
+#define HEADER_CURL_AXTLS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2010, DirecTV, Contact: Eric Hu <ehu@directv.com>
+ * Copyright (C) 2010 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifdef USE_AXTLS
+#include "curl/curl.h"
+#include "urldata.h"
+
+int Curl_axtls_init(void);
+int Curl_axtls_cleanup(void);
+CURLcode Curl_axtls_connect(struct connectdata *conn, int sockindex);
+CURLcode Curl_axtls_connect_nonblocking(
+ struct connectdata *conn,
+ int sockindex,
+ bool *done);
+
+ /* close a SSL connection */
+void Curl_axtls_close(struct connectdata *conn, int sockindex);
+
+void Curl_axtls_session_free(void *ptr);
+size_t Curl_axtls_version(char *buffer, size_t size);
+int Curl_axtls_shutdown(struct connectdata *conn, int sockindex);
+int Curl_axtls_check_cxn(struct connectdata *conn);
+int Curl_axtls_random(struct SessionHandle *data,
+ unsigned char *entropy,
+ size_t length);
+
+/* Set the API backend definition to axTLS */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_AXTLS
+
+/* API setup for axTLS */
+#define curlssl_init Curl_axtls_init
+#define curlssl_cleanup Curl_axtls_cleanup
+#define curlssl_connect Curl_axtls_connect
+#define curlssl_connect_nonblocking Curl_axtls_connect_nonblocking
+#define curlssl_session_free(x) Curl_axtls_session_free(x)
+#define curlssl_close_all(x) ((void)x)
+#define curlssl_close Curl_axtls_close
+#define curlssl_shutdown(x,y) Curl_axtls_shutdown(x,y)
+#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN)
+#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN)
+#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL)
+#define curlssl_version Curl_axtls_version
+#define curlssl_check_cxn(x) Curl_axtls_check_cxn(x)
+#define curlssl_data_pending(x,y) ((void)x, (void)y, 0)
+#define curlssl_random(x,y,z) Curl_axtls_random(x,y,z)
+
+#endif /* USE_AXTLS */
+#endif /* HEADER_CURL_AXTLS_H */
+
diff --git a/Utilities/cmcurl/lib/vtls/cyassl.c b/Utilities/cmcurl/lib/vtls/cyassl.c
new file mode 100644
index 000000000..3ded7f11d
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/cyassl.c
@@ -0,0 +1,786 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all CyaSSL-specific code for the TLS/SSL layer. No code
+ * but vtls.c should ever call or use these functions.
+ *
+ */
+
+#include "curl_setup.h"
+
+#ifdef USE_CYASSL
+
+#define WOLFSSL_OPTIONS_IGNORE_SYS
+/* CyaSSL's version.h, which should contain only the version, should come
+before all other CyaSSL includes and be immediately followed by build config
+aka options.h. http://curl.haxx.se/mail/lib-2015-04/0069.html */
+#include <cyassl/version.h>
+#if defined(HAVE_CYASSL_OPTIONS_H) && (LIBCYASSL_VERSION_HEX > 0x03004008)
+#if defined(CYASSL_API) || defined(WOLFSSL_API)
+/* Safety measure. If either is defined some API include was already included
+and that's a problem since options.h hasn't been included yet. */
+#error "CyaSSL API was included before the CyaSSL build options."
+#endif
+#include <cyassl/options.h>
+#endif
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "inet_pton.h"
+#include "cyassl.h"
+#include "vtls.h"
+#include "parsedate.h"
+#include "connect.h" /* for the connect timeout */
+#include "select.h"
+#include "rawstr.h"
+#include "x509asn1.h"
+#include "curl_printf.h"
+
+#include <cyassl/ssl.h>
+#ifdef HAVE_CYASSL_ERROR_SSL_H
+#include <cyassl/error-ssl.h>
+#else
+#include <cyassl/error.h>
+#endif
+#include <cyassl/ctaocrypt/random.h>
+#include <cyassl/ctaocrypt/sha256.h>
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#if LIBCYASSL_VERSION_HEX < 0x02007002 /* < 2.7.2 */
+#define CYASSL_MAX_ERROR_SZ 80
+#endif
+
+static Curl_recv cyassl_recv;
+static Curl_send cyassl_send;
+
+
+static int do_file_type(const char *type)
+{
+ if(!type || !type[0])
+ return SSL_FILETYPE_PEM;
+ if(Curl_raw_equal(type, "PEM"))
+ return SSL_FILETYPE_PEM;
+ if(Curl_raw_equal(type, "DER"))
+ return SSL_FILETYPE_ASN1;
+ return -1;
+}
+
+/*
+ * This function loads all the client/CA certificates and CRLs. Setup the TLS
+ * layer and do all necessary magic.
+ */
+static CURLcode
+cyassl_connect_step1(struct connectdata *conn,
+ int sockindex)
+{
+ char error_buffer[CYASSL_MAX_ERROR_SZ];
+ struct SessionHandle *data = conn->data;
+ struct ssl_connect_data* conssl = &conn->ssl[sockindex];
+ SSL_METHOD* req_method = NULL;
+ void* ssl_sessionid = NULL;
+ curl_socket_t sockfd = conn->sock[sockindex];
+#ifdef HAVE_SNI
+ bool sni = FALSE;
+#define use_sni(x) sni = (x)
+#else
+#define use_sni(x) Curl_nop_stmt
+#endif
+
+ if(conssl->state == ssl_connection_complete)
+ return CURLE_OK;
+
+ /* check to see if we've been told to use an explicit SSL/TLS version */
+ switch(data->set.ssl.version) {
+ case CURL_SSLVERSION_DEFAULT:
+ case CURL_SSLVERSION_TLSv1:
+#if LIBCYASSL_VERSION_HEX >= 0x03003000 /* >= 3.3.0 */
+ /* minimum protocol version is set later after the CTX object is created */
+ req_method = SSLv23_client_method();
+#else
+ infof(data, "CyaSSL <3.3.0 cannot be configured to use TLS 1.0-1.2, "
+ "TLS 1.0 is used exclusively\n");
+ req_method = TLSv1_client_method();
+#endif
+ use_sni(TRUE);
+ break;
+ case CURL_SSLVERSION_TLSv1_0:
+ req_method = TLSv1_client_method();
+ use_sni(TRUE);
+ break;
+ case CURL_SSLVERSION_TLSv1_1:
+ req_method = TLSv1_1_client_method();
+ use_sni(TRUE);
+ break;
+ case CURL_SSLVERSION_TLSv1_2:
+ req_method = TLSv1_2_client_method();
+ use_sni(TRUE);
+ break;
+ case CURL_SSLVERSION_SSLv3:
+ req_method = SSLv3_client_method();
+ use_sni(FALSE);
+ break;
+ case CURL_SSLVERSION_SSLv2:
+ failf(data, "CyaSSL does not support SSLv2");
+ return CURLE_SSL_CONNECT_ERROR;
+ default:
+ failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
+ if(!req_method) {
+ failf(data, "SSL: couldn't create a method!");
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ if(conssl->ctx)
+ SSL_CTX_free(conssl->ctx);
+ conssl->ctx = SSL_CTX_new(req_method);
+
+ if(!conssl->ctx) {
+ failf(data, "SSL: couldn't create a context!");
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ switch(data->set.ssl.version) {
+ case CURL_SSLVERSION_DEFAULT:
+ case CURL_SSLVERSION_TLSv1:
+#if LIBCYASSL_VERSION_HEX > 0x03004006 /* > 3.4.6 */
+ /* Versions 3.3.0 to 3.4.6 we know the minimum protocol version is whatever
+ minimum version of TLS was built in and at least TLS 1.0. For later library
+ versions that could change (eg TLS 1.0 built in but defaults to TLS 1.1) so
+ we have this short circuit evaluation to find the minimum supported TLS
+ version. We use wolfSSL_CTX_SetMinVersion and not CyaSSL_SetMinVersion
+ because only the former will work before the user's CTX callback is called.
+ */
+ if((wolfSSL_CTX_SetMinVersion(conssl->ctx, WOLFSSL_TLSV1) != 1) &&
+ (wolfSSL_CTX_SetMinVersion(conssl->ctx, WOLFSSL_TLSV1_1) != 1) &&
+ (wolfSSL_CTX_SetMinVersion(conssl->ctx, WOLFSSL_TLSV1_2) != 1)) {
+ failf(data, "SSL: couldn't set the minimum protocol version");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+#endif
+ break;
+ }
+
+#ifndef NO_FILESYSTEM
+ /* load trusted cacert */
+ if(data->set.str[STRING_SSL_CAFILE]) {
+ if(1 != SSL_CTX_load_verify_locations(conssl->ctx,
+ data->set.str[STRING_SSL_CAFILE],
+ data->set.str[STRING_SSL_CAPATH])) {
+ if(data->set.ssl.verifypeer) {
+ /* Fail if we insist on successfully verifying the server. */
+ failf(data, "error setting certificate verify locations:\n"
+ " CAfile: %s\n CApath: %s",
+ data->set.str[STRING_SSL_CAFILE]?
+ data->set.str[STRING_SSL_CAFILE]: "none",
+ data->set.str[STRING_SSL_CAPATH]?
+ data->set.str[STRING_SSL_CAPATH] : "none");
+ return CURLE_SSL_CACERT_BADFILE;
+ }
+ else {
+ /* Just continue with a warning if no strict certificate
+ verification is required. */
+ infof(data, "error setting certificate verify locations,"
+ " continuing anyway:\n");
+ }
+ }
+ else {
+ /* Everything is fine. */
+ infof(data, "successfully set certificate verify locations:\n");
+ }
+ infof(data,
+ " CAfile: %s\n"
+ " CApath: %s\n",
+ data->set.str[STRING_SSL_CAFILE] ? data->set.str[STRING_SSL_CAFILE]:
+ "none",
+ data->set.str[STRING_SSL_CAPATH] ? data->set.str[STRING_SSL_CAPATH]:
+ "none");
+ }
+
+ /* Load the client certificate, and private key */
+ if(data->set.str[STRING_CERT] && data->set.str[STRING_KEY]) {
+ int file_type = do_file_type(data->set.str[STRING_CERT_TYPE]);
+
+ if(SSL_CTX_use_certificate_file(conssl->ctx, data->set.str[STRING_CERT],
+ file_type) != 1) {
+ failf(data, "unable to use client certificate (no key or wrong pass"
+ " phrase?)");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
+ file_type = do_file_type(data->set.str[STRING_KEY_TYPE]);
+ if(SSL_CTX_use_PrivateKey_file(conssl->ctx, data->set.str[STRING_KEY],
+ file_type) != 1) {
+ failf(data, "unable to set private key");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ }
+#endif /* !NO_FILESYSTEM */
+
+ /* SSL always tries to verify the peer, this only says whether it should
+ * fail to connect if the verification fails, or if it should continue
+ * anyway. In the latter case the result of the verification is checked with
+ * SSL_get_verify_result() below. */
+ SSL_CTX_set_verify(conssl->ctx,
+ data->set.ssl.verifypeer?SSL_VERIFY_PEER:SSL_VERIFY_NONE,
+ NULL);
+
+#ifdef HAVE_SNI
+ if(sni) {
+ struct in_addr addr4;
+#ifdef ENABLE_IPV6
+ struct in6_addr addr6;
+#endif
+ size_t hostname_len = strlen(conn->host.name);
+ if((hostname_len < USHRT_MAX) &&
+ (0 == Curl_inet_pton(AF_INET, conn->host.name, &addr4)) &&
+#ifdef ENABLE_IPV6
+ (0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr6)) &&
+#endif
+ (CyaSSL_CTX_UseSNI(conssl->ctx, CYASSL_SNI_HOST_NAME, conn->host.name,
+ (unsigned short)hostname_len) != 1)) {
+ infof(data, "WARNING: failed to configure server name indication (SNI) "
+ "TLS extension\n");
+ }
+ }
+#endif
+
+ /* give application a chance to interfere with SSL set up. */
+ if(data->set.ssl.fsslctx) {
+ CURLcode result = CURLE_OK;
+ result = (*data->set.ssl.fsslctx)(data, conssl->ctx,
+ data->set.ssl.fsslctxp);
+ if(result) {
+ failf(data, "error signaled by ssl ctx callback");
+ return result;
+ }
+ }
+#ifdef NO_FILESYSTEM
+ else if(data->set.ssl.verifypeer) {
+ failf(data, "SSL: Certificates couldn't be loaded because CyaSSL was built"
+ " with \"no filesystem\". Either disable peer verification"
+ " (insecure) or if you are building an application with libcurl you"
+ " can load certificates via CURLOPT_SSL_CTX_FUNCTION.");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+#endif
+
+ /* Let's make an SSL structure */
+ if(conssl->handle)
+ SSL_free(conssl->handle);
+ conssl->handle = SSL_new(conssl->ctx);
+ if(!conssl->handle) {
+ failf(data, "SSL: couldn't create a context (handle)!");
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ /* Check if there's a cached ID we can/should use here! */
+ if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) {
+ /* we got a session id, use it! */
+ if(!SSL_set_session(conssl->handle, ssl_sessionid)) {
+ failf(data, "SSL: SSL_set_session failed: %s",
+ ERR_error_string(SSL_get_error(conssl->handle, 0), error_buffer));
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ /* Informational message */
+ infof (data, "SSL re-using session ID\n");
+ }
+
+ /* pass the raw socket into the SSL layer */
+ if(!SSL_set_fd(conssl->handle, (int)sockfd)) {
+ failf(data, "SSL: SSL_set_fd failed");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
+ conssl->connecting_state = ssl_connect_2;
+ return CURLE_OK;
+}
+
+
+static CURLcode
+cyassl_connect_step2(struct connectdata *conn,
+ int sockindex)
+{
+ int ret = -1;
+ struct SessionHandle *data = conn->data;
+ struct ssl_connect_data* conssl = &conn->ssl[sockindex];
+
+ conn->recv[sockindex] = cyassl_recv;
+ conn->send[sockindex] = cyassl_send;
+
+ /* Enable RFC2818 checks */
+ if(data->set.ssl.verifyhost) {
+ ret = CyaSSL_check_domain_name(conssl->handle, conn->host.name);
+ if(ret == SSL_FAILURE)
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ ret = SSL_connect(conssl->handle);
+ if(ret != 1) {
+ char error_buffer[CYASSL_MAX_ERROR_SZ];
+ int detail = SSL_get_error(conssl->handle, ret);
+
+ if(SSL_ERROR_WANT_READ == detail) {
+ conssl->connecting_state = ssl_connect_2_reading;
+ return CURLE_OK;
+ }
+ else if(SSL_ERROR_WANT_WRITE == detail) {
+ conssl->connecting_state = ssl_connect_2_writing;
+ return CURLE_OK;
+ }
+ /* There is no easy way to override only the CN matching.
+ * This will enable the override of both mismatching SubjectAltNames
+ * as also mismatching CN fields */
+ else if(DOMAIN_NAME_MISMATCH == detail) {
+#if 1
+ failf(data, "\tsubject alt name(s) or common name do not match \"%s\"\n",
+ conn->host.dispname);
+ return CURLE_PEER_FAILED_VERIFICATION;
+#else
+ /* When the CyaSSL_check_domain_name() is used and you desire to continue
+ * on a DOMAIN_NAME_MISMATCH, i.e. 'data->set.ssl.verifyhost == 0',
+ * CyaSSL version 2.4.0 will fail with an INCOMPLETE_DATA error. The only
+ * way to do this is currently to switch the CyaSSL_check_domain_name()
+ * in and out based on the 'data->set.ssl.verifyhost' value. */
+ if(data->set.ssl.verifyhost) {
+ failf(data,
+ "\tsubject alt name(s) or common name do not match \"%s\"\n",
+ conn->host.dispname);
+ return CURLE_PEER_FAILED_VERIFICATION;
+ }
+ else {
+ infof(data,
+ "\tsubject alt name(s) and/or common name do not match \"%s\"\n",
+ conn->host.dispname);
+ return CURLE_OK;
+ }
+#endif
+ }
+#if LIBCYASSL_VERSION_HEX >= 0x02007000 /* 2.7.0 */
+ else if(ASN_NO_SIGNER_E == detail) {
+ if(data->set.ssl.verifypeer) {
+ failf(data, "\tCA signer not available for verification\n");
+ return CURLE_SSL_CACERT_BADFILE;
+ }
+ else {
+ /* Just continue with a warning if no strict certificate
+ verification is required. */
+ infof(data, "CA signer not available for verification, "
+ "continuing anyway\n");
+ }
+ }
+#endif
+ else {
+ failf(data, "SSL_connect failed with error %d: %s", detail,
+ ERR_error_string(detail, error_buffer));
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ }
+
+ if(data->set.str[STRING_SSL_PINNEDPUBLICKEY]) {
+ X509 *x509;
+ const char *x509_der;
+ int x509_der_len;
+ curl_X509certificate x509_parsed;
+ curl_asn1Element *pubkey;
+ CURLcode result;
+
+ x509 = SSL_get_peer_certificate(conssl->handle);
+ if(!x509) {
+ failf(data, "SSL: failed retrieving server certificate");
+ return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+ }
+
+ x509_der = (const char *)CyaSSL_X509_get_der(x509, &x509_der_len);
+ if(!x509_der) {
+ failf(data, "SSL: failed retrieving ASN.1 server certificate");
+ return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+ }
+
+ memset(&x509_parsed, 0, sizeof x509_parsed);
+ Curl_parseX509(&x509_parsed, x509_der, x509_der + x509_der_len);
+
+ pubkey = &x509_parsed.subjectPublicKeyInfo;
+ if(!pubkey->header || pubkey->end <= pubkey->header) {
+ failf(data, "SSL: failed retrieving public key from server certificate");
+ return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+ }
+
+ result = Curl_pin_peer_pubkey(data->set.str[STRING_SSL_PINNEDPUBLICKEY],
+ (const unsigned char *)pubkey->header,
+ (size_t)(pubkey->end - pubkey->header));
+ if(result) {
+ failf(data, "SSL: public key does not match pinned public key!");
+ return result;
+ }
+ }
+
+ conssl->connecting_state = ssl_connect_3;
+ infof(data, "SSL connected\n");
+
+ return CURLE_OK;
+}
+
+
+static CURLcode
+cyassl_connect_step3(struct connectdata *conn,
+ int sockindex)
+{
+ CURLcode result = CURLE_OK;
+ void *old_ssl_sessionid=NULL;
+ struct SessionHandle *data = conn->data;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ bool incache;
+ SSL_SESSION *our_ssl_sessionid;
+
+ DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
+
+ our_ssl_sessionid = SSL_get_session(connssl->handle);
+
+ incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL));
+ if(incache) {
+ if(old_ssl_sessionid != our_ssl_sessionid) {
+ infof(data, "old SSL session ID is stale, removing\n");
+ Curl_ssl_delsessionid(conn, old_ssl_sessionid);
+ incache = FALSE;
+ }
+ }
+
+ if(!incache) {
+ result = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
+ 0 /* unknown size */);
+ if(result) {
+ failf(data, "failed to store ssl session");
+ return result;
+ }
+ }
+
+ connssl->connecting_state = ssl_connect_done;
+
+ return result;
+}
+
+
+static ssize_t cyassl_send(struct connectdata *conn,
+ int sockindex,
+ const void *mem,
+ size_t len,
+ CURLcode *curlcode)
+{
+ char error_buffer[CYASSL_MAX_ERROR_SZ];
+ int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
+ int rc = SSL_write(conn->ssl[sockindex].handle, mem, memlen);
+
+ if(rc < 0) {
+ int err = SSL_get_error(conn->ssl[sockindex].handle, rc);
+
+ switch(err) {
+ case SSL_ERROR_WANT_READ:
+ case SSL_ERROR_WANT_WRITE:
+ /* there's data pending, re-invoke SSL_write() */
+ *curlcode = CURLE_AGAIN;
+ return -1;
+ default:
+ failf(conn->data, "SSL write: %s, errno %d",
+ ERR_error_string(err, error_buffer),
+ SOCKERRNO);
+ *curlcode = CURLE_SEND_ERROR;
+ return -1;
+ }
+ }
+ return rc;
+}
+
+void Curl_cyassl_close(struct connectdata *conn, int sockindex)
+{
+ struct ssl_connect_data *conssl = &conn->ssl[sockindex];
+
+ if(conssl->handle) {
+ (void)SSL_shutdown(conssl->handle);
+ SSL_free (conssl->handle);
+ conssl->handle = NULL;
+ }
+ if(conssl->ctx) {
+ SSL_CTX_free (conssl->ctx);
+ conssl->ctx = NULL;
+ }
+}
+
+static ssize_t cyassl_recv(struct connectdata *conn,
+ int num,
+ char *buf,
+ size_t buffersize,
+ CURLcode *curlcode)
+{
+ char error_buffer[CYASSL_MAX_ERROR_SZ];
+ int buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
+ int nread = SSL_read(conn->ssl[num].handle, buf, buffsize);
+
+ if(nread < 0) {
+ int err = SSL_get_error(conn->ssl[num].handle, nread);
+
+ switch(err) {
+ case SSL_ERROR_ZERO_RETURN: /* no more data */
+ break;
+ case SSL_ERROR_WANT_READ:
+ case SSL_ERROR_WANT_WRITE:
+ /* there's data pending, re-invoke SSL_read() */
+ *curlcode = CURLE_AGAIN;
+ return -1;
+ default:
+ failf(conn->data, "SSL read: %s, errno %d",
+ ERR_error_string(err, error_buffer),
+ SOCKERRNO);
+ *curlcode = CURLE_RECV_ERROR;
+ return -1;
+ }
+ }
+ return nread;
+}
+
+
+void Curl_cyassl_session_free(void *ptr)
+{
+ (void)ptr;
+ /* CyaSSL reuses sessions on own, no free */
+}
+
+
+size_t Curl_cyassl_version(char *buffer, size_t size)
+{
+#ifdef WOLFSSL_VERSION
+ return snprintf(buffer, size, "wolfSSL/%s", WOLFSSL_VERSION);
+#elif defined(CYASSL_VERSION)
+ return snprintf(buffer, size, "CyaSSL/%s", CYASSL_VERSION);
+#else
+ return snprintf(buffer, size, "CyaSSL/%s", "<1.8.8");
+#endif
+}
+
+
+int Curl_cyassl_init(void)
+{
+ return (CyaSSL_Init() == SSL_SUCCESS);
+}
+
+
+bool Curl_cyassl_data_pending(const struct connectdata* conn, int connindex)
+{
+ if(conn->ssl[connindex].handle) /* SSL is in use */
+ return (0 != SSL_pending(conn->ssl[connindex].handle)) ? TRUE : FALSE;
+ else
+ return FALSE;
+}
+
+
+/*
+ * This function is called to shut down the SSL layer but keep the
+ * socket open (CCC - Clear Command Channel)
+ */
+int Curl_cyassl_shutdown(struct connectdata *conn, int sockindex)
+{
+ int retval = 0;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+ if(connssl->handle) {
+ SSL_free (connssl->handle);
+ connssl->handle = NULL;
+ }
+ return retval;
+}
+
+
+static CURLcode
+cyassl_connect_common(struct connectdata *conn,
+ int sockindex,
+ bool nonblocking,
+ bool *done)
+{
+ CURLcode result;
+ struct SessionHandle *data = conn->data;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ curl_socket_t sockfd = conn->sock[sockindex];
+ long timeout_ms;
+ int what;
+
+ /* check if the connection has already been established */
+ if(ssl_connection_complete == connssl->state) {
+ *done = TRUE;
+ return CURLE_OK;
+ }
+
+ if(ssl_connect_1==connssl->connecting_state) {
+ /* Find out how much more time we're allowed */
+ timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+ if(timeout_ms < 0) {
+ /* no need to continue if time already is up */
+ failf(data, "SSL connection timeout");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+
+ result = cyassl_connect_step1(conn, sockindex);
+ if(result)
+ return result;
+ }
+
+ while(ssl_connect_2 == connssl->connecting_state ||
+ ssl_connect_2_reading == connssl->connecting_state ||
+ ssl_connect_2_writing == connssl->connecting_state) {
+
+ /* check allowed time left */
+ timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+ if(timeout_ms < 0) {
+ /* no need to continue if time already is up */
+ failf(data, "SSL connection timeout");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+
+ /* if ssl is expecting something, check if it's available. */
+ if(connssl->connecting_state == ssl_connect_2_reading
+ || connssl->connecting_state == ssl_connect_2_writing) {
+
+ curl_socket_t writefd = ssl_connect_2_writing==
+ connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+ curl_socket_t readfd = ssl_connect_2_reading==
+ connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+
+ what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
+ if(what < 0) {
+ /* fatal error */
+ failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ else if(0 == what) {
+ if(nonblocking) {
+ *done = FALSE;
+ return CURLE_OK;
+ }
+ else {
+ /* timeout */
+ failf(data, "SSL connection timeout");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+ }
+ /* socket is readable or writable */
+ }
+
+ /* Run transaction, and return to the caller if it failed or if
+ * this connection is part of a multi handle and this loop would
+ * execute again. This permits the owner of a multi handle to
+ * abort a connection attempt before step2 has completed while
+ * ensuring that a client using select() or epoll() will always
+ * have a valid fdset to wait on.
+ */
+ result = cyassl_connect_step2(conn, sockindex);
+ if(result || (nonblocking &&
+ (ssl_connect_2 == connssl->connecting_state ||
+ ssl_connect_2_reading == connssl->connecting_state ||
+ ssl_connect_2_writing == connssl->connecting_state)))
+ return result;
+ } /* repeat step2 until all transactions are done. */
+
+ if(ssl_connect_3 == connssl->connecting_state) {
+ result = cyassl_connect_step3(conn, sockindex);
+ if(result)
+ return result;
+ }
+
+ if(ssl_connect_done == connssl->connecting_state) {
+ connssl->state = ssl_connection_complete;
+ conn->recv[sockindex] = cyassl_recv;
+ conn->send[sockindex] = cyassl_send;
+ *done = TRUE;
+ }
+ else
+ *done = FALSE;
+
+ /* Reset our connect state machine */
+ connssl->connecting_state = ssl_connect_1;
+
+ return CURLE_OK;
+}
+
+
+CURLcode
+Curl_cyassl_connect_nonblocking(struct connectdata *conn,
+ int sockindex,
+ bool *done)
+{
+ return cyassl_connect_common(conn, sockindex, TRUE, done);
+}
+
+
+CURLcode
+Curl_cyassl_connect(struct connectdata *conn,
+ int sockindex)
+{
+ CURLcode result;
+ bool done = FALSE;
+
+ result = cyassl_connect_common(conn, sockindex, FALSE, &done);
+ if(result)
+ return result;
+
+ DEBUGASSERT(done);
+
+ return CURLE_OK;
+}
+
+int Curl_cyassl_random(struct SessionHandle *data,
+ unsigned char *entropy,
+ size_t length)
+{
+ RNG rng;
+ (void)data;
+ if(InitRng(&rng))
+ return 1;
+ if(length > UINT_MAX)
+ return 1;
+ if(RNG_GenerateBlock(&rng, entropy, (unsigned)length))
+ return 1;
+ return 0;
+}
+
+void Curl_cyassl_sha256sum(const unsigned char *tmp, /* input */
+ size_t tmplen,
+ unsigned char *sha256sum /* output */,
+ size_t unused)
+{
+ Sha256 SHA256pw;
+ (void)unused;
+ InitSha256(&SHA256pw);
+ Sha256Update(&SHA256pw, tmp, tmplen);
+ Sha256Final(&SHA256pw, sha256sum);
+}
+
+#endif
diff --git a/Utilities/cmcurl/lib/vtls/cyassl.h b/Utilities/cmcurl/lib/vtls/cyassl.h
new file mode 100644
index 000000000..167de74f3
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/cyassl.h
@@ -0,0 +1,75 @@
+#ifndef HEADER_CURL_CYASSL_H
+#define HEADER_CURL_CYASSL_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef USE_CYASSL
+
+CURLcode Curl_cyassl_connect(struct connectdata *conn, int sockindex);
+bool Curl_cyassl_data_pending(const struct connectdata* conn, int connindex);
+int Curl_cyassl_shutdown(struct connectdata* conn, int sockindex);
+
+ /* close a SSL connection */
+void Curl_cyassl_close(struct connectdata *conn, int sockindex);
+
+void Curl_cyassl_session_free(void *ptr);
+size_t Curl_cyassl_version(char *buffer, size_t size);
+int Curl_cyassl_shutdown(struct connectdata *conn, int sockindex);
+int Curl_cyassl_init(void);
+CURLcode Curl_cyassl_connect_nonblocking(struct connectdata *conn,
+ int sockindex,
+ bool *done);
+int Curl_cyassl_random(struct SessionHandle *data,
+ unsigned char *entropy,
+ size_t length);
+void Curl_cyassl_sha256sum(const unsigned char *tmp, /* input */
+ size_t tmplen,
+ unsigned char *sha256sum, /* output */
+ size_t unused);
+
+/* Set the API backend definition to Schannel */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_CYASSL
+
+/* this backend supports CURLOPT_SSL_CTX_* */
+#define have_curlssl_ssl_ctx 1
+
+/* API setup for CyaSSL */
+#define curlssl_init Curl_cyassl_init
+#define curlssl_cleanup() Curl_nop_stmt
+#define curlssl_connect Curl_cyassl_connect
+#define curlssl_connect_nonblocking Curl_cyassl_connect_nonblocking
+#define curlssl_session_free(x) Curl_cyassl_session_free(x)
+#define curlssl_close_all(x) ((void)x)
+#define curlssl_close Curl_cyassl_close
+#define curlssl_shutdown(x,y) Curl_cyassl_shutdown(x,y)
+#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN)
+#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN)
+#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL)
+#define curlssl_version Curl_cyassl_version
+#define curlssl_check_cxn(x) ((void)x, -1)
+#define curlssl_data_pending(x,y) Curl_cyassl_data_pending(x,y)
+#define curlssl_random(x,y,z) Curl_cyassl_random(x,y,z)
+#define curlssl_sha256sum(a,b,c,d) Curl_cyassl_sha256sum(a,b,c,d)
+
+#endif /* USE_CYASSL */
+#endif /* HEADER_CURL_CYASSL_H */
diff --git a/Utilities/cmcurl/lib/vtls/darwinssl.c b/Utilities/cmcurl/lib/vtls/darwinssl.c
new file mode 100644
index 000000000..03adcef28
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/darwinssl.c
@@ -0,0 +1,2484 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman@gmail.com>.
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all iOS and Mac OS X SecureTransport-specific code for the
+ * TLS/SSL layer. No code but vtls.c should ever call or use these functions.
+ */
+
+#include "curl_setup.h"
+
+#include "urldata.h" /* for the SessionHandle definition */
+#include "curl_base64.h"
+#include "strtok.h"
+
+#ifdef USE_DARWINSSL
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include <Security/Security.h>
+#include <Security/SecureTransport.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <CommonCrypto/CommonDigest.h>
+
+/* The Security framework has changed greatly between iOS and different OS X
+ versions, and we will try to support as many of them as we can (back to
+ Leopard and iOS 5) by using macros and weak-linking.
+
+ IMPORTANT: If TLS 1.1 and 1.2 support are important for you on OS X, then
+ you must build this project against the 10.8 SDK or later. */
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
+#error "The darwinssl back-end requires Leopard or later."
+#endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1050 */
+
+#define CURL_BUILD_IOS 0
+#define CURL_BUILD_IOS_7 0
+#define CURL_BUILD_MAC 1
+/* This is the maximum API level we are allowed to use when building: */
+#define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
+#define CURL_BUILD_MAC_10_6 MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
+#define CURL_BUILD_MAC_10_7 MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
+#define CURL_BUILD_MAC_10_8 MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
+#define CURL_BUILD_MAC_10_9 MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
+/* These macros mean "the following code is present to allow runtime backward
+ compatibility with at least this cat or earlier":
+ (You set this at build-time by setting the MACOSX_DEPLOYMENT_TARGET
+ environmental variable.) */
+#define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
+#define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060
+#define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
+#define CURL_SUPPORT_MAC_10_8 MAC_OS_X_VERSION_MIN_REQUIRED <= 1080
+#define CURL_SUPPORT_MAC_10_9 MAC_OS_X_VERSION_MIN_REQUIRED <= 1090
+
+#elif TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
+#define CURL_BUILD_IOS 1
+#define CURL_BUILD_IOS_7 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
+#define CURL_BUILD_MAC 0
+#define CURL_BUILD_MAC_10_5 0
+#define CURL_BUILD_MAC_10_6 0
+#define CURL_BUILD_MAC_10_7 0
+#define CURL_BUILD_MAC_10_8 0
+#define CURL_SUPPORT_MAC_10_5 0
+#define CURL_SUPPORT_MAC_10_6 0
+#define CURL_SUPPORT_MAC_10_7 0
+#define CURL_SUPPORT_MAC_10_8 0
+#define CURL_SUPPORT_MAC_10_9 0
+
+#else
+#error "The darwinssl back-end requires iOS or OS X."
+#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
+
+#if CURL_BUILD_MAC
+#include <sys/sysctl.h>
+#endif /* CURL_BUILD_MAC */
+
+#include "urldata.h"
+#include "sendf.h"
+#include "inet_pton.h"
+#include "connect.h"
+#include "select.h"
+#include "vtls.h"
+#include "darwinssl.h"
+#include "curl_printf.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* From MacTypes.h (which we can't include because it isn't present in iOS: */
+#define ioErr -36
+#define paramErr -50
+
+/* The following two functions were ripped from Apple sample code,
+ * with some modifications: */
+static OSStatus SocketRead(SSLConnectionRef connection,
+ void *data, /* owned by
+ * caller, data
+ * RETURNED */
+ size_t *dataLength) /* IN/OUT */
+{
+ size_t bytesToGo = *dataLength;
+ size_t initLen = bytesToGo;
+ UInt8 *currData = (UInt8 *)data;
+ /*int sock = *(int *)connection;*/
+ struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
+ int sock = connssl->ssl_sockfd;
+ OSStatus rtn = noErr;
+ size_t bytesRead;
+ ssize_t rrtn;
+ int theErr;
+
+ *dataLength = 0;
+
+ for(;;) {
+ bytesRead = 0;
+ rrtn = read(sock, currData, bytesToGo);
+ if(rrtn <= 0) {
+ /* this is guesswork... */
+ theErr = errno;
+ if(rrtn == 0) { /* EOF = server hung up */
+ /* the framework will turn this into errSSLClosedNoNotify */
+ rtn = errSSLClosedGraceful;
+ }
+ else /* do the switch */
+ switch(theErr) {
+ case ENOENT:
+ /* connection closed */
+ rtn = errSSLClosedGraceful;
+ break;
+ case ECONNRESET:
+ rtn = errSSLClosedAbort;
+ break;
+ case EAGAIN:
+ rtn = errSSLWouldBlock;
+ connssl->ssl_direction = false;
+ break;
+ default:
+ rtn = ioErr;
+ break;
+ }
+ break;
+ }
+ else {
+ bytesRead = rrtn;
+ }
+ bytesToGo -= bytesRead;
+ currData += bytesRead;
+
+ if(bytesToGo == 0) {
+ /* filled buffer with incoming data, done */
+ break;
+ }
+ }
+ *dataLength = initLen - bytesToGo;
+
+ return rtn;
+}
+
+static OSStatus SocketWrite(SSLConnectionRef connection,
+ const void *data,
+ size_t *dataLength) /* IN/OUT */
+{
+ size_t bytesSent = 0;
+ /*int sock = *(int *)connection;*/
+ struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
+ int sock = connssl->ssl_sockfd;
+ ssize_t length;
+ size_t dataLen = *dataLength;
+ const UInt8 *dataPtr = (UInt8 *)data;
+ OSStatus ortn;
+ int theErr;
+
+ *dataLength = 0;
+
+ do {
+ length = write(sock,
+ (char*)dataPtr + bytesSent,
+ dataLen - bytesSent);
+ } while((length > 0) &&
+ ( (bytesSent += length) < dataLen) );
+
+ if(length <= 0) {
+ theErr = errno;
+ if(theErr == EAGAIN) {
+ ortn = errSSLWouldBlock;
+ connssl->ssl_direction = true;
+ }
+ else {
+ ortn = ioErr;
+ }
+ }
+ else {
+ ortn = noErr;
+ }
+ *dataLength = bytesSent;
+ return ortn;
+}
+
+CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher) {
+ switch (cipher) {
+ /* SSL version 3.0 */
+ case SSL_RSA_WITH_NULL_MD5:
+ return "SSL_RSA_WITH_NULL_MD5";
+ break;
+ case SSL_RSA_WITH_NULL_SHA:
+ return "SSL_RSA_WITH_NULL_SHA";
+ break;
+ case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
+ return "SSL_RSA_EXPORT_WITH_RC4_40_MD5";
+ break;
+ case SSL_RSA_WITH_RC4_128_MD5:
+ return "SSL_RSA_WITH_RC4_128_MD5";
+ break;
+ case SSL_RSA_WITH_RC4_128_SHA:
+ return "SSL_RSA_WITH_RC4_128_SHA";
+ break;
+ case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
+ return "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5";
+ break;
+ case SSL_RSA_WITH_IDEA_CBC_SHA:
+ return "SSL_RSA_WITH_IDEA_CBC_SHA";
+ break;
+ case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
+ return "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA";
+ break;
+ case SSL_RSA_WITH_DES_CBC_SHA:
+ return "SSL_RSA_WITH_DES_CBC_SHA";
+ break;
+ case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
+ return "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
+ break;
+ case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
+ return "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA";
+ break;
+ case SSL_DH_DSS_WITH_DES_CBC_SHA:
+ return "SSL_DH_DSS_WITH_DES_CBC_SHA";
+ break;
+ case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA:
+ return "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA";
+ break;
+ case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
+ return "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA";
+ break;
+ case SSL_DH_RSA_WITH_DES_CBC_SHA:
+ return "SSL_DH_RSA_WITH_DES_CBC_SHA";
+ break;
+ case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA:
+ return "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA";
+ break;
+ case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
+ return "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA";
+ break;
+ case SSL_DHE_DSS_WITH_DES_CBC_SHA:
+ return "SSL_DHE_DSS_WITH_DES_CBC_SHA";
+ break;
+ case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
+ return "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
+ break;
+ case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
+ return "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA";
+ break;
+ case SSL_DHE_RSA_WITH_DES_CBC_SHA:
+ return "SSL_DHE_RSA_WITH_DES_CBC_SHA";
+ break;
+ case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
+ return "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
+ break;
+ case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
+ return "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5";
+ break;
+ case SSL_DH_anon_WITH_RC4_128_MD5:
+ return "SSL_DH_anon_WITH_RC4_128_MD5";
+ break;
+ case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
+ return "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA";
+ break;
+ case SSL_DH_anon_WITH_DES_CBC_SHA:
+ return "SSL_DH_anon_WITH_DES_CBC_SHA";
+ break;
+ case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
+ return "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA";
+ break;
+ case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
+ return "SSL_FORTEZZA_DMS_WITH_NULL_SHA";
+ break;
+ case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
+ return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA";
+ break;
+ /* TLS 1.0 with AES (RFC 3268)
+ (Apparently these are used in SSLv3 implementations as well.) */
+ case TLS_RSA_WITH_AES_128_CBC_SHA:
+ return "TLS_RSA_WITH_AES_128_CBC_SHA";
+ break;
+ case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
+ return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
+ break;
+ case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
+ return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
+ break;
+ case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
+ return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
+ break;
+ case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
+ return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
+ break;
+ case TLS_DH_anon_WITH_AES_128_CBC_SHA:
+ return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
+ break;
+ case TLS_RSA_WITH_AES_256_CBC_SHA:
+ return "TLS_RSA_WITH_AES_256_CBC_SHA";
+ break;
+ case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
+ return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
+ break;
+ case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
+ return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
+ break;
+ case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
+ return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
+ break;
+ case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
+ return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
+ break;
+ case TLS_DH_anon_WITH_AES_256_CBC_SHA:
+ return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
+ break;
+ /* SSL version 2.0 */
+ case SSL_RSA_WITH_RC2_CBC_MD5:
+ return "SSL_RSA_WITH_RC2_CBC_MD5";
+ break;
+ case SSL_RSA_WITH_IDEA_CBC_MD5:
+ return "SSL_RSA_WITH_IDEA_CBC_MD5";
+ break;
+ case SSL_RSA_WITH_DES_CBC_MD5:
+ return "SSL_RSA_WITH_DES_CBC_MD5";
+ break;
+ case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
+ return "SSL_RSA_WITH_3DES_EDE_CBC_MD5";
+ break;
+ }
+ return "SSL_NULL_WITH_NULL_NULL";
+}
+
+CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) {
+ switch(cipher) {
+ /* TLS 1.0 with AES (RFC 3268) */
+ case TLS_RSA_WITH_AES_128_CBC_SHA:
+ return "TLS_RSA_WITH_AES_128_CBC_SHA";
+ break;
+ case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
+ return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
+ break;
+ case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
+ return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
+ break;
+ case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
+ return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
+ break;
+ case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
+ return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
+ break;
+ case TLS_DH_anon_WITH_AES_128_CBC_SHA:
+ return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
+ break;
+ case TLS_RSA_WITH_AES_256_CBC_SHA:
+ return "TLS_RSA_WITH_AES_256_CBC_SHA";
+ break;
+ case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
+ return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
+ break;
+ case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
+ return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
+ break;
+ case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
+ return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
+ break;
+ case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
+ return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
+ break;
+ case TLS_DH_anon_WITH_AES_256_CBC_SHA:
+ return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
+ break;
+#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
+ /* TLS 1.0 with ECDSA (RFC 4492) */
+ case TLS_ECDH_ECDSA_WITH_NULL_SHA:
+ return "TLS_ECDH_ECDSA_WITH_NULL_SHA";
+ break;
+ case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
+ return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
+ break;
+ case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
+ return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
+ break;
+ case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
+ return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
+ break;
+ case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
+ return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
+ break;
+ case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
+ return "TLS_ECDHE_ECDSA_WITH_NULL_SHA";
+ break;
+ case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
+ return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
+ break;
+ case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
+ return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
+ break;
+ case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
+ return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
+ break;
+ case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
+ return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
+ break;
+ case TLS_ECDH_RSA_WITH_NULL_SHA:
+ return "TLS_ECDH_RSA_WITH_NULL_SHA";
+ break;
+ case TLS_ECDH_RSA_WITH_RC4_128_SHA:
+ return "TLS_ECDH_RSA_WITH_RC4_128_SHA";
+ break;
+ case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
+ return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
+ break;
+ case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
+ return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
+ break;
+ case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
+ return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
+ break;
+ case TLS_ECDHE_RSA_WITH_NULL_SHA:
+ return "TLS_ECDHE_RSA_WITH_NULL_SHA";
+ break;
+ case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
+ return "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
+ break;
+ case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
+ return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
+ break;
+ case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
+ return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
+ break;
+ case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
+ return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
+ break;
+ case TLS_ECDH_anon_WITH_NULL_SHA:
+ return "TLS_ECDH_anon_WITH_NULL_SHA";
+ break;
+ case TLS_ECDH_anon_WITH_RC4_128_SHA:
+ return "TLS_ECDH_anon_WITH_RC4_128_SHA";
+ break;
+ case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
+ return "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA";
+ break;
+ case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
+ return "TLS_ECDH_anon_WITH_AES_128_CBC_SHA";
+ break;
+ case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
+ return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA";
+ break;
+#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+ /* TLS 1.2 (RFC 5246) */
+ case TLS_RSA_WITH_NULL_MD5:
+ return "TLS_RSA_WITH_NULL_MD5";
+ break;
+ case TLS_RSA_WITH_NULL_SHA:
+ return "TLS_RSA_WITH_NULL_SHA";
+ break;
+ case TLS_RSA_WITH_RC4_128_MD5:
+ return "TLS_RSA_WITH_RC4_128_MD5";
+ break;
+ case TLS_RSA_WITH_RC4_128_SHA:
+ return "TLS_RSA_WITH_RC4_128_SHA";
+ break;
+ case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
+ return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
+ break;
+ case TLS_RSA_WITH_NULL_SHA256:
+ return "TLS_RSA_WITH_NULL_SHA256";
+ break;
+ case TLS_RSA_WITH_AES_128_CBC_SHA256:
+ return "TLS_RSA_WITH_AES_128_CBC_SHA256";
+ break;
+ case TLS_RSA_WITH_AES_256_CBC_SHA256:
+ return "TLS_RSA_WITH_AES_256_CBC_SHA256";
+ break;
+ case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
+ return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA";
+ break;
+ case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
+ return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA";
+ break;
+ case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
+ return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
+ break;
+ case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
+ return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
+ break;
+ case TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
+ return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256";
+ break;
+ case TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
+ return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256";
+ break;
+ case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
+ return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256";
+ break;
+ case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
+ return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
+ break;
+ case TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
+ return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256";
+ break;
+ case TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
+ return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256";
+ break;
+ case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
+ return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256";
+ break;
+ case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
+ return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
+ break;
+ case TLS_DH_anon_WITH_RC4_128_MD5:
+ return "TLS_DH_anon_WITH_RC4_128_MD5";
+ break;
+ case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:
+ return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
+ break;
+ case TLS_DH_anon_WITH_AES_128_CBC_SHA256:
+ return "TLS_DH_anon_WITH_AES_128_CBC_SHA256";
+ break;
+ case TLS_DH_anon_WITH_AES_256_CBC_SHA256:
+ return "TLS_DH_anon_WITH_AES_256_CBC_SHA256";
+ break;
+ /* TLS 1.2 with AES GCM (RFC 5288) */
+ case TLS_RSA_WITH_AES_128_GCM_SHA256:
+ return "TLS_RSA_WITH_AES_128_GCM_SHA256";
+ break;
+ case TLS_RSA_WITH_AES_256_GCM_SHA384:
+ return "TLS_RSA_WITH_AES_256_GCM_SHA384";
+ break;
+ case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
+ return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
+ break;
+ case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
+ return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
+ break;
+ case TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
+ return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256";
+ break;
+ case TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
+ return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384";
+ break;
+ case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
+ return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256";
+ break;
+ case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
+ return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384";
+ break;
+ case TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
+ return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256";
+ break;
+ case TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
+ return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384";
+ break;
+ case TLS_DH_anon_WITH_AES_128_GCM_SHA256:
+ return "TLS_DH_anon_WITH_AES_128_GCM_SHA256";
+ break;
+ case TLS_DH_anon_WITH_AES_256_GCM_SHA384:
+ return "TLS_DH_anon_WITH_AES_256_GCM_SHA384";
+ break;
+ /* TLS 1.2 with elliptic curve ciphers (RFC 5289) */
+ case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
+ return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
+ break;
+ case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
+ return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
+ break;
+ case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
+ return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
+ break;
+ case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
+ return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
+ break;
+ case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
+ return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
+ break;
+ case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
+ return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
+ break;
+ case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
+ return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256";
+ break;
+ case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
+ return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384";
+ break;
+ case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
+ return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
+ break;
+ case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
+ return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
+ break;
+ case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
+ return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
+ break;
+ case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
+ return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
+ break;
+ case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
+ return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
+ break;
+ case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
+ return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
+ break;
+ case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
+ return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
+ break;
+ case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
+ return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
+ break;
+ case TLS_EMPTY_RENEGOTIATION_INFO_SCSV:
+ return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
+ break;
+#else
+ case SSL_RSA_WITH_NULL_MD5:
+ return "TLS_RSA_WITH_NULL_MD5";
+ break;
+ case SSL_RSA_WITH_NULL_SHA:
+ return "TLS_RSA_WITH_NULL_SHA";
+ break;
+ case SSL_RSA_WITH_RC4_128_MD5:
+ return "TLS_RSA_WITH_RC4_128_MD5";
+ break;
+ case SSL_RSA_WITH_RC4_128_SHA:
+ return "TLS_RSA_WITH_RC4_128_SHA";
+ break;
+ case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
+ return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
+ break;
+ case SSL_DH_anon_WITH_RC4_128_MD5:
+ return "TLS_DH_anon_WITH_RC4_128_MD5";
+ break;
+ case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
+ return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
+ break;
+#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
+#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
+ /* TLS PSK (RFC 4279): */
+ case TLS_PSK_WITH_RC4_128_SHA:
+ return "TLS_PSK_WITH_RC4_128_SHA";
+ break;
+ case TLS_PSK_WITH_3DES_EDE_CBC_SHA:
+ return "TLS_PSK_WITH_3DES_EDE_CBC_SHA";
+ break;
+ case TLS_PSK_WITH_AES_128_CBC_SHA:
+ return "TLS_PSK_WITH_AES_128_CBC_SHA";
+ break;
+ case TLS_PSK_WITH_AES_256_CBC_SHA:
+ return "TLS_PSK_WITH_AES_256_CBC_SHA";
+ break;
+ case TLS_DHE_PSK_WITH_RC4_128_SHA:
+ return "TLS_DHE_PSK_WITH_RC4_128_SHA";
+ break;
+ case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
+ return "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA";
+ break;
+ case TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
+ return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA";
+ break;
+ case TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
+ return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA";
+ break;
+ case TLS_RSA_PSK_WITH_RC4_128_SHA:
+ return "TLS_RSA_PSK_WITH_RC4_128_SHA";
+ break;
+ case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
+ return "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA";
+ break;
+ case TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
+ return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA";
+ break;
+ case TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
+ return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA";
+ break;
+ /* More TLS PSK (RFC 4785): */
+ case TLS_PSK_WITH_NULL_SHA:
+ return "TLS_PSK_WITH_NULL_SHA";
+ break;
+ case TLS_DHE_PSK_WITH_NULL_SHA:
+ return "TLS_DHE_PSK_WITH_NULL_SHA";
+ break;
+ case TLS_RSA_PSK_WITH_NULL_SHA:
+ return "TLS_RSA_PSK_WITH_NULL_SHA";
+ break;
+ /* Even more TLS PSK (RFC 5487): */
+ case TLS_PSK_WITH_AES_128_GCM_SHA256:
+ return "TLS_PSK_WITH_AES_128_GCM_SHA256";
+ break;
+ case TLS_PSK_WITH_AES_256_GCM_SHA384:
+ return "TLS_PSK_WITH_AES_256_GCM_SHA384";
+ break;
+ case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
+ return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256";
+ break;
+ case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
+ return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384";
+ break;
+ case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
+ return "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256";
+ break;
+ case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
+ return "TLS_PSK_WITH_AES_256_GCM_SHA384";
+ break;
+ case TLS_PSK_WITH_AES_128_CBC_SHA256:
+ return "TLS_PSK_WITH_AES_128_CBC_SHA256";
+ break;
+ case TLS_PSK_WITH_AES_256_CBC_SHA384:
+ return "TLS_PSK_WITH_AES_256_CBC_SHA384";
+ break;
+ case TLS_PSK_WITH_NULL_SHA256:
+ return "TLS_PSK_WITH_NULL_SHA256";
+ break;
+ case TLS_PSK_WITH_NULL_SHA384:
+ return "TLS_PSK_WITH_NULL_SHA384";
+ break;
+ case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
+ return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256";
+ break;
+ case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
+ return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384";
+ break;
+ case TLS_DHE_PSK_WITH_NULL_SHA256:
+ return "TLS_DHE_PSK_WITH_NULL_SHA256";
+ break;
+ case TLS_DHE_PSK_WITH_NULL_SHA384:
+ return "TLS_RSA_PSK_WITH_NULL_SHA384";
+ break;
+ case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
+ return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256";
+ break;
+ case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
+ return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384";
+ break;
+ case TLS_RSA_PSK_WITH_NULL_SHA256:
+ return "TLS_RSA_PSK_WITH_NULL_SHA256";
+ break;
+ case TLS_RSA_PSK_WITH_NULL_SHA384:
+ return "TLS_RSA_PSK_WITH_NULL_SHA384";
+ break;
+#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
+ }
+ return "TLS_NULL_WITH_NULL_NULL";
+}
+
+#if CURL_BUILD_MAC
+CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
+{
+ int mib[2];
+ char *os_version;
+ size_t os_version_len;
+ char *os_version_major, *os_version_minor/*, *os_version_point*/;
+ char *tok_buf;
+
+ /* Get the Darwin kernel version from the kernel using sysctl(): */
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_OSRELEASE;
+ if(sysctl(mib, 2, NULL, &os_version_len, NULL, 0) == -1)
+ return;
+ os_version = malloc(os_version_len*sizeof(char));
+ if(!os_version)
+ return;
+ if(sysctl(mib, 2, os_version, &os_version_len, NULL, 0) == -1) {
+ free(os_version);
+ return;
+ }
+
+ /* Parse the version: */
+ os_version_major = strtok_r(os_version, ".", &tok_buf);
+ os_version_minor = strtok_r(NULL, ".", &tok_buf);
+ /*os_version_point = strtok_r(NULL, ".", &tok_buf);*/
+ *major = atoi(os_version_major);
+ *minor = atoi(os_version_minor);
+ free(os_version);
+}
+#endif /* CURL_BUILD_MAC */
+
+/* Apple provides a myriad of ways of getting information about a certificate
+ into a string. Some aren't available under iOS or newer cats. So here's
+ a unified function for getting a string describing the certificate that
+ ought to work in all cats starting with Leopard. */
+CF_INLINE CFStringRef CopyCertSubject(SecCertificateRef cert)
+{
+ CFStringRef server_cert_summary = CFSTR("(null)");
+
+#if CURL_BUILD_IOS
+ /* iOS: There's only one way to do this. */
+ server_cert_summary = SecCertificateCopySubjectSummary(cert);
+#else
+#if CURL_BUILD_MAC_10_7
+ /* Lion & later: Get the long description if we can. */
+ if(SecCertificateCopyLongDescription != NULL)
+ server_cert_summary =
+ SecCertificateCopyLongDescription(NULL, cert, NULL);
+ else
+#endif /* CURL_BUILD_MAC_10_7 */
+#if CURL_BUILD_MAC_10_6
+ /* Snow Leopard: Get the certificate summary. */
+ if(SecCertificateCopySubjectSummary != NULL)
+ server_cert_summary = SecCertificateCopySubjectSummary(cert);
+ else
+#endif /* CURL_BUILD_MAC_10_6 */
+ /* Leopard is as far back as we go... */
+ (void)SecCertificateCopyCommonName(cert, &server_cert_summary);
+#endif /* CURL_BUILD_IOS */
+ return server_cert_summary;
+}
+
+#if CURL_SUPPORT_MAC_10_6
+/* The SecKeychainSearch API was deprecated in Lion, and using it will raise
+ deprecation warnings, so let's not compile this unless it's necessary: */
+static OSStatus CopyIdentityWithLabelOldSchool(char *label,
+ SecIdentityRef *out_c_a_k)
+{
+ OSStatus status = errSecItemNotFound;
+ SecKeychainAttributeList attr_list;
+ SecKeychainAttribute attr;
+ SecKeychainSearchRef search = NULL;
+ SecCertificateRef cert = NULL;
+
+ /* Set up the attribute list: */
+ attr_list.count = 1L;
+ attr_list.attr = &attr;
+
+ /* Set up our lone search criterion: */
+ attr.tag = kSecLabelItemAttr;
+ attr.data = label;
+ attr.length = (UInt32)strlen(label);
+
+ /* Start searching: */
+ status = SecKeychainSearchCreateFromAttributes(NULL,
+ kSecCertificateItemClass,
+ &attr_list,
+ &search);
+ if(status == noErr) {
+ status = SecKeychainSearchCopyNext(search,
+ (SecKeychainItemRef *)&cert);
+ if(status == noErr && cert) {
+ /* If we found a certificate, does it have a private key? */
+ status = SecIdentityCreateWithCertificate(NULL, cert, out_c_a_k);
+ CFRelease(cert);
+ }
+ }
+
+ if(search)
+ CFRelease(search);
+ return status;
+}
+#endif /* CURL_SUPPORT_MAC_10_6 */
+
+static OSStatus CopyIdentityWithLabel(char *label,
+ SecIdentityRef *out_cert_and_key)
+{
+ OSStatus status = errSecItemNotFound;
+
+#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
+ /* SecItemCopyMatching() was introduced in iOS and Snow Leopard.
+ kSecClassIdentity was introduced in Lion. If both exist, let's use them
+ to find the certificate. */
+ if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) {
+ CFTypeRef keys[4];
+ CFTypeRef values[4];
+ CFDictionaryRef query_dict;
+ CFStringRef label_cf = CFStringCreateWithCString(NULL, label,
+ kCFStringEncodingUTF8);
+
+ /* Set up our search criteria and expected results: */
+ values[0] = kSecClassIdentity; /* we want a certificate and a key */
+ keys[0] = kSecClass;
+ values[1] = kCFBooleanTrue; /* we want a reference */
+ keys[1] = kSecReturnRef;
+ values[2] = kSecMatchLimitOne; /* one is enough, thanks */
+ keys[2] = kSecMatchLimit;
+ /* identity searches need a SecPolicyRef in order to work */
+ values[3] = SecPolicyCreateSSL(false, label_cf);
+ keys[3] = kSecMatchPolicy;
+ query_dict = CFDictionaryCreate(NULL, (const void **)keys,
+ (const void **)values, 4L,
+ &kCFCopyStringDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ CFRelease(values[3]);
+ CFRelease(label_cf);
+
+ /* Do we have a match? */
+ status = SecItemCopyMatching(query_dict, (CFTypeRef *)out_cert_and_key);
+ CFRelease(query_dict);
+ }
+ else {
+#if CURL_SUPPORT_MAC_10_6
+ /* On Leopard and Snow Leopard, fall back to SecKeychainSearch. */
+ status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
+#endif /* CURL_SUPPORT_MAC_10_7 */
+ }
+#elif CURL_SUPPORT_MAC_10_6
+ /* For developers building on older cats, we have no choice but to fall back
+ to SecKeychainSearch. */
+ status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
+#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
+ return status;
+}
+
+static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
+ const char *cPassword,
+ SecIdentityRef *out_cert_and_key)
+{
+ OSStatus status = errSecItemNotFound;
+ CFURLRef pkcs_url = CFURLCreateFromFileSystemRepresentation(NULL,
+ (const UInt8 *)cPath, strlen(cPath), false);
+ CFStringRef password = cPassword ? CFStringCreateWithCString(NULL,
+ cPassword, kCFStringEncodingUTF8) : NULL;
+ CFDataRef pkcs_data = NULL;
+
+ /* We can import P12 files on iOS or OS X 10.7 or later: */
+ /* These constants are documented as having first appeared in 10.6 but they
+ raise linker errors when used on that cat for some reason. */
+#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
+ if(CFURLCreateDataAndPropertiesFromResource(NULL, pkcs_url, &pkcs_data,
+ NULL, NULL, &status)) {
+ const void *cKeys[] = {kSecImportExportPassphrase};
+ const void *cValues[] = {password};
+ CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues,
+ password ? 1L : 0L, NULL, NULL);
+ CFArrayRef items = NULL;
+
+ /* Here we go: */
+ status = SecPKCS12Import(pkcs_data, options, &items);
+ if(status == noErr && items && CFArrayGetCount(items)) {
+ CFDictionaryRef identity_and_trust = CFArrayGetValueAtIndex(items, 0L);
+ const void *temp_identity = CFDictionaryGetValue(identity_and_trust,
+ kSecImportItemIdentity);
+
+ /* Retain the identity; we don't care about any other data... */
+ CFRetain(temp_identity);
+ *out_cert_and_key = (SecIdentityRef)temp_identity;
+ }
+
+ if(items)
+ CFRelease(items);
+ CFRelease(options);
+ CFRelease(pkcs_data);
+ }
+#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
+ if(password)
+ CFRelease(password);
+ CFRelease(pkcs_url);
+ return status;
+}
+
+/* This code was borrowed from nss.c, with some modifications:
+ * Determine whether the nickname passed in is a filename that needs to
+ * be loaded as a PEM or a regular NSS nickname.
+ *
+ * returns 1 for a file
+ * returns 0 for not a file
+ */
+CF_INLINE bool is_file(const char *filename)
+{
+ struct_stat st;
+
+ if(filename == NULL)
+ return false;
+
+ if(stat(filename, &st) == 0)
+ return S_ISREG(st.st_mode);
+ return false;
+}
+
+static CURLcode darwinssl_connect_step1(struct connectdata *conn,
+ int sockindex)
+{
+ struct SessionHandle *data = conn->data;
+ curl_socket_t sockfd = conn->sock[sockindex];
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+#ifdef ENABLE_IPV6
+ struct in6_addr addr;
+#else
+ struct in_addr addr;
+#endif /* ENABLE_IPV6 */
+ size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
+ SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
+ char *ssl_sessionid;
+ size_t ssl_sessionid_len;
+ OSStatus err = noErr;
+#if CURL_BUILD_MAC
+ int darwinver_maj = 0, darwinver_min = 0;
+
+ GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
+#endif /* CURL_BUILD_MAC */
+
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+ if(SSLCreateContext != NULL) { /* use the newer API if avaialble */
+ if(connssl->ssl_ctx)
+ CFRelease(connssl->ssl_ctx);
+ connssl->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
+ if(!connssl->ssl_ctx) {
+ failf(data, "SSL: couldn't create a context!");
+ return CURLE_OUT_OF_MEMORY;
+ }
+ }
+ else {
+ /* The old ST API does not exist under iOS, so don't compile it: */
+#if CURL_SUPPORT_MAC_10_8
+ if(connssl->ssl_ctx)
+ (void)SSLDisposeContext(connssl->ssl_ctx);
+ err = SSLNewContext(false, &(connssl->ssl_ctx));
+ if(err != noErr) {
+ failf(data, "SSL: couldn't create a context: OSStatus %d", err);
+ return CURLE_OUT_OF_MEMORY;
+ }
+#endif /* CURL_SUPPORT_MAC_10_8 */
+ }
+#else
+ if(connssl->ssl_ctx)
+ (void)SSLDisposeContext(connssl->ssl_ctx);
+ err = SSLNewContext(false, &(connssl->ssl_ctx));
+ if(err != noErr) {
+ failf(data, "SSL: couldn't create a context: OSStatus %d", err);
+ return CURLE_OUT_OF_MEMORY;
+ }
+#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
+ connssl->ssl_write_buffered_length = 0UL; /* reset buffered write length */
+
+ /* check to see if we've been told to use an explicit SSL/TLS version */
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+ if(SSLSetProtocolVersionMax != NULL) {
+ switch(data->set.ssl.version) {
+ default:
+ case CURL_SSLVERSION_DEFAULT:
+ case CURL_SSLVERSION_TLSv1:
+ (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
+ (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
+ break;
+ case CURL_SSLVERSION_TLSv1_0:
+ (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
+ (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol1);
+ break;
+ case CURL_SSLVERSION_TLSv1_1:
+ (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol11);
+ (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol11);
+ break;
+ case CURL_SSLVERSION_TLSv1_2:
+ (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol12);
+ (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
+ break;
+ case CURL_SSLVERSION_SSLv3:
+ err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
+ if(err != noErr) {
+ failf(data, "Your version of the OS does not support SSLv3");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
+ break;
+ case CURL_SSLVERSION_SSLv2:
+ err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2);
+ if(err != noErr) {
+ failf(data, "Your version of the OS does not support SSLv2");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2);
+ }
+ }
+ else {
+#if CURL_SUPPORT_MAC_10_8
+ (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+ kSSLProtocolAll,
+ false);
+ switch (data->set.ssl.version) {
+ default:
+ case CURL_SSLVERSION_DEFAULT:
+ case CURL_SSLVERSION_TLSv1:
+ (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+ kTLSProtocol1,
+ true);
+ (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+ kTLSProtocol11,
+ true);
+ (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+ kTLSProtocol12,
+ true);
+ break;
+ case CURL_SSLVERSION_TLSv1_0:
+ (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+ kTLSProtocol1,
+ true);
+ break;
+ case CURL_SSLVERSION_TLSv1_1:
+ (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+ kTLSProtocol11,
+ true);
+ break;
+ case CURL_SSLVERSION_TLSv1_2:
+ (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+ kTLSProtocol12,
+ true);
+ break;
+ case CURL_SSLVERSION_SSLv3:
+ err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+ kSSLProtocol3,
+ true);
+ if(err != noErr) {
+ failf(data, "Your version of the OS does not support SSLv3");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ break;
+ case CURL_SSLVERSION_SSLv2:
+ err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+ kSSLProtocol2,
+ true);
+ if(err != noErr) {
+ failf(data, "Your version of the OS does not support SSLv2");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ break;
+ }
+#endif /* CURL_SUPPORT_MAC_10_8 */
+ }
+#else
+ (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
+ switch(data->set.ssl.version) {
+ default:
+ case CURL_SSLVERSION_DEFAULT:
+ case CURL_SSLVERSION_TLSv1:
+ case CURL_SSLVERSION_TLSv1_0:
+ (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+ kTLSProtocol1,
+ true);
+ break;
+ case CURL_SSLVERSION_TLSv1_1:
+ failf(data, "Your version of the OS does not support TLSv1.1");
+ return CURLE_SSL_CONNECT_ERROR;
+ case CURL_SSLVERSION_TLSv1_2:
+ failf(data, "Your version of the OS does not support TLSv1.2");
+ return CURLE_SSL_CONNECT_ERROR;
+ case CURL_SSLVERSION_SSLv2:
+ err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+ kSSLProtocol2,
+ true);
+ if(err != noErr) {
+ failf(data, "Your version of the OS does not support SSLv2");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ break;
+ case CURL_SSLVERSION_SSLv3:
+ err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+ kSSLProtocol3,
+ true);
+ if(err != noErr) {
+ failf(data, "Your version of the OS does not support SSLv3");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ break;
+ }
+#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
+
+ if(data->set.str[STRING_KEY]) {
+ infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
+ "Transport. The private key must be in the Keychain.\n");
+ }
+
+ if(data->set.str[STRING_CERT]) {
+ SecIdentityRef cert_and_key = NULL;
+ bool is_cert_file = is_file(data->set.str[STRING_CERT]);
+
+ /* User wants to authenticate with a client cert. Look for it:
+ If we detect that this is a file on disk, then let's load it.
+ Otherwise, assume that the user wants to use an identity loaded
+ from the Keychain. */
+ if(is_cert_file) {
+ if(!data->set.str[STRING_CERT_TYPE])
+ infof(data, "WARNING: SSL: Certificate type not set, assuming "
+ "PKCS#12 format.\n");
+ else if(strncmp(data->set.str[STRING_CERT_TYPE], "P12",
+ strlen(data->set.str[STRING_CERT_TYPE])) != 0)
+ infof(data, "WARNING: SSL: The Security framework only supports "
+ "loading identities that are in PKCS#12 format.\n");
+
+ err = CopyIdentityFromPKCS12File(data->set.str[STRING_CERT],
+ data->set.str[STRING_KEY_PASSWD], &cert_and_key);
+ }
+ else
+ err = CopyIdentityWithLabel(data->set.str[STRING_CERT], &cert_and_key);
+
+ if(err == noErr) {
+ SecCertificateRef cert = NULL;
+ CFTypeRef certs_c[1];
+ CFArrayRef certs;
+
+ /* If we found one, print it out: */
+ err = SecIdentityCopyCertificate(cert_and_key, &cert);
+ if(err == noErr) {
+ CFStringRef cert_summary = CopyCertSubject(cert);
+ char cert_summary_c[128];
+
+ if(cert_summary) {
+ memset(cert_summary_c, 0, 128);
+ if(CFStringGetCString(cert_summary,
+ cert_summary_c,
+ 128,
+ kCFStringEncodingUTF8)) {
+ infof(data, "Client certificate: %s\n", cert_summary_c);
+ }
+ CFRelease(cert_summary);
+ CFRelease(cert);
+ }
+ }
+ certs_c[0] = cert_and_key;
+ certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
+ &kCFTypeArrayCallBacks);
+ err = SSLSetCertificate(connssl->ssl_ctx, certs);
+ if(certs)
+ CFRelease(certs);
+ if(err != noErr) {
+ failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err);
+ return CURLE_SSL_CERTPROBLEM;
+ }
+ CFRelease(cert_and_key);
+ }
+ else {
+ switch(err) {
+ case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
+ failf(data, "SSL: Incorrect password for the certificate \"%s\" "
+ "and its private key.", data->set.str[STRING_CERT]);
+ break;
+ case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */
+ failf(data, "SSL: Couldn't make sense of the data in the "
+ "certificate \"%s\" and its private key.",
+ data->set.str[STRING_CERT]);
+ break;
+ case -25260: /* errSecPassphraseRequired */
+ failf(data, "SSL The certificate \"%s\" requires a password.",
+ data->set.str[STRING_CERT]);
+ break;
+ case errSecItemNotFound:
+ failf(data, "SSL: Can't find the certificate \"%s\" and its private "
+ "key in the Keychain.", data->set.str[STRING_CERT]);
+ break;
+ default:
+ failf(data, "SSL: Can't load the certificate \"%s\" and its private "
+ "key: OSStatus %d", data->set.str[STRING_CERT], err);
+ break;
+ }
+ return CURLE_SSL_CERTPROBLEM;
+ }
+ }
+
+ /* SSL always tries to verify the peer, this only says whether it should
+ * fail to connect if the verification fails, or if it should continue
+ * anyway. In the latter case the result of the verification is checked with
+ * SSL_get_verify_result() below. */
+#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
+ /* Snow Leopard introduced the SSLSetSessionOption() function, but due to
+ a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag
+ works, it doesn't work as expected under Snow Leopard or Lion.
+ So we need to call SSLSetEnableCertVerify() on those older cats in order
+ to disable certificate validation if the user turned that off.
+ (SecureTransport will always validate the certificate chain by
+ default.) */
+ /* (Note: Darwin 12.x.x is Mountain Lion.) */
+#if CURL_BUILD_MAC
+ if(SSLSetSessionOption != NULL && darwinver_maj >= 12) {
+#else
+ if(SSLSetSessionOption != NULL) {
+#endif /* CURL_BUILD_MAC */
+ bool break_on_auth = !data->set.ssl.verifypeer ||
+ data->set.str[STRING_SSL_CAFILE];
+ err = SSLSetSessionOption(connssl->ssl_ctx,
+ kSSLSessionOptionBreakOnServerAuth,
+ break_on_auth);
+ if(err != noErr) {
+ failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ }
+ else {
+#if CURL_SUPPORT_MAC_10_8
+ err = SSLSetEnableCertVerify(connssl->ssl_ctx,
+ data->set.ssl.verifypeer?true:false);
+ if(err != noErr) {
+ failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+#endif /* CURL_SUPPORT_MAC_10_8 */
+ }
+#else
+ err = SSLSetEnableCertVerify(connssl->ssl_ctx,
+ data->set.ssl.verifypeer?true:false);
+ if(err != noErr) {
+ failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
+
+ if(data->set.str[STRING_SSL_CAFILE]) {
+ bool is_cert_file = is_file(data->set.str[STRING_SSL_CAFILE]);
+
+ if(!is_cert_file) {
+ failf(data, "SSL: can't load CA certificate file %s",
+ data->set.str[STRING_SSL_CAFILE]);
+ return CURLE_SSL_CACERT_BADFILE;
+ }
+ if(!data->set.ssl.verifypeer) {
+ failf(data, "SSL: CA certificate set, but certificate verification "
+ "is disabled");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ }
+
+ /* Configure hostname check. SNI is used if available.
+ * Both hostname check and SNI require SSLSetPeerDomainName().
+ * Also: the verifyhost setting influences SNI usage */
+ if(data->set.ssl.verifyhost) {
+ err = SSLSetPeerDomainName(connssl->ssl_ctx, conn->host.name,
+ strlen(conn->host.name));
+
+ if(err != noErr) {
+ infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n",
+ err);
+ }
+
+ if((Curl_inet_pton(AF_INET, conn->host.name, &addr))
+ #ifdef ENABLE_IPV6
+ || (Curl_inet_pton(AF_INET6, conn->host.name, &addr))
+ #endif
+ ) {
+ infof(data, "WARNING: using IP address, SNI is being disabled by "
+ "the OS.\n");
+ }
+ }
+
+ /* Disable cipher suites that ST supports but are not safe. These ciphers
+ are unlikely to be used in any case since ST gives other ciphers a much
+ higher priority, but it's probably better that we not connect at all than
+ to give the user a false sense of security if the server only supports
+ insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
+ (void)SSLGetNumberSupportedCiphers(connssl->ssl_ctx, &all_ciphers_count);
+ all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
+ allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
+ if(all_ciphers && allowed_ciphers &&
+ SSLGetSupportedCiphers(connssl->ssl_ctx, all_ciphers,
+ &all_ciphers_count) == noErr) {
+ for(i = 0UL ; i < all_ciphers_count ; i++) {
+#if CURL_BUILD_MAC
+ /* There's a known bug in early versions of Mountain Lion where ST's ECC
+ ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
+ Work around the problem here by disabling those ciphers if we are
+ running in an affected version of OS X. */
+ if(darwinver_maj == 12 && darwinver_min <= 3 &&
+ all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
+ continue;
+ }
+#endif /* CURL_BUILD_MAC */
+ switch(all_ciphers[i]) {
+ /* Disable NULL ciphersuites: */
+ case SSL_NULL_WITH_NULL_NULL:
+ case SSL_RSA_WITH_NULL_MD5:
+ case SSL_RSA_WITH_NULL_SHA:
+ case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */
+ case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
+ case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
+ case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
+ case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */
+ case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */
+ case 0x002C: /* TLS_PSK_WITH_NULL_SHA */
+ case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */
+ case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */
+ case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */
+ case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */
+ case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */
+ case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */
+ case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */
+ case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */
+ /* Disable anonymous ciphersuites: */
+ case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
+ case SSL_DH_anon_WITH_RC4_128_MD5:
+ case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
+ case SSL_DH_anon_WITH_DES_CBC_SHA:
+ case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
+ case TLS_DH_anon_WITH_AES_128_CBC_SHA:
+ case TLS_DH_anon_WITH_AES_256_CBC_SHA:
+ case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */
+ case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */
+ case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
+ case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
+ case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
+ case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
+ case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
+ case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
+ case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
+ /* Disable weak key ciphersuites: */
+ case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
+ case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
+ case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
+ case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
+ case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
+ case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
+ case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
+ case SSL_RSA_WITH_DES_CBC_SHA:
+ case SSL_DH_DSS_WITH_DES_CBC_SHA:
+ case SSL_DH_RSA_WITH_DES_CBC_SHA:
+ case SSL_DHE_DSS_WITH_DES_CBC_SHA:
+ case SSL_DHE_RSA_WITH_DES_CBC_SHA:
+ /* Disable IDEA: */
+ case SSL_RSA_WITH_IDEA_CBC_SHA:
+ case SSL_RSA_WITH_IDEA_CBC_MD5:
+ break;
+ default: /* enable everything else */
+ allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
+ break;
+ }
+ }
+ err = SSLSetEnabledCiphers(connssl->ssl_ctx, allowed_ciphers,
+ allowed_ciphers_count);
+ if(err != noErr) {
+ failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ }
+ else {
+ Curl_safefree(all_ciphers);
+ Curl_safefree(allowed_ciphers);
+ failf(data, "SSL: Failed to allocate memory for allowed ciphers");
+ return CURLE_OUT_OF_MEMORY;
+ }
+ Curl_safefree(all_ciphers);
+ Curl_safefree(allowed_ciphers);
+
+#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
+ /* We want to enable 1/n-1 when using a CBC cipher unless the user
+ specifically doesn't want us doing that: */
+ if(SSLSetSessionOption != NULL) {
+ SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
+ !data->set.ssl_enable_beast);
+ SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionFalseStart,
+ data->set.ssl.falsestart); /* false start support */
+ }
+#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
+
+ /* Check if there's a cached ID we can/should use here! */
+ if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
+ &ssl_sessionid_len)) {
+ /* we got a session id, use it! */
+ err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
+ if(err != noErr) {
+ failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ /* Informational message */
+ infof(data, "SSL re-using session ID\n");
+ }
+ /* If there isn't one, then let's make one up! This has to be done prior
+ to starting the handshake. */
+ else {
+ CURLcode result;
+ ssl_sessionid =
+ aprintf("%s:%d:%d:%s:%hu", data->set.str[STRING_SSL_CAFILE],
+ data->set.ssl.verifypeer, data->set.ssl.verifyhost,
+ conn->host.name, conn->remote_port);
+ ssl_sessionid_len = strlen(ssl_sessionid);
+
+ err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
+ if(err != noErr) {
+ failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
+ result = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len);
+ if(result) {
+ failf(data, "failed to store ssl session");
+ return result;
+ }
+ }
+
+ err = SSLSetIOFuncs(connssl->ssl_ctx, SocketRead, SocketWrite);
+ if(err != noErr) {
+ failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
+ /* pass the raw socket into the SSL layers */
+ /* We need to store the FD in a constant memory address, because
+ * SSLSetConnection() will not copy that address. I've found that
+ * conn->sock[sockindex] may change on its own. */
+ connssl->ssl_sockfd = sockfd;
+ err = SSLSetConnection(connssl->ssl_ctx, connssl);
+ if(err != noErr) {
+ failf(data, "SSL: SSLSetConnection() failed: %d", err);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
+ connssl->connecting_state = ssl_connect_2;
+ return CURLE_OK;
+}
+
+static long pem_to_der(const char *in, unsigned char **out, size_t *outlen)
+{
+ char *sep_start, *sep_end, *cert_start, *cert_end;
+ size_t i, j, err;
+ size_t len;
+ unsigned char *b64;
+
+ /* Jump through the separators at the beginning of the certificate. */
+ sep_start = strstr(in, "-----");
+ if(sep_start == NULL)
+ return 0;
+ cert_start = strstr(sep_start + 1, "-----");
+ if(cert_start == NULL)
+ return -1;
+
+ cert_start += 5;
+
+ /* Find separator after the end of the certificate. */
+ cert_end = strstr(cert_start, "-----");
+ if(cert_end == NULL)
+ return -1;
+
+ sep_end = strstr(cert_end + 1, "-----");
+ if(sep_end == NULL)
+ return -1;
+ sep_end += 5;
+
+ len = cert_end - cert_start;
+ b64 = malloc(len + 1);
+ if(!b64)
+ return -1;
+
+ /* Create base64 string without linefeeds. */
+ for(i = 0, j = 0; i < len; i++) {
+ if(cert_start[i] != '\r' && cert_start[i] != '\n')
+ b64[j++] = cert_start[i];
+ }
+ b64[j] = '\0';
+
+ err = Curl_base64_decode((const char *)b64, out, outlen);
+ free(b64);
+ if(err) {
+ free(*out);
+ return -1;
+ }
+
+ return sep_end - in;
+}
+
+static int read_cert(const char *file, unsigned char **out, size_t *outlen)
+{
+ int fd;
+ ssize_t n, len = 0, cap = 512;
+ unsigned char buf[cap], *data;
+
+ fd = open(file, 0);
+ if(fd < 0)
+ return -1;
+
+ data = malloc(cap);
+ if(!data) {
+ close(fd);
+ return -1;
+ }
+
+ for(;;) {
+ n = read(fd, buf, sizeof(buf));
+ if(n < 0) {
+ close(fd);
+ free(data);
+ return -1;
+ }
+ else if(n == 0) {
+ close(fd);
+ break;
+ }
+
+ if(len + n >= cap) {
+ cap *= 2;
+ data = realloc(data, cap);
+ if(!data) {
+ close(fd);
+ return -1;
+ }
+ }
+
+ memcpy(data + len, buf, n);
+ len += n;
+ }
+ data[len] = '\0';
+
+ *out = data;
+ *outlen = len;
+
+ return 0;
+}
+
+static int sslerr_to_curlerr(struct SessionHandle *data, int err)
+{
+ switch(err) {
+ case errSSLXCertChainInvalid:
+ failf(data, "SSL certificate problem: Invalid certificate chain");
+ return CURLE_SSL_CACERT;
+ case errSSLUnknownRootCert:
+ failf(data, "SSL certificate problem: Untrusted root certificate");
+ return CURLE_SSL_CACERT;
+ case errSSLNoRootCert:
+ failf(data, "SSL certificate problem: No root certificate");
+ return CURLE_SSL_CACERT;
+ case errSSLCertExpired:
+ failf(data, "SSL certificate problem: Certificate chain had an "
+ "expired certificate");
+ return CURLE_SSL_CACERT;
+ case errSSLBadCert:
+ failf(data, "SSL certificate problem: Couldn't understand the server "
+ "certificate format");
+ return CURLE_SSL_CONNECT_ERROR;
+ case errSSLHostNameMismatch:
+ failf(data, "SSL certificate peer hostname mismatch");
+ return CURLE_PEER_FAILED_VERIFICATION;
+ default:
+ failf(data, "SSL unexpected certificate error %d", err);
+ return CURLE_SSL_CACERT;
+ }
+}
+
+static int append_cert_to_array(struct SessionHandle *data,
+ unsigned char *buf, size_t buflen,
+ CFMutableArrayRef array)
+{
+ CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen);
+ if(!certdata) {
+ failf(data, "SSL: failed to allocate array for CA certificate");
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ SecCertificateRef cacert =
+ SecCertificateCreateWithData(kCFAllocatorDefault, certdata);
+ CFRelease(certdata);
+ if(!cacert) {
+ failf(data, "SSL: failed to create SecCertificate from CA certificate");
+ return CURLE_SSL_CACERT;
+ }
+
+ /* Check if cacert is valid. */
+ CFStringRef subject = CopyCertSubject(cacert);
+ if(subject) {
+ char subject_cbuf[128];
+ memset(subject_cbuf, 0, 128);
+ if(!CFStringGetCString(subject,
+ subject_cbuf,
+ 128,
+ kCFStringEncodingUTF8)) {
+ CFRelease(cacert);
+ failf(data, "SSL: invalid CA certificate subject");
+ return CURLE_SSL_CACERT;
+ }
+ CFRelease(subject);
+ }
+ else {
+ CFRelease(cacert);
+ failf(data, "SSL: invalid CA certificate");
+ return CURLE_SSL_CACERT;
+ }
+
+ CFArrayAppendValue(array, cacert);
+ CFRelease(cacert);
+
+ return CURLE_OK;
+}
+
+static int verify_cert(const char *cafile, struct SessionHandle *data,
+ SSLContextRef ctx)
+{
+ int n = 0, rc;
+ long res;
+ unsigned char *certbuf, *der;
+ size_t buflen, derlen, offset = 0;
+
+ if(read_cert(cafile, &certbuf, &buflen) < 0) {
+ failf(data, "SSL: failed to read or invalid CA certificate");
+ return CURLE_SSL_CACERT;
+ }
+
+ /*
+ * Certbuf now contains the contents of the certificate file, which can be
+ * - a single DER certificate,
+ * - a single PEM certificate or
+ * - a bunch of PEM certificates (certificate bundle).
+ *
+ * Go through certbuf, and convert any PEM certificate in it into DER
+ * format.
+ */
+ CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0,
+ &kCFTypeArrayCallBacks);
+ if(array == NULL) {
+ free(certbuf);
+ failf(data, "SSL: out of memory creating CA certificate array");
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ while(offset < buflen) {
+ n++;
+
+ /*
+ * Check if the certificate is in PEM format, and convert it to DER. If
+ * this fails, we assume the certificate is in DER format.
+ */
+ res = pem_to_der((const char *)certbuf + offset, &der, &derlen);
+ if(res < 0) {
+ free(certbuf);
+ CFRelease(array);
+ failf(data, "SSL: invalid CA certificate #%d (offset %d) in bundle",
+ n, offset);
+ return CURLE_SSL_CACERT;
+ }
+ offset += res;
+
+ if(res == 0 && offset == 0) {
+ /* This is not a PEM file, probably a certificate in DER format. */
+ rc = append_cert_to_array(data, certbuf, buflen, array);
+ free(certbuf);
+ if(rc != CURLE_OK) {
+ CFRelease(array);
+ return rc;
+ }
+ break;
+ }
+ else if(res == 0) {
+ /* No more certificates in the bundle. */
+ free(certbuf);
+ break;
+ }
+
+ rc = append_cert_to_array(data, der, derlen, array);
+ free(der);
+ if(rc != CURLE_OK) {
+ free(certbuf);
+ CFRelease(array);
+ return rc;
+ }
+ }
+
+ SecTrustRef trust;
+ OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
+ if(trust == NULL) {
+ failf(data, "SSL: error getting certificate chain");
+ CFRelease(array);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ else if(ret != noErr) {
+ CFRelease(array);
+ return sslerr_to_curlerr(data, ret);
+ }
+
+ ret = SecTrustSetAnchorCertificates(trust, array);
+ if(ret != noErr) {
+ CFRelease(trust);
+ return sslerr_to_curlerr(data, ret);
+ }
+ ret = SecTrustSetAnchorCertificatesOnly(trust, true);
+ if(ret != noErr) {
+ CFRelease(trust);
+ return sslerr_to_curlerr(data, ret);
+ }
+
+ SecTrustResultType trust_eval = 0;
+ ret = SecTrustEvaluate(trust, &trust_eval);
+ CFRelease(array);
+ CFRelease(trust);
+ if(ret != noErr) {
+ return sslerr_to_curlerr(data, ret);
+ }
+
+ switch (trust_eval) {
+ case kSecTrustResultUnspecified:
+ case kSecTrustResultProceed:
+ return CURLE_OK;
+
+ case kSecTrustResultRecoverableTrustFailure:
+ case kSecTrustResultDeny:
+ default:
+ failf(data, "SSL: certificate verification failed (result: %d)",
+ trust_eval);
+ return CURLE_PEER_FAILED_VERIFICATION;
+ }
+}
+
+static CURLcode
+darwinssl_connect_step2(struct connectdata *conn, int sockindex)
+{
+ struct SessionHandle *data = conn->data;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ OSStatus err;
+ SSLCipherSuite cipher;
+ SSLProtocol protocol = 0;
+
+ DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
+ || ssl_connect_2_reading == connssl->connecting_state
+ || ssl_connect_2_writing == connssl->connecting_state);
+
+ /* Here goes nothing: */
+ err = SSLHandshake(connssl->ssl_ctx);
+
+ if(err != noErr) {
+ switch (err) {
+ case errSSLWouldBlock: /* they're not done with us yet */
+ connssl->connecting_state = connssl->ssl_direction ?
+ ssl_connect_2_writing : ssl_connect_2_reading;
+ return CURLE_OK;
+
+ /* The below is errSSLServerAuthCompleted; it's not defined in
+ Leopard's headers */
+ case -9841:
+ if(data->set.str[STRING_SSL_CAFILE]) {
+ int res = verify_cert(data->set.str[STRING_SSL_CAFILE], data,
+ connssl->ssl_ctx);
+ if(res != CURLE_OK)
+ return res;
+ }
+ /* the documentation says we need to call SSLHandshake() again */
+ return darwinssl_connect_step2(conn, sockindex);
+
+ /* These are all certificate problems with the server: */
+ case errSSLXCertChainInvalid:
+ failf(data, "SSL certificate problem: Invalid certificate chain");
+ return CURLE_SSL_CACERT;
+ case errSSLUnknownRootCert:
+ failf(data, "SSL certificate problem: Untrusted root certificate");
+ return CURLE_SSL_CACERT;
+ case errSSLNoRootCert:
+ failf(data, "SSL certificate problem: No root certificate");
+ return CURLE_SSL_CACERT;
+ case errSSLCertExpired:
+ failf(data, "SSL certificate problem: Certificate chain had an "
+ "expired certificate");
+ return CURLE_SSL_CACERT;
+ case errSSLBadCert:
+ failf(data, "SSL certificate problem: Couldn't understand the server "
+ "certificate format");
+ return CURLE_SSL_CONNECT_ERROR;
+
+ /* These are all certificate problems with the client: */
+ case errSecAuthFailed:
+ failf(data, "SSL authentication failed");
+ return CURLE_SSL_CONNECT_ERROR;
+ case errSSLPeerHandshakeFail:
+ failf(data, "SSL peer handshake failed, the server most likely "
+ "requires a client certificate to connect");
+ return CURLE_SSL_CONNECT_ERROR;
+ case errSSLPeerUnknownCA:
+ failf(data, "SSL server rejected the client certificate due to "
+ "the certificate being signed by an unknown certificate "
+ "authority");
+ return CURLE_SSL_CONNECT_ERROR;
+
+ /* This error is raised if the server's cert didn't match the server's
+ host name: */
+ case errSSLHostNameMismatch:
+ failf(data, "SSL certificate peer verification failed, the "
+ "certificate did not match \"%s\"\n", conn->host.dispname);
+ return CURLE_PEER_FAILED_VERIFICATION;
+
+ /* Generic handshake errors: */
+ case errSSLConnectionRefused:
+ failf(data, "Server dropped the connection during the SSL handshake");
+ return CURLE_SSL_CONNECT_ERROR;
+ case errSSLClosedAbort:
+ failf(data, "Server aborted the SSL handshake");
+ return CURLE_SSL_CONNECT_ERROR;
+ case errSSLNegotiation:
+ failf(data, "Could not negotiate an SSL cipher suite with the server");
+ return CURLE_SSL_CONNECT_ERROR;
+ /* Sometimes paramErr happens with buggy ciphers: */
+ case paramErr: case errSSLInternal:
+ failf(data, "Internal SSL engine error encountered during the "
+ "SSL handshake");
+ return CURLE_SSL_CONNECT_ERROR;
+ case errSSLFatalAlert:
+ failf(data, "Fatal SSL engine error encountered during the SSL "
+ "handshake");
+ return CURLE_SSL_CONNECT_ERROR;
+ default:
+ failf(data, "Unknown SSL protocol error in connection to %s:%d",
+ conn->host.name, err);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ }
+ else {
+ /* we have been connected fine, we're not waiting for anything else. */
+ connssl->connecting_state = ssl_connect_3;
+
+ /* Informational message */
+ (void)SSLGetNegotiatedCipher(connssl->ssl_ctx, &cipher);
+ (void)SSLGetNegotiatedProtocolVersion(connssl->ssl_ctx, &protocol);
+ switch (protocol) {
+ case kSSLProtocol2:
+ infof(data, "SSL 2.0 connection using %s\n",
+ SSLCipherNameForNumber(cipher));
+ break;
+ case kSSLProtocol3:
+ infof(data, "SSL 3.0 connection using %s\n",
+ SSLCipherNameForNumber(cipher));
+ break;
+ case kTLSProtocol1:
+ infof(data, "TLS 1.0 connection using %s\n",
+ TLSCipherNameForNumber(cipher));
+ break;
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+ case kTLSProtocol11:
+ infof(data, "TLS 1.1 connection using %s\n",
+ TLSCipherNameForNumber(cipher));
+ break;
+ case kTLSProtocol12:
+ infof(data, "TLS 1.2 connection using %s\n",
+ TLSCipherNameForNumber(cipher));
+ break;
+#endif
+ default:
+ infof(data, "Unknown protocol connection\n");
+ break;
+ }
+
+ return CURLE_OK;
+ }
+}
+
+static CURLcode
+darwinssl_connect_step3(struct connectdata *conn,
+ int sockindex)
+{
+ struct SessionHandle *data = conn->data;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ CFStringRef server_cert_summary;
+ char server_cert_summary_c[128];
+ CFArrayRef server_certs = NULL;
+ SecCertificateRef server_cert;
+ OSStatus err;
+ CFIndex i, count;
+ SecTrustRef trust = NULL;
+
+ /* There is no step 3!
+ * Well, okay, if verbose mode is on, let's print the details of the
+ * server certificates. */
+#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
+#if CURL_BUILD_IOS
+#pragma unused(server_certs)
+ err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
+ /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
+ a null trust, so be on guard for that: */
+ if(err == noErr && trust) {
+ count = SecTrustGetCertificateCount(trust);
+ for(i = 0L ; i < count ; i++) {
+ server_cert = SecTrustGetCertificateAtIndex(trust, i);
+ server_cert_summary = CopyCertSubject(server_cert);
+ memset(server_cert_summary_c, 0, 128);
+ if(CFStringGetCString(server_cert_summary,
+ server_cert_summary_c,
+ 128,
+ kCFStringEncodingUTF8)) {
+ infof(data, "Server certificate: %s\n", server_cert_summary_c);
+ }
+ CFRelease(server_cert_summary);
+ }
+ CFRelease(trust);
+ }
+#else
+ /* SSLCopyPeerCertificates() is deprecated as of Mountain Lion.
+ The function SecTrustGetCertificateAtIndex() is officially present
+ in Lion, but it is unfortunately also present in Snow Leopard as
+ private API and doesn't work as expected. So we have to look for
+ a different symbol to make sure this code is only executed under
+ Lion or later. */
+ if(SecTrustEvaluateAsync != NULL) {
+#pragma unused(server_certs)
+ err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
+ /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
+ a null trust, so be on guard for that: */
+ if(err == noErr && trust) {
+ count = SecTrustGetCertificateCount(trust);
+ for(i = 0L ; i < count ; i++) {
+ server_cert = SecTrustGetCertificateAtIndex(trust, i);
+ server_cert_summary = CopyCertSubject(server_cert);
+ memset(server_cert_summary_c, 0, 128);
+ if(CFStringGetCString(server_cert_summary,
+ server_cert_summary_c,
+ 128,
+ kCFStringEncodingUTF8)) {
+ infof(data, "Server certificate: %s\n", server_cert_summary_c);
+ }
+ CFRelease(server_cert_summary);
+ }
+ CFRelease(trust);
+ }
+ }
+ else {
+#if CURL_SUPPORT_MAC_10_8
+ err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
+ /* Just in case SSLCopyPeerCertificates() returns null too... */
+ if(err == noErr && server_certs) {
+ count = CFArrayGetCount(server_certs);
+ for(i = 0L ; i < count ; i++) {
+ server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
+ i);
+
+ server_cert_summary = CopyCertSubject(server_cert);
+ memset(server_cert_summary_c, 0, 128);
+ if(CFStringGetCString(server_cert_summary,
+ server_cert_summary_c,
+ 128,
+ kCFStringEncodingUTF8)) {
+ infof(data, "Server certificate: %s\n", server_cert_summary_c);
+ }
+ CFRelease(server_cert_summary);
+ }
+ CFRelease(server_certs);
+ }
+#endif /* CURL_SUPPORT_MAC_10_8 */
+ }
+#endif /* CURL_BUILD_IOS */
+#else
+#pragma unused(trust)
+ err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
+ if(err == noErr) {
+ count = CFArrayGetCount(server_certs);
+ for(i = 0L ; i < count ; i++) {
+ server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i);
+ server_cert_summary = CopyCertSubject(server_cert);
+ memset(server_cert_summary_c, 0, 128);
+ if(CFStringGetCString(server_cert_summary,
+ server_cert_summary_c,
+ 128,
+ kCFStringEncodingUTF8)) {
+ infof(data, "Server certificate: %s\n", server_cert_summary_c);
+ }
+ CFRelease(server_cert_summary);
+ }
+ CFRelease(server_certs);
+ }
+#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
+
+ connssl->connecting_state = ssl_connect_done;
+ return CURLE_OK;
+}
+
+static Curl_recv darwinssl_recv;
+static Curl_send darwinssl_send;
+
+static CURLcode
+darwinssl_connect_common(struct connectdata *conn,
+ int sockindex,
+ bool nonblocking,
+ bool *done)
+{
+ CURLcode result;
+ struct SessionHandle *data = conn->data;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ curl_socket_t sockfd = conn->sock[sockindex];
+ long timeout_ms;
+ int what;
+
+ /* check if the connection has already been established */
+ if(ssl_connection_complete == connssl->state) {
+ *done = TRUE;
+ return CURLE_OK;
+ }
+
+ if(ssl_connect_1==connssl->connecting_state) {
+ /* Find out how much more time we're allowed */
+ timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+ if(timeout_ms < 0) {
+ /* no need to continue if time already is up */
+ failf(data, "SSL connection timeout");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+
+ result = darwinssl_connect_step1(conn, sockindex);
+ if(result)
+ return result;
+ }
+
+ while(ssl_connect_2 == connssl->connecting_state ||
+ ssl_connect_2_reading == connssl->connecting_state ||
+ ssl_connect_2_writing == connssl->connecting_state) {
+
+ /* check allowed time left */
+ timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+ if(timeout_ms < 0) {
+ /* no need to continue if time already is up */
+ failf(data, "SSL connection timeout");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+
+ /* if ssl is expecting something, check if it's available. */
+ if(connssl->connecting_state == ssl_connect_2_reading ||
+ connssl->connecting_state == ssl_connect_2_writing) {
+
+ curl_socket_t writefd = ssl_connect_2_writing ==
+ connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+ curl_socket_t readfd = ssl_connect_2_reading ==
+ connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+
+ what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
+ if(what < 0) {
+ /* fatal error */
+ failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ else if(0 == what) {
+ if(nonblocking) {
+ *done = FALSE;
+ return CURLE_OK;
+ }
+ else {
+ /* timeout */
+ failf(data, "SSL connection timeout");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+ }
+ /* socket is readable or writable */
+ }
+
+ /* Run transaction, and return to the caller if it failed or if this
+ * connection is done nonblocking and this loop would execute again. This
+ * permits the owner of a multi handle to abort a connection attempt
+ * before step2 has completed while ensuring that a client using select()
+ * or epoll() will always have a valid fdset to wait on.
+ */
+ result = darwinssl_connect_step2(conn, sockindex);
+ if(result || (nonblocking &&
+ (ssl_connect_2 == connssl->connecting_state ||
+ ssl_connect_2_reading == connssl->connecting_state ||
+ ssl_connect_2_writing == connssl->connecting_state)))
+ return result;
+
+ } /* repeat step2 until all transactions are done. */
+
+
+ if(ssl_connect_3 == connssl->connecting_state) {
+ result = darwinssl_connect_step3(conn, sockindex);
+ if(result)
+ return result;
+ }
+
+ if(ssl_connect_done == connssl->connecting_state) {
+ connssl->state = ssl_connection_complete;
+ conn->recv[sockindex] = darwinssl_recv;
+ conn->send[sockindex] = darwinssl_send;
+ *done = TRUE;
+ }
+ else
+ *done = FALSE;
+
+ /* Reset our connect state machine */
+ connssl->connecting_state = ssl_connect_1;
+
+ return CURLE_OK;
+}
+
+CURLcode
+Curl_darwinssl_connect_nonblocking(struct connectdata *conn,
+ int sockindex,
+ bool *done)
+{
+ return darwinssl_connect_common(conn, sockindex, TRUE, done);
+}
+
+CURLcode
+Curl_darwinssl_connect(struct connectdata *conn,
+ int sockindex)
+{
+ CURLcode result;
+ bool done = FALSE;
+
+ result = darwinssl_connect_common(conn, sockindex, FALSE, &done);
+
+ if(result)
+ return result;
+
+ DEBUGASSERT(done);
+
+ return CURLE_OK;
+}
+
+void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
+{
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+ if(connssl->ssl_ctx) {
+ (void)SSLClose(connssl->ssl_ctx);
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+ if(SSLCreateContext != NULL)
+ CFRelease(connssl->ssl_ctx);
+#if CURL_SUPPORT_MAC_10_8
+ else
+ (void)SSLDisposeContext(connssl->ssl_ctx);
+#endif /* CURL_SUPPORT_MAC_10_8 */
+#else
+ (void)SSLDisposeContext(connssl->ssl_ctx);
+#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
+ connssl->ssl_ctx = NULL;
+ }
+ connssl->ssl_sockfd = 0;
+}
+
+int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
+{
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct SessionHandle *data = conn->data;
+ ssize_t nread;
+ int what;
+ int rc;
+ char buf[120];
+
+ if(!connssl->ssl_ctx)
+ return 0;
+
+ if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
+ return 0;
+
+ Curl_darwinssl_close(conn, sockindex);
+
+ rc = 0;
+
+ what = Curl_socket_ready(conn->sock[sockindex],
+ CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
+
+ for(;;) {
+ if(what < 0) {
+ /* anything that gets here is fatally bad */
+ failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+ rc = -1;
+ break;
+ }
+
+ if(!what) { /* timeout */
+ failf(data, "SSL shutdown timeout");
+ break;
+ }
+
+ /* Something to read, let's do it and hope that it is the close
+ notify alert from the server. No way to SSL_Read now, so use read(). */
+
+ nread = read(conn->sock[sockindex], buf, sizeof(buf));
+
+ if(nread < 0) {
+ failf(data, "read: %s", strerror(errno));
+ rc = -1;
+ }
+
+ if(nread <= 0)
+ break;
+
+ what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, 0);
+ }
+
+ return rc;
+}
+
+void Curl_darwinssl_session_free(void *ptr)
+{
+ /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a
+ cached session ID inside the Security framework. There is a private
+ function that does this, but I don't want to have to explain to you why I
+ got your application rejected from the App Store due to the use of a
+ private API, so the best we can do is free up our own char array that we
+ created way back in darwinssl_connect_step1... */
+ Curl_safefree(ptr);
+}
+
+size_t Curl_darwinssl_version(char *buffer, size_t size)
+{
+ return snprintf(buffer, size, "SecureTransport");
+}
+
+/*
+ * This function uses SSLGetSessionState to determine connection status.
+ *
+ * Return codes:
+ * 1 means the connection is still in place
+ * 0 means the connection has been closed
+ * -1 means the connection status is unknown
+ */
+int Curl_darwinssl_check_cxn(struct connectdata *conn)
+{
+ struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
+ OSStatus err;
+ SSLSessionState state;
+
+ if(connssl->ssl_ctx) {
+ err = SSLGetSessionState(connssl->ssl_ctx, &state);
+ if(err == noErr)
+ return state == kSSLConnected || state == kSSLHandshake;
+ return -1;
+ }
+ return 0;
+}
+
+bool Curl_darwinssl_data_pending(const struct connectdata *conn,
+ int connindex)
+{
+ const struct ssl_connect_data *connssl = &conn->ssl[connindex];
+ OSStatus err;
+ size_t buffer;
+
+ if(connssl->ssl_ctx) { /* SSL is in use */
+ err = SSLGetBufferedReadSize(connssl->ssl_ctx, &buffer);
+ if(err == noErr)
+ return buffer > 0UL;
+ return false;
+ }
+ else
+ return false;
+}
+
+int Curl_darwinssl_random(unsigned char *entropy,
+ size_t length)
+{
+ /* arc4random_buf() isn't available on cats older than Lion, so let's
+ do this manually for the benefit of the older cats. */
+ size_t i;
+ u_int32_t random_number = 0;
+
+ for(i = 0 ; i < length ; i++) {
+ if(i % sizeof(u_int32_t) == 0)
+ random_number = arc4random();
+ entropy[i] = random_number & 0xFF;
+ random_number >>= 8;
+ }
+ i = random_number = 0;
+ return 0;
+}
+
+void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
+ size_t tmplen,
+ unsigned char *md5sum, /* output */
+ size_t md5len)
+{
+ (void)md5len;
+ (void)CC_MD5(tmp, (CC_LONG)tmplen, md5sum);
+}
+
+bool Curl_darwinssl_false_start(void) {
+#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
+ if(SSLSetSessionOption != NULL)
+ return TRUE;
+#endif
+ return FALSE;
+}
+
+static ssize_t darwinssl_send(struct connectdata *conn,
+ int sockindex,
+ const void *mem,
+ size_t len,
+ CURLcode *curlcode)
+{
+ /*struct SessionHandle *data = conn->data;*/
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ size_t processed = 0UL;
+ OSStatus err;
+
+ /* The SSLWrite() function works a little differently than expected. The
+ fourth argument (processed) is currently documented in Apple's
+ documentation as: "On return, the length, in bytes, of the data actually
+ written."
+
+ Now, one could interpret that as "written to the socket," but actually,
+ it returns the amount of data that was written to a buffer internal to
+ the SSLContextRef instead. So it's possible for SSLWrite() to return
+ errSSLWouldBlock and a number of bytes "written" because those bytes were
+ encrypted and written to a buffer, not to the socket.
+
+ So if this happens, then we need to keep calling SSLWrite() over and
+ over again with no new data until it quits returning errSSLWouldBlock. */
+
+ /* Do we have buffered data to write from the last time we were called? */
+ if(connssl->ssl_write_buffered_length) {
+ /* Write the buffered data: */
+ err = SSLWrite(connssl->ssl_ctx, NULL, 0UL, &processed);
+ switch (err) {
+ case noErr:
+ /* processed is always going to be 0 because we didn't write to
+ the buffer, so return how much was written to the socket */
+ processed = connssl->ssl_write_buffered_length;
+ connssl->ssl_write_buffered_length = 0UL;
+ break;
+ case errSSLWouldBlock: /* argh, try again */
+ *curlcode = CURLE_AGAIN;
+ return -1L;
+ default:
+ failf(conn->data, "SSLWrite() returned error %d", err);
+ *curlcode = CURLE_SEND_ERROR;
+ return -1L;
+ }
+ }
+ else {
+ /* We've got new data to write: */
+ err = SSLWrite(connssl->ssl_ctx, mem, len, &processed);
+ if(err != noErr) {
+ switch (err) {
+ case errSSLWouldBlock:
+ /* Data was buffered but not sent, we have to tell the caller
+ to try sending again, and remember how much was buffered */
+ connssl->ssl_write_buffered_length = len;
+ *curlcode = CURLE_AGAIN;
+ return -1L;
+ default:
+ failf(conn->data, "SSLWrite() returned error %d", err);
+ *curlcode = CURLE_SEND_ERROR;
+ return -1L;
+ }
+ }
+ }
+ return (ssize_t)processed;
+}
+
+static ssize_t darwinssl_recv(struct connectdata *conn,
+ int num,
+ char *buf,
+ size_t buffersize,
+ CURLcode *curlcode)
+{
+ /*struct SessionHandle *data = conn->data;*/
+ struct ssl_connect_data *connssl = &conn->ssl[num];
+ size_t processed = 0UL;
+ OSStatus err = SSLRead(connssl->ssl_ctx, buf, buffersize, &processed);
+
+ if(err != noErr) {
+ switch (err) {
+ case errSSLWouldBlock: /* return how much we read (if anything) */
+ if(processed)
+ return (ssize_t)processed;
+ *curlcode = CURLE_AGAIN;
+ return -1L;
+ break;
+
+ /* errSSLClosedGraceful - server gracefully shut down the SSL session
+ errSSLClosedNoNotify - server hung up on us instead of sending a
+ closure alert notice, read() is returning 0
+ Either way, inform the caller that the server disconnected. */
+ case errSSLClosedGraceful:
+ case errSSLClosedNoNotify:
+ *curlcode = CURLE_OK;
+ return -1L;
+ break;
+
+ default:
+ failf(conn->data, "SSLRead() return error %d", err);
+ *curlcode = CURLE_RECV_ERROR;
+ return -1L;
+ break;
+ }
+ }
+ return (ssize_t)processed;
+}
+
+#endif /* USE_DARWINSSL */
diff --git a/Utilities/cmcurl/lib/vtls/darwinssl.h b/Utilities/cmcurl/lib/vtls/darwinssl.h
new file mode 100644
index 000000000..3bb69c01a
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/darwinssl.h
@@ -0,0 +1,76 @@
+#ifndef HEADER_CURL_DARWINSSL_H
+#define HEADER_CURL_DARWINSSL_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman@gmail.com>.
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef USE_DARWINSSL
+
+CURLcode Curl_darwinssl_connect(struct connectdata *conn, int sockindex);
+
+CURLcode Curl_darwinssl_connect_nonblocking(struct connectdata *conn,
+ int sockindex,
+ bool *done);
+
+/* close a SSL connection */
+void Curl_darwinssl_close(struct connectdata *conn, int sockindex);
+
+void Curl_darwinssl_session_free(void *ptr);
+size_t Curl_darwinssl_version(char *buffer, size_t size);
+int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex);
+int Curl_darwinssl_check_cxn(struct connectdata *conn);
+bool Curl_darwinssl_data_pending(const struct connectdata *conn,
+ int connindex);
+
+int Curl_darwinssl_random(unsigned char *entropy,
+ size_t length);
+void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
+ size_t tmplen,
+ unsigned char *md5sum, /* output */
+ size_t md5len);
+bool Curl_darwinssl_false_start(void);
+
+/* Set the API backend definition to SecureTransport */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_DARWINSSL
+
+/* API setup for SecureTransport */
+#define curlssl_init() (1)
+#define curlssl_cleanup() Curl_nop_stmt
+#define curlssl_connect Curl_darwinssl_connect
+#define curlssl_connect_nonblocking Curl_darwinssl_connect_nonblocking
+#define curlssl_session_free(x) Curl_darwinssl_session_free(x)
+#define curlssl_close_all(x) ((void)x)
+#define curlssl_close Curl_darwinssl_close
+#define curlssl_shutdown(x,y) 0
+#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN)
+#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN)
+#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL)
+#define curlssl_version Curl_darwinssl_version
+#define curlssl_check_cxn Curl_darwinssl_check_cxn
+#define curlssl_data_pending(x,y) Curl_darwinssl_data_pending(x, y)
+#define curlssl_random(x,y,z) ((void)x, Curl_darwinssl_random(y,z))
+#define curlssl_md5sum(a,b,c,d) Curl_darwinssl_md5sum(a,b,c,d)
+#define curlssl_false_start() Curl_darwinssl_false_start()
+
+#endif /* USE_DARWINSSL */
+#endif /* HEADER_CURL_DARWINSSL_H */
diff --git a/Utilities/cmcurl/lib/vtls/gskit.c b/Utilities/cmcurl/lib/vtls/gskit.c
new file mode 100644
index 000000000..d884bd4c4
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/gskit.c
@@ -0,0 +1,1069 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_GSKIT
+
+#include <gskssl.h>
+#include <qsoasync.h>
+
+/* Some symbols are undefined/unsupported on OS400 versions < V7R1. */
+#ifndef GSK_SSL_EXTN_SERVERNAME_REQUEST
+#define GSK_SSL_EXTN_SERVERNAME_REQUEST 230
+#endif
+
+#ifndef GSK_TLSV10_CIPHER_SPECS
+#define GSK_TLSV10_CIPHER_SPECS 236
+#endif
+
+#ifndef GSK_TLSV11_CIPHER_SPECS
+#define GSK_TLSV11_CIPHER_SPECS 237
+#endif
+
+#ifndef GSK_TLSV12_CIPHER_SPECS
+#define GSK_TLSV12_CIPHER_SPECS 238
+#endif
+
+#ifndef GSK_PROTOCOL_TLSV11
+#define GSK_PROTOCOL_TLSV11 437
+#endif
+
+#ifndef GSK_PROTOCOL_TLSV12
+#define GSK_PROTOCOL_TLSV12 438
+#endif
+
+#ifndef GSK_FALSE
+#define GSK_FALSE 0
+#endif
+
+#ifndef GSK_TRUE
+#define GSK_TRUE 1
+#endif
+
+
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "sendf.h"
+#include "gskit.h"
+#include "vtls.h"
+#include "connect.h" /* for the connect timeout */
+#include "select.h"
+#include "strequal.h"
+#include "x509asn1.h"
+#include "curl_printf.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+
+/* SSL version flags. */
+#define CURL_GSKPROTO_SSLV2 0
+#define CURL_GSKPROTO_SSLV2_MASK (1 << CURL_GSKPROTO_SSLV2)
+#define CURL_GSKPROTO_SSLV3 1
+#define CURL_GSKPROTO_SSLV3_MASK (1 << CURL_GSKPROTO_SSLV3)
+#define CURL_GSKPROTO_TLSV10 2
+#define CURL_GSKPROTO_TLSV10_MASK (1 << CURL_GSKPROTO_TLSV10)
+#define CURL_GSKPROTO_TLSV11 3
+#define CURL_GSKPROTO_TLSV11_MASK (1 << CURL_GSKPROTO_TLSV11)
+#define CURL_GSKPROTO_TLSV12 4
+#define CURL_GSKPROTO_TLSV12_MASK (1 << CURL_GSKPROTO_TLSV12)
+#define CURL_GSKPROTO_LAST 5
+
+
+/* Supported ciphers. */
+typedef struct {
+ const char *name; /* Cipher name. */
+ const char *gsktoken; /* Corresponding token for GSKit String. */
+ unsigned int versions; /* SSL version flags. */
+} gskit_cipher;
+
+static const gskit_cipher ciphertable[] = {
+ { "null-md5", "01",
+ CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
+ CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
+ { "null-sha", "02",
+ CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
+ CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
+ { "exp-rc4-md5", "03",
+ CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK },
+ { "rc4-md5", "04",
+ CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
+ CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
+ { "rc4-sha", "05",
+ CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
+ CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
+ { "exp-rc2-cbc-md5", "06",
+ CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK },
+ { "exp-des-cbc-sha", "09",
+ CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
+ CURL_GSKPROTO_TLSV11_MASK },
+ { "des-cbc3-sha", "0A",
+ CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
+ CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
+ { "aes128-sha", "2F",
+ CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK |
+ CURL_GSKPROTO_TLSV12_MASK },
+ { "aes256-sha", "35",
+ CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK |
+ CURL_GSKPROTO_TLSV12_MASK },
+ { "null-sha256", "3B", CURL_GSKPROTO_TLSV12_MASK },
+ { "aes128-sha256", "3C", CURL_GSKPROTO_TLSV12_MASK },
+ { "aes256-sha256", "3D", CURL_GSKPROTO_TLSV12_MASK },
+ { "aes128-gcm-sha256",
+ "9C", CURL_GSKPROTO_TLSV12_MASK },
+ { "aes256-gcm-sha384",
+ "9D", CURL_GSKPROTO_TLSV12_MASK },
+ { "rc4-md5", "1", CURL_GSKPROTO_SSLV2_MASK },
+ { "exp-rc4-md5", "2", CURL_GSKPROTO_SSLV2_MASK },
+ { "rc2-md5", "3", CURL_GSKPROTO_SSLV2_MASK },
+ { "exp-rc2-md5", "4", CURL_GSKPROTO_SSLV2_MASK },
+ { "des-cbc-md5", "6", CURL_GSKPROTO_SSLV2_MASK },
+ { "des-cbc3-md5", "7", CURL_GSKPROTO_SSLV2_MASK },
+ { (const char *) NULL, (const char *) NULL, 0 }
+};
+
+
+static bool is_separator(char c)
+{
+ /* Return whether character is a cipher list separator. */
+ switch (c) {
+ case ' ':
+ case '\t':
+ case ':':
+ case ',':
+ case ';':
+ return true;
+ }
+ return false;
+}
+
+
+static CURLcode gskit_status(struct SessionHandle *data, int rc,
+ const char *procname, CURLcode defcode)
+{
+ /* Process GSKit status and map it to a CURLcode. */
+ switch (rc) {
+ case GSK_OK:
+ case GSK_OS400_ASYNCHRONOUS_SOC_INIT:
+ return CURLE_OK;
+ case GSK_KEYRING_OPEN_ERROR:
+ case GSK_OS400_ERROR_NO_ACCESS:
+ return CURLE_SSL_CACERT_BADFILE;
+ case GSK_INSUFFICIENT_STORAGE:
+ return CURLE_OUT_OF_MEMORY;
+ case GSK_ERROR_BAD_V2_CIPHER:
+ case GSK_ERROR_BAD_V3_CIPHER:
+ case GSK_ERROR_NO_CIPHERS:
+ return CURLE_SSL_CIPHER;
+ case GSK_OS400_ERROR_NOT_TRUSTED_ROOT:
+ case GSK_ERROR_CERT_VALIDATION:
+ return CURLE_PEER_FAILED_VERIFICATION;
+ case GSK_OS400_ERROR_TIMED_OUT:
+ return CURLE_OPERATION_TIMEDOUT;
+ case GSK_WOULD_BLOCK:
+ return CURLE_AGAIN;
+ case GSK_OS400_ERROR_NOT_REGISTERED:
+ break;
+ case GSK_ERROR_IO:
+ switch (errno) {
+ case ENOMEM:
+ return CURLE_OUT_OF_MEMORY;
+ default:
+ failf(data, "%s I/O error: %s", procname, strerror(errno));
+ break;
+ }
+ break;
+ default:
+ failf(data, "%s: %s", procname, gsk_strerror(rc));
+ break;
+ }
+ return defcode;
+}
+
+
+static CURLcode set_enum(struct SessionHandle *data, gsk_handle h,
+ GSK_ENUM_ID id, GSK_ENUM_VALUE value, bool unsupported_ok)
+{
+ int rc = gsk_attribute_set_enum(h, id, value);
+
+ switch (rc) {
+ case GSK_OK:
+ return CURLE_OK;
+ case GSK_ERROR_IO:
+ failf(data, "gsk_attribute_set_enum() I/O error: %s", strerror(errno));
+ break;
+ case GSK_ATTRIBUTE_INVALID_ID:
+ if(unsupported_ok)
+ return CURLE_UNSUPPORTED_PROTOCOL;
+ default:
+ failf(data, "gsk_attribute_set_enum(): %s", gsk_strerror(rc));
+ break;
+ }
+ return CURLE_SSL_CONNECT_ERROR;
+}
+
+
+static CURLcode set_buffer(struct SessionHandle *data, gsk_handle h,
+ GSK_BUF_ID id, const char *buffer, bool unsupported_ok)
+{
+ int rc = gsk_attribute_set_buffer(h, id, buffer, 0);
+
+ switch (rc) {
+ case GSK_OK:
+ return CURLE_OK;
+ case GSK_ERROR_IO:
+ failf(data, "gsk_attribute_set_buffer() I/O error: %s", strerror(errno));
+ break;
+ case GSK_ATTRIBUTE_INVALID_ID:
+ if(unsupported_ok)
+ return CURLE_UNSUPPORTED_PROTOCOL;
+ default:
+ failf(data, "gsk_attribute_set_buffer(): %s", gsk_strerror(rc));
+ break;
+ }
+ return CURLE_SSL_CONNECT_ERROR;
+}
+
+
+static CURLcode set_numeric(struct SessionHandle *data,
+ gsk_handle h, GSK_NUM_ID id, int value)
+{
+ int rc = gsk_attribute_set_numeric_value(h, id, value);
+
+ switch (rc) {
+ case GSK_OK:
+ return CURLE_OK;
+ case GSK_ERROR_IO:
+ failf(data, "gsk_attribute_set_numeric_value() I/O error: %s",
+ strerror(errno));
+ break;
+ default:
+ failf(data, "gsk_attribute_set_numeric_value(): %s", gsk_strerror(rc));
+ break;
+ }
+ return CURLE_SSL_CONNECT_ERROR;
+}
+
+
+static CURLcode set_callback(struct SessionHandle *data,
+ gsk_handle h, GSK_CALLBACK_ID id, void *info)
+{
+ int rc = gsk_attribute_set_callback(h, id, info);
+
+ switch (rc) {
+ case GSK_OK:
+ return CURLE_OK;
+ case GSK_ERROR_IO:
+ failf(data, "gsk_attribute_set_callback() I/O error: %s", strerror(errno));
+ break;
+ default:
+ failf(data, "gsk_attribute_set_callback(): %s", gsk_strerror(rc));
+ break;
+ }
+ return CURLE_SSL_CONNECT_ERROR;
+}
+
+
+static CURLcode set_ciphers(struct SessionHandle *data,
+ gsk_handle h, unsigned int *protoflags)
+{
+ const char *cipherlist = data->set.str[STRING_SSL_CIPHER_LIST];
+ const char *clp;
+ const gskit_cipher *ctp;
+ int i;
+ int l;
+ bool unsupported;
+ CURLcode result;
+ struct {
+ char *buf;
+ char *ptr;
+ } ciphers[CURL_GSKPROTO_LAST];
+
+ /* Compile cipher list into GSKit-compatible cipher lists. */
+
+ if(!cipherlist)
+ return CURLE_OK;
+ while(is_separator(*cipherlist)) /* Skip initial separators. */
+ cipherlist++;
+ if(!*cipherlist)
+ return CURLE_OK;
+
+ /* We allocate GSKit buffers of the same size as the input string: since
+ GSKit tokens are always shorter than their cipher names, allocated buffers
+ will always be large enough to accomodate the result. */
+ l = strlen(cipherlist) + 1;
+ memset((char *) ciphers, 0, sizeof ciphers);
+ for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
+ ciphers[i].buf = malloc(l);
+ if(!ciphers[i].buf) {
+ while(i--)
+ free(ciphers[i].buf);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ ciphers[i].ptr = ciphers[i].buf;
+ *ciphers[i].ptr = '\0';
+ }
+
+ /* Process each cipher in input string. */
+ unsupported = FALSE;
+ result = CURLE_OK;
+ for(;;) {
+ for(clp = cipherlist; *cipherlist && !is_separator(*cipherlist);)
+ cipherlist++;
+ l = cipherlist - clp;
+ if(!l)
+ break;
+ /* Search the cipher in our table. */
+ for(ctp = ciphertable; ctp->name; ctp++)
+ if(strnequal(ctp->name, clp, l) && !ctp->name[l])
+ break;
+ if(!ctp->name) {
+ failf(data, "Unknown cipher %.*s", l, clp);
+ result = CURLE_SSL_CIPHER;
+ }
+ else {
+ unsupported |= !(ctp->versions & (CURL_GSKPROTO_SSLV2_MASK |
+ CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK));
+ for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
+ if(ctp->versions & (1 << i)) {
+ strcpy(ciphers[i].ptr, ctp->gsktoken);
+ ciphers[i].ptr += strlen(ctp->gsktoken);
+ }
+ }
+ }
+
+ /* Advance to next cipher name or end of string. */
+ while(is_separator(*cipherlist))
+ cipherlist++;
+ }
+
+ /* Disable protocols with empty cipher lists. */
+ for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
+ if(!(*protoflags & (1 << i)) || !ciphers[i].buf[0]) {
+ *protoflags &= ~(1 << i);
+ ciphers[i].buf[0] = '\0';
+ }
+ }
+
+ /* Try to set-up TLSv1.1 and TLSv2.1 ciphers. */
+ if(*protoflags & CURL_GSKPROTO_TLSV11_MASK) {
+ result = set_buffer(data, h, GSK_TLSV11_CIPHER_SPECS,
+ ciphers[CURL_GSKPROTO_TLSV11].buf, TRUE);
+ if(result == CURLE_UNSUPPORTED_PROTOCOL) {
+ result = CURLE_OK;
+ if(unsupported) {
+ failf(data, "TLSv1.1-only ciphers are not yet supported");
+ result = CURLE_SSL_CIPHER;
+ }
+ }
+ }
+ if(!result && (*protoflags & CURL_GSKPROTO_TLSV12_MASK)) {
+ result = set_buffer(data, h, GSK_TLSV12_CIPHER_SPECS,
+ ciphers[CURL_GSKPROTO_TLSV12].buf, TRUE);
+ if(result == CURLE_UNSUPPORTED_PROTOCOL) {
+ result = CURLE_OK;
+ if(unsupported) {
+ failf(data, "TLSv1.2-only ciphers are not yet supported");
+ result = CURLE_SSL_CIPHER;
+ }
+ }
+ }
+
+ /* Try to set-up TLSv1.0 ciphers. If not successful, concatenate them to
+ the SSLv3 ciphers. OS/400 prior to version 7.1 will understand it. */
+ if(!result && (*protoflags & CURL_GSKPROTO_TLSV10_MASK)) {
+ result = set_buffer(data, h, GSK_TLSV10_CIPHER_SPECS,
+ ciphers[CURL_GSKPROTO_TLSV10].buf, TRUE);
+ if(result == CURLE_UNSUPPORTED_PROTOCOL) {
+ result = CURLE_OK;
+ strcpy(ciphers[CURL_GSKPROTO_SSLV3].ptr,
+ ciphers[CURL_GSKPROTO_TLSV10].ptr);
+ }
+ }
+
+ /* Set-up other ciphers. */
+ if(!result && (*protoflags & CURL_GSKPROTO_SSLV3_MASK))
+ result = set_buffer(data, h, GSK_V3_CIPHER_SPECS,
+ ciphers[CURL_GSKPROTO_SSLV3].buf, FALSE);
+ if(!result && (*protoflags & CURL_GSKPROTO_SSLV2_MASK))
+ result = set_buffer(data, h, GSK_V2_CIPHER_SPECS,
+ ciphers[CURL_GSKPROTO_SSLV2].buf, FALSE);
+
+ /* Clean-up. */
+ for(i = 0; i < CURL_GSKPROTO_LAST; i++)
+ free(ciphers[i].buf);
+
+ return result;
+}
+
+
+int Curl_gskit_init(void)
+{
+ /* No initialisation needed. */
+
+ return 1;
+}
+
+
+void Curl_gskit_cleanup(void)
+{
+ /* Nothing to do. */
+}
+
+
+static CURLcode init_environment(struct SessionHandle *data,
+ gsk_handle *envir, const char *appid,
+ const char *file, const char *label,
+ const char *password)
+{
+ int rc;
+ CURLcode result;
+ gsk_handle h;
+
+ /* Creates the GSKit environment. */
+
+ rc = gsk_environment_open(&h);
+ switch (rc) {
+ case GSK_OK:
+ break;
+ case GSK_INSUFFICIENT_STORAGE:
+ return CURLE_OUT_OF_MEMORY;
+ default:
+ failf(data, "gsk_environment_open(): %s", gsk_strerror(rc));
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
+ result = set_enum(data, h, GSK_SESSION_TYPE, GSK_CLIENT_SESSION, FALSE);
+ if(!result && appid)
+ result = set_buffer(data, h, GSK_OS400_APPLICATION_ID, appid, FALSE);
+ if(!result && file)
+ result = set_buffer(data, h, GSK_KEYRING_FILE, file, FALSE);
+ if(!result && label)
+ result = set_buffer(data, h, GSK_KEYRING_LABEL, label, FALSE);
+ if(!result && password)
+ result = set_buffer(data, h, GSK_KEYRING_PW, password, FALSE);
+
+ if(!result) {
+ /* Locate CAs, Client certificate and key according to our settings.
+ Note: this call may be blocking for some tenths of seconds. */
+ result = gskit_status(data, gsk_environment_init(h),
+ "gsk_environment_init()", CURLE_SSL_CERTPROBLEM);
+ if(!result) {
+ *envir = h;
+ return result;
+ }
+ }
+ /* Error: rollback. */
+ gsk_environment_close(&h);
+ return result;
+}
+
+
+static void cancel_async_handshake(struct connectdata *conn, int sockindex)
+{
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ Qso_OverlappedIO_t cstat;
+
+ if(QsoCancelOperation(conn->sock[sockindex], 0) > 0)
+ QsoWaitForIOCompletion(connssl->iocport, &cstat, (struct timeval *) NULL);
+}
+
+
+static void close_async_handshake(struct ssl_connect_data *connssl)
+{
+ QsoDestroyIOCompletionPort(connssl->iocport);
+ connssl->iocport = -1;
+}
+
+
+static void close_one(struct ssl_connect_data *conn,
+ struct SessionHandle *data)
+{
+ if(conn->handle) {
+ gskit_status(data, gsk_secure_soc_close(&conn->handle),
+ "gsk_secure_soc_close()", 0);
+ conn->handle = (gsk_handle) NULL;
+ }
+ if(conn->iocport >= 0)
+ close_async_handshake(conn);
+}
+
+
+static ssize_t gskit_send(struct connectdata *conn, int sockindex,
+ const void *mem, size_t len, CURLcode *curlcode)
+{
+ struct SessionHandle *data = conn->data;
+ CURLcode cc;
+ int written;
+
+ cc = gskit_status(data,
+ gsk_secure_soc_write(conn->ssl[sockindex].handle,
+ (char *) mem, (int) len, &written),
+ "gsk_secure_soc_write()", CURLE_SEND_ERROR);
+ if(cc != CURLE_OK) {
+ *curlcode = cc;
+ written = -1;
+ }
+ return (ssize_t) written; /* number of bytes */
+}
+
+
+static ssize_t gskit_recv(struct connectdata *conn, int num, char *buf,
+ size_t buffersize, CURLcode *curlcode)
+{
+ struct SessionHandle *data = conn->data;
+ int buffsize;
+ int nread;
+ CURLcode cc;
+
+ buffsize = buffersize > (size_t) INT_MAX? INT_MAX: (int) buffersize;
+ cc = gskit_status(data, gsk_secure_soc_read(conn->ssl[num].handle,
+ buf, buffsize, &nread),
+ "gsk_secure_soc_read()", CURLE_RECV_ERROR);
+ if(cc != CURLE_OK) {
+ *curlcode = cc;
+ nread = -1;
+ }
+ return (ssize_t) nread;
+}
+
+
+static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
+{
+ struct SessionHandle *data = conn->data;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ gsk_handle envir;
+ CURLcode result;
+ int rc;
+ char *keyringfile;
+ char *keyringpwd;
+ char *keyringlabel;
+ char *sni;
+ unsigned int protoflags;
+ long timeout;
+ Qso_OverlappedIO_t commarea;
+
+ /* Create SSL environment, start (preferably asynchronous) handshake. */
+
+ connssl->handle = (gsk_handle) NULL;
+ connssl->iocport = -1;
+
+ /* GSKit supports two ways of specifying an SSL context: either by
+ * application identifier (that should have been defined at the system
+ * level) or by keyring file, password and certificate label.
+ * Local certificate name (CURLOPT_SSLCERT) is used to hold either the
+ * application identifier of the certificate label.
+ * Key password (CURLOPT_KEYPASSWD) holds the keyring password.
+ * It is not possible to have different keyrings for the CAs and the
+ * local certificate. We thus use the CA file (CURLOPT_CAINFO) to identify
+ * the keyring file.
+ * If no key password is given and the keyring is the system keyring,
+ * application identifier mode is tried first, as recommended in IBM doc.
+ */
+
+ keyringfile = data->set.str[STRING_SSL_CAFILE];
+ keyringpwd = data->set.str[STRING_KEY_PASSWD];
+ keyringlabel = data->set.str[STRING_CERT];
+ envir = (gsk_handle) NULL;
+
+ if(keyringlabel && *keyringlabel && !keyringpwd &&
+ !strcmp(keyringfile, CURL_CA_BUNDLE)) {
+ /* Try application identifier mode. */
+ init_environment(data, &envir, keyringlabel, (const char *) NULL,
+ (const char *) NULL, (const char *) NULL);
+ }
+
+ if(!envir) {
+ /* Use keyring mode. */
+ result = init_environment(data, &envir, (const char *) NULL,
+ keyringfile, keyringlabel, keyringpwd);
+ if(result)
+ return result;
+ }
+
+ /* Create secure session. */
+ result = gskit_status(data, gsk_secure_soc_open(envir, &connssl->handle),
+ "gsk_secure_soc_open()", CURLE_SSL_CONNECT_ERROR);
+ gsk_environment_close(&envir);
+ if(result)
+ return result;
+
+ /* Determine which SSL/TLS version should be enabled. */
+ protoflags = CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK |
+ CURL_GSKPROTO_TLSV12_MASK;
+ sni = conn->host.name;
+ switch (data->set.ssl.version) {
+ case CURL_SSLVERSION_SSLv2:
+ protoflags = CURL_GSKPROTO_SSLV2_MASK;
+ sni = (char *) NULL;
+ break;
+ case CURL_SSLVERSION_SSLv3:
+ protoflags = CURL_GSKPROTO_SSLV3_MASK;
+ sni = (char *) NULL;
+ break;
+ case CURL_SSLVERSION_TLSv1:
+ protoflags = CURL_GSKPROTO_TLSV10_MASK |
+ CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK;
+ break;
+ case CURL_SSLVERSION_TLSv1_0:
+ protoflags = CURL_GSKPROTO_TLSV10_MASK;
+ break;
+ case CURL_SSLVERSION_TLSv1_1:
+ protoflags = CURL_GSKPROTO_TLSV11_MASK;
+ break;
+ case CURL_SSLVERSION_TLSv1_2:
+ protoflags = CURL_GSKPROTO_TLSV12_MASK;
+ break;
+ }
+
+ /* Process SNI. Ignore if not supported (on OS400 < V7R1). */
+ if(sni) {
+ result = set_buffer(data, connssl->handle,
+ GSK_SSL_EXTN_SERVERNAME_REQUEST, sni, TRUE);
+ if(result == CURLE_UNSUPPORTED_PROTOCOL)
+ result = CURLE_OK;
+ }
+
+ /* Set session parameters. */
+ if(!result) {
+ /* Compute the handshake timeout. Since GSKit granularity is 1 second,
+ we round up the required value. */
+ timeout = Curl_timeleft(data, NULL, TRUE);
+ if(timeout < 0)
+ result = CURLE_OPERATION_TIMEDOUT;
+ else
+ result = set_numeric(data, connssl->handle, GSK_HANDSHAKE_TIMEOUT,
+ (timeout + 999) / 1000);
+ }
+ if(!result)
+ result = set_numeric(data, connssl->handle, GSK_FD, conn->sock[sockindex]);
+ if(!result)
+ result = set_ciphers(data, connssl->handle, &protoflags);
+ if(!protoflags) {
+ failf(data, "No SSL protocol/cipher combination enabled");
+ result = CURLE_SSL_CIPHER;
+ }
+ if(!result)
+ result = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV2,
+ (protoflags & CURL_GSKPROTO_SSLV2_MASK)?
+ GSK_PROTOCOL_SSLV2_ON: GSK_PROTOCOL_SSLV2_OFF, FALSE);
+ if(!result)
+ result = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV3,
+ (protoflags & CURL_GSKPROTO_SSLV3_MASK)?
+ GSK_PROTOCOL_SSLV3_ON: GSK_PROTOCOL_SSLV3_OFF, FALSE);
+ if(!result)
+ result = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV1,
+ (protoflags & CURL_GSKPROTO_TLSV10_MASK)?
+ GSK_PROTOCOL_TLSV1_ON: GSK_PROTOCOL_TLSV1_OFF, FALSE);
+ if(!result) {
+ result = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV11,
+ (protoflags & CURL_GSKPROTO_TLSV11_MASK)?
+ GSK_TRUE: GSK_FALSE, TRUE);
+ if(result == CURLE_UNSUPPORTED_PROTOCOL) {
+ result = CURLE_OK;
+ if(protoflags == CURL_GSKPROTO_TLSV11_MASK) {
+ failf(data, "TLS 1.1 not yet supported");
+ result = CURLE_SSL_CIPHER;
+ }
+ }
+ }
+ if(!result) {
+ result = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV12,
+ (protoflags & CURL_GSKPROTO_TLSV12_MASK)?
+ GSK_TRUE: GSK_FALSE, TRUE);
+ if(result == CURLE_UNSUPPORTED_PROTOCOL) {
+ result = CURLE_OK;
+ if(protoflags == CURL_GSKPROTO_TLSV12_MASK) {
+ failf(data, "TLS 1.2 not yet supported");
+ result = CURLE_SSL_CIPHER;
+ }
+ }
+ }
+ if(!result)
+ result = set_enum(data, connssl->handle, GSK_SERVER_AUTH_TYPE,
+ data->set.ssl.verifypeer? GSK_SERVER_AUTH_FULL:
+ GSK_SERVER_AUTH_PASSTHRU, FALSE);
+
+ if(!result) {
+ /* Start handshake. Try asynchronous first. */
+ memset(&commarea, 0, sizeof commarea);
+ connssl->iocport = QsoCreateIOCompletionPort();
+ if(connssl->iocport != -1) {
+ result = gskit_status(data,
+ gsk_secure_soc_startInit(connssl->handle,
+ connssl->iocport,
+ &commarea),
+ "gsk_secure_soc_startInit()",
+ CURLE_SSL_CONNECT_ERROR);
+ if(!result) {
+ connssl->connecting_state = ssl_connect_2;
+ return CURLE_OK;
+ }
+ else
+ close_async_handshake(connssl);
+ }
+ else if(errno != ENOBUFS)
+ result = gskit_status(data, GSK_ERROR_IO,
+ "QsoCreateIOCompletionPort()", 0);
+ else {
+ /* No more completion port available. Use synchronous IO. */
+ result = gskit_status(data, gsk_secure_soc_init(connssl->handle),
+ "gsk_secure_soc_init()", CURLE_SSL_CONNECT_ERROR);
+ if(!result) {
+ connssl->connecting_state = ssl_connect_3;
+ return CURLE_OK;
+ }
+ }
+ }
+
+ /* Error: rollback. */
+ close_one(connssl, data);
+ return result;
+}
+
+
+static CURLcode gskit_connect_step2(struct connectdata *conn, int sockindex,
+ bool nonblocking)
+{
+ struct SessionHandle *data = conn->data;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ Qso_OverlappedIO_t cstat;
+ long timeout_ms;
+ struct timeval stmv;
+ CURLcode result;
+
+ /* Poll or wait for end of SSL asynchronous handshake. */
+
+ for(;;) {
+ timeout_ms = nonblocking? 0: Curl_timeleft(data, NULL, TRUE);
+ if(timeout_ms < 0)
+ timeout_ms = 0;
+ stmv.tv_sec = timeout_ms / 1000;
+ stmv.tv_usec = (timeout_ms - stmv.tv_sec * 1000) * 1000;
+ switch (QsoWaitForIOCompletion(connssl->iocport, &cstat, &stmv)) {
+ case 1: /* Operation complete. */
+ break;
+ case -1: /* An error occurred: handshake still in progress. */
+ if(errno == EINTR) {
+ if(nonblocking)
+ return CURLE_OK;
+ continue; /* Retry. */
+ }
+ if(errno != ETIME) {
+ failf(data, "QsoWaitForIOCompletion() I/O error: %s", strerror(errno));
+ cancel_async_handshake(conn, sockindex);
+ close_async_handshake(connssl);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ /* FALL INTO... */
+ case 0: /* Handshake in progress, timeout occurred. */
+ if(nonblocking)
+ return CURLE_OK;
+ cancel_async_handshake(conn, sockindex);
+ close_async_handshake(connssl);
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+ break;
+ }
+ result = gskit_status(data, cstat.returnValue, "SSL handshake",
+ CURLE_SSL_CONNECT_ERROR);
+ if(!result)
+ connssl->connecting_state = ssl_connect_3;
+ close_async_handshake(connssl);
+ return result;
+}
+
+
+static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex)
+{
+ struct SessionHandle *data = conn->data;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ const gsk_cert_data_elem *cdev;
+ int cdec;
+ const gsk_cert_data_elem *p;
+ const char *cert = (const char *) NULL;
+ const char *certend;
+ const char *ptr;
+ int i;
+ CURLcode result;
+
+ /* SSL handshake done: gather certificate info and verify host. */
+
+ if(gskit_status(data, gsk_attribute_get_cert_info(connssl->handle,
+ GSK_PARTNER_CERT_INFO,
+ &cdev, &cdec),
+ "gsk_attribute_get_cert_info()", CURLE_SSL_CONNECT_ERROR) ==
+ CURLE_OK) {
+ infof(data, "Server certificate:\n");
+ p = cdev;
+ for(i = 0; i++ < cdec; p++)
+ switch (p->cert_data_id) {
+ case CERT_BODY_DER:
+ cert = p->cert_data_p;
+ certend = cert + cdev->cert_data_l;
+ break;
+ case CERT_DN_PRINTABLE:
+ infof(data, "\t subject: %.*s\n", p->cert_data_l, p->cert_data_p);
+ break;
+ case CERT_ISSUER_DN_PRINTABLE:
+ infof(data, "\t issuer: %.*s\n", p->cert_data_l, p->cert_data_p);
+ break;
+ case CERT_VALID_FROM:
+ infof(data, "\t start date: %.*s\n", p->cert_data_l, p->cert_data_p);
+ break;
+ case CERT_VALID_TO:
+ infof(data, "\t expire date: %.*s\n", p->cert_data_l, p->cert_data_p);
+ break;
+ }
+ }
+
+ /* Verify host. */
+ result = Curl_verifyhost(conn, cert, certend);
+ if(result)
+ return result;
+
+ /* The only place GSKit can get the whole CA chain is a validation
+ callback where no user data pointer is available. Therefore it's not
+ possible to copy this chain into our structures for CAINFO.
+ However the server certificate may be available, thus we can return
+ info about it. */
+ if(data->set.ssl.certinfo) {
+ result = Curl_ssl_init_certinfo(data, 1);
+ if(result)
+ return result;
+
+ if(cert) {
+ result = Curl_extract_certinfo(conn, 0, cert, certend);
+ if(result)
+ return result;
+ }
+ }
+
+ /* Check pinned public key. */
+ ptr = data->set.str[STRING_SSL_PINNEDPUBLICKEY];
+ if(!result && ptr) {
+ curl_X509certificate x509;
+ curl_asn1Element *p;
+
+ if(!cert)
+ return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+ Curl_parseX509(&x509, cert, certend);
+ p = &x509.subjectPublicKeyInfo;
+ result = Curl_pin_peer_pubkey(ptr, p->header, p->end - p->header);
+ if(result) {
+ failf(data, "SSL: public key does not match pinned public key!");
+ return result;
+ }
+ }
+
+ connssl->connecting_state = ssl_connect_done;
+ return CURLE_OK;
+}
+
+
+static CURLcode gskit_connect_common(struct connectdata *conn, int sockindex,
+ bool nonblocking, bool *done)
+{
+ struct SessionHandle *data = conn->data;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ long timeout_ms;
+ Qso_OverlappedIO_t cstat;
+ CURLcode result = CURLE_OK;
+
+ *done = connssl->state == ssl_connection_complete;
+ if(*done)
+ return CURLE_OK;
+
+ /* Step 1: create session, start handshake. */
+ if(connssl->connecting_state == ssl_connect_1) {
+ /* check allowed time left */
+ timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+ if(timeout_ms < 0) {
+ /* no need to continue if time already is up */
+ failf(data, "SSL connection timeout");
+ result = CURLE_OPERATION_TIMEDOUT;
+ }
+ else
+ result = gskit_connect_step1(conn, sockindex);
+ }
+
+ /* Step 2: check if handshake is over. */
+ if(!result && connssl->connecting_state == ssl_connect_2) {
+ /* check allowed time left */
+ timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+ if(timeout_ms < 0) {
+ /* no need to continue if time already is up */
+ failf(data, "SSL connection timeout");
+ result = CURLE_OPERATION_TIMEDOUT;
+ }
+ else
+ result = gskit_connect_step2(conn, sockindex, nonblocking);
+ }
+
+ /* Step 3: gather certificate info, verify host. */
+ if(!result && connssl->connecting_state == ssl_connect_3)
+ result = gskit_connect_step3(conn, sockindex);
+
+ if(result)
+ close_one(connssl, data);
+ else if(connssl->connecting_state == ssl_connect_done) {
+ connssl->state = ssl_connection_complete;
+ connssl->connecting_state = ssl_connect_1;
+ conn->recv[sockindex] = gskit_recv;
+ conn->send[sockindex] = gskit_send;
+ *done = TRUE;
+ }
+
+ return result;
+}
+
+
+CURLcode Curl_gskit_connect_nonblocking(struct connectdata *conn,
+ int sockindex,
+ bool *done)
+{
+ CURLcode result;
+
+ result = gskit_connect_common(conn, sockindex, TRUE, done);
+ if(*done || result)
+ conn->ssl[sockindex].connecting_state = ssl_connect_1;
+ return result;
+}
+
+
+CURLcode Curl_gskit_connect(struct connectdata *conn, int sockindex)
+{
+ CURLcode result;
+ bool done;
+
+ conn->ssl[sockindex].connecting_state = ssl_connect_1;
+ result = gskit_connect_common(conn, sockindex, FALSE, &done);
+ if(result)
+ return result;
+
+ DEBUGASSERT(done);
+
+ return CURLE_OK;
+}
+
+
+void Curl_gskit_close(struct connectdata *conn, int sockindex)
+{
+ struct SessionHandle *data = conn->data;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+ if(connssl->use)
+ close_one(connssl, data);
+}
+
+
+int Curl_gskit_shutdown(struct connectdata *conn, int sockindex)
+{
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct SessionHandle *data = conn->data;
+ ssize_t nread;
+ int what;
+ int rc;
+ char buf[120];
+
+ if(!connssl->handle)
+ return 0;
+
+ if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
+ return 0;
+
+ close_one(connssl, data);
+ rc = 0;
+ what = Curl_socket_ready(conn->sock[sockindex],
+ CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
+
+ for(;;) {
+ if(what < 0) {
+ /* anything that gets here is fatally bad */
+ failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+ rc = -1;
+ break;
+ }
+
+ if(!what) { /* timeout */
+ failf(data, "SSL shutdown timeout");
+ break;
+ }
+
+ /* Something to read, let's do it and hope that it is the close
+ notify alert from the server. No way to gsk_secure_soc_read() now, so
+ use read(). */
+
+ nread = read(conn->sock[sockindex], buf, sizeof(buf));
+
+ if(nread < 0) {
+ failf(data, "read: %s", strerror(errno));
+ rc = -1;
+ }
+
+ if(nread <= 0)
+ break;
+
+ what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, 0);
+ }
+
+ return rc;
+}
+
+
+size_t Curl_gskit_version(char *buffer, size_t size)
+{
+ strncpy(buffer, "GSKit", size);
+ return strlen(buffer);
+}
+
+
+int Curl_gskit_check_cxn(struct connectdata *cxn)
+{
+ int err;
+ int errlen;
+
+ /* The only thing that can be tested here is at the socket level. */
+
+ if(!cxn->ssl[FIRSTSOCKET].handle)
+ return 0; /* connection has been closed */
+
+ err = 0;
+ errlen = sizeof err;
+
+ if(getsockopt(cxn->sock[FIRSTSOCKET], SOL_SOCKET, SO_ERROR,
+ (unsigned char *) &err, &errlen) ||
+ errlen != sizeof err || err)
+ return 0; /* connection has been closed */
+
+ return -1; /* connection status unknown */
+}
+
+#endif /* USE_GSKIT */
diff --git a/Utilities/cmcurl/lib/vtls/gskit.h b/Utilities/cmcurl/lib/vtls/gskit.h
new file mode 100644
index 000000000..af31fafad
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/gskit.h
@@ -0,0 +1,71 @@
+#ifndef HEADER_CURL_GSKIT_H
+#define HEADER_CURL_GSKIT_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+/*
+ * This header should only be needed to get included by vtls.c and gskit.c
+ */
+
+#include "urldata.h"
+
+#ifdef USE_GSKIT
+int Curl_gskit_init(void);
+void Curl_gskit_cleanup(void);
+CURLcode Curl_gskit_connect(struct connectdata *conn, int sockindex);
+CURLcode Curl_gskit_connect_nonblocking(struct connectdata *conn,
+ int sockindex, bool *done);
+void Curl_gskit_close(struct connectdata *conn, int sockindex);
+int Curl_gskit_shutdown(struct connectdata *conn, int sockindex);
+
+size_t Curl_gskit_version(char *buffer, size_t size);
+int Curl_gskit_check_cxn(struct connectdata *cxn);
+
+/* Set the API backend definition to GSKit */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_GSKIT
+
+/* this backend supports CURLOPT_CERTINFO */
+#define have_curlssl_certinfo 1
+
+/* API setup for GSKit */
+#define curlssl_init Curl_gskit_init
+#define curlssl_cleanup Curl_gskit_cleanup
+#define curlssl_connect Curl_gskit_connect
+#define curlssl_connect_nonblocking Curl_gskit_connect_nonblocking
+
+/* No session handling for GSKit */
+#define curlssl_session_free(x) Curl_nop_stmt
+#define curlssl_close_all(x) ((void)x)
+#define curlssl_close Curl_gskit_close
+#define curlssl_shutdown(x,y) Curl_gskit_shutdown(x,y)
+#define curlssl_set_engine(x,y) CURLE_NOT_BUILT_IN
+#define curlssl_set_engine_default(x) CURLE_NOT_BUILT_IN
+#define curlssl_engines_list(x) NULL
+#define curlssl_version Curl_gskit_version
+#define curlssl_check_cxn(x) Curl_gskit_check_cxn(x)
+#define curlssl_data_pending(x,y) 0
+#define curlssl_random(x,y,z) -1
+
+#endif /* USE_GSKIT */
+
+#endif /* HEADER_CURL_GSKIT_H */
diff --git a/Utilities/cmcurl/lib/vtls/gtls.c b/Utilities/cmcurl/lib/vtls/gtls.c
new file mode 100644
index 000000000..c54dfc1d2
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/gtls.c
@@ -0,0 +1,1589 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all GnuTLS-specific code for the TLS/SSL layer. No code
+ * but vtls.c should ever call or use these functions.
+ *
+ * Note: don't use the GnuTLS' *_t variable type names in this source code,
+ * since they were not present in 1.0.X.
+ */
+
+#include "curl_setup.h"
+
+#ifdef USE_GNUTLS
+
+#include <gnutls/abstract.h>
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+
+#ifdef USE_GNUTLS_NETTLE
+#include <gnutls/crypto.h>
+#include <nettle/md5.h>
+#include <nettle/sha2.h>
+#else
+#include <gcrypt.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "inet_pton.h"
+#include "gtls.h"
+#include "vtls.h"
+#include "parsedate.h"
+#include "connect.h" /* for the connect timeout */
+#include "select.h"
+#include "rawstr.h"
+#include "warnless.h"
+#include "x509asn1.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ Some hackish cast macros based on:
+ http://library.gnome.org/devel/glib/unstable/glib-Type-Conversion-Macros.html
+*/
+#ifndef GNUTLS_POINTER_TO_INT_CAST
+#define GNUTLS_POINTER_TO_INT_CAST(p) ((int) (long) (p))
+#endif
+#ifndef GNUTLS_INT_TO_POINTER_CAST
+#define GNUTLS_INT_TO_POINTER_CAST(i) ((void*) (long) (i))
+#endif
+
+/* Enable GnuTLS debugging by defining GTLSDEBUG */
+/*#define GTLSDEBUG */
+
+#ifdef GTLSDEBUG
+static void tls_log_func(int level, const char *str)
+{
+ fprintf(stderr, "|<%d>| %s", level, str);
+}
+#endif
+static bool gtls_inited = FALSE;
+
+#if defined(GNUTLS_VERSION_NUMBER)
+# if (GNUTLS_VERSION_NUMBER >= 0x020c00)
+# undef gnutls_transport_set_lowat
+# define gnutls_transport_set_lowat(A,B) Curl_nop_stmt
+# define USE_GNUTLS_PRIORITY_SET_DIRECT 1
+# endif
+# if (GNUTLS_VERSION_NUMBER >= 0x020c03)
+# define GNUTLS_MAPS_WINSOCK_ERRORS 1
+# endif
+
+# if (GNUTLS_VERSION_NUMBER >= 0x030200)
+# define HAS_ALPN
+# endif
+
+# if (GNUTLS_VERSION_NUMBER >= 0x03020d)
+# define HAS_OCSP
+# endif
+
+# if (GNUTLS_VERSION_NUMBER >= 0x030306)
+# define HAS_CAPATH
+# endif
+#endif
+
+#ifdef HAS_OCSP
+# include <gnutls/ocsp.h>
+#endif
+
+/*
+ * Custom push and pull callback functions used by GNU TLS to read and write
+ * to the socket. These functions are simple wrappers to send() and recv()
+ * (although here using the sread/swrite macros as defined by
+ * curl_setup_once.h).
+ * We use custom functions rather than the GNU TLS defaults because it allows
+ * us to get specific about the fourth "flags" argument, and to use arbitrary
+ * private data with gnutls_transport_set_ptr if we wish.
+ *
+ * When these custom push and pull callbacks fail, GNU TLS checks its own
+ * session-specific error variable, and when not set also its own global
+ * errno variable, in order to take appropriate action. GNU TLS does not
+ * require that the transport is actually a socket. This implies that for
+ * Windows builds these callbacks should ideally set the session-specific
+ * error variable using function gnutls_transport_set_errno or as a last
+ * resort global errno variable using gnutls_transport_set_global_errno,
+ * with a transport agnostic error value. This implies that some winsock
+ * error translation must take place in these callbacks.
+ *
+ * Paragraph above applies to GNU TLS versions older than 2.12.3, since
+ * this version GNU TLS does its own internal winsock error translation
+ * using system_errno() function.
+ */
+
+#if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS)
+# define gtls_EINTR 4
+# define gtls_EIO 5
+# define gtls_EAGAIN 11
+static int gtls_mapped_sockerrno(void)
+{
+ switch(SOCKERRNO) {
+ case WSAEWOULDBLOCK:
+ return gtls_EAGAIN;
+ case WSAEINTR:
+ return gtls_EINTR;
+ default:
+ break;
+ }
+ return gtls_EIO;
+}
+#endif
+
+static ssize_t Curl_gtls_push(void *s, const void *buf, size_t len)
+{
+ ssize_t ret = swrite(GNUTLS_POINTER_TO_INT_CAST(s), buf, len);
+#if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS)
+ if(ret < 0)
+ gnutls_transport_set_global_errno(gtls_mapped_sockerrno());
+#endif
+ return ret;
+}
+
+static ssize_t Curl_gtls_pull(void *s, void *buf, size_t len)
+{
+ ssize_t ret = sread(GNUTLS_POINTER_TO_INT_CAST(s), buf, len);
+#if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS)
+ if(ret < 0)
+ gnutls_transport_set_global_errno(gtls_mapped_sockerrno());
+#endif
+ return ret;
+}
+
+/* Curl_gtls_init()
+ *
+ * Global GnuTLS init, called from Curl_ssl_init(). This calls functions that
+ * are not thread-safe and thus this function itself is not thread-safe and
+ * must only be called from within curl_global_init() to keep the thread
+ * situation under control!
+ */
+int Curl_gtls_init(void)
+{
+ int ret = 1;
+ if(!gtls_inited) {
+ ret = gnutls_global_init()?0:1;
+#ifdef GTLSDEBUG
+ gnutls_global_set_log_function(tls_log_func);
+ gnutls_global_set_log_level(2);
+#endif
+ gtls_inited = TRUE;
+ }
+ return ret;
+}
+
+int Curl_gtls_cleanup(void)
+{
+ if(gtls_inited) {
+ gnutls_global_deinit();
+ gtls_inited = FALSE;
+ }
+ return 1;
+}
+
+static void showtime(struct SessionHandle *data,
+ const char *text,
+ time_t stamp)
+{
+ struct tm buffer;
+ const struct tm *tm = &buffer;
+ CURLcode result = Curl_gmtime(stamp, &buffer);
+ if(result)
+ return;
+
+ snprintf(data->state.buffer,
+ BUFSIZE,
+ "\t %s: %s, %02d %s %4d %02d:%02d:%02d GMT",
+ text,
+ Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
+ tm->tm_mday,
+ Curl_month[tm->tm_mon],
+ tm->tm_year + 1900,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec);
+ infof(data, "%s\n", data->state.buffer);
+}
+
+static gnutls_datum_t load_file (const char *file)
+{
+ FILE *f;
+ gnutls_datum_t loaded_file = { NULL, 0 };
+ long filelen;
+ void *ptr;
+
+ if(!(f = fopen(file, "rb")))
+ return loaded_file;
+ if(fseek(f, 0, SEEK_END) != 0
+ || (filelen = ftell(f)) < 0
+ || fseek(f, 0, SEEK_SET) != 0
+ || !(ptr = malloc((size_t)filelen)))
+ goto out;
+ if(fread(ptr, 1, (size_t)filelen, f) < (size_t)filelen) {
+ free(ptr);
+ goto out;
+ }
+
+ loaded_file.data = ptr;
+ loaded_file.size = (unsigned int)filelen;
+out:
+ fclose(f);
+ return loaded_file;
+}
+
+static void unload_file(gnutls_datum_t data) {
+ free(data.data);
+}
+
+
+/* this function does a SSL/TLS (re-)handshake */
+static CURLcode handshake(struct connectdata *conn,
+ int sockindex,
+ bool duringconnect,
+ bool nonblocking)
+{
+ struct SessionHandle *data = conn->data;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ gnutls_session_t session = conn->ssl[sockindex].session;
+ curl_socket_t sockfd = conn->sock[sockindex];
+ long timeout_ms;
+ int rc;
+ int what;
+
+ for(;;) {
+ /* check allowed time left */
+ timeout_ms = Curl_timeleft(data, NULL, duringconnect);
+
+ if(timeout_ms < 0) {
+ /* no need to continue if time already is up */
+ failf(data, "SSL connection timeout");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+
+ /* if ssl is expecting something, check if it's available. */
+ if(connssl->connecting_state == ssl_connect_2_reading
+ || connssl->connecting_state == ssl_connect_2_writing) {
+
+ curl_socket_t writefd = ssl_connect_2_writing==
+ connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+ curl_socket_t readfd = ssl_connect_2_reading==
+ connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+
+ what = Curl_socket_ready(readfd, writefd,
+ nonblocking?0:
+ timeout_ms?timeout_ms:1000);
+ if(what < 0) {
+ /* fatal error */
+ failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ else if(0 == what) {
+ if(nonblocking)
+ return CURLE_OK;
+ else if(timeout_ms) {
+ /* timeout */
+ failf(data, "SSL connection timeout at %ld", timeout_ms);
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+ }
+ /* socket is readable or writable */
+ }
+
+ rc = gnutls_handshake(session);
+
+ if((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED)) {
+ connssl->connecting_state =
+ gnutls_record_get_direction(session)?
+ ssl_connect_2_writing:ssl_connect_2_reading;
+ continue;
+ }
+ else if((rc < 0) && !gnutls_error_is_fatal(rc)) {
+ const char *strerr = NULL;
+
+ if(rc == GNUTLS_E_WARNING_ALERT_RECEIVED) {
+ int alert = gnutls_alert_get(session);
+ strerr = gnutls_alert_get_name(alert);
+ }
+
+ if(strerr == NULL)
+ strerr = gnutls_strerror(rc);
+
+ infof(data, "gnutls_handshake() warning: %s\n", strerr);
+ continue;
+ }
+ else if(rc < 0) {
+ const char *strerr = NULL;
+
+ if(rc == GNUTLS_E_FATAL_ALERT_RECEIVED) {
+ int alert = gnutls_alert_get(session);
+ strerr = gnutls_alert_get_name(alert);
+ }
+
+ if(strerr == NULL)
+ strerr = gnutls_strerror(rc);
+
+ failf(data, "gnutls_handshake() failed: %s", strerr);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
+ /* Reset our connect state machine */
+ connssl->connecting_state = ssl_connect_1;
+ return CURLE_OK;
+ }
+}
+
+static gnutls_x509_crt_fmt_t do_file_type(const char *type)
+{
+ if(!type || !type[0])
+ return GNUTLS_X509_FMT_PEM;
+ if(Curl_raw_equal(type, "PEM"))
+ return GNUTLS_X509_FMT_PEM;
+ if(Curl_raw_equal(type, "DER"))
+ return GNUTLS_X509_FMT_DER;
+ return -1;
+}
+
+static CURLcode
+gtls_connect_step1(struct connectdata *conn,
+ int sockindex)
+{
+ struct SessionHandle *data = conn->data;
+ gnutls_session_t session;
+ int rc;
+ void *ssl_sessionid;
+ size_t ssl_idsize;
+ bool sni = TRUE; /* default is SNI enabled */
+#ifdef ENABLE_IPV6
+ struct in6_addr addr;
+#else
+ struct in_addr addr;
+#endif
+#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
+ static const int cipher_priority[] = {
+ /* These two ciphers were added to GnuTLS as late as ver. 3.0.1,
+ but this code path is only ever used for ver. < 2.12.0.
+ GNUTLS_CIPHER_AES_128_GCM,
+ GNUTLS_CIPHER_AES_256_GCM,
+ */
+ GNUTLS_CIPHER_AES_128_CBC,
+ GNUTLS_CIPHER_AES_256_CBC,
+ GNUTLS_CIPHER_CAMELLIA_128_CBC,
+ GNUTLS_CIPHER_CAMELLIA_256_CBC,
+ GNUTLS_CIPHER_3DES_CBC,
+ };
+ static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
+ static int protocol_priority[] = { 0, 0, 0, 0 };
+#else
+#define GNUTLS_CIPHERS "NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509"
+/* If GnuTLS was compiled without support for SRP it will error out if SRP is
+ requested in the priority string, so treat it specially
+ */
+#define GNUTLS_SRP "+SRP"
+ const char* prioritylist;
+ const char *err = NULL;
+#endif
+
+ if(conn->ssl[sockindex].state == ssl_connection_complete)
+ /* to make us tolerant against being called more than once for the
+ same connection */
+ return CURLE_OK;
+
+ if(!gtls_inited)
+ Curl_gtls_init();
+
+ /* GnuTLS only supports SSLv3 and TLSv1 */
+ if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
+ failf(data, "GnuTLS does not support SSLv2");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ else if(data->set.ssl.version == CURL_SSLVERSION_SSLv3)
+ sni = FALSE; /* SSLv3 has no SNI */
+
+ /* allocate a cred struct */
+ rc = gnutls_certificate_allocate_credentials(&conn->ssl[sockindex].cred);
+ if(rc != GNUTLS_E_SUCCESS) {
+ failf(data, "gnutls_cert_all_cred() failed: %s", gnutls_strerror(rc));
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
+#ifdef USE_TLS_SRP
+ if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
+ infof(data, "Using TLS-SRP username: %s\n", data->set.ssl.username);
+
+ rc = gnutls_srp_allocate_client_credentials(
+ &conn->ssl[sockindex].srp_client_cred);
+ if(rc != GNUTLS_E_SUCCESS) {
+ failf(data, "gnutls_srp_allocate_client_cred() failed: %s",
+ gnutls_strerror(rc));
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ rc = gnutls_srp_set_client_credentials(conn->ssl[sockindex].
+ srp_client_cred,
+ data->set.ssl.username,
+ data->set.ssl.password);
+ if(rc != GNUTLS_E_SUCCESS) {
+ failf(data, "gnutls_srp_set_client_cred() failed: %s",
+ gnutls_strerror(rc));
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+ }
+#endif
+
+ if(data->set.ssl.CAfile) {
+ /* set the trusted CA cert bundle file */
+ gnutls_certificate_set_verify_flags(conn->ssl[sockindex].cred,
+ GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
+
+ rc = gnutls_certificate_set_x509_trust_file(conn->ssl[sockindex].cred,
+ data->set.ssl.CAfile,
+ GNUTLS_X509_FMT_PEM);
+ if(rc < 0) {
+ infof(data, "error reading ca cert file %s (%s)\n",
+ data->set.ssl.CAfile, gnutls_strerror(rc));
+ if(data->set.ssl.verifypeer)
+ return CURLE_SSL_CACERT_BADFILE;
+ }
+ else
+ infof(data, "found %d certificates in %s\n",
+ rc, data->set.ssl.CAfile);
+ }
+
+#ifdef HAS_CAPATH
+ if(data->set.ssl.CApath) {
+ /* set the trusted CA cert directory */
+ rc = gnutls_certificate_set_x509_trust_dir(conn->ssl[sockindex].cred,
+ data->set.ssl.CApath,
+ GNUTLS_X509_FMT_PEM);
+ if(rc < 0) {
+ infof(data, "error reading ca cert file %s (%s)\n",
+ data->set.ssl.CAfile, gnutls_strerror(rc));
+ if(data->set.ssl.verifypeer)
+ return CURLE_SSL_CACERT_BADFILE;
+ }
+ else
+ infof(data, "found %d certificates in %s\n",
+ rc, data->set.ssl.CApath);
+ }
+#endif
+
+ if(data->set.ssl.CRLfile) {
+ /* set the CRL list file */
+ rc = gnutls_certificate_set_x509_crl_file(conn->ssl[sockindex].cred,
+ data->set.ssl.CRLfile,
+ GNUTLS_X509_FMT_PEM);
+ if(rc < 0) {
+ failf(data, "error reading crl file %s (%s)",
+ data->set.ssl.CRLfile, gnutls_strerror(rc));
+ return CURLE_SSL_CRL_BADFILE;
+ }
+ else
+ infof(data, "found %d CRL in %s\n",
+ rc, data->set.ssl.CRLfile);
+ }
+
+ /* Initialize TLS session as a client */
+ rc = gnutls_init(&conn->ssl[sockindex].session, GNUTLS_CLIENT);
+ if(rc != GNUTLS_E_SUCCESS) {
+ failf(data, "gnutls_init() failed: %d", rc);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
+ /* convenient assign */
+ session = conn->ssl[sockindex].session;
+
+ if((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr)) &&
+#ifdef ENABLE_IPV6
+ (0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) &&
+#endif
+ sni &&
+ (gnutls_server_name_set(session, GNUTLS_NAME_DNS, conn->host.name,
+ strlen(conn->host.name)) < 0))
+ infof(data, "WARNING: failed to configure server name indication (SNI) "
+ "TLS extension\n");
+
+ /* Use default priorities */
+ rc = gnutls_set_default_priority(session);
+ if(rc != GNUTLS_E_SUCCESS)
+ return CURLE_SSL_CONNECT_ERROR;
+
+#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
+ rc = gnutls_cipher_set_priority(session, cipher_priority);
+ if(rc != GNUTLS_E_SUCCESS)
+ return CURLE_SSL_CONNECT_ERROR;
+
+ /* Sets the priority on the certificate types supported by gnutls. Priority
+ is higher for types specified before others. After specifying the types
+ you want, you must append a 0. */
+ rc = gnutls_certificate_type_set_priority(session, cert_type_priority);
+ if(rc != GNUTLS_E_SUCCESS)
+ return CURLE_SSL_CONNECT_ERROR;
+
+ if(data->set.ssl.cipher_list != NULL) {
+ failf(data, "can't pass a custom cipher list to older GnuTLS"
+ " versions");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
+ switch (data->set.ssl.version) {
+ case CURL_SSLVERSION_SSLv3:
+ protocol_priority[0] = GNUTLS_SSL3;
+ break;
+ case CURL_SSLVERSION_DEFAULT:
+ case CURL_SSLVERSION_TLSv1:
+ protocol_priority[0] = GNUTLS_TLS1_0;
+ protocol_priority[1] = GNUTLS_TLS1_1;
+ protocol_priority[2] = GNUTLS_TLS1_2;
+ break;
+ case CURL_SSLVERSION_TLSv1_0:
+ protocol_priority[0] = GNUTLS_TLS1_0;
+ break;
+ case CURL_SSLVERSION_TLSv1_1:
+ protocol_priority[0] = GNUTLS_TLS1_1;
+ break;
+ case CURL_SSLVERSION_TLSv1_2:
+ protocol_priority[0] = GNUTLS_TLS1_2;
+ break;
+ case CURL_SSLVERSION_SSLv2:
+ default:
+ failf(data, "GnuTLS does not support SSLv2");
+ return CURLE_SSL_CONNECT_ERROR;
+ break;
+ }
+ rc = gnutls_protocol_set_priority(session, protocol_priority);
+ if(rc != GNUTLS_E_SUCCESS) {
+ failf(data, "Did you pass a valid GnuTLS cipher list?");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
+#else
+ /* Ensure +SRP comes at the *end* of all relevant strings so that it can be
+ * removed if a run-time error indicates that SRP is not supported by this
+ * GnuTLS version */
+ switch (data->set.ssl.version) {
+ case CURL_SSLVERSION_SSLv3:
+ prioritylist = GNUTLS_CIPHERS ":-VERS-TLS-ALL:+VERS-SSL3.0";
+ sni = false;
+ break;
+ case CURL_SSLVERSION_DEFAULT:
+ case CURL_SSLVERSION_TLSv1:
+ prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:" GNUTLS_SRP;
+ break;
+ case CURL_SSLVERSION_TLSv1_0:
+ prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+ "+VERS-TLS1.0:" GNUTLS_SRP;
+ break;
+ case CURL_SSLVERSION_TLSv1_1:
+ prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+ "+VERS-TLS1.1:" GNUTLS_SRP;
+ break;
+ case CURL_SSLVERSION_TLSv1_2:
+ prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+ "+VERS-TLS1.2:" GNUTLS_SRP;
+ break;
+ case CURL_SSLVERSION_SSLv2:
+ default:
+ failf(data, "GnuTLS does not support SSLv2");
+ return CURLE_SSL_CONNECT_ERROR;
+ break;
+ }
+ rc = gnutls_priority_set_direct(session, prioritylist, &err);
+ if((rc == GNUTLS_E_INVALID_REQUEST) && err) {
+ if(!strcmp(err, GNUTLS_SRP)) {
+ /* This GnuTLS was probably compiled without support for SRP.
+ * Note that fact and try again without it. */
+ int validprioritylen = curlx_uztosi(err - prioritylist);
+ char *prioritycopy = strdup(prioritylist);
+ if(!prioritycopy)
+ return CURLE_OUT_OF_MEMORY;
+
+ infof(data, "This GnuTLS does not support SRP\n");
+ if(validprioritylen)
+ /* Remove the :+SRP */
+ prioritycopy[validprioritylen - 1] = 0;
+ rc = gnutls_priority_set_direct(session, prioritycopy, &err);
+ free(prioritycopy);
+ }
+ }
+ if(rc != GNUTLS_E_SUCCESS) {
+ failf(data, "Error %d setting GnuTLS cipher list starting with %s",
+ rc, err);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+#endif
+
+#ifdef HAS_ALPN
+ if(data->set.ssl_enable_alpn) {
+ int cur = 0;
+ gnutls_datum_t protocols[2];
+
+#ifdef USE_NGHTTP2
+ if(data->set.httpversion == CURL_HTTP_VERSION_2_0) {
+ protocols[cur].data = (unsigned char *)NGHTTP2_PROTO_VERSION_ID;
+ protocols[cur].size = NGHTTP2_PROTO_VERSION_ID_LEN;
+ cur++;
+ infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
+ }
+#endif
+
+ protocols[cur].data = (unsigned char *)ALPN_HTTP_1_1;
+ protocols[cur].size = ALPN_HTTP_1_1_LENGTH;
+ cur++;
+ infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
+
+ gnutls_alpn_set_protocols(session, protocols, cur, 0);
+ }
+#endif
+
+ if(data->set.str[STRING_CERT]) {
+ if(gnutls_certificate_set_x509_key_file(
+ conn->ssl[sockindex].cred,
+ data->set.str[STRING_CERT],
+ data->set.str[STRING_KEY] ?
+ data->set.str[STRING_KEY] : data->set.str[STRING_CERT],
+ do_file_type(data->set.str[STRING_CERT_TYPE]) ) !=
+ GNUTLS_E_SUCCESS) {
+ failf(data, "error reading X.509 key or certificate file");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ }
+
+#ifdef USE_TLS_SRP
+ /* put the credentials to the current session */
+ if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
+ rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP,
+ conn->ssl[sockindex].srp_client_cred);
+ if(rc != GNUTLS_E_SUCCESS) {
+ failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ }
+ else
+#endif
+ {
+ rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
+ conn->ssl[sockindex].cred);
+ if(rc != GNUTLS_E_SUCCESS) {
+ failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ }
+
+ /* set the connection handle (file descriptor for the socket) */
+ gnutls_transport_set_ptr(session,
+ GNUTLS_INT_TO_POINTER_CAST(conn->sock[sockindex]));
+
+ /* register callback functions to send and receive data. */
+ gnutls_transport_set_push_function(session, Curl_gtls_push);
+ gnutls_transport_set_pull_function(session, Curl_gtls_pull);
+
+ /* lowat must be set to zero when using custom push and pull functions. */
+ gnutls_transport_set_lowat(session, 0);
+
+#ifdef HAS_OCSP
+ if(data->set.ssl.verifystatus) {
+ rc = gnutls_ocsp_status_request_enable_client(session, NULL, 0, NULL);
+ if(rc != GNUTLS_E_SUCCESS) {
+ failf(data, "gnutls_ocsp_status_request_enable_client() failed: %d", rc);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ }
+#endif
+
+ /* This might be a reconnect, so we check for a session ID in the cache
+ to speed up things */
+
+ if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, &ssl_idsize)) {
+ /* we got a session id, use it! */
+ gnutls_session_set_data(session, ssl_sessionid, ssl_idsize);
+
+ /* Informational message */
+ infof (data, "SSL re-using session ID\n");
+ }
+
+ return CURLE_OK;
+}
+
+static CURLcode pkp_pin_peer_pubkey(gnutls_x509_crt_t cert,
+ const char *pinnedpubkey)
+{
+ /* Scratch */
+ size_t len1 = 0, len2 = 0;
+ unsigned char *buff1 = NULL;
+
+ gnutls_pubkey_t key = NULL;
+
+ /* Result is returned to caller */
+ int ret = 0;
+ CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+
+ /* if a path wasn't specified, don't pin */
+ if(NULL == pinnedpubkey)
+ return CURLE_OK;
+
+ if(NULL == cert)
+ return result;
+
+ do {
+ /* Begin Gyrations to get the public key */
+ gnutls_pubkey_init(&key);
+
+ ret = gnutls_pubkey_import_x509(key, cert, 0);
+ if(ret < 0)
+ break; /* failed */
+
+ ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, NULL, &len1);
+ if(ret != GNUTLS_E_SHORT_MEMORY_BUFFER || len1 == 0)
+ break; /* failed */
+
+ buff1 = malloc(len1);
+ if(NULL == buff1)
+ break; /* failed */
+
+ len2 = len1;
+
+ ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, buff1, &len2);
+ if(ret < 0 || len1 != len2)
+ break; /* failed */
+
+ /* End Gyrations */
+
+ /* The one good exit point */
+ result = Curl_pin_peer_pubkey(pinnedpubkey, buff1, len1);
+ } while(0);
+
+ if(NULL != key)
+ gnutls_pubkey_deinit(key);
+
+ Curl_safefree(buff1);
+
+ return result;
+}
+
+static Curl_recv gtls_recv;
+static Curl_send gtls_send;
+
+static CURLcode
+gtls_connect_step3(struct connectdata *conn,
+ int sockindex)
+{
+ unsigned int cert_list_size;
+ const gnutls_datum_t *chainp;
+ unsigned int verify_status = 0;
+ gnutls_x509_crt_t x509_cert, x509_issuer;
+ gnutls_datum_t issuerp;
+ char certbuf[256] = ""; /* big enough? */
+ size_t size;
+ unsigned int algo;
+ unsigned int bits;
+ time_t certclock;
+ const char *ptr;
+ struct SessionHandle *data = conn->data;
+ gnutls_session_t session = conn->ssl[sockindex].session;
+ int rc;
+ bool incache;
+ void *ssl_sessionid;
+#ifdef HAS_ALPN
+ gnutls_datum_t proto;
+#endif
+ CURLcode result = CURLE_OK;
+
+ gnutls_protocol_t version = gnutls_protocol_get_version(session);
+
+ /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */
+ ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(session),
+ gnutls_cipher_get(session),
+ gnutls_mac_get(session));
+
+ infof(data, "SSL connection using %s / %s\n",
+ gnutls_protocol_get_name(version), ptr);
+
+ /* This function will return the peer's raw certificate (chain) as sent by
+ the peer. These certificates are in raw format (DER encoded for
+ X.509). In case of a X.509 then a certificate list may be present. The
+ first certificate in the list is the peer's certificate, following the
+ issuer's certificate, then the issuer's issuer etc. */
+
+ chainp = gnutls_certificate_get_peers(session, &cert_list_size);
+ if(!chainp) {
+ if(data->set.ssl.verifypeer ||
+ data->set.ssl.verifyhost ||
+ data->set.ssl.issuercert) {
+#ifdef USE_TLS_SRP
+ if(data->set.ssl.authtype == CURL_TLSAUTH_SRP
+ && data->set.ssl.username != NULL
+ && !data->set.ssl.verifypeer
+ && gnutls_cipher_get(session)) {
+ /* no peer cert, but auth is ok if we have SRP user and cipher and no
+ peer verify */
+ }
+ else {
+#endif
+ failf(data, "failed to get server cert");
+ return CURLE_PEER_FAILED_VERIFICATION;
+#ifdef USE_TLS_SRP
+ }
+#endif
+ }
+ infof(data, "\t common name: WARNING couldn't obtain\n");
+ }
+
+ if(data->set.ssl.certinfo && chainp) {
+ unsigned int i;
+
+ result = Curl_ssl_init_certinfo(data, cert_list_size);
+ if(result)
+ return result;
+
+ for(i = 0; i < cert_list_size; i++) {
+ const char *beg = (const char *) chainp[i].data;
+ const char *end = beg + chainp[i].size;
+
+ result = Curl_extract_certinfo(conn, i, beg, end);
+ if(result)
+ return result;
+ }
+ }
+
+ if(data->set.ssl.verifypeer) {
+ /* This function will try to verify the peer's certificate and return its
+ status (trusted, invalid etc.). The value of status should be one or
+ more of the gnutls_certificate_status_t enumerated elements bitwise
+ or'd. To avoid denial of service attacks some default upper limits
+ regarding the certificate key size and chain size are set. To override
+ them use gnutls_certificate_set_verify_limits(). */
+
+ rc = gnutls_certificate_verify_peers2(session, &verify_status);
+ if(rc < 0) {
+ failf(data, "server cert verify failed: %d", rc);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
+ /* verify_status is a bitmask of gnutls_certificate_status bits */
+ if(verify_status & GNUTLS_CERT_INVALID) {
+ if(data->set.ssl.verifypeer) {
+ failf(data, "server certificate verification failed. CAfile: %s "
+ "CRLfile: %s", data->set.ssl.CAfile?data->set.ssl.CAfile:"none",
+ data->set.ssl.CRLfile?data->set.ssl.CRLfile:"none");
+ return CURLE_SSL_CACERT;
+ }
+ else
+ infof(data, "\t server certificate verification FAILED\n");
+ }
+ else
+ infof(data, "\t server certificate verification OK\n");
+ }
+ else
+ infof(data, "\t server certificate verification SKIPPED\n");
+
+#ifdef HAS_OCSP
+ if(data->set.ssl.verifystatus) {
+ if(gnutls_ocsp_status_request_is_checked(session, 0) == 0) {
+ gnutls_datum_t status_request;
+ gnutls_ocsp_resp_t ocsp_resp;
+
+ gnutls_ocsp_cert_status_t status;
+ gnutls_x509_crl_reason_t reason;
+
+ rc = gnutls_ocsp_status_request_get(session, &status_request);
+
+ infof(data, "\t server certificate status verification FAILED\n");
+
+ if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
+ failf(data, "No OCSP response received");
+ return CURLE_SSL_INVALIDCERTSTATUS;
+ }
+
+ if(rc < 0) {
+ failf(data, "Invalid OCSP response received");
+ return CURLE_SSL_INVALIDCERTSTATUS;
+ }
+
+ gnutls_ocsp_resp_init(&ocsp_resp);
+
+ rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request);
+ if(rc < 0) {
+ failf(data, "Invalid OCSP response received");
+ return CURLE_SSL_INVALIDCERTSTATUS;
+ }
+
+ rc = gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL,
+ &status, NULL, NULL, NULL, &reason);
+
+ switch(status) {
+ case GNUTLS_OCSP_CERT_GOOD:
+ break;
+
+ case GNUTLS_OCSP_CERT_REVOKED: {
+ const char *crl_reason;
+
+ switch(reason) {
+ default:
+ case GNUTLS_X509_CRLREASON_UNSPECIFIED:
+ crl_reason = "unspecified reason";
+ break;
+
+ case GNUTLS_X509_CRLREASON_KEYCOMPROMISE:
+ crl_reason = "private key compromised";
+ break;
+
+ case GNUTLS_X509_CRLREASON_CACOMPROMISE:
+ crl_reason = "CA compromised";
+ break;
+
+ case GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED:
+ crl_reason = "affiliation has changed";
+ break;
+
+ case GNUTLS_X509_CRLREASON_SUPERSEDED:
+ crl_reason = "certificate superseded";
+ break;
+
+ case GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION:
+ crl_reason = "operation has ceased";
+ break;
+
+ case GNUTLS_X509_CRLREASON_CERTIFICATEHOLD:
+ crl_reason = "certificate is on hold";
+ break;
+
+ case GNUTLS_X509_CRLREASON_REMOVEFROMCRL:
+ crl_reason = "will be removed from delta CRL";
+ break;
+
+ case GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN:
+ crl_reason = "privilege withdrawn";
+ break;
+
+ case GNUTLS_X509_CRLREASON_AACOMPROMISE:
+ crl_reason = "AA compromised";
+ break;
+ }
+
+ failf(data, "Server certificate was revoked: %s", crl_reason);
+ break;
+ }
+
+ default:
+ case GNUTLS_OCSP_CERT_UNKNOWN:
+ failf(data, "Server certificate status is unknown");
+ break;
+ }
+
+ gnutls_ocsp_resp_deinit(ocsp_resp);
+
+ return CURLE_SSL_INVALIDCERTSTATUS;
+ }
+ else
+ infof(data, "\t server certificate status verification OK\n");
+ }
+ else
+ infof(data, "\t server certificate status verification SKIPPED\n");
+#endif
+
+ /* initialize an X.509 certificate structure. */
+ gnutls_x509_crt_init(&x509_cert);
+
+ if(chainp)
+ /* convert the given DER or PEM encoded Certificate to the native
+ gnutls_x509_crt_t format */
+ gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER);
+
+ if(data->set.ssl.issuercert) {
+ gnutls_x509_crt_init(&x509_issuer);
+ issuerp = load_file(data->set.ssl.issuercert);
+ gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM);
+ rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer);
+ gnutls_x509_crt_deinit(x509_issuer);
+ unload_file(issuerp);
+ if(rc <= 0) {
+ failf(data, "server certificate issuer check failed (IssuerCert: %s)",
+ data->set.ssl.issuercert?data->set.ssl.issuercert:"none");
+ gnutls_x509_crt_deinit(x509_cert);
+ return CURLE_SSL_ISSUER_ERROR;
+ }
+ infof(data, "\t server certificate issuer check OK (Issuer Cert: %s)\n",
+ data->set.ssl.issuercert?data->set.ssl.issuercert:"none");
+ }
+
+ size=sizeof(certbuf);
+ rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME,
+ 0, /* the first and only one */
+ FALSE,
+ certbuf,
+ &size);
+ if(rc) {
+ infof(data, "error fetching CN from cert:%s\n",
+ gnutls_strerror(rc));
+ }
+
+ /* This function will check if the given certificate's subject matches the
+ given hostname. This is a basic implementation of the matching described
+ in RFC2818 (HTTPS), which takes into account wildcards, and the subject
+ alternative name PKIX extension. Returns non zero on success, and zero on
+ failure. */
+ rc = gnutls_x509_crt_check_hostname(x509_cert, conn->host.name);
+#if GNUTLS_VERSION_NUMBER < 0x030306
+ /* Before 3.3.6, gnutls_x509_crt_check_hostname() didn't check IP
+ addresses. */
+ if(!rc) {
+#ifdef ENABLE_IPV6
+ #define use_addr in6_addr
+#else
+ #define use_addr in_addr
+#endif
+ unsigned char addrbuf[sizeof(struct use_addr)];
+ unsigned char certaddr[sizeof(struct use_addr)];
+ size_t addrlen = 0, certaddrlen;
+ int i;
+ int ret = 0;
+
+ if(Curl_inet_pton(AF_INET, conn->host.name, addrbuf) > 0)
+ addrlen = 4;
+#ifdef ENABLE_IPV6
+ else if(Curl_inet_pton(AF_INET6, conn->host.name, addrbuf) > 0)
+ addrlen = 16;
+#endif
+
+ if(addrlen) {
+ for(i=0; ; i++) {
+ certaddrlen = sizeof(certaddr);
+ ret = gnutls_x509_crt_get_subject_alt_name(x509_cert, i, certaddr,
+ &certaddrlen, NULL);
+ /* If this happens, it wasn't an IP address. */
+ if(ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
+ continue;
+ if(ret < 0)
+ break;
+ if(ret != GNUTLS_SAN_IPADDRESS)
+ continue;
+ if(certaddrlen == addrlen && !memcmp(addrbuf, certaddr, addrlen)) {
+ rc = 1;
+ break;
+ }
+ }
+ }
+ }
+#endif
+ if(!rc) {
+ if(data->set.ssl.verifyhost) {
+ failf(data, "SSL: certificate subject name (%s) does not match "
+ "target host name '%s'", certbuf, conn->host.dispname);
+ gnutls_x509_crt_deinit(x509_cert);
+ return CURLE_PEER_FAILED_VERIFICATION;
+ }
+ else
+ infof(data, "\t common name: %s (does not match '%s')\n",
+ certbuf, conn->host.dispname);
+ }
+ else
+ infof(data, "\t common name: %s (matched)\n", certbuf);
+
+ /* Check for time-based validity */
+ certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
+
+ if(certclock == (time_t)-1) {
+ if(data->set.ssl.verifypeer) {
+ failf(data, "server cert expiration date verify failed");
+ gnutls_x509_crt_deinit(x509_cert);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ else
+ infof(data, "\t server certificate expiration date verify FAILED\n");
+ }
+ else {
+ if(certclock < time(NULL)) {
+ if(data->set.ssl.verifypeer) {
+ failf(data, "server certificate expiration date has passed.");
+ gnutls_x509_crt_deinit(x509_cert);
+ return CURLE_PEER_FAILED_VERIFICATION;
+ }
+ else
+ infof(data, "\t server certificate expiration date FAILED\n");
+ }
+ else
+ infof(data, "\t server certificate expiration date OK\n");
+ }
+
+ certclock = gnutls_x509_crt_get_activation_time(x509_cert);
+
+ if(certclock == (time_t)-1) {
+ if(data->set.ssl.verifypeer) {
+ failf(data, "server cert activation date verify failed");
+ gnutls_x509_crt_deinit(x509_cert);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ else
+ infof(data, "\t server certificate activation date verify FAILED\n");
+ }
+ else {
+ if(certclock > time(NULL)) {
+ if(data->set.ssl.verifypeer) {
+ failf(data, "server certificate not activated yet.");
+ gnutls_x509_crt_deinit(x509_cert);
+ return CURLE_PEER_FAILED_VERIFICATION;
+ }
+ else
+ infof(data, "\t server certificate activation date FAILED\n");
+ }
+ else
+ infof(data, "\t server certificate activation date OK\n");
+ }
+
+ ptr = data->set.str[STRING_SSL_PINNEDPUBLICKEY];
+ if(ptr) {
+ result = pkp_pin_peer_pubkey(x509_cert, ptr);
+ if(result != CURLE_OK) {
+ failf(data, "SSL: public key does not match pinned public key!");
+ gnutls_x509_crt_deinit(x509_cert);
+ return result;
+ }
+ }
+
+ /* Show:
+
+ - subject
+ - start date
+ - expire date
+ - common name
+ - issuer
+
+ */
+
+ /* public key algorithm's parameters */
+ algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &bits);
+ infof(data, "\t certificate public key: %s\n",
+ gnutls_pk_algorithm_get_name(algo));
+
+ /* version of the X.509 certificate. */
+ infof(data, "\t certificate version: #%d\n",
+ gnutls_x509_crt_get_version(x509_cert));
+
+
+ size = sizeof(certbuf);
+ gnutls_x509_crt_get_dn(x509_cert, certbuf, &size);
+ infof(data, "\t subject: %s\n", certbuf);
+
+ certclock = gnutls_x509_crt_get_activation_time(x509_cert);
+ showtime(data, "start date", certclock);
+
+ certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
+ showtime(data, "expire date", certclock);
+
+ size = sizeof(certbuf);
+ gnutls_x509_crt_get_issuer_dn(x509_cert, certbuf, &size);
+ infof(data, "\t issuer: %s\n", certbuf);
+
+ gnutls_x509_crt_deinit(x509_cert);
+
+ /* compression algorithm (if any) */
+ ptr = gnutls_compression_get_name(gnutls_compression_get(session));
+ /* the *_get_name() says "NULL" if GNUTLS_COMP_NULL is returned */
+ infof(data, "\t compression: %s\n", ptr);
+
+#ifdef HAS_ALPN
+ if(data->set.ssl_enable_alpn) {
+ rc = gnutls_alpn_get_selected_protocol(session, &proto);
+ if(rc == 0) {
+ infof(data, "ALPN, server accepted to use %.*s\n", proto.size,
+ proto.data);
+
+#ifdef USE_NGHTTP2
+ if(proto.size == NGHTTP2_PROTO_VERSION_ID_LEN &&
+ !memcmp(NGHTTP2_PROTO_VERSION_ID, proto.data,
+ NGHTTP2_PROTO_VERSION_ID_LEN)) {
+ conn->negnpn = CURL_HTTP_VERSION_2_0;
+ }
+ else
+#endif
+ if(proto.size == ALPN_HTTP_1_1_LENGTH &&
+ !memcmp(ALPN_HTTP_1_1, proto.data, ALPN_HTTP_1_1_LENGTH)) {
+ conn->negnpn = CURL_HTTP_VERSION_1_1;
+ }
+ }
+ else
+ infof(data, "ALPN, server did not agree to a protocol\n");
+ }
+#endif
+
+ conn->ssl[sockindex].state = ssl_connection_complete;
+ conn->recv[sockindex] = gtls_recv;
+ conn->send[sockindex] = gtls_send;
+
+ {
+ /* we always unconditionally get the session id here, as even if we
+ already got it from the cache and asked to use it in the connection, it
+ might've been rejected and then a new one is in use now and we need to
+ detect that. */
+ void *connect_sessionid;
+ size_t connect_idsize = 0;
+
+ /* get the session ID data size */
+ gnutls_session_get_data(session, NULL, &connect_idsize);
+ connect_sessionid = malloc(connect_idsize); /* get a buffer for it */
+
+ if(connect_sessionid) {
+ /* extract session ID to the allocated buffer */
+ gnutls_session_get_data(session, connect_sessionid, &connect_idsize);
+
+ incache = !(Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL));
+ if(incache) {
+ /* there was one before in the cache, so instead of risking that the
+ previous one was rejected, we just kill that and store the new */
+ Curl_ssl_delsessionid(conn, ssl_sessionid);
+ }
+
+ /* store this session id */
+ result = Curl_ssl_addsessionid(conn, connect_sessionid, connect_idsize);
+ if(result) {
+ free(connect_sessionid);
+ result = CURLE_OUT_OF_MEMORY;
+ }
+ }
+ else
+ result = CURLE_OUT_OF_MEMORY;
+ }
+
+ return result;
+}
+
+
+/*
+ * This function is called after the TCP connect has completed. Setup the TLS
+ * layer and do all necessary magic.
+ */
+/* We use connssl->connecting_state to keep track of the connection status;
+ there are three states: 'ssl_connect_1' (not started yet or complete),
+ 'ssl_connect_2_reading' (waiting for data from server), and
+ 'ssl_connect_2_writing' (waiting to be able to write).
+ */
+static CURLcode
+gtls_connect_common(struct connectdata *conn,
+ int sockindex,
+ bool nonblocking,
+ bool *done)
+{
+ int rc;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+ /* Initiate the connection, if not already done */
+ if(ssl_connect_1==connssl->connecting_state) {
+ rc = gtls_connect_step1 (conn, sockindex);
+ if(rc)
+ return rc;
+ }
+
+ rc = handshake(conn, sockindex, TRUE, nonblocking);
+ if(rc)
+ /* handshake() sets its own error message with failf() */
+ return rc;
+
+ /* Finish connecting once the handshake is done */
+ if(ssl_connect_1==connssl->connecting_state) {
+ rc = gtls_connect_step3(conn, sockindex);
+ if(rc)
+ return rc;
+ }
+
+ *done = ssl_connect_1==connssl->connecting_state;
+
+ return CURLE_OK;
+}
+
+CURLcode
+Curl_gtls_connect_nonblocking(struct connectdata *conn,
+ int sockindex,
+ bool *done)
+{
+ return gtls_connect_common(conn, sockindex, TRUE, done);
+}
+
+CURLcode
+Curl_gtls_connect(struct connectdata *conn,
+ int sockindex)
+
+{
+ CURLcode result;
+ bool done = FALSE;
+
+ result = gtls_connect_common(conn, sockindex, FALSE, &done);
+ if(result)
+ return result;
+
+ DEBUGASSERT(done);
+
+ return CURLE_OK;
+}
+
+static ssize_t gtls_send(struct connectdata *conn,
+ int sockindex,
+ const void *mem,
+ size_t len,
+ CURLcode *curlcode)
+{
+ ssize_t rc = gnutls_record_send(conn->ssl[sockindex].session, mem, len);
+
+ if(rc < 0 ) {
+ *curlcode = (rc == GNUTLS_E_AGAIN)
+ ? CURLE_AGAIN
+ : CURLE_SEND_ERROR;
+
+ rc = -1;
+ }
+
+ return rc;
+}
+
+static void close_one(struct connectdata *conn,
+ int idx)
+{
+ if(conn->ssl[idx].session) {
+ gnutls_bye(conn->ssl[idx].session, GNUTLS_SHUT_RDWR);
+ gnutls_deinit(conn->ssl[idx].session);
+ conn->ssl[idx].session = NULL;
+ }
+ if(conn->ssl[idx].cred) {
+ gnutls_certificate_free_credentials(conn->ssl[idx].cred);
+ conn->ssl[idx].cred = NULL;
+ }
+#ifdef USE_TLS_SRP
+ if(conn->ssl[idx].srp_client_cred) {
+ gnutls_srp_free_client_credentials(conn->ssl[idx].srp_client_cred);
+ conn->ssl[idx].srp_client_cred = NULL;
+ }
+#endif
+}
+
+void Curl_gtls_close(struct connectdata *conn, int sockindex)
+{
+ close_one(conn, sockindex);
+}
+
+/*
+ * This function is called to shut down the SSL layer but keep the
+ * socket open (CCC - Clear Command Channel)
+ */
+int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
+{
+ ssize_t result;
+ int retval = 0;
+ struct SessionHandle *data = conn->data;
+ int done = 0;
+ char buf[120];
+
+ /* This has only been tested on the proftpd server, and the mod_tls code
+ sends a close notify alert without waiting for a close notify alert in
+ response. Thus we wait for a close notify alert from the server, but
+ we do not send one. Let's hope other servers do the same... */
+
+ if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
+ gnutls_bye(conn->ssl[sockindex].session, GNUTLS_SHUT_WR);
+
+ if(conn->ssl[sockindex].session) {
+ while(!done) {
+ int what = Curl_socket_ready(conn->sock[sockindex],
+ CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
+ if(what > 0) {
+ /* Something to read, let's do it and hope that it is the close
+ notify alert from the server */
+ result = gnutls_record_recv(conn->ssl[sockindex].session,
+ buf, sizeof(buf));
+ switch(result) {
+ case 0:
+ /* This is the expected response. There was no data but only
+ the close notify alert */
+ done = 1;
+ break;
+ case GNUTLS_E_AGAIN:
+ case GNUTLS_E_INTERRUPTED:
+ infof(data, "GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED\n");
+ break;
+ default:
+ retval = -1;
+ done = 1;
+ break;
+ }
+ }
+ else if(0 == what) {
+ /* timeout */
+ failf(data, "SSL shutdown timeout");
+ done = 1;
+ break;
+ }
+ else {
+ /* anything that gets here is fatally bad */
+ failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+ retval = -1;
+ done = 1;
+ }
+ }
+ gnutls_deinit(conn->ssl[sockindex].session);
+ }
+ gnutls_certificate_free_credentials(conn->ssl[sockindex].cred);
+
+#ifdef USE_TLS_SRP
+ if(data->set.ssl.authtype == CURL_TLSAUTH_SRP
+ && data->set.ssl.username != NULL)
+ gnutls_srp_free_client_credentials(conn->ssl[sockindex].srp_client_cred);
+#endif
+
+ conn->ssl[sockindex].cred = NULL;
+ conn->ssl[sockindex].session = NULL;
+
+ return retval;
+}
+
+static ssize_t gtls_recv(struct connectdata *conn, /* connection data */
+ int num, /* socketindex */
+ char *buf, /* store read data here */
+ size_t buffersize, /* max amount to read */
+ CURLcode *curlcode)
+{
+ ssize_t ret;
+
+ ret = gnutls_record_recv(conn->ssl[num].session, buf, buffersize);
+ if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) {
+ *curlcode = CURLE_AGAIN;
+ return -1;
+ }
+
+ if(ret == GNUTLS_E_REHANDSHAKE) {
+ /* BLOCKING call, this is bad but a work-around for now. Fixing this "the
+ proper way" takes a whole lot of work. */
+ CURLcode result = handshake(conn, num, FALSE, FALSE);
+ if(result)
+ /* handshake() writes error message on its own */
+ *curlcode = result;
+ else
+ *curlcode = CURLE_AGAIN; /* then return as if this was a wouldblock */
+ return -1;
+ }
+
+ if(ret < 0) {
+ failf(conn->data, "GnuTLS recv error (%d): %s",
+ (int)ret, gnutls_strerror((int)ret));
+ *curlcode = CURLE_RECV_ERROR;
+ return -1;
+ }
+
+ return ret;
+}
+
+void Curl_gtls_session_free(void *ptr)
+{
+ free(ptr);
+}
+
+size_t Curl_gtls_version(char *buffer, size_t size)
+{
+ return snprintf(buffer, size, "GnuTLS/%s", gnutls_check_version(NULL));
+}
+
+#ifndef USE_GNUTLS_NETTLE
+static int Curl_gtls_seed(struct SessionHandle *data)
+{
+ /* we have the "SSL is seeded" boolean static to prevent multiple
+ time-consuming seedings in vain */
+ static bool ssl_seeded = FALSE;
+
+ /* Quickly add a bit of entropy */
+ gcry_fast_random_poll();
+
+ if(!ssl_seeded || data->set.str[STRING_SSL_RANDOM_FILE] ||
+ data->set.str[STRING_SSL_EGDSOCKET]) {
+
+ /* TODO: to a good job seeding the RNG
+ This may involve the gcry_control function and these options:
+ GCRYCTL_SET_RANDOM_SEED_FILE
+ GCRYCTL_SET_RNDEGD_SOCKET
+ */
+ ssl_seeded = TRUE;
+ }
+ return 0;
+}
+#endif
+
+/* data might be NULL! */
+int Curl_gtls_random(struct SessionHandle *data,
+ unsigned char *entropy,
+ size_t length)
+{
+#if defined(USE_GNUTLS_NETTLE)
+ (void)data;
+ gnutls_rnd(GNUTLS_RND_RANDOM, entropy, length);
+#elif defined(USE_GNUTLS)
+ if(data)
+ Curl_gtls_seed(data); /* Initiate the seed if not already done */
+ gcry_randomize(entropy, length, GCRY_STRONG_RANDOM);
+#endif
+ return 0;
+}
+
+void Curl_gtls_md5sum(unsigned char *tmp, /* input */
+ size_t tmplen,
+ unsigned char *md5sum, /* output */
+ size_t md5len)
+{
+#if defined(USE_GNUTLS_NETTLE)
+ struct md5_ctx MD5pw;
+ md5_init(&MD5pw);
+ md5_update(&MD5pw, (unsigned int)tmplen, tmp);
+ md5_digest(&MD5pw, (unsigned int)md5len, md5sum);
+#elif defined(USE_GNUTLS)
+ gcry_md_hd_t MD5pw;
+ gcry_md_open(&MD5pw, GCRY_MD_MD5, 0);
+ gcry_md_write(MD5pw, tmp, tmplen);
+ memcpy(md5sum, gcry_md_read (MD5pw, 0), md5len);
+ gcry_md_close(MD5pw);
+#endif
+}
+
+void Curl_gtls_sha256sum(const unsigned char *tmp, /* input */
+ size_t tmplen,
+ unsigned char *sha256sum, /* output */
+ size_t sha256len)
+{
+#if defined(USE_GNUTLS_NETTLE)
+ struct sha256_ctx SHA256pw;
+ sha256_init(&SHA256pw);
+ sha256_update(&SHA256pw, (unsigned int)tmplen, tmp);
+ sha256_digest(&SHA256pw, (unsigned int)sha256len, sha256sum);
+#elif defined(USE_GNUTLS)
+ gcry_md_hd_t SHA256pw;
+ gcry_md_open(&SHA256pw, GCRY_MD_SHA256, 0);
+ gcry_md_write(SHA256pw, tmp, tmplen);
+ memcpy(sha256sum, gcry_md_read (SHA256pw, 0), sha256len);
+ gcry_md_close(SHA256pw);
+#endif
+}
+
+bool Curl_gtls_cert_status_request(void)
+{
+#ifdef HAS_OCSP
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+
+#endif /* USE_GNUTLS */
diff --git a/Utilities/cmcurl/lib/vtls/gtls.h b/Utilities/cmcurl/lib/vtls/gtls.h
new file mode 100644
index 000000000..0afd9b94a
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/gtls.h
@@ -0,0 +1,88 @@
+#ifndef HEADER_CURL_GTLS_H
+#define HEADER_CURL_GTLS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_GNUTLS
+
+#include "urldata.h"
+
+int Curl_gtls_init(void);
+int Curl_gtls_cleanup(void);
+CURLcode Curl_gtls_connect(struct connectdata *conn, int sockindex);
+CURLcode Curl_gtls_connect_nonblocking(struct connectdata *conn,
+ int sockindex,
+ bool *done);
+
+ /* close a SSL connection */
+void Curl_gtls_close(struct connectdata *conn, int sockindex);
+
+void Curl_gtls_session_free(void *ptr);
+size_t Curl_gtls_version(char *buffer, size_t size);
+int Curl_gtls_shutdown(struct connectdata *conn, int sockindex);
+int Curl_gtls_random(struct SessionHandle *data,
+ unsigned char *entropy,
+ size_t length);
+void Curl_gtls_md5sum(unsigned char *tmp, /* input */
+ size_t tmplen,
+ unsigned char *md5sum, /* output */
+ size_t md5len);
+void Curl_gtls_sha256sum(const unsigned char *tmp, /* input */
+ size_t tmplen,
+ unsigned char *sha256sum, /* output */
+ size_t sha256len);
+
+bool Curl_gtls_cert_status_request(void);
+
+/* Set the API backend definition to GnuTLS */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_GNUTLS
+
+/* this backend supports the CAPATH option */
+#define have_curlssl_ca_path 1
+
+/* this backend supports CURLOPT_CERTINFO */
+#define have_curlssl_certinfo 1
+
+/* API setup for GnuTLS */
+#define curlssl_init Curl_gtls_init
+#define curlssl_cleanup Curl_gtls_cleanup
+#define curlssl_connect Curl_gtls_connect
+#define curlssl_connect_nonblocking Curl_gtls_connect_nonblocking
+#define curlssl_session_free(x) Curl_gtls_session_free(x)
+#define curlssl_close_all(x) ((void)x)
+#define curlssl_close Curl_gtls_close
+#define curlssl_shutdown(x,y) Curl_gtls_shutdown(x,y)
+#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN)
+#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN)
+#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL)
+#define curlssl_version Curl_gtls_version
+#define curlssl_check_cxn(x) ((void)x, -1)
+#define curlssl_data_pending(x,y) ((void)x, (void)y, 0)
+#define curlssl_random(x,y,z) Curl_gtls_random(x,y,z)
+#define curlssl_md5sum(a,b,c,d) Curl_gtls_md5sum(a,b,c,d)
+#define curlssl_sha256sum(a,b,c,d) Curl_gtls_sha256sum(a,b,c,d)
+#define curlssl_cert_status_request() Curl_gtls_cert_status_request()
+
+#endif /* USE_GNUTLS */
+#endif /* HEADER_CURL_GTLS_H */
diff --git a/Utilities/cmcurl/lib/vtls/nss.c b/Utilities/cmcurl/lib/vtls/nss.c
new file mode 100644
index 000000000..91727c7c3
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/nss.c
@@ -0,0 +1,2074 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all NSS-specific code for the TLS/SSL layer. No code
+ * but vtls.c should ever call or use these functions.
+ */
+
+#include "curl_setup.h"
+
+#ifdef USE_NSS
+
+#include "urldata.h"
+#include "sendf.h"
+#include "formdata.h" /* for the boundary function */
+#include "url.h" /* for the ssl config check function */
+#include "connect.h"
+#include "strequal.h"
+#include "select.h"
+#include "vtls.h"
+#include "llist.h"
+#include "curl_printf.h"
+#include "nssg.h"
+#include <nspr.h>
+#include <nss.h>
+#include <ssl.h>
+#include <sslerr.h>
+#include <secerr.h>
+#include <secmod.h>
+#include <sslproto.h>
+#include <prtypes.h>
+#include <pk11pub.h>
+#include <prio.h>
+#include <secitem.h>
+#include <secport.h>
+#include <certdb.h>
+#include <base64.h>
+#include <cert.h>
+#include <prerror.h>
+#include <keyhi.h> /* for SECKEY_DestroyPublicKey() */
+
+#define NSSVERNUM ((NSS_VMAJOR<<16)|(NSS_VMINOR<<8)|NSS_VPATCH)
+
+#if NSSVERNUM >= 0x030f00 /* 3.15.0 */
+#include <ocsp.h>
+#endif
+
+#include "rawstr.h"
+#include "warnless.h"
+#include "x509asn1.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define SSL_DIR "/etc/pki/nssdb"
+
+/* enough to fit the string "PEM Token #[0|1]" */
+#define SLOTSIZE 13
+
+PRFileDesc *PR_ImportTCPSocket(PRInt32 osfd);
+
+PRLock * nss_initlock = NULL;
+PRLock * nss_crllock = NULL;
+struct curl_llist *nss_crl_list = NULL;
+NSSInitContext * nss_context = NULL;
+
+volatile int initialized = 0;
+
+typedef struct {
+ const char *name;
+ int num;
+} cipher_s;
+
+#define PK11_SETATTRS(_attr, _idx, _type, _val, _len) do { \
+ CK_ATTRIBUTE *ptr = (_attr) + ((_idx)++); \
+ ptr->type = (_type); \
+ ptr->pValue = (_val); \
+ ptr->ulValueLen = (_len); \
+} WHILE_FALSE
+
+#define CERT_NewTempCertificate __CERT_NewTempCertificate
+
+#define NUM_OF_CIPHERS sizeof(cipherlist)/sizeof(cipherlist[0])
+static const cipher_s cipherlist[] = {
+ /* SSL2 cipher suites */
+ {"rc4", SSL_EN_RC4_128_WITH_MD5},
+ {"rc4-md5", SSL_EN_RC4_128_WITH_MD5},
+ {"rc4export", SSL_EN_RC4_128_EXPORT40_WITH_MD5},
+ {"rc2", SSL_EN_RC2_128_CBC_WITH_MD5},
+ {"rc2export", SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5},
+ {"des", SSL_EN_DES_64_CBC_WITH_MD5},
+ {"desede3", SSL_EN_DES_192_EDE3_CBC_WITH_MD5},
+ /* SSL3/TLS cipher suites */
+ {"rsa_rc4_128_md5", SSL_RSA_WITH_RC4_128_MD5},
+ {"rsa_rc4_128_sha", SSL_RSA_WITH_RC4_128_SHA},
+ {"rsa_3des_sha", SSL_RSA_WITH_3DES_EDE_CBC_SHA},
+ {"rsa_des_sha", SSL_RSA_WITH_DES_CBC_SHA},
+ {"rsa_rc4_40_md5", SSL_RSA_EXPORT_WITH_RC4_40_MD5},
+ {"rsa_rc2_40_md5", SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5},
+ {"rsa_null_md5", SSL_RSA_WITH_NULL_MD5},
+ {"rsa_null_sha", SSL_RSA_WITH_NULL_SHA},
+ {"fips_3des_sha", SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA},
+ {"fips_des_sha", SSL_RSA_FIPS_WITH_DES_CBC_SHA},
+ {"fortezza", SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA},
+ {"fortezza_rc4_128_sha", SSL_FORTEZZA_DMS_WITH_RC4_128_SHA},
+ {"fortezza_null", SSL_FORTEZZA_DMS_WITH_NULL_SHA},
+ /* TLS 1.0: Exportable 56-bit Cipher Suites. */
+ {"rsa_des_56_sha", TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA},
+ {"rsa_rc4_56_sha", TLS_RSA_EXPORT1024_WITH_RC4_56_SHA},
+ /* AES ciphers. */
+ {"dhe_dss_aes_128_cbc_sha", TLS_DHE_DSS_WITH_AES_128_CBC_SHA},
+ {"dhe_dss_aes_256_cbc_sha", TLS_DHE_DSS_WITH_AES_256_CBC_SHA},
+ {"dhe_rsa_aes_128_cbc_sha", TLS_DHE_RSA_WITH_AES_128_CBC_SHA},
+ {"dhe_rsa_aes_256_cbc_sha", TLS_DHE_RSA_WITH_AES_256_CBC_SHA},
+ {"rsa_aes_128_sha", TLS_RSA_WITH_AES_128_CBC_SHA},
+ {"rsa_aes_256_sha", TLS_RSA_WITH_AES_256_CBC_SHA},
+ /* ECC ciphers. */
+ {"ecdh_ecdsa_null_sha", TLS_ECDH_ECDSA_WITH_NULL_SHA},
+ {"ecdh_ecdsa_rc4_128_sha", TLS_ECDH_ECDSA_WITH_RC4_128_SHA},
+ {"ecdh_ecdsa_3des_sha", TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA},
+ {"ecdh_ecdsa_aes_128_sha", TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA},
+ {"ecdh_ecdsa_aes_256_sha", TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA},
+ {"ecdhe_ecdsa_null_sha", TLS_ECDHE_ECDSA_WITH_NULL_SHA},
+ {"ecdhe_ecdsa_rc4_128_sha", TLS_ECDHE_ECDSA_WITH_RC4_128_SHA},
+ {"ecdhe_ecdsa_3des_sha", TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA},
+ {"ecdhe_ecdsa_aes_128_sha", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA},
+ {"ecdhe_ecdsa_aes_256_sha", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
+ {"ecdh_rsa_null_sha", TLS_ECDH_RSA_WITH_NULL_SHA},
+ {"ecdh_rsa_128_sha", TLS_ECDH_RSA_WITH_RC4_128_SHA},
+ {"ecdh_rsa_3des_sha", TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA},
+ {"ecdh_rsa_aes_128_sha", TLS_ECDH_RSA_WITH_AES_128_CBC_SHA},
+ {"ecdh_rsa_aes_256_sha", TLS_ECDH_RSA_WITH_AES_256_CBC_SHA},
+ {"echde_rsa_null", TLS_ECDHE_RSA_WITH_NULL_SHA},
+ {"ecdhe_rsa_rc4_128_sha", TLS_ECDHE_RSA_WITH_RC4_128_SHA},
+ {"ecdhe_rsa_3des_sha", TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA},
+ {"ecdhe_rsa_aes_128_sha", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
+ {"ecdhe_rsa_aes_256_sha", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA},
+ {"ecdh_anon_null_sha", TLS_ECDH_anon_WITH_NULL_SHA},
+ {"ecdh_anon_rc4_128sha", TLS_ECDH_anon_WITH_RC4_128_SHA},
+ {"ecdh_anon_3des_sha", TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA},
+ {"ecdh_anon_aes_128_sha", TLS_ECDH_anon_WITH_AES_128_CBC_SHA},
+ {"ecdh_anon_aes_256_sha", TLS_ECDH_anon_WITH_AES_256_CBC_SHA},
+#ifdef TLS_RSA_WITH_NULL_SHA256
+ /* new HMAC-SHA256 cipher suites specified in RFC */
+ {"rsa_null_sha_256", TLS_RSA_WITH_NULL_SHA256},
+ {"rsa_aes_128_cbc_sha_256", TLS_RSA_WITH_AES_128_CBC_SHA256},
+ {"rsa_aes_256_cbc_sha_256", TLS_RSA_WITH_AES_256_CBC_SHA256},
+ {"dhe_rsa_aes_128_cbc_sha_256", TLS_DHE_RSA_WITH_AES_128_CBC_SHA256},
+ {"dhe_rsa_aes_256_cbc_sha_256", TLS_DHE_RSA_WITH_AES_256_CBC_SHA256},
+ {"ecdhe_ecdsa_aes_128_cbc_sha_256", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256},
+ {"ecdhe_rsa_aes_128_cbc_sha_256", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256},
+#endif
+#ifdef TLS_RSA_WITH_AES_128_GCM_SHA256
+ /* AES GCM cipher suites in RFC 5288 and RFC 5289 */
+ {"rsa_aes_128_gcm_sha_256", TLS_RSA_WITH_AES_128_GCM_SHA256},
+ {"dhe_rsa_aes_128_gcm_sha_256", TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
+ {"dhe_dss_aes_128_gcm_sha_256", TLS_DHE_DSS_WITH_AES_128_GCM_SHA256},
+ {"ecdhe_ecdsa_aes_128_gcm_sha_256", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+ {"ecdh_ecdsa_aes_128_gcm_sha_256", TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256},
+ {"ecdhe_rsa_aes_128_gcm_sha_256", TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ {"ecdh_rsa_aes_128_gcm_sha_256", TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256},
+#endif
+};
+
+static const char* pem_library = "libnsspem.so";
+SECMODModule* mod = NULL;
+
+/* NSPR I/O layer we use to detect blocking direction during SSL handshake */
+static PRDescIdentity nspr_io_identity = PR_INVALID_IO_LAYER;
+static PRIOMethods nspr_io_methods;
+
+static const char* nss_error_to_name(PRErrorCode code)
+{
+ const char *name = PR_ErrorToName(code);
+ if(name)
+ return name;
+
+ return "unknown error";
+}
+
+static void nss_print_error_message(struct SessionHandle *data, PRUint32 err)
+{
+ failf(data, "%s", PR_ErrorToString(err, PR_LANGUAGE_I_DEFAULT));
+}
+
+static SECStatus set_ciphers(struct SessionHandle *data, PRFileDesc * model,
+ char *cipher_list)
+{
+ unsigned int i;
+ PRBool cipher_state[NUM_OF_CIPHERS];
+ PRBool found;
+ char *cipher;
+
+ /* First disable all ciphers. This uses a different max value in case
+ * NSS adds more ciphers later we don't want them available by
+ * accident
+ */
+ for(i=0; i<SSL_NumImplementedCiphers; i++) {
+ SSL_CipherPrefSet(model, SSL_ImplementedCiphers[i], PR_FALSE);
+ }
+
+ /* Set every entry in our list to false */
+ for(i=0; i<NUM_OF_CIPHERS; i++) {
+ cipher_state[i] = PR_FALSE;
+ }
+
+ cipher = cipher_list;
+
+ while(cipher_list && (cipher_list[0])) {
+ while((*cipher) && (ISSPACE(*cipher)))
+ ++cipher;
+
+ if((cipher_list = strchr(cipher, ','))) {
+ *cipher_list++ = '\0';
+ }
+
+ found = PR_FALSE;
+
+ for(i=0; i<NUM_OF_CIPHERS; i++) {
+ if(Curl_raw_equal(cipher, cipherlist[i].name)) {
+ cipher_state[i] = PR_TRUE;
+ found = PR_TRUE;
+ break;
+ }
+ }
+
+ if(found == PR_FALSE) {
+ failf(data, "Unknown cipher in list: %s", cipher);
+ return SECFailure;
+ }
+
+ if(cipher_list) {
+ cipher = cipher_list;
+ }
+ }
+
+ /* Finally actually enable the selected ciphers */
+ for(i=0; i<NUM_OF_CIPHERS; i++) {
+ if(!cipher_state[i])
+ continue;
+
+ if(SSL_CipherPrefSet(model, cipherlist[i].num, PR_TRUE) != SECSuccess) {
+ failf(data, "cipher-suite not supported by NSS: %s", cipherlist[i].name);
+ return SECFailure;
+ }
+ }
+
+ return SECSuccess;
+}
+
+/*
+ * Get the number of ciphers that are enabled. We use this to determine
+ * if we need to call NSS_SetDomesticPolicy() to enable the default ciphers.
+ */
+static int num_enabled_ciphers(void)
+{
+ PRInt32 policy = 0;
+ int count = 0;
+ unsigned int i;
+
+ for(i=0; i<NUM_OF_CIPHERS; i++) {
+ SSL_CipherPolicyGet(cipherlist[i].num, &policy);
+ if(policy)
+ count++;
+ }
+ return count;
+}
+
+/*
+ * Determine whether the nickname passed in is a filename that needs to
+ * be loaded as a PEM or a regular NSS nickname.
+ *
+ * returns 1 for a file
+ * returns 0 for not a file (NSS nickname)
+ */
+static int is_file(const char *filename)
+{
+ struct_stat st;
+
+ if(filename == NULL)
+ return 0;
+
+ if(stat(filename, &st) == 0)
+ if(S_ISREG(st.st_mode))
+ return 1;
+
+ return 0;
+}
+
+/* Check if the given string is filename or nickname of a certificate. If the
+ * given string is recognized as filename, return NULL. If the given string is
+ * recognized as nickname, return a duplicated string. The returned string
+ * should be later deallocated using free(). If the OOM failure occurs, we
+ * return NULL, too.
+ */
+static char* dup_nickname(struct SessionHandle *data, enum dupstring cert_kind)
+{
+ const char *str = data->set.str[cert_kind];
+ const char *n;
+
+ if(!is_file(str))
+ /* no such file exists, use the string as nickname */
+ return strdup(str);
+
+ /* search the last slash; we require at least one slash in a file name */
+ n = strrchr(str, '/');
+ if(!n) {
+ infof(data, "warning: certificate file name \"%s\" handled as nickname; "
+ "please use \"./%s\" to force file name\n", str, str);
+ return strdup(str);
+ }
+
+ /* we'll use the PEM reader to read the certificate from file */
+ return NULL;
+}
+
+/* Call PK11_CreateGenericObject() with the given obj_class and filename. If
+ * the call succeeds, append the object handle to the list of objects so that
+ * the object can be destroyed in Curl_nss_close(). */
+static CURLcode nss_create_object(struct ssl_connect_data *ssl,
+ CK_OBJECT_CLASS obj_class,
+ const char *filename, bool cacert)
+{
+ PK11SlotInfo *slot;
+ PK11GenericObject *obj;
+ CK_BBOOL cktrue = CK_TRUE;
+ CK_BBOOL ckfalse = CK_FALSE;
+ CK_ATTRIBUTE attrs[/* max count of attributes */ 4];
+ int attr_cnt = 0;
+ CURLcode result = (cacert)
+ ? CURLE_SSL_CACERT_BADFILE
+ : CURLE_SSL_CERTPROBLEM;
+
+ const int slot_id = (cacert) ? 0 : 1;
+ char *slot_name = aprintf("PEM Token #%d", slot_id);
+ if(!slot_name)
+ return CURLE_OUT_OF_MEMORY;
+
+ slot = PK11_FindSlotByName(slot_name);
+ free(slot_name);
+ if(!slot)
+ return result;
+
+ PK11_SETATTRS(attrs, attr_cnt, CKA_CLASS, &obj_class, sizeof(obj_class));
+ PK11_SETATTRS(attrs, attr_cnt, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL));
+ PK11_SETATTRS(attrs, attr_cnt, CKA_LABEL, (unsigned char *)filename,
+ strlen(filename) + 1);
+
+ if(CKO_CERTIFICATE == obj_class) {
+ CK_BBOOL *pval = (cacert) ? (&cktrue) : (&ckfalse);
+ PK11_SETATTRS(attrs, attr_cnt, CKA_TRUST, pval, sizeof(*pval));
+ }
+
+ obj = PK11_CreateGenericObject(slot, attrs, attr_cnt, PR_FALSE);
+ PK11_FreeSlot(slot);
+ if(!obj)
+ return result;
+
+ if(!Curl_llist_insert_next(ssl->obj_list, ssl->obj_list->tail, obj)) {
+ PK11_DestroyGenericObject(obj);
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ if(!cacert && CKO_CERTIFICATE == obj_class)
+ /* store reference to a client certificate */
+ ssl->obj_clicert = obj;
+
+ return CURLE_OK;
+}
+
+/* Destroy the NSS object whose handle is given by ptr. This function is
+ * a callback of Curl_llist_alloc() used by Curl_llist_destroy() to destroy
+ * NSS objects in Curl_nss_close() */
+static void nss_destroy_object(void *user, void *ptr)
+{
+ PK11GenericObject *obj = (PK11GenericObject *)ptr;
+ (void) user;
+ PK11_DestroyGenericObject(obj);
+}
+
+/* same as nss_destroy_object() but for CRL items */
+static void nss_destroy_crl_item(void *user, void *ptr)
+{
+ SECItem *crl_der = (SECItem *)ptr;
+ (void) user;
+ SECITEM_FreeItem(crl_der, PR_TRUE);
+}
+
+static CURLcode nss_load_cert(struct ssl_connect_data *ssl,
+ const char *filename, PRBool cacert)
+{
+ CURLcode result = (cacert)
+ ? CURLE_SSL_CACERT_BADFILE
+ : CURLE_SSL_CERTPROBLEM;
+
+ /* libnsspem.so leaks memory if the requested file does not exist. For more
+ * details, go to <https://bugzilla.redhat.com/734760>. */
+ if(is_file(filename))
+ result = nss_create_object(ssl, CKO_CERTIFICATE, filename, cacert);
+
+ if(!result && !cacert) {
+ /* we have successfully loaded a client certificate */
+ CERTCertificate *cert;
+ char *nickname = NULL;
+ char *n = strrchr(filename, '/');
+ if(n)
+ n++;
+
+ /* The following undocumented magic helps to avoid a SIGSEGV on call
+ * of PK11_ReadRawAttribute() from SelectClientCert() when using an
+ * immature version of libnsspem.so. For more details, go to
+ * <https://bugzilla.redhat.com/733685>. */
+ nickname = aprintf("PEM Token #1:%s", n);
+ if(nickname) {
+ cert = PK11_FindCertFromNickname(nickname, NULL);
+ if(cert)
+ CERT_DestroyCertificate(cert);
+
+ free(nickname);
+ }
+ }
+
+ return result;
+}
+
+/* add given CRL to cache if it is not already there */
+static CURLcode nss_cache_crl(SECItem *crl_der)
+{
+ CERTCertDBHandle *db = CERT_GetDefaultCertDB();
+ CERTSignedCrl *crl = SEC_FindCrlByDERCert(db, crl_der, 0);
+ if(crl) {
+ /* CRL already cached */
+ SEC_DestroyCrl(crl);
+ SECITEM_FreeItem(crl_der, PR_TRUE);
+ return CURLE_OK;
+ }
+
+ /* acquire lock before call of CERT_CacheCRL() and accessing nss_crl_list */
+ PR_Lock(nss_crllock);
+
+ /* store the CRL item so that we can free it in Curl_nss_cleanup() */
+ if(!Curl_llist_insert_next(nss_crl_list, nss_crl_list->tail, crl_der)) {
+ SECITEM_FreeItem(crl_der, PR_TRUE);
+ PR_Unlock(nss_crllock);
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ if(SECSuccess != CERT_CacheCRL(db, crl_der)) {
+ /* unable to cache CRL */
+ PR_Unlock(nss_crllock);
+ return CURLE_SSL_CRL_BADFILE;
+ }
+
+ /* we need to clear session cache, so that the CRL could take effect */
+ SSL_ClearSessionCache();
+ PR_Unlock(nss_crllock);
+ return CURLE_OK;
+}
+
+static CURLcode nss_load_crl(const char* crlfilename)
+{
+ PRFileDesc *infile;
+ PRFileInfo info;
+ SECItem filedata = { 0, NULL, 0 };
+ SECItem *crl_der = NULL;
+ char *body;
+
+ infile = PR_Open(crlfilename, PR_RDONLY, 0);
+ if(!infile)
+ return CURLE_SSL_CRL_BADFILE;
+
+ if(PR_SUCCESS != PR_GetOpenFileInfo(infile, &info))
+ goto fail;
+
+ if(!SECITEM_AllocItem(NULL, &filedata, info.size + /* zero ended */ 1))
+ goto fail;
+
+ if(info.size != PR_Read(infile, filedata.data, info.size))
+ goto fail;
+
+ crl_der = SECITEM_AllocItem(NULL, NULL, 0U);
+ if(!crl_der)
+ goto fail;
+
+ /* place a trailing zero right after the visible data */
+ body = (char*)filedata.data;
+ body[--filedata.len] = '\0';
+
+ body = strstr(body, "-----BEGIN");
+ if(body) {
+ /* assume ASCII */
+ char *trailer;
+ char *begin = PORT_Strchr(body, '\n');
+ if(!begin)
+ begin = PORT_Strchr(body, '\r');
+ if(!begin)
+ goto fail;
+
+ trailer = strstr(++begin, "-----END");
+ if(!trailer)
+ goto fail;
+
+ /* retrieve DER from ASCII */
+ *trailer = '\0';
+ if(ATOB_ConvertAsciiToItem(crl_der, begin))
+ goto fail;
+
+ SECITEM_FreeItem(&filedata, PR_FALSE);
+ }
+ else
+ /* assume DER */
+ *crl_der = filedata;
+
+ PR_Close(infile);
+ return nss_cache_crl(crl_der);
+
+fail:
+ PR_Close(infile);
+ SECITEM_FreeItem(crl_der, PR_TRUE);
+ SECITEM_FreeItem(&filedata, PR_FALSE);
+ return CURLE_SSL_CRL_BADFILE;
+}
+
+static CURLcode nss_load_key(struct connectdata *conn, int sockindex,
+ char *key_file)
+{
+ PK11SlotInfo *slot;
+ SECStatus status;
+ CURLcode result;
+ struct ssl_connect_data *ssl = conn->ssl;
+
+ (void)sockindex; /* unused */
+
+ result = nss_create_object(ssl, CKO_PRIVATE_KEY, key_file, FALSE);
+ if(result) {
+ PR_SetError(SEC_ERROR_BAD_KEY, 0);
+ return result;
+ }
+
+ slot = PK11_FindSlotByName("PEM Token #1");
+ if(!slot)
+ return CURLE_SSL_CERTPROBLEM;
+
+ /* This will force the token to be seen as re-inserted */
+ SECMOD_WaitForAnyTokenEvent(mod, 0, 0);
+ PK11_IsPresent(slot);
+
+ status = PK11_Authenticate(slot, PR_TRUE,
+ conn->data->set.str[STRING_KEY_PASSWD]);
+ PK11_FreeSlot(slot);
+
+ return (SECSuccess == status) ? CURLE_OK : CURLE_SSL_CERTPROBLEM;
+}
+
+static int display_error(struct connectdata *conn, PRInt32 err,
+ const char *filename)
+{
+ switch(err) {
+ case SEC_ERROR_BAD_PASSWORD:
+ failf(conn->data, "Unable to load client key: Incorrect password");
+ return 1;
+ case SEC_ERROR_UNKNOWN_CERT:
+ failf(conn->data, "Unable to load certificate %s", filename);
+ return 1;
+ default:
+ break;
+ }
+ return 0; /* The caller will print a generic error */
+}
+
+static CURLcode cert_stuff(struct connectdata *conn, int sockindex,
+ char *cert_file, char *key_file)
+{
+ struct SessionHandle *data = conn->data;
+ CURLcode result;
+
+ if(cert_file) {
+ result = nss_load_cert(&conn->ssl[sockindex], cert_file, PR_FALSE);
+ if(result) {
+ const PRErrorCode err = PR_GetError();
+ if(!display_error(conn, err, cert_file)) {
+ const char *err_name = nss_error_to_name(err);
+ failf(data, "unable to load client cert: %d (%s)", err, err_name);
+ }
+
+ return result;
+ }
+ }
+
+ if(key_file || (is_file(cert_file))) {
+ if(key_file)
+ result = nss_load_key(conn, sockindex, key_file);
+ else
+ /* In case the cert file also has the key */
+ result = nss_load_key(conn, sockindex, cert_file);
+ if(result) {
+ const PRErrorCode err = PR_GetError();
+ if(!display_error(conn, err, key_file)) {
+ const char *err_name = nss_error_to_name(err);
+ failf(data, "unable to load client key: %d (%s)", err, err_name);
+ }
+
+ return result;
+ }
+ }
+
+ return CURLE_OK;
+}
+
+static char * nss_get_password(PK11SlotInfo * slot, PRBool retry, void *arg)
+{
+ (void)slot; /* unused */
+
+ if(retry || NULL == arg)
+ return NULL;
+ else
+ return (char *)PORT_Strdup((char *)arg);
+}
+
+/* bypass the default SSL_AuthCertificate() hook in case we do not want to
+ * verify peer */
+static SECStatus nss_auth_cert_hook(void *arg, PRFileDesc *fd, PRBool checksig,
+ PRBool isServer)
+{
+ struct connectdata *conn = (struct connectdata *)arg;
+
+#ifdef SSL_ENABLE_OCSP_STAPLING
+ if(conn->data->set.ssl.verifystatus) {
+ SECStatus cacheResult;
+
+ const SECItemArray *csa = SSL_PeerStapledOCSPResponses(fd);
+ if(!csa) {
+ failf(conn->data, "Invalid OCSP response");
+ return SECFailure;
+ }
+
+ if(csa->len == 0) {
+ failf(conn->data, "No OCSP response received");
+ return SECFailure;
+ }
+
+ cacheResult = CERT_CacheOCSPResponseFromSideChannel(
+ CERT_GetDefaultCertDB(), SSL_PeerCertificate(fd),
+ PR_Now(), &csa->items[0], arg
+ );
+
+ if(cacheResult != SECSuccess) {
+ failf(conn->data, "Invalid OCSP response");
+ return cacheResult;
+ }
+ }
+#endif
+
+ if(!conn->data->set.ssl.verifypeer) {
+ infof(conn->data, "skipping SSL peer certificate verification\n");
+ return SECSuccess;
+ }
+
+ return SSL_AuthCertificate(CERT_GetDefaultCertDB(), fd, checksig, isServer);
+}
+
+/**
+ * Inform the application that the handshake is complete.
+ */
+static void HandshakeCallback(PRFileDesc *sock, void *arg)
+{
+ struct connectdata *conn = (struct connectdata*) arg;
+ unsigned int buflenmax = 50;
+ unsigned char buf[50];
+ unsigned int buflen;
+ SSLNextProtoState state;
+
+ if(!conn->data->set.ssl_enable_npn && !conn->data->set.ssl_enable_alpn) {
+ return;
+ }
+
+ if(SSL_GetNextProto(sock, &state, buf, &buflen, buflenmax) == SECSuccess) {
+
+ switch(state) {
+ case SSL_NEXT_PROTO_NO_SUPPORT:
+ case SSL_NEXT_PROTO_NO_OVERLAP:
+ infof(conn->data, "ALPN/NPN, server did not agree to a protocol\n");
+ return;
+#ifdef SSL_ENABLE_ALPN
+ case SSL_NEXT_PROTO_SELECTED:
+ infof(conn->data, "ALPN, server accepted to use %.*s\n", buflen, buf);
+ break;
+#endif
+ case SSL_NEXT_PROTO_NEGOTIATED:
+ infof(conn->data, "NPN, server accepted to use %.*s\n", buflen, buf);
+ break;
+ }
+
+#ifdef USE_NGHTTP2
+ if(buflen == NGHTTP2_PROTO_VERSION_ID_LEN &&
+ !memcmp(NGHTTP2_PROTO_VERSION_ID, buf, NGHTTP2_PROTO_VERSION_ID_LEN)) {
+ conn->negnpn = CURL_HTTP_VERSION_2_0;
+ }
+ else
+#endif
+ if(buflen == ALPN_HTTP_1_1_LENGTH &&
+ !memcmp(ALPN_HTTP_1_1, buf, ALPN_HTTP_1_1_LENGTH)) {
+ conn->negnpn = CURL_HTTP_VERSION_1_1;
+ }
+ }
+}
+
+#if NSSVERNUM >= 0x030f04 /* 3.15.4 */
+static SECStatus CanFalseStartCallback(PRFileDesc *sock, void *client_data,
+ PRBool *canFalseStart)
+{
+ struct connectdata *conn = client_data;
+ struct SessionHandle *data = conn->data;
+
+ SSLChannelInfo channelInfo;
+ SSLCipherSuiteInfo cipherInfo;
+
+ SECStatus rv;
+ PRBool negotiatedExtension;
+
+ *canFalseStart = PR_FALSE;
+
+ if(SSL_GetChannelInfo(sock, &channelInfo, sizeof(channelInfo)) != SECSuccess)
+ return SECFailure;
+
+ if(SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo,
+ sizeof(cipherInfo)) != SECSuccess)
+ return SECFailure;
+
+ /* Prevent version downgrade attacks from TLS 1.2, and avoid False Start for
+ * TLS 1.3 and later. See https://bugzilla.mozilla.org/show_bug.cgi?id=861310
+ */
+ if(channelInfo.protocolVersion != SSL_LIBRARY_VERSION_TLS_1_2)
+ goto end;
+
+ /* Only allow ECDHE key exchange algorithm.
+ * See https://bugzilla.mozilla.org/show_bug.cgi?id=952863 */
+ if(cipherInfo.keaType != ssl_kea_ecdh)
+ goto end;
+
+ /* Prevent downgrade attacks on the symmetric cipher. We do not allow CBC
+ * mode due to BEAST, POODLE, and other attacks on the MAC-then-Encrypt
+ * design. See https://bugzilla.mozilla.org/show_bug.cgi?id=1109766 */
+ if(cipherInfo.symCipher != ssl_calg_aes_gcm)
+ goto end;
+
+ /* Enforce ALPN or NPN to do False Start, as an indicator of server
+ * compatibility. */
+ rv = SSL_HandshakeNegotiatedExtension(sock, ssl_app_layer_protocol_xtn,
+ &negotiatedExtension);
+ if(rv != SECSuccess || !negotiatedExtension) {
+ rv = SSL_HandshakeNegotiatedExtension(sock, ssl_next_proto_nego_xtn,
+ &negotiatedExtension);
+ }
+
+ if(rv != SECSuccess || !negotiatedExtension)
+ goto end;
+
+ *canFalseStart = PR_TRUE;
+
+ infof(data, "Trying TLS False Start\n");
+
+end:
+ return SECSuccess;
+}
+#endif
+
+static void display_cert_info(struct SessionHandle *data,
+ CERTCertificate *cert)
+{
+ char *subject, *issuer, *common_name;
+ PRExplodedTime printableTime;
+ char timeString[256];
+ PRTime notBefore, notAfter;
+
+ subject = CERT_NameToAscii(&cert->subject);
+ issuer = CERT_NameToAscii(&cert->issuer);
+ common_name = CERT_GetCommonName(&cert->subject);
+ infof(data, "\tsubject: %s\n", subject);
+
+ CERT_GetCertTimes(cert, &notBefore, &notAfter);
+ PR_ExplodeTime(notBefore, PR_GMTParameters, &printableTime);
+ PR_FormatTime(timeString, 256, "%b %d %H:%M:%S %Y GMT", &printableTime);
+ infof(data, "\tstart date: %s\n", timeString);
+ PR_ExplodeTime(notAfter, PR_GMTParameters, &printableTime);
+ PR_FormatTime(timeString, 256, "%b %d %H:%M:%S %Y GMT", &printableTime);
+ infof(data, "\texpire date: %s\n", timeString);
+ infof(data, "\tcommon name: %s\n", common_name);
+ infof(data, "\tissuer: %s\n", issuer);
+
+ PR_Free(subject);
+ PR_Free(issuer);
+ PR_Free(common_name);
+}
+
+static CURLcode display_conn_info(struct connectdata *conn, PRFileDesc *sock)
+{
+ CURLcode result = CURLE_OK;
+ SSLChannelInfo channel;
+ SSLCipherSuiteInfo suite;
+ CERTCertificate *cert;
+ CERTCertificate *cert2;
+ CERTCertificate *cert3;
+ PRTime now;
+ int i;
+
+ if(SSL_GetChannelInfo(sock, &channel, sizeof channel) ==
+ SECSuccess && channel.length == sizeof channel &&
+ channel.cipherSuite) {
+ if(SSL_GetCipherSuiteInfo(channel.cipherSuite,
+ &suite, sizeof suite) == SECSuccess) {
+ infof(conn->data, "SSL connection using %s\n", suite.cipherSuiteName);
+ }
+ }
+
+ cert = SSL_PeerCertificate(sock);
+ if(cert) {
+ infof(conn->data, "Server certificate:\n");
+
+ if(!conn->data->set.ssl.certinfo) {
+ display_cert_info(conn->data, cert);
+ CERT_DestroyCertificate(cert);
+ }
+ else {
+ /* Count certificates in chain. */
+ now = PR_Now();
+ i = 1;
+ if(!cert->isRoot) {
+ cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA);
+ while(cert2) {
+ i++;
+ if(cert2->isRoot) {
+ CERT_DestroyCertificate(cert2);
+ break;
+ }
+ cert3 = CERT_FindCertIssuer(cert2, now, certUsageSSLCA);
+ CERT_DestroyCertificate(cert2);
+ cert2 = cert3;
+ }
+ }
+
+ result = Curl_ssl_init_certinfo(conn->data, i);
+ if(!result) {
+ for(i = 0; cert; cert = cert2) {
+ result = Curl_extract_certinfo(conn, i++, (char *)cert->derCert.data,
+ (char *)cert->derCert.data +
+ cert->derCert.len);
+ if(result)
+ break;
+
+ if(cert->isRoot) {
+ CERT_DestroyCertificate(cert);
+ break;
+ }
+
+ cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA);
+ CERT_DestroyCertificate(cert);
+ }
+ }
+ }
+ }
+
+ return result;
+}
+
+static SECStatus BadCertHandler(void *arg, PRFileDesc *sock)
+{
+ struct connectdata *conn = (struct connectdata *)arg;
+ struct SessionHandle *data = conn->data;
+ PRErrorCode err = PR_GetError();
+ CERTCertificate *cert;
+
+ /* remember the cert verification result */
+ data->set.ssl.certverifyresult = err;
+
+ if(err == SSL_ERROR_BAD_CERT_DOMAIN && !data->set.ssl.verifyhost)
+ /* we are asked not to verify the host name */
+ return SECSuccess;
+
+ /* print only info about the cert, the error is printed off the callback */
+ cert = SSL_PeerCertificate(sock);
+ if(cert) {
+ infof(data, "Server certificate:\n");
+ display_cert_info(data, cert);
+ CERT_DestroyCertificate(cert);
+ }
+
+ return SECFailure;
+}
+
+/**
+ *
+ * Check that the Peer certificate's issuer certificate matches the one found
+ * by issuer_nickname. This is not exactly the way OpenSSL and GNU TLS do the
+ * issuer check, so we provide comments that mimic the OpenSSL
+ * X509_check_issued function (in x509v3/v3_purp.c)
+ */
+static SECStatus check_issuer_cert(PRFileDesc *sock,
+ char *issuer_nickname)
+{
+ CERTCertificate *cert, *cert_issuer, *issuer;
+ SECStatus res=SECSuccess;
+ void *proto_win = NULL;
+
+ /*
+ PRArenaPool *tmpArena = NULL;
+ CERTAuthKeyID *authorityKeyID = NULL;
+ SECITEM *caname = NULL;
+ */
+
+ cert = SSL_PeerCertificate(sock);
+ cert_issuer = CERT_FindCertIssuer(cert, PR_Now(), certUsageObjectSigner);
+
+ proto_win = SSL_RevealPinArg(sock);
+ issuer = PK11_FindCertFromNickname(issuer_nickname, proto_win);
+
+ if((!cert_issuer) || (!issuer))
+ res = SECFailure;
+ else if(SECITEM_CompareItem(&cert_issuer->derCert,
+ &issuer->derCert)!=SECEqual)
+ res = SECFailure;
+
+ CERT_DestroyCertificate(cert);
+ CERT_DestroyCertificate(issuer);
+ CERT_DestroyCertificate(cert_issuer);
+ return res;
+}
+
+static CURLcode cmp_peer_pubkey(struct ssl_connect_data *connssl,
+ const char *pinnedpubkey)
+{
+ CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+ struct SessionHandle *data = connssl->data;
+ CERTCertificate *cert;
+
+ if(!pinnedpubkey)
+ /* no pinned public key specified */
+ return CURLE_OK;
+
+ /* get peer certificate */
+ cert = SSL_PeerCertificate(connssl->handle);
+ if(cert) {
+ /* extract public key from peer certificate */
+ SECKEYPublicKey *pubkey = CERT_ExtractPublicKey(cert);
+ if(pubkey) {
+ /* encode the public key as DER */
+ SECItem *cert_der = PK11_DEREncodePublicKey(pubkey);
+ if(cert_der) {
+ /* compare the public key with the pinned public key */
+ result = Curl_pin_peer_pubkey(pinnedpubkey,
+ cert_der->data,
+ cert_der->len);
+ SECITEM_FreeItem(cert_der, PR_TRUE);
+ }
+ SECKEY_DestroyPublicKey(pubkey);
+ }
+ CERT_DestroyCertificate(cert);
+ }
+
+ /* report the resulting status */
+ switch(result) {
+ case CURLE_OK:
+ infof(data, "pinned public key verified successfully!\n");
+ break;
+ case CURLE_SSL_PINNEDPUBKEYNOTMATCH:
+ failf(data, "failed to verify pinned public key");
+ break;
+ default:
+ /* OOM, etc. */
+ break;
+ }
+
+ return result;
+}
+
+/**
+ *
+ * Callback to pick the SSL client certificate.
+ */
+static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
+ struct CERTDistNamesStr *caNames,
+ struct CERTCertificateStr **pRetCert,
+ struct SECKEYPrivateKeyStr **pRetKey)
+{
+ struct ssl_connect_data *connssl = (struct ssl_connect_data *)arg;
+ struct SessionHandle *data = connssl->data;
+ const char *nickname = connssl->client_nickname;
+
+ if(connssl->obj_clicert) {
+ /* use the cert/key provided by PEM reader */
+ static const char pem_slotname[] = "PEM Token #1";
+ SECItem cert_der = { 0, NULL, 0 };
+ void *proto_win = SSL_RevealPinArg(sock);
+ struct CERTCertificateStr *cert;
+ struct SECKEYPrivateKeyStr *key;
+
+ PK11SlotInfo *slot = PK11_FindSlotByName(pem_slotname);
+ if(NULL == slot) {
+ failf(data, "NSS: PK11 slot not found: %s", pem_slotname);
+ return SECFailure;
+ }
+
+ if(PK11_ReadRawAttribute(PK11_TypeGeneric, connssl->obj_clicert, CKA_VALUE,
+ &cert_der) != SECSuccess) {
+ failf(data, "NSS: CKA_VALUE not found in PK11 generic object");
+ PK11_FreeSlot(slot);
+ return SECFailure;
+ }
+
+ cert = PK11_FindCertFromDERCertItem(slot, &cert_der, proto_win);
+ SECITEM_FreeItem(&cert_der, PR_FALSE);
+ if(NULL == cert) {
+ failf(data, "NSS: client certificate from file not found");
+ PK11_FreeSlot(slot);
+ return SECFailure;
+ }
+
+ key = PK11_FindPrivateKeyFromCert(slot, cert, NULL);
+ PK11_FreeSlot(slot);
+ if(NULL == key) {
+ failf(data, "NSS: private key from file not found");
+ CERT_DestroyCertificate(cert);
+ return SECFailure;
+ }
+
+ infof(data, "NSS: client certificate from file\n");
+ display_cert_info(data, cert);
+
+ *pRetCert = cert;
+ *pRetKey = key;
+ return SECSuccess;
+ }
+
+ /* use the default NSS hook */
+ if(SECSuccess != NSS_GetClientAuthData((void *)nickname, sock, caNames,
+ pRetCert, pRetKey)
+ || NULL == *pRetCert) {
+
+ if(NULL == nickname)
+ failf(data, "NSS: client certificate not found (nickname not "
+ "specified)");
+ else
+ failf(data, "NSS: client certificate not found: %s", nickname);
+
+ return SECFailure;
+ }
+
+ /* get certificate nickname if any */
+ nickname = (*pRetCert)->nickname;
+ if(NULL == nickname)
+ nickname = "[unknown]";
+
+ if(NULL == *pRetKey) {
+ failf(data, "NSS: private key not found for certificate: %s", nickname);
+ return SECFailure;
+ }
+
+ infof(data, "NSS: using client certificate: %s\n", nickname);
+ display_cert_info(data, *pRetCert);
+ return SECSuccess;
+}
+
+/* update blocking direction in case of PR_WOULD_BLOCK_ERROR */
+static void nss_update_connecting_state(ssl_connect_state state, void *secret)
+{
+ struct ssl_connect_data *connssl = (struct ssl_connect_data *)secret;
+ if(PR_GetError() != PR_WOULD_BLOCK_ERROR)
+ /* an unrelated error is passing by */
+ return;
+
+ switch(connssl->connecting_state) {
+ case ssl_connect_2:
+ case ssl_connect_2_reading:
+ case ssl_connect_2_writing:
+ break;
+ default:
+ /* we are not called from an SSL handshake */
+ return;
+ }
+
+ /* update the state accordingly */
+ connssl->connecting_state = state;
+}
+
+/* recv() wrapper we use to detect blocking direction during SSL handshake */
+static PRInt32 nspr_io_recv(PRFileDesc *fd, void *buf, PRInt32 amount,
+ PRIntn flags, PRIntervalTime timeout)
+{
+ const PRRecvFN recv_fn = fd->lower->methods->recv;
+ const PRInt32 rv = recv_fn(fd->lower, buf, amount, flags, timeout);
+ if(rv < 0)
+ /* check for PR_WOULD_BLOCK_ERROR and update blocking direction */
+ nss_update_connecting_state(ssl_connect_2_reading, fd->secret);
+ return rv;
+}
+
+/* send() wrapper we use to detect blocking direction during SSL handshake */
+static PRInt32 nspr_io_send(PRFileDesc *fd, const void *buf, PRInt32 amount,
+ PRIntn flags, PRIntervalTime timeout)
+{
+ const PRSendFN send_fn = fd->lower->methods->send;
+ const PRInt32 rv = send_fn(fd->lower, buf, amount, flags, timeout);
+ if(rv < 0)
+ /* check for PR_WOULD_BLOCK_ERROR and update blocking direction */
+ nss_update_connecting_state(ssl_connect_2_writing, fd->secret);
+ return rv;
+}
+
+/* close() wrapper to avoid assertion failure due to fd->secret != NULL */
+static PRStatus nspr_io_close(PRFileDesc *fd)
+{
+ const PRCloseFN close_fn = PR_GetDefaultIOMethods()->close;
+ fd->secret = NULL;
+ return close_fn(fd);
+}
+
+/* data might be NULL */
+static CURLcode nss_init_core(struct SessionHandle *data, const char *cert_dir)
+{
+ NSSInitParameters initparams;
+
+ if(nss_context != NULL)
+ return CURLE_OK;
+
+ memset((void *) &initparams, '\0', sizeof(initparams));
+ initparams.length = sizeof(initparams);
+
+ if(cert_dir) {
+ char *certpath = aprintf("sql:%s", cert_dir);
+ if(!certpath)
+ return CURLE_OUT_OF_MEMORY;
+
+ infof(data, "Initializing NSS with certpath: %s\n", certpath);
+ nss_context = NSS_InitContext(certpath, "", "", "", &initparams,
+ NSS_INIT_READONLY | NSS_INIT_PK11RELOAD);
+ free(certpath);
+
+ if(nss_context != NULL)
+ return CURLE_OK;
+
+ infof(data, "Unable to initialize NSS database\n");
+ }
+
+ infof(data, "Initializing NSS with certpath: none\n");
+ nss_context = NSS_InitContext("", "", "", "", &initparams, NSS_INIT_READONLY
+ | NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB | NSS_INIT_FORCEOPEN
+ | NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD);
+ if(nss_context != NULL)
+ return CURLE_OK;
+
+ infof(data, "Unable to initialize NSS\n");
+ return CURLE_SSL_CACERT_BADFILE;
+}
+
+/* data might be NULL */
+static CURLcode nss_init(struct SessionHandle *data)
+{
+ char *cert_dir;
+ struct_stat st;
+ CURLcode result;
+
+ if(initialized)
+ return CURLE_OK;
+
+ /* list of all CRL items we need to destroy in Curl_nss_cleanup() */
+ nss_crl_list = Curl_llist_alloc(nss_destroy_crl_item);
+ if(!nss_crl_list)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* First we check if $SSL_DIR points to a valid dir */
+ cert_dir = getenv("SSL_DIR");
+ if(cert_dir) {
+ if((stat(cert_dir, &st) != 0) ||
+ (!S_ISDIR(st.st_mode))) {
+ cert_dir = NULL;
+ }
+ }
+
+ /* Now we check if the default location is a valid dir */
+ if(!cert_dir) {
+ if((stat(SSL_DIR, &st) == 0) &&
+ (S_ISDIR(st.st_mode))) {
+ cert_dir = (char *)SSL_DIR;
+ }
+ }
+
+ if(nspr_io_identity == PR_INVALID_IO_LAYER) {
+ /* allocate an identity for our own NSPR I/O layer */
+ nspr_io_identity = PR_GetUniqueIdentity("libcurl");
+ if(nspr_io_identity == PR_INVALID_IO_LAYER)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* the default methods just call down to the lower I/O layer */
+ memcpy(&nspr_io_methods, PR_GetDefaultIOMethods(), sizeof nspr_io_methods);
+
+ /* override certain methods in the table by our wrappers */
+ nspr_io_methods.recv = nspr_io_recv;
+ nspr_io_methods.send = nspr_io_send;
+ nspr_io_methods.close = nspr_io_close;
+ }
+
+ result = nss_init_core(data, cert_dir);
+ if(result)
+ return result;
+
+ if(num_enabled_ciphers() == 0)
+ NSS_SetDomesticPolicy();
+
+ initialized = 1;
+
+ return CURLE_OK;
+}
+
+/**
+ * Global SSL init
+ *
+ * @retval 0 error initializing SSL
+ * @retval 1 SSL initialized successfully
+ */
+int Curl_nss_init(void)
+{
+ /* curl_global_init() is not thread-safe so this test is ok */
+ if(nss_initlock == NULL) {
+ PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 256);
+ nss_initlock = PR_NewLock();
+ nss_crllock = PR_NewLock();
+ }
+
+ /* We will actually initialize NSS later */
+
+ return 1;
+}
+
+/* data might be NULL */
+CURLcode Curl_nss_force_init(struct SessionHandle *data)
+{
+ CURLcode result;
+ if(!nss_initlock) {
+ if(data)
+ failf(data, "unable to initialize NSS, curl_global_init() should have "
+ "been called with CURL_GLOBAL_SSL or CURL_GLOBAL_ALL");
+ return CURLE_FAILED_INIT;
+ }
+
+ PR_Lock(nss_initlock);
+ result = nss_init(data);
+ PR_Unlock(nss_initlock);
+
+ return result;
+}
+
+/* Global cleanup */
+void Curl_nss_cleanup(void)
+{
+ /* This function isn't required to be threadsafe and this is only done
+ * as a safety feature.
+ */
+ PR_Lock(nss_initlock);
+ if(initialized) {
+ /* Free references to client certificates held in the SSL session cache.
+ * Omitting this hampers destruction of the security module owning
+ * the certificates. */
+ SSL_ClearSessionCache();
+
+ if(mod && SECSuccess == SECMOD_UnloadUserModule(mod)) {
+ SECMOD_DestroyModule(mod);
+ mod = NULL;
+ }
+ NSS_ShutdownContext(nss_context);
+ nss_context = NULL;
+ }
+
+ /* destroy all CRL items */
+ Curl_llist_destroy(nss_crl_list, NULL);
+ nss_crl_list = NULL;
+
+ PR_Unlock(nss_initlock);
+
+ PR_DestroyLock(nss_initlock);
+ PR_DestroyLock(nss_crllock);
+ nss_initlock = NULL;
+
+ initialized = 0;
+}
+
+/*
+ * This function uses SSL_peek to determine connection status.
+ *
+ * Return codes:
+ * 1 means the connection is still in place
+ * 0 means the connection has been closed
+ * -1 means the connection status is unknown
+ */
+int
+Curl_nss_check_cxn(struct connectdata *conn)
+{
+ int rc;
+ char buf;
+
+ rc =
+ PR_Recv(conn->ssl[FIRSTSOCKET].handle, (void *)&buf, 1, PR_MSG_PEEK,
+ PR_SecondsToInterval(1));
+ if(rc > 0)
+ return 1; /* connection still in place */
+
+ if(rc == 0)
+ return 0; /* connection has been closed */
+
+ return -1; /* connection status unknown */
+}
+
+/*
+ * This function is called when an SSL connection is closed.
+ */
+void Curl_nss_close(struct connectdata *conn, int sockindex)
+{
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+ if(connssl->handle) {
+ /* NSS closes the socket we previously handed to it, so we must mark it
+ as closed to avoid double close */
+ fake_sclose(conn->sock[sockindex]);
+ conn->sock[sockindex] = CURL_SOCKET_BAD;
+
+ if((connssl->client_nickname != NULL) || (connssl->obj_clicert != NULL))
+ /* A server might require different authentication based on the
+ * particular path being requested by the client. To support this
+ * scenario, we must ensure that a connection will never reuse the
+ * authentication data from a previous connection. */
+ SSL_InvalidateSession(connssl->handle);
+
+ free(connssl->client_nickname);
+ connssl->client_nickname = NULL;
+ /* destroy all NSS objects in order to avoid failure of NSS shutdown */
+ Curl_llist_destroy(connssl->obj_list, NULL);
+ connssl->obj_list = NULL;
+ connssl->obj_clicert = NULL;
+
+ PR_Close(connssl->handle);
+ connssl->handle = NULL;
+ }
+}
+
+/* return true if NSS can provide error code (and possibly msg) for the
+ error */
+static bool is_nss_error(CURLcode err)
+{
+ switch(err) {
+ case CURLE_PEER_FAILED_VERIFICATION:
+ case CURLE_SSL_CACERT:
+ case CURLE_SSL_CERTPROBLEM:
+ case CURLE_SSL_CONNECT_ERROR:
+ case CURLE_SSL_ISSUER_ERROR:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+/* return true if the given error code is related to a client certificate */
+static bool is_cc_error(PRInt32 err)
+{
+ switch(err) {
+ case SSL_ERROR_BAD_CERT_ALERT:
+ case SSL_ERROR_EXPIRED_CERT_ALERT:
+ case SSL_ERROR_REVOKED_CERT_ALERT:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+static Curl_recv nss_recv;
+static Curl_send nss_send;
+
+static CURLcode nss_load_ca_certificates(struct connectdata *conn,
+ int sockindex)
+{
+ struct SessionHandle *data = conn->data;
+ const char *cafile = data->set.ssl.CAfile;
+ const char *capath = data->set.ssl.CApath;
+
+ if(cafile) {
+ CURLcode result = nss_load_cert(&conn->ssl[sockindex], cafile, PR_TRUE);
+ if(result)
+ return result;
+ }
+
+ if(capath) {
+ struct_stat st;
+ if(stat(capath, &st) == -1)
+ return CURLE_SSL_CACERT_BADFILE;
+
+ if(S_ISDIR(st.st_mode)) {
+ PRDirEntry *entry;
+ PRDir *dir = PR_OpenDir(capath);
+ if(!dir)
+ return CURLE_SSL_CACERT_BADFILE;
+
+ while((entry = PR_ReadDir(dir, PR_SKIP_BOTH | PR_SKIP_HIDDEN))) {
+ char *fullpath = aprintf("%s/%s", capath, entry->name);
+ if(!fullpath) {
+ PR_CloseDir(dir);
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ if(CURLE_OK != nss_load_cert(&conn->ssl[sockindex], fullpath, PR_TRUE))
+ /* This is purposefully tolerant of errors so non-PEM files can
+ * be in the same directory */
+ infof(data, "failed to load '%s' from CURLOPT_CAPATH\n", fullpath);
+
+ free(fullpath);
+ }
+
+ PR_CloseDir(dir);
+ }
+ else
+ infof(data, "warning: CURLOPT_CAPATH not a directory (%s)\n", capath);
+ }
+
+ infof(data, " CAfile: %s\n CApath: %s\n",
+ cafile ? cafile : "none",
+ capath ? capath : "none");
+
+ return CURLE_OK;
+}
+
+static CURLcode nss_init_sslver(SSLVersionRange *sslver,
+ struct SessionHandle *data)
+{
+ switch(data->set.ssl.version) {
+ default:
+ case CURL_SSLVERSION_DEFAULT:
+ case CURL_SSLVERSION_TLSv1:
+ sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
+#ifdef SSL_LIBRARY_VERSION_TLS_1_2
+ sslver->max = SSL_LIBRARY_VERSION_TLS_1_2;
+#elif defined SSL_LIBRARY_VERSION_TLS_1_1
+ sslver->max = SSL_LIBRARY_VERSION_TLS_1_1;
+#else
+ sslver->max = SSL_LIBRARY_VERSION_TLS_1_0;
+#endif
+ return CURLE_OK;
+
+ case CURL_SSLVERSION_SSLv2:
+ sslver->min = SSL_LIBRARY_VERSION_2;
+ sslver->max = SSL_LIBRARY_VERSION_2;
+ return CURLE_OK;
+
+ case CURL_SSLVERSION_SSLv3:
+ sslver->min = SSL_LIBRARY_VERSION_3_0;
+ sslver->max = SSL_LIBRARY_VERSION_3_0;
+ return CURLE_OK;
+
+ case CURL_SSLVERSION_TLSv1_0:
+ sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
+ sslver->max = SSL_LIBRARY_VERSION_TLS_1_0;
+ return CURLE_OK;
+
+ case CURL_SSLVERSION_TLSv1_1:
+#ifdef SSL_LIBRARY_VERSION_TLS_1_1
+ sslver->min = SSL_LIBRARY_VERSION_TLS_1_1;
+ sslver->max = SSL_LIBRARY_VERSION_TLS_1_1;
+ return CURLE_OK;
+#endif
+ break;
+
+ case CURL_SSLVERSION_TLSv1_2:
+#ifdef SSL_LIBRARY_VERSION_TLS_1_2
+ sslver->min = SSL_LIBRARY_VERSION_TLS_1_2;
+ sslver->max = SSL_LIBRARY_VERSION_TLS_1_2;
+ return CURLE_OK;
+#endif
+ break;
+ }
+
+ failf(data, "TLS minor version cannot be set");
+ return CURLE_SSL_CONNECT_ERROR;
+}
+
+static CURLcode nss_fail_connect(struct ssl_connect_data *connssl,
+ struct SessionHandle *data,
+ CURLcode curlerr)
+{
+ PRErrorCode err = 0;
+
+ if(is_nss_error(curlerr)) {
+ /* read NSPR error code */
+ err = PR_GetError();
+ if(is_cc_error(err))
+ curlerr = CURLE_SSL_CERTPROBLEM;
+
+ /* print the error number and error string */
+ infof(data, "NSS error %d (%s)\n", err, nss_error_to_name(err));
+
+ /* print a human-readable message describing the error if available */
+ nss_print_error_message(data, err);
+ }
+
+ /* cleanup on connection failure */
+ Curl_llist_destroy(connssl->obj_list, NULL);
+ connssl->obj_list = NULL;
+
+ return curlerr;
+}
+
+/* Switch the SSL socket into non-blocking mode. */
+static CURLcode nss_set_nonblock(struct ssl_connect_data *connssl,
+ struct SessionHandle *data)
+{
+ static PRSocketOptionData sock_opt;
+ sock_opt.option = PR_SockOpt_Nonblocking;
+ sock_opt.value.non_blocking = PR_TRUE;
+
+ if(PR_SetSocketOption(connssl->handle, &sock_opt) != PR_SUCCESS)
+ return nss_fail_connect(connssl, data, CURLE_SSL_CONNECT_ERROR);
+
+ return CURLE_OK;
+}
+
+static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
+{
+ PRFileDesc *model = NULL;
+ PRFileDesc *nspr_io = NULL;
+ PRFileDesc *nspr_io_stub = NULL;
+ PRBool ssl_no_cache;
+ PRBool ssl_cbc_random_iv;
+ struct SessionHandle *data = conn->data;
+ curl_socket_t sockfd = conn->sock[sockindex];
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ CURLcode result;
+
+ SSLVersionRange sslver = {
+ SSL_LIBRARY_VERSION_TLS_1_0, /* min */
+ SSL_LIBRARY_VERSION_TLS_1_0 /* max */
+ };
+
+ connssl->data = data;
+
+ /* list of all NSS objects we need to destroy in Curl_nss_close() */
+ connssl->obj_list = Curl_llist_alloc(nss_destroy_object);
+ if(!connssl->obj_list)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* FIXME. NSS doesn't support multiple databases open at the same time. */
+ PR_Lock(nss_initlock);
+ result = nss_init(conn->data);
+ if(result) {
+ PR_Unlock(nss_initlock);
+ goto error;
+ }
+
+ result = CURLE_SSL_CONNECT_ERROR;
+
+ if(!mod) {
+ char *configstring = aprintf("library=%s name=PEM", pem_library);
+ if(!configstring) {
+ PR_Unlock(nss_initlock);
+ goto error;
+ }
+ mod = SECMOD_LoadUserModule(configstring, NULL, PR_FALSE);
+ free(configstring);
+
+ if(!mod || !mod->loaded) {
+ if(mod) {
+ SECMOD_DestroyModule(mod);
+ mod = NULL;
+ }
+ infof(data, "WARNING: failed to load NSS PEM library %s. Using "
+ "OpenSSL PEM certificates will not work.\n", pem_library);
+ }
+ }
+
+ PK11_SetPasswordFunc(nss_get_password);
+ PR_Unlock(nss_initlock);
+
+ model = PR_NewTCPSocket();
+ if(!model)
+ goto error;
+ model = SSL_ImportFD(NULL, model);
+
+ if(SSL_OptionSet(model, SSL_SECURITY, PR_TRUE) != SECSuccess)
+ goto error;
+ if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_SERVER, PR_FALSE) != SECSuccess)
+ goto error;
+ if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE) != SECSuccess)
+ goto error;
+
+ /* do not use SSL cache if disabled or we are not going to verify peer */
+ ssl_no_cache = (conn->ssl_config.sessionid && data->set.ssl.verifypeer) ?
+ PR_FALSE : PR_TRUE;
+ if(SSL_OptionSet(model, SSL_NO_CACHE, ssl_no_cache) != SECSuccess)
+ goto error;
+
+ /* enable/disable the requested SSL version(s) */
+ if(nss_init_sslver(&sslver, data) != CURLE_OK)
+ goto error;
+ if(SSL_VersionRangeSet(model, &sslver) != SECSuccess)
+ goto error;
+
+ ssl_cbc_random_iv = !data->set.ssl_enable_beast;
+#ifdef SSL_CBC_RANDOM_IV
+ /* unless the user explicitly asks to allow the protocol vulnerability, we
+ use the work-around */
+ if(SSL_OptionSet(model, SSL_CBC_RANDOM_IV, ssl_cbc_random_iv) != SECSuccess)
+ infof(data, "warning: failed to set SSL_CBC_RANDOM_IV = %d\n",
+ ssl_cbc_random_iv);
+#else
+ if(ssl_cbc_random_iv)
+ infof(data, "warning: support for SSL_CBC_RANDOM_IV not compiled in\n");
+#endif
+
+ if(data->set.ssl.cipher_list) {
+ if(set_ciphers(data, model, data->set.ssl.cipher_list) != SECSuccess) {
+ result = CURLE_SSL_CIPHER;
+ goto error;
+ }
+ }
+
+ if(!data->set.ssl.verifypeer && data->set.ssl.verifyhost)
+ infof(data, "warning: ignoring value of ssl.verifyhost\n");
+
+ /* bypass the default SSL_AuthCertificate() hook in case we do not want to
+ * verify peer */
+ if(SSL_AuthCertificateHook(model, nss_auth_cert_hook, conn) != SECSuccess)
+ goto error;
+
+ data->set.ssl.certverifyresult=0; /* not checked yet */
+ if(SSL_BadCertHook(model, BadCertHandler, conn) != SECSuccess)
+ goto error;
+
+ if(SSL_HandshakeCallback(model, HandshakeCallback, conn) != SECSuccess)
+ goto error;
+
+ if(data->set.ssl.verifypeer) {
+ const CURLcode rv = nss_load_ca_certificates(conn, sockindex);
+ if(rv) {
+ result = rv;
+ goto error;
+ }
+ }
+
+ if(data->set.ssl.CRLfile) {
+ const CURLcode rv = nss_load_crl(data->set.ssl.CRLfile);
+ if(rv) {
+ result = rv;
+ goto error;
+ }
+ infof(data, " CRLfile: %s\n", data->set.ssl.CRLfile);
+ }
+
+ if(data->set.str[STRING_CERT]) {
+ char *nickname = dup_nickname(data, STRING_CERT);
+ if(nickname) {
+ /* we are not going to use libnsspem.so to read the client cert */
+ connssl->obj_clicert = NULL;
+ }
+ else {
+ CURLcode rv = cert_stuff(conn, sockindex, data->set.str[STRING_CERT],
+ data->set.str[STRING_KEY]);
+ if(rv) {
+ /* failf() is already done in cert_stuff() */
+ result = rv;
+ goto error;
+ }
+ }
+
+ /* store the nickname for SelectClientCert() called during handshake */
+ connssl->client_nickname = nickname;
+ }
+ else
+ connssl->client_nickname = NULL;
+
+ if(SSL_GetClientAuthDataHook(model, SelectClientCert,
+ (void *)connssl) != SECSuccess) {
+ result = CURLE_SSL_CERTPROBLEM;
+ goto error;
+ }
+
+ /* wrap OS file descriptor by NSPR's file descriptor abstraction */
+ nspr_io = PR_ImportTCPSocket(sockfd);
+ if(!nspr_io)
+ goto error;
+
+ /* create our own NSPR I/O layer */
+ nspr_io_stub = PR_CreateIOLayerStub(nspr_io_identity, &nspr_io_methods);
+ if(!nspr_io_stub) {
+ PR_Close(nspr_io);
+ goto error;
+ }
+
+ /* make the per-connection data accessible from NSPR I/O callbacks */
+ nspr_io_stub->secret = (void *)connssl;
+
+ /* push our new layer to the NSPR I/O stack */
+ if(PR_PushIOLayer(nspr_io, PR_TOP_IO_LAYER, nspr_io_stub) != PR_SUCCESS) {
+ PR_Close(nspr_io);
+ PR_Close(nspr_io_stub);
+ goto error;
+ }
+
+ /* import our model socket onto the current I/O stack */
+ connssl->handle = SSL_ImportFD(model, nspr_io);
+ if(!connssl->handle) {
+ PR_Close(nspr_io);
+ goto error;
+ }
+
+ PR_Close(model); /* We don't need this any more */
+ model = NULL;
+
+ /* This is the password associated with the cert that we're using */
+ if(data->set.str[STRING_KEY_PASSWD]) {
+ SSL_SetPKCS11PinArg(connssl->handle, data->set.str[STRING_KEY_PASSWD]);
+ }
+
+#ifdef SSL_ENABLE_OCSP_STAPLING
+ if(data->set.ssl.verifystatus) {
+ if(SSL_OptionSet(connssl->handle, SSL_ENABLE_OCSP_STAPLING, PR_TRUE)
+ != SECSuccess)
+ goto error;
+ }
+#endif
+
+#ifdef SSL_ENABLE_NPN
+ if(SSL_OptionSet(connssl->handle, SSL_ENABLE_NPN, data->set.ssl_enable_npn
+ ? PR_TRUE : PR_FALSE) != SECSuccess)
+ goto error;
+#endif
+
+#ifdef SSL_ENABLE_ALPN
+ if(SSL_OptionSet(connssl->handle, SSL_ENABLE_ALPN, data->set.ssl_enable_alpn
+ ? PR_TRUE : PR_FALSE) != SECSuccess)
+ goto error;
+#endif
+
+#if NSSVERNUM >= 0x030f04 /* 3.15.4 */
+ if(data->set.ssl.falsestart) {
+ if(SSL_OptionSet(connssl->handle, SSL_ENABLE_FALSE_START, PR_TRUE)
+ != SECSuccess)
+ goto error;
+
+ if(SSL_SetCanFalseStartCallback(connssl->handle, CanFalseStartCallback,
+ conn) != SECSuccess)
+ goto error;
+ }
+#endif
+
+#if defined(SSL_ENABLE_NPN) || defined(SSL_ENABLE_ALPN)
+ if(data->set.ssl_enable_npn || data->set.ssl_enable_alpn) {
+ int cur = 0;
+ unsigned char protocols[128];
+
+#ifdef USE_NGHTTP2
+ if(data->set.httpversion == CURL_HTTP_VERSION_2_0) {
+ protocols[cur++] = NGHTTP2_PROTO_VERSION_ID_LEN;
+ memcpy(&protocols[cur], NGHTTP2_PROTO_VERSION_ID,
+ NGHTTP2_PROTO_VERSION_ID_LEN);
+ cur += NGHTTP2_PROTO_VERSION_ID_LEN;
+ }
+#endif
+ protocols[cur++] = ALPN_HTTP_1_1_LENGTH;
+ memcpy(&protocols[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH);
+ cur += ALPN_HTTP_1_1_LENGTH;
+
+ if(SSL_SetNextProtoNego(connssl->handle, protocols, cur) != SECSuccess)
+ goto error;
+ }
+#endif
+
+
+ /* Force handshake on next I/O */
+ SSL_ResetHandshake(connssl->handle, /* asServer */ PR_FALSE);
+
+ SSL_SetURL(connssl->handle, conn->host.name);
+
+ return CURLE_OK;
+
+error:
+ if(model)
+ PR_Close(model);
+
+ return nss_fail_connect(connssl, data, result);
+}
+
+static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
+{
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct SessionHandle *data = conn->data;
+ CURLcode result = CURLE_SSL_CONNECT_ERROR;
+ PRUint32 timeout;
+
+ /* check timeout situation */
+ const long time_left = Curl_timeleft(data, NULL, TRUE);
+ if(time_left < 0L) {
+ failf(data, "timed out before SSL handshake");
+ result = CURLE_OPERATION_TIMEDOUT;
+ goto error;
+ }
+
+ /* Force the handshake now */
+ timeout = PR_MillisecondsToInterval((PRUint32) time_left);
+ if(SSL_ForceHandshakeWithTimeout(connssl->handle, timeout) != SECSuccess) {
+ if(PR_GetError() == PR_WOULD_BLOCK_ERROR)
+ /* blocking direction is updated by nss_update_connecting_state() */
+ return CURLE_AGAIN;
+ else if(conn->data->set.ssl.certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN)
+ result = CURLE_PEER_FAILED_VERIFICATION;
+ else if(conn->data->set.ssl.certverifyresult!=0)
+ result = CURLE_SSL_CACERT;
+ goto error;
+ }
+
+ result = display_conn_info(conn, connssl->handle);
+ if(result)
+ goto error;
+
+ if(data->set.str[STRING_SSL_ISSUERCERT]) {
+ SECStatus ret = SECFailure;
+ char *nickname = dup_nickname(data, STRING_SSL_ISSUERCERT);
+ if(nickname) {
+ /* we support only nicknames in case of STRING_SSL_ISSUERCERT for now */
+ ret = check_issuer_cert(connssl->handle, nickname);
+ free(nickname);
+ }
+
+ if(SECFailure == ret) {
+ infof(data, "SSL certificate issuer check failed\n");
+ result = CURLE_SSL_ISSUER_ERROR;
+ goto error;
+ }
+ else {
+ infof(data, "SSL certificate issuer check ok\n");
+ }
+ }
+
+ result = cmp_peer_pubkey(connssl, data->set.str[STRING_SSL_PINNEDPUBLICKEY]);
+ if(result)
+ /* status already printed */
+ goto error;
+
+ return CURLE_OK;
+
+error:
+ return nss_fail_connect(connssl, data, result);
+}
+
+static CURLcode nss_connect_common(struct connectdata *conn, int sockindex,
+ bool *done)
+{
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct SessionHandle *data = conn->data;
+ const bool blocking = (done == NULL);
+ CURLcode result;
+
+ if(connssl->state == ssl_connection_complete)
+ return CURLE_OK;
+
+ if(connssl->connecting_state == ssl_connect_1) {
+ result = nss_setup_connect(conn, sockindex);
+ if(result)
+ /* we do not expect CURLE_AGAIN from nss_setup_connect() */
+ return result;
+
+ if(!blocking) {
+ /* in non-blocking mode, set NSS non-blocking mode before handshake */
+ result = nss_set_nonblock(connssl, data);
+ if(result)
+ return result;
+ }
+
+ connssl->connecting_state = ssl_connect_2;
+ }
+
+ result = nss_do_connect(conn, sockindex);
+ switch(result) {
+ case CURLE_OK:
+ break;
+ case CURLE_AGAIN:
+ if(!blocking)
+ /* CURLE_AGAIN in non-blocking mode is not an error */
+ return CURLE_OK;
+ /* fall through */
+ default:
+ return result;
+ }
+
+ if(blocking) {
+ /* in blocking mode, set NSS non-blocking mode _after_ SSL handshake */
+ result = nss_set_nonblock(connssl, data);
+ if(result)
+ return result;
+ }
+ else
+ /* signal completed SSL handshake */
+ *done = TRUE;
+
+ connssl->state = ssl_connection_complete;
+ conn->recv[sockindex] = nss_recv;
+ conn->send[sockindex] = nss_send;
+
+ /* ssl_connect_done is never used outside, go back to the initial state */
+ connssl->connecting_state = ssl_connect_1;
+
+ return CURLE_OK;
+}
+
+CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
+{
+ return nss_connect_common(conn, sockindex, /* blocking */ NULL);
+}
+
+CURLcode Curl_nss_connect_nonblocking(struct connectdata *conn,
+ int sockindex, bool *done)
+{
+ return nss_connect_common(conn, sockindex, done);
+}
+
+static ssize_t nss_send(struct connectdata *conn, /* connection data */
+ int sockindex, /* socketindex */
+ const void *mem, /* send this data */
+ size_t len, /* amount to write */
+ CURLcode *curlcode)
+{
+ ssize_t rc = PR_Send(conn->ssl[sockindex].handle, mem, (int)len, 0,
+ PR_INTERVAL_NO_WAIT);
+ if(rc < 0) {
+ PRInt32 err = PR_GetError();
+ if(err == PR_WOULD_BLOCK_ERROR)
+ *curlcode = CURLE_AGAIN;
+ else {
+ /* print the error number and error string */
+ const char *err_name = nss_error_to_name(err);
+ infof(conn->data, "SSL write: error %d (%s)\n", err, err_name);
+
+ /* print a human-readable message describing the error if available */
+ nss_print_error_message(conn->data, err);
+
+ *curlcode = (is_cc_error(err))
+ ? CURLE_SSL_CERTPROBLEM
+ : CURLE_SEND_ERROR;
+ }
+
+ return -1;
+ }
+
+ return rc; /* number of bytes */
+}
+
+static ssize_t nss_recv(struct connectdata * conn, /* connection data */
+ int num, /* socketindex */
+ char *buf, /* store read data here */
+ size_t buffersize, /* max amount to read */
+ CURLcode *curlcode)
+{
+ ssize_t nread = PR_Recv(conn->ssl[num].handle, buf, (int)buffersize, 0,
+ PR_INTERVAL_NO_WAIT);
+ if(nread < 0) {
+ /* failed SSL read */
+ PRInt32 err = PR_GetError();
+
+ if(err == PR_WOULD_BLOCK_ERROR)
+ *curlcode = CURLE_AGAIN;
+ else {
+ /* print the error number and error string */
+ const char *err_name = nss_error_to_name(err);
+ infof(conn->data, "SSL read: errno %d (%s)\n", err, err_name);
+
+ /* print a human-readable message describing the error if available */
+ nss_print_error_message(conn->data, err);
+
+ *curlcode = (is_cc_error(err))
+ ? CURLE_SSL_CERTPROBLEM
+ : CURLE_RECV_ERROR;
+ }
+
+ return -1;
+ }
+
+ return nread;
+}
+
+size_t Curl_nss_version(char *buffer, size_t size)
+{
+ return snprintf(buffer, size, "NSS/%s", NSS_VERSION);
+}
+
+/* data might be NULL */
+int Curl_nss_seed(struct SessionHandle *data)
+{
+ /* make sure that NSS is initialized */
+ return !!Curl_nss_force_init(data);
+}
+
+/* data might be NULL */
+int Curl_nss_random(struct SessionHandle *data,
+ unsigned char *entropy,
+ size_t length)
+{
+ Curl_nss_seed(data); /* Initiate the seed if not already done */
+
+ if(SECSuccess != PK11_GenerateRandom(entropy, curlx_uztosi(length)))
+ /* signal a failure */
+ return -1;
+
+ return 0;
+}
+
+void Curl_nss_md5sum(unsigned char *tmp, /* input */
+ size_t tmplen,
+ unsigned char *md5sum, /* output */
+ size_t md5len)
+{
+ PK11Context *MD5pw = PK11_CreateDigestContext(SEC_OID_MD5);
+ unsigned int MD5out;
+
+ PK11_DigestOp(MD5pw, tmp, curlx_uztoui(tmplen));
+ PK11_DigestFinal(MD5pw, md5sum, &MD5out, curlx_uztoui(md5len));
+ PK11_DestroyContext(MD5pw, PR_TRUE);
+}
+
+void Curl_nss_sha256sum(const unsigned char *tmp, /* input */
+ size_t tmplen,
+ unsigned char *sha256sum, /* output */
+ size_t sha256len)
+{
+ PK11Context *SHA256pw = PK11_CreateDigestContext(SEC_OID_SHA256);
+ unsigned int SHA256out;
+
+ PK11_DigestOp(SHA256pw, tmp, curlx_uztoui(tmplen));
+ PK11_DigestFinal(SHA256pw, sha256sum, &SHA256out, curlx_uztoui(sha256len));
+ PK11_DestroyContext(SHA256pw, PR_TRUE);
+}
+
+bool Curl_nss_cert_status_request(void)
+{
+#ifdef SSL_ENABLE_OCSP_STAPLING
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+
+bool Curl_nss_false_start(void) {
+#if NSSVERNUM >= 0x030f04 /* 3.15.4 */
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+
+#endif /* USE_NSS */
diff --git a/Utilities/cmcurl/lib/vtls/nssg.h b/Utilities/cmcurl/lib/vtls/nssg.h
new file mode 100644
index 000000000..5fd72751d
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/nssg.h
@@ -0,0 +1,102 @@
+#ifndef HEADER_CURL_NSSG_H
+#define HEADER_CURL_NSSG_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef USE_NSS
+/*
+ * This header should only be needed to get included by vtls.c and nss.c
+ */
+
+#include "urldata.h"
+
+CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex);
+CURLcode Curl_nss_connect_nonblocking(struct connectdata *conn,
+ int sockindex,
+ bool *done);
+/* close a SSL connection */
+void Curl_nss_close(struct connectdata *conn, int sockindex);
+
+int Curl_nss_init(void);
+void Curl_nss_cleanup(void);
+
+size_t Curl_nss_version(char *buffer, size_t size);
+int Curl_nss_check_cxn(struct connectdata *cxn);
+int Curl_nss_seed(struct SessionHandle *data);
+
+/* initialize NSS library if not already */
+CURLcode Curl_nss_force_init(struct SessionHandle *data);
+
+int Curl_nss_random(struct SessionHandle *data,
+ unsigned char *entropy,
+ size_t length);
+
+void Curl_nss_md5sum(unsigned char *tmp, /* input */
+ size_t tmplen,
+ unsigned char *md5sum, /* output */
+ size_t md5len);
+
+void Curl_nss_sha256sum(const unsigned char *tmp, /* input */
+ size_t tmplen,
+ unsigned char *sha256sum, /* output */
+ size_t sha256len);
+
+bool Curl_nss_cert_status_request(void);
+
+bool Curl_nss_false_start(void);
+
+/* Set the API backend definition to NSS */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_NSS
+
+/* this backend supports the CAPATH option */
+#define have_curlssl_ca_path 1
+
+/* this backend supports CURLOPT_CERTINFO */
+#define have_curlssl_certinfo 1
+
+/* API setup for NSS */
+#define curlssl_init Curl_nss_init
+#define curlssl_cleanup Curl_nss_cleanup
+#define curlssl_connect Curl_nss_connect
+#define curlssl_connect_nonblocking Curl_nss_connect_nonblocking
+
+/* NSS has its own session ID cache */
+#define curlssl_session_free(x) Curl_nop_stmt
+#define curlssl_close_all(x) ((void)x)
+#define curlssl_close Curl_nss_close
+/* NSS has no shutdown function provided and thus always fail */
+#define curlssl_shutdown(x,y) ((void)x, (void)y, 1)
+#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN)
+#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN)
+#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL)
+#define curlssl_version Curl_nss_version
+#define curlssl_check_cxn(x) Curl_nss_check_cxn(x)
+#define curlssl_data_pending(x,y) ((void)x, (void)y, 0)
+#define curlssl_random(x,y,z) Curl_nss_random(x,y,z)
+#define curlssl_md5sum(a,b,c,d) Curl_nss_md5sum(a,b,c,d)
+#define curlssl_sha256sum(a,b,c,d) Curl_nss_sha256sum(a,b,c,d)
+#define curlssl_cert_status_request() Curl_nss_cert_status_request()
+#define curlssl_false_start() Curl_nss_false_start()
+
+#endif /* USE_NSS */
+#endif /* HEADER_CURL_NSSG_H */
diff --git a/Utilities/cmcurl/lib/vtls/openssl.c b/Utilities/cmcurl/lib/vtls/openssl.c
new file mode 100644
index 000000000..90e4c2b32
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/openssl.c
@@ -0,0 +1,3209 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all OpenSSL-specific code for the TLS/SSL layer. No code
+ * but vtls.c should ever call or use these functions.
+ */
+
+/*
+ * The original SSLeay-using code for curl was written by Linas Vepstas and
+ * Sampo Kellomaki 1998.
+ */
+
+#include "curl_setup.h"
+
+#ifdef USE_OPENSSL
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "formdata.h" /* for the boundary function */
+#include "url.h" /* for the ssl config check function */
+#include "inet_pton.h"
+#include "openssl.h"
+#include "connect.h"
+#include "slist.h"
+#include "strequal.h"
+#include "select.h"
+#include "vtls.h"
+#include "rawstr.h"
+#include "hostcheck.h"
+#include "curl_printf.h"
+
+#include <openssl/ssl.h>
+#include <openssl/rand.h>
+#include <openssl/x509v3.h>
+#include <openssl/dsa.h>
+#include <openssl/dh.h>
+#include <openssl/err.h>
+#include <openssl/md5.h>
+#include <openssl/conf.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+
+#ifdef HAVE_OPENSSL_PKCS12_H
+#include <openssl/pkcs12.h>
+#endif
+
+#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_IS_BORINGSSL)
+#include <openssl/ocsp.h>
+#endif
+
+#include "warnless.h"
+#include "non-ascii.h" /* for Curl_convert_from_utf8 prototype */
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#ifndef OPENSSL_VERSION_NUMBER
+#error "OPENSSL_VERSION_NUMBER not defined"
+#endif
+
+#if OPENSSL_VERSION_NUMBER >= 0x00907001L && !defined(OPENSSL_IS_BORINGSSL)
+/* ENGINE_load_private_key() takes four arguments */
+#define HAVE_ENGINE_LOAD_FOUR_ARGS
+#include <openssl/ui.h>
+#else
+/* ENGINE_load_private_key() takes three arguments */
+#undef HAVE_ENGINE_LOAD_FOUR_ARGS
+#endif
+
+#if (OPENSSL_VERSION_NUMBER >= 0x00903001L) && \
+ defined(HAVE_OPENSSL_PKCS12_H) && \
+ !defined(OPENSSL_IS_BORINGSSL)
+/* OpenSSL has PKCS 12 support, BoringSSL does not */
+#define HAVE_PKCS12_SUPPORT
+#else
+/* OpenSSL does not have PKCS12 support */
+#undef HAVE_PKCS12_SUPPORT
+#endif
+
+#if OPENSSL_VERSION_NUMBER >= 0x00909000L
+#define SSL_METHOD_QUAL const
+#else
+#define SSL_METHOD_QUAL
+#endif
+
+#if OPENSSL_VERSION_NUMBER >= 0x00907000L
+/* 0.9.6 didn't have X509_STORE_set_flags() */
+#define HAVE_X509_STORE_SET_FLAGS 1
+#else
+#define X509_STORE_set_flags(x,y) Curl_nop_stmt
+#endif
+
+#ifdef OPENSSL_IS_BORINGSSL
+/* BoringSSL has no ERR_remove_state() */
+#define ERR_remove_state(x)
+#elif (OPENSSL_VERSION_NUMBER >= 0x10000000L)
+#define HAVE_ERR_REMOVE_THREAD_STATE 1
+#endif
+
+#if !defined(HAVE_SSLV2_CLIENT_METHOD) || \
+ OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0+ has no SSLv2 */
+#undef OPENSSL_NO_SSL2 /* undef first to avoid compiler warnings */
+#define OPENSSL_NO_SSL2
+#endif
+
+#if defined(OPENSSL_IS_BORINGSSL)
+#define NO_RAND_SEED 1
+/* In BoringSSL OpenSSL_add_all_algorithms does nothing */
+#define OpenSSL_add_all_algorithms()
+/* BoringSSL does not have CONF_modules_load_file */
+#define CONF_modules_load_file(a,b,c)
+#endif
+
+#if (OPENSSL_VERSION_NUMBER < 0x0090808fL) || defined(OPENSSL_IS_BORINGSSL)
+/* not present in BoringSSL or older OpenSSL */
+#define OPENSSL_load_builtin_modules(x)
+#endif
+
+/*
+ * Number of bytes to read from the random number seed file. This must be
+ * a finite value (because some entropy "files" like /dev/urandom have
+ * an infinite length), but must be large enough to provide enough
+ * entopy to properly seed OpenSSL's PRNG.
+ */
+#define RAND_LOAD_LENGTH 1024
+
+static int passwd_callback(char *buf, int num, int encrypting,
+ void *global_passwd)
+{
+ DEBUGASSERT(0 == encrypting);
+
+ if(!encrypting) {
+ int klen = curlx_uztosi(strlen((char *)global_passwd));
+ if(num > klen) {
+ memcpy(buf, global_passwd, klen+1);
+ return klen;
+ }
+ }
+ return 0;
+}
+
+/*
+ * rand_enough() is a function that returns TRUE if we have seeded the random
+ * engine properly. We use some preprocessor magic to provide a seed_enough()
+ * macro to use, just to prevent a compiler warning on this function if we
+ * pass in an argument that is never used.
+ */
+
+#ifndef NO_RAND_SEED
+#ifdef HAVE_RAND_STATUS
+#define seed_enough(x) rand_enough()
+static bool rand_enough(void)
+{
+ return (0 != RAND_status()) ? TRUE : FALSE;
+}
+#else
+#define seed_enough(x) rand_enough(x)
+static bool rand_enough(int nread)
+{
+ /* this is a very silly decision to make */
+ return (nread > 500) ? TRUE : FALSE;
+}
+#endif
+
+static int ossl_seed(struct SessionHandle *data)
+{
+ char *buf = data->state.buffer; /* point to the big buffer */
+ int nread=0;
+
+ /* Q: should we add support for a random file name as a libcurl option?
+ A: Yes, it is here */
+
+#ifndef RANDOM_FILE
+ /* if RANDOM_FILE isn't defined, we only perform this if an option tells
+ us to! */
+ if(data->set.ssl.random_file)
+#define RANDOM_FILE "" /* doesn't matter won't be used */
+#endif
+ {
+ /* let the option override the define */
+ nread += RAND_load_file((data->set.str[STRING_SSL_RANDOM_FILE]?
+ data->set.str[STRING_SSL_RANDOM_FILE]:
+ RANDOM_FILE),
+ RAND_LOAD_LENGTH);
+ if(seed_enough(nread))
+ return nread;
+ }
+
+#if defined(HAVE_RAND_EGD)
+ /* only available in OpenSSL 0.9.5 and later */
+ /* EGD_SOCKET is set at configure time or not at all */
+#ifndef EGD_SOCKET
+ /* If we don't have the define set, we only do this if the egd-option
+ is set */
+ if(data->set.str[STRING_SSL_EGDSOCKET])
+#define EGD_SOCKET "" /* doesn't matter won't be used */
+#endif
+ {
+ /* If there's an option and a define, the option overrides the
+ define */
+ int ret = RAND_egd(data->set.str[STRING_SSL_EGDSOCKET]?
+ data->set.str[STRING_SSL_EGDSOCKET]:EGD_SOCKET);
+ if(-1 != ret) {
+ nread += ret;
+ if(seed_enough(nread))
+ return nread;
+ }
+ }
+#endif
+
+ /* If we get here, it means we need to seed the PRNG using a "silly"
+ approach! */
+ do {
+ unsigned char randb[64];
+ int len = sizeof(randb);
+ RAND_bytes(randb, len);
+ RAND_add(randb, len, (len >> 1));
+ } while(!RAND_status());
+
+ /* generates a default path for the random seed file */
+ buf[0]=0; /* blank it first */
+ RAND_file_name(buf, BUFSIZE);
+ if(buf[0]) {
+ /* we got a file name to try */
+ nread += RAND_load_file(buf, RAND_LOAD_LENGTH);
+ if(seed_enough(nread))
+ return nread;
+ }
+
+ infof(data, "libcurl is now using a weak random seed!\n");
+ return nread;
+}
+
+static void Curl_ossl_seed(struct SessionHandle *data)
+{
+ /* we have the "SSL is seeded" boolean static to prevent multiple
+ time-consuming seedings in vain */
+ static bool ssl_seeded = FALSE;
+
+ if(!ssl_seeded || data->set.str[STRING_SSL_RANDOM_FILE] ||
+ data->set.str[STRING_SSL_EGDSOCKET]) {
+ ossl_seed(data);
+ ssl_seeded = TRUE;
+ }
+}
+#else
+/* BoringSSL needs no seeding */
+#define Curl_ossl_seed(x)
+#endif
+
+
+#ifndef SSL_FILETYPE_ENGINE
+#define SSL_FILETYPE_ENGINE 42
+#endif
+#ifndef SSL_FILETYPE_PKCS12
+#define SSL_FILETYPE_PKCS12 43
+#endif
+static int do_file_type(const char *type)
+{
+ if(!type || !type[0])
+ return SSL_FILETYPE_PEM;
+ if(Curl_raw_equal(type, "PEM"))
+ return SSL_FILETYPE_PEM;
+ if(Curl_raw_equal(type, "DER"))
+ return SSL_FILETYPE_ASN1;
+ if(Curl_raw_equal(type, "ENG"))
+ return SSL_FILETYPE_ENGINE;
+ if(Curl_raw_equal(type, "P12"))
+ return SSL_FILETYPE_PKCS12;
+ return -1;
+}
+
+#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_LOAD_FOUR_ARGS)
+/*
+ * Supply default password to the engine user interface conversation.
+ * The password is passed by OpenSSL engine from ENGINE_load_private_key()
+ * last argument to the ui and can be obtained by UI_get0_user_data(ui) here.
+ */
+static int ssl_ui_reader(UI *ui, UI_STRING *uis)
+{
+ const char *password;
+ switch(UI_get_string_type(uis)) {
+ case UIT_PROMPT:
+ case UIT_VERIFY:
+ password = (const char*)UI_get0_user_data(ui);
+ if(password && (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD)) {
+ UI_set_result(ui, uis, password);
+ return 1;
+ }
+ default:
+ break;
+ }
+ return (UI_method_get_reader(UI_OpenSSL()))(ui, uis);
+}
+
+/*
+ * Suppress interactive request for a default password if available.
+ */
+static int ssl_ui_writer(UI *ui, UI_STRING *uis)
+{
+ switch(UI_get_string_type(uis)) {
+ case UIT_PROMPT:
+ case UIT_VERIFY:
+ if(UI_get0_user_data(ui) &&
+ (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD)) {
+ return 1;
+ }
+ default:
+ break;
+ }
+ return (UI_method_get_writer(UI_OpenSSL()))(ui, uis);
+}
+#endif
+
+static
+int cert_stuff(struct connectdata *conn,
+ SSL_CTX* ctx,
+ char *cert_file,
+ const char *cert_type,
+ char *key_file,
+ const char *key_type)
+{
+ struct SessionHandle *data = conn->data;
+
+ int file_type = do_file_type(cert_type);
+
+ if(cert_file || (file_type == SSL_FILETYPE_ENGINE)) {
+ SSL *ssl;
+ X509 *x509;
+ int cert_done = 0;
+
+ if(data->set.str[STRING_KEY_PASSWD]) {
+ /* set the password in the callback userdata */
+ SSL_CTX_set_default_passwd_cb_userdata(ctx,
+ data->set.str[STRING_KEY_PASSWD]);
+ /* Set passwd callback: */
+ SSL_CTX_set_default_passwd_cb(ctx, passwd_callback);
+ }
+
+
+ switch(file_type) {
+ case SSL_FILETYPE_PEM:
+ /* SSL_CTX_use_certificate_chain_file() only works on PEM files */
+ if(SSL_CTX_use_certificate_chain_file(ctx,
+ cert_file) != 1) {
+ failf(data,
+ "could not load PEM client certificate, OpenSSL error %s, "
+ "(no key found, wrong pass phrase, or wrong file format?)",
+ ERR_error_string(ERR_get_error(), NULL) );
+ return 0;
+ }
+ break;
+
+ case SSL_FILETYPE_ASN1:
+ /* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but
+ we use the case above for PEM so this can only be performed with
+ ASN1 files. */
+ if(SSL_CTX_use_certificate_file(ctx,
+ cert_file,
+ file_type) != 1) {
+ failf(data,
+ "could not load ASN1 client certificate, OpenSSL error %s, "
+ "(no key found, wrong pass phrase, or wrong file format?)",
+ ERR_error_string(ERR_get_error(), NULL) );
+ return 0;
+ }
+ break;
+ case SSL_FILETYPE_ENGINE:
+#if defined(HAVE_OPENSSL_ENGINE_H) && defined(ENGINE_CTRL_GET_CMD_FROM_NAME)
+ {
+ if(data->state.engine) {
+ const char *cmd_name = "LOAD_CERT_CTRL";
+ struct {
+ const char *cert_id;
+ X509 *cert;
+ } params;
+
+ params.cert_id = cert_file;
+ params.cert = NULL;
+
+ /* Does the engine supports LOAD_CERT_CTRL ? */
+ if(!ENGINE_ctrl(data->state.engine, ENGINE_CTRL_GET_CMD_FROM_NAME,
+ 0, (void *)cmd_name, NULL)) {
+ failf(data, "ssl engine does not support loading certificates");
+ return 0;
+ }
+
+ /* Load the certificate from the engine */
+ if(!ENGINE_ctrl_cmd(data->state.engine, cmd_name,
+ 0, &params, NULL, 1)) {
+ failf(data, "ssl engine cannot load client cert with id"
+ " '%s' [%s]", cert_file,
+ ERR_error_string(ERR_get_error(), NULL));
+ return 0;
+ }
+
+ if(!params.cert) {
+ failf(data, "ssl engine didn't initialized the certificate "
+ "properly.");
+ return 0;
+ }
+
+ if(SSL_CTX_use_certificate(ctx, params.cert) != 1) {
+ failf(data, "unable to set client certificate");
+ X509_free(params.cert);
+ return 0;
+ }
+ X509_free(params.cert); /* we don't need the handle any more... */
+ }
+ else {
+ failf(data, "crypto engine not set, can't load certificate");
+ return 0;
+ }
+ }
+ break;
+#else
+ failf(data, "file type ENG for certificate not implemented");
+ return 0;
+#endif
+
+ case SSL_FILETYPE_PKCS12:
+ {
+#ifdef HAVE_PKCS12_SUPPORT
+ FILE *f;
+ PKCS12 *p12;
+ EVP_PKEY *pri;
+ STACK_OF(X509) *ca = NULL;
+ int i;
+
+ f = fopen(cert_file, "rb");
+ if(!f) {
+ failf(data, "could not open PKCS12 file '%s'", cert_file);
+ return 0;
+ }
+ p12 = d2i_PKCS12_fp(f, NULL);
+ fclose(f);
+
+ if(!p12) {
+ failf(data, "error reading PKCS12 file '%s'", cert_file);
+ return 0;
+ }
+
+ PKCS12_PBE_add();
+
+ if(!PKCS12_parse(p12, data->set.str[STRING_KEY_PASSWD], &pri, &x509,
+ &ca)) {
+ failf(data,
+ "could not parse PKCS12 file, check password, OpenSSL error %s",
+ ERR_error_string(ERR_get_error(), NULL) );
+ PKCS12_free(p12);
+ return 0;
+ }
+
+ PKCS12_free(p12);
+
+ if(SSL_CTX_use_certificate(ctx, x509) != 1) {
+ failf(data,
+ "could not load PKCS12 client certificate, OpenSSL error %s",
+ ERR_error_string(ERR_get_error(), NULL) );
+ goto fail;
+ }
+
+ if(SSL_CTX_use_PrivateKey(ctx, pri) != 1) {
+ failf(data, "unable to use private key from PKCS12 file '%s'",
+ cert_file);
+ goto fail;
+ }
+
+ if(!SSL_CTX_check_private_key (ctx)) {
+ failf(data, "private key from PKCS12 file '%s' "
+ "does not match certificate in same file", cert_file);
+ goto fail;
+ }
+ /* Set Certificate Verification chain */
+ if(ca && sk_X509_num(ca)) {
+ for(i = 0; i < sk_X509_num(ca); i++) {
+ /*
+ * Note that sk_X509_pop() is used below to make sure the cert is
+ * removed from the stack properly before getting passed to
+ * SSL_CTX_add_extra_chain_cert(). Previously we used
+ * sk_X509_value() instead, but then we'd clean it in the subsequent
+ * sk_X509_pop_free() call.
+ */
+ X509 *x = sk_X509_pop(ca);
+ if(!SSL_CTX_add_extra_chain_cert(ctx, x)) {
+ failf(data, "cannot add certificate to certificate chain");
+ goto fail;
+ }
+ /* SSL_CTX_add_client_CA() seems to work with either sk_* function,
+ * presumably because it duplicates what we pass to it.
+ */
+ if(!SSL_CTX_add_client_CA(ctx, x)) {
+ failf(data, "cannot add certificate to client CA list");
+ goto fail;
+ }
+ }
+ }
+
+ cert_done = 1;
+ fail:
+ EVP_PKEY_free(pri);
+ X509_free(x509);
+ sk_X509_pop_free(ca, X509_free);
+
+ if(!cert_done)
+ return 0; /* failure! */
+ break;
+#else
+ failf(data, "file type P12 for certificate not supported");
+ return 0;
+#endif
+ }
+ default:
+ failf(data, "not supported file type '%s' for certificate", cert_type);
+ return 0;
+ }
+
+ file_type = do_file_type(key_type);
+
+ switch(file_type) {
+ case SSL_FILETYPE_PEM:
+ if(cert_done)
+ break;
+ if(!key_file)
+ /* cert & key can only be in PEM case in the same file */
+ key_file=cert_file;
+ case SSL_FILETYPE_ASN1:
+ if(SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type) != 1) {
+ failf(data, "unable to set private key file: '%s' type %s",
+ key_file, key_type?key_type:"PEM");
+ return 0;
+ }
+ break;
+ case SSL_FILETYPE_ENGINE:
+#ifdef HAVE_OPENSSL_ENGINE_H
+ { /* XXXX still needs some work */
+ EVP_PKEY *priv_key = NULL;
+ if(data->state.engine) {
+#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
+ UI_METHOD *ui_method =
+ UI_create_method((char *)"cURL user interface");
+ if(!ui_method) {
+ failf(data, "unable do create OpenSSL user-interface method");
+ return 0;
+ }
+ UI_method_set_opener(ui_method, UI_method_get_opener(UI_OpenSSL()));
+ UI_method_set_closer(ui_method, UI_method_get_closer(UI_OpenSSL()));
+ UI_method_set_reader(ui_method, ssl_ui_reader);
+ UI_method_set_writer(ui_method, ssl_ui_writer);
+#endif
+ /* the typecast below was added to please mingw32 */
+ priv_key = (EVP_PKEY *)
+ ENGINE_load_private_key(data->state.engine, key_file,
+#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
+ ui_method,
+#endif
+ data->set.str[STRING_KEY_PASSWD]);
+#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
+ UI_destroy_method(ui_method);
+#endif
+ if(!priv_key) {
+ failf(data, "failed to load private key from crypto engine");
+ return 0;
+ }
+ if(SSL_CTX_use_PrivateKey(ctx, priv_key) != 1) {
+ failf(data, "unable to set private key");
+ EVP_PKEY_free(priv_key);
+ return 0;
+ }
+ EVP_PKEY_free(priv_key); /* we don't need the handle any more... */
+ }
+ else {
+ failf(data, "crypto engine not set, can't load private key");
+ return 0;
+ }
+ }
+ break;
+#else
+ failf(data, "file type ENG for private key not supported");
+ return 0;
+#endif
+ case SSL_FILETYPE_PKCS12:
+ if(!cert_done) {
+ failf(data, "file type P12 for private key not supported");
+ return 0;
+ }
+ break;
+ default:
+ failf(data, "not supported file type for private key");
+ return 0;
+ }
+
+ ssl=SSL_new(ctx);
+ if(!ssl) {
+ failf(data, "unable to create an SSL structure");
+ return 0;
+ }
+
+ x509=SSL_get_certificate(ssl);
+
+ /* This version was provided by Evan Jordan and is supposed to not
+ leak memory as the previous version: */
+ if(x509) {
+ EVP_PKEY *pktmp = X509_get_pubkey(x509);
+ EVP_PKEY_copy_parameters(pktmp, SSL_get_privatekey(ssl));
+ EVP_PKEY_free(pktmp);
+ }
+
+ SSL_free(ssl);
+
+ /* If we are using DSA, we can copy the parameters from
+ * the private key */
+
+
+ /* Now we know that a key and cert have been set against
+ * the SSL context */
+ if(!SSL_CTX_check_private_key(ctx)) {
+ failf(data, "Private key does not match the certificate public key");
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/* returns non-zero on failure */
+static int x509_name_oneline(X509_NAME *a, char *buf, size_t size)
+{
+#if 0
+ return X509_NAME_oneline(a, buf, size);
+#else
+ BIO *bio_out = BIO_new(BIO_s_mem());
+ BUF_MEM *biomem;
+ int rc;
+
+ if(!bio_out)
+ return 1; /* alloc failed! */
+
+ rc = X509_NAME_print_ex(bio_out, a, 0, XN_FLAG_SEP_SPLUS_SPC);
+ BIO_get_mem_ptr(bio_out, &biomem);
+
+ if((size_t)biomem->length < size)
+ size = biomem->length;
+ else
+ size--; /* don't overwrite the buffer end */
+
+ memcpy(buf, biomem->data, size);
+ buf[size]=0;
+
+ BIO_free(bio_out);
+
+ return !rc;
+#endif
+}
+
+/* Return error string for last OpenSSL error
+ */
+static char *SSL_strerror(unsigned long error, char *buf, size_t size)
+{
+ /* OpenSSL 0.9.6 and later has a function named
+ ERR_error_string_n() that takes the size of the buffer as a
+ third argument */
+ ERR_error_string_n(error, buf, size);
+ return buf;
+}
+
+/**
+ * Global SSL init
+ *
+ * @retval 0 error initializing SSL
+ * @retval 1 SSL initialized successfully
+ */
+int Curl_ossl_init(void)
+{
+ OPENSSL_load_builtin_modules();
+
+#ifdef HAVE_ENGINE_LOAD_BUILTIN_ENGINES
+ ENGINE_load_builtin_engines();
+#endif
+
+ /* Lets get nice error messages */
+ SSL_load_error_strings();
+
+ /* Init the global ciphers and digests */
+ if(!SSLeay_add_ssl_algorithms())
+ return 0;
+
+ OpenSSL_add_all_algorithms();
+
+
+ /* OPENSSL_config(NULL); is "strongly recommended" to use but unfortunately
+ that function makes an exit() call on wrongly formatted config files
+ which makes it hard to use in some situations. OPENSSL_config() itself
+ calls CONF_modules_load_file() and we use that instead and we ignore
+ its return code! */
+
+ /* CONF_MFLAGS_DEFAULT_SECTION introduced some time between 0.9.8b and
+ 0.9.8e */
+#ifndef CONF_MFLAGS_DEFAULT_SECTION
+#define CONF_MFLAGS_DEFAULT_SECTION 0x0
+#endif
+
+ CONF_modules_load_file(NULL, NULL,
+ CONF_MFLAGS_DEFAULT_SECTION|
+ CONF_MFLAGS_IGNORE_MISSING_FILE);
+
+ return 1;
+}
+
+/* Global cleanup */
+void Curl_ossl_cleanup(void)
+{
+ /* Free ciphers and digests lists */
+ EVP_cleanup();
+
+#ifdef HAVE_ENGINE_CLEANUP
+ /* Free engine list */
+ ENGINE_cleanup();
+#endif
+
+#ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
+ /* Free OpenSSL ex_data table */
+ CRYPTO_cleanup_all_ex_data();
+#endif
+
+ /* Free OpenSSL error strings */
+ ERR_free_strings();
+
+ /* Free thread local error state, destroying hash upon zero refcount */
+#ifdef HAVE_ERR_REMOVE_THREAD_STATE
+ ERR_remove_thread_state(NULL);
+#else
+ ERR_remove_state(0);
+#endif
+}
+
+/*
+ * This function uses SSL_peek to determine connection status.
+ *
+ * Return codes:
+ * 1 means the connection is still in place
+ * 0 means the connection has been closed
+ * -1 means the connection status is unknown
+ */
+int Curl_ossl_check_cxn(struct connectdata *conn)
+{
+ int rc;
+ char buf;
+
+ rc = SSL_peek(conn->ssl[FIRSTSOCKET].handle, (void*)&buf, 1);
+ if(rc > 0)
+ return 1; /* connection still in place */
+
+ if(rc == 0)
+ return 0; /* connection has been closed */
+
+ return -1; /* connection status unknown */
+}
+
+/* Selects an OpenSSL crypto engine
+ */
+CURLcode Curl_ossl_set_engine(struct SessionHandle *data, const char *engine)
+{
+#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_ENGINE_H)
+ ENGINE *e;
+
+#if OPENSSL_VERSION_NUMBER >= 0x00909000L
+ e = ENGINE_by_id(engine);
+#else
+ /* avoid memory leak */
+ for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) {
+ const char *e_id = ENGINE_get_id(e);
+ if(!strcmp(engine, e_id))
+ break;
+ }
+#endif
+
+ if(!e) {
+ failf(data, "SSL Engine '%s' not found", engine);
+ return CURLE_SSL_ENGINE_NOTFOUND;
+ }
+
+ if(data->state.engine) {
+ ENGINE_finish(data->state.engine);
+ ENGINE_free(data->state.engine);
+ data->state.engine = NULL;
+ }
+ if(!ENGINE_init(e)) {
+ char buf[256];
+
+ ENGINE_free(e);
+ failf(data, "Failed to initialise SSL Engine '%s':\n%s",
+ engine, SSL_strerror(ERR_get_error(), buf, sizeof(buf)));
+ return CURLE_SSL_ENGINE_INITFAILED;
+ }
+ data->state.engine = e;
+ return CURLE_OK;
+#else
+ (void)engine;
+ failf(data, "SSL Engine not supported");
+ return CURLE_SSL_ENGINE_NOTFOUND;
+#endif
+}
+
+/* Sets engine as default for all SSL operations
+ */
+CURLcode Curl_ossl_set_engine_default(struct SessionHandle *data)
+{
+#ifdef HAVE_OPENSSL_ENGINE_H
+ if(data->state.engine) {
+ if(ENGINE_set_default(data->state.engine, ENGINE_METHOD_ALL) > 0) {
+ infof(data, "set default crypto engine '%s'\n",
+ ENGINE_get_id(data->state.engine));
+ }
+ else {
+ failf(data, "set default crypto engine '%s' failed",
+ ENGINE_get_id(data->state.engine));
+ return CURLE_SSL_ENGINE_SETFAILED;
+ }
+ }
+#else
+ (void) data;
+#endif
+ return CURLE_OK;
+}
+
+/* Return list of OpenSSL crypto engine names.
+ */
+struct curl_slist *Curl_ossl_engines_list(struct SessionHandle *data)
+{
+ struct curl_slist *list = NULL;
+#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_ENGINE_H)
+ struct curl_slist *beg;
+ ENGINE *e;
+
+ for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) {
+ beg = curl_slist_append(list, ENGINE_get_id(e));
+ if(!beg) {
+ curl_slist_free_all(list);
+ return NULL;
+ }
+ list = beg;
+ }
+#endif
+ (void) data;
+ return list;
+}
+
+
+/*
+ * This function is called when an SSL connection is closed.
+ */
+void Curl_ossl_close(struct connectdata *conn, int sockindex)
+{
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+ if(connssl->handle) {
+ (void)SSL_shutdown(connssl->handle);
+ SSL_set_connect_state(connssl->handle);
+
+ SSL_free (connssl->handle);
+ connssl->handle = NULL;
+ }
+ if(connssl->ctx) {
+ SSL_CTX_free (connssl->ctx);
+ connssl->ctx = NULL;
+ }
+}
+
+/*
+ * This function is called to shut down the SSL layer but keep the
+ * socket open (CCC - Clear Command Channel)
+ */
+int Curl_ossl_shutdown(struct connectdata *conn, int sockindex)
+{
+ int retval = 0;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct SessionHandle *data = conn->data;
+ char buf[120]; /* We will use this for the OpenSSL error buffer, so it has
+ to be at least 120 bytes long. */
+ unsigned long sslerror;
+ ssize_t nread;
+ int buffsize;
+ int err;
+ int done = 0;
+
+ /* This has only been tested on the proftpd server, and the mod_tls code
+ sends a close notify alert without waiting for a close notify alert in
+ response. Thus we wait for a close notify alert from the server, but
+ we do not send one. Let's hope other servers do the same... */
+
+ if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
+ (void)SSL_shutdown(connssl->handle);
+
+ if(connssl->handle) {
+ buffsize = (int)sizeof(buf);
+ while(!done) {
+ int what = Curl_socket_ready(conn->sock[sockindex],
+ CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
+ if(what > 0) {
+ ERR_clear_error();
+
+ /* Something to read, let's do it and hope that it is the close
+ notify alert from the server */
+ nread = (ssize_t)SSL_read(conn->ssl[sockindex].handle, buf,
+ buffsize);
+ err = SSL_get_error(conn->ssl[sockindex].handle, (int)nread);
+
+ switch(err) {
+ case SSL_ERROR_NONE: /* this is not an error */
+ case SSL_ERROR_ZERO_RETURN: /* no more data */
+ /* This is the expected response. There was no data but only
+ the close notify alert */
+ done = 1;
+ break;
+ case SSL_ERROR_WANT_READ:
+ /* there's data pending, re-invoke SSL_read() */
+ infof(data, "SSL_ERROR_WANT_READ\n");
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ /* SSL wants a write. Really odd. Let's bail out. */
+ infof(data, "SSL_ERROR_WANT_WRITE\n");
+ done = 1;
+ break;
+ default:
+ /* openssl/ssl.h says "look at error stack/return value/errno" */
+ sslerror = ERR_get_error();
+ failf(conn->data, "SSL read: %s, errno %d",
+ ERR_error_string(sslerror, buf),
+ SOCKERRNO);
+ done = 1;
+ break;
+ }
+ }
+ else if(0 == what) {
+ /* timeout */
+ failf(data, "SSL shutdown timeout");
+ done = 1;
+ }
+ else {
+ /* anything that gets here is fatally bad */
+ failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+ retval = -1;
+ done = 1;
+ }
+ } /* while()-loop for the select() */
+
+ if(data->set.verbose) {
+#ifdef HAVE_SSL_GET_SHUTDOWN
+ switch(SSL_get_shutdown(connssl->handle)) {
+ case SSL_SENT_SHUTDOWN:
+ infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN\n");
+ break;
+ case SSL_RECEIVED_SHUTDOWN:
+ infof(data, "SSL_get_shutdown() returned SSL_RECEIVED_SHUTDOWN\n");
+ break;
+ case SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN:
+ infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN|"
+ "SSL_RECEIVED__SHUTDOWN\n");
+ break;
+ }
+#endif
+ }
+
+ SSL_free (connssl->handle);
+ connssl->handle = NULL;
+ }
+ return retval;
+}
+
+void Curl_ossl_session_free(void *ptr)
+{
+ /* free the ID */
+ SSL_SESSION_free(ptr);
+}
+
+/*
+ * This function is called when the 'data' struct is going away. Close
+ * down everything and free all resources!
+ */
+void Curl_ossl_close_all(struct SessionHandle *data)
+{
+#ifdef HAVE_OPENSSL_ENGINE_H
+ if(data->state.engine) {
+ ENGINE_finish(data->state.engine);
+ ENGINE_free(data->state.engine);
+ data->state.engine = NULL;
+ }
+#else
+ (void)data;
+#endif
+}
+
+static int asn1_output(const ASN1_UTCTIME *tm,
+ char *buf,
+ size_t sizeofbuf)
+{
+ const char *asn1_string;
+ int gmt=FALSE;
+ int i;
+ int year=0, month=0, day=0, hour=0, minute=0, second=0;
+
+ i=tm->length;
+ asn1_string=(const char *)tm->data;
+
+ if(i < 10)
+ return 1;
+ if(asn1_string[i-1] == 'Z')
+ gmt=TRUE;
+ for(i=0; i<10; i++)
+ if((asn1_string[i] > '9') || (asn1_string[i] < '0'))
+ return 2;
+
+ year= (asn1_string[0]-'0')*10+(asn1_string[1]-'0');
+ if(year < 50)
+ year+=100;
+
+ month= (asn1_string[2]-'0')*10+(asn1_string[3]-'0');
+ if((month > 12) || (month < 1))
+ return 3;
+
+ day= (asn1_string[4]-'0')*10+(asn1_string[5]-'0');
+ hour= (asn1_string[6]-'0')*10+(asn1_string[7]-'0');
+ minute= (asn1_string[8]-'0')*10+(asn1_string[9]-'0');
+
+ if((asn1_string[10] >= '0') && (asn1_string[10] <= '9') &&
+ (asn1_string[11] >= '0') && (asn1_string[11] <= '9'))
+ second= (asn1_string[10]-'0')*10+(asn1_string[11]-'0');
+
+ snprintf(buf, sizeofbuf,
+ "%04d-%02d-%02d %02d:%02d:%02d %s",
+ year+1900, month, day, hour, minute, second, (gmt?"GMT":""));
+
+ return 0;
+}
+
+/* ====================================================== */
+
+
+/* Quote from RFC2818 section 3.1 "Server Identity"
+
+ If a subjectAltName extension of type dNSName is present, that MUST
+ be used as the identity. Otherwise, the (most specific) Common Name
+ field in the Subject field of the certificate MUST be used. Although
+ the use of the Common Name is existing practice, it is deprecated and
+ Certification Authorities are encouraged to use the dNSName instead.
+
+ Matching is performed using the matching rules specified by
+ [RFC2459]. If more than one identity of a given type is present in
+ the certificate (e.g., more than one dNSName name, a match in any one
+ of the set is considered acceptable.) Names may contain the wildcard
+ character * which is considered to match any single domain name
+ component or component fragment. E.g., *.a.com matches foo.a.com but
+ not bar.foo.a.com. f*.com matches foo.com but not bar.com.
+
+ In some cases, the URI is specified as an IP address rather than a
+ hostname. In this case, the iPAddress subjectAltName must be present
+ in the certificate and must exactly match the IP in the URI.
+
+*/
+static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert)
+{
+ int matched = -1; /* -1 is no alternative match yet, 1 means match and 0
+ means mismatch */
+ int target = GEN_DNS; /* target type, GEN_DNS or GEN_IPADD */
+ size_t addrlen = 0;
+ struct SessionHandle *data = conn->data;
+ STACK_OF(GENERAL_NAME) *altnames;
+#ifdef ENABLE_IPV6
+ struct in6_addr addr;
+#else
+ struct in_addr addr;
+#endif
+ CURLcode result = CURLE_OK;
+
+#ifdef ENABLE_IPV6
+ if(conn->bits.ipv6_ip &&
+ Curl_inet_pton(AF_INET6, conn->host.name, &addr)) {
+ target = GEN_IPADD;
+ addrlen = sizeof(struct in6_addr);
+ }
+ else
+#endif
+ if(Curl_inet_pton(AF_INET, conn->host.name, &addr)) {
+ target = GEN_IPADD;
+ addrlen = sizeof(struct in_addr);
+ }
+
+ /* get a "list" of alternative names */
+ altnames = X509_get_ext_d2i(server_cert, NID_subject_alt_name, NULL, NULL);
+
+ if(altnames) {
+ int numalts;
+ int i;
+
+ /* get amount of alternatives, RFC2459 claims there MUST be at least
+ one, but we don't depend on it... */
+ numalts = sk_GENERAL_NAME_num(altnames);
+
+ /* loop through all alternatives while none has matched */
+ for(i=0; (i<numalts) && (matched != 1); i++) {
+ /* get a handle to alternative name number i */
+ const GENERAL_NAME *check = sk_GENERAL_NAME_value(altnames, i);
+
+ /* only check alternatives of the same type the target is */
+ if(check->type == target) {
+ /* get data and length */
+ const char *altptr = (char *)ASN1_STRING_data(check->d.ia5);
+ size_t altlen = (size_t) ASN1_STRING_length(check->d.ia5);
+
+ switch(target) {
+ case GEN_DNS: /* name/pattern comparison */
+ /* The OpenSSL man page explicitly says: "In general it cannot be
+ assumed that the data returned by ASN1_STRING_data() is null
+ terminated or does not contain embedded nulls." But also that
+ "The actual format of the data will depend on the actual string
+ type itself: for example for and IA5String the data will be ASCII"
+
+ Gisle researched the OpenSSL sources:
+ "I checked the 0.9.6 and 0.9.8 sources before my patch and
+ it always 0-terminates an IA5String."
+ */
+ if((altlen == strlen(altptr)) &&
+ /* if this isn't true, there was an embedded zero in the name
+ string and we cannot match it. */
+ Curl_cert_hostcheck(altptr, conn->host.name))
+ matched = 1;
+ else
+ matched = 0;
+ break;
+
+ case GEN_IPADD: /* IP address comparison */
+ /* compare alternative IP address if the data chunk is the same size
+ our server IP address is */
+ if((altlen == addrlen) && !memcmp(altptr, &addr, altlen))
+ matched = 1;
+ else
+ matched = 0;
+ break;
+ }
+ }
+ }
+ GENERAL_NAMES_free(altnames);
+ }
+
+ if(matched == 1)
+ /* an alternative name matched the server hostname */
+ infof(data, "\t subjectAltName: %s matched\n", conn->host.dispname);
+ else if(matched == 0) {
+ /* an alternative name field existed, but didn't match and then
+ we MUST fail */
+ infof(data, "\t subjectAltName does not match %s\n", conn->host.dispname);
+ failf(data, "SSL: no alternative certificate subject name matches "
+ "target host name '%s'", conn->host.dispname);
+ result = CURLE_PEER_FAILED_VERIFICATION;
+ }
+ else {
+ /* we have to look to the last occurrence of a commonName in the
+ distinguished one to get the most significant one. */
+ int j, i=-1;
+
+/* The following is done because of a bug in 0.9.6b */
+
+ unsigned char *nulstr = (unsigned char *)"";
+ unsigned char *peer_CN = nulstr;
+
+ X509_NAME *name = X509_get_subject_name(server_cert);
+ if(name)
+ while((j = X509_NAME_get_index_by_NID(name, NID_commonName, i))>=0)
+ i=j;
+
+ /* we have the name entry and we will now convert this to a string
+ that we can use for comparison. Doing this we support BMPstring,
+ UTF8 etc. */
+
+ if(i>=0) {
+ ASN1_STRING *tmp =
+ X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i));
+
+ /* In OpenSSL 0.9.7d and earlier, ASN1_STRING_to_UTF8 fails if the input
+ is already UTF-8 encoded. We check for this case and copy the raw
+ string manually to avoid the problem. This code can be made
+ conditional in the future when OpenSSL has been fixed. Work-around
+ brought by Alexis S. L. Carvalho. */
+ if(tmp) {
+ if(ASN1_STRING_type(tmp) == V_ASN1_UTF8STRING) {
+ j = ASN1_STRING_length(tmp);
+ if(j >= 0) {
+ peer_CN = OPENSSL_malloc(j+1);
+ if(peer_CN) {
+ memcpy(peer_CN, ASN1_STRING_data(tmp), j);
+ peer_CN[j] = '\0';
+ }
+ }
+ }
+ else /* not a UTF8 name */
+ j = ASN1_STRING_to_UTF8(&peer_CN, tmp);
+
+ if(peer_CN && (curlx_uztosi(strlen((char *)peer_CN)) != j)) {
+ /* there was a terminating zero before the end of string, this
+ cannot match and we return failure! */
+ failf(data, "SSL: illegal cert name field");
+ result = CURLE_PEER_FAILED_VERIFICATION;
+ }
+ }
+ }
+
+ if(peer_CN == nulstr)
+ peer_CN = NULL;
+ else {
+ /* convert peer_CN from UTF8 */
+ CURLcode rc = Curl_convert_from_utf8(data, peer_CN, strlen(peer_CN));
+ /* Curl_convert_from_utf8 calls failf if unsuccessful */
+ if(rc) {
+ OPENSSL_free(peer_CN);
+ return rc;
+ }
+ }
+
+ if(result)
+ /* error already detected, pass through */
+ ;
+ else if(!peer_CN) {
+ failf(data,
+ "SSL: unable to obtain common name from peer certificate");
+ result = CURLE_PEER_FAILED_VERIFICATION;
+ }
+ else if(!Curl_cert_hostcheck((const char *)peer_CN, conn->host.name)) {
+ failf(data, "SSL: certificate subject name '%s' does not match "
+ "target host name '%s'", peer_CN, conn->host.dispname);
+ result = CURLE_PEER_FAILED_VERIFICATION;
+ }
+ else {
+ infof(data, "\t common name: %s (matched)\n", peer_CN);
+ }
+ if(peer_CN)
+ OPENSSL_free(peer_CN);
+ }
+
+ return result;
+}
+
+#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
+ !defined(OPENSSL_IS_BORINGSSL)
+static CURLcode verifystatus(struct connectdata *conn,
+ struct ssl_connect_data *connssl)
+{
+ int i, ocsp_status;
+ const unsigned char *p;
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+
+ OCSP_RESPONSE *rsp = NULL;
+ OCSP_BASICRESP *br = NULL;
+ X509_STORE *st = NULL;
+ STACK_OF(X509) *ch = NULL;
+
+ long len = SSL_get_tlsext_status_ocsp_resp(connssl->handle, &p);
+
+ if(!p) {
+ failf(data, "No OCSP response received");
+ result = CURLE_SSL_INVALIDCERTSTATUS;
+ goto end;
+ }
+
+ rsp = d2i_OCSP_RESPONSE(NULL, &p, len);
+ if(!rsp) {
+ failf(data, "Invalid OCSP response");
+ result = CURLE_SSL_INVALIDCERTSTATUS;
+ goto end;
+ }
+
+ ocsp_status = OCSP_response_status(rsp);
+ if(ocsp_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
+ failf(data, "Invalid OCSP response status: %s (%d)",
+ OCSP_response_status_str(ocsp_status), ocsp_status);
+ result = CURLE_SSL_INVALIDCERTSTATUS;
+ goto end;
+ }
+
+ br = OCSP_response_get1_basic(rsp);
+ if(!br) {
+ failf(data, "Invalid OCSP response");
+ result = CURLE_SSL_INVALIDCERTSTATUS;
+ goto end;
+ }
+
+ ch = SSL_get_peer_cert_chain(connssl->handle);
+ st = SSL_CTX_get_cert_store(connssl->ctx);
+
+#if ((OPENSSL_VERSION_NUMBER <= 0x1000201fL) /* Fixed after 1.0.2a */ || \
+ defined(LIBRESSL_VERSION_NUMBER))
+ /* The authorized responder cert in the OCSP response MUST be signed by the
+ peer cert's issuer (see RFC6960 section 4.2.2.2). If that's a root cert,
+ no problem, but if it's an intermediate cert OpenSSL has a bug where it
+ expects this issuer to be present in the chain embedded in the OCSP
+ response. So we add it if necessary. */
+
+ /* First make sure the peer cert chain includes both a peer and an issuer,
+ and the OCSP response contains a responder cert. */
+ if(sk_X509_num(ch) >= 2 && sk_X509_num(br->certs) >= 1) {
+ X509 *responder = sk_X509_value(br->certs, sk_X509_num(br->certs) - 1);
+
+ /* Find issuer of responder cert and add it to the OCSP response chain */
+ for(i = 0; i < sk_X509_num(ch); i++) {
+ X509 *issuer = sk_X509_value(ch, i);
+ if(X509_check_issued(issuer, responder) == X509_V_OK) {
+ if(!OCSP_basic_add1_cert(br, issuer)) {
+ failf(data, "Could not add issuer cert to OCSP response");
+ result = CURLE_SSL_INVALIDCERTSTATUS;
+ goto end;
+ }
+ }
+ }
+ }
+#endif
+
+ if(OCSP_basic_verify(br, ch, st, 0) <= 0) {
+ failf(data, "OCSP response verification failed");
+ result = CURLE_SSL_INVALIDCERTSTATUS;
+ goto end;
+ }
+
+ for(i = 0; i < OCSP_resp_count(br); i++) {
+ int cert_status, crl_reason;
+ OCSP_SINGLERESP *single = NULL;
+
+ ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
+
+ if(!(single = OCSP_resp_get0(br, i)))
+ continue;
+
+ cert_status = OCSP_single_get0_status(single, &crl_reason, &rev,
+ &thisupd, &nextupd);
+
+ if(!OCSP_check_validity(thisupd, nextupd, 300L, -1L)) {
+ failf(data, "OCSP response has expired");
+ result = CURLE_SSL_INVALIDCERTSTATUS;
+ goto end;
+ }
+
+ infof(data, "SSL certificate status: %s (%d)\n",
+ OCSP_cert_status_str(cert_status), cert_status);
+
+ switch(cert_status) {
+ case V_OCSP_CERTSTATUS_GOOD:
+ break;
+
+ case V_OCSP_CERTSTATUS_REVOKED:
+ result = CURLE_SSL_INVALIDCERTSTATUS;
+
+ failf(data, "SSL certificate revocation reason: %s (%d)",
+ OCSP_crl_reason_str(crl_reason), crl_reason);
+ goto end;
+
+ case V_OCSP_CERTSTATUS_UNKNOWN:
+ result = CURLE_SSL_INVALIDCERTSTATUS;
+ goto end;
+ }
+ }
+
+end:
+ if(br) OCSP_BASICRESP_free(br);
+ OCSP_RESPONSE_free(rsp);
+
+ return result;
+}
+#endif
+
+#endif /* USE_OPENSSL */
+
+/* The SSL_CTRL_SET_MSG_CALLBACK doesn't exist in ancient OpenSSL versions
+ and thus this cannot be done there. */
+#ifdef SSL_CTRL_SET_MSG_CALLBACK
+
+static const char *ssl_msg_type(int ssl_ver, int msg)
+{
+#ifdef SSL2_VERSION_MAJOR
+ if(ssl_ver == SSL2_VERSION_MAJOR) {
+ switch (msg) {
+ case SSL2_MT_ERROR:
+ return "Error";
+ case SSL2_MT_CLIENT_HELLO:
+ return "Client hello";
+ case SSL2_MT_CLIENT_MASTER_KEY:
+ return "Client key";
+ case SSL2_MT_CLIENT_FINISHED:
+ return "Client finished";
+ case SSL2_MT_SERVER_HELLO:
+ return "Server hello";
+ case SSL2_MT_SERVER_VERIFY:
+ return "Server verify";
+ case SSL2_MT_SERVER_FINISHED:
+ return "Server finished";
+ case SSL2_MT_REQUEST_CERTIFICATE:
+ return "Request CERT";
+ case SSL2_MT_CLIENT_CERTIFICATE:
+ return "Client CERT";
+ }
+ }
+ else
+#endif
+ if(ssl_ver == SSL3_VERSION_MAJOR) {
+ switch (msg) {
+ case SSL3_MT_HELLO_REQUEST:
+ return "Hello request";
+ case SSL3_MT_CLIENT_HELLO:
+ return "Client hello";
+ case SSL3_MT_SERVER_HELLO:
+ return "Server hello";
+#ifdef SSL3_MT_NEWSESSION_TICKET
+ case SSL3_MT_NEWSESSION_TICKET:
+ return "Newsession Ticket";
+#endif
+ case SSL3_MT_CERTIFICATE:
+ return "Certificate";
+ case SSL3_MT_SERVER_KEY_EXCHANGE:
+ return "Server key exchange";
+ case SSL3_MT_CLIENT_KEY_EXCHANGE:
+ return "Client key exchange";
+ case SSL3_MT_CERTIFICATE_REQUEST:
+ return "Request CERT";
+ case SSL3_MT_SERVER_DONE:
+ return "Server finished";
+ case SSL3_MT_CERTIFICATE_VERIFY:
+ return "CERT verify";
+ case SSL3_MT_FINISHED:
+ return "Finished";
+#ifdef SSL3_MT_CERTIFICATE_STATUS
+ case SSL3_MT_CERTIFICATE_STATUS:
+ return "Certificate Status";
+#endif
+ }
+ }
+ return "Unknown";
+}
+
+static const char *tls_rt_type(int type)
+{
+ switch(type) {
+#ifdef SSL3_RT_HEADER
+ case SSL3_RT_HEADER:
+ return "TLS header";
+#endif
+ case SSL3_RT_CHANGE_CIPHER_SPEC:
+ return "TLS change cipher";
+ case SSL3_RT_ALERT:
+ return "TLS alert";
+ case SSL3_RT_HANDSHAKE:
+ return "TLS handshake";
+ case SSL3_RT_APPLICATION_DATA:
+ return "TLS app data";
+ default:
+ return "TLS Unknown";
+ }
+}
+
+
+/*
+ * Our callback from the SSL/TLS layers.
+ */
+static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
+ const void *buf, size_t len, SSL *ssl,
+ void *userp)
+{
+ struct SessionHandle *data;
+ const char *msg_name, *tls_rt_name;
+ char ssl_buf[1024];
+ char unknown[32];
+ int msg_type, txt_len;
+ const char *verstr = NULL;
+ struct connectdata *conn = userp;
+
+ if(!conn || !conn->data || !conn->data->set.fdebug ||
+ (direction != 0 && direction != 1))
+ return;
+
+ data = conn->data;
+
+ switch(ssl_ver) {
+#ifdef SSL2_VERSION /* removed in recent versions */
+ case SSL2_VERSION:
+ verstr = "SSLv2";
+ break;
+#endif
+#ifdef SSL3_VERSION
+ case SSL3_VERSION:
+ verstr = "SSLv3";
+ break;
+#endif
+ case TLS1_VERSION:
+ verstr = "TLSv1.0";
+ break;
+#ifdef TLS1_1_VERSION
+ case TLS1_1_VERSION:
+ verstr = "TLSv1.1";
+ break;
+#endif
+#ifdef TLS1_2_VERSION
+ case TLS1_2_VERSION:
+ verstr = "TLSv1.2";
+ break;
+#endif
+ case 0:
+ break;
+ default:
+ snprintf(unknown, sizeof(unknown), "(%x)", ssl_ver);
+ verstr = unknown;
+ break;
+ }
+
+ if(ssl_ver) {
+ /* the info given when the version is zero is not that useful for us */
+
+ ssl_ver >>= 8; /* check the upper 8 bits only below */
+
+ /* SSLv2 doesn't seem to have TLS record-type headers, so OpenSSL
+ * always pass-up content-type as 0. But the interesting message-type
+ * is at 'buf[0]'.
+ */
+ if(ssl_ver == SSL3_VERSION_MAJOR && content_type)
+ tls_rt_name = tls_rt_type(content_type);
+ else
+ tls_rt_name = "";
+
+ msg_type = *(char*)buf;
+ msg_name = ssl_msg_type(ssl_ver, msg_type);
+
+ txt_len = snprintf(ssl_buf, sizeof(ssl_buf), "%s (%s), %s, %s (%d):\n",
+ verstr, direction?"OUT":"IN",
+ tls_rt_name, msg_name, msg_type);
+ Curl_debug(data, CURLINFO_TEXT, ssl_buf, (size_t)txt_len, NULL);
+ }
+
+ Curl_debug(data, (direction == 1) ? CURLINFO_SSL_DATA_OUT :
+ CURLINFO_SSL_DATA_IN, (char *)buf, len, NULL);
+ (void) ssl;
+}
+#endif
+
+#ifdef USE_OPENSSL
+/* ====================================================== */
+
+#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
+# define use_sni(x) sni = (x)
+#else
+# define use_sni(x) Curl_nop_stmt
+#endif
+
+/* Check for OpenSSL 1.0.2 which has ALPN support. */
+#undef HAS_ALPN
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L \
+ && !defined(OPENSSL_NO_TLSEXT)
+# define HAS_ALPN 1
+#endif
+
+/* Check for OpenSSL 1.0.1 which has NPN support. */
+#undef HAS_NPN
+#if OPENSSL_VERSION_NUMBER >= 0x10001000L \
+ && !defined(OPENSSL_NO_TLSEXT) \
+ && !defined(OPENSSL_NO_NEXTPROTONEG)
+# define HAS_NPN 1
+#endif
+
+#ifdef HAS_NPN
+
+/*
+ * in is a list of lenght prefixed strings. this function has to select
+ * the protocol we want to use from the list and write its string into out.
+ */
+
+static int
+select_next_protocol(unsigned char **out, unsigned char *outlen,
+ const unsigned char *in, unsigned int inlen,
+ const char *key, unsigned int keylen)
+{
+ unsigned int i;
+ for(i = 0; i + keylen <= inlen; i += in[i] + 1) {
+ if(memcmp(&in[i + 1], key, keylen) == 0) {
+ *out = (unsigned char *) &in[i + 1];
+ *outlen = in[i];
+ return 0;
+ }
+ }
+ return -1;
+}
+
+static int
+select_next_proto_cb(SSL *ssl,
+ unsigned char **out, unsigned char *outlen,
+ const unsigned char *in, unsigned int inlen,
+ void *arg)
+{
+ struct connectdata *conn = (struct connectdata*) arg;
+
+ (void)ssl;
+
+#ifdef USE_NGHTTP2
+ if(conn->data->set.httpversion == CURL_HTTP_VERSION_2_0 &&
+ !select_next_protocol(out, outlen, in, inlen, NGHTTP2_PROTO_VERSION_ID,
+ NGHTTP2_PROTO_VERSION_ID_LEN)) {
+ infof(conn->data, "NPN, negotiated HTTP2 (%s)\n",
+ NGHTTP2_PROTO_VERSION_ID);
+ conn->negnpn = CURL_HTTP_VERSION_2_0;
+ return SSL_TLSEXT_ERR_OK;
+ }
+#endif
+
+ if(!select_next_protocol(out, outlen, in, inlen, ALPN_HTTP_1_1,
+ ALPN_HTTP_1_1_LENGTH)) {
+ infof(conn->data, "NPN, negotiated HTTP1.1\n");
+ conn->negnpn = CURL_HTTP_VERSION_1_1;
+ return SSL_TLSEXT_ERR_OK;
+ }
+
+ infof(conn->data, "NPN, no overlap, use HTTP1.1\n");
+ *out = (unsigned char *)ALPN_HTTP_1_1;
+ *outlen = ALPN_HTTP_1_1_LENGTH;
+ conn->negnpn = CURL_HTTP_VERSION_1_1;
+
+ return SSL_TLSEXT_ERR_OK;
+}
+#endif /* HAS_NPN */
+
+static const char *
+get_ssl_version_txt(SSL *ssl)
+{
+ if(!ssl)
+ return "";
+
+ switch(SSL_version(ssl)) {
+#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
+ case TLS1_2_VERSION:
+ return "TLSv1.2";
+ case TLS1_1_VERSION:
+ return "TLSv1.1";
+#endif
+ case TLS1_VERSION:
+ return "TLSv1.0";
+ case SSL3_VERSION:
+ return "SSLv3";
+ case SSL2_VERSION:
+ return "SSLv2";
+ }
+ return "unknown";
+}
+
+static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
+{
+ CURLcode result = CURLE_OK;
+ char *ciphers;
+ struct SessionHandle *data = conn->data;
+ SSL_METHOD_QUAL SSL_METHOD *req_method = NULL;
+ void *ssl_sessionid = NULL;
+ X509_LOOKUP *lookup = NULL;
+ curl_socket_t sockfd = conn->sock[sockindex];
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ long ctx_options;
+#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
+ bool sni;
+#ifdef ENABLE_IPV6
+ struct in6_addr addr;
+#else
+ struct in_addr addr;
+#endif
+#endif
+
+ DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
+
+ /* Make funny stuff to get random input */
+ Curl_ossl_seed(data);
+
+ data->set.ssl.certverifyresult = !X509_V_OK;
+
+ /* check to see if we've been told to use an explicit SSL/TLS version */
+
+ switch(data->set.ssl.version) {
+ default:
+ case CURL_SSLVERSION_DEFAULT:
+ case CURL_SSLVERSION_TLSv1:
+ case CURL_SSLVERSION_TLSv1_0:
+ case CURL_SSLVERSION_TLSv1_1:
+ case CURL_SSLVERSION_TLSv1_2:
+ /* it will be handled later with the context options */
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \
+ !defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_IS_BORINGSSL)
+ req_method = TLS_client_method();
+#else
+ req_method = SSLv23_client_method();
+#endif
+ use_sni(TRUE);
+ break;
+ case CURL_SSLVERSION_SSLv2:
+#ifdef OPENSSL_NO_SSL2
+ failf(data, "OpenSSL was built without SSLv2 support");
+ return CURLE_NOT_BUILT_IN;
+#else
+#ifdef USE_TLS_SRP
+ if(data->set.ssl.authtype == CURL_TLSAUTH_SRP)
+ return CURLE_SSL_CONNECT_ERROR;
+#endif
+ req_method = SSLv2_client_method();
+ use_sni(FALSE);
+ break;
+#endif
+ case CURL_SSLVERSION_SSLv3:
+#ifdef OPENSSL_NO_SSL3_METHOD
+ failf(data, "OpenSSL was built without SSLv3 support");
+ return CURLE_NOT_BUILT_IN;
+#else
+#ifdef USE_TLS_SRP
+ if(data->set.ssl.authtype == CURL_TLSAUTH_SRP)
+ return CURLE_SSL_CONNECT_ERROR;
+#endif
+ req_method = SSLv3_client_method();
+ use_sni(FALSE);
+ break;
+#endif
+ }
+
+ if(connssl->ctx)
+ SSL_CTX_free(connssl->ctx);
+ connssl->ctx = SSL_CTX_new(req_method);
+
+ if(!connssl->ctx) {
+ failf(data, "SSL: couldn't create a context: %s",
+ ERR_error_string(ERR_peek_error(), NULL));
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+#ifdef SSL_MODE_RELEASE_BUFFERS
+ SSL_CTX_set_mode(connssl->ctx, SSL_MODE_RELEASE_BUFFERS);
+#endif
+
+#ifdef SSL_CTRL_SET_MSG_CALLBACK
+ if(data->set.fdebug && data->set.verbose) {
+ /* the SSL trace callback is only used for verbose logging */
+ SSL_CTX_set_msg_callback(connssl->ctx, ssl_tls_trace);
+ SSL_CTX_set_msg_callback_arg(connssl->ctx, conn);
+ }
+#endif
+
+ /* OpenSSL contains code to work-around lots of bugs and flaws in various
+ SSL-implementations. SSL_CTX_set_options() is used to enabled those
+ work-arounds. The man page for this option states that SSL_OP_ALL enables
+ all the work-arounds and that "It is usually safe to use SSL_OP_ALL to
+ enable the bug workaround options if compatibility with somewhat broken
+ implementations is desired."
+
+ The "-no_ticket" option was introduced in Openssl0.9.8j. It's a flag to
+ disable "rfc4507bis session ticket support". rfc4507bis was later turned
+ into the proper RFC5077 it seems: https://tools.ietf.org/html/rfc5077
+
+ The enabled extension concerns the session management. I wonder how often
+ libcurl stops a connection and then resumes a TLS session. also, sending
+ the session data is some overhead. .I suggest that you just use your
+ proposed patch (which explicitly disables TICKET).
+
+ If someone writes an application with libcurl and openssl who wants to
+ enable the feature, one can do this in the SSL callback.
+
+ SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG option enabling allowed proper
+ interoperability with web server Netscape Enterprise Server 2.0.1 which
+ was released back in 1996.
+
+ Due to CVE-2010-4180, option SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG has
+ become ineffective as of OpenSSL 0.9.8q and 1.0.0c. In order to mitigate
+ CVE-2010-4180 when using previous OpenSSL versions we no longer enable
+ this option regardless of OpenSSL version and SSL_OP_ALL definition.
+
+ OpenSSL added a work-around for a SSL 3.0/TLS 1.0 CBC vulnerability
+ (https://www.openssl.org/~bodo/tls-cbc.txt). In 0.9.6e they added a bit to
+ SSL_OP_ALL that _disables_ that work-around despite the fact that
+ SSL_OP_ALL is documented to do "rather harmless" workarounds. In order to
+ keep the secure work-around, the SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS bit
+ must not be set.
+ */
+
+ ctx_options = SSL_OP_ALL;
+
+#ifdef SSL_OP_NO_TICKET
+ ctx_options |= SSL_OP_NO_TICKET;
+#endif
+
+#ifdef SSL_OP_NO_COMPRESSION
+ ctx_options |= SSL_OP_NO_COMPRESSION;
+#endif
+
+#ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
+ /* mitigate CVE-2010-4180 */
+ ctx_options &= ~SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG;
+#endif
+
+#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
+ /* unless the user explicitly ask to allow the protocol vulnerability we
+ use the work-around */
+ if(!conn->data->set.ssl_enable_beast)
+ ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
+#endif
+
+ switch(data->set.ssl.version) {
+ case CURL_SSLVERSION_SSLv3:
+#ifdef USE_TLS_SRP
+ if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
+ infof(data, "Set version TLSv1.x for SRP authorisation\n");
+ }
+#endif
+ ctx_options |= SSL_OP_NO_SSLv2;
+ ctx_options |= SSL_OP_NO_TLSv1;
+#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
+ ctx_options |= SSL_OP_NO_TLSv1_1;
+ ctx_options |= SSL_OP_NO_TLSv1_2;
+#endif
+ break;
+
+ case CURL_SSLVERSION_DEFAULT:
+ case CURL_SSLVERSION_TLSv1:
+ ctx_options |= SSL_OP_NO_SSLv2;
+ ctx_options |= SSL_OP_NO_SSLv3;
+ break;
+
+ case CURL_SSLVERSION_TLSv1_0:
+ ctx_options |= SSL_OP_NO_SSLv2;
+ ctx_options |= SSL_OP_NO_SSLv3;
+#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
+ ctx_options |= SSL_OP_NO_TLSv1_1;
+ ctx_options |= SSL_OP_NO_TLSv1_2;
+#endif
+ break;
+
+#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
+ case CURL_SSLVERSION_TLSv1_1:
+ ctx_options |= SSL_OP_NO_SSLv2;
+ ctx_options |= SSL_OP_NO_SSLv3;
+ ctx_options |= SSL_OP_NO_TLSv1;
+ ctx_options |= SSL_OP_NO_TLSv1_2;
+ break;
+
+ case CURL_SSLVERSION_TLSv1_2:
+ ctx_options |= SSL_OP_NO_SSLv2;
+ ctx_options |= SSL_OP_NO_SSLv3;
+ ctx_options |= SSL_OP_NO_TLSv1;
+ ctx_options |= SSL_OP_NO_TLSv1_1;
+ break;
+#endif
+
+#ifndef OPENSSL_NO_SSL2
+ case CURL_SSLVERSION_SSLv2:
+ ctx_options |= SSL_OP_NO_SSLv3;
+ ctx_options |= SSL_OP_NO_TLSv1;
+#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
+ ctx_options |= SSL_OP_NO_TLSv1_1;
+ ctx_options |= SSL_OP_NO_TLSv1_2;
+#endif
+ break;
+#endif
+
+ default:
+ failf(data, "Unsupported SSL protocol version");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
+ SSL_CTX_set_options(connssl->ctx, ctx_options);
+
+#ifdef HAS_NPN
+ if(data->set.ssl_enable_npn)
+ SSL_CTX_set_next_proto_select_cb(connssl->ctx, select_next_proto_cb, conn);
+#endif
+
+#ifdef HAS_ALPN
+ if(data->set.ssl_enable_alpn) {
+ int cur = 0;
+ unsigned char protocols[128];
+
+#ifdef USE_NGHTTP2
+ if(data->set.httpversion == CURL_HTTP_VERSION_2_0) {
+ protocols[cur++] = NGHTTP2_PROTO_VERSION_ID_LEN;
+
+ memcpy(&protocols[cur], NGHTTP2_PROTO_VERSION_ID,
+ NGHTTP2_PROTO_VERSION_ID_LEN);
+ cur += NGHTTP2_PROTO_VERSION_ID_LEN;
+ infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
+ }
+#endif
+
+ protocols[cur++] = ALPN_HTTP_1_1_LENGTH;
+ memcpy(&protocols[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH);
+ cur += ALPN_HTTP_1_1_LENGTH;
+ infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
+
+ /* expects length prefixed preference ordered list of protocols in wire
+ * format
+ */
+ SSL_CTX_set_alpn_protos(connssl->ctx, protocols, cur);
+ }
+#endif
+
+ if(data->set.str[STRING_CERT] || data->set.str[STRING_CERT_TYPE]) {
+ if(!cert_stuff(conn,
+ connssl->ctx,
+ data->set.str[STRING_CERT],
+ data->set.str[STRING_CERT_TYPE],
+ data->set.str[STRING_KEY],
+ data->set.str[STRING_KEY_TYPE])) {
+ /* failf() is already done in cert_stuff() */
+ return CURLE_SSL_CERTPROBLEM;
+ }
+ }
+
+ ciphers = data->set.str[STRING_SSL_CIPHER_LIST];
+ if(!ciphers)
+ ciphers = (char *)DEFAULT_CIPHER_SELECTION;
+ if(!SSL_CTX_set_cipher_list(connssl->ctx, ciphers)) {
+ failf(data, "failed setting cipher list: %s", ciphers);
+ return CURLE_SSL_CIPHER;
+ }
+ infof(data, "Cipher selection: %s\n", ciphers);
+
+#ifdef USE_TLS_SRP
+ if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
+ infof(data, "Using TLS-SRP username: %s\n", data->set.ssl.username);
+
+ if(!SSL_CTX_set_srp_username(connssl->ctx, data->set.ssl.username)) {
+ failf(data, "Unable to set SRP user name");
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+ if(!SSL_CTX_set_srp_password(connssl->ctx, data->set.ssl.password)) {
+ failf(data, "failed setting SRP password");
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+ if(!data->set.str[STRING_SSL_CIPHER_LIST]) {
+ infof(data, "Setting cipher list SRP\n");
+
+ if(!SSL_CTX_set_cipher_list(connssl->ctx, "SRP")) {
+ failf(data, "failed setting SRP cipher list");
+ return CURLE_SSL_CIPHER;
+ }
+ }
+ }
+#endif
+ if(data->set.str[STRING_SSL_CAFILE] || data->set.str[STRING_SSL_CAPATH]) {
+ /* tell SSL where to find CA certificates that are used to verify
+ the servers certificate. */
+ if(!SSL_CTX_load_verify_locations(connssl->ctx,
+ data->set.str[STRING_SSL_CAFILE],
+ data->set.str[STRING_SSL_CAPATH])) {
+ if(data->set.ssl.verifypeer) {
+ /* Fail if we insist on successfully verifying the server. */
+ failf(data, "error setting certificate verify locations:\n"
+ " CAfile: %s\n CApath: %s",
+ data->set.str[STRING_SSL_CAFILE]?
+ data->set.str[STRING_SSL_CAFILE]: "none",
+ data->set.str[STRING_SSL_CAPATH]?
+ data->set.str[STRING_SSL_CAPATH] : "none");
+ return CURLE_SSL_CACERT_BADFILE;
+ }
+ else {
+ /* Just continue with a warning if no strict certificate verification
+ is required. */
+ infof(data, "error setting certificate verify locations,"
+ " continuing anyway:\n");
+ }
+ }
+ else {
+ /* Everything is fine. */
+ infof(data, "successfully set certificate verify locations:\n");
+ }
+ infof(data,
+ " CAfile: %s\n"
+ " CApath: %s\n",
+ data->set.str[STRING_SSL_CAFILE] ? data->set.str[STRING_SSL_CAFILE]:
+ "none",
+ data->set.str[STRING_SSL_CAPATH] ? data->set.str[STRING_SSL_CAPATH]:
+ "none");
+ }
+
+ if(data->set.str[STRING_SSL_CRLFILE]) {
+ /* tell SSL where to find CRL file that is used to check certificate
+ * revocation */
+ lookup=X509_STORE_add_lookup(SSL_CTX_get_cert_store(connssl->ctx),
+ X509_LOOKUP_file());
+ if(!lookup ||
+ (!X509_load_crl_file(lookup, data->set.str[STRING_SSL_CRLFILE],
+ X509_FILETYPE_PEM)) ) {
+ failf(data, "error loading CRL file: %s",
+ data->set.str[STRING_SSL_CRLFILE]);
+ return CURLE_SSL_CRL_BADFILE;
+ }
+ else {
+ /* Everything is fine. */
+ infof(data, "successfully load CRL file:\n");
+ X509_STORE_set_flags(SSL_CTX_get_cert_store(connssl->ctx),
+ X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
+ }
+ infof(data,
+ " CRLfile: %s\n", data->set.str[STRING_SSL_CRLFILE] ?
+ data->set.str[STRING_SSL_CRLFILE]: "none");
+ }
+
+ /* Try building a chain using issuers in the trusted store first to avoid
+ problems with server-sent legacy intermediates.
+ Newer versions of OpenSSL do alternate chain checking by default which
+ gives us the same fix without as much of a performance hit (slight), so we
+ prefer that if available.
+ https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest
+ */
+#if defined(X509_V_FLAG_TRUSTED_FIRST) && !defined(X509_V_FLAG_NO_ALT_CHAINS)
+ if(data->set.ssl.verifypeer) {
+ X509_STORE_set_flags(SSL_CTX_get_cert_store(connssl->ctx),
+ X509_V_FLAG_TRUSTED_FIRST);
+ }
+#endif
+
+ /* SSL always tries to verify the peer, this only says whether it should
+ * fail to connect if the verification fails, or if it should continue
+ * anyway. In the latter case the result of the verification is checked with
+ * SSL_get_verify_result() below. */
+ SSL_CTX_set_verify(connssl->ctx,
+ data->set.ssl.verifypeer?SSL_VERIFY_PEER:SSL_VERIFY_NONE,
+ NULL);
+
+ /* give application a chance to interfere with SSL set up. */
+ if(data->set.ssl.fsslctx) {
+ result = (*data->set.ssl.fsslctx)(data, connssl->ctx,
+ data->set.ssl.fsslctxp);
+ if(result) {
+ failf(data, "error signaled by ssl ctx callback");
+ return result;
+ }
+ }
+
+ /* Lets make an SSL structure */
+ if(connssl->handle)
+ SSL_free(connssl->handle);
+ connssl->handle = SSL_new(connssl->ctx);
+ if(!connssl->handle) {
+ failf(data, "SSL: couldn't create a context (handle)!");
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
+ !defined(OPENSSL_IS_BORINGSSL)
+ if(data->set.ssl.verifystatus)
+ SSL_set_tlsext_status_type(connssl->handle, TLSEXT_STATUSTYPE_ocsp);
+#endif
+
+ SSL_set_connect_state(connssl->handle);
+
+ connssl->server_cert = 0x0;
+
+#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
+ if((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr)) &&
+#ifdef ENABLE_IPV6
+ (0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) &&
+#endif
+ sni &&
+ !SSL_set_tlsext_host_name(connssl->handle, conn->host.name))
+ infof(data, "WARNING: failed to configure server name indication (SNI) "
+ "TLS extension\n");
+#endif
+
+ /* Check if there's a cached ID we can/should use here! */
+ if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) {
+ /* we got a session id, use it! */
+ if(!SSL_set_session(connssl->handle, ssl_sessionid)) {
+ failf(data, "SSL: SSL_set_session failed: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ /* Informational message */
+ infof (data, "SSL re-using session ID\n");
+ }
+
+ /* pass the raw socket into the SSL layers */
+ if(!SSL_set_fd(connssl->handle, (int)sockfd)) {
+ failf(data, "SSL: SSL_set_fd failed: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
+ connssl->connecting_state = ssl_connect_2;
+
+ return CURLE_OK;
+}
+
+static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
+{
+ struct SessionHandle *data = conn->data;
+ int err;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
+ || ssl_connect_2_reading == connssl->connecting_state
+ || ssl_connect_2_writing == connssl->connecting_state);
+
+ ERR_clear_error();
+
+ err = SSL_connect(connssl->handle);
+
+ /* 1 is fine
+ 0 is "not successful but was shut down controlled"
+ <0 is "handshake was not successful, because a fatal error occurred" */
+ if(1 != err) {
+ int detail = SSL_get_error(connssl->handle, err);
+
+ if(SSL_ERROR_WANT_READ == detail) {
+ connssl->connecting_state = ssl_connect_2_reading;
+ return CURLE_OK;
+ }
+ else if(SSL_ERROR_WANT_WRITE == detail) {
+ connssl->connecting_state = ssl_connect_2_writing;
+ return CURLE_OK;
+ }
+ else {
+ /* untreated error */
+ unsigned long errdetail;
+ char error_buffer[256]=""; /* OpenSSL documents that this must be at
+ least 256 bytes long. */
+ CURLcode result;
+ long lerr;
+
+ connssl->connecting_state = ssl_connect_2; /* the connection failed,
+ we're not waiting for
+ anything else. */
+
+ errdetail = ERR_get_error(); /* Gets the earliest error code from the
+ thread's error queue and removes the
+ entry. */
+
+ switch(errdetail) {
+ case 0x1407E086:
+ /* 1407E086:
+ SSL routines:
+ SSL2_SET_CERTIFICATE:
+ certificate verify failed */
+ /* fall-through */
+ case 0x14090086:
+ /* 14090086:
+ SSL routines:
+ SSL3_GET_SERVER_CERTIFICATE:
+ certificate verify failed */
+ result = CURLE_SSL_CACERT;
+
+ lerr = SSL_get_verify_result(connssl->handle);
+ if(lerr != X509_V_OK) {
+ snprintf(error_buffer, sizeof(error_buffer),
+ "SSL certificate problem: %s",
+ X509_verify_cert_error_string(lerr));
+ }
+ else
+ /* strcpy() is fine here as long as the string fits within
+ error_buffer */
+ strcpy(error_buffer,
+ "SSL certificate problem, check your CA cert");
+ break;
+ default:
+ result = CURLE_SSL_CONNECT_ERROR;
+ SSL_strerror(errdetail, error_buffer, sizeof(error_buffer));
+ break;
+ }
+
+ /* detail is already set to the SSL error above */
+
+ /* If we e.g. use SSLv2 request-method and the server doesn't like us
+ * (RST connection etc.), OpenSSL gives no explanation whatsoever and
+ * the SO_ERROR is also lost.
+ */
+ if(CURLE_SSL_CONNECT_ERROR == result && errdetail == 0) {
+ failf(data, "Unknown SSL protocol error in connection to %s:%ld ",
+ conn->host.name, conn->remote_port);
+ return result;
+ }
+
+ /* Could be a CERT problem */
+ failf(data, "%s", error_buffer);
+
+ return result;
+ }
+ }
+ else {
+ /* we have been connected fine, we're not waiting for anything else. */
+ connssl->connecting_state = ssl_connect_3;
+
+ /* Informational message */
+ infof(data, "SSL connection using %s / %s\n",
+ get_ssl_version_txt(connssl->handle),
+ SSL_get_cipher(connssl->handle));
+
+#ifdef HAS_ALPN
+ /* Sets data and len to negotiated protocol, len is 0 if no protocol was
+ * negotiated
+ */
+ if(data->set.ssl_enable_alpn) {
+ const unsigned char* neg_protocol;
+ unsigned int len;
+ SSL_get0_alpn_selected(connssl->handle, &neg_protocol, &len);
+ if(len != 0) {
+ infof(data, "ALPN, server accepted to use %.*s\n", len, neg_protocol);
+
+#ifdef USE_NGHTTP2
+ if(len == NGHTTP2_PROTO_VERSION_ID_LEN &&
+ !memcmp(NGHTTP2_PROTO_VERSION_ID, neg_protocol, len)) {
+ conn->negnpn = CURL_HTTP_VERSION_2_0;
+ }
+ else
+#endif
+ if(len == ALPN_HTTP_1_1_LENGTH &&
+ !memcmp(ALPN_HTTP_1_1, neg_protocol, ALPN_HTTP_1_1_LENGTH)) {
+ conn->negnpn = CURL_HTTP_VERSION_1_1;
+ }
+ }
+ else
+ infof(data, "ALPN, server did not agree to a protocol\n");
+ }
+#endif
+
+ return CURLE_OK;
+ }
+}
+
+static int asn1_object_dump(ASN1_OBJECT *a, char *buf, size_t len)
+{
+ int i, ilen;
+
+ if((ilen = (int)len) < 0)
+ return 1; /* buffer too big */
+
+ i = i2t_ASN1_OBJECT(buf, ilen, a);
+
+ if(i >= ilen)
+ return 1; /* buffer too small */
+
+ return 0;
+}
+
+static void pubkey_show(struct SessionHandle *data,
+ int num,
+ const char *type,
+ const char *name,
+ unsigned char *raw,
+ int len)
+{
+ size_t left;
+ int i;
+ char namebuf[32];
+ char *buffer;
+
+ left = len*3 + 1;
+ buffer = malloc(left);
+ if(buffer) {
+ char *ptr=buffer;
+ snprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name);
+ for(i=0; i< len; i++) {
+ snprintf(ptr, left, "%02x:", raw[i]);
+ ptr += 3;
+ left -= 3;
+ }
+ infof(data, " %s: %s\n", namebuf, buffer);
+ Curl_ssl_push_certinfo(data, num, namebuf, buffer);
+ free(buffer);
+ }
+}
+
+#define print_pubkey_BN(_type, _name, _num) \
+do { \
+ if(pubkey->pkey._type->_name) { \
+ int len = BN_num_bytes(pubkey->pkey._type->_name); \
+ if(len < CERTBUFFERSIZE) { \
+ BN_bn2bin(pubkey->pkey._type->_name, (unsigned char*)bufp); \
+ bufp[len] = 0; \
+ pubkey_show(data, _num, #_type, #_name, (unsigned char*)bufp, len); \
+ } \
+ } \
+} WHILE_FALSE
+
+static int X509V3_ext(struct SessionHandle *data,
+ int certnum,
+ STACK_OF(X509_EXTENSION) *exts)
+{
+ int i;
+ size_t j;
+
+ if(sk_X509_EXTENSION_num(exts) <= 0)
+ /* no extensions, bail out */
+ return 1;
+
+ for(i=0; i<sk_X509_EXTENSION_num(exts); i++) {
+ ASN1_OBJECT *obj;
+ X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
+ BUF_MEM *biomem;
+ char buf[512];
+ char *ptr=buf;
+ char namebuf[128];
+ BIO *bio_out = BIO_new(BIO_s_mem());
+
+ if(!bio_out)
+ return 1;
+
+ obj = X509_EXTENSION_get_object(ext);
+
+ asn1_object_dump(obj, namebuf, sizeof(namebuf));
+
+ infof(data, "%s: %s\n", namebuf,
+ X509_EXTENSION_get_critical(ext)?"(critical)":"");
+
+ if(!X509V3_EXT_print(bio_out, ext, 0, 0))
+ ASN1_STRING_print(bio_out, (ASN1_STRING *)X509_EXTENSION_get_data(ext));
+
+ BIO_get_mem_ptr(bio_out, &biomem);
+
+ /* biomem->length bytes at biomem->data, this little loop here is only
+ done for the infof() call, we send the "raw" data to the certinfo
+ function */
+ for(j=0; j<(size_t)biomem->length; j++) {
+ const char *sep="";
+ if(biomem->data[j] == '\n') {
+ sep=", ";
+ j++; /* skip the newline */
+ };
+ while((j<(size_t)biomem->length) && (biomem->data[j] == ' '))
+ j++;
+ if(j<(size_t)biomem->length)
+ ptr+=snprintf(ptr, sizeof(buf)-(ptr-buf), "%s%c", sep,
+ biomem->data[j]);
+ }
+ infof(data, " %s\n", buf);
+
+ Curl_ssl_push_certinfo(data, certnum, namebuf, buf);
+
+ BIO_free(bio_out);
+
+ }
+ return 0; /* all is fine */
+}
+
+
+static void X509_signature(struct SessionHandle *data,
+ int numcert,
+ ASN1_STRING *sig)
+{
+ char buf[1024];
+ char *ptr = buf;
+ int i;
+
+ for(i=0; i<sig->length; i++)
+ ptr+=snprintf(ptr, sizeof(buf)-(ptr-buf), "%02x:", sig->data[i]);
+
+ infof(data, " Signature: %s\n", buf);
+ Curl_ssl_push_certinfo(data, numcert, "Signature", buf);
+}
+
+static void dumpcert(struct SessionHandle *data, X509 *x, int numcert)
+{
+ BIO *bio_out = BIO_new(BIO_s_mem());
+ BUF_MEM *biomem;
+
+ /* this outputs the cert in this 64 column wide style with newlines and
+ -----BEGIN CERTIFICATE----- texts and more */
+ PEM_write_bio_X509(bio_out, x);
+
+ BIO_get_mem_ptr(bio_out, &biomem);
+
+ Curl_ssl_push_certinfo_len(data, numcert,
+ "Cert", biomem->data, biomem->length);
+
+ BIO_free(bio_out);
+}
+
+/*
+ * This size was previously 512 which has been reported "too small" without
+ * any specifics, so it was enlarged to allow more data to get shown uncut.
+ * The "perfect" size is yet to figure out.
+ */
+#define CERTBUFFERSIZE 8192
+
+static CURLcode get_cert_chain(struct connectdata *conn,
+ struct ssl_connect_data *connssl)
+
+{
+ CURLcode result;
+ STACK_OF(X509) *sk;
+ int i;
+ char *bufp;
+ struct SessionHandle *data = conn->data;
+ int numcerts;
+
+ bufp = malloc(CERTBUFFERSIZE);
+ if(!bufp)
+ return CURLE_OUT_OF_MEMORY;
+
+ sk = SSL_get_peer_cert_chain(connssl->handle);
+ if(!sk) {
+ free(bufp);
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ numcerts = sk_X509_num(sk);
+
+ result = Curl_ssl_init_certinfo(data, numcerts);
+ if(result) {
+ free(bufp);
+ return result;
+ }
+
+ infof(data, "--- Certificate chain\n");
+ for(i=0; i<numcerts; i++) {
+ long value;
+ ASN1_INTEGER *num;
+ ASN1_TIME *certdate;
+
+ /* get the certs in "importance order" */
+#if 0
+ X509 *x = sk_X509_value(sk, numcerts - i - 1);
+#else
+ X509 *x = sk_X509_value(sk, i);
+#endif
+
+ X509_CINF *cinf;
+ EVP_PKEY *pubkey=NULL;
+ int j;
+ char *ptr;
+
+ (void)x509_name_oneline(X509_get_subject_name(x), bufp, CERTBUFFERSIZE);
+ infof(data, "%2d Subject: %s\n", i, bufp);
+ Curl_ssl_push_certinfo(data, i, "Subject", bufp);
+
+ (void)x509_name_oneline(X509_get_issuer_name(x), bufp, CERTBUFFERSIZE);
+ infof(data, " Issuer: %s\n", bufp);
+ Curl_ssl_push_certinfo(data, i, "Issuer", bufp);
+
+ value = X509_get_version(x);
+ infof(data, " Version: %lu (0x%lx)\n", value+1, value);
+ snprintf(bufp, CERTBUFFERSIZE, "%lx", value);
+ Curl_ssl_push_certinfo(data, i, "Version", bufp); /* hex */
+
+ num=X509_get_serialNumber(x);
+ {
+ int left = CERTBUFFERSIZE;
+
+ ptr = bufp;
+ if(num->type == V_ASN1_NEG_INTEGER) {
+ *ptr++='-';
+ left--;
+ }
+
+ for(j=0; (j<num->length) && (left>=3); j++) {
+ snprintf(ptr, left, "%02x", num->data[j]);
+ ptr += 2;
+ left -= 2;
+ }
+ if(num->length)
+ infof(data, " Serial Number: %s\n", bufp);
+ else
+ bufp[0]=0;
+ }
+ if(bufp[0])
+ Curl_ssl_push_certinfo(data, i, "Serial Number", bufp); /* hex */
+
+ cinf = x->cert_info;
+
+ j = asn1_object_dump(cinf->signature->algorithm, bufp, CERTBUFFERSIZE);
+ if(!j) {
+ infof(data, " Signature Algorithm: %s\n", bufp);
+ Curl_ssl_push_certinfo(data, i, "Signature Algorithm", bufp);
+ }
+
+ certdate = X509_get_notBefore(x);
+ asn1_output(certdate, bufp, CERTBUFFERSIZE);
+ infof(data, " Start date: %s\n", bufp);
+ Curl_ssl_push_certinfo(data, i, "Start date", bufp);
+
+ certdate = X509_get_notAfter(x);
+ asn1_output(certdate, bufp, CERTBUFFERSIZE);
+ infof(data, " Expire date: %s\n", bufp);
+ Curl_ssl_push_certinfo(data, i, "Expire date", bufp);
+
+ j = asn1_object_dump(cinf->key->algor->algorithm, bufp, CERTBUFFERSIZE);
+ if(!j) {
+ infof(data, " Public Key Algorithm: %s\n", bufp);
+ Curl_ssl_push_certinfo(data, i, "Public Key Algorithm", bufp);
+ }
+
+ pubkey = X509_get_pubkey(x);
+ if(!pubkey)
+ infof(data, " Unable to load public key\n");
+ else {
+ switch(pubkey->type) {
+ case EVP_PKEY_RSA:
+ infof(data, " RSA Public Key (%d bits)\n",
+ BN_num_bits(pubkey->pkey.rsa->n));
+ snprintf(bufp, CERTBUFFERSIZE, "%d", BN_num_bits(pubkey->pkey.rsa->n));
+ Curl_ssl_push_certinfo(data, i, "RSA Public Key", bufp);
+
+ print_pubkey_BN(rsa, n, i);
+ print_pubkey_BN(rsa, e, i);
+ print_pubkey_BN(rsa, d, i);
+ print_pubkey_BN(rsa, p, i);
+ print_pubkey_BN(rsa, q, i);
+ print_pubkey_BN(rsa, dmp1, i);
+ print_pubkey_BN(rsa, dmq1, i);
+ print_pubkey_BN(rsa, iqmp, i);
+ break;
+ case EVP_PKEY_DSA:
+ print_pubkey_BN(dsa, p, i);
+ print_pubkey_BN(dsa, q, i);
+ print_pubkey_BN(dsa, g, i);
+ print_pubkey_BN(dsa, priv_key, i);
+ print_pubkey_BN(dsa, pub_key, i);
+ break;
+ case EVP_PKEY_DH:
+ print_pubkey_BN(dh, p, i);
+ print_pubkey_BN(dh, g, i);
+ print_pubkey_BN(dh, priv_key, i);
+ print_pubkey_BN(dh, pub_key, i);
+ break;
+#if 0
+ case EVP_PKEY_EC: /* symbol not present in OpenSSL 0.9.6 */
+ /* left TODO */
+ break;
+#endif
+ }
+ EVP_PKEY_free(pubkey);
+ }
+
+ X509V3_ext(data, i, cinf->extensions);
+
+ X509_signature(data, i, x->signature);
+
+ dumpcert(data, x, i);
+ }
+
+ free(bufp);
+
+ return CURLE_OK;
+}
+
+/*
+ * Heavily modified from:
+ * https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#OpenSSL
+ */
+static CURLcode pkp_pin_peer_pubkey(X509* cert, const char *pinnedpubkey)
+{
+ /* Scratch */
+ int len1 = 0, len2 = 0;
+ unsigned char *buff1 = NULL, *temp = NULL;
+
+ /* Result is returned to caller */
+ CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+
+ /* if a path wasn't specified, don't pin */
+ if(!pinnedpubkey)
+ return CURLE_OK;
+
+ if(!cert)
+ return result;
+
+ do {
+ /* Begin Gyrations to get the subjectPublicKeyInfo */
+ /* Thanks to Viktor Dukhovni on the OpenSSL mailing list */
+
+ /* https://groups.google.com/group/mailing.openssl.users/browse_thread
+ /thread/d61858dae102c6c7 */
+ len1 = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), NULL);
+ if(len1 < 1)
+ break; /* failed */
+
+ /* https://www.openssl.org/docs/crypto/buffer.html */
+ buff1 = temp = OPENSSL_malloc(len1);
+ if(!buff1)
+ break; /* failed */
+
+ /* https://www.openssl.org/docs/crypto/d2i_X509.html */
+ len2 = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &temp);
+
+ /*
+ * These checks are verifying we got back the same values as when we
+ * sized the buffer. It's pretty weak since they should always be the
+ * same. But it gives us something to test.
+ */
+ if((len1 != len2) || !temp || ((temp - buff1) != len1))
+ break; /* failed */
+
+ /* End Gyrations */
+
+ /* The one good exit point */
+ result = Curl_pin_peer_pubkey(pinnedpubkey, buff1, len1);
+ } while(0);
+
+ /* https://www.openssl.org/docs/crypto/buffer.html */
+ if(buff1)
+ OPENSSL_free(buff1);
+
+ return result;
+}
+
+/*
+ * Get the server cert, verify it and show it etc, only call failf() if the
+ * 'strict' argument is TRUE as otherwise all this is for informational
+ * purposes only!
+ *
+ * We check certificates to authenticate the server; otherwise we risk
+ * man-in-the-middle attack.
+ */
+static CURLcode servercert(struct connectdata *conn,
+ struct ssl_connect_data *connssl,
+ bool strict)
+{
+ CURLcode result = CURLE_OK;
+ int rc;
+ long lerr;
+ ASN1_TIME *certdate;
+ struct SessionHandle *data = conn->data;
+ X509 *issuer;
+ FILE *fp;
+ char *buffer = data->state.buffer;
+ const char *ptr;
+
+ if(data->set.ssl.certinfo)
+ /* we've been asked to gather certificate info! */
+ (void)get_cert_chain(conn, connssl);
+
+ connssl->server_cert = SSL_get_peer_certificate(connssl->handle);
+ if(!connssl->server_cert) {
+ if(strict)
+ failf(data, "SSL: couldn't get peer certificate!");
+ return CURLE_PEER_FAILED_VERIFICATION;
+ }
+
+ infof(data, "Server certificate:\n");
+
+ rc = x509_name_oneline(X509_get_subject_name(connssl->server_cert),
+ buffer, BUFSIZE);
+ infof(data, "\t subject: %s\n", rc?"[NONE]":buffer);
+
+ certdate = X509_get_notBefore(connssl->server_cert);
+ asn1_output(certdate, buffer, BUFSIZE);
+ infof(data, "\t start date: %s\n", buffer);
+
+ certdate = X509_get_notAfter(connssl->server_cert);
+ asn1_output(certdate, buffer, BUFSIZE);
+ infof(data, "\t expire date: %s\n", buffer);
+
+ if(data->set.ssl.verifyhost) {
+ result = verifyhost(conn, connssl->server_cert);
+ if(result) {
+ X509_free(connssl->server_cert);
+ connssl->server_cert = NULL;
+ return result;
+ }
+ }
+
+ rc = x509_name_oneline(X509_get_issuer_name(connssl->server_cert),
+ buffer, BUFSIZE);
+ if(rc) {
+ if(strict)
+ failf(data, "SSL: couldn't get X509-issuer name!");
+ result = CURLE_SSL_CONNECT_ERROR;
+ }
+ else {
+ infof(data, "\t issuer: %s\n", buffer);
+
+ /* We could do all sorts of certificate verification stuff here before
+ deallocating the certificate. */
+
+ /* e.g. match issuer name with provided issuer certificate */
+ if(data->set.str[STRING_SSL_ISSUERCERT]) {
+ fp = fopen(data->set.str[STRING_SSL_ISSUERCERT], FOPEN_READTEXT);
+ if(!fp) {
+ if(strict)
+ failf(data, "SSL: Unable to open issuer cert (%s)",
+ data->set.str[STRING_SSL_ISSUERCERT]);
+ X509_free(connssl->server_cert);
+ connssl->server_cert = NULL;
+ return CURLE_SSL_ISSUER_ERROR;
+ }
+
+ issuer = PEM_read_X509(fp, NULL, ZERO_NULL, NULL);
+ if(!issuer) {
+ if(strict)
+ failf(data, "SSL: Unable to read issuer cert (%s)",
+ data->set.str[STRING_SSL_ISSUERCERT]);
+ X509_free(connssl->server_cert);
+ X509_free(issuer);
+ fclose(fp);
+ return CURLE_SSL_ISSUER_ERROR;
+ }
+
+ fclose(fp);
+
+ if(X509_check_issued(issuer, connssl->server_cert) != X509_V_OK) {
+ if(strict)
+ failf(data, "SSL: Certificate issuer check failed (%s)",
+ data->set.str[STRING_SSL_ISSUERCERT]);
+ X509_free(connssl->server_cert);
+ X509_free(issuer);
+ connssl->server_cert = NULL;
+ return CURLE_SSL_ISSUER_ERROR;
+ }
+
+ infof(data, "\t SSL certificate issuer check ok (%s)\n",
+ data->set.str[STRING_SSL_ISSUERCERT]);
+ X509_free(issuer);
+ }
+
+ lerr = data->set.ssl.certverifyresult =
+ SSL_get_verify_result(connssl->handle);
+
+ if(data->set.ssl.certverifyresult != X509_V_OK) {
+ if(data->set.ssl.verifypeer) {
+ /* We probably never reach this, because SSL_connect() will fail
+ and we return earlier if verifypeer is set? */
+ if(strict)
+ failf(data, "SSL certificate verify result: %s (%ld)",
+ X509_verify_cert_error_string(lerr), lerr);
+ result = CURLE_PEER_FAILED_VERIFICATION;
+ }
+ else
+ infof(data, "\t SSL certificate verify result: %s (%ld),"
+ " continuing anyway.\n",
+ X509_verify_cert_error_string(lerr), lerr);
+ }
+ else
+ infof(data, "\t SSL certificate verify ok.\n");
+ }
+
+#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
+ !defined(OPENSSL_IS_BORINGSSL)
+ if(data->set.ssl.verifystatus) {
+ result = verifystatus(conn, connssl);
+ if(result) {
+ X509_free(connssl->server_cert);
+ connssl->server_cert = NULL;
+ return result;
+ }
+ }
+#endif
+
+ if(!strict)
+ /* when not strict, we don't bother about the verify cert problems */
+ result = CURLE_OK;
+
+ ptr = data->set.str[STRING_SSL_PINNEDPUBLICKEY];
+ if(!result && ptr) {
+ result = pkp_pin_peer_pubkey(connssl->server_cert, ptr);
+ if(result)
+ failf(data, "SSL: public key does not match pinned public key!");
+ }
+
+ X509_free(connssl->server_cert);
+ connssl->server_cert = NULL;
+ connssl->connecting_state = ssl_connect_done;
+
+ return result;
+}
+
+static CURLcode ossl_connect_step3(struct connectdata *conn, int sockindex)
+{
+ CURLcode result = CURLE_OK;
+ void *old_ssl_sessionid = NULL;
+ struct SessionHandle *data = conn->data;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ bool incache;
+ SSL_SESSION *our_ssl_sessionid;
+
+ DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
+
+ our_ssl_sessionid = SSL_get1_session(connssl->handle);
+
+ /* SSL_get1_session() will increment the reference count and the session
+ will stay in memory until explicitly freed with SSL_SESSION_free(3),
+ regardless of its state. */
+
+ incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL));
+ if(incache) {
+ if(old_ssl_sessionid != our_ssl_sessionid) {
+ infof(data, "old SSL session ID is stale, removing\n");
+ Curl_ssl_delsessionid(conn, old_ssl_sessionid);
+ incache = FALSE;
+ }
+ }
+
+ if(!incache) {
+ result = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
+ 0 /* unknown size */);
+ if(result) {
+ failf(data, "failed to store ssl session");
+ return result;
+ }
+ }
+ else {
+ /* Session was incache, so refcount already incremented earlier.
+ * Avoid further increments with each SSL_get1_session() call.
+ * This does not free the session as refcount remains > 0
+ */
+ SSL_SESSION_free(our_ssl_sessionid);
+ }
+
+ /*
+ * We check certificates to authenticate the server; otherwise we risk
+ * man-in-the-middle attack; NEVERTHELESS, if we're told explicitly not to
+ * verify the peer ignore faults and failures from the server cert
+ * operations.
+ */
+
+ result = servercert(conn, connssl,
+ (data->set.ssl.verifypeer || data->set.ssl.verifyhost));
+
+ if(!result)
+ connssl->connecting_state = ssl_connect_done;
+
+ return result;
+}
+
+static Curl_recv ossl_recv;
+static Curl_send ossl_send;
+
+static CURLcode ossl_connect_common(struct connectdata *conn,
+ int sockindex,
+ bool nonblocking,
+ bool *done)
+{
+ CURLcode result;
+ struct SessionHandle *data = conn->data;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ curl_socket_t sockfd = conn->sock[sockindex];
+ long timeout_ms;
+ int what;
+
+ /* check if the connection has already been established */
+ if(ssl_connection_complete == connssl->state) {
+ *done = TRUE;
+ return CURLE_OK;
+ }
+
+ if(ssl_connect_1 == connssl->connecting_state) {
+ /* Find out how much more time we're allowed */
+ timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+ if(timeout_ms < 0) {
+ /* no need to continue if time already is up */
+ failf(data, "SSL connection timeout");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+
+ result = ossl_connect_step1(conn, sockindex);
+ if(result)
+ return result;
+ }
+
+ while(ssl_connect_2 == connssl->connecting_state ||
+ ssl_connect_2_reading == connssl->connecting_state ||
+ ssl_connect_2_writing == connssl->connecting_state) {
+
+ /* check allowed time left */
+ timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+ if(timeout_ms < 0) {
+ /* no need to continue if time already is up */
+ failf(data, "SSL connection timeout");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+
+ /* if ssl is expecting something, check if it's available. */
+ if(connssl->connecting_state == ssl_connect_2_reading ||
+ connssl->connecting_state == ssl_connect_2_writing) {
+
+ curl_socket_t writefd = ssl_connect_2_writing==
+ connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+ curl_socket_t readfd = ssl_connect_2_reading==
+ connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+
+ what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
+ if(what < 0) {
+ /* fatal error */
+ failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ else if(0 == what) {
+ if(nonblocking) {
+ *done = FALSE;
+ return CURLE_OK;
+ }
+ else {
+ /* timeout */
+ failf(data, "SSL connection timeout");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+ }
+ /* socket is readable or writable */
+ }
+
+ /* Run transaction, and return to the caller if it failed or if this
+ * connection is done nonblocking and this loop would execute again. This
+ * permits the owner of a multi handle to abort a connection attempt
+ * before step2 has completed while ensuring that a client using select()
+ * or epoll() will always have a valid fdset to wait on.
+ */
+ result = ossl_connect_step2(conn, sockindex);
+ if(result || (nonblocking &&
+ (ssl_connect_2 == connssl->connecting_state ||
+ ssl_connect_2_reading == connssl->connecting_state ||
+ ssl_connect_2_writing == connssl->connecting_state)))
+ return result;
+
+ } /* repeat step2 until all transactions are done. */
+
+ if(ssl_connect_3 == connssl->connecting_state) {
+ result = ossl_connect_step3(conn, sockindex);
+ if(result)
+ return result;
+ }
+
+ if(ssl_connect_done == connssl->connecting_state) {
+ connssl->state = ssl_connection_complete;
+ conn->recv[sockindex] = ossl_recv;
+ conn->send[sockindex] = ossl_send;
+ *done = TRUE;
+ }
+ else
+ *done = FALSE;
+
+ /* Reset our connect state machine */
+ connssl->connecting_state = ssl_connect_1;
+
+ return CURLE_OK;
+}
+
+CURLcode Curl_ossl_connect_nonblocking(struct connectdata *conn,
+ int sockindex,
+ bool *done)
+{
+ return ossl_connect_common(conn, sockindex, TRUE, done);
+}
+
+CURLcode Curl_ossl_connect(struct connectdata *conn, int sockindex)
+{
+ CURLcode result;
+ bool done = FALSE;
+
+ result = ossl_connect_common(conn, sockindex, FALSE, &done);
+ if(result)
+ return result;
+
+ DEBUGASSERT(done);
+
+ return CURLE_OK;
+}
+
+bool Curl_ossl_data_pending(const struct connectdata *conn, int connindex)
+{
+ if(conn->ssl[connindex].handle)
+ /* SSL is in use */
+ return (0 != SSL_pending(conn->ssl[connindex].handle)) ? TRUE : FALSE;
+ else
+ return FALSE;
+}
+
+static ssize_t ossl_send(struct connectdata *conn,
+ int sockindex,
+ const void *mem,
+ size_t len,
+ CURLcode *curlcode)
+{
+ /* SSL_write() is said to return 'int' while write() and send() returns
+ 'size_t' */
+ int err;
+ char error_buffer[120]; /* OpenSSL documents that this must be at least 120
+ bytes long. */
+ unsigned long sslerror;
+ int memlen;
+ int rc;
+
+ ERR_clear_error();
+
+ memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
+ rc = SSL_write(conn->ssl[sockindex].handle, mem, memlen);
+
+ if(rc <= 0) {
+ err = SSL_get_error(conn->ssl[sockindex].handle, rc);
+
+ switch(err) {
+ case SSL_ERROR_WANT_READ:
+ case SSL_ERROR_WANT_WRITE:
+ /* The operation did not complete; the same TLS/SSL I/O function
+ should be called again later. This is basically an EWOULDBLOCK
+ equivalent. */
+ *curlcode = CURLE_AGAIN;
+ return -1;
+ case SSL_ERROR_SYSCALL:
+ failf(conn->data, "SSL_write() returned SYSCALL, errno = %d",
+ SOCKERRNO);
+ *curlcode = CURLE_SEND_ERROR;
+ return -1;
+ case SSL_ERROR_SSL:
+ /* A failure in the SSL library occurred, usually a protocol error.
+ The OpenSSL error queue contains more information on the error. */
+ sslerror = ERR_get_error();
+ failf(conn->data, "SSL_write() error: %s",
+ ERR_error_string(sslerror, error_buffer));
+ *curlcode = CURLE_SEND_ERROR;
+ return -1;
+ }
+ /* a true error */
+ failf(conn->data, "SSL_write() return error %d", err);
+ *curlcode = CURLE_SEND_ERROR;
+ return -1;
+ }
+ *curlcode = CURLE_OK;
+ return (ssize_t)rc; /* number of bytes */
+}
+
+static ssize_t ossl_recv(struct connectdata *conn, /* connection data */
+ int num, /* socketindex */
+ char *buf, /* store read data here */
+ size_t buffersize, /* max amount to read */
+ CURLcode *curlcode)
+{
+ char error_buffer[120]; /* OpenSSL documents that this must be at
+ least 120 bytes long. */
+ unsigned long sslerror;
+ ssize_t nread;
+ int buffsize;
+
+ ERR_clear_error();
+
+ buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
+ nread = (ssize_t)SSL_read(conn->ssl[num].handle, buf, buffsize);
+ if(nread <= 0) {
+ /* failed SSL_read */
+ int err = SSL_get_error(conn->ssl[num].handle, (int)nread);
+
+ switch(err) {
+ case SSL_ERROR_NONE: /* this is not an error */
+ case SSL_ERROR_ZERO_RETURN: /* no more data */
+ break;
+ case SSL_ERROR_WANT_READ:
+ case SSL_ERROR_WANT_WRITE:
+ /* there's data pending, re-invoke SSL_read() */
+ *curlcode = CURLE_AGAIN;
+ return -1;
+ default:
+ /* openssl/ssl.h for SSL_ERROR_SYSCALL says "look at error stack/return
+ value/errno" */
+ /* https://www.openssl.org/docs/crypto/ERR_get_error.html */
+ sslerror = ERR_get_error();
+ if((nread < 0) || sslerror) {
+ /* If the return code was negative or there actually is an error in the
+ queue */
+ failf(conn->data, "SSL read: %s, errno %d",
+ ERR_error_string(sslerror, error_buffer),
+ SOCKERRNO);
+ *curlcode = CURLE_RECV_ERROR;
+ return -1;
+ }
+ }
+ }
+ return nread;
+}
+
+size_t Curl_ossl_version(char *buffer, size_t size)
+{
+#ifdef YASSL_VERSION
+ /* yassl provides an OpenSSL API compatibility layer so it looks identical
+ to OpenSSL in all other aspects */
+ return snprintf(buffer, size, "yassl/%s", YASSL_VERSION);
+#else /* YASSL_VERSION */
+#ifdef OPENSSL_IS_BORINGSSL
+ return snprintf(buffer, size, "BoringSSL");
+#else /* OPENSSL_IS_BORINGSSL */
+
+#if(OPENSSL_VERSION_NUMBER >= 0x905000)
+ {
+ char sub[3];
+ unsigned long ssleay_value;
+ sub[2]='\0';
+ sub[1]='\0';
+ ssleay_value=SSLeay();
+ if(ssleay_value < 0x906000) {
+ ssleay_value=SSLEAY_VERSION_NUMBER;
+ sub[0]='\0';
+ }
+ else {
+ if(ssleay_value&0xff0) {
+ int minor_ver = (ssleay_value >> 4) & 0xff;
+ if(minor_ver > 26) {
+ /* handle extended version introduced for 0.9.8za */
+ sub[1] = (char) ((minor_ver - 1) % 26 + 'a' + 1);
+ sub[0] = 'z';
+ }
+ else {
+ sub[0]=(char)(((ssleay_value>>4)&0xff) + 'a' -1);
+ }
+ }
+ else
+ sub[0]='\0';
+ }
+
+ return snprintf(buffer, size, "%s/%lx.%lx.%lx%s",
+#ifdef LIBRESSL_VERSION_NUMBER
+ "LibreSSL"
+#else
+ "OpenSSL"
+#endif
+ , (ssleay_value>>28)&0xf,
+ (ssleay_value>>20)&0xff,
+ (ssleay_value>>12)&0xff,
+ sub);
+ }
+
+#else /* OPENSSL_VERSION_NUMBER is less than 0.9.5 */
+
+#if(OPENSSL_VERSION_NUMBER >= 0x900000)
+ return snprintf(buffer, size, "OpenSSL/%lx.%lx.%lx",
+ (OPENSSL_VERSION_NUMBER>>28)&0xff,
+ (OPENSSL_VERSION_NUMBER>>20)&0xff,
+ (OPENSSL_VERSION_NUMBER>>12)&0xf);
+
+#else /* (OPENSSL_VERSION_NUMBER >= 0x900000) */
+ {
+ char sub[2];
+ sub[1]='\0';
+ if(OPENSSL_VERSION_NUMBER&0x0f) {
+ sub[0]=(OPENSSL_VERSION_NUMBER&0x0f) + 'a' -1;
+ }
+ else
+ sub[0]='\0';
+
+ return snprintf(buffer, size, "SSL/%x.%x.%x%s",
+ (OPENSSL_VERSION_NUMBER>>12)&0xff,
+ (OPENSSL_VERSION_NUMBER>>8)&0xf,
+ (OPENSSL_VERSION_NUMBER>>4)&0xf, sub);
+ }
+#endif /* (OPENSSL_VERSION_NUMBER >= 0x900000) */
+#endif /* OPENSSL_VERSION_NUMBER is less than 0.9.5 */
+
+#endif /* OPENSSL_IS_BORINGSSL */
+#endif /* YASSL_VERSION */
+}
+
+/* can be called with data == NULL */
+int Curl_ossl_random(struct SessionHandle *data, unsigned char *entropy,
+ size_t length)
+{
+ if(data) {
+ Curl_ossl_seed(data); /* Initiate the seed if not already done */
+ }
+ RAND_bytes(entropy, curlx_uztosi(length));
+ return 0; /* 0 as in no problem */
+}
+
+void Curl_ossl_md5sum(unsigned char *tmp, /* input */
+ size_t tmplen,
+ unsigned char *md5sum /* output */,
+ size_t unused)
+{
+ MD5_CTX MD5pw;
+ (void)unused;
+ MD5_Init(&MD5pw);
+ MD5_Update(&MD5pw, tmp, tmplen);
+ MD5_Final(md5sum, &MD5pw);
+}
+
+#ifndef OPENSSL_NO_SHA256
+void Curl_ossl_sha256sum(const unsigned char *tmp, /* input */
+ size_t tmplen,
+ unsigned char *sha256sum /* output */,
+ size_t unused)
+{
+ SHA256_CTX SHA256pw;
+ (void)unused;
+ SHA256_Init(&SHA256pw);
+ SHA256_Update(&SHA256pw, tmp, tmplen);
+ SHA256_Final(sha256sum, &SHA256pw);
+}
+#endif
+
+bool Curl_ossl_cert_status_request(void)
+{
+#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
+ !defined(OPENSSL_IS_BORINGSSL)
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+#endif /* USE_OPENSSL */
diff --git a/Utilities/cmcurl/lib/vtls/openssl.h b/Utilities/cmcurl/lib/vtls/openssl.h
new file mode 100644
index 000000000..a1f347a05
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/openssl.h
@@ -0,0 +1,120 @@
+#ifndef HEADER_CURL_SSLUSE_H
+#define HEADER_CURL_SSLUSE_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_OPENSSL
+/*
+ * This header should only be needed to get included by vtls.c and openssl.c
+ */
+
+#include "urldata.h"
+
+CURLcode Curl_ossl_connect(struct connectdata *conn, int sockindex);
+CURLcode Curl_ossl_connect_nonblocking(struct connectdata *conn,
+ int sockindex,
+ bool *done);
+
+/* close a SSL connection */
+void Curl_ossl_close(struct connectdata *conn, int sockindex);
+
+/* tell OpenSSL to close down all open information regarding connections (and
+ thus session ID caching etc) */
+void Curl_ossl_close_all(struct SessionHandle *data);
+
+/* Sets an OpenSSL engine */
+CURLcode Curl_ossl_set_engine(struct SessionHandle *data, const char *engine);
+
+/* function provided for the generic SSL-layer, called when a session id
+ should be freed */
+void Curl_ossl_session_free(void *ptr);
+
+/* Sets engine as default for all SSL operations */
+CURLcode Curl_ossl_set_engine_default(struct SessionHandle *data);
+
+/* Build list of OpenSSL engines */
+struct curl_slist *Curl_ossl_engines_list(struct SessionHandle *data);
+
+int Curl_ossl_init(void);
+void Curl_ossl_cleanup(void);
+
+size_t Curl_ossl_version(char *buffer, size_t size);
+int Curl_ossl_check_cxn(struct connectdata *cxn);
+int Curl_ossl_shutdown(struct connectdata *conn, int sockindex);
+bool Curl_ossl_data_pending(const struct connectdata *conn,
+ int connindex);
+
+/* return 0 if a find random is filled in */
+int Curl_ossl_random(struct SessionHandle *data, unsigned char *entropy,
+ size_t length);
+void Curl_ossl_md5sum(unsigned char *tmp, /* input */
+ size_t tmplen,
+ unsigned char *md5sum /* output */,
+ size_t unused);
+void Curl_ossl_sha256sum(const unsigned char *tmp, /* input */
+ size_t tmplen,
+ unsigned char *sha256sum /* output */,
+ size_t unused);
+
+bool Curl_ossl_cert_status_request(void);
+
+/* Set the API backend definition to OpenSSL */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_OPENSSL
+
+/* this backend supports the CAPATH option */
+#define have_curlssl_ca_path 1
+
+/* this backend supports CURLOPT_CERTINFO */
+#define have_curlssl_certinfo 1
+
+/* this backend suppots CURLOPT_SSL_CTX_* */
+#define have_curlssl_ssl_ctx 1
+
+/* API setup for OpenSSL */
+#define curlssl_init Curl_ossl_init
+#define curlssl_cleanup Curl_ossl_cleanup
+#define curlssl_connect Curl_ossl_connect
+#define curlssl_connect_nonblocking Curl_ossl_connect_nonblocking
+#define curlssl_session_free(x) Curl_ossl_session_free(x)
+#define curlssl_close_all Curl_ossl_close_all
+#define curlssl_close Curl_ossl_close
+#define curlssl_shutdown(x,y) Curl_ossl_shutdown(x,y)
+#define curlssl_set_engine(x,y) Curl_ossl_set_engine(x,y)
+#define curlssl_set_engine_default(x) Curl_ossl_set_engine_default(x)
+#define curlssl_engines_list(x) Curl_ossl_engines_list(x)
+#define curlssl_version Curl_ossl_version
+#define curlssl_check_cxn Curl_ossl_check_cxn
+#define curlssl_data_pending(x,y) Curl_ossl_data_pending(x,y)
+#define curlssl_random(x,y,z) Curl_ossl_random(x,y,z)
+#define curlssl_md5sum(a,b,c,d) Curl_ossl_md5sum(a,b,c,d)
+#ifndef OPENSSL_NO_SHA256
+#define curlssl_sha256sum(a,b,c,d) Curl_ossl_sha256sum(a,b,c,d)
+#endif
+#define curlssl_cert_status_request() Curl_ossl_cert_status_request()
+
+#define DEFAULT_CIPHER_SELECTION \
+ "ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH"
+
+#endif /* USE_OPENSSL */
+#endif /* HEADER_CURL_SSLUSE_H */
diff --git a/Utilities/cmcurl/lib/vtls/polarssl.c b/Utilities/cmcurl/lib/vtls/polarssl.c
new file mode 100644
index 000000000..066c055e6
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/polarssl.c
@@ -0,0 +1,753 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all PolarSSL-specific code for the TLS/SSL layer. No code
+ * but vtls.c should ever call or use these functions.
+ *
+ */
+
+#include "curl_setup.h"
+
+#ifdef USE_POLARSSL
+
+#include <polarssl/net.h>
+#include <polarssl/ssl.h>
+#include <polarssl/certs.h>
+#include <polarssl/x509.h>
+#include <polarssl/version.h>
+
+#if POLARSSL_VERSION_NUMBER < 0x01030000
+#error too old PolarSSL
+#endif
+
+#include <polarssl/error.h>
+#include <polarssl/entropy.h>
+#include <polarssl/ctr_drbg.h>
+
+#include "urldata.h"
+#include "sendf.h"
+#include "inet_pton.h"
+#include "polarssl.h"
+#include "vtls.h"
+#include "parsedate.h"
+#include "connect.h" /* for the connect timeout */
+#include "select.h"
+#include "rawstr.h"
+#include "polarssl_threadlock.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* apply threading? */
+#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
+#define THREADING_SUPPORT
+#endif
+
+#if defined(THREADING_SUPPORT)
+static entropy_context entropy;
+
+static int entropy_init_initialized = 0;
+
+/* start of entropy_init_mutex() */
+static void entropy_init_mutex(entropy_context *ctx)
+{
+ /* lock 0 = entropy_init_mutex() */
+ polarsslthreadlock_lock_function(0);
+ if(entropy_init_initialized == 0) {
+ entropy_init(ctx);
+ entropy_init_initialized = 1;
+ }
+ polarsslthreadlock_unlock_function(0);
+}
+/* end of entropy_init_mutex() */
+
+/* start of entropy_func_mutex() */
+static int entropy_func_mutex(void *data, unsigned char *output, size_t len)
+{
+ int ret;
+ /* lock 1 = entropy_func_mutex() */
+ polarsslthreadlock_lock_function(1);
+ ret = entropy_func(data, output, len);
+ polarsslthreadlock_unlock_function(1);
+
+ return ret;
+}
+/* end of entropy_func_mutex() */
+
+#endif /* THREADING_SUPPORT */
+
+/* Define this to enable lots of debugging for PolarSSL */
+#undef POLARSSL_DEBUG
+
+#ifdef POLARSSL_DEBUG
+static void polarssl_debug(void *context, int level, const char *line)
+{
+ struct SessionHandle *data = NULL;
+
+ if(!context)
+ return;
+
+ data = (struct SessionHandle *)context;
+
+ infof(data, "%s", line);
+ (void) level;
+}
+#else
+#endif
+
+/* ALPN for http2? */
+#ifdef POLARSSL_SSL_ALPN
+# define HAS_ALPN
+#endif
+
+static Curl_recv polarssl_recv;
+static Curl_send polarssl_send;
+
+
+static CURLcode
+polarssl_connect_step1(struct connectdata *conn,
+ int sockindex)
+{
+ struct SessionHandle *data = conn->data;
+ struct ssl_connect_data* connssl = &conn->ssl[sockindex];
+
+ bool sni = TRUE; /* default is SNI enabled */
+ int ret = -1;
+#ifdef ENABLE_IPV6
+ struct in6_addr addr;
+#else
+ struct in_addr addr;
+#endif
+ void *old_session = NULL;
+ size_t old_session_size = 0;
+ char errorbuf[128];
+ errorbuf[0]=0;
+
+ /* PolarSSL only supports SSLv3 and TLSv1 */
+ if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
+ failf(data, "PolarSSL does not support SSLv2");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ else if(data->set.ssl.version == CURL_SSLVERSION_SSLv3)
+ sni = FALSE; /* SSLv3 has no SNI */
+
+#ifdef THREADING_SUPPORT
+ entropy_init_mutex(&entropy);
+
+ if((ret = ctr_drbg_init(&connssl->ctr_drbg, entropy_func_mutex, &entropy,
+ connssl->ssn.id, connssl->ssn.length)) != 0) {
+#ifdef POLARSSL_ERROR_C
+ error_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* POLARSSL_ERROR_C */
+ failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
+ -ret, errorbuf);
+ }
+#else
+ entropy_init(&connssl->entropy);
+
+ if((ret = ctr_drbg_init(&connssl->ctr_drbg, entropy_func, &connssl->entropy,
+ connssl->ssn.id, connssl->ssn.length)) != 0) {
+#ifdef POLARSSL_ERROR_C
+ error_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* POLARSSL_ERROR_C */
+ failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
+ -ret, errorbuf);
+ }
+#endif /* THREADING_SUPPORT */
+
+ /* Load the trusted CA */
+ memset(&connssl->cacert, 0, sizeof(x509_crt));
+
+ if(data->set.str[STRING_SSL_CAFILE]) {
+ ret = x509_crt_parse_file(&connssl->cacert,
+ data->set.str[STRING_SSL_CAFILE]);
+
+ if(ret<0) {
+#ifdef POLARSSL_ERROR_C
+ error_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* POLARSSL_ERROR_C */
+ failf(data, "Error reading ca cert file %s - PolarSSL: (-0x%04X) %s",
+ data->set.str[STRING_SSL_CAFILE], -ret, errorbuf);
+
+ if(data->set.ssl.verifypeer)
+ return CURLE_SSL_CACERT_BADFILE;
+ }
+ }
+
+ if(data->set.str[STRING_SSL_CAPATH]) {
+ ret = x509_crt_parse_path(&connssl->cacert,
+ data->set.str[STRING_SSL_CAPATH]);
+
+ if(ret<0) {
+#ifdef POLARSSL_ERROR_C
+ error_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* POLARSSL_ERROR_C */
+ failf(data, "Error reading ca cert path %s - PolarSSL: (-0x%04X) %s",
+ data->set.str[STRING_SSL_CAPATH], -ret, errorbuf);
+
+ if(data->set.ssl.verifypeer)
+ return CURLE_SSL_CACERT_BADFILE;
+ }
+ }
+
+ /* Load the client certificate */
+ memset(&connssl->clicert, 0, sizeof(x509_crt));
+
+ if(data->set.str[STRING_CERT]) {
+ ret = x509_crt_parse_file(&connssl->clicert,
+ data->set.str[STRING_CERT]);
+
+ if(ret) {
+#ifdef POLARSSL_ERROR_C
+ error_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* POLARSSL_ERROR_C */
+ failf(data, "Error reading client cert file %s - PolarSSL: (-0x%04X) %s",
+ data->set.str[STRING_CERT], -ret, errorbuf);
+
+ return CURLE_SSL_CERTPROBLEM;
+ }
+ }
+
+ /* Load the client private key */
+ if(data->set.str[STRING_KEY]) {
+ pk_context pk;
+ pk_init(&pk);
+ ret = pk_parse_keyfile(&pk, data->set.str[STRING_KEY],
+ data->set.str[STRING_KEY_PASSWD]);
+ if(ret == 0 && !pk_can_do(&pk, POLARSSL_PK_RSA))
+ ret = POLARSSL_ERR_PK_TYPE_MISMATCH;
+ if(ret == 0)
+ rsa_copy(&connssl->rsa, pk_rsa(pk));
+ else
+ rsa_free(&connssl->rsa);
+ pk_free(&pk);
+
+ if(ret) {
+#ifdef POLARSSL_ERROR_C
+ error_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* POLARSSL_ERROR_C */
+ failf(data, "Error reading private key %s - PolarSSL: (-0x%04X) %s",
+ data->set.str[STRING_KEY], -ret, errorbuf);
+
+ return CURLE_SSL_CERTPROBLEM;
+ }
+ }
+
+ /* Load the CRL */
+ memset(&connssl->crl, 0, sizeof(x509_crl));
+
+ if(data->set.str[STRING_SSL_CRLFILE]) {
+ ret = x509_crl_parse_file(&connssl->crl,
+ data->set.str[STRING_SSL_CRLFILE]);
+
+ if(ret) {
+#ifdef POLARSSL_ERROR_C
+ error_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* POLARSSL_ERROR_C */
+ failf(data, "Error reading CRL file %s - PolarSSL: (-0x%04X) %s",
+ data->set.str[STRING_SSL_CRLFILE], -ret, errorbuf);
+
+ return CURLE_SSL_CRL_BADFILE;
+ }
+ }
+
+ infof(data, "PolarSSL: Connecting to %s:%d\n",
+ conn->host.name, conn->remote_port);
+
+ if(ssl_init(&connssl->ssl)) {
+ failf(data, "PolarSSL: ssl_init failed");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
+ switch(data->set.ssl.version) {
+ default:
+ case CURL_SSLVERSION_DEFAULT:
+ case CURL_SSLVERSION_TLSv1:
+ ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
+ SSL_MINOR_VERSION_1);
+ break;
+ case CURL_SSLVERSION_SSLv3:
+ ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
+ SSL_MINOR_VERSION_0);
+ ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
+ SSL_MINOR_VERSION_0);
+ infof(data, "PolarSSL: Forced min. SSL Version to be SSLv3\n");
+ break;
+ case CURL_SSLVERSION_TLSv1_0:
+ ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
+ SSL_MINOR_VERSION_1);
+ ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
+ SSL_MINOR_VERSION_1);
+ infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.0\n");
+ break;
+ case CURL_SSLVERSION_TLSv1_1:
+ ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
+ SSL_MINOR_VERSION_2);
+ ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
+ SSL_MINOR_VERSION_2);
+ infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.1\n");
+ break;
+ case CURL_SSLVERSION_TLSv1_2:
+ ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
+ SSL_MINOR_VERSION_3);
+ ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
+ SSL_MINOR_VERSION_3);
+ infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.2\n");
+ break;
+ }
+
+ ssl_set_endpoint(&connssl->ssl, SSL_IS_CLIENT);
+ ssl_set_authmode(&connssl->ssl, SSL_VERIFY_OPTIONAL);
+
+ ssl_set_rng(&connssl->ssl, ctr_drbg_random,
+ &connssl->ctr_drbg);
+ ssl_set_bio(&connssl->ssl,
+ net_recv, &conn->sock[sockindex],
+ net_send, &conn->sock[sockindex]);
+
+ ssl_set_ciphersuites(&connssl->ssl, ssl_list_ciphersuites());
+ if(!Curl_ssl_getsessionid(conn, &old_session, &old_session_size)) {
+ memcpy(&connssl->ssn, old_session, old_session_size);
+ infof(data, "PolarSSL re-using session\n");
+ }
+
+ ssl_set_session(&connssl->ssl,
+ &connssl->ssn);
+
+ ssl_set_ca_chain(&connssl->ssl,
+ &connssl->cacert,
+ &connssl->crl,
+ conn->host.name);
+
+ ssl_set_own_cert_rsa(&connssl->ssl,
+ &connssl->clicert, &connssl->rsa);
+
+ if(!Curl_inet_pton(AF_INET, conn->host.name, &addr) &&
+#ifdef ENABLE_IPV6
+ !Curl_inet_pton(AF_INET6, conn->host.name, &addr) &&
+#endif
+ sni && ssl_set_hostname(&connssl->ssl, conn->host.name)) {
+ infof(data, "WARNING: failed to configure "
+ "server name indication (SNI) TLS extension\n");
+ }
+
+#ifdef HAS_ALPN
+ if(data->set.ssl_enable_alpn) {
+ static const char* protocols[3];
+ int cur = 0;
+
+#ifdef USE_NGHTTP2
+ if(data->set.httpversion == CURL_HTTP_VERSION_2_0) {
+ protocols[cur++] = NGHTTP2_PROTO_VERSION_ID;
+ infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
+ }
+#endif
+
+ protocols[cur++] = ALPN_HTTP_1_1;
+ infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
+
+ protocols[cur] = NULL;
+
+ ssl_set_alpn_protocols(&connssl->ssl, protocols);
+ }
+#endif
+
+#ifdef POLARSSL_DEBUG
+ ssl_set_dbg(&connssl->ssl, polarssl_debug, data);
+#endif
+
+ connssl->connecting_state = ssl_connect_2;
+
+ return CURLE_OK;
+}
+
+static CURLcode
+polarssl_connect_step2(struct connectdata *conn,
+ int sockindex)
+{
+ int ret;
+ struct SessionHandle *data = conn->data;
+ struct ssl_connect_data* connssl = &conn->ssl[sockindex];
+ char buffer[1024];
+
+ char errorbuf[128];
+ errorbuf[0] = 0;
+
+ conn->recv[sockindex] = polarssl_recv;
+ conn->send[sockindex] = polarssl_send;
+
+ ret = ssl_handshake(&connssl->ssl);
+
+ switch(ret) {
+ case 0:
+ break;
+
+ case POLARSSL_ERR_NET_WANT_READ:
+ connssl->connecting_state = ssl_connect_2_reading;
+ return CURLE_OK;
+
+ case POLARSSL_ERR_NET_WANT_WRITE:
+ connssl->connecting_state = ssl_connect_2_writing;
+ return CURLE_OK;
+
+ default:
+#ifdef POLARSSL_ERROR_C
+ error_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* POLARSSL_ERROR_C */
+ failf(data, "ssl_handshake returned - PolarSSL: (-0x%04X) %s",
+ -ret, errorbuf);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
+ infof(data, "PolarSSL: Handshake complete, cipher is %s\n",
+ ssl_get_ciphersuite(&conn->ssl[sockindex].ssl) );
+
+ ret = ssl_get_verify_result(&conn->ssl[sockindex].ssl);
+
+ if(ret && data->set.ssl.verifypeer) {
+ if(ret & BADCERT_EXPIRED)
+ failf(data, "Cert verify failed: BADCERT_EXPIRED");
+
+ if(ret & BADCERT_REVOKED) {
+ failf(data, "Cert verify failed: BADCERT_REVOKED");
+ return CURLE_SSL_CACERT;
+ }
+
+ if(ret & BADCERT_CN_MISMATCH)
+ failf(data, "Cert verify failed: BADCERT_CN_MISMATCH");
+
+ if(ret & BADCERT_NOT_TRUSTED)
+ failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED");
+
+ return CURLE_PEER_FAILED_VERIFICATION;
+ }
+
+ if(ssl_get_peer_cert(&(connssl->ssl))) {
+ /* If the session was resumed, there will be no peer certs */
+ memset(buffer, 0, sizeof(buffer));
+
+ if(x509_crt_info(buffer, sizeof(buffer), (char *)"* ",
+ ssl_get_peer_cert(&(connssl->ssl))) != -1)
+ infof(data, "Dumping cert info:\n%s\n", buffer);
+ }
+
+#ifdef HAS_ALPN
+ if(data->set.ssl_enable_alpn) {
+ const char *next_protocol = ssl_get_alpn_protocol(&connssl->ssl);
+
+ if(next_protocol != NULL) {
+ infof(data, "ALPN, server accepted to use %s\n", next_protocol);
+
+#ifdef USE_NGHTTP2
+ if(!strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID,
+ NGHTTP2_PROTO_VERSION_ID_LEN)) {
+ conn->negnpn = CURL_HTTP_VERSION_2_0;
+ }
+ else
+#endif
+ if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) {
+ conn->negnpn = CURL_HTTP_VERSION_1_1;
+ }
+ }
+ else
+ infof(data, "ALPN, server did not agree to a protocol\n");
+ }
+#endif
+
+ connssl->connecting_state = ssl_connect_3;
+ infof(data, "SSL connected\n");
+
+ return CURLE_OK;
+}
+
+static CURLcode
+polarssl_connect_step3(struct connectdata *conn,
+ int sockindex)
+{
+ CURLcode result = CURLE_OK;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct SessionHandle *data = conn->data;
+ void *old_ssl_sessionid = NULL;
+ ssl_session *our_ssl_sessionid = &conn->ssl[sockindex].ssn;
+ bool incache;
+
+ DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
+
+ /* Save the current session data for possible re-use */
+ incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL));
+ if(incache) {
+ if(old_ssl_sessionid != our_ssl_sessionid) {
+ infof(data, "old SSL session ID is stale, removing\n");
+ Curl_ssl_delsessionid(conn, old_ssl_sessionid);
+ incache = FALSE;
+ }
+ }
+
+ if(!incache) {
+ void *new_session = malloc(sizeof(ssl_session));
+
+ if(new_session) {
+ memcpy(new_session, our_ssl_sessionid, sizeof(ssl_session));
+
+ result = Curl_ssl_addsessionid(conn, new_session, sizeof(ssl_session));
+ }
+ else
+ result = CURLE_OUT_OF_MEMORY;
+
+ if(result) {
+ failf(data, "failed to store ssl session");
+ return result;
+ }
+ }
+
+ connssl->connecting_state = ssl_connect_done;
+
+ return CURLE_OK;
+}
+
+static ssize_t polarssl_send(struct connectdata *conn,
+ int sockindex,
+ const void *mem,
+ size_t len,
+ CURLcode *curlcode)
+{
+ int ret = -1;
+
+ ret = ssl_write(&conn->ssl[sockindex].ssl,
+ (unsigned char *)mem, len);
+
+ if(ret < 0) {
+ *curlcode = (ret == POLARSSL_ERR_NET_WANT_WRITE) ?
+ CURLE_AGAIN : CURLE_SEND_ERROR;
+ ret = -1;
+ }
+
+ return ret;
+}
+
+void Curl_polarssl_close(struct connectdata *conn, int sockindex)
+{
+ rsa_free(&conn->ssl[sockindex].rsa);
+ x509_crt_free(&conn->ssl[sockindex].clicert);
+ x509_crt_free(&conn->ssl[sockindex].cacert);
+ x509_crl_free(&conn->ssl[sockindex].crl);
+ ssl_free(&conn->ssl[sockindex].ssl);
+}
+
+static ssize_t polarssl_recv(struct connectdata *conn,
+ int num,
+ char *buf,
+ size_t buffersize,
+ CURLcode *curlcode)
+{
+ int ret = -1;
+ ssize_t len = -1;
+
+ memset(buf, 0, buffersize);
+ ret = ssl_read(&conn->ssl[num].ssl, (unsigned char *)buf, buffersize);
+
+ if(ret <= 0) {
+ if(ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY)
+ return 0;
+
+ *curlcode = (ret == POLARSSL_ERR_NET_WANT_READ) ?
+ CURLE_AGAIN : CURLE_RECV_ERROR;
+ return -1;
+ }
+
+ len = ret;
+
+ return len;
+}
+
+void Curl_polarssl_session_free(void *ptr)
+{
+ free(ptr);
+}
+
+/* 1.3.10 was the first rebranded version. All new releases (in 1.3 branch and
+ higher) will be mbed TLS branded.. */
+
+size_t Curl_polarssl_version(char *buffer, size_t size)
+{
+ unsigned int version = version_get_number();
+ return snprintf(buffer, size, "%s/%d.%d.%d",
+ version >= 0x01030A00?"mbedTLS":"PolarSSL",
+ version>>24, (version>>16)&0xff, (version>>8)&0xff);
+}
+
+static CURLcode
+polarssl_connect_common(struct connectdata *conn,
+ int sockindex,
+ bool nonblocking,
+ bool *done)
+{
+ CURLcode result;
+ struct SessionHandle *data = conn->data;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ curl_socket_t sockfd = conn->sock[sockindex];
+ long timeout_ms;
+ int what;
+
+ /* check if the connection has already been established */
+ if(ssl_connection_complete == connssl->state) {
+ *done = TRUE;
+ return CURLE_OK;
+ }
+
+ if(ssl_connect_1 == connssl->connecting_state) {
+ /* Find out how much more time we're allowed */
+ timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+ if(timeout_ms < 0) {
+ /* no need to continue if time already is up */
+ failf(data, "SSL connection timeout");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+
+ result = polarssl_connect_step1(conn, sockindex);
+ if(result)
+ return result;
+ }
+
+ while(ssl_connect_2 == connssl->connecting_state ||
+ ssl_connect_2_reading == connssl->connecting_state ||
+ ssl_connect_2_writing == connssl->connecting_state) {
+
+ /* check allowed time left */
+ timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+ if(timeout_ms < 0) {
+ /* no need to continue if time already is up */
+ failf(data, "SSL connection timeout");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+
+ /* if ssl is expecting something, check if it's available. */
+ if(connssl->connecting_state == ssl_connect_2_reading ||
+ connssl->connecting_state == ssl_connect_2_writing) {
+
+ curl_socket_t writefd = ssl_connect_2_writing==
+ connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+ curl_socket_t readfd = ssl_connect_2_reading==
+ connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+
+ what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
+ if(what < 0) {
+ /* fatal error */
+ failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ else if(0 == what) {
+ if(nonblocking) {
+ *done = FALSE;
+ return CURLE_OK;
+ }
+ else {
+ /* timeout */
+ failf(data, "SSL connection timeout");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+ }
+ /* socket is readable or writable */
+ }
+
+ /* Run transaction, and return to the caller if it failed or if
+ * this connection is part of a multi handle and this loop would
+ * execute again. This permits the owner of a multi handle to
+ * abort a connection attempt before step2 has completed while
+ * ensuring that a client using select() or epoll() will always
+ * have a valid fdset to wait on.
+ */
+ result = polarssl_connect_step2(conn, sockindex);
+ if(result || (nonblocking &&
+ (ssl_connect_2 == connssl->connecting_state ||
+ ssl_connect_2_reading == connssl->connecting_state ||
+ ssl_connect_2_writing == connssl->connecting_state)))
+ return result;
+
+ } /* repeat step2 until all transactions are done. */
+
+ if(ssl_connect_3 == connssl->connecting_state) {
+ result = polarssl_connect_step3(conn, sockindex);
+ if(result)
+ return result;
+ }
+
+ if(ssl_connect_done == connssl->connecting_state) {
+ connssl->state = ssl_connection_complete;
+ conn->recv[sockindex] = polarssl_recv;
+ conn->send[sockindex] = polarssl_send;
+ *done = TRUE;
+ }
+ else
+ *done = FALSE;
+
+ /* Reset our connect state machine */
+ connssl->connecting_state = ssl_connect_1;
+
+ return CURLE_OK;
+}
+
+CURLcode
+Curl_polarssl_connect_nonblocking(struct connectdata *conn,
+ int sockindex,
+ bool *done)
+{
+ return polarssl_connect_common(conn, sockindex, TRUE, done);
+}
+
+
+CURLcode
+Curl_polarssl_connect(struct connectdata *conn,
+ int sockindex)
+{
+ CURLcode result;
+ bool done = FALSE;
+
+ result = polarssl_connect_common(conn, sockindex, FALSE, &done);
+ if(result)
+ return result;
+
+ DEBUGASSERT(done);
+
+ return CURLE_OK;
+}
+
+/*
+ * return 0 error initializing SSL
+ * return 1 SSL initialized successfully
+ */
+int polarssl_init(void)
+{
+ return polarsslthreadlock_thread_setup();
+}
+
+void polarssl_cleanup(void)
+{
+ (void)polarsslthreadlock_thread_cleanup();
+}
+
+#endif /* USE_POLARSSL */
diff --git a/Utilities/cmcurl/lib/vtls/polarssl.h b/Utilities/cmcurl/lib/vtls/polarssl.h
new file mode 100644
index 000000000..f980dbb2e
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/polarssl.h
@@ -0,0 +1,75 @@
+#ifndef HEADER_CURL_POLARSSL_H
+#define HEADER_CURL_POLARSSL_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com>
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef USE_POLARSSL
+
+/* Called on first use PolarSSL, setup threading if supported */
+int polarssl_init(void);
+void polarssl_cleanup(void);
+
+
+CURLcode Curl_polarssl_connect(struct connectdata *conn, int sockindex);
+
+CURLcode Curl_polarssl_connect_nonblocking(struct connectdata *conn,
+ int sockindex,
+ bool *done);
+
+ /* close a SSL connection */
+void Curl_polarssl_close(struct connectdata *conn, int sockindex);
+
+void Curl_polarssl_session_free(void *ptr);
+size_t Curl_polarssl_version(char *buffer, size_t size);
+int Curl_polarssl_shutdown(struct connectdata *conn, int sockindex);
+
+/* Set the API backend definition to PolarSSL */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_POLARSSL
+
+/* this backend supports the CAPATH option */
+#define have_curlssl_ca_path 1
+
+/* API setup for PolarSSL */
+#define curlssl_init() polarssl_init()
+#define curlssl_cleanup() polarssl_cleanup()
+#define curlssl_connect Curl_polarssl_connect
+#define curlssl_connect_nonblocking Curl_polarssl_connect_nonblocking
+#define curlssl_session_free(x) Curl_polarssl_session_free(x)
+#define curlssl_close_all(x) ((void)x)
+#define curlssl_close Curl_polarssl_close
+#define curlssl_shutdown(x,y) 0
+#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN)
+#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN)
+#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL)
+#define curlssl_version Curl_polarssl_version
+#define curlssl_check_cxn(x) ((void)x, -1)
+#define curlssl_data_pending(x,y) ((void)x, (void)y, 0)
+
+/* This might cause libcurl to use a weeker random!
+ TODO: implement proper use of Polarssl's CTR-DRBG or HMAC-DRBG and use that
+*/
+#define curlssl_random(x,y,z) ((void)x, (void)y, (void)z, CURLE_NOT_BUILT_IN)
+
+#endif /* USE_POLARSSL */
+#endif /* HEADER_CURL_POLARSSL_H */
diff --git a/Utilities/cmcurl/lib/vtls/polarssl_threadlock.c b/Utilities/cmcurl/lib/vtls/polarssl_threadlock.c
new file mode 100644
index 000000000..62abf43b2
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/polarssl_threadlock.c
@@ -0,0 +1,153 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2010, 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
+ * Copyright (C) 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#if defined(USE_POLARSSL) && \
+ (defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32))
+
+#if defined(USE_THREADS_POSIX)
+# ifdef HAVE_PTHREAD_H
+# include <pthread.h>
+# endif
+#elif defined(USE_THREADS_WIN32)
+# ifdef HAVE_PROCESS_H
+# include <process.h>
+# endif
+#endif
+
+#include "polarssl_threadlock.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* number of thread locks */
+#define NUMT 2
+
+/* This array will store all of the mutexes available to PolarSSL. */
+static POLARSSL_MUTEX_T *mutex_buf = NULL;
+
+int polarsslthreadlock_thread_setup(void)
+{
+ int i;
+ int ret;
+
+ mutex_buf = malloc(NUMT * sizeof(POLARSSL_MUTEX_T));
+ if(!mutex_buf)
+ return 0; /* error, no number of threads defined */
+
+#ifdef HAVE_PTHREAD_H
+ for(i = 0; i < NUMT; i++) {
+ ret = pthread_mutex_init(&mutex_buf[i], NULL);
+ if(ret)
+ return 0; /* pthread_mutex_init failed */
+ }
+#elif defined(HAVE_PROCESS_H)
+ for(i = 0; i < NUMT; i++) {
+ mutex_buf[i] = CreateMutex(0, FALSE, 0);
+ if(mutex_buf[i] == 0)
+ return 0; /* CreateMutex failed */
+ }
+#endif /* HAVE_PTHREAD_H */
+
+ return 1; /* OK */
+}
+
+int polarsslthreadlock_thread_cleanup(void)
+{
+ int i;
+ int ret;
+
+ if(!mutex_buf)
+ return 0; /* error, no threads locks defined */
+
+#ifdef HAVE_PTHREAD_H
+ for(i = 0; i < NUMT; i++) {
+ ret = pthread_mutex_destroy(&mutex_buf[i]);
+ if(ret)
+ return 0; /* pthread_mutex_destroy failed */
+ }
+#elif defined(HAVE_PROCESS_H)
+ for(i = 0; i < NUMT; i++) {
+ ret = CloseHandle(mutex_buf[i]);
+ if(!ret)
+ return 0; /* CloseHandle failed */
+ }
+#endif /* HAVE_PTHREAD_H */
+ free(mutex_buf);
+ mutex_buf = NULL;
+
+ return 1; /* OK */
+}
+
+int polarsslthreadlock_lock_function(int n)
+{
+ int ret;
+#ifdef HAVE_PTHREAD_H
+ if(n < NUMT) {
+ ret = pthread_mutex_lock(&mutex_buf[n]);
+ if(ret) {
+ DEBUGF(fprintf(stderr,
+ "Error: polarsslthreadlock_lock_function failed\n"));
+ return 0; /* pthread_mutex_lock failed */
+ }
+ }
+#elif defined(HAVE_PROCESS_H)
+ if(n < NUMT) {
+ ret = (WaitForSingleObject(mutex_buf[n], INFINITE)==WAIT_FAILED?1:0);
+ if(ret) {
+ DEBUGF(fprintf(stderr,
+ "Error: polarsslthreadlock_lock_function failed\n"));
+ return 0; /* pthread_mutex_lock failed */
+ }
+ }
+#endif /* HAVE_PTHREAD_H */
+ return 1; /* OK */
+}
+
+int polarsslthreadlock_unlock_function(int n)
+{
+ int ret;
+#ifdef HAVE_PTHREAD_H
+ if(n < NUMT) {
+ ret = pthread_mutex_unlock(&mutex_buf[n]);
+ if(ret) {
+ DEBUGF(fprintf(stderr,
+ "Error: polarsslthreadlock_unlock_function failed\n"));
+ return 0; /* pthread_mutex_unlock failed */
+ }
+ }
+#elif defined(HAVE_PROCESS_H)
+ if(n < NUMT) {
+ ret = ReleaseMutex(mutex_buf[n]);
+ if(!ret) {
+ DEBUGF(fprintf(stderr,
+ "Error: polarsslthreadlock_unlock_function failed\n"));
+ return 0; /* pthread_mutex_lock failed */
+ }
+ }
+#endif /* HAVE_PTHREAD_H */
+ return 1; /* OK */
+}
+
+#endif /* USE_POLARSSL */
diff --git a/Utilities/cmcurl/lib/vtls/polarssl_threadlock.h b/Utilities/cmcurl/lib/vtls/polarssl_threadlock.h
new file mode 100644
index 000000000..b67b3f9ab
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/polarssl_threadlock.h
@@ -0,0 +1,53 @@
+#ifndef HEADER_CURL_POLARSSL_THREADLOCK_H
+#define HEADER_CURL_POLARSSL_THREADLOCK_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com>
+ * Copyright (C) 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef USE_POLARSSL
+
+#if defined(USE_THREADS_POSIX)
+# define POLARSSL_MUTEX_T pthread_mutex_t
+#elif defined(USE_THREADS_WIN32)
+# define POLARSSL_MUTEX_T HANDLE
+#endif
+
+#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
+
+int polarsslthreadlock_thread_setup(void);
+int polarsslthreadlock_thread_cleanup(void);
+int polarsslthreadlock_lock_function(int n);
+int polarsslthreadlock_unlock_function(int n);
+
+#else
+
+#define polarsslthreadlock_thread_setup() 1
+#define polarsslthreadlock_thread_cleanup() 1
+#define polarsslthreadlock_lock_function(x) 1
+#define polarsslthreadlock_unlock_function(x) 1
+
+#endif /* USE_THREADS_POSIX || USE_THREADS_WIN32 */
+
+#endif /* USE_POLARSSL */
+
+#endif /* HEADER_CURL_POLARSSL_THREADLOCK_H */
diff --git a/Utilities/cmcurl/lib/vtls/schannel.c b/Utilities/cmcurl/lib/vtls/schannel.c
new file mode 100644
index 000000000..2174e21a3
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/schannel.c
@@ -0,0 +1,1501 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2015, Marc Hoersken, <info@marc-hoersken.de>
+ * Copyright (C) 2012, Mark Salisbury, <mark.salisbury@hp.com>
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all SChannel-specific code for the TLS/SSL layer. No code
+ * but vtls.c should ever call or use these functions.
+ *
+ */
+
+/*
+ * Based upon the PolarSSL implementation in polarssl.c and polarssl.h:
+ * Copyright (C) 2010, 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
+ *
+ * Based upon the CyaSSL implementation in cyassl.c and cyassl.h:
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * Thanks for code and inspiration!
+ */
+
+#include "curl_setup.h"
+
+#ifdef USE_SCHANNEL
+
+#ifndef USE_WINDOWS_SSPI
+# error "Can't compile SCHANNEL support without SSPI."
+#endif
+
+#include "curl_sspi.h"
+#include "schannel.h"
+#include "vtls.h"
+#include "sendf.h"
+#include "connect.h" /* for the connect timeout */
+#include "strerror.h"
+#include "select.h" /* for the socket readyness */
+#include "inet_pton.h" /* for IP addr SNI check */
+#include "curl_multibyte.h"
+#include "warnless.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* Uncomment to force verbose output
+ * #define infof(x, y, ...) printf(y, __VA_ARGS__)
+ * #define failf(x, y, ...) printf(y, __VA_ARGS__)
+ */
+
+static Curl_recv schannel_recv;
+static Curl_send schannel_send;
+
+#ifdef _WIN32_WCE
+static CURLcode verify_certificate(struct connectdata *conn, int sockindex);
+#endif
+
+static void InitSecBuffer(SecBuffer *buffer, unsigned long BufType,
+ void *BufDataPtr, unsigned long BufByteSize)
+{
+ buffer->cbBuffer = BufByteSize;
+ buffer->BufferType = BufType;
+ buffer->pvBuffer = BufDataPtr;
+}
+
+static void InitSecBufferDesc(SecBufferDesc *desc, SecBuffer *BufArr,
+ unsigned long NumArrElem)
+{
+ desc->ulVersion = SECBUFFER_VERSION;
+ desc->pBuffers = BufArr;
+ desc->cBuffers = NumArrElem;
+}
+
+static CURLcode
+schannel_connect_step1(struct connectdata *conn, int sockindex)
+{
+ ssize_t written = -1;
+ struct SessionHandle *data = conn->data;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ SecBuffer outbuf;
+ SecBufferDesc outbuf_desc;
+ SCHANNEL_CRED schannel_cred;
+ SECURITY_STATUS sspi_status = SEC_E_OK;
+ struct curl_schannel_cred *old_cred = NULL;
+ struct in_addr addr;
+#ifdef ENABLE_IPV6
+ struct in6_addr addr6;
+#endif
+ TCHAR *host_name;
+ CURLcode result;
+
+ infof(data, "schannel: SSL/TLS connection with %s port %hu (step 1/3)\n",
+ conn->host.name, conn->remote_port);
+
+ /* check for an existing re-usable credential handle */
+ if(!Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL)) {
+ connssl->cred = old_cred;
+ infof(data, "schannel: re-using existing credential handle\n");
+ }
+ else {
+ /* setup Schannel API options */
+ memset(&schannel_cred, 0, sizeof(schannel_cred));
+ schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
+
+ if(data->set.ssl.verifypeer) {
+#ifdef _WIN32_WCE
+ /* certificate validation on CE doesn't seem to work right; we'll
+ do it following a more manual process. */
+ schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION |
+ SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
+ SCH_CRED_IGNORE_REVOCATION_OFFLINE;
+#else
+ schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION;
+ if(data->set.ssl_no_revoke)
+ schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
+ SCH_CRED_IGNORE_REVOCATION_OFFLINE;
+ else
+ schannel_cred.dwFlags |= SCH_CRED_REVOCATION_CHECK_CHAIN;
+#endif
+ if(data->set.ssl_no_revoke)
+ infof(data, "schannel: disabled server certificate revocation "
+ "checks\n");
+ else
+ infof(data, "schannel: checking server certificate revocation\n");
+ }
+ else {
+ schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION |
+ SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
+ SCH_CRED_IGNORE_REVOCATION_OFFLINE;
+ infof(data, "schannel: disabled server certificate revocation checks\n");
+ }
+
+ if(!data->set.ssl.verifyhost) {
+ schannel_cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK;
+ infof(data, "schannel: verifyhost setting prevents Schannel from "
+ "comparing the supplied target name with the subject "
+ "names in server certificates. Also disables SNI.\n");
+ }
+
+ switch(data->set.ssl.version) {
+ default:
+ case CURL_SSLVERSION_DEFAULT:
+ case CURL_SSLVERSION_TLSv1:
+ schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_0_CLIENT |
+ SP_PROT_TLS1_1_CLIENT |
+ SP_PROT_TLS1_2_CLIENT;
+ break;
+ case CURL_SSLVERSION_TLSv1_0:
+ schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_0_CLIENT;
+ break;
+ case CURL_SSLVERSION_TLSv1_1:
+ schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_1_CLIENT;
+ break;
+ case CURL_SSLVERSION_TLSv1_2:
+ schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT;
+ break;
+ case CURL_SSLVERSION_SSLv3:
+ schannel_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT;
+ break;
+ case CURL_SSLVERSION_SSLv2:
+ schannel_cred.grbitEnabledProtocols = SP_PROT_SSL2_CLIENT;
+ break;
+ }
+
+ /* allocate memory for the re-usable credential handle */
+ connssl->cred = (struct curl_schannel_cred *)
+ malloc(sizeof(struct curl_schannel_cred));
+ if(!connssl->cred) {
+ failf(data, "schannel: unable to allocate memory");
+ return CURLE_OUT_OF_MEMORY;
+ }
+ memset(connssl->cred, 0, sizeof(struct curl_schannel_cred));
+
+ /* http://msdn.microsoft.com/en-us/library/windows/desktop/aa374716.aspx */
+ sspi_status =
+ s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *)UNISP_NAME,
+ SECPKG_CRED_OUTBOUND, NULL,
+ &schannel_cred, NULL, NULL,
+ &connssl->cred->cred_handle,
+ &connssl->cred->time_stamp);
+
+ if(sspi_status != SEC_E_OK) {
+ if(sspi_status == SEC_E_WRONG_PRINCIPAL)
+ failf(data, "schannel: SNI or certificate check failed: %s",
+ Curl_sspi_strerror(conn, sspi_status));
+ else
+ failf(data, "schannel: AcquireCredentialsHandle failed: %s",
+ Curl_sspi_strerror(conn, sspi_status));
+ Curl_safefree(connssl->cred);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ }
+
+ /* Warn if SNI is disabled due to use of an IP address */
+ if(Curl_inet_pton(AF_INET, conn->host.name, &addr)
+#ifdef ENABLE_IPV6
+ || Curl_inet_pton(AF_INET6, conn->host.name, &addr6)
+#endif
+ ) {
+ infof(data, "schannel: using IP address, SNI is not supported by OS.\n");
+ }
+
+ /* setup output buffer */
+ InitSecBuffer(&outbuf, SECBUFFER_EMPTY, NULL, 0);
+ InitSecBufferDesc(&outbuf_desc, &outbuf, 1);
+
+ /* setup request flags */
+ connssl->req_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
+ ISC_REQ_CONFIDENTIALITY | ISC_REQ_ALLOCATE_MEMORY |
+ ISC_REQ_STREAM;
+
+ /* allocate memory for the security context handle */
+ connssl->ctxt = (struct curl_schannel_ctxt *)
+ malloc(sizeof(struct curl_schannel_ctxt));
+ if(!connssl->ctxt) {
+ failf(data, "schannel: unable to allocate memory");
+ return CURLE_OUT_OF_MEMORY;
+ }
+ memset(connssl->ctxt, 0, sizeof(struct curl_schannel_ctxt));
+
+ host_name = Curl_convert_UTF8_to_tchar(conn->host.name);
+ if(!host_name)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* http://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx */
+
+ sspi_status = s_pSecFn->InitializeSecurityContext(
+ &connssl->cred->cred_handle, NULL, host_name,
+ connssl->req_flags, 0, 0, NULL, 0, &connssl->ctxt->ctxt_handle,
+ &outbuf_desc, &connssl->ret_flags, &connssl->ctxt->time_stamp);
+
+ Curl_unicodefree(host_name);
+
+ if(sspi_status != SEC_I_CONTINUE_NEEDED) {
+ if(sspi_status == SEC_E_WRONG_PRINCIPAL)
+ failf(data, "schannel: SNI or certificate check failed: %s",
+ Curl_sspi_strerror(conn, sspi_status));
+ else
+ failf(data, "schannel: initial InitializeSecurityContext failed: %s",
+ Curl_sspi_strerror(conn, sspi_status));
+ Curl_safefree(connssl->ctxt);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
+ infof(data, "schannel: sending initial handshake data: "
+ "sending %lu bytes...\n", outbuf.cbBuffer);
+
+ /* send initial handshake data which is now stored in output buffer */
+ result = Curl_write_plain(conn, conn->sock[sockindex], outbuf.pvBuffer,
+ outbuf.cbBuffer, &written);
+ s_pSecFn->FreeContextBuffer(outbuf.pvBuffer);
+ if((result != CURLE_OK) || (outbuf.cbBuffer != (size_t) written)) {
+ failf(data, "schannel: failed to send initial handshake data: "
+ "sent %zd of %lu bytes", written, outbuf.cbBuffer);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
+ infof(data, "schannel: sent initial handshake data: "
+ "sent %zd bytes\n", written);
+
+ connssl->recv_unrecoverable_err = CURLE_OK;
+ connssl->recv_sspi_close_notify = false;
+ connssl->recv_connection_closed = false;
+
+ /* continue to second handshake step */
+ connssl->connecting_state = ssl_connect_2;
+
+ return CURLE_OK;
+}
+
+static CURLcode
+schannel_connect_step2(struct connectdata *conn, int sockindex)
+{
+ int i;
+ ssize_t nread = -1, written = -1;
+ struct SessionHandle *data = conn->data;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ unsigned char *reallocated_buffer;
+ size_t reallocated_length;
+ SecBuffer outbuf[3];
+ SecBufferDesc outbuf_desc;
+ SecBuffer inbuf[2];
+ SecBufferDesc inbuf_desc;
+ SECURITY_STATUS sspi_status = SEC_E_OK;
+ TCHAR *host_name;
+ CURLcode result;
+ bool doread;
+
+ doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE;
+
+ infof(data, "schannel: SSL/TLS connection with %s port %hu (step 2/3)\n",
+ conn->host.name, conn->remote_port);
+
+ if(!connssl->cred || !connssl->ctxt)
+ return CURLE_SSL_CONNECT_ERROR;
+
+ /* buffer to store previously received and decrypted data */
+ if(connssl->decdata_buffer == NULL) {
+ connssl->decdata_offset = 0;
+ connssl->decdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
+ connssl->decdata_buffer = malloc(connssl->decdata_length);
+ if(connssl->decdata_buffer == NULL) {
+ failf(data, "schannel: unable to allocate memory");
+ return CURLE_OUT_OF_MEMORY;
+ }
+ }
+
+ /* buffer to store previously received and encrypted data */
+ if(connssl->encdata_buffer == NULL) {
+ connssl->encdata_offset = 0;
+ connssl->encdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
+ connssl->encdata_buffer = malloc(connssl->encdata_length);
+ if(connssl->encdata_buffer == NULL) {
+ failf(data, "schannel: unable to allocate memory");
+ return CURLE_OUT_OF_MEMORY;
+ }
+ }
+
+ /* if we need a bigger buffer to read a full message, increase buffer now */
+ if(connssl->encdata_length - connssl->encdata_offset <
+ CURL_SCHANNEL_BUFFER_FREE_SIZE) {
+ /* increase internal encrypted data buffer */
+ reallocated_length = connssl->encdata_offset +
+ CURL_SCHANNEL_BUFFER_FREE_SIZE;
+ reallocated_buffer = realloc(connssl->encdata_buffer,
+ reallocated_length);
+
+ if(reallocated_buffer == NULL) {
+ failf(data, "schannel: unable to re-allocate memory");
+ return CURLE_OUT_OF_MEMORY;
+ }
+ else {
+ connssl->encdata_buffer = reallocated_buffer;
+ connssl->encdata_length = reallocated_length;
+ }
+ }
+
+ for(;;) {
+ if(doread) {
+ /* read encrypted handshake data from socket */
+ result = Curl_read_plain(conn->sock[sockindex],
+ (char *) (connssl->encdata_buffer +
+ connssl->encdata_offset),
+ connssl->encdata_length -
+ connssl->encdata_offset,
+ &nread);
+ if(result == CURLE_AGAIN) {
+ if(connssl->connecting_state != ssl_connect_2_writing)
+ connssl->connecting_state = ssl_connect_2_reading;
+ infof(data, "schannel: failed to receive handshake, "
+ "need more data\n");
+ return CURLE_OK;
+ }
+ else if((result != CURLE_OK) || (nread == 0)) {
+ failf(data, "schannel: failed to receive handshake, "
+ "SSL/TLS connection failed");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
+ /* increase encrypted data buffer offset */
+ connssl->encdata_offset += nread;
+ }
+
+ infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
+ connssl->encdata_offset, connssl->encdata_length);
+
+ /* setup input buffers */
+ InitSecBuffer(&inbuf[0], SECBUFFER_TOKEN, malloc(connssl->encdata_offset),
+ curlx_uztoul(connssl->encdata_offset));
+ InitSecBuffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0);
+ InitSecBufferDesc(&inbuf_desc, inbuf, 2);
+
+ /* setup output buffers */
+ InitSecBuffer(&outbuf[0], SECBUFFER_TOKEN, NULL, 0);
+ InitSecBuffer(&outbuf[1], SECBUFFER_ALERT, NULL, 0);
+ InitSecBuffer(&outbuf[2], SECBUFFER_EMPTY, NULL, 0);
+ InitSecBufferDesc(&outbuf_desc, outbuf, 3);
+
+ if(inbuf[0].pvBuffer == NULL) {
+ failf(data, "schannel: unable to allocate memory");
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ /* copy received handshake data into input buffer */
+ memcpy(inbuf[0].pvBuffer, connssl->encdata_buffer,
+ connssl->encdata_offset);
+
+ host_name = Curl_convert_UTF8_to_tchar(conn->host.name);
+ if(!host_name)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* http://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx */
+
+ sspi_status = s_pSecFn->InitializeSecurityContext(
+ &connssl->cred->cred_handle, &connssl->ctxt->ctxt_handle,
+ host_name, connssl->req_flags, 0, 0, &inbuf_desc, 0, NULL,
+ &outbuf_desc, &connssl->ret_flags, &connssl->ctxt->time_stamp);
+
+ Curl_unicodefree(host_name);
+
+ /* free buffer for received handshake data */
+ Curl_safefree(inbuf[0].pvBuffer);
+
+ /* check if the handshake was incomplete */
+ if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
+ connssl->connecting_state = ssl_connect_2_reading;
+ infof(data, "schannel: received incomplete message, need more data\n");
+ return CURLE_OK;
+ }
+
+ /* If the server has requested a client certificate, attempt to continue
+ the handshake without one. This will allow connections to servers which
+ request a client certificate but do not require it. */
+ if(sspi_status == SEC_I_INCOMPLETE_CREDENTIALS &&
+ !(connssl->req_flags & ISC_REQ_USE_SUPPLIED_CREDS)) {
+ connssl->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
+ connssl->connecting_state = ssl_connect_2_writing;
+ infof(data, "schannel: a client certificate has been requested\n");
+ return CURLE_OK;
+ }
+
+ /* check if the handshake needs to be continued */
+ if(sspi_status == SEC_I_CONTINUE_NEEDED || sspi_status == SEC_E_OK) {
+ for(i = 0; i < 3; i++) {
+ /* search for handshake tokens that need to be send */
+ if(outbuf[i].BufferType == SECBUFFER_TOKEN && outbuf[i].cbBuffer > 0) {
+ infof(data, "schannel: sending next handshake data: "
+ "sending %lu bytes...\n", outbuf[i].cbBuffer);
+
+ /* send handshake token to server */
+ result = Curl_write_plain(conn, conn->sock[sockindex],
+ outbuf[i].pvBuffer, outbuf[i].cbBuffer,
+ &written);
+ if((result != CURLE_OK) ||
+ (outbuf[i].cbBuffer != (size_t) written)) {
+ failf(data, "schannel: failed to send next handshake data: "
+ "sent %zd of %lu bytes", written, outbuf[i].cbBuffer);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ }
+
+ /* free obsolete buffer */
+ if(outbuf[i].pvBuffer != NULL) {
+ s_pSecFn->FreeContextBuffer(outbuf[i].pvBuffer);
+ }
+ }
+ }
+ else {
+ if(sspi_status == SEC_E_WRONG_PRINCIPAL)
+ failf(data, "schannel: SNI or certificate check failed: %s",
+ Curl_sspi_strerror(conn, sspi_status));
+ else
+ failf(data, "schannel: next InitializeSecurityContext failed: %s",
+ Curl_sspi_strerror(conn, sspi_status));
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
+ /* check if there was additional remaining encrypted data */
+ if(inbuf[1].BufferType == SECBUFFER_EXTRA && inbuf[1].cbBuffer > 0) {
+ infof(data, "schannel: encrypted data length: %lu\n", inbuf[1].cbBuffer);
+ /*
+ There are two cases where we could be getting extra data here:
+ 1) If we're renegotiating a connection and the handshake is already
+ complete (from the server perspective), it can encrypted app data
+ (not handshake data) in an extra buffer at this point.
+ 2) (sspi_status == SEC_I_CONTINUE_NEEDED) We are negotiating a
+ connection and this extra data is part of the handshake.
+ We should process the data immediately; waiting for the socket to
+ be ready may fail since the server is done sending handshake data.
+ */
+ /* check if the remaining data is less than the total amount
+ and therefore begins after the already processed data */
+ if(connssl->encdata_offset > inbuf[1].cbBuffer) {
+ memmove(connssl->encdata_buffer,
+ (connssl->encdata_buffer + connssl->encdata_offset) -
+ inbuf[1].cbBuffer, inbuf[1].cbBuffer);
+ connssl->encdata_offset = inbuf[1].cbBuffer;
+ if(sspi_status == SEC_I_CONTINUE_NEEDED) {
+ doread = FALSE;
+ continue;
+ }
+ }
+ }
+ else {
+ connssl->encdata_offset = 0;
+ }
+ break;
+ }
+
+ /* check if the handshake needs to be continued */
+ if(sspi_status == SEC_I_CONTINUE_NEEDED) {
+ connssl->connecting_state = ssl_connect_2_reading;
+ return CURLE_OK;
+ }
+
+ /* check if the handshake is complete */
+ if(sspi_status == SEC_E_OK) {
+ connssl->connecting_state = ssl_connect_3;
+ infof(data, "schannel: SSL/TLS handshake complete\n");
+ }
+
+#ifdef _WIN32_WCE
+ /* Windows CE doesn't do any server certificate validation.
+ We have to do it manually. */
+ if(data->set.ssl.verifypeer)
+ return verify_certificate(conn, sockindex);
+#endif
+
+ return CURLE_OK;
+}
+
+static CURLcode
+schannel_connect_step3(struct connectdata *conn, int sockindex)
+{
+ CURLcode result = CURLE_OK;
+ struct SessionHandle *data = conn->data;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct curl_schannel_cred *old_cred = NULL;
+ bool incache;
+
+ DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
+
+ infof(data, "schannel: SSL/TLS connection with %s port %hu (step 3/3)\n",
+ conn->host.name, conn->remote_port);
+
+ if(!connssl->cred)
+ return CURLE_SSL_CONNECT_ERROR;
+
+ /* check if the required context attributes are met */
+ if(connssl->ret_flags != connssl->req_flags) {
+ if(!(connssl->ret_flags & ISC_RET_SEQUENCE_DETECT))
+ failf(data, "schannel: failed to setup sequence detection");
+ if(!(connssl->ret_flags & ISC_RET_REPLAY_DETECT))
+ failf(data, "schannel: failed to setup replay detection");
+ if(!(connssl->ret_flags & ISC_RET_CONFIDENTIALITY))
+ failf(data, "schannel: failed to setup confidentiality");
+ if(!(connssl->ret_flags & ISC_RET_ALLOCATED_MEMORY))
+ failf(data, "schannel: failed to setup memory allocation");
+ if(!(connssl->ret_flags & ISC_RET_STREAM))
+ failf(data, "schannel: failed to setup stream orientation");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
+ /* increment the reference counter of the credential/session handle */
+ if(connssl->cred && connssl->ctxt) {
+ connssl->cred->refcount++;
+ infof(data, "schannel: incremented credential handle refcount = %d\n",
+ connssl->cred->refcount);
+ }
+
+ /* save the current session data for possible re-use */
+ incache = !(Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL));
+ if(incache) {
+ if(old_cred != connssl->cred) {
+ infof(data, "schannel: old credential handle is stale, removing\n");
+ Curl_ssl_delsessionid(conn, (void *)old_cred);
+ incache = FALSE;
+ }
+ }
+
+ if(!incache) {
+ result = Curl_ssl_addsessionid(conn, (void *)connssl->cred,
+ sizeof(struct curl_schannel_cred));
+ if(result) {
+ failf(data, "schannel: failed to store credential handle");
+ return result;
+ }
+ else {
+ connssl->cred->cached = TRUE;
+ infof(data, "schannel: stored credential handle in session cache\n");
+ }
+ }
+
+ connssl->connecting_state = ssl_connect_done;
+
+ return CURLE_OK;
+}
+
+static CURLcode
+schannel_connect_common(struct connectdata *conn, int sockindex,
+ bool nonblocking, bool *done)
+{
+ CURLcode result;
+ struct SessionHandle *data = conn->data;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ curl_socket_t sockfd = conn->sock[sockindex];
+ long timeout_ms;
+ int what;
+
+ /* check if the connection has already been established */
+ if(ssl_connection_complete == connssl->state) {
+ *done = TRUE;
+ return CURLE_OK;
+ }
+
+ if(ssl_connect_1 == connssl->connecting_state) {
+ /* check out how much more time we're allowed */
+ timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+ if(timeout_ms < 0) {
+ /* no need to continue if time already is up */
+ failf(data, "SSL/TLS connection timeout");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+
+ result = schannel_connect_step1(conn, sockindex);
+ if(result)
+ return result;
+ }
+
+ while(ssl_connect_2 == connssl->connecting_state ||
+ ssl_connect_2_reading == connssl->connecting_state ||
+ ssl_connect_2_writing == connssl->connecting_state) {
+
+ /* check out how much more time we're allowed */
+ timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+ if(timeout_ms < 0) {
+ /* no need to continue if time already is up */
+ failf(data, "SSL/TLS connection timeout");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+
+ /* if ssl is expecting something, check if it's available. */
+ if(connssl->connecting_state == ssl_connect_2_reading
+ || connssl->connecting_state == ssl_connect_2_writing) {
+
+ curl_socket_t writefd = ssl_connect_2_writing ==
+ connssl->connecting_state ? sockfd : CURL_SOCKET_BAD;
+ curl_socket_t readfd = ssl_connect_2_reading ==
+ connssl->connecting_state ? sockfd : CURL_SOCKET_BAD;
+
+ what = Curl_socket_ready(readfd, writefd, nonblocking ? 0 : timeout_ms);
+ if(what < 0) {
+ /* fatal error */
+ failf(data, "select/poll on SSL/TLS socket, errno: %d", SOCKERRNO);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ else if(0 == what) {
+ if(nonblocking) {
+ *done = FALSE;
+ return CURLE_OK;
+ }
+ else {
+ /* timeout */
+ failf(data, "SSL/TLS connection timeout");
+ return CURLE_OPERATION_TIMEDOUT;
+ }
+ }
+ /* socket is readable or writable */
+ }
+
+ /* Run transaction, and return to the caller if it failed or if
+ * this connection is part of a multi handle and this loop would
+ * execute again. This permits the owner of a multi handle to
+ * abort a connection attempt before step2 has completed while
+ * ensuring that a client using select() or epoll() will always
+ * have a valid fdset to wait on.
+ */
+ result = schannel_connect_step2(conn, sockindex);
+ if(result || (nonblocking &&
+ (ssl_connect_2 == connssl->connecting_state ||
+ ssl_connect_2_reading == connssl->connecting_state ||
+ ssl_connect_2_writing == connssl->connecting_state)))
+ return result;
+
+ } /* repeat step2 until all transactions are done. */
+
+ if(ssl_connect_3 == connssl->connecting_state) {
+ result = schannel_connect_step3(conn, sockindex);
+ if(result)
+ return result;
+ }
+
+ if(ssl_connect_done == connssl->connecting_state) {
+ connssl->state = ssl_connection_complete;
+ conn->recv[sockindex] = schannel_recv;
+ conn->send[sockindex] = schannel_send;
+ *done = TRUE;
+ }
+ else
+ *done = FALSE;
+
+ /* reset our connection state machine */
+ connssl->connecting_state = ssl_connect_1;
+
+ return CURLE_OK;
+}
+
+static ssize_t
+schannel_send(struct connectdata *conn, int sockindex,
+ const void *buf, size_t len, CURLcode *err)
+{
+ ssize_t written = -1;
+ size_t data_len = 0;
+ unsigned char *data = NULL;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ SecBuffer outbuf[4];
+ SecBufferDesc outbuf_desc;
+ SECURITY_STATUS sspi_status = SEC_E_OK;
+ CURLcode result;
+
+ /* check if the maximum stream sizes were queried */
+ if(connssl->stream_sizes.cbMaximumMessage == 0) {
+ sspi_status = s_pSecFn->QueryContextAttributes(
+ &connssl->ctxt->ctxt_handle,
+ SECPKG_ATTR_STREAM_SIZES,
+ &connssl->stream_sizes);
+ if(sspi_status != SEC_E_OK) {
+ *err = CURLE_SEND_ERROR;
+ return -1;
+ }
+ }
+
+ /* check if the buffer is longer than the maximum message length */
+ if(len > connssl->stream_sizes.cbMaximumMessage) {
+ *err = CURLE_SEND_ERROR;
+ return -1;
+ }
+
+ /* calculate the complete message length and allocate a buffer for it */
+ data_len = connssl->stream_sizes.cbHeader + len +
+ connssl->stream_sizes.cbTrailer;
+ data = (unsigned char *) malloc(data_len);
+ if(data == NULL) {
+ *err = CURLE_OUT_OF_MEMORY;
+ return -1;
+ }
+
+ /* setup output buffers (header, data, trailer, empty) */
+ InitSecBuffer(&outbuf[0], SECBUFFER_STREAM_HEADER,
+ data, connssl->stream_sizes.cbHeader);
+ InitSecBuffer(&outbuf[1], SECBUFFER_DATA,
+ data + connssl->stream_sizes.cbHeader, curlx_uztoul(len));
+ InitSecBuffer(&outbuf[2], SECBUFFER_STREAM_TRAILER,
+ data + connssl->stream_sizes.cbHeader + len,
+ connssl->stream_sizes.cbTrailer);
+ InitSecBuffer(&outbuf[3], SECBUFFER_EMPTY, NULL, 0);
+ InitSecBufferDesc(&outbuf_desc, outbuf, 4);
+
+ /* copy data into output buffer */
+ memcpy(outbuf[1].pvBuffer, buf, len);
+
+ /* http://msdn.microsoft.com/en-us/library/windows/desktop/aa375390.aspx */
+ sspi_status = s_pSecFn->EncryptMessage(&connssl->ctxt->ctxt_handle, 0,
+ &outbuf_desc, 0);
+
+ /* check if the message was encrypted */
+ if(sspi_status == SEC_E_OK) {
+ written = 0;
+
+ /* send the encrypted message including header, data and trailer */
+ len = outbuf[0].cbBuffer + outbuf[1].cbBuffer + outbuf[2].cbBuffer;
+
+ /*
+ It's important to send the full message which includes the header,
+ encrypted payload, and trailer. Until the client receives all the
+ data a coherent message has not been delivered and the client
+ can't read any of it.
+
+ If we wanted to buffer the unwritten encrypted bytes, we would
+ tell the client that all data it has requested to be sent has been
+ sent. The unwritten encrypted bytes would be the first bytes to
+ send on the next invocation.
+ Here's the catch with this - if we tell the client that all the
+ bytes have been sent, will the client call this method again to
+ send the buffered data? Looking at who calls this function, it
+ seems the answer is NO.
+ */
+
+ /* send entire message or fail */
+ while(len > (size_t)written) {
+ ssize_t this_write;
+ long timeleft;
+ int what;
+
+ this_write = 0;
+
+ timeleft = Curl_timeleft(conn->data, NULL, FALSE);
+ if(timeleft < 0) {
+ /* we already got the timeout */
+ failf(conn->data, "schannel: timed out sending data "
+ "(bytes sent: %zd)", written);
+ *err = CURLE_OPERATION_TIMEDOUT;
+ written = -1;
+ break;
+ }
+
+ what = Curl_socket_ready(CURL_SOCKET_BAD, conn->sock[sockindex],
+ timeleft);
+ if(what < 0) {
+ /* fatal error */
+ failf(conn->data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+ *err = CURLE_SEND_ERROR;
+ written = -1;
+ break;
+ }
+ else if(0 == what) {
+ failf(conn->data, "schannel: timed out sending data "
+ "(bytes sent: %zd)", written);
+ *err = CURLE_OPERATION_TIMEDOUT;
+ written = -1;
+ break;
+ }
+ /* socket is writable */
+
+ result = Curl_write_plain(conn, conn->sock[sockindex], data + written,
+ len - written, &this_write);
+ if(result == CURLE_AGAIN)
+ continue;
+ else if(result != CURLE_OK) {
+ *err = result;
+ written = -1;
+ break;
+ }
+
+ written += this_write;
+ }
+ }
+ else if(sspi_status == SEC_E_INSUFFICIENT_MEMORY) {
+ *err = CURLE_OUT_OF_MEMORY;
+ }
+ else{
+ *err = CURLE_SEND_ERROR;
+ }
+
+ Curl_safefree(data);
+
+ if(len == (size_t)written)
+ /* Encrypted message including header, data and trailer entirely sent.
+ The return value is the number of unencrypted bytes that were sent. */
+ written = outbuf[1].cbBuffer;
+
+ return written;
+}
+
+static ssize_t
+schannel_recv(struct connectdata *conn, int sockindex,
+ char *buf, size_t len, CURLcode *err)
+{
+ size_t size = 0;
+ ssize_t nread = -1;
+ struct SessionHandle *data = conn->data;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ unsigned char *reallocated_buffer;
+ size_t reallocated_length;
+ bool done = FALSE;
+ SecBuffer inbuf[4];
+ SecBufferDesc inbuf_desc;
+ SECURITY_STATUS sspi_status = SEC_E_OK;
+ /* we want the length of the encrypted buffer to be at least large enough
+ that it can hold all the bytes requested and some TLS record overhead. */
+ size_t min_encdata_length = len + CURL_SCHANNEL_BUFFER_FREE_SIZE;
+
+ /****************************************************************************
+ * Don't return or set connssl->recv_unrecoverable_err unless in the cleanup.
+ * The pattern for return error is set *err, optional infof, goto cleanup.
+ *
+ * Our priority is to always return as much decrypted data to the caller as
+ * possible, even if an error occurs. The state of the decrypted buffer must
+ * always be valid. Transfer of decrypted data to the caller's buffer is
+ * handled in the cleanup.
+ */
+
+ infof(data, "schannel: client wants to read %zu bytes\n", len);
+ *err = CURLE_OK;
+
+ if(len && len <= connssl->decdata_offset) {
+ infof(data, "schannel: enough decrypted data is already available\n");
+ goto cleanup;
+ }
+ else if(connssl->recv_unrecoverable_err) {
+ *err = connssl->recv_unrecoverable_err;
+ infof(data, "schannel: an unrecoverable error occurred in a prior call\n");
+ goto cleanup;
+ }
+ else if(connssl->recv_sspi_close_notify) {
+ /* once a server has indicated shutdown there is no more encrypted data */
+ infof(data, "schannel: server indicated shutdown in a prior call\n");
+ goto cleanup;
+ }
+ else if(!len) {
+ /* It's debatable what to return when !len. Regardless we can't return
+ immediately because there may be data to decrypt (in the case we want to
+ decrypt all encrypted cached data) so handle !len later in cleanup.
+ */
+ ; /* do nothing */
+ }
+ else if(!connssl->recv_connection_closed) {
+ /* increase enc buffer in order to fit the requested amount of data */
+ size = connssl->encdata_length - connssl->encdata_offset;
+ if(size < CURL_SCHANNEL_BUFFER_FREE_SIZE ||
+ connssl->encdata_length < min_encdata_length) {
+ reallocated_length = connssl->encdata_offset +
+ CURL_SCHANNEL_BUFFER_FREE_SIZE;
+ if(reallocated_length < min_encdata_length) {
+ reallocated_length = min_encdata_length;
+ }
+ reallocated_buffer = realloc(connssl->encdata_buffer,
+ reallocated_length);
+ if(reallocated_buffer == NULL) {
+ *err = CURLE_OUT_OF_MEMORY;
+ failf(data, "schannel: unable to re-allocate memory");
+ goto cleanup;
+ }
+
+ connssl->encdata_buffer = reallocated_buffer;
+ connssl->encdata_length = reallocated_length;
+ size = connssl->encdata_length - connssl->encdata_offset;
+ infof(data, "schannel: encdata_buffer resized %zu\n",
+ connssl->encdata_length);
+ }
+
+ infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
+ connssl->encdata_offset, connssl->encdata_length);
+
+ /* read encrypted data from socket */
+ *err = Curl_read_plain(conn->sock[sockindex],
+ (char *)(connssl->encdata_buffer +
+ connssl->encdata_offset),
+ size, &nread);
+ if(*err) {
+ nread = -1;
+ if(*err == CURLE_AGAIN)
+ infof(data, "schannel: Curl_read_plain returned CURLE_AGAIN\n");
+ else if(*err == CURLE_RECV_ERROR)
+ infof(data, "schannel: Curl_read_plain returned CURLE_RECV_ERROR\n");
+ else
+ infof(data, "schannel: Curl_read_plain returned error %d\n", *err);
+ }
+ else if(nread == 0) {
+ connssl->recv_connection_closed = true;
+ infof(data, "schannel: server closed the connection\n");
+ }
+ else if(nread > 0) {
+ connssl->encdata_offset += (size_t)nread;
+ infof(data, "schannel: encrypted data got %zd\n", nread);
+ }
+ }
+
+ infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
+ connssl->encdata_offset, connssl->encdata_length);
+
+ /* decrypt loop */
+ while(connssl->encdata_offset > 0 && sspi_status == SEC_E_OK &&
+ (!len || connssl->decdata_offset < len ||
+ connssl->recv_connection_closed)) {
+ /* prepare data buffer for DecryptMessage call */
+ InitSecBuffer(&inbuf[0], SECBUFFER_DATA, connssl->encdata_buffer,
+ curlx_uztoul(connssl->encdata_offset));
+
+ /* we need 3 more empty input buffers for possible output */
+ InitSecBuffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0);
+ InitSecBuffer(&inbuf[2], SECBUFFER_EMPTY, NULL, 0);
+ InitSecBuffer(&inbuf[3], SECBUFFER_EMPTY, NULL, 0);
+ InitSecBufferDesc(&inbuf_desc, inbuf, 4);
+
+ /* http://msdn.microsoft.com/en-us/library/windows/desktop/aa375348.aspx */
+ sspi_status = s_pSecFn->DecryptMessage(&connssl->ctxt->ctxt_handle,
+ &inbuf_desc, 0, NULL);
+
+ /* check if everything went fine (server may want to renegotiate
+ or shutdown the connection context) */
+ if(sspi_status == SEC_E_OK || sspi_status == SEC_I_RENEGOTIATE ||
+ sspi_status == SEC_I_CONTEXT_EXPIRED) {
+ /* check for successfully decrypted data, even before actual
+ renegotiation or shutdown of the connection context */
+ if(inbuf[1].BufferType == SECBUFFER_DATA) {
+ infof(data, "schannel: decrypted data length: %lu\n",
+ inbuf[1].cbBuffer);
+
+ /* increase buffer in order to fit the received amount of data */
+ size = inbuf[1].cbBuffer > CURL_SCHANNEL_BUFFER_FREE_SIZE ?
+ inbuf[1].cbBuffer : CURL_SCHANNEL_BUFFER_FREE_SIZE;
+ if(connssl->decdata_length - connssl->decdata_offset < size ||
+ connssl->decdata_length < len) {
+ /* increase internal decrypted data buffer */
+ reallocated_length = connssl->decdata_offset + size;
+ /* make sure that the requested amount of data fits */
+ if(reallocated_length < len) {
+ reallocated_length = len;
+ }
+ reallocated_buffer = realloc(connssl->decdata_buffer,
+ reallocated_length);
+ if(reallocated_buffer == NULL) {
+ *err = CURLE_OUT_OF_MEMORY;
+ failf(data, "schannel: unable to re-allocate memory");
+ goto cleanup;
+ }
+ connssl->decdata_buffer = reallocated_buffer;
+ connssl->decdata_length = reallocated_length;
+ }
+
+ /* copy decrypted data to internal buffer */
+ size = inbuf[1].cbBuffer;
+ if(size) {
+ memcpy(connssl->decdata_buffer + connssl->decdata_offset,
+ inbuf[1].pvBuffer, size);
+ connssl->decdata_offset += size;
+ }
+
+ infof(data, "schannel: decrypted data added: %zu\n", size);
+ infof(data, "schannel: decrypted data cached: offset %zu length %zu\n",
+ connssl->decdata_offset, connssl->decdata_length);
+ }
+
+ /* check for remaining encrypted data */
+ if(inbuf[3].BufferType == SECBUFFER_EXTRA && inbuf[3].cbBuffer > 0) {
+ infof(data, "schannel: encrypted data length: %lu\n",
+ inbuf[3].cbBuffer);
+
+ /* check if the remaining data is less than the total amount
+ * and therefore begins after the already processed data
+ */
+ if(connssl->encdata_offset > inbuf[3].cbBuffer) {
+ /* move remaining encrypted data forward to the beginning of
+ buffer */
+ memmove(connssl->encdata_buffer,
+ (connssl->encdata_buffer + connssl->encdata_offset) -
+ inbuf[3].cbBuffer, inbuf[3].cbBuffer);
+ connssl->encdata_offset = inbuf[3].cbBuffer;
+ }
+
+ infof(data, "schannel: encrypted data cached: offset %zu length %zu\n",
+ connssl->encdata_offset, connssl->encdata_length);
+ }
+ else {
+ /* reset encrypted buffer offset, because there is no data remaining */
+ connssl->encdata_offset = 0;
+ }
+
+ /* check if server wants to renegotiate the connection context */
+ if(sspi_status == SEC_I_RENEGOTIATE) {
+ infof(data, "schannel: remote party requests renegotiation\n");
+ if(*err && *err != CURLE_AGAIN) {
+ infof(data, "schannel: can't renogotiate, an error is pending\n");
+ goto cleanup;
+ }
+ if(connssl->encdata_offset) {
+ *err = CURLE_RECV_ERROR;
+ infof(data, "schannel: can't renogotiate, "
+ "encrypted data available\n");
+ goto cleanup;
+ }
+ /* begin renegotiation */
+ infof(data, "schannel: renegotiating SSL/TLS connection\n");
+ connssl->state = ssl_connection_negotiating;
+ connssl->connecting_state = ssl_connect_2_writing;
+ *err = schannel_connect_common(conn, sockindex, FALSE, &done);
+ if(*err) {
+ infof(data, "schannel: renegotiation failed\n");
+ goto cleanup;
+ }
+ /* now retry receiving data */
+ sspi_status = SEC_E_OK;
+ infof(data, "schannel: SSL/TLS connection renegotiated\n");
+ continue;
+ }
+ /* check if the server closed the connection */
+ else if(sspi_status == SEC_I_CONTEXT_EXPIRED) {
+ /* In Windows 2000 SEC_I_CONTEXT_EXPIRED (close_notify) is not
+ returned so we have to work around that in cleanup. */
+ connssl->recv_sspi_close_notify = true;
+ if(!connssl->recv_connection_closed) {
+ connssl->recv_connection_closed = true;
+ infof(data, "schannel: server closed the connection\n");
+ }
+ goto cleanup;
+ }
+ }
+ else if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
+ if(!*err)
+ *err = CURLE_AGAIN;
+ infof(data, "schannel: failed to decrypt data, need more data\n");
+ goto cleanup;
+ }
+ else {
+ *err = CURLE_RECV_ERROR;
+ infof(data, "schannel: failed to read data from server: %s\n",
+ Curl_sspi_strerror(conn, sspi_status));
+ goto cleanup;
+ }
+ }
+
+ infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
+ connssl->encdata_offset, connssl->encdata_length);
+
+ infof(data, "schannel: decrypted data buffer: offset %zu length %zu\n",
+ connssl->decdata_offset, connssl->decdata_length);
+
+cleanup:
+ /* Warning- there is no guarantee the encdata state is valid at this point */
+ infof(data, "schannel: schannel_recv cleanup\n");
+
+ /* Error if the connection has closed without a close_notify.
+ Behavior here is a matter of debate. We don't want to be vulnerable to a
+ truncation attack however there's some browser precedent for ignoring the
+ close_notify for compatibility reasons.
+ Additionally, Windows 2000 (v5.0) is a special case since it seems it doesn't
+ return close_notify. In that case if the connection was closed we assume it
+ was graceful (close_notify) since there doesn't seem to be a way to tell.
+ */
+ if(len && !connssl->decdata_offset && connssl->recv_connection_closed &&
+ !connssl->recv_sspi_close_notify) {
+ BOOL isWin2k;
+ ULONGLONG cm;
+ OSVERSIONINFOEX osver;
+
+ memset(&osver, 0, sizeof(osver));
+ osver.dwOSVersionInfoSize = sizeof(osver);
+ osver.dwMajorVersion = 5;
+
+ cm = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
+ cm = VerSetConditionMask(cm, VER_MINORVERSION, VER_EQUAL);
+ cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
+ cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL);
+
+ isWin2k = VerifyVersionInfo(&osver,
+ (VER_MAJORVERSION | VER_MINORVERSION |
+ VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR),
+ cm);
+
+ if(isWin2k && sspi_status == SEC_E_OK)
+ connssl->recv_sspi_close_notify = true;
+ else {
+ *err = CURLE_RECV_ERROR;
+ infof(data, "schannel: server closed abruptly (missing close_notify)\n");
+ }
+ }
+
+ /* Any error other than CURLE_AGAIN is an unrecoverable error. */
+ if(*err && *err != CURLE_AGAIN)
+ connssl->recv_unrecoverable_err = *err;
+
+ size = len < connssl->decdata_offset ? len : connssl->decdata_offset;
+ if(size) {
+ memcpy(buf, connssl->decdata_buffer, size);
+ memmove(connssl->decdata_buffer, connssl->decdata_buffer + size,
+ connssl->decdata_offset - size);
+ connssl->decdata_offset -= size;
+
+ infof(data, "schannel: decrypted data returned %zu\n", size);
+ infof(data, "schannel: decrypted data buffer: offset %zu length %zu\n",
+ connssl->decdata_offset, connssl->decdata_length);
+ *err = CURLE_OK;
+ return (ssize_t)size;
+ }
+
+ if(!*err && !connssl->recv_connection_closed)
+ *err = CURLE_AGAIN;
+
+ /* It's debatable what to return when !len. We could return whatever error we
+ got from decryption but instead we override here so the return is consistent.
+ */
+ if(!len)
+ *err = CURLE_OK;
+
+ return *err ? -1 : 0;
+}
+
+CURLcode
+Curl_schannel_connect_nonblocking(struct connectdata *conn, int sockindex,
+ bool *done)
+{
+ return schannel_connect_common(conn, sockindex, TRUE, done);
+}
+
+CURLcode
+Curl_schannel_connect(struct connectdata *conn, int sockindex)
+{
+ CURLcode result;
+ bool done = FALSE;
+
+ result = schannel_connect_common(conn, sockindex, FALSE, &done);
+ if(result)
+ return result;
+
+ DEBUGASSERT(done);
+
+ return CURLE_OK;
+}
+
+bool Curl_schannel_data_pending(const struct connectdata *conn, int sockindex)
+{
+ const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+ if(connssl->use) /* SSL/TLS is in use */
+ return (connssl->encdata_offset > 0 ||
+ connssl->decdata_offset > 0 ) ? TRUE : FALSE;
+ else
+ return FALSE;
+}
+
+void Curl_schannel_close(struct connectdata *conn, int sockindex)
+{
+ if(conn->ssl[sockindex].use)
+ /* if the SSL/TLS channel hasn't been shut down yet, do that now. */
+ Curl_ssl_shutdown(conn, sockindex);
+}
+
+int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
+{
+ /* See http://msdn.microsoft.com/en-us/library/windows/desktop/aa380138.aspx
+ * Shutting Down an Schannel Connection
+ */
+ struct SessionHandle *data = conn->data;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+ infof(data, "schannel: shutting down SSL/TLS connection with %s port %hu\n",
+ conn->host.name, conn->remote_port);
+
+ if(connssl->cred && connssl->ctxt) {
+ SecBufferDesc BuffDesc;
+ SecBuffer Buffer;
+ SECURITY_STATUS sspi_status;
+ SecBuffer outbuf;
+ SecBufferDesc outbuf_desc;
+ CURLcode result;
+ TCHAR *host_name;
+ DWORD dwshut = SCHANNEL_SHUTDOWN;
+
+ InitSecBuffer(&Buffer, SECBUFFER_TOKEN, &dwshut, sizeof(dwshut));
+ InitSecBufferDesc(&BuffDesc, &Buffer, 1);
+
+ sspi_status = s_pSecFn->ApplyControlToken(&connssl->ctxt->ctxt_handle,
+ &BuffDesc);
+
+ if(sspi_status != SEC_E_OK)
+ failf(data, "schannel: ApplyControlToken failure: %s",
+ Curl_sspi_strerror(conn, sspi_status));
+
+ host_name = Curl_convert_UTF8_to_tchar(conn->host.name);
+ if(!host_name)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* setup output buffer */
+ InitSecBuffer(&outbuf, SECBUFFER_EMPTY, NULL, 0);
+ InitSecBufferDesc(&outbuf_desc, &outbuf, 1);
+
+ sspi_status = s_pSecFn->InitializeSecurityContext(
+ &connssl->cred->cred_handle,
+ &connssl->ctxt->ctxt_handle,
+ host_name,
+ connssl->req_flags,
+ 0,
+ 0,
+ NULL,
+ 0,
+ &connssl->ctxt->ctxt_handle,
+ &outbuf_desc,
+ &connssl->ret_flags,
+ &connssl->ctxt->time_stamp);
+
+ Curl_unicodefree(host_name);
+
+ if((sspi_status == SEC_E_OK) || (sspi_status == SEC_I_CONTEXT_EXPIRED)) {
+ /* send close message which is in output buffer */
+ ssize_t written;
+ result = Curl_write_plain(conn, conn->sock[sockindex], outbuf.pvBuffer,
+ outbuf.cbBuffer, &written);
+
+ s_pSecFn->FreeContextBuffer(outbuf.pvBuffer);
+ if((result != CURLE_OK) || (outbuf.cbBuffer != (size_t) written)) {
+ infof(data, "schannel: failed to send close msg: %s"
+ " (bytes written: %zd)\n", curl_easy_strerror(result), written);
+ }
+ }
+ }
+
+ /* free SSPI Schannel API security context handle */
+ if(connssl->ctxt) {
+ infof(data, "schannel: clear security context handle\n");
+ s_pSecFn->DeleteSecurityContext(&connssl->ctxt->ctxt_handle);
+ Curl_safefree(connssl->ctxt);
+ }
+
+ /* free SSPI Schannel API credential handle */
+ if(connssl->cred) {
+ /* decrement the reference counter of the credential/session handle */
+ if(connssl->cred->refcount > 0) {
+ connssl->cred->refcount--;
+ infof(data, "schannel: decremented credential handle refcount = %d\n",
+ connssl->cred->refcount);
+ }
+
+ /* if the handle was not cached and the refcount is zero */
+ if(!connssl->cred->cached && connssl->cred->refcount == 0) {
+ infof(data, "schannel: clear credential handle\n");
+ s_pSecFn->FreeCredentialsHandle(&connssl->cred->cred_handle);
+ Curl_safefree(connssl->cred);
+ }
+ }
+
+ /* free internal buffer for received encrypted data */
+ if(connssl->encdata_buffer != NULL) {
+ Curl_safefree(connssl->encdata_buffer);
+ connssl->encdata_length = 0;
+ connssl->encdata_offset = 0;
+ }
+
+ /* free internal buffer for received decrypted data */
+ if(connssl->decdata_buffer != NULL) {
+ Curl_safefree(connssl->decdata_buffer);
+ connssl->decdata_length = 0;
+ connssl->decdata_offset = 0;
+ }
+
+ return CURLE_OK;
+}
+
+void Curl_schannel_session_free(void *ptr)
+{
+ struct curl_schannel_cred *cred = ptr;
+
+ if(cred && cred->cached) {
+ if(cred->refcount == 0) {
+ s_pSecFn->FreeCredentialsHandle(&cred->cred_handle);
+ Curl_safefree(cred);
+ }
+ else {
+ cred->cached = FALSE;
+ }
+ }
+}
+
+int Curl_schannel_init(void)
+{
+ return (Curl_sspi_global_init() == CURLE_OK ? 1 : 0);
+}
+
+void Curl_schannel_cleanup(void)
+{
+ Curl_sspi_global_cleanup();
+}
+
+size_t Curl_schannel_version(char *buffer, size_t size)
+{
+ size = snprintf(buffer, size, "WinSSL");
+
+ return size;
+}
+
+int Curl_schannel_random(unsigned char *entropy, size_t length)
+{
+ HCRYPTPROV hCryptProv = 0;
+
+ if(!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
+ return 1;
+
+ if(!CryptGenRandom(hCryptProv, (DWORD)length, entropy)) {
+ CryptReleaseContext(hCryptProv, 0UL);
+ return 1;
+ }
+
+ CryptReleaseContext(hCryptProv, 0UL);
+ return 0;
+}
+
+#ifdef _WIN32_WCE
+static CURLcode verify_certificate(struct connectdata *conn, int sockindex)
+{
+ SECURITY_STATUS status;
+ struct SessionHandle *data = conn->data;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ CURLcode result = CURLE_OK;
+ CERT_CONTEXT *pCertContextServer = NULL;
+ const CERT_CHAIN_CONTEXT *pChainContext = NULL;
+
+ status = s_pSecFn->QueryContextAttributes(&connssl->ctxt->ctxt_handle,
+ SECPKG_ATTR_REMOTE_CERT_CONTEXT,
+ &pCertContextServer);
+
+ if((status != SEC_E_OK) || (pCertContextServer == NULL)) {
+ failf(data, "schannel: Failed to read remote certificate context: %s",
+ Curl_sspi_strerror(conn, status));
+ result = CURLE_PEER_FAILED_VERIFICATION;
+ }
+
+ if(result == CURLE_OK) {
+ CERT_CHAIN_PARA ChainPara;
+ memset(&ChainPara, 0, sizeof(ChainPara));
+ ChainPara.cbSize = sizeof(ChainPara);
+
+ if(!CertGetCertificateChain(NULL,
+ pCertContextServer,
+ NULL,
+ pCertContextServer->hCertStore,
+ &ChainPara,
+ (data->set.ssl_no_revoke ? 0 :
+ CERT_CHAIN_REVOCATION_CHECK_CHAIN),
+ NULL,
+ &pChainContext)) {
+ failf(data, "schannel: CertGetCertificateChain failed: %s",
+ Curl_sspi_strerror(conn, GetLastError()));
+ pChainContext = NULL;
+ result = CURLE_PEER_FAILED_VERIFICATION;
+ }
+
+ if(result == CURLE_OK) {
+ CERT_SIMPLE_CHAIN *pSimpleChain = pChainContext->rgpChain[0];
+ DWORD dwTrustErrorMask = ~(DWORD)(CERT_TRUST_IS_NOT_TIME_NESTED);
+ dwTrustErrorMask &= pSimpleChain->TrustStatus.dwErrorStatus;
+ if(dwTrustErrorMask) {
+ if(dwTrustErrorMask & CERT_TRUST_IS_REVOKED)
+ failf(data, "schannel: CertGetCertificateChain trust error"
+ " CERT_TRUST_IS_REVOKED");
+ else if(dwTrustErrorMask & CERT_TRUST_IS_PARTIAL_CHAIN)
+ failf(data, "schannel: CertGetCertificateChain trust error"
+ " CERT_TRUST_IS_PARTIAL_CHAIN");
+ else if(dwTrustErrorMask & CERT_TRUST_IS_UNTRUSTED_ROOT)
+ failf(data, "schannel: CertGetCertificateChain trust error"
+ " CERT_TRUST_IS_UNTRUSTED_ROOT");
+ else if(dwTrustErrorMask & CERT_TRUST_IS_NOT_TIME_VALID)
+ failf(data, "schannel: CertGetCertificateChain trust error"
+ " CERT_TRUST_IS_NOT_TIME_VALID");
+ else
+ failf(data, "schannel: CertGetCertificateChain error mask: 0x%08x",
+ dwTrustErrorMask);
+ result = CURLE_PEER_FAILED_VERIFICATION;
+ }
+ }
+ }
+
+ if(result == CURLE_OK) {
+ if(data->set.ssl.verifyhost) {
+ TCHAR cert_hostname_buff[128];
+ xcharp_u hostname;
+ xcharp_u cert_hostname;
+ DWORD len;
+
+ cert_hostname.const_tchar_ptr = cert_hostname_buff;
+ hostname.tchar_ptr = Curl_convert_UTF8_to_tchar(conn->host.name);
+
+ /* TODO: Fix this for certificates with multiple alternative names.
+ Right now we're only asking for the first preferred alternative name.
+ Instead we'd need to do all via CERT_NAME_SEARCH_ALL_NAMES_FLAG
+ (if WinCE supports that?) and run this section in a loop for each.
+ https://msdn.microsoft.com/en-us/library/windows/desktop/aa376086.aspx
+ curl: (51) schannel: CertGetNameString() certificate hostname
+ (.google.com) did not match connection (google.com)
+ */
+ len = CertGetNameString(pCertContextServer,
+ CERT_NAME_DNS_TYPE,
+ 0,
+ NULL,
+ cert_hostname.tchar_ptr,
+ 128);
+ if(len > 0 && *cert_hostname.tchar_ptr == '*') {
+ /* this is a wildcard cert. try matching the last len - 1 chars */
+ int hostname_len = strlen(conn->host.name);
+ cert_hostname.tchar_ptr++;
+ if(_tcsicmp(cert_hostname.const_tchar_ptr,
+ hostname.const_tchar_ptr + hostname_len - len + 2) != 0)
+ result = CURLE_PEER_FAILED_VERIFICATION;
+ }
+ else if(len == 0 || _tcsicmp(hostname.const_tchar_ptr,
+ cert_hostname.const_tchar_ptr) != 0) {
+ result = CURLE_PEER_FAILED_VERIFICATION;
+ }
+ if(result == CURLE_PEER_FAILED_VERIFICATION) {
+ char *_cert_hostname;
+ _cert_hostname = Curl_convert_tchar_to_UTF8(cert_hostname.tchar_ptr);
+ failf(data, "schannel: CertGetNameString() certificate hostname "
+ "(%s) did not match connection (%s)",
+ _cert_hostname, conn->host.name);
+ Curl_unicodefree(_cert_hostname);
+ }
+ Curl_unicodefree(hostname.tchar_ptr);
+ }
+ }
+
+ if(pChainContext)
+ CertFreeCertificateChain(pChainContext);
+
+ if(pCertContextServer)
+ CertFreeCertificateContext(pCertContextServer);
+
+ return result;
+}
+#endif /* _WIN32_WCE */
+
+#endif /* USE_SCHANNEL */
diff --git a/Utilities/cmcurl/lib/vtls/schannel.h b/Utilities/cmcurl/lib/vtls/schannel.h
new file mode 100644
index 000000000..532958483
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/schannel.h
@@ -0,0 +1,118 @@
+#ifndef HEADER_CURL_SCHANNEL_H
+#define HEADER_CURL_SCHANNEL_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012, Marc Hoersken, <info@marc-hoersken.de>, et al.
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef USE_SCHANNEL
+
+#include "urldata.h"
+
+#ifndef UNISP_NAME_A
+#define UNISP_NAME_A "Microsoft Unified Security Protocol Provider"
+#endif
+
+#ifndef UNISP_NAME_W
+#define UNISP_NAME_W L"Microsoft Unified Security Protocol Provider"
+#endif
+
+#ifndef UNISP_NAME
+#ifdef UNICODE
+#define UNISP_NAME UNISP_NAME_W
+#else
+#define UNISP_NAME UNISP_NAME_A
+#endif
+#endif
+
+#ifndef SP_PROT_SSL2_CLIENT
+#define SP_PROT_SSL2_CLIENT 0x00000008
+#endif
+
+#ifndef SP_PROT_SSL3_CLIENT
+#define SP_PROT_SSL3_CLIENT 0x00000008
+#endif
+
+#ifndef SP_PROT_TLS1_CLIENT
+#define SP_PROT_TLS1_CLIENT 0x00000080
+#endif
+
+#ifndef SP_PROT_TLS1_0_CLIENT
+#define SP_PROT_TLS1_0_CLIENT SP_PROT_TLS1_CLIENT
+#endif
+
+#ifndef SP_PROT_TLS1_1_CLIENT
+#define SP_PROT_TLS1_1_CLIENT 0x00000200
+#endif
+
+#ifndef SP_PROT_TLS1_2_CLIENT
+#define SP_PROT_TLS1_2_CLIENT 0x00000800
+#endif
+
+#ifndef SECBUFFER_ALERT
+#define SECBUFFER_ALERT 17
+#endif
+
+/* Both schannel buffer sizes must be > 0 */
+#define CURL_SCHANNEL_BUFFER_INIT_SIZE 4096
+#define CURL_SCHANNEL_BUFFER_FREE_SIZE 1024
+
+
+CURLcode Curl_schannel_connect(struct connectdata *conn, int sockindex);
+
+CURLcode Curl_schannel_connect_nonblocking(struct connectdata *conn,
+ int sockindex,
+ bool *done);
+
+bool Curl_schannel_data_pending(const struct connectdata *conn, int sockindex);
+void Curl_schannel_close(struct connectdata *conn, int sockindex);
+int Curl_schannel_shutdown(struct connectdata *conn, int sockindex);
+void Curl_schannel_session_free(void *ptr);
+
+int Curl_schannel_init(void);
+void Curl_schannel_cleanup(void);
+size_t Curl_schannel_version(char *buffer, size_t size);
+
+int Curl_schannel_random(unsigned char *entropy, size_t length);
+
+/* Set the API backend definition to Schannel */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_SCHANNEL
+
+/* API setup for Schannel */
+#define curlssl_init Curl_schannel_init
+#define curlssl_cleanup Curl_schannel_cleanup
+#define curlssl_connect Curl_schannel_connect
+#define curlssl_connect_nonblocking Curl_schannel_connect_nonblocking
+#define curlssl_session_free Curl_schannel_session_free
+#define curlssl_close_all(x) ((void)x)
+#define curlssl_close Curl_schannel_close
+#define curlssl_shutdown Curl_schannel_shutdown
+#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN)
+#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN)
+#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL)
+#define curlssl_version Curl_schannel_version
+#define curlssl_check_cxn(x) ((void)x, -1)
+#define curlssl_data_pending Curl_schannel_data_pending
+#define curlssl_random(x,y,z) ((void)x, Curl_schannel_random(y,z))
+
+#endif /* USE_SCHANNEL */
+#endif /* HEADER_CURL_SCHANNEL_H */
diff --git a/Utilities/cmcurl/lib/vtls/vtls.c b/Utilities/cmcurl/lib/vtls/vtls.c
new file mode 100644
index 000000000..01bbc6130
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/vtls.c
@@ -0,0 +1,962 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* This file is for implementing all "generic" SSL functions that all libcurl
+ internals should use. It is then responsible for calling the proper
+ "backend" function.
+
+ SSL-functions in libcurl should call functions in this source file, and not
+ to any specific SSL-layer.
+
+ Curl_ssl_ - prefix for generic ones
+ Curl_ossl_ - prefix for OpenSSL ones
+ Curl_gtls_ - prefix for GnuTLS ones
+ Curl_nss_ - prefix for NSS ones
+ Curl_gskit_ - prefix for GSKit ones
+ Curl_polarssl_ - prefix for PolarSSL ones
+ Curl_cyassl_ - prefix for CyaSSL ones
+ Curl_schannel_ - prefix for Schannel SSPI ones
+ Curl_darwinssl_ - prefix for SecureTransport (Darwin) ones
+
+ Note that this source code uses curlssl_* functions, and they are all
+ defines/macros #defined by the lib-specific header files.
+
+ "SSL/TLS Strong Encryption: An Introduction"
+ http://httpd.apache.org/docs-2.0/ssl/ssl_intro.html
+*/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#include "urldata.h"
+
+#include "vtls.h" /* generic SSL protos etc */
+#include "slist.h"
+#include "sendf.h"
+#include "rawstr.h"
+#include "url.h"
+#include "progress.h"
+#include "share.h"
+#include "timeval.h"
+#include "curl_md5.h"
+#include "warnless.h"
+#include "curl_base64.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* convenience macro to check if this handle is using a shared SSL session */
+#define SSLSESSION_SHARED(data) (data->share && \
+ (data->share->specifier & \
+ (1<<CURL_LOCK_DATA_SSL_SESSION)))
+
+static bool safe_strequal(char* str1, char* str2)
+{
+ if(str1 && str2)
+ /* both pointers point to something then compare them */
+ return (0 != Curl_raw_equal(str1, str2)) ? TRUE : FALSE;
+ else
+ /* if both pointers are NULL then treat them as equal */
+ return (!str1 && !str2) ? TRUE : FALSE;
+}
+
+bool
+Curl_ssl_config_matches(struct ssl_config_data* data,
+ struct ssl_config_data* needle)
+{
+ if((data->version == needle->version) &&
+ (data->verifypeer == needle->verifypeer) &&
+ (data->verifyhost == needle->verifyhost) &&
+ safe_strequal(data->CApath, needle->CApath) &&
+ safe_strequal(data->CAfile, needle->CAfile) &&
+ safe_strequal(data->random_file, needle->random_file) &&
+ safe_strequal(data->egdsocket, needle->egdsocket) &&
+ safe_strequal(data->cipher_list, needle->cipher_list))
+ return TRUE;
+
+ return FALSE;
+}
+
+bool
+Curl_clone_ssl_config(struct ssl_config_data *source,
+ struct ssl_config_data *dest)
+{
+ dest->sessionid = source->sessionid;
+ dest->verifyhost = source->verifyhost;
+ dest->verifypeer = source->verifypeer;
+ dest->version = source->version;
+
+ if(source->CAfile) {
+ dest->CAfile = strdup(source->CAfile);
+ if(!dest->CAfile)
+ return FALSE;
+ }
+ else
+ dest->CAfile = NULL;
+
+ if(source->CApath) {
+ dest->CApath = strdup(source->CApath);
+ if(!dest->CApath)
+ return FALSE;
+ }
+ else
+ dest->CApath = NULL;
+
+ if(source->cipher_list) {
+ dest->cipher_list = strdup(source->cipher_list);
+ if(!dest->cipher_list)
+ return FALSE;
+ }
+ else
+ dest->cipher_list = NULL;
+
+ if(source->egdsocket) {
+ dest->egdsocket = strdup(source->egdsocket);
+ if(!dest->egdsocket)
+ return FALSE;
+ }
+ else
+ dest->egdsocket = NULL;
+
+ if(source->random_file) {
+ dest->random_file = strdup(source->random_file);
+ if(!dest->random_file)
+ return FALSE;
+ }
+ else
+ dest->random_file = NULL;
+
+ return TRUE;
+}
+
+void Curl_free_ssl_config(struct ssl_config_data* sslc)
+{
+ Curl_safefree(sslc->CAfile);
+ Curl_safefree(sslc->CApath);
+ Curl_safefree(sslc->cipher_list);
+ Curl_safefree(sslc->egdsocket);
+ Curl_safefree(sslc->random_file);
+}
+
+
+/*
+ * Curl_rand() returns a random unsigned integer, 32bit.
+ *
+ * This non-SSL function is put here only because this file is the only one
+ * with knowledge of what the underlying SSL libraries provide in terms of
+ * randomizers.
+ *
+ * NOTE: 'data' may be passed in as NULL when coming from external API without
+ * easy handle!
+ *
+ */
+
+unsigned int Curl_rand(struct SessionHandle *data)
+{
+ unsigned int r = 0;
+ static unsigned int randseed;
+ static bool seeded = FALSE;
+
+#ifdef CURLDEBUG
+ char *force_entropy = getenv("CURL_ENTROPY");
+ if(force_entropy) {
+ if(!seeded) {
+ size_t elen = strlen(force_entropy);
+ size_t clen = sizeof(randseed);
+ size_t min = elen < clen ? elen : clen;
+ memcpy((char *)&randseed, force_entropy, min);
+ seeded = TRUE;
+ }
+ else
+ randseed++;
+ return randseed;
+ }
+#endif
+
+ /* data may be NULL! */
+ if(!Curl_ssl_random(data, (unsigned char *)&r, sizeof(r)))
+ return r;
+
+ /* If Curl_ssl_random() returns non-zero it couldn't offer randomness and we
+ instead perform a "best effort" */
+
+#ifdef RANDOM_FILE
+ if(!seeded) {
+ /* if there's a random file to read a seed from, use it */
+ int fd = open(RANDOM_FILE, O_RDONLY);
+ if(fd > -1) {
+ /* read random data into the randseed variable */
+ ssize_t nread = read(fd, &randseed, sizeof(randseed));
+ if(nread == sizeof(randseed))
+ seeded = TRUE;
+ close(fd);
+ }
+ }
+#endif
+
+ if(!seeded) {
+ struct timeval now = curlx_tvnow();
+ infof(data, "WARNING: Using weak random seed\n");
+ randseed += (unsigned int)now.tv_usec + (unsigned int)now.tv_sec;
+ randseed = randseed * 1103515245 + 12345;
+ randseed = randseed * 1103515245 + 12345;
+ randseed = randseed * 1103515245 + 12345;
+ seeded = TRUE;
+ }
+
+ /* Return an unsigned 32-bit pseudo-random number. */
+ r = randseed = randseed * 1103515245 + 12345;
+ return (r << 16) | ((r >> 16) & 0xFFFF);
+}
+
+int Curl_ssl_backend(void)
+{
+ return (int)CURL_SSL_BACKEND;
+}
+
+#ifdef USE_SSL
+
+/* "global" init done? */
+static bool init_ssl=FALSE;
+
+/**
+ * Global SSL init
+ *
+ * @retval 0 error initializing SSL
+ * @retval 1 SSL initialized successfully
+ */
+int Curl_ssl_init(void)
+{
+ /* make sure this is only done once */
+ if(init_ssl)
+ return 1;
+ init_ssl = TRUE; /* never again */
+
+ return curlssl_init();
+}
+
+
+/* Global cleanup */
+void Curl_ssl_cleanup(void)
+{
+ if(init_ssl) {
+ /* only cleanup if we did a previous init */
+ curlssl_cleanup();
+ init_ssl = FALSE;
+ }
+}
+
+static bool ssl_prefs_check(struct SessionHandle *data)
+{
+ /* check for CURLOPT_SSLVERSION invalid parameter value */
+ if((data->set.ssl.version < 0)
+ || (data->set.ssl.version >= CURL_SSLVERSION_LAST)) {
+ failf(data, "Unrecognized parameter value passed via CURLOPT_SSLVERSION");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+CURLcode
+Curl_ssl_connect(struct connectdata *conn, int sockindex)
+{
+ CURLcode result;
+
+ if(!ssl_prefs_check(conn->data))
+ return CURLE_SSL_CONNECT_ERROR;
+
+ /* mark this is being ssl-enabled from here on. */
+ conn->ssl[sockindex].use = TRUE;
+ conn->ssl[sockindex].state = ssl_connection_negotiating;
+
+ result = curlssl_connect(conn, sockindex);
+
+ if(!result)
+ Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSL is connected */
+
+ return result;
+}
+
+CURLcode
+Curl_ssl_connect_nonblocking(struct connectdata *conn, int sockindex,
+ bool *done)
+{
+ CURLcode result;
+
+ if(!ssl_prefs_check(conn->data))
+ return CURLE_SSL_CONNECT_ERROR;
+
+ /* mark this is being ssl requested from here on. */
+ conn->ssl[sockindex].use = TRUE;
+#ifdef curlssl_connect_nonblocking
+ result = curlssl_connect_nonblocking(conn, sockindex, done);
+#else
+ *done = TRUE; /* fallback to BLOCKING */
+ result = curlssl_connect(conn, sockindex);
+#endif /* non-blocking connect support */
+ if(!result && *done)
+ Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSL is connected */
+ return result;
+}
+
+/*
+ * Check if there's a session ID for the given connection in the cache, and if
+ * there's one suitable, it is provided. Returns TRUE when no entry matched.
+ */
+bool Curl_ssl_getsessionid(struct connectdata *conn,
+ void **ssl_sessionid,
+ size_t *idsize) /* set 0 if unknown */
+{
+ struct curl_ssl_session *check;
+ struct SessionHandle *data = conn->data;
+ size_t i;
+ long *general_age;
+ bool no_match = TRUE;
+
+ *ssl_sessionid = NULL;
+
+ if(!conn->ssl_config.sessionid)
+ /* session ID re-use is disabled */
+ return TRUE;
+
+ /* Lock if shared */
+ if(SSLSESSION_SHARED(data)) {
+ Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SINGLE);
+ general_age = &data->share->sessionage;
+ }
+ else
+ general_age = &data->state.sessionage;
+
+ for(i = 0; i < data->set.ssl.max_ssl_sessions; i++) {
+ check = &data->state.session[i];
+ if(!check->sessionid)
+ /* not session ID means blank entry */
+ continue;
+ if(Curl_raw_equal(conn->host.name, check->name) &&
+ (conn->remote_port == check->remote_port) &&
+ Curl_ssl_config_matches(&conn->ssl_config, &check->ssl_config)) {
+ /* yes, we have a session ID! */
+ (*general_age)++; /* increase general age */
+ check->age = *general_age; /* set this as used in this age */
+ *ssl_sessionid = check->sessionid;
+ if(idsize)
+ *idsize = check->idsize;
+ no_match = FALSE;
+ break;
+ }
+ }
+
+ /* Unlock */
+ if(SSLSESSION_SHARED(data))
+ Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION);
+
+ return no_match;
+}
+
+/*
+ * Kill a single session ID entry in the cache.
+ */
+void Curl_ssl_kill_session(struct curl_ssl_session *session)
+{
+ if(session->sessionid) {
+ /* defensive check */
+
+ /* free the ID the SSL-layer specific way */
+ curlssl_session_free(session->sessionid);
+
+ session->sessionid = NULL;
+ session->age = 0; /* fresh */
+
+ Curl_free_ssl_config(&session->ssl_config);
+
+ Curl_safefree(session->name);
+ }
+}
+
+/*
+ * Delete the given session ID from the cache.
+ */
+void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid)
+{
+ size_t i;
+ struct SessionHandle *data=conn->data;
+
+ if(SSLSESSION_SHARED(data))
+ Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SINGLE);
+
+ for(i = 0; i < data->set.ssl.max_ssl_sessions; i++) {
+ struct curl_ssl_session *check = &data->state.session[i];
+
+ if(check->sessionid == ssl_sessionid) {
+ Curl_ssl_kill_session(check);
+ break;
+ }
+ }
+
+ if(SSLSESSION_SHARED(data))
+ Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION);
+}
+
+/*
+ * Store session id in the session cache. The ID passed on to this function
+ * must already have been extracted and allocated the proper way for the SSL
+ * layer. Curl_XXXX_session_free() will be called to free/kill the session ID
+ * later on.
+ */
+CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
+ void *ssl_sessionid,
+ size_t idsize)
+{
+ size_t i;
+ struct SessionHandle *data=conn->data; /* the mother of all structs */
+ struct curl_ssl_session *store = &data->state.session[0];
+ long oldest_age=data->state.session[0].age; /* zero if unused */
+ char *clone_host;
+ long *general_age;
+
+ /* Even though session ID re-use might be disabled, that only disables USING
+ IT. We still store it here in case the re-using is again enabled for an
+ upcoming transfer */
+
+ clone_host = strdup(conn->host.name);
+ if(!clone_host)
+ return CURLE_OUT_OF_MEMORY; /* bail out */
+
+ /* Now we should add the session ID and the host name to the cache, (remove
+ the oldest if necessary) */
+
+ /* If using shared SSL session, lock! */
+ if(SSLSESSION_SHARED(data)) {
+ Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SINGLE);
+ general_age = &data->share->sessionage;
+ }
+ else {
+ general_age = &data->state.sessionage;
+ }
+
+ /* find an empty slot for us, or find the oldest */
+ for(i = 1; (i < data->set.ssl.max_ssl_sessions) &&
+ data->state.session[i].sessionid; i++) {
+ if(data->state.session[i].age < oldest_age) {
+ oldest_age = data->state.session[i].age;
+ store = &data->state.session[i];
+ }
+ }
+ if(i == data->set.ssl.max_ssl_sessions)
+ /* cache is full, we must "kill" the oldest entry! */
+ Curl_ssl_kill_session(store);
+ else
+ store = &data->state.session[i]; /* use this slot */
+
+ /* now init the session struct wisely */
+ store->sessionid = ssl_sessionid;
+ store->idsize = idsize;
+ store->age = *general_age; /* set current age */
+ /* free it if there's one already present */
+ free(store->name);
+ store->name = clone_host; /* clone host name */
+ store->remote_port = conn->remote_port; /* port number */
+
+
+ /* Unlock */
+ if(SSLSESSION_SHARED(data))
+ Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION);
+
+ if(!Curl_clone_ssl_config(&conn->ssl_config, &store->ssl_config)) {
+ store->sessionid = NULL; /* let caller free sessionid */
+ free(clone_host);
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ return CURLE_OK;
+}
+
+
+void Curl_ssl_close_all(struct SessionHandle *data)
+{
+ size_t i;
+ /* kill the session ID cache if not shared */
+ if(data->state.session && !SSLSESSION_SHARED(data)) {
+ for(i = 0; i < data->set.ssl.max_ssl_sessions; i++)
+ /* the single-killer function handles empty table slots */
+ Curl_ssl_kill_session(&data->state.session[i]);
+
+ /* free the cache data */
+ Curl_safefree(data->state.session);
+ }
+
+ curlssl_close_all(data);
+}
+
+void Curl_ssl_close(struct connectdata *conn, int sockindex)
+{
+ DEBUGASSERT((sockindex <= 1) && (sockindex >= -1));
+ curlssl_close(conn, sockindex);
+}
+
+CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex)
+{
+ if(curlssl_shutdown(conn, sockindex))
+ return CURLE_SSL_SHUTDOWN_FAILED;
+
+ conn->ssl[sockindex].use = FALSE; /* get back to ordinary socket usage */
+ conn->ssl[sockindex].state = ssl_connection_none;
+
+ conn->recv[sockindex] = Curl_recv_plain;
+ conn->send[sockindex] = Curl_send_plain;
+
+ return CURLE_OK;
+}
+
+/* Selects an SSL crypto engine
+ */
+CURLcode Curl_ssl_set_engine(struct SessionHandle *data, const char *engine)
+{
+ return curlssl_set_engine(data, engine);
+}
+
+/* Selects the default SSL crypto engine
+ */
+CURLcode Curl_ssl_set_engine_default(struct SessionHandle *data)
+{
+ return curlssl_set_engine_default(data);
+}
+
+/* Return list of OpenSSL crypto engine names. */
+struct curl_slist *Curl_ssl_engines_list(struct SessionHandle *data)
+{
+ return curlssl_engines_list(data);
+}
+
+/*
+ * This sets up a session ID cache to the specified size. Make sure this code
+ * is agnostic to what underlying SSL technology we use.
+ */
+CURLcode Curl_ssl_initsessions(struct SessionHandle *data, size_t amount)
+{
+ struct curl_ssl_session *session;
+
+ if(data->state.session)
+ /* this is just a precaution to prevent multiple inits */
+ return CURLE_OK;
+
+ session = calloc(amount, sizeof(struct curl_ssl_session));
+ if(!session)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* store the info in the SSL section */
+ data->set.ssl.max_ssl_sessions = amount;
+ data->state.session = session;
+ data->state.sessionage = 1; /* this is brand new */
+ return CURLE_OK;
+}
+
+size_t Curl_ssl_version(char *buffer, size_t size)
+{
+ return curlssl_version(buffer, size);
+}
+
+/*
+ * This function tries to determine connection status.
+ *
+ * Return codes:
+ * 1 means the connection is still in place
+ * 0 means the connection has been closed
+ * -1 means the connection status is unknown
+ */
+int Curl_ssl_check_cxn(struct connectdata *conn)
+{
+ return curlssl_check_cxn(conn);
+}
+
+bool Curl_ssl_data_pending(const struct connectdata *conn,
+ int connindex)
+{
+ return curlssl_data_pending(conn, connindex);
+}
+
+void Curl_ssl_free_certinfo(struct SessionHandle *data)
+{
+ int i;
+ struct curl_certinfo *ci = &data->info.certs;
+
+ if(ci->num_of_certs) {
+ /* free all individual lists used */
+ for(i=0; i<ci->num_of_certs; i++) {
+ curl_slist_free_all(ci->certinfo[i]);
+ ci->certinfo[i] = NULL;
+ }
+
+ free(ci->certinfo); /* free the actual array too */
+ ci->certinfo = NULL;
+ ci->num_of_certs = 0;
+ }
+}
+
+CURLcode Curl_ssl_init_certinfo(struct SessionHandle *data, int num)
+{
+ struct curl_certinfo *ci = &data->info.certs;
+ struct curl_slist **table;
+
+ /* Free any previous certificate information structures */
+ Curl_ssl_free_certinfo(data);
+
+ /* Allocate the required certificate information structures */
+ table = calloc((size_t) num, sizeof(struct curl_slist *));
+ if(!table)
+ return CURLE_OUT_OF_MEMORY;
+
+ ci->num_of_certs = num;
+ ci->certinfo = table;
+
+ return CURLE_OK;
+}
+
+/*
+ * 'value' is NOT a zero terminated string
+ */
+CURLcode Curl_ssl_push_certinfo_len(struct SessionHandle *data,
+ int certnum,
+ const char *label,
+ const char *value,
+ size_t valuelen)
+{
+ struct curl_certinfo * ci = &data->info.certs;
+ char * output;
+ struct curl_slist * nl;
+ CURLcode result = CURLE_OK;
+ size_t labellen = strlen(label);
+ size_t outlen = labellen + 1 + valuelen + 1; /* label:value\0 */
+
+ output = malloc(outlen);
+ if(!output)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* sprintf the label and colon */
+ snprintf(output, outlen, "%s:", label);
+
+ /* memcpy the value (it might not be zero terminated) */
+ memcpy(&output[labellen+1], value, valuelen);
+
+ /* zero terminate the output */
+ output[labellen + 1 + valuelen] = 0;
+
+ nl = Curl_slist_append_nodup(ci->certinfo[certnum], output);
+ if(!nl) {
+ free(output);
+ curl_slist_free_all(ci->certinfo[certnum]);
+ result = CURLE_OUT_OF_MEMORY;
+ }
+
+ ci->certinfo[certnum] = nl;
+ return result;
+}
+
+/*
+ * This is a convenience function for push_certinfo_len that takes a zero
+ * terminated value.
+ */
+CURLcode Curl_ssl_push_certinfo(struct SessionHandle *data,
+ int certnum,
+ const char *label,
+ const char *value)
+{
+ size_t valuelen = strlen(value);
+
+ return Curl_ssl_push_certinfo_len(data, certnum, label, value, valuelen);
+}
+
+int Curl_ssl_random(struct SessionHandle *data,
+ unsigned char *entropy,
+ size_t length)
+{
+ return curlssl_random(data, entropy, length);
+}
+
+/*
+ * Public key pem to der conversion
+ */
+
+static CURLcode pubkey_pem_to_der(const char *pem,
+ unsigned char **der, size_t *der_len)
+{
+ char *stripped_pem, *begin_pos, *end_pos;
+ size_t pem_count, stripped_pem_count = 0, pem_len;
+ CURLcode result;
+
+ /* if no pem, exit. */
+ if(!pem)
+ return CURLE_BAD_CONTENT_ENCODING;
+
+ begin_pos = strstr(pem, "-----BEGIN PUBLIC KEY-----");
+ if(!begin_pos)
+ return CURLE_BAD_CONTENT_ENCODING;
+
+ pem_count = begin_pos - pem;
+ /* Invalid if not at beginning AND not directly following \n */
+ if(0 != pem_count && '\n' != pem[pem_count - 1])
+ return CURLE_BAD_CONTENT_ENCODING;
+
+ /* 26 is length of "-----BEGIN PUBLIC KEY-----" */
+ pem_count += 26;
+
+ /* Invalid if not directly following \n */
+ end_pos = strstr(pem + pem_count, "\n-----END PUBLIC KEY-----");
+ if(!end_pos)
+ return CURLE_BAD_CONTENT_ENCODING;
+
+ pem_len = end_pos - pem;
+
+ stripped_pem = malloc(pem_len - pem_count + 1);
+ if(!stripped_pem)
+ return CURLE_OUT_OF_MEMORY;
+
+ /*
+ * Here we loop through the pem array one character at a time between the
+ * correct indices, and place each character that is not '\n' or '\r'
+ * into the stripped_pem array, which should represent the raw base64 string
+ */
+ while(pem_count < pem_len) {
+ if('\n' != pem[pem_count] && '\r' != pem[pem_count])
+ stripped_pem[stripped_pem_count++] = pem[pem_count];
+ ++pem_count;
+ }
+ /* Place the null terminator in the correct place */
+ stripped_pem[stripped_pem_count] = '\0';
+
+ result = Curl_base64_decode(stripped_pem, der, der_len);
+
+ Curl_safefree(stripped_pem);
+
+ return result;
+}
+
+/*
+ * Generic pinned public key check.
+ */
+
+CURLcode Curl_pin_peer_pubkey(const char *pinnedpubkey,
+ const unsigned char *pubkey, size_t pubkeylen)
+{
+ FILE *fp;
+ unsigned char *buf = NULL, *pem_ptr = NULL;
+ long filesize;
+ size_t size, pem_len;
+ CURLcode pem_read;
+ CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+#ifdef curlssl_sha256sum
+ size_t pinkeylen;
+ char *pinkeycopy, *begin_pos, *end_pos;
+ unsigned char *sha256sumdigest = NULL, *expectedsha256sumdigest = NULL;
+#endif
+
+ /* if a path wasn't specified, don't pin */
+ if(!pinnedpubkey)
+ return CURLE_OK;
+ if(!pubkey || !pubkeylen)
+ return result;
+
+#ifdef curlssl_sha256sum
+ /* only do this if pinnedpubkey starts with "sha256//", length 8 */
+ if(strncmp(pinnedpubkey, "sha256//", 8) == 0) {
+ /* compute sha256sum of public key */
+ sha256sumdigest = malloc(SHA256_DIGEST_LENGTH);
+ if(!sha256sumdigest)
+ return CURLE_OUT_OF_MEMORY;
+ curlssl_sha256sum(pubkey, pubkeylen,
+ sha256sumdigest, SHA256_DIGEST_LENGTH);
+
+ /* it starts with sha256//, copy so we can modify it */
+ pinkeylen = strlen(pinnedpubkey) + 1;
+ pinkeycopy = malloc(pinkeylen);
+ if(!pinkeycopy) {
+ Curl_safefree(sha256sumdigest);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ memcpy(pinkeycopy, pinnedpubkey, pinkeylen);
+ /* point begin_pos to the copy, and start extracting keys */
+ begin_pos = pinkeycopy;
+ do {
+ end_pos = strstr(begin_pos, ";sha256//");
+ /*
+ * if there is an end_pos, null terminate,
+ * otherwise it'll go to the end of the original string
+ */
+ if(end_pos)
+ end_pos[0] = '\0';
+
+ /* decode base64 pinnedpubkey, 8 is length of "sha256//" */
+ pem_read = Curl_base64_decode(begin_pos + 8,
+ &expectedsha256sumdigest, &size);
+ /* if not valid base64, don't bother comparing or freeing */
+ if(!pem_read) {
+ /* compare sha256 digests directly */
+ if(SHA256_DIGEST_LENGTH == size &&
+ !memcmp(sha256sumdigest, expectedsha256sumdigest,
+ SHA256_DIGEST_LENGTH)) {
+ result = CURLE_OK;
+ Curl_safefree(expectedsha256sumdigest);
+ break;
+ }
+ Curl_safefree(expectedsha256sumdigest);
+ }
+
+ /*
+ * change back the null-terminator we changed earlier,
+ * and look for next begin
+ */
+ if(end_pos) {
+ end_pos[0] = ';';
+ begin_pos = strstr(end_pos, "sha256//");
+ }
+ } while(end_pos && begin_pos);
+ Curl_safefree(sha256sumdigest);
+ Curl_safefree(pinkeycopy);
+ return result;
+ }
+#endif
+
+ fp = fopen(pinnedpubkey, "rb");
+ if(!fp)
+ return result;
+
+ do {
+ /* Determine the file's size */
+ if(fseek(fp, 0, SEEK_END))
+ break;
+ filesize = ftell(fp);
+ if(fseek(fp, 0, SEEK_SET))
+ break;
+ if(filesize < 0 || filesize > MAX_PINNED_PUBKEY_SIZE)
+ break;
+
+ /*
+ * if the size of our certificate is bigger than the file
+ * size then it can't match
+ */
+ size = curlx_sotouz((curl_off_t) filesize);
+ if(pubkeylen > size)
+ break;
+
+ /*
+ * Allocate buffer for the pinned key
+ * With 1 additional byte for null terminator in case of PEM key
+ */
+ buf = malloc(size + 1);
+ if(!buf)
+ break;
+
+ /* Returns number of elements read, which should be 1 */
+ if((int) fread(buf, size, 1, fp) != 1)
+ break;
+
+ /* If the sizes are the same, it can't be base64 encoded, must be der */
+ if(pubkeylen == size) {
+ if(!memcmp(pubkey, buf, pubkeylen))
+ result = CURLE_OK;
+ break;
+ }
+
+ /*
+ * Otherwise we will assume it's PEM and try to decode it
+ * after placing null terminator
+ */
+ buf[size] = '\0';
+ pem_read = pubkey_pem_to_der((const char *)buf, &pem_ptr, &pem_len);
+ /* if it wasn't read successfully, exit */
+ if(pem_read)
+ break;
+
+ /*
+ * if the size of our certificate doesn't match the size of
+ * the decoded file, they can't be the same, otherwise compare
+ */
+ if(pubkeylen == pem_len && !memcmp(pubkey, pem_ptr, pubkeylen))
+ result = CURLE_OK;
+ } while(0);
+
+ Curl_safefree(buf);
+ Curl_safefree(pem_ptr);
+ fclose(fp);
+
+ return result;
+}
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+CURLcode Curl_ssl_md5sum(unsigned char *tmp, /* input */
+ size_t tmplen,
+ unsigned char *md5sum, /* output */
+ size_t md5len)
+{
+#ifdef curlssl_md5sum
+ curlssl_md5sum(tmp, tmplen, md5sum, md5len);
+#else
+ MD5_context *MD5pw;
+
+ (void) md5len;
+
+ MD5pw = Curl_MD5_init(Curl_DIGEST_MD5);
+ if(!MD5pw)
+ return CURLE_OUT_OF_MEMORY;
+ Curl_MD5_update(MD5pw, tmp, curlx_uztoui(tmplen));
+ Curl_MD5_final(MD5pw, md5sum);
+#endif
+ return CURLE_OK;
+}
+#endif
+
+/*
+ * Check whether the SSL backend supports the status_request extension.
+ */
+bool Curl_ssl_cert_status_request(void)
+{
+#ifdef curlssl_cert_status_request
+ return curlssl_cert_status_request();
+#else
+ return FALSE;
+#endif
+}
+
+/*
+ * Check whether the SSL backend supports false start.
+ */
+bool Curl_ssl_false_start(void)
+{
+#ifdef curlssl_false_start
+ return curlssl_false_start();
+#else
+ return FALSE;
+#endif
+}
+
+#endif /* USE_SSL */
diff --git a/Utilities/cmcurl/lib/vtls/vtls.h b/Utilities/cmcurl/lib/vtls/vtls.h
new file mode 100644
index 000000000..2349e5b93
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/vtls.h
@@ -0,0 +1,157 @@
+#ifndef HEADER_CURL_VTLS_H
+#define HEADER_CURL_VTLS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#include "openssl.h" /* OpenSSL versions */
+#include "gtls.h" /* GnuTLS versions */
+#include "nssg.h" /* NSS versions */
+#include "gskit.h" /* Global Secure ToolKit versions */
+#include "polarssl.h" /* PolarSSL versions */
+#include "axtls.h" /* axTLS versions */
+#include "cyassl.h" /* CyaSSL versions */
+#include "schannel.h" /* Schannel SSPI version */
+#include "darwinssl.h" /* SecureTransport (Darwin) version */
+
+#ifndef MAX_PINNED_PUBKEY_SIZE
+#define MAX_PINNED_PUBKEY_SIZE 1048576 /* 1MB */
+#endif
+
+#ifndef MD5_DIGEST_LENGTH
+#define MD5_DIGEST_LENGTH 16 /* fixed size */
+#endif
+
+#ifndef SHA256_DIGEST_LENGTH
+#define SHA256_DIGEST_LENGTH 32 /* fixed size */
+#endif
+
+/* see http://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg-04 */
+#define ALPN_HTTP_1_1_LENGTH 8
+#define ALPN_HTTP_1_1 "http/1.1"
+
+bool Curl_ssl_config_matches(struct ssl_config_data* data,
+ struct ssl_config_data* needle);
+bool Curl_clone_ssl_config(struct ssl_config_data* source,
+ struct ssl_config_data* dest);
+void Curl_free_ssl_config(struct ssl_config_data* sslc);
+
+unsigned int Curl_rand(struct SessionHandle *);
+
+int Curl_ssl_backend(void);
+
+#ifdef USE_SSL
+int Curl_ssl_init(void);
+void Curl_ssl_cleanup(void);
+CURLcode Curl_ssl_connect(struct connectdata *conn, int sockindex);
+CURLcode Curl_ssl_connect_nonblocking(struct connectdata *conn,
+ int sockindex,
+ bool *done);
+/* tell the SSL stuff to close down all open information regarding
+ connections (and thus session ID caching etc) */
+void Curl_ssl_close_all(struct SessionHandle *data);
+void Curl_ssl_close(struct connectdata *conn, int sockindex);
+CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex);
+CURLcode Curl_ssl_set_engine(struct SessionHandle *data, const char *engine);
+/* Sets engine as default for all SSL operations */
+CURLcode Curl_ssl_set_engine_default(struct SessionHandle *data);
+struct curl_slist *Curl_ssl_engines_list(struct SessionHandle *data);
+
+/* init the SSL session ID cache */
+CURLcode Curl_ssl_initsessions(struct SessionHandle *, size_t);
+size_t Curl_ssl_version(char *buffer, size_t size);
+bool Curl_ssl_data_pending(const struct connectdata *conn,
+ int connindex);
+int Curl_ssl_check_cxn(struct connectdata *conn);
+
+/* Certificate information list handling. */
+
+void Curl_ssl_free_certinfo(struct SessionHandle *data);
+CURLcode Curl_ssl_init_certinfo(struct SessionHandle * data, int num);
+CURLcode Curl_ssl_push_certinfo_len(struct SessionHandle * data, int certnum,
+ const char * label, const char * value,
+ size_t valuelen);
+CURLcode Curl_ssl_push_certinfo(struct SessionHandle * data, int certnum,
+ const char * label, const char * value);
+
+/* Functions to be used by SSL library adaptation functions */
+
+/* extract a session ID */
+bool Curl_ssl_getsessionid(struct connectdata *conn,
+ void **ssl_sessionid,
+ size_t *idsize) /* set 0 if unknown */;
+/* add a new session ID */
+CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
+ void *ssl_sessionid,
+ size_t idsize);
+/* Kill a single session ID entry in the cache */
+void Curl_ssl_kill_session(struct curl_ssl_session *session);
+/* delete a session from the cache */
+void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid);
+
+/* get N random bytes into the buffer, return 0 if a find random is filled
+ in */
+int Curl_ssl_random(struct SessionHandle *data, unsigned char *buffer,
+ size_t length);
+CURLcode Curl_ssl_md5sum(unsigned char *tmp, /* input */
+ size_t tmplen,
+ unsigned char *md5sum, /* output */
+ size_t md5len);
+/* Check pinned public key. */
+CURLcode Curl_pin_peer_pubkey(const char *pinnedpubkey,
+ const unsigned char *pubkey, size_t pubkeylen);
+
+bool Curl_ssl_cert_status_request(void);
+
+bool Curl_ssl_false_start(void);
+
+#define SSL_SHUTDOWN_TIMEOUT 10000 /* ms */
+
+#else
+/* Set the API backend definition to none */
+#define CURL_SSL_BACKEND CURLSSLBACKEND_NONE
+
+/* When SSL support is not present, just define away these function calls */
+#define Curl_ssl_init() 1
+#define Curl_ssl_cleanup() Curl_nop_stmt
+#define Curl_ssl_connect(x,y) CURLE_NOT_BUILT_IN
+#define Curl_ssl_close_all(x) Curl_nop_stmt
+#define Curl_ssl_close(x,y) Curl_nop_stmt
+#define Curl_ssl_shutdown(x,y) CURLE_NOT_BUILT_IN
+#define Curl_ssl_set_engine(x,y) CURLE_NOT_BUILT_IN
+#define Curl_ssl_set_engine_default(x) CURLE_NOT_BUILT_IN
+#define Curl_ssl_engines_list(x) NULL
+#define Curl_ssl_send(a,b,c,d,e) -1
+#define Curl_ssl_recv(a,b,c,d,e) -1
+#define Curl_ssl_initsessions(x,y) CURLE_OK
+#define Curl_ssl_version(x,y) 0
+#define Curl_ssl_data_pending(x,y) 0
+#define Curl_ssl_check_cxn(x) 0
+#define Curl_ssl_free_certinfo(x) Curl_nop_stmt
+#define Curl_ssl_connect_nonblocking(x,y,z) CURLE_NOT_BUILT_IN
+#define Curl_ssl_kill_session(x) Curl_nop_stmt
+#define Curl_ssl_random(x,y,z) ((void)x, CURLE_NOT_BUILT_IN)
+#define Curl_ssl_cert_status_request() FALSE
+#define Curl_ssl_false_start() FALSE
+#endif
+
+#endif /* HEADER_CURL_VTLS_H */
diff --git a/Utilities/cmcurl/lib/warnless.c b/Utilities/cmcurl/lib/warnless.c
new file mode 100644
index 000000000..8c130d34c
--- /dev/null
+++ b/Utilities/cmcurl/lib/warnless.c
@@ -0,0 +1,486 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(__INTEL_COMPILER) && defined(__unix__)
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+
+#endif /* __INTEL_COMPILER && __unix__ */
+
+#define BUILDING_WARNLESS_C 1
+
+#include "warnless.h"
+
+#define CURL_MASK_SCHAR 0x7F
+#define CURL_MASK_UCHAR 0xFF
+
+#if (SIZEOF_SHORT == 2)
+# define CURL_MASK_SSHORT 0x7FFF
+# define CURL_MASK_USHORT 0xFFFF
+#elif (SIZEOF_SHORT == 4)
+# define CURL_MASK_SSHORT 0x7FFFFFFF
+# define CURL_MASK_USHORT 0xFFFFFFFF
+#elif (SIZEOF_SHORT == 8)
+# define CURL_MASK_SSHORT 0x7FFFFFFFFFFFFFFF
+# define CURL_MASK_USHORT 0xFFFFFFFFFFFFFFFF
+#else
+# error "SIZEOF_SHORT not defined"
+#endif
+
+#if (SIZEOF_INT == 2)
+# define CURL_MASK_SINT 0x7FFF
+# define CURL_MASK_UINT 0xFFFF
+#elif (SIZEOF_INT == 4)
+# define CURL_MASK_SINT 0x7FFFFFFF
+# define CURL_MASK_UINT 0xFFFFFFFF
+#elif (SIZEOF_INT == 8)
+# define CURL_MASK_SINT 0x7FFFFFFFFFFFFFFF
+# define CURL_MASK_UINT 0xFFFFFFFFFFFFFFFF
+#elif (SIZEOF_INT == 16)
+# define CURL_MASK_SINT 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+# define CURL_MASK_UINT 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+#else
+# error "SIZEOF_INT not defined"
+#endif
+
+#if (CURL_SIZEOF_LONG == 2)
+# define CURL_MASK_SLONG 0x7FFFL
+# define CURL_MASK_ULONG 0xFFFFUL
+#elif (CURL_SIZEOF_LONG == 4)
+# define CURL_MASK_SLONG 0x7FFFFFFFL
+# define CURL_MASK_ULONG 0xFFFFFFFFUL
+#elif (CURL_SIZEOF_LONG == 8)
+# define CURL_MASK_SLONG 0x7FFFFFFFFFFFFFFFL
+# define CURL_MASK_ULONG 0xFFFFFFFFFFFFFFFFUL
+#elif (CURL_SIZEOF_LONG == 16)
+# define CURL_MASK_SLONG 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFL
+# define CURL_MASK_ULONG 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFUL
+#else
+# error "CURL_SIZEOF_LONG not defined"
+#endif
+
+#if (CURL_SIZEOF_CURL_OFF_T == 2)
+# define CURL_MASK_SCOFFT CURL_OFF_T_C(0x7FFF)
+# define CURL_MASK_UCOFFT CURL_OFF_TU_C(0xFFFF)
+#elif (CURL_SIZEOF_CURL_OFF_T == 4)
+# define CURL_MASK_SCOFFT CURL_OFF_T_C(0x7FFFFFFF)
+# define CURL_MASK_UCOFFT CURL_OFF_TU_C(0xFFFFFFFF)
+#elif (CURL_SIZEOF_CURL_OFF_T == 8)
+# define CURL_MASK_SCOFFT CURL_OFF_T_C(0x7FFFFFFFFFFFFFFF)
+# define CURL_MASK_UCOFFT CURL_OFF_TU_C(0xFFFFFFFFFFFFFFFF)
+#elif (CURL_SIZEOF_CURL_OFF_T == 16)
+# define CURL_MASK_SCOFFT CURL_OFF_T_C(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
+# define CURL_MASK_UCOFFT CURL_OFF_TU_C(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
+#else
+# error "CURL_SIZEOF_CURL_OFF_T not defined"
+#endif
+
+#if (SIZEOF_SIZE_T == SIZEOF_SHORT)
+# define CURL_MASK_SSIZE_T CURL_MASK_SSHORT
+# define CURL_MASK_USIZE_T CURL_MASK_USHORT
+#elif (SIZEOF_SIZE_T == SIZEOF_INT)
+# define CURL_MASK_SSIZE_T CURL_MASK_SINT
+# define CURL_MASK_USIZE_T CURL_MASK_UINT
+#elif (SIZEOF_SIZE_T == CURL_SIZEOF_LONG)
+# define CURL_MASK_SSIZE_T CURL_MASK_SLONG
+# define CURL_MASK_USIZE_T CURL_MASK_ULONG
+#elif (SIZEOF_SIZE_T == CURL_SIZEOF_CURL_OFF_T)
+# define CURL_MASK_SSIZE_T CURL_MASK_SCOFFT
+# define CURL_MASK_USIZE_T CURL_MASK_UCOFFT
+#else
+# error "SIZEOF_SIZE_T not defined"
+#endif
+
+/*
+** unsigned long to unsigned short
+*/
+
+unsigned short curlx_ultous(unsigned long ulnum)
+{
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+ DEBUGASSERT(ulnum <= (unsigned long) CURL_MASK_USHORT);
+ return (unsigned short)(ulnum & (unsigned long) CURL_MASK_USHORT);
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+}
+
+/*
+** unsigned long to unsigned char
+*/
+
+unsigned char curlx_ultouc(unsigned long ulnum)
+{
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+ DEBUGASSERT(ulnum <= (unsigned long) CURL_MASK_UCHAR);
+ return (unsigned char)(ulnum & (unsigned long) CURL_MASK_UCHAR);
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+}
+
+/*
+** unsigned long to signed int
+*/
+
+int curlx_ultosi(unsigned long ulnum)
+{
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+ DEBUGASSERT(ulnum <= (unsigned long) CURL_MASK_SINT);
+ return (int)(ulnum & (unsigned long) CURL_MASK_SINT);
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+}
+
+/*
+** unsigned size_t to signed curl_off_t
+*/
+
+curl_off_t curlx_uztoso(size_t uznum)
+{
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+ DEBUGASSERT(uznum <= (size_t) CURL_MASK_SCOFFT);
+ return (curl_off_t)(uznum & (size_t) CURL_MASK_SCOFFT);
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+}
+
+/*
+** unsigned size_t to signed int
+*/
+
+int curlx_uztosi(size_t uznum)
+{
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+ DEBUGASSERT(uznum <= (size_t) CURL_MASK_SINT);
+ return (int)(uznum & (size_t) CURL_MASK_SINT);
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+}
+
+/*
+** unsigned size_t to unsigned long
+*/
+
+unsigned long curlx_uztoul(size_t uznum)
+{
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+#if (CURL_SIZEOF_LONG < SIZEOF_SIZE_T)
+ DEBUGASSERT(uznum <= (size_t) CURL_MASK_ULONG);
+#endif
+ return (unsigned long)(uznum & (size_t) CURL_MASK_ULONG);
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+}
+
+/*
+** unsigned size_t to unsigned int
+*/
+
+unsigned int curlx_uztoui(size_t uznum)
+{
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+#if (SIZEOF_INT < SIZEOF_SIZE_T)
+ DEBUGASSERT(uznum <= (size_t) CURL_MASK_UINT);
+#endif
+ return (unsigned int)(uznum & (size_t) CURL_MASK_UINT);
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+}
+
+/*
+** signed long to signed int
+*/
+
+int curlx_sltosi(long slnum)
+{
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+ DEBUGASSERT(slnum >= 0);
+#if (SIZEOF_INT < CURL_SIZEOF_LONG)
+ DEBUGASSERT((unsigned long) slnum <= (unsigned long) CURL_MASK_SINT);
+#endif
+ return (int)(slnum & (long) CURL_MASK_SINT);
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+}
+
+/*
+** signed long to unsigned int
+*/
+
+unsigned int curlx_sltoui(long slnum)
+{
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+ DEBUGASSERT(slnum >= 0);
+#if (SIZEOF_INT < CURL_SIZEOF_LONG)
+ DEBUGASSERT((unsigned long) slnum <= (unsigned long) CURL_MASK_UINT);
+#endif
+ return (unsigned int)(slnum & (long) CURL_MASK_UINT);
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+}
+
+/*
+** signed long to unsigned short
+*/
+
+unsigned short curlx_sltous(long slnum)
+{
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+ DEBUGASSERT(slnum >= 0);
+ DEBUGASSERT((unsigned long) slnum <= (unsigned long) CURL_MASK_USHORT);
+ return (unsigned short)(slnum & (long) CURL_MASK_USHORT);
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+}
+
+/*
+** unsigned size_t to signed ssize_t
+*/
+
+ssize_t curlx_uztosz(size_t uznum)
+{
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+ DEBUGASSERT(uznum <= (size_t) CURL_MASK_SSIZE_T);
+ return (ssize_t)(uznum & (size_t) CURL_MASK_SSIZE_T);
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+}
+
+/*
+** signed curl_off_t to unsigned size_t
+*/
+
+size_t curlx_sotouz(curl_off_t sonum)
+{
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+ DEBUGASSERT(sonum >= 0);
+ return (size_t)(sonum & (curl_off_t) CURL_MASK_USIZE_T);
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+}
+
+/*
+** signed ssize_t to signed int
+*/
+
+int curlx_sztosi(ssize_t sznum)
+{
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+ DEBUGASSERT(sznum >= 0);
+#if (SIZEOF_INT < SIZEOF_SIZE_T)
+ DEBUGASSERT((size_t) sznum <= (size_t) CURL_MASK_SINT);
+#endif
+ return (int)(sznum & (ssize_t) CURL_MASK_SINT);
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+}
+
+/*
+** signed int to unsigned size_t
+*/
+
+size_t curlx_sitouz(int sinum)
+{
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+ DEBUGASSERT(sinum >= 0);
+ return (size_t) sinum;
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+}
+
+#ifdef USE_WINSOCK
+
+/*
+** curl_socket_t to signed int
+*/
+
+int curlx_sktosi(curl_socket_t s)
+{
+ return (int)((ssize_t) s);
+}
+
+/*
+** signed int to curl_socket_t
+*/
+
+curl_socket_t curlx_sitosk(int i)
+{
+ return (curl_socket_t)((ssize_t) i);
+}
+
+#endif /* USE_WINSOCK */
+
+#if defined(WIN32) || defined(_WIN32)
+
+ssize_t curlx_read(int fd, void *buf, size_t count)
+{
+ return (ssize_t)read(fd, buf, curlx_uztoui(count));
+}
+
+ssize_t curlx_write(int fd, const void *buf, size_t count)
+{
+ return (ssize_t)write(fd, buf, curlx_uztoui(count));
+}
+
+#endif /* WIN32 || _WIN32 */
+
+#if defined(__INTEL_COMPILER) && defined(__unix__)
+
+int curlx_FD_ISSET(int fd, fd_set *fdset)
+{
+ #pragma warning(push)
+ #pragma warning(disable:1469) /* clobber ignored */
+ return FD_ISSET(fd, fdset);
+ #pragma warning(pop)
+}
+
+void curlx_FD_SET(int fd, fd_set *fdset)
+{
+ #pragma warning(push)
+ #pragma warning(disable:1469) /* clobber ignored */
+ FD_SET(fd, fdset);
+ #pragma warning(pop)
+}
+
+void curlx_FD_ZERO(fd_set *fdset)
+{
+ #pragma warning(push)
+ #pragma warning(disable:593) /* variable was set but never used */
+ FD_ZERO(fdset);
+ #pragma warning(pop)
+}
+
+unsigned short curlx_htons(unsigned short usnum)
+{
+#if (__INTEL_COMPILER == 910) && defined(__i386__)
+ return (unsigned short)(((usnum << 8) & 0xFF00) | ((usnum >> 8) & 0x00FF));
+#else
+ #pragma warning(push)
+ #pragma warning(disable:810) /* conversion may lose significant bits */
+ return htons(usnum);
+ #pragma warning(pop)
+#endif
+}
+
+unsigned short curlx_ntohs(unsigned short usnum)
+{
+#if (__INTEL_COMPILER == 910) && defined(__i386__)
+ return (unsigned short)(((usnum << 8) & 0xFF00) | ((usnum >> 8) & 0x00FF));
+#else
+ #pragma warning(push)
+ #pragma warning(disable:810) /* conversion may lose significant bits */
+ return ntohs(usnum);
+ #pragma warning(pop)
+#endif
+}
+
+#endif /* __INTEL_COMPILER && __unix__ */
diff --git a/Utilities/cmcurl/lib/warnless.h b/Utilities/cmcurl/lib/warnless.h
new file mode 100644
index 000000000..ad77d3c20
--- /dev/null
+++ b/Utilities/cmcurl/lib/warnless.h
@@ -0,0 +1,107 @@
+#ifndef HEADER_CURL_WARNLESS_H
+#define HEADER_CURL_WARNLESS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifdef USE_WINSOCK
+#include <curl/curl.h> /* for curl_socket_t */
+#endif
+
+unsigned short curlx_ultous(unsigned long ulnum);
+
+unsigned char curlx_ultouc(unsigned long ulnum);
+
+int curlx_ultosi(unsigned long ulnum);
+
+int curlx_uztosi(size_t uznum);
+
+curl_off_t curlx_uztoso(size_t uznum);
+
+unsigned long curlx_uztoul(size_t uznum);
+
+unsigned int curlx_uztoui(size_t uznum);
+
+int curlx_sltosi(long slnum);
+
+unsigned int curlx_sltoui(long slnum);
+
+unsigned short curlx_sltous(long slnum);
+
+ssize_t curlx_uztosz(size_t uznum);
+
+size_t curlx_sotouz(curl_off_t sonum);
+
+int curlx_sztosi(ssize_t sznum);
+
+size_t curlx_sitouz(int sinum);
+
+#ifdef USE_WINSOCK
+
+int curlx_sktosi(curl_socket_t s);
+
+curl_socket_t curlx_sitosk(int i);
+
+#endif /* USE_WINSOCK */
+
+#if defined(WIN32) || defined(_WIN32)
+
+ssize_t curlx_read(int fd, void *buf, size_t count);
+
+ssize_t curlx_write(int fd, const void *buf, size_t count);
+
+#ifndef BUILDING_WARNLESS_C
+# undef read
+# define read(fd, buf, count) curlx_read(fd, buf, count)
+# undef write
+# define write(fd, buf, count) curlx_write(fd, buf, count)
+#endif
+
+#endif /* WIN32 || _WIN32 */
+
+#if defined(__INTEL_COMPILER) && defined(__unix__)
+
+int curlx_FD_ISSET(int fd, fd_set *fdset);
+
+void curlx_FD_SET(int fd, fd_set *fdset);
+
+void curlx_FD_ZERO(fd_set *fdset);
+
+unsigned short curlx_htons(unsigned short usnum);
+
+unsigned short curlx_ntohs(unsigned short usnum);
+
+#ifndef BUILDING_WARNLESS_C
+# undef FD_ISSET
+# define FD_ISSET(a,b) curlx_FD_ISSET((a),(b))
+# undef FD_SET
+# define FD_SET(a,b) curlx_FD_SET((a),(b))
+# undef FD_ZERO
+# define FD_ZERO(a) curlx_FD_ZERO((a))
+# undef htons
+# define htons(a) curlx_htons((a))
+# undef ntohs
+# define ntohs(a) curlx_ntohs((a))
+#endif
+
+#endif /* __INTEL_COMPILER && __unix__ */
+
+#endif /* HEADER_CURL_WARNLESS_H */
diff --git a/Utilities/cmcurl/lib/wildcard.c b/Utilities/cmcurl/lib/wildcard.c
new file mode 100644
index 000000000..6f55839db
--- /dev/null
+++ b/Utilities/cmcurl/lib/wildcard.c
@@ -0,0 +1,69 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "wildcard.h"
+#include "llist.h"
+#include "fileinfo.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+CURLcode Curl_wildcard_init(struct WildcardData *wc)
+{
+ DEBUGASSERT(wc->filelist == NULL);
+ /* now allocate only wc->filelist, everything else
+ will be allocated if it is needed. */
+ wc->filelist = Curl_llist_alloc(Curl_fileinfo_dtor);
+ if(!wc->filelist) {;
+ return CURLE_OUT_OF_MEMORY;
+ }
+ return CURLE_OK;
+}
+
+void Curl_wildcard_dtor(struct WildcardData *wc)
+{
+ if(!wc)
+ return;
+
+ if(wc->tmp_dtor) {
+ wc->tmp_dtor(wc->tmp);
+ wc->tmp_dtor = ZERO_NULL;
+ wc->tmp = NULL;
+ }
+ DEBUGASSERT(wc->tmp == NULL);
+
+ if(wc->filelist) {
+ Curl_llist_destroy(wc->filelist, NULL);
+ wc->filelist = NULL;
+ }
+
+ free(wc->path);
+ wc->path = NULL;
+ free(wc->pattern);
+ wc->pattern = NULL;
+
+ wc->customptr = NULL;
+ wc->state = CURLWC_INIT;
+}
diff --git a/Utilities/cmcurl/lib/wildcard.h b/Utilities/cmcurl/lib/wildcard.h
new file mode 100644
index 000000000..16c80ecbe
--- /dev/null
+++ b/Utilities/cmcurl/lib/wildcard.h
@@ -0,0 +1,58 @@
+#ifndef HEADER_CURL_WILDCARD_H
+#define HEADER_CURL_WILDCARD_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2010 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <curl/curl.h>
+
+/* list of wildcard process states */
+typedef enum {
+ CURLWC_INIT = 0,
+ CURLWC_MATCHING, /* library is trying to get list of addresses for
+ downloading */
+ CURLWC_DOWNLOADING,
+ CURLWC_CLEAN, /* deallocate resources and reset settings */
+ CURLWC_SKIP, /* skip over concrete file */
+ CURLWC_ERROR, /* error cases */
+ CURLWC_DONE /* if is wildcard->state == CURLWC_DONE wildcard loop
+ will end */
+} curl_wildcard_states;
+
+typedef void (*curl_wildcard_tmp_dtor)(void *ptr);
+
+/* struct keeping information about wildcard download process */
+struct WildcardData {
+ curl_wildcard_states state;
+ char *path; /* path to the directory, where we trying wildcard-match */
+ char *pattern; /* wildcard pattern */
+ struct curl_llist *filelist; /* llist with struct Curl_fileinfo */
+ void *tmp; /* pointer to protocol specific temporary data */
+ curl_wildcard_tmp_dtor tmp_dtor;
+ void *customptr; /* for CURLOPT_CHUNK_DATA pointer */
+};
+
+CURLcode Curl_wildcard_init(struct WildcardData *wc);
+void Curl_wildcard_dtor(struct WildcardData *wc);
+
+struct SessionHandle;
+
+#endif /* HEADER_CURL_WILDCARD_H */
diff --git a/Utilities/cmcurl/lib/x509asn1.c b/Utilities/cmcurl/lib/x509asn1.c
new file mode 100644
index 000000000..a3dfd646b
--- /dev/null
+++ b/Utilities/cmcurl/lib/x509asn1.c
@@ -0,0 +1,1188 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \
+ defined(USE_CYASSL)
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "strequal.h"
+#include "hostcheck.h"
+#include "vtls/vtls.h"
+#include "sendf.h"
+#include "inet_pton.h"
+#include "curl_base64.h"
+#include "x509asn1.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+
+/* ASN.1 OIDs. */
+static const char cnOID[] = "2.5.4.3"; /* Common name. */
+static const char sanOID[] = "2.5.29.17"; /* Subject alternative name. */
+
+static const curl_OID OIDtable[] = {
+ { "1.2.840.10040.4.1", "dsa" },
+ { "1.2.840.10040.4.3", "dsa-with-sha1" },
+ { "1.2.840.10045.2.1", "ecPublicKey" },
+ { "1.2.840.10045.3.0.1", "c2pnb163v1" },
+ { "1.2.840.10045.4.1", "ecdsa-with-SHA1" },
+ { "1.2.840.10046.2.1", "dhpublicnumber" },
+ { "1.2.840.113549.1.1.1", "rsaEncryption" },
+ { "1.2.840.113549.1.1.2", "md2WithRSAEncryption" },
+ { "1.2.840.113549.1.1.4", "md5WithRSAEncryption" },
+ { "1.2.840.113549.1.1.5", "sha1WithRSAEncryption" },
+ { "1.2.840.113549.1.1.10", "RSASSA-PSS" },
+ { "1.2.840.113549.1.1.14", "sha224WithRSAEncryption" },
+ { "1.2.840.113549.1.1.11", "sha256WithRSAEncryption" },
+ { "1.2.840.113549.1.1.12", "sha384WithRSAEncryption" },
+ { "1.2.840.113549.1.1.13", "sha512WithRSAEncryption" },
+ { "1.2.840.113549.2.2", "md2" },
+ { "1.2.840.113549.2.5", "md5" },
+ { "1.3.14.3.2.26", "sha1" },
+ { cnOID, "CN" },
+ { "2.5.4.4", "SN" },
+ { "2.5.4.5", "serialNumber" },
+ { "2.5.4.6", "C" },
+ { "2.5.4.7", "L" },
+ { "2.5.4.8", "ST" },
+ { "2.5.4.9", "streetAddress" },
+ { "2.5.4.10", "O" },
+ { "2.5.4.11", "OU" },
+ { "2.5.4.12", "title" },
+ { "2.5.4.13", "description" },
+ { "2.5.4.17", "postalCode" },
+ { "2.5.4.41", "name" },
+ { "2.5.4.42", "givenName" },
+ { "2.5.4.43", "initials" },
+ { "2.5.4.44", "generationQualifier" },
+ { "2.5.4.45", "X500UniqueIdentifier" },
+ { "2.5.4.46", "dnQualifier" },
+ { "2.5.4.65", "pseudonym" },
+ { "1.2.840.113549.1.9.1", "emailAddress" },
+ { "2.5.4.72", "role" },
+ { sanOID, "subjectAltName" },
+ { "2.5.29.18", "issuerAltName" },
+ { "2.5.29.19", "basicConstraints" },
+ { "2.16.840.1.101.3.4.2.4", "sha224" },
+ { "2.16.840.1.101.3.4.2.1", "sha256" },
+ { "2.16.840.1.101.3.4.2.2", "sha384" },
+ { "2.16.840.1.101.3.4.2.3", "sha512" },
+ { (const char *) NULL, (const char *) NULL }
+};
+
+/*
+ * Lightweight ASN.1 parser.
+ * In particular, it does not check for syntactic/lexical errors.
+ * It is intended to support certificate information gathering for SSL backends
+ * that offer a mean to get certificates as a whole, but do not supply
+ * entry points to get particular certificate sub-fields.
+ * Please note there is no pretention here to rewrite a full SSL library.
+ */
+
+
+const char * Curl_getASN1Element(curl_asn1Element * elem,
+ const char * beg, const char * end)
+{
+ unsigned char b;
+ unsigned long len;
+ curl_asn1Element lelem;
+
+ /* Get a single ASN.1 element into `elem', parse ASN.1 string at `beg'
+ ending at `end'.
+ Returns a pointer in source string after the parsed element, or NULL
+ if an error occurs. */
+
+ if(beg >= end || !*beg)
+ return (const char *) NULL;
+
+ /* Process header byte. */
+ elem->header = beg;
+ b = (unsigned char) *beg++;
+ elem->constructed = (b & 0x20) != 0;
+ elem->class = (b >> 6) & 3;
+ b &= 0x1F;
+ if(b == 0x1F)
+ return (const char *) NULL; /* Long tag values not supported here. */
+ elem->tag = b;
+
+ /* Process length. */
+ if(beg >= end)
+ return (const char *) NULL;
+ b = (unsigned char) *beg++;
+ if(!(b & 0x80))
+ len = b;
+ else if(!(b &= 0x7F)) {
+ /* Unspecified length. Since we have all the data, we can determine the
+ effective length by skipping element until an end element is found. */
+ if(!elem->constructed)
+ return (const char *) NULL;
+ elem->beg = beg;
+ while(beg < end && *beg) {
+ beg = Curl_getASN1Element(&lelem, beg, end);
+ if(!beg)
+ return (const char *) NULL;
+ }
+ if(beg >= end)
+ return (const char *) NULL;
+ elem->end = beg;
+ return beg + 1;
+ }
+ else if(beg + b > end)
+ return (const char *) NULL; /* Does not fit in source. */
+ else {
+ /* Get long length. */
+ len = 0;
+ do {
+ if(len & 0xFF000000L)
+ return (const char *) NULL; /* Lengths > 32 bits are not supported. */
+ len = (len << 8) | (unsigned char) *beg++;
+ } while(--b);
+ }
+ if((unsigned long) (end - beg) < len)
+ return (const char *) NULL; /* Element data does not fit in source. */
+ elem->beg = beg;
+ elem->end = beg + len;
+ return elem->end;
+}
+
+static const curl_OID * searchOID(const char * oid)
+{
+ const curl_OID * op;
+
+ /* Search the null terminated OID or OID identifier in local table.
+ Return the table entry pointer or NULL if not found. */
+
+ for(op = OIDtable; op->numoid; op++)
+ if(!strcmp(op->numoid, oid) || curl_strequal(op->textoid, oid))
+ return op;
+
+ return (const curl_OID *) NULL;
+}
+
+static const char * bool2str(const char * beg, const char * end)
+{
+ /* Convert an ASN.1 Boolean value into its string representation.
+ Return the dynamically allocated string, or NULL if source is not an
+ ASN.1 Boolean value. */
+
+ if(end - beg != 1)
+ return (const char *) NULL;
+ return strdup(*beg? "TRUE": "FALSE");
+}
+
+static const char * octet2str(const char * beg, const char * end)
+{
+ size_t n = end - beg;
+ char * buf;
+
+ /* Convert an ASN.1 octet string to a printable string.
+ Return the dynamically allocated string, or NULL if an error occurs. */
+
+ buf = malloc(3 * n + 1);
+ if(buf)
+ for(n = 0; beg < end; n += 3)
+ snprintf(buf + n, 4, "%02x:", *(const unsigned char *) beg++);
+ return buf;
+}
+
+static const char * bit2str(const char * beg, const char * end)
+{
+ /* Convert an ASN.1 bit string to a printable string.
+ Return the dynamically allocated string, or NULL if an error occurs. */
+
+ if(++beg > end)
+ return (const char *) NULL;
+ return octet2str(beg, end);
+}
+
+static const char * int2str(const char * beg, const char * end)
+{
+ long val = 0;
+ size_t n = end - beg;
+
+ /* Convert an ASN.1 integer value into its string representation.
+ Return the dynamically allocated string, or NULL if source is not an
+ ASN.1 integer value. */
+
+ if(!n)
+ return (const char *) NULL;
+
+ if(n > 4)
+ return octet2str(beg, end);
+
+ /* Represent integers <= 32-bit as a single value. */
+ if(*beg & 0x80)
+ val = ~val;
+
+ do
+ val = (val << 8) | *(const unsigned char *) beg++;
+ while(beg < end);
+ return curl_maprintf("%s%lx", (val < 0 || val >= 10)? "0x": "", val);
+}
+
+static ssize_t
+utf8asn1str(char * * to, int type, const char * from, const char * end)
+{
+ size_t inlength = end - from;
+ int size = 1;
+ size_t outlength;
+ int charsize;
+ unsigned int wc;
+ char * buf;
+
+ /* Perform a lazy conversion from an ASN.1 typed string to UTF8. Allocate the
+ destination buffer dynamically. The allocation size will normally be too
+ large: this is to avoid buffer overflows.
+ Terminate the string with a nul byte and return the converted
+ string length. */
+
+ *to = (char *) NULL;
+ switch (type) {
+ case CURL_ASN1_BMP_STRING:
+ size = 2;
+ break;
+ case CURL_ASN1_UNIVERSAL_STRING:
+ size = 4;
+ break;
+ case CURL_ASN1_NUMERIC_STRING:
+ case CURL_ASN1_PRINTABLE_STRING:
+ case CURL_ASN1_TELETEX_STRING:
+ case CURL_ASN1_IA5_STRING:
+ case CURL_ASN1_VISIBLE_STRING:
+ case CURL_ASN1_UTF8_STRING:
+ break;
+ default:
+ return -1; /* Conversion not supported. */
+ }
+
+ if(inlength % size)
+ return -1; /* Length inconsistent with character size. */
+ buf = malloc(4 * (inlength / size) + 1);
+ if(!buf)
+ return -1; /* Not enough memory. */
+
+ if(type == CURL_ASN1_UTF8_STRING) {
+ /* Just copy. */
+ outlength = inlength;
+ if(outlength)
+ memcpy(buf, from, outlength);
+ }
+ else {
+ for(outlength = 0; from < end;) {
+ wc = 0;
+ switch (size) {
+ case 4:
+ wc = (wc << 8) | *(const unsigned char *) from++;
+ wc = (wc << 8) | *(const unsigned char *) from++;
+ /* fallthrough */
+ case 2:
+ wc = (wc << 8) | *(const unsigned char *) from++;
+ /* fallthrough */
+ default: /* case 1: */
+ wc = (wc << 8) | *(const unsigned char *) from++;
+ }
+ charsize = 1;
+ if(wc >= 0x00000080) {
+ if(wc >= 0x00000800) {
+ if(wc >= 0x00010000) {
+ if(wc >= 0x00200000) {
+ free(buf);
+ return -1; /* Invalid char. size for target encoding. */
+ }
+ buf[outlength + 3] = (char) (0x80 | (wc & 0x3F));
+ wc = (wc >> 6) | 0x00010000;
+ charsize++;
+ }
+ buf[outlength + 2] = (char) (0x80 | (wc & 0x3F));
+ wc = (wc >> 6) | 0x00000800;
+ charsize++;
+ }
+ buf[outlength + 1] = (char) (0x80 | (wc & 0x3F));
+ wc = (wc >> 6) | 0x000000C0;
+ charsize++;
+ }
+ buf[outlength] = (char) wc;
+ outlength += charsize;
+ }
+ }
+ buf[outlength] = '\0';
+ *to = buf;
+ return outlength;
+}
+
+static const char * string2str(int type, const char * beg, const char * end)
+{
+ char * buf;
+
+ /* Convert an ASN.1 String into its UTF-8 string representation.
+ Return the dynamically allocated string, or NULL if an error occurs. */
+
+ if(utf8asn1str(&buf, type, beg, end) < 0)
+ return (const char *) NULL;
+ return buf;
+}
+
+static int encodeUint(char * buf, int n, unsigned int x)
+{
+ int i = 0;
+ unsigned int y = x / 10;
+
+ /* Decimal ASCII encode unsigned integer `x' in the `n'-byte buffer at `buf'.
+ Return the total number of encoded digits, even if larger than `n'. */
+
+ if(y) {
+ i += encodeUint(buf, n, y);
+ x -= y * 10;
+ }
+ if(i < n)
+ buf[i] = (char) ('0' + x);
+ i++;
+ if(i < n)
+ buf[i] = '\0'; /* Store a terminator if possible. */
+ return i;
+}
+
+static int encodeOID(char * buf, int n, const char * beg, const char * end)
+{
+ int i = 0;
+ unsigned int x;
+ unsigned int y;
+
+ /* Convert an ASN.1 OID into its dotted string representation.
+ Store the result in th `n'-byte buffer at `buf'.
+ Return the converted string length, or -1 if an error occurs. */
+
+ /* Process the first two numbers. */
+ y = *(const unsigned char *) beg++;
+ x = y / 40;
+ y -= x * 40;
+ i += encodeUint(buf + i, n - i, x);
+ if(i < n)
+ buf[i] = '.';
+ i++;
+ i += encodeUint(buf + i, n - i, y);
+
+ /* Process the trailing numbers. */
+ while(beg < end) {
+ if(i < n)
+ buf[i] = '.';
+ i++;
+ x = 0;
+ do {
+ if(x & 0xFF000000)
+ return -1;
+ y = *(const unsigned char *) beg++;
+ x = (x << 7) | (y & 0x7F);
+ } while(y & 0x80);
+ i += encodeUint(buf + i, n - i, x);
+ }
+ if(i < n)
+ buf[i] = '\0';
+ return i;
+}
+
+static const char * OID2str(const char * beg, const char * end, bool symbolic)
+{
+ char * buf = (char *) NULL;
+ const curl_OID * op;
+ int n;
+
+ /* Convert an ASN.1 OID into its dotted or symbolic string representation.
+ Return the dynamically allocated string, or NULL if an error occurs. */
+
+ if(beg < end) {
+ n = encodeOID((char *) NULL, -1, beg, end);
+ if(n >= 0) {
+ buf = malloc(n + 1);
+ if(buf) {
+ encodeOID(buf, n, beg, end);
+ buf[n] = '\0';
+
+ if(symbolic) {
+ op = searchOID(buf);
+ if(op) {
+ free(buf);
+ buf = strdup(op->textoid);
+ }
+ }
+ }
+ }
+ }
+ return buf;
+}
+
+static const char * GTime2str(const char * beg, const char * end)
+{
+ const char * tzp;
+ const char * fracp;
+ char sec1, sec2;
+ size_t fracl;
+ size_t tzl;
+ const char * sep = "";
+
+ /* Convert an ASN.1 Generalized time to a printable string.
+ Return the dynamically allocated string, or NULL if an error occurs. */
+
+ for(fracp = beg; fracp < end && *fracp >= '0' && *fracp <= '9'; fracp++)
+ ;
+
+ /* Get seconds digits. */
+ sec1 = '0';
+ switch (fracp - beg - 12) {
+ case 0:
+ sec2 = '0';
+ break;
+ case 2:
+ sec1 = fracp[-2];
+ case 1:
+ sec2 = fracp[-1];
+ break;
+ default:
+ return (const char *) NULL;
+ }
+
+ /* Scan for timezone, measure fractional seconds. */
+ tzp = fracp;
+ fracl = 0;
+ if(fracp < end && (*fracp == '.' || *fracp == ',')) {
+ fracp++;
+ do
+ tzp++;
+ while(tzp < end && *tzp >= '0' && *tzp <= '9');
+ /* Strip leading zeroes in fractional seconds. */
+ for(fracl = tzp - fracp - 1; fracl && fracp[fracl - 1] == '0'; fracl--)
+ ;
+ }
+
+ /* Process timezone. */
+ if(tzp >= end)
+ ; /* Nothing to do. */
+ else if(*tzp == 'Z') {
+ tzp = " GMT";
+ end = tzp + 4;
+ }
+ else {
+ sep = " ";
+ tzp++;
+ }
+
+ tzl = end - tzp;
+ return curl_maprintf("%.4s-%.2s-%.2s %.2s:%.2s:%c%c%s%.*s%s%.*s",
+ beg, beg + 4, beg + 6,
+ beg + 8, beg + 10, sec1, sec2,
+ fracl? ".": "", fracl, fracp,
+ sep, tzl, tzp);
+}
+
+static const char * UTime2str(const char * beg, const char * end)
+{
+ const char * tzp;
+ size_t tzl;
+ const char * sec;
+
+ /* Convert an ASN.1 UTC time to a printable string.
+ Return the dynamically allocated string, or NULL if an error occurs. */
+
+ for(tzp = beg; tzp < end && *tzp >= '0' && *tzp <= '9'; tzp++)
+ ;
+ /* Get the seconds. */
+ sec = beg + 10;
+ switch (tzp - sec) {
+ case 0:
+ sec = "00";
+ case 2:
+ break;
+ default:
+ return (const char *) NULL;
+ }
+
+ /* Process timezone. */
+ if(tzp >= end)
+ return (const char *) NULL;
+ if(*tzp == 'Z') {
+ tzp = "GMT";
+ end = tzp + 3;
+ }
+ else
+ tzp++;
+
+ tzl = end - tzp;
+ return curl_maprintf("%u%.2s-%.2s-%.2s %.2s:%.2s:%.2s %.*s",
+ 20 - (*beg >= '5'), beg, beg + 2, beg + 4,
+ beg + 6, beg + 8, sec,
+ tzl, tzp);
+}
+
+const char * Curl_ASN1tostr(curl_asn1Element * elem, int type)
+{
+ /* Convert an ASN.1 element to a printable string.
+ Return the dynamically allocated string, or NULL if an error occurs. */
+
+ if(elem->constructed)
+ return (const char *) NULL; /* No conversion of structured elements. */
+
+ if(!type)
+ type = elem->tag; /* Type not forced: use element tag as type. */
+
+ switch (type) {
+ case CURL_ASN1_BOOLEAN:
+ return bool2str(elem->beg, elem->end);
+ case CURL_ASN1_INTEGER:
+ case CURL_ASN1_ENUMERATED:
+ return int2str(elem->beg, elem->end);
+ case CURL_ASN1_BIT_STRING:
+ return bit2str(elem->beg, elem->end);
+ case CURL_ASN1_OCTET_STRING:
+ return octet2str(elem->beg, elem->end);
+ case CURL_ASN1_NULL:
+ return strdup("");
+ case CURL_ASN1_OBJECT_IDENTIFIER:
+ return OID2str(elem->beg, elem->end, TRUE);
+ case CURL_ASN1_UTC_TIME:
+ return UTime2str(elem->beg, elem->end);
+ case CURL_ASN1_GENERALIZED_TIME:
+ return GTime2str(elem->beg, elem->end);
+ case CURL_ASN1_UTF8_STRING:
+ case CURL_ASN1_NUMERIC_STRING:
+ case CURL_ASN1_PRINTABLE_STRING:
+ case CURL_ASN1_TELETEX_STRING:
+ case CURL_ASN1_IA5_STRING:
+ case CURL_ASN1_VISIBLE_STRING:
+ case CURL_ASN1_UNIVERSAL_STRING:
+ case CURL_ASN1_BMP_STRING:
+ return string2str(type, elem->beg, elem->end);
+ }
+
+ return (const char *) NULL; /* Unsupported. */
+}
+
+static ssize_t encodeDN(char * buf, size_t n, curl_asn1Element * dn)
+{
+ curl_asn1Element rdn;
+ curl_asn1Element atv;
+ curl_asn1Element oid;
+ curl_asn1Element value;
+ size_t l = 0;
+ const char * p1;
+ const char * p2;
+ const char * p3;
+ const char * str;
+
+ /* ASCII encode distinguished name at `dn' into the `n'-byte buffer at `buf'.
+ Return the total string length, even if larger than `n'. */
+
+ for(p1 = dn->beg; p1 < dn->end;) {
+ p1 = Curl_getASN1Element(&rdn, p1, dn->end);
+ for(p2 = rdn.beg; p2 < rdn.end;) {
+ p2 = Curl_getASN1Element(&atv, p2, rdn.end);
+ p3 = Curl_getASN1Element(&oid, atv.beg, atv.end);
+ Curl_getASN1Element(&value, p3, atv.end);
+ str = Curl_ASN1tostr(&oid, 0);
+ if(!str)
+ return -1;
+
+ /* Encode delimiter.
+ If attribute has a short uppercase name, delimiter is ", ". */
+ if(l) {
+ for(p3 = str; isupper(*p3); p3++)
+ ;
+ for(p3 = (*p3 || p3 - str > 2)? "/": ", "; *p3; p3++) {
+ if(l < n)
+ buf[l] = *p3;
+ l++;
+ }
+ }
+
+ /* Encode attribute name. */
+ for(p3 = str; *p3; p3++) {
+ if(l < n)
+ buf[l] = *p3;
+ l++;
+ }
+ free((char *) str);
+
+ /* Generate equal sign. */
+ if(l < n)
+ buf[l] = '=';
+ l++;
+
+ /* Generate value. */
+ str = Curl_ASN1tostr(&value, 0);
+ if(!str)
+ return -1;
+ for(p3 = str; *p3; p3++) {
+ if(l < n)
+ buf[l] = *p3;
+ l++;
+ }
+ free((char *) str);
+ }
+ }
+
+ return l;
+}
+
+const char * Curl_DNtostr(curl_asn1Element * dn)
+{
+ char * buf = (char *) NULL;
+ ssize_t n = encodeDN(buf, 0, dn);
+
+ /* Convert an ASN.1 distinguished name into a printable string.
+ Return the dynamically allocated string, or NULL if an error occurs. */
+
+ if(n >= 0) {
+ buf = malloc(n + 1);
+ if(buf) {
+ encodeDN(buf, n + 1, dn);
+ buf[n] = '\0';
+ }
+ }
+ return (const char *) buf;
+}
+
+/*
+ * X509 parser.
+ */
+
+void Curl_parseX509(curl_X509certificate * cert,
+ const char * beg, const char * end)
+{
+ curl_asn1Element elem;
+ curl_asn1Element tbsCertificate;
+ const char * ccp;
+ static const char defaultVersion = 0; /* v1. */
+
+ /* ASN.1 parse an X509 certificate into structure subfields.
+ Syntax is assumed to have already been checked by the SSL backend.
+ See RFC 5280. */
+
+ cert->certificate.header = NULL;
+ cert->certificate.beg = beg;
+ cert->certificate.end = end;
+
+ /* Get the sequence content. */
+ Curl_getASN1Element(&elem, beg, end);
+ beg = elem.beg;
+ end = elem.end;
+
+ /* Get tbsCertificate. */
+ beg = Curl_getASN1Element(&tbsCertificate, beg, end);
+ /* Skip the signatureAlgorithm. */
+ beg = Curl_getASN1Element(&cert->signatureAlgorithm, beg, end);
+ /* Get the signatureValue. */
+ Curl_getASN1Element(&cert->signature, beg, end);
+
+ /* Parse TBSCertificate. */
+ beg = tbsCertificate.beg;
+ end = tbsCertificate.end;
+ /* Get optional version, get serialNumber. */
+ cert->version.header = NULL;
+ cert->version.beg = &defaultVersion;
+ cert->version.end = &defaultVersion + sizeof defaultVersion;;
+ beg = Curl_getASN1Element(&elem, beg, end);
+ if(elem.tag == 0) {
+ Curl_getASN1Element(&cert->version, elem.beg, elem.end);
+ beg = Curl_getASN1Element(&elem, beg, end);
+ }
+ cert->serialNumber = elem;
+ /* Get signature algorithm. */
+ beg = Curl_getASN1Element(&cert->signatureAlgorithm, beg, end);
+ /* Get issuer. */
+ beg = Curl_getASN1Element(&cert->issuer, beg, end);
+ /* Get notBefore and notAfter. */
+ beg = Curl_getASN1Element(&elem, beg, end);
+ ccp = Curl_getASN1Element(&cert->notBefore, elem.beg, elem.end);
+ Curl_getASN1Element(&cert->notAfter, ccp, elem.end);
+ /* Get subject. */
+ beg = Curl_getASN1Element(&cert->subject, beg, end);
+ /* Get subjectPublicKeyAlgorithm and subjectPublicKey. */
+ beg = Curl_getASN1Element(&cert->subjectPublicKeyInfo, beg, end);
+ ccp = Curl_getASN1Element(&cert->subjectPublicKeyAlgorithm,
+ cert->subjectPublicKeyInfo.beg,
+ cert->subjectPublicKeyInfo.end);
+ Curl_getASN1Element(&cert->subjectPublicKey, ccp,
+ cert->subjectPublicKeyInfo.end);
+ /* Get optional issuerUiqueID, subjectUniqueID and extensions. */
+ cert->issuerUniqueID.tag = cert->subjectUniqueID.tag = 0;
+ cert->extensions.tag = elem.tag = 0;
+ cert->issuerUniqueID.header = cert->subjectUniqueID.header = NULL;
+ cert->issuerUniqueID.beg = cert->issuerUniqueID.end = "";
+ cert->subjectUniqueID.beg = cert->subjectUniqueID.end = "";
+ cert->extensions.header = NULL;
+ cert->extensions.beg = cert->extensions.end = "";
+ if(beg < end)
+ beg = Curl_getASN1Element(&elem, beg, end);
+ if(elem.tag == 1) {
+ cert->issuerUniqueID = elem;
+ if(beg < end)
+ beg = Curl_getASN1Element(&elem, beg, end);
+ }
+ if(elem.tag == 2) {
+ cert->subjectUniqueID = elem;
+ if(beg < end)
+ beg = Curl_getASN1Element(&elem, beg, end);
+ }
+ if(elem.tag == 3)
+ Curl_getASN1Element(&cert->extensions, elem.beg, elem.end);
+}
+
+static size_t copySubstring(char * to, const char * from)
+{
+ size_t i;
+
+ /* Copy at most 64-characters, terminate with a newline and returns the
+ effective number of stored characters. */
+
+ for(i = 0; i < 64; i++) {
+ to[i] = *from;
+ if(!*from++)
+ break;
+ }
+
+ to[i++] = '\n';
+ return i;
+}
+
+static const char * dumpAlgo(curl_asn1Element * param,
+ const char * beg, const char * end)
+{
+ curl_asn1Element oid;
+
+ /* Get algorithm parameters and return algorithm name. */
+
+ beg = Curl_getASN1Element(&oid, beg, end);
+ param->header = NULL;
+ param->tag = 0;
+ param->beg = param->end = end;
+ if(beg < end)
+ Curl_getASN1Element(param, beg, end);
+ return OID2str(oid.beg, oid.end, TRUE);
+}
+
+static void do_pubkey_field(struct SessionHandle * data, int certnum,
+ const char * label, curl_asn1Element * elem)
+{
+ const char * output;
+
+ /* Generate a certificate information record for the public key. */
+
+ output = Curl_ASN1tostr(elem, 0);
+ if(output) {
+ if(data->set.ssl.certinfo)
+ Curl_ssl_push_certinfo(data, certnum, label, output);
+ if(!certnum)
+ infof(data, " %s: %s\n", label, output);
+ free((char *) output);
+ }
+}
+
+static void do_pubkey(struct SessionHandle * data, int certnum,
+ const char * algo, curl_asn1Element * param,
+ curl_asn1Element * pubkey)
+{
+ curl_asn1Element elem;
+ curl_asn1Element pk;
+ const char * p;
+ const char * q;
+ unsigned long len;
+ unsigned int i;
+
+ /* Generate all information records for the public key. */
+
+ /* Get the public key (single element). */
+ Curl_getASN1Element(&pk, pubkey->beg + 1, pubkey->end);
+
+ if(curl_strequal(algo, "rsaEncryption")) {
+ p = Curl_getASN1Element(&elem, pk.beg, pk.end);
+ /* Compute key length. */
+ for(q = elem.beg; !*q && q < elem.end; q++)
+ ;
+ len = (unsigned long)((elem.end - q) * 8);
+ if(len)
+ for(i = *(unsigned char *) q; !(i & 0x80); i <<= 1)
+ len--;
+ if(len > 32)
+ elem.beg = q; /* Strip leading zero bytes. */
+ if(!certnum)
+ infof(data, " RSA Public Key (%lu bits)\n", len);
+ if(data->set.ssl.certinfo) {
+ q = curl_maprintf("%lu", len);
+ if(q) {
+ Curl_ssl_push_certinfo(data, certnum, "RSA Public Key", q);
+ free((char *) q);
+ }
+ }
+ /* Generate coefficients. */
+ do_pubkey_field(data, certnum, "rsa(n)", &elem);
+ Curl_getASN1Element(&elem, p, pk.end);
+ do_pubkey_field(data, certnum, "rsa(e)", &elem);
+ }
+ else if(curl_strequal(algo, "dsa")) {
+ p = Curl_getASN1Element(&elem, param->beg, param->end);
+ do_pubkey_field(data, certnum, "dsa(p)", &elem);
+ p = Curl_getASN1Element(&elem, p, param->end);
+ do_pubkey_field(data, certnum, "dsa(q)", &elem);
+ Curl_getASN1Element(&elem, p, param->end);
+ do_pubkey_field(data, certnum, "dsa(g)", &elem);
+ do_pubkey_field(data, certnum, "dsa(pub_key)", &pk);
+ }
+ else if(curl_strequal(algo, "dhpublicnumber")) {
+ p = Curl_getASN1Element(&elem, param->beg, param->end);
+ do_pubkey_field(data, certnum, "dh(p)", &elem);
+ Curl_getASN1Element(&elem, param->beg, param->end);
+ do_pubkey_field(data, certnum, "dh(g)", &elem);
+ do_pubkey_field(data, certnum, "dh(pub_key)", &pk);
+ }
+#if 0 /* Patent-encumbered. */
+ else if(curl_strequal(algo, "ecPublicKey")) {
+ /* Left TODO. */
+ }
+#endif
+}
+
+CURLcode Curl_extract_certinfo(struct connectdata * conn,
+ int certnum,
+ const char * beg,
+ const char * end)
+{
+ curl_X509certificate cert;
+ struct SessionHandle * data = conn->data;
+ curl_asn1Element param;
+ const char * ccp;
+ char * cp1;
+ size_t cl1;
+ char * cp2;
+ CURLcode result;
+ unsigned long version;
+ size_t i;
+ size_t j;
+
+ if(!data->set.ssl.certinfo)
+ if(certnum)
+ return CURLE_OK;
+
+ /* Prepare the certificate information for curl_easy_getinfo(). */
+
+ /* Extract the certificate ASN.1 elements. */
+ Curl_parseX509(&cert, beg, end);
+
+ /* Subject. */
+ ccp = Curl_DNtostr(&cert.subject);
+ if(!ccp)
+ return CURLE_OUT_OF_MEMORY;
+ if(data->set.ssl.certinfo)
+ Curl_ssl_push_certinfo(data, certnum, "Subject", ccp);
+ if(!certnum)
+ infof(data, "%2d Subject: %s\n", certnum, ccp);
+ free((char *) ccp);
+
+ /* Issuer. */
+ ccp = Curl_DNtostr(&cert.issuer);
+ if(!ccp)
+ return CURLE_OUT_OF_MEMORY;
+ if(data->set.ssl.certinfo)
+ Curl_ssl_push_certinfo(data, certnum, "Issuer", ccp);
+ if(!certnum)
+ infof(data, " Issuer: %s\n", ccp);
+ free((char *) ccp);
+
+ /* Version (always fits in less than 32 bits). */
+ version = 0;
+ for(ccp = cert.version.beg; ccp < cert.version.end; ccp++)
+ version = (version << 8) | *(const unsigned char *) ccp;
+ if(data->set.ssl.certinfo) {
+ ccp = curl_maprintf("%lx", version);
+ if(!ccp)
+ return CURLE_OUT_OF_MEMORY;
+ Curl_ssl_push_certinfo(data, certnum, "Version", ccp);
+ free((char *) ccp);
+ }
+ if(!certnum)
+ infof(data, " Version: %lu (0x%lx)\n", version + 1, version);
+
+ /* Serial number. */
+ ccp = Curl_ASN1tostr(&cert.serialNumber, 0);
+ if(!ccp)
+ return CURLE_OUT_OF_MEMORY;
+ if(data->set.ssl.certinfo)
+ Curl_ssl_push_certinfo(data, certnum, "Serial Number", ccp);
+ if(!certnum)
+ infof(data, " Serial Number: %s\n", ccp);
+ free((char *) ccp);
+
+ /* Signature algorithm .*/
+ ccp = dumpAlgo(&param, cert.signatureAlgorithm.beg,
+ cert.signatureAlgorithm.end);
+ if(!ccp)
+ return CURLE_OUT_OF_MEMORY;
+ if(data->set.ssl.certinfo)
+ Curl_ssl_push_certinfo(data, certnum, "Signature Algorithm", ccp);
+ if(!certnum)
+ infof(data, " Signature Algorithm: %s\n", ccp);
+ free((char *) ccp);
+
+ /* Start Date. */
+ ccp = Curl_ASN1tostr(&cert.notBefore, 0);
+ if(!ccp)
+ return CURLE_OUT_OF_MEMORY;
+ if(data->set.ssl.certinfo)
+ Curl_ssl_push_certinfo(data, certnum, "Start Date", ccp);
+ if(!certnum)
+ infof(data, " Start Date: %s\n", ccp);
+ free((char *) ccp);
+
+ /* Expire Date. */
+ ccp = Curl_ASN1tostr(&cert.notAfter, 0);
+ if(!ccp)
+ return CURLE_OUT_OF_MEMORY;
+ if(data->set.ssl.certinfo)
+ Curl_ssl_push_certinfo(data, certnum, "Expire Date", ccp);
+ if(!certnum)
+ infof(data, " Expire Date: %s\n", ccp);
+ free((char *) ccp);
+
+ /* Public Key Algorithm. */
+ ccp = dumpAlgo(&param, cert.subjectPublicKeyAlgorithm.beg,
+ cert.subjectPublicKeyAlgorithm.end);
+ if(!ccp)
+ return CURLE_OUT_OF_MEMORY;
+ if(data->set.ssl.certinfo)
+ Curl_ssl_push_certinfo(data, certnum, "Public Key Algorithm", ccp);
+ if(!certnum)
+ infof(data, " Public Key Algorithm: %s\n", ccp);
+ do_pubkey(data, certnum, ccp, &param, &cert.subjectPublicKey);
+ free((char *) ccp);
+
+/* TODO: extensions. */
+
+ /* Signature. */
+ ccp = Curl_ASN1tostr(&cert.signature, 0);
+ if(!ccp)
+ return CURLE_OUT_OF_MEMORY;
+ if(data->set.ssl.certinfo)
+ Curl_ssl_push_certinfo(data, certnum, "Signature", ccp);
+ if(!certnum)
+ infof(data, " Signature: %s\n", ccp);
+ free((char *) ccp);
+
+ /* Generate PEM certificate. */
+ result = Curl_base64_encode(data, cert.certificate.beg,
+ cert.certificate.end - cert.certificate.beg,
+ &cp1, &cl1);
+ if(result)
+ return result;
+ /* Compute the number of characters in final certificate string. Format is:
+ -----BEGIN CERTIFICATE-----\n
+ <max 64 base64 characters>\n
+ .
+ .
+ .
+ -----END CERTIFICATE-----\n
+ */
+ i = 28 + cl1 + (cl1 + 64 - 1) / 64 + 26;
+ cp2 = malloc(i + 1);
+ if(!cp2) {
+ free(cp1);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ /* Build the certificate string. */
+ i = copySubstring(cp2, "-----BEGIN CERTIFICATE-----");
+ for(j = 0; j < cl1; j += 64)
+ i += copySubstring(cp2 + i, cp1 + j);
+ i += copySubstring(cp2 + i, "-----END CERTIFICATE-----");
+ cp2[i] = '\0';
+ free(cp1);
+ if(data->set.ssl.certinfo)
+ Curl_ssl_push_certinfo(data, certnum, "Cert", cp2);
+ if(!certnum)
+ infof(data, "%s\n", cp2);
+ free(cp2);
+ return CURLE_OK;
+}
+
+#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_CYASSL */
+
+#if defined(USE_GSKIT)
+
+static const char * checkOID(const char * beg, const char * end,
+ const char * oid)
+{
+ curl_asn1Element e;
+ const char * ccp;
+ const char * p;
+ bool matched;
+
+ /* Check if first ASN.1 element at `beg' is the given OID.
+ Return a pointer in the source after the OID if found, else NULL. */
+
+ ccp = Curl_getASN1Element(&e, beg, end);
+ if(!ccp || e.tag != CURL_ASN1_OBJECT_IDENTIFIER)
+ return (const char *) NULL;
+
+ p = OID2str(e.beg, e.end, FALSE);
+ if(!p)
+ return (const char *) NULL;
+
+ matched = !strcmp(p, oid);
+ free((char *) p);
+ return matched? ccp: (const char *) NULL;
+}
+
+CURLcode Curl_verifyhost(struct connectdata * conn,
+ const char * beg, const char * end)
+{
+ struct SessionHandle * data = conn->data;
+ curl_X509certificate cert;
+ curl_asn1Element dn;
+ curl_asn1Element elem;
+ curl_asn1Element ext;
+ curl_asn1Element name;
+ int i;
+ const char * p;
+ const char * q;
+ char * dnsname;
+ int matched = -1;
+ size_t addrlen = (size_t) -1;
+ ssize_t len;
+#ifdef ENABLE_IPV6
+ struct in6_addr addr;
+#else
+ struct in_addr addr;
+#endif
+
+ /* Verify that connection server matches info in X509 certificate at
+ `beg'..`end'. */
+
+ if(!data->set.ssl.verifyhost)
+ return CURLE_OK;
+
+ if(!beg)
+ return CURLE_PEER_FAILED_VERIFICATION;
+ Curl_parseX509(&cert, beg, end);
+
+ /* Get the server IP address. */
+#ifdef ENABLE_IPV6
+ if(conn->bits.ipv6_ip && Curl_inet_pton(AF_INET6, conn->host.name, &addr))
+ addrlen = sizeof(struct in6_addr);
+ else
+#endif
+ if(Curl_inet_pton(AF_INET, conn->host.name, &addr))
+ addrlen = sizeof(struct in_addr);
+
+ /* Process extensions. */
+ for(p = cert.extensions.beg; p < cert.extensions.end && matched != 1;) {
+ p = Curl_getASN1Element(&ext, p, cert.extensions.end);
+ /* Check if extension is a subjectAlternativeName. */
+ ext.beg = checkOID(ext.beg, ext.end, sanOID);
+ if(ext.beg) {
+ ext.beg = Curl_getASN1Element(&elem, ext.beg, ext.end);
+ /* Skip critical if present. */
+ if(elem.tag == CURL_ASN1_BOOLEAN)
+ ext.beg = Curl_getASN1Element(&elem, ext.beg, ext.end);
+ /* Parse the octet string contents: is a single sequence. */
+ Curl_getASN1Element(&elem, elem.beg, elem.end);
+ /* Check all GeneralNames. */
+ for(q = elem.beg; matched != 1 && q < elem.end;) {
+ q = Curl_getASN1Element(&name, q, elem.end);
+ switch (name.tag) {
+ case 2: /* DNS name. */
+ i = 0;
+ len = utf8asn1str(&dnsname, CURL_ASN1_IA5_STRING,
+ name.beg, name.end);
+ if(len > 0)
+ if(strlen(dnsname) == (size_t) len)
+ i = Curl_cert_hostcheck((const char *) dnsname, conn->host.name);
+ free(dnsname);
+ if(!i)
+ return CURLE_PEER_FAILED_VERIFICATION;
+ matched = i;
+ break;
+
+ case 7: /* IP address. */
+ matched = (size_t) (name.end - q) == addrlen &&
+ !memcmp(&addr, q, addrlen);
+ break;
+ }
+ }
+ }
+ }
+
+ switch (matched) {
+ case 1:
+ /* an alternative name matched the server hostname */
+ infof(data, "\t subjectAltName: %s matched\n", conn->host.dispname);
+ return CURLE_OK;
+ case 0:
+ /* an alternative name field existed, but didn't match and then
+ we MUST fail */
+ infof(data, "\t subjectAltName does not match %s\n", conn->host.dispname);
+ return CURLE_PEER_FAILED_VERIFICATION;
+ }
+
+ /* Process subject. */
+ name.header = NULL;
+ name.beg = name.end = "";
+ q = cert.subject.beg;
+ /* we have to look to the last occurrence of a commonName in the
+ distinguished one to get the most significant one. */
+ while(q < cert.subject.end) {
+ q = Curl_getASN1Element(&dn, q, cert.subject.end);
+ for(p = dn.beg; p < dn.end;) {
+ p = Curl_getASN1Element(&elem, p, dn.end);
+ /* We have a DN's AttributeTypeAndValue: check it in case it's a CN. */
+ elem.beg = checkOID(elem.beg, elem.end, cnOID);
+ if(elem.beg)
+ name = elem; /* Latch CN. */
+ }
+ }
+
+ /* Check the CN if found. */
+ if(!Curl_getASN1Element(&elem, name.beg, name.end))
+ failf(data, "SSL: unable to obtain common name from peer certificate");
+ else {
+ len = utf8asn1str(&dnsname, elem.tag, elem.beg, elem.end);
+ if(len < 0) {
+ free(dnsname);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ if(strlen(dnsname) != (size_t) len) /* Nul byte in string ? */
+ failf(data, "SSL: illegal cert name field");
+ else if(Curl_cert_hostcheck((const char *) dnsname, conn->host.name)) {
+ infof(data, "\t common name: %s (matched)\n", dnsname);
+ free(dnsname);
+ return CURLE_OK;
+ }
+ else
+ failf(data, "SSL: certificate subject name '%s' does not match "
+ "target host name '%s'", dnsname, conn->host.dispname);
+ free(dnsname);
+ }
+
+ return CURLE_PEER_FAILED_VERIFICATION;
+}
+
+#endif /* USE_GSKIT */
diff --git a/Utilities/cmcurl/lib/x509asn1.h b/Utilities/cmcurl/lib/x509asn1.h
new file mode 100644
index 000000000..eb23e506a
--- /dev/null
+++ b/Utilities/cmcurl/lib/x509asn1.h
@@ -0,0 +1,132 @@
+#ifndef HEADER_CURL_X509ASN1_H
+#define HEADER_CURL_X509ASN1_H
+
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \
+ defined(USE_CYASSL)
+
+#include "urldata.h"
+
+/*
+ * Constants.
+ */
+
+/* ASN.1 classes. */
+#define CURL_ASN1_UNIVERSAL 0
+#define CURL_ASN1_APPLICATION 1
+#define CURL_ASN1_CONTEXT_SPECIFIC 2
+#define CURL_ASN1_PRIVATE 3
+
+/* ASN.1 types. */
+#define CURL_ASN1_BOOLEAN 1
+#define CURL_ASN1_INTEGER 2
+#define CURL_ASN1_BIT_STRING 3
+#define CURL_ASN1_OCTET_STRING 4
+#define CURL_ASN1_NULL 5
+#define CURL_ASN1_OBJECT_IDENTIFIER 6
+#define CURL_ASN1_OBJECT_DESCRIPTOR 7
+#define CURL_ASN1_INSTANCE_OF 8
+#define CURL_ASN1_REAL 9
+#define CURL_ASN1_ENUMERATED 10
+#define CURL_ASN1_EMBEDDED 11
+#define CURL_ASN1_UTF8_STRING 12
+#define CURL_ASN1_RELATIVE_OID 13
+#define CURL_ASN1_SEQUENCE 16
+#define CURL_ASN1_SET 17
+#define CURL_ASN1_NUMERIC_STRING 18
+#define CURL_ASN1_PRINTABLE_STRING 19
+#define CURL_ASN1_TELETEX_STRING 20
+#define CURL_ASN1_VIDEOTEX_STRING 21
+#define CURL_ASN1_IA5_STRING 22
+#define CURL_ASN1_UTC_TIME 23
+#define CURL_ASN1_GENERALIZED_TIME 24
+#define CURL_ASN1_GRAPHIC_STRING 25
+#define CURL_ASN1_VISIBLE_STRING 26
+#define CURL_ASN1_GENERAL_STRING 27
+#define CURL_ASN1_UNIVERSAL_STRING 28
+#define CURL_ASN1_CHARACTER_STRING 29
+#define CURL_ASN1_BMP_STRING 30
+
+
+/*
+ * Types.
+ */
+
+/* ASN.1 parsed element. */
+typedef struct {
+ const char * header; /* Pointer to header byte. */
+ const char * beg; /* Pointer to element data. */
+ const char * end; /* Pointer to 1st byte after element. */
+ unsigned char class; /* ASN.1 element class. */
+ unsigned char tag; /* ASN.1 element tag. */
+ bool constructed; /* Element is constructed. */
+} curl_asn1Element;
+
+
+/* ASN.1 OID table entry. */
+typedef struct {
+ const char * numoid; /* Dotted-numeric OID. */
+ const char * textoid; /* OID name. */
+} curl_OID;
+
+
+/* X509 certificate: RFC 5280. */
+typedef struct {
+ curl_asn1Element certificate;
+ curl_asn1Element version;
+ curl_asn1Element serialNumber;
+ curl_asn1Element signatureAlgorithm;
+ curl_asn1Element signature;
+ curl_asn1Element issuer;
+ curl_asn1Element notBefore;
+ curl_asn1Element notAfter;
+ curl_asn1Element subject;
+ curl_asn1Element subjectPublicKeyInfo;
+ curl_asn1Element subjectPublicKeyAlgorithm;
+ curl_asn1Element subjectPublicKey;
+ curl_asn1Element issuerUniqueID;
+ curl_asn1Element subjectUniqueID;
+ curl_asn1Element extensions;
+} curl_X509certificate;
+
+
+/*
+ * Prototypes.
+ */
+
+const char * Curl_getASN1Element(curl_asn1Element * elem,
+ const char * beg, const char * end);
+const char * Curl_ASN1tostr(curl_asn1Element * elem, int type);
+const char * Curl_DNtostr(curl_asn1Element * dn);
+void Curl_parseX509(curl_X509certificate * cert,
+ const char * beg, const char * end);
+CURLcode Curl_extract_certinfo(struct connectdata * conn, int certnum,
+ const char * beg, const char * end);
+CURLcode Curl_verifyhost(struct connectdata * conn,
+ const char * beg, const char * end);
+
+#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_CYASSL */
+#endif /* HEADER_CURL_X509ASN1_H */
diff --git a/Utilities/cmcurl/llist.c b/Utilities/cmcurl/llist.c
deleted file mode 100644
index 921d1d1f9..000000000
--- a/Utilities/cmcurl/llist.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#include <string.h>
-#include <stdlib.h>
-
-#include "llist.h"
-#include "memory.h"
-
-/* this must be the last include file */
-#include "memdebug.h"
-
-void
-Curl_llist_init(struct curl_llist *l, curl_llist_dtor dtor)
-{
- l->size = 0;
- l->dtor = dtor;
- l->head = NULL;
- l->tail = NULL;
-}
-
-struct curl_llist *
-Curl_llist_alloc(curl_llist_dtor dtor)
-{
- struct curl_llist *list;
-
- list = (struct curl_llist *)malloc(sizeof(struct curl_llist));
- if(NULL == list)
- return NULL;
-
- Curl_llist_init(list, dtor);
-
- return list;
-}
-
-/*
- * Curl_llist_insert_next() returns 1 on success and 0 on failure.
- */
-int
-Curl_llist_insert_next(struct curl_llist *list, struct curl_llist_element *e,
- const void *p)
-{
- struct curl_llist_element *ne =
- (struct curl_llist_element *) malloc(sizeof(struct curl_llist_element));
- if(!ne)
- return 0;
-
- ne->ptr = (void *) p;
- if (list->size == 0) {
- list->head = ne;
- list->head->prev = NULL;
- list->head->next = NULL;
- list->tail = ne;
- }
- else {
- ne->next = e->next;
- ne->prev = e;
- if (e->next) {
- e->next->prev = ne;
- }
- else {
- list->tail = ne;
- }
- e->next = ne;
- }
-
- ++list->size;
-
- return 1;
-}
-
-int
-Curl_llist_remove(struct curl_llist *list, struct curl_llist_element *e,
- void *user)
-{
- if (e == NULL || list->size == 0)
- return 1;
-
- if (e == list->head) {
- list->head = e->next;
-
- if (list->head == NULL)
- list->tail = NULL;
- else
- e->next->prev = NULL;
- } else {
- e->prev->next = e->next;
- if (!e->next)
- list->tail = e->prev;
- else
- e->next->prev = e->prev;
- }
-
- list->dtor(user, e->ptr);
- free(e);
- --list->size;
-
- return 1;
-}
-
-void
-Curl_llist_destroy(struct curl_llist *list, void *user)
-{
- if(list) {
- while (list->size > 0)
- Curl_llist_remove(list, list->tail, user);
-
- free(list);
- }
-}
-
-size_t
-Curl_llist_count(struct curl_llist *list)
-{
- return list->size;
-}
diff --git a/Utilities/cmcurl/llist.h b/Utilities/cmcurl/llist.h
deleted file mode 100644
index 5c7a8a008..000000000
--- a/Utilities/cmcurl/llist.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef __LLIST_H
-#define __LLIST_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-#include <stddef.h>
-
-typedef void (*curl_llist_dtor)(void *, void *);
-
-struct curl_llist_element {
- void *ptr;
-
- struct curl_llist_element *prev;
- struct curl_llist_element *next;
-};
-
-struct curl_llist {
- struct curl_llist_element *head;
- struct curl_llist_element *tail;
-
- curl_llist_dtor dtor;
-
- size_t size;
-};
-
-void Curl_llist_init(struct curl_llist *, curl_llist_dtor);
-struct curl_llist *Curl_llist_alloc(curl_llist_dtor);
-int Curl_llist_insert_next(struct curl_llist *, struct curl_llist_element *,
- const void *);
-int Curl_llist_insert_prev(struct curl_llist *, struct curl_llist_element *,
- const void *);
-int Curl_llist_remove(struct curl_llist *, struct curl_llist_element *,
- void *);
-int Curl_llist_remove_next(struct curl_llist *, struct curl_llist_element *,
- void *);
-size_t Curl_llist_count(struct curl_llist *);
-void Curl_llist_destroy(struct curl_llist *, void *);
-
-#endif
diff --git a/Utilities/cmcurl/md5.c b/Utilities/cmcurl/md5.c
deleted file mode 100644
index 4cfb073ea..000000000
--- a/Utilities/cmcurl/md5.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#ifndef CURL_DISABLE_CRYPTO_AUTH
-
-#if !defined(USE_SSLEAY) || !defined(USE_OPENSSL)
-/* This code segment is only used if OpenSSL is not provided, as if it is
- we use the MD5-function provided there instead. No good duplicating
- code! */
-
-/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
-rights reserved.
-
-License to copy and use this software is granted provided that it
-is identified as the "RSA Data Security, Inc. MD5 Message-Digest
-Algorithm" in all material mentioning or referencing this software
-or this function.
-
-License is also granted to make and use derivative works provided
-that such works are identified as "derived from the RSA Data
-Security, Inc. MD5 Message-Digest Algorithm" in all material
-mentioning or referencing the derived work.
-
-RSA Data Security, Inc. makes no representations concerning either
-the merchantability of this software or the suitability of this
-software for any particular purpose. It is provided "as is"
-without express or implied warranty of any kind.
-
-These notices must be retained in any copies of any part of this
-documentation and/or software.
- */
-
-#include <string.h>
-
-/* UINT4 defines a four byte word */
-typedef unsigned int UINT4;
-
-/* MD5 context. */
-struct md5_ctx {
- UINT4 state[4]; /* state (ABCD) */
- UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
- unsigned char buffer[64]; /* input buffer */
-};
-
-typedef struct md5_ctx MD5_CTX;
-
-static void MD5_Init(struct md5_ctx *);
-static void MD5_Update(struct md5_ctx *, const unsigned char *, unsigned int);
-static void MD5_Final(unsigned char [16], struct md5_ctx *);
-
-/* Constants for MD5Transform routine.
- */
-
-#define S11 7
-#define S12 12
-#define S13 17
-#define S14 22
-#define S21 5
-#define S22 9
-#define S23 14
-#define S24 20
-#define S31 4
-#define S32 11
-#define S33 16
-#define S34 23
-#define S41 6
-#define S42 10
-#define S43 15
-#define S44 21
-
-static void MD5Transform(UINT4 [4], const unsigned char [64]);
-static void Encode(unsigned char *, UINT4 *, unsigned int);
-static void Decode(UINT4 *, const unsigned char *, unsigned int);
-
-static const unsigned char PADDING[64] = {
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-/* F, G, H and I are basic MD5 functions.
- */
-#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
-#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define I(x, y, z) ((y) ^ ((x) | (~z)))
-
-/* ROTATE_LEFT rotates x left n bits.
- */
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
-
-/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
-Rotation is separate from addition to prevent recomputation.
- */
-#define FF(a, b, c, d, x, s, ac) { \
- (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define GG(a, b, c, d, x, s, ac) { \
- (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define HH(a, b, c, d, x, s, ac) { \
- (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define II(a, b, c, d, x, s, ac) { \
- (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-
-/* MD5 initialization. Begins an MD5 operation, writing a new context.
- */
-static void MD5_Init(struct md5_ctx *context)
-{
- context->count[0] = context->count[1] = 0;
- /* Load magic initialization constants. */
- context->state[0] = 0x67452301;
- context->state[1] = 0xefcdab89;
- context->state[2] = 0x98badcfe;
- context->state[3] = 0x10325476;
-}
-
-/* MD5 block update operation. Continues an MD5 message-digest
- operation, processing another message block, and updating the
- context.
- */
-static void MD5_Update (struct md5_ctx *context, /* context */
- const unsigned char *input, /* input block */
- unsigned int inputLen) /* length of input block */
-{
- unsigned int i, bufindex, partLen;
-
- /* Compute number of bytes mod 64 */
- bufindex = (unsigned int)((context->count[0] >> 3) & 0x3F);
-
- /* Update number of bits */
- if ((context->count[0] += ((UINT4)inputLen << 3))
- < ((UINT4)inputLen << 3))
- context->count[1]++;
- context->count[1] += ((UINT4)inputLen >> 29);
-
- partLen = 64 - bufindex;
-
- /* Transform as many times as possible. */
- if (inputLen >= partLen) {
- memcpy((void *)&context->buffer[bufindex], (void *)input, partLen);
- MD5Transform(context->state, context->buffer);
-
- for (i = partLen; i + 63 < inputLen; i += 64)
- MD5Transform(context->state, &input[i]);
-
- bufindex = 0;
- }
- else
- i = 0;
-
- /* Buffer remaining input */
- memcpy((void *)&context->buffer[bufindex], (void *)&input[i], inputLen-i);
-}
-
-/* MD5 finalization. Ends an MD5 message-digest operation, writing the
- the message digest and zeroizing the context.
-*/
-static void MD5_Final(unsigned char digest[16], /* message digest */
- struct md5_ctx *context) /* context */
-{
- unsigned char bits[8];
- unsigned int count, padLen;
-
- /* Save number of bits */
- Encode (bits, context->count, 8);
-
- /* Pad out to 56 mod 64. */
- count = (unsigned int)((context->count[0] >> 3) & 0x3f);
- padLen = (count < 56) ? (56 - count) : (120 - count);
- MD5_Update (context, PADDING, padLen);
-
- /* Append length (before padding) */
- MD5_Update (context, bits, 8);
-
- /* Store state in digest */
- Encode (digest, context->state, 16);
-
- /* Zeroize sensitive information. */
- memset ((void *)context, 0, sizeof (*context));
-}
-
-/* MD5 basic transformation. Transforms state based on block. */
-static void MD5Transform(UINT4 state[4],
- const unsigned char block[64])
-{
- UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
-
- Decode (x, block, 64);
-
- /* Round 1 */
- FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
- FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
- FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
- FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
- FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
- FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
- FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
- FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
- FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
- FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
- FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
- FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
- FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
- FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
- FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
- FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
-
- /* Round 2 */
- GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
- GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
- GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
- GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
- GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
- GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
- GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
- GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
- GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
- GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
- GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
- GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
- GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
- GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
- GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
- GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
-
- /* Round 3 */
- HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
- HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
- HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
- HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
- HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
- HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
- HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
- HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
- HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
- HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
- HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
- HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
- HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
- HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
- HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
- HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
-
- /* Round 4 */
- II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
- II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
- II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
- II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
- II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
- II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
- II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
- II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
- II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
- II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
- II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
- II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
- II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
- II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
- II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
- II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
-
- state[0] += a;
- state[1] += b;
- state[2] += c;
- state[3] += d;
-
- /* Zeroize sensitive information. */
- memset((void *)x, 0, sizeof (x));
-}
-
-/* Encodes input (UINT4) into output (unsigned char). Assumes len is
- a multiple of 4.
- */
-static void Encode (unsigned char *output,
- UINT4 *input,
- unsigned int len)
-{
- unsigned int i, j;
-
- for (i = 0, j = 0; j < len; i++, j += 4) {
- output[j] = (unsigned char)(input[i] & 0xff);
- output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
- output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
- output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
- }
-}
-
-/* Decodes input (unsigned char) into output (UINT4). Assumes len is
- a multiple of 4.
-*/
-static void Decode (UINT4 *output,
- const unsigned char *input,
- unsigned int len)
-{
- unsigned int i, j;
-
- for (i = 0, j = 0; j < len; i++, j += 4)
- output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
- (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
-}
-
-#else
-/* If OpenSSL is present */
-#include <openssl/md5.h>
-#include <string.h>
-#endif
-
-#include "md5.h"
-
-void Curl_md5it(unsigned char *outbuffer, /* 16 bytes */
- const unsigned char *input)
-{
- MD5_CTX ctx;
- MD5_Init(&ctx);
- MD5_Update(&ctx, input, (unsigned int)strlen((char *)input));
- MD5_Final(outbuffer, &ctx);
-}
-
-#endif
diff --git a/Utilities/cmcurl/md5.h b/Utilities/cmcurl/md5.h
deleted file mode 100644
index 63cc70e84..000000000
--- a/Utilities/cmcurl/md5.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef __MD5_H
-#define __MD5_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-void Curl_md5it(unsigned char *output,
- const unsigned char *input);
-
-#endif
diff --git a/Utilities/cmcurl/memdebug.c b/Utilities/cmcurl/memdebug.c
deleted file mode 100644
index a8cca44cb..000000000
--- a/Utilities/cmcurl/memdebug.c
+++ /dev/null
@@ -1,298 +0,0 @@
-#ifdef CURLDEBUG
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#include <curl/curl.h>
-
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-
-#define _MPRINTF_REPLACE
-#include <curl/mprintf.h>
-#include "urldata.h"
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#define MEMDEBUG_NODEFINES /* don't redefine the standard functions */
-#include "memory.h"
-#include "memdebug.h"
-
-struct memdebug {
- size_t size;
- double mem[1];
- /* I'm hoping this is the thing with the strictest alignment
- * requirements. That also means we waste some space :-( */
-};
-
-/*
- * Note that these debug functions are very simple and they are meant to
- * remain so. For advanced analysis, record a log file and write perl scripts
- * to analyze them!
- *
- * Don't use these with multithreaded test programs!
- */
-
-#define logfile curl_debuglogfile
-FILE *curl_debuglogfile = NULL;
-static bool memlimit = FALSE; /* enable memory limit */
-static long memsize = 0; /* set number of mallocs allowed */
-
-/* this sets the log file name */
-void curl_memdebug(const char *logname)
-{
- if (!logfile) {
- if(logname)
- logfile = fopen(logname, "w");
- else
- logfile = stderr;
- }
-}
-
-/* This function sets the number of malloc() calls that should return
- successfully! */
-void curl_memlimit(long limit)
-{
- if (!memlimit) {
- memlimit = TRUE;
- memsize = limit;
- }
-}
-
-/* returns TRUE if this isn't allowed! */
-static bool countcheck(const char *func, int line, const char *source)
-{
- /* if source is NULL, then the call is made internally and this check
- should not be made */
- if(memlimit && source) {
- if(!memsize) {
- if(logfile && source)
- fprintf(logfile, "LIMIT %s:%d %s reached memlimit\n",
- source, line, func);
- if(source)
- fprintf(stderr, "LIMIT %s:%d %s reached memlimit\n",
- source, line, func);
- errno = ENOMEM;
- return TRUE; /* RETURN ERROR! */
- }
- else
- memsize--; /* countdown */
-
- /* log the countdown */
- if(logfile && source)
- fprintf(logfile, "LIMIT %s:%d %ld ALLOCS left\n",
- source, line, memsize);
-
- }
-
- return FALSE; /* allow this */
-}
-
-void *curl_domalloc(size_t wantedsize, int line, const char *source)
-{
- struct memdebug *mem;
- size_t size;
-
- if(countcheck("malloc", line, source))
- return NULL;
-
- /* alloc at least 64 bytes */
- size = sizeof(struct memdebug)+wantedsize;
-
- mem=(struct memdebug *)(Curl_cmalloc)(size);
- if(mem) {
- /* fill memory with junk */
- memset(mem->mem, 0xA5, wantedsize);
- mem->size = wantedsize;
- }
-
- if(logfile && source)
- fprintf(logfile, "MEM %s:%d malloc(%zd) = %p\n",
- source, line, wantedsize, mem ? mem->mem : 0);
- return (mem ? mem->mem : NULL);
-}
-
-void *curl_docalloc(size_t wanted_elements, size_t wanted_size,
- int line, const char *source)
-{
- struct memdebug *mem;
- size_t size, user_size;
-
- if(countcheck("calloc", line, source))
- return NULL;
-
- /* alloc at least 64 bytes */
- user_size = wanted_size * wanted_elements;
- size = sizeof(struct memdebug) + user_size;
-
- mem = (struct memdebug *)(Curl_cmalloc)(size);
- if(mem) {
- /* fill memory with zeroes */
- memset(mem->mem, 0, user_size);
- mem->size = user_size;
- }
-
- if(logfile && source)
- fprintf(logfile, "MEM %s:%d calloc(%u,%u) = %p\n",
- source, line, wanted_elements, wanted_size, mem ? mem->mem : 0);
- return (mem ? mem->mem : NULL);
-}
-
-char *curl_dostrdup(const char *str, int line, const char *source)
-{
- char *mem;
- size_t len;
-
- curlassert(str != NULL);
-
- if(countcheck("strdup", line, source))
- return NULL;
-
- len=strlen(str)+1;
-
- mem=curl_domalloc(len, 0, NULL); /* NULL prevents logging */
- if (mem)
- memcpy(mem, str, len);
-
- if(logfile)
- fprintf(logfile, "MEM %s:%d strdup(%p) (%zd) = %p\n",
- source, line, str, len, mem);
-
- return mem;
-}
-
-/* We provide a realloc() that accepts a NULL as pointer, which then
- performs a malloc(). In order to work with ares. */
-void *curl_dorealloc(void *ptr, size_t wantedsize,
- int line, const char *source)
-{
- struct memdebug *mem=NULL;
-
- size_t size = sizeof(struct memdebug)+wantedsize;
-
- if(countcheck("realloc", line, source))
- return NULL;
-
- if(ptr)
- mem = (struct memdebug *)((char *)ptr - offsetof(struct memdebug, mem));
-
- mem=(struct memdebug *)(Curl_crealloc)(mem, size);
- if(logfile)
- fprintf(logfile, "MEM %s:%d realloc(%p, %zd) = %p\n",
- source, line, ptr, wantedsize, mem?mem->mem:NULL);
-
- if(mem) {
- mem->size = wantedsize;
- return mem->mem;
- }
-
- return NULL;
-}
-
-void curl_dofree(void *ptr, int line, const char *source)
-{
- struct memdebug *mem;
-
- curlassert(ptr != NULL);
-
- mem = (struct memdebug *)((char *)ptr - offsetof(struct memdebug, mem));
-
- /* destroy */
- memset(mem->mem, 0x13, mem->size);
-
- /* free for real */
- (Curl_cfree)(mem);
-
- if(logfile)
- fprintf(logfile, "MEM %s:%d free(%p)\n", source, line, ptr);
-}
-
-int curl_socket(int domain, int type, int protocol, int line,
- const char *source)
-{
- int sockfd=(socket)(domain, type, protocol);
- if(logfile && (sockfd!=-1))
- fprintf(logfile, "FD %s:%d socket() = %d\n",
- source, line, sockfd);
- return sockfd;
-}
-
-int curl_accept(int s, void *saddr, void *saddrlen,
- int line, const char *source)
-{
- struct sockaddr *addr = (struct sockaddr *)saddr;
- socklen_t *addrlen = (socklen_t *)saddrlen;
- int sockfd=(accept)(s, addr, addrlen);
- if(logfile)
- fprintf(logfile, "FD %s:%d accept() = %d\n",
- source, line, sockfd);
- return sockfd;
-}
-
-/* this is our own defined way to close sockets on *ALL* platforms */
-int curl_sclose(int sockfd, int line, const char *source)
-{
- int res=sclose(sockfd);
- if(logfile)
- fprintf(logfile, "FD %s:%d sclose(%d)\n",
- source, line, sockfd);
- return res;
-}
-
-FILE *curl_fopen(const char *file, const char *mode,
- int line, const char *source)
-{
- FILE *res=(fopen)(file, mode);
- if(logfile)
- fprintf(logfile, "FILE %s:%d fopen(\"%s\",\"%s\") = %p\n",
- source, line, file, mode, res);
- return res;
-}
-
-int curl_fclose(FILE *file, int line, const char *source)
-{
- int res;
-
- curlassert(file != NULL);
-
- res=(fclose)(file);
- if(logfile)
- fprintf(logfile, "FILE %s:%d fclose(%p)\n",
- source, line, file);
- return res;
-}
-#else
-#ifdef VMS
-int VOID_VAR_MEMDEBUG;
-#else
-/* we provide a fake do-nothing function here to avoid compiler warnings */
-void curl_memdebug(void) {}
-#endif /* VMS */
-#endif /* CURLDEBUG */
diff --git a/Utilities/cmcurl/memdebug.h b/Utilities/cmcurl/memdebug.h
deleted file mode 100644
index a4ce7e59a..000000000
--- a/Utilities/cmcurl/memdebug.h
+++ /dev/null
@@ -1,125 +0,0 @@
-#ifdef CURLDEBUG
-#ifndef _CURL_MEDEBUG_H
-#define _CURL_MEDEBUG_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-/*
- * CAUTION: this header is designed to work when included by the app-side
- * as well as the library. Do not mix with library internals!
- */
-
-#include "setup.h"
-
-#include <curl/curl.h>
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif
-
-#define logfile curl_debuglogfile
-
-extern FILE *logfile;
-
-/* memory functions */
-CURL_EXTERN void *curl_domalloc(size_t size, int line, const char *source);
-CURL_EXTERN void *curl_docalloc(size_t elements, size_t size, int line, const char *source);
-CURL_EXTERN void *curl_dorealloc(void *ptr, size_t size, int line, const char *source);
-CURL_EXTERN void curl_dofree(void *ptr, int line, const char *source);
-CURL_EXTERN char *curl_dostrdup(const char *str, int line, const char *source);
-CURL_EXTERN void curl_memdebug(const char *logname);
-CURL_EXTERN void curl_memlimit(long limit);
-
-/* file descriptor manipulators */
-CURL_EXTERN int curl_socket(int domain, int type, int protocol, int line , const char *);
-CURL_EXTERN int curl_sclose(int sockfd, int, const char *source);
-CURL_EXTERN int curl_accept(int s, void *addr, void *addrlen,
- int line, const char *source);
-
-/* FILE functions */
-CURL_EXTERN FILE *curl_fopen(const char *file, const char *mode, int line,
- const char *source);
-CURL_EXTERN int curl_fclose(FILE *file, int line, const char *source);
-
-#ifndef MEMDEBUG_NODEFINES
-
-/* Set this symbol on the command-line, recompile all lib-sources */
-#undef strdup
-#define strdup(ptr) curl_dostrdup(ptr, __LINE__, __FILE__)
-#define malloc(size) curl_domalloc(size, __LINE__, __FILE__)
-#define calloc(nbelem,size) curl_docalloc(nbelem, size, __LINE__, __FILE__)
-#define realloc(ptr,size) curl_dorealloc(ptr, size, __LINE__, __FILE__)
-#define free(ptr) curl_dofree(ptr, __LINE__, __FILE__)
-
-#define socket(domain,type,protocol)\
- curl_socket(domain,type,protocol,__LINE__,__FILE__)
-#undef accept /* for those with accept as a macro */
-#define accept(sock,addr,len)\
- curl_accept(sock,addr,len,__LINE__,__FILE__)
-
-#if defined(getaddrinfo) && defined(__osf__)
-/* OSF/1 and Tru64 have getaddrinfo as a define already, so we cannot define
- our macro as for other platforms. Instead, we redefine the new name they
- define getaddrinfo to become! */
-#define ogetaddrinfo(host,serv,hint,res) \
- curl_dogetaddrinfo(host,serv,hint,res,__LINE__,__FILE__)
-#else
-#undef getaddrinfo
-#define getaddrinfo(host,serv,hint,res) \
- curl_dogetaddrinfo(host,serv,hint,res,__LINE__,__FILE__)
-#endif
-
-#ifdef HAVE_GETNAMEINFO
-#undef getnameinfo
-#define getnameinfo(sa,salen,host,hostlen,serv,servlen,flags) \
- curl_dogetnameinfo(sa,salen,host,hostlen,serv,servlen,flags, __LINE__, \
- __FILE__)
-#endif
-
-#undef freeaddrinfo
-#define freeaddrinfo(data) \
- curl_dofreeaddrinfo(data,__LINE__,__FILE__)
-
-/* sclose is probably already defined, redefine it! */
-#undef sclose
-#define sclose(sockfd) curl_sclose(sockfd,__LINE__,__FILE__)
-/* ares-adjusted define: */
-#undef closesocket
-#define closesocket(sockfd) curl_sclose(sockfd,__LINE__,__FILE__)
-
-#undef fopen
-#define fopen(file,mode) curl_fopen(file,mode,__LINE__,__FILE__)
-#define fclose(file) curl_fclose(file,__LINE__,__FILE__)
-
-#endif /* MEMDEBUG_NODEFINES */
-
-#endif /* _CURL_MEDEBUG_H */
-#endif /* CURLDEBUG */
diff --git a/Utilities/cmcurl/memory.h b/Utilities/cmcurl/memory.h
deleted file mode 100644
index 076d20a28..000000000
--- a/Utilities/cmcurl/memory.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef _CURL_MEMORY_H
-#define _CURL_MEMORY_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include <curl/curl.h> /* for the typedefs */
-
-extern curl_malloc_callback Curl_cmalloc;
-extern curl_free_callback Curl_cfree;
-extern curl_realloc_callback Curl_crealloc;
-extern curl_strdup_callback Curl_cstrdup;
-extern curl_calloc_callback Curl_ccalloc;
-
-#ifndef CURLDEBUG
-/* Only do this define-mania if we're not using the memdebug system, as that
- has preference on this magic. */
-#undef strdup
-#define strdup(ptr) Curl_cstrdup(ptr)
-#undef malloc
-#define malloc(size) Curl_cmalloc(size)
-#undef calloc
-#define calloc(nbelem,size) Curl_ccalloc(nbelem, size)
-#undef realloc
-#define realloc(ptr,size) Curl_crealloc(ptr, size)
-#undef free
-#define free(ptr) Curl_cfree(ptr)
-
-#endif
-
-#endif /* _CURL_MEMORY_H */
diff --git a/Utilities/cmcurl/mprintf.c b/Utilities/cmcurl/mprintf.c
deleted file mode 100644
index 8b2f3d07e..000000000
--- a/Utilities/cmcurl/mprintf.c
+++ /dev/null
@@ -1,1218 +0,0 @@
-/****************************************************************************
- *
- * $Id$
- *
- *************************************************************************
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- * Purpose:
- * A merge of Bjorn Reese's format() function and Daniel's dsprintf()
- * 1.0. A full blooded printf() clone with full support for <num>$
- * everywhere (parameters, widths and precisions) including variabled
- * sized parameters (like doubles, long longs, long doubles and even
- * void * in 64-bit architectures).
- *
- * Current restrictions:
- * - Max 128 parameters
- * - No 'long double' support.
- *
- * If you ever want truly portable and good *printf() clones, the project that
- * took on from here is named 'Trio' and you find more details on the trio web
- * page at http://daniel.haxx.se/trio/
- */
-
-
-#include "setup.h"
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <string.h>
-
-#if defined(DJGPP) && (DJGPP_MINOR < 4)
-#undef _MPRINTF_REPLACE /* don't use x_was_used() here */
-#endif
-
-#include <curl/mprintf.h>
-
-#ifndef SIZEOF_SIZE_T
-/* default to 4 bytes for size_t unless defined in the config.h */
-#define SIZEOF_SIZE_T 4
-#endif
-
-#ifdef DPRINTF_DEBUG
-#define HAVE_LONGLONG
-#define LONG_LONG long long
-#define ENABLE_64BIT
-#endif
-
-#include "memory.h"
-/* The last #include file should be: */
-#include "memdebug.h"
-
-#define BUFFSIZE 256 /* buffer for long-to-str and float-to-str calcs */
-#define MAX_PARAMETERS 128 /* lame static limit */
-
-#undef TRUE
-#undef FALSE
-#undef BOOL
-#ifdef __cplusplus
-# define TRUE true
-# define FALSE false
-# define BOOL bool
-#else
-# define TRUE ((char)(1 == 1))
-# define FALSE ((char)(0 == 1))
-# define BOOL char
-#endif
-
-#ifdef _AMIGASF
-# undef FORMAT_INT
-#endif
-
-/* Lower-case digits. */
-static const char lower_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
-
-/* Upper-case digits. */
-static const char upper_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-
-#define OUTCHAR(x) \
- do{ \
- if(stream((unsigned char)(x), (FILE *)data) != -1) \
- done++; \
- else \
- return done; /* return immediately on failure */ \
- } while(0)
-
-/* Data type to read from the arglist */
-typedef enum {
- FORMAT_UNKNOWN = 0,
- FORMAT_STRING,
- FORMAT_PTR,
- FORMAT_INT,
- FORMAT_INTPTR,
- FORMAT_LONG,
- FORMAT_LONGLONG,
- FORMAT_DOUBLE,
- FORMAT_LONGDOUBLE,
- FORMAT_WIDTH /* For internal use */
-} FormatType;
-
-/* convertion and display flags */
-enum {
- FLAGS_NEW = 0,
- FLAGS_SPACE = 1<<0,
- FLAGS_SHOWSIGN = 1<<1,
- FLAGS_LEFT = 1<<2,
- FLAGS_ALT = 1<<3,
- FLAGS_SHORT = 1<<4,
- FLAGS_LONG = 1<<5,
- FLAGS_LONGLONG = 1<<6,
- FLAGS_LONGDOUBLE = 1<<7,
- FLAGS_PAD_NIL = 1<<8,
- FLAGS_UNSIGNED = 1<<9,
- FLAGS_OCTAL = 1<<10,
- FLAGS_HEX = 1<<11,
- FLAGS_UPPER = 1<<12,
- FLAGS_WIDTH = 1<<13, /* '*' or '*<num>$' used */
- FLAGS_WIDTHPARAM = 1<<14, /* width PARAMETER was specified */
- FLAGS_PREC = 1<<15, /* precision was specified */
- FLAGS_PRECPARAM = 1<<16, /* precision PARAMETER was specified */
- FLAGS_CHAR = 1<<17, /* %c story */
- FLAGS_FLOATE = 1<<18, /* %e or %E */
- FLAGS_FLOATG = 1<<19 /* %g or %G */
-};
-
-typedef struct {
- FormatType type;
- int flags;
- long width; /* width OR width parameter number */
- long precision; /* precision OR precision parameter number */
- union {
- char *str;
- void *ptr;
- long num;
-#ifdef ENABLE_64BIT
- LONG_LONG lnum;
-#endif
- double dnum;
- } data;
-} va_stack_t;
-
-struct nsprintf {
- char *buffer;
- size_t length;
- size_t max;
-};
-
-struct asprintf {
- char *buffer; /* allocated buffer */
- size_t len; /* length of string */
- size_t alloc; /* length of alloc */
- bool fail; /* TRUE if an alloc has failed and thus the output is not
- the complete data */
-};
-
-int curl_msprintf(char *buffer, const char *format, ...);
-
-static long dprintf_DollarString(char *input, char **end)
-{
- int number=0;
- while(ISDIGIT(*input)) {
- number *= 10;
- number += *input-'0';
- input++;
- }
- if(number && ('$'==*input++)) {
- *end = input;
- return number;
- }
- return 0;
-}
-
-static BOOL dprintf_IsQualifierNoDollar(char c)
-{
- switch (c) {
- case '-': case '+': case ' ': case '#': case '.':
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- case 'h': case 'l': case 'L': case 'z': case 'q':
- case '*': case 'O':
- return TRUE;
- default:
- return FALSE;
- }
-}
-
-#ifdef DPRINTF_DEBUG2
-int dprintf_Pass1Report(va_stack_t *vto, int max)
-{
- int i;
- char buffer[128];
- int bit;
- int flags;
-
- for(i=0; i<max; i++) {
- char *type;
- switch(vto[i].type) {
- case FORMAT_UNKNOWN:
- type = "unknown";
- break;
- case FORMAT_STRING:
- type ="string";
- break;
- case FORMAT_PTR:
- type ="pointer";
- break;
- case FORMAT_INT:
- type = "int";
- break;
- case FORMAT_LONG:
- type = "long";
- break;
- case FORMAT_LONGLONG:
- type = "long long";
- break;
- case FORMAT_DOUBLE:
- type = "double";
- break;
- case FORMAT_LONGDOUBLE:
- type = "long double";
- break;
- }
-
-
- buffer[0]=0;
-
- for(bit=0; bit<31; bit++) {
- flags = vto[i].flags & (1<<bit);
-
- if(flags & FLAGS_SPACE)
- strcat(buffer, "space ");
- else if(flags & FLAGS_SHOWSIGN)
- strcat(buffer, "plus ");
- else if(flags & FLAGS_LEFT)
- strcat(buffer, "left ");
- else if(flags & FLAGS_ALT)
- strcat(buffer, "alt ");
- else if(flags & FLAGS_SHORT)
- strcat(buffer, "short ");
- else if(flags & FLAGS_LONG)
- strcat(buffer, "long ");
- else if(flags & FLAGS_LONGLONG)
- strcat(buffer, "longlong ");
- else if(flags & FLAGS_LONGDOUBLE)
- strcat(buffer, "longdouble ");
- else if(flags & FLAGS_PAD_NIL)
- strcat(buffer, "padnil ");
- else if(flags & FLAGS_UNSIGNED)
- strcat(buffer, "unsigned ");
- else if(flags & FLAGS_OCTAL)
- strcat(buffer, "octal ");
- else if(flags & FLAGS_HEX)
- strcat(buffer, "hex ");
- else if(flags & FLAGS_UPPER)
- strcat(buffer, "upper ");
- else if(flags & FLAGS_WIDTH)
- strcat(buffer, "width ");
- else if(flags & FLAGS_WIDTHPARAM)
- strcat(buffer, "widthparam ");
- else if(flags & FLAGS_PREC)
- strcat(buffer, "precision ");
- else if(flags & FLAGS_PRECPARAM)
- strcat(buffer, "precparam ");
- else if(flags & FLAGS_CHAR)
- strcat(buffer, "char ");
- else if(flags & FLAGS_FLOATE)
- strcat(buffer, "floate ");
- else if(flags & FLAGS_FLOATG)
- strcat(buffer, "floatg ");
- }
- printf("REPORT: %d. %s [%s]\n", i, type, buffer);
-
- }
-
-
-}
-#endif
-
-/******************************************************************
- *
- * Pass 1:
- * Create an index with the type of each parameter entry and its
- * value (may vary in size)
- *
- ******************************************************************/
-
-static long dprintf_Pass1(char *format, va_stack_t *vto, char **endpos,
- va_list arglist)
-{
- char *fmt = format;
- int param_num = 0;
- long this_param;
- long width;
- long precision;
- int flags;
- long max_param=0;
- long i;
-
- while (*fmt) {
- if (*fmt++ == '%') {
- if (*fmt == '%') {
- fmt++;
- continue; /* while */
- }
-
- flags = FLAGS_NEW;
-
- /* Handle the positional case (N$) */
-
- param_num++;
-
- this_param = dprintf_DollarString(fmt, &fmt);
- if (0 == this_param)
- /* we got no positional, get the next counter */
- this_param = param_num;
-
- if (this_param > max_param)
- max_param = this_param;
-
- /*
- * The parameter with number 'i' should be used. Next, we need
- * to get SIZE and TYPE of the parameter. Add the information
- * to our array.
- */
-
- width = 0;
- precision = 0;
-
- /* Handle the flags */
-
- while (dprintf_IsQualifierNoDollar(*fmt)) {
- switch (*fmt++) {
- case ' ':
- flags |= FLAGS_SPACE;
- break;
- case '+':
- flags |= FLAGS_SHOWSIGN;
- break;
- case '-':
- flags |= FLAGS_LEFT;
- flags &= ~FLAGS_PAD_NIL;
- break;
- case '#':
- flags |= FLAGS_ALT;
- break;
- case '.':
- flags |= FLAGS_PREC;
- if ('*' == *fmt) {
- /* The precision is picked from a specified parameter */
-
- flags |= FLAGS_PRECPARAM;
- fmt++;
- param_num++;
-
- i = dprintf_DollarString(fmt, &fmt);
- if (i)
- precision = i;
- else
- precision = param_num;
-
- if (precision > max_param)
- max_param = precision;
- }
- else {
- flags |= FLAGS_PREC;
- precision = strtol(fmt, &fmt, 10);
- }
- break;
- case 'h':
- flags |= FLAGS_SHORT;
- break;
- case 'l':
- if (flags & FLAGS_LONG)
- flags |= FLAGS_LONGLONG;
- else
- flags |= FLAGS_LONG;
- break;
- case 'L':
- flags |= FLAGS_LONGDOUBLE;
- break;
- case 'q':
- flags |= FLAGS_LONGLONG;
- break;
- case 'z':
- /* the code below generates a warning if -Wunreachable-code is
- used */
-#if SIZEOF_SIZE_T>4
- flags |= FLAGS_LONGLONG;
-#else
- flags |= FLAGS_LONG;
-#endif
- break;
- case 'O':
-#if SIZEOF_CURL_OFF_T > 4
- flags |= FLAGS_LONGLONG;
-#else
- flags |= FLAGS_LONG;
-#endif
- break;
- case '0':
- if (!(flags & FLAGS_LEFT))
- flags |= FLAGS_PAD_NIL;
- /* FALLTHROUGH */
- case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- flags |= FLAGS_WIDTH;
- width = strtol(fmt-1, &fmt, 10);
- break;
- case '*': /* Special case */
- flags |= FLAGS_WIDTHPARAM;
- param_num++;
-
- i = dprintf_DollarString(fmt, &fmt);
- if(i)
- width = i;
- else
- width = param_num;
- if(width > max_param)
- max_param=width;
- break;
- default:
- break;
- }
- } /* switch */
-
- /* Handle the specifier */
-
- i = this_param - 1;
-
- switch (*fmt) {
- case 'S':
- flags |= FLAGS_ALT;
- /* FALLTHROUGH */
- case 's':
- vto[i].type = FORMAT_STRING;
- break;
- case 'n':
- vto[i].type = FORMAT_INTPTR;
- break;
- case 'p':
- vto[i].type = FORMAT_PTR;
- break;
- case 'd': case 'i':
- vto[i].type = FORMAT_INT;
- break;
- case 'u':
- vto[i].type = FORMAT_INT;
- flags |= FLAGS_UNSIGNED;
- break;
- case 'o':
- vto[i].type = FORMAT_INT;
- flags |= FLAGS_OCTAL;
- break;
- case 'x':
- vto[i].type = FORMAT_INT;
- flags |= FLAGS_HEX;
- break;
- case 'X':
- vto[i].type = FORMAT_INT;
- flags |= FLAGS_HEX|FLAGS_UPPER;
- break;
- case 'c':
- vto[i].type = FORMAT_INT;
- flags |= FLAGS_CHAR;
- break;
- case 'f':
- vto[i].type = FORMAT_DOUBLE;
- break;
- case 'e':
- vto[i].type = FORMAT_DOUBLE;
- flags |= FLAGS_FLOATE;
- break;
- case 'E':
- vto[i].type = FORMAT_DOUBLE;
- flags |= FLAGS_FLOATE|FLAGS_UPPER;
- break;
- case 'g':
- vto[i].type = FORMAT_DOUBLE;
- flags |= FLAGS_FLOATG;
- break;
- case 'G':
- vto[i].type = FORMAT_DOUBLE;
- flags |= FLAGS_FLOATG|FLAGS_UPPER;
- break;
- default:
- vto[i].type = FORMAT_UNKNOWN;
- break;
- } /* switch */
-
- vto[i].flags = flags;
- vto[i].width = width;
- vto[i].precision = precision;
-
- if (flags & FLAGS_WIDTHPARAM) {
- /* we have the width specified from a parameter, so we make that
- parameter's info setup properly */
- vto[i].width = width - 1;
- i = width - 1;
- vto[i].type = FORMAT_WIDTH;
- vto[i].flags = FLAGS_NEW;
- vto[i].precision = vto[i].width = 0; /* can't use width or precision
- of width! */
- }
- if (flags & FLAGS_PRECPARAM) {
- /* we have the precision specified from a parameter, so we make that
- parameter's info setup properly */
- vto[i].precision = precision - 1;
- i = precision - 1;
- vto[i].type = FORMAT_WIDTH;
- vto[i].flags = FLAGS_NEW;
- vto[i].precision = vto[i].width = 0; /* can't use width or precision
- of width! */
- }
- *endpos++ = fmt + 1; /* end of this sequence */
- }
- }
-
-#ifdef DPRINTF_DEBUG2
- dprintf_Pass1Report(vto, max_param);
-#endif
-
- /* Read the arg list parameters into our data list */
- for (i=0; i<max_param; i++) {
- if ((i + 1 < max_param) && (vto[i + 1].type == FORMAT_WIDTH))
- {
- /* Width/precision arguments must be read before the main argument
- * they are attached to
- */
- vto[i + 1].data.num = va_arg(arglist, int);
- }
-
- switch (vto[i].type)
- {
- case FORMAT_STRING:
- vto[i].data.str = va_arg(arglist, char *);
- break;
-
- case FORMAT_INTPTR:
- case FORMAT_UNKNOWN:
- case FORMAT_PTR:
- vto[i].data.ptr = va_arg(arglist, void *);
- break;
-
- case FORMAT_INT:
-#ifdef ENABLE_64BIT
- if(vto[i].flags & FLAGS_LONGLONG)
- vto[i].data.lnum = va_arg(arglist, LONG_LONG);
- else
-#endif
- if(vto[i].flags & FLAGS_LONG)
- vto[i].data.num = va_arg(arglist, long);
- else
- vto[i].data.num = va_arg(arglist, int);
- break;
-
- case FORMAT_DOUBLE:
- vto[i].data.dnum = va_arg(arglist, double);
- break;
-
- case FORMAT_WIDTH:
- /* Argument has been read. Silently convert it into an integer
- * for later use
- */
- vto[i].type = FORMAT_INT;
- break;
-
- default:
- break;
- }
- }
-
- return max_param;
-
-}
-
-static int dprintf_formatf(
- void *data, /* untouched by format(), just sent to the stream() function in
- the second argument */
- /* function pointer called for each output character */
- int (*stream)(int, FILE *),
- const char *format, /* %-formatted string */
- va_list ap_save) /* list of parameters */
-{
- /* Base-36 digits for numbers. */
- const char *digits = lower_digits;
-
- /* Pointer into the format string. */
- char *f;
-
- /* Number of characters written. */
- int done = 0;
-
- long param; /* current parameter to read */
- long param_num=0; /* parameter counter */
-
- va_stack_t vto[MAX_PARAMETERS];
- char *endpos[MAX_PARAMETERS];
- char **end;
-
- char work[BUFFSIZE];
-
- va_stack_t *p;
-
- /* Do the actual %-code parsing */
- dprintf_Pass1((char *)format, vto, endpos, ap_save);
-
- end = &endpos[0]; /* the initial end-position from the list dprintf_Pass1()
- created for us */
-
- f = (char *)format;
- while (*f != '\0') {
- /* Format spec modifiers. */
- char alt;
-
- /* Width of a field. */
- long width;
-
- /* Precision of a field. */
- long prec;
-
- /* Decimal integer is negative. */
- char is_neg;
-
- /* Base of a number to be written. */
- long base;
-
- /* Integral values to be written. */
-#ifdef ENABLE_64BIT
- unsigned LONG_LONG num;
-#else
- unsigned long num;
-#endif
- long signed_num;
-
- if (*f != '%') {
- /* This isn't a format spec, so write everything out until the next one
- OR end of string is reached. */
- do {
- OUTCHAR(*f);
- } while(*++f && ('%' != *f));
- continue;
- }
-
- ++f;
-
- /* Check for "%%". Note that although the ANSI standard lists
- '%' as a conversion specifier, it says "The complete format
- specification shall be `%%'," so we can avoid all the width
- and precision processing. */
- if (*f == '%') {
- ++f;
- OUTCHAR('%');
- continue;
- }
-
- /* If this is a positional parameter, the position must follow imediately
- after the %, thus create a %<num>$ sequence */
- param=dprintf_DollarString(f, &f);
-
- if(!param)
- param = param_num;
- else
- --param;
-
- param_num++; /* increase this always to allow "%2$s %1$s %s" and then the
- third %s will pick the 3rd argument */
-
- p = &vto[param];
-
- /* pick up the specified width */
- if(p->flags & FLAGS_WIDTHPARAM)
- width = vto[p->width].data.num;
- else
- width = p->width;
-
- /* pick up the specified precision */
- if(p->flags & FLAGS_PRECPARAM)
- prec = vto[p->precision].data.num;
- else if(p->flags & FLAGS_PREC)
- prec = p->precision;
- else
- prec = -1;
-
- alt = (p->flags & FLAGS_ALT)?TRUE:FALSE;
-
- switch (p->type) {
- case FORMAT_INT:
- num = p->data.num;
- if(p->flags & FLAGS_CHAR) {
- /* Character. */
- if (!(p->flags & FLAGS_LEFT))
- while (--width > 0)
- OUTCHAR(' ');
- OUTCHAR((char) num);
- if (p->flags & FLAGS_LEFT)
- while (--width > 0)
- OUTCHAR(' ');
- break;
- }
- if(p->flags & FLAGS_UNSIGNED) {
- /* Decimal unsigned integer. */
- base = 10;
- goto unsigned_number;
- }
- if(p->flags & FLAGS_OCTAL) {
- /* Octal unsigned integer. */
- base = 8;
- goto unsigned_number;
- }
- if(p->flags & FLAGS_HEX) {
- /* Hexadecimal unsigned integer. */
-
- digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits;
- base = 16;
- goto unsigned_number;
- }
-
- /* Decimal integer. */
- base = 10;
-
-#ifdef ENABLE_64BIT
- if(p->flags & FLAGS_LONGLONG) {
- /* long long */
- is_neg = p->data.lnum < 0;
- num = is_neg ? (- p->data.lnum) : p->data.lnum;
- }
- else
-#endif
- {
- signed_num = (long) num;
- is_neg = signed_num < 0;
- num = is_neg ? (- signed_num) : signed_num;
- }
- goto number;
-
- unsigned_number:
- /* Unsigned number of base BASE. */
- is_neg = 0;
-
- number:
- /* Number of base BASE. */
- {
- char *workend = &work[sizeof(work) - 1];
- char *w;
-
- /* Supply a default precision if none was given. */
- if (prec == -1)
- prec = 1;
-
- /* Put the number in WORK. */
- w = workend;
- while (num > 0) {
- *w-- = digits[num % base];
- num /= base;
- }
- width -= (long)(workend - w);
- prec -= (long)(workend - w);
-
- if (alt && base == 8 && prec <= 0) {
- *w-- = '0';
- --width;
- }
-
- if (prec > 0) {
- width -= prec;
- while (prec-- > 0)
- *w-- = '0';
- }
-
- if (alt && base == 16)
- width -= 2;
-
- if (is_neg || (p->flags & FLAGS_SHOWSIGN) || (p->flags & FLAGS_SPACE))
- --width;
-
- if (!(p->flags & FLAGS_LEFT) && !(p->flags & FLAGS_PAD_NIL))
- while (width-- > 0)
- OUTCHAR(' ');
-
- if (is_neg)
- OUTCHAR('-');
- else if (p->flags & FLAGS_SHOWSIGN)
- OUTCHAR('+');
- else if (p->flags & FLAGS_SPACE)
- OUTCHAR(' ');
-
- if (alt && base == 16) {
- OUTCHAR('0');
- if(p->flags & FLAGS_UPPER)
- OUTCHAR('X');
- else
- OUTCHAR('x');
- }
-
- if (!(p->flags & FLAGS_LEFT) && (p->flags & FLAGS_PAD_NIL))
- while (width-- > 0)
- OUTCHAR('0');
-
- /* Write the number. */
- while (++w <= workend) {
- OUTCHAR(*w);
- }
-
- if (p->flags & FLAGS_LEFT)
- while (width-- > 0)
- OUTCHAR(' ');
- }
- break;
-
- case FORMAT_STRING:
- /* String. */
- {
- static const char null[] = "(nil)";
- const char *str;
- size_t len;
-
- str = (char *) p->data.str;
- if ( str == NULL) {
- /* Write null[] if there's space. */
- if (prec == -1 || prec >= (long) sizeof(null) - 1) {
- str = null;
- len = sizeof(null) - 1;
- /* Disable quotes around (nil) */
- p->flags &= (~FLAGS_ALT);
- }
- else {
- str = "";
- len = 0;
- }
- }
- else
- len = strlen(str);
-
- if (prec != -1 && (size_t) prec < len)
- len = prec;
- width -= (long)len;
-
- if (p->flags & FLAGS_ALT)
- OUTCHAR('"');
-
- if (!(p->flags&FLAGS_LEFT))
- while (width-- > 0)
- OUTCHAR(' ');
-
- while (len-- > 0)
- OUTCHAR(*str++);
- if (p->flags&FLAGS_LEFT)
- while (width-- > 0)
- OUTCHAR(' ');
-
- if (p->flags & FLAGS_ALT)
- OUTCHAR('"');
- }
- break;
-
- case FORMAT_PTR:
- /* Generic pointer. */
- {
- void *ptr;
- ptr = (void *) p->data.ptr;
- if (ptr != NULL) {
- /* If the pointer is not NULL, write it as a %#x spec. */
- base = 16;
- digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits;
- alt = 1;
- num = (size_t) ptr;
- is_neg = 0;
- goto number;
- }
- else {
- /* Write "(nil)" for a nil pointer. */
- static const char strnil[] = "(nil)";
- const char *point;
-
- width -= sizeof(strnil) - 1;
- if (p->flags & FLAGS_LEFT)
- while (width-- > 0)
- OUTCHAR(' ');
- for (point = strnil; *point != '\0'; ++point)
- OUTCHAR(*point);
- if (! (p->flags & FLAGS_LEFT))
- while (width-- > 0)
- OUTCHAR(' ');
- }
- }
- break;
-
- case FORMAT_DOUBLE:
- {
- char formatbuf[32]="%";
- char *fptr;
- size_t left = sizeof(formatbuf)-strlen(formatbuf);
- int len;
-
- width = -1;
- if (p->flags & FLAGS_WIDTH)
- width = p->width;
- else if (p->flags & FLAGS_WIDTHPARAM)
- width = vto[p->width].data.num;
-
- prec = -1;
- if (p->flags & FLAGS_PREC)
- prec = p->precision;
- else if (p->flags & FLAGS_PRECPARAM)
- prec = vto[p->precision].data.num;
-
- if (p->flags & FLAGS_LEFT)
- strcat(formatbuf, "-");
- if (p->flags & FLAGS_SHOWSIGN)
- strcat(formatbuf, "+");
- if (p->flags & FLAGS_SPACE)
- strcat(formatbuf, " ");
- if (p->flags & FLAGS_ALT)
- strcat(formatbuf, "#");
-
- fptr=&formatbuf[strlen(formatbuf)];
-
- if(width >= 0) {
- /* RECURSIVE USAGE */
- len = curl_msnprintf(fptr, left, "%ld", width);
- fptr += len;
- left -= len;
- }
- if(prec >= 0) {
- /* RECURSIVE USAGE */
- len = curl_msnprintf(fptr, left, ".%ld", prec);
- fptr += len;
- left -= len;
- }
- if (p->flags & FLAGS_LONG)
- *fptr++ = 'l';
-
- if (p->flags & FLAGS_FLOATE)
- *fptr++ = p->flags&FLAGS_UPPER ? 'E':'e';
- else if (p->flags & FLAGS_FLOATG)
- *fptr++ = p->flags & FLAGS_UPPER ? 'G' : 'g';
- else
- *fptr++ = 'f';
-
- *fptr = 0; /* and a final zero termination */
-
- /* NOTE NOTE NOTE!! Not all sprintf() implementations returns number
- of output characters */
- (sprintf)(work, formatbuf, p->data.dnum);
-
- for(fptr=work; *fptr; fptr++)
- OUTCHAR(*fptr);
- }
- break;
-
- case FORMAT_INTPTR:
- /* Answer the count of characters written. */
-#ifdef ENABLE_64BIT
- if (p->flags & FLAGS_LONGLONG)
- *(LONG_LONG *) p->data.ptr = (LONG_LONG)done;
- else
-#endif
- if (p->flags & FLAGS_LONG)
- *(long *) p->data.ptr = (long)done;
- else if (!(p->flags & FLAGS_SHORT))
- *(int *) p->data.ptr = (int)done;
- else
- *(short *) p->data.ptr = (short)done;
- break;
-
- default:
- break;
- }
- f = *end++; /* goto end of %-code */
-
- }
- return done;
-}
-
-/* fputc() look-alike */
-static int addbyter(int output, FILE *data)
-{
- struct nsprintf *infop=(struct nsprintf *)data;
- unsigned char outc = (unsigned char)output;
-
- if(infop->length < infop->max) {
- /* only do this if we haven't reached max length yet */
- infop->buffer[0] = outc; /* store */
- infop->buffer++; /* increase pointer */
- infop->length++; /* we are now one byte larger */
- return outc; /* fputc() returns like this on success */
- }
- return -1;
-}
-
-int curl_mvsnprintf(char *buffer, size_t maxlength, const char *format,
- va_list ap_save)
-{
- int retcode;
- struct nsprintf info;
-
- info.buffer = buffer;
- info.length = 0;
- info.max = maxlength;
-
- retcode = dprintf_formatf(&info, addbyter, format, ap_save);
- if(info.max) {
- /* we terminate this with a zero byte */
- if(info.max == info.length)
- /* we're at maximum, scrap the last letter */
- info.buffer[-1] = 0;
- else
- info.buffer[0] = 0;
- }
- return retcode;
-}
-
-int curl_msnprintf(char *buffer, size_t maxlength, const char *format, ...)
-{
- int retcode;
- va_list ap_save; /* argument pointer */
- va_start(ap_save, format);
- retcode = curl_mvsnprintf(buffer, maxlength, format, ap_save);
- va_end(ap_save);
- return retcode;
-}
-
-/* fputc() look-alike */
-static int alloc_addbyter(int output, FILE *data)
-{
- struct asprintf *infop=(struct asprintf *)data;
- unsigned char outc = (unsigned char)output;
-
- if(!infop->buffer) {
- infop->buffer=(char *)malloc(32);
- if(!infop->buffer) {
- infop->fail = TRUE;
- return -1; /* fail */
- }
- infop->alloc = 32;
- infop->len =0;
- }
- else if(infop->len+1 >= infop->alloc) {
- char *newptr;
-
- newptr = (char *)realloc(infop->buffer, infop->alloc*2);
-
- if(!newptr) {
- infop->fail = TRUE;
- return -1;
- }
- infop->buffer = newptr;
- infop->alloc *= 2;
- }
-
- infop->buffer[ infop->len ] = outc;
-
- infop->len++;
-
- return outc; /* fputc() returns like this on success */
-}
-
-char *curl_maprintf(const char *format, ...)
-{
- va_list ap_save; /* argument pointer */
- int retcode;
- struct asprintf info;
-
- info.buffer = NULL;
- info.len = 0;
- info.alloc = 0;
- info.fail = FALSE;
-
- va_start(ap_save, format);
- retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
- va_end(ap_save);
- if((-1 == retcode) || info.fail) {
- if(info.alloc)
- free(info.buffer);
- return NULL;
- }
- if(info.alloc) {
- info.buffer[info.len] = 0; /* we terminate this with a zero byte */
- return info.buffer;
- }
- else
- return strdup("");
-}
-
-char *curl_mvaprintf(const char *format, va_list ap_save)
-{
- int retcode;
- struct asprintf info;
-
- info.buffer = NULL;
- info.len = 0;
- info.alloc = 0;
- info.fail = FALSE;
-
- retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
- if((-1 == retcode) || info.fail) {
- if(info.alloc)
- free(info.buffer);
- return NULL;
- }
-
- if(info.alloc) {
- info.buffer[info.len] = 0; /* we terminate this with a zero byte */
- return info.buffer;
- }
- else
- return strdup("");
-}
-
-static int storebuffer(int output, FILE *data)
-{
- char **buffer = (char **)data;
- unsigned char outc = (unsigned char)output;
- **buffer = outc;
- (*buffer)++;
- return outc; /* act like fputc() ! */
-}
-
-int curl_msprintf(char *buffer, const char *format, ...)
-{
- va_list ap_save; /* argument pointer */
- int retcode;
- va_start(ap_save, format);
- retcode = dprintf_formatf(&buffer, storebuffer, format, ap_save);
- va_end(ap_save);
- *buffer=0; /* we terminate this with a zero byte */
- return retcode;
-}
-
-int curl_mprintf(const char *format, ...)
-{
- int retcode;
- va_list ap_save; /* argument pointer */
- va_start(ap_save, format);
-
- retcode = dprintf_formatf(stdout, fputc, format, ap_save);
- va_end(ap_save);
- return retcode;
-}
-
-int curl_mfprintf(FILE *whereto, const char *format, ...)
-{
- int retcode;
- va_list ap_save; /* argument pointer */
- va_start(ap_save, format);
- retcode = dprintf_formatf(whereto, fputc, format, ap_save);
- va_end(ap_save);
- return retcode;
-}
-
-int curl_mvsprintf(char *buffer, const char *format, va_list ap_save)
-{
- int retcode;
- retcode = dprintf_formatf(&buffer, storebuffer, format, ap_save);
- *buffer=0; /* we terminate this with a zero byte */
- return retcode;
-}
-
-int curl_mvprintf(const char *format, va_list ap_save)
-{
- return dprintf_formatf(stdout, fputc, format, ap_save);
-}
-
-int curl_mvfprintf(FILE *whereto, const char *format, va_list ap_save)
-{
- return dprintf_formatf(whereto, fputc, format, ap_save);
-}
-
-#ifdef DPRINTF_DEBUG
-int main()
-{
- char buffer[129];
- char *ptr;
-#ifdef ENABLE_64BIT
- long long one=99;
- long long two=100;
- long long test = 0x1000000000LL;
- curl_mprintf("%lld %lld %lld\n", one, two, test);
-#endif
-
- curl_mprintf("%3d %5d\n", 10, 1998);
-
- ptr=curl_maprintf("test this then baby %s%s%s%s%s%s %d %d %d loser baby get a hit in yer face now!", "", "pretty long string pretty long string pretty long string pretty long string pretty long string", "/", "/", "/", "pretty long string", 1998, 1999, 2001);
-
- puts(ptr);
-
- memset(ptr, 55, strlen(ptr)+1);
-
- free(ptr);
-
-#if 1
- curl_mprintf(buffer, "%s %s %d", "daniel", "stenberg", 19988);
- puts(buffer);
-
- curl_mfprintf(stderr, "%s %#08x\n", "dummy", 65);
-
- printf("%s %#08x\n", "dummy", 65);
- {
- double tryout = 3.14156592;
- curl_mprintf(buffer, "%.2g %G %f %e %E", tryout, tryout, tryout, tryout, tryout);
- puts(buffer);
- printf("%.2g %G %f %e %E\n", tryout, tryout, tryout, tryout, tryout);
- }
-#endif
-
- return 0;
-}
-
-#endif
diff --git a/Utilities/cmcurl/multi.c b/Utilities/cmcurl/multi.c
deleted file mode 100644
index b501f296f..000000000
--- a/Utilities/cmcurl/multi.c
+++ /dev/null
@@ -1,1988 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include <curl/curl.h>
-
-#include "urldata.h"
-#include "transfer.h"
-#include "url.h"
-#include "connect.h"
-#include "progress.h"
-#include "memory.h"
-#include "easyif.h"
-#include "multiif.h"
-#include "sendf.h"
-#include "timeval.h"
-
-/* The last #include file should be: */
-#include "memdebug.h"
-
-struct Curl_message {
- /* the 'CURLMsg' is the part that is visible to the external user */
- struct CURLMsg extmsg;
- struct Curl_message *next;
-};
-
-typedef enum {
- CURLM_STATE_INIT, /* start in this state */
- CURLM_STATE_CONNECT, /* resolve/connect has been sent off */
- CURLM_STATE_WAITRESOLVE, /* awaiting the resolve to finalize */
- CURLM_STATE_WAITCONNECT, /* awaiting the connect to finalize */
- CURLM_STATE_PROTOCONNECT, /* completing the protocol-specific connect
- phase */
- CURLM_STATE_WAITDO, /* wait for our turn to send the request */
- CURLM_STATE_DO, /* start send off the request (part 1) */
- CURLM_STATE_DOING, /* sending off the request (part 1) */
- CURLM_STATE_DO_MORE, /* send off the request (part 2) */
- CURLM_STATE_DO_DONE, /* done sending off request */
- CURLM_STATE_WAITPERFORM, /* wait for our turn to read the response */
- CURLM_STATE_PERFORM, /* transfer data */
- CURLM_STATE_TOOFAST, /* wait because limit-rate exceeded */
- CURLM_STATE_DONE, /* post data transfer operation */
- CURLM_STATE_COMPLETED, /* operation complete */
- CURLM_STATE_CANCELLED, /* cancelled */
-
- CURLM_STATE_LAST /* not a true state, never use this */
-} CURLMstate;
-
-/* we support N sockets per easy handle. Set the corresponding bit to what
- action we should wait for */
-#define MAX_SOCKSPEREASYHANDLE 5
-#define GETSOCK_READABLE (0x00ff)
-#define GETSOCK_WRITABLE (0xff00)
-
-struct closure {
- struct closure *next; /* a simple one-way list of structs */
- struct SessionHandle *easy_handle;
-};
-
-struct Curl_one_easy {
- /* first, two fields for the linked list of these */
- struct Curl_one_easy *next;
- struct Curl_one_easy *prev;
-
- struct SessionHandle *easy_handle; /* the easy handle for this unit */
- struct connectdata *easy_conn; /* the "unit's" connection */
-
- CURLMstate state; /* the handle's state */
- CURLcode result; /* previous result */
-
- struct Curl_message *msg; /* A pointer to one single posted message.
- Cleanup should be done on this pointer NOT on
- the linked list in Curl_multi. This message
- will be deleted when this handle is removed
- from the multi-handle */
- int msg_num; /* number of messages left in 'msg' to return */
-
- /* Array with the plain socket numbers this handle takes care of, in no
- particular order. Note that all sockets are added to the sockhash, where
- the state etc are also kept. This array is mostly used to detect when a
- socket is to be removed from the hash. See singlesocket(). */
- curl_socket_t sockets[MAX_SOCKSPEREASYHANDLE];
- int numsocks;
-};
-
-#define CURL_MULTI_HANDLE 0x000bab1e
-
-#define GOOD_MULTI_HANDLE(x) \
- ((x)&&(((struct Curl_multi *)x)->type == CURL_MULTI_HANDLE))
-#define GOOD_EASY_HANDLE(x) \
- (((struct SessionHandle *)x)->magic == CURLEASY_MAGIC_NUMBER)
-
-/* This is the struct known as CURLM on the outside */
-struct Curl_multi {
- /* First a simple identifier to easier detect if a user mix up
- this multi handle with an easy handle. Set this to CURL_MULTI_HANDLE. */
- long type;
-
- /* We have a linked list with easy handles */
- struct Curl_one_easy easy;
-
- int num_easy; /* amount of entries in the linked list above. */
- int num_msgs; /* amount of messages in the easy handles */
- int num_alive; /* amount of easy handles that are added but have not yet
- reached COMPLETE state */
-
- /* callback function and user data pointer for the *socket() API */
- curl_socket_callback socket_cb;
- void *socket_userp;
-
- /* Hostname cache */
- struct curl_hash *hostcache;
-
- /* timetree points to the splay-tree of time nodes to figure out expire
- times of all currently set timers */
- struct Curl_tree *timetree;
-
- /* 'sockhash' is the lookup hash for socket descriptor => easy handles (note
- the pluralis form, there can be more than one easy handle waiting on the
- same actual socket) */
- struct curl_hash *sockhash;
-
- /* Whether pipelining is enabled for this multi handle */
- bool pipelining_enabled;
-
- /* shared connection cache */
- struct conncache *connc;
-
- /* list of easy handles kept around for doing nice connection closures */
- struct closure *closure;
-
- /* timer callback and user data pointer for the *socket() API */
- curl_multi_timer_callback timer_cb;
- void *timer_userp;
- time_t timer_lastcall; /* the fixed time for the timeout for the previous
- callback */
-};
-
-static bool multi_conn_using(struct Curl_multi *multi,
- struct SessionHandle *data);
-static void singlesocket(struct Curl_multi *multi,
- struct Curl_one_easy *easy);
-static void add_closure(struct Curl_multi *multi,
- struct SessionHandle *data);
-static int update_timer(struct Curl_multi *multi);
-
-#ifdef CURLDEBUG
-static const char *statename[]={
- "INIT",
- "CONNECT",
- "WAITRESOLVE",
- "WAITCONNECT",
- "PROTOCONNECT",
- "WAITDO",
- "DO",
- "DOING",
- "DO_MORE",
- "DO_DONE",
- "WAITPERFORM",
- "PERFORM",
- "TOOFAST",
- "DONE",
- "COMPLETED",
- "CANCELLED"
-};
-
-void curl_multi_dump(CURLM *multi_handle);
-#endif
-
-/* always use this function to change state, to make debugging easier */
-static void multistate(struct Curl_one_easy *easy, CURLMstate state)
-{
-#ifdef CURLDEBUG
- long index = -1;
-#endif
- CURLMstate oldstate = easy->state;
-
- if(oldstate == state)
- /* don't bother when the new state is the same as the old state */
- return;
-
- easy->state = state;
-
-#ifdef CURLDEBUG
- if(easy->state > CURLM_STATE_CONNECT &&
- easy->state < CURLM_STATE_COMPLETED)
- index = easy->easy_conn->connectindex;
-
- infof(easy->easy_handle,
- "STATE: %s => %s handle %p; (connection #%ld) \n",
- statename[oldstate], statename[easy->state],
- (char *)easy, index);
-#endif
- if(state == CURLM_STATE_COMPLETED)
- /* changing to COMPLETED means there's one less easy handle 'alive' */
- easy->easy_handle->multi->num_alive--;
-}
-
-/*
- * We add one of these structs to the sockhash for a particular socket
- */
-
-struct Curl_sh_entry {
- struct SessionHandle *easy;
- time_t timestamp;
- long inuse;
- int action; /* what action READ/WRITE this socket waits for */
- curl_socket_t socket; /* mainly to ease debugging */
- void *socketp; /* settable by users with curl_multi_assign() */
-};
-/* bits for 'action' having no bits means this socket is not expecting any
- action */
-#define SH_READ 1
-#define SH_WRITE 2
-
-/* make sure this socket is present in the hash for this handle */
-static struct Curl_sh_entry *sh_addentry(struct curl_hash *sh,
- curl_socket_t s,
- struct SessionHandle *data)
-{
- struct Curl_sh_entry *there =
- Curl_hash_pick(sh, (char *)&s, sizeof(curl_socket_t));
- struct Curl_sh_entry *check;
-
- if(there)
- /* it is present, return fine */
- return there;
-
- /* not present, add it */
- check = calloc(sizeof(struct Curl_sh_entry), 1);
- if(!check)
- return NULL; /* major failure */
- check->easy = data;
- check->socket = s;
-
- /* make/add new hash entry */
- if(NULL == Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) {
- free(check);
- return NULL; /* major failure */
- }
-
- return check; /* things are good in sockhash land */
-}
-
-
-/* delete the given socket + handle from the hash */
-static void sh_delentry(struct curl_hash *sh, curl_socket_t s)
-{
- struct Curl_sh_entry *there =
- Curl_hash_pick(sh, (char *)&s, sizeof(curl_socket_t));
-
- if(there) {
- /* this socket is in the hash */
- /* We remove the hash entry. (This'll end up in a call to
- sh_freeentry().) */
- Curl_hash_delete(sh, (char *)&s, sizeof(curl_socket_t));
- }
-}
-
-/*
- * free a sockhash entry
- */
-static void sh_freeentry(void *freethis)
-{
- struct Curl_sh_entry *p = (struct Curl_sh_entry *) freethis;
-
- free(p);
-}
-
-/*
- * sh_init() creates a new socket hash and returns the handle for it.
- *
- * Quote from README.multi_socket:
- *
- * "Some tests at 7000 and 9000 connections showed that the socket hash lookup
- * is somewhat of a bottle neck. Its current implementation may be a bit too
- * limiting. It simply has a fixed-size array, and on each entry in the array
- * it has a linked list with entries. So the hash only checks which list to
- * scan through. The code I had used so for used a list with merely 7 slots
- * (as that is what the DNS hash uses) but with 7000 connections that would
- * make an average of 1000 nodes in each list to run through. I upped that to
- * 97 slots (I believe a prime is suitable) and noticed a significant speed
- * increase. I need to reconsider the hash implementation or use a rather
- * large default value like this. At 9000 connections I was still below 10us
- * per call."
- *
- */
-static struct curl_hash *sh_init(void)
-{
- return Curl_hash_alloc(97, sh_freeentry);
-}
-
-CURLM *curl_multi_init(void)
-{
- struct Curl_multi *multi = (void *)calloc(sizeof(struct Curl_multi), 1);
-
- if(!multi)
- return NULL;
-
- multi->type = CURL_MULTI_HANDLE;
-
- multi->hostcache = Curl_mk_dnscache();
- if(!multi->hostcache) {
- /* failure, free mem and bail out */
- free(multi);
- return NULL;
- }
-
- multi->sockhash = sh_init();
- if(!multi->sockhash) {
- /* failure, free mem and bail out */
- Curl_hash_destroy(multi->hostcache);
- free(multi);
- return NULL;
- }
-
- multi->connc = Curl_mk_connc(CONNCACHE_MULTI, -1);
- if(!multi->connc) {
- Curl_hash_destroy(multi->hostcache);
- free(multi);
- return NULL;
- }
-
- return (CURLM *) multi;
-}
-
-CURLMcode curl_multi_add_handle(CURLM *multi_handle,
- CURL *easy_handle)
-{
- struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
- struct Curl_one_easy *easy;
- struct closure *cl;
- struct closure *prev=NULL;
-
- /* First, make some basic checks that the CURLM handle is a good handle */
- if(!GOOD_MULTI_HANDLE(multi))
- return CURLM_BAD_HANDLE;
-
- /* Verify that we got a somewhat good easy handle too */
- if(!GOOD_EASY_HANDLE(easy_handle))
- return CURLM_BAD_EASY_HANDLE;
-
- /* Prevent users to add the same handle more than once! */
- if(((struct SessionHandle *)easy_handle)->multi)
- /* possibly we should create a new unique error code for this condition */
- return CURLM_BAD_EASY_HANDLE;
-
- /* Now, time to add an easy handle to the multi stack */
- easy = (struct Curl_one_easy *)calloc(sizeof(struct Curl_one_easy), 1);
- if(!easy)
- return CURLM_OUT_OF_MEMORY;
-
- cl = multi->closure;
- while(cl) {
- struct closure *next = cl->next;
- if(cl->easy_handle == (struct SessionHandle *)easy_handle) {
- /* remove this handle from the closure list */
- free(cl);
- if(prev)
- prev->next = next;
- else
- multi->closure = next;
- break; /* no need to continue since this handle can only be present once
- in the list */
- }
- cl = next;
- }
-
- /* set the easy handle */
- easy->easy_handle = easy_handle;
- multistate(easy, CURLM_STATE_INIT);
-
- /* for multi interface connections, we share DNS cache automatically if the
- easy handle's one is currently private. */
- if (easy->easy_handle->dns.hostcache &&
- (easy->easy_handle->dns.hostcachetype == HCACHE_PRIVATE)) {
- Curl_hash_destroy(easy->easy_handle->dns.hostcache);
- easy->easy_handle->dns.hostcache = NULL;
- easy->easy_handle->dns.hostcachetype = HCACHE_NONE;
- }
-
- if (!easy->easy_handle->dns.hostcache ||
- (easy->easy_handle->dns.hostcachetype == HCACHE_NONE)) {
- easy->easy_handle->dns.hostcache = multi->hostcache;
- easy->easy_handle->dns.hostcachetype = HCACHE_MULTI;
- }
-
- if(easy->easy_handle->state.connc) {
- if(easy->easy_handle->state.connc->type == CONNCACHE_PRIVATE) {
- /* kill old private version */
- Curl_rm_connc(easy->easy_handle->state.connc);
- /* point out our shared one instead */
- easy->easy_handle->state.connc = multi->connc;
- }
- /* else it is already using multi? */
- }
- else
- /* point out our shared one */
- easy->easy_handle->state.connc = multi->connc;
-
- /* Make sure the type is setup correctly */
- easy->easy_handle->state.connc->type = CONNCACHE_MULTI;
-
- /* We add this new entry first in the list. We make our 'next' point to the
- previous next and our 'prev' point back to the 'first' struct */
- easy->next = multi->easy.next;
- easy->prev = &multi->easy;
-
- /* make 'easy' the first node in the chain */
- multi->easy.next = easy;
-
- /* if there was a next node, make sure its 'prev' pointer links back to
- the new node */
- if(easy->next)
- easy->next->prev = easy;
-
- Curl_easy_addmulti(easy_handle, multi_handle);
-
- /* make the SessionHandle struct refer back to this struct */
- easy->easy_handle->set.one_easy = easy;
-
- /* increase the node-counter */
- multi->num_easy++;
-
- if((multi->num_easy * 4) > multi->connc->num) {
- /* We want the connection cache to have plenty room. Before we supported
- the shared cache every single easy handle had 5 entries in their cache
- by default. */
- CURLcode res = Curl_ch_connc(easy_handle, multi->connc,
- multi->connc->num*4);
- if(res != CURLE_OK)
- /* TODO: we need to do some cleaning up here! */
- return CURLM_OUT_OF_MEMORY;
- }
-
- /* increase the alive-counter */
- multi->num_alive++;
-
- update_timer(multi);
- return CURLM_OK;
-}
-
-#if 0
-/* Debug-function, used like this:
- *
- * Curl_hash_print(multi->sockhash, debug_print_sock_hash);
- *
- * Enable the hash print function first by editing hash.c
- */
-static void debug_print_sock_hash(void *p)
-{
- struct Curl_sh_entry *sh = (struct Curl_sh_entry *)p;
-
- fprintf(stderr, " [easy %p/magic %x/socket %d]",
- (void *)sh->easy, sh->easy->magic, sh->socket);
-}
-#endif
-
-CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
- CURL *curl_handle)
-{
- struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
- struct Curl_one_easy *easy;
-
- /* First, make some basic checks that the CURLM handle is a good handle */
- if(!GOOD_MULTI_HANDLE(multi))
- return CURLM_BAD_HANDLE;
-
- /* Verify that we got a somewhat good easy handle too */
- if(!GOOD_EASY_HANDLE(curl_handle))
- return CURLM_BAD_EASY_HANDLE;
-
- /* scan through the list and remove the 'curl_handle' */
- easy = multi->easy.next;
- while(easy) {
- if(easy->easy_handle == (struct SessionHandle *)curl_handle)
- break;
- easy=easy->next;
- }
-
- if(easy) {
- bool premature = (bool)(easy->state != CURLM_STATE_COMPLETED);
-
- /* If the 'state' is not INIT or COMPLETED, we might need to do something
- nice to put the easy_handle in a good known state when this returns. */
- if(premature)
- /* this handle is "alive" so we need to count down the total number of
- alive connections when this is removed */
- multi->num_alive--;
-
- if (easy->easy_handle->state.is_in_pipeline &&
- easy->state > CURLM_STATE_DO) {
- /* If the handle is in a pipeline and has finished sending off its
- request, we need to remember the fact that we want to remove this
- handle but do the actual removal at a later time */
- easy->easy_handle->state.cancelled = TRUE;
- return CURLM_OK;
- }
-
- /* The timer must be shut down before easy->multi is set to NULL,
- else the timenode will remain in the splay tree after
- curl_easy_cleanup is called. */
- Curl_expire(easy->easy_handle, 0);
-
- if(easy->easy_handle->dns.hostcachetype == HCACHE_MULTI) {
- /* clear out the usage of the shared DNS cache */
- easy->easy_handle->dns.hostcache = NULL;
- easy->easy_handle->dns.hostcachetype = HCACHE_NONE;
- }
-
- /* if we have a connection we must call Curl_done() here so that we
- don't leave a half-baked one around */
- if(easy->easy_conn) {
- /* Set up the association right */
- easy->easy_conn->data = easy->easy_handle;
-
- /* Curl_done() clears the conn->data field to lose the association
- between the easy handle and the connection */
- Curl_done(&easy->easy_conn, easy->result, premature);
-
- if(easy->easy_conn)
- /* the connection is still alive, set back the association to enable
- the check below to trigger TRUE */
- easy->easy_conn->data = easy->easy_handle;
- }
-
- /* If this easy_handle was the last one in charge for one or more
- connections a the shared connection cache, we might need to keep this
- handle around until either A) the connection is closed and killed
- properly, or B) another easy_handle uses the connection.
-
- The reason why we need to have a easy_handle associated with a live
- connection is simply that some connections will need a handle to get
- closed down properly. Currently, the only connections that need to keep
- a easy_handle handle around are using FTP(S). Such connections have
- the PROT_CLOSEACTION bit set.
-
- Thus, we need to check for all connections in the shared cache that
- points to this handle and are using PROT_CLOSEACTION. If there's any,
- we need to add this handle to the list of "easy handles kept around for
- nice connection closures".
- */
- if(multi_conn_using(multi, easy->easy_handle)) {
- /* There's at least one connection using this handle so we must keep
- this handle around. We also keep the connection cache pointer
- pointing to the shared one since that will be used on close as
- well. */
- easy->easy_handle->state.shared_conn = multi;
-
- /* this handle is still being used by a shared connection cache and
- thus we leave it around for now */
- add_closure(multi, easy->easy_handle);
- }
-
- if(easy->easy_handle->state.connc->type == CONNCACHE_MULTI) {
- /* if this was using the shared connection cache we clear the pointer
- to that since we're not part of that handle anymore */
- easy->easy_handle->state.connc = NULL;
-
- /* and modify the connectindex since this handle can't point to the
- connection cache anymore */
- if(easy->easy_conn)
- easy->easy_conn->connectindex = -1;
- }
-
- /* change state without using multistate(), only to make singlesocket() do
- what we want */
- easy->state = CURLM_STATE_COMPLETED;
- singlesocket(multi, easy); /* to let the application know what sockets
- that vanish with this handle */
-
- Curl_easy_addmulti(easy->easy_handle, NULL); /* clear the association
- to this multi handle */
-
- /* make the previous node point to our next */
- if(easy->prev)
- easy->prev->next = easy->next;
- /* make our next point to our previous node */
- if(easy->next)
- easy->next->prev = easy->prev;
-
- easy->easy_handle->set.one_easy = NULL; /* detached */
-
- /* NOTE NOTE NOTE
- We do not touch the easy handle here! */
- if (easy->msg)
- free(easy->msg);
- free(easy);
-
- multi->num_easy--; /* one less to care about now */
-
- update_timer(multi);
- return CURLM_OK;
- }
- else
- return CURLM_BAD_EASY_HANDLE; /* twasn't found */
-}
-
-bool Curl_multi_canPipeline(struct Curl_multi* multi)
-{
- return multi->pipelining_enabled;
-}
-
-static int waitconnect_getsock(struct connectdata *conn,
- curl_socket_t *sock,
- int numsocks)
-{
- if(!numsocks)
- return GETSOCK_BLANK;
-
- sock[0] = conn->sock[FIRSTSOCKET];
- return GETSOCK_WRITESOCK(0);
-}
-
-static int domore_getsock(struct connectdata *conn,
- curl_socket_t *sock,
- int numsocks)
-{
- if(!numsocks)
- return GETSOCK_BLANK;
-
- /* When in DO_MORE state, we could be either waiting for us
- to connect to a remote site, or we could wait for that site
- to connect to us. It makes a difference in the way: if we
- connect to the site we wait for the socket to become writable, if
- the site connects to us we wait for it to become readable */
- sock[0] = conn->sock[SECONDARYSOCKET];
-
- return GETSOCK_WRITESOCK(0);
-}
-
-/* returns bitmapped flags for this handle and its sockets */
-static int multi_getsock(struct Curl_one_easy *easy,
- curl_socket_t *socks, /* points to numsocks number
- of sockets */
- int numsocks)
-{
- if (easy->easy_handle->state.pipe_broke) {
- return 0;
- }
-
- if (easy->state > CURLM_STATE_CONNECT &&
- easy->state < CURLM_STATE_COMPLETED) {
- /* Set up ownership correctly */
- easy->easy_conn->data = easy->easy_handle;
- }
-
- switch(easy->state) {
- case CURLM_STATE_TOOFAST: /* returns 0, so will not select. */
- default:
- /* this will get called with CURLM_STATE_COMPLETED when a handle is
- removed */
- return 0;
-
- case CURLM_STATE_WAITRESOLVE:
- return Curl_resolv_getsock(easy->easy_conn, socks, numsocks);
-
- case CURLM_STATE_PROTOCONNECT:
- return Curl_protocol_getsock(easy->easy_conn, socks, numsocks);
-
- case CURLM_STATE_DOING:
- return Curl_doing_getsock(easy->easy_conn, socks, numsocks);
-
- case CURLM_STATE_WAITCONNECT:
- return waitconnect_getsock(easy->easy_conn, socks, numsocks);
-
- case CURLM_STATE_DO_MORE:
- return domore_getsock(easy->easy_conn, socks, numsocks);
-
- case CURLM_STATE_PERFORM:
- case CURLM_STATE_WAITPERFORM:
- return Curl_single_getsock(easy->easy_conn, socks, numsocks);
- }
-
-}
-
-CURLMcode curl_multi_fdset(CURLM *multi_handle,
- fd_set *read_fd_set, fd_set *write_fd_set,
- fd_set *exc_fd_set, int *max_fd)
-{
- /* Scan through all the easy handles to get the file descriptors set.
- Some easy handles may not have connected to the remote host yet,
- and then we must make sure that is done. */
- struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
- struct Curl_one_easy *easy;
- int this_max_fd=-1;
- curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
- int bitmap;
- int i;
- (void)exc_fd_set; /* not used */
-
- if(!GOOD_MULTI_HANDLE(multi))
- return CURLM_BAD_HANDLE;
-
- easy=multi->easy.next;
- while(easy) {
- bitmap = multi_getsock(easy, sockbunch, MAX_SOCKSPEREASYHANDLE);
-
- for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
- curl_socket_t s = CURL_SOCKET_BAD;
-
- if(bitmap & GETSOCK_READSOCK(i)) {
- FD_SET(sockbunch[i], read_fd_set);
- s = sockbunch[i];
- }
- if(bitmap & GETSOCK_WRITESOCK(i)) {
- FD_SET(sockbunch[i], write_fd_set);
- s = sockbunch[i];
- }
- if(s == CURL_SOCKET_BAD)
- /* this socket is unused, break out of loop */
- break;
- else {
- if((int)s > this_max_fd)
- this_max_fd = (int)s;
- }
- }
-
- easy = easy->next; /* check next handle */
- }
-
- *max_fd = this_max_fd;
-
- return CURLM_OK;
-}
-
-static CURLMcode multi_runsingle(struct Curl_multi *multi,
- struct Curl_one_easy *easy)
-{
- struct Curl_message *msg = NULL;
- bool connected;
- bool async;
- bool protocol_connect;
- bool dophase_done;
- bool done;
- CURLMcode result = CURLM_OK;
- struct Curl_transfer_keeper *k;
-
- do {
-
- if(!GOOD_EASY_HANDLE(easy->easy_handle))
- return CURLM_BAD_EASY_HANDLE;
-
- if (easy->easy_handle->state.pipe_broke) {
- infof(easy->easy_handle, "Pipe broke: handle 0x%x, url = %s\n",
- easy, easy->easy_handle->reqdata.path);
- if(easy->easy_handle->state.is_in_pipeline) {
- /* Head back to the CONNECT state */
- multistate(easy, CURLM_STATE_CONNECT);
- result = CURLM_CALL_MULTI_PERFORM;
- easy->result = CURLE_OK;
- } else {
- easy->result = CURLE_COULDNT_CONNECT;
- multistate(easy, CURLM_STATE_COMPLETED);
- }
-
- easy->easy_handle->state.pipe_broke = FALSE;
- easy->easy_conn = NULL;
- break;
- }
-
- if (easy->state > CURLM_STATE_CONNECT &&
- easy->state < CURLM_STATE_COMPLETED) {
- /* Make sure we set the connection's current owner */
- easy->easy_conn->data = easy->easy_handle;
- }
-
- if (CURLM_STATE_WAITCONNECT <= easy->state &&
- easy->state <= CURLM_STATE_DO &&
- easy->easy_handle->change.url_changed) {
- char *gotourl;
- Curl_posttransfer(easy->easy_handle);
-
- easy->result = Curl_done(&easy->easy_conn, CURLE_OK, FALSE);
- /* We make sure that the pipe broken flag is reset
- because in this case, it isn't an actual break */
- easy->easy_handle->state.pipe_broke = FALSE;
- if(CURLE_OK == easy->result) {
- gotourl = strdup(easy->easy_handle->change.url);
- if(gotourl) {
- easy->easy_handle->change.url_changed = FALSE;
- easy->result = Curl_follow(easy->easy_handle, gotourl, FALSE);
- if(CURLE_OK == easy->result)
- multistate(easy, CURLM_STATE_CONNECT);
- else
- free(gotourl);
- }
- else {
- easy->result = CURLE_OUT_OF_MEMORY;
- multistate(easy, CURLM_STATE_COMPLETED);
- break;
- }
- }
- }
-
- easy->easy_handle->change.url_changed = FALSE;
-
- switch(easy->state) {
- case CURLM_STATE_INIT:
- /* init this transfer. */
- easy->result=Curl_pretransfer(easy->easy_handle);
-
- if(CURLE_OK == easy->result) {
- /* after init, go CONNECT */
- multistate(easy, CURLM_STATE_CONNECT);
- result = CURLM_CALL_MULTI_PERFORM;
-
- easy->easy_handle->state.used_interface = Curl_if_multi;
- }
- break;
-
- case CURLM_STATE_CONNECT:
- /* Connect. We get a connection identifier filled in. */
- Curl_pgrsTime(easy->easy_handle, TIMER_STARTSINGLE);
- easy->result = Curl_connect(easy->easy_handle, &easy->easy_conn,
- &async, &protocol_connect);
-
- if(CURLE_OK == easy->result) {
- /* Add this handle to the send pipeline */
- Curl_addHandleToPipeline(easy->easy_handle,
- easy->easy_conn->send_pipe);
-
- if(async)
- /* We're now waiting for an asynchronous name lookup */
- multistate(easy, CURLM_STATE_WAITRESOLVE);
- else {
- /* after the connect has been sent off, go WAITCONNECT unless the
- protocol connect is already done and we can go directly to
- WAITDO! */
- result = CURLM_CALL_MULTI_PERFORM;
-
- if(protocol_connect) {
- multistate(easy, CURLM_STATE_WAITDO);
- } else {
- multistate(easy, CURLM_STATE_WAITCONNECT);
- }
- }
- }
- break;
-
- case CURLM_STATE_WAITRESOLVE:
- /* awaiting an asynch name resolve to complete */
- {
- struct Curl_dns_entry *dns = NULL;
-
- /* check if we have the name resolved by now */
- easy->result = Curl_is_resolved(easy->easy_conn, &dns);
-
- if(dns) {
- /* Perform the next step in the connection phase, and then move on
- to the WAITCONNECT state */
- easy->result = Curl_async_resolved(easy->easy_conn,
- &protocol_connect);
-
- if(CURLE_OK != easy->result)
- /* if Curl_async_resolved() returns failure, the connection struct
- is already freed and gone */
- easy->easy_conn = NULL; /* no more connection */
- else {
- /* call again please so that we get the next socket setup */
- result = CURLM_CALL_MULTI_PERFORM;
- if(protocol_connect)
- multistate(easy, CURLM_STATE_DO);
- else
- multistate(easy, CURLM_STATE_WAITCONNECT);
- }
- }
-
- if(CURLE_OK != easy->result) {
- /* failure detected */
- Curl_disconnect(easy->easy_conn); /* disconnect properly */
- easy->easy_conn = NULL; /* no more connection */
- break;
- }
- }
- break;
-
- case CURLM_STATE_WAITCONNECT:
- /* awaiting a completion of an asynch connect */
- easy->result = Curl_is_connected(easy->easy_conn,
- FIRSTSOCKET,
- &connected);
- if(connected)
- easy->result = Curl_protocol_connect(easy->easy_conn,
- &protocol_connect);
-
- if(CURLE_OK != easy->result) {
- /* failure detected */
- Curl_disconnect(easy->easy_conn); /* close the connection */
- easy->easy_conn = NULL; /* no more connection */
- break;
- }
-
- if(connected) {
- if(!protocol_connect) {
- /* We have a TCP connection, but 'protocol_connect' may be false
- and then we continue to 'STATE_PROTOCONNECT'. If protocol
- connect is TRUE, we move on to STATE_DO. */
- multistate(easy, CURLM_STATE_PROTOCONNECT);
- }
- else {
- /* after the connect has completed, go WAITDO */
- multistate(easy, CURLM_STATE_WAITDO);
-
- result = CURLM_CALL_MULTI_PERFORM;
- }
- }
- break;
-
- case CURLM_STATE_PROTOCONNECT:
- /* protocol-specific connect phase */
- easy->result = Curl_protocol_connecting(easy->easy_conn,
- &protocol_connect);
- if(protocol_connect) {
- /* after the connect has completed, go WAITDO */
- multistate(easy, CURLM_STATE_WAITDO);
- result = CURLM_CALL_MULTI_PERFORM;
- }
- else if(easy->result) {
- /* failure detected */
- Curl_posttransfer(easy->easy_handle);
- Curl_done(&easy->easy_conn, easy->result, FALSE);
- Curl_disconnect(easy->easy_conn); /* close the connection */
- easy->easy_conn = NULL; /* no more connection */
- }
- break;
-
- case CURLM_STATE_WAITDO:
- /* Wait for our turn to DO when we're pipelining requests */
-#ifdef CURLDEBUG
- infof(easy->easy_handle, "Conn %d send pipe %d inuse %d athead %d\n",
- easy->easy_conn->connectindex,
- easy->easy_conn->send_pipe->size,
- easy->easy_conn->writechannel_inuse,
- Curl_isHandleAtHead(easy->easy_handle,
- easy->easy_conn->send_pipe));
-#endif
- if (!easy->easy_conn->writechannel_inuse &&
- Curl_isHandleAtHead(easy->easy_handle,
- easy->easy_conn->send_pipe)) {
- /* Grab the channel */
- easy->easy_conn->writechannel_inuse = TRUE;
- multistate(easy, CURLM_STATE_DO);
- result = CURLM_CALL_MULTI_PERFORM;
- }
- break;
-
- case CURLM_STATE_DO:
- if(easy->easy_handle->set.connect_only) {
- /* keep connection open for application to use the socket */
- easy->easy_conn->bits.close = FALSE;
- multistate(easy, CURLM_STATE_DONE);
- easy->result = CURLE_OK;
- result = CURLM_OK;
- }
- else {
- /* Perform the protocol's DO action */
- easy->result = Curl_do(&easy->easy_conn,
- &dophase_done);
-
- if(CURLE_OK == easy->result) {
-
- if(!dophase_done) {
- /* DO was not completed in one function call, we must continue
- DOING... */
- multistate(easy, CURLM_STATE_DOING);
- result = CURLM_OK;
- }
-
- /* after DO, go DO_DONE... or DO_MORE */
- else if(easy->easy_conn->bits.do_more) {
- /* we're supposed to do more, but we need to sit down, relax
- and wait a little while first */
- multistate(easy, CURLM_STATE_DO_MORE);
- result = CURLM_OK;
- }
- else {
- /* we're done with the DO, now DO_DONE */
- easy->result = Curl_readwrite_init(easy->easy_conn);
- if(CURLE_OK == easy->result) {
- multistate(easy, CURLM_STATE_DO_DONE);
- result = CURLM_CALL_MULTI_PERFORM;
- }
- }
- }
- else {
- /* failure detected */
- Curl_posttransfer(easy->easy_handle);
- Curl_done(&easy->easy_conn, easy->result, FALSE);
- Curl_disconnect(easy->easy_conn); /* close the connection */
- easy->easy_conn = NULL; /* no more connection */
- }
- }
- break;
-
- case CURLM_STATE_DOING:
- /* we continue DOING until the DO phase is complete */
- easy->result = Curl_protocol_doing(easy->easy_conn,
- &dophase_done);
- if(CURLE_OK == easy->result) {
- if(dophase_done) {
- /* after DO, go PERFORM... or DO_MORE */
- if(easy->easy_conn->bits.do_more) {
- /* we're supposed to do more, but we need to sit down, relax
- and wait a little while first */
- multistate(easy, CURLM_STATE_DO_MORE);
- result = CURLM_OK;
- }
- else {
- /* we're done with the DO, now DO_DONE */
- easy->result = Curl_readwrite_init(easy->easy_conn);
- if(CURLE_OK == easy->result) {
- multistate(easy, CURLM_STATE_DO_DONE);
- result = CURLM_CALL_MULTI_PERFORM;
- }
- }
- } /* dophase_done */
- }
- else {
- /* failure detected */
- Curl_posttransfer(easy->easy_handle);
- Curl_done(&easy->easy_conn, easy->result, FALSE);
- Curl_disconnect(easy->easy_conn); /* close the connection */
- easy->easy_conn = NULL; /* no more connection */
- }
- break;
-
- case CURLM_STATE_DO_MORE:
- /* Ready to do more? */
- easy->result = Curl_is_connected(easy->easy_conn,
- SECONDARYSOCKET,
- &connected);
- if(connected) {
- /*
- * When we are connected, DO MORE and then go DO_DONE
- */
- easy->result = Curl_do_more(easy->easy_conn);
-
- if(CURLE_OK == easy->result)
- easy->result = Curl_readwrite_init(easy->easy_conn);
- else
- /* Remove ourselves from the send pipeline */
- Curl_removeHandleFromPipeline(easy->easy_handle,
- easy->easy_conn->send_pipe);
-
- if(CURLE_OK == easy->result) {
- multistate(easy, CURLM_STATE_DO_DONE);
- result = CURLM_CALL_MULTI_PERFORM;
- }
- }
- break;
-
- case CURLM_STATE_DO_DONE:
- /* Remove ourselves from the send pipeline */
- Curl_removeHandleFromPipeline(easy->easy_handle,
- easy->easy_conn->send_pipe);
- /* Add ourselves to the recv pipeline */
- Curl_addHandleToPipeline(easy->easy_handle,
- easy->easy_conn->recv_pipe);
- multistate(easy, CURLM_STATE_WAITPERFORM);
- result = CURLM_CALL_MULTI_PERFORM;
- break;
-
- case CURLM_STATE_WAITPERFORM:
-#ifdef CURLDEBUG
- infof(easy->easy_handle, "Conn %d recv pipe %d inuse %d athead %d\n",
- easy->easy_conn->connectindex,
- easy->easy_conn->recv_pipe->size,
- easy->easy_conn->readchannel_inuse,
- Curl_isHandleAtHead(easy->easy_handle,
- easy->easy_conn->recv_pipe));
-#endif
- /* Wait for our turn to PERFORM */
- if (!easy->easy_conn->readchannel_inuse &&
- Curl_isHandleAtHead(easy->easy_handle,
- easy->easy_conn->recv_pipe)) {
- /* Grab the channel */
- easy->easy_conn->readchannel_inuse = TRUE;
- multistate(easy, CURLM_STATE_PERFORM);
- result = CURLM_CALL_MULTI_PERFORM;
- }
- break;
-
- case CURLM_STATE_TOOFAST: /* limit-rate exceeded in either direction */
- /* if both rates are within spec, resume transfer */
- Curl_pgrsUpdate(easy->easy_conn);
- if ( ( ( easy->easy_handle->set.max_send_speed == 0 ) ||
- ( easy->easy_handle->progress.ulspeed <
- easy->easy_handle->set.max_send_speed ) ) &&
- ( ( easy->easy_handle->set.max_recv_speed == 0 ) ||
- ( easy->easy_handle->progress.dlspeed <
- easy->easy_handle->set.max_recv_speed ) )
- )
- multistate(easy, CURLM_STATE_PERFORM);
- break;
-
- case CURLM_STATE_PERFORM:
- /* check if over speed */
- if ( ( ( easy->easy_handle->set.max_send_speed > 0 ) &&
- ( easy->easy_handle->progress.ulspeed >
- easy->easy_handle->set.max_send_speed ) ) ||
- ( ( easy->easy_handle->set.max_recv_speed > 0 ) &&
- ( easy->easy_handle->progress.dlspeed >
- easy->easy_handle->set.max_recv_speed ) )
- ) {
- /* Transfer is over the speed limit. Change state. TODO: Call
- * Curl_expire() with the time left until we're targeted to be below
- * the speed limit again. */
- multistate(easy, CURLM_STATE_TOOFAST );
- break;
- }
-
- /* read/write data if it is ready to do so */
- easy->result = Curl_readwrite(easy->easy_conn, &done);
-
- k = &easy->easy_handle->reqdata.keep;
-
- if (!(k->keepon & KEEP_READ)) {
- /* We're done reading */
- easy->easy_conn->readchannel_inuse = FALSE;
- }
-
- if (!(k->keepon & KEEP_WRITE)) {
- /* We're done writing */
- easy->easy_conn->writechannel_inuse = FALSE;
- }
-
- if(easy->result) {
- /* The transfer phase returned error, we mark the connection to get
- * closed to prevent being re-used. This is becasue we can't
- * possibly know if the connection is in a good shape or not now. */
- easy->easy_conn->bits.close = TRUE;
-
- if(CURL_SOCKET_BAD != easy->easy_conn->sock[SECONDARYSOCKET]) {
- /* if we failed anywhere, we must clean up the secondary socket if
- it was used */
- sclose(easy->easy_conn->sock[SECONDARYSOCKET]);
- easy->easy_conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
- }
- Curl_posttransfer(easy->easy_handle);
- Curl_done(&easy->easy_conn, easy->result, FALSE);
- }
- else if(TRUE == done) {
- char *newurl;
- bool retry = Curl_retry_request(easy->easy_conn, &newurl);
-
- /* call this even if the readwrite function returned error */
- Curl_posttransfer(easy->easy_handle);
-
- /* When we follow redirects, must to go back to the CONNECT state */
- if(easy->easy_handle->reqdata.newurl || retry) {
- Curl_removeHandleFromPipeline(easy->easy_handle,
- easy->easy_conn->recv_pipe);
- if(!retry) {
- /* if the URL is a follow-location and not just a retried request
- then figure out the URL here */
- newurl = easy->easy_handle->reqdata.newurl;
- easy->easy_handle->reqdata.newurl = NULL;
- }
- easy->result = Curl_done(&easy->easy_conn, CURLE_OK, FALSE);
- if(easy->result == CURLE_OK)
- easy->result = Curl_follow(easy->easy_handle, newurl, retry);
- if(CURLE_OK == easy->result) {
- multistate(easy, CURLM_STATE_CONNECT);
- result = CURLM_CALL_MULTI_PERFORM;
- }
- else
- /* Since we "took it", we are in charge of freeing this on
- failure */
- free(newurl);
- }
- else {
- /* after the transfer is done, go DONE */
- multistate(easy, CURLM_STATE_DONE);
- result = CURLM_CALL_MULTI_PERFORM;
- }
- }
-
- break;
-
- case CURLM_STATE_DONE:
- /* Remove ourselves from the receive pipeline */
- Curl_removeHandleFromPipeline(easy->easy_handle,
- easy->easy_conn->recv_pipe);
- easy->easy_handle->state.is_in_pipeline = FALSE;
-
- if (easy->easy_conn->bits.stream_was_rewound) {
- /* This request read past its response boundary so we quickly
- let the other requests consume those bytes since there is no
- guarantee that the socket will become active again */
- result = CURLM_CALL_MULTI_PERFORM;
- }
-
- if (!easy->easy_handle->state.cancelled) {
- /* post-transfer command */
- easy->result = Curl_done(&easy->easy_conn, CURLE_OK, FALSE);
-
- /* after we have DONE what we're supposed to do, go COMPLETED, and
- it doesn't matter what the Curl_done() returned! */
- multistate(easy, CURLM_STATE_COMPLETED);
- }
-
- break;
-
- case CURLM_STATE_COMPLETED:
- if (easy->easy_handle->state.cancelled)
- /* Go into the CANCELLED state if we were cancelled */
- multistate(easy, CURLM_STATE_CANCELLED);
-
- /* this is a completed transfer, it is likely to still be connected */
-
- /* This node should be delinked from the list now and we should post
- an information message that we are complete. */
- break;
-
- case CURLM_STATE_CANCELLED:
- /* Cancelled transfer, wait to be cleaned up */
- break;
-
- default:
- return CURLM_INTERNAL_ERROR;
- }
-
- if(CURLM_STATE_COMPLETED != easy->state) {
- if(CURLE_OK != easy->result) {
- /*
- * If an error was returned, and we aren't in completed state now,
- * then we go to completed and consider this transfer aborted.
- */
- easy->easy_handle->state.is_in_pipeline = FALSE;
- easy->easy_handle->state.pipe_broke = FALSE;
-
- if(easy->easy_conn) {
- /* if this has a connection, unsubscribe from the pipelines */
- easy->easy_conn->writechannel_inuse = FALSE;
- easy->easy_conn->readchannel_inuse = FALSE;
- }
- multistate(easy, CURLM_STATE_COMPLETED);
- }
- }
-
- } while (easy->easy_handle->change.url_changed);
-
- if ((CURLM_STATE_COMPLETED == easy->state) && !easy->msg) {
- if(easy->easy_handle->dns.hostcachetype == HCACHE_MULTI) {
- /* clear out the usage of the shared DNS cache */
- easy->easy_handle->dns.hostcache = NULL;
- easy->easy_handle->dns.hostcachetype = HCACHE_NONE;
- }
-
- /* now add a node to the Curl_message linked list with this info */
- msg = (struct Curl_message *)malloc(sizeof(struct Curl_message));
-
- if(!msg)
- return CURLM_OUT_OF_MEMORY;
-
- msg->extmsg.msg = CURLMSG_DONE;
- msg->extmsg.easy_handle = easy->easy_handle;
- msg->extmsg.data.result = easy->result;
- msg->next = NULL;
-
- easy->msg = msg;
- easy->msg_num = 1; /* there is one unread message here */
-
- multi->num_msgs++; /* increase message counter */
- }
-
- return result;
-}
-
-
-CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
-{
- struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
- struct Curl_one_easy *easy;
- CURLMcode returncode=CURLM_OK;
- struct Curl_tree *t;
-
- if(!GOOD_MULTI_HANDLE(multi))
- return CURLM_BAD_HANDLE;
-
- easy=multi->easy.next;
- while(easy) {
- CURLMcode result;
-
- if (easy->easy_handle->state.cancelled &&
- easy->state == CURLM_STATE_CANCELLED) {
- /* Remove cancelled handles once it's safe to do so */
- Curl_multi_rmeasy(multi_handle, easy->easy_handle);
- easy->easy_handle = NULL;
- easy = easy->next;
- continue;
- }
-
- result = multi_runsingle(multi, easy);
- if(result)
- returncode = result;
-
- easy = easy->next; /* operate on next handle */
- }
-
- /*
- * Simply remove all expired timers from the splay since handles are dealt
- * with unconditionally by this function and curl_multi_timeout() requires
- * that already passed/handled expire times are removed from the splay.
- */
- do {
- struct timeval now = Curl_tvnow();
- int key = now.tv_sec; /* drop the usec part */
-
- multi->timetree = Curl_splaygetbest(key, multi->timetree, &t);
- if (t) {
- struct SessionHandle *d = t->payload;
- struct timeval* tv = &d->state.expiretime;
-
- /* clear the expire times within the handles that we remove from the
- splay tree */
- tv->tv_sec = 0;
- tv->tv_usec = 0;
- }
-
- } while(t);
-
- *running_handles = multi->num_alive;
-
- if ( CURLM_OK == returncode )
- update_timer(multi);
- return returncode;
-}
-
-/* This is called when an easy handle is cleanup'ed that is part of a multi
- handle */
-void Curl_multi_rmeasy(void *multi_handle, CURL *easy_handle)
-{
- curl_multi_remove_handle(multi_handle, easy_handle);
-}
-
-
-CURLMcode curl_multi_cleanup(CURLM *multi_handle)
-{
- struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
- struct Curl_one_easy *easy;
- struct Curl_one_easy *nexteasy;
- int i;
- struct closure *cl;
- struct closure *n;
-
- if(GOOD_MULTI_HANDLE(multi)) {
- multi->type = 0; /* not good anymore */
- Curl_hash_destroy(multi->hostcache);
- Curl_hash_destroy(multi->sockhash);
-
- /* go over all connections that have close actions */
- for(i=0; i< multi->connc->num; i++) {
- if(multi->connc->connects[i] &&
- multi->connc->connects[i]->protocol & PROT_CLOSEACTION) {
- Curl_disconnect(multi->connc->connects[i]);
- multi->connc->connects[i] = NULL;
- }
- }
- /* now walk through the list of handles we kept around only to be
- able to close connections "properly" */
- cl = multi->closure;
- while(cl) {
- cl->easy_handle->state.shared_conn = NULL; /* no more shared */
- if(cl->easy_handle->state.closed)
- /* close handle only if curl_easy_cleanup() already has been called
- for this easy handle */
- Curl_close(cl->easy_handle);
- n = cl->next;
- free(cl);
- cl= n;
- }
-
- Curl_rm_connc(multi->connc);
-
- /* remove all easy handles */
- easy = multi->easy.next;
- while(easy) {
- nexteasy=easy->next;
- if(easy->easy_handle->dns.hostcachetype == HCACHE_MULTI) {
- /* clear out the usage of the shared DNS cache */
- easy->easy_handle->dns.hostcache = NULL;
- easy->easy_handle->dns.hostcachetype = HCACHE_NONE;
- }
-
- /* Clear the pointer to the connection cache */
- easy->easy_handle->state.connc = NULL;
-
- Curl_easy_addmulti(easy->easy_handle, NULL); /* clear the association */
-
- if (easy->msg)
- free(easy->msg);
- free(easy);
- easy = nexteasy;
- }
-
- free(multi);
-
- return CURLM_OK;
- }
- else
- return CURLM_BAD_HANDLE;
-}
-
-CURLMsg *curl_multi_info_read(CURLM *multi_handle, int *msgs_in_queue)
-{
- struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
-
- *msgs_in_queue = 0; /* default to none */
-
- if(GOOD_MULTI_HANDLE(multi)) {
- struct Curl_one_easy *easy;
-
- if(!multi->num_msgs)
- return NULL; /* no messages left to return */
-
- easy=multi->easy.next;
- while(easy) {
- if(easy->msg_num) {
- easy->msg_num--;
- break;
- }
- easy = easy->next;
- }
- if(!easy)
- return NULL; /* this means internal count confusion really */
-
- multi->num_msgs--;
- *msgs_in_queue = multi->num_msgs;
-
- return &easy->msg->extmsg;
- }
- else
- return NULL;
-}
-
-/*
- * singlesocket() checks what sockets we deal with and their "action state"
- * and if we have a different state in any of those sockets from last time we
- * call the callback accordingly.
- */
-static void singlesocket(struct Curl_multi *multi,
- struct Curl_one_easy *easy)
-{
- curl_socket_t socks[MAX_SOCKSPEREASYHANDLE];
- int i;
- struct Curl_sh_entry *entry;
- curl_socket_t s;
- int num;
- unsigned int curraction;
-
- memset(&socks, 0, sizeof(socks));
- for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++)
- socks[i] = CURL_SOCKET_BAD;
-
- /* Fill in the 'current' struct with the state as it is now: what sockets to
- supervise and for what actions */
- curraction = multi_getsock(easy, socks, MAX_SOCKSPEREASYHANDLE);
-
- /* We have 0 .. N sockets already and we get to know about the 0 .. M
- sockets we should have from now on. Detect the differences, remove no
- longer supervised ones and add new ones */
-
- /* walk over the sockets we got right now */
- for(i=0; (i< MAX_SOCKSPEREASYHANDLE) &&
- (curraction & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i)));
- i++) {
- int action = CURL_POLL_NONE;
-
- s = socks[i];
-
- /* get it from the hash */
- entry = Curl_hash_pick(multi->sockhash, (char *)&s, sizeof(s));
-
- if(curraction & GETSOCK_READSOCK(i))
- action |= CURL_POLL_IN;
- if(curraction & GETSOCK_WRITESOCK(i))
- action |= CURL_POLL_OUT;
-
- if(entry) {
- /* yeps, already present so check if it has the same action set */
- if(entry->action == action)
- /* same, continue */
- continue;
- }
- else {
- /* this is a socket we didn't have before, add it! */
- entry = sh_addentry(multi->sockhash, s, easy->easy_handle);
- if(!entry)
- /* fatal */
- return;
- }
-
- multi->socket_cb(easy->easy_handle,
- s,
- action,
- multi->socket_userp,
- entry ? entry->socketp : NULL);
-
- entry->action = action; /* store the current action state */
- }
-
- num = i; /* number of sockets */
-
- /* when we've walked over all the sockets we should have right now, we must
- make sure to detect sockets that are removed */
- for(i=0; i< easy->numsocks; i++) {
- int j;
- s = easy->sockets[i];
- for(j=0; j<num; j++) {
- if(s == socks[j]) {
- /* this is still supervised */
- s = CURL_SOCKET_BAD;
- break;
- }
- }
- if(s != CURL_SOCKET_BAD) {
- /* this socket has been removed. Remove it */
-
- entry = Curl_hash_pick(multi->sockhash, (char *)&s, sizeof(s));
- if(entry) {
- /* just a precaution, this socket really SHOULD be in the hash already
- but in case it isn't, we don't have to tell the app to remove it
- either since it never got to know about it */
- multi->socket_cb(easy->easy_handle,
- s,
- CURL_POLL_REMOVE,
- multi->socket_userp,
- entry ? entry->socketp : NULL);
-
- sh_delentry(multi->sockhash, s);
- }
- }
- }
-
- memcpy(easy->sockets, socks, num*sizeof(curl_socket_t));
- easy->numsocks = num;
-}
-
-static CURLMcode multi_socket(struct Curl_multi *multi,
- bool checkall,
- curl_socket_t s,
- int *running_handles)
-{
- CURLMcode result = CURLM_OK;
- struct SessionHandle *data = NULL;
- struct Curl_tree *t;
-
- if(checkall) {
- struct Curl_one_easy *easyp;
- /* *perform() deals with running_handles on its own */
- result = curl_multi_perform(multi, running_handles);
-
- /* walk through each easy handle and do the socket state change magic
- and callbacks */
- easyp=multi->easy.next;
- while(easyp) {
- singlesocket(multi, easyp);
- easyp = easyp->next;
- }
-
- /* or should we fall-through and do the timer-based stuff? */
- return result;
- }
- else if (s != CURL_SOCKET_TIMEOUT) {
-
- struct Curl_sh_entry *entry =
- Curl_hash_pick(multi->sockhash, (char *)&s, sizeof(s));
-
- if(!entry)
- /* unmatched socket, major problemo! */
- return CURLM_BAD_SOCKET; /* better return code? */
-
- data = entry->easy;
-
- if(data->magic != CURLEASY_MAGIC_NUMBER)
- /* bad bad bad bad bad bad bad */
- return CURLM_INTERNAL_ERROR;
-
- result = multi_runsingle(multi, data->set.one_easy);
-
- if(result == CURLM_OK)
- /* get the socket(s) and check if the state has been changed since
- last */
- singlesocket(multi, data->set.one_easy);
-
- /* Now we fall-through and do the timer-based stuff, since we don't want
- to force the user to have to deal with timeouts as long as at least one
- connection in fact has traffic. */
-
- data = NULL; /* set data to NULL again to avoid calling multi_runsingle()
- in case there's no need to */
- }
-
- /*
- * The loop following here will go on as long as there are expire-times left
- * to process in the splay and 'data' will be re-assigned for every expired
- * handle we deal with.
- */
- do {
- int key;
- struct timeval now;
-
- /* the first loop lap 'data' can be NULL */
- if(data) {
- result = multi_runsingle(multi, data->set.one_easy);
-
- if(result == CURLM_OK)
- /* get the socket(s) and check if the state has been changed since
- last */
- singlesocket(multi, data->set.one_easy);
- }
-
- /* Check if there's one (more) expired timer to deal with! This function
- extracts a matching node if there is one */
-
- now = Curl_tvnow();
- key = now.tv_sec; /* drop the usec part */
-
- multi->timetree = Curl_splaygetbest(key, multi->timetree, &t);
- if(t) {
- /* assign 'data' to be the easy handle we just removed from the splay
- tree */
- data = t->payload;
- /* clear the expire time within the handle we removed from the
- splay tree */
- data->state.expiretime.tv_sec = 0;
- data->state.expiretime.tv_usec = 0;
- }
-
- } while(t);
-
- *running_handles = multi->num_alive;
- return result;
-}
-
-CURLMcode curl_multi_setopt(CURLM *multi_handle,
- CURLMoption option, ...)
-{
- struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
- CURLMcode res = CURLM_OK;
- va_list param;
-
- if(!GOOD_MULTI_HANDLE(multi))
- return CURLM_BAD_HANDLE;
-
- va_start(param, option);
-
- switch(option) {
- case CURLMOPT_SOCKETFUNCTION:
- multi->socket_cb = va_arg(param, curl_socket_callback);
- break;
- case CURLMOPT_SOCKETDATA:
- multi->socket_userp = va_arg(param, void *);
- break;
- case CURLMOPT_PIPELINING:
- multi->pipelining_enabled = (bool)(0 != va_arg(param, long));
- break;
- case CURLMOPT_TIMERFUNCTION:
- multi->timer_cb = va_arg(param, curl_multi_timer_callback);
- break;
- case CURLMOPT_TIMERDATA:
- multi->timer_userp = va_arg(param, void *);
- break;
- default:
- res = CURLM_UNKNOWN_OPTION;
- break;
- }
- va_end(param);
- return res;
-}
-
-
-CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
- int *running_handles)
-{
- CURLMcode result = multi_socket((struct Curl_multi *)multi_handle, FALSE, s,
- running_handles);
- if (CURLM_OK == result)
- update_timer((struct Curl_multi *)multi_handle);
- return result;
-}
-
-CURLMcode curl_multi_socket_all(CURLM *multi_handle, int *running_handles)
-
-{
- CURLMcode result = multi_socket((struct Curl_multi *)multi_handle,
- TRUE, CURL_SOCKET_BAD, running_handles);
- if (CURLM_OK == result)
- update_timer((struct Curl_multi *)multi_handle);
- return result;
-}
-
-static CURLMcode multi_timeout(struct Curl_multi *multi,
- long *timeout_ms)
-{
- if(multi->timetree) {
- /* we have a tree of expire times */
- struct timeval now = Curl_tvnow();
-
- /* splay the lowest to the bottom */
- multi->timetree = Curl_splay(0, multi->timetree);
-
- /* At least currently, the splay key is a time_t for the expire time */
- *timeout_ms = (multi->timetree->key - now.tv_sec) * 1000 -
- now.tv_usec/1000;
- if(*timeout_ms < 0)
- /* 0 means immediately */
- *timeout_ms = 0;
- }
- else
- *timeout_ms = -1;
-
- return CURLM_OK;
-}
-
-CURLMcode curl_multi_timeout(CURLM *multi_handle,
- long *timeout_ms)
-{
- struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
-
- /* First, make some basic checks that the CURLM handle is a good handle */
- if(!GOOD_MULTI_HANDLE(multi))
- return CURLM_BAD_HANDLE;
-
- return multi_timeout(multi, timeout_ms);
-}
-
-/*
- * Tell the application it should update its timers, if it subscribes to the
- * update timer callback.
- */
-static int update_timer(struct Curl_multi *multi)
-{
- long timeout_ms;
- if (!multi->timer_cb)
- return 0;
- if ( multi_timeout(multi, &timeout_ms) != CURLM_OK )
- return -1;
- if ( timeout_ms < 0 )
- return 0;
-
- /* When multi_timeout() is done, multi->timetree points to the node with the
- * timeout we got the (relative) time-out time for. We can thus easily check
- * if this is the same (fixed) time as we got in a previous call and then
- * avoid calling the callback again. */
- if(multi->timetree->key == multi->timer_lastcall)
- return 0;
-
- multi->timer_lastcall = multi->timetree->key;
-
- return multi->timer_cb((CURLM*)multi, timeout_ms, multi->timer_userp);
-}
-
-/* given a number of milliseconds from now to use to set the 'act before
- this'-time for the transfer, to be extracted by curl_multi_timeout() */
-void Curl_expire(struct SessionHandle *data, long milli)
-{
- struct Curl_multi *multi = data->multi;
- struct timeval *nowp = &data->state.expiretime;
- int rc;
-
- /* this is only interesting for multi-interface using libcurl, and only
- while there is still a multi interface struct remaining! */
- if(!multi)
- return;
-
- if(!milli) {
- /* No timeout, clear the time data. */
- if(nowp->tv_sec) {
- /* Since this is an cleared time, we must remove the previous entry from
- the splay tree */
- rc = Curl_splayremovebyaddr(multi->timetree,
- &data->state.timenode,
- &multi->timetree);
- if(rc)
- infof(data, "Internal error clearing splay node = %d\n", rc);
- infof(data, "Expire cleared\n");
- nowp->tv_sec = 0;
- nowp->tv_usec = 0;
- }
- }
- else {
- struct timeval set;
- int rest;
-
- set = Curl_tvnow();
- set.tv_sec += milli/1000;
- set.tv_usec += (milli%1000)*1000;
-
- rest = (int)(set.tv_usec - 1000000);
- if(rest > 0) {
- /* bigger than a full microsec */
- set.tv_sec++;
- set.tv_usec -= 1000000;
- }
-
- if(nowp->tv_sec) {
- /* This means that the struct is added as a node in the splay tree.
- Compare if the new time is earlier, and only remove-old/add-new if it
- is. */
- long diff = curlx_tvdiff(set, *nowp);
- if(diff > 0)
- /* the new expire time was later so we don't change this */
- return;
-
- /* Since this is an updated time, we must remove the previous entry from
- the splay tree first and then re-add the new value */
- rc = Curl_splayremovebyaddr(multi->timetree,
- &data->state.timenode,
- &multi->timetree);
- if(rc)
- infof(data, "Internal error removing splay node = %d\n", rc);
- }
-
- *nowp = set;
-#if 0
- infof(data, "Expire at %ld / %ld (%ldms)\n",
- (long)nowp->tv_sec, (long)nowp->tv_usec, milli);
-#endif
- data->state.timenode.payload = data;
- multi->timetree = Curl_splayinsert((int)nowp->tv_sec,
- multi->timetree,
- &data->state.timenode);
- }
-#if 0
- Curl_splayprint(multi->timetree, 0, TRUE);
-#endif
-}
-
-CURLMcode curl_multi_assign(CURLM *multi_handle,
- curl_socket_t s, void *hashp)
-{
- struct Curl_sh_entry *there = NULL;
- struct Curl_multi *multi = (struct Curl_multi *)multi_handle;
-
- if(s != CURL_SOCKET_BAD)
- there = Curl_hash_pick(multi->sockhash, (char *)&s, sizeof(curl_socket_t));
-
- if(!there)
- return CURLM_BAD_SOCKET;
-
- there->socketp = hashp;
-
- return CURLM_OK;
-}
-
-static bool multi_conn_using(struct Curl_multi *multi,
- struct SessionHandle *data)
-{
- /* any live CLOSEACTION-connections pointing to the give 'data' ? */
- int i;
-
- for(i=0; i< multi->connc->num; i++) {
- if(multi->connc->connects[i] &&
- (multi->connc->connects[i]->data == data) &&
- multi->connc->connects[i]->protocol & PROT_CLOSEACTION)
- return TRUE;
- }
-
- return FALSE;
-}
-
-/* Add the given data pointer to the list of 'closure handles' that are kept
- around only to be able to close some connections nicely - just make sure
- that this handle isn't already added, like for the cases when an easy
- handle is removed, added and removed again... */
-static void add_closure(struct Curl_multi *multi,
- struct SessionHandle *data)
-{
- int i;
- struct closure *cl = (struct closure *)calloc(sizeof(struct closure), 1);
- struct closure *p=NULL;
- struct closure *n;
- if(cl) {
- cl->easy_handle = data;
- cl->next = multi->closure;
- multi->closure = cl;
- }
-
- p = multi->closure;
- cl = p->next; /* start immediately on the second since the first is the one
- we just added and it is _very_ likely to actually exist
- used in the cache since that's the whole purpose of adding
- it to this list! */
-
- /* When adding, scan through all the other currently kept handles and see if
- there are any connections still referring to them and kill them if not. */
- while(cl) {
- bool inuse = FALSE;
- for(i=0; i< multi->connc->num; i++) {
- if(multi->connc->connects[i] &&
- (multi->connc->connects[i]->data == cl->easy_handle)) {
- inuse = TRUE;
- break;
- }
- }
-
- n = cl->next;
-
- if(!inuse) {
- /* cl->easy_handle is now killable */
- infof(data, "Delayed kill of easy handle %p\n", cl->easy_handle);
- /* unmark it as not having a connection around that uses it anymore */
- cl->easy_handle->state.shared_conn= NULL;
- Curl_close(cl->easy_handle);
- if(p)
- p->next = n;
- else
- multi->closure = n;
- free(cl);
- }
- else
- p = cl;
-
- cl = n;
- }
-
-}
-
-#ifdef CURLDEBUG
-void curl_multi_dump(CURLM *multi_handle)
-{
- struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
- struct Curl_one_easy *easy;
- int i;
- fprintf(stderr, "* Multi status: %d handles, %d alive\n",
- multi->num_easy, multi->num_alive);
- for(easy=multi->easy.next; easy; easy = easy->next) {
- if(easy->state != CURLM_STATE_COMPLETED) {
- /* only display handles that are not completed */
- fprintf(stderr, "handle %p, state %s, %d sockets\n",
- (void *)easy->easy_handle,
- statename[easy->state], easy->numsocks);
- for(i=0; i < easy->numsocks; i++) {
- curl_socket_t s = easy->sockets[i];
- struct Curl_sh_entry *entry =
- Curl_hash_pick(multi->sockhash, (char *)&s, sizeof(s));
-
- fprintf(stderr, "%d ", (int)s);
- if(!entry) {
- fprintf(stderr, "INTERNAL CONFUSION\n");
- continue;
- }
- fprintf(stderr, "[%s %s] ",
- entry->action&CURL_POLL_IN?"RECVING":"",
- entry->action&CURL_POLL_OUT?"SENDING":"");
- }
- if(easy->numsocks)
- fprintf(stderr, "\n");
- }
- }
-}
-#endif
diff --git a/Utilities/cmcurl/multiif.h b/Utilities/cmcurl/multiif.h
deleted file mode 100644
index 800aa0f5d..000000000
--- a/Utilities/cmcurl/multiif.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef __MULTIIF_H
-#define __MULTIIF_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-/*
- * Prototypes for library-wide functions provided by multi.c
- */
-void Curl_expire(struct SessionHandle *data, long milli);
-
-void Curl_multi_rmeasy(void *multi, CURL *data);
-
-bool Curl_multi_canPipeline(struct Curl_multi* multi);
-
-/* the write bits start at bit 16 for the *getsock() bitmap */
-#define GETSOCK_WRITEBITSTART 16
-
-#define GETSOCK_BLANK 0 /* no bits set */
-
-/* set the bit for the given sock number to make the bitmap for writable */
-#define GETSOCK_WRITESOCK(x) (1 << (GETSOCK_WRITEBITSTART + (x)))
-
-/* set the bit for the given sock number to make the bitmap for readable */
-#define GETSOCK_READSOCK(x) (1 << (x))
-
-#endif /* __MULTIIF_H */
diff --git a/Utilities/cmcurl/netrc.c b/Utilities/cmcurl/netrc.c
deleted file mode 100644
index 54d175989..000000000
--- a/Utilities/cmcurl/netrc.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_PWD_H
-#include <pwd.h>
-#endif
-#ifdef VMS
-#include <unixlib.h>
-#endif
-
-#include <curl/curl.h>
-#include "netrc.h"
-
-#include "strequal.h"
-#include "strtok.h"
-#include "memory.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
-#include "memdebug.h"
-
-/* Debug this single source file with:
- 'make netrc' then run './netrc'!
-
- Oh, make sure you have a .netrc file too ;-)
- */
-
-/* Get user and password from .netrc when given a machine name */
-
-enum {
- NOTHING,
- HOSTFOUND, /* the 'machine' keyword was found */
- HOSTCOMPLETE, /* the machine name following the keyword was found too */
- HOSTVALID, /* this is "our" machine! */
-
- HOSTEND /* LAST enum */
-};
-
-/* make sure we have room for at least this size: */
-#define LOGINSIZE 64
-#define PASSWORDSIZE 64
-
-/* returns -1 on failure, 0 if the host is found, 1 is the host isn't found */
-int Curl_parsenetrc(char *host,
- char *login,
- char *password,
- char *netrcfile)
-{
- FILE *file;
- int retcode=1;
- int specific_login = (login[0] != 0);
- char *home = NULL;
- bool home_alloc = FALSE;
- bool netrc_alloc = FALSE;
- int state=NOTHING;
-
- char state_login=0; /* Found a login keyword */
- char state_password=0; /* Found a password keyword */
- int state_our_login=FALSE; /* With specific_login, found *our* login name */
-
-#define NETRC DOT_CHAR "netrc"
-
-#ifdef CURLDEBUG
- {
- /* This is a hack to allow testing.
- * If compiled with --enable-debug and CURL_DEBUG_NETRC is defined,
- * then it's the path to a substitute .netrc for testing purposes *only* */
-
- char *override = curl_getenv("CURL_DEBUG_NETRC");
-
- if (override) {
- fprintf(stderr, "NETRC: overridden " NETRC " file: %s\n", override);
- netrcfile = override;
- netrc_alloc = TRUE;
- }
- }
-#endif /* CURLDEBUG */
- if(!netrcfile) {
- home = curl_getenv("HOME"); /* portable environment reader */
- if(home) {
- home_alloc = TRUE;
-#if defined(HAVE_GETPWUID) && defined(HAVE_GETEUID)
- }
- else {
- struct passwd *pw;
- pw= getpwuid(geteuid());
- if (pw) {
-#ifdef VMS
- home = decc$translate_vms(pw->pw_dir);
-#else
- home = pw->pw_dir;
-#endif
- }
-#endif
- }
-
- if(!home)
- return -1;
-
- netrcfile = curl_maprintf("%s%s%s", home, DIR_CHAR, NETRC);
- if(!netrcfile) {
- if(home_alloc)
- free(home);
- return -1;
- }
- netrc_alloc = TRUE;
- }
-
- file = fopen(netrcfile, "r");
- if(file) {
- char *tok;
- char *tok_buf;
- bool done=FALSE;
- char netrcbuffer[256];
-
- while(!done && fgets(netrcbuffer, sizeof(netrcbuffer), file)) {
- tok=strtok_r(netrcbuffer, " \t\n", &tok_buf);
- while(!done && tok) {
-
- if (login[0] && password[0]) {
- done=TRUE;
- break;
- }
-
- switch(state) {
- case NOTHING:
- if(strequal("machine", tok)) {
- /* the next tok is the machine name, this is in itself the
- delimiter that starts the stuff entered for this machine,
- after this we need to search for 'login' and
- 'password'. */
- state=HOSTFOUND;
- }
- break;
- case HOSTFOUND:
- if(strequal(host, tok)) {
- /* and yes, this is our host! */
- state=HOSTVALID;
-#ifdef _NETRC_DEBUG
- fprintf(stderr, "HOST: %s\n", tok);
-#endif
- retcode=0; /* we did find our host */
- }
- else
- /* not our host */
- state=NOTHING;
- break;
- case HOSTVALID:
- /* we are now parsing sub-keywords concerning "our" host */
- if(state_login) {
- if (specific_login) {
- state_our_login = strequal(login, tok);
- }
- else {
- strncpy(login, tok, LOGINSIZE-1);
-#ifdef _NETRC_DEBUG
- fprintf(stderr, "LOGIN: %s\n", login);
-#endif
- }
- state_login=0;
- }
- else if(state_password) {
- if (state_our_login || !specific_login) {
- strncpy(password, tok, PASSWORDSIZE-1);
-#ifdef _NETRC_DEBUG
- fprintf(stderr, "PASSWORD: %s\n", password);
-#endif
- }
- state_password=0;
- }
- else if(strequal("login", tok))
- state_login=1;
- else if(strequal("password", tok))
- state_password=1;
- else if(strequal("machine", tok)) {
- /* ok, there's machine here go => */
- state = HOSTFOUND;
- state_our_login = FALSE;
- }
- break;
- } /* switch (state) */
-
- tok = strtok_r(NULL, " \t\n", &tok_buf);
- } /* while (tok) */
- } /* while fgets() */
-
- fclose(file);
- }
-
- if(home_alloc)
- free(home);
- if(netrc_alloc)
- free(netrcfile);
-
- return retcode;
-}
-
-#ifdef _NETRC_DEBUG
-int main(int argc, char **argv)
-{
- char login[64]="";
- char password[64]="";
-
- if(argc<2)
- return -1;
-
- if(0 == ParseNetrc(argv[1], login, password)) {
- printf("HOST: %s LOGIN: %s PASSWORD: %s\n",
- argv[1], login, password);
- }
-}
-
-#endif
diff --git a/Utilities/cmcurl/netrc.h b/Utilities/cmcurl/netrc.h
deleted file mode 100644
index 939c552df..000000000
--- a/Utilities/cmcurl/netrc.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef __NETRC_H
-#define __NETRC_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-int Curl_parsenetrc(char *host,
- char *login,
- char *password,
- char *filename);
- /* Assume: password[0]=0, host[0] != 0.
- * If login[0] = 0, search for login and password within a machine section
- * in the netrc.
- * If login[0] != 0, search for password within machine and login.
- */
-#endif
diff --git a/Utilities/cmcurl/nwlib.c b/Utilities/cmcurl/nwlib.c
deleted file mode 100644
index b0eea56c7..000000000
--- a/Utilities/cmcurl/nwlib.c
+++ /dev/null
@@ -1,300 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <library.h>
-#include <netware.h>
-#include <screen.h>
-#include <nks/thread.h>
-#include <nks/synch.h>
-
-#include "memory.h"
-#include "memdebug.h"
-
-typedef struct
-{
- int _errno;
- void *twentybytes;
-} libthreaddata_t;
-
-typedef struct
-{
- int x;
- int y;
- int z;
- void *tenbytes;
- NXKey_t perthreadkey; /* if -1, no key obtained... */
- NXMutex_t *lock;
-} libdata_t;
-
-int gLibId = -1;
-void *gLibHandle = (void *) NULL;
-rtag_t gAllocTag = (rtag_t) NULL;
-NXMutex_t *gLibLock = (NXMutex_t *) NULL;
-
-/* internal library function prototypes... */
-int DisposeLibraryData ( void * );
-void DisposeThreadData ( void * );
-int GetOrSetUpData ( int id, libdata_t **data, libthreaddata_t **threaddata );
-
-
-int _NonAppStart( void *NLMHandle,
- void *errorScreen,
- const char *cmdLine,
- const char *loadDirPath,
- size_t uninitializedDataLength,
- void *NLMFileHandle,
- int (*readRoutineP)( int conn,
- void *fileHandle, size_t offset,
- size_t nbytes,
- size_t *bytesRead,
- void *buffer ),
- size_t customDataOffset,
- size_t customDataSize,
- int messageCount,
- const char **messages )
-{
- NX_LOCK_INFO_ALLOC(liblock, "Per-Application Data Lock", 0);
-
-#ifndef __GNUC__
-#pragma unused(cmdLine)
-#pragma unused(loadDirPath)
-#pragma unused(uninitializedDataLength)
-#pragma unused(NLMFileHandle)
-#pragma unused(readRoutineP)
-#pragma unused(customDataOffset)
-#pragma unused(customDataSize)
-#pragma unused(messageCount)
-#pragma unused(messages)
-#endif
-
-/*
-** Here we process our command line, post errors (to the error screen),
-** perform initializations and anything else we need to do before being able
-** to accept calls into us. If we succeed, we return non-zero and the NetWare
-** Loader will leave us up, otherwise we fail to load and get dumped.
-*/
- gAllocTag = AllocateResourceTag(NLMHandle,
- "<library-name> memory allocations",
- AllocSignature);
-
- if (!gAllocTag) {
- OutputToScreen(errorScreen, "Unable to allocate resource tag for "
- "library memory allocations.\n");
- return -1;
- }
-
- gLibId = register_library(DisposeLibraryData);
-
- if (gLibId < -1) {
- OutputToScreen(errorScreen, "Unable to register library with kernel.\n");
- return -1;
- }
-
- gLibHandle = NLMHandle;
-
- gLibLock = NXMutexAlloc(0, 0, &liblock);
-
- if (!gLibLock) {
- OutputToScreen(errorScreen, "Unable to allocate library data lock.\n");
- return -1;
- }
-
- return 0;
-}
-
-/*
-** Here we clean up any resources we allocated. Resource tags is a big part
-** of what we created, but NetWare doesn't ask us to free those.
-*/
-void _NonAppStop( void )
-{
- (void) unregister_library(gLibId);
- NXMutexFree(gLibLock);
-}
-
-/*
-** This function cannot be the first in the file for if the file is linked
-** first, then the check-unload function's offset will be nlmname.nlm+0
-** which is how to tell that there isn't one. When the check function is
-** first in the linked objects, it is ambiguous. For this reason, we will
-** put it inside this file after the stop function.
-**
-** Here we check to see if it's alright to ourselves to be unloaded. If not,
-** we return a non-zero value. Right now, there isn't any reason not to allow
-** it.
-*/
-int _NonAppCheckUnload( void )
-{
- return 0;
-}
-
-int GetOrSetUpData(int id, libdata_t **appData,
- libthreaddata_t **threadData )
-{
- int err;
- libdata_t *app_data;
- libthreaddata_t *thread_data;
- NXKey_t key;
- NX_LOCK_INFO_ALLOC(liblock, "Application Data Lock", 0);
-
- err = 0;
- thread_data = (libthreaddata_t *) NULL;
-
-/*
-** Attempt to get our data for the application calling us. This is where we
-** store whatever application-specific information we need to carry in support
-** of calling applications.
-*/
- app_data = (libdata_t *) get_app_data(id);
-
- if (!app_data) {
-/*
-** This application hasn't called us before; set up application AND per-thread
-** data. Of course, just in case a thread from this same application is calling
-** us simultaneously, we better lock our application data-creation mutex. We
-** also need to recheck for data after we acquire the lock because WE might be
-** that other thread that was too late to create the data and the first thread
-** in will have created it.
-*/
- NXLock(gLibLock);
-
- if (!(app_data = (libdata_t *) get_app_data(id))) {
- app_data = (libdata_t *) malloc(sizeof(libdata_t));
-
- if (app_data) {
- memset(app_data, 0, sizeof(libdata_t));
-
- app_data->tenbytes = malloc(10);
- app_data->lock = NXMutexAlloc(0, 0, &liblock);
-
- if (!app_data->tenbytes || !app_data->lock) {
- if (app_data->lock)
- NXMutexFree(app_data->lock);
-
- free(app_data);
- app_data = (libdata_t *) NULL;
- err = ENOMEM;
- }
-
- if (app_data) {
-/*
-** Here we burn in the application data that we were trying to get by calling
-** get_app_data(). Next time we call the first function, we'll get this data
-** we're just now setting. We also go on here to establish the per-thread data
-** for the calling thread, something we'll have to do on each application
-** thread the first time it calls us.
-*/
- err = set_app_data(gLibId, app_data);
-
- if (err) {
- free(app_data);
- app_data = (libdata_t *) NULL;
- err = ENOMEM;
- }
- else {
- /* create key for thread-specific data... */
- err = NXKeyCreate(DisposeThreadData, (void *) NULL, &key);
-
- if (err) /* (no more keys left?) */
- key = -1;
-
- app_data->perthreadkey = key;
- }
- }
- }
- }
-
- NXUnlock(gLibLock);
- }
-
- if (app_data) {
- key = app_data->perthreadkey;
-
- if (key != -1 /* couldn't create a key? no thread data */
- && !(err = NXKeyGetValue(key, (void **) &thread_data))
- && !thread_data) {
-/*
-** Allocate the per-thread data for the calling thread. Regardless of whether
-** there was already application data or not, this may be the first call by a
-** a new thread. The fact that we allocation 20 bytes on a pointer is not very
-** important, this just helps to demonstrate that we can have arbitrarily
-** complex per-thread data.
-*/
- thread_data = (libthreaddata_t *) malloc(sizeof(libthreaddata_t));
-
- if (thread_data) {
- thread_data->_errno = 0;
- thread_data->twentybytes = malloc(20);
-
- if (!thread_data->twentybytes) {
- free(thread_data);
- thread_data = (libthreaddata_t *) NULL;
- err = ENOMEM;
- }
-
- if ((err = NXKeySetValue(key, thread_data))) {
- free(thread_data->twentybytes);
- free(thread_data);
- thread_data = (libthreaddata_t *) NULL;
- }
- }
- }
- }
-
- if (appData)
- *appData = app_data;
-
- if (threadData)
- *threadData = thread_data;
-
- return err;
-}
-
-int DisposeLibraryData( void *data)
-{
- if (data) {
- void *tenbytes = ((libdata_t *) data)->tenbytes;
-
- if (tenbytes)
- free(tenbytes);
-
- free(data);
- }
-
- return 0;
-}
-
-void DisposeThreadData(void *data)
-{
- if (data) {
- void *twentybytes = ((libthreaddata_t *) data)->twentybytes;
-
- if (twentybytes)
- free(twentybytes);
-
- free(data);
- }
-}
diff --git a/Utilities/cmcurl/parsedate.c b/Utilities/cmcurl/parsedate.c
deleted file mode 100644
index ef91585e5..000000000
--- a/Utilities/cmcurl/parsedate.c
+++ /dev/null
@@ -1,425 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-/*
- A brief summary of the date string formats this parser groks:
-
- RFC 2616 3.3.1
-
- Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123
- Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
- Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format
-
- we support dates without week day name:
-
- 06 Nov 1994 08:49:37 GMT
- 06-Nov-94 08:49:37 GMT
- Nov 6 08:49:37 1994
-
- without the time zone:
-
- 06 Nov 1994 08:49:37
- 06-Nov-94 08:49:37
-
- weird order:
-
- 1994 Nov 6 08:49:37 (GNU date fails)
- GMT 08:49:37 06-Nov-94 Sunday
- 94 6 Nov 08:49:37 (GNU date fails)
-
- time left out:
-
- 1994 Nov 6
- 06-Nov-94
- Sun Nov 6 94
-
- unusual separators:
-
- 1994.Nov.6
- Sun/Nov/6/94/GMT
-
- commonly used time zone names:
-
- Sun, 06 Nov 1994 08:49:37 CET
- 06 Nov 1994 08:49:37 EST
-
- time zones specified using RFC822 style:
-
- Sun, 12 Sep 2004 15:05:58 -0700
- Sat, 11 Sep 2004 21:32:11 +0200
-
- compact numerical date strings:
-
- 20040912 15:05:58 -0700
- 20040911 +0200
-
-*/
-#include "setup.h"
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h> /* for strtol() */
-#endif
-
-#include <curl/curl.h>
-
-static time_t Curl_parsedate(const char *date);
-
-const char * const Curl_wkday[] =
-{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
-static const char * const weekday[] =
-{ "Monday", "Tuesday", "Wednesday", "Thursday",
- "Friday", "Saturday", "Sunday" };
-const char * const Curl_month[]=
-{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
-
-struct tzinfo {
- const char *name;
- int offset; /* +/- in minutes */
-};
-
-/* Here's a bunch of frequently used time zone names. These were supported
- by the old getdate parser. */
-#define tDAYZONE -60 /* offset for daylight savings time */
-static const struct tzinfo tz[]= {
- {"GMT", 0}, /* Greenwich Mean */
- {"UTC", 0}, /* Universal (Coordinated) */
- {"WET", 0}, /* Western European */
- {"BST", 0 tDAYZONE}, /* British Summer */
- {"WAT", 60}, /* West Africa */
- {"AST", 240}, /* Atlantic Standard */
- {"ADT", 240 tDAYZONE}, /* Atlantic Daylight */
- {"EST", 300}, /* Eastern Standard */
- {"EDT", 300 tDAYZONE}, /* Eastern Daylight */
- {"CST", 360}, /* Central Standard */
- {"CDT", 360 tDAYZONE}, /* Central Daylight */
- {"MST", 420}, /* Mountain Standard */
- {"MDT", 420 tDAYZONE}, /* Mountain Daylight */
- {"PST", 480}, /* Pacific Standard */
- {"PDT", 480 tDAYZONE}, /* Pacific Daylight */
- {"YST", 540}, /* Yukon Standard */
- {"YDT", 540 tDAYZONE}, /* Yukon Daylight */
- {"HST", 600}, /* Hawaii Standard */
- {"HDT", 600 tDAYZONE}, /* Hawaii Daylight */
- {"CAT", 600}, /* Central Alaska */
- {"AHST", 600}, /* Alaska-Hawaii Standard */
- {"NT", 660}, /* Nome */
- {"IDLW", 720}, /* International Date Line West */
- {"CET", -60}, /* Central European */
- {"MET", -60}, /* Middle European */
- {"MEWT", -60}, /* Middle European Winter */
- {"MEST", -60 tDAYZONE}, /* Middle European Summer */
- {"CEST", -60 tDAYZONE}, /* Central European Summer */
- {"MESZ", -60 tDAYZONE}, /* Middle European Summer */
- {"FWT", -60}, /* French Winter */
- {"FST", -60 tDAYZONE}, /* French Summer */
- {"EET", -120}, /* Eastern Europe, USSR Zone 1 */
- {"WAST", -420}, /* West Australian Standard */
- {"WADT", -420 tDAYZONE}, /* West Australian Daylight */
- {"CCT", -480}, /* China Coast, USSR Zone 7 */
- {"JST", -540}, /* Japan Standard, USSR Zone 8 */
- {"EAST", -600}, /* Eastern Australian Standard */
- {"EADT", -600 tDAYZONE}, /* Eastern Australian Daylight */
- {"GST", -600}, /* Guam Standard, USSR Zone 9 */
- {"NZT", -720}, /* New Zealand */
- {"NZST", -720}, /* New Zealand Standard */
- {"NZDT", -720 tDAYZONE}, /* New Zealand Daylight */
- {"IDLE", -720}, /* International Date Line East */
-};
-
-/* returns:
- -1 no day
- 0 monday - 6 sunday
-*/
-
-static int checkday(char *check, size_t len)
-{
- int i;
- const char * const *what;
- bool found= FALSE;
- if(len > 3)
- what = &weekday[0];
- else
- what = &Curl_wkday[0];
- for(i=0; i<7; i++) {
- if(curl_strequal(check, what[0])) {
- found=TRUE;
- break;
- }
- what++;
- }
- return found?i:-1;
-}
-
-static int checkmonth(char *check)
-{
- int i;
- const char * const *what;
- bool found= FALSE;
-
- what = &Curl_month[0];
- for(i=0; i<12; i++) {
- if(curl_strequal(check, what[0])) {
- found=TRUE;
- break;
- }
- what++;
- }
- return found?i:-1; /* return the offset or -1, no real offset is -1 */
-}
-
-/* return the time zone offset between GMT and the input one, in number
- of seconds or -1 if the timezone wasn't found/legal */
-
-static int checktz(char *check)
-{
- unsigned int i;
- const struct tzinfo *what;
- bool found= FALSE;
-
- what = tz;
- for(i=0; i< sizeof(tz)/sizeof(tz[0]); i++) {
- if(curl_strequal(check, what->name)) {
- found=TRUE;
- break;
- }
- what++;
- }
- return found?what->offset*60:-1;
-}
-
-static void skip(const char **date)
-{
- /* skip everything that aren't letters or digits */
- while(**date && !ISALNUM(**date))
- (*date)++;
-}
-
-enum assume {
- DATE_MDAY,
- DATE_YEAR,
- DATE_TIME
-};
-
-static time_t Curl_parsedate(const char *date)
-{
- time_t t = 0;
- int wdaynum=-1; /* day of the week number, 0-6 (mon-sun) */
- int monnum=-1; /* month of the year number, 0-11 */
- int mdaynum=-1; /* day of month, 1 - 31 */
- int hournum=-1;
- int minnum=-1;
- int secnum=-1;
- int yearnum=-1;
- int tzoff=-1;
- struct tm tm;
- enum assume dignext = DATE_MDAY;
- const char *indate = date; /* save the original pointer */
- int part = 0; /* max 6 parts */
-
- while(*date && (part < 6)) {
- bool found=FALSE;
-
- skip(&date);
-
- if(ISALPHA(*date)) {
- /* a name coming up */
- char buf[32]="";
- size_t len;
- sscanf(date, "%31[A-Za-z]", buf);
- len = strlen(buf);
-
- if(wdaynum == -1) {
- wdaynum = checkday(buf, len);
- if(wdaynum != -1)
- found = TRUE;
- }
- if(!found && (monnum == -1)) {
- monnum = checkmonth(buf);
- if(monnum != -1)
- found = TRUE;
- }
-
- if(!found && (tzoff == -1)) {
- /* this just must be a time zone string */
- tzoff = checktz(buf);
- if(tzoff != -1)
- found = TRUE;
- }
-
- if(!found)
- return -1; /* bad string */
-
- date += len;
- }
- else if(ISDIGIT(*date)) {
- /* a digit */
- int val;
- char *end;
- if((secnum == -1) &&
- (3 == sscanf(date, "%02d:%02d:%02d", &hournum, &minnum, &secnum))) {
- /* time stamp! */
- date += 8;
- found = TRUE;
- }
- else {
- val = (int)strtol(date, &end, 10);
-
- if((tzoff == -1) &&
- ((end - date) == 4) &&
- (val < 1300) &&
- (indate< date) &&
- ((date[-1] == '+' || date[-1] == '-'))) {
- /* four digits and a value less than 1300 and it is preceeded with
- a plus or minus. This is a time zone indication. */
- found = TRUE;
- tzoff = (val/100 * 60 + val%100)*60;
-
- /* the + and - prefix indicates the local time compared to GMT,
- this we need ther reversed math to get what we want */
- tzoff = date[-1]=='+'?-tzoff:tzoff;
- }
-
- if(((end - date) == 8) &&
- (yearnum == -1) &&
- (monnum == -1) &&
- (mdaynum == -1)) {
- /* 8 digits, no year, month or day yet. This is YYYYMMDD */
- found = TRUE;
- yearnum = val/10000;
- monnum = (val%10000)/100-1; /* month is 0 - 11 */
- mdaynum = val%100;
- }
-
- if(!found && (dignext == DATE_MDAY) && (mdaynum == -1)) {
- if((val > 0) && (val<32)) {
- mdaynum = val;
- found = TRUE;
- }
- dignext = DATE_YEAR;
- }
-
- if(!found && (dignext == DATE_YEAR) && (yearnum == -1)) {
- yearnum = val;
- found = TRUE;
- if(yearnum < 1900) {
- if (yearnum > 70)
- yearnum += 1900;
- else
- yearnum += 2000;
- }
- if(mdaynum == -1)
- dignext = DATE_MDAY;
- }
-
- if(!found)
- return -1;
-
- date = end;
- }
- }
-
- part++;
- }
-
- if(-1 == secnum)
- secnum = minnum = hournum = 0; /* no time, make it zero */
-
- if((-1 == mdaynum) ||
- (-1 == monnum) ||
- (-1 == yearnum))
- /* lacks vital info, fail */
- return -1;
-
-#if SIZEOF_TIME_T < 5
- /* 32 bit time_t can only hold dates to the beginning of 2038 */
- if(yearnum > 2037)
- return 0x7fffffff;
-#endif
-
- tm.tm_sec = secnum;
- tm.tm_min = minnum;
- tm.tm_hour = hournum;
- tm.tm_mday = mdaynum;
- tm.tm_mon = monnum;
- tm.tm_year = yearnum - 1900;
- tm.tm_wday = 0;
- tm.tm_yday = 0;
- tm.tm_isdst = 0;
-
- /* mktime() returns a time_t. time_t is often 32 bits, even on many
- architectures that feature 64 bit 'long'.
-
- Some systems have 64 bit time_t and deal with years beyond 2038. However,
- even some of the systems with 64 bit time_t returns -1 for dates beyond
- 03:14:07 UTC, January 19, 2038. (Such as AIX 5100-06)
- */
- t = mktime(&tm);
-
- /* time zone adjust (cast t to int to compare to negative one) */
- if(-1 != (int)t) {
- struct tm *gmt;
- long delta;
- time_t t2;
-
-#ifdef HAVE_GMTIME_R
- /* thread-safe version */
- struct tm keeptime2;
- gmt = (struct tm *)gmtime_r(&t, &keeptime2);
- if(!gmt)
- return -1; /* illegal date/time */
- t2 = mktime(gmt);
-#else
- /* It seems that at least the MSVC version of mktime() doesn't work
- properly if it gets the 'gmt' pointer passed in (which is a pointer
- returned from gmtime() pointing to static memory), so instead we copy
- the tm struct to a local struct and pass a pointer to that struct as
- input to mktime(). */
- struct tm gmt2;
- gmt = gmtime(&t); /* use gmtime_r() if available */
- if(!gmt)
- return -1; /* illegal date/time */
- gmt2 = *gmt;
- t2 = mktime(&gmt2);
-#endif
-
- /* Add the time zone diff (between the given timezone and GMT) and the
- diff between the local time zone and GMT. */
- delta = (long)((tzoff!=-1?tzoff:0) + (t - t2));
-
- if((delta>0) && (t + delta < t))
- return -1; /* time_t overflow */
-
- t += delta;
- }
-
- return t;
-}
-
-time_t curl_getdate(const char *p, const time_t *now)
-{
- (void)now;
- return Curl_parsedate(p);
-}
diff --git a/Utilities/cmcurl/parsedate.h b/Utilities/cmcurl/parsedate.h
deleted file mode 100644
index 0ea2d83c3..000000000
--- a/Utilities/cmcurl/parsedate.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef __PARSEDATE_H
-#define __PARSEDATEL_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-extern const char * const Curl_wkday[7];
-extern const char * const Curl_month[12];
-
-#endif
diff --git a/Utilities/cmcurl/progress.c b/Utilities/cmcurl/progress.c
deleted file mode 100644
index 5ba829a03..000000000
--- a/Utilities/cmcurl/progress.c
+++ /dev/null
@@ -1,424 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#include <string.h>
-#include <time.h>
-
-#if defined(__EMX__)
-#include <stdlib.h>
-#endif
-
-#include <curl/curl.h>
-#include "urldata.h"
-#include "sendf.h"
-#include "progress.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* Provide a string that is 2 + 1 + 2 + 1 + 2 = 8 letters long (plus the zero
- byte) */
-static void time2str(char *r, long t)
-{
- long h;
- if(!t) {
- strcpy(r, "--:--:--");
- return;
- }
- h = (t/3600);
- if(h <= 99) {
- long m = (t-(h*3600))/60;
- long s = (t-(h*3600)-(m*60));
- snprintf(r, 9, "%2ld:%02ld:%02ld",h,m,s);
- }
- else {
- /* this equals to more than 99 hours, switch to a more suitable output
- format to fit within the limits. */
- if(h/24 <= 999)
- snprintf(r, 9, "%3ldd %02ldh", h/24, h-(h/24)*24);
- else
- snprintf(r, 9, "%7ldd", h/24);
- }
-}
-
-/* The point of this function would be to return a string of the input data,
- but never longer than 5 columns (+ one zero byte).
- Add suffix k, M, G when suitable... */
-static char *max5data(curl_off_t bytes, char *max5)
-{
-#define ONE_KILOBYTE 1024
-#define ONE_MEGABYTE (1024* ONE_KILOBYTE)
-#define ONE_GIGABYTE (1024* ONE_MEGABYTE)
-#define ONE_TERRABYTE ((curl_off_t)1024* ONE_GIGABYTE)
-#define ONE_PETABYTE ((curl_off_t)1024* ONE_TERRABYTE)
-
- if(bytes < 100000) {
- snprintf(max5, 6, "%5" FORMAT_OFF_T, bytes);
- }
- else if(bytes < (10000*ONE_KILOBYTE)) {
- snprintf(max5, 6, "%4" FORMAT_OFF_T "k", (curl_off_t)(bytes/ONE_KILOBYTE));
- }
- else if(bytes < (100*ONE_MEGABYTE)) {
- /* 'XX.XM' is good as long as we're less than 100 megs */
- snprintf(max5, 6, "%2d.%0dM",
- (int)(bytes/ONE_MEGABYTE),
- (int)(bytes%ONE_MEGABYTE)/(ONE_MEGABYTE/10) );
- }
-#if SIZEOF_CURL_OFF_T > 4
- else if(bytes < ( (curl_off_t)10000*ONE_MEGABYTE))
- /* 'XXXXM' is good until we're at 10000MB or above */
- snprintf(max5, 6, "%4" FORMAT_OFF_T "M", (curl_off_t)(bytes/ONE_MEGABYTE));
-
- else if(bytes < (curl_off_t)100*ONE_GIGABYTE)
- /* 10000 MB - 100 GB, we show it as XX.XG */
- snprintf(max5, 6, "%2d.%0dG",
- (int)(bytes/ONE_GIGABYTE),
- (int)(bytes%ONE_GIGABYTE)/(ONE_GIGABYTE/10) );
-
- else if(bytes < (curl_off_t)10000 * ONE_GIGABYTE)
- /* up to 10000GB, display without decimal: XXXXG */
- snprintf(max5, 6, "%4dG", (int)(bytes/ONE_GIGABYTE));
-
- else if(bytes < (curl_off_t)10000 * ONE_TERRABYTE)
- /* up to 10000TB, display without decimal: XXXXT */
- snprintf(max5, 6, "%4dT", (int)(bytes/ONE_TERRABYTE));
- else {
- /* up to 10000PB, display without decimal: XXXXP */
- snprintf(max5, 6, "%4dP", (int)(bytes/ONE_PETABYTE));
-
- /* 16384 petabytes (16 exabytes) is maximum a 64 bit number can hold,
- but this type is signed so 8192PB will be max.*/
- }
-
-#else
- else
- snprintf(max5, 6, "%4" FORMAT_OFF_T "M", (curl_off_t)(bytes/ONE_MEGABYTE));
-#endif
-
- return max5;
-}
-
-/*
-
- New proposed interface, 9th of February 2000:
-
- pgrsStartNow() - sets start time
- pgrsSetDownloadSize(x) - known expected download size
- pgrsSetUploadSize(x) - known expected upload size
- pgrsSetDownloadCounter() - amount of data currently downloaded
- pgrsSetUploadCounter() - amount of data currently uploaded
- pgrsUpdate() - show progress
- pgrsDone() - transfer complete
-
-*/
-
-void Curl_pgrsDone(struct connectdata *conn)
-{
- struct SessionHandle *data = conn->data;
- data->progress.lastshow=0;
- Curl_pgrsUpdate(conn); /* the final (forced) update */
-
- data->progress.speeder_c = 0; /* reset the progress meter display */
-}
-
-/* reset all times except redirect */
-void Curl_pgrsResetTimes(struct SessionHandle *data)
-{
- data->progress.t_nslookup = 0.0;
- data->progress.t_connect = 0.0;
- data->progress.t_pretransfer = 0.0;
- data->progress.t_starttransfer = 0.0;
-}
-
-void Curl_pgrsTime(struct SessionHandle *data, timerid timer)
-{
- switch(timer) {
- default:
- case TIMER_NONE:
- /* mistake filter */
- break;
- case TIMER_STARTSINGLE:
- /* This is set at the start of a single fetch */
- data->progress.t_startsingle = Curl_tvnow();
- break;
-
- case TIMER_NAMELOOKUP:
- data->progress.t_nslookup =
- Curl_tvdiff_secs(Curl_tvnow(), data->progress.t_startsingle);
- break;
- case TIMER_CONNECT:
- data->progress.t_connect =
- Curl_tvdiff_secs(Curl_tvnow(), data->progress.t_startsingle);
- break;
- case TIMER_PRETRANSFER:
- data->progress.t_pretransfer =
- Curl_tvdiff_secs(Curl_tvnow(), data->progress.t_startsingle);
- break;
- case TIMER_STARTTRANSFER:
- data->progress.t_starttransfer =
- Curl_tvdiff_secs(Curl_tvnow(), data->progress.t_startsingle);
- break;
- case TIMER_POSTRANSFER:
- /* this is the normal end-of-transfer thing */
- break;
- case TIMER_REDIRECT:
- data->progress.t_redirect =
- Curl_tvdiff_secs(Curl_tvnow(), data->progress.start);
- break;
- }
-}
-
-void Curl_pgrsStartNow(struct SessionHandle *data)
-{
- data->progress.speeder_c = 0; /* reset the progress meter display */
- data->progress.start = Curl_tvnow();
-}
-
-void Curl_pgrsSetDownloadCounter(struct SessionHandle *data, curl_off_t size)
-{
- data->progress.downloaded = size;
-}
-
-void Curl_pgrsSetUploadCounter(struct SessionHandle *data, curl_off_t size)
-{
- data->progress.uploaded = size;
-}
-
-void Curl_pgrsSetDownloadSize(struct SessionHandle *data, curl_off_t size)
-{
- data->progress.size_dl = size;
- if(size > 0)
- data->progress.flags |= PGRS_DL_SIZE_KNOWN;
- else
- data->progress.flags &= ~PGRS_DL_SIZE_KNOWN;
-}
-
-void Curl_pgrsSetUploadSize(struct SessionHandle *data, curl_off_t size)
-{
- data->progress.size_ul = size;
- if(size > 0)
- data->progress.flags |= PGRS_UL_SIZE_KNOWN;
- else
- data->progress.flags &= ~PGRS_UL_SIZE_KNOWN;
-}
-
-int Curl_pgrsUpdate(struct connectdata *conn)
-{
- struct timeval now;
- int result;
- char max5[6][10];
- int dlpercen=0;
- int ulpercen=0;
- int total_percen=0;
- curl_off_t total_transfer;
- curl_off_t total_expected_transfer;
- long timespent;
- struct SessionHandle *data = conn->data;
- int nowindex = data->progress.speeder_c% CURR_TIME;
- int checkindex;
- int countindex; /* amount of seconds stored in the speeder array */
- char time_left[10];
- char time_total[10];
- char time_spent[10];
- long ulestimate=0;
- long dlestimate=0;
- long total_estimate;
-
- if(data->progress.flags & PGRS_HIDE)
- ; /* We do enter this function even if we don't wanna see anything, since
- this is were lots of the calculations are being made that will be used
- even when not displayed! */
- else if(!(data->progress.flags & PGRS_HEADERS_OUT)) {
- if (!data->progress.callback) {
- if(data->reqdata.resume_from)
- fprintf(data->set.err,
- "** Resuming transfer from byte position %" FORMAT_OFF_T
- "\n",
- data->reqdata.resume_from);
- fprintf(data->set.err,
- " %% Total %% Received %% Xferd Average Speed Time Time Time Current\n"
- " Dload Upload Total Spent Left Speed\n");
- }
- data->progress.flags |= PGRS_HEADERS_OUT; /* headers are shown */
- }
-
- now = Curl_tvnow(); /* what time is it */
-
- /* The time spent so far (from the start) */
- data->progress.timespent = Curl_tvdiff_secs(now, data->progress.start);
- timespent = (long)data->progress.timespent;
-
- /* The average download speed this far */
- data->progress.dlspeed = (curl_off_t)
- ((double)data->progress.downloaded/
- (data->progress.timespent>0?data->progress.timespent:1));
-
- /* The average upload speed this far */
- data->progress.ulspeed = (curl_off_t)
- ((double)data->progress.uploaded/
- (data->progress.timespent>0?data->progress.timespent:1));
-
- if(data->progress.lastshow == Curl_tvlong(now))
- return 0; /* never update this more than once a second if the end isn't
- reached */
- data->progress.lastshow = now.tv_sec;
-
- /* Let's do the "current speed" thing, which should use the fastest
- of the dl/ul speeds. Store the fasted speed at entry 'nowindex'. */
- data->progress.speeder[ nowindex ] =
- data->progress.downloaded>data->progress.uploaded?
- data->progress.downloaded:data->progress.uploaded;
-
- /* remember the exact time for this moment */
- data->progress.speeder_time [ nowindex ] = now;
-
- /* advance our speeder_c counter, which is increased every time we get
- here and we expect it to never wrap as 2^32 is a lot of seconds! */
- data->progress.speeder_c++;
-
- /* figure out how many index entries of data we have stored in our speeder
- array. With N_ENTRIES filled in, we have about N_ENTRIES-1 seconds of
- transfer. Imagine, after one second we have filled in two entries,
- after two seconds we've filled in three entries etc. */
- countindex = ((data->progress.speeder_c>=CURR_TIME)?
- CURR_TIME:data->progress.speeder_c) - 1;
-
- /* first of all, we don't do this if there's no counted seconds yet */
- if(countindex) {
- long span_ms;
-
- /* Get the index position to compare with the 'nowindex' position.
- Get the oldest entry possible. While we have less than CURR_TIME
- entries, the first entry will remain the oldest. */
- checkindex = (data->progress.speeder_c>=CURR_TIME)?
- data->progress.speeder_c%CURR_TIME:0;
-
- /* Figure out the exact time for the time span */
- span_ms = Curl_tvdiff(now,
- data->progress.speeder_time[checkindex]);
- if(0 == span_ms)
- span_ms=1; /* at least one millisecond MUST have passed */
-
- /* Calculate the average speed the last 'span_ms' milliseconds */
- {
- curl_off_t amount = data->progress.speeder[nowindex]-
- data->progress.speeder[checkindex];
-
- if(amount > 4294967 /* 0xffffffff/1000 */)
- /* the 'amount' value is bigger than would fit in 32 bits if
- multiplied with 1000, so we use the double math for this */
- data->progress.current_speed = (curl_off_t)
- ((double)amount/((double)span_ms/1000.0));
- else
- /* the 'amount' value is small enough to fit within 32 bits even
- when multiplied with 1000 */
- data->progress.current_speed = amount*1000/span_ms;
- }
- }
- else
- /* the first second we use the main average */
- data->progress.current_speed =
- (data->progress.ulspeed>data->progress.dlspeed)?
- data->progress.ulspeed:data->progress.dlspeed;
-
- if(data->progress.flags & PGRS_HIDE)
- return 0;
-
- else if(data->set.fprogress) {
- /* There's a callback set, so we call that instead of writing
- anything ourselves. This really is the way to go. */
- result= data->set.fprogress(data->set.progress_client,
- (double)data->progress.size_dl,
- (double)data->progress.downloaded,
- (double)data->progress.size_ul,
- (double)data->progress.uploaded);
- if(result)
- failf(data, "Callback aborted");
- return result;
- }
-
- /* Figure out the estimated time of arrival for the upload */
- if((data->progress.flags & PGRS_UL_SIZE_KNOWN) &&
- (data->progress.ulspeed>0) &&
- (data->progress.size_ul > 100) ) {
- ulestimate = (long)(data->progress.size_ul / data->progress.ulspeed);
- ulpercen = (int)(100*(data->progress.uploaded/100) /
- (data->progress.size_ul/100) );
- }
-
- /* ... and the download */
- if((data->progress.flags & PGRS_DL_SIZE_KNOWN) &&
- (data->progress.dlspeed>0) &&
- (data->progress.size_dl>100)) {
- dlestimate = (long)(data->progress.size_dl / data->progress.dlspeed);
- dlpercen = (int)(100*(data->progress.downloaded/100) /
- (data->progress.size_dl/100));
- }
-
- /* Now figure out which of them that is slower and use for the for
- total estimate! */
- total_estimate = ulestimate>dlestimate?ulestimate:dlestimate;
-
- /* create the three time strings */
- time2str(time_left, total_estimate > 0?(total_estimate - timespent):0);
- time2str(time_total, total_estimate);
- time2str(time_spent, timespent);
-
- /* Get the total amount of data expected to get transfered */
- total_expected_transfer =
- (data->progress.flags & PGRS_UL_SIZE_KNOWN?
- data->progress.size_ul:data->progress.uploaded)+
- (data->progress.flags & PGRS_DL_SIZE_KNOWN?
- data->progress.size_dl:data->progress.downloaded);
-
- /* We have transfered this much so far */
- total_transfer = data->progress.downloaded + data->progress.uploaded;
-
- /* Get the percentage of data transfered so far */
- if(total_expected_transfer > 100)
- total_percen=(int)(100*(total_transfer/100) /
- (total_expected_transfer/100) );
-
- fprintf(data->set.err,
- "\r%3d %s %3d %s %3d %s %s %s %s %s %s %s",
- total_percen, /* 3 letters */ /* total % */
- max5data(total_expected_transfer, max5[2]), /* total size */
- dlpercen, /* 3 letters */ /* rcvd % */
- max5data(data->progress.downloaded, max5[0]), /* rcvd size */
- ulpercen, /* 3 letters */ /* xfer % */
- max5data(data->progress.uploaded, max5[1]), /* xfer size */
- max5data(data->progress.dlspeed, max5[3]), /* avrg dl speed */
- max5data(data->progress.ulspeed, max5[4]), /* avrg ul speed */
- time_total, /* 8 letters */ /* total time */
- time_spent, /* 8 letters */ /* time spent */
- time_left, /* 8 letters */ /* time left */
- max5data(data->progress.current_speed, max5[5]) /* current speed */
- );
-
- /* we flush the output stream to make it appear as soon as possible */
- fflush(data->set.err);
-
- return 0;
-}
diff --git a/Utilities/cmcurl/progress.h b/Utilities/cmcurl/progress.h
deleted file mode 100644
index ad9d6623e..000000000
--- a/Utilities/cmcurl/progress.h
+++ /dev/null
@@ -1,70 +0,0 @@
-#ifndef __PROGRESS_H
-#define __PROGRESS_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "timeval.h"
-
-
-typedef enum {
- TIMER_NONE,
- TIMER_NAMELOOKUP,
- TIMER_CONNECT,
- TIMER_PRETRANSFER,
- TIMER_STARTTRANSFER,
- TIMER_POSTRANSFER,
- TIMER_STARTSINGLE,
- TIMER_REDIRECT,
- TIMER_LAST /* must be last */
-} timerid;
-
-void Curl_pgrsDone(struct connectdata *);
-void Curl_pgrsStartNow(struct SessionHandle *data);
-void Curl_pgrsSetDownloadSize(struct SessionHandle *data, curl_off_t size);
-void Curl_pgrsSetUploadSize(struct SessionHandle *data, curl_off_t size);
-void Curl_pgrsSetDownloadCounter(struct SessionHandle *data, curl_off_t size);
-void Curl_pgrsSetUploadCounter(struct SessionHandle *data, curl_off_t size);
-int Curl_pgrsUpdate(struct connectdata *);
-void Curl_pgrsResetTimes(struct SessionHandle *data);
-void Curl_pgrsTime(struct SessionHandle *data, timerid timer);
-
-
-/* Don't show progress for sizes smaller than: */
-#define LEAST_SIZE_PROGRESS BUFSIZE
-
-#define PROGRESS_DOWNLOAD (1<<0)
-#define PROGRESS_UPLOAD (1<<1)
-#define PROGRESS_DOWN_AND_UP (PROGRESS_UPLOAD | PROGRESS_DOWNLOAD)
-
-#define PGRS_SHOW_DL (1<<0)
-#define PGRS_SHOW_UL (1<<1)
-#define PGRS_DONE_DL (1<<2)
-#define PGRS_DONE_UL (1<<3)
-#define PGRS_HIDE (1<<4)
-#define PGRS_UL_SIZE_KNOWN (1<<5)
-#define PGRS_DL_SIZE_KNOWN (1<<6)
-
-#define PGRS_HEADERS_OUT (1<<7) /* set when the headers have been written */
-
-
-#endif /* __PROGRESS_H */
diff --git a/Utilities/cmcurl/security.c b/Utilities/cmcurl/security.c
deleted file mode 100644
index 4c9aed812..000000000
--- a/Utilities/cmcurl/security.c
+++ /dev/null
@@ -1,493 +0,0 @@
-/* This source code was modified by Martin Hedenfalk <mhe@stacken.kth.se> for
- * use in Curl. His latest changes were done 2000-09-18.
- *
- * It has since been patched and modified a lot by Daniel Stenberg
- * <daniel@haxx.se> to make it better applied to curl conditions, and to make
- * it not use globals, pollute name space and more. This source code awaits a
- * rewrite to work around the paragraph 2 in the BSD licenses as explained
- * below.
- *
- * Copyright (c) 1998, 1999 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * 3. Neither the name of the Institute nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE. */
-
-#include "setup.h"
-
-#ifndef CURL_DISABLE_FTP
-#ifdef HAVE_KRB4
-
-#define _MPRINTF_REPLACE /* we want curl-functions instead of native ones */
-#include <curl/mprintf.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <netdb.h>
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "urldata.h"
-#include "krb4.h"
-#include "base64.h"
-#include "sendf.h"
-#include "ftp.h"
-#include "memory.h"
-
-/* The last #include file should be: */
-#include "memdebug.h"
-
-#define min(a, b) ((a) < (b) ? (a) : (b))
-
-static const struct {
- enum protection_level level;
- const char *name;
-} level_names[] = {
- { prot_clear, "clear" },
- { prot_safe, "safe" },
- { prot_confidential, "confidential" },
- { prot_private, "private" }
-};
-
-static enum protection_level
-name_to_level(const char *name)
-{
- int i;
- for(i = 0; i < (int)sizeof(level_names)/(int)sizeof(level_names[0]); i++)
- if(curl_strnequal(level_names[i].name, name, strlen(name)))
- return level_names[i].level;
- return (enum protection_level)-1;
-}
-
-static const struct Curl_sec_client_mech * const mechs[] = {
-#ifdef KRB5
- /* not supported */
-#endif
-#ifdef HAVE_KRB4
- &Curl_krb4_client_mech,
-#endif
- NULL
-};
-
-int
-Curl_sec_getc(struct connectdata *conn, FILE *F)
-{
- if(conn->sec_complete && conn->data_prot) {
- char c;
- if(Curl_sec_read(conn, fileno(F), &c, 1) <= 0)
- return EOF;
- return c;
- }
- else
- return getc(F);
-}
-
-static int
-block_read(int fd, void *buf, size_t len)
-{
- unsigned char *p = buf;
- int b;
- while(len) {
- b = read(fd, p, len);
- if (b == 0)
- return 0;
- else if (b < 0)
- return -1;
- len -= b;
- p += b;
- }
- return p - (unsigned char*)buf;
-}
-
-static int
-block_write(int fd, void *buf, size_t len)
-{
- unsigned char *p = buf;
- int b;
- while(len) {
- b = write(fd, p, len);
- if(b < 0)
- return -1;
- len -= b;
- p += b;
- }
- return p - (unsigned char*)buf;
-}
-
-static int
-sec_get_data(struct connectdata *conn,
- int fd, struct krb4buffer *buf)
-{
- int len;
- int b;
-
- b = block_read(fd, &len, sizeof(len));
- if (b == 0)
- return 0;
- else if (b < 0)
- return -1;
- len = ntohl(len);
- buf->data = realloc(buf->data, len);
- b = block_read(fd, buf->data, len);
- if (b == 0)
- return 0;
- else if (b < 0)
- return -1;
- buf->size = (conn->mech->decode)(conn->app_data, buf->data, len,
- conn->data_prot, conn);
- buf->index = 0;
- return 0;
-}
-
-static size_t
-buffer_read(struct krb4buffer *buf, void *data, size_t len)
-{
- len = min(len, buf->size - buf->index);
- memcpy(data, (char*)buf->data + buf->index, len);
- buf->index += len;
- return len;
-}
-
-static size_t
-buffer_write(struct krb4buffer *buf, void *data, size_t len)
-{
- if(buf->index + len > buf->size) {
- void *tmp;
- if(buf->data == NULL)
- tmp = malloc(1024);
- else
- tmp = realloc(buf->data, buf->index + len);
- if(tmp == NULL)
- return -1;
- buf->data = tmp;
- buf->size = buf->index + len;
- }
- memcpy((char*)buf->data + buf->index, data, len);
- buf->index += len;
- return len;
-}
-
-int
-Curl_sec_read(struct connectdata *conn, int fd, void *buffer, int length)
-{
- size_t len;
- int rx = 0;
-
- if(conn->sec_complete == 0 || conn->data_prot == 0)
- return read(fd, buffer, length);
-
- if(conn->in_buffer.eof_flag){
- conn->in_buffer.eof_flag = 0;
- return 0;
- }
-
- len = buffer_read(&conn->in_buffer, buffer, length);
- length -= len;
- rx += len;
- buffer = (char*)buffer + len;
-
- while(length) {
- if(sec_get_data(conn, fd, &conn->in_buffer) < 0)
- return -1;
- if(conn->in_buffer.size == 0) {
- if(rx)
- conn->in_buffer.eof_flag = 1;
- return rx;
- }
- len = buffer_read(&conn->in_buffer, buffer, length);
- length -= len;
- rx += len;
- buffer = (char*)buffer + len;
- }
- return rx;
-}
-
-static int
-sec_send(struct connectdata *conn, int fd, char *from, int length)
-{
- int bytes;
- void *buf;
- bytes = (conn->mech->encode)(conn->app_data, from, length, conn->data_prot,
- &buf, conn);
- bytes = htonl(bytes);
- block_write(fd, &bytes, sizeof(bytes));
- block_write(fd, buf, ntohl(bytes));
- free(buf);
- return length;
-}
-
-int
-Curl_sec_fflush_fd(struct connectdata *conn, int fd)
-{
- if(conn->data_prot != prot_clear) {
- if(conn->out_buffer.index > 0){
- Curl_sec_write(conn, fd,
- conn->out_buffer.data, conn->out_buffer.index);
- conn->out_buffer.index = 0;
- }
- sec_send(conn, fd, NULL, 0);
- }
- return 0;
-}
-
-int
-Curl_sec_write(struct connectdata *conn, int fd, char *buffer, int length)
-{
- int len = conn->buffer_size;
- int tx = 0;
-
- if(conn->data_prot == prot_clear)
- return write(fd, buffer, length);
-
- len -= (conn->mech->overhead)(conn->app_data, conn->data_prot, len);
- while(length){
- if(length < len)
- len = length;
- sec_send(conn, fd, buffer, len);
- length -= len;
- buffer += len;
- tx += len;
- }
- return tx;
-}
-
-ssize_t
-Curl_sec_send(struct connectdata *conn, int num, char *buffer, int length)
-{
- curl_socket_t fd = conn->sock[num];
- return (ssize_t)Curl_sec_write(conn, fd, buffer, length);
-}
-
-int
-Curl_sec_putc(struct connectdata *conn, int c, FILE *F)
-{
- char ch = c;
- if(conn->data_prot == prot_clear)
- return putc(c, F);
-
- buffer_write(&conn->out_buffer, &ch, 1);
- if(c == '\n' || conn->out_buffer.index >= 1024 /* XXX */) {
- Curl_sec_write(conn, fileno(F), conn->out_buffer.data,
- conn->out_buffer.index);
- conn->out_buffer.index = 0;
- }
- return c;
-}
-
-int
-Curl_sec_read_msg(struct connectdata *conn, char *s, int level)
-{
- int len;
- unsigned char *buf;
- int code;
-
- len = Curl_base64_decode(s + 4, &buf); /* XXX */
- if(len > 0)
- len = (conn->mech->decode)(conn->app_data, buf, len, level, conn);
- else
- return -1;
-
- if(len < 0) {
- free(buf);
- return -1;
- }
-
- buf[len] = '\0';
-
- if(buf[3] == '-')
- code = 0;
- else
- sscanf((char *)buf, "%d", &code);
- if(buf[len-1] == '\n')
- buf[len-1] = '\0';
- strcpy(s, (char *)buf);
- free(buf);
- return code;
-}
-
-enum protection_level
-Curl_set_command_prot(struct connectdata *conn, enum protection_level level)
-{
- enum protection_level old = conn->command_prot;
- conn->command_prot = level;
- return old;
-}
-
-static int
-sec_prot_internal(struct connectdata *conn, int level)
-{
- char *p;
- unsigned int s = 1048576;
- ssize_t nread;
-
- if(!conn->sec_complete){
- infof(conn->data, "No security data exchange has taken place.\n");
- return -1;
- }
-
- if(level){
- int code;
- if(Curl_ftpsendf(conn, "PBSZ %u", s))
- return -1;
-
- if(Curl_GetFTPResponse(&nread, conn, &code))
- return -1;
-
- if(code/100 != '2'){
- failf(conn->data, "Failed to set protection buffer size.");
- return -1;
- }
- conn->buffer_size = s;
-
- p = strstr(conn->data->state.buffer, "PBSZ=");
- if(p)
- sscanf(p, "PBSZ=%u", &s);
- if(s < conn->buffer_size)
- conn->buffer_size = s;
- }
-
- if(Curl_ftpsendf(conn, "PROT %c", level["CSEP"]))
- return -1;
-
- if(Curl_GetFTPResponse(&nread, conn, NULL))
- return -1;
-
- if(conn->data->state.buffer[0] != '2'){
- failf(conn->data, "Failed to set protection level.");
- return -1;
- }
-
- conn->data_prot = (enum protection_level)level;
- return 0;
-}
-
-void
-Curl_sec_set_protection_level(struct connectdata *conn)
-{
- if(conn->sec_complete && conn->data_prot != conn->request_data_prot)
- sec_prot_internal(conn, conn->request_data_prot);
-}
-
-
-int
-Curl_sec_request_prot(struct connectdata *conn, const char *level)
-{
- int l = name_to_level(level);
- if(l == -1)
- return -1;
- conn->request_data_prot = (enum protection_level)l;
- return 0;
-}
-
-int
-Curl_sec_login(struct connectdata *conn)
-{
- int ret;
- const struct Curl_sec_client_mech * const *m;
- ssize_t nread;
- struct SessionHandle *data=conn->data;
- int ftpcode;
-
- for(m = mechs; *m && (*m)->name; m++) {
- void *tmp;
-
- tmp = realloc(conn->app_data, (*m)->size);
- if (tmp == NULL) {
- failf (data, "realloc %u failed", (*m)->size);
- return -1;
- }
- conn->app_data = tmp;
-
- if((*m)->init && (*(*m)->init)(conn->app_data) != 0) {
- infof(data, "Skipping %s...\n", (*m)->name);
- continue;
- }
- infof(data, "Trying %s...\n", (*m)->name);
-
- if(Curl_ftpsendf(conn, "AUTH %s", (*m)->name))
- return -1;
-
- if(Curl_GetFTPResponse(&nread, conn, &ftpcode))
- return -1;
-
- if(conn->data->state.buffer[0] != '3'){
- switch(ftpcode) {
- case 504:
- infof(data,
- "%s is not supported by the server.\n", (*m)->name);
- break;
- case 534:
- infof(data, "%s rejected as security mechanism.\n", (*m)->name);
- break;
- default:
- if(conn->data->state.buffer[0] == '5') {
- infof(data, "The server doesn't support the FTP "
- "security extensions.\n");
- return -1;
- }
- break;
- }
- continue;
- }
-
- ret = (*(*m)->auth)(conn->app_data, conn);
-
- if(ret == AUTH_CONTINUE)
- continue;
- else if(ret != AUTH_OK){
- /* mechanism is supposed to output error string */
- return -1;
- }
- conn->mech = *m;
- conn->sec_complete = 1;
- conn->command_prot = prot_safe;
- break;
- }
-
- return *m == NULL;
-}
-
-void
-Curl_sec_end(struct connectdata *conn)
-{
- if (conn->mech != NULL) {
- if(conn->mech->end)
- (conn->mech->end)(conn->app_data);
- memset(conn->app_data, 0, conn->mech->size);
- free(conn->app_data);
- conn->app_data = NULL;
- }
- conn->sec_complete = 0;
- conn->data_prot = (enum protection_level)0;
- conn->mech=NULL;
-}
-
-#endif /* HAVE_KRB4 */
-#endif /* CURL_DISABLE_FTP */
diff --git a/Utilities/cmcurl/select.c b/Utilities/cmcurl/select.c
deleted file mode 100644
index 51adbcf37..000000000
--- a/Utilities/cmcurl/select.c
+++ /dev/null
@@ -1,315 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#include <errno.h>
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-
-#ifndef HAVE_SELECT
-#error "We can't compile without select() support!"
-#endif
-
-#if defined(__BEOS__) && !defined(__HAIKU__)
-/* BeOS has FD_SET defined in socket.h */
-#include <socket.h>
-#endif
-
-#ifdef __MSDOS__
-#include <dos.h> /* delay() */
-#endif
-
-#include <curl/curl.h>
-
-#include "urldata.h"
-#include "connect.h"
-#include "select.h"
-
-#if defined(USE_WINSOCK) || defined(TPF)
-#define VERIFY_SOCK(x) /* sockets are not in range [0..FD_SETSIZE] */
-#else
-#define VALID_SOCK(s) (((s) >= 0) && ((s) < FD_SETSIZE))
-#define VERIFY_SOCK(x) do { \
- if(!VALID_SOCK(x)) { \
- errno = EINVAL; \
- return -1; \
- } \
-} while(0)
-#endif
-
-/*
- * This is an internal function used for waiting for read or write
- * events on single file descriptors. It attempts to replace select()
- * in order to avoid limits with FD_SETSIZE.
- *
- * Return values:
- * -1 = system call error
- * 0 = timeout
- * CSELECT_IN | CSELECT_OUT | CSELECT_ERR
- */
-int Curl_select(curl_socket_t readfd, curl_socket_t writefd, int timeout_ms)
-{
-#if (defined(HAVE_POLL) && !defined(_POLL_EMUL_H_)) || defined(CURL_HAVE_WSAPOLL)
- struct pollfd pfd[2];
- int num;
- int r;
- int ret;
-
- num = 0;
- if (readfd != CURL_SOCKET_BAD) {
- pfd[num].fd = readfd;
- pfd[num].events = POLLIN;
- num++;
- }
- if (writefd != CURL_SOCKET_BAD) {
- pfd[num].fd = writefd;
- pfd[num].events = POLLOUT;
- num++;
- }
-
-#if defined(HAVE_POLL) && !defined(_POLL_EMUL_H_)
- do {
- r = poll(pfd, num, timeout_ms);
- } while((r == -1) && (errno == EINTR));
-#else
- r = WSAPoll(pfd, num, timeout_ms);
-#endif
-
- if (r < 0)
- return -1;
- if (r == 0)
- return 0;
-
- ret = 0;
- num = 0;
- if (readfd != CURL_SOCKET_BAD) {
- if (pfd[num].revents & (POLLIN|POLLHUP))
- ret |= CSELECT_IN;
- if (pfd[num].revents & POLLERR) {
-#ifdef __CYGWIN__
- /* Cygwin 1.5.21 needs this hack to pass test 160 */
- if (errno == EINPROGRESS)
- ret |= CSELECT_IN;
- else
-#endif
- ret |= CSELECT_ERR;
- }
- num++;
- }
- if (writefd != CURL_SOCKET_BAD) {
- if (pfd[num].revents & POLLOUT)
- ret |= CSELECT_OUT;
- if (pfd[num].revents & (POLLERR|POLLHUP))
- ret |= CSELECT_ERR;
- }
-
- return ret;
-#else
- struct timeval timeout;
- fd_set fds_read;
- fd_set fds_write;
- fd_set fds_err;
- curl_socket_t maxfd;
- int r;
- int ret;
-
- timeout.tv_sec = timeout_ms / 1000;
- timeout.tv_usec = (timeout_ms % 1000) * 1000;
-
- if((readfd == CURL_SOCKET_BAD) && (writefd == CURL_SOCKET_BAD)) {
- /* According to POSIX we should pass in NULL pointers if we don't want to
- wait for anything in particular but just use the timeout function.
- Windows however returns immediately if done so. I copied the MSDOS
- delay() use from src/main.c that already had this work-around. */
-#ifdef WIN32
- Sleep(timeout_ms);
-#elif defined(__MSDOS__)
- delay(timeout_ms);
-#else
- select(0, NULL, NULL, NULL, &timeout);
-#endif
- return 0;
- }
-
- FD_ZERO(&fds_err);
- maxfd = (curl_socket_t)-1;
-
- FD_ZERO(&fds_read);
- if (readfd != CURL_SOCKET_BAD) {
- VERIFY_SOCK(readfd);
- FD_SET(readfd, &fds_read);
- FD_SET(readfd, &fds_err);
- maxfd = readfd;
- }
-
- FD_ZERO(&fds_write);
- if (writefd != CURL_SOCKET_BAD) {
- VERIFY_SOCK(writefd);
- FD_SET(writefd, &fds_write);
- FD_SET(writefd, &fds_err);
- if (writefd > maxfd)
- maxfd = writefd;
- }
-
- do {
- r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, &timeout);
- } while((r == -1) && (Curl_sockerrno() == EINTR));
-
- if (r < 0)
- return -1;
- if (r == 0)
- return 0;
-
- ret = 0;
- if (readfd != CURL_SOCKET_BAD) {
- if (FD_ISSET(readfd, &fds_read))
- ret |= CSELECT_IN;
- if (FD_ISSET(readfd, &fds_err))
- ret |= CSELECT_ERR;
- }
- if (writefd != CURL_SOCKET_BAD) {
- if (FD_ISSET(writefd, &fds_write))
- ret |= CSELECT_OUT;
- if (FD_ISSET(writefd, &fds_err))
- ret |= CSELECT_ERR;
- }
-
- return ret;
-#endif
-}
-
-/*
- * This is a wrapper around poll(). If poll() does not exist, then
- * select() is used instead. An error is returned if select() is
- * being used and a file descriptor too large for FD_SETSIZE.
- *
- * Return values:
- * -1 = system call error or fd >= FD_SETSIZE
- * 0 = timeout
- * 1 = number of structures with non zero revent fields
- */
-int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
-{
- int r;
-#if defined(HAVE_POLL) && !defined(_POLL_EMUL_H_)
- do {
- r = poll(ufds, nfds, timeout_ms);
- } while((r == -1) && (errno == EINTR));
-#elif defined(CURL_HAVE_WSAPOLL)
- r = WSAPoll(ufds, nfds, timeout_ms);
-#else
- struct timeval timeout;
- struct timeval *ptimeout;
- fd_set fds_read;
- fd_set fds_write;
- fd_set fds_err;
- curl_socket_t maxfd;
- unsigned int i;
-
- FD_ZERO(&fds_read);
- FD_ZERO(&fds_write);
- FD_ZERO(&fds_err);
- maxfd = (curl_socket_t)-1;
-
- for (i = 0; i < nfds; i++) {
- if (ufds[i].fd == CURL_SOCKET_BAD)
- continue;
-#ifndef USE_WINSOCK /* winsock sockets are not in range [0..FD_SETSIZE] */
- if (ufds[i].fd >= FD_SETSIZE) {
- errno = EINVAL;
- return -1;
- }
-#endif
- if (ufds[i].fd > maxfd)
- maxfd = ufds[i].fd;
- if (ufds[i].events & POLLIN)
- FD_SET(ufds[i].fd, &fds_read);
- if (ufds[i].events & POLLOUT)
- FD_SET(ufds[i].fd, &fds_write);
- if (ufds[i].events & POLLERR)
- FD_SET(ufds[i].fd, &fds_err);
- }
-
- if (timeout_ms < 0) {
- ptimeout = NULL; /* wait forever */
- } else {
- timeout.tv_sec = timeout_ms / 1000;
- timeout.tv_usec = (timeout_ms % 1000) * 1000;
- ptimeout = &timeout;
- }
-
- do {
- r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
- } while((r == -1) && (Curl_sockerrno() == EINTR));
-
- if (r < 0)
- return -1;
- if (r == 0)
- return 0;
-
- r = 0;
- for (i = 0; i < nfds; i++) {
- ufds[i].revents = 0;
- if (ufds[i].fd == CURL_SOCKET_BAD)
- continue;
- if (FD_ISSET(ufds[i].fd, &fds_read))
- ufds[i].revents |= POLLIN;
- if (FD_ISSET(ufds[i].fd, &fds_write))
- ufds[i].revents |= POLLOUT;
- if (FD_ISSET(ufds[i].fd, &fds_err))
- ufds[i].revents |= POLLERR;
- if (ufds[i].revents != 0)
- r++;
- }
-#endif
- return r;
-}
-
-#ifdef TPF
-/*
- * This is a replacement for select() on the TPF platform.
- * It is used whenever libcurl calls select().
- * The call below to tpf_process_signals() is required because
- * TPF's select calls are not signal interruptible.
- *
- * Return values are the same as select's.
- */
-int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
- fd_set* excepts, struct timeval* tv)
-{
- int rc;
-
- rc = tpf_select_bsd(maxfds, reads, writes, excepts, tv);
- tpf_process_signals();
- return(rc);
-}
-#endif /* TPF */
diff --git a/Utilities/cmcurl/select.h b/Utilities/cmcurl/select.h
deleted file mode 100644
index 7573b1f54..000000000
--- a/Utilities/cmcurl/select.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef __SELECT_H
-#define __SELECT_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#ifdef HAVE_SYS_POLL_H
-#include <sys/poll.h>
-#else
-#ifndef POLLIN
-#define POLLIN 0x01
-#define POLLPRI 0x02
-#define POLLOUT 0x04
-#define POLLERR 0x08
-#define POLLHUP 0x10
-#define POLLNVAL 0x20
-
-struct pollfd
-{
- curl_socket_t fd;
- short events;
- short revents;
-};
-#endif
-
-#endif
-
-#define CSELECT_IN 0x01
-#define CSELECT_OUT 0x02
-#define CSELECT_ERR 0x04
-
-int Curl_select(curl_socket_t readfd, curl_socket_t writefd, int timeout_ms);
-
-int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms);
-
-#ifdef TPF
-int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
- fd_set* excepts, struct timeval* tv);
-#endif
-
-#endif
diff --git a/Utilities/cmcurl/sendf.c b/Utilities/cmcurl/sendf.c
deleted file mode 100644
index 500bf66f0..000000000
--- a/Utilities/cmcurl/sendf.c
+++ /dev/null
@@ -1,663 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h> /* required for send() & recv() prototypes */
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include <curl/curl.h>
-#include "urldata.h"
-#include "sendf.h"
-#include "connect.h" /* for the Curl_sockerrno() proto */
-#include "sslgen.h"
-#include "ssh.h"
-#include "multiif.h"
-
-#define _MPRINTF_REPLACE /* use the internal *printf() functions */
-#include <curl/mprintf.h>
-
-#ifdef HAVE_KRB4
-#include "krb4.h"
-#else
-#define Curl_sec_send(a,b,c,d) -1
-#define Curl_sec_read(a,b,c,d) -1
-#endif
-
-#include <string.h>
-#include "memory.h"
-#include "strerror.h"
-#include "easyif.h" /* for the Curl_convert_from_network prototype */
-/* The last #include file should be: */
-#include "memdebug.h"
-
-/* returns last node in linked list */
-static struct curl_slist *slist_get_last(struct curl_slist *list)
-{
- struct curl_slist *item;
-
- /* if caller passed us a NULL, return now */
- if (!list)
- return NULL;
-
- /* loop through to find the last item */
- item = list;
- while (item->next) {
- item = item->next;
- }
- return item;
-}
-
-/*
- * curl_slist_append() appends a string to the linked list. It always retunrs
- * the address of the first record, so that you can sure this function as an
- * initialization function as well as an append function. If you find this
- * bothersome, then simply create a separate _init function and call it
- * appropriately from within the proram.
- */
-struct curl_slist *curl_slist_append(struct curl_slist *list,
- const char *data)
-{
- struct curl_slist *last;
- struct curl_slist *new_item;
-
- new_item = (struct curl_slist *) malloc(sizeof(struct curl_slist));
- if (new_item) {
- char *dup = strdup(data);
- if(dup) {
- new_item->next = NULL;
- new_item->data = dup;
- }
- else {
- free(new_item);
- return NULL;
- }
- }
- else
- return NULL;
-
- if (list) {
- last = slist_get_last(list);
- last->next = new_item;
- return list;
- }
-
- /* if this is the first item, then new_item *is* the list */
- return new_item;
-}
-
-/* be nice and clean up resources */
-void curl_slist_free_all(struct curl_slist *list)
-{
- struct curl_slist *next;
- struct curl_slist *item;
-
- if (!list)
- return;
-
- item = list;
- do {
- next = item->next;
-
- if (item->data) {
- free(item->data);
- }
- free(item);
- item = next;
- } while (next);
-}
-
-#ifdef CURL_DO_LINEEND_CONV
-/*
- * convert_lineends() changes CRLF (\r\n) end-of-line markers to a single LF
- * (\n), with special processing for CRLF sequences that are split between two
- * blocks of data. Remaining, bare CRs are changed to LFs. The possibly new
- * size of the data is returned.
- */
-static size_t convert_lineends(struct SessionHandle *data,
- char *startPtr, size_t size)
-{
- char *inPtr, *outPtr;
-
- /* sanity check */
- if ((startPtr == NULL) || (size < 1)) {
- return(size);
- }
-
- if (data->state.prev_block_had_trailing_cr == TRUE) {
- /* The previous block of incoming data
- had a trailing CR, which was turned into a LF. */
- if (*startPtr == '\n') {
- /* This block of incoming data starts with the
- previous block's LF so get rid of it */
- memcpy(startPtr, startPtr+1, size-1);
- size--;
- /* and it wasn't a bare CR but a CRLF conversion instead */
- data->state.crlf_conversions++;
- }
- data->state.prev_block_had_trailing_cr = FALSE; /* reset the flag */
- }
-
- /* find 1st CR, if any */
- inPtr = outPtr = memchr(startPtr, '\r', size);
- if (inPtr) {
- /* at least one CR, now look for CRLF */
- while (inPtr < (startPtr+size-1)) {
- /* note that it's size-1, so we'll never look past the last byte */
- if (memcmp(inPtr, "\r\n", 2) == 0) {
- /* CRLF found, bump past the CR and copy the NL */
- inPtr++;
- *outPtr = *inPtr;
- /* keep track of how many CRLFs we converted */
- data->state.crlf_conversions++;
- }
- else {
- if (*inPtr == '\r') {
- /* lone CR, move LF instead */
- *outPtr = '\n';
- }
- else {
- /* not a CRLF nor a CR, just copy whatever it is */
- *outPtr = *inPtr;
- }
- }
- outPtr++;
- inPtr++;
- } /* end of while loop */
-
- if (inPtr < startPtr+size) {
- /* handle last byte */
- if (*inPtr == '\r') {
- /* deal with a CR at the end of the buffer */
- *outPtr = '\n'; /* copy a NL instead */
- /* note that a CRLF might be split across two blocks */
- data->state.prev_block_had_trailing_cr = TRUE;
- }
- else {
- /* copy last byte */
- *outPtr = *inPtr;
- }
- outPtr++;
- inPtr++;
- }
- if (outPtr < startPtr+size) {
- /* tidy up by null terminating the now shorter data */
- *outPtr = '\0';
- }
- return(outPtr - startPtr);
- }
- return(size);
-}
-#endif /* CURL_DO_LINEEND_CONV */
-
-/* Curl_infof() is for info message along the way */
-
-void Curl_infof(struct SessionHandle *data, const char *fmt, ...)
-{
- if(data && data->set.verbose) {
- va_list ap;
- size_t len;
- char print_buffer[1024 + 1];
- va_start(ap, fmt);
- vsnprintf(print_buffer, 1024, fmt, ap);
- va_end(ap);
- len = strlen(print_buffer);
- Curl_debug(data, CURLINFO_TEXT, print_buffer, len, NULL);
- }
-}
-
-/* Curl_failf() is for messages stating why we failed.
- * The message SHALL NOT include any LF or CR.
- */
-
-void Curl_failf(struct SessionHandle *data, const char *fmt, ...)
-{
- va_list ap;
- size_t len;
- va_start(ap, fmt);
-
- vsnprintf(data->state.buffer, BUFSIZE, fmt, ap);
-
- if(data->set.errorbuffer && !data->state.errorbuf) {
- snprintf(data->set.errorbuffer, CURL_ERROR_SIZE, "%s", data->state.buffer);
- data->state.errorbuf = TRUE; /* wrote error string */
- }
- if(data->set.verbose) {
- len = strlen(data->state.buffer);
- if(len < BUFSIZE - 1) {
- data->state.buffer[len] = '\n';
- data->state.buffer[++len] = '\0';
- }
- Curl_debug(data, CURLINFO_TEXT, data->state.buffer, len, NULL);
- }
-
- va_end(ap);
-}
-
-/* Curl_sendf() sends formated data to the server */
-CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn,
- const char *fmt, ...)
-{
- struct SessionHandle *data = conn->data;
- ssize_t bytes_written;
- size_t write_len;
- CURLcode res = CURLE_OK;
- char *s;
- char *sptr;
- va_list ap;
- va_start(ap, fmt);
- s = vaprintf(fmt, ap); /* returns an allocated string */
- va_end(ap);
- if(!s)
- return CURLE_OUT_OF_MEMORY; /* failure */
-
- bytes_written=0;
- write_len = strlen(s);
- sptr = s;
-
- while (1) {
- /* Write the buffer to the socket */
- res = Curl_write(conn, sockfd, sptr, write_len, &bytes_written);
-
- if(CURLE_OK != res)
- break;
-
- if(data->set.verbose)
- Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written, conn);
-
- if((size_t)bytes_written != write_len) {
- /* if not all was written at once, we must advance the pointer, decrease
- the size left and try again! */
- write_len -= bytes_written;
- sptr += bytes_written;
- }
- else
- break;
- }
-
- free(s); /* free the output string */
-
- return res;
-}
-
-static ssize_t Curl_plain_send(struct connectdata *conn,
- int num,
- void *mem,
- size_t len)
-{
- curl_socket_t sockfd = conn->sock[num];
- ssize_t bytes_written = swrite(sockfd, mem, len);
-
- if(-1 == bytes_written) {
- int err = Curl_sockerrno();
-
- if(
-#ifdef WSAEWOULDBLOCK
- /* This is how Windows does it */
- (WSAEWOULDBLOCK == err)
-#else
- /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
- due to its inability to send off data without blocking. We therefor
- treat both error codes the same here */
- (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
-#endif
- )
- /* this is just a case of EWOULDBLOCK */
- bytes_written=0;
- else
- failf(conn->data, "Send failure: %s",
- Curl_strerror(conn, err));
- }
- return bytes_written;
-}
-
-/*
- * Curl_write() is an internal write function that sends data to the
- * server. Works with plain sockets, SCP, SSL or kerberos.
- */
-CURLcode Curl_write(struct connectdata *conn,
- curl_socket_t sockfd,
- void *mem,
- size_t len,
- ssize_t *written)
-{
- ssize_t bytes_written;
- CURLcode retcode;
- int num = (sockfd == conn->sock[SECONDARYSOCKET]);
-
- if (conn->ssl[num].use)
- /* only TRUE if SSL enabled */
- bytes_written = Curl_ssl_send(conn, num, mem, len);
-#ifdef USE_LIBSSH2
- else if (conn->protocol & PROT_SCP)
- bytes_written = Curl_scp_send(conn, num, mem, len);
- else if (conn->protocol & PROT_SFTP)
- bytes_written = Curl_sftp_send(conn, num, mem, len);
-#endif /* !USE_LIBSSH2 */
- else if(conn->sec_complete)
- /* only TRUE if krb4 enabled */
- bytes_written = Curl_sec_send(conn, num, mem, len);
- else
- bytes_written = Curl_plain_send(conn, num, mem, len);
-
- *written = bytes_written;
- retcode = (-1 != bytes_written)?CURLE_OK:CURLE_SEND_ERROR;
-
- return retcode;
-}
-
-/* client_write() sends data to the write callback(s)
-
- The bit pattern defines to what "streams" to write to. Body and/or header.
- The defines are in sendf.h of course.
- */
-CURLcode Curl_client_write(struct connectdata *conn,
- int type,
- char *ptr,
- size_t len)
-{
- struct SessionHandle *data = conn->data;
- size_t wrote;
-
- if (data->state.cancelled) {
- /* We just suck everything into a black hole */
- return CURLE_OK;
- }
-
- if(0 == len)
- len = strlen(ptr);
-
- if(type & CLIENTWRITE_BODY) {
- if((conn->protocol&PROT_FTP) && conn->proto.ftpc.transfertype == 'A') {
-#ifdef CURL_DOES_CONVERSIONS
- /* convert from the network encoding */
- size_t rc;
- rc = Curl_convert_from_network(data, ptr, len);
- /* Curl_convert_from_network calls failf if unsuccessful */
- if(rc != CURLE_OK)
- return rc;
-#endif /* CURL_DOES_CONVERSIONS */
-
-#ifdef CURL_DO_LINEEND_CONV
- /* convert end-of-line markers */
- len = convert_lineends(data, ptr, len);
-#endif /* CURL_DO_LINEEND_CONV */
- }
- /* If the previous block of data ended with CR and this block of data is
- just a NL, then the length might be zero */
- if (len) {
- wrote = data->set.fwrite(ptr, 1, len, data->set.out);
- }
- else {
- wrote = len;
- }
-
- if(wrote != len) {
- failf (data, "Failed writing body");
- return CURLE_WRITE_ERROR;
- }
- }
-
- if((type & CLIENTWRITE_HEADER) &&
- (data->set.fwrite_header || data->set.writeheader) ) {
- /*
- * Write headers to the same callback or to the especially setup
- * header callback function (added after version 7.7.1).
- */
- curl_write_callback writeit=
- data->set.fwrite_header?data->set.fwrite_header:data->set.fwrite;
-
- /* Note: The header is in the host encoding
- regardless of the ftp transfer mode (ASCII/Image) */
-
- wrote = writeit(ptr, 1, len, data->set.writeheader);
- if(wrote != len) {
- failf (data, "Failed writing header");
- return CURLE_WRITE_ERROR;
- }
- }
-
- return CURLE_OK;
-}
-
-#ifndef MIN
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-#endif
-
-/*
- * Internal read-from-socket function. This is meant to deal with plain
- * sockets, SSL sockets and kerberos sockets.
- *
- * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
- * a regular CURLcode value.
- */
-int Curl_read(struct connectdata *conn, /* connection data */
- curl_socket_t sockfd, /* read from this socket */
- char *buf, /* store read data here */
- size_t sizerequested, /* max amount to read */
- ssize_t *n) /* amount bytes read */
-{
- ssize_t nread;
- size_t bytesfromsocket = 0;
- char *buffertofill = NULL;
- bool pipelining = (bool)(conn->data->multi &&
- Curl_multi_canPipeline(conn->data->multi));
-
- /* Set 'num' to 0 or 1, depending on which socket that has been sent here.
- If it is the second socket, we set num to 1. Otherwise to 0. This lets
- us use the correct ssl handle. */
- int num = (sockfd == conn->sock[SECONDARYSOCKET]);
-
- *n=0; /* reset amount to zero */
-
- /* If session can pipeline, check connection buffer */
- if(pipelining) {
- size_t bytestocopy = MIN(conn->buf_len - conn->read_pos, sizerequested);
-
- /* Copy from our master buffer first if we have some unread data there*/
- if (bytestocopy > 0) {
- memcpy(buf, conn->master_buffer + conn->read_pos, bytestocopy);
- conn->read_pos += bytestocopy;
- conn->bits.stream_was_rewound = FALSE;
-
- *n = (ssize_t)bytestocopy;
- return CURLE_OK;
- }
- /* If we come here, it means that there is no data to read from the buffer,
- * so we read from the socket */
- bytesfromsocket = MIN(sizerequested, sizeof(conn->master_buffer));
- buffertofill = conn->master_buffer;
- }
- else {
- bytesfromsocket = MIN((long)sizerequested, conn->data->set.buffer_size ?
- conn->data->set.buffer_size : BUFSIZE);
- buffertofill = buf;
- }
-
- if(conn->ssl[num].use) {
- nread = Curl_ssl_recv(conn, num, buffertofill, bytesfromsocket);
-
- if(nread == -1) {
- return -1; /* -1 from Curl_ssl_recv() means EWOULDBLOCK */
- }
- }
-#ifdef USE_LIBSSH2
- else if (conn->protocol & PROT_SCP) {
- nread = Curl_scp_recv(conn, num, buffertofill, bytesfromsocket);
- /* TODO: return CURLE_OK also for nread <= 0
- read failures and timeouts ? */
- }
- else if (conn->protocol & PROT_SFTP) {
- nread = Curl_sftp_recv(conn, num, buffertofill, bytesfromsocket);
- }
-#endif /* !USE_LIBSSH2 */
- else {
- if(conn->sec_complete)
- nread = Curl_sec_read(conn, sockfd, buffertofill,
- bytesfromsocket);
- else
- nread = sread(sockfd, buffertofill, bytesfromsocket);
-
- if(-1 == nread) {
- int err = Curl_sockerrno();
-#ifdef USE_WINSOCK
- if(WSAEWOULDBLOCK == err)
-#else
- if((EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err))
-#endif
- return -1;
- }
- }
-
- if (nread >= 0) {
- if(pipelining) {
- memcpy(buf, conn->master_buffer, nread);
- conn->buf_len = nread;
- conn->read_pos = nread;
- }
-
- *n += nread;
- }
-
- return CURLE_OK;
-}
-
-/* return 0 on success */
-static int showit(struct SessionHandle *data, curl_infotype type,
- char *ptr, size_t size)
-{
- static const char * const s_infotype[CURLINFO_END] = {
- "* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
-
-#ifdef CURL_DOES_CONVERSIONS
- char buf[BUFSIZE+1];
- size_t conv_size = 0;
-
- switch(type) {
- case CURLINFO_HEADER_OUT:
- /* assume output headers are ASCII */
- /* copy the data into my buffer so the original is unchanged */
- if (size > BUFSIZE) {
- size = BUFSIZE; /* truncate if necessary */
- buf[BUFSIZE] = '\0';
- }
- conv_size = size;
- memcpy(buf, ptr, size);
- /* Special processing is needed for this block if it
- * contains both headers and data (separated by CRLFCRLF).
- * We want to convert just the headers, leaving the data as-is.
- */
- if(size > 4) {
- size_t i;
- for(i = 0; i < size-4; i++) {
- if(memcmp(&buf[i], "\x0d\x0a\x0d\x0a", 4) == 0) {
- /* convert everthing through this CRLFCRLF but no further */
- conv_size = i + 4;
- break;
- }
- }
- }
-
- Curl_convert_from_network(data, buf, conv_size);
- /* Curl_convert_from_network calls failf if unsuccessful */
- /* we might as well continue even if it fails... */
- ptr = buf; /* switch pointer to use my buffer instead */
- break;
- default:
- /* leave everything else as-is */
- break;
- }
-#endif /* CURL_DOES_CONVERSIONS */
-
- if(data->set.fdebug)
- return (*data->set.fdebug)(data, type, ptr, size,
- data->set.debugdata);
-
- switch(type) {
- case CURLINFO_TEXT:
- case CURLINFO_HEADER_OUT:
- case CURLINFO_HEADER_IN:
- fwrite(s_infotype[type], 2, 1, data->set.err);
- fwrite(ptr, size, 1, data->set.err);
-#ifdef CURL_DOES_CONVERSIONS
- if(size != conv_size) {
- /* we had untranslated data so we need an explicit newline */
- fwrite("\n", 1, 1, data->set.err);
- }
-#endif
- break;
- default: /* nada */
- break;
- }
- return 0;
-}
-
-int Curl_debug(struct SessionHandle *data, curl_infotype type,
- char *ptr, size_t size,
- struct connectdata *conn)
-{
- int rc;
- if(data->set.printhost && conn && conn->host.dispname) {
- char buffer[160];
- const char *t=NULL;
- const char *w="Data";
- switch (type) {
- case CURLINFO_HEADER_IN:
- w = "Header";
- case CURLINFO_DATA_IN:
- t = "from";
- break;
- case CURLINFO_HEADER_OUT:
- w = "Header";
- case CURLINFO_DATA_OUT:
- t = "to";
- break;
- default:
- break;
- }
-
- if(t) {
- snprintf(buffer, sizeof(buffer), "[%s %s %s]", w, t,
- conn->host.dispname);
- rc = showit(data, CURLINFO_TEXT, buffer, strlen(buffer));
- if(rc)
- return rc;
- }
- }
- rc = showit(data, type, ptr, size);
- return rc;
-}
diff --git a/Utilities/cmcurl/sendf.h b/Utilities/cmcurl/sendf.h
deleted file mode 100644
index 7877df823..000000000
--- a/Utilities/cmcurl/sendf.h
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef __SENDF_H
-#define __SENDF_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *,
- const char *fmt, ...);
-void Curl_infof(struct SessionHandle *, const char *fmt, ...);
-void Curl_failf(struct SessionHandle *, const char *fmt, ...);
-
-#if defined(CURL_DISABLE_VERBOSE_STRINGS)
-#if defined(__GNUC__)
-/* This style of variable argument macros is a gcc extension */
-#define infof(x...) /*ignore*/
-#else
-/* C99 compilers could use this if we could detect them */
-/*#define infof(...) */
-/* Cast the args to void to make them a noop, side effects notwithstanding */
-#define infof (void)
-#endif
-#else
-#define infof Curl_infof
-#endif
-#define failf Curl_failf
-
-#define CLIENTWRITE_BODY 1
-#define CLIENTWRITE_HEADER 2
-#define CLIENTWRITE_BOTH (CLIENTWRITE_BODY|CLIENTWRITE_HEADER)
-
-CURLcode Curl_client_write(struct connectdata *conn, int type, char *ptr,
- size_t len);
-
-void Curl_read_rewind(struct connectdata *conn,
- size_t extraBytesRead);
-
-/* internal read-function, does plain socket, SSL and krb4 */
-int Curl_read(struct connectdata *conn, curl_socket_t sockfd,
- char *buf, size_t buffersize,
- ssize_t *n);
-/* internal write-function, does plain socket, SSL and krb4 */
-CURLcode Curl_write(struct connectdata *conn,
- curl_socket_t sockfd,
- void *mem, size_t len,
- ssize_t *written);
-
-/* the function used to output verbose information */
-int Curl_debug(struct SessionHandle *handle, curl_infotype type,
- char *data, size_t size,
- struct connectdata *conn);
-
-
-#endif
diff --git a/Utilities/cmcurl/setup.h b/Utilities/cmcurl/setup.h
deleted file mode 100644
index 5ae881fba..000000000
--- a/Utilities/cmcurl/setup.h
+++ /dev/null
@@ -1,390 +0,0 @@
-#ifndef __LIB_CURL_SETUP_H
-#define __LIB_CURL_SETUP_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#ifdef HTTP_ONLY
-#define CURL_DISABLE_TFTP
-#define CURL_DISABLE_FTP
-#define CURL_DISABLE_LDAP
-#define CURL_DISABLE_TELNET
-#define CURL_DISABLE_DICT
-#define CURL_DISABLE_FILE
-#endif /* HTTP_ONLY */
-
-#if !defined(WIN32) && defined(__WIN32__)
-/* Borland fix */
-#define WIN32
-#endif
-
-#if !defined(WIN32) && defined(_WIN32)
-/* VS2005 on x64 fix */
-#define WIN32
-#endif
-
-#if defined(__clang__)
-# pragma clang diagnostic ignored "-Wcast-align"
-#endif
-
-/*
- * Include configuration script results or hand-crafted
- * configuration file for platforms which lack config tool.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#else
-
-/*
-#ifdef _WIN32_WCE
-#include "config-win32ce.h"
-#else
-#ifdef WIN32
-#include "config-win32.h"
-#endif
-#endif
-*/
-
-#ifdef macintosh
-#include "config-mac.h"
-#endif
-
-#ifdef AMIGA
-#include "amigaos.h"
-#endif
-
-#ifdef TPF
-#include "config-tpf.h" /* hand-modified TPF config.h */
-/* change which select is used for libcurl */
-#define select(a,b,c,d,e) tpf_select_libcurl(a,b,c,d,e)
-#endif
-
-#endif /* HAVE_CONFIG_H */
-
-/*
- * Include header files for windows builds before redefining anything.
- * Use this preproessor block only to include or exclude windows.h,
- * winsock2.h, ws2tcpip.h or winsock.h. Any other windows thing belongs
- * to any other further and independant block. Under Cygwin things work
- * just as under linux (e.g. <sys/socket.h>) and the winsock headers should
- * never be included when __CYGWIN__ is defined. configure script takes
- * care of this, not defining HAVE_WINDOWS_H, HAVE_WINSOCK_H, HAVE_WINSOCK2_H,
- * neither HAVE_WS2TCPIP_H when __CYGWIN__ is defined.
- */
-
-#ifdef HAVE_WINDOWS_H
-# ifndef WIN32_LEAN_AND_MEAN
-# define WIN32_LEAN_AND_MEAN
-# endif
-# include <windows.h>
-# ifdef HAVE_WINSOCK2_H
-# include <winsock2.h>
-# ifdef HAVE_WS2TCPIP_H
-# include <ws2tcpip.h>
-# endif
-# else
-# ifdef HAVE_WINSOCK_H
-# include <winsock.h>
-# endif
-# endif
-#endif
-
-/*
- * Define USE_WINSOCK to 2 if we have and use WINSOCK2 API, else
- * define USE_WINSOCK to 1 if we have and use WINSOCK API, else
- * undefine USE_WINSOCK.
- */
-
-#undef USE_WINSOCK
-
-#ifdef HAVE_WINSOCK2_H
-# define USE_WINSOCK 2
-#else
-# ifdef HAVE_WINSOCK_H
-# define USE_WINSOCK 1
-# endif
-#endif
-
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#if !defined(__cplusplus) && !defined(__BEOS__) && !defined(__ECOS) && !defined(typedef_bool)
-typedef unsigned char bool;
-#define typedef_bool
-#endif
-
-#ifdef HAVE_LONGLONG
-#define LONG_LONG long long
-#define ENABLE_64BIT
-#else
-#ifdef _MSC_VER
-#define LONG_LONG __int64
-#define ENABLE_64BIT
-#endif /* _MSC_VER */
-#endif /* HAVE_LONGLONG */
-
-#ifndef SIZEOF_CURL_OFF_T
-/* If we don't know the size here, we assume a conservative size: 4. When
- building libcurl, the actual size of this variable should be define in the
- config*.h file. */
-#define SIZEOF_CURL_OFF_T 4
-#endif
-
-/* We set up our internal preferred (CURL_)FORMAT_OFF_T here */
-#if SIZEOF_CURL_OFF_T > 4
-#define FORMAT_OFF_T "lld"
-#else
-#define FORMAT_OFF_T "ld"
-#endif /* SIZEOF_CURL_OFF_T */
-
-#ifndef _REENTRANT
-/* Solaris needs _REENTRANT set for a few function prototypes and things to
- appear in the #include files. We need to #define it before all #include
- files. Unixware needs it to build proper reentrant code. Others may also
- need it. */
-#define _REENTRANT
-#endif
-
-#include <stdio.h>
-#ifdef HAVE_ASSERT_H
-#include <assert.h>
-#endif
-#include <errno.h>
-
-#ifdef __TANDEM /* for nsr-tandem-nsk systems */
-#include <floss.h>
-#endif
-
-#ifndef STDC_HEADERS /* no standard C headers! */
-#include <curl/stdcheaders.h>
-#endif
-
-/*
- * PellesC cludge section (yikes);
- * - It has 'ssize_t', but it is in <unistd.h>. The way the headers
- * on Win32 are included, forces me to include this header here.
- * - sys_nerr, EINTR is missing in v4.0 or older.
- */
-#ifdef __POCC__
- #include <sys/types.h>
- #include <unistd.h>
- #if (__POCC__ <= 400)
- #define sys_nerr EILSEQ /* for strerror.c */
- #define EINTR -1 /* for select.c */
- #endif
-#endif
-
-/*
- * Salford-C cludge section (mostly borrowed from wxWidgets).
- */
-#ifdef __SALFORDC__
- #pragma suppress 353 /* Possible nested comments */
- #pragma suppress 593 /* Define not used */
- #pragma suppress 61 /* enum has no name */
- #pragma suppress 106 /* unnamed, unused parameter */
- #include <clib.h>
-#endif
-
-#if defined(CURLDEBUG) && defined(HAVE_ASSERT_H)
-#define curlassert(x) assert(x)
-#else
-/* does nothing without CURLDEBUG defined */
-#define curlassert(x)
-#endif
-
-
-/* To make large file support transparent even on Windows */
-#if defined(WIN32) && (SIZEOF_CURL_OFF_T > 4)
-#include <sys/stat.h> /* must come first before we redefine stat() */
-#include <io.h>
-#define lseek(x,y,z) _lseeki64(x, y, z)
-#define struct_stat struct _stati64
-#define stat(file,st) _stati64(file,st)
-#define fstat(fd,st) _fstati64(fd,st)
-#else
-#define struct_stat struct stat
-#endif /* Win32 with large file support */
-
-
-/* Below we define some functions. They should
- 1. close a socket
-
- 4. set the SIGALRM signal timeout
- 5. set dir/file naming defines
- */
-
-#ifdef WIN32
-
-#if !defined(__CYGWIN__)
-#define sclose(x) closesocket(x)
-
-#undef HAVE_ALARM
-#else
- /* gcc-for-win is still good :) */
-#define sclose(x) close(x)
-#define HAVE_ALARM
-#endif /* !GNU or mingw */
-
-#define DIR_CHAR "\\"
-#define DOT_CHAR "_"
-
-#else /* WIN32 */
-
-#ifdef MSDOS /* Watt-32 */
-#include <sys/ioctl.h>
-#define sclose(x) close_s(x)
-#define select(n,r,w,x,t) select_s(n,r,w,x,t)
-#define ioctl(x,y,z) ioctlsocket(x,y,(char *)(z))
-#define IOCTL_3_ARGS
-#include <tcp.h>
-#ifdef word
-#undef word
-#endif
-
-#else /* MSDOS */
-
-#ifdef __VMS
-#define IOCTL_3_ARGS 1
-#endif
-
-#ifdef __BEOS__
-#define sclose(x) closesocket(x)
-#else /* __BEOS__ */
-#define sclose(x) close(x)
-#endif /* __BEOS__ */
-
-#define HAVE_ALARM
-
-#endif /* MSDOS */
-
-#ifdef _AMIGASF
-#undef HAVE_ALARM
-#undef sclose
-#define sclose(x) CloseSocket(x)
-#endif
-
-#define DIR_CHAR "/"
-#ifndef DOT_CHAR
-#define DOT_CHAR "."
-#endif
-
-#ifdef MSDOS
-#undef DOT_CHAR
-#define DOT_CHAR "_"
-#endif
-
-#ifndef fileno /* sunos 4 have this as a macro! */
-int fileno( FILE *stream);
-#endif
-
-#endif /* WIN32 */
-
-#if defined(WIN32) && !defined(__CYGWIN__) && !defined(USE_ARES) && \
- !defined(__LCC__) /* lcc-win32 doesn't have _beginthreadex() */
-#ifdef ENABLE_IPV6
-#define USE_THREADING_GETADDRINFO
-#else
-#define USE_THREADING_GETHOSTBYNAME /* Cygwin uses alarm() function */
-#endif
-#endif
-
-/* "cl -ML" or "cl -MLd" implies a single-threaded runtime library where
- _beginthreadex() is not available */
-#if (defined(_MSC_VER) && !defined(__POCC__)) && !defined(_MT) && !defined(USE_ARES)
-#undef USE_THREADING_GETADDRINFO
-#undef USE_THREADING_GETHOSTBYNAME
-#define CURL_NO__BEGINTHREADEX
-#endif
-
-/*
- * msvc 6.0 does not have struct sockaddr_storage and
- * does not define IPPROTO_ESP in winsock2.h. But both
- * are available if PSDK is properly installed.
- */
-
-#ifdef _MSC_VER
-#if !defined(HAVE_WINSOCK2_H) || ((_MSC_VER < 1300) && !defined(IPPROTO_ESP))
-#undef HAVE_STRUCT_SOCKADDR_STORAGE
-#endif
-#endif
-
-#ifdef mpeix
-#define IOCTL_3_ARGS
-#endif
-
-#ifdef NETWARE
-#undef HAVE_ALARM
-#endif
-
-#if defined(HAVE_LIBIDN) && defined(HAVE_TLD_H)
-/* The lib was present and the tld.h header (which is missing in libidn 0.3.X
- but we only work with libidn 0.4.1 or later) */
-#define USE_LIBIDN
-#endif
-
-#ifndef SIZEOF_TIME_T
-/* assume default size of time_t to be 32 bit */
-#define SIZEOF_TIME_T 4
-#endif
-
-#define LIBIDN_REQUIRED_VERSION "0.4.1"
-
-#ifdef __UCLIBC__
-#define HAVE_INET_NTOA_R_2_ARGS 1
-#endif
-
-#if defined(USE_GNUTLS) || defined(USE_SSLEAY)
-#define USE_SSL /* Either OpenSSL || GnuTLS */
-#endif
-
-#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_NTLM)
-#if defined(USE_SSLEAY) || defined(USE_WINDOWS_SSPI)
-#define USE_NTLM
-#endif
-#endif
-
-#ifdef CURLDEBUG
-#define DEBUGF(x) x
-#else
-#define DEBUGF(x)
-#endif
-
-/* non-configure builds may define CURL_WANTS_CA_BUNDLE_ENV */
-#if defined(CURL_WANTS_CA_BUNDLE_ENV) && !defined(CURL_CA_BUNDLE)
-#define CURL_CA_BUNDLE getenv("CURL_CA_BUNDLE")
-#endif
-
-/*
- * Include macros and defines that should only be processed once.
- */
-
-#ifndef __SETUP_ONCE_H
-#include "setup_once.h"
-#endif
-
-#endif /* __LIB_CURL_SETUP_H */
diff --git a/Utilities/cmcurl/setup_once.h b/Utilities/cmcurl/setup_once.h
deleted file mode 100644
index ee6864158..000000000
--- a/Utilities/cmcurl/setup_once.h
+++ /dev/null
@@ -1,153 +0,0 @@
-#ifndef __SETUP_ONCE_H
-#define __SETUP_ONCE_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-
-/********************************************************************
- * NOTICE *
- * ======== *
- * *
- * Content of header files lib/setup_once.h and ares/setup_once.h *
- * must be kept in sync. Modify the other one if you change this. *
- * *
- ********************************************************************/
-
-
-/*
- * If we have the MSG_NOSIGNAL define, make sure we use
- * it as the fourth argument of function send()
- */
-
-#ifdef HAVE_MSG_NOSIGNAL
-#define SEND_4TH_ARG MSG_NOSIGNAL
-#else
-#define SEND_4TH_ARG 0
-#endif
-
-
-/*
- * The definitions for the return type and arguments types
- * of functions recv() and send() belong and come from the
- * configuration file. Do not define them in any other place.
- *
- * HAVE_RECV is defined if you have a function named recv()
- * which is used to read incoming data from sockets. If your
- * function has another name then don't define HAVE_RECV.
- *
- * If HAVE_RECV is defined then RECV_TYPE_ARG1, RECV_TYPE_ARG2,
- * RECV_TYPE_ARG3, RECV_TYPE_ARG4 and RECV_TYPE_RETV must also
- * be defined.
- *
- * HAVE_SEND is defined if you have a function named send()
- * which is used to write outgoing data on a connected socket.
- * If yours has another name then don't define HAVE_SEND.
- *
- * If HAVE_SEND is defined then SEND_TYPE_ARG1, SEND_QUAL_ARG2,
- * SEND_TYPE_ARG2, SEND_TYPE_ARG3, SEND_TYPE_ARG4 and
- * SEND_TYPE_RETV must also be defined.
- */
-
-#ifdef HAVE_RECV
-#if !defined(RECV_TYPE_ARG1) || \
- !defined(RECV_TYPE_ARG2) || \
- !defined(RECV_TYPE_ARG3) || \
- !defined(RECV_TYPE_ARG4) || \
- !defined(RECV_TYPE_RETV)
- /* */
- Error Missing_definition_of_return_and_arguments_types_of_recv
- /* */
-#else
-#define sread(x,y,z) (ssize_t)recv((RECV_TYPE_ARG1)(x), \
- (RECV_TYPE_ARG2)(y), \
- (RECV_TYPE_ARG3)(z), \
- (RECV_TYPE_ARG4)(0))
-#endif
-#else /* HAVE_RECV */
-#ifndef sread
- /* */
- Error Missing_definition_of_macro_sread
- /* */
-#endif
-#endif /* HAVE_RECV */
-
-#ifdef HAVE_SEND
-#if !defined(SEND_TYPE_ARG1) || \
- !defined(SEND_QUAL_ARG2) || \
- !defined(SEND_TYPE_ARG2) || \
- !defined(SEND_TYPE_ARG3) || \
- !defined(SEND_TYPE_ARG4) || \
- !defined(SEND_TYPE_RETV)
- /* */
- Error Missing_definition_of_return_and_arguments_types_of_send
- /* */
-#else
-#define swrite(x,y,z) (ssize_t)send((SEND_TYPE_ARG1)(x), \
- (SEND_TYPE_ARG2)(y), \
- (SEND_TYPE_ARG3)(z), \
- (SEND_TYPE_ARG4)(SEND_4TH_ARG))
-#endif
-#else /* HAVE_SEND */
-#ifndef swrite
- /* */
- Error Missing_definition_of_macro_swrite
- /* */
-#endif
-#endif /* HAVE_SEND */
-
-
-/*
- * Uppercase macro versions of ANSI/ISO is*() functions/macros which
- * avoid negative number inputs with argument byte codes > 127.
- */
-
-#define ISSPACE(x) (isspace((int) ((unsigned char)x)))
-#define ISDIGIT(x) (isdigit((int) ((unsigned char)x)))
-#define ISALNUM(x) (isalnum((int) ((unsigned char)x)))
-#define ISXDIGIT(x) (isxdigit((int) ((unsigned char)x)))
-#define ISGRAPH(x) (isgraph((int) ((unsigned char)x)))
-#define ISALPHA(x) (isalpha((int) ((unsigned char)x)))
-#define ISPRINT(x) (isprint((int) ((unsigned char)x)))
-
-
-/*
- * Typedef to 'int' if sig_atomic_t is not an available 'typedefed' type.
- */
-
-#ifndef HAVE_SIG_ATOMIC_T
-typedef int sig_atomic_t;
-#define HAVE_SIG_ATOMIC_T
-#endif
-
-
-/*
- * Default return type for signal handlers.
- */
-
-#ifndef RETSIGTYPE
-#define RETSIGTYPE void
-#endif
-
-
-#endif /* __SETUP_ONCE_H */
-
diff --git a/Utilities/cmcurl/share.c b/Utilities/cmcurl/share.c
deleted file mode 100644
index de13b6021..000000000
--- a/Utilities/cmcurl/share.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <curl/curl.h>
-#include "urldata.h"
-#include "share.h"
-#include "memory.h"
-
-/* The last #include file should be: */
-#include "memdebug.h"
-
-CURLSH *
-curl_share_init(void)
-{
- struct Curl_share *share =
- (struct Curl_share *)malloc(sizeof(struct Curl_share));
- if (share) {
- memset (share, 0, sizeof(struct Curl_share));
- share->specifier |= (1<<CURL_LOCK_DATA_SHARE);
- }
-
- return share;
-}
-
-CURLSHcode
-curl_share_setopt(CURLSH *sh, CURLSHoption option, ...)
-{
- struct Curl_share *share = (struct Curl_share *)sh;
- va_list param;
- int type;
- curl_lock_function lockfunc;
- curl_unlock_function unlockfunc;
- void *ptr;
-
- if (share->dirty)
- /* don't allow setting options while one or more handles are already
- using this share */
- return CURLSHE_IN_USE;
-
- va_start(param, option);
-
- switch(option) {
- case CURLSHOPT_SHARE:
- /* this is a type this share will share */
- type = va_arg(param, int);
- share->specifier |= (1<<type);
- switch( type ) {
- case CURL_LOCK_DATA_DNS:
- if (!share->hostcache) {
- share->hostcache = Curl_mk_dnscache();
- if(!share->hostcache)
- return CURLSHE_NOMEM;
- }
- break;
-
-#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
- case CURL_LOCK_DATA_COOKIE:
- if (!share->cookies) {
- share->cookies = Curl_cookie_init(NULL, NULL, NULL, TRUE );
- if(!share->cookies)
- return CURLSHE_NOMEM;
- }
- break;
-#endif /* CURL_DISABLE_HTTP */
-
- case CURL_LOCK_DATA_SSL_SESSION: /* not supported (yet) */
- case CURL_LOCK_DATA_CONNECT: /* not supported (yet) */
-
- default:
- return CURLSHE_BAD_OPTION;
- }
- break;
-
- case CURLSHOPT_UNSHARE:
- /* this is a type this share will no longer share */
- type = va_arg(param, int);
- share->specifier &= ~(1<<type);
- switch( type )
- {
- case CURL_LOCK_DATA_DNS:
- if (share->hostcache) {
- Curl_hash_destroy(share->hostcache);
- share->hostcache = NULL;
- }
- break;
-
-#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
- case CURL_LOCK_DATA_COOKIE:
- if (share->cookies) {
- Curl_cookie_cleanup(share->cookies);
- share->cookies = NULL;
- }
- break;
-#endif /* CURL_DISABLE_HTTP */
-
- case CURL_LOCK_DATA_SSL_SESSION:
- break;
-
- case CURL_LOCK_DATA_CONNECT:
- break;
-
- default:
- return CURLSHE_BAD_OPTION;
- }
- break;
-
- case CURLSHOPT_LOCKFUNC:
- lockfunc = va_arg(param, curl_lock_function);
- share->lockfunc = lockfunc;
- break;
-
- case CURLSHOPT_UNLOCKFUNC:
- unlockfunc = va_arg(param, curl_unlock_function);
- share->unlockfunc = unlockfunc;
- break;
-
- case CURLSHOPT_USERDATA:
- ptr = va_arg(param, void *);
- share->clientdata = ptr;
- break;
-
- default:
- return CURLSHE_BAD_OPTION;
- }
-
- return CURLSHE_OK;
-}
-
-CURLSHcode
-curl_share_cleanup(CURLSH *sh)
-{
- struct Curl_share *share = (struct Curl_share *)sh;
-
- if (share == NULL)
- return CURLSHE_INVALID;
-
- if(share->lockfunc)
- share->lockfunc(NULL, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE,
- share->clientdata);
-
- if (share->dirty) {
- if(share->unlockfunc)
- share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata);
- return CURLSHE_IN_USE;
- }
-
- if(share->hostcache)
- Curl_hash_destroy(share->hostcache);
-
-#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
- if(share->cookies)
- Curl_cookie_cleanup(share->cookies);
-#endif /* CURL_DISABLE_HTTP */
-
- if(share->unlockfunc)
- share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata);
- free(share);
-
- return CURLSHE_OK;
-}
-
-
-CURLSHcode
-Curl_share_lock(struct SessionHandle *data, curl_lock_data type,
- curl_lock_access accesstype)
-{
- struct Curl_share *share = data->share;
-
- if (share == NULL)
- return CURLSHE_INVALID;
-
- if(share->specifier & (1<<type)) {
- if(share->lockfunc) /* only call this if set! */
- share->lockfunc(data, type, accesstype, share->clientdata);
- }
- /* else if we don't share this, pretend successful lock */
-
- return CURLSHE_OK;
-}
-
-CURLSHcode
-Curl_share_unlock(struct SessionHandle *data, curl_lock_data type)
-{
- struct Curl_share *share = data->share;
-
- if (share == NULL)
- return CURLSHE_INVALID;
-
- if(share->specifier & (1<<type)) {
- if(share->unlockfunc) /* only call this if set! */
- share->unlockfunc (data, type, share->clientdata);
- }
-
- return CURLSHE_OK;
-}
diff --git a/Utilities/cmcurl/share.h b/Utilities/cmcurl/share.h
deleted file mode 100644
index 5cfe8c792..000000000
--- a/Utilities/cmcurl/share.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef __CURL_SHARE_H
-#define __CURL_SHARE_H
-
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-#include <curl/curl.h>
-#include "cookie.h"
-
-/* SalfordC says "A structure member may not be volatile". Hence:
- */
-#ifdef __SALFORDC__
-#define CURL_VOLATILE
-#else
-#define CURL_VOLATILE volatile
-#endif
-
-/* this struct is libcurl-private, don't export details */
-struct Curl_share {
- unsigned int specifier;
- CURL_VOLATILE unsigned int dirty;
-
- curl_lock_function lockfunc;
- curl_unlock_function unlockfunc;
- void *clientdata;
-
- struct curl_hash *hostcache;
- struct CookieInfo *cookies;
-};
-
-CURLSHcode Curl_share_lock (struct SessionHandle *, curl_lock_data,
- curl_lock_access);
-CURLSHcode Curl_share_unlock (struct SessionHandle *, curl_lock_data);
-
-#endif /* __CURL_SHARE_H */
diff --git a/Utilities/cmcurl/sockaddr.h b/Utilities/cmcurl/sockaddr.h
deleted file mode 100644
index 78dad4d9e..000000000
--- a/Utilities/cmcurl/sockaddr.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef __SOCKADDR_H
-#define __SOCKADDR_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#ifdef HAVE_STRUCT_SOCKADDR_STORAGE
-struct Curl_sockaddr_storage {
- struct sockaddr_storage buffer;
-};
-#else
-struct Curl_sockaddr_storage {
- char buffer[256]; /* this should be big enough to fit a lot */
-};
-#endif
-
-#endif /* __SOCKADDR_H */
diff --git a/Utilities/cmcurl/socks.c b/Utilities/cmcurl/socks.c
deleted file mode 100644
index e0e947b80..000000000
--- a/Utilities/cmcurl/socks.c
+++ /dev/null
@@ -1,592 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#include <string.h>
-
-#ifdef NEED_MALLOC_H
-#include <malloc.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#include "urldata.h"
-#include "sendf.h"
-#include "strequal.h"
-#include "select.h"
-#include "connect.h"
-#include "timeval.h"
-#include "socks.h"
-
-/* The last #include file should be: */
-#include "memdebug.h"
-
-/*
- * Helper read-from-socket functions. Does the same as Curl_read() but it
- * blocks until all bytes amount of buffersize will be read. No more, no less.
- *
- * This is STUPID BLOCKING behaviour which we frown upon, but right now this
- * is what we have...
- */
-static int blockread_all(struct connectdata *conn, /* connection data */
- curl_socket_t sockfd, /* read from this socket */
- char *buf, /* store read data here */
- ssize_t buffersize, /* max amount to read */
- ssize_t *n, /* amount bytes read */
- long conn_timeout) /* timeout for data wait
- relative to
- conn->created */
-{
- ssize_t nread;
- ssize_t allread = 0;
- int result;
- struct timeval tvnow;
- long conntime;
- *n = 0;
- do {
- tvnow = Curl_tvnow();
- /* calculating how long connection is establishing */
- conntime = Curl_tvdiff(tvnow, conn->created);
- if(conntime > conn_timeout) {
- /* we already got the timeout */
- result = ~CURLE_OK;
- break;
- }
- if(Curl_select(sockfd, CURL_SOCKET_BAD,
- (int)(conn_timeout - conntime)) <= 0) {
- result = ~CURLE_OK;
- break;
- }
- result = Curl_read(conn, sockfd, buf, buffersize, &nread);
- if(result)
- break;
-
- if(buffersize == nread) {
- allread += nread;
- *n = allread;
- result = CURLE_OK;
- break;
- }
- buffersize -= nread;
- buf += nread;
- allread += nread;
- } while(1);
- return result;
-}
-
-/*
-* This function logs in to a SOCKS4 proxy and sends the specifics to the final
-* destination server.
-*
-* Reference :
-* http://socks.permeo.com/protocol/socks4.protocol
-*
-* Note :
-* Nonsupport "SOCKS 4A (Simple Extension to SOCKS 4 Protocol)"
-* Nonsupport "Identification Protocol (RFC1413)"
-*/
-CURLcode Curl_SOCKS4(const char *proxy_name,
- struct connectdata *conn)
-{
- unsigned char socksreq[262]; /* room for SOCKS4 request incl. user id */
- int result;
- CURLcode code;
- curl_socket_t sock = conn->sock[FIRSTSOCKET];
- long timeout;
- struct SessionHandle *data = conn->data;
-
- /* get timeout */
- if(data->set.timeout && data->set.connecttimeout) {
- if (data->set.timeout < data->set.connecttimeout)
- timeout = data->set.timeout*1000;
- else
- timeout = data->set.connecttimeout*1000;
- }
- else if(data->set.timeout)
- timeout = data->set.timeout*1000;
- else if(data->set.connecttimeout)
- timeout = data->set.connecttimeout*1000;
- else
- timeout = DEFAULT_CONNECT_TIMEOUT;
-
- Curl_nonblock(sock, FALSE);
-
- /*
- * Compose socks4 request
- *
- * Request format
- *
- * +----+----+----+----+----+----+----+----+----+----+....+----+
- * | VN | CD | DSTPORT | DSTIP | USERID |NULL|
- * +----+----+----+----+----+----+----+----+----+----+....+----+
- * # of bytes: 1 1 2 4 variable 1
- */
-
- socksreq[0] = 4; /* version (SOCKS4) */
- socksreq[1] = 1; /* connect */
- *((unsigned short*)&socksreq[2]) = htons(conn->remote_port);
-
- /* DNS resolve */
- {
- struct Curl_dns_entry *dns;
- Curl_addrinfo *hp=NULL;
- int rc;
-
- rc = Curl_resolv(conn, conn->host.name, (int)conn->remote_port, &dns);
-
- if(rc == CURLRESOLV_ERROR)
- return CURLE_COULDNT_RESOLVE_PROXY;
-
- if(rc == CURLRESOLV_PENDING)
- /* this requires that we're in "wait for resolve" state */
- rc = Curl_wait_for_resolv(conn, &dns);
-
- /*
- * We cannot use 'hostent' as a struct that Curl_resolv() returns. It
- * returns a Curl_addrinfo pointer that may not always look the same.
- */
- if(dns)
- hp=dns->addr;
- if (hp) {
- char buf[64];
- unsigned short ip[4];
- Curl_printable_address(hp, buf, sizeof(buf));
-
- if(4 == sscanf( buf, "%hu.%hu.%hu.%hu",
- &ip[0], &ip[1], &ip[2], &ip[3])) {
- /* Set DSTIP */
- socksreq[4] = (unsigned char)ip[0];
- socksreq[5] = (unsigned char)ip[1];
- socksreq[6] = (unsigned char)ip[2];
- socksreq[7] = (unsigned char)ip[3];
- }
- else
- hp = NULL; /* fail! */
-
- Curl_resolv_unlock(data, dns); /* not used anymore from now on */
-
- }
- if(!hp) {
- failf(data, "Failed to resolve \"%s\" for SOCKS4 connect.",
- conn->host.name);
- return CURLE_COULDNT_RESOLVE_HOST;
- }
- }
-
- /*
- * This is currently not supporting "Identification Protocol (RFC1413)".
- */
- socksreq[8] = 0; /* ensure empty userid is NUL-terminated */
- if(proxy_name) {
- size_t plen = strlen(proxy_name);
- if(plen >= sizeof(socksreq) - 8) {
- failf(data, "Too long SOCKS proxy name, can't use!\n");
- return CURLE_COULDNT_CONNECT;
- }
- /* copy the proxy name WITH trailing zero */
- memcpy(socksreq + 8, proxy_name, plen+1);
- }
-
- /*
- * Make connection
- */
- {
- ssize_t actualread;
- ssize_t written;
- int packetsize = 9 +
- (int)strlen((char*)socksreq + 8); /* size including NUL */
-
- /* Send request */
- code = Curl_write(conn, sock, (char *)socksreq, packetsize, &written);
- if ((code != CURLE_OK) || (written != packetsize)) {
- failf(data, "Failed to send SOCKS4 connect request.");
- return CURLE_COULDNT_CONNECT;
- }
-
- packetsize = 8; /* receive data size */
-
- /* Receive response */
- result = blockread_all(conn, sock, (char *)socksreq, packetsize,
- &actualread, timeout);
- if ((result != CURLE_OK) || (actualread != packetsize)) {
- failf(data, "Failed to receive SOCKS4 connect request ack.");
- return CURLE_COULDNT_CONNECT;
- }
-
- /*
- * Response format
- *
- * +----+----+----+----+----+----+----+----+
- * | VN | CD | DSTPORT | DSTIP |
- * +----+----+----+----+----+----+----+----+
- * # of bytes: 1 1 2 4
- *
- * VN is the version of the reply code and should be 0. CD is the result
- * code with one of the following values:
- *
- * 90: request granted
- * 91: request rejected or failed
- * 92: request rejected because SOCKS server cannot connect to
- * identd on the client
- * 93: request rejected because the client program and identd
- * report different user-ids
- */
-
- /* wrong version ? */
- if (socksreq[0] != 0) {
- failf(data,
- "SOCKS4 reply has wrong version, version should be 4.");
- return CURLE_COULDNT_CONNECT;
- }
-
- /* Result */
- switch(socksreq[1])
- {
- case 90:
- infof(data, "SOCKS4 request granted.\n");
- break;
- case 91:
- failf(data,
- "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
- ", request rejected or failed.",
- (unsigned char)socksreq[4], (unsigned char)socksreq[5],
- (unsigned char)socksreq[6], (unsigned char)socksreq[7],
- (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])),
- socksreq[1]);
- return CURLE_COULDNT_CONNECT;
- case 92:
- failf(data,
- "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
- ", request rejected because SOCKS server cannot connect to "
- "identd on the client.",
- (unsigned char)socksreq[4], (unsigned char)socksreq[5],
- (unsigned char)socksreq[6], (unsigned char)socksreq[7],
- (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])),
- socksreq[1]);
- return CURLE_COULDNT_CONNECT;
- case 93:
- failf(data,
- "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
- ", request rejected because the client program and identd "
- "report different user-ids.",
- (unsigned char)socksreq[4], (unsigned char)socksreq[5],
- (unsigned char)socksreq[6], (unsigned char)socksreq[7],
- (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])),
- socksreq[1]);
- return CURLE_COULDNT_CONNECT;
- default:
- failf(data,
- "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
- ", Unknown.",
- (unsigned char)socksreq[4], (unsigned char)socksreq[5],
- (unsigned char)socksreq[6], (unsigned char)socksreq[7],
- (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])),
- socksreq[1]);
- return CURLE_COULDNT_CONNECT;
- }
- }
-
- Curl_nonblock(sock, TRUE);
-
- return CURLE_OK; /* Proxy was successful! */
-}
-
-/*
- * This function logs in to a SOCKS5 proxy and sends the specifics to the final
- * destination server.
- */
-CURLcode Curl_SOCKS5(const char *proxy_name,
- const char *proxy_password,
- struct connectdata *conn)
-{
- /*
- According to the RFC1928, section "6. Replies". This is what a SOCK5
- replies:
-
- +----+-----+-------+------+----------+----------+
- |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
- +----+-----+-------+------+----------+----------+
- | 1 | 1 | X'00' | 1 | Variable | 2 |
- +----+-----+-------+------+----------+----------+
-
- Where:
-
- o VER protocol version: X'05'
- o REP Reply field:
- o X'00' succeeded
- */
-
- unsigned char socksreq[600]; /* room for large user/pw (255 max each) */
- ssize_t actualread;
- ssize_t written;
- int result;
- CURLcode code;
- curl_socket_t sock = conn->sock[FIRSTSOCKET];
- struct SessionHandle *data = conn->data;
- long timeout;
-
- /* get timeout */
- if(data->set.timeout && data->set.connecttimeout) {
- if (data->set.timeout < data->set.connecttimeout)
- timeout = data->set.timeout*1000;
- else
- timeout = data->set.connecttimeout*1000;
- }
- else if(data->set.timeout)
- timeout = data->set.timeout*1000;
- else if(data->set.connecttimeout)
- timeout = data->set.connecttimeout*1000;
- else
- timeout = DEFAULT_CONNECT_TIMEOUT;
-
- Curl_nonblock(sock, TRUE);
-
- /* wait until socket gets connected */
- result = Curl_select(CURL_SOCKET_BAD, sock, (int)timeout);
-
- if(-1 == result) {
- failf(conn->data, "SOCKS5: no connection here");
- return CURLE_COULDNT_CONNECT;
- }
- else if(0 == result) {
- failf(conn->data, "SOCKS5: connection timeout");
- return CURLE_OPERATION_TIMEDOUT;
- }
-
- if(result & CSELECT_ERR) {
- failf(conn->data, "SOCKS5: error occured during connection");
- return CURLE_COULDNT_CONNECT;
- }
-
- socksreq[0] = 5; /* version */
- socksreq[1] = (char)(proxy_name ? 2 : 1); /* number of methods (below) */
- socksreq[2] = 0; /* no authentication */
- socksreq[3] = 2; /* username/password */
-
- Curl_nonblock(sock, FALSE);
-
- code = Curl_write(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]),
- &written);
- if ((code != CURLE_OK) || (written != (2 + (int)socksreq[1]))) {
- failf(data, "Unable to send initial SOCKS5 request.");
- return CURLE_COULDNT_CONNECT;
- }
-
- Curl_nonblock(sock, TRUE);
-
- result = Curl_select(sock, CURL_SOCKET_BAD, (int)timeout);
-
- if(-1 == result) {
- failf(conn->data, "SOCKS5 nothing to read");
- return CURLE_COULDNT_CONNECT;
- }
- else if(0 == result) {
- failf(conn->data, "SOCKS5 read timeout");
- return CURLE_OPERATION_TIMEDOUT;
- }
-
- if(result & CSELECT_ERR) {
- failf(conn->data, "SOCKS5 read error occured");
- return CURLE_RECV_ERROR;
- }
-
- Curl_nonblock(sock, FALSE);
-
- result=blockread_all(conn, sock, (char *)socksreq, 2, &actualread, timeout);
- if ((result != CURLE_OK) || (actualread != 2)) {
- failf(data, "Unable to receive initial SOCKS5 response.");
- return CURLE_COULDNT_CONNECT;
- }
-
- if (socksreq[0] != 5) {
- failf(data, "Received invalid version in initial SOCKS5 response.");
- return CURLE_COULDNT_CONNECT;
- }
- if (socksreq[1] == 0) {
- /* Nothing to do, no authentication needed */
- ;
- }
- else if (socksreq[1] == 2) {
- /* Needs user name and password */
- size_t userlen, pwlen;
- int len;
- if(proxy_name && proxy_password) {
- userlen = strlen(proxy_name);
- pwlen = proxy_password?strlen(proxy_password):0;
- }
- else {
- userlen = 0;
- pwlen = 0;
- }
-
- /* username/password request looks like
- * +----+------+----------+------+----------+
- * |VER | ULEN | UNAME | PLEN | PASSWD |
- * +----+------+----------+------+----------+
- * | 1 | 1 | 1 to 255 | 1 | 1 to 255 |
- * +----+------+----------+------+----------+
- */
- len = 0;
- socksreq[len++] = 1; /* username/pw subnegotiation version */
- socksreq[len++] = (char) userlen;
- memcpy(socksreq + len, proxy_name, (int) userlen);
- len += userlen;
- socksreq[len++] = (char) pwlen;
- memcpy(socksreq + len, proxy_password, (int) pwlen);
- len += pwlen;
-
- code = Curl_write(conn, sock, (char *)socksreq, len, &written);
- if ((code != CURLE_OK) || (len != written)) {
- failf(data, "Failed to send SOCKS5 sub-negotiation request.");
- return CURLE_COULDNT_CONNECT;
- }
-
- result=blockread_all(conn, sock, (char *)socksreq, 2, &actualread,
- timeout);
- if ((result != CURLE_OK) || (actualread != 2)) {
- failf(data, "Unable to receive SOCKS5 sub-negotiation response.");
- return CURLE_COULDNT_CONNECT;
- }
-
- /* ignore the first (VER) byte */
- if (socksreq[1] != 0) { /* status */
- failf(data, "User was rejected by the SOCKS5 server (%d %d).",
- socksreq[0], socksreq[1]);
- return CURLE_COULDNT_CONNECT;
- }
-
- /* Everything is good so far, user was authenticated! */
- }
- else {
- /* error */
- if (socksreq[1] == 1) {
- failf(data,
- "SOCKS5 GSSAPI per-message authentication is not supported.");
- return CURLE_COULDNT_CONNECT;
- }
- else if (socksreq[1] == 255) {
- if (!proxy_name || !*proxy_name) {
- failf(data,
- "No authentication method was acceptable. (It is quite likely"
- " that the SOCKS5 server wanted a username/password, since none"
- " was supplied to the server on this connection.)");
- }
- else {
- failf(data, "No authentication method was acceptable.");
- }
- return CURLE_COULDNT_CONNECT;
- }
- else {
- failf(data,
- "Undocumented SOCKS5 mode attempted to be used by server.");
- return CURLE_COULDNT_CONNECT;
- }
- }
-
- /* Authentication is complete, now specify destination to the proxy */
- socksreq[0] = 5; /* version (SOCKS5) */
- socksreq[1] = 1; /* connect */
- socksreq[2] = 0; /* must be zero */
- socksreq[3] = 1; /* IPv4 = 1 */
-
- {
- struct Curl_dns_entry *dns;
- Curl_addrinfo *hp=NULL;
- int rc = Curl_resolv(conn, conn->host.name, (int)conn->remote_port, &dns);
-
- if(rc == CURLRESOLV_ERROR)
- return CURLE_COULDNT_RESOLVE_HOST;
-
- if(rc == CURLRESOLV_PENDING)
- /* this requires that we're in "wait for resolve" state */
- rc = Curl_wait_for_resolv(conn, &dns);
-
- /*
- * We cannot use 'hostent' as a struct that Curl_resolv() returns. It
- * returns a Curl_addrinfo pointer that may not always look the same.
- */
- if(dns)
- hp=dns->addr;
- if (hp) {
- char buf[64];
- unsigned short ip[4];
- Curl_printable_address(hp, buf, sizeof(buf));
-
- if(4 == sscanf( buf, "%hu.%hu.%hu.%hu",
- &ip[0], &ip[1], &ip[2], &ip[3])) {
- socksreq[4] = (unsigned char)ip[0];
- socksreq[5] = (unsigned char)ip[1];
- socksreq[6] = (unsigned char)ip[2];
- socksreq[7] = (unsigned char)ip[3];
- }
- else
- hp = NULL; /* fail! */
-
- Curl_resolv_unlock(data, dns); /* not used anymore from now on */
- }
- if(!hp) {
- failf(data, "Failed to resolve \"%s\" for SOCKS5 connect.",
- conn->host.name);
- return CURLE_COULDNT_RESOLVE_HOST;
- }
- }
-
- *((unsigned short*)&socksreq[8]) = htons(conn->remote_port);
-
- {
- const int packetsize = 10;
-
- code = Curl_write(conn, sock, (char *)socksreq, packetsize, &written);
- if ((code != CURLE_OK) || (written != packetsize)) {
- failf(data, "Failed to send SOCKS5 connect request.");
- return CURLE_COULDNT_CONNECT;
- }
-
- result = blockread_all(conn, sock, (char *)socksreq, packetsize,
- &actualread, timeout);
- if ((result != CURLE_OK) || (actualread != packetsize)) {
- failf(data, "Failed to receive SOCKS5 connect request ack.");
- return CURLE_COULDNT_CONNECT;
- }
-
- if (socksreq[0] != 5) { /* version */
- failf(data,
- "SOCKS5 reply has wrong version, version should be 5.");
- return CURLE_COULDNT_CONNECT;
- }
- if (socksreq[1] != 0) { /* Anything besides 0 is an error */
- failf(data,
- "Can't complete SOCKS5 connection to %d.%d.%d.%d:%d. (%d)",
- (unsigned char)socksreq[4], (unsigned char)socksreq[5],
- (unsigned char)socksreq[6], (unsigned char)socksreq[7],
- (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])),
- socksreq[1]);
- return CURLE_COULDNT_CONNECT;
- }
- }
-
- Curl_nonblock(sock, TRUE);
- return CURLE_OK; /* Proxy was successful! */
-}
diff --git a/Utilities/cmcurl/socks.h b/Utilities/cmcurl/socks.h
deleted file mode 100644
index 0da987998..000000000
--- a/Utilities/cmcurl/socks.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef __SOCKS_H
-#define __SOCKS_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-/*
- * This function logs in to a SOCKS4 proxy and sends the specifics to the
- * final destination server.
- */
-CURLcode Curl_SOCKS4(const char *proxy_name,
- struct connectdata *conn);
-
-/*
- * This function logs in to a SOCKS5 proxy and sends the specifics to the
- * final destination server.
- */
-CURLcode Curl_SOCKS5(const char *proxy_name,
- const char *proxy_password,
- struct connectdata *conn);
-
-#endif
diff --git a/Utilities/cmcurl/speedcheck.c b/Utilities/cmcurl/speedcheck.c
deleted file mode 100644
index adda8a963..000000000
--- a/Utilities/cmcurl/speedcheck.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#include <stdio.h>
-#include <string.h>
-
-#include <curl/curl.h>
-#include "urldata.h"
-#include "sendf.h"
-#include "multiif.h"
-#include "speedcheck.h"
-
-void Curl_speedinit(struct SessionHandle *data)
-{
- memset(&data->state.keeps_speed, 0, sizeof(struct timeval));
-}
-
-CURLcode Curl_speedcheck(struct SessionHandle *data,
- struct timeval now)
-{
- if((data->progress.current_speed >= 0) &&
- data->set.low_speed_time &&
- (Curl_tvlong(data->state.keeps_speed) != 0) &&
- (data->progress.current_speed < data->set.low_speed_limit)) {
- long howlong = Curl_tvdiff(now, data->state.keeps_speed);
-
- /* We are now below the "low speed limit". If we are below it
- for "low speed time" seconds we consider that enough reason
- to abort the download. */
-
- if( (howlong/1000) > data->set.low_speed_time) {
- /* we have been this slow for long enough, now die */
- failf(data,
- "Operation too slow. "
- "Less than %d bytes/sec transfered the last %d seconds",
- data->set.low_speed_limit,
- data->set.low_speed_time);
- return CURLE_OPERATION_TIMEOUTED;
- }
- Curl_expire(data, howlong);
- }
- else {
- /* we keep up the required speed all right */
- data->state.keeps_speed = now;
-
- if(data->set.low_speed_limit)
- /* if there is a low speed limit enabled, we set the expire timer to
- make this connection's speed get checked again no later than when
- this time is up */
- Curl_expire(data, data->set.low_speed_time*1000);
- }
- return CURLE_OK;
-}
diff --git a/Utilities/cmcurl/speedcheck.h b/Utilities/cmcurl/speedcheck.h
deleted file mode 100644
index 62475f640..000000000
--- a/Utilities/cmcurl/speedcheck.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef __SPEEDCHECK_H
-#define __SPEEDCHECK_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#include "timeval.h"
-
-void Curl_speedinit(struct SessionHandle *data);
-CURLcode Curl_speedcheck(struct SessionHandle *data,
- struct timeval now);
-
-#endif
diff --git a/Utilities/cmcurl/splay.c b/Utilities/cmcurl/splay.c
deleted file mode 100644
index 9fb66c76a..000000000
--- a/Utilities/cmcurl/splay.c
+++ /dev/null
@@ -1,425 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1997 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "splay.h"
-
-#define compare(i,j) ((i)-(j))
-
-/* Set this to a key value that will *NEVER* appear otherwise */
-#define KEY_NOTUSED -1
-
-/*
- * Splay using the key i (which may or may not be in the tree.) The starting
- * root is t.
- */
-struct Curl_tree *Curl_splay(int i, struct Curl_tree *t)
-{
- struct Curl_tree N, *l, *r, *y;
- int comp;
-
- if (t == NULL)
- return t;
- N.smaller = N.larger = NULL;
- l = r = &N;
-
- for (;;) {
- comp = compare(i, t->key);
- if (comp < 0) {
- if (t->smaller == NULL)
- break;
- if (compare(i, t->smaller->key) < 0) {
- y = t->smaller; /* rotate smaller */
- t->smaller = y->larger;
- y->larger = t;
- t = y;
- if (t->smaller == NULL)
- break;
- }
- r->smaller = t; /* link smaller */
- r = t;
- t = t->smaller;
- }
- else if (comp > 0) {
- if (t->larger == NULL)
- break;
- if (compare(i, t->larger->key) > 0) {
- y = t->larger; /* rotate larger */
- t->larger = y->smaller;
- y->smaller = t;
- t = y;
- if (t->larger == NULL)
- break;
- }
- l->larger = t; /* link larger */
- l = t;
- t = t->larger;
- }
- else
- break;
- }
-
- l->larger = t->smaller; /* assemble */
- r->smaller = t->larger;
- t->smaller = N.larger;
- t->larger = N.smaller;
-
- return t;
-}
-
-/* Insert key i into the tree t. Return a pointer to the resulting tree or
- NULL if something went wrong. */
-struct Curl_tree *Curl_splayinsert(int i,
- struct Curl_tree *t,
- struct Curl_tree *node)
-{
- if (node == NULL)
- return t;
-
- if (t != NULL) {
- t = Curl_splay(i,t);
- if (compare(i, t->key)==0) {
- /* There already exists a node in the tree with the very same key. Build
- a linked list of nodes. We make the new 'node' struct the new master
- node and make the previous node the first one in the 'same' list. */
-
- node->same = t;
- node->key = i;
- node->smaller = t->smaller;
- node->larger = t->larger;
-
- t->smaller = node; /* in the sub node for this same key, we use the
- smaller pointer to point back to the master
- node */
-
- t->key = KEY_NOTUSED; /* and we set the key in the sub node to NOTUSED
- to quickly identify this node as a subnode */
-
- return node; /* new root node */
- }
- }
-
- if (t == NULL) {
- node->smaller = node->larger = NULL;
- }
- else if (compare(i, t->key) < 0) {
- node->smaller = t->smaller;
- node->larger = t;
- t->smaller = NULL;
-
- }
- else {
- node->larger = t->larger;
- node->smaller = t;
- t->larger = NULL;
- }
- node->key = i;
-
- node->same = NULL; /* no identical node (yet) */
- return node;
-}
-
-#if 0
-/* Deletes 'i' from the tree if it's there (with an exact match). Returns a
- pointer to the resulting tree.
-
- Function not used in libcurl.
-*/
-struct Curl_tree *Curl_splayremove(int i, struct Curl_tree *t,
- struct Curl_tree **removed)
-{
- struct Curl_tree *x;
-
- *removed = NULL; /* default to no removed */
-
- if (t==NULL)
- return NULL;
-
- t = Curl_splay(i,t);
- if (compare(i, t->key) == 0) { /* found it */
-
- /* FIRST! Check if there is a list with identical sizes */
- if((x = t->same)) {
- /* there is, pick one from the list */
-
- /* 'x' is the new root node */
-
- x->key = t->key;
- x->larger = t->larger;
- x->smaller = t->smaller;
-
- *removed = t;
- return x; /* new root */
- }
-
- if (t->smaller == NULL) {
- x = t->larger;
- }
- else {
- x = Curl_splay(i, t->smaller);
- x->larger = t->larger;
- }
- *removed = t;
-
- return x;
- }
- else
- return t; /* It wasn't there */
-}
-#endif
-
-/* Finds and deletes the best-fit node from the tree. Return a pointer to the
- resulting tree. best-fit means the node with the given or lower number */
-struct Curl_tree *Curl_splaygetbest(int i, struct Curl_tree *t,
- struct Curl_tree **removed)
-{
- struct Curl_tree *x;
-
- if (!t) {
- *removed = NULL; /* none removed since there was no root */
- return NULL;
- }
-
- t = Curl_splay(i,t);
- if(compare(i, t->key) < 0) {
- /* too big node, try the smaller chain */
- if(t->smaller)
- t=Curl_splay(t->smaller->key, t);
- else {
- /* fail */
- *removed = NULL;
- return t;
- }
- }
-
- if (compare(i, t->key) >= 0) { /* found it */
- /* FIRST! Check if there is a list with identical sizes */
- x = t->same;
- if(x) {
- /* there is, pick one from the list */
-
- /* 'x' is the new root node */
-
- x->key = t->key;
- x->larger = t->larger;
- x->smaller = t->smaller;
-
- *removed = t;
- return x; /* new root */
- }
-
- if (t->smaller == NULL) {
- x = t->larger;
- }
- else {
- x = Curl_splay(i, t->smaller);
- x->larger = t->larger;
- }
- *removed = t;
-
- return x;
- }
- else {
- *removed = NULL; /* no match */
- return t; /* It wasn't there */
- }
-}
-
-
-/* Deletes the very node we point out from the tree if it's there. Stores a
- pointer to the new resulting tree in 'newroot'.
-
- Returns zero on success and non-zero on errors! TODO: document error codes.
- When returning error, it does not touch the 'newroot' pointer.
-
- NOTE: when the last node of the tree is removed, there's no tree left so
- 'newroot' will be made to point to NULL.
-*/
-int Curl_splayremovebyaddr(struct Curl_tree *t,
- struct Curl_tree *remove,
- struct Curl_tree **newroot)
-{
- struct Curl_tree *x;
-
- if (!t || !remove)
- return 1;
-
- if(KEY_NOTUSED == remove->key) {
- /* Key set to NOTUSED means it is a subnode within a 'same' linked list
- and thus we can unlink it easily. The 'smaller' link of a subnode
- links to the parent node. */
- if (remove->smaller == NULL)
- return 3;
-
- remove->smaller->same = remove->same;
- if(remove->same)
- remove->same->smaller = remove->smaller;
-
- /* Ensures that double-remove gets caught. */
- remove->smaller = NULL;
-
- /* voila, we're done! */
- *newroot = t; /* return the same root */
- return 0;
- }
-
- t = Curl_splay(remove->key, t);
-
- /* First make sure that we got the same root node as the one we want
- to remove, as otherwise we might be trying to remove a node that
- isn't actually in the tree.
-
- We cannot just compare the keys here as a double remove in quick
- succession of a node with key != KEY_NOTUSED && same != NULL
- could return the same key but a different node. */
- if(t != remove)
- return 2;
-
- /* Check if there is a list with identical sizes, as then we're trying to
- remove the root node of a list of nodes with identical keys. */
- x = t->same;
- if(x) {
- /* 'x' is the new root node, we just make it use the root node's
- smaller/larger links */
-
- x->key = t->key;
- x->larger = t->larger;
- x->smaller = t->smaller;
- }
- else {
- /* Remove the root node */
- if (t->smaller == NULL)
- x = t->larger;
- else {
- x = Curl_splay(remove->key, t->smaller);
- x->larger = t->larger;
- }
- }
-
- *newroot = x; /* store new root pointer */
-
- return 0;
-}
-
-#ifdef CURLDEBUG
-
-void Curl_splayprint(struct Curl_tree * t, int d, char output)
-{
- struct Curl_tree *node;
- int i;
- int count;
- if (t == NULL)
- return;
-
- Curl_splayprint(t->larger, d+1, output);
- for (i=0; i<d; i++)
- if(output)
- printf(" ");
-
- if(output) {
- printf("%d[%d]", t->key, i);
- }
-
- for(count=0, node = t->same; node; node = node->same, count++)
- ;
-
- if(output) {
- if(count)
- printf(" [%d more]\n", count);
- else
- printf("\n");
- }
-
- Curl_splayprint(t->smaller, d+1, output);
-}
-#endif
-
-#ifdef TEST_SPLAY
-
-/*#define TEST2 */
-#define MAX 50
-#define TEST2
-
-/* A sample use of these functions. Start with the empty tree, insert some
- stuff into it, and then delete it */
-int main(int argc, char **argv)
-{
- struct Curl_tree *root, *t;
- void *ptrs[MAX];
- int adds=0;
- int rc;
-
- long sizes[]={
- 50, 60, 50, 100, 60, 200, 120, 300, 400, 200, 256, 122, 60, 120, 200, 300,
- 220, 80, 90, 50, 100, 60, 200, 120, 300, 400, 200, 256, 122, 60, 120, 200,
- 300, 220, 80, 90, 50, 100, 60, 200, 120, 300, 400, 200, 256, 122, 60, 120,
- 200, 300, 220, 80, 90};
- int i;
- root = NULL; /* the empty tree */
-
- for (i = 0; i < MAX; i++) {
- int key;
- ptrs[i] = t = (struct Curl_tree *)malloc(sizeof(struct Curl_tree));
-
-#ifdef TEST2
- key = sizes[i];
-#elif defined(TEST1)
- key = (541*i)%1023;
-#elif defined(TEST3)
- key = 100;
-#endif
-
- t->payload = (void *)key; /* for simplicity */
- if(!t) {
- puts("out of memory!");
- return 0;
- }
- root = Curl_splayinsert(key, root, t);
- }
-
-#if 0
- puts("Result:");
- Curl_splayprint(root, 0, 1);
-#endif
-
-#if 1
- for (i = 0; i < MAX; i++) {
- int rem = (i+7)%MAX;
- struct Curl_tree *r;
- printf("Tree look:\n");
- Curl_splayprint(root, 0, 1);
- printf("remove pointer %d, payload %d\n", rem,
- (int)((struct Curl_tree *)ptrs[rem])->payload);
- rc = Curl_splayremovebyaddr(root, (struct Curl_tree *)ptrs[rem], &root);
- if(rc)
- /* failed! */
- printf("remove %d failed!\n", rem);
- }
-#endif
-
- return 0;
-}
-
-#endif /* TEST_SPLAY */
diff --git a/Utilities/cmcurl/splay.h b/Utilities/cmcurl/splay.h
deleted file mode 100644
index 16745341e..000000000
--- a/Utilities/cmcurl/splay.h
+++ /dev/null
@@ -1,54 +0,0 @@
-#ifndef __SPLAY_H
-#define __SPLAY_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1997 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-struct Curl_tree {
- struct Curl_tree *smaller; /* smaller node */
- struct Curl_tree *larger; /* larger node */
- struct Curl_tree *same; /* points to a node with identical key */
- int key; /* the "sort" key */
- void *payload; /* data the splay code doesn't care about */
-};
-
-struct Curl_tree *Curl_splay(int i, struct Curl_tree *t);
-struct Curl_tree *Curl_splayinsert(int key, struct Curl_tree *t,
- struct Curl_tree *newnode);
-#if 0
-struct Curl_tree *Curl_splayremove(int key, struct Curl_tree *t,
- struct Curl_tree **removed);
-#endif
-
-struct Curl_tree *Curl_splaygetbest(int key, struct Curl_tree *t,
- struct Curl_tree **removed);
-int Curl_splayremovebyaddr(struct Curl_tree *t,
- struct Curl_tree *remove,
- struct Curl_tree **newroot);
-
-#ifdef CURLDEBUG
-void Curl_splayprint(struct Curl_tree * t, int d, char output);
-#else
-#define Curl_splayprint(x,y,z)
-#endif
-
-#endif
diff --git a/Utilities/cmcurl/ssh.c b/Utilities/cmcurl/ssh.c
deleted file mode 100644
index 24cba1bac..000000000
--- a/Utilities/cmcurl/ssh.c
+++ /dev/null
@@ -1,979 +0,0 @@
-/***************************************************************************
-* _ _ ____ _
-* Project ___| | | | _ \| |
-* / __| | | | |_) | |
-* | (__| |_| | _ <| |___
-* \___|\___/|_| \_\_____|
-*
-* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
-*
-* This software is licensed as described in the file COPYING, which
-* you should have received as part of this distribution. The terms
-* are also available at http://curl.haxx.se/docs/copyright.html.
-*
-* You may opt to use, copy, modify, merge, publish, distribute and/or sell
-* copies of the Software, and permit persons to whom the Software is
-* furnished to do so, under the terms of the COPYING file.
-*
-* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
-* KIND, either express or implied.
-*
-* $Id$
-***************************************************************************/
-
-/* #define CURL_LIBSSH2_DEBUG */
-
-#include "setup.h"
-
-#ifdef USE_LIBSSH2
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <limits.h>
-
-#include <libssh2.h>
-#include <libssh2_sftp.h>
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-
-#ifdef HAVE_TIME_H
-#include <time.h>
-#endif
-
-#ifdef WIN32
-
-#else /* probably some kind of unix */
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#include <sys/types.h>
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_UTSNAME_H
-#include <sys/utsname.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifdef VMS
-#include <in.h>
-#include <inet.h>
-#endif
-#endif
-
-#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
-#undef in_addr_t
-#define in_addr_t unsigned long
-#endif
-
-#include <curl/curl.h>
-#include "urldata.h"
-#include "sendf.h"
-#include "easyif.h" /* for Curl_convert_... prototypes */
-
-#include "if2ip.h"
-#include "hostip.h"
-#include "progress.h"
-#include "transfer.h"
-#include "escape.h"
-#include "http.h" /* for HTTP proxy tunnel stuff */
-#include "ssh.h"
-#include "url.h"
-#include "speedcheck.h"
-#include "getinfo.h"
-
-#include "strtoofft.h"
-#include "strequal.h"
-#include "sslgen.h"
-#include "connect.h"
-#include "strerror.h"
-#include "memory.h"
-#include "inet_ntop.h"
-#include "select.h"
-#include "parsedate.h" /* for the week day and month names */
-#include "sockaddr.h" /* required for Curl_sockaddr_storage */
-#include "multiif.h"
-
-#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
-#include "inet_ntoa_r.h"
-#endif
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-#if defined(WIN32) || defined(MSDOS) || defined(__EMX__)
-#define DIRSEP '\\'
-#else
-#define DIRSEP '/'
-#endif
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
-#ifdef CURLDEBUG
-#include "memdebug.h"
-#endif
-
-#ifndef LIBSSH2_SFTP_S_IRUSR
-/* Here's a work-around for those of you who happend to run a libssh2 version
- that is 0.14 or older. We should remove this kludge as soon as we can
- require a more recent libssh2 release. */
-#ifndef S_IRGRP
-#define S_IRGRP 0
-#endif
-
-#ifndef S_IROTH
-#define S_IROTH 0
-#endif
-
-#define LIBSSH2_SFTP_S_IRUSR S_IRUSR
-#define LIBSSH2_SFTP_S_IWUSR S_IWUSR
-#define LIBSSH2_SFTP_S_IRGRP S_IRGRP
-#define LIBSSH2_SFTP_S_IROTH S_IROTH
-#define LIBSSH2_SFTP_S_IRUSR S_IRUSR
-#define LIBSSH2_SFTP_S_IWUSR S_IWUSR
-#define LIBSSH2_SFTP_S_IRGRP S_IRGRP
-#define LIBSSH2_SFTP_S_IROTH S_IROTH
-#define LIBSSH2_SFTP_S_IFMT S_IFMT
-#define LIBSSH2_SFTP_S_IFDIR S_IFDIR
-#define LIBSSH2_SFTP_S_IFLNK S_IFLNK
-#define LIBSSH2_SFTP_S_IFSOCK S_IFSOCK
-#define LIBSSH2_SFTP_S_IFCHR S_IFCHR
-#define LIBSSH2_SFTP_S_IFBLK S_IFBLK
-#define LIBSSH2_SFTP_S_IXUSR S_IXUSR
-#define LIBSSH2_SFTP_S_IWGRP S_IWGRP
-#define LIBSSH2_SFTP_S_IXGRP S_IXGRP
-#define LIBSSH2_SFTP_S_IWOTH S_IWOTH
-#define LIBSSH2_SFTP_S_IXOTH S_IXOTH
-#endif
-
-static LIBSSH2_ALLOC_FUNC(libssh2_malloc);
-static LIBSSH2_REALLOC_FUNC(libssh2_realloc);
-static LIBSSH2_FREE_FUNC(libssh2_free);
-
-static void
-kbd_callback(const char *name, int name_len, const char *instruction,
- int instruction_len, int num_prompts,
- const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
- LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
- void **abstract)
-{
- struct SSHPROTO *ssh = (struct SSHPROTO *)*abstract;
-
-#ifdef CURL_LIBSSH2_DEBUG
- fprintf(stderr, "name=%s\n", name);
- fprintf(stderr, "name_len=%d\n", name_len);
- fprintf(stderr, "instruction=%s\n", instruction);
- fprintf(stderr, "instruction_len=%d\n", instruction_len);
- fprintf(stderr, "num_prompts=%d\n", num_prompts);
-#else
- (void)name;
- (void)name_len;
- (void)instruction;
- (void)instruction_len;
-#endif /* CURL_LIBSSH2_DEBUG */
- if (num_prompts == 1) {
- responses[0].text = strdup(ssh->passwd);
- responses[0].length = strlen(ssh->passwd);
- }
- (void)prompts;
- (void)abstract;
-} /* kbd_callback */
-
-static CURLcode libssh2_error_to_CURLE(struct connectdata *conn)
-{
- int errorcode;
- struct SSHPROTO *scp = conn->data->reqdata.proto.ssh;
-
- /* Get the libssh2 error code and string */
- errorcode = libssh2_session_last_error(scp->ssh_session, &scp->errorstr,
- NULL, 0);
- if (errorcode == LIBSSH2_FX_OK)
- return CURLE_OK;
-
- infof(conn->data, "libssh2 error %d, '%s'\n", errorcode, scp->errorstr);
-
- /* TODO: map some of the libssh2 errors to the more appropriate CURLcode
- error code, and possibly add a few new SSH-related one. We must however
- not return or even depend on libssh2 errors in the public libcurl API */
-
- return CURLE_SSH;
-}
-
-static LIBSSH2_ALLOC_FUNC(libssh2_malloc)
-{
- return malloc(count);
- (void)abstract;
-}
-
-static LIBSSH2_REALLOC_FUNC(libssh2_realloc)
-{
- return realloc(ptr, count);
- (void)abstract;
-}
-
-static LIBSSH2_FREE_FUNC(libssh2_free)
-{
- free(ptr);
- (void)abstract;
-}
-
-static CURLcode ssh_init(struct connectdata *conn)
-{
- struct SessionHandle *data = conn->data;
- struct SSHPROTO *ssh;
- if (data->reqdata.proto.ssh)
- return CURLE_OK;
-
- ssh = (struct SSHPROTO *)calloc(sizeof(struct SSHPROTO), 1);
- if (!ssh)
- return CURLE_OUT_OF_MEMORY;
-
- data->reqdata.proto.ssh = ssh;
-
- /* get some initial data into the ssh struct */
- ssh->bytecountp = &data->reqdata.keep.bytecount;
-
- /* no need to duplicate them, this connectdata struct won't change */
- ssh->user = conn->user;
- ssh->passwd = conn->passwd;
-
- ssh->errorstr = NULL;
-
- ssh->ssh_session = NULL;
- ssh->ssh_channel = NULL;
- ssh->sftp_session = NULL;
- ssh->sftp_handle = NULL;
-
- return CURLE_OK;
-}
-
-/*
- * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
- * do protocol-specific actions at connect-time.
- */
-CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done)
-{
- int i;
- struct SSHPROTO *ssh;
- const char *fingerprint;
- const char *authlist;
- char *home;
- char rsa_pub[PATH_MAX];
- char rsa[PATH_MAX];
- char tempHome[PATH_MAX];
- curl_socket_t sock;
- char *real_path;
- char *working_path;
- int working_path_len;
- bool authed = FALSE;
- CURLcode result;
- struct SessionHandle *data = conn->data;
-
- rsa_pub[0] = rsa[0] = '\0';
-
- result = ssh_init(conn);
- if (result)
- return result;
-
- ssh = data->reqdata.proto.ssh;
-
- working_path = curl_easy_unescape(data, data->reqdata.path, 0,
- &working_path_len);
- if (!working_path)
- return CURLE_OUT_OF_MEMORY;
-
-#ifdef CURL_LIBSSH2_DEBUG
- if (ssh->user) {
- infof(data, "User: %s\n", ssh->user);
- }
- if (ssh->passwd) {
- infof(data, "Password: %s\n", ssh->passwd);
- }
-#endif /* CURL_LIBSSH2_DEBUG */
- sock = conn->sock[FIRSTSOCKET];
- ssh->ssh_session = libssh2_session_init_ex(libssh2_malloc, libssh2_free,
- libssh2_realloc, ssh);
- if (ssh->ssh_session == NULL) {
- failf(data, "Failure initialising ssh session\n");
- Curl_safefree(ssh->path);
- return CURLE_FAILED_INIT;
- }
-#ifdef CURL_LIBSSH2_DEBUG
- infof(data, "SSH socket: %d\n", sock);
-#endif /* CURL_LIBSSH2_DEBUG */
-
- if (libssh2_session_startup(ssh->ssh_session, sock)) {
- failf(data, "Failure establishing ssh session\n");
- libssh2_session_free(ssh->ssh_session);
- ssh->ssh_session = NULL;
- Curl_safefree(ssh->path);
- return CURLE_FAILED_INIT;
- }
-
- /*
- * Before we authenticate we should check the hostkey's fingerprint against
- * our known hosts. How that is handled (reading from file, whatever) is
- * up to us. As for know not much is implemented, besides showing how to
- * get the fingerprint.
- */
- fingerprint = libssh2_hostkey_hash(ssh->ssh_session,
- LIBSSH2_HOSTKEY_HASH_MD5);
-
-#ifdef CURL_LIBSSH2_DEBUG
- /* The fingerprint points to static storage (!), don't free() it. */
- infof(data, "Fingerprint: ");
- for (i = 0; i < 16; i++) {
- infof(data, "%02X ", (unsigned char) fingerprint[i]);
- }
- infof(data, "\n");
-#endif /* CURL_LIBSSH2_DEBUG */
-
- /* TBD - methods to check the host keys need to be done */
-
- /*
- * Figure out authentication methods
- * NB: As soon as we have provided a username to an openssh server we must
- * never change it later. Thus, always specify the correct username here,
- * even though the libssh2 docs kind of indicate that it should be possible
- * to get a 'generic' list (not user-specific) of authentication methods,
- * presumably with a blank username. That won't work in my experience.
- * So always specify it here.
- */
- authlist = libssh2_userauth_list(ssh->ssh_session, ssh->user,
- strlen(ssh->user));
-
- /*
- * Check the supported auth types in the order I feel is most secure with the
- * requested type of authentication
- */
- if ((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
- (strstr(authlist, "publickey") != NULL)) {
- /* To ponder about: should really the lib be messing about with the HOME
- environment variable etc? */
- home = curl_getenv("HOME");
-
- if (data->set.ssh_public_key)
- snprintf(rsa_pub, sizeof(rsa_pub), "%s", data->set.ssh_public_key);
- else if (home)
- snprintf(rsa_pub, sizeof(rsa_pub), "%s/.ssh/id_dsa.pub", home);
-
- if (data->set.ssh_private_key)
- snprintf(rsa, sizeof(rsa), "%s", data->set.ssh_private_key);
- else if (home)
- snprintf(rsa, sizeof(rsa), "%s/.ssh/id_dsa", home);
-
- curl_free(home);
-
- if (rsa_pub[0]) {
- /* The function below checks if the files exists, no need to stat() here.
- */
- if (libssh2_userauth_publickey_fromfile(ssh->ssh_session, ssh->user,
- rsa_pub, rsa, "") == 0) {
- authed = TRUE;
- }
- }
- }
- if (!authed &&
- (data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
- (strstr(authlist, "password") != NULL)) {
- if (!libssh2_userauth_password(ssh->ssh_session, ssh->user, ssh->passwd))
- authed = TRUE;
- }
- if (!authed && (data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
- (strstr(authlist, "hostbased") != NULL)) {
- }
- if (!authed && (data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
- && (strstr(authlist, "keyboard-interactive") != NULL)) {
- /* Authentication failed. Continue with keyboard-interactive now. */
- if (libssh2_userauth_keyboard_interactive_ex(ssh->ssh_session, ssh->user,
- strlen(ssh->user),
- &kbd_callback) == 0) {
- authed = TRUE;
- }
- }
-
- if (!authed) {
- failf(data, "Authentication failure\n");
- libssh2_session_free(ssh->ssh_session);
- ssh->ssh_session = NULL;
- Curl_safefree(ssh->path);
- return CURLE_FAILED_INIT;
- }
-
- /*
- * At this point we have an authenticated ssh session.
- */
- conn->sockfd = sock;
- conn->writesockfd = CURL_SOCKET_BAD;
-
- if (conn->protocol == PROT_SFTP) {
- /*
- * Start the libssh2 sftp session
- */
- ssh->sftp_session = libssh2_sftp_init(ssh->ssh_session);
- if (ssh->sftp_session == NULL) {
- failf(data, "Failure initialising sftp session\n");
- libssh2_sftp_shutdown(ssh->sftp_session);
- ssh->sftp_session = NULL;
- libssh2_session_free(ssh->ssh_session);
- ssh->ssh_session = NULL;
- return CURLE_FAILED_INIT;
- }
-
- /*
- * Get the "home" directory
- */
- i = libssh2_sftp_realpath(ssh->sftp_session, ".", tempHome, PATH_MAX-1);
- if (i > 0) {
- /* It seems that this string is not always NULL terminated */
- tempHome[i] = '\0';
- ssh->homedir = (char *)strdup(tempHome);
- if (!ssh->homedir) {
- libssh2_sftp_shutdown(ssh->sftp_session);
- ssh->sftp_session = NULL;
- libssh2_session_free(ssh->ssh_session);
- ssh->ssh_session = NULL;
- return CURLE_OUT_OF_MEMORY;
- }
- }
- else {
- /* Return the error type */
- i = libssh2_sftp_last_error(ssh->sftp_session);
- DEBUGF(infof(data, "error = %d\n", i));
- }
- }
-
- /* Check for /~/ , indicating realative to the users home directory */
- if (conn->protocol == PROT_SCP) {
- real_path = (char *)malloc(working_path_len+1);
- if (real_path == NULL) {
- Curl_safefree(working_path);
- libssh2_session_free(ssh->ssh_session);
- ssh->ssh_session = NULL;
- return CURLE_OUT_OF_MEMORY;
- }
- if (working_path[1] == '~')
- /* It is referenced to the home directory, so strip the leading '/' */
- memcpy(real_path, working_path+1, 1 + working_path_len-1);
- else
- memcpy(real_path, working_path, 1 + working_path_len);
- }
- else if (conn->protocol == PROT_SFTP) {
- if (working_path[1] == '~') {
- real_path = (char *)malloc(strlen(ssh->homedir) +
- working_path_len + 1);
- if (real_path == NULL) {
- libssh2_sftp_shutdown(ssh->sftp_session);
- ssh->sftp_session = NULL;
- libssh2_session_free(ssh->ssh_session);
- ssh->ssh_session = NULL;
- Curl_safefree(working_path);
- return CURLE_OUT_OF_MEMORY;
- }
- /* It is referenced to the home directory, so strip the leading '/' */
- memcpy(real_path, ssh->homedir, strlen(ssh->homedir));
- real_path[strlen(ssh->homedir)] = '/';
- real_path[strlen(ssh->homedir)+1] = '\0';
- if (working_path_len > 3) {
- memcpy(real_path+strlen(ssh->homedir)+1, working_path + 3,
- 1 + working_path_len -3);
- }
- }
- else {
- real_path = (char *)malloc(working_path_len+1);
- if (real_path == NULL) {
- libssh2_session_free(ssh->ssh_session);
- ssh->ssh_session = NULL;
- Curl_safefree(working_path);
- return CURLE_OUT_OF_MEMORY;
- }
- memcpy(real_path, working_path, 1+working_path_len);
- }
- }
- else
- return CURLE_FAILED_INIT;
-
- Curl_safefree(working_path);
- ssh->path = real_path;
-
- *done = TRUE;
- return CURLE_OK;
-}
-
-CURLcode Curl_scp_do(struct connectdata *conn, bool *done)
-{
- struct stat sb;
- struct SSHPROTO *scp = conn->data->reqdata.proto.ssh;
- CURLcode res = CURLE_OK;
-
- *done = TRUE; /* unconditionally */
-
- if (conn->data->set.upload) {
- /*
- * NOTE!!! libssh2 requires that the destination path is a full path
- * that includes the destination file and name OR ends in a "/" .
- * If this is not done the destination file will be named the
- * same name as the last directory in the path.
- */
- scp->ssh_channel = libssh2_scp_send_ex(scp->ssh_session, scp->path,
- LIBSSH2_SFTP_S_IRUSR|
- LIBSSH2_SFTP_S_IWUSR|
- LIBSSH2_SFTP_S_IRGRP|
- LIBSSH2_SFTP_S_IROTH,
- conn->data->set.infilesize, 0, 0);
- if (!scp->ssh_channel)
- return CURLE_FAILED_INIT;
-
- /* upload data */
- res = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
- }
- else {
- /*
- * We must check the remote file, if it is a directory no vaules will
- * be set in sb
- */
- curl_off_t bytecount;
- memset(&sb, 0, sizeof(struct stat));
- scp->ssh_channel = libssh2_scp_recv(scp->ssh_session, scp->path, &sb);
- if (!scp->ssh_channel) {
- if ((sb.st_mode == 0) && (sb.st_atime == 0) && (sb.st_mtime == 0) &&
- (sb.st_size == 0)) {
- /* Since sb is still empty, it is likely the file was not found */
- return CURLE_REMOTE_FILE_NOT_FOUND;
- }
- return libssh2_error_to_CURLE(conn);
- }
- /* download data */
- bytecount = (curl_off_t) sb.st_size;
- conn->data->reqdata.maxdownload = (curl_off_t) sb.st_size;
- res = Curl_setup_transfer(conn, FIRSTSOCKET,
- bytecount, FALSE, NULL, -1, NULL);
- }
-
- return res;
-}
-
-CURLcode Curl_scp_done(struct connectdata *conn, CURLcode status,
- bool premature)
-{
- struct SSHPROTO *scp = conn->data->reqdata.proto.ssh;
- (void)premature; /* not used */
-
- Curl_safefree(scp->path);
- scp->path = NULL;
-
- if (scp->ssh_channel) {
- if (libssh2_channel_close(scp->ssh_channel) < 0) {
- infof(conn->data, "Failed to stop libssh2 channel subsystem\n");
- }
- }
-
- if (scp->ssh_session) {
- libssh2_session_disconnect(scp->ssh_session, "Shutdown");
- libssh2_session_free(scp->ssh_session);
- scp->ssh_session = NULL;
- }
-
- free(conn->data->reqdata.proto.ssh);
- conn->data->reqdata.proto.ssh = NULL;
- Curl_pgrsDone(conn);
-
- (void)status; /* unused */
-
- return CURLE_OK;
-}
-
-/* return number of received (decrypted) bytes */
-ssize_t Curl_scp_send(struct connectdata *conn, int sockindex,
- void *mem, size_t len)
-{
- ssize_t nwrite;
-
- /* libssh2_channel_write() returns int
- *
- * NOTE: we should not store nor rely on connection-related data to be
- * in the SessionHandle struct
- */
- nwrite = (ssize_t)
- libssh2_channel_write(conn->data->reqdata.proto.ssh->ssh_channel,
- mem, len);
- (void)sockindex;
- return nwrite;
-}
-
-/*
- * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
- * a regular CURLcode value.
- */
-ssize_t Curl_scp_recv(struct connectdata *conn, int sockindex,
- char *mem, size_t len)
-{
- ssize_t nread;
-
- /* libssh2_channel_read() returns int
- *
- * NOTE: we should not store nor rely on connection-related data to be
- * in the SessionHandle struct
- */
-
- nread = (ssize_t)
- libssh2_channel_read(conn->data->reqdata.proto.ssh->ssh_channel,
- mem, len);
- (void)sockindex;
- return nread;
-}
-
-/*
- * =============== SFTP ===============
- */
-
-CURLcode Curl_sftp_do(struct connectdata *conn, bool *done)
-{
- LIBSSH2_SFTP_ATTRIBUTES attrs;
- struct SSHPROTO *sftp = conn->data->reqdata.proto.ssh;
- CURLcode res = CURLE_OK;
- struct SessionHandle *data = conn->data;
- curl_off_t bytecount = 0;
- char *buf = data->state.buffer;
-
- *done = TRUE; /* unconditionally */
-
- if (data->set.upload) {
- /*
- * NOTE!!! libssh2 requires that the destination path is a full path
- * that includes the destination file and name OR ends in a "/" .
- * If this is not done the destination file will be named the
- * same name as the last directory in the path.
- */
- sftp->sftp_handle =
- libssh2_sftp_open(sftp->sftp_session, sftp->path,
- LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT,
- LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
- LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);
- if (!sftp->sftp_handle)
- return CURLE_FAILED_INIT;
-
- /* upload data */
- res = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
- }
- else {
- if (sftp->path[strlen(sftp->path)-1] == '/') {
- /*
- * This is a directory that we are trying to get, so produce a
- * directory listing
- *
- * **BLOCKING behaviour** This should be made into a state machine and
- * get a separate function called from Curl_sftp_recv() when there is
- * data to read from the network, instead of "hanging" here.
- */
- char filename[PATH_MAX+1];
- int len, totalLen, currLen;
- char *line;
-
- sftp->sftp_handle =
- libssh2_sftp_opendir(sftp->sftp_session, sftp->path);
- if (!sftp->sftp_handle)
- return CURLE_SSH;
-
- while ((len = libssh2_sftp_readdir(sftp->sftp_handle, filename,
- PATH_MAX, &attrs)) > 0) {
- filename[len] = '\0';
-
- if (data->set.ftp_list_only) {
- if ((attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
- ((attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
- LIBSSH2_SFTP_S_IFDIR)) {
- infof(data, "%s\n", filename);
- }
- }
- else {
- totalLen = 80 + len;
- line = (char *)malloc(totalLen);
- if (!line)
- return CURLE_OUT_OF_MEMORY;
-
- if (!(attrs.flags & LIBSSH2_SFTP_ATTR_UIDGID))
- attrs.uid = attrs.gid =0;
-
- currLen = snprintf(line, totalLen, "---------- 1 %5d %5d",
- attrs.uid, attrs.gid);
-
- if (attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) {
- if ((attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
- LIBSSH2_SFTP_S_IFDIR) {
- line[0] = 'd';
- }
- else if ((attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
- LIBSSH2_SFTP_S_IFLNK) {
- line[0] = 'l';
- }
- else if ((attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
- LIBSSH2_SFTP_S_IFSOCK) {
- line[0] = 's';
- }
- else if ((attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
- LIBSSH2_SFTP_S_IFCHR) {
- line[0] = 'c';
- }
- else if ((attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
- LIBSSH2_SFTP_S_IFBLK) {
- line[0] = 'b';
- }
- if (attrs.permissions & LIBSSH2_SFTP_S_IRUSR) {
- line[1] = 'r';
- }
- if (attrs.permissions & LIBSSH2_SFTP_S_IWUSR) {
- line[2] = 'w';
- }
- if (attrs.permissions & LIBSSH2_SFTP_S_IXUSR) {
- line[3] = 'x';
- }
- if (attrs.permissions & LIBSSH2_SFTP_S_IRGRP) {
- line[4] = 'r';
- }
- if (attrs.permissions & LIBSSH2_SFTP_S_IWGRP) {
- line[5] = 'w';
- }
- if (attrs.permissions & LIBSSH2_SFTP_S_IXGRP) {
- line[6] = 'x';
- }
- if (attrs.permissions & LIBSSH2_SFTP_S_IROTH) {
- line[7] = 'r';
- }
- if (attrs.permissions & LIBSSH2_SFTP_S_IWOTH) {
- line[8] = 'w';
- }
- if (attrs.permissions & LIBSSH2_SFTP_S_IXOTH) {
- line[9] = 'x';
- }
- }
- if (attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) {
- currLen += snprintf(line+currLen, totalLen-currLen, "%11lld",
- attrs.filesize);
- }
- if (attrs.flags & LIBSSH2_SFTP_ATTR_ACMODTIME) {
- const char *months[12] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
- struct tm *nowParts;
- time_t now, remoteTime;
-
- now = time(NULL);
- remoteTime = (time_t)attrs.mtime;
- nowParts = localtime(&remoteTime);
-
- if ((time_t)attrs.mtime > (now - (3600 * 24 * 180))) {
- currLen += snprintf(line+currLen, totalLen-currLen,
- " %s %2d %2d:%02d", months[nowParts->tm_mon],
- nowParts->tm_mday, nowParts->tm_hour,
- nowParts->tm_min);
- }
- else {
- currLen += snprintf(line+currLen, totalLen-currLen,
- " %s %2d %5d", months[nowParts->tm_mon],
- nowParts->tm_mday, 1900+nowParts->tm_year);
- }
- }
- currLen += snprintf(line+currLen, totalLen-currLen, " %s", filename);
- if ((attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
- ((attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
- LIBSSH2_SFTP_S_IFLNK)) {
- char linkPath[PATH_MAX + 1];
-
- snprintf(linkPath, PATH_MAX, "%s%s", sftp->path, filename);
- len = libssh2_sftp_readlink(sftp->sftp_session, linkPath, filename,
- PATH_MAX);
- line = realloc(line, totalLen + 4 + len);
- if (!line)
- return CURLE_OUT_OF_MEMORY;
-
- currLen += snprintf(line+currLen, totalLen-currLen, " -> %s",
- filename);
- }
-
- currLen += snprintf(line+currLen, totalLen-currLen, "\n");
- res = Curl_client_write(conn, CLIENTWRITE_BODY, line, 0);
- free(line);
- }
- }
- libssh2_sftp_closedir(sftp->sftp_handle);
- sftp->sftp_handle = NULL;
-
- /* no data to transfer */
- res = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
- }
- else {
- /*
- * Work on getting the specified file
- */
- sftp->sftp_handle =
- libssh2_sftp_open(sftp->sftp_session, sftp->path, LIBSSH2_FXF_READ,
- LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
- LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);
- if (!sftp->sftp_handle)
- return CURLE_SSH;
-
- if (libssh2_sftp_stat(sftp->sftp_session, sftp->path, &attrs)) {
- /*
- * libssh2_sftp_open() didn't return an error, so maybe the server
- * just doesn't support stat()
- */
- data->reqdata.size = -1;
- data->reqdata.maxdownload = -1;
- }
- else {
- data->reqdata.size = attrs.filesize;
- data->reqdata.maxdownload = attrs.filesize;
- Curl_pgrsSetDownloadSize(data, attrs.filesize);
- }
-
- Curl_pgrsTime(data, TIMER_STARTTRANSFER);
-
- /* Now download data. The libssh2 0.14 doesn't offer any way to do this
- without using this BLOCKING approach, so here's room for improvement
- once libssh2 can return EWOULDBLOCK to us. */
-#if 0
- /* code left here just because this is what this function will use the
- day libssh2 is improved */
- res = Curl_setup_transfer(conn, FIRSTSOCKET,
- bytecount, FALSE, NULL, -1, NULL);
-#endif
- while (res == CURLE_OK) {
- size_t nread;
- /* NOTE: most *read() functions return ssize_t but this returns size_t
- which normally is unsigned! */
- nread = libssh2_sftp_read(data->reqdata.proto.ssh->sftp_handle,
- buf, BUFSIZE-1);
-
- if (nread > 0)
- buf[nread] = 0;
-
- /* this check can be changed to a <= 0 when nread is changed to a
- signed variable type */
- if ((nread == 0) || (nread == (size_t)~0))
- break;
-
- bytecount += nread;
-
- res = Curl_client_write(conn, CLIENTWRITE_BODY, buf, nread);
- if(res)
- return res;
-
- Curl_pgrsSetDownloadCounter(data, bytecount);
-
- if(Curl_pgrsUpdate(conn))
- res = CURLE_ABORTED_BY_CALLBACK;
- else {
- struct timeval now = Curl_tvnow();
- res = Curl_speedcheck(data, now);
- }
- }
- if(Curl_pgrsUpdate(conn))
- res = CURLE_ABORTED_BY_CALLBACK;
-
- /* no (more) data to transfer */
- res = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
- }
- }
-
- return res;
-}
-
-CURLcode Curl_sftp_done(struct connectdata *conn, CURLcode status,
- bool premature)
-{
- struct SSHPROTO *sftp = conn->data->reqdata.proto.ssh;
- (void)premature; /* not used */
-
- Curl_safefree(sftp->path);
- sftp->path = NULL;
-
- Curl_safefree(sftp->homedir);
- sftp->homedir = NULL;
-
- if (sftp->sftp_handle) {
- if (libssh2_sftp_close(sftp->sftp_handle) < 0) {
- infof(conn->data, "Failed to close libssh2 file\n");
- }
- }
-
- if (sftp->sftp_session) {
- if (libssh2_sftp_shutdown(sftp->sftp_session) < 0) {
- infof(conn->data, "Failed to stop libssh2 sftp subsystem\n");
- }
- }
-
- if (sftp->ssh_channel) {
- if (libssh2_channel_close(sftp->ssh_channel) < 0) {
- infof(conn->data, "Failed to stop libssh2 channel subsystem\n");
- }
- }
-
- if (sftp->ssh_session) {
- libssh2_session_disconnect(sftp->ssh_session, "Shutdown");
- libssh2_session_free(sftp->ssh_session);
- sftp->ssh_session = NULL;
- }
-
- free(conn->data->reqdata.proto.ssh);
- conn->data->reqdata.proto.ssh = NULL;
- Curl_pgrsDone(conn);
-
- (void)status; /* unused */
-
- return CURLE_OK;
-}
-
-/* return number of received (decrypted) bytes */
-ssize_t Curl_sftp_send(struct connectdata *conn, int sockindex,
- void *mem, size_t len)
-{
- ssize_t nwrite;
-
- /* libssh2_sftp_write() returns size_t !*/
-
- nwrite = (ssize_t)
- libssh2_sftp_write(conn->data->reqdata.proto.ssh->sftp_handle, mem, len);
- (void)sockindex;
- return nwrite;
-}
-
-/*
- * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
- * a regular CURLcode value.
- */
-ssize_t Curl_sftp_recv(struct connectdata *conn, int sockindex,
- char *mem, size_t len)
-{
- ssize_t nread;
-
- /* libssh2_sftp_read() returns size_t !*/
-
- nread = (ssize_t)
- libssh2_sftp_read(conn->data->reqdata.proto.ssh->sftp_handle, mem, len);
- (void)sockindex;
- return nread;
-}
-
-#endif /* USE_LIBSSH2 */
diff --git a/Utilities/cmcurl/ssh.h b/Utilities/cmcurl/ssh.h
deleted file mode 100644
index d9144903b..000000000
--- a/Utilities/cmcurl/ssh.h
+++ /dev/null
@@ -1,49 +0,0 @@
-#ifndef __SSH_H
-#define __SSH_H
-
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#ifdef USE_LIBSSH2
-
-CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done);
-
-CURLcode Curl_scp_do(struct connectdata *conn, bool *done);
-CURLcode Curl_scp_done(struct connectdata *conn, CURLcode, bool premature);
-
-ssize_t Curl_scp_send(struct connectdata *conn, int sockindex,
- void *mem, size_t len);
-ssize_t Curl_scp_recv(struct connectdata *conn, int sockindex,
- char *mem, size_t len);
-
-CURLcode Curl_sftp_do(struct connectdata *conn, bool *done);
-CURLcode Curl_sftp_done(struct connectdata *conn, CURLcode, bool premature);
-
-ssize_t Curl_sftp_send(struct connectdata *conn, int sockindex,
- void *mem, size_t len);
-ssize_t Curl_sftp_recv(struct connectdata *conn, int sockindex,
- char *mem, size_t len);
-
-#endif /* USE_LIBSSH2 */
-
-#endif /* __SSH_H */
diff --git a/Utilities/cmcurl/sslgen.c b/Utilities/cmcurl/sslgen.c
deleted file mode 100644
index f110a51ea..000000000
--- a/Utilities/cmcurl/sslgen.c
+++ /dev/null
@@ -1,618 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-/* This file is for "generic" SSL functions that all libcurl internals should
- use. It is responsible for calling the proper 'ossl' function in ssluse.c
- (OpenSSL based) or the 'gtls' function in gtls.c (GnuTLS based).
-
- SSL-functions in libcurl should call functions in this source file, and not
- to any specific SSL-layer.
-
- Curl_ssl_ - prefix for generic ones
- Curl_ossl_ - prefix for OpenSSL ones
- Curl_gtls_ - prefix for GnuTLS ones
-
- "SSL/TLS Strong Encryption: An Introduction"
- http://httpd.apache.org/docs-2.0/ssl/ssl_intro.html
-*/
-
-#include "setup.h"
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-
-#include "urldata.h"
-#define SSLGEN_C
-#include "sslgen.h" /* generic SSL protos etc */
-#include "ssluse.h" /* OpenSSL versions */
-#include "gtls.h" /* GnuTLS versions */
-#include "sendf.h"
-#include "strequal.h"
-#include "url.h"
-#include "memory.h"
-/* The last #include file should be: */
-#include "memdebug.h"
-
-/* "global" init done? */
-static bool init_ssl=FALSE;
-
-static bool safe_strequal(char* str1, char* str2);
-
-static bool safe_strequal(char* str1, char* str2)
-{
- if(str1 && str2)
- /* both pointers point to something then compare them */
- return (bool)(0 != strequal(str1, str2));
- else
- /* if both pointers are NULL then treat them as equal */
- return (bool)(!str1 && !str2);
-}
-
-bool
-Curl_ssl_config_matches(struct ssl_config_data* data,
- struct ssl_config_data* needle)
-{
- if((data->version == needle->version) &&
- (data->verifypeer == needle->verifypeer) &&
- (data->verifyhost == needle->verifyhost) &&
- safe_strequal(data->CApath, needle->CApath) &&
- safe_strequal(data->CAfile, needle->CAfile) &&
- safe_strequal(data->random_file, needle->random_file) &&
- safe_strequal(data->egdsocket, needle->egdsocket) &&
- safe_strequal(data->cipher_list, needle->cipher_list))
- return TRUE;
-
- return FALSE;
-}
-
-bool
-Curl_clone_ssl_config(struct ssl_config_data *source,
- struct ssl_config_data *dest)
-{
- dest->verifyhost = source->verifyhost;
- dest->verifypeer = source->verifypeer;
- dest->version = source->version;
-
- if(source->CAfile) {
- dest->CAfile = strdup(source->CAfile);
- if(!dest->CAfile)
- return FALSE;
- }
-
- if(source->CApath) {
- dest->CApath = strdup(source->CApath);
- if(!dest->CApath)
- return FALSE;
- }
-
- if(source->cipher_list) {
- dest->cipher_list = strdup(source->cipher_list);
- if(!dest->cipher_list)
- return FALSE;
- }
-
- if(source->egdsocket) {
- dest->egdsocket = strdup(source->egdsocket);
- if(!dest->egdsocket)
- return FALSE;
- }
-
- if(source->random_file) {
- dest->random_file = strdup(source->random_file);
- if(!dest->random_file)
- return FALSE;
- }
-
- return TRUE;
-}
-
-void Curl_free_ssl_config(struct ssl_config_data* sslc)
-{
- if(sslc->CAfile)
- free(sslc->CAfile);
-
- if(sslc->CApath)
- free(sslc->CApath);
-
- if(sslc->cipher_list)
- free(sslc->cipher_list);
-
- if(sslc->egdsocket)
- free(sslc->egdsocket);
-
- if(sslc->random_file)
- free(sslc->random_file);
-}
-
-/**
- * Global SSL init
- *
- * @retval 0 error initializing SSL
- * @retval 1 SSL initialized successfully
- */
-int Curl_ssl_init(void)
-{
- /* make sure this is only done once */
- if(init_ssl)
- return 1;
- init_ssl = TRUE; /* never again */
-
-#ifdef USE_SSLEAY
- return Curl_ossl_init();
-#else
-#ifdef USE_GNUTLS
- return Curl_gtls_init();
-#else
- /* no SSL support */
- return 1;
-#endif /* USE_GNUTLS */
-#endif /* USE_SSLEAY */
-}
-
-
-/* Global cleanup */
-void Curl_ssl_cleanup(void)
-{
- if(init_ssl) {
- /* only cleanup if we did a previous init */
-#ifdef USE_SSLEAY
- Curl_ossl_cleanup();
-#else
-#ifdef USE_GNUTLS
- Curl_gtls_cleanup();
-#endif /* USE_GNUTLS */
-#endif /* USE_SSLEAY */
- init_ssl = FALSE;
- }
-}
-
-CURLcode
-Curl_ssl_connect(struct connectdata *conn, int sockindex)
-{
-#ifdef USE_SSL
- /* mark this is being ssl enabled from here on. */
- conn->ssl[sockindex].use = TRUE;
-
-#ifdef USE_SSLEAY
- return Curl_ossl_connect(conn, sockindex);
-#else
-#ifdef USE_GNUTLS
- return Curl_gtls_connect(conn, sockindex);
-#endif /* USE_GNUTLS */
-#endif /* USE_SSLEAY */
-
-#else
- /* without SSL */
- (void)conn;
- (void)sockindex;
- return CURLE_OK;
-#endif /* USE_SSL */
-}
-
-CURLcode
-Curl_ssl_connect_nonblocking(struct connectdata *conn, int sockindex,
- bool *done)
-{
-#if defined(USE_SSL) && defined(USE_SSLEAY)
- /* mark this is being ssl enabled from here on. */
- conn->ssl[sockindex].use = TRUE;
- return Curl_ossl_connect_nonblocking(conn, sockindex, done);
-
-#else
- /* not implemented!
- fallback to BLOCKING call. */
- *done = TRUE;
- return Curl_ssl_connect(conn, sockindex);
-#endif
-}
-
-#ifdef USE_SSL
-
-/*
- * Check if there's a session ID for the given connection in the cache, and if
- * there's one suitable, it is provided. Returns TRUE when no entry matched.
- */
-int Curl_ssl_getsessionid(struct connectdata *conn,
- void **ssl_sessionid,
- size_t *idsize) /* set 0 if unknown */
-{
- struct curl_ssl_session *check;
- struct SessionHandle *data = conn->data;
- long i;
-
- if(!conn->ssl_config.sessionid)
- /* session ID re-use is disabled */
- return TRUE;
-
- for(i=0; i< data->set.ssl.numsessions; i++) {
- check = &data->state.session[i];
- if(!check->sessionid)
- /* not session ID means blank entry */
- continue;
- if(curl_strequal(conn->host.name, check->name) &&
- (conn->remote_port == check->remote_port) &&
- Curl_ssl_config_matches(&conn->ssl_config, &check->ssl_config)) {
- /* yes, we have a session ID! */
- data->state.sessionage++; /* increase general age */
- check->age = data->state.sessionage; /* set this as used in this age */
- *ssl_sessionid = check->sessionid;
- if(idsize)
- *idsize = check->idsize;
- return FALSE;
- }
- }
- *ssl_sessionid = NULL;
- return TRUE;
-}
-
-/*
- * Kill a single session ID entry in the cache.
- */
-static int kill_session(struct curl_ssl_session *session)
-{
- if(session->sessionid) {
- /* defensive check */
-
- /* free the ID the SSL-layer specific way */
-#ifdef USE_SSLEAY
- Curl_ossl_session_free(session->sessionid);
-#else
- Curl_gtls_session_free(session->sessionid);
-#endif
- session->sessionid=NULL;
- session->age = 0; /* fresh */
-
- Curl_free_ssl_config(&session->ssl_config);
-
- Curl_safefree(session->name);
- session->name = NULL; /* no name */
-
- return 0; /* ok */
- }
- else
- return 1;
-}
-
-/*
- * Store session id in the session cache. The ID passed on to this function
- * must already have been extracted and allocated the proper way for the SSL
- * layer. Curl_XXXX_session_free() will be called to free/kill the session ID
- * later on.
- */
-CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
- void *ssl_sessionid,
- size_t idsize)
-{
- int i;
- struct SessionHandle *data=conn->data; /* the mother of all structs */
- struct curl_ssl_session *store = &data->state.session[0];
- long oldest_age=data->state.session[0].age; /* zero if unused */
- char *clone_host;
-
- /* Even though session ID re-use might be disabled, that only disables USING
- IT. We still store it here in case the re-using is again enabled for an
- upcoming transfer */
-
- clone_host = strdup(conn->host.name);
- if(!clone_host)
- return CURLE_OUT_OF_MEMORY; /* bail out */
-
- /* Now we should add the session ID and the host name to the cache, (remove
- the oldest if necessary) */
-
- /* find an empty slot for us, or find the oldest */
- for(i=1; (i<data->set.ssl.numsessions) &&
- data->state.session[i].sessionid; i++) {
- if(data->state.session[i].age < oldest_age) {
- oldest_age = data->state.session[i].age;
- store = &data->state.session[i];
- }
- }
- if(i == data->set.ssl.numsessions)
- /* cache is full, we must "kill" the oldest entry! */
- kill_session(store);
- else
- store = &data->state.session[i]; /* use this slot */
-
- /* now init the session struct wisely */
- store->sessionid = ssl_sessionid;
- store->idsize = idsize;
- store->age = data->state.sessionage; /* set current age */
- store->name = clone_host; /* clone host name */
- store->remote_port = conn->remote_port; /* port number */
-
- if (!Curl_clone_ssl_config(&conn->ssl_config, &store->ssl_config))
- return CURLE_OUT_OF_MEMORY;
-
- return CURLE_OK;
-}
-
-
-#endif
-
-void Curl_ssl_close_all(struct SessionHandle *data)
-{
-#ifdef USE_SSL
- int i;
- /* kill the session ID cache */
- if(data->state.session) {
- for(i=0; i< data->set.ssl.numsessions; i++)
- /* the single-killer function handles empty table slots */
- kill_session(&data->state.session[i]);
-
- /* free the cache data */
- free(data->state.session);
- data->state.session = NULL;
- }
-#ifdef USE_SSLEAY
- Curl_ossl_close_all(data);
-#else
-#ifdef USE_GNUTLS
- Curl_gtls_close_all(data);
-#endif /* USE_GNUTLS */
-#endif /* USE_SSLEAY */
-#else /* USE_SSL */
- (void)data;
-#endif /* USE_SSL */
-}
-
-void Curl_ssl_close(struct connectdata *conn)
-{
- if(conn->ssl[FIRSTSOCKET].use) {
-#ifdef USE_SSLEAY
- Curl_ossl_close(conn);
-#else
-#ifdef USE_GNUTLS
- Curl_gtls_close(conn);
-#else
- (void)conn;
-#endif /* USE_GNUTLS */
-#endif /* USE_SSLEAY */
- }
-}
-
-CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex)
-{
- if(conn->ssl[sockindex].use) {
-#ifdef USE_SSLEAY
- if(Curl_ossl_shutdown(conn, sockindex))
- return CURLE_SSL_SHUTDOWN_FAILED;
-#else
-#ifdef USE_GNUTLS
- if(Curl_gtls_shutdown(conn, sockindex))
- return CURLE_SSL_SHUTDOWN_FAILED;
-#else
- (void)conn;
- (void)sockindex;
-#endif /* USE_GNUTLS */
-#endif /* USE_SSLEAY */
- }
- return CURLE_OK;
-}
-
-/* Selects an (Open)SSL crypto engine
- */
-CURLcode Curl_ssl_set_engine(struct SessionHandle *data, const char *engine)
-{
-#ifdef USE_SSLEAY
- return Curl_ossl_set_engine(data, engine);
-#else
-#ifdef USE_GNUTLS
- /* FIX: add code here */
- (void)data;
- (void)engine;
- return CURLE_FAILED_INIT;
-#else
- /* no SSL layer */
- (void)data;
- (void)engine;
- return CURLE_FAILED_INIT;
-#endif /* USE_GNUTLS */
-#endif /* USE_SSLEAY */
-}
-
-/* Selects an (Open?)SSL crypto engine
- */
-CURLcode Curl_ssl_set_engine_default(struct SessionHandle *data)
-{
-#ifdef USE_SSLEAY
- return Curl_ossl_set_engine_default(data);
-#else
-#ifdef USE_GNUTLS
- /* FIX: add code here */
- (void)data;
- return CURLE_FAILED_INIT;
-#else
- /* No SSL layer */
- (void)data;
- return CURLE_FAILED_INIT;
-#endif /* USE_GNUTLS */
-#endif /* USE_SSLEAY */
-}
-
-/* Return list of OpenSSL crypto engine names. */
-struct curl_slist *Curl_ssl_engines_list(struct SessionHandle *data)
-{
-#ifdef USE_SSLEAY
- return Curl_ossl_engines_list(data);
-#else
-#ifdef USE_GNUTLS
- /* FIX: add code here? */
- (void)data;
- return NULL;
-#else
- (void)data;
- return NULL;
-#endif /* USE_GNUTLS */
-#endif /* USE_SSLEAY */
-}
-
-/* return number of sent (non-SSL) bytes */
-ssize_t Curl_ssl_send(struct connectdata *conn,
- int sockindex,
- void *mem,
- size_t len)
-{
-#ifdef USE_SSLEAY
- return Curl_ossl_send(conn, sockindex, mem, len);
-#else
-#ifdef USE_GNUTLS
- return Curl_gtls_send(conn, sockindex, mem, len);
-#else
- (void)conn;
- (void)sockindex;
- (void)mem;
- (void)len;
- return 0;
-#endif /* USE_GNUTLS */
-#endif /* USE_SSLEAY */
-}
-
-/* return number of received (decrypted) bytes */
-
-/*
- * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
- * a regular CURLcode value.
- */
-ssize_t Curl_ssl_recv(struct connectdata *conn, /* connection data */
- int sockindex, /* socketindex */
- char *mem, /* store read data here */
- size_t len) /* max amount to read */
-{
-#ifdef USE_SSL
- ssize_t nread;
- bool block = FALSE;
-
-#ifdef USE_SSLEAY
- nread = Curl_ossl_recv(conn, sockindex, mem, len, &block);
-#else
-#ifdef USE_GNUTLS
- nread = Curl_gtls_recv(conn, sockindex, mem, len, &block);
-#endif /* USE_GNUTLS */
-#endif /* USE_SSLEAY */
- if(nread == -1) {
- if(!block)
- return 0; /* this is a true error, not EWOULDBLOCK */
- else
- return -1;
- }
-
- return (int)nread;
-
-#else /* USE_SSL */
- (void)conn;
- (void)sockindex;
- (void)mem;
- (void)len;
- return 0;
-#endif /* USE_SSL */
-}
-
-
-/*
- * This sets up a session ID cache to the specified size. Make sure this code
- * is agnostic to what underlying SSL technology we use.
- */
-CURLcode Curl_ssl_initsessions(struct SessionHandle *data, long amount)
-{
-#ifdef USE_SSL
- struct curl_ssl_session *session;
-
- if(data->state.session)
- /* this is just a precaution to prevent multiple inits */
- return CURLE_OK;
-
- session = (struct curl_ssl_session *)
- calloc(sizeof(struct curl_ssl_session), amount);
- if(!session)
- return CURLE_OUT_OF_MEMORY;
-
- /* store the info in the SSL section */
- data->set.ssl.numsessions = amount;
- data->state.session = session;
- data->state.sessionage = 1; /* this is brand new */
-#else
- /* without SSL, do nothing */
- (void)data;
- (void)amount;
-#endif
-
- return CURLE_OK;
-}
-
-size_t Curl_ssl_version(char *buffer, size_t size)
-{
-#ifdef USE_SSLEAY
- return Curl_ossl_version(buffer, size);
-#else
-#ifdef USE_GNUTLS
- return Curl_gtls_version(buffer, size);
-#else
- (void)buffer;
- (void)size;
- return 0; /* no SSL support */
-#endif /* USE_GNUTLS */
-#endif /* USE_SSLEAY */
-}
-
-
-/*
- * This function tries to determine connection status.
- *
- * Return codes:
- * 1 means the connection is still in place
- * 0 means the connection has been closed
- * -1 means the connection status is unknown
- */
-int Curl_ssl_check_cxn(struct connectdata *conn)
-{
-#ifdef USE_SSLEAY
- return Curl_ossl_check_cxn(conn);
-#else
- (void)conn;
- /* TODO: we lack implementation of this for GnuTLS */
- return -1; /* connection status unknown */
-#endif /* USE_SSLEAY */
-}
-
-bool Curl_ssl_data_pending(struct connectdata *conn,
- int connindex)
-{
-#ifdef USE_SSLEAY
- /* OpenSSL-specific */
- if(conn->ssl[connindex].handle)
- /* SSL is in use */
- return SSL_pending(conn->ssl[connindex].handle);
-#else
- (void)conn;
- (void)connindex;
-#endif
- return FALSE; /* nothing pending */
-
-}
diff --git a/Utilities/cmcurl/sslgen.h b/Utilities/cmcurl/sslgen.h
deleted file mode 100644
index c24d46bf3..000000000
--- a/Utilities/cmcurl/sslgen.h
+++ /dev/null
@@ -1,84 +0,0 @@
-#ifndef __SSLGEN_H
-#define __SSLGEN_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-bool Curl_ssl_config_matches(struct ssl_config_data* data,
- struct ssl_config_data* needle);
-bool Curl_clone_ssl_config(struct ssl_config_data* source,
- struct ssl_config_data* dest);
-void Curl_free_ssl_config(struct ssl_config_data* sslc);
-
-int Curl_ssl_init(void);
-void Curl_ssl_cleanup(void);
-CURLcode Curl_ssl_connect(struct connectdata *conn, int sockindex);
-CURLcode Curl_ssl_connect_nonblocking(struct connectdata *conn,
- int sockindex,
- bool *done);
-void Curl_ssl_close(struct connectdata *conn);
-/* tell the SSL stuff to close down all open information regarding
- connections (and thus session ID caching etc) */
-void Curl_ssl_close_all(struct SessionHandle *data);
-CURLcode Curl_ssl_set_engine(struct SessionHandle *data, const char *engine);
-/* Sets engine as default for all SSL operations */
-CURLcode Curl_ssl_set_engine_default(struct SessionHandle *data);
-ssize_t Curl_ssl_send(struct connectdata *conn,
- int sockindex,
- void *mem,
- size_t len);
-ssize_t Curl_ssl_recv(struct connectdata *conn, /* connection data */
- int sockindex, /* socketindex */
- char *mem, /* store read data here */
- size_t len); /* max amount to read */
-
-/* init the SSL session ID cache */
-CURLcode Curl_ssl_initsessions(struct SessionHandle *, long);
-/* extract a session ID */
-int Curl_ssl_getsessionid(struct connectdata *conn,
- void **ssl_sessionid,
- size_t *idsize) /* set 0 if unknown */;
-/* add a new session ID */
-CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
- void *ssl_sessionid,
- size_t idsize);
-
-
-struct curl_slist *Curl_ssl_engines_list(struct SessionHandle *data);
-
-size_t Curl_ssl_version(char *buffer, size_t size);
-
-int Curl_ssl_check_cxn(struct connectdata *conn);
-
-CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex);
-
-bool Curl_ssl_data_pending(struct connectdata *conn,
- int connindex);
-
-#if !defined(USE_SSL) && !defined(SSLGEN_C)
-/* set up blank macros for none-SSL builds */
-#define Curl_ssl_close_all(x)
-#endif
-
-#define SSL_SHUTDOWN_TIMEOUT 10000 /* ms */
-
-#endif
diff --git a/Utilities/cmcurl/ssluse.c b/Utilities/cmcurl/ssluse.c
deleted file mode 100644
index 6709278fa..000000000
--- a/Utilities/cmcurl/ssluse.c
+++ /dev/null
@@ -1,1950 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-/*
- * Source file for all OpenSSL-specific code for the TLS/SSL layer. No code
- * but sslgen.c should ever call or use these functions.
- */
-
-/*
- * The original SSLeay-using code for curl was written by Linas Vepstas and
- * Sampo Kellomaki 1998.
- */
-
-#include "setup.h"
-
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-
-#include "urldata.h"
-#include "sendf.h"
-#include "formdata.h" /* for the boundary function */
-#include "url.h" /* for the ssl config check function */
-#include "inet_pton.h"
-#include "ssluse.h"
-#include "connect.h" /* Curl_sockerrno() proto */
-#include "strequal.h"
-#include "select.h"
-#include "sslgen.h"
-
-#define _MPRINTF_REPLACE /* use the internal *printf() functions */
-#include <curl/mprintf.h>
-
-#ifdef USE_SSLEAY
-
-#ifdef USE_OPENSSL
-#include <openssl/rand.h>
-#include <openssl/x509v3.h>
-#else
-#include <rand.h>
-#include <x509v3.h>
-#endif
-
-#include "memory.h"
-#include "easyif.h" /* for Curl_convert_from_utf8 prototype */
-
-/* The last #include file should be: */
-#include "memdebug.h"
-
-#ifndef min
-#define min(a, b) ((a) < (b) ? (a) : (b))
-#endif
-
-#if OPENSSL_VERSION_NUMBER >= 0x0090581fL
-#define HAVE_SSL_GET1_SESSION 1
-#else
-#undef HAVE_SSL_GET1_SESSION
-#endif
-
-#if OPENSSL_VERSION_NUMBER >= 0x00904100L
-#define HAVE_USERDATA_IN_PWD_CALLBACK 1
-#else
-#undef HAVE_USERDATA_IN_PWD_CALLBACK
-#endif
-
-#if OPENSSL_VERSION_NUMBER >= 0x00907001L
-/* ENGINE_load_private_key() takes four arguments */
-#define HAVE_ENGINE_LOAD_FOUR_ARGS
-#else
-/* ENGINE_load_private_key() takes three arguments */
-#undef HAVE_ENGINE_LOAD_FOUR_ARGS
-#endif
-
-#if (OPENSSL_VERSION_NUMBER >= 0x00903001L) && defined(HAVE_OPENSSL_PKCS12_H)
-/* OpenSSL has PKCS 12 support */
-#define HAVE_PKCS12_SUPPORT
-#else
-/* OpenSSL/SSLEay does not have PKCS12 support */
-#undef HAVE_PKCS12_SUPPORT
-#endif
-
-#if OPENSSL_VERSION_NUMBER >= 0x00906001L
-#define HAVE_ERR_ERROR_STRING_N 1
-#endif
-
-#if OPENSSL_VERSION_NUMBER >= 0x00909000L
-#define SSL_METHOD_QUAL const
-#else
-#define SSL_METHOD_QUAL
-#endif
-
-/*
- * Number of bytes to read from the random number seed file. This must be
- * a finite value (because some entropy "files" like /dev/urandom have
- * an infinite length), but must be large enough to provide enough
- * entopy to properly seed OpenSSL's PRNG.
- */
-#define RAND_LOAD_LENGTH 1024
-
-#ifndef HAVE_USERDATA_IN_PWD_CALLBACK
-static char global_passwd[64];
-#endif
-
-static int passwd_callback(char *buf, int num, int verify
-#if HAVE_USERDATA_IN_PWD_CALLBACK
- /* This was introduced in 0.9.4, we can set this
- using SSL_CTX_set_default_passwd_cb_userdata()
- */
- , void *global_passwd
-#endif
- )
-{
- if(verify)
- fprintf(stderr, "%s\n", buf);
- else {
- if(num > (int)strlen((char *)global_passwd)) {
- strcpy(buf, global_passwd);
- return (int)strlen(buf);
- }
- }
- return 0;
-}
-
-/*
- * rand_enough() is a function that returns TRUE if we have seeded the random
- * engine properly. We use some preprocessor magic to provide a seed_enough()
- * macro to use, just to prevent a compiler warning on this function if we
- * pass in an argument that is never used.
- */
-
-#ifdef HAVE_RAND_STATUS
-#define seed_enough(x) rand_enough()
-static bool rand_enough(void)
-{
- return (bool)(0 != RAND_status());
-}
-#else
-#define seed_enough(x) rand_enough(x)
-static bool rand_enough(int nread)
-{
- /* this is a very silly decision to make */
- return (bool)(nread > 500);
-}
-#endif
-
-static int ossl_seed(struct SessionHandle *data)
-{
- char *buf = data->state.buffer; /* point to the big buffer */
- int nread=0;
-
- /* Q: should we add support for a random file name as a libcurl option?
- A: Yes, it is here */
-
-#ifndef RANDOM_FILE
- /* if RANDOM_FILE isn't defined, we only perform this if an option tells
- us to! */
- if(data->set.ssl.random_file)
-#define RANDOM_FILE "" /* doesn't matter won't be used */
-#endif
- {
- /* let the option override the define */
- nread += RAND_load_file((data->set.ssl.random_file?
- data->set.ssl.random_file:RANDOM_FILE),
- RAND_LOAD_LENGTH);
- if(seed_enough(nread))
- return nread;
- }
-
-#if defined(HAVE_RAND_EGD)
- /* only available in OpenSSL 0.9.5 and later */
- /* EGD_SOCKET is set at configure time or not at all */
-#ifndef EGD_SOCKET
- /* If we don't have the define set, we only do this if the egd-option
- is set */
- if(data->set.ssl.egdsocket)
-#define EGD_SOCKET "" /* doesn't matter won't be used */
-#endif
- {
- /* If there's an option and a define, the option overrides the
- define */
- int ret = RAND_egd(data->set.ssl.egdsocket?
- data->set.ssl.egdsocket:EGD_SOCKET);
- if(-1 != ret) {
- nread += ret;
- if(seed_enough(nread))
- return nread;
- }
- }
-#endif
-
- /* If we get here, it means we need to seed the PRNG using a "silly"
- approach! */
-#ifdef HAVE_RAND_SCREEN
- /* This one gets a random value by reading the currently shown screen */
- RAND_screen();
- nread = 100; /* just a value */
-#else
- {
- int len;
- char *area;
-
- /* Changed call to RAND_seed to use the underlying RAND_add implementation
- * directly. Do this in a loop, with the amount of additional entropy
- * being dependent upon the algorithm used by Curl_FormBoundary(): N bytes
- * of a 7-bit ascii set. -- Richard Gorton, March 11 2003.
- */
-
- do {
- area = Curl_FormBoundary();
- if(!area)
- return 3; /* out of memory */
-
- len = (int)strlen(area);
- RAND_add(area, len, (len >> 1));
-
- free(area); /* now remove the random junk */
- } while (!RAND_status());
- }
-#endif
-
- /* generates a default path for the random seed file */
- buf[0]=0; /* blank it first */
- RAND_file_name(buf, BUFSIZE);
- if(buf[0]) {
- /* we got a file name to try */
- nread += RAND_load_file(buf, RAND_LOAD_LENGTH);
- if(seed_enough(nread))
- return nread;
- }
-
- infof(data, "libcurl is now using a weak random seed!\n");
- return nread;
-}
-
-int Curl_ossl_seed(struct SessionHandle *data)
-{
- /* we have the "SSL is seeded" boolean static to prevent multiple
- time-consuming seedings in vain */
- static bool ssl_seeded = FALSE;
-
- if(!ssl_seeded || data->set.ssl.random_file || data->set.ssl.egdsocket) {
- ossl_seed(data);
- ssl_seeded = TRUE;
- }
- return 0;
-}
-
-
-#ifndef SSL_FILETYPE_ENGINE
-#define SSL_FILETYPE_ENGINE 42
-#endif
-#ifndef SSL_FILETYPE_PKCS12
-#define SSL_FILETYPE_PKCS12 43
-#endif
-static int do_file_type(const char *type)
-{
- if(!type || !type[0])
- return SSL_FILETYPE_PEM;
- if(curl_strequal(type, "PEM"))
- return SSL_FILETYPE_PEM;
- if(curl_strequal(type, "DER"))
- return SSL_FILETYPE_ASN1;
- if(curl_strequal(type, "ENG"))
- return SSL_FILETYPE_ENGINE;
- if(curl_strequal(type, "P12"))
- return SSL_FILETYPE_PKCS12;
- return -1;
-}
-
-static
-int cert_stuff(struct connectdata *conn,
- SSL_CTX* ctx,
- char *cert_file,
- const char *cert_type,
- char *key_file,
- const char *key_type)
-{
- struct SessionHandle *data = conn->data;
- int file_type;
-
- if(cert_file != NULL) {
- SSL *ssl;
- X509 *x509;
- int cert_done = 0;
-
- if(data->set.key_passwd) {
-#ifndef HAVE_USERDATA_IN_PWD_CALLBACK
- /*
- * If password has been given, we store that in the global
- * area (*shudder*) for a while:
- */
- size_t len = strlen(data->set.key_passwd);
- if(len < sizeof(global_passwd))
- memcpy(global_passwd, data->set.key_passwd, len+1);
-#else
- /*
- * We set the password in the callback userdata
- */
- SSL_CTX_set_default_passwd_cb_userdata(ctx,
- data->set.key_passwd);
-#endif
- /* Set passwd callback: */
- SSL_CTX_set_default_passwd_cb(ctx, passwd_callback);
- }
-
- file_type = do_file_type(cert_type);
-
-#define SSL_CLIENT_CERT_ERR \
- "unable to use client certificate (no key found or wrong pass phrase?)"
-
- switch(file_type) {
- case SSL_FILETYPE_PEM:
- /* SSL_CTX_use_certificate_chain_file() only works on PEM files */
- if(SSL_CTX_use_certificate_chain_file(ctx,
- cert_file) != 1) {
- failf(data, SSL_CLIENT_CERT_ERR);
- return 0;
- }
- break;
-
- case SSL_FILETYPE_ASN1:
- /* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but
- we use the case above for PEM so this can only be performed with
- ASN1 files. */
- if(SSL_CTX_use_certificate_file(ctx,
- cert_file,
- file_type) != 1) {
- failf(data, SSL_CLIENT_CERT_ERR);
- return 0;
- }
- break;
- case SSL_FILETYPE_ENGINE:
- failf(data, "file type ENG for certificate not implemented");
- return 0;
-
- case SSL_FILETYPE_PKCS12:
- {
-#ifdef HAVE_PKCS12_SUPPORT
- FILE *f;
- PKCS12 *p12;
- EVP_PKEY *pri;
-
- f = fopen(cert_file,"rb");
- if (!f) {
- failf(data, "could not open PKCS12 file '%s'", cert_file);
- return 0;
- }
- p12 = d2i_PKCS12_fp(f, NULL);
- fclose(f);
-
- PKCS12_PBE_add();
-
- if (!PKCS12_parse(p12, data->set.key_passwd, &pri, &x509, NULL)) {
- failf(data,
- "could not parse PKCS12 file, check password, OpenSSL error %s",
- ERR_error_string(ERR_get_error(), NULL) );
- return 0;
- }
-
- PKCS12_free(p12);
-
- if(SSL_CTX_use_certificate(ctx, x509) != 1) {
- failf(data, SSL_CLIENT_CERT_ERR);
- EVP_PKEY_free(pri);
- X509_free(x509);
- return 0;
- }
-
- if(SSL_CTX_use_PrivateKey(ctx, pri) != 1) {
- failf(data, "unable to use private key from PKCS12 file '%s'",
- cert_file);
- EVP_PKEY_free(pri);
- X509_free(x509);
- return 0;
- }
-
- EVP_PKEY_free(pri);
- X509_free(x509);
- cert_done = 1;
- break;
-#else
- failf(data, "file type P12 for certificate not supported");
- return 0;
-#endif
- }
- default:
- failf(data, "not supported file type '%s' for certificate", cert_type);
- return 0;
- }
-
- file_type = do_file_type(key_type);
-
- switch(file_type) {
- case SSL_FILETYPE_PEM:
- if(cert_done)
- break;
- if(key_file == NULL)
- /* cert & key can only be in PEM case in the same file */
- key_file=cert_file;
- case SSL_FILETYPE_ASN1:
- if(SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type) != 1) {
- failf(data, "unable to set private key file: '%s' type %s\n",
- key_file, key_type?key_type:"PEM");
- return 0;
- }
- break;
- case SSL_FILETYPE_ENGINE:
-#ifdef HAVE_OPENSSL_ENGINE_H
- { /* XXXX still needs some work */
- EVP_PKEY *priv_key = NULL;
- if(conn && conn->data && conn->data->state.engine) {
-#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
- UI_METHOD *ui_method = UI_OpenSSL();
-#endif
- if(!key_file || !key_file[0]) {
- failf(data, "no key set to load from crypto engine\n");
- return 0;
- }
- /* the typecast below was added to please MinGW32 */
- priv_key = (EVP_PKEY *)
- ENGINE_load_private_key(conn->data->state.engine,key_file,
-#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
- ui_method,
-#endif
- data->set.key_passwd);
- if(!priv_key) {
- failf(data, "failed to load private key from crypto engine\n");
- return 0;
- }
- if(SSL_CTX_use_PrivateKey(ctx, priv_key) != 1) {
- failf(data, "unable to set private key\n");
- EVP_PKEY_free(priv_key);
- return 0;
- }
- EVP_PKEY_free(priv_key); /* we don't need the handle any more... */
- }
- else {
- failf(data, "crypto engine not set, can't load private key\n");
- return 0;
- }
- }
- break;
-#else
- failf(data, "file type ENG for private key not supported\n");
- return 0;
-#endif
- case SSL_FILETYPE_PKCS12:
- if(!cert_done) {
- failf(data, "file type P12 for private key not supported\n");
- return 0;
- }
- break;
- default:
- failf(data, "not supported file type for private key\n");
- return 0;
- }
-
- ssl=SSL_new(ctx);
- if (NULL == ssl) {
- failf(data,"unable to create an SSL structure\n");
- return 0;
- }
-
- x509=SSL_get_certificate(ssl);
-
- /* This version was provided by Evan Jordan and is supposed to not
- leak memory as the previous version: */
- if(x509 != NULL) {
- EVP_PKEY *pktmp = X509_get_pubkey(x509);
- EVP_PKEY_copy_parameters(pktmp,SSL_get_privatekey(ssl));
- EVP_PKEY_free(pktmp);
- }
-
- SSL_free(ssl);
-
- /* If we are using DSA, we can copy the parameters from
- * the private key */
-
-
- /* Now we know that a key and cert have been set against
- * the SSL context */
- if(!SSL_CTX_check_private_key(ctx)) {
- failf(data, "Private key does not match the certificate public key");
- return(0);
- }
-#ifndef HAVE_USERDATA_IN_PWD_CALLBACK
- /* erase it now */
- memset(global_passwd, 0, sizeof(global_passwd));
-#endif
- }
- return(1);
-}
-
-static
-int cert_verify_callback(int ok, X509_STORE_CTX *ctx)
-{
- X509 *err_cert;
- char buf[256];
-
- err_cert=X509_STORE_CTX_get_current_cert(ctx);
- X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf));
- return ok;
-}
-
-/* Return error string for last OpenSSL error
- */
-static char *SSL_strerror(unsigned long error, char *buf, size_t size)
-{
-#ifdef HAVE_ERR_ERROR_STRING_N
- /* OpenSSL 0.9.6 and later has a function named
- ERRO_error_string_n() that takes the size of the buffer as a
- third argument */
- ERR_error_string_n(error, buf, size);
-#else
- (void) size;
- ERR_error_string(error, buf);
-#endif
- return (buf);
-}
-
-#endif /* USE_SSLEAY */
-
-#ifdef USE_SSLEAY
-/**
- * Global SSL init
- *
- * @retval 0 error initializing SSL
- * @retval 1 SSL initialized successfully
- */
-int Curl_ossl_init(void)
-{
-#ifdef HAVE_ENGINE_LOAD_BUILTIN_ENGINES
- ENGINE_load_builtin_engines();
-#endif
-
- /* Lets get nice error messages */
- SSL_load_error_strings();
-
- /* Setup all the global SSL stuff */
- if (!SSLeay_add_ssl_algorithms())
- return 0;
-
- return 1;
-}
-
-#endif /* USE_SSLEAY */
-
-#ifdef USE_SSLEAY
-
-/* Global cleanup */
-void Curl_ossl_cleanup(void)
-{
- /* Free the SSL error strings */
- ERR_free_strings();
-
- /* EVP_cleanup() removes all ciphers and digests from the
- table. */
- EVP_cleanup();
-
-#ifdef HAVE_ENGINE_cleanup
- ENGINE_cleanup();
-#endif
-
-#ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
- /* this function was not present in 0.9.6b, but was added sometimes
- later */
- CRYPTO_cleanup_all_ex_data();
-#endif
-}
-
-/*
- * This function uses SSL_peek to determine connection status.
- *
- * Return codes:
- * 1 means the connection is still in place
- * 0 means the connection has been closed
- * -1 means the connection status is unknown
- */
-int Curl_ossl_check_cxn(struct connectdata *conn)
-{
- int rc;
- char buf;
-
- rc = SSL_peek(conn->ssl[FIRSTSOCKET].handle, (void*)&buf, 1);
- if (rc > 0)
- return 1; /* connection still in place */
-
- if (rc == 0)
- return 0; /* connection has been closed */
-
- return -1; /* connection status unknown */
-}
-
-#endif /* USE_SSLEAY */
-
-/* Selects an OpenSSL crypto engine
- */
-CURLcode Curl_ossl_set_engine(struct SessionHandle *data, const char *engine)
-{
-#if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H)
- ENGINE *e = ENGINE_by_id(engine);
-
- if (!e) {
- failf(data, "SSL Engine '%s' not found", engine);
- return (CURLE_SSL_ENGINE_NOTFOUND);
- }
-
- if (data->state.engine) {
- ENGINE_finish(data->state.engine);
- ENGINE_free(data->state.engine);
- data->state.engine = NULL;
- }
- if (!ENGINE_init(e)) {
- char buf[256];
-
- ENGINE_free(e);
- failf(data, "Failed to initialise SSL Engine '%s':\n%s",
- engine, SSL_strerror(ERR_get_error(), buf, sizeof(buf)));
- return (CURLE_SSL_ENGINE_INITFAILED);
- }
- data->state.engine = e;
- return (CURLE_OK);
-#else
- (void)engine;
- failf(data, "SSL Engine not supported");
- return (CURLE_SSL_ENGINE_NOTFOUND);
-#endif
-}
-
-#ifdef USE_SSLEAY
-/* Sets engine as default for all SSL operations
- */
-CURLcode Curl_ossl_set_engine_default(struct SessionHandle *data)
-{
-#ifdef HAVE_OPENSSL_ENGINE_H
- if (data->state.engine) {
- if (ENGINE_set_default(data->state.engine, ENGINE_METHOD_ALL) > 0) {
- infof(data,"set default crypto engine '%s'\n", ENGINE_get_id(data->state.engine));
- }
- else {
- failf(data, "set default crypto engine '%s' failed", ENGINE_get_id(data->state.engine));
- return CURLE_SSL_ENGINE_SETFAILED;
- }
- }
-#else
- (void) data;
-#endif
- return CURLE_OK;
-}
-#endif /* USE_SSLEAY */
-
-/* Return list of OpenSSL crypto engine names.
- */
-struct curl_slist *Curl_ossl_engines_list(struct SessionHandle *data)
-{
- struct curl_slist *list = NULL;
-#if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H)
- ENGINE *e;
-
- for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
- list = curl_slist_append(list, ENGINE_get_id(e));
-#endif
- (void) data;
- return (list);
-}
-
-
-#ifdef USE_SSLEAY
-
-/*
- * This function is called when an SSL connection is closed.
- */
-void Curl_ossl_close(struct connectdata *conn)
-{
- int i;
- /*
- ERR_remove_state() frees the error queue associated with
- thread pid. If pid == 0, the current thread will have its
- error queue removed.
-
- Since error queue data structures are allocated
- automatically for new threads, they must be freed when
- threads are terminated in oder to avoid memory leaks.
- */
- ERR_remove_state(0);
-
- for(i=0; i<2; i++) {
- struct ssl_connect_data *connssl = &conn->ssl[i];
-
- if(connssl->handle) {
- (void)SSL_shutdown(connssl->handle);
- SSL_set_connect_state(connssl->handle);
-
- SSL_free (connssl->handle);
- connssl->handle = NULL;
- }
- if(connssl->ctx) {
- SSL_CTX_free (connssl->ctx);
- connssl->ctx = NULL;
- }
- connssl->use = FALSE; /* get back to ordinary socket usage */
- }
-}
-
-/*
- * This function is called to shut down the SSL layer but keep the
- * socket open (CCC - Clear Command Channel)
- */
-int Curl_ossl_shutdown(struct connectdata *conn, int sockindex)
-{
- int retval = 0;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- struct SessionHandle *data = conn->data;
- char buf[120]; /* We will use this for the OpenSSL error buffer, so it has
- to be at least 120 bytes long. */
- unsigned long sslerror;
- ssize_t nread;
- int err;
- int done = 0;
-
- /* This has only been tested on the proftpd server, and the mod_tls code
- sends a close notify alert without waiting for a close notify alert in
- response. Thus we wait for a close notify alert from the server, but
- we do not send one. Let's hope other servers do the same... */
-
- if(connssl->handle) {
- while(!done) {
- int what = Curl_select(conn->sock[sockindex],
- CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
- if(what > 0) {
- /* Something to read, let's do it and hope that it is the close
- notify alert from the server */
- nread = (ssize_t)SSL_read(conn->ssl[sockindex].handle, buf,
- sizeof(buf));
- err = SSL_get_error(conn->ssl[sockindex].handle, (int)nread);
-
- switch(err) {
- case SSL_ERROR_NONE: /* this is not an error */
- case SSL_ERROR_ZERO_RETURN: /* no more data */
- /* This is the expected response. There was no data but only
- the close notify alert */
- done = 1;
- break;
- case SSL_ERROR_WANT_READ:
- /* there's data pending, re-invoke SSL_read() */
- infof(data, "SSL_ERROR_WANT_READ\n");
- break;
- case SSL_ERROR_WANT_WRITE:
- /* SSL wants a write. Really odd. Let's bail out. */
- infof(data, "SSL_ERROR_WANT_WRITE\n");
- done = 1;
- break;
- default:
- /* openssl/ssl.h says "look at error stack/return value/errno" */
- sslerror = ERR_get_error();
- failf(conn->data, "SSL read: %s, errno %d",
- ERR_error_string(sslerror, buf),
- Curl_sockerrno() );
- done = 1;
- break;
- }
- }
- else if(0 == what) {
- /* timeout */
- failf(data, "SSL shutdown timeout");
- done = 1;
- break;
- }
- else {
- /* anything that gets here is fatally bad */
- failf(data, "select on SSL socket, errno: %d", Curl_sockerrno());
- retval = -1;
- done = 1;
- }
- } /* while()-loop for the select() */
-
- if(data->set.verbose) {
- switch(SSL_get_shutdown(connssl->handle)) {
- case SSL_SENT_SHUTDOWN:
- infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN\n");
- break;
- case SSL_RECEIVED_SHUTDOWN:
- infof(data, "SSL_get_shutdown() returned SSL_RECEIVED_SHUTDOWN\n");
- break;
- case SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN:
- infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN|"
- "SSL_RECEIVED__SHUTDOWN\n");
- break;
- }
- }
-
- connssl->use = FALSE; /* get back to ordinary socket usage */
-
- SSL_free (connssl->handle);
- connssl->handle = NULL;
- }
- return retval;
-}
-
-void Curl_ossl_session_free(void *ptr)
-{
- /* free the ID */
- SSL_SESSION_free(ptr);
-}
-
-/*
- * This function is called when the 'data' struct is going away. Close
- * down everything and free all resources!
- */
-int Curl_ossl_close_all(struct SessionHandle *data)
-{
-#ifdef HAVE_OPENSSL_ENGINE_H
- if(data->state.engine) {
- ENGINE_finish(data->state.engine);
- ENGINE_free(data->state.engine);
- data->state.engine = NULL;
- }
-#else
- (void)data;
-#endif
- return 0;
-}
-
-static int Curl_ASN1_UTCTIME_output(struct connectdata *conn,
- const char *prefix,
- ASN1_UTCTIME *tm)
-{
- char *asn1_string;
- int gmt=FALSE;
- int i;
- int year=0,month=0,day=0,hour=0,minute=0,second=0;
- struct SessionHandle *data = conn->data;
-
- if(!data->set.verbose)
- return 0;
-
- i=tm->length;
- asn1_string=(char *)tm->data;
-
- if(i < 10)
- return 1;
- if(asn1_string[i-1] == 'Z')
- gmt=TRUE;
- for (i=0; i<10; i++)
- if((asn1_string[i] > '9') || (asn1_string[i] < '0'))
- return 2;
-
- year= (asn1_string[0]-'0')*10+(asn1_string[1]-'0');
- if(year < 50)
- year+=100;
-
- month= (asn1_string[2]-'0')*10+(asn1_string[3]-'0');
- if((month > 12) || (month < 1))
- return 3;
-
- day= (asn1_string[4]-'0')*10+(asn1_string[5]-'0');
- hour= (asn1_string[6]-'0')*10+(asn1_string[7]-'0');
- minute= (asn1_string[8]-'0')*10+(asn1_string[9]-'0');
-
- if((asn1_string[10] >= '0') && (asn1_string[10] <= '9') &&
- (asn1_string[11] >= '0') && (asn1_string[11] <= '9'))
- second= (asn1_string[10]-'0')*10+(asn1_string[11]-'0');
-
- infof(data,
- "%s%04d-%02d-%02d %02d:%02d:%02d %s\n",
- prefix, year+1900, month, day, hour, minute, second, (gmt?"GMT":""));
-
- return 0;
-}
-
-#endif
-
-/* ====================================================== */
-#ifdef USE_SSLEAY
-
-/*
- * Match a hostname against a wildcard pattern.
- * E.g.
- * "foo.host.com" matches "*.host.com".
- *
- * We are a bit more liberal than RFC2818 describes in that we
- * accept multiple "*" in pattern (similar to what some other browsers do).
- * E.g.
- * "abc.def.domain.com" should strickly not match "*.domain.com", but we
- * don't consider "." to be important in CERT checking.
- */
-#define HOST_NOMATCH 0
-#define HOST_MATCH 1
-
-static int hostmatch(const char *hostname, const char *pattern)
-{
- while (1) {
- int c = *pattern++;
-
- if (c == '\0')
- return (*hostname ? HOST_NOMATCH : HOST_MATCH);
-
- if (c == '*') {
- c = *pattern;
- if (c == '\0') /* "*\0" matches anything remaining */
- return HOST_MATCH;
-
- while (*hostname) {
- /* The only recursive function in libcurl! */
- if (hostmatch(hostname++,pattern) == HOST_MATCH)
- return HOST_MATCH;
- }
- break;
- }
-
- if (toupper(c) != toupper(*hostname++))
- break;
- }
- return HOST_NOMATCH;
-}
-
-static int
-cert_hostcheck(const char *match_pattern, const char *hostname)
-{
- if (!match_pattern || !*match_pattern ||
- !hostname || !*hostname) /* sanity check */
- return 0;
-
- if(curl_strequal(hostname,match_pattern)) /* trivial case */
- return 1;
-
- if (hostmatch(hostname,match_pattern) == HOST_MATCH)
- return 1;
- return 0;
-}
-
-/* Quote from RFC2818 section 3.1 "Server Identity"
-
- If a subjectAltName extension of type dNSName is present, that MUST
- be used as the identity. Otherwise, the (most specific) Common Name
- field in the Subject field of the certificate MUST be used. Although
- the use of the Common Name is existing practice, it is deprecated and
- Certification Authorities are encouraged to use the dNSName instead.
-
- Matching is performed using the matching rules specified by
- [RFC2459]. If more than one identity of a given type is present in
- the certificate (e.g., more than one dNSName name, a match in any one
- of the set is considered acceptable.) Names may contain the wildcard
- character * which is considered to match any single domain name
- component or component fragment. E.g., *.a.com matches foo.a.com but
- not bar.foo.a.com. f*.com matches foo.com but not bar.com.
-
- In some cases, the URI is specified as an IP address rather than a
- hostname. In this case, the iPAddress subjectAltName must be present
- in the certificate and must exactly match the IP in the URI.
-
-*/
-static CURLcode verifyhost(struct connectdata *conn,
- X509 *server_cert)
-{
- bool matched = FALSE; /* no alternative match yet */
- int target = GEN_DNS; /* target type, GEN_DNS or GEN_IPADD */
- int addrlen = 0;
- struct SessionHandle *data = conn->data;
- STACK_OF(GENERAL_NAME) *altnames;
-#ifdef ENABLE_IPV6
- struct in6_addr addr;
-#else
- struct in_addr addr;
-#endif
- CURLcode res = CURLE_OK;
-
-#ifdef ENABLE_IPV6
- if(conn->bits.ipv6_ip &&
- Curl_inet_pton(AF_INET6, conn->host.name, &addr)) {
- target = GEN_IPADD;
- addrlen = sizeof(struct in6_addr);
- }
- else
-#endif
- if(Curl_inet_pton(AF_INET, conn->host.name, &addr)) {
- target = GEN_IPADD;
- addrlen = sizeof(struct in_addr);
- }
-
- /* get a "list" of alternative names */
- altnames = X509_get_ext_d2i(server_cert, NID_subject_alt_name, NULL, NULL);
-
- if(altnames) {
- int numalts;
- int i;
-
- /* get amount of alternatives, RFC2459 claims there MUST be at least
- one, but we don't depend on it... */
- numalts = sk_GENERAL_NAME_num(altnames);
-
- /* loop through all alternatives while none has matched */
- for (i=0; (i<numalts) && !matched; i++) {
- /* get a handle to alternative name number i */
- const GENERAL_NAME *check = sk_GENERAL_NAME_value(altnames, i);
-
- /* only check alternatives of the same type the target is */
- if(check->type == target) {
- /* get data and length */
- const char *altptr = (char *)ASN1_STRING_data(check->d.ia5);
- int altlen;
-
- switch(target) {
- case GEN_DNS: /* name/pattern comparison */
- /* The OpenSSL man page explicitly says: "In general it cannot be
- assumed that the data returned by ASN1_STRING_data() is null
- terminated or does not contain embedded nulls." But also that
- "The actual format of the data will depend on the actual string
- type itself: for example for and IA5String the data will be ASCII"
-
- Gisle researched the OpenSSL sources:
- "I checked the 0.9.6 and 0.9.8 sources before my patch and
- it always 0-terminates an IA5String."
- */
- if (cert_hostcheck(altptr, conn->host.name))
- matched = TRUE;
- break;
-
- case GEN_IPADD: /* IP address comparison */
- /* compare alternative IP address if the data chunk is the same size
- our server IP address is */
- altlen = ASN1_STRING_length(check->d.ia5);
- if((altlen == addrlen) && !memcmp(altptr, &addr, altlen))
- matched = TRUE;
- break;
- }
- }
- }
- GENERAL_NAMES_free(altnames);
- }
-
- if(matched)
- /* an alternative name matched the server hostname */
- infof(data, "\t subjectAltName: %s matched\n", conn->host.dispname);
- else {
- /* we have to look to the last occurence of a commonName in the
- distinguished one to get the most significant one. */
- int j,i=-1 ;
-
-/* The following is done because of a bug in 0.9.6b */
-
- unsigned char *nulstr = (unsigned char *)"";
- unsigned char *peer_CN = nulstr;
-
- X509_NAME *name = X509_get_subject_name(server_cert) ;
- if (name)
- while ((j=X509_NAME_get_index_by_NID(name,NID_commonName,i))>=0)
- i=j;
-
- /* we have the name entry and we will now convert this to a string
- that we can use for comparison. Doing this we support BMPstring,
- UTF8 etc. */
-
- if (i>=0) {
- ASN1_STRING *tmp = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name,i));
-
- /* In OpenSSL 0.9.7d and earlier, ASN1_STRING_to_UTF8 fails if the input
- is already UTF-8 encoded. We check for this case and copy the raw
- string manually to avoid the problem. This code can be made
- conditional in the future when OpenSSL has been fixed. Work-around
- brought by Alexis S. L. Carvalho. */
- if (tmp && ASN1_STRING_type(tmp) == V_ASN1_UTF8STRING) {
- j = ASN1_STRING_length(tmp);
- if (j >= 0) {
- peer_CN = OPENSSL_malloc(j+1);
- if (peer_CN) {
- memcpy(peer_CN, ASN1_STRING_data(tmp), j);
- peer_CN[j] = '\0';
- }
- }
- }
- else /* not a UTF8 name */
- j = ASN1_STRING_to_UTF8(&peer_CN, tmp);
- }
-
- if (peer_CN == nulstr)
- peer_CN = NULL;
-#ifdef CURL_DOES_CONVERSIONS
- else {
- /* convert peer_CN from UTF8 */
- size_t rc;
- rc = Curl_convert_from_utf8(data, peer_CN, strlen(peer_CN));
- /* Curl_convert_from_utf8 calls failf if unsuccessful */
- if (rc != CURLE_OK) {
- return(rc);
- }
- }
-#endif /* CURL_DOES_CONVERSIONS */
-
- if (!peer_CN) {
- if(data->set.ssl.verifyhost > 1) {
- failf(data,
- "SSL: unable to obtain common name from peer certificate");
- return CURLE_SSL_PEER_CERTIFICATE;
- }
- else {
- /* Consider verifyhost == 1 as an "OK" for a missing CN field, but we
- output a note about the situation */
- infof(data, "\t common name: WARNING couldn't obtain\n");
- }
- }
- else if(!cert_hostcheck((const char *)peer_CN, conn->host.name)) {
- if(data->set.ssl.verifyhost > 1) {
- failf(data, "SSL: certificate subject name '%s' does not match "
- "target host name '%s'", peer_CN, conn->host.dispname);
- res = CURLE_SSL_PEER_CERTIFICATE;
- }
- else
- infof(data, "\t common name: %s (does not match '%s')\n",
- peer_CN, conn->host.dispname);
- }
- else {
- infof(data, "\t common name: %s (matched)\n", peer_CN);
- }
- if(peer_CN)
- OPENSSL_free(peer_CN);
- }
- return res;
-}
-#endif
-
-/* The SSL_CTRL_SET_MSG_CALLBACK doesn't exist in ancient OpenSSL versions
- and thus this cannot be done there. */
-#ifdef SSL_CTRL_SET_MSG_CALLBACK
-
-static const char *ssl_msg_type(int ssl_ver, int msg)
-{
- if (ssl_ver == SSL2_VERSION_MAJOR) {
- switch (msg) {
- case SSL2_MT_ERROR:
- return "Error";
- case SSL2_MT_CLIENT_HELLO:
- return "Client hello";
- case SSL2_MT_CLIENT_MASTER_KEY:
- return "Client key";
- case SSL2_MT_CLIENT_FINISHED:
- return "Client finished";
- case SSL2_MT_SERVER_HELLO:
- return "Server hello";
- case SSL2_MT_SERVER_VERIFY:
- return "Server verify";
- case SSL2_MT_SERVER_FINISHED:
- return "Server finished";
- case SSL2_MT_REQUEST_CERTIFICATE:
- return "Request CERT";
- case SSL2_MT_CLIENT_CERTIFICATE:
- return "Client CERT";
- }
- }
- else if (ssl_ver == SSL3_VERSION_MAJOR) {
- switch (msg) {
- case SSL3_MT_HELLO_REQUEST:
- return "Hello request";
- case SSL3_MT_CLIENT_HELLO:
- return "Client hello";
- case SSL3_MT_SERVER_HELLO:
- return "Server hello";
- case SSL3_MT_CERTIFICATE:
- return "CERT";
- case SSL3_MT_SERVER_KEY_EXCHANGE:
- return "Server key exchange";
- case SSL3_MT_CLIENT_KEY_EXCHANGE:
- return "Client key exchange";
- case SSL3_MT_CERTIFICATE_REQUEST:
- return "Request CERT";
- case SSL3_MT_SERVER_DONE:
- return "Server finished";
- case SSL3_MT_CERTIFICATE_VERIFY:
- return "CERT verify";
- case SSL3_MT_FINISHED:
- return "Finished";
- }
- }
- return "Unknown";
-}
-
-static const char *tls_rt_type(int type)
-{
- return (
- type == SSL3_RT_CHANGE_CIPHER_SPEC ? "TLS change cipher, " :
- type == SSL3_RT_ALERT ? "TLS alert, " :
- type == SSL3_RT_HANDSHAKE ? "TLS handshake, " :
- type == SSL3_RT_APPLICATION_DATA ? "TLS app data, " :
- "TLS Unknown, ");
-}
-
-
-/*
- * Our callback from the SSL/TLS layers.
- */
-static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
- const void *buf, size_t len, const SSL *ssl,
- struct connectdata *conn)
-{
- struct SessionHandle *data;
- const char *msg_name, *tls_rt_name;
- char ssl_buf[1024];
- int ver, msg_type, txt_len;
-
- if (!conn || !conn->data || !conn->data->set.fdebug ||
- (direction != 0 && direction != 1))
- return;
-
- data = conn->data;
- ssl_ver >>= 8;
- ver = (ssl_ver == SSL2_VERSION_MAJOR ? '2' :
- ssl_ver == SSL3_VERSION_MAJOR ? '3' : '?');
-
- /* SSLv2 doesn't seem to have TLS record-type headers, so OpenSSL
- * always pass-up content-type as 0. But the interesting message-type
- * is at 'buf[0]'.
- */
- if (ssl_ver == SSL3_VERSION_MAJOR && content_type != 0)
- tls_rt_name = tls_rt_type(content_type);
- else
- tls_rt_name = "";
-
- msg_type = *(char*)buf;
- msg_name = ssl_msg_type(ssl_ver, msg_type);
-
- txt_len = snprintf(ssl_buf, sizeof(ssl_buf), "SSLv%c, %s%s (%d):\n",
- ver, tls_rt_name, msg_name, msg_type);
- Curl_debug(data, CURLINFO_TEXT, ssl_buf, (size_t)txt_len, NULL);
-
- Curl_debug(data, (direction == 1) ? CURLINFO_SSL_DATA_OUT :
- CURLINFO_SSL_DATA_IN, (char *)buf, len, NULL);
- (void) ssl;
-}
-#endif
-
-#ifdef USE_SSLEAY
-/* ====================================================== */
-
-static CURLcode
-Curl_ossl_connect_step1(struct connectdata *conn,
- int sockindex)
-{
- CURLcode retcode = CURLE_OK;
-
- struct SessionHandle *data = conn->data;
- SSL_METHOD_QUAL SSL_METHOD *req_method=NULL;
- void *ssl_sessionid=NULL;
- curl_socket_t sockfd = conn->sock[sockindex];
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-
- curlassert(ssl_connect_1 == connssl->connecting_state);
-
- /* Make funny stuff to get random input */
- Curl_ossl_seed(data);
-
- /* check to see if we've been told to use an explicit SSL/TLS version */
- switch(data->set.ssl.version) {
- default:
- case CURL_SSLVERSION_DEFAULT:
- /* we try to figure out version */
- req_method = SSLv23_client_method();
- break;
- case CURL_SSLVERSION_TLSv1:
- req_method = TLSv1_client_method();
- break;
- case CURL_SSLVERSION_SSLv2:
-#ifdef OPENSSL_NO_SSL2
- failf(data, "OpenSSL was built without SSLv2 support");
- return CURLE_NOT_BUILT_IN;
-#else
- req_method = SSLv2_client_method();
- break;
-#endif
- case CURL_SSLVERSION_SSLv3:
- req_method = SSLv3_client_method();
- break;
- }
-
- if (connssl->ctx)
- SSL_CTX_free(connssl->ctx);
- connssl->ctx = SSL_CTX_new(req_method);
-
- if(!connssl->ctx) {
- failf(data, "SSL: couldn't create a context!");
- return CURLE_OUT_OF_MEMORY;
- }
-
-#ifdef SSL_CTRL_SET_MSG_CALLBACK
- if (data->set.fdebug && data->set.verbose) {
- /* the SSL trace callback is only used for verbose logging so we only
- inform about failures of setting it */
- if (!SSL_CTX_callback_ctrl(connssl->ctx, SSL_CTRL_SET_MSG_CALLBACK,
- (void (*)(void))ssl_tls_trace)) {
- infof(data, "SSL: couldn't set callback!\n");
- }
- else if (!SSL_CTX_ctrl(connssl->ctx, SSL_CTRL_SET_MSG_CALLBACK_ARG, 0,
- conn)) {
- infof(data, "SSL: couldn't set callback argument!\n");
- }
- }
-#endif
-
- /* OpenSSL contains code to work-around lots of bugs and flaws in various
- SSL-implementations. SSL_CTX_set_options() is used to enabled those
- work-arounds. The man page for this option states that SSL_OP_ALL enables
- all the work-arounds and that "It is usually safe to use SSL_OP_ALL to
- enable the bug workaround options if compatibility with somewhat broken
- implementations is desired."
-
- */
- SSL_CTX_set_options(connssl->ctx, SSL_OP_ALL);
-
-#if 0
- /*
- * Not sure it's needed to tell SSL_connect() that socket is
- * non-blocking. It doesn't seem to care, but just return with
- * SSL_ERROR_WANT_x.
- */
- if (data->state.used_interface == Curl_if_multi)
- SSL_CTX_ctrl(connssl->ctx, BIO_C_SET_NBIO, 1, NULL);
-#endif
-
- if(data->set.cert) {
- if(!cert_stuff(conn,
- connssl->ctx,
- data->set.cert,
- data->set.cert_type,
- data->set.key,
- data->set.key_type)) {
- /* failf() is already done in cert_stuff() */
- return CURLE_SSL_CERTPROBLEM;
- }
- }
-
- if(data->set.ssl.cipher_list) {
- if(!SSL_CTX_set_cipher_list(connssl->ctx,
- data->set.ssl.cipher_list)) {
- failf(data, "failed setting cipher list");
- return CURLE_SSL_CIPHER;
- }
- }
-
- if (data->set.ssl.CAfile || data->set.ssl.CApath) {
- /* tell SSL where to find CA certificates that are used to verify
- the servers certificate. */
- if (!SSL_CTX_load_verify_locations(connssl->ctx, data->set.ssl.CAfile,
- data->set.ssl.CApath)) {
- if (data->set.ssl.verifypeer) {
- /* Fail if we insist on successfully verifying the server. */
- failf(data,"error setting certificate verify locations:\n"
- " CAfile: %s\n CApath: %s\n",
- data->set.ssl.CAfile ? data->set.ssl.CAfile : "none",
- data->set.ssl.CApath ? data->set.ssl.CApath : "none");
- return CURLE_SSL_CACERT_BADFILE;
- }
- else {
- /* Just continue with a warning if no strict certificate verification
- is required. */
- infof(data, "error setting certificate verify locations,"
- " continuing anyway:\n");
- }
- }
- else {
- /* Everything is fine. */
- infof(data, "successfully set certificate verify locations:\n");
- }
- infof(data,
- " CAfile: %s\n"
- " CApath: %s\n",
- data->set.ssl.CAfile ? data->set.ssl.CAfile : "none",
- data->set.ssl.CApath ? data->set.ssl.CApath : "none");
- }
- /* SSL always tries to verify the peer, this only says whether it should
- * fail to connect if the verification fails, or if it should continue
- * anyway. In the latter case the result of the verification is checked with
- * SSL_get_verify_result() below. */
- SSL_CTX_set_verify(connssl->ctx,
- data->set.ssl.verifypeer?SSL_VERIFY_PEER:SSL_VERIFY_NONE,
- cert_verify_callback);
-
- /* give application a chance to interfere with SSL set up. */
- if(data->set.ssl.fsslctx) {
- retcode = (*data->set.ssl.fsslctx)(data, connssl->ctx,
- data->set.ssl.fsslctxp);
- if(retcode) {
- failf(data,"error signaled by ssl ctx callback");
- return retcode;
- }
- }
-
- /* Lets make an SSL structure */
- if (connssl->handle)
- SSL_free(connssl->handle);
- connssl->handle = SSL_new(connssl->ctx);
- if (!connssl->handle) {
- failf(data, "SSL: couldn't create a context (handle)!");
- return CURLE_OUT_OF_MEMORY;
- }
- SSL_set_connect_state(connssl->handle);
-
- connssl->server_cert = 0x0;
-
- /* Check if there's a cached ID we can/should use here! */
- if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) {
- /* we got a session id, use it! */
- if (!SSL_set_session(connssl->handle, ssl_sessionid)) {
- failf(data, "SSL: SSL_set_session failed: %s",
- ERR_error_string(ERR_get_error(),NULL));
- return CURLE_SSL_CONNECT_ERROR;
- }
- /* Informational message */
- infof (data, "SSL re-using session ID\n");
- }
-
- /* pass the raw socket into the SSL layers */
- if (!SSL_set_fd(connssl->handle, sockfd)) {
- failf(data, "SSL: SSL_set_fd failed: %s",
- ERR_error_string(ERR_get_error(),NULL));
- return CURLE_SSL_CONNECT_ERROR;
- }
-
- connssl->connecting_state = ssl_connect_2;
- return CURLE_OK;
-}
-
-static CURLcode
-Curl_ossl_connect_step2(struct connectdata *conn,
- int sockindex, long *timeout_ms)
-{
- struct SessionHandle *data = conn->data;
- int err;
- long has_passed;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-
- curlassert(ssl_connect_2 == connssl->connecting_state
- || ssl_connect_2_reading == connssl->connecting_state
- || ssl_connect_2_writing == connssl->connecting_state);
-
- /* Find out if any timeout is set. If not, use 300 seconds.
- Otherwise, figure out the most strict timeout of the two possible one
- and then how much time that has elapsed to know how much time we
- allow for the connect call */
- if(data->set.timeout && data->set.connecttimeout) {
- /* get the most strict timeout of the ones converted to milliseconds */
- if(data->set.timeout<data->set.connecttimeout)
- *timeout_ms = data->set.timeout*1000;
- else
- *timeout_ms = data->set.connecttimeout*1000;
- }
- else if(data->set.timeout)
- *timeout_ms = data->set.timeout*1000;
- else if(data->set.connecttimeout)
- *timeout_ms = data->set.connecttimeout*1000;
- else
- /* no particular time-out has been set */
- *timeout_ms= DEFAULT_CONNECT_TIMEOUT;
-
- /* Evaluate in milliseconds how much time that has passed */
- has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
-
- /* subtract the passed time */
- *timeout_ms -= has_passed;
-
- if(*timeout_ms < 0) {
- /* a precaution, no need to continue if time already is up */
- failf(data, "SSL connection timeout");
- return CURLE_OPERATION_TIMEOUTED;
- }
-
- err = SSL_connect(connssl->handle);
-
- /* 1 is fine
- 0 is "not successful but was shut down controlled"
- <0 is "handshake was not successful, because a fatal error occurred" */
- if(1 != err) {
- int detail = SSL_get_error(connssl->handle, err);
-
- if(SSL_ERROR_WANT_READ == detail) {
- connssl->connecting_state = ssl_connect_2_reading;
- return CURLE_OK;
- }
- else if(SSL_ERROR_WANT_WRITE == detail) {
- connssl->connecting_state = ssl_connect_2_writing;
- return CURLE_OK;
- }
- else {
- /* untreated error */
- unsigned long errdetail;
- char error_buffer[256]; /* OpenSSL documents that this must be at least
- 256 bytes long. */
- CURLcode rc;
- const char *cert_problem = NULL;
-
- connssl->connecting_state = ssl_connect_2; /* the connection failed,
- we're not waiting for
- anything else. */
-
- errdetail = ERR_get_error(); /* Gets the earliest error code from the
- thread's error queue and removes the
- entry. */
-
- switch(errdetail) {
- case 0x1407E086:
- /* 1407E086:
- SSL routines:
- SSL2_SET_CERTIFICATE:
- certificate verify failed */
- /* fall-through */
- case 0x14090086:
- /* 14090086:
- SSL routines:
- SSL3_GET_SERVER_CERTIFICATE:
- certificate verify failed */
- cert_problem = "SSL certificate problem, verify that the CA cert is"
- " OK. Details:\n";
- rc = CURLE_SSL_CACERT;
- break;
- default:
- rc = CURLE_SSL_CONNECT_ERROR;
- break;
- }
-
- /* detail is already set to the SSL error above */
-
- /* If we e.g. use SSLv2 request-method and the server doesn't like us
- * (RST connection etc.), OpenSSL gives no explanation whatsoever and
- * the SO_ERROR is also lost.
- */
- if (CURLE_SSL_CONNECT_ERROR == rc && errdetail == 0) {
- failf(data, "Unknown SSL protocol error in connection to %s:%d ",
- conn->host.name, conn->port);
- return rc;
- }
- /* Could be a CERT problem */
-
- SSL_strerror(errdetail, error_buffer, sizeof(error_buffer));
- failf(data, "%s%s", cert_problem ? cert_problem : "", error_buffer);
- return rc;
- }
- }
- else {
- /* we have been connected fine, we're not waiting for anything else. */
- connssl->connecting_state = ssl_connect_3;
-
- /* Informational message */
- infof (data, "SSL connection using %s\n",
- SSL_get_cipher(connssl->handle));
-
- return CURLE_OK;
- }
-}
-
-static CURLcode
-Curl_ossl_connect_step3(struct connectdata *conn,
- int sockindex)
-{
- CURLcode retcode = CURLE_OK;
- char * str;
- long lerr;
- ASN1_TIME *certdate;
- void *ssl_sessionid=NULL;
- struct SessionHandle *data = conn->data;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-
- curlassert(ssl_connect_3 == connssl->connecting_state);
-
- if(Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) {
- /* Since this is not a cached session ID, then we want to stach this one
- in the cache! */
- SSL_SESSION *our_ssl_sessionid;
-#ifdef HAVE_SSL_GET1_SESSION
- our_ssl_sessionid = SSL_get1_session(connssl->handle);
-
- /* SSL_get1_session() will increment the reference
- count and the session will stay in memory until explicitly freed with
- SSL_SESSION_free(3), regardless of its state.
- This function was introduced in openssl 0.9.5a. */
-#else
- our_ssl_sessionid = SSL_get_session(connssl->handle);
-
- /* if SSL_get1_session() is unavailable, use SSL_get_session().
- This is an inferior option because the session can be flushed
- at any time by openssl. It is included only so curl compiles
- under versions of openssl < 0.9.5a.
-
- WARNING: How curl behaves if it's session is flushed is
- untested.
- */
-#endif
- retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
- 0 /* unknown size */);
- if(retcode) {
- failf(data, "failed to store ssl session");
- return retcode;
- }
- }
-
-
- /* Get server's certificate (note: beware of dynamic allocation) - opt */
- /* major serious hack alert -- we should check certificates
- * to authenticate the server; otherwise we risk man-in-the-middle
- * attack
- */
-
- connssl->server_cert = SSL_get_peer_certificate(connssl->handle);
- if(!connssl->server_cert) {
- failf(data, "SSL: couldn't get peer certificate!");
- return CURLE_SSL_PEER_CERTIFICATE;
- }
- infof (data, "Server certificate:\n");
-
- str = X509_NAME_oneline(X509_get_subject_name(connssl->server_cert),
- NULL, 0);
- if(!str) {
- failf(data, "SSL: couldn't get X509-subject!");
- X509_free(connssl->server_cert);
- connssl->server_cert = NULL;
- return CURLE_SSL_CONNECT_ERROR;
- }
- infof(data, "\t subject: %s\n", str);
- CRYPTO_free(str);
-
- certdate = X509_get_notBefore(connssl->server_cert);
- Curl_ASN1_UTCTIME_output(conn, "\t start date: ", certdate);
-
- certdate = X509_get_notAfter(connssl->server_cert);
- Curl_ASN1_UTCTIME_output(conn, "\t expire date: ", certdate);
-
- if(data->set.ssl.verifyhost) {
- retcode = verifyhost(conn, connssl->server_cert);
- if(retcode) {
- X509_free(connssl->server_cert);
- connssl->server_cert = NULL;
- return retcode;
- }
- }
-
- str = X509_NAME_oneline(X509_get_issuer_name(connssl->server_cert),
- NULL, 0);
- if(!str) {
- failf(data, "SSL: couldn't get X509-issuer name!");
- retcode = CURLE_SSL_CONNECT_ERROR;
- }
- else {
- infof(data, "\t issuer: %s\n", str);
- CRYPTO_free(str);
-
- /* We could do all sorts of certificate verification stuff here before
- deallocating the certificate. */
-
- lerr = data->set.ssl.certverifyresult=
- SSL_get_verify_result(connssl->handle);
- if(data->set.ssl.certverifyresult != X509_V_OK) {
- if(data->set.ssl.verifypeer) {
- /* We probably never reach this, because SSL_connect() will fail
- and we return earlyer if verifypeer is set? */
- failf(data, "SSL certificate verify result: %s (%ld)",
- X509_verify_cert_error_string(lerr), lerr);
- retcode = CURLE_SSL_PEER_CERTIFICATE;
- }
- else
- infof(data, "SSL certificate verify result: %s (%ld),"
- " continuing anyway.\n",
- X509_verify_cert_error_string(lerr), lerr);
- }
- else
- infof(data, "SSL certificate verify ok.\n");
- }
-
- X509_free(connssl->server_cert);
- connssl->server_cert = NULL;
- connssl->connecting_state = ssl_connect_done;
- return retcode;
-}
-
-static CURLcode
-Curl_ossl_connect_common(struct connectdata *conn,
- int sockindex,
- bool nonblocking,
- bool *done)
-{
- CURLcode retcode;
- struct SessionHandle *data = conn->data;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- curl_socket_t sockfd = conn->sock[sockindex];
- long timeout_ms;
-
- if (ssl_connect_1==connssl->connecting_state) {
- retcode = Curl_ossl_connect_step1(conn, sockindex);
- if (retcode)
- return retcode;
- }
-
- timeout_ms = 0;
- while (ssl_connect_2 == connssl->connecting_state ||
- ssl_connect_2_reading == connssl->connecting_state ||
- ssl_connect_2_writing == connssl->connecting_state) {
-
- /* if ssl is expecting something, check if it's available. */
- if (connssl->connecting_state == ssl_connect_2_reading
- || connssl->connecting_state == ssl_connect_2_writing) {
-
- int writefd = ssl_connect_2_writing==
- connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
- int readfd = ssl_connect_2_reading==
- connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
-
- while(1) {
- int what = Curl_select(readfd, writefd, nonblocking?0:(int)timeout_ms);
- if(what > 0)
- /* readable or writable, go loop in the outer loop */
- break;
- else if(0 == what) {
- if (nonblocking) {
- *done = FALSE;
- return CURLE_OK;
- }
- else {
- /* timeout */
- failf(data, "SSL connection timeout");
- return CURLE_OPERATION_TIMEDOUT;
- }
- }
- else {
- /* anything that gets here is fatally bad */
- failf(data, "select on SSL socket, errno: %d", Curl_sockerrno());
- return CURLE_SSL_CONNECT_ERROR;
- }
- } /* while()-loop for the select() */
- }
-
- /* get the timeout from step2 to avoid computing it twice. */
- retcode = Curl_ossl_connect_step2(conn, sockindex, &timeout_ms);
- if (retcode)
- return retcode;
-
- } /* repeat step2 until all transactions are done. */
-
-
- if (ssl_connect_3==connssl->connecting_state) {
- retcode = Curl_ossl_connect_step3(conn, sockindex);
- if (retcode)
- return retcode;
- }
-
- if (ssl_connect_done==connssl->connecting_state) {
- *done = TRUE;
- }
- else {
- *done = FALSE;
- }
-
- /* Reset our connect state machine */
- connssl->connecting_state = ssl_connect_1;
-
- return CURLE_OK;
-}
-
-CURLcode
-Curl_ossl_connect_nonblocking(struct connectdata *conn,
- int sockindex,
- bool *done)
-{
- return Curl_ossl_connect_common(conn, sockindex, TRUE, done);
-}
-
-CURLcode
-Curl_ossl_connect(struct connectdata *conn,
- int sockindex)
-{
- CURLcode retcode;
- bool done = FALSE;
-
- retcode = Curl_ossl_connect_common(conn, sockindex, FALSE, &done);
- if (retcode)
- return retcode;
-
- curlassert(done);
-
- return CURLE_OK;
-}
-
-/* return number of sent (non-SSL) bytes */
-ssize_t Curl_ossl_send(struct connectdata *conn,
- int sockindex,
- void *mem,
- size_t len)
-{
- /* SSL_write() is said to return 'int' while write() and send() returns
- 'size_t' */
- int err;
- char error_buffer[120]; /* OpenSSL documents that this must be at least 120
- bytes long. */
- unsigned long sslerror;
- int rc = SSL_write(conn->ssl[sockindex].handle, mem, (int)len);
-
- if(rc < 0) {
- err = SSL_get_error(conn->ssl[sockindex].handle, rc);
-
- switch(err) {
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_WANT_WRITE:
- /* The operation did not complete; the same TLS/SSL I/O function
- should be called again later. This is basicly an EWOULDBLOCK
- equivalent. */
- return 0;
- case SSL_ERROR_SYSCALL:
- failf(conn->data, "SSL_write() returned SYSCALL, errno = %d\n",
- Curl_sockerrno());
- return -1;
- case SSL_ERROR_SSL:
- /* A failure in the SSL library occurred, usually a protocol error.
- The OpenSSL error queue contains more information on the error. */
- sslerror = ERR_get_error();
- failf(conn->data, "SSL_write() error: %s\n",
- ERR_error_string(sslerror, error_buffer));
- return -1;
- }
- /* a true error */
- failf(conn->data, "SSL_write() return error %d\n", err);
- return -1;
- }
- return (ssize_t)rc; /* number of bytes */
-}
-
-/*
- * If the read would block we return -1 and set 'wouldblock' to TRUE.
- * Otherwise we return the amount of data read. Other errors should return -1
- * and set 'wouldblock' to FALSE.
- */
-ssize_t Curl_ossl_recv(struct connectdata *conn, /* connection data */
- int num, /* socketindex */
- char *buf, /* store read data here */
- size_t buffersize, /* max amount to read */
- bool *wouldblock)
-{
- char error_buffer[120]; /* OpenSSL documents that this must be at
- least 120 bytes long. */
- unsigned long sslerror;
- ssize_t nread = (ssize_t)SSL_read(conn->ssl[num].handle, buf,
- (int)buffersize);
- *wouldblock = FALSE;
- if(nread < 0) {
- /* failed SSL_read */
- int err = SSL_get_error(conn->ssl[num].handle, (int)nread);
-
- switch(err) {
- case SSL_ERROR_NONE: /* this is not an error */
- case SSL_ERROR_ZERO_RETURN: /* no more data */
- break;
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_WANT_WRITE:
- /* there's data pending, re-invoke SSL_read() */
- *wouldblock = TRUE;
- return -1; /* basically EWOULDBLOCK */
- default:
- /* openssl/ssl.h says "look at error stack/return value/errno" */
- sslerror = ERR_get_error();
- failf(conn->data, "SSL read: %s, errno %d",
- ERR_error_string(sslerror, error_buffer),
- Curl_sockerrno() );
- return -1;
- }
- }
- return nread;
-}
-
-size_t Curl_ossl_version(char *buffer, size_t size)
-{
-#ifdef YASSL_VERSION
- /* yassl provides an OpenSSL API compatiblity layer so it looks identical
- to OpenSSL in all other aspects */
- return snprintf(buffer, size, " yassl/%s", YASSL_VERSION);
-#else /* YASSL_VERSION */
-
-#if (SSLEAY_VERSION_NUMBER >= 0x905000)
- {
- char sub[2];
- unsigned long ssleay_value;
- sub[1]='\0';
- ssleay_value=SSLeay();
- if(ssleay_value < 0x906000) {
- ssleay_value=SSLEAY_VERSION_NUMBER;
- sub[0]='\0';
- }
- else {
- if(ssleay_value&0xff0) {
- sub[0]=(char)(((ssleay_value>>4)&0xff) + 'a' -1);
- }
- else
- sub[0]='\0';
- }
-
- return snprintf(buffer, size, " OpenSSL/%lx.%lx.%lx%s",
- (ssleay_value>>28)&0xf,
- (ssleay_value>>20)&0xff,
- (ssleay_value>>12)&0xff,
- sub);
- }
-
-#else /* SSLEAY_VERSION_NUMBER is less than 0.9.5 */
-
-#if (SSLEAY_VERSION_NUMBER >= 0x900000)
- return snprintf(buffer, size, " OpenSSL/%lx.%lx.%lx",
- (SSLEAY_VERSION_NUMBER>>28)&0xff,
- (SSLEAY_VERSION_NUMBER>>20)&0xff,
- (SSLEAY_VERSION_NUMBER>>12)&0xf);
-
-#else /* (SSLEAY_VERSION_NUMBER >= 0x900000) */
- {
- char sub[2];
- sub[1]='\0';
- if(SSLEAY_VERSION_NUMBER&0x0f) {
- sub[0]=(SSLEAY_VERSION_NUMBER&0x0f) + 'a' -1;
- }
- else
- sub[0]='\0';
-
- return snprintf(buffer, size, " SSL/%x.%x.%x%s",
- (SSLEAY_VERSION_NUMBER>>12)&0xff,
- (SSLEAY_VERSION_NUMBER>>8)&0xf,
- (SSLEAY_VERSION_NUMBER>>4)&0xf, sub);
- }
-#endif /* (SSLEAY_VERSION_NUMBER >= 0x900000) */
-#endif /* SSLEAY_VERSION_NUMBER is less than 0.9.5 */
-
-#endif /* YASSL_VERSION */
-}
-#endif /* USE_SSLEAY */
diff --git a/Utilities/cmcurl/ssluse.h b/Utilities/cmcurl/ssluse.h
deleted file mode 100644
index 5bb7090c5..000000000
--- a/Utilities/cmcurl/ssluse.h
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef __SSLUSE_H
-#define __SSLUSE_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-/*
- * This header should only be needed to get included by sslgen.c and ssluse.c
- */
-
-#include "urldata.h"
-CURLcode Curl_ossl_connect(struct connectdata *conn, int sockindex);
-CURLcode Curl_ossl_connect_nonblocking(struct connectdata *conn,
- int sockindex,
- bool *done);
-void Curl_ossl_close(struct connectdata *conn); /* close a SSL connection */
-/* tell OpenSSL to close down all open information regarding connections (and
- thus session ID caching etc) */
-int Curl_ossl_close_all(struct SessionHandle *data);
-/* Sets an OpenSSL engine */
-CURLcode Curl_ossl_set_engine(struct SessionHandle *data, const char *engine);
-
-/* function provided for the generic SSL-layer, called when a session id
- should be freed */
-void Curl_ossl_session_free(void *ptr);
-
-/* Sets engine as default for all SSL operations */
-CURLcode Curl_ossl_set_engine_default(struct SessionHandle *data);
-
-/* Build list of OpenSSL engines */
-struct curl_slist *Curl_ossl_engines_list(struct SessionHandle *data);
-
-int Curl_ossl_init(void);
-void Curl_ossl_cleanup(void);
-
-ssize_t Curl_ossl_send(struct connectdata *conn,
- int sockindex,
- void *mem,
- size_t len);
-ssize_t Curl_ossl_recv(struct connectdata *conn, /* connection data */
- int num, /* socketindex */
- char *buf, /* store read data here */
- size_t buffersize, /* max amount to read */
- bool *wouldblock);
-
-size_t Curl_ossl_version(char *buffer, size_t size);
-int Curl_ossl_check_cxn(struct connectdata *cxn);
-int Curl_ossl_seed(struct SessionHandle *data);
-
-int Curl_ossl_shutdown(struct connectdata *conn, int sockindex);
-
-#endif
diff --git a/Utilities/cmcurl/strdup.c b/Utilities/cmcurl/strdup.c
deleted file mode 100644
index e16e08a72..000000000
--- a/Utilities/cmcurl/strdup.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-#include "strdup.h"
-
-#ifndef HAVE_STRDUP
-char *curlx_strdup(const char *str)
-{
- int len;
- char *newstr;
-
- if (!str)
- return (char *)NULL;
-
- len = strlen(str);
- newstr = (char *) malloc((len+1)*sizeof(char));
- if (!newstr)
- return (char *)NULL;
-
- strcpy(newstr,str);
-
- return newstr;
-
-}
-#endif
diff --git a/Utilities/cmcurl/strdup.h b/Utilities/cmcurl/strdup.h
deleted file mode 100644
index 3206db3cf..000000000
--- a/Utilities/cmcurl/strdup.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#ifndef _CURL_STRDUP_H
-#define _CURL_STRDUP_H
-
-#include "setup.h"
-
-#ifndef HAVE_STRDUP
-extern char *curlx_strdup(const char *str);
-#endif
-
-#endif
-
diff --git a/Utilities/cmcurl/strequal.c b/Utilities/cmcurl/strequal.c
deleted file mode 100644
index 83796f667..000000000
--- a/Utilities/cmcurl/strequal.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#include <string.h>
-#include <ctype.h>
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-
-#include "strequal.h"
-
-#if defined(HAVE_STRCASECMP) && defined(__STRICT_ANSI__)
-/* this is for "-ansi -Wall -pedantic" to stop complaining! */
-extern int (strcasecmp)(const char *s1, const char *s2);
-extern int (strncasecmp)(const char *s1, const char *s2, size_t n);
-#endif
-
-int curl_strequal(const char *first, const char *second)
-{
-#if defined(HAVE_STRCASECMP)
- return !(strcasecmp)(first, second);
-#elif defined(HAVE_STRCMPI)
- return !(strcmpi)(first, second);
-#elif defined(HAVE_STRICMP)
- return !(stricmp)(first, second);
-#else
- while (*first && *second) {
- if (toupper(*first) != toupper(*second)) {
- break;
- }
- first++;
- second++;
- }
- return toupper(*first) == toupper(*second);
-#endif
-}
-
-int curl_strnequal(const char *first, const char *second, size_t max)
-{
-#if defined(HAVE_STRCASECMP)
- return !strncasecmp(first, second, max);
-#elif defined(HAVE_STRCMPI)
- return !strncmpi(first, second, max);
-#elif defined(HAVE_STRICMP)
- return !strnicmp(first, second, max);
-#else
- while (*first && *second && max) {
- if (toupper(*first) != toupper(*second)) {
- break;
- }
- max--;
- first++;
- second++;
- }
- if(0 == max)
- return 1; /* they are equal this far */
-
- return toupper(*first) == toupper(*second);
-#endif
-}
-
-/*
- * Curl_strcasestr() finds the first occurrence of the substring needle in the
- * string haystack. The terminating `\0' characters are not compared. The
- * matching is done CASE INSENSITIVE, which thus is the difference between
- * this and strstr().
- */
-char *Curl_strcasestr(const char *haystack, const char *needle)
-{
- size_t nlen = strlen(needle);
- size_t hlen = strlen(haystack);
-
- while(hlen-- >= nlen) {
- if(curl_strnequal(haystack, needle, nlen))
- return (char *)haystack;
- haystack++;
- }
- return NULL;
-}
diff --git a/Utilities/cmcurl/strequal.h b/Utilities/cmcurl/strequal.h
deleted file mode 100644
index 6718c3c0e..000000000
--- a/Utilities/cmcurl/strequal.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef __STREQUAL_H
-#define __STREQUAL_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include <curl/curl.h>
-
-#define strequal(a,b) curl_strequal(a,b)
-#define strnequal(a,b,c) curl_strnequal(a,b,c)
-
-/* checkprefix() is a shorter version of the above, used when the first
- argument is zero-byte terminated */
-#define checkprefix(a,b) strnequal(a,b,strlen(a))
-
-/* case insensitive strstr() */
-char *Curl_strcasestr(const char *haystack, const char *needle);
-
-#endif
diff --git a/Utilities/cmcurl/strerror.c b/Utilities/cmcurl/strerror.c
deleted file mode 100644
index 74c345779..000000000
--- a/Utilities/cmcurl/strerror.c
+++ /dev/null
@@ -1,751 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2004 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#ifdef HAVE_STRERROR_R
-#if !defined(HAVE_POSIX_STRERROR_R) && !defined(HAVE_GLIBC_STRERROR_R)
-#error "you MUST have either POSIX or glibc strerror_r if strerror_r is found"
-#endif /* !POSIX && !glibc */
-#endif /* HAVE_STRERROR_R */
-
-#include <curl/curl.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#ifdef USE_LIBIDN
-#include <idna.h>
-#endif
-
-#include "strerror.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-#if defined(HAVE_STRERROR_R) && defined(HAVE_NO_STRERROR_R_DECL)
-#ifdef HAVE_POSIX_STRERROR_R
-/* seen on AIX 5100-02 gcc 2.9 */
-extern int strerror_r(int errnum, char *strerrbuf, size_t buflen);
-#else
-extern char *strerror_r(int errnum, char *buf, size_t buflen);
-#endif
-#endif
-
-const char *
-curl_easy_strerror(CURLcode error)
-{
-#ifndef CURL_DISABLE_VERBOSE_STRINGS
- switch (error) {
- case CURLE_OK:
- return "no error";
-
- case CURLE_UNSUPPORTED_PROTOCOL:
- return "unsupported protocol";
-
- case CURLE_FAILED_INIT:
- return "failed init";
-
- case CURLE_URL_MALFORMAT:
- return "URL using bad/illegal format or missing URL";
-
- case CURLE_NOT_BUILT_IN:
- return "A requested feature, protocol or option was not found built-in in"
- " this libcurl due to a build-time decision.";
-
- case CURLE_COULDNT_RESOLVE_PROXY:
- return "couldn't resolve proxy name";
-
- case CURLE_COULDNT_RESOLVE_HOST:
- return "couldn't resolve host name";
-
- case CURLE_COULDNT_CONNECT:
- return "couldn't connect to server";
-
- case CURLE_FTP_WEIRD_SERVER_REPLY:
- return "FTP: weird server reply";
-
- case CURLE_FTP_ACCESS_DENIED:
- return "FTP: access denied";
-
- case CURLE_FTP_WEIRD_PASS_REPLY:
- return "FTP: unknown PASS reply";
-
- case CURLE_FTP_WEIRD_USER_REPLY:
- return "FTP: unknown USER reply";
-
- case CURLE_FTP_WEIRD_PASV_REPLY:
- return "FTP: unknown PASV reply";
-
- case CURLE_FTP_WEIRD_227_FORMAT:
- return "FTP: unknown 227 response format";
-
- case CURLE_FTP_CANT_GET_HOST:
- return "FTP: can't figure out the host in the PASV response";
-
- case CURLE_FTP_CANT_RECONNECT:
- return "FTP: can't connect to server the response code is unknown";
-
- case CURLE_FTP_COULDNT_SET_BINARY:
- return "FTP: couldn't set binary mode";
-
- case CURLE_PARTIAL_FILE:
- return "Transferred a partial file";
-
- case CURLE_FTP_COULDNT_RETR_FILE:
- return "FTP: couldn't retrieve (RETR failed) the specified file";
-
- case CURLE_FTP_WRITE_ERROR:
- return "FTP: the post-transfer acknowledge response was not OK";
-
- case CURLE_FTP_QUOTE_ERROR:
- return "FTP: a quote command returned error";
-
- case CURLE_HTTP_RETURNED_ERROR:
- return "HTTP response code said error";
-
- case CURLE_WRITE_ERROR:
- return "failed writing received data to disk/application";
-
- case CURLE_FTP_COULDNT_STOR_FILE:
- return "failed FTP upload (the STOR command)";
-
- case CURLE_READ_ERROR:
- return "failed to open/read local data from file/application";
-
- case CURLE_OUT_OF_MEMORY:
-#ifdef CURL_DOES_CONVERSIONS
- return "conversion failed -or- out of memory";
-#else
- return "out of memory";
-#endif /* CURL_DOES_CONVERSIONS */
-
- case CURLE_OPERATION_TIMEOUTED:
- return "a timeout was reached";
-
- case CURLE_FTP_COULDNT_SET_ASCII:
- return "FTP could not set ASCII mode (TYPE A)";
-
- case CURLE_FTP_PORT_FAILED:
- return "FTP command PORT failed";
-
- case CURLE_FTP_COULDNT_USE_REST:
- return "FTP command REST failed";
-
- case CURLE_FTP_COULDNT_GET_SIZE:
- return "FTP command SIZE failed";
-
- case CURLE_HTTP_RANGE_ERROR:
- return "a range was requested but the server did not deliver it";
-
- case CURLE_HTTP_POST_ERROR:
- return "internal problem setting up the POST";
-
- case CURLE_SSL_CONNECT_ERROR:
- return "SSL connect error";
-
- case CURLE_BAD_DOWNLOAD_RESUME:
- return "couldn't resume download";
-
- case CURLE_FILE_COULDNT_READ_FILE:
- return "couldn't read a file:// file";
-
- case CURLE_LDAP_CANNOT_BIND:
- return "LDAP: cannot bind";
-
- case CURLE_LDAP_SEARCH_FAILED:
- return "LDAP: search failed";
-
- case CURLE_LIBRARY_NOT_FOUND:
- return "a required shared library was not found";
-
- case CURLE_FUNCTION_NOT_FOUND:
- return "a required function in the shared library was not found";
-
- case CURLE_ABORTED_BY_CALLBACK:
- return "the operation was aborted by an application callback";
-
- case CURLE_BAD_FUNCTION_ARGUMENT:
- return "a libcurl function was given a bad argument";
-
- case CURLE_INTERFACE_FAILED:
- return "failed binding local connection end";
-
- case CURLE_TOO_MANY_REDIRECTS :
- return "number of redirects hit maximum amount";
-
- case CURLE_UNKNOWN_TELNET_OPTION:
- return "User specified an unknown option";
-
- case CURLE_TELNET_OPTION_SYNTAX :
- return "Malformed telnet option";
-
- case CURLE_SSL_PEER_CERTIFICATE:
- return "SSL peer certificate was not ok";
-
- case CURLE_GOT_NOTHING:
- return "server returned nothing (no headers, no data)";
-
- case CURLE_SSL_ENGINE_NOTFOUND:
- return "SSL crypto engine not found";
-
- case CURLE_SSL_ENGINE_SETFAILED:
- return "can not set SSL crypto engine as default";
-
- case CURLE_SSL_ENGINE_INITFAILED:
- return "failed to initialise SSL crypto engine";
-
- case CURLE_SEND_ERROR:
- return "failed sending data to the peer";
-
- case CURLE_RECV_ERROR:
- return "failure when receiving data from the peer";
-
- case CURLE_SHARE_IN_USE:
- return "share is already in use";
-
- case CURLE_SSL_CERTPROBLEM:
- return "problem with the local SSL certificate";
-
- case CURLE_SSL_CIPHER:
- return "couldn't use specified SSL cipher";
-
- case CURLE_SSL_CACERT:
- return "peer certificate cannot be authenticated with known CA certificates";
-
- case CURLE_SSL_CACERT_BADFILE:
- return "problem with the SSL CA cert (path? access rights?)";
-
- case CURLE_BAD_CONTENT_ENCODING:
- return "Unrecognized HTTP Content-Encoding";
-
- case CURLE_LDAP_INVALID_URL:
- return "Invalid LDAP URL";
-
- case CURLE_FILESIZE_EXCEEDED:
- return "Maximum file size exceeded";
-
- case CURLE_FTP_SSL_FAILED:
- return "Requested FTP SSL level failed";
-
- case CURLE_SSL_SHUTDOWN_FAILED:
- return "Failed to shut down the SSL connection";
-
- case CURLE_SEND_FAIL_REWIND:
- return "Send failed since rewinding of the data stream failed";
-
- case CURLE_LOGIN_DENIED:
- return "FTP: login denied";
-
- case CURLE_TFTP_NOTFOUND:
- return "TFTP: File Not Found";
-
- case CURLE_TFTP_PERM:
- return "TFTP: Access Violation";
-
- case CURLE_TFTP_DISKFULL:
- return "TFTP: Disk full or allocation exceeded";
-
- case CURLE_TFTP_ILLEGAL:
- return "TFTP: Illegal operation";
-
- case CURLE_TFTP_UNKNOWNID:
- return "TFTP: Unknown transfer ID";
-
- case CURLE_TFTP_EXISTS:
- return "TFTP: File already exists";
-
- case CURLE_TFTP_NOSUCHUSER:
- return "TFTP: No such user";
-
- case CURLE_CONV_FAILED:
- return "conversion failed";
-
- case CURLE_CONV_REQD:
- return "caller must register CURLOPT_CONV_ callback options";
-
- case CURLE_REMOTE_FILE_NOT_FOUND:
- return "Remote file not found";
-
- case CURLE_SSH:
- return "Error in the SSH layer";
-
- /* error codes not used by current libcurl */
- case CURLE_FTP_USER_PASSWORD_INCORRECT:
- case CURLE_MALFORMAT_USER:
- case CURLE_BAD_CALLING_ORDER:
- case CURLE_BAD_PASSWORD_ENTERED:
- case CURLE_OBSOLETE:
- case CURL_LAST:
- break;
- }
- /*
- * By using a switch, gcc -Wall will complain about enum values
- * which do not appear, helping keep this function up-to-date.
- * By using gcc -Wall -Werror, you can't forget.
- *
- * A table would not have the same benefit. Most compilers will
- * generate code very similar to a table in any case, so there
- * is little performance gain from a table. And something is broken
- * for the user's application, anyways, so does it matter how fast
- * it _doesn't_ work?
- *
- * The line number for the error will be near this comment, which
- * is why it is here, and not at the start of the switch.
- */
- return "unknown error";
-#else
- if (error == CURLE_OK)
- return "no error";
- else
- return "error";
-#endif
-}
-
-const char *
-curl_multi_strerror(CURLMcode error)
-{
-#ifndef CURL_DISABLE_VERBOSE_STRINGS
- switch (error) {
- case CURLM_CALL_MULTI_PERFORM:
- return "please call curl_multi_perform() soon";
-
- case CURLM_OK:
- return "no error";
-
- case CURLM_BAD_HANDLE:
- return "invalid multi handle";
-
- case CURLM_BAD_EASY_HANDLE:
- return "invalid easy handle";
-
- case CURLM_OUT_OF_MEMORY:
- return "out of memory";
-
- case CURLM_INTERNAL_ERROR:
- return "internal error";
-
- case CURLM_BAD_SOCKET:
- return "invalid socket argument";
-
- case CURLM_UNKNOWN_OPTION:
- return "unknown option";
-
- case CURLM_LAST:
- break;
- }
-
- return "unknown error";
-#else
- if (error == CURLM_OK)
- return "no error";
- else
- return "error";
-#endif
-}
-
-const char *
-curl_share_strerror(CURLSHcode error)
-{
-#ifndef CURL_DISABLE_VERBOSE_STRINGS
- switch (error) {
- case CURLSHE_OK:
- return "no error";
-
- case CURLSHE_BAD_OPTION:
- return "unknown share option";
-
- case CURLSHE_IN_USE:
- return "share currently in use";
-
- case CURLSHE_INVALID:
- return "invalid share handle";
-
- case CURLSHE_NOMEM:
- return "out of memory";
-
- case CURLSHE_LAST:
- break;
- }
-
- return "CURLSH unknown";
-#else
- if (error == CURLSHE_OK)
- return "no error";
- else
- return "error";
-#endif
-}
-
-#ifdef USE_WINSOCK
-
-/* This function handles most / all (?) Winsock errors cURL is able to produce.
- */
-static const char *
-get_winsock_error (int err, char *buf, size_t len)
-{
- const char *p;
-
-#ifndef CURL_DISABLE_VERBOSE_STRINGS
- switch (err) {
- case WSAEINTR:
- p = "Call interrupted.";
- break;
- case WSAEBADF:
- p = "Bad file";
- break;
- case WSAEACCES:
- p = "Bad access";
- break;
- case WSAEFAULT:
- p = "Bad argument";
- break;
- case WSAEINVAL:
- p = "Invalid arguments";
- break;
- case WSAEMFILE:
- p = "Out of file descriptors";
- break;
- case WSAEWOULDBLOCK:
- p = "Call would block";
- break;
- case WSAEINPROGRESS:
- case WSAEALREADY:
- p = "Blocking call in progress";
- break;
- case WSAENOTSOCK:
- p = "Descriptor is not a socket.";
- break;
- case WSAEDESTADDRREQ:
- p = "Need destination address";
- break;
- case WSAEMSGSIZE:
- p = "Bad message size";
- break;
- case WSAEPROTOTYPE:
- p = "Bad protocol";
- break;
- case WSAENOPROTOOPT:
- p = "Protocol option is unsupported";
- break;
- case WSAEPROTONOSUPPORT:
- p = "Protocol is unsupported";
- break;
- case WSAESOCKTNOSUPPORT:
- p = "Socket is unsupported";
- break;
- case WSAEOPNOTSUPP:
- p = "Operation not supported";
- break;
- case WSAEAFNOSUPPORT:
- p = "Address family not supported";
- break;
- case WSAEPFNOSUPPORT:
- p = "Protocol family not supported";
- break;
- case WSAEADDRINUSE:
- p = "Address already in use";
- break;
- case WSAEADDRNOTAVAIL:
- p = "Address not available";
- break;
- case WSAENETDOWN:
- p = "Network down";
- break;
- case WSAENETUNREACH:
- p = "Network unreachable";
- break;
- case WSAENETRESET:
- p = "Network has been reset";
- break;
- case WSAECONNABORTED:
- p = "Connection was aborted";
- break;
- case WSAECONNRESET:
- p = "Connection was reset";
- break;
- case WSAENOBUFS:
- p = "No buffer space";
- break;
- case WSAEISCONN:
- p = "Socket is already connected";
- break;
- case WSAENOTCONN:
- p = "Socket is not connected";
- break;
- case WSAESHUTDOWN:
- p = "Socket has been shut down";
- break;
- case WSAETOOMANYREFS:
- p = "Too many references";
- break;
- case WSAETIMEDOUT:
- p = "Timed out";
- break;
- case WSAECONNREFUSED:
- p = "Connection refused";
- break;
- case WSAELOOP:
- p = "Loop??";
- break;
- case WSAENAMETOOLONG:
- p = "Name too long";
- break;
- case WSAEHOSTDOWN:
- p = "Host down";
- break;
- case WSAEHOSTUNREACH:
- p = "Host unreachable";
- break;
- case WSAENOTEMPTY:
- p = "Not empty";
- break;
- case WSAEPROCLIM:
- p = "Process limit reached";
- break;
- case WSAEUSERS:
- p = "Too many users";
- break;
- case WSAEDQUOT:
- p = "Bad quota";
- break;
- case WSAESTALE:
- p = "Something is stale";
- break;
- case WSAEREMOTE:
- p = "Remote error";
- break;
-#ifdef WSAEDISCON /* missing in SalfordC! */
- case WSAEDISCON:
- p = "Disconnected";
- break;
-#endif
- /* Extended Winsock errors */
- case WSASYSNOTREADY:
- p = "Winsock library is not ready";
- break;
- case WSANOTINITIALISED:
- p = "Winsock library not initialised";
- break;
- case WSAVERNOTSUPPORTED:
- p = "Winsock version not supported.";
- break;
-
- /* getXbyY() errors (already handled in herrmsg):
- * Authoritative Answer: Host not found */
- case WSAHOST_NOT_FOUND:
- p = "Host not found";
- break;
-
- /* Non-Authoritative: Host not found, or SERVERFAIL */
- case WSATRY_AGAIN:
- p = "Host not found, try again";
- break;
-
- /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
- case WSANO_RECOVERY:
- p = "Unrecoverable error in call to nameserver";
- break;
-
- /* Valid name, no data record of requested type */
- case WSANO_DATA:
- p = "No data record of requested type";
- break;
-
- default:
- return NULL;
- }
-#else
- if (error == CURLE_OK)
- return NULL;
- else
- p = "error";
-#endif
- strncpy (buf, p, len);
- buf [len-1] = '\0';
- return buf;
-}
-#endif /* USE_WINSOCK */
-
-/*
- * Our thread-safe and smart strerror() replacement.
- *
- * The 'err' argument passed in to this function MUST be a true errno number
- * as reported on this system. We do no range checking on the number before
- * we pass it to the "number-to-message" convertion function and there might
- * be systems that don't do proper range checking in there themselves.
- *
- * We don't do range checking (on systems other than Windows) since there is
- * no good reliable and portable way to do it.
- */
-const char *Curl_strerror(struct connectdata *conn, int err)
-{
- char *buf, *p;
- size_t max;
-
- curlassert(conn);
- curlassert(err >= 0);
-
- buf = conn->syserr_buf;
- max = sizeof(conn->syserr_buf)-1;
- *buf = '\0';
-
-#ifdef USE_WINSOCK
-
-#ifdef _WIN32_WCE
- buf[0]=0;
- {
- wchar_t wbuf[256];
-
- FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
- LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL);
- wcstombs(buf,wbuf,max);
- }
-
-#else
-
- /* 'sys_nerr' is the maximum errno number, it is not widely portable */
- if (err >= 0 && err < sys_nerr)
- strncpy(buf, strerror(err), max);
- else {
- if (!get_winsock_error(err, buf, max) &&
- !FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
- LANG_NEUTRAL, buf, (DWORD)max, NULL))
- snprintf(buf, max, "Unknown error %d (%#x)", err, err);
- }
-#endif
-#else /* not USE_WINSOCK coming up */
-
- /* These should be atomic and hopefully thread-safe */
-#ifdef HAVE_STRERROR_R
- /* There are two different APIs for strerror_r(). The POSIX and the GLIBC
- versions. */
-#ifdef HAVE_POSIX_STRERROR_R
- strerror_r(err, buf, max);
- /* this may set errno to ERANGE if insufficient storage was supplied via
- 'strerrbuf' and 'buflen' to contain the generated message string, or
- EINVAL if the value of 'errnum' is not a valid error number.*/
-#else
- {
- /* HAVE_GLIBC_STRERROR_R */
- char buffer[256];
- char *msg = strerror_r(err, buffer, sizeof(buffer));
- /* this version of strerror_r() only *might* use the buffer we pass to
- the function, but it always returns the error message as a pointer,
- so we must copy that string unconditionally (if non-NULL) */
- if(msg)
- strncpy(buf, msg, max);
- else
- snprintf(buf, max, "Unknown error %d", err);
- }
-#endif /* end of HAVE_GLIBC_STRERROR_R */
-#else /* HAVE_STRERROR_R */
- strncpy(buf, strerror(err), max);
-#endif /* end of HAVE_STRERROR_R */
-#endif /* end of ! USE_WINSOCK */
-
- buf[max] = '\0'; /* make sure the string is zero terminated */
-
- /* strip trailing '\r\n' or '\n'. */
- if ((p = strrchr(buf,'\n')) != NULL && (p - buf) >= 2)
- *p = '\0';
- if ((p = strrchr(buf,'\r')) != NULL && (p - buf) >= 1)
- *p = '\0';
- return buf;
-}
-
-#ifdef USE_LIBIDN
-/*
- * Return error-string for libidn status as returned from idna_to_ascii_lz().
- */
-const char *Curl_idn_strerror (struct connectdata *conn, int err)
-{
-#ifdef HAVE_IDNA_STRERROR
- (void)conn;
- return idna_strerror((Idna_rc) err);
-#else
- const char *str;
- char *buf;
- size_t max;
-
- curlassert(conn);
-
- buf = conn->syserr_buf;
- max = sizeof(conn->syserr_buf)-1;
-
-#ifndef CURL_DISABLE_VERBOSE_STRINGS
- switch ((Idna_rc)err) {
- case IDNA_SUCCESS:
- str = "No error";
- break;
- case IDNA_STRINGPREP_ERROR:
- str = "Error in string preparation";
- break;
- case IDNA_PUNYCODE_ERROR:
- str = "Error in Punycode operation";
- break;
- case IDNA_CONTAINS_NON_LDH:
- str = "Illegal ASCII characters";
- break;
- case IDNA_CONTAINS_MINUS:
- str = "Contains minus";
- break;
- case IDNA_INVALID_LENGTH:
- str = "Invalid output length";
- break;
- case IDNA_NO_ACE_PREFIX:
- str = "No ACE prefix (\"xn--\")";
- break;
- case IDNA_ROUNDTRIP_VERIFY_ERROR:
- str = "Roundtrip verify error";
- break;
- case IDNA_CONTAINS_ACE_PREFIX:
- str = "Already have ACE prefix (\"xn--\")";
- break;
- case IDNA_ICONV_ERROR:
- str = "Locale conversion failed";
- break;
- case IDNA_MALLOC_ERROR:
- str = "Allocation failed";
- break;
- case IDNA_DLOPEN_ERROR:
- str = "dlopen() error";
- break;
- default:
- snprintf(buf, max, "error %d", (int)err);
- str = NULL;
- break;
- }
-#else
- if ((Idna_rc)err == IDNA_SUCCESS)
- str = "No error";
- else
- str = "error";
-#endif
- if (str)
- strncpy(buf, str, max);
- buf[max] = '\0';
- return (buf);
-#endif
-}
-#endif /* USE_LIBIDN */
diff --git a/Utilities/cmcurl/strerror.h b/Utilities/cmcurl/strerror.h
deleted file mode 100644
index b28050437..000000000
--- a/Utilities/cmcurl/strerror.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef __CURL_STRERROR_H
-#define __CURL_STRERROR_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "urldata.h"
-
-const char *Curl_strerror (struct connectdata *conn, int err);
-
-#ifdef USE_LIBIDN
-const char *Curl_idn_strerror (struct connectdata *conn, int err);
-#endif
-
-#endif
diff --git a/Utilities/cmcurl/strtok.c b/Utilities/cmcurl/strtok.c
deleted file mode 100644
index 630e4e029..000000000
--- a/Utilities/cmcurl/strtok.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#ifndef HAVE_STRTOK_R
-#include <stddef.h>
-#include <string.h>
-
-#include "strtok.h"
-
-char *
-Curl_strtok_r(char *ptr, const char *sep, char **end)
-{
- if (!ptr)
- /* we got NULL input so then we get our last position instead */
- ptr = *end;
-
- /* pass all letters that are including in the separator string */
- while (*ptr && strchr(sep, *ptr))
- ++ptr;
-
- if (*ptr) {
- /* so this is where the next piece of string starts */
- char *start = ptr;
-
- /* set the end pointer to the first byte after the start */
- *end = start + 1;
-
- /* scan through the string to find where it ends, it ends on a
- null byte or a character that exists in the separator string */
- while (**end && !strchr(sep, **end))
- ++*end;
-
- if (**end) {
- /* the end is not a null byte */
- **end = '\0'; /* zero terminate it! */
- ++*end; /* advance the last pointer to beyond the null byte */
- }
-
- return start; /* return the position where the string starts */
- }
-
- /* we ended up on a null byte, there are no more strings to find! */
- return NULL;
-}
-
-#endif /* this was only compiled if strtok_r wasn't present */
diff --git a/Utilities/cmcurl/strtok.h b/Utilities/cmcurl/strtok.h
deleted file mode 100644
index cf9fac8c7..000000000
--- a/Utilities/cmcurl/strtok.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#ifndef _CURL_STRTOK_R_H
-#define _CURL_STRTOK_R_H
-
-#include "setup.h"
-#include <stddef.h>
-
-#ifndef HAVE_STRTOK_R
-char *Curl_strtok_r(char *s, const char *delim, char **last);
-#define strtok_r Curl_strtok_r
-#else
-#include <string.h>
-#endif
-
-#endif
-
diff --git a/Utilities/cmcurl/strtoofft.c b/Utilities/cmcurl/strtoofft.c
deleted file mode 100644
index 3ab1bfdff..000000000
--- a/Utilities/cmcurl/strtoofft.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-#include "strtoofft.h"
-
-/*
- * NOTE:
- *
- * In the ISO C standard (IEEE Std 1003.1), there is a strtoimax() function we
- * could use in case strtoll() doesn't exist... See
- * http://www.opengroup.org/onlinepubs/009695399/functions/strtoimax.html
- */
-
-#ifdef NEED_CURL_STRTOLL
-#include <stdlib.h>
-#include <ctype.h>
-#include <errno.h>
-
-static int get_char(char c, int base);
-
-/**
- * Emulated version of the strtoll function. This extracts a long long
- * value from the given input string and returns it.
- */
-curl_off_t
-curlx_strtoll(const char *nptr, char **endptr, int base)
-{
- char *end;
- int is_negative = 0;
- int overflow;
- int i;
- curl_off_t value = 0;
- curl_off_t newval;
-
- /* Skip leading whitespace. */
- end = (char *)nptr;
- while (ISSPACE(end[0])) {
- end++;
- }
-
- /* Handle the sign, if any. */
- if (end[0] == '-') {
- is_negative = 1;
- end++;
- }
- else if (end[0] == '+') {
- end++;
- }
- else if (end[0] == '\0') {
- /* We had nothing but perhaps some whitespace -- there was no number. */
- if (endptr) {
- *endptr = end;
- }
- return 0;
- }
-
- /* Handle special beginnings, if present and allowed. */
- if (end[0] == '0' && end[1] == 'x') {
- if (base == 16 || base == 0) {
- end += 2;
- base = 16;
- }
- }
- else if (end[0] == '0') {
- if (base == 8 || base == 0) {
- end++;
- base = 8;
- }
- }
-
- /* Matching strtol, if the base is 0 and it doesn't look like
- * the number is octal or hex, we assume it's base 10.
- */
- if (base == 0) {
- base = 10;
- }
-
- /* Loop handling digits. */
- value = 0;
- overflow = 0;
- for (i = get_char(end[0], base);
- i != -1;
- end++, i = get_char(end[0], base)) {
- newval = base * value + i;
- if (newval < value) {
- /* We've overflowed. */
- overflow = 1;
- break;
- }
- else
- value = newval;
- }
-
- if (!overflow) {
- if (is_negative) {
- /* Fix the sign. */
- value *= -1;
- }
- }
- else {
- if (is_negative)
- value = CURL_LLONG_MIN;
- else
- value = CURL_LLONG_MAX;
-
- errno = ERANGE;
- }
-
- if (endptr)
- *endptr = end;
-
- return value;
-}
-
-/**
- * Returns the value of c in the given base, or -1 if c cannot
- * be interpreted properly in that base (i.e., is out of range,
- * is a null, etc.).
- *
- * @param c the character to interpret according to base
- * @param base the base in which to interpret c
- *
- * @return the value of c in base, or -1 if c isn't in range
- */
-static int get_char(char c, int base)
-{
- int value = -1;
- if (c <= '9' && c >= '0') {
- value = c - '0';
- }
- else if (c <= 'Z' && c >= 'A') {
- value = c - 'A' + 10;
- }
- else if (c <= 'z' && c >= 'a') {
- value = c - 'a' + 10;
- }
-
- if (value >= base) {
- value = -1;
- }
-
- return value;
-}
-#endif /* Only present if we need strtoll, but don't have it. */
diff --git a/Utilities/cmcurl/strtoofft.h b/Utilities/cmcurl/strtoofft.h
deleted file mode 100644
index e27b43261..000000000
--- a/Utilities/cmcurl/strtoofft.h
+++ /dev/null
@@ -1,73 +0,0 @@
-#ifndef _CURL_STRTOOFFT_H
-#define _CURL_STRTOOFFT_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-/*
- * CAUTION: this header is designed to work when included by the app-side
- * as well as the library. Do not mix with library internals!
- */
-
-#include "setup.h"
-#include <stddef.h>
-#include <curl/curl.h> /* for the curl_off_t type */
-
-/* Determine what type of file offset conversion handling we wish to use. For
- * systems with a 32-bit curl_off_t type, we should use strtol. For systems
- * with a 64-bit curl_off_t type, we should use strtoll if it exists, and if
- * not, should try to emulate its functionality. At any rate, we define
- * 'strtoofft' such that it can be used to work with curl_off_t's regardless.
- */
-#if (SIZEOF_CURL_OFF_T > 4) && (SIZEOF_LONG < 8)
-#if HAVE_STRTOLL
-#define curlx_strtoofft strtoll
-#else /* HAVE_STRTOLL */
-
-/* For MSVC7 we can use _strtoi64() which seems to be a strtoll() clone */
-#if defined(_MSC_VER) && (_MSC_VER >= 1300)
-#define curlx_strtoofft _strtoi64
-#else /* MSVC7 or later */
-curl_off_t curlx_strtoll(const char *nptr, char **endptr, int base);
-#define curlx_strtoofft curlx_strtoll
-#define NEED_CURL_STRTOLL
-#endif /* MSVC7 or later */
-
-#endif /* HAVE_STRTOLL */
-#else /* (SIZEOF_CURL_OFF_T > 4) && (SIZEOF_LONG < 8) */
-/* simply use strtol() to get numbers, either 32 or 64 bit */
-#define curlx_strtoofft strtol
-#endif
-
-#if defined(_MSC_VER) || defined(__WATCOMC__)
-#define CURL_LLONG_MIN 0x8000000000000000i64
-#define CURL_LLONG_MAX 0x7FFFFFFFFFFFFFFFi64
-#elif defined(HAVE_LL)
-#define CURL_LLONG_MIN 0x8000000000000000LL
-#define CURL_LLONG_MAX 0x7FFFFFFFFFFFFFFFLL
-#else
-#define CURL_LLONG_MIN 0x8000000000000000L
-#define CURL_LLONG_MAX 0x7FFFFFFFFFFFFFFFL
-#endif
-
-#endif
-
diff --git a/Utilities/cmcurl/telnet.c b/Utilities/cmcurl/telnet.c
deleted file mode 100644
index 97d22b788..000000000
--- a/Utilities/cmcurl/telnet.c
+++ /dev/null
@@ -1,1403 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#ifndef CURL_DISABLE_TELNET
-/* -- WIN32 approved -- */
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <ctype.h>
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-
-#if defined(WIN32)
-#include <time.h>
-#include <io.h>
-#else
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#include <netinet/in.h>
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <netdb.h>
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_NET_IF_H
-#include <net/if.h>
-#endif
-#include <sys/ioctl.h>
-#include <signal.h>
-
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
-
-#endif
-
-#include "urldata.h"
-#include <curl/curl.h>
-#include "transfer.h"
-#include "sendf.h"
-#include "telnet.h"
-#include "connect.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-#define TELOPTS
-#define TELCMDS
-
-#include "arpa_telnet.h"
-#include "memory.h"
-#include "select.h"
-
-/* The last #include file should be: */
-#include "memdebug.h"
-
-#define SUBBUFSIZE 512
-
-#define CURL_SB_CLEAR(x) x->subpointer = x->subbuffer;
-#define CURL_SB_TERM(x) { x->subend = x->subpointer; CURL_SB_CLEAR(x); }
-#define CURL_SB_ACCUM(x,c) \
- if (x->subpointer < (x->subbuffer+sizeof x->subbuffer)) { \
- *x->subpointer++ = (c); \
- }
-
-#define CURL_SB_GET(x) ((*x->subpointer++)&0xff)
-#define CURL_SB_PEEK(x) ((*x->subpointer)&0xff)
-#define CURL_SB_EOF(x) (x->subpointer >= x->subend)
-#define CURL_SB_LEN(x) (x->subend - x->subpointer)
-
-#ifdef USE_WINSOCK
-typedef FARPROC WSOCK2_FUNC;
-static CURLcode check_wsock2 ( struct SessionHandle *data );
-#endif
-
-static
-void telrcv(struct connectdata *,
- unsigned char *inbuf, /* Data received from socket */
- ssize_t count); /* Number of bytes received */
-
-static void printoption(struct SessionHandle *data,
- const char *direction,
- int cmd, int option);
-
-static void negotiate(struct connectdata *);
-static void send_negotiation(struct connectdata *, int cmd, int option);
-static void set_local_option(struct connectdata *, int cmd, int option);
-static void set_remote_option(struct connectdata *, int cmd, int option);
-
-static void printsub(struct SessionHandle *data,
- int direction, unsigned char *pointer,
- size_t length);
-static void suboption(struct connectdata *);
-
-/* For negotiation compliant to RFC 1143 */
-#define CURL_NO 0
-#define CURL_YES 1
-#define CURL_WANTYES 2
-#define CURL_WANTNO 3
-
-#define CURL_EMPTY 0
-#define CURL_OPPOSITE 1
-
-/*
- * Telnet receiver states for fsm
- */
-typedef enum
-{
- CURL_TS_DATA = 0,
- CURL_TS_IAC,
- CURL_TS_WILL,
- CURL_TS_WONT,
- CURL_TS_DO,
- CURL_TS_DONT,
- CURL_TS_CR,
- CURL_TS_SB, /* sub-option collection */
- CURL_TS_SE /* looking for sub-option end */
-} TelnetReceive;
-
-struct TELNET {
- int please_negotiate;
- int already_negotiated;
- int us[256];
- int usq[256];
- int us_preferred[256];
- int him[256];
- int himq[256];
- int him_preferred[256];
- char subopt_ttype[32]; /* Set with suboption TTYPE */
- char subopt_xdisploc[128]; /* Set with suboption XDISPLOC */
- struct curl_slist *telnet_vars; /* Environment variables */
-
- /* suboptions */
- unsigned char subbuffer[SUBBUFSIZE];
- unsigned char *subpointer, *subend; /* buffer for sub-options */
-
- TelnetReceive telrcv_state;
-};
-
-#ifdef USE_WINSOCK
-static CURLcode
-check_wsock2 ( struct SessionHandle *data )
-{
- int err;
- WORD wVersionRequested;
- WSADATA wsaData;
-
- curlassert(data);
-
- /* telnet requires at least WinSock 2.0 so ask for it. */
- wVersionRequested = MAKEWORD(2, 0);
-
- err = WSAStartup(wVersionRequested, &wsaData);
-
- /* We must've called this once already, so this call */
- /* should always succeed. But, just in case... */
- if (err != 0) {
- failf(data,"WSAStartup failed (%d)",err);
- return CURLE_FAILED_INIT;
- }
-
- /* We have to have a WSACleanup call for every successful */
- /* WSAStartup call. */
- WSACleanup();
-
- /* Check that our version is supported */
- if (LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) ||
- HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested)) {
- /* Our version isn't supported */
- failf(data,"insufficient winsock version to support "
- "telnet");
- return CURLE_FAILED_INIT;
- }
-
- /* Our version is supported */
- return CURLE_OK;
-}
-#endif
-
-static
-CURLcode init_telnet(struct connectdata *conn)
-{
- struct TELNET *tn;
-
- tn = (struct TELNET *)calloc(1, sizeof(struct TELNET));
- if(!tn)
- return CURLE_OUT_OF_MEMORY;
-
- conn->data->reqdata.proto.telnet = (void *)tn; /* make us known */
-
- tn->telrcv_state = CURL_TS_DATA;
-
- /* Init suboptions */
- CURL_SB_CLEAR(tn);
-
- /* Set the options we want by default */
- tn->us_preferred[CURL_TELOPT_BINARY] = CURL_YES;
- tn->us_preferred[CURL_TELOPT_SGA] = CURL_YES;
- tn->him_preferred[CURL_TELOPT_BINARY] = CURL_YES;
- tn->him_preferred[CURL_TELOPT_SGA] = CURL_YES;
-
- return CURLE_OK;
-}
-
-static void negotiate(struct connectdata *conn)
-{
- int i;
- struct TELNET *tn = (struct TELNET *) conn->data->reqdata.proto.telnet;
-
- for(i = 0;i < CURL_NTELOPTS;i++)
- {
- if(tn->us_preferred[i] == CURL_YES)
- set_local_option(conn, i, CURL_YES);
-
- if(tn->him_preferred[i] == CURL_YES)
- set_remote_option(conn, i, CURL_YES);
- }
-}
-
-static void printoption(struct SessionHandle *data,
- const char *direction, int cmd, int option)
-{
- const char *fmt;
- const char *opt;
-
- if (data->set.verbose)
- {
- if (cmd == CURL_IAC)
- {
- if (CURL_TELCMD_OK(option))
- infof(data, "%s IAC %s\n", direction, CURL_TELCMD(option));
- else
- infof(data, "%s IAC %d\n", direction, option);
- }
- else
- {
- fmt = (cmd == CURL_WILL) ? "WILL" : (cmd == CURL_WONT) ? "WONT" :
- (cmd == CURL_DO) ? "DO" : (cmd == CURL_DONT) ? "DONT" : 0;
- if (fmt)
- {
- if (CURL_TELOPT_OK(option))
- opt = CURL_TELOPT(option);
- else if (option == CURL_TELOPT_EXOPL)
- opt = "EXOPL";
- else
- opt = NULL;
-
- if(opt)
- infof(data, "%s %s %s\n", direction, fmt, opt);
- else
- infof(data, "%s %s %d\n", direction, fmt, option);
- }
- else
- infof(data, "%s %d %d\n", direction, cmd, option);
- }
- }
-}
-
-static void send_negotiation(struct connectdata *conn, int cmd, int option)
-{
- unsigned char buf[3];
- ssize_t bytes_written;
- int err;
- struct SessionHandle *data = conn->data;
-
- buf[0] = CURL_IAC;
- buf[1] = (unsigned char)cmd;
- buf[2] = (unsigned char)option;
-
- bytes_written = swrite(conn->sock[FIRSTSOCKET], buf, 3);
- if(bytes_written < 0) {
- err = Curl_sockerrno();
- failf(data,"Sending data failed (%d)",err);
- }
-
- printoption(conn->data, "SENT", cmd, option);
-}
-
-static
-void set_remote_option(struct connectdata *conn, int option, int newstate)
-{
- struct TELNET *tn = (struct TELNET *)conn->data->reqdata.proto.telnet;
- if(newstate == CURL_YES)
- {
- switch(tn->him[option])
- {
- case CURL_NO:
- tn->him[option] = CURL_WANTYES;
- send_negotiation(conn, CURL_DO, option);
- break;
-
- case CURL_YES:
- /* Already enabled */
- break;
-
- case CURL_WANTNO:
- switch(tn->himq[option])
- {
- case CURL_EMPTY:
- /* Already negotiating for CURL_YES, queue the request */
- tn->himq[option] = CURL_OPPOSITE;
- break;
- case CURL_OPPOSITE:
- /* Error: already queued an enable request */
- break;
- }
- break;
-
- case CURL_WANTYES:
- switch(tn->himq[option])
- {
- case CURL_EMPTY:
- /* Error: already negotiating for enable */
- break;
- case CURL_OPPOSITE:
- tn->himq[option] = CURL_EMPTY;
- break;
- }
- break;
- }
- }
- else /* NO */
- {
- switch(tn->him[option])
- {
- case CURL_NO:
- /* Already disabled */
- break;
-
- case CURL_YES:
- tn->him[option] = CURL_WANTNO;
- send_negotiation(conn, CURL_DONT, option);
- break;
-
- case CURL_WANTNO:
- switch(tn->himq[option])
- {
- case CURL_EMPTY:
- /* Already negotiating for NO */
- break;
- case CURL_OPPOSITE:
- tn->himq[option] = CURL_EMPTY;
- break;
- }
- break;
-
- case CURL_WANTYES:
- switch(tn->himq[option])
- {
- case CURL_EMPTY:
- tn->himq[option] = CURL_OPPOSITE;
- break;
- case CURL_OPPOSITE:
- break;
- }
- break;
- }
- }
-}
-
-static
-void rec_will(struct connectdata *conn, int option)
-{
- struct TELNET *tn = (struct TELNET *)conn->data->reqdata.proto.telnet;
- switch(tn->him[option])
- {
- case CURL_NO:
- if(tn->him_preferred[option] == CURL_YES)
- {
- tn->him[option] = CURL_YES;
- send_negotiation(conn, CURL_DO, option);
- }
- else
- {
- send_negotiation(conn, CURL_DONT, option);
- }
- break;
-
- case CURL_YES:
- /* Already enabled */
- break;
-
- case CURL_WANTNO:
- switch(tn->himq[option])
- {
- case CURL_EMPTY:
- /* Error: DONT answered by WILL */
- tn->him[option] = CURL_NO;
- break;
- case CURL_OPPOSITE:
- /* Error: DONT answered by WILL */
- tn->him[option] = CURL_YES;
- tn->himq[option] = CURL_EMPTY;
- break;
- }
- break;
-
- case CURL_WANTYES:
- switch(tn->himq[option])
- {
- case CURL_EMPTY:
- tn->him[option] = CURL_YES;
- break;
- case CURL_OPPOSITE:
- tn->him[option] = CURL_WANTNO;
- tn->himq[option] = CURL_EMPTY;
- send_negotiation(conn, CURL_DONT, option);
- break;
- }
- break;
- }
-}
-
-static
-void rec_wont(struct connectdata *conn, int option)
-{
- struct TELNET *tn = (struct TELNET *)conn->data->reqdata.proto.telnet;
- switch(tn->him[option])
- {
- case CURL_NO:
- /* Already disabled */
- break;
-
- case CURL_YES:
- tn->him[option] = CURL_NO;
- send_negotiation(conn, CURL_DONT, option);
- break;
-
- case CURL_WANTNO:
- switch(tn->himq[option])
- {
- case CURL_EMPTY:
- tn->him[option] = CURL_NO;
- break;
-
- case CURL_OPPOSITE:
- tn->him[option] = CURL_WANTYES;
- tn->himq[option] = CURL_EMPTY;
- send_negotiation(conn, CURL_DO, option);
- break;
- }
- break;
-
- case CURL_WANTYES:
- switch(tn->himq[option])
- {
- case CURL_EMPTY:
- tn->him[option] = CURL_NO;
- break;
- case CURL_OPPOSITE:
- tn->him[option] = CURL_NO;
- tn->himq[option] = CURL_EMPTY;
- break;
- }
- break;
- }
-}
-
-static void
-set_local_option(struct connectdata *conn, int option, int newstate)
-{
- struct TELNET *tn = (struct TELNET *)conn->data->reqdata.proto.telnet;
- if(newstate == CURL_YES)
- {
- switch(tn->us[option])
- {
- case CURL_NO:
- tn->us[option] = CURL_WANTYES;
- send_negotiation(conn, CURL_WILL, option);
- break;
-
- case CURL_YES:
- /* Already enabled */
- break;
-
- case CURL_WANTNO:
- switch(tn->usq[option])
- {
- case CURL_EMPTY:
- /* Already negotiating for CURL_YES, queue the request */
- tn->usq[option] = CURL_OPPOSITE;
- break;
- case CURL_OPPOSITE:
- /* Error: already queued an enable request */
- break;
- }
- break;
-
- case CURL_WANTYES:
- switch(tn->usq[option])
- {
- case CURL_EMPTY:
- /* Error: already negotiating for enable */
- break;
- case CURL_OPPOSITE:
- tn->usq[option] = CURL_EMPTY;
- break;
- }
- break;
- }
- }
- else /* NO */
- {
- switch(tn->us[option])
- {
- case CURL_NO:
- /* Already disabled */
- break;
-
- case CURL_YES:
- tn->us[option] = CURL_WANTNO;
- send_negotiation(conn, CURL_WONT, option);
- break;
-
- case CURL_WANTNO:
- switch(tn->usq[option])
- {
- case CURL_EMPTY:
- /* Already negotiating for NO */
- break;
- case CURL_OPPOSITE:
- tn->usq[option] = CURL_EMPTY;
- break;
- }
- break;
-
- case CURL_WANTYES:
- switch(tn->usq[option])
- {
- case CURL_EMPTY:
- tn->usq[option] = CURL_OPPOSITE;
- break;
- case CURL_OPPOSITE:
- break;
- }
- break;
- }
- }
-}
-
-static
-void rec_do(struct connectdata *conn, int option)
-{
- struct TELNET *tn = (struct TELNET *)conn->data->reqdata.proto.telnet;
- switch(tn->us[option])
- {
- case CURL_NO:
- if(tn->us_preferred[option] == CURL_YES)
- {
- tn->us[option] = CURL_YES;
- send_negotiation(conn, CURL_WILL, option);
- }
- else
- {
- send_negotiation(conn, CURL_WONT, option);
- }
- break;
-
- case CURL_YES:
- /* Already enabled */
- break;
-
- case CURL_WANTNO:
- switch(tn->usq[option])
- {
- case CURL_EMPTY:
- /* Error: DONT answered by WILL */
- tn->us[option] = CURL_NO;
- break;
- case CURL_OPPOSITE:
- /* Error: DONT answered by WILL */
- tn->us[option] = CURL_YES;
- tn->usq[option] = CURL_EMPTY;
- break;
- }
- break;
-
- case CURL_WANTYES:
- switch(tn->usq[option])
- {
- case CURL_EMPTY:
- tn->us[option] = CURL_YES;
- break;
- case CURL_OPPOSITE:
- tn->us[option] = CURL_WANTNO;
- tn->himq[option] = CURL_EMPTY;
- send_negotiation(conn, CURL_WONT, option);
- break;
- }
- break;
- }
-}
-
-static
-void rec_dont(struct connectdata *conn, int option)
-{
- struct TELNET *tn = (struct TELNET *)conn->data->reqdata.proto.telnet;
- switch(tn->us[option])
- {
- case CURL_NO:
- /* Already disabled */
- break;
-
- case CURL_YES:
- tn->us[option] = CURL_NO;
- send_negotiation(conn, CURL_WONT, option);
- break;
-
- case CURL_WANTNO:
- switch(tn->usq[option])
- {
- case CURL_EMPTY:
- tn->us[option] = CURL_NO;
- break;
-
- case CURL_OPPOSITE:
- tn->us[option] = CURL_WANTYES;
- tn->usq[option] = CURL_EMPTY;
- send_negotiation(conn, CURL_WILL, option);
- break;
- }
- break;
-
- case CURL_WANTYES:
- switch(tn->usq[option])
- {
- case CURL_EMPTY:
- tn->us[option] = CURL_NO;
- break;
- case CURL_OPPOSITE:
- tn->us[option] = CURL_NO;
- tn->usq[option] = CURL_EMPTY;
- break;
- }
- break;
- }
-}
-
-
-static void printsub(struct SessionHandle *data,
- int direction, /* '<' or '>' */
- unsigned char *pointer, /* where suboption data is */
- size_t length) /* length of suboption data */
-{
- unsigned int i = 0;
-
- if (data->set.verbose)
- {
- if (direction)
- {
- infof(data, "%s IAC SB ", (direction == '<')? "RCVD":"SENT");
- if (length >= 3)
- {
- int j;
-
- i = pointer[length-2];
- j = pointer[length-1];
-
- if (i != CURL_IAC || j != CURL_SE)
- {
- infof(data, "(terminated by ");
- if (CURL_TELOPT_OK(i))
- infof(data, "%s ", CURL_TELOPT(i));
- else if (CURL_TELCMD_OK(i))
- infof(data, "%s ", CURL_TELCMD(i));
- else
- infof(data, "%d ", i);
- if (CURL_TELOPT_OK(j))
- infof(data, "%s", CURL_TELOPT(j));
- else if (CURL_TELCMD_OK(j))
- infof(data, "%s", CURL_TELCMD(j));
- else
- infof(data, "%d", j);
- infof(data, ", not IAC SE!) ");
- }
- }
- length -= 2;
- }
- if (length < 1)
- {
- infof(data, "(Empty suboption?)");
- return;
- }
-
- if (CURL_TELOPT_OK(pointer[0])) {
- switch(pointer[0]) {
- case CURL_TELOPT_TTYPE:
- case CURL_TELOPT_XDISPLOC:
- case CURL_TELOPT_NEW_ENVIRON:
- infof(data, "%s", CURL_TELOPT(pointer[0]));
- break;
- default:
- infof(data, "%s (unsupported)", CURL_TELOPT(pointer[0]));
- break;
- }
- }
- else
- infof(data, "%d (unknown)", pointer[i]);
-
- switch(pointer[1]) {
- case CURL_TELQUAL_IS:
- infof(data, " IS");
- break;
- case CURL_TELQUAL_SEND:
- infof(data, " SEND");
- break;
- case CURL_TELQUAL_INFO:
- infof(data, " INFO/REPLY");
- break;
- case CURL_TELQUAL_NAME:
- infof(data, " NAME");
- break;
- }
-
- switch(pointer[0]) {
- case CURL_TELOPT_TTYPE:
- case CURL_TELOPT_XDISPLOC:
- pointer[length] = 0;
- infof(data, " \"%s\"", &pointer[2]);
- break;
- case CURL_TELOPT_NEW_ENVIRON:
- if(pointer[1] == CURL_TELQUAL_IS) {
- infof(data, " ");
- for(i = 3;i < length;i++) {
- switch(pointer[i]) {
- case CURL_NEW_ENV_VAR:
- infof(data, ", ");
- break;
- case CURL_NEW_ENV_VALUE:
- infof(data, " = ");
- break;
- default:
- infof(data, "%c", pointer[i]);
- break;
- }
- }
- }
- break;
- default:
- for (i = 2; i < length; i++)
- infof(data, " %.2x", pointer[i]);
- break;
- }
-
- if (direction)
- {
- infof(data, "\n");
- }
- }
-}
-
-static CURLcode check_telnet_options(struct connectdata *conn)
-{
- struct curl_slist *head;
- char option_keyword[128];
- char option_arg[256];
- char *buf;
- struct SessionHandle *data = conn->data;
- struct TELNET *tn = (struct TELNET *)conn->data->reqdata.proto.telnet;
-
- /* Add the user name as an environment variable if it
- was given on the command line */
- if(conn->bits.user_passwd)
- {
- snprintf(option_arg, sizeof(option_arg), "USER,%s", conn->user);
- tn->telnet_vars = curl_slist_append(tn->telnet_vars, option_arg);
-
- tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES;
- }
-
- for(head = data->set.telnet_options; head; head=head->next) {
- if(sscanf(head->data, "%127[^= ]%*[ =]%255s",
- option_keyword, option_arg) == 2) {
-
- /* Terminal type */
- if(curl_strequal(option_keyword, "TTYPE")) {
- strncpy(tn->subopt_ttype, option_arg, 31);
- tn->subopt_ttype[31] = 0; /* String termination */
- tn->us_preferred[CURL_TELOPT_TTYPE] = CURL_YES;
- continue;
- }
-
- /* Display variable */
- if(curl_strequal(option_keyword, "XDISPLOC")) {
- strncpy(tn->subopt_xdisploc, option_arg, 127);
- tn->subopt_xdisploc[127] = 0; /* String termination */
- tn->us_preferred[CURL_TELOPT_XDISPLOC] = CURL_YES;
- continue;
- }
-
- /* Environment variable */
- if(curl_strequal(option_keyword, "NEW_ENV")) {
- buf = strdup(option_arg);
- if(!buf)
- return CURLE_OUT_OF_MEMORY;
- tn->telnet_vars = curl_slist_append(tn->telnet_vars, buf);
- tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES;
- continue;
- }
-
- failf(data, "Unknown telnet option %s", head->data);
- return CURLE_UNKNOWN_TELNET_OPTION;
- } else {
- failf(data, "Syntax error in telnet option: %s", head->data);
- return CURLE_TELNET_OPTION_SYNTAX;
- }
- }
-
- return CURLE_OK;
-}
-
-/*
- * suboption()
- *
- * Look at the sub-option buffer, and try to be helpful to the other
- * side.
- */
-
-static void suboption(struct connectdata *conn)
-{
- struct curl_slist *v;
- unsigned char temp[2048];
- ssize_t bytes_written;
- size_t len;
- size_t tmplen;
- int err;
- char varname[128];
- char varval[128];
- struct SessionHandle *data = conn->data;
- struct TELNET *tn = (struct TELNET *)data->reqdata.proto.telnet;
-
- printsub(data, '<', (unsigned char *)tn->subbuffer, CURL_SB_LEN(tn)+2);
- switch (CURL_SB_GET(tn)) {
- case CURL_TELOPT_TTYPE:
- len = strlen(tn->subopt_ttype) + 4 + 2;
- snprintf((char *)temp, sizeof(temp),
- "%c%c%c%c%s%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_TTYPE,
- CURL_TELQUAL_IS, tn->subopt_ttype, CURL_IAC, CURL_SE);
- bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len);
- if(bytes_written < 0) {
- err = Curl_sockerrno();
- failf(data,"Sending data failed (%d)",err);
- }
- printsub(data, '>', &temp[2], len-2);
- break;
- case CURL_TELOPT_XDISPLOC:
- len = strlen(tn->subopt_xdisploc) + 4 + 2;
- snprintf((char *)temp, sizeof(temp),
- "%c%c%c%c%s%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_XDISPLOC,
- CURL_TELQUAL_IS, tn->subopt_xdisploc, CURL_IAC, CURL_SE);
- bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len);
- if(bytes_written < 0) {
- err = Curl_sockerrno();
- failf(data,"Sending data failed (%d)",err);
- }
- printsub(data, '>', &temp[2], len-2);
- break;
- case CURL_TELOPT_NEW_ENVIRON:
- snprintf((char *)temp, sizeof(temp),
- "%c%c%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_NEW_ENVIRON,
- CURL_TELQUAL_IS);
- len = 4;
-
- for(v = tn->telnet_vars;v;v = v->next) {
- tmplen = (strlen(v->data) + 1);
- /* Add the variable only if it fits */
- if(len + tmplen < (int)sizeof(temp)-6) {
- sscanf(v->data, "%127[^,],%127s", varname, varval);
- snprintf((char *)&temp[len], sizeof(temp) - len,
- "%c%s%c%s", CURL_NEW_ENV_VAR, varname,
- CURL_NEW_ENV_VALUE, varval);
- len += tmplen;
- }
- }
- snprintf((char *)&temp[len], sizeof(temp) - len,
- "%c%c", CURL_IAC, CURL_SE);
- len += 2;
- bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len);
- if(bytes_written < 0) {
- err = Curl_sockerrno();
- failf(data,"Sending data failed (%d)",err);
- }
- printsub(data, '>', &temp[2], len-2);
- break;
- }
- return;
-}
-
-static
-void telrcv(struct connectdata *conn,
- unsigned char *inbuf, /* Data received from socket */
- ssize_t count) /* Number of bytes received */
-{
- unsigned char c;
- int in = 0;
- struct SessionHandle *data = conn->data;
- struct TELNET *tn = (struct TELNET *)data->reqdata.proto.telnet;
-
- while(count--)
- {
- c = inbuf[in++];
-
- switch (tn->telrcv_state)
- {
- case CURL_TS_CR:
- tn->telrcv_state = CURL_TS_DATA;
- if (c == '\0')
- {
- break; /* Ignore \0 after CR */
- }
-
- Curl_client_write(conn, CLIENTWRITE_BODY, (char *)&c, 1);
- continue;
-
- case CURL_TS_DATA:
- if (c == CURL_IAC)
- {
- tn->telrcv_state = CURL_TS_IAC;
- break;
- }
- else if(c == '\r')
- {
- tn->telrcv_state = CURL_TS_CR;
- }
-
- Curl_client_write(conn, CLIENTWRITE_BODY, (char *)&c, 1);
- continue;
-
- case CURL_TS_IAC:
- process_iac:
- switch (c)
- {
- case CURL_WILL:
- tn->telrcv_state = CURL_TS_WILL;
- continue;
- case CURL_WONT:
- tn->telrcv_state = CURL_TS_WONT;
- continue;
- case CURL_DO:
- tn->telrcv_state = CURL_TS_DO;
- continue;
- case CURL_DONT:
- tn->telrcv_state = CURL_TS_DONT;
- continue;
- case CURL_SB:
- CURL_SB_CLEAR(tn);
- tn->telrcv_state = CURL_TS_SB;
- continue;
- case CURL_IAC:
- Curl_client_write(conn, CLIENTWRITE_BODY, (char *)&c, 1);
- break;
- case CURL_DM:
- case CURL_NOP:
- case CURL_GA:
- default:
- printoption(data, "RCVD", CURL_IAC, c);
- break;
- }
- tn->telrcv_state = CURL_TS_DATA;
- continue;
-
- case CURL_TS_WILL:
- printoption(data, "RCVD", CURL_WILL, c);
- tn->please_negotiate = 1;
- rec_will(conn, c);
- tn->telrcv_state = CURL_TS_DATA;
- continue;
-
- case CURL_TS_WONT:
- printoption(data, "RCVD", CURL_WONT, c);
- tn->please_negotiate = 1;
- rec_wont(conn, c);
- tn->telrcv_state = CURL_TS_DATA;
- continue;
-
- case CURL_TS_DO:
- printoption(data, "RCVD", CURL_DO, c);
- tn->please_negotiate = 1;
- rec_do(conn, c);
- tn->telrcv_state = CURL_TS_DATA;
- continue;
-
- case CURL_TS_DONT:
- printoption(data, "RCVD", CURL_DONT, c);
- tn->please_negotiate = 1;
- rec_dont(conn, c);
- tn->telrcv_state = CURL_TS_DATA;
- continue;
-
- case CURL_TS_SB:
- if (c == CURL_IAC)
- {
- tn->telrcv_state = CURL_TS_SE;
- }
- else
- {
- CURL_SB_ACCUM(tn,c);
- }
- continue;
-
- case CURL_TS_SE:
- if (c != CURL_SE)
- {
- if (c != CURL_IAC)
- {
- /*
- * This is an error. We only expect to get "IAC IAC" or "IAC SE".
- * Several things may have happend. An IAC was not doubled, the
- * IAC SE was left off, or another option got inserted into the
- * suboption are all possibilities. If we assume that the IAC was
- * not doubled, and really the IAC SE was left off, we could get
- * into an infinate loop here. So, instead, we terminate the
- * suboption, and process the partial suboption if we can.
- */
- CURL_SB_ACCUM(tn, CURL_IAC);
- CURL_SB_ACCUM(tn, c);
- tn->subpointer -= 2;
- CURL_SB_TERM(tn);
-
- printoption(data, "In SUBOPTION processing, RCVD", CURL_IAC, c);
- suboption(conn); /* handle sub-option */
- tn->telrcv_state = CURL_TS_IAC;
- goto process_iac;
- }
- CURL_SB_ACCUM(tn,c);
- tn->telrcv_state = CURL_TS_SB;
- }
- else
- {
- CURL_SB_ACCUM(tn, CURL_IAC);
- CURL_SB_ACCUM(tn, CURL_SE);
- tn->subpointer -= 2;
- CURL_SB_TERM(tn);
- suboption(conn); /* handle sub-option */
- tn->telrcv_state = CURL_TS_DATA;
- }
- break;
- }
- }
-}
-
-CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode status, bool premature)
-{
- struct TELNET *tn = (struct TELNET *)conn->data->reqdata.proto.telnet;
- (void)status; /* unused */
- (void)premature; /* not used */
-
- curl_slist_free_all(tn->telnet_vars);
-
- free(conn->data->reqdata.proto.telnet);
- conn->data->reqdata.proto.telnet = NULL;
-
- return CURLE_OK;
-}
-
-CURLcode Curl_telnet(struct connectdata *conn, bool *done)
-{
- CURLcode code;
- struct SessionHandle *data = conn->data;
- curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
-#ifdef USE_WINSOCK
- HMODULE wsock2;
- WSOCK2_FUNC close_event_func;
- WSOCK2_FUNC create_event_func;
- WSOCK2_FUNC event_select_func;
- WSOCK2_FUNC enum_netevents_func;
- WSAEVENT event_handle;
- WSANETWORKEVENTS events;
- HANDLE stdin_handle;
- HANDLE objs[2];
- DWORD obj_count;
- DWORD wait_timeout;
- DWORD waitret;
- DWORD readfile_read;
-#else
- int interval_ms;
- struct pollfd pfd[2];
-#endif
- ssize_t nread;
- bool keepon = TRUE;
- char *buf = data->state.buffer;
- struct TELNET *tn;
-
- *done = TRUE; /* uncontionally */
-
- code = init_telnet(conn);
- if(code)
- return code;
-
- tn = (struct TELNET *)data->reqdata.proto.telnet;
-
- code = check_telnet_options(conn);
- if(code)
- return code;
-
-#ifdef USE_WINSOCK
- /*
- ** This functionality only works with WinSock >= 2.0. So,
- ** make sure have it.
- */
- code = check_wsock2(data);
- if (code)
- return code;
-
- /* OK, so we have WinSock 2.0. We need to dynamically */
- /* load ws2_32.dll and get the function pointers we need. */
- wsock2 = LoadLibrary("WS2_32.DLL");
- if (wsock2 == NULL) {
- failf(data,"failed to load WS2_32.DLL (%d)",GetLastError());
- return CURLE_FAILED_INIT;
- }
-
- /* Grab a pointer to WSACreateEvent */
- create_event_func = GetProcAddress(wsock2,"WSACreateEvent");
- if (create_event_func == NULL) {
- failf(data,"failed to find WSACreateEvent function (%d)",
- GetLastError());
- FreeLibrary(wsock2);
- return CURLE_FAILED_INIT;
- }
-
- /* And WSACloseEvent */
- close_event_func = GetProcAddress(wsock2,"WSACloseEvent");
- if (close_event_func == NULL) {
- failf(data,"failed to find WSACloseEvent function (%d)",
- GetLastError());
- FreeLibrary(wsock2);
- return CURLE_FAILED_INIT;
- }
-
- /* And WSAEventSelect */
- event_select_func = GetProcAddress(wsock2,"WSAEventSelect");
- if (event_select_func == NULL) {
- failf(data,"failed to find WSAEventSelect function (%d)",
- GetLastError());
- FreeLibrary(wsock2);
- return CURLE_FAILED_INIT;
- }
-
- /* And WSAEnumNetworkEvents */
- enum_netevents_func = GetProcAddress(wsock2,"WSAEnumNetworkEvents");
- if (enum_netevents_func == NULL) {
- failf(data,"failed to find WSAEnumNetworkEvents function (%d)",
- GetLastError());
- FreeLibrary(wsock2);
- return CURLE_FAILED_INIT;
- }
-
- /* We want to wait for both stdin and the socket. Since
- ** the select() function in winsock only works on sockets
- ** we have to use the WaitForMultipleObjects() call.
- */
-
- /* First, create a sockets event object */
- event_handle = (WSAEVENT)create_event_func();
- if (event_handle == WSA_INVALID_EVENT) {
- failf(data,"WSACreateEvent failed (%d)",WSAGetLastError());
- FreeLibrary(wsock2);
- return CURLE_FAILED_INIT;
- }
-
- /* The get the Windows file handle for stdin */
- stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
-
- /* Create the list of objects to wait for */
- objs[0] = event_handle;
- objs[1] = stdin_handle;
-
- /* Tell winsock what events we want to listen to */
- if(event_select_func(sockfd, event_handle, FD_READ|FD_CLOSE) == SOCKET_ERROR) {
- close_event_func(event_handle);
- FreeLibrary(wsock2);
- return 0;
- }
-
- /* If stdin_handle is a pipe, use PeekNamedPipe() method to check it,
- else use the old WaitForMultipleObjects() way */
- if(GetFileType(stdin_handle) == FILE_TYPE_PIPE) {
- /* Don't wait for stdin_handle, just wait for event_handle */
- obj_count = 1;
- /* Check stdin_handle per 100 milliseconds */
- wait_timeout = 100;
- } else {
- obj_count = 2;
- wait_timeout = INFINITE;
- }
-
- /* Keep on listening and act on events */
- while(keepon) {
- waitret = WaitForMultipleObjects(obj_count, objs, FALSE, wait_timeout);
- switch(waitret) {
- case WAIT_TIMEOUT:
- {
- unsigned char outbuf[2];
- int out_count = 0;
- ssize_t bytes_written;
- char *buffer = buf;
-
- while(1) {
- if(!PeekNamedPipe(stdin_handle, NULL, 0, NULL, &readfile_read, NULL)) {
- keepon = FALSE;
- break;
- }
- nread = readfile_read;
-
- if(!nread)
- break;
-
- if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
- &readfile_read, NULL)) {
- keepon = FALSE;
- break;
- }
- nread = readfile_read;
-
- while(nread--) {
- outbuf[0] = *buffer++;
- out_count = 1;
- if(outbuf[0] == CURL_IAC)
- outbuf[out_count++] = CURL_IAC;
-
- Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf,
- out_count, &bytes_written);
- }
- }
- }
- break;
-
- case WAIT_OBJECT_0 + 1:
- {
- unsigned char outbuf[2];
- int out_count = 0;
- ssize_t bytes_written;
- char *buffer = buf;
-
- if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
- &readfile_read, NULL)) {
- keepon = FALSE;
- break;
- }
- nread = readfile_read;
-
- while(nread--) {
- outbuf[0] = *buffer++;
- out_count = 1;
- if(outbuf[0] == CURL_IAC)
- outbuf[out_count++] = CURL_IAC;
-
- Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf,
- out_count, &bytes_written);
- }
- }
- break;
-
- case WAIT_OBJECT_0:
- if(enum_netevents_func(sockfd, event_handle, &events)
- != SOCKET_ERROR) {
- if(events.lNetworkEvents & FD_READ) {
- /* This reallu OUGHT to check its return code. */
- (void)Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread);
-
- telrcv(conn, (unsigned char *)buf, nread);
-
- fflush(stdout);
-
- /* Negotiate if the peer has started negotiating,
- otherwise don't. We don't want to speak telnet with
- non-telnet servers, like POP or SMTP. */
- if(tn->please_negotiate && !tn->already_negotiated) {
- negotiate(conn);
- tn->already_negotiated = 1;
- }
- }
-
- if(events.lNetworkEvents & FD_CLOSE) {
- keepon = FALSE;
- }
- }
- break;
- }
- }
-
- /* We called WSACreateEvent, so call WSACloseEvent */
- if (close_event_func(event_handle) == FALSE) {
- infof(data,"WSACloseEvent failed (%d)",WSAGetLastError());
- }
-
- /* "Forget" pointers into the library we're about to free */
- create_event_func = NULL;
- close_event_func = NULL;
- event_select_func = NULL;
- enum_netevents_func = NULL;
-
- /* We called LoadLibrary, so call FreeLibrary */
- if (!FreeLibrary(wsock2))
- infof(data,"FreeLibrary(wsock2) failed (%d)",GetLastError());
-#else
- pfd[0].fd = sockfd;
- pfd[0].events = POLLIN;
- pfd[1].fd = 0;
- pfd[1].events = POLLIN;
- interval_ms = 1 * 1000;
-
- while (keepon) {
- switch (Curl_poll(pfd, 2, interval_ms)) {
- case -1: /* error, stop reading */
- keepon = FALSE;
- continue;
- case 0: /* timeout */
- break;
- default: /* read! */
- if(pfd[1].revents & POLLIN) { /* read from stdin */
- unsigned char outbuf[2];
- int out_count = 0;
- ssize_t bytes_written;
- char *buffer = buf;
-
- nread = read(0, buf, 255);
-
- while(nread--) {
- outbuf[0] = *buffer++;
- out_count = 1;
- if(outbuf[0] == CURL_IAC)
- outbuf[out_count++] = CURL_IAC;
-
- Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf,
- out_count, &bytes_written);
- }
- }
-
- if(pfd[0].revents & POLLIN) {
- /* This OUGHT to check the return code... */
- (void)Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread);
-
- /* if we receive 0 or less here, the server closed the connection and
- we bail out from this! */
- if (nread <= 0) {
- keepon = FALSE;
- break;
- }
-
- telrcv(conn, (unsigned char *)buf, nread);
-
- /* Negotiate if the peer has started negotiating,
- otherwise don't. We don't want to speak telnet with
- non-telnet servers, like POP or SMTP. */
- if(tn->please_negotiate && !tn->already_negotiated) {
- negotiate(conn);
- tn->already_negotiated = 1;
- }
- }
- }
- if(data->set.timeout) {
- struct timeval now; /* current time */
- now = Curl_tvnow();
- if(Curl_tvdiff(now, conn->created)/1000 >= data->set.timeout) {
- failf(data, "Time-out");
- code = CURLE_OPERATION_TIMEOUTED;
- keepon = FALSE;
- }
- }
- }
-#endif
- /* mark this as "no further transfer wanted" */
- Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
-
- return code;
-}
-#endif
diff --git a/Utilities/cmcurl/telnet.h b/Utilities/cmcurl/telnet.h
deleted file mode 100644
index 693abf3f8..000000000
--- a/Utilities/cmcurl/telnet.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef __TELNET_H
-#define __TELNET_H
-
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-#ifndef CURL_DISABLE_TELNET
-CURLcode Curl_telnet(struct connectdata *conn, bool *done);
-CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode, bool premature);
-#endif
-#endif
diff --git a/Utilities/cmcurl/tftp.c b/Utilities/cmcurl/tftp.c
deleted file mode 100644
index 0e2e7ab45..000000000
--- a/Utilities/cmcurl/tftp.c
+++ /dev/null
@@ -1,816 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#ifndef CURL_DISABLE_TFTP
-/* -- WIN32 approved -- */
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <ctype.h>
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-
-#if defined(WIN32)
-#include <time.h>
-#include <io.h>
-#else
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#include <netinet/in.h>
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <netdb.h>
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_NET_IF_H
-#include <net/if.h>
-#endif
-#include <sys/ioctl.h>
-#include <signal.h>
-
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
-
-#endif
-
-#include "urldata.h"
-#include <curl/curl.h>
-#include "transfer.h"
-#include "sendf.h"
-#include "tftp.h"
-#include "progress.h"
-#include "connect.h"
-#include "strerror.h"
-#include "sockaddr.h" /* required for Curl_sockaddr_storage */
-#include "url.h"
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-#include "memory.h"
-#include "select.h"
-
-/* The last #include file should be: */
-#include "memdebug.h"
-
-/* RFC2348 allows the block size to be negotiated, but we don't support that */
-#define TFTP_BLOCKSIZE 512
-
-typedef enum {
- TFTP_MODE_NETASCII=0,
- TFTP_MODE_OCTET
-} tftp_mode_t;
-
-typedef enum {
- TFTP_STATE_START=0,
- TFTP_STATE_RX,
- TFTP_STATE_TX,
- TFTP_STATE_FIN
-} tftp_state_t;
-
-typedef enum {
- TFTP_EVENT_INIT=0,
- TFTP_EVENT_RRQ = 1,
- TFTP_EVENT_WRQ = 2,
- TFTP_EVENT_DATA = 3,
- TFTP_EVENT_ACK = 4,
- TFTP_EVENT_ERROR = 5,
- TFTP_EVENT_TIMEOUT
-} tftp_event_t;
-
-typedef enum {
- TFTP_ERR_UNDEF=0,
- TFTP_ERR_NOTFOUND,
- TFTP_ERR_PERM,
- TFTP_ERR_DISKFULL,
- TFTP_ERR_ILLEGAL,
- TFTP_ERR_UNKNOWNID,
- TFTP_ERR_EXISTS,
- TFTP_ERR_NOSUCHUSER,
- TFTP_ERR_TIMEOUT,
- TFTP_ERR_NORESPONSE
-} tftp_error_t;
-
-typedef struct tftp_packet {
- unsigned char data[2 + 2 + TFTP_BLOCKSIZE];
-} tftp_packet_t;
-
-typedef struct tftp_state_data {
- tftp_state_t state;
- tftp_mode_t mode;
- tftp_error_t error;
- struct connectdata *conn;
- curl_socket_t sockfd;
- int retries;
- int retry_time;
- int retry_max;
- time_t start_time;
- time_t max_time;
- unsigned short block;
- struct Curl_sockaddr_storage local_addr;
- socklen_t local_addrlen;
- struct Curl_sockaddr_storage remote_addr;
- socklen_t remote_addrlen;
- int rbytes;
- int sbytes;
- tftp_packet_t rpacket;
- tftp_packet_t spacket;
-} tftp_state_data_t;
-
-
-/* Forward declarations */
-static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event) ;
-static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event) ;
-void tftp_set_timeouts(tftp_state_data_t *state) ;
-
-/**********************************************************
- *
- * tftp_set_timeouts -
- *
- * Set timeouts based on state machine state.
- * Use user provided connect timeouts until DATA or ACK
- * packet is received, then use user-provided transfer timeouts
- *
- *
- **********************************************************/
-void tftp_set_timeouts(tftp_state_data_t *state)
-{
-
- struct SessionHandle *data = state->conn->data;
- time_t maxtime, timeout;
-
- time(&state->start_time);
- if(state->state == TFTP_STATE_START) {
- /* Compute drop-dead time */
- maxtime = (time_t)(data->set.connecttimeout?data->set.connecttimeout:30);
- state->max_time = state->start_time+maxtime;
-
- /* Set per-block timeout to total */
- timeout = maxtime ;
-
- /* Average restart after 5 seconds */
- state->retry_max = (int)(timeout/5);
-
- /* Compute the re-start interval to suit the timeout */
- state->retry_time = (int)(timeout/state->retry_max);
- if(state->retry_time<1)
- state->retry_time=1;
-
- }
- else {
-
- /* Compute drop-dead time */
- maxtime = (time_t)(data->set.timeout?data->set.timeout:3600);
- state->max_time = state->start_time+maxtime;
-
- /* Set per-block timeout to 10% of total */
- timeout = maxtime/10 ;
-
- /* Average reposting an ACK after 15 seconds */
- state->retry_max = (int)(timeout/15);
- }
- /* But bound the total number */
- if(state->retry_max<3)
- state->retry_max=3;
-
- if(state->retry_max>50)
- state->retry_max=50;
-
- /* Compute the re-ACK interval to suit the timeout */
- state->retry_time = (int)(timeout/state->retry_max);
- if(state->retry_time<1)
- state->retry_time=1;
-
- infof(data, "set timeouts for state %d; Total %d, retry %d maxtry %d\n",
- state->state, (state->max_time-state->start_time),
- state->retry_time, state->retry_max);
-}
-
-/**********************************************************
- *
- * tftp_set_send_first
- *
- * Event handler for the START state
- *
- **********************************************************/
-
-static void setpacketevent(tftp_packet_t *packet, unsigned short num)
-{
- packet->data[0] = (unsigned char)(num >> 8);
- packet->data[1] = (unsigned char)(num & 0xff);
-}
-
-
-static void setpacketblock(tftp_packet_t *packet, unsigned short num)
-{
- packet->data[2] = (unsigned char)(num >> 8);
- packet->data[3] = (unsigned char)(num & 0xff);
-}
-
-static unsigned short getrpacketevent(tftp_packet_t *packet)
-{
- return (unsigned short)((packet->data[0] << 8) | packet->data[1]);
-}
-
-static unsigned short getrpacketblock(tftp_packet_t *packet)
-{
- return (unsigned short)((packet->data[2] << 8) | packet->data[3]);
-}
-
-static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
-{
- int sbytes;
- const char *mode = "octet";
- char *filename;
- struct SessionHandle *data = state->conn->data;
- CURLcode res = CURLE_OK;
-
- /* Set ascii mode if -B flag was used */
- if(data->set.prefer_ascii)
- mode = "netascii";
-
- switch(event) {
-
- case TFTP_EVENT_INIT: /* Send the first packet out */
- case TFTP_EVENT_TIMEOUT: /* Resend the first packet out */
- /* Increment the retry counter, quit if over the limit */
- state->retries++;
- if(state->retries>state->retry_max) {
- state->error = TFTP_ERR_NORESPONSE;
- state->state = TFTP_STATE_FIN;
- return res;
- }
-
- if(data->set.upload) {
- /* If we are uploading, send an WRQ */
- setpacketevent(&state->spacket, TFTP_EVENT_WRQ);
- state->conn->data->reqdata.upload_fromhere = (char *)&state->spacket.data[4];
- if(data->set.infilesize != -1)
- Curl_pgrsSetUploadSize(data, data->set.infilesize);
- }
- else {
- /* If we are downloading, send an RRQ */
- setpacketevent(&state->spacket, TFTP_EVENT_RRQ);
- }
- /* As RFC3617 describes the separator slash is not actually part of the
- file name so we skip the always-present first letter of the path string. */
- filename = curl_easy_unescape(data, &state->conn->data->reqdata.path[1], 0,
- NULL);
- snprintf((char *)&state->spacket.data[2],
- TFTP_BLOCKSIZE,
- "%s%c%s%c", filename, '\0', mode, '\0');
- sbytes = 4 + (int)strlen(filename) + (int)strlen(mode);
- sbytes = sendto(state->sockfd, (void *)&state->spacket,
- sbytes, 0,
- state->conn->ip_addr->ai_addr,
- state->conn->ip_addr->ai_addrlen);
- if(sbytes < 0) {
- failf(data, "%s\n", Curl_strerror(state->conn, Curl_sockerrno()));
- }
- Curl_safefree(filename);
- break;
-
- case TFTP_EVENT_ACK: /* Connected for transmit */
- infof(data, "%s\n", "Connected for transmit");
- state->state = TFTP_STATE_TX;
- tftp_set_timeouts(state);
- return tftp_tx(state, event);
-
- case TFTP_EVENT_DATA: /* connected for receive */
- infof(data, "%s\n", "Connected for receive");
- state->state = TFTP_STATE_RX;
- tftp_set_timeouts(state);
- return tftp_rx(state, event);
-
- case TFTP_EVENT_ERROR:
- state->state = TFTP_STATE_FIN;
- break;
-
- default:
- failf(state->conn->data, "tftp_send_first: internal error\n");
- break;
- }
- return res;
-}
-
-/**********************************************************
- *
- * tftp_rx
- *
- * Event handler for the RX state
- *
- **********************************************************/
-static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event)
-{
- int sbytes;
- int rblock;
- struct SessionHandle *data = state->conn->data;
-
- switch(event) {
-
- case TFTP_EVENT_DATA:
-
- /* Is this the block we expect? */
- rblock = getrpacketblock(&state->rpacket);
- if ((state->block+1) != rblock) {
- /* No, log it, up the retry count and fail if over the limit */
- infof(data,
- "Received unexpected DATA packet block %d\n", rblock);
- state->retries++;
- if (state->retries>state->retry_max) {
- failf(data, "tftp_rx: giving up waiting for block %d\n",
- state->block+1);
- return CURLE_TFTP_ILLEGAL;
- }
- }
- /* This is the expected block. Reset counters and ACK it. */
- state->block = (unsigned short)rblock;
- state->retries = 0;
- setpacketevent(&state->spacket, TFTP_EVENT_ACK);
- setpacketblock(&state->spacket, state->block);
- sbytes = sendto(state->sockfd, (void *)state->spacket.data,
- 4, SEND_4TH_ARG,
- (struct sockaddr *)&state->remote_addr,
- state->remote_addrlen);
- if(sbytes < 0) {
- failf(data, "%s\n", Curl_strerror(state->conn, Curl_sockerrno()));
- }
-
- /* Check if completed (That is, a less than full packet is received) */
- if (state->rbytes < (int)sizeof(state->spacket)){
- state->state = TFTP_STATE_FIN;
- }
- else {
- state->state = TFTP_STATE_RX;
- }
- break;
-
- case TFTP_EVENT_TIMEOUT:
- /* Increment the retry count and fail if over the limit */
- state->retries++;
- infof(data,
- "Timeout waiting for block %d ACK. Retries = %d\n", state->retries);
- if(state->retries > state->retry_max) {
- state->error = TFTP_ERR_TIMEOUT;
- state->state = TFTP_STATE_FIN;
- }
- else {
- /* Resend the previous ACK */
- sbytes = sendto(state->sockfd, (void *)&state->spacket,
- 4, SEND_4TH_ARG,
- (struct sockaddr *)&state->remote_addr,
- state->remote_addrlen);
- /* Check all sbytes were sent */
- if(sbytes<0) {
- failf(data, "%s\n", Curl_strerror(state->conn, Curl_sockerrno()));
- }
- }
- break;
-
- case TFTP_EVENT_ERROR:
- state->state = TFTP_STATE_FIN;
- break;
-
- default:
- failf(data, "%s\n", "tftp_rx: internal error");
- break;
- }
- Curl_pgrsSetDownloadCounter(data,
- (curl_off_t) state->block*TFTP_BLOCKSIZE);
- return CURLE_OK;
-}
-
-/**********************************************************
- *
- * tftp_tx
- *
- * Event handler for the TX state
- *
- **********************************************************/
-static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
-{
- struct SessionHandle *data = state->conn->data;
- int sbytes;
- int rblock;
- CURLcode res = CURLE_OK;
-
- switch(event) {
-
- case TFTP_EVENT_ACK:
- /* Ack the packet */
- rblock = getrpacketblock(&state->rpacket);
-
- if(rblock != state->block) {
- /* This isn't the expected block. Log it and up the retry counter */
- infof(data, "Received ACK for block %d, expecting %d\n",
- rblock, state->block);
- state->retries++;
- /* Bail out if over the maximum */
- if(state->retries>state->retry_max) {
- failf(data, "tftp_tx: giving up waiting for block %d ack",
- state->block);
- res = CURLE_SEND_ERROR;
- }
- else {
- /* Re-send the data packet */
- sbytes = sendto(state->sockfd, (void *)&state->spacket,
- 4+state->sbytes, SEND_4TH_ARG,
- (struct sockaddr *)&state->remote_addr,
- state->remote_addrlen);
- /* Check all sbytes were sent */
- if(sbytes<0) {
- failf(data, "%s\n", Curl_strerror(state->conn, Curl_sockerrno()));
- res = CURLE_SEND_ERROR;
- }
- }
- return res;
- }
- /* This is the expected packet. Reset the counters and send the next
- block */
- state->block++;
- state->retries = 0;
- setpacketevent(&state->spacket, TFTP_EVENT_DATA);
- setpacketblock(&state->spacket, state->block);
- if(state->block > 1 && state->sbytes < TFTP_BLOCKSIZE) {
- state->state = TFTP_STATE_FIN;
- return CURLE_OK;
- }
- res = Curl_fillreadbuffer(state->conn, TFTP_BLOCKSIZE, &state->sbytes);
- if(res)
- return res;
- sbytes = sendto(state->sockfd, (void *)state->spacket.data,
- 4+state->sbytes, SEND_4TH_ARG,
- (struct sockaddr *)&state->remote_addr,
- state->remote_addrlen);
- /* Check all sbytes were sent */
- if(sbytes<0) {
- failf(data, "%s\n", Curl_strerror(state->conn, Curl_sockerrno()));
- }
- break;
-
- case TFTP_EVENT_TIMEOUT:
- /* Increment the retry counter and log the timeout */
- state->retries++;
- infof(data, "Timeout waiting for block %d ACK. "
- " Retries = %d\n", state->retries);
- /* Decide if we've had enough */
- if(state->retries > state->retry_max) {
- state->error = TFTP_ERR_TIMEOUT;
- state->state = TFTP_STATE_FIN;
- } else {
- /* Re-send the data packet */
- sbytes = sendto(state->sockfd, (void *)&state->spacket,
- 4+state->sbytes, SEND_4TH_ARG,
- (struct sockaddr *)&state->remote_addr,
- state->remote_addrlen);
- /* Check all sbytes were sent */
- if(sbytes<0) {
- failf(data, "%s\n", Curl_strerror(state->conn, Curl_sockerrno()));
- }
- }
- break;
-
- case TFTP_EVENT_ERROR:
- state->state = TFTP_STATE_FIN;
- break;
-
- default:
- failf(data, "%s\n", "tftp_tx: internal error");
- break;
- }
-
- /* Update the progress meter */
- Curl_pgrsSetUploadCounter(data, (curl_off_t) state->block*TFTP_BLOCKSIZE);
-
- return res;
-}
-
-/**********************************************************
- *
- * tftp_state_machine
- *
- * The tftp state machine event dispatcher
- *
- **********************************************************/
-static CURLcode tftp_state_machine(tftp_state_data_t *state,
- tftp_event_t event)
-{
- CURLcode res = CURLE_OK;
- struct SessionHandle *data = state->conn->data;
- switch(state->state) {
- case TFTP_STATE_START:
- DEBUGF(infof(data, "TFTP_STATE_START\n"));
- res = tftp_send_first(state, event);
- break;
- case TFTP_STATE_RX:
- DEBUGF(infof(data, "TFTP_STATE_RX\n"));
- res = tftp_rx(state, event);
- break;
- case TFTP_STATE_TX:
- DEBUGF(infof(data, "TFTP_STATE_TX\n"));
- res = tftp_tx(state, event);
- break;
- case TFTP_STATE_FIN:
- infof(data, "%s\n", "TFTP finished");
- break;
- default:
- DEBUGF(infof(data, "STATE: %d\n", state->state));
- failf(data, "%s\n", "Internal state machine error");
- res = CURLE_TFTP_ILLEGAL;
- break;
- }
- return res;
-}
-
-
-/**********************************************************
- *
- * Curl_tftp_connect
- *
- * The connect callback
- *
- **********************************************************/
-CURLcode Curl_tftp_connect(struct connectdata *conn, bool *done)
-{
- CURLcode code;
- tftp_state_data_t *state;
- int rc;
-
- state = conn->data->reqdata.proto.tftp = calloc(sizeof(tftp_state_data_t),
- 1);
- if(!state)
- return CURLE_OUT_OF_MEMORY;
-
- conn->bits.close = FALSE; /* keep it open if possible */
-
- state->conn = conn;
- state->sockfd = state->conn->sock[FIRSTSOCKET];
- state->state = TFTP_STATE_START;
-
- ((struct sockaddr *)&state->local_addr)->sa_family =
- conn->ip_addr->ai_family;
-
- tftp_set_timeouts(state);
-
- if(!conn->bits.reuse) {
- /* If not reused, bind to any interface, random UDP port. If it is reused,
- * this has already been done!
- *
- * We once used the size of the local_addr struct as the third argument for
- * bind() to better work with IPv6 or whatever size the struct could have,
- * but we learned that at least Tru64, AIX and IRIX *requires* the size of
- * that argument to match the exact size of a 'sockaddr_in' struct when
- * running IPv4-only.
- *
- * Therefore we use the size from the address we connected to, which we
- * assume uses the same IP version and thus hopefully this works for both
- * IPv4 and IPv6...
- */
- rc = bind(state->sockfd, (struct sockaddr *)&state->local_addr,
- conn->ip_addr->ai_addrlen);
- if(rc) {
- failf(conn->data, "bind() failed; %s\n",
- Curl_strerror(conn, Curl_sockerrno()));
- return CURLE_COULDNT_CONNECT;
- }
- }
-
- Curl_pgrsStartNow(conn->data);
-
- *done = TRUE;
- code = CURLE_OK;
- return(code);
-}
-
-/**********************************************************
- *
- * Curl_tftp_done
- *
- * The done callback
- *
- **********************************************************/
-CURLcode Curl_tftp_done(struct connectdata *conn, CURLcode status,
- bool premature)
-{
- (void)status; /* unused */
- (void)premature; /* not used */
-
-#if 0
- free(conn->data->reqdata.proto.tftp);
- conn->data->reqdata.proto.tftp = NULL;
-#endif
- Curl_pgrsDone(conn);
-
- return CURLE_OK;
-}
-
-
-/**********************************************************
- *
- * Curl_tftp
- *
- * The do callback
- *
- * This callback handles the entire TFTP transfer
- *
- **********************************************************/
-
-CURLcode Curl_tftp(struct connectdata *conn, bool *done)
-{
- struct SessionHandle *data = conn->data;
- tftp_state_data_t *state =
- (tftp_state_data_t *) conn->data->reqdata.proto.tftp;
- tftp_event_t event;
- CURLcode code;
- int rc;
- struct Curl_sockaddr_storage fromaddr;
- socklen_t fromlen;
- int check_time = 0;
-
- *done = TRUE;
-
- /*
- Since connections can be re-used between SessionHandles, this might be a
- connection already existing but on a fresh SessionHandle struct so we must
- make sure we have a good 'struct TFTP' to play with. For new connections,
- the struct TFTP is allocated and setup in the Curl_tftp_connect() function.
- */
- if(!state) {
- code = Curl_tftp_connect(conn, done);
- if(code)
- return code;
- state = (tftp_state_data_t *)conn->data->reqdata.proto.tftp;
- }
-
- /* Run the TFTP State Machine */
- for(tftp_state_machine(state, TFTP_EVENT_INIT);
- state->state != TFTP_STATE_FIN;
- tftp_state_machine(state, event) ) {
-
- /* Wait until ready to read or timeout occurs */
- rc=Curl_select(state->sockfd, CURL_SOCKET_BAD, state->retry_time * 1000);
-
- if(rc == -1) {
- /* bail out */
- int error = Curl_sockerrno();
- failf(data, "%s\n", Curl_strerror(conn, error));
- event = TFTP_EVENT_ERROR;
- }
- else if (rc==0) {
- /* A timeout occured */
- event = TFTP_EVENT_TIMEOUT;
-
- /* Force a look at transfer timeouts */
- check_time = 0;
-
- }
- else {
-
- /* Receive the packet */
- fromlen=sizeof(fromaddr);
- state->rbytes = recvfrom(state->sockfd,
- (void *)&state->rpacket, sizeof(state->rpacket),
- 0, (struct sockaddr *)&fromaddr, &fromlen);
- if(state->remote_addrlen==0) {
- memcpy(&state->remote_addr, &fromaddr, fromlen);
- state->remote_addrlen = fromlen;
- }
-
- /* Sanity check packet length */
- if (state->rbytes < 4) {
- failf(conn->data, "Received too short packet\n");
- /* Not a timeout, but how best to handle it? */
- event = TFTP_EVENT_TIMEOUT;
- }
- else {
-
- /* The event is given by the TFTP packet time */
- event = (tftp_event_t)getrpacketevent(&state->rpacket);
-
- switch(event) {
- case TFTP_EVENT_DATA:
- /* Don't pass to the client empty or retransmitted packets */
- if (state->rbytes > 4 &&
- ((state->block+1) == getrpacketblock(&state->rpacket))) {
- code = Curl_client_write(conn, CLIENTWRITE_BODY,
- (char *)&state->rpacket.data[4],
- state->rbytes-4);
- if(code)
- return code;
- }
- break;
- case TFTP_EVENT_ERROR:
- state->error = (tftp_error_t)getrpacketblock(&state->rpacket);
- infof(conn->data, "%s\n", (char *)&state->rpacket.data[4]);
- break;
- case TFTP_EVENT_ACK:
- break;
- case TFTP_EVENT_RRQ:
- case TFTP_EVENT_WRQ:
- default:
- failf(conn->data, "%s\n", "Internal error: Unexpected packet");
- break;
- }
-
- /* Update the progress meter */
- if(Curl_pgrsUpdate(conn))
- return CURLE_ABORTED_BY_CALLBACK;
- }
- }
-
- /* Check for transfer timeout every 10 blocks, or after timeout */
- if(check_time%10==0) {
- time_t current;
- time(&current);
- if(current>state->max_time) {
- DEBUGF(infof(data, "timeout: %d > %d\n",
- current, state->max_time));
- state->error = TFTP_ERR_TIMEOUT;
- state->state = TFTP_STATE_FIN;
- }
- }
-
- }
-
- /* Tell curl we're done */
- code = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
- if(code)
- return code;
-
- /* If we have encountered an error */
- if(state->error) {
-
- /* Translate internal error codes to curl error codes */
- switch(state->error) {
- case TFTP_ERR_NOTFOUND:
- code = CURLE_TFTP_NOTFOUND;
- break;
- case TFTP_ERR_PERM:
- code = CURLE_TFTP_PERM;
- break;
- case TFTP_ERR_DISKFULL:
- code = CURLE_TFTP_DISKFULL;
- break;
- case TFTP_ERR_ILLEGAL:
- code = CURLE_TFTP_ILLEGAL;
- break;
- case TFTP_ERR_UNKNOWNID:
- code = CURLE_TFTP_UNKNOWNID;
- break;
- case TFTP_ERR_EXISTS:
- code = CURLE_TFTP_EXISTS;
- break;
- case TFTP_ERR_NOSUCHUSER:
- code = CURLE_TFTP_NOSUCHUSER;
- break;
- case TFTP_ERR_TIMEOUT:
- code = CURLE_OPERATION_TIMEOUTED;
- break;
- case TFTP_ERR_NORESPONSE:
- code = CURLE_COULDNT_CONNECT;
- break;
- default:
- code= CURLE_ABORTED_BY_CALLBACK;
- break;
- }
- }
- else
- code = CURLE_OK;
- return code;
-}
-#endif
diff --git a/Utilities/cmcurl/tftp.h b/Utilities/cmcurl/tftp.h
deleted file mode 100644
index c7125417b..000000000
--- a/Utilities/cmcurl/tftp.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef __TFTP_H
-#define __TFTP_H
-
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-#ifndef CURL_DISABLE_TFTP
-CURLcode Curl_tftp_connect(struct connectdata *conn, bool *done);
-CURLcode Curl_tftp(struct connectdata *conn, bool *done);
-CURLcode Curl_tftp_done(struct connectdata *conn, CURLcode, bool premature);
-#endif
-#endif
diff --git a/Utilities/cmcurl/timeval.c b/Utilities/cmcurl/timeval.c
deleted file mode 100644
index bb9c0a174..000000000
--- a/Utilities/cmcurl/timeval.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "timeval.h"
-
-#ifndef HAVE_GETTIMEOFDAY
-
-#ifdef WIN32
-#include <mmsystem.h>
-
-static int gettimeofday(struct timeval *tp, void *nothing)
-{
-#ifdef WITHOUT_MM_LIB
- SYSTEMTIME st;
- time_t tt;
- struct tm tmtm;
- /* mktime converts local to UTC */
- GetLocalTime (&st);
- tmtm.tm_sec = st.wSecond;
- tmtm.tm_min = st.wMinute;
- tmtm.tm_hour = st.wHour;
- tmtm.tm_mday = st.wDay;
- tmtm.tm_mon = st.wMonth - 1;
- tmtm.tm_year = st.wYear - 1900;
- tmtm.tm_isdst = -1;
- tt = mktime (&tmtm);
- tp->tv_sec = tt;
- tp->tv_usec = st.wMilliseconds * 1000;
-#else
- /**
- ** The earlier time calculations using GetLocalTime
- ** had a time resolution of 10ms.The timeGetTime, part
- ** of multimedia apis offer a better time resolution
- ** of 1ms.Need to link against winmm.lib for this
- **/
- unsigned long Ticks = 0;
- unsigned long Sec =0;
- unsigned long Usec = 0;
- Ticks = timeGetTime();
-
- Sec = Ticks/1000;
- Usec = (Ticks - (Sec*1000))*1000;
- tp->tv_sec = Sec;
- tp->tv_usec = Usec;
-#endif /* WITHOUT_MM_LIB */
- (void)nothing;
- return 0;
-}
-#else /* WIN32 */
-/* non-win32 version of Curl_gettimeofday() */
-static int gettimeofday(struct timeval *tp, void *nothing)
-{
- (void)nothing; /* we don't support specific time-zones */
- tp->tv_sec = (long)time(NULL);
- tp->tv_usec = 0;
- return 0;
-}
-#endif /* WIN32 */
-#endif /* HAVE_GETTIMEOFDAY */
-
-/* Return the current time in a timeval struct */
-struct timeval curlx_tvnow(void)
-{
- struct timeval now;
- (void)gettimeofday(&now, NULL);
- return now;
-}
-
-/*
- * Make sure that the first argument is the more recent time, as otherwise
- * we'll get a weird negative time-diff back...
- *
- * Returns: the time difference in number of milliseconds.
- */
-long curlx_tvdiff(struct timeval newer, struct timeval older)
-{
- return (newer.tv_sec-older.tv_sec)*1000+
- (newer.tv_usec-older.tv_usec)/1000;
-}
-
-/*
- * Same as curlx_tvdiff but with full usec resolution.
- *
- * Returns: the time difference in seconds with subsecond resolution.
- */
-double curlx_tvdiff_secs(struct timeval newer, struct timeval older)
-{
- return (double)(newer.tv_sec-older.tv_sec)+
- (double)(newer.tv_usec-older.tv_usec)/1000000.0;
-}
-
-/* return the number of seconds in the given input timeval struct */
-long Curl_tvlong(struct timeval t1)
-{
- return t1.tv_sec;
-}
diff --git a/Utilities/cmcurl/timeval.h b/Utilities/cmcurl/timeval.h
deleted file mode 100644
index effd741da..000000000
--- a/Utilities/cmcurl/timeval.h
+++ /dev/null
@@ -1,76 +0,0 @@
-#ifndef __TIMEVAL_H
-#define __TIMEVAL_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-/*
- * CAUTION: this header is designed to work when included by the app-side
- * as well as the library. Do not mix with library internals!
- */
-
-#include "setup.h"
-
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#ifdef TIME_WITH_SYS_TIME
-#include <time.h>
-#endif
-#else
-#ifdef HAVE_TIME_H
-#include <time.h>
-#endif
-#endif
-
-#ifndef HAVE_STRUCT_TIMEVAL
-struct timeval {
- long tv_sec;
- long tv_usec;
-};
-#endif
-
-struct timeval curlx_tvnow(void);
-
-/*
- * Make sure that the first argument (t1) is the more recent time and t2 is
- * the older time, as otherwise you get a weird negative time-diff back...
- *
- * Returns: the time difference in number of milliseconds.
- */
-long curlx_tvdiff(struct timeval t1, struct timeval t2);
-
-/*
- * Same as curlx_tvdiff but with full usec resolution.
- *
- * Returns: the time difference in seconds with subsecond resolution.
- */
-double curlx_tvdiff_secs(struct timeval t1, struct timeval t2);
-
-long Curl_tvlong(struct timeval t1);
-
-/* These two defines below exist to provide the older API for library
- internals only. */
-#define Curl_tvnow() curlx_tvnow()
-#define Curl_tvdiff(x,y) curlx_tvdiff(x,y)
-#define Curl_tvdiff_secs(x,y) curlx_tvdiff_secs(x,y)
-
-#endif
diff --git a/Utilities/cmcurl/transfer.c b/Utilities/cmcurl/transfer.c
deleted file mode 100644
index 5cb3361d2..000000000
--- a/Utilities/cmcurl/transfer.c
+++ /dev/null
@@ -1,2494 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-/* -- WIN32 approved -- */
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <ctype.h>
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-
-#include <errno.h>
-
-#include "strtoofft.h"
-#include "strequal.h"
-
-#ifdef WIN32
-#include <time.h>
-#include <io.h>
-#else
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <netdb.h>
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_NET_IF_H
-#include <net/if.h>
-#endif
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-#include <signal.h>
-
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-#ifndef HAVE_SOCKET
-#error "We can't compile without socket() support!"
-#endif
-
-#endif
-
-#include "urldata.h"
-#include <curl/curl.h>
-#include "netrc.h"
-
-#include "content_encoding.h"
-#include "hostip.h"
-#include "transfer.h"
-#include "sendf.h"
-#include "speedcheck.h"
-#include "progress.h"
-#include "http.h"
-#include "url.h"
-#include "getinfo.h"
-#include "sslgen.h"
-#include "http_digest.h"
-#include "http_ntlm.h"
-#include "http_negotiate.h"
-#include "share.h"
-#include "memory.h"
-#include "select.h"
-#include "multiif.h"
-#include "easyif.h" /* for Curl_convert_to_network prototype */
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
-#include "memdebug.h"
-
-#define CURL_TIMEOUT_EXPECT_100 1000 /* counting ms here */
-
-/*
- * This function will call the read callback to fill our buffer with data
- * to upload.
- */
-CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
-{
- struct SessionHandle *data = conn->data;
- size_t buffersize = (size_t)bytes;
- int nread;
-
- if(conn->bits.upload_chunky) {
- /* if chunked Transfer-Encoding */
- buffersize -= (8 + 2 + 2); /* 32bit hex + CRLF + CRLF */
- data->reqdata.upload_fromhere += 10; /* 32bit hex + CRLF */
- }
-
- /* this function returns a size_t, so we typecast to int to prevent warnings
- with picky compilers */
- nread = (int)conn->fread(data->reqdata.upload_fromhere, 1,
- buffersize, conn->fread_in);
-
- if(nread == CURL_READFUNC_ABORT) {
- failf(data, "operation aborted by callback\n");
- return CURLE_ABORTED_BY_CALLBACK;
- }
-
- if(!conn->bits.forbidchunk && conn->bits.upload_chunky) {
- /* if chunked Transfer-Encoding */
- char hexbuffer[11];
- int hexlen = snprintf(hexbuffer, sizeof(hexbuffer),
- "%x\r\n", nread);
- /* move buffer pointer */
- data->reqdata.upload_fromhere -= hexlen;
- nread += hexlen;
-
- /* copy the prefix to the buffer */
- memcpy(data->reqdata.upload_fromhere, hexbuffer, hexlen);
-
- /* always append CRLF to the data */
- memcpy(data->reqdata.upload_fromhere + nread, "\r\n", 2);
-
- if((nread - hexlen) == 0) {
- /* mark this as done once this chunk is transfered */
- data->reqdata.keep.upload_done = TRUE;
- }
-
- nread+=2; /* for the added CRLF */
- }
-
- *nreadp = nread;
-
-#ifdef CURL_DOES_CONVERSIONS
- if(data->set.prefer_ascii) {
- CURLcode res;
- res = Curl_convert_to_network(data, data->reqdata.upload_fromhere, nread);
- /* Curl_convert_to_network calls failf if unsuccessful */
- if(res != CURLE_OK) {
- return(res);
- }
- }
-#endif /* CURL_DOES_CONVERSIONS */
-
- return CURLE_OK;
-}
-
-/*
- * checkhttpprefix()
- *
- * Returns TRUE if member of the list matches prefix of string
- */
-static bool
-checkhttpprefix(struct SessionHandle *data,
- const char *s)
-{
- struct curl_slist *head = data->set.http200aliases;
- bool rc = FALSE;
-#ifdef CURL_DOES_CONVERSIONS
- /* convert from the network encoding using a scratch area */
- char *scratch = calloc(1, strlen(s)+1);
- if (NULL == scratch) {
- failf (data, "Failed to calloc memory for conversion!");
- return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
- }
- strcpy(scratch, s);
- if (CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
- /* Curl_convert_from_network calls failf if unsuccessful */
- free(scratch);
- return FALSE; /* can't return CURLE_foobar so return FALSE */
- }
- s = scratch;
-#endif /* CURL_DOES_CONVERSIONS */
-
- while (head) {
- if (checkprefix(head->data, s)) {
- rc = TRUE;
- break;
- }
- head = head->next;
- }
-
- if ((rc != TRUE) && (checkprefix("HTTP/", s))) {
- rc = TRUE;
- }
-
-#ifdef CURL_DOES_CONVERSIONS
- free(scratch);
-#endif /* CURL_DOES_CONVERSIONS */
- return rc;
-}
-
-/*
- * Curl_readrewind() rewinds the read stream. This typically (so far) only
- * used for HTTP POST/PUT with multi-pass authentication when a sending was
- * denied and a resend is necessary.
- */
-CURLcode Curl_readrewind(struct connectdata *conn)
-{
- struct SessionHandle *data = conn->data;
-
- conn->bits.rewindaftersend = FALSE; /* we rewind now */
-
- /* We have sent away data. If not using CURLOPT_POSTFIELDS or
- CURLOPT_HTTPPOST, call app to rewind
- */
- if(data->set.postfields ||
- (data->set.httpreq == HTTPREQ_POST_FORM))
- ; /* do nothing */
- else {
- if(data->set.ioctl) {
- curlioerr err;
-
- err = (data->set.ioctl) (data, CURLIOCMD_RESTARTREAD,
- data->set.ioctl_client);
- infof(data, "the ioctl callback returned %d\n", (int)err);
-
- if(err) {
- /* FIXME: convert to a human readable error message */
- failf(data, "ioctl callback returned error %d\n", (int)err);
- return CURLE_SEND_FAIL_REWIND;
- }
- }
- else {
- /* If no CURLOPT_READFUNCTION is used, we know that we operate on a
- given FILE * stream and we can actually attempt to rewind that
- ourself with fseek() */
- if(data->set.fread == (curl_read_callback)fread) {
- if(-1 != fseek(data->set.in, 0, SEEK_SET))
- /* successful rewind */
- return CURLE_OK;
- }
-
- /* no callback set or failure aboe, makes us fail at once */
- failf(data, "necessary data rewind wasn't possible\n");
- return CURLE_SEND_FAIL_REWIND;
- }
- }
- return CURLE_OK;
-}
-
-static int data_pending(struct connectdata *conn)
-{
- return Curl_ssl_data_pending(conn, FIRSTSOCKET);
-}
-
-#ifndef MIN
-#define MIN(a,b) (a < b ? a : b)
-#endif
-
-static void read_rewind(struct connectdata *conn,
- size_t thismuch)
-{
- conn->read_pos -= thismuch;
- conn->bits.stream_was_rewound = TRUE;
-
-#ifdef CURLDEBUG
- {
- char buf[512 + 1];
- size_t show;
-
- show = MIN(conn->buf_len - conn->read_pos, sizeof(buf)-1);
- memcpy(buf, conn->master_buffer + conn->read_pos, show);
- buf[show] = '\0';
-
- DEBUGF(infof(conn->data,
- "Buffer after stream rewind (read_pos = %d): [%s]",
- conn->read_pos, buf));
- }
-#endif
-}
-
-/*
- * Curl_readwrite() is the low-level function to be called when data is to
- * be read and written to/from the connection.
- */
-CURLcode Curl_readwrite(struct connectdata *conn,
- bool *done)
-{
- struct SessionHandle *data = conn->data;
- struct Curl_transfer_keeper *k = &data->reqdata.keep;
- CURLcode result;
- ssize_t nread; /* number of bytes read */
- int didwhat=0;
-
- curl_socket_t fd_read;
- curl_socket_t fd_write;
- int select_res;
-
- curl_off_t contentlength;
-
- /* only use the proper socket if the *_HOLD bit is not set simultaneously as
- then we are in rate limiting state in that transfer direction */
-
- if((k->keepon & (KEEP_READ|KEEP_READ_HOLD)) == KEEP_READ)
- fd_read = conn->sockfd;
- else
- fd_read = CURL_SOCKET_BAD;
-
- if((k->keepon & (KEEP_WRITE|KEEP_WRITE_HOLD)) == KEEP_WRITE)
- fd_write = conn->writesockfd;
- else
- fd_write = CURL_SOCKET_BAD;
-
- select_res = Curl_select(fd_read, fd_write, 0);
- if(select_res == CSELECT_ERR) {
- failf(data, "select/poll returned error");
- return CURLE_SEND_ERROR;
- }
-
- do {
- /* We go ahead and do a read if we have a readable socket or if
- the stream was rewound (in which case we have data in a
- buffer) */
- if((k->keepon & KEEP_READ) &&
- ((select_res & CSELECT_IN) || conn->bits.stream_was_rewound)) {
- /* read */
- bool is_empty_data = FALSE;
-
- /* This is where we loop until we have read everything there is to
- read or we get a EWOULDBLOCK */
- do {
- size_t buffersize = data->set.buffer_size?
- data->set.buffer_size : BUFSIZE;
- size_t bytestoread = buffersize;
- int readrc;
-
- if (k->size != -1 && !k->header) {
- /* make sure we don't read "too much" if we can help it since we
- might be pipelining and then someone else might want to read what
- follows! */
- curl_off_t totalleft = k->size - k->bytecount;
- if(totalleft < (curl_off_t)bytestoread)
- bytestoread = (size_t)totalleft;
- }
-
- /* receive data from the network! */
- readrc = Curl_read(conn, conn->sockfd, k->buf, bytestoread, &nread);
-
- /* subzero, this would've blocked */
- if(0 > readrc)
- break; /* get out of loop */
-
- /* get the CURLcode from the int */
- result = (CURLcode)readrc;
-
- if(result>0)
- return result;
-
- if ((k->bytecount == 0) && (k->writebytecount == 0)) {
- Curl_pgrsTime(data, TIMER_STARTTRANSFER);
- if(k->wait100_after_headers)
- /* set time stamp to compare with when waiting for the 100 */
- k->start100 = Curl_tvnow();
- }
-
- didwhat |= KEEP_READ;
- /* indicates data of zero size, i.e. empty file */
- is_empty_data = (bool)((nread == 0) && (k->bodywrites == 0));
-
- /* NULL terminate, allowing string ops to be used */
- if (0 < nread || is_empty_data) {
- k->buf[nread] = 0;
- }
- else if (0 >= nread) {
- /* if we receive 0 or less here, the server closed the connection
- and we bail out from this! */
-
- k->keepon &= ~KEEP_READ;
- break;
- }
-
- /* Default buffer to use when we write the buffer, it may be changed
- in the flow below before the actual storing is done. */
- k->str = k->buf;
-
- /* Since this is a two-state thing, we check if we are parsing
- headers at the moment or not. */
- if (k->header) {
- /* we are in parse-the-header-mode */
- bool stop_reading = FALSE;
-
- /* header line within buffer loop */
- do {
- size_t hbufp_index;
- size_t rest_length;
- size_t full_length;
- int writetype;
-
- /* str_start is start of line within buf */
- k->str_start = k->str;
-
- /* data is in network encoding so use 0x0a instead of '\n' */
- k->end_ptr = memchr(k->str_start, 0x0a, nread);
-
- if (!k->end_ptr) {
- /* Not a complete header line within buffer, append the data to
- the end of the headerbuff. */
-
- if (k->hbuflen + nread >= data->state.headersize) {
- /* We enlarge the header buffer as it is too small */
- char *newbuff;
- size_t newsize=CURLMAX((k->hbuflen+nread)*3/2,
- data->state.headersize*2);
- hbufp_index = k->hbufp - data->state.headerbuff;
- newbuff = (char *)realloc(data->state.headerbuff, newsize);
- if(!newbuff) {
- failf (data, "Failed to alloc memory for big header!");
- return CURLE_OUT_OF_MEMORY;
- }
- data->state.headersize=newsize;
- data->state.headerbuff = newbuff;
- k->hbufp = data->state.headerbuff + hbufp_index;
- }
- memcpy(k->hbufp, k->str, nread);
- k->hbufp += nread;
- k->hbuflen += nread;
- if (!k->headerline && (k->hbuflen>5)) {
- /* make a first check that this looks like a HTTP header */
- if(!checkhttpprefix(data, data->state.headerbuff)) {
- /* this is not the beginning of a HTTP first header line */
- k->header = FALSE;
- k->badheader = HEADER_ALLBAD;
- break;
- }
- }
-
- break; /* read more and try again */
- }
-
- /* decrease the size of the remaining (supposed) header line */
- rest_length = (k->end_ptr - k->str)+1;
- nread -= (ssize_t)rest_length;
-
- k->str = k->end_ptr + 1; /* move past new line */
-
- full_length = k->str - k->str_start;
-
- /*
- * We're about to copy a chunk of data to the end of the
- * already received header. We make sure that the full string
- * fit in the allocated header buffer, or else we enlarge
- * it.
- */
- if (k->hbuflen + full_length >=
- data->state.headersize) {
- char *newbuff;
- size_t newsize=CURLMAX((k->hbuflen+full_length)*3/2,
- data->state.headersize*2);
- hbufp_index = k->hbufp - data->state.headerbuff;
- newbuff = (char *)realloc(data->state.headerbuff, newsize);
- if(!newbuff) {
- failf (data, "Failed to alloc memory for big header!");
- return CURLE_OUT_OF_MEMORY;
- }
- data->state.headersize= newsize;
- data->state.headerbuff = newbuff;
- k->hbufp = data->state.headerbuff + hbufp_index;
- }
-
- /* copy to end of line */
- memcpy(k->hbufp, k->str_start, full_length);
- k->hbufp += full_length;
- k->hbuflen += full_length;
- *k->hbufp = 0;
- k->end_ptr = k->hbufp;
-
- k->p = data->state.headerbuff;
-
- /****
- * We now have a FULL header line that p points to
- *****/
-
- if(!k->headerline) {
- /* the first read header */
- if((k->hbuflen>5) &&
- !checkhttpprefix(data, data->state.headerbuff)) {
- /* this is not the beginning of a HTTP first header line */
- k->header = FALSE;
- if(nread)
- /* since there's more, this is a partial bad header */
- k->badheader = HEADER_PARTHEADER;
- else {
- /* this was all we read so its all a bad header */
- k->badheader = HEADER_ALLBAD;
- nread = (ssize_t)rest_length;
- }
- break;
- }
- }
-
- /* headers are in network encoding so
- use 0x0a and 0x0d instead of '\n' and '\r' */
- if ((0x0a == *k->p) || (0x0d == *k->p)) {
- size_t headerlen;
- /* Zero-length header line means end of headers! */
-
-#ifdef CURL_DOES_CONVERSIONS
- if (0x0d == *k->p) {
- *k->p = '\r'; /* replace with CR in host encoding */
- k->p++; /* pass the CR byte */
- }
- if (0x0a == *k->p) {
- *k->p = '\n'; /* replace with LF in host encoding */
- k->p++; /* pass the LF byte */
- }
-#else
- if ('\r' == *k->p)
- k->p++; /* pass the \r byte */
- if ('\n' == *k->p)
- k->p++; /* pass the \n byte */
-#endif /* CURL_DOES_CONVERSIONS */
-
- if(100 == k->httpcode) {
- /*
- * We have made a HTTP PUT or POST and this is 1.1-lingo
- * that tells us that the server is OK with this and ready
- * to receive the data.
- * However, we'll get more headers now so we must get
- * back into the header-parsing state!
- */
- k->header = TRUE;
- k->headerline = 0; /* restart the header line counter */
- /* if we did wait for this do enable write now! */
- if (k->write_after_100_header) {
-
- k->write_after_100_header = FALSE;
- k->keepon |= KEEP_WRITE;
- }
- }
- else {
- k->header = FALSE; /* no more header to parse! */
-
- if((k->size == -1) && !conn->bits.chunk && !conn->bits.close)
- /* When connection is not to get closed, but no
- Content-Length nor Content-Encoding chunked have been
- received, there is no body in this response. We don't set
- stop_reading TRUE since that would also prevent necessary
- authentication actions to take place. */
- conn->bits.no_body = TRUE;
-
- }
-
- if (417 == k->httpcode) {
- /*
- * we got: "417 Expectation Failed" this means:
- * we have made a HTTP call and our Expect Header
- * seems to cause a problem => abort the write operations
- * (or prevent them from starting).
- */
- k->write_after_100_header = FALSE;
- k->keepon &= ~KEEP_WRITE;
- }
-
-#ifndef CURL_DISABLE_HTTP
- /*
- * When all the headers have been parsed, see if we should give
- * up and return an error.
- */
- if (Curl_http_should_fail(conn)) {
- failf (data, "The requested URL returned error: %d",
- k->httpcode);
- return CURLE_HTTP_RETURNED_ERROR;
- }
-#endif /* CURL_DISABLE_HTTP */
-
- /* now, only output this if the header AND body are requested:
- */
- writetype = CLIENTWRITE_HEADER;
- if (data->set.include_header)
- writetype |= CLIENTWRITE_BODY;
-
- headerlen = k->p - data->state.headerbuff;
-
- result = Curl_client_write(conn, writetype,
- data->state.headerbuff,
- headerlen);
- if(result)
- return result;
-
- data->info.header_size += (long)headerlen;
- conn->headerbytecount += (long)headerlen;
-
- conn->deductheadercount =
- (100 == k->httpcode)?conn->headerbytecount:0;
-
- if (data->reqdata.resume_from &&
- (data->set.httpreq==HTTPREQ_GET) &&
- (k->httpcode == 416)) {
- /* "Requested Range Not Satisfiable" */
- stop_reading = TRUE;
- }
-
-#ifndef CURL_DISABLE_HTTP
- if(!stop_reading) {
- /* Curl_http_auth_act() checks what authentication methods
- * that are available and decides which one (if any) to
- * use. It will set 'newurl' if an auth metod was picked. */
- result = Curl_http_auth_act(conn);
-
- if(result)
- return result;
-
- if(conn->bits.rewindaftersend) {
- /* We rewind after a complete send, so thus we continue
- sending now */
- infof(data, "Keep sending data to get tossed away!\n");
- k->keepon |= KEEP_WRITE;
- }
- }
-#endif /* CURL_DISABLE_HTTP */
-
- if(!k->header) {
- /*
- * really end-of-headers.
- *
- * If we requested a "no body", this is a good time to get
- * out and return home.
- */
- if(conn->bits.no_body)
- stop_reading = TRUE;
- else {
- /* If we know the expected size of this document, we set the
- maximum download size to the size of the expected
- document or else, we won't know when to stop reading!
-
- Note that we set the download maximum even if we read a
- "Connection: close" header, to make sure that
- "Content-Length: 0" still prevents us from attempting to
- read the (missing) response-body.
- */
- /* According to RFC2616 section 4.4, we MUST ignore
- Content-Length: headers if we are now receiving data
- using chunked Transfer-Encoding.
- */
- if(conn->bits.chunk)
- k->size=-1;
-
- }
- if(-1 != k->size) {
- /* We do this operation even if no_body is true, since this
- data might be retrieved later with curl_easy_getinfo()
- and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
-
- Curl_pgrsSetDownloadSize(data, k->size);
- k->maxdownload = k->size;
- }
- /* If max download size is *zero* (nothing) we already
- have nothing and can safely return ok now! */
- if(0 == k->maxdownload)
- stop_reading = TRUE;
-
- if(stop_reading) {
- /* we make sure that this socket isn't read more now */
- k->keepon &= ~KEEP_READ;
- }
-
- break; /* exit header line loop */
- }
-
- /* We continue reading headers, so reset the line-based
- header parsing variables hbufp && hbuflen */
- k->hbufp = data->state.headerbuff;
- k->hbuflen = 0;
- continue;
- }
-
- /*
- * Checks for special headers coming up.
- */
-
- if (!k->headerline++) {
- /* This is the first header, it MUST be the error code line
- or else we consider this to be the body right away! */
- int httpversion_major;
- int nc;
-#ifdef CURL_DOES_CONVERSIONS
-#define HEADER1 scratch
-#define SCRATCHSIZE 21
- CURLcode res;
- char scratch[SCRATCHSIZE+1]; /* "HTTP/major.minor 123" */
- /* We can't really convert this yet because we
- don't know if it's the 1st header line or the body.
- So we do a partial conversion into a scratch area,
- leaving the data at k->p as-is.
- */
- strncpy(&scratch[0], k->p, SCRATCHSIZE);
- scratch[SCRATCHSIZE] = 0; /* null terminate */
- res = Curl_convert_from_network(data,
- &scratch[0],
- SCRATCHSIZE);
- if (CURLE_OK != res) {
- /* Curl_convert_from_network calls failf if unsuccessful */
- return res;
- }
-#else
-#define HEADER1 k->p /* no conversion needed, just use k->p */
-#endif /* CURL_DOES_CONVERSIONS */
-
- nc = sscanf(HEADER1,
- " HTTP/%d.%d %3d",
- &httpversion_major,
- &k->httpversion,
- &k->httpcode);
- if (nc==3) {
- k->httpversion += 10 * httpversion_major;
- }
- else {
- /* this is the real world, not a Nirvana
- NCSA 1.5.x returns this crap when asked for HTTP/1.1
- */
- nc=sscanf(HEADER1, " HTTP %3d", &k->httpcode);
- k->httpversion = 10;
-
- /* If user has set option HTTP200ALIASES,
- compare header line against list of aliases
- */
- if (!nc) {
- if (checkhttpprefix(data, k->p)) {
- nc = 1;
- k->httpcode = 200;
- k->httpversion =
- (data->set.httpversion==CURL_HTTP_VERSION_1_0)? 10 : 11;
- }
- }
- }
-
- if (nc) {
- data->info.httpcode = k->httpcode;
- data->info.httpversion = k->httpversion;
-
- /*
- * This code executes as part of processing the header. As a
- * result, it's not totally clear how to interpret the
- * response code yet as that depends on what other headers may
- * be present. 401 and 407 may be errors, but may be OK
- * depending on how authentication is working. Other codes
- * are definitely errors, so give up here.
- */
- if (data->set.http_fail_on_error && (k->httpcode >= 400) &&
- ((k->httpcode != 401) || !data->set.userpwd) &&
- ((k->httpcode != 407) || !data->set.proxyuserpwd) ) {
-
- if (data->reqdata.resume_from &&
- (data->set.httpreq==HTTPREQ_GET) &&
- (k->httpcode == 416)) {
- /* "Requested Range Not Satisfiable", just proceed and
- pretend this is no error */
- }
- else {
- /* serious error, go home! */
- failf (data, "The requested URL returned error: %d",
- k->httpcode);
- return CURLE_HTTP_RETURNED_ERROR;
- }
- }
-
- if(k->httpversion == 10)
- /* Default action for HTTP/1.0 must be to close, unless
- we get one of those fancy headers that tell us the
- server keeps it open for us! */
- conn->bits.close = TRUE;
-
- switch(k->httpcode) {
- case 204:
- /* (quote from RFC2616, section 10.2.5): The server has
- * fulfilled the request but does not need to return an
- * entity-body ... The 204 response MUST NOT include a
- * message-body, and thus is always terminated by the first
- * empty line after the header fields. */
- /* FALLTHROUGH */
- case 416: /* Requested Range Not Satisfiable, it has the
- Content-Length: set as the "real" document but no
- actual response is sent. */
- case 304:
- /* (quote from RFC2616, section 10.3.5): The 304 response
- * MUST NOT contain a message-body, and thus is always
- * terminated by the first empty line after the header
- * fields. */
- k->size=0;
- k->maxdownload=0;
- k->ignorecl = TRUE; /* ignore Content-Length headers */
- break;
- default:
- /* nothing */
- break;
- }
- }
- else {
- k->header = FALSE; /* this is not a header line */
- break;
- }
- }
-
-#ifdef CURL_DOES_CONVERSIONS
- /* convert from the network encoding */
- result = Curl_convert_from_network(data, k->p, strlen(k->p));
- if (CURLE_OK != result) {
- return(result);
- }
- /* Curl_convert_from_network calls failf if unsuccessful */
-#endif /* CURL_DOES_CONVERSIONS */
-
- /* Check for Content-Length: header lines to get size. Ignore
- the header completely if we get a 416 response as then we're
- resuming a document that we don't get, and this header contains
- info about the true size of the document we didn't get now. */
- if (!k->ignorecl && !data->set.ignorecl &&
- checkprefix("Content-Length:", k->p)) {
- contentlength = curlx_strtoofft(k->p+15, NULL, 10);
- if (data->set.max_filesize &&
- contentlength > data->set.max_filesize) {
- failf(data, "Maximum file size exceeded");
- return CURLE_FILESIZE_EXCEEDED;
- }
- if(contentlength >= 0) {
- k->size = contentlength;
- k->maxdownload = k->size;
- }
- else {
- /* Negative Content-Length is really odd, and we know it
- happens for example when older Apache servers send large
- files */
- conn->bits.close = TRUE;
- infof(data, "Negative content-length: %" FORMAT_OFF_T
- ", closing after transfer\n", contentlength);
- }
- }
- /* check for Content-Type: header lines to get the mime-type */
- else if (checkprefix("Content-Type:", k->p)) {
- char *start;
- char *end;
- size_t len;
-
- /* Find the first non-space letter */
- for(start=k->p+13;
- *start && ISSPACE(*start);
- start++)
- ; /* empty loop */
-
- /* data is now in the host encoding so
- use '\r' and '\n' instead of 0x0d and 0x0a */
- end = strchr(start, '\r');
- if(!end)
- end = strchr(start, '\n');
-
- if(end) {
- /* skip all trailing space letters */
- for(; ISSPACE(*end) && (end > start); end--)
- ; /* empty loop */
-
- /* get length of the type */
- len = end-start+1;
-
- /* allocate memory of a cloned copy */
- Curl_safefree(data->info.contenttype);
-
- data->info.contenttype = malloc(len + 1);
- if (NULL == data->info.contenttype)
- return CURLE_OUT_OF_MEMORY;
-
- /* copy the content-type string */
- memcpy(data->info.contenttype, start, len);
- data->info.contenttype[len] = 0; /* zero terminate */
- }
- }
-#ifndef CURL_DISABLE_HTTP
- else if((k->httpversion == 10) &&
- conn->bits.httpproxy &&
- Curl_compareheader(k->p,
- "Proxy-Connection:", "keep-alive")) {
- /*
- * When a HTTP/1.0 reply comes when using a proxy, the
- * 'Proxy-Connection: keep-alive' line tells us the
- * connection will be kept alive for our pleasure.
- * Default action for 1.0 is to close.
- */
- conn->bits.close = FALSE; /* don't close when done */
- infof(data, "HTTP/1.0 proxy connection set to keep alive!\n");
- }
- else if((k->httpversion == 11) &&
- conn->bits.httpproxy &&
- Curl_compareheader(k->p,
- "Proxy-Connection:", "close")) {
- /*
- * We get a HTTP/1.1 response from a proxy and it says it'll
- * close down after this transfer.
- */
- conn->bits.close = TRUE; /* close when done */
- infof(data, "HTTP/1.1 proxy connection set close!\n");
- }
- else if((k->httpversion == 10) &&
- Curl_compareheader(k->p, "Connection:", "keep-alive")) {
- /*
- * A HTTP/1.0 reply with the 'Connection: keep-alive' line
- * tells us the connection will be kept alive for our
- * pleasure. Default action for 1.0 is to close.
- *
- * [RFC2068, section 19.7.1] */
- conn->bits.close = FALSE; /* don't close when done */
- infof(data, "HTTP/1.0 connection set to keep alive!\n");
- }
- else if (Curl_compareheader(k->p, "Connection:", "close")) {
- /*
- * [RFC 2616, section 8.1.2.1]
- * "Connection: close" is HTTP/1.1 language and means that
- * the connection will close when this request has been
- * served.
- */
- conn->bits.close = TRUE; /* close when done */
- }
- else if (Curl_compareheader(k->p,
- "Transfer-Encoding:", "chunked")) {
- /*
- * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
- * means that the server will send a series of "chunks". Each
- * chunk starts with line with info (including size of the
- * coming block) (terminated with CRLF), then a block of data
- * with the previously mentioned size. There can be any amount
- * of chunks, and a chunk-data set to zero signals the
- * end-of-chunks. */
- conn->bits.chunk = TRUE; /* chunks coming our way */
-
- /* init our chunky engine */
- Curl_httpchunk_init(conn);
- }
-
- else if (checkprefix("Trailer:", k->p) ||
- checkprefix("Trailers:", k->p)) {
- /*
- * This test helps Curl_httpchunk_read() to determine to look
- * for well formed trailers after the zero chunksize record. In
- * this case a CRLF is required after the zero chunksize record
- * when no trailers are sent, or after the last trailer record.
- *
- * It seems both Trailer: and Trailers: occur in the wild.
- */
- conn->bits.trailerHdrPresent = TRUE;
- }
-
- else if (checkprefix("Content-Encoding:", k->p) &&
- data->set.encoding) {
- /*
- * Process Content-Encoding. Look for the values: identity,
- * gzip, deflate, compress, x-gzip and x-compress. x-gzip and
- * x-compress are the same as gzip and compress. (Sec 3.5 RFC
- * 2616). zlib cannot handle compress. However, errors are
- * handled further down when the response body is processed
- */
- char *start;
-
- /* Find the first non-space letter */
- for(start=k->p+17;
- *start && ISSPACE(*start);
- start++)
- ; /* empty loop */
-
- /* Record the content-encoding for later use */
- if (checkprefix("identity", start))
- k->content_encoding = IDENTITY;
- else if (checkprefix("deflate", start))
- k->content_encoding = DEFLATE;
- else if (checkprefix("gzip", start)
- || checkprefix("x-gzip", start))
- k->content_encoding = GZIP;
- else if (checkprefix("compress", start)
- || checkprefix("x-compress", start))
- k->content_encoding = COMPRESS;
- }
- else if (checkprefix("Content-Range:", k->p)) {
- /* Content-Range: bytes [num]-
- Content-Range: bytes: [num]-
- Content-Range: [num]-
-
- The second format was added since Sun's webserver
- JavaWebServer/1.1.1 obviously sends the header this way!
- The third added since some servers use that!
- */
-
- char *ptr = k->p + 14;
-
- /* Move forward until first digit */
- while(*ptr && !ISDIGIT(*ptr))
- ptr++;
-
- k->offset = curlx_strtoofft(ptr, NULL, 10);
-
- if (data->reqdata.resume_from == k->offset)
- /* we asked for a resume and we got it */
- k->content_range = TRUE;
- }
-#if !defined(CURL_DISABLE_COOKIES)
- else if(data->cookies &&
- checkprefix("Set-Cookie:", k->p)) {
- Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
- CURL_LOCK_ACCESS_SINGLE);
- Curl_cookie_add(data,
- data->cookies, TRUE, k->p+11,
- /* If there is a custom-set Host: name, use it
- here, or else use real peer host name. */
- conn->allocptr.cookiehost?
- conn->allocptr.cookiehost:conn->host.name,
- data->reqdata.path);
- Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
- }
-#endif
- else if(checkprefix("Last-Modified:", k->p) &&
- (data->set.timecondition || data->set.get_filetime) ) {
- time_t secs=time(NULL);
- k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
- &secs);
- if(data->set.get_filetime)
- data->info.filetime = (long)k->timeofdoc;
- }
- else if((checkprefix("WWW-Authenticate:", k->p) &&
- (401 == k->httpcode)) ||
- (checkprefix("Proxy-authenticate:", k->p) &&
- (407 == k->httpcode))) {
- result = Curl_http_input_auth(conn, k->httpcode, k->p);
- if(result)
- return result;
- }
- else if ((k->httpcode >= 300 && k->httpcode < 400) &&
- checkprefix("Location:", k->p)) {
- if(data->set.http_follow_location) {
- /* this is the URL that the server advices us to get instead */
- char *ptr;
- char *start=k->p;
- char backup;
-
- start += 9; /* pass "Location:" */
-
- /* Skip spaces and tabs. We do this to support multiple
- white spaces after the "Location:" keyword. */
- while(*start && ISSPACE(*start ))
- start++;
-
- /* Scan through the string from the end to find the last
- non-space. k->end_ptr points to the actual terminating zero
- letter, move pointer one letter back and start from
- there. This logic strips off trailing whitespace, but keeps
- any embedded whitespace. */
- ptr = k->end_ptr-1;
- while((ptr>=start) && ISSPACE(*ptr))
- ptr--;
- ptr++;
-
- backup = *ptr; /* store the ending letter */
- if(ptr != start) {
- *ptr = '\0'; /* zero terminate */
- data->reqdata.newurl = strdup(start); /* clone string */
- *ptr = backup; /* restore ending letter */
- if(!data->reqdata.newurl)
- return CURLE_OUT_OF_MEMORY;
- }
- }
- }
-#endif /* CURL_DISABLE_HTTP */
-
- /*
- * End of header-checks. Write them to the client.
- */
-
- writetype = CLIENTWRITE_HEADER;
- if (data->set.include_header)
- writetype |= CLIENTWRITE_BODY;
-
- if(data->set.verbose)
- Curl_debug(data, CURLINFO_HEADER_IN,
- k->p, (size_t)k->hbuflen, conn);
-
- result = Curl_client_write(conn, writetype, k->p, k->hbuflen);
- if(result)
- return result;
-
- data->info.header_size += (long)k->hbuflen;
- conn->headerbytecount += (long)k->hbuflen;
-
- /* reset hbufp pointer && hbuflen */
- k->hbufp = data->state.headerbuff;
- k->hbuflen = 0;
- }
- while (!stop_reading && *k->str); /* header line within buffer */
-
- if(stop_reading)
- /* We've stopped dealing with input, get out of the do-while loop */
- break;
-
- /* We might have reached the end of the header part here, but
- there might be a non-header part left in the end of the read
- buffer. */
-
- } /* end if header mode */
-
- /* This is not an 'else if' since it may be a rest from the header
- parsing, where the beginning of the buffer is headers and the end
- is non-headers. */
- if (k->str && !k->header && (nread > 0 || is_empty_data)) {
-
- if(0 == k->bodywrites && !is_empty_data) {
- /* These checks are only made the first time we are about to
- write a piece of the body */
- if(conn->protocol&PROT_HTTP) {
- /* HTTP-only checks */
-
- if (data->reqdata.newurl) {
- if(conn->bits.close) {
- /* Abort after the headers if "follow Location" is set
- and we're set to close anyway. */
- k->keepon &= ~KEEP_READ;
- *done = TRUE;
- return CURLE_OK;
- }
- /* We have a new url to load, but since we want to be able
- to re-use this connection properly, we read the full
- response in "ignore more" */
- k->ignorebody = TRUE;
- infof(data, "Ignoring the response-body\n");
- }
- if (data->reqdata.resume_from && !k->content_range &&
- (data->set.httpreq==HTTPREQ_GET) &&
- !k->ignorebody) {
- /* we wanted to resume a download, although the server doesn't
- * seem to support this and we did this with a GET (if it
- * wasn't a GET we did a POST or PUT resume) */
- failf(data, "HTTP server doesn't seem to support "
- "byte ranges. Cannot resume.");
- return CURLE_HTTP_RANGE_ERROR;
- }
-
- if(data->set.timecondition && !data->reqdata.range) {
- /* A time condition has been set AND no ranges have been
- requested. This seems to be what chapter 13.3.4 of
- RFC 2616 defines to be the correct action for a
- HTTP/1.1 client */
- if((k->timeofdoc > 0) && (data->set.timevalue > 0)) {
- switch(data->set.timecondition) {
- case CURL_TIMECOND_IFMODSINCE:
- default:
- if(k->timeofdoc < data->set.timevalue) {
- infof(data,
- "The requested document is not new enough\n");
- *done = TRUE;
- return CURLE_OK;
- }
- break;
- case CURL_TIMECOND_IFUNMODSINCE:
- if(k->timeofdoc > data->set.timevalue) {
- infof(data,
- "The requested document is not old enough\n");
- *done = TRUE;
- return CURLE_OK;
- }
- break;
- } /* switch */
- } /* two valid time strings */
- } /* we have a time condition */
-
- } /* this is HTTP */
- } /* this is the first time we write a body part */
- k->bodywrites++;
-
- /* pass data to the debug function before it gets "dechunked" */
- if(data->set.verbose) {
- if(k->badheader) {
- Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff,
- (size_t)k->hbuflen, conn);
- if(k->badheader == HEADER_PARTHEADER)
- Curl_debug(data, CURLINFO_DATA_IN,
- k->str, (size_t)nread, conn);
- }
- else
- Curl_debug(data, CURLINFO_DATA_IN,
- k->str, (size_t)nread, conn);
- }
-
-#ifndef CURL_DISABLE_HTTP
- if(conn->bits.chunk) {
- /*
- * Bless me father for I have sinned. Here comes a chunked
- * transfer flying and we need to decode this properly. While
- * the name says read, this function both reads and writes away
- * the data. The returned 'nread' holds the number of actual
- * data it wrote to the client. */
-
- CHUNKcode res =
- Curl_httpchunk_read(conn, k->str, nread, &nread);
-
- if(CHUNKE_OK < res) {
- if(CHUNKE_WRITE_ERROR == res) {
- failf(data, "Failed writing data");
- return CURLE_WRITE_ERROR;
- }
- failf(data, "Received problem %d in the chunky parser", res);
- return CURLE_RECV_ERROR;
- }
- else if(CHUNKE_STOP == res) {
- /* we're done reading chunks! */
- k->keepon &= ~KEEP_READ; /* read no more */
-
- /* There are now possibly N number of bytes at the end of the
- str buffer that weren't written to the client, but we don't
- care about them right now. */
- }
- /* If it returned OK, we just keep going */
- }
-#endif /* CURL_DISABLE_HTTP */
-
- if((-1 != k->maxdownload) &&
- (k->bytecount + nread >= k->maxdownload)) {
- /* The 'excess' amount below can't be more than BUFSIZE which
- always will fit in a size_t */
- size_t excess = (size_t)(k->bytecount + nread - k->maxdownload);
- if (excess > 0 && !k->ignorebody) {
- infof(data,
- "Rewinding stream by : %d"
- " bytes on url %s (size = %" FORMAT_OFF_T
- ", maxdownload = %" FORMAT_OFF_T
- ", bytecount = %" FORMAT_OFF_T ", nread = %d)\n",
- excess, conn->data->reqdata.path,
- k->size, k->maxdownload, k->bytecount, nread);
- read_rewind(conn, excess);
- }
-
- nread = (ssize_t) (k->maxdownload - k->bytecount);
- if(nread < 0 ) /* this should be unusual */
- nread = 0;
-
- k->keepon &= ~KEEP_READ; /* we're done reading */
- }
-
- k->bytecount += nread;
-
- Curl_pgrsSetDownloadCounter(data, k->bytecount);
-
- if(!conn->bits.chunk && (nread || k->badheader || is_empty_data)) {
- /* If this is chunky transfer, it was already written */
-
- if(k->badheader && !k->ignorebody) {
- /* we parsed a piece of data wrongly assuming it was a header
- and now we output it as body instead */
- result = Curl_client_write(conn, CLIENTWRITE_BODY,
- data->state.headerbuff,
- k->hbuflen);
- if(result)
- return result;
- }
- if(k->badheader < HEADER_ALLBAD) {
- /* This switch handles various content encodings. If there's an
- error here, be sure to check over the almost identical code
- in http_chunks.c.
- Make sure that ALL_CONTENT_ENCODINGS contains all the
- encodings handled here. */
-#ifdef HAVE_LIBZ
- switch (k->content_encoding) {
- case IDENTITY:
-#endif
- /* This is the default when the server sends no
- Content-Encoding header. See Curl_readwrite_init; the
- memset() call initializes k->content_encoding to zero. */
- if(!k->ignorebody)
- result = Curl_client_write(conn, CLIENTWRITE_BODY, k->str,
- nread);
-#ifdef HAVE_LIBZ
- break;
-
- case DEFLATE:
- /* Assume CLIENTWRITE_BODY; headers are not encoded. */
- if(!k->ignorebody)
- result = Curl_unencode_deflate_write(conn, k, nread);
- break;
-
- case GZIP:
- /* Assume CLIENTWRITE_BODY; headers are not encoded. */
- if(!k->ignorebody)
- result = Curl_unencode_gzip_write(conn, k, nread);
- break;
-
- case COMPRESS:
- default:
- failf (data, "Unrecognized content encoding type. "
- "libcurl understands `identity', `deflate' and `gzip' "
- "content encodings.");
- result = CURLE_BAD_CONTENT_ENCODING;
- break;
- }
-#endif
- }
- k->badheader = HEADER_NORMAL; /* taken care of now */
-
- if(result)
- return result;
- }
-
- } /* if (! header and data to read ) */
-
- if (is_empty_data) {
- /* if we received nothing, the server closed the connection and we
- are done */
- k->keepon &= ~KEEP_READ;
- }
-
- } while(data_pending(conn));
-
- } /* if( read from socket ) */
-
- /* If we still have writing to do, we check if we have a writable
- socket. */
- if((k->keepon & KEEP_WRITE) && (select_res & CSELECT_OUT)) {
- /* write */
-
- int i, si;
- ssize_t bytes_written;
- bool writedone=TRUE;
-
- if ((k->bytecount == 0) && (k->writebytecount == 0))
- Curl_pgrsTime(data, TIMER_STARTTRANSFER);
-
- didwhat |= KEEP_WRITE;
-
- /*
- * We loop here to do the READ and SEND loop until we run out of
- * data to send or until we get EWOULDBLOCK back
- */
- do {
-
- /* only read more data if there's no upload data already
- present in the upload buffer */
- if(0 == data->reqdata.upload_present) {
- /* init the "upload from here" pointer */
- data->reqdata.upload_fromhere = k->uploadbuf;
-
- if(!k->upload_done) {
- /* HTTP pollution, this should be written nicer to become more
- protocol agnostic. */
- int fillcount;
-
- if(k->wait100_after_headers &&
- (data->reqdata.proto.http->sending == HTTPSEND_BODY)) {
- /* If this call is to send body data, we must take some action:
- We have sent off the full HTTP 1.1 request, and we shall now
- go into the Expect: 100 state and await such a header */
- k->wait100_after_headers = FALSE; /* headers sent */
- k->write_after_100_header = TRUE; /* wait for the header */
- k->keepon &= ~KEEP_WRITE; /* disable writing */
- k->start100 = Curl_tvnow(); /* timeout count starts now */
- didwhat &= ~KEEP_WRITE; /* we didn't write anything actually */
- break;
- }
-
- result = Curl_fillreadbuffer(conn, BUFSIZE, &fillcount);
- if(result)
- return result;
-
- nread = (ssize_t)fillcount;
- }
- else
- nread = 0; /* we're done uploading/reading */
-
- /* the signed int typecase of nread of for systems that has
- unsigned size_t */
- if (nread<=0) {
- /* done */
- k->keepon &= ~KEEP_WRITE; /* we're done writing */
- writedone = TRUE;
-
- if(conn->bits.rewindaftersend) {
- result = Curl_readrewind(conn);
- if(result)
- return result;
- }
- break;
- }
-
- /* store number of bytes available for upload */
- data->reqdata.upload_present = nread;
-
- /* convert LF to CRLF if so asked */
-#ifdef CURL_DO_LINEEND_CONV
- /* always convert if we're FTPing in ASCII mode */
- if ((data->set.crlf) || (data->set.prefer_ascii)) {
-#else
- if (data->set.crlf) {
-#endif /* CURL_DO_LINEEND_CONV */
- if(data->state.scratch == NULL)
- data->state.scratch = malloc(2*BUFSIZE);
- if(data->state.scratch == NULL) {
- failf (data, "Failed to alloc scratch buffer!");
- return CURLE_OUT_OF_MEMORY;
- }
- /*
- * ASCII/EBCDIC Note: This is presumably a text (not binary)
- * transfer so the data should already be in ASCII.
- * That means the hex values for ASCII CR (0x0d) & LF (0x0a)
- * must be used instead of the escape sequences \r & \n.
- */
- for(i = 0, si = 0; i < nread; i++, si++) {
- if (data->reqdata.upload_fromhere[i] == 0x0a) {
- data->state.scratch[si++] = 0x0d;
- data->state.scratch[si] = 0x0a;
- if (!data->set.crlf) {
- /* we're here only because FTP is in ASCII mode...
- bump infilesize for the LF we just added */
- data->set.infilesize++;
- }
- }
- else
- data->state.scratch[si] = data->reqdata.upload_fromhere[i];
- }
- if(si != nread) {
- /* only perform the special operation if we really did replace
- anything */
- nread = si;
-
- /* upload from the new (replaced) buffer instead */
- data->reqdata.upload_fromhere = data->state.scratch;
-
- /* set the new amount too */
- data->reqdata.upload_present = nread;
- }
- }
- }
- else {
- /* We have a partial buffer left from a previous "round". Use
- that instead of reading more data */
- }
-
- /* write to socket (send away data) */
- result = Curl_write(conn,
- conn->writesockfd, /* socket to send to */
- data->reqdata.upload_fromhere, /* buffer pointer */
- data->reqdata.upload_present, /* buffer size */
- &bytes_written); /* actually send away */
- if(result)
- return result;
-
- if(data->set.verbose)
- /* show the data before we change the pointer upload_fromhere */
- Curl_debug(data, CURLINFO_DATA_OUT, data->reqdata.upload_fromhere,
- (size_t)bytes_written, conn);
-
- if(data->reqdata.upload_present != bytes_written) {
- /* we only wrote a part of the buffer (if anything), deal with it! */
-
- /* store the amount of bytes left in the buffer to write */
- data->reqdata.upload_present -= bytes_written;
-
- /* advance the pointer where to find the buffer when the next send
- is to happen */
- data->reqdata.upload_fromhere += bytes_written;
-
- writedone = TRUE; /* we are done, stop the loop */
- }
- else {
- /* we've uploaded that buffer now */
- data->reqdata.upload_fromhere = k->uploadbuf;
- data->reqdata.upload_present = 0; /* no more bytes left */
-
- if(k->upload_done) {
- /* switch off writing, we're done! */
- k->keepon &= ~KEEP_WRITE; /* we're done writing */
- writedone = TRUE;
- }
- }
-
- k->writebytecount += bytes_written;
- Curl_pgrsSetUploadCounter(data, k->writebytecount);
-
- } while(!writedone); /* loop until we're done writing! */
-
- }
-
- } while(0); /* just to break out from! */
-
- k->now = Curl_tvnow();
- if(didwhat) {
- /* Update read/write counters */
- if(k->bytecountp)
- *k->bytecountp = k->bytecount; /* read count */
- if(k->writebytecountp)
- *k->writebytecountp = k->writebytecount; /* write count */
- }
- else {
- /* no read no write, this is a timeout? */
- if (k->write_after_100_header) {
- /* This should allow some time for the header to arrive, but only a
- very short time as otherwise it'll be too much wasted times too
- often. */
-
- /* Quoting RFC2616, section "8.2.3 Use of the 100 (Continue) Status":
-
- Therefore, when a client sends this header field to an origin server
- (possibly via a proxy) from which it has never seen a 100 (Continue)
- status, the client SHOULD NOT wait for an indefinite period before
- sending the request body.
-
- */
-
- long ms = Curl_tvdiff(k->now, k->start100);
- if(ms > CURL_TIMEOUT_EXPECT_100) {
- /* we've waited long enough, continue anyway */
- k->write_after_100_header = FALSE;
- k->keepon |= KEEP_WRITE;
- }
- }
- }
-
- if(Curl_pgrsUpdate(conn))
- result = CURLE_ABORTED_BY_CALLBACK;
- else
- result = Curl_speedcheck(data, k->now);
- if (result)
- return result;
-
- if (data->set.timeout &&
- ((Curl_tvdiff(k->now, k->start)/1000) >= data->set.timeout)) {
- if (k->size != -1) {
- failf(data, "Operation timed out after %d seconds with %"
- FORMAT_OFF_T " out of %" FORMAT_OFF_T " bytes received",
- data->set.timeout, k->bytecount, k->size);
- } else {
- failf(data, "Operation timed out after %d seconds with %"
- FORMAT_OFF_T " bytes received",
- data->set.timeout, k->bytecount);
- }
- return CURLE_OPERATION_TIMEOUTED;
- }
-
- if(!k->keepon) {
- /*
- * The transfer has been performed. Just make some general checks before
- * returning.
- */
-
- if(!(conn->bits.no_body) && (k->size != -1) &&
- (k->bytecount != k->size) &&
-#ifdef CURL_DO_LINEEND_CONV
- /* Most FTP servers don't adjust their file SIZE response for CRLFs,
- so we'll check to see if the discrepancy can be explained
- by the number of CRLFs we've changed to LFs.
- */
- (k->bytecount != (k->size + data->state.crlf_conversions)) &&
-#endif /* CURL_DO_LINEEND_CONV */
- !data->reqdata.newurl) {
- failf(data, "transfer closed with %" FORMAT_OFF_T
- " bytes remaining to read",
- k->size - k->bytecount);
- return CURLE_PARTIAL_FILE;
- }
- else if(!(conn->bits.no_body) &&
- conn->bits.chunk &&
- (data->reqdata.proto.http->chunk.state != CHUNK_STOP)) {
- /*
- * In chunked mode, return an error if the connection is closed prior to
- * the empty (terminiating) chunk is read.
- *
- * The condition above used to check for
- * conn->proto.http->chunk.datasize != 0 which is true after reading
- * *any* chunk, not just the empty chunk.
- *
- */
- failf(data, "transfer closed with outstanding read data remaining");
- return CURLE_PARTIAL_FILE;
- }
- if(Curl_pgrsUpdate(conn))
- return CURLE_ABORTED_BY_CALLBACK;
- }
-
- /* Now update the "done" boolean we return */
- *done = (bool)(0 == (k->keepon&(KEEP_READ|KEEP_WRITE)));
-
- return CURLE_OK;
-}
-
-
-/*
- * Curl_readwrite_init() inits the readwrite session. This is inited each time for a
- * transfer, sometimes multiple times on the same SessionHandle
- */
-
-CURLcode Curl_readwrite_init(struct connectdata *conn)
-{
- struct SessionHandle *data = conn->data;
- struct Curl_transfer_keeper *k = &data->reqdata.keep;
-
- /* NB: the content encoding software depends on this initialization of
- Curl_transfer_keeper.*/
- memset(k, 0, sizeof(struct Curl_transfer_keeper));
-
- k->start = Curl_tvnow(); /* start time */
- k->now = k->start; /* current time is now */
- k->header = TRUE; /* assume header */
- k->httpversion = -1; /* unknown at this point */
-
- k->size = data->reqdata.size;
- k->maxdownload = data->reqdata.maxdownload;
- k->bytecountp = data->reqdata.bytecountp;
- k->writebytecountp = data->reqdata.writebytecountp;
-
- k->bytecount = 0;
-
- k->buf = data->state.buffer;
- k->uploadbuf = data->state.uploadbuffer;
- k->maxfd = (conn->sockfd>conn->writesockfd?
- conn->sockfd:conn->writesockfd)+1;
- k->hbufp = data->state.headerbuff;
- k->ignorebody=FALSE;
-
- Curl_pgrsTime(data, TIMER_PRETRANSFER);
- Curl_speedinit(data);
-
- Curl_pgrsSetUploadCounter(data, 0);
- Curl_pgrsSetDownloadCounter(data, 0);
-
- if (!conn->bits.getheader) {
- k->header = FALSE;
- if(k->size > 0)
- Curl_pgrsSetDownloadSize(data, k->size);
- }
- /* we want header and/or body, if neither then don't do this! */
- if(conn->bits.getheader || !conn->bits.no_body) {
-
- if(conn->sockfd != CURL_SOCKET_BAD) {
- k->keepon |= KEEP_READ;
- }
-
- if(conn->writesockfd != CURL_SOCKET_BAD) {
- /* HTTP 1.1 magic:
-
- Even if we require a 100-return code before uploading data, we might
- need to write data before that since the REQUEST may not have been
- finished sent off just yet.
-
- Thus, we must check if the request has been sent before we set the
- state info where we wait for the 100-return code
- */
- if (data->state.expect100header &&
- (data->reqdata.proto.http->sending == HTTPSEND_BODY)) {
- /* wait with write until we either got 100-continue or a timeout */
- k->write_after_100_header = TRUE;
- k->start100 = k->start;
- }
- else {
- if(data->state.expect100header)
- /* when we've sent off the rest of the headers, we must await a
- 100-continue */
- k->wait100_after_headers = TRUE;
- k->keepon |= KEEP_WRITE;
- }
- }
- }
-
- return CURLE_OK;
-}
-
-/*
- * Curl_single_getsock() gets called by the multi interface code when the app
- * has requested to get the sockets for the current connection. This function
- * will then be called once for every connection that the multi interface
- * keeps track of. This function will only be called for connections that are
- * in the proper state to have this information available.
- */
-int Curl_single_getsock(struct connectdata *conn,
- curl_socket_t *sock, /* points to numsocks number
- of sockets */
- int numsocks)
-{
- struct SessionHandle *data = conn->data;
- int bitmap = GETSOCK_BLANK;
- int index = 0;
-
- if(numsocks < 2)
- /* simple check but we might need two slots */
- return GETSOCK_BLANK;
-
- if(data->reqdata.keep.keepon & KEEP_READ) {
- bitmap |= GETSOCK_READSOCK(index);
- sock[index] = conn->sockfd;
- }
-
- if(data->reqdata.keep.keepon & KEEP_WRITE) {
-
- if((conn->sockfd != conn->writesockfd) ||
- !(data->reqdata.keep.keepon & KEEP_READ)) {
- /* only if they are not the same socket or we didn't have a readable
- one, we increase index */
- if(data->reqdata.keep.keepon & KEEP_READ)
- index++; /* increase index if we need two entries */
- sock[index] = conn->writesockfd;
- }
-
- bitmap |= GETSOCK_WRITESOCK(index);
- }
-
- return bitmap;
-}
-
-
-/*
- * Transfer()
- *
- * This function is what performs the actual transfer. It is capable of
- * doing both ways simultaneously.
- * The transfer must already have been setup by a call to Curl_setup_transfer().
- *
- * Note that headers are created in a preallocated buffer of a default size.
- * That buffer can be enlarged on demand, but it is never shrunken again.
- *
- * Parts of this function was once written by the friendly Mark Butler
- * <butlerm@xmission.com>.
- */
-
-static CURLcode
-Transfer(struct connectdata *conn)
-{
- CURLcode result;
- struct SessionHandle *data = conn->data;
- struct Curl_transfer_keeper *k = &data->reqdata.keep;
- bool done=FALSE;
-
- if(!(conn->protocol & PROT_FILE))
- /* Only do this if we are not transferring FILE:, since the file: treatment
- is different*/
- Curl_readwrite_init(conn);
-
- if((conn->sockfd == CURL_SOCKET_BAD) &&
- (conn->writesockfd == CURL_SOCKET_BAD))
- /* nothing to read, nothing to write, we're already OK! */
- return CURLE_OK;
-
- /* we want header and/or body, if neither then don't do this! */
- if(!conn->bits.getheader && conn->bits.no_body)
- return CURLE_OK;
-
- while (!done) {
- curl_socket_t fd_read;
- curl_socket_t fd_write;
-
- /* limit-rate logic: if speed exceeds threshold, then do not include fd in
- select set. The current speed is recalculated in each Curl_readwrite()
- call */
- if ((k->keepon & KEEP_WRITE) &&
- (!data->set.max_send_speed ||
- (data->progress.ulspeed < data->set.max_send_speed) )) {
- fd_write = conn->writesockfd;
- k->keepon &= ~KEEP_WRITE_HOLD;
- }
- else {
- fd_write = CURL_SOCKET_BAD;
- if(k->keepon & KEEP_WRITE)
- k->keepon |= KEEP_WRITE_HOLD; /* hold it */
- }
-
- if ((k->keepon & KEEP_READ) &&
- (!data->set.max_recv_speed ||
- (data->progress.dlspeed < data->set.max_recv_speed)) ) {
- fd_read = conn->sockfd;
- k->keepon &= ~KEEP_READ_HOLD;
- }
- else {
- fd_read = CURL_SOCKET_BAD;
- if(k->keepon & KEEP_READ)
- k->keepon |= KEEP_READ_HOLD; /* hold it */
- }
-
- /* The *_HOLD logic is necessary since even though there might be no
- traffic during the select interval, we still call Curl_readwrite() for
- the timeout case and if we limit transfer speed we must make sure that
- this function doesn't transfer anything while in HOLD status. */
-
- switch (Curl_select(fd_read, fd_write, 1000)) {
- case -1: /* select() error, stop reading */
-#ifdef EINTR
- /* The EINTR is not serious, and it seems you might get this more
- ofen when using the lib in a multi-threaded environment! */
- if(errno == EINTR)
- ;
- else
-#endif
- done = TRUE; /* no more read or write */
- continue;
- case 0: /* timeout */
- default: /* readable descriptors */
-
- result = Curl_readwrite(conn, &done);
- break;
- }
- if(result)
- return result;
-
- /* "done" signals to us if the transfer(s) are ready */
- }
-
- return CURLE_OK;
-}
-
-/*
- * Curl_pretransfer() is called immediately before a transfer starts.
- */
-CURLcode Curl_pretransfer(struct SessionHandle *data)
-{
- CURLcode res;
- if(!data->change.url) {
- /* we can't do anything wihout URL */
- failf(data, "No URL set!\n");
- return CURLE_URL_MALFORMAT;
- }
-
- /* Init the SSL session ID cache here. We do it here since we want to do it
- after the *_setopt() calls (that could change the size of the cache) but
- before any transfer takes place. */
- res = Curl_ssl_initsessions(data, data->set.ssl.numsessions);
- if(res)
- return res;
-
- data->set.followlocation=0; /* reset the location-follow counter */
- data->state.this_is_a_follow = FALSE; /* reset this */
- data->state.errorbuf = FALSE; /* no error has occurred */
-
- data->state.authproblem = FALSE;
- data->state.authhost.want = data->set.httpauth;
- data->state.authproxy.want = data->set.proxyauth;
-
- /* If there is a list of cookie files to read, do it now! */
- if(data->change.cookielist) {
- Curl_cookie_loadfiles(data);
- }
-
- /* Allow data->set.use_port to set which port to use. This needs to be
- * disabled for example when we follow Location: headers to URLs using
- * different ports! */
- data->state.allow_port = TRUE;
-
-#if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL)
- /*************************************************************
- * Tell signal handler to ignore SIGPIPE
- *************************************************************/
- if(!data->set.no_signal)
- data->state.prev_signal = signal(SIGPIPE, SIG_IGN);
-#endif
-
- Curl_initinfo(data); /* reset session-specific information "variables" */
- Curl_pgrsStartNow(data);
-
- return CURLE_OK;
-}
-
-/*
- * Curl_posttransfer() is called immediately after a transfer ends
- */
-CURLcode Curl_posttransfer(struct SessionHandle *data)
-{
-#if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL)
- /* restore the signal handler for SIGPIPE before we get back */
- if(!data->set.no_signal)
- signal(SIGPIPE, data->state.prev_signal);
-#else
- (void)data; /* unused parameter */
-#endif
-
- if(!(data->progress.flags & PGRS_HIDE) &&
- !data->progress.callback)
- /* only output if we don't use a progress callback and we're not hidden */
- fprintf(data->set.err, "\n");
-
- return CURLE_OK;
-}
-
-/*
- * strlen_url() returns the length of the given URL if the spaces within the
- * URL were properly URL encoded.
- */
-static int strlen_url(char *url)
-{
- char *ptr;
- int newlen=0;
- bool left=TRUE; /* left side of the ? */
-
- for(ptr=url; *ptr; ptr++) {
- switch(*ptr) {
- case '?':
- left=FALSE;
- default:
- newlen++;
- break;
- case ' ':
- if(left)
- newlen+=3;
- else
- newlen++;
- break;
- }
- }
- return newlen;
-}
-
-/* strcpy_url() copies a url to a output buffer and URL-encodes the spaces in
- * the source URL accordingly.
- */
-static void strcpy_url(char *output, char *url)
-{
- /* we must add this with whitespace-replacing */
- bool left=TRUE;
- char *iptr;
- char *optr = output;
- for(iptr = url; /* read from here */
- *iptr; /* until zero byte */
- iptr++) {
- switch(*iptr) {
- case '?':
- left=FALSE;
- default:
- *optr++=*iptr;
- break;
- case ' ':
- if(left) {
- *optr++='%'; /* add a '%' */
- *optr++='2'; /* add a '2' */
- *optr++='0'; /* add a '0' */
- }
- else
- *optr++='+'; /* add a '+' here */
- break;
- }
- }
- *optr=0; /* zero terminate output buffer */
-
-}
-
-/*
- * Curl_follow() handles the URL redirect magic. Pass in the 'newurl' string
- * as given by the remote server and set up the new URL to request.
- */
-CURLcode Curl_follow(struct SessionHandle *data,
- char *newurl, /* this 'newurl' is the Location: string,
- and it must be malloc()ed before passed
- here */
- bool retry) /* set TRUE if this is a request retry as
- opposed to a real redirect following */
-{
- /* Location: redirect */
- char prot[16]; /* URL protocol string storage */
- char letter; /* used for a silly sscanf */
- size_t newlen;
- char *newest;
-
- if(!retry) {
- if ((data->set.maxredirs != -1) &&
- (data->set.followlocation >= data->set.maxredirs)) {
- failf(data,"Maximum (%d) redirects followed", data->set.maxredirs);
- return CURLE_TOO_MANY_REDIRECTS;
- }
-
- /* mark the next request as a followed location: */
- data->state.this_is_a_follow = TRUE;
-
- data->set.followlocation++; /* count location-followers */
- }
-
- if(data->set.http_auto_referer) {
- /* We are asked to automatically set the previous URL as the
- referer when we get the next URL. We pick the ->url field,
- which may or may not be 100% correct */
-
- if(data->change.referer_alloc)
- /* If we already have an allocated referer, free this first */
- free(data->change.referer);
-
- data->change.referer = strdup(data->change.url);
- data->change.referer_alloc = TRUE; /* yes, free this later */
- }
-
- if(2 != sscanf(newurl, "%15[^?&/:]://%c", prot, &letter)) {
- /***
- *DANG* this is an RFC 2068 violation. The URL is supposed
- to be absolute and this doesn't seem to be that!
- ***
- Instead, we have to TRY to append this new path to the old URL
- to the right of the host part. Oh crap, this is doomed to cause
- problems in the future...
- */
- char *protsep;
- char *pathsep;
-
- char *useurl = newurl;
- size_t urllen;
-
- /* we must make our own copy of the URL to play with, as it may
- point to read-only data */
- char *url_clone=strdup(data->change.url);
-
- if(!url_clone)
- return CURLE_OUT_OF_MEMORY; /* skip out of this NOW */
-
- /* protsep points to the start of the host name */
- protsep=strstr(url_clone, "//");
- if(!protsep)
- protsep=url_clone;
- else
- protsep+=2; /* pass the slashes */
-
- if('/' != newurl[0]) {
- int level=0;
-
- /* First we need to find out if there's a ?-letter in the URL,
- and cut it and the right-side of that off */
- pathsep = strchr(protsep, '?');
- if(pathsep)
- *pathsep=0;
-
- /* we have a relative path to append to the last slash if
- there's one available */
- pathsep = strrchr(protsep, '/');
- if(pathsep)
- *pathsep=0;
-
- /* Check if there's any slash after the host name, and if so,
- remember that position instead */
- pathsep = strchr(protsep, '/');
- if(pathsep)
- protsep = pathsep+1;
- else
- protsep = NULL;
-
- /* now deal with one "./" or any amount of "../" in the newurl
- and act accordingly */
-
- if((useurl[0] == '.') && (useurl[1] == '/'))
- useurl+=2; /* just skip the "./" */
-
- while((useurl[0] == '.') &&
- (useurl[1] == '.') &&
- (useurl[2] == '/')) {
- level++;
- useurl+=3; /* pass the "../" */
- }
-
- if(protsep) {
- while(level--) {
- /* cut off one more level from the right of the original URL */
- pathsep = strrchr(protsep, '/');
- if(pathsep)
- *pathsep=0;
- else {
- *protsep=0;
- break;
- }
- }
- }
- }
- else {
- /* We got a new absolute path for this server, cut off from the
- first slash */
- pathsep = strchr(protsep, '/');
- if(pathsep) {
- /* When people use badly formatted URLs, such as
- "http://www.url.com?dir=/home/daniel" we must not use the first
- slash, if there's a ?-letter before it! */
- char *sep = strchr(protsep, '?');
- if(sep && (sep < pathsep))
- pathsep = sep;
- *pathsep=0;
- }
- else {
- /* There was no slash. Now, since we might be operating on a badly
- formatted URL, such as "http://www.url.com?id=2380" which doesn't
- use a slash separator as it is supposed to, we need to check for a
- ?-letter as well! */
- pathsep = strchr(protsep, '?');
- if(pathsep)
- *pathsep=0;
- }
- }
-
- /* If the new part contains a space, this is a mighty stupid redirect
- but we still make an effort to do "right". To the left of a '?'
- letter we replace each space with %20 while it is replaced with '+'
- on the right side of the '?' letter.
- */
- newlen = strlen_url(useurl);
-
- urllen = strlen(url_clone);
-
- newest=(char *)malloc( urllen + 1 + /* possible slash */
- newlen + 1 /* zero byte */);
-
- if(!newest) {
- free(url_clone); /* don't leak this */
- return CURLE_OUT_OF_MEMORY; /* go out from this */
- }
-
- /* copy over the root url part */
- memcpy(newest, url_clone, urllen);
-
- /* check if we need to append a slash */
- if(('/' == useurl[0]) || (protsep && !*protsep))
- ;
- else
- newest[urllen++]='/';
-
- /* then append the new piece on the right side */
- strcpy_url(&newest[urllen], useurl);
-
- free(newurl); /* newurl is the allocated pointer */
- free(url_clone);
- newurl = newest;
- }
- else {
- /* This is an absolute URL, don't allow the custom port number */
- data->state.allow_port = FALSE;
-
- if(strchr(newurl, ' ')) {
- /* This new URL contains at least one space, this is a mighty stupid
- redirect but we still make an effort to do "right". */
- newlen = strlen_url(newurl);
-
- newest = malloc(newlen+1); /* get memory for this */
- if(newest) {
- strcpy_url(newest, newurl); /* create a space-free URL */
-
- free(newurl); /* that was no good */
- newurl = newest; /* use this instead now */
- }
- }
-
- }
-
- if(data->change.url_alloc)
- free(data->change.url);
- else
- data->change.url_alloc = TRUE; /* the URL is allocated */
-
- data->change.url = newurl;
- newurl = NULL; /* don't free! */
-
- infof(data, "Issue another request to this URL: '%s'\n", data->change.url);
-
- /*
- * We get here when the HTTP code is 300-399 (and 401). We need to perform
- * differently based on exactly what return code there was.
- *
- * News from 7.10.6: we can also get here on a 401 or 407, in case we act on
- * a HTTP (proxy-) authentication scheme other than Basic.
- */
- switch(data->info.httpcode) {
- /* 401 - Act on a www-authentication, we keep on moving and do the
- Authorization: XXXX header in the HTTP request code snippet */
- /* 407 - Act on a proxy-authentication, we keep on moving and do the
- Proxy-Authorization: XXXX header in the HTTP request code snippet */
- /* 300 - Multiple Choices */
- /* 306 - Not used */
- /* 307 - Temporary Redirect */
- default: /* for all above (and the unknown ones) */
- /* Some codes are explicitly mentioned since I've checked RFC2616 and they
- * seem to be OK to POST to.
- */
- break;
- case 301: /* Moved Permanently */
- /* (quote from RFC2616, section 10.3.2):
- *
- * Note: When automatically redirecting a POST request after receiving a
- * 301 status code, some existing HTTP/1.0 user agents will erroneously
- * change it into a GET request.
- *
- * ----
- *
- * Warning: Because most of importants user agents do this obvious RFC2616
- * violation, many webservers expect this misbehavior. So these servers
- * often answers to a POST request with an error page. To be sure that
- * libcurl gets the page that most user agents would get, libcurl has to
- * force GET:
- */
- if( data->set.httpreq == HTTPREQ_POST
- || data->set.httpreq == HTTPREQ_POST_FORM) {
- infof(data,
- "Violate RFC 2616/10.3.2 and switch from POST to GET\n");
- data->set.httpreq = HTTPREQ_GET;
- }
- break;
- case 302: /* Found */
- /* (From 10.3.3)
-
- Note: RFC 1945 and RFC 2068 specify that the client is not allowed
- to change the method on the redirected request. However, most
- existing user agent implementations treat 302 as if it were a 303
- response, performing a GET on the Location field-value regardless
- of the original request method. The status codes 303 and 307 have
- been added for servers that wish to make unambiguously clear which
- kind of reaction is expected of the client.
-
- (From 10.3.4)
-
- Note: Many pre-HTTP/1.1 user agents do not understand the 303
- status. When interoperability with such clients is a concern, the
- 302 status code may be used instead, since most user agents react
- to a 302 response as described here for 303.
- */
- case 303: /* See Other */
- /* Disable both types of POSTs, since doing a second POST when
- * following isn't what anyone would want! */
- if(data->set.httpreq != HTTPREQ_GET) {
- data->set.httpreq = HTTPREQ_GET; /* enforce GET request */
- infof(data, "Disables POST, goes with %s\n",
- data->set.opt_no_body?"HEAD":"GET");
- }
- break;
- case 304: /* Not Modified */
- /* 304 means we did a conditional request and it was "Not modified".
- * We shouldn't get any Location: header in this response!
- */
- break;
- case 305: /* Use Proxy */
- /* (quote from RFC2616, section 10.3.6):
- * "The requested resource MUST be accessed through the proxy given
- * by the Location field. The Location field gives the URI of the
- * proxy. The recipient is expected to repeat this single request
- * via the proxy. 305 responses MUST only be generated by origin
- * servers."
- */
- break;
- }
- Curl_pgrsTime(data, TIMER_REDIRECT);
- Curl_pgrsResetTimes(data);
-
- return CURLE_OK;
-}
-
-static CURLcode
-Curl_connect_host(struct SessionHandle *data,
- struct connectdata **conn)
-{
- CURLcode res = CURLE_OK;
- int urlchanged = FALSE;
-
- do {
- bool async;
- bool protocol_done=TRUE; /* will be TRUE always since this is only used
- within the easy interface */
- Curl_pgrsTime(data, TIMER_STARTSINGLE);
- data->change.url_changed = FALSE;
- res = Curl_connect(data, conn, &async, &protocol_done);
-
- if((CURLE_OK == res) && async) {
- /* Now, if async is TRUE here, we need to wait for the name
- to resolve */
- res = Curl_wait_for_resolv(*conn, NULL);
- if(CURLE_OK == res)
- /* Resolved, continue with the connection */
- res = Curl_async_resolved(*conn, &protocol_done);
- else
- /* if we can't resolve, we kill this "connection" now */
- (void)Curl_disconnect(*conn);
- }
- if(res)
- break;
-
- /* If a callback (or something) has altered the URL we should use within
- the Curl_connect(), we detect it here and act as if we are redirected
- to the new URL */
- urlchanged = data->change.url_changed;
- if ((CURLE_OK == res) && urlchanged) {
- res = Curl_done(conn, res, FALSE);
- if(CURLE_OK == res) {
- char *gotourl = strdup(data->change.url);
- res = Curl_follow(data, gotourl, FALSE);
- if(res)
- free(gotourl);
- }
- }
- } while (urlchanged && res == CURLE_OK);
-
- return res;
-}
-
-/* Returns TRUE and sets '*url' if a request retry is wanted */
-bool Curl_retry_request(struct connectdata *conn,
- char **url)
-{
- bool retry = FALSE;
- struct SessionHandle *data = conn->data;
-
- if((data->reqdata.keep.bytecount+conn->headerbytecount == 0) &&
- conn->bits.reuse &&
- !conn->bits.no_body) {
- /* We got no data, we attempted to re-use a connection and yet we want a
- "body". This might happen if the connection was left alive when we were
- done using it before, but that was closed when we wanted to read from
- it again. Bad luck. Retry the same request on a fresh connect! */
- infof(conn->data, "Connection died, retrying a fresh connect\n");
- *url = strdup(conn->data->change.url);
-
- conn->bits.close = TRUE; /* close this connection */
- conn->bits.retry = TRUE; /* mark this as a connection we're about
- to retry. Marking it this way should
- prevent i.e HTTP transfers to return
- error just because nothing has been
- transfered! */
- retry = TRUE;
- }
-
- return retry;
-}
-
-/*
- * Curl_perform() is the internal high-level function that gets called by the
- * external curl_easy_perform() function. It inits, performs and cleans up a
- * single file transfer.
- */
-CURLcode Curl_perform(struct SessionHandle *data)
-{
- CURLcode res;
- CURLcode res2;
- struct connectdata *conn=NULL;
- char *newurl = NULL; /* possibly a new URL to follow to! */
- bool retry = FALSE;
-
- data->state.used_interface = Curl_if_easy;
-
- res = Curl_pretransfer(data);
- if(res)
- return res;
-
- /*
- * It is important that there is NO 'return' from this function at any other
- * place than falling down to the end of the function! This is because we
- * have cleanup stuff that must be done before we get back, and that is only
- * performed after this do-while loop.
- */
-
- do {
- res = Curl_connect_host(data, &conn); /* primary connection */
-
- if(res == CURLE_OK) {
- bool do_done;
- if(data->set.connect_only) {
- /* keep connection open for application to use the socket */
- conn->bits.close = FALSE;
- res = Curl_done(&conn, CURLE_OK, FALSE);
- break;
- }
- res = Curl_do(&conn, &do_done);
-
- if(res == CURLE_OK) {
- res = Transfer(conn); /* now fetch that URL please */
- if(res == CURLE_OK) {
- retry = Curl_retry_request(conn, &newurl);
-
- if(!retry)
- /*
- * We must duplicate the new URL here as the connection data may
- * be free()ed in the Curl_done() function.
- */
- newurl = data->reqdata.newurl?strdup(data->reqdata.newurl):NULL;
- }
- else {
- /* The transfer phase returned error, we mark the connection to get
- * closed to prevent being re-used. This is becasue we can't
- * possibly know if the connection is in a good shape or not now. */
- conn->bits.close = TRUE;
-
- if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) {
- /* if we failed anywhere, we must clean up the secondary socket if
- it was used */
- sclose(conn->sock[SECONDARYSOCKET]);
- conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
- }
- }
-
- /* Always run Curl_done(), even if some of the previous calls
- failed, but return the previous (original) error code */
- res2 = Curl_done(&conn, res, FALSE);
-
- if(CURLE_OK == res)
- res = res2;
- }
- else
- /* Curl_do() failed, clean up left-overs in the done-call */
- res2 = Curl_done(&conn, res, FALSE);
-
- /*
- * Important: 'conn' cannot be used here, since it may have been closed
- * in 'Curl_done' or other functions.
- */
-
- if((res == CURLE_OK) && newurl) {
- res = Curl_follow(data, newurl, retry);
- if(CURLE_OK == res) {
- newurl = NULL;
- continue;
- }
- }
- }
- break; /* it only reaches here when this shouldn't loop */
-
- } while(1); /* loop if Location: */
-
- if(newurl)
- free(newurl);
-
- if(res && !data->state.errorbuf) {
- /*
- * As an extra precaution: if no error string has been set and there was
- * an error, use the strerror() string or if things are so bad that not
- * even that is good, set a bad string that mentions the error code.
- */
- const char *str = curl_easy_strerror(res);
- if(!str)
- failf(data, "unspecified error %d", (int)res);
- else
- failf(data, "%s", str);
- }
-
- /* run post-transfer uncondionally, but don't clobber the return code if
- we already have an error code recorder */
- res2 = Curl_posttransfer(data);
- if(!res && res2)
- res = res2;
-
- return res;
-}
-
-/*
- * Curl_setup_transfer() is called to setup some basic properties for the
- * upcoming transfer.
- */
-CURLcode
-Curl_setup_transfer(
- struct connectdata *c_conn, /* connection data */
- int sockindex, /* socket index to read from or -1 */
- curl_off_t size, /* -1 if unknown at this point */
- bool getheader, /* TRUE if header parsing is wanted */
- curl_off_t *bytecountp, /* return number of bytes read or NULL */
- int writesockindex, /* socket index to write to, it may very
- well be the same we read from. -1
- disables */
- curl_off_t *writecountp /* return number of bytes written or
- NULL */
- )
-{
- struct connectdata *conn = (struct connectdata *)c_conn;
- struct SessionHandle *data = conn->data;
-
- if(!conn)
- return CURLE_BAD_FUNCTION_ARGUMENT;
-
- curlassert((sockindex <= 1) && (sockindex >= -1));
-
- /* now copy all input parameters */
- conn->sockfd = sockindex == -1 ?
- CURL_SOCKET_BAD : conn->sock[sockindex];
- conn->writesockfd = writesockindex == -1 ?
- CURL_SOCKET_BAD:conn->sock[writesockindex];
- conn->bits.getheader = getheader;
-
- data->reqdata.size = size;
- data->reqdata.bytecountp = bytecountp;
- data->reqdata.writebytecountp = writecountp;
-
- return CURLE_OK;
-}
diff --git a/Utilities/cmcurl/transfer.h b/Utilities/cmcurl/transfer.h
deleted file mode 100644
index 3c415cc72..000000000
--- a/Utilities/cmcurl/transfer.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef __TRANSFER_H
-#define __TRANSFER_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-CURLcode Curl_perform(struct SessionHandle *data);
-CURLcode Curl_pretransfer(struct SessionHandle *data);
-CURLcode Curl_second_connect(struct connectdata *conn);
-CURLcode Curl_posttransfer(struct SessionHandle *data);
-CURLcode Curl_follow(struct SessionHandle *data, char *newurl, bool retry);
-CURLcode Curl_readwrite(struct connectdata *conn, bool *done);
-int Curl_single_getsock(struct connectdata *conn,
- curl_socket_t *socks,
- int numsocks);
-CURLcode Curl_readwrite_init(struct connectdata *conn);
-CURLcode Curl_readrewind(struct connectdata *conn);
-CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp);
-bool Curl_retry_request(struct connectdata *conn, char **url);
-
-/* This sets up a forthcoming transfer */
-CURLcode
-Curl_setup_transfer (struct connectdata *data,
- int sockindex, /* socket index to read from or -1 */
- curl_off_t size, /* -1 if unknown at this point */
- bool getheader, /* TRUE if header parsing is wanted */
- curl_off_t *bytecountp, /* return number of bytes read */
- int writesockindex, /* socket index to write to, it may
- very well be the same we read from.
- -1 disables */
- curl_off_t *writecountp /* return number of bytes written */
-);
-#endif
diff --git a/Utilities/cmcurl/url.c b/Utilities/cmcurl/url.c
deleted file mode 100644
index da12231f1..000000000
--- a/Utilities/cmcurl/url.c
+++ /dev/null
@@ -1,4252 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-/* -- WIN32 approved -- */
-
-#include "setup.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <ctype.h>
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#include <errno.h>
-
-#ifdef WIN32
-#include <time.h>
-#include <io.h>
-#else
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#include <netinet/in.h>
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <netdb.h>
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_NET_IF_H
-#include <net/if.h>
-#endif
-#include <sys/ioctl.h>
-#include <signal.h>
-
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
-#ifdef VMS
-#include <in.h>
-#include <inet.h>
-#endif
-
-#ifdef HAVE_SETJMP_H
-#include <setjmp.h>
-#endif
-
-#ifndef HAVE_SOCKET
-#error "We can't compile without socket() support!"
-#endif
-#endif
-
-#ifdef USE_LIBIDN
-#include <idna.h>
-#include <tld.h>
-#include <stringprep.h>
-#ifdef HAVE_IDN_FREE_H
-#include <idn-free.h>
-#else
-void idn_free (void *ptr); /* prototype from idn-free.h, not provided by
- libidn 0.4.5's make install! */
-#endif
-#ifndef HAVE_IDN_FREE
-/* if idn_free() was not found in this version of libidn, use plain free()
- instead */
-#define idn_free(x) (free)(x)
-#endif
-#endif /* USE_LIBIDN */
-
-#include "urldata.h"
-#include "netrc.h"
-
-#include "formdata.h"
-#include "base64.h"
-#include "sslgen.h"
-#include "hostip.h"
-#include "transfer.h"
-#include "sendf.h"
-#include "progress.h"
-#include "cookie.h"
-#include "strequal.h"
-#include "strerror.h"
-#include "escape.h"
-#include "strtok.h"
-#include "share.h"
-#include "content_encoding.h"
-#include "http_digest.h"
-#include "http_negotiate.h"
-#include "select.h"
-#include "multiif.h"
-#include "easyif.h"
-
-/* And now for the protocols */
-#include "ftp.h"
-#include "dict.h"
-#include "telnet.h"
-#include "tftp.h"
-#include "http.h"
-#include "file.h"
-#include "ldap.h"
-#include "ssh.h"
-#include "url.h"
-#include "connect.h"
-#include "inet_ntop.h"
-#include "http_ntlm.h"
-#include "socks.h"
-#include <ca-bundle.h>
-
-#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
-#include "inet_ntoa_r.h"
-#endif
-
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-#ifdef HAVE_KRB4
-#include "krb4.h"
-#endif
-#include "memory.h"
-
-/* The last #include file should be: */
-#include "memdebug.h"
-
-/* Local static prototypes */
-static long ConnectionKillOne(struct SessionHandle *data);
-static bool ConnectionExists(struct SessionHandle *data,
- struct connectdata *needle,
- struct connectdata **usethis);
-static long ConnectionStore(struct SessionHandle *data,
- struct connectdata *conn);
-static bool IsPipeliningPossible(struct SessionHandle *handle);
-static bool IsPipeliningEnabled(struct SessionHandle *handle);
-static void conn_free(struct connectdata *conn);
-
-static void signalPipeClose(struct curl_llist *pipe);
-
-#define MAX_PIPELINE_LENGTH 5
-
-/*
- * We use this ZERO_NULL to avoid picky compiler warnings,
- * when assigning a NULL pointer to a function pointer var.
- */
-
-#define ZERO_NULL 0
-
-#ifndef USE_ARES
-/* not for ares builds */
-
-#ifndef WIN32
-/* not for WIN32 builds */
-
-#ifdef HAVE_SIGSETJMP
-extern sigjmp_buf curl_jmpenv;
-#endif
-
-#ifdef SIGALRM
-static
-RETSIGTYPE alarmfunc(int sig)
-{
- /* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */
- (void)sig;
-#ifdef HAVE_SIGSETJMP
- siglongjmp(curl_jmpenv, 1);
-#endif
- /*return;*/ /* not reahed, and has no effect anyway */
-}
-#endif /* SIGALRM */
-#endif /* WIN32 */
-#endif /* USE_ARES */
-
-void Curl_safefree(void *ptr)
-{
- if(ptr)
- free(ptr);
-}
-
-static void close_connections(struct SessionHandle *data)
-{
- /* Loop through all open connections and kill them one by one */
- while(-1 != ConnectionKillOne(data))
- ; /* empty loop */
-}
-
-/*
- * This is the internal function curl_easy_cleanup() calls. This should
- * cleanup and free all resources associated with this sessionhandle.
- *
- * NOTE: if we ever add something that attempts to write to a socket or
- * similar here, we must ignore SIGPIPE first. It is currently only done
- * when curl_easy_perform() is invoked.
- */
-
-CURLcode Curl_close(struct SessionHandle *data)
-{
- struct Curl_multi *m = data->multi;
-
-#ifdef CURLDEBUG
- /* only for debugging, scan through all connections and see if there's a
- pipe reference still identifying this handle */
-
- if(data->state.is_in_pipeline)
- fprintf(stderr, "CLOSED when in pipeline!\n");
-
- if(data->state.connc && data->state.connc->type == CONNCACHE_MULTI) {
- struct conncache *c = data->state.connc;
- int i;
- struct curl_llist *pipe;
- struct curl_llist_element *curr;
- struct connectdata *connptr;
-
- for(i=0; i< c->num; i++) {
- connptr = c->connects[i];
- if(!connptr)
- continue;
-
- pipe = connptr->send_pipe;
- if(pipe) {
- for (curr = pipe->head; curr; curr=curr->next) {
- if(data == (struct SessionHandle *) curr->ptr) {
- fprintf(stderr,
- "MAJOR problem we %p are still in send pipe for %p done %d\n",
- data, connptr, connptr->bits.done);
- }
- }
- }
- pipe = connptr->recv_pipe;
- if(pipe) {
- for (curr = pipe->head; curr; curr=curr->next) {
- if(data == (struct SessionHandle *) curr->ptr) {
- fprintf(stderr,
- "MAJOR problem we %p are still in recv pipe for %p done %d\n",
- data, connptr, connptr->bits.done);
- }
- }
- }
- }
- }
-#endif
-
- if(m)
- /* This handle is still part of a multi handle, take care of this first
- and detach this handle from there. */
- Curl_multi_rmeasy(data->multi, data);
-
- data->magic = 0; /* force a clear AFTER the possibly enforced removal from
- the multi handle, since that function uses the magic
- field! */
-
- if(data->state.connc) {
-
- if(data->state.connc->type == CONNCACHE_PRIVATE) {
- /* close all connections still alive that are in the private connection
- cache, as we no longer have the pointer left to the shared one. */
- close_connections(data);
-
- /* free the connection cache if allocated privately */
- Curl_rm_connc(data->state.connc);
- }
- }
-
- if(data->state.shared_conn) {
- /* marked to be used by a pending connection so we can't kill this handle
- just yet */
- data->state.closed = TRUE;
- return CURLE_OK;
- }
-
- if ( ! (data->share && data->share->hostcache) ) {
- if ( !Curl_global_host_cache_use(data)) {
- Curl_hash_destroy(data->dns.hostcache);
- }
- }
-
- /* Free the pathbuffer */
- Curl_safefree(data->reqdata.pathbuffer);
- Curl_safefree(data->reqdata.proto.generic);
-
- /* Close down all open SSL info and sessions */
- Curl_ssl_close_all(data);
- Curl_safefree(data->state.first_host);
- Curl_safefree(data->state.scratch);
-
- if(data->change.referer_alloc)
- free(data->change.referer);
-
- if(data->change.url_alloc)
- free(data->change.url);
-
- Curl_safefree(data->state.headerbuff);
-
-#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
- Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
- if(data->set.cookiejar) {
- if(data->change.cookielist) {
- /* If there is a list of cookie files to read, do it first so that
- we have all the told files read before we write the new jar */
- Curl_cookie_loadfiles(data);
- }
-
- /* we have a "destination" for all the cookies to get dumped to */
- if(Curl_cookie_output(data->cookies, data->set.cookiejar))
- infof(data, "WARNING: failed to save cookies in %s\n",
- data->set.cookiejar);
- }
- else {
- if(data->change.cookielist)
- /* since nothing is written, we can just free the list of cookie file
- names */
- curl_slist_free_all(data->change.cookielist); /* clean up list */
- }
-
- if( !data->share || (data->cookies != data->share->cookies) ) {
- Curl_cookie_cleanup(data->cookies);
- }
- Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
-#endif
-
- Curl_digest_cleanup(data);
-
- Curl_safefree(data->info.contenttype);
-
- /* this destroys the channel and we cannot use it anymore after this */
- ares_destroy(data->state.areschannel);
-
-#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
- /* close iconv conversion descriptors */
- if (data->inbound_cd != (iconv_t)-1) {
- iconv_close(data->inbound_cd);
- }
- if (data->outbound_cd != (iconv_t)-1) {
- iconv_close(data->outbound_cd);
- }
- if (data->utf8_cd != (iconv_t)-1) {
- iconv_close(data->utf8_cd);
- }
-#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
-
- /* No longer a dirty share, if it exists */
- if (data->share)
- data->share->dirty--;
-
- free(data);
- return CURLE_OK;
-}
-
-/* create a connection cache of a private or multi type */
-struct conncache *Curl_mk_connc(int type,
- int amount) /* set -1 to use default */
-{
- /* It is subject for debate how many default connections to have for a multi
- connection cache... */
- int default_amount = amount == -1?
- ((type == CONNCACHE_PRIVATE)?5:10):amount;
- struct conncache *c;
-
- c= calloc(sizeof(struct conncache), 1);
- if(!c)
- return NULL;
-
- c->connects = calloc(sizeof(struct connectdata *), default_amount);
- if(!c->connects) {
- free(c);
- return NULL;
- }
-
- c->num = default_amount;
-
- return c;
-}
-
-/* Change number of entries of a connection cache */
-CURLcode Curl_ch_connc(struct SessionHandle *data,
- struct conncache *c,
- long newamount)
-{
- long i;
- struct connectdata **newptr;
-
- if(newamount < 1)
- newamount = 1; /* we better have at least one entry */
-
- if(!c) {
- /* we get a NULL pointer passed in as connection cache, which means that
- there is no cache created for this SessionHandle just yet, we create a
- brand new with the requested size.
- */
- data->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE, newamount);
- if(!data->state.connc)
- return CURLE_OUT_OF_MEMORY;
- return CURLE_OK;
- }
-
- if(newamount < c->num) {
- /* Since this number is *decreased* from the existing number, we must
- close the possibly open connections that live on the indexes that
- are being removed!
-
- NOTE: for conncache_multi cases we must make sure that we only
- close handles not in use.
- */
- for(i=newamount; i< c->num; i++)
- Curl_disconnect(c->connects[i]);
-
- /* If the most recent connection is no longer valid, mark it
- invalid. */
- if(data->state.lastconnect <= newamount)
- data->state.lastconnect = -1;
- }
- if(newamount > 0) {
- newptr= (struct connectdata **)
- realloc(c->connects, sizeof(struct connectdata *) * newamount);
- if(!newptr)
- /* we closed a few connections in vain, but so what? */
- return CURLE_OUT_OF_MEMORY;
-
- /* nullify the newly added pointers */
- for(i=c->num; i<newamount; i++)
- newptr[i] = NULL;
-
- c->connects = newptr;
- c->num = newamount;
- }
- /* we no longer support less than 1 as size for the connection cache, and
- I'm not sure it ever worked to set it to zero */
- return CURLE_OK;
-}
-
-/* Free a connection cache. This is called from Curl_close() and
- curl_multi_cleanup(). */
-void Curl_rm_connc(struct conncache *c)
-{
- if(c->connects) {
- int i;
- for(i = 0; i < c->num; ++i)
- conn_free(c->connects[i]);
-
- free(c->connects);
- }
-
- free(c);
-}
-
-/**
- * Curl_open()
- *
- * @param curl is a pointer to a sessionhandle pointer that gets set by this
- * function.
- * @return CURLcode
- */
-
-CURLcode Curl_open(struct SessionHandle **curl)
-{
- CURLcode res = CURLE_OK;
- struct SessionHandle *data;
-
- /* Very simple start-up: alloc the struct, init it with zeroes and return */
- data = (struct SessionHandle *)calloc(1, sizeof(struct SessionHandle));
- if(!data)
- /* this is a very serious error */
- return CURLE_OUT_OF_MEMORY;
-
- data->magic = CURLEASY_MAGIC_NUMBER;
-
-#ifdef USE_ARES
- if(ARES_SUCCESS != ares_init(&data->state.areschannel)) {
- free(data);
- return CURLE_FAILED_INIT;
- }
- /* make sure that all other returns from this function should destroy the
- ares channel before returning error! */
-#endif
-
- /* We do some initial setup here, all those fields that can't be just 0 */
-
- data->state.headerbuff=(char*)malloc(HEADERSIZE);
- if(!data->state.headerbuff)
- res = CURLE_OUT_OF_MEMORY;
- else {
- data->state.headersize=HEADERSIZE;
-
- data->set.out = stdout; /* default output to stdout */
- data->set.in = stdin; /* default input from stdin */
- data->set.err = stderr; /* default stderr to stderr */
-
- /* use fwrite as default function to store output */
- data->set.fwrite = (curl_write_callback)fwrite;
-
- /* use fread as default function to read input */
- data->set.fread = (curl_read_callback)fread;
-
- /* conversion callbacks for non-ASCII hosts */
- data->set.convfromnetwork = (curl_conv_callback)ZERO_NULL;
- data->set.convtonetwork = (curl_conv_callback)ZERO_NULL;
- data->set.convfromutf8 = (curl_conv_callback)ZERO_NULL;
-
-#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
- /* conversion descriptors for iconv calls */
- data->outbound_cd = (iconv_t)-1;
- data->inbound_cd = (iconv_t)-1;
- data->utf8_cd = (iconv_t)-1;
-#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
-
- data->set.infilesize = -1; /* we don't know any size */
- data->set.postfieldsize = -1;
- data->set.maxredirs = -1; /* allow any amount by default */
- data->state.current_speed = -1; /* init to negative == impossible */
-
- data->set.httpreq = HTTPREQ_GET; /* Default HTTP request */
- data->set.ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */
- data->set.ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */
- data->set.ftp_filemethod = FTPFILE_MULTICWD;
- data->set.dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
-
- /* make libcurl quiet by default: */
- data->set.hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */
- data->progress.flags |= PGRS_HIDE;
-
- /* Set the default size of the SSL session ID cache */
- data->set.ssl.numsessions = 5;
-
- data->set.proxyport = 1080;
- data->set.proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
- data->set.httpauth = CURLAUTH_BASIC; /* defaults to basic */
- data->set.proxyauth = CURLAUTH_BASIC; /* defaults to basic */
-
- /* This no longer creates a connection cache here. It is instead made on
- the first call to curl_easy_perform() or when the handle is added to a
- multi stack. */
-
- data->set.ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
- type */
-
- /* most recent connection is not yet defined */
- data->state.lastconnect = -1;
-
- Curl_easy_initHandleData(data);
-
- /*
- * libcurl 7.10 introduced SSL verification *by default*! This needs to be
- * switched off unless wanted.
- */
- data->set.ssl.verifypeer = TRUE;
- data->set.ssl.verifyhost = 2;
- data->set.ssl.sessionid = TRUE; /* session ID caching enabled by default */
-#ifdef CURL_CA_BUNDLE
- /* This is our preferred CA cert bundle since install time */
- data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE;
-#endif
- }
-
- if(res) {
- ares_destroy(data->state.areschannel);
- if(data->state.headerbuff)
- free(data->state.headerbuff);
- free(data);
- data = NULL;
- }
- else
- *curl = data;
-
- return res;
-}
-
-CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
- va_list param)
-{
- char *argptr;
- CURLcode result = CURLE_OK;
-
- switch(option) {
- case CURLOPT_DNS_CACHE_TIMEOUT:
- data->set.dns_cache_timeout = va_arg(param, int);
- break;
- case CURLOPT_DNS_USE_GLOBAL_CACHE:
- {
- int use_cache = va_arg(param, int);
- if (use_cache) {
- Curl_global_host_cache_init();
- }
-
- data->set.global_dns_cache = (bool)(0 != use_cache);
- }
- break;
- case CURLOPT_SSL_CIPHER_LIST:
- /* set a list of cipher we want to use in the SSL connection */
- data->set.ssl.cipher_list = va_arg(param, char *);
- break;
-
- case CURLOPT_RANDOM_FILE:
- /*
- * This is the path name to a file that contains random data to seed
- * the random SSL stuff with. The file is only used for reading.
- */
- data->set.ssl.random_file = va_arg(param, char *);
- break;
- case CURLOPT_EGDSOCKET:
- /*
- * The Entropy Gathering Daemon socket pathname
- */
- data->set.ssl.egdsocket = va_arg(param, char *);
- break;
- case CURLOPT_MAXCONNECTS:
- /*
- * Set the absolute number of maximum simultaneous alive connection that
- * libcurl is allowed to have.
- */
- result = Curl_ch_connc(data, data->state.connc, va_arg(param, long));
- break;
- case CURLOPT_FORBID_REUSE:
- /*
- * When this transfer is done, it must not be left to be reused by a
- * subsequent transfer but shall be closed immediately.
- */
- data->set.reuse_forbid = (bool)(0 != va_arg(param, long));
- break;
- case CURLOPT_FRESH_CONNECT:
- /*
- * This transfer shall not use a previously cached connection but
- * should be made with a fresh new connect!
- */
- data->set.reuse_fresh = (bool)(0 != va_arg(param, long));
- break;
- case CURLOPT_VERBOSE:
- /*
- * Verbose means infof() calls that give a lot of information about
- * the connection and transfer procedures as well as internal choices.
- */
- data->set.verbose = (bool)(0 != va_arg(param, long));
- break;
- case CURLOPT_HEADER:
- /*
- * Set to include the header in the general data output stream.
- */
- data->set.include_header = (bool)(0 != va_arg(param, long));
- break;
- case CURLOPT_NOPROGRESS:
- /*
- * Shut off the internal supported progress meter
- */
- data->set.hide_progress = (bool)(0 != va_arg(param, long));
- if(data->set.hide_progress)
- data->progress.flags |= PGRS_HIDE;
- else
- data->progress.flags &= ~PGRS_HIDE;
- break;
- case CURLOPT_NOBODY:
- /*
- * Do not include the body part in the output data stream.
- */
- data->set.opt_no_body = (bool)(0 != va_arg(param, long));
- if(data->set.opt_no_body)
- /* in HTTP lingo, this means using the HEAD request */
- data->set.httpreq = HTTPREQ_HEAD;
- break;
- case CURLOPT_FAILONERROR:
- /*
- * Don't output the >=300 error code HTML-page, but instead only
- * return error.
- */
- data->set.http_fail_on_error = (bool)(0 != va_arg(param, long));
- break;
- case CURLOPT_UPLOAD:
- case CURLOPT_PUT:
- /*
- * We want to sent data to the remote host. If this is HTTP, that equals
- * using the PUT request.
- */
- data->set.upload = (bool)(0 != va_arg(param, long));
- if(data->set.upload)
- /* If this is HTTP, PUT is what's needed to "upload" */
- data->set.httpreq = HTTPREQ_PUT;
- break;
- case CURLOPT_FILETIME:
- /*
- * Try to get the file time of the remote document. The time will
- * later (possibly) become available using curl_easy_getinfo().
- */
- data->set.get_filetime = (bool)(0 != va_arg(param, long));
- break;
- case CURLOPT_FTP_CREATE_MISSING_DIRS:
- /*
- * An FTP option that modifies an upload to create missing directories on
- * the server.
- */
- data->set.ftp_create_missing_dirs = (bool)(0 != va_arg(param, long));
- break;
- case CURLOPT_FTP_RESPONSE_TIMEOUT:
- /*
- * An FTP option that specifies how quickly an FTP response must be
- * obtained before it is considered failure.
- */
- data->set.ftp_response_timeout = va_arg( param , long );
- break;
- case CURLOPT_FTPLISTONLY:
- /*
- * An FTP option that changes the command to one that asks for a list
- * only, no file info details.
- */
- data->set.ftp_list_only = (bool)(0 != va_arg(param, long));
- break;
- case CURLOPT_FTPAPPEND:
- /*
- * We want to upload and append to an existing (FTP) file.
- */
- data->set.ftp_append = (bool)(0 != va_arg(param, long));
- break;
- case CURLOPT_FTP_FILEMETHOD:
- /*
- * How do access files over FTP.
- */
- data->set.ftp_filemethod = (curl_ftpfile)va_arg(param, long);
- break;
- case CURLOPT_NETRC:
- /*
- * Parse the $HOME/.netrc file
- */
- data->set.use_netrc = (enum CURL_NETRC_OPTION)va_arg(param, long);
- break;
- case CURLOPT_NETRC_FILE:
- /*
- * Use this file instead of the $HOME/.netrc file
- */
- data->set.netrc_file = va_arg(param, char *);
- break;
- case CURLOPT_TRANSFERTEXT:
- /*
- * This option was previously named 'FTPASCII'. Renamed to work with
- * more protocols than merely FTP.
- *
- * Transfer using ASCII (instead of BINARY).
- */
- data->set.prefer_ascii = (bool)(0 != va_arg(param, long));
- break;
- case CURLOPT_TIMECONDITION:
- /*
- * Set HTTP time condition. This must be one of the defines in the
- * curl/curl.h header file.
- */
- data->set.timecondition = (curl_TimeCond)va_arg(param, long);
- break;
- case CURLOPT_TIMEVALUE:
- /*
- * This is the value to compare with the remote document with the
- * method set with CURLOPT_TIMECONDITION
- */
- data->set.timevalue = (time_t)va_arg(param, long);
- break;
- case CURLOPT_SSLVERSION:
- /*
- * Set explicit SSL version to try to connect with, as some SSL
- * implementations are lame.
- */
- data->set.ssl.version = va_arg(param, long);
- break;
-
-#ifndef CURL_DISABLE_HTTP
- case CURLOPT_AUTOREFERER:
- /*
- * Switch on automatic referer that gets set if curl follows locations.
- */
- data->set.http_auto_referer = (bool)(0 != va_arg(param, long));
- break;
-
- case CURLOPT_ENCODING:
- /*
- * String to use at the value of Accept-Encoding header.
- *
- * If the encoding is set to "" we use an Accept-Encoding header that
- * encompasses all the encodings we support.
- * If the encoding is set to NULL we don't send an Accept-Encoding header
- * and ignore an received Content-Encoding header.
- *
- */
- data->set.encoding = va_arg(param, char *);
- if(data->set.encoding && !*data->set.encoding)
- data->set.encoding = (char*)ALL_CONTENT_ENCODINGS;
- break;
-
- case CURLOPT_FOLLOWLOCATION:
- /*
- * Follow Location: header hints on a HTTP-server.
- */
- data->set.http_follow_location = (bool)(0 != va_arg(param, long));
- break;
-
- case CURLOPT_UNRESTRICTED_AUTH:
- /*
- * Send authentication (user+password) when following locations, even when
- * hostname changed.
- */
- data->set.http_disable_hostname_check_before_authentication =
- (bool)(0 != va_arg(param, long));
- break;
-
- case CURLOPT_MAXREDIRS:
- /*
- * The maximum amount of hops you allow curl to follow Location:
- * headers. This should mostly be used to detect never-ending loops.
- */
- data->set.maxredirs = va_arg(param, long);
- break;
-
- case CURLOPT_POST:
- /* Does this option serve a purpose anymore? Yes it does, when
- CURLOPT_POSTFIELDS isn't used and the POST data is read off the
- callback! */
- if(va_arg(param, long)) {
- data->set.httpreq = HTTPREQ_POST;
- data->set.opt_no_body = FALSE; /* this is implied */
- }
- else
- data->set.httpreq = HTTPREQ_GET;
- break;
-
- case CURLOPT_POSTFIELDS:
- /*
- * A string with POST data. Makes curl HTTP POST. Even if it is NULL.
- */
- data->set.postfields = va_arg(param, char *);
- data->set.httpreq = HTTPREQ_POST;
- break;
-
- case CURLOPT_POSTFIELDSIZE:
- /*
- * The size of the POSTFIELD data to prevent libcurl to do strlen() to
- * figure it out. Enables binary posts.
- */
- data->set.postfieldsize = va_arg(param, long);
- break;
-
- case CURLOPT_POSTFIELDSIZE_LARGE:
- /*
- * The size of the POSTFIELD data to prevent libcurl to do strlen() to
- * figure it out. Enables binary posts.
- */
- data->set.postfieldsize = va_arg(param, curl_off_t);
- break;
-
- case CURLOPT_HTTPPOST:
- /*
- * Set to make us do HTTP POST
- */
- data->set.httppost = va_arg(param, struct curl_httppost *);
- data->set.httpreq = HTTPREQ_POST_FORM;
- data->set.opt_no_body = FALSE; /* this is implied */
- break;
-
- case CURLOPT_REFERER:
- /*
- * String to set in the HTTP Referer: field.
- */
- if(data->change.referer_alloc) {
- free(data->change.referer);
- data->change.referer_alloc = FALSE;
- }
- data->set.set_referer = va_arg(param, char *);
- data->change.referer = data->set.set_referer;
- break;
-
- case CURLOPT_USERAGENT:
- /*
- * String to use in the HTTP User-Agent field
- */
- data->set.useragent = va_arg(param, char *);
- break;
-
- case CURLOPT_HTTPHEADER:
- /*
- * Set a list with HTTP headers to use (or replace internals with)
- */
- data->set.headers = va_arg(param, struct curl_slist *);
- break;
-
- case CURLOPT_HTTP200ALIASES:
- /*
- * Set a list of aliases for HTTP 200 in response header
- */
- data->set.http200aliases = va_arg(param, struct curl_slist *);
- break;
-
-#if !defined(CURL_DISABLE_COOKIES)
- case CURLOPT_COOKIE:
- /*
- * Cookie string to send to the remote server in the request.
- */
- data->set.cookie = va_arg(param, char *);
- break;
-
- case CURLOPT_COOKIEFILE:
- /*
- * Set cookie file to read and parse. Can be used multiple times.
- */
- argptr = (char *)va_arg(param, void *);
- if(argptr) {
- struct curl_slist *cl;
- /* append the cookie file name to the list of file names, and deal with
- them later */
- cl = curl_slist_append(data->change.cookielist, argptr);
-
- if(!cl)
- return CURLE_OUT_OF_MEMORY;
-
- data->change.cookielist = cl;
- }
- break;
-
- case CURLOPT_COOKIEJAR:
- /*
- * Set cookie file name to dump all cookies to when we're done.
- */
- data->set.cookiejar = (char *)va_arg(param, void *);
-
- /*
- * Activate the cookie parser. This may or may not already
- * have been made.
- */
- data->cookies = Curl_cookie_init(data, NULL, data->cookies,
- data->set.cookiesession);
- break;
-
- case CURLOPT_COOKIESESSION:
- /*
- * Set this option to TRUE to start a new "cookie session". It will
- * prevent the forthcoming read-cookies-from-file actions to accept
- * cookies that are marked as being session cookies, as they belong to a
- * previous session.
- *
- * In the original Netscape cookie spec, "session cookies" are cookies
- * with no expire date set. RFC2109 describes the same action if no
- * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds
- * a 'Discard' action that can enforce the discard even for cookies that
- * have a Max-Age.
- *
- * We run mostly with the original cookie spec, as hardly anyone implements
- * anything else.
- */
- data->set.cookiesession = (bool)(0 != va_arg(param, long));
- break;
-
- case CURLOPT_COOKIELIST:
- argptr = va_arg(param, char *);
-
- if(argptr == NULL)
- break;
-
- if(strequal(argptr, "ALL")) {
- /* clear all cookies */
- Curl_cookie_clearall(data->cookies);
- break;
- }
- else if(strequal(argptr, "SESS")) {
- /* clear session cookies */
- Curl_cookie_clearsess(data->cookies);
- break;
- }
-
- if(!data->cookies)
- /* if cookie engine was not running, activate it */
- data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE);
-
- argptr = strdup(argptr);
- if(!argptr) {
- result = CURLE_OUT_OF_MEMORY;
- break;
- }
-
- if(checkprefix("Set-Cookie:", argptr))
- /* HTTP Header format line */
- Curl_cookie_add(data, data->cookies, TRUE, argptr + 11, NULL, NULL);
-
- else
- /* Netscape format line */
- Curl_cookie_add(data, data->cookies, FALSE, argptr, NULL, NULL);
-
- free(argptr);
- break;
-#endif /* CURL_DISABLE_COOKIES */
-
- case CURLOPT_HTTPGET:
- /*
- * Set to force us do HTTP GET
- */
- if(va_arg(param, long)) {
- data->set.httpreq = HTTPREQ_GET;
- data->set.upload = FALSE; /* switch off upload */
- data->set.opt_no_body = FALSE; /* this is implied */
- }
- break;
-
- case CURLOPT_HTTP_VERSION:
- /*
- * This sets a requested HTTP version to be used. The value is one of
- * the listed enums in curl/curl.h.
- */
- data->set.httpversion = va_arg(param, long);
- break;
-
- case CURLOPT_HTTPPROXYTUNNEL:
- /*
- * Tunnel operations through the proxy instead of normal proxy use
- */
- data->set.tunnel_thru_httpproxy = (bool)(0 != va_arg(param, long));
- break;
-
- case CURLOPT_CUSTOMREQUEST:
- /*
- * Set a custom string to use as request
- */
- data->set.customrequest = va_arg(param, char *);
-
- /* we don't set
- data->set.httpreq = HTTPREQ_CUSTOM;
- here, we continue as if we were using the already set type
- and this just changes the actual request keyword */
- break;
-
- case CURLOPT_PROXYPORT:
- /*
- * Explicitly set HTTP proxy port number.
- */
- data->set.proxyport = va_arg(param, long);
- break;
-
- case CURLOPT_HTTPAUTH:
- /*
- * Set HTTP Authentication type BITMASK.
- */
- {
- long auth = va_arg(param, long);
- /* switch off bits we can't support */
-#ifndef USE_NTLM
- auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
-#endif
-#ifndef HAVE_GSSAPI
- auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
-#endif
- if(!auth)
- return CURLE_FAILED_INIT; /* no supported types left! */
-
- data->set.httpauth = auth;
- }
- break;
-
- case CURLOPT_PROXYAUTH:
- /*
- * Set HTTP Authentication type BITMASK.
- */
- {
- long auth = va_arg(param, long);
- /* switch off bits we can't support */
-#ifndef USE_NTLM
- auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
-#endif
-#ifndef HAVE_GSSAPI
- auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
-#endif
- if(!auth)
- return CURLE_FAILED_INIT; /* no supported types left! */
-
- data->set.proxyauth = auth;
- }
- break;
-#endif /* CURL_DISABLE_HTTP */
-
- case CURLOPT_PROXY:
- /*
- * Set proxy server:port to use as HTTP proxy.
- *
- * If the proxy is set to "" we explicitly say that we don't want to use a
- * proxy (even though there might be environment variables saying so).
- *
- * Setting it to NULL, means no proxy but allows the environment variables
- * to decide for us.
- */
- data->set.proxy = va_arg(param, char *);
- break;
-
- case CURLOPT_WRITEHEADER:
- /*
- * Custom pointer to pass the header write callback function
- */
- data->set.writeheader = (void *)va_arg(param, void *);
- break;
- case CURLOPT_ERRORBUFFER:
- /*
- * Error buffer provided by the caller to get the human readable
- * error string in.
- */
- data->set.errorbuffer = va_arg(param, char *);
- break;
- case CURLOPT_FILE:
- /*
- * FILE pointer to write to or include in the data write callback
- */
- data->set.out = va_arg(param, FILE *);
- break;
- case CURLOPT_FTPPORT:
- /*
- * Use FTP PORT, this also specifies which IP address to use
- */
- data->set.ftpport = va_arg(param, char *);
- data->set.ftp_use_port = (bool)(NULL != data->set.ftpport);
- break;
-
- case CURLOPT_FTP_USE_EPRT:
- data->set.ftp_use_eprt = (bool)(0 != va_arg(param, long));
- break;
-
- case CURLOPT_FTP_USE_EPSV:
- data->set.ftp_use_epsv = (bool)(0 != va_arg(param, long));
- break;
-
- case CURLOPT_FTP_SSL_CCC:
- data->set.ftp_use_ccc = (bool)(0 != va_arg(param, long));
- break;
-
- case CURLOPT_FTP_SKIP_PASV_IP:
- /*
- * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the
- * bypass of the IP address in PASV responses.
- */
- data->set.ftp_skip_ip = (bool)(0 != va_arg(param, long));
- break;
-
- case CURLOPT_INFILE:
- /*
- * FILE pointer to read the file to be uploaded from. Or possibly
- * used as argument to the read callback.
- */
- data->set.in = va_arg(param, FILE *);
- break;
- case CURLOPT_INFILESIZE:
- /*
- * If known, this should inform curl about the file size of the
- * to-be-uploaded file.
- */
- data->set.infilesize = va_arg(param, long);
- break;
- case CURLOPT_INFILESIZE_LARGE:
- /*
- * If known, this should inform curl about the file size of the
- * to-be-uploaded file.
- */
- data->set.infilesize = va_arg(param, curl_off_t);
- break;
- case CURLOPT_LOW_SPEED_LIMIT:
- /*
- * The low speed limit that if transfers are below this for
- * CURLOPT_LOW_SPEED_TIME, the transfer is aborted.
- */
- data->set.low_speed_limit=va_arg(param, long);
- break;
- case CURLOPT_MAX_SEND_SPEED_LARGE:
- /*
- * The max speed limit that sends transfer more than
- * CURLOPT_MAX_SEND_PER_SECOND bytes per second the transfer is
- * throttled..
- */
- data->set.max_send_speed=va_arg(param, curl_off_t);
- break;
- case CURLOPT_MAX_RECV_SPEED_LARGE:
- /*
- * The max speed limit that sends transfer more than
- * CURLOPT_MAX_RECV_PER_SECOND bytes per second the transfer is
- * throttled..
- */
- data->set.max_recv_speed=va_arg(param, curl_off_t);
- break;
- case CURLOPT_LOW_SPEED_TIME:
- /*
- * The low speed time that if transfers are below the set
- * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted.
- */
- data->set.low_speed_time=va_arg(param, long);
- break;
- case CURLOPT_URL:
- /*
- * The URL to fetch.
- */
- if(data->change.url_alloc) {
- /* the already set URL is allocated, free it first! */
- free(data->change.url);
- data->change.url_alloc=FALSE;
- }
- data->set.set_url = va_arg(param, char *);
- data->change.url = data->set.set_url;
- data->change.url_changed = TRUE;
- break;
- case CURLOPT_PORT:
- /*
- * The port number to use when getting the URL
- */
- data->set.use_port = va_arg(param, long);
- break;
- case CURLOPT_TIMEOUT:
- /*
- * The maximum time you allow curl to use for a single transfer
- * operation.
- */
- data->set.timeout = va_arg(param, long);
- break;
- case CURLOPT_CONNECTTIMEOUT:
- /*
- * The maximum time you allow curl to use to connect.
- */
- data->set.connecttimeout = va_arg(param, long);
- break;
-
- case CURLOPT_USERPWD:
- /*
- * user:password to use in the operation
- */
- data->set.userpwd = va_arg(param, char *);
- break;
- case CURLOPT_POSTQUOTE:
- /*
- * List of RAW FTP commands to use after a transfer
- */
- data->set.postquote = va_arg(param, struct curl_slist *);
- break;
- case CURLOPT_PREQUOTE:
- /*
- * List of RAW FTP commands to use prior to RETR (Wesley Laxton)
- */
- data->set.prequote = va_arg(param, struct curl_slist *);
- break;
- case CURLOPT_QUOTE:
- /*
- * List of RAW FTP commands to use before a transfer
- */
- data->set.quote = va_arg(param, struct curl_slist *);
- break;
- case CURLOPT_PROGRESSFUNCTION:
- /*
- * Progress callback function
- */
- data->set.fprogress = va_arg(param, curl_progress_callback);
- if(data->set.fprogress)
- data->progress.callback = TRUE; /* no longer internal */
- else
- data->progress.callback = FALSE; /* NULL enforces internal */
-
- break;
- case CURLOPT_PROGRESSDATA:
- /*
- * Custom client data to pass to the progress callback
- */
- data->set.progress_client = va_arg(param, void *);
- break;
- case CURLOPT_PROXYUSERPWD:
- /*
- * user:password needed to use the proxy
- */
- data->set.proxyuserpwd = va_arg(param, char *);
- break;
- case CURLOPT_RANGE:
- /*
- * What range of the file you want to transfer
- */
- data->set.set_range = va_arg(param, char *);
- break;
- case CURLOPT_RESUME_FROM:
- /*
- * Resume transfer at the give file position
- */
- data->set.set_resume_from = va_arg(param, long);
- break;
- case CURLOPT_RESUME_FROM_LARGE:
- /*
- * Resume transfer at the give file position
- */
- data->set.set_resume_from = va_arg(param, curl_off_t);
- break;
- case CURLOPT_DEBUGFUNCTION:
- /*
- * stderr write callback.
- */
- data->set.fdebug = va_arg(param, curl_debug_callback);
- /*
- * if the callback provided is NULL, it'll use the default callback
- */
- break;
- case CURLOPT_DEBUGDATA:
- /*
- * Set to a void * that should receive all error writes. This
- * defaults to CURLOPT_STDERR for normal operations.
- */
- data->set.debugdata = va_arg(param, void *);
- break;
- case CURLOPT_STDERR:
- /*
- * Set to a FILE * that should receive all error writes. This
- * defaults to stderr for normal operations.
- */
- data->set.err = va_arg(param, FILE *);
- if(!data->set.err)
- data->set.err = stderr;
- break;
- case CURLOPT_HEADERFUNCTION:
- /*
- * Set header write callback
- */
- data->set.fwrite_header = va_arg(param, curl_write_callback);
- break;
- case CURLOPT_WRITEFUNCTION:
- /*
- * Set data write callback
- */
- data->set.fwrite = va_arg(param, curl_write_callback);
- if(!data->set.fwrite)
- /* When set to NULL, reset to our internal default function */
- data->set.fwrite = (curl_write_callback)fwrite;
- break;
- case CURLOPT_READFUNCTION:
- /*
- * Read data callback
- */
- data->set.fread = va_arg(param, curl_read_callback);
- if(!data->set.fread)
- /* When set to NULL, reset to our internal default function */
- data->set.fread = (curl_read_callback)fread;
- break;
- case CURLOPT_CONV_FROM_NETWORK_FUNCTION:
- /*
- * "Convert from network encoding" callback
- */
- data->set.convfromnetwork = va_arg(param, curl_conv_callback);
- break;
- case CURLOPT_CONV_TO_NETWORK_FUNCTION:
- /*
- * "Convert to network encoding" callback
- */
- data->set.convtonetwork = va_arg(param, curl_conv_callback);
- break;
- case CURLOPT_CONV_FROM_UTF8_FUNCTION:
- /*
- * "Convert from UTF-8 encoding" callback
- */
- data->set.convfromutf8 = va_arg(param, curl_conv_callback);
- break;
- case CURLOPT_IOCTLFUNCTION:
- /*
- * I/O control callback. Might be NULL.
- */
- data->set.ioctl = va_arg(param, curl_ioctl_callback);
- break;
- case CURLOPT_IOCTLDATA:
- /*
- * I/O control data pointer. Might be NULL.
- */
- data->set.ioctl_client = va_arg(param, void *);
- break;
- case CURLOPT_SSLCERT:
- /*
- * String that holds file name of the SSL certificate to use
- */
- data->set.cert = va_arg(param, char *);
- break;
- case CURLOPT_SSLCERTTYPE:
- /*
- * String that holds file type of the SSL certificate to use
- */
- data->set.cert_type = va_arg(param, char *);
- break;
- case CURLOPT_SSLKEY:
- /*
- * String that holds file name of the SSL certificate to use
- */
- data->set.key = va_arg(param, char *);
- break;
- case CURLOPT_SSLKEYTYPE:
- /*
- * String that holds file type of the SSL certificate to use
- */
- data->set.key_type = va_arg(param, char *);
- break;
- case CURLOPT_SSLKEYPASSWD:
- /*
- * String that holds the SSL private key password.
- */
- data->set.key_passwd = va_arg(param, char *);
- break;
- case CURLOPT_SSLENGINE:
- /*
- * String that holds the SSL crypto engine.
- */
- argptr = va_arg(param, char *);
- if (argptr && argptr[0])
- result = Curl_ssl_set_engine(data, argptr);
- break;
-
- case CURLOPT_SSLENGINE_DEFAULT:
- /*
- * flag to set engine as default.
- */
- result = Curl_ssl_set_engine_default(data);
- break;
- case CURLOPT_CRLF:
- /*
- * Kludgy option to enable CRLF conversions. Subject for removal.
- */
- data->set.crlf = (bool)(0 != va_arg(param, long));
- break;
-
- case CURLOPT_INTERFACE:
- /*
- * Set what interface or address/hostname to bind the socket to when
- * performing an operation and thus what from-IP your connection will use.
- */
- data->set.device = va_arg(param, char *);
- break;
- case CURLOPT_LOCALPORT:
- /*
- * Set what local port to bind the socket to when performing an operation.
- */
- data->set.localport = (unsigned short) va_arg(param, long);
- break;
- case CURLOPT_LOCALPORTRANGE:
- /*
- * Set number of local ports to try, starting with CURLOPT_LOCALPORT.
- */
- data->set.localportrange = (int) va_arg(param, long);
- break;
- case CURLOPT_KRB4LEVEL:
- /*
- * A string that defines the krb4 security level.
- */
- data->set.krb4_level = va_arg(param, char *);
- data->set.krb4 = (bool)(NULL != data->set.krb4_level);
- break;
- case CURLOPT_SSL_VERIFYPEER:
- /*
- * Enable peer SSL verifying.
- */
- data->set.ssl.verifypeer = va_arg(param, long);
- break;
- case CURLOPT_SSL_VERIFYHOST:
- /*
- * Enable verification of the CN contained in the peer certificate
- */
- data->set.ssl.verifyhost = va_arg(param, long);
- break;
- case CURLOPT_SSL_CTX_FUNCTION:
- /*
- * Set a SSL_CTX callback
- */
- data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
- break;
- case CURLOPT_SSL_CTX_DATA:
- /*
- * Set a SSL_CTX callback parameter pointer
- */
- data->set.ssl.fsslctxp = va_arg(param, void *);
- break;
- case CURLOPT_CAINFO:
- /*
- * Set CA info for SSL connection. Specify file name of the CA certificate
- */
- data->set.ssl.CAfile = va_arg(param, char *);
- break;
- case CURLOPT_CAPATH:
- /*
- * Set CA path info for SSL connection. Specify directory name of the CA
- * certificates which have been prepared using openssl c_rehash utility.
- */
- /* This does not work on windows. */
- data->set.ssl.CApath = va_arg(param, char *);
- break;
- case CURLOPT_TELNETOPTIONS:
- /*
- * Set a linked list of telnet options
- */
- data->set.telnet_options = va_arg(param, struct curl_slist *);
- break;
-
- case CURLOPT_BUFFERSIZE:
- /*
- * The application kindly asks for a differently sized receive buffer.
- * If it seems reasonable, we'll use it.
- */
- data->set.buffer_size = va_arg(param, long);
-
- if((data->set.buffer_size> (BUFSIZE -1 )) ||
- (data->set.buffer_size < 1))
- data->set.buffer_size = 0; /* huge internal default */
-
- break;
-
- case CURLOPT_NOSIGNAL:
- /*
- * The application asks not to set any signal() or alarm() handlers,
- * even when using a timeout.
- */
- data->set.no_signal = (bool)(0 != va_arg(param, long));
- break;
-
- case CURLOPT_SHARE:
- {
- struct Curl_share *set;
- set = va_arg(param, struct Curl_share *);
-
- /* disconnect from old share, if any */
- if(data->share) {
- Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
-
- if(data->dns.hostcachetype == HCACHE_SHARED) {
- data->dns.hostcache = NULL;
- data->dns.hostcachetype = HCACHE_NONE;
- }
-
- if(data->share->cookies == data->cookies)
- data->cookies = NULL;
-
- data->share->dirty--;
-
- Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
- data->share = NULL;
- }
-
- /* use new share if it set */
- data->share = set;
- if(data->share) {
-
- Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
-
- data->share->dirty++;
-
- if(data->share->hostcache) {
- /* use shared host cache, first free the private one if any */
- if(data->dns.hostcachetype == HCACHE_PRIVATE)
- Curl_hash_destroy(data->dns.hostcache);
-
- data->dns.hostcache = data->share->hostcache;
- data->dns.hostcachetype = HCACHE_SHARED;
- }
-#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
- if(data->share->cookies) {
- /* use shared cookie list, first free own one if any */
- if (data->cookies)
- Curl_cookie_cleanup(data->cookies);
- data->cookies = data->share->cookies;
- }
-#endif /* CURL_DISABLE_HTTP */
- Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
-
- }
-#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
- /* check cookie list is set */
- if(!data->cookies)
- data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE );
-#endif /* CURL_DISABLE_HTTP */
- /* check for host cache not needed,
- * it will be done by curl_easy_perform */
- }
- break;
-
- case CURLOPT_PROXYTYPE:
- /*
- * Set proxy type. HTTP/SOCKS4/SOCKS5
- */
- data->set.proxytype = (curl_proxytype)va_arg(param, long);
- break;
-
- case CURLOPT_PRIVATE:
- /*
- * Set private data pointer.
- */
- data->set.private_data = va_arg(param, char *);
- break;
-
- case CURLOPT_MAXFILESIZE:
- /*
- * Set the maximum size of a file to download.
- */
- data->set.max_filesize = va_arg(param, long);
- break;
-
- case CURLOPT_FTP_SSL:
- /*
- * Make FTP transfers attempt to use SSL/TLS.
- */
- data->set.ftp_ssl = (curl_ftpssl)va_arg(param, long);
- break;
-
- case CURLOPT_FTPSSLAUTH:
- /*
- * Set a specific auth for FTP-SSL transfers.
- */
- data->set.ftpsslauth = (curl_ftpauth)va_arg(param, long);
- break;
-
- case CURLOPT_IPRESOLVE:
- data->set.ip_version = va_arg(param, long);
- break;
-
- case CURLOPT_MAXFILESIZE_LARGE:
- /*
- * Set the maximum size of a file to download.
- */
- data->set.max_filesize = va_arg(param, curl_off_t);
- break;
-
- case CURLOPT_TCP_NODELAY:
- /*
- * Enable or disable TCP_NODELAY, which will disable/enable the Nagle
- * algorithm
- */
- data->set.tcp_nodelay = (bool)(0 != va_arg(param, long));
- break;
-
- /*
- case CURLOPT_SOURCE_URL:
- case CURLOPT_SOURCE_USERPWD:
- case CURLOPT_SOURCE_QUOTE:
- case CURLOPT_SOURCE_PREQUOTE:
- case CURLOPT_SOURCE_POSTQUOTE:
- These former 3rd party transfer options are deprecated */
-
- case CURLOPT_FTP_ACCOUNT:
- data->set.ftp_account = va_arg(param, char *);
- break;
-
- case CURLOPT_IGNORE_CONTENT_LENGTH:
- data->set.ignorecl = (bool)(0 != va_arg(param, long));
- break;
-
- case CURLOPT_CONNECT_ONLY:
- /*
- * No data transfer, set up connection and let application use the socket
- */
- data->set.connect_only = (bool)(0 != va_arg(param, long));
- break;
-
- case CURLOPT_FTP_ALTERNATIVE_TO_USER:
- data->set.ftp_alternative_to_user = va_arg(param, char *);
- break;
-
- case CURLOPT_SOCKOPTFUNCTION:
- /*
- * socket callback function: called after socket() but before connect()
- */
- data->set.fsockopt = va_arg(param, curl_sockopt_callback);
- break;
-
- case CURLOPT_SOCKOPTDATA:
- /*
- * socket callback data pointer. Might be NULL.
- */
- data->set.sockopt_client = va_arg(param, void *);
- break;
-
- case CURLOPT_SSL_SESSIONID_CACHE:
- data->set.ssl.sessionid = (bool)(0 != va_arg(param, long));
- break;
-
- case CURLOPT_SSH_AUTH_TYPES:
- data->set.ssh_auth_types = va_arg(param, long);
- break;
-
- case CURLOPT_SSH_PUBLIC_KEYFILE:
- /*
- * Use this file instead of the $HOME/.ssh/id_dsa.pub file
- */
- data->set.ssh_public_key = va_arg(param, char *);
- break;
-
- case CURLOPT_SSH_PRIVATE_KEYFILE:
- /*
- * Use this file instead of the $HOME/.ssh/id_dsa file
- */
- data->set.ssh_private_key = va_arg(param, char *);
- break;
-
- default:
- /* unknown tag and its companion, just ignore: */
- result = CURLE_FAILED_INIT; /* correct this */
- break;
- }
-
- return result;
-}
-
-static void conn_free(struct connectdata *conn)
-{
- if (!conn)
- return;
-
- /* close possibly still open sockets */
- if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
- sclose(conn->sock[SECONDARYSOCKET]);
- if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
- sclose(conn->sock[FIRSTSOCKET]);
-
- Curl_safefree(conn->user);
- Curl_safefree(conn->passwd);
- Curl_safefree(conn->proxyuser);
- Curl_safefree(conn->proxypasswd);
- Curl_safefree(conn->allocptr.proxyuserpwd);
- Curl_safefree(conn->allocptr.uagent);
- Curl_safefree(conn->allocptr.userpwd);
- Curl_safefree(conn->allocptr.accept_encoding);
- Curl_safefree(conn->allocptr.rangeline);
- Curl_safefree(conn->allocptr.ref);
- Curl_safefree(conn->allocptr.host);
- Curl_safefree(conn->allocptr.cookiehost);
- Curl_safefree(conn->ip_addr_str);
- Curl_safefree(conn->trailer);
- Curl_safefree(conn->host.rawalloc); /* host name buffer */
- Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */
-
- Curl_llist_destroy(conn->send_pipe, NULL);
- Curl_llist_destroy(conn->recv_pipe, NULL);
-
- /* possible left-overs from the async name resolvers */
-#if defined(USE_ARES)
- Curl_safefree(conn->async.hostname);
- Curl_safefree(conn->async.os_specific);
-#elif defined(CURLRES_THREADED)
- Curl_destroy_thread_data(&conn->async);
-#endif
-
- Curl_free_ssl_config(&conn->ssl_config);
-
- free(conn); /* free all the connection oriented data */
-}
-
-CURLcode Curl_disconnect(struct connectdata *conn)
-{
- struct SessionHandle *data;
- if(!conn)
- return CURLE_OK; /* this is closed and fine already */
- data = conn->data;
-
- if(!data) {
- DEBUGF(infof(data, "DISCONNECT without easy handle, ignoring\n"));
- return CURLE_OK;
- }
-
-#if defined(CURLDEBUG) && defined(AGGRESIVE_TEST)
- /* scan for DNS cache entries still marked as in use */
- Curl_hash_apply(data->hostcache,
- NULL, Curl_scan_cache_used);
-#endif
-
- Curl_expire(data, 0); /* shut off timers */
- Curl_hostcache_prune(data); /* kill old DNS cache entries */
-
- /*
- * The range string is usually freed in curl_done(), but we might
- * get here *instead* if we fail prematurely. Thus we need to be able
- * to free this resource here as well.
- */
- if(data->reqdata.rangestringalloc) {
- free(data->reqdata.range);
- data->reqdata.rangestringalloc = FALSE;
- }
-
- if((conn->ntlm.state != NTLMSTATE_NONE) ||
- (conn->proxyntlm.state != NTLMSTATE_NONE)) {
- /* Authentication data is a mix of connection-related and sessionhandle-
- related stuff. NTLM is connection-related so when we close the shop
- we shall forget. */
- data->state.authhost.done = FALSE;
- data->state.authhost.picked =
- data->state.authhost.want;
-
- data->state.authproxy.done = FALSE;
- data->state.authproxy.picked =
- data->state.authproxy.want;
-
- data->state.authproblem = FALSE;
-
- Curl_ntlm_cleanup(conn);
- }
-
- if(conn->curl_disconnect)
- /* This is set if protocol-specific cleanups should be made */
- conn->curl_disconnect(conn);
-
- if(-1 != conn->connectindex) {
- /* unlink ourselves! */
- infof(data, "Closing connection #%ld\n", conn->connectindex);
- if(data->state.connc)
- /* only clear the table entry if we still know in which cache we
- used to be in */
- data->state.connc->connects[conn->connectindex] = NULL;
- }
-
-#ifdef USE_LIBIDN
- if(conn->host.encalloc)
- idn_free(conn->host.encalloc); /* encoded host name buffer, must be freed
- with idn_free() since this was allocated
- by libidn */
- if(conn->proxy.encalloc)
- idn_free(conn->proxy.encalloc); /* encoded proxy name buffer, must be
- freed with idn_free() since this was
- allocated by libidn */
-#endif
-
- Curl_ssl_close(conn);
-
- /* Indicate to all handles on the pipe that we're dead */
- if (IsPipeliningEnabled(data)) {
- signalPipeClose(conn->send_pipe);
- signalPipeClose(conn->recv_pipe);
- }
-
- conn_free(conn);
-
- return CURLE_OK;
-}
-
-/*
- * This function should return TRUE if the socket is to be assumed to
- * be dead. Most commonly this happens when the server has closed the
- * connection due to inactivity.
- */
-static bool SocketIsDead(curl_socket_t sock)
-{
- int sval;
- bool ret_val = TRUE;
-
- sval = Curl_select(sock, CURL_SOCKET_BAD, 0);
- if(sval == 0)
- /* timeout */
- ret_val = FALSE;
-
- return ret_val;
-}
-
-static bool IsPipeliningPossible(struct SessionHandle *handle)
-{
- if (handle->multi && Curl_multi_canPipeline(handle->multi) &&
- (handle->set.httpreq == HTTPREQ_GET ||
- handle->set.httpreq == HTTPREQ_HEAD) &&
- handle->set.httpversion != CURL_HTTP_VERSION_1_0)
- return TRUE;
-
- return FALSE;
-}
-
-static bool IsPipeliningEnabled(struct SessionHandle *handle)
-{
- if (handle->multi && Curl_multi_canPipeline(handle->multi))
- return TRUE;
-
- return FALSE;
-}
-
-void Curl_addHandleToPipeline(struct SessionHandle *data,
- struct curl_llist *pipe)
-{
-#ifdef CURLDEBUG
- if(!IsPipeliningPossible(data)) {
- /* when not pipelined, there MUST be no handle in the list already */
- if(pipe->head)
- infof(data, "PIPE when no PIPE supposed!\n");
- }
-#endif
- Curl_llist_insert_next(pipe, pipe->tail, data);
-}
-
-
-int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
- struct curl_llist *pipe)
-{
- struct curl_llist_element *curr;
-
- curr = pipe->head;
- while (curr) {
- if (curr->ptr == handle) {
- Curl_llist_remove(pipe, curr, NULL);
- return 1; /* we removed a handle */
- }
- curr = curr->next;
- }
-
- return 0;
-}
-
-#if 0 /* this code is saved here as it is useful for debugging purposes */
-static void Curl_printPipeline(struct curl_llist *pipe)
-{
- struct curl_llist_element *curr;
-
- curr = pipe->head;
- while (curr) {
- struct SessionHandle *data = (struct SessionHandle *) curr->ptr;
- infof(data, "Handle in pipeline: %s\n",
- data->reqdata.path);
- curr = curr->next;
- }
-}
-#endif
-
-bool Curl_isHandleAtHead(struct SessionHandle *handle,
- struct curl_llist *pipe)
-{
- struct curl_llist_element *curr = pipe->head;
- if (curr) {
- return (bool)(curr->ptr == handle);
- }
-
- return FALSE;
-}
-
-static void signalPipeClose(struct curl_llist *pipe)
-{
- struct curl_llist_element *curr;
-
- curr = pipe->head;
- while (curr) {
- struct curl_llist_element *next = curr->next;
- struct SessionHandle *data = (struct SessionHandle *) curr->ptr;
-
-#ifdef CURLDEBUG /* debug-only code */
- if(data->magic != CURLEASY_MAGIC_NUMBER) {
- /* MAJOR BADNESS */
- fprintf(stderr, "signalPipeClose() found BAAD easy handle\n");
- }
- else
-#endif
-
- data->state.pipe_broke = TRUE;
- Curl_llist_remove(pipe, curr, NULL);
- curr = next;
- }
-}
-
-
-/*
- * Given one filled in connection struct (named needle), this function should
- * detect if there already is one that has all the significant details
- * exactly the same and thus should be used instead.
- *
- * If there is a match, this function returns TRUE - and has marked the
- * connection as 'in-use'. It must later be called with ConnectionDone() to
- * return back to 'idle' (unused) state.
- */
-static bool
-ConnectionExists(struct SessionHandle *data,
- struct connectdata *needle,
- struct connectdata **usethis)
-{
- long i;
- struct connectdata *check;
- bool canPipeline = IsPipeliningPossible(data);
-
- for(i=0; i< data->state.connc->num; i++) {
- bool match = FALSE;
- /*
- * Note that if we use a HTTP proxy, we check connections to that
- * proxy and not to the actual remote server.
- */
- check = data->state.connc->connects[i];
- if(!check)
- /* NULL pointer means not filled-in entry */
- continue;
-
- if (check->connectindex == -1) {
- check->connectindex = i; /* Set this appropriately since it might have
- been set to -1 when the easy was removed
- from the multi */
- }
-
- infof(data, "Examining connection #%ld for reuse\n", check->connectindex);
-
- if(check->inuse && !canPipeline) {
- /* can only happen within multi handles, and means that another easy
- handle is using this connection */
- continue;
- }
-
-#ifdef CURLRES_ASYNCH
- /* ip_addr_str is NULL only if the resolving of the name hasn't completed
- yet and until then we don't re-use this connection */
- if (!check->ip_addr_str) {
- infof(data,
- "Connection #%ld has not finished name resolve, can't reuse\n",
- check->connectindex);
- continue;
- }
-#endif
-
- if (check->send_pipe->size +
- check->recv_pipe->size >= MAX_PIPELINE_LENGTH) {
- infof(data, "Connection #%ld has its pipeline full, can't reuse\n",
- check->connectindex);
- continue;
- }
-
- if (data->state.is_in_pipeline && check->bits.close) {
- /* Don't pick a connection that is going to be closed */
- infof(data, "Connection #%ld has been marked for close, can't reuse\n",
- check->connectindex);
- continue;
- }
-
- if((needle->protocol&PROT_SSL) != (check->protocol&PROT_SSL))
- /* don't do mixed SSL and non-SSL connections */
- continue;
-
- if(!needle->bits.httpproxy || needle->protocol&PROT_SSL) {
- /* The requested connection does not use a HTTP proxy or it
- uses SSL. */
-
- if(!(needle->protocol&PROT_SSL) && check->bits.httpproxy)
- /* we don't do SSL but the cached connection has a proxy,
- then don't match this */
- continue;
-
- if(strequal(needle->protostr, check->protostr) &&
- strequal(needle->host.name, check->host.name) &&
- (needle->remote_port == check->remote_port) ) {
- if(needle->protocol & PROT_SSL) {
- /* This is SSL, verify that we're using the same
- ssl options as well */
- if(!Curl_ssl_config_matches(&needle->ssl_config,
- &check->ssl_config)) {
- infof(data,
- "Connection #%ld has different SSL parameters, "
- "can't reuse\n",
- check->connectindex );
- continue;
- }
- }
- if((needle->protocol & PROT_FTP) ||
- ((needle->protocol & PROT_HTTP) &&
- (data->state.authhost.want==CURLAUTH_NTLM))) {
- /* This is FTP or HTTP+NTLM, verify that we're using the same name
- and password as well */
- if(!strequal(needle->user, check->user) ||
- !strequal(needle->passwd, check->passwd)) {
- /* one of them was different */
- continue;
- }
- }
- match = TRUE;
- }
- }
- else { /* The requested needle connection is using a proxy,
- is the checked one using the same? */
- if(check->bits.httpproxy &&
- strequal(needle->proxy.name, check->proxy.name) &&
- needle->port == check->port) {
- /* This is the same proxy connection, use it! */
- match = TRUE;
- }
- }
-
- if(match) {
- if (!IsPipeliningEnabled(data)) {
- /* The check for a dead socket makes sense only in the
- non-pipelining case */
- bool dead = SocketIsDead(check->sock[FIRSTSOCKET]);
- if(dead) {
- check->data = data;
- infof(data, "Connection #%d seems to be dead!\n", i);
-
- Curl_disconnect(check); /* disconnect resources */
- data->state.connc->connects[i]=NULL; /* nothing here */
-
- return FALSE;
- }
- }
-
- check->inuse = TRUE; /* mark this as being in use so that no other
- handle in a multi stack may nick it */
-
- if (canPipeline) {
- /* Mark the connection as being in a pipeline */
- check->is_in_pipeline = TRUE;
- }
-
- check->connectindex = i; /* Set this appropriately since it might have
- been set to -1 when the easy was removed
- from the multi */
- *usethis = check;
- return TRUE; /* yes, we found one to use! */
- }
- }
-
- return FALSE; /* no matching connecting exists */
-}
-
-
-
-/*
- * This function frees/closes a connection in the connection cache. This
- * should take the previously set policy into account when deciding which
- * of the connections to kill.
- */
-static long
-ConnectionKillOne(struct SessionHandle *data)
-{
- long i;
- struct connectdata *conn;
- long highscore=-1;
- long connindex=-1;
- long score;
- struct timeval now;
-
- now = Curl_tvnow();
-
- for(i=0; data->state.connc && (i< data->state.connc->num); i++) {
- conn = data->state.connc->connects[i];
-
- if(!conn || conn->inuse)
- continue;
-
- /* Set higher score for the age passed since the connection was used */
- score = Curl_tvdiff(now, conn->now);
-
- if(score > highscore) {
- highscore = score;
- connindex = i;
- }
- }
- if(connindex >= 0) {
- /* Set the connection's owner correctly */
- conn = data->state.connc->connects[connindex];
- conn->data = data;
-
- /* the winner gets the honour of being disconnected */
- (void)Curl_disconnect(conn);
-
- /* clean the array entry */
- data->state.connc->connects[connindex] = NULL;
- }
-
- return connindex; /* return the available index or -1 */
-}
-
-/* this connection can now be marked 'idle' */
-static void
-ConnectionDone(struct connectdata *conn)
-{
- conn->inuse = FALSE;
- if (!conn->send_pipe && !conn->recv_pipe)
- conn->is_in_pipeline = FALSE;
-}
-
-/*
- * The given input connection struct pointer is to be stored. If the "cache"
- * is already full, we must clean out the most suitable using the previously
- * set policy.
- *
- * The given connection should be unique. That must've been checked prior to
- * this call.
- */
-static long
-ConnectionStore(struct SessionHandle *data,
- struct connectdata *conn)
-{
- long i;
- for(i=0; i< data->state.connc->num; i++) {
- if(!data->state.connc->connects[i])
- break;
- }
- if(i == data->state.connc->num) {
- /* there was no room available, kill one */
- i = ConnectionKillOne(data);
- if(-1 != i)
- infof(data, "Connection (#%d) was killed to make room (holds %d)\n",
- i, data->state.connc->num);
- else
- infof(data, "This connection did not fit in the connection cache\n");
- }
-
- conn->connectindex = i; /* Make the child know where the pointer to this
- particular data is stored. But note that this -1
- if this is not within the cache and this is
- probably not checked for everywhere (yet). */
- conn->inuse = TRUE;
- if(-1 != i) {
- /* Only do this if a true index was returned, if -1 was returned there
- is no room in the cache for an unknown reason and we cannot store
- this there.
-
- TODO: make sure we really can work with more handles than positions in
- the cache, or possibly we should (allow to automatically) resize the
- connection cache when we add more easy handles to a multi handle!
- */
- data->state.connc->connects[i] = conn; /* fill in this */
- conn->data = data;
- }
-
- return i;
-}
-
-static CURLcode ConnectPlease(struct SessionHandle *data,
- struct connectdata *conn,
- struct Curl_dns_entry *hostaddr,
- bool *connected)
-{
- CURLcode result;
- Curl_addrinfo *addr;
- char *hostname = conn->bits.httpproxy?conn->proxy.name:conn->host.name;
-
- infof(data, "About to connect() to %s%s port %d (#%d)\n",
- conn->bits.httpproxy?"proxy ":"",
- hostname, conn->port, conn->connectindex);
-
- /*************************************************************
- * Connect to server/proxy
- *************************************************************/
- result= Curl_connecthost(conn,
- hostaddr,
- &conn->sock[FIRSTSOCKET],
- &addr,
- connected);
- if(CURLE_OK == result) {
- /* All is cool, then we store the current information */
- conn->dns_entry = hostaddr;
- conn->ip_addr = addr;
-
- Curl_store_ip_addr(conn);
-
- switch(data->set.proxytype) {
- case CURLPROXY_SOCKS5:
- result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, conn);
- break;
- case CURLPROXY_HTTP:
- /* do nothing here. handled later. */
- break;
- case CURLPROXY_SOCKS4:
- result = Curl_SOCKS4(conn->proxyuser, conn);
- break;
- default:
- failf(data, "unknown proxytype option given");
- result = CURLE_COULDNT_CONNECT;
- break;
- }
- }
-
- return result;
-}
-
-/*
- * verboseconnect() displays verbose information after a connect
- */
-static void verboseconnect(struct connectdata *conn)
-{
- infof(conn->data, "Connected to %s (%s) port %d (#%d)\n",
- conn->bits.httpproxy ? conn->proxy.dispname : conn->host.dispname,
- conn->ip_addr_str, conn->port, conn->connectindex);
-}
-
-int Curl_protocol_getsock(struct connectdata *conn,
- curl_socket_t *socks,
- int numsocks)
-{
- if(conn->curl_proto_getsock)
- return conn->curl_proto_getsock(conn, socks, numsocks);
- return GETSOCK_BLANK;
-}
-
-int Curl_doing_getsock(struct connectdata *conn,
- curl_socket_t *socks,
- int numsocks)
-{
- if(conn && conn->curl_doing_getsock)
- return conn->curl_doing_getsock(conn, socks, numsocks);
- return GETSOCK_BLANK;
-}
-
-/*
- * We are doing protocol-specific connecting and this is being called over and
- * over from the multi interface until the connection phase is done on
- * protocol layer.
- */
-
-CURLcode Curl_protocol_connecting(struct connectdata *conn,
- bool *done)
-{
- CURLcode result=CURLE_OK;
-
- if(conn && conn->curl_connecting) {
- *done = FALSE;
- result = conn->curl_connecting(conn, done);
- }
- else
- *done = TRUE;
-
- return result;
-}
-
-/*
- * We are DOING this is being called over and over from the multi interface
- * until the DOING phase is done on protocol layer.
- */
-
-CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done)
-{
- CURLcode result=CURLE_OK;
-
- if(conn && conn->curl_doing) {
- *done = FALSE;
- result = conn->curl_doing(conn, done);
- }
- else
- *done = TRUE;
-
- return result;
-}
-
-/*
- * We have discovered that the TCP connection has been successful, we can now
- * proceed with some action.
- *
- */
-CURLcode Curl_protocol_connect(struct connectdata *conn,
- bool *protocol_done)
-{
- CURLcode result=CURLE_OK;
- struct SessionHandle *data = conn->data;
-
- *protocol_done = FALSE;
-
- if(conn->bits.tcpconnect && conn->bits.protoconnstart) {
- /* We already are connected, get back. This may happen when the connect
- worked fine in the first call, like when we connect to a local server
- or proxy. Note that we don't know if the protocol is actually done.
-
- Unless this protocol doesn't have any protocol-connect callback, as
- then we know we're done. */
- if(!conn->curl_connecting)
- *protocol_done = TRUE;
-
- return CURLE_OK;
- }
-
- if(!conn->bits.tcpconnect) {
-
- Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
-
- if(data->set.verbose)
- verboseconnect(conn);
- }
-
- if(!conn->bits.protoconnstart) {
- if(conn->curl_connect) {
- /* is there a protocol-specific connect() procedure? */
-
- /* Set start time here for timeout purposes in the connect procedure, it
- is later set again for the progress meter purpose */
- conn->now = Curl_tvnow();
-
- /* Call the protocol-specific connect function */
- result = conn->curl_connect(conn, protocol_done);
- }
- else
- *protocol_done = TRUE;
-
- /* it has started, possibly even completed but that knowledge isn't stored
- in this bit! */
- if (!result)
- conn->bits.protoconnstart = TRUE;
- }
-
- return result; /* pass back status */
-}
-
-/*
- * Helpers for IDNA convertions.
- */
-#ifdef USE_LIBIDN
-static bool is_ASCII_name(const char *hostname)
-{
- const unsigned char *ch = (const unsigned char*)hostname;
-
- while (*ch) {
- if (*ch++ & 0x80)
- return FALSE;
- }
- return TRUE;
-}
-
-/*
- * Check if characters in hostname is allowed in Top Level Domain.
- */
-static bool tld_check_name(struct SessionHandle *data,
- const char *ace_hostname)
-{
- size_t err_pos;
- char *uc_name = NULL;
- int rc;
-
- /* Convert (and downcase) ACE-name back into locale's character set */
- rc = idna_to_unicode_lzlz(ace_hostname, &uc_name, 0);
- if (rc != IDNA_SUCCESS)
- return (FALSE);
-
- rc = tld_check_lz(uc_name, &err_pos, NULL);
- if (rc == TLD_INVALID)
- infof(data, "WARNING: %s; pos %u = `%c'/0x%02X\n",
-#ifdef HAVE_TLD_STRERROR
- tld_strerror((Tld_rc)rc),
-#else
- "<no msg>",
-#endif
- err_pos, uc_name[err_pos],
- uc_name[err_pos] & 255);
- else if (rc != TLD_SUCCESS)
- infof(data, "WARNING: TLD check for %s failed; %s\n",
- uc_name,
-#ifdef HAVE_TLD_STRERROR
- tld_strerror((Tld_rc)rc)
-#else
- "<no msg>"
-#endif
- );
- if (uc_name)
- idn_free(uc_name);
- return (bool)(rc == TLD_SUCCESS);
-}
-#endif
-
-static void fix_hostname(struct SessionHandle *data,
- struct connectdata *conn, struct hostname *host)
-{
- /* set the name we use to display the host name */
- host->dispname = host->name;
-
-#ifdef USE_LIBIDN
- /*************************************************************
- * Check name for non-ASCII and convert hostname to ACE form.
- *************************************************************/
- if (!is_ASCII_name(host->name) &&
- stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
- char *ace_hostname = NULL;
- int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0);
- infof (data, "Input domain encoded as `%s'\n",
- stringprep_locale_charset ());
- if (rc != IDNA_SUCCESS)
- infof(data, "Failed to convert %s to ACE; %s\n",
- host->name, Curl_idn_strerror(conn,rc));
- else {
- /* tld_check_name() displays a warning if the host name contains
- "illegal" characters for this TLD */
- (void)tld_check_name(data, ace_hostname);
-
- host->encalloc = ace_hostname;
- /* change the name pointer to point to the encoded hostname */
- host->name = host->encalloc;
- }
- }
-#else
- (void)data; /* never used */
- (void)conn; /* never used */
-#endif
-}
-
-/*
- * Parse URL and fill in the relevant members of the connection struct.
- */
-static CURLcode ParseURLAndFillConnection(struct SessionHandle *data,
- struct connectdata *conn)
-{
- char *at;
- char *tmp;
-
- char *path = data->reqdata.path;
-
- /*************************************************************
- * Parse the URL.
- *
- * We need to parse the url even when using the proxy, because we will need
- * the hostname and port in case we are trying to SSL connect through the
- * proxy -- and we don't know if we will need to use SSL until we parse the
- * url ...
- ************************************************************/
- if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]",
- conn->protostr,
- path)) && strequal(conn->protostr, "file")) {
- if(path[0] == '/' && path[1] == '/') {
- /* Allow omitted hostname (e.g. file:/<path>). This is not strictly
- * speaking a valid file: URL by RFC 1738, but treating file:/<path> as
- * file://localhost/<path> is similar to how other schemes treat missing
- * hostnames. See RFC 1808. */
-
- /* This cannot be done with strcpy() in a portable manner, since the
- memory areas overlap! */
- memmove(path, path + 2, strlen(path + 2)+1);
- }
- /*
- * we deal with file://<host>/<path> differently since it supports no
- * hostname other than "localhost" and "127.0.0.1", which is unique among
- * the URL protocols specified in RFC 1738
- */
- if(path[0] != '/') {
- /* the URL included a host name, we ignore host names in file:// URLs
- as the standards don't define what to do with them */
- char *ptr=strchr(path, '/');
- if(ptr) {
- /* there was a slash present
-
- RFC1738 (section 3.1, page 5) says:
-
- The rest of the locator consists of data specific to the scheme,
- and is known as the "url-path". It supplies the details of how the
- specified resource can be accessed. Note that the "/" between the
- host (or port) and the url-path is NOT part of the url-path.
-
- As most agents use file://localhost/foo to get '/foo' although the
- slash preceding foo is a separator and not a slash for the path,
- a URL as file://localhost//foo must be valid as well, to refer to
- the same file with an absolute path.
- */
-
- if(ptr[1] && ('/' == ptr[1]))
- /* if there was two slashes, we skip the first one as that is then
- used truly as a separator */
- ptr++;
-
- /* This cannot be made with strcpy, as the memory chunks overlap! */
- memmove(path, ptr, strlen(ptr)+1);
- }
- }
-
- strcpy(conn->protostr, "file"); /* store protocol string lowercase */
- }
- else {
- /* clear path */
- path[0]=0;
-
- if (2 > sscanf(data->change.url,
- "%15[^\n:]://%[^\n/]%[^\n]",
- conn->protostr,
- conn->host.name, path)) {
-
- /*
- * The URL was badly formatted, let's try the browser-style _without_
- * protocol specified like 'http://'.
- */
- if((1 > sscanf(data->change.url, "%[^\n/]%[^\n]",
- conn->host.name, path)) ) {
- /*
- * We couldn't even get this format.
- */
- failf(data, "<url> malformed");
- return CURLE_URL_MALFORMAT;
- }
-
- /*
- * Since there was no protocol part specified, we guess what protocol it
- * is based on the first letters of the server name.
- */
-
- /* Note: if you add a new protocol, please update the list in
- * lib/version.c too! */
-
- if(checkprefix("FTP.", conn->host.name))
- strcpy(conn->protostr, "ftp");
- else if (checkprefix("DICT.", conn->host.name))
- strcpy(conn->protostr, "DICT");
- else if (checkprefix("LDAP.", conn->host.name))
- strcpy(conn->protostr, "LDAP");
- else {
- strcpy(conn->protostr, "http");
- }
-
- conn->protocol |= PROT_MISSING; /* not given in URL */
- }
- }
-
- /* We search for '?' in the host name (but only on the right side of a
- * @-letter to allow ?-letters in username and password) to handle things
- * like http://example.com?param= (notice the missing '/').
- */
- at = strchr(conn->host.name, '@');
- if(at)
- tmp = strchr(at+1, '?');
- else
- tmp = strchr(conn->host.name, '?');
-
- if(tmp) {
- /* We must insert a slash before the '?'-letter in the URL. If the URL had
- a slash after the '?', that is where the path currently begins and the
- '?string' is still part of the host name.
-
- We must move the trailing part from the host name and put it first in
- the path. And have it all prefixed with a slash.
- */
-
- size_t hostlen = strlen(tmp);
- size_t pathlen = strlen(path);
-
- /* move the existing path plus the zero byte forward, to make room for
- the host-name part */
- memmove(path+hostlen+1, path, pathlen+1);
-
- /* now copy the trailing host part in front of the existing path */
- memcpy(path+1, tmp, hostlen);
-
- path[0]='/'; /* prepend the missing slash */
-
- *tmp=0; /* now cut off the hostname at the ? */
- }
- else if(!path[0]) {
- /* if there's no path set, use a single slash */
- strcpy(path, "/");
- }
-
- /* If the URL is malformatted (missing a '/' after hostname before path) we
- * insert a slash here. The only letter except '/' we accept to start a path
- * is '?'.
- */
- if(path[0] == '?') {
- /* We need this function to deal with overlapping memory areas. We know
- that the memory area 'path' points to is 'urllen' bytes big and that
- is bigger than the path. Use +1 to move the zero byte too. */
- memmove(&path[1], path, strlen(path)+1);
- path[0] = '/';
- }
-
- /*
- * So if the URL was A://B/C,
- * conn->protostr is A
- * conn->host.name is B
- * data->reqdata.path is /C
- */
-
- return CURLE_OK;
-}
-
-static void llist_dtor(void *user, void *element)
-{
- (void)user;
- (void)element;
- /* Do nothing */
-}
-
-
-/**
- * CreateConnection() sets up a new connectdata struct, or re-uses an already
- * existing one, and resolves host name.
- *
- * if this function returns CURLE_OK and *async is set to TRUE, the resolve
- * response will be coming asynchronously. If *async is FALSE, the name is
- * already resolved.
- *
- * @param data The sessionhandle pointer
- * @param in_connect is set to the next connection data pointer
- * @param addr is set to the new dns entry for this connection. If this
- * connection is re-used it will be NULL.
- * @param async is set TRUE/FALSE depending on the nature of this lookup
- * @return CURLcode
- * @see SetupConnection()
- *
- * *NOTE* this function assigns the conn->data pointer!
- */
-
-static CURLcode CreateConnection(struct SessionHandle *data,
- struct connectdata **in_connect,
- struct Curl_dns_entry **addr,
- bool *async)
-{
-
- char *tmp;
- CURLcode result=CURLE_OK;
- struct connectdata *conn;
- struct connectdata *conn_temp = NULL;
- size_t urllen;
- struct Curl_dns_entry *hostaddr;
-#if defined(HAVE_ALARM) && !defined(USE_ARES)
- unsigned int prev_alarm=0;
-#endif
- char endbracket;
- char user[MAX_CURL_USER_LENGTH];
- char passwd[MAX_CURL_PASSWORD_LENGTH];
- int rc;
- bool reuse;
- char *proxy;
- bool proxy_alloc = FALSE;
-
-#ifndef USE_ARES
-#ifdef SIGALRM
-#ifdef HAVE_SIGACTION
- struct sigaction keep_sigact; /* store the old struct here */
- bool keep_copysig=FALSE; /* did copy it? */
-#else
-#ifdef HAVE_SIGNAL
- void (*keep_sigact)(int); /* store the old handler here */
-#endif /* HAVE_SIGNAL */
-#endif /* HAVE_SIGACTION */
-#endif /* SIGALRM */
-#endif /* USE_ARES */
-
- *addr = NULL; /* nothing yet */
- *async = FALSE;
-
- /*************************************************************
- * Check input data
- *************************************************************/
-
- if(!data->change.url)
- return CURLE_URL_MALFORMAT;
-
- /* First, split up the current URL in parts so that we can use the
- parts for checking against the already present connections. In order
- to not have to modify everything at once, we allocate a temporary
- connection data struct and fill in for comparison purposes. */
-
- conn = (struct connectdata *)calloc(sizeof(struct connectdata), 1);
- if(!conn) {
- *in_connect = NULL; /* clear the pointer */
- return CURLE_OUT_OF_MEMORY;
- }
- /* We must set the return variable as soon as possible, so that our
- parent can cleanup any possible allocs we may have done before
- any failure */
- *in_connect = conn;
-
- /* and we setup a few fields in case we end up actually using this struct */
-
- conn->data = data; /* Setup the association between this connection
- and the SessionHandle */
-
- conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
- conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
- conn->connectindex = -1; /* no index */
-
- conn->bits.httpproxy = (bool)(data->set.proxy /* http proxy or not */
- && *data->set.proxy
- && (data->set.proxytype == CURLPROXY_HTTP));
- proxy = data->set.proxy; /* if global proxy is set, this is it */
-
- /* Default protocol-independent behavior doesn't support persistent
- connections, so we set this to force-close. Protocols that support
- this need to set this to FALSE in their "curl_do" functions. */
- conn->bits.close = TRUE;
-
- conn->readchannel_inuse = FALSE;
- conn->writechannel_inuse = FALSE;
-
- conn->read_pos = 0;
- conn->buf_len = 0;
-
- /* Initialize the pipeline lists */
- conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
- conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
-
- /* Store creation time to help future close decision making */
- conn->created = Curl_tvnow();
-
- /* range status */
- data->reqdata.use_range = (bool)(NULL != data->set.set_range);
-
- data->reqdata.range = data->set.set_range; /* clone the range setting */
- data->reqdata.resume_from = data->set.set_resume_from;
-
- conn->bits.user_passwd = (bool)(NULL != data->set.userpwd);
- conn->bits.proxy_user_passwd = (bool)(NULL != data->set.proxyuserpwd);
- conn->bits.no_body = data->set.opt_no_body;
- conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
- conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
- conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
-
- /* This initing continues below, see the comment "Continue connectdata
- * initialization here" */
-
- /***********************************************************
- * We need to allocate memory to store the path in. We get the size of the
- * full URL to be sure, and we need to make it at least 256 bytes since
- * other parts of the code will rely on this fact
- ***********************************************************/
-#define LEAST_PATH_ALLOC 256
- urllen=strlen(data->change.url);
- if(urllen < LEAST_PATH_ALLOC)
- urllen=LEAST_PATH_ALLOC;
-
- if (!data->set.source_url /* 3rd party FTP */
- && data->reqdata.pathbuffer) {
- /* Free the old buffer */
- free(data->reqdata.pathbuffer);
- }
-
- /*
- * We malloc() the buffers below urllen+2 to make room for to possibilities:
- * 1 - an extra terminating zero
- * 2 - an extra slash (in case a syntax like "www.host.com?moo" is used)
- */
-
- data->reqdata.pathbuffer=(char *)malloc(urllen+2);
- if(NULL == data->reqdata.pathbuffer)
- return CURLE_OUT_OF_MEMORY; /* really bad error */
- data->reqdata.path = data->reqdata.pathbuffer;
-
- conn->host.rawalloc=(char *)malloc(urllen+2);
- if(NULL == conn->host.rawalloc)
- return CURLE_OUT_OF_MEMORY;
-
- conn->host.name = conn->host.rawalloc;
- conn->host.name[0] = 0;
-
- result = ParseURLAndFillConnection(data, conn);
- if (result != CURLE_OK) {
- return result;
- }
-
- /*************************************************************
- * Take care of proxy authentication stuff
- *************************************************************/
- if(conn->bits.proxy_user_passwd) {
- char proxyuser[MAX_CURL_USER_LENGTH]="";
- char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
-
- sscanf(data->set.proxyuserpwd,
- "%" MAX_CURL_USER_LENGTH_TXT "[^:]:"
- "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]",
- proxyuser, proxypasswd);
-
- conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
- if(!conn->proxyuser)
- return CURLE_OUT_OF_MEMORY;
-
- conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
- if(!conn->proxypasswd)
- return CURLE_OUT_OF_MEMORY;
- }
-
-#ifndef CURL_DISABLE_HTTP
- /*************************************************************
- * Detect what (if any) proxy to use
- *************************************************************/
- if(!conn->bits.httpproxy) {
- /* If proxy was not specified, we check for default proxy environment
- * variables, to enable i.e Lynx compliance:
- *
- * http_proxy=http://some.server.dom:port/
- * https_proxy=http://some.server.dom:port/
- * ftp_proxy=http://some.server.dom:port/
- * no_proxy=domain1.dom,host.domain2.dom
- * (a comma-separated list of hosts which should
- * not be proxied, or an asterisk to override
- * all proxy variables)
- * all_proxy=http://some.server.dom:port/
- * (seems to exist for the CERN www lib. Probably
- * the first to check for.)
- *
- * For compatibility, the all-uppercase versions of these variables are
- * checked if the lowercase versions don't exist.
- */
- char *no_proxy=NULL;
- char *no_proxy_tok_buf;
- char proxy_env[128];
-
- no_proxy=curl_getenv("no_proxy");
- if(!no_proxy)
- no_proxy=curl_getenv("NO_PROXY");
-
- if(!no_proxy || !strequal("*", no_proxy)) {
- /* NO_PROXY wasn't specified or it wasn't just an asterisk */
- char *nope;
-
- nope=no_proxy?strtok_r(no_proxy, ", ", &no_proxy_tok_buf):NULL;
- while(nope) {
- size_t namelen;
- char *endptr = strchr(conn->host.name, ':');
- if(endptr)
- namelen=endptr-conn->host.name;
- else
- namelen=strlen(conn->host.name);
-
- if(strlen(nope) <= namelen) {
- char *checkn=
- conn->host.name + namelen - strlen(nope);
- if(checkprefix(nope, checkn)) {
- /* no proxy for this host! */
- break;
- }
- }
- nope=strtok_r(NULL, ", ", &no_proxy_tok_buf);
- }
- if(!nope) {
- /* It was not listed as without proxy */
- char *protop = conn->protostr;
- char *envp = proxy_env;
- char *prox;
-
- /* Now, build <protocol>_proxy and check for such a one to use */
- while(*protop)
- *envp++ = (char)tolower((int)*protop++);
-
- /* append _proxy */
- strcpy(envp, "_proxy");
-
- /* read the protocol proxy: */
- prox=curl_getenv(proxy_env);
-
- /*
- * We don't try the uppercase version of HTTP_PROXY because of
- * security reasons:
- *
- * When curl is used in a webserver application
- * environment (cgi or php), this environment variable can
- * be controlled by the web server user by setting the
- * http header 'Proxy:' to some value.
- *
- * This can cause 'internal' http/ftp requests to be
- * arbitrarily redirected by any external attacker.
- */
- if(!prox && !strequal("http_proxy", proxy_env)) {
- /* There was no lowercase variable, try the uppercase version: */
- for(envp = proxy_env; *envp; envp++)
- *envp = (char)toupper((int)*envp);
- prox=curl_getenv(proxy_env);
- }
-
- if(prox && *prox) { /* don't count "" strings */
- proxy = prox; /* use this */
- }
- else {
- proxy = curl_getenv("all_proxy"); /* default proxy to use */
- if(!proxy)
- proxy=curl_getenv("ALL_PROXY");
- }
-
- if(proxy && *proxy) {
- long bits = conn->protocol & (PROT_HTTPS|PROT_SSL|PROT_MISSING);
- /* force this to become HTTP */
- conn->protocol = PROT_HTTP | bits;
-
- proxy_alloc=TRUE; /* this needs to be freed later */
- conn->bits.httpproxy = TRUE;
- }
- } /* if (!nope) - it wasn't specified non-proxy */
- } /* NO_PROXY wasn't specified or '*' */
- if(no_proxy)
- free(no_proxy);
- } /* if not using proxy */
-#endif /* CURL_DISABLE_HTTP */
-
- /*************************************************************
- * No protocol part in URL was used, add it!
- *************************************************************/
- if(conn->protocol&PROT_MISSING) {
- /* We're guessing prefixes here and if we're told to use a proxy or if
- we're gonna follow a Location: later or... then we need the protocol
- part added so that we have a valid URL. */
- char *reurl;
-
- reurl = aprintf("%s://%s", conn->protostr, data->change.url);
-
- if(!reurl)
- return CURLE_OUT_OF_MEMORY;
-
- data->change.url = reurl;
- data->change.url_alloc = TRUE; /* free this later */
- conn->protocol &= ~PROT_MISSING; /* switch that one off again */
- }
-
-#ifndef CURL_DISABLE_HTTP
- /************************************************************
- * RESUME on a HTTP page is a tricky business. First, let's just check that
- * 'range' isn't used, then set the range parameter and leave the resume as
- * it is to inform about this situation for later use. We will then
- * "attempt" to resume, and if we're talking to a HTTP/1.1 (or later)
- * server, we will get the document resumed. If we talk to a HTTP/1.0
- * server, we just fail since we can't rewind the file writing from within
- * this function.
- ***********************************************************/
- if(data->reqdata.resume_from) {
- if(!data->reqdata.use_range) {
- /* if it already was in use, we just skip this */
- data->reqdata.range = aprintf("%" FORMAT_OFF_T "-", data->reqdata.resume_from);
- if(!data->reqdata.range)
- return CURLE_OUT_OF_MEMORY;
- data->reqdata.rangestringalloc = TRUE; /* mark as allocated */
- data->reqdata.use_range = 1; /* switch on range usage */
- }
- }
-#endif
- /*************************************************************
- * Setup internals depending on protocol
- *************************************************************/
-
- conn->socktype = SOCK_STREAM; /* most of them are TCP streams */
-
- if (strequal(conn->protostr, "HTTP")) {
-#ifndef CURL_DISABLE_HTTP
- conn->port = PORT_HTTP;
- conn->remote_port = PORT_HTTP;
- conn->protocol |= PROT_HTTP;
- conn->curl_do = Curl_http;
- conn->curl_do_more = (Curl_do_more_func)ZERO_NULL;
- conn->curl_done = Curl_http_done;
- conn->curl_connect = Curl_http_connect;
-#else
- failf(data, LIBCURL_NAME
- " was built with HTTP disabled, http: not supported!");
- return CURLE_UNSUPPORTED_PROTOCOL;
-#endif
- }
- else if (strequal(conn->protostr, "HTTPS")) {
-#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
-
- conn->port = PORT_HTTPS;
- conn->remote_port = PORT_HTTPS;
- conn->protocol |= PROT_HTTP|PROT_HTTPS|PROT_SSL;
-
- conn->curl_do = Curl_http;
- conn->curl_do_more = (Curl_do_more_func)ZERO_NULL;
- conn->curl_done = Curl_http_done;
- conn->curl_connect = Curl_http_connect;
- conn->curl_connecting = Curl_https_connecting;
- conn->curl_proto_getsock = Curl_https_getsock;
-
-#else /* USE_SSL */
- failf(data, LIBCURL_NAME
- " was built with SSL disabled, https: not supported!");
- return CURLE_UNSUPPORTED_PROTOCOL;
-#endif /* !USE_SSL */
- }
- else if(strequal(conn->protostr, "FTP") ||
- strequal(conn->protostr, "FTPS")) {
-
-#ifndef CURL_DISABLE_FTP
- char *type;
- int port = PORT_FTP;
-
- if(strequal(conn->protostr, "FTPS")) {
-#ifdef USE_SSL
- conn->protocol |= PROT_FTPS|PROT_SSL;
- conn->ssl[SECONDARYSOCKET].use = TRUE; /* send data securely */
- port = PORT_FTPS;
-#else
- failf(data, LIBCURL_NAME
- " was built with SSL disabled, ftps: not supported!");
- return CURLE_UNSUPPORTED_PROTOCOL;
-#endif /* !USE_SSL */
- }
-
- conn->port = port;
- conn->remote_port = (unsigned short)port;
- conn->protocol |= PROT_FTP;
-
- if(proxy && *proxy && !data->set.tunnel_thru_httpproxy) {
- /* Unless we have asked to tunnel ftp operations through the proxy, we
- switch and use HTTP operations only */
-#ifndef CURL_DISABLE_HTTP
- conn->curl_do = Curl_http;
- conn->curl_done = Curl_http_done;
- conn->protocol = PROT_HTTP; /* switch to HTTP */
-#else
- failf(data, "FTP over http proxy requires HTTP support built-in!");
- return CURLE_UNSUPPORTED_PROTOCOL;
-#endif
- }
- else {
- conn->curl_do = Curl_ftp;
- conn->curl_do_more = Curl_ftp_nextconnect;
- conn->curl_done = Curl_ftp_done;
- conn->curl_connect = Curl_ftp_connect;
- conn->curl_connecting = Curl_ftp_multi_statemach;
- conn->curl_doing = Curl_ftp_doing;
- conn->curl_proto_getsock = Curl_ftp_getsock;
- conn->curl_doing_getsock = Curl_ftp_getsock;
- conn->curl_disconnect = Curl_ftp_disconnect;
- }
-
- data->reqdata.path++; /* don't include the initial slash */
-
- /* FTP URLs support an extension like ";type=<typecode>" that
- * we'll try to get now! */
- type=strstr(data->reqdata.path, ";type=");
- if(!type) {
- type=strstr(conn->host.rawalloc, ";type=");
- }
- if(type) {
- char command;
- *type=0; /* it was in the middle of the hostname */
- command = (char)toupper((int)type[6]);
- switch(command) {
- case 'A': /* ASCII mode */
- data->set.prefer_ascii = TRUE;
- break;
- case 'D': /* directory mode */
- data->set.ftp_list_only = TRUE;
- break;
- case 'I': /* binary mode */
- default:
- /* switch off ASCII */
- data->set.prefer_ascii = FALSE;
- break;
- }
- }
-#else /* CURL_DISABLE_FTP */
- failf(data, LIBCURL_NAME
- " was built with FTP disabled, ftp/ftps: not supported!");
- return CURLE_UNSUPPORTED_PROTOCOL;
-#endif
- }
- else if(strequal(conn->protostr, "TELNET")) {
-#ifndef CURL_DISABLE_TELNET
- /* telnet testing factory */
- conn->protocol |= PROT_TELNET;
-
- conn->port = PORT_TELNET;
- conn->remote_port = PORT_TELNET;
- conn->curl_do = Curl_telnet;
- conn->curl_done = Curl_telnet_done;
-#else
- failf(data, LIBCURL_NAME
- " was built with TELNET disabled!");
-#endif
- }
- else if (strequal(conn->protostr, "DICT")) {
-#ifndef CURL_DISABLE_DICT
- conn->protocol |= PROT_DICT;
- conn->port = PORT_DICT;
- conn->remote_port = PORT_DICT;
- conn->curl_do = Curl_dict;
- /* no DICT-specific done */
- conn->curl_done = (Curl_done_func)ZERO_NULL;
-#else
- failf(data, LIBCURL_NAME
- " was built with DICT disabled!");
-#endif
- }
- else if (strequal(conn->protostr, "LDAP")) {
-#ifndef CURL_DISABLE_LDAP
- conn->protocol |= PROT_LDAP;
- conn->port = PORT_LDAP;
- conn->remote_port = PORT_LDAP;
- conn->curl_do = Curl_ldap;
- /* no LDAP-specific done */
- conn->curl_done = (Curl_done_func)ZERO_NULL;
-#else
- failf(data, LIBCURL_NAME
- " was built with LDAP disabled!");
-#endif
- }
- else if (strequal(conn->protostr, "FILE")) {
-#ifndef CURL_DISABLE_FILE
- conn->protocol |= PROT_FILE;
-
- conn->curl_do = Curl_file;
- conn->curl_done = Curl_file_done;
-
- /* anyway, this is supposed to be the connect function so we better
- at least check that the file is present here! */
- result = Curl_file_connect(conn);
-
- /* Setup a "faked" transfer that'll do nothing */
- if(CURLE_OK == result) {
- conn->data = data;
- conn->bits.tcpconnect = TRUE; /* we are "connected */
- ConnectionStore(data, conn);
-
- result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
- -1, NULL); /* no upload */
- }
-
- return result;
-#else
- failf(data, LIBCURL_NAME
- " was built with FILE disabled!");
-#endif
- }
- else if (strequal(conn->protostr, "TFTP")) {
-#ifndef CURL_DISABLE_TFTP
- char *type;
- conn->socktype = SOCK_DGRAM; /* UDP datagram based */
- conn->protocol |= PROT_TFTP;
- conn->port = PORT_TFTP;
- conn->remote_port = PORT_TFTP;
- conn->curl_connect = Curl_tftp_connect;
- conn->curl_do = Curl_tftp;
- conn->curl_done = Curl_tftp_done;
- /* TFTP URLs support an extension like ";mode=<typecode>" that
- * we'll try to get now! */
- type=strstr(data->reqdata.path, ";mode=");
- if(!type) {
- type=strstr(conn->host.rawalloc, ";mode=");
- }
- if(type) {
- char command;
- *type=0; /* it was in the middle of the hostname */
- command = (char)toupper((int)type[6]);
- switch(command) {
- case 'A': /* ASCII mode */
- case 'N': /* NETASCII mode */
- data->set.prefer_ascii = TRUE;
- break;
- case 'O': /* octet mode */
- case 'I': /* binary mode */
- default:
- /* switch off ASCII */
- data->set.prefer_ascii = FALSE;
- break;
- }
- }
-#else
- failf(data, LIBCURL_NAME
- " was built with TFTP disabled!");
-#endif
- }
- else if (strequal(conn->protostr, "SCP")) {
-#ifdef USE_LIBSSH2
- conn->port = PORT_SSH;
- conn->remote_port = PORT_SSH;
- conn->protocol = PROT_SCP;
- conn->curl_connect = Curl_ssh_connect; /* ssh_connect? */
- conn->curl_do = Curl_scp_do;
- conn->curl_done = Curl_scp_done;
- conn->curl_do_more = (Curl_do_more_func)ZERO_NULL;
-#else
- failf(data, LIBCURL_NAME
- " was built without LIBSSH2, scp: not supported!");
- return CURLE_UNSUPPORTED_PROTOCOL;
-#endif
- }
- else if (strequal(conn->protostr, "SFTP")) {
-#ifdef USE_LIBSSH2
- conn->port = PORT_SSH;
- conn->remote_port = PORT_SSH;
- conn->protocol = PROT_SFTP;
- conn->curl_connect = Curl_ssh_connect; /* ssh_connect? */
- conn->curl_do = Curl_sftp_do;
- conn->curl_done = Curl_sftp_done;
- conn->curl_do_more = (Curl_do_more_func)NULL;
-#else
- failf(data, LIBCURL_NAME
- " was built without LIBSSH2, scp: not supported!");
- return CURLE_UNSUPPORTED_PROTOCOL;
-#endif
-}
-else {
- /* We fell through all checks and thus we don't support the specified
- protocol */
- failf(data, "Unsupported protocol: %s", conn->protostr);
- return CURLE_UNSUPPORTED_PROTOCOL;
- }
-
- if(proxy && *proxy) {
- /* If this is supposed to use a proxy, we need to figure out the proxy
- host name name, so that we can re-use an existing connection
- that may exist registered to the same proxy host. */
-
- char *prox_portno;
- char *endofprot;
-
- /* We need to make a duplicate of the proxy so that we can modify the
- string safely. If 'proxy_alloc' is TRUE, the string is already
- allocated and we can treat it as duplicated. */
- char *proxydup=proxy_alloc?proxy:strdup(proxy);
-
- /* We use 'proxyptr' to point to the proxy name from now on... */
- char *proxyptr=proxydup;
- char *portptr;
- char *atsign;
-
- if(NULL == proxydup) {
- failf(data, "memory shortage");
- return CURLE_OUT_OF_MEMORY;
- }
-
- /* We do the proxy host string parsing here. We want the host name and the
- * port name. Accept a protocol:// prefix, even though it should just be
- * ignored.
- */
-
- /* Skip the protocol part if present */
- endofprot=strstr(proxyptr, "://");
- if(endofprot)
- proxyptr = endofprot+3;
-
- /* Is there a username and password given in this proxy url? */
- atsign = strchr(proxyptr, '@');
- if(atsign) {
- char proxyuser[MAX_CURL_USER_LENGTH];
- char proxypasswd[MAX_CURL_PASSWORD_LENGTH];
- proxypasswd[0] = 0;
-
- if(1 <= sscanf(proxyptr,
- "%" MAX_CURL_USER_LENGTH_TXT"[^:]:"
- "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]",
- proxyuser, proxypasswd)) {
- CURLcode res = CURLE_OK;
-
- /* found user and password, rip them out. note that we are
- unescaping them, as there is otherwise no way to have a
- username or password with reserved characters like ':' in
- them. */
- Curl_safefree(conn->proxyuser);
- conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
-
- if(!conn->proxyuser)
- res = CURLE_OUT_OF_MEMORY;
- else {
- Curl_safefree(conn->proxypasswd);
- conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
-
- if(!conn->proxypasswd)
- res = CURLE_OUT_OF_MEMORY;
- }
-
- if(CURLE_OK == res) {
- conn->bits.proxy_user_passwd = TRUE; /* enable it */
- atsign = strdup(atsign+1); /* the right side of the @-letter */
-
- if(atsign) {
- free(proxydup); /* free the former proxy string */
- proxydup = proxyptr = atsign; /* now use this instead */
- }
- else
- res = CURLE_OUT_OF_MEMORY;
- }
-
- if(res) {
- free(proxydup); /* free the allocated proxy string */
- return res;
- }
- }
- }
-
- /* start scanning for port number at this point */
- portptr = proxyptr;
-
- /* detect and extract RFC2732-style IPv6-addresses */
- if(*proxyptr == '[') {
- char *ptr = ++proxyptr; /* advance beyond the initial bracket */
- while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':')))
- ptr++;
- if(*ptr == ']') {
- /* yeps, it ended nicely with a bracket as well */
- *ptr = 0;
- portptr = ptr+1;
- }
- /* Note that if this didn't end with a bracket, we still advanced the
- * proxyptr first, but I can't see anything wrong with that as no host
- * name nor a numeric can legally start with a bracket.
- */
- }
-
- /* Get port number off proxy.server.com:1080 */
- prox_portno = strchr(portptr, ':');
- if (prox_portno) {
- *prox_portno = 0x0; /* cut off number from host name */
- prox_portno ++;
- /* now set the local port number */
- conn->port = atoi(prox_portno);
- }
- else if(data->set.proxyport) {
- /* None given in the proxy string, then get the default one if it is
- given */
- conn->port = data->set.proxyport;
- }
-
- /* now, clone the cleaned proxy host name */
- conn->proxy.rawalloc = strdup(proxyptr);
- conn->proxy.name = conn->proxy.rawalloc;
-
- free(proxydup); /* free the duplicate pointer and not the modified */
- proxy = NULL; /* this may have just been freed */
- if(!conn->proxy.rawalloc)
- return CURLE_OUT_OF_MEMORY;
- }
-
- /*************************************************************
- * If the protocol is using SSL and HTTP proxy is used, we set
- * the tunnel_proxy bit.
- *************************************************************/
- if((conn->protocol&PROT_SSL) && conn->bits.httpproxy)
- conn->bits.tunnel_proxy = TRUE;
-
- /*************************************************************
- * Take care of user and password authentication stuff
- *************************************************************/
-
- /*
- * Inputs: data->set.userpwd (CURLOPT_USERPWD)
- * data->set.fpasswd (CURLOPT_PASSWDFUNCTION)
- * data->set.use_netrc (CURLOPT_NETRC)
- * conn->host.name
- * netrc file
- * hard-coded defaults
- *
- * Outputs: (almost :- all currently undefined)
- * conn->bits.user_passwd - non-zero if non-default passwords exist
- * conn->user - non-zero length if defined
- * conn->passwd - ditto
- * conn->host.name - remove user name and password
- */
-
- /* At this point, we're hoping all the other special cases have
- * been taken care of, so conn->host.name is at most
- * [user[:password]]@]hostname
- *
- * We need somewhere to put the embedded details, so do that first.
- */
-
- user[0] =0; /* to make everything well-defined */
- passwd[0]=0;
-
- if (conn->protocol & (PROT_FTP|PROT_HTTP|PROT_SCP|PROT_SFTP)) {
- /* This is a FTP, HTTP, SCP or SFTP URL, we will now try to extract the
- * possible user+password pair in a string like:
- * ftp://user:password@ftp.my.site:8021/README */
- char *ptr=strchr(conn->host.name, '@');
- char *userpass = conn->host.name;
- if(ptr != NULL) {
- /* there's a user+password given here, to the left of the @ */
-
- conn->host.name = ++ptr;
-
- /* So the hostname is sane. Only bother interpreting the
- * results if we could care. It could still be wasted
- * work because it might be overtaken by the programmatically
- * set user/passwd, but doing that first adds more cases here :-(
- */
-
- if (data->set.use_netrc != CURL_NETRC_REQUIRED) {
- /* We could use the one in the URL */
-
- conn->bits.user_passwd = 1; /* enable user+password */
-
- if(*userpass != ':') {
- /* the name is given, get user+password */
- sscanf(userpass, "%" MAX_CURL_USER_LENGTH_TXT "[^:@]:"
- "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]",
- user, passwd);
- }
- else
- /* no name given, get the password only */
- sscanf(userpass, ":%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", passwd);
-
- if(user[0]) {
- char *newname=curl_easy_unescape(data, user, 0, NULL);
- if(!newname)
- return CURLE_OUT_OF_MEMORY;
- if(strlen(newname) < sizeof(user))
- strcpy(user, newname);
-
- /* if the new name is longer than accepted, then just use
- the unconverted name, it'll be wrong but what the heck */
- free(newname);
- }
- if (passwd[0]) {
- /* we have a password found in the URL, decode it! */
- char *newpasswd=curl_easy_unescape(data, passwd, 0, NULL);
- if(!newpasswd)
- return CURLE_OUT_OF_MEMORY;
- if(strlen(newpasswd) < sizeof(passwd))
- strcpy(passwd, newpasswd);
-
- free(newpasswd);
- }
- }
- }
- }
-
- /*************************************************************
- * Figure out the remote port number
- *
- * No matter if we use a proxy or not, we have to figure out the remote
- * port number of various reasons.
- *
- * To be able to detect port number flawlessly, we must not confuse them
- * IPv6-specified addresses in the [0::1] style. (RFC2732)
- *
- * The conn->host.name is currently [user:passwd@]host[:port] where host
- * could be a hostname, IPv4 address or IPv6 address.
- *************************************************************/
- if((1 == sscanf(conn->host.name, "[%*39[0-9a-fA-F:.]%c", &endbracket)) &&
- (']' == endbracket)) {
- /* this is a RFC2732-style specified IP-address */
- conn->bits.ipv6_ip = TRUE;
-
- conn->host.name++; /* pass the starting bracket */
- tmp = strchr(conn->host.name, ']');
- *tmp = 0; /* zero terminate */
- tmp++; /* pass the ending bracket */
- if(':' != *tmp)
- tmp = NULL; /* no port number available */
- }
- else
- tmp = strrchr(conn->host.name, ':');
-
- if(data->set.use_port && data->state.allow_port) {
- /* if set, we use this and ignore the port possibly given in the URL */
- conn->remote_port = (unsigned short)data->set.use_port;
- if(tmp)
- *tmp = '\0'; /* cut off the name there anyway - if there was a port
- number - since the port number is to be ignored! */
- if(conn->bits.httpproxy) {
- /* we need to create new URL with the new port number */
- char *url;
-
- url = aprintf("http://%s:%d%s", conn->host.name, conn->remote_port,
- data->reqdata.path);
- if(!url)
- return CURLE_OUT_OF_MEMORY;
-
- if(data->change.url_alloc)
- free(data->change.url);
-
- data->change.url = url;
- data->change.url_alloc = TRUE;
- }
- }
- else if (tmp) {
- /* no CURLOPT_PORT given, extract the one from the URL */
-
- char *rest;
- unsigned long port;
-
- port=strtoul(tmp+1, &rest, 10); /* Port number must be decimal */
-
- if (rest != (tmp+1) && *rest == '\0') {
- /* The colon really did have only digits after it,
- * so it is either a port number or a mistake */
-
- if (port > 0xffff) { /* Single unix standard says port numbers are
- * 16 bits long */
- failf(data, "Port number too large: %lu", port);
- return CURLE_URL_MALFORMAT;
- }
-
- *tmp = '\0'; /* cut off the name there */
- conn->remote_port = (unsigned short)port;
- }
- }
-
- /* Programmatically set password:
- * - always applies, if available
- * - takes precedence over the values we just set above
- * so scribble it over the top.
- * User-supplied passwords are assumed not to need unescaping.
- *
- * user_password is set in "inherit initial knowledge' above,
- * so it doesn't have to be set in this block
- */
- if (data->set.userpwd != NULL) {
- /* the name is given, get user+password */
- sscanf(data->set.userpwd,
- "%" MAX_CURL_USER_LENGTH_TXT "[^:]:"
- "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^\n]",
- user, passwd);
- }
-
- conn->bits.netrc = FALSE;
- if (data->set.use_netrc != CURL_NETRC_IGNORED) {
- if(Curl_parsenetrc(conn->host.name,
- user, passwd,
- data->set.netrc_file)) {
- infof(data, "Couldn't find host %s in the " DOT_CHAR
- "netrc file, using defaults\n",
- conn->host.name);
- }
- else {
- /* set bits.netrc TRUE to remember that we got the name from a .netrc
- file, so that it is safe to use even if we followed a Location: to a
- different host or similar. */
- conn->bits.netrc = TRUE;
-
- conn->bits.user_passwd = 1; /* enable user+password */
- }
- }
-
- /* If our protocol needs a password and we have none, use the defaults */
- if ( (conn->protocol & PROT_FTP) &&
- !conn->bits.user_passwd) {
-
- conn->user = strdup(CURL_DEFAULT_USER);
- conn->passwd = strdup(CURL_DEFAULT_PASSWORD);
- /* This is the default password, so DON'T set conn->bits.user_passwd */
- }
- else {
- /* store user + password, zero-length if not set */
- conn->user = strdup(user);
- conn->passwd = strdup(passwd);
- }
- if(!conn->user || !conn->passwd)
- return CURLE_OUT_OF_MEMORY;
-
- /*************************************************************
- * Check the current list of connections to see if we can
- * re-use an already existing one or if we have to create a
- * new one.
- *************************************************************/
-
- /* get a cloned copy of the SSL config situation stored in the
- connection struct */
- if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config))
- return CURLE_OUT_OF_MEMORY;
-
- /* reuse_fresh is TRUE if we are told to use a new connection by force, but
- we only acknowledge this option if this is not a re-used connection
- already (which happens due to follow-location or during a HTTP
- authentication phase). */
- if(data->set.reuse_fresh && !data->state.this_is_a_follow)
- reuse = FALSE;
- else
- reuse = ConnectionExists(data, conn, &conn_temp);
-
- if(reuse) {
- /*
- * We already have a connection for this, we got the former connection
- * in the conn_temp variable and thus we need to cleanup the one we
- * just allocated before we can move along and use the previously
- * existing one.
- */
- struct connectdata *old_conn = conn;
-
- if(old_conn->proxy.rawalloc)
- free(old_conn->proxy.rawalloc);
-
- /* free the SSL config struct from this connection struct as this was
- allocated in vain and is targeted for destruction */
- Curl_free_ssl_config(&conn->ssl_config);
-
- conn = conn_temp; /* use this connection from now on */
-
- conn->data = old_conn->data;
-
- /* get the user+password information from the old_conn struct since it may
- * be new for this request even when we re-use an existing connection */
- conn->bits.user_passwd = old_conn->bits.user_passwd;
- if (conn->bits.user_passwd) {
- /* use the new user namd and password though */
- Curl_safefree(conn->user);
- Curl_safefree(conn->passwd);
- conn->user = old_conn->user;
- conn->passwd = old_conn->passwd;
- old_conn->user = NULL;
- old_conn->passwd = NULL;
- }
-
- conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
- if (conn->bits.proxy_user_passwd) {
- /* use the new proxy user name and proxy password though */
- Curl_safefree(conn->proxyuser);
- Curl_safefree(conn->proxypasswd);
- conn->proxyuser = old_conn->proxyuser;
- conn->proxypasswd = old_conn->proxypasswd;
- old_conn->proxyuser = NULL;
- old_conn->proxypasswd = NULL;
- }
-
- /* host can change, when doing keepalive with a proxy ! */
- if (conn->bits.httpproxy) {
- free(conn->host.rawalloc);
- conn->host=old_conn->host;
- }
-
- /* get the newly set value, not the old one */
- conn->bits.no_body = old_conn->bits.no_body;
-
- if (!conn->bits.httpproxy)
- free(old_conn->host.rawalloc); /* free the newly allocated name buffer */
-
- /* re-use init */
- conn->bits.reuse = TRUE; /* yes, we're re-using here */
- conn->bits.chunk = FALSE; /* always assume not chunked unless told
- otherwise */
-
- Curl_safefree(old_conn->user);
- Curl_safefree(old_conn->passwd);
- Curl_safefree(old_conn->proxyuser);
- Curl_safefree(old_conn->proxypasswd);
- Curl_llist_destroy(old_conn->send_pipe, NULL);
- Curl_llist_destroy(old_conn->recv_pipe, NULL);
-
- free(old_conn); /* we don't need this anymore */
-
- /*
- * If we're doing a resumed transfer, we need to setup our stuff
- * properly.
- */
- data->reqdata.resume_from = data->set.set_resume_from;
- if (data->reqdata.resume_from) {
- if (data->reqdata.rangestringalloc == TRUE)
- free(data->reqdata.range);
- data->reqdata.range = aprintf("%" FORMAT_OFF_T "-",
- data->reqdata.resume_from);
- if(!data->reqdata.range)
- return CURLE_OUT_OF_MEMORY;
-
- /* tell ourselves to fetch this range */
- data->reqdata.use_range = TRUE; /* enable range download */
- data->reqdata.rangestringalloc = TRUE; /* mark range string allocated */
- }
- else if (data->set.set_range) {
- /* There is a range, but is not a resume, useful for random ftp access */
- data->reqdata.range = strdup(data->set.set_range);
- if(!data->reqdata.range)
- return CURLE_OUT_OF_MEMORY;
- data->reqdata.rangestringalloc = TRUE; /* mark range string allocated */
- data->reqdata.use_range = TRUE; /* enable range download */
- }
- else
- data->reqdata.use_range = FALSE; /* disable range download */
-
- *in_connect = conn; /* return this instead! */
-
- infof(data, "Re-using existing connection! (#%ld) with host %s\n",
- conn->connectindex,
- conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
- }
- else {
- /*
- * This is a brand new connection, so let's store it in the connection
- * cache of ours!
- */
- ConnectionStore(data, conn);
- }
-
- /* Continue connectdata initialization here. */
-
- /*
- *
- * Inherit the proper values from the urldata struct AFTER we have arranged
- * the persistent connection stuff */
- conn->fread = data->set.fread;
- conn->fread_in = data->set.in;
-
- if ((conn->protocol&PROT_HTTP) &&
- data->set.upload &&
- (data->set.infilesize == -1) &&
- (data->set.httpversion != CURL_HTTP_VERSION_1_0)) {
- /* HTTP, upload, unknown file size and not HTTP 1.0 */
- conn->bits.upload_chunky = TRUE;
- }
- else {
- /* else, no chunky upload */
- conn->bits.upload_chunky = FALSE;
- }
-
-#ifndef USE_ARES
- /*************************************************************
- * Set timeout if that is being used, and we're not using an asynchronous
- * name resolve.
- *************************************************************/
- if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) {
- /*************************************************************
- * Set signal handler to catch SIGALRM
- * Store the old value to be able to set it back later!
- *************************************************************/
-
-#ifdef SIGALRM
-#ifdef HAVE_ALARM
- long shortest;
-#endif
-#ifdef HAVE_SIGACTION
- struct sigaction sigact;
- sigaction(SIGALRM, NULL, &sigact);
- keep_sigact = sigact;
- keep_copysig = TRUE; /* yes, we have a copy */
- sigact.sa_handler = alarmfunc;
-#ifdef SA_RESTART
- /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */
- sigact.sa_flags &= ~SA_RESTART;
-#endif
- /* now set the new struct */
- sigaction(SIGALRM, &sigact, NULL);
-#else /* HAVE_SIGACTION */
- /* no sigaction(), revert to the much lamer signal() */
-#ifdef HAVE_SIGNAL
- keep_sigact = signal(SIGALRM, alarmfunc);
-#endif
-#endif /* HAVE_SIGACTION */
-
- /* We set the timeout on the name resolving phase first, separately from
- * the download/upload part to allow a maximum time on everything. This is
- * a signal-based timeout, why it won't work and shouldn't be used in
- * multi-threaded environments. */
-
-#ifdef HAVE_ALARM
- shortest = data->set.timeout; /* default to this timeout value */
- if(shortest && data->set.connecttimeout &&
- (data->set.connecttimeout < shortest))
- /* if both are set, pick the shortest */
- shortest = data->set.connecttimeout;
- else if(!shortest)
- /* if timeout is not set, use the connect timeout */
- shortest = data->set.connecttimeout;
-
- /* alarm() makes a signal get sent when the timeout fires off, and that
- will abort system calls */
- prev_alarm = alarm((unsigned int) shortest);
- /* We can expect the conn->created time to be "now", as that was just
- recently set in the beginning of this function and nothing slow
- has been done since then until now. */
-#endif
-#endif /* SIGALRM */
- }
-#endif /* USE_ARES */
-
- /*************************************************************
- * Resolve the name of the server or proxy
- *************************************************************/
- if(conn->bits.reuse) {
- /* re-used connection, no resolving is necessary */
- hostaddr = NULL;
- /* we'll need to clear conn->dns_entry later in Curl_disconnect() */
-
- if (conn->bits.httpproxy)
- fix_hostname(data, conn, &conn->host);
- }
- else {
- /* this is a fresh connect */
-
- /* set a pointer to the hostname we display */
- fix_hostname(data, conn, &conn->host);
-
- if(!conn->proxy.name || !*conn->proxy.name) {
- /* If not connecting via a proxy, extract the port from the URL, if it is
- * there, thus overriding any defaults that might have been set above. */
- conn->port = conn->remote_port; /* it is the same port */
-
- /* Resolve target host right on */
- rc = Curl_resolv(conn, conn->host.name, (int)conn->port, &hostaddr);
- if(rc == CURLRESOLV_PENDING)
- *async = TRUE;
-
- else if(!hostaddr) {
- failf(data, "Couldn't resolve host '%s'", conn->host.dispname);
- result = CURLE_COULDNT_RESOLVE_HOST;
- /* don't return yet, we need to clean up the timeout first */
- }
- }
- else {
- /* This is a proxy that hasn't been resolved yet. */
-
- /* IDN-fix the proxy name */
- fix_hostname(data, conn, &conn->proxy);
-
- /* resolve proxy */
- rc = Curl_resolv(conn, conn->proxy.name, (int)conn->port, &hostaddr);
-
- if(rc == CURLRESOLV_PENDING)
- *async = TRUE;
-
- else if(!hostaddr) {
- failf(data, "Couldn't resolve proxy '%s'", conn->proxy.dispname);
- result = CURLE_COULDNT_RESOLVE_PROXY;
- /* don't return yet, we need to clean up the timeout first */
- }
- }
- }
- *addr = hostaddr;
-
-#if defined(HAVE_ALARM) && defined(SIGALRM) && !defined(USE_ARES)
- if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) {
-#ifdef HAVE_SIGACTION
- if(keep_copysig) {
- /* we got a struct as it looked before, now put that one back nice
- and clean */
- sigaction(SIGALRM, &keep_sigact, NULL); /* put it back */
- }
-#else
-#ifdef HAVE_SIGNAL
- /* restore the previous SIGALRM handler */
- signal(SIGALRM, keep_sigact);
-#endif
-#endif /* HAVE_SIGACTION */
-
- /* switch back the alarm() to either zero or to what it was before minus
- the time we spent until now! */
- if(prev_alarm) {
- /* there was an alarm() set before us, now put it back */
- unsigned long elapsed_ms = Curl_tvdiff(Curl_tvnow(), conn->created);
- unsigned long alarm_set;
-
- /* the alarm period is counted in even number of seconds */
- alarm_set = prev_alarm - elapsed_ms/1000;
-
- if(!alarm_set ||
- ((alarm_set >= 0x80000000) && (prev_alarm < 0x80000000)) ) {
- /* if the alarm time-left reached zero or turned "negative" (counted
- with unsigned values), we should fire off a SIGALRM here, but we
- won't, and zero would be to switch it off so we never set it to
- less than 1! */
- alarm(1);
- result = CURLE_OPERATION_TIMEOUTED;
- failf(data, "Previous alarm fired off!");
- }
- else
- alarm((unsigned int)alarm_set);
- }
- else
- alarm(0); /* just shut it off */
- }
-#endif
-
- return result;
-}
-
-/* SetupConnection() is called after the name resolve initiated in
- * CreateConnection() is all done.
- *
- * NOTE: the argument 'hostaddr' is NULL when this function is called for a
- * re-used connection.
- *
- * conn->data MUST already have been setup fine (in CreateConnection)
- */
-
-static CURLcode SetupConnection(struct connectdata *conn,
- struct Curl_dns_entry *hostaddr,
- bool *protocol_done)
-{
- CURLcode result=CURLE_OK;
- struct SessionHandle *data = conn->data;
-
- Curl_pgrsTime(data, TIMER_NAMELOOKUP);
-
- if(conn->protocol & PROT_FILE) {
- /* There's nothing in this function to setup if we're only doing
- a file:// transfer */
- *protocol_done = TRUE;
- return result;
- }
- *protocol_done = FALSE; /* default to not done */
-
- /*************************************************************
- * Send user-agent to HTTP proxies even if the target protocol
- * isn't HTTP.
- *************************************************************/
- if((conn->protocol&PROT_HTTP) || conn->bits.httpproxy) {
- if(data->set.useragent) {
- Curl_safefree(conn->allocptr.uagent);
- conn->allocptr.uagent =
- aprintf("User-Agent: %s\r\n", data->set.useragent);
- if(!conn->allocptr.uagent)
- return CURLE_OUT_OF_MEMORY;
- }
- }
-
- conn->headerbytecount = 0;
-
-#ifdef CURL_DO_LINEEND_CONV
- data->state.crlf_conversions = 0; /* reset CRLF conversion counter */
-#endif /* CURL_DO_LINEEND_CONV */
-
- for(;;) {
- /* loop for CURL_SERVER_CLOSED_CONNECTION */
-
- if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
- bool connected = FALSE;
-
- /* Connect only if not already connected! */
- result = ConnectPlease(data, conn, hostaddr, &connected);
-
- if(connected) {
- result = Curl_protocol_connect(conn, protocol_done);
- if(CURLE_OK == result)
- conn->bits.tcpconnect = TRUE;
- }
- else
- conn->bits.tcpconnect = FALSE;
-
- /* if the connection was closed by the server while exchanging
- authentication information, retry with the new set
- authentication information */
- if(conn->bits.proxy_connect_closed) {
- /* reset the error buffer */
- if (data->set.errorbuffer)
- data->set.errorbuffer[0] = '\0';
- data->state.errorbuf = FALSE;
- continue;
- }
-
- if(CURLE_OK != result)
- return result;
- }
- else {
- Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
- conn->bits.tcpconnect = TRUE;
- *protocol_done = TRUE;
- if(data->set.verbose)
- verboseconnect(conn);
- }
- /* Stop the loop now */
- break;
- }
-
- conn->now = Curl_tvnow(); /* time this *after* the connect is done, we
- set this here perhaps a second time */
-
-#ifdef __EMX__
- /* 20000330 mgs
- * the check is quite a hack...
- * we're calling _fsetmode to fix the problem with fwrite converting newline
- * characters (you get mangled text files, and corrupted binary files when
- * you download to stdout and redirect it to a file). */
-
- if ((data->set.out)->_handle == NULL) {
- _fsetmode(stdout, "b");
- }
-#endif
-
- return CURLE_OK;
-}
-
-CURLcode Curl_connect(struct SessionHandle *data,
- struct connectdata **in_connect,
- bool *asyncp,
- bool *protocol_done)
-{
- CURLcode code;
- struct Curl_dns_entry *dns;
-
- *asyncp = FALSE; /* assume synchronous resolves by default */
-
- /* call the stuff that needs to be called */
- code = CreateConnection(data, in_connect, &dns, asyncp);
-
- if(CURLE_OK == code) {
- /* no error */
- if(dns || !*asyncp)
- /* If an address is available it means that we already have the name
- resolved, OR it isn't async. if this is a re-used connection 'dns'
- will be NULL here. Continue connecting from here */
- code = SetupConnection(*in_connect, dns, protocol_done);
- /* else
- response will be received and treated async wise */
- }
-
- if(CURLE_OK != code) {
- /* We're not allowed to return failure with memory left allocated
- in the connectdata struct, free those here */
- if(*in_connect) {
- Curl_disconnect(*in_connect); /* close the connection */
- *in_connect = NULL; /* return a NULL */
- }
- }
- else {
- if ((*in_connect)->is_in_pipeline)
- data->state.is_in_pipeline = TRUE;
- }
-
- return code;
-}
-
-/* Call this function after Curl_connect() has returned async=TRUE and
- then a successful name resolve has been received.
-
- Note: this function disconnects and frees the conn data in case of
- resolve failure */
-CURLcode Curl_async_resolved(struct connectdata *conn,
- bool *protocol_done)
-{
-#if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \
- defined(USE_THREADING_GETADDRINFO)
- CURLcode code = SetupConnection(conn, conn->async.dns, protocol_done);
-
- if(code)
- /* We're not allowed to return failure with memory left allocated
- in the connectdata struct, free those here */
- Curl_disconnect(conn); /* close the connection */
-
- return code;
-#else
- (void)conn;
- (void)protocol_done;
- return CURLE_OK;
-#endif
-}
-
-
-CURLcode Curl_done(struct connectdata **connp,
- CURLcode status, bool premature) /* an error if this is called after an
- error was detected */
-{
- CURLcode result;
- struct connectdata *conn = *connp;
- struct SessionHandle *data = conn->data;
-
- Curl_expire(data, 0); /* stop timer */
-
- if(conn->bits.done)
- return CURLE_OK; /* Curl_done() has already been called */
-
- conn->bits.done = TRUE; /* called just now! */
-
- if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) &&
- conn->readchannel_inuse)
- conn->readchannel_inuse = FALSE;
- if(Curl_removeHandleFromPipeline(data, conn->send_pipe) &&
- conn->writechannel_inuse)
- conn->writechannel_inuse = FALSE;
-
- /* cleanups done even if the connection is re-used */
- if(data->reqdata.rangestringalloc) {
- free(data->reqdata.range);
- data->reqdata.rangestringalloc = FALSE;
- }
-
- /* Cleanup possible redirect junk */
- if(data->reqdata.newurl) {
- free(data->reqdata.newurl);
- data->reqdata.newurl = NULL;
- }
-
- if(conn->dns_entry) {
- Curl_resolv_unlock(data, conn->dns_entry); /* done with this */
- conn->dns_entry = NULL;
- }
-
- /* this calls the protocol-specific function pointer previously set */
- if(conn->curl_done)
- result = conn->curl_done(conn, status, premature);
- else
- result = CURLE_OK;
-
- Curl_pgrsDone(conn); /* done with the operation */
-
- /* for ares-using, make sure all possible outstanding requests are properly
- cancelled before we proceed */
- ares_cancel(data->state.areschannel);
-
- /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
- forced us to close this no matter what we think.
-
- if conn->bits.close is TRUE, it means that the connection should be
- closed in spite of all our efforts to be nice, due to protocol
- restrictions in our or the server's end */
- if(data->set.reuse_forbid || conn->bits.close) {
- CURLcode res2 = Curl_disconnect(conn); /* close the connection */
-
- *connp = NULL; /* to make the caller of this function better detect that
- this was actually killed here */
-
- /* If we had an error already, make sure we return that one. But
- if we got a new error, return that. */
- if(!result && res2)
- result = res2;
- }
- else {
- ConnectionDone(conn); /* the connection is no longer in use */
-
- /* remember the most recently used connection */
- data->state.lastconnect = conn->connectindex;
-
- infof(data, "Connection #%ld to host %s left intact\n",
- conn->connectindex,
- conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
- }
-
- return result;
-}
-
-CURLcode Curl_do(struct connectdata **connp, bool *done)
-{
- CURLcode result=CURLE_OK;
- struct connectdata *conn = *connp;
- struct SessionHandle *data = conn->data;
-
- conn->bits.done = FALSE; /* Curl_done() is not called yet */
- conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */
-
- if(conn->curl_do) {
- /* generic protocol-specific function pointer set in curl_connect() */
- result = conn->curl_do(conn, done);
-
- /* This was formerly done in transfer.c, but we better do it here */
-
- if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
- /* This was a re-use of a connection and we got a write error in the
- * DO-phase. Then we DISCONNECT this connection and have another attempt
- * to CONNECT and then DO again! The retry cannot possibly find another
- * connection to re-use, since we only keep one possible connection for
- * each. */
-
- infof(data, "Re-used connection seems dead, get a new one\n");
-
- conn->bits.close = TRUE; /* enforce close of this connection */
- result = Curl_done(&conn, result, FALSE); /* we are so done with this */
-
- /* conn may no longer be a good pointer */
-
- /*
- * According to bug report #1330310. We need to check for
- * CURLE_SEND_ERROR here as well. I figure this could happen when the
- * request failed on a FTP connection and thus Curl_done() itself tried
- * to use the connection (again). Slight Lack of feedback in the report,
- * but I don't think this extra check can do much harm.
- */
- if((CURLE_OK == result) || (CURLE_SEND_ERROR == result)) {
- bool async;
- bool protocol_done = TRUE;
-
- /* Now, redo the connect and get a new connection */
- result = Curl_connect(data, connp, &async, &protocol_done);
- if(CURLE_OK == result) {
- /* We have connected or sent away a name resolve query fine */
-
- conn = *connp; /* setup conn to again point to something nice */
- if(async) {
- /* Now, if async is TRUE here, we need to wait for the name
- to resolve */
- result = Curl_wait_for_resolv(conn, NULL);
- if(result)
- return result;
-
- /* Resolved, continue with the connection */
- result = Curl_async_resolved(conn, &protocol_done);
- if(result)
- return result;
- }
-
- /* ... finally back to actually retry the DO phase */
- result = conn->curl_do(conn, done);
- }
- }
- }
- }
- return result;
-}
-
-CURLcode Curl_do_more(struct connectdata *conn)
-{
- CURLcode result=CURLE_OK;
-
- if(conn->curl_do_more)
- result = conn->curl_do_more(conn);
-
- return result;
-}
diff --git a/Utilities/cmcurl/url.h b/Utilities/cmcurl/url.h
deleted file mode 100644
index 446b3d91a..000000000
--- a/Utilities/cmcurl/url.h
+++ /dev/null
@@ -1,85 +0,0 @@
-#ifndef __URL_H
-#define __URL_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include <stdarg.h> /* to make sure we have ap_list */
-
-/*
- * Prototypes for library-wide functions provided by url.c
- */
-
-CURLcode Curl_open(struct SessionHandle **curl);
-CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
- va_list arg);
-CURLcode Curl_close(struct SessionHandle *data); /* opposite of curl_open() */
-CURLcode Curl_connect(struct SessionHandle *, struct connectdata **,
- bool *async, bool *protocol_connect);
-CURLcode Curl_async_resolved(struct connectdata *conn,
- bool *protocol_connect);
-CURLcode Curl_do(struct connectdata **, bool *done);
-CURLcode Curl_do_more(struct connectdata *);
-CURLcode Curl_done(struct connectdata **, CURLcode, bool premature);
-CURLcode Curl_disconnect(struct connectdata *);
-CURLcode Curl_protocol_connect(struct connectdata *conn, bool *done);
-CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done);
-CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done);
-void Curl_safefree(void *ptr);
-
-/* create a connection cache */
-struct conncache *Curl_mk_connc(int type, int amount);
-/* free a connection cache */
-void Curl_rm_connc(struct conncache *c);
-/* Change number of entries of a connection cache */
-CURLcode Curl_ch_connc(struct SessionHandle *data,
- struct conncache *c,
- long newamount);
-
-int Curl_protocol_getsock(struct connectdata *conn,
- curl_socket_t *socks,
- int numsocks);
-int Curl_doing_getsock(struct connectdata *conn,
- curl_socket_t *socks,
- int numsocks);
-
-void Curl_addHandleToPipeline(struct SessionHandle *handle,
- struct curl_llist *pipe);
-int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
- struct curl_llist *pipe);
-bool Curl_isHandleAtHead(struct SessionHandle *handle,
- struct curl_llist *pipe);
-
-void Curl_close_connections(struct SessionHandle *data);
-
-#if 0
-CURLcode Curl_protocol_fdset(struct connectdata *conn,
- fd_set *read_fd_set,
- fd_set *write_fd_set,
- int *max_fdp);
-CURLcode Curl_doing_fdset(struct connectdata *conn,
- fd_set *read_fd_set,
- fd_set *write_fd_set,
- int *max_fdp);
-#endif
-
-#endif
diff --git a/Utilities/cmcurl/urldata.h b/Utilities/cmcurl/urldata.h
deleted file mode 100644
index 46d956d1a..000000000
--- a/Utilities/cmcurl/urldata.h
+++ /dev/null
@@ -1,1340 +0,0 @@
-#ifndef __URLDATA_H
-#define __URLDATA_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-/* This file is for lib internal stuff */
-
-#include "setup.h"
-
-#define PORT_FTP 21
-#define PORT_FTPS 990
-#define PORT_TELNET 23
-#define PORT_HTTP 80
-#define PORT_HTTPS 443
-#define PORT_DICT 2628
-#define PORT_LDAP 389
-#define PORT_TFTP 69
-#define PORT_SSH 22
-
-#define DICT_MATCH "/MATCH:"
-#define DICT_MATCH2 "/M:"
-#define DICT_MATCH3 "/FIND:"
-#define DICT_DEFINE "/DEFINE:"
-#define DICT_DEFINE2 "/D:"
-#define DICT_DEFINE3 "/LOOKUP:"
-
-#define CURL_DEFAULT_USER "anonymous"
-#define CURL_DEFAULT_PASSWORD "curl_by_daniel@haxx.se"
-
-#include "cookie.h"
-#include "formdata.h"
-
-#ifdef USE_SSLEAY
-#ifdef USE_OPENSSL
-#include "openssl/rsa.h"
-#include "openssl/crypto.h"
-#include "openssl/x509.h"
-#include "openssl/pem.h"
-#include "openssl/ssl.h"
-#include "openssl/err.h"
-#ifdef HAVE_OPENSSL_ENGINE_H
-#include <openssl/engine.h>
-#endif
-#ifdef HAVE_OPENSSL_PKCS12_H
-#include <openssl/pkcs12.h>
-#endif
-#else /* SSLeay-style includes */
-#include "rsa.h"
-#include "crypto.h"
-#include "x509.h"
-#include "pem.h"
-#include "ssl.h"
-#include "err.h"
-#endif /* USE_OPENSSL */
-#endif /* USE_SSLEAY */
-
-#ifdef USE_GNUTLS
-#include <gnutls/gnutls.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-
-#include "timeval.h"
-
-#ifdef HAVE_ZLIB_H
-#include <zlib.h> /* for content-encoding */
-#endif
-
-#ifdef USE_ARES
-#include <ares.h>
-#endif
-
-#include <curl/curl.h>
-
-#include "http_chunks.h" /* for the structs and enum stuff */
-#include "hostip.h"
-#include "hash.h"
-#include "splay.h"
-
-#ifdef HAVE_GSSAPI
-# ifdef HAVE_GSSGNU
-# include <gss.h>
-# elif defined HAVE_GSSMIT
-# include <gssapi/gssapi.h>
-# include <gssapi/gssapi_generic.h>
-# else
-# include <gssapi.h>
-# endif
-#endif
-
-#ifdef HAVE_LIBSSH2_H
-#include <libssh2.h>
-#include <libssh2_sftp.h>
-#endif /* HAVE_LIBSSH2_H */
-
-/* Download buffer size, keep it fairly big for speed reasons */
-#undef BUFSIZE
-#define BUFSIZE CURL_MAX_WRITE_SIZE
-
-/* Initial size of the buffer to store headers in, it'll be enlarged in case
- of need. */
-#define HEADERSIZE 256
-
-#define CURLEASY_MAGIC_NUMBER 0xc0dedbad
-
-/* Just a convenience macro to get the larger value out of two given.
- We prefix with CURL to prevent name collisions. */
-#define CURLMAX(x,y) ((x)>(y)?(x):(y))
-
-#ifdef HAVE_KRB4
-/* Types needed for krb4-ftp connections */
-struct krb4buffer {
- void *data;
- size_t size;
- size_t index;
- int eof_flag;
-};
-enum protection_level {
- prot_clear,
- prot_safe,
- prot_confidential,
- prot_private
-};
-#endif
-
-/* enum for the nonblocking SSL connection state machine */
-typedef enum {
- ssl_connect_1,
- ssl_connect_2,
- ssl_connect_2_reading,
- ssl_connect_2_writing,
- ssl_connect_3,
- ssl_connect_done
-} ssl_connect_state;
-
-/* struct for data related to each SSL connection */
-struct ssl_connect_data {
- bool use; /* use ssl encrypted communications TRUE/FALSE */
-#ifdef USE_SSLEAY
- /* these ones requires specific SSL-types */
- SSL_CTX* ctx;
- SSL* handle;
- X509* server_cert;
- ssl_connect_state connecting_state;
-#endif /* USE_SSLEAY */
-#ifdef USE_GNUTLS
- gnutls_session session;
- gnutls_certificate_credentials cred;
-#endif /* USE_GNUTLS */
-};
-
-struct ssl_config_data {
- long version; /* what version the client wants to use */
- long certverifyresult; /* result from the certificate verification */
- long verifypeer; /* set TRUE if this is desired */
- long verifyhost; /* 0: no verify
- 1: check that CN exists
- 2: CN must match hostname */
- char *CApath; /* DOES NOT WORK ON WINDOWS */
- char *CAfile; /* cerficate to verify peer against */
- char *random_file; /* path to file containing "random" data */
- char *egdsocket; /* path to file containing the EGD daemon socket */
- char *cipher_list; /* list of ciphers to use */
- long numsessions; /* SSL session id cache size */
- curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */
- void *fsslctxp; /* parameter for call back */
- bool sessionid; /* cache session IDs or not */
-};
-
-/* information stored about one single SSL session */
-struct curl_ssl_session {
- char *name; /* host name for which this ID was used */
- void *sessionid; /* as returned from the SSL layer */
- size_t idsize; /* if known, otherwise 0 */
- long age; /* just a number, the higher the more recent */
- unsigned short remote_port; /* remote port to connect to */
- struct ssl_config_data ssl_config; /* setup for this session */
-};
-
-/* Struct used for Digest challenge-response authentication */
-struct digestdata {
- char *nonce;
- char *cnonce;
- char *realm;
- int algo;
- bool stale; /* set true for re-negotiation */
- char *opaque;
- char *qop;
- char *algorithm;
- int nc; /* nounce count */
-};
-
-typedef enum {
- NTLMSTATE_NONE,
- NTLMSTATE_TYPE1,
- NTLMSTATE_TYPE2,
- NTLMSTATE_TYPE3,
- NTLMSTATE_LAST
-} curlntlm;
-
-#ifdef USE_WINDOWS_SSPI
-/* When including these headers, you must define either SECURITY_WIN32
- * or SECURITY_KERNEL, indicating who is compiling the code.
- */
-#define SECURITY_WIN32 1
-#include <security.h>
-#include <sspi.h>
-#include <rpc.h>
-#endif
-
-#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
-#include <iconv.h>
-#endif
-
-/* Struct used for NTLM challenge-response authentication */
-struct ntlmdata {
- curlntlm state;
-#ifdef USE_WINDOWS_SSPI
- CredHandle handle;
- CtxtHandle c_handle;
- SEC_WINNT_AUTH_IDENTITY identity;
- SEC_WINNT_AUTH_IDENTITY *p_identity;
- int has_handles;
- void *type_2;
- int n_type_2;
-#else
- unsigned int flags;
- unsigned char nonce[8];
-#endif
-};
-
-#ifdef HAVE_GSSAPI
-struct negotiatedata {
- bool gss; /* Whether we're processing GSS-Negotiate or Negotiate */
- const char* protocol; /* "GSS-Negotiate" or "Negotiate" */
- OM_uint32 status;
- gss_ctx_id_t context;
- gss_name_t server_name;
- gss_buffer_desc output_token;
-};
-#endif
-
-/****************************************************************************
- * HTTP unique setup
- ***************************************************************************/
-struct HTTP {
- struct FormData *sendit;
- curl_off_t postsize; /* off_t to handle large file sizes */
- char *postdata;
-
- const char *p_pragma; /* Pragma: string */
- const char *p_accept; /* Accept: string */
- curl_off_t readbytecount;
- curl_off_t writebytecount;
-
- /* For FORM posting */
- struct Form form;
- struct Curl_chunker chunk;
-
- struct back {
- curl_read_callback fread; /* backup storage for fread pointer */
- void *fread_in; /* backup storage for fread_in pointer */
- char *postdata;
- curl_off_t postsize;
- } backup;
-
- enum {
- HTTPSEND_NADA, /* init */
- HTTPSEND_REQUEST, /* sending a request */
- HTTPSEND_BODY, /* sending body */
- HTTPSEND_LAST /* never use this */
- } sending;
-
- void *send_buffer; /* used if the request couldn't be sent in one chunk,
- points to an allocated send_buffer struct */
-};
-
-/****************************************************************************
- * FTP unique setup
- ***************************************************************************/
-typedef enum {
- FTP_STOP, /* do nothing state, stops the state machine */
- FTP_WAIT220, /* waiting for the initial 220 response immediately after
- a connect */
- FTP_AUTH,
- FTP_USER,
- FTP_PASS,
- FTP_ACCT,
- FTP_PBSZ,
- FTP_PROT,
- FTP_CCC,
- FTP_PWD,
- FTP_QUOTE, /* waiting for a response to a command sent in a quote list */
- FTP_RETR_PREQUOTE,
- FTP_STOR_PREQUOTE,
- FTP_POSTQUOTE,
- FTP_CWD, /* change dir */
- FTP_MKD, /* if the dir didn't exist */
- FTP_MDTM, /* to figure out the datestamp */
- FTP_TYPE, /* to set type when doing a head-like request */
- FTP_LIST_TYPE, /* set type when about to do a dir list */
- FTP_RETR_TYPE, /* set type when about to RETR a file */
- FTP_STOR_TYPE, /* set type when about to STOR a file */
- FTP_SIZE, /* get the remote file's size for head-like request */
- FTP_RETR_SIZE, /* get the remote file's size for RETR */
- FTP_STOR_SIZE, /* get the size for (resumed) STOR */
- FTP_REST, /* when used to check if the server supports it in head-like */
- FTP_RETR_REST, /* when asking for "resume" in for RETR */
- FTP_PORT, /* generic state for PORT, LPRT and EPRT, check count1 */
- FTP_PASV, /* generic state for PASV and EPSV, check count1 */
- FTP_LIST, /* generic state for LIST, NLST or a custom list command */
- FTP_RETR,
- FTP_STOR, /* generic state for STOR and APPE */
- FTP_QUIT,
- FTP_LAST /* never used */
-} ftpstate;
-
-typedef enum {
- FTPFILE_MULTICWD = 1, /* as defined by RFC1738 */
- FTPFILE_NOCWD = 2, /* use SIZE / RETR / STOR on the full path */
- FTPFILE_SINGLECWD = 3 /* make one CWD, then SIZE / RETR / STOR on the file */
-} curl_ftpfile;
-
-/* This FTP struct is used in the SessionHandle. All FTP data that is
- connection-oriented must be in FTP_conn to properly deal with the fact that
- perhaps the SessionHandle is changed between the times the connection is
- used. */
-struct FTP {
- curl_off_t *bytecountp;
- char *user; /* user name string */
- char *passwd; /* password string */
- char *urlpath; /* the originally given path part of the URL */
- char *file; /* decoded file */
- bool no_transfer; /* nothing was transfered, (possibly because a resumed
- transfer already was complete) */
- curl_off_t downloadsize;
-};
-
-/* ftp_conn is used for striuct connection-oriented data in the connectdata
- struct */
-struct ftp_conn {
- char *entrypath; /* the PWD reply when we logged on */
- char **dirs; /* realloc()ed array for path components */
- int dirdepth; /* number of entries used in the 'dirs' array */
- int diralloc; /* number of entries allocated for the 'dirs' array */
- char *cache; /* data cache between getresponse()-calls */
- curl_off_t cache_size; /* size of cache in bytes */
- bool dont_check; /* Set to TRUE to prevent the final (post-transfer)
- file size and 226/250 status check. It should still
- read the line, just ignore the result. */
- long response_time; /* When no timeout is given, this is the amount of
- seconds we await for an FTP response. Initialized
- in Curl_ftp_connect() */
- bool ctl_valid; /* Tells Curl_ftp_quit() whether or not to do anything. If
- the connection has timed out or been closed, this
- should be FALSE when it gets to Curl_ftp_quit() */
- bool cwddone; /* if it has been determined that the proper CWD combo
- already has been done */
- bool cwdfail; /* set TRUE if a CWD command fails, as then we must prevent
- caching the current directory */
- char *prevpath; /* conn->path from the previous transfer */
- char transfertype; /* set by ftp_transfertype for use by Curl_client_write()a
- and others (A/I or zero) */
- size_t nread_resp; /* number of bytes currently read of a server response */
- char *linestart_resp; /* line start pointer for the FTP server response
- reader function */
-
- int count1; /* general purpose counter for the state machine */
- int count2; /* general purpose counter for the state machine */
- int count3; /* general purpose counter for the state machine */
- char *sendthis; /* allocated pointer to a buffer that is to be sent to the
- ftp server */
- size_t sendleft; /* number of bytes left to send from the sendthis buffer */
- size_t sendsize; /* total size of the sendthis buffer */
- struct timeval response; /* set to Curl_tvnow() when a command has been sent
- off, used to time-out response reading */
- ftpstate state; /* always use ftp.c:state() to change state! */
-};
-
-struct SSHPROTO {
- curl_off_t *bytecountp;
- char *user;
- char *passwd;
- char *path; /* the path we operate on */
- char *homedir;
- char *errorstr;
-#ifdef USE_LIBSSH2
- LIBSSH2_SESSION *ssh_session; /* Secure Shell session */
- LIBSSH2_CHANNEL *ssh_channel; /* Secure Shell channel handle */
- LIBSSH2_SFTP *sftp_session; /* SFTP handle */
- LIBSSH2_SFTP_HANDLE *sftp_handle;
-#endif /* USE_LIBSSH2 */
-};
-
-
-/****************************************************************************
- * FILE unique setup
- ***************************************************************************/
-struct FILEPROTO {
- char *path; /* the path we operate on */
- char *freepath; /* pointer to the allocated block we must free, this might
- differ from the 'path' pointer */
- int fd; /* open file descriptor to read from! */
-};
-
-/*
- * Boolean values that concerns this connection.
- */
-struct ConnectBits {
- bool close; /* if set, we close the connection after this request */
- bool reuse; /* if set, this is a re-used connection */
- bool chunk; /* if set, this is a chunked transfer-encoding */
- bool httpproxy; /* if set, this transfer is done through a http proxy */
- bool user_passwd; /* do we use user+password for this connection? */
- bool proxy_user_passwd; /* user+password for the proxy? */
- bool ipv6_ip; /* we communicate with a remote site specified with pure IPv6
- IP address */
- bool ipv6; /* we communicate with a site using an IPv6 address */
-
- bool do_more; /* this is set TRUE if the ->curl_do_more() function is
- supposed to be called, after ->curl_do() */
-
- bool upload_chunky; /* set TRUE if we are doing chunked transfer-encoding
- on upload */
- bool getheader; /* TRUE if header parsing is wanted */
-
- bool forbidchunk; /* used only to explicitly forbid chunk-upload for
- specific upload buffers. See readmoredata() in
- http.c for details. */
-
- bool tcpconnect; /* the TCP layer (or simimlar) is connected, this is set
- the first time on the first connect function call */
- bool protoconnstart;/* the protocol layer has STARTED its operation after
- the TCP layer connect */
-
- bool retry; /* this connection is about to get closed and then
- re-attempted at another connection. */
- bool no_body; /* CURLOPT_NO_BODY (or similar) was set */
- bool tunnel_proxy; /* if CONNECT is used to "tunnel" through the proxy.
- This is implicit when SSL-protocols are used through
- proxies, but can also be enabled explicitly by
- apps */
- bool authneg; /* TRUE when the auth phase has started, which means
- that we are creating a request with an auth header,
- but it is not the final request in the auth
- negotiation. */
- bool rewindaftersend;/* TRUE when the sending couldn't be stopped even
- though it will be discarded. When the whole send
- operation is done, we must call the data rewind
- callback. */
- bool ftp_use_epsv; /* As set with CURLOPT_FTP_USE_EPSV, but if we find out
- EPSV doesn't work we disable it for the forthcoming
- requests */
-
- bool ftp_use_eprt; /* As set with CURLOPT_FTP_USE_EPRT, but if we find out
- EPRT doesn't work we disable it for the forthcoming
- requests */
- bool netrc; /* name+password provided by netrc */
-
- bool trailerHdrPresent; /* Set when Trailer: header found in HTTP response.
- Required to determine whether to look for trailers
- in case of Transfer-Encoding: chunking */
- bool done; /* set to FALSE when Curl_do() is called and set to TRUE
- when Curl_done() is called, to prevent Curl_done() to
- get invoked twice when the multi interface is
- used. */
- bool stream_was_rewound; /* Indicates that the stream was rewound after a
- request read past the end of its response byte
- boundary */
- bool proxy_connect_closed; /* set true if a proxy disconnected the
- connection in a CONNECT request with auth, so
- that libcurl should reconnect and continue. */
-};
-
-struct hostname {
- char *rawalloc; /* allocated "raw" version of the name */
- char *encalloc; /* allocated IDN-encoded version of the name */
- char *name; /* name to use internally, might be encoded, might be raw */
- char *dispname; /* name to display, as 'name' might be encoded */
-};
-
-/*
- * Flags on the keepon member of the Curl_transfer_keeper
- */
-
-#define KEEP_NONE 0
-#define KEEP_READ 1 /* there is or may be data to read */
-#define KEEP_WRITE 2 /* there is or may be data to write */
-#define KEEP_READ_HOLD 4 /* when set, no reading should be done but there
- might still be data to read */
-#define KEEP_WRITE_HOLD 8 /* when set, no writing should be done but there
- might still be data to write */
-
-/*
- * This struct is all the previously local variables from Curl_perform() moved
- * to struct to allow the function to return and get re-invoked better without
- * losing state.
- */
-
-struct Curl_transfer_keeper {
-
- /** Values copied over from the HandleData struct each time on init **/
-
- curl_off_t size; /* -1 if unknown at this point */
- curl_off_t *bytecountp; /* return number of bytes read or NULL */
-
- curl_off_t maxdownload; /* in bytes, the maximum amount of data to fetch, 0
- means unlimited */
- curl_off_t *writebytecountp; /* return number of bytes written or NULL */
-
- /** End of HandleData struct copies **/
-
- curl_off_t bytecount; /* total number of bytes read */
- curl_off_t writebytecount; /* number of bytes written */
-
- struct timeval start; /* transfer started at this time */
- struct timeval now; /* current time */
- bool header; /* incoming data has HTTP header */
- enum {
- HEADER_NORMAL, /* no bad header at all */
- HEADER_PARTHEADER, /* part of the chunk is a bad header, the rest
- is normal data */
- HEADER_ALLBAD /* all was believed to be header */
- } badheader; /* the header was deemed bad and will be
- written as body */
- int headerline; /* counts header lines to better track the
- first one */
- char *hbufp; /* points at *end* of header line */
- size_t hbuflen;
- char *str; /* within buf */
- char *str_start; /* within buf */
- char *end_ptr; /* within buf */
- char *p; /* within headerbuff */
- bool content_range; /* set TRUE if Content-Range: was found */
- curl_off_t offset; /* possible resume offset read from the
- Content-Range: header */
- int httpcode; /* error code from the 'HTTP/1.? XXX' line */
- int httpversion; /* the HTTP version*10 */
- struct timeval start100; /* time stamp to wait for the 100 code from */
- bool write_after_100_header; /* TRUE = we enable the write after we
- received a 100-continue/timeout or
- FALSE = directly */
- bool wait100_after_headers; /* TRUE = after the request-headers have been
- sent off properly, we go into the wait100
- state, FALSE = don't */
- int content_encoding; /* What content encoding. sec 3.5, RFC2616. */
-
-#define IDENTITY 0 /* No encoding */
-#define DEFLATE 1 /* zlib delfate [RFC 1950 & 1951] */
-#define GZIP 2 /* gzip algorithm [RFC 1952] */
-#define COMPRESS 3 /* Not handled, added for completeness */
-
-#ifdef HAVE_LIBZ
- bool zlib_init; /* True if zlib already initialized;
- undefined if Content-Encoding header. */
- z_stream z; /* State structure for zlib. */
-#endif
-
- time_t timeofdoc;
- long bodywrites;
-
- char *buf;
- char *uploadbuf;
- curl_socket_t maxfd;
-
- int keepon;
-
- bool upload_done; /* set to TRUE when doing chunked transfer-encoding upload
- and we're uploading the last chunk */
-
- bool ignorebody; /* we read a response-body but we ignore it! */
- bool ignorecl; /* This HTTP response has no body so we ignore the Content-
- Length: header */
-};
-
-#if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \
- defined(USE_THREADING_GETADDRINFO)
-struct Curl_async {
- char *hostname;
- int port;
- struct Curl_dns_entry *dns;
- bool done; /* set TRUE when the lookup is complete */
- int status; /* if done is TRUE, this is the status from the callback */
- void *os_specific; /* 'struct thread_data' for Windows */
-};
-#endif
-
-#define FIRSTSOCKET 0
-#define SECONDARYSOCKET 1
-
-/* These function pointer types are here only to allow easier typecasting
- within the source when we need to cast between data pointers (such as NULL)
- and function pointers. */
-typedef CURLcode (*Curl_do_more_func)(struct connectdata *);
-typedef CURLcode (*Curl_done_func)(struct connectdata *, CURLcode, bool);
-
-
-/*
- * Store's request specific data in the easy handle (SessionHandle).
- * Previously, these members were on the connectdata struct but since
- * a conn struct may now be shared between different SessionHandles,
- * we store connection-specific data here.
- *
- */
-struct HandleData {
- char *pathbuffer;/* allocated buffer to store the URL's path part in */
- char *path; /* path to use, points to somewhere within the pathbuffer
- area */
-
- char *newurl; /* This can only be set if a Location: was in the
- document headers */
-
- /* This struct is inited when needed */
- struct Curl_transfer_keeper keep;
-
- /* 'upload_present' is used to keep a byte counter of how much data there is
- still left in the buffer, aimed for upload. */
- ssize_t upload_present;
-
- /* 'upload_fromhere' is used as a read-pointer when we uploaded parts of a
- buffer, so the next read should read from where this pointer points to,
- and the 'upload_present' contains the number of bytes available at this
- position */
- char *upload_fromhere;
-
- curl_off_t size; /* -1 if unknown at this point */
- curl_off_t *bytecountp; /* return number of bytes read or NULL */
-
- curl_off_t maxdownload; /* in bytes, the maximum amount of data to fetch, 0
- means unlimited */
- curl_off_t *writebytecountp; /* return number of bytes written or NULL */
-
- bool use_range;
- bool rangestringalloc; /* the range string is malloc()'ed */
-
- char *range; /* range, if used. See README for detailed specification on
- this syntax. */
- curl_off_t resume_from; /* continue [ftp] transfer from here */
-
- /* Protocol specific data */
-
- union {
- struct HTTP *http;
- struct HTTP *https; /* alias, just for the sake of being more readable */
- struct FTP *ftp;
- void *tftp; /* private for tftp.c-eyes only */
- struct FILEPROTO *file;
- void *telnet; /* private for telnet.c-eyes only */
- void *generic;
- struct SSHPROTO *ssh;
- } proto;
-};
-
-/*
- * The connectdata struct contains all fields and variables that should be
- * unique for an entire connection.
- */
-struct connectdata {
- /* 'data' is the CURRENT SessionHandle using this connection -- take great
- caution that this might very well vary between different times this
- connection is used! */
- struct SessionHandle *data;
-
- bool inuse; /* This is a marker for the connection cache logic. If this is
- TRUE this handle is being used by an easy handle and cannot
- be used by any other easy handle without careful
- consideration (== only for pipelining). */
-
- /**** Fields set when inited and not modified again */
- long connectindex; /* what index in the connection cache connects index this
- particular struct has */
- long protocol; /* PROT_* flags concerning the protocol set */
-#define PROT_MISSING (1<<0)
-#define PROT_HTTP (1<<2)
-#define PROT_HTTPS (1<<3)
-#define PROT_FTP (1<<4)
-#define PROT_TELNET (1<<5)
-#define PROT_DICT (1<<6)
-#define PROT_LDAP (1<<7)
-#define PROT_FILE (1<<8)
-#define PROT_FTPS (1<<9)
-#define PROT_SSL (1<<10) /* protocol requires SSL */
-#define PROT_TFTP (1<<11)
-#define PROT_SCP (1<<12)
-#define PROT_SFTP (1<<13)
-
-#define PROT_CLOSEACTION PROT_FTP /* these ones need action before socket
- close */
-
- /* 'dns_entry' is the particular host we use. This points to an entry in the
- DNS cache and it will not get pruned while locked. It gets unlocked in
- Curl_done(). This entry will be NULL if the connection is re-used as then
- there is no name resolve done. */
- struct Curl_dns_entry *dns_entry;
-
- /* 'ip_addr' is the particular IP we connected to. It points to a struct
- within the DNS cache, so this pointer is only valid as long as the DNS
- cache entry remains locked. It gets unlocked in Curl_done() */
- Curl_addrinfo *ip_addr;
-
- /* 'ip_addr_str' is the ip_addr data as a human readable malloc()ed string.
- It remains available as long as the connection does, which is longer than
- the ip_addr itself. Set with Curl_store_ip_addr() when ip_addr has been
- set. */
- char *ip_addr_str;
-
- char protostr[16]; /* store the protocol string in this buffer */
- int socktype; /* SOCK_STREAM or SOCK_DGRAM */
-
- struct hostname host;
- struct hostname proxy;
-
- long port; /* which port to use locally */
- unsigned short remote_port; /* what remote port to connect to,
- not the proxy port! */
-
- long headerbytecount; /* only count received headers */
- long deductheadercount; /* this amount of bytes doesn't count when we check
- if anything has been transfered at the end of
- a connection. We use this counter to make only
- a 100 reply (without a following second response
- code) result in a CURLE_GOT_NOTHING error code */
-
- char *user; /* user name string, allocated */
- char *passwd; /* password string, allocated */
-
- char *proxyuser; /* proxy user name string, allocated */
- char *proxypasswd; /* proxy password string, allocated */
-
- struct timeval now; /* "current" time */
- struct timeval created; /* creation time */
- curl_socket_t sock[2]; /* two sockets, the second is used for the data
- transfer when doing FTP */
-
- struct ssl_connect_data ssl[2]; /* this is for ssl-stuff */
- struct ssl_config_data ssl_config;
-
- struct ConnectBits bits; /* various state-flags for this connection */
-
- /* These two functions MUST be set by the curl_connect() function to be
- be protocol dependent */
- CURLcode (*curl_do)(struct connectdata *, bool *done);
- Curl_done_func curl_done;
-
- /* If the curl_do() function is better made in two halves, this
- * curl_do_more() function will be called afterwards, if set. For example
- * for doing the FTP stuff after the PASV/PORT command.
- */
- Curl_do_more_func curl_do_more;
-
- /* This function *MAY* be set to a protocol-dependent function that is run
- * after the connect() and everything is done, as a step in the connection.
- * The 'done' pointer points to a bool that should be set to TRUE if the
- * function completes before return. If it doesn't complete, the caller
- * should call the curl_connecting() function until it is.
- */
- CURLcode (*curl_connect)(struct connectdata *, bool *done);
-
- /* See above. Currently only used for FTP. */
- CURLcode (*curl_connecting)(struct connectdata *, bool *done);
- CURLcode (*curl_doing)(struct connectdata *, bool *done);
-
- /* Called from the multi interface during the PROTOCONNECT phase, and it
- should then return a proper fd set */
- int (*curl_proto_getsock)(struct connectdata *conn,
- curl_socket_t *socks,
- int numsocks);
-
- /* Called from the multi interface during the DOING phase, and it should
- then return a proper fd set */
- int (*curl_doing_getsock)(struct connectdata *conn,
- curl_socket_t *socks,
- int numsocks);
-
- /* This function *MAY* be set to a protocol-dependent function that is run
- * by the curl_disconnect(), as a step in the disconnection.
- */
- CURLcode (*curl_disconnect)(struct connectdata *);
-
- /* This function *MAY* be set to a protocol-dependent function that is run
- * in the curl_close() function if protocol-specific cleanups are required.
- */
- CURLcode (*curl_close)(struct connectdata *);
-
- /**** curl_get() phase fields */
-
- curl_socket_t sockfd; /* socket to read from or CURL_SOCKET_BAD */
- curl_socket_t writesockfd; /* socket to write to, it may very
- well be the same we read from.
- CURL_SOCKET_BAD disables */
-
- /** Dynamicly allocated strings, may need to be freed before this **/
- /** struct is killed. **/
- struct dynamically_allocated_data {
- char *proxyuserpwd; /* free later if not NULL! */
- char *uagent; /* free later if not NULL! */
- char *accept_encoding; /* free later if not NULL! */
- char *userpwd; /* free later if not NULL! */
- char *rangeline; /* free later if not NULL! */
- char *ref; /* free later if not NULL! */
- char *host; /* free later if not NULL */
- char *cookiehost; /* free later if not NULL */
- } allocptr;
-
- int sec_complete; /* if krb4 is enabled for this connection */
-#ifdef HAVE_KRB4
- enum protection_level command_prot;
- enum protection_level data_prot;
- enum protection_level request_data_prot;
- size_t buffer_size;
- struct krb4buffer in_buffer, out_buffer;
- void *app_data;
- const struct Curl_sec_client_mech *mech;
- struct sockaddr_in local_addr;
-#endif
-
- bool readchannel_inuse; /* whether the read channel is in use by an easy
- handle */
- bool writechannel_inuse; /* whether the write channel is in use by an easy
- handle */
- bool is_in_pipeline; /* TRUE if this connection is in a pipeline */
-
- struct curl_llist *send_pipe; /* List of handles waiting to
- send on this pipeline */
- struct curl_llist *recv_pipe; /* List of handles waiting to read
- their responses on this pipeline */
-
- char master_buffer[BUFSIZE]; /* The master buffer for this connection. */
- size_t read_pos; /* Current read position in the master buffer */
- size_t buf_len; /* Length of the buffer?? */
-
-
- /*************** Request - specific items ************/
-
- /* previously this was in the urldata struct */
- curl_read_callback fread; /* function that reads the input */
- void *fread_in; /* pointer to pass to the fread() above */
-
- struct ntlmdata ntlm; /* NTLM differs from other authentication schemes
- because it authenticates connections, not
- single requests! */
- struct ntlmdata proxyntlm; /* NTLM data for proxy */
-
- char syserr_buf [256]; /* buffer for Curl_strerror() */
-
-#if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \
- defined(USE_THREADING_GETADDRINFO)
- /* data used for the asynch name resolve callback */
- struct Curl_async async;
-#endif
-
- /* These three are used for chunked-encoding trailer support */
- char *trailer; /* allocated buffer to store trailer in */
- int trlMax; /* allocated buffer size */
- int trlPos; /* index of where to store data */
-
- union {
- struct ftp_conn ftpc;
- } proto;
-};
-
-/* The end of connectdata. */
-
-/*
- * Struct to keep statistical and informational data.
- */
-struct PureInfo {
- int httpcode; /* Recent HTTP or FTP response code */
- int httpproxycode;
- int httpversion;
- long filetime; /* If requested, this is might get set. Set to -1 if the time
- was unretrievable. We cannot have this of type time_t,
- since time_t is unsigned on several platforms such as
- OpenVMS. */
- long header_size; /* size of read header(s) in bytes */
- long request_size; /* the amount of bytes sent in the request(s) */
-
- long proxyauthavail;
- long httpauthavail;
-
- long numconnects; /* how many new connection did libcurl created */
-
- char *contenttype; /* the content type of the object */
-};
-
-
-struct Progress {
- long lastshow; /* time() of the last displayed progress meter or NULL to
- force redraw at next call */
- curl_off_t size_dl; /* total expected size */
- curl_off_t size_ul; /* total expected size */
- curl_off_t downloaded; /* transfered so far */
- curl_off_t uploaded; /* transfered so far */
-
- curl_off_t current_speed; /* uses the currently fastest transfer */
-
- bool callback; /* set when progress callback is used */
- int width; /* screen width at download start */
- int flags; /* see progress.h */
-
- double timespent;
-
- curl_off_t dlspeed;
- curl_off_t ulspeed;
-
- double t_nslookup;
- double t_connect;
- double t_pretransfer;
- double t_starttransfer;
- double t_redirect;
-
- struct timeval start;
- struct timeval t_startsingle;
-#define CURR_TIME (5+1) /* 6 entries for 5 seconds */
-
- curl_off_t speeder[ CURR_TIME ];
- struct timeval speeder_time[ CURR_TIME ];
- int speeder_c;
-};
-
-typedef enum {
- HTTPREQ_NONE, /* first in list */
- HTTPREQ_GET,
- HTTPREQ_POST,
- HTTPREQ_POST_FORM, /* we make a difference internally */
- HTTPREQ_PUT,
- HTTPREQ_HEAD,
- HTTPREQ_CUSTOM,
- HTTPREQ_LAST /* last in list */
-} Curl_HttpReq;
-
-/*
- * Values that are generated, temporary or calculated internally for a
- * "session handle" must be defined within the 'struct UrlState'. This struct
- * will be used within the SessionHandle struct. When the 'SessionHandle'
- * struct is cloned, this data MUST NOT be copied.
- *
- * Remember that any "state" information goes globally for the curl handle.
- * Session-data MUST be put in the connectdata struct and here. */
-#define MAX_CURL_USER_LENGTH 256
-#define MAX_CURL_PASSWORD_LENGTH 256
-#define MAX_CURL_USER_LENGTH_TXT "255"
-#define MAX_CURL_PASSWORD_LENGTH_TXT "255"
-
-struct auth {
- long want; /* Bitmask set to the authentication methods wanted by the app
- (with CURLOPT_HTTPAUTH or CURLOPT_PROXYAUTH). */
- long picked;
- long avail; /* bitmask for what the server reports to support for this
- resource */
- bool done; /* TRUE when the auth phase is done and ready to do the *actual*
- request */
- bool multi; /* TRUE if this is not yet authenticated but within the auth
- multipass negotiation */
-
-};
-
-struct conncache {
- /* 'connects' will be an allocated array with pointers. If the pointer is
- set, it holds an allocated connection. */
- struct connectdata **connects;
- long num; /* number of entries of the 'connects' array */
- enum {
- CONNCACHE_PRIVATE, /* used for an easy handle alone */
- CONNCACHE_MULTI /* shared within a multi handle */
- } type;
-};
-
-
-struct UrlState {
- enum {
- Curl_if_none,
- Curl_if_easy,
- Curl_if_multi
- } used_interface;
-
- struct conncache *connc; /* points to the connection cache this handle
- uses */
-
- /* buffers to store authentication data in, as parsed from input options */
- struct timeval keeps_speed; /* for the progress meter really */
-
- long lastconnect; /* index of most recent connect or -1 if undefined */
-
- char *headerbuff; /* allocated buffer to store headers in */
- size_t headersize; /* size of the allocation */
-
- char buffer[BUFSIZE+1]; /* download buffer */
- char uploadbuffer[BUFSIZE+1]; /* upload buffer */
- curl_off_t current_speed; /* the ProgressShow() funcion sets this,
- bytes / second */
- bool this_is_a_follow; /* this is a followed Location: request */
-
- bool is_in_pipeline; /* Indicates whether this handle is part of a pipeline */
-
- char *first_host; /* if set, this should be the host name that we will
- sent authorization to, no else. Used to make Location:
- following not keep sending user+password... This is
- strdup() data.
- */
-
- struct curl_ssl_session *session; /* array of 'numsessions' size */
- long sessionage; /* number of the most recent session */
-
- char *scratch; /* huge buffer[BUFSIZE*2] when doing upload CRLF replacing */
- bool errorbuf; /* Set to TRUE if the error buffer is already filled in.
- This must be set to FALSE every time _easy_perform() is
- called. */
- int os_errno; /* filled in with errno whenever an error occurs */
-#ifdef HAVE_SIGNAL
- /* storage for the previous bag^H^H^HSIGPIPE signal handler :-) */
- void (*prev_signal)(int sig);
-#endif
- bool allow_port; /* Is set.use_port allowed to take effect or not. This
- is always set TRUE when curl_easy_perform() is called. */
-
- struct digestdata digest;
- struct digestdata proxydigest;
-
-#ifdef HAVE_GSSAPI
- struct negotiatedata negotiate;
-#endif
-
- struct auth authhost;
- struct auth authproxy;
-
- bool authproblem; /* TRUE if there's some problem authenticating */
-
-#ifdef USE_ARES
- ares_channel areschannel; /* for name resolves */
-#endif
-
-#if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H)
- ENGINE *engine;
-#endif /* USE_SSLEAY */
- struct timeval expiretime; /* set this with Curl_expire() only */
- struct Curl_tree timenode; /* for the splay stuff */
-
- /* a place to store the most recenlty set FTP entrypath */
- char *most_recent_ftp_entrypath;
-
- /* set after initial USER failure, to prevent an authentication loop */
- bool ftp_trying_alternative;
-
- bool expect100header; /* TRUE if we added Expect: 100-continue */
-
- bool pipe_broke; /* TRUE if the connection we were pipelined on broke
- and we need to restart from the beginning */
- bool cancelled; /* TRUE if the request was cancelled */
-
-#ifndef WIN32
-/* do FTP line-end conversions on most platforms */
-#define CURL_DO_LINEEND_CONV
- /* for FTP downloads: track CRLF sequences that span blocks */
- bool prev_block_had_trailing_cr;
- /* for FTP downloads: how many CRLFs did we converted to LFs? */
- curl_off_t crlf_conversions;
-#endif
- /* If set to non-NULL, there's a connection in a shared connection cache
- that uses this handle so we can't kill this SessionHandle just yet but
- must keep it around and add it to the list of handles to kill once all
- its connections are gone */
- void *shared_conn;
- bool closed; /* set to TRUE when curl_easy_cleanup() has been called on this
- handle, but it is kept around as mentioned for
- shared_conn */
-};
-
-
-/*
- * This 'DynamicStatic' struct defines dynamic states that actually change
- * values in the 'UserDefined' area, which MUST be taken into consideration
- * if the UserDefined struct is cloned or similar. You can probably just
- * copy these, but each one indicate a special action on other data.
- */
-
-struct DynamicStatic {
- char *url; /* work URL, copied from UserDefined */
- bool url_alloc; /* URL string is malloc()'ed */
- bool url_changed; /* set on CURL_OPT_URL, used to detect if the URL was
- changed after the connect phase, as we allow callback
- to change it and if so, we reconnect to use the new
- URL instead */
- char *referer; /* referer string */
- bool referer_alloc; /* referer sting is malloc()ed */
- struct curl_slist *cookielist; /* list of cookie files set by
- curl_easy_setopt(COOKIEFILE) calls */
-};
-
-/*
- * This 'UserDefined' struct must only contain data that is set once to go
- * for many (perhaps) independent connections. Values that are generated or
- * calculated internally for the "session handle" MUST be defined within the
- * 'struct UrlState' instead. The only exceptions MUST note the changes in
- * the 'DynamicStatic' struct.
- */
-struct Curl_one_easy; /* declared and used only in multi.c */
-struct Curl_multi; /* declared and used only in multi.c */
-
-struct UserDefined {
- FILE *err; /* the stderr user data goes here */
- void *debugdata; /* the data that will be passed to fdebug */
- char *errorbuffer; /* store failure messages in here */
- char *proxyuserpwd; /* Proxy <user:password>, if used */
- long proxyport; /* If non-zero, use this port number by default. If the
- proxy string features a ":[port]" that one will override
- this. */
- void *out; /* the fetched file goes here */
- void *in; /* the uploaded file is read from here */
- void *writeheader; /* write the header to this if non-NULL */
- char *set_url; /* what original URL to work on */
- char *proxy; /* proxy to use */
- long use_port; /* which port to use (when not using default) */
- char *userpwd; /* <user:password>, if used */
- long httpauth; /* what kind of HTTP authentication to use (bitmask) */
- long proxyauth; /* what kind of proxy authentication to use (bitmask) */
- char *set_range; /* range, if used. See README for detailed specification
- on this syntax. */
- long followlocation; /* as in HTTP Location: */
- long maxredirs; /* maximum no. of http(s) redirects to follow, set to -1
- for infinity */
- char *set_referer; /* custom string */
- bool free_referer; /* set TRUE if 'referer' points to a string we
- allocated */
- char *useragent; /* User-Agent string */
- char *encoding; /* Accept-Encoding string */
- char *postfields; /* if POST, set the fields' values here */
- curl_off_t postfieldsize; /* if POST, this might have a size to use instead
- of strlen(), and then the data *may* be binary
- (contain zero bytes) */
- char *ftpport; /* port to send with the FTP PORT command */
- char *device; /* local network interface/address to use */
- unsigned short localport; /* local port number to bind to */
- int localportrange; /* number of additional port numbers to test in case the
- 'localport' one can't be bind()ed */
- curl_write_callback fwrite; /* function that stores the output */
- curl_write_callback fwrite_header; /* function that stores headers */
- curl_read_callback fread; /* function that reads the input */
- curl_progress_callback fprogress; /* function for progress information */
- curl_debug_callback fdebug; /* function that write informational data */
- curl_ioctl_callback ioctl; /* function for I/O control */
- curl_sockopt_callback fsockopt; /* function for setting socket options */
- void *sockopt_client; /* pointer to pass to the socket options callback */
-
- /* the 3 curl_conv_callback functions below are used on non-ASCII hosts */
- /* function to convert from the network encoding: */
- curl_conv_callback convfromnetwork;
- /* function to convert to the network encoding: */
- curl_conv_callback convtonetwork;
- /* function to convert from UTF-8 encoding: */
- curl_conv_callback convfromutf8;
-
- void *progress_client; /* pointer to pass to the progress callback */
- void *ioctl_client; /* pointer to pass to the ioctl callback */
- long timeout; /* in seconds, 0 means no timeout */
- long connecttimeout; /* in seconds, 0 means no timeout */
- long ftp_response_timeout; /* in seconds, 0 means no timeout */
- curl_off_t infilesize; /* size of file to upload, -1 means unknown */
- long low_speed_limit; /* bytes/second */
- long low_speed_time; /* number of seconds */
- curl_off_t max_send_speed; /* high speed limit in bytes/second for upload */
- curl_off_t max_recv_speed; /* high speed limit in bytes/second for download */
- curl_off_t set_resume_from; /* continue [ftp] transfer from here */
- char *cookie; /* HTTP cookie string to send */
- struct curl_slist *headers; /* linked list of extra headers */
- struct curl_httppost *httppost; /* linked list of POST data */
- char *cert; /* certificate */
- char *cert_type; /* format for certificate (default: PEM) */
- char *key; /* private key */
- char *key_type; /* format for private key (default: PEM) */
- char *key_passwd; /* plain text private key password */
- char *cookiejar; /* dump all cookies to this file */
- bool cookiesession; /* new cookie session? */
- bool crlf; /* convert crlf on ftp upload(?) */
- char *ftp_account; /* ftp account data */
- char *ftp_alternative_to_user; /* command to send if USER/PASS fails */
- struct curl_slist *quote; /* after connection is established */
- struct curl_slist *postquote; /* after the transfer */
- struct curl_slist *prequote; /* before the transfer, after type */
- struct curl_slist *source_quote; /* 3rd party quote */
- struct curl_slist *source_prequote; /* in 3rd party transfer mode - before
- the transfer on source host */
- struct curl_slist *source_postquote; /* in 3rd party transfer mode - after
- the transfer on source host */
- struct curl_slist *telnet_options; /* linked list of telnet options */
- curl_TimeCond timecondition; /* kind of time/date comparison */
- time_t timevalue; /* what time to compare with */
- Curl_HttpReq httpreq; /* what kind of HTTP request (if any) is this */
- char *customrequest; /* HTTP/FTP request to use */
- long httpversion; /* when non-zero, a specific HTTP version requested to
- be used in the library's request(s) */
- char *auth_host; /* if set, this is the allocated string to the host name
- * to which to send the authorization data to, and no other
- * host (which location-following otherwise could lead to)
- */
- char *krb4_level; /* what security level */
- struct ssl_config_data ssl; /* user defined SSL stuff */
-
- curl_proxytype proxytype; /* what kind of proxy that is in use */
-
- int dns_cache_timeout; /* DNS cache timeout */
- long buffer_size; /* size of receive buffer to use */
-
- char *private_data; /* Private data */
-
- struct Curl_one_easy *one_easy; /* When adding an easy handle to a multi
- handle, an internal 'Curl_one_easy'
- struct is created and this is a pointer
- to the particular struct associated with
- this SessionHandle */
-
- struct curl_slist *http200aliases; /* linked list of aliases for http200 */
-
- long ip_version;
-
- curl_off_t max_filesize; /* Maximum file size to download */
-
- char *source_url; /* for 3rd party transfer */
- char *source_userpwd; /* for 3rd party transfer */
-
- curl_ftpfile ftp_filemethod; /* how to get to a file when FTP is used */
-
-/* Here follows boolean settings that define how to behave during
- this session. They are STATIC, set by libcurl users or at least initially
- and they don't change during operations. */
-
- bool printhost; /* printing host name in debug info */
- bool get_filetime;
- bool tunnel_thru_httpproxy;
- bool prefer_ascii; /* ASCII rather than binary */
- bool ftp_append;
- bool ftp_list_only;
- bool ftp_create_missing_dirs;
- bool ftp_use_port;
- bool hide_progress;
- bool http_fail_on_error;
- bool http_follow_location;
- bool http_disable_hostname_check_before_authentication;
- bool include_header; /* include received protocol headers in data output */
- bool http_set_referer;
- bool http_auto_referer; /* set "correct" referer when following location: */
- bool opt_no_body; /* as set with CURLOPT_NO_BODY */
- bool set_port;
- bool upload;
- enum CURL_NETRC_OPTION
- use_netrc; /* defined in include/curl.h */
- char *netrc_file; /* if not NULL, use this instead of trying to find
- $HOME/.netrc */
- bool verbose;
- bool krb4; /* kerberos4 connection requested */
- bool reuse_forbid; /* forbidden to be reused, close after use */
- bool reuse_fresh; /* do not re-use an existing connection */
- bool ftp_use_epsv; /* if EPSV is to be attempted or not */
- bool ftp_use_eprt; /* if EPRT is to be attempted or not */
- bool ftp_use_ccc; /* if CCC is to be attempted or not */
-
- curl_ftpssl ftp_ssl; /* if AUTH TLS is to be attempted etc */
- curl_ftpauth ftpsslauth; /* what AUTH XXX to be attempted */
- bool no_signal; /* do not use any signal/alarm handler */
- bool global_dns_cache; /* subject for future removal */
- bool tcp_nodelay; /* whether to enable TCP_NODELAY or not */
- bool ignorecl; /* ignore content length */
- bool ftp_skip_ip; /* skip the IP address the FTP server passes on to
- us */
- bool connect_only; /* make connection, let application use the socket */
- long ssh_auth_types; /* allowed SSH auth types */
- char *ssh_public_key; /* the path to the public key file for
- authentication */
- char *ssh_private_key; /* the path to the private key file for
- authentication */
-};
-
-struct Names {
- struct curl_hash *hostcache;
- enum {
- HCACHE_NONE, /* not pointing to anything */
- HCACHE_PRIVATE, /* points to our own */
- HCACHE_GLOBAL, /* points to the (shrug) global one */
- HCACHE_MULTI, /* points to a shared one in the multi handle */
- HCACHE_SHARED /* points to a shared one in a shared object */
- } hostcachetype;
-};
-
-/*
- * The 'connectdata' struct MUST have all the connection oriented stuff as we
- * may have several simultaneous connections and connection structs in memory.
- *
- * The 'struct UserDefined' must only contain data that is set once to go for
- * many (perhaps) independent connections. Values that are generated or
- * calculated internally for the "session handle" must be defined within the
- * 'struct UrlState' instead.
- */
-
-struct SessionHandle {
- struct Names dns;
- struct Curl_multi *multi; /* if non-NULL, points to the multi handle
- struct to which this "belongs" */
- struct Curl_share *share; /* Share, handles global variable mutexing */
- struct HandleData reqdata; /* Request-specific data */
- struct UserDefined set; /* values set by the libcurl user */
- struct DynamicStatic change; /* possibly modified userdefined data */
-
- struct CookieInfo *cookies; /* the cookies, read from files and servers */
- struct Progress progress; /* for all the progress meter data */
- struct UrlState state; /* struct for fields used for state info and
- other dynamic purposes */
- struct PureInfo info; /* stats, reports and info data */
-#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
- iconv_t outbound_cd; /* for translating to the network encoding */
- iconv_t inbound_cd; /* for translating from the network encoding */
- iconv_t utf8_cd; /* for translating to UTF8 */
-#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
- unsigned int magic; /* set to a CURLEASY_MAGIC_NUMBER */
-};
-
-#define LIBCURL_NAME "libcurl"
-
-#endif
diff --git a/Utilities/cmcurl/version.c b/Utilities/cmcurl/version.c
deleted file mode 100644
index 9085f7df8..000000000
--- a/Utilities/cmcurl/version.c
+++ /dev/null
@@ -1,249 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * $Id$
- ***************************************************************************/
-
-#include "setup.h"
-
-#include <string.h>
-#include <stdio.h>
-
-#include <curl/curl.h>
-#include "urldata.h"
-#include "sslgen.h"
-
-#define _MPRINTF_REPLACE /* use the internal *printf() functions */
-#include <curl/mprintf.h>
-
-#ifdef USE_ARES
-#include <ares_version.h>
-#endif
-
-#ifdef USE_LIBIDN
-#include <stringprep.h>
-#endif
-
-#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
-#include <iconv.h>
-#endif
-
-#ifdef USE_LIBSSH2
-#include <libssh2.h>
-#endif
-
-
-char *curl_version(void)
-{
- static char version[200];
- char *ptr=version;
- size_t len;
- size_t left = sizeof(version);
- strcpy(ptr, LIBCURL_NAME "/" LIBCURL_VERSION );
- ptr=strchr(ptr, '\0');
- left -= strlen(ptr);
-
- len = Curl_ssl_version(ptr, left);
- left -= len;
- ptr += len;
-
-#ifdef HAVE_LIBZ
- len = snprintf(ptr, left, " zlib/%s", zlibVersion());
- left -= len;
- ptr += len;
-#endif
-#ifdef USE_ARES
- /* this function is only present in c-ares, not in the original ares */
- len = snprintf(ptr, left, " c-ares/%s", ares_version(NULL));
- left -= len;
- ptr += len;
-#endif
-#ifdef USE_LIBIDN
- if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
- len = snprintf(ptr, left, " libidn/%s", stringprep_check_version(NULL));
- left -= len;
- ptr += len;
- }
-#endif
-#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
-#ifdef _LIBICONV_VERSION
- len = snprintf(ptr, left, " iconv/%d.%d",
- _LIBICONV_VERSION >> 8, _LIBICONV_VERSION & 255);
-#else
- /* version unknown */
- len = snprintf(ptr, left, " iconv");
-#endif /* _LIBICONV_VERSION */
- left -= len;
- ptr += len;
-#endif
-#ifdef USE_LIBSSH2
- len = snprintf(ptr, left, " libssh2/%s", LIBSSH2_VERSION);
- left -= len;
- ptr += len;
-#endif
-
- return version;
-}
-
-/* data for curl_version_info */
-
-static const char * const protocols[] = {
-#ifndef CURL_DISABLE_TFTP
- "tftp",
-#endif
-#ifndef CURL_DISABLE_FTP
- "ftp",
-#endif
-#ifndef CURL_DISABLE_TELNET
- "telnet",
-#endif
-#ifndef CURL_DISABLE_DICT
- "dict",
-#endif
-#ifndef CURL_DISABLE_LDAP
- "ldap",
-#endif
-#ifndef CURL_DISABLE_HTTP
- "http",
-#endif
-#ifndef CURL_DISABLE_FILE
- "file",
-#endif
-
-#ifdef USE_SSL
-#ifndef CURL_DISABLE_HTTP
- "https",
-#endif
-#ifndef CURL_DISABLE_FTP
- "ftps",
-#endif
-#endif
-
-#ifdef USE_LIBSSH2
- "scp",
- "sftp",
-#endif
-
- NULL
-};
-
-static curl_version_info_data version_info = {
- CURLVERSION_NOW,
- LIBCURL_VERSION,
- LIBCURL_VERSION_NUM,
- OS, /* as found by configure or set by hand at build-time */
- 0 /* features is 0 by default */
-#ifdef ENABLE_IPV6
- | CURL_VERSION_IPV6
-#endif
-#ifdef HAVE_KRB4
- | CURL_VERSION_KERBEROS4
-#endif
-#ifdef USE_SSL
- | CURL_VERSION_SSL
-#endif
-#ifdef USE_NTLM
- | CURL_VERSION_NTLM
-#endif
-#ifdef USE_WINDOWS_SSPI
- | CURL_VERSION_SSPI
-#endif
-#ifdef HAVE_LIBZ
- | CURL_VERSION_LIBZ
-#endif
-#ifdef HAVE_GSSAPI
- | CURL_VERSION_GSSNEGOTIATE
-#endif
-#ifdef CURLDEBUG
- | CURL_VERSION_DEBUG
-#endif
-#ifdef USE_ARES
- | CURL_VERSION_ASYNCHDNS
-#endif
-#ifdef HAVE_SPNEGO
- | CURL_VERSION_SPNEGO
-#endif
-#if defined(ENABLE_64BIT) && (SIZEOF_CURL_OFF_T > 4)
- | CURL_VERSION_LARGEFILE
-#endif
-#if defined(CURL_DOES_CONVERSIONS)
- | CURL_VERSION_CONV
-#endif
- ,
- NULL, /* ssl_version */
- 0, /* ssl_version_num, this is kept at zero */
- NULL, /* zlib_version */
- protocols,
- NULL, /* c-ares version */
- 0, /* c-ares version numerical */
- NULL, /* libidn version */
- 0, /* iconv version */
- NULL, /* ssh lib version */
-};
-
-curl_version_info_data *curl_version_info(CURLversion stamp)
-{
-#ifdef USE_LIBSSH2
- static char ssh_buffer[80];
-#endif
-
-#ifdef USE_SSL
- static char ssl_buffer[80];
- Curl_ssl_version(ssl_buffer, sizeof(ssl_buffer));
- version_info.ssl_version = ssl_buffer;
-#endif
-
-#ifdef HAVE_LIBZ
- version_info.libz_version = zlibVersion();
- /* libz left NULL if non-existing */
-#endif
-#ifdef USE_ARES
- {
- int aresnum;
- version_info.ares = ares_version(&aresnum);
- version_info.ares_num = aresnum;
- }
-#endif
-#ifdef USE_LIBIDN
- /* This returns a version string if we use the given version or later,
- otherwise it returns NULL */
- version_info.libidn = stringprep_check_version(LIBIDN_REQUIRED_VERSION);
- if(version_info.libidn)
- version_info.features |= CURL_VERSION_IDN;
-#endif
-
-#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
-#ifdef _LIBICONV_VERSION
- version_info.iconv_ver_num = _LIBICONV_VERSION;
-#else
- /* version unknown */
- version_info.iconv_ver_num = -1;
-#endif /* _LIBICONV_VERSION */
-#endif
-
-#ifdef USE_LIBSSH2
- snprintf(ssh_buffer, sizeof(ssh_buffer), "libssh2/%s", LIBSSH2_VERSION);
- version_info.libssh_version = ssh_buffer;
-#endif
-
- (void)stamp; /* avoid compiler warnings, we don't use this */
-
- return &version_info;
-}
diff --git a/Utilities/cmjsoncpp/.gitattributes b/Utilities/cmjsoncpp/.gitattributes
new file mode 100644
index 000000000..562b12e16
--- /dev/null
+++ b/Utilities/cmjsoncpp/.gitattributes
@@ -0,0 +1 @@
+* -whitespace
diff --git a/Utilities/cmjsoncpp/CMakeLists.txt b/Utilities/cmjsoncpp/CMakeLists.txt
new file mode 100644
index 000000000..d0114e711
--- /dev/null
+++ b/Utilities/cmjsoncpp/CMakeLists.txt
@@ -0,0 +1,26 @@
+project(JsonCpp CXX)
+
+# Disable warnings to avoid changing 3rd party code.
+if(CMAKE_CXX_COMPILER_ID MATCHES
+ "^(GNU|Clang|AppleClang|XL|VisualAge|SunPro|MIPSpro|HP|Intel)$")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w")
+elseif(CMAKE_CXX_COMPILER_ID STREQUAL "PathScale")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -woffall")
+endif()
+
+set(JSONCPP_SOURCES
+ src/lib_json/json_batchallocator.h
+ src/lib_json/json_reader.cpp
+ src/lib_json/json_tool.h
+ src/lib_json/json_value.cpp
+ src/lib_json/json_valueiterator.inl
+ src/lib_json/json_writer.cpp
+ )
+
+include_directories(
+ ${JsonCpp_SOURCE_DIR}/include
+ ${KWSYS_HEADER_ROOT}
+ )
+
+add_library(cmjsoncpp ${JSONCPP_SOURCES})
+target_link_libraries(cmjsoncpp ${CMake_KWIML_LIBRARIES})
diff --git a/Utilities/cmjsoncpp/LICENSE b/Utilities/cmjsoncpp/LICENSE
new file mode 100644
index 000000000..ca2bfe1a0
--- /dev/null
+++ b/Utilities/cmjsoncpp/LICENSE
@@ -0,0 +1,55 @@
+The JsonCpp library's source code, including accompanying documentation,
+tests and demonstration applications, are licensed under the following
+conditions...
+
+The author (Baptiste Lepilleur) explicitly disclaims copyright in all
+jurisdictions which recognize such a disclaimer. In such jurisdictions,
+this software is released into the Public Domain.
+
+In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
+2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is
+released under the terms of the MIT License (see below).
+
+In jurisdictions which recognize Public Domain property, the user of this
+software may choose to accept it either as 1) Public Domain, 2) under the
+conditions of the MIT License (see below), or 3) under the terms of dual
+Public Domain/MIT License conditions described here, as they choose.
+
+The MIT License is about as close to Public Domain as a license can get, and is
+described in clear, concise terms at:
+
+ http://en.wikipedia.org/wiki/MIT_License
+
+The full text of the MIT License follows:
+
+========================================================================
+Copyright (c) 2007-2010 Baptiste Lepilleur
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use, copy,
+modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+========================================================================
+(END LICENSE TEXT)
+
+The MIT license is compatible with both the GPL and commercial
+software, affording one all of the rights of Public Domain with the
+minor nuisance of being required to keep the above copyright notice
+and license text in the source code. Note also that by accepting the
+Public Domain "license" you can re-license your copy using whatever
+license you like.
diff --git a/Utilities/cmjsoncpp/README-CMake.txt b/Utilities/cmjsoncpp/README-CMake.txt
new file mode 100644
index 000000000..bf74094dd
--- /dev/null
+++ b/Utilities/cmjsoncpp/README-CMake.txt
@@ -0,0 +1,66 @@
+The Utilities/cmjsoncpp directory contains a reduced distribution
+of the jsoncpp source tree with only the library source code and
+CMake build system. It is not a submodule; the actual content is part
+of our source tree and changes can be made and committed directly.
+
+We update from upstream using Git's "subtree" merge strategy. A
+special branch contains commits of upstream jsoncpp snapshots and
+nothing else. No Git ref points explicitly to the head of this
+branch, but it is merged into our history.
+
+Update jsoncpp from upstream as follows. Create a local branch to
+explicitly reference the upstream snapshot branch head:
+
+ git branch jsoncpp-upstream 53f6ccb0
+
+Use a temporary directory to checkout the branch:
+
+ mkdir jsoncpp-tmp
+ cd jsoncpp-tmp
+ git init
+ git pull .. jsoncpp-upstream
+ rm -rf *
+
+Now place the (reduced) jsoncpp content in this directory. See
+instructions shown by
+
+ git log 53f6ccb0
+
+for help extracting the content from the upstream svn repo. Then run
+the following commands to commit the new version. Substitute the
+appropriate date and version number:
+
+ git add --all
+
+ GIT_AUTHOR_NAME='JsonCpp Upstream' \
+ GIT_AUTHOR_EMAIL='kwrobot@kitware.com' \
+ GIT_AUTHOR_DATE='Thu Nov 20 08:45:58 2014 -0600' \
+ git commit -m 'JsonCpp 1.0.0 (reduced)' &&
+ git commit --amend
+
+Edit the commit message to describe the procedure used to obtain the
+content. Then push the changes back up to the main local repository:
+
+ git push .. HEAD:jsoncpp-upstream
+ cd ..
+ rm -rf jsoncpp-tmp
+
+Create a topic in the main repository on which to perform the update:
+
+ git checkout -b update-jsoncpp master
+
+Merge the jsoncpp-upstream branch as a subtree:
+
+ git merge -s recursive -X subtree=Utilities/cmjsoncpp \
+ jsoncpp-upstream
+
+If there are conflicts, resolve them and commit. Build and test the
+tree. Commit any additional changes needed to succeed.
+
+Finally, run
+
+ git rev-parse --short=8 jsoncpp-upstream
+
+to get the commit from which the jsoncpp-upstream branch must be started
+on the next update. Edit the "git branch jsoncpp-upstream" line above to
+record it, and commit this file.
diff --git a/Utilities/cmjsoncpp/include/json/assertions.h b/Utilities/cmjsoncpp/include/json/assertions.h
new file mode 100644
index 000000000..37a3ff553
--- /dev/null
+++ b/Utilities/cmjsoncpp/include/json/assertions.h
@@ -0,0 +1,41 @@
+// Copyright 2007-2010 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#ifndef CPPTL_JSON_ASSERTIONS_H_INCLUDED
+#define CPPTL_JSON_ASSERTIONS_H_INCLUDED
+
+#if !defined(JSON_IS_AMALGAMATION)
+#include "config.h"
+#endif // if !defined(JSON_IS_AMALGAMATION)
+
+#include <stdlib.h>
+
+#if JSON_USE_EXCEPTION
+#include <stdexcept>
+#define JSON_ASSERT(condition) \
+ assert(condition); // @todo <= change this into an exception throw
+#define JSON_FAIL_MESSAGE(message) throw std::runtime_error(message);
+#else // JSON_USE_EXCEPTION
+#define JSON_ASSERT(condition) assert(condition);
+
+// The call to assert() will show the failure message in debug builds. In
+// release bugs we write to invalid memory in order to crash hard, so that a
+// debugger or crash reporter gets the chance to take over. We still call exit()
+// afterward in order to tell the compiler that this macro doesn't return.
+#define JSON_FAIL_MESSAGE(message) \
+ { \
+ assert(false&& message); \
+ strcpy(reinterpret_cast<char*>(666), message); \
+ exit(123); \
+ }
+
+#endif
+
+#define JSON_ASSERT_MESSAGE(condition, message) \
+ if (!(condition)) { \
+ JSON_FAIL_MESSAGE(message) \
+ }
+
+#endif // CPPTL_JSON_ASSERTIONS_H_INCLUDED
diff --git a/Utilities/cmjsoncpp/include/json/config.h b/Utilities/cmjsoncpp/include/json/config.h
new file mode 100644
index 000000000..6847ceba8
--- /dev/null
+++ b/Utilities/cmjsoncpp/include/json/config.h
@@ -0,0 +1,119 @@
+// Copyright 2007-2010 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#ifndef JSON_CONFIG_H_INCLUDED
+#define JSON_CONFIG_H_INCLUDED
+
+// Include KWSys Large File Support configuration.
+#include <cmsys/Configure.h>
+
+#if defined(_MSC_VER)
+# pragma warning(push,1)
+#endif
+
+/// If defined, indicates that json library is embedded in CppTL library.
+//# define JSON_IN_CPPTL 1
+
+/// If defined, indicates that json may leverage CppTL library
+//# define JSON_USE_CPPTL 1
+/// If defined, indicates that cpptl vector based map should be used instead of
+/// std::map
+/// as Value container.
+//# define JSON_USE_CPPTL_SMALLMAP 1
+/// If defined, indicates that Json specific container should be used
+/// (hash table & simple deque container with customizable allocator).
+/// THIS FEATURE IS STILL EXPERIMENTAL! There is know bugs: See #3177332
+//# define JSON_VALUE_USE_INTERNAL_MAP 1
+/// Force usage of standard new/malloc based allocator instead of memory pool
+/// based allocator.
+/// The memory pools allocator used optimization (initializing Value and
+/// ValueInternalLink
+/// as if it was a POD) that may cause some validation tool to report errors.
+/// Only has effects if JSON_VALUE_USE_INTERNAL_MAP is defined.
+//# define JSON_USE_SIMPLE_INTERNAL_ALLOCATOR 1
+
+// If non-zero, the library uses exceptions to report bad input instead of C
+// assertion macros. The default is to use exceptions.
+#ifndef JSON_USE_EXCEPTION
+#define JSON_USE_EXCEPTION 1
+#endif
+
+/// If defined, indicates that the source file is amalgated
+/// to prevent private header inclusion.
+/// Remarks: it is automatically defined in the generated amalgated header.
+// #define JSON_IS_AMALGAMATION
+
+#ifdef JSON_IN_CPPTL
+#include <cpptl/config.h>
+#ifndef JSON_USE_CPPTL
+#define JSON_USE_CPPTL 1
+#endif
+#endif
+
+#ifdef JSON_IN_CPPTL
+#define JSON_API CPPTL_API
+#elif defined(JSON_DLL_BUILD)
+#if defined(_MSC_VER)
+#define JSON_API __declspec(dllexport)
+#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
+#endif // if defined(_MSC_VER)
+#elif defined(JSON_DLL)
+#if defined(_MSC_VER)
+#define JSON_API __declspec(dllimport)
+#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
+#endif // if defined(_MSC_VER)
+#endif // ifdef JSON_IN_CPPTL
+#if !defined(JSON_API)
+#define JSON_API
+#endif
+
+// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for
+// integer
+// Storages, and 64 bits integer support is disabled.
+// #define JSON_NO_INT64 1
+
+#if defined(_MSC_VER) && _MSC_VER <= 1200 // MSVC 6
+// Microsoft Visual Studio 6 only support conversion from __int64 to double
+// (no conversion from unsigned __int64).
+#define JSON_USE_INT64_DOUBLE_CONVERSION 1
+// Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255'
+// characters in the debug information)
+// All projects I've ever seen with VS6 were using this globally (not bothering
+// with pragma push/pop).
+#pragma warning(disable : 4786)
+#endif // if defined(_MSC_VER) && _MSC_VER < 1200 // MSVC 6
+
+#if defined(_MSC_VER) && _MSC_VER >= 1500 // MSVC 2008
+/// Indicates that the following function is deprecated.
+#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
+#endif
+
+#if !defined(JSONCPP_DEPRECATED)
+#define JSONCPP_DEPRECATED(message)
+#endif // if !defined(JSONCPP_DEPRECATED)
+
+namespace Json {
+typedef int Int;
+typedef unsigned int UInt;
+#if defined(JSON_NO_INT64)
+typedef int LargestInt;
+typedef unsigned int LargestUInt;
+#undef JSON_HAS_INT64
+#else // if defined(JSON_NO_INT64)
+// For Microsoft Visual use specific types as long long is not supported
+#if defined(_MSC_VER) // Microsoft Visual Studio
+typedef __int64 Int64;
+typedef unsigned __int64 UInt64;
+#else // if defined(_MSC_VER) // Other platforms, use long long
+typedef long long int Int64;
+typedef unsigned long long int UInt64;
+#endif // if defined(_MSC_VER)
+typedef Int64 LargestInt;
+typedef UInt64 LargestUInt;
+#define JSON_HAS_INT64
+#endif // if defined(JSON_NO_INT64)
+} // end namespace Json
+
+#endif // JSON_CONFIG_H_INCLUDED
diff --git a/Utilities/cmjsoncpp/include/json/features.h b/Utilities/cmjsoncpp/include/json/features.h
new file mode 100644
index 000000000..1bb7bb614
--- /dev/null
+++ b/Utilities/cmjsoncpp/include/json/features.h
@@ -0,0 +1,57 @@
+// Copyright 2007-2010 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#ifndef CPPTL_JSON_FEATURES_H_INCLUDED
+#define CPPTL_JSON_FEATURES_H_INCLUDED
+
+#if !defined(JSON_IS_AMALGAMATION)
+#include "forwards.h"
+#endif // if !defined(JSON_IS_AMALGAMATION)
+
+namespace Json {
+
+/** \brief Configuration passed to reader and writer.
+ * This configuration object can be used to force the Reader or Writer
+ * to behave in a standard conforming way.
+ */
+class JSON_API Features {
+public:
+ /** \brief A configuration that allows all features and assumes all strings
+ * are UTF-8.
+ * - C & C++ comments are allowed
+ * - Root object can be any JSON value
+ * - Assumes Value strings are encoded in UTF-8
+ */
+ static Features all();
+
+ /** \brief A configuration that is strictly compatible with the JSON
+ * specification.
+ * - Comments are forbidden.
+ * - Root object must be either an array or an object value.
+ * - Assumes Value strings are encoded in UTF-8
+ */
+ static Features strictMode();
+
+ /** \brief Initialize the configuration like JsonConfig::allFeatures;
+ */
+ Features();
+
+ /// \c true if comments are allowed. Default: \c true.
+ bool allowComments_;
+
+ /// \c true if root must be either an array or an object value. Default: \c
+ /// false.
+ bool strictRoot_;
+
+ /// \c true if dropped null placeholders are allowed. Default: \c false.
+ bool allowDroppedNullPlaceholders_;
+
+ /// \c true if numeric object key are allowed. Default: \c false.
+ bool allowNumericKeys_;
+};
+
+} // namespace Json
+
+#endif // CPPTL_JSON_FEATURES_H_INCLUDED
diff --git a/Utilities/cmjsoncpp/include/json/forwards.h b/Utilities/cmjsoncpp/include/json/forwards.h
new file mode 100644
index 000000000..84a26cd2f
--- /dev/null
+++ b/Utilities/cmjsoncpp/include/json/forwards.h
@@ -0,0 +1,43 @@
+// Copyright 2007-2010 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#ifndef JSON_FORWARDS_H_INCLUDED
+#define JSON_FORWARDS_H_INCLUDED
+
+#if !defined(JSON_IS_AMALGAMATION)
+#include "config.h"
+#endif // if !defined(JSON_IS_AMALGAMATION)
+
+namespace Json {
+
+// writer.h
+class FastWriter;
+class StyledWriter;
+
+// reader.h
+class Reader;
+
+// features.h
+class Features;
+
+// value.h
+typedef unsigned int ArrayIndex;
+class StaticString;
+class Path;
+class PathArgument;
+class Value;
+class ValueIteratorBase;
+class ValueIterator;
+class ValueConstIterator;
+#ifdef JSON_VALUE_USE_INTERNAL_MAP
+class ValueMapAllocator;
+class ValueInternalLink;
+class ValueInternalArray;
+class ValueInternalMap;
+#endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP
+
+} // namespace Json
+
+#endif // JSON_FORWARDS_H_INCLUDED
diff --git a/Utilities/cmjsoncpp/include/json/json.h b/Utilities/cmjsoncpp/include/json/json.h
new file mode 100644
index 000000000..f89bc6270
--- /dev/null
+++ b/Utilities/cmjsoncpp/include/json/json.h
@@ -0,0 +1,14 @@
+// Copyright 2007-2010 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#ifndef JSON_JSON_H_INCLUDED
+#define JSON_JSON_H_INCLUDED
+
+#include "value.h"
+#include "reader.h"
+#include "writer.h"
+#include "features.h"
+
+#endif // JSON_JSON_H_INCLUDED
diff --git a/Utilities/cmjsoncpp/include/json/reader.h b/Utilities/cmjsoncpp/include/json/reader.h
new file mode 100644
index 000000000..95237d168
--- /dev/null
+++ b/Utilities/cmjsoncpp/include/json/reader.h
@@ -0,0 +1,274 @@
+// Copyright 2007-2010 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#ifndef CPPTL_JSON_READER_H_INCLUDED
+#define CPPTL_JSON_READER_H_INCLUDED
+
+#if !defined(JSON_IS_AMALGAMATION)
+#include "features.h"
+#include "value.h"
+#endif // if !defined(JSON_IS_AMALGAMATION)
+#include <deque>
+#include <iosfwd>
+#include <stack>
+#include <string>
+
+// Disable warning C4251: <data member>: <type> needs to have dll-interface to
+// be used by...
+#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
+#pragma warning(push)
+#pragma warning(disable : 4251)
+#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
+
+namespace Json {
+
+/** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a
+ *Value.
+ *
+ */
+class JSON_API Reader {
+public:
+ typedef char Char;
+ typedef const Char* Location;
+
+ /** \brief An error tagged with where in the JSON text it was encountered.
+ *
+ * The offsets give the [start, limit) range of bytes within the text. Note
+ * that this is bytes, not codepoints.
+ *
+ */
+ struct StructuredError {
+ size_t offset_start;
+ size_t offset_limit;
+ std::string message;
+ };
+
+ /** \brief Constructs a Reader allowing all features
+ * for parsing.
+ */
+ Reader();
+
+ /** \brief Constructs a Reader allowing the specified feature set
+ * for parsing.
+ */
+ Reader(const Features& features);
+
+ /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
+ * document.
+ * \param document UTF-8 encoded string containing the document to read.
+ * \param root [out] Contains the root value of the document if it was
+ * successfully parsed.
+ * \param collectComments \c true to collect comment and allow writing them
+ * back during
+ * serialization, \c false to discard comments.
+ * This parameter is ignored if
+ * Features::allowComments_
+ * is \c false.
+ * \return \c true if the document was successfully parsed, \c false if an
+ * error occurred.
+ */
+ bool
+ parse(const std::string& document, Value& root, bool collectComments = true);
+
+ /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
+ document.
+ * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the
+ document to read.
+ * \param endDoc Pointer on the end of the UTF-8 encoded string of the
+ document to read.
+ \ Must be >= beginDoc.
+ * \param root [out] Contains the root value of the document if it was
+ * successfully parsed.
+ * \param collectComments \c true to collect comment and allow writing them
+ back during
+ * serialization, \c false to discard comments.
+ * This parameter is ignored if
+ Features::allowComments_
+ * is \c false.
+ * \return \c true if the document was successfully parsed, \c false if an
+ error occurred.
+ */
+ bool parse(const char* beginDoc,
+ const char* endDoc,
+ Value& root,
+ bool collectComments = true);
+
+ /// \brief Parse from input stream.
+ /// \see Json::operator>>(std::istream&, Json::Value&).
+ bool parse(std::istream& is, Value& root, bool collectComments = true);
+
+ /** \brief Returns a user friendly string that list errors in the parsed
+ * document.
+ * \return Formatted error message with the list of errors with their location
+ * in
+ * the parsed document. An empty string is returned if no error
+ * occurred
+ * during parsing.
+ */
+ std::string getFormatedErrorMessages() const;
+
+ /** \brief Returns a user friendly string that list errors in the parsed
+ * document.
+ * \return Formatted error message with the list of errors with their location
+ * in
+ * the parsed document. An empty string is returned if no error
+ * occurred
+ * during parsing.
+ */
+ std::string getFormattedErrorMessages() const;
+
+ /** \brief Returns a vector of structured erros encounted while parsing.
+ * \return A (possibly empty) vector of StructuredError objects. Currently
+ * only one error can be returned, but the caller should tolerate
+ * multiple
+ * errors. This can occur if the parser recovers from a non-fatal
+ * parse error and then encounters additional errors.
+ */
+ std::vector<StructuredError> getStructuredErrors() const;
+
+ /** \brief Add a semantic error message.
+ * \param value JSON Value location associated with the error
+ * \param message The error message.
+ * \return \c true if the error was successfully added, \c false if the
+ * Value offset exceeds the document size.
+ */
+ bool pushError(const Value& value, const std::string& message);
+
+ /** \brief Add a semantic error message with extra context.
+ * \param value JSON Value location associated with the error
+ * \param message The error message.
+ * \param extra Additional JSON Value location to contextualize the error
+ * \return \c true if the error was successfully added, \c false if either
+ * Value offset exceeds the document size.
+ */
+ bool pushError(const Value& value, const std::string& message, const Value& extra);
+
+ /** \brief Return whether there are any errors.
+ * \return \c true if there are no errors to report \c false if
+ * errors have occurred.
+ */
+ bool good() const;
+
+private:
+ enum TokenType {
+ tokenEndOfStream = 0,
+ tokenObjectBegin,
+ tokenObjectEnd,
+ tokenArrayBegin,
+ tokenArrayEnd,
+ tokenString,
+ tokenNumber,
+ tokenTrue,
+ tokenFalse,
+ tokenNull,
+ tokenArraySeparator,
+ tokenMemberSeparator,
+ tokenComment,
+ tokenError
+ };
+
+ class Token {
+ public:
+ TokenType type_;
+ Location start_;
+ Location end_;
+ };
+
+ class ErrorInfo {
+ public:
+ Token token_;
+ std::string message_;
+ Location extra_;
+ };
+
+ typedef std::deque<ErrorInfo> Errors;
+
+ bool expectToken(TokenType type, Token& token, const char* message);
+ bool readToken(Token& token);
+ void skipSpaces();
+ bool match(Location pattern, int patternLength);
+ bool readComment();
+ bool readCStyleComment();
+ bool readCppStyleComment();
+ bool readString();
+ void readNumber();
+ bool readValue();
+ bool readObject(Token& token);
+ bool readArray(Token& token);
+ bool decodeNumber(Token& token);
+ bool decodeNumber(Token& token, Value& decoded);
+ bool decodeString(Token& token);
+ bool decodeString(Token& token, std::string& decoded);
+ bool decodeDouble(Token& token);
+ bool decodeDouble(Token& token, Value& decoded);
+ bool decodeUnicodeCodePoint(Token& token,
+ Location& current,
+ Location end,
+ unsigned int& unicode);
+ bool decodeUnicodeEscapeSequence(Token& token,
+ Location& current,
+ Location end,
+ unsigned int& unicode);
+ bool addError(const std::string& message, Token& token, Location extra = 0);
+ bool recoverFromError(TokenType skipUntilToken);
+ bool addErrorAndRecover(const std::string& message,
+ Token& token,
+ TokenType skipUntilToken);
+ void skipUntilSpace();
+ Value& currentValue();
+ Char getNextChar();
+ void
+ getLocationLineAndColumn(Location location, int& line, int& column) const;
+ std::string getLocationLineAndColumn(Location location) const;
+ void addComment(Location begin, Location end, CommentPlacement placement);
+ void skipCommentTokens(Token& token);
+
+ typedef std::stack<Value*> Nodes;
+ Nodes nodes_;
+ Errors errors_;
+ std::string document_;
+ Location begin_;
+ Location end_;
+ Location current_;
+ Location lastValueEnd_;
+ Value* lastValue_;
+ std::string commentsBefore_;
+ Features features_;
+ bool collectComments_;
+};
+
+/** \brief Read from 'sin' into 'root'.
+
+ Always keep comments from the input JSON.
+
+ This can be used to read a file into a particular sub-object.
+ For example:
+ \code
+ Json::Value root;
+ cin >> root["dir"]["file"];
+ cout << root;
+ \endcode
+ Result:
+ \verbatim
+ {
+ "dir": {
+ "file": {
+ // The input stream JSON would be nested here.
+ }
+ }
+ }
+ \endverbatim
+ \throw std::exception on parse error.
+ \see Json::operator<<()
+*/
+JSON_API std::istream& operator>>(std::istream&, Value&);
+
+} // namespace Json
+
+#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
+#pragma warning(pop)
+#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
+
+#endif // CPPTL_JSON_READER_H_INCLUDED
diff --git a/Utilities/cmjsoncpp/include/json/value.h b/Utilities/cmjsoncpp/include/json/value.h
new file mode 100644
index 000000000..197a85614
--- /dev/null
+++ b/Utilities/cmjsoncpp/include/json/value.h
@@ -0,0 +1,1088 @@
+// Copyright 2007-2010 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#ifndef CPPTL_JSON_H_INCLUDED
+#define CPPTL_JSON_H_INCLUDED
+
+#if !defined(JSON_IS_AMALGAMATION)
+#include "forwards.h"
+#endif // if !defined(JSON_IS_AMALGAMATION)
+#include <string>
+#include <vector>
+
+#ifndef JSON_USE_CPPTL_SMALLMAP
+#include <map>
+#else
+#include <cpptl/smallmap.h>
+#endif
+#ifdef JSON_USE_CPPTL
+#include <cpptl/forwards.h>
+#endif
+
+// Disable warning C4251: <data member>: <type> needs to have dll-interface to
+// be used by...
+#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
+#pragma warning(push)
+#pragma warning(disable : 4251)
+#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
+
+/** \brief JSON (JavaScript Object Notation).
+ */
+namespace Json {
+
+/** \brief Type of the value held by a Value object.
+ */
+enum ValueType {
+ nullValue = 0, ///< 'null' value
+ intValue, ///< signed integer value
+ uintValue, ///< unsigned integer value
+ realValue, ///< double value
+ stringValue, ///< UTF-8 string value
+ booleanValue, ///< bool value
+ arrayValue, ///< array value (ordered list)
+ objectValue ///< object value (collection of name/value pairs).
+};
+
+enum CommentPlacement {
+ commentBefore = 0, ///< a comment placed on the line before a value
+ commentAfterOnSameLine, ///< a comment just after a value on the same line
+ commentAfter, ///< a comment on the line after a value (only make sense for
+ /// root value)
+ numberOfCommentPlacement
+};
+
+//# ifdef JSON_USE_CPPTL
+// typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;
+// typedef CppTL::AnyEnumerator<const Value &> EnumValues;
+//# endif
+
+/** \brief Lightweight wrapper to tag static string.
+ *
+ * Value constructor and objectValue member assignement takes advantage of the
+ * StaticString and avoid the cost of string duplication when storing the
+ * string or the member name.
+ *
+ * Example of usage:
+ * \code
+ * Json::Value aValue( StaticString("some text") );
+ * Json::Value object;
+ * static const StaticString code("code");
+ * object[code] = 1234;
+ * \endcode
+ */
+class JSON_API StaticString {
+public:
+ explicit StaticString(const char* czstring) : str_(czstring) {}
+
+ operator const char*() const { return str_; }
+
+ const char* c_str() const { return str_; }
+
+private:
+ const char* str_;
+};
+
+/** \brief Represents a <a HREF="http://www.json.org">JSON</a> value.
+ *
+ * This class is a discriminated union wrapper that can represents a:
+ * - signed integer [range: Value::minInt - Value::maxInt]
+ * - unsigned integer (range: 0 - Value::maxUInt)
+ * - double
+ * - UTF-8 string
+ * - boolean
+ * - 'null'
+ * - an ordered list of Value
+ * - collection of name/value pairs (javascript object)
+ *
+ * The type of the held value is represented by a #ValueType and
+ * can be obtained using type().
+ *
+ * values of an #objectValue or #arrayValue can be accessed using operator[]()
+ *methods.
+ * Non const methods will automatically create the a #nullValue element
+ * if it does not exist.
+ * The sequence of an #arrayValue will be automatically resize and initialized
+ * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue.
+ *
+ * The get() methods can be used to obtanis default value in the case the
+ *required element
+ * does not exist.
+ *
+ * It is possible to iterate over the list of a #objectValue values using
+ * the getMemberNames() method.
+ */
+class JSON_API Value {
+ friend class ValueIteratorBase;
+#ifdef JSON_VALUE_USE_INTERNAL_MAP
+ friend class ValueInternalLink;
+ friend class ValueInternalMap;
+#endif
+public:
+ typedef std::vector<std::string> Members;
+ typedef ValueIterator iterator;
+ typedef ValueConstIterator const_iterator;
+ typedef Json::UInt UInt;
+ typedef Json::Int Int;
+#if defined(JSON_HAS_INT64)
+ typedef Json::UInt64 UInt64;
+ typedef Json::Int64 Int64;
+#endif // defined(JSON_HAS_INT64)
+ typedef Json::LargestInt LargestInt;
+ typedef Json::LargestUInt LargestUInt;
+ typedef Json::ArrayIndex ArrayIndex;
+
+ static const Value& null;
+ /// Minimum signed integer value that can be stored in a Json::Value.
+ static const LargestInt minLargestInt;
+ /// Maximum signed integer value that can be stored in a Json::Value.
+ static const LargestInt maxLargestInt;
+ /// Maximum unsigned integer value that can be stored in a Json::Value.
+ static const LargestUInt maxLargestUInt;
+
+ /// Minimum signed int value that can be stored in a Json::Value.
+ static const Int minInt;
+ /// Maximum signed int value that can be stored in a Json::Value.
+ static const Int maxInt;
+ /// Maximum unsigned int value that can be stored in a Json::Value.
+ static const UInt maxUInt;
+
+#if defined(JSON_HAS_INT64)
+ /// Minimum signed 64 bits int value that can be stored in a Json::Value.
+ static const Int64 minInt64;
+ /// Maximum signed 64 bits int value that can be stored in a Json::Value.
+ static const Int64 maxInt64;
+ /// Maximum unsigned 64 bits int value that can be stored in a Json::Value.
+ static const UInt64 maxUInt64;
+#endif // defined(JSON_HAS_INT64)
+
+private:
+#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ class CZString {
+ public:
+ enum DuplicationPolicy {
+ noDuplication = 0,
+ duplicate,
+ duplicateOnCopy
+ };
+ CZString(ArrayIndex index);
+ CZString(const char* cstr, DuplicationPolicy allocate);
+ CZString(const CZString& other);
+ ~CZString();
+ CZString& operator=(CZString other);
+ bool operator<(const CZString& other) const;
+ bool operator==(const CZString& other) const;
+ ArrayIndex index() const;
+ const char* c_str() const;
+ bool isStaticString() const;
+
+ private:
+ void swap(CZString& other);
+ const char* cstr_;
+ ArrayIndex index_;
+ };
+
+public:
+#ifndef JSON_USE_CPPTL_SMALLMAP
+ typedef std::map<CZString, Value> ObjectValues;
+#else
+ typedef CppTL::SmallMap<CZString, Value> ObjectValues;
+#endif // ifndef JSON_USE_CPPTL_SMALLMAP
+#endif // ifndef JSON_VALUE_USE_INTERNAL_MAP
+#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
+
+public:
+ /** \brief Create a default Value of the given type.
+
+ This is a very useful constructor.
+ To create an empty array, pass arrayValue.
+ To create an empty object, pass objectValue.
+ Another Value can then be set to this one by assignment.
+This is useful since clear() and resize() will not alter types.
+
+ Examples:
+\code
+Json::Value null_value; // null
+Json::Value arr_value(Json::arrayValue); // []
+Json::Value obj_value(Json::objectValue); // {}
+\endcode
+ */
+ Value(ValueType type = nullValue);
+ Value(Int value);
+ Value(UInt value);
+#if defined(JSON_HAS_INT64)
+ Value(Int64 value);
+ Value(UInt64 value);
+#endif // if defined(JSON_HAS_INT64)
+ Value(double value);
+ Value(const char* value);
+ Value(const char* beginValue, const char* endValue);
+ /** \brief Constructs a value from a static string.
+
+ * Like other value string constructor but do not duplicate the string for
+ * internal storage. The given string must remain alive after the call to this
+ * constructor.
+ * Example of usage:
+ * \code
+ * Json::Value aValue( StaticString("some text") );
+ * \endcode
+ */
+ Value(const StaticString& value);
+ Value(const std::string& value);
+#ifdef JSON_USE_CPPTL
+ Value(const CppTL::ConstString& value);
+#endif
+ Value(bool value);
+ Value(const Value& other);
+ ~Value();
+
+ Value& operator=(Value other);
+ /// Swap values.
+ /// \note Currently, comments are intentionally not swapped, for
+ /// both logic and efficiency.
+ void swap(Value& other);
+
+ ValueType type() const;
+
+ bool operator<(const Value& other) const;
+ bool operator<=(const Value& other) const;
+ bool operator>=(const Value& other) const;
+ bool operator>(const Value& other) const;
+
+ bool operator==(const Value& other) const;
+ bool operator!=(const Value& other) const;
+
+ int compare(const Value& other) const;
+
+ const char* asCString() const;
+ std::string asString() const;
+#ifdef JSON_USE_CPPTL
+ CppTL::ConstString asConstString() const;
+#endif
+ Int asInt() const;
+ UInt asUInt() const;
+#if defined(JSON_HAS_INT64)
+ Int64 asInt64() const;
+ UInt64 asUInt64() const;
+#endif // if defined(JSON_HAS_INT64)
+ LargestInt asLargestInt() const;
+ LargestUInt asLargestUInt() const;
+ float asFloat() const;
+ double asDouble() const;
+ bool asBool() const;
+
+ bool isNull() const;
+ bool isBool() const;
+ bool isInt() const;
+ bool isInt64() const;
+ bool isUInt() const;
+ bool isUInt64() const;
+ bool isIntegral() const;
+ bool isDouble() const;
+ bool isNumeric() const;
+ bool isString() const;
+ bool isArray() const;
+ bool isObject() const;
+
+ bool isConvertibleTo(ValueType other) const;
+
+ /// Number of values in array or object
+ ArrayIndex size() const;
+
+ /// \brief Return true if empty array, empty object, or null;
+ /// otherwise, false.
+ bool empty() const;
+
+ /// Return isNull()
+ bool operator!() const;
+
+ /// Remove all object members and array elements.
+ /// \pre type() is arrayValue, objectValue, or nullValue
+ /// \post type() is unchanged
+ void clear();
+
+ /// Resize the array to size elements.
+ /// New elements are initialized to null.
+ /// May only be called on nullValue or arrayValue.
+ /// \pre type() is arrayValue or nullValue
+ /// \post type() is arrayValue
+ void resize(ArrayIndex size);
+
+ /// Access an array element (zero based index ).
+ /// If the array contains less than index element, then null value are
+ /// inserted
+ /// in the array so that its size is index+1.
+ /// (You may need to say 'value[0u]' to get your compiler to distinguish
+ /// this from the operator[] which takes a string.)
+ Value& operator[](ArrayIndex index);
+
+ /// Access an array element (zero based index ).
+ /// If the array contains less than index element, then null value are
+ /// inserted
+ /// in the array so that its size is index+1.
+ /// (You may need to say 'value[0u]' to get your compiler to distinguish
+ /// this from the operator[] which takes a string.)
+ Value& operator[](int index);
+
+ /// Access an array element (zero based index )
+ /// (You may need to say 'value[0u]' to get your compiler to distinguish
+ /// this from the operator[] which takes a string.)
+ const Value& operator[](ArrayIndex index) const;
+
+ /// Access an array element (zero based index )
+ /// (You may need to say 'value[0u]' to get your compiler to distinguish
+ /// this from the operator[] which takes a string.)
+ const Value& operator[](int index) const;
+
+ /// If the array contains at least index+1 elements, returns the element
+ /// value,
+ /// otherwise returns defaultValue.
+ Value get(ArrayIndex index, const Value& defaultValue) const;
+ /// Return true if index < size().
+ bool isValidIndex(ArrayIndex index) const;
+ /// \brief Append value to array at the end.
+ ///
+ /// Equivalent to jsonvalue[jsonvalue.size()] = value;
+ Value& append(const Value& value);
+
+ /// Access an object value by name, create a null member if it does not exist.
+ Value& operator[](const char* key);
+ /// Access an object value by name, returns null if there is no member with
+ /// that name.
+ const Value& operator[](const char* key) const;
+ /// Access an object value by name, create a null member if it does not exist.
+ Value& operator[](const std::string& key);
+ /// Access an object value by name, returns null if there is no member with
+ /// that name.
+ const Value& operator[](const std::string& key) const;
+ /** \brief Access an object value by name, create a null member if it does not
+ exist.
+
+ * If the object as no entry for that name, then the member name used to store
+ * the new entry is not duplicated.
+ * Example of use:
+ * \code
+ * Json::Value object;
+ * static const StaticString code("code");
+ * object[code] = 1234;
+ * \endcode
+ */
+ Value& operator[](const StaticString& key);
+#ifdef JSON_USE_CPPTL
+ /// Access an object value by name, create a null member if it does not exist.
+ Value& operator[](const CppTL::ConstString& key);
+ /// Access an object value by name, returns null if there is no member with
+ /// that name.
+ const Value& operator[](const CppTL::ConstString& key) const;
+#endif
+ /// Return the member named key if it exist, defaultValue otherwise.
+ Value get(const char* key, const Value& defaultValue) const;
+ /// Return the member named key if it exist, defaultValue otherwise.
+ Value get(const std::string& key, const Value& defaultValue) const;
+#ifdef JSON_USE_CPPTL
+ /// Return the member named key if it exist, defaultValue otherwise.
+ Value get(const CppTL::ConstString& key, const Value& defaultValue) const;
+#endif
+ /// \brief Remove and return the named member.
+ ///
+ /// Do nothing if it did not exist.
+ /// \return the removed Value, or null.
+ /// \pre type() is objectValue or nullValue
+ /// \post type() is unchanged
+ Value removeMember(const char* key);
+ /// Same as removeMember(const char*)
+ Value removeMember(const std::string& key);
+
+ /// Return true if the object has a member named key.
+ bool isMember(const char* key) const;
+ /// Return true if the object has a member named key.
+ bool isMember(const std::string& key) const;
+#ifdef JSON_USE_CPPTL
+ /// Return true if the object has a member named key.
+ bool isMember(const CppTL::ConstString& key) const;
+#endif
+
+ /// \brief Return a list of the member names.
+ ///
+ /// If null, return an empty list.
+ /// \pre type() is objectValue or nullValue
+ /// \post if type() was nullValue, it remains nullValue
+ Members getMemberNames() const;
+
+ //# ifdef JSON_USE_CPPTL
+ // EnumMemberNames enumMemberNames() const;
+ // EnumValues enumValues() const;
+ //# endif
+
+ /// Comments must be //... or /* ... */
+ void setComment(const char* comment, CommentPlacement placement);
+ /// Comments must be //... or /* ... */
+ void setComment(const std::string& comment, CommentPlacement placement);
+ bool hasComment(CommentPlacement placement) const;
+ /// Include delimiters and embedded newlines.
+ std::string getComment(CommentPlacement placement) const;
+
+ std::string toStyledString() const;
+
+ const_iterator begin() const;
+ const_iterator end() const;
+
+ iterator begin();
+ iterator end();
+
+ // Accessors for the [start, limit) range of bytes within the JSON text from
+ // which this value was parsed, if any.
+ void setOffsetStart(size_t start);
+ void setOffsetLimit(size_t limit);
+ size_t getOffsetStart() const;
+ size_t getOffsetLimit() const;
+
+private:
+ void initBasic(ValueType type, bool allocated = false);
+
+ Value& resolveReference(const char* key, bool isStatic);
+
+#ifdef JSON_VALUE_USE_INTERNAL_MAP
+ inline bool isItemAvailable() const { return itemIsUsed_ == 0; }
+
+ inline void setItemUsed(bool isUsed = true) { itemIsUsed_ = isUsed ? 1 : 0; }
+
+ inline bool isMemberNameStatic() const { return memberNameIsStatic_ == 0; }
+
+ inline void setMemberNameIsStatic(bool isStatic) {
+ memberNameIsStatic_ = isStatic ? 1 : 0;
+ }
+#endif // # ifdef JSON_VALUE_USE_INTERNAL_MAP
+
+private:
+ struct CommentInfo {
+ CommentInfo();
+ ~CommentInfo();
+
+ void setComment(const char* text);
+
+ char* comment_;
+ };
+
+ // struct MemberNamesTransform
+ //{
+ // typedef const char *result_type;
+ // const char *operator()( const CZString &name ) const
+ // {
+ // return name.c_str();
+ // }
+ //};
+
+ union ValueHolder {
+ LargestInt int_;
+ LargestUInt uint_;
+ double real_;
+ bool bool_;
+ char* string_;
+#ifdef JSON_VALUE_USE_INTERNAL_MAP
+ ValueInternalArray* array_;
+ ValueInternalMap* map_;
+#else
+ ObjectValues* map_;
+#endif
+ } value_;
+ ValueType type_ : 8;
+ int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
+#ifdef JSON_VALUE_USE_INTERNAL_MAP
+ unsigned int itemIsUsed_ : 1; // used by the ValueInternalMap container.
+ int memberNameIsStatic_ : 1; // used by the ValueInternalMap container.
+#endif
+ CommentInfo* comments_;
+
+ // [start, limit) byte offsets in the source JSON text from which this Value
+ // was extracted.
+ size_t start_;
+ size_t limit_;
+};
+
+/** \brief Experimental and untested: represents an element of the "path" to
+ * access a node.
+ */
+class JSON_API PathArgument {
+public:
+ friend class Path;
+
+ PathArgument();
+ PathArgument(ArrayIndex index);
+ PathArgument(const char* key);
+ PathArgument(const std::string& key);
+
+private:
+ enum Kind {
+ kindNone = 0,
+ kindIndex,
+ kindKey
+ };
+ std::string key_;
+ ArrayIndex index_;
+ Kind kind_;
+};
+
+/** \brief Experimental and untested: represents a "path" to access a node.
+ *
+ * Syntax:
+ * - "." => root node
+ * - ".[n]" => elements at index 'n' of root node (an array value)
+ * - ".name" => member named 'name' of root node (an object value)
+ * - ".name1.name2.name3"
+ * - ".[0][1][2].name1[3]"
+ * - ".%" => member name is provided as parameter
+ * - ".[%]" => index is provied as parameter
+ */
+class JSON_API Path {
+public:
+ Path(const std::string& path,
+ const PathArgument& a1 = PathArgument(),
+ const PathArgument& a2 = PathArgument(),
+ const PathArgument& a3 = PathArgument(),
+ const PathArgument& a4 = PathArgument(),
+ const PathArgument& a5 = PathArgument());
+
+ const Value& resolve(const Value& root) const;
+ Value resolve(const Value& root, const Value& defaultValue) const;
+ /// Creates the "path" to access the specified node and returns a reference on
+ /// the node.
+ Value& make(Value& root) const;
+
+private:
+ typedef std::vector<const PathArgument*> InArgs;
+ typedef std::vector<PathArgument> Args;
+
+ void makePath(const std::string& path, const InArgs& in);
+ void addPathInArg(const std::string& path,
+ const InArgs& in,
+ InArgs::const_iterator& itInArg,
+ PathArgument::Kind kind);
+ void invalidPath(const std::string& path, int location);
+
+ Args args_;
+};
+
+#ifdef JSON_VALUE_USE_INTERNAL_MAP
+/** \brief Allocator to customize Value internal map.
+ * Below is an example of a simple implementation (default implementation
+ actually
+ * use memory pool for speed).
+ * \code
+ class DefaultValueMapAllocator : public ValueMapAllocator
+ {
+ public: // overridden from ValueMapAllocator
+ virtual ValueInternalMap *newMap()
+ {
+ return new ValueInternalMap();
+ }
+
+ virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other )
+ {
+ return new ValueInternalMap( other );
+ }
+
+ virtual void destructMap( ValueInternalMap *map )
+ {
+ delete map;
+ }
+
+ virtual ValueInternalLink *allocateMapBuckets( unsigned int size )
+ {
+ return new ValueInternalLink[size];
+ }
+
+ virtual void releaseMapBuckets( ValueInternalLink *links )
+ {
+ delete [] links;
+ }
+
+ virtual ValueInternalLink *allocateMapLink()
+ {
+ return new ValueInternalLink();
+ }
+
+ virtual void releaseMapLink( ValueInternalLink *link )
+ {
+ delete link;
+ }
+ };
+ * \endcode
+ */
+class JSON_API ValueMapAllocator {
+public:
+ virtual ~ValueMapAllocator();
+ virtual ValueInternalMap* newMap() = 0;
+ virtual ValueInternalMap* newMapCopy(const ValueInternalMap& other) = 0;
+ virtual void destructMap(ValueInternalMap* map) = 0;
+ virtual ValueInternalLink* allocateMapBuckets(unsigned int size) = 0;
+ virtual void releaseMapBuckets(ValueInternalLink* links) = 0;
+ virtual ValueInternalLink* allocateMapLink() = 0;
+ virtual void releaseMapLink(ValueInternalLink* link) = 0;
+};
+
+/** \brief ValueInternalMap hash-map bucket chain link (for internal use only).
+ * \internal previous_ & next_ allows for bidirectional traversal.
+ */
+class JSON_API ValueInternalLink {
+public:
+ enum {
+ itemPerLink = 6
+ }; // sizeof(ValueInternalLink) = 128 on 32 bits architecture.
+ enum InternalFlags {
+ flagAvailable = 0,
+ flagUsed = 1
+ };
+
+ ValueInternalLink();
+
+ ~ValueInternalLink();
+
+ Value items_[itemPerLink];
+ char* keys_[itemPerLink];
+ ValueInternalLink* previous_;
+ ValueInternalLink* next_;
+};
+
+/** \brief A linked page based hash-table implementation used internally by
+ *Value.
+ * \internal ValueInternalMap is a tradional bucket based hash-table, with a
+ *linked
+ * list in each bucket to handle collision. There is an addional twist in that
+ * each node of the collision linked list is a page containing a fixed amount of
+ * value. This provides a better compromise between memory usage and speed.
+ *
+ * Each bucket is made up of a chained list of ValueInternalLink. The last
+ * link of a given bucket can be found in the 'previous_' field of the following
+ *bucket.
+ * The last link of the last bucket is stored in tailLink_ as it has no
+ *following bucket.
+ * Only the last link of a bucket may contains 'available' item. The last link
+ *always
+ * contains at least one element unless is it the bucket one very first link.
+ */
+class JSON_API ValueInternalMap {
+ friend class ValueIteratorBase;
+ friend class Value;
+
+public:
+ typedef unsigned int HashKey;
+ typedef unsigned int BucketIndex;
+
+#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
+ struct IteratorState {
+ IteratorState() : map_(0), link_(0), itemIndex_(0), bucketIndex_(0) {}
+ ValueInternalMap* map_;
+ ValueInternalLink* link_;
+ BucketIndex itemIndex_;
+ BucketIndex bucketIndex_;
+ };
+#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
+
+ ValueInternalMap();
+ ValueInternalMap(const ValueInternalMap& other);
+ ValueInternalMap& operator=(ValueInternalMap other);
+ ~ValueInternalMap();
+
+ void swap(ValueInternalMap& other);
+
+ BucketIndex size() const;
+
+ void clear();
+
+ bool reserveDelta(BucketIndex growth);
+
+ bool reserve(BucketIndex newItemCount);
+
+ const Value* find(const char* key) const;
+
+ Value* find(const char* key);
+
+ Value& resolveReference(const char* key, bool isStatic);
+
+ void remove(const char* key);
+
+ void doActualRemove(ValueInternalLink* link,
+ BucketIndex index,
+ BucketIndex bucketIndex);
+
+ ValueInternalLink*& getLastLinkInBucket(BucketIndex bucketIndex);
+
+ Value& setNewItem(const char* key,
+ bool isStatic,
+ ValueInternalLink* link,
+ BucketIndex index);
+
+ Value& unsafeAdd(const char* key, bool isStatic, HashKey hashedKey);
+
+ HashKey hash(const char* key) const;
+
+ int compare(const ValueInternalMap& other) const;
+
+private:
+ void makeBeginIterator(IteratorState& it) const;
+ void makeEndIterator(IteratorState& it) const;
+ static bool equals(const IteratorState& x, const IteratorState& other);
+ static void increment(IteratorState& iterator);
+ static void incrementBucket(IteratorState& iterator);
+ static void decrement(IteratorState& iterator);
+ static const char* key(const IteratorState& iterator);
+ static const char* key(const IteratorState& iterator, bool& isStatic);
+ static Value& value(const IteratorState& iterator);
+ static int distance(const IteratorState& x, const IteratorState& y);
+
+private:
+ ValueInternalLink* buckets_;
+ ValueInternalLink* tailLink_;
+ BucketIndex bucketsSize_;
+ BucketIndex itemCount_;
+};
+
+/** \brief A simplified deque implementation used internally by Value.
+* \internal
+* It is based on a list of fixed "page", each page contains a fixed number of
+*items.
+* Instead of using a linked-list, a array of pointer is used for fast item
+*look-up.
+* Look-up for an element is as follow:
+* - compute page index: pageIndex = itemIndex / itemsPerPage
+* - look-up item in page: pages_[pageIndex][itemIndex % itemsPerPage]
+*
+* Insertion is amortized constant time (only the array containing the index of
+*pointers
+* need to be reallocated when items are appended).
+*/
+class JSON_API ValueInternalArray {
+ friend class Value;
+ friend class ValueIteratorBase;
+
+public:
+ enum {
+ itemsPerPage = 8
+ }; // should be a power of 2 for fast divide and modulo.
+ typedef Value::ArrayIndex ArrayIndex;
+ typedef unsigned int PageIndex;
+
+#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
+ struct IteratorState // Must be a POD
+ {
+ IteratorState() : array_(0), currentPageIndex_(0), currentItemIndex_(0) {}
+ ValueInternalArray* array_;
+ Value** currentPageIndex_;
+ unsigned int currentItemIndex_;
+ };
+#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
+
+ ValueInternalArray();
+ ValueInternalArray(const ValueInternalArray& other);
+ ValueInternalArray& operator=(ValueInternalArray other);
+ ~ValueInternalArray();
+ void swap(ValueInternalArray& other);
+
+ void clear();
+ void resize(ArrayIndex newSize);
+
+ Value& resolveReference(ArrayIndex index);
+
+ Value* find(ArrayIndex index) const;
+
+ ArrayIndex size() const;
+
+ int compare(const ValueInternalArray& other) const;
+
+private:
+ static bool equals(const IteratorState& x, const IteratorState& other);
+ static void increment(IteratorState& iterator);
+ static void decrement(IteratorState& iterator);
+ static Value& dereference(const IteratorState& iterator);
+ static Value& unsafeDereference(const IteratorState& iterator);
+ static int distance(const IteratorState& x, const IteratorState& y);
+ static ArrayIndex indexOf(const IteratorState& iterator);
+ void makeBeginIterator(IteratorState& it) const;
+ void makeEndIterator(IteratorState& it) const;
+ void makeIterator(IteratorState& it, ArrayIndex index) const;
+
+ void makeIndexValid(ArrayIndex index);
+
+ Value** pages_;
+ ArrayIndex size_;
+ PageIndex pageCount_;
+};
+
+/** \brief Experimental: do not use. Allocator to customize Value internal
+array.
+ * Below is an example of a simple implementation (actual implementation use
+ * memory pool).
+ \code
+class DefaultValueArrayAllocator : public ValueArrayAllocator
+{
+public: // overridden from ValueArrayAllocator
+virtual ~DefaultValueArrayAllocator()
+{
+}
+
+virtual ValueInternalArray *newArray()
+{
+ return new ValueInternalArray();
+}
+
+virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other )
+{
+ return new ValueInternalArray( other );
+}
+
+virtual void destruct( ValueInternalArray *array )
+{
+ delete array;
+}
+
+virtual void reallocateArrayPageIndex( Value **&indexes,
+ ValueInternalArray::PageIndex
+&indexCount,
+ ValueInternalArray::PageIndex
+minNewIndexCount )
+{
+ ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;
+ if ( minNewIndexCount > newIndexCount )
+ newIndexCount = minNewIndexCount;
+ void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount );
+ if ( !newIndexes )
+ throw std::bad_alloc();
+ indexCount = newIndexCount;
+ indexes = static_cast<Value **>( newIndexes );
+}
+virtual void releaseArrayPageIndex( Value **indexes,
+ ValueInternalArray::PageIndex indexCount )
+{
+ if ( indexes )
+ free( indexes );
+}
+
+virtual Value *allocateArrayPage()
+{
+ return static_cast<Value *>( malloc( sizeof(Value) *
+ValueInternalArray::itemsPerPage ) );
+}
+
+virtual void releaseArrayPage( Value *value )
+{
+ if ( value )
+ free( value );
+}
+};
+ \endcode
+ */
+class JSON_API ValueArrayAllocator {
+public:
+ virtual ~ValueArrayAllocator();
+ virtual ValueInternalArray* newArray() = 0;
+ virtual ValueInternalArray* newArrayCopy(const ValueInternalArray& other) = 0;
+ virtual void destructArray(ValueInternalArray* array) = 0;
+ /** \brief Reallocate array page index.
+ * Reallocates an array of pointer on each page.
+ * \param indexes [input] pointer on the current index. May be \c NULL.
+ * [output] pointer on the new index of at least
+ * \a minNewIndexCount pages.
+ * \param indexCount [input] current number of pages in the index.
+ * [output] number of page the reallocated index can handle.
+ * \b MUST be >= \a minNewIndexCount.
+ * \param minNewIndexCount Minimum number of page the new index must be able
+ * to
+ * handle.
+ */
+ virtual void
+ reallocateArrayPageIndex(Value**& indexes,
+ ValueInternalArray::PageIndex& indexCount,
+ ValueInternalArray::PageIndex minNewIndexCount) = 0;
+ virtual void
+ releaseArrayPageIndex(Value** indexes,
+ ValueInternalArray::PageIndex indexCount) = 0;
+ virtual Value* allocateArrayPage() = 0;
+ virtual void releaseArrayPage(Value* value) = 0;
+};
+#endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP
+
+/** \brief base class for Value iterators.
+ *
+ */
+class JSON_API ValueIteratorBase {
+public:
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef unsigned int size_t;
+ typedef int difference_type;
+ typedef ValueIteratorBase SelfType;
+
+ ValueIteratorBase();
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ explicit ValueIteratorBase(const Value::ObjectValues::iterator& current);
+#else
+ ValueIteratorBase(const ValueInternalArray::IteratorState& state);
+ ValueIteratorBase(const ValueInternalMap::IteratorState& state);
+#endif
+
+ bool operator==(const SelfType& other) const { return isEqual(other); }
+
+ bool operator!=(const SelfType& other) const { return !isEqual(other); }
+
+ difference_type operator-(const SelfType& other) const {
+ return computeDistance(other);
+ }
+
+ /// Return either the index or the member name of the referenced value as a
+ /// Value.
+ Value key() const;
+
+ /// Return the index of the referenced Value. -1 if it is not an arrayValue.
+ UInt index() const;
+
+ /// Return the member name of the referenced Value. "" if it is not an
+ /// objectValue.
+ const char* memberName() const;
+
+protected:
+ Value& deref() const;
+
+ void increment();
+
+ void decrement();
+
+ difference_type computeDistance(const SelfType& other) const;
+
+ bool isEqual(const SelfType& other) const;
+
+ void copy(const SelfType& other);
+
+private:
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ Value::ObjectValues::iterator current_;
+ // Indicates that iterator is for a null value.
+ bool isNull_;
+#else
+ union {
+ ValueInternalArray::IteratorState array_;
+ ValueInternalMap::IteratorState map_;
+ } iterator_;
+ bool isArray_;
+#endif
+};
+
+/** \brief const iterator for object and array value.
+ *
+ */
+class JSON_API ValueConstIterator : public ValueIteratorBase {
+ friend class Value;
+
+public:
+ typedef const Value value_type;
+ typedef unsigned int size_t;
+ typedef int difference_type;
+ typedef const Value& reference;
+ typedef const Value* pointer;
+ typedef ValueConstIterator SelfType;
+
+ ValueConstIterator();
+
+private:
+/*! \internal Use by Value to create an iterator.
+ */
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ explicit ValueConstIterator(const Value::ObjectValues::iterator& current);
+#else
+ ValueConstIterator(const ValueInternalArray::IteratorState& state);
+ ValueConstIterator(const ValueInternalMap::IteratorState& state);
+#endif
+public:
+ SelfType& operator=(const ValueIteratorBase& other);
+
+ SelfType operator++(int) {
+ SelfType temp(*this);
+ ++*this;
+ return temp;
+ }
+
+ SelfType operator--(int) {
+ SelfType temp(*this);
+ --*this;
+ return temp;
+ }
+
+ SelfType& operator--() {
+ decrement();
+ return *this;
+ }
+
+ SelfType& operator++() {
+ increment();
+ return *this;
+ }
+
+ reference operator*() const { return deref(); }
+
+ pointer operator->() const { return &deref(); }
+};
+
+/** \brief Iterator for object and array value.
+ */
+class JSON_API ValueIterator : public ValueIteratorBase {
+ friend class Value;
+
+public:
+ typedef Value value_type;
+ typedef unsigned int size_t;
+ typedef int difference_type;
+ typedef Value& reference;
+ typedef Value* pointer;
+ typedef ValueIterator SelfType;
+
+ ValueIterator();
+ ValueIterator(const ValueConstIterator& other);
+ ValueIterator(const ValueIterator& other);
+
+private:
+/*! \internal Use by Value to create an iterator.
+ */
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ explicit ValueIterator(const Value::ObjectValues::iterator& current);
+#else
+ ValueIterator(const ValueInternalArray::IteratorState& state);
+ ValueIterator(const ValueInternalMap::IteratorState& state);
+#endif
+public:
+ SelfType& operator=(const SelfType& other);
+
+ SelfType operator++(int) {
+ SelfType temp(*this);
+ ++*this;
+ return temp;
+ }
+
+ SelfType operator--(int) {
+ SelfType temp(*this);
+ --*this;
+ return temp;
+ }
+
+ SelfType& operator--() {
+ decrement();
+ return *this;
+ }
+
+ SelfType& operator++() {
+ increment();
+ return *this;
+ }
+
+ reference operator*() const { return deref(); }
+
+ pointer operator->() const { return &deref(); }
+};
+
+} // namespace Json
+
+#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
+#pragma warning(pop)
+#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
+
+#endif // CPPTL_JSON_H_INCLUDED
diff --git a/Utilities/cmjsoncpp/include/json/version.h b/Utilities/cmjsoncpp/include/json/version.h
new file mode 100644
index 000000000..6fe06824d
--- /dev/null
+++ b/Utilities/cmjsoncpp/include/json/version.h
@@ -0,0 +1,14 @@
+// DO NOT EDIT. This file is generated by CMake from "version"
+// and "version.h.in" files.
+// Run CMake configure step to update it.
+#ifndef JSON_VERSION_H_INCLUDED
+# define JSON_VERSION_H_INCLUDED
+
+# define JSONCPP_VERSION_STRING "1.0.0"
+# define JSONCPP_VERSION_MAJOR 1
+# define JSONCPP_VERSION_MINOR 0
+# define JSONCPP_VERSION_PATCH 0
+# define JSONCPP_VERSION_QUALIFIER
+# define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8))
+
+#endif // JSON_VERSION_H_INCLUDED
diff --git a/Utilities/cmjsoncpp/include/json/writer.h b/Utilities/cmjsoncpp/include/json/writer.h
new file mode 100644
index 000000000..10863b078
--- /dev/null
+++ b/Utilities/cmjsoncpp/include/json/writer.h
@@ -0,0 +1,213 @@
+// Copyright 2007-2010 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#ifndef JSON_WRITER_H_INCLUDED
+#define JSON_WRITER_H_INCLUDED
+
+#if !defined(JSON_IS_AMALGAMATION)
+#include "value.h"
+#endif // if !defined(JSON_IS_AMALGAMATION)
+#include <iosfwd>
+#include <vector>
+#include <string>
+
+// Disable warning C4251: <data member>: <type> needs to have dll-interface to
+// be used by...
+#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
+#pragma warning(push)
+#pragma warning(disable : 4251)
+#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
+
+namespace Json {
+
+class Value;
+
+/** \brief Abstract class for writers.
+ */
+class JSON_API Writer {
+public:
+ virtual ~Writer();
+
+ virtual std::string write(const Value& root) = 0;
+};
+
+/** \brief Outputs a Value in <a HREF="http://www.json.org">JSON</a> format
+ *without formatting (not human friendly).
+ *
+ * The JSON document is written in a single line. It is not intended for 'human'
+ *consumption,
+ * but may be usefull to support feature such as RPC where bandwith is limited.
+ * \sa Reader, Value
+ */
+class JSON_API FastWriter : public Writer {
+public:
+ FastWriter();
+ virtual ~FastWriter() {}
+
+ void enableYAMLCompatibility();
+
+ /** \brief Drop the "null" string from the writer's output for nullValues.
+ * Strictly speaking, this is not valid JSON. But when the output is being
+ * fed to a browser's Javascript, it makes for smaller output and the
+ * browser can handle the output just fine.
+ */
+ void dropNullPlaceholders();
+
+ void omitEndingLineFeed();
+
+public: // overridden from Writer
+ virtual std::string write(const Value& root);
+
+private:
+ void writeValue(const Value& value);
+
+ std::string document_;
+ bool yamlCompatiblityEnabled_;
+ bool dropNullPlaceholders_;
+ bool omitEndingLineFeed_;
+};
+
+/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
+ *human friendly way.
+ *
+ * The rules for line break and indent are as follow:
+ * - Object value:
+ * - if empty then print {} without indent and line break
+ * - if not empty the print '{', line break & indent, print one value per
+ *line
+ * and then unindent and line break and print '}'.
+ * - Array value:
+ * - if empty then print [] without indent and line break
+ * - if the array contains no object value, empty array or some other value
+ *types,
+ * and all the values fit on one lines, then print the array on a single
+ *line.
+ * - otherwise, it the values do not fit on one line, or the array contains
+ * object or non empty array, then print one value per line.
+ *
+ * If the Value have comments then they are outputed according to their
+ *#CommentPlacement.
+ *
+ * \sa Reader, Value, Value::setComment()
+ */
+class JSON_API StyledWriter : public Writer {
+public:
+ StyledWriter();
+ virtual ~StyledWriter() {}
+
+public: // overridden from Writer
+ /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
+ * \param root Value to serialize.
+ * \return String containing the JSON document that represents the root value.
+ */
+ virtual std::string write(const Value& root);
+
+private:
+ void writeValue(const Value& value);
+ void writeArrayValue(const Value& value);
+ bool isMultineArray(const Value& value);
+ void pushValue(const std::string& value);
+ void writeIndent();
+ void writeWithIndent(const std::string& value);
+ void indent();
+ void unindent();
+ void writeCommentBeforeValue(const Value& root);
+ void writeCommentAfterValueOnSameLine(const Value& root);
+ bool hasCommentForValue(const Value& value);
+ static std::string normalizeEOL(const std::string& text);
+
+ typedef std::vector<std::string> ChildValues;
+
+ ChildValues childValues_;
+ std::string document_;
+ std::string indentString_;
+ int rightMargin_;
+ int indentSize_;
+ bool addChildValues_;
+};
+
+/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
+ human friendly way,
+ to a stream rather than to a string.
+ *
+ * The rules for line break and indent are as follow:
+ * - Object value:
+ * - if empty then print {} without indent and line break
+ * - if not empty the print '{', line break & indent, print one value per
+ line
+ * and then unindent and line break and print '}'.
+ * - Array value:
+ * - if empty then print [] without indent and line break
+ * - if the array contains no object value, empty array or some other value
+ types,
+ * and all the values fit on one lines, then print the array on a single
+ line.
+ * - otherwise, it the values do not fit on one line, or the array contains
+ * object or non empty array, then print one value per line.
+ *
+ * If the Value have comments then they are outputed according to their
+ #CommentPlacement.
+ *
+ * \sa Reader, Value, Value::setComment()
+ */
+class JSON_API StyledStreamWriter {
+public:
+ StyledStreamWriter(std::string indentation = "\t");
+ ~StyledStreamWriter() {}
+
+public:
+ /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
+ * \param out Stream to write to. (Can be ostringstream, e.g.)
+ * \param root Value to serialize.
+ * \note There is no point in deriving from Writer, since write() should not
+ * return a value.
+ */
+ void write(std::ostream& out, const Value& root);
+
+private:
+ void writeValue(const Value& value);
+ void writeArrayValue(const Value& value);
+ bool isMultineArray(const Value& value);
+ void pushValue(const std::string& value);
+ void writeIndent();
+ void writeWithIndent(const std::string& value);
+ void indent();
+ void unindent();
+ void writeCommentBeforeValue(const Value& root);
+ void writeCommentAfterValueOnSameLine(const Value& root);
+ bool hasCommentForValue(const Value& value);
+ static std::string normalizeEOL(const std::string& text);
+
+ typedef std::vector<std::string> ChildValues;
+
+ ChildValues childValues_;
+ std::ostream* document_;
+ std::string indentString_;
+ int rightMargin_;
+ std::string indentation_;
+ bool addChildValues_;
+};
+
+#if defined(JSON_HAS_INT64)
+std::string JSON_API valueToString(Int value);
+std::string JSON_API valueToString(UInt value);
+#endif // if defined(JSON_HAS_INT64)
+std::string JSON_API valueToString(LargestInt value);
+std::string JSON_API valueToString(LargestUInt value);
+std::string JSON_API valueToString(double value);
+std::string JSON_API valueToString(bool value);
+std::string JSON_API valueToQuotedString(const char* value);
+
+/// \brief Output using the StyledStreamWriter.
+/// \see Json::operator>>()
+JSON_API std::ostream& operator<<(std::ostream&, const Value& root);
+
+} // namespace Json
+
+#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
+#pragma warning(pop)
+#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
+
+#endif // JSON_WRITER_H_INCLUDED
diff --git a/Utilities/cmjsoncpp/src/lib_json/json_batchallocator.h b/Utilities/cmjsoncpp/src/lib_json/json_batchallocator.h
new file mode 100644
index 000000000..2fbef7a86
--- /dev/null
+++ b/Utilities/cmjsoncpp/src/lib_json/json_batchallocator.h
@@ -0,0 +1,121 @@
+// Copyright 2007-2010 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#ifndef JSONCPP_BATCHALLOCATOR_H_INCLUDED
+#define JSONCPP_BATCHALLOCATOR_H_INCLUDED
+
+#include <stdlib.h>
+#include <assert.h>
+
+#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
+
+namespace Json {
+
+/* Fast memory allocator.
+ *
+ * This memory allocator allocates memory for a batch of object (specified by
+ * the page size, the number of object in each page).
+ *
+ * It does not allow the destruction of a single object. All the allocated
+ * objects can be destroyed at once. The memory can be either released or reused
+ * for future allocation.
+ *
+ * The in-place new operator must be used to construct the object using the
+ * pointer returned by allocate.
+ */
+template <typename AllocatedType, const unsigned int objectPerAllocation>
+class BatchAllocator {
+public:
+ BatchAllocator(unsigned int objectsPerPage = 255)
+ : freeHead_(0), objectsPerPage_(objectsPerPage) {
+ // printf( "Size: %d => %s\n", sizeof(AllocatedType),
+ // typeid(AllocatedType).name() );
+ assert(sizeof(AllocatedType) * objectPerAllocation >=
+ sizeof(AllocatedType*)); // We must be able to store a slist in the
+ // object free space.
+ assert(objectsPerPage >= 16);
+ batches_ = allocateBatch(0); // allocated a dummy page
+ currentBatch_ = batches_;
+ }
+
+ ~BatchAllocator() {
+ for (BatchInfo* batch = batches_; batch;) {
+ BatchInfo* nextBatch = batch->next_;
+ free(batch);
+ batch = nextBatch;
+ }
+ }
+
+ /// allocate space for an array of objectPerAllocation object.
+ /// @warning it is the responsability of the caller to call objects
+ /// constructors.
+ AllocatedType* allocate() {
+ if (freeHead_) // returns node from free list.
+ {
+ AllocatedType* object = freeHead_;
+ freeHead_ = *(AllocatedType**)object;
+ return object;
+ }
+ if (currentBatch_->used_ == currentBatch_->end_) {
+ currentBatch_ = currentBatch_->next_;
+ while (currentBatch_ && currentBatch_->used_ == currentBatch_->end_)
+ currentBatch_ = currentBatch_->next_;
+
+ if (!currentBatch_) // no free batch found, allocate a new one
+ {
+ currentBatch_ = allocateBatch(objectsPerPage_);
+ currentBatch_->next_ = batches_; // insert at the head of the list
+ batches_ = currentBatch_;
+ }
+ }
+ AllocatedType* allocated = currentBatch_->used_;
+ currentBatch_->used_ += objectPerAllocation;
+ return allocated;
+ }
+
+ /// Release the object.
+ /// @warning it is the responsability of the caller to actually destruct the
+ /// object.
+ void release(AllocatedType* object) {
+ assert(object != 0);
+ *(AllocatedType**)object = freeHead_;
+ freeHead_ = object;
+ }
+
+private:
+ struct BatchInfo {
+ BatchInfo* next_;
+ AllocatedType* used_;
+ AllocatedType* end_;
+ AllocatedType buffer_[objectPerAllocation];
+ };
+
+ // disabled copy constructor and assignement operator.
+ BatchAllocator(const BatchAllocator&);
+ void operator=(const BatchAllocator&);
+
+ static BatchInfo* allocateBatch(unsigned int objectsPerPage) {
+ const unsigned int mallocSize =
+ sizeof(BatchInfo) - sizeof(AllocatedType) * objectPerAllocation +
+ sizeof(AllocatedType) * objectPerAllocation * objectsPerPage;
+ BatchInfo* batch = static_cast<BatchInfo*>(malloc(mallocSize));
+ batch->next_ = 0;
+ batch->used_ = batch->buffer_;
+ batch->end_ = batch->buffer_ + objectsPerPage;
+ return batch;
+ }
+
+ BatchInfo* batches_;
+ BatchInfo* currentBatch_;
+ /// Head of a single linked list within the allocated space of freeed object
+ AllocatedType* freeHead_;
+ unsigned int objectsPerPage_;
+};
+
+} // namespace Json
+
+#endif // ifndef JSONCPP_DOC_INCLUDE_IMPLEMENTATION
+
+#endif // JSONCPP_BATCHALLOCATOR_H_INCLUDED
diff --git a/Utilities/cmjsoncpp/src/lib_json/json_internalarray.inl b/Utilities/cmjsoncpp/src/lib_json/json_internalarray.inl
new file mode 100644
index 000000000..9ee15e9db
--- /dev/null
+++ b/Utilities/cmjsoncpp/src/lib_json/json_internalarray.inl
@@ -0,0 +1,360 @@
+// Copyright 2007-2010 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+// included by json_value.cpp
+
+namespace Json {
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// class ValueInternalArray
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+
+ValueArrayAllocator::~ValueArrayAllocator() {}
+
+// //////////////////////////////////////////////////////////////////
+// class DefaultValueArrayAllocator
+// //////////////////////////////////////////////////////////////////
+#ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
+class DefaultValueArrayAllocator : public ValueArrayAllocator {
+public: // overridden from ValueArrayAllocator
+ virtual ~DefaultValueArrayAllocator() {}
+
+ virtual ValueInternalArray* newArray() { return new ValueInternalArray(); }
+
+ virtual ValueInternalArray* newArrayCopy(const ValueInternalArray& other) {
+ return new ValueInternalArray(other);
+ }
+
+ virtual void destructArray(ValueInternalArray* array) { delete array; }
+
+ virtual void
+ reallocateArrayPageIndex(Value**& indexes,
+ ValueInternalArray::PageIndex& indexCount,
+ ValueInternalArray::PageIndex minNewIndexCount) {
+ ValueInternalArray::PageIndex newIndexCount = (indexCount * 3) / 2 + 1;
+ if (minNewIndexCount > newIndexCount)
+ newIndexCount = minNewIndexCount;
+ void* newIndexes = realloc(indexes, sizeof(Value*) * newIndexCount);
+ JSON_ASSERT_MESSAGE(newIndexes, "Couldn't realloc.");
+ indexCount = newIndexCount;
+ indexes = static_cast<Value**>(newIndexes);
+ }
+ virtual void releaseArrayPageIndex(Value** indexes,
+ ValueInternalArray::PageIndex indexCount) {
+ if (indexes)
+ free(indexes);
+ }
+
+ virtual Value* allocateArrayPage() {
+ return static_cast<Value*>(
+ malloc(sizeof(Value) * ValueInternalArray::itemsPerPage));
+ }
+
+ virtual void releaseArrayPage(Value* value) {
+ if (value)
+ free(value);
+ }
+};
+
+#else // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
+/// @todo make this thread-safe (lock when accessign batch allocator)
+class DefaultValueArrayAllocator : public ValueArrayAllocator {
+public: // overridden from ValueArrayAllocator
+ virtual ~DefaultValueArrayAllocator() {}
+
+ virtual ValueInternalArray* newArray() {
+ ValueInternalArray* array = arraysAllocator_.allocate();
+ new (array) ValueInternalArray(); // placement new
+ return array;
+ }
+
+ virtual ValueInternalArray* newArrayCopy(const ValueInternalArray& other) {
+ ValueInternalArray* array = arraysAllocator_.allocate();
+ new (array) ValueInternalArray(other); // placement new
+ return array;
+ }
+
+ virtual void destructArray(ValueInternalArray* array) {
+ if (array) {
+ array->~ValueInternalArray();
+ arraysAllocator_.release(array);
+ }
+ }
+
+ virtual void
+ reallocateArrayPageIndex(Value**& indexes,
+ ValueInternalArray::PageIndex& indexCount,
+ ValueInternalArray::PageIndex minNewIndexCount) {
+ ValueInternalArray::PageIndex newIndexCount = (indexCount * 3) / 2 + 1;
+ if (minNewIndexCount > newIndexCount)
+ newIndexCount = minNewIndexCount;
+ void* newIndexes = realloc(indexes, sizeof(Value*) * newIndexCount);
+ JSON_ASSERT_MESSAGE(newIndexes, "Couldn't realloc.");
+ indexCount = newIndexCount;
+ indexes = static_cast<Value**>(newIndexes);
+ }
+ virtual void releaseArrayPageIndex(Value** indexes,
+ ValueInternalArray::PageIndex indexCount) {
+ if (indexes)
+ free(indexes);
+ }
+
+ virtual Value* allocateArrayPage() {
+ return static_cast<Value*>(pagesAllocator_.allocate());
+ }
+
+ virtual void releaseArrayPage(Value* value) {
+ if (value)
+ pagesAllocator_.release(value);
+ }
+
+private:
+ BatchAllocator<ValueInternalArray, 1> arraysAllocator_;
+ BatchAllocator<Value, ValueInternalArray::itemsPerPage> pagesAllocator_;
+};
+#endif // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
+
+static ValueArrayAllocator*& arrayAllocator() {
+ static DefaultValueArrayAllocator defaultAllocator;
+ static ValueArrayAllocator* arrayAllocator = &defaultAllocator;
+ return arrayAllocator;
+}
+
+static struct DummyArrayAllocatorInitializer {
+ DummyArrayAllocatorInitializer() {
+ arrayAllocator(); // ensure arrayAllocator() statics are initialized before
+ // main().
+ }
+} dummyArrayAllocatorInitializer;
+
+// //////////////////////////////////////////////////////////////////
+// class ValueInternalArray
+// //////////////////////////////////////////////////////////////////
+bool ValueInternalArray::equals(const IteratorState& x,
+ const IteratorState& other) {
+ return x.array_ == other.array_ &&
+ x.currentItemIndex_ == other.currentItemIndex_ &&
+ x.currentPageIndex_ == other.currentPageIndex_;
+}
+
+void ValueInternalArray::increment(IteratorState& it) {
+ JSON_ASSERT_MESSAGE(
+ it.array_ && (it.currentPageIndex_ - it.array_->pages_) * itemsPerPage +
+ it.currentItemIndex_ !=
+ it.array_->size_,
+ "ValueInternalArray::increment(): moving iterator beyond end");
+ ++(it.currentItemIndex_);
+ if (it.currentItemIndex_ == itemsPerPage) {
+ it.currentItemIndex_ = 0;
+ ++(it.currentPageIndex_);
+ }
+}
+
+void ValueInternalArray::decrement(IteratorState& it) {
+ JSON_ASSERT_MESSAGE(
+ it.array_ && it.currentPageIndex_ == it.array_->pages_ &&
+ it.currentItemIndex_ == 0,
+ "ValueInternalArray::decrement(): moving iterator beyond end");
+ if (it.currentItemIndex_ == 0) {
+ it.currentItemIndex_ = itemsPerPage - 1;
+ --(it.currentPageIndex_);
+ } else {
+ --(it.currentItemIndex_);
+ }
+}
+
+Value& ValueInternalArray::unsafeDereference(const IteratorState& it) {
+ return (*(it.currentPageIndex_))[it.currentItemIndex_];
+}
+
+Value& ValueInternalArray::dereference(const IteratorState& it) {
+ JSON_ASSERT_MESSAGE(
+ it.array_ && (it.currentPageIndex_ - it.array_->pages_) * itemsPerPage +
+ it.currentItemIndex_ <
+ it.array_->size_,
+ "ValueInternalArray::dereference(): dereferencing invalid iterator");
+ return unsafeDereference(it);
+}
+
+void ValueInternalArray::makeBeginIterator(IteratorState& it) const {
+ it.array_ = const_cast<ValueInternalArray*>(this);
+ it.currentItemIndex_ = 0;
+ it.currentPageIndex_ = pages_;
+}
+
+void ValueInternalArray::makeIterator(IteratorState& it,
+ ArrayIndex index) const {
+ it.array_ = const_cast<ValueInternalArray*>(this);
+ it.currentItemIndex_ = index % itemsPerPage;
+ it.currentPageIndex_ = pages_ + index / itemsPerPage;
+}
+
+void ValueInternalArray::makeEndIterator(IteratorState& it) const {
+ makeIterator(it, size_);
+}
+
+ValueInternalArray::ValueInternalArray() : pages_(0), size_(0), pageCount_(0) {}
+
+ValueInternalArray::ValueInternalArray(const ValueInternalArray& other)
+ : pages_(0), size_(other.size_), pageCount_(0) {
+ PageIndex minNewPages = other.size_ / itemsPerPage;
+ arrayAllocator()->reallocateArrayPageIndex(pages_, pageCount_, minNewPages);
+ JSON_ASSERT_MESSAGE(pageCount_ >= minNewPages,
+ "ValueInternalArray::reserve(): bad reallocation");
+ IteratorState itOther;
+ other.makeBeginIterator(itOther);
+ Value* value;
+ for (ArrayIndex index = 0; index < size_; ++index, increment(itOther)) {
+ if (index % itemsPerPage == 0) {
+ PageIndex pageIndex = index / itemsPerPage;
+ value = arrayAllocator()->allocateArrayPage();
+ pages_[pageIndex] = value;
+ }
+ new (value) Value(dereference(itOther));
+ }
+}
+
+ValueInternalArray& ValueInternalArray::operator=(ValueInternalArray other) {
+ swap(other);
+ return *this;
+}
+
+ValueInternalArray::~ValueInternalArray() {
+ // destroy all constructed items
+ IteratorState it;
+ IteratorState itEnd;
+ makeBeginIterator(it);
+ makeEndIterator(itEnd);
+ for (; !equals(it, itEnd); increment(it)) {
+ Value* value = &dereference(it);
+ value->~Value();
+ }
+ // release all pages
+ PageIndex lastPageIndex = size_ / itemsPerPage;
+ for (PageIndex pageIndex = 0; pageIndex < lastPageIndex; ++pageIndex)
+ arrayAllocator()->releaseArrayPage(pages_[pageIndex]);
+ // release pages index
+ arrayAllocator()->releaseArrayPageIndex(pages_, pageCount_);
+}
+
+void ValueInternalArray::swap(ValueInternalArray& other) {
+ Value** tempPages = pages_;
+ pages_ = other.pages_;
+ other.pages_ = tempPages;
+ ArrayIndex tempSize = size_;
+ size_ = other.size_;
+ other.size_ = tempSize;
+ PageIndex tempPageCount = pageCount_;
+ pageCount_ = other.pageCount_;
+ other.pageCount_ = tempPageCount;
+}
+
+void ValueInternalArray::clear() {
+ ValueInternalArray dummy;
+ swap(dummy);
+}
+
+void ValueInternalArray::resize(ArrayIndex newSize) {
+ if (newSize == 0)
+ clear();
+ else if (newSize < size_) {
+ IteratorState it;
+ IteratorState itEnd;
+ makeIterator(it, newSize);
+ makeIterator(itEnd, size_);
+ for (; !equals(it, itEnd); increment(it)) {
+ Value* value = &dereference(it);
+ value->~Value();
+ }
+ PageIndex pageIndex = (newSize + itemsPerPage - 1) / itemsPerPage;
+ PageIndex lastPageIndex = size_ / itemsPerPage;
+ for (; pageIndex < lastPageIndex; ++pageIndex)
+ arrayAllocator()->releaseArrayPage(pages_[pageIndex]);
+ size_ = newSize;
+ } else if (newSize > size_)
+ resolveReference(newSize);
+}
+
+void ValueInternalArray::makeIndexValid(ArrayIndex index) {
+ // Need to enlarge page index ?
+ if (index >= pageCount_ * itemsPerPage) {
+ PageIndex minNewPages = (index + 1) / itemsPerPage;
+ arrayAllocator()->reallocateArrayPageIndex(pages_, pageCount_, minNewPages);
+ JSON_ASSERT_MESSAGE(pageCount_ >= minNewPages,
+ "ValueInternalArray::reserve(): bad reallocation");
+ }
+
+ // Need to allocate new pages ?
+ ArrayIndex nextPageIndex = (size_ % itemsPerPage) != 0
+ ? size_ - (size_ % itemsPerPage) + itemsPerPage
+ : size_;
+ if (nextPageIndex <= index) {
+ PageIndex pageIndex = nextPageIndex / itemsPerPage;
+ PageIndex pageToAllocate = (index - nextPageIndex) / itemsPerPage + 1;
+ for (; pageToAllocate-- > 0; ++pageIndex)
+ pages_[pageIndex] = arrayAllocator()->allocateArrayPage();
+ }
+
+ // Initialize all new entries
+ IteratorState it;
+ IteratorState itEnd;
+ makeIterator(it, size_);
+ size_ = index + 1;
+ makeIterator(itEnd, size_);
+ for (; !equals(it, itEnd); increment(it)) {
+ Value* value = &dereference(it);
+ new (value) Value(); // Construct a default value using placement new
+ }
+}
+
+Value& ValueInternalArray::resolveReference(ArrayIndex index) {
+ if (index >= size_)
+ makeIndexValid(index);
+ return pages_[index / itemsPerPage][index % itemsPerPage];
+}
+
+Value* ValueInternalArray::find(ArrayIndex index) const {
+ if (index >= size_)
+ return 0;
+ return &(pages_[index / itemsPerPage][index % itemsPerPage]);
+}
+
+ValueInternalArray::ArrayIndex ValueInternalArray::size() const {
+ return size_;
+}
+
+int ValueInternalArray::distance(const IteratorState& x,
+ const IteratorState& y) {
+ return indexOf(y) - indexOf(x);
+}
+
+ValueInternalArray::ArrayIndex
+ValueInternalArray::indexOf(const IteratorState& iterator) {
+ if (!iterator.array_)
+ return ArrayIndex(-1);
+ return ArrayIndex((iterator.currentPageIndex_ - iterator.array_->pages_) *
+ itemsPerPage +
+ iterator.currentItemIndex_);
+}
+
+int ValueInternalArray::compare(const ValueInternalArray& other) const {
+ int sizeDiff(size_ - other.size_);
+ if (sizeDiff != 0)
+ return sizeDiff;
+
+ for (ArrayIndex index = 0; index < size_; ++index) {
+ int diff = pages_[index / itemsPerPage][index % itemsPerPage].compare(
+ other.pages_[index / itemsPerPage][index % itemsPerPage]);
+ if (diff != 0)
+ return diff;
+ }
+ return 0;
+}
+
+} // namespace Json
diff --git a/Utilities/cmjsoncpp/src/lib_json/json_internalmap.inl b/Utilities/cmjsoncpp/src/lib_json/json_internalmap.inl
new file mode 100644
index 000000000..ef3f3302d
--- /dev/null
+++ b/Utilities/cmjsoncpp/src/lib_json/json_internalmap.inl
@@ -0,0 +1,473 @@
+// Copyright 2007-2010 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+// included by json_value.cpp
+
+namespace Json {
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// class ValueInternalMap
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+
+/** \internal MUST be safely initialized using memset( this, 0,
+ * sizeof(ValueInternalLink) );
+ * This optimization is used by the fast allocator.
+ */
+ValueInternalLink::ValueInternalLink() : previous_(0), next_(0) {}
+
+ValueInternalLink::~ValueInternalLink() {
+ for (int index = 0; index < itemPerLink; ++index) {
+ if (!items_[index].isItemAvailable()) {
+ if (!items_[index].isMemberNameStatic())
+ free(keys_[index]);
+ } else
+ break;
+ }
+}
+
+ValueMapAllocator::~ValueMapAllocator() {}
+
+#ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
+class DefaultValueMapAllocator : public ValueMapAllocator {
+public: // overridden from ValueMapAllocator
+ virtual ValueInternalMap* newMap() { return new ValueInternalMap(); }
+
+ virtual ValueInternalMap* newMapCopy(const ValueInternalMap& other) {
+ return new ValueInternalMap(other);
+ }
+
+ virtual void destructMap(ValueInternalMap* map) { delete map; }
+
+ virtual ValueInternalLink* allocateMapBuckets(unsigned int size) {
+ return new ValueInternalLink[size];
+ }
+
+ virtual void releaseMapBuckets(ValueInternalLink* links) { delete[] links; }
+
+ virtual ValueInternalLink* allocateMapLink() {
+ return new ValueInternalLink();
+ }
+
+ virtual void releaseMapLink(ValueInternalLink* link) { delete link; }
+};
+#else
+/// @todo make this thread-safe (lock when accessign batch allocator)
+class DefaultValueMapAllocator : public ValueMapAllocator {
+public: // overridden from ValueMapAllocator
+ virtual ValueInternalMap* newMap() {
+ ValueInternalMap* map = mapsAllocator_.allocate();
+ new (map) ValueInternalMap(); // placement new
+ return map;
+ }
+
+ virtual ValueInternalMap* newMapCopy(const ValueInternalMap& other) {
+ ValueInternalMap* map = mapsAllocator_.allocate();
+ new (map) ValueInternalMap(other); // placement new
+ return map;
+ }
+
+ virtual void destructMap(ValueInternalMap* map) {
+ if (map) {
+ map->~ValueInternalMap();
+ mapsAllocator_.release(map);
+ }
+ }
+
+ virtual ValueInternalLink* allocateMapBuckets(unsigned int size) {
+ return new ValueInternalLink[size];
+ }
+
+ virtual void releaseMapBuckets(ValueInternalLink* links) { delete[] links; }
+
+ virtual ValueInternalLink* allocateMapLink() {
+ ValueInternalLink* link = linksAllocator_.allocate();
+ memset(link, 0, sizeof(ValueInternalLink));
+ return link;
+ }
+
+ virtual void releaseMapLink(ValueInternalLink* link) {
+ link->~ValueInternalLink();
+ linksAllocator_.release(link);
+ }
+
+private:
+ BatchAllocator<ValueInternalMap, 1> mapsAllocator_;
+ BatchAllocator<ValueInternalLink, 1> linksAllocator_;
+};
+#endif
+
+static ValueMapAllocator*& mapAllocator() {
+ static DefaultValueMapAllocator defaultAllocator;
+ static ValueMapAllocator* mapAllocator = &defaultAllocator;
+ return mapAllocator;
+}
+
+static struct DummyMapAllocatorInitializer {
+ DummyMapAllocatorInitializer() {
+ mapAllocator(); // ensure mapAllocator() statics are initialized before
+ // main().
+ }
+} dummyMapAllocatorInitializer;
+
+// h(K) = value * K >> w ; with w = 32 & K prime w.r.t. 2^32.
+
+/*
+use linked list hash map.
+buckets array is a container.
+linked list element contains 6 key/values. (memory = (16+4) * 6 + 4 = 124)
+value have extra state: valid, available, deleted
+*/
+
+ValueInternalMap::ValueInternalMap()
+ : buckets_(0), tailLink_(0), bucketsSize_(0), itemCount_(0) {}
+
+ValueInternalMap::ValueInternalMap(const ValueInternalMap& other)
+ : buckets_(0), tailLink_(0), bucketsSize_(0), itemCount_(0) {
+ reserve(other.itemCount_);
+ IteratorState it;
+ IteratorState itEnd;
+ other.makeBeginIterator(it);
+ other.makeEndIterator(itEnd);
+ for (; !equals(it, itEnd); increment(it)) {
+ bool isStatic;
+ const char* memberName = key(it, isStatic);
+ const Value& aValue = value(it);
+ resolveReference(memberName, isStatic) = aValue;
+ }
+}
+
+ValueInternalMap& ValueInternalMap::operator=(ValueInternalMap other) {
+ swap(other);
+ return *this;
+}
+
+ValueInternalMap::~ValueInternalMap() {
+ if (buckets_) {
+ for (BucketIndex bucketIndex = 0; bucketIndex < bucketsSize_;
+ ++bucketIndex) {
+ ValueInternalLink* link = buckets_[bucketIndex].next_;
+ while (link) {
+ ValueInternalLink* linkToRelease = link;
+ link = link->next_;
+ mapAllocator()->releaseMapLink(linkToRelease);
+ }
+ }
+ mapAllocator()->releaseMapBuckets(buckets_);
+ }
+}
+
+void ValueInternalMap::swap(ValueInternalMap& other) {
+ ValueInternalLink* tempBuckets = buckets_;
+ buckets_ = other.buckets_;
+ other.buckets_ = tempBuckets;
+ ValueInternalLink* tempTailLink = tailLink_;
+ tailLink_ = other.tailLink_;
+ other.tailLink_ = tempTailLink;
+ BucketIndex tempBucketsSize = bucketsSize_;
+ bucketsSize_ = other.bucketsSize_;
+ other.bucketsSize_ = tempBucketsSize;
+ BucketIndex tempItemCount = itemCount_;
+ itemCount_ = other.itemCount_;
+ other.itemCount_ = tempItemCount;
+}
+
+void ValueInternalMap::clear() {
+ ValueInternalMap dummy;
+ swap(dummy);
+}
+
+ValueInternalMap::BucketIndex ValueInternalMap::size() const {
+ return itemCount_;
+}
+
+bool ValueInternalMap::reserveDelta(BucketIndex growth) {
+ return reserve(itemCount_ + growth);
+}
+
+bool ValueInternalMap::reserve(BucketIndex newItemCount) {
+ if (!buckets_ && newItemCount > 0) {
+ buckets_ = mapAllocator()->allocateMapBuckets(1);
+ bucketsSize_ = 1;
+ tailLink_ = &buckets_[0];
+ }
+ // BucketIndex idealBucketCount = (newItemCount +
+ // ValueInternalLink::itemPerLink) / ValueInternalLink::itemPerLink;
+ return true;
+}
+
+const Value* ValueInternalMap::find(const char* key) const {
+ if (!bucketsSize_)
+ return 0;
+ HashKey hashedKey = hash(key);
+ BucketIndex bucketIndex = hashedKey % bucketsSize_;
+ for (const ValueInternalLink* current = &buckets_[bucketIndex]; current != 0;
+ current = current->next_) {
+ for (BucketIndex index = 0; index < ValueInternalLink::itemPerLink;
+ ++index) {
+ if (current->items_[index].isItemAvailable())
+ return 0;
+ if (strcmp(key, current->keys_[index]) == 0)
+ return &current->items_[index];
+ }
+ }
+ return 0;
+}
+
+Value* ValueInternalMap::find(const char* key) {
+ const ValueInternalMap* constThis = this;
+ return const_cast<Value*>(constThis->find(key));
+}
+
+Value& ValueInternalMap::resolveReference(const char* key, bool isStatic) {
+ HashKey hashedKey = hash(key);
+ if (bucketsSize_) {
+ BucketIndex bucketIndex = hashedKey % bucketsSize_;
+ ValueInternalLink** previous = 0;
+ BucketIndex index;
+ for (ValueInternalLink* current = &buckets_[bucketIndex]; current != 0;
+ previous = &current->next_, current = current->next_) {
+ for (index = 0; index < ValueInternalLink::itemPerLink; ++index) {
+ if (current->items_[index].isItemAvailable())
+ return setNewItem(key, isStatic, current, index);
+ if (strcmp(key, current->keys_[index]) == 0)
+ return current->items_[index];
+ }
+ }
+ }
+
+ reserveDelta(1);
+ return unsafeAdd(key, isStatic, hashedKey);
+}
+
+void ValueInternalMap::remove(const char* key) {
+ HashKey hashedKey = hash(key);
+ if (!bucketsSize_)
+ return;
+ BucketIndex bucketIndex = hashedKey % bucketsSize_;
+ for (ValueInternalLink* link = &buckets_[bucketIndex]; link != 0;
+ link = link->next_) {
+ BucketIndex index;
+ for (index = 0; index < ValueInternalLink::itemPerLink; ++index) {
+ if (link->items_[index].isItemAvailable())
+ return;
+ if (strcmp(key, link->keys_[index]) == 0) {
+ doActualRemove(link, index, bucketIndex);
+ return;
+ }
+ }
+ }
+}
+
+void ValueInternalMap::doActualRemove(ValueInternalLink* link,
+ BucketIndex index,
+ BucketIndex bucketIndex) {
+ // find last item of the bucket and swap it with the 'removed' one.
+ // set removed items flags to 'available'.
+ // if last page only contains 'available' items, then desallocate it (it's
+ // empty)
+ ValueInternalLink*& lastLink = getLastLinkInBucket(index);
+ BucketIndex lastItemIndex = 1; // a link can never be empty, so start at 1
+ for (; lastItemIndex < ValueInternalLink::itemPerLink;
+ ++lastItemIndex) // may be optimized with dicotomic search
+ {
+ if (lastLink->items_[lastItemIndex].isItemAvailable())
+ break;
+ }
+
+ BucketIndex lastUsedIndex = lastItemIndex - 1;
+ Value* valueToDelete = &link->items_[index];
+ Value* valueToPreserve = &lastLink->items_[lastUsedIndex];
+ if (valueToDelete != valueToPreserve)
+ valueToDelete->swap(*valueToPreserve);
+ if (lastUsedIndex == 0) // page is now empty
+ { // remove it from bucket linked list and delete it.
+ ValueInternalLink* linkPreviousToLast = lastLink->previous_;
+ if (linkPreviousToLast != 0) // can not deleted bucket link.
+ {
+ mapAllocator()->releaseMapLink(lastLink);
+ linkPreviousToLast->next_ = 0;
+ lastLink = linkPreviousToLast;
+ }
+ } else {
+ Value dummy;
+ valueToPreserve->swap(dummy); // restore deleted to default Value.
+ valueToPreserve->setItemUsed(false);
+ }
+ --itemCount_;
+}
+
+ValueInternalLink*&
+ValueInternalMap::getLastLinkInBucket(BucketIndex bucketIndex) {
+ if (bucketIndex == bucketsSize_ - 1)
+ return tailLink_;
+ ValueInternalLink*& previous = buckets_[bucketIndex + 1].previous_;
+ if (!previous)
+ previous = &buckets_[bucketIndex];
+ return previous;
+}
+
+Value& ValueInternalMap::setNewItem(const char* key,
+ bool isStatic,
+ ValueInternalLink* link,
+ BucketIndex index) {
+ char* duplicatedKey = makeMemberName(key);
+ ++itemCount_;
+ link->keys_[index] = duplicatedKey;
+ link->items_[index].setItemUsed();
+ link->items_[index].setMemberNameIsStatic(isStatic);
+ return link->items_[index]; // items already default constructed.
+}
+
+Value&
+ValueInternalMap::unsafeAdd(const char* key, bool isStatic, HashKey hashedKey) {
+ JSON_ASSERT_MESSAGE(bucketsSize_ > 0,
+ "ValueInternalMap::unsafeAdd(): internal logic error.");
+ BucketIndex bucketIndex = hashedKey % bucketsSize_;
+ ValueInternalLink*& previousLink = getLastLinkInBucket(bucketIndex);
+ ValueInternalLink* link = previousLink;
+ BucketIndex index;
+ for (index = 0; index < ValueInternalLink::itemPerLink; ++index) {
+ if (link->items_[index].isItemAvailable())
+ break;
+ }
+ if (index == ValueInternalLink::itemPerLink) // need to add a new page
+ {
+ ValueInternalLink* newLink = mapAllocator()->allocateMapLink();
+ index = 0;
+ link->next_ = newLink;
+ previousLink = newLink;
+ link = newLink;
+ }
+ return setNewItem(key, isStatic, link, index);
+}
+
+ValueInternalMap::HashKey ValueInternalMap::hash(const char* key) const {
+ HashKey hash = 0;
+ while (*key)
+ hash += *key++ * 37;
+ return hash;
+}
+
+int ValueInternalMap::compare(const ValueInternalMap& other) const {
+ int sizeDiff(itemCount_ - other.itemCount_);
+ if (sizeDiff != 0)
+ return sizeDiff;
+ // Strict order guaranty is required. Compare all keys FIRST, then compare
+ // values.
+ IteratorState it;
+ IteratorState itEnd;
+ makeBeginIterator(it);
+ makeEndIterator(itEnd);
+ for (; !equals(it, itEnd); increment(it)) {
+ if (!other.find(key(it)))
+ return 1;
+ }
+
+ // All keys are equals, let's compare values
+ makeBeginIterator(it);
+ for (; !equals(it, itEnd); increment(it)) {
+ const Value* otherValue = other.find(key(it));
+ int valueDiff = value(it).compare(*otherValue);
+ if (valueDiff != 0)
+ return valueDiff;
+ }
+ return 0;
+}
+
+void ValueInternalMap::makeBeginIterator(IteratorState& it) const {
+ it.map_ = const_cast<ValueInternalMap*>(this);
+ it.bucketIndex_ = 0;
+ it.itemIndex_ = 0;
+ it.link_ = buckets_;
+}
+
+void ValueInternalMap::makeEndIterator(IteratorState& it) const {
+ it.map_ = const_cast<ValueInternalMap*>(this);
+ it.bucketIndex_ = bucketsSize_;
+ it.itemIndex_ = 0;
+ it.link_ = 0;
+}
+
+bool ValueInternalMap::equals(const IteratorState& x,
+ const IteratorState& other) {
+ return x.map_ == other.map_ && x.bucketIndex_ == other.bucketIndex_ &&
+ x.link_ == other.link_ && x.itemIndex_ == other.itemIndex_;
+}
+
+void ValueInternalMap::incrementBucket(IteratorState& iterator) {
+ ++iterator.bucketIndex_;
+ JSON_ASSERT_MESSAGE(
+ iterator.bucketIndex_ <= iterator.map_->bucketsSize_,
+ "ValueInternalMap::increment(): attempting to iterate beyond end.");
+ if (iterator.bucketIndex_ == iterator.map_->bucketsSize_)
+ iterator.link_ = 0;
+ else
+ iterator.link_ = &(iterator.map_->buckets_[iterator.bucketIndex_]);
+ iterator.itemIndex_ = 0;
+}
+
+void ValueInternalMap::increment(IteratorState& iterator) {
+ JSON_ASSERT_MESSAGE(iterator.map_,
+ "Attempting to iterator using invalid iterator.");
+ ++iterator.itemIndex_;
+ if (iterator.itemIndex_ == ValueInternalLink::itemPerLink) {
+ JSON_ASSERT_MESSAGE(
+ iterator.link_ != 0,
+ "ValueInternalMap::increment(): attempting to iterate beyond end.");
+ iterator.link_ = iterator.link_->next_;
+ if (iterator.link_ == 0)
+ incrementBucket(iterator);
+ } else if (iterator.link_->items_[iterator.itemIndex_].isItemAvailable()) {
+ incrementBucket(iterator);
+ }
+}
+
+void ValueInternalMap::decrement(IteratorState& iterator) {
+ if (iterator.itemIndex_ == 0) {
+ JSON_ASSERT_MESSAGE(iterator.map_,
+ "Attempting to iterate using invalid iterator.");
+ if (iterator.link_ == &iterator.map_->buckets_[iterator.bucketIndex_]) {
+ JSON_ASSERT_MESSAGE(iterator.bucketIndex_ > 0,
+ "Attempting to iterate beyond beginning.");
+ --(iterator.bucketIndex_);
+ }
+ iterator.link_ = iterator.link_->previous_;
+ iterator.itemIndex_ = ValueInternalLink::itemPerLink - 1;
+ }
+}
+
+const char* ValueInternalMap::key(const IteratorState& iterator) {
+ JSON_ASSERT_MESSAGE(iterator.link_,
+ "Attempting to iterate using invalid iterator.");
+ return iterator.link_->keys_[iterator.itemIndex_];
+}
+
+const char* ValueInternalMap::key(const IteratorState& iterator,
+ bool& isStatic) {
+ JSON_ASSERT_MESSAGE(iterator.link_,
+ "Attempting to iterate using invalid iterator.");
+ isStatic = iterator.link_->items_[iterator.itemIndex_].isMemberNameStatic();
+ return iterator.link_->keys_[iterator.itemIndex_];
+}
+
+Value& ValueInternalMap::value(const IteratorState& iterator) {
+ JSON_ASSERT_MESSAGE(iterator.link_,
+ "Attempting to iterate using invalid iterator.");
+ return iterator.link_->items_[iterator.itemIndex_];
+}
+
+int ValueInternalMap::distance(const IteratorState& x, const IteratorState& y) {
+ int offset = 0;
+ IteratorState it = x;
+ while (!equals(it, y))
+ increment(it);
+ return offset;
+}
+
+} // namespace Json
diff --git a/Utilities/cmjsoncpp/src/lib_json/json_reader.cpp b/Utilities/cmjsoncpp/src/lib_json/json_reader.cpp
new file mode 100644
index 000000000..7b338285c
--- /dev/null
+++ b/Utilities/cmjsoncpp/src/lib_json/json_reader.cpp
@@ -0,0 +1,885 @@
+// Copyright 2007-2011 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#if !defined(JSON_IS_AMALGAMATION)
+#include <json/assertions.h>
+#include <json/reader.h>
+#include <json/value.h>
+#include "json_tool.h"
+#endif // if !defined(JSON_IS_AMALGAMATION)
+#include <utility>
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <istream>
+
+#if defined(_MSC_VER) && _MSC_VER < 1500 // VC++ 8.0 and below
+#define snprintf _snprintf
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0
+// Disable warning about strdup being deprecated.
+#pragma warning(disable : 4996)
+#endif
+
+namespace Json {
+
+// Implementation of class Features
+// ////////////////////////////////
+
+Features::Features()
+ : allowComments_(true), strictRoot_(false),
+ allowDroppedNullPlaceholders_(false), allowNumericKeys_(false) {}
+
+Features Features::all() { return Features(); }
+
+Features Features::strictMode() {
+ Features features;
+ features.allowComments_ = false;
+ features.strictRoot_ = true;
+ features.allowDroppedNullPlaceholders_ = false;
+ features.allowNumericKeys_ = false;
+ return features;
+}
+
+// Implementation of class Reader
+// ////////////////////////////////
+
+static inline bool in(Reader::Char c,
+ Reader::Char c1,
+ Reader::Char c2,
+ Reader::Char c3,
+ Reader::Char c4) {
+ return c == c1 || c == c2 || c == c3 || c == c4;
+}
+
+static inline bool in(Reader::Char c,
+ Reader::Char c1,
+ Reader::Char c2,
+ Reader::Char c3,
+ Reader::Char c4,
+ Reader::Char c5) {
+ return c == c1 || c == c2 || c == c3 || c == c4 || c == c5;
+}
+
+static bool containsNewLine(Reader::Location begin, Reader::Location end) {
+ for (; begin < end; ++begin)
+ if (*begin == '\n' || *begin == '\r')
+ return true;
+ return false;
+}
+
+// Class Reader
+// //////////////////////////////////////////////////////////////////
+
+Reader::Reader()
+ : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
+ lastValue_(), commentsBefore_(), features_(Features::all()),
+ collectComments_() {}
+
+Reader::Reader(const Features& features)
+ : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
+ lastValue_(), commentsBefore_(), features_(features), collectComments_() {
+}
+
+bool
+Reader::parse(const std::string& document, Value& root, bool collectComments) {
+ document_ = document;
+ const char* begin = document_.c_str();
+ const char* end = begin + document_.length();
+ return parse(begin, end, root, collectComments);
+}
+
+bool Reader::parse(std::istream& sin, Value& root, bool collectComments) {
+ // std::istream_iterator<char> begin(sin);
+ // std::istream_iterator<char> end;
+ // Those would allow streamed input from a file, if parse() were a
+ // template function.
+
+ // Since std::string is reference-counted, this at least does not
+ // create an extra copy.
+ std::string doc;
+ std::getline(sin, doc, (char)EOF);
+ return parse(doc, root, collectComments);
+}
+
+bool Reader::parse(const char* beginDoc,
+ const char* endDoc,
+ Value& root,
+ bool collectComments) {
+ if (!features_.allowComments_) {
+ collectComments = false;
+ }
+
+ begin_ = beginDoc;
+ end_ = endDoc;
+ collectComments_ = collectComments;
+ current_ = begin_;
+ lastValueEnd_ = 0;
+ lastValue_ = 0;
+ commentsBefore_ = "";
+ errors_.clear();
+ while (!nodes_.empty())
+ nodes_.pop();
+ nodes_.push(&root);
+
+ bool successful = readValue();
+ Token token;
+ skipCommentTokens(token);
+ if (collectComments_ && !commentsBefore_.empty())
+ root.setComment(commentsBefore_, commentAfter);
+ if (features_.strictRoot_) {
+ if (!root.isArray() && !root.isObject()) {
+ // Set error location to start of doc, ideally should be first token found
+ // in doc
+ token.type_ = tokenError;
+ token.start_ = beginDoc;
+ token.end_ = endDoc;
+ addError(
+ "A valid JSON document must be either an array or an object value.",
+ token);
+ return false;
+ }
+ }
+ return successful;
+}
+
+bool Reader::readValue() {
+ Token token;
+ skipCommentTokens(token);
+ bool successful = true;
+
+ if (collectComments_ && !commentsBefore_.empty()) {
+ // Remove newline characters at the end of the comments
+ size_t lastNonNewline = commentsBefore_.find_last_not_of("\r\n");
+ if (lastNonNewline != std::string::npos) {
+ commentsBefore_.erase(lastNonNewline + 1);
+ } else {
+ commentsBefore_.clear();
+ }
+
+ currentValue().setComment(commentsBefore_, commentBefore);
+ commentsBefore_ = "";
+ }
+
+ switch (token.type_) {
+ case tokenObjectBegin:
+ successful = readObject(token);
+ currentValue().setOffsetLimit(current_ - begin_);
+ break;
+ case tokenArrayBegin:
+ successful = readArray(token);
+ currentValue().setOffsetLimit(current_ - begin_);
+ break;
+ case tokenNumber:
+ successful = decodeNumber(token);
+ break;
+ case tokenString:
+ successful = decodeString(token);
+ break;
+ case tokenTrue:
+ currentValue() = true;
+ currentValue().setOffsetStart(token.start_ - begin_);
+ currentValue().setOffsetLimit(token.end_ - begin_);
+ break;
+ case tokenFalse:
+ currentValue() = false;
+ currentValue().setOffsetStart(token.start_ - begin_);
+ currentValue().setOffsetLimit(token.end_ - begin_);
+ break;
+ case tokenNull:
+ currentValue() = Value();
+ currentValue().setOffsetStart(token.start_ - begin_);
+ currentValue().setOffsetLimit(token.end_ - begin_);
+ break;
+ case tokenArraySeparator:
+ if (features_.allowDroppedNullPlaceholders_) {
+ // "Un-read" the current token and mark the current value as a null
+ // token.
+ current_--;
+ currentValue() = Value();
+ currentValue().setOffsetStart(current_ - begin_ - 1);
+ currentValue().setOffsetLimit(current_ - begin_);
+ break;
+ }
+ // Else, fall through...
+ default:
+ currentValue().setOffsetStart(token.start_ - begin_);
+ currentValue().setOffsetLimit(token.end_ - begin_);
+ return addError("Syntax error: value, object or array expected.", token);
+ }
+
+ if (collectComments_) {
+ lastValueEnd_ = current_;
+ lastValue_ = &currentValue();
+ }
+
+ return successful;
+}
+
+void Reader::skipCommentTokens(Token& token) {
+ if (features_.allowComments_) {
+ do {
+ readToken(token);
+ } while (token.type_ == tokenComment);
+ } else {
+ readToken(token);
+ }
+}
+
+bool Reader::expectToken(TokenType type, Token& token, const char* message) {
+ readToken(token);
+ if (token.type_ != type)
+ return addError(message, token);
+ return true;
+}
+
+bool Reader::readToken(Token& token) {
+ skipSpaces();
+ token.start_ = current_;
+ Char c = getNextChar();
+ bool ok = true;
+ switch (c) {
+ case '{':
+ token.type_ = tokenObjectBegin;
+ break;
+ case '}':
+ token.type_ = tokenObjectEnd;
+ break;
+ case '[':
+ token.type_ = tokenArrayBegin;
+ break;
+ case ']':
+ token.type_ = tokenArrayEnd;
+ break;
+ case '"':
+ token.type_ = tokenString;
+ ok = readString();
+ break;
+ case '/':
+ token.type_ = tokenComment;
+ ok = readComment();
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '-':
+ token.type_ = tokenNumber;
+ readNumber();
+ break;
+ case 't':
+ token.type_ = tokenTrue;
+ ok = match("rue", 3);
+ break;
+ case 'f':
+ token.type_ = tokenFalse;
+ ok = match("alse", 4);
+ break;
+ case 'n':
+ token.type_ = tokenNull;
+ ok = match("ull", 3);
+ break;
+ case ',':
+ token.type_ = tokenArraySeparator;
+ break;
+ case ':':
+ token.type_ = tokenMemberSeparator;
+ break;
+ case 0:
+ token.type_ = tokenEndOfStream;
+ break;
+ default:
+ ok = false;
+ break;
+ }
+ if (!ok)
+ token.type_ = tokenError;
+ token.end_ = current_;
+ return true;
+}
+
+void Reader::skipSpaces() {
+ while (current_ != end_) {
+ Char c = *current_;
+ if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
+ ++current_;
+ else
+ break;
+ }
+}
+
+bool Reader::match(Location pattern, int patternLength) {
+ if (end_ - current_ < patternLength)
+ return false;
+ int index = patternLength;
+ while (index--)
+ if (current_[index] != pattern[index])
+ return false;
+ current_ += patternLength;
+ return true;
+}
+
+bool Reader::readComment() {
+ Location commentBegin = current_ - 1;
+ Char c = getNextChar();
+ bool successful = false;
+ if (c == '*')
+ successful = readCStyleComment();
+ else if (c == '/')
+ successful = readCppStyleComment();
+ if (!successful)
+ return false;
+
+ if (collectComments_) {
+ CommentPlacement placement = commentBefore;
+ if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) {
+ if (c != '*' || !containsNewLine(commentBegin, current_))
+ placement = commentAfterOnSameLine;
+ }
+
+ addComment(commentBegin, current_, placement);
+ }
+ return true;
+}
+
+void
+Reader::addComment(Location begin, Location end, CommentPlacement placement) {
+ assert(collectComments_);
+ if (placement == commentAfterOnSameLine) {
+ assert(lastValue_ != 0);
+ lastValue_->setComment(std::string(begin, end), placement);
+ } else {
+ commentsBefore_ += std::string(begin, end);
+ }
+}
+
+bool Reader::readCStyleComment() {
+ while (current_ != end_) {
+ Char c = getNextChar();
+ if (c == '*' && *current_ == '/')
+ break;
+ }
+ return getNextChar() == '/';
+}
+
+bool Reader::readCppStyleComment() {
+ while (current_ != end_) {
+ Char c = getNextChar();
+ if (c == '\r' || c == '\n')
+ break;
+ }
+ return true;
+}
+
+void Reader::readNumber() {
+ while (current_ != end_) {
+ if (!(*current_ >= '0' && *current_ <= '9') &&
+ !in(*current_, '.', 'e', 'E', '+', '-'))
+ break;
+ ++current_;
+ }
+}
+
+bool Reader::readString() {
+ Char c = 0;
+ while (current_ != end_) {
+ c = getNextChar();
+ if (c == '\\')
+ getNextChar();
+ else if (c == '"')
+ break;
+ }
+ return c == '"';
+}
+
+bool Reader::readObject(Token& tokenStart) {
+ Token tokenName;
+ std::string name;
+ currentValue() = Value(objectValue);
+ currentValue().setOffsetStart(tokenStart.start_ - begin_);
+ while (readToken(tokenName)) {
+ bool initialTokenOk = true;
+ while (tokenName.type_ == tokenComment && initialTokenOk)
+ initialTokenOk = readToken(tokenName);
+ if (!initialTokenOk)
+ break;
+ if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object
+ return true;
+ name = "";
+ if (tokenName.type_ == tokenString) {
+ if (!decodeString(tokenName, name))
+ return recoverFromError(tokenObjectEnd);
+ } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) {
+ Value numberName;
+ if (!decodeNumber(tokenName, numberName))
+ return recoverFromError(tokenObjectEnd);
+ name = numberName.asString();
+ } else {
+ break;
+ }
+
+ Token colon;
+ if (!readToken(colon) || colon.type_ != tokenMemberSeparator) {
+ return addErrorAndRecover(
+ "Missing ':' after object member name", colon, tokenObjectEnd);
+ }
+ Value& value = currentValue()[name];
+ nodes_.push(&value);
+ bool ok = readValue();
+ nodes_.pop();
+ if (!ok) // error already set
+ return recoverFromError(tokenObjectEnd);
+
+ Token comma;
+ if (!readToken(comma) ||
+ (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&
+ comma.type_ != tokenComment)) {
+ return addErrorAndRecover(
+ "Missing ',' or '}' in object declaration", comma, tokenObjectEnd);
+ }
+ bool finalizeTokenOk = true;
+ while (comma.type_ == tokenComment && finalizeTokenOk)
+ finalizeTokenOk = readToken(comma);
+ if (comma.type_ == tokenObjectEnd)
+ return true;
+ }
+ return addErrorAndRecover(
+ "Missing '}' or object member name", tokenName, tokenObjectEnd);
+}
+
+bool Reader::readArray(Token& tokenStart) {
+ currentValue() = Value(arrayValue);
+ currentValue().setOffsetStart(tokenStart.start_ - begin_);
+ skipSpaces();
+ if (*current_ == ']') // empty array
+ {
+ Token endArray;
+ readToken(endArray);
+ return true;
+ }
+ int index = 0;
+ for (;;) {
+ Value& value = currentValue()[index++];
+ nodes_.push(&value);
+ bool ok = readValue();
+ nodes_.pop();
+ if (!ok) // error already set
+ return recoverFromError(tokenArrayEnd);
+
+ Token token;
+ // Accept Comment after last item in the array.
+ ok = readToken(token);
+ while (token.type_ == tokenComment && ok) {
+ ok = readToken(token);
+ }
+ bool badTokenType =
+ (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd);
+ if (!ok || badTokenType) {
+ return addErrorAndRecover(
+ "Missing ',' or ']' in array declaration", token, tokenArrayEnd);
+ }
+ if (token.type_ == tokenArrayEnd)
+ break;
+ }
+ return true;
+}
+
+bool Reader::decodeNumber(Token& token) {
+ Value decoded;
+ if (!decodeNumber(token, decoded))
+ return false;
+ currentValue() = decoded;
+ currentValue().setOffsetStart(token.start_ - begin_);
+ currentValue().setOffsetLimit(token.end_ - begin_);
+ return true;
+}
+
+bool Reader::decodeNumber(Token& token, Value& decoded) {
+ bool isDouble = false;
+ for (Location inspect = token.start_; inspect != token.end_; ++inspect) {
+ isDouble = isDouble || in(*inspect, '.', 'e', 'E', '+') ||
+ (*inspect == '-' && inspect != token.start_);
+ }
+ if (isDouble)
+ return decodeDouble(token, decoded);
+ // Attempts to parse the number as an integer. If the number is
+ // larger than the maximum supported value of an integer then
+ // we decode the number as a double.
+ Location current = token.start_;
+ bool isNegative = *current == '-';
+ if (isNegative)
+ ++current;
+ Value::LargestUInt maxIntegerValue =
+ isNegative ? Value::LargestUInt(-Value::minLargestInt)
+ : Value::maxLargestUInt;
+ Value::LargestUInt threshold = maxIntegerValue / 10;
+ Value::LargestUInt value = 0;
+ while (current < token.end_) {
+ Char c = *current++;
+ if (c < '0' || c > '9')
+ return addError("'" + std::string(token.start_, token.end_) +
+ "' is not a number.",
+ token);
+ Value::UInt digit(static_cast<Value::UInt>(c - '0'));
+ if (value >= threshold) {
+ // We've hit or exceeded the max value divided by 10 (rounded down). If
+ // a) we've only just touched the limit, b) this is the last digit, and
+ // c) it's small enough to fit in that rounding delta, we're okay.
+ // Otherwise treat this number as a double to avoid overflow.
+ if (value > threshold || current != token.end_ ||
+ digit > maxIntegerValue % 10) {
+ return decodeDouble(token, decoded);
+ }
+ }
+ value = value * 10 + digit;
+ }
+ if (isNegative)
+ decoded = -Value::LargestInt(value);
+ else if (value <= Value::LargestUInt(Value::maxInt))
+ decoded = Value::LargestInt(value);
+ else
+ decoded = value;
+ return true;
+}
+
+bool Reader::decodeDouble(Token& token) {
+ Value decoded;
+ if (!decodeDouble(token, decoded))
+ return false;
+ currentValue() = decoded;
+ currentValue().setOffsetStart(token.start_ - begin_);
+ currentValue().setOffsetLimit(token.end_ - begin_);
+ return true;
+}
+
+bool Reader::decodeDouble(Token& token, Value& decoded) {
+ double value = 0;
+ const int bufferSize = 32;
+ int count;
+ int length = int(token.end_ - token.start_);
+
+ // Sanity check to avoid buffer overflow exploits.
+ if (length < 0) {
+ return addError("Unable to parse token length", token);
+ }
+
+ // Avoid using a string constant for the format control string given to
+ // sscanf, as this can cause hard to debug crashes on OS X. See here for more
+ // info:
+ //
+ // http://developer.apple.com/library/mac/#DOCUMENTATION/DeveloperTools/gcc-4.0.1/gcc/Incompatibilities.html
+ char format[] = "%lf";
+
+ if (length <= bufferSize) {
+ Char buffer[bufferSize + 1];
+ memcpy(buffer, token.start_, length);
+ buffer[length] = 0;
+ count = sscanf(buffer, format, &value);
+ } else {
+ std::string buffer(token.start_, token.end_);
+ count = sscanf(buffer.c_str(), format, &value);
+ }
+
+ if (count != 1)
+ return addError("'" + std::string(token.start_, token.end_) +
+ "' is not a number.",
+ token);
+ decoded = value;
+ return true;
+}
+
+bool Reader::decodeString(Token& token) {
+ std::string decoded;
+ if (!decodeString(token, decoded))
+ return false;
+ currentValue() = decoded;
+ currentValue().setOffsetStart(token.start_ - begin_);
+ currentValue().setOffsetLimit(token.end_ - begin_);
+ return true;
+}
+
+bool Reader::decodeString(Token& token, std::string& decoded) {
+ decoded.reserve(token.end_ - token.start_ - 2);
+ Location current = token.start_ + 1; // skip '"'
+ Location end = token.end_ - 1; // do not include '"'
+ while (current != end) {
+ Char c = *current++;
+ if (c == '"')
+ break;
+ else if (c == '\\') {
+ if (current == end)
+ return addError("Empty escape sequence in string", token, current);
+ Char escape = *current++;
+ switch (escape) {
+ case '"':
+ decoded += '"';
+ break;
+ case '/':
+ decoded += '/';
+ break;
+ case '\\':
+ decoded += '\\';
+ break;
+ case 'b':
+ decoded += '\b';
+ break;
+ case 'f':
+ decoded += '\f';
+ break;
+ case 'n':
+ decoded += '\n';
+ break;
+ case 'r':
+ decoded += '\r';
+ break;
+ case 't':
+ decoded += '\t';
+ break;
+ case 'u': {
+ unsigned int unicode;
+ if (!decodeUnicodeCodePoint(token, current, end, unicode))
+ return false;
+ decoded += codePointToUTF8(unicode);
+ } break;
+ default:
+ return addError("Bad escape sequence in string", token, current);
+ }
+ } else {
+ decoded += c;
+ }
+ }
+ return true;
+}
+
+bool Reader::decodeUnicodeCodePoint(Token& token,
+ Location& current,
+ Location end,
+ unsigned int& unicode) {
+
+ if (!decodeUnicodeEscapeSequence(token, current, end, unicode))
+ return false;
+ if (unicode >= 0xD800 && unicode <= 0xDBFF) {
+ // surrogate pairs
+ if (end - current < 6)
+ return addError(
+ "additional six characters expected to parse unicode surrogate pair.",
+ token,
+ current);
+ unsigned int surrogatePair;
+ if (*(current++) == '\\' && *(current++) == 'u') {
+ if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) {
+ unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF);
+ } else
+ return false;
+ } else
+ return addError("expecting another \\u token to begin the second half of "
+ "a unicode surrogate pair",
+ token,
+ current);
+ }
+ return true;
+}
+
+bool Reader::decodeUnicodeEscapeSequence(Token& token,
+ Location& current,
+ Location end,
+ unsigned int& unicode) {
+ if (end - current < 4)
+ return addError(
+ "Bad unicode escape sequence in string: four digits expected.",
+ token,
+ current);
+ unicode = 0;
+ for (int index = 0; index < 4; ++index) {
+ Char c = *current++;
+ unicode *= 16;
+ if (c >= '0' && c <= '9')
+ unicode += c - '0';
+ else if (c >= 'a' && c <= 'f')
+ unicode += c - 'a' + 10;
+ else if (c >= 'A' && c <= 'F')
+ unicode += c - 'A' + 10;
+ else
+ return addError(
+ "Bad unicode escape sequence in string: hexadecimal digit expected.",
+ token,
+ current);
+ }
+ return true;
+}
+
+bool
+Reader::addError(const std::string& message, Token& token, Location extra) {
+ ErrorInfo info;
+ info.token_ = token;
+ info.message_ = message;
+ info.extra_ = extra;
+ errors_.push_back(info);
+ return false;
+}
+
+bool Reader::recoverFromError(TokenType skipUntilToken) {
+ int errorCount = int(errors_.size());
+ Token skip;
+ for (;;) {
+ if (!readToken(skip))
+ errors_.resize(errorCount); // discard errors caused by recovery
+ if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream)
+ break;
+ }
+ errors_.resize(errorCount);
+ return false;
+}
+
+bool Reader::addErrorAndRecover(const std::string& message,
+ Token& token,
+ TokenType skipUntilToken) {
+ addError(message, token);
+ return recoverFromError(skipUntilToken);
+}
+
+Value& Reader::currentValue() { return *(nodes_.top()); }
+
+Reader::Char Reader::getNextChar() {
+ if (current_ == end_)
+ return 0;
+ return *current_++;
+}
+
+void Reader::getLocationLineAndColumn(Location location,
+ int& line,
+ int& column) const {
+ Location current = begin_;
+ Location lastLineStart = current;
+ line = 0;
+ while (current < location && current != end_) {
+ Char c = *current++;
+ if (c == '\r') {
+ if (*current == '\n')
+ ++current;
+ lastLineStart = current;
+ ++line;
+ } else if (c == '\n') {
+ lastLineStart = current;
+ ++line;
+ }
+ }
+ // column & line start at 1
+ column = int(location - lastLineStart) + 1;
+ ++line;
+}
+
+std::string Reader::getLocationLineAndColumn(Location location) const {
+ int line, column;
+ getLocationLineAndColumn(location, line, column);
+ char buffer[18 + 16 + 16 + 1];
+#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__)
+#if defined(WINCE)
+ _snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column);
+#else
+ sprintf_s(buffer, sizeof(buffer), "Line %d, Column %d", line, column);
+#endif
+#else
+ snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column);
+#endif
+ return buffer;
+}
+
+// Deprecated. Preserved for backward compatibility
+std::string Reader::getFormatedErrorMessages() const {
+ return getFormattedErrorMessages();
+}
+
+std::string Reader::getFormattedErrorMessages() const {
+ std::string formattedMessage;
+ for (Errors::const_iterator itError = errors_.begin();
+ itError != errors_.end();
+ ++itError) {
+ const ErrorInfo& error = *itError;
+ formattedMessage +=
+ "* " + getLocationLineAndColumn(error.token_.start_) + "\n";
+ formattedMessage += " " + error.message_ + "\n";
+ if (error.extra_)
+ formattedMessage +=
+ "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n";
+ }
+ return formattedMessage;
+}
+
+std::vector<Reader::StructuredError> Reader::getStructuredErrors() const {
+ std::vector<Reader::StructuredError> allErrors;
+ for (Errors::const_iterator itError = errors_.begin();
+ itError != errors_.end();
+ ++itError) {
+ const ErrorInfo& error = *itError;
+ Reader::StructuredError structured;
+ structured.offset_start = error.token_.start_ - begin_;
+ structured.offset_limit = error.token_.end_ - begin_;
+ structured.message = error.message_;
+ allErrors.push_back(structured);
+ }
+ return allErrors;
+}
+
+bool Reader::pushError(const Value& value, const std::string& message) {
+ size_t length = end_ - begin_;
+ if(value.getOffsetStart() > length
+ || value.getOffsetLimit() > length)
+ return false;
+ Token token;
+ token.type_ = tokenError;
+ token.start_ = begin_ + value.getOffsetStart();
+ token.end_ = end_ + value.getOffsetLimit();
+ ErrorInfo info;
+ info.token_ = token;
+ info.message_ = message;
+ info.extra_ = 0;
+ errors_.push_back(info);
+ return true;
+}
+
+bool Reader::pushError(const Value& value, const std::string& message, const Value& extra) {
+ size_t length = end_ - begin_;
+ if(value.getOffsetStart() > length
+ || value.getOffsetLimit() > length
+ || extra.getOffsetLimit() > length)
+ return false;
+ Token token;
+ token.type_ = tokenError;
+ token.start_ = begin_ + value.getOffsetStart();
+ token.end_ = begin_ + value.getOffsetLimit();
+ ErrorInfo info;
+ info.token_ = token;
+ info.message_ = message;
+ info.extra_ = begin_ + extra.getOffsetStart();
+ errors_.push_back(info);
+ return true;
+}
+
+bool Reader::good() const {
+ return !errors_.size();
+}
+
+std::istream& operator>>(std::istream& sin, Value& root) {
+ Json::Reader reader;
+ bool ok = reader.parse(sin, root, true);
+ if (!ok) {
+ fprintf(stderr,
+ "Error from reader: %s",
+ reader.getFormattedErrorMessages().c_str());
+
+ JSON_FAIL_MESSAGE("reader error");
+ }
+ return sin;
+}
+
+} // namespace Json
diff --git a/Utilities/cmjsoncpp/src/lib_json/json_tool.h b/Utilities/cmjsoncpp/src/lib_json/json_tool.h
new file mode 100644
index 000000000..f9b61c38c
--- /dev/null
+++ b/Utilities/cmjsoncpp/src/lib_json/json_tool.h
@@ -0,0 +1,87 @@
+// Copyright 2007-2010 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#ifndef LIB_JSONCPP_JSON_TOOL_H_INCLUDED
+#define LIB_JSONCPP_JSON_TOOL_H_INCLUDED
+
+/* This header provides common string manipulation support, such as UTF-8,
+ * portable conversion from/to string...
+ *
+ * It is an internal header that must not be exposed.
+ */
+
+namespace Json {
+
+/// Converts a unicode code-point to UTF-8.
+static inline std::string codePointToUTF8(unsigned int cp) {
+ std::string result;
+
+ // based on description from http://en.wikipedia.org/wiki/UTF-8
+
+ if (cp <= 0x7f) {
+ result.resize(1);
+ result[0] = static_cast<char>(cp);
+ } else if (cp <= 0x7FF) {
+ result.resize(2);
+ result[1] = static_cast<char>(0x80 | (0x3f & cp));
+ result[0] = static_cast<char>(0xC0 | (0x1f & (cp >> 6)));
+ } else if (cp <= 0xFFFF) {
+ result.resize(3);
+ result[2] = static_cast<char>(0x80 | (0x3f & cp));
+ result[1] = 0x80 | static_cast<char>((0x3f & (cp >> 6)));
+ result[0] = 0xE0 | static_cast<char>((0xf & (cp >> 12)));
+ } else if (cp <= 0x10FFFF) {
+ result.resize(4);
+ result[3] = static_cast<char>(0x80 | (0x3f & cp));
+ result[2] = static_cast<char>(0x80 | (0x3f & (cp >> 6)));
+ result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 12)));
+ result[0] = static_cast<char>(0xF0 | (0x7 & (cp >> 18)));
+ }
+
+ return result;
+}
+
+/// Returns true if ch is a control character (in range [0,32[).
+static inline bool isControlCharacter(char ch) { return ch > 0 && ch <= 0x1F; }
+
+enum {
+ /// Constant that specify the size of the buffer that must be passed to
+ /// uintToString.
+ uintToStringBufferSize = 3 * sizeof(LargestUInt) + 1
+};
+
+// Defines a char buffer for use with uintToString().
+typedef char UIntToStringBuffer[uintToStringBufferSize];
+
+/** Converts an unsigned integer to string.
+ * @param value Unsigned interger to convert to string
+ * @param current Input/Output string buffer.
+ * Must have at least uintToStringBufferSize chars free.
+ */
+static inline void uintToString(LargestUInt value, char*& current) {
+ *--current = 0;
+ do {
+ *--current = char(value % 10) + '0';
+ value /= 10;
+ } while (value != 0);
+}
+
+/** Change ',' to '.' everywhere in buffer.
+ *
+ * We had a sophisticated way, but it did not work in WinCE.
+ * @see https://github.com/open-source-parsers/jsoncpp/pull/9
+ */
+static inline void fixNumericLocale(char* begin, char* end) {
+ while (begin < end) {
+ if (*begin == ',') {
+ *begin = '.';
+ }
+ ++begin;
+ }
+}
+
+} // namespace Json {
+
+#endif // LIB_JSONCPP_JSON_TOOL_H_INCLUDED
diff --git a/Utilities/cmjsoncpp/src/lib_json/json_value.cpp b/Utilities/cmjsoncpp/src/lib_json/json_value.cpp
new file mode 100644
index 000000000..478afe102
--- /dev/null
+++ b/Utilities/cmjsoncpp/src/lib_json/json_value.cpp
@@ -0,0 +1,1482 @@
+// Copyright 2011 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#if !defined(JSON_IS_AMALGAMATION)
+#include <json/assertions.h>
+#include <json/value.h>
+#include <json/writer.h>
+#ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
+#include "json_batchallocator.h"
+#endif // #ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
+#endif // if !defined(JSON_IS_AMALGAMATION)
+#include <math.h>
+#include <sstream>
+#include <utility>
+#include <string.h>
+#include <assert.h>
+#ifdef JSON_USE_CPPTL
+#include <cpptl/conststring.h>
+#endif
+#include <cstddef> // size_t
+
+#define JSON_ASSERT_UNREACHABLE assert(false)
+
+namespace Json {
+
+// This is a walkaround to avoid the static initialization of Value::null.
+// kNull must be word-aligned to avoid crashing on ARM. We use an alignment of
+// 8 (instead of 4) as a bit of future-proofing.
+#if defined(__ARMEL__)
+#define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
+#else
+#define ALIGNAS(byte_alignment)
+#endif
+static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 };
+const unsigned char& kNullRef = kNull[0];
+const Value& Value::null = reinterpret_cast<const Value&>(kNullRef);
+
+const Int Value::minInt = Int(~(UInt(-1) / 2));
+const Int Value::maxInt = Int(UInt(-1) / 2);
+const UInt Value::maxUInt = UInt(-1);
+#if defined(JSON_HAS_INT64)
+const Int64 Value::minInt64 = Int64(~(UInt64(-1) / 2));
+const Int64 Value::maxInt64 = Int64(UInt64(-1) / 2);
+const UInt64 Value::maxUInt64 = UInt64(-1);
+// The constant is hard-coded because some compiler have trouble
+// converting Value::maxUInt64 to a double correctly (AIX/xlC).
+// Assumes that UInt64 is a 64 bits integer.
+static const double maxUInt64AsDouble = 18446744073709551615.0;
+#endif // defined(JSON_HAS_INT64)
+const LargestInt Value::minLargestInt = LargestInt(~(LargestUInt(-1) / 2));
+const LargestInt Value::maxLargestInt = LargestInt(LargestUInt(-1) / 2);
+const LargestUInt Value::maxLargestUInt = LargestUInt(-1);
+
+/// Unknown size marker
+static const unsigned int unknown = (unsigned)-1;
+
+#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
+template <typename T, typename U>
+static inline bool InRange(double d, T min, U max) {
+ return d >= min && d <= max;
+}
+#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
+static inline double integerToDouble(Json::UInt64 value) {
+ return static_cast<double>(Int64(value / 2)) * 2.0 + Int64(value & 1);
+}
+
+template <typename T> static inline double integerToDouble(T value) {
+ return static_cast<double>(value);
+}
+
+template <typename T, typename U>
+static inline bool InRange(double d, T min, U max) {
+ return d >= integerToDouble(min) && d <= integerToDouble(max);
+}
+#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
+
+/** Duplicates the specified string value.
+ * @param value Pointer to the string to duplicate. Must be zero-terminated if
+ * length is "unknown".
+ * @param length Length of the value. if equals to unknown, then it will be
+ * computed using strlen(value).
+ * @return Pointer on the duplicate instance of string.
+ */
+static inline char* duplicateStringValue(const char* value,
+ unsigned int length = unknown) {
+ if (length == unknown)
+ length = (unsigned int)strlen(value);
+
+ // Avoid an integer overflow in the call to malloc below by limiting length
+ // to a sane value.
+ if (length >= (unsigned)Value::maxInt)
+ length = Value::maxInt - 1;
+
+ char* newString = static_cast<char*>(malloc(length + 1));
+ JSON_ASSERT_MESSAGE(newString != 0,
+ "in Json::Value::duplicateStringValue(): "
+ "Failed to allocate string value buffer");
+ memcpy(newString, value, length);
+ newString[length] = 0;
+ return newString;
+}
+
+/** Free the string duplicated by duplicateStringValue().
+ */
+static inline void releaseStringValue(char* value) { free(value); }
+
+} // namespace Json
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// ValueInternals...
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+#if !defined(JSON_IS_AMALGAMATION)
+#ifdef JSON_VALUE_USE_INTERNAL_MAP
+#include "json_internalarray.inl"
+#include "json_internalmap.inl"
+#endif // JSON_VALUE_USE_INTERNAL_MAP
+
+#include "json_valueiterator.inl"
+#endif // if !defined(JSON_IS_AMALGAMATION)
+
+namespace Json {
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// class Value::CommentInfo
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+
+Value::CommentInfo::CommentInfo() : comment_(0) {}
+
+Value::CommentInfo::~CommentInfo() {
+ if (comment_)
+ releaseStringValue(comment_);
+}
+
+void Value::CommentInfo::setComment(const char* text) {
+ if (comment_)
+ releaseStringValue(comment_);
+ JSON_ASSERT(text != 0);
+ JSON_ASSERT_MESSAGE(
+ text[0] == '\0' || text[0] == '/',
+ "in Json::Value::setComment(): Comments must start with /");
+ // It seems that /**/ style comments are acceptable as well.
+ comment_ = duplicateStringValue(text);
+}
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// class Value::CZString
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+
+// Notes: index_ indicates if the string was allocated when
+// a string is stored.
+
+Value::CZString::CZString(ArrayIndex index) : cstr_(0), index_(index) {}
+
+Value::CZString::CZString(const char* cstr, DuplicationPolicy allocate)
+ : cstr_(allocate == duplicate ? duplicateStringValue(cstr) : cstr),
+ index_(allocate) {}
+
+Value::CZString::CZString(const CZString& other)
+ : cstr_(other.index_ != noDuplication && other.cstr_ != 0
+ ? duplicateStringValue(other.cstr_)
+ : other.cstr_),
+ index_(other.cstr_
+ ? static_cast<ArrayIndex>(other.index_ == noDuplication
+ ? noDuplication : duplicate)
+ : other.index_) {}
+
+Value::CZString::~CZString() {
+ if (cstr_ && index_ == duplicate)
+ releaseStringValue(const_cast<char*>(cstr_));
+}
+
+void Value::CZString::swap(CZString& other) {
+ std::swap(cstr_, other.cstr_);
+ std::swap(index_, other.index_);
+}
+
+Value::CZString& Value::CZString::operator=(CZString other) {
+ swap(other);
+ return *this;
+}
+
+bool Value::CZString::operator<(const CZString& other) const {
+ if (cstr_) {
+ assert(other.cstr_);
+ return strcmp(cstr_, other.cstr_) < 0;
+ }
+ return index_ < other.index_;
+}
+
+bool Value::CZString::operator==(const CZString& other) const {
+ if (cstr_) {
+ assert(other.cstr_);
+ return strcmp(cstr_, other.cstr_) == 0;
+ }
+ return index_ == other.index_;
+}
+
+ArrayIndex Value::CZString::index() const { return index_; }
+
+const char* Value::CZString::c_str() const { return cstr_; }
+
+bool Value::CZString::isStaticString() const { return index_ == noDuplication; }
+
+#endif // ifndef JSON_VALUE_USE_INTERNAL_MAP
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// class Value::Value
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+
+/*! \internal Default constructor initialization must be equivalent to:
+ * memset( this, 0, sizeof(Value) )
+ * This optimization is used in ValueInternalMap fast allocator.
+ */
+Value::Value(ValueType type) {
+ initBasic(type);
+ switch (type) {
+ case nullValue:
+ break;
+ case intValue:
+ case uintValue:
+ value_.int_ = 0;
+ break;
+ case realValue:
+ value_.real_ = 0.0;
+ break;
+ case stringValue:
+ value_.string_ = 0;
+ break;
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ case arrayValue:
+ case objectValue:
+ value_.map_ = new ObjectValues();
+ break;
+#else
+ case arrayValue:
+ value_.array_ = arrayAllocator()->newArray();
+ break;
+ case objectValue:
+ value_.map_ = mapAllocator()->newMap();
+ break;
+#endif
+ case booleanValue:
+ value_.bool_ = false;
+ break;
+ default:
+ JSON_ASSERT_UNREACHABLE;
+ }
+}
+
+Value::Value(Int value) {
+ initBasic(intValue);
+ value_.int_ = value;
+}
+
+Value::Value(UInt value) {
+ initBasic(uintValue);
+ value_.uint_ = value;
+}
+#if defined(JSON_HAS_INT64)
+Value::Value(Int64 value) {
+ initBasic(intValue);
+ value_.int_ = value;
+}
+Value::Value(UInt64 value) {
+ initBasic(uintValue);
+ value_.uint_ = value;
+}
+#endif // defined(JSON_HAS_INT64)
+
+Value::Value(double value) {
+ initBasic(realValue);
+ value_.real_ = value;
+}
+
+Value::Value(const char* value) {
+ initBasic(stringValue, true);
+ value_.string_ = duplicateStringValue(value);
+}
+
+Value::Value(const char* beginValue, const char* endValue) {
+ initBasic(stringValue, true);
+ value_.string_ =
+ duplicateStringValue(beginValue, (unsigned int)(endValue - beginValue));
+}
+
+Value::Value(const std::string& value) {
+ initBasic(stringValue, true);
+ value_.string_ =
+ duplicateStringValue(value.c_str(), (unsigned int)value.length());
+}
+
+Value::Value(const StaticString& value) {
+ initBasic(stringValue);
+ value_.string_ = const_cast<char*>(value.c_str());
+}
+
+#ifdef JSON_USE_CPPTL
+Value::Value(const CppTL::ConstString& value) {
+ initBasic(stringValue, true);
+ value_.string_ = duplicateStringValue(value, value.length());
+}
+#endif
+
+Value::Value(bool value) {
+ initBasic(booleanValue);
+ value_.bool_ = value;
+}
+
+Value::Value(const Value& other)
+ : type_(other.type_), allocated_(false)
+#ifdef JSON_VALUE_USE_INTERNAL_MAP
+ ,
+ itemIsUsed_(0)
+#endif
+ ,
+ comments_(0), start_(other.start_), limit_(other.limit_) {
+ switch (type_) {
+ case nullValue:
+ case intValue:
+ case uintValue:
+ case realValue:
+ case booleanValue:
+ value_ = other.value_;
+ break;
+ case stringValue:
+ if (other.value_.string_) {
+ value_.string_ = duplicateStringValue(other.value_.string_);
+ allocated_ = true;
+ } else {
+ value_.string_ = 0;
+ allocated_ = false;
+ }
+ break;
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ case arrayValue:
+ case objectValue:
+ value_.map_ = new ObjectValues(*other.value_.map_);
+ break;
+#else
+ case arrayValue:
+ value_.array_ = arrayAllocator()->newArrayCopy(*other.value_.array_);
+ break;
+ case objectValue:
+ value_.map_ = mapAllocator()->newMapCopy(*other.value_.map_);
+ break;
+#endif
+ default:
+ JSON_ASSERT_UNREACHABLE;
+ }
+ if (other.comments_) {
+ comments_ = new CommentInfo[numberOfCommentPlacement];
+ for (int comment = 0; comment < numberOfCommentPlacement; ++comment) {
+ const CommentInfo& otherComment = other.comments_[comment];
+ if (otherComment.comment_)
+ comments_[comment].setComment(otherComment.comment_);
+ }
+ }
+}
+
+Value::~Value() {
+ switch (type_) {
+ case nullValue:
+ case intValue:
+ case uintValue:
+ case realValue:
+ case booleanValue:
+ break;
+ case stringValue:
+ if (allocated_)
+ releaseStringValue(value_.string_);
+ break;
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ case arrayValue:
+ case objectValue:
+ delete value_.map_;
+ break;
+#else
+ case arrayValue:
+ arrayAllocator()->destructArray(value_.array_);
+ break;
+ case objectValue:
+ mapAllocator()->destructMap(value_.map_);
+ break;
+#endif
+ default:
+ JSON_ASSERT_UNREACHABLE;
+ }
+
+ if (comments_)
+ delete[] comments_;
+}
+
+Value& Value::operator=(Value other) {
+ swap(other);
+ return *this;
+}
+
+void Value::swap(Value& other) {
+ ValueType temp = type_;
+ type_ = other.type_;
+ other.type_ = temp;
+ std::swap(value_, other.value_);
+ int temp2 = allocated_;
+ allocated_ = other.allocated_;
+ other.allocated_ = temp2;
+ std::swap(start_, other.start_);
+ std::swap(limit_, other.limit_);
+}
+
+ValueType Value::type() const { return type_; }
+
+int Value::compare(const Value& other) const {
+ if (*this < other)
+ return -1;
+ if (*this > other)
+ return 1;
+ return 0;
+}
+
+bool Value::operator<(const Value& other) const {
+ int typeDelta = type_ - other.type_;
+ if (typeDelta)
+ return typeDelta < 0 ? true : false;
+ switch (type_) {
+ case nullValue:
+ return false;
+ case intValue:
+ return value_.int_ < other.value_.int_;
+ case uintValue:
+ return value_.uint_ < other.value_.uint_;
+ case realValue:
+ return value_.real_ < other.value_.real_;
+ case booleanValue:
+ return value_.bool_ < other.value_.bool_;
+ case stringValue:
+ return (value_.string_ == 0 && other.value_.string_) ||
+ (other.value_.string_ && value_.string_ &&
+ strcmp(value_.string_, other.value_.string_) < 0);
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ case arrayValue:
+ case objectValue: {
+ int delta = int(value_.map_->size() - other.value_.map_->size());
+ if (delta)
+ return delta < 0;
+ return (*value_.map_) < (*other.value_.map_);
+ }
+#else
+ case arrayValue:
+ return value_.array_->compare(*(other.value_.array_)) < 0;
+ case objectValue:
+ return value_.map_->compare(*(other.value_.map_)) < 0;
+#endif
+ default:
+ JSON_ASSERT_UNREACHABLE;
+ }
+ return false; // unreachable
+}
+
+bool Value::operator<=(const Value& other) const { return !(other < *this); }
+
+bool Value::operator>=(const Value& other) const { return !(*this < other); }
+
+bool Value::operator>(const Value& other) const { return other < *this; }
+
+bool Value::operator==(const Value& other) const {
+ // if ( type_ != other.type_ )
+ // GCC 2.95.3 says:
+ // attempt to take address of bit-field structure member `Json::Value::type_'
+ // Beats me, but a temp solves the problem.
+ int temp = other.type_;
+ if (type_ != temp)
+ return false;
+ switch (type_) {
+ case nullValue:
+ return true;
+ case intValue:
+ return value_.int_ == other.value_.int_;
+ case uintValue:
+ return value_.uint_ == other.value_.uint_;
+ case realValue:
+ return value_.real_ == other.value_.real_;
+ case booleanValue:
+ return value_.bool_ == other.value_.bool_;
+ case stringValue:
+ return (value_.string_ == other.value_.string_) ||
+ (other.value_.string_ && value_.string_ &&
+ strcmp(value_.string_, other.value_.string_) == 0);
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ case arrayValue:
+ case objectValue:
+ return value_.map_->size() == other.value_.map_->size() &&
+ (*value_.map_) == (*other.value_.map_);
+#else
+ case arrayValue:
+ return value_.array_->compare(*(other.value_.array_)) == 0;
+ case objectValue:
+ return value_.map_->compare(*(other.value_.map_)) == 0;
+#endif
+ default:
+ JSON_ASSERT_UNREACHABLE;
+ }
+ return false; // unreachable
+}
+
+bool Value::operator!=(const Value& other) const { return !(*this == other); }
+
+const char* Value::asCString() const {
+ JSON_ASSERT_MESSAGE(type_ == stringValue,
+ "in Json::Value::asCString(): requires stringValue");
+ return value_.string_;
+}
+
+std::string Value::asString() const {
+ switch (type_) {
+ case nullValue:
+ return "";
+ case stringValue:
+ return value_.string_ ? value_.string_ : "";
+ case booleanValue:
+ return value_.bool_ ? "true" : "false";
+ case intValue:
+ return valueToString(value_.int_);
+ case uintValue:
+ return valueToString(value_.uint_);
+ case realValue:
+ return valueToString(value_.real_);
+ default:
+ JSON_FAIL_MESSAGE("Type is not convertible to string");
+ }
+}
+
+#ifdef JSON_USE_CPPTL
+CppTL::ConstString Value::asConstString() const {
+ return CppTL::ConstString(asString().c_str());
+}
+#endif
+
+Value::Int Value::asInt() const {
+ switch (type_) {
+ case intValue:
+ JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range");
+ return Int(value_.int_);
+ case uintValue:
+ JSON_ASSERT_MESSAGE(isInt(), "LargestUInt out of Int range");
+ return Int(value_.uint_);
+ case realValue:
+ JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt),
+ "double out of Int range");
+ return Int(value_.real_);
+ case nullValue:
+ return 0;
+ case booleanValue:
+ return value_.bool_ ? 1 : 0;
+ default:
+ break;
+ }
+ JSON_FAIL_MESSAGE("Value is not convertible to Int.");
+}
+
+Value::UInt Value::asUInt() const {
+ switch (type_) {
+ case intValue:
+ JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range");
+ return UInt(value_.int_);
+ case uintValue:
+ JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range");
+ return UInt(value_.uint_);
+ case realValue:
+ JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt),
+ "double out of UInt range");
+ return UInt(value_.real_);
+ case nullValue:
+ return 0;
+ case booleanValue:
+ return value_.bool_ ? 1 : 0;
+ default:
+ break;
+ }
+ JSON_FAIL_MESSAGE("Value is not convertible to UInt.");
+}
+
+#if defined(JSON_HAS_INT64)
+
+Value::Int64 Value::asInt64() const {
+ switch (type_) {
+ case intValue:
+ return Int64(value_.int_);
+ case uintValue:
+ JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range");
+ return Int64(value_.uint_);
+ case realValue:
+ JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64),
+ "double out of Int64 range");
+ return Int64(value_.real_);
+ case nullValue:
+ return 0;
+ case booleanValue:
+ return value_.bool_ ? 1 : 0;
+ default:
+ break;
+ }
+ JSON_FAIL_MESSAGE("Value is not convertible to Int64.");
+}
+
+Value::UInt64 Value::asUInt64() const {
+ switch (type_) {
+ case intValue:
+ JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range");
+ return UInt64(value_.int_);
+ case uintValue:
+ return UInt64(value_.uint_);
+ case realValue:
+ JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64),
+ "double out of UInt64 range");
+ return UInt64(value_.real_);
+ case nullValue:
+ return 0;
+ case booleanValue:
+ return value_.bool_ ? 1 : 0;
+ default:
+ break;
+ }
+ JSON_FAIL_MESSAGE("Value is not convertible to UInt64.");
+}
+#endif // if defined(JSON_HAS_INT64)
+
+LargestInt Value::asLargestInt() const {
+#if defined(JSON_NO_INT64)
+ return asInt();
+#else
+ return asInt64();
+#endif
+}
+
+LargestUInt Value::asLargestUInt() const {
+#if defined(JSON_NO_INT64)
+ return asUInt();
+#else
+ return asUInt64();
+#endif
+}
+
+double Value::asDouble() const {
+ switch (type_) {
+ case intValue:
+ return static_cast<double>(value_.int_);
+ case uintValue:
+#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
+ return static_cast<double>(value_.uint_);
+#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
+ return integerToDouble(value_.uint_);
+#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
+ case realValue:
+ return value_.real_;
+ case nullValue:
+ return 0.0;
+ case booleanValue:
+ return value_.bool_ ? 1.0 : 0.0;
+ default:
+ break;
+ }
+ JSON_FAIL_MESSAGE("Value is not convertible to double.");
+}
+
+float Value::asFloat() const {
+ switch (type_) {
+ case intValue:
+ return static_cast<float>(value_.int_);
+ case uintValue:
+#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
+ return static_cast<float>(value_.uint_);
+#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
+ return integerToDouble(value_.uint_);
+#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
+ case realValue:
+ return static_cast<float>(value_.real_);
+ case nullValue:
+ return 0.0;
+ case booleanValue:
+ return value_.bool_ ? 1.0f : 0.0f;
+ default:
+ break;
+ }
+ JSON_FAIL_MESSAGE("Value is not convertible to float.");
+}
+
+bool Value::asBool() const {
+ switch (type_) {
+ case booleanValue:
+ return value_.bool_;
+ case nullValue:
+ return false;
+ case intValue:
+ return value_.int_ ? true : false;
+ case uintValue:
+ return value_.uint_ ? true : false;
+ case realValue:
+ return value_.real_ ? true : false;
+ default:
+ break;
+ }
+ JSON_FAIL_MESSAGE("Value is not convertible to bool.");
+}
+
+bool Value::isConvertibleTo(ValueType other) const {
+ switch (other) {
+ case nullValue:
+ return (isNumeric() && asDouble() == 0.0) ||
+ (type_ == booleanValue && value_.bool_ == false) ||
+ (type_ == stringValue && asString() == "") ||
+ (type_ == arrayValue && value_.map_->size() == 0) ||
+ (type_ == objectValue && value_.map_->size() == 0) ||
+ type_ == nullValue;
+ case intValue:
+ return isInt() ||
+ (type_ == realValue && InRange(value_.real_, minInt, maxInt)) ||
+ type_ == booleanValue || type_ == nullValue;
+ case uintValue:
+ return isUInt() ||
+ (type_ == realValue && InRange(value_.real_, 0, maxUInt)) ||
+ type_ == booleanValue || type_ == nullValue;
+ case realValue:
+ return isNumeric() || type_ == booleanValue || type_ == nullValue;
+ case booleanValue:
+ return isNumeric() || type_ == booleanValue || type_ == nullValue;
+ case stringValue:
+ return isNumeric() || type_ == booleanValue || type_ == stringValue ||
+ type_ == nullValue;
+ case arrayValue:
+ return type_ == arrayValue || type_ == nullValue;
+ case objectValue:
+ return type_ == objectValue || type_ == nullValue;
+ }
+ JSON_ASSERT_UNREACHABLE;
+ return false;
+}
+
+/// Number of values in array or object
+ArrayIndex Value::size() const {
+ switch (type_) {
+ case nullValue:
+ case intValue:
+ case uintValue:
+ case realValue:
+ case booleanValue:
+ case stringValue:
+ return 0;
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ case arrayValue: // size of the array is highest index + 1
+ if (!value_.map_->empty()) {
+ ObjectValues::const_iterator itLast = value_.map_->end();
+ --itLast;
+ return (*itLast).first.index() + 1;
+ }
+ return 0;
+ case objectValue:
+ return ArrayIndex(value_.map_->size());
+#else
+ case arrayValue:
+ return Int(value_.array_->size());
+ case objectValue:
+ return Int(value_.map_->size());
+#endif
+ }
+ JSON_ASSERT_UNREACHABLE;
+ return 0; // unreachable;
+}
+
+bool Value::empty() const {
+ if (isNull() || isArray() || isObject())
+ return size() == 0u;
+ else
+ return false;
+}
+
+bool Value::operator!() const { return isNull(); }
+
+void Value::clear() {
+ JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue ||
+ type_ == objectValue,
+ "in Json::Value::clear(): requires complex value");
+ start_ = 0;
+ limit_ = 0;
+ switch (type_) {
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ case arrayValue:
+ case objectValue:
+ value_.map_->clear();
+ break;
+#else
+ case arrayValue:
+ value_.array_->clear();
+ break;
+ case objectValue:
+ value_.map_->clear();
+ break;
+#endif
+ default:
+ break;
+ }
+}
+
+void Value::resize(ArrayIndex newSize) {
+ JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue,
+ "in Json::Value::resize(): requires arrayValue");
+ if (type_ == nullValue)
+ *this = Value(arrayValue);
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ ArrayIndex oldSize = size();
+ if (newSize == 0)
+ clear();
+ else if (newSize > oldSize)
+ (*this)[newSize - 1];
+ else {
+ for (ArrayIndex index = newSize; index < oldSize; ++index) {
+ value_.map_->erase(index);
+ }
+ assert(size() == newSize);
+ }
+#else
+ value_.array_->resize(newSize);
+#endif
+}
+
+Value& Value::operator[](ArrayIndex index) {
+ JSON_ASSERT_MESSAGE(
+ type_ == nullValue || type_ == arrayValue,
+ "in Json::Value::operator[](ArrayIndex): requires arrayValue");
+ if (type_ == nullValue)
+ *this = Value(arrayValue);
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ CZString key(index);
+ ObjectValues::iterator it = value_.map_->lower_bound(key);
+ if (it != value_.map_->end() && (*it).first == key)
+ return (*it).second;
+
+ ObjectValues::value_type defaultValue(key, null);
+ it = value_.map_->insert(it, defaultValue);
+ return (*it).second;
+#else
+ return value_.array_->resolveReference(index);
+#endif
+}
+
+Value& Value::operator[](int index) {
+ JSON_ASSERT_MESSAGE(
+ index >= 0,
+ "in Json::Value::operator[](int index): index cannot be negative");
+ return (*this)[ArrayIndex(index)];
+}
+
+const Value& Value::operator[](ArrayIndex index) const {
+ JSON_ASSERT_MESSAGE(
+ type_ == nullValue || type_ == arrayValue,
+ "in Json::Value::operator[](ArrayIndex)const: requires arrayValue");
+ if (type_ == nullValue)
+ return null;
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ CZString key(index);
+ ObjectValues::const_iterator it = value_.map_->find(key);
+ if (it == value_.map_->end())
+ return null;
+ return (*it).second;
+#else
+ Value* value = value_.array_->find(index);
+ return value ? *value : null;
+#endif
+}
+
+const Value& Value::operator[](int index) const {
+ JSON_ASSERT_MESSAGE(
+ index >= 0,
+ "in Json::Value::operator[](int index) const: index cannot be negative");
+ return (*this)[ArrayIndex(index)];
+}
+
+Value& Value::operator[](const char* key) {
+ return resolveReference(key, false);
+}
+
+void Value::initBasic(ValueType type, bool allocated) {
+ type_ = type;
+ allocated_ = allocated;
+#ifdef JSON_VALUE_USE_INTERNAL_MAP
+ itemIsUsed_ = 0;
+#endif
+ comments_ = 0;
+ start_ = 0;
+ limit_ = 0;
+}
+
+Value& Value::resolveReference(const char* key, bool isStatic) {
+ JSON_ASSERT_MESSAGE(
+ type_ == nullValue || type_ == objectValue,
+ "in Json::Value::resolveReference(): requires objectValue");
+ if (type_ == nullValue)
+ *this = Value(objectValue);
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ CZString actualKey(
+ key, isStatic ? CZString::noDuplication : CZString::duplicateOnCopy);
+ ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
+ if (it != value_.map_->end() && (*it).first == actualKey)
+ return (*it).second;
+
+ ObjectValues::value_type defaultValue(actualKey, null);
+ it = value_.map_->insert(it, defaultValue);
+ Value& value = (*it).second;
+ return value;
+#else
+ return value_.map_->resolveReference(key, isStatic);
+#endif
+}
+
+Value Value::get(ArrayIndex index, const Value& defaultValue) const {
+ const Value* value = &((*this)[index]);
+ return value == &null ? defaultValue : *value;
+}
+
+bool Value::isValidIndex(ArrayIndex index) const { return index < size(); }
+
+const Value& Value::operator[](const char* key) const {
+ JSON_ASSERT_MESSAGE(
+ type_ == nullValue || type_ == objectValue,
+ "in Json::Value::operator[](char const*)const: requires objectValue");
+ if (type_ == nullValue)
+ return null;
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ CZString actualKey(key, CZString::noDuplication);
+ ObjectValues::const_iterator it = value_.map_->find(actualKey);
+ if (it == value_.map_->end())
+ return null;
+ return (*it).second;
+#else
+ const Value* value = value_.map_->find(key);
+ return value ? *value : null;
+#endif
+}
+
+Value& Value::operator[](const std::string& key) {
+ return (*this)[key.c_str()];
+}
+
+const Value& Value::operator[](const std::string& key) const {
+ return (*this)[key.c_str()];
+}
+
+Value& Value::operator[](const StaticString& key) {
+ return resolveReference(key, true);
+}
+
+#ifdef JSON_USE_CPPTL
+Value& Value::operator[](const CppTL::ConstString& key) {
+ return (*this)[key.c_str()];
+}
+
+const Value& Value::operator[](const CppTL::ConstString& key) const {
+ return (*this)[key.c_str()];
+}
+#endif
+
+Value& Value::append(const Value& value) { return (*this)[size()] = value; }
+
+Value Value::get(const char* key, const Value& defaultValue) const {
+ const Value* value = &((*this)[key]);
+ return value == &null ? defaultValue : *value;
+}
+
+Value Value::get(const std::string& key, const Value& defaultValue) const {
+ return get(key.c_str(), defaultValue);
+}
+
+Value Value::removeMember(const char* key) {
+ JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue,
+ "in Json::Value::removeMember(): requires objectValue");
+ if (type_ == nullValue)
+ return null;
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ CZString actualKey(key, CZString::noDuplication);
+ ObjectValues::iterator it = value_.map_->find(actualKey);
+ if (it == value_.map_->end())
+ return null;
+ Value old(it->second);
+ value_.map_->erase(it);
+ return old;
+#else
+ Value* value = value_.map_->find(key);
+ if (value) {
+ Value old(*value);
+ value_.map_.remove(key);
+ return old;
+ } else {
+ return null;
+ }
+#endif
+}
+
+Value Value::removeMember(const std::string& key) {
+ return removeMember(key.c_str());
+}
+
+#ifdef JSON_USE_CPPTL
+Value Value::get(const CppTL::ConstString& key,
+ const Value& defaultValue) const {
+ return get(key.c_str(), defaultValue);
+}
+#endif
+
+bool Value::isMember(const char* key) const {
+ const Value* value = &((*this)[key]);
+ return value != &null;
+}
+
+bool Value::isMember(const std::string& key) const {
+ return isMember(key.c_str());
+}
+
+#ifdef JSON_USE_CPPTL
+bool Value::isMember(const CppTL::ConstString& key) const {
+ return isMember(key.c_str());
+}
+#endif
+
+Value::Members Value::getMemberNames() const {
+ JSON_ASSERT_MESSAGE(
+ type_ == nullValue || type_ == objectValue,
+ "in Json::Value::getMemberNames(), value must be objectValue");
+ if (type_ == nullValue)
+ return Value::Members();
+ Members members;
+ members.reserve(value_.map_->size());
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ ObjectValues::const_iterator it = value_.map_->begin();
+ ObjectValues::const_iterator itEnd = value_.map_->end();
+ for (; it != itEnd; ++it)
+ members.push_back(std::string((*it).first.c_str()));
+#else
+ ValueInternalMap::IteratorState it;
+ ValueInternalMap::IteratorState itEnd;
+ value_.map_->makeBeginIterator(it);
+ value_.map_->makeEndIterator(itEnd);
+ for (; !ValueInternalMap::equals(it, itEnd); ValueInternalMap::increment(it))
+ members.push_back(std::string(ValueInternalMap::key(it)));
+#endif
+ return members;
+}
+//
+//# ifdef JSON_USE_CPPTL
+// EnumMemberNames
+// Value::enumMemberNames() const
+//{
+// if ( type_ == objectValue )
+// {
+// return CppTL::Enum::any( CppTL::Enum::transform(
+// CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() ),
+// MemberNamesTransform() ) );
+// }
+// return EnumMemberNames();
+//}
+//
+//
+// EnumValues
+// Value::enumValues() const
+//{
+// if ( type_ == objectValue || type_ == arrayValue )
+// return CppTL::Enum::anyValues( *(value_.map_),
+// CppTL::Type<const Value &>() );
+// return EnumValues();
+//}
+//
+//# endif
+
+static bool IsIntegral(double d) {
+ double integral_part;
+ return modf(d, &integral_part) == 0.0;
+}
+
+bool Value::isNull() const { return type_ == nullValue; }
+
+bool Value::isBool() const { return type_ == booleanValue; }
+
+bool Value::isInt() const {
+ switch (type_) {
+ case intValue:
+ return value_.int_ >= minInt && value_.int_ <= maxInt;
+ case uintValue:
+ return value_.uint_ <= UInt(maxInt);
+ case realValue:
+ return value_.real_ >= minInt && value_.real_ <= maxInt &&
+ IsIntegral(value_.real_);
+ default:
+ break;
+ }
+ return false;
+}
+
+bool Value::isUInt() const {
+ switch (type_) {
+ case intValue:
+ return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt);
+ case uintValue:
+ return value_.uint_ <= maxUInt;
+ case realValue:
+ return value_.real_ >= 0 && value_.real_ <= maxUInt &&
+ IsIntegral(value_.real_);
+ default:
+ break;
+ }
+ return false;
+}
+
+bool Value::isInt64() const {
+#if defined(JSON_HAS_INT64)
+ switch (type_) {
+ case intValue:
+ return true;
+ case uintValue:
+ return value_.uint_ <= UInt64(maxInt64);
+ case realValue:
+ // Note that maxInt64 (= 2^63 - 1) is not exactly representable as a
+ // double, so double(maxInt64) will be rounded up to 2^63. Therefore we
+ // require the value to be strictly less than the limit.
+ return value_.real_ >= double(minInt64) &&
+ value_.real_ < double(maxInt64) && IsIntegral(value_.real_);
+ default:
+ break;
+ }
+#endif // JSON_HAS_INT64
+ return false;
+}
+
+bool Value::isUInt64() const {
+#if defined(JSON_HAS_INT64)
+ switch (type_) {
+ case intValue:
+ return value_.int_ >= 0;
+ case uintValue:
+ return true;
+ case realValue:
+ // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a
+ // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we
+ // require the value to be strictly less than the limit.
+ return value_.real_ >= 0 && value_.real_ < maxUInt64AsDouble &&
+ IsIntegral(value_.real_);
+ default:
+ break;
+ }
+#endif // JSON_HAS_INT64
+ return false;
+}
+
+bool Value::isIntegral() const {
+#if defined(JSON_HAS_INT64)
+ return isInt64() || isUInt64();
+#else
+ return isInt() || isUInt();
+#endif
+}
+
+bool Value::isDouble() const { return type_ == realValue || isIntegral(); }
+
+bool Value::isNumeric() const { return isIntegral() || isDouble(); }
+
+bool Value::isString() const { return type_ == stringValue; }
+
+bool Value::isArray() const { return type_ == arrayValue; }
+
+bool Value::isObject() const { return type_ == objectValue; }
+
+void Value::setComment(const char* comment, CommentPlacement placement) {
+ if (!comments_)
+ comments_ = new CommentInfo[numberOfCommentPlacement];
+ comments_[placement].setComment(comment);
+}
+
+void Value::setComment(const std::string& comment, CommentPlacement placement) {
+ setComment(comment.c_str(), placement);
+}
+
+bool Value::hasComment(CommentPlacement placement) const {
+ return comments_ != 0 && comments_[placement].comment_ != 0;
+}
+
+std::string Value::getComment(CommentPlacement placement) const {
+ if (hasComment(placement))
+ return comments_[placement].comment_;
+ return "";
+}
+
+void Value::setOffsetStart(size_t start) { start_ = start; }
+
+void Value::setOffsetLimit(size_t limit) { limit_ = limit; }
+
+size_t Value::getOffsetStart() const { return start_; }
+
+size_t Value::getOffsetLimit() const { return limit_; }
+
+std::string Value::toStyledString() const {
+ StyledWriter writer;
+ return writer.write(*this);
+}
+
+Value::const_iterator Value::begin() const {
+ switch (type_) {
+#ifdef JSON_VALUE_USE_INTERNAL_MAP
+ case arrayValue:
+ if (value_.array_) {
+ ValueInternalArray::IteratorState it;
+ value_.array_->makeBeginIterator(it);
+ return const_iterator(it);
+ }
+ break;
+ case objectValue:
+ if (value_.map_) {
+ ValueInternalMap::IteratorState it;
+ value_.map_->makeBeginIterator(it);
+ return const_iterator(it);
+ }
+ break;
+#else
+ case arrayValue:
+ case objectValue:
+ if (value_.map_)
+ return const_iterator(value_.map_->begin());
+ break;
+#endif
+ default:
+ break;
+ }
+ return const_iterator();
+}
+
+Value::const_iterator Value::end() const {
+ switch (type_) {
+#ifdef JSON_VALUE_USE_INTERNAL_MAP
+ case arrayValue:
+ if (value_.array_) {
+ ValueInternalArray::IteratorState it;
+ value_.array_->makeEndIterator(it);
+ return const_iterator(it);
+ }
+ break;
+ case objectValue:
+ if (value_.map_) {
+ ValueInternalMap::IteratorState it;
+ value_.map_->makeEndIterator(it);
+ return const_iterator(it);
+ }
+ break;
+#else
+ case arrayValue:
+ case objectValue:
+ if (value_.map_)
+ return const_iterator(value_.map_->end());
+ break;
+#endif
+ default:
+ break;
+ }
+ return const_iterator();
+}
+
+Value::iterator Value::begin() {
+ switch (type_) {
+#ifdef JSON_VALUE_USE_INTERNAL_MAP
+ case arrayValue:
+ if (value_.array_) {
+ ValueInternalArray::IteratorState it;
+ value_.array_->makeBeginIterator(it);
+ return iterator(it);
+ }
+ break;
+ case objectValue:
+ if (value_.map_) {
+ ValueInternalMap::IteratorState it;
+ value_.map_->makeBeginIterator(it);
+ return iterator(it);
+ }
+ break;
+#else
+ case arrayValue:
+ case objectValue:
+ if (value_.map_)
+ return iterator(value_.map_->begin());
+ break;
+#endif
+ default:
+ break;
+ }
+ return iterator();
+}
+
+Value::iterator Value::end() {
+ switch (type_) {
+#ifdef JSON_VALUE_USE_INTERNAL_MAP
+ case arrayValue:
+ if (value_.array_) {
+ ValueInternalArray::IteratorState it;
+ value_.array_->makeEndIterator(it);
+ return iterator(it);
+ }
+ break;
+ case objectValue:
+ if (value_.map_) {
+ ValueInternalMap::IteratorState it;
+ value_.map_->makeEndIterator(it);
+ return iterator(it);
+ }
+ break;
+#else
+ case arrayValue:
+ case objectValue:
+ if (value_.map_)
+ return iterator(value_.map_->end());
+ break;
+#endif
+ default:
+ break;
+ }
+ return iterator();
+}
+
+// class PathArgument
+// //////////////////////////////////////////////////////////////////
+
+PathArgument::PathArgument() : key_(), index_(), kind_(kindNone) {}
+
+PathArgument::PathArgument(ArrayIndex index)
+ : key_(), index_(index), kind_(kindIndex) {}
+
+PathArgument::PathArgument(const char* key)
+ : key_(key), index_(), kind_(kindKey) {}
+
+PathArgument::PathArgument(const std::string& key)
+ : key_(key.c_str()), index_(), kind_(kindKey) {}
+
+// class Path
+// //////////////////////////////////////////////////////////////////
+
+Path::Path(const std::string& path,
+ const PathArgument& a1,
+ const PathArgument& a2,
+ const PathArgument& a3,
+ const PathArgument& a4,
+ const PathArgument& a5) {
+ InArgs in;
+ in.push_back(&a1);
+ in.push_back(&a2);
+ in.push_back(&a3);
+ in.push_back(&a4);
+ in.push_back(&a5);
+ makePath(path, in);
+}
+
+void Path::makePath(const std::string& path, const InArgs& in) {
+ const char* current = path.c_str();
+ const char* end = current + path.length();
+ InArgs::const_iterator itInArg = in.begin();
+ while (current != end) {
+ if (*current == '[') {
+ ++current;
+ if (*current == '%')
+ addPathInArg(path, in, itInArg, PathArgument::kindIndex);
+ else {
+ ArrayIndex index = 0;
+ for (; current != end && *current >= '0' && *current <= '9'; ++current)
+ index = index * 10 + ArrayIndex(*current - '0');
+ args_.push_back(index);
+ }
+ if (current == end || *current++ != ']')
+ invalidPath(path, int(current - path.c_str()));
+ } else if (*current == '%') {
+ addPathInArg(path, in, itInArg, PathArgument::kindKey);
+ ++current;
+ } else if (*current == '.') {
+ ++current;
+ } else {
+ const char* beginName = current;
+ while (current != end && !strchr("[.", *current))
+ ++current;
+ args_.push_back(std::string(beginName, current));
+ }
+ }
+}
+
+void Path::addPathInArg(const std::string& /*path*/,
+ const InArgs& in,
+ InArgs::const_iterator& itInArg,
+ PathArgument::Kind kind) {
+ if (itInArg == in.end()) {
+ // Error: missing argument %d
+ } else if ((*itInArg)->kind_ != kind) {
+ // Error: bad argument type
+ } else {
+ args_.push_back(**itInArg);
+ }
+}
+
+void Path::invalidPath(const std::string& /*path*/, int /*location*/) {
+ // Error: invalid path.
+}
+
+const Value& Path::resolve(const Value& root) const {
+ const Value* node = &root;
+ for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
+ const PathArgument& arg = *it;
+ if (arg.kind_ == PathArgument::kindIndex) {
+ if (!node->isArray() || !node->isValidIndex(arg.index_)) {
+ // Error: unable to resolve path (array value expected at position...
+ }
+ node = &((*node)[arg.index_]);
+ } else if (arg.kind_ == PathArgument::kindKey) {
+ if (!node->isObject()) {
+ // Error: unable to resolve path (object value expected at position...)
+ }
+ node = &((*node)[arg.key_]);
+ if (node == &Value::null) {
+ // Error: unable to resolve path (object has no member named '' at
+ // position...)
+ }
+ }
+ }
+ return *node;
+}
+
+Value Path::resolve(const Value& root, const Value& defaultValue) const {
+ const Value* node = &root;
+ for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
+ const PathArgument& arg = *it;
+ if (arg.kind_ == PathArgument::kindIndex) {
+ if (!node->isArray() || !node->isValidIndex(arg.index_))
+ return defaultValue;
+ node = &((*node)[arg.index_]);
+ } else if (arg.kind_ == PathArgument::kindKey) {
+ if (!node->isObject())
+ return defaultValue;
+ node = &((*node)[arg.key_]);
+ if (node == &Value::null)
+ return defaultValue;
+ }
+ }
+ return *node;
+}
+
+Value& Path::make(Value& root) const {
+ Value* node = &root;
+ for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
+ const PathArgument& arg = *it;
+ if (arg.kind_ == PathArgument::kindIndex) {
+ if (!node->isArray()) {
+ // Error: node is not an array at position ...
+ }
+ node = &((*node)[arg.index_]);
+ } else if (arg.kind_ == PathArgument::kindKey) {
+ if (!node->isObject()) {
+ // Error: node is not an object at position...
+ }
+ node = &((*node)[arg.key_]);
+ }
+ }
+ return *node;
+}
+
+} // namespace Json
diff --git a/Utilities/cmjsoncpp/src/lib_json/json_valueiterator.inl b/Utilities/cmjsoncpp/src/lib_json/json_valueiterator.inl
new file mode 100644
index 000000000..a9f7df63a
--- /dev/null
+++ b/Utilities/cmjsoncpp/src/lib_json/json_valueiterator.inl
@@ -0,0 +1,241 @@
+// Copyright 2007-2010 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+// included by json_value.cpp
+
+namespace Json {
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// class ValueIteratorBase
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+
+ValueIteratorBase::ValueIteratorBase()
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ : current_(), isNull_(true) {
+}
+#else
+ : isArray_(true), isNull_(true) {
+ iterator_.array_ = ValueInternalArray::IteratorState();
+}
+#endif
+
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ValueIteratorBase::ValueIteratorBase(
+ const Value::ObjectValues::iterator& current)
+ : current_(current), isNull_(false) {}
+#else
+ValueIteratorBase::ValueIteratorBase(
+ const ValueInternalArray::IteratorState& state)
+ : isArray_(true) {
+ iterator_.array_ = state;
+}
+
+ValueIteratorBase::ValueIteratorBase(
+ const ValueInternalMap::IteratorState& state)
+ : isArray_(false) {
+ iterator_.map_ = state;
+}
+#endif
+
+Value& ValueIteratorBase::deref() const {
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ return current_->second;
+#else
+ if (isArray_)
+ return ValueInternalArray::dereference(iterator_.array_);
+ return ValueInternalMap::value(iterator_.map_);
+#endif
+}
+
+void ValueIteratorBase::increment() {
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ ++current_;
+#else
+ if (isArray_)
+ ValueInternalArray::increment(iterator_.array_);
+ ValueInternalMap::increment(iterator_.map_);
+#endif
+}
+
+void ValueIteratorBase::decrement() {
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ --current_;
+#else
+ if (isArray_)
+ ValueInternalArray::decrement(iterator_.array_);
+ ValueInternalMap::decrement(iterator_.map_);
+#endif
+}
+
+ValueIteratorBase::difference_type
+ValueIteratorBase::computeDistance(const SelfType& other) const {
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+#ifdef JSON_USE_CPPTL_SMALLMAP
+ return current_ - other.current_;
+#else
+ // Iterator for null value are initialized using the default
+ // constructor, which initialize current_ to the default
+ // std::map::iterator. As begin() and end() are two instance
+ // of the default std::map::iterator, they can not be compared.
+ // To allow this, we handle this comparison specifically.
+ if (isNull_ && other.isNull_) {
+ return 0;
+ }
+
+ // Usage of std::distance is not portable (does not compile with Sun Studio 12
+ // RogueWave STL,
+ // which is the one used by default).
+ // Using a portable hand-made version for non random iterator instead:
+ // return difference_type( std::distance( current_, other.current_ ) );
+ difference_type myDistance = 0;
+ for (Value::ObjectValues::iterator it = current_; it != other.current_;
+ ++it) {
+ ++myDistance;
+ }
+ return myDistance;
+#endif
+#else
+ if (isArray_)
+ return ValueInternalArray::distance(iterator_.array_,
+ other.iterator_.array_);
+ return ValueInternalMap::distance(iterator_.map_, other.iterator_.map_);
+#endif
+}
+
+bool ValueIteratorBase::isEqual(const SelfType& other) const {
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ if (isNull_) {
+ return other.isNull_;
+ }
+ return current_ == other.current_;
+#else
+ if (isArray_)
+ return ValueInternalArray::equals(iterator_.array_, other.iterator_.array_);
+ return ValueInternalMap::equals(iterator_.map_, other.iterator_.map_);
+#endif
+}
+
+void ValueIteratorBase::copy(const SelfType& other) {
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ current_ = other.current_;
+ isNull_ = other.isNull_;
+#else
+ if (isArray_)
+ iterator_.array_ = other.iterator_.array_;
+ iterator_.map_ = other.iterator_.map_;
+#endif
+}
+
+Value ValueIteratorBase::key() const {
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ const Value::CZString czstring = (*current_).first;
+ if (czstring.c_str()) {
+ if (czstring.isStaticString())
+ return Value(StaticString(czstring.c_str()));
+ return Value(czstring.c_str());
+ }
+ return Value(czstring.index());
+#else
+ if (isArray_)
+ return Value(ValueInternalArray::indexOf(iterator_.array_));
+ bool isStatic;
+ const char* memberName = ValueInternalMap::key(iterator_.map_, isStatic);
+ if (isStatic)
+ return Value(StaticString(memberName));
+ return Value(memberName);
+#endif
+}
+
+UInt ValueIteratorBase::index() const {
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ const Value::CZString czstring = (*current_).first;
+ if (!czstring.c_str())
+ return czstring.index();
+ return Value::UInt(-1);
+#else
+ if (isArray_)
+ return Value::UInt(ValueInternalArray::indexOf(iterator_.array_));
+ return Value::UInt(-1);
+#endif
+}
+
+const char* ValueIteratorBase::memberName() const {
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ const char* name = (*current_).first.c_str();
+ return name ? name : "";
+#else
+ if (!isArray_)
+ return ValueInternalMap::key(iterator_.map_);
+ return "";
+#endif
+}
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// class ValueConstIterator
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+
+ValueConstIterator::ValueConstIterator() {}
+
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ValueConstIterator::ValueConstIterator(
+ const Value::ObjectValues::iterator& current)
+ : ValueIteratorBase(current) {}
+#else
+ValueConstIterator::ValueConstIterator(
+ const ValueInternalArray::IteratorState& state)
+ : ValueIteratorBase(state) {}
+
+ValueConstIterator::ValueConstIterator(
+ const ValueInternalMap::IteratorState& state)
+ : ValueIteratorBase(state) {}
+#endif
+
+ValueConstIterator& ValueConstIterator::
+operator=(const ValueIteratorBase& other) {
+ copy(other);
+ return *this;
+}
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// class ValueIterator
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+
+ValueIterator::ValueIterator() {}
+
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ValueIterator::ValueIterator(const Value::ObjectValues::iterator& current)
+ : ValueIteratorBase(current) {}
+#else
+ValueIterator::ValueIterator(const ValueInternalArray::IteratorState& state)
+ : ValueIteratorBase(state) {}
+
+ValueIterator::ValueIterator(const ValueInternalMap::IteratorState& state)
+ : ValueIteratorBase(state) {}
+#endif
+
+ValueIterator::ValueIterator(const ValueConstIterator& other)
+ : ValueIteratorBase(other) {}
+
+ValueIterator::ValueIterator(const ValueIterator& other)
+ : ValueIteratorBase(other) {}
+
+ValueIterator& ValueIterator::operator=(const SelfType& other) {
+ copy(other);
+ return *this;
+}
+
+} // namespace Json
diff --git a/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp b/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp
new file mode 100644
index 000000000..e3f4e53cf
--- /dev/null
+++ b/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp
@@ -0,0 +1,724 @@
+// Copyright 2011 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#if !defined(JSON_IS_AMALGAMATION)
+#include <json/writer.h>
+#include "json_tool.h"
+#endif // if !defined(JSON_IS_AMALGAMATION)
+#include <utility>
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <sstream>
+#include <iomanip>
+#include <math.h>
+
+#if defined(_MSC_VER) && _MSC_VER < 1500 // VC++ 8.0 and below
+#include <float.h>
+#define isfinite _finite
+#define snprintf _snprintf
+#endif
+
+// Solaris
+#if defined(__sun)
+# include <ieeefp.h>
+# if !defined(isfinite)
+# define isfinite finite
+# endif
+#endif
+
+// AIX
+#if defined(_AIX)
+# if !defined(isfinite)
+# define isfinite finite
+# endif
+#endif
+
+// HP-UX
+#if defined(__hpux)
+# if !defined(isfinite)
+# if defined(__ia64) && !defined(finite)
+# define isfinite(x) ((sizeof(x) == sizeof(float) ? \
+ _Isfinitef(x) : _Isfinite(x)))
+# else
+# define isfinite finite
+# endif
+# endif
+#endif
+
+// Ancient glibc
+#if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 2
+# if !defined(isfinite)
+# define isfinite __finite
+# endif
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0
+// Disable warning about strdup being deprecated.
+#pragma warning(disable : 4996)
+#endif
+
+namespace Json {
+
+static bool containsControlCharacter(const char* str) {
+ while (*str) {
+ if (isControlCharacter(*(str++)))
+ return true;
+ }
+ return false;
+}
+
+std::string valueToString(LargestInt value) {
+ UIntToStringBuffer buffer;
+ char* current = buffer + sizeof(buffer);
+ bool isNegative = value < 0;
+ if (isNegative)
+ value = -value;
+ uintToString(LargestUInt(value), current);
+ if (isNegative)
+ *--current = '-';
+ assert(current >= buffer);
+ return current;
+}
+
+std::string valueToString(LargestUInt value) {
+ UIntToStringBuffer buffer;
+ char* current = buffer + sizeof(buffer);
+ uintToString(value, current);
+ assert(current >= buffer);
+ return current;
+}
+
+#if defined(JSON_HAS_INT64)
+
+std::string valueToString(Int value) {
+ return valueToString(LargestInt(value));
+}
+
+std::string valueToString(UInt value) {
+ return valueToString(LargestUInt(value));
+}
+
+#endif // # if defined(JSON_HAS_INT64)
+
+std::string valueToString(double value) {
+ // Allocate a buffer that is more than large enough to store the 16 digits of
+ // precision requested below.
+ char buffer[32];
+ int len = -1;
+
+// Print into the buffer. We need not request the alternative representation
+// that always has a decimal point because JSON doesn't distingish the
+// concepts of reals and integers.
+#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) // Use secure version with
+ // visual studio 2005 to
+ // avoid warning.
+#if defined(WINCE)
+ len = _snprintf(buffer, sizeof(buffer), "%.16g", value);
+#else
+ len = sprintf_s(buffer, sizeof(buffer), "%.16g", value);
+#endif
+#else
+ if (isfinite(value)) {
+ len = snprintf(buffer, sizeof(buffer), "%.16g", value);
+ } else {
+ // IEEE standard states that NaN values will not compare to themselves
+ if (value != value) {
+ len = snprintf(buffer, sizeof(buffer), "null");
+ } else if (value < 0) {
+ len = snprintf(buffer, sizeof(buffer), "-1e+9999");
+ } else {
+ len = snprintf(buffer, sizeof(buffer), "1e+9999");
+ }
+ // For those, we do not need to call fixNumLoc, but it is fast.
+ }
+#endif
+ assert(len >= 0);
+ fixNumericLocale(buffer, buffer + len);
+ return buffer;
+}
+
+std::string valueToString(bool value) { return value ? "true" : "false"; }
+
+std::string valueToQuotedString(const char* value) {
+ if (value == NULL)
+ return "";
+ // Not sure how to handle unicode...
+ if (strpbrk(value, "\"\\\b\f\n\r\t") == NULL &&
+ !containsControlCharacter(value))
+ return std::string("\"") + value + "\"";
+ // We have to walk value and escape any special characters.
+ // Appending to std::string is not efficient, but this should be rare.
+ // (Note: forward slashes are *not* rare, but I am not escaping them.)
+ std::string::size_type maxsize =
+ strlen(value) * 2 + 3; // allescaped+quotes+NULL
+ std::string result;
+ result.reserve(maxsize); // to avoid lots of mallocs
+ result += "\"";
+ for (const char* c = value; *c != 0; ++c) {
+ switch (*c) {
+ case '\"':
+ result += "\\\"";
+ break;
+ case '\\':
+ result += "\\\\";
+ break;
+ case '\b':
+ result += "\\b";
+ break;
+ case '\f':
+ result += "\\f";
+ break;
+ case '\n':
+ result += "\\n";
+ break;
+ case '\r':
+ result += "\\r";
+ break;
+ case '\t':
+ result += "\\t";
+ break;
+ // case '/':
+ // Even though \/ is considered a legal escape in JSON, a bare
+ // slash is also legal, so I see no reason to escape it.
+ // (I hope I am not misunderstanding something.
+ // blep notes: actually escaping \/ may be useful in javascript to avoid </
+ // sequence.
+ // Should add a flag to allow this compatibility mode and prevent this
+ // sequence from occurring.
+ default:
+ if (isControlCharacter(*c)) {
+ std::ostringstream oss;
+ oss << "\\u" << std::hex << std::uppercase << std::setfill('0')
+ << std::setw(4) << static_cast<int>(*c);
+ result += oss.str();
+ } else {
+ result += *c;
+ }
+ break;
+ }
+ }
+ result += "\"";
+ return result;
+}
+
+// Class Writer
+// //////////////////////////////////////////////////////////////////
+Writer::~Writer() {}
+
+// Class FastWriter
+// //////////////////////////////////////////////////////////////////
+
+FastWriter::FastWriter()
+ : yamlCompatiblityEnabled_(false), dropNullPlaceholders_(false),
+ omitEndingLineFeed_(false) {}
+
+void FastWriter::enableYAMLCompatibility() { yamlCompatiblityEnabled_ = true; }
+
+void FastWriter::dropNullPlaceholders() { dropNullPlaceholders_ = true; }
+
+void FastWriter::omitEndingLineFeed() { omitEndingLineFeed_ = true; }
+
+std::string FastWriter::write(const Value& root) {
+ document_ = "";
+ writeValue(root);
+ if (!omitEndingLineFeed_)
+ document_ += "\n";
+ return document_;
+}
+
+void FastWriter::writeValue(const Value& value) {
+ switch (value.type()) {
+ case nullValue:
+ if (!dropNullPlaceholders_)
+ document_ += "null";
+ break;
+ case intValue:
+ document_ += valueToString(value.asLargestInt());
+ break;
+ case uintValue:
+ document_ += valueToString(value.asLargestUInt());
+ break;
+ case realValue:
+ document_ += valueToString(value.asDouble());
+ break;
+ case stringValue:
+ document_ += valueToQuotedString(value.asCString());
+ break;
+ case booleanValue:
+ document_ += valueToString(value.asBool());
+ break;
+ case arrayValue: {
+ document_ += '[';
+ int size = value.size();
+ for (int index = 0; index < size; ++index) {
+ if (index > 0)
+ document_ += ',';
+ writeValue(value[index]);
+ }
+ document_ += ']';
+ } break;
+ case objectValue: {
+ Value::Members members(value.getMemberNames());
+ document_ += '{';
+ for (Value::Members::iterator it = members.begin(); it != members.end();
+ ++it) {
+ const std::string& name = *it;
+ if (it != members.begin())
+ document_ += ',';
+ document_ += valueToQuotedString(name.c_str());
+ document_ += yamlCompatiblityEnabled_ ? ": " : ":";
+ writeValue(value[name]);
+ }
+ document_ += '}';
+ } break;
+ }
+}
+
+// Class StyledWriter
+// //////////////////////////////////////////////////////////////////
+
+StyledWriter::StyledWriter()
+ : rightMargin_(74), indentSize_(3), addChildValues_() {}
+
+std::string StyledWriter::write(const Value& root) {
+ document_ = "";
+ addChildValues_ = false;
+ indentString_ = "";
+ writeCommentBeforeValue(root);
+ writeValue(root);
+ writeCommentAfterValueOnSameLine(root);
+ document_ += "\n";
+ return document_;
+}
+
+void StyledWriter::writeValue(const Value& value) {
+ switch (value.type()) {
+ case nullValue:
+ pushValue("null");
+ break;
+ case intValue:
+ pushValue(valueToString(value.asLargestInt()));
+ break;
+ case uintValue:
+ pushValue(valueToString(value.asLargestUInt()));
+ break;
+ case realValue:
+ pushValue(valueToString(value.asDouble()));
+ break;
+ case stringValue:
+ pushValue(valueToQuotedString(value.asCString()));
+ break;
+ case booleanValue:
+ pushValue(valueToString(value.asBool()));
+ break;
+ case arrayValue:
+ writeArrayValue(value);
+ break;
+ case objectValue: {
+ Value::Members members(value.getMemberNames());
+ if (members.empty())
+ pushValue("{}");
+ else {
+ writeWithIndent("{");
+ indent();
+ Value::Members::iterator it = members.begin();
+ for (;;) {
+ const std::string& name = *it;
+ const Value& childValue = value[name];
+ writeCommentBeforeValue(childValue);
+ writeWithIndent(valueToQuotedString(name.c_str()));
+ document_ += " : ";
+ writeValue(childValue);
+ if (++it == members.end()) {
+ writeCommentAfterValueOnSameLine(childValue);
+ break;
+ }
+ document_ += ',';
+ writeCommentAfterValueOnSameLine(childValue);
+ }
+ unindent();
+ writeWithIndent("}");
+ }
+ } break;
+ }
+}
+
+void StyledWriter::writeArrayValue(const Value& value) {
+ unsigned size = value.size();
+ if (size == 0)
+ pushValue("[]");
+ else {
+ bool isArrayMultiLine = isMultineArray(value);
+ if (isArrayMultiLine) {
+ writeWithIndent("[");
+ indent();
+ bool hasChildValue = !childValues_.empty();
+ unsigned index = 0;
+ for (;;) {
+ const Value& childValue = value[index];
+ writeCommentBeforeValue(childValue);
+ if (hasChildValue)
+ writeWithIndent(childValues_[index]);
+ else {
+ writeIndent();
+ writeValue(childValue);
+ }
+ if (++index == size) {
+ writeCommentAfterValueOnSameLine(childValue);
+ break;
+ }
+ document_ += ',';
+ writeCommentAfterValueOnSameLine(childValue);
+ }
+ unindent();
+ writeWithIndent("]");
+ } else // output on a single line
+ {
+ assert(childValues_.size() == size);
+ document_ += "[ ";
+ for (unsigned index = 0; index < size; ++index) {
+ if (index > 0)
+ document_ += ", ";
+ document_ += childValues_[index];
+ }
+ document_ += " ]";
+ }
+ }
+}
+
+bool StyledWriter::isMultineArray(const Value& value) {
+ int size = value.size();
+ bool isMultiLine = size * 3 >= rightMargin_;
+ childValues_.clear();
+ for (int index = 0; index < size && !isMultiLine; ++index) {
+ const Value& childValue = value[index];
+ isMultiLine =
+ isMultiLine || ((childValue.isArray() || childValue.isObject()) &&
+ childValue.size() > 0);
+ }
+ if (!isMultiLine) // check if line length > max line length
+ {
+ childValues_.reserve(size);
+ addChildValues_ = true;
+ int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
+ for (int index = 0; index < size; ++index) {
+ writeValue(value[index]);
+ lineLength += int(childValues_[index].length());
+ }
+ addChildValues_ = false;
+ isMultiLine = isMultiLine || lineLength >= rightMargin_;
+ }
+ return isMultiLine;
+}
+
+void StyledWriter::pushValue(const std::string& value) {
+ if (addChildValues_)
+ childValues_.push_back(value);
+ else
+ document_ += value;
+}
+
+void StyledWriter::writeIndent() {
+ if (!document_.empty()) {
+ char last = document_[document_.length() - 1];
+ if (last == ' ') // already indented
+ return;
+ if (last != '\n') // Comments may add new-line
+ document_ += '\n';
+ }
+ document_ += indentString_;
+}
+
+void StyledWriter::writeWithIndent(const std::string& value) {
+ writeIndent();
+ document_ += value;
+}
+
+void StyledWriter::indent() { indentString_ += std::string(indentSize_, ' '); }
+
+void StyledWriter::unindent() {
+ assert(int(indentString_.size()) >= indentSize_);
+ indentString_.resize(indentString_.size() - indentSize_);
+}
+
+void StyledWriter::writeCommentBeforeValue(const Value& root) {
+ if (!root.hasComment(commentBefore))
+ return;
+
+ document_ += "\n";
+ writeIndent();
+ std::string normalizedComment = normalizeEOL(root.getComment(commentBefore));
+ std::string::const_iterator iter = normalizedComment.begin();
+ while (iter != normalizedComment.end()) {
+ document_ += *iter;
+ if (*iter == '\n' && *(iter + 1) == '/')
+ writeIndent();
+ ++iter;
+ }
+
+ // Comments are stripped of newlines, so add one here
+ document_ += "\n";
+}
+
+void StyledWriter::writeCommentAfterValueOnSameLine(const Value& root) {
+ if (root.hasComment(commentAfterOnSameLine))
+ document_ += " " + normalizeEOL(root.getComment(commentAfterOnSameLine));
+
+ if (root.hasComment(commentAfter)) {
+ document_ += "\n";
+ document_ += normalizeEOL(root.getComment(commentAfter));
+ document_ += "\n";
+ }
+}
+
+bool StyledWriter::hasCommentForValue(const Value& value) {
+ return value.hasComment(commentBefore) ||
+ value.hasComment(commentAfterOnSameLine) ||
+ value.hasComment(commentAfter);
+}
+
+std::string StyledWriter::normalizeEOL(const std::string& text) {
+ std::string normalized;
+ normalized.reserve(text.length());
+ const char* begin = text.c_str();
+ const char* end = begin + text.length();
+ const char* current = begin;
+ while (current != end) {
+ char c = *current++;
+ if (c == '\r') // mac or dos EOL
+ {
+ if (*current == '\n') // convert dos EOL
+ ++current;
+ normalized += '\n';
+ } else // handle unix EOL & other char
+ normalized += c;
+ }
+ return normalized;
+}
+
+// Class StyledStreamWriter
+// //////////////////////////////////////////////////////////////////
+
+StyledStreamWriter::StyledStreamWriter(std::string indentation)
+ : document_(NULL), rightMargin_(74), indentation_(indentation),
+ addChildValues_() {}
+
+void StyledStreamWriter::write(std::ostream& out, const Value& root) {
+ document_ = &out;
+ addChildValues_ = false;
+ indentString_ = "";
+ writeCommentBeforeValue(root);
+ writeValue(root);
+ writeCommentAfterValueOnSameLine(root);
+ *document_ << "\n";
+ document_ = NULL; // Forget the stream, for safety.
+}
+
+void StyledStreamWriter::writeValue(const Value& value) {
+ switch (value.type()) {
+ case nullValue:
+ pushValue("null");
+ break;
+ case intValue:
+ pushValue(valueToString(value.asLargestInt()));
+ break;
+ case uintValue:
+ pushValue(valueToString(value.asLargestUInt()));
+ break;
+ case realValue:
+ pushValue(valueToString(value.asDouble()));
+ break;
+ case stringValue:
+ pushValue(valueToQuotedString(value.asCString()));
+ break;
+ case booleanValue:
+ pushValue(valueToString(value.asBool()));
+ break;
+ case arrayValue:
+ writeArrayValue(value);
+ break;
+ case objectValue: {
+ Value::Members members(value.getMemberNames());
+ if (members.empty())
+ pushValue("{}");
+ else {
+ writeWithIndent("{");
+ indent();
+ Value::Members::iterator it = members.begin();
+ for (;;) {
+ const std::string& name = *it;
+ const Value& childValue = value[name];
+ writeCommentBeforeValue(childValue);
+ writeWithIndent(valueToQuotedString(name.c_str()));
+ *document_ << " : ";
+ writeValue(childValue);
+ if (++it == members.end()) {
+ writeCommentAfterValueOnSameLine(childValue);
+ break;
+ }
+ *document_ << ",";
+ writeCommentAfterValueOnSameLine(childValue);
+ }
+ unindent();
+ writeWithIndent("}");
+ }
+ } break;
+ }
+}
+
+void StyledStreamWriter::writeArrayValue(const Value& value) {
+ unsigned size = value.size();
+ if (size == 0)
+ pushValue("[]");
+ else {
+ bool isArrayMultiLine = isMultineArray(value);
+ if (isArrayMultiLine) {
+ writeWithIndent("[");
+ indent();
+ bool hasChildValue = !childValues_.empty();
+ unsigned index = 0;
+ for (;;) {
+ const Value& childValue = value[index];
+ writeCommentBeforeValue(childValue);
+ if (hasChildValue)
+ writeWithIndent(childValues_[index]);
+ else {
+ writeIndent();
+ writeValue(childValue);
+ }
+ if (++index == size) {
+ writeCommentAfterValueOnSameLine(childValue);
+ break;
+ }
+ *document_ << ",";
+ writeCommentAfterValueOnSameLine(childValue);
+ }
+ unindent();
+ writeWithIndent("]");
+ } else // output on a single line
+ {
+ assert(childValues_.size() == size);
+ *document_ << "[ ";
+ for (unsigned index = 0; index < size; ++index) {
+ if (index > 0)
+ *document_ << ", ";
+ *document_ << childValues_[index];
+ }
+ *document_ << " ]";
+ }
+ }
+}
+
+bool StyledStreamWriter::isMultineArray(const Value& value) {
+ int size = value.size();
+ bool isMultiLine = size * 3 >= rightMargin_;
+ childValues_.clear();
+ for (int index = 0; index < size && !isMultiLine; ++index) {
+ const Value& childValue = value[index];
+ isMultiLine =
+ isMultiLine || ((childValue.isArray() || childValue.isObject()) &&
+ childValue.size() > 0);
+ }
+ if (!isMultiLine) // check if line length > max line length
+ {
+ childValues_.reserve(size);
+ addChildValues_ = true;
+ int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
+ for (int index = 0; index < size; ++index) {
+ writeValue(value[index]);
+ lineLength += int(childValues_[index].length());
+ }
+ addChildValues_ = false;
+ isMultiLine = isMultiLine || lineLength >= rightMargin_;
+ }
+ return isMultiLine;
+}
+
+void StyledStreamWriter::pushValue(const std::string& value) {
+ if (addChildValues_)
+ childValues_.push_back(value);
+ else
+ *document_ << value;
+}
+
+void StyledStreamWriter::writeIndent() {
+ /*
+ Some comments in this method would have been nice. ;-)
+
+ if ( !document_.empty() )
+ {
+ char last = document_[document_.length()-1];
+ if ( last == ' ' ) // already indented
+ return;
+ if ( last != '\n' ) // Comments may add new-line
+ *document_ << '\n';
+ }
+ */
+ *document_ << '\n' << indentString_;
+}
+
+void StyledStreamWriter::writeWithIndent(const std::string& value) {
+ writeIndent();
+ *document_ << value;
+}
+
+void StyledStreamWriter::indent() { indentString_ += indentation_; }
+
+void StyledStreamWriter::unindent() {
+ assert(indentString_.size() >= indentation_.size());
+ indentString_.resize(indentString_.size() - indentation_.size());
+}
+
+void StyledStreamWriter::writeCommentBeforeValue(const Value& root) {
+ if (!root.hasComment(commentBefore))
+ return;
+ *document_ << normalizeEOL(root.getComment(commentBefore));
+ *document_ << "\n";
+}
+
+void StyledStreamWriter::writeCommentAfterValueOnSameLine(const Value& root) {
+ if (root.hasComment(commentAfterOnSameLine))
+ *document_ << " " + normalizeEOL(root.getComment(commentAfterOnSameLine));
+
+ if (root.hasComment(commentAfter)) {
+ *document_ << "\n";
+ *document_ << normalizeEOL(root.getComment(commentAfter));
+ *document_ << "\n";
+ }
+}
+
+bool StyledStreamWriter::hasCommentForValue(const Value& value) {
+ return value.hasComment(commentBefore) ||
+ value.hasComment(commentAfterOnSameLine) ||
+ value.hasComment(commentAfter);
+}
+
+std::string StyledStreamWriter::normalizeEOL(const std::string& text) {
+ std::string normalized;
+ normalized.reserve(text.length());
+ const char* begin = text.c_str();
+ const char* end = begin + text.length();
+ const char* current = begin;
+ while (current != end) {
+ char c = *current++;
+ if (c == '\r') // mac or dos EOL
+ {
+ if (*current == '\n') // convert dos EOL
+ ++current;
+ normalized += '\n';
+ } else // handle unix EOL & other char
+ normalized += c;
+ }
+ return normalized;
+}
+
+std::ostream& operator<<(std::ostream& sout, const Value& root) {
+ Json::StyledStreamWriter writer;
+ writer.write(sout, root);
+ return sout;
+}
+
+} // namespace Json
diff --git a/Utilities/cmlibarchive/.gitattributes b/Utilities/cmlibarchive/.gitattributes
index be7062b6e..562b12e16 100644
--- a/Utilities/cmlibarchive/.gitattributes
+++ b/Utilities/cmlibarchive/.gitattributes
@@ -1,2 +1 @@
-*.h whitespace=indent-with-non-tab,-blank-at-eol
-*.c whitespace=indent-with-non-tab,-blank-at-eol
+* -whitespace
diff --git a/Utilities/cmlibarchive/CMakeLists.txt b/Utilities/cmlibarchive/CMakeLists.txt
index 8ef0e89d6..00550e2e9 100644
--- a/Utilities/cmlibarchive/CMakeLists.txt
+++ b/Utilities/cmlibarchive/CMakeLists.txt
@@ -8,6 +8,9 @@ endif()
# On MacOS, prefer MacPorts libraries to system libraries.
# I haven't come up with a compelling argument for this to be conditional.
list(APPEND CMAKE_PREFIX_PATH /opt/local)
+# Enable @rpath in the install name.
+# detail in "cmake --help-policy CMP0042"
+SET(CMAKE_MACOSX_RPATH ON)
#
# Version - read from 'version' file.
@@ -28,11 +31,12 @@ STRING(REGEX REPLACE "[0]*([^0]*[0-9])$" "\\1" _trimmed_revision ${_revision})
SET(VERSION "${_major}.${_trimmed_minor}.${_trimmed_revision}${_quality}")
SET(BSDCPIO_VERSION_STRING "${VERSION}")
SET(BSDTAR_VERSION_STRING "${VERSION}")
+SET(BSDCAT_VERSION_STRING "${VERSION}")
SET(LIBARCHIVE_VERSION_NUMBER "${_version_number}")
SET(LIBARCHIVE_VERSION_STRING "${VERSION}")
# INTERFACE_VERSION increments with every release
-# libarchive 2.7 == interface version 9 = 2 + 7
+# libarchive 2.7 == interface version 9 = 2 + 7
# libarchive 2.8 == interface version 10 = 2 + 8
# libarchive 2.9 == interface version 11 = 2 + 9
# libarchive 3.0 == interface version 12
@@ -55,13 +59,11 @@ SET(CMAKE_REQUIRED_LIBRARIES)
SET(CMAKE_REQUIRED_FLAGS)
# Disable warnings to avoid changing 3rd party code.
-IF("${CMAKE_C_COMPILER_ID}" MATCHES
- "^(GNU|Clang|XL|VisualAge|SunPro|MIPSpro|HP|Intel)$")
+IF(CMAKE_C_COMPILER_ID MATCHES
+ "^(GNU|Clang|AppleClang|XL|VisualAge|SunPro|MIPSpro|HP|Intel)$")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w")
-ELSEIF("${CMAKE_C_COMPILER_ID}" MATCHES "^(PathScale)$")
+ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "PathScale")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall")
-ELSEIF(BORLAND)
- SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w-")
ENDIF()
# Enable CTest/CDash support
@@ -69,6 +71,16 @@ include(CTest)
OPTION(ENABLE_NETTLE "Enable use of Nettle" ON)
OPTION(ENABLE_OPENSSL "Enable use of OpenSSL" ON)
+OPTION(ENABLE_LZMA "Enable the use of the system found LZMA library if found" ON)
+OPTION(ENABLE_ZLIB "Enable the use of the system found ZLIB library if found" ON)
+OPTION(ENABLE_BZip2 "Enable the use of the system found BZip2 library if found" ON)
+OPTION(ENABLE_LIBXML2 "Enable the use of the system found libxml2 library if found" ON)
+OPTION(ENABLE_EXPAT "Enable the use of the system found EXPAT library if found" ON)
+OPTION(ENABLE_PCREPOSIX "Enable the use of the system found PCREPOSIX library if found" ON)
+OPTION(ENABLE_LibGCC "Enable the use of the system found LibGCC library if found" ON)
+# CNG is used for encrypt/decrypt Zip archives on Windows.
+OPTION(ENABLE_CNG "Enable the use of CNG(Crypto Next Generation)" ON)
+
OPTION(ENABLE_XATTR "Enable extended attribute support" ON)
OPTION(ENABLE_ACL "Enable ACL support" ON)
OPTION(ENABLE_ICONV "Enable iconv support" ON)
@@ -82,6 +94,8 @@ IF(WIN32)
SET(_WIN32_WINNT ${WINVER})
ENDIF(WIN32)
+set(HAVE_PTHREAD_H 0) # no threads in CMake
+
IF("${CMAKE_C_PLATFORM_ID}" MATCHES "^(HP-UX)$")
ADD_DEFINITIONS(-D_XOPEN_SOURCE=500) # Ask wchar.h for mbstate_t
ENDIF()
@@ -190,7 +204,7 @@ IF(DEFINED __GNUWIN32PATH AND EXISTS "${__GNUWIN32PATH}")
#--- zconf.h.orig 2005-07-21 00:40:26.000000000
#+++ zconf.h 2009-01-19 11:39:10.093750000
#@@ -286,7 +286,7 @@
- #
+ #
# #if 1 /* HAVE_UNISTD_H -- this line is updated by ./configure */
# # include <sys/types.h> /* for off_t */
#-# include <unistd.h> /* for SEEK_* and off_t */
@@ -204,7 +218,11 @@ SET(ADDITIONAL_LIBS "")
#
# Find ZLIB
#
-FIND_PACKAGE(ZLIB)
+IF(ENABLE_ZLIB)
+ FIND_PACKAGE(ZLIB)
+ELSE()
+ SET(ZLIB_FOUND FALSE) # Override cached value
+ENDIF()
IF(ZLIB_FOUND)
SET(HAVE_LIBZ 1)
SET(HAVE_ZLIB_H 1)
@@ -239,7 +257,11 @@ ENDIF(ZLIB_FOUND)
#
# Find BZip2
#
-FIND_PACKAGE(BZip2)
+IF(ENABLE_BZip2)
+ FIND_PACKAGE(BZip2)
+ELSE()
+ SET(BZIP2_FOUND FALSE) # Override cached value
+ENDIF()
IF(BZIP2_FOUND)
SET(HAVE_LIBBZ2 1)
SET(HAVE_BZLIB_H 1)
@@ -259,31 +281,45 @@ IF(BZIP2_FOUND)
ENDIF(BZIP2_FOUND)
MARK_AS_ADVANCED(CLEAR BZIP2_INCLUDE_DIR)
MARK_AS_ADVANCED(CLEAR BZIP2_LIBRARIES)
-IF(0) # CMake does not need LZMA or LZO2 support in libarchive
+
+
#
# Find LZMA
#
-FIND_PACKAGE(LZMA)
+IF(ENABLE_LZMA)
+ FIND_PACKAGE(LZMA)
+ELSE()
+ SET(LZMA_FOUND FALSE) # Override cached value
+ SET(LZMADEC_FOUND FALSE) # Override cached value
+ENDIF()
+
IF(LZMA_FOUND)
SET(HAVE_LIBLZMA 1)
SET(HAVE_LZMA_H 1)
INCLUDE_DIRECTORIES(${LZMA_INCLUDE_DIR})
LIST(APPEND ADDITIONAL_LIBS ${LZMA_LIBRARIES})
- # Test if a macro is needed for the library.
- TRY_MACRO_FOR_LIBRARY(
- "${LZMA_INCLUDE_DIR}" "${LZMA_LIBRARIES}"
- COMPILES
- "#include <lzma.h>\nint main() {return (int)lzma_version_number(); }"
- "WITHOUT_LZMA_API_STATIC;LZMA_API_STATIC")
- IF(NOT WITHOUT_LZMA_API_STATIC AND LZMA_API_STATIC)
+ IF(CMAKE_USE_SYSTEM_LIBLZMA)
+ # Test if a macro is needed for the library.
+ TRY_MACRO_FOR_LIBRARY(
+ "${LZMA_INCLUDE_DIR}" "${LZMA_LIBRARIES}"
+ COMPILES
+ "#include <lzma.h>\nint main() {return (int)lzma_version_number(); }"
+ "WITHOUT_LZMA_API_STATIC;LZMA_API_STATIC")
+ IF(NOT WITHOUT_LZMA_API_STATIC AND LZMA_API_STATIC)
+ ADD_DEFINITIONS(-DLZMA_API_STATIC)
+ ENDIF(NOT WITHOUT_LZMA_API_STATIC AND LZMA_API_STATIC)
+ ELSE()
ADD_DEFINITIONS(-DLZMA_API_STATIC)
- ENDIF(NOT WITHOUT_LZMA_API_STATIC AND LZMA_API_STATIC)
+ ENDIF()
ELSEIF(LZMADEC_FOUND)
SET(HAVE_LIBLZMADEC 1)
SET(HAVE_LZMADEC_H 1)
INCLUDE_DIRECTORIES(${LZMADEC_INCLUDE_DIR})
LIST(APPEND ADDITIONAL_LIBS ${LZMADEC_LIBRARIES})
+ELSE(LZMA_FOUND)
+# LZMA not found and will not be used.
ENDIF(LZMA_FOUND)
+IF(0) # CMake does not need LZO2 support in libarchive
#
# Find LZO2
#
@@ -309,6 +345,35 @@ ENDIF(LZO2_FOUND)
MARK_AS_ADVANCED(CLEAR LZO2_INCLUDE_DIR)
MARK_AS_ADVANCED(CLEAR LZO2_LIBRARY)
ENDIF()
+IF(0) # CMake does not need LZ4 support in libarchive
+#
+# Find LZ4
+#
+IF (LZ4_INCLUDE_DIR)
+ # Already in cache, be silent
+ SET(LZ4_FIND_QUIETLY TRUE)
+ENDIF (LZ4_INCLUDE_DIR)
+
+FIND_PATH(LZ4_INCLUDE_DIR lz4.h)
+FIND_LIBRARY(LZ4_LIBRARY NAMES lz4 liblz4)
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LZ4 DEFAULT_MSG LZ4_LIBRARY LZ4_INCLUDE_DIR)
+IF(LZ4_FOUND)
+ SET(HAVE_LIBLZ4 1)
+ SET(HAVE_LZ4_H 1)
+ CMAKE_PUSH_CHECK_STATE() # Save the state of the variables
+ SET(CMAKE_REQUIRED_INCLUDES ${LZ4_INCLUDE_DIR})
+ CHECK_INCLUDE_FILES("lz4hc.h" HAVE_LZ4HC_H)
+ CMAKE_POP_CHECK_STATE() # Restore the state of the variables
+ INCLUDE_DIRECTORIES(${LZ4_INCLUDE_DIR})
+ LIST(APPEND ADDITIONAL_LIBS ${LZ4_LIBRARY})
+ #
+ # TODO: test for static library.
+ #
+ENDIF(LZ4_FOUND)
+MARK_AS_ADVANCED(CLEAR LZ4_INCLUDE_DIR)
+MARK_AS_ADVANCED(CLEAR LZ4_LIBRARY)
+ENDIF()
#
# Check headers
@@ -327,7 +392,11 @@ ENDMACRO (LA_CHECK_INCLUDE_FILE)
LA_CHECK_INCLUDE_FILE("sys/types.h" HAVE_SYS_TYPES_H)
# Alphabetize the rest unless there's a compelling reason
-LA_CHECK_INCLUDE_FILE("acl/libacl.h" HAVE_ACL_LIBACL_H)
+IF(ENABLE_ACL)
+ LA_CHECK_INCLUDE_FILE("acl/libacl.h" HAVE_ACL_LIBACL_H)
+ELSE(ENABLE_ACL)
+ SET(HAVE_ACL_LIBACL_H FALSE)
+ENDIF(ENABLE_ACL)
LA_CHECK_INCLUDE_FILE("ctype.h" HAVE_CTYPE_H)
LA_CHECK_INCLUDE_FILE("copyfile.h" HAVE_COPYFILE_H)
LA_CHECK_INCLUDE_FILE("direct.h" HAVE_DIRECT_H)
@@ -354,7 +423,9 @@ LA_CHECK_INCLUDE_FILE("memory.h" HAVE_MEMORY_H)
LA_CHECK_INCLUDE_FILE("paths.h" HAVE_PATHS_H)
LA_CHECK_INCLUDE_FILE("poll.h" HAVE_POLL_H)
LA_CHECK_INCLUDE_FILE("process.h" HAVE_PROCESS_H)
+LA_CHECK_INCLUDE_FILE("pthread.h" HAVE_PTHREAD_H)
LA_CHECK_INCLUDE_FILE("pwd.h" HAVE_PWD_H)
+LA_CHECK_INCLUDE_FILE("readpassphrase.h" HAVE_READPASSPHRASE_H)
LA_CHECK_INCLUDE_FILE("regex.h" HAVE_REGEX_H)
LA_CHECK_INCLUDE_FILE("signal.h" HAVE_SIGNAL_H)
LA_CHECK_INCLUDE_FILE("spawn.h" HAVE_SPAWN_H)
@@ -385,6 +456,11 @@ LA_CHECK_INCLUDE_FILE("utime.h" HAVE_UTIME_H)
LA_CHECK_INCLUDE_FILE("wchar.h" HAVE_WCHAR_H)
LA_CHECK_INCLUDE_FILE("wctype.h" HAVE_WCTYPE_H)
LA_CHECK_INCLUDE_FILE("windows.h" HAVE_WINDOWS_H)
+IF(ENABLE_CNG)
+ LA_CHECK_INCLUDE_FILE("Bcrypt.h" HAVE_BCRYPT_H)
+ELSE(ENABLE_CNG)
+ UNSET(HAVE_BCRYPT_H CACHE)
+ENDIF(ENABLE_CNG)
# Following files need windwos.h, so we should test it after windows.h test.
LA_CHECK_INCLUDE_FILE("wincrypt.h" HAVE_WINCRYPT_H)
LA_CHECK_INCLUDE_FILE("winioctl.h" HAVE_WINIOCTL_H)
@@ -416,6 +492,7 @@ IF(ENABLE_NETTLE)
SET(HAVE_NETTLE_SHA_H 1)
INCLUDE_DIRECTORIES(${NETTLE_INCLUDE_DIR})
LIST(APPEND ADDITIONAL_LIBS ${NETTLE_LIBRARIES})
+ LA_CHECK_INCLUDE_FILE("nettle/pbkdf2.h" HAVE_NETTLE_PBKDF2_H)
ENDIF(NETTLE_FOUND)
MARK_AS_ADVANCED(CLEAR NETTLE_INCLUDE_DIR)
MARK_AS_ADVANCED(CLEAR NETTLE_LIBRARIES)
@@ -427,6 +504,9 @@ ENDIF(ENABLE_NETTLE)
#
IF(ENABLE_OPENSSL AND NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
FIND_PACKAGE(OpenSSL)
+ IF(OPENSSL_FOUND)
+ SET(HAVE_LIBCRYPTO 1)
+ ENDIF(OPENSSL_FOUND)
ELSE()
SET(OPENSSL_FOUND FALSE) # Override cached value
ENDIF()
@@ -445,7 +525,7 @@ ENDIF(NOT OPENSSL_FOUND)
#
# How to prove that CRYPTO functions, which have several names on various
-# platforms, just see if archive_crypto.c can compile and link against
+# platforms, just see if archive_digest.c can compile and link against
# required libraries.
#
MACRO(CHECK_CRYPTO ALGORITHMS IMPLEMENTATION)
@@ -484,7 +564,7 @@ MACRO(CHECK_CRYPTO ALGORITHMS IMPLEMENTATION)
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/confdefs.h)
FILE(READ "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/confdefs.h"
CONFDEFS_H)
- FILE(READ "${CMAKE_CURRENT_SOURCE_DIR}/libarchive/archive_crypto.c"
+ FILE(READ "${CMAKE_CURRENT_SOURCE_DIR}/libarchive/archive_digest.c"
ARCHIVE_CRYPTO_C)
SET(SOURCE "${CONFDEFS_H}
@@ -510,16 +590,10 @@ main(int argc, char **argv)
FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_md.c" "${SOURCE}")
MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}")
- IF(CMAKE_REQUIRED_LINKER_FLAGS)
- SET(CHECK_CRYPTO_ADD_LINKER_FLAGS
- "-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS}")
- ELSE(CMAKE_REQUIRED_LINKER_FLAGS)
- SET(CHECK_CRYPTO_ADD_LINKER_FLAGS)
- ENDIF(CMAKE_REQUIRED_LINKER_FLAGS)
TRY_COMPILE(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}
${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_md.c
- CMAKE_FLAGS ${CHECK_CRYPTO_ADD_LINKER_FLAGS}
+ CMAKE_FLAGS
"${TRY_CRYPTO_REQUIRED_LIBS}"
"${TRY_CRYPTO_REQUIRED_INCLUDES}"
OUTPUT_VARIABLE OUTPUT)
@@ -604,16 +678,10 @@ main(int argc, char **argv)
FILE(WRITE "${SOURCE_FILE}" "${SOURCE}")
MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN")
- IF(CMAKE_REQUIRED_LINKER_FLAGS)
- SET(CHECK_CRYPTO_WIN_ADD_LINKER_FLAGS
- "-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS}")
- ELSE(CMAKE_REQUIRED_LINKER_FLAGS)
- SET(CHECK_CRYPTO_WIN_ADD_LINKER_FLAGS)
- ENDIF(CMAKE_REQUIRED_LINKER_FLAGS)
TRY_COMPILE(ARCHIVE_CRYPTO_${CRYPTO}_WIN
${CMAKE_BINARY_DIR}
${SOURCE_FILE}
- CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_BINARY_DIR};${CMAKE_CURRENT_SOURCE_DIR}/libarchive" ${CHECK_CRYPTO_WIN_ADD_LINKER_FLAGS}
+ CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_BINARY_DIR};${CMAKE_CURRENT_SOURCE_DIR}/libarchive"
OUTPUT_VARIABLE OUTPUT)
IF (ARCHIVE_CRYPTO_${CRYPTO}_WIN)
@@ -646,14 +714,15 @@ ENDMACRO(CHECK_CRYPTO_WIN CRYPTO_LIST)
MACRO(CHECK_ICONV LIB TRY_ICONV_CONST)
IF(NOT HAVE_ICONV)
CMAKE_PUSH_CHECK_STATE() # Save the state of the variables
- IF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
+ IF (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR
+ CMAKE_C_COMPILER_ID STREQUAL "Clang")
#
# During checking iconv proto type, we should use -Werror to avoid the
# success of iconv detection with a warnig which success is a miss
# detection. So this needs for all build mode(even it's a release mode).
#
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror")
- ENDIF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
+ ENDIF ()
IF (MSVC)
# NOTE: /WX option is the same as gcc's -Werror option.
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} /WX")
@@ -777,7 +846,11 @@ IF(0) # CMake does not need XML support in libarchive
#
# Find Libxml2
#
-FIND_PACKAGE(LibXml2)
+IF(ENABLE_LIBXML2)
+ FIND_PACKAGE(LibXml2)
+ELSE()
+ SET(LIBXML2_FOUND FALSE)
+ENDIF()
IF(LIBXML2_FOUND)
CMAKE_PUSH_CHECK_STATE() # Save the state of the variables
INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR})
@@ -802,7 +875,11 @@ ELSE(LIBXML2_FOUND)
#
# Find Expat
#
- FIND_PACKAGE(EXPAT)
+ IF(ENABLE_EXPAT)
+ FIND_PACKAGE(EXPAT)
+ ELSE()
+ SET(EXPAT_FOUND FALSE)
+ ENDIF()
IF(EXPAT_FOUND)
CMAKE_PUSH_CHECK_STATE() # Save the state of the variables
INCLUDE_DIRECTORIES(${EXPAT_INCLUDE_DIR})
@@ -820,15 +897,17 @@ ENDIF()
# Check functions
#
CMAKE_PUSH_CHECK_STATE() # Save the state of the variables
-IF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
+IF (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR
+ CMAKE_C_COMPILER_ID STREQUAL "Clang")
#
# During checking functions, we should use -fno-builtin to avoid the
# failure of function detection which failure is an error "conflicting
# types for built-in function" caused by using -Werror option.
#
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-builtin")
-ENDIF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
+ENDIF ()
CHECK_SYMBOL_EXISTS(_CrtSetReportMode "crtdbg.h" HAVE__CrtSetReportMode)
+CHECK_FUNCTION_EXISTS_GLIBC(arc4random_buf HAVE_ARC4RANDOM_BUF)
CHECK_FUNCTION_EXISTS_GLIBC(chflags HAVE_CHFLAGS)
CHECK_FUNCTION_EXISTS_GLIBC(chown HAVE_CHOWN)
CHECK_FUNCTION_EXISTS_GLIBC(chroot HAVE_CHROOT)
@@ -876,6 +955,7 @@ CHECK_FUNCTION_EXISTS_GLIBC(pipe HAVE_PIPE)
CHECK_FUNCTION_EXISTS_GLIBC(poll HAVE_POLL)
CHECK_FUNCTION_EXISTS_GLIBC(posix_spawnp HAVE_POSIX_SPAWNP)
CHECK_FUNCTION_EXISTS_GLIBC(readlink HAVE_READLINK)
+CHECK_FUNCTION_EXISTS_GLIBC(readpassphrase HAVE_READPASSPHRASE)
CHECK_FUNCTION_EXISTS_GLIBC(select HAVE_SELECT)
CHECK_FUNCTION_EXISTS_GLIBC(setenv HAVE_SETENV)
CHECK_FUNCTION_EXISTS_GLIBC(setlocale HAVE_SETLOCALE)
@@ -914,6 +994,7 @@ CHECK_FUNCTION_EXISTS(strftime HAVE_STRFTIME)
CHECK_FUNCTION_EXISTS(vprintf HAVE_VPRINTF)
CHECK_FUNCTION_EXISTS(wmemcmp HAVE_WMEMCMP)
CHECK_FUNCTION_EXISTS(wmemcpy HAVE_WMEMCPY)
+CHECK_FUNCTION_EXISTS(wmemmove HAVE_WMEMMOVE)
CMAKE_POP_CHECK_STATE() # Restore the state of the variables
@@ -1030,13 +1111,13 @@ CHECK_TYPE_SIZE("unsigned long long" SIZE_OF_UNSIGNED_LONG_LONG)
CHECK_TYPE_SIZE("__int64" __INT64)
CHECK_TYPE_SIZE("unsigned __int64" UNSIGNED___INT64)
-CHECK_TYPE_SIZE(int16_t INT16_T)
+CHECK_TYPE_SIZE(int16_t INT16_T)
CHECK_TYPE_SIZE(int32_t INT32_T)
CHECK_TYPE_SIZE(int64_t INT64_T)
CHECK_TYPE_SIZE(intmax_t INTMAX_T)
-CHECK_TYPE_SIZE(uint8_t UINT8_T)
-CHECK_TYPE_SIZE(uint16_t UINT16_T)
-CHECK_TYPE_SIZE(uint32_t UINT32_T)
+CHECK_TYPE_SIZE(uint8_t UINT8_T)
+CHECK_TYPE_SIZE(uint16_t UINT16_T)
+CHECK_TYPE_SIZE(uint32_t UINT32_T)
CHECK_TYPE_SIZE(uint64_t UINT64_T)
CHECK_TYPE_SIZE(uintmax_t UINTMAX_T)
diff --git a/Utilities/cmlibarchive/COPYING b/Utilities/cmlibarchive/COPYING
index b25880600..93952b77a 100644
--- a/Utilities/cmlibarchive/COPYING
+++ b/Utilities/cmlibarchive/COPYING
@@ -17,12 +17,11 @@ the actual statements in the files are controlling.
files for details:
libarchive/archive_entry.c
libarchive/archive_read_support_filter_compress.c
- libarchive/archive_write_set_filter_compress.c
+ libarchive/archive_write_add_filter_compress.c
libarchive/mtree.5
- tar/matching.c
* The following source files are in the public domain:
- tar/getdate.c
+ libarchive/archive_getdate.c
* The build files---including Makefiles, configure scripts,
and auxiliary scripts used as part of the compile process---have
diff --git a/Utilities/cmlibarchive/README-CMake.txt b/Utilities/cmlibarchive/README-CMake.txt
index ab105f064..0a3e34a96 100644
--- a/Utilities/cmlibarchive/README-CMake.txt
+++ b/Utilities/cmlibarchive/README-CMake.txt
@@ -11,7 +11,7 @@ branch, but it is merged into our history.
Update libarchive from upstream as follows. Create a local branch to
explicitly reference the upstream snapshot branch head:
- git branch libarchive-upstream 35df7c8b
+ git branch libarchive-upstream 1a8c7bc2
Use a temporary directory to checkout the branch:
@@ -24,7 +24,7 @@ Use a temporary directory to checkout the branch:
Now place the (reduced) libarchive content in this directory. See
instructions shown by
- git log 35df7c8b
+ git log 1a8c7bc2
for help extracting the content from the upstream svn repo. Then run
the following commands to commit the new version. Substitute the
@@ -34,8 +34,8 @@ appropriate date and version number:
GIT_AUTHOR_NAME='LibArchive Upstream' \
GIT_AUTHOR_EMAIL='libarchive-discuss@googlegroups.com' \
- GIT_AUTHOR_DATE='2013-02-09 12:17:57 -0500' \
- git commit -m 'libarchive 3.1.2 (reduced)' &&
+ GIT_AUTHOR_DATE='Wed Oct 21 01:47:34 2015 -0700' \
+ git commit -m 'libarchive 3.1.2-601-g3bfe5f1 (reduced)' &&
git commit --amend
Edit the commit message to describe the procedure used to obtain the
diff --git a/Utilities/cmlibarchive/build/cmake/CheckFuncs.cmake b/Utilities/cmlibarchive/build/cmake/CheckFuncs.cmake
index 0670df97f..84cc881e3 100644
--- a/Utilities/cmlibarchive/build/cmake/CheckFuncs.cmake
+++ b/Utilities/cmlibarchive/build/cmake/CheckFuncs.cmake
@@ -31,7 +31,7 @@ MACRO (CHECK_FUNCTION_EXISTS_GLIBC _FUNC _FUNCVAR)
SET(CHECK_STUB_FUNC_1 "__stub_${_FUNC}")
SET(CHECK_STUB_FUNC_2 "__stub___${_FUNC}")
CONFIGURE_FILE( ${_selfdir_CheckFunctionExistsGlibc}/CheckFuncs_stub.c.in
- ${CMAKE_CURRENT_BINARY_DIR}/cmake.tmp/CheckFuncs_stub.c IMMEDIATE)
+ ${CMAKE_CURRENT_BINARY_DIR}/cmake.tmp/CheckFuncs_stub.c)
TRY_COMPILE(__stub
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_BINARY_DIR}/cmake.tmp/CheckFuncs_stub.c
diff --git a/Utilities/cmlibarchive/build/cmake/CreatePkgConfigFile.cmake b/Utilities/cmlibarchive/build/cmake/CreatePkgConfigFile.cmake
new file mode 100644
index 000000000..fc8529a57
--- /dev/null
+++ b/Utilities/cmlibarchive/build/cmake/CreatePkgConfigFile.cmake
@@ -0,0 +1,33 @@
+# - Generate a libarchive.pc like autotools for pkg-config
+#
+
+# Set the required variables (we use the same input file as autotools)
+SET(prefix ${CMAKE_INSTALL_PREFIX})
+SET(exec_prefix \${prefix})
+SET(libdir \${exec_prefix}/lib)
+SET(includedir \${prefix}/include)
+# Now, this is not particularly pretty, nor is it terribly accurate...
+# Loop over all our additional libs
+FOREACH(mylib ${ADDITIONAL_LIBS})
+ # Extract the filename from the absolute path
+ GET_FILENAME_COMPONENT(mylib_name ${mylib} NAME_WE)
+ # Strip the lib prefix
+ STRING(REGEX REPLACE "^lib" "" mylib_name ${mylib_name})
+ # Append it to our LIBS string
+ SET(LIBS "${LIBS} -l${mylib_name}")
+ENDFOREACH()
+# libxml2 is easier, since it's already using pkg-config
+FOREACH(mylib ${PC_LIBXML_STATIC_LDFLAGS})
+ SET(LIBS "${LIBS} ${mylib}")
+ENDFOREACH()
+# FIXME: The order of the libraries doesn't take dependencies into account,
+# thus there's a good chance it'll make some binutils versions unhappy...
+# This only affects Libs.private (looked up for static builds) though.
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/build/pkgconfig/libarchive.pc.in
+ ${CMAKE_CURRENT_SOURCE_DIR}/build/pkgconfig/libarchive.pc
+ @ONLY)
+# And install it, of course ;).
+IF(ENABLE_INSTALL)
+ INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/build/pkgconfig/libarchive.pc
+ DESTINATION "lib/pkgconfig")
+ENDIF()
diff --git a/Utilities/cmlibarchive/build/cmake/LibarchiveCodeCoverage.cmake b/Utilities/cmlibarchive/build/cmake/LibarchiveCodeCoverage.cmake
new file mode 100644
index 000000000..297b886cc
--- /dev/null
+++ b/Utilities/cmlibarchive/build/cmake/LibarchiveCodeCoverage.cmake
@@ -0,0 +1,68 @@
+#################################################################
+# Adds a build target called "coverage" for code coverage.
+#
+# This compiles the code using special GCC flags, run the tests,
+# and then generates a nice HTML output. This new "coverage" make
+# target will only be available if you build using GCC in Debug
+# mode. If any of the required programs (lcov and genhtml) were
+# not found, a FATAL_ERROR message is printed.
+#
+# If not already done, this code will set ENABLE_TEST to ON.
+#
+# To build the code coverage and open it in your browser do this:
+#
+# mkdir debug
+# cd debug
+# cmake -DCMAKE_BUILD_TYPE=Debug -DENABLE_COVERAGE=ON ..
+# make -j4
+# make coverage
+# xdg-open coverage/index.html
+#################################################################
+
+# Find programs we need
+FIND_PROGRAM(LCOV_EXECUTABLE lcov DOC "Full path to lcov executable")
+FIND_PROGRAM(GENHTML_EXECUTABLE genhtml DOC "Full path to genhtml executable")
+MARK_AS_ADVANCED(LCOV_EXECUTABLE GENHTML_EXECUTABLE)
+
+# Check, compiler, build types and programs are available
+IF(NOT CMAKE_COMPILER_IS_GNUCC)
+MESSAGE(FATAL_ERROR "Coverage can only be built on GCC")
+ELSEIF(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
+MESSAGE(FATAL_ERROR "Coverage can only be built in Debug mode")
+ELSEIF(NOT LCOV_EXECUTABLE)
+MESSAGE(FATAL_ERROR "lcov executable not found")
+ELSEIF(NOT GENHTML_EXECUTABLE)
+MESSAGE(FATAL_ERROR "genhtml executable not found")
+ENDIF(NOT CMAKE_COMPILER_IS_GNUCC)
+
+# Enable testing if not already done
+SET(ENABLE_TEST ON)
+
+#################################################################
+# Set special compiler and linker flags for test coverage
+#################################################################
+# 0. Enable debug: -g
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g")
+# 1. Disable optimizations: -O0
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0")
+# 2. Enable all kind of warnings:
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -W")
+# 3. Enable special coverage flag (HINT: --coverage is a synonym for -fprofile-arcs -ftest-coverage)
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage")
+SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --coverage")
+SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage")
+#################################################################
+
+ADD_CUSTOM_TARGET(coverage
+COMMAND ${CMAKE_COMMAND} -E echo "Beginning test coverage. Output is written to coverage.log."
+COMMAND ${CMAKE_COMMAND} -E echo "COVERAGE-STEP-1/5: Reset all execution counts to zero"
+COMMAND ${LCOV_EXECUTABLE} --directory . --zerocounters > coverage.log 2>&1
+COMMAND ${CMAKE_COMMAND} -E echo "COVERAGE-STEP-2/5: Run testrunner"
+COMMAND ${CMAKE_CTEST_COMMAND} >> coverage.log 2>&1
+COMMAND ${CMAKE_COMMAND} -E echo "COVERAGE-STEP-3/5: Collect coverage data"
+COMMAND ${LCOV_EXECUTABLE} --capture --directory . --output-file "./coverage.info" >> coverage.log 2>&1
+COMMAND ${CMAKE_COMMAND} -E echo "COVERAGE-STEP-4/5: Generate HTML from coverage data"
+COMMAND ${GENHTML_EXECUTABLE} "coverage.info" --title="libarchive-${LIBARCHIVE_VERSION_STRING}" --show-details --legend --output-directory "./coverage" >> coverage.log 2>&1
+COMMAND ${CMAKE_COMMAND} -E echo "COVERAGE-STEP-5/5: Open test coverage HTML output in browser: xdg-open ./coverage/index.html"
+COMMENT "Runs testrunner and generates coverage output (formats: .info and .html)")
+
diff --git a/Utilities/cmlibarchive/build/cmake/config.h.in b/Utilities/cmlibarchive/build/cmake/config.h.in
index 750ae660a..1abeaaae7 100644
--- a/Utilities/cmlibarchive/build/cmake/config.h.in
+++ b/Utilities/cmlibarchive/build/cmake/config.h.in
@@ -66,7 +66,7 @@ typedef long long int64_t;
* Similarly for int32_t
*/
#if !defined(HAVE_INT32_T) && SIZE_OF_INT == 4
-typedef long int32_t;
+typedef int int32_t;
#define HAVE_INT32_T
#endif
@@ -292,6 +292,9 @@ typedef uint64_t uintmax_t;
/* Version number of bsdtar */
#cmakedefine BSDTAR_VERSION_STRING "${BSDTAR_VERSION_STRING}"
+/* Version number of bsdcat */
+#cmakedefine BSDCAT_VERSION_STRING "${BSDCAT_VERSION_STRING}"
+
/* Define to 1 if you have the `acl_create_entry' function. */
#cmakedefine HAVE_ACL_CREATE_ENTRY 1
@@ -328,9 +331,15 @@ typedef uint64_t uintmax_t;
/* True for systems with POSIX ACL support */
#cmakedefine HAVE_ACL_USER 1
+/* Define to 1 if you have the `arc4random_buf' function. */
+#cmakedefine HAVE_ARC4RANDOM_BUF 1
+
/* Define to 1 if you have the <attr/xattr.h> header file. */
#cmakedefine HAVE_ATTR_XATTR_H 1
+/* Define to 1 if you have the <Bcrypt.h> header file. */
+#cmakedefine HAVE_BCRYPT_H 1
+
/* Define to 1 if you have the <bsdxml.h> header file. */
#cmakedefine HAVE_BSDXML_H 1
@@ -579,12 +588,21 @@ typedef uint64_t uintmax_t;
/* Define to 1 if you have the `bz2' library (-lbz2). */
#cmakedefine HAVE_LIBBZ2 1
+/* Define to 1 if you have the `charset' library (-lcharset). */
+#cmakedefine HAVE_LIBCHARSET 1
+
+/* Define to 1 if you have the `crypto' library (-lcrypto). */
+#cmakedefine HAVE_LIBCRYPTO 1
+
/* Define to 1 if you have the `expat' library (-lexpat). */
#cmakedefine HAVE_LIBEXPAT 1
/* Define to 1 if you have the `gcc' library (-lgcc). */
#cmakedefine HAVE_LIBGCC 1
+/* Define to 1 if you have the `lz4' library (-llz4). */
+#cmakedefine HAVE_LIBLZ4 1
+
/* Define to 1 if you have the `lzma' library (-llzma). */
#cmakedefine HAVE_LIBLZMA 1
@@ -679,6 +697,12 @@ typedef uint64_t uintmax_t;
/* Define to 1 if you have the `lutimes' function. */
#cmakedefine HAVE_LUTIMES 1
+/* Define to 1 if you have the <lz4hc.h> header file. */
+#cmakedefine HAVE_LZ4HC_H 1
+
+/* Define to 1 if you have the <lz4.h> header file. */
+#cmakedefine HAVE_LZ4_H 1
+
/* Define to 1 if you have the <lzmadec.h> header file. */
#cmakedefine HAVE_LZMADEC_H 1
@@ -718,6 +742,9 @@ typedef uint64_t uintmax_t;
/* Define to 1 if you have the <nettle/md5.h> header file. */
#cmakedefine HAVE_NETTLE_MD5_H 1
+/* Define to 1 if you have the <nettle/pbkdf2.h> header file. */
+#cmakedefine HAVE_NETTLE_PBKDF2_H 1
+
/* Define to 1 if you have the <nettle/ripemd160.h> header file. */
#cmakedefine HAVE_NETTLE_RIPEMD160_H 1
@@ -739,6 +766,9 @@ typedef uint64_t uintmax_t;
/* Define to 1 if you have the `pipe' function. */
#cmakedefine HAVE_PIPE 1
+/* Define to 1 if you have the `PKCS5_PBKDF2_HMAC_SHA1' function. */
+#cmakedefine HAVE_PKCS5_PBKDF2_HMAC_SHA1 1
+
/* Define to 1 if you have the `poll' function. */
#cmakedefine HAVE_POLL 1
@@ -751,6 +781,9 @@ typedef uint64_t uintmax_t;
/* Define to 1 if you have the <process.h> header file. */
#cmakedefine HAVE_PROCESS_H 1
+/* Define to 1 if you have the <pthread.h> header file. */
+#cmakedefine HAVE_PTHREAD_H 1
+
/* Define to 1 if you have the <pwd.h> header file. */
#cmakedefine HAVE_PWD_H 1
@@ -763,6 +796,12 @@ typedef uint64_t uintmax_t;
/* Define to 1 if you have the `readlinkat' function. */
#cmakedefine HAVE_READLINKAT 1
+/* Define to 1 if you have the `readpassphrase' function. */
+#cmakedefine HAVE_READPASSPHRASE 1
+
+/* Define to 1 if you have the <readpassphrase.h> header file. */
+#cmakedefine HAVE_READPASSPHRASE_H 1
+
/* Define to 1 if you have the <regex.h> header file. */
#cmakedefine HAVE_REGEX_H 1
@@ -1018,6 +1057,9 @@ typedef uint64_t uintmax_t;
/* Define to 1 if you have the `wmemcpy' function. */
#cmakedefine HAVE_WMEMCPY 1
+/* Define to 1 if you have the `wmemmove' function. */
+#cmakedefine HAVE_WMEMMOVE 1
+
/* Define to 1 if you have a working EXT2_IOC_GETFLAGS */
#cmakedefine HAVE_WORKING_EXT2_IOC_GETFLAGS 1
@@ -1112,8 +1154,13 @@ typedef uint64_t uintmax_t;
#cmakedefine _LARGE_FILES ${_LARGE_FILES}
/* Define for Windows to use Windows 2000+ APIs. */
+#ifndef _WIN32_WINNT
#cmakedefine _WIN32_WINNT ${_WIN32_WINNT}
+#endif // _WIN32_WINNT
+
+#ifndef WINVER
#cmakedefine WINVER ${WINVER}
+#endif // WINVER
/* Define to empty if `const' does not conform to ANSI C. */
#cmakedefine const ${const}
diff --git a/Utilities/cmlibarchive/libarchive/CMakeLists.txt b/Utilities/cmlibarchive/libarchive/CMakeLists.txt
index 42781bc3c..891c72877 100644
--- a/Utilities/cmlibarchive/libarchive/CMakeLists.txt
+++ b/Utilities/cmlibarchive/libarchive/CMakeLists.txt
@@ -18,8 +18,10 @@ SET(libarchive_SOURCES
archive_cmdline.c
archive_cmdline_private.h
archive_crc32.h
- archive_crypto.c
- archive_crypto_private.h
+ archive_cryptor.c
+ archive_cryptor_private.h
+ archive_digest.c
+ archive_digest_private.h
archive_endian.h
archive_entry.c
archive_entry.h
@@ -32,9 +34,13 @@ SET(libarchive_SOURCES
archive_entry_strmode.c
archive_entry_xattr.c
archive_getdate.c
+ archive_hmac.c
+ archive_hmac_private.h
archive_match.c
archive_options.c
archive_options_private.h
+ archive_pack_dev.h
+ archive_pack_dev.c
archive_pathmatch.c
archive_pathmatch.h
archive_platform.h
@@ -42,9 +48,12 @@ SET(libarchive_SOURCES
archive_ppmd7.c
archive_ppmd7_private.h
archive_private.h
+ archive_random.c
+ archive_random_private.h
archive_rb.c
archive_rb.h
archive_read.c
+ archive_read_add_passphrase.c
archive_read_append_filter.c
archive_read_data_into_fd.c
archive_read_disk_entry_from_file.c
@@ -52,6 +61,7 @@ SET(libarchive_SOURCES
archive_read_disk_private.h
archive_read_disk_set_standard_lookup.c
archive_read_extract.c
+ archive_read_extract2.c
archive_read_open_fd.c
archive_read_open_file.c
archive_read_open_filename.c
@@ -65,6 +75,7 @@ SET(libarchive_SOURCES
archive_read_support_filter_gzip.c
archive_read_support_filter_grzip.c
archive_read_support_filter_lrzip.c
+ archive_read_support_filter_lz4.c
archive_read_support_filter_lzop.c
archive_read_support_filter_none.c
archive_read_support_filter_program.c
@@ -84,6 +95,7 @@ SET(libarchive_SOURCES
archive_read_support_format_rar.c
archive_read_support_format_raw.c
archive_read_support_format_tar.c
+ archive_read_support_format_warc.c
archive_read_support_format_xar.c
archive_read_support_format_zip.c
archive_string.c
@@ -110,6 +122,7 @@ SET(libarchive_SOURCES
archive_write_add_filter_grzip.c
archive_write_add_filter_gzip.c
archive_write_add_filter_lrzip.c
+ archive_write_add_filter_lz4.c
archive_write_add_filter_lzop.c
archive_write_add_filter_none.c
archive_write_add_filter_program.c
@@ -121,18 +134,24 @@ SET(libarchive_SOURCES
archive_write_set_format_by_name.c
archive_write_set_format_cpio.c
archive_write_set_format_cpio_newc.c
+ archive_write_set_format_filter_by_ext.c
archive_write_set_format_gnutar.c
archive_write_set_format_iso9660.c
archive_write_set_format_mtree.c
archive_write_set_format_pax.c
+ archive_write_set_format_raw.c
archive_write_set_format_shar.c
archive_write_set_format_ustar.c
archive_write_set_format_v7tar.c
+ archive_write_set_format_warc.c
archive_write_set_format_xar.c
archive_write_set_format_zip.c
archive_write_set_options.c
+ archive_write_set_passphrase.c
+ archive_xxhash.h
filter_fork_posix.c
filter_fork.h
+ xxhash.c
)
# Man pages
@@ -145,12 +164,14 @@ SET(libarchive_MANS
archive_entry_stat.3
archive_entry_time.3
archive_read.3
+ archive_read_add_passphrase.3
archive_read_disk.3
archive_read_set_options.3
archive_util.3
archive_write.3
archive_write_disk.3
archive_write_set_options.3
+ archive_write_set_passphrase.3
cpio.5
libarchive.3
libarchive_internals.3
diff --git a/Utilities/cmlibarchive/libarchive/archive.h b/Utilities/cmlibarchive/libarchive/archive.h
index 1a1d32a6d..a8d4c6cad 100644
--- a/Utilities/cmlibarchive/libarchive/archive.h
+++ b/Utilities/cmlibarchive/libarchive/archive.h
@@ -28,6 +28,16 @@
#ifndef ARCHIVE_H_INCLUDED
#define ARCHIVE_H_INCLUDED
+/*
+ * The version number is expressed as a single integer that makes it
+ * easy to compare versions at build time: for version a.b.c, the
+ * version number is printf("%d%03d%03d",a,b,c). For example, if you
+ * know your application requires version 2.12.108 or later, you can
+ * assert that ARCHIVE_VERSION_NUMBER >= 2012108.
+ */
+/* Note: Compiler will complain if this does not match archive_entry.h! */
+#define ARCHIVE_VERSION_NUMBER 3001002
+
#include <sys/stat.h>
#include <stddef.h> /* for wchar_t */
#include <stdio.h> /* For FILE * */
@@ -45,32 +55,44 @@
# include <inttypes.h>
#endif
-/* Borland symbols are case-insensitive. This workaround only works
- within CMake because we do not mix compilers. */
-#if defined(__BORLANDC__)
-# define archive_read_open_FILE archive_read_open_FILE_
-# define archive_write_open_FILE archive_write_open_FILE_
+/* Get appropriate definitions of 64-bit integer */
+#if !defined(__LA_INT64_T_DEFINED)
+/* Older code relied on the __LA_INT64_T macro; after 4.0 we'll switch to the typedef exclusively. */
+# if ARCHIVE_VERSION_NUMBER < 4000000
+#define __LA_INT64_T la_int64_t
+# endif
+#define __LA_INT64_T_DEFINED
+# if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__)
+typedef __int64 la_int64_t;
+# else
+# include <unistd.h> /* ssize_t */
+# if defined(_SCO_DS) || defined(__osf__)
+typedef long long la_int64_t;
+# else
+typedef int64_t la_int64_t;
+# endif
+# endif
#endif
-/* Get appropriate definitions of standard POSIX-style types. */
-/* These should match the types used in 'struct stat' */
-#if defined(_WIN32) && !defined(__CYGWIN__)
-# define __LA_INT64_T __int64
-# if defined(_SSIZE_T_DEFINED) || defined(_SSIZE_T_)
-# define __LA_SSIZE_T ssize_t
-# elif defined(_WIN64)
-# define __LA_SSIZE_T __int64
-# else
-# define __LA_SSIZE_T long
+/* The la_ssize_t should match the type used in 'struct stat' */
+#if !defined(__LA_SSIZE_T_DEFINED)
+/* Older code relied on the __LA_SSIZE_T macro; after 4.0 we'll switch to the typedef exclusively. */
+# if ARCHIVE_VERSION_NUMBER < 4000000
+#define __LA_SSIZE_T la_ssize_t
# endif
-#else
-# include <unistd.h> /* ssize_t, uid_t, and gid_t */
-# if defined(_SCO_DS) || defined(__osf__)
-# define __LA_INT64_T long long
+#define __LA_SSIZE_T_DEFINED
+# if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__)
+# if defined(_SSIZE_T_DEFINED) || defined(_SSIZE_T_)
+typedef ssize_t la_ssize_t;
+# elif defined(_WIN64)
+typedef __int64 la_ssize_t;
+# else
+typedef long la_ssize_t;
+# endif
# else
-# define __LA_INT64_T int64_t
+# include <unistd.h> /* ssize_t */
+typedef ssize_t la_ssize_t;
# endif
-# define __LA_SSIZE_T ssize_t
#endif
/*
@@ -119,24 +141,24 @@ extern "C" {
* header and library are very different, you should expect some
* strangeness. Don't do that.
*/
-
-/*
- * The version number is expressed as a single integer that makes it
- * easy to compare versions at build time: for version a.b.c, the
- * version number is printf("%d%03d%03d",a,b,c). For example, if you
- * know your application requires version 2.12.108 or later, you can
- * assert that ARCHIVE_VERSION_NUMBER >= 2012108.
- */
-/* Note: Compiler will complain if this does not match archive_entry.h! */
-#define ARCHIVE_VERSION_NUMBER 3001002
__LA_DECL int archive_version_number(void);
/*
* Textual name/version of the library, useful for version displays.
*/
-#define ARCHIVE_VERSION_STRING "libarchive 3.1.2"
+#define ARCHIVE_VERSION_ONLY_STRING "3.1.2"
+#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
__LA_DECL const char * archive_version_string(void);
+/*
+ * Detailed textual name/version of the library and its dependencies.
+ * This has the form:
+ * "libarchive x.y.z zlib/a.b.c liblzma/d.e.f ... etc ..."
+ * the list of libraries described here will vary depending on how
+ * libarchive was compiled.
+ */
+__LA_DECL const char * archive_version_details(void);
+
/* Declare our basic types. */
struct archive;
struct archive_entry;
@@ -177,7 +199,7 @@ struct archive_entry;
*/
/* Returns pointer and size of next block of data from archive. */
-typedef __LA_SSIZE_T archive_read_callback(struct archive *,
+typedef la_ssize_t archive_read_callback(struct archive *,
void *_client_data, const void **_buffer);
/* Skips at most request bytes from archive and returns the skipped amount.
@@ -185,18 +207,18 @@ typedef __LA_SSIZE_T archive_read_callback(struct archive *,
* If you do skip fewer bytes than requested, libarchive will invoke your
* read callback and discard data as necessary to make up the full skip.
*/
-typedef __LA_INT64_T archive_skip_callback(struct archive *,
- void *_client_data, __LA_INT64_T request);
+typedef la_int64_t archive_skip_callback(struct archive *,
+ void *_client_data, la_int64_t request);
/* Seeks to specified location in the file and returns the position.
* Whence values are SEEK_SET, SEEK_CUR, SEEK_END from stdio.h.
* Return ARCHIVE_FATAL if the seek fails for any reason.
*/
-typedef __LA_INT64_T archive_seek_callback(struct archive *,
- void *_client_data, __LA_INT64_T offset, int whence);
+typedef la_int64_t archive_seek_callback(struct archive *,
+ void *_client_data, la_int64_t offset, int whence);
/* Returns size actually written, zero on EOF, -1 on error. */
-typedef __LA_SSIZE_T archive_write_callback(struct archive *,
+typedef la_ssize_t archive_write_callback(struct archive *,
void *_client_data,
const void *_buffer, size_t _length);
@@ -212,6 +234,13 @@ typedef int archive_switch_callback(struct archive *, void *_client_data1,
void *_client_data2);
/*
+ * Returns a passphrase used for encryption or decryption, NULL on nothing
+ * to do and give it up.
+ */
+typedef const char *archive_passphrase_callback(struct archive *,
+ void *_client_data);
+
+/*
* Codes to identify various stream filters.
*/
#define ARCHIVE_FILTER_NONE 0
@@ -227,6 +256,7 @@ typedef int archive_switch_callback(struct archive *, void *_client_data1,
#define ARCHIVE_FILTER_LRZIP 10
#define ARCHIVE_FILTER_LZOP 11
#define ARCHIVE_FILTER_GRZIP 12
+#define ARCHIVE_FILTER_LZ4 13
#if ARCHIVE_VERSION_NUMBER < 4000000
#define ARCHIVE_COMPRESSION_NONE ARCHIVE_FILTER_NONE
@@ -288,6 +318,31 @@ typedef int archive_switch_callback(struct archive *, void *_client_data1,
#define ARCHIVE_FORMAT_CAB 0xC0000
#define ARCHIVE_FORMAT_RAR 0xD0000
#define ARCHIVE_FORMAT_7ZIP 0xE0000
+#define ARCHIVE_FORMAT_WARC 0xF0000
+
+/*
+ * Codes returned by archive_read_format_capabilities().
+ *
+ * This list can be extended with values between 0 and 0xffff.
+ * The original purpose of this list was to let different archive
+ * format readers expose their general capabilities in terms of
+ * encryption.
+ */
+#define ARCHIVE_READ_FORMAT_CAPS_NONE (0) /* no special capabilities */
+#define ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA (1<<0) /* reader can detect encrypted data */
+#define ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA (1<<1) /* reader can detect encryptable metadata (pathname, mtime, etc.) */
+
+/*
+ * Codes returned by archive_read_has_encrypted_entries().
+ *
+ * In case the archive does not support encryption detection at all
+ * ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED is returned. If the reader
+ * for some other reason (e.g. not enough bytes read) cannot say if
+ * there are encrypted entries, ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW
+ * is returned.
+ */
+#define ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED -2
+#define ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW -1
/*-
* Basic outline for reading an archive:
@@ -346,6 +401,7 @@ __LA_DECL int archive_read_support_filter_compress(struct archive *);
__LA_DECL int archive_read_support_filter_gzip(struct archive *);
__LA_DECL int archive_read_support_filter_grzip(struct archive *);
__LA_DECL int archive_read_support_filter_lrzip(struct archive *);
+__LA_DECL int archive_read_support_filter_lz4(struct archive *);
__LA_DECL int archive_read_support_filter_lzip(struct archive *);
__LA_DECL int archive_read_support_filter_lzma(struct archive *);
__LA_DECL int archive_read_support_filter_lzop(struct archive *);
@@ -373,8 +429,17 @@ __LA_DECL int archive_read_support_format_mtree(struct archive *);
__LA_DECL int archive_read_support_format_rar(struct archive *);
__LA_DECL int archive_read_support_format_raw(struct archive *);
__LA_DECL int archive_read_support_format_tar(struct archive *);
+__LA_DECL int archive_read_support_format_warc(struct archive *);
__LA_DECL int archive_read_support_format_xar(struct archive *);
+/* archive_read_support_format_zip() enables both streamable and seekable
+ * zip readers. */
__LA_DECL int archive_read_support_format_zip(struct archive *);
+/* Reads Zip archives as stream from beginning to end. Doesn't
+ * correctly handle SFX ZIP files or ZIP archives that have been modified
+ * in-place. */
+__LA_DECL int archive_read_support_format_zip_streamable(struct archive *);
+/* Reads starting from central directory; requires seekable input. */
+__LA_DECL int archive_read_support_format_zip_seekable(struct archive *);
/* Functions to manually set the format and filters to be used. This is
* useful to bypass the bidding process when the format and filters to use
@@ -445,9 +510,9 @@ __LA_DECL int archive_read_open_file(struct archive *,
const char *_filename, size_t _block_size) __LA_DEPRECATED;
/* Read an archive that's stored in memory. */
__LA_DECL int archive_read_open_memory(struct archive *,
- void * buff, size_t size);
+ const void * buff, size_t size);
/* A more involved version that is only used for internal testing. */
-__LA_DECL int archive_read_open_memory2(struct archive *a, void *buff,
+__LA_DECL int archive_read_open_memory2(struct archive *a, const void *buff,
size_t size, size_t read_size);
/* Read an archive that's already open, using the file descriptor. */
__LA_DECL int archive_read_open_fd(struct archive *, int _fd,
@@ -468,14 +533,40 @@ __LA_DECL int archive_read_next_header2(struct archive *,
* Retrieve the byte offset in UNCOMPRESSED data where last-read
* header started.
*/
-__LA_DECL __LA_INT64_T archive_read_header_position(struct archive *);
+__LA_DECL la_int64_t archive_read_header_position(struct archive *);
+
+/*
+ * Returns 1 if the archive contains at least one encrypted entry.
+ * If the archive format not support encryption at all
+ * ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED is returned.
+ * If for any other reason (e.g. not enough data read so far)
+ * we cannot say whether there are encrypted entries, then
+ * ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW is returned.
+ * In general, this function will return values below zero when the
+ * reader is uncertain or totally uncapable of encryption support.
+ * When this function returns 0 you can be sure that the reader
+ * supports encryption detection but no encrypted entries have
+ * been found yet.
+ *
+ * NOTE: If the metadata/header of an archive is also encrypted, you
+ * cannot rely on the number of encrypted entries. That is why this
+ * function does not return the number of encrypted entries but#
+ * just shows that there are some.
+ */
+__LA_DECL int archive_read_has_encrypted_entries(struct archive *);
+
+/*
+ * Returns a bitmask of capabilities that are supported by the archive format reader.
+ * If the reader has no special capabilities, ARCHIVE_READ_FORMAT_CAPS_NONE is returned.
+ */
+__LA_DECL int archive_read_format_capabilities(struct archive *);
/* Read data from the body of an entry. Similar to read(2). */
-__LA_DECL __LA_SSIZE_T archive_read_data(struct archive *,
+__LA_DECL la_ssize_t archive_read_data(struct archive *,
void *, size_t);
/* Seek within the body of an entry. Similar to lseek(2). */
-__LA_DECL __LA_INT64_T archive_seek_data(struct archive *, __LA_INT64_T, int);
+__LA_DECL la_int64_t archive_seek_data(struct archive *, la_int64_t, int);
/*
* A zero-copy version of archive_read_data that also exposes the file offset
@@ -484,7 +575,7 @@ __LA_DECL __LA_INT64_T archive_seek_data(struct archive *, __LA_INT64_T, int);
* be strictly increasing and that returned blocks will not overlap.
*/
__LA_DECL int archive_read_data_block(struct archive *a,
- const void **buff, size_t *size, __LA_INT64_T *offset);
+ const void **buff, size_t *size, la_int64_t *offset);
/*-
* Some convenience functions that are built on archive_read_data:
@@ -514,6 +605,14 @@ __LA_DECL int archive_read_set_option(struct archive *_a,
__LA_DECL int archive_read_set_options(struct archive *_a,
const char *opts);
+/*
+ * Add a decryption passphrase.
+ */
+__LA_DECL int archive_read_add_passphrase(struct archive *, const char *);
+__LA_DECL int archive_read_set_passphrase_callback(struct archive *,
+ void *client_data, archive_passphrase_callback *);
+
+
/*-
* Convenience function to recreate the current entry (whose header
* has just been read) on disk.
@@ -566,6 +665,10 @@ __LA_DECL int archive_read_set_options(struct archive *_a,
/* Default: Do not use HFS+ compression if it was not compressed. */
/* This has no effect except on Mac OS v10.6 or later. */
#define ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED (0x8000)
+/* Default: Do not reject entries with absolute paths */
+#define ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS (0x10000)
+/* Default: Do not clear no-change flags when unlinking object */
+#define ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS (0x20000)
__LA_DECL int archive_read_extract(struct archive *, struct archive_entry *,
int flags);
@@ -577,7 +680,7 @@ __LA_DECL void archive_read_extract_set_progress_callback(struct archive *,
/* Record the dev/ino of a file that will not be written. This is
* generally set to the dev/ino of the archive being read. */
__LA_DECL void archive_read_extract_set_skip_file(struct archive *,
- __LA_INT64_T, __LA_INT64_T);
+ la_int64_t, la_int64_t);
/* Close the file and release most resources. */
__LA_DECL int archive_read_close(struct archive *);
@@ -616,7 +719,7 @@ __LA_DECL int archive_write_get_bytes_in_last_block(struct archive *);
/* The dev/ino of a file that won't be archived. This is used
* to avoid recursively adding an archive to itself. */
__LA_DECL int archive_write_set_skip_file(struct archive *,
- __LA_INT64_T, __LA_INT64_T);
+ la_int64_t, la_int64_t);
#if ARCHIVE_VERSION_NUMBER < 4000000
__LA_DECL int archive_write_set_compression_bzip2(struct archive *)
@@ -647,6 +750,7 @@ __LA_DECL int archive_write_add_filter_compress(struct archive *);
__LA_DECL int archive_write_add_filter_grzip(struct archive *);
__LA_DECL int archive_write_add_filter_gzip(struct archive *);
__LA_DECL int archive_write_add_filter_lrzip(struct archive *);
+__LA_DECL int archive_write_add_filter_lz4(struct archive *);
__LA_DECL int archive_write_add_filter_lzip(struct archive *);
__LA_DECL int archive_write_add_filter_lzma(struct archive *);
__LA_DECL int archive_write_add_filter_lzop(struct archive *);
@@ -674,12 +778,16 @@ __LA_DECL int archive_write_set_format_mtree_classic(struct archive *);
/* TODO: int archive_write_set_format_old_tar(struct archive *); */
__LA_DECL int archive_write_set_format_pax(struct archive *);
__LA_DECL int archive_write_set_format_pax_restricted(struct archive *);
+__LA_DECL int archive_write_set_format_raw(struct archive *);
__LA_DECL int archive_write_set_format_shar(struct archive *);
__LA_DECL int archive_write_set_format_shar_dump(struct archive *);
__LA_DECL int archive_write_set_format_ustar(struct archive *);
__LA_DECL int archive_write_set_format_v7tar(struct archive *);
+__LA_DECL int archive_write_set_format_warc(struct archive *);
__LA_DECL int archive_write_set_format_xar(struct archive *);
__LA_DECL int archive_write_set_format_zip(struct archive *);
+__LA_DECL int archive_write_set_format_filter_by_ext(struct archive *a, const char *filename);
+__LA_DECL int archive_write_set_format_filter_by_ext_def(struct archive *a, const char *filename, const char * def_ext);
__LA_DECL int archive_write_zip_set_compression_deflate(struct archive *);
__LA_DECL int archive_write_zip_set_compression_store(struct archive *);
__LA_DECL int archive_write_open(struct archive *, void *,
@@ -704,12 +812,12 @@ __LA_DECL int archive_write_open_memory(struct archive *,
*/
__LA_DECL int archive_write_header(struct archive *,
struct archive_entry *);
-__LA_DECL __LA_SSIZE_T archive_write_data(struct archive *,
+__LA_DECL la_ssize_t archive_write_data(struct archive *,
const void *, size_t);
/* This interface is currently only available for archive_write_disk handles. */
-__LA_DECL __LA_SSIZE_T archive_write_data_block(struct archive *,
- const void *, size_t, __LA_INT64_T);
+__LA_DECL la_ssize_t archive_write_data_block(struct archive *,
+ const void *, size_t, la_int64_t);
__LA_DECL int archive_write_finish_entry(struct archive *);
__LA_DECL int archive_write_close(struct archive *);
@@ -744,6 +852,13 @@ __LA_DECL int archive_write_set_option(struct archive *_a,
__LA_DECL int archive_write_set_options(struct archive *_a,
const char *opts);
+/*
+ * Set a encryption passphrase.
+ */
+__LA_DECL int archive_write_set_passphrase(struct archive *_a, const char *p);
+__LA_DECL int archive_write_set_passphrase_callback(struct archive *,
+ void *client_data, archive_passphrase_callback *);
+
/*-
* ARCHIVE_WRITE_DISK API
*
@@ -763,7 +878,7 @@ __LA_DECL int archive_write_set_options(struct archive *_a,
__LA_DECL struct archive *archive_write_disk_new(void);
/* This file will not be overwritten. */
__LA_DECL int archive_write_disk_set_skip_file(struct archive *,
- __LA_INT64_T, __LA_INT64_T);
+ la_int64_t, la_int64_t);
/* Set flags to control how the next item gets created.
* This accepts a bitmask of ARCHIVE_EXTRACT_XXX flags defined above. */
__LA_DECL int archive_write_disk_set_options(struct archive *,
@@ -793,14 +908,14 @@ __LA_DECL int archive_write_disk_set_standard_lookup(struct archive *);
*/
__LA_DECL int archive_write_disk_set_group_lookup(struct archive *,
void * /* private_data */,
- __LA_INT64_T (*)(void *, const char *, __LA_INT64_T),
+ la_int64_t (*)(void *, const char *, la_int64_t),
void (* /* cleanup */)(void *));
__LA_DECL int archive_write_disk_set_user_lookup(struct archive *,
void * /* private_data */,
- __LA_INT64_T (*)(void *, const char *, __LA_INT64_T),
+ la_int64_t (*)(void *, const char *, la_int64_t),
void (* /* cleanup */)(void *));
-__LA_DECL __LA_INT64_T archive_write_disk_gid(struct archive *, const char *, __LA_INT64_T);
-__LA_DECL __LA_INT64_T archive_write_disk_uid(struct archive *, const char *, __LA_INT64_T);
+__LA_DECL la_int64_t archive_write_disk_gid(struct archive *, const char *, la_int64_t);
+__LA_DECL la_int64_t archive_write_disk_uid(struct archive *, const char *, la_int64_t);
/*
* ARCHIVE_READ_DISK API
@@ -821,19 +936,19 @@ __LA_DECL int archive_read_disk_entry_from_file(struct archive *,
struct archive_entry *, int /* fd */, const struct stat *);
/* Look up gname for gid or uname for uid. */
/* Default implementations are very, very stupid. */
-__LA_DECL const char *archive_read_disk_gname(struct archive *, __LA_INT64_T);
-__LA_DECL const char *archive_read_disk_uname(struct archive *, __LA_INT64_T);
+__LA_DECL const char *archive_read_disk_gname(struct archive *, la_int64_t);
+__LA_DECL const char *archive_read_disk_uname(struct archive *, la_int64_t);
/* "Standard" implementation uses getpwuid_r, getgrgid_r and caches the
* results for performance. */
__LA_DECL int archive_read_disk_set_standard_lookup(struct archive *);
/* You can install your own lookups if you like. */
__LA_DECL int archive_read_disk_set_gname_lookup(struct archive *,
void * /* private_data */,
- const char *(* /* lookup_fn */)(void *, __LA_INT64_T),
+ const char *(* /* lookup_fn */)(void *, la_int64_t),
void (* /* cleanup_fn */)(void *));
__LA_DECL int archive_read_disk_set_uname_lookup(struct archive *,
void * /* private_data */,
- const char *(* /* lookup_fn */)(void *, __LA_INT64_T),
+ const char *(* /* lookup_fn */)(void *, la_int64_t),
void (* /* cleanup_fn */)(void *));
/* Start traversal. */
__LA_DECL int archive_read_disk_open(struct archive *, const char *);
@@ -863,8 +978,10 @@ __LA_DECL int archive_read_disk_set_atime_restored(struct archive *);
/* Default: Skip a mac resource fork file whose prefix is "._" because of
* using copyfile. */
#define ARCHIVE_READDISK_MAC_COPYFILE (0x0004)
-/* Default: Do not traverse mount points. */
+/* Default: Traverse mount points. */
#define ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS (0x0008)
+/* Default: Xattrs are read from disk. */
+#define ARCHIVE_READDISK_NO_XATTR (0x0010)
__LA_DECL int archive_read_disk_set_behavior(struct archive *,
int flags);
@@ -883,6 +1000,10 @@ __LA_DECL int archive_read_disk_set_metadata_filter_callback(struct archive *,
int (*_metadata_filter_func)(struct archive *, void *,
struct archive_entry *), void *_client_data);
+/* Simplified cleanup interface;
+ * This calls archive_read_free() or archive_write_free() as needed. */
+__LA_DECL int archive_free(struct archive *);
+
/*
* Accessor functions to read/set various information in
* the struct archive object:
@@ -893,7 +1014,7 @@ __LA_DECL int archive_read_disk_set_metadata_filter_callback(struct archive *,
* last filter, which is always the pseudo-filter that wraps the
* client callbacks. */
__LA_DECL int archive_filter_count(struct archive *);
-__LA_DECL __LA_INT64_T archive_filter_bytes(struct archive *, int);
+__LA_DECL la_int64_t archive_filter_bytes(struct archive *, int);
__LA_DECL int archive_filter_code(struct archive *, int);
__LA_DECL const char * archive_filter_name(struct archive *, int);
@@ -901,10 +1022,10 @@ __LA_DECL const char * archive_filter_name(struct archive *, int);
/* These don't properly handle multiple filters, so are deprecated and
* will eventually be removed. */
/* As of libarchive 3.0, this is an alias for archive_filter_bytes(a, -1); */
-__LA_DECL __LA_INT64_T archive_position_compressed(struct archive *)
+__LA_DECL la_int64_t archive_position_compressed(struct archive *)
__LA_DEPRECATED;
/* As of libarchive 3.0, this is an alias for archive_filter_bytes(a, 0); */
-__LA_DECL __LA_INT64_T archive_position_uncompressed(struct archive *)
+__LA_DECL la_int64_t archive_position_uncompressed(struct archive *)
__LA_DEPRECATED;
/* As of libarchive 3.0, this is an alias for archive_filter_name(a, 0); */
__LA_DECL const char *archive_compression_name(struct archive *)
@@ -1020,8 +1141,8 @@ __LA_DECL int archive_match_exclude_entry(struct archive *,
__LA_DECL int archive_match_owner_excluded(struct archive *,
struct archive_entry *);
/* Add inclusion uid, gid, uname and gname. */
-__LA_DECL int archive_match_include_uid(struct archive *, __LA_INT64_T);
-__LA_DECL int archive_match_include_gid(struct archive *, __LA_INT64_T);
+__LA_DECL int archive_match_include_uid(struct archive *, la_int64_t);
+__LA_DECL int archive_match_include_gid(struct archive *, la_int64_t);
__LA_DECL int archive_match_include_uname(struct archive *, const char *);
__LA_DECL int archive_match_include_uname_w(struct archive *,
const wchar_t *);
@@ -1029,6 +1150,10 @@ __LA_DECL int archive_match_include_gname(struct archive *, const char *);
__LA_DECL int archive_match_include_gname_w(struct archive *,
const wchar_t *);
+/* Utility functions */
+/* Convenience function to sort a NULL terminated list of strings */
+__LA_DECL int archive_utility_string_sort(char **);
+
#ifdef __cplusplus
}
#endif
@@ -1036,9 +1161,4 @@ __LA_DECL int archive_match_include_gname_w(struct archive *,
/* These are meaningless outside of this header. */
#undef __LA_DECL
-/* These need to remain defined because they're used in the
- * callback type definitions. XXX Fix this. This is ugly. XXX */
-/* #undef __LA_INT64_T */
-/* #undef __LA_SSIZE_T */
-
#endif /* !ARCHIVE_H_INCLUDED */
diff --git a/Utilities/cmlibarchive/libarchive/archive_crypto.c b/Utilities/cmlibarchive/libarchive/archive_crypto.c
deleted file mode 100644
index 85aba3ae2..000000000
--- a/Utilities/cmlibarchive/libarchive/archive_crypto.c
+++ /dev/null
@@ -1,1429 +0,0 @@
-/*-
-* Copyright (c) 2003-2007 Tim Kientzle
-* Copyright (c) 2011 Andres Mejia
-* Copyright (c) 2011 Michihiro NAKAJIMA
-* All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions
-* are met:
-* 1. Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* 2. Redistributions in binary form must reproduce the above copyright
-* notice, this list of conditions and the following disclaimer in the
-* documentation and/or other materials provided with the distribution.
-*
-* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
-* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
-* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include "archive_platform.h"
-
-#include "archive.h"
-#include "archive_crypto_private.h"
-
-/* In particular, force the configure probe to break if it tries
- * to test a combination of OpenSSL and libmd. */
-#if defined(ARCHIVE_CRYPTO_OPENSSL) && defined(ARCHIVE_CRYPTO_LIBMD)
-#error Cannot use both OpenSSL and libmd.
-#endif
-
-/*
- * Message digest functions for Windows platform.
- */
-#if defined(ARCHIVE_CRYPTO_MD5_WIN) ||\
- defined(ARCHIVE_CRYPTO_SHA1_WIN) ||\
- defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
- defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
- defined(ARCHIVE_CRYPTO_SHA512_WIN)
-
-/*
- * Initialize a Message digest.
- */
-static int
-win_crypto_init(Digest_CTX *ctx, ALG_ID algId)
-{
-
- ctx->valid = 0;
- if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL,
- PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
- if (GetLastError() != (DWORD)NTE_BAD_KEYSET)
- return (ARCHIVE_FAILED);
- if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL,
- PROV_RSA_FULL, CRYPT_NEWKEYSET))
- return (ARCHIVE_FAILED);
- }
-
- if (!CryptCreateHash(ctx->cryptProv, algId, 0, 0, &ctx->hash)) {
- CryptReleaseContext(ctx->cryptProv, 0);
- return (ARCHIVE_FAILED);
- }
-
- ctx->valid = 1;
- return (ARCHIVE_OK);
-}
-
-/*
- * Update a Message digest.
- */
-static int
-win_crypto_Update(Digest_CTX *ctx, const unsigned char *buf, size_t len)
-{
-
- if (!ctx->valid)
- return (ARCHIVE_FAILED);
-
- CryptHashData(ctx->hash,
- (unsigned char *)(uintptr_t)buf,
- (DWORD)len, 0);
- return (ARCHIVE_OK);
-}
-
-static int
-win_crypto_Final(unsigned char *buf, size_t bufsize, Digest_CTX *ctx)
-{
- DWORD siglen = (DWORD)bufsize;
-
- if (!ctx->valid)
- return (ARCHIVE_FAILED);
-
- CryptGetHashParam(ctx->hash, HP_HASHVAL, buf, &siglen, 0);
- CryptDestroyHash(ctx->hash);
- CryptReleaseContext(ctx->cryptProv, 0);
- ctx->valid = 0;
- return (ARCHIVE_OK);
-}
-
-#endif /* defined(ARCHIVE_CRYPTO_*_WIN) */
-
-
-/* MD5 implementations */
-#if defined(ARCHIVE_CRYPTO_MD5_LIBC)
-
-static int
-__archive_libc_md5init(archive_md5_ctx *ctx)
-{
- MD5Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libc_md5update(archive_md5_ctx *ctx, const void *indata,
- size_t insize)
-{
- MD5Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libc_md5final(archive_md5_ctx *ctx, void *md)
-{
- MD5Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_MD5_LIBMD)
-
-static int
-__archive_libmd_md5init(archive_md5_ctx *ctx)
-{
- MD5Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libmd_md5update(archive_md5_ctx *ctx, const void *indata,
- size_t insize)
-{
- MD5Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libmd_md5final(archive_md5_ctx *ctx, void *md)
-{
- MD5Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM)
-
-static int
-__archive_libsystem_md5init(archive_md5_ctx *ctx)
-{
- CC_MD5_Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libsystem_md5update(archive_md5_ctx *ctx, const void *indata,
- size_t insize)
-{
- CC_MD5_Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libsystem_md5final(archive_md5_ctx *ctx, void *md)
-{
- CC_MD5_Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_MD5_NETTLE)
-
-static int
-__archive_nettle_md5init(archive_md5_ctx *ctx)
-{
- md5_init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_nettle_md5update(archive_md5_ctx *ctx, const void *indata,
- size_t insize)
-{
- md5_update(ctx, insize, indata);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_nettle_md5final(archive_md5_ctx *ctx, void *md)
-{
- md5_digest(ctx, MD5_DIGEST_SIZE, md);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_MD5_OPENSSL)
-
-static int
-__archive_openssl_md5init(archive_md5_ctx *ctx)
-{
- EVP_DigestInit(ctx, EVP_md5());
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_openssl_md5update(archive_md5_ctx *ctx, const void *indata,
- size_t insize)
-{
- EVP_DigestUpdate(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_openssl_md5final(archive_md5_ctx *ctx, void *md)
-{
- /* HACK: archive_write_set_format_xar.c is finalizing empty contexts, so
- * this is meant to cope with that. Real fix is probably to fix
- * archive_write_set_format_xar.c
- */
- if (ctx->digest)
- EVP_DigestFinal(ctx, md, NULL);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_MD5_WIN)
-
-static int
-__archive_windowsapi_md5init(archive_md5_ctx *ctx)
-{
- return (win_crypto_init(ctx, CALG_MD5));
-}
-
-static int
-__archive_windowsapi_md5update(archive_md5_ctx *ctx, const void *indata,
- size_t insize)
-{
- return (win_crypto_Update(ctx, indata, insize));
-}
-
-static int
-__archive_windowsapi_md5final(archive_md5_ctx *ctx, void *md)
-{
- return (win_crypto_Final(md, 16, ctx));
-}
-
-#else
-
-static int
-__archive_stub_md5init(archive_md5_ctx *ctx)
-{
- (void)ctx; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-static int
-__archive_stub_md5update(archive_md5_ctx *ctx, const void *indata,
- size_t insize)
-{
- (void)ctx; /* UNUSED */
- (void)indata; /* UNUSED */
- (void)insize; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-static int
-__archive_stub_md5final(archive_md5_ctx *ctx, void *md)
-{
- (void)ctx; /* UNUSED */
- (void)md; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-#endif
-
-/* RIPEMD160 implementations */
-#if defined(ARCHIVE_CRYPTO_RMD160_LIBC)
-
-static int
-__archive_libc_ripemd160init(archive_rmd160_ctx *ctx)
-{
- RMD160Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libc_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
- size_t insize)
-{
- RMD160Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libc_ripemd160final(archive_rmd160_ctx *ctx, void *md)
-{
- RMD160Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_RMD160_LIBMD)
-
-static int
-__archive_libmd_ripemd160init(archive_rmd160_ctx *ctx)
-{
- RIPEMD160_Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libmd_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
- size_t insize)
-{
- RIPEMD160_Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libmd_ripemd160final(archive_rmd160_ctx *ctx, void *md)
-{
- RIPEMD160_Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
-
-static int
-__archive_nettle_ripemd160init(archive_rmd160_ctx *ctx)
-{
- ripemd160_init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_nettle_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
- size_t insize)
-{
- ripemd160_update(ctx, insize, indata);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_nettle_ripemd160final(archive_rmd160_ctx *ctx, void *md)
-{
- ripemd160_digest(ctx, RIPEMD160_DIGEST_SIZE, md);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_RMD160_OPENSSL)
-
-static int
-__archive_openssl_ripemd160init(archive_rmd160_ctx *ctx)
-{
- EVP_DigestInit(ctx, EVP_ripemd160());
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_openssl_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
- size_t insize)
-{
- EVP_DigestUpdate(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_openssl_ripemd160final(archive_rmd160_ctx *ctx, void *md)
-{
- EVP_DigestFinal(ctx, md, NULL);
- return (ARCHIVE_OK);
-}
-
-#else
-
-static int
-__archive_stub_ripemd160init(archive_rmd160_ctx *ctx)
-{
- (void)ctx; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-static int
-__archive_stub_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
- size_t insize)
-{
- (void)ctx; /* UNUSED */
- (void)indata; /* UNUSED */
- (void)insize; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-static int
-__archive_stub_ripemd160final(archive_rmd160_ctx *ctx, void *md)
-{
- (void)ctx; /* UNUSED */
- (void)md; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-#endif
-
-/* SHA1 implementations */
-#if defined(ARCHIVE_CRYPTO_SHA1_LIBC)
-
-static int
-__archive_libc_sha1init(archive_sha1_ctx *ctx)
-{
- SHA1Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libc_sha1update(archive_sha1_ctx *ctx, const void *indata,
- size_t insize)
-{
- SHA1Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libc_sha1final(archive_sha1_ctx *ctx, void *md)
-{
- SHA1Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA1_LIBMD)
-
-static int
-__archive_libmd_sha1init(archive_sha1_ctx *ctx)
-{
- SHA1_Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libmd_sha1update(archive_sha1_ctx *ctx, const void *indata,
- size_t insize)
-{
- SHA1_Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libmd_sha1final(archive_sha1_ctx *ctx, void *md)
-{
- SHA1_Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM)
-
-static int
-__archive_libsystem_sha1init(archive_sha1_ctx *ctx)
-{
- CC_SHA1_Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libsystem_sha1update(archive_sha1_ctx *ctx, const void *indata,
- size_t insize)
-{
- CC_SHA1_Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libsystem_sha1final(archive_sha1_ctx *ctx, void *md)
-{
- CC_SHA1_Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE)
-
-static int
-__archive_nettle_sha1init(archive_sha1_ctx *ctx)
-{
- sha1_init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_nettle_sha1update(archive_sha1_ctx *ctx, const void *indata,
- size_t insize)
-{
- sha1_update(ctx, insize, indata);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_nettle_sha1final(archive_sha1_ctx *ctx, void *md)
-{
- sha1_digest(ctx, SHA1_DIGEST_SIZE, md);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA1_OPENSSL)
-
-static int
-__archive_openssl_sha1init(archive_sha1_ctx *ctx)
-{
- EVP_DigestInit(ctx, EVP_sha1());
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_openssl_sha1update(archive_sha1_ctx *ctx, const void *indata,
- size_t insize)
-{
- EVP_DigestUpdate(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_openssl_sha1final(archive_sha1_ctx *ctx, void *md)
-{
- /* HACK: archive_write_set_format_xar.c is finalizing empty contexts, so
- * this is meant to cope with that. Real fix is probably to fix
- * archive_write_set_format_xar.c
- */
- if (ctx->digest)
- EVP_DigestFinal(ctx, md, NULL);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA1_WIN)
-
-static int
-__archive_windowsapi_sha1init(archive_sha1_ctx *ctx)
-{
- return (win_crypto_init(ctx, CALG_SHA1));
-}
-
-static int
-__archive_windowsapi_sha1update(archive_sha1_ctx *ctx, const void *indata,
- size_t insize)
-{
- return (win_crypto_Update(ctx, indata, insize));
-}
-
-static int
-__archive_windowsapi_sha1final(archive_sha1_ctx *ctx, void *md)
-{
- return (win_crypto_Final(md, 20, ctx));
-}
-
-#else
-
-static int
-__archive_stub_sha1init(archive_sha1_ctx *ctx)
-{
- (void)ctx; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-static int
-__archive_stub_sha1update(archive_sha1_ctx *ctx, const void *indata,
- size_t insize)
-{
- (void)ctx; /* UNUSED */
- (void)indata; /* UNUSED */
- (void)insize; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-static int
-__archive_stub_sha1final(archive_sha1_ctx *ctx, void *md)
-{
- (void)ctx; /* UNUSED */
- (void)md; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-#endif
-
-/* SHA256 implementations */
-#if defined(ARCHIVE_CRYPTO_SHA256_LIBC)
-
-static int
-__archive_libc_sha256init(archive_sha256_ctx *ctx)
-{
- SHA256_Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libc_sha256update(archive_sha256_ctx *ctx, const void *indata,
- size_t insize)
-{
- SHA256_Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libc_sha256final(archive_sha256_ctx *ctx, void *md)
-{
- SHA256_Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC2)
-
-static int
-__archive_libc2_sha256init(archive_sha256_ctx *ctx)
-{
- SHA256Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libc2_sha256update(archive_sha256_ctx *ctx, const void *indata,
- size_t insize)
-{
- SHA256Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libc2_sha256final(archive_sha256_ctx *ctx, void *md)
-{
- SHA256Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC3)
-
-static int
-__archive_libc3_sha256init(archive_sha256_ctx *ctx)
-{
- SHA256Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libc3_sha256update(archive_sha256_ctx *ctx, const void *indata,
- size_t insize)
-{
- SHA256Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libc3_sha256final(archive_sha256_ctx *ctx, void *md)
-{
- SHA256Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA256_LIBMD)
-
-static int
-__archive_libmd_sha256init(archive_sha256_ctx *ctx)
-{
- SHA256_Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libmd_sha256update(archive_sha256_ctx *ctx, const void *indata,
- size_t insize)
-{
- SHA256_Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libmd_sha256final(archive_sha256_ctx *ctx, void *md)
-{
- SHA256_Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM)
-
-static int
-__archive_libsystem_sha256init(archive_sha256_ctx *ctx)
-{
- CC_SHA256_Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libsystem_sha256update(archive_sha256_ctx *ctx, const void *indata,
- size_t insize)
-{
- CC_SHA256_Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libsystem_sha256final(archive_sha256_ctx *ctx, void *md)
-{
- CC_SHA256_Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE)
-
-static int
-__archive_nettle_sha256init(archive_sha256_ctx *ctx)
-{
- sha256_init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_nettle_sha256update(archive_sha256_ctx *ctx, const void *indata,
- size_t insize)
-{
- sha256_update(ctx, insize, indata);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_nettle_sha256final(archive_sha256_ctx *ctx, void *md)
-{
- sha256_digest(ctx, SHA256_DIGEST_SIZE, md);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA256_OPENSSL)
-
-static int
-__archive_openssl_sha256init(archive_sha256_ctx *ctx)
-{
- EVP_DigestInit(ctx, EVP_sha256());
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_openssl_sha256update(archive_sha256_ctx *ctx, const void *indata,
- size_t insize)
-{
- EVP_DigestUpdate(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_openssl_sha256final(archive_sha256_ctx *ctx, void *md)
-{
- EVP_DigestFinal(ctx, md, NULL);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA256_WIN)
-
-static int
-__archive_windowsapi_sha256init(archive_sha256_ctx *ctx)
-{
- return (win_crypto_init(ctx, CALG_SHA_256));
-}
-
-static int
-__archive_windowsapi_sha256update(archive_sha256_ctx *ctx, const void *indata,
- size_t insize)
-{
- return (win_crypto_Update(ctx, indata, insize));
-}
-
-static int
-__archive_windowsapi_sha256final(archive_sha256_ctx *ctx, void *md)
-{
- return (win_crypto_Final(md, 32, ctx));
-}
-
-#else
-
-static int
-__archive_stub_sha256init(archive_sha256_ctx *ctx)
-{
- (void)ctx; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-static int
-__archive_stub_sha256update(archive_sha256_ctx *ctx, const void *indata,
- size_t insize)
-{
- (void)ctx; /* UNUSED */
- (void)indata; /* UNUSED */
- (void)insize; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-static int
-__archive_stub_sha256final(archive_sha256_ctx *ctx, void *md)
-{
- (void)ctx; /* UNUSED */
- (void)md; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-#endif
-
-/* SHA384 implementations */
-#if defined(ARCHIVE_CRYPTO_SHA384_LIBC)
-
-static int
-__archive_libc_sha384init(archive_sha384_ctx *ctx)
-{
- SHA384_Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libc_sha384update(archive_sha384_ctx *ctx, const void *indata,
- size_t insize)
-{
- SHA384_Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libc_sha384final(archive_sha384_ctx *ctx, void *md)
-{
- SHA384_Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC2)
-
-static int
-__archive_libc2_sha384init(archive_sha384_ctx *ctx)
-{
- SHA384Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libc2_sha384update(archive_sha384_ctx *ctx, const void *indata,
- size_t insize)
-{
- SHA384Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libc2_sha384final(archive_sha384_ctx *ctx, void *md)
-{
- SHA384Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC3)
-
-static int
-__archive_libc3_sha384init(archive_sha384_ctx *ctx)
-{
- SHA384Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libc3_sha384update(archive_sha384_ctx *ctx, const void *indata,
- size_t insize)
-{
- SHA384Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libc3_sha384final(archive_sha384_ctx *ctx, void *md)
-{
- SHA384Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM)
-
-static int
-__archive_libsystem_sha384init(archive_sha384_ctx *ctx)
-{
- CC_SHA384_Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libsystem_sha384update(archive_sha384_ctx *ctx, const void *indata,
- size_t insize)
-{
- CC_SHA384_Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libsystem_sha384final(archive_sha384_ctx *ctx, void *md)
-{
- CC_SHA384_Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE)
-
-static int
-__archive_nettle_sha384init(archive_sha384_ctx *ctx)
-{
- sha384_init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_nettle_sha384update(archive_sha384_ctx *ctx, const void *indata,
- size_t insize)
-{
- sha384_update(ctx, insize, indata);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_nettle_sha384final(archive_sha384_ctx *ctx, void *md)
-{
- sha384_digest(ctx, SHA384_DIGEST_SIZE, md);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA384_OPENSSL)
-
-static int
-__archive_openssl_sha384init(archive_sha384_ctx *ctx)
-{
- EVP_DigestInit(ctx, EVP_sha384());
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_openssl_sha384update(archive_sha384_ctx *ctx, const void *indata,
- size_t insize)
-{
- EVP_DigestUpdate(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_openssl_sha384final(archive_sha384_ctx *ctx, void *md)
-{
- EVP_DigestFinal(ctx, md, NULL);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA384_WIN)
-
-static int
-__archive_windowsapi_sha384init(archive_sha384_ctx *ctx)
-{
- return (win_crypto_init(ctx, CALG_SHA_384));
-}
-
-static int
-__archive_windowsapi_sha384update(archive_sha384_ctx *ctx, const void *indata,
- size_t insize)
-{
- return (win_crypto_Update(ctx, indata, insize));
-}
-
-static int
-__archive_windowsapi_sha384final(archive_sha384_ctx *ctx, void *md)
-{
- return (win_crypto_Final(md, 48, ctx));
-}
-
-#else
-
-static int
-__archive_stub_sha384init(archive_sha384_ctx *ctx)
-{
- (void)ctx; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-static int
-__archive_stub_sha384update(archive_sha384_ctx *ctx, const void *indata,
- size_t insize)
-{
- (void)ctx; /* UNUSED */
- (void)indata; /* UNUSED */
- (void)insize; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-static int
-__archive_stub_sha384final(archive_sha384_ctx *ctx, void *md)
-{
- (void)ctx; /* UNUSED */
- (void)md; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-#endif
-
-/* SHA512 implementations */
-#if defined(ARCHIVE_CRYPTO_SHA512_LIBC)
-
-static int
-__archive_libc_sha512init(archive_sha512_ctx *ctx)
-{
- SHA512_Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libc_sha512update(archive_sha512_ctx *ctx, const void *indata,
- size_t insize)
-{
- SHA512_Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libc_sha512final(archive_sha512_ctx *ctx, void *md)
-{
- SHA512_Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC2)
-
-static int
-__archive_libc2_sha512init(archive_sha512_ctx *ctx)
-{
- SHA512Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libc2_sha512update(archive_sha512_ctx *ctx, const void *indata,
- size_t insize)
-{
- SHA512Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libc2_sha512final(archive_sha512_ctx *ctx, void *md)
-{
- SHA512Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC3)
-
-static int
-__archive_libc3_sha512init(archive_sha512_ctx *ctx)
-{
- SHA512Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libc3_sha512update(archive_sha512_ctx *ctx, const void *indata,
- size_t insize)
-{
- SHA512Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libc3_sha512final(archive_sha512_ctx *ctx, void *md)
-{
- SHA512Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
-
-static int
-__archive_libmd_sha512init(archive_sha512_ctx *ctx)
-{
- SHA512_Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libmd_sha512update(archive_sha512_ctx *ctx, const void *indata,
- size_t insize)
-{
- SHA512_Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libmd_sha512final(archive_sha512_ctx *ctx, void *md)
-{
- SHA512_Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM)
-
-static int
-__archive_libsystem_sha512init(archive_sha512_ctx *ctx)
-{
- CC_SHA512_Init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libsystem_sha512update(archive_sha512_ctx *ctx, const void *indata,
- size_t insize)
-{
- CC_SHA512_Update(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_libsystem_sha512final(archive_sha512_ctx *ctx, void *md)
-{
- CC_SHA512_Final(md, ctx);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
-
-static int
-__archive_nettle_sha512init(archive_sha512_ctx *ctx)
-{
- sha512_init(ctx);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_nettle_sha512update(archive_sha512_ctx *ctx, const void *indata,
- size_t insize)
-{
- sha512_update(ctx, insize, indata);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_nettle_sha512final(archive_sha512_ctx *ctx, void *md)
-{
- sha512_digest(ctx, SHA512_DIGEST_SIZE, md);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA512_OPENSSL)
-
-static int
-__archive_openssl_sha512init(archive_sha512_ctx *ctx)
-{
- EVP_DigestInit(ctx, EVP_sha512());
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_openssl_sha512update(archive_sha512_ctx *ctx, const void *indata,
- size_t insize)
-{
- EVP_DigestUpdate(ctx, indata, insize);
- return (ARCHIVE_OK);
-}
-
-static int
-__archive_openssl_sha512final(archive_sha512_ctx *ctx, void *md)
-{
- EVP_DigestFinal(ctx, md, NULL);
- return (ARCHIVE_OK);
-}
-
-#elif defined(ARCHIVE_CRYPTO_SHA512_WIN)
-
-static int
-__archive_windowsapi_sha512init(archive_sha512_ctx *ctx)
-{
- return (win_crypto_init(ctx, CALG_SHA_512));
-}
-
-static int
-__archive_windowsapi_sha512update(archive_sha512_ctx *ctx, const void *indata,
- size_t insize)
-{
- return (win_crypto_Update(ctx, indata, insize));
-}
-
-static int
-__archive_windowsapi_sha512final(archive_sha512_ctx *ctx, void *md)
-{
- return (win_crypto_Final(md, 64, ctx));
-}
-
-#else
-
-static int
-__archive_stub_sha512init(archive_sha512_ctx *ctx)
-{
- (void)ctx; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-static int
-__archive_stub_sha512update(archive_sha512_ctx *ctx, const void *indata,
- size_t insize)
-{
- (void)ctx; /* UNUSED */
- (void)indata; /* UNUSED */
- (void)insize; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-static int
-__archive_stub_sha512final(archive_sha512_ctx *ctx, void *md)
-{
- (void)ctx; /* UNUSED */
- (void)md; /* UNUSED */
- return (ARCHIVE_FAILED);
-}
-
-#endif
-
-/* NOTE: Crypto functions are set based on availability and by the following
- * order of preference.
- * 1. libc
- * 2. libc2
- * 3. libc3
- * 4. libSystem
- * 5. Nettle
- * 6. OpenSSL
- * 7. libmd
- * 8. Windows API
- */
-const struct archive_crypto __archive_crypto =
-{
-/* MD5 */
-#if defined(ARCHIVE_CRYPTO_MD5_LIBC)
- &__archive_libc_md5init,
- &__archive_libc_md5update,
- &__archive_libc_md5final,
-#elif defined(ARCHIVE_CRYPTO_MD5_LIBMD)
- &__archive_libmd_md5init,
- &__archive_libmd_md5update,
- &__archive_libmd_md5final,
-#elif defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM)
- &__archive_libsystem_md5init,
- &__archive_libsystem_md5update,
- &__archive_libsystem_md5final,
-#elif defined(ARCHIVE_CRYPTO_MD5_NETTLE)
- &__archive_nettle_md5init,
- &__archive_nettle_md5update,
- &__archive_nettle_md5final,
-#elif defined(ARCHIVE_CRYPTO_MD5_OPENSSL)
- &__archive_openssl_md5init,
- &__archive_openssl_md5update,
- &__archive_openssl_md5final,
-#elif defined(ARCHIVE_CRYPTO_MD5_WIN)
- &__archive_windowsapi_md5init,
- &__archive_windowsapi_md5update,
- &__archive_windowsapi_md5final,
-#elif !defined(ARCHIVE_MD5_COMPILE_TEST)
- &__archive_stub_md5init,
- &__archive_stub_md5update,
- &__archive_stub_md5final,
-#endif
-
-/* RIPEMD160 */
-#if defined(ARCHIVE_CRYPTO_RMD160_LIBC)
- &__archive_libc_ripemd160init,
- &__archive_libc_ripemd160update,
- &__archive_libc_ripemd160final,
-#elif defined(ARCHIVE_CRYPTO_RMD160_LIBMD)
- &__archive_libmd_ripemd160init,
- &__archive_libmd_ripemd160update,
- &__archive_libmd_ripemd160final,
-#elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
- &__archive_nettle_ripemd160init,
- &__archive_nettle_ripemd160update,
- &__archive_nettle_ripemd160final,
-#elif defined(ARCHIVE_CRYPTO_RMD160_OPENSSL)
- &__archive_openssl_ripemd160init,
- &__archive_openssl_ripemd160update,
- &__archive_openssl_ripemd160final,
-#elif !defined(ARCHIVE_RMD160_COMPILE_TEST)
- &__archive_stub_ripemd160init,
- &__archive_stub_ripemd160update,
- &__archive_stub_ripemd160final,
-#endif
-
-/* SHA1 */
-#if defined(ARCHIVE_CRYPTO_SHA1_LIBC)
- &__archive_libc_sha1init,
- &__archive_libc_sha1update,
- &__archive_libc_sha1final,
-#elif defined(ARCHIVE_CRYPTO_SHA1_LIBMD)
- &__archive_libmd_sha1init,
- &__archive_libmd_sha1update,
- &__archive_libmd_sha1final,
-#elif defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM)
- &__archive_libsystem_sha1init,
- &__archive_libsystem_sha1update,
- &__archive_libsystem_sha1final,
-#elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE)
- &__archive_nettle_sha1init,
- &__archive_nettle_sha1update,
- &__archive_nettle_sha1final,
-#elif defined(ARCHIVE_CRYPTO_SHA1_OPENSSL)
- &__archive_openssl_sha1init,
- &__archive_openssl_sha1update,
- &__archive_openssl_sha1final,
-#elif defined(ARCHIVE_CRYPTO_SHA1_WIN)
- &__archive_windowsapi_sha1init,
- &__archive_windowsapi_sha1update,
- &__archive_windowsapi_sha1final,
-#elif !defined(ARCHIVE_SHA1_COMPILE_TEST)
- &__archive_stub_sha1init,
- &__archive_stub_sha1update,
- &__archive_stub_sha1final,
-#endif
-
-/* SHA256 */
-#if defined(ARCHIVE_CRYPTO_SHA256_LIBC)
- &__archive_libc_sha256init,
- &__archive_libc_sha256update,
- &__archive_libc_sha256final,
-#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC2)
- &__archive_libc2_sha256init,
- &__archive_libc2_sha256update,
- &__archive_libc2_sha256final,
-#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC3)
- &__archive_libc3_sha256init,
- &__archive_libc3_sha256update,
- &__archive_libc3_sha256final,
-#elif defined(ARCHIVE_CRYPTO_SHA256_LIBMD)
- &__archive_libmd_sha256init,
- &__archive_libmd_sha256update,
- &__archive_libmd_sha256final,
-#elif defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM)
- &__archive_libsystem_sha256init,
- &__archive_libsystem_sha256update,
- &__archive_libsystem_sha256final,
-#elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE)
- &__archive_nettle_sha256init,
- &__archive_nettle_sha256update,
- &__archive_nettle_sha256final,
-#elif defined(ARCHIVE_CRYPTO_SHA256_OPENSSL)
- &__archive_openssl_sha256init,
- &__archive_openssl_sha256update,
- &__archive_openssl_sha256final,
-#elif defined(ARCHIVE_CRYPTO_SHA256_WIN)
- &__archive_windowsapi_sha256init,
- &__archive_windowsapi_sha256update,
- &__archive_windowsapi_sha256final,
-#elif !defined(ARCHIVE_SHA256_COMPILE_TEST)
- &__archive_stub_sha256init,
- &__archive_stub_sha256update,
- &__archive_stub_sha256final,
-#endif
-
-/* SHA384 */
-#if defined(ARCHIVE_CRYPTO_SHA384_LIBC)
- &__archive_libc_sha384init,
- &__archive_libc_sha384update,
- &__archive_libc_sha384final,
-#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC2)
- &__archive_libc2_sha384init,
- &__archive_libc2_sha384update,
- &__archive_libc2_sha384final,
-#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC3)
- &__archive_libc3_sha384init,
- &__archive_libc3_sha384update,
- &__archive_libc3_sha384final,
-#elif defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM)
- &__archive_libsystem_sha384init,
- &__archive_libsystem_sha384update,
- &__archive_libsystem_sha384final,
-#elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE)
- &__archive_nettle_sha384init,
- &__archive_nettle_sha384update,
- &__archive_nettle_sha384final,
-#elif defined(ARCHIVE_CRYPTO_SHA384_OPENSSL)
- &__archive_openssl_sha384init,
- &__archive_openssl_sha384update,
- &__archive_openssl_sha384final,
-#elif defined(ARCHIVE_CRYPTO_SHA384_WIN)
- &__archive_windowsapi_sha384init,
- &__archive_windowsapi_sha384update,
- &__archive_windowsapi_sha384final,
-#elif !defined(ARCHIVE_SHA384_COMPILE_TEST)
- &__archive_stub_sha384init,
- &__archive_stub_sha384update,
- &__archive_stub_sha384final,
-#endif
-
-/* SHA512 */
-#if defined(ARCHIVE_CRYPTO_SHA512_LIBC)
- &__archive_libc_sha512init,
- &__archive_libc_sha512update,
- &__archive_libc_sha512final
-#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC2)
- &__archive_libc2_sha512init,
- &__archive_libc2_sha512update,
- &__archive_libc2_sha512final
-#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC3)
- &__archive_libc3_sha512init,
- &__archive_libc3_sha512update,
- &__archive_libc3_sha512final
-#elif defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
- &__archive_libmd_sha512init,
- &__archive_libmd_sha512update,
- &__archive_libmd_sha512final
-#elif defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM)
- &__archive_libsystem_sha512init,
- &__archive_libsystem_sha512update,
- &__archive_libsystem_sha512final
-#elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
- &__archive_nettle_sha512init,
- &__archive_nettle_sha512update,
- &__archive_nettle_sha512final,
-#elif defined(ARCHIVE_CRYPTO_SHA512_OPENSSL)
- &__archive_openssl_sha512init,
- &__archive_openssl_sha512update,
- &__archive_openssl_sha512final
-#elif defined(ARCHIVE_CRYPTO_SHA512_WIN)
- &__archive_windowsapi_sha512init,
- &__archive_windowsapi_sha512update,
- &__archive_windowsapi_sha512final
-#elif !defined(ARCHIVE_SHA512_COMPILE_TEST)
- &__archive_stub_sha512init,
- &__archive_stub_sha512update,
- &__archive_stub_sha512final
-#endif
-};
diff --git a/Utilities/cmlibarchive/libarchive/archive_crypto_private.h b/Utilities/cmlibarchive/libarchive/archive_crypto_private.h
deleted file mode 100644
index f8b1fb3c3..000000000
--- a/Utilities/cmlibarchive/libarchive/archive_crypto_private.h
+++ /dev/null
@@ -1,376 +0,0 @@
-/*-
-* Copyright (c) 2003-2007 Tim Kientzle
-* Copyright (c) 2011 Andres Mejia
-* All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions
-* are met:
-* 1. Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* 2. Redistributions in binary form must reproduce the above copyright
-* notice, this list of conditions and the following disclaimer in the
-* documentation and/or other materials provided with the distribution.
-*
-* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
-* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
-* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef __LIBARCHIVE_BUILD
-#error This header is only to be used internally to libarchive.
-#endif
-
-#ifndef ARCHIVE_CRYPTO_PRIVATE_H_INCLUDED
-#define ARCHIVE_CRYPTO_PRIVATE_H_INCLUDED
-
-/*
- * Crypto support in various Operating Systems:
- *
- * NetBSD:
- * - MD5 and SHA1 in libc: without _ after algorithm name
- * - SHA2 in libc: with _ after algorithm name
- *
- * OpenBSD:
- * - MD5, SHA1 and SHA2 in libc: without _ after algorithm name
- * - OpenBSD 4.4 and earlier have SHA2 in libc with _ after algorithm name
- *
- * DragonFly and FreeBSD:
- * - MD5 libmd: without _ after algorithm name
- * - SHA1, SHA256 and SHA512 in libmd: with _ after algorithm name
- *
- * Mac OS X (10.4 and later):
- * - MD5, SHA1 and SHA2 in libSystem: with CC_ prefix and _ after algorithm name
- *
- * OpenSSL:
- * - MD5, SHA1 and SHA2 in libcrypto: with _ after algorithm name
- *
- * Windows:
- * - MD5, SHA1 and SHA2 in archive_crypto.c using Windows crypto API
- */
-
-/* libc crypto headers */
-#if defined(ARCHIVE_CRYPTO_MD5_LIBC)
-#include <md5.h>
-#endif
-#if defined(ARCHIVE_CRYPTO_RMD160_LIBC)
-#include <rmd160.h>
-#endif
-#if defined(ARCHIVE_CRYPTO_SHA1_LIBC)
-#include <sha1.h>
-#endif
-#if defined(ARCHIVE_CRYPTO_SHA256_LIBC) ||\
- defined(ARCHIVE_CRYPTO_SHA256_LIBC2) ||\
- defined(ARCHIVE_CRYPTO_SHA256_LIBC3) ||\
- defined(ARCHIVE_CRYPTO_SHA384_LIBC) ||\
- defined(ARCHIVE_CRYPTO_SHA384_LIBC2) ||\
- defined(ARCHIVE_CRYPTO_SHA384_LIBC3) ||\
- defined(ARCHIVE_CRYPTO_SHA512_LIBC) ||\
- defined(ARCHIVE_CRYPTO_SHA512_LIBC2) ||\
- defined(ARCHIVE_CRYPTO_SHA512_LIBC3)
-#include <sha2.h>
-#endif
-
-/* libmd crypto headers */
-#if defined(ARCHIVE_CRYPTO_MD5_LIBMD) ||\
- defined(ARCHIVE_CRYPTO_RMD160_LIBMD) ||\
- defined(ARCHIVE_CRYPTO_SHA1_LIBMD) ||\
- defined(ARCHIVE_CRYPTO_SHA256_LIBMD) ||\
- defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
-#define ARCHIVE_CRYPTO_LIBMD 1
-#endif
-
-#if defined(ARCHIVE_CRYPTO_MD5_LIBMD)
-#include <md5.h>
-#endif
-#if defined(ARCHIVE_CRYPTO_RMD160_LIBMD)
-#include <ripemd.h>
-#endif
-#if defined(ARCHIVE_CRYPTO_SHA1_LIBMD)
-#include <sha.h>
-#endif
-#if defined(ARCHIVE_CRYPTO_SHA256_LIBMD)
-#include <sha256.h>
-#endif
-#if defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
-#include <sha512.h>
-#endif
-
-/* libSystem crypto headers */
-#if defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM) ||\
- defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM) ||\
- defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM) ||\
- defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM) ||\
- defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM)
-#include <CommonCrypto/CommonDigest.h>
-#endif
-
-/* Nettle crypto headers */
-#if defined(ARCHIVE_CRYPTO_MD5_NETTLE)
-#include <nettle/md5.h>
-#endif
-#if defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
-#include <nettle/ripemd160.h>
-#endif
-#if defined(ARCHIVE_CRYPTO_SHA1_NETTLE) ||\
- defined(ARCHIVE_CRYPTO_SHA256_NETTLE) ||\
- defined(ARCHIVE_CRYPTO_SHA384_NETTLE) ||\
- defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
-#include <nettle/sha.h>
-#endif
-
-/* OpenSSL crypto headers */
-#if defined(ARCHIVE_CRYPTO_MD5_OPENSSL) ||\
- defined(ARCHIVE_CRYPTO_RMD160_OPENSSL) ||\
- defined(ARCHIVE_CRYPTO_SHA1_OPENSSL) ||\
- defined(ARCHIVE_CRYPTO_SHA256_OPENSSL) ||\
- defined(ARCHIVE_CRYPTO_SHA384_OPENSSL) ||\
- defined(ARCHIVE_CRYPTO_SHA512_OPENSSL)
-#define ARCHIVE_CRYPTO_OPENSSL 1
-#include <openssl/evp.h>
-#endif
-
-/* Windows crypto headers */
-#if defined(ARCHIVE_CRYPTO_MD5_WIN) ||\
- defined(ARCHIVE_CRYPTO_SHA1_WIN) ||\
- defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
- defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
- defined(ARCHIVE_CRYPTO_SHA512_WIN)
-#include <wincrypt.h>
-typedef struct {
- int valid;
- HCRYPTPROV cryptProv;
- HCRYPTHASH hash;
-} Digest_CTX;
-#endif
-
-/* typedefs */
-#if defined(ARCHIVE_CRYPTO_MD5_LIBC)
-typedef MD5_CTX archive_md5_ctx;
-#elif defined(ARCHIVE_CRYPTO_MD5_LIBMD)
-typedef MD5_CTX archive_md5_ctx;
-#elif defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM)
-typedef CC_MD5_CTX archive_md5_ctx;
-#elif defined(ARCHIVE_CRYPTO_MD5_NETTLE)
-typedef struct md5_ctx archive_md5_ctx;
-#elif defined(ARCHIVE_CRYPTO_MD5_OPENSSL)
-typedef EVP_MD_CTX archive_md5_ctx;
-#elif defined(ARCHIVE_CRYPTO_MD5_WIN)
-typedef Digest_CTX archive_md5_ctx;
-#else
-typedef unsigned char archive_md5_ctx;
-#endif
-
-#if defined(ARCHIVE_CRYPTO_RMD160_LIBC)
-typedef RMD160_CTX archive_rmd160_ctx;
-#elif defined(ARCHIVE_CRYPTO_RMD160_LIBMD)
-typedef RIPEMD160_CTX archive_rmd160_ctx;
-#elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
-typedef struct ripemd160_ctx archive_rmd160_ctx;
-#elif defined(ARCHIVE_CRYPTO_RMD160_OPENSSL)
-typedef EVP_MD_CTX archive_rmd160_ctx;
-#else
-typedef unsigned char archive_rmd160_ctx;
-#endif
-
-#if defined(ARCHIVE_CRYPTO_SHA1_LIBC)
-typedef SHA1_CTX archive_sha1_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA1_LIBMD)
-typedef SHA1_CTX archive_sha1_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM)
-typedef CC_SHA1_CTX archive_sha1_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE)
-typedef struct sha1_ctx archive_sha1_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA1_OPENSSL)
-typedef EVP_MD_CTX archive_sha1_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA1_WIN)
-typedef Digest_CTX archive_sha1_ctx;
-#else
-typedef unsigned char archive_sha1_ctx;
-#endif
-
-#if defined(ARCHIVE_CRYPTO_SHA256_LIBC)
-typedef SHA256_CTX archive_sha256_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC2)
-typedef SHA256_CTX archive_sha256_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC3)
-typedef SHA2_CTX archive_sha256_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA256_LIBMD)
-typedef SHA256_CTX archive_sha256_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM)
-typedef CC_SHA256_CTX archive_sha256_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE)
-typedef struct sha256_ctx archive_sha256_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA256_OPENSSL)
-typedef EVP_MD_CTX archive_sha256_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA256_WIN)
-typedef Digest_CTX archive_sha256_ctx;
-#else
-typedef unsigned char archive_sha256_ctx;
-#endif
-
-#if defined(ARCHIVE_CRYPTO_SHA384_LIBC)
-typedef SHA384_CTX archive_sha384_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC2)
-typedef SHA384_CTX archive_sha384_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC3)
-typedef SHA2_CTX archive_sha384_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM)
-typedef CC_SHA512_CTX archive_sha384_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE)
-typedef struct sha384_ctx archive_sha384_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA384_OPENSSL)
-typedef EVP_MD_CTX archive_sha384_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA384_WIN)
-typedef Digest_CTX archive_sha384_ctx;
-#else
-typedef unsigned char archive_sha384_ctx;
-#endif
-
-#if defined(ARCHIVE_CRYPTO_SHA512_LIBC)
-typedef SHA512_CTX archive_sha512_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC2)
-typedef SHA512_CTX archive_sha512_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC3)
-typedef SHA2_CTX archive_sha512_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
-typedef SHA512_CTX archive_sha512_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM)
-typedef CC_SHA512_CTX archive_sha512_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
-typedef struct sha512_ctx archive_sha512_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA512_OPENSSL)
-typedef EVP_MD_CTX archive_sha512_ctx;
-#elif defined(ARCHIVE_CRYPTO_SHA512_WIN)
-typedef Digest_CTX archive_sha512_ctx;
-#else
-typedef unsigned char archive_sha512_ctx;
-#endif
-
-/* defines */
-#if defined(ARCHIVE_CRYPTO_MD5_LIBC) ||\
- defined(ARCHIVE_CRYPTO_MD5_LIBMD) || \
- defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM) ||\
- defined(ARCHIVE_CRYPTO_MD5_NETTLE) ||\
- defined(ARCHIVE_CRYPTO_MD5_OPENSSL) ||\
- defined(ARCHIVE_CRYPTO_MD5_WIN)
-#define ARCHIVE_HAS_MD5
-#endif
-#define archive_md5_init(ctx)\
- __archive_crypto.md5init(ctx)
-#define archive_md5_final(ctx, md)\
- __archive_crypto.md5final(ctx, md)
-#define archive_md5_update(ctx, buf, n)\
- __archive_crypto.md5update(ctx, buf, n)
-
-#if defined(ARCHIVE_CRYPTO_RMD160_LIBC) ||\
- defined(ARCHIVE_CRYPTO_RMD160_NETTLE) ||\
- defined(ARCHIVE_CRYPTO_RMD160_OPENSSL)
-#define ARCHIVE_HAS_RMD160
-#endif
-#define archive_rmd160_init(ctx)\
- __archive_crypto.rmd160init(ctx)
-#define archive_rmd160_final(ctx, md)\
- __archive_crypto.rmd160final(ctx, md)
-#define archive_rmd160_update(ctx, buf, n)\
- __archive_crypto.rmd160update(ctx, buf, n)
-
-#if defined(ARCHIVE_CRYPTO_SHA1_LIBC) ||\
- defined(ARCHIVE_CRYPTO_SHA1_LIBMD) || \
- defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM) ||\
- defined(ARCHIVE_CRYPTO_SHA1_NETTLE) ||\
- defined(ARCHIVE_CRYPTO_SHA1_OPENSSL) ||\
- defined(ARCHIVE_CRYPTO_SHA1_WIN)
-#define ARCHIVE_HAS_SHA1
-#endif
-#define archive_sha1_init(ctx)\
- __archive_crypto.sha1init(ctx)
-#define archive_sha1_final(ctx, md)\
- __archive_crypto.sha1final(ctx, md)
-#define archive_sha1_update(ctx, buf, n)\
- __archive_crypto.sha1update(ctx, buf, n)
-
-#if defined(ARCHIVE_CRYPTO_SHA256_LIBC) ||\
- defined(ARCHIVE_CRYPTO_SHA256_LIBC2) ||\
- defined(ARCHIVE_CRYPTO_SHA256_LIBC3) ||\
- defined(ARCHIVE_CRYPTO_SHA256_LIBMD) ||\
- defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM) ||\
- defined(ARCHIVE_CRYPTO_SHA256_NETTLE) ||\
- defined(ARCHIVE_CRYPTO_SHA256_OPENSSL) ||\
- defined(ARCHIVE_CRYPTO_SHA256_WIN)
-#define ARCHIVE_HAS_SHA256
-#endif
-#define archive_sha256_init(ctx)\
- __archive_crypto.sha256init(ctx)
-#define archive_sha256_final(ctx, md)\
- __archive_crypto.sha256final(ctx, md)
-#define archive_sha256_update(ctx, buf, n)\
- __archive_crypto.sha256update(ctx, buf, n)
-
-#if defined(ARCHIVE_CRYPTO_SHA384_LIBC) ||\
- defined(ARCHIVE_CRYPTO_SHA384_LIBC2) ||\
- defined(ARCHIVE_CRYPTO_SHA384_LIBC3) ||\
- defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM) ||\
- defined(ARCHIVE_CRYPTO_SHA384_NETTLE) ||\
- defined(ARCHIVE_CRYPTO_SHA384_OPENSSL) ||\
- defined(ARCHIVE_CRYPTO_SHA384_WIN)
-#define ARCHIVE_HAS_SHA384
-#endif
-#define archive_sha384_init(ctx)\
- __archive_crypto.sha384init(ctx)
-#define archive_sha384_final(ctx, md)\
- __archive_crypto.sha384final(ctx, md)
-#define archive_sha384_update(ctx, buf, n)\
- __archive_crypto.sha384update(ctx, buf, n)
-
-#if defined(ARCHIVE_CRYPTO_SHA512_LIBC) ||\
- defined(ARCHIVE_CRYPTO_SHA512_LIBC2) ||\
- defined(ARCHIVE_CRYPTO_SHA512_LIBC3) ||\
- defined(ARCHIVE_CRYPTO_SHA512_LIBMD) ||\
- defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM) ||\
- defined(ARCHIVE_CRYPTO_SHA512_NETTLE) ||\
- defined(ARCHIVE_CRYPTO_SHA512_OPENSSL) ||\
- defined(ARCHIVE_CRYPTO_SHA512_WIN)
-#define ARCHIVE_HAS_SHA512
-#endif
-#define archive_sha512_init(ctx)\
- __archive_crypto.sha512init(ctx)
-#define archive_sha512_final(ctx, md)\
- __archive_crypto.sha512final(ctx, md)
-#define archive_sha512_update(ctx, buf, n)\
- __archive_crypto.sha512update(ctx, buf, n)
-
-/* Minimal interface to crypto functionality for internal use in libarchive */
-struct archive_crypto
-{
- /* Message Digest */
- int (*md5init)(archive_md5_ctx *ctx);
- int (*md5update)(archive_md5_ctx *, const void *, size_t);
- int (*md5final)(archive_md5_ctx *, void *);
- int (*rmd160init)(archive_rmd160_ctx *);
- int (*rmd160update)(archive_rmd160_ctx *, const void *, size_t);
- int (*rmd160final)(archive_rmd160_ctx *, void *);
- int (*sha1init)(archive_sha1_ctx *);
- int (*sha1update)(archive_sha1_ctx *, const void *, size_t);
- int (*sha1final)(archive_sha1_ctx *, void *);
- int (*sha256init)(archive_sha256_ctx *);
- int (*sha256update)(archive_sha256_ctx *, const void *, size_t);
- int (*sha256final)(archive_sha256_ctx *, void *);
- int (*sha384init)(archive_sha384_ctx *);
- int (*sha384update)(archive_sha384_ctx *, const void *, size_t);
- int (*sha384final)(archive_sha384_ctx *, void *);
- int (*sha512init)(archive_sha512_ctx *);
- int (*sha512update)(archive_sha512_ctx *, const void *, size_t);
- int (*sha512final)(archive_sha512_ctx *, void *);
-};
-
-extern const struct archive_crypto __archive_crypto;
-
-#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_cryptor.c b/Utilities/cmlibarchive/libarchive/archive_cryptor.c
new file mode 100644
index 000000000..efd350d29
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_cryptor.c
@@ -0,0 +1,435 @@
+/*-
+* Copyright (c) 2014 Michihiro NAKAJIMA
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "archive_platform.h"
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include "archive.h"
+#include "archive_cryptor_private.h"
+
+#ifdef ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto
+
+static int
+pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
+ size_t salt_len, unsigned rounds, uint8_t *derived_key,
+ size_t derived_key_len)
+{
+ CCKeyDerivationPBKDF(kCCPBKDF2, (const char *)pw,
+ pw_len, salt, salt_len, kCCPRFHmacAlgSHA1, rounds,
+ derived_key, derived_key_len);
+ return 0;
+}
+
+#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
+#ifdef _MSC_VER
+#pragma comment(lib, "Bcrypt.lib")
+#endif
+
+static int
+pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
+ size_t salt_len, unsigned rounds, uint8_t *derived_key,
+ size_t derived_key_len)
+{
+ NTSTATUS status;
+ BCRYPT_ALG_HANDLE hAlg;
+
+ status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA1_ALGORITHM,
+ MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
+ if (!BCRYPT_SUCCESS(status))
+ return -1;
+
+ status = BCryptDeriveKeyPBKDF2(hAlg,
+ (PUCHAR)(uintptr_t)pw, (ULONG)pw_len,
+ (PUCHAR)(uintptr_t)salt, (ULONG)salt_len, rounds,
+ (PUCHAR)derived_key, (ULONG)derived_key_len, 0);
+
+ BCryptCloseAlgorithmProvider(hAlg, 0);
+
+ return (BCRYPT_SUCCESS(status)) ? 0: -1;
+}
+
+#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_PBKDF2_H)
+
+static int
+pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
+ size_t salt_len, unsigned rounds, uint8_t *derived_key,
+ size_t derived_key_len) {
+ pbkdf2_hmac_sha1((unsigned)pw_len, (const uint8_t *)pw, rounds,
+ salt_len, salt, derived_key_len, derived_key);
+ return 0;
+}
+
+#elif defined(HAVE_LIBCRYPTO) && defined(HAVE_PKCS5_PBKDF2_HMAC_SHA1)
+
+static int
+pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
+ size_t salt_len, unsigned rounds, uint8_t *derived_key,
+ size_t derived_key_len) {
+
+ PKCS5_PBKDF2_HMAC_SHA1(pw, pw_len, salt, salt_len, rounds,
+ derived_key_len, derived_key);
+ return 0;
+}
+
+#else
+
+/* Stub */
+static int
+pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
+ size_t salt_len, unsigned rounds, uint8_t *derived_key,
+ size_t derived_key_len) {
+ (void)pw; /* UNUSED */
+ (void)pw_len; /* UNUSED */
+ (void)salt; /* UNUSED */
+ (void)salt_len; /* UNUSED */
+ (void)rounds; /* UNUSED */
+ (void)derived_key; /* UNUSED */
+ (void)derived_key_len; /* UNUSED */
+ return -1; /* UNSUPPORTED */
+}
+
+#endif
+
+#ifdef ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto
+# if MAC_OS_X_VERSION_MAX_ALLOWED < 1090
+# define kCCAlgorithmAES kCCAlgorithmAES128
+# endif
+
+static int
+aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
+{
+ CCCryptorStatus r;
+
+ ctx->key_len = key_len;
+ memcpy(ctx->key, key, key_len);
+ memset(ctx->nonce, 0, sizeof(ctx->nonce));
+ ctx->encr_pos = AES_BLOCK_SIZE;
+ r = CCCryptorCreateWithMode(kCCEncrypt, kCCModeECB, kCCAlgorithmAES,
+ ccNoPadding, NULL, key, key_len, NULL, 0, 0, 0, &ctx->ctx);
+ return (r == kCCSuccess)? 0: -1;
+}
+
+static int
+aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
+{
+ CCCryptorRef ref = ctx->ctx;
+ CCCryptorStatus r;
+
+ r = CCCryptorReset(ref, NULL);
+ if (r != kCCSuccess)
+ return -1;
+ r = CCCryptorUpdate(ref, ctx->nonce, AES_BLOCK_SIZE, ctx->encr_buf,
+ AES_BLOCK_SIZE, NULL);
+ return (r == kCCSuccess)? 0: -1;
+}
+
+static int
+aes_ctr_release(archive_crypto_ctx *ctx)
+{
+ memset(ctx->key, 0, ctx->key_len);
+ memset(ctx->nonce, 0, sizeof(ctx->nonce));
+ return 0;
+}
+
+#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
+
+static int
+aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
+{
+ BCRYPT_ALG_HANDLE hAlg;
+ BCRYPT_KEY_HANDLE hKey;
+ DWORD keyObj_len, aes_key_len;
+ PBYTE keyObj;
+ ULONG result;
+ NTSTATUS status;
+ BCRYPT_KEY_LENGTHS_STRUCT key_lengths;
+
+ ctx->hAlg = NULL;
+ ctx->hKey = NULL;
+ ctx->keyObj = NULL;
+ switch (key_len) {
+ case 16: aes_key_len = 128; break;
+ case 24: aes_key_len = 192; break;
+ case 32: aes_key_len = 256; break;
+ default: return -1;
+ }
+ status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_AES_ALGORITHM,
+ MS_PRIMITIVE_PROVIDER, 0);
+ if (!BCRYPT_SUCCESS(status))
+ return -1;
+ status = BCryptGetProperty(hAlg, BCRYPT_KEY_LENGTHS, (PUCHAR)&key_lengths,
+ sizeof(key_lengths), &result, 0);
+ if (!BCRYPT_SUCCESS(status)) {
+ BCryptCloseAlgorithmProvider(hAlg, 0);
+ return -1;
+ }
+ if (key_lengths.dwMinLength > aes_key_len
+ || key_lengths.dwMaxLength < aes_key_len) {
+ BCryptCloseAlgorithmProvider(hAlg, 0);
+ return -1;
+ }
+ status = BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH, (PUCHAR)&keyObj_len,
+ sizeof(keyObj_len), &result, 0);
+ if (!BCRYPT_SUCCESS(status)) {
+ BCryptCloseAlgorithmProvider(hAlg, 0);
+ return -1;
+ }
+ keyObj = (PBYTE)HeapAlloc(GetProcessHeap(), 0, keyObj_len);
+ if (keyObj == NULL) {
+ BCryptCloseAlgorithmProvider(hAlg, 0);
+ return -1;
+ }
+ status = BCryptSetProperty(hAlg, BCRYPT_CHAINING_MODE,
+ (PUCHAR)BCRYPT_CHAIN_MODE_ECB, sizeof(BCRYPT_CHAIN_MODE_ECB), 0);
+ if (!BCRYPT_SUCCESS(status)) {
+ BCryptCloseAlgorithmProvider(hAlg, 0);
+ HeapFree(GetProcessHeap(), 0, keyObj);
+ return -1;
+ }
+ status = BCryptGenerateSymmetricKey(hAlg, &hKey,
+ keyObj, keyObj_len,
+ (PUCHAR)(uintptr_t)key, (ULONG)key_len, 0);
+ if (!BCRYPT_SUCCESS(status)) {
+ BCryptCloseAlgorithmProvider(hAlg, 0);
+ HeapFree(GetProcessHeap(), 0, keyObj);
+ return -1;
+ }
+
+ ctx->hAlg = hAlg;
+ ctx->hKey = hKey;
+ ctx->keyObj = keyObj;
+ ctx->keyObj_len = keyObj_len;
+ ctx->encr_pos = AES_BLOCK_SIZE;
+
+ return 0;
+}
+
+static int
+aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
+{
+ NTSTATUS status;
+ ULONG result;
+
+ status = BCryptEncrypt(ctx->hKey, (PUCHAR)ctx->nonce, AES_BLOCK_SIZE,
+ NULL, NULL, 0, (PUCHAR)ctx->encr_buf, AES_BLOCK_SIZE,
+ &result, 0);
+ return BCRYPT_SUCCESS(status) ? 0 : -1;
+}
+
+static int
+aes_ctr_release(archive_crypto_ctx *ctx)
+{
+
+ if (ctx->hAlg != NULL) {
+ BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
+ ctx->hAlg = NULL;
+ BCryptDestroyKey(ctx->hKey);
+ ctx->hKey = NULL;
+ HeapFree(GetProcessHeap(), 0, ctx->keyObj);
+ ctx->keyObj = NULL;
+ }
+ memset(ctx, 0, sizeof(*ctx));
+ return 0;
+}
+
+#elif defined(HAVE_LIBNETTLE)
+
+static int
+aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
+{
+ ctx->key_len = key_len;
+ memcpy(ctx->key, key, key_len);
+ memset(ctx->nonce, 0, sizeof(ctx->nonce));
+ ctx->encr_pos = AES_BLOCK_SIZE;
+ memset(&ctx->ctx, 0, sizeof(ctx->ctx));
+ return 0;
+}
+
+static int
+aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
+{
+ aes_set_encrypt_key(&ctx->ctx, ctx->key_len, ctx->key);
+ aes_encrypt(&ctx->ctx, AES_BLOCK_SIZE, ctx->encr_buf, ctx->nonce);
+ return 0;
+}
+
+static int
+aes_ctr_release(archive_crypto_ctx *ctx)
+{
+ memset(ctx, 0, sizeof(*ctx));
+ return 0;
+}
+
+#elif defined(HAVE_LIBCRYPTO)
+
+static int
+aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
+{
+
+ switch (key_len) {
+ case 16: ctx->type = EVP_aes_128_ecb(); break;
+ case 24: ctx->type = EVP_aes_192_ecb(); break;
+ case 32: ctx->type = EVP_aes_256_ecb(); break;
+ default: ctx->type = NULL; return -1;
+ }
+
+ ctx->key_len = key_len;
+ memcpy(ctx->key, key, key_len);
+ memset(ctx->nonce, 0, sizeof(ctx->nonce));
+ ctx->encr_pos = AES_BLOCK_SIZE;
+ EVP_CIPHER_CTX_init(&ctx->ctx);
+ return 0;
+}
+
+static int
+aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
+{
+ int outl = 0;
+ int r;
+
+ r = EVP_EncryptInit_ex(&ctx->ctx, ctx->type, NULL, ctx->key, NULL);
+ if (r == 0)
+ return -1;
+ r = EVP_EncryptUpdate(&ctx->ctx, ctx->encr_buf, &outl, ctx->nonce,
+ AES_BLOCK_SIZE);
+ if (r == 0 || outl != AES_BLOCK_SIZE)
+ return -1;
+ return 0;
+}
+
+static int
+aes_ctr_release(archive_crypto_ctx *ctx)
+{
+ EVP_CIPHER_CTX_cleanup(&ctx->ctx);
+ memset(ctx->key, 0, ctx->key_len);
+ memset(ctx->nonce, 0, sizeof(ctx->nonce));
+ return 0;
+}
+
+#else
+
+#define ARCHIVE_CRYPTOR_STUB
+/* Stub */
+static int
+aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
+{
+ (void)ctx; /* UNUSED */
+ (void)key; /* UNUSED */
+ (void)key_len; /* UNUSED */
+ return -1;
+}
+
+static int
+aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
+{
+ (void)ctx; /* UNUSED */
+ return -1;
+}
+
+static int
+aes_ctr_release(archive_crypto_ctx *ctx)
+{
+ (void)ctx; /* UNUSED */
+ return 0;
+}
+
+#endif
+
+#ifdef ARCHIVE_CRYPTOR_STUB
+static int
+aes_ctr_update(archive_crypto_ctx *ctx, const uint8_t * const in,
+ size_t in_len, uint8_t * const out, size_t *out_len)
+{
+ (void)ctx; /* UNUSED */
+ (void)in; /* UNUSED */
+ (void)in_len; /* UNUSED */
+ (void)out; /* UNUSED */
+ (void)out_len; /* UNUSED */
+ aes_ctr_encrypt_counter(ctx); /* UNUSED */ /* Fix unused function warning */
+ return -1;
+}
+
+#else
+static void
+aes_ctr_increase_counter(archive_crypto_ctx *ctx)
+{
+ uint8_t *const nonce = ctx->nonce;
+ int j;
+
+ for (j = 0; j < 8; j++) {
+ if (++nonce[j])
+ break;
+ }
+}
+
+static int
+aes_ctr_update(archive_crypto_ctx *ctx, const uint8_t * const in,
+ size_t in_len, uint8_t * const out, size_t *out_len)
+{
+ uint8_t *const ebuf = ctx->encr_buf;
+ unsigned pos = ctx->encr_pos;
+ unsigned max = (unsigned)((in_len < *out_len)? in_len: *out_len);
+ unsigned i;
+
+ for (i = 0; i < max; ) {
+ if (pos == AES_BLOCK_SIZE) {
+ aes_ctr_increase_counter(ctx);
+ if (aes_ctr_encrypt_counter(ctx) != 0)
+ return -1;
+ while (max -i >= AES_BLOCK_SIZE) {
+ for (pos = 0; pos < AES_BLOCK_SIZE; pos++)
+ out[i+pos] = in[i+pos] ^ ebuf[pos];
+ i += AES_BLOCK_SIZE;
+ aes_ctr_increase_counter(ctx);
+ if (aes_ctr_encrypt_counter(ctx) != 0)
+ return -1;
+ }
+ pos = 0;
+ if (i >= max)
+ break;
+ }
+ out[i] = in[i] ^ ebuf[pos++];
+ i++;
+ }
+ ctx->encr_pos = pos;
+ *out_len = i;
+
+ return 0;
+}
+#endif /* ARCHIVE_CRYPTOR_STUB */
+
+
+const struct archive_cryptor __archive_cryptor =
+{
+ &pbkdf2_sha1,
+ &aes_ctr_init,
+ &aes_ctr_update,
+ &aes_ctr_release,
+ &aes_ctr_init,
+ &aes_ctr_update,
+ &aes_ctr_release,
+};
diff --git a/Utilities/cmlibarchive/libarchive/archive_cryptor_private.h b/Utilities/cmlibarchive/libarchive/archive_cryptor_private.h
new file mode 100644
index 000000000..9a96aeea6
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_cryptor_private.h
@@ -0,0 +1,152 @@
+/*-
+* Copyright (c) 2014 Michihiro NAKAJIMA
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#ifndef ARCHIVE_CRYPTOR_PRIVATE_H_INCLUDED
+#define ARCHIVE_CRYPTOR_PRIVATE_H_INCLUDED
+
+#ifdef __APPLE__
+# include <AvailabilityMacros.h>
+# if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
+# define ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto
+# endif
+#endif
+
+#ifdef ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto
+#include <CommonCrypto/CommonCryptor.h>
+#include <CommonCrypto/CommonKeyDerivation.h>
+#define AES_BLOCK_SIZE 16
+#define AES_MAX_KEY_SIZE kCCKeySizeAES256
+
+typedef struct {
+ CCCryptorRef ctx;
+ uint8_t key[AES_MAX_KEY_SIZE];
+ unsigned key_len;
+ uint8_t nonce[AES_BLOCK_SIZE];
+ uint8_t encr_buf[AES_BLOCK_SIZE];
+ unsigned encr_pos;
+} archive_crypto_ctx;
+
+#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
+#include <Bcrypt.h>
+
+/* Common in other bcrypt implementations, but missing from VS2008. */
+#ifndef BCRYPT_SUCCESS
+#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
+#endif
+
+#define AES_MAX_KEY_SIZE 32
+#define AES_BLOCK_SIZE 16
+typedef struct {
+ BCRYPT_ALG_HANDLE hAlg;
+ BCRYPT_KEY_HANDLE hKey;
+ PBYTE keyObj;
+ DWORD keyObj_len;
+ uint8_t nonce[AES_BLOCK_SIZE];
+ uint8_t encr_buf[AES_BLOCK_SIZE];
+ unsigned encr_pos;
+} archive_crypto_ctx;
+
+#elif defined(HAVE_LIBNETTLE)
+#if defined(HAVE_NETTLE_PBKDF2_H)
+#include <nettle/pbkdf2.h>
+#endif
+#include <nettle/aes.h>
+
+typedef struct {
+ struct aes_ctx ctx;
+ uint8_t key[AES_MAX_KEY_SIZE];
+ unsigned key_len;
+ uint8_t nonce[AES_BLOCK_SIZE];
+ uint8_t encr_buf[AES_BLOCK_SIZE];
+ unsigned encr_pos;
+} archive_crypto_ctx;
+
+#elif defined(HAVE_LIBCRYPTO)
+#include <openssl/evp.h>
+#define AES_BLOCK_SIZE 16
+#define AES_MAX_KEY_SIZE 32
+
+typedef struct {
+ EVP_CIPHER_CTX ctx;
+ const EVP_CIPHER *type;
+ uint8_t key[AES_MAX_KEY_SIZE];
+ unsigned key_len;
+ uint8_t nonce[AES_BLOCK_SIZE];
+ uint8_t encr_buf[AES_BLOCK_SIZE];
+ unsigned encr_pos;
+} archive_crypto_ctx;
+
+#else
+
+#define AES_BLOCK_SIZE 16
+#define AES_MAX_KEY_SIZE 32
+typedef int archive_crypto_ctx;
+
+#endif
+
+/* defines */
+#define archive_pbkdf2_sha1(pw, pw_len, salt, salt_len, rounds, dk, dk_len)\
+ __archive_cryptor.pbkdf2sha1(pw, pw_len, salt, salt_len, rounds, dk, dk_len)
+
+#define archive_decrypto_aes_ctr_init(ctx, key, key_len) \
+ __archive_cryptor.decrypto_aes_ctr_init(ctx, key, key_len)
+#define archive_decrypto_aes_ctr_update(ctx, in, in_len, out, out_len) \
+ __archive_cryptor.decrypto_aes_ctr_update(ctx, in, in_len, out, out_len)
+#define archive_decrypto_aes_ctr_release(ctx) \
+ __archive_cryptor.decrypto_aes_ctr_release(ctx)
+
+#define archive_encrypto_aes_ctr_init(ctx, key, key_len) \
+ __archive_cryptor.encrypto_aes_ctr_init(ctx, key, key_len)
+#define archive_encrypto_aes_ctr_update(ctx, in, in_len, out, out_len) \
+ __archive_cryptor.encrypto_aes_ctr_update(ctx, in, in_len, out, out_len)
+#define archive_encrypto_aes_ctr_release(ctx) \
+ __archive_cryptor.encrypto_aes_ctr_release(ctx)
+
+/* Minimal interface to cryptographic functionality for internal use in
+ * libarchive */
+struct archive_cryptor
+{
+ /* PKCS5 PBKDF2 HMAC-SHA1 */
+ int (*pbkdf2sha1)(const char *pw, size_t pw_len, const uint8_t *salt,
+ size_t salt_len, unsigned rounds, uint8_t *derived_key,
+ size_t derived_key_len);
+ /* AES CTR mode(little endian version) */
+ int (*decrypto_aes_ctr_init)(archive_crypto_ctx *, const uint8_t *, size_t);
+ int (*decrypto_aes_ctr_update)(archive_crypto_ctx *, const uint8_t *,
+ size_t, uint8_t *, size_t *);
+ int (*decrypto_aes_ctr_release)(archive_crypto_ctx *);
+ int (*encrypto_aes_ctr_init)(archive_crypto_ctx *, const uint8_t *, size_t);
+ int (*encrypto_aes_ctr_update)(archive_crypto_ctx *, const uint8_t *,
+ size_t, uint8_t *, size_t *);
+ int (*encrypto_aes_ctr_release)(archive_crypto_ctx *);
+};
+
+extern const struct archive_cryptor __archive_cryptor;
+
+#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_digest.c b/Utilities/cmlibarchive/libarchive/archive_digest.c
new file mode 100644
index 000000000..f009d317a
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_digest.c
@@ -0,0 +1,1429 @@
+/*-
+* Copyright (c) 2003-2007 Tim Kientzle
+* Copyright (c) 2011 Andres Mejia
+* Copyright (c) 2011 Michihiro NAKAJIMA
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "archive_platform.h"
+
+#include "archive.h"
+#include "archive_digest_private.h"
+
+/* In particular, force the configure probe to break if it tries
+ * to test a combination of OpenSSL and libmd. */
+#if defined(ARCHIVE_CRYPTO_OPENSSL) && defined(ARCHIVE_CRYPTO_LIBMD)
+#error Cannot use both OpenSSL and libmd.
+#endif
+
+/*
+ * Message digest functions for Windows platform.
+ */
+#if defined(ARCHIVE_CRYPTO_MD5_WIN) ||\
+ defined(ARCHIVE_CRYPTO_SHA1_WIN) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_WIN)
+
+/*
+ * Initialize a Message digest.
+ */
+static int
+win_crypto_init(Digest_CTX *ctx, ALG_ID algId)
+{
+
+ ctx->valid = 0;
+ if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL,
+ PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
+ if (GetLastError() != (DWORD)NTE_BAD_KEYSET)
+ return (ARCHIVE_FAILED);
+ if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL,
+ PROV_RSA_FULL, CRYPT_NEWKEYSET))
+ return (ARCHIVE_FAILED);
+ }
+
+ if (!CryptCreateHash(ctx->cryptProv, algId, 0, 0, &ctx->hash)) {
+ CryptReleaseContext(ctx->cryptProv, 0);
+ return (ARCHIVE_FAILED);
+ }
+
+ ctx->valid = 1;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Update a Message digest.
+ */
+static int
+win_crypto_Update(Digest_CTX *ctx, const unsigned char *buf, size_t len)
+{
+
+ if (!ctx->valid)
+ return (ARCHIVE_FAILED);
+
+ CryptHashData(ctx->hash,
+ (unsigned char *)(uintptr_t)buf,
+ (DWORD)len, 0);
+ return (ARCHIVE_OK);
+}
+
+static int
+win_crypto_Final(unsigned char *buf, size_t bufsize, Digest_CTX *ctx)
+{
+ DWORD siglen = (DWORD)bufsize;
+
+ if (!ctx->valid)
+ return (ARCHIVE_FAILED);
+
+ CryptGetHashParam(ctx->hash, HP_HASHVAL, buf, &siglen, 0);
+ CryptDestroyHash(ctx->hash);
+ CryptReleaseContext(ctx->cryptProv, 0);
+ ctx->valid = 0;
+ return (ARCHIVE_OK);
+}
+
+#endif /* defined(ARCHIVE_CRYPTO_*_WIN) */
+
+
+/* MD5 implementations */
+#if defined(ARCHIVE_CRYPTO_MD5_LIBC)
+
+static int
+__archive_libc_md5init(archive_md5_ctx *ctx)
+{
+ MD5Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc_md5update(archive_md5_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ MD5Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc_md5final(archive_md5_ctx *ctx, void *md)
+{
+ MD5Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_MD5_LIBMD)
+
+static int
+__archive_libmd_md5init(archive_md5_ctx *ctx)
+{
+ MD5Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libmd_md5update(archive_md5_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ MD5Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libmd_md5final(archive_md5_ctx *ctx, void *md)
+{
+ MD5Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM)
+
+static int
+__archive_libsystem_md5init(archive_md5_ctx *ctx)
+{
+ CC_MD5_Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libsystem_md5update(archive_md5_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ CC_MD5_Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libsystem_md5final(archive_md5_ctx *ctx, void *md)
+{
+ CC_MD5_Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_MD5_NETTLE)
+
+static int
+__archive_nettle_md5init(archive_md5_ctx *ctx)
+{
+ md5_init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_nettle_md5update(archive_md5_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ md5_update(ctx, insize, indata);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_nettle_md5final(archive_md5_ctx *ctx, void *md)
+{
+ md5_digest(ctx, MD5_DIGEST_SIZE, md);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_MD5_OPENSSL)
+
+static int
+__archive_openssl_md5init(archive_md5_ctx *ctx)
+{
+ EVP_DigestInit(ctx, EVP_md5());
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_openssl_md5update(archive_md5_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ EVP_DigestUpdate(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_openssl_md5final(archive_md5_ctx *ctx, void *md)
+{
+ /* HACK: archive_write_set_format_xar.c is finalizing empty contexts, so
+ * this is meant to cope with that. Real fix is probably to fix
+ * archive_write_set_format_xar.c
+ */
+ if (ctx->digest)
+ EVP_DigestFinal(ctx, md, NULL);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_MD5_WIN)
+
+static int
+__archive_windowsapi_md5init(archive_md5_ctx *ctx)
+{
+ return (win_crypto_init(ctx, CALG_MD5));
+}
+
+static int
+__archive_windowsapi_md5update(archive_md5_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ return (win_crypto_Update(ctx, indata, insize));
+}
+
+static int
+__archive_windowsapi_md5final(archive_md5_ctx *ctx, void *md)
+{
+ return (win_crypto_Final(md, 16, ctx));
+}
+
+#else
+
+static int
+__archive_stub_md5init(archive_md5_ctx *ctx)
+{
+ (void)ctx; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+static int
+__archive_stub_md5update(archive_md5_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ (void)ctx; /* UNUSED */
+ (void)indata; /* UNUSED */
+ (void)insize; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+static int
+__archive_stub_md5final(archive_md5_ctx *ctx, void *md)
+{
+ (void)ctx; /* UNUSED */
+ (void)md; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+#endif
+
+/* RIPEMD160 implementations */
+#if defined(ARCHIVE_CRYPTO_RMD160_LIBC)
+
+static int
+__archive_libc_ripemd160init(archive_rmd160_ctx *ctx)
+{
+ RMD160Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ RMD160Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc_ripemd160final(archive_rmd160_ctx *ctx, void *md)
+{
+ RMD160Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_RMD160_LIBMD)
+
+static int
+__archive_libmd_ripemd160init(archive_rmd160_ctx *ctx)
+{
+ RIPEMD160_Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libmd_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ RIPEMD160_Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libmd_ripemd160final(archive_rmd160_ctx *ctx, void *md)
+{
+ RIPEMD160_Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
+
+static int
+__archive_nettle_ripemd160init(archive_rmd160_ctx *ctx)
+{
+ ripemd160_init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_nettle_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ ripemd160_update(ctx, insize, indata);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_nettle_ripemd160final(archive_rmd160_ctx *ctx, void *md)
+{
+ ripemd160_digest(ctx, RIPEMD160_DIGEST_SIZE, md);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_RMD160_OPENSSL)
+
+static int
+__archive_openssl_ripemd160init(archive_rmd160_ctx *ctx)
+{
+ EVP_DigestInit(ctx, EVP_ripemd160());
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_openssl_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ EVP_DigestUpdate(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_openssl_ripemd160final(archive_rmd160_ctx *ctx, void *md)
+{
+ EVP_DigestFinal(ctx, md, NULL);
+ return (ARCHIVE_OK);
+}
+
+#else
+
+static int
+__archive_stub_ripemd160init(archive_rmd160_ctx *ctx)
+{
+ (void)ctx; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+static int
+__archive_stub_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ (void)ctx; /* UNUSED */
+ (void)indata; /* UNUSED */
+ (void)insize; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+static int
+__archive_stub_ripemd160final(archive_rmd160_ctx *ctx, void *md)
+{
+ (void)ctx; /* UNUSED */
+ (void)md; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+#endif
+
+/* SHA1 implementations */
+#if defined(ARCHIVE_CRYPTO_SHA1_LIBC)
+
+static int
+__archive_libc_sha1init(archive_sha1_ctx *ctx)
+{
+ SHA1Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc_sha1update(archive_sha1_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ SHA1Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc_sha1final(archive_sha1_ctx *ctx, void *md)
+{
+ SHA1Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA1_LIBMD)
+
+static int
+__archive_libmd_sha1init(archive_sha1_ctx *ctx)
+{
+ SHA1_Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libmd_sha1update(archive_sha1_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ SHA1_Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libmd_sha1final(archive_sha1_ctx *ctx, void *md)
+{
+ SHA1_Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM)
+
+static int
+__archive_libsystem_sha1init(archive_sha1_ctx *ctx)
+{
+ CC_SHA1_Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libsystem_sha1update(archive_sha1_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ CC_SHA1_Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libsystem_sha1final(archive_sha1_ctx *ctx, void *md)
+{
+ CC_SHA1_Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE)
+
+static int
+__archive_nettle_sha1init(archive_sha1_ctx *ctx)
+{
+ sha1_init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_nettle_sha1update(archive_sha1_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ sha1_update(ctx, insize, indata);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_nettle_sha1final(archive_sha1_ctx *ctx, void *md)
+{
+ sha1_digest(ctx, SHA1_DIGEST_SIZE, md);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA1_OPENSSL)
+
+static int
+__archive_openssl_sha1init(archive_sha1_ctx *ctx)
+{
+ EVP_DigestInit(ctx, EVP_sha1());
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_openssl_sha1update(archive_sha1_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ EVP_DigestUpdate(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_openssl_sha1final(archive_sha1_ctx *ctx, void *md)
+{
+ /* HACK: archive_write_set_format_xar.c is finalizing empty contexts, so
+ * this is meant to cope with that. Real fix is probably to fix
+ * archive_write_set_format_xar.c
+ */
+ if (ctx->digest)
+ EVP_DigestFinal(ctx, md, NULL);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA1_WIN)
+
+static int
+__archive_windowsapi_sha1init(archive_sha1_ctx *ctx)
+{
+ return (win_crypto_init(ctx, CALG_SHA1));
+}
+
+static int
+__archive_windowsapi_sha1update(archive_sha1_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ return (win_crypto_Update(ctx, indata, insize));
+}
+
+static int
+__archive_windowsapi_sha1final(archive_sha1_ctx *ctx, void *md)
+{
+ return (win_crypto_Final(md, 20, ctx));
+}
+
+#else
+
+static int
+__archive_stub_sha1init(archive_sha1_ctx *ctx)
+{
+ (void)ctx; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+static int
+__archive_stub_sha1update(archive_sha1_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ (void)ctx; /* UNUSED */
+ (void)indata; /* UNUSED */
+ (void)insize; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+static int
+__archive_stub_sha1final(archive_sha1_ctx *ctx, void *md)
+{
+ (void)ctx; /* UNUSED */
+ (void)md; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+#endif
+
+/* SHA256 implementations */
+#if defined(ARCHIVE_CRYPTO_SHA256_LIBC)
+
+static int
+__archive_libc_sha256init(archive_sha256_ctx *ctx)
+{
+ SHA256_Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc_sha256update(archive_sha256_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ SHA256_Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc_sha256final(archive_sha256_ctx *ctx, void *md)
+{
+ SHA256_Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC2)
+
+static int
+__archive_libc2_sha256init(archive_sha256_ctx *ctx)
+{
+ SHA256Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc2_sha256update(archive_sha256_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ SHA256Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc2_sha256final(archive_sha256_ctx *ctx, void *md)
+{
+ SHA256Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC3)
+
+static int
+__archive_libc3_sha256init(archive_sha256_ctx *ctx)
+{
+ SHA256Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc3_sha256update(archive_sha256_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ SHA256Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc3_sha256final(archive_sha256_ctx *ctx, void *md)
+{
+ SHA256Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA256_LIBMD)
+
+static int
+__archive_libmd_sha256init(archive_sha256_ctx *ctx)
+{
+ SHA256_Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libmd_sha256update(archive_sha256_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ SHA256_Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libmd_sha256final(archive_sha256_ctx *ctx, void *md)
+{
+ SHA256_Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM)
+
+static int
+__archive_libsystem_sha256init(archive_sha256_ctx *ctx)
+{
+ CC_SHA256_Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libsystem_sha256update(archive_sha256_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ CC_SHA256_Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libsystem_sha256final(archive_sha256_ctx *ctx, void *md)
+{
+ CC_SHA256_Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE)
+
+static int
+__archive_nettle_sha256init(archive_sha256_ctx *ctx)
+{
+ sha256_init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_nettle_sha256update(archive_sha256_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ sha256_update(ctx, insize, indata);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_nettle_sha256final(archive_sha256_ctx *ctx, void *md)
+{
+ sha256_digest(ctx, SHA256_DIGEST_SIZE, md);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA256_OPENSSL)
+
+static int
+__archive_openssl_sha256init(archive_sha256_ctx *ctx)
+{
+ EVP_DigestInit(ctx, EVP_sha256());
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_openssl_sha256update(archive_sha256_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ EVP_DigestUpdate(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_openssl_sha256final(archive_sha256_ctx *ctx, void *md)
+{
+ EVP_DigestFinal(ctx, md, NULL);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA256_WIN)
+
+static int
+__archive_windowsapi_sha256init(archive_sha256_ctx *ctx)
+{
+ return (win_crypto_init(ctx, CALG_SHA_256));
+}
+
+static int
+__archive_windowsapi_sha256update(archive_sha256_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ return (win_crypto_Update(ctx, indata, insize));
+}
+
+static int
+__archive_windowsapi_sha256final(archive_sha256_ctx *ctx, void *md)
+{
+ return (win_crypto_Final(md, 32, ctx));
+}
+
+#else
+
+static int
+__archive_stub_sha256init(archive_sha256_ctx *ctx)
+{
+ (void)ctx; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+static int
+__archive_stub_sha256update(archive_sha256_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ (void)ctx; /* UNUSED */
+ (void)indata; /* UNUSED */
+ (void)insize; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+static int
+__archive_stub_sha256final(archive_sha256_ctx *ctx, void *md)
+{
+ (void)ctx; /* UNUSED */
+ (void)md; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+#endif
+
+/* SHA384 implementations */
+#if defined(ARCHIVE_CRYPTO_SHA384_LIBC)
+
+static int
+__archive_libc_sha384init(archive_sha384_ctx *ctx)
+{
+ SHA384_Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc_sha384update(archive_sha384_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ SHA384_Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc_sha384final(archive_sha384_ctx *ctx, void *md)
+{
+ SHA384_Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC2)
+
+static int
+__archive_libc2_sha384init(archive_sha384_ctx *ctx)
+{
+ SHA384Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc2_sha384update(archive_sha384_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ SHA384Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc2_sha384final(archive_sha384_ctx *ctx, void *md)
+{
+ SHA384Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC3)
+
+static int
+__archive_libc3_sha384init(archive_sha384_ctx *ctx)
+{
+ SHA384Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc3_sha384update(archive_sha384_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ SHA384Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc3_sha384final(archive_sha384_ctx *ctx, void *md)
+{
+ SHA384Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM)
+
+static int
+__archive_libsystem_sha384init(archive_sha384_ctx *ctx)
+{
+ CC_SHA384_Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libsystem_sha384update(archive_sha384_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ CC_SHA384_Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libsystem_sha384final(archive_sha384_ctx *ctx, void *md)
+{
+ CC_SHA384_Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE)
+
+static int
+__archive_nettle_sha384init(archive_sha384_ctx *ctx)
+{
+ sha384_init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_nettle_sha384update(archive_sha384_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ sha384_update(ctx, insize, indata);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_nettle_sha384final(archive_sha384_ctx *ctx, void *md)
+{
+ sha384_digest(ctx, SHA384_DIGEST_SIZE, md);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA384_OPENSSL)
+
+static int
+__archive_openssl_sha384init(archive_sha384_ctx *ctx)
+{
+ EVP_DigestInit(ctx, EVP_sha384());
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_openssl_sha384update(archive_sha384_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ EVP_DigestUpdate(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_openssl_sha384final(archive_sha384_ctx *ctx, void *md)
+{
+ EVP_DigestFinal(ctx, md, NULL);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA384_WIN)
+
+static int
+__archive_windowsapi_sha384init(archive_sha384_ctx *ctx)
+{
+ return (win_crypto_init(ctx, CALG_SHA_384));
+}
+
+static int
+__archive_windowsapi_sha384update(archive_sha384_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ return (win_crypto_Update(ctx, indata, insize));
+}
+
+static int
+__archive_windowsapi_sha384final(archive_sha384_ctx *ctx, void *md)
+{
+ return (win_crypto_Final(md, 48, ctx));
+}
+
+#else
+
+static int
+__archive_stub_sha384init(archive_sha384_ctx *ctx)
+{
+ (void)ctx; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+static int
+__archive_stub_sha384update(archive_sha384_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ (void)ctx; /* UNUSED */
+ (void)indata; /* UNUSED */
+ (void)insize; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+static int
+__archive_stub_sha384final(archive_sha384_ctx *ctx, void *md)
+{
+ (void)ctx; /* UNUSED */
+ (void)md; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+#endif
+
+/* SHA512 implementations */
+#if defined(ARCHIVE_CRYPTO_SHA512_LIBC)
+
+static int
+__archive_libc_sha512init(archive_sha512_ctx *ctx)
+{
+ SHA512_Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc_sha512update(archive_sha512_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ SHA512_Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc_sha512final(archive_sha512_ctx *ctx, void *md)
+{
+ SHA512_Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC2)
+
+static int
+__archive_libc2_sha512init(archive_sha512_ctx *ctx)
+{
+ SHA512Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc2_sha512update(archive_sha512_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ SHA512Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc2_sha512final(archive_sha512_ctx *ctx, void *md)
+{
+ SHA512Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC3)
+
+static int
+__archive_libc3_sha512init(archive_sha512_ctx *ctx)
+{
+ SHA512Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc3_sha512update(archive_sha512_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ SHA512Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libc3_sha512final(archive_sha512_ctx *ctx, void *md)
+{
+ SHA512Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
+
+static int
+__archive_libmd_sha512init(archive_sha512_ctx *ctx)
+{
+ SHA512_Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libmd_sha512update(archive_sha512_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ SHA512_Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libmd_sha512final(archive_sha512_ctx *ctx, void *md)
+{
+ SHA512_Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM)
+
+static int
+__archive_libsystem_sha512init(archive_sha512_ctx *ctx)
+{
+ CC_SHA512_Init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libsystem_sha512update(archive_sha512_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ CC_SHA512_Update(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_libsystem_sha512final(archive_sha512_ctx *ctx, void *md)
+{
+ CC_SHA512_Final(md, ctx);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
+
+static int
+__archive_nettle_sha512init(archive_sha512_ctx *ctx)
+{
+ sha512_init(ctx);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_nettle_sha512update(archive_sha512_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ sha512_update(ctx, insize, indata);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_nettle_sha512final(archive_sha512_ctx *ctx, void *md)
+{
+ sha512_digest(ctx, SHA512_DIGEST_SIZE, md);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA512_OPENSSL)
+
+static int
+__archive_openssl_sha512init(archive_sha512_ctx *ctx)
+{
+ EVP_DigestInit(ctx, EVP_sha512());
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_openssl_sha512update(archive_sha512_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ EVP_DigestUpdate(ctx, indata, insize);
+ return (ARCHIVE_OK);
+}
+
+static int
+__archive_openssl_sha512final(archive_sha512_ctx *ctx, void *md)
+{
+ EVP_DigestFinal(ctx, md, NULL);
+ return (ARCHIVE_OK);
+}
+
+#elif defined(ARCHIVE_CRYPTO_SHA512_WIN)
+
+static int
+__archive_windowsapi_sha512init(archive_sha512_ctx *ctx)
+{
+ return (win_crypto_init(ctx, CALG_SHA_512));
+}
+
+static int
+__archive_windowsapi_sha512update(archive_sha512_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ return (win_crypto_Update(ctx, indata, insize));
+}
+
+static int
+__archive_windowsapi_sha512final(archive_sha512_ctx *ctx, void *md)
+{
+ return (win_crypto_Final(md, 64, ctx));
+}
+
+#else
+
+static int
+__archive_stub_sha512init(archive_sha512_ctx *ctx)
+{
+ (void)ctx; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+static int
+__archive_stub_sha512update(archive_sha512_ctx *ctx, const void *indata,
+ size_t insize)
+{
+ (void)ctx; /* UNUSED */
+ (void)indata; /* UNUSED */
+ (void)insize; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+static int
+__archive_stub_sha512final(archive_sha512_ctx *ctx, void *md)
+{
+ (void)ctx; /* UNUSED */
+ (void)md; /* UNUSED */
+ return (ARCHIVE_FAILED);
+}
+
+#endif
+
+/* NOTE: Message Digest functions are set based on availability and by the
+ * following order of preference.
+ * 1. libc
+ * 2. libc2
+ * 3. libc3
+ * 4. libSystem
+ * 5. Nettle
+ * 6. OpenSSL
+ * 7. libmd
+ * 8. Windows API
+ */
+const struct archive_digest __archive_digest =
+{
+/* MD5 */
+#if defined(ARCHIVE_CRYPTO_MD5_LIBC)
+ &__archive_libc_md5init,
+ &__archive_libc_md5update,
+ &__archive_libc_md5final,
+#elif defined(ARCHIVE_CRYPTO_MD5_LIBMD)
+ &__archive_libmd_md5init,
+ &__archive_libmd_md5update,
+ &__archive_libmd_md5final,
+#elif defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM)
+ &__archive_libsystem_md5init,
+ &__archive_libsystem_md5update,
+ &__archive_libsystem_md5final,
+#elif defined(ARCHIVE_CRYPTO_MD5_NETTLE)
+ &__archive_nettle_md5init,
+ &__archive_nettle_md5update,
+ &__archive_nettle_md5final,
+#elif defined(ARCHIVE_CRYPTO_MD5_OPENSSL)
+ &__archive_openssl_md5init,
+ &__archive_openssl_md5update,
+ &__archive_openssl_md5final,
+#elif defined(ARCHIVE_CRYPTO_MD5_WIN)
+ &__archive_windowsapi_md5init,
+ &__archive_windowsapi_md5update,
+ &__archive_windowsapi_md5final,
+#elif !defined(ARCHIVE_MD5_COMPILE_TEST)
+ &__archive_stub_md5init,
+ &__archive_stub_md5update,
+ &__archive_stub_md5final,
+#endif
+
+/* RIPEMD160 */
+#if defined(ARCHIVE_CRYPTO_RMD160_LIBC)
+ &__archive_libc_ripemd160init,
+ &__archive_libc_ripemd160update,
+ &__archive_libc_ripemd160final,
+#elif defined(ARCHIVE_CRYPTO_RMD160_LIBMD)
+ &__archive_libmd_ripemd160init,
+ &__archive_libmd_ripemd160update,
+ &__archive_libmd_ripemd160final,
+#elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
+ &__archive_nettle_ripemd160init,
+ &__archive_nettle_ripemd160update,
+ &__archive_nettle_ripemd160final,
+#elif defined(ARCHIVE_CRYPTO_RMD160_OPENSSL)
+ &__archive_openssl_ripemd160init,
+ &__archive_openssl_ripemd160update,
+ &__archive_openssl_ripemd160final,
+#elif !defined(ARCHIVE_RMD160_COMPILE_TEST)
+ &__archive_stub_ripemd160init,
+ &__archive_stub_ripemd160update,
+ &__archive_stub_ripemd160final,
+#endif
+
+/* SHA1 */
+#if defined(ARCHIVE_CRYPTO_SHA1_LIBC)
+ &__archive_libc_sha1init,
+ &__archive_libc_sha1update,
+ &__archive_libc_sha1final,
+#elif defined(ARCHIVE_CRYPTO_SHA1_LIBMD)
+ &__archive_libmd_sha1init,
+ &__archive_libmd_sha1update,
+ &__archive_libmd_sha1final,
+#elif defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM)
+ &__archive_libsystem_sha1init,
+ &__archive_libsystem_sha1update,
+ &__archive_libsystem_sha1final,
+#elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE)
+ &__archive_nettle_sha1init,
+ &__archive_nettle_sha1update,
+ &__archive_nettle_sha1final,
+#elif defined(ARCHIVE_CRYPTO_SHA1_OPENSSL)
+ &__archive_openssl_sha1init,
+ &__archive_openssl_sha1update,
+ &__archive_openssl_sha1final,
+#elif defined(ARCHIVE_CRYPTO_SHA1_WIN)
+ &__archive_windowsapi_sha1init,
+ &__archive_windowsapi_sha1update,
+ &__archive_windowsapi_sha1final,
+#elif !defined(ARCHIVE_SHA1_COMPILE_TEST)
+ &__archive_stub_sha1init,
+ &__archive_stub_sha1update,
+ &__archive_stub_sha1final,
+#endif
+
+/* SHA256 */
+#if defined(ARCHIVE_CRYPTO_SHA256_LIBC)
+ &__archive_libc_sha256init,
+ &__archive_libc_sha256update,
+ &__archive_libc_sha256final,
+#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC2)
+ &__archive_libc2_sha256init,
+ &__archive_libc2_sha256update,
+ &__archive_libc2_sha256final,
+#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC3)
+ &__archive_libc3_sha256init,
+ &__archive_libc3_sha256update,
+ &__archive_libc3_sha256final,
+#elif defined(ARCHIVE_CRYPTO_SHA256_LIBMD)
+ &__archive_libmd_sha256init,
+ &__archive_libmd_sha256update,
+ &__archive_libmd_sha256final,
+#elif defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM)
+ &__archive_libsystem_sha256init,
+ &__archive_libsystem_sha256update,
+ &__archive_libsystem_sha256final,
+#elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE)
+ &__archive_nettle_sha256init,
+ &__archive_nettle_sha256update,
+ &__archive_nettle_sha256final,
+#elif defined(ARCHIVE_CRYPTO_SHA256_OPENSSL)
+ &__archive_openssl_sha256init,
+ &__archive_openssl_sha256update,
+ &__archive_openssl_sha256final,
+#elif defined(ARCHIVE_CRYPTO_SHA256_WIN)
+ &__archive_windowsapi_sha256init,
+ &__archive_windowsapi_sha256update,
+ &__archive_windowsapi_sha256final,
+#elif !defined(ARCHIVE_SHA256_COMPILE_TEST)
+ &__archive_stub_sha256init,
+ &__archive_stub_sha256update,
+ &__archive_stub_sha256final,
+#endif
+
+/* SHA384 */
+#if defined(ARCHIVE_CRYPTO_SHA384_LIBC)
+ &__archive_libc_sha384init,
+ &__archive_libc_sha384update,
+ &__archive_libc_sha384final,
+#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC2)
+ &__archive_libc2_sha384init,
+ &__archive_libc2_sha384update,
+ &__archive_libc2_sha384final,
+#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC3)
+ &__archive_libc3_sha384init,
+ &__archive_libc3_sha384update,
+ &__archive_libc3_sha384final,
+#elif defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM)
+ &__archive_libsystem_sha384init,
+ &__archive_libsystem_sha384update,
+ &__archive_libsystem_sha384final,
+#elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE)
+ &__archive_nettle_sha384init,
+ &__archive_nettle_sha384update,
+ &__archive_nettle_sha384final,
+#elif defined(ARCHIVE_CRYPTO_SHA384_OPENSSL)
+ &__archive_openssl_sha384init,
+ &__archive_openssl_sha384update,
+ &__archive_openssl_sha384final,
+#elif defined(ARCHIVE_CRYPTO_SHA384_WIN)
+ &__archive_windowsapi_sha384init,
+ &__archive_windowsapi_sha384update,
+ &__archive_windowsapi_sha384final,
+#elif !defined(ARCHIVE_SHA384_COMPILE_TEST)
+ &__archive_stub_sha384init,
+ &__archive_stub_sha384update,
+ &__archive_stub_sha384final,
+#endif
+
+/* SHA512 */
+#if defined(ARCHIVE_CRYPTO_SHA512_LIBC)
+ &__archive_libc_sha512init,
+ &__archive_libc_sha512update,
+ &__archive_libc_sha512final
+#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC2)
+ &__archive_libc2_sha512init,
+ &__archive_libc2_sha512update,
+ &__archive_libc2_sha512final
+#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC3)
+ &__archive_libc3_sha512init,
+ &__archive_libc3_sha512update,
+ &__archive_libc3_sha512final
+#elif defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
+ &__archive_libmd_sha512init,
+ &__archive_libmd_sha512update,
+ &__archive_libmd_sha512final
+#elif defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM)
+ &__archive_libsystem_sha512init,
+ &__archive_libsystem_sha512update,
+ &__archive_libsystem_sha512final
+#elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
+ &__archive_nettle_sha512init,
+ &__archive_nettle_sha512update,
+ &__archive_nettle_sha512final
+#elif defined(ARCHIVE_CRYPTO_SHA512_OPENSSL)
+ &__archive_openssl_sha512init,
+ &__archive_openssl_sha512update,
+ &__archive_openssl_sha512final
+#elif defined(ARCHIVE_CRYPTO_SHA512_WIN)
+ &__archive_windowsapi_sha512init,
+ &__archive_windowsapi_sha512update,
+ &__archive_windowsapi_sha512final
+#elif !defined(ARCHIVE_SHA512_COMPILE_TEST)
+ &__archive_stub_sha512init,
+ &__archive_stub_sha512update,
+ &__archive_stub_sha512final
+#endif
+};
diff --git a/Utilities/cmlibarchive/libarchive/archive_digest_private.h b/Utilities/cmlibarchive/libarchive/archive_digest_private.h
new file mode 100644
index 000000000..77fad5806
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_digest_private.h
@@ -0,0 +1,376 @@
+/*-
+* Copyright (c) 2003-2007 Tim Kientzle
+* Copyright (c) 2011 Andres Mejia
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#ifndef ARCHIVE_CRYPTO_PRIVATE_H_INCLUDED
+#define ARCHIVE_CRYPTO_PRIVATE_H_INCLUDED
+
+/*
+ * Crypto support in various Operating Systems:
+ *
+ * NetBSD:
+ * - MD5 and SHA1 in libc: without _ after algorithm name
+ * - SHA2 in libc: with _ after algorithm name
+ *
+ * OpenBSD:
+ * - MD5, SHA1 and SHA2 in libc: without _ after algorithm name
+ * - OpenBSD 4.4 and earlier have SHA2 in libc with _ after algorithm name
+ *
+ * DragonFly and FreeBSD:
+ * - MD5 libmd: without _ after algorithm name
+ * - SHA1, SHA256 and SHA512 in libmd: with _ after algorithm name
+ *
+ * Mac OS X (10.4 and later):
+ * - MD5, SHA1 and SHA2 in libSystem: with CC_ prefix and _ after algorithm name
+ *
+ * OpenSSL:
+ * - MD5, SHA1 and SHA2 in libcrypto: with _ after algorithm name
+ *
+ * Windows:
+ * - MD5, SHA1 and SHA2 in archive_crypto.c using Windows crypto API
+ */
+
+/* libc crypto headers */
+#if defined(ARCHIVE_CRYPTO_MD5_LIBC)
+#include <md5.h>
+#endif
+#if defined(ARCHIVE_CRYPTO_RMD160_LIBC)
+#include <rmd160.h>
+#endif
+#if defined(ARCHIVE_CRYPTO_SHA1_LIBC)
+#include <sha1.h>
+#endif
+#if defined(ARCHIVE_CRYPTO_SHA256_LIBC) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_LIBC2) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_LIBC3) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_LIBC) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_LIBC2) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_LIBC3) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_LIBC) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_LIBC2) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_LIBC3)
+#include <sha2.h>
+#endif
+
+/* libmd crypto headers */
+#if defined(ARCHIVE_CRYPTO_MD5_LIBMD) ||\
+ defined(ARCHIVE_CRYPTO_RMD160_LIBMD) ||\
+ defined(ARCHIVE_CRYPTO_SHA1_LIBMD) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_LIBMD) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
+#define ARCHIVE_CRYPTO_LIBMD 1
+#endif
+
+#if defined(ARCHIVE_CRYPTO_MD5_LIBMD)
+#include <md5.h>
+#endif
+#if defined(ARCHIVE_CRYPTO_RMD160_LIBMD)
+#include <ripemd.h>
+#endif
+#if defined(ARCHIVE_CRYPTO_SHA1_LIBMD)
+#include <sha.h>
+#endif
+#if defined(ARCHIVE_CRYPTO_SHA256_LIBMD)
+#include <sha256.h>
+#endif
+#if defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
+#include <sha512.h>
+#endif
+
+/* libSystem crypto headers */
+#if defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM) ||\
+ defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM)
+#include <CommonCrypto/CommonDigest.h>
+#endif
+
+/* Nettle crypto headers */
+#if defined(ARCHIVE_CRYPTO_MD5_NETTLE)
+#include <nettle/md5.h>
+#endif
+#if defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
+#include <nettle/ripemd160.h>
+#endif
+#if defined(ARCHIVE_CRYPTO_SHA1_NETTLE) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_NETTLE) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_NETTLE) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
+#include <nettle/sha.h>
+#endif
+
+/* OpenSSL crypto headers */
+#if defined(ARCHIVE_CRYPTO_MD5_OPENSSL) ||\
+ defined(ARCHIVE_CRYPTO_RMD160_OPENSSL) ||\
+ defined(ARCHIVE_CRYPTO_SHA1_OPENSSL) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_OPENSSL) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_OPENSSL) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_OPENSSL)
+#define ARCHIVE_CRYPTO_OPENSSL 1
+#include <openssl/evp.h>
+#endif
+
+/* Windows crypto headers */
+#if defined(ARCHIVE_CRYPTO_MD5_WIN) ||\
+ defined(ARCHIVE_CRYPTO_SHA1_WIN) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_WIN)
+#include <wincrypt.h>
+typedef struct {
+ int valid;
+ HCRYPTPROV cryptProv;
+ HCRYPTHASH hash;
+} Digest_CTX;
+#endif
+
+/* typedefs */
+#if defined(ARCHIVE_CRYPTO_MD5_LIBC)
+typedef MD5_CTX archive_md5_ctx;
+#elif defined(ARCHIVE_CRYPTO_MD5_LIBMD)
+typedef MD5_CTX archive_md5_ctx;
+#elif defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM)
+typedef CC_MD5_CTX archive_md5_ctx;
+#elif defined(ARCHIVE_CRYPTO_MD5_NETTLE)
+typedef struct md5_ctx archive_md5_ctx;
+#elif defined(ARCHIVE_CRYPTO_MD5_OPENSSL)
+typedef EVP_MD_CTX archive_md5_ctx;
+#elif defined(ARCHIVE_CRYPTO_MD5_WIN)
+typedef Digest_CTX archive_md5_ctx;
+#else
+typedef unsigned char archive_md5_ctx;
+#endif
+
+#if defined(ARCHIVE_CRYPTO_RMD160_LIBC)
+typedef RMD160_CTX archive_rmd160_ctx;
+#elif defined(ARCHIVE_CRYPTO_RMD160_LIBMD)
+typedef RIPEMD160_CTX archive_rmd160_ctx;
+#elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
+typedef struct ripemd160_ctx archive_rmd160_ctx;
+#elif defined(ARCHIVE_CRYPTO_RMD160_OPENSSL)
+typedef EVP_MD_CTX archive_rmd160_ctx;
+#else
+typedef unsigned char archive_rmd160_ctx;
+#endif
+
+#if defined(ARCHIVE_CRYPTO_SHA1_LIBC)
+typedef SHA1_CTX archive_sha1_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA1_LIBMD)
+typedef SHA1_CTX archive_sha1_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM)
+typedef CC_SHA1_CTX archive_sha1_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE)
+typedef struct sha1_ctx archive_sha1_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA1_OPENSSL)
+typedef EVP_MD_CTX archive_sha1_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA1_WIN)
+typedef Digest_CTX archive_sha1_ctx;
+#else
+typedef unsigned char archive_sha1_ctx;
+#endif
+
+#if defined(ARCHIVE_CRYPTO_SHA256_LIBC)
+typedef SHA256_CTX archive_sha256_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC2)
+typedef SHA256_CTX archive_sha256_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC3)
+typedef SHA2_CTX archive_sha256_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA256_LIBMD)
+typedef SHA256_CTX archive_sha256_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM)
+typedef CC_SHA256_CTX archive_sha256_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE)
+typedef struct sha256_ctx archive_sha256_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA256_OPENSSL)
+typedef EVP_MD_CTX archive_sha256_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA256_WIN)
+typedef Digest_CTX archive_sha256_ctx;
+#else
+typedef unsigned char archive_sha256_ctx;
+#endif
+
+#if defined(ARCHIVE_CRYPTO_SHA384_LIBC)
+typedef SHA384_CTX archive_sha384_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC2)
+typedef SHA384_CTX archive_sha384_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC3)
+typedef SHA2_CTX archive_sha384_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM)
+typedef CC_SHA512_CTX archive_sha384_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE)
+typedef struct sha384_ctx archive_sha384_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA384_OPENSSL)
+typedef EVP_MD_CTX archive_sha384_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA384_WIN)
+typedef Digest_CTX archive_sha384_ctx;
+#else
+typedef unsigned char archive_sha384_ctx;
+#endif
+
+#if defined(ARCHIVE_CRYPTO_SHA512_LIBC)
+typedef SHA512_CTX archive_sha512_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC2)
+typedef SHA512_CTX archive_sha512_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC3)
+typedef SHA2_CTX archive_sha512_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
+typedef SHA512_CTX archive_sha512_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM)
+typedef CC_SHA512_CTX archive_sha512_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
+typedef struct sha512_ctx archive_sha512_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA512_OPENSSL)
+typedef EVP_MD_CTX archive_sha512_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA512_WIN)
+typedef Digest_CTX archive_sha512_ctx;
+#else
+typedef unsigned char archive_sha512_ctx;
+#endif
+
+/* defines */
+#if defined(ARCHIVE_CRYPTO_MD5_LIBC) ||\
+ defined(ARCHIVE_CRYPTO_MD5_LIBMD) || \
+ defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM) ||\
+ defined(ARCHIVE_CRYPTO_MD5_NETTLE) ||\
+ defined(ARCHIVE_CRYPTO_MD5_OPENSSL) ||\
+ defined(ARCHIVE_CRYPTO_MD5_WIN)
+#define ARCHIVE_HAS_MD5
+#endif
+#define archive_md5_init(ctx)\
+ __archive_digest.md5init(ctx)
+#define archive_md5_final(ctx, md)\
+ __archive_digest.md5final(ctx, md)
+#define archive_md5_update(ctx, buf, n)\
+ __archive_digest.md5update(ctx, buf, n)
+
+#if defined(ARCHIVE_CRYPTO_RMD160_LIBC) ||\
+ defined(ARCHIVE_CRYPTO_RMD160_NETTLE) ||\
+ defined(ARCHIVE_CRYPTO_RMD160_OPENSSL)
+#define ARCHIVE_HAS_RMD160
+#endif
+#define archive_rmd160_init(ctx)\
+ __archive_digest.rmd160init(ctx)
+#define archive_rmd160_final(ctx, md)\
+ __archive_digest.rmd160final(ctx, md)
+#define archive_rmd160_update(ctx, buf, n)\
+ __archive_digest.rmd160update(ctx, buf, n)
+
+#if defined(ARCHIVE_CRYPTO_SHA1_LIBC) ||\
+ defined(ARCHIVE_CRYPTO_SHA1_LIBMD) || \
+ defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM) ||\
+ defined(ARCHIVE_CRYPTO_SHA1_NETTLE) ||\
+ defined(ARCHIVE_CRYPTO_SHA1_OPENSSL) ||\
+ defined(ARCHIVE_CRYPTO_SHA1_WIN)
+#define ARCHIVE_HAS_SHA1
+#endif
+#define archive_sha1_init(ctx)\
+ __archive_digest.sha1init(ctx)
+#define archive_sha1_final(ctx, md)\
+ __archive_digest.sha1final(ctx, md)
+#define archive_sha1_update(ctx, buf, n)\
+ __archive_digest.sha1update(ctx, buf, n)
+
+#if defined(ARCHIVE_CRYPTO_SHA256_LIBC) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_LIBC2) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_LIBC3) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_LIBMD) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_NETTLE) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_OPENSSL) ||\
+ defined(ARCHIVE_CRYPTO_SHA256_WIN)
+#define ARCHIVE_HAS_SHA256
+#endif
+#define archive_sha256_init(ctx)\
+ __archive_digest.sha256init(ctx)
+#define archive_sha256_final(ctx, md)\
+ __archive_digest.sha256final(ctx, md)
+#define archive_sha256_update(ctx, buf, n)\
+ __archive_digest.sha256update(ctx, buf, n)
+
+#if defined(ARCHIVE_CRYPTO_SHA384_LIBC) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_LIBC2) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_LIBC3) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_NETTLE) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_OPENSSL) ||\
+ defined(ARCHIVE_CRYPTO_SHA384_WIN)
+#define ARCHIVE_HAS_SHA384
+#endif
+#define archive_sha384_init(ctx)\
+ __archive_digest.sha384init(ctx)
+#define archive_sha384_final(ctx, md)\
+ __archive_digest.sha384final(ctx, md)
+#define archive_sha384_update(ctx, buf, n)\
+ __archive_digest.sha384update(ctx, buf, n)
+
+#if defined(ARCHIVE_CRYPTO_SHA512_LIBC) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_LIBC2) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_LIBC3) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_LIBMD) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_NETTLE) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_OPENSSL) ||\
+ defined(ARCHIVE_CRYPTO_SHA512_WIN)
+#define ARCHIVE_HAS_SHA512
+#endif
+#define archive_sha512_init(ctx)\
+ __archive_digest.sha512init(ctx)
+#define archive_sha512_final(ctx, md)\
+ __archive_digest.sha512final(ctx, md)
+#define archive_sha512_update(ctx, buf, n)\
+ __archive_digest.sha512update(ctx, buf, n)
+
+/* Minimal interface to digest functionality for internal use in libarchive */
+struct archive_digest
+{
+ /* Message Digest */
+ int (*md5init)(archive_md5_ctx *ctx);
+ int (*md5update)(archive_md5_ctx *, const void *, size_t);
+ int (*md5final)(archive_md5_ctx *, void *);
+ int (*rmd160init)(archive_rmd160_ctx *);
+ int (*rmd160update)(archive_rmd160_ctx *, const void *, size_t);
+ int (*rmd160final)(archive_rmd160_ctx *, void *);
+ int (*sha1init)(archive_sha1_ctx *);
+ int (*sha1update)(archive_sha1_ctx *, const void *, size_t);
+ int (*sha1final)(archive_sha1_ctx *, void *);
+ int (*sha256init)(archive_sha256_ctx *);
+ int (*sha256update)(archive_sha256_ctx *, const void *, size_t);
+ int (*sha256final)(archive_sha256_ctx *, void *);
+ int (*sha384init)(archive_sha384_ctx *);
+ int (*sha384update)(archive_sha384_ctx *, const void *, size_t);
+ int (*sha384final)(archive_sha384_ctx *, void *);
+ int (*sha512init)(archive_sha512_ctx *);
+ int (*sha512update)(archive_sha512_ctx *, const void *, size_t);
+ int (*sha512final)(archive_sha512_ctx *, void *);
+};
+
+extern const struct archive_digest __archive_digest;
+
+#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry.3 b/Utilities/cmlibarchive/libarchive/archive_entry.3
index f77f385f2..f5e22af85 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry.3
@@ -131,11 +131,11 @@ be discarded in favor of the new data.
.\" .Sh RETURN VALUES
.\" .Sh ERRORS
.Sh SEE ALSO
-.Xr archive 3 ,
.Xr archive_entry_acl 3 ,
.Xr archive_entry_paths 3 ,
.Xr archive_entry_perms 3 ,
.Xr archive_entry_time 3
+.Xr libarchive 3 ,
.Sh HISTORY
The
.Nm libarchive
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry.c b/Utilities/cmlibarchive/libarchive/archive_entry.c
index 386e51d47..4ac196608 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry.c
+++ b/Utilities/cmlibarchive/libarchive/archive_entry.c
@@ -201,6 +201,9 @@ archive_entry_clone(struct archive_entry *entry)
entry2->ae_set = entry->ae_set;
archive_mstring_copy(&entry2->ae_uname, &entry->ae_uname);
+ /* Copy encryption status */
+ entry2->encryption = entry->encryption;
+
/* Copy ACL data over. */
archive_acl_copy(&entry2->acl, &entry->acl);
@@ -415,6 +418,18 @@ archive_entry_gname(struct archive_entry *entry)
return (NULL);
}
+const char *
+archive_entry_gname_utf8(struct archive_entry *entry)
+{
+ const char *p;
+ if (archive_mstring_get_utf8(entry->archive, &entry->ae_gname, &p) == 0)
+ return (p);
+ if (errno == ENOMEM)
+ __archive_errx(1, "No memory");
+ return (NULL);
+}
+
+
const wchar_t *
archive_entry_gname_w(struct archive_entry *entry)
{
@@ -447,6 +462,20 @@ archive_entry_hardlink(struct archive_entry *entry)
return (NULL);
}
+const char *
+archive_entry_hardlink_utf8(struct archive_entry *entry)
+{
+ const char *p;
+ if ((entry->ae_set & AE_SET_HARDLINK) == 0)
+ return (NULL);
+ if (archive_mstring_get_utf8(
+ entry->archive, &entry->ae_hardlink, &p) == 0)
+ return (p);
+ if (errno == ENOMEM)
+ __archive_errx(1, "No memory");
+ return (NULL);
+}
+
const wchar_t *
archive_entry_hardlink_w(struct archive_entry *entry)
{
@@ -533,6 +562,18 @@ archive_entry_pathname(struct archive_entry *entry)
return (NULL);
}
+const char *
+archive_entry_pathname_utf8(struct archive_entry *entry)
+{
+ const char *p;
+ if (archive_mstring_get_utf8(
+ entry->archive, &entry->ae_pathname, &p) == 0)
+ return (p);
+ if (errno == ENOMEM)
+ __archive_errx(1, "No memory");
+ return (NULL);
+}
+
const wchar_t *
archive_entry_pathname_w(struct archive_entry *entry)
{
@@ -634,6 +675,20 @@ archive_entry_symlink(struct archive_entry *entry)
return (NULL);
}
+const char *
+archive_entry_symlink_utf8(struct archive_entry *entry)
+{
+ const char *p;
+ if ((entry->ae_set & AE_SET_SYMLINK) == 0)
+ return (NULL);
+ if (archive_mstring_get_utf8(
+ entry->archive, &entry->ae_symlink, &p) == 0)
+ return (p);
+ if (errno == ENOMEM)
+ __archive_errx(1, "No memory");
+ return (NULL);
+}
+
const wchar_t *
archive_entry_symlink_w(struct archive_entry *entry)
{
@@ -677,6 +732,17 @@ archive_entry_uname(struct archive_entry *entry)
return (NULL);
}
+const char *
+archive_entry_uname_utf8(struct archive_entry *entry)
+{
+ const char *p;
+ if (archive_mstring_get_utf8(entry->archive, &entry->ae_uname, &p) == 0)
+ return (p);
+ if (errno == ENOMEM)
+ __archive_errx(1, "No memory");
+ return (NULL);
+}
+
const wchar_t *
archive_entry_uname_w(struct archive_entry *entry)
{
@@ -695,6 +761,24 @@ _archive_entry_uname_l(struct archive_entry *entry,
return (archive_mstring_get_mbs_l(&entry->ae_uname, p, len, sc));
}
+int
+archive_entry_is_data_encrypted(struct archive_entry *entry)
+{
+ return ((entry->encryption & AE_ENCRYPTION_DATA) == AE_ENCRYPTION_DATA);
+}
+
+int
+archive_entry_is_metadata_encrypted(struct archive_entry *entry)
+{
+ return ((entry->encryption & AE_ENCRYPTION_METADATA) == AE_ENCRYPTION_METADATA);
+}
+
+int
+archive_entry_is_encrypted(struct archive_entry *entry)
+{
+ return (entry->encryption & (AE_ENCRYPTION_DATA|AE_ENCRYPTION_METADATA));
+}
+
/*
* Functions to set archive_entry properties.
*/
@@ -748,6 +832,12 @@ archive_entry_set_gname(struct archive_entry *entry, const char *name)
}
void
+archive_entry_set_gname_utf8(struct archive_entry *entry, const char *name)
+{
+ archive_mstring_copy_utf8(&entry->ae_gname, name);
+}
+
+void
archive_entry_copy_gname(struct archive_entry *entry, const char *name)
{
archive_mstring_copy_mbs(&entry->ae_gname, name);
@@ -804,6 +894,16 @@ archive_entry_set_hardlink(struct archive_entry *entry, const char *target)
}
void
+archive_entry_set_hardlink_utf8(struct archive_entry *entry, const char *target)
+{
+ archive_mstring_copy_utf8(&entry->ae_hardlink, target);
+ if (target != NULL)
+ entry->ae_set |= AE_SET_HARDLINK;
+ else
+ entry->ae_set &= ~AE_SET_HARDLINK;
+}
+
+void
archive_entry_copy_hardlink(struct archive_entry *entry, const char *target)
{
archive_mstring_copy_mbs(&entry->ae_hardlink, target);
@@ -941,6 +1041,15 @@ archive_entry_set_link(struct archive_entry *entry, const char *target)
archive_mstring_copy_mbs(&entry->ae_hardlink, target);
}
+void
+archive_entry_set_link_utf8(struct archive_entry *entry, const char *target)
+{
+ if (entry->ae_set & AE_SET_SYMLINK)
+ archive_mstring_copy_utf8(&entry->ae_symlink, target);
+ else
+ archive_mstring_copy_utf8(&entry->ae_hardlink, target);
+}
+
/* Set symlink if symlink is already set, else set hardlink. */
void
archive_entry_copy_link(struct archive_entry *entry, const char *target)
@@ -1031,6 +1140,12 @@ archive_entry_set_pathname(struct archive_entry *entry, const char *name)
}
void
+archive_entry_set_pathname_utf8(struct archive_entry *entry, const char *name)
+{
+ archive_mstring_copy_utf8(&entry->ae_pathname, name);
+}
+
+void
archive_entry_copy_pathname(struct archive_entry *entry, const char *name)
{
archive_mstring_copy_mbs(&entry->ae_pathname, name);
@@ -1131,6 +1246,16 @@ archive_entry_set_symlink(struct archive_entry *entry, const char *linkname)
}
void
+archive_entry_set_symlink_utf8(struct archive_entry *entry, const char *linkname)
+{
+ archive_mstring_copy_utf8(&entry->ae_symlink, linkname);
+ if (linkname != NULL)
+ entry->ae_set |= AE_SET_SYMLINK;
+ else
+ entry->ae_set &= ~AE_SET_SYMLINK;
+}
+
+void
archive_entry_copy_symlink(struct archive_entry *entry, const char *linkname)
{
archive_mstring_copy_mbs(&entry->ae_symlink, linkname);
@@ -1194,6 +1319,12 @@ archive_entry_set_uname(struct archive_entry *entry, const char *name)
}
void
+archive_entry_set_uname_utf8(struct archive_entry *entry, const char *name)
+{
+ archive_mstring_copy_utf8(&entry->ae_uname, name);
+}
+
+void
archive_entry_copy_uname(struct archive_entry *entry, const char *name)
{
archive_mstring_copy_mbs(&entry->ae_uname, name);
@@ -1216,6 +1347,26 @@ archive_entry_update_uname_utf8(struct archive_entry *entry, const char *name)
return (0);
}
+void
+archive_entry_set_is_data_encrypted(struct archive_entry *entry, char is_encrypted)
+{
+ if (is_encrypted) {
+ entry->encryption |= AE_ENCRYPTION_DATA;
+ } else {
+ entry->encryption &= ~AE_ENCRYPTION_DATA;
+ }
+}
+
+void
+archive_entry_set_is_metadata_encrypted(struct archive_entry *entry, char is_encrypted)
+{
+ if (is_encrypted) {
+ entry->encryption |= AE_ENCRYPTION_METADATA;
+ } else {
+ entry->encryption &= ~AE_ENCRYPTION_METADATA;
+ }
+}
+
int
_archive_entry_copy_uname_l(struct archive_entry *entry,
const char *name, size_t len, struct archive_string_conv *sc)
@@ -1588,19 +1739,23 @@ ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp)
while (*start == '\t' || *start == ' ' || *start == ',')
start++;
while (*start != '\0') {
+ size_t length;
/* Locate end of token. */
end = start;
while (*end != '\0' && *end != '\t' &&
*end != ' ' && *end != ',')
end++;
+ length = end - start;
for (flag = flags; flag->name != NULL; flag++) {
- if (memcmp(start, flag->name, end - start) == 0) {
+ size_t flag_length = strlen(flag->name);
+ if (length == flag_length
+ && memcmp(start, flag->name, length) == 0) {
/* Matched "noXXXX", so reverse the sense. */
clear |= flag->set;
set |= flag->clear;
break;
- } else if (memcmp(start, flag->name + 2, end - start)
- == 0) {
+ } else if (length == flag_length - 2
+ && memcmp(start, flag->name + 2, length) == 0) {
/* Matched "XXXX", so don't reverse. */
set |= flag->set;
clear |= flag->clear;
@@ -1652,19 +1807,23 @@ ae_wcstofflags(const wchar_t *s, unsigned long *setp, unsigned long *clrp)
while (*start == L'\t' || *start == L' ' || *start == L',')
start++;
while (*start != L'\0') {
+ size_t length;
/* Locate end of token. */
end = start;
while (*end != L'\0' && *end != L'\t' &&
*end != L' ' && *end != L',')
end++;
+ length = end - start;
for (flag = flags; flag->wname != NULL; flag++) {
- if (wmemcmp(start, flag->wname, end - start) == 0) {
+ size_t flag_length = wcslen(flag->wname);
+ if (length == flag_length
+ && wmemcmp(start, flag->wname, length) == 0) {
/* Matched "noXXXX", so reverse the sense. */
clear |= flag->set;
set |= flag->clear;
break;
- } else if (wmemcmp(start, flag->wname + 2, end - start)
- == 0) {
+ } else if (length == flag_length - 2
+ && wmemcmp(start, flag->wname + 2, length) == 0) {
/* Matched "XXXX", so don't reverse. */
set |= flag->set;
clear |= flag->clear;
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry.h b/Utilities/cmlibarchive/libarchive/archive_entry.h
index 85ea885f7..68d8ab984 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry.h
+++ b/Utilities/cmlibarchive/libarchive/archive_entry.h
@@ -48,14 +48,20 @@
#endif
/* Get a suitable 64-bit integer type. */
-#if defined(_WIN32) && !defined(__CYGWIN__)
-# define __LA_INT64_T __int64
-#else
-#include <unistd.h>
-# if defined(_SCO_DS) || defined(__osf__)
-# define __LA_INT64_T long long
+#if !defined(__LA_INT64_T_DEFINED)
+# if ARCHIVE_VERSION_NUMBER < 4000000
+#define __LA_INT64_T la_int64_t
+# endif
+#define __LA_INT64_T_DEFINED
+# if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__)
+typedef __int64 la_int64_t;
# else
-# define __LA_INT64_T int64_t
+#include <unistd.h>
+# if defined(_SCO_DS) || defined(__osf__)
+typedef long long la_int64_t;
+# else
+typedef int64_t la_int64_t;
+# endif
# endif
#endif
@@ -63,7 +69,7 @@
#if ARCHIVE_VERSION_NUMBER >= 3999000
/* Switch to plain 'int' for libarchive 4.0. It's less broken than 'mode_t' */
# define __LA_MODE_T int
-#elif defined(_WIN32) && !defined(__CYGWIN__) && !defined(__BORLANDC__)
+#elif defined(_WIN32) && !defined(__CYGWIN__) && !defined(__BORLANDC__) && !defined(__WATCOMC__)
# define __LA_MODE_T unsigned short
#else
# define __LA_MODE_T mode_t
@@ -206,13 +212,15 @@ __LA_DECL void archive_entry_fflags(struct archive_entry *,
unsigned long * /* set */,
unsigned long * /* clear */);
__LA_DECL const char *archive_entry_fflags_text(struct archive_entry *);
-__LA_DECL __LA_INT64_T archive_entry_gid(struct archive_entry *);
+__LA_DECL la_int64_t archive_entry_gid(struct archive_entry *);
__LA_DECL const char *archive_entry_gname(struct archive_entry *);
+__LA_DECL const char *archive_entry_gname_utf8(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_gname_w(struct archive_entry *);
__LA_DECL const char *archive_entry_hardlink(struct archive_entry *);
+__LA_DECL const char *archive_entry_hardlink_utf8(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_hardlink_w(struct archive_entry *);
-__LA_DECL __LA_INT64_T archive_entry_ino(struct archive_entry *);
-__LA_DECL __LA_INT64_T archive_entry_ino64(struct archive_entry *);
+__LA_DECL la_int64_t archive_entry_ino(struct archive_entry *);
+__LA_DECL la_int64_t archive_entry_ino64(struct archive_entry *);
__LA_DECL int archive_entry_ino_is_set(struct archive_entry *);
__LA_DECL __LA_MODE_T archive_entry_mode(struct archive_entry *);
__LA_DECL time_t archive_entry_mtime(struct archive_entry *);
@@ -220,6 +228,7 @@ __LA_DECL long archive_entry_mtime_nsec(struct archive_entry *);
__LA_DECL int archive_entry_mtime_is_set(struct archive_entry *);
__LA_DECL unsigned int archive_entry_nlink(struct archive_entry *);
__LA_DECL const char *archive_entry_pathname(struct archive_entry *);
+__LA_DECL const char *archive_entry_pathname_utf8(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_pathname_w(struct archive_entry *);
__LA_DECL __LA_MODE_T archive_entry_perm(struct archive_entry *);
__LA_DECL dev_t archive_entry_rdev(struct archive_entry *);
@@ -227,14 +236,19 @@ __LA_DECL dev_t archive_entry_rdevmajor(struct archive_entry *);
__LA_DECL dev_t archive_entry_rdevminor(struct archive_entry *);
__LA_DECL const char *archive_entry_sourcepath(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_sourcepath_w(struct archive_entry *);
-__LA_DECL __LA_INT64_T archive_entry_size(struct archive_entry *);
+__LA_DECL la_int64_t archive_entry_size(struct archive_entry *);
__LA_DECL int archive_entry_size_is_set(struct archive_entry *);
__LA_DECL const char *archive_entry_strmode(struct archive_entry *);
__LA_DECL const char *archive_entry_symlink(struct archive_entry *);
+__LA_DECL const char *archive_entry_symlink_utf8(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_symlink_w(struct archive_entry *);
-__LA_DECL __LA_INT64_T archive_entry_uid(struct archive_entry *);
+__LA_DECL la_int64_t archive_entry_uid(struct archive_entry *);
__LA_DECL const char *archive_entry_uname(struct archive_entry *);
+__LA_DECL const char *archive_entry_uname_utf8(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_uname_w(struct archive_entry *);
+__LA_DECL int archive_entry_is_data_encrypted(struct archive_entry *);
+__LA_DECL int archive_entry_is_metadata_encrypted(struct archive_entry *);
+__LA_DECL int archive_entry_is_encrypted(struct archive_entry *);
/*
* Set fields in an archive_entry.
@@ -248,7 +262,7 @@ __LA_DECL const wchar_t *archive_entry_uname_w(struct archive_entry *);
__LA_DECL void archive_entry_set_atime(struct archive_entry *, time_t, long);
__LA_DECL void archive_entry_unset_atime(struct archive_entry *);
#if defined(_WIN32) && !defined(__CYGWIN__)
-__LA_DECL void archive_entry_copy_bhfi(struct archive_entry *, BY_HANDLE_FILE_INFORMATION *);
+__LA_DECL void archive_entry_copy_bhfi(struct archive_entry *, struct _BY_HANDLE_FILE_INFORMATION *);
#endif
__LA_DECL void archive_entry_set_birthtime(struct archive_entry *, time_t, long);
__LA_DECL void archive_entry_unset_birthtime(struct archive_entry *);
@@ -266,18 +280,21 @@ __LA_DECL const char *archive_entry_copy_fflags_text(struct archive_entry *,
const char *);
__LA_DECL const wchar_t *archive_entry_copy_fflags_text_w(struct archive_entry *,
const wchar_t *);
-__LA_DECL void archive_entry_set_gid(struct archive_entry *, __LA_INT64_T);
+__LA_DECL void archive_entry_set_gid(struct archive_entry *, la_int64_t);
__LA_DECL void archive_entry_set_gname(struct archive_entry *, const char *);
+__LA_DECL void archive_entry_set_gname_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_gname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_gname_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_gname_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_hardlink(struct archive_entry *, const char *);
+__LA_DECL void archive_entry_set_hardlink_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_hardlink(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_hardlink_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_hardlink_utf8(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_set_ino(struct archive_entry *, __LA_INT64_T);
-__LA_DECL void archive_entry_set_ino64(struct archive_entry *, __LA_INT64_T);
+__LA_DECL void archive_entry_set_ino(struct archive_entry *, la_int64_t);
+__LA_DECL void archive_entry_set_ino64(struct archive_entry *, la_int64_t);
__LA_DECL void archive_entry_set_link(struct archive_entry *, const char *);
+__LA_DECL void archive_entry_set_link_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_link(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_link_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_link_utf8(struct archive_entry *, const char *);
@@ -286,6 +303,7 @@ __LA_DECL void archive_entry_set_mtime(struct archive_entry *, time_t, long);
__LA_DECL void archive_entry_unset_mtime(struct archive_entry *);
__LA_DECL void archive_entry_set_nlink(struct archive_entry *, unsigned int);
__LA_DECL void archive_entry_set_pathname(struct archive_entry *, const char *);
+__LA_DECL void archive_entry_set_pathname_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_pathname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_pathname_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_pathname_utf8(struct archive_entry *, const char *);
@@ -293,19 +311,23 @@ __LA_DECL void archive_entry_set_perm(struct archive_entry *, __LA_MODE_T);
__LA_DECL void archive_entry_set_rdev(struct archive_entry *, dev_t);
__LA_DECL void archive_entry_set_rdevmajor(struct archive_entry *, dev_t);
__LA_DECL void archive_entry_set_rdevminor(struct archive_entry *, dev_t);
-__LA_DECL void archive_entry_set_size(struct archive_entry *, __LA_INT64_T);
+__LA_DECL void archive_entry_set_size(struct archive_entry *, la_int64_t);
__LA_DECL void archive_entry_unset_size(struct archive_entry *);
__LA_DECL void archive_entry_copy_sourcepath(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_sourcepath_w(struct archive_entry *, const wchar_t *);
__LA_DECL void archive_entry_set_symlink(struct archive_entry *, const char *);
+__LA_DECL void archive_entry_set_symlink_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_symlink(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_symlink_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_symlink_utf8(struct archive_entry *, const char *);
-__LA_DECL void archive_entry_set_uid(struct archive_entry *, __LA_INT64_T);
+__LA_DECL void archive_entry_set_uid(struct archive_entry *, la_int64_t);
__LA_DECL void archive_entry_set_uname(struct archive_entry *, const char *);
+__LA_DECL void archive_entry_set_uname_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_uname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_uname_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_uname_utf8(struct archive_entry *, const char *);
+__LA_DECL void archive_entry_set_is_data_encrypted(struct archive_entry *, char is_encrypted);
+__LA_DECL void archive_entry_set_is_metadata_encrypted(struct archive_entry *, char is_encrypted);
/*
* Routines to bulk copy fields to/from a platform-native "struct
* stat." Libarchive used to just store a struct stat inside of each
@@ -514,7 +536,7 @@ __LA_DECL int archive_entry_xattr_next(struct archive_entry *,
__LA_DECL void archive_entry_sparse_clear(struct archive_entry *);
__LA_DECL void archive_entry_sparse_add_entry(struct archive_entry *,
- __LA_INT64_T /* offset */, __LA_INT64_T /* length */);
+ la_int64_t /* offset */, la_int64_t /* length */);
/*
* To retrieve the xattr list, first "reset", then repeatedly ask for the
@@ -524,7 +546,7 @@ __LA_DECL void archive_entry_sparse_add_entry(struct archive_entry *,
__LA_DECL int archive_entry_sparse_count(struct archive_entry *);
__LA_DECL int archive_entry_sparse_reset(struct archive_entry *);
__LA_DECL int archive_entry_sparse_next(struct archive_entry *,
- __LA_INT64_T * /* offset */, __LA_INT64_T * /* length */);
+ la_int64_t * /* offset */, la_int64_t * /* length */);
/*
* Utility to match up hardlinks.
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_acl.3 b/Utilities/cmlibarchive/libarchive/archive_entry_acl.3
index f5c337733..5aff99682 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_acl.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_acl.3
@@ -226,8 +226,8 @@ The returned long string is valid until the next call to
or
.Fn archive_entry_acl_text_w .
.Sh SEE ALSO
-.Xr archive 3 ,
.Xr archive_entry 3
+.Xr libarchive 3 ,
.Sh BUGS
.Dv ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID
and
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_paths.3 b/Utilities/cmlibarchive/libarchive/archive_entry_paths.3
index 51c8b8c8e..fd22cf7e2 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_paths.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_paths.3
@@ -149,5 +149,5 @@ It doesn't have a corresponding get accessor function.
is an alias for
.Fn archive_entry_copy_XXX .
.Sh SEE ALSO
-.Xr archive 3 ,
.Xr archive_entry 3
+.Xr libarchive 3 ,
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_perms.3 b/Utilities/cmlibarchive/libarchive/archive_entry_perms.3
index 5b7b5d955..340c5ea72 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_perms.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_perms.3
@@ -194,11 +194,11 @@ every name that is recognized.
.Xr strtofflags 3 ,
which stops parsing at the first unrecognized name.)
.Sh SEE ALSO
-.Xr archive 3 ,
.Xr archive_entry 3 ,
.Xr archive_entry_acl 3 ,
.Xr archive_read_disk 3 ,
.Xr archive_write_disk 3
+.Xr libarchive 3 ,
.Sh BUGS
The platform types
.Vt uid_t
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_private.h b/Utilities/cmlibarchive/libarchive/archive_entry_private.h
index e3547c3e3..c69233e68 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_private.h
@@ -154,6 +154,11 @@ struct archive_entry {
/* Not used within libarchive; useful for some clients. */
struct archive_mstring ae_sourcepath; /* Path this entry is sourced from. */
+#define AE_ENCRYPTION_NONE 0
+#define AE_ENCRYPTION_DATA 1
+#define AE_ENCRYPTION_METADATA 2
+ char encryption;
+
void *mac_metadata;
size_t mac_metadata_size;
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_sparse.c b/Utilities/cmlibarchive/libarchive/archive_entry_sparse.c
index 10c54474a..fed74f512 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_sparse.c
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_sparse.c
@@ -58,7 +58,7 @@ archive_entry_sparse_add_entry(struct archive_entry *entry,
if (offset < 0 || length < 0)
/* Invalid value */
return;
- if (offset + length < 0 ||
+ if (offset > INT64_MAX - length ||
offset + length > archive_entry_size(entry))
/* A value of "length" parameter is too large. */
return;
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_stat.3 b/Utilities/cmlibarchive/libarchive/archive_entry_stat.3
index 84a4ea12a..26611e4c6 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_stat.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_stat.3
@@ -226,7 +226,7 @@ and
are used by
.Xr archive_entry_linkify 3
to find hardlinks.
-The pair of device and inode is suppossed to identify hardlinked files.
+The pair of device and inode is supposed to identify hardlinked files.
.Pp
The device major and minor number can be obtained independently using
.Fn archive_entry_devmajor
@@ -267,8 +267,8 @@ platforms.
Some archive formats use the combined form, while other formats use
the split form.
.Sh SEE ALSO
-.Xr archive 3 ,
.Xr archive_entry_acl 3 ,
.Xr archive_entry_perms 3 ,
.Xr archive_entry_time 3 ,
+.Xr libarchive 3 ,
.Xr stat 2
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_time.3 b/Utilities/cmlibarchive/libarchive/archive_entry_time.3
index 17c658a65..186452159 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_time.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_time.3
@@ -113,8 +113,8 @@ The current state can be queried using
.Fn XXX_is_set .
Unset time fields have a second and nanosecond field of 0.
.Sh SEE ALSO
-.Xr archive 3 ,
.Xr archive_entry 3
+.Xr libarchive 3 ,
.Sh HISTORY
The
.Nm libarchive
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_xattr.c b/Utilities/cmlibarchive/libarchive/archive_entry_xattr.c
index a3efe7ca8..05eb90f1a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_xattr.c
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_xattr.c
@@ -98,7 +98,10 @@ archive_entry_xattr_add_entry(struct archive_entry *entry,
/* XXX Error XXX */
return;
- xp->name = strdup(name);
+ if ((xp->name = strdup(name)) == NULL)
+ /* XXX Error XXX */
+ return;
+
if ((xp->value = malloc(size)) != NULL) {
memcpy(xp->value, value, size);
xp->size = size;
diff --git a/Utilities/cmlibarchive/libarchive/archive_getdate.c b/Utilities/cmlibarchive/libarchive/archive_getdate.c
index f8b5a28d5..f665e2db7 100644
--- a/Utilities/cmlibarchive/libarchive/archive_getdate.c
+++ b/Utilities/cmlibarchive/libarchive/archive_getdate.c
@@ -39,7 +39,7 @@ __FBSDID("$FreeBSD$");
#include <time.h>
/* This file defines a single public function. */
-time_t __archive_get_date(time_t now, char *);
+time_t __archive_get_date(time_t now, const char *);
/* Basic time units. */
#define EPOCH 1970
@@ -369,8 +369,8 @@ relunitphrase(struct gdstate *gds)
&& gds->tokenp[1].token == tSEC_UNIT) {
/* "1 day" */
gds->HaveRel++;
- gds->RelSeconds += gds->tokenp[1].value * gds->tokenp[2].value;
- gds->tokenp += 3;
+ gds->RelSeconds += gds->tokenp[0].value * gds->tokenp[1].value;
+ gds->tokenp += 2;
return 1;
}
if (gds->tokenp[0].token == '-'
@@ -403,7 +403,7 @@ relunitphrase(struct gdstate *gds)
/* "now", "tomorrow" */
gds->HaveRel++;
gds->RelSeconds += gds->tokenp[0].value;
- ++gds->tokenp;
+ gds->tokenp += 1;
return 1;
}
if (gds->tokenp[0].token == tMONTH_UNIT) {
@@ -782,7 +782,7 @@ RelativeMonth(time_t Start, time_t Timezone, time_t RelMonth)
* Tokenizer.
*/
static int
-nexttoken(char **in, time_t *value)
+nexttoken(const char **in, time_t *value)
{
char c;
char buff[64];
@@ -809,7 +809,7 @@ nexttoken(char **in, time_t *value)
/* Try the next token in the word table first. */
/* This allows us to match "2nd", for example. */
{
- char *src = *in;
+ const char *src = *in;
const struct LEXICON *tp;
unsigned i = 0;
@@ -894,7 +894,7 @@ difftm (struct tm *a, struct tm *b)
* TODO: tokens[] array should be dynamically sized.
*/
time_t
-__archive_get_date(time_t now, char *p)
+__archive_get_date(time_t now, const char *p)
{
struct token tokens[256];
struct gdstate _gds;
@@ -1022,10 +1022,11 @@ int
main(int argc, char **argv)
{
time_t d;
+ time_t now = time(NULL);
while (*++argv != NULL) {
(void)printf("Input: %s\n", *argv);
- d = get_date(*argv);
+ d = get_date(now, *argv);
if (d == -1)
(void)printf("Bad format - couldn't convert.\n");
else
diff --git a/Utilities/cmlibarchive/libarchive/archive_hmac.c b/Utilities/cmlibarchive/libarchive/archive_hmac.c
new file mode 100644
index 000000000..36e3e1c6f
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_hmac.c
@@ -0,0 +1,234 @@
+/*-
+* Copyright (c) 2014 Michihiro NAKAJIMA
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "archive_platform.h"
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include "archive.h"
+#include "archive_hmac_private.h"
+
+#ifdef ARCHIVE_HMAC_USE_Apple_CommonCrypto
+
+static int
+__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
+{
+ CCHmacInit(ctx, kCCHmacAlgSHA1, key, key_len);
+ return 0;
+}
+
+static void
+__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
+ size_t data_len)
+{
+ CCHmacUpdate(ctx, data, data_len);
+}
+
+static void
+__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
+{
+ CCHmacFinal(ctx, out);
+ *out_len = 20;
+}
+
+static void
+__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
+{
+ memset(ctx, 0, sizeof(*ctx));
+}
+
+#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
+
+static int
+__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
+{
+ BCRYPT_ALG_HANDLE hAlg;
+ BCRYPT_HASH_HANDLE hHash;
+ DWORD hash_len;
+ PBYTE hash;
+ ULONG result;
+ NTSTATUS status;
+
+ ctx->hAlg = NULL;
+ status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA1_ALGORITHM,
+ MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
+ if (!BCRYPT_SUCCESS(status))
+ return -1;
+ status = BCryptGetProperty(hAlg, BCRYPT_HASH_LENGTH, (PUCHAR)&hash_len,
+ sizeof(hash_len), &result, 0);
+ if (!BCRYPT_SUCCESS(status)) {
+ BCryptCloseAlgorithmProvider(hAlg, 0);
+ return -1;
+ }
+ hash = (PBYTE)HeapAlloc(GetProcessHeap(), 0, hash_len);
+ if (hash == NULL) {
+ BCryptCloseAlgorithmProvider(hAlg, 0);
+ return -1;
+ }
+ status = BCryptCreateHash(hAlg, &hHash, NULL, 0,
+ (PUCHAR)key, (ULONG)key_len, BCRYPT_HASH_REUSABLE_FLAG);
+ if (!BCRYPT_SUCCESS(status)) {
+ BCryptCloseAlgorithmProvider(hAlg, 0);
+ HeapFree(GetProcessHeap(), 0, hash);
+ return -1;
+ }
+
+ ctx->hAlg = hAlg;
+ ctx->hHash = hHash;
+ ctx->hash_len = hash_len;
+ ctx->hash = hash;
+
+ return 0;
+}
+
+static void
+__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
+ size_t data_len)
+{
+ BCryptHashData(ctx->hHash, (PUCHAR)(uintptr_t)data, (ULONG)data_len, 0);
+}
+
+static void
+__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
+{
+ BCryptFinishHash(ctx->hHash, ctx->hash, ctx->hash_len, 0);
+ if (ctx->hash_len == *out_len)
+ memcpy(out, ctx->hash, *out_len);
+}
+
+static void
+__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
+{
+ if (ctx->hAlg != NULL) {
+ BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
+ HeapFree(GetProcessHeap(), 0, ctx->hash);
+ ctx->hAlg = NULL;
+ }
+}
+
+#elif defined(HAVE_LIBNETTLE)
+
+static int
+__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
+{
+ hmac_sha1_set_key(ctx, key_len, key);
+ return 0;
+}
+
+static void
+__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
+ size_t data_len)
+{
+ hmac_sha1_update(ctx, data_len, data);
+}
+
+static void
+__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
+{
+ hmac_sha1_digest(ctx, (unsigned)*out_len, out);
+}
+
+static void
+__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
+{
+ memset(ctx, 0, sizeof(*ctx));
+}
+
+#elif defined(HAVE_LIBCRYPTO)
+
+static int
+__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
+{
+ HMAC_CTX_init(ctx);
+ HMAC_Init(ctx, key, key_len, EVP_sha1());
+ return 0;
+}
+
+static void
+__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
+ size_t data_len)
+{
+ HMAC_Update(ctx, data, data_len);
+}
+
+static void
+__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
+{
+ unsigned int len = (unsigned int)*out_len;
+ HMAC_Final(ctx, out, &len);
+ *out_len = len;
+}
+
+static void
+__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
+{
+ HMAC_CTX_cleanup(ctx);
+ memset(ctx, 0, sizeof(*ctx));
+}
+
+#else
+
+/* Stub */
+static int
+__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
+{
+ (void)ctx;/* UNUSED */
+ (void)key;/* UNUSED */
+ (void)key_len;/* UNUSED */
+ return -1;
+}
+
+static void
+__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
+ size_t data_len)
+{
+ (void)ctx;/* UNUSED */
+ (void)data;/* UNUSED */
+ (void)data_len;/* UNUSED */
+}
+
+static void
+__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
+{
+ (void)ctx;/* UNUSED */
+ (void)out;/* UNUSED */
+ (void)out_len;/* UNUSED */
+}
+
+static void
+__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
+{
+ (void)ctx;/* UNUSED */
+}
+
+#endif
+
+const struct archive_hmac __archive_hmac = {
+ &__hmac_sha1_init,
+ &__hmac_sha1_update,
+ &__hmac_sha1_final,
+ &__hmac_sha1_cleanup,
+};
diff --git a/Utilities/cmlibarchive/libarchive/archive_hmac_private.h b/Utilities/cmlibarchive/libarchive/archive_hmac_private.h
new file mode 100644
index 000000000..a9fb8eca5
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_hmac_private.h
@@ -0,0 +1,95 @@
+/*-
+* Copyright (c) 2014 Michihiro NAKAJIMA
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#ifndef ARCHIVE_HMAC_PRIVATE_H_INCLUDED
+#define ARCHIVE_HMAC_PRIVATE_H_INCLUDED
+
+#ifdef __APPLE__
+# include <AvailabilityMacros.h>
+# if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
+# define ARCHIVE_HMAC_USE_Apple_CommonCrypto
+# endif
+#endif
+
+#ifdef ARCHIVE_HMAC_USE_Apple_CommonCrypto
+#include <CommonCrypto/CommonHMAC.h>
+
+typedef CCHmacContext archive_hmac_sha1_ctx;
+
+#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
+#include <bcrypt.h>
+
+typedef struct {
+ BCRYPT_ALG_HANDLE hAlg;
+ BCRYPT_HASH_HANDLE hHash;
+ DWORD hash_len;
+ PBYTE hash;
+
+} archive_hmac_sha1_ctx;
+
+#elif defined(HAVE_LIBNETTLE)
+#include <nettle/hmac.h>
+
+typedef struct hmac_sha1_ctx archive_hmac_sha1_ctx;
+
+#elif defined(HAVE_LIBCRYPTO)
+#include <openssl/hmac.h>
+
+typedef HMAC_CTX archive_hmac_sha1_ctx;
+
+#else
+
+typedef int archive_hmac_sha1_ctx;
+
+#endif
+
+
+/* HMAC */
+#define archive_hmac_sha1_init(ctx, key, key_len)\
+ __archive_hmac.__hmac_sha1_init(ctx, key, key_len)
+#define archive_hmac_sha1_update(ctx, data, data_len)\
+ __archive_hmac.__hmac_sha1_update(ctx, data, data_len)
+#define archive_hmac_sha1_final(ctx, out, out_len)\
+ __archive_hmac.__hmac_sha1_final(ctx, out, out_len)
+#define archive_hmac_sha1_cleanup(ctx)\
+ __archive_hmac.__hmac_sha1_cleanup(ctx)
+
+
+struct archive_hmac {
+ /* HMAC */
+ int (*__hmac_sha1_init)(archive_hmac_sha1_ctx *, const uint8_t *,
+ size_t);
+ void (*__hmac_sha1_update)(archive_hmac_sha1_ctx *, const uint8_t *,
+ size_t);
+ void (*__hmac_sha1_final)(archive_hmac_sha1_ctx *, uint8_t *, size_t *);
+ void (*__hmac_sha1_cleanup)(archive_hmac_sha1_ctx *);
+};
+
+extern const struct archive_hmac __archive_hmac;
+#endif /* ARCHIVE_HMAC_PRIVATE_H_INCLUDED */
diff --git a/Utilities/cmlibarchive/libarchive/archive_match.c b/Utilities/cmlibarchive/libarchive/archive_match.c
index 6b6be9cb2..74aaacb5a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_match.c
+++ b/Utilities/cmlibarchive/libarchive/archive_match.c
@@ -580,6 +580,7 @@ add_pattern_from_file(struct archive_match *a, struct match_list *mlist,
return (ARCHIVE_FATAL);
}
r = archive_read_support_format_raw(ar);
+ r = archive_read_support_format_empty(ar);
if (r != ARCHIVE_OK) {
archive_copy_error(&(a->archive), ar);
archive_read_free(ar);
@@ -596,9 +597,13 @@ add_pattern_from_file(struct archive_match *a, struct match_list *mlist,
}
r = archive_read_next_header(ar, &ae);
if (r != ARCHIVE_OK) {
- archive_copy_error(&(a->archive), ar);
archive_read_free(ar);
- return (r);
+ if (r == ARCHIVE_EOF) {
+ return (ARCHIVE_OK);
+ } else {
+ archive_copy_error(&(a->archive), ar);
+ return (r);
+ }
}
archive_string_init(&as);
@@ -1152,7 +1157,7 @@ set_timefilter_pathname_mbs(struct archive_match *a, int timetype,
{
/* NOTE: stat() on Windows cannot handle nano seconds. */
HANDLE h;
- WIN32_FIND_DATA d;
+ WIN32_FIND_DATAA d;
if (path == NULL || *path == '\0') {
archive_set_error(&(a->archive), EINVAL, "pathname is empty");
diff --git a/Utilities/cmlibarchive/libarchive/archive_pack_dev.c b/Utilities/cmlibarchive/libarchive/archive_pack_dev.c
new file mode 100644
index 000000000..6b7b4726d
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_pack_dev.c
@@ -0,0 +1,329 @@
+/* $NetBSD: pack_dev.c,v 1.12 2013/06/14 16:28:20 tsutsui Exp $ */
+
+/*-
+ * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles M. Hannum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Originally from NetBSD's mknod(8) source. */
+
+#include "archive_platform.h"
+
+#if HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#if !defined(lint)
+__RCSID("$NetBSD$");
+#endif /* not lint */
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "archive_pack_dev.h"
+
+static pack_t pack_netbsd;
+static pack_t pack_freebsd;
+static pack_t pack_8_8;
+static pack_t pack_12_20;
+static pack_t pack_14_18;
+static pack_t pack_8_24;
+static pack_t pack_bsdos;
+static int compare_format(const void *, const void *);
+
+static const char iMajorError[] = "invalid major number";
+static const char iMinorError[] = "invalid minor number";
+static const char tooManyFields[] = "too many fields for format";
+
+/* This is blatantly stolen from libarchive/archive_entry.c,
+ * in an attempt to get this to play nice on MinGW... */
+#if !defined(HAVE_MAJOR) && !defined(major)
+/* Replacement for major/minor/makedev. */
+#define major(x) ((int)(0x00ff & ((x) >> 8)))
+#define minor(x) ((int)(0xffff00ff & (x)))
+#define makedev(maj,min) ((0xff00 & ((maj)<<8)) | (0xffff00ff & (min)))
+#endif
+
+/* Play games to come up with a suitable makedev() definition. */
+#ifdef __QNXNTO__
+/* QNX. <sigh> */
+#include <sys/netmgr.h>
+#define apd_makedev(maj, min) makedev(ND_LOCAL_NODE, (maj), (min))
+#elif defined makedev
+/* There's a "makedev" macro. */
+#define apd_makedev(maj, min) makedev((maj), (min))
+#elif defined mkdev || ((defined _WIN32 || defined __WIN32__) && !defined(__CYGWIN__))
+/* Windows. <sigh> */
+#define apd_makedev(maj, min) mkdev((maj), (min))
+#else
+/* There's a "makedev" function. */
+#define apd_makedev(maj, min) makedev((maj), (min))
+#endif
+
+/* exported */
+dev_t
+pack_native(int n, unsigned long numbers[], const char **error)
+{
+ dev_t dev = 0;
+
+ if (n == 2) {
+ dev = apd_makedev(numbers[0], numbers[1]);
+ if ((unsigned long)major(dev) != numbers[0])
+ *error = iMajorError;
+ else if ((unsigned long)minor(dev) != numbers[1])
+ *error = iMinorError;
+ } else
+ *error = tooManyFields;
+ return (dev);
+}
+
+
+static dev_t
+pack_netbsd(int n, unsigned long numbers[], const char **error)
+{
+ dev_t dev = 0;
+
+ if (n == 2) {
+ dev = makedev_netbsd(numbers[0], numbers[1]);
+ if ((unsigned long)major_netbsd(dev) != numbers[0])
+ *error = iMajorError;
+ else if ((unsigned long)minor_netbsd(dev) != numbers[1])
+ *error = iMinorError;
+ } else
+ *error = tooManyFields;
+ return (dev);
+}
+
+
+#define major_freebsd(x) ((int32_t)(((x) & 0x0000ff00) >> 8))
+#define minor_freebsd(x) ((int32_t)(((x) & 0xffff00ff) >> 0))
+#define makedev_freebsd(x,y) ((dev_t)((((x) << 8) & 0x0000ff00) | \
+ (((y) << 0) & 0xffff00ff)))
+
+static dev_t
+pack_freebsd(int n, unsigned long numbers[], const char **error)
+{
+ dev_t dev = 0;
+
+ if (n == 2) {
+ dev = makedev_freebsd(numbers[0], numbers[1]);
+ if ((unsigned long)major_freebsd(dev) != numbers[0])
+ *error = iMajorError;
+ if ((unsigned long)minor_freebsd(dev) != numbers[1])
+ *error = iMinorError;
+ } else
+ *error = tooManyFields;
+ return (dev);
+}
+
+
+#define major_8_8(x) ((int32_t)(((x) & 0x0000ff00) >> 8))
+#define minor_8_8(x) ((int32_t)(((x) & 0x000000ff) >> 0))
+#define makedev_8_8(x,y) ((dev_t)((((x) << 8) & 0x0000ff00) | \
+ (((y) << 0) & 0x000000ff)))
+
+static dev_t
+pack_8_8(int n, unsigned long numbers[], const char **error)
+{
+ dev_t dev = 0;
+
+ if (n == 2) {
+ dev = makedev_8_8(numbers[0], numbers[1]);
+ if ((unsigned long)major_8_8(dev) != numbers[0])
+ *error = iMajorError;
+ if ((unsigned long)minor_8_8(dev) != numbers[1])
+ *error = iMinorError;
+ } else
+ *error = tooManyFields;
+ return (dev);
+}
+
+
+#define major_12_20(x) ((int32_t)(((x) & 0xfff00000) >> 20))
+#define minor_12_20(x) ((int32_t)(((x) & 0x000fffff) >> 0))
+#define makedev_12_20(x,y) ((dev_t)((((x) << 20) & 0xfff00000) | \
+ (((y) << 0) & 0x000fffff)))
+
+static dev_t
+pack_12_20(int n, unsigned long numbers[], const char **error)
+{
+ dev_t dev = 0;
+
+ if (n == 2) {
+ dev = makedev_12_20(numbers[0], numbers[1]);
+ if ((unsigned long)major_12_20(dev) != numbers[0])
+ *error = iMajorError;
+ if ((unsigned long)minor_12_20(dev) != numbers[1])
+ *error = iMinorError;
+ } else
+ *error = tooManyFields;
+ return (dev);
+}
+
+
+#define major_14_18(x) ((int32_t)(((x) & 0xfffc0000) >> 18))
+#define minor_14_18(x) ((int32_t)(((x) & 0x0003ffff) >> 0))
+#define makedev_14_18(x,y) ((dev_t)((((x) << 18) & 0xfffc0000) | \
+ (((y) << 0) & 0x0003ffff)))
+
+static dev_t
+pack_14_18(int n, unsigned long numbers[], const char **error)
+{
+ dev_t dev = 0;
+
+ if (n == 2) {
+ dev = makedev_14_18(numbers[0], numbers[1]);
+ if ((unsigned long)major_14_18(dev) != numbers[0])
+ *error = iMajorError;
+ if ((unsigned long)minor_14_18(dev) != numbers[1])
+ *error = iMinorError;
+ } else
+ *error = tooManyFields;
+ return (dev);
+}
+
+
+#define major_8_24(x) ((int32_t)(((x) & 0xff000000) >> 24))
+#define minor_8_24(x) ((int32_t)(((x) & 0x00ffffff) >> 0))
+#define makedev_8_24(x,y) ((dev_t)((((x) << 24) & 0xff000000) | \
+ (((y) << 0) & 0x00ffffff)))
+
+static dev_t
+pack_8_24(int n, unsigned long numbers[], const char **error)
+{
+ dev_t dev = 0;
+
+ if (n == 2) {
+ dev = makedev_8_24(numbers[0], numbers[1]);
+ if ((unsigned long)major_8_24(dev) != numbers[0])
+ *error = iMajorError;
+ if ((unsigned long)minor_8_24(dev) != numbers[1])
+ *error = iMinorError;
+ } else
+ *error = tooManyFields;
+ return (dev);
+}
+
+
+#define major_12_12_8(x) ((int32_t)(((x) & 0xfff00000) >> 20))
+#define unit_12_12_8(x) ((int32_t)(((x) & 0x000fff00) >> 8))
+#define subunit_12_12_8(x) ((int32_t)(((x) & 0x000000ff) >> 0))
+#define makedev_12_12_8(x,y,z) ((dev_t)((((x) << 20) & 0xfff00000) | \
+ (((y) << 8) & 0x000fff00) | \
+ (((z) << 0) & 0x000000ff)))
+
+static dev_t
+pack_bsdos(int n, unsigned long numbers[], const char **error)
+{
+ dev_t dev = 0;
+
+ if (n == 2) {
+ dev = makedev_12_20(numbers[0], numbers[1]);
+ if ((unsigned long)major_12_20(dev) != numbers[0])
+ *error = iMajorError;
+ if ((unsigned long)minor_12_20(dev) != numbers[1])
+ *error = iMinorError;
+ } else if (n == 3) {
+ dev = makedev_12_12_8(numbers[0], numbers[1], numbers[2]);
+ if ((unsigned long)major_12_12_8(dev) != numbers[0])
+ *error = iMajorError;
+ if ((unsigned long)unit_12_12_8(dev) != numbers[1])
+ *error = "invalid unit number";
+ if ((unsigned long)subunit_12_12_8(dev) != numbers[2])
+ *error = "invalid subunit number";
+ } else
+ *error = tooManyFields;
+ return (dev);
+}
+
+
+ /* list of formats and pack functions */
+ /* this list must be sorted lexically */
+static struct format {
+ const char *name;
+ pack_t *pack;
+} formats[] = {
+ {"386bsd", pack_8_8},
+ {"4bsd", pack_8_8},
+ {"bsdos", pack_bsdos},
+ {"freebsd", pack_freebsd},
+ {"hpux", pack_8_24},
+ {"isc", pack_8_8},
+ {"linux", pack_8_8},
+ {"native", pack_native},
+ {"netbsd", pack_netbsd},
+ {"osf1", pack_12_20},
+ {"sco", pack_8_8},
+ {"solaris", pack_14_18},
+ {"sunos", pack_8_8},
+ {"svr3", pack_8_8},
+ {"svr4", pack_14_18},
+ {"ultrix", pack_8_8},
+};
+
+static int
+compare_format(const void *key, const void *element)
+{
+ const char *name;
+ const struct format *format;
+
+ name = key;
+ format = element;
+
+ return (strcmp(name, format->name));
+}
+
+
+pack_t *
+pack_find(const char *name)
+{
+ struct format *format;
+
+ format = bsearch(name, formats,
+ sizeof(formats)/sizeof(formats[0]),
+ sizeof(formats[0]), compare_format);
+ if (format == 0)
+ return (NULL);
+ return (format->pack);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_pack_dev.h b/Utilities/cmlibarchive/libarchive/archive_pack_dev.h
new file mode 100644
index 000000000..749fd3d2c
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_pack_dev.h
@@ -0,0 +1,49 @@
+/* $NetBSD: pack_dev.h,v 1.8 2013/06/14 16:28:20 tsutsui Exp $ */
+
+/*-
+ * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles M. Hannum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Originally from NetBSD's mknod(8) source. */
+
+#ifndef _PACK_DEV_H
+#define _PACK_DEV_H
+
+typedef dev_t pack_t(int, unsigned long [], const char **);
+
+pack_t *pack_find(const char *);
+pack_t pack_native;
+
+#define major_netbsd(x) ((int32_t)((((x) & 0x000fff00) >> 8)))
+#define minor_netbsd(x) ((int32_t)((((x) & 0xfff00000) >> 12) | \
+ (((x) & 0x000000ff) >> 0)))
+#define makedev_netbsd(x,y) ((dev_t)((((x) << 8) & 0x000fff00) | \
+ (((y) << 12) & 0xfff00000) | \
+ (((y) << 0) & 0x000000ff)))
+
+#endif /* _PACK_DEV_H */
diff --git a/Utilities/cmlibarchive/libarchive/archive_pathmatch.c b/Utilities/cmlibarchive/libarchive/archive_pathmatch.c
index 505252a18..619e2b622 100644
--- a/Utilities/cmlibarchive/libarchive/archive_pathmatch.c
+++ b/Utilities/cmlibarchive/libarchive/archive_pathmatch.c
@@ -394,8 +394,8 @@ __archive_pathmatch(const char *p, const char *s, int flags)
if (*p == '/' && *s != '/')
return (0);
- /* Certain patterns and file names anchor implicitly. */
- if (*p == '*' || *p == '/' || *p == '/') {
+ /* Certain patterns anchor implicitly. */
+ if (*p == '*' || *p == '/') {
while (*p == '/')
++p;
while (*s == '/')
@@ -434,8 +434,8 @@ __archive_pathmatch_w(const wchar_t *p, const wchar_t *s, int flags)
if (*p == L'/' && *s != L'/')
return (0);
- /* Certain patterns and file names anchor implicitly. */
- if (*p == L'*' || *p == L'/' || *p == L'/') {
+ /* Certain patterns anchor implicitly. */
+ if (*p == L'*' || *p == L'/') {
while (*p == L'/')
++p;
while (*s == L'/')
diff --git a/Utilities/cmlibarchive/libarchive/archive_platform.h b/Utilities/cmlibarchive/libarchive/archive_platform.h
index cdd9c7c86..cbe08ec9b 100644
--- a/Utilities/cmlibarchive/libarchive/archive_platform.h
+++ b/Utilities/cmlibarchive/libarchive/archive_platform.h
@@ -66,15 +66,18 @@
* headers as required.
*/
-/* Get a real definition for __FBSDID if we can */
+/* Get a real definition for __FBSDID or __RCSID if we can */
#if HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
-/* If not, define it so as to avoid dangling semicolons. */
+/* If not, define them so as to avoid dangling semicolons. */
#ifndef __FBSDID
#define __FBSDID(a) struct _undefined_hack
#endif
+#ifndef __RCSID
+#define __RCSID(a) struct _undefined_hack
+#endif
/* Old glibc mbsnrtowcs fails assertions in our use case. */
#if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ <= 1
diff --git a/Utilities/cmlibarchive/libarchive/archive_private.h b/Utilities/cmlibarchive/libarchive/archive_private.h
index 30d472fcd..4b4be9796 100644
--- a/Utilities/cmlibarchive/libarchive/archive_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_private.h
@@ -119,6 +119,23 @@ struct archive {
unsigned current_codepage; /* Current ACP(ANSI CodePage). */
unsigned current_oemcp; /* Current OEMCP(OEM CodePage). */
struct archive_string_conv *sconv;
+
+ /*
+ * Used by archive_read_data() to track blocks and copy
+ * data to client buffers, filling gaps with zero bytes.
+ */
+ const char *read_data_block;
+ int64_t read_data_offset;
+ int64_t read_data_output_offset;
+ size_t read_data_remaining;
+
+ /*
+ * Used by formats/filters to determine the amount of data
+ * requested from a call to archive_read_data(). This is only
+ * useful when the format/filter has seek support.
+ */
+ char read_data_is_posix_read;
+ size_t read_data_requested;
};
/* Check magic value and state; return(ARCHIVE_FATAL) if it isn't valid. */
@@ -139,6 +156,8 @@ int __archive_mktemp(const char *tmpdir);
int __archive_clean(struct archive *);
+void __archive_reset_read_data(struct archive *);
+
#define err_combine(a,b) ((a) < (b) ? (a) : (b))
#if defined(__BORLANDC__) || (defined(_MSC_VER) && _MSC_VER <= 1300)
diff --git a/Utilities/cmlibarchive/libarchive/archive_random.c b/Utilities/cmlibarchive/libarchive/archive_random.c
new file mode 100644
index 000000000..a20b9b111
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_random.c
@@ -0,0 +1,269 @@
+/*-
+ * Copyright (c) 2014 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#if !defined(HAVE_ARC4RANDOM_BUF) && (!defined(_WIN32) || defined(__CYGWIN__))
+
+#ifdef HAVE_FCNTL
+#include <fcntl.h>
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+
+static void arc4random_buf(void *, size_t);
+
+#endif /* HAVE_ARC4RANDOM_BUF */
+
+#include "archive.h"
+#include "archive_random_private.h"
+
+#if defined(HAVE_WINCRYPT_H) && !defined(__CYGWIN__)
+#include <wincrypt.h>
+#endif
+
+#ifndef O_CLOEXEC
+#define O_CLOEXEC 0
+#endif
+
+/*
+ * Random number generator function.
+ * This simply calls arc4random_buf function if the platform provides it.
+ */
+
+int
+archive_random(void *buf, size_t nbytes)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ HCRYPTPROV hProv;
+ BOOL success;
+
+ success = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT);
+ if (!success && GetLastError() == NTE_BAD_KEYSET) {
+ success = CryptAcquireContext(&hProv, NULL, NULL,
+ PROV_RSA_FULL, CRYPT_NEWKEYSET);
+ }
+ if (success) {
+ success = CryptGenRandom(hProv, (DWORD)nbytes, (BYTE*)buf);
+ CryptReleaseContext(hProv, 0);
+ if (success)
+ return ARCHIVE_OK;
+ }
+ /* TODO: Does this case really happen? */
+ return ARCHIVE_FAILED;
+#else
+ arc4random_buf(buf, nbytes);
+ return ARCHIVE_OK;
+#endif
+}
+
+#if !defined(HAVE_ARC4RANDOM_BUF) && (!defined(_WIN32) || defined(__CYGWIN__))
+
+/* $OpenBSD: arc4random.c,v 1.24 2013/06/11 16:59:50 deraadt Exp $ */
+/*
+ * Copyright (c) 1996, David Mazieres <dm@uun.org>
+ * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Arc4 random number generator for OpenBSD.
+ *
+ * This code is derived from section 17.1 of Applied Cryptography,
+ * second edition, which describes a stream cipher allegedly
+ * compatible with RSA Labs "RC4" cipher (the actual description of
+ * which is a trade secret). The same algorithm is used as a stream
+ * cipher called "arcfour" in Tatu Ylonen's ssh package.
+ *
+ * RC4 is a registered trademark of RSA Laboratories.
+ */
+
+#ifdef __GNUC__
+#define inline __inline
+#else /* !__GNUC__ */
+#define inline
+#endif /* !__GNUC__ */
+
+struct arc4_stream {
+ uint8_t i;
+ uint8_t j;
+ uint8_t s[256];
+};
+
+#define RANDOMDEV "/dev/urandom"
+#define KEYSIZE 128
+#ifdef HAVE_PTHREAD_H
+static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
+#define _ARC4_LOCK() pthread_mutex_lock(&arc4random_mtx);
+#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx);
+#else
+#define _ARC4_LOCK()
+#define _ARC4_UNLOCK()
+#endif
+
+static int rs_initialized;
+static struct arc4_stream rs;
+static pid_t arc4_stir_pid;
+static int arc4_count;
+
+static inline uint8_t arc4_getbyte(void);
+static void arc4_stir(void);
+
+static inline void
+arc4_init(void)
+{
+ int n;
+
+ for (n = 0; n < 256; n++)
+ rs.s[n] = n;
+ rs.i = 0;
+ rs.j = 0;
+}
+
+static inline void
+arc4_addrandom(u_char *dat, int datlen)
+{
+ int n;
+ uint8_t si;
+
+ rs.i--;
+ for (n = 0; n < 256; n++) {
+ rs.i = (rs.i + 1);
+ si = rs.s[rs.i];
+ rs.j = (rs.j + si + dat[n % datlen]);
+ rs.s[rs.i] = rs.s[rs.j];
+ rs.s[rs.j] = si;
+ }
+ rs.j = rs.i;
+}
+
+static void
+arc4_stir(void)
+{
+ int done, fd, i;
+ struct {
+ struct timeval tv;
+ pid_t pid;
+ u_char rnd[KEYSIZE];
+ } rdat;
+
+ if (!rs_initialized) {
+ arc4_init();
+ rs_initialized = 1;
+ }
+ done = 0;
+ fd = open(RANDOMDEV, O_RDONLY | O_CLOEXEC, 0);
+ if (fd >= 0) {
+ if (read(fd, &rdat, KEYSIZE) == KEYSIZE)
+ done = 1;
+ (void)close(fd);
+ }
+ if (!done) {
+ (void)gettimeofday(&rdat.tv, NULL);
+ rdat.pid = getpid();
+ /* We'll just take whatever was on the stack too... */
+ }
+
+ arc4_addrandom((u_char *)&rdat, KEYSIZE);
+
+ /*
+ * Discard early keystream, as per recommendations in:
+ * "(Not So) Random Shuffles of RC4" by Ilya Mironov.
+ */
+ for (i = 0; i < 1024; i++)
+ (void)arc4_getbyte();
+ arc4_count = 1600000;
+}
+
+static void
+arc4_stir_if_needed(void)
+{
+ pid_t pid = getpid();
+
+ if (arc4_count <= 0 || !rs_initialized || arc4_stir_pid != pid) {
+ arc4_stir_pid = pid;
+ arc4_stir();
+ }
+}
+
+static inline uint8_t
+arc4_getbyte(void)
+{
+ uint8_t si, sj;
+
+ rs.i = (rs.i + 1);
+ si = rs.s[rs.i];
+ rs.j = (rs.j + si);
+ sj = rs.s[rs.j];
+ rs.s[rs.i] = sj;
+ rs.s[rs.j] = si;
+ return (rs.s[(si + sj) & 0xff]);
+}
+
+static void
+arc4random_buf(void *_buf, size_t n)
+{
+ u_char *buf = (u_char *)_buf;
+ _ARC4_LOCK();
+ arc4_stir_if_needed();
+ while (n--) {
+ if (--arc4_count <= 0)
+ arc4_stir();
+ buf[n] = arc4_getbyte();
+ }
+ _ARC4_UNLOCK();
+}
+
+#endif /* !HAVE_ARC4RANDOM_BUF */
diff --git a/Utilities/cmlibarchive/libarchive/archive_random_private.h b/Utilities/cmlibarchive/libarchive/archive_random_private.h
new file mode 100644
index 000000000..c414779f8
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_random_private.h
@@ -0,0 +1,36 @@
+/*-
+ * Copyright (c) 2014 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#ifndef ARCHIVE_RANDOM_PRIVATE_H_INCLUDED
+#define ARCHIVE_RANDOM_PRIVATE_H_INCLUDED
+
+/* Random number generator. */
+int archive_random(void *buf, size_t nbytes);
+
+#endif /* ARCHIVE_RANDOM_PRIVATE_H_INCLUDED */
diff --git a/Utilities/cmlibarchive/libarchive/archive_read.3 b/Utilities/cmlibarchive/libarchive/archive_read.3
index a29cc1ea6..d37e7327c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read.3
@@ -130,7 +130,7 @@ which provides a slightly more efficient interface.
You may prefer to use the higher-level
.Fn archive_read_data_skip ,
which reads and discards the data for this entry,
-.Fn archive_read_data_to_file ,
+.Fn archive_read_data_into_fd ,
which copies the data to the provided file descriptor, or
.Fn archive_read_extract ,
which recreates the specified entry on disk and copies data
@@ -186,7 +186,7 @@ list_archive(const char *name)
free(mydata);
}
-ssize_t
+la_ssize_t
myread(struct archive *a, void *client_data, const void **buff)
{
struct mydata *mydata = client_data;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read.c b/Utilities/cmlibarchive/libarchive/archive_read.c
index 796d37d06..033ed8b57 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read.c
@@ -101,16 +101,17 @@ archive_read_new(void)
{
struct archive_read *a;
- a = (struct archive_read *)malloc(sizeof(*a));
+ a = (struct archive_read *)calloc(1, sizeof(*a));
if (a == NULL)
return (NULL);
- memset(a, 0, sizeof(*a));
a->archive.magic = ARCHIVE_READ_MAGIC;
a->archive.state = ARCHIVE_STATE_NEW;
a->entry = archive_entry_new2(&a->archive);
a->archive.vtable = archive_read_vtable();
+ a->passphrases.last = &a->passphrases.first;
+
return (&a->archive);
}
@@ -194,10 +195,12 @@ client_skip_proxy(struct archive_read_filter *self, int64_t request)
ask = skip_limit;
get = (self->archive->client.skipper)
(&self->archive->archive, self->data, ask);
- if (get == 0)
+ total += get;
+ if (get == 0 || get == request)
return (total);
+ if (get > request)
+ return ARCHIVE_FATAL;
request -= get;
- total += get;
}
} else if (self->archive->client.seeker != NULL
&& request > 64 * 1024) {
@@ -230,8 +233,11 @@ client_seek_proxy(struct archive_read_filter *self, int64_t offset, int whence)
* other libarchive code that assumes a successful forward
* seek means it can also seek backwards.
*/
- if (self->archive->client.seeker == NULL)
+ if (self->archive->client.seeker == NULL) {
+ archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
+ "Current client reader does not support seeking a device");
return (ARCHIVE_FAILED);
+ }
return (self->archive->client.seeker)(&self->archive->archive,
self->data, offset, whence);
}
@@ -454,7 +460,7 @@ archive_read_open1(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
struct archive_read_filter *filter, *tmp;
- int slot, e;
+ int slot, e = ARCHIVE_OK;
unsigned int i;
archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
@@ -544,13 +550,13 @@ archive_read_open1(struct archive *_a)
static int
choose_filters(struct archive_read *a)
{
- int number_bidders, i, bid, best_bid;
+ int number_bidders, i, bid, best_bid, n;
struct archive_read_filter_bidder *bidder, *best_bidder;
struct archive_read_filter *filter;
ssize_t avail;
int r;
- for (;;) {
+ for (n = 0; n < 25; ++n) {
number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]);
best_bid = 0;
@@ -596,6 +602,9 @@ choose_filters(struct archive_read *a)
return (ARCHIVE_FATAL);
}
}
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Input requires too many filters for decoding");
+ return (ARCHIVE_FATAL);
}
/*
@@ -658,16 +667,14 @@ _archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
break;
}
- a->read_data_output_offset = 0;
- a->read_data_remaining = 0;
- a->read_data_is_posix_read = 0;
- a->read_data_requested = 0;
+ __archive_reset_read_data(&a->archive);
+
a->data_start_node = a->client.cursor;
/* EOF always wins; otherwise return the worst error. */
return (r2 < r1 || r2 == ARCHIVE_EOF) ? r2 : r1;
}
-int
+static int
_archive_read_next_header(struct archive *_a, struct archive_entry **entryp)
{
int ret;
@@ -747,6 +754,59 @@ archive_read_header_position(struct archive *_a)
}
/*
+ * Returns 1 if the archive contains at least one encrypted entry.
+ * If the archive format not support encryption at all
+ * ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED is returned.
+ * If for any other reason (e.g. not enough data read so far)
+ * we cannot say whether there are encrypted entries, then
+ * ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW is returned.
+ * In general, this function will return values below zero when the
+ * reader is uncertain or totally uncapable of encryption support.
+ * When this function returns 0 you can be sure that the reader
+ * supports encryption detection but no encrypted entries have
+ * been found yet.
+ *
+ * NOTE: If the metadata/header of an archive is also encrypted, you
+ * cannot rely on the number of encrypted entries. That is why this
+ * function does not return the number of encrypted entries but#
+ * just shows that there are some.
+ */
+int
+archive_read_has_encrypted_entries(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ int format_supports_encryption = archive_read_format_capabilities(_a)
+ & (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA | ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA);
+
+ if (!_a || !format_supports_encryption) {
+ /* Format in general doesn't support encryption */
+ return ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED;
+ }
+
+ /* A reader potentially has read enough data now. */
+ if (a->format && a->format->has_encrypted_entries) {
+ return (a->format->has_encrypted_entries)(a);
+ }
+
+ /* For any other reason we cannot say how many entries are there. */
+ return ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
+}
+
+/*
+ * Returns a bitmask of capabilities that are supported by the archive format reader.
+ * If the reader has no special capabilities, ARCHIVE_READ_FORMAT_CAPS_NONE is returned.
+ */
+int
+archive_read_format_capabilities(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ if (a && a->format && a->format->format_capabilties) {
+ return (a->format->format_capabilties)(a);
+ }
+ return ARCHIVE_READ_FORMAT_CAPS_NONE;
+}
+
+/*
* Read data from an archive entry, using a read(2)-style interface.
* This is a convenience routine that just calls
* archive_read_data_block and copies the results into the client
@@ -760,7 +820,7 @@ archive_read_header_position(struct archive *_a)
ssize_t
archive_read_data(struct archive *_a, void *buff, size_t s)
{
- struct archive_read *a = (struct archive_read *)_a;
+ struct archive *a = (struct archive *)_a;
char *dest;
const void *read_buf;
size_t bytes_read;
@@ -775,7 +835,7 @@ archive_read_data(struct archive *_a, void *buff, size_t s)
read_buf = a->read_data_block;
a->read_data_is_posix_read = 1;
a->read_data_requested = s;
- r = _archive_read_data_block(&a->archive, &read_buf,
+ r = archive_read_data_block(a, &read_buf,
&a->read_data_remaining, &a->read_data_offset);
a->read_data_block = read_buf;
if (r == ARCHIVE_EOF)
@@ -790,7 +850,7 @@ archive_read_data(struct archive *_a, void *buff, size_t s)
}
if (a->read_data_offset < a->read_data_output_offset) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
"Encountered out-of-order sparse blocks");
return (ARCHIVE_RETRY);
}
@@ -834,6 +894,21 @@ archive_read_data(struct archive *_a, void *buff, size_t s)
}
/*
+ * Reset the read_data_* variables, used for starting a new entry.
+ */
+void __archive_reset_read_data(struct archive * a)
+{
+ a->read_data_output_offset = 0;
+ a->read_data_remaining = 0;
+ a->read_data_is_posix_read = 0;
+ a->read_data_requested = 0;
+
+ /* extra resets, from rar.c */
+ a->read_data_block = NULL;
+ a->read_data_offset = 0;
+}
+
+/*
* Skip over all remaining data in this entry.
*/
int
@@ -900,7 +975,7 @@ _archive_read_data_block(struct archive *_a,
if (a->format->read_data == NULL) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
"Internal error: "
- "No format_read_data_block function registered");
+ "No format->read_data function registered");
return (ARCHIVE_FATAL);
}
@@ -987,6 +1062,7 @@ static int
_archive_read_free(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
+ struct archive_read_passphrase *p;
int i, n;
int slots;
int r = ARCHIVE_OK;
@@ -1024,9 +1100,20 @@ _archive_read_free(struct archive *_a)
}
}
+ /* Release passphrase list. */
+ p = a->passphrases.first;
+ while (p != NULL) {
+ struct archive_read_passphrase *np = p->next;
+
+ /* A passphrase should be cleaned. */
+ memset(p->passphrase, 0, strlen(p->passphrase));
+ free(p->passphrase);
+ free(p);
+ p = np;
+ }
+
archive_string_free(&a->archive.error_string);
- if (a->entry)
- archive_entry_free(a->entry);
+ archive_entry_free(a->entry);
a->archive.magic = 0;
__archive_clean(&a->archive);
free(a->client.dataset);
@@ -1094,7 +1181,9 @@ __archive_read_register_format(struct archive_read *a,
int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *),
int (*read_data_skip)(struct archive_read *),
int64_t (*seek_data)(struct archive_read *, int64_t, int),
- int (*cleanup)(struct archive_read *))
+ int (*cleanup)(struct archive_read *),
+ int (*format_capabilities)(struct archive_read *),
+ int (*has_encrypted_entries)(struct archive_read *))
{
int i, number_slots;
@@ -1117,6 +1206,8 @@ __archive_read_register_format(struct archive_read *a,
a->formats[i].cleanup = cleanup;
a->formats[i].data = format_data;
a->formats[i].name = name;
+ a->formats[i].format_capabilties = format_capabilities;
+ a->formats[i].has_encrypted_entries = has_encrypted_entries;
return (ARCHIVE_OK);
}
}
@@ -1394,6 +1485,8 @@ __archive_read_filter_consume(struct archive_read_filter * filter,
{
int64_t skipped;
+ if (request < 0)
+ return ARCHIVE_FATAL;
if (request == 0)
return 0;
@@ -1557,10 +1650,9 @@ __archive_read_filter_seek(struct archive_read_filter *filter, int64_t offset,
client->dataset[++cursor].begin_position = r;
}
offset -= client->dataset[cursor].begin_position;
- if (offset < 0)
- offset = 0;
- else if (offset > client->dataset[cursor].total_size - 1)
- offset = client->dataset[cursor].total_size - 1;
+ if (offset < 0
+ || offset > client->dataset[cursor].total_size)
+ return ARCHIVE_FATAL;
if ((r = client_seek_proxy(filter, offset, SEEK_SET)) < 0)
return r;
break;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.3 b/Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.3
new file mode 100644
index 000000000..8b242ea79
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.3
@@ -0,0 +1,74 @@
+.\" Copyright (c) 2014 Michihiro NAKAJIMA
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd September 14, 2014
+.Dt ARCHIVE_READ_ADD_PASSPHRASE 3
+.Os
+.Sh NAME
+.Nm archive_read_add_passphrase ,
+.Nm archive_read_set_passphrase_callback
+.Nd functions for reading encrypted archives
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
+.Sh SYNOPSIS
+.In archive.h
+.Ft int
+.Fo archive_read_add_passphrase
+.Fa "struct archive *"
+.Fa "const char *passphrase"
+.Fc
+.Ft int
+.Fo archive_read_set_passphrase_callback
+.Fa "struct archive *"
+.Fa "void *client_data"
+.Fa "archive_passphrase_callback *"
+.Fc
+.Sh DESCRIPTION
+.Bl -tag -width indent
+.It Fn archive_read_add_passphrase
+Register passphrases for reading an encryption archive.
+If
+.Ar passphrase
+is
+.Dv NULL
+or empty, this function will do nothing and
+.Cm ARCHIVE_FAILED
+will be returned.
+Otherwise,
+.Cm ARCHIVE_OK
+will be returned.
+.It Fn archive_read_set_passphrase_callback
+Register callback function that will be invoked to get a passphrase
+for decrption after trying all passphrases registered by the
+.Fn archive_read_add_passphrase
+function failed.
+.El
+.\" .Sh ERRORS
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_read 3 ,
+.Xr archive_read_set_options 3
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.c b/Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.c
new file mode 100644
index 000000000..f67f1ebc6
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.c
@@ -0,0 +1,186 @@
+/*-
+ * Copyright (c) 2014 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include "archive_read_private.h"
+
+static void
+add_passphrase_to_tail(struct archive_read *a,
+ struct archive_read_passphrase *p)
+{
+ *a->passphrases.last = p;
+ a->passphrases.last = &p->next;
+ p->next = NULL;
+}
+
+static struct archive_read_passphrase *
+remove_passphrases_from_head(struct archive_read *a)
+{
+ struct archive_read_passphrase *p;
+
+ p = a->passphrases.first;
+ if (p != NULL)
+ a->passphrases.first = p->next;
+ return (p);
+}
+
+static void
+insert_passphrase_to_head(struct archive_read *a,
+ struct archive_read_passphrase *p)
+{
+ p->next = a->passphrases.first;
+ a->passphrases.first = p;
+}
+
+static struct archive_read_passphrase *
+new_read_passphrase(struct archive_read *a, const char *passphrase)
+{
+ struct archive_read_passphrase *p;
+
+ p = malloc(sizeof(*p));
+ if (p == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (NULL);
+ }
+ p->passphrase = strdup(passphrase);
+ if (p->passphrase == NULL) {
+ free(p);
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (NULL);
+ }
+ return (p);
+}
+
+int
+archive_read_add_passphrase(struct archive *_a, const char *passphrase)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct archive_read_passphrase *p;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+ "archive_read_add_passphrase");
+
+ if (passphrase == NULL || passphrase[0] == '\0') {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Empty passphrase is unacceptable");
+ return (ARCHIVE_FAILED);
+ }
+
+ p = new_read_passphrase(a, passphrase);
+ if (p == NULL)
+ return (ARCHIVE_FATAL);
+ add_passphrase_to_tail(a, p);
+
+ return (ARCHIVE_OK);
+}
+
+int
+archive_read_set_passphrase_callback(struct archive *_a, void *client_data,
+ archive_passphrase_callback *cb)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+ "archive_read_set_passphrase_callback");
+
+ a->passphrases.callback = cb;
+ a->passphrases.client_data = client_data;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Call this in advance when you start to get a passphrase for decryption
+ * for a entry.
+ */
+void
+__archive_read_reset_passphrase(struct archive_read *a)
+{
+
+ a->passphrases.candiate = -1;
+}
+
+/*
+ * Get a passphrase for decryption.
+ */
+const char *
+__archive_read_next_passphrase(struct archive_read *a)
+{
+ struct archive_read_passphrase *p;
+ const char *passphrase;
+
+ if (a->passphrases.candiate < 0) {
+ /* Count out how many passphrases we have. */
+ int cnt = 0;
+
+ for (p = a->passphrases.first; p != NULL; p = p->next)
+ cnt++;
+ a->passphrases.candiate = cnt;
+ p = a->passphrases.first;
+ } else if (a->passphrases.candiate > 1) {
+ /* Rotate a passphrase list. */
+ a->passphrases.candiate--;
+ p = remove_passphrases_from_head(a);
+ add_passphrase_to_tail(a, p);
+ /* Pick a new passphrase candiate up. */
+ p = a->passphrases.first;
+ } else if (a->passphrases.candiate == 1) {
+ /* This case is that all cadiates failed to decryption. */
+ a->passphrases.candiate = 0;
+ if (a->passphrases.first->next != NULL) {
+ /* Rotate a passphrase list. */
+ p = remove_passphrases_from_head(a);
+ add_passphrase_to_tail(a, p);
+ }
+ p = NULL;
+ } else /* There is no passphrase candaite. */
+ p = NULL;
+
+ if (p != NULL)
+ passphrase = p->passphrase;
+ else if (a->passphrases.callback != NULL) {
+ /* Get a passphrase through a call-back function
+ * since we tried all passphrases out or we don't
+ * have it. */
+ passphrase = a->passphrases.callback(&a->archive,
+ a->passphrases.client_data);
+ if (passphrase != NULL) {
+ p = new_read_passphrase(a, passphrase);
+ if (p == NULL)
+ return (NULL);
+ insert_passphrase_to_head(a, p);
+ a->passphrases.candiate = 1;
+ }
+ } else
+ passphrase = NULL;
+
+ return (passphrase);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_append_filter.c b/Utilities/cmlibarchive/libarchive/archive_read_append_filter.c
index 017d7c68a..3a0d4d68d 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_append_filter.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_append_filter.c
@@ -43,7 +43,7 @@ archive_read_append_filter(struct archive *_a, int code)
struct archive_read_filter *filter;
struct archive_read *a = (struct archive_read *)_a;
- r1 = r2 = (ARCHIVE_OK);
+ r2 = (ARCHIVE_OK);
switch (code)
{
case ARCHIVE_FILTER_NONE:
@@ -85,6 +85,10 @@ archive_read_append_filter(struct archive *_a, int code)
strcpy(str, "rpm");
r1 = archive_read_support_filter_rpm(_a);
break;
+ case ARCHIVE_FILTER_LZ4:
+ strcpy(str, "lz4");
+ r1 = archive_read_support_filter_lz4(_a);
+ break;
case ARCHIVE_FILTER_LZIP:
strcpy(str, "lzip");
r1 = archive_read_support_filter_lzip(_a);
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_data.3 b/Utilities/cmlibarchive/libarchive/archive_read_data.3
index bf0578ce3..c1bc15d7c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_data.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_data.3
@@ -37,7 +37,7 @@
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS
.In archive.h
-.Ft ssize_t
+.Ft la_ssize_t
.Fn archive_read_data "struct archive *" "void *buff" "size_t len"
.Ft int
.Fo archive_read_data_block
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c b/Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c
index e984aaadb..38303aa87 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c
@@ -251,9 +251,11 @@ archive_read_disk_entry_from_file(struct archive *_a,
#endif /* HAVE_READLINK || HAVE_READLINKAT */
r = setup_acls(a, entry, &fd);
- r1 = setup_xattrs(a, entry, &fd);
- if (r1 < r)
- r = r1;
+ if (!a->suppress_xattr) {
+ r1 = setup_xattrs(a, entry, &fd);
+ if (r1 < r)
+ r = r1;
+ }
if (a->enable_copyfile) {
r1 = setup_mac_metadata(a, entry, &fd);
if (r1 < r)
@@ -399,7 +401,7 @@ setup_mac_metadata(struct archive_read_disk *a,
#endif
-#if defined(HAVE_POSIX_ACL) && defined(ACL_TYPE_NFS4)
+#ifdef HAVE_POSIX_ACL
static int translate_acl(struct archive_read_disk *a,
struct archive_entry *entry, acl_t acl, int archive_entry_acl_type);
@@ -419,6 +421,7 @@ setup_acls(struct archive_read_disk *a,
archive_entry_acl_clear(entry);
+#ifdef ACL_TYPE_NFS4
/* Try NFS4 ACL first. */
if (*fd >= 0)
acl = acl_get_fd(*fd);
@@ -447,6 +450,7 @@ setup_acls(struct archive_read_disk *a,
acl_free(acl);
return (ARCHIVE_OK);
}
+#endif
/* Retrieve access ACL from file. */
if (*fd >= 0)
@@ -492,6 +496,7 @@ static struct {
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
+#ifdef ACL_TYPE_NFS4
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
@@ -508,8 +513,10 @@ static struct {
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
+#endif
};
+#ifdef ACL_TYPE_NFS4
static struct {
int archive_inherit;
int platform_inherit;
@@ -519,21 +526,25 @@ static struct {
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY}
};
-
+#endif
static int
translate_acl(struct archive_read_disk *a,
struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
{
acl_tag_t acl_tag;
+#ifdef ACL_TYPE_NFS4
acl_entry_type_t acl_type;
acl_flagset_t acl_flagset;
+ int brand, r;
+#endif
acl_entry_t acl_entry;
acl_permset_t acl_permset;
- int brand, i, r, entry_acl_type;
+ int i, entry_acl_type;
int s, ae_id, ae_tag, ae_perm;
const char *ae_name;
+#ifdef ACL_TYPE_NFS4
// FreeBSD "brands" ACLs as POSIX.1e or NFSv4
// Make sure the "brand" on this ACL is consistent
// with the default_entry_acl_type bits provided.
@@ -560,6 +571,7 @@ translate_acl(struct archive_read_disk *a,
return ARCHIVE_FAILED;
break;
}
+#endif
s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
@@ -592,9 +604,11 @@ translate_acl(struct archive_read_disk *a,
case ACL_OTHER:
ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
break;
+#ifdef ACL_TYPE_NFS4
case ACL_EVERYONE:
ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
break;
+#endif
default:
/* Skip types that libarchive can't support. */
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
@@ -605,6 +619,7 @@ translate_acl(struct archive_read_disk *a,
// XXX acl_get_entry_type_np on FreeBSD returns EINVAL for
// non-NFSv4 ACLs
entry_acl_type = default_entry_acl_type;
+#ifdef ACL_TYPE_NFS4
r = acl_get_entry_type_np(acl_entry, &acl_type);
if (r == 0) {
switch (acl_type) {
@@ -634,9 +649,10 @@ translate_acl(struct archive_read_disk *a,
ae_perm |= acl_inherit_map[i].archive_inherit;
}
+#endif
acl_get_permset(acl_entry, &acl_permset);
- for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) {
+ for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) {
/*
* acl_get_perm() is spelled differently on different
* platforms; see above.
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c b/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
index a13dbbf81..f48053922 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
@@ -356,6 +356,8 @@ static int _archive_read_free(struct archive *);
static int _archive_read_close(struct archive *);
static int _archive_read_data_block(struct archive *,
const void **, size_t *, int64_t *);
+static int _archive_read_next_header(struct archive *,
+ struct archive_entry **);
static int _archive_read_next_header2(struct archive *,
struct archive_entry *);
static const char *trivial_lookup_gname(void *, int64_t gid);
@@ -377,6 +379,7 @@ archive_read_disk_vtable(void)
av.archive_free = _archive_read_free;
av.archive_close = _archive_read_close;
av.archive_read_data_block = _archive_read_data_block;
+ av.archive_read_next_header = _archive_read_next_header;
av.archive_read_next_header2 = _archive_read_next_header2;
inited = 1;
}
@@ -459,6 +462,7 @@ archive_read_disk_new(void)
a->archive.magic = ARCHIVE_READ_DISK_MAGIC;
a->archive.state = ARCHIVE_STATE_NEW;
a->archive.vtable = archive_read_disk_vtable();
+ a->entry = archive_entry_new2(&a->archive);
a->lookup_uname = trivial_lookup_uname;
a->lookup_gname = trivial_lookup_gname;
a->enable_copyfile = 1;
@@ -491,6 +495,7 @@ _archive_read_free(struct archive *_a)
if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
(a->cleanup_uname)(a->lookup_uname_data);
archive_string_free(&a->archive.error_string);
+ archive_entry_free(a->entry);
a->archive.magic = 0;
__archive_clean(&a->archive);
free(a);
@@ -609,6 +614,10 @@ archive_read_disk_set_behavior(struct archive *_a, int flags)
a->traverse_mount_points = 0;
else
a->traverse_mount_points = 1;
+ if (flags & ARCHIVE_READDISK_NO_XATTR)
+ a->suppress_xattr = 1;
+ else
+ a->suppress_xattr = 0;
return (r);
}
@@ -974,7 +983,7 @@ next_entry(struct archive_read_disk *a, struct tree *t,
t->initial_filesystem_id = t->current_filesystem_id;
if (!a->traverse_mount_points) {
if (t->initial_filesystem_id != t->current_filesystem_id)
- return (ARCHIVE_RETRY);
+ descend = 0;
}
t->descend = descend;
@@ -1081,6 +1090,17 @@ next_entry(struct archive_read_disk *a, struct tree *t,
}
static int
+_archive_read_next_header(struct archive *_a, struct archive_entry **entryp)
+{
+ int ret;
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ *entryp = NULL;
+ ret = _archive_read_next_header2(_a, a->entry);
+ *entryp = a->entry;
+ return ret;
+}
+
+static int
_archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
@@ -1148,6 +1168,7 @@ _archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
break;
}
+ __archive_reset_read_data(&a->archive);
return (r);
}
@@ -1973,7 +1994,7 @@ tree_dup(int fd)
static volatile int can_dupfd_cloexec = 1;
if (can_dupfd_cloexec) {
- new_fd = fcntl(fd, F_DUPFD_CLOEXEC);
+ new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
if (new_fd != -1)
return (new_fd);
/* Linux 2.6.18 - 2.6.23 declare F_DUPFD_CLOEXEC,
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_private.h b/Utilities/cmlibarchive/libarchive/archive_read_disk_private.h
index e5af16b91..2569321da 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_private.h
@@ -39,6 +39,9 @@ struct archive_entry;
struct archive_read_disk {
struct archive archive;
+ /* Reused by archive_read_next_header() */
+ struct archive_entry *entry;
+
/*
* Symlink mode is one of 'L'ogical, 'P'hysical, or 'H'ybrid,
* following an old BSD convention. 'L' follows all symlinks,
@@ -68,6 +71,8 @@ struct archive_read_disk {
int enable_copyfile;
/* Set 1 if users request to traverse mount points. */
int traverse_mount_points;
+ /* Set 1 if users want to suppress xattr information. */
+ int suppress_xattr;
const char * (*lookup_gname)(void *private, int64_t gid);
void (*cleanup_gname)(void *private);
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_set_standard_lookup.c b/Utilities/cmlibarchive/libarchive/archive_read_disk_set_standard_lookup.c
index 3bc52c70d..d6b2d55b8 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk_set_standard_lookup.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_set_standard_lookup.c
@@ -83,7 +83,7 @@ static const char * lookup_uname_helper(struct name_cache *, id_t uid);
* a simple cache to accelerate such lookups---into the archive_read_disk
* object. This is in a separate file because getpwuid()/getgrgid()
* can pull in a LOT of library code (including NIS/LDAP functions, which
- * pull in DNS resolveers, etc). This can easily top 500kB, which makes
+ * pull in DNS resolvers, etc). This can easily top 500kB, which makes
* it inappropriate for some space-constrained applications.
*
* Applications that are size-sensitive may want to just use the
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c b/Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c
index 9c5420d80..53bd4b8bd 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c
@@ -288,6 +288,8 @@ static int _archive_read_free(struct archive *);
static int _archive_read_close(struct archive *);
static int _archive_read_data_block(struct archive *,
const void **, size_t *, int64_t *);
+static int _archive_read_next_header(struct archive *,
+ struct archive_entry **);
static int _archive_read_next_header2(struct archive *,
struct archive_entry *);
static const char *trivial_lookup_gname(void *, int64_t gid);
@@ -310,6 +312,7 @@ archive_read_disk_vtable(void)
av.archive_free = _archive_read_free;
av.archive_close = _archive_read_close;
av.archive_read_data_block = _archive_read_data_block;
+ av.archive_read_next_header = _archive_read_next_header;
av.archive_read_next_header2 = _archive_read_next_header2;
inited = 1;
}
@@ -393,6 +396,7 @@ archive_read_disk_new(void)
a->archive.magic = ARCHIVE_READ_DISK_MAGIC;
a->archive.state = ARCHIVE_STATE_NEW;
a->archive.vtable = archive_read_disk_vtable();
+ a->entry = archive_entry_new2(&a->archive);
a->lookup_uname = trivial_lookup_uname;
a->lookup_gname = trivial_lookup_gname;
a->enable_copyfile = 1;
@@ -422,6 +426,7 @@ _archive_read_free(struct archive *_a)
if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
(a->cleanup_uname)(a->lookup_uname_data);
archive_string_free(&a->archive.error_string);
+ archive_entry_free(a->entry);
a->archive.magic = 0;
free(a);
return (r);
@@ -929,7 +934,7 @@ next_entry(struct archive_read_disk *a, struct tree *t,
else
flags |= FILE_FLAG_SEQUENTIAL_SCAN;
t->entry_fh = CreateFileW(tree_current_access_path(t),
- GENERIC_READ, 0, NULL, OPEN_EXISTING, flags, NULL);
+ GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, flags, NULL);
if (t->entry_fh == INVALID_HANDLE_VALUE) {
archive_set_error(&a->archive, errno,
"Couldn't open %ls", tree_current_path(a->tree));
@@ -945,6 +950,17 @@ next_entry(struct archive_read_disk *a, struct tree *t,
}
static int
+_archive_read_next_header(struct archive *_a, struct archive_entry **entryp)
+{
+ int ret;
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ *entryp = NULL;
+ ret = _archive_read_next_header2(_a, a->entry);
+ *entryp = a->entry;
+ return ret;
+}
+
+static int
_archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
@@ -1000,6 +1016,7 @@ _archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
break;
}
+ __archive_reset_read_data(&a->archive);
return (r);
}
@@ -1851,8 +1868,6 @@ entry_copy_bhfi(struct archive_entry *entry, const wchar_t *path,
break;
case L'C': case L'c':
if (((p[2] == L'M' || p[2] == L'm' ) &&
- (p[3] == L'D' || p[3] == L'd' )) ||
- ((p[2] == L'M' || p[2] == L'm' ) &&
(p[3] == L'D' || p[3] == L'd' )))
mode |= S_IXUSR | S_IXGRP | S_IXOTH;
break;
@@ -1886,7 +1901,7 @@ tree_current_file_information(struct tree *t, BY_HANDLE_FILE_INFORMATION *st,
if (sim_lstat && tree_current_is_physical_link(t))
flag |= FILE_FLAG_OPEN_REPARSE_POINT;
- h = CreateFileW(tree_current_access_path(t), 0, 0, NULL,
+ h = CreateFileW(tree_current_access_path(t), 0, FILE_SHARE_READ, NULL,
OPEN_EXISTING, flag, NULL);
if (h == INVALID_HANDLE_VALUE) {
la_dosmaperr(GetLastError());
@@ -2115,7 +2130,7 @@ archive_read_disk_entry_from_file(struct archive *_a,
} else
desiredAccess = GENERIC_READ;
- h = CreateFileW(path, desiredAccess, 0, NULL,
+ h = CreateFileW(path, desiredAccess, FILE_SHARE_READ, NULL,
OPEN_EXISTING, flag, NULL);
if (h == INVALID_HANDLE_VALUE) {
la_dosmaperr(GetLastError());
@@ -2162,7 +2177,7 @@ archive_read_disk_entry_from_file(struct archive *_a,
if (fd >= 0) {
h = (HANDLE)_get_osfhandle(fd);
} else {
- h = CreateFileW(path, GENERIC_READ, 0, NULL,
+ h = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (h == INVALID_HANDLE_VALUE) {
la_dosmaperr(GetLastError());
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_extract.c b/Utilities/cmlibarchive/libarchive/archive_read_extract.c
index 795f2abea..b7973fa8e 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_extract.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_extract.c
@@ -26,158 +26,35 @@
#include "archive_platform.h"
__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_extract.c,v 1.61 2008/05/26 17:00:22 kientzle Exp $");
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
#include "archive.h"
#include "archive_entry.h"
#include "archive_private.h"
#include "archive_read_private.h"
-#include "archive_write_disk_private.h"
-
-struct extract {
- struct archive *ad; /* archive_write_disk object */
-
- /* Progress function invoked during extract. */
- void (*extract_progress)(void *);
- void *extract_progress_user_data;
-};
-
-static int archive_read_extract_cleanup(struct archive_read *);
-static int copy_data(struct archive *ar, struct archive *aw);
-static struct extract *get_extract(struct archive_read *);
-
-static struct extract *
-get_extract(struct archive_read *a)
-{
- /* If we haven't initialized, do it now. */
- /* This also sets up a lot of global state. */
- if (a->extract == NULL) {
- a->extract = (struct extract *)malloc(sizeof(*a->extract));
- if (a->extract == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Can't extract");
- return (NULL);
- }
- memset(a->extract, 0, sizeof(*a->extract));
- a->extract->ad = archive_write_disk_new();
- if (a->extract->ad == NULL) {
- archive_set_error(&a->archive, ENOMEM, "Can't extract");
- return (NULL);
- }
- archive_write_disk_set_standard_lookup(a->extract->ad);
- a->cleanup_archive_extract = archive_read_extract_cleanup;
- }
- return (a->extract);
-}
int
archive_read_extract(struct archive *_a, struct archive_entry *entry, int flags)
{
- struct extract *extract;
+ struct archive_read_extract *extract;
+ struct archive_read * a = (struct archive_read *)_a;
- extract = get_extract((struct archive_read *)_a);
+ extract = __archive_read_get_extract(a);
if (extract == NULL)
return (ARCHIVE_FATAL);
- archive_write_disk_set_options(extract->ad, flags);
- return (archive_read_extract2(_a, entry, extract->ad));
-}
-int
-archive_read_extract2(struct archive *_a, struct archive_entry *entry,
- struct archive *ad)
-{
- struct archive_read *a = (struct archive_read *)_a;
- int r, r2;
-
- /* Set up for this particular entry. */
- if (a->skip_file_set)
- archive_write_disk_set_skip_file(ad,
- a->skip_file_dev, a->skip_file_ino);
- r = archive_write_header(ad, entry);
- if (r < ARCHIVE_WARN)
- r = ARCHIVE_WARN;
- if (r != ARCHIVE_OK)
- /* If _write_header failed, copy the error. */
- archive_copy_error(&a->archive, ad);
- else if (!archive_entry_size_is_set(entry) || archive_entry_size(entry) > 0)
- /* Otherwise, pour data into the entry. */
- r = copy_data(_a, ad);
- r2 = archive_write_finish_entry(ad);
- if (r2 < ARCHIVE_WARN)
- r2 = ARCHIVE_WARN;
- /* Use the first message. */
- if (r2 != ARCHIVE_OK && r == ARCHIVE_OK)
- archive_copy_error(&a->archive, ad);
- /* Use the worst error return. */
- if (r2 < r)
- r = r2;
- return (r);
-}
-
-void
-archive_read_extract_set_progress_callback(struct archive *_a,
- void (*progress_func)(void *), void *user_data)
-{
- struct archive_read *a = (struct archive_read *)_a;
- struct extract *extract = get_extract(a);
- if (extract != NULL) {
- extract->extract_progress = progress_func;
- extract->extract_progress_user_data = user_data;
- }
-}
-
-static int
-copy_data(struct archive *ar, struct archive *aw)
-{
- int64_t offset;
- const void *buff;
- struct extract *extract;
- size_t size;
- int r;
-
- extract = get_extract((struct archive_read *)ar);
- if (extract == NULL)
- return (ARCHIVE_FATAL);
- for (;;) {
- r = archive_read_data_block(ar, &buff, &size, &offset);
- if (r == ARCHIVE_EOF)
- return (ARCHIVE_OK);
- if (r != ARCHIVE_OK)
- return (r);
- r = (int)archive_write_data_block(aw, buff, size, offset);
- if (r < ARCHIVE_WARN)
- r = ARCHIVE_WARN;
- if (r != ARCHIVE_OK) {
- archive_set_error(ar, archive_errno(aw),
- "%s", archive_error_string(aw));
- return (r);
+ /* If we haven't initialized the archive_write_disk object, do it now. */
+ if (extract->ad == NULL) {
+ extract->ad = archive_write_disk_new();
+ if (extract->ad == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Can't extract");
+ return (ARCHIVE_FATAL);
}
- if (extract->extract_progress)
- (extract->extract_progress)
- (extract->extract_progress_user_data);
+ archive_write_disk_set_standard_lookup(extract->ad);
}
-}
-/*
- * Cleanup function for archive_extract.
- */
-static int
-archive_read_extract_cleanup(struct archive_read *a)
-{
- int ret = ARCHIVE_OK;
-
- ret = archive_write_free(a->extract->ad);
- free(a->extract);
- a->extract = NULL;
- return (ret);
+ archive_write_disk_set_options(extract->ad, flags);
+ return (archive_read_extract2(&a->archive, entry, extract->ad));
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_extract2.c b/Utilities/cmlibarchive/libarchive/archive_read_extract2.c
new file mode 100644
index 000000000..7b2c12631
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_extract2.c
@@ -0,0 +1,156 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_extract.c,v 1.61 2008/05/26 17:00:22 kientzle Exp $");
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+
+static int copy_data(struct archive *ar, struct archive *aw);
+static int archive_read_extract_cleanup(struct archive_read *);
+
+
+/* Retrieve an extract object without initialising the associated
+ * archive_write_disk object.
+ */
+struct archive_read_extract *
+__archive_read_get_extract(struct archive_read *a)
+{
+ if (a->extract == NULL) {
+ a->extract = (struct archive_read_extract *)malloc(sizeof(*a->extract));
+ if (a->extract == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Can't extract");
+ return (NULL);
+ }
+ memset(a->extract, 0, sizeof(*a->extract));
+ a->cleanup_archive_extract = archive_read_extract_cleanup;
+ }
+ return (a->extract);
+}
+
+/*
+ * Cleanup function for archive_extract.
+ */
+static int
+archive_read_extract_cleanup(struct archive_read *a)
+{
+ int ret = ARCHIVE_OK;
+
+ if (a->extract->ad != NULL) {
+ ret = archive_write_free(a->extract->ad);
+ }
+ free(a->extract);
+ a->extract = NULL;
+ return (ret);
+}
+
+int
+archive_read_extract2(struct archive *_a, struct archive_entry *entry,
+ struct archive *ad)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ int r, r2;
+
+ /* Set up for this particular entry. */
+ if (a->skip_file_set)
+ archive_write_disk_set_skip_file(ad,
+ a->skip_file_dev, a->skip_file_ino);
+ r = archive_write_header(ad, entry);
+ if (r < ARCHIVE_WARN)
+ r = ARCHIVE_WARN;
+ if (r != ARCHIVE_OK)
+ /* If _write_header failed, copy the error. */
+ archive_copy_error(&a->archive, ad);
+ else if (!archive_entry_size_is_set(entry) || archive_entry_size(entry) > 0)
+ /* Otherwise, pour data into the entry. */
+ r = copy_data(_a, ad);
+ r2 = archive_write_finish_entry(ad);
+ if (r2 < ARCHIVE_WARN)
+ r2 = ARCHIVE_WARN;
+ /* Use the first message. */
+ if (r2 != ARCHIVE_OK && r == ARCHIVE_OK)
+ archive_copy_error(&a->archive, ad);
+ /* Use the worst error return. */
+ if (r2 < r)
+ r = r2;
+ return (r);
+}
+
+void
+archive_read_extract_set_progress_callback(struct archive *_a,
+ void (*progress_func)(void *), void *user_data)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct archive_read_extract *extract = __archive_read_get_extract(a);
+ if (extract != NULL) {
+ extract->extract_progress = progress_func;
+ extract->extract_progress_user_data = user_data;
+ }
+}
+
+static int
+copy_data(struct archive *ar, struct archive *aw)
+{
+ int64_t offset;
+ const void *buff;
+ struct archive_read_extract *extract;
+ size_t size;
+ int r;
+
+ extract = __archive_read_get_extract((struct archive_read *)ar);
+ if (extract == NULL)
+ return (ARCHIVE_FATAL);
+ for (;;) {
+ r = archive_read_data_block(ar, &buff, &size, &offset);
+ if (r == ARCHIVE_EOF)
+ return (ARCHIVE_OK);
+ if (r != ARCHIVE_OK)
+ return (r);
+ r = (int)archive_write_data_block(aw, buff, size, offset);
+ if (r < ARCHIVE_WARN)
+ r = ARCHIVE_WARN;
+ if (r < ARCHIVE_OK) {
+ archive_set_error(ar, archive_errno(aw),
+ "%s", archive_error_string(aw));
+ return (r);
+ }
+ if (extract->extract_progress)
+ (extract->extract_progress)
+ (extract->extract_progress_user_data);
+ }
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_filter.3 b/Utilities/cmlibarchive/libarchive/archive_read_filter.3
index 8761127d9..47effacca 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_filter.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_filter.3
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 2, 2012
+.Dd August 14, 2014
.Dt ARCHIVE_READ_FILTER 3
.Os
.Sh NAME
@@ -32,8 +32,11 @@
.Nm archive_read_support_filter_bzip2 ,
.Nm archive_read_support_filter_compress ,
.Nm archive_read_support_filter_gzip ,
+.Nm archive_read_support_filter_lz4 ,
.Nm archive_read_support_filter_lzma ,
.Nm archive_read_support_filter_none ,
+.Nm archive_read_support_filter_rpm ,
+.Nm archive_read_support_filter_uu ,
.Nm archive_read_support_filter_xz ,
.Nm archive_read_support_filter_program ,
.Nm archive_read_support_filter_program_signature
@@ -52,10 +55,18 @@ Streaming Archive Library (libarchive, -larchive)
.Ft int
.Fn archive_read_support_filter_gzip "struct archive *"
.Ft int
+.Fn archive_read_support_filter_lz4 "struct archive *"
+.Ft int
.Fn archive_read_support_filter_lzma "struct archive *"
.Ft int
+.Fn archive_read_support_filter_lzop "struct archive *"
+.Ft int
.Fn archive_read_support_filter_none "struct archive *"
.Ft int
+.Fn archive_read_support_filter_rpm "struct archive *"
+.Ft int
+.Fn archive_read_support_filter_uu "struct archive *"
+.Ft int
.Fn archive_read_support_filter_xz "struct archive *"
.Ft int
.Fo archive_read_support_filter_program
@@ -76,8 +87,12 @@ Streaming Archive Library (libarchive, -larchive)
.Fn archive_read_support_filter_bzip2 ,
.Fn archive_read_support_filter_compress ,
.Fn archive_read_support_filter_gzip ,
+.Fn archive_read_support_filter_lz4 ,
.Fn archive_read_support_filter_lzma ,
+.Fn archive_read_support_filter_lzop ,
.Fn archive_read_support_filter_none ,
+.Fn archive_read_support_filter_rpm ,
+.Fn archive_read_support_filter_uu ,
.Fn archive_read_support_filter_xz
.Xc
Enables auto-detection code and decompression support for the
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_open.3 b/Utilities/cmlibarchive/libarchive/archive_read_open.3
index 30a740bef..4d8272cac 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_open.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_open.3
@@ -130,14 +130,14 @@ objects can be found in the overview manual page for
The callback functions must match the following prototypes:
.Bl -item -offset indent
.It
-.Ft typedef ssize_t
+.Ft typedef la_ssize_t
.Fo archive_read_callback
.Fa "struct archive *"
.Fa "void *client_data"
.Fa "const void **buffer"
.Fc
.It
-.Ft typedef off_t
+.Ft typedef la_int64_t
.Fo archive_skip_callback
.Fa "struct archive *"
.Fa "void *client_data"
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_open_fd.c b/Utilities/cmlibarchive/libarchive/archive_read_open_fd.c
index e0f95bf41..f59cd07fe 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_open_fd.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_open_fd.c
@@ -59,6 +59,7 @@ struct read_fd_data {
static int file_close(struct archive *, void *);
static ssize_t file_read(struct archive *, void *, const void **buff);
+static int64_t file_seek(struct archive *, void *, int64_t request, int);
static int64_t file_skip(struct archive *, void *, int64_t request);
int
@@ -102,6 +103,7 @@ archive_read_open_fd(struct archive *a, int fd, size_t block_size)
archive_read_set_read_callback(a, file_read);
archive_read_set_skip_callback(a, file_skip);
+ archive_read_set_seek_callback(a, file_seek);
archive_read_set_close_callback(a, file_close);
archive_read_set_callback_data(a, mine);
return (archive_read_open1(a));
@@ -170,6 +172,33 @@ file_skip(struct archive *a, void *client_data, int64_t request)
return (-1);
}
+/*
+ * TODO: Store the offset and use it in the read callback.
+ */
+static int64_t
+file_seek(struct archive *a, void *client_data, int64_t request, int whence)
+{
+ struct read_fd_data *mine = (struct read_fd_data *)client_data;
+ int64_t r;
+
+ /* We use off_t here because lseek() is declared that way. */
+ /* See above for notes about when off_t is less than 64 bits. */
+ r = lseek(mine->fd, request, whence);
+ if (r >= 0)
+ return r;
+
+ if (errno == ESPIPE) {
+ archive_set_error(a, errno,
+ "A file descriptor(%d) is not seekable(PIPE)", mine->fd);
+ return (ARCHIVE_FAILED);
+ } else {
+ /* If the input is corrupted or truncated, fail. */
+ archive_set_error(a, errno,
+ "Error seeking in a file descriptor(%d)", mine->fd);
+ return (ARCHIVE_FATAL);
+ }
+}
+
static int
file_close(struct archive *a, void *client_data)
{
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_open_memory.c b/Utilities/cmlibarchive/libarchive/archive_read_open_memory.c
index bcc7d6f78..ff935a708 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_open_memory.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_open_memory.c
@@ -41,9 +41,9 @@ __FBSDID("$FreeBSD: src/lib/libarchive/archive_read_open_memory.c,v 1.6 2007/07/
*/
struct read_memory_data {
- unsigned char *start;
- unsigned char *p;
- unsigned char *end;
+ const unsigned char *start;
+ const unsigned char *p;
+ const unsigned char *end;
ssize_t read_size;
};
@@ -54,7 +54,7 @@ static int64_t memory_read_skip(struct archive *, void *, int64_t request);
static ssize_t memory_read(struct archive *, void *, const void **buff);
int
-archive_read_open_memory(struct archive *a, void *buff, size_t size)
+archive_read_open_memory(struct archive *a, const void *buff, size_t size)
{
return archive_read_open_memory2(a, buff, size, size);
}
@@ -65,7 +65,7 @@ archive_read_open_memory(struct archive *a, void *buff, size_t size)
* test harnesses can exercise block operations inside the library.
*/
int
-archive_read_open_memory2(struct archive *a, void *buff,
+archive_read_open_memory2(struct archive *a, const void *buff,
size_t size, size_t read_size)
{
struct read_memory_data *mine;
@@ -76,7 +76,7 @@ archive_read_open_memory2(struct archive *a, void *buff,
return (ARCHIVE_FATAL);
}
memset(mine, 0, sizeof(*mine));
- mine->start = mine->p = (unsigned char *)buff;
+ mine->start = mine->p = (const unsigned char *)buff;
mine->end = mine->start + size;
mine->read_size = read_size;
archive_read_set_open_callback(a, memory_read_open);
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_private.h b/Utilities/cmlibarchive/libarchive/archive_read_private.h
index 8a6c859a8..9b61a5380 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_read_private.h
@@ -26,8 +26,10 @@
*/
#ifndef __LIBARCHIVE_BUILD
+#ifndef __LIBARCHIVE_TEST
#error This header is only to be used internally to libarchive.
#endif
+#endif
#ifndef ARCHIVE_READ_PRIVATE_H_INCLUDED
#define ARCHIVE_READ_PRIVATE_H_INCLUDED
@@ -141,6 +143,18 @@ struct archive_read_client {
int64_t position;
struct archive_read_data_node *dataset;
};
+struct archive_read_passphrase {
+ char *passphrase;
+ struct archive_read_passphrase *next;
+};
+
+struct archive_read_extract {
+ struct archive *ad; /* archive_write_disk object */
+
+ /* Progress function invoked during extract. */
+ void (*extract_progress)(void *);
+ void *extract_progress_user_data;
+};
struct archive_read {
struct archive archive;
@@ -152,28 +166,11 @@ struct archive_read {
int64_t skip_file_dev;
int64_t skip_file_ino;
- /*
- * Used by archive_read_data() to track blocks and copy
- * data to client buffers, filling gaps with zero bytes.
- */
- const char *read_data_block;
- int64_t read_data_offset;
- int64_t read_data_output_offset;
- size_t read_data_remaining;
-
- /*
- * Used by formats/filters to determine the amount of data
- * requested from a call to archive_read_data(). This is only
- * useful when the format/filter has seek support.
- */
- char read_data_is_posix_read;
- size_t read_data_requested;
-
/* Callbacks to open/read/write/close client archive streams. */
struct archive_read_client client;
/* Registered filter bidders. */
- struct archive_read_filter_bidder bidders[14];
+ struct archive_read_filter_bidder bidders[16];
/* Last filter in chain */
struct archive_read_filter *filter;
@@ -207,26 +204,41 @@ struct archive_read {
int (*read_data_skip)(struct archive_read *);
int64_t (*seek_data)(struct archive_read *, int64_t, int);
int (*cleanup)(struct archive_read *);
+ int (*format_capabilties)(struct archive_read *);
+ int (*has_encrypted_entries)(struct archive_read *);
} formats[16];
struct archive_format_descriptor *format; /* Active format. */
/*
* Various information needed by archive_extract.
*/
- struct extract *extract;
+ struct archive_read_extract *extract;
int (*cleanup_archive_extract)(struct archive_read *);
+
+ /*
+ * Decryption passphrase.
+ */
+ struct {
+ struct archive_read_passphrase *first;
+ struct archive_read_passphrase **last;
+ int candiate;
+ archive_passphrase_callback *callback;
+ void *client_data;
+ } passphrases;
};
int __archive_read_register_format(struct archive_read *a,
- void *format_data,
- const char *name,
- int (*bid)(struct archive_read *, int),
- int (*options)(struct archive_read *, const char *, const char *),
- int (*read_header)(struct archive_read *, struct archive_entry *),
- int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *),
- int (*read_data_skip)(struct archive_read *),
- int64_t (*seek_data)(struct archive_read *, int64_t, int),
- int (*cleanup)(struct archive_read *));
+ void *format_data,
+ const char *name,
+ int (*bid)(struct archive_read *, int),
+ int (*options)(struct archive_read *, const char *, const char *),
+ int (*read_header)(struct archive_read *, struct archive_entry *),
+ int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *),
+ int (*read_data_skip)(struct archive_read *),
+ int64_t (*seek_data)(struct archive_read *, int64_t, int),
+ int (*cleanup)(struct archive_read *),
+ int (*format_capabilities)(struct archive_read *),
+ int (*has_encrypted_entries)(struct archive_read *));
int __archive_read_get_bidder(struct archive_read *a,
struct archive_read_filter_bidder **bidder);
@@ -241,4 +253,12 @@ int64_t __archive_read_filter_consume(struct archive_read_filter *, int64_t);
int __archive_read_program(struct archive_read_filter *, const char *);
void __archive_read_free_filters(struct archive_read *);
int __archive_read_close_filters(struct archive_read *);
+struct archive_read_extract *__archive_read_get_extract(struct archive_read *);
+
+
+/*
+ * Get a decryption passphrase.
+ */
+void __archive_read_reset_passphrase(struct archive_read *a);
+const char * __archive_read_next_passphrase(struct archive_read *a);
#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_set_options.3 b/Utilities/cmlibarchive/libarchive/archive_read_set_options.3
index 6fe9f90f8..1a251cefe 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_set_options.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_set_options.3
@@ -193,6 +193,28 @@ Defaults to enabled, use
.Cm !rockridge
to disable.
.El
+.It Format tar
+.Bl -tag -compact -width indent
+.It Cm compat-2x
+Libarchive 2.x incorrectly encoded Unicode filenames on
+some platforms.
+This option mimics the libarchive 2.x filename handling
+so that such archives can be read correctly.
+.It Cm hdrcharset
+The value is used as a character set name that will be
+used when translating filenames.
+.It Cm mac-ext
+Support Mac OS metadata extension that records data in special
+files beginning with a period and underscore.
+Defaults to enabled on Mac OS, disabled on other platforms.
+Use
+.Cm !mac-ext
+to disable.
+.It Cm read_concatenated_archives
+Ignore zeroed blocks in the archive, which occurs when multiple tar archives
+have been concatenated together. Without this option, only the contents of
+the first concatenated archive would be read.
+.El
.El
.\"
.Sh ERRORS
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_set_options.c b/Utilities/cmlibarchive/libarchive/archive_read_set_options.c
index 793f8f73e..2e2eea690 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_set_options.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_set_options.c
@@ -76,18 +76,20 @@ archive_set_format_option(struct archive *_a, const char *m, const char *o,
const char *v)
{
struct archive_read *a = (struct archive_read *)_a;
- struct archive_format_descriptor *format;
size_t i;
- int r, rv = ARCHIVE_WARN;
+ int r, rv = ARCHIVE_WARN, matched_modules = 0;
for (i = 0; i < sizeof(a->formats)/sizeof(a->formats[0]); i++) {
- format = &a->formats[i];
- if (format == NULL || format->options == NULL ||
- format->name == NULL)
+ struct archive_format_descriptor *format = &a->formats[i];
+
+ if (format->options == NULL || format->name == NULL)
/* This format does not support option. */
continue;
- if (m != NULL && strcmp(format->name, m) != 0)
- continue;
+ if (m != NULL) {
+ if (strcmp(format->name, m) != 0)
+ continue;
+ ++matched_modules;
+ }
a->format = format;
r = format->options(a, o, v);
@@ -96,16 +98,13 @@ archive_set_format_option(struct archive *_a, const char *m, const char *o,
if (r == ARCHIVE_FATAL)
return (ARCHIVE_FATAL);
- if (m != NULL)
- return (r);
-
if (r == ARCHIVE_OK)
rv = ARCHIVE_OK;
}
/* If the format name didn't match, return a special code for
* _archive_set_option[s]. */
- if (rv == ARCHIVE_WARN && m != NULL)
- rv = ARCHIVE_WARN - 1;
+ if (m != NULL && matched_modules == 0)
+ return ARCHIVE_WARN - 1;
return (rv);
}
@@ -116,7 +115,7 @@ archive_set_filter_option(struct archive *_a, const char *m, const char *o,
struct archive_read *a = (struct archive_read *)_a;
struct archive_read_filter *filter;
struct archive_read_filter_bidder *bidder;
- int r, rv = ARCHIVE_WARN;
+ int r, rv = ARCHIVE_WARN, matched_modules = 0;
for (filter = a->filter; filter != NULL; filter = filter->upstream) {
bidder = filter->bidder;
@@ -125,24 +124,24 @@ archive_set_filter_option(struct archive *_a, const char *m, const char *o,
if (bidder->options == NULL)
/* This bidder does not support option */
continue;
- if (m != NULL && strcmp(filter->name, m) != 0)
- continue;
+ if (m != NULL) {
+ if (strcmp(filter->name, m) != 0)
+ continue;
+ ++matched_modules;
+ }
r = bidder->options(bidder, o, v);
if (r == ARCHIVE_FATAL)
return (ARCHIVE_FATAL);
- if (m != NULL)
- return (r);
-
if (r == ARCHIVE_OK)
rv = ARCHIVE_OK;
}
/* If the filter name didn't match, return a special code for
* _archive_set_option[s]. */
- if (rv == ARCHIVE_WARN && m != NULL)
- rv = ARCHIVE_WARN - 1;
+ if (m != NULL && matched_modules == 0)
+ return ARCHIVE_WARN - 1;
return (rv);
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_all.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_all.c
index b778cfb79..68c53de41 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_all.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_all.c
@@ -69,6 +69,8 @@ archive_read_support_filter_all(struct archive *a)
archive_read_support_filter_lzop(a);
/* The decode code always uses "grzip -d" command-line. */
archive_read_support_filter_grzip(a);
+ /* Lz4 falls back to "lz4 -d" command-line program. */
+ archive_read_support_filter_lz4(a);
/* Note: We always return ARCHIVE_OK here, even if some of the
* above return ARCHIVE_WARN. The intent here is to enable
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_compress.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_compress.c
index 3f5d1f37e..e05132dbf 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_compress.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_compress.c
@@ -185,19 +185,22 @@ compress_bidder_bid(struct archive_read_filter_bidder *self,
(void)self; /* UNUSED */
- buffer = __archive_read_filter_ahead(filter, 2, &avail);
+ /* Shortest valid compress file is 3 bytes. */
+ buffer = __archive_read_filter_ahead(filter, 3, &avail);
if (buffer == NULL)
return (0);
bits_checked = 0;
+ /* First two bytes are the magic value */
if (buffer[0] != 0x1F || buffer[1] != 0x9D)
return (0);
- bits_checked += 16;
-
- /*
- * TODO: Verify more.
- */
+ /* Third byte holds compression parameters. */
+ if (buffer[2] & 0x20) /* Reserved bit, must be zero. */
+ return (0);
+ if (buffer[2] & 0x40) /* Reserved bit, must be zero. */
+ return (0);
+ bits_checked += 18;
return (bits_checked);
}
@@ -239,7 +242,13 @@ compress_bidder_init(struct archive_read_filter *self)
(void)getbits(self, 8); /* Skip first signature byte. */
(void)getbits(self, 8); /* Skip second signature byte. */
+ /* Get compression parameters. */
code = getbits(self, 8);
+ if ((code & 0x1f) > 16) {
+ archive_set_error(&self->archive->archive, -1,
+ "Invalid compressed data");
+ return (ARCHIVE_FATAL);
+ }
state->maxcode_bits = code & 0x1f;
state->maxcode = (1 << state->maxcode_bits);
state->use_reset_code = code & 0x80;
@@ -368,7 +377,8 @@ next_code(struct archive_read_filter *self)
return (next_code(self));
}
- if (code > state->free_ent) {
+ if (code > state->free_ent
+ || (code == state->free_ent && state->oldcode < 0)) {
/* An invalid code is a fatal error. */
archive_set_error(&(self->archive->archive), -1,
"Invalid compressed data");
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c
new file mode 100644
index 000000000..db62cb355
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c
@@ -0,0 +1,728 @@
+/*-
+ * Copyright (c) 2014 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+
+__FBSDID("$FreeBSD$");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_LZ4_H
+#include <lz4.h>
+#endif
+
+#include "archive.h"
+#include "archive_endian.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+#include "archive_xxhash.h"
+
+#define LZ4_MAGICNUMBER 0x184d2204
+#define LZ4_SKIPPABLED 0x184d2a50
+#define LZ4_LEGACY 0x184c2102
+
+#if defined(HAVE_LIBLZ4)
+struct private_data {
+ enum { SELECT_STREAM,
+ READ_DEFAULT_STREAM,
+ READ_DEFAULT_BLOCK,
+ READ_LEGACY_STREAM,
+ READ_LEGACY_BLOCK,
+ } stage;
+ struct {
+ unsigned block_independence:1;
+ unsigned block_checksum:3;
+ unsigned stream_size:1;
+ unsigned stream_checksum:1;
+ unsigned preset_dictionary:1;
+ int block_maximum_size;
+ } flags;
+ int64_t stream_size;
+ uint32_t dict_id;
+ char *out_block;
+ size_t out_block_size;
+
+ /* Bytes read but not yet consumed via __archive_read_consume() */
+ size_t unconsumed;
+ size_t decoded_size;
+ void *xxh32_state;
+
+ char valid; /* True = decompressor is initialized */
+ char eof; /* True = found end of compressed data. */
+};
+
+#define LEGACY_BLOCK_SIZE (8 * 1024 * 1024)
+
+/* Lz4 filter */
+static ssize_t lz4_filter_read(struct archive_read_filter *, const void **);
+static int lz4_filter_close(struct archive_read_filter *);
+#endif
+
+/*
+ * Note that we can detect lz4 archives even if we can't decompress
+ * them. (In fact, we like detecting them because we can give better
+ * error messages.) So the bid framework here gets compiled even
+ * if liblz4 is unavailable.
+ */
+static int lz4_reader_bid(struct archive_read_filter_bidder *, struct archive_read_filter *);
+static int lz4_reader_init(struct archive_read_filter *);
+static int lz4_reader_free(struct archive_read_filter_bidder *);
+#if defined(HAVE_LIBLZ4)
+static ssize_t lz4_filter_read_default_stream(struct archive_read_filter *,
+ const void **);
+static ssize_t lz4_filter_read_legacy_stream(struct archive_read_filter *,
+ const void **);
+#endif
+
+int
+archive_read_support_filter_lz4(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct archive_read_filter_bidder *reader;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_filter_lz4");
+
+ if (__archive_read_get_bidder(a, &reader) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ reader->data = NULL;
+ reader->name = "lz4";
+ reader->bid = lz4_reader_bid;
+ reader->init = lz4_reader_init;
+ reader->options = NULL;
+ reader->free = lz4_reader_free;
+#if defined(HAVE_LIBLZ4)
+ return (ARCHIVE_OK);
+#else
+ archive_set_error(_a, ARCHIVE_ERRNO_MISC,
+ "Using external lz4 program");
+ return (ARCHIVE_WARN);
+#endif
+}
+
+static int
+lz4_reader_free(struct archive_read_filter_bidder *self){
+ (void)self; /* UNUSED */
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Test whether we can handle this data.
+ *
+ * This logic returns zero if any part of the signature fails. It
+ * also tries to Do The Right Thing if a very short buffer prevents us
+ * from verifying as much as we would like.
+ */
+static int
+lz4_reader_bid(struct archive_read_filter_bidder *self,
+ struct archive_read_filter *filter)
+{
+ const unsigned char *buffer;
+ ssize_t avail;
+ int bits_checked;
+ uint32_t number;
+
+ (void)self; /* UNUSED */
+
+ /* Minimal lz4 archive is 11 bytes. */
+ buffer = __archive_read_filter_ahead(filter, 11, &avail);
+ if (buffer == NULL)
+ return (0);
+
+ /* First four bytes must be LZ4 magic numbers. */
+ bits_checked = 0;
+ if ((number = archive_le32dec(buffer)) == LZ4_MAGICNUMBER) {
+ unsigned char flag, BD;
+
+ bits_checked += 32;
+ /* Next follows a stream descriptor. */
+ /* Descriptor Flags. */
+ flag = buffer[4];
+ /* A version number must be "01". */
+ if (((flag & 0xc0) >> 6) != 1)
+ return (0);
+ /* A reserved bit must be "0". */
+ if (flag & 2)
+ return (0);
+ bits_checked += 8;
+ BD = buffer[5];
+ /* A block maximum size shuld be more than 3. */
+ if (((BD & 0x70) >> 4) < 4)
+ return (0);
+ /* Reserved bits must be "0". */
+ if (BD & ~0x70)
+ return (0);
+ bits_checked += 8;
+ } else if (number == LZ4_LEGACY) {
+ bits_checked += 32;
+ }
+
+ return (bits_checked);
+}
+
+#if !defined(HAVE_LIBLZ4)
+
+/*
+ * If we don't have the library on this system, we can't actually do the
+ * decompression. We can, however, still detect compressed archives
+ * and emit a useful message.
+ */
+static int
+lz4_reader_init(struct archive_read_filter *self)
+{
+ int r;
+
+ r = __archive_read_program(self, "lz4 -d -q");
+ /* Note: We set the format here even if __archive_read_program()
+ * above fails. We do, after all, know what the format is
+ * even if we weren't able to read it. */
+ self->code = ARCHIVE_FILTER_LZ4;
+ self->name = "lz4";
+ return (r);
+}
+
+
+#else
+
+/*
+ * Setup the callbacks.
+ */
+static int
+lz4_reader_init(struct archive_read_filter *self)
+{
+ struct private_data *state;
+
+ self->code = ARCHIVE_FILTER_LZ4;
+ self->name = "lz4";
+
+ state = (struct private_data *)calloc(sizeof(*state), 1);
+ if (state == NULL) {
+ archive_set_error(&self->archive->archive, ENOMEM,
+ "Can't allocate data for lz4 decompression");
+ return (ARCHIVE_FATAL);
+ }
+
+ self->data = state;
+ state->stage = SELECT_STREAM;
+ self->read = lz4_filter_read;
+ self->skip = NULL; /* not supported */
+ self->close = lz4_filter_close;
+
+ return (ARCHIVE_OK);
+}
+
+static int
+lz4_allocate_out_block(struct archive_read_filter *self)
+{
+ struct private_data *state = (struct private_data *)self->data;
+ size_t out_block_size = state->flags.block_maximum_size;
+ void *out_block;
+
+ if (!state->flags.block_independence)
+ out_block_size += 64 * 1024;
+ if (state->out_block_size < out_block_size) {
+ free(state->out_block);
+ out_block = (unsigned char *)malloc(out_block_size);
+ state->out_block_size = out_block_size;
+ if (out_block == NULL) {
+ archive_set_error(&self->archive->archive, ENOMEM,
+ "Can't allocate data for lz4 decompression");
+ return (ARCHIVE_FATAL);
+ }
+ state->out_block = out_block;
+ }
+ if (!state->flags.block_independence)
+ memset(state->out_block, 0, 64 * 1024);
+ return (ARCHIVE_OK);
+}
+
+static int
+lz4_allocate_out_block_for_legacy(struct archive_read_filter *self)
+{
+ struct private_data *state = (struct private_data *)self->data;
+ size_t out_block_size = LEGACY_BLOCK_SIZE;
+ void *out_block;
+
+ if (state->out_block_size < out_block_size) {
+ free(state->out_block);
+ out_block = (unsigned char *)malloc(out_block_size);
+ state->out_block_size = out_block_size;
+ if (out_block == NULL) {
+ archive_set_error(&self->archive->archive, ENOMEM,
+ "Can't allocate data for lz4 decompression");
+ return (ARCHIVE_FATAL);
+ }
+ state->out_block = out_block;
+ }
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Return the next block of decompressed data.
+ */
+static ssize_t
+lz4_filter_read(struct archive_read_filter *self, const void **p)
+{
+ struct private_data *state = (struct private_data *)self->data;
+ ssize_t ret;
+
+ if (state->eof) {
+ *p = NULL;
+ return (0);
+ }
+
+ __archive_read_filter_consume(self->upstream, state->unconsumed);
+ state->unconsumed = 0;
+
+ switch (state->stage) {
+ case SELECT_STREAM:
+ break;
+ case READ_DEFAULT_STREAM:
+ case READ_LEGACY_STREAM:
+ /* Reading a lz4 stream already failed. */
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC, "Invalid sequence.");
+ return (ARCHIVE_FATAL);
+ case READ_DEFAULT_BLOCK:
+ ret = lz4_filter_read_default_stream(self, p);
+ if (ret != 0 || state->stage != SELECT_STREAM)
+ return ret;
+ break;
+ case READ_LEGACY_BLOCK:
+ ret = lz4_filter_read_legacy_stream(self, p);
+ if (ret != 0 || state->stage != SELECT_STREAM)
+ return ret;
+ break;
+ default:
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC, "Program error.");
+ return (ARCHIVE_FATAL);
+ break;
+ }
+
+ while (state->stage == SELECT_STREAM) {
+ const char *read_buf;
+
+ /* Read a magic number. */
+ read_buf = __archive_read_filter_ahead(self->upstream, 4,
+ NULL);
+ if (read_buf == NULL) {
+ state->eof = 1;
+ *p = NULL;
+ return (0);
+ }
+ uint32_t number = archive_le32dec(read_buf);
+ __archive_read_filter_consume(self->upstream, 4);
+ if (number == LZ4_MAGICNUMBER)
+ return lz4_filter_read_default_stream(self, p);
+ else if (number == LZ4_LEGACY)
+ return lz4_filter_read_legacy_stream(self, p);
+ else if ((number & ~0xF) == LZ4_SKIPPABLED) {
+ read_buf = __archive_read_filter_ahead(
+ self->upstream, 4, NULL);
+ if (read_buf == NULL) {
+ archive_set_error(
+ &self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Malformed lz4 data");
+ return (ARCHIVE_FATAL);
+ }
+ uint32_t skip_bytes = archive_le32dec(read_buf);
+ __archive_read_filter_consume(self->upstream,
+ 4 + skip_bytes);
+ } else {
+ /* Ignore following unrecognized data. */
+ state->eof = 1;
+ *p = NULL;
+ return (0);
+ }
+ }
+ state->eof = 1;
+ *p = NULL;
+ return (0);
+}
+
+static int
+lz4_filter_read_descriptor(struct archive_read_filter *self)
+{
+ struct private_data *state = (struct private_data *)self->data;
+ const char *read_buf;
+ ssize_t bytes_remaining;
+ ssize_t descriptor_bytes;
+ unsigned char flag, bd;
+ unsigned int chsum, chsum_verifier;
+
+ /* Make sure we have 2 bytes for flags. */
+ read_buf = __archive_read_filter_ahead(self->upstream, 2,
+ &bytes_remaining);
+ if (read_buf == NULL) {
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "truncated lz4 input");
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ Parse flags.
+ */
+ flag = (unsigned char)read_buf[0];
+ /* Verify version number. */
+ if ((flag & 0xc0) != 1<<6)
+ goto malformed_error;
+ /* A reserved bit must be zero. */
+ if (flag & 0x02)
+ goto malformed_error;
+ state->flags.block_independence = (flag & 0x20) != 0;
+ state->flags.block_checksum = (flag & 0x10)?4:0;
+ state->flags.stream_size = (flag & 0x08) != 0;
+ state->flags.stream_checksum = (flag & 0x04) != 0;
+ state->flags.preset_dictionary = (flag & 0x01) != 0;
+
+ /* BD */
+ bd = (unsigned char)read_buf[1];
+ /* Reserved bits must be zero. */
+ if (bd & 0x8f)
+ goto malformed_error;
+ /* Get a maxinum block size. */
+ switch (read_buf[1] >> 4) {
+ case 4: /* 64 KB */
+ state->flags.block_maximum_size = 64 * 1024;
+ break;
+ case 5: /* 256 KB */
+ state->flags.block_maximum_size = 256 * 1024;
+ break;
+ case 6: /* 1 MB */
+ state->flags.block_maximum_size = 1024 * 1024;
+ break;
+ case 7: /* 4 MB */
+ state->flags.block_maximum_size = 4 * 1024 * 1024;
+ break;
+ default:
+ goto malformed_error;
+ }
+
+ /* Read the whole descriptor in a stream block. */
+ descriptor_bytes = 3;
+ if (state->flags.stream_size)
+ descriptor_bytes += 8;
+ if (state->flags.preset_dictionary)
+ descriptor_bytes += 4;
+ if (bytes_remaining < descriptor_bytes) {
+ read_buf = __archive_read_filter_ahead(self->upstream,
+ descriptor_bytes, &bytes_remaining);
+ if (read_buf == NULL) {
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "truncated lz4 input");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ /* Check if a descriptor is corrupted */
+ chsum = __archive_xxhash.XXH32(read_buf, (int)descriptor_bytes -1, 0);
+ chsum = (chsum >> 8) & 0xff;
+ chsum_verifier = read_buf[descriptor_bytes-1] & 0xff;
+ if (chsum != chsum_verifier)
+ goto malformed_error;
+
+ __archive_read_filter_consume(self->upstream, descriptor_bytes);
+
+ /* Make sure we have an enough buffer for uncompressed data. */
+ if (lz4_allocate_out_block(self) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ if (state->flags.stream_checksum)
+ state->xxh32_state = __archive_xxhash.XXH32_init(0);
+
+ state->decoded_size = 0;
+ /* Success */
+ return (ARCHIVE_OK);
+malformed_error:
+ archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
+ "malformed lz4 data");
+ return (ARCHIVE_FATAL);
+}
+
+static ssize_t
+lz4_filter_read_data_block(struct archive_read_filter *self, const void **p)
+{
+ struct private_data *state = (struct private_data *)self->data;
+ ssize_t compressed_size;
+ const char *read_buf;
+ ssize_t bytes_remaining;
+ int checksum_size;
+ ssize_t uncompressed_size;
+ size_t prefix64k;
+
+ *p = NULL;
+
+ /* Make sure we have 4 bytes for a block size. */
+ read_buf = __archive_read_filter_ahead(self->upstream, 4,
+ &bytes_remaining);
+ if (read_buf == NULL)
+ goto truncated_error;
+ compressed_size = archive_le32dec(read_buf);
+ if ((compressed_size & ~(1 << 31)) > state->flags.block_maximum_size)
+ goto malformed_error;
+ /* A compressed size == 0 means the end of stream blocks. */
+ if (compressed_size == 0) {
+ __archive_read_filter_consume(self->upstream, 4);
+ return 0;
+ }
+
+ checksum_size = state->flags.block_checksum;
+ /* Check if the block is uncompressed. */
+ if (compressed_size & (1 << 31)) {
+ compressed_size &= ~(1 << 31);
+ uncompressed_size = compressed_size;
+ } else
+ uncompressed_size = 0;/* Unknown yet. */
+
+ /*
+ Unfortunately, lz4 decompression API requires a whole block
+ for its decompression speed, so we read a whole block and allocate
+ a huge buffer used for decoded data.
+ */
+ read_buf = __archive_read_filter_ahead(self->upstream,
+ 4 + compressed_size + checksum_size, &bytes_remaining);
+ if (read_buf == NULL)
+ goto truncated_error;
+
+ /* Optional process, checking a block sum. */
+ if (checksum_size) {
+ unsigned int chsum = __archive_xxhash.XXH32(
+ read_buf + 4, (int)compressed_size, 0);
+ unsigned int chsum_block =
+ archive_le32dec(read_buf + 4 + compressed_size);
+ if (chsum != chsum_block)
+ goto malformed_error;
+ }
+
+
+ /* If the block is uncompressed, there is nothing to do. */
+ if (uncompressed_size) {
+ /* Prepare a prefix 64k block for next block. */
+ if (!state->flags.block_independence) {
+ prefix64k = 64 * 1024;
+ if (uncompressed_size < (ssize_t)prefix64k) {
+ memcpy(state->out_block
+ + prefix64k - uncompressed_size,
+ read_buf + 4,
+ uncompressed_size);
+ memset(state->out_block, 0,
+ prefix64k - uncompressed_size);
+ } else {
+ memcpy(state->out_block,
+ read_buf + 4
+ + uncompressed_size - prefix64k,
+ prefix64k);
+ }
+ state->decoded_size = 0;
+ }
+ state->unconsumed = 4 + uncompressed_size + checksum_size;
+ *p = read_buf + 4;
+ return uncompressed_size;
+ }
+
+ /*
+ Decompress a block data.
+ */
+ if (state->flags.block_independence) {
+ prefix64k = 0;
+ uncompressed_size = LZ4_decompress_safe(read_buf + 4,
+ state->out_block, (int)compressed_size,
+ state->flags.block_maximum_size);
+ } else {
+ prefix64k = 64 * 1024;
+ if (state->decoded_size) {
+ if (state->decoded_size < prefix64k) {
+ memmove(state->out_block
+ + prefix64k - state->decoded_size,
+ state->out_block + prefix64k,
+ state->decoded_size);
+ memset(state->out_block, 0,
+ prefix64k - state->decoded_size);
+ } else {
+ memmove(state->out_block,
+ state->out_block + state->decoded_size,
+ prefix64k);
+ }
+ }
+ uncompressed_size = LZ4_decompress_safe_withPrefix64k(
+ read_buf + 4,
+ state->out_block + prefix64k, (int)compressed_size,
+ state->flags.block_maximum_size);
+ }
+
+ /* Check if an error happend in decompression process. */
+ if (uncompressed_size < 0) {
+ archive_set_error(&(self->archive->archive),
+ ARCHIVE_ERRNO_MISC, "lz4 decompression failed");
+ return (ARCHIVE_FATAL);
+ }
+
+ state->unconsumed = 4 + compressed_size + checksum_size;
+ *p = state->out_block + prefix64k;
+ state->decoded_size = uncompressed_size;
+ return uncompressed_size;
+
+malformed_error:
+ archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
+ "malformed lz4 data");
+ return (ARCHIVE_FATAL);
+truncated_error:
+ archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
+ "truncated lz4 input");
+ return (ARCHIVE_FATAL);
+}
+
+static ssize_t
+lz4_filter_read_default_stream(struct archive_read_filter *self, const void **p)
+{
+ struct private_data *state = (struct private_data *)self->data;
+ const char *read_buf;
+ ssize_t bytes_remaining;
+ ssize_t ret;
+
+ if (state->stage == SELECT_STREAM) {
+ state->stage = READ_DEFAULT_STREAM;
+ /* First, read a desciprtor. */
+ if((ret = lz4_filter_read_descriptor(self)) != ARCHIVE_OK)
+ return (ret);
+ state->stage = READ_DEFAULT_BLOCK;
+ }
+ /* Decompress a block. */
+ ret = lz4_filter_read_data_block(self, p);
+
+ /* If the end of block is detected, change the filter status
+ to read next stream. */
+ if (ret == 0 && *p == NULL)
+ state->stage = SELECT_STREAM;
+
+ /* Optional process, checking a stream sum. */
+ if (state->flags.stream_checksum) {
+ if (state->stage == SELECT_STREAM) {
+ unsigned int checksum;
+ unsigned int checksum_stream;
+ read_buf = __archive_read_filter_ahead(self->upstream,
+ 4, &bytes_remaining);
+ if (read_buf == NULL) {
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC, "truncated lz4 input");
+ return (ARCHIVE_FATAL);
+ }
+ checksum = archive_le32dec(read_buf);
+ __archive_read_filter_consume(self->upstream, 4);
+ checksum_stream = __archive_xxhash.XXH32_digest(
+ state->xxh32_state);
+ state->xxh32_state = NULL;
+ if (checksum != checksum_stream) {
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "lz4 stream cheksum error");
+ return (ARCHIVE_FATAL);
+ }
+ } else if (ret > 0)
+ __archive_xxhash.XXH32_update(state->xxh32_state,
+ *p, (int)ret);
+ }
+ return (ret);
+}
+
+static ssize_t
+lz4_filter_read_legacy_stream(struct archive_read_filter *self, const void **p)
+{
+ struct private_data *state = (struct private_data *)self->data;
+ int compressed;
+ const char *read_buf;
+ ssize_t ret;
+
+ *p = NULL;
+ ret = lz4_allocate_out_block_for_legacy(self);
+ if (ret != ARCHIVE_OK)
+ return ret;
+
+ /* Make sure we have 4 bytes for a block size. */
+ read_buf = __archive_read_filter_ahead(self->upstream, 4, NULL);
+ if (read_buf == NULL) {
+ if (state->stage == SELECT_STREAM) {
+ state->stage = READ_LEGACY_STREAM;
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "truncated lz4 input");
+ return (ARCHIVE_FATAL);
+ }
+ state->stage = SELECT_STREAM;
+ return 0;
+ }
+ state->stage = READ_LEGACY_BLOCK;
+ compressed = archive_le32dec(read_buf);
+ if (compressed > LZ4_COMPRESSBOUND(LEGACY_BLOCK_SIZE)) {
+ state->stage = SELECT_STREAM;
+ return 0;
+ }
+
+ /* Make sure we have a whole block. */
+ read_buf = __archive_read_filter_ahead(self->upstream,
+ 4 + compressed, NULL);
+ ret = LZ4_decompress_safe(read_buf + 4, state->out_block,
+ compressed, (int)state->out_block_size);
+ if (ret < 0) {
+ archive_set_error(&(self->archive->archive),
+ ARCHIVE_ERRNO_MISC, "lz4 decompression failed");
+ return (ARCHIVE_FATAL);
+ }
+ *p = state->out_block;
+ state->unconsumed = 4 + compressed;
+ return ret;
+}
+
+/*
+ * Clean up the decompressor.
+ */
+static int
+lz4_filter_close(struct archive_read_filter *self)
+{
+ struct private_data *state;
+ int ret = ARCHIVE_OK;
+
+ state = (struct private_data *)self->data;
+ free(state->xxh32_state);
+ free(state->out_block);
+ free(state);
+ return (ret);
+}
+
+#endif /* HAVE_LIBLZ4 */
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c
index 7958fa50a..23c18c7fb 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c
@@ -242,10 +242,18 @@ consume_header(struct archive_read_filter *self)
if (version >= 0x940) {
unsigned level = *p++;
- if (method == 1 && level == 0) level = 3;
- if (method == 2 && level == 0) level = 1;
- if (method == 3 && level == 0) level = 9;
- if (level < 1 && level > 9) {
+#if 0
+ unsigned default_level[] = {0, 3, 1, 9};
+#endif
+ if (level == 0)
+ /* Method is 1..3 here due to check above. */
+#if 0 /* Avoid an error Clang Static Analyzer claims
+ "Value stored to 'level' is never read". */
+ level = default_level[method];
+#else
+ ;/* NOP */
+#endif
+ else if (level > 9) {
archive_set_error(&self->archive->archive,
ARCHIVE_ERRNO_MISC, "Invalid level");
return (ARCHIVE_FAILED);
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_uu.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_uu.c
index 471771b6f..787a619f2 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_uu.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_uu.c
@@ -509,7 +509,7 @@ read_more:
return (ARCHIVE_FATAL);
}
llen = len;
- if (nl == 0) {
+ if ((nl == 0) && (uudecode->state != ST_UUEND)) {
/*
* Save remaining data which does not contain
* NL('\n','\r').
@@ -527,6 +527,7 @@ read_more:
self->upstream, ravail);
goto read_more;
}
+ used += len;
break;
}
switch (uudecode->state) {
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c
index 15824b1d0..8f48273ed 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c
@@ -42,7 +42,7 @@ __FBSDID("$FreeBSD$");
#include <unistd.h>
#endif
#if HAVE_LZMA_H
-#include <lzma.h>
+#include <cm_lzma.h>
#elif HAVE_LZMADEC_H
#include <lzmadec.h>
#endif
@@ -601,7 +601,7 @@ lzip_init(struct archive_read_filter *self)
return (ARCHIVE_FATAL);
}
ret = lzma_raw_decoder(&(state->stream), filters);
-#if LZMA_VERSION < 50000030
+#if LZMA_VERSION < 50010000
free(filters[0].options);
#endif
if (ret != LZMA_OK) {
@@ -627,7 +627,7 @@ lzip_tail(struct archive_read_filter *self)
f = __archive_read_filter_ahead(self->upstream, tail, &avail_in);
if (f == NULL && avail_in < 0)
return (ARCHIVE_FATAL);
- if (avail_in < tail) {
+ if (f == NULL || avail_in < tail) {
archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
"Lzip: Remaining data is less bytes");
return (ARCHIVE_FAILED);
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
index 54ea24590..f045b8fe7 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
@@ -36,7 +36,7 @@ __FBSDID("$FreeBSD$");
#include <cm_bzlib.h>
#endif
#ifdef HAVE_LZMA_H
-#include <lzma.h>
+#include <cm_lzma.h>
#endif
#ifdef HAVE_ZLIB_H
#include <cm_zlib.h>
@@ -69,7 +69,11 @@ __FBSDID("$FreeBSD$");
#define _7Z_BZ2 0x040202
#define _7Z_PPMD 0x030401
#define _7Z_DELTA 0x03
-#define _7Z_CRYPTO 0x06F10701
+#define _7Z_CRYPTO_MAIN_ZIP 0x06F10101 /* Main Zip crypto algo */
+#define _7Z_CRYPTO_RAR_29 0x06F10303 /* Rar29 AES-128 + (modified SHA-1) */
+#define _7Z_CRYPTO_AES_256_SHA_256 0x06F10701 /* AES-256 + SHA-256 */
+
+
#define _7Z_X86 0x03030103
#define _7Z_X86_BCJ2 0x0303011B
#define _7Z_POWERPC 0x03030205
@@ -104,6 +108,7 @@ __FBSDID("$FreeBSD$");
#define kMTime 0x14
#define kAttributes 0x15
#define kEncodedHeader 0x17
+#define kDummy 0x19
struct _7z_digests {
unsigned char *defineds;
@@ -322,8 +327,18 @@ struct _7zip {
struct archive_string_conv *sconv;
char format_name[64];
+
+ /* Custom value that is non-zero if this archive contains encrypted entries. */
+ int has_encrypted_entries;
};
+/* Maximum entry size. This limitation prevents reading intentional
+ * corrupted 7-zip files on assuming there are not so many entries in
+ * the files. */
+#define UMAX_ENTRY ARCHIVE_LITERAL_ULL(100000000)
+
+static int archive_read_format_7zip_has_encrypted_entries(struct archive_read *);
+static int archive_read_support_format_7zip_capabilities(struct archive_read *a);
static int archive_read_format_7zip_bid(struct archive_read *, int);
static int archive_read_format_7zip_cleanup(struct archive_read *);
static int archive_read_format_7zip_read_data(struct archive_read *,
@@ -401,6 +416,13 @@ archive_read_support_format_7zip(struct archive *_a)
return (ARCHIVE_FATAL);
}
+ /*
+ * Until enough data has been read, we cannot tell about
+ * any encrypted entries yet.
+ */
+ zip->has_encrypted_entries = ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
+
+
r = __archive_read_register_format(a,
zip,
"7zip",
@@ -410,7 +432,9 @@ archive_read_support_format_7zip(struct archive *_a)
archive_read_format_7zip_read_data,
archive_read_format_7zip_read_data_skip,
NULL,
- archive_read_format_7zip_cleanup);
+ archive_read_format_7zip_cleanup,
+ archive_read_support_format_7zip_capabilities,
+ archive_read_format_7zip_has_encrypted_entries);
if (r != ARCHIVE_OK)
free(zip);
@@ -418,6 +442,27 @@ archive_read_support_format_7zip(struct archive *_a)
}
static int
+archive_read_support_format_7zip_capabilities(struct archive_read * a)
+{
+ (void)a; /* UNUSED */
+ return (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA |
+ ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA);
+}
+
+
+static int
+archive_read_format_7zip_has_encrypted_entries(struct archive_read *_a)
+{
+ if (_a && _a->format) {
+ struct _7zip * zip = (struct _7zip *)_a->format->data;
+ if (zip) {
+ return zip->has_encrypted_entries;
+ }
+ }
+ return ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
+}
+
+static int
archive_read_format_7zip_bid(struct archive_read *a, int best_bid)
{
const char *p;
@@ -476,7 +521,7 @@ check_7zip_header_in_sfx(const char *p)
switch ((unsigned char)p[5]) {
case 0x1C:
if (memcmp(p, _7ZIP_SIGNATURE, 6) != 0)
- return (6);
+ return (6);
/*
* Test the CRC because its extraction code has 7-Zip
* Magic Code, so we should do this in order not to
@@ -484,15 +529,15 @@ check_7zip_header_in_sfx(const char *p)
*/
if (crc32(0, (const unsigned char *)p + 12, 20)
!= archive_le32dec(p + 8))
- return (6);
+ return (6);
/* Hit the header! */
return (0);
- case 0x37: return (5);
- case 0x7A: return (4);
- case 0xBC: return (3);
- case 0xAF: return (2);
- case 0x27: return (1);
- default: return (6);
+ case 0x37: return (5);
+ case 0x7A: return (4);
+ case 0xBC: return (3);
+ case 0xAF: return (2);
+ case 0x27: return (1);
+ default: return (6);
}
}
@@ -568,6 +613,19 @@ archive_read_format_7zip_read_header(struct archive_read *a,
struct _7zip *zip = (struct _7zip *)a->format->data;
struct _7zip_entry *zip_entry;
int r, ret = ARCHIVE_OK;
+ struct _7z_folder *folder = 0;
+ uint64_t fidx = 0;
+
+ /*
+ * It should be sufficient to call archive_read_next_header() for
+ * a reader to determine if an entry is encrypted or not. If the
+ * encryption of an entry is only detectable when calling
+ * archive_read_data(), so be it. We'll do the same check there
+ * as well.
+ */
+ if (zip->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
+ zip->has_encrypted_entries = 0;
+ }
a->archive.archive_format = ARCHIVE_FORMAT_7ZIP;
if (a->archive.archive_format_name == NULL)
@@ -588,7 +646,7 @@ archive_read_format_7zip_read_header(struct archive_read *a,
}
zip_entry = zip->entry;
- if (zip->entries_remaining <= 0)
+ if (zip->entries_remaining <= 0 || zip_entry == NULL)
return ARCHIVE_EOF;
--zip->entries_remaining;
@@ -604,6 +662,32 @@ archive_read_format_7zip_read_header(struct archive_read *a,
return (ARCHIVE_FATAL);
}
+ /* Figure out if the entry is encrypted by looking at the folder
+ that is associated to the current 7zip entry. If the folder
+ has a coder with a _7Z_CRYPTO codec then the folder is encrypted.
+ Hence the entry must also be encrypted. */
+ if (zip_entry && zip_entry->folderIndex < zip->si.ci.numFolders) {
+ folder = &(zip->si.ci.folders[zip_entry->folderIndex]);
+ for (fidx=0; folder && fidx<folder->numCoders; fidx++) {
+ switch(folder->coders[fidx].codec) {
+ case _7Z_CRYPTO_MAIN_ZIP:
+ case _7Z_CRYPTO_RAR_29:
+ case _7Z_CRYPTO_AES_256_SHA_256: {
+ archive_entry_set_is_data_encrypted(entry, 1);
+ zip->has_encrypted_entries = 1;
+ break;
+ }
+ }
+ }
+ }
+
+ /* Now that we've checked for encryption, if there were still no
+ * encrypted entries found we can say for sure that there are none.
+ */
+ if (zip->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
+ zip->has_encrypted_entries = 0;
+ }
+
if (archive_entry_copy_pathname_l(entry,
(const char *)zip_entry->utf16name,
zip_entry->name_len, zip->sconv) != 0) {
@@ -707,6 +791,10 @@ archive_read_format_7zip_read_data(struct archive_read *a,
zip = (struct _7zip *)(a->format->data);
+ if (zip->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
+ zip->has_encrypted_entries = 0;
+ }
+
if (zip->pack_stream_bytes_unconsumed)
read_consume(a);
@@ -969,7 +1057,7 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
{
lzma_options_delta delta_opt;
lzma_filter filters[LZMA_FILTERS_MAX];
-#if LZMA_VERSION < 50000030
+#if LZMA_VERSION < 50010000
lzma_filter *ff;
#endif
int fi = 0;
@@ -994,7 +1082,7 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
* for BCJ+LZMA. If we were able to tell the uncompressed
* size to liblzma when using lzma_raw_decoder() liblzma
* could correctly deal with BCJ+LZMA. But unfortunately
- * there is no way to do that.
+ * there is no way to do that.
* Discussion about this can be found at XZ Utils forum.
*/
if (coder2 != NULL) {
@@ -1056,7 +1144,7 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
else
filters[fi].id = LZMA_FILTER_LZMA1;
filters[fi].options = NULL;
-#if LZMA_VERSION < 50000030
+#if LZMA_VERSION < 50010000
ff = &filters[fi];
#endif
r = lzma_properties_decode(&filters[fi], NULL,
@@ -1070,7 +1158,7 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
filters[fi].id = LZMA_VLI_UNKNOWN;
filters[fi].options = NULL;
r = lzma_raw_decoder(&(zip->lzstream), filters);
-#if LZMA_VERSION < 50000030
+#if LZMA_VERSION < 50010000
free(ff->options);
#endif
if (r != LZMA_OK) {
@@ -1203,6 +1291,17 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Unexpected codec ID: %lX", zip->codec);
return (ARCHIVE_FAILED);
+ case _7Z_CRYPTO_MAIN_ZIP:
+ case _7Z_CRYPTO_RAR_29:
+ case _7Z_CRYPTO_AES_256_SHA_256:
+ if (a->entry) {
+ archive_entry_set_is_metadata_encrypted(a->entry, 1);
+ archive_entry_set_is_data_encrypted(a->entry, 1);
+ zip->has_encrypted_entries = 1;
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Crypto codec not supported yet (ID: 0x%lX)", zip->codec);
+ return (ARCHIVE_FAILED);
default:
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Unknown codec ID: %lX", zip->codec);
@@ -1426,7 +1525,7 @@ decompress(struct archive_read *a, struct _7zip *zip,
do {
int sym;
-
+
sym = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
&(zip->ppmd7_context), &(zip->range_dec.p));
if (sym < 0) {
@@ -1570,7 +1669,7 @@ parse_7zip_uint64(struct archive_read *a, uint64_t *val)
mask >>= 1;
continue;
}
- *val += (avail & (mask -1)) << (8 * i);
+ *val += ((uint64_t)(avail & (mask -1))) << (8 * i);
break;
}
return (0);
@@ -1670,7 +1769,7 @@ read_PackInfo(struct archive_read *a, struct _7z_pack_info *pi)
return (-1);
if (pi->numPackStreams == 0)
return (-1);
- if (1000000 < pi->numPackStreams)
+ if (UMAX_ENTRY < pi->numPackStreams)
return (-1);
/*
@@ -1799,12 +1898,12 @@ read_Folder(struct archive_read *a, struct _7z_folder *f)
if (parse_7zip_uint64(
a, &(f->coders[i].numInStreams)) < 0)
return (-1);
- if (1000000 < f->coders[i].numInStreams)
+ if (UMAX_ENTRY < f->coders[i].numInStreams)
return (-1);
if (parse_7zip_uint64(
a, &(f->coders[i].numOutStreams)) < 0)
return (-1);
- if (1000000 < f->coders[i].numOutStreams)
+ if (UMAX_ENTRY < f->coders[i].numOutStreams)
return (-1);
}
@@ -1844,11 +1943,11 @@ read_Folder(struct archive_read *a, struct _7z_folder *f)
for (i = 0; i < f->numBindPairs; i++) {
if (parse_7zip_uint64(a, &(f->bindPairs[i].inIndex)) < 0)
return (-1);
- if (1000000 < f->bindPairs[i].inIndex)
+ if (UMAX_ENTRY < f->bindPairs[i].inIndex)
return (-1);
if (parse_7zip_uint64(a, &(f->bindPairs[i].outIndex)) < 0)
return (-1);
- if (1000000 < f->bindPairs[i].outIndex)
+ if (UMAX_ENTRY < f->bindPairs[i].outIndex)
return (-1);
}
@@ -1874,7 +1973,7 @@ read_Folder(struct archive_read *a, struct _7z_folder *f)
for (i = 0; i < f->numPackedStreams; i++) {
if (parse_7zip_uint64(a, &(f->packedStreams[i])) < 0)
return (-1);
- if (1000000 < f->packedStreams[i])
+ if (UMAX_ENTRY < f->packedStreams[i])
return (-1);
}
}
@@ -1916,8 +2015,8 @@ read_CodersInfo(struct archive_read *a, struct _7z_coders_info *ci)
*/
if (parse_7zip_uint64(a, &(ci->numFolders)) < 0)
goto failed;
- if (1000000 < ci->numFolders)
- return (-1);
+ if (UMAX_ENTRY < ci->numFolders)
+ return (-1);
/*
* Read External.
@@ -1938,9 +2037,18 @@ read_CodersInfo(struct archive_read *a, struct _7z_coders_info *ci)
case 1:
if (parse_7zip_uint64(a, &(ci->dataStreamIndex)) < 0)
return (-1);
- if (1000000 < ci->dataStreamIndex)
+ if (UMAX_ENTRY < ci->dataStreamIndex)
return (-1);
+ if (ci->numFolders > 0) {
+ archive_set_error(&a->archive, -1,
+ "Malformed 7-Zip archive");
+ goto failed;
+ }
break;
+ default:
+ archive_set_error(&a->archive, -1,
+ "Malformed 7-Zip archive");
+ goto failed;
}
if ((p = header_bytes(a, 1)) == NULL)
@@ -2043,7 +2151,7 @@ read_SubStreamsInfo(struct archive_read *a, struct _7z_substream_info *ss,
for (i = 0; i < numFolders; i++) {
if (parse_7zip_uint64(a, &(f[i].numUnpackStreams)) < 0)
return (-1);
- if (1000000 < f[i].numUnpackStreams)
+ if (UMAX_ENTRY < f[i].numUnpackStreams)
return (-1);
unpack_streams += (size_t)f[i].numUnpackStreams;
}
@@ -2292,8 +2400,8 @@ read_Header(struct archive_read *a, struct _7z_header_info *h,
if (parse_7zip_uint64(a, &(zip->numFiles)) < 0)
return (-1);
- if (1000000 < zip->numFiles)
- return (-1);
+ if (UMAX_ENTRY < zip->numFiles)
+ return (-1);
zip->entries = calloc((size_t)zip->numFiles, sizeof(*zip->entries));
if (zip->entries == NULL)
@@ -2452,6 +2560,9 @@ read_Header(struct archive_read *a, struct _7z_header_info *h,
}
break;
}
+ case kDummy:
+ if (ll == 0)
+ break;
default:
if (header_bytes(a, ll) == NULL)
return (-1);
@@ -2591,7 +2702,7 @@ read_Times(struct archive_read *a, struct _7z_header_info *h, int type)
if (*p) {
if (parse_7zip_uint64(a, &(h->dataIndex)) < 0)
goto failed;
- if (1000000 < h->dataIndex)
+ if (UMAX_ENTRY < h->dataIndex)
goto failed;
}
@@ -2755,6 +2866,7 @@ slurp_central_directory(struct archive_read *a, struct _7zip *zip,
zip->header_crc32 = 0;
zip->header_is_encoded = 0;
zip->header_is_being_read = 1;
+ zip->has_encrypted_entries = 0;
check_header_crc = 1;
if ((p = header_bytes(a, 1)) == NULL) {
@@ -3170,7 +3282,7 @@ read_stream(struct archive_read *a, const void **buff, size_t size,
return (r);
/*
- * Skip the bytes we alrady has skipped in skip_stream().
+ * Skip the bytes we alrady has skipped in skip_stream().
*/
while (skip_bytes) {
ssize_t skipped;
@@ -3235,16 +3347,36 @@ setup_decode_folder(struct archive_read *a, struct _7z_folder *folder,
* Check coder types.
*/
for (i = 0; i < folder->numCoders; i++) {
- if (folder->coders[i].codec == _7Z_CRYPTO) {
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC,
- "The %s is encrypted, "
- "but currently not supported", cname);
- return (ARCHIVE_FATAL);
+ switch(folder->coders[i].codec) {
+ case _7Z_CRYPTO_MAIN_ZIP:
+ case _7Z_CRYPTO_RAR_29:
+ case _7Z_CRYPTO_AES_256_SHA_256: {
+ /* For entry that is associated with this folder, mark
+ it as encrypted (data+metadata). */
+ zip->has_encrypted_entries = 1;
+ if (a->entry) {
+ archive_entry_set_is_data_encrypted(a->entry, 1);
+ archive_entry_set_is_metadata_encrypted(a->entry, 1);
+ }
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "The %s is encrypted, "
+ "but currently not supported", cname);
+ return (ARCHIVE_FATAL);
+ }
+ case _7Z_X86_BCJ2: {
+ found_bcj2++;
+ break;
+ }
}
- if (folder->coders[i].codec == _7Z_X86_BCJ2)
- found_bcj2++;
}
+ /* Now that we've checked for encryption, if there were still no
+ * encrypted entries found we can say for sure that there are none.
+ */
+ if (zip->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
+ zip->has_encrypted_entries = 0;
+ }
+
if ((folder->numCoders > 2 && !found_bcj2) || found_bcj2 > 1) {
archive_set_error(&(a->archive),
ARCHIVE_ERRNO_MISC,
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_all.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_all.c
index 53fe6fa39..2127ebd33 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_all.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_all.c
@@ -61,6 +61,7 @@ archive_read_support_format_all(struct archive *a)
archive_read_support_format_mtree(a);
archive_read_support_format_tar(a);
archive_read_support_format_xar(a);
+ archive_read_support_format_warc(a);
/*
* Install expensive bidders last. By doing them last, we
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_ar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_ar.c
index 40be18c0c..4b5b66bd5 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_ar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_ar.c
@@ -122,7 +122,9 @@ archive_read_support_format_ar(struct archive *_a)
archive_read_format_ar_read_data,
archive_read_format_ar_skip,
NULL,
- archive_read_format_ar_cleanup);
+ archive_read_format_ar_cleanup,
+ NULL,
+ NULL);
if (r != ARCHIVE_OK) {
free(ar);
@@ -178,7 +180,7 @@ _ar_read_header(struct archive_read *a, struct archive_entry *entry,
if (strncmp(h + AR_fmag_offset, "`\n", 2) != 0) {
archive_set_error(&a->archive, EINVAL,
"Incorrect file header signature");
- return (ARCHIVE_WARN);
+ return (ARCHIVE_FATAL);
}
/* Copy filename into work buffer. */
@@ -237,8 +239,15 @@ _ar_read_header(struct archive_read *a, struct archive_entry *entry,
* and are not terminated in '/', so we don't trim anything
* that starts with '/'.)
*/
- if (filename[0] != '/' && *p == '/')
+ if (filename[0] != '/' && p > filename && *p == '/') {
*p = '\0';
+ }
+
+ if (p < filename) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Found entry with empty filename");
+ return (ARCHIVE_FATAL);
+ }
/*
* '//' is the GNU filename table.
@@ -260,12 +269,12 @@ _ar_read_header(struct archive_read *a, struct archive_entry *entry,
if (entry_size == 0) {
archive_set_error(&a->archive, EINVAL,
"Invalid string table");
- return (ARCHIVE_WARN);
+ return (ARCHIVE_FATAL);
}
if (ar->strtab != NULL) {
archive_set_error(&a->archive, EINVAL,
"More than one string tables exist");
- return (ARCHIVE_WARN);
+ return (ARCHIVE_FATAL);
}
/* Read the filename table into memory. */
@@ -309,11 +318,11 @@ _ar_read_header(struct archive_read *a, struct archive_entry *entry,
*/
if (ar->strtab == NULL || number > ar->strtab_size) {
archive_set_error(&a->archive, EINVAL,
- "Can't find long filename for entry");
+ "Can't find long filename for GNU/SVR4 archive entry");
archive_entry_copy_pathname(entry, filename);
/* Parse the time, owner, mode, size fields. */
ar_parse_common_header(ar, entry, h);
- return (ARCHIVE_WARN);
+ return (ARCHIVE_FATAL);
}
archive_entry_copy_pathname(entry, &ar->strtab[(size_t)number]);
@@ -571,7 +580,7 @@ bad_string_table:
"Invalid string table");
free(ar->strtab);
ar->strtab = NULL;
- return (ARCHIVE_WARN);
+ return (ARCHIVE_FATAL);
}
static uint64_t
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
index 4dd38db93..63569635e 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
@@ -383,7 +383,9 @@ archive_read_support_format_cab(struct archive *_a)
archive_read_format_cab_read_data,
archive_read_format_cab_read_data_skip,
NULL,
- archive_read_format_cab_cleanup);
+ archive_read_format_cab_cleanup,
+ NULL,
+ NULL);
if (r != ARCHIVE_OK)
free(cab);
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c
index 819f4a4f5..c2ca85bd3 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c
@@ -198,7 +198,7 @@ static int archive_read_format_cpio_read_data(struct archive_read *,
static int archive_read_format_cpio_read_header(struct archive_read *,
struct archive_entry *);
static int archive_read_format_cpio_skip(struct archive_read *);
-static int be4(const unsigned char *);
+static int64_t be4(const unsigned char *);
static int find_odc_header(struct archive_read *);
static int find_newc_header(struct archive_read *);
static int header_bin_be(struct archive_read *, struct cpio *,
@@ -213,7 +213,7 @@ static int header_afiol(struct archive_read *, struct cpio *,
struct archive_entry *, size_t *, size_t *);
static int is_octal(const char *, size_t);
static int is_hex(const char *, size_t);
-static int le4(const unsigned char *);
+static int64_t le4(const unsigned char *);
static int record_hardlink(struct archive_read *a,
struct cpio *cpio, struct archive_entry *entry);
@@ -243,7 +243,9 @@ archive_read_support_format_cpio(struct archive *_a)
archive_read_format_cpio_read_data,
archive_read_format_cpio_skip,
NULL,
- archive_read_format_cpio_cleanup);
+ archive_read_format_cpio_cleanup,
+ NULL,
+ NULL);
if (r != ARCHIVE_OK)
free(cpio);
@@ -864,8 +866,11 @@ header_bin_le(struct archive_read *a, struct cpio *cpio,
/* Read fixed-size portion of header. */
h = __archive_read_ahead(a, bin_header_size, NULL);
- if (h == NULL)
+ if (h == NULL) {
+ archive_set_error(&a->archive, 0,
+ "End of file trying to read next cpio header");
return (ARCHIVE_FATAL);
+ }
/* Parse out binary fields. */
header = (const unsigned char *)h;
@@ -900,8 +905,11 @@ header_bin_be(struct archive_read *a, struct cpio *cpio,
/* Read fixed-size portion of header. */
h = __archive_read_ahead(a, bin_header_size, NULL);
- if (h == NULL)
+ if (h == NULL) {
+ archive_set_error(&a->archive, 0,
+ "End of file trying to read next cpio header");
return (ARCHIVE_FATAL);
+ }
/* Parse out binary fields. */
header = (const unsigned char *)h;
@@ -944,17 +952,17 @@ archive_read_format_cpio_cleanup(struct archive_read *a)
return (ARCHIVE_OK);
}
-static int
+static int64_t
le4(const unsigned char *p)
{
- return ((p[0]<<16) + (p[1]<<24) + (p[2]<<0) + (p[3]<<8));
+ return ((p[0] << 16) + (((int64_t)p[1]) << 24) + (p[2] << 0) + (p[3] << 8));
}
-static int
+static int64_t
be4(const unsigned char *p)
{
- return ((p[0]<<24) + (p[1]<<16) + (p[2]<<8) + (p[3]));
+ return ((((int64_t)p[0]) << 24) + (p[1] << 16) + (p[2] << 8) + (p[3]));
}
/*
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_empty.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_empty.c
index 366073820..c641eb9b1 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_empty.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_empty.c
@@ -54,6 +54,8 @@ archive_read_support_format_empty(struct archive *_a)
archive_read_format_empty_read_data,
NULL,
NULL,
+ NULL,
+ NULL,
NULL);
return (r);
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
index 8147461b9..3628025c4 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
@@ -387,7 +387,7 @@ static int archive_read_format_iso9660_read_data(struct archive_read *,
static int archive_read_format_iso9660_read_data_skip(struct archive_read *);
static int archive_read_format_iso9660_read_header(struct archive_read *,
struct archive_entry *);
-static const char *build_pathname(struct archive_string *, struct file_info *);
+static const char *build_pathname(struct archive_string *, struct file_info *, int);
static int build_pathname_utf16be(unsigned char *, size_t, size_t *,
struct file_info *);
#if DEBUG
@@ -478,7 +478,9 @@ archive_read_support_format_iso9660(struct archive *_a)
archive_read_format_iso9660_read_data,
archive_read_format_iso9660_read_data_skip,
NULL,
- archive_read_format_iso9660_cleanup);
+ archive_read_format_iso9660_cleanup,
+ NULL,
+ NULL);
if (r != ARCHIVE_OK) {
free(iso9660);
@@ -1223,6 +1225,7 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Pathname is too long");
+ return (ARCHIVE_FATAL);
}
r = archive_entry_copy_pathname_l(entry,
@@ -1245,9 +1248,16 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
rd_r = ARCHIVE_WARN;
}
} else {
- archive_string_empty(&iso9660->pathname);
- archive_entry_set_pathname(entry,
- build_pathname(&iso9660->pathname, file));
+ const char *path = build_pathname(&iso9660->pathname, file, 0);
+ if (path == NULL) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Pathname is too long");
+ return (ARCHIVE_FATAL);
+ } else {
+ archive_string_empty(&iso9660->pathname);
+ archive_entry_set_pathname(entry, path);
+ }
}
iso9660->entry_bytes_remaining = file->size;
@@ -1742,12 +1752,12 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
const unsigned char *isodirrec)
{
struct iso9660 *iso9660;
- struct file_info *file;
+ struct file_info *file, *filep;
size_t name_len;
const unsigned char *rr_start, *rr_end;
const unsigned char *p;
size_t dr_len;
- uint64_t fsize;
+ uint64_t fsize, offset;
int32_t location;
int flags;
@@ -1791,6 +1801,16 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
return (NULL);
}
+ /* Sanity check that this entry does not create a cycle. */
+ offset = iso9660->logical_block_size * (uint64_t)location;
+ for (filep = parent; filep != NULL; filep = filep->parent) {
+ if (filep->offset == offset) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Directory structure contains loop");
+ return (NULL);
+ }
+ }
+
/* Create a new file entry and copy data from the ISO dir record. */
file = (struct file_info *)calloc(1, sizeof(*file));
if (file == NULL) {
@@ -1799,7 +1819,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
return (NULL);
}
file->parent = parent;
- file->offset = iso9660->logical_block_size * (uint64_t)location;
+ file->offset = offset;
file->size = fsize;
file->mtime = isodate7(isodirrec + DR_date_offset);
file->ctime = file->atime = file->mtime;
@@ -3145,29 +3165,39 @@ static time_t
time_from_tm(struct tm *t)
{
#if HAVE_TIMEGM
- /* Use platform timegm() if available. */
- return (timegm(t));
+ /* Use platform timegm() if available. */
+ return (timegm(t));
#elif HAVE__MKGMTIME64
- return (_mkgmtime64(t));
+ return (_mkgmtime64(t));
#else
- /* Else use direct calculation using POSIX assumptions. */
- /* First, fix up tm_yday based on the year/month/day. */
- if (mktime(t) == (time_t)-1)
- return ((time_t)-1);
- /* Then we can compute timegm() from first principles. */
- return (t->tm_sec + t->tm_min * 60 + t->tm_hour * 3600
- + t->tm_yday * 86400 + (t->tm_year - 70) * 31536000
- + ((t->tm_year - 69) / 4) * 86400 -
- ((t->tm_year - 1) / 100) * 86400
- + ((t->tm_year + 299) / 400) * 86400);
+ /* Else use direct calculation using POSIX assumptions. */
+ /* First, fix up tm_yday based on the year/month/day. */
+ if (mktime(t) == (time_t)-1)
+ return ((time_t)-1);
+ /* Then we can compute timegm() from first principles. */
+ return (t->tm_sec
+ + t->tm_min * 60
+ + t->tm_hour * 3600
+ + t->tm_yday * 86400
+ + (t->tm_year - 70) * 31536000
+ + ((t->tm_year - 69) / 4) * 86400
+ - ((t->tm_year - 1) / 100) * 86400
+ + ((t->tm_year + 299) / 400) * 86400);
#endif
}
static const char *
-build_pathname(struct archive_string *as, struct file_info *file)
+build_pathname(struct archive_string *as, struct file_info *file, int depth)
{
+ // Plain ISO9660 only allows 8 dir levels; if we get
+ // to 1000, then something is very, very wrong.
+ if (depth > 1000) {
+ return NULL;
+ }
if (file->parent != NULL && archive_strlen(&file->parent->name) > 0) {
- build_pathname(as, file->parent);
+ if (build_pathname(as, file->parent, depth + 1) == NULL) {
+ return NULL;
+ }
archive_strcat(as, "/");
}
if (archive_strlen(&file->name) == 0)
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c
index f702949fb..eff02d814 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2008-2012 Michihiro NAKAJIMA
+ * Copyright (c) 2008-2014 Michihiro NAKAJIMA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -82,9 +82,6 @@ struct lzh_dec {
/* The length how many bytes we can copy decoded code from
* the window. */
int copy_len;
- /* The remaining bytes that we have not copied decoded data from
- * the window to an output buffer. */
- int w_remaining;
/*
* Bit stream reader.
@@ -140,10 +137,10 @@ struct lzh_dec {
struct lzh_stream {
const unsigned char *next_in;
- int64_t avail_in;
+ int avail_in;
int64_t total_in;
- unsigned char *next_out;
- int64_t avail_out;
+ const unsigned char *ref_ptr;
+ int avail_out;
int64_t total_out;
struct lzh_dec *ds;
};
@@ -198,9 +195,6 @@ struct lha {
char end_of_entry_cleanup;
char entry_is_compressed;
- unsigned char *uncompressed_buffer;
- size_t uncompressed_buffer_size;
-
char format_name[64];
struct lzh_stream strm;
@@ -214,41 +208,6 @@ struct lha {
#define H_LEVEL_OFFSET 20 /* Header Level. */
#define H_SIZE 22 /* Minimum header size. */
-static const uint16_t crc16tbl[256] = {
- 0x0000,0xC0C1,0xC181,0x0140,0xC301,0x03C0,0x0280,0xC241,
- 0xC601,0x06C0,0x0780,0xC741,0x0500,0xC5C1,0xC481,0x0440,
- 0xCC01,0x0CC0,0x0D80,0xCD41,0x0F00,0xCFC1,0xCE81,0x0E40,
- 0x0A00,0xCAC1,0xCB81,0x0B40,0xC901,0x09C0,0x0880,0xC841,
- 0xD801,0x18C0,0x1980,0xD941,0x1B00,0xDBC1,0xDA81,0x1A40,
- 0x1E00,0xDEC1,0xDF81,0x1F40,0xDD01,0x1DC0,0x1C80,0xDC41,
- 0x1400,0xD4C1,0xD581,0x1540,0xD701,0x17C0,0x1680,0xD641,
- 0xD201,0x12C0,0x1380,0xD341,0x1100,0xD1C1,0xD081,0x1040,
- 0xF001,0x30C0,0x3180,0xF141,0x3300,0xF3C1,0xF281,0x3240,
- 0x3600,0xF6C1,0xF781,0x3740,0xF501,0x35C0,0x3480,0xF441,
- 0x3C00,0xFCC1,0xFD81,0x3D40,0xFF01,0x3FC0,0x3E80,0xFE41,
- 0xFA01,0x3AC0,0x3B80,0xFB41,0x3900,0xF9C1,0xF881,0x3840,
- 0x2800,0xE8C1,0xE981,0x2940,0xEB01,0x2BC0,0x2A80,0xEA41,
- 0xEE01,0x2EC0,0x2F80,0xEF41,0x2D00,0xEDC1,0xEC81,0x2C40,
- 0xE401,0x24C0,0x2580,0xE541,0x2700,0xE7C1,0xE681,0x2640,
- 0x2200,0xE2C1,0xE381,0x2340,0xE101,0x21C0,0x2080,0xE041,
- 0xA001,0x60C0,0x6180,0xA141,0x6300,0xA3C1,0xA281,0x6240,
- 0x6600,0xA6C1,0xA781,0x6740,0xA501,0x65C0,0x6480,0xA441,
- 0x6C00,0xACC1,0xAD81,0x6D40,0xAF01,0x6FC0,0x6E80,0xAE41,
- 0xAA01,0x6AC0,0x6B80,0xAB41,0x6900,0xA9C1,0xA881,0x6840,
- 0x7800,0xB8C1,0xB981,0x7940,0xBB01,0x7BC0,0x7A80,0xBA41,
- 0xBE01,0x7EC0,0x7F80,0xBF41,0x7D00,0xBDC1,0xBC81,0x7C40,
- 0xB401,0x74C0,0x7580,0xB541,0x7700,0xB7C1,0xB681,0x7640,
- 0x7200,0xB2C1,0xB381,0x7340,0xB101,0x71C0,0x7080,0xB041,
- 0x5000,0x90C1,0x9181,0x5140,0x9301,0x53C0,0x5280,0x9241,
- 0x9601,0x56C0,0x5780,0x9741,0x5500,0x95C1,0x9481,0x5440,
- 0x9C01,0x5CC0,0x5D80,0x9D41,0x5F00,0x9FC1,0x9E81,0x5E40,
- 0x5A00,0x9AC1,0x9B81,0x5B40,0x9901,0x59C0,0x5880,0x9841,
- 0x8801,0x48C0,0x4980,0x8941,0x4B00,0x8BC1,0x8A81,0x4A40,
- 0x4E00,0x8EC1,0x8F81,0x4F40,0x8D01,0x4DC0,0x4C80,0x8C41,
- 0x4400,0x84C1,0x8581,0x4540,0x8701,0x47C0,0x4680,0x8641,
- 0x8201,0x42C0,0x4380,0x8341,0x4100,0x81C1,0x8081,0x4040
-};
-
static int archive_read_format_lha_bid(struct archive_read *, int);
static int archive_read_format_lha_options(struct archive_read *,
const char *, const char *);
@@ -279,6 +238,7 @@ static int lha_read_data_none(struct archive_read *, const void **,
size_t *, int64_t *);
static int lha_read_data_lzh(struct archive_read *, const void **,
size_t *, int64_t *);
+static void lha_crc16_init(void);
static uint16_t lha_crc16(uint16_t, const void *, size_t);
static int lzh_decode_init(struct lzh_stream *, const char *);
static void lzh_decode_free(struct lzh_stream *);
@@ -320,7 +280,9 @@ archive_read_support_format_lha(struct archive *_a)
archive_read_format_lha_read_data,
archive_read_format_lha_read_data_skip,
NULL,
- archive_read_format_lha_cleanup);
+ archive_read_format_lha_cleanup,
+ NULL,
+ NULL);
if (r != ARCHIVE_OK)
free(lha);
@@ -518,6 +480,8 @@ archive_read_format_lha_read_header(struct archive_read *a,
const char *signature;
int err;
+ lha_crc16_init();
+
a->archive.archive_format = ARCHIVE_FORMAT_LHA;
if (a->archive.archive_format_name == NULL)
a->archive.archive_format_name = "lha";
@@ -1230,13 +1194,15 @@ lha_read_file_extended_header(struct archive_read *a, struct lha *lha,
archive_string_empty(&lha->filename);
break;
}
+ if (extdheader[0] == '\0')
+ goto invalid;
archive_strncpy(&lha->filename,
(const char *)extdheader, datasize);
break;
case EXT_DIRECTORY:
- if (datasize == 0)
+ if (datasize == 0 || extdheader[0] == '\0')
/* no directory name data. exit this case. */
- break;
+ goto invalid;
archive_strncpy(&lha->dirname,
(const char *)extdheader, datasize);
@@ -1376,6 +1342,26 @@ invalid:
}
static int
+lha_end_of_entry(struct archive_read *a)
+{
+ struct lha *lha = (struct lha *)(a->format->data);
+ int r = ARCHIVE_EOF;
+
+ if (!lha->end_of_entry_cleanup) {
+ if ((lha->setflag & CRC_IS_SET) &&
+ lha->crc != lha->entry_crc_calculated) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "LHa data CRC error");
+ r = ARCHIVE_WARN;
+ }
+
+ /* End-of-entry cleanup done. */
+ lha->end_of_entry_cleanup = 1;
+ }
+ return (r);
+}
+
+static int
archive_read_format_lha_read_data(struct archive_read *a,
const void **buff, size_t *size, int64_t *offset)
{
@@ -1388,22 +1374,10 @@ archive_read_format_lha_read_data(struct archive_read *a,
lha->entry_unconsumed = 0;
}
if (lha->end_of_entry) {
- if (!lha->end_of_entry_cleanup) {
- if ((lha->setflag & CRC_IS_SET) &&
- lha->crc != lha->entry_crc_calculated) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "LHa data CRC error");
- return (ARCHIVE_WARN);
- }
-
- /* End-of-entry cleanup done. */
- lha->end_of_entry_cleanup = 1;
- }
*offset = lha->entry_offset;
*size = 0;
*buff = NULL;
- return (ARCHIVE_EOF);
+ return (lha_end_of_entry(a));
}
if (lha->entry_is_compressed)
@@ -1475,18 +1449,6 @@ lha_read_data_lzh(struct archive_read *a, const void **buff,
ssize_t bytes_avail;
int r;
- /* If the buffer hasn't been allocated, allocate it now. */
- if (lha->uncompressed_buffer == NULL) {
- lha->uncompressed_buffer_size = 64 * 1024;
- lha->uncompressed_buffer
- = (unsigned char *)malloc(lha->uncompressed_buffer_size);
- if (lha->uncompressed_buffer == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "No memory for lzh decompression");
- return (ARCHIVE_FATAL);
- }
- }
-
/* If we haven't yet read any data, initialize the decompressor. */
if (!lha->decompress_init) {
r = lzh_decode_init(&(lha->strm), lha->method);
@@ -1532,12 +1494,9 @@ lha_read_data_lzh(struct archive_read *a, const void **buff,
if (bytes_avail > lha->entry_bytes_remaining)
bytes_avail = (ssize_t)lha->entry_bytes_remaining;
- lha->strm.avail_in = bytes_avail;
+ lha->strm.avail_in = (int)bytes_avail;
lha->strm.total_in = 0;
- if (lha->strm.avail_out == 0) {
- lha->strm.next_out = lha->uncompressed_buffer;
- lha->strm.avail_out = lha->uncompressed_buffer_size;
- }
+ lha->strm.avail_out = 0;
r = lzh_decode(&(lha->strm), bytes_avail == lha->entry_bytes_remaining);
switch (r) {
@@ -1554,10 +1513,10 @@ lha_read_data_lzh(struct archive_read *a, const void **buff,
lha->entry_unconsumed = lha->strm.total_in;
lha->entry_bytes_remaining -= lha->strm.total_in;
- if (lha->strm.avail_out == 0 || lha->end_of_entry) {
+ if (lha->strm.avail_out) {
*offset = lha->entry_offset;
- *size = lha->strm.next_out - lha->uncompressed_buffer;
- *buff = lha->uncompressed_buffer;
+ *size = lha->strm.avail_out;
+ *buff = lha->strm.ref_ptr;
lha->entry_crc_calculated =
lha_crc16(lha->entry_crc_calculated, *buff, *size);
lha->entry_offset += *size;
@@ -1565,6 +1524,8 @@ lha_read_data_lzh(struct archive_read *a, const void **buff,
*offset = lha->entry_offset;
*size = 0;
*buff = NULL;
+ if (lha->end_of_entry)
+ return (lha_end_of_entry(a));
}
return (ARCHIVE_OK);
}
@@ -1609,7 +1570,6 @@ archive_read_format_lha_cleanup(struct archive_read *a)
struct lha *lha = (struct lha *)(a->format->data);
lzh_decode_free(&(lha->strm));
- free(lha->uncompressed_buffer);
archive_string_free(&(lha->dirname));
archive_string_free(&(lha->filename));
archive_string_free(&(lha->uname));
@@ -1700,50 +1660,90 @@ lha_calcsum(unsigned char sum, const void *pp, int offset, size_t size)
return (sum);
}
-#define CRC16(crc, v) do { \
- (crc) = crc16tbl[((crc) ^ v) & 0xFF] ^ ((crc) >> 8); \
-} while (0)
+static uint16_t crc16tbl[2][256];
+static void
+lha_crc16_init(void)
+{
+ unsigned int i;
+ static int crc16init = 0;
+
+ if (crc16init)
+ return;
+ crc16init = 1;
+
+ for (i = 0; i < 256; i++) {
+ unsigned int j;
+ uint16_t crc = (uint16_t)i;
+ for (j = 8; j; j--)
+ crc = (crc >> 1) ^ ((crc & 1) * 0xA001);
+ crc16tbl[0][i] = crc;
+ }
+
+ for (i = 0; i < 256; i++) {
+ crc16tbl[1][i] = (crc16tbl[0][i] >> 8)
+ ^ crc16tbl[0][crc16tbl[0][i] & 0xff];
+ }
+}
static uint16_t
lha_crc16(uint16_t crc, const void *pp, size_t len)
{
- const unsigned char *buff = (const unsigned char *)pp;
-
- while (len >= 8) {
- CRC16(crc, *buff++); CRC16(crc, *buff++);
- CRC16(crc, *buff++); CRC16(crc, *buff++);
- CRC16(crc, *buff++); CRC16(crc, *buff++);
- CRC16(crc, *buff++); CRC16(crc, *buff++);
- len -= 8;
+ const unsigned char *p = (const unsigned char *)pp;
+ const uint16_t *buff;
+ const union {
+ uint32_t i;
+ char c[4];
+ } u = { 0x01020304 };
+
+ if (len == 0)
+ return crc;
+
+ /* Process unaligned address. */
+ if (((uintptr_t)p) & (uintptr_t)0x1) {
+ crc = (crc >> 8) ^ crc16tbl[0][(crc ^ *p++) & 0xff];
+ len--;
}
- switch (len) {
- case 7:
- CRC16(crc, *buff++);
- /* FALL THROUGH */
- case 6:
- CRC16(crc, *buff++);
- /* FALL THROUGH */
- case 5:
- CRC16(crc, *buff++);
- /* FALL THROUGH */
- case 4:
- CRC16(crc, *buff++);
- /* FALL THROUGH */
- case 3:
- CRC16(crc, *buff++);
- /* FALL THROUGH */
- case 2:
- CRC16(crc, *buff++);
- /* FALL THROUGH */
- case 1:
- CRC16(crc, *buff);
- /* FALL THROUGH */
- case 0:
- break;
+ buff = (const uint16_t *)p;
+ /*
+ * Modern C compiler such as GCC does not unroll automatically yet
+ * without unrolling pragma, and Clang is so. So we should
+ * unroll this loop for its performance.
+ */
+ for (;len >= 8; len -= 8) {
+ /* This if statement expects compiler optimization will
+ * remove the stament which will not be executed. */
+#ifndef __has_builtin
+# define __has_builtin(x) 0
+#endif
+#if defined(_MSC_VER) && _MSC_VER >= 1400 /* Visual Studio */
+# define bswap16(x) _byteswap_ushort(x)
+#elif (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8) \
+ || (defined(__clang__) && __has_builtin(__builtin_bswap16))
+# define bswap16(x) __builtin_bswap16(x)
+#else
+# define bswap16(x) ((((x) >> 8) & 0xff) | ((x) << 8))
+#endif
+#define CRC16W do { \
+ if(u.c[0] == 1) { /* Big endian */ \
+ crc ^= bswap16(*buff); buff++; \
+ } else \
+ crc ^= *buff++; \
+ crc = crc16tbl[1][crc & 0xff] ^ crc16tbl[0][crc >> 8];\
+} while (0)
+ CRC16W;
+ CRC16W;
+ CRC16W;
+ CRC16W;
+#undef CRC16W
+#undef bswap16
}
- return (crc);
-}
+ p = (const unsigned char *)buff;
+ for (;len; len--) {
+ crc = (crc >> 8) ^ crc16tbl[0][(crc ^ *p++) & 0xff];
+ }
+ return crc;
+}
/*
* Initialize LZHUF decoder.
@@ -1782,18 +1782,18 @@ lzh_decode_init(struct lzh_stream *strm, const char *method)
return (ARCHIVE_FAILED);/* Not supported. */
}
ds->error = ARCHIVE_FATAL;
- w_size = ds->w_size;
- ds->w_size = 1U << w_bits;
+ /* Expand a window size up to 128 KiB for decompressing process
+ * performance whatever its original window size is. */
+ ds->w_size = 1U << 17;
ds->w_mask = ds->w_size -1;
- if (ds->w_buff == NULL || w_size != ds->w_size) {
- free(ds->w_buff);
+ if (ds->w_buff == NULL) {
ds->w_buff = malloc(ds->w_size);
if (ds->w_buff == NULL)
return (ARCHIVE_FATAL);
}
- memset(ds->w_buff, 0x20, ds->w_size);
+ w_size = 1U << w_bits;
+ memset(ds->w_buff + ds->w_size - w_size, 0x20, w_size);
ds->w_pos = 0;
- ds->w_remaining = 0;
ds->state = 0;
ds->pos_pt_len_size = w_bits + 1;
ds->pos_pt_len_bits = (w_bits == 15 || w_bits == 16)? 5: 4;
@@ -1880,9 +1880,10 @@ lzh_br_fillup(struct lzh_stream *strm, struct lzh_br *br)
int n = CACHE_BITS - br->cache_avail;
for (;;) {
- switch (n >> 3) {
- case 8:
- if (strm->avail_in >= 8) {
+ const int x = n >> 3;
+ if (strm->avail_in >= x) {
+ switch (x) {
+ case 8:
br->cache_buffer =
((uint64_t)strm->next_in[0]) << 56 |
((uint64_t)strm->next_in[1]) << 48 |
@@ -1896,10 +1897,7 @@ lzh_br_fillup(struct lzh_stream *strm, struct lzh_br *br)
strm->avail_in -= 8;
br->cache_avail += 8 * 8;
return (1);
- }
- break;
- case 7:
- if (strm->avail_in >= 7) {
+ case 7:
br->cache_buffer =
(br->cache_buffer << 56) |
((uint64_t)strm->next_in[0]) << 48 |
@@ -1913,10 +1911,7 @@ lzh_br_fillup(struct lzh_stream *strm, struct lzh_br *br)
strm->avail_in -= 7;
br->cache_avail += 7 * 8;
return (1);
- }
- break;
- case 6:
- if (strm->avail_in >= 6) {
+ case 6:
br->cache_buffer =
(br->cache_buffer << 48) |
((uint64_t)strm->next_in[0]) << 40 |
@@ -1929,14 +1924,13 @@ lzh_br_fillup(struct lzh_stream *strm, struct lzh_br *br)
strm->avail_in -= 6;
br->cache_avail += 6 * 8;
return (1);
+ case 0:
+ /* We have enough compressed data in
+ * the cache buffer.*/
+ return (1);
+ default:
+ break;
}
- break;
- case 0:
- /* We have enough compressed data in
- * the cache buffer.*/
- return (1);
- default:
- break;
}
if (strm->avail_in == 0) {
/* There is not enough compressed data to fill up the
@@ -1991,7 +1985,7 @@ static int
lzh_decode(struct lzh_stream *strm, int last)
{
struct lzh_dec *ds = strm->ds;
- int64_t avail_in;
+ int avail_in;
int r;
if (ds->error)
@@ -2008,35 +2002,12 @@ lzh_decode(struct lzh_stream *strm, int last)
return (r);
}
-static int
-lzh_copy_from_window(struct lzh_stream *strm, struct lzh_dec *ds)
+static void
+lzh_emit_window(struct lzh_stream *strm, size_t s)
{
- size_t copy_bytes;
-
- if (ds->w_remaining == 0 && ds->w_pos > 0) {
- if (ds->w_pos - ds->copy_pos <= strm->avail_out)
- copy_bytes = ds->w_pos - ds->copy_pos;
- else
- copy_bytes = (size_t)strm->avail_out;
- memcpy(strm->next_out,
- ds->w_buff + ds->copy_pos, copy_bytes);
- ds->copy_pos += (int)copy_bytes;
- } else {
- if (ds->w_remaining <= strm->avail_out)
- copy_bytes = ds->w_remaining;
- else
- copy_bytes = (size_t)strm->avail_out;
- memcpy(strm->next_out,
- ds->w_buff + ds->w_size - ds->w_remaining, copy_bytes);
- ds->w_remaining -= (int)copy_bytes;
- }
- strm->next_out += copy_bytes;
- strm->avail_out -= copy_bytes;
- strm->total_out += copy_bytes;
- if (strm->avail_out == 0)
- return (0);
- else
- return (1);
+ strm->ref_ptr = strm->ds->w_buff;
+ strm->avail_out = (int)s;
+ strm->total_out += s;
}
static int
@@ -2071,8 +2042,9 @@ lzh_read_blocks(struct lzh_stream *strm, int last)
goto failed;
}
if (ds->w_pos > 0) {
- if (!lzh_copy_from_window(strm, ds))
- return (ARCHIVE_OK);
+ lzh_emit_window(strm, ds->w_pos);
+ ds->w_pos = 0;
+ return (ARCHIVE_OK);
}
/* End of compressed data; we have completely
* handled all compressed data. */
@@ -2289,10 +2261,6 @@ lzh_decode_blocks(struct lzh_stream *strm, int last)
int lt_max_bits = lt->max_bits, pt_max_bits = pt->max_bits;
int state = ds->state;
- if (ds->w_remaining > 0) {
- if (!lzh_copy_from_window(strm, ds))
- goto next_data;
- }
for (;;) {
switch (state) {
case ST_GET_LITERAL:
@@ -2347,9 +2315,8 @@ lzh_decode_blocks(struct lzh_stream *strm, int last)
w_buff[w_pos] = c;
if (++w_pos >= w_size) {
w_pos = 0;
- ds->w_remaining = w_size;
- if (!lzh_copy_from_window(strm, ds))
- goto next_data;
+ lzh_emit_window(strm, w_size);
+ goto next_data;
}
}
/* 'c' is the length of a match pattern we have
@@ -2427,25 +2394,26 @@ lzh_decode_blocks(struct lzh_stream *strm, int last)
d = w_buff + w_pos;
s = w_buff + copy_pos;
- for (li = 0; li < l; li++)
+ for (li = 0; li < l-1;) {
+ d[li] = s[li];li++;
+ d[li] = s[li];li++;
+ }
+ if (li < l)
d[li] = s[li];
}
- w_pos = (w_pos + l) & w_mask;
- if (w_pos == 0) {
- ds->w_remaining = w_size;
- if (!lzh_copy_from_window(strm, ds)) {
- if (copy_len <= l)
- state = ST_GET_LITERAL;
- else {
- state = ST_COPY_DATA;
- ds->copy_len =
- copy_len - l;
- ds->copy_pos =
- (copy_pos + l)
- & w_mask;
- }
- goto next_data;
+ w_pos += l;
+ if (w_pos == w_size) {
+ w_pos = 0;
+ lzh_emit_window(strm, w_size);
+ if (copy_len <= l)
+ state = ST_GET_LITERAL;
+ else {
+ state = ST_COPY_DATA;
+ ds->copy_len = copy_len - l;
+ ds->copy_pos =
+ (copy_pos + l) & w_mask;
}
+ goto next_data;
}
if (copy_len <= l)
/* A copy of current pattern ended. */
@@ -2505,14 +2473,80 @@ lzh_huffman_free(struct huffman *hf)
free(hf->tree);
}
+static char bitlen_tbl[0x400] = {
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 16, 0
+};
static int
lzh_read_pt_bitlen(struct lzh_stream *strm, int start, int end)
{
struct lzh_dec *ds = strm->ds;
- struct lzh_br * br = &(ds->br);
+ struct lzh_br *br = &(ds->br);
int c, i;
- for (i = start; i < end;) {
+ for (i = start; i < end; ) {
/*
* bit pattern the number we need
* 000 -> 0
@@ -2528,17 +2562,13 @@ lzh_read_pt_bitlen(struct lzh_stream *strm, int start, int end)
if (!lzh_br_read_ahead(strm, br, 3))
return (i);
if ((c = lzh_br_bits(br, 3)) == 7) {
- int d;
if (!lzh_br_read_ahead(strm, br, 13))
return (i);
- d = lzh_br_bits(br, 13);
- while (d & 0x200) {
- c++;
- d <<= 1;
- }
- if (c > 16)
+ c = bitlen_tbl[lzh_br_bits(br, 13) & 0x3FF];
+ if (c)
+ lzh_br_consume(br, c - 3);
+ else
return (-1);/* Invalid data. */
- lzh_br_consume(br, c - 3);
} else
lzh_br_consume(br, 3);
ds->pt.bitlen[i++] = c;
@@ -2601,7 +2631,7 @@ lzh_make_huffman_table(struct huffman *hf)
}
}
if (maxbits > HTBL_BITS) {
- int htbl_max;
+ unsigned htbl_max;
uint16_t *p;
diffbits = maxbits - HTBL_BITS;
@@ -2645,8 +2675,40 @@ lzh_make_huffman_table(struct huffman *hf)
return (0);/* Invalid */
/* Update the table */
p = &(tbl[ptn]);
- while (--cnt >= 0)
- p[cnt] = (uint16_t)i;
+ if (cnt > 7) {
+ uint16_t *pc;
+
+ cnt -= 8;
+ pc = &p[cnt];
+ pc[0] = (uint16_t)i;
+ pc[1] = (uint16_t)i;
+ pc[2] = (uint16_t)i;
+ pc[3] = (uint16_t)i;
+ pc[4] = (uint16_t)i;
+ pc[5] = (uint16_t)i;
+ pc[6] = (uint16_t)i;
+ pc[7] = (uint16_t)i;
+ if (cnt > 7) {
+ cnt -= 8;
+ memcpy(&p[cnt], pc,
+ 8 * sizeof(uint16_t));
+ pc = &p[cnt];
+ while (cnt > 15) {
+ cnt -= 16;
+ memcpy(&p[cnt], pc,
+ 16 * sizeof(uint16_t));
+ }
+ }
+ if (cnt)
+ memcpy(p, pc, cnt * sizeof(uint16_t));
+ } else {
+ while (cnt > 1) {
+ p[--cnt] = (uint16_t)i;
+ p[--cnt] = (uint16_t)i;
+ }
+ if (cnt)
+ p[--cnt] = (uint16_t)i;
+ }
continue;
}
@@ -2740,7 +2802,7 @@ lzh_decode_huffman(struct huffman *hf, unsigned rbits)
* If it fails, search a huffman tree for.
*/
c = hf->tbl[rbits >> hf->shift_bits];
- if (c < hf->len_avail)
+ if (c < hf->len_avail || hf->len_avail == 0)
return (c);
/* This bit pattern needs to be found out at a huffman tree. */
return (lzh_decode_huffman_tree(hf, rbits, c));
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
index c4e7021a8..b5f8e30d6 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_mtree.c 2011
#include "archive_private.h"
#include "archive_read_private.h"
#include "archive_string.h"
+#include "archive_pack_dev.h"
#ifndef O_BINARY
#define O_BINARY 0
@@ -103,6 +104,7 @@ struct mtree {
struct archive_entry_linkresolver *resolver;
int64_t cur_size;
+ char checkfs;
};
static int bid_keycmp(const char *, const char *, ssize_t);
@@ -137,16 +139,19 @@ get_time_t_max(void)
#if defined(TIME_T_MAX)
return TIME_T_MAX;
#else
- static time_t t;
- time_t a;
- if (t == 0) {
- a = 1;
- while (a > t) {
- t = a;
- a = a * 2 + 1;
- }
+ /* ISO C allows time_t to be a floating-point type,
+ but POSIX requires an integer type. The following
+ should work on any system that follows the POSIX
+ conventions. */
+ if (((time_t)0) < ((time_t)-1)) {
+ /* Time_t is unsigned */
+ return (~(time_t)0);
+ } else {
+ /* Time_t is signed. */
+ const uintmax_t max_unsigned_time_t = (uintmax_t)(~(time_t)0);
+ const uintmax_t max_signed_time_t = max_unsigned_time_t >> 1;
+ return (time_t)max_signed_time_t;
}
- return t;
#endif
}
@@ -156,23 +161,42 @@ get_time_t_min(void)
#if defined(TIME_T_MIN)
return TIME_T_MIN;
#else
- /* 't' will hold the minimum value, which will be zero (if
- * time_t is unsigned) or -2^n (if time_t is signed). */
- static int computed;
- static time_t t;
- time_t a;
- if (computed == 0) {
- a = (time_t)-1;
- while (a < t) {
- t = a;
- a = a * 2;
- }
- computed = 1;
+ if (((time_t)0) < ((time_t)-1)) {
+ /* Time_t is unsigned */
+ return (time_t)0;
+ } else {
+ /* Time_t is signed. */
+ const uintmax_t max_unsigned_time_t = (uintmax_t)(~(time_t)0);
+ const uintmax_t max_signed_time_t = max_unsigned_time_t >> 1;
+ const intmax_t min_signed_time_t = (intmax_t)~max_signed_time_t;
+ return (time_t)min_signed_time_t;
}
- return t;
#endif
}
+static int
+archive_read_format_mtree_options(struct archive_read *a,
+ const char *key, const char *val)
+{
+ struct mtree *mtree;
+
+ mtree = (struct mtree *)(a->format->data);
+ if (strcmp(key, "checkfs") == 0) {
+ /* Allows to read information missing from the mtree from the file system */
+ if (val == NULL || val[0] == 0) {
+ mtree->checkfs = 0;
+ } else {
+ mtree->checkfs = 1;
+ }
+ return (ARCHIVE_OK);
+ }
+
+ /* Note: The "warn" return is just to inform the options
+ * supervisor that we didn't handle it. It will generate
+ * a suitable error if no one used this option. */
+ return (ARCHIVE_WARN);
+}
+
static void
free_options(struct mtree_option *head)
{
@@ -205,7 +229,7 @@ archive_read_support_format_mtree(struct archive *_a)
mtree->fd = -1;
r = __archive_read_register_format(a, mtree, "mtree",
- mtree_bid, NULL, read_header, read_data, skip, NULL, cleanup);
+ mtree_bid, archive_read_format_mtree_options, read_header, read_data, skip, NULL, cleanup, NULL, NULL);
if (r != ARCHIVE_OK)
free(mtree);
@@ -367,7 +391,7 @@ bid_keyword(const char *p, ssize_t len)
"gid", "gname", NULL
};
static const char *keys_il[] = {
- "ignore", "link", NULL
+ "ignore", "inode", "link", NULL
};
static const char *keys_m[] = {
"md5", "md5digest", "mode", NULL
@@ -376,7 +400,7 @@ bid_keyword(const char *p, ssize_t len)
"nlink", "nochange", "optional", NULL
};
static const char *keys_r[] = {
- "rmd160", "rmd160digest", NULL
+ "resdevice", "rmd160", "rmd160digest", NULL
};
static const char *keys_s[] = {
"sha1", "sha1digest",
@@ -507,32 +531,34 @@ bid_entry(const char *p, ssize_t len, ssize_t nl, int *last_is_path)
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F0 - FF */
};
- ssize_t ll = len;
+ ssize_t ll;
const char *pp = p;
+ const char * const pp_end = pp + len;
*last_is_path = 0;
/*
* Skip the path-name which is quoted.
*/
- while (ll > 0 && *pp != ' ' &&*pp != '\t' && *pp != '\r' &&
- *pp != '\n') {
+ for (;pp < pp_end; ++pp) {
if (!safe_char[*(const unsigned char *)pp]) {
- f = 0;
+ if (*pp != ' ' && *pp != '\t' && *pp != '\r'
+ && *pp != '\n')
+ f = 0;
break;
}
- ++pp;
- --ll;
- ++f;
+ f = 1;
}
+ ll = pp_end - pp;
+
/* If a path-name was not found at the first, try to check
- * a mtree format ``NetBSD's mtree -D'' creates, which
- * places the path-name at the last. */
+ * a mtree format(a.k.a form D) ``NetBSD's mtree -D'' creates,
+ * which places the path-name at the last. */
if (f == 0) {
const char *pb = p + len - nl;
int name_len = 0;
int slash;
- /* Do not accept multi lines for form D. */
+ /* The form D accepts only a single line for an entry. */
if (pb-2 >= p &&
pb[-1] == '\\' && (pb[-2] == ' ' || pb[-2] == '\t'))
return (-1);
@@ -1031,7 +1057,8 @@ read_header(struct archive_read *a, struct archive_entry *entry)
}
if (!mtree->this_entry->used) {
use_next = 0;
- r = parse_file(a, entry, mtree, mtree->this_entry, &use_next);
+ r = parse_file(a, entry, mtree, mtree->this_entry,
+ &use_next);
if (use_next == 0)
return (r);
}
@@ -1103,162 +1130,168 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
mtree->current_dir.length = n;
}
- /*
- * Try to open and stat the file to get the real size
- * and other file info. It would be nice to avoid
- * this here so that getting a listing of an mtree
- * wouldn't require opening every referenced contents
- * file. But then we wouldn't know the actual
- * contents size, so I don't see a really viable way
- * around this. (Also, we may want to someday pull
- * other unspecified info from the contents file on
- * disk.)
- */
- mtree->fd = -1;
- if (archive_strlen(&mtree->contents_name) > 0)
- path = mtree->contents_name.s;
- else
- path = archive_entry_pathname(entry);
-
- if (archive_entry_filetype(entry) == AE_IFREG ||
- archive_entry_filetype(entry) == AE_IFDIR) {
- mtree->fd = open(path, O_RDONLY | O_BINARY | O_CLOEXEC);
- __archive_ensure_cloexec_flag(mtree->fd);
- if (mtree->fd == -1 &&
- (errno != ENOENT ||
- archive_strlen(&mtree->contents_name) > 0)) {
- archive_set_error(&a->archive, errno,
- "Can't open %s", path);
- r = ARCHIVE_WARN;
+ if (mtree->checkfs) {
+ /*
+ * Try to open and stat the file to get the real size
+ * and other file info. It would be nice to avoid
+ * this here so that getting a listing of an mtree
+ * wouldn't require opening every referenced contents
+ * file. But then we wouldn't know the actual
+ * contents size, so I don't see a really viable way
+ * around this. (Also, we may want to someday pull
+ * other unspecified info from the contents file on
+ * disk.)
+ */
+ mtree->fd = -1;
+ if (archive_strlen(&mtree->contents_name) > 0)
+ path = mtree->contents_name.s;
+ else
+ path = archive_entry_pathname(entry);
+
+ if (archive_entry_filetype(entry) == AE_IFREG ||
+ archive_entry_filetype(entry) == AE_IFDIR) {
+ mtree->fd = open(path, O_RDONLY | O_BINARY | O_CLOEXEC);
+ __archive_ensure_cloexec_flag(mtree->fd);
+ if (mtree->fd == -1 &&
+ (errno != ENOENT ||
+ archive_strlen(&mtree->contents_name) > 0)) {
+ archive_set_error(&a->archive, errno,
+ "Can't open %s", path);
+ r = ARCHIVE_WARN;
+ }
}
- }
- st = &st_storage;
- if (mtree->fd >= 0) {
- if (fstat(mtree->fd, st) == -1) {
- archive_set_error(&a->archive, errno,
- "Could not fstat %s", path);
- r = ARCHIVE_WARN;
- /* If we can't stat it, don't keep it open. */
- close(mtree->fd);
- mtree->fd = -1;
+ st = &st_storage;
+ if (mtree->fd >= 0) {
+ if (fstat(mtree->fd, st) == -1) {
+ archive_set_error(&a->archive, errno,
+ "Could not fstat %s", path);
+ r = ARCHIVE_WARN;
+ /* If we can't stat it, don't keep it open. */
+ close(mtree->fd);
+ mtree->fd = -1;
+ st = NULL;
+ }
+ } else if (lstat(path, st) == -1) {
st = NULL;
}
- } else if (lstat(path, st) == -1) {
- st = NULL;
- }
- /*
- * Check for a mismatch between the type in the specification and
- * the type of the contents object on disk.
- */
- if (st != NULL) {
- if (
- ((st->st_mode & S_IFMT) == S_IFREG &&
- archive_entry_filetype(entry) == AE_IFREG)
+ /*
+ * Check for a mismatch between the type in the specification
+ * and the type of the contents object on disk.
+ */
+ if (st != NULL) {
+ if (((st->st_mode & S_IFMT) == S_IFREG &&
+ archive_entry_filetype(entry) == AE_IFREG)
#ifdef S_IFLNK
- || ((st->st_mode & S_IFMT) == S_IFLNK &&
- archive_entry_filetype(entry) == AE_IFLNK)
+ ||((st->st_mode & S_IFMT) == S_IFLNK &&
+ archive_entry_filetype(entry) == AE_IFLNK)
#endif
#ifdef S_IFSOCK
- || ((st->st_mode & S_IFSOCK) == S_IFSOCK &&
- archive_entry_filetype(entry) == AE_IFSOCK)
+ ||((st->st_mode & S_IFSOCK) == S_IFSOCK &&
+ archive_entry_filetype(entry) == AE_IFSOCK)
#endif
#ifdef S_IFCHR
- || ((st->st_mode & S_IFMT) == S_IFCHR &&
- archive_entry_filetype(entry) == AE_IFCHR)
+ ||((st->st_mode & S_IFMT) == S_IFCHR &&
+ archive_entry_filetype(entry) == AE_IFCHR)
#endif
#ifdef S_IFBLK
- || ((st->st_mode & S_IFMT) == S_IFBLK &&
- archive_entry_filetype(entry) == AE_IFBLK)
+ ||((st->st_mode & S_IFMT) == S_IFBLK &&
+ archive_entry_filetype(entry) == AE_IFBLK)
#endif
- || ((st->st_mode & S_IFMT) == S_IFDIR &&
- archive_entry_filetype(entry) == AE_IFDIR)
+ ||((st->st_mode & S_IFMT) == S_IFDIR &&
+ archive_entry_filetype(entry) == AE_IFDIR)
#ifdef S_IFIFO
- || ((st->st_mode & S_IFMT) == S_IFIFO &&
- archive_entry_filetype(entry) == AE_IFIFO)
+ ||((st->st_mode & S_IFMT) == S_IFIFO &&
+ archive_entry_filetype(entry) == AE_IFIFO)
#endif
- ) {
- /* Types match. */
- } else {
- /* Types don't match; bail out gracefully. */
- if (mtree->fd >= 0)
- close(mtree->fd);
- mtree->fd = -1;
- if (parsed_kws & MTREE_HAS_OPTIONAL) {
- /* It's not an error for an optional entry
- to not match disk. */
- *use_next = 1;
- } else if (r == ARCHIVE_OK) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "mtree specification has different type for %s",
- archive_entry_pathname(entry));
- r = ARCHIVE_WARN;
+ ) {
+ /* Types match. */
+ } else {
+ /* Types don't match; bail out gracefully. */
+ if (mtree->fd >= 0)
+ close(mtree->fd);
+ mtree->fd = -1;
+ if (parsed_kws & MTREE_HAS_OPTIONAL) {
+ /* It's not an error for an optional
+ * entry to not match disk. */
+ *use_next = 1;
+ } else if (r == ARCHIVE_OK) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "mtree specification has different"
+ " type for %s",
+ archive_entry_pathname(entry));
+ r = ARCHIVE_WARN;
+ }
+ return (r);
}
- return r;
}
- }
- /*
- * If there is a contents file on disk, pick some of the metadata
- * from that file. For most of these, we only set it from the contents
- * if it wasn't already parsed from the specification.
- */
- if (st != NULL) {
- if (((parsed_kws & MTREE_HAS_DEVICE) == 0 ||
- (parsed_kws & MTREE_HAS_NOCHANGE) != 0) &&
- (archive_entry_filetype(entry) == AE_IFCHR ||
- archive_entry_filetype(entry) == AE_IFBLK))
- archive_entry_set_rdev(entry, st->st_rdev);
- if ((parsed_kws & (MTREE_HAS_GID | MTREE_HAS_GNAME)) == 0 ||
- (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
- archive_entry_set_gid(entry, st->st_gid);
- if ((parsed_kws & (MTREE_HAS_UID | MTREE_HAS_UNAME)) == 0 ||
- (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
- archive_entry_set_uid(entry, st->st_uid);
- if ((parsed_kws & MTREE_HAS_MTIME) == 0 ||
- (parsed_kws & MTREE_HAS_NOCHANGE) != 0) {
+ /*
+ * If there is a contents file on disk, pick some of the
+ * metadata from that file. For most of these, we only
+ * set it from the contents if it wasn't already parsed
+ * from the specification.
+ */
+ if (st != NULL) {
+ if (((parsed_kws & MTREE_HAS_DEVICE) == 0 ||
+ (parsed_kws & MTREE_HAS_NOCHANGE) != 0) &&
+ (archive_entry_filetype(entry) == AE_IFCHR ||
+ archive_entry_filetype(entry) == AE_IFBLK))
+ archive_entry_set_rdev(entry, st->st_rdev);
+ if ((parsed_kws & (MTREE_HAS_GID | MTREE_HAS_GNAME))
+ == 0 ||
+ (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
+ archive_entry_set_gid(entry, st->st_gid);
+ if ((parsed_kws & (MTREE_HAS_UID | MTREE_HAS_UNAME))
+ == 0 ||
+ (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
+ archive_entry_set_uid(entry, st->st_uid);
+ if ((parsed_kws & MTREE_HAS_MTIME) == 0 ||
+ (parsed_kws & MTREE_HAS_NOCHANGE) != 0) {
#if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
- archive_entry_set_mtime(entry, st->st_mtime,
- st->st_mtimespec.tv_nsec);
+ archive_entry_set_mtime(entry, st->st_mtime,
+ st->st_mtimespec.tv_nsec);
#elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
- archive_entry_set_mtime(entry, st->st_mtime,
- st->st_mtim.tv_nsec);
+ archive_entry_set_mtime(entry, st->st_mtime,
+ st->st_mtim.tv_nsec);
#elif HAVE_STRUCT_STAT_ST_MTIME_N
- archive_entry_set_mtime(entry, st->st_mtime,
- st->st_mtime_n);
+ archive_entry_set_mtime(entry, st->st_mtime,
+ st->st_mtime_n);
#elif HAVE_STRUCT_STAT_ST_UMTIME
- archive_entry_set_mtime(entry, st->st_mtime,
- st->st_umtime*1000);
+ archive_entry_set_mtime(entry, st->st_mtime,
+ st->st_umtime*1000);
#elif HAVE_STRUCT_STAT_ST_MTIME_USEC
- archive_entry_set_mtime(entry, st->st_mtime,
- st->st_mtime_usec*1000);
+ archive_entry_set_mtime(entry, st->st_mtime,
+ st->st_mtime_usec*1000);
#else
- archive_entry_set_mtime(entry, st->st_mtime, 0);
+ archive_entry_set_mtime(entry, st->st_mtime, 0);
#endif
+ }
+ if ((parsed_kws & MTREE_HAS_NLINK) == 0 ||
+ (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
+ archive_entry_set_nlink(entry, st->st_nlink);
+ if ((parsed_kws & MTREE_HAS_PERM) == 0 ||
+ (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
+ archive_entry_set_perm(entry, st->st_mode);
+ if ((parsed_kws & MTREE_HAS_SIZE) == 0 ||
+ (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
+ archive_entry_set_size(entry, st->st_size);
+ archive_entry_set_ino(entry, st->st_ino);
+ archive_entry_set_dev(entry, st->st_dev);
+
+ archive_entry_linkify(mtree->resolver, &entry,
+ &sparse_entry);
+ } else if (parsed_kws & MTREE_HAS_OPTIONAL) {
+ /*
+ * Couldn't open the entry, stat it or the on-disk type
+ * didn't match. If this entry is optional, just
+ * ignore it and read the next header entry.
+ */
+ *use_next = 1;
+ return ARCHIVE_OK;
}
- if ((parsed_kws & MTREE_HAS_NLINK) == 0 ||
- (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
- archive_entry_set_nlink(entry, st->st_nlink);
- if ((parsed_kws & MTREE_HAS_PERM) == 0 ||
- (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
- archive_entry_set_perm(entry, st->st_mode);
- if ((parsed_kws & MTREE_HAS_SIZE) == 0 ||
- (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
- archive_entry_set_size(entry, st->st_size);
- archive_entry_set_ino(entry, st->st_ino);
- archive_entry_set_dev(entry, st->st_dev);
-
- archive_entry_linkify(mtree->resolver, &entry, &sparse_entry);
- } else if (parsed_kws & MTREE_HAS_OPTIONAL) {
- /*
- * Couldn't open the entry, stat it or the on-disk type
- * didn't match. If this entry is optional, just ignore it
- * and read the next header entry.
- */
- *use_next = 1;
- return ARCHIVE_OK;
}
mtree->cur_size = archive_entry_size(entry);
@@ -1292,33 +1325,82 @@ parse_line(struct archive_read *a, struct archive_entry *entry,
/*
* Device entries have one of the following forms:
- * raw dev_t
- * format,major,minor[,subdevice]
- *
- * Just use major and minor, no translation etc is done
- * between formats.
+ * - raw dev_t
+ * - format,major,minor[,subdevice]
+ * When parsing succeeded, `pdev' will contain the appropriate dev_t value.
*/
-static int
-parse_device(struct archive *a, struct archive_entry *entry, char *val)
+
+/* strsep() is not in C90, but strcspn() is. */
+/* Taken from http://unixpapa.com/incnote/string.html */
+static char *
+la_strsep(char **sp, char *sep)
{
- char *comma1, *comma2;
+ char *p, *s;
+ if (sp == NULL || *sp == NULL || **sp == '\0')
+ return(NULL);
+ s = *sp;
+ p = s + strcspn(s, sep);
+ if (*p != '\0')
+ *p++ = '\0';
+ *sp = p;
+ return(s);
+}
- comma1 = strchr(val, ',');
- if (comma1 == NULL) {
- archive_entry_set_dev(entry, (dev_t)mtree_atol10(&val));
- return (ARCHIVE_OK);
- }
- ++comma1;
- comma2 = strchr(comma1, ',');
- if (comma2 == NULL) {
- archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
- "Malformed device attribute");
- return (ARCHIVE_WARN);
+static int
+parse_device(dev_t *pdev, struct archive *a, char *val)
+{
+#define MAX_PACK_ARGS 3
+ unsigned long numbers[MAX_PACK_ARGS];
+ char *p, *dev;
+ int argc;
+ pack_t *pack;
+ dev_t result;
+ const char *error = NULL;
+
+ memset(pdev, 0, sizeof(*pdev));
+ if ((dev = strchr(val, ',')) != NULL) {
+ /*
+ * Device's major/minor are given in a specified format.
+ * Decode and pack it accordingly.
+ */
+ *dev++ = '\0';
+ if ((pack = pack_find(val)) == NULL) {
+ archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unknown format `%s'", val);
+ return ARCHIVE_WARN;
+ }
+ argc = 0;
+ while ((p = la_strsep(&dev, ",")) != NULL) {
+ if (*p == '\0') {
+ archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Missing number");
+ return ARCHIVE_WARN;
+ }
+ numbers[argc++] = (unsigned long)mtree_atol(&p);
+ if (argc > MAX_PACK_ARGS) {
+ archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Too many arguments");
+ return ARCHIVE_WARN;
+ }
+ }
+ if (argc < 2) {
+ archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Not enough arguments");
+ return ARCHIVE_WARN;
+ }
+ result = (*pack)(argc, numbers, &error);
+ if (error != NULL) {
+ archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+ "%s", error);
+ return ARCHIVE_WARN;
+ }
+ } else {
+ /* file system raw value. */
+ result = (dev_t)mtree_atol(&val);
}
- ++comma2;
- archive_entry_set_rdevmajor(entry, (dev_t)mtree_atol(&comma1));
- archive_entry_set_rdevminor(entry, (dev_t)mtree_atol(&comma2));
- return (ARCHIVE_OK);
+ *pdev = result;
+ return ARCHIVE_OK;
+#undef MAX_PACK_ARGS
}
/*
@@ -1374,8 +1456,16 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
break;
case 'd':
if (strcmp(key, "device") == 0) {
+ /* stat(2) st_rdev field, e.g. the major/minor IDs
+ * of a char/block special file */
+ int r;
+ dev_t dev;
+
*parsed_kws |= MTREE_HAS_DEVICE;
- return parse_device(&a->archive, entry, val);
+ r = parse_device(&dev, &a->archive, val);
+ if (r == ARCHIVE_OK)
+ archive_entry_set_rdev(entry, dev);
+ return r;
}
case 'f':
if (strcmp(key, "flags") == 0) {
@@ -1394,6 +1484,11 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
archive_entry_copy_gname(entry, val);
break;
}
+ case 'i':
+ if (strcmp(key, "inode") == 0) {
+ archive_entry_set_ino(entry, mtree_atol10(&val));
+ break;
+ }
case 'l':
if (strcmp(key, "link") == 0) {
archive_entry_copy_symlink(entry, val);
@@ -1423,6 +1518,17 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
break;
}
case 'r':
+ if (strcmp(key, "resdevice") == 0) {
+ /* stat(2) st_dev field, e.g. the device ID where the
+ * inode resides */
+ int r;
+ dev_t dev;
+
+ r = parse_device(&dev, &a->archive, val);
+ if (r == ARCHIVE_OK)
+ archive_entry_set_dev(entry, dev);
+ return r;
+ }
if (strcmp(key, "rmd160") == 0 ||
strcmp(key, "rmd160digest") == 0)
break;
@@ -1483,32 +1589,38 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
}
case 'c':
if (strcmp(val, "char") == 0) {
- archive_entry_set_filetype(entry, AE_IFCHR);
+ archive_entry_set_filetype(entry,
+ AE_IFCHR);
break;
}
case 'd':
if (strcmp(val, "dir") == 0) {
- archive_entry_set_filetype(entry, AE_IFDIR);
+ archive_entry_set_filetype(entry,
+ AE_IFDIR);
break;
}
case 'f':
if (strcmp(val, "fifo") == 0) {
- archive_entry_set_filetype(entry, AE_IFIFO);
+ archive_entry_set_filetype(entry,
+ AE_IFIFO);
break;
}
if (strcmp(val, "file") == 0) {
- archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_filetype(entry,
+ AE_IFREG);
break;
}
case 'l':
if (strcmp(val, "link") == 0) {
- archive_entry_set_filetype(entry, AE_IFLNK);
+ archive_entry_set_filetype(entry,
+ AE_IFLNK);
break;
}
default:
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
- "Unrecognized file type \"%s\"; assuming \"file\"", val);
+ "Unrecognized file type \"%s\"; "
+ "assuming \"file\"", val);
archive_entry_set_filetype(entry, AE_IFREG);
return (ARCHIVE_WARN);
}
@@ -1535,7 +1647,8 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
}
static int
-read_data(struct archive_read *a, const void **buff, size_t *size, int64_t *offset)
+read_data(struct archive_read *a, const void **buff, size_t *size,
+ int64_t *offset)
{
size_t bytes_to_read;
ssize_t bytes_read;
@@ -1661,6 +1774,10 @@ parse_escapes(char *src, struct mtree_entry *mentry)
c = '\v';
++src;
break;
+ case '\\':
+ c = '\\';
+ ++src;
+ break;
}
}
*dest++ = c;
@@ -1798,14 +1915,14 @@ mtree_atol(char **p)
* point to first character of line.
*/
static ssize_t
-readline(struct archive_read *a, struct mtree *mtree, char **start, ssize_t limit)
+readline(struct archive_read *a, struct mtree *mtree, char **start,
+ ssize_t limit)
{
ssize_t bytes_read;
ssize_t total_size = 0;
ssize_t find_off = 0;
const void *t;
- const char *s;
- void *p;
+ void *nl;
char *u;
/* Accumulate line in a line buffer. */
@@ -1816,11 +1933,10 @@ readline(struct archive_read *a, struct mtree *mtree, char **start, ssize_t limi
return (0);
if (bytes_read < 0)
return (ARCHIVE_FATAL);
- s = t; /* Start of line? */
- p = memchr(t, '\n', bytes_read);
- /* If we found '\n', trim the read. */
- if (p != NULL) {
- bytes_read = 1 + ((const char *)p) - s;
+ nl = memchr(t, '\n', bytes_read);
+ /* If we found '\n', trim the read to end exactly there. */
+ if (nl != NULL) {
+ bytes_read = ((const char *)nl) - ((const char *)t) + 1;
}
if (total_size + bytes_read + 1 > limit) {
archive_set_error(&a->archive,
@@ -1834,38 +1950,34 @@ readline(struct archive_read *a, struct mtree *mtree, char **start, ssize_t limi
"Can't allocate working buffer");
return (ARCHIVE_FATAL);
}
+ /* Append new bytes to string. */
memcpy(mtree->line.s + total_size, t, bytes_read);
__archive_read_consume(a, bytes_read);
total_size += bytes_read;
- /* Null terminate. */
mtree->line.s[total_size] = '\0';
- /* If we found an unescaped '\n', clean up and return. */
+
for (u = mtree->line.s + find_off; *u; ++u) {
if (u[0] == '\n') {
+ /* Ends with unescaped newline. */
*start = mtree->line.s;
return total_size;
- }
- if (u[0] == '#') {
- if (p == NULL)
+ } else if (u[0] == '#') {
+ /* Ends with comment sequence #...\n */
+ if (nl == NULL) {
+ /* But we've not found the \n yet */
break;
- *start = mtree->line.s;
- return total_size;
- }
- if (u[0] != '\\')
- continue;
- if (u[1] == '\\') {
- ++u;
- continue;
- }
- if (u[1] == '\n') {
- memmove(u, u + 1,
- total_size - (u - mtree->line.s) + 1);
- --total_size;
- ++u;
- break;
+ }
+ } else if (u[0] == '\\') {
+ if (u[1] == '\n') {
+ /* Trim escaped newline. */
+ total_size -= 2;
+ mtree->line.s[total_size] = '\0';
+ break;
+ } else if (u[1] != '\0') {
+ /* Skip the two-char escape sequence */
+ ++u;
+ }
}
- if (u[1] == '\0')
- break;
}
find_off = u - mtree->line.s;
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
index dc1563d9e..35ac7cf4d 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
@@ -186,6 +186,7 @@ struct huffman_code
{
struct huffman_tree_node *tree;
int numentries;
+ int numallocatedentries;
int minlength;
int maxlength;
int tablesize;
@@ -225,6 +226,7 @@ struct rar
mode_t mode;
char *filename;
char *filename_save;
+ size_t filename_save_size;
size_t filename_allocated;
/* File header optional entries */
@@ -304,8 +306,15 @@ struct rar
ssize_t avail_in;
const unsigned char *next_in;
} br;
+
+ /*
+ * Custom field to denote that this archive contains encrypted entries
+ */
+ int has_encrypted_entries;
};
+static int archive_read_support_format_rar_capabilities(struct archive_read *);
+static int archive_read_format_rar_has_encrypted_entries(struct archive_read *);
static int archive_read_format_rar_bid(struct archive_read *, int);
static int archive_read_format_rar_options(struct archive_read *,
const char *, const char *);
@@ -646,6 +655,12 @@ archive_read_support_format_rar(struct archive *_a)
}
memset(rar, 0, sizeof(*rar));
+ /*
+ * Until enough data has been read, we cannot tell about
+ * any encrypted entries yet.
+ */
+ rar->has_encrypted_entries = ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
+
r = __archive_read_register_format(a,
rar,
"rar",
@@ -655,7 +670,9 @@ archive_read_support_format_rar(struct archive *_a)
archive_read_format_rar_read_data,
archive_read_format_rar_read_data_skip,
archive_read_format_rar_seek_data,
- archive_read_format_rar_cleanup);
+ archive_read_format_rar_cleanup,
+ archive_read_support_format_rar_capabilities,
+ archive_read_format_rar_has_encrypted_entries);
if (r != ARCHIVE_OK)
free(rar);
@@ -663,6 +680,27 @@ archive_read_support_format_rar(struct archive *_a)
}
static int
+archive_read_support_format_rar_capabilities(struct archive_read * a)
+{
+ (void)a; /* UNUSED */
+ return (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA
+ | ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA);
+}
+
+static int
+archive_read_format_rar_has_encrypted_entries(struct archive_read *_a)
+{
+ if (_a && _a->format) {
+ struct rar * rar = (struct rar *)_a->format->data;
+ if (rar) {
+ return rar->has_encrypted_entries;
+ }
+ }
+ return ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
+}
+
+
+static int
archive_read_format_rar_bid(struct archive_read *a, int best_bid)
{
const char *p;
@@ -755,7 +793,7 @@ archive_read_format_rar_options(struct archive_read *a,
{
struct rar *rar;
int ret = ARCHIVE_FAILED;
-
+
rar = (struct rar *)(a->format->data);
if (strcmp(key, "hdrcharset") == 0) {
if (val == NULL || val[0] == 0)
@@ -797,6 +835,17 @@ archive_read_format_rar_read_header(struct archive_read *a,
rar = (struct rar *)(a->format->data);
+ /*
+ * It should be sufficient to call archive_read_next_header() for
+ * a reader to determine if an entry is encrypted or not. If the
+ * encryption of an entry is only detectable when calling
+ * archive_read_data(), so be it. We'll do the same check there
+ * as well.
+ */
+ if (rar->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
+ rar->has_encrypted_entries = 0;
+ }
+
/* RAR files can be generated without EOF headers, so return ARCHIVE_EOF if
* this fails.
*/
@@ -857,9 +906,14 @@ archive_read_format_rar_read_header(struct archive_read *a,
sizeof(rar->reserved2));
}
+ /* Main header is password encrytped, so we cannot read any
+ file names or any other info about files from the header. */
if (rar->main_flags & MHD_PASSWORD)
{
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ archive_entry_set_is_metadata_encrypted(entry, 1);
+ archive_entry_set_is_data_encrypted(entry, 1);
+ rar->has_encrypted_entries = 1;
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"RAR encryption support unavailable.");
return (ARCHIVE_FATAL);
}
@@ -938,14 +992,18 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
struct rar *rar = (struct rar *)(a->format->data);
int ret;
+ if (rar->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
+ rar->has_encrypted_entries = 0;
+ }
+
if (rar->bytes_unconsumed > 0) {
/* Consume as much as the decompressor actually used. */
__archive_read_consume(a, rar->bytes_unconsumed);
rar->bytes_unconsumed = 0;
}
+ *buff = NULL;
if (rar->entry_eof || rar->offset_seek >= rar->unp_size) {
- *buff = NULL;
*size = 0;
*offset = rar->offset;
if (*offset < rar->unp_size)
@@ -957,7 +1015,7 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
{
case COMPRESS_METHOD_STORE:
ret = read_data_stored(a, buff, size, offset);
- break;
+ break;
case COMPRESS_METHOD_FASTEST:
case COMPRESS_METHOD_FAST:
@@ -967,13 +1025,13 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
ret = read_data_compressed(a, buff, size, offset);
if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN)
__archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
- break;
+ break;
default:
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Unsupported compression method for RAR file.");
ret = ARCHIVE_FATAL;
- break;
+ break;
}
return (ret);
}
@@ -1145,10 +1203,8 @@ archive_read_format_rar_seek_data(struct archive_read *a, int64_t offset,
ret -= rar->dbo[0].start_offset;
/* Always restart reading the file after a seek */
- a->read_data_block = NULL;
- a->read_data_offset = 0;
- a->read_data_output_offset = 0;
- a->read_data_remaining = 0;
+ __archive_reset_read_data(&a->archive);
+
rar->bytes_unconsumed = 0;
rar->offset = 0;
@@ -1290,9 +1346,14 @@ read_header(struct archive_read *a, struct archive_entry *entry,
if (rar->file_flags & FHD_PASSWORD)
{
+ archive_entry_set_is_data_encrypted(entry, 1);
+ rar->has_encrypted_entries = 1;
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"RAR encryption support unavailable.");
- return (ARCHIVE_FATAL);
+ /* Since it is only the data part itself that is encrypted we can at least
+ extract information about the currently processed entry and don't need
+ to return ARCHIVE_FATAL here. */
+ /*return (ARCHIVE_FATAL);*/
}
if (rar->file_flags & FHD_LARGE)
@@ -1377,7 +1438,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
flagbyte = *(p + offset++);
flagbits = 8;
}
-
+
flagbits -= 2;
switch((flagbyte >> flagbits) & 3)
{
@@ -1469,6 +1530,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
/* Split file in multivolume RAR. No more need to process header. */
if (rar->filename_save &&
+ filename_size == rar->filename_save_size &&
!memcmp(rar->filename, rar->filename_save, filename_size + 1))
{
__archive_read_consume(a, header_size - 7);
@@ -1498,6 +1560,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
rar->filename_save = (char*)realloc(rar->filename_save,
filename_size + 1);
memcpy(rar->filename_save, rar->filename, filename_size + 1);
+ rar->filename_save_size = filename_size;
/* Set info for seeking */
free(rar->dbo);
@@ -2345,6 +2408,8 @@ create_code(struct archive_read *a, struct huffman_code *code,
{
int i, j, codebits = 0, symbolsleft = numsymbols;
+ code->numentries = 0;
+ code->numallocatedentries = 0;
if (new_node(code) < 0) {
archive_set_error(&a->archive, ENOMEM,
"Unable to allocate memory for node data.");
@@ -2473,11 +2538,17 @@ static int
new_node(struct huffman_code *code)
{
void *new_tree;
-
- new_tree = realloc(code->tree, (code->numentries + 1) * sizeof(*code->tree));
- if (new_tree == NULL)
- return (-1);
- code->tree = (struct huffman_tree_node *)new_tree;
+ if (code->numallocatedentries == code->numentries) {
+ int new_num_entries = 256;
+ if (code->numentries > 0) {
+ new_num_entries = code->numentries * 2;
+ }
+ new_tree = realloc(code->tree, new_num_entries * sizeof(*code->tree));
+ if (new_tree == NULL)
+ return (-1);
+ code->tree = (struct huffman_tree_node *)new_tree;
+ code->numallocatedentries = new_num_entries;
+ }
code->tree[code->numentries].branches[0] = -1;
code->tree[code->numentries].branches[1] = -2;
return 1;
@@ -2611,7 +2682,7 @@ expand(struct archive_read *a, int64_t end)
if ((symbol = read_next_symbol(a, &rar->maincode)) < 0)
return (ARCHIVE_FATAL);
rar->output_last_match = 0;
-
+
if (symbol < 256)
{
lzss_emit_literal(rar, symbol);
@@ -2834,8 +2905,8 @@ rar_read_ahead(struct archive_read *a, size_t min, ssize_t *avail)
int ret;
if (avail)
{
- if (a->read_data_is_posix_read && *avail > (ssize_t)a->read_data_requested)
- *avail = a->read_data_requested;
+ if (a->archive.read_data_is_posix_read && *avail > (ssize_t)a->archive.read_data_requested)
+ *avail = a->archive.read_data_requested;
if (*avail > rar->bytes_remaining)
*avail = (ssize_t)rar->bytes_remaining;
if (*avail < 0)
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_raw.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_raw.c
index 843497878..efa2c6a33 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_raw.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_raw.c
@@ -78,7 +78,9 @@ archive_read_support_format_raw(struct archive *_a)
archive_read_format_raw_read_data,
archive_read_format_raw_read_data_skip,
NULL,
- archive_read_format_raw_cleanup);
+ archive_read_format_raw_cleanup,
+ NULL,
+ NULL);
if (r != ARCHIVE_OK)
free(info);
return (r);
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
index e9523cb68..01d85cf6a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
@@ -151,6 +151,8 @@ struct tar {
struct archive_string_conv *sconv_default;
int init_default_conversion;
int compat_2x;
+ int process_mac_extensions;
+ int read_concatenated_archives;
};
static int archive_block_is_null(const char *p);
@@ -241,6 +243,10 @@ archive_read_support_format_tar(struct archive *_a)
ARCHIVE_STATE_NEW, "archive_read_support_format_tar");
tar = (struct tar *)calloc(1, sizeof(*tar));
+#ifdef HAVE_COPYFILE_H
+ /* Set this by default on Mac OS. */
+ tar->process_mac_extensions = 1;
+#endif
if (tar == NULL) {
archive_set_error(&a->archive, ENOMEM,
"Can't allocate tar data");
@@ -254,7 +260,9 @@ archive_read_support_format_tar(struct archive *_a)
archive_read_format_tar_read_data,
archive_read_format_tar_skip,
NULL,
- archive_read_format_tar_cleanup);
+ archive_read_format_tar_cleanup,
+ NULL,
+ NULL);
if (r != ARCHIVE_OK)
free(tar);
@@ -368,7 +376,7 @@ archive_read_format_tar_options(struct archive_read *a,
tar = (struct tar *)(a->format->data);
if (strcmp(key, "compat-2x") == 0) {
/* Handle UTF-8 filnames as libarchive 2.x */
- tar->compat_2x = (val != NULL)?1:0;
+ tar->compat_2x = (val != NULL && val[0] != 0);
tar->init_default_conversion = tar->compat_2x;
return (ARCHIVE_OK);
} else if (strcmp(key, "hdrcharset") == 0) {
@@ -385,6 +393,12 @@ archive_read_format_tar_options(struct archive_read *a,
ret = ARCHIVE_FATAL;
}
return (ret);
+ } else if (strcmp(key, "mac-ext") == 0) {
+ tar->process_mac_extensions = (val != NULL && val[0] != 0);
+ return (ARCHIVE_OK);
+ } else if (strcmp(key, "read_concatenated_archives") == 0) {
+ tar->read_concatenated_archives = (val != NULL && val[0] != 0);
+ return (ARCHIVE_OK);
}
/* Note: The "warn" return is just to inform the options
@@ -397,7 +411,7 @@ archive_read_format_tar_options(struct archive_read *a,
* how much unconsumed data we have floating around, and to consume
* anything outstanding since we're going to do read_aheads
*/
-static void
+static void
tar_flush_unconsumed(struct archive_read *a, size_t *unconsumed)
{
if (*unconsumed) {
@@ -442,6 +456,7 @@ archive_read_format_tar_read_header(struct archive_read *a,
static int default_dev;
struct tar *tar;
const char *p;
+ const wchar_t *wp;
int r;
size_t l, unconsumed = 0;
@@ -492,27 +507,22 @@ archive_read_format_tar_read_header(struct archive_read *a,
}
}
- if (r == ARCHIVE_OK) {
+ if (r == ARCHIVE_OK && archive_entry_filetype(entry) == AE_IFREG) {
/*
* "Regular" entry with trailing '/' is really
* directory: This is needed for certain old tar
* variants and even for some broken newer ones.
*/
- const wchar_t *wp;
- wp = archive_entry_pathname_w(entry);
- if (wp != NULL) {
+ if ((wp = archive_entry_pathname_w(entry)) != NULL) {
l = wcslen(wp);
- if (archive_entry_filetype(entry) == AE_IFREG
- && wp[l-1] == L'/')
+ if (l > 0 && wp[l - 1] == L'/') {
archive_entry_set_filetype(entry, AE_IFDIR);
- } else {
- p = archive_entry_pathname(entry);
- if (p == NULL)
- return (ARCHIVE_FAILED);
+ }
+ } else if ((p = archive_entry_pathname(entry)) != NULL) {
l = strlen(p);
- if (archive_entry_filetype(entry) == AE_IFREG
- && p[l-1] == '/')
+ if (l > 0 && p[l - 1] == '/') {
archive_entry_set_filetype(entry, AE_IFDIR);
+ }
}
}
return (r);
@@ -585,13 +595,27 @@ static int
archive_read_format_tar_skip(struct archive_read *a)
{
int64_t bytes_skipped;
+ int64_t request;
+ struct sparse_block *p;
struct tar* tar;
tar = (struct tar *)(a->format->data);
- bytes_skipped = __archive_read_consume(a,
- tar->entry_bytes_remaining + tar->entry_padding +
- tar->entry_bytes_unconsumed);
+ /* Do not consume the hole of a sparse file. */
+ request = 0;
+ for (p = tar->sparse_list; p != NULL; p = p->next) {
+ if (!p->hole) {
+ if (p->remaining >= INT64_MAX - request) {
+ return ARCHIVE_FATAL;
+ }
+ request += p->remaining;
+ }
+ }
+ if (request > tar->entry_bytes_remaining)
+ request = tar->entry_bytes_remaining;
+ request += tar->entry_padding + tar->entry_bytes_unconsumed;
+
+ bytes_skipped = __archive_read_consume(a, request);
if (bytes_skipped < 0)
return (ARCHIVE_FATAL);
@@ -619,36 +643,50 @@ tar_read_header(struct archive_read *a, struct tar *tar,
const struct archive_entry_header_ustar *header;
const struct archive_entry_header_gnutar *gnuheader;
- tar_flush_unconsumed(a, unconsumed);
+ /* Loop until we find a workable header record. */
+ for (;;) {
+ tar_flush_unconsumed(a, unconsumed);
- /* Read 512-byte header record */
- h = __archive_read_ahead(a, 512, &bytes);
- if (bytes < 0)
- return ((int)bytes);
- if (bytes == 0) { /* EOF at a block boundary. */
- /* Some writers do omit the block of nulls. <sigh> */
- return (ARCHIVE_EOF);
- }
- if (bytes < 512) { /* Short block at EOF; this is bad. */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated tar archive");
- return (ARCHIVE_FATAL);
- }
- *unconsumed = 512;
+ /* Read 512-byte header record */
+ h = __archive_read_ahead(a, 512, &bytes);
+ if (bytes < 0)
+ return ((int)bytes);
+ if (bytes == 0) { /* EOF at a block boundary. */
+ /* Some writers do omit the block of nulls. <sigh> */
+ return (ARCHIVE_EOF);
+ }
+ if (bytes < 512) { /* Short block at EOF; this is bad. */
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated tar archive");
+ return (ARCHIVE_FATAL);
+ }
+ *unconsumed = 512;
- /* Check for end-of-archive mark. */
- if (h[0] == 0 && archive_block_is_null(h)) {
- /* Try to consume a second all-null record, as well. */
- tar_flush_unconsumed(a, unconsumed);
- h = __archive_read_ahead(a, 512, NULL);
- if (h != NULL)
- __archive_read_consume(a, 512);
- archive_clear_error(&a->archive);
+ /* Header is workable if it's not an end-of-archive mark. */
+ if (h[0] != 0 || !archive_block_is_null(h))
+ break;
+
+ /* Ensure format is set for archives with only null blocks. */
if (a->archive.archive_format_name == NULL) {
a->archive.archive_format = ARCHIVE_FORMAT_TAR;
a->archive.archive_format_name = "tar";
}
- return (ARCHIVE_EOF);
+
+ if (!tar->read_concatenated_archives) {
+ /* Try to consume a second all-null record, as well. */
+ tar_flush_unconsumed(a, unconsumed);
+ h = __archive_read_ahead(a, 512, NULL);
+ if (h != NULL && h[0] == 0 && archive_block_is_null(h))
+ __archive_read_consume(a, 512);
+ archive_clear_error(&a->archive);
+ return (ARCHIVE_EOF);
+ }
+
+ /*
+ * We're reading concatenated archives, ignore this block and
+ * loop to get the next.
+ */
}
/*
@@ -683,6 +721,8 @@ tar_read_header(struct archive_read *a, struct tar *tar,
a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
a->archive.archive_format_name = "POSIX pax interchange format";
err = header_pax_global(a, tar, entry, h, unconsumed);
+ if (err == ARCHIVE_EOF)
+ return (err);
break;
case 'K': /* Long link name (GNU tar, others) */
err = header_longlink(a, tar, entry, h, unconsumed);
@@ -735,9 +775,9 @@ tar_read_header(struct archive_read *a, struct tar *tar,
* extensions for both the AppleDouble extension entry and the
* regular entry.
*/
- /* TODO: Should this be disabled on non-Mac platforms? */
if ((err == ARCHIVE_WARN || err == ARCHIVE_OK) &&
- tar->header_recursion_depth == 0) {
+ tar->header_recursion_depth == 0 &&
+ tar->process_mac_extensions) {
int err2 = read_mac_metadata_blob(a, tar, entry, h, unconsumed);
if (err2 < err)
err = err2;
@@ -780,12 +820,20 @@ checksum(struct archive_read *a, const void *h)
{
const unsigned char *bytes;
const struct archive_entry_header_ustar *header;
- int check, i, sum;
+ int check, sum;
+ size_t i;
(void)a; /* UNUSED */
bytes = (const unsigned char *)h;
header = (const struct archive_entry_header_ustar *)h;
+ /* Checksum field must hold an octal number */
+ for (i = 0; i < sizeof(header->checksum); ++i) {
+ char c = header->checksum[i];
+ if (c != ' ' && c != '\0' && (c < '0' || c > '7'))
+ return 0;
+ }
+
/*
* Test the checksum. Note that POSIX specifies _unsigned_
* bytes for this calculation.
@@ -1277,7 +1325,7 @@ read_mac_metadata_blob(struct archive_read *a, struct tar *tar,
if (wp[0] == '/' && wp[1] != L'\0')
wname = wp + 1;
}
- /*
+ /*
* If last path element starts with "._", then
* this is a Mac extension.
*/
@@ -1292,7 +1340,7 @@ read_mac_metadata_blob(struct archive_read *a, struct tar *tar,
if (p[0] == '/' && p[1] != '\0')
name = p + 1;
}
- /*
+ /*
* If last path element starts with "._", then
* this is a Mac extension.
*/
@@ -2079,6 +2127,10 @@ gnu_add_sparse_entry(struct archive_read *a, struct tar *tar,
else
tar->sparse_list = p;
tar->sparse_last = p;
+ if (remaining < 0 || offset < 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Malformed sparse map data");
+ return (ARCHIVE_FATAL);
+ }
p->offset = offset;
p->remaining = remaining;
return (ARCHIVE_OK);
@@ -2412,9 +2464,10 @@ tar_atol(const char *p, size_t char_cnt)
static int64_t
tar_atol_base_n(const char *p, size_t char_cnt, int base)
{
- int64_t l, limit, last_digit_limit;
+ int64_t l, maxval, limit, last_digit_limit;
int digit, sign;
+ maxval = INT64_MAX;
limit = INT64_MAX / base;
last_digit_limit = INT64_MAX % base;
@@ -2431,6 +2484,10 @@ tar_atol_base_n(const char *p, size_t char_cnt, int base)
sign = -1;
p++;
char_cnt--;
+
+ maxval = INT64_MIN;
+ limit = -(INT64_MIN / base);
+ last_digit_limit = INT64_MIN % base;
}
l = 0;
@@ -2438,8 +2495,7 @@ tar_atol_base_n(const char *p, size_t char_cnt, int base)
digit = *p - '0';
while (digit >= 0 && digit < base && char_cnt != 0) {
if (l>limit || (l == limit && digit > last_digit_limit)) {
- l = INT64_MAX; /* Truncate on overflow. */
- break;
+ return maxval; /* Truncate on overflow. */
}
l = (l * base) + digit;
digit = *++p - '0';
@@ -2462,36 +2518,56 @@ tar_atol10(const char *p, size_t char_cnt)
}
/*
- * Parse a base-256 integer. This is just a straight signed binary
- * value in big-endian order, except that the high-order bit is
- * ignored.
+ * Parse a base-256 integer. This is just a variable-length
+ * twos-complement signed binary value in big-endian order, except
+ * that the high-order bit is ignored. The values here can be up to
+ * 12 bytes, so we need to be careful about overflowing 64-bit
+ * (8-byte) integers.
+ *
+ * This code unashamedly assumes that the local machine uses 8-bit
+ * bytes and twos-complement arithmetic.
*/
static int64_t
tar_atol256(const char *_p, size_t char_cnt)
{
- int64_t l, upper_limit, lower_limit;
+ uint64_t l;
const unsigned char *p = (const unsigned char *)_p;
+ unsigned char c, neg;
+
+ /* Extend 7-bit 2s-comp to 8-bit 2s-comp, decide sign. */
+ c = *p;
+ if (c & 0x40) {
+ neg = 0xff;
+ c |= 0x80;
+ l = ~ARCHIVE_LITERAL_ULL(0);
+ } else {
+ neg = 0;
+ c &= 0x7f;
+ l = 0;
+ }
+
+ /* If more than 8 bytes, check that we can ignore
+ * high-order bits without overflow. */
+ while (char_cnt > sizeof(int64_t)) {
+ --char_cnt;
+ if (c != neg)
+ return neg ? INT64_MIN : INT64_MAX;
+ c = *++p;
+ }
- upper_limit = INT64_MAX / 256;
- lower_limit = INT64_MIN / 256;
+ /* c is first byte that fits; if sign mismatch, return overflow */
+ if ((c ^ neg) & 0x80) {
+ return neg ? INT64_MIN : INT64_MAX;
+ }
- /* Pad with 1 or 0 bits, depending on sign. */
- if ((0x40 & *p) == 0x40)
- l = (int64_t)-1;
- else
- l = 0;
- l = (l << 6) | (0x3f & *p++);
+ /* Accumulate remaining bytes. */
while (--char_cnt > 0) {
- if (l > upper_limit) {
- l = INT64_MAX; /* Truncate on overflow */
- break;
- } else if (l < lower_limit) {
- l = INT64_MIN;
- break;
- }
- l = (l << 8) | (0xff & (int64_t)*p++);
+ l = (l << 8) | c;
+ c = *++p;
}
- return (l);
+ l = (l << 8) | c;
+ /* Return signed twos-complement value. */
+ return (int64_t)(l);
}
/*
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c
new file mode 100644
index 000000000..57534f3f6
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c
@@ -0,0 +1,794 @@
+/*-
+ * Copyright (c) 2014 Sebastian Freundt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+/**
+ * WARC is standardised by ISO TC46/SC4/WG12 and currently available as
+ * ISO 28500:2009.
+ * For the purposes of this file we used the final draft from:
+ * http://bibnum.bnf.fr/warc/WARC_ISO_28500_version1_latestdraft.pdf
+ *
+ * Todo:
+ * [ ] real-world warcs can contain resources at endpoints ending in /
+ * e.g. http://bibnum.bnf.fr/warc/
+ * if you're lucky their response contains a Content-Location: header
+ * pointing to a unix-compliant filename, in the example above it's
+ * Content-Location: http://bibnum.bnf.fr/warc/index.html
+ * however, that's not mandated and github for example doesn't follow
+ * this convention.
+ * We need a set of archive options to control what to do with
+ * entries like these, at the moment care is taken to skip them.
+ *
+ **/
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+
+typedef enum {
+ WT_NONE,
+ /* warcinfo */
+ WT_INFO,
+ /* metadata */
+ WT_META,
+ /* resource */
+ WT_RSRC,
+ /* request, unsupported */
+ WT_REQ,
+ /* response, unsupported */
+ WT_RSP,
+ /* revisit, unsupported */
+ WT_RVIS,
+ /* conversion, unsupported */
+ WT_CONV,
+ /* continutation, unsupported at the moment */
+ WT_CONT,
+ /* invalid type */
+ LAST_WT
+} warc_type_t;
+
+typedef struct {
+ size_t len;
+ const char *str;
+} warc_string_t;
+
+typedef struct {
+ size_t len;
+ char *str;
+} warc_strbuf_t;
+
+struct warc_s {
+ /* content length ahead */
+ size_t cntlen;
+ /* and how much we've processed so far */
+ size_t cntoff;
+ /* and how much we need to consume between calls */
+ size_t unconsumed;
+
+ /* string pool */
+ warc_strbuf_t pool;
+ /* previous version */
+ unsigned int pver;
+ /* stringified format name */
+ struct archive_string sver;
+};
+
+static int _warc_bid(struct archive_read *a, int);
+static int _warc_cleanup(struct archive_read *a);
+static int _warc_read(struct archive_read*, const void**, size_t*, int64_t*);
+static int _warc_skip(struct archive_read *a);
+static int _warc_rdhdr(struct archive_read *a, struct archive_entry *e);
+
+/* private routines */
+static unsigned int _warc_rdver(const char buf[10], size_t bsz);
+static unsigned int _warc_rdtyp(const char *buf, size_t bsz);
+static warc_string_t _warc_rduri(const char *buf, size_t bsz);
+static ssize_t _warc_rdlen(const char *buf, size_t bsz);
+static time_t _warc_rdrtm(const char *buf, size_t bsz);
+static time_t _warc_rdmtm(const char *buf, size_t bsz);
+static const char *_warc_find_eoh(const char *buf, size_t bsz);
+
+
+int
+archive_read_support_format_warc(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct warc_s *w;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_warc");
+
+ if ((w = malloc(sizeof(*w))) == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate warc data");
+ return (ARCHIVE_FATAL);
+ }
+ memset(w, 0, sizeof(*w));
+
+ r = __archive_read_register_format(
+ a, w, "warc",
+ _warc_bid, NULL, _warc_rdhdr, _warc_read,
+ _warc_skip, NULL, _warc_cleanup, NULL, NULL);
+
+ if (r != ARCHIVE_OK) {
+ free(w);
+ return (r);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+_warc_cleanup(struct archive_read *a)
+{
+ struct warc_s *w = a->format->data;
+
+ if (w->pool.len > 0U) {
+ free(w->pool.str);
+ }
+ archive_string_free(&w->sver);
+ free(w);
+ a->format->data = NULL;
+ return (ARCHIVE_OK);
+}
+
+static int
+_warc_bid(struct archive_read *a, int best_bid)
+{
+ const char *hdr;
+ ssize_t nrd;
+ unsigned int ver;
+
+ (void)best_bid; /* UNUSED */
+
+ /* check first line of file, it should be a record already */
+ if ((hdr = __archive_read_ahead(a, 12U, &nrd)) == NULL) {
+ /* no idea what to do */
+ return -1;
+ } else if (nrd < 12) {
+ /* nah, not for us, our magic cookie is at least 12 bytes */
+ return -1;
+ }
+
+ /* otherwise snarf the record's version number */
+ ver = _warc_rdver(hdr, nrd);
+ if (ver == 0U || ver > 10000U) {
+ /* oh oh oh, best not to wager ... */
+ return -1;
+ }
+
+ /* otherwise be confident */
+ return (64);
+}
+
+static int
+_warc_rdhdr(struct archive_read *a, struct archive_entry *entry)
+{
+#define HDR_PROBE_LEN (12U)
+ struct warc_s *w = a->format->data;
+ unsigned int ver;
+ const char *buf;
+ ssize_t nrd;
+ const char *eoh;
+ /* for the file name, saves some strndup()'ing */
+ warc_string_t fnam;
+ /* warc record type, not that we really use it a lot */
+ warc_type_t ftyp;
+ /* content-length+error monad */
+ ssize_t cntlen;
+ /* record time is the WARC-Date time we reinterpret it as ctime */
+ time_t rtime;
+ /* mtime is the Last-Modified time which will be the entry's mtime */
+ time_t mtime;
+
+start_over:
+ /* just use read_ahead() they keep track of unconsumed
+ * bits and bobs for us; no need to put an extra shift in
+ * and reproduce that functionality here */
+ buf = __archive_read_ahead(a, HDR_PROBE_LEN, &nrd);
+
+ if (nrd < 0) {
+ /* no good */
+ archive_set_error(
+ &a->archive, ARCHIVE_ERRNO_MISC,
+ "Bad record header");
+ return (ARCHIVE_FATAL);
+ } else if (buf == NULL) {
+ /* there should be room for at least WARC/bla\r\n
+ * must be EOF therefore */
+ return (ARCHIVE_EOF);
+ }
+ /* looks good so far, try and find the end of the header now */
+ eoh = _warc_find_eoh(buf, nrd);
+ if (eoh == NULL) {
+ /* still no good, the header end might be beyond the
+ * probe we've requested, but then again who'd cram
+ * so much stuff into the header *and* be 28500-compliant */
+ archive_set_error(
+ &a->archive, ARCHIVE_ERRNO_MISC,
+ "Bad record header");
+ return (ARCHIVE_FATAL);
+ } else if ((ver = _warc_rdver(buf, eoh - buf)) > 10000U) {
+ /* nawww, I wish they promised backward compatibility
+ * anyhoo, in their infinite wisdom the 28500 guys might
+ * come up with something we can't possibly handle so
+ * best end things here */
+ archive_set_error(
+ &a->archive, ARCHIVE_ERRNO_MISC,
+ "Unsupported record version");
+ return (ARCHIVE_FATAL);
+ } else if ((cntlen = _warc_rdlen(buf, eoh - buf)) < 0) {
+ /* nightmare! the specs say content-length is mandatory
+ * so I don't feel overly bad stopping the reader here */
+ archive_set_error(
+ &a->archive, EINVAL,
+ "Bad content length");
+ return (ARCHIVE_FATAL);
+ } else if ((rtime = _warc_rdrtm(buf, eoh - buf)) == (time_t)-1) {
+ /* record time is mandatory as per WARC/1.0,
+ * so just barf here, fast and loud */
+ archive_set_error(
+ &a->archive, EINVAL,
+ "Bad record time");
+ return (ARCHIVE_FATAL);
+ }
+
+ /* let the world know we're a WARC archive */
+ a->archive.archive_format = ARCHIVE_FORMAT_WARC;
+ if (ver != w->pver) {
+ /* stringify this entry's version */
+ archive_string_sprintf(&w->sver,
+ "WARC/%u.%u", ver / 10000, ver % 10000);
+ /* remember the version */
+ w->pver = ver;
+ }
+ /* start off with the type */
+ ftyp = _warc_rdtyp(buf, eoh - buf);
+ /* and let future calls know about the content */
+ w->cntlen = cntlen;
+ w->cntoff = 0U;
+ mtime = 0;/* Avoid compiling error on some platform. */
+
+ switch (ftyp) {
+ case WT_RSRC:
+ case WT_RSP:
+ /* only try and read the filename in the cases that are
+ * guaranteed to have one */
+ fnam = _warc_rduri(buf, eoh - buf);
+ /* check the last character in the URI to avoid creating
+ * directory endpoints as files, see Todo above */
+ if (fnam.len == 0 || fnam.str[fnam.len - 1] == '/') {
+ /* break here for now */
+ fnam.len = 0U;
+ fnam.str = NULL;
+ break;
+ }
+ /* bang to our string pool, so we save a
+ * malloc()+free() roundtrip */
+ if (fnam.len + 1U > w->pool.len) {
+ w->pool.len = ((fnam.len + 64U) / 64U) * 64U;
+ w->pool.str = realloc(w->pool.str, w->pool.len);
+ }
+ memcpy(w->pool.str, fnam.str, fnam.len);
+ w->pool.str[fnam.len] = '\0';
+ /* let noone else know about the pool, it's a secret, shhh */
+ fnam.str = w->pool.str;
+
+ /* snarf mtime or deduce from rtime
+ * this is a custom header added by our writer, it's quite
+ * hard to believe anyone else would go through with it
+ * (apart from being part of some http responses of course) */
+ if ((mtime = _warc_rdmtm(buf, eoh - buf)) == (time_t)-1) {
+ mtime = rtime;
+ }
+ break;
+ default:
+ fnam.len = 0U;
+ fnam.str = NULL;
+ break;
+ }
+
+ /* now eat some of those delicious buffer bits */
+ __archive_read_consume(a, eoh - buf);
+
+ switch (ftyp) {
+ case WT_RSRC:
+ case WT_RSP:
+ if (fnam.len > 0U) {
+ /* populate entry object */
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_copy_pathname(entry, fnam.str);
+ archive_entry_set_size(entry, cntlen);
+ archive_entry_set_perm(entry, 0644);
+ /* rtime is the new ctime, mtime stays mtime */
+ archive_entry_set_ctime(entry, rtime, 0L);
+ archive_entry_set_mtime(entry, mtime, 0L);
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
+ /* consume the content and start over */
+ _warc_skip(a);
+ goto start_over;
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+_warc_read(struct archive_read *a, const void **buf, size_t *bsz, int64_t *off)
+{
+ struct warc_s *w = a->format->data;
+ const char *rab;
+ ssize_t nrd;
+
+ if (w->cntoff >= w->cntlen) {
+ eof:
+ /* it's our lucky day, no work, we can leave early */
+ *buf = NULL;
+ *bsz = 0U;
+ *off = w->cntoff + 4U/*for \r\n\r\n separator*/;
+ w->unconsumed = 0U;
+ return (ARCHIVE_EOF);
+ }
+
+ rab = __archive_read_ahead(a, 1U, &nrd);
+ if (nrd < 0) {
+ *bsz = 0U;
+ /* big catastrophe */
+ return (int)nrd;
+ } else if (nrd == 0) {
+ goto eof;
+ } else if ((size_t)nrd > w->cntlen - w->cntoff) {
+ /* clamp to content-length */
+ nrd = w->cntlen - w->cntoff;
+ }
+ *off = w->cntoff;
+ *bsz = nrd;
+ *buf = rab;
+
+ w->cntoff += nrd;
+ w->unconsumed = (size_t)nrd;
+ return (ARCHIVE_OK);
+}
+
+static int
+_warc_skip(struct archive_read *a)
+{
+ struct warc_s *w = a->format->data;
+
+ __archive_read_consume(a, w->cntlen + 4U/*\r\n\r\n separator*/);
+ w->cntlen = 0U;
+ w->cntoff = 0U;
+ return (ARCHIVE_OK);
+}
+
+
+/* private routines */
+static void*
+deconst(const void *c)
+{
+ return (char *)0x1 + (((const char *)c) - (const char *)0x1);
+}
+
+static char*
+xmemmem(const char *hay, const size_t hz_, const char *ndl, const size_t nz)
+{
+ const char *const eoh = hay + hz_;
+ const char *const eon = ndl + nz;
+ const char *hp;
+ const char *np;
+ const char *cand;
+ unsigned int hsum;
+ unsigned int nsum;
+ unsigned int eqp;
+
+ /* trivial checks first
+ * a 0-sized needle is defined to be found anywhere in haystack
+ * then run strchr() to find a candidate in HAYSTACK (i.e. a portion
+ * that happens to begin with *NEEDLE) */
+ if (nz == 0UL) {
+ return deconst(hay);
+ } else if ((hay = memchr(hay, *ndl, hz_)) == NULL) {
+ /* trivial */
+ return NULL;
+ }
+
+ /* First characters of haystack and needle are the same now. Both are
+ * guaranteed to be at least one character long. Now computes the sum
+ * of characters values of needle together with the sum of the first
+ * needle_len characters of haystack. */
+ for (hp = hay + 1U, np = ndl + 1U, hsum = *hay, nsum = *hay, eqp = 1U;
+ hp < eoh && np < eon;
+ hsum ^= *hp, nsum ^= *np, eqp &= *hp == *np, hp++, np++);
+
+ /* HP now references the (NZ + 1)-th character. */
+ if (np < eon) {
+ /* haystack is smaller than needle, :O */
+ return NULL;
+ } else if (eqp) {
+ /* found a match */
+ return deconst(hay);
+ }
+
+ /* now loop through the rest of haystack,
+ * updating the sum iteratively */
+ for (cand = hay; hp < eoh; hp++) {
+ hsum ^= *cand++;
+ hsum ^= *hp;
+
+ /* Since the sum of the characters is already known to be
+ * equal at that point, it is enough to check just NZ - 1
+ * characters for equality,
+ * also CAND is by design < HP, so no need for range checks */
+ if (hsum == nsum && memcmp(cand, ndl, nz - 1U) == 0) {
+ return deconst(cand);
+ }
+ }
+ return NULL;
+}
+
+static int
+strtoi_lim(const char *str, const char **ep, int llim, int ulim)
+{
+ int res = 0;
+ const char *sp;
+ /* we keep track of the number of digits via rulim */
+ int rulim;
+
+ for (sp = str, rulim = ulim > 10 ? ulim : 10;
+ res * 10 <= ulim && rulim && *sp >= '0' && *sp <= '9';
+ sp++, rulim /= 10) {
+ res *= 10;
+ res += *sp - '0';
+ }
+ if (sp == str) {
+ res = -1;
+ } else if (res < llim || res > ulim) {
+ res = -2;
+ }
+ *ep = (const char*)sp;
+ return res;
+}
+
+static time_t
+time_from_tm(struct tm *t)
+{
+#if HAVE_TIMEGM
+ /* Use platform timegm() if available. */
+ return (timegm(t));
+#elif HAVE__MKGMTIME64
+ return (_mkgmtime64(t));
+#else
+ /* Else use direct calculation using POSIX assumptions. */
+ /* First, fix up tm_yday based on the year/month/day. */
+ if (mktime(t) == (time_t)-1)
+ return ((time_t)-1);
+ /* Then we can compute timegm() from first principles. */
+ return (t->tm_sec
+ + t->tm_min * 60
+ + t->tm_hour * 3600
+ + t->tm_yday * 86400
+ + (t->tm_year - 70) * 31536000
+ + ((t->tm_year - 69) / 4) * 86400
+ - ((t->tm_year - 1) / 100) * 86400
+ + ((t->tm_year + 299) / 400) * 86400);
+#endif
+}
+
+static time_t
+xstrpisotime(const char *s, char **endptr)
+{
+/** like strptime() but strictly for ISO 8601 Zulu strings */
+ struct tm tm;
+ time_t res = (time_t)-1;
+
+ /* make sure tm is clean */
+ memset(&tm, 0, sizeof(tm));
+
+ /* as a courtesy to our callers, and since this is a non-standard
+ * routine, we skip leading whitespace */
+ for (; isspace(*s); s++);
+
+ /* read year */
+ if ((tm.tm_year = strtoi_lim(s, &s, 1583, 4095)) < 0 || *s++ != '-') {
+ goto out;
+ }
+ /* read month */
+ if ((tm.tm_mon = strtoi_lim(s, &s, 1, 12)) < 0 || *s++ != '-') {
+ goto out;
+ }
+ /* read day-of-month */
+ if ((tm.tm_mday = strtoi_lim(s, &s, 1, 31)) < 0 || *s++ != 'T') {
+ goto out;
+ }
+ /* read hour */
+ if ((tm.tm_hour = strtoi_lim(s, &s, 0, 23)) < 0 || *s++ != ':') {
+ goto out;
+ }
+ /* read minute */
+ if ((tm.tm_min = strtoi_lim(s, &s, 0, 59)) < 0 || *s++ != ':') {
+ goto out;
+ }
+ /* read second */
+ if ((tm.tm_sec = strtoi_lim(s, &s, 0, 60)) < 0 || *s++ != 'Z') {
+ goto out;
+ }
+
+ /* massage TM to fulfill some of POSIX' contraints */
+ tm.tm_year -= 1900;
+ tm.tm_mon--;
+
+ /* now convert our custom tm struct to a unix stamp using UTC */
+ res = time_from_tm(&tm);
+
+out:
+ if (endptr != NULL) {
+ *endptr = deconst(s);
+ }
+ return res;
+}
+
+static unsigned int
+_warc_rdver(const char buf[10], size_t bsz)
+{
+ static const char magic[] = "WARC/";
+ unsigned int ver;
+
+ (void)bsz; /* UNUSED */
+
+ if (memcmp(buf, magic, sizeof(magic) - 1U) != 0) {
+ /* nope */
+ return 99999U;
+ }
+ /* looks good so far, read the version number for a laugh */
+ buf += sizeof(magic) - 1U;
+ /* most common case gets a quick-check here */
+ if (memcmp(buf, "1.0\r\n", 5U) == 0) {
+ ver = 10000U;
+ } else {
+ switch (*buf) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ if (buf[1U] == '.') {
+ char *on;
+
+ /* set up major version */
+ ver = (buf[0U] - '0') * 10000U;
+ /* minor version, anyone? */
+ ver += (strtol(buf + 2U, &on, 10)) * 100U;
+ /* don't parse anything else */
+ if (on > buf + 2U) {
+ break;
+ }
+ }
+ /* FALLTHROUGH */
+ case '9':
+ default:
+ /* just make the version ridiculously high */
+ ver = 999999U;
+ break;
+ }
+ }
+ return ver;
+}
+
+static unsigned int
+_warc_rdtyp(const char *buf, size_t bsz)
+{
+ static const char _key[] = "\r\nWARC-Type:";
+ const char *const eob = buf + bsz;
+ const char *val;
+
+ if ((val = xmemmem(buf, bsz, _key, sizeof(_key) - 1U)) == NULL) {
+ /* no bother */
+ return WT_NONE;
+ }
+ /* overread whitespace */
+ for (val += sizeof(_key) - 1U; val < eob && isspace(*val); val++);
+
+ if (val + 8U > eob) {
+ ;
+ } else if (memcmp(val, "resource", 8U) == 0) {
+ return WT_RSRC;
+ } else if (memcmp(val, "warcinfo", 8U) == 0) {
+ return WT_INFO;
+ } else if (memcmp(val, "metadata", 8U) == 0) {
+ return WT_META;
+ } else if (memcmp(val, "request", 7U) == 0) {
+ return WT_REQ;
+ } else if (memcmp(val, "response", 8U) == 0) {
+ return WT_RSP;
+ } else if (memcmp(val, "conversi", 8U) == 0) {
+ return WT_CONV;
+ } else if (memcmp(val, "continua", 8U) == 0) {
+ return WT_CONT;
+ }
+ return WT_NONE;
+}
+
+static warc_string_t
+_warc_rduri(const char *buf, size_t bsz)
+{
+ static const char _key[] = "\r\nWARC-Target-URI:";
+ const char *const eob = buf + bsz;
+ const char *val;
+ const char *uri;
+ const char *eol;
+ warc_string_t res = {0U, NULL};
+
+ if ((val = xmemmem(buf, bsz, _key, sizeof(_key) - 1U)) == NULL) {
+ /* no bother */
+ return res;
+ }
+ /* overread whitespace */
+ for (val += sizeof(_key) - 1U; val < eob && isspace(*val); val++);
+
+ /* overread URL designators */
+ if ((uri = xmemmem(val, eob - val, "://", 3U)) == NULL) {
+ /* not touching that! */
+ return res;
+ } else if ((eol = memchr(uri, '\n', eob - uri)) == NULL) {
+ /* no end of line? :O */
+ return res;
+ }
+
+ /* massage uri to point to after :// */
+ uri += 3U;
+ /* also massage eol to point to the first whitespace
+ * after the last non-whitespace character before
+ * the end of the line */
+ for (; eol > uri && isspace(eol[-1]); eol--);
+
+ /* now then, inspect the URI */
+ if (memcmp(val, "file", 4U) == 0) {
+ /* perfect, nothing left to do here */
+
+ } else if (memcmp(val, "http", 4U) == 0 ||
+ memcmp(val, "ftp", 3U) == 0) {
+ /* overread domain, and the first / */
+ while (uri < eol && *uri++ != '/');
+ } else {
+ /* not sure what to do? best to bugger off */
+ return res;
+ }
+ res.str = uri;
+ res.len = eol - uri;
+ return res;
+}
+
+static ssize_t
+_warc_rdlen(const char *buf, size_t bsz)
+{
+ static const char _key[] = "\r\nContent-Length:";
+ const char *val;
+ char *on = NULL;
+ long int len;
+
+ if ((val = xmemmem(buf, bsz, _key, sizeof(_key) - 1U)) == NULL) {
+ /* no bother */
+ return -1;
+ }
+
+ /* strtol kindly overreads whitespace for us, so use that */
+ val += sizeof(_key) - 1U;
+ len = strtol(val, &on, 10);
+ if (on == NULL || !isspace(*on)) {
+ /* hm, can we trust that number? Best not. */
+ return -1;
+ }
+ return (size_t)len;
+}
+
+static time_t
+_warc_rdrtm(const char *buf, size_t bsz)
+{
+ static const char _key[] = "\r\nWARC-Date:";
+ const char *val;
+ char *on = NULL;
+ time_t res;
+
+ if ((val = xmemmem(buf, bsz, _key, sizeof(_key) - 1U)) == NULL) {
+ /* no bother */
+ return (time_t)-1;
+ }
+
+ /* xstrpisotime() kindly overreads whitespace for us, so use that */
+ val += sizeof(_key) - 1U;
+ res = xstrpisotime(val, &on);
+ if (on == NULL || !isspace(*on)) {
+ /* hm, can we trust that number? Best not. */
+ return (time_t)-1;
+ }
+ return res;
+}
+
+static time_t
+_warc_rdmtm(const char *buf, size_t bsz)
+{
+ static const char _key[] = "\r\nLast-Modified:";
+ const char *val;
+ char *on = NULL;
+ time_t res;
+
+ if ((val = xmemmem(buf, bsz, _key, sizeof(_key) - 1U)) == NULL) {
+ /* no bother */
+ return (time_t)-1;
+ }
+
+ /* xstrpisotime() kindly overreads whitespace for us, so use that */
+ val += sizeof(_key) - 1U;
+ res = xstrpisotime(val, &on);
+ if (on == NULL || !isspace(*on)) {
+ /* hm, can we trust that number? Best not. */
+ return (time_t)-1;
+ }
+ return res;
+}
+
+static const char*
+_warc_find_eoh(const char *buf, size_t bsz)
+{
+ static const char _marker[] = "\r\n\r\n";
+ const char *hit = xmemmem(buf, bsz, _marker, sizeof(_marker) - 1U);
+
+ if (hit != NULL) {
+ hit += sizeof(_marker) - 1U;
+ }
+ return hit;
+}
+
+/* archive_read_support_format_warc.c ends here */
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
index 2530e34e1..bbef99f88 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
@@ -42,7 +42,7 @@ __FBSDID("$FreeBSD$");
#include <cm_bzlib.h>
#endif
#if HAVE_LZMA_H
-#include <lzma.h>
+#include <cm_lzma.h>
#elif HAVE_LZMADEC_H
#include <lzmadec.h>
#endif
@@ -51,7 +51,7 @@ __FBSDID("$FreeBSD$");
#endif
#include "archive.h"
-#include "archive_crypto_private.h"
+#include "archive_digest_private.h"
#include "archive_endian.h"
#include "archive_entry.h"
#include "archive_entry_locale.h"
@@ -468,7 +468,9 @@ archive_read_support_format_xar(struct archive *_a)
xar_read_data,
xar_read_data_skip,
NULL,
- xar_cleanup);
+ xar_cleanup,
+ NULL,
+ NULL);
if (r != ARCHIVE_OK)
free(xar);
return (r);
@@ -967,10 +969,14 @@ move_reading_point(struct archive_read *a, uint64_t offset)
return ((int)step);
xar->offset += step;
} else {
- archive_set_error(&(a->archive),
- ARCHIVE_ERRNO_MISC,
- "Cannot seek.");
- return (ARCHIVE_FAILED);
+ int64_t pos = __archive_read_seek(a, offset, SEEK_SET);
+ if (pos == ARCHIVE_FAILED) {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Cannot seek.");
+ return (ARCHIVE_FAILED);
+ }
+ xar->offset = pos;
}
}
return (ARCHIVE_OK);
@@ -1101,20 +1107,23 @@ static time_t
time_from_tm(struct tm *t)
{
#if HAVE_TIMEGM
- /* Use platform timegm() if available. */
- return (timegm(t));
+ /* Use platform timegm() if available. */
+ return (timegm(t));
#elif HAVE__MKGMTIME64
- return (_mkgmtime64(t));
+ return (_mkgmtime64(t));
#else
- /* Else use direct calculation using POSIX assumptions. */
- /* First, fix up tm_yday based on the year/month/day. */
- mktime(t);
- /* Then we can compute timegm() from first principles. */
- return (t->tm_sec + t->tm_min * 60 + t->tm_hour * 3600
- + t->tm_yday * 86400 + (t->tm_year - 70) * 31536000
- + ((t->tm_year - 69) / 4) * 86400 -
- ((t->tm_year - 1) / 100) * 86400
- + ((t->tm_year + 299) / 400) * 86400);
+ /* Else use direct calculation using POSIX assumptions. */
+ /* First, fix up tm_yday based on the year/month/day. */
+ mktime(t);
+ /* Then we can compute timegm() from first principles. */
+ return (t->tm_sec
+ + t->tm_min * 60
+ + t->tm_hour * 3600
+ + t->tm_yday * 86400
+ + (t->tm_year - 70) * 31536000
+ + ((t->tm_year - 69) / 4) * 86400
+ - ((t->tm_year - 1) / 100) * 86400
+ + ((t->tm_year + 299) / 400) * 86400);
#endif
}
@@ -3183,9 +3192,8 @@ xml2_read_toc(struct archive_read *a)
case XML_READER_TYPE_ELEMENT:
empty = xmlTextReaderIsEmptyElement(reader);
r = xml2_xmlattr_setup(a, &list, reader);
- if (r != ARCHIVE_OK)
- return (r);
- r = xml_start(a, name, &list);
+ if (r == ARCHIVE_OK)
+ r = xml_start(a, name, &list);
xmlattr_cleanup(&list);
if (r != ARCHIVE_OK)
return (r);
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
index 2fdc08b6a..62bf5e3fb 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
@@ -1,6 +1,7 @@
/*-
- * Copyright (c) 2004 Tim Kientzle
- * Copyright (c) 2011-2012 Michihiro NAKAJIMA
+ * Copyright (c) 2004-2013 Tim Kientzle
+ * Copyright (c) 2011-2012,2014 Michihiro NAKAJIMA
+ * Copyright (c) 2013 Konrad Kleine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,6 +28,20 @@
#include "archive_platform.h"
__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_zip.c 201102 2009-12-28 03:11:36Z kientzle $");
+/*
+ * The definitive documentation of the Zip file format is:
+ * http://www.pkware.com/documents/casestudies/APPNOTE.TXT
+ *
+ * The Info-Zip project has pioneered various extensions to better
+ * support Zip on Unix, including the 0x5455 "UT", 0x5855 "UX", 0x7855
+ * "Ux", and 0x7875 "ux" extensions for time and ownership
+ * information.
+ *
+ * History of this code: The streaming Zip reader was first added to
+ * libarchive in January 2005. Support for seekable input sources was
+ * added in Nov 2011.
+ */
+
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
@@ -38,9 +53,12 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_zip.c 201102
#endif
#include "archive.h"
+#include "archive_digest_private.h"
+#include "archive_cryptor_private.h"
#include "archive_endian.h"
#include "archive_entry.h"
#include "archive_entry_locale.h"
+#include "archive_hmac_private.h"
#include "archive_private.h"
#include "archive_rb.h"
#include "archive_read_private.h"
@@ -51,42 +69,85 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_zip.c 201102
struct zip_entry {
struct archive_rb_node node;
+ struct zip_entry *next;
int64_t local_header_offset;
int64_t compressed_size;
int64_t uncompressed_size;
int64_t gid;
int64_t uid;
- struct archive_entry *entry;
struct archive_string rsrcname;
time_t mtime;
time_t atime;
time_t ctime;
uint32_t crc32;
uint16_t mode;
- uint16_t flags;
- char compression;
- char system;
+ uint16_t zip_flags; /* From GP Flags Field */
+ unsigned char compression;
+ unsigned char system; /* From "version written by" */
+ unsigned char flags; /* Our extra markers. */
+ unsigned char decdat;/* Used for Decryption check */
+
+ /* WinZip AES encryption extra field should be available
+ * when compression is 99. */
+ struct {
+ /* Vendor version: AE-1 - 0x0001, AE-2 - 0x0002 */
+ unsigned vendor;
+#define AES_VENDOR_AE_1 0x0001
+#define AES_VENDOR_AE_2 0x0002
+ /* AES encryption strength:
+ * 1 - 128 bits, 2 - 192 bits, 2 - 256 bits. */
+ unsigned strength;
+ /* Actual compression method. */
+ unsigned char compression;
+ } aes_extra;
+};
+
+struct trad_enc_ctx {
+ uint32_t keys[3];
};
+/* Bits used in zip_flags. */
+#define ZIP_ENCRYPTED (1 << 0)
+#define ZIP_LENGTH_AT_END (1 << 3)
+#define ZIP_STRONG_ENCRYPTED (1 << 6)
+#define ZIP_UTF8_NAME (1 << 11)
+/* See "7.2 Single Password Symmetric Encryption Method"
+ in http://www.pkware.com/documents/casestudies/APPNOTE.TXT */
+#define ZIP_CENTRAL_DIRECTORY_ENCRYPTED (1 << 13)
+
+/* Bits used in flags. */
+#define LA_USED_ZIP64 (1 << 0)
+#define LA_FROM_CENTRAL_DIRECTORY (1 << 1)
+
+/*
+ * See "WinZip - AES Encryption Information"
+ * http://www.winzip.com/aes_info.htm
+ */
+/* Value used in compression method. */
+#define WINZIP_AES_ENCRYPTION 99
+/* Authentication code size. */
+#define AUTH_CODE_SIZE 10
+/**/
+#define MAX_DERIVED_KEY_BUF_SIZE (AES_MAX_KEY_SIZE * 2 + 2)
+
struct zip {
/* Structural information about the archive. */
- int64_t end_of_central_directory_offset;
+ struct archive_string format_name;
int64_t central_directory_offset;
- size_t central_directory_size;
- size_t central_directory_entries;
- char have_central_directory;
- int64_t offset;
+ size_t central_directory_entries_total;
+ size_t central_directory_entries_on_this_disk;
+ int has_encrypted_entries;
/* List of entries (seekable Zip only) */
- size_t entries_remaining;
struct zip_entry *zip_entries;
- struct zip_entry *entry;
struct archive_rb_tree tree;
struct archive_rb_tree tree_rsrc;
+ /* Bytes read but not yet consumed via __archive_read_consume() */
size_t unconsumed;
- /* entry_bytes_remaining is the number of bytes we expect. */
+ /* Information about entry we're currently reading. */
+ struct zip_entry *entry;
int64_t entry_bytes_remaining;
/* These count the number of bytes actually read for the entry. */
@@ -95,852 +156,549 @@ struct zip {
/* Running CRC32 of the decompressed data */
unsigned long entry_crc32;
+ unsigned long (*crc32func)(unsigned long, const void *,
+ size_t);
+ char ignore_crc32;
/* Flags to mark progress of decompression. */
char decompress_init;
char end_of_entry;
- ssize_t filename_length;
- ssize_t extra_length;
-
+#ifdef HAVE_ZLIB_H
unsigned char *uncompressed_buffer;
size_t uncompressed_buffer_size;
-#ifdef HAVE_ZLIB_H
z_stream stream;
char stream_valid;
#endif
- struct archive_string extra;
struct archive_string_conv *sconv;
struct archive_string_conv *sconv_default;
struct archive_string_conv *sconv_utf8;
int init_default_conversion;
- char format_name[64];
+ int process_mac_extensions;
+
+ char init_decryption;
+
+ /* Decryption buffer. */
+ unsigned char *decrypted_buffer;
+ unsigned char *decrypted_ptr;
+ size_t decrypted_buffer_size;
+ size_t decrypted_bytes_remaining;
+ size_t decrypted_unconsumed_bytes;
+
+ /* Traditional PKWARE decryption. */
+ struct trad_enc_ctx tctx;
+ char tctx_valid;
+
+ /* WinZip AES decyption. */
+ /* Contexts used for AES decryption. */
+ archive_crypto_ctx cctx;
+ char cctx_valid;
+ archive_hmac_sha1_ctx hctx;
+ char hctx_valid;
+
+ /* Strong encryption's decryption header information. */
+ unsigned iv_size;
+ unsigned alg_id;
+ unsigned bit_len;
+ unsigned flags;
+ unsigned erd_size;
+ unsigned v_size;
+ unsigned v_crc32;
+ uint8_t *iv;
+ uint8_t *erd;
+ uint8_t *v_data;
};
-#define ZIP_LENGTH_AT_END 8
-#define ZIP_ENCRYPTED (1<<0)
-#define ZIP_STRONG_ENCRYPTED (1<<6)
-#define ZIP_UTF8_NAME (1<<11)
-
-static int archive_read_format_zip_streamable_bid(struct archive_read *,
- int);
-static int archive_read_format_zip_seekable_bid(struct archive_read *,
- int);
-static int archive_read_format_zip_options(struct archive_read *,
- const char *, const char *);
-static int archive_read_format_zip_cleanup(struct archive_read *);
-static int archive_read_format_zip_read_data(struct archive_read *,
- const void **, size_t *, int64_t *);
-static int archive_read_format_zip_read_data_skip(struct archive_read *a);
-static int archive_read_format_zip_seekable_read_header(
- struct archive_read *, struct archive_entry *);
-static int archive_read_format_zip_streamable_read_header(
- struct archive_read *, struct archive_entry *);
-static ssize_t zip_get_local_file_header_size(struct archive_read *, size_t);
-#ifdef HAVE_ZLIB_H
-static int zip_deflate_init(struct archive_read *, struct zip *);
-static int zip_read_data_deflate(struct archive_read *a, const void **buff,
- size_t *size, int64_t *offset);
-#endif
-static int zip_read_data_none(struct archive_read *a, const void **buff,
- size_t *size, int64_t *offset);
-static int zip_read_local_file_header(struct archive_read *a,
- struct archive_entry *entry, struct zip *);
-static time_t zip_time(const char *);
-static const char *compression_name(int compression);
-static void process_extra(const char *, size_t, struct zip_entry *);
+/* Many systems define min or MIN, but not all. */
+#define zipmin(a,b) ((a) < (b) ? (a) : (b))
-int archive_read_support_format_zip_streamable(struct archive *);
-int archive_read_support_format_zip_seekable(struct archive *);
+/* ------------------------------------------------------------------------ */
-int
-archive_read_support_format_zip_streamable(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
- struct zip *zip;
- int r;
-
- archive_check_magic(_a, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_support_format_zip");
-
- zip = (struct zip *)malloc(sizeof(*zip));
- if (zip == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate zip data");
- return (ARCHIVE_FATAL);
- }
- memset(zip, 0, sizeof(*zip));
+/*
+ Traditional PKWARE Decryption functions.
+ */
- r = __archive_read_register_format(a,
- zip,
- "zip",
- archive_read_format_zip_streamable_bid,
- archive_read_format_zip_options,
- archive_read_format_zip_streamable_read_header,
- archive_read_format_zip_read_data,
- archive_read_format_zip_read_data_skip,
- NULL,
- archive_read_format_zip_cleanup);
+static void
+trad_enc_update_keys(struct trad_enc_ctx *ctx, uint8_t c)
+{
+ uint8_t t;
+#define CRC32(c, b) (crc32(c ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL)
+
+ ctx->keys[0] = CRC32(ctx->keys[0], c);
+ ctx->keys[1] = (ctx->keys[1] + (ctx->keys[0] & 0xff)) * 134775813L + 1;
+ t = (ctx->keys[1] >> 24) & 0xff;
+ ctx->keys[2] = CRC32(ctx->keys[2], t);
+#undef CRC32
+}
- if (r != ARCHIVE_OK)
- free(zip);
- return (ARCHIVE_OK);
+static uint8_t
+trad_enc_decypt_byte(struct trad_enc_ctx *ctx)
+{
+ unsigned temp = ctx->keys[2] | 2;
+ return (uint8_t)((temp * (temp ^ 1)) >> 8) & 0xff;
}
-int
-archive_read_support_format_zip_seekable(struct archive *_a)
+static void
+trad_enc_decrypt_update(struct trad_enc_ctx *ctx, const uint8_t *in,
+ size_t in_len, uint8_t *out, size_t out_len)
{
- struct archive_read *a = (struct archive_read *)_a;
- struct zip *zip;
- int r;
+ unsigned i, max;
- archive_check_magic(_a, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_support_format_zip_seekable");
+ max = (unsigned)((in_len < out_len)? in_len: out_len);
- zip = (struct zip *)malloc(sizeof(*zip));
- if (zip == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate zip data");
- return (ARCHIVE_FATAL);
+ for (i = 0; i < max; i++) {
+ uint8_t t = in[i] ^ trad_enc_decypt_byte(ctx);
+ out[i] = t;
+ trad_enc_update_keys(ctx, t);
}
- memset(zip, 0, sizeof(*zip));
-
- r = __archive_read_register_format(a,
- zip,
- "zip",
- archive_read_format_zip_seekable_bid,
- archive_read_format_zip_options,
- archive_read_format_zip_seekable_read_header,
- archive_read_format_zip_read_data,
- archive_read_format_zip_read_data_skip,
- NULL,
- archive_read_format_zip_cleanup);
-
- if (r != ARCHIVE_OK)
- free(zip);
- return (ARCHIVE_OK);
}
-int
-archive_read_support_format_zip(struct archive *a)
-{
- int r;
- r = archive_read_support_format_zip_streamable(a);
- if (r != ARCHIVE_OK)
- return r;
- return (archive_read_support_format_zip_seekable(a));
-}
-
-/*
- * TODO: This is a performance sink because it forces the read core to
- * drop buffered data from the start of file, which will then have to
- * be re-read again if this bidder loses.
- *
- * We workaround this a little by passing in the best bid so far so
- * that later bidders can do nothing if they know they'll never
- * outbid. But we can certainly do better...
- */
static int
-archive_read_format_zip_seekable_bid(struct archive_read *a, int best_bid)
+trad_enc_init(struct trad_enc_ctx *ctx, const char *pw, size_t pw_len,
+ const uint8_t *key, size_t key_len, uint8_t *crcchk)
{
- struct zip *zip = (struct zip *)a->format->data;
- int64_t filesize;
- const char *p;
+ uint8_t header[12];
- /* If someone has already bid more than 32, then avoid
- trashing the look-ahead buffers with a seek. */
- if (best_bid > 32)
- return (-1);
-
- filesize = __archive_read_seek(a, -22, SEEK_END);
- /* If we can't seek, then we can't bid. */
- if (filesize <= 0)
- return 0;
-
- /* TODO: More robust search for end of central directory record. */
- if ((p = __archive_read_ahead(a, 22, NULL)) == NULL)
- return 0;
- /* First four bytes are signature for end of central directory
- record. Four zero bytes ensure this isn't a multi-volume
- Zip file (which we don't yet support). */
- if (memcmp(p, "PK\005\006\000\000\000\000", 8) != 0) {
- int64_t i, tail;
- int found;
-
- /*
- * If there is a comment in end of central directory
- * record, 22 bytes are too short. we have to read more
- * to properly detect the record. Hopefully, a length
- * of the comment is not longer than 16362 bytes(16K-22).
- */
- if (filesize + 22 > 1024 * 16) {
- tail = 1024 * 16;
- filesize = __archive_read_seek(a, tail * -1, SEEK_END);
- } else {
- tail = filesize + 22;
- filesize = __archive_read_seek(a, 0, SEEK_SET);
- }
- if (filesize < 0)
- return 0;
- if ((p = __archive_read_ahead(a, (size_t)tail, NULL)) == NULL)
- return 0;
- for (found = 0, i = 0;!found && i < tail - 22;) {
- switch (p[i]) {
- case 'P':
- if (memcmp(p+i,
- "PK\005\006\000\000\000\000", 8) == 0) {
- p += i;
- filesize += tail -
- (22 + archive_le16dec(p+20));
- found = 1;
- } else
- i += 8;
- break;
- case 'K': i += 7; break;
- case 005: i += 6; break;
- case 006: i += 5; break;
- default: i += 1; break;
- }
- }
- if (!found)
- return 0;
+ if (key_len < 12) {
+ *crcchk = 0xff;
+ return -1;
}
- /* Since we've already done the hard work of finding the
- end of central directory record, let's save the important
- information. */
- zip->central_directory_entries = archive_le16dec(p + 10);
- zip->central_directory_size = archive_le32dec(p + 12);
- zip->central_directory_offset = archive_le32dec(p + 16);
- zip->end_of_central_directory_offset = filesize;
+ ctx->keys[0] = 305419896L;
+ ctx->keys[1] = 591751049L;
+ ctx->keys[2] = 878082192L;
- /* Just one volume, so central dir must all be on this volume. */
- if (zip->central_directory_entries != archive_le16dec(p + 8))
- return 0;
- /* Central directory can't extend beyond end of this file. */
- if (zip->central_directory_offset +
- (int64_t)zip->central_directory_size > filesize)
- return 0;
+ for (;pw_len; --pw_len)
+ trad_enc_update_keys(ctx, *pw++);
- /* This is just a tiny bit higher than the maximum returned by
- the streaming Zip bidder. This ensures that the more accurate
- seeking Zip parser wins whenever seek is available. */
- return 32;
+ trad_enc_decrypt_update(ctx, key, 12, header, 12);
+ /* Return the last byte for CRC check. */
+ *crcchk = header[11];
+ return 0;
}
-static int
-cmp_node(const struct archive_rb_node *n1, const struct archive_rb_node *n2)
+#if 0
+static void
+crypt_derive_key_sha1(const void *p, int size, unsigned char *key,
+ int key_size)
{
- const struct zip_entry *e1 = (const struct zip_entry *)n1;
- const struct zip_entry *e2 = (const struct zip_entry *)n2;
-
- return ((int)(e2->local_header_offset - e1->local_header_offset));
+#define MD_SIZE 20
+ archive_sha1_ctx ctx;
+ unsigned char md1[MD_SIZE];
+ unsigned char md2[MD_SIZE * 2];
+ unsigned char mkb[64];
+ int i;
+
+ archive_sha1_init(&ctx);
+ archive_sha1_update(&ctx, p, size);
+ archive_sha1_final(&ctx, md1);
+
+ memset(mkb, 0x36, sizeof(mkb));
+ for (i = 0; i < MD_SIZE; i++)
+ mkb[i] ^= md1[i];
+ archive_sha1_init(&ctx);
+ archive_sha1_update(&ctx, mkb, sizeof(mkb));
+ archive_sha1_final(&ctx, md2);
+
+ memset(mkb, 0x5C, sizeof(mkb));
+ for (i = 0; i < MD_SIZE; i++)
+ mkb[i] ^= md1[i];
+ archive_sha1_init(&ctx);
+ archive_sha1_update(&ctx, mkb, sizeof(mkb));
+ archive_sha1_final(&ctx, md2 + MD_SIZE);
+
+ if (key_size > 32)
+ key_size = 32;
+ memcpy(key, md2, key_size);
+#undef MD_SIZE
}
+#endif
-static int
-cmp_key(const struct archive_rb_node *n, const void *key)
-{
- /* This function won't be called */
- (void)n; /* UNUSED */
- (void)key; /* UNUSED */
- return 1;
-}
+/*
+ * Common code for streaming or seeking modes.
+ *
+ * Includes code to read local file headers, decompress data
+ * from entry bodies, and common API.
+ */
-static int
-rsrc_cmp_node(const struct archive_rb_node *n1,
- const struct archive_rb_node *n2)
+static unsigned long
+real_crc32(unsigned long crc, const void *buff, size_t len)
{
- const struct zip_entry *e1 = (const struct zip_entry *)n1;
- const struct zip_entry *e2 = (const struct zip_entry *)n2;
-
- return (strcmp(e2->rsrcname.s, e1->rsrcname.s));
+ return crc32(crc, buff, (unsigned int)len);
}
-static int
-rsrc_cmp_key(const struct archive_rb_node *n, const void *key)
+/* Used by "ignorecrc32" option to speed up tests. */
+static unsigned long
+fake_crc32(unsigned long crc, const void *buff, size_t len)
{
- const struct zip_entry *e = (const struct zip_entry *)n;
- return (strcmp((const char *)key, e->rsrcname.s));
+ (void)crc; /* UNUSED */
+ (void)buff; /* UNUSED */
+ (void)len; /* UNUSED */
+ return 0;
}
+static struct {
+ int id;
+ const char * name;
+} compression_methods[] = {
+ {0, "uncompressed"}, /* The file is stored (no compression) */
+ {1, "shrinking"}, /* The file is Shrunk */
+ {2, "reduced-1"}, /* The file is Reduced with compression factor 1 */
+ {3, "reduced-2"}, /* The file is Reduced with compression factor 2 */
+ {4, "reduced-3"}, /* The file is Reduced with compression factor 3 */
+ {5, "reduced-4"}, /* The file is Reduced with compression factor 4 */
+ {6, "imploded"}, /* The file is Imploded */
+ {7, "reserved"}, /* Reserved for Tokenizing compression algorithm */
+ {8, "deflation"}, /* The file is Deflated */
+ {9, "deflation-64-bit"}, /* Enhanced Deflating using Deflate64(tm) */
+ {10, "ibm-terse"},/* PKWARE Data Compression Library Imploding
+ * (old IBM TERSE) */
+ {11, "reserved"}, /* Reserved by PKWARE */
+ {12, "bzip"}, /* File is compressed using BZIP2 algorithm */
+ {13, "reserved"}, /* Reserved by PKWARE */
+ {14, "lzma"}, /* LZMA (EFS) */
+ {15, "reserved"}, /* Reserved by PKWARE */
+ {16, "reserved"}, /* Reserved by PKWARE */
+ {17, "reserved"}, /* Reserved by PKWARE */
+ {18, "ibm-terse-new"}, /* File is compressed using IBM TERSE (new) */
+ {19, "ibm-lz777"},/* IBM LZ77 z Architecture (PFS) */
+ {97, "wav-pack"}, /* WavPack compressed data */
+ {98, "ppmd-1"}, /* PPMd version I, Rev 1 */
+ {99, "aes"} /* WinZip AES encryption */
+};
+
static const char *
-rsrc_basename(const char *name, size_t name_length)
+compression_name(const int compression)
{
- const char *s, *r;
-
- r = s = name;
- for (;;) {
- s = memchr(s, '/', name_length - (s - name));
- if (s == NULL)
- break;
- r = ++s;
+ static const int num_compression_methods =
+ sizeof(compression_methods)/sizeof(compression_methods[0]);
+ int i=0;
+
+ while(compression >= 0 && i < num_compression_methods) {
+ if (compression_methods[i].id == compression)
+ return compression_methods[i].name;
+ i++;
}
- return (r);
+ return "??";
}
-static void
-expose_parent_dirs(struct zip *zip, const char *name, size_t name_length)
-{
- struct archive_string str;
- struct zip_entry *dir;
- char *s;
-
- archive_string_init(&str);
- archive_strncpy(&str, name, name_length);
- for (;;) {
- s = strrchr(str.s, '/');
- if (s == NULL)
- break;
- *s = '\0';
- /* Transfer the parent directory from zip->tree_rsrc RB
- * tree to zip->tree RB tree to expose. */
- dir = (struct zip_entry *)
- __archive_rb_tree_find_node(&zip->tree_rsrc, str.s);
- if (dir == NULL)
- break;
- __archive_rb_tree_remove_node(&zip->tree_rsrc, &dir->node);
- archive_string_free(&dir->rsrcname);
- __archive_rb_tree_insert_node(&zip->tree, &dir->node);
- }
- archive_string_free(&str);
-}
-
-static int
-slurp_central_directory(struct archive_read *a, struct zip *zip)
+/* Convert an MSDOS-style date/time into Unix-style time. */
+static time_t
+zip_time(const char *p)
{
- unsigned i;
- int64_t correction;
- static const struct archive_rb_tree_ops rb_ops = {
- &cmp_node, &cmp_key
- };
- static const struct archive_rb_tree_ops rb_rsrc_ops = {
- &rsrc_cmp_node, &rsrc_cmp_key
- };
-
- /*
- * Consider the archive file we are reading may be SFX.
- * So we have to calculate a SFX header size to revise
- * ZIP header offsets.
- */
- correction = zip->end_of_central_directory_offset -
- (zip->central_directory_offset + zip->central_directory_size);
- /* The central directory offset is relative value, and so
- * we revise this offset for SFX. */
- zip->central_directory_offset += correction;
-
- __archive_read_seek(a, zip->central_directory_offset, SEEK_SET);
- zip->offset = zip->central_directory_offset;
- __archive_rb_tree_init(&zip->tree, &rb_ops);
- __archive_rb_tree_init(&zip->tree_rsrc, &rb_rsrc_ops);
-
- zip->zip_entries = calloc(zip->central_directory_entries,
- sizeof(struct zip_entry));
- for (i = 0; i < zip->central_directory_entries; ++i) {
- struct zip_entry *zip_entry = &zip->zip_entries[i];
- size_t filename_length, extra_length, comment_length;
- uint32_t external_attributes;
- const char *name, *p, *r;
-
- if ((p = __archive_read_ahead(a, 46, NULL)) == NULL)
- return ARCHIVE_FATAL;
- if (memcmp(p, "PK\001\002", 4) != 0) {
- archive_set_error(&a->archive,
- -1, "Invalid central directory signature");
- return ARCHIVE_FATAL;
- }
- zip->have_central_directory = 1;
- /* version = p[4]; */
- zip_entry->system = p[5];
- /* version_required = archive_le16dec(p + 6); */
- zip_entry->flags = archive_le16dec(p + 8);
- zip_entry->compression = (char)archive_le16dec(p + 10);
- zip_entry->mtime = zip_time(p + 12);
- zip_entry->crc32 = archive_le32dec(p + 16);
- zip_entry->compressed_size = archive_le32dec(p + 20);
- zip_entry->uncompressed_size = archive_le32dec(p + 24);
- filename_length = archive_le16dec(p + 28);
- extra_length = archive_le16dec(p + 30);
- comment_length = archive_le16dec(p + 32);
- /* disk_start = archive_le16dec(p + 34); */ /* Better be zero. */
- /* internal_attributes = archive_le16dec(p + 36); */ /* text bit */
- external_attributes = archive_le32dec(p + 38);
- zip_entry->local_header_offset =
- archive_le32dec(p + 42) + correction;
-
- /* If we can't guess the mode, leave it zero here;
- when we read the local file header we might get
- more information. */
- zip_entry->mode = 0;
- if (zip_entry->system == 3) {
- zip_entry->mode = external_attributes >> 16;
- }
-
- /*
- * Mac resource fork files are stored under the
- * "__MACOSX/" directory, so we should check if
- * it is.
- */
- /* Make sure we have the file name. */
- if ((p = __archive_read_ahead(a, 46 + filename_length, NULL))
- == NULL)
- return ARCHIVE_FATAL;
- name = p + 46;
- r = rsrc_basename(name, filename_length);
- if (filename_length >= 9 &&
- strncmp("__MACOSX/", name, 9) == 0) {
- /* If this file is not a resource fork nor
- * a directory. We should treat it as a non
- * resource fork file to expose it. */
- if (name[filename_length-1] != '/' &&
- (r - name < 3 || r[0] != '.' || r[1] != '_')) {
- __archive_rb_tree_insert_node(&zip->tree,
- &zip_entry->node);
- /* Expose its parent directories. */
- expose_parent_dirs(zip, name, filename_length);
- } else {
- /* This file is a resource fork file or
- * a directory. */
- archive_strncpy(&(zip_entry->rsrcname), name,
- filename_length);
- __archive_rb_tree_insert_node(&zip->tree_rsrc,
- &zip_entry->node);
- }
- } else {
- /* Generate resource fork name to find its resource
- * file at zip->tree_rsrc. */
- archive_strcpy(&(zip_entry->rsrcname), "__MACOSX/");
- archive_strncat(&(zip_entry->rsrcname), name, r - name);
- archive_strcat(&(zip_entry->rsrcname), "._");
- archive_strncat(&(zip_entry->rsrcname),
- name + (r - name), filename_length - (r - name));
- /* Register an entry to RB tree to sort it by
- * file offset. */
- __archive_rb_tree_insert_node(&zip->tree,
- &zip_entry->node);
- }
+ int msTime, msDate;
+ struct tm ts;
- /* We don't read the filename until we get to the
- local file header. Reading it here would speed up
- table-of-contents operations (removing the need to
- find and read local file header to get the
- filename) at the cost of requiring a lot of extra
- space. */
- /* We don't read the extra block here. We assume it
- will be duplicated at the local file header. */
- __archive_read_consume(a,
- 46 + filename_length + extra_length + comment_length);
- }
+ msTime = (0xff & (unsigned)p[0]) + 256 * (0xff & (unsigned)p[1]);
+ msDate = (0xff & (unsigned)p[2]) + 256 * (0xff & (unsigned)p[3]);
- return ARCHIVE_OK;
+ memset(&ts, 0, sizeof(ts));
+ ts.tm_year = ((msDate >> 9) & 0x7f) + 80; /* Years since 1900. */
+ ts.tm_mon = ((msDate >> 5) & 0x0f) - 1; /* Month number. */
+ ts.tm_mday = msDate & 0x1f; /* Day of month. */
+ ts.tm_hour = (msTime >> 11) & 0x1f;
+ ts.tm_min = (msTime >> 5) & 0x3f;
+ ts.tm_sec = (msTime << 1) & 0x3e;
+ ts.tm_isdst = -1;
+ return mktime(&ts);
}
-static int64_t
-zip_read_consume(struct archive_read *a, int64_t bytes)
+/*
+ * The extra data is stored as a list of
+ * id1+size1+data1 + id2+size2+data2 ...
+ * triplets. id and size are 2 bytes each.
+ */
+static void
+process_extra(const char *p, size_t extra_length, struct zip_entry* zip_entry)
{
- struct zip *zip = (struct zip *)a->format->data;
- int64_t skip;
-
- skip = __archive_read_consume(a, bytes);
- if (skip > 0)
- zip->offset += skip;
- return (skip);
-}
+ unsigned offset = 0;
-static int
-zip_read_mac_metadata(struct archive_read *a, struct archive_entry *entry,
- struct zip_entry *rsrc)
-{
- struct zip *zip = (struct zip *)a->format->data;
- unsigned char *metadata, *mp;
- int64_t offset = zip->offset;
- size_t remaining_bytes, metadata_bytes;
- ssize_t hsize;
- int ret = ARCHIVE_OK, eof;
+ while (offset < extra_length - 4) {
+ unsigned short headerid = archive_le16dec(p + offset);
+ unsigned short datasize = archive_le16dec(p + offset + 2);
- switch(rsrc->compression) {
- case 0: /* No compression. */
-#ifdef HAVE_ZLIB_H
- case 8: /* Deflate compression. */
+ offset += 4;
+ if (offset + datasize > extra_length)
+ break;
+#ifdef DEBUG
+ fprintf(stderr, "Header id 0x%04x, length %d\n",
+ headerid, datasize);
#endif
- break;
- default: /* Unsupported compression. */
- /* Return a warning. */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Unsupported ZIP compression method (%s)",
- compression_name(rsrc->compression));
- /* We can't decompress this entry, but we will
- * be able to skip() it and try the next entry. */
- return (ARCHIVE_WARN);
- }
-
- if (rsrc->uncompressed_size > (128 * 1024)) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Mac metadata is too large: %jd > 128K bytes",
- (intmax_t)rsrc->uncompressed_size);
- return (ARCHIVE_WARN);
- }
-
- metadata = malloc((size_t)rsrc->uncompressed_size);
- if (metadata == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Mac metadata");
- return (ARCHIVE_FATAL);
- }
-
- if (zip->offset < rsrc->local_header_offset)
- zip_read_consume(a, rsrc->local_header_offset - zip->offset);
- else if (zip->offset != rsrc->local_header_offset) {
- __archive_read_seek(a, rsrc->local_header_offset, SEEK_SET);
- zip->offset = zip->entry->local_header_offset;
- }
-
- hsize = zip_get_local_file_header_size(a, 0);
- zip_read_consume(a, hsize);
-
- remaining_bytes = (size_t)rsrc->compressed_size;
- metadata_bytes = (size_t)rsrc->uncompressed_size;
- mp = metadata;
- eof = 0;
- while (!eof && remaining_bytes) {
- const unsigned char *p;
- ssize_t bytes_avail;
- size_t bytes_used;
-
- p = __archive_read_ahead(a, 1, &bytes_avail);
- if (p == NULL) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated ZIP file header");
- ret = ARCHIVE_WARN;
- goto exit_mac_metadata;
- }
- if ((size_t)bytes_avail > remaining_bytes)
- bytes_avail = remaining_bytes;
- switch(rsrc->compression) {
- case 0: /* No compression. */
- memcpy(mp, p, bytes_avail);
- bytes_used = (size_t)bytes_avail;
- metadata_bytes -= bytes_used;
- mp += bytes_used;
- if (metadata_bytes == 0)
- eof = 1;
+ switch (headerid) {
+ case 0x0001:
+ /* Zip64 extended information extra field. */
+ zip_entry->flags |= LA_USED_ZIP64;
+ if (zip_entry->uncompressed_size == 0xffffffff) {
+ if (datasize < 8)
+ break;
+ zip_entry->uncompressed_size =
+ archive_le64dec(p + offset);
+ offset += 8;
+ datasize -= 8;
+ }
+ if (zip_entry->compressed_size == 0xffffffff) {
+ if (datasize < 8)
+ break;
+ zip_entry->compressed_size =
+ archive_le64dec(p + offset);
+ offset += 8;
+ datasize -= 8;
+ }
+ if (zip_entry->local_header_offset == 0xffffffff) {
+ if (datasize < 8)
+ break;
+ zip_entry->local_header_offset =
+ archive_le64dec(p + offset);
+ offset += 8;
+ datasize -= 8;
+ }
+ /* archive_le32dec(p + offset) gives disk
+ * on which file starts, but we don't handle
+ * multi-volume Zip files. */
break;
-#ifdef HAVE_ZLIB_H
- case 8: /* Deflate compression. */
+#ifdef DEBUG
+ case 0x0017:
{
- int r;
-
- ret = zip_deflate_init(a, zip);
- if (ret != ARCHIVE_OK)
- goto exit_mac_metadata;
- zip->stream.next_in =
- (Bytef *)(uintptr_t)(const void *)p;
- zip->stream.avail_in = (uInt)bytes_avail;
- zip->stream.total_in = 0;
- zip->stream.next_out = mp;
- zip->stream.avail_out = (uInt)metadata_bytes;
- zip->stream.total_out = 0;
-
- r = inflate(&zip->stream, 0);
- switch (r) {
- case Z_OK:
- break;
- case Z_STREAM_END:
- eof = 1;
- break;
- case Z_MEM_ERROR:
- archive_set_error(&a->archive, ENOMEM,
- "Out of memory for ZIP decompression");
- ret = ARCHIVE_FATAL;
- goto exit_mac_metadata;
- default:
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_MISC,
- "ZIP decompression failed (%d)", r);
- ret = ARCHIVE_FATAL;
- goto exit_mac_metadata;
+ /* Strong encryption field. */
+ if (archive_le16dec(p + offset) == 2) {
+ unsigned algId =
+ archive_le16dec(p + offset + 2);
+ unsigned bitLen =
+ archive_le16dec(p + offset + 4);
+ int flags =
+ archive_le16dec(p + offset + 6);
+ fprintf(stderr, "algId=0x%04x, bitLen=%u, "
+ "flgas=%d\n", algId, bitLen,flags);
}
- bytes_used = zip->stream.total_in;
- metadata_bytes -= zip->stream.total_out;
- mp += zip->stream.total_out;
break;
}
#endif
- default:
- bytes_used = 0;
+ case 0x5455:
+ {
+ /* Extended time field "UT". */
+ int flags = p[offset];
+ offset++;
+ datasize--;
+ /* Flag bits indicate which dates are present. */
+ if (flags & 0x01)
+ {
+#ifdef DEBUG
+ fprintf(stderr, "mtime: %lld -> %d\n",
+ (long long)zip_entry->mtime,
+ archive_le32dec(p + offset));
+#endif
+ if (datasize < 4)
+ break;
+ zip_entry->mtime = archive_le32dec(p + offset);
+ offset += 4;
+ datasize -= 4;
+ }
+ if (flags & 0x02)
+ {
+ if (datasize < 4)
+ break;
+ zip_entry->atime = archive_le32dec(p + offset);
+ offset += 4;
+ datasize -= 4;
+ }
+ if (flags & 0x04)
+ {
+ if (datasize < 4)
+ break;
+ zip_entry->ctime = archive_le32dec(p + offset);
+ offset += 4;
+ datasize -= 4;
+ }
break;
}
- zip_read_consume(a, bytes_used);
- remaining_bytes -= bytes_used;
- }
- archive_entry_copy_mac_metadata(entry, metadata,
- (size_t)rsrc->uncompressed_size - metadata_bytes);
-
- __archive_read_seek(a, offset, SEEK_SET);
- zip->offset = offset;
-exit_mac_metadata:
- zip->decompress_init = 0;
- free(metadata);
- return (ret);
-}
-
-static int
-archive_read_format_zip_seekable_read_header(struct archive_read *a,
- struct archive_entry *entry)
-{
- struct zip *zip = (struct zip *)a->format->data;
- struct zip_entry *rsrc;
- int r, ret = ARCHIVE_OK;
-
- a->archive.archive_format = ARCHIVE_FORMAT_ZIP;
- if (a->archive.archive_format_name == NULL)
- a->archive.archive_format_name = "ZIP";
-
- if (zip->zip_entries == NULL) {
- r = slurp_central_directory(a, zip);
- zip->entries_remaining = zip->central_directory_entries;
- if (r != ARCHIVE_OK)
- return r;
- /* Get first entry whose local header offset is lower than
- * other entries in the archive file. */
- zip->entry =
- (struct zip_entry *)ARCHIVE_RB_TREE_MIN(&zip->tree);
- } else if (zip->entry != NULL) {
- /* Get next entry in local header offset order. */
- zip->entry = (struct zip_entry *)__archive_rb_tree_iterate(
- &zip->tree, &zip->entry->node, ARCHIVE_RB_DIR_RIGHT);
- }
-
- if (zip->entries_remaining <= 0 || zip->entry == NULL)
- return ARCHIVE_EOF;
- --zip->entries_remaining;
-
- if (zip->entry->rsrcname.s)
- rsrc = (struct zip_entry *)__archive_rb_tree_find_node(
- &zip->tree_rsrc, zip->entry->rsrcname.s);
- else
- rsrc = NULL;
-
- /* File entries are sorted by the header offset, we should mostly
- * use zip_read_consume to advance a read point to avoid redundant
- * data reading. */
- if (zip->offset < zip->entry->local_header_offset)
- zip_read_consume(a,
- zip->entry->local_header_offset - zip->offset);
- else if (zip->offset != zip->entry->local_header_offset) {
- __archive_read_seek(a, zip->entry->local_header_offset,
- SEEK_SET);
- zip->offset = zip->entry->local_header_offset;
- }
- zip->unconsumed = 0;
- r = zip_read_local_file_header(a, entry, zip);
- if (r != ARCHIVE_OK)
- return r;
- if ((zip->entry->mode & AE_IFMT) == AE_IFLNK) {
- const void *p;
- struct archive_string_conv *sconv;
- size_t linkname_length = (size_t)archive_entry_size(entry);
-
- archive_entry_set_size(entry, 0);
- p = __archive_read_ahead(a, linkname_length, NULL);
- if (p == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Truncated Zip file");
- return ARCHIVE_FATAL;
- }
-
- sconv = zip->sconv;
- if (sconv == NULL && (zip->entry->flags & ZIP_UTF8_NAME))
- sconv = zip->sconv_utf8;
- if (sconv == NULL)
- sconv = zip->sconv_default;
- if (archive_entry_copy_symlink_l(entry, p, linkname_length,
- sconv) != 0) {
- if (errno != ENOMEM && sconv == zip->sconv_utf8 &&
- (zip->entry->flags & ZIP_UTF8_NAME))
- archive_entry_copy_symlink_l(entry, p,
- linkname_length, NULL);
- if (errno == ENOMEM) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate memory for Symlink");
- return (ARCHIVE_FATAL);
+ case 0x5855:
+ {
+ /* Info-ZIP Unix Extra Field (old version) "UX". */
+ if (datasize >= 8) {
+ zip_entry->atime = archive_le32dec(p + offset);
+ zip_entry->mtime =
+ archive_le32dec(p + offset + 4);
}
- /*
- * Since there is no character-set regulation for
- * symlink name, do not report the conversion error
- * in an automatic conversion.
- */
- if (sconv != zip->sconv_utf8 ||
- (zip->entry->flags & ZIP_UTF8_NAME) == 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Symlink cannot be converted "
- "from %s to current locale.",
- archive_string_conversion_charset_name(
- sconv));
- ret = ARCHIVE_WARN;
+ if (datasize >= 12) {
+ zip_entry->uid =
+ archive_le16dec(p + offset + 8);
+ zip_entry->gid =
+ archive_le16dec(p + offset + 10);
}
+ break;
}
- }
- if (rsrc) {
- int ret2 = zip_read_mac_metadata(a, entry, rsrc);
- if (ret2 < ret)
- ret = ret2;
- }
- return (ret);
-}
-
-static int
-archive_read_format_zip_streamable_bid(struct archive_read *a, int best_bid)
-{
- const char *p;
-
- (void)best_bid; /* UNUSED */
-
- if ((p = __archive_read_ahead(a, 4, NULL)) == NULL)
- return (-1);
-
- /*
- * Bid of 30 here is: 16 bits for "PK",
- * next 16-bit field has four options (-2 bits).
- * 16 + 16-2 = 30.
- */
- if (p[0] == 'P' && p[1] == 'K') {
- if ((p[2] == '\001' && p[3] == '\002')
- || (p[2] == '\003' && p[3] == '\004')
- || (p[2] == '\005' && p[3] == '\006')
- || (p[2] == '\007' && p[3] == '\010')
- || (p[2] == '0' && p[3] == '0'))
- return (30);
- }
-
- /* TODO: It's worth looking ahead a little bit for a valid
- * PK signature. In particular, that would make it possible
- * to read some UUEncoded SFX files or SFX files coming from
- * a network socket. */
-
- return (0);
-}
-
-static int
-archive_read_format_zip_options(struct archive_read *a,
- const char *key, const char *val)
-{
- struct zip *zip;
- int ret = ARCHIVE_FAILED;
-
- zip = (struct zip *)(a->format->data);
- if (strcmp(key, "compat-2x") == 0) {
- /* Handle filnames as libarchive 2.x */
- zip->init_default_conversion = (val != NULL) ? 1 : 0;
- return (ARCHIVE_OK);
- } else if (strcmp(key, "hdrcharset") == 0) {
- if (val == NULL || val[0] == 0)
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "zip: hdrcharset option needs a character-set name"
- );
- else {
- zip->sconv = archive_string_conversion_from_charset(
- &a->archive, val, 0);
- if (zip->sconv != NULL) {
- if (strcmp(val, "UTF-8") == 0)
- zip->sconv_utf8 = zip->sconv;
- ret = ARCHIVE_OK;
- } else
- ret = ARCHIVE_FATAL;
- }
- return (ret);
- }
-
- /* Note: The "warn" return is just to inform the options
- * supervisor that we didn't handle it. It will generate
- * a suitable error if no one used this option. */
- return (ARCHIVE_WARN);
-}
-
-static int
-archive_read_format_zip_streamable_read_header(struct archive_read *a,
- struct archive_entry *entry)
-{
- struct zip *zip;
+ case 0x6c78:
+ {
+ /* Experimental 'xl' field */
+ /*
+ * Introduced Dec 2013 to provide a way to
+ * include external file attributes (and other
+ * fields that ordinarily appear only in
+ * central directory) in local file header.
+ * This provides file type and permission
+ * information necessary to support full
+ * streaming extraction. Currently being
+ * discussed with other Zip developers
+ * ... subject to change.
+ *
+ * Format:
+ * The field starts with a bitmap that specifies
+ * which additional fields are included. The
+ * bitmap is variable length and can be extended in
+ * the future.
+ *
+ * n bytes - feature bitmap: first byte has low-order
+ * 7 bits. If high-order bit is set, a subsequent
+ * byte holds the next 7 bits, etc.
+ *
+ * if bitmap & 1, 2 byte "version made by"
+ * if bitmap & 2, 2 byte "internal file attributes"
+ * if bitmap & 4, 4 byte "external file attributes"
+ * if bitmap * 7, 2 byte comment length + n byte comment
+ */
+ int bitmap, bitmap_last;
- a->archive.archive_format = ARCHIVE_FORMAT_ZIP;
- if (a->archive.archive_format_name == NULL)
- a->archive.archive_format_name = "ZIP";
+ if (datasize < 1)
+ break;
+ bitmap_last = bitmap = 0xff & p[offset];
+ offset += 1;
+ datasize -= 1;
+
+ /* We only support first 7 bits of bitmap; skip rest. */
+ while ((bitmap_last & 0x80) != 0
+ && datasize >= 1) {
+ bitmap_last = p[offset];
+ offset += 1;
+ datasize -= 1;
+ }
- zip = (struct zip *)(a->format->data);
+ if (bitmap & 1) {
+ /* 2 byte "version made by" */
+ if (datasize < 2)
+ break;
+ zip_entry->system
+ = archive_le16dec(p + offset) >> 8;
+ offset += 2;
+ datasize -= 2;
+ }
+ if (bitmap & 2) {
+ /* 2 byte "internal file attributes" */
+ uint32_t internal_attributes;
+ if (datasize < 2)
+ break;
+ internal_attributes
+ = archive_le16dec(p + offset);
+ /* Not used by libarchive at present. */
+ (void)internal_attributes; /* UNUSED */
+ offset += 2;
+ datasize -= 2;
+ }
+ if (bitmap & 4) {
+ /* 4 byte "external file attributes" */
+ uint32_t external_attributes;
+ if (datasize < 4)
+ break;
+ external_attributes
+ = archive_le32dec(p + offset);
+ if (zip_entry->system == 3) {
+ zip_entry->mode
+ = external_attributes >> 16;
+ }
+ offset += 4;
+ datasize -= 4;
+ }
+ if (bitmap & 8) {
+ /* 2 byte comment length + comment */
+ uint32_t comment_length;
+ if (datasize < 2)
+ break;
+ comment_length
+ = archive_le16dec(p + offset);
+ offset += 2;
+ datasize -= 2;
- /* Make sure we have a zip_entry structure to use. */
- if (zip->zip_entries == NULL) {
- zip->zip_entries = malloc(sizeof(struct zip_entry));
- if (zip->zip_entries == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Out of memory");
- return ARCHIVE_FATAL;
+ if (datasize < comment_length)
+ break;
+ /* Comment is not supported by libarchive */
+ offset += comment_length;
+ datasize -= comment_length;
+ }
+ break;
}
- }
- zip->entry = zip->zip_entries;
- memset(zip->entry, 0, sizeof(struct zip_entry));
-
- /* Search ahead for the next local file header. */
- zip_read_consume(a, zip->unconsumed);
- zip->unconsumed = 0;
- for (;;) {
- int64_t skipped = 0;
- const char *p, *end;
- ssize_t bytes;
-
- p = __archive_read_ahead(a, 4, &bytes);
- if (p == NULL)
- return (ARCHIVE_FATAL);
- end = p + bytes;
-
- while (p + 4 <= end) {
- if (p[0] == 'P' && p[1] == 'K') {
- if (p[2] == '\001' && p[3] == '\002')
- /* Beginning of central directory. */
- return (ARCHIVE_EOF);
+ case 0x7855:
+ /* Info-ZIP Unix Extra Field (type 2) "Ux". */
+#ifdef DEBUG
+ fprintf(stderr, "uid %d gid %d\n",
+ archive_le16dec(p + offset),
+ archive_le16dec(p + offset + 2));
+#endif
+ if (datasize >= 2)
+ zip_entry->uid = archive_le16dec(p + offset);
+ if (datasize >= 4)
+ zip_entry->gid =
+ archive_le16dec(p + offset + 2);
+ break;
+ case 0x7875:
+ {
+ /* Info-Zip Unix Extra Field (type 3) "ux". */
+ int uidsize = 0, gidsize = 0;
- if (p[2] == '\003' && p[3] == '\004') {
- /* Regular file entry. */
- zip_read_consume(a, skipped);
- return zip_read_local_file_header(a,
- entry, zip);
+ /* TODO: support arbitrary uidsize/gidsize. */
+ if (datasize >= 1 && p[offset] == 1) {/* version=1 */
+ if (datasize >= 4) {
+ /* get a uid size. */
+ uidsize = 0xff & (int)p[offset+1];
+ if (uidsize == 2)
+ zip_entry->uid =
+ archive_le16dec(
+ p + offset + 2);
+ else if (uidsize == 4 && datasize >= 6)
+ zip_entry->uid =
+ archive_le32dec(
+ p + offset + 2);
+ }
+ if (datasize >= (2 + uidsize + 3)) {
+ /* get a gid size. */
+ gidsize = 0xff & (int)p[offset+2+uidsize];
+ if (gidsize == 2)
+ zip_entry->gid =
+ archive_le16dec(
+ p+offset+2+uidsize+1);
+ else if (gidsize == 4 &&
+ datasize >= (2 + uidsize + 5))
+ zip_entry->gid =
+ archive_le32dec(
+ p+offset+2+uidsize+1);
}
-
- if (p[2] == '\005' && p[3] == '\006')
- /* End of central directory. */
- return (ARCHIVE_EOF);
}
- ++p;
- ++skipped;
+ break;
}
- zip_read_consume(a, skipped);
- }
-}
-
-static ssize_t
-zip_get_local_file_header_size(struct archive_read *a, size_t extra)
-{
- const char *p;
- ssize_t filename_length, extra_length;
-
- if ((p = __archive_read_ahead(a, extra + 30, NULL)) == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated ZIP file header");
- return (ARCHIVE_WARN);
+ case 0x9901:
+ /* WinZIp AES extra data field. */
+ if (p[offset + 2] == 'A' && p[offset + 3] == 'E') {
+ /* Vendor version. */
+ zip_entry->aes_extra.vendor =
+ archive_le16dec(p + offset);
+ /* AES encryption strength. */
+ zip_entry->aes_extra.strength = p[offset + 4];
+ /* Actual compression method. */
+ zip_entry->aes_extra.compression =
+ p[offset + 5];
+ }
+ break;
+ default:
+ break;
+ }
+ offset += datasize;
}
- p += extra;
-
- if (memcmp(p, "PK\003\004", 4) != 0) {
- archive_set_error(&a->archive, -1, "Damaged Zip archive");
- return ARCHIVE_WARN;
+#ifdef DEBUG
+ if (offset != extra_length)
+ {
+ fprintf(stderr,
+ "Extra data field contents do not match reported size!\n");
}
- filename_length = archive_le16dec(p + 26);
- extra_length = archive_le16dec(p + 28);
-
- return (30 + filename_length + extra_length);
+#endif
}
/*
@@ -957,16 +715,18 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
size_t len, filename_length, extra_length;
struct archive_string_conv *sconv;
struct zip_entry *zip_entry = zip->entry;
- uint32_t local_crc32;
- int64_t compressed_size, uncompressed_size;
+ struct zip_entry zip_entry_central_dir;
int ret = ARCHIVE_OK;
char version;
+ /* Save a copy of the original for consistency checks. */
+ zip_entry_central_dir = *zip_entry;
+
zip->decompress_init = 0;
zip->end_of_entry = 0;
zip->entry_uncompressed_bytes_read = 0;
zip->entry_compressed_bytes_read = 0;
- zip->entry_crc32 = crc32(0, NULL, 0);
+ zip->entry_crc32 = zip->crc32func(0, NULL, 0);
/* Setup default conversion. */
if (zip->sconv == NULL && !zip->init_default_conversion) {
@@ -987,52 +747,31 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
}
version = p[4];
zip_entry->system = p[5];
- zip_entry->flags = archive_le16dec(p + 6);
+ zip_entry->zip_flags = archive_le16dec(p + 6);
+ if (zip_entry->zip_flags & (ZIP_ENCRYPTED | ZIP_STRONG_ENCRYPTED)) {
+ zip->has_encrypted_entries = 1;
+ archive_entry_set_is_data_encrypted(entry, 1);
+ if (zip_entry->zip_flags & ZIP_CENTRAL_DIRECTORY_ENCRYPTED &&
+ zip_entry->zip_flags & ZIP_ENCRYPTED &&
+ zip_entry->zip_flags & ZIP_STRONG_ENCRYPTED) {
+ archive_entry_set_is_metadata_encrypted(entry, 1);
+ return ARCHIVE_FATAL;
+ }
+ }
+ zip->init_decryption = (zip_entry->zip_flags & ZIP_ENCRYPTED);
zip_entry->compression = (char)archive_le16dec(p + 8);
zip_entry->mtime = zip_time(p + 10);
- local_crc32 = archive_le32dec(p + 14);
- compressed_size = archive_le32dec(p + 18);
- uncompressed_size = archive_le32dec(p + 22);
+ zip_entry->crc32 = archive_le32dec(p + 14);
+ if (zip_entry->zip_flags & ZIP_LENGTH_AT_END)
+ zip_entry->decdat = p[11];
+ else
+ zip_entry->decdat = p[17];
+ zip_entry->compressed_size = archive_le32dec(p + 18);
+ zip_entry->uncompressed_size = archive_le32dec(p + 22);
filename_length = archive_le16dec(p + 26);
extra_length = archive_le16dec(p + 28);
- zip_read_consume(a, 30);
-
- if (zip->have_central_directory) {
- /* If we read the central dir entry, we must have size
- * information as well, so ignore the length-at-end flag. */
- zip_entry->flags &= ~ZIP_LENGTH_AT_END;
- /* If we have values from both the local file header
- and the central directory, warn about mismatches
- which might indicate a damaged file. But some
- writers always put zero in the local header; don't
- bother warning about that. */
- if (local_crc32 != 0 && local_crc32 != zip_entry->crc32) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Inconsistent CRC32 values");
- ret = ARCHIVE_WARN;
- }
- if (compressed_size != 0
- && compressed_size != zip_entry->compressed_size) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Inconsistent compressed size");
- ret = ARCHIVE_WARN;
- }
- if (uncompressed_size != 0
- && uncompressed_size != zip_entry->uncompressed_size) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Inconsistent uncompressed size");
- ret = ARCHIVE_WARN;
- }
- } else {
- /* If we don't have the CD info, use whatever we do have. */
- zip_entry->crc32 = local_crc32;
- zip_entry->compressed_size = compressed_size;
- zip_entry->uncompressed_size = uncompressed_size;
- }
+ __archive_read_consume(a, 30);
/* Read the filename. */
if ((h = __archive_read_ahead(a, filename_length, NULL)) == NULL) {
@@ -1040,7 +779,7 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
"Truncated ZIP file header");
return (ARCHIVE_FATAL);
}
- if (zip_entry->flags & ZIP_UTF8_NAME) {
+ if (zip_entry->zip_flags & ZIP_UTF8_NAME) {
/* The filename is stored to be UTF-8. */
if (zip->sconv_utf8 == NULL) {
zip->sconv_utf8 =
@@ -1069,26 +808,38 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
archive_string_conversion_charset_name(sconv));
ret = ARCHIVE_WARN;
}
- zip_read_consume(a, filename_length);
+ __archive_read_consume(a, filename_length);
- if (zip_entry->mode == 0) {
+ /* Work around a bug in Info-Zip: When reading from a pipe, it
+ * stats the pipe instead of synthesizing a file entry. */
+ if ((zip_entry->mode & AE_IFMT) == AE_IFIFO) {
+ zip_entry->mode &= ~ AE_IFMT;
+ zip_entry->mode |= AE_IFREG;
+ }
+
+ if ((zip_entry->mode & AE_IFMT) == 0) {
/* Especially in streaming mode, we can end up
- here without having seen any mode information.
+ here without having seen proper mode information.
Guess from the filename. */
wp = archive_entry_pathname_w(entry);
if (wp != NULL) {
len = wcslen(wp);
if (len > 0 && wp[len - 1] == L'/')
- zip_entry->mode = AE_IFDIR | 0777;
+ zip_entry->mode |= AE_IFDIR;
else
- zip_entry->mode = AE_IFREG | 0666;
+ zip_entry->mode |= AE_IFREG;
} else {
cp = archive_entry_pathname(entry);
len = (cp != NULL)?strlen(cp):0;
if (len > 0 && cp[len - 1] == '/')
- zip_entry->mode = AE_IFDIR | 0777;
+ zip_entry->mode |= AE_IFDIR;
else
- zip_entry->mode = AE_IFREG | 0666;
+ zip_entry->mode |= AE_IFREG;
+ }
+ if (zip_entry->mode == AE_IFDIR) {
+ zip_entry->mode |= 0775;
+ } else if (zip_entry->mode == AE_IFREG) {
+ zip_entry->mode |= 0664;
}
}
@@ -1098,8 +849,53 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
"Truncated ZIP file header");
return (ARCHIVE_FATAL);
}
+
process_extra(h, extra_length, zip_entry);
- zip_read_consume(a, extra_length);
+ __archive_read_consume(a, extra_length);
+
+ if (zip_entry->flags & LA_FROM_CENTRAL_DIRECTORY) {
+ /* If this came from the central dir, it's size info
+ * is definitive, so ignore the length-at-end flag. */
+ zip_entry->zip_flags &= ~ZIP_LENGTH_AT_END;
+ /* If local header is missing a value, use the one from
+ the central directory. If both have it, warn about
+ mismatches. */
+ if (zip_entry->crc32 == 0) {
+ zip_entry->crc32 = zip_entry_central_dir.crc32;
+ } else if (!zip->ignore_crc32
+ && zip_entry->crc32 != zip_entry_central_dir.crc32) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Inconsistent CRC32 values");
+ ret = ARCHIVE_WARN;
+ }
+ if (zip_entry->compressed_size == 0) {
+ zip_entry->compressed_size
+ = zip_entry_central_dir.compressed_size;
+ } else if (zip_entry->compressed_size
+ != zip_entry_central_dir.compressed_size) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Inconsistent compressed size: "
+ "%jd in central directory, %jd in local header",
+ (intmax_t)zip_entry_central_dir.compressed_size,
+ (intmax_t)zip_entry->compressed_size);
+ ret = ARCHIVE_WARN;
+ }
+ if (zip_entry->uncompressed_size == 0) {
+ zip_entry->uncompressed_size
+ = zip_entry_central_dir.uncompressed_size;
+ } else if (zip_entry->uncompressed_size
+ != zip_entry_central_dir.uncompressed_size) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Inconsistent uncompressed size: "
+ "%jd in central directory, %jd in local header",
+ (intmax_t)zip_entry_central_dir.uncompressed_size,
+ (intmax_t)zip_entry->uncompressed_size);
+ ret = ARCHIVE_WARN;
+ }
+ }
/* Populate some additional entry fields: */
archive_entry_set_mode(entry, zip_entry->mode);
@@ -1108,155 +904,120 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
archive_entry_set_mtime(entry, zip_entry->mtime, 0);
archive_entry_set_ctime(entry, zip_entry->ctime, 0);
archive_entry_set_atime(entry, zip_entry->atime, 0);
- /* Set the size only if it's meaningful. */
- if (0 == (zip_entry->flags & ZIP_LENGTH_AT_END))
- archive_entry_set_size(entry, zip_entry->uncompressed_size);
+ if ((zip->entry->mode & AE_IFMT) == AE_IFLNK) {
+ size_t linkname_length;
+
+ if (zip_entry->compressed_size > 64 * 1024) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Zip file with oversized link entry");
+ return ARCHIVE_FATAL;
+ }
+
+ linkname_length = (size_t)zip_entry->compressed_size;
+
+ archive_entry_set_size(entry, 0);
+ p = __archive_read_ahead(a, linkname_length, NULL);
+ if (p == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Truncated Zip file");
+ return ARCHIVE_FATAL;
+ }
+
+ sconv = zip->sconv;
+ if (sconv == NULL && (zip->entry->zip_flags & ZIP_UTF8_NAME))
+ sconv = zip->sconv_utf8;
+ if (sconv == NULL)
+ sconv = zip->sconv_default;
+ if (archive_entry_copy_symlink_l(entry, p, linkname_length,
+ sconv) != 0) {
+ if (errno != ENOMEM && sconv == zip->sconv_utf8 &&
+ (zip->entry->zip_flags & ZIP_UTF8_NAME))
+ archive_entry_copy_symlink_l(entry, p,
+ linkname_length, NULL);
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Symlink");
+ return (ARCHIVE_FATAL);
+ }
+ /*
+ * Since there is no character-set regulation for
+ * symlink name, do not report the conversion error
+ * in an automatic conversion.
+ */
+ if (sconv != zip->sconv_utf8 ||
+ (zip->entry->zip_flags & ZIP_UTF8_NAME) == 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Symlink cannot be converted "
+ "from %s to current locale.",
+ archive_string_conversion_charset_name(
+ sconv));
+ ret = ARCHIVE_WARN;
+ }
+ }
+ zip_entry->uncompressed_size = zip_entry->compressed_size = 0;
+
+ if (__archive_read_consume(a, linkname_length) < 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Read error skipping symlink target name");
+ return ARCHIVE_FATAL;
+ }
+ } else if (0 == (zip_entry->zip_flags & ZIP_LENGTH_AT_END)
+ || zip_entry->uncompressed_size > 0) {
+ /* Set the size only if it's meaningful. */
+ archive_entry_set_size(entry, zip_entry->uncompressed_size);
+ }
zip->entry_bytes_remaining = zip_entry->compressed_size;
/* If there's no body, force read_data() to return EOF immediately. */
- if (0 == (zip_entry->flags & ZIP_LENGTH_AT_END)
+ if (0 == (zip_entry->zip_flags & ZIP_LENGTH_AT_END)
&& zip->entry_bytes_remaining < 1)
zip->end_of_entry = 1;
/* Set up a more descriptive format name. */
- sprintf(zip->format_name, "ZIP %d.%d (%s)",
+ archive_string_sprintf(&zip->format_name, "ZIP %d.%d (%s)",
version / 10, version % 10,
compression_name(zip->entry->compression));
- a->archive.archive_format_name = zip->format_name;
+ a->archive.archive_format_name = zip->format_name.s;
return (ret);
}
-static const char *
-compression_name(int compression)
-{
- static const char *compression_names[] = {
- "uncompressed",
- "shrinking",
- "reduced-1",
- "reduced-2",
- "reduced-3",
- "reduced-4",
- "imploded",
- "reserved",
- "deflation"
- };
-
- if (0 <= compression && compression <
- (int)(sizeof(compression_names)/sizeof(compression_names[0])))
- return compression_names[compression];
- else
- return "??";
-}
-
-/* Convert an MSDOS-style date/time into Unix-style time. */
-static time_t
-zip_time(const char *p)
-{
- int msTime, msDate;
- struct tm ts;
-
- msTime = (0xff & (unsigned)p[0]) + 256 * (0xff & (unsigned)p[1]);
- msDate = (0xff & (unsigned)p[2]) + 256 * (0xff & (unsigned)p[3]);
-
- memset(&ts, 0, sizeof(ts));
- ts.tm_year = ((msDate >> 9) & 0x7f) + 80; /* Years since 1900. */
- ts.tm_mon = ((msDate >> 5) & 0x0f) - 1; /* Month number. */
- ts.tm_mday = msDate & 0x1f; /* Day of month. */
- ts.tm_hour = (msTime >> 11) & 0x1f;
- ts.tm_min = (msTime >> 5) & 0x3f;
- ts.tm_sec = (msTime << 1) & 0x3e;
- ts.tm_isdst = -1;
- return mktime(&ts);
-}
-
static int
-archive_read_format_zip_read_data(struct archive_read *a,
- const void **buff, size_t *size, int64_t *offset)
+check_authentication_code(struct archive_read *a, const void *_p)
{
- int r;
struct zip *zip = (struct zip *)(a->format->data);
- *offset = zip->entry_uncompressed_bytes_read;
- *size = 0;
- *buff = NULL;
-
- /* If we hit end-of-entry last time, return ARCHIVE_EOF. */
- if (zip->end_of_entry)
- return (ARCHIVE_EOF);
-
- /* Return EOF immediately if this is a non-regular file. */
- if (AE_IFREG != (zip->entry->mode & AE_IFMT))
- return (ARCHIVE_EOF);
-
- if (zip->entry->flags & (ZIP_ENCRYPTED | ZIP_STRONG_ENCRYPTED)) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Encrypted file is unsupported");
- return (ARCHIVE_FAILED);
- }
-
- zip_read_consume(a, zip->unconsumed);
- zip->unconsumed = 0;
-
- switch(zip->entry->compression) {
- case 0: /* No compression. */
- r = zip_read_data_none(a, buff, size, offset);
- break;
-#ifdef HAVE_ZLIB_H
- case 8: /* Deflate compression. */
- r = zip_read_data_deflate(a, buff, size, offset);
- break;
-#endif
- default: /* Unsupported compression. */
- /* Return a warning. */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Unsupported ZIP compression method (%s)",
- compression_name(zip->entry->compression));
- /* We can't decompress this entry, but we will
- * be able to skip() it and try the next entry. */
- return (ARCHIVE_FAILED);
- break;
- }
- if (r != ARCHIVE_OK)
- return (r);
- /* Update checksum */
- if (*size)
- zip->entry_crc32 = crc32(zip->entry_crc32, *buff,
- (unsigned)*size);
- /* If we hit the end, swallow any end-of-data marker. */
- if (zip->end_of_entry) {
- /* Check file size, CRC against these values. */
- if (zip->entry->compressed_size !=
- zip->entry_compressed_bytes_read) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "ZIP compressed data is wrong size "
- "(read %jd, expected %jd)",
- (intmax_t)zip->entry_compressed_bytes_read,
- (intmax_t)zip->entry->compressed_size);
- return (ARCHIVE_WARN);
- }
- /* Size field only stores the lower 32 bits of the actual
- * size. */
- if ((zip->entry->uncompressed_size & UINT32_MAX)
- != (zip->entry_uncompressed_bytes_read & UINT32_MAX)) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "ZIP uncompressed data is wrong size "
- "(read %jd, expected %jd)",
- (intmax_t)zip->entry_uncompressed_bytes_read,
- (intmax_t)zip->entry->uncompressed_size);
- return (ARCHIVE_WARN);
+ /* Check authentication code. */
+ if (zip->hctx_valid) {
+ const void *p;
+ uint8_t hmac[20];
+ size_t hmac_len = 20;
+ int cmp;
+
+ archive_hmac_sha1_final(&zip->hctx, hmac, &hmac_len);
+ if (_p == NULL) {
+ /* Read authentication code. */
+ p = __archive_read_ahead(a, AUTH_CODE_SIZE, NULL);
+ if (p == NULL) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated ZIP file data");
+ return (ARCHIVE_FATAL);
+ }
+ } else {
+ p = _p;
}
- /* Check computed CRC against header */
- if (zip->entry->crc32 != zip->entry_crc32) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "ZIP bad CRC: 0x%lx should be 0x%lx",
- (unsigned long)zip->entry_crc32,
- (unsigned long)zip->entry->crc32);
+ cmp = memcmp(hmac, p, AUTH_CODE_SIZE);
+ __archive_read_consume(a, AUTH_CODE_SIZE);
+ if (cmp != 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "ZIP bad Authentication code");
return (ARCHIVE_WARN);
}
}
-
return (ARCHIVE_OK);
}
@@ -1276,9 +1037,10 @@ archive_read_format_zip_read_data(struct archive_read *a,
* TODO: Technically, the PK\007\010 signature is optional.
* In the original spec, the data descriptor contained CRC
* and size fields but had no leading signature. In practice,
- * newer writers seem to provide the signature pretty consistently,
- * but we might need to do something more complex here if
- * we want to handle older archives that lack that signature.
+ * newer writers seem to provide the signature pretty consistently.
+ *
+ * For uncompressed data, the PK\007\010 marker seems essential
+ * to be sure we've actually seen the end of the entry.
*
* Returns ARCHIVE_OK if successful, ARCHIVE_FATAL otherwise, sets
* zip->end_of_entry if it consumes all of the data.
@@ -1290,40 +1052,62 @@ zip_read_data_none(struct archive_read *a, const void **_buff,
struct zip *zip;
const char *buff;
ssize_t bytes_avail;
+ int r;
(void)offset; /* UNUSED */
zip = (struct zip *)(a->format->data);
- if (zip->entry->flags & ZIP_LENGTH_AT_END) {
+ if (zip->entry->zip_flags & ZIP_LENGTH_AT_END) {
const char *p;
+ ssize_t grabbing_bytes = 24;
- /* Grab at least 16 bytes. */
- buff = __archive_read_ahead(a, 16, &bytes_avail);
- if (bytes_avail < 16) {
+ if (zip->hctx_valid)
+ grabbing_bytes += AUTH_CODE_SIZE;
+ /* Grab at least 24 bytes. */
+ buff = __archive_read_ahead(a, grabbing_bytes, &bytes_avail);
+ if (bytes_avail < grabbing_bytes) {
/* Zip archives have end-of-archive markers
that are longer than this, so a failure to get at
- least 16 bytes really does indicate a truncated
+ least 24 bytes really does indicate a truncated
file. */
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated ZIP file data");
return (ARCHIVE_FATAL);
}
- /* Check for a complete PK\007\010 signature. */
+ /* Check for a complete PK\007\010 signature, followed
+ * by the correct 4-byte CRC. */
p = buff;
- if (p[0] == 'P' && p[1] == 'K'
+ if (zip->hctx_valid)
+ p += AUTH_CODE_SIZE;
+ if (p[0] == 'P' && p[1] == 'K'
&& p[2] == '\007' && p[3] == '\010'
- && archive_le32dec(p + 4) == zip->entry_crc32
- && archive_le32dec(p + 8) ==
- zip->entry_compressed_bytes_read
- && archive_le32dec(p + 12) ==
- zip->entry_uncompressed_bytes_read) {
- zip->entry->crc32 = archive_le32dec(p + 4);
- zip->entry->compressed_size = archive_le32dec(p + 8);
- zip->entry->uncompressed_size = archive_le32dec(p + 12);
+ && (archive_le32dec(p + 4) == zip->entry_crc32
+ || zip->ignore_crc32
+ || (zip->hctx_valid
+ && zip->entry->aes_extra.vendor == AES_VENDOR_AE_2))) {
+ if (zip->entry->flags & LA_USED_ZIP64) {
+ zip->entry->crc32 = archive_le32dec(p + 4);
+ zip->entry->compressed_size =
+ archive_le64dec(p + 8);
+ zip->entry->uncompressed_size =
+ archive_le64dec(p + 16);
+ zip->unconsumed = 24;
+ } else {
+ zip->entry->crc32 = archive_le32dec(p + 4);
+ zip->entry->compressed_size =
+ archive_le32dec(p + 8);
+ zip->entry->uncompressed_size =
+ archive_le32dec(p + 12);
+ zip->unconsumed = 16;
+ }
+ if (zip->hctx_valid) {
+ r = check_authentication_code(a, buff);
+ if (r != ARCHIVE_OK)
+ return (r);
+ }
zip->end_of_entry = 1;
- zip->unconsumed = 16;
return (ARCHIVE_OK);
}
/* If not at EOF, ensure we consume at least one byte. */
@@ -1339,6 +1123,8 @@ zip_read_data_none(struct archive_read *a, const void **_buff,
else if (p[3] == '\007') { p += 1; }
else if (p[3] == '\010' && p[2] == '\007'
&& p[1] == 'K' && p[0] == 'P') {
+ if (zip->hctx_valid)
+ p -= AUTH_CODE_SIZE;
break;
} else { p += 4; }
}
@@ -1346,6 +1132,11 @@ zip_read_data_none(struct archive_read *a, const void **_buff,
} else {
if (zip->entry_bytes_remaining == 0) {
zip->end_of_entry = 1;
+ if (zip->hctx_valid) {
+ r = check_authentication_code(a, NULL);
+ if (r != ARCHIVE_OK)
+ return (r);
+ }
return (ARCHIVE_OK);
}
/* Grab a bunch of bytes. */
@@ -1359,6 +1150,26 @@ zip_read_data_none(struct archive_read *a, const void **_buff,
if (bytes_avail > zip->entry_bytes_remaining)
bytes_avail = (ssize_t)zip->entry_bytes_remaining;
}
+ if (zip->tctx_valid || zip->cctx_valid) {
+ size_t dec_size = bytes_avail;
+
+ if (dec_size > zip->decrypted_buffer_size)
+ dec_size = zip->decrypted_buffer_size;
+ if (zip->tctx_valid) {
+ trad_enc_decrypt_update(&zip->tctx,
+ (const uint8_t *)buff, dec_size,
+ zip->decrypted_buffer, dec_size);
+ } else {
+ size_t dsize = dec_size;
+ archive_hmac_sha1_update(&zip->hctx,
+ (const uint8_t *)buff, dec_size);
+ archive_decrypto_aes_ctr_update(&zip->cctx,
+ (const uint8_t *)buff, dec_size,
+ zip->decrypted_buffer, &dsize);
+ }
+ bytes_avail = dec_size;
+ buff = (const char *)zip->decrypted_buffer;
+ }
*size = bytes_avail;
zip->entry_bytes_remaining -= bytes_avail;
zip->entry_uncompressed_bytes_read += bytes_avail;
@@ -1400,7 +1211,7 @@ zip_read_data_deflate(struct archive_read *a, const void **buff,
{
struct zip *zip;
ssize_t bytes_avail;
- const void *compressed_buff;
+ const void *compressed_buff, *sp;
int r;
(void)offset; /* UNUSED */
@@ -1429,8 +1240,8 @@ zip_read_data_deflate(struct archive_read *a, const void **buff,
* available bytes; asking for more than that forces the
* decompressor to combine reads by copying data.
*/
- compressed_buff = __archive_read_ahead(a, 1, &bytes_avail);
- if (0 == (zip->entry->flags & ZIP_LENGTH_AT_END)
+ compressed_buff = sp = __archive_read_ahead(a, 1, &bytes_avail);
+ if (0 == (zip->entry->zip_flags & ZIP_LENGTH_AT_END)
&& bytes_avail > zip->entry_bytes_remaining) {
bytes_avail = (ssize_t)zip->entry_bytes_remaining;
}
@@ -1440,6 +1251,51 @@ zip_read_data_deflate(struct archive_read *a, const void **buff,
return (ARCHIVE_FATAL);
}
+ if (zip->tctx_valid || zip->cctx_valid) {
+ if (zip->decrypted_bytes_remaining < (size_t)bytes_avail) {
+ size_t buff_remaining = zip->decrypted_buffer_size
+ - (zip->decrypted_ptr - zip->decrypted_buffer);
+
+ if (buff_remaining > (size_t)bytes_avail)
+ buff_remaining = (size_t)bytes_avail;
+
+ if (0 == (zip->entry->zip_flags & ZIP_LENGTH_AT_END) &&
+ zip->entry_bytes_remaining > 0) {
+ if ((int64_t)(zip->decrypted_bytes_remaining
+ + buff_remaining)
+ > zip->entry_bytes_remaining) {
+ if (zip->entry_bytes_remaining <
+ (int64_t)zip->decrypted_bytes_remaining)
+ buff_remaining = 0;
+ else
+ buff_remaining =
+ (size_t)zip->entry_bytes_remaining
+ - zip->decrypted_bytes_remaining;
+ }
+ }
+ if (buff_remaining > 0) {
+ if (zip->tctx_valid) {
+ trad_enc_decrypt_update(&zip->tctx,
+ compressed_buff, buff_remaining,
+ zip->decrypted_ptr
+ + zip->decrypted_bytes_remaining,
+ buff_remaining);
+ } else {
+ size_t dsize = buff_remaining;
+ archive_decrypto_aes_ctr_update(
+ &zip->cctx,
+ compressed_buff, buff_remaining,
+ zip->decrypted_ptr
+ + zip->decrypted_bytes_remaining,
+ &dsize);
+ }
+ zip->decrypted_bytes_remaining += buff_remaining;
+ }
+ }
+ bytes_avail = zip->decrypted_bytes_remaining;
+ compressed_buff = (const char *)zip->decrypted_ptr;
+ }
+
/*
* A bug in zlib.h: stream.next_in should be marked 'const'
* but isn't (the library never alters data through the
@@ -1472,7 +1328,17 @@ zip_read_data_deflate(struct archive_read *a, const void **buff,
/* Consume as much as the compressor actually used. */
bytes_avail = zip->stream.total_in;
- zip_read_consume(a, bytes_avail);
+ if (zip->tctx_valid || zip->cctx_valid) {
+ zip->decrypted_bytes_remaining -= bytes_avail;
+ if (zip->decrypted_bytes_remaining == 0)
+ zip->decrypted_ptr = zip->decrypted_buffer;
+ else
+ zip->decrypted_ptr += bytes_avail;
+ }
+ /* Calculate compressed data as much as we used.*/
+ if (zip->hctx_valid)
+ archive_hmac_sha1_update(&zip->hctx, sp, bytes_avail);
+ __archive_read_consume(a, bytes_avail);
zip->entry_bytes_remaining -= bytes_avail;
zip->entry_compressed_bytes_read += bytes_avail;
@@ -1480,10 +1346,16 @@ zip_read_data_deflate(struct archive_read *a, const void **buff,
zip->entry_uncompressed_bytes_read += zip->stream.total_out;
*buff = zip->uncompressed_buffer;
- if (zip->end_of_entry && (zip->entry->flags & ZIP_LENGTH_AT_END)) {
+ if (zip->end_of_entry && zip->hctx_valid) {
+ r = check_authentication_code(a, NULL);
+ if (r != ARCHIVE_OK)
+ return (r);
+ }
+
+ if (zip->end_of_entry && (zip->entry->zip_flags & ZIP_LENGTH_AT_END)) {
const char *p;
- if (NULL == (p = __archive_read_ahead(a, 16, NULL))) {
+ if (NULL == (p = __archive_read_ahead(a, 24, NULL))) {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated ZIP end-of-file record");
@@ -1492,10 +1364,19 @@ zip_read_data_deflate(struct archive_read *a, const void **buff,
/* Consume the optional PK\007\010 marker. */
if (p[0] == 'P' && p[1] == 'K' &&
p[2] == '\007' && p[3] == '\010') {
- zip->entry->crc32 = archive_le32dec(p + 4);
- zip->entry->compressed_size = archive_le32dec(p + 8);
- zip->entry->uncompressed_size = archive_le32dec(p + 12);
- zip->unconsumed = 16;
+ p += 4;
+ zip->unconsumed = 4;
+ }
+ if (zip->entry->flags & LA_USED_ZIP64) {
+ zip->entry->crc32 = archive_le32dec(p);
+ zip->entry->compressed_size = archive_le64dec(p + 4);
+ zip->entry->uncompressed_size = archive_le64dec(p + 12);
+ zip->unconsumed += 20;
+ } else {
+ zip->entry->crc32 = archive_le32dec(p);
+ zip->entry->compressed_size = archive_le32dec(p + 4);
+ zip->entry->uncompressed_size = archive_le32dec(p + 8);
+ zip->unconsumed += 12;
}
}
@@ -1504,27 +1385,780 @@ zip_read_data_deflate(struct archive_read *a, const void **buff,
#endif
static int
-archive_read_format_zip_read_data_skip(struct archive_read *a)
+read_decryption_header(struct archive_read *a)
+{
+ struct zip *zip = (struct zip *)(a->format->data);
+ const char *p;
+ unsigned int remaining_size;
+ unsigned int ts;
+
+ /*
+ * Read an initialization vector data field.
+ */
+ p = __archive_read_ahead(a, 2, NULL);
+ if (p == NULL)
+ goto truncated;
+ ts = zip->iv_size;
+ zip->iv_size = archive_le16dec(p);
+ __archive_read_consume(a, 2);
+ if (ts < zip->iv_size) {
+ free(zip->iv);
+ zip->iv = NULL;
+ }
+ p = __archive_read_ahead(a, zip->iv_size, NULL);
+ if (p == NULL)
+ goto truncated;
+ if (zip->iv == NULL) {
+ zip->iv = malloc(zip->iv_size);
+ if (zip->iv == NULL)
+ goto nomem;
+ }
+ memcpy(zip->iv, p, zip->iv_size);
+ __archive_read_consume(a, zip->iv_size);
+
+ /*
+ * Read a size of remaining decryption header field.
+ */
+ p = __archive_read_ahead(a, 14, NULL);
+ if (p == NULL)
+ goto truncated;
+ remaining_size = archive_le32dec(p);
+ if (remaining_size < 16 || remaining_size > (1 << 18))
+ goto corrupted;
+
+ /* Check if format version is supported. */
+ if (archive_le16dec(p+4) != 3) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unsupported encryption format version: %u",
+ archive_le16dec(p+4));
+ return (ARCHIVE_FAILED);
+ }
+
+ /*
+ * Read an encryption algorithm field.
+ */
+ zip->alg_id = archive_le16dec(p+6);
+ switch (zip->alg_id) {
+ case 0x6601:/* DES */
+ case 0x6602:/* RC2 */
+ case 0x6603:/* 3DES 168 */
+ case 0x6609:/* 3DES 112 */
+ case 0x660E:/* AES 128 */
+ case 0x660F:/* AES 192 */
+ case 0x6610:/* AES 256 */
+ case 0x6702:/* RC2 (version >= 5.2) */
+ case 0x6720:/* Blowfish */
+ case 0x6721:/* Twofish */
+ case 0x6801:/* RC4 */
+ /* Suuported encryption algorithm. */
+ break;
+ default:
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unknown encryption algorithm: %u", zip->alg_id);
+ return (ARCHIVE_FAILED);
+ }
+
+ /*
+ * Read a bit length field.
+ */
+ zip->bit_len = archive_le16dec(p+8);
+
+ /*
+ * Read a flags field.
+ */
+ zip->flags = archive_le16dec(p+10);
+ switch (zip->flags & 0xf000) {
+ case 0x0001: /* Password is required to decrypt. */
+ case 0x0002: /* Certificates only. */
+ case 0x0003: /* Password or certificate required to decrypt. */
+ break;
+ default:
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unknown encryption flag: %u", zip->flags);
+ return (ARCHIVE_FAILED);
+ }
+ if ((zip->flags & 0xf000) == 0 ||
+ (zip->flags & 0xf000) == 0x4000) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unknown encryption flag: %u", zip->flags);
+ return (ARCHIVE_FAILED);
+ }
+
+ /*
+ * Read an encrypted random data field.
+ */
+ ts = zip->erd_size;
+ zip->erd_size = archive_le16dec(p+12);
+ __archive_read_consume(a, 14);
+ if ((zip->erd_size & 0xf) != 0 ||
+ (zip->erd_size + 16) > remaining_size ||
+ (zip->erd_size + 16) < zip->erd_size)
+ goto corrupted;
+
+ if (ts < zip->erd_size) {
+ free(zip->erd);
+ zip->erd = NULL;
+ }
+ p = __archive_read_ahead(a, zip->erd_size, NULL);
+ if (p == NULL)
+ goto truncated;
+ if (zip->erd == NULL) {
+ zip->erd = malloc(zip->erd_size);
+ if (zip->erd == NULL)
+ goto nomem;
+ }
+ memcpy(zip->erd, p, zip->erd_size);
+ __archive_read_consume(a, zip->erd_size);
+
+ /*
+ * Read a reserved data field.
+ */
+ p = __archive_read_ahead(a, 4, NULL);
+ if (p == NULL)
+ goto truncated;
+ /* Reserved data size should be zero. */
+ if (archive_le32dec(p) != 0)
+ goto corrupted;
+ __archive_read_consume(a, 4);
+
+ /*
+ * Read a password validation data field.
+ */
+ p = __archive_read_ahead(a, 2, NULL);
+ if (p == NULL)
+ goto truncated;
+ ts = zip->v_size;
+ zip->v_size = archive_le16dec(p);
+ __archive_read_consume(a, 2);
+ if ((zip->v_size & 0x0f) != 0 ||
+ (zip->erd_size + zip->v_size + 16) > remaining_size ||
+ (zip->erd_size + zip->v_size + 16) < (zip->erd_size + zip->v_size))
+ goto corrupted;
+ if (ts < zip->v_size) {
+ free(zip->v_data);
+ zip->v_data = NULL;
+ }
+ p = __archive_read_ahead(a, zip->v_size, NULL);
+ if (p == NULL)
+ goto truncated;
+ if (zip->v_data == NULL) {
+ zip->v_data = malloc(zip->v_size);
+ if (zip->v_data == NULL)
+ goto nomem;
+ }
+ memcpy(zip->v_data, p, zip->v_size);
+ __archive_read_consume(a, zip->v_size);
+
+ p = __archive_read_ahead(a, 4, NULL);
+ if (p == NULL)
+ goto truncated;
+ zip->v_crc32 = archive_le32dec(p);
+ __archive_read_consume(a, 4);
+
+ /*return (ARCHIVE_OK);
+ * This is not fully implemnted yet.*/
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Encrypted file is unsupported");
+ return (ARCHIVE_FAILED);
+truncated:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated ZIP file data");
+ return (ARCHIVE_FATAL);
+corrupted:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Corrupted ZIP file data");
+ return (ARCHIVE_FATAL);
+nomem:
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for ZIP decryption");
+ return (ARCHIVE_FATAL);
+}
+
+static int
+zip_alloc_decryption_buffer(struct archive_read *a)
+{
+ struct zip *zip = (struct zip *)(a->format->data);
+ size_t bs = 256 * 1024;
+
+ if (zip->decrypted_buffer == NULL) {
+ zip->decrypted_buffer_size = bs;
+ zip->decrypted_buffer = malloc(bs);
+ if (zip->decrypted_buffer == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for ZIP decryption");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ zip->decrypted_ptr = zip->decrypted_buffer;
+ return (ARCHIVE_OK);
+}
+
+static int
+init_traditional_PKWARE_decryption(struct archive_read *a)
+{
+ struct zip *zip = (struct zip *)(a->format->data);
+ const void *p;
+ int retry;
+ int r;
+
+ if (zip->tctx_valid)
+ return (ARCHIVE_OK);
+
+ /*
+ Read the 12 bytes encryption header stored at
+ the start of the data area.
+ */
+#define ENC_HEADER_SIZE 12
+ if (0 == (zip->entry->zip_flags & ZIP_LENGTH_AT_END)
+ && zip->entry_bytes_remaining < ENC_HEADER_SIZE) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated Zip encrypted body: only %jd bytes available",
+ (intmax_t)zip->entry_bytes_remaining);
+ return (ARCHIVE_FATAL);
+ }
+
+ p = __archive_read_ahead(a, ENC_HEADER_SIZE, NULL);
+ if (p == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated ZIP file data");
+ return (ARCHIVE_FATAL);
+ }
+
+ for (retry = 0;; retry++) {
+ const char *passphrase;
+ uint8_t crcchk;
+
+ passphrase = __archive_read_next_passphrase(a);
+ if (passphrase == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ (retry > 0)?
+ "Incorrect passphrase":
+ "Passphrase required for this entry");
+ return (ARCHIVE_FAILED);
+ }
+
+ /*
+ * Initialize ctx for Traditional PKWARE Decyption.
+ */
+ r = trad_enc_init(&zip->tctx, passphrase, strlen(passphrase),
+ p, ENC_HEADER_SIZE, &crcchk);
+ if (r == 0 && crcchk == zip->entry->decdat)
+ break;/* The passphrase is OK. */
+ if (retry > 10000) {
+ /* Avoid infinity loop. */
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Too many incorrect passphrases");
+ return (ARCHIVE_FAILED);
+ }
+ }
+
+ __archive_read_consume(a, ENC_HEADER_SIZE);
+ zip->tctx_valid = 1;
+ if (0 == (zip->entry->zip_flags & ZIP_LENGTH_AT_END)) {
+ zip->entry_bytes_remaining -= ENC_HEADER_SIZE;
+ }
+ /*zip->entry_uncompressed_bytes_read += ENC_HEADER_SIZE;*/
+ zip->entry_compressed_bytes_read += ENC_HEADER_SIZE;
+ zip->decrypted_bytes_remaining = 0;
+
+ return (zip_alloc_decryption_buffer(a));
+#undef ENC_HEADER_SIZE
+}
+
+static int
+init_WinZip_AES_decryption(struct archive_read *a)
+{
+ struct zip *zip = (struct zip *)(a->format->data);
+ const void *p;
+ const uint8_t *pv;
+ size_t key_len, salt_len;
+ uint8_t derived_key[MAX_DERIVED_KEY_BUF_SIZE];
+ int retry;
+ int r;
+
+ if (zip->cctx_valid || zip->hctx_valid)
+ return (ARCHIVE_OK);
+
+ switch (zip->entry->aes_extra.strength) {
+ case 1: salt_len = 8; key_len = 16; break;
+ case 2: salt_len = 12; key_len = 24; break;
+ case 3: salt_len = 16; key_len = 32; break;
+ default: goto corrupted;
+ }
+ p = __archive_read_ahead(a, salt_len + 2, NULL);
+ if (p == NULL)
+ goto truncated;
+
+ for (retry = 0;; retry++) {
+ const char *passphrase;
+
+ passphrase = __archive_read_next_passphrase(a);
+ if (passphrase == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ (retry > 0)?
+ "Incorrect passphrase":
+ "Passphrase required for this entry");
+ return (ARCHIVE_FAILED);
+ }
+ memset(derived_key, 0, sizeof(derived_key));
+ r = archive_pbkdf2_sha1(passphrase, strlen(passphrase),
+ p, salt_len, 1000, derived_key, key_len * 2 + 2);
+ if (r != 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Decryption is unsupported due to lack of "
+ "crypto library");
+ return (ARCHIVE_FAILED);
+ }
+
+ /* Check password verification value. */
+ pv = ((const uint8_t *)p) + salt_len;
+ if (derived_key[key_len * 2] == pv[0] &&
+ derived_key[key_len * 2 + 1] == pv[1])
+ break;/* The passphrase is OK. */
+ if (retry > 10000) {
+ /* Avoid infinity loop. */
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Too many incorrect passphrases");
+ return (ARCHIVE_FAILED);
+ }
+ }
+
+ r = archive_decrypto_aes_ctr_init(&zip->cctx, derived_key, key_len);
+ if (r != 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Decryption is unsupported due to lack of crypto library");
+ return (ARCHIVE_FAILED);
+ }
+ r = archive_hmac_sha1_init(&zip->hctx, derived_key + key_len, key_len);
+ if (r != 0) {
+ archive_decrypto_aes_ctr_release(&zip->cctx);
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Failed to initialize HMAC-SHA1");
+ return (ARCHIVE_FAILED);
+ }
+ zip->cctx_valid = zip->hctx_valid = 1;
+ __archive_read_consume(a, salt_len + 2);
+ zip->entry_bytes_remaining -= salt_len + 2 + AUTH_CODE_SIZE;
+ if (0 == (zip->entry->zip_flags & ZIP_LENGTH_AT_END)
+ && zip->entry_bytes_remaining < 0)
+ goto corrupted;
+ zip->entry_compressed_bytes_read += salt_len + 2 + AUTH_CODE_SIZE;
+ zip->decrypted_bytes_remaining = 0;
+
+ zip->entry->compression = zip->entry->aes_extra.compression;
+ return (zip_alloc_decryption_buffer(a));
+
+truncated:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated ZIP file data");
+ return (ARCHIVE_FATAL);
+corrupted:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Corrupted ZIP file data");
+ return (ARCHIVE_FATAL);
+}
+
+static int
+archive_read_format_zip_read_data(struct archive_read *a,
+ const void **buff, size_t *size, int64_t *offset)
+{
+ int r;
+ struct zip *zip = (struct zip *)(a->format->data);
+
+ if (zip->has_encrypted_entries ==
+ ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
+ zip->has_encrypted_entries = 0;
+ }
+
+ *offset = zip->entry_uncompressed_bytes_read;
+ *size = 0;
+ *buff = NULL;
+
+ /* If we hit end-of-entry last time, return ARCHIVE_EOF. */
+ if (zip->end_of_entry)
+ return (ARCHIVE_EOF);
+
+ /* Return EOF immediately if this is a non-regular file. */
+ if (AE_IFREG != (zip->entry->mode & AE_IFMT))
+ return (ARCHIVE_EOF);
+
+ __archive_read_consume(a, zip->unconsumed);
+ zip->unconsumed = 0;
+
+ if (zip->init_decryption) {
+ zip->has_encrypted_entries = 1;
+ if (zip->entry->zip_flags & ZIP_STRONG_ENCRYPTED)
+ r = read_decryption_header(a);
+ else if (zip->entry->compression == WINZIP_AES_ENCRYPTION)
+ r = init_WinZip_AES_decryption(a);
+ else
+ r = init_traditional_PKWARE_decryption(a);
+ if (r != ARCHIVE_OK)
+ return (r);
+ zip->init_decryption = 0;
+ }
+
+ switch(zip->entry->compression) {
+ case 0: /* No compression. */
+ r = zip_read_data_none(a, buff, size, offset);
+ break;
+#ifdef HAVE_ZLIB_H
+ case 8: /* Deflate compression. */
+ r = zip_read_data_deflate(a, buff, size, offset);
+ break;
+#endif
+ default: /* Unsupported compression. */
+ /* Return a warning. */
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unsupported ZIP compression method (%s)",
+ compression_name(zip->entry->compression));
+ /* We can't decompress this entry, but we will
+ * be able to skip() it and try the next entry. */
+ return (ARCHIVE_FAILED);
+ break;
+ }
+ if (r != ARCHIVE_OK)
+ return (r);
+ /* Update checksum */
+ if (*size)
+ zip->entry_crc32 = zip->crc32func(zip->entry_crc32, *buff,
+ (unsigned)*size);
+ /* If we hit the end, swallow any end-of-data marker. */
+ if (zip->end_of_entry) {
+ /* Check file size, CRC against these values. */
+ if (zip->entry->compressed_size !=
+ zip->entry_compressed_bytes_read) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "ZIP compressed data is wrong size "
+ "(read %jd, expected %jd)",
+ (intmax_t)zip->entry_compressed_bytes_read,
+ (intmax_t)zip->entry->compressed_size);
+ return (ARCHIVE_WARN);
+ }
+ /* Size field only stores the lower 32 bits of the actual
+ * size. */
+ if ((zip->entry->uncompressed_size & UINT32_MAX)
+ != (zip->entry_uncompressed_bytes_read & UINT32_MAX)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "ZIP uncompressed data is wrong size "
+ "(read %jd, expected %jd)\n",
+ (intmax_t)zip->entry_uncompressed_bytes_read,
+ (intmax_t)zip->entry->uncompressed_size);
+ return (ARCHIVE_WARN);
+ }
+ /* Check computed CRC against header */
+ if ((!zip->hctx_valid ||
+ zip->entry->aes_extra.vendor != AES_VENDOR_AE_2) &&
+ zip->entry->crc32 != zip->entry_crc32
+ && !zip->ignore_crc32) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "ZIP bad CRC: 0x%lx should be 0x%lx",
+ (unsigned long)zip->entry_crc32,
+ (unsigned long)zip->entry->crc32);
+ return (ARCHIVE_WARN);
+ }
+ }
+
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_read_format_zip_cleanup(struct archive_read *a)
{
struct zip *zip;
+ struct zip_entry *zip_entry, *next_zip_entry;
zip = (struct zip *)(a->format->data);
+#ifdef HAVE_ZLIB_H
+ if (zip->stream_valid)
+ inflateEnd(&zip->stream);
+ free(zip->uncompressed_buffer);
+#endif
+ if (zip->zip_entries) {
+ zip_entry = zip->zip_entries;
+ while (zip_entry != NULL) {
+ next_zip_entry = zip_entry->next;
+ archive_string_free(&zip_entry->rsrcname);
+ free(zip_entry);
+ zip_entry = next_zip_entry;
+ }
+ }
+ free(zip->decrypted_buffer);
+ if (zip->cctx_valid)
+ archive_decrypto_aes_ctr_release(&zip->cctx);
+ if (zip->hctx_valid)
+ archive_hmac_sha1_cleanup(&zip->hctx);
+ free(zip->iv);
+ free(zip->erd);
+ free(zip->v_data);
+ archive_string_free(&zip->format_name);
+ free(zip);
+ (a->format->data) = NULL;
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_read_format_zip_has_encrypted_entries(struct archive_read *_a)
+{
+ if (_a && _a->format) {
+ struct zip * zip = (struct zip *)_a->format->data;
+ if (zip) {
+ return zip->has_encrypted_entries;
+ }
+ }
+ return ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
+}
+
+static int
+archive_read_format_zip_options(struct archive_read *a,
+ const char *key, const char *val)
+{
+ struct zip *zip;
+ int ret = ARCHIVE_FAILED;
+
+ zip = (struct zip *)(a->format->data);
+ if (strcmp(key, "compat-2x") == 0) {
+ /* Handle filenames as libarchive 2.x */
+ zip->init_default_conversion = (val != NULL) ? 1 : 0;
+ return (ARCHIVE_OK);
+ } else if (strcmp(key, "hdrcharset") == 0) {
+ if (val == NULL || val[0] == 0)
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "zip: hdrcharset option needs a character-set name"
+ );
+ else {
+ zip->sconv = archive_string_conversion_from_charset(
+ &a->archive, val, 0);
+ if (zip->sconv != NULL) {
+ if (strcmp(val, "UTF-8") == 0)
+ zip->sconv_utf8 = zip->sconv;
+ ret = ARCHIVE_OK;
+ } else
+ ret = ARCHIVE_FATAL;
+ }
+ return (ret);
+ } else if (strcmp(key, "ignorecrc32") == 0) {
+ /* Mostly useful for testing. */
+ if (val == NULL || val[0] == 0) {
+ zip->crc32func = real_crc32;
+ zip->ignore_crc32 = 0;
+ } else {
+ zip->crc32func = fake_crc32;
+ zip->ignore_crc32 = 1;
+ }
+ return (ARCHIVE_OK);
+ } else if (strcmp(key, "mac-ext") == 0) {
+ zip->process_mac_extensions = (val != NULL && val[0] != 0);
+ return (ARCHIVE_OK);
+ }
+
+ /* Note: The "warn" return is just to inform the options
+ * supervisor that we didn't handle it. It will generate
+ * a suitable error if no one used this option. */
+ return (ARCHIVE_WARN);
+}
+
+int
+archive_read_support_format_zip(struct archive *a)
+{
+ int r;
+ r = archive_read_support_format_zip_streamable(a);
+ if (r != ARCHIVE_OK)
+ return r;
+ return (archive_read_support_format_zip_seekable(a));
+}
+
+/* ------------------------------------------------------------------------ */
+
+/*
+ * Streaming-mode support
+ */
+
+
+static int
+archive_read_support_format_zip_capabilities_streamable(struct archive_read * a)
+{
+ (void)a; /* UNUSED */
+ return (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA |
+ ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA);
+}
+
+static int
+archive_read_format_zip_streamable_bid(struct archive_read *a, int best_bid)
+{
+ const char *p;
+
+ (void)best_bid; /* UNUSED */
+
+ if ((p = __archive_read_ahead(a, 4, NULL)) == NULL)
+ return (-1);
+
+ /*
+ * Bid of 29 here comes from:
+ * + 16 bits for "PK",
+ * + next 16-bit field has 6 options so contributes
+ * about 16 - log_2(6) ~= 16 - 2.6 ~= 13 bits
+ *
+ * So we've effectively verified ~29 total bits of check data.
+ */
+ if (p[0] == 'P' && p[1] == 'K') {
+ if ((p[2] == '\001' && p[3] == '\002')
+ || (p[2] == '\003' && p[3] == '\004')
+ || (p[2] == '\005' && p[3] == '\006')
+ || (p[2] == '\006' && p[3] == '\006')
+ || (p[2] == '\007' && p[3] == '\010')
+ || (p[2] == '0' && p[3] == '0'))
+ return (29);
+ }
+
+ /* TODO: It's worth looking ahead a little bit for a valid
+ * PK signature. In particular, that would make it possible
+ * to read some UUEncoded SFX files or SFX files coming from
+ * a network socket. */
+
+ return (0);
+}
+
+static int
+archive_read_format_zip_streamable_read_header(struct archive_read *a,
+ struct archive_entry *entry)
+{
+ struct zip *zip;
+
+ a->archive.archive_format = ARCHIVE_FORMAT_ZIP;
+ if (a->archive.archive_format_name == NULL)
+ a->archive.archive_format_name = "ZIP";
+
+ zip = (struct zip *)(a->format->data);
+
+ /*
+ * It should be sufficient to call archive_read_next_header() for
+ * a reader to determine if an entry is encrypted or not. If the
+ * encryption of an entry is only detectable when calling
+ * archive_read_data(), so be it. We'll do the same check there
+ * as well.
+ */
+ if (zip->has_encrypted_entries ==
+ ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW)
+ zip->has_encrypted_entries = 0;
+
+ /* Make sure we have a zip_entry structure to use. */
+ if (zip->zip_entries == NULL) {
+ zip->zip_entries = malloc(sizeof(struct zip_entry));
+ if (zip->zip_entries == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Out of memory");
+ return ARCHIVE_FATAL;
+ }
+ }
+ zip->entry = zip->zip_entries;
+ memset(zip->entry, 0, sizeof(struct zip_entry));
+
+ if (zip->cctx_valid)
+ archive_decrypto_aes_ctr_release(&zip->cctx);
+ if (zip->hctx_valid)
+ archive_hmac_sha1_cleanup(&zip->hctx);
+ zip->tctx_valid = zip->cctx_valid = zip->hctx_valid = 0;
+ __archive_read_reset_passphrase(a);
+
+ /* Search ahead for the next local file header. */
+ __archive_read_consume(a, zip->unconsumed);
+ zip->unconsumed = 0;
+ for (;;) {
+ int64_t skipped = 0;
+ const char *p, *end;
+ ssize_t bytes;
+
+ p = __archive_read_ahead(a, 4, &bytes);
+ if (p == NULL)
+ return (ARCHIVE_FATAL);
+ end = p + bytes;
+
+ while (p + 4 <= end) {
+ if (p[0] == 'P' && p[1] == 'K') {
+ if (p[2] == '\003' && p[3] == '\004') {
+ /* Regular file entry. */
+ __archive_read_consume(a, skipped);
+ return zip_read_local_file_header(a,
+ entry, zip);
+ }
+
+ /*
+ * TODO: We cannot restore permissions
+ * based only on the local file headers.
+ * Consider scanning the central
+ * directory and returning additional
+ * entries for at least directories.
+ * This would allow us to properly set
+ * directory permissions.
+ *
+ * This won't help us fix symlinks
+ * and may not help with regular file
+ * permissions, either. <sigh>
+ */
+ if (p[2] == '\001' && p[3] == '\002') {
+ return (ARCHIVE_EOF);
+ }
+
+ /* End of central directory? Must be an
+ * empty archive. */
+ if ((p[2] == '\005' && p[3] == '\006')
+ || (p[2] == '\006' && p[3] == '\006'))
+ return (ARCHIVE_EOF);
+ }
+ ++p;
+ ++skipped;
+ }
+ __archive_read_consume(a, skipped);
+ }
+}
+
+static int
+archive_read_format_zip_read_data_skip_streamable(struct archive_read *a)
+{
+ struct zip *zip;
+ int64_t bytes_skipped;
+
+ zip = (struct zip *)(a->format->data);
+ bytes_skipped = __archive_read_consume(a, zip->unconsumed);
+ zip->unconsumed = 0;
+ if (bytes_skipped < 0)
+ return (ARCHIVE_FATAL);
/* If we've already read to end of data, we're done. */
if (zip->end_of_entry)
return (ARCHIVE_OK);
/* So we know we're streaming... */
- if (0 == (zip->entry->flags & ZIP_LENGTH_AT_END)) {
+ if (0 == (zip->entry->zip_flags & ZIP_LENGTH_AT_END)
+ || zip->entry->compressed_size > 0) {
/* We know the compressed length, so we can just skip. */
- int64_t bytes_skipped = zip_read_consume(a,
- zip->entry_bytes_remaining + zip->unconsumed);
+ bytes_skipped = __archive_read_consume(a,
+ zip->entry_bytes_remaining);
if (bytes_skipped < 0)
return (ARCHIVE_FATAL);
- zip->unconsumed = 0;
return (ARCHIVE_OK);
}
+ if (zip->init_decryption) {
+ int r;
+
+ zip->has_encrypted_entries = 1;
+ if (zip->entry->zip_flags & ZIP_STRONG_ENCRYPTED)
+ r = read_decryption_header(a);
+ else if (zip->entry->compression == WINZIP_AES_ENCRYPTION)
+ r = init_WinZip_AES_decryption(a);
+ else
+ r = init_traditional_PKWARE_decryption(a);
+ if (r != ARCHIVE_OK)
+ return (r);
+ zip->init_decryption = 0;
+ }
+
/* We're streaming and we don't know the length. */
/* If the body is compressed and we know the format, we can
* find an exact end-of-entry by decompressing it. */
@@ -1544,8 +2178,6 @@ archive_read_format_zip_read_data_skip(struct archive_read *a)
#endif
default: /* Uncompressed or unknown. */
/* Scan for a PK\007\010 signature. */
- zip_read_consume(a, zip->unconsumed);
- zip->unconsumed = 0;
for (;;) {
const char *p, *buff;
ssize_t bytes_avail;
@@ -1563,180 +2195,794 @@ archive_read_format_zip_read_data_skip(struct archive_read *a)
else if (p[3] == '\007') { p += 1; }
else if (p[3] == '\010' && p[2] == '\007'
&& p[1] == 'K' && p[0] == 'P') {
- zip_read_consume(a, p - buff + 16);
+ if (zip->entry->flags & LA_USED_ZIP64)
+ __archive_read_consume(a,
+ p - buff + 24);
+ else
+ __archive_read_consume(a,
+ p - buff + 16);
return ARCHIVE_OK;
} else { p += 4; }
}
- zip_read_consume(a, p - buff);
+ __archive_read_consume(a, p - buff);
}
}
}
-static int
-archive_read_format_zip_cleanup(struct archive_read *a)
+int
+archive_read_support_format_zip_streamable(struct archive *_a)
{
+ struct archive_read *a = (struct archive_read *)_a;
struct zip *zip;
+ int r;
- zip = (struct zip *)(a->format->data);
-#ifdef HAVE_ZLIB_H
- if (zip->stream_valid)
- inflateEnd(&zip->stream);
-#endif
- if (zip->zip_entries && zip->central_directory_entries) {
- unsigned i;
- for (i = 0; i < zip->central_directory_entries; i++)
- archive_string_free(&(zip->zip_entries[i].rsrcname));
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_zip");
+
+ zip = (struct zip *)calloc(1, sizeof(*zip));
+ if (zip == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate zip data");
+ return (ARCHIVE_FATAL);
}
- free(zip->zip_entries);
- free(zip->uncompressed_buffer);
- archive_string_free(&(zip->extra));
- free(zip);
- (a->format->data) = NULL;
+
+ /* Streamable reader doesn't support mac extensions. */
+ zip->process_mac_extensions = 0;
+
+ /*
+ * Until enough data has been read, we cannot tell about
+ * any encrypted entries yet.
+ */
+ zip->has_encrypted_entries = ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
+ zip->crc32func = real_crc32;
+
+ r = __archive_read_register_format(a,
+ zip,
+ "zip",
+ archive_read_format_zip_streamable_bid,
+ archive_read_format_zip_options,
+ archive_read_format_zip_streamable_read_header,
+ archive_read_format_zip_read_data,
+ archive_read_format_zip_read_data_skip_streamable,
+ NULL,
+ archive_read_format_zip_cleanup,
+ archive_read_support_format_zip_capabilities_streamable,
+ archive_read_format_zip_has_encrypted_entries);
+
+ if (r != ARCHIVE_OK)
+ free(zip);
return (ARCHIVE_OK);
}
+/* ------------------------------------------------------------------------ */
+
/*
- * The extra data is stored as a list of
- * id1+size1+data1 + id2+size2+data2 ...
- * triplets. id and size are 2 bytes each.
+ * Seeking-mode support
+ */
+
+static int
+archive_read_support_format_zip_capabilities_seekable(struct archive_read * a)
+{
+ (void)a; /* UNUSED */
+ return (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA |
+ ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA);
+}
+
+/*
+ * TODO: This is a performance sink because it forces the read core to
+ * drop buffered data from the start of file, which will then have to
+ * be re-read again if this bidder loses.
+ *
+ * We workaround this a little by passing in the best bid so far so
+ * that later bidders can do nothing if they know they'll never
+ * outbid. But we can certainly do better...
+ */
+static int
+read_eocd(struct zip *zip, const char *p, int64_t current_offset)
+{
+ /* Sanity-check the EOCD we've found. */
+
+ /* This must be the first volume. */
+ if (archive_le16dec(p + 4) != 0)
+ return 0;
+ /* Central directory must be on this volume. */
+ if (archive_le16dec(p + 4) != archive_le16dec(p + 6))
+ return 0;
+ /* All central directory entries must be on this volume. */
+ if (archive_le16dec(p + 10) != archive_le16dec(p + 8))
+ return 0;
+ /* Central directory can't extend beyond start of EOCD record. */
+ if (archive_le32dec(p + 16) + archive_le32dec(p + 12)
+ > current_offset)
+ return 0;
+
+ /* Save the central directory location for later use. */
+ zip->central_directory_offset = archive_le32dec(p + 16);
+
+ /* This is just a tiny bit higher than the maximum
+ returned by the streaming Zip bidder. This ensures
+ that the more accurate seeking Zip parser wins
+ whenever seek is available. */
+ return 32;
+}
+
+/*
+ * Examine Zip64 EOCD locator: If it's valid, store the information
+ * from it.
*/
static void
-process_extra(const char *p, size_t extra_length, struct zip_entry* zip_entry)
+read_zip64_eocd(struct archive_read *a, struct zip *zip, const char *p)
{
- unsigned offset = 0;
+ int64_t eocd64_offset;
+ int64_t eocd64_size;
+
+ /* Sanity-check the locator record. */
+
+ /* Central dir must be on first volume. */
+ if (archive_le32dec(p + 4) != 0)
+ return;
+ /* Must be only a single volume. */
+ if (archive_le32dec(p + 16) != 1)
+ return;
+
+ /* Find the Zip64 EOCD record. */
+ eocd64_offset = archive_le64dec(p + 8);
+ if (__archive_read_seek(a, eocd64_offset, SEEK_SET) < 0)
+ return;
+ if ((p = __archive_read_ahead(a, 56, NULL)) == NULL)
+ return;
+ /* Make sure we can read all of it. */
+ eocd64_size = archive_le64dec(p + 4) + 12;
+ if (eocd64_size < 56 || eocd64_size > 16384)
+ return;
+ if ((p = __archive_read_ahead(a, (size_t)eocd64_size, NULL)) == NULL)
+ return;
+
+ /* Sanity-check the EOCD64 */
+ if (archive_le32dec(p + 16) != 0) /* Must be disk #0 */
+ return;
+ if (archive_le32dec(p + 20) != 0) /* CD must be on disk #0 */
+ return;
+ /* CD can't be split. */
+ if (archive_le64dec(p + 24) != archive_le64dec(p + 32))
+ return;
+
+ /* Save the central directory offset for later use. */
+ zip->central_directory_offset = archive_le64dec(p + 48);
+}
- while (offset < extra_length - 4)
- {
- unsigned short headerid = archive_le16dec(p + offset);
- unsigned short datasize = archive_le16dec(p + offset + 2);
- offset += 4;
- if (offset + datasize > extra_length)
+static int
+archive_read_format_zip_seekable_bid(struct archive_read *a, int best_bid)
+{
+ struct zip *zip = (struct zip *)a->format->data;
+ int64_t file_size, current_offset;
+ const char *p;
+ int i, tail;
+
+ /* If someone has already bid more than 32, then avoid
+ trashing the look-ahead buffers with a seek. */
+ if (best_bid > 32)
+ return (-1);
+
+ file_size = __archive_read_seek(a, 0, SEEK_END);
+ if (file_size <= 0)
+ return 0;
+
+ /* Search last 16k of file for end-of-central-directory
+ * record (which starts with PK\005\006) */
+ tail = (int)zipmin(1024 * 16, file_size);
+ current_offset = __archive_read_seek(a, -tail, SEEK_END);
+ if (current_offset < 0)
+ return 0;
+ if ((p = __archive_read_ahead(a, (size_t)tail, NULL)) == NULL)
+ return 0;
+ /* Boyer-Moore search backwards from the end, since we want
+ * to match the last EOCD in the file (there can be more than
+ * one if there is an uncompressed Zip archive as a member
+ * within this Zip archive). */
+ for (i = tail - 22; i > 0;) {
+ switch (p[i]) {
+ case 'P':
+ if (memcmp(p + i, "PK\005\006", 4) == 0) {
+ int ret = read_eocd(zip, p + i,
+ current_offset + i);
+ if (ret > 0) {
+ /* Zip64 EOCD locator precedes
+ * regular EOCD if present. */
+ if (i >= 20
+ && memcmp(p + i - 20, "PK\006\007", 4) == 0) {
+ read_zip64_eocd(a, zip, p + i - 20);
+ }
+ return (ret);
+ }
+ }
+ i -= 4;
break;
-#ifdef DEBUG
- fprintf(stderr, "Header id 0x%x, length %d\n",
- headerid, datasize);
-#endif
- switch (headerid) {
- case 0x0001:
- /* Zip64 extended information extra field. */
- if (datasize >= 8)
- zip_entry->uncompressed_size =
- archive_le64dec(p + offset);
- if (datasize >= 16)
- zip_entry->compressed_size =
- archive_le64dec(p + offset + 8);
+ case 'K': i -= 1; break;
+ case 005: i -= 2; break;
+ case 006: i -= 3; break;
+ default: i -= 4; break;
+ }
+ }
+ return 0;
+}
+
+/* The red-black trees are only used in seeking mode to manage
+ * the in-memory copy of the central directory. */
+
+static int
+cmp_node(const struct archive_rb_node *n1, const struct archive_rb_node *n2)
+{
+ const struct zip_entry *e1 = (const struct zip_entry *)n1;
+ const struct zip_entry *e2 = (const struct zip_entry *)n2;
+
+ if (e1->local_header_offset > e2->local_header_offset)
+ return -1;
+ if (e1->local_header_offset < e2->local_header_offset)
+ return 1;
+ return 0;
+}
+
+static int
+cmp_key(const struct archive_rb_node *n, const void *key)
+{
+ /* This function won't be called */
+ (void)n; /* UNUSED */
+ (void)key; /* UNUSED */
+ return 1;
+}
+
+static const struct archive_rb_tree_ops rb_ops = {
+ &cmp_node, &cmp_key
+};
+
+static int
+rsrc_cmp_node(const struct archive_rb_node *n1,
+ const struct archive_rb_node *n2)
+{
+ const struct zip_entry *e1 = (const struct zip_entry *)n1;
+ const struct zip_entry *e2 = (const struct zip_entry *)n2;
+
+ return (strcmp(e2->rsrcname.s, e1->rsrcname.s));
+}
+
+static int
+rsrc_cmp_key(const struct archive_rb_node *n, const void *key)
+{
+ const struct zip_entry *e = (const struct zip_entry *)n;
+ return (strcmp((const char *)key, e->rsrcname.s));
+}
+
+static const struct archive_rb_tree_ops rb_rsrc_ops = {
+ &rsrc_cmp_node, &rsrc_cmp_key
+};
+
+static const char *
+rsrc_basename(const char *name, size_t name_length)
+{
+ const char *s, *r;
+
+ r = s = name;
+ for (;;) {
+ s = memchr(s, '/', name_length - (s - name));
+ if (s == NULL)
break;
- case 0x5455:
- {
- /* Extended time field "UT". */
- int flags = p[offset];
- offset++;
- datasize--;
- /* Flag bits indicate which dates are present. */
- if (flags & 0x01)
- {
-#ifdef DEBUG
- fprintf(stderr, "mtime: %lld -> %d\n",
- (long long)zip_entry->mtime,
- archive_le32dec(p + offset));
-#endif
- if (datasize < 4)
- break;
- zip_entry->mtime = archive_le32dec(p + offset);
- offset += 4;
- datasize -= 4;
- }
- if (flags & 0x02)
- {
- if (datasize < 4)
- break;
- zip_entry->atime = archive_le32dec(p + offset);
- offset += 4;
- datasize -= 4;
- }
- if (flags & 0x04)
- {
- if (datasize < 4)
- break;
- zip_entry->ctime = archive_le32dec(p + offset);
- offset += 4;
- datasize -= 4;
+ r = ++s;
+ }
+ return (r);
+}
+
+static void
+expose_parent_dirs(struct zip *zip, const char *name, size_t name_length)
+{
+ struct archive_string str;
+ struct zip_entry *dir;
+ char *s;
+
+ archive_string_init(&str);
+ archive_strncpy(&str, name, name_length);
+ for (;;) {
+ s = strrchr(str.s, '/');
+ if (s == NULL)
+ break;
+ *s = '\0';
+ /* Transfer the parent directory from zip->tree_rsrc RB
+ * tree to zip->tree RB tree to expose. */
+ dir = (struct zip_entry *)
+ __archive_rb_tree_find_node(&zip->tree_rsrc, str.s);
+ if (dir == NULL)
+ break;
+ __archive_rb_tree_remove_node(&zip->tree_rsrc, &dir->node);
+ archive_string_free(&dir->rsrcname);
+ __archive_rb_tree_insert_node(&zip->tree, &dir->node);
+ }
+ archive_string_free(&str);
+}
+
+static int
+slurp_central_directory(struct archive_read *a, struct zip *zip)
+{
+ ssize_t i;
+ unsigned found;
+ int64_t correction;
+ ssize_t bytes_avail;
+ const char *p;
+
+ /*
+ * Find the start of the central directory. The end-of-CD
+ * record has our starting point, but there are lots of
+ * Zip archives which have had other data prepended to the
+ * file, which makes the recorded offsets all too small.
+ * So we search forward from the specified offset until we
+ * find the real start of the central directory. Then we
+ * know the correction we need to apply to account for leading
+ * padding.
+ */
+ if (__archive_read_seek(a, zip->central_directory_offset, SEEK_SET) < 0)
+ return ARCHIVE_FATAL;
+
+ found = 0;
+ while (!found) {
+ if ((p = __archive_read_ahead(a, 20, &bytes_avail)) == NULL)
+ return ARCHIVE_FATAL;
+ for (found = 0, i = 0; !found && i < bytes_avail - 4;) {
+ switch (p[i + 3]) {
+ case 'P': i += 3; break;
+ case 'K': i += 2; break;
+ case 001: i += 1; break;
+ case 002:
+ if (memcmp(p + i, "PK\001\002", 4) == 0) {
+ p += i;
+ found = 1;
+ } else
+ i += 4;
+ break;
+ case 005: i += 1; break;
+ case 006:
+ if (memcmp(p + i, "PK\005\006", 4) == 0) {
+ p += i;
+ found = 1;
+ } else if (memcmp(p + i, "PK\006\006", 4) == 0) {
+ p += i;
+ found = 1;
+ } else
+ i += 1;
+ break;
+ default: i += 4; break;
}
+ }
+ __archive_read_consume(a, i);
+ }
+ correction = archive_filter_bytes(&a->archive, 0)
+ - zip->central_directory_offset;
+
+ __archive_rb_tree_init(&zip->tree, &rb_ops);
+ __archive_rb_tree_init(&zip->tree_rsrc, &rb_rsrc_ops);
+
+ zip->central_directory_entries_total = 0;
+ while (1) {
+ struct zip_entry *zip_entry;
+ size_t filename_length, extra_length, comment_length;
+ uint32_t external_attributes;
+ const char *name, *r;
+
+ if ((p = __archive_read_ahead(a, 4, NULL)) == NULL)
+ return ARCHIVE_FATAL;
+ if (memcmp(p, "PK\006\006", 4) == 0
+ || memcmp(p, "PK\005\006", 4) == 0) {
break;
+ } else if (memcmp(p, "PK\001\002", 4) != 0) {
+ archive_set_error(&a->archive,
+ -1, "Invalid central directory signature");
+ return ARCHIVE_FATAL;
}
- case 0x5855:
- {
- /* Info-ZIP Unix Extra Field (old version) "UX". */
- if (datasize >= 8) {
- zip_entry->atime = archive_le32dec(p + offset);
- zip_entry->mtime =
- archive_le32dec(p + offset + 4);
- }
- if (datasize >= 12) {
- zip_entry->uid =
- archive_le16dec(p + offset + 8);
- zip_entry->gid =
- archive_le16dec(p + offset + 10);
+ if ((p = __archive_read_ahead(a, 46, NULL)) == NULL)
+ return ARCHIVE_FATAL;
+
+ zip_entry = calloc(1, sizeof(struct zip_entry));
+ zip_entry->next = zip->zip_entries;
+ zip_entry->flags |= LA_FROM_CENTRAL_DIRECTORY;
+ zip->zip_entries = zip_entry;
+ zip->central_directory_entries_total++;
+
+ /* version = p[4]; */
+ zip_entry->system = p[5];
+ /* version_required = archive_le16dec(p + 6); */
+ zip_entry->zip_flags = archive_le16dec(p + 8);
+ if (zip_entry->zip_flags
+ & (ZIP_ENCRYPTED | ZIP_STRONG_ENCRYPTED)){
+ zip->has_encrypted_entries = 1;
+ }
+ zip_entry->compression = (char)archive_le16dec(p + 10);
+ zip_entry->mtime = zip_time(p + 12);
+ zip_entry->crc32 = archive_le32dec(p + 16);
+ if (zip_entry->zip_flags & ZIP_LENGTH_AT_END)
+ zip_entry->decdat = p[13];
+ else
+ zip_entry->decdat = p[19];
+ zip_entry->compressed_size = archive_le32dec(p + 20);
+ zip_entry->uncompressed_size = archive_le32dec(p + 24);
+ filename_length = archive_le16dec(p + 28);
+ extra_length = archive_le16dec(p + 30);
+ comment_length = archive_le16dec(p + 32);
+ /* disk_start = archive_le16dec(p + 34); */ /* Better be zero. */
+ /* internal_attributes = archive_le16dec(p + 36); */ /* text bit */
+ external_attributes = archive_le32dec(p + 38);
+ zip_entry->local_header_offset =
+ archive_le32dec(p + 42) + correction;
+
+ /* If we can't guess the mode, leave it zero here;
+ when we read the local file header we might get
+ more information. */
+ zip_entry->mode = 0;
+ if (zip_entry->system == 3) {
+ zip_entry->mode = external_attributes >> 16;
+ }
+
+ /* We're done with the regular data; get the filename and
+ * extra data. */
+ __archive_read_consume(a, 46);
+ p = __archive_read_ahead(a, filename_length + extra_length,
+ NULL);
+ if (p == NULL) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated ZIP file header");
+ return ARCHIVE_FATAL;
+ }
+ process_extra(p + filename_length, extra_length, zip_entry);
+
+ /*
+ * Mac resource fork files are stored under the
+ * "__MACOSX/" directory, so we should check if
+ * it is.
+ */
+ if (!zip->process_mac_extensions) {
+ /* Treat every entry as a regular entry. */
+ __archive_rb_tree_insert_node(&zip->tree,
+ &zip_entry->node);
+ } else {
+ name = p;
+ r = rsrc_basename(name, filename_length);
+ if (filename_length >= 9 &&
+ strncmp("__MACOSX/", name, 9) == 0) {
+ /* If this file is not a resource fork nor
+ * a directory. We should treat it as a non
+ * resource fork file to expose it. */
+ if (name[filename_length-1] != '/' &&
+ (r - name < 3 || r[0] != '.' || r[1] != '_')) {
+ __archive_rb_tree_insert_node(
+ &zip->tree, &zip_entry->node);
+ /* Expose its parent directories. */
+ expose_parent_dirs(zip, name,
+ filename_length);
+ } else {
+ /* This file is a resource fork file or
+ * a directory. */
+ archive_strncpy(&(zip_entry->rsrcname),
+ name, filename_length);
+ __archive_rb_tree_insert_node(
+ &zip->tree_rsrc, &zip_entry->node);
+ }
+ } else {
+ /* Generate resource fork name to find its
+ * resource file at zip->tree_rsrc. */
+ archive_strcpy(&(zip_entry->rsrcname),
+ "__MACOSX/");
+ archive_strncat(&(zip_entry->rsrcname),
+ name, r - name);
+ archive_strcat(&(zip_entry->rsrcname), "._");
+ archive_strncat(&(zip_entry->rsrcname),
+ name + (r - name),
+ filename_length - (r - name));
+ /* Register an entry to RB tree to sort it by
+ * file offset. */
+ __archive_rb_tree_insert_node(&zip->tree,
+ &zip_entry->node);
}
- break;
}
- case 0x7855:
- /* Info-ZIP Unix Extra Field (type 2) "Ux". */
-#ifdef DEBUG
- fprintf(stderr, "uid %d gid %d\n",
- archive_le16dec(p + offset),
- archive_le16dec(p + offset + 2));
+
+ /* Skip the comment too ... */
+ __archive_read_consume(a,
+ filename_length + extra_length + comment_length);
+ }
+
+ return ARCHIVE_OK;
+}
+
+static ssize_t
+zip_get_local_file_header_size(struct archive_read *a, size_t extra)
+{
+ const char *p;
+ ssize_t filename_length, extra_length;
+
+ if ((p = __archive_read_ahead(a, extra + 30, NULL)) == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated ZIP file header");
+ return (ARCHIVE_WARN);
+ }
+ p += extra;
+
+ if (memcmp(p, "PK\003\004", 4) != 0) {
+ archive_set_error(&a->archive, -1, "Damaged Zip archive");
+ return ARCHIVE_WARN;
+ }
+ filename_length = archive_le16dec(p + 26);
+ extra_length = archive_le16dec(p + 28);
+
+ return (30 + filename_length + extra_length);
+}
+
+static int
+zip_read_mac_metadata(struct archive_read *a, struct archive_entry *entry,
+ struct zip_entry *rsrc)
+{
+ struct zip *zip = (struct zip *)a->format->data;
+ unsigned char *metadata, *mp;
+ int64_t offset = archive_filter_bytes(&a->archive, 0);
+ size_t remaining_bytes, metadata_bytes;
+ ssize_t hsize;
+ int ret = ARCHIVE_OK, eof;
+
+ switch(rsrc->compression) {
+ case 0: /* No compression. */
+#ifdef HAVE_ZLIB_H
+ case 8: /* Deflate compression. */
#endif
- if (datasize >= 2)
- zip_entry->uid = archive_le16dec(p + offset);
- if (datasize >= 4)
- zip_entry->gid =
- archive_le16dec(p + offset + 2);
+ break;
+ default: /* Unsupported compression. */
+ /* Return a warning. */
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unsupported ZIP compression method (%s)",
+ compression_name(rsrc->compression));
+ /* We can't decompress this entry, but we will
+ * be able to skip() it and try the next entry. */
+ return (ARCHIVE_WARN);
+ }
+
+ if (rsrc->uncompressed_size > (4 * 1024 * 1024)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Mac metadata is too large: %jd > 4M bytes",
+ (intmax_t)rsrc->uncompressed_size);
+ return (ARCHIVE_WARN);
+ }
+
+ metadata = malloc((size_t)rsrc->uncompressed_size);
+ if (metadata == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Mac metadata");
+ return (ARCHIVE_FATAL);
+ }
+
+ if (offset < rsrc->local_header_offset)
+ __archive_read_consume(a, rsrc->local_header_offset - offset);
+ else if (offset != rsrc->local_header_offset) {
+ __archive_read_seek(a, rsrc->local_header_offset, SEEK_SET);
+ }
+
+ hsize = zip_get_local_file_header_size(a, 0);
+ __archive_read_consume(a, hsize);
+
+ remaining_bytes = (size_t)rsrc->compressed_size;
+ metadata_bytes = (size_t)rsrc->uncompressed_size;
+ mp = metadata;
+ eof = 0;
+ while (!eof && remaining_bytes) {
+ const unsigned char *p;
+ ssize_t bytes_avail;
+ size_t bytes_used;
+
+ p = __archive_read_ahead(a, 1, &bytes_avail);
+ if (p == NULL) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated ZIP file header");
+ ret = ARCHIVE_WARN;
+ goto exit_mac_metadata;
+ }
+ if ((size_t)bytes_avail > remaining_bytes)
+ bytes_avail = remaining_bytes;
+ switch(rsrc->compression) {
+ case 0: /* No compression. */
+ memcpy(mp, p, bytes_avail);
+ bytes_used = (size_t)bytes_avail;
+ metadata_bytes -= bytes_used;
+ mp += bytes_used;
+ if (metadata_bytes == 0)
+ eof = 1;
break;
- case 0x7875:
+#ifdef HAVE_ZLIB_H
+ case 8: /* Deflate compression. */
{
- /* Info-Zip Unix Extra Field (type 3) "ux". */
- int uidsize = 0, gidsize = 0;
+ int r;
- if (datasize >= 1 && p[offset] == 1) {/* version=1 */
- if (datasize >= 4) {
- /* get a uid size. */
- uidsize = p[offset+1];
- if (uidsize == 2)
- zip_entry->uid =
- archive_le16dec(
- p + offset + 2);
- else if (uidsize == 4 && datasize >= 6)
- zip_entry->uid =
- archive_le32dec(
- p + offset + 2);
- }
- if (datasize >= (2 + uidsize + 3)) {
- /* get a gid size. */
- gidsize = p[offset+2+uidsize];
- if (gidsize == 2)
- zip_entry->gid =
- archive_le16dec(
- p+offset+2+uidsize+1);
- else if (gidsize == 4 &&
- datasize >= (2 + uidsize + 5))
- zip_entry->gid =
- archive_le32dec(
- p+offset+2+uidsize+1);
- }
+ ret = zip_deflate_init(a, zip);
+ if (ret != ARCHIVE_OK)
+ goto exit_mac_metadata;
+ zip->stream.next_in =
+ (Bytef *)(uintptr_t)(const void *)p;
+ zip->stream.avail_in = (uInt)bytes_avail;
+ zip->stream.total_in = 0;
+ zip->stream.next_out = mp;
+ zip->stream.avail_out = (uInt)metadata_bytes;
+ zip->stream.total_out = 0;
+
+ r = inflate(&zip->stream, 0);
+ switch (r) {
+ case Z_OK:
+ break;
+ case Z_STREAM_END:
+ eof = 1;
+ break;
+ case Z_MEM_ERROR:
+ archive_set_error(&a->archive, ENOMEM,
+ "Out of memory for ZIP decompression");
+ ret = ARCHIVE_FATAL;
+ goto exit_mac_metadata;
+ default:
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "ZIP decompression failed (%d)", r);
+ ret = ARCHIVE_FATAL;
+ goto exit_mac_metadata;
}
+ bytes_used = zip->stream.total_in;
+ metadata_bytes -= zip->stream.total_out;
+ mp += zip->stream.total_out;
break;
}
+#endif
default:
+ bytes_used = 0;
break;
}
- offset += datasize;
+ __archive_read_consume(a, bytes_used);
+ remaining_bytes -= bytes_used;
}
-#ifdef DEBUG
- if (offset != extra_length)
- {
- fprintf(stderr,
- "Extra data field contents do not match reported size!\n");
+ archive_entry_copy_mac_metadata(entry, metadata,
+ (size_t)rsrc->uncompressed_size - metadata_bytes);
+
+exit_mac_metadata:
+ __archive_read_seek(a, offset, SEEK_SET);
+ zip->decompress_init = 0;
+ free(metadata);
+ return (ret);
+}
+
+static int
+archive_read_format_zip_seekable_read_header(struct archive_read *a,
+ struct archive_entry *entry)
+{
+ struct zip *zip = (struct zip *)a->format->data;
+ struct zip_entry *rsrc;
+ int64_t offset;
+ int r, ret = ARCHIVE_OK;
+
+ /*
+ * It should be sufficient to call archive_read_next_header() for
+ * a reader to determine if an entry is encrypted or not. If the
+ * encryption of an entry is only detectable when calling
+ * archive_read_data(), so be it. We'll do the same check there
+ * as well.
+ */
+ if (zip->has_encrypted_entries ==
+ ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW)
+ zip->has_encrypted_entries = 0;
+
+ a->archive.archive_format = ARCHIVE_FORMAT_ZIP;
+ if (a->archive.archive_format_name == NULL)
+ a->archive.archive_format_name = "ZIP";
+
+ if (zip->zip_entries == NULL) {
+ r = slurp_central_directory(a, zip);
+ if (r != ARCHIVE_OK)
+ return r;
+ /* Get first entry whose local header offset is lower than
+ * other entries in the archive file. */
+ zip->entry =
+ (struct zip_entry *)ARCHIVE_RB_TREE_MIN(&zip->tree);
+ } else if (zip->entry != NULL) {
+ /* Get next entry in local header offset order. */
+ zip->entry = (struct zip_entry *)__archive_rb_tree_iterate(
+ &zip->tree, &zip->entry->node, ARCHIVE_RB_DIR_RIGHT);
+ }
+
+ if (zip->entry == NULL)
+ return ARCHIVE_EOF;
+
+ if (zip->entry->rsrcname.s)
+ rsrc = (struct zip_entry *)__archive_rb_tree_find_node(
+ &zip->tree_rsrc, zip->entry->rsrcname.s);
+ else
+ rsrc = NULL;
+
+ if (zip->cctx_valid)
+ archive_decrypto_aes_ctr_release(&zip->cctx);
+ if (zip->hctx_valid)
+ archive_hmac_sha1_cleanup(&zip->hctx);
+ zip->tctx_valid = zip->cctx_valid = zip->hctx_valid = 0;
+ __archive_read_reset_passphrase(a);
+
+ /* File entries are sorted by the header offset, we should mostly
+ * use __archive_read_consume to advance a read point to avoid redundant
+ * data reading. */
+ offset = archive_filter_bytes(&a->archive, 0);
+ if (offset < zip->entry->local_header_offset)
+ __archive_read_consume(a,
+ zip->entry->local_header_offset - offset);
+ else if (offset != zip->entry->local_header_offset) {
+ __archive_read_seek(a, zip->entry->local_header_offset,
+ SEEK_SET);
+ }
+ zip->unconsumed = 0;
+ r = zip_read_local_file_header(a, entry, zip);
+ if (r != ARCHIVE_OK)
+ return r;
+ if (rsrc) {
+ int ret2 = zip_read_mac_metadata(a, entry, rsrc);
+ if (ret2 < ret)
+ ret = ret2;
}
+ return (ret);
+}
+
+/*
+ * We're going to seek for the next header anyway, so we don't
+ * need to bother doing anything here.
+ */
+static int
+archive_read_format_zip_read_data_skip_seekable(struct archive_read *a)
+{
+ struct zip *zip;
+ zip = (struct zip *)(a->format->data);
+
+ zip->unconsumed = 0;
+ return (ARCHIVE_OK);
+}
+
+int
+archive_read_support_format_zip_seekable(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct zip *zip;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_zip_seekable");
+
+ zip = (struct zip *)calloc(1, sizeof(*zip));
+ if (zip == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate zip data");
+ return (ARCHIVE_FATAL);
+ }
+
+#ifdef HAVE_COPYFILE_H
+ /* Set this by default on Mac OS. */
+ zip->process_mac_extensions = 1;
#endif
+
+ /*
+ * Until enough data has been read, we cannot tell about
+ * any encrypted entries yet.
+ */
+ zip->has_encrypted_entries = ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
+ zip->crc32func = real_crc32;
+
+ r = __archive_read_register_format(a,
+ zip,
+ "zip",
+ archive_read_format_zip_seekable_bid,
+ archive_read_format_zip_options,
+ archive_read_format_zip_seekable_read_header,
+ archive_read_format_zip_read_data,
+ archive_read_format_zip_read_data_skip_seekable,
+ NULL,
+ archive_read_format_zip_cleanup,
+ archive_read_support_format_zip_capabilities_seekable,
+ archive_read_format_zip_has_encrypted_entries);
+
+ if (r != ARCHIVE_OK)
+ free(zip);
+ return (ARCHIVE_OK);
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_string.c b/Utilities/cmlibarchive/libarchive/archive_string.c
index 87f9288f1..3d4be8259 100644
--- a/Utilities/cmlibarchive/libarchive/archive_string.c
+++ b/Utilities/cmlibarchive/libarchive/archive_string.c
@@ -71,6 +71,10 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_string.c 201095 2009-12-28 02:33
#define wmemcpy(a,b,i) (wchar_t *)memcpy((a), (b), (i) * sizeof(wchar_t))
#endif
+#if !defined(HAVE_WMEMMOVE) && !defined(wmemmove)
+#define wmemmove(a,b,i) (wchar_t *)memmove((a), (b), (i) * sizeof(wchar_t))
+#endif
+
struct archive_string_conv {
struct archive_string_conv *next;
char *from_charset;
@@ -127,12 +131,7 @@ struct archive_string_conv {
#define UNICODE_MAX 0x10FFFF
#define UNICODE_R_CHAR 0xFFFD /* Replacement character. */
/* Set U+FFFD(Replacement character) in UTF-8. */
-#define UTF8_SET_R_CHAR(outp) do { \
- (outp)[0] = 0xef; \
- (outp)[1] = 0xbf; \
- (outp)[2] = 0xbd; \
-} while (0)
-#define UTF8_R_CHAR_SIZE 3
+static const char utf8_replacement_char[] = {0xef, 0xbf, 0xbd};
static struct archive_string_conv *find_sconv_object(struct archive *,
const char *, const char *);
@@ -203,7 +202,7 @@ archive_string_append(struct archive_string *as, const char *p, size_t s)
{
if (archive_string_ensure(as, as->length + s + 1) == NULL)
return (NULL);
- memcpy(as->s + as->length, p, s);
+ memmove(as->s + as->length, p, s);
as->length += s;
as->s[as->length] = 0;
return (as);
@@ -214,7 +213,7 @@ archive_wstring_append(struct archive_wstring *as, const wchar_t *p, size_t s)
{
if (archive_wstring_ensure(as, as->length + s + 1) == NULL)
return (NULL);
- wmemcpy(as->s + as->length, p, s);
+ wmemmove(as->s + as->length, p, s);
as->length += s;
as->s[as->length] = 0;
return (as);
@@ -2037,7 +2036,7 @@ iconv_strncat_in_locale(struct archive_string *as, const void *_p,
if (sc->flag & (SCONV_TO_UTF8 | SCONV_TO_UTF16)) {
size_t rbytes;
if (sc->flag & SCONV_TO_UTF8)
- rbytes = UTF8_R_CHAR_SIZE;
+ rbytes = sizeof(utf8_replacement_char);
else
rbytes = 2;
@@ -2053,7 +2052,7 @@ iconv_strncat_in_locale(struct archive_string *as, const void *_p,
- as->length - to_size;
}
if (sc->flag & SCONV_TO_UTF8)
- UTF8_SET_R_CHAR(outp);
+ memcpy(outp, utf8_replacement_char, sizeof(utf8_replacement_char));
else if (sc->flag & SCONV_TO_UTF16BE)
archive_be16enc(outp, UNICODE_R_CHAR);
else
@@ -2202,9 +2201,7 @@ best_effort_strncat_in_locale(struct archive_string *as, const void *_p,
size_t length, struct archive_string_conv *sc)
{
size_t remaining;
- char *otp;
const uint8_t *itp;
- size_t avail;
int return_value = 0; /* success */
/*
@@ -2223,46 +2220,25 @@ best_effort_strncat_in_locale(struct archive_string *as, const void *_p,
* byte sequence 0xEF 0xBD 0xBD, which are code point U+FFFD,
* a Replacement Character in Unicode.
*/
- if (archive_string_ensure(as, as->length + length + 1) == NULL)
- return (-1);
remaining = length;
itp = (const uint8_t *)_p;
- otp = as->s + as->length;
- avail = as->buffer_length - as->length -1;
while (*itp && remaining > 0) {
- if (*itp > 127 && (sc->flag & SCONV_TO_UTF8)) {
- if (avail < UTF8_R_CHAR_SIZE) {
- as->length = otp - as->s;
- if (NULL == archive_string_ensure(as,
- as->buffer_length + remaining +
- UTF8_R_CHAR_SIZE))
- return (-1);
- otp = as->s + as->length;
- avail = as->buffer_length - as->length -1;
+ if (*itp > 127) {
+ // Non-ASCII: Substitute with suitable replacement
+ if (sc->flag & SCONV_TO_UTF8) {
+ if (archive_string_append(as, utf8_replacement_char, sizeof(utf8_replacement_char)) == NULL) {
+ __archive_errx(1, "Out of memory");
+ }
+ } else {
+ archive_strappend_char(as, '?');
}
- /*
- * When coping a string in UTF-8, unknown character
- * should be U+FFFD (replacement character).
- */
- UTF8_SET_R_CHAR(otp);
- otp += UTF8_R_CHAR_SIZE;
- avail -= UTF8_R_CHAR_SIZE;
- itp++;
- remaining--;
- return_value = -1;
- } else if (*itp > 127) {
- *otp++ = '?';
- itp++;
- remaining--;
return_value = -1;
} else {
- *otp++ = (char)*itp++;
- remaining--;
+ archive_strappend_char(as, *itp);
}
+ ++itp;
}
- as->length = otp - as->s;
- as->s[as->length] = '\0';
return (return_value);
}
@@ -2488,6 +2464,9 @@ unicode_to_utf8(char *p, size_t remaining, uint32_t uc)
{
char *_p = p;
+ /* Invalid Unicode char maps to Replacement character */
+ if (uc > UNICODE_MAX)
+ uc = UNICODE_R_CHAR;
/* Translate code point to UTF8 */
if (uc <= 0x7f) {
if (remaining == 0)
@@ -2504,22 +2483,13 @@ unicode_to_utf8(char *p, size_t remaining, uint32_t uc)
*p++ = 0xe0 | ((uc >> 12) & 0x0f);
*p++ = 0x80 | ((uc >> 6) & 0x3f);
*p++ = 0x80 | (uc & 0x3f);
- } else if (uc <= UNICODE_MAX) {
+ } else {
if (remaining < 4)
return (0);
*p++ = 0xf0 | ((uc >> 18) & 0x07);
*p++ = 0x80 | ((uc >> 12) & 0x3f);
*p++ = 0x80 | ((uc >> 6) & 0x3f);
*p++ = 0x80 | (uc & 0x3f);
- } else {
- /*
- * Undescribed code point should be U+FFFD
- * (replacement character).
- */
- if (remaining < UTF8_R_CHAR_SIZE)
- return (0);
- UTF8_SET_R_CHAR(p);
- p += UTF8_R_CHAR_SIZE;
}
return (p - _p);
}
@@ -3887,7 +3857,7 @@ archive_mstring_get_utf8(struct archive *a, struct archive_mstring *aes,
sc = archive_string_conversion_to_charset(a, "UTF-8", 1);
if (sc == NULL)
return (-1);/* Couldn't allocate memory for sc. */
- r = archive_strncpy_l(&(aes->aes_mbs), aes->aes_mbs.s,
+ r = archive_strncpy_l(&(aes->aes_utf8), aes->aes_mbs.s,
aes->aes_mbs.length, sc);
if (a == NULL)
free_sconv_object(sc);
@@ -4062,6 +4032,19 @@ archive_mstring_copy_wcs(struct archive_mstring *aes, const wchar_t *wcs)
}
int
+archive_mstring_copy_utf8(struct archive_mstring *aes, const char *utf8)
+{
+ if (utf8 == NULL) {
+ aes->aes_set = 0;
+ }
+ aes->aes_set = AES_SET_UTF8;
+ archive_string_empty(&(aes->aes_mbs));
+ archive_string_empty(&(aes->aes_wcs));
+ archive_strncpy(&(aes->aes_utf8), utf8, strlen(utf8));
+ return (int)strlen(utf8);
+}
+
+int
archive_mstring_copy_wcs_len(struct archive_mstring *aes, const wchar_t *wcs,
size_t len)
{
diff --git a/Utilities/cmlibarchive/libarchive/archive_util.c b/Utilities/cmlibarchive/libarchive/archive_util.c
index 34d8081cb..5f31edf5c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_util.c
+++ b/Utilities/cmlibarchive/libarchive/archive_util.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2009-2012 Michihiro NAKAJIMA
+ * Copyright (c) 2009-2012,2014 Michihiro NAKAJIMA
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
@@ -45,15 +45,30 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:1
#if defined(HAVE_WINCRYPT_H) && !defined(__CYGWIN__)
#include <wincrypt.h>
#endif
+#ifdef HAVE_ZLIB_H
+#include <cm_zlib.h>
+#endif
+#ifdef HAVE_LZMA_H
+#include <cm_lzma.h>
+#endif
+#ifdef HAVE_BZLIB_H
+#include <cm_bzlib.h>
+#endif
+#ifdef HAVE_LZ4_H
+#include <lz4.h>
+#endif
#include "archive.h"
#include "archive_private.h"
+#include "archive_random_private.h"
#include "archive_string.h"
#ifndef O_CLOEXEC
#define O_CLOEXEC 0
#endif
+static int archive_utility_string_sort_helper(char **, unsigned int);
+
/* Generic initialization of 'struct archive' objects. */
int
__archive_clean(struct archive *a)
@@ -74,6 +89,42 @@ archive_version_string(void)
return (ARCHIVE_VERSION_STRING);
}
+const char *
+archive_version_details(void)
+{
+ static struct archive_string str;
+ static int init = 0;
+
+ if (!init) {
+ archive_string_init(&str);
+
+ archive_strcat(&str, ARCHIVE_VERSION_STRING);
+#ifdef HAVE_ZLIB_H
+ archive_strcat(&str, " zlib/");
+ archive_strcat(&str, ZLIB_VERSION);
+#endif
+#ifdef HAVE_LZMA_H
+ archive_strcat(&str, " liblzma/");
+ archive_strcat(&str, LZMA_VERSION_STRING);
+#endif
+#ifdef HAVE_BZLIB_H
+ {
+ const char *p = BZ2_bzlibVersion();
+ const char *sep = strchr(p, ',');
+ if (sep == NULL)
+ sep = p + strlen(p);
+ archive_strcat(&str, " bz2lib/");
+ archive_strncat(&str, p, sep - p);
+ }
+#endif
+#if defined(HAVE_LZ4_H) && defined(HAVE_LIBLZ4)
+ archive_string_sprintf(&str, " liblz4/%d.%d.%d",
+ LZ4_VERSION_MAJOR, LZ4_VERSION_MINOR, LZ4_VERSION_RELEASE);
+#endif
+ }
+ return str.s;
+}
+
int
archive_errno(struct archive *a)
{
@@ -206,6 +257,8 @@ __archive_errx(int retvalue, const char *msg)
int
__archive_mktemp(const char *tmpdir)
{
+ static const wchar_t *prefix = L"libarchive_";
+ static const wchar_t *suffix = L"XXXXXXXXXX";
static const wchar_t num[] = {
L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7',
L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F',
@@ -280,10 +333,10 @@ __archive_mktemp(const char *tmpdir)
/*
* Create a temporary file.
*/
- archive_wstrcat(&temp_name, L"libarchive_");
- xp = temp_name.s + archive_strlen(&temp_name);
- archive_wstrcat(&temp_name, L"XXXXXXXXXX");
+ archive_wstrcat(&temp_name, prefix);
+ archive_wstrcat(&temp_name, suffix);
ep = temp_name.s + archive_strlen(&temp_name);
+ xp = ep - wcslen(suffix);
if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT)) {
@@ -420,7 +473,6 @@ __archive_mktemp(const char *tmpdir)
struct stat st;
int fd;
char *tp, *ep;
- unsigned seed;
fd = -1;
archive_string_init(&temp_name);
@@ -444,21 +496,15 @@ __archive_mktemp(const char *tmpdir)
archive_strcat(&temp_name, "XXXXXXXXXX");
ep = temp_name.s + archive_strlen(&temp_name);
- fd = open("/dev/random", O_RDONLY | O_CLOEXEC);
- __archive_ensure_cloexec_flag(fd);
- if (fd < 0)
- seed = time(NULL);
- else {
- if (read(fd, &seed, sizeof(seed)) < 0)
- seed = time(NULL);
- close(fd);
- }
do {
char *p;
p = tp;
- while (p < ep)
- *p++ = num[((unsigned)rand_r(&seed)) % sizeof(num)];
+ archive_random(p, ep - p);
+ while (p < ep) {
+ int d = *((unsigned char *)p) % sizeof(num);
+ *p++ = num[d];
+ }
fd = open(temp_name.s, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC,
0600);
} while (fd < 0 && errno == EEXIST);
@@ -499,3 +545,77 @@ __archive_ensure_cloexec_flag(int fd)
}
#endif
}
+
+/*
+ * Utility function to sort a group of strings using quicksort.
+ */
+static int
+archive_utility_string_sort_helper(char **strings, unsigned int n)
+{
+ unsigned int i, lesser_count, greater_count;
+ char **lesser, **greater, **tmp, *pivot;
+ int retval1, retval2;
+
+ /* A list of 0 or 1 elements is already sorted */
+ if (n <= 1)
+ return (ARCHIVE_OK);
+
+ lesser_count = greater_count = 0;
+ lesser = greater = NULL;
+ pivot = strings[0];
+ for (i = 1; i < n; i++)
+ {
+ if (strcmp(strings[i], pivot) < 0)
+ {
+ lesser_count++;
+ tmp = (char **)realloc(lesser,
+ lesser_count * sizeof(char *));
+ if (!tmp) {
+ free(greater);
+ free(lesser);
+ return (ARCHIVE_FATAL);
+ }
+ lesser = tmp;
+ lesser[lesser_count - 1] = strings[i];
+ }
+ else
+ {
+ greater_count++;
+ tmp = (char **)realloc(greater,
+ greater_count * sizeof(char *));
+ if (!tmp) {
+ free(greater);
+ free(lesser);
+ return (ARCHIVE_FATAL);
+ }
+ greater = tmp;
+ greater[greater_count - 1] = strings[i];
+ }
+ }
+
+ /* quicksort(lesser) */
+ retval1 = archive_utility_string_sort_helper(lesser, lesser_count);
+ for (i = 0; i < lesser_count; i++)
+ strings[i] = lesser[i];
+ free(lesser);
+
+ /* pivot */
+ strings[lesser_count] = pivot;
+
+ /* quicksort(greater) */
+ retval2 = archive_utility_string_sort_helper(greater, greater_count);
+ for (i = 0; i < greater_count; i++)
+ strings[lesser_count + 1 + i] = greater[i];
+ free(greater);
+
+ return (retval1 < retval2) ? retval1 : retval2;
+}
+
+int
+archive_utility_string_sort(char **strings)
+{
+ unsigned int size = 0;
+ while (strings[size] != NULL)
+ size++;
+ return archive_utility_string_sort_helper(strings, size);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_virtual.c b/Utilities/cmlibarchive/libarchive/archive_virtual.c
index 0c4155f21..de2595a9e 100644
--- a/Utilities/cmlibarchive/libarchive/archive_virtual.c
+++ b/Utilities/cmlibarchive/libarchive/archive_virtual.c
@@ -55,6 +55,14 @@ archive_filter_bytes(struct archive *a, int n)
}
int
+archive_free(struct archive *a)
+{
+ if (a == NULL)
+ return (ARCHIVE_OK);
+ return ((a->vtable->archive_free)(a));
+}
+
+int
archive_write_close(struct archive *a)
{
return ((a->vtable->archive_close)(a));
@@ -76,9 +84,7 @@ archive_write_fail(struct archive *a)
int
archive_write_free(struct archive *a)
{
- if (a == NULL)
- return (ARCHIVE_OK);
- return ((a->vtable->archive_free)(a));
+ return archive_free(a);
}
#if ARCHIVE_VERSION_NUMBER < 4000000
@@ -93,9 +99,7 @@ archive_write_finish(struct archive *a)
int
archive_read_free(struct archive *a)
{
- if (a == NULL)
- return (ARCHIVE_OK);
- return ((a->vtable->archive_free)(a));
+ return archive_free(a);
}
#if ARCHIVE_VERSION_NUMBER < 4000000
diff --git a/Utilities/cmlibarchive/libarchive/archive_windows.c b/Utilities/cmlibarchive/libarchive/archive_windows.c
index d3bf758bb..d4e93fe78 100644
--- a/Utilities/cmlibarchive/libarchive/archive_windows.c
+++ b/Utilities/cmlibarchive/libarchive/archive_windows.c
@@ -301,7 +301,7 @@ __la_open(const char *path, int flags, ...)
ws = NULL;
if ((flags & ~O_BINARY) == O_RDONLY) {
/*
- * When we open a directory, _open function returns
+ * When we open a directory, _open function returns
* "Permission denied" error.
*/
attr = GetFileAttributesA(path);
@@ -515,9 +515,9 @@ __hstat(HANDLE handle, struct ustat *st)
else
mode |= S_IFREG;
st->st_mode = mode;
-
+
fileTimeToUTC(&info.ftLastAccessTime, &t, &ns);
- st->st_atime = t;
+ st->st_atime = t;
st->st_atime_nsec = ns;
fileTimeToUTC(&info.ftLastWriteTime, &t, &ns);
st->st_mtime = t;
@@ -525,7 +525,7 @@ __hstat(HANDLE handle, struct ustat *st)
fileTimeToUTC(&info.ftCreationTime, &t, &ns);
st->st_ctime = t;
st->st_ctime_nsec = ns;
- st->st_size =
+ st->st_size =
((int64_t)(info.nFileSizeHigh) * ((int64_t)MAXDWORD + 1))
+ (int64_t)(info.nFileSizeLow);
#ifdef SIMULATE_WIN_STAT
@@ -599,7 +599,7 @@ __la_stat(const char *path, struct stat *st)
struct ustat u;
int ret;
- handle = la_CreateFile(path, 0, 0, NULL, OPEN_EXISTING,
+ handle = la_CreateFile(path, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
NULL);
if (handle == INVALID_HANDLE_VALUE) {
diff --git a/Utilities/cmlibarchive/libarchive/archive_windows.h b/Utilities/cmlibarchive/libarchive/archive_windows.h
index 620810c1c..7c31a1691 100644
--- a/Utilities/cmlibarchive/libarchive/archive_windows.h
+++ b/Utilities/cmlibarchive/libarchive/archive_windows.h
@@ -76,6 +76,7 @@
#if defined(_MSC_VER)
#pragma warning(push,1)
+#pragma warning(disable:4142) /* benign redefinition of type */
#pragma warning(disable:4761) /* integral size mismatch in argument; conversion supplied */
#endif
#if defined(__BORLANDC__)
@@ -93,7 +94,7 @@
/* Alias the Windows _function to the POSIX equivalent. */
#define close _close
-#define fcntl(fd, cmd, flg) /* No operation. */
+#define fcntl(fd, cmd, flg) /* No operation. */
#ifndef fileno
#define fileno _fileno
#endif
@@ -113,13 +114,14 @@
#define lstat __la_stat
#define open __la_open
#define read __la_read
-#if !defined(__BORLANDC__)
+#if !defined(__BORLANDC__) && !defined(__WATCOMC__)
#define setmode _setmode
#endif
#ifdef stat
#undef stat
#endif
#define stat(path,stref) __la_stat(path,stref)
+#if !defined(__WATCOMC__)
#if !defined(__BORLANDC__)
#define strdup _strdup
#endif
@@ -127,9 +129,12 @@
#if !defined(__BORLANDC__)
#define umask _umask
#endif
+#endif
#define waitpid __la_waitpid
#define write __la_write
+#if !defined(__WATCOMC__)
+
#ifndef O_RDONLY
#define O_RDONLY _O_RDONLY
#define O_WRONLY _O_WRONLY
@@ -188,6 +193,7 @@
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) /* directory */
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) /* regular file */
#endif
+
#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) /* Symbolic link */
#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) /* Socket */
@@ -207,7 +213,7 @@
#define _S_IXGRP (_S_IXUSR >> 3) /* read permission, group */
#define _S_IWGRP (_S_IWUSR >> 3) /* write permission, group */
#define _S_IRGRP (_S_IRUSR >> 3) /* execute/search permission, group */
-#define _S_IRWXO (_S_IRWXG >> 3)
+#define _S_IRWXO (_S_IRWXG >> 3)
#define _S_IXOTH (_S_IXGRP >> 3) /* read permission, other */
#define _S_IWOTH (_S_IWGRP >> 3) /* write permission, other */
#define _S_IROTH (_S_IRGRP >> 3) /* execute/search permission, other */
@@ -221,12 +227,16 @@
#define S_IRWXG _S_IRWXG
#define S_IXGRP _S_IXGRP
#define S_IWGRP _S_IWGRP
+#ifndef S_IRGRP
#define S_IRGRP _S_IRGRP
+#endif
#define S_IRWXO _S_IRWXO
#define S_IXOTH _S_IXOTH
#define S_IWOTH _S_IWOTH
#define S_IROTH _S_IROTH
+#endif
+
#define F_DUPFD 0 /* Duplicate file descriptor. */
#define F_GETFD 1 /* Get file descriptor flags. */
#define F_SETFD 2 /* Set file descriptor flags. */
diff --git a/Utilities/cmlibarchive/libarchive/archive_write.3 b/Utilities/cmlibarchive/libarchive/archive_write.3
index 228bc2cb8..376d71dee 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write.3
@@ -155,7 +155,7 @@ myopen(struct archive *a, void *client_data)
return (ARCHIVE_FATAL);
}
-ssize_t
+la_ssize_t
mywrite(struct archive *a, void *client_data, const void *buff, size_t n)
{
struct mydata *mydata = client_data;
@@ -186,8 +186,13 @@ write_archive(const char *outname, const char **filename)
a = archive_write_new();
mydata->name = outname;
- archive_write_add_filter_gzip(a);
- archive_write_set_format_ustar(a);
+ /* Set archive format and filter according to output file extension.
+ * If it fails, set default format. Platform depended function.
+ * See supported formats in archive_write_set_format_filter_by_ext.c */
+ if (archive_write_set_format_filter_by_ext(a, outname) != ARCHIVE_OK) {
+ archive_write_add_filter_gzip(a);
+ archive_write_set_format_ustar(a);
+ }
archive_write_open(a, mydata, myopen, mywrite, myclose);
while (*filename) {
stat(*filename, &st);
@@ -197,7 +202,7 @@ write_archive(const char *outname, const char **filename)
archive_write_header(a, entry);
if ((fd = open(*filename, O_RDONLY)) != -1) {
len = read(fd, buff, sizeof(buff));
- while ( len > 0 ) {
+ while (len > 0) {
archive_write_data(a, buff, len);
len = read(fd, buff, sizeof(buff));
}
@@ -213,7 +218,7 @@ int main(int argc, const char **argv)
{
const char *outname;
argv++;
- outname = argv++;
+ outname = *argv++;
write_archive(outname, argv);
return 0;
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write.c b/Utilities/cmlibarchive/libarchive/archive_write.c
index b296069e9..e3fa3357b 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write.c
@@ -444,6 +444,12 @@ archive_write_client_close(struct archive_write_filter *f)
/* Clear the close handler myself not to be called again. */
f->close = NULL;
a->client_data = NULL;
+ /* Clear passphrase. */
+ if (a->passphrase != NULL) {
+ memset(a->passphrase, 0, strlen(a->passphrase));
+ free(a->passphrase);
+ a->passphrase = NULL;
+ }
return (ret);
}
@@ -503,8 +509,9 @@ _archive_write_close(struct archive *_a)
archive_clear_error(&a->archive);
- /* Finish the last entry. */
- if (a->archive.state == ARCHIVE_STATE_DATA)
+ /* Finish the last entry if a finish callback is specified */
+ if (a->archive.state == ARCHIVE_STATE_DATA
+ && a->format_finish_entry != NULL)
r = ((a->format_finish_entry)(a));
/* Finish off the archive. */
@@ -591,6 +598,11 @@ _archive_write_free(struct archive *_a)
/* Release various dynamic buffers. */
free((void *)(uintptr_t)(const void *)a->nulls);
archive_string_free(&a->archive.error_string);
+ if (a->passphrase != NULL) {
+ /* A passphrase should be cleaned. */
+ memset(a->passphrase, 0, strlen(a->passphrase));
+ free(a->passphrase);
+ }
a->archive.magic = 0;
__archive_clean(&a->archive);
free(a);
@@ -638,6 +650,9 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry)
/* Format and write header. */
r2 = ((a->format_write_header)(a, entry));
+ if (r2 == ARCHIVE_FAILED) {
+ return (ARCHIVE_FAILED);
+ }
if (r2 == ARCHIVE_FATAL) {
a->archive.state = ARCHIVE_STATE_FATAL;
return (ARCHIVE_FATAL);
@@ -658,7 +673,8 @@ _archive_write_finish_entry(struct archive *_a)
archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
"archive_write_finish_entry");
- if (a->archive.state & ARCHIVE_STATE_DATA)
+ if (a->archive.state & ARCHIVE_STATE_DATA
+ && a->format_finish_entry != NULL)
ret = (a->format_finish_entry)(a);
a->archive.state = ARCHIVE_STATE_HEADER;
return (ret);
@@ -671,8 +687,13 @@ static ssize_t
_archive_write_data(struct archive *_a, const void *buff, size_t s)
{
struct archive_write *a = (struct archive_write *)_a;
+ const size_t max_write = INT_MAX;
+
archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_DATA, "archive_write_data");
+ /* In particular, this catches attempts to pass negative values. */
+ if (s > max_write)
+ s = max_write;
archive_clear_error(&a->archive);
return ((a->format_write_data)(a, buff, s));
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter.c
index 81dd683aa..ad5dc832f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter.c
@@ -47,6 +47,7 @@ struct { int code; int (*setter)(struct archive *); } codes[] =
{ ARCHIVE_FILTER_COMPRESS, archive_write_add_filter_compress },
{ ARCHIVE_FILTER_GRZIP, archive_write_add_filter_grzip },
{ ARCHIVE_FILTER_LRZIP, archive_write_add_filter_lrzip },
+ { ARCHIVE_FILTER_LZ4, archive_write_add_filter_lz4 },
{ ARCHIVE_FILTER_LZIP, archive_write_add_filter_lzip },
{ ARCHIVE_FILTER_LZMA, archive_write_add_filter_lzma },
{ ARCHIVE_FILTER_LZOP, archive_write_add_filter_lzip },
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_by_name.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_by_name.c
index e4cba4afa..eac4011cb 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_by_name.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_by_name.c
@@ -51,6 +51,7 @@ struct { const char *name; int (*setter)(struct archive *); } names[] =
{ "grzip", archive_write_add_filter_grzip },
{ "gzip", archive_write_add_filter_gzip },
{ "lrzip", archive_write_add_filter_lrzip },
+ { "lz4", archive_write_add_filter_lz4 },
{ "lzip", archive_write_add_filter_lzip },
{ "lzma", archive_write_add_filter_lzma },
{ "lzop", archive_write_add_filter_lzop },
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lrzip.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lrzip.c
index 85fdf6af5..da1cf5e4c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lrzip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lrzip.c
@@ -44,7 +44,7 @@ __FBSDID("$FreeBSD$");
struct write_lrzip {
struct archive_write_program_data *pdata;
int compression_level;
- enum { lzma = 0, bzip2, gzip, lzo, zpaq } compression;
+ enum { lzma = 0, bzip2, gzip, lzo, none, zpaq } compression;
};
static int archive_write_lrzip_open(struct archive_write_filter *);
@@ -107,6 +107,8 @@ archive_write_lrzip_options(struct archive_write_filter *f, const char *key,
data->compression = gzip;
else if (strcmp(value, "lzo") == 0)
data->compression = lzo;
+ else if (strcmp(value, "none") == 0)
+ data->compression = none;
else if (strcmp(value, "zpaq") == 0)
data->compression = zpaq;
else
@@ -148,6 +150,9 @@ archive_write_lrzip_open(struct archive_write_filter *f)
case lzo:
archive_strcat(&as, " -l");
break;
+ case none:
+ archive_strcat(&as, " -n");
+ break;
case zpaq:
archive_strcat(&as, " -z");
break;
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lz4.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lz4.c
new file mode 100644
index 000000000..e23e5e939
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lz4.c
@@ -0,0 +1,646 @@
+/*-
+ * Copyright (c) 2014 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+
+__FBSDID("$FreeBSD$");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_LZ4_H
+#include <lz4.h>
+#endif
+#ifdef HAVE_LZ4HC_H
+#include <lz4hc.h>
+#endif
+
+#include "archive.h"
+#include "archive_endian.h"
+#include "archive_private.h"
+#include "archive_write_private.h"
+#include "archive_xxhash.h"
+
+#define LZ4_MAGICNUMBER 0x184d2204
+
+struct private_data {
+ int compression_level;
+ unsigned header_written:1;
+ unsigned version_number:1;
+ unsigned block_independence:1;
+ unsigned block_checksum:1;
+ unsigned stream_size:1;
+ unsigned stream_checksum:1;
+ unsigned preset_dictionary:1;
+ unsigned block_maximum_size:3;
+#if defined(HAVE_LIBLZ4) && LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 2
+ int64_t total_in;
+ char *out;
+ char *out_buffer;
+ size_t out_buffer_size;
+ size_t out_block_size;
+ char *in;
+ char *in_buffer_allocated;
+ char *in_buffer;
+ size_t in_buffer_size;
+ size_t block_size;
+
+ void *xxh32_state;
+ void *lz4_stream;
+#else
+ struct archive_write_program_data *pdata;
+#endif
+};
+
+static int archive_filter_lz4_close(struct archive_write_filter *);
+static int archive_filter_lz4_free(struct archive_write_filter *);
+static int archive_filter_lz4_open(struct archive_write_filter *);
+static int archive_filter_lz4_options(struct archive_write_filter *,
+ const char *, const char *);
+static int archive_filter_lz4_write(struct archive_write_filter *,
+ const void *, size_t);
+
+/*
+ * Add a lz4 compression filter to this write handle.
+ */
+int
+archive_write_add_filter_lz4(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct archive_write_filter *f = __archive_write_allocate_filter(_a);
+ struct private_data *data;
+
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_add_filter_lz4");
+
+ data = calloc(1, sizeof(*data));
+ if (data == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Setup default settings.
+ */
+ data->compression_level = 1;
+ data->version_number = 0x01;
+ data->block_independence = 1;
+ data->block_checksum = 0;
+ data->stream_size = 0;
+ data->stream_checksum = 1;
+ data->preset_dictionary = 0;
+ data->block_maximum_size = 7;
+
+ /*
+ * Setup a filter setting.
+ */
+ f->data = data;
+ f->options = &archive_filter_lz4_options;
+ f->close = &archive_filter_lz4_close;
+ f->free = &archive_filter_lz4_free;
+ f->open = &archive_filter_lz4_open;
+ f->code = ARCHIVE_FILTER_LZ4;
+ f->name = "lz4";
+#if defined(HAVE_LIBLZ4) && LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 2
+ return (ARCHIVE_OK);
+#else
+ /*
+ * We don't have lz4 library, and execute external lz4 program
+ * instead.
+ */
+ data->pdata = __archive_write_program_allocate();
+ if (data->pdata == NULL) {
+ free(data);
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ data->compression_level = 0;
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Using external lz4 program");
+ return (ARCHIVE_WARN);
+#endif
+}
+
+/*
+ * Set write options.
+ */
+static int
+archive_filter_lz4_options(struct archive_write_filter *f,
+ const char *key, const char *value)
+{
+ struct private_data *data = (struct private_data *)f->data;
+
+ if (strcmp(key, "compression-level") == 0) {
+ if (value == NULL || !(value[0] >= '1' && value[0] <= '9') ||
+ value[1] != '\0')
+ return (ARCHIVE_WARN);
+ data->compression_level = value[0] - '0';
+ return (ARCHIVE_OK);
+ }
+ if (strcmp(key, "stream-checksum") == 0) {
+ data->stream_checksum = value != NULL;
+ return (ARCHIVE_OK);
+ }
+ if (strcmp(key, "block-checksum") == 0) {
+ data->block_checksum = value != NULL;
+ return (ARCHIVE_OK);
+ }
+ if (strcmp(key, "block-size") == 0) {
+ if (value == NULL || !(value[0] >= '4' && value[0] <= '7') ||
+ value[1] != '\0')
+ return (ARCHIVE_WARN);
+ data->block_maximum_size = value[0] - '0';
+ return (ARCHIVE_OK);
+ }
+ if (strcmp(key, "block-dependence") == 0) {
+ data->block_independence = value == NULL;
+ return (ARCHIVE_OK);
+ }
+
+ /* Note: The "warn" return is just to inform the options
+ * supervisor that we didn't handle it. It will generate
+ * a suitable error if no one used this option. */
+ return (ARCHIVE_WARN);
+}
+
+#if defined(HAVE_LIBLZ4) && LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 2
+/* Don't compile this if we don't have liblz4. */
+
+static int drive_compressor(struct archive_write_filter *, const char *,
+ size_t);
+static int drive_compressor_independence(struct archive_write_filter *,
+ const char *, size_t);
+static int drive_compressor_dependence(struct archive_write_filter *,
+ const char *, size_t);
+static int lz4_write_stream_descriptor(struct archive_write_filter *);
+static ssize_t lz4_write_one_block(struct archive_write_filter *, const char *,
+ size_t);
+
+
+/*
+ * Setup callback.
+ */
+static int
+archive_filter_lz4_open(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ int ret;
+ size_t required_size;
+ static size_t bkmap[] = { 64 * 1024, 256 * 1024, 1 * 1024 * 1024,
+ 4 * 1024 * 1024 };
+ size_t pre_block_size;
+
+ ret = __archive_write_open_filter(f->next_filter);
+ if (ret != 0)
+ return (ret);
+
+ if (data->block_maximum_size < 4)
+ data->block_size = bkmap[0];
+ else
+ data->block_size = bkmap[data->block_maximum_size - 4];
+
+ required_size = 4 + 15 + 4 + data->block_size + 4 + 4;
+ if (data->out_buffer_size < required_size) {
+ size_t bs = required_size, bpb;
+ free(data->out_buffer);
+ if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
+ /* Buffer size should be a multiple number of
+ * the of bytes per block for performance. */
+ bpb = archive_write_get_bytes_per_block(f->archive);
+ if (bpb > bs)
+ bs = bpb;
+ else if (bpb != 0) {
+ bs += bpb;
+ bs -= bs % bpb;
+ }
+ }
+ data->out_block_size = bs;
+ bs += required_size;
+ data->out_buffer = malloc(bs);
+ data->out = data->out_buffer;
+ data->out_buffer_size = bs;
+ }
+
+ pre_block_size = (data->block_independence)? 0: 64 * 1024;
+ if (data->in_buffer_size < data->block_size + pre_block_size) {
+ free(data->in_buffer_allocated);
+ data->in_buffer_size = data->block_size;
+ data->in_buffer_allocated =
+ malloc(data->in_buffer_size + pre_block_size);
+ data->in_buffer = data->in_buffer_allocated + pre_block_size;
+ if (!data->block_independence && data->compression_level >= 3)
+ data->in_buffer = data->in_buffer_allocated;
+ data->in = data->in_buffer;
+ data->in_buffer_size = data->block_size;
+ }
+
+ if (data->out_buffer == NULL || data->in_buffer_allocated == NULL) {
+ archive_set_error(f->archive, ENOMEM,
+ "Can't allocate data for compression buffer");
+ return (ARCHIVE_FATAL);
+ }
+
+ f->write = archive_filter_lz4_write;
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Write data to the out stream.
+ *
+ * Returns ARCHIVE_OK if all data written, error otherwise.
+ */
+static int
+archive_filter_lz4_write(struct archive_write_filter *f,
+ const void *buff, size_t length)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ int ret = ARCHIVE_OK;
+ const char *p;
+ size_t remaining;
+ ssize_t size;
+
+ /* If we haven't written a stream descriptor, we have to do it first. */
+ if (!data->header_written) {
+ ret = lz4_write_stream_descriptor(f);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ data->header_written = 1;
+ }
+
+ /* Update statistics */
+ data->total_in += length;
+
+ p = (const char *)buff;
+ remaining = length;
+ while (remaining) {
+ size_t l;
+ /* Compress input data to output buffer */
+ size = lz4_write_one_block(f, p, remaining);
+ if (size < ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ l = data->out - data->out_buffer;
+ if (l >= data->out_block_size) {
+ ret = __archive_write_filter(f->next_filter,
+ data->out_buffer, data->out_block_size);
+ l -= data->out_block_size;
+ memcpy(data->out_buffer,
+ data->out_buffer + data->out_block_size, l);
+ data->out = data->out_buffer + l;
+ if (ret < ARCHIVE_WARN)
+ break;
+ }
+ p += size;
+ remaining -= size;
+ }
+
+ return (ret);
+}
+
+/*
+ * Finish the compression.
+ */
+static int
+archive_filter_lz4_close(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ int ret, r1;
+
+ /* Finish compression cycle. */
+ ret = (int)lz4_write_one_block(f, NULL, 0);
+ if (ret >= 0) {
+ /*
+ * Write the last block and the end of the stream data.
+ */
+
+ /* Write End Of Stream. */
+ memset(data->out, 0, 4); data->out += 4;
+ /* Write Stream checksum if needed. */
+ if (data->stream_checksum) {
+ unsigned int checksum;
+ checksum = __archive_xxhash.XXH32_digest(
+ data->xxh32_state);
+ data->xxh32_state = NULL;
+ archive_le32enc(data->out, checksum);
+ data->out += 4;
+ }
+ ret = __archive_write_filter(f->next_filter,
+ data->out_buffer, data->out - data->out_buffer);
+ }
+
+ r1 = __archive_write_close_filter(f->next_filter);
+ return (r1 < ret ? r1 : ret);
+}
+
+static int
+archive_filter_lz4_free(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+
+ if (data->lz4_stream != NULL) {
+ if (data->compression_level < 3)
+#if LZ4_VERSION_MINOR >= 3
+ LZ4_freeStream(data->lz4_stream);
+#else
+ LZ4_free(data->lz4_stream);
+#endif
+ else
+ LZ4_freeHC(data->lz4_stream);
+ }
+ free(data->out_buffer);
+ free(data->in_buffer_allocated);
+ free(data->xxh32_state);
+ free(data);
+ f->data = NULL;
+ return (ARCHIVE_OK);
+}
+
+static int
+lz4_write_stream_descriptor(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ uint8_t *sd;
+
+ sd = (uint8_t *)data->out;
+ /* Write Magic Number. */
+ archive_le32enc(&sd[0], LZ4_MAGICNUMBER);
+ /* FLG */
+ sd[4] = (data->version_number << 6)
+ | (data->block_independence << 5)
+ | (data->block_checksum << 4)
+ | (data->stream_size << 3)
+ | (data->stream_checksum << 2)
+ | (data->preset_dictionary << 0);
+ /* BD */
+ sd[5] = (data->block_maximum_size << 4);
+ sd[6] = (__archive_xxhash.XXH32(&sd[4], 2, 0) >> 8) & 0xff;
+ data->out += 7;
+ if (data->stream_checksum)
+ data->xxh32_state = __archive_xxhash.XXH32_init(0);
+ else
+ data->xxh32_state = NULL;
+ return (ARCHIVE_OK);
+}
+
+static ssize_t
+lz4_write_one_block(struct archive_write_filter *f, const char *p,
+ size_t length)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ ssize_t r;
+
+ if (p == NULL) {
+ /* Compress remaining uncompressed data. */
+ if (data->in_buffer == data->in)
+ return 0;
+ else {
+ size_t l = data->in - data->in_buffer;
+ r = drive_compressor(f, data->in_buffer, l);
+ if (r == ARCHIVE_OK)
+ r = (ssize_t)l;
+ }
+ } else if ((data->block_independence || data->compression_level < 3) &&
+ data->in_buffer == data->in && length >= data->block_size) {
+ r = drive_compressor(f, p, data->block_size);
+ if (r == ARCHIVE_OK)
+ r = (ssize_t)data->block_size;
+ } else {
+ size_t remaining_size = data->in_buffer_size -
+ (data->in - data->in_buffer);
+ size_t l = (remaining_size > length)? length: remaining_size;
+ memcpy(data->in, p, l);
+ data->in += l;
+ if (l == remaining_size) {
+ r = drive_compressor(f, data->in_buffer,
+ data->block_size);
+ if (r == ARCHIVE_OK)
+ r = (ssize_t)l;
+ data->in = data->in_buffer;
+ } else
+ r = (ssize_t)l;
+ }
+
+ return (r);
+}
+
+
+/*
+ * Utility function to push input data through compressor, writing
+ * full output blocks as necessary.
+ *
+ * Note that this handles both the regular write case (finishing ==
+ * false) and the end-of-archive case (finishing == true).
+ */
+static int
+drive_compressor(struct archive_write_filter *f, const char *p, size_t length)
+{
+ struct private_data *data = (struct private_data *)f->data;
+
+ if (data->stream_checksum)
+ __archive_xxhash.XXH32_update(data->xxh32_state,
+ p, (int)length);
+ if (data->block_independence)
+ return drive_compressor_independence(f, p, length);
+ else
+ return drive_compressor_dependence(f, p, length);
+}
+
+static int
+drive_compressor_independence(struct archive_write_filter *f, const char *p,
+ size_t length)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ unsigned int outsize;
+
+ if (data->compression_level < 4)
+ outsize = LZ4_compress_limitedOutput(p, data->out + 4,
+ (int)length, (int)data->block_size);
+ else
+ outsize = LZ4_compressHC2_limitedOutput(p, data->out + 4,
+ (int)length, (int)data->block_size,
+ data->compression_level);
+
+ if (outsize) {
+ /* The buffer is compressed. */
+ archive_le32enc(data->out, outsize);
+ data->out += 4;
+ } else {
+ /* The buffer is not compressed. The commpressed size was
+ * bigger than its uncompressed size. */
+ archive_le32enc(data->out, length | 0x80000000);
+ data->out += 4;
+ memcpy(data->out, p, length);
+ outsize = length;
+ }
+ data->out += outsize;
+ if (data->block_checksum) {
+ unsigned int checksum =
+ __archive_xxhash.XXH32(data->out - outsize, outsize, 0);
+ archive_le32enc(data->out, checksum);
+ data->out += 4;
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+drive_compressor_dependence(struct archive_write_filter *f, const char *p,
+ size_t length)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ int outsize;
+
+ if (data->compression_level < 3) {
+ if (data->lz4_stream == NULL) {
+ data->lz4_stream = LZ4_createStream();
+ if (data->lz4_stream == NULL) {
+ archive_set_error(f->archive, ENOMEM,
+ "Can't allocate data for compression"
+ " buffer");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ outsize = LZ4_compress_limitedOutput_continue(
+ data->lz4_stream, p, data->out + 4, (int)length,
+ (int)data->block_size);
+ } else {
+ if (data->lz4_stream == NULL) {
+ data->lz4_stream =
+ LZ4_createHC(data->in_buffer_allocated);
+ if (data->lz4_stream == NULL) {
+ archive_set_error(f->archive, ENOMEM,
+ "Can't allocate data for compression"
+ " buffer");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ outsize = LZ4_compressHC2_limitedOutput_continue(
+ data->lz4_stream, p, data->out + 4, (int)length,
+ (int)data->block_size, data->compression_level);
+ }
+
+ if (outsize) {
+ /* The buffer is compressed. */
+ archive_le32enc(data->out, outsize);
+ data->out += 4;
+ } else {
+ /* The buffer is not compressed. The commpressed size was
+ * bigger than its uncompressed size. */
+ archive_le32enc(data->out, length | 0x80000000);
+ data->out += 4;
+ memcpy(data->out, p, length);
+ outsize = length;
+ }
+ data->out += outsize;
+ if (data->block_checksum) {
+ unsigned int checksum =
+ __archive_xxhash.XXH32(data->out - outsize, outsize, 0);
+ archive_le32enc(data->out, checksum);
+ data->out += 4;
+ }
+
+ if (length == data->block_size) {
+#define DICT_SIZE (64 * 1024)
+ if (data->compression_level < 3)
+ LZ4_saveDict(data->lz4_stream,
+ data->in_buffer_allocated, DICT_SIZE);
+ else {
+ LZ4_slideInputBufferHC(data->lz4_stream);
+ data->in_buffer = data->in_buffer_allocated + DICT_SIZE;
+ }
+#undef DICT_SIZE
+ }
+ return (ARCHIVE_OK);
+}
+
+#else /* HAVE_LIBLZ4 */
+
+static int
+archive_filter_lz4_open(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ struct archive_string as;
+ int r;
+
+ archive_string_init(&as);
+ archive_strcpy(&as, "lz4 -z -q -q");
+
+ /* Specify a compression level. */
+ if (data->compression_level > 0) {
+ archive_strcat(&as, " -");
+ archive_strappend_char(&as, '0' + data->compression_level);
+ }
+ /* Specify a block size. */
+ archive_strcat(&as, " -B");
+ archive_strappend_char(&as, '0' + data->block_maximum_size);
+
+ if (data->block_checksum)
+ archive_strcat(&as, " -BX");
+ if (data->stream_checksum == 0)
+ archive_strcat(&as, " -Sx");
+ if (data->block_independence == 0)
+ archive_strcat(&as, " -BD");
+
+ f->write = archive_filter_lz4_write;
+
+ r = __archive_write_program_open(f, data->pdata, as.s);
+ archive_string_free(&as);
+ return (r);
+}
+
+static int
+archive_filter_lz4_write(struct archive_write_filter *f, const void *buff,
+ size_t length)
+{
+ struct private_data *data = (struct private_data *)f->data;
+
+ return __archive_write_program_write(f, data->pdata, buff, length);
+}
+
+static int
+archive_filter_lz4_close(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+
+ return __archive_write_program_close(f, data->pdata);
+}
+
+static int
+archive_filter_lz4_free(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+
+ __archive_write_program_free(data->pdata);
+ free(data);
+ return (ARCHIVE_OK);
+}
+
+#endif /* HAVE_LIBLZ4 */
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lzop.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lzop.c
index 088ecea51..c666551d1 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lzop.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lzop.c
@@ -85,7 +85,7 @@ static int archive_write_lzop_free(struct archive_write_filter *);
#if defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H)
/* Maximum block size. */
#define BLOCK_SIZE (256 * 1024)
-/* Block infomation is composed of uncompressed size(4 bytes),
+/* Block information is composed of uncompressed size(4 bytes),
* compressed size(4 bytes) and the checksum of uncompressed data(4 bytes)
* in this lzop writer. */
#define BLOCK_INfO_SIZE 12
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_xz.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_xz.c
index fa73311e7..4f849ce92 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_xz.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_xz.c
@@ -39,7 +39,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_xz.c 20110
#endif
#include <time.h>
#ifdef HAVE_LZMA_H
-#include <lzma.h>
+#include <cm_lzma.h>
#endif
#include "archive.h"
@@ -100,6 +100,7 @@ archive_write_add_filter_lzip(struct archive *a)
struct private_data {
int compression_level;
+ uint32_t threads;
lzma_stream stream;
lzma_filter lzmafilters[2];
lzma_options_lzma lzma_opt;
@@ -151,6 +152,7 @@ common_setup(struct archive_write_filter *f)
}
f->data = data;
data->compression_level = LZMA_PRESET_DEFAULT;
+ data->threads = 1;
f->open = &archive_compressor_xz_open;
f->close = archive_compressor_xz_close;
f->free = archive_compressor_xz_free;
@@ -221,23 +223,37 @@ archive_compressor_xz_init_stream(struct archive_write_filter *f,
{
static const lzma_stream lzma_stream_init_data = LZMA_STREAM_INIT;
int ret;
+#ifdef HAVE_LZMA_STREAM_ENCODER_MT
+ lzma_mt mt_options;
+#endif
data->stream = lzma_stream_init_data;
data->stream.next_out = data->compressed;
data->stream.avail_out = data->compressed_buffer_size;
- if (f->code == ARCHIVE_FILTER_XZ)
- ret = lzma_stream_encoder(&(data->stream),
- data->lzmafilters, LZMA_CHECK_CRC64);
- else if (f->code == ARCHIVE_FILTER_LZMA)
+ if (f->code == ARCHIVE_FILTER_XZ) {
+#ifdef HAVE_LZMA_STREAM_ENCODER_MT
+ if (data->threads != 1) {
+ bzero(&mt_options, sizeof(mt_options));
+ mt_options.threads = data->threads;
+ mt_options.timeout = 300;
+ mt_options.filters = data->lzmafilters;
+ mt_options.check = LZMA_CHECK_CRC64;
+ ret = lzma_stream_encoder_mt(&(data->stream),
+ &mt_options);
+ } else
+#endif
+ ret = lzma_stream_encoder(&(data->stream),
+ data->lzmafilters, LZMA_CHECK_CRC64);
+ } else if (f->code == ARCHIVE_FILTER_LZMA) {
ret = lzma_alone_encoder(&(data->stream), &data->lzma_opt);
- else { /* ARCHIVE_FILTER_LZIP */
+ } else { /* ARCHIVE_FILTER_LZIP */
int dict_size = data->lzma_opt.dict_size;
int ds, log2dic, wedges;
/* Calculate a coded dictionary size */
if (dict_size < (1 << 12) || dict_size > (1 << 27)) {
archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
- "Unacceptable dictionary dize for lzip: %d",
+ "Unacceptable dictionary size for lzip: %d",
dict_size);
return (ARCHIVE_FATAL);
}
@@ -373,6 +389,22 @@ archive_compressor_xz_options(struct archive_write_filter *f,
if (data->compression_level > 6)
data->compression_level = 6;
return (ARCHIVE_OK);
+ } else if (strcmp(key, "threads") == 0) {
+ if (value == NULL)
+ return (ARCHIVE_WARN);
+ data->threads = (int)strtoul(value, NULL, 10);
+ if (data->threads == 0 && errno != 0) {
+ data->threads = 1;
+ return (ARCHIVE_WARN);
+ }
+ if (data->threads == 0) {
+#ifdef HAVE_LZMA_STREAM_ENCODER_MT
+ data->threads = lzma_cputhreads();
+#else
+ data->threads = 1;
+#endif
+ }
+ return (ARCHIVE_OK);
}
/* Note: The "warn" return is just to inform the options
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_data.3 b/Utilities/cmlibarchive/libarchive/archive_write_data.3
index cfd5cd552..0cdd25f1f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_data.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_data.3
@@ -34,7 +34,7 @@
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS
.In archive.h
-.Ft ssize_t
+.Ft la_ssize_t
.Fn archive_write_data "struct archive *" "const void *" "size_t"
.Sh DESCRIPTION
Write data corresponding to the header just written.
@@ -42,8 +42,7 @@ Write data corresponding to the header just written.
.\"
.Sh RETURN VALUES
This function returns the number of bytes actually written, or
-.Li -1
-on error.
+a negative error code on error.
.\"
.Sh ERRORS
Detailed error codes and textual descriptions are available from the
@@ -52,6 +51,15 @@ and
.Fn archive_error_string
functions.
.\"
+.Sh BUGS
+In libarchive 3.x, this function sometimes returns
+zero on success instead of returning the number of bytes written.
+Specifically, this occurs when writing to an
+.Vt archive_write_disk
+handle.
+Clients should treat any value less than zero as an error
+and consider any non-negative value as success.
+.\"
.Sh SEE ALSO
.Xr tar 1 ,
.Xr libarchive 3 ,
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk.3 b/Utilities/cmlibarchive/libarchive/archive_write_disk.3
index fa925cc54..ba6c9706e 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk.3
@@ -70,9 +70,9 @@ Streaming Archive Library (libarchive, -larchive)
.Fc
.Ft int
.Fn archive_write_header "struct archive *" "struct archive_entry *"
-.Ft ssize_t
+.Ft la_ssize_t
.Fn archive_write_data "struct archive *" "const void *" "size_t"
-.Ft ssize_t
+.Ft la_ssize_t
.Fn archive_write_data_block "struct archive *" "const void *" "size_t size" "int64_t offset"
.Ft int
.Fn archive_write_finish_entry "struct archive *"
@@ -177,10 +177,16 @@ The default is to not refuse such paths.
Note that paths ending in
.Pa ..
always cause an error, regardless of this flag.
+.It Cm ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS
+Refuse to extract an absolute path.
+The default is to not refuse such paths.
.It Cm ARCHIVE_EXTRACT_SPARSE
Scan data for blocks of NUL bytes and try to recreate them with holes.
This results in sparse files, independent of whether the archive format
supports or uses them.
+.It Cm ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS
+Before removing a file system object prior to replacing it, clear
+platform-specific file flags which might prevent its removal.
.El
.It Xo
.Fn archive_write_disk_set_group_lookup ,
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_acl.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_acl.c
index 97972033c..5cbba54f0 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk_acl.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_acl.c
@@ -43,7 +43,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_disk.c 201159 2009-12-29 0
#include "archive_acl_private.h"
#include "archive_write_disk_private.h"
-#if !defined(HAVE_POSIX_ACL) || !defined(ACL_TYPE_NFS4)
+#ifndef HAVE_POSIX_ACL
/* Default empty function body to satisfy mainline code. */
int
archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
@@ -79,10 +79,12 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_DEFAULT,
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
return (ret);
+#ifdef ACL_TYPE_NFS4
} else if (archive_acl_count(abstract_acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4) > 0) {
ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_NFS4,
ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
return (ret);
+#endif
} else
return ARCHIVE_OK;
}
@@ -94,6 +96,7 @@ static struct {
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
+#ifdef ACL_TYPE_NFS4
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
@@ -110,8 +113,10 @@ static struct {
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
+#endif
};
+#ifdef ACL_TYPE_NFS4
static struct {
int archive_inherit;
int platform_inherit;
@@ -121,6 +126,7 @@ static struct {
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY}
};
+#endif
static int
set_acl(struct archive *a, int fd, const char *name,
@@ -130,7 +136,9 @@ set_acl(struct archive *a, int fd, const char *name,
acl_t acl;
acl_entry_t acl_entry;
acl_permset_t acl_permset;
+#ifdef ACL_TYPE_NFS4
acl_flagset_t acl_flagset;
+#endif
int ret;
int ae_type, ae_permset, ae_tag, ae_id;
uid_t ae_uid;
@@ -171,14 +179,17 @@ set_acl(struct archive *a, int fd, const char *name,
case ARCHIVE_ENTRY_ACL_OTHER:
acl_set_tag_type(acl_entry, ACL_OTHER);
break;
+#ifdef ACL_TYPE_NFS4
case ARCHIVE_ENTRY_ACL_EVERYONE:
acl_set_tag_type(acl_entry, ACL_EVERYONE);
break;
+#endif
default:
/* XXX */
break;
}
+#ifdef ACL_TYPE_NFS4
switch (ae_type) {
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALLOW);
@@ -200,6 +211,7 @@ set_acl(struct archive *a, int fd, const char *name,
// XXX error handling here.
break;
}
+#endif
acl_get_permset(acl_entry, &acl_permset);
acl_clear_perms(acl_permset);
@@ -210,6 +222,7 @@ set_acl(struct archive *a, int fd, const char *name,
acl_perm_map[i].platform_perm);
}
+#ifdef ACL_TYPE_NFS4
acl_get_flagset_np(acl_entry, &acl_flagset);
acl_clear_flags_np(acl_flagset);
for (i = 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map[0])); ++i) {
@@ -217,6 +230,7 @@ set_acl(struct archive *a, int fd, const char *name,
acl_add_flag_np(acl_flagset,
acl_inherit_map[i].platform_inherit);
}
+#endif
}
/* Try restoring the ACL through 'fd' if we can. */
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
index b69c8739d..450ac7504 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
@@ -343,6 +343,7 @@ static int restore_entry(struct archive_write_disk *);
static int set_mac_metadata(struct archive_write_disk *, const char *,
const void *, size_t);
static int set_xattrs(struct archive_write_disk *);
+static int clear_nochange_fflags(struct archive_write_disk *);
static int set_fflags(struct archive_write_disk *);
static int set_fflags_platform(struct archive_write_disk *, int fd,
const char *name, mode_t mode,
@@ -1467,10 +1468,14 @@ _archive_write_disk_data_block(struct archive *_a,
return (r);
if ((size_t)r < size) {
archive_set_error(&a->archive, 0,
- "Write request too large");
+ "Too much data: Truncating file at %ju bytes", (uintmax_t)a->filesize);
return (ARCHIVE_WARN);
}
+#if ARCHIVE_VERSION_NUMBER < 3999000
return (ARCHIVE_OK);
+#else
+ return (size);
+#endif
}
static ssize_t
@@ -1842,6 +1847,8 @@ restore_entry(struct archive_write_disk *a)
* object is a dir, but that doesn't mean the old
* object isn't a dir.
*/
+ if (a->flags & ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS)
+ (void)clear_nochange_fflags(a);
if (unlink(a->name) == 0) {
/* We removed it, reset cached stat. */
a->pst = NULL;
@@ -1869,6 +1876,13 @@ restore_entry(struct archive_write_disk *a)
en = create_filesystem_object(a);
}
+ if ((en == ENOENT) && (archive_entry_hardlink(a->entry) != NULL)) {
+ archive_set_error(&a->archive, en,
+ "Hard-link target '%s' does not exist.",
+ archive_entry_hardlink(a->entry));
+ return (ARCHIVE_FAILED);
+ }
+
if ((en == EISDIR || en == EEXIST)
&& (a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
/* If we're not overwriting, we're done. */
@@ -1940,6 +1954,8 @@ restore_entry(struct archive_write_disk *a)
if (!S_ISDIR(a->st.st_mode)) {
/* A non-dir is in the way, unlink it. */
+ if (a->flags & ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS)
+ (void)clear_nochange_fflags(a);
if (unlink(a->name) != 0) {
archive_set_error(&a->archive, errno,
"Can't unlink already-existing object");
@@ -1950,6 +1966,8 @@ restore_entry(struct archive_write_disk *a)
en = create_filesystem_object(a);
} else if (!S_ISDIR(a->mode)) {
/* A dir is in the way of a non-dir, rmdir it. */
+ if (a->flags & ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS)
+ (void)clear_nochange_fflags(a);
if (rmdir(a->name) != 0) {
archive_set_error(&a->archive, errno,
"Can't replace existing directory with non-directory");
@@ -2215,7 +2233,8 @@ _archive_write_disk_free(struct archive *_a)
free(a->resource_fork);
free(a->compressed_buffer);
free(a->uncompressed_buffer);
-#ifdef HAVE_ZLIB_H
+#if defined(__APPLE__) && defined(UF_COMPRESSED) && defined(HAVE_SYS_XATTR_H)\
+ && defined(HAVE_ZLIB_H)
if (a->stream_valid) {
switch (deflateEnd(&a->stream)) {
case Z_OK:
@@ -2504,8 +2523,9 @@ cleanup_pathname_win(struct archive_write_disk *a)
/*
* Canonicalize the pathname. In particular, this strips duplicate
* '/' characters, '.' elements, and trailing '/'. It also raises an
- * error for an empty path, a trailing '..' or (if _SECURE_NODOTDOT is
- * set) any '..' in the path.
+ * error for an empty path, a trailing '..', (if _SECURE_NODOTDOT is
+ * set) any '..' in the path or (if ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS
+ * is set) if the path is absolute.
*/
static int
cleanup_pathname(struct archive_write_disk *a)
@@ -2524,8 +2544,15 @@ cleanup_pathname(struct archive_write_disk *a)
cleanup_pathname_win(a);
#endif
/* Skip leading '/'. */
- if (*src == '/')
+ if (*src == '/') {
+ if (a->flags & ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Path is absolute");
+ return (ARCHIVE_FAILED);
+ }
+
separator = *src++;
+ }
/* Scan the pathname one element at a time. */
for (;;) {
@@ -2861,7 +2888,7 @@ set_time(int fd, int mode, const char *name,
#endif
}
-#ifdef F_SETTIMES /* Tru64 */
+#ifdef F_SETTIMES
static int
set_time_tru64(int fd, int mode, const char *name,
time_t atime, long atime_nsec,
@@ -2869,19 +2896,21 @@ set_time_tru64(int fd, int mode, const char *name,
time_t ctime, long ctime_nsec)
{
struct attr_timbuf tstamp;
- struct timeval times[3];
- times[0].tv_sec = atime;
- times[0].tv_usec = atime_nsec / 1000;
- times[1].tv_sec = mtime;
- times[1].tv_usec = mtime_nsec / 1000;
- times[2].tv_sec = ctime;
- times[2].tv_usec = ctime_nsec / 1000;
- tstamp.atime = times[0];
- tstamp.mtime = times[1];
- tstamp.ctime = times[2];
+ tstamp.atime.tv_sec = atime;
+ tstamp.mtime.tv_sec = mtime;
+ tstamp.ctime.tv_sec = ctime;
+#if defined (__hpux) && defined (__ia64)
+ tstamp.atime.tv_nsec = atime_nsec;
+ tstamp.mtime.tv_nsec = mtime_nsec;
+ tstamp.ctime.tv_nsec = ctime_nsec;
+#else
+ tstamp.atime.tv_usec = atime_nsec / 1000;
+ tstamp.mtime.tv_usec = mtime_nsec / 1000;
+ tstamp.ctime.tv_usec = ctime_nsec / 1000;
+#endif
return (fcntl(fd,F_SETTIMES,&tstamp));
}
-#endif /* Tru64 */
+#endif /* F_SETTIMES */
static int
set_times(struct archive_write_disk *a,
@@ -3053,9 +3082,23 @@ set_mode(struct archive_write_disk *a, int mode)
* impact.
*/
if (lchmod(a->name, mode) != 0) {
- archive_set_error(&a->archive, errno,
- "Can't set permissions to 0%o", (int)mode);
- r = ARCHIVE_WARN;
+ switch (errno) {
+ case ENOTSUP:
+ case ENOSYS:
+#if ENOTSUP != EOPNOTSUPP
+ case EOPNOTSUPP:
+#endif
+ /*
+ * if lchmod is defined but the platform
+ * doesn't support it, silently ignore
+ * error
+ */
+ break;
+ default:
+ archive_set_error(&a->archive, errno,
+ "Can't set permissions to 0%o", (int)mode);
+ r = ARCHIVE_WARN;
+ }
}
#endif
} else if (!S_ISDIR(a->mode)) {
@@ -3156,6 +3199,36 @@ set_fflags(struct archive_write_disk *a)
return (ARCHIVE_OK);
}
+static int
+clear_nochange_fflags(struct archive_write_disk *a)
+{
+ int nochange_flags;
+ mode_t mode = archive_entry_mode(a->entry);
+
+ /* Hopefully, the compiler will optimize this mess into a constant. */
+ nochange_flags = 0;
+#ifdef SF_IMMUTABLE
+ nochange_flags |= SF_IMMUTABLE;
+#endif
+#ifdef UF_IMMUTABLE
+ nochange_flags |= UF_IMMUTABLE;
+#endif
+#ifdef SF_APPEND
+ nochange_flags |= SF_APPEND;
+#endif
+#ifdef UF_APPEND
+ nochange_flags |= UF_APPEND;
+#endif
+#ifdef EXT2_APPEND_FL
+ nochange_flags |= EXT2_APPEND_FL;
+#endif
+#ifdef EXT2_IMMUTABLE_FL
+ nochange_flags |= EXT2_IMMUTABLE_FL;
+#endif
+
+ return (set_fflags_platform(a, a->fd, a->name, mode, 0, nochange_flags));
+}
+
#if ( defined(HAVE_LCHFLAGS) || defined(HAVE_CHFLAGS) || defined(HAVE_FCHFLAGS) ) && defined(HAVE_STRUCT_STAT_ST_FLAGS)
/*
@@ -3363,6 +3436,7 @@ copy_xattrs(struct archive_write_disk *a, int tmpfd, int dffd)
}
for (xattr_i = 0; xattr_i < xattr_size;
xattr_i += strlen(xattr_names + xattr_i) + 1) {
+ char *xattr_val_saved;
ssize_t s;
int f;
@@ -3373,11 +3447,13 @@ copy_xattrs(struct archive_write_disk *a, int tmpfd, int dffd)
ret = ARCHIVE_WARN;
goto exit_xattr;
}
+ xattr_val_saved = xattr_val;
xattr_val = realloc(xattr_val, s);
if (xattr_val == NULL) {
archive_set_error(&a->archive, ENOMEM,
"Failed to get metadata(xattr)");
ret = ARCHIVE_WARN;
+ free(xattr_val_saved);
goto exit_xattr;
}
s = fgetxattr(tmpfd, xattr_names + xattr_i, xattr_val, s, 0, 0);
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_set_standard_lookup.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_set_standard_lookup.c
index e79008ef6..3b868fbad 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk_set_standard_lookup.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_set_standard_lookup.c
@@ -67,7 +67,7 @@ static void cleanup(void *);
* a simple cache to accelerate such lookups---into the archive_write_disk
* object. This is in a separate file because getpwnam()/getgrnam()
* can pull in a LOT of library code (including NIS/LDAP functions, which
- * pull in DNS resolveers, etc). This can easily top 500kB, which makes
+ * pull in DNS resolvers, etc). This can easily top 500kB, which makes
* it inappropriate for some space-constrained applications.
*
* Applications that are size-sensitive may want to just use the
@@ -86,6 +86,11 @@ archive_write_disk_set_standard_lookup(struct archive *a)
{
struct bucket *ucache = malloc(cache_size * sizeof(struct bucket));
struct bucket *gcache = malloc(cache_size * sizeof(struct bucket));
+ if (ucache == NULL || gcache == NULL) {
+ free(ucache);
+ free(gcache);
+ return (ARCHIVE_FATAL);
+ }
memset(ucache, 0, cache_size * sizeof(struct bucket));
memset(gcache, 0, cache_size * sizeof(struct bucket));
archive_write_disk_set_group_lookup(a, gcache, lookup_gid, cleanup);
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
index 0f0780a8e..800aa893f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
@@ -330,8 +330,6 @@ file_information(struct archive_write_disk *a, wchar_t *path,
break;
case L'C': case L'c':
if (((p[2] == L'M' || p[2] == L'm' ) &&
- (p[3] == L'D' || p[3] == L'd' )) ||
- ((p[2] == L'M' || p[2] == L'm' ) &&
(p[3] == L'D' || p[3] == L'd' )))
*mode |= S_IXUSR | S_IXGRP | S_IXOTH;
break;
@@ -525,7 +523,7 @@ la_GetFunctionKernel32(const char *name)
static int set;
if (!set) {
set = 1;
- lib = LoadLibrary("kernel32.dll");
+ lib = LoadLibrary(TEXT("kernel32.dll"));
}
if (lib == NULL) {
fprintf(stderr, "Can't load kernel32.dll?!\n");
@@ -1011,7 +1009,11 @@ _archive_write_disk_data_block(struct archive *_a,
"Write request too large");
return (ARCHIVE_WARN);
}
+#if ARCHIVE_VERSION_NUMBER < 3999000
return (ARCHIVE_OK);
+#else
+ return (size);
+#endif
}
static ssize_t
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_filter.3 b/Utilities/cmlibarchive/libarchive/archive_write_filter.3
index 3ca248b72..83bd2c64f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_filter.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_filter.3
@@ -24,46 +24,62 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 2, 2012
+.Dd August 14, 2014
.Dt ARCHIVE_WRITE_FILTER 3
.Os
.Sh NAME
+.Nm archive_write_add_filter_b64encode ,
.Nm archive_write_add_filter_bzip2 ,
.Nm archive_write_add_filter_compress ,
.Nm archive_write_add_filter_gzip ,
+.Nm archive_write_add_filter_lz4 ,
.Nm archive_write_add_filter_lzip ,
.Nm archive_write_add_filter_lzma ,
+.Nm archive_write_add_filter_lzop ,
.Nm archive_write_add_filter_none ,
.Nm archive_write_add_filter_program ,
+.Nm archive_write_add_filter_uuencode ,
.Nm archive_write_add_filter_xz
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS
.In archive.h
.Ft int
+.Fn archive_write_add_filter_b64encode "struct archive *"
+.Ft int
.Fn archive_write_add_filter_bzip2 "struct archive *"
.Ft int
.Fn archive_write_add_filter_compress "struct archive *"
.Ft int
.Fn archive_write_add_filter_gzip "struct archive *"
.Ft int
+.Fn archive_write_add_filter_lz4 "struct archive *"
+.Ft int
.Fn archive_write_add_filter_lzip "struct archive *"
.Ft int
.Fn archive_write_add_filter_lzma "struct archive *"
.Ft int
+.Fn archive_write_add_filter_lzop "struct archive *"
+.Ft int
.Fn archive_write_add_filter_none "struct archive *"
.Ft int
.Fn archive_write_add_filter_program "struct archive *" "const char * cmd"
.Ft int
+.Fn archive_write_add_filter_uuencode "struct archive *"
+.Ft int
.Fn archive_write_add_filter_xz "struct archive *"
.Sh DESCRIPTION
.Bl -tag -width indent
.It Xo
+.Fn archive_write_add_filter_b64encode ,
.Fn archive_write_add_filter_bzip2 ,
.Fn archive_write_add_filter_compress ,
.Fn archive_write_add_filter_gzip ,
+.Fn archive_write_add_filter_lz4 ,
.Fn archive_write_add_filter_lzip ,
.Fn archive_write_add_filter_lzma ,
+.Fn archive_write_add_filter_lzop ,
+.Fn archive_write_add_filter_uuencode ,
.Fn archive_write_add_filter_xz ,
.Xc
The resulting archive will be compressed as specified.
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_finish_entry.3 b/Utilities/cmlibarchive/libarchive/archive_write_finish_entry.3
index d881c80ea..c5ef69ebc 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_finish_entry.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_finish_entry.3
@@ -41,7 +41,7 @@ Close out the entry just written.
In particular, this writes out the final padding required by some formats.
Ordinarily, clients never need to call this, as it
is called automatically by
-.Fn archive_write_next_header
+.Fn archive_write_header
and
.Fn archive_write_close
as needed.
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_format.3 b/Utilities/cmlibarchive/libarchive/archive_write_format.3
index dad2f7d7e..4bd116340 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_format.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_format.3
@@ -24,16 +24,19 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 2, 2012
+.Dd February 14, 2013
.Dt ARCHIVE_WRITE_FORMAT 3
.Os
.Sh NAME
.Nm archive_write_set_format_cpio ,
.Nm archive_write_set_format_pax ,
.Nm archive_write_set_format_pax_restricted ,
+.Nm archive_write_set_format_raw ,
.Nm archive_write_set_format_shar ,
.Nm archive_write_set_format_shar_dump ,
-.Nm archive_write_set_format_ustar
+.Nm archive_write_set_format_ustar ,
+.Nm archive_write_set_format_filter_by_ext ,
+.Nm archive_write_set_format_filter_by_ext_def
.Nd functions for creating archives
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
@@ -46,11 +49,17 @@ Streaming Archive Library (libarchive, -larchive)
.Ft int
.Fn archive_write_set_format_pax_restricted "struct archive *"
.Ft int
+.Fn archive_write_set_format_raw "struct archive *"
+.Ft int
.Fn archive_write_set_format_shar "struct archive *"
.Ft int
.Fn archive_write_set_format_shar_dump "struct archive *"
.Ft int
.Fn archive_write_set_format_ustar "struct archive *"
+.Ft int
+.Fn archive_write_set_format_filter_by_ext "struct archive *" "const char *"
+.Ft int
+.Fn archive_write_set_format_filter_by_ext_def "struct archive *" "const char *" "const char *"
.Sh DESCRIPTION
These functions set the format that will be used for the archive.
.Pp
@@ -76,6 +85,14 @@ filenames, linknames, uids, sizes, etc.
is the library default; this is the same as pax format, but suppresses
the pax extended header for most normal files.
In most cases, this will result in ordinary ustar archives.
+.Bl -tag -width indent
+.It Xo
+.Fn archive_write_set_format_filter_by_ext ,
+.Fn archive_write_set_format_filter_by_ext_def
+.Xc
+Format and filter for archive can be set automatically, based on output file name extension.
+The functions are platform dependent.
+Supported extensions: .7z, .zip, .jar, .cpio, .iso, .a, .ar, .tar, .tgz, .tar.gz, .tar.bz2, .tar.xz
.\"
.Sh RETURN VALUES
These functions return
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_open.3 b/Utilities/cmlibarchive/libarchive/archive_write_open.3
index 4037248e0..a52959b98 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_open.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_open.3
@@ -154,7 +154,7 @@ to register an error code and message and return
.Cm ARCHIVE_FATAL .
.Bl -item -offset indent
.It
-.Ft typedef ssize_t
+.Ft typedef la_ssize_t
.Fo archive_write_callback
.Fa "struct archive *"
.Fa "void *client_data"
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_open_filename.c b/Utilities/cmlibarchive/libarchive/archive_write_open_filename.c
index 196b770e8..66e0dfee9 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_open_filename.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_open_filename.c
@@ -243,7 +243,10 @@ file_close(struct archive *a, void *client_data)
struct write_file_data *mine = (struct write_file_data *)client_data;
(void)a; /* UNUSED */
- close(mine->fd);
+
+ if (mine->fd >= 0)
+ close(mine->fd);
+
archive_mstring_clean(&mine->filename);
free(mine);
return (ARCHIVE_OK);
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_private.h b/Utilities/cmlibarchive/libarchive/archive_write_private.h
index e600d5474..0c3cc0c6f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_write_private.h
@@ -26,8 +26,10 @@
*/
#ifndef __LIBARCHIVE_BUILD
+#ifndef __LIBARCHIVE_TEST
#error This header is only to be used internally to libarchive.
#endif
+#endif
#ifndef ARCHIVE_WRITE_PRIVATE_H_INCLUDED
#define ARCHIVE_WRITE_PRIVATE_H_INCLUDED
@@ -116,6 +118,14 @@ struct archive_write {
const void *buff, size_t);
int (*format_close)(struct archive_write *);
int (*format_free)(struct archive_write *);
+
+
+ /*
+ * Encryption passphrase.
+ */
+ char *passphrase;
+ archive_passphrase_callback *passphrase_callback;
+ void *passphrase_client_data;
};
/*
@@ -142,4 +152,9 @@ int __archive_write_program_close(struct archive_write_filter *,
struct archive_write_program_data *);
int __archive_write_program_write(struct archive_write_filter *,
struct archive_write_program_data *, const void *, size_t);
+
+/*
+ * Get a encryption passphrase.
+ */
+const char * __archive_write_get_passphrase(struct archive_write *a);
#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format.c
index 641d56f6c..744302d06 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format.c
@@ -47,6 +47,7 @@ struct { int code; int (*setter)(struct archive *); } codes[] =
{ ARCHIVE_FORMAT_CPIO_SVR4_NOCRC, archive_write_set_format_cpio_newc },
{ ARCHIVE_FORMAT_ISO9660, archive_write_set_format_iso9660 },
{ ARCHIVE_FORMAT_MTREE, archive_write_set_format_mtree },
+ { ARCHIVE_FORMAT_RAW, archive_write_set_format_raw },
{ ARCHIVE_FORMAT_SHAR, archive_write_set_format_shar },
{ ARCHIVE_FORMAT_SHAR_BASE, archive_write_set_format_shar },
{ ARCHIVE_FORMAT_SHAR_DUMP, archive_write_set_format_shar_dump },
@@ -56,8 +57,9 @@ struct { int code; int (*setter)(struct archive *); } codes[] =
{ ARCHIVE_FORMAT_TAR_PAX_RESTRICTED,
archive_write_set_format_pax_restricted },
{ ARCHIVE_FORMAT_TAR_USTAR, archive_write_set_format_ustar },
+ { ARCHIVE_FORMAT_WARC, archive_write_set_format_warc },
{ ARCHIVE_FORMAT_XAR, archive_write_set_format_xar },
- { ARCHIVE_FORMAT_ZIP, archive_write_set_format_zip },
+ { ARCHIVE_FORMAT_ZIP, archive_write_set_format_zip },
{ 0, NULL }
};
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c
index 4f1bc2622..515885422 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c
@@ -34,7 +34,7 @@ __FBSDID("$FreeBSD$");
#include <cm_bzlib.h>
#endif
#if HAVE_LZMA_H
-#include <lzma.h>
+#include <cm_lzma.h>
#endif
#ifdef HAVE_ZLIB_H
#include <cm_zlib.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_by_name.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_by_name.c
index af3105e48..a2ce7c6cd 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_by_name.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_by_name.c
@@ -63,12 +63,14 @@ struct { const char *name; int (*setter)(struct archive *); } names[] =
{ "pax", archive_write_set_format_pax },
{ "paxr", archive_write_set_format_pax_restricted },
{ "posix", archive_write_set_format_pax },
+ { "raw", archive_write_set_format_raw },
{ "rpax", archive_write_set_format_pax_restricted },
{ "shar", archive_write_set_format_shar },
{ "shardump", archive_write_set_format_shar_dump },
{ "ustar", archive_write_set_format_ustar },
{ "v7tar", archive_write_set_format_v7tar },
{ "v7", archive_write_set_format_v7tar },
+ { "warc", archive_write_set_format_warc },
{ "xar", archive_write_set_format_xar },
{ "zip", archive_write_set_format_zip },
{ NULL, NULL }
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_filter_by_ext.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_filter_by_ext.c
new file mode 100644
index 000000000..adec9b265
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_filter_by_ext.c
@@ -0,0 +1,142 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2015 Okhotnikov Kirill
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_by_name.c 201168 2009-12-29 06:15:32Z kientzle $");
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include "archive.h"
+#include "archive_private.h"
+
+/* A table that maps names to functions. */
+static
+struct { const char *name; int (*format)(struct archive *); int (*filter)(struct archive *); } names[] =
+{
+ { ".7z", archive_write_set_format_7zip, archive_write_add_filter_none},
+ { ".zip", archive_write_set_format_zip, archive_write_add_filter_none},
+ { ".jar", archive_write_set_format_zip, archive_write_add_filter_none},
+ { ".cpio", archive_write_set_format_cpio, archive_write_add_filter_none},
+ { ".iso", archive_write_set_format_iso9660, archive_write_add_filter_none},
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
+ { ".a", archive_write_set_format_ar_bsd, archive_write_add_filter_none},
+ { ".ar", archive_write_set_format_ar_bsd, archive_write_add_filter_none},
+#else
+ { ".a", archive_write_set_format_ar_svr4, archive_write_add_filter_none},
+ { ".ar", archive_write_set_format_ar_svr4, archive_write_add_filter_none},
+#endif
+ { ".tar", archive_write_set_format_pax_restricted, archive_write_add_filter_none},
+ { ".tgz", archive_write_set_format_pax_restricted, archive_write_add_filter_gzip},
+ { ".tar.gz", archive_write_set_format_pax_restricted, archive_write_add_filter_gzip},
+ { ".tar.bz2", archive_write_set_format_pax_restricted, archive_write_add_filter_bzip2},
+ { ".tar.xz", archive_write_set_format_pax_restricted, archive_write_add_filter_xz},
+ { NULL, NULL, NULL }
+};
+
+static
+int cmpsuff(const char *str, const char *suffix)
+{
+ size_t length_str, length_suffix;
+
+ if ((str == NULL) || (suffix == NULL))
+ return -1;
+
+ length_str = strlen(str);
+ length_suffix = strlen(suffix);
+
+ if (length_str >= length_suffix) {
+ return strcmp(str + (length_str - length_suffix), suffix);
+ } else {
+ return -1;
+ }
+}
+
+static int get_array_index(const char *name)
+{
+ int i;
+
+ for (i = 0; names[i].name != NULL; i++)
+ {
+ if (cmpsuff(name, names[i].name) == 0)
+ return i;
+ }
+ return -1;
+
+}
+
+int
+archive_write_set_format_filter_by_ext(struct archive *a, const char *filename)
+{
+ int names_index = get_array_index(filename);
+
+ if (names_index >= 0)
+ {
+ int format_state = (names[names_index].format)(a);
+ if (format_state == ARCHIVE_OK)
+ return ((names[names_index].filter)(a));
+ else
+ return format_state;
+ }
+
+ archive_set_error(a, EINVAL, "No such format '%s'", filename);
+ a->state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+}
+
+int
+archive_write_set_format_filter_by_ext_def(struct archive *a, const char *filename, const char * def_ext)
+{
+ int names_index = get_array_index(filename);
+
+ if (names_index < 0)
+ names_index = get_array_index(def_ext);
+
+ if (names_index >= 0)
+ {
+ int format_state = (names[names_index].format)(a);
+ if (format_state == ARCHIVE_OK)
+ return ((names[names_index].filter)(a));
+ else
+ return format_state;
+ }
+
+ archive_set_error(a, EINVAL, "No such format '%s'", filename);
+ a->state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+}
+
+
+
+
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_gnutar.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_gnutar.c
index 13942c132..647079de6 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_gnutar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_gnutar.c
@@ -644,18 +644,18 @@ archive_format_gnutar_header(struct archive_write *a, char h[512],
format_octal(archive_entry_mode(entry) & 07777,
h + GNUTAR_mode_offset, GNUTAR_mode_size);
- /* TODO: How does GNU tar handle large UIDs? */
- if (format_octal(archive_entry_uid(entry),
- h + GNUTAR_uid_offset, GNUTAR_uid_size)) {
+ /* GNU tar supports base-256 here, so should never overflow. */
+ if (format_number(archive_entry_uid(entry), h + GNUTAR_uid_offset,
+ GNUTAR_uid_size, GNUTAR_uid_max_size)) {
archive_set_error(&a->archive, ERANGE,
"Numeric user ID %jd too large",
(intmax_t)archive_entry_uid(entry));
ret = ARCHIVE_FAILED;
}
- /* TODO: How does GNU tar handle large GIDs? */
- if (format_octal(archive_entry_gid(entry),
- h + GNUTAR_gid_offset, GNUTAR_gid_size)) {
+ /* GNU tar supports base-256 here, so should never overflow. */
+ if (format_number(archive_entry_gid(entry), h + GNUTAR_gid_offset,
+ GNUTAR_gid_size, GNUTAR_gid_max_size)) {
archive_set_error(&a->archive, ERANGE,
"Numeric group ID %jd too large",
(intmax_t)archive_entry_gid(entry));
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c
index e7226256b..576f4c29f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c
@@ -2719,6 +2719,16 @@ extra_get_record(struct isoent *isoent, int *space, int *off, int *loc)
rec->offset = 0;
/* Insert `rec` into the tail of isoent->extr_rec_list */
rec->next = NULL;
+ /*
+ * Note: testing isoent->extr_rec_list.last == NULL
+ * here is really unneeded since it has been already
+ * initialized at isoent_new function but Clang Static
+ * Analyzer claims that it is dereference of null
+ * pointer.
+ */
+ if (isoent->extr_rec_list.last == NULL)
+ isoent->extr_rec_list.last =
+ &(isoent->extr_rec_list.first);
*isoent->extr_rec_list.last = rec;
isoent->extr_rec_list.last = &(rec->next);
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c
index 9c0613c9b..b686303d9 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c
@@ -35,7 +35,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_mtree.c 201171
#include <string.h>
#include "archive.h"
-#include "archive_crypto_private.h"
+#include "archive_digest_private.h"
#include "archive_entry.h"
#include "archive_private.h"
#include "archive_rb.h"
@@ -128,6 +128,9 @@ struct mtree_entry {
unsigned long fflags_clear;
dev_t rdevmajor;
dev_t rdevminor;
+ dev_t devmajor;
+ dev_t devminor;
+ int64_t ino;
};
struct mtree_writer {
@@ -210,6 +213,9 @@ struct mtree_writer {
#define F_SHA256 0x00800000 /* SHA-256 digest */
#define F_SHA384 0x01000000 /* SHA-384 digest */
#define F_SHA512 0x02000000 /* SHA-512 digest */
+#define F_INO 0x04000000 /* inode number */
+#define F_RESDEV 0x08000000 /* device ID on which the
+ * entry resides */
/* Options */
int dironly; /* If it is set, ignore all files except
@@ -633,7 +639,7 @@ attr_counter_inc(struct attr_counter **top, struct attr_counter *ac,
*top = ac;
ac->next->prev = ac;
}
- } else {
+ } else if (last != NULL) {
ac = attr_counter_new(me, last);
if (ac == NULL)
return (-1);
@@ -823,8 +829,11 @@ mtree_entry_new(struct archive_write *a, struct archive_entry *entry,
archive_entry_fflags(entry, &me->fflags_set, &me->fflags_clear);
me->mtime = archive_entry_mtime(entry);
me->mtime_nsec = archive_entry_mtime_nsec(entry);
- me->rdevmajor = archive_entry_rdevmajor(entry);
+ me->rdevmajor = archive_entry_rdevmajor(entry);
me->rdevminor = archive_entry_rdevminor(entry);
+ me->devmajor = archive_entry_devmajor(entry);
+ me->devminor = archive_entry_devminor(entry);
+ me->ino = archive_entry_ino(entry);
me->size = archive_entry_size(entry);
if (me->filetype == AE_IFDIR) {
me->dir_info = calloc(1, sizeof(*me->dir_info));
@@ -882,7 +891,7 @@ archive_write_mtree_header(struct archive_write *a,
mtree->first = 0;
archive_strcat(&mtree->buf, "#mtree\n");
if ((mtree->keys & SET_KEYS) == 0)
- mtree->output_global_set = 0;/* Disalbed. */
+ mtree->output_global_set = 0;/* Disabled. */
}
mtree->entry_bytes_remaining = archive_entry_size(entry);
@@ -983,6 +992,15 @@ write_mtree_entry(struct archive_write *a, struct mtree_entry *me)
if ((keys & F_UID) != 0)
archive_string_sprintf(str, " uid=%jd", (intmax_t)me->uid);
+ if ((keys & F_INO) != 0)
+ archive_string_sprintf(str, " inode=%jd", (intmax_t)me->ino);
+ if ((keys & F_RESDEV) != 0) {
+ archive_string_sprintf(str,
+ " resdevice=native,%ju,%ju",
+ (uintmax_t)me->devmajor,
+ (uintmax_t)me->devminor);
+ }
+
switch (me->filetype) {
case AE_IFLNK:
if ((keys & F_TYPE) != 0)
@@ -1097,7 +1115,7 @@ write_mtree_entry_tree(struct archive_write *a)
do {
if (mtree->output_global_set) {
/*
- * Collect attribute infomation to know which value
+ * Collect attribute information to know which value
* is frequently used among the children.
*/
attr_counter_set_reset(mtree);
@@ -1117,7 +1135,7 @@ write_mtree_entry_tree(struct archive_write *a)
} else {
/* Whenever output_global_set is enabled
* output global value(/set keywords)
- * even if the directory entry is not allowd
+ * even if the directory entry is not allowed
* to be written because the global values
* can be used for the children. */
if (mtree->output_global_set)
@@ -1296,6 +1314,8 @@ archive_write_mtree_options(struct archive_write *a, const char *key,
if (strcmp(key, "indent") == 0) {
mtree->indent = (value != NULL)? 1: 0;
return (ARCHIVE_OK);
+ } else if (strcmp(key, "inode") == 0) {
+ keybit = F_INO;
}
break;
case 'l':
@@ -1314,7 +1334,9 @@ archive_write_mtree_options(struct archive_write *a, const char *key,
keybit = F_NLINK;
break;
case 'r':
- if (strcmp(key, "ripemd160digest") == 0 ||
+ if (strcmp(key, "resdevice") == 0) {
+ keybit = F_RESDEV;
+ } else if (strcmp(key, "ripemd160digest") == 0 ||
strcmp(key, "rmd160") == 0 ||
strcmp(key, "rmd160digest") == 0)
keybit = F_RMD160;
@@ -1855,9 +1877,9 @@ mtree_entry_setup_filenames(struct archive_write *a, struct mtree_entry *file,
return (ret);
}
- /* Make a basename from dirname and slash */
+ /* Make a basename from file->parentdir.s and slash */
*slash = '\0';
- file->parentdir.length = slash - dirname;
+ file->parentdir.length = slash - file->parentdir.s;
archive_strcpy(&(file->basename), slash + 1);
return (ret);
}
@@ -2198,6 +2220,9 @@ mtree_entry_exchange_same_entry(struct archive_write *a, struct mtree_entry *np,
np->mtime_nsec = file->mtime_nsec;
np->rdevmajor = file->rdevmajor;
np->rdevminor = file->rdevminor;
+ np->devmajor = file->devmajor;
+ np->devminor = file->devminor;
+ np->ino = file->ino;
return (ARCHIVE_WARN);
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_raw.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_raw.c
new file mode 100644
index 000000000..feff93697
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_raw.c
@@ -0,0 +1,125 @@
+/*-
+ * Copyright (c) 2013 Marek Kubica
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include "archive_entry.h"
+#include "archive_write_private.h"
+
+static ssize_t archive_write_raw_data(struct archive_write *,
+ const void *buff, size_t s);
+static int archive_write_raw_free(struct archive_write *);
+static int archive_write_raw_header(struct archive_write *,
+ struct archive_entry *);
+
+struct raw {
+ int entries_written;
+};
+
+/*
+ * Set output format to 'raw' format.
+ */
+int
+archive_write_set_format_raw(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct raw *raw;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_raw");
+
+ /* If someone else was already registered, unregister them. */
+ if (a->format_free != NULL)
+ (a->format_free)(a);
+
+ raw = (struct raw *)calloc(1, sizeof(*raw));
+ if (raw == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Can't allocate raw data");
+ return (ARCHIVE_FATAL);
+ }
+ raw->entries_written = 0;
+ a->format_data = raw;
+ a->format_name = "raw";
+ /* no options exist for this format */
+ a->format_options = NULL;
+ a->format_write_header = archive_write_raw_header;
+ a->format_write_data = archive_write_raw_data;
+ a->format_finish_entry = NULL;
+ /* nothing needs to be done on closing */
+ a->format_close = NULL;
+ a->format_free = archive_write_raw_free;
+ a->archive.archive_format = ARCHIVE_FORMAT_RAW;
+ a->archive.archive_format_name = "RAW";
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_raw_header(struct archive_write *a, struct archive_entry *entry)
+{
+ struct raw *raw = (struct raw *)a->format_data;
+
+ if (archive_entry_filetype(entry) != AE_IFREG) {
+ archive_set_error(&a->archive, ERANGE,
+ "Raw format only supports filetype AE_IFREG");
+ return (ARCHIVE_FATAL);
+ }
+
+
+ if (raw->entries_written > 0) {
+ archive_set_error(&a->archive, ERANGE,
+ "Raw format only supports one entry per archive");
+ return (ARCHIVE_FATAL);
+ }
+ raw->entries_written++;
+
+ return (ARCHIVE_OK);
+}
+
+static ssize_t
+archive_write_raw_data(struct archive_write *a, const void *buff, size_t s)
+{
+ int ret;
+
+ ret = __archive_write_output(a, buff, s);
+ if (ret >= 0)
+ return (s);
+ else
+ return (ret);
+}
+
+static int
+archive_write_raw_free(struct archive_write *a)
+{
+ struct raw *raw;
+
+ raw = (struct raw *)a->format_data;
+ free(raw);
+ a->format_data = NULL;
+ return (ARCHIVE_OK);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_shar.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_shar.c
index 9ec15f915..c033fb32f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_shar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_shar.c
@@ -548,6 +548,7 @@ archive_write_shar_finish_entry(struct archive_write *a)
archive_strcat(&shar->work, ":");
shar_quote(&shar->work, g, 1);
}
+ archive_strcat(&shar->work, " ");
shar_quote(&shar->work,
archive_entry_pathname(shar->entry), 1);
archive_strcat(&shar->work, "\n");
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_warc.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_warc.c
new file mode 100644
index 000000000..80abc6f4e
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_warc.c
@@ -0,0 +1,439 @@
+/*-
+ * Copyright (c) 2014 Sebastian Freundt
+ * Author: Sebastian Freundt <devel@fresse.org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_private.h"
+#include "archive_random_private.h"
+#include "archive_write_private.h"
+
+struct warc_s {
+ unsigned int omit_warcinfo:1;
+
+ time_t now;
+ mode_t typ;
+ unsigned int rng;
+ /* populated size */
+ uint64_t populz;
+};
+
+static const char warcinfo[] =
+ "software: libarchive/" ARCHIVE_VERSION_ONLY_STRING "\r\n"
+ "format: WARC file version 1.0\r\n";
+
+typedef enum {
+ WT_NONE,
+ /* warcinfo */
+ WT_INFO,
+ /* metadata */
+ WT_META,
+ /* resource */
+ WT_RSRC,
+ /* request, unsupported */
+ WT_REQ,
+ /* response, unsupported */
+ WT_RSP,
+ /* revisit, unsupported */
+ WT_RVIS,
+ /* conversion, unsupported */
+ WT_CONV,
+ /* continutation, unsupported at the moment */
+ WT_CONT,
+ /* invalid type */
+ LAST_WT
+} warc_type_t;
+
+typedef struct {
+ warc_type_t type;
+ const char *tgturi;
+ const char *recid;
+ time_t rtime;
+ time_t mtime;
+ const char *cnttyp;
+ uint64_t cntlen;
+} warc_essential_hdr_t;
+
+typedef struct {
+ unsigned int u[4U];
+} warc_uuid_t;
+
+static int _warc_options(struct archive_write*, const char *key, const char *v);
+static int _warc_header(struct archive_write *a, struct archive_entry *entry);
+static ssize_t _warc_data(struct archive_write *a, const void *buf, size_t sz);
+static int _warc_finish_entry(struct archive_write *a);
+static int _warc_close(struct archive_write *a);
+static int _warc_free(struct archive_write *a);
+
+/* private routines */
+static ssize_t _popul_ehdr(struct archive_string *t, size_t z, warc_essential_hdr_t);
+static int _gen_uuid(warc_uuid_t *tgt);
+
+
+/*
+ * Set output format to ISO 28500 (aka WARC) format.
+ */
+int
+archive_write_set_format_warc(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct warc_s *w;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_warc");
+
+ /* If another format was already registered, unregister it. */
+ if (a->format_free != NULL) {
+ (a->format_free)(a);
+ }
+
+ w = malloc(sizeof(*w));
+ if (w == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate warc data");
+ return (ARCHIVE_FATAL);
+ }
+ /* by default we're emitting a file wide header */
+ w->omit_warcinfo = 0U;
+ /* obtain current time for date fields */
+ w->now = time(NULL);
+ /* reset file type info */
+ w->typ = 0;
+ /* also initialise our rng */
+ w->rng = (unsigned int)w->now;
+
+ a->format_data = w;
+ a->format_name = "WARC/1.0";
+ a->format_options = _warc_options;
+ a->format_write_header = _warc_header;
+ a->format_write_data = _warc_data;
+ a->format_close = _warc_close;
+ a->format_free = _warc_free;
+ a->format_finish_entry = _warc_finish_entry;
+ a->archive.archive_format = ARCHIVE_FORMAT_WARC;
+ a->archive.archive_format_name = "WARC/1.0";
+ return (ARCHIVE_OK);
+}
+
+
+/* archive methods */
+static int
+_warc_options(struct archive_write *a, const char *key, const char *val)
+{
+ struct warc_s *w = a->format_data;
+
+ if (strcmp(key, "omit-warcinfo") == 0) {
+ if (val == NULL || strcmp(val, "true") == 0) {
+ /* great */
+ w->omit_warcinfo = 1U;
+ return (ARCHIVE_OK);
+ }
+ }
+
+ /* Note: The "warn" return is just to inform the options
+ * supervisor that we didn't handle it. It will generate
+ * a suitable error if no one used this option. */
+ return (ARCHIVE_WARN);
+}
+
+static int
+_warc_header(struct archive_write *a, struct archive_entry *entry)
+{
+ struct warc_s *w = a->format_data;
+ struct archive_string hdr;
+#define MAX_HDR_SIZE 512
+
+ /* check whether warcinfo record needs outputting */
+ if (!w->omit_warcinfo) {
+ warc_essential_hdr_t wi = {
+ WT_INFO,
+ /*uri*/NULL,
+ /*urn*/NULL,
+ /*rtm*/w->now,
+ /*mtm*/w->now,
+ /*cty*/"application/warc-fields",
+ /*len*/sizeof(warcinfo) - 1U,
+ };
+ ssize_t r;
+
+ archive_string_init(&hdr);
+ r = _popul_ehdr(&hdr, MAX_HDR_SIZE, wi);
+ if (r >= 0) {
+ /* jackpot! */
+ /* now also use HDR buffer for the actual warcinfo */
+ archive_strncat(&hdr, warcinfo, sizeof(warcinfo) -1);
+
+ /* append end-of-record indicator */
+ archive_strncat(&hdr, "\r\n\r\n", 4);
+
+ /* write to output stream */
+ __archive_write_output(a, hdr.s, archive_strlen(&hdr));
+ }
+ /* indicate we're done with file header writing */
+ w->omit_warcinfo = 1U;
+ archive_string_free(&hdr);
+ }
+
+ if (archive_entry_pathname(entry) == NULL) {
+ archive_set_error(&a->archive, EINVAL,
+ "Invalid filename");
+ return (ARCHIVE_WARN);
+ }
+
+ w->typ = archive_entry_filetype(entry);
+ w->populz = 0U;
+ if (w->typ == AE_IFREG) {
+ warc_essential_hdr_t rh = {
+ WT_RSRC,
+ /*uri*/archive_entry_pathname(entry),
+ /*urn*/NULL,
+ /*rtm*/w->now,
+ /*mtm*/archive_entry_mtime(entry),
+ /*cty*/NULL,
+ /*len*/(size_t)archive_entry_size(entry),
+ };
+ ssize_t r;
+
+ archive_string_init(&hdr);
+ r = _popul_ehdr(&hdr, MAX_HDR_SIZE, rh);
+ if (r < 0) {
+ /* don't bother */
+ archive_set_error(
+ &a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "cannot archive file");
+ return (ARCHIVE_WARN);
+ }
+ /* otherwise append to output stream */
+ __archive_write_output(a, hdr.s, r);
+ /* and let subsequent calls to _data() know about the size */
+ w->populz = rh.cntlen;
+ archive_string_free(&hdr);
+ return (ARCHIVE_OK);
+ }
+ /* just resort to erroring as per Tim's advice */
+ archive_set_error(
+ &a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "WARC can only process regular files");
+ return (ARCHIVE_FAILED);
+}
+
+static ssize_t
+_warc_data(struct archive_write *a, const void *buf, size_t len)
+{
+ struct warc_s *w = a->format_data;
+
+ if (w->typ == AE_IFREG) {
+ int rc;
+
+ /* never write more bytes than announced */
+ if (len > w->populz) {
+ len = (size_t)w->populz;
+ }
+
+ /* now then, out we put the whole shebang */
+ rc = __archive_write_output(a, buf, len);
+ if (rc != ARCHIVE_OK) {
+ return rc;
+ }
+ }
+ return len;
+}
+
+static int
+_warc_finish_entry(struct archive_write *a)
+{
+ static const char _eor[] = "\r\n\r\n";
+ struct warc_s *w = a->format_data;
+
+ if (w->typ == AE_IFREG) {
+ int rc = __archive_write_output(a, _eor, sizeof(_eor) - 1U);
+
+ if (rc != ARCHIVE_OK) {
+ return rc;
+ }
+ }
+ /* reset type info */
+ w->typ = 0;
+ return (ARCHIVE_OK);
+}
+
+static int
+_warc_close(struct archive_write *a)
+{
+ (void)a; /* UNUSED */
+ return (ARCHIVE_OK);
+}
+
+static int
+_warc_free(struct archive_write *a)
+{
+ struct warc_s *w = a->format_data;
+
+ free(w);
+ a->format_data = NULL;
+ return (ARCHIVE_OK);
+}
+
+
+/* private routines */
+static void
+xstrftime(struct archive_string *as, const char *fmt, time_t t)
+{
+/** like strftime(3) but for time_t objects */
+ struct tm *rt;
+#if defined(HAVE_GMTIME_R) || defined(HAVE__GMTIME64_S)
+ struct tm time;
+#endif
+ char strtime[100];
+ size_t len;
+
+#ifdef HAVE_GMTIME_R
+ if ((rt = gmtime_r(&t, &time)) == NULL)
+ return;
+#elif defined(HAVE__GMTIME64_S)
+ _gmtime64_s(&time, &t);
+#else
+ if ((rt = gmtime(&t)) == NULL)
+ return;
+#endif
+ /* leave the hard yacker to our role model strftime() */
+ len = strftime(strtime, sizeof(strtime)-1, fmt, rt);
+ archive_strncat(as, strtime, len);
+}
+
+static ssize_t
+_popul_ehdr(struct archive_string *tgt, size_t tsz, warc_essential_hdr_t hdr)
+{
+ static const char _ver[] = "WARC/1.0\r\n";
+ static const char *_typ[LAST_WT] = {
+ NULL, "warcinfo", "metadata", "resource", NULL
+ };
+ char std_uuid[48U];
+
+ if (hdr.type == WT_NONE || hdr.type > WT_RSRC) {
+ /* brilliant, how exactly did we get here? */
+ return -1;
+ }
+
+ archive_strcpy(tgt, _ver);
+
+ archive_string_sprintf(tgt, "WARC-Type: %s\r\n", _typ[hdr.type]);
+
+ if (hdr.tgturi != NULL) {
+ /* check if there's a xyz:// */
+ static const char _uri[] = "";
+ static const char _fil[] = "file://";
+ const char *u;
+ char *chk = strchr(hdr.tgturi, ':');
+
+ if (chk != NULL && chk[1U] == '/' && chk[2U] == '/') {
+ /* yep, it's definitely a URI */
+ u = _uri;
+ } else {
+ /* hm, best to prepend file:// then */
+ u = _fil;
+ }
+ archive_string_sprintf(tgt,
+ "WARC-Target-URI: %s%s\r\n", u, hdr.tgturi);
+ }
+
+ /* record time is usually when the http is sent off,
+ * just treat the archive writing as such for a moment */
+ xstrftime(tgt, "WARC-Date: %Y-%m-%dT%H:%M:%SZ\r\n", hdr.rtime);
+
+ /* while we're at it, record the mtime */
+ xstrftime(tgt, "Last-Modified: %Y-%m-%dT%H:%M:%SZ\r\n", hdr.mtime);
+
+ if (hdr.recid == NULL) {
+ /* generate one, grrrr */
+ warc_uuid_t u;
+
+ _gen_uuid(&u);
+ /* Unfortunately, archive_string_sprintf does not
+ * handle the minimum number following '%'.
+ * So we have to use snprintf function here instead
+ * of archive_string_snprintf function. */
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#define snprintf _snprintf
+#endif
+ snprintf(
+ std_uuid, sizeof(std_uuid),
+ "<urn:uuid:%08x-%04x-%04x-%04x-%04x%08x>",
+ u.u[0U],
+ u.u[1U] >> 16U, u.u[1U] & 0xffffU,
+ u.u[2U] >> 16U, u.u[2U] & 0xffffU,
+ u.u[3U]);
+ hdr.recid = std_uuid;
+ }
+
+ /* record-id is mandatory, fingers crossed we won't fail */
+ archive_string_sprintf(tgt, "WARC-Record-ID: %s\r\n", hdr.recid);
+
+ if (hdr.cnttyp != NULL) {
+ archive_string_sprintf(tgt, "Content-Type: %s\r\n", hdr.cnttyp);
+ }
+
+ /* next one is mandatory */
+ archive_string_sprintf(tgt, "Content-Length: %ju\r\n", (uintmax_t)hdr.cntlen);
+ /**/
+ archive_strncat(tgt, "\r\n", 2);
+
+ return (archive_strlen(tgt) >= tsz)? -1: (ssize_t)archive_strlen(tgt);
+}
+
+static int
+_gen_uuid(warc_uuid_t *tgt)
+{
+ archive_random(tgt->u, sizeof(tgt->u));
+ /* obey uuid version 4 rules */
+ tgt->u[1U] &= 0xffff0fffU;
+ tgt->u[1U] |= 0x4000U;
+ tgt->u[2U] &= 0x3fffffffU;
+ tgt->u[2U] |= 0x80000000U;
+ return 0;
+}
+
+/* archive_write_set_format_warc.c ends here */
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c
index a4ce7ee6f..a47c53c0a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c
@@ -40,14 +40,14 @@ __FBSDID("$FreeBSD$");
#include <cm_bzlib.h>
#endif
#if HAVE_LZMA_H
-#include <lzma.h>
+#include <cm_lzma.h>
#endif
#ifdef HAVE_ZLIB_H
#include <cm_zlib.h>
#endif
#include "archive.h"
-#include "archive_crypto_private.h"
+#include "archive_digest_private.h"
#include "archive_endian.h"
#include "archive_entry.h"
#include "archive_entry_locale.h"
@@ -114,7 +114,7 @@ enum sumalg {
#define MAX_SUM_SIZE 20
#define MD5_NAME "md5"
#define SHA1_NAME "sha1"
-
+
enum enctype {
NONE,
GZIP,
@@ -242,6 +242,7 @@ struct xar {
enum sumalg opt_sumalg;
enum enctype opt_compression;
int opt_compression_level;
+ uint32_t opt_threads;
struct chksumwork a_sumwrk; /* archived checksum. */
struct chksumwork e_sumwrk; /* extracted checksum. */
@@ -317,7 +318,7 @@ static int compression_end_bzip2(struct archive *, struct la_zstream *);
static int compression_init_encoder_lzma(struct archive *,
struct la_zstream *, int);
static int compression_init_encoder_xz(struct archive *,
- struct la_zstream *, int);
+ struct la_zstream *, int, int);
#if defined(HAVE_LZMA_H)
static int compression_code_lzma(struct archive *,
struct la_zstream *, enum la_zaction);
@@ -380,9 +381,10 @@ archive_write_set_format_xar(struct archive *_a)
/* Set default checksum type. */
xar->opt_toc_sumalg = CKSUM_SHA1;
xar->opt_sumalg = CKSUM_SHA1;
- /* Set default compression type and level. */
+ /* Set default compression type, level, and number of threads. */
xar->opt_compression = GZIP;
xar->opt_compression_level = 6;
+ xar->opt_threads = 1;
a->format_data = xar;
@@ -493,6 +495,26 @@ xar_options(struct archive_write *a, const char *key, const char *value)
}
return (ARCHIVE_OK);
}
+ if (strcmp(key, "threads") == 0) {
+ if (value == NULL)
+ return (ARCHIVE_FAILED);
+ xar->opt_threads = (int)strtoul(value, NULL, 10);
+ if (xar->opt_threads == 0 && errno != 0) {
+ xar->opt_threads = 1;
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Illegal value `%s'",
+ value);
+ return (ARCHIVE_FAILED);
+ }
+ if (xar->opt_threads == 0) {
+#ifdef HAVE_LZMA_STREAM_ENCODER_MT
+ xar->opt_threads = lzma_cputhreads();
+#else
+ xar->opt_threads = 1;
+#endif
+ }
+ }
/* Note: The "warn" return is just to inform the options
* supervisor that we didn't handle it. It will generate
@@ -805,7 +827,7 @@ xmlwrite_string(struct archive_write *a, xmlTextWriterPtr writer,
if (value == NULL)
return (ARCHIVE_OK);
-
+
r = xmlTextWriterStartElement(writer, BAD_CAST_CONST(key));
if (r < 0) {
archive_set_error(&a->archive,
@@ -1875,7 +1897,7 @@ file_cmp_node(const struct archive_rb_node *n1,
return (strcmp(f1->basename.s, f2->basename.s));
}
-
+
static int
file_cmp_key(const struct archive_rb_node *n, const void *key)
{
@@ -2154,7 +2176,7 @@ file_gen_utility_names(struct archive_write *a, struct file *file)
file->parentdir.length = len;
archive_string_copy(&(file->basename), &(file->parentdir));
archive_string_empty(&(file->parentdir));
- file->parentdir.s = '\0';
+ *file->parentdir.s = '\0';
return (r);
}
@@ -2494,7 +2516,7 @@ file_init_hardlinks(struct xar *xar)
static const struct archive_rb_tree_ops rb_ops = {
file_hd_cmp_node, file_hd_cmp_key,
};
-
+
__archive_rb_tree_init(&(xar->hardlink_rbtree), &rb_ops);
}
@@ -2848,13 +2870,18 @@ compression_init_encoder_lzma(struct archive *a,
static int
compression_init_encoder_xz(struct archive *a,
- struct la_zstream *lastrm, int level)
+ struct la_zstream *lastrm, int level, int threads)
{
static const lzma_stream lzma_init_data = LZMA_STREAM_INIT;
lzma_stream *strm;
lzma_filter *lzmafilters;
lzma_options_lzma lzma_opt;
int r;
+#ifdef HAVE_LZMA_STREAM_ENCODER_MT
+ lzma_mt mt_options;
+#endif
+
+ (void)threads; /* UNUSED (if multi-threaded LZMA library not avail) */
if (lastrm->valid)
compression_end(a, lastrm);
@@ -2879,7 +2906,17 @@ compression_init_encoder_xz(struct archive *a,
lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */
*strm = lzma_init_data;
- r = lzma_stream_encoder(strm, lzmafilters, LZMA_CHECK_CRC64);
+#ifdef HAVE_LZMA_STREAM_ENCODER_MT
+ if (threads > 1) {
+ bzero(&mt_options, sizeof(mt_options));
+ mt_options.threads = threads;
+ mt_options.timeout = 300;
+ mt_options.filters = lzmafilters;
+ mt_options.check = LZMA_CHECK_CRC64;
+ r = lzma_stream_encoder_mt(strm, &mt_options);
+ } else
+#endif
+ r = lzma_stream_encoder(strm, lzmafilters, LZMA_CHECK_CRC64);
switch (r) {
case LZMA_OK:
lastrm->real_stream = strm;
@@ -2979,10 +3016,11 @@ compression_init_encoder_lzma(struct archive *a,
}
static int
compression_init_encoder_xz(struct archive *a,
- struct la_zstream *lastrm, int level)
+ struct la_zstream *lastrm, int level, int threads)
{
(void) level; /* UNUSED */
+ (void) threads; /* UNUSED */
if (lastrm->valid)
compression_end(a, lastrm);
return (compression_unsupported_encoder(a, lastrm, "xz"));
@@ -3015,7 +3053,7 @@ xar_compression_init_encoder(struct archive_write *a)
case XZ:
r = compression_init_encoder_xz(
&(a->archive), &(xar->stream),
- xar->opt_compression_level);
+ xar->opt_compression_level, xar->opt_threads);
break;
default:
r = ARCHIVE_OK;
@@ -3178,4 +3216,3 @@ getalgname(enum sumalg sumalg)
}
#endif /* Support xar format */
-
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c
index 5a9f114f0..0636f46f5 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c
@@ -1,7 +1,7 @@
/*-
* Copyright (c) 2008 Anselm Strauss
* Copyright (c) 2009 Joerg Sonnenberger
- * Copyright (c) 2011-2012 Michihiro NAKAJIMA
+ * Copyright (c) 2011-2012,2014 Michihiro NAKAJIMA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,24 +29,6 @@
* Development supported by Google Summer of Code 2008.
*/
-/*
- * The current implementation is very limited:
- *
- * - No encryption support.
- * - No ZIP64 support.
- * - No support for splitting and spanning.
- * - Only supports regular file and folder entries.
- *
- * Note that generally data in ZIP files is little-endian encoded,
- * with some exceptions.
- *
- * TODO: Since Libarchive is generally 64bit oriented, but this implementation
- * does not yet support sizes exceeding 32bit, it is highly fragile for
- * big archives. This should change when ZIP64 is finally implemented, otherwise
- * some serious checking has to be done.
- *
- */
-
#include "archive_platform.h"
__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_zip.c 201168 2009-12-29 06:15:32Z kientzle $");
@@ -67,35 +49,130 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_zip.c 201168 20
#endif
#include "archive.h"
+#include "archive_cryptor_private.h"
#include "archive_endian.h"
#include "archive_entry.h"
#include "archive_entry_locale.h"
+#include "archive_hmac_private.h"
#include "archive_private.h"
+#include "archive_random_private.h"
#include "archive_write_private.h"
#ifndef HAVE_ZLIB_H
#include "archive_crc32.h"
#endif
-#define ZIP_SIGNATURE_LOCAL_FILE_HEADER 0x04034b50
-#define ZIP_SIGNATURE_DATA_DESCRIPTOR 0x08074b50
-#define ZIP_SIGNATURE_FILE_HEADER 0x02014b50
-#define ZIP_SIGNATURE_CENTRAL_DIRECTORY_END 0x06054b50
-#define ZIP_SIGNATURE_EXTRA_TIMESTAMP 0x5455
-#define ZIP_SIGNATURE_EXTRA_NEW_UNIX 0x7875
-#define ZIP_VERSION_EXTRACT 0x0014 /* ZIP version 2.0 is needed. */
-#define ZIP_VERSION_BY 0x0314 /* Made by UNIX, using ZIP version 2.0. */
-#define ZIP_FLAGS 0x08 /* Flagging bit 3 (count from 0) for using data descriptor. */
-#define ZIP_FLAGS_UTF8_NAME (1 << 11)
+#define ZIP_ENTRY_FLAG_ENCRYPTED (1<<0)
+#define ZIP_ENTRY_FLAG_LENGTH_AT_END (1<<3)
+#define ZIP_ENTRY_FLAG_UTF8_NAME (1 << 11)
enum compression {
- COMPRESSION_STORE = 0
-#ifdef HAVE_ZLIB_H
- ,
+ COMPRESSION_UNSPECIFIED = -1,
+ COMPRESSION_STORE = 0,
COMPRESSION_DEFLATE = 8
+};
+
+#ifdef HAVE_ZLIB_H
+#define COMPRESSION_DEFAULT COMPRESSION_DEFLATE
+#else
+#define COMPRESSION_DEFAULT COMPRESSION_STORE
#endif
+
+enum encryption {
+ ENCRYPTION_NONE = 0,
+ ENCRYPTION_TRADITIONAL, /* Traditional PKWARE encryption. */
+ ENCRYPTION_WINZIP_AES128, /* WinZIP AES-128 encryption. */
+ ENCRYPTION_WINZIP_AES256, /* WinZIP AES-256 encryption. */
};
+#define TRAD_HEADER_SIZE 12
+/*
+ * See "WinZip - AES Encryption Information"
+ * http://www.winzip.com/aes_info.htm
+ */
+/* Value used in compression method. */
+#define WINZIP_AES_ENCRYPTION 99
+/* A WinZip AES header size which is stored at the beginning of
+ * file contents. */
+#define WINZIP_AES128_HEADER_SIZE (8 + 2)
+#define WINZIP_AES256_HEADER_SIZE (16 + 2)
+/* AES vendor version. */
+#define AES_VENDOR_AE_1 0x0001
+#define AES_VENDOR_AE_2 0x0002
+/* Authentication code size. */
+#define AUTH_CODE_SIZE 10
+/**/
+#define MAX_DERIVED_KEY_BUF_SIZE (AES_MAX_KEY_SIZE * 2 + 2)
+
+struct cd_segment {
+ struct cd_segment *next;
+ size_t buff_size;
+ unsigned char *buff;
+ unsigned char *p;
+};
+
+struct trad_enc_ctx {
+ uint32_t keys[3];
+};
+
+struct zip {
+
+ int64_t entry_offset;
+ int64_t entry_compressed_size;
+ int64_t entry_uncompressed_size;
+ int64_t entry_compressed_written;
+ int64_t entry_uncompressed_written;
+ int64_t entry_uncompressed_limit;
+ struct archive_entry *entry;
+ uint32_t entry_crc32;
+ enum compression entry_compression;
+ enum encryption entry_encryption;
+ int entry_flags;
+ int entry_uses_zip64;
+ int experiments;
+ struct trad_enc_ctx tctx;
+ char tctx_valid;
+ unsigned char trad_chkdat;
+ unsigned aes_vendor;
+ archive_crypto_ctx cctx;
+ char cctx_valid;
+ archive_hmac_sha1_ctx hctx;
+ char hctx_valid;
+
+ unsigned char *file_header;
+ size_t file_header_extra_offset;
+ unsigned long (*crc32func)(unsigned long crc, const void *buff, size_t len);
+
+ struct cd_segment *central_directory;
+ struct cd_segment *central_directory_last;
+ size_t central_directory_bytes;
+ size_t central_directory_entries;
+
+ int64_t written_bytes; /* Overall position in file. */
+
+ struct archive_string_conv *opt_sconv;
+ struct archive_string_conv *sconv_default;
+ enum compression requested_compression;
+ int deflate_compression_level;
+ int init_default_conversion;
+ enum encryption encryption_type;
+
+#define ZIP_FLAG_AVOID_ZIP64 1
+#define ZIP_FLAG_FORCE_ZIP64 2
+#define ZIP_FLAG_EXPERIMENT_xl 4
+ int flags;
+
+#ifdef HAVE_ZLIB_H
+ z_stream stream;
+#endif
+ size_t len_buf;
+ unsigned char *buf;
+};
+
+/* Don't call this min or MIN, since those are already defined
+ on lots of platforms (but not all). */
+#define zipmin(a, b) ((a) > (b) ? (b) : (a))
+
static ssize_t archive_write_zip_data(struct archive_write *,
const void *buff, size_t s);
static int archive_write_zip_close(struct archive_write *);
@@ -108,106 +185,65 @@ static int archive_write_zip_options(struct archive_write *,
static unsigned int dos_time(const time_t);
static size_t path_length(struct archive_entry *);
static int write_path(struct archive_entry *, struct archive_write *);
+static void copy_path(struct archive_entry *, unsigned char *);
+static struct archive_string_conv *get_sconv(struct archive_write *, struct zip *);
+static int trad_enc_init(struct trad_enc_ctx *, const char *, size_t);
+static unsigned trad_enc_encrypt_update(struct trad_enc_ctx *, const uint8_t *,
+ size_t, uint8_t *, size_t);
+static int init_traditional_pkware_encryption(struct archive_write *);
+static int is_traditional_pkware_encryption_supported(void);
+static int init_winzip_aes_encryption(struct archive_write *);
+static int is_winzip_aes_encryption_supported(int encryption);
+
+static unsigned char *
+cd_alloc(struct zip *zip, size_t length)
+{
+ unsigned char *p;
+
+ if (zip->central_directory == NULL
+ || (zip->central_directory_last->p + length
+ > zip->central_directory_last->buff + zip->central_directory_last->buff_size)) {
+ struct cd_segment *segment = calloc(1, sizeof(*segment));
+ if (segment == NULL)
+ return NULL;
+ segment->buff_size = 64 * 1024;
+ segment->buff = malloc(segment->buff_size);
+ if (segment->buff == NULL) {
+ free(segment);
+ return NULL;
+ }
+ segment->p = segment->buff;
-#define LOCAL_FILE_HEADER_SIGNATURE 0
-#define LOCAL_FILE_HEADER_VERSION 4
-#define LOCAL_FILE_HEADER_FLAGS 6
-#define LOCAL_FILE_HEADER_COMPRESSION 8
-#define LOCAL_FILE_HEADER_TIMEDATE 10
-#define LOCAL_FILE_HEADER_CRC32 14
-#define LOCAL_FILE_HEADER_COMPRESSED_SIZE 18
-#define LOCAL_FILE_HEADER_UNCOMPRESSED_SIZE 22
-#define LOCAL_FILE_HEADER_FILENAME_LENGTH 26
-#define LOCAL_FILE_HEADER_EXTRA_LENGTH 28
-#define SIZE_LOCAL_FILE_HEADER 30
-
-#define FILE_HEADER_SIGNATURE 0
-#define FILE_HEADER_VERSION_BY 4
-#define FILE_HEADER_VERSION_EXTRACT 6
-#define FILE_HEADER_FLAGS 8
-#define FILE_HEADER_COMPRESSION 10
-#define FILE_HEADER_TIMEDATE 12
-#define FILE_HEADER_CRC32 16
-#define FILE_HEADER_COMPRESSED_SIZE 20
-#define FILE_HEADER_UNCOMPRESSED_SIZE 24
-#define FILE_HEADER_FILENAME_LENGTH 28
-#define FILE_HEADER_EXTRA_LENGTH 30
-#define FILE_HEADER_COMMENT_LENGTH 32
-#define FILE_HEADER_DISK_NUMBER 34
-#define FILE_HEADER_ATTRIBUTES_INTERNAL 36
-#define FILE_HEADER_ATTRIBUTES_EXTERNAL 38
-#define FILE_HEADER_OFFSET 42
-#define SIZE_FILE_HEADER 46
-
- /* Not mandatory, but recommended by specification. */
-#define DATA_DESCRIPTOR_SIGNATURE 0
-#define DATA_DESCRIPTOR_CRC32 4
-#define DATA_DESCRIPTOR_COMPRESSED_SIZE 8
-#define DATA_DESCRIPTOR_UNCOMPRESSED_SIZE 12
-#define SIZE_DATA_DESCRIPTOR 16
-
-#define EXTRA_DATA_LOCAL_TIME_ID 0
-#define EXTRA_DATA_LOCAL_TIME_SIZE 2
-#define EXTRA_DATA_LOCAL_TIME_FLAG 4
-#define EXTRA_DATA_LOCAL_MTIME 5
-#define EXTRA_DATA_LOCAL_ATIME 9
-#define EXTRA_DATA_LOCAL_CTIME 13
-#define EXTRA_DATA_LOCAL_UNIX_ID 17
-#define EXTRA_DATA_LOCAL_UNIX_SIZE 19
-#define EXTRA_DATA_LOCAL_UNIX_VERSION 21
-#define EXTRA_DATA_LOCAL_UNIX_UID_SIZE 22
-#define EXTRA_DATA_LOCAL_UNIX_UID 23
-#define EXTRA_DATA_LOCAL_UNIX_GID_SIZE 27
-#define EXTRA_DATA_LOCAL_UNIX_GID 28
-#define SIZE_EXTRA_DATA_LOCAL 32
-
-#define EXTRA_DATA_CENTRAL_TIME_ID 0
-#define EXTRA_DATA_CENTRAL_TIME_SIZE 2
-#define EXTRA_DATA_CENTRAL_TIME_FLAG 4
-#define EXTRA_DATA_CENTRAL_MTIME 5
-#define EXTRA_DATA_CENTRAL_UNIX_ID 9
-#define EXTRA_DATA_CENTRAL_UNIX_SIZE 11
-#define SIZE_EXTRA_DATA_CENTRAL 13
-
-#define CENTRAL_DIRECTORY_END_SIGNATURE 0
-#define CENTRAL_DIRECTORY_END_DISK 4
-#define CENTRAL_DIRECTORY_END_START_DISK 6
-#define CENTRAL_DIRECTORY_END_ENTRIES_DISK 8
-#define CENTRAL_DIRECTORY_END_ENTRIES 10
-#define CENTRAL_DIRECTORY_END_SIZE 12
-#define CENTRAL_DIRECTORY_END_OFFSET 16
-#define CENTRAL_DIRECTORY_END_COMMENT_LENGTH 20
-#define SIZE_CENTRAL_DIRECTORY_END 22
-
-struct zip_file_header_link {
- struct zip_file_header_link *next;
- struct archive_entry *entry;
- int64_t offset;
- unsigned long crc32;
- int64_t compressed_size;
- enum compression compression;
- int flags;
-};
+ if (zip->central_directory == NULL) {
+ zip->central_directory
+ = zip->central_directory_last
+ = segment;
+ } else {
+ zip->central_directory_last->next = segment;
+ zip->central_directory_last = segment;
+ }
+ }
-struct zip {
- uint8_t data_descriptor[SIZE_DATA_DESCRIPTOR];
- struct zip_file_header_link *central_directory;
- struct zip_file_header_link *central_directory_end;
- int64_t offset;
- int64_t written_bytes;
- int64_t remaining_data_bytes;
- enum compression compression;
- int flags;
- struct archive_string_conv *opt_sconv;
- struct archive_string_conv *sconv_default;
- int init_default_conversion;
+ p = zip->central_directory_last->p;
+ zip->central_directory_last->p += length;
+ zip->central_directory_bytes += length;
+ return (p);
+}
-#ifdef HAVE_ZLIB_H
- z_stream stream;
- size_t len_buf;
- unsigned char *buf;
-#endif
-};
+static unsigned long
+real_crc32(unsigned long crc, const void *buff, size_t len)
+{
+ return crc32(crc, buff, (unsigned int)len);
+}
+
+static unsigned long
+fake_crc32(unsigned long crc, const void *buff, size_t len)
+{
+ (void)crc; /* UNUSED */
+ (void)buff; /* UNUSED */
+ (void)len; /* UNUSED */
+ return 0;
+}
static int
archive_write_zip_options(struct archive_write *a, const char *key,
@@ -217,24 +253,108 @@ archive_write_zip_options(struct archive_write *a, const char *key,
int ret = ARCHIVE_FAILED;
if (strcmp(key, "compression") == 0) {
+ /*
+ * Set compression to use on all future entries.
+ * This only affects regular files.
+ */
if (val == NULL || val[0] == 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"%s: compression option needs a compression name",
a->format_name);
} else if (strcmp(val, "deflate") == 0) {
#ifdef HAVE_ZLIB_H
- zip->compression = COMPRESSION_DEFLATE;
+ zip->requested_compression = COMPRESSION_DEFLATE;
ret = ARCHIVE_OK;
#else
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"deflate compression not supported");
#endif
} else if (strcmp(val, "store") == 0) {
- zip->compression = COMPRESSION_STORE;
+ zip->requested_compression = COMPRESSION_STORE;
ret = ARCHIVE_OK;
}
return (ret);
+ } else if (strcmp(key, "compression-level") == 0) {
+ if (val == NULL || !(val[0] >= '0' && val[0] <= '9') || val[1] != '\0') {
+ return ARCHIVE_WARN;
+ }
+
+ if (val[0] == '0') {
+ zip->requested_compression = COMPRESSION_STORE;
+ return ARCHIVE_OK;
+ } else {
+#ifdef HAVE_ZLIB_H
+ zip->requested_compression = COMPRESSION_DEFLATE;
+ zip->deflate_compression_level = val[0] - '0';
+ return ARCHIVE_OK;
+#else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "deflate compression not supported");
+#endif
+ }
+ } else if (strcmp(key, "encryption") == 0) {
+ if (val == NULL) {
+ zip->encryption_type = ENCRYPTION_NONE;
+ ret = ARCHIVE_OK;
+ } else if (val[0] == '1' || strcmp(val, "traditional") == 0
+ || strcmp(val, "zipcrypt") == 0
+ || strcmp(val, "ZipCrypt") == 0) {
+ if (is_traditional_pkware_encryption_supported()) {
+ zip->encryption_type = ENCRYPTION_TRADITIONAL;
+ ret = ARCHIVE_OK;
+ } else {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "encryption not supported");
+ }
+ } else if (strcmp(val, "aes128") == 0) {
+ if (is_winzip_aes_encryption_supported(
+ ENCRYPTION_WINZIP_AES128)) {
+ zip->encryption_type = ENCRYPTION_WINZIP_AES128;
+ ret = ARCHIVE_OK;
+ } else {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "encryption not supported");
+ }
+ } else if (strcmp(val, "aes256") == 0) {
+ if (is_winzip_aes_encryption_supported(
+ ENCRYPTION_WINZIP_AES256)) {
+ zip->encryption_type = ENCRYPTION_WINZIP_AES256;
+ ret = ARCHIVE_OK;
+ } else {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "encryption not supported");
+ }
+ } else {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: unknown encryption '%s'",
+ a->format_name, val);
+ }
+ return (ret);
+ } else if (strcmp(key, "experimental") == 0) {
+ if (val == NULL || val[0] == 0) {
+ zip->flags &= ~ ZIP_FLAG_EXPERIMENT_xl;
+ } else {
+ zip->flags |= ZIP_FLAG_EXPERIMENT_xl;
+ }
+ return (ARCHIVE_OK);
+ } else if (strcmp(key, "fakecrc32") == 0) {
+ /*
+ * FOR TESTING ONLY: disable CRC calculation to speed up
+ * certain complex tests.
+ */
+ if (val == NULL || val[0] == 0) {
+ zip->crc32func = real_crc32;
+ } else {
+ zip->crc32func = fake_crc32;
+ }
+ return (ARCHIVE_OK);
} else if (strcmp(key, "hdrcharset") == 0) {
+ /*
+ * Set the character set used in translating filenames.
+ */
if (val == NULL || val[0] == 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"%s: hdrcharset option needs a character-set name",
@@ -248,6 +368,21 @@ archive_write_zip_options(struct archive_write *a, const char *key,
ret = ARCHIVE_FATAL;
}
return (ret);
+ } else if (strcmp(key, "zip64") == 0) {
+ /*
+ * Bias decisions about Zip64: force them to be
+ * generated in certain cases where they are not
+ * forbidden or avoid them in certain cases where they
+ * are not strictly required.
+ */
+ if (val != NULL && *val != '\0') {
+ zip->flags |= ZIP_FLAG_FORCE_ZIP64;
+ zip->flags &= ~ZIP_FLAG_AVOID_ZIP64;
+ } else {
+ zip->flags &= ~ZIP_FLAG_FORCE_ZIP64;
+ zip->flags |= ZIP_FLAG_AVOID_ZIP64;
+ }
+ return (ARCHIVE_OK);
}
/* Note: The "warn" return is just to inform the options
@@ -261,9 +396,9 @@ archive_write_zip_set_compression_deflate(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
int ret = ARCHIVE_FAILED;
-
+
archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW | ARCHIVE_STATE_HEADER,
+ ARCHIVE_STATE_NEW | ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
"archive_write_zip_set_compression_deflate");
if (a->archive.archive_format != ARCHIVE_FORMAT_ZIP) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
@@ -273,11 +408,12 @@ archive_write_zip_set_compression_deflate(struct archive *_a)
} else {
#ifdef HAVE_ZLIB_H
struct zip *zip = a->format_data;
- zip->compression = COMPRESSION_DEFLATE;
+ zip->requested_compression = COMPRESSION_DEFLATE;
ret = ARCHIVE_OK;
#else
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"deflate compression not supported");
+ ret = ARCHIVE_FAILED;
#endif
}
return (ret);
@@ -289,9 +425,9 @@ archive_write_zip_set_compression_store(struct archive *_a)
struct archive_write *a = (struct archive_write *)_a;
struct zip *zip = a->format_data;
int ret = ARCHIVE_FAILED;
-
+
archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW | ARCHIVE_STATE_HEADER,
+ ARCHIVE_STATE_NEW | ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
"archive_write_zip_set_compression_deflate");
if (a->archive.archive_format != ARCHIVE_FORMAT_ZIP) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
@@ -299,7 +435,7 @@ archive_write_zip_set_compression_store(struct archive *_a)
" with zip format");
ret = ARCHIVE_FATAL;
} else {
- zip->compression = COMPRESSION_STORE;
+ zip->requested_compression = COMPRESSION_STORE;
ret = ARCHIVE_OK;
}
return (ret);
@@ -324,14 +460,15 @@ archive_write_set_format_zip(struct archive *_a)
"Can't allocate zip data");
return (ARCHIVE_FATAL);
}
- zip->central_directory = NULL;
- zip->central_directory_end = NULL;
- zip->offset = 0;
- zip->written_bytes = 0;
- zip->remaining_data_bytes = 0;
+ /* "Unspecified" lets us choose the appropriate compression. */
+ zip->requested_compression = COMPRESSION_UNSPECIFIED;
#ifdef HAVE_ZLIB_H
- zip->compression = COMPRESSION_DEFLATE;
+ zip->deflate_compression_level = Z_DEFAULT_COMPRESSION;
+#endif
+ zip->crc32func = real_crc32;
+
+ /* A buffer used for both compression and encryption. */
zip->len_buf = 65536;
zip->buf = malloc(zip->len_buf);
if (zip->buf == NULL) {
@@ -340,9 +477,6 @@ archive_write_set_format_zip(struct archive *_a)
"Can't allocate compression buffer");
return (ARCHIVE_FATAL);
}
-#else
- zip->compression = COMPRESSION_STORE;
-#endif
a->format_data = zip;
a->format_name = "zip";
@@ -355,9 +489,6 @@ archive_write_set_format_zip(struct archive *_a)
a->archive.archive_format = ARCHIVE_FORMAT_ZIP;
a->archive.archive_format_name = "ZIP";
- archive_le32enc(&zip->data_descriptor[DATA_DESCRIPTOR_SIGNATURE],
- ZIP_SIGNATURE_DATA_DESCRIPTOR);
-
return (ARCHIVE_OK);
}
@@ -376,17 +507,20 @@ is_all_ascii(const char *p)
static int
archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
{
- struct zip *zip;
- uint8_t h[SIZE_LOCAL_FILE_HEADER];
- uint8_t e[SIZE_EXTRA_DATA_LOCAL];
- uint8_t *d;
- struct zip_file_header_link *l;
- struct archive_string_conv *sconv;
+ unsigned char local_header[32];
+ unsigned char local_extra[144];
+ struct zip *zip = a->format_data;
+ unsigned char *e;
+ unsigned char *cd_extra;
+ size_t filename_length;
+ const char *slink = NULL;
+ size_t slink_size = 0;
+ struct archive_string_conv *sconv = get_sconv(a, zip);
int ret, ret2 = ARCHIVE_OK;
- int64_t size;
mode_t type;
+ int version_needed = 10;
- /* Entries other than a regular file or a folder are skipped. */
+ /* Ignore types of entries that we don't support. */
type = archive_entry_filetype(entry);
if (type != AE_IFREG && type != AE_IFDIR && type != AE_IFLNK) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
@@ -394,70 +528,88 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
return ARCHIVE_FAILED;
};
- /* Directory entries should have a size of 0. */
- if (type == AE_IFDIR)
+ /* If we're not using Zip64, reject large files. */
+ if (zip->flags & ZIP_FLAG_AVOID_ZIP64) {
+ /* Reject entries over 4GB. */
+ if (archive_entry_size_is_set(entry)
+ && (archive_entry_size(entry) >
+ ARCHIVE_LITERAL_LL(0xffffffff))) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Files > 4GB require Zip64 extensions");
+ return ARCHIVE_FAILED;
+ }
+ /* Reject entries if archive is > 4GB. */
+ if (zip->written_bytes > ARCHIVE_LITERAL_LL(0xffffffff)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Archives > 4GB require Zip64 extensions");
+ return ARCHIVE_FAILED;
+ }
+ }
+
+ /* Only regular files can have size > 0. */
+ if (type != AE_IFREG)
archive_entry_set_size(entry, 0);
- zip = a->format_data;
- /* Setup default conversion. */
- if (zip->opt_sconv == NULL && !zip->init_default_conversion) {
- zip->sconv_default =
- archive_string_default_conversion_for_write(&(a->archive));
- zip->init_default_conversion = 1;
+
+ /* Reset information from last entry. */
+ zip->entry_offset = zip->written_bytes;
+ zip->entry_uncompressed_limit = INT64_MAX;
+ zip->entry_compressed_size = 0;
+ zip->entry_uncompressed_size = 0;
+ zip->entry_compressed_written = 0;
+ zip->entry_uncompressed_written = 0;
+ zip->entry_flags = 0;
+ zip->entry_uses_zip64 = 0;
+ zip->entry_crc32 = zip->crc32func(0, NULL, 0);
+ zip->entry_encryption = 0;
+ if (zip->entry != NULL) {
+ archive_entry_free(zip->entry);
+ zip->entry = NULL;
}
- if (zip->flags == 0) {
- /* Initialize the general purpose flags. */
- zip->flags = ZIP_FLAGS;
- if (zip->opt_sconv != NULL) {
- if (strcmp(archive_string_conversion_charset_name(
- zip->opt_sconv), "UTF-8") == 0)
- zip->flags |= ZIP_FLAGS_UTF8_NAME;
-#if HAVE_NL_LANGINFO
- } else if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0) {
- zip->flags |= ZIP_FLAGS_UTF8_NAME;
-#endif
+ if (zip->cctx_valid)
+ archive_encrypto_aes_ctr_release(&zip->cctx);
+ if (zip->hctx_valid)
+ archive_hmac_sha1_cleanup(&zip->hctx);
+ zip->tctx_valid = zip->cctx_valid = zip->hctx_valid = 0;
+
+ if (type == AE_IFREG
+ &&(!archive_entry_size_is_set(entry)
+ || archive_entry_size(entry) > 0)) {
+ switch (zip->encryption_type) {
+ case ENCRYPTION_TRADITIONAL:
+ case ENCRYPTION_WINZIP_AES128:
+ case ENCRYPTION_WINZIP_AES256:
+ zip->entry_flags |= ZIP_ENTRY_FLAG_ENCRYPTED;
+ zip->entry_encryption = zip->encryption_type;
+ break;
+ default:
+ break;
}
}
- d = zip->data_descriptor;
- size = archive_entry_size(entry);
- zip->remaining_data_bytes = size;
- /* Append archive entry to the central directory data. */
- l = (struct zip_file_header_link *) malloc(sizeof(*l));
- if (l == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate zip header data");
- return (ARCHIVE_FATAL);
- }
+
#if defined(_WIN32) && !defined(__CYGWIN__)
/* Make sure the path separators in pahtname, hardlink and symlink
* are all slash '/', not the Windows path separator '\'. */
- l->entry = __la_win_entry_in_posix_pathseparator(entry);
- if (l->entry == entry)
- l->entry = archive_entry_clone(entry);
+ zip->entry = __la_win_entry_in_posix_pathseparator(entry);
+ if (zip->entry == entry)
+ zip->entry = archive_entry_clone(entry);
#else
- l->entry = archive_entry_clone(entry);
+ zip->entry = archive_entry_clone(entry);
#endif
- if (l->entry == NULL) {
+ if (zip->entry == NULL) {
archive_set_error(&a->archive, ENOMEM,
"Can't allocate zip header data");
- free(l);
return (ARCHIVE_FATAL);
}
- l->flags = zip->flags;
- if (zip->opt_sconv != NULL)
- sconv = zip->opt_sconv;
- else
- sconv = zip->sconv_default;
+
if (sconv != NULL) {
const char *p;
size_t len;
if (archive_entry_pathname_l(entry, &p, &len, sconv) != 0) {
if (errno == ENOMEM) {
- archive_entry_free(l->entry);
- free(l);
archive_set_error(&a->archive, ENOMEM,
"Can't allocate memory for Pathname");
return (ARCHIVE_FATAL);
@@ -470,163 +622,380 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
ret2 = ARCHIVE_WARN;
}
if (len > 0)
- archive_entry_set_pathname(l->entry, p);
+ archive_entry_set_pathname(zip->entry, p);
/*
- * Although there is no character-set regulation for Symlink,
- * it is suitable to convert a character-set of Symlinke to
- * what those of the Pathname has been converted to.
+ * There is no standard for symlink handling; we convert
+ * it using the same character-set translation that we use
+ * for filename.
*/
if (type == AE_IFLNK) {
if (archive_entry_symlink_l(entry, &p, &len, sconv)) {
if (errno == ENOMEM) {
- archive_entry_free(l->entry);
- free(l);
archive_set_error(&a->archive, ENOMEM,
"Can't allocate memory "
" for Symlink");
return (ARCHIVE_FATAL);
}
- /*
- * Even if the strng conversion failed,
- * we should not report the error since
- * thre is no regulation for.
- */
+ /* No error if we can't convert. */
} else if (len > 0)
- archive_entry_set_symlink(l->entry, p);
+ archive_entry_set_symlink(zip->entry, p);
+ }
+ }
+
+ /* If filename isn't ASCII and we can use UTF-8, set the UTF-8 flag. */
+ if (!is_all_ascii(archive_entry_pathname(zip->entry))) {
+ if (zip->opt_sconv != NULL) {
+ if (strcmp(archive_string_conversion_charset_name(
+ zip->opt_sconv), "UTF-8") == 0)
+ zip->entry_flags |= ZIP_ENTRY_FLAG_UTF8_NAME;
+#if HAVE_NL_LANGINFO
+ } else if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0) {
+ zip->entry_flags |= ZIP_ENTRY_FLAG_UTF8_NAME;
+#endif
}
}
- /* If all characters in a filename are ASCII, Reset UTF-8 Name flag. */
- if ((l->flags & ZIP_FLAGS_UTF8_NAME) != 0 &&
- is_all_ascii(archive_entry_pathname(l->entry)))
- l->flags &= ~ZIP_FLAGS_UTF8_NAME;
+ filename_length = path_length(zip->entry);
- /* Initialize the CRC variable and potentially the local crc32(). */
- l->crc32 = crc32(0, NULL, 0);
+ /* Determine appropriate compression and size for this entry. */
if (type == AE_IFLNK) {
- const char *p = archive_entry_symlink(l->entry);
- if (p != NULL)
- size = strlen(p);
+ slink = archive_entry_symlink(zip->entry);
+ if (slink != NULL)
+ slink_size = strlen(slink);
else
- size = 0;
- zip->remaining_data_bytes = 0;
- archive_entry_set_size(l->entry, size);
- l->compression = COMPRESSION_STORE;
- l->compressed_size = size;
+ slink_size = 0;
+ zip->entry_uncompressed_limit = slink_size;
+ zip->entry_compressed_size = slink_size;
+ zip->entry_uncompressed_size = slink_size;
+ zip->entry_crc32 = zip->crc32func(zip->entry_crc32,
+ (const unsigned char *)slink, slink_size);
+ zip->entry_compression = COMPRESSION_STORE;
+ version_needed = 20;
+ } else if (type != AE_IFREG) {
+ zip->entry_compression = COMPRESSION_STORE;
+ zip->entry_uncompressed_limit = 0;
+ version_needed = 20;
+ } else if (archive_entry_size_is_set(zip->entry)) {
+ int64_t size = archive_entry_size(zip->entry);
+ int64_t additional_size = 0;
+
+ zip->entry_uncompressed_limit = size;
+ zip->entry_compression = zip->requested_compression;
+ if (zip->entry_compression == COMPRESSION_UNSPECIFIED) {
+ zip->entry_compression = COMPRESSION_DEFAULT;
+ }
+ if (zip->entry_compression == COMPRESSION_STORE) {
+ zip->entry_compressed_size = size;
+ zip->entry_uncompressed_size = size;
+ version_needed = 10;
+ } else {
+ zip->entry_uncompressed_size = size;
+ version_needed = 20;
+ }
+
+ if (zip->entry_flags & ZIP_ENTRY_FLAG_ENCRYPTED) {
+ switch (zip->entry_encryption) {
+ case ENCRYPTION_TRADITIONAL:
+ additional_size = TRAD_HEADER_SIZE;
+ version_needed = 20;
+ break;
+ case ENCRYPTION_WINZIP_AES128:
+ additional_size = WINZIP_AES128_HEADER_SIZE
+ + AUTH_CODE_SIZE;
+ version_needed = 20;
+ break;
+ case ENCRYPTION_WINZIP_AES256:
+ additional_size = WINZIP_AES256_HEADER_SIZE
+ + AUTH_CODE_SIZE;
+ version_needed = 20;
+ break;
+ default:
+ break;
+ }
+ if (zip->entry_compression == COMPRESSION_STORE)
+ zip->entry_compressed_size += additional_size;
+ }
+
+ /*
+ * Set Zip64 extension in any of the following cases
+ * (this was suggested by discussion on info-zip-dev
+ * mailing list):
+ * = Zip64 is being forced by user
+ * = File is over 4GiB uncompressed
+ * (including encryption header, if any)
+ * = File is close to 4GiB and is being compressed
+ * (compression might make file larger)
+ */
+ if ((zip->flags & ZIP_FLAG_FORCE_ZIP64)
+ || (zip->entry_uncompressed_size + additional_size >
+ ARCHIVE_LITERAL_LL(0xffffffff))
+ || (zip->entry_uncompressed_size >
+ ARCHIVE_LITERAL_LL(0xff000000)
+ && zip->entry_compression != COMPRESSION_STORE)) {
+ zip->entry_uses_zip64 = 1;
+ version_needed = 45;
+ }
+
+ /* We may know the size, but never the CRC. */
+ zip->entry_flags |= ZIP_ENTRY_FLAG_LENGTH_AT_END;
} else {
- l->compression = zip->compression;
- l->compressed_size = 0;
+ /* We don't know the size. In this case, we prefer
+ * deflate (it has a clear end-of-data marker which
+ * makes length-at-end more reliable) and will
+ * enable Zip64 extensions unless we're told not to.
+ */
+ zip->entry_compression = COMPRESSION_DEFAULT;
+ zip->entry_flags |= ZIP_ENTRY_FLAG_LENGTH_AT_END;
+ if ((zip->flags & ZIP_FLAG_AVOID_ZIP64) == 0) {
+ zip->entry_uses_zip64 = 1;
+ version_needed = 45;
+ } else if (zip->entry_compression == COMPRESSION_STORE) {
+ version_needed = 10;
+ } else {
+ version_needed = 20;
+ }
+
+ if (zip->entry_flags & ZIP_ENTRY_FLAG_ENCRYPTED) {
+ switch (zip->entry_encryption) {
+ case ENCRYPTION_TRADITIONAL:
+ case ENCRYPTION_WINZIP_AES128:
+ case ENCRYPTION_WINZIP_AES256:
+ if (version_needed < 20)
+ version_needed = 20;
+ break;
+ default:
+ break;
+ }
+ }
}
- l->next = NULL;
- if (zip->central_directory == NULL) {
- zip->central_directory = l;
+
+ /* Format the local header. */
+ memset(local_header, 0, sizeof(local_header));
+ memcpy(local_header, "PK\003\004", 4);
+ archive_le16enc(local_header + 4, version_needed);
+ archive_le16enc(local_header + 6, zip->entry_flags);
+ if (zip->entry_encryption == ENCRYPTION_WINZIP_AES128
+ || zip->entry_encryption == ENCRYPTION_WINZIP_AES256)
+ archive_le16enc(local_header + 8, WINZIP_AES_ENCRYPTION);
+ else
+ archive_le16enc(local_header + 8, zip->entry_compression);
+ archive_le32enc(local_header + 10,
+ dos_time(archive_entry_mtime(zip->entry)));
+ archive_le32enc(local_header + 14, zip->entry_crc32);
+ if (zip->entry_uses_zip64) {
+ /* Zip64 data in the local header "must" include both
+ * compressed and uncompressed sizes AND those fields
+ * are included only if these are 0xffffffff;
+ * THEREFORE these must be set this way, even if we
+ * know one of them is smaller. */
+ archive_le32enc(local_header + 18, ARCHIVE_LITERAL_LL(0xffffffff));
+ archive_le32enc(local_header + 22, ARCHIVE_LITERAL_LL(0xffffffff));
} else {
- zip->central_directory_end->next = l;
- }
- zip->central_directory_end = l;
-
- /* Store the offset of this header for later use in central
- * directory. */
- l->offset = zip->written_bytes;
-
- memset(h, 0, sizeof(h));
- archive_le32enc(&h[LOCAL_FILE_HEADER_SIGNATURE],
- ZIP_SIGNATURE_LOCAL_FILE_HEADER);
- archive_le16enc(&h[LOCAL_FILE_HEADER_VERSION], ZIP_VERSION_EXTRACT);
- archive_le16enc(&h[LOCAL_FILE_HEADER_FLAGS], l->flags);
- archive_le16enc(&h[LOCAL_FILE_HEADER_COMPRESSION], l->compression);
- archive_le32enc(&h[LOCAL_FILE_HEADER_TIMEDATE],
- dos_time(archive_entry_mtime(entry)));
- archive_le16enc(&h[LOCAL_FILE_HEADER_FILENAME_LENGTH],
- (uint16_t)path_length(l->entry));
-
- switch (l->compression) {
- case COMPRESSION_STORE:
- /* Setting compressed and uncompressed sizes even when
- * specification says to set to zero when using data
- * descriptors. Otherwise the end of the data for an
- * entry is rather difficult to find. */
- archive_le32enc(&h[LOCAL_FILE_HEADER_COMPRESSED_SIZE],
- (uint32_t)size);
- archive_le32enc(&h[LOCAL_FILE_HEADER_UNCOMPRESSED_SIZE],
- (uint32_t)size);
- break;
-#ifdef HAVE_ZLIB_H
- case COMPRESSION_DEFLATE:
- archive_le32enc(&h[LOCAL_FILE_HEADER_UNCOMPRESSED_SIZE],
- (uint32_t)size);
+ archive_le32enc(local_header + 18, (uint32_t)zip->entry_compressed_size);
+ archive_le32enc(local_header + 22, (uint32_t)zip->entry_uncompressed_size);
+ }
+ archive_le16enc(local_header + 26, (uint16_t)filename_length);
- zip->stream.zalloc = Z_NULL;
- zip->stream.zfree = Z_NULL;
- zip->stream.opaque = Z_NULL;
- zip->stream.next_out = zip->buf;
- zip->stream.avail_out = (uInt)zip->len_buf;
- if (deflateInit2(&zip->stream, Z_DEFAULT_COMPRESSION,
- Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY) != Z_OK) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't init deflate compressor");
- return (ARCHIVE_FATAL);
+ if (zip->entry_encryption == ENCRYPTION_TRADITIONAL) {
+ if (zip->entry_flags & ZIP_ENTRY_FLAG_LENGTH_AT_END)
+ zip->trad_chkdat = local_header[11];
+ else
+ zip->trad_chkdat = local_header[17];
+ }
+
+ /* Format as much of central directory file header as we can: */
+ zip->file_header = cd_alloc(zip, 46);
+ /* If (zip->file_header == NULL) XXXX */
+ ++zip->central_directory_entries;
+ memset(zip->file_header, 0, 46);
+ memcpy(zip->file_header, "PK\001\002", 4);
+ /* "Made by PKZip 2.0 on Unix." */
+ archive_le16enc(zip->file_header + 4, 3 * 256 + version_needed);
+ archive_le16enc(zip->file_header + 6, version_needed);
+ archive_le16enc(zip->file_header + 8, zip->entry_flags);
+ if (zip->entry_encryption == ENCRYPTION_WINZIP_AES128
+ || zip->entry_encryption == ENCRYPTION_WINZIP_AES256)
+ archive_le16enc(zip->file_header + 10, WINZIP_AES_ENCRYPTION);
+ else
+ archive_le16enc(zip->file_header + 10, zip->entry_compression);
+ archive_le32enc(zip->file_header + 12,
+ dos_time(archive_entry_mtime(zip->entry)));
+ archive_le16enc(zip->file_header + 28, (uint16_t)filename_length);
+ /* Following Info-Zip, store mode in the "external attributes" field. */
+ archive_le32enc(zip->file_header + 38,
+ ((uint32_t)archive_entry_mode(zip->entry)) << 16);
+ e = cd_alloc(zip, filename_length);
+ /* If (e == NULL) XXXX */
+ copy_path(zip->entry, e);
+
+ /* Format extra data. */
+ memset(local_extra, 0, sizeof(local_extra));
+ e = local_extra;
+
+ /* First, extra blocks that are the same between
+ * the local file header and the central directory.
+ * We format them once and then duplicate them. */
+
+ /* UT timestamp, length depends on what timestamps are set. */
+ memcpy(e, "UT", 2);
+ archive_le16enc(e + 2,
+ 1
+ + (archive_entry_mtime_is_set(entry) ? 4 : 0)
+ + (archive_entry_atime_is_set(entry) ? 4 : 0)
+ + (archive_entry_ctime_is_set(entry) ? 4 : 0));
+ e += 4;
+ *e++ =
+ (archive_entry_mtime_is_set(entry) ? 1 : 0)
+ | (archive_entry_atime_is_set(entry) ? 2 : 0)
+ | (archive_entry_ctime_is_set(entry) ? 4 : 0);
+ if (archive_entry_mtime_is_set(entry)) {
+ archive_le32enc(e, (uint32_t)archive_entry_mtime(entry));
+ e += 4;
+ }
+ if (archive_entry_atime_is_set(entry)) {
+ archive_le32enc(e, (uint32_t)archive_entry_atime(entry));
+ e += 4;
+ }
+ if (archive_entry_ctime_is_set(entry)) {
+ archive_le32enc(e, (uint32_t)archive_entry_ctime(entry));
+ e += 4;
+ }
+
+ /* ux Unix extra data, length 11, version 1 */
+ /* TODO: If uid < 64k, use 2 bytes, ditto for gid. */
+ memcpy(e, "ux\013\000\001", 5);
+ e += 5;
+ *e++ = 4; /* Length of following UID */
+ archive_le32enc(e, (uint32_t)archive_entry_uid(entry));
+ e += 4;
+ *e++ = 4; /* Length of following GID */
+ archive_le32enc(e, (uint32_t)archive_entry_gid(entry));
+ e += 4;
+
+ /* AES extra data field: WinZIP AES information, ID=0x9901 */
+ if ((zip->entry_flags & ZIP_ENTRY_FLAG_ENCRYPTED)
+ && (zip->entry_encryption == ENCRYPTION_WINZIP_AES128
+ || zip->entry_encryption == ENCRYPTION_WINZIP_AES256)) {
+
+ memcpy(e, "\001\231\007\000\001\000AE", 8);
+ /* AES vendoer version AE-2 does not store a CRC.
+ * WinZip 11 uses AE-1, which does store the CRC,
+ * but it does not store the CRC when the file size
+ * is less than 20 bytes. So we simulate what
+ * WinZip 11 does.
+ * NOTE: WinZip 9.0 and 10.0 uses AE-2 by default. */
+ if (archive_entry_size_is_set(zip->entry)
+ && archive_entry_size(zip->entry) < 20) {
+ archive_le16enc(e+4, AES_VENDOR_AE_2);
+ zip->aes_vendor = AES_VENDOR_AE_2;/* no CRC. */
+ } else
+ zip->aes_vendor = AES_VENDOR_AE_1;
+ e += 8;
+ /* AES encryption strength. */
+ *e++ = (zip->entry_encryption == ENCRYPTION_WINZIP_AES128)?1:3;
+ /* Actual compression method. */
+ archive_le16enc(e, zip->entry_compression);
+ e += 2;
+ }
+
+ /* Copy UT ,ux, and AES-extra into central directory as well. */
+ zip->file_header_extra_offset = zip->central_directory_bytes;
+ cd_extra = cd_alloc(zip, e - local_extra);
+ memcpy(cd_extra, local_extra, e - local_extra);
+
+ /*
+ * Following extra blocks vary between local header and
+ * central directory. These are the local header versions.
+ * Central directory versions get formatted in
+ * archive_write_zip_finish_entry() below.
+ */
+
+ /* "[Zip64 entry] in the local header MUST include BOTH
+ * original [uncompressed] and compressed size fields." */
+ if (zip->entry_uses_zip64) {
+ unsigned char *zip64_start = e;
+ memcpy(e, "\001\000\020\000", 4);
+ e += 4;
+ archive_le64enc(e, zip->entry_uncompressed_size);
+ e += 8;
+ archive_le64enc(e, zip->entry_compressed_size);
+ e += 8;
+ archive_le16enc(zip64_start + 2, (uint16_t)(e - (zip64_start + 4)));
+ }
+
+ if (zip->flags & ZIP_FLAG_EXPERIMENT_xl) {
+ /* Experimental 'xl' extension to improve streaming. */
+ unsigned char *external_info = e;
+ int included = 7;
+ memcpy(e, "xl\000\000", 4); // 0x6c65 + 2-byte length
+ e += 4;
+ e[0] = included; /* bitmap of included fields */
+ e += 1;
+ if (included & 1) {
+ archive_le16enc(e, /* "Version created by" */
+ 3 * 256 + version_needed);
+ e += 2;
}
- break;
-#endif
+ if (included & 2) {
+ archive_le16enc(e, 0); /* internal file attributes */
+ e += 2;
+ }
+ if (included & 4) {
+ archive_le32enc(e, /* external file attributes */
+ ((uint32_t)archive_entry_mode(zip->entry)) << 16);
+ e += 4;
+ }
+ if (included & 8) {
+ // Libarchive does not currently support file comments.
+ }
+ archive_le16enc(external_info + 2, (uint16_t)(e - (external_info + 4)));
}
- /* Formatting extra data. */
- archive_le16enc(&h[LOCAL_FILE_HEADER_EXTRA_LENGTH], sizeof(e));
- archive_le16enc(&e[EXTRA_DATA_LOCAL_TIME_ID],
- ZIP_SIGNATURE_EXTRA_TIMESTAMP);
- archive_le16enc(&e[EXTRA_DATA_LOCAL_TIME_SIZE], 1 + 4 * 3);
- e[EXTRA_DATA_LOCAL_TIME_FLAG] = 0x07;
- archive_le32enc(&e[EXTRA_DATA_LOCAL_MTIME],
- (uint32_t)archive_entry_mtime(entry));
- archive_le32enc(&e[EXTRA_DATA_LOCAL_ATIME],
- (uint32_t)archive_entry_atime(entry));
- archive_le32enc(&e[EXTRA_DATA_LOCAL_CTIME],
- (uint32_t)archive_entry_ctime(entry));
-
- archive_le16enc(&e[EXTRA_DATA_LOCAL_UNIX_ID],
- ZIP_SIGNATURE_EXTRA_NEW_UNIX);
- archive_le16enc(&e[EXTRA_DATA_LOCAL_UNIX_SIZE], 1 + (1 + 4) * 2);
- e[EXTRA_DATA_LOCAL_UNIX_VERSION] = 1;
- e[EXTRA_DATA_LOCAL_UNIX_UID_SIZE] = 4;
- archive_le32enc(&e[EXTRA_DATA_LOCAL_UNIX_UID],
- (uint32_t)archive_entry_uid(entry));
- e[EXTRA_DATA_LOCAL_UNIX_GID_SIZE] = 4;
- archive_le32enc(&e[EXTRA_DATA_LOCAL_UNIX_GID],
- (uint32_t)archive_entry_gid(entry));
-
- archive_le32enc(&d[DATA_DESCRIPTOR_UNCOMPRESSED_SIZE],
- (uint32_t)size);
-
- ret = __archive_write_output(a, h, sizeof(h));
+ /* Update local header with size of extra data and write it all out: */
+ archive_le16enc(local_header + 28, (uint16_t)(e - local_extra));
+
+ ret = __archive_write_output(a, local_header, 30);
if (ret != ARCHIVE_OK)
return (ARCHIVE_FATAL);
- zip->written_bytes += sizeof(h);
+ zip->written_bytes += 30;
- ret = write_path(l->entry, a);
+ ret = write_path(zip->entry, a);
if (ret <= ARCHIVE_OK)
return (ARCHIVE_FATAL);
zip->written_bytes += ret;
- ret = __archive_write_output(a, e, sizeof(e));
+ ret = __archive_write_output(a, local_extra, e - local_extra);
if (ret != ARCHIVE_OK)
return (ARCHIVE_FATAL);
- zip->written_bytes += sizeof(e);
-
- if (type == AE_IFLNK) {
- const unsigned char *p;
+ zip->written_bytes += e - local_extra;
- p = (const unsigned char *)archive_entry_symlink(l->entry);
- ret = __archive_write_output(a, p, (size_t)size);
+ /* For symlinks, write the body now. */
+ if (slink != NULL) {
+ ret = __archive_write_output(a, slink, slink_size);
if (ret != ARCHIVE_OK)
return (ARCHIVE_FATAL);
- zip->written_bytes += size;
- l->crc32 = crc32(l->crc32, p, (unsigned)size);
+ zip->entry_compressed_written += slink_size;
+ zip->entry_uncompressed_written += slink_size;
+ zip->written_bytes += slink_size;
}
- if (ret2 != ARCHIVE_OK)
- return (ret2);
- return (ARCHIVE_OK);
+#ifdef HAVE_ZLIB_H
+ if (zip->entry_compression == COMPRESSION_DEFLATE) {
+ zip->stream.zalloc = Z_NULL;
+ zip->stream.zfree = Z_NULL;
+ zip->stream.opaque = Z_NULL;
+ zip->stream.next_out = zip->buf;
+ zip->stream.avail_out = (uInt)zip->len_buf;
+ if (deflateInit2(&zip->stream, zip->deflate_compression_level,
+ Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY) != Z_OK) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't init deflate compressor");
+ return (ARCHIVE_FATAL);
+ }
+ }
+#endif
+
+ return (ret2);
}
static ssize_t
@@ -634,22 +1003,80 @@ archive_write_zip_data(struct archive_write *a, const void *buff, size_t s)
{
int ret;
struct zip *zip = a->format_data;
- struct zip_file_header_link *l = zip->central_directory_end;
- if ((int64_t)s > zip->remaining_data_bytes)
- s = (size_t)zip->remaining_data_bytes;
+ if ((int64_t)s > zip->entry_uncompressed_limit)
+ s = (size_t)zip->entry_uncompressed_limit;
+ zip->entry_uncompressed_written += s;
if (s == 0) return 0;
- switch (l->compression) {
+ if (zip->entry_flags & ZIP_ENTRY_FLAG_ENCRYPTED) {
+ switch (zip->entry_encryption) {
+ case ENCRYPTION_TRADITIONAL:
+ /* Initialize traditoinal PKWARE encryption context. */
+ if (!zip->tctx_valid) {
+ ret = init_traditional_pkware_encryption(a);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ zip->tctx_valid = 1;
+ }
+ break;
+ case ENCRYPTION_WINZIP_AES128:
+ case ENCRYPTION_WINZIP_AES256:
+ if (!zip->cctx_valid) {
+ ret = init_winzip_aes_encryption(a);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ zip->cctx_valid = zip->hctx_valid = 1;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ switch (zip->entry_compression) {
case COMPRESSION_STORE:
- ret = __archive_write_output(a, buff, s);
- if (ret != ARCHIVE_OK) return (ret);
- zip->written_bytes += s;
- zip->remaining_data_bytes -= s;
- l->compressed_size += s;
- l->crc32 = crc32(l->crc32, buff, (unsigned)s);
- return (s);
+ if (zip->tctx_valid || zip->cctx_valid) {
+ const uint8_t *rb = (const uint8_t *)buff;
+ const uint8_t * const re = rb + s;
+
+ while (rb < re) {
+ size_t l;
+
+ if (zip->tctx_valid) {
+ l = trad_enc_encrypt_update(&zip->tctx,
+ rb, re - rb,
+ zip->buf, zip->len_buf);
+ } else {
+ l = zip->len_buf;
+ ret = archive_encrypto_aes_ctr_update(
+ &zip->cctx,
+ rb, re - rb, zip->buf, &l);
+ if (ret < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Failed to encrypt file");
+ return (ARCHIVE_FAILED);
+ }
+ archive_hmac_sha1_update(&zip->hctx,
+ zip->buf, l);
+ }
+ ret = __archive_write_output(a, zip->buf, l);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ zip->entry_compressed_written += l;
+ zip->written_bytes += l;
+ rb += l;
+ }
+ } else {
+ ret = __archive_write_output(a, buff, s);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ zip->written_bytes += s;
+ zip->entry_compressed_written += s;
+ }
+ break;
#if HAVE_ZLIB_H
case COMPRESSION_DEFLATE:
zip->stream.next_in = (unsigned char*)(uintptr_t)buff;
@@ -659,20 +1086,36 @@ archive_write_zip_data(struct archive_write *a, const void *buff, size_t s)
if (ret == Z_STREAM_ERROR)
return (ARCHIVE_FATAL);
if (zip->stream.avail_out == 0) {
+ if (zip->tctx_valid) {
+ trad_enc_encrypt_update(&zip->tctx,
+ zip->buf, zip->len_buf,
+ zip->buf, zip->len_buf);
+ } else if (zip->cctx_valid) {
+ size_t outl = zip->len_buf;
+ ret = archive_encrypto_aes_ctr_update(
+ &zip->cctx,
+ zip->buf, zip->len_buf,
+ zip->buf, &outl);
+ if (ret < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Failed to encrypt file");
+ return (ARCHIVE_FAILED);
+ }
+ archive_hmac_sha1_update(&zip->hctx,
+ zip->buf, zip->len_buf);
+ }
ret = __archive_write_output(a, zip->buf,
zip->len_buf);
if (ret != ARCHIVE_OK)
return (ret);
- l->compressed_size += zip->len_buf;
+ zip->entry_compressed_written += zip->len_buf;
zip->written_bytes += zip->len_buf;
zip->stream.next_out = zip->buf;
zip->stream.avail_out = (uInt)zip->len_buf;
}
} while (zip->stream.avail_in != 0);
- zip->remaining_data_bytes -= s;
- /* If we have it, use zlib's fast crc32() */
- l->crc32 = crc32(l->crc32, buff, (uInt)s);
- return (s);
+ break;
#endif
default:
@@ -680,153 +1123,224 @@ archive_write_zip_data(struct archive_write *a, const void *buff, size_t s)
"Invalid ZIP compression type");
return ARCHIVE_FATAL;
}
+
+ zip->entry_uncompressed_limit -= s;
+ if (!zip->cctx_valid || zip->aes_vendor != AES_VENDOR_AE_2)
+ zip->entry_crc32 =
+ zip->crc32func(zip->entry_crc32, buff, (unsigned)s);
+ return (s);
+
}
static int
archive_write_zip_finish_entry(struct archive_write *a)
{
- /* Write the data descripter after file data has been written. */
- int ret;
struct zip *zip = a->format_data;
- uint8_t *d = zip->data_descriptor;
- struct zip_file_header_link *l = zip->central_directory_end;
-#if HAVE_ZLIB_H
- size_t reminder;
-#endif
+ int ret;
- switch(l->compression) {
- case COMPRESSION_STORE:
- break;
#if HAVE_ZLIB_H
- case COMPRESSION_DEFLATE:
+ if (zip->entry_compression == COMPRESSION_DEFLATE) {
for (;;) {
+ size_t remainder;
+
ret = deflate(&zip->stream, Z_FINISH);
if (ret == Z_STREAM_ERROR)
return (ARCHIVE_FATAL);
- reminder = zip->len_buf - zip->stream.avail_out;
- ret = __archive_write_output(a, zip->buf, reminder);
+ remainder = zip->len_buf - zip->stream.avail_out;
+ if (zip->tctx_valid) {
+ trad_enc_encrypt_update(&zip->tctx,
+ zip->buf, remainder, zip->buf, remainder);
+ } else if (zip->cctx_valid) {
+ size_t outl = remainder;
+ ret = archive_encrypto_aes_ctr_update(
+ &zip->cctx, zip->buf, remainder,
+ zip->buf, &outl);
+ if (ret < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Failed to encrypt file");
+ return (ARCHIVE_FAILED);
+ }
+ archive_hmac_sha1_update(&zip->hctx,
+ zip->buf, remainder);
+ }
+ ret = __archive_write_output(a, zip->buf, remainder);
if (ret != ARCHIVE_OK)
return (ret);
- l->compressed_size += reminder;
- zip->written_bytes += reminder;
+ zip->entry_compressed_written += remainder;
+ zip->written_bytes += remainder;
zip->stream.next_out = zip->buf;
if (zip->stream.avail_out != 0)
break;
zip->stream.avail_out = (uInt)zip->len_buf;
}
deflateEnd(&zip->stream);
- break;
+ }
#endif
+ if (zip->hctx_valid) {
+ uint8_t hmac[20];
+ size_t hmac_len = 20;
+
+ archive_hmac_sha1_final(&zip->hctx, hmac, &hmac_len);
+ ret = __archive_write_output(a, hmac, AUTH_CODE_SIZE);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ zip->entry_compressed_written += AUTH_CODE_SIZE;
+ zip->written_bytes += AUTH_CODE_SIZE;
}
- archive_le32enc(&d[DATA_DESCRIPTOR_CRC32], l->crc32);
- archive_le32enc(&d[DATA_DESCRIPTOR_COMPRESSED_SIZE],
- (uint32_t)l->compressed_size);
- ret = __archive_write_output(a, d, SIZE_DATA_DESCRIPTOR);
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- zip->written_bytes += SIZE_DATA_DESCRIPTOR;
+ /* Write trailing data descriptor. */
+ if ((zip->entry_flags & ZIP_ENTRY_FLAG_LENGTH_AT_END) != 0) {
+ char d[24];
+ memcpy(d, "PK\007\010", 4);
+ if (zip->cctx_valid && zip->aes_vendor == AES_VENDOR_AE_2)
+ archive_le32enc(d + 4, 0);/* no CRC.*/
+ else
+ archive_le32enc(d + 4, zip->entry_crc32);
+ if (zip->entry_uses_zip64) {
+ archive_le64enc(d + 8,
+ (uint64_t)zip->entry_compressed_written);
+ archive_le64enc(d + 16,
+ (uint64_t)zip->entry_uncompressed_written);
+ ret = __archive_write_output(a, d, 24);
+ zip->written_bytes += 24;
+ } else {
+ archive_le32enc(d + 8,
+ (uint32_t)zip->entry_compressed_written);
+ archive_le32enc(d + 12,
+ (uint32_t)zip->entry_uncompressed_written);
+ ret = __archive_write_output(a, d, 16);
+ zip->written_bytes += 16;
+ }
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Append Zip64 extra data to central directory information. */
+ if (zip->entry_compressed_written > ARCHIVE_LITERAL_LL(0xffffffff)
+ || zip->entry_uncompressed_written > ARCHIVE_LITERAL_LL(0xffffffff)
+ || zip->entry_offset > ARCHIVE_LITERAL_LL(0xffffffff)) {
+ unsigned char zip64[32];
+ unsigned char *z = zip64, *zd;
+ memcpy(z, "\001\000\000\000", 4);
+ z += 4;
+ if (zip->entry_uncompressed_written >= ARCHIVE_LITERAL_LL(0xffffffff)) {
+ archive_le64enc(z, zip->entry_uncompressed_written);
+ z += 8;
+ }
+ if (zip->entry_compressed_written >= ARCHIVE_LITERAL_LL(0xffffffff)) {
+ archive_le64enc(z, zip->entry_compressed_written);
+ z += 8;
+ }
+ if (zip->entry_offset >= ARCHIVE_LITERAL_LL(0xffffffff)) {
+ archive_le64enc(z, zip->entry_offset);
+ z += 8;
+ }
+ archive_le16enc(zip64 + 2, (uint16_t)(z - (zip64 + 4)));
+ zd = cd_alloc(zip, z - zip64);
+ if (zd == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate zip data");
+ return (ARCHIVE_FATAL);
+ }
+ memcpy(zd, zip64, z - zip64);
+ /* Zip64 means version needs to be set to at least 4.5 */
+ if (archive_le16dec(zip->file_header + 6) < 45)
+ archive_le16enc(zip->file_header + 6, 45);
+ }
+
+ /* Fix up central directory file header. */
+ if (zip->cctx_valid && zip->aes_vendor == AES_VENDOR_AE_2)
+ archive_le32enc(zip->file_header + 16, 0);/* no CRC.*/
+ else
+ archive_le32enc(zip->file_header + 16, zip->entry_crc32);
+ archive_le32enc(zip->file_header + 20,
+ (uint32_t)zipmin(zip->entry_compressed_written,
+ ARCHIVE_LITERAL_LL(0xffffffff)));
+ archive_le32enc(zip->file_header + 24,
+ (uint32_t)zipmin(zip->entry_uncompressed_written,
+ ARCHIVE_LITERAL_LL(0xffffffff)));
+ archive_le16enc(zip->file_header + 30,
+ (uint16_t)(zip->central_directory_bytes - zip->file_header_extra_offset));
+ archive_le32enc(zip->file_header + 42,
+ (uint32_t)zipmin(zip->entry_offset,
+ ARCHIVE_LITERAL_LL(0xffffffff)));
+
return (ARCHIVE_OK);
}
static int
archive_write_zip_close(struct archive_write *a)
{
- struct zip *zip;
- struct zip_file_header_link *l;
- uint8_t h[SIZE_FILE_HEADER];
- uint8_t end[SIZE_CENTRAL_DIRECTORY_END];
- uint8_t e[SIZE_EXTRA_DATA_CENTRAL];
+ uint8_t buff[64];
int64_t offset_start, offset_end;
- int entries;
+ struct zip *zip = a->format_data;
+ struct cd_segment *segment;
int ret;
- zip = a->format_data;
- l = zip->central_directory;
-
- /*
- * Formatting central directory file header fields that are
- * fixed for all entries.
- * Fields not used (and therefor 0) are:
- *
- * - comment_length
- * - disk_number
- * - attributes_internal
- */
- memset(h, 0, sizeof(h));
- archive_le32enc(&h[FILE_HEADER_SIGNATURE], ZIP_SIGNATURE_FILE_HEADER);
- archive_le16enc(&h[FILE_HEADER_VERSION_BY], ZIP_VERSION_BY);
- archive_le16enc(&h[FILE_HEADER_VERSION_EXTRACT], ZIP_VERSION_EXTRACT);
-
- entries = 0;
offset_start = zip->written_bytes;
-
- /* Formatting individual header fields per entry and
- * writing each entry. */
- while (l != NULL) {
- archive_le16enc(&h[FILE_HEADER_FLAGS], l->flags);
- archive_le16enc(&h[FILE_HEADER_COMPRESSION], l->compression);
- archive_le32enc(&h[FILE_HEADER_TIMEDATE],
- dos_time(archive_entry_mtime(l->entry)));
- archive_le32enc(&h[FILE_HEADER_CRC32], l->crc32);
- archive_le32enc(&h[FILE_HEADER_COMPRESSED_SIZE],
- (uint32_t)l->compressed_size);
- archive_le32enc(&h[FILE_HEADER_UNCOMPRESSED_SIZE],
- (uint32_t)archive_entry_size(l->entry));
- archive_le16enc(&h[FILE_HEADER_FILENAME_LENGTH],
- (uint16_t)path_length(l->entry));
- archive_le16enc(&h[FILE_HEADER_EXTRA_LENGTH], sizeof(e));
- archive_le16enc(&h[FILE_HEADER_ATTRIBUTES_EXTERNAL+2],
- archive_entry_mode(l->entry));
- archive_le32enc(&h[FILE_HEADER_OFFSET], (uint32_t)l->offset);
-
- /* Formatting extra data. */
- archive_le16enc(&e[EXTRA_DATA_CENTRAL_TIME_ID],
- ZIP_SIGNATURE_EXTRA_TIMESTAMP);
- archive_le16enc(&e[EXTRA_DATA_CENTRAL_TIME_SIZE], 1 + 4);
- e[EXTRA_DATA_CENTRAL_TIME_FLAG] = 0x07;
- archive_le32enc(&e[EXTRA_DATA_CENTRAL_MTIME],
- (uint32_t)archive_entry_mtime(l->entry));
- archive_le16enc(&e[EXTRA_DATA_CENTRAL_UNIX_ID],
- ZIP_SIGNATURE_EXTRA_NEW_UNIX);
- archive_le16enc(&e[EXTRA_DATA_CENTRAL_UNIX_SIZE], 0x0000);
-
- ret = __archive_write_output(a, h, sizeof(h));
+ segment = zip->central_directory;
+ while (segment != NULL) {
+ ret = __archive_write_output(a,
+ segment->buff, segment->p - segment->buff);
if (ret != ARCHIVE_OK)
return (ARCHIVE_FATAL);
- zip->written_bytes += sizeof(h);
-
- ret = write_path(l->entry, a);
- if (ret <= ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- zip->written_bytes += ret;
+ zip->written_bytes += segment->p - segment->buff;
+ segment = segment->next;
+ }
+ offset_end = zip->written_bytes;
- ret = __archive_write_output(a, e, sizeof(e));
- if (ret != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
- zip->written_bytes += sizeof(e);
+ /* If central dir info is too large, write Zip64 end-of-cd */
+ if (offset_end - offset_start > ARCHIVE_LITERAL_LL(0xffffffff)
+ || offset_start > ARCHIVE_LITERAL_LL(0xffffffff)
+ || zip->central_directory_entries > 0xffffUL
+ || (zip->flags & ZIP_FLAG_FORCE_ZIP64)) {
+ /* Zip64 end-of-cd record */
+ memset(buff, 0, 56);
+ memcpy(buff, "PK\006\006", 4);
+ archive_le64enc(buff + 4, 44);
+ archive_le16enc(buff + 12, 45);
+ archive_le16enc(buff + 14, 45);
+ /* This is disk 0 of 0. */
+ archive_le64enc(buff + 24, zip->central_directory_entries);
+ archive_le64enc(buff + 32, zip->central_directory_entries);
+ archive_le64enc(buff + 40, offset_end - offset_start);
+ archive_le64enc(buff + 48, offset_start);
+ ret = __archive_write_output(a, buff, 56);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ zip->written_bytes += 56;
+
+ /* Zip64 end-of-cd locator record. */
+ memset(buff, 0, 20);
+ memcpy(buff, "PK\006\007", 4);
+ archive_le32enc(buff + 4, 0);
+ archive_le64enc(buff + 8, offset_end);
+ archive_le32enc(buff + 16, 1);
+ ret = __archive_write_output(a, buff, 20);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ zip->written_bytes += 20;
- l = l->next;
- entries++;
}
- offset_end = zip->written_bytes;
- /* Formatting end of central directory. */
- memset(end, 0, sizeof(end));
- archive_le32enc(&end[CENTRAL_DIRECTORY_END_SIGNATURE],
- ZIP_SIGNATURE_CENTRAL_DIRECTORY_END);
- archive_le16enc(&end[CENTRAL_DIRECTORY_END_ENTRIES_DISK], entries);
- archive_le16enc(&end[CENTRAL_DIRECTORY_END_ENTRIES], entries);
- archive_le32enc(&end[CENTRAL_DIRECTORY_END_SIZE],
- (uint32_t)(offset_end - offset_start));
- archive_le32enc(&end[CENTRAL_DIRECTORY_END_OFFSET],
- (uint32_t)offset_start);
-
- /* Writing end of central directory. */
- ret = __archive_write_output(a, end, sizeof(end));
+ /* Format and write end of central directory. */
+ memset(buff, 0, sizeof(buff));
+ memcpy(buff, "PK\005\006", 4);
+ archive_le16enc(buff + 8, (uint16_t)zipmin(0xffffU,
+ zip->central_directory_entries));
+ archive_le16enc(buff + 10, (uint16_t)zipmin(0xffffU,
+ zip->central_directory_entries));
+ archive_le32enc(buff + 12,
+ (uint32_t)zipmin(ARCHIVE_LITERAL_LL(0xffffffff),
+ (offset_end - offset_start)));
+ archive_le32enc(buff + 16,
+ (uint32_t)zipmin(ARCHIVE_LITERAL_LL(0xffffffff),
+ offset_start));
+ ret = __archive_write_output(a, buff, 22);
if (ret != ARCHIVE_OK)
return (ARCHIVE_FATAL);
- zip->written_bytes += sizeof(end);
+ zip->written_bytes += 22;
return (ARCHIVE_OK);
}
@@ -834,18 +1348,23 @@ static int
archive_write_zip_free(struct archive_write *a)
{
struct zip *zip;
- struct zip_file_header_link *l;
+ struct cd_segment *segment;
zip = a->format_data;
while (zip->central_directory != NULL) {
- l = zip->central_directory;
- zip->central_directory = l->next;
- archive_entry_free(l->entry);
- free(l);
+ segment = zip->central_directory;
+ zip->central_directory = segment->next;
+ free(segment->buff);
+ free(segment);
}
-#ifdef HAVE_ZLIB_H
free(zip->buf);
-#endif
+ archive_entry_free(zip->entry);
+ if (zip->cctx_valid)
+ archive_encrypto_aes_ctr_release(&zip->cctx);
+ if (zip->hctx_valid)
+ archive_hmac_sha1_cleanup(&zip->hctx);
+ /* TODO: Free opt_sconv, sconv_default */
+
free(zip);
a->format_data = NULL;
return (ARCHIVE_OK);
@@ -918,7 +1437,7 @@ write_path(struct archive_entry *entry, struct archive_write *archive)
return (ARCHIVE_FATAL);
written_bytes += strlen(path);
- /* Folders are recognized by a traling slash. */
+ /* Folders are recognized by a trailing slash. */
if ((type == AE_IFDIR) & (path[strlen(path) - 1] != '/')) {
ret = __archive_write_output(archive, "/", 1);
if (ret != ARCHIVE_OK)
@@ -928,3 +1447,234 @@ write_path(struct archive_entry *entry, struct archive_write *archive)
return ((int)written_bytes);
}
+
+static void
+copy_path(struct archive_entry *entry, unsigned char *p)
+{
+ const char *path;
+ size_t pathlen;
+ mode_t type;
+
+ path = archive_entry_pathname(entry);
+ pathlen = strlen(path);
+ type = archive_entry_filetype(entry);
+
+ memcpy(p, path, pathlen);
+
+ /* Folders are recognized by a trailing slash. */
+ if ((type == AE_IFDIR) & (path[pathlen - 1] != '/')) {
+ p[pathlen] = '/';
+ p[pathlen + 1] = '\0';
+ }
+}
+
+
+static struct archive_string_conv *
+get_sconv(struct archive_write *a, struct zip *zip)
+{
+ if (zip->opt_sconv != NULL)
+ return (zip->opt_sconv);
+
+ if (!zip->init_default_conversion) {
+ zip->sconv_default =
+ archive_string_default_conversion_for_write(&(a->archive));
+ zip->init_default_conversion = 1;
+ }
+ return (zip->sconv_default);
+}
+
+/*
+ Traditional PKWARE Decryption functions.
+ */
+
+static void
+trad_enc_update_keys(struct trad_enc_ctx *ctx, uint8_t c)
+{
+ uint8_t t;
+#define CRC32(c, b) (crc32(c ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL)
+
+ ctx->keys[0] = CRC32(ctx->keys[0], c);
+ ctx->keys[1] = (ctx->keys[1] + (ctx->keys[0] & 0xff)) * 134775813L + 1;
+ t = (ctx->keys[1] >> 24) & 0xff;
+ ctx->keys[2] = CRC32(ctx->keys[2], t);
+#undef CRC32
+}
+
+static uint8_t
+trad_enc_decypt_byte(struct trad_enc_ctx *ctx)
+{
+ unsigned temp = ctx->keys[2] | 2;
+ return (uint8_t)((temp * (temp ^ 1)) >> 8) & 0xff;
+}
+
+static unsigned
+trad_enc_encrypt_update(struct trad_enc_ctx *ctx, const uint8_t *in,
+ size_t in_len, uint8_t *out, size_t out_len)
+{
+ unsigned i, max;
+
+ max = (unsigned)((in_len < out_len)? in_len: out_len);
+
+ for (i = 0; i < max; i++) {
+ uint8_t t = in[i];
+ out[i] = t ^ trad_enc_decypt_byte(ctx);
+ trad_enc_update_keys(ctx, t);
+ }
+ return i;
+}
+
+static int
+trad_enc_init(struct trad_enc_ctx *ctx, const char *pw, size_t pw_len)
+{
+
+ ctx->keys[0] = 305419896L;
+ ctx->keys[1] = 591751049L;
+ ctx->keys[2] = 878082192L;
+
+ for (;pw_len; --pw_len)
+ trad_enc_update_keys(ctx, *pw++);
+ return 0;
+}
+
+static int
+is_traditional_pkware_encryption_supported(void)
+{
+ uint8_t key[TRAD_HEADER_SIZE];
+
+ if (archive_random(key, sizeof(key)-1) != ARCHIVE_OK)
+ return (0);
+ return (1);
+}
+
+static int
+init_traditional_pkware_encryption(struct archive_write *a)
+{
+ struct zip *zip = a->format_data;
+ const char *passphrase;
+ uint8_t key[TRAD_HEADER_SIZE];
+ uint8_t key_encrypted[TRAD_HEADER_SIZE];
+ int ret;
+
+ passphrase = __archive_write_get_passphrase(a);
+ if (passphrase == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Encryption needs passphrase");
+ return ARCHIVE_FAILED;
+ }
+ if (archive_random(key, sizeof(key)-1) != ARCHIVE_OK) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Can't generate random number for encryption");
+ return ARCHIVE_FATAL;
+ }
+ trad_enc_init(&zip->tctx, passphrase, strlen(passphrase));
+ /* Set the last key code which will be used as a check code
+ * for verifying passphrase in decryption. */
+ key[TRAD_HEADER_SIZE-1] = zip->trad_chkdat;
+ trad_enc_encrypt_update(&zip->tctx, key, TRAD_HEADER_SIZE,
+ key_encrypted, TRAD_HEADER_SIZE);
+ /* Write encrypted keys in the top of the file content. */
+ ret = __archive_write_output(a, key_encrypted, TRAD_HEADER_SIZE);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ zip->written_bytes += TRAD_HEADER_SIZE;
+ zip->entry_compressed_written += TRAD_HEADER_SIZE;
+ return (ret);
+}
+
+static int
+init_winzip_aes_encryption(struct archive_write *a)
+{
+ struct zip *zip = a->format_data;
+ const char *passphrase;
+ size_t key_len, salt_len;
+ uint8_t salt[16 + 2];
+ uint8_t derived_key[MAX_DERIVED_KEY_BUF_SIZE];
+ int ret;
+
+ passphrase = __archive_write_get_passphrase(a);
+ if (passphrase == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Encryption needs passphrase");
+ return (ARCHIVE_FAILED);
+ }
+ if (zip->entry_encryption == ENCRYPTION_WINZIP_AES128) {
+ salt_len = 8;
+ key_len = 16;
+ } else {
+ /* AES 256 */
+ salt_len = 16;
+ key_len = 32;
+ }
+ if (archive_random(salt, salt_len) != ARCHIVE_OK) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Can't generate random number for encryption");
+ return (ARCHIVE_FATAL);
+ }
+ archive_pbkdf2_sha1(passphrase, strlen(passphrase),
+ salt, salt_len, 1000, derived_key, key_len * 2 + 2);
+
+ ret = archive_encrypto_aes_ctr_init(&zip->cctx, derived_key, key_len);
+ if (ret != 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Decryption is unsupported due to lack of crypto library");
+ return (ARCHIVE_FAILED);
+ }
+ ret = archive_hmac_sha1_init(&zip->hctx, derived_key + key_len,
+ key_len);
+ if (ret != 0) {
+ archive_encrypto_aes_ctr_release(&zip->cctx);
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Failed to initialize HMAC-SHA1");
+ return (ARCHIVE_FAILED);
+ }
+
+ /* Set a passowrd verification value after the 'salt'. */
+ salt[salt_len] = derived_key[key_len * 2];
+ salt[salt_len + 1] = derived_key[key_len * 2 + 1];
+
+ /* Write encrypted keys in the top of the file content. */
+ ret = __archive_write_output(a, salt, salt_len + 2);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ zip->written_bytes += salt_len + 2;
+ zip->entry_compressed_written += salt_len + 2;
+
+ return (ARCHIVE_OK);
+}
+
+static int
+is_winzip_aes_encryption_supported(int encryption)
+{
+ size_t key_len, salt_len;
+ uint8_t salt[16 + 2];
+ uint8_t derived_key[MAX_DERIVED_KEY_BUF_SIZE];
+ archive_crypto_ctx cctx;
+ archive_hmac_sha1_ctx hctx;
+ int ret;
+
+ if (encryption == ENCRYPTION_WINZIP_AES128) {
+ salt_len = 8;
+ key_len = 16;
+ } else {
+ /* AES 256 */
+ salt_len = 16;
+ key_len = 32;
+ }
+ if (archive_random(salt, salt_len) != ARCHIVE_OK)
+ return (0);
+ ret = archive_pbkdf2_sha1("p", 1, salt, salt_len, 1000,
+ derived_key, key_len * 2 + 2);
+ if (ret != 0)
+ return (0);
+
+ ret = archive_encrypto_aes_ctr_init(&cctx, derived_key, key_len);
+ if (ret != 0)
+ return (0);
+ ret = archive_hmac_sha1_init(&hctx, derived_key + key_len,
+ key_len);
+ archive_encrypto_aes_ctr_release(&cctx);
+ if (ret != 0)
+ return (0);
+ archive_hmac_sha1_cleanup(&hctx);
+ return (1);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_options.3 b/Utilities/cmlibarchive/libarchive/archive_write_set_options.3
index 9d605151a..a2f4b57d8 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_options.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_options.3
@@ -255,7 +255,7 @@ If the
.Ar value
is
.Cm hd ,
-then the the boot image is assumed to be a bootable hard disk image.
+then the boot image is assumed to be a bootable hard disk image.
If the
.Ar value
is
@@ -397,6 +397,48 @@ Specifies a filename that should not be compressed when using
This option can be provided multiple times to suppress compression
on many files.
.El
+.It Format zip
+.Bl -tag -compact -width indent
+.It Cm compression
+The value is either
+.Dq store
+or
+.Dq deflate
+to indicate how the following entries should be compressed.
+Note that this setting is ignored for directories, symbolic links,
+and other special entries.
+.It Cm experimental
+This boolean option enables or disables experimental Zip features
+that may not be compatible with other Zip implementations.
+.It Cm fakecrc32
+This boolean option disables CRC calculations.
+All CRC fields are set to zero.
+It should not be used except for testing purposes.
+.It Cm hdrcharset
+This sets the character set used for filenames.
+.It Cm zip64
+Zip64 extensions provide additional file size information
+for entries larger than 4 GiB.
+They also provide extended file offset and archive size information
+when archives exceed 4 GiB.
+By default, the Zip writer selectively enables these extensions only as needed.
+In particular, if the file size is unknown, the Zip writer will
+include Zip64 extensions to guard against the possibility that the
+file might be larger than 4 GiB.
+.Pp
+Setting this boolean option will force the writer to use Zip64 extensions
+even for small files that would not otherwise require them.
+This is primarily useful for testing.
+.Pp
+Disabling this option with
+.Cm !zip64
+will force the Zip writer to avoid Zip64 extensions:
+It will reject files with size greater than 4 GiB,
+it will reject any new entries once the total archive size reaches 4 GiB,
+and it will not use Zip64 extensions for files with unknown size.
+In particular, this can improve compatibility when generating archives
+where the entry sizes are not known in advance.
+.El
.El
.Sh EXAMPLES
The following example creates an archive write handle to
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_passphrase.3 b/Utilities/cmlibarchive/libarchive/archive_write_set_passphrase.3
new file mode 100644
index 000000000..2585595e3
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_passphrase.3
@@ -0,0 +1,74 @@
+.\" Copyright (c) 2014 Michihiro NAKAJIMA
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd September 21, 2014
+.Dt ARCHIVE_WRITE_SET_PASSPHRASE 3
+.Os
+.Sh NAME
+.Nm archive_write_set_passphrase ,
+.Nm archive_write_set_passphrase_callback
+.Nd functions for writing encrypted archives
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
+.Sh SYNOPSIS
+.In archive.h
+.Ft int
+.Fo archive_write_set_passphrase
+.Fa "struct archive *"
+.Fa "const char *passphrase"
+.Fc
+.Ft int
+.Fo archive_write_set_passphrase_callback
+.Fa "struct archive *"
+.Fa "void *client_data"
+.Fa "archive_passphrase_callback *"
+.Fc
+.Sh DESCRIPTION
+.Bl -tag -width indent
+.It Fn archive_write_set_passphrase
+Set a passphrase for writing an encryption archive.
+If
+.Ar passphrase
+is
+.Dv NULL
+or empty, this function will do nothing and
+.Cm ARCHIVE_FAILED
+will be returned.
+Otherwise,
+.Cm ARCHIVE_OK
+will be returned.
+.It Fn archive_write_set_passphrase_callback
+Register callback function that will be invoked to get a passphrase
+for encrption if the passphrase was not set by the
+.Fn archive_write_set_passphrase
+function.
+.El
+.\" .Sh ERRORS
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_write 3 ,
+.Xr archive_write_set_options 3
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_passphrase.c b/Utilities/cmlibarchive/libarchive/archive_write_set_passphrase.c
new file mode 100644
index 000000000..710ecba52
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_passphrase.c
@@ -0,0 +1,95 @@
+/*-
+ * Copyright (c) 2014 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include "archive_write_private.h"
+
+int
+archive_write_set_passphrase(struct archive *_a, const char *p)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_NEW,
+ "archive_write_set_passphrase");
+
+ if (p == NULL || p[0] == '\0') {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Empty passphrase is unacceptable");
+ return (ARCHIVE_FAILED);
+ }
+ free(a->passphrase);
+ a->passphrase = strdup(p);
+ if (a->passphrase == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate data for passphrase");
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_OK);
+}
+
+
+int
+archive_write_set_passphrase_callback(struct archive *_a, void *client_data,
+ archive_passphrase_callback *cb)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_NEW,
+ "archive_write_set_passphrase_callback");
+
+ a->passphrase_callback = cb;
+ a->passphrase_client_data = client_data;
+ return (ARCHIVE_OK);
+}
+
+
+const char *
+__archive_write_get_passphrase(struct archive_write *a)
+{
+
+ if (a->passphrase != NULL)
+ return (a->passphrase);
+
+ if (a->passphrase_callback != NULL) {
+ const char *p;
+ p = a->passphrase_callback(&a->archive,
+ a->passphrase_client_data);
+ if (p != NULL) {
+ a->passphrase = strdup(p);
+ if (a->passphrase == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate data for passphrase");
+ return (NULL);
+ }
+ return (a->passphrase);
+ }
+ }
+ return (NULL);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_xxhash.h b/Utilities/cmlibarchive/libarchive/archive_xxhash.h
new file mode 100644
index 000000000..427241641
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_xxhash.h
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 2014 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#ifndef ARCHIVE_XXHASH_H
+#define ARCHIVE_XXHASH_H
+
+typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;
+
+struct archive_xxhash {
+ unsigned int (*XXH32)(const void* input, unsigned int len,
+ unsigned int seed);
+ void* (*XXH32_init)(unsigned int seed);
+ XXH_errorcode (*XXH32_update)(void* state, const void* input,
+ unsigned int len);
+ unsigned int (*XXH32_digest)(void* state);
+};
+
+extern const struct archive_xxhash __archive_xxhash;
+
+#endif
diff --git a/Utilities/cmlibarchive/libarchive/filter_fork_windows.c b/Utilities/cmlibarchive/libarchive/filter_fork_windows.c
index fa59cc9e9..ad271fe68 100644
--- a/Utilities/cmlibarchive/libarchive/filter_fork_windows.c
+++ b/Utilities/cmlibarchive/libarchive/filter_fork_windows.c
@@ -36,7 +36,7 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout)
{
HANDLE childStdout[2], childStdin[2],childStderr;
SECURITY_ATTRIBUTES secAtts;
- STARTUPINFO staInfo;
+ STARTUPINFOA staInfo;
PROCESS_INFORMATION childInfo;
struct archive_string cmdline;
struct archive_string fullpath;
diff --git a/Utilities/cmlibarchive/libarchive/libarchive.3 b/Utilities/cmlibarchive/libarchive/libarchive.3
index 3a9a841d3..c6894d2d4 100644
--- a/Utilities/cmlibarchive/libarchive/libarchive.3
+++ b/Utilities/cmlibarchive/libarchive/libarchive.3
@@ -146,11 +146,11 @@ pages for each API or utility function.
.\"
.Sh READING AN ARCHIVE
See
-.Xr libarchive_read 3 .
+.Xr archive_read 3 .
.\"
.Sh WRITING AN ARCHIVE
See
-.Xr libarchive_write 3 .
+.Xr archive_write 3 .
.\"
.Sh WRITING ENTRIES TO DISK
The
diff --git a/Utilities/cmlibarchive/libarchive/libarchive_internals.3 b/Utilities/cmlibarchive/libarchive/libarchive_internals.3
index 4aa09f93e..8275d66e6 100644
--- a/Utilities/cmlibarchive/libarchive/libarchive_internals.3
+++ b/Utilities/cmlibarchive/libarchive/libarchive_internals.3
@@ -347,11 +347,11 @@ Fortunately, such archives are very rare, and libarchive can read
most ZIP archives, though it cannot always extract as much information
as a dedicated ZIP program.
.Sh SEE ALSO
-.Xr archive 3 ,
.Xr archive_entry 3 ,
.Xr archive_read 3 ,
.Xr archive_write 3 ,
.Xr archive_write_disk 3
+.Xr libarchive 3 ,
.Sh HISTORY
The
.Nm libarchive
diff --git a/Utilities/cmlibarchive/libarchive/mtree.5 b/Utilities/cmlibarchive/libarchive/mtree.5
index 983fff723..16c8abec4 100644
--- a/Utilities/cmlibarchive/libarchive/mtree.5
+++ b/Utilities/cmlibarchive/libarchive/mtree.5
@@ -28,7 +28,7 @@
.\" From: @(#)mtree.8 8.2 (Berkeley) 12/11/93
.\" $FreeBSD$
.\"
-.Dd May 6, 2008
+.Dd September 4, 2013
.Dt MTREE 5
.Os
.Sh NAME
@@ -56,14 +56,6 @@ corresponding character.
.Pp
Each line is interpreted independently as one of the following types:
.Bl -tag -width Cm
-.It Signature
-The first line of any mtree file must begin with
-.Dq #mtree .
-If a file contains any full path entries, the first line should
-begin with
-.Dq #mtree v2.0 ,
-otherwise, the first line should begin with
-.Dq #mtree v1.0 .
.It Blank
Blank lines are ignored.
.It Comment
@@ -134,6 +126,52 @@ The checksum of the file using the default algorithm specified by
the
.Xr cksum 1
utility.
+.It Cm device
+The device number for
+.Sy block
+or
+.Sy char
+file types.
+The value must be one of the following forms:
+.Pp
+.Bl -tag -width 4n
+.It Ar format , Ns Ar major , Ns Ar minor Ns Bo , Ns Ar subunit Bc
+A device with
+.Ar major , minor
+and optional
+.Ar subunit
+fields.
+Their meaning is specified by the operating's system
+.Ar format .
+See below for valid formats.
+.It Ar number
+Opaque number (as stored on the file system).
+.El
+.Pp
+The following values for
+.Ar format
+are recognized:
+.Sy native ,
+.Sy 386bsd ,
+.Sy 4bsd ,
+.Sy bsdos ,
+.Sy freebsd ,
+.Sy hpux ,
+.Sy isc ,
+.Sy linux ,
+.Sy netbsd ,
+.Sy osf1 ,
+.Sy sco ,
+.Sy solaris ,
+.Sy sunos ,
+.Sy svr3 ,
+.Sy svr4 ,
+and
+.Sy ultrix .
+.Pp
+See
+.Xr mknod 8
+for more details.
.It Cm contents
The full pathname of a file that holds the contents of this file.
.It Cm flags
@@ -150,6 +188,8 @@ The file group as a numeric value.
The file group as a symbolic name.
.It Cm ignore
Ignore any file hierarchy below this file.
+.It Cm inode
+The inode number.
.It Cm link
The target of the symbolic link when type=link.
.It Cm md5
@@ -164,6 +204,16 @@ value.
The number of hard links the file is expected to have.
.It Cm nochange
Make sure this file or directory exists but otherwise ignore all attributes.
+.It Cm optional
+The file is optional; do not complain about the file if it is not in
+the file hierarchy.
+.It Cm resdevice
+The
+.Dq resident
+device number of the file, e.g. the ID of the device that
+contains the file.
+Its format is the same as the one for
+.Cm device .
.It Cm ripemd160digest
The
.Tn RIPEMD160
@@ -192,6 +242,24 @@ message digest of the file.
.It Cm sha256digest
A synonym for
.Cm sha256 .
+.It Cm sha384
+The
+.Tn FIPS
+180-2
+.Pq Dq Tn SHA-384
+message digest of the file.
+.It Cm sha384digest
+A synonym for
+.Cm sha384 .
+.It Cm sha512
+The
+.Tn FIPS
+180-2
+.Pq Dq Tn SHA-512
+message digest of the file.
+.It Cm sha512digest
+A synonym for
+.Cm sha512 .
.It Cm size
The size, in bytes, of the file.
.It Cm time
@@ -226,16 +294,6 @@ The file owner as a symbolic name.
.Xr find 1 ,
.Xr mtree 8
.Sh BUGS
-The
-.Fx
-implementation of mtree does not currently support
-the
-.Nm
-2.0
-format.
-The requirement for a
-.Dq #mtree
-signature line is new and not yet widely implemented.
.Sh HISTORY
The
.Nm
diff --git a/Utilities/cmlibarchive/libarchive/tar.5 b/Utilities/cmlibarchive/libarchive/tar.5
index 688bb922c..6e6f0c096 100644
--- a/Utilities/cmlibarchive/libarchive/tar.5
+++ b/Utilities/cmlibarchive/libarchive/tar.5
@@ -935,7 +935,7 @@ and formed the basis of
(circa 1988).
Joerg Shilling's
.Nm star
-archiver is another open-source (GPL) archiver (originally developed
+archiver is another open-source (CDDL) archiver (originally developed
circa 1985) which features complete support for pax interchange
format.
.Pp
diff --git a/Utilities/cmlibarchive/libarchive/xxhash.c b/Utilities/cmlibarchive/libarchive/xxhash.c
new file mode 100644
index 000000000..f7647a5e5
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/xxhash.c
@@ -0,0 +1,500 @@
+/*
+xxHash - Fast Hash algorithm
+Copyright (C) 2012-2014, Yann Collet.
+BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+You can contact the author at :
+- xxHash source repository : http://code.google.com/p/xxhash/
+*/
+
+#include "archive_platform.h"
+#ifdef HAVE_LIBLZ4
+
+/***************************************
+** Tuning parameters
+****************************************/
+/* Unaligned memory access is automatically enabled for "common" CPU, such as x86.
+** For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected.
+** If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance.
+** You can also enable this parameter if you know your input data will always be aligned (boundaries of 4, for U32).
+*/
+#if defined(__ARM_FEATURE_UNALIGNED) || defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
+# define XXH_USE_UNALIGNED_ACCESS 1
+#endif
+
+/* XXH_ACCEPT_NULL_INPUT_POINTER :
+** If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer.
+** When this option is enabled, xxHash output for null input pointers will be the same as a null-length input.
+** This option has a very small performance cost (only measurable on small inputs).
+** By default, this option is disabled. To enable it, uncomment below define :
+** #define XXH_ACCEPT_NULL_INPUT_POINTER 1
+
+** XXH_FORCE_NATIVE_FORMAT :
+** By default, xxHash library provides endian-independant Hash values, based on little-endian convention.
+** Results are therefore identical for little-endian and big-endian CPU.
+** This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format.
+** Should endian-independance be of no importance for your application, you may set the #define below to 1.
+** It will improve speed for Big-endian CPU.
+** This option has no impact on Little_Endian CPU.
+*/
+#define XXH_FORCE_NATIVE_FORMAT 0
+
+/***************************************
+** Compiler Specific Options
+****************************************/
+/* Disable some Visual warning messages */
+#ifdef _MSC_VER /* Visual Studio */
+# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
+#endif
+
+#ifdef _MSC_VER /* Visual Studio */
+# define FORCE_INLINE __forceinline
+#else
+# ifdef __GNUC__
+# define FORCE_INLINE inline __attribute__((always_inline))
+# else
+# define FORCE_INLINE inline
+# endif
+#endif
+
+/***************************************
+** Includes & Memory related functions
+****************************************/
+#include "archive_xxhash.h"
+#include <stdlib.h>
+#define XXH_malloc malloc
+#define XXH_free free
+#include <string.h>
+#define XXH_memcpy memcpy
+
+
+static unsigned int XXH32 (const void*, unsigned int, unsigned int);
+static void* XXH32_init (unsigned int);
+static XXH_errorcode XXH32_update (void*, const void*, unsigned int);
+static unsigned int XXH32_digest (void*);
+/*static int XXH32_sizeofState(void);*/
+static XXH_errorcode XXH32_resetState(void*, unsigned int);
+#define XXH32_SIZEOFSTATE 48
+typedef struct { long long ll[(XXH32_SIZEOFSTATE+(sizeof(long long)-1))/sizeof(long long)]; } XXH32_stateSpace_t;
+static unsigned int XXH32_intermediateDigest (void*);
+
+/***************************************
+** Basic Types
+****************************************/
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
+# include <stdint.h>
+ typedef uint8_t BYTE;
+ typedef uint16_t U16;
+ typedef uint32_t U32;
+ typedef int32_t S32;
+ typedef uint64_t U64;
+#else
+ typedef unsigned char BYTE;
+ typedef unsigned short U16;
+ typedef unsigned int U32;
+ typedef signed int S32;
+ typedef unsigned long long U64;
+#endif
+
+#if defined(__GNUC__) && !defined(XXH_USE_UNALIGNED_ACCESS)
+# define _PACKED __attribute__ ((packed))
+#else
+# define _PACKED
+#endif
+
+#if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__)
+# ifdef __IBMC__
+# pragma pack(1)
+# else
+# pragma pack(push, 1)
+# endif
+#endif
+
+typedef struct _U32_S { U32 v; } _PACKED U32_S;
+
+#if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__)
+# pragma pack(pop)
+#endif
+
+#define A32(x) (((const U32_S *)(x))->v)
+
+
+/****************************************
+** Compiler-specific Functions and Macros
+*****************************************/
+#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
+
+/* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */
+#if defined(_MSC_VER)
+# define XXH_rotl32(x,r) _rotl(x,r)
+#else
+# define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r)))
+#endif
+
+#if defined(_MSC_VER) /* Visual Studio */
+# define XXH_swap32 _byteswap_ulong
+#elif GCC_VERSION >= 403
+# define XXH_swap32 __builtin_bswap32
+#else
+static inline U32 XXH_swap32 (U32 x) {
+ return ((x << 24) & 0xff000000 ) |
+ ((x << 8) & 0x00ff0000 ) |
+ ((x >> 8) & 0x0000ff00 ) |
+ ((x >> 24) & 0x000000ff );}
+#endif
+
+
+/***************************************
+** Constants
+****************************************/
+#define PRIME32_1 2654435761U
+#define PRIME32_2 2246822519U
+#define PRIME32_3 3266489917U
+#define PRIME32_4 668265263U
+#define PRIME32_5 374761393U
+
+
+/***************************************
+** Architecture Macros
+****************************************/
+typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;
+#ifndef XXH_CPU_LITTLE_ENDIAN /* It is possible to define XXH_CPU_LITTLE_ENDIAN externally, for example using a compiler switch */
+ static const int one = 1;
+# define XXH_CPU_LITTLE_ENDIAN (*(const char*)(&one))
+#endif
+
+
+/***************************************
+** Macros
+****************************************/
+#define XXH_STATIC_ASSERT(c) { enum { XXH_static_assert = 1/(!!(c)) }; } /* use only *after* variable declarations */
+
+
+/*****************************
+** Memory reads
+******************************/
+typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment;
+
+static
+FORCE_INLINE U32 XXH_readLE32_align(const U32* ptr, XXH_endianess endian, XXH_alignment align)
+{
+ if (align==XXH_unaligned)
+ return endian==XXH_littleEndian ? A32(ptr) : XXH_swap32(A32(ptr));
+ else
+ return endian==XXH_littleEndian ? *ptr : XXH_swap32(*ptr);
+}
+
+static
+FORCE_INLINE U32 XXH_readLE32(const U32* ptr, XXH_endianess endian) { return XXH_readLE32_align(ptr, endian, XXH_unaligned); }
+
+
+/*****************************
+** Simple Hash Functions
+******************************/
+static
+FORCE_INLINE U32 XXH32_endian_align(const void* input, unsigned int len, U32 seed, XXH_endianess endian, XXH_alignment align)
+{
+ const BYTE* p = (const BYTE*)input;
+ const BYTE* bEnd = p + len;
+ U32 h32;
+#define XXH_get32bits(p) XXH_readLE32_align((const U32*)p, endian, align)
+
+#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
+ if (p==NULL) { len=0; bEnd=p=(const BYTE*)(size_t)16; }
+#endif
+
+ if (len>=16)
+ {
+ const BYTE* const limit = bEnd - 16;
+ U32 v1 = seed + PRIME32_1 + PRIME32_2;
+ U32 v2 = seed + PRIME32_2;
+ U32 v3 = seed + 0;
+ U32 v4 = seed - PRIME32_1;
+
+ do
+ {
+ v1 += XXH_get32bits(p) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4;
+ v2 += XXH_get32bits(p) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4;
+ v3 += XXH_get32bits(p) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4;
+ v4 += XXH_get32bits(p) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4;
+ } while (p<=limit);
+
+ h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);
+ }
+ else
+ {
+ h32 = seed + PRIME32_5;
+ }
+
+ h32 += (U32) len;
+
+ while (p<=bEnd-4)
+ {
+ h32 += XXH_get32bits(p) * PRIME32_3;
+ h32 = XXH_rotl32(h32, 17) * PRIME32_4 ;
+ p+=4;
+ }
+
+ while (p<bEnd)
+ {
+ h32 += (*p) * PRIME32_5;
+ h32 = XXH_rotl32(h32, 11) * PRIME32_1 ;
+ p++;
+ }
+
+ h32 ^= h32 >> 15;
+ h32 *= PRIME32_2;
+ h32 ^= h32 >> 13;
+ h32 *= PRIME32_3;
+ h32 ^= h32 >> 16;
+
+ return h32;
+}
+
+
+U32 XXH32(const void* input, unsigned int len, U32 seed)
+{
+#if 0
+ // Simple version, good for code maintenance, but unfortunately slow for small inputs
+ void* state = XXH32_init(seed);
+ XXH32_update(state, input, len);
+ return XXH32_digest(state);
+#else
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
+
+# if !defined(XXH_USE_UNALIGNED_ACCESS)
+ if ((((size_t)input) & 3) == 0) /* Input is aligned, let's leverage the speed advantage */
+ {
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
+ else
+ return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
+ }
+# endif
+
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
+ else
+ return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);
+#endif
+}
+
+/*****************************
+** Advanced Hash Functions
+******************************/
+
+struct XXH_state32_t
+{
+ U64 total_len;
+ U32 seed;
+ U32 v1;
+ U32 v2;
+ U32 v3;
+ U32 v4;
+ int memsize;
+ char memory[16];
+};
+
+#if 0
+static
+int XXH32_sizeofState(void)
+{
+ XXH_STATIC_ASSERT(XXH32_SIZEOFSTATE >= sizeof(struct XXH_state32_t)); /* A compilation error here means XXH32_SIZEOFSTATE is not large enough */
+ return sizeof(struct XXH_state32_t);
+}
+#endif
+
+static
+XXH_errorcode XXH32_resetState(void* state_in, U32 seed)
+{
+ struct XXH_state32_t * state = (struct XXH_state32_t *) state_in;
+ state->seed = seed;
+ state->v1 = seed + PRIME32_1 + PRIME32_2;
+ state->v2 = seed + PRIME32_2;
+ state->v3 = seed + 0;
+ state->v4 = seed - PRIME32_1;
+ state->total_len = 0;
+ state->memsize = 0;
+ return XXH_OK;
+}
+
+static
+void* XXH32_init (U32 seed)
+{
+ void* state = XXH_malloc (sizeof(struct XXH_state32_t));
+ XXH32_resetState(state, seed);
+ return state;
+}
+
+static
+FORCE_INLINE XXH_errorcode XXH32_update_endian (void* state_in, const void* input, int len, XXH_endianess endian)
+{
+ struct XXH_state32_t * state = (struct XXH_state32_t *) state_in;
+ const BYTE* p = (const BYTE*)input;
+ const BYTE* const bEnd = p + len;
+
+#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
+ if (input==NULL) return XXH_ERROR;
+#endif
+
+ state->total_len += len;
+
+ if (state->memsize + len < 16) /* fill in tmp buffer */
+ {
+ XXH_memcpy(state->memory + state->memsize, input, len);
+ state->memsize += len;
+ return XXH_OK;
+ }
+
+ if (state->memsize) /* some data left from previous update */
+ {
+ XXH_memcpy(state->memory + state->memsize, input, 16-state->memsize);
+ {
+ const U32* p32 = (const U32*)state->memory;
+ state->v1 += XXH_readLE32(p32, endian) * PRIME32_2; state->v1 = XXH_rotl32(state->v1, 13); state->v1 *= PRIME32_1; p32++;
+ state->v2 += XXH_readLE32(p32, endian) * PRIME32_2; state->v2 = XXH_rotl32(state->v2, 13); state->v2 *= PRIME32_1; p32++;
+ state->v3 += XXH_readLE32(p32, endian) * PRIME32_2; state->v3 = XXH_rotl32(state->v3, 13); state->v3 *= PRIME32_1; p32++;
+ state->v4 += XXH_readLE32(p32, endian) * PRIME32_2; state->v4 = XXH_rotl32(state->v4, 13); state->v4 *= PRIME32_1; p32++;
+ }
+ p += 16-state->memsize;
+ state->memsize = 0;
+ }
+
+ if (p <= bEnd-16)
+ {
+ const BYTE* const limit = bEnd - 16;
+ U32 v1 = state->v1;
+ U32 v2 = state->v2;
+ U32 v3 = state->v3;
+ U32 v4 = state->v4;
+
+ do
+ {
+ v1 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4;
+ v2 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4;
+ v3 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4;
+ v4 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4;
+ } while (p<=limit);
+
+ state->v1 = v1;
+ state->v2 = v2;
+ state->v3 = v3;
+ state->v4 = v4;
+ }
+
+ if (p < bEnd)
+ {
+ XXH_memcpy(state->memory, p, bEnd-p);
+ state->memsize = (int)(bEnd-p);
+ }
+
+ return XXH_OK;
+}
+
+static
+XXH_errorcode XXH32_update (void* state_in, const void* input, unsigned int len)
+{
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
+
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH32_update_endian(state_in, input, len, XXH_littleEndian);
+ else
+ return XXH32_update_endian(state_in, input, len, XXH_bigEndian);
+}
+
+
+
+static
+FORCE_INLINE U32 XXH32_intermediateDigest_endian (void* state_in, XXH_endianess endian)
+{
+ struct XXH_state32_t * state = (struct XXH_state32_t *) state_in;
+ const BYTE * p = (const BYTE*)state->memory;
+ BYTE* bEnd = (BYTE*)state->memory + state->memsize;
+ U32 h32;
+
+ if (state->total_len >= 16)
+ {
+ h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18);
+ }
+ else
+ {
+ h32 = state->seed + PRIME32_5;
+ }
+
+ h32 += (U32) state->total_len;
+
+ while (p<=bEnd-4)
+ {
+ h32 += XXH_readLE32((const U32*)p, endian) * PRIME32_3;
+ h32 = XXH_rotl32(h32, 17) * PRIME32_4;
+ p+=4;
+ }
+
+ while (p<bEnd)
+ {
+ h32 += (*p) * PRIME32_5;
+ h32 = XXH_rotl32(h32, 11) * PRIME32_1;
+ p++;
+ }
+
+ h32 ^= h32 >> 15;
+ h32 *= PRIME32_2;
+ h32 ^= h32 >> 13;
+ h32 *= PRIME32_3;
+ h32 ^= h32 >> 16;
+
+ return h32;
+}
+
+static
+U32 XXH32_intermediateDigest (void* state_in)
+{
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
+
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH32_intermediateDigest_endian(state_in, XXH_littleEndian);
+ else
+ return XXH32_intermediateDigest_endian(state_in, XXH_bigEndian);
+}
+
+static
+U32 XXH32_digest (void* state_in)
+{
+ U32 h32 = XXH32_intermediateDigest(state_in);
+
+ XXH_free(state_in);
+
+ return h32;
+}
+
+const
+struct archive_xxhash __archive_xxhash = {
+ XXH32,
+ XXH32_init,
+ XXH32_update,
+ XXH32_digest
+};
+#endif /* HAVE_LIBLZ4 */
diff --git a/Utilities/cmliblzma/.gitattributes b/Utilities/cmliblzma/.gitattributes
new file mode 100644
index 000000000..562b12e16
--- /dev/null
+++ b/Utilities/cmliblzma/.gitattributes
@@ -0,0 +1 @@
+* -whitespace
diff --git a/Utilities/cmliblzma/CMakeLists.txt b/Utilities/cmliblzma/CMakeLists.txt
new file mode 100644
index 000000000..89205366f
--- /dev/null
+++ b/Utilities/cmliblzma/CMakeLists.txt
@@ -0,0 +1,224 @@
+PROJECT(CMLIBLZMA C)
+
+include(CheckCSourceCompiles)
+include(CheckIncludeFile)
+include(CheckSymbolExists)
+include(CheckTypeSize)
+include(TestBigEndian)
+
+CHECK_C_SOURCE_COMPILES(
+ "int test (void *restrict x);\nint main (void) {return 0;}"
+ HAVE_RESTRICT)
+
+CHECK_C_SOURCE_COMPILES(
+"typedef struct abc *d;\nint test (d __restrict x);\nint main (void) {return 0;}"
+ HAVE___RESTRICT)
+
+CHECK_C_SOURCE_COMPILES(
+ "inline int test (void) {return 0;}\nint main (void) {return test();}"
+ HAVE_INLINE)
+
+CHECK_C_SOURCE_COMPILES (
+ "__inline int test (void) {return 0;}\nint main (void) {return test();}"
+ HAVE___INLINE)
+
+CHECK_INCLUDE_FILE(byteswap.h HAVE_BYTESWAP_H)
+CHECK_INCLUDE_FILE(inttypes.h HAVE_INTTYPES_H)
+CHECK_INCLUDE_FILE(limits.h HAVE_LIMITS_H)
+CHECK_INCLUDE_FILE(memory.h HAVE_MEMORY_H)
+CHECK_INCLUDE_FILE(strings.h HAVE_STRINGS_H)
+CHECK_INCLUDE_FILE(string.h HAVE_STRING_H)
+CHECK_INCLUDE_FILE(sys/sysctl.h HAVE_SYS_SYSCTL_H)
+
+CHECK_INCLUDE_FILE(stdbool.h HAVE_STDBOOL_H)
+if(NOT HAVE_STDBOOL_H)
+ CHECK_TYPE_SIZE(_Bool _BOOL)
+endif()
+
+CHECK_C_SOURCE_COMPILES (
+ "#include<byteswap.h>\nint main(void){bswap_16(0);return 0;}"
+ HAVE_BSWAP_16)
+CHECK_C_SOURCE_COMPILES (
+ "#include<byteswap.h>\nint main(void){bswap_32(0);return 0;}"
+ HAVE_BSWAP_32)
+CHECK_C_SOURCE_COMPILES (
+ "#include<byteswap.h>\nint main(void){bswap_64(0);return 0;}"
+ HAVE_BSWAP_64)
+
+TEST_BIG_ENDIAN(WORDS_BIGENDIAN)
+
+set(HAVE_CHECK_CRC64 1)
+set(HAVE_CHECK_SHA256 1)
+
+set(HAVE_DECODER_ARM 1)
+set(HAVE_DECODER_ARMTHUMB 1)
+set(HAVE_DECODER_DELTA 1)
+set(HAVE_DECODER_IA64 1)
+set(HAVE_DECODER_LZMA1 1)
+set(HAVE_DECODER_LZMA2 1)
+set(HAVE_DECODER_POWERPC 1)
+set(HAVE_DECODER_SPARC 1)
+set(HAVE_DECODER_X86 1)
+
+set(HAVE_ENCODER_ARM 1)
+set(HAVE_ENCODER_ARMTHUMB 1)
+set(HAVE_ENCODER_DELTA 1)
+set(HAVE_ENCODER_IA64 1)
+set(HAVE_ENCODER_LZMA1 1)
+set(HAVE_ENCODER_LZMA2 1)
+set(HAVE_ENCODER_POWERPC 1)
+set(HAVE_ENCODER_SPARC 1)
+set(HAVE_ENCODER_X86 1)
+
+set(HAVE_MF_BT2 1)
+set(HAVE_MF_BT3 1)
+set(HAVE_MF_BT4 1)
+set(HAVE_MF_HC3 1)
+set(HAVE_MF_HC4 1)
+
+CHECK_TYPE_SIZE(int16_t INT16_T)
+CHECK_TYPE_SIZE(int32_t INT32_T)
+CHECK_TYPE_SIZE(int64_t INT64_T)
+CHECK_TYPE_SIZE(intmax_t INTMAX_T)
+CHECK_TYPE_SIZE(uint8_t UINT8_T)
+CHECK_TYPE_SIZE(uint16_t UINT16_T)
+CHECK_TYPE_SIZE(uint32_t UINT32_T)
+CHECK_TYPE_SIZE(uint64_t UINT64_T)
+CHECK_TYPE_SIZE(uintmax_t UINTMAX_T)
+
+CHECK_TYPE_SIZE("short" SIZE_OF_SHORT)
+CHECK_TYPE_SIZE("int" SIZE_OF_INT)
+CHECK_TYPE_SIZE("long" SIZE_OF_LONG)
+CHECK_TYPE_SIZE("long long" SIZE_OF_LONG_LONG)
+
+CHECK_TYPE_SIZE("unsigned short" SIZE_OF_UNSIGNED_SHORT)
+CHECK_TYPE_SIZE("unsigned" SIZE_OF_UNSIGNED)
+CHECK_TYPE_SIZE("unsigned long" SIZE_OF_UNSIGNED_LONG)
+CHECK_TYPE_SIZE("unsigned long long" SIZE_OF_UNSIGNED_LONG_LONG)
+CHECK_TYPE_SIZE("size_t" SIZE_OF_SIZE_T)
+
+CHECK_TYPE_SIZE("__int64" __INT64)
+CHECK_TYPE_SIZE("unsigned __int64" UNSIGNED___INT64)
+
+CHECK_TYPE_SIZE(uintptr_t UINTPTR_T)
+IF(NOT HAVE_UINTPTR_T)
+ IF("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
+ SET(uintptr_t "uint64_t")
+ ELSE()
+ SET(uintptr_t "uint32_t")
+ ENDIF()
+ENDIF()
+
+
+SET(LZMA_SRCS
+ common/sysdefs.h
+ common/tuklib_integer.h
+ liblzma/check/check.c
+ liblzma/check/crc32_fast.c
+ liblzma/check/crc32_table.c
+ liblzma/check/crc64_fast.c
+ liblzma/check/crc64_table.c
+ liblzma/check/sha256.c
+ liblzma/common/alone_decoder.c
+ liblzma/common/alone_encoder.c
+ liblzma/common/auto_decoder.c
+ liblzma/common/block_buffer_decoder.c
+ liblzma/common/block_buffer_encoder.c
+ liblzma/common/block_decoder.c
+ liblzma/common/block_encoder.c
+ liblzma/common/block_header_decoder.c
+ liblzma/common/block_header_encoder.c
+ liblzma/common/block_util.c
+ liblzma/common/common.c
+ liblzma/common/easy_buffer_encoder.c
+ liblzma/common/easy_decoder_memusage.c
+ liblzma/common/easy_encoder.c
+ liblzma/common/easy_encoder_memusage.c
+ liblzma/common/easy_preset.c
+ liblzma/common/filter_buffer_decoder.c
+ liblzma/common/filter_buffer_encoder.c
+ liblzma/common/filter_common.c
+ liblzma/common/filter_decoder.c
+ liblzma/common/filter_encoder.c
+ liblzma/common/filter_flags_decoder.c
+ liblzma/common/filter_flags_encoder.c
+ liblzma/common/index.c
+ liblzma/common/index_decoder.c
+ liblzma/common/index_encoder.c
+ liblzma/common/index_hash.c
+ liblzma/common/stream_buffer_decoder.c
+ liblzma/common/stream_buffer_encoder.c
+ liblzma/common/stream_decoder.c
+ liblzma/common/stream_encoder.c
+ liblzma/common/stream_flags_common.c
+ liblzma/common/stream_flags_decoder.c
+ liblzma/common/stream_flags_encoder.c
+ liblzma/common/vli_decoder.c
+ liblzma/common/vli_encoder.c
+ liblzma/common/vli_size.c
+ liblzma/delta/delta_common.c
+ liblzma/delta/delta_decoder.c
+ liblzma/delta/delta_encoder.c
+ liblzma/lz/lz_decoder.c
+ liblzma/lz/lz_encoder.c
+ liblzma/lz/lz_encoder_mf.c
+ liblzma/lzma/fastpos_table.c
+ liblzma/lzma/lzma2_decoder.c
+ liblzma/lzma/lzma2_encoder.c
+ liblzma/lzma/lzma_decoder.c
+ liblzma/lzma/lzma_encoder.c
+ liblzma/lzma/lzma_encoder_optimum_fast.c
+ liblzma/lzma/lzma_encoder_optimum_normal.c
+ liblzma/lzma/lzma_encoder_presets.c
+ liblzma/rangecoder/price_table.c
+ liblzma/simple/arm.c
+ liblzma/simple/armthumb.c
+ liblzma/simple/ia64.c
+ liblzma/simple/powerpc.c
+ liblzma/simple/simple_coder.c
+ liblzma/simple/simple_decoder.c
+ liblzma/simple/simple_encoder.c
+ liblzma/simple/sparc.c
+ liblzma/simple/x86.c
+ )
+
+IF(WIN32 AND BUILD_SHARED_LIBS)
+ SET(LZMA_SRCS ${LZMA_SRCS} liblzma/liblzma_w32res.rc)
+ENDIF()
+
+CONFIGURE_FILE(config.h.in config.h @ONLY)
+
+INCLUDE_DIRECTORIES(
+ "${CMLIBLZMA_SOURCE_DIR}/common"
+ "${CMLIBLZMA_SOURCE_DIR}/liblzma/api"
+ "${CMLIBLZMA_SOURCE_DIR}/liblzma/check"
+ "${CMLIBLZMA_SOURCE_DIR}/liblzma/common"
+ "${CMLIBLZMA_SOURCE_DIR}/liblzma/delta"
+ "${CMLIBLZMA_SOURCE_DIR}/liblzma/lz"
+ "${CMLIBLZMA_SOURCE_DIR}/liblzma/lzma"
+ "${CMLIBLZMA_SOURCE_DIR}/liblzma/rangecoder"
+ "${CMLIBLZMA_SOURCE_DIR}/liblzma/simple"
+ "${CMLIBLZMA_BINARY_DIR}"
+ )
+
+# Disable warnings to avoid changing 3rd party code.
+IF(CMAKE_C_COMPILER_ID MATCHES
+ "^(GNU|Clang|AppleClang|XL|VisualAge|SunPro|MIPSpro|HP|Intel)$")
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w")
+ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "PathScale")
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall")
+ENDIF()
+
+ADD_LIBRARY(cmliblzma ${LZMA_SRCS})
+
+IF(CMAKE_C_COMPILER_ID STREQUAL "XL")
+ # Disable the XL compiler optimizer because it causes crashes
+ # and other bad behavior in liblzma code.
+ SET_PROPERTY(TARGET cmliblzma PROPERTY COMPILE_FLAGS "-qnooptimize")
+ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND
+ CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4)
+ # Disable the old GNU compiler optimizer.
+ SET_PROPERTY(TARGET cmliblzma PROPERTY COMPILE_FLAGS "-O0")
+ENDIF()
+
+INSTALL(FILES COPYING DESTINATION ${CMAKE_DOC_DIR}/cmliblzma)
diff --git a/Utilities/cmliblzma/COPYING b/Utilities/cmliblzma/COPYING
new file mode 100644
index 000000000..43c90d059
--- /dev/null
+++ b/Utilities/cmliblzma/COPYING
@@ -0,0 +1,65 @@
+
+XZ Utils Licensing
+==================
+
+ Different licenses apply to different files in this package. Here
+ is a rough summary of which licenses apply to which parts of this
+ package (but check the individual files to be sure!):
+
+ - liblzma is in the public domain.
+
+ - xz, xzdec, and lzmadec command line tools are in the public
+ domain unless GNU getopt_long had to be compiled and linked
+ in from the lib directory. The getopt_long code is under
+ GNU LGPLv2.1+.
+
+ - The scripts to grep, diff, and view compressed files have been
+ adapted from gzip. These scripts and their documentation are
+ under GNU GPLv2+.
+
+ - All the documentation in the doc directory and most of the
+ XZ Utils specific documentation files in other directories
+ are in the public domain.
+
+ - Translated messages are in the public domain.
+
+ - The build system contains public domain files, and files that
+ are under GNU GPLv2+ or GNU GPLv3+. None of these files end up
+ in the binaries being built.
+
+ - Test files and test code in the tests directory, and debugging
+ utilities in the debug directory are in the public domain.
+
+ - The extra directory may contain public domain files, and files
+ that are under various free software licenses.
+
+ You can do whatever you want with the files that have been put into
+ the public domain. If you find public domain legally problematic,
+ take the previous sentence as a license grant. If you still find
+ the lack of copyright legally problematic, you have too many
+ lawyers.
+
+ As usual, this software is provided "as is", without any warranty.
+
+ If you copy significant amounts of public domain code from XZ Utils
+ into your project, acknowledging this somewhere in your software is
+ polite (especially if it is proprietary, non-free software), but
+ naturally it is not legally required. Here is an example of a good
+ notice to put into "about box" or into documentation:
+
+ This software includes code from XZ Utils <http://tukaani.org/xz/>.
+
+ The following license texts are included in the following files:
+ - COPYING.LGPLv2.1: GNU Lesser General Public License version 2.1
+ - COPYING.GPLv2: GNU General Public License version 2
+ - COPYING.GPLv3: GNU General Public License version 3
+
+ Note that the toolchain (compiler, linker etc.) may add some code
+ pieces that are copyrighted. Thus, it is possible that e.g. liblzma
+ binary wouldn't actually be in the public domain in its entirety
+ even though it contains no copyrighted code from the XZ Utils source
+ package.
+
+ If you have questions, don't hesitate to ask the author(s) for more
+ information.
+
diff --git a/Utilities/cmliblzma/README-CMake.txt b/Utilities/cmliblzma/README-CMake.txt
new file mode 100644
index 000000000..b51299707
--- /dev/null
+++ b/Utilities/cmliblzma/README-CMake.txt
@@ -0,0 +1,66 @@
+The Utilities/cmliblzma directory contains a reduced distribution
+of the liblzma source tree with only the library source code and
+CMake build system. It is not a submodule; the actual content is part
+of our source tree and changes can be made and committed directly.
+
+We update from upstream using Git's "subtree" merge strategy. A
+special branch contains commits of upstream liblzma snapshots and
+nothing else. No Git ref points explicitly to the head of this
+branch, but it is merged into our history.
+
+Update liblzma from upstream as follows. Create a local branch to
+explicitly reference the upstream snapshot branch head:
+
+ git branch liblzma-upstream c289e634
+
+Use a temporary directory to checkout the branch:
+
+ mkdir liblzma-tmp
+ cd liblzma-tmp
+ git init
+ git pull .. liblzma-upstream
+ rm -rf *
+
+Now place the (reduced) liblzma content in this directory. See
+instructions shown by
+
+ git log c289e634
+
+for help extracting the content from the upstream svn repo. Then run
+the following commands to commit the new version. Substitute the
+appropriate date and version number:
+
+ git add --all
+
+ GIT_AUTHOR_NAME='liblzma upstream' \
+ GIT_AUTHOR_EMAIL='xz-devel@tukaani.org' \
+ GIT_AUTHOR_DATE='Sun Jun 30 19:55:49 2013 +0300' \
+ git commit -m 'liblzma 5.0.5-gb69900ed (reduced)' &&
+ git commit --amend
+
+Edit the commit message to describe the procedure used to obtain the
+content. Then push the changes back up to the main local repository:
+
+ git push .. HEAD:liblzma-upstream
+ cd ..
+ rm -rf liblzma-tmp
+
+Create a topic in the main repository on which to perform the update:
+
+ git checkout -b update-liblzma master
+
+Merge the liblzma-upstream branch as a subtree:
+
+ git merge -s recursive -X subtree=Utilities/cmliblzma \
+ liblzma-upstream
+
+If there are conflicts, resolve them and commit. Build and test the
+tree. Commit any additional changes needed to succeed.
+
+Finally, run
+
+ git rev-parse --short=8 liblzma-upstream
+
+to get the commit from which the liblzma-upstream branch must be started
+on the next update. Edit the "git branch liblzma-upstream" line above to
+record it, and commit this file.
diff --git a/Utilities/cmliblzma/common/common_w32res.rc b/Utilities/cmliblzma/common/common_w32res.rc
new file mode 100644
index 000000000..fdb88d184
--- /dev/null
+++ b/Utilities/cmliblzma/common/common_w32res.rc
@@ -0,0 +1,50 @@
+/*
+ * Author: Lasse Collin
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ */
+
+#include <winresrc.h>
+#include "config.h"
+#define LZMA_H_INTERNAL
+#define LZMA_H_INTERNAL_RC
+#include "lzma/version.h"
+
+#ifndef MY_BUILD
+# define MY_BUILD 0
+#endif
+#define MY_VERSION LZMA_VERSION_MAJOR,LZMA_VERSION_MINOR,LZMA_VERSION_PATCH,MY_BUILD
+
+#define MY_FILENAME MY_NAME MY_SUFFIX
+#define MY_COMPANY "The Tukaani Project <http://tukaani.org/>"
+#define MY_PRODUCT PACKAGE_NAME " <" PACKAGE_URL ">"
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION MY_VERSION
+ PRODUCTVERSION MY_VERSION
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE MY_TYPE
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", MY_COMPANY
+ VALUE "FileDescription", MY_DESC
+ VALUE "FileVersion", LZMA_VERSION_STRING
+ VALUE "InternalName", MY_NAME
+ VALUE "OriginalFilename", MY_FILENAME
+ VALUE "ProductName", MY_PRODUCT
+ VALUE "ProductVersion", LZMA_VERSION_STRING
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/Utilities/cmliblzma/common/sysdefs.h b/Utilities/cmliblzma/common/sysdefs.h
new file mode 100644
index 000000000..a6edea8b0
--- /dev/null
+++ b/Utilities/cmliblzma/common/sysdefs.h
@@ -0,0 +1,202 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file sysdefs.h
+/// \brief Common includes, definitions, system-specific things etc.
+///
+/// This file is used also by the lzma command line tool, that's why this
+/// file is separate from common.h.
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_SYSDEFS_H
+#define LZMA_SYSDEFS_H
+
+#if defined(_MSC_VER)
+# pragma warning(push,1)
+# pragma warning(disable: 4142) /* benign redefinition of type */
+# pragma warning(disable: 4761) /* integral size mismatch in argument */
+#endif
+
+//////////////
+// Includes //
+//////////////
+
+#include "config.h"
+
+// Get standard-compliant stdio functions under MinGW and MinGW-w64.
+#ifdef __MINGW32__
+# define __USE_MINGW_ANSI_STDIO 1
+#endif
+
+// size_t and NULL
+#include <stddef.h>
+
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+
+// C99 says that inttypes.h always includes stdint.h, but some systems
+// don't do that, and require including stdint.h separately.
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+// Some pre-C99 systems have SIZE_MAX in limits.h instead of stdint.h. The
+// limits are also used to figure out some macros missing from pre-C99 systems.
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+
+
+#if defined(_MSC_VER) && (_MSC_VER < 1310)
+# define UINT64_C(n) n ## ui64
+#endif
+
+
+// Be more compatible with systems that have non-conforming inttypes.h.
+// We assume that int is 32-bit and that long is either 32-bit or 64-bit.
+// Full Autoconf test could be more correct, but this should work well enough.
+// Note that this duplicates some code from lzma.h, but this is better since
+// we can work without inttypes.h thanks to Autoconf tests.
+#ifndef UINT32_C
+# if UINT_MAX != 4294967295U
+# error UINT32_C is not defined and unsigned int is not 32-bit.
+# endif
+# define UINT32_C(n) n ## U
+#endif
+#ifndef UINT32_MAX
+# define UINT32_MAX UINT32_C(4294967295)
+#endif
+#ifndef PRIu32
+# define PRIu32 "u"
+#endif
+#ifndef PRIx32
+# define PRIx32 "x"
+#endif
+#ifndef PRIX32
+# define PRIX32 "X"
+#endif
+
+#if ULONG_MAX == 4294967295UL
+# ifndef UINT64_C
+# define UINT64_C(n) n ## ULL
+# endif
+# ifndef PRIu64
+# define PRIu64 "llu"
+# endif
+# ifndef PRIx64
+# define PRIx64 "llx"
+# endif
+# ifndef PRIX64
+# define PRIX64 "llX"
+# endif
+#else
+# ifndef UINT64_C
+# define UINT64_C(n) n ## UL
+# endif
+# ifndef PRIu64
+# define PRIu64 "lu"
+# endif
+# ifndef PRIx64
+# define PRIx64 "lx"
+# endif
+# ifndef PRIX64
+# define PRIX64 "lX"
+# endif
+#endif
+#ifndef UINT64_MAX
+# define UINT64_MAX UINT64_C(18446744073709551615)
+#endif
+
+// Incorrect(?) SIZE_MAX:
+// - Interix headers typedef size_t to unsigned long,
+// but a few lines later define SIZE_MAX to INT32_MAX.
+// - SCO OpenServer (x86) headers typedef size_t to unsigned int
+// but define SIZE_MAX to INT32_MAX.
+#if defined(__INTERIX) || defined(_SCO_DS)
+# undef SIZE_MAX
+#endif
+
+// The code currently assumes that size_t is either 32-bit or 64-bit.
+#ifndef SIZE_MAX
+# if SIZE_OF_SIZE_T == 4
+# define SIZE_MAX UINT32_MAX
+# elif SIZE_OF_SIZE_T == 8
+# define SIZE_MAX UINT64_MAX
+# else
+# error size_t is not 32-bit or 64-bit
+# endif
+#endif
+#if SIZE_MAX != UINT32_MAX && SIZE_MAX != UINT64_MAX
+# error size_t is not 32-bit or 64-bit
+#endif
+
+#include <stdlib.h>
+#include <assert.h>
+
+// Pre-C99 systems lack stdbool.h. All the code in LZMA Utils must be written
+// so that it works with fake bool type, for example:
+//
+// bool foo = (flags & 0x100) != 0;
+// bool bar = !!(flags & 0x100);
+//
+// This works with the real C99 bool but breaks with fake bool:
+//
+// bool baz = (flags & 0x100);
+//
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# if ! HAVE__BOOL
+typedef unsigned char _Bool;
+# endif
+# define bool _Bool
+# define false 0
+# define true 1
+# define __bool_true_false_are_defined 1
+#endif
+
+// string.h should be enough but let's include strings.h and memory.h too if
+// they exists, since that shouldn't do any harm, but may improve portability.
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif
+
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#ifdef HAVE_MEMORY_H
+# include <memory.h>
+#endif
+
+
+////////////
+// Macros //
+////////////
+
+#undef memzero
+#define memzero(s, n) memset(s, 0, n)
+
+// NOTE: Avoid using MIN() and MAX(), because even conditionally defining
+// those macros can cause some portability trouble, since on some systems
+// the system headers insist defining their own versions.
+#define my_min(x, y) ((x) < (y) ? (x) : (y))
+#define my_max(x, y) ((x) > (y) ? (x) : (y))
+
+#ifndef ARRAY_SIZE
+# define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
+#endif
+
+#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4
+# define lzma_attr_alloc_size(x) __attribute__((__alloc_size__(x)))
+#else
+# define lzma_attr_alloc_size(x)
+#endif
+
+#endif
diff --git a/Utilities/cmliblzma/common/tuklib_integer.h b/Utilities/cmliblzma/common/tuklib_integer.h
new file mode 100644
index 000000000..5e8262a11
--- /dev/null
+++ b/Utilities/cmliblzma/common/tuklib_integer.h
@@ -0,0 +1,514 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file tuklib_integer.h
+/// \brief Various integer and bit operations
+///
+/// This file provides macros or functions to do some basic integer and bit
+/// operations.
+///
+/// Endianness related integer operations (XX = 16, 32, or 64; Y = b or l):
+/// - Byte swapping: bswapXX(num)
+/// - Byte order conversions to/from native: convXXYe(num)
+/// - Aligned reads: readXXYe(ptr)
+/// - Aligned writes: writeXXYe(ptr, num)
+/// - Unaligned reads (16/32-bit only): unaligned_readXXYe(ptr)
+/// - Unaligned writes (16/32-bit only): unaligned_writeXXYe(ptr, num)
+///
+/// Since they can macros, the arguments should have no side effects since
+/// they may be evaluated more than once.
+///
+/// \todo PowerPC and possibly some other architectures support
+/// byte swapping load and store instructions. This file
+/// doesn't take advantage of those instructions.
+///
+/// Bit scan operations for non-zero 32-bit integers:
+/// - Bit scan reverse (find highest non-zero bit): bsr32(num)
+/// - Count leading zeros: clz32(num)
+/// - Count trailing zeros: ctz32(num)
+/// - Bit scan forward (simply an alias for ctz32()): bsf32(num)
+///
+/// The above bit scan operations return 0-31. If num is zero,
+/// the result is undefined.
+//
+// Authors: Lasse Collin
+// Joachim Henke
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef TUKLIB_INTEGER_H
+#define TUKLIB_INTEGER_H
+
+#include "sysdefs.h"
+
+#if defined(__GNUC__) && defined(__GNUC_MINOR__)
+# define TUKLIB_GNUC_REQ(major, minor) \
+ ((__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)) \
+ || __GNUC__ > (major))
+#else
+# define TUKLIB_GNUC_REQ(major, minor) 0
+#endif
+
+
+////////////////////////////////////////
+// Operating system specific features //
+////////////////////////////////////////
+
+#if defined(HAVE_BYTESWAP_H)
+ // glibc, uClibc, dietlibc
+# include <byteswap.h>
+# ifdef HAVE_BSWAP_16
+# define bswap16(num) bswap_16(num)
+# endif
+# ifdef HAVE_BSWAP_32
+# define bswap32(num) bswap_32(num)
+# endif
+# ifdef HAVE_BSWAP_64
+# define bswap64(num) bswap_64(num)
+# endif
+
+#elif defined(HAVE_SYS_ENDIAN_H)
+ // *BSDs and Darwin
+# include <sys/endian.h>
+
+#elif defined(HAVE_SYS_BYTEORDER_H)
+ // Solaris
+# include <sys/byteorder.h>
+# ifdef BSWAP_16
+# define bswap16(num) BSWAP_16(num)
+# endif
+# ifdef BSWAP_32
+# define bswap32(num) BSWAP_32(num)
+# endif
+# ifdef BSWAP_64
+# define bswap64(num) BSWAP_64(num)
+# endif
+# ifdef BE_16
+# define conv16be(num) BE_16(num)
+# endif
+# ifdef BE_32
+# define conv32be(num) BE_32(num)
+# endif
+# ifdef BE_64
+# define conv64be(num) BE_64(num)
+# endif
+# ifdef LE_16
+# define conv16le(num) LE_16(num)
+# endif
+# ifdef LE_32
+# define conv32le(num) LE_32(num)
+# endif
+# ifdef LE_64
+# define conv64le(num) LE_64(num)
+# endif
+#endif
+
+
+///////////////////
+// Byte swapping //
+///////////////////
+
+#ifndef bswap16
+# define bswap16(num) \
+ (((uint16_t)(num) << 8) | ((uint16_t)(num) >> 8))
+#endif
+
+#ifndef bswap32
+# define bswap32(num) \
+ ( (((uint32_t)(num) << 24) ) \
+ | (((uint32_t)(num) << 8) & UINT32_C(0x00FF0000)) \
+ | (((uint32_t)(num) >> 8) & UINT32_C(0x0000FF00)) \
+ | (((uint32_t)(num) >> 24) ) )
+#endif
+
+#ifndef bswap64
+# define bswap64(num) \
+ ( (((uint64_t)(num) << 56) ) \
+ | (((uint64_t)(num) << 40) & UINT64_C(0x00FF000000000000)) \
+ | (((uint64_t)(num) << 24) & UINT64_C(0x0000FF0000000000)) \
+ | (((uint64_t)(num) << 8) & UINT64_C(0x000000FF00000000)) \
+ | (((uint64_t)(num) >> 8) & UINT64_C(0x00000000FF000000)) \
+ | (((uint64_t)(num) >> 24) & UINT64_C(0x0000000000FF0000)) \
+ | (((uint64_t)(num) >> 40) & UINT64_C(0x000000000000FF00)) \
+ | (((uint64_t)(num) >> 56) ) )
+#endif
+
+// Define conversion macros using the basic byte swapping macros.
+#ifdef WORDS_BIGENDIAN
+# ifndef conv16be
+# define conv16be(num) ((uint16_t)(num))
+# endif
+# ifndef conv32be
+# define conv32be(num) ((uint32_t)(num))
+# endif
+# ifndef conv64be
+# define conv64be(num) ((uint64_t)(num))
+# endif
+# ifndef conv16le
+# define conv16le(num) bswap16(num)
+# endif
+# ifndef conv32le
+# define conv32le(num) bswap32(num)
+# endif
+# ifndef conv64le
+# define conv64le(num) bswap64(num)
+# endif
+#else
+# ifndef conv16be
+# define conv16be(num) bswap16(num)
+# endif
+# ifndef conv32be
+# define conv32be(num) bswap32(num)
+# endif
+# ifndef conv64be
+# define conv64be(num) bswap64(num)
+# endif
+# ifndef conv16le
+# define conv16le(num) ((uint16_t)(num))
+# endif
+# ifndef conv32le
+# define conv32le(num) ((uint32_t)(num))
+# endif
+# ifndef conv64le
+# define conv64le(num) ((uint64_t)(num))
+# endif
+#endif
+
+
+//////////////////////////////
+// Aligned reads and writes //
+//////////////////////////////
+
+static inline uint16_t
+read16be(const uint8_t *buf)
+{
+ uint16_t num = *(const uint16_t *)buf;
+ return conv16be(num);
+}
+
+
+static inline uint16_t
+read16le(const uint8_t *buf)
+{
+ uint16_t num = *(const uint16_t *)buf;
+ return conv16le(num);
+}
+
+
+static inline uint32_t
+read32be(const uint8_t *buf)
+{
+ uint32_t num = *(const uint32_t *)buf;
+ return conv32be(num);
+}
+
+
+static inline uint32_t
+read32le(const uint8_t *buf)
+{
+ uint32_t num = *(const uint32_t *)buf;
+ return conv32le(num);
+}
+
+
+static inline uint64_t
+read64be(const uint8_t *buf)
+{
+ uint64_t num = *(const uint64_t *)buf;
+ return conv64be(num);
+}
+
+
+static inline uint64_t
+read64le(const uint8_t *buf)
+{
+ uint64_t num = *(const uint64_t *)buf;
+ return conv64le(num);
+}
+
+
+// NOTE: Possible byte swapping must be done in a macro to allow GCC
+// to optimize byte swapping of constants when using glibc's or *BSD's
+// byte swapping macros. The actual write is done in an inline function
+// to make type checking of the buf pointer possible similarly to readXXYe()
+// functions.
+
+#define write16be(buf, num) write16ne((buf), conv16be(num))
+#define write16le(buf, num) write16ne((buf), conv16le(num))
+#define write32be(buf, num) write32ne((buf), conv32be(num))
+#define write32le(buf, num) write32ne((buf), conv32le(num))
+#define write64be(buf, num) write64ne((buf), conv64be(num))
+#define write64le(buf, num) write64ne((buf), conv64le(num))
+
+
+static inline void
+write16ne(uint8_t *buf, uint16_t num)
+{
+ *(uint16_t *)buf = num;
+ return;
+}
+
+
+static inline void
+write32ne(uint8_t *buf, uint32_t num)
+{
+ *(uint32_t *)buf = num;
+ return;
+}
+
+
+static inline void
+write64ne(uint8_t *buf, uint64_t num)
+{
+ *(uint64_t *)buf = num;
+ return;
+}
+
+
+////////////////////////////////
+// Unaligned reads and writes //
+////////////////////////////////
+
+// NOTE: TUKLIB_FAST_UNALIGNED_ACCESS indicates only support for 16-bit and
+// 32-bit unaligned integer loads and stores. It's possible that 64-bit
+// unaligned access doesn't work or is slower than byte-by-byte access.
+// Since unaligned 64-bit is probably not needed as often as 16-bit or
+// 32-bit, we simply don't support 64-bit unaligned access for now.
+#ifdef TUKLIB_FAST_UNALIGNED_ACCESS
+# define unaligned_read16be read16be
+# define unaligned_read16le read16le
+# define unaligned_read32be read32be
+# define unaligned_read32le read32le
+# define unaligned_write16be write16be
+# define unaligned_write16le write16le
+# define unaligned_write32be write32be
+# define unaligned_write32le write32le
+
+#else
+
+static inline uint16_t
+unaligned_read16be(const uint8_t *buf)
+{
+ uint16_t num = ((uint16_t)buf[0] << 8) | (uint16_t)buf[1];
+ return num;
+}
+
+
+static inline uint16_t
+unaligned_read16le(const uint8_t *buf)
+{
+ uint16_t num = ((uint16_t)buf[0]) | ((uint16_t)buf[1] << 8);
+ return num;
+}
+
+
+static inline uint32_t
+unaligned_read32be(const uint8_t *buf)
+{
+ uint32_t num = (uint32_t)buf[0] << 24;
+ num |= (uint32_t)buf[1] << 16;
+ num |= (uint32_t)buf[2] << 8;
+ num |= (uint32_t)buf[3];
+ return num;
+}
+
+
+static inline uint32_t
+unaligned_read32le(const uint8_t *buf)
+{
+ uint32_t num = (uint32_t)buf[0];
+ num |= (uint32_t)buf[1] << 8;
+ num |= (uint32_t)buf[2] << 16;
+ num |= (uint32_t)buf[3] << 24;
+ return num;
+}
+
+
+static inline void
+unaligned_write16be(uint8_t *buf, uint16_t num)
+{
+ buf[0] = num >> 8;
+ buf[1] = num;
+ return;
+}
+
+
+static inline void
+unaligned_write16le(uint8_t *buf, uint16_t num)
+{
+ buf[0] = num;
+ buf[1] = num >> 8;
+ return;
+}
+
+
+static inline void
+unaligned_write32be(uint8_t *buf, uint32_t num)
+{
+ buf[0] = num >> 24;
+ buf[1] = num >> 16;
+ buf[2] = num >> 8;
+ buf[3] = num;
+ return;
+}
+
+
+static inline void
+unaligned_write32le(uint8_t *buf, uint32_t num)
+{
+ buf[0] = num;
+ buf[1] = num >> 8;
+ buf[2] = num >> 16;
+ buf[3] = num >> 24;
+ return;
+}
+
+#endif
+
+
+static inline uint32_t
+bsr32(uint32_t n)
+{
+ // Check for ICC first, since it tends to define __GNUC__ too.
+#if defined(__INTEL_COMPILER)
+ return _bit_scan_reverse(n);
+
+#elif TUKLIB_GNUC_REQ(3, 4) && UINT_MAX == UINT32_MAX
+ // GCC >= 3.4 has __builtin_clz(), which gives good results on
+ // multiple architectures. On x86, __builtin_clz() ^ 31U becomes
+ // either plain BSR (so the XOR gets optimized away) or LZCNT and
+ // XOR (if -march indicates that SSE4a instructions are supported).
+ return __builtin_clz(n) ^ 31U;
+
+#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+ uint32_t i;
+ __asm__("bsrl %1, %0" : "=r" (i) : "rm" (n));
+ return i;
+
+#else
+ uint32_t i = 31;
+
+ if ((n & UINT32_C(0xFFFF0000)) == 0) {
+ n <<= 16;
+ i = 15;
+ }
+
+ if ((n & UINT32_C(0xFF000000)) == 0) {
+ n <<= 8;
+ i -= 8;
+ }
+
+ if ((n & UINT32_C(0xF0000000)) == 0) {
+ n <<= 4;
+ i -= 4;
+ }
+
+ if ((n & UINT32_C(0xC0000000)) == 0) {
+ n <<= 2;
+ i -= 2;
+ }
+
+ if ((n & UINT32_C(0x80000000)) == 0)
+ --i;
+
+ return i;
+#endif
+}
+
+
+static inline uint32_t
+clz32(uint32_t n)
+{
+#if defined(__INTEL_COMPILER)
+ return _bit_scan_reverse(n) ^ 31U;
+
+#elif TUKLIB_GNUC_REQ(3, 4) && UINT_MAX == UINT32_MAX
+ return __builtin_clz(n);
+
+#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+ uint32_t i;
+ __asm__("bsrl %1, %0\n\t"
+ "xorl $31, %0"
+ : "=r" (i) : "rm" (n));
+ return i;
+
+#else
+ uint32_t i = 0;
+
+ if ((n & UINT32_C(0xFFFF0000)) == 0) {
+ n <<= 16;
+ i = 16;
+ }
+
+ if ((n & UINT32_C(0xFF000000)) == 0) {
+ n <<= 8;
+ i += 8;
+ }
+
+ if ((n & UINT32_C(0xF0000000)) == 0) {
+ n <<= 4;
+ i += 4;
+ }
+
+ if ((n & UINT32_C(0xC0000000)) == 0) {
+ n <<= 2;
+ i += 2;
+ }
+
+ if ((n & UINT32_C(0x80000000)) == 0)
+ ++i;
+
+ return i;
+#endif
+}
+
+
+static inline uint32_t
+ctz32(uint32_t n)
+{
+#if defined(__INTEL_COMPILER)
+ return _bit_scan_forward(n);
+
+#elif TUKLIB_GNUC_REQ(3, 4) && UINT_MAX >= UINT32_MAX
+ return __builtin_ctz(n);
+
+#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+ uint32_t i;
+ __asm__("bsfl %1, %0" : "=r" (i) : "rm" (n));
+ return i;
+
+#else
+ uint32_t i = 0;
+
+ if ((n & UINT32_C(0x0000FFFF)) == 0) {
+ n >>= 16;
+ i = 16;
+ }
+
+ if ((n & UINT32_C(0x000000FF)) == 0) {
+ n >>= 8;
+ i += 8;
+ }
+
+ if ((n & UINT32_C(0x0000000F)) == 0) {
+ n >>= 4;
+ i += 4;
+ }
+
+ if ((n & UINT32_C(0x00000003)) == 0) {
+ n >>= 2;
+ i += 2;
+ }
+
+ if ((n & UINT32_C(0x00000001)) == 0)
+ ++i;
+
+ return i;
+#endif
+}
+
+#define bsf32 ctz32
+
+#endif
diff --git a/Utilities/cmliblzma/config.h.in b/Utilities/cmliblzma/config.h.in
new file mode 100644
index 000000000..9c53150bf
--- /dev/null
+++ b/Utilities/cmliblzma/config.h.in
@@ -0,0 +1,289 @@
+
+/*
+ * Ensure we have C99-style int64_t, etc, all defined.
+ */
+
+/* First, we need to know if the system has already defined them. */
+#cmakedefine HAVE_INT16_T
+#cmakedefine HAVE_INT32_T
+#cmakedefine HAVE_INT64_T
+#cmakedefine HAVE_INTMAX_T
+
+#cmakedefine HAVE_UINT8_T
+#cmakedefine HAVE_UINT16_T
+#cmakedefine HAVE_UINT32_T
+#cmakedefine HAVE_UINT64_T
+#cmakedefine HAVE_UINTMAX_T
+
+/* We might have the types we want under other spellings. */
+#cmakedefine HAVE___INT64
+#cmakedefine HAVE_U_INT64_T
+#cmakedefine HAVE_UNSIGNED___INT64
+
+/* The sizes of various standard integer types. */
+@SIZE_OF_SHORT_CODE@
+@SIZE_OF_INT_CODE@
+@SIZE_OF_LONG_CODE@
+@SIZE_OF_LONG_LONG_CODE@
+@SIZE_OF_UNSIGNED_SHORT_CODE@
+@SIZE_OF_UNSIGNED_CODE@
+@SIZE_OF_UNSIGNED_LONG_CODE@
+@SIZE_OF_UNSIGNED_LONG_LONG_CODE@
+@SIZE_OF_SIZE_T_CODE@
+
+/*
+ * If we lack int64_t, define it to the first of __int64, int, long, and long long
+ * that exists and is the right size.
+ */
+#if !defined(HAVE_INT64_T) && defined(HAVE___INT64)
+typedef __int64 int64_t;
+#define HAVE_INT64_T
+#endif
+
+#if !defined(HAVE_INT64_T) && SIZE_OF_INT == 8
+typedef int int64_t;
+#define HAVE_INT64_T
+#endif
+
+#if !defined(HAVE_INT64_T) && SIZE_OF_LONG == 8
+typedef long int64_t;
+#define HAVE_INT64_T
+#endif
+
+#if !defined(HAVE_INT64_T) && SIZE_OF_LONG_LONG == 8
+typedef long long int64_t;
+#define HAVE_INT64_T
+#endif
+
+#if !defined(HAVE_INT64_T)
+#error No 64-bit integer type was found.
+#endif
+
+/*
+ * Similarly for int32_t
+ */
+#if !defined(HAVE_INT32_T) && SIZE_OF_INT == 4
+typedef int int32_t;
+#define HAVE_INT32_T
+#endif
+
+#if !defined(HAVE_INT32_T) && SIZE_OF_LONG == 4
+typedef long int32_t;
+#define HAVE_INT32_T
+#endif
+
+#if !defined(HAVE_INT32_T)
+#error No 32-bit integer type was found.
+#endif
+
+/*
+ * Similarly for int16_t
+ */
+#if !defined(HAVE_INT16_T) && SIZE_OF_INT == 2
+typedef int int16_t;
+#define HAVE_INT16_T
+#endif
+
+#if !defined(HAVE_INT16_T) && SIZE_OF_SHORT == 2
+typedef short int16_t;
+#define HAVE_INT16_T
+#endif
+
+#if !defined(HAVE_INT16_T)
+#error No 16-bit integer type was found.
+#endif
+
+/*
+ * Similarly for uint64_t
+ */
+#if !defined(HAVE_UINT64_T) && defined(HAVE_UNSIGNED___INT64)
+typedef unsigned __int64 uint64_t;
+#define HAVE_UINT64_T
+#endif
+
+#if !defined(HAVE_UINT64_T) && SIZE_OF_UNSIGNED == 8
+typedef unsigned uint64_t;
+#define HAVE_UINT64_T
+#endif
+
+#if !defined(HAVE_UINT64_T) && SIZE_OF_UNSIGNED_LONG == 8
+typedef unsigned long uint64_t;
+#define HAVE_UINT64_T
+#endif
+
+#if !defined(HAVE_UINT64_T) && SIZE_OF_UNSIGNED_LONG_LONG == 8
+typedef unsigned long long uint64_t;
+#define HAVE_UINT64_T
+#endif
+
+#if !defined(HAVE_UINT64_T)
+#error No 64-bit unsigned integer type was found.
+#endif
+
+/*
+ * Similarly for uint32_t
+ */
+#if !defined(HAVE_UINT32_T) && SIZE_OF_UNSIGNED == 4
+typedef unsigned uint32_t;
+#define HAVE_UINT32_T
+#endif
+
+#if !defined(HAVE_UINT32_T) && SIZE_OF_UNSIGNED_LONG == 4
+typedef unsigned long uint32_t;
+#define HAVE_UINT32_T
+#endif
+
+#if !defined(HAVE_UINT32_T)
+#error No 32-bit unsigned integer type was found.
+#endif
+
+/*
+ * Similarly for uint16_t
+ */
+#if !defined(HAVE_UINT16_T) && SIZE_OF_UNSIGNED == 2
+typedef unsigned uint16_t;
+#define HAVE_UINT16_T
+#endif
+
+#if !defined(HAVE_UINT16_T) && SIZE_OF_UNSIGNED_SHORT == 2
+typedef unsigned short uint16_t;
+#define HAVE_UINT16_T
+#endif
+
+#if !defined(HAVE_UINT16_T)
+#error No 16-bit unsigned integer type was found.
+#endif
+
+/*
+ * Similarly for uint8_t
+ */
+#if !defined(HAVE_UINT8_T)
+typedef unsigned char uint8_t;
+#define HAVE_UINT8_T
+#endif
+
+#if !defined(HAVE_UINT16_T)
+#error No 8-bit unsigned integer type was found.
+#endif
+
+/* Define intmax_t and uintmax_t if they are not already defined. */
+#if !defined(HAVE_INTMAX_T)
+typedef int64_t intmax_t;
+#define INTMAX_MIN INT64_MIN
+#define INTMAX_MAX INT64_MAX
+#endif
+
+#if !defined(HAVE_UINTMAX_T)
+typedef uint64_t uintmax_t;
+#endif
+
+
+#cmakedefine uintptr_t @uintptr_t@
+
+
+#cmakedefine HAVE_RESTRICT
+#cmakedefine HAVE___RESTRICT
+
+#cmakedefine HAVE_INLINE
+#cmakedefine HAVE___INLINE
+
+#ifndef HAVE_RESTRICT
+# ifdef HAVE___RESTRICT
+# define LZMA_RESTRICT __restrict
+# else
+# define LZMA_RESTRICT
+# endif
+#else
+# define LZMA_RESTRICT restrict
+#endif /* HAVE_RESTRICT */
+
+#ifndef HAVE_INLINE
+# ifdef HAVE___INLINE
+# define inline __inline
+# else
+# define inline
+# endif
+#endif /* HAVE_INLINE */
+
+
+#cmakedefine WORDS_BIGENDIAN 1
+
+#cmakedefine HAVE_BYTESWAP_H 1
+#cmakedefine HAVE_BSWAP_16 1
+#cmakedefine HAVE_BSWAP_32 1
+#cmakedefine HAVE_BSWAP_64 1
+
+
+#define HAVE_CHECK_CRC32 1
+#define HAVE_CHECK_CRC64 1
+#define HAVE_CHECK_SHA256 1
+
+#define HAVE_DECODER_ARM 1
+#define HAVE_DECODER_ARMTHUMB 1
+#define HAVE_DECODER_DELTA 1
+#define HAVE_DECODER_IA64 1
+#define HAVE_DECODER_LZMA1 1
+#define HAVE_DECODER_LZMA2 1
+#define HAVE_DECODER_POWERPC 1
+#define HAVE_DECODER_SPARC 1
+#define HAVE_DECODER_X86 1
+
+#define HAVE_ENCODER_ARM 1
+#define HAVE_ENCODER_ARMTHUMB 1
+#define HAVE_ENCODER_DELTA 1
+#define HAVE_ENCODER_IA64 1
+#define HAVE_ENCODER_LZMA1 1
+#define HAVE_ENCODER_LZMA2 1
+#define HAVE_ENCODER_POWERPC 1
+#define HAVE_ENCODER_SPARC 1
+#define HAVE_ENCODER_X86 1
+
+#define HAVE_MF_BT2 1
+#define HAVE_MF_BT3 1
+#define HAVE_MF_BT4 1
+#define HAVE_MF_HC3 1
+#define HAVE_MF_HC4 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#cmakedefine HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <limits.h> header file. */
+#cmakedefine HAVE_LIMITS_H 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#cmakedefine HAVE_MEMORY_H 1
+
+/* Define to 1 if stdbool.h conforms to C99. */
+#cmakedefine HAVE_STDBOOL_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#cmakedefine HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#cmakedefine HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#cmakedefine HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/byteorder.h> header file. */
+#cmakedefine HAVE_SYS_BYTEORDER_H 1
+
+/* Define to 1 if you have the <sys/endian.h> header file. */
+#cmakedefine HAVE_SYS_ENDIAN_H 1
+
+/* Define to 1 or 0, depending whether the compiler supports simple visibility
+ declarations. */
+#cmakedefine HAVE_VISIBILITY 1
+
+/* Define to 1 if the system has the type `_Bool'. */
+#cmakedefine HAVE__BOOL 1
+
+/* Define to 1 if the system supports fast unaligned access to 16-bit and
+ 32-bit integers. */
+#if defined(__i386) || defined(__i386__) || defined(_M_IX86) \
+ || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) \
+ || defined(__amd64) || defined(__amd64__) \
+ || defined(__powerpc) || defined(__powerpc__) \
+ || defined(__ppc) || defined(__ppc__) || defined(__POWERPC__)
+# define TUKLIB_FAST_UNALIGNED_ACCESS 1
+#endif
diff --git a/Utilities/cmliblzma/liblzma/api/lzma.h b/Utilities/cmliblzma/liblzma/api/lzma.h
new file mode 100644
index 000000000..fb874c3e1
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/api/lzma.h
@@ -0,0 +1,313 @@
+/**
+ * \file api/lzma.h
+ * \brief The public API of liblzma data compression library
+ *
+ * liblzma is a public domain general-purpose data compression library with
+ * a zlib-like API. The native file format is .xz, but also the old .lzma
+ * format and raw (no headers) streams are supported. Multiple compression
+ * algorithms (filters) are supported. Currently LZMA2 is the primary filter.
+ *
+ * liblzma is part of XZ Utils <http://tukaani.org/xz/>. XZ Utils includes
+ * a gzip-like command line tool named xz and some other tools. XZ Utils
+ * is developed and maintained by Lasse Collin.
+ *
+ * Major parts of liblzma are based on Igor Pavlov's public domain LZMA SDK
+ * <http://7-zip.org/sdk.html>.
+ *
+ * The SHA-256 implementation is based on the public domain code found from
+ * 7-Zip <http://7-zip.org/>, which has a modified version of the public
+ * domain SHA-256 code found from Crypto++ <http://www.cryptopp.com/>.
+ * The SHA-256 code in Crypto++ was written by Kevin Springle and Wei Dai.
+ */
+
+/*
+ * Author: Lasse Collin
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ */
+
+#ifndef LZMA_H
+#define LZMA_H
+
+/*****************************
+ * Required standard headers *
+ *****************************/
+
+/*
+ * liblzma API headers need some standard types and macros. To allow
+ * including lzma.h without requiring the application to include other
+ * headers first, lzma.h includes the required standard headers unless
+ * they already seem to be included already or if LZMA_MANUAL_HEADERS
+ * has been defined.
+ *
+ * Here's what types and macros are needed and from which headers:
+ * - stddef.h: size_t, NULL
+ * - stdint.h: uint8_t, uint32_t, uint64_t, UINT32_C(n), uint64_C(n),
+ * UINT32_MAX, UINT64_MAX
+ *
+ * However, inttypes.h is a little more portable than stdint.h, although
+ * inttypes.h declares some unneeded things compared to plain stdint.h.
+ *
+ * The hacks below aren't perfect, specifically they assume that inttypes.h
+ * exists and that it typedefs at least uint8_t, uint32_t, and uint64_t,
+ * and that, in case of incomplete inttypes.h, unsigned int is 32-bit.
+ * If the application already takes care of setting up all the types and
+ * macros properly (for example by using gnulib's stdint.h or inttypes.h),
+ * we try to detect that the macros are already defined and don't include
+ * inttypes.h here again. However, you may define LZMA_MANUAL_HEADERS to
+ * force this file to never include any system headers.
+ *
+ * Some could argue that liblzma API should provide all the required types,
+ * for example lzma_uint64, LZMA_UINT64_C(n), and LZMA_UINT64_MAX. This was
+ * seen as an unnecessary mess, since most systems already provide all the
+ * necessary types and macros in the standard headers.
+ *
+ * Note that liblzma API still has lzma_bool, because using stdbool.h would
+ * break C89 and C++ programs on many systems. sizeof(bool) in C99 isn't
+ * necessarily the same as sizeof(bool) in C++.
+ */
+
+#ifndef LZMA_MANUAL_HEADERS
+ /*
+ * I suppose this works portably also in C++. Note that in C++,
+ * we need to get size_t into the global namespace.
+ */
+# include <stddef.h>
+
+ /*
+ * Skip inttypes.h if we already have all the required macros. If we
+ * have the macros, we assume that we have the matching typedefs too.
+ */
+# if !defined(UINT32_C) || !defined(UINT64_C) \
+ || !defined(UINT32_MAX) || !defined(UINT64_MAX)
+ /*
+ * MSVC has no C99 support, and thus it cannot be used to
+ * compile liblzma. The liblzma API has to still be usable
+ * from MSVC, so we need to define the required standard
+ * integer types here.
+ */
+# if defined(_WIN32) && defined(_MSC_VER)
+ typedef unsigned __int8 uint8_t;
+ typedef unsigned __int32 uint32_t;
+ typedef unsigned __int64 uint64_t;
+# else
+ /* Use the standard inttypes.h. */
+# ifdef __cplusplus
+ /*
+ * C99 sections 7.18.2 and 7.18.4 specify
+ * that C++ implementations define the limit
+ * and constant macros only if specifically
+ * requested. Note that if you want the
+ * format macros (PRIu64 etc.) too, you need
+ * to define __STDC_FORMAT_MACROS before
+ * including lzma.h, since re-including
+ * inttypes.h with __STDC_FORMAT_MACROS
+ * defined doesn't necessarily work.
+ */
+# ifndef __STDC_LIMIT_MACROS
+# define __STDC_LIMIT_MACROS 1
+# endif
+# ifndef __STDC_CONSTANT_MACROS
+# define __STDC_CONSTANT_MACROS 1
+# endif
+# endif
+
+# include <inttypes.h>
+# endif
+
+ /*
+ * Some old systems have only the typedefs in inttypes.h, and
+ * lack all the macros. For those systems, we need a few more
+ * hacks. We assume that unsigned int is 32-bit and unsigned
+ * long is either 32-bit or 64-bit. If these hacks aren't
+ * enough, the application has to setup the types manually
+ * before including lzma.h.
+ */
+# ifndef UINT32_C
+# if defined(_WIN32) && defined(_MSC_VER)
+# define UINT32_C(n) n ## UI32
+# else
+# define UINT32_C(n) n ## U
+# endif
+# endif
+
+# ifndef UINT64_C
+# if defined(_WIN32) && defined(_MSC_VER)
+# define UINT64_C(n) n ## UI64
+# else
+ /* Get ULONG_MAX. */
+# include <limits.h>
+# if ULONG_MAX == 4294967295UL
+# define UINT64_C(n) n ## ULL
+# else
+# define UINT64_C(n) n ## UL
+# endif
+# endif
+# endif
+
+# ifndef UINT32_MAX
+# define UINT32_MAX (UINT32_C(4294967295))
+# endif
+
+# ifndef UINT64_MAX
+# define UINT64_MAX (UINT64_C(18446744073709551615))
+# endif
+# endif
+#endif /* ifdef LZMA_MANUAL_HEADERS */
+
+
+/******************
+ * LZMA_API macro *
+ ******************/
+
+/*
+ * Some systems require that the functions and function pointers are
+ * declared specially in the headers. LZMA_API_IMPORT is for importing
+ * symbols and LZMA_API_CALL is to specify the calling convention.
+ *
+ * By default it is assumed that the application will link dynamically
+ * against liblzma. #define LZMA_API_STATIC in your application if you
+ * want to link against static liblzma. If you don't care about portability
+ * to operating systems like Windows, or at least don't care about linking
+ * against static liblzma on them, don't worry about LZMA_API_STATIC. That
+ * is, most developers will never need to use LZMA_API_STATIC.
+ *
+ * The GCC variants are a special case on Windows (Cygwin and MinGW).
+ * We rely on GCC doing the right thing with its auto-import feature,
+ * and thus don't use __declspec(dllimport). This way developers don't
+ * need to worry about LZMA_API_STATIC. Also the calling convention is
+ * omitted on Cygwin but not on MinGW.
+ */
+#ifndef LZMA_API_IMPORT
+# if !defined(LZMA_API_STATIC) && defined(_WIN32) && !defined(__GNUC__)
+# define LZMA_API_IMPORT __declspec(dllimport)
+# else
+# define LZMA_API_IMPORT
+# endif
+#endif
+
+#ifndef LZMA_API_CALL
+# if defined(_WIN32) && !defined(__CYGWIN__)
+# define LZMA_API_CALL __cdecl
+# else
+# define LZMA_API_CALL
+# endif
+#endif
+
+#ifndef LZMA_API
+# define LZMA_API(type) LZMA_API_IMPORT type LZMA_API_CALL
+#endif
+
+
+/***********
+ * nothrow *
+ ***********/
+
+/*
+ * None of the functions in liblzma may throw an exception. Even
+ * the functions that use callback functions won't throw exceptions,
+ * because liblzma would break if a callback function threw an exception.
+ */
+#ifndef lzma_nothrow
+# if defined(__cplusplus)
+# define lzma_nothrow throw()
+# elif __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
+# define lzma_nothrow __attribute__((__nothrow__))
+# else
+# define lzma_nothrow
+# endif
+#endif
+
+
+/********************
+ * GNU C extensions *
+ ********************/
+
+/*
+ * GNU C extensions are used conditionally in the public API. It doesn't
+ * break anything if these are sometimes enabled and sometimes not, only
+ * affects warnings and optimizations.
+ */
+#if __GNUC__ >= 3
+# ifndef lzma_attribute
+# define lzma_attribute(attr) __attribute__(attr)
+# endif
+
+ /* warn_unused_result was added in GCC 3.4. */
+# ifndef lzma_attr_warn_unused_result
+# if __GNUC__ == 3 && __GNUC_MINOR__ < 4
+# define lzma_attr_warn_unused_result
+# endif
+# endif
+
+#else
+# ifndef lzma_attribute
+# define lzma_attribute(attr)
+# endif
+#endif
+
+
+#ifndef lzma_attr_pure
+# define lzma_attr_pure lzma_attribute((__pure__))
+#endif
+
+#ifndef lzma_attr_const
+# define lzma_attr_const lzma_attribute((__const__))
+#endif
+
+#ifndef lzma_attr_warn_unused_result
+# define lzma_attr_warn_unused_result \
+ lzma_attribute((__warn_unused_result__))
+#endif
+
+
+/**************
+ * Subheaders *
+ **************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Subheaders check that this is defined. It is to prevent including
+ * them directly from applications.
+ */
+#define LZMA_H_INTERNAL 1
+
+/* Basic features */
+#include "lzma/version.h"
+#include "lzma/base.h"
+#include "lzma/vli.h"
+#include "lzma/check.h"
+
+/* Filters */
+#include "lzma/filter.h"
+#include "lzma/bcj.h"
+#include "lzma/delta.h"
+#include "lzma/lzma.h"
+
+/* Container formats */
+#include "lzma/container.h"
+
+/* Advanced features */
+#include "lzma/stream_flags.h"
+#include "lzma/block.h"
+#include "lzma/index.h"
+#include "lzma/index_hash.h"
+
+/* Hardware information */
+#include "lzma/hardware.h"
+
+/*
+ * All subheaders included. Undefine LZMA_H_INTERNAL to prevent applications
+ * re-including the subheaders.
+ */
+#undef LZMA_H_INTERNAL
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ifndef LZMA_H */
diff --git a/Utilities/cmliblzma/liblzma/api/lzma/base.h b/Utilities/cmliblzma/liblzma/api/lzma/base.h
new file mode 100644
index 000000000..43dde8d60
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/api/lzma/base.h
@@ -0,0 +1,601 @@
+/**
+ * \file lzma/base.h
+ * \brief Data types and functions used in many places in liblzma API
+ */
+
+/*
+ * Author: Lasse Collin
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ *
+ * See ../lzma.h for information about liblzma as a whole.
+ */
+
+#ifndef LZMA_H_INTERNAL
+# error Never include this file directly. Use <lzma.h> instead.
+#endif
+
+
+/**
+ * \brief Boolean
+ *
+ * This is here because C89 doesn't have stdbool.h. To set a value for
+ * variables having type lzma_bool, you can use
+ * - C99's `true' and `false' from stdbool.h;
+ * - C++'s internal `true' and `false'; or
+ * - integers one (true) and zero (false).
+ */
+typedef unsigned char lzma_bool;
+
+
+/**
+ * \brief Type of reserved enumeration variable in structures
+ *
+ * To avoid breaking library ABI when new features are added, several
+ * structures contain extra variables that may be used in future. Since
+ * sizeof(enum) can be different than sizeof(int), and sizeof(enum) may
+ * even vary depending on the range of enumeration constants, we specify
+ * a separate type to be used for reserved enumeration variables. All
+ * enumeration constants in liblzma API will be non-negative and less
+ * than 128, which should guarantee that the ABI won't break even when
+ * new constants are added to existing enumerations.
+ */
+typedef enum {
+ LZMA_RESERVED_ENUM = 0
+} lzma_reserved_enum;
+
+
+/**
+ * \brief Return values used by several functions in liblzma
+ *
+ * Check the descriptions of specific functions to find out which return
+ * values they can return. With some functions the return values may have
+ * more specific meanings than described here; those differences are
+ * described per-function basis.
+ */
+typedef enum {
+ LZMA_OK = 0,
+ /**<
+ * \brief Operation completed successfully
+ */
+
+ LZMA_STREAM_END = 1,
+ /**<
+ * \brief End of stream was reached
+ *
+ * In encoder, LZMA_SYNC_FLUSH, LZMA_FULL_FLUSH, or
+ * LZMA_FINISH was finished. In decoder, this indicates
+ * that all the data was successfully decoded.
+ *
+ * In all cases, when LZMA_STREAM_END is returned, the last
+ * output bytes should be picked from strm->next_out.
+ */
+
+ LZMA_NO_CHECK = 2,
+ /**<
+ * \brief Input stream has no integrity check
+ *
+ * This return value can be returned only if the
+ * LZMA_TELL_NO_CHECK flag was used when initializing
+ * the decoder. LZMA_NO_CHECK is just a warning, and
+ * the decoding can be continued normally.
+ *
+ * It is possible to call lzma_get_check() immediately after
+ * lzma_code has returned LZMA_NO_CHECK. The result will
+ * naturally be LZMA_CHECK_NONE, but the possibility to call
+ * lzma_get_check() may be convenient in some applications.
+ */
+
+ LZMA_UNSUPPORTED_CHECK = 3,
+ /**<
+ * \brief Cannot calculate the integrity check
+ *
+ * The usage of this return value is different in encoders
+ * and decoders.
+ *
+ * Encoders can return this value only from the initialization
+ * function. If initialization fails with this value, the
+ * encoding cannot be done, because there's no way to produce
+ * output with the correct integrity check.
+ *
+ * Decoders can return this value only from lzma_code() and
+ * only if the LZMA_TELL_UNSUPPORTED_CHECK flag was used when
+ * initializing the decoder. The decoding can still be
+ * continued normally even if the check type is unsupported,
+ * but naturally the check will not be validated, and possible
+ * errors may go undetected.
+ *
+ * With decoder, it is possible to call lzma_get_check()
+ * immediately after lzma_code() has returned
+ * LZMA_UNSUPPORTED_CHECK. This way it is possible to find
+ * out what the unsupported Check ID was.
+ */
+
+ LZMA_GET_CHECK = 4,
+ /**<
+ * \brief Integrity check type is now available
+ *
+ * This value can be returned only by the lzma_code() function
+ * and only if the decoder was initialized with the
+ * LZMA_TELL_ANY_CHECK flag. LZMA_GET_CHECK tells the
+ * application that it may now call lzma_get_check() to find
+ * out the Check ID. This can be used, for example, to
+ * implement a decoder that accepts only files that have
+ * strong enough integrity check.
+ */
+
+ LZMA_MEM_ERROR = 5,
+ /**<
+ * \brief Cannot allocate memory
+ *
+ * Memory allocation failed, or the size of the allocation
+ * would be greater than SIZE_MAX.
+ *
+ * Due to internal implementation reasons, the coding cannot
+ * be continued even if more memory were made available after
+ * LZMA_MEM_ERROR.
+ */
+
+ LZMA_MEMLIMIT_ERROR = 6,
+ /**
+ * \brief Memory usage limit was reached
+ *
+ * Decoder would need more memory than allowed by the
+ * specified memory usage limit. To continue decoding,
+ * the memory usage limit has to be increased with
+ * lzma_memlimit_set().
+ */
+
+ LZMA_FORMAT_ERROR = 7,
+ /**<
+ * \brief File format not recognized
+ *
+ * The decoder did not recognize the input as supported file
+ * format. This error can occur, for example, when trying to
+ * decode .lzma format file with lzma_stream_decoder,
+ * because lzma_stream_decoder accepts only the .xz format.
+ */
+
+ LZMA_OPTIONS_ERROR = 8,
+ /**<
+ * \brief Invalid or unsupported options
+ *
+ * Invalid or unsupported options, for example
+ * - unsupported filter(s) or filter options; or
+ * - reserved bits set in headers (decoder only).
+ *
+ * Rebuilding liblzma with more features enabled, or
+ * upgrading to a newer version of liblzma may help.
+ */
+
+ LZMA_DATA_ERROR = 9,
+ /**<
+ * \brief Data is corrupt
+ *
+ * The usage of this return value is different in encoders
+ * and decoders. In both encoder and decoder, the coding
+ * cannot continue after this error.
+ *
+ * Encoders return this if size limits of the target file
+ * format would be exceeded. These limits are huge, thus
+ * getting this error from an encoder is mostly theoretical.
+ * For example, the maximum compressed and uncompressed
+ * size of a .xz Stream is roughly 8 EiB (2^63 bytes).
+ *
+ * Decoders return this error if the input data is corrupt.
+ * This can mean, for example, invalid CRC32 in headers
+ * or invalid check of uncompressed data.
+ */
+
+ LZMA_BUF_ERROR = 10,
+ /**<
+ * \brief No progress is possible
+ *
+ * This error code is returned when the coder cannot consume
+ * any new input and produce any new output. The most common
+ * reason for this error is that the input stream being
+ * decoded is truncated or corrupt.
+ *
+ * This error is not fatal. Coding can be continued normally
+ * by providing more input and/or more output space, if
+ * possible.
+ *
+ * Typically the first call to lzma_code() that can do no
+ * progress returns LZMA_OK instead of LZMA_BUF_ERROR. Only
+ * the second consecutive call doing no progress will return
+ * LZMA_BUF_ERROR. This is intentional.
+ *
+ * With zlib, Z_BUF_ERROR may be returned even if the
+ * application is doing nothing wrong, so apps will need
+ * to handle Z_BUF_ERROR specially. The above hack
+ * guarantees that liblzma never returns LZMA_BUF_ERROR
+ * to properly written applications unless the input file
+ * is truncated or corrupt. This should simplify the
+ * applications a little.
+ */
+
+ LZMA_PROG_ERROR = 11,
+ /**<
+ * \brief Programming error
+ *
+ * This indicates that the arguments given to the function are
+ * invalid or the internal state of the decoder is corrupt.
+ * - Function arguments are invalid or the structures
+ * pointed by the argument pointers are invalid
+ * e.g. if strm->next_out has been set to NULL and
+ * strm->avail_out > 0 when calling lzma_code().
+ * - lzma_* functions have been called in wrong order
+ * e.g. lzma_code() was called right after lzma_end().
+ * - If errors occur randomly, the reason might be flaky
+ * hardware.
+ *
+ * If you think that your code is correct, this error code
+ * can be a sign of a bug in liblzma. See the documentation
+ * how to report bugs.
+ */
+} lzma_ret;
+
+
+/**
+ * \brief The `action' argument for lzma_code()
+ *
+ * After the first use of LZMA_SYNC_FLUSH, LZMA_FULL_FLUSH, or LZMA_FINISH,
+ * the same `action' must is used until lzma_code() returns LZMA_STREAM_END.
+ * Also, the amount of input (that is, strm->avail_in) must not be modified
+ * by the application until lzma_code() returns LZMA_STREAM_END. Changing the
+ * `action' or modifying the amount of input will make lzma_code() return
+ * LZMA_PROG_ERROR.
+ */
+typedef enum {
+ LZMA_RUN = 0,
+ /**<
+ * \brief Continue coding
+ *
+ * Encoder: Encode as much input as possible. Some internal
+ * buffering will probably be done (depends on the filter
+ * chain in use), which causes latency: the input used won't
+ * usually be decodeable from the output of the same
+ * lzma_code() call.
+ *
+ * Decoder: Decode as much input as possible and produce as
+ * much output as possible.
+ */
+
+ LZMA_SYNC_FLUSH = 1,
+ /**<
+ * \brief Make all the input available at output
+ *
+ * Normally the encoder introduces some latency.
+ * LZMA_SYNC_FLUSH forces all the buffered data to be
+ * available at output without resetting the internal
+ * state of the encoder. This way it is possible to use
+ * compressed stream for example for communication over
+ * network.
+ *
+ * Only some filters support LZMA_SYNC_FLUSH. Trying to use
+ * LZMA_SYNC_FLUSH with filters that don't support it will
+ * make lzma_code() return LZMA_OPTIONS_ERROR. For example,
+ * LZMA1 doesn't support LZMA_SYNC_FLUSH but LZMA2 does.
+ *
+ * Using LZMA_SYNC_FLUSH very often can dramatically reduce
+ * the compression ratio. With some filters (for example,
+ * LZMA2), fine-tuning the compression options may help
+ * mitigate this problem significantly (for example,
+ * match finder with LZMA2).
+ *
+ * Decoders don't support LZMA_SYNC_FLUSH.
+ */
+
+ LZMA_FULL_FLUSH = 2,
+ /**<
+ * \brief Finish encoding of the current Block
+ *
+ * All the input data going to the current Block must have
+ * been given to the encoder (the last bytes can still be
+ * pending in* next_in). Call lzma_code() with LZMA_FULL_FLUSH
+ * until it returns LZMA_STREAM_END. Then continue normally
+ * with LZMA_RUN or finish the Stream with LZMA_FINISH.
+ *
+ * This action is currently supported only by Stream encoder
+ * and easy encoder (which uses Stream encoder). If there is
+ * no unfinished Block, no empty Block is created.
+ */
+
+ LZMA_FINISH = 3
+ /**<
+ * \brief Finish the coding operation
+ *
+ * All the input data must have been given to the encoder
+ * (the last bytes can still be pending in next_in).
+ * Call lzma_code() with LZMA_FINISH until it returns
+ * LZMA_STREAM_END. Once LZMA_FINISH has been used,
+ * the amount of input must no longer be changed by
+ * the application.
+ *
+ * When decoding, using LZMA_FINISH is optional unless the
+ * LZMA_CONCATENATED flag was used when the decoder was
+ * initialized. When LZMA_CONCATENATED was not used, the only
+ * effect of LZMA_FINISH is that the amount of input must not
+ * be changed just like in the encoder.
+ */
+} lzma_action;
+
+
+/**
+ * \brief Custom functions for memory handling
+ *
+ * A pointer to lzma_allocator may be passed via lzma_stream structure
+ * to liblzma, and some advanced functions take a pointer to lzma_allocator
+ * as a separate function argument. The library will use the functions
+ * specified in lzma_allocator for memory handling instead of the default
+ * malloc() and free(). C++ users should note that the custom memory
+ * handling functions must not throw exceptions.
+ *
+ * liblzma doesn't make an internal copy of lzma_allocator. Thus, it is
+ * OK to change these function pointers in the middle of the coding
+ * process, but obviously it must be done carefully to make sure that the
+ * replacement `free' can deallocate memory allocated by the earlier
+ * `alloc' function(s).
+ */
+typedef struct {
+ /**
+ * \brief Pointer to a custom memory allocation function
+ *
+ * If you don't want a custom allocator, but still want
+ * custom free(), set this to NULL and liblzma will use
+ * the standard malloc().
+ *
+ * \param opaque lzma_allocator.opaque (see below)
+ * \param nmemb Number of elements like in calloc(). liblzma
+ * will always set nmemb to 1, so it is safe to
+ * ignore nmemb in a custom allocator if you like.
+ * The nmemb argument exists only for
+ * compatibility with zlib and libbzip2.
+ * \param size Size of an element in bytes.
+ * liblzma never sets this to zero.
+ *
+ * \return Pointer to the beginning of a memory block of
+ * `size' bytes, or NULL if allocation fails
+ * for some reason. When allocation fails, functions
+ * of liblzma return LZMA_MEM_ERROR.
+ *
+ * The allocator should not waste time zeroing the allocated buffers.
+ * This is not only about speed, but also memory usage, since the
+ * operating system kernel doesn't necessarily allocate the requested
+ * memory in physical memory until it is actually used. With small
+ * input files, liblzma may actually need only a fraction of the
+ * memory that it requested for allocation.
+ *
+ * \note LZMA_MEM_ERROR is also used when the size of the
+ * allocation would be greater than SIZE_MAX. Thus,
+ * don't assume that the custom allocator must have
+ * returned NULL if some function from liblzma
+ * returns LZMA_MEM_ERROR.
+ */
+ void *(LZMA_API_CALL *alloc)(void *opaque, size_t nmemb, size_t size);
+
+ /**
+ * \brief Pointer to a custom memory freeing function
+ *
+ * If you don't want a custom freeing function, but still
+ * want a custom allocator, set this to NULL and liblzma
+ * will use the standard free().
+ *
+ * \param opaque lzma_allocator.opaque (see below)
+ * \param ptr Pointer returned by lzma_allocator.alloc(),
+ * or when it is set to NULL, a pointer returned
+ * by the standard malloc().
+ */
+ void (LZMA_API_CALL *free)(void *opaque, void *ptr);
+
+ /**
+ * \brief Pointer passed to .alloc() and .free()
+ *
+ * opaque is passed as the first argument to lzma_allocator.alloc()
+ * and lzma_allocator.free(). This intended to ease implementing
+ * custom memory allocation functions for use with liblzma.
+ *
+ * If you don't need this, you should set this to NULL.
+ */
+ void *opaque;
+
+} lzma_allocator;
+
+
+/**
+ * \brief Internal data structure
+ *
+ * The contents of this structure is not visible outside the library.
+ */
+typedef struct lzma_internal_s lzma_internal;
+
+
+/**
+ * \brief Passing data to and from liblzma
+ *
+ * The lzma_stream structure is used for
+ * - passing pointers to input and output buffers to liblzma;
+ * - defining custom memory hander functions; and
+ * - holding a pointer to coder-specific internal data structures.
+ *
+ * Typical usage:
+ *
+ * - After allocating lzma_stream (on stack or with malloc()), it must be
+ * initialized to LZMA_STREAM_INIT (see LZMA_STREAM_INIT for details).
+ *
+ * - Initialize a coder to the lzma_stream, for example by using
+ * lzma_easy_encoder() or lzma_auto_decoder(). Some notes:
+ * - In contrast to zlib, strm->next_in and strm->next_out are
+ * ignored by all initialization functions, thus it is safe
+ * to not initialize them yet.
+ * - The initialization functions always set strm->total_in and
+ * strm->total_out to zero.
+ * - If the initialization function fails, no memory is left allocated
+ * that would require freeing with lzma_end() even if some memory was
+ * associated with the lzma_stream structure when the initialization
+ * function was called.
+ *
+ * - Use lzma_code() to do the actual work.
+ *
+ * - Once the coding has been finished, the existing lzma_stream can be
+ * reused. It is OK to reuse lzma_stream with different initialization
+ * function without calling lzma_end() first. Old allocations are
+ * automatically freed.
+ *
+ * - Finally, use lzma_end() to free the allocated memory. lzma_end() never
+ * frees the lzma_stream structure itself.
+ *
+ * Application may modify the values of total_in and total_out as it wants.
+ * They are updated by liblzma to match the amount of data read and
+ * written, but aren't used for anything else.
+ */
+typedef struct {
+ const uint8_t *next_in; /**< Pointer to the next input byte. */
+ size_t avail_in; /**< Number of available input bytes in next_in. */
+ uint64_t total_in; /**< Total number of bytes read by liblzma. */
+
+ uint8_t *next_out; /**< Pointer to the next output position. */
+ size_t avail_out; /**< Amount of free space in next_out. */
+ uint64_t total_out; /**< Total number of bytes written by liblzma. */
+
+ /**
+ * \brief Custom memory allocation functions
+ *
+ * In most cases this is NULL which makes liblzma use
+ * the standard malloc() and free().
+ */
+ lzma_allocator *allocator;
+
+ /** Internal state is not visible to applications. */
+ lzma_internal *internal;
+
+ /*
+ * Reserved space to allow possible future extensions without
+ * breaking the ABI. Excluding the initialization of this structure,
+ * you should not touch these, because the names of these variables
+ * may change.
+ */
+ void *reserved_ptr1;
+ void *reserved_ptr2;
+ void *reserved_ptr3;
+ void *reserved_ptr4;
+ uint64_t reserved_int1;
+ uint64_t reserved_int2;
+ size_t reserved_int3;
+ size_t reserved_int4;
+ lzma_reserved_enum reserved_enum1;
+ lzma_reserved_enum reserved_enum2;
+
+} lzma_stream;
+
+
+/**
+ * \brief Initialization for lzma_stream
+ *
+ * When you declare an instance of lzma_stream, you can immediately
+ * initialize it so that initialization functions know that no memory
+ * has been allocated yet:
+ *
+ * lzma_stream strm = LZMA_STREAM_INIT;
+ *
+ * If you need to initialize a dynamically allocated lzma_stream, you can use
+ * memset(strm_pointer, 0, sizeof(lzma_stream)). Strictly speaking, this
+ * violates the C standard since NULL may have different internal
+ * representation than zero, but it should be portable enough in practice.
+ * Anyway, for maximum portability, you can use something like this:
+ *
+ * lzma_stream tmp = LZMA_STREAM_INIT;
+ * *strm = tmp;
+ */
+#define LZMA_STREAM_INIT \
+ { NULL, 0, 0, NULL, 0, 0, NULL, NULL, \
+ NULL, NULL, NULL, NULL, 0, 0, 0, 0, \
+ LZMA_RESERVED_ENUM, LZMA_RESERVED_ENUM }
+
+
+/**
+ * \brief Encode or decode data
+ *
+ * Once the lzma_stream has been successfully initialized (e.g. with
+ * lzma_stream_encoder()), the actual encoding or decoding is done
+ * using this function. The application has to update strm->next_in,
+ * strm->avail_in, strm->next_out, and strm->avail_out to pass input
+ * to and get output from liblzma.
+ *
+ * See the description of the coder-specific initialization function to find
+ * out what `action' values are supported by the coder.
+ */
+extern LZMA_API(lzma_ret) lzma_code(lzma_stream *strm, lzma_action action)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Free memory allocated for the coder data structures
+ *
+ * \param strm Pointer to lzma_stream that is at least initialized
+ * with LZMA_STREAM_INIT.
+ *
+ * After lzma_end(strm), strm->internal is guaranteed to be NULL. No other
+ * members of the lzma_stream structure are touched.
+ *
+ * \note zlib indicates an error if application end()s unfinished
+ * stream structure. liblzma doesn't do this, and assumes that
+ * application knows what it is doing.
+ */
+extern LZMA_API(void) lzma_end(lzma_stream *strm) lzma_nothrow;
+
+
+/**
+ * \brief Get the memory usage of decoder filter chain
+ *
+ * This function is currently supported only when *strm has been initialized
+ * with a function that takes a memlimit argument. With other functions, you
+ * should use e.g. lzma_raw_encoder_memusage() or lzma_raw_decoder_memusage()
+ * to estimate the memory requirements.
+ *
+ * This function is useful e.g. after LZMA_MEMLIMIT_ERROR to find out how big
+ * the memory usage limit should have been to decode the input. Note that
+ * this may give misleading information if decoding .xz Streams that have
+ * multiple Blocks, because each Block can have different memory requirements.
+ *
+ * \return How much memory is currently allocated for the filter
+ * decoders. If no filter chain is currently allocated,
+ * some non-zero value is still returned, which is less than
+ * or equal to what any filter chain would indicate as its
+ * memory requirement.
+ *
+ * If this function isn't supported by *strm or some other error
+ * occurs, zero is returned.
+ */
+extern LZMA_API(uint64_t) lzma_memusage(const lzma_stream *strm)
+ lzma_nothrow lzma_attr_pure;
+
+
+/**
+ * \brief Get the current memory usage limit
+ *
+ * This function is supported only when *strm has been initialized with
+ * a function that takes a memlimit argument.
+ *
+ * \return On success, the current memory usage limit is returned
+ * (always non-zero). On error, zero is returned.
+ */
+extern LZMA_API(uint64_t) lzma_memlimit_get(const lzma_stream *strm)
+ lzma_nothrow lzma_attr_pure;
+
+
+/**
+ * \brief Set the memory usage limit
+ *
+ * This function is supported only when *strm has been initialized with
+ * a function that takes a memlimit argument.
+ *
+ * \return - LZMA_OK: New memory usage limit successfully set.
+ * - LZMA_MEMLIMIT_ERROR: The new limit is too small.
+ * The limit was not changed.
+ * - LZMA_PROG_ERROR: Invalid arguments, e.g. *strm doesn't
+ * support memory usage limit or memlimit was zero.
+ */
+extern LZMA_API(lzma_ret) lzma_memlimit_set(
+ lzma_stream *strm, uint64_t memlimit) lzma_nothrow;
diff --git a/Utilities/cmliblzma/liblzma/api/lzma/bcj.h b/Utilities/cmliblzma/liblzma/api/lzma/bcj.h
new file mode 100644
index 000000000..8e37538ad
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/api/lzma/bcj.h
@@ -0,0 +1,90 @@
+/**
+ * \file lzma/bcj.h
+ * \brief Branch/Call/Jump conversion filters
+ */
+
+/*
+ * Author: Lasse Collin
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ *
+ * See ../lzma.h for information about liblzma as a whole.
+ */
+
+#ifndef LZMA_H_INTERNAL
+# error Never include this file directly. Use <lzma.h> instead.
+#endif
+
+
+/* Filter IDs for lzma_filter.id */
+
+#define LZMA_FILTER_X86 LZMA_VLI_C(0x04)
+ /**<
+ * Filter for x86 binaries
+ */
+
+#define LZMA_FILTER_POWERPC LZMA_VLI_C(0x05)
+ /**<
+ * Filter for Big endian PowerPC binaries
+ */
+
+#define LZMA_FILTER_IA64 LZMA_VLI_C(0x06)
+ /**<
+ * Filter for IA-64 (Itanium) binaries.
+ */
+
+#define LZMA_FILTER_ARM LZMA_VLI_C(0x07)
+ /**<
+ * Filter for ARM binaries.
+ */
+
+#define LZMA_FILTER_ARMTHUMB LZMA_VLI_C(0x08)
+ /**<
+ * Filter for ARM-Thumb binaries.
+ */
+
+#define LZMA_FILTER_SPARC LZMA_VLI_C(0x09)
+ /**<
+ * Filter for SPARC binaries.
+ */
+
+
+/**
+ * \brief Options for BCJ filters
+ *
+ * The BCJ filters never change the size of the data. Specifying options
+ * for them is optional: if pointer to options is NULL, default value is
+ * used. You probably never need to specify options to BCJ filters, so just
+ * set the options pointer to NULL and be happy.
+ *
+ * If options with non-default values have been specified when encoding,
+ * the same options must also be specified when decoding.
+ *
+ * \note At the moment, none of the BCJ filters support
+ * LZMA_SYNC_FLUSH. If LZMA_SYNC_FLUSH is specified,
+ * LZMA_OPTIONS_ERROR will be returned. If there is need,
+ * partial support for LZMA_SYNC_FLUSH can be added in future.
+ * Partial means that flushing would be possible only at
+ * offsets that are multiple of 2, 4, or 16 depending on
+ * the filter, except x86 which cannot be made to support
+ * LZMA_SYNC_FLUSH predictably.
+ */
+typedef struct {
+ /**
+ * \brief Start offset for conversions
+ *
+ * This setting is useful only when the same filter is used
+ * _separately_ for multiple sections of the same executable file,
+ * and the sections contain cross-section branch/call/jump
+ * instructions. In that case it is beneficial to set the start
+ * offset of the non-first sections so that the relative addresses
+ * of the cross-section branch/call/jump instructions will use the
+ * same absolute addresses as in the first section.
+ *
+ * When the pointer to options is NULL, the default value (zero)
+ * is used.
+ */
+ uint32_t start_offset;
+
+} lzma_options_bcj;
diff --git a/Utilities/cmliblzma/liblzma/api/lzma/block.h b/Utilities/cmliblzma/liblzma/api/lzma/block.h
new file mode 100644
index 000000000..8a4bf2323
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/api/lzma/block.h
@@ -0,0 +1,530 @@
+/**
+ * \file lzma/block.h
+ * \brief .xz Block handling
+ */
+
+/*
+ * Author: Lasse Collin
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ *
+ * See ../lzma.h for information about liblzma as a whole.
+ */
+
+#ifndef LZMA_H_INTERNAL
+# error Never include this file directly. Use <lzma.h> instead.
+#endif
+
+
+/**
+ * \brief Options for the Block and Block Header encoders and decoders
+ *
+ * Different Block handling functions use different parts of this structure.
+ * Some read some members, other functions write, and some do both. Only the
+ * members listed for reading need to be initialized when the specified
+ * functions are called. The members marked for writing will be assigned
+ * new values at some point either by calling the given function or by
+ * later calls to lzma_code().
+ */
+typedef struct {
+ /**
+ * \brief Block format version
+ *
+ * To prevent API and ABI breakages if new features are needed in
+ * the Block field, a version number is used to indicate which
+ * fields in this structure are in use. For now, version must always
+ * be zero. With non-zero version, most Block related functions will
+ * return LZMA_OPTIONS_ERROR.
+ *
+ * Read by:
+ * - All functions that take pointer to lzma_block as argument,
+ * including lzma_block_header_decode().
+ *
+ * Written by:
+ * - lzma_block_header_decode()
+ */
+ uint32_t version;
+
+ /**
+ * \brief Size of the Block Header field
+ *
+ * This is always a multiple of four.
+ *
+ * Read by:
+ * - lzma_block_header_encode()
+ * - lzma_block_header_decode()
+ * - lzma_block_compressed_size()
+ * - lzma_block_unpadded_size()
+ * - lzma_block_total_size()
+ * - lzma_block_decoder()
+ * - lzma_block_buffer_decode()
+ *
+ * Written by:
+ * - lzma_block_header_size()
+ * - lzma_block_buffer_encode()
+ */
+ uint32_t header_size;
+# define LZMA_BLOCK_HEADER_SIZE_MIN 8
+# define LZMA_BLOCK_HEADER_SIZE_MAX 1024
+
+ /**
+ * \brief Type of integrity Check
+ *
+ * The Check ID is not stored into the Block Header, thus its value
+ * must be provided also when decoding.
+ *
+ * Read by:
+ * - lzma_block_header_encode()
+ * - lzma_block_header_decode()
+ * - lzma_block_compressed_size()
+ * - lzma_block_unpadded_size()
+ * - lzma_block_total_size()
+ * - lzma_block_encoder()
+ * - lzma_block_decoder()
+ * - lzma_block_buffer_encode()
+ * - lzma_block_buffer_decode()
+ */
+ lzma_check check;
+
+ /**
+ * \brief Size of the Compressed Data in bytes
+ *
+ * Encoding: If this is not LZMA_VLI_UNKNOWN, Block Header encoder
+ * will store this value to the Block Header. Block encoder doesn't
+ * care about this value, but will set it once the encoding has been
+ * finished.
+ *
+ * Decoding: If this is not LZMA_VLI_UNKNOWN, Block decoder will
+ * verify that the size of the Compressed Data field matches
+ * compressed_size.
+ *
+ * Usually you don't know this value when encoding in streamed mode,
+ * and thus cannot write this field into the Block Header.
+ *
+ * In non-streamed mode you can reserve space for this field before
+ * encoding the actual Block. After encoding the data, finish the
+ * Block by encoding the Block Header. Steps in detail:
+ *
+ * - Set compressed_size to some big enough value. If you don't know
+ * better, use LZMA_VLI_MAX, but remember that bigger values take
+ * more space in Block Header.
+ *
+ * - Call lzma_block_header_size() to see how much space you need to
+ * reserve for the Block Header.
+ *
+ * - Encode the Block using lzma_block_encoder() and lzma_code().
+ * It sets compressed_size to the correct value.
+ *
+ * - Use lzma_block_header_encode() to encode the Block Header.
+ * Because space was reserved in the first step, you don't need
+ * to call lzma_block_header_size() anymore, because due to
+ * reserving, header_size has to be big enough. If it is "too big",
+ * lzma_block_header_encode() will add enough Header Padding to
+ * make Block Header to match the size specified by header_size.
+ *
+ * Read by:
+ * - lzma_block_header_size()
+ * - lzma_block_header_encode()
+ * - lzma_block_compressed_size()
+ * - lzma_block_unpadded_size()
+ * - lzma_block_total_size()
+ * - lzma_block_decoder()
+ * - lzma_block_buffer_decode()
+ *
+ * Written by:
+ * - lzma_block_header_decode()
+ * - lzma_block_compressed_size()
+ * - lzma_block_encoder()
+ * - lzma_block_decoder()
+ * - lzma_block_buffer_encode()
+ * - lzma_block_buffer_decode()
+ */
+ lzma_vli compressed_size;
+
+ /**
+ * \brief Uncompressed Size in bytes
+ *
+ * This is handled very similarly to compressed_size above.
+ *
+ * uncompressed_size is needed by fewer functions than
+ * compressed_size. This is because uncompressed_size isn't
+ * needed to validate that Block stays within proper limits.
+ *
+ * Read by:
+ * - lzma_block_header_size()
+ * - lzma_block_header_encode()
+ * - lzma_block_decoder()
+ * - lzma_block_buffer_decode()
+ *
+ * Written by:
+ * - lzma_block_header_decode()
+ * - lzma_block_encoder()
+ * - lzma_block_decoder()
+ * - lzma_block_buffer_encode()
+ * - lzma_block_buffer_decode()
+ */
+ lzma_vli uncompressed_size;
+
+ /**
+ * \brief Array of filters
+ *
+ * There can be 1-4 filters. The end of the array is marked with
+ * .id = LZMA_VLI_UNKNOWN.
+ *
+ * Read by:
+ * - lzma_block_header_size()
+ * - lzma_block_header_encode()
+ * - lzma_block_encoder()
+ * - lzma_block_decoder()
+ * - lzma_block_buffer_encode()
+ * - lzma_block_buffer_decode()
+ *
+ * Written by:
+ * - lzma_block_header_decode(): Note that this does NOT free()
+ * the old filter options structures. All unused filters[] will
+ * have .id == LZMA_VLI_UNKNOWN and .options == NULL. If
+ * decoding fails, all filters[] are guaranteed to be
+ * LZMA_VLI_UNKNOWN and NULL.
+ *
+ * \note Because of the array is terminated with
+ * .id = LZMA_VLI_UNKNOWN, the actual array must
+ * have LZMA_FILTERS_MAX + 1 members or the Block
+ * Header decoder will overflow the buffer.
+ */
+ lzma_filter *filters;
+
+ /**
+ * \brief Raw value stored in the Check field
+ *
+ * After successful coding, the first lzma_check_size(check) bytes
+ * of this array contain the raw value stored in the Check field.
+ *
+ * Note that CRC32 and CRC64 are stored in little endian byte order.
+ * Take it into account if you display the Check values to the user.
+ *
+ * Written by:
+ * - lzma_block_encoder()
+ * - lzma_block_decoder()
+ * - lzma_block_buffer_encode()
+ * - lzma_block_buffer_decode()
+ */
+ uint8_t raw_check[LZMA_CHECK_SIZE_MAX];
+
+ /*
+ * Reserved space to allow possible future extensions without
+ * breaking the ABI. You should not touch these, because the names
+ * of these variables may change. These are and will never be used
+ * with the currently supported options, so it is safe to leave these
+ * uninitialized.
+ */
+ void *reserved_ptr1;
+ void *reserved_ptr2;
+ void *reserved_ptr3;
+ uint32_t reserved_int1;
+ uint32_t reserved_int2;
+ lzma_vli reserved_int3;
+ lzma_vli reserved_int4;
+ lzma_vli reserved_int5;
+ lzma_vli reserved_int6;
+ lzma_vli reserved_int7;
+ lzma_vli reserved_int8;
+ lzma_reserved_enum reserved_enum1;
+ lzma_reserved_enum reserved_enum2;
+ lzma_reserved_enum reserved_enum3;
+ lzma_reserved_enum reserved_enum4;
+ lzma_bool reserved_bool1;
+ lzma_bool reserved_bool2;
+ lzma_bool reserved_bool3;
+ lzma_bool reserved_bool4;
+ lzma_bool reserved_bool5;
+ lzma_bool reserved_bool6;
+ lzma_bool reserved_bool7;
+ lzma_bool reserved_bool8;
+
+} lzma_block;
+
+
+/**
+ * \brief Decode the Block Header Size field
+ *
+ * To decode Block Header using lzma_block_header_decode(), the size of the
+ * Block Header has to be known and stored into lzma_block.header_size.
+ * The size can be calculated from the first byte of a Block using this macro.
+ * Note that if the first byte is 0x00, it indicates beginning of Index; use
+ * this macro only when the byte is not 0x00.
+ *
+ * There is no encoding macro, because Block Header encoder is enough for that.
+ */
+#define lzma_block_header_size_decode(b) (((uint32_t)(b) + 1) * 4)
+
+
+/**
+ * \brief Calculate Block Header Size
+ *
+ * Calculate the minimum size needed for the Block Header field using the
+ * settings specified in the lzma_block structure. Note that it is OK to
+ * increase the calculated header_size value as long as it is a multiple of
+ * four and doesn't exceed LZMA_BLOCK_HEADER_SIZE_MAX. Increasing header_size
+ * just means that lzma_block_header_encode() will add Header Padding.
+ *
+ * \return - LZMA_OK: Size calculated successfully and stored to
+ * block->header_size.
+ * - LZMA_OPTIONS_ERROR: Unsupported version, filters or
+ * filter options.
+ * - LZMA_PROG_ERROR: Invalid values like compressed_size == 0.
+ *
+ * \note This doesn't check that all the options are valid i.e. this
+ * may return LZMA_OK even if lzma_block_header_encode() or
+ * lzma_block_encoder() would fail. If you want to validate the
+ * filter chain, consider using lzma_memlimit_encoder() which as
+ * a side-effect validates the filter chain.
+ */
+extern LZMA_API(lzma_ret) lzma_block_header_size(lzma_block *block)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Encode Block Header
+ *
+ * The caller must have calculated the size of the Block Header already with
+ * lzma_block_header_size(). If a value larger than the one calculated by
+ * lzma_block_header_size() is used, the Block Header will be padded to the
+ * specified size.
+ *
+ * \param out Beginning of the output buffer. This must be
+ * at least block->header_size bytes.
+ * \param block Block options to be encoded.
+ *
+ * \return - LZMA_OK: Encoding was successful. block->header_size
+ * bytes were written to output buffer.
+ * - LZMA_OPTIONS_ERROR: Invalid or unsupported options.
+ * - LZMA_PROG_ERROR: Invalid arguments, for example
+ * block->header_size is invalid or block->filters is NULL.
+ */
+extern LZMA_API(lzma_ret) lzma_block_header_encode(
+ const lzma_block *block, uint8_t *out)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Decode Block Header
+ *
+ * block->version should be set to the highest value supported by the
+ * application; currently the only possible version is zero. This function
+ * will set version to the lowest value that still supports all the features
+ * required by the Block Header.
+ *
+ * The size of the Block Header must have already been decoded with
+ * lzma_block_header_size_decode() macro and stored to block->header_size.
+ *
+ * block->filters must have been allocated, but they don't need to be
+ * initialized (possible existing filter options are not freed).
+ *
+ * \param block Destination for Block options.
+ * \param allocator lzma_allocator for custom allocator functions.
+ * Set to NULL to use malloc() (and also free()
+ * if an error occurs).
+ * \param in Beginning of the input buffer. This must be
+ * at least block->header_size bytes.
+ *
+ * \return - LZMA_OK: Decoding was successful. block->header_size
+ * bytes were read from the input buffer.
+ * - LZMA_OPTIONS_ERROR: The Block Header specifies some
+ * unsupported options such as unsupported filters. This can
+ * happen also if block->version was set to a too low value
+ * compared to what would be required to properly represent
+ * the information stored in the Block Header.
+ * - LZMA_DATA_ERROR: Block Header is corrupt, for example,
+ * the CRC32 doesn't match.
+ * - LZMA_PROG_ERROR: Invalid arguments, for example
+ * block->header_size is invalid or block->filters is NULL.
+ */
+extern LZMA_API(lzma_ret) lzma_block_header_decode(lzma_block *block,
+ lzma_allocator *allocator, const uint8_t *in)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Validate and set Compressed Size according to Unpadded Size
+ *
+ * Block Header stores Compressed Size, but Index has Unpadded Size. If the
+ * application has already parsed the Index and is now decoding Blocks,
+ * it can calculate Compressed Size from Unpadded Size. This function does
+ * exactly that with error checking:
+ *
+ * - Compressed Size calculated from Unpadded Size must be positive integer,
+ * that is, Unpadded Size must be big enough that after Block Header and
+ * Check fields there's still at least one byte for Compressed Size.
+ *
+ * - If Compressed Size was present in Block Header, the new value
+ * calculated from Unpadded Size is compared against the value
+ * from Block Header.
+ *
+ * \note This function must be called _after_ decoding the Block Header
+ * field so that it can properly validate Compressed Size if it
+ * was present in Block Header.
+ *
+ * \return - LZMA_OK: block->compressed_size was set successfully.
+ * - LZMA_DATA_ERROR: unpadded_size is too small compared to
+ * block->header_size and lzma_check_size(block->check).
+ * - LZMA_PROG_ERROR: Some values are invalid. For example,
+ * block->header_size must be a multiple of four and
+ * between 8 and 1024 inclusive.
+ */
+extern LZMA_API(lzma_ret) lzma_block_compressed_size(
+ lzma_block *block, lzma_vli unpadded_size)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Calculate Unpadded Size
+ *
+ * The Index field stores Unpadded Size and Uncompressed Size. The latter
+ * can be taken directly from the lzma_block structure after coding a Block,
+ * but Unpadded Size needs to be calculated from Block Header Size,
+ * Compressed Size, and size of the Check field. This is where this function
+ * is needed.
+ *
+ * \return Unpadded Size on success, or zero on error.
+ */
+extern LZMA_API(lzma_vli) lzma_block_unpadded_size(const lzma_block *block)
+ lzma_nothrow lzma_attr_pure;
+
+
+/**
+ * \brief Calculate the total encoded size of a Block
+ *
+ * This is equivalent to lzma_block_unpadded_size() except that the returned
+ * value includes the size of the Block Padding field.
+ *
+ * \return On success, total encoded size of the Block. On error,
+ * zero is returned.
+ */
+extern LZMA_API(lzma_vli) lzma_block_total_size(const lzma_block *block)
+ lzma_nothrow lzma_attr_pure;
+
+
+/**
+ * \brief Initialize .xz Block encoder
+ *
+ * Valid actions for lzma_code() are LZMA_RUN, LZMA_SYNC_FLUSH (only if the
+ * filter chain supports it), and LZMA_FINISH.
+ *
+ * \return - LZMA_OK: All good, continue with lzma_code().
+ * - LZMA_MEM_ERROR
+ * - LZMA_OPTIONS_ERROR
+ * - LZMA_UNSUPPORTED_CHECK: block->check specifies a Check ID
+ * that is not supported by this buid of liblzma. Initializing
+ * the encoder failed.
+ * - LZMA_PROG_ERROR
+ */
+extern LZMA_API(lzma_ret) lzma_block_encoder(
+ lzma_stream *strm, lzma_block *block)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Initialize .xz Block decoder
+ *
+ * Valid actions for lzma_code() are LZMA_RUN and LZMA_FINISH. Using
+ * LZMA_FINISH is not required. It is supported only for convenience.
+ *
+ * \return - LZMA_OK: All good, continue with lzma_code().
+ * - LZMA_UNSUPPORTED_CHECK: Initialization was successful, but
+ * the given Check ID is not supported, thus Check will be
+ * ignored.
+ * - LZMA_PROG_ERROR
+ * - LZMA_MEM_ERROR
+ */
+extern LZMA_API(lzma_ret) lzma_block_decoder(
+ lzma_stream *strm, lzma_block *block)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Calculate maximum output size for single-call Block encoding
+ *
+ * This is equivalent to lzma_stream_buffer_bound() but for .xz Blocks.
+ * See the documentation of lzma_stream_buffer_bound().
+ */
+extern LZMA_API(size_t) lzma_block_buffer_bound(size_t uncompressed_size)
+ lzma_nothrow;
+
+
+/**
+ * \brief Single-call .xz Block encoder
+ *
+ * In contrast to the multi-call encoder initialized with
+ * lzma_block_encoder(), this function encodes also the Block Header. This
+ * is required to make it possible to write appropriate Block Header also
+ * in case the data isn't compressible, and different filter chain has to be
+ * used to encode the data in uncompressed form using uncompressed chunks
+ * of the LZMA2 filter.
+ *
+ * When the data isn't compressible, header_size, compressed_size, and
+ * uncompressed_size are set just like when the data was compressible, but
+ * it is possible that header_size is too small to hold the filter chain
+ * specified in block->filters, because that isn't necessarily the filter
+ * chain that was actually used to encode the data. lzma_block_unpadded_size()
+ * still works normally, because it doesn't read the filters array.
+ *
+ * \param block Block options: block->version, block->check,
+ * and block->filters must have been initialized.
+ * \param allocator lzma_allocator for custom allocator functions.
+ * Set to NULL to use malloc() and free().
+ * \param in Beginning of the input buffer
+ * \param in_size Size of the input buffer
+ * \param out Beginning of the output buffer
+ * \param out_pos The next byte will be written to out[*out_pos].
+ * *out_pos is updated only if encoding succeeds.
+ * \param out_size Size of the out buffer; the first byte into
+ * which no data is written to is out[out_size].
+ *
+ * \return - LZMA_OK: Encoding was successful.
+ * - LZMA_BUF_ERROR: Not enough output buffer space.
+ * - LZMA_UNSUPPORTED_CHECK
+ * - LZMA_OPTIONS_ERROR
+ * - LZMA_MEM_ERROR
+ * - LZMA_DATA_ERROR
+ * - LZMA_PROG_ERROR
+ */
+extern LZMA_API(lzma_ret) lzma_block_buffer_encode(
+ lzma_block *block, lzma_allocator *allocator,
+ const uint8_t *in, size_t in_size,
+ uint8_t *out, size_t *out_pos, size_t out_size)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Single-call .xz Block decoder
+ *
+ * This is single-call equivalent of lzma_block_decoder(), and requires that
+ * the caller has already decoded Block Header and checked its memory usage.
+ *
+ * \param block Block options just like with lzma_block_decoder().
+ * \param allocator lzma_allocator for custom allocator functions.
+ * Set to NULL to use malloc() and free().
+ * \param in Beginning of the input buffer
+ * \param in_pos The next byte will be read from in[*in_pos].
+ * *in_pos is updated only if decoding succeeds.
+ * \param in_size Size of the input buffer; the first byte that
+ * won't be read is in[in_size].
+ * \param out Beginning of the output buffer
+ * \param out_pos The next byte will be written to out[*out_pos].
+ * *out_pos is updated only if encoding succeeds.
+ * \param out_size Size of the out buffer; the first byte into
+ * which no data is written to is out[out_size].
+ *
+ * \return - LZMA_OK: Decoding was successful.
+ * - LZMA_OPTIONS_ERROR
+ * - LZMA_DATA_ERROR
+ * - LZMA_MEM_ERROR
+ * - LZMA_BUF_ERROR: Output buffer was too small.
+ * - LZMA_PROG_ERROR
+ */
+extern LZMA_API(lzma_ret) lzma_block_buffer_decode(
+ lzma_block *block, lzma_allocator *allocator,
+ const uint8_t *in, size_t *in_pos, size_t in_size,
+ uint8_t *out, size_t *out_pos, size_t out_size)
+ lzma_nothrow;
diff --git a/Utilities/cmliblzma/liblzma/api/lzma/check.h b/Utilities/cmliblzma/liblzma/api/lzma/check.h
new file mode 100644
index 000000000..6a243db0d
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/api/lzma/check.h
@@ -0,0 +1,150 @@
+/**
+ * \file lzma/check.h
+ * \brief Integrity checks
+ */
+
+/*
+ * Author: Lasse Collin
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ *
+ * See ../lzma.h for information about liblzma as a whole.
+ */
+
+#ifndef LZMA_H_INTERNAL
+# error Never include this file directly. Use <lzma.h> instead.
+#endif
+
+
+/**
+ * \brief Type of the integrity check (Check ID)
+ *
+ * The .xz format supports multiple types of checks that are calculated
+ * from the uncompressed data. They vary in both speed and ability to
+ * detect errors.
+ */
+typedef enum {
+ LZMA_CHECK_NONE = 0,
+ /**<
+ * No Check is calculated.
+ *
+ * Size of the Check field: 0 bytes
+ */
+
+ LZMA_CHECK_CRC32 = 1,
+ /**<
+ * CRC32 using the polynomial from the IEEE 802.3 standard
+ *
+ * Size of the Check field: 4 bytes
+ */
+
+ LZMA_CHECK_CRC64 = 4,
+ /**<
+ * CRC64 using the polynomial from the ECMA-182 standard
+ *
+ * Size of the Check field: 8 bytes
+ */
+
+ LZMA_CHECK_SHA256 = 10
+ /**<
+ * SHA-256
+ *
+ * Size of the Check field: 32 bytes
+ */
+} lzma_check;
+
+
+/**
+ * \brief Maximum valid Check ID
+ *
+ * The .xz file format specification specifies 16 Check IDs (0-15). Some
+ * of them are only reserved, that is, no actual Check algorithm has been
+ * assigned. When decoding, liblzma still accepts unknown Check IDs for
+ * future compatibility. If a valid but unsupported Check ID is detected,
+ * liblzma can indicate a warning; see the flags LZMA_TELL_NO_CHECK,
+ * LZMA_TELL_UNSUPPORTED_CHECK, and LZMA_TELL_ANY_CHECK in container.h.
+ */
+#define LZMA_CHECK_ID_MAX 15
+
+
+/**
+ * \brief Test if the given Check ID is supported
+ *
+ * Return true if the given Check ID is supported by this liblzma build.
+ * Otherwise false is returned. It is safe to call this with a value that
+ * is not in the range [0, 15]; in that case the return value is always false.
+ *
+ * You can assume that LZMA_CHECK_NONE and LZMA_CHECK_CRC32 are always
+ * supported (even if liblzma is built with limited features).
+ */
+extern LZMA_API(lzma_bool) lzma_check_is_supported(lzma_check check)
+ lzma_nothrow lzma_attr_const;
+
+
+/**
+ * \brief Get the size of the Check field with the given Check ID
+ *
+ * Although not all Check IDs have a check algorithm associated, the size of
+ * every Check is already frozen. This function returns the size (in bytes) of
+ * the Check field with the specified Check ID. The values are:
+ * { 0, 4, 4, 4, 8, 8, 8, 16, 16, 16, 32, 32, 32, 64, 64, 64 }
+ *
+ * If the argument is not in the range [0, 15], UINT32_MAX is returned.
+ */
+extern LZMA_API(uint32_t) lzma_check_size(lzma_check check)
+ lzma_nothrow lzma_attr_const;
+
+
+/**
+ * \brief Maximum size of a Check field
+ */
+#define LZMA_CHECK_SIZE_MAX 64
+
+
+/**
+ * \brief Calculate CRC32
+ *
+ * Calculate CRC32 using the polynomial from the IEEE 802.3 standard.
+ *
+ * \param buf Pointer to the input buffer
+ * \param size Size of the input buffer
+ * \param crc Previously returned CRC value. This is used to
+ * calculate the CRC of a big buffer in smaller chunks.
+ * Set to zero when starting a new calculation.
+ *
+ * \return Updated CRC value, which can be passed to this function
+ * again to continue CRC calculation.
+ */
+extern LZMA_API(uint32_t) lzma_crc32(
+ const uint8_t *buf, size_t size, uint32_t crc)
+ lzma_nothrow lzma_attr_pure;
+
+
+/**
+ * \brief Calculate CRC64
+ *
+ * Calculate CRC64 using the polynomial from the ECMA-182 standard.
+ *
+ * This function is used similarly to lzma_crc32(). See its documentation.
+ */
+extern LZMA_API(uint64_t) lzma_crc64(
+ const uint8_t *buf, size_t size, uint64_t crc)
+ lzma_nothrow lzma_attr_pure;
+
+
+/*
+ * SHA-256 functions are currently not exported to public API.
+ * Contact Lasse Collin if you think it should be.
+ */
+
+
+/**
+ * \brief Get the type of the integrity check
+ *
+ * This function can be called only immediately after lzma_code() has
+ * returned LZMA_NO_CHECK, LZMA_UNSUPPORTED_CHECK, or LZMA_GET_CHECK.
+ * Calling this function in any other situation has undefined behavior.
+ */
+extern LZMA_API(lzma_check) lzma_get_check(const lzma_stream *strm)
+ lzma_nothrow;
diff --git a/Utilities/cmliblzma/liblzma/api/lzma/container.h b/Utilities/cmliblzma/liblzma/api/lzma/container.h
new file mode 100644
index 000000000..7a9ffc645
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/api/lzma/container.h
@@ -0,0 +1,424 @@
+/**
+ * \file lzma/container.h
+ * \brief File formats
+ */
+
+/*
+ * Author: Lasse Collin
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ *
+ * See ../lzma.h for information about liblzma as a whole.
+ */
+
+#ifndef LZMA_H_INTERNAL
+# error Never include this file directly. Use <lzma.h> instead.
+#endif
+
+
+/************
+ * Encoding *
+ ************/
+
+/**
+ * \brief Default compression preset
+ *
+ * It's not straightforward to recommend a default preset, because in some
+ * cases keeping the resource usage relatively low is more important that
+ * getting the maximum compression ratio.
+ */
+#define LZMA_PRESET_DEFAULT UINT32_C(6)
+
+
+/**
+ * \brief Mask for preset level
+ *
+ * This is useful only if you need to extract the level from the preset
+ * variable. That should be rare.
+ */
+#define LZMA_PRESET_LEVEL_MASK UINT32_C(0x1F)
+
+
+/*
+ * Preset flags
+ *
+ * Currently only one flag is defined.
+ */
+
+/**
+ * \brief Extreme compression preset
+ *
+ * This flag modifies the preset to make the encoding significantly slower
+ * while improving the compression ratio only marginally. This is useful
+ * when you don't mind wasting time to get as small result as possible.
+ *
+ * This flag doesn't affect the memory usage requirements of the decoder (at
+ * least not significantly). The memory usage of the encoder may be increased
+ * a little but only at the lowest preset levels (0-3).
+ */
+#define LZMA_PRESET_EXTREME (UINT32_C(1) << 31)
+
+
+/**
+ * \brief Calculate approximate memory usage of easy encoder
+ *
+ * This function is a wrapper for lzma_raw_encoder_memusage().
+ *
+ * \param preset Compression preset (level and possible flags)
+ *
+ * \return Number of bytes of memory required for the given
+ * preset when encoding. If an error occurs, for example
+ * due to unsupported preset, UINT64_MAX is returned.
+ */
+extern LZMA_API(uint64_t) lzma_easy_encoder_memusage(uint32_t preset)
+ lzma_nothrow lzma_attr_pure;
+
+
+/**
+ * \brief Calculate approximate decoder memory usage of a preset
+ *
+ * This function is a wrapper for lzma_raw_decoder_memusage().
+ *
+ * \param preset Compression preset (level and possible flags)
+ *
+ * \return Number of bytes of memory required to decompress a file
+ * that was compressed using the given preset. If an error
+ * occurs, for example due to unsupported preset, UINT64_MAX
+ * is returned.
+ */
+extern LZMA_API(uint64_t) lzma_easy_decoder_memusage(uint32_t preset)
+ lzma_nothrow lzma_attr_pure;
+
+
+/**
+ * \brief Initialize .xz Stream encoder using a preset number
+ *
+ * This function is intended for those who just want to use the basic features
+ * if liblzma (that is, most developers out there).
+ *
+ * \param strm Pointer to lzma_stream that is at least initialized
+ * with LZMA_STREAM_INIT.
+ * \param preset Compression preset to use. A preset consist of level
+ * number and zero or more flags. Usually flags aren't
+ * used, so preset is simply a number [0, 9] which match
+ * the options -0 ... -9 of the xz command line tool.
+ * Additional flags can be be set using bitwise-or with
+ * the preset level number, e.g. 6 | LZMA_PRESET_EXTREME.
+ * \param check Integrity check type to use. See check.h for available
+ * checks. The xz command line tool defaults to
+ * LZMA_CHECK_CRC64, which is a good choice if you are
+ * unsure. LZMA_CHECK_CRC32 is good too as long as the
+ * uncompressed file is not many gigabytes.
+ *
+ * \return - LZMA_OK: Initialization succeeded. Use lzma_code() to
+ * encode your data.
+ * - LZMA_MEM_ERROR: Memory allocation failed.
+ * - LZMA_OPTIONS_ERROR: The given compression preset is not
+ * supported by this build of liblzma.
+ * - LZMA_UNSUPPORTED_CHECK: The given check type is not
+ * supported by this liblzma build.
+ * - LZMA_PROG_ERROR: One or more of the parameters have values
+ * that will never be valid. For example, strm == NULL.
+ *
+ * If initialization fails (return value is not LZMA_OK), all the memory
+ * allocated for *strm by liblzma is always freed. Thus, there is no need
+ * to call lzma_end() after failed initialization.
+ *
+ * If initialization succeeds, use lzma_code() to do the actual encoding.
+ * Valid values for `action' (the second argument of lzma_code()) are
+ * LZMA_RUN, LZMA_SYNC_FLUSH, LZMA_FULL_FLUSH, and LZMA_FINISH. In future,
+ * there may be compression levels or flags that don't support LZMA_SYNC_FLUSH.
+ */
+extern LZMA_API(lzma_ret) lzma_easy_encoder(
+ lzma_stream *strm, uint32_t preset, lzma_check check)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Single-call .xz Stream encoding using a preset number
+ *
+ * The maximum required output buffer size can be calculated with
+ * lzma_stream_buffer_bound().
+ *
+ * \param preset Compression preset to use. See the description
+ * in lzma_easy_encoder().
+ * \param check Type of the integrity check to calculate from
+ * uncompressed data.
+ * \param allocator lzma_allocator for custom allocator functions.
+ * Set to NULL to use malloc() and free().
+ * \param in Beginning of the input buffer
+ * \param in_size Size of the input buffer
+ * \param out Beginning of the output buffer
+ * \param out_pos The next byte will be written to out[*out_pos].
+ * *out_pos is updated only if encoding succeeds.
+ * \param out_size Size of the out buffer; the first byte into
+ * which no data is written to is out[out_size].
+ *
+ * \return - LZMA_OK: Encoding was successful.
+ * - LZMA_BUF_ERROR: Not enough output buffer space.
+ * - LZMA_UNSUPPORTED_CHECK
+ * - LZMA_OPTIONS_ERROR
+ * - LZMA_MEM_ERROR
+ * - LZMA_DATA_ERROR
+ * - LZMA_PROG_ERROR
+ */
+extern LZMA_API(lzma_ret) lzma_easy_buffer_encode(
+ uint32_t preset, lzma_check check,
+ lzma_allocator *allocator, const uint8_t *in, size_t in_size,
+ uint8_t *out, size_t *out_pos, size_t out_size) lzma_nothrow;
+
+
+/**
+ * \brief Initialize .xz Stream encoder using a custom filter chain
+ *
+ * \param strm Pointer to properly prepared lzma_stream
+ * \param filters Array of filters. This must be terminated with
+ * filters[n].id = LZMA_VLI_UNKNOWN. See filter.h for
+ * more information.
+ * \param check Type of the integrity check to calculate from
+ * uncompressed data.
+ *
+ * \return - LZMA_OK: Initialization was successful.
+ * - LZMA_MEM_ERROR
+ * - LZMA_UNSUPPORTED_CHECK
+ * - LZMA_OPTIONS_ERROR
+ * - LZMA_PROG_ERROR
+ */
+extern LZMA_API(lzma_ret) lzma_stream_encoder(lzma_stream *strm,
+ const lzma_filter *filters, lzma_check check)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Initialize .lzma encoder (legacy file format)
+ *
+ * The .lzma format is sometimes called the LZMA_Alone format, which is the
+ * reason for the name of this function. The .lzma format supports only the
+ * LZMA1 filter. There is no support for integrity checks like CRC32.
+ *
+ * Use this function if and only if you need to create files readable by
+ * legacy LZMA tools such as LZMA Utils 4.32.x. Moving to the .xz format
+ * is strongly recommended.
+ *
+ * The valid action values for lzma_code() are LZMA_RUN and LZMA_FINISH.
+ * No kind of flushing is supported, because the file format doesn't make
+ * it possible.
+ *
+ * \return - LZMA_OK
+ * - LZMA_MEM_ERROR
+ * - LZMA_OPTIONS_ERROR
+ * - LZMA_PROG_ERROR
+ */
+extern LZMA_API(lzma_ret) lzma_alone_encoder(
+ lzma_stream *strm, const lzma_options_lzma *options)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Calculate output buffer size for single-call Stream encoder
+ *
+ * When trying to compress uncompressible data, the encoded size will be
+ * slightly bigger than the input data. This function calculates how much
+ * output buffer space is required to be sure that lzma_stream_buffer_encode()
+ * doesn't return LZMA_BUF_ERROR.
+ *
+ * The calculated value is not exact, but it is guaranteed to be big enough.
+ * The actual maximum output space required may be slightly smaller (up to
+ * about 100 bytes). This should not be a problem in practice.
+ *
+ * If the calculated maximum size doesn't fit into size_t or would make the
+ * Stream grow past LZMA_VLI_MAX (which should never happen in practice),
+ * zero is returned to indicate the error.
+ *
+ * \note The limit calculated by this function applies only to
+ * single-call encoding. Multi-call encoding may (and probably
+ * will) have larger maximum expansion when encoding
+ * uncompressible data. Currently there is no function to
+ * calculate the maximum expansion of multi-call encoding.
+ */
+extern LZMA_API(size_t) lzma_stream_buffer_bound(size_t uncompressed_size)
+ lzma_nothrow;
+
+
+/**
+ * \brief Single-call .xz Stream encoder
+ *
+ * \param filters Array of filters. This must be terminated with
+ * filters[n].id = LZMA_VLI_UNKNOWN. See filter.h
+ * for more information.
+ * \param check Type of the integrity check to calculate from
+ * uncompressed data.
+ * \param allocator lzma_allocator for custom allocator functions.
+ * Set to NULL to use malloc() and free().
+ * \param in Beginning of the input buffer
+ * \param in_size Size of the input buffer
+ * \param out Beginning of the output buffer
+ * \param out_pos The next byte will be written to out[*out_pos].
+ * *out_pos is updated only if encoding succeeds.
+ * \param out_size Size of the out buffer; the first byte into
+ * which no data is written to is out[out_size].
+ *
+ * \return - LZMA_OK: Encoding was successful.
+ * - LZMA_BUF_ERROR: Not enough output buffer space.
+ * - LZMA_UNSUPPORTED_CHECK
+ * - LZMA_OPTIONS_ERROR
+ * - LZMA_MEM_ERROR
+ * - LZMA_DATA_ERROR
+ * - LZMA_PROG_ERROR
+ */
+extern LZMA_API(lzma_ret) lzma_stream_buffer_encode(
+ lzma_filter *filters, lzma_check check,
+ lzma_allocator *allocator, const uint8_t *in, size_t in_size,
+ uint8_t *out, size_t *out_pos, size_t out_size)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/************
+ * Decoding *
+ ************/
+
+/**
+ * This flag makes lzma_code() return LZMA_NO_CHECK if the input stream
+ * being decoded has no integrity check. Note that when used with
+ * lzma_auto_decoder(), all .lzma files will trigger LZMA_NO_CHECK
+ * if LZMA_TELL_NO_CHECK is used.
+ */
+#define LZMA_TELL_NO_CHECK UINT32_C(0x01)
+
+
+/**
+ * This flag makes lzma_code() return LZMA_UNSUPPORTED_CHECK if the input
+ * stream has an integrity check, but the type of the integrity check is not
+ * supported by this liblzma version or build. Such files can still be
+ * decoded, but the integrity check cannot be verified.
+ */
+#define LZMA_TELL_UNSUPPORTED_CHECK UINT32_C(0x02)
+
+
+/**
+ * This flag makes lzma_code() return LZMA_GET_CHECK as soon as the type
+ * of the integrity check is known. The type can then be got with
+ * lzma_get_check().
+ */
+#define LZMA_TELL_ANY_CHECK UINT32_C(0x04)
+
+
+/**
+ * This flag enables decoding of concatenated files with file formats that
+ * allow concatenating compressed files as is. From the formats currently
+ * supported by liblzma, only the .xz format allows concatenated files.
+ * Concatenated files are not allowed with the legacy .lzma format.
+ *
+ * This flag also affects the usage of the `action' argument for lzma_code().
+ * When LZMA_CONCATENATED is used, lzma_code() won't return LZMA_STREAM_END
+ * unless LZMA_FINISH is used as `action'. Thus, the application has to set
+ * LZMA_FINISH in the same way as it does when encoding.
+ *
+ * If LZMA_CONCATENATED is not used, the decoders still accept LZMA_FINISH
+ * as `action' for lzma_code(), but the usage of LZMA_FINISH isn't required.
+ */
+#define LZMA_CONCATENATED UINT32_C(0x08)
+
+
+/**
+ * \brief Initialize .xz Stream decoder
+ *
+ * \param strm Pointer to properly prepared lzma_stream
+ * \param memlimit Memory usage limit as bytes. Use UINT64_MAX
+ * to effectively disable the limiter.
+ * \param flags Bitwise-or of zero or more of the decoder flags:
+ * LZMA_TELL_NO_CHECK, LZMA_TELL_UNSUPPORTED_CHECK,
+ * LZMA_TELL_ANY_CHECK, LZMA_CONCATENATED
+ *
+ * \return - LZMA_OK: Initialization was successful.
+ * - LZMA_MEM_ERROR: Cannot allocate memory.
+ * - LZMA_OPTIONS_ERROR: Unsupported flags
+ * - LZMA_PROG_ERROR
+ */
+extern LZMA_API(lzma_ret) lzma_stream_decoder(
+ lzma_stream *strm, uint64_t memlimit, uint32_t flags)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Decode .xz Streams and .lzma files with autodetection
+ *
+ * This decoder autodetects between the .xz and .lzma file formats, and
+ * calls lzma_stream_decoder() or lzma_alone_decoder() once the type
+ * of the input file has been detected.
+ *
+ * \param strm Pointer to properly prepared lzma_stream
+ * \param memlimit Memory usage limit as bytes. Use UINT64_MAX
+ * to effectively disable the limiter.
+ * \param flags Bitwise-or of flags, or zero for no flags.
+ *
+ * \return - LZMA_OK: Initialization was successful.
+ * - LZMA_MEM_ERROR: Cannot allocate memory.
+ * - LZMA_OPTIONS_ERROR: Unsupported flags
+ * - LZMA_PROG_ERROR
+ */
+extern LZMA_API(lzma_ret) lzma_auto_decoder(
+ lzma_stream *strm, uint64_t memlimit, uint32_t flags)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Initialize .lzma decoder (legacy file format)
+ *
+ * Valid `action' arguments to lzma_code() are LZMA_RUN and LZMA_FINISH.
+ * There is no need to use LZMA_FINISH, but allowing it may simplify
+ * certain types of applications.
+ *
+ * \return - LZMA_OK
+ * - LZMA_MEM_ERROR
+ * - LZMA_PROG_ERROR
+ */
+extern LZMA_API(lzma_ret) lzma_alone_decoder(
+ lzma_stream *strm, uint64_t memlimit)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Single-call .xz Stream decoder
+ *
+ * \param memlimit Pointer to how much memory the decoder is allowed
+ * to allocate. The value pointed by this pointer is
+ * modified if and only if LZMA_MEMLIMIT_ERROR is
+ * returned.
+ * \param flags Bitwise-or of zero or more of the decoder flags:
+ * LZMA_TELL_NO_CHECK, LZMA_TELL_UNSUPPORTED_CHECK,
+ * LZMA_CONCATENATED. Note that LZMA_TELL_ANY_CHECK
+ * is not allowed and will return LZMA_PROG_ERROR.
+ * \param allocator lzma_allocator for custom allocator functions.
+ * Set to NULL to use malloc() and free().
+ * \param in Beginning of the input buffer
+ * \param in_pos The next byte will be read from in[*in_pos].
+ * *in_pos is updated only if decoding succeeds.
+ * \param in_size Size of the input buffer; the first byte that
+ * won't be read is in[in_size].
+ * \param out Beginning of the output buffer
+ * \param out_pos The next byte will be written to out[*out_pos].
+ * *out_pos is updated only if decoding succeeds.
+ * \param out_size Size of the out buffer; the first byte into
+ * which no data is written to is out[out_size].
+ *
+ * \return - LZMA_OK: Decoding was successful.
+ * - LZMA_FORMAT_ERROR
+ * - LZMA_OPTIONS_ERROR
+ * - LZMA_DATA_ERROR
+ * - LZMA_NO_CHECK: This can be returned only if using
+ * the LZMA_TELL_NO_CHECK flag.
+ * - LZMA_UNSUPPORTED_CHECK: This can be returned only if using
+ * the LZMA_TELL_UNSUPPORTED_CHECK flag.
+ * - LZMA_MEM_ERROR
+ * - LZMA_MEMLIMIT_ERROR: Memory usage limit was reached.
+ * The minimum required memlimit value was stored to *memlimit.
+ * - LZMA_BUF_ERROR: Output buffer was too small.
+ * - LZMA_PROG_ERROR
+ */
+extern LZMA_API(lzma_ret) lzma_stream_buffer_decode(
+ uint64_t *memlimit, uint32_t flags, lzma_allocator *allocator,
+ const uint8_t *in, size_t *in_pos, size_t in_size,
+ uint8_t *out, size_t *out_pos, size_t out_size)
+ lzma_nothrow lzma_attr_warn_unused_result;
diff --git a/Utilities/cmliblzma/liblzma/api/lzma/delta.h b/Utilities/cmliblzma/liblzma/api/lzma/delta.h
new file mode 100644
index 000000000..592fc4f84
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/api/lzma/delta.h
@@ -0,0 +1,77 @@
+/**
+ * \file lzma/delta.h
+ * \brief Delta filter
+ */
+
+/*
+ * Author: Lasse Collin
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ *
+ * See ../lzma.h for information about liblzma as a whole.
+ */
+
+#ifndef LZMA_H_INTERNAL
+# error Never include this file directly. Use <lzma.h> instead.
+#endif
+
+
+/**
+ * \brief Filter ID
+ *
+ * Filter ID of the Delta filter. This is used as lzma_filter.id.
+ */
+#define LZMA_FILTER_DELTA LZMA_VLI_C(0x03)
+
+
+/**
+ * \brief Type of the delta calculation
+ *
+ * Currently only byte-wise delta is supported. Other possible types could
+ * be, for example, delta of 16/32/64-bit little/big endian integers, but
+ * these are not currently planned since byte-wise delta is almost as good.
+ */
+typedef enum {
+ LZMA_DELTA_TYPE_BYTE
+} lzma_delta_type;
+
+
+/**
+ * \brief Options for the Delta filter
+ *
+ * These options are needed by both encoder and decoder.
+ */
+typedef struct {
+ /** For now, this must always be LZMA_DELTA_TYPE_BYTE. */
+ lzma_delta_type type;
+
+ /**
+ * \brief Delta distance
+ *
+ * With the only currently supported type, LZMA_DELTA_TYPE_BYTE,
+ * the distance is as bytes.
+ *
+ * Examples:
+ * - 16-bit stereo audio: distance = 4 bytes
+ * - 24-bit RGB image data: distance = 3 bytes
+ */
+ uint32_t dist;
+# define LZMA_DELTA_DIST_MIN 1
+# define LZMA_DELTA_DIST_MAX 256
+
+ /*
+ * Reserved space to allow possible future extensions without
+ * breaking the ABI. You should not touch these, because the names
+ * of these variables may change. These are and will never be used
+ * when type is LZMA_DELTA_TYPE_BYTE, so it is safe to leave these
+ * uninitialized.
+ */
+ uint32_t reserved_int1;
+ uint32_t reserved_int2;
+ uint32_t reserved_int3;
+ uint32_t reserved_int4;
+ void *reserved_ptr1;
+ void *reserved_ptr2;
+
+} lzma_options_delta;
diff --git a/Utilities/cmliblzma/liblzma/api/lzma/filter.h b/Utilities/cmliblzma/liblzma/api/lzma/filter.h
new file mode 100644
index 000000000..e0bc163ad
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/api/lzma/filter.h
@@ -0,0 +1,424 @@
+/**
+ * \file lzma/filter.h
+ * \brief Common filter related types and functions
+ */
+
+/*
+ * Author: Lasse Collin
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ *
+ * See ../lzma.h for information about liblzma as a whole.
+ */
+
+#ifndef LZMA_H_INTERNAL
+# error Never include this file directly. Use <lzma.h> instead.
+#endif
+
+
+/**
+ * \brief Maximum number of filters in a chain
+ *
+ * A filter chain can have 1-4 filters, of which three are allowed to change
+ * the size of the data. Usually only one or two filters are needed.
+ */
+#define LZMA_FILTERS_MAX 4
+
+
+/**
+ * \brief Filter options
+ *
+ * This structure is used to pass Filter ID and a pointer filter's
+ * options to liblzma. A few functions work with a single lzma_filter
+ * structure, while most functions expect a filter chain.
+ *
+ * A filter chain is indicated with an array of lzma_filter structures.
+ * The array is terminated with .id = LZMA_VLI_UNKNOWN. Thus, the filter
+ * array must have LZMA_FILTERS_MAX + 1 elements (that is, five) to
+ * be able to hold any arbitrary filter chain. This is important when
+ * using lzma_block_header_decode() from block.h, because too small
+ * array would make liblzma write past the end of the filters array.
+ */
+typedef struct {
+ /**
+ * \brief Filter ID
+ *
+ * Use constants whose name begin with `LZMA_FILTER_' to specify
+ * different filters. In an array of lzma_filter structures, use
+ * LZMA_VLI_UNKNOWN to indicate end of filters.
+ *
+ * \note This is not an enum, because on some systems enums
+ * cannot be 64-bit.
+ */
+ lzma_vli id;
+
+ /**
+ * \brief Pointer to filter-specific options structure
+ *
+ * If the filter doesn't need options, set this to NULL. If id is
+ * set to LZMA_VLI_UNKNOWN, options is ignored, and thus
+ * doesn't need be initialized.
+ */
+ void *options;
+
+} lzma_filter;
+
+
+/**
+ * \brief Test if the given Filter ID is supported for encoding
+ *
+ * Return true if the give Filter ID is supported for encoding by this
+ * liblzma build. Otherwise false is returned.
+ *
+ * There is no way to list which filters are available in this particular
+ * liblzma version and build. It would be useless, because the application
+ * couldn't know what kind of options the filter would need.
+ */
+extern LZMA_API(lzma_bool) lzma_filter_encoder_is_supported(lzma_vli id)
+ lzma_nothrow lzma_attr_const;
+
+
+/**
+ * \brief Test if the given Filter ID is supported for decoding
+ *
+ * Return true if the give Filter ID is supported for decoding by this
+ * liblzma build. Otherwise false is returned.
+ */
+extern LZMA_API(lzma_bool) lzma_filter_decoder_is_supported(lzma_vli id)
+ lzma_nothrow lzma_attr_const;
+
+
+/**
+ * \brief Copy the filters array
+ *
+ * Copy the Filter IDs and filter-specific options from src to dest.
+ * Up to LZMA_FILTERS_MAX filters are copied, plus the terminating
+ * .id == LZMA_VLI_UNKNOWN. Thus, dest should have at least
+ * LZMA_FILTERS_MAX + 1 elements space unless the caller knows that
+ * src is smaller than that.
+ *
+ * Unless the filter-specific options is NULL, the Filter ID has to be
+ * supported by liblzma, because liblzma needs to know the size of every
+ * filter-specific options structure. The filter-specific options are not
+ * validated. If options is NULL, any unsupported Filter IDs are copied
+ * without returning an error.
+ *
+ * Old filter-specific options in dest are not freed, so dest doesn't
+ * need to be initialized by the caller in any way.
+ *
+ * If an error occurs, memory possibly already allocated by this function
+ * is always freed.
+ *
+ * \return - LZMA_OK
+ * - LZMA_MEM_ERROR
+ * - LZMA_OPTIONS_ERROR: Unsupported Filter ID and its options
+ * is not NULL.
+ * - LZMA_PROG_ERROR: src or dest is NULL.
+ */
+extern LZMA_API(lzma_ret) lzma_filters_copy(const lzma_filter *src,
+ lzma_filter *dest, lzma_allocator *allocator) lzma_nothrow;
+
+
+/**
+ * \brief Calculate approximate memory requirements for raw encoder
+ *
+ * This function can be used to calculate the memory requirements for
+ * Block and Stream encoders too because Block and Stream encoders don't
+ * need significantly more memory than raw encoder.
+ *
+ * \param filters Array of filters terminated with
+ * .id == LZMA_VLI_UNKNOWN.
+ *
+ * \return Number of bytes of memory required for the given
+ * filter chain when encoding. If an error occurs,
+ * for example due to unsupported filter chain,
+ * UINT64_MAX is returned.
+ */
+extern LZMA_API(uint64_t) lzma_raw_encoder_memusage(const lzma_filter *filters)
+ lzma_nothrow lzma_attr_pure;
+
+
+/**
+ * \brief Calculate approximate memory requirements for raw decoder
+ *
+ * This function can be used to calculate the memory requirements for
+ * Block and Stream decoders too because Block and Stream decoders don't
+ * need significantly more memory than raw decoder.
+ *
+ * \param filters Array of filters terminated with
+ * .id == LZMA_VLI_UNKNOWN.
+ *
+ * \return Number of bytes of memory required for the given
+ * filter chain when decoding. If an error occurs,
+ * for example due to unsupported filter chain,
+ * UINT64_MAX is returned.
+ */
+extern LZMA_API(uint64_t) lzma_raw_decoder_memusage(const lzma_filter *filters)
+ lzma_nothrow lzma_attr_pure;
+
+
+/**
+ * \brief Initialize raw encoder
+ *
+ * This function may be useful when implementing custom file formats.
+ *
+ * \param strm Pointer to properly prepared lzma_stream
+ * \param filters Array of lzma_filter structures. The end of the
+ * array must be marked with .id = LZMA_VLI_UNKNOWN.
+ *
+ * The `action' with lzma_code() can be LZMA_RUN, LZMA_SYNC_FLUSH (if the
+ * filter chain supports it), or LZMA_FINISH.
+ *
+ * \return - LZMA_OK
+ * - LZMA_MEM_ERROR
+ * - LZMA_OPTIONS_ERROR
+ * - LZMA_PROG_ERROR
+ */
+extern LZMA_API(lzma_ret) lzma_raw_encoder(
+ lzma_stream *strm, const lzma_filter *filters)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Initialize raw decoder
+ *
+ * The initialization of raw decoder goes similarly to raw encoder.
+ *
+ * The `action' with lzma_code() can be LZMA_RUN or LZMA_FINISH. Using
+ * LZMA_FINISH is not required, it is supported just for convenience.
+ *
+ * \return - LZMA_OK
+ * - LZMA_MEM_ERROR
+ * - LZMA_OPTIONS_ERROR
+ * - LZMA_PROG_ERROR
+ */
+extern LZMA_API(lzma_ret) lzma_raw_decoder(
+ lzma_stream *strm, const lzma_filter *filters)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Update the filter chain in the encoder
+ *
+ * This function is for advanced users only. This function has two slightly
+ * different purposes:
+ *
+ * - After LZMA_FULL_FLUSH when using Stream encoder: Set a new filter
+ * chain, which will be used starting from the next Block.
+ *
+ * - After LZMA_SYNC_FLUSH using Raw, Block, or Stream encoder: Change
+ * the filter-specific options in the middle of encoding. The actual
+ * filters in the chain (Filter IDs) cannot be changed. In the future,
+ * it might become possible to change the filter options without
+ * using LZMA_SYNC_FLUSH.
+ *
+ * While rarely useful, this function may be called also when no data has
+ * been compressed yet. In that case, this function will behave as if
+ * LZMA_FULL_FLUSH (Stream encoder) or LZMA_SYNC_FLUSH (Raw or Block
+ * encoder) had been used right before calling this function.
+ *
+ * \return - LZMA_OK
+ * - LZMA_MEM_ERROR
+ * - LZMA_MEMLIMIT_ERROR
+ * - LZMA_OPTIONS_ERROR
+ * - LZMA_PROG_ERROR
+ */
+extern LZMA_API(lzma_ret) lzma_filters_update(
+ lzma_stream *strm, const lzma_filter *filters) lzma_nothrow;
+
+
+/**
+ * \brief Single-call raw encoder
+ *
+ * \param filters Array of lzma_filter structures. The end of the
+ * array must be marked with .id = LZMA_VLI_UNKNOWN.
+ * \param allocator lzma_allocator for custom allocator functions.
+ * Set to NULL to use malloc() and free().
+ * \param in Beginning of the input buffer
+ * \param in_size Size of the input buffer
+ * \param out Beginning of the output buffer
+ * \param out_pos The next byte will be written to out[*out_pos].
+ * *out_pos is updated only if encoding succeeds.
+ * \param out_size Size of the out buffer; the first byte into
+ * which no data is written to is out[out_size].
+ *
+ * \return - LZMA_OK: Encoding was successful.
+ * - LZMA_BUF_ERROR: Not enough output buffer space.
+ * - LZMA_OPTIONS_ERROR
+ * - LZMA_MEM_ERROR
+ * - LZMA_DATA_ERROR
+ * - LZMA_PROG_ERROR
+ *
+ * \note There is no function to calculate how big output buffer
+ * would surely be big enough. (lzma_stream_buffer_bound()
+ * works only for lzma_stream_buffer_encode(); raw encoder
+ * won't necessarily meet that bound.)
+ */
+extern LZMA_API(lzma_ret) lzma_raw_buffer_encode(
+ const lzma_filter *filters, lzma_allocator *allocator,
+ const uint8_t *in, size_t in_size, uint8_t *out,
+ size_t *out_pos, size_t out_size) lzma_nothrow;
+
+
+/**
+ * \brief Single-call raw decoder
+ *
+ * \param filters Array of lzma_filter structures. The end of the
+ * array must be marked with .id = LZMA_VLI_UNKNOWN.
+ * \param allocator lzma_allocator for custom allocator functions.
+ * Set to NULL to use malloc() and free().
+ * \param in Beginning of the input buffer
+ * \param in_pos The next byte will be read from in[*in_pos].
+ * *in_pos is updated only if decoding succeeds.
+ * \param in_size Size of the input buffer; the first byte that
+ * won't be read is in[in_size].
+ * \param out Beginning of the output buffer
+ * \param out_pos The next byte will be written to out[*out_pos].
+ * *out_pos is updated only if encoding succeeds.
+ * \param out_size Size of the out buffer; the first byte into
+ * which no data is written to is out[out_size].
+ */
+extern LZMA_API(lzma_ret) lzma_raw_buffer_decode(
+ const lzma_filter *filters, lzma_allocator *allocator,
+ const uint8_t *in, size_t *in_pos, size_t in_size,
+ uint8_t *out, size_t *out_pos, size_t out_size) lzma_nothrow;
+
+
+/**
+ * \brief Get the size of the Filter Properties field
+ *
+ * This function may be useful when implementing custom file formats
+ * using the raw encoder and decoder.
+ *
+ * \param size Pointer to uint32_t to hold the size of the properties
+ * \param filter Filter ID and options (the size of the properties may
+ * vary depending on the options)
+ *
+ * \return - LZMA_OK
+ * - LZMA_OPTIONS_ERROR
+ * - LZMA_PROG_ERROR
+ *
+ * \note This function validates the Filter ID, but does not
+ * necessarily validate the options. Thus, it is possible
+ * that this returns LZMA_OK while the following call to
+ * lzma_properties_encode() returns LZMA_OPTIONS_ERROR.
+ */
+extern LZMA_API(lzma_ret) lzma_properties_size(
+ uint32_t *size, const lzma_filter *filter) lzma_nothrow;
+
+
+/**
+ * \brief Encode the Filter Properties field
+ *
+ * \param filter Filter ID and options
+ * \param props Buffer to hold the encoded options. The size of
+ * buffer must have been already determined with
+ * lzma_properties_size().
+ *
+ * \return - LZMA_OK
+ * - LZMA_OPTIONS_ERROR
+ * - LZMA_PROG_ERROR
+ *
+ * \note Even this function won't validate more options than actually
+ * necessary. Thus, it is possible that encoding the properties
+ * succeeds but using the same options to initialize the encoder
+ * will fail.
+ *
+ * \note If lzma_properties_size() indicated that the size
+ * of the Filter Properties field is zero, calling
+ * lzma_properties_encode() is not required, but it
+ * won't do any harm either.
+ */
+extern LZMA_API(lzma_ret) lzma_properties_encode(
+ const lzma_filter *filter, uint8_t *props) lzma_nothrow;
+
+
+/**
+ * \brief Decode the Filter Properties field
+ *
+ * \param filter filter->id must have been set to the correct
+ * Filter ID. filter->options doesn't need to be
+ * initialized (it's not freed by this function). The
+ * decoded options will be stored to filter->options.
+ * filter->options is set to NULL if there are no
+ * properties or if an error occurs.
+ * \param allocator Custom memory allocator used to allocate the
+ * options. Set to NULL to use the default malloc(),
+ * and in case of an error, also free().
+ * \param props Input buffer containing the properties.
+ * \param props_size Size of the properties. This must be the exact
+ * size; giving too much or too little input will
+ * return LZMA_OPTIONS_ERROR.
+ *
+ * \return - LZMA_OK
+ * - LZMA_OPTIONS_ERROR
+ * - LZMA_MEM_ERROR
+ */
+extern LZMA_API(lzma_ret) lzma_properties_decode(
+ lzma_filter *filter, lzma_allocator *allocator,
+ const uint8_t *props, size_t props_size) lzma_nothrow;
+
+
+/**
+ * \brief Calculate encoded size of a Filter Flags field
+ *
+ * Knowing the size of Filter Flags is useful to know when allocating
+ * memory to hold the encoded Filter Flags.
+ *
+ * \param size Pointer to integer to hold the calculated size
+ * \param filter Filter ID and associated options whose encoded
+ * size is to be calculated
+ *
+ * \return - LZMA_OK: *size set successfully. Note that this doesn't
+ * guarantee that filter->options is valid, thus
+ * lzma_filter_flags_encode() may still fail.
+ * - LZMA_OPTIONS_ERROR: Unknown Filter ID or unsupported options.
+ * - LZMA_PROG_ERROR: Invalid options
+ *
+ * \note If you need to calculate size of List of Filter Flags,
+ * you need to loop over every lzma_filter entry.
+ */
+extern LZMA_API(lzma_ret) lzma_filter_flags_size(
+ uint32_t *size, const lzma_filter *filter)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Encode Filter Flags into given buffer
+ *
+ * In contrast to some functions, this doesn't allocate the needed buffer.
+ * This is due to how this function is used internally by liblzma.
+ *
+ * \param filter Filter ID and options to be encoded
+ * \param out Beginning of the output buffer
+ * \param out_pos out[*out_pos] is the next write position. This
+ * is updated by the encoder.
+ * \param out_size out[out_size] is the first byte to not write.
+ *
+ * \return - LZMA_OK: Encoding was successful.
+ * - LZMA_OPTIONS_ERROR: Invalid or unsupported options.
+ * - LZMA_PROG_ERROR: Invalid options or not enough output
+ * buffer space (you should have checked it with
+ * lzma_filter_flags_size()).
+ */
+extern LZMA_API(lzma_ret) lzma_filter_flags_encode(const lzma_filter *filter,
+ uint8_t *out, size_t *out_pos, size_t out_size)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Decode Filter Flags from given buffer
+ *
+ * The decoded result is stored into *filter. The old value of
+ * filter->options is not free()d.
+ *
+ * \return - LZMA_OK
+ * - LZMA_OPTIONS_ERROR
+ * - LZMA_MEM_ERROR
+ * - LZMA_PROG_ERROR
+ */
+extern LZMA_API(lzma_ret) lzma_filter_flags_decode(
+ lzma_filter *filter, lzma_allocator *allocator,
+ const uint8_t *in, size_t *in_pos, size_t in_size)
+ lzma_nothrow lzma_attr_warn_unused_result;
diff --git a/Utilities/cmliblzma/liblzma/api/lzma/hardware.h b/Utilities/cmliblzma/liblzma/api/lzma/hardware.h
new file mode 100644
index 000000000..e7dd03c3e
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/api/lzma/hardware.h
@@ -0,0 +1,50 @@
+/**
+ * \file lzma/hardware.h
+ * \brief Hardware information
+ *
+ * Since liblzma can consume a lot of system resources, it also provides
+ * ways to limit the resource usage. Applications linking against liblzma
+ * need to do the actual decisions how much resources to let liblzma to use.
+ * To ease making these decisions, liblzma provides functions to find out
+ * the relevant capabilities of the underlaying hardware. Currently there
+ * is only a function to find out the amount of RAM, but in the future there
+ * will be also a function to detect how many concurrent threads the system
+ * can run.
+ *
+ * \note On some operating systems, these function may temporarily
+ * load a shared library or open file descriptor(s) to find out
+ * the requested hardware information. Unless the application
+ * assumes that specific file descriptors are not touched by
+ * other threads, this should have no effect on thread safety.
+ * Possible operations involving file descriptors will restart
+ * the syscalls if they return EINTR.
+ */
+
+/*
+ * Author: Lasse Collin
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ *
+ * See ../lzma.h for information about liblzma as a whole.
+ */
+
+#ifndef LZMA_H_INTERNAL
+# error Never include this file directly. Use <lzma.h> instead.
+#endif
+
+
+/**
+ * \brief Get the total amount of physical memory (RAM) in bytes
+ *
+ * This function may be useful when determining a reasonable memory
+ * usage limit for decompressing or how much memory it is OK to use
+ * for compressing.
+ *
+ * \return On success, the total amount of physical memory in bytes
+ * is returned. If the amount of RAM cannot be determined,
+ * zero is returned. This can happen if an error occurs
+ * or if there is no code in liblzma to detect the amount
+ * of RAM on the specific operating system.
+ */
+extern LZMA_API(uint64_t) lzma_physmem(void) lzma_nothrow;
diff --git a/Utilities/cmliblzma/liblzma/api/lzma/index.h b/Utilities/cmliblzma/liblzma/api/lzma/index.h
new file mode 100644
index 000000000..16bacc287
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/api/lzma/index.h
@@ -0,0 +1,682 @@
+/**
+ * \file lzma/index.h
+ * \brief Handling of .xz Index and related information
+ */
+
+/*
+ * Author: Lasse Collin
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ *
+ * See ../lzma.h for information about liblzma as a whole.
+ */
+
+#ifndef LZMA_H_INTERNAL
+# error Never include this file directly. Use <lzma.h> instead.
+#endif
+
+
+/**
+ * \brief Opaque data type to hold the Index(es) and other information
+ *
+ * lzma_index often holds just one .xz Index and possibly the Stream Flags
+ * of the same Stream and size of the Stream Padding field. However,
+ * multiple lzma_indexes can be concatenated with lzma_index_cat() and then
+ * there may be information about multiple Streams in the same lzma_index.
+ *
+ * Notes about thread safety: Only one thread may modify lzma_index at
+ * a time. All functions that take non-const pointer to lzma_index
+ * modify it. As long as no thread is modifying the lzma_index, getting
+ * information from the same lzma_index can be done from multiple threads
+ * at the same time with functions that take a const pointer to
+ * lzma_index or use lzma_index_iter. The same iterator must be used
+ * only by one thread at a time, of course, but there can be as many
+ * iterators for the same lzma_index as needed.
+ */
+typedef struct lzma_index_s lzma_index;
+
+
+/**
+ * \brief Iterator to get information about Blocks and Streams
+ */
+typedef struct {
+ struct {
+ /**
+ * \brief Pointer to Stream Flags
+ *
+ * This is NULL if Stream Flags have not been set for
+ * this Stream with lzma_index_stream_flags().
+ */
+ const lzma_stream_flags *flags;
+
+ const void *reserved_ptr1;
+ const void *reserved_ptr2;
+ const void *reserved_ptr3;
+
+ /**
+ * \brief Stream number in the lzma_index
+ *
+ * The first Stream is 1.
+ */
+ lzma_vli number;
+
+ /**
+ * \brief Number of Blocks in the Stream
+ *
+ * If this is zero, the block structure below has
+ * undefined values.
+ */
+ lzma_vli block_count;
+
+ /**
+ * \brief Compressed start offset of this Stream
+ *
+ * The offset is relative to the beginning of the lzma_index
+ * (i.e. usually the beginning of the .xz file).
+ */
+ lzma_vli compressed_offset;
+
+ /**
+ * \brief Uncompressed start offset of this Stream
+ *
+ * The offset is relative to the beginning of the lzma_index
+ * (i.e. usually the beginning of the .xz file).
+ */
+ lzma_vli uncompressed_offset;
+
+ /**
+ * \brief Compressed size of this Stream
+ *
+ * This includes all headers except the possible
+ * Stream Padding after this Stream.
+ */
+ lzma_vli compressed_size;
+
+ /**
+ * \brief Uncompressed size of this Stream
+ */
+ lzma_vli uncompressed_size;
+
+ /**
+ * \brief Size of Stream Padding after this Stream
+ *
+ * If it hasn't been set with lzma_index_stream_padding(),
+ * this defaults to zero. Stream Padding is always
+ * a multiple of four bytes.
+ */
+ lzma_vli padding;
+
+ lzma_vli reserved_vli1;
+ lzma_vli reserved_vli2;
+ lzma_vli reserved_vli3;
+ lzma_vli reserved_vli4;
+ } stream;
+
+ struct {
+ /**
+ * \brief Block number in the file
+ *
+ * The first Block is 1.
+ */
+ lzma_vli number_in_file;
+
+ /**
+ * \brief Compressed start offset of this Block
+ *
+ * This offset is relative to the beginning of the
+ * lzma_index (i.e. usually the beginning of the .xz file).
+ * Normally this is where you should seek in the .xz file
+ * to start decompressing this Block.
+ */
+ lzma_vli compressed_file_offset;
+
+ /**
+ * \brief Uncompressed start offset of this Block
+ *
+ * This offset is relative to the beginning of the lzma_index
+ * (i.e. usually the beginning of the .xz file).
+ *
+ * When doing random-access reading, it is possible that
+ * the target offset is not exactly at Block boundary. One
+ * will need to compare the target offset against
+ * uncompressed_file_offset or uncompressed_stream_offset,
+ * and possibly decode and throw away some amount of data
+ * before reaching the target offset.
+ */
+ lzma_vli uncompressed_file_offset;
+
+ /**
+ * \brief Block number in this Stream
+ *
+ * The first Block is 1.
+ */
+ lzma_vli number_in_stream;
+
+ /**
+ * \brief Compressed start offset of this Block
+ *
+ * This offset is relative to the beginning of the Stream
+ * containing this Block.
+ */
+ lzma_vli compressed_stream_offset;
+
+ /**
+ * \brief Uncompressed start offset of this Block
+ *
+ * This offset is relative to the beginning of the Stream
+ * containing this Block.
+ */
+ lzma_vli uncompressed_stream_offset;
+
+ /**
+ * \brief Uncompressed size of this Block
+ *
+ * You should pass this to the Block decoder if you will
+ * decode this Block. It will allow the Block decoder to
+ * validate the uncompressed size.
+ */
+ lzma_vli uncompressed_size;
+
+ /**
+ * \brief Unpadded size of this Block
+ *
+ * You should pass this to the Block decoder if you will
+ * decode this Block. It will allow the Block decoder to
+ * validate the unpadded size.
+ */
+ lzma_vli unpadded_size;
+
+ /**
+ * \brief Total compressed size
+ *
+ * This includes all headers and padding in this Block.
+ * This is useful if you need to know how many bytes
+ * the Block decoder will actually read.
+ */
+ lzma_vli total_size;
+
+ lzma_vli reserved_vli1;
+ lzma_vli reserved_vli2;
+ lzma_vli reserved_vli3;
+ lzma_vli reserved_vli4;
+
+ const void *reserved_ptr1;
+ const void *reserved_ptr2;
+ const void *reserved_ptr3;
+ const void *reserved_ptr4;
+ } block;
+
+ /*
+ * Internal data which is used to store the state of the iterator.
+ * The exact format may vary between liblzma versions, so don't
+ * touch these in any way.
+ */
+ union {
+ const void *p;
+ size_t s;
+ lzma_vli v;
+ } internal[6];
+} lzma_index_iter;
+
+
+/**
+ * \brief Operation mode for lzma_index_iter_next()
+ */
+typedef enum {
+ LZMA_INDEX_ITER_ANY = 0,
+ /**<
+ * \brief Get the next Block or Stream
+ *
+ * Go to the next Block if the current Stream has at least
+ * one Block left. Otherwise go to the next Stream even if
+ * it has no Blocks. If the Stream has no Blocks
+ * (lzma_index_iter.stream.block_count == 0),
+ * lzma_index_iter.block will have undefined values.
+ */
+
+ LZMA_INDEX_ITER_STREAM = 1,
+ /**<
+ * \brief Get the next Stream
+ *
+ * Go to the next Stream even if the current Stream has
+ * unread Blocks left. If the next Stream has at least one
+ * Block, the iterator will point to the first Block.
+ * If there are no Blocks, lzma_index_iter.block will have
+ * undefined values.
+ */
+
+ LZMA_INDEX_ITER_BLOCK = 2,
+ /**<
+ * \brief Get the next Block
+ *
+ * Go to the next Block if the current Stream has at least
+ * one Block left. If the current Stream has no Blocks left,
+ * the next Stream with at least one Block is located and
+ * the iterator will be made to point to the first Block of
+ * that Stream.
+ */
+
+ LZMA_INDEX_ITER_NONEMPTY_BLOCK = 3
+ /**<
+ * \brief Get the next non-empty Block
+ *
+ * This is like LZMA_INDEX_ITER_BLOCK except that it will
+ * skip Blocks whose Uncompressed Size is zero.
+ */
+
+} lzma_index_iter_mode;
+
+
+/**
+ * \brief Calculate memory usage of lzma_index
+ *
+ * On disk, the size of the Index field depends on both the number of Records
+ * stored and how big values the Records store (due to variable-length integer
+ * encoding). When the Index is kept in lzma_index structure, the memory usage
+ * depends only on the number of Records/Blocks stored in the Index(es), and
+ * in case of concatenated lzma_indexes, the number of Streams. The size in
+ * RAM is almost always significantly bigger than in the encoded form on disk.
+ *
+ * This function calculates an approximate amount of memory needed hold
+ * the given number of Streams and Blocks in lzma_index structure. This
+ * value may vary between CPU architectures and also between liblzma versions
+ * if the internal implementation is modified.
+ */
+extern LZMA_API(uint64_t) lzma_index_memusage(
+ lzma_vli streams, lzma_vli blocks) lzma_nothrow;
+
+
+/**
+ * \brief Calculate the memory usage of an existing lzma_index
+ *
+ * This is a shorthand for lzma_index_memusage(lzma_index_stream_count(i),
+ * lzma_index_block_count(i)).
+ */
+extern LZMA_API(uint64_t) lzma_index_memused(const lzma_index *i)
+ lzma_nothrow;
+
+
+/**
+ * \brief Allocate and initialize a new lzma_index structure
+ *
+ * \return On success, a pointer to an empty initialized lzma_index is
+ * returned. If allocation fails, NULL is returned.
+ */
+extern LZMA_API(lzma_index *) lzma_index_init(lzma_allocator *allocator)
+ lzma_nothrow;
+
+
+/**
+ * \brief Deallocate lzma_index
+ *
+ * If i is NULL, this does nothing.
+ */
+extern LZMA_API(void) lzma_index_end(lzma_index *i, lzma_allocator *allocator)
+ lzma_nothrow;
+
+
+/**
+ * \brief Add a new Block to lzma_index
+ *
+ * \param i Pointer to a lzma_index structure
+ * \param allocator Pointer to lzma_allocator, or NULL to
+ * use malloc()
+ * \param unpadded_size Unpadded Size of a Block. This can be
+ * calculated with lzma_block_unpadded_size()
+ * after encoding or decoding the Block.
+ * \param uncompressed_size Uncompressed Size of a Block. This can be
+ * taken directly from lzma_block structure
+ * after encoding or decoding the Block.
+ *
+ * Appending a new Block does not invalidate iterators. For example,
+ * if an iterator was pointing to the end of the lzma_index, after
+ * lzma_index_append() it is possible to read the next Block with
+ * an existing iterator.
+ *
+ * \return - LZMA_OK
+ * - LZMA_MEM_ERROR
+ * - LZMA_DATA_ERROR: Compressed or uncompressed size of the
+ * Stream or size of the Index field would grow too big.
+ * - LZMA_PROG_ERROR
+ */
+extern LZMA_API(lzma_ret) lzma_index_append(
+ lzma_index *i, lzma_allocator *allocator,
+ lzma_vli unpadded_size, lzma_vli uncompressed_size)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Set the Stream Flags
+ *
+ * Set the Stream Flags of the last (and typically the only) Stream
+ * in lzma_index. This can be useful when reading information from the
+ * lzma_index, because to decode Blocks, knowing the integrity check type
+ * is needed.
+ *
+ * The given Stream Flags are copied into internal preallocated structure
+ * in the lzma_index, thus the caller doesn't need to keep the *stream_flags
+ * available after calling this function.
+ *
+ * \return - LZMA_OK
+ * - LZMA_OPTIONS_ERROR: Unsupported stream_flags->version.
+ * - LZMA_PROG_ERROR
+ */
+extern LZMA_API(lzma_ret) lzma_index_stream_flags(
+ lzma_index *i, const lzma_stream_flags *stream_flags)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Get the types of integrity Checks
+ *
+ * If lzma_index_stream_flags() is used to set the Stream Flags for
+ * every Stream, lzma_index_checks() can be used to get a bitmask to
+ * indicate which Check types have been used. It can be useful e.g. if
+ * showing the Check types to the user.
+ *
+ * The bitmask is 1 << check_id, e.g. CRC32 is 1 << 1 and SHA-256 is 1 << 10.
+ */
+extern LZMA_API(uint32_t) lzma_index_checks(const lzma_index *i)
+ lzma_nothrow lzma_attr_pure;
+
+
+/**
+ * \brief Set the amount of Stream Padding
+ *
+ * Set the amount of Stream Padding of the last (and typically the only)
+ * Stream in the lzma_index. This is needed when planning to do random-access
+ * reading within multiple concatenated Streams.
+ *
+ * By default, the amount of Stream Padding is assumed to be zero bytes.
+ *
+ * \return - LZMA_OK
+ * - LZMA_DATA_ERROR: The file size would grow too big.
+ * - LZMA_PROG_ERROR
+ */
+extern LZMA_API(lzma_ret) lzma_index_stream_padding(
+ lzma_index *i, lzma_vli stream_padding)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Get the number of Streams
+ */
+extern LZMA_API(lzma_vli) lzma_index_stream_count(const lzma_index *i)
+ lzma_nothrow lzma_attr_pure;
+
+
+/**
+ * \brief Get the number of Blocks
+ *
+ * This returns the total number of Blocks in lzma_index. To get number
+ * of Blocks in individual Streams, use lzma_index_iter.
+ */
+extern LZMA_API(lzma_vli) lzma_index_block_count(const lzma_index *i)
+ lzma_nothrow lzma_attr_pure;
+
+
+/**
+ * \brief Get the size of the Index field as bytes
+ *
+ * This is needed to verify the Backward Size field in the Stream Footer.
+ */
+extern LZMA_API(lzma_vli) lzma_index_size(const lzma_index *i)
+ lzma_nothrow lzma_attr_pure;
+
+
+/**
+ * \brief Get the total size of the Stream
+ *
+ * If multiple lzma_indexes have been combined, this works as if the Blocks
+ * were in a single Stream. This is useful if you are going to combine
+ * Blocks from multiple Streams into a single new Stream.
+ */
+extern LZMA_API(lzma_vli) lzma_index_stream_size(const lzma_index *i)
+ lzma_nothrow lzma_attr_pure;
+
+
+/**
+ * \brief Get the total size of the Blocks
+ *
+ * This doesn't include the Stream Header, Stream Footer, Stream Padding,
+ * or Index fields.
+ */
+extern LZMA_API(lzma_vli) lzma_index_total_size(const lzma_index *i)
+ lzma_nothrow lzma_attr_pure;
+
+
+/**
+ * \brief Get the total size of the file
+ *
+ * When no lzma_indexes have been combined with lzma_index_cat() and there is
+ * no Stream Padding, this function is identical to lzma_index_stream_size().
+ * If multiple lzma_indexes have been combined, this includes also the headers
+ * of each separate Stream and the possible Stream Padding fields.
+ */
+extern LZMA_API(lzma_vli) lzma_index_file_size(const lzma_index *i)
+ lzma_nothrow lzma_attr_pure;
+
+
+/**
+ * \brief Get the uncompressed size of the file
+ */
+extern LZMA_API(lzma_vli) lzma_index_uncompressed_size(const lzma_index *i)
+ lzma_nothrow lzma_attr_pure;
+
+
+/**
+ * \brief Initialize an iterator
+ *
+ * \param iter Pointer to a lzma_index_iter structure
+ * \param i lzma_index to which the iterator will be associated
+ *
+ * This function associates the iterator with the given lzma_index, and calls
+ * lzma_index_iter_rewind() on the iterator.
+ *
+ * This function doesn't allocate any memory, thus there is no
+ * lzma_index_iter_end(). The iterator is valid as long as the
+ * associated lzma_index is valid, that is, until lzma_index_end() or
+ * using it as source in lzma_index_cat(). Specifically, lzma_index doesn't
+ * become invalid if new Blocks are added to it with lzma_index_append() or
+ * if it is used as the destination in lzma_index_cat().
+ *
+ * It is safe to make copies of an initialized lzma_index_iter, for example,
+ * to easily restart reading at some particular position.
+ */
+extern LZMA_API(void) lzma_index_iter_init(
+ lzma_index_iter *iter, const lzma_index *i) lzma_nothrow;
+
+
+/**
+ * \brief Rewind the iterator
+ *
+ * Rewind the iterator so that next call to lzma_index_iter_next() will
+ * return the first Block or Stream.
+ */
+extern LZMA_API(void) lzma_index_iter_rewind(lzma_index_iter *iter)
+ lzma_nothrow;
+
+
+/**
+ * \brief Get the next Block or Stream
+ *
+ * \param iter Iterator initialized with lzma_index_iter_init()
+ * \param mode Specify what kind of information the caller wants
+ * to get. See lzma_index_iter_mode for details.
+ *
+ * \return If next Block or Stream matching the mode was found, *iter
+ * is updated and this function returns false. If no Block or
+ * Stream matching the mode is found, *iter is not modified
+ * and this function returns true. If mode is set to an unknown
+ * value, *iter is not modified and this function returns true.
+ */
+extern LZMA_API(lzma_bool) lzma_index_iter_next(
+ lzma_index_iter *iter, lzma_index_iter_mode mode)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Locate a Block
+ *
+ * If it is possible to seek in the .xz file, it is possible to parse
+ * the Index field(s) and use lzma_index_iter_locate() to do random-access
+ * reading with granularity of Block size.
+ *
+ * \param iter Iterator that was earlier initialized with
+ * lzma_index_iter_init().
+ * \param target Uncompressed target offset which the caller would
+ * like to locate from the Stream
+ *
+ * If the target is smaller than the uncompressed size of the Stream (can be
+ * checked with lzma_index_uncompressed_size()):
+ * - Information about the Stream and Block containing the requested
+ * uncompressed offset is stored into *iter.
+ * - Internal state of the iterator is adjusted so that
+ * lzma_index_iter_next() can be used to read subsequent Blocks or Streams.
+ * - This function returns false.
+ *
+ * If target is greater than the uncompressed size of the Stream, *iter
+ * is not modified, and this function returns true.
+ */
+extern LZMA_API(lzma_bool) lzma_index_iter_locate(
+ lzma_index_iter *iter, lzma_vli target) lzma_nothrow;
+
+
+/**
+ * \brief Concatenate lzma_indexes
+ *
+ * Concatenating lzma_indexes is useful when doing random-access reading in
+ * multi-Stream .xz file, or when combining multiple Streams into single
+ * Stream.
+ *
+ * \param dest lzma_index after which src is appended
+ * \param src lzma_index to be appended after dest. If this
+ * function succeeds, the memory allocated for src
+ * is freed or moved to be part of dest, and all
+ * iterators pointing to src will become invalid.
+ * \param allocator Custom memory allocator; can be NULL to use
+ * malloc() and free().
+ *
+ * \return - LZMA_OK: lzma_indexes were concatenated successfully.
+ * src is now a dangling pointer.
+ * - LZMA_DATA_ERROR: *dest would grow too big.
+ * - LZMA_MEM_ERROR
+ * - LZMA_PROG_ERROR
+ */
+extern LZMA_API(lzma_ret) lzma_index_cat(
+ lzma_index *dest, lzma_index *src, lzma_allocator *allocator)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Duplicate lzma_index
+ *
+ * \return A copy of the lzma_index, or NULL if memory allocation failed.
+ */
+extern LZMA_API(lzma_index *) lzma_index_dup(
+ const lzma_index *i, lzma_allocator *allocator)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Initialize .xz Index encoder
+ *
+ * \param strm Pointer to properly prepared lzma_stream
+ * \param i Pointer to lzma_index which should be encoded.
+ *
+ * The valid `action' values for lzma_code() are LZMA_RUN and LZMA_FINISH.
+ * It is enough to use only one of them (you can choose freely; use LZMA_RUN
+ * to support liblzma versions older than 5.0.0).
+ *
+ * \return - LZMA_OK: Initialization succeeded, continue with lzma_code().
+ * - LZMA_MEM_ERROR
+ * - LZMA_PROG_ERROR
+ */
+extern LZMA_API(lzma_ret) lzma_index_encoder(
+ lzma_stream *strm, const lzma_index *i)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Initialize .xz Index decoder
+ *
+ * \param strm Pointer to properly prepared lzma_stream
+ * \param i The decoded Index will be made available via
+ * this pointer. Initially this function will
+ * set *i to NULL (the old value is ignored). If
+ * decoding succeeds (lzma_code() returns
+ * LZMA_STREAM_END), *i will be set to point
+ * to a new lzma_index, which the application
+ * has to later free with lzma_index_end().
+ * \param memlimit How much memory the resulting lzma_index is
+ * allowed to require.
+ *
+ * The valid `action' values for lzma_code() are LZMA_RUN and LZMA_FINISH.
+ * It is enough to use only one of them (you can choose freely; use LZMA_RUN
+ * to support liblzma versions older than 5.0.0).
+ *
+ * \return - LZMA_OK: Initialization succeeded, continue with lzma_code().
+ * - LZMA_MEM_ERROR
+ * - LZMA_MEMLIMIT_ERROR
+ * - LZMA_PROG_ERROR
+ */
+extern LZMA_API(lzma_ret) lzma_index_decoder(
+ lzma_stream *strm, lzma_index **i, uint64_t memlimit)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Single-call .xz Index encoder
+ *
+ * \param i lzma_index to be encoded
+ * \param out Beginning of the output buffer
+ * \param out_pos The next byte will be written to out[*out_pos].
+ * *out_pos is updated only if encoding succeeds.
+ * \param out_size Size of the out buffer; the first byte into
+ * which no data is written to is out[out_size].
+ *
+ * \return - LZMA_OK: Encoding was successful.
+ * - LZMA_BUF_ERROR: Output buffer is too small. Use
+ * lzma_index_size() to find out how much output
+ * space is needed.
+ * - LZMA_PROG_ERROR
+ *
+ * \note This function doesn't take allocator argument since all
+ * the internal data is allocated on stack.
+ */
+extern LZMA_API(lzma_ret) lzma_index_buffer_encode(const lzma_index *i,
+ uint8_t *out, size_t *out_pos, size_t out_size) lzma_nothrow;
+
+
+/**
+ * \brief Single-call .xz Index decoder
+ *
+ * \param i If decoding succeeds, *i will point to a new
+ * lzma_index, which the application has to
+ * later free with lzma_index_end(). If an error
+ * occurs, *i will be NULL. The old value of *i
+ * is always ignored and thus doesn't need to be
+ * initialized by the caller.
+ * \param memlimit Pointer to how much memory the resulting
+ * lzma_index is allowed to require. The value
+ * pointed by this pointer is modified if and only
+ * if LZMA_MEMLIMIT_ERROR is returned.
+ * \param allocator Pointer to lzma_allocator, or NULL to use malloc()
+ * \param in Beginning of the input buffer
+ * \param in_pos The next byte will be read from in[*in_pos].
+ * *in_pos is updated only if decoding succeeds.
+ * \param in_size Size of the input buffer; the first byte that
+ * won't be read is in[in_size].
+ *
+ * \return - LZMA_OK: Decoding was successful.
+ * - LZMA_MEM_ERROR
+ * - LZMA_MEMLIMIT_ERROR: Memory usage limit was reached.
+ * The minimum required memlimit value was stored to *memlimit.
+ * - LZMA_DATA_ERROR
+ * - LZMA_PROG_ERROR
+ */
+extern LZMA_API(lzma_ret) lzma_index_buffer_decode(lzma_index **i,
+ uint64_t *memlimit, lzma_allocator *allocator,
+ const uint8_t *in, size_t *in_pos, size_t in_size)
+ lzma_nothrow;
diff --git a/Utilities/cmliblzma/liblzma/api/lzma/index_hash.h b/Utilities/cmliblzma/liblzma/api/lzma/index_hash.h
new file mode 100644
index 000000000..fa2e048d5
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/api/lzma/index_hash.h
@@ -0,0 +1,107 @@
+/**
+ * \file lzma/index_hash.h
+ * \brief Validate Index by using a hash function
+ *
+ * Hashing makes it possible to use constant amount of memory to validate
+ * Index of arbitrary size.
+ */
+
+/*
+ * Author: Lasse Collin
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ *
+ * See ../lzma.h for information about liblzma as a whole.
+ */
+
+#ifndef LZMA_H_INTERNAL
+# error Never include this file directly. Use <lzma.h> instead.
+#endif
+
+/**
+ * \brief Opaque data type to hold the Index hash
+ */
+typedef struct lzma_index_hash_s lzma_index_hash;
+
+
+/**
+ * \brief Allocate and initialize a new lzma_index_hash structure
+ *
+ * If index_hash is NULL, a new lzma_index_hash structure is allocated,
+ * initialized, and a pointer to it returned. If allocation fails, NULL
+ * is returned.
+ *
+ * If index_hash is non-NULL, it is reinitialized and the same pointer
+ * returned. In this case, return value cannot be NULL or a different
+ * pointer than the index_hash that was given as an argument.
+ */
+extern LZMA_API(lzma_index_hash *) lzma_index_hash_init(
+ lzma_index_hash *index_hash, lzma_allocator *allocator)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Deallocate lzma_index_hash structure
+ */
+extern LZMA_API(void) lzma_index_hash_end(
+ lzma_index_hash *index_hash, lzma_allocator *allocator)
+ lzma_nothrow;
+
+
+/**
+ * \brief Add a new Record to an Index hash
+ *
+ * \param index Pointer to a lzma_index_hash structure
+ * \param unpadded_size Unpadded Size of a Block
+ * \param uncompressed_size Uncompressed Size of a Block
+ *
+ * \return - LZMA_OK
+ * - LZMA_DATA_ERROR: Compressed or uncompressed size of the
+ * Stream or size of the Index field would grow too big.
+ * - LZMA_PROG_ERROR: Invalid arguments or this function is being
+ * used when lzma_index_hash_decode() has already been used.
+ */
+extern LZMA_API(lzma_ret) lzma_index_hash_append(lzma_index_hash *index_hash,
+ lzma_vli unpadded_size, lzma_vli uncompressed_size)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Decode and validate the Index field
+ *
+ * After telling the sizes of all Blocks with lzma_index_hash_append(),
+ * the actual Index field is decoded with this function. Specifically,
+ * once decoding of the Index field has been started, no more Records
+ * can be added using lzma_index_hash_append().
+ *
+ * This function doesn't use lzma_stream structure to pass the input data.
+ * Instead, the input buffer is specified using three arguments. This is
+ * because it matches better the internal APIs of liblzma.
+ *
+ * \param index_hash Pointer to a lzma_index_hash structure
+ * \param in Pointer to the beginning of the input buffer
+ * \param in_pos in[*in_pos] is the next byte to process
+ * \param in_size in[in_size] is the first byte not to process
+ *
+ * \return - LZMA_OK: So far good, but more input is needed.
+ * - LZMA_STREAM_END: Index decoded successfully and it matches
+ * the Records given with lzma_index_hash_append().
+ * - LZMA_DATA_ERROR: Index is corrupt or doesn't match the
+ * information given with lzma_index_hash_append().
+ * - LZMA_BUF_ERROR: Cannot progress because *in_pos >= in_size.
+ * - LZMA_PROG_ERROR
+ */
+extern LZMA_API(lzma_ret) lzma_index_hash_decode(lzma_index_hash *index_hash,
+ const uint8_t *in, size_t *in_pos, size_t in_size)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Get the size of the Index field as bytes
+ *
+ * This is needed to verify the Backward Size field in the Stream Footer.
+ */
+extern LZMA_API(lzma_vli) lzma_index_hash_size(
+ const lzma_index_hash *index_hash)
+ lzma_nothrow lzma_attr_pure;
diff --git a/Utilities/cmliblzma/liblzma/api/lzma/lzma.h b/Utilities/cmliblzma/liblzma/api/lzma/lzma.h
new file mode 100644
index 000000000..3f8e095f7
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/api/lzma/lzma.h
@@ -0,0 +1,420 @@
+/**
+ * \file lzma/lzma.h
+ * \brief LZMA1 and LZMA2 filters
+ */
+
+/*
+ * Author: Lasse Collin
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ *
+ * See ../lzma.h for information about liblzma as a whole.
+ */
+
+#ifndef LZMA_H_INTERNAL
+# error Never include this file directly. Use <lzma.h> instead.
+#endif
+
+
+/**
+ * \brief LZMA1 Filter ID
+ *
+ * LZMA1 is the very same thing as what was called just LZMA in LZMA Utils,
+ * 7-Zip, and LZMA SDK. It's called LZMA1 here to prevent developers from
+ * accidentally using LZMA when they actually want LZMA2.
+ *
+ * LZMA1 shouldn't be used for new applications unless you _really_ know
+ * what you are doing. LZMA2 is almost always a better choice.
+ */
+#define LZMA_FILTER_LZMA1 LZMA_VLI_C(0x4000000000000001)
+
+/**
+ * \brief LZMA2 Filter ID
+ *
+ * Usually you want this instead of LZMA1. Compared to LZMA1, LZMA2 adds
+ * support for LZMA_SYNC_FLUSH, uncompressed chunks (smaller expansion
+ * when trying to compress uncompressible data), possibility to change
+ * lc/lp/pb in the middle of encoding, and some other internal improvements.
+ */
+#define LZMA_FILTER_LZMA2 LZMA_VLI_C(0x21)
+
+
+/**
+ * \brief Match finders
+ *
+ * Match finder has major effect on both speed and compression ratio.
+ * Usually hash chains are faster than binary trees.
+ *
+ * If you will use LZMA_SYNC_FLUSH often, the hash chains may be a better
+ * choice, because binary trees get much higher compression ratio penalty
+ * with LZMA_SYNC_FLUSH.
+ *
+ * The memory usage formulas are only rough estimates, which are closest to
+ * reality when dict_size is a power of two. The formulas are more complex
+ * in reality, and can also change a little between liblzma versions. Use
+ * lzma_raw_encoder_memusage() to get more accurate estimate of memory usage.
+ */
+typedef enum {
+ LZMA_MF_HC3 = 0x03,
+ /**<
+ * \brief Hash Chain with 2- and 3-byte hashing
+ *
+ * Minimum nice_len: 3
+ *
+ * Memory usage:
+ * - dict_size <= 16 MiB: dict_size * 7.5
+ * - dict_size > 16 MiB: dict_size * 5.5 + 64 MiB
+ */
+
+ LZMA_MF_HC4 = 0x04,
+ /**<
+ * \brief Hash Chain with 2-, 3-, and 4-byte hashing
+ *
+ * Minimum nice_len: 4
+ *
+ * Memory usage:
+ * - dict_size <= 32 MiB: dict_size * 7.5
+ * - dict_size > 32 MiB: dict_size * 6.5
+ */
+
+ LZMA_MF_BT2 = 0x12,
+ /**<
+ * \brief Binary Tree with 2-byte hashing
+ *
+ * Minimum nice_len: 2
+ *
+ * Memory usage: dict_size * 9.5
+ */
+
+ LZMA_MF_BT3 = 0x13,
+ /**<
+ * \brief Binary Tree with 2- and 3-byte hashing
+ *
+ * Minimum nice_len: 3
+ *
+ * Memory usage:
+ * - dict_size <= 16 MiB: dict_size * 11.5
+ * - dict_size > 16 MiB: dict_size * 9.5 + 64 MiB
+ */
+
+ LZMA_MF_BT4 = 0x14
+ /**<
+ * \brief Binary Tree with 2-, 3-, and 4-byte hashing
+ *
+ * Minimum nice_len: 4
+ *
+ * Memory usage:
+ * - dict_size <= 32 MiB: dict_size * 11.5
+ * - dict_size > 32 MiB: dict_size * 10.5
+ */
+} lzma_match_finder;
+
+
+/**
+ * \brief Test if given match finder is supported
+ *
+ * Return true if the given match finder is supported by this liblzma build.
+ * Otherwise false is returned. It is safe to call this with a value that
+ * isn't listed in lzma_match_finder enumeration; the return value will be
+ * false.
+ *
+ * There is no way to list which match finders are available in this
+ * particular liblzma version and build. It would be useless, because
+ * a new match finder, which the application developer wasn't aware,
+ * could require giving additional options to the encoder that the older
+ * match finders don't need.
+ */
+extern LZMA_API(lzma_bool) lzma_mf_is_supported(lzma_match_finder match_finder)
+ lzma_nothrow lzma_attr_const;
+
+
+/**
+ * \brief Compression modes
+ *
+ * This selects the function used to analyze the data produced by the match
+ * finder.
+ */
+typedef enum {
+ LZMA_MODE_FAST = 1,
+ /**<
+ * \brief Fast compression
+ *
+ * Fast mode is usually at its best when combined with
+ * a hash chain match finder.
+ */
+
+ LZMA_MODE_NORMAL = 2
+ /**<
+ * \brief Normal compression
+ *
+ * This is usually notably slower than fast mode. Use this
+ * together with binary tree match finders to expose the
+ * full potential of the LZMA1 or LZMA2 encoder.
+ */
+} lzma_mode;
+
+
+/**
+ * \brief Test if given compression mode is supported
+ *
+ * Return true if the given compression mode is supported by this liblzma
+ * build. Otherwise false is returned. It is safe to call this with a value
+ * that isn't listed in lzma_mode enumeration; the return value will be false.
+ *
+ * There is no way to list which modes are available in this particular
+ * liblzma version and build. It would be useless, because a new compression
+ * mode, which the application developer wasn't aware, could require giving
+ * additional options to the encoder that the older modes don't need.
+ */
+extern LZMA_API(lzma_bool) lzma_mode_is_supported(lzma_mode mode)
+ lzma_nothrow lzma_attr_const;
+
+
+/**
+ * \brief Options specific to the LZMA1 and LZMA2 filters
+ *
+ * Since LZMA1 and LZMA2 share most of the code, it's simplest to share
+ * the options structure too. For encoding, all but the reserved variables
+ * need to be initialized unless specifically mentioned otherwise.
+ * lzma_lzma_preset() can be used to get a good starting point.
+ *
+ * For raw decoding, both LZMA1 and LZMA2 need dict_size, preset_dict, and
+ * preset_dict_size (if preset_dict != NULL). LZMA1 needs also lc, lp, and pb.
+ */
+typedef struct {
+ /**
+ * \brief Dictionary size in bytes
+ *
+ * Dictionary size indicates how many bytes of the recently processed
+ * uncompressed data is kept in memory. One method to reduce size of
+ * the uncompressed data is to store distance-length pairs, which
+ * indicate what data to repeat from the dictionary buffer. Thus,
+ * the bigger the dictionary, the better the compression ratio
+ * usually is.
+ *
+ * Maximum size of the dictionary depends on multiple things:
+ * - Memory usage limit
+ * - Available address space (not a problem on 64-bit systems)
+ * - Selected match finder (encoder only)
+ *
+ * Currently the maximum dictionary size for encoding is 1.5 GiB
+ * (i.e. (UINT32_C(1) << 30) + (UINT32_C(1) << 29)) even on 64-bit
+ * systems for certain match finder implementation reasons. In the
+ * future, there may be match finders that support bigger
+ * dictionaries.
+ *
+ * Decoder already supports dictionaries up to 4 GiB - 1 B (i.e.
+ * UINT32_MAX), so increasing the maximum dictionary size of the
+ * encoder won't cause problems for old decoders.
+ *
+ * Because extremely small dictionaries sizes would have unneeded
+ * overhead in the decoder, the minimum dictionary size is 4096 bytes.
+ *
+ * \note When decoding, too big dictionary does no other harm
+ * than wasting memory.
+ */
+ uint32_t dict_size;
+# define LZMA_DICT_SIZE_MIN UINT32_C(4096)
+# define LZMA_DICT_SIZE_DEFAULT (UINT32_C(1) << 23)
+
+ /**
+ * \brief Pointer to an initial dictionary
+ *
+ * It is possible to initialize the LZ77 history window using
+ * a preset dictionary. It is useful when compressing many
+ * similar, relatively small chunks of data independently from
+ * each other. The preset dictionary should contain typical
+ * strings that occur in the files being compressed. The most
+ * probable strings should be near the end of the preset dictionary.
+ *
+ * This feature should be used only in special situations. For
+ * now, it works correctly only with raw encoding and decoding.
+ * Currently none of the container formats supported by
+ * liblzma allow preset dictionary when decoding, thus if
+ * you create a .xz or .lzma file with preset dictionary, it
+ * cannot be decoded with the regular decoder functions. In the
+ * future, the .xz format will likely get support for preset
+ * dictionary though.
+ */
+ const uint8_t *preset_dict;
+
+ /**
+ * \brief Size of the preset dictionary
+ *
+ * Specifies the size of the preset dictionary. If the size is
+ * bigger than dict_size, only the last dict_size bytes are
+ * processed.
+ *
+ * This variable is read only when preset_dict is not NULL.
+ * If preset_dict is not NULL but preset_dict_size is zero,
+ * no preset dictionary is used (identical to only setting
+ * preset_dict to NULL).
+ */
+ uint32_t preset_dict_size;
+
+ /**
+ * \brief Number of literal context bits
+ *
+ * How many of the highest bits of the previous uncompressed
+ * eight-bit byte (also known as `literal') are taken into
+ * account when predicting the bits of the next literal.
+ *
+ * E.g. in typical English text, an upper-case letter is
+ * often followed by a lower-case letter, and a lower-case
+ * letter is usually followed by another lower-case letter.
+ * In the US-ASCII character set, the highest three bits are 010
+ * for upper-case letters and 011 for lower-case letters.
+ * When lc is at least 3, the literal coding can take advantage of
+ * this property in the uncompressed data.
+ *
+ * There is a limit that applies to literal context bits and literal
+ * position bits together: lc + lp <= 4. Without this limit the
+ * decoding could become very slow, which could have security related
+ * results in some cases like email servers doing virus scanning.
+ * This limit also simplifies the internal implementation in liblzma.
+ *
+ * There may be LZMA1 streams that have lc + lp > 4 (maximum possible
+ * lc would be 8). It is not possible to decode such streams with
+ * liblzma.
+ */
+ uint32_t lc;
+# define LZMA_LCLP_MIN 0
+# define LZMA_LCLP_MAX 4
+# define LZMA_LC_DEFAULT 3
+
+ /**
+ * \brief Number of literal position bits
+ *
+ * lp affects what kind of alignment in the uncompressed data is
+ * assumed when encoding literals. A literal is a single 8-bit byte.
+ * See pb below for more information about alignment.
+ */
+ uint32_t lp;
+# define LZMA_LP_DEFAULT 0
+
+ /**
+ * \brief Number of position bits
+ *
+ * pb affects what kind of alignment in the uncompressed data is
+ * assumed in general. The default means four-byte alignment
+ * (2^ pb =2^2=4), which is often a good choice when there's
+ * no better guess.
+ *
+ * When the aligment is known, setting pb accordingly may reduce
+ * the file size a little. E.g. with text files having one-byte
+ * alignment (US-ASCII, ISO-8859-*, UTF-8), setting pb=0 can
+ * improve compression slightly. For UTF-16 text, pb=1 is a good
+ * choice. If the alignment is an odd number like 3 bytes, pb=0
+ * might be the best choice.
+ *
+ * Even though the assumed alignment can be adjusted with pb and
+ * lp, LZMA1 and LZMA2 still slightly favor 16-byte alignment.
+ * It might be worth taking into account when designing file formats
+ * that are likely to be often compressed with LZMA1 or LZMA2.
+ */
+ uint32_t pb;
+# define LZMA_PB_MIN 0
+# define LZMA_PB_MAX 4
+# define LZMA_PB_DEFAULT 2
+
+ /** Compression mode */
+ lzma_mode mode;
+
+ /**
+ * \brief Nice length of a match
+ *
+ * This determines how many bytes the encoder compares from the match
+ * candidates when looking for the best match. Once a match of at
+ * least nice_len bytes long is found, the encoder stops looking for
+ * better candidates and encodes the match. (Naturally, if the found
+ * match is actually longer than nice_len, the actual length is
+ * encoded; it's not truncated to nice_len.)
+ *
+ * Bigger values usually increase the compression ratio and
+ * compression time. For most files, 32 to 128 is a good value,
+ * which gives very good compression ratio at good speed.
+ *
+ * The exact minimum value depends on the match finder. The maximum
+ * is 273, which is the maximum length of a match that LZMA1 and
+ * LZMA2 can encode.
+ */
+ uint32_t nice_len;
+
+ /** Match finder ID */
+ lzma_match_finder mf;
+
+ /**
+ * \brief Maximum search depth in the match finder
+ *
+ * For every input byte, match finder searches through the hash chain
+ * or binary tree in a loop, each iteration going one step deeper in
+ * the chain or tree. The searching stops if
+ * - a match of at least nice_len bytes long is found;
+ * - all match candidates from the hash chain or binary tree have
+ * been checked; or
+ * - maximum search depth is reached.
+ *
+ * Maximum search depth is needed to prevent the match finder from
+ * wasting too much time in case there are lots of short match
+ * candidates. On the other hand, stopping the search before all
+ * candidates have been checked can reduce compression ratio.
+ *
+ * Setting depth to zero tells liblzma to use an automatic default
+ * value, that depends on the selected match finder and nice_len.
+ * The default is in the range [4, 200] or so (it may vary between
+ * liblzma versions).
+ *
+ * Using a bigger depth value than the default can increase
+ * compression ratio in some cases. There is no strict maximum value,
+ * but high values (thousands or millions) should be used with care:
+ * the encoder could remain fast enough with typical input, but
+ * malicious input could cause the match finder to slow down
+ * dramatically, possibly creating a denial of service attack.
+ */
+ uint32_t depth;
+
+ /*
+ * Reserved space to allow possible future extensions without
+ * breaking the ABI. You should not touch these, because the names
+ * of these variables may change. These are and will never be used
+ * with the currently supported options, so it is safe to leave these
+ * uninitialized.
+ */
+ uint32_t reserved_int1;
+ uint32_t reserved_int2;
+ uint32_t reserved_int3;
+ uint32_t reserved_int4;
+ uint32_t reserved_int5;
+ uint32_t reserved_int6;
+ uint32_t reserved_int7;
+ uint32_t reserved_int8;
+ lzma_reserved_enum reserved_enum1;
+ lzma_reserved_enum reserved_enum2;
+ lzma_reserved_enum reserved_enum3;
+ lzma_reserved_enum reserved_enum4;
+ void *reserved_ptr1;
+ void *reserved_ptr2;
+
+} lzma_options_lzma;
+
+
+/**
+ * \brief Set a compression preset to lzma_options_lzma structure
+ *
+ * 0 is the fastest and 9 is the slowest. These match the switches -0 .. -9
+ * of the xz command line tool. In addition, it is possible to bitwise-or
+ * flags to the preset. Currently only LZMA_PRESET_EXTREME is supported.
+ * The flags are defined in container.h, because the flags are used also
+ * with lzma_easy_encoder().
+ *
+ * The preset values are subject to changes between liblzma versions.
+ *
+ * This function is available only if LZMA1 or LZMA2 encoder has been enabled
+ * when building liblzma.
+ *
+ * \return On success, false is returned. If the preset is not
+ * supported, true is returned.
+ */
+extern LZMA_API(lzma_bool) lzma_lzma_preset(
+ lzma_options_lzma *options, uint32_t preset) lzma_nothrow;
diff --git a/Utilities/cmliblzma/liblzma/api/lzma/stream_flags.h b/Utilities/cmliblzma/liblzma/api/lzma/stream_flags.h
new file mode 100644
index 000000000..bbdd40826
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/api/lzma/stream_flags.h
@@ -0,0 +1,223 @@
+/**
+ * \file lzma/stream_flags.h
+ * \brief .xz Stream Header and Stream Footer encoder and decoder
+ */
+
+/*
+ * Author: Lasse Collin
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ *
+ * See ../lzma.h for information about liblzma as a whole.
+ */
+
+#ifndef LZMA_H_INTERNAL
+# error Never include this file directly. Use <lzma.h> instead.
+#endif
+
+
+/**
+ * \brief Size of Stream Header and Stream Footer
+ *
+ * Stream Header and Stream Footer have the same size and they are not
+ * going to change even if a newer version of the .xz file format is
+ * developed in future.
+ */
+#define LZMA_STREAM_HEADER_SIZE 12
+
+
+/**
+ * \brief Options for encoding/decoding Stream Header and Stream Footer
+ */
+typedef struct {
+ /**
+ * \brief Stream Flags format version
+ *
+ * To prevent API and ABI breakages if new features are needed in
+ * Stream Header or Stream Footer, a version number is used to
+ * indicate which fields in this structure are in use. For now,
+ * version must always be zero. With non-zero version, the
+ * lzma_stream_header_encode() and lzma_stream_footer_encode()
+ * will return LZMA_OPTIONS_ERROR.
+ *
+ * lzma_stream_header_decode() and lzma_stream_footer_decode()
+ * will always set this to the lowest value that supports all the
+ * features indicated by the Stream Flags field. The application
+ * must check that the version number set by the decoding functions
+ * is supported by the application. Otherwise it is possible that
+ * the application will decode the Stream incorrectly.
+ */
+ uint32_t version;
+
+ /**
+ * \brief Backward Size
+ *
+ * Backward Size must be a multiple of four bytes. In this Stream
+ * format version, Backward Size is the size of the Index field.
+ *
+ * Backward Size isn't actually part of the Stream Flags field, but
+ * it is convenient to include in this structure anyway. Backward
+ * Size is present only in the Stream Footer. There is no need to
+ * initialize backward_size when encoding Stream Header.
+ *
+ * lzma_stream_header_decode() always sets backward_size to
+ * LZMA_VLI_UNKNOWN so that it is convenient to use
+ * lzma_stream_flags_compare() when both Stream Header and Stream
+ * Footer have been decoded.
+ */
+ lzma_vli backward_size;
+# define LZMA_BACKWARD_SIZE_MIN 4
+# define LZMA_BACKWARD_SIZE_MAX (LZMA_VLI_C(1) << 34)
+
+ /**
+ * \brief Check ID
+ *
+ * This indicates the type of the integrity check calculated from
+ * uncompressed data.
+ */
+ lzma_check check;
+
+ /*
+ * Reserved space to allow possible future extensions without
+ * breaking the ABI. You should not touch these, because the
+ * names of these variables may change.
+ *
+ * (We will never be able to use all of these since Stream Flags
+ * is just two bytes plus Backward Size of four bytes. But it's
+ * nice to have the proper types when they are needed.)
+ */
+ lzma_reserved_enum reserved_enum1;
+ lzma_reserved_enum reserved_enum2;
+ lzma_reserved_enum reserved_enum3;
+ lzma_reserved_enum reserved_enum4;
+ lzma_bool reserved_bool1;
+ lzma_bool reserved_bool2;
+ lzma_bool reserved_bool3;
+ lzma_bool reserved_bool4;
+ lzma_bool reserved_bool5;
+ lzma_bool reserved_bool6;
+ lzma_bool reserved_bool7;
+ lzma_bool reserved_bool8;
+ uint32_t reserved_int1;
+ uint32_t reserved_int2;
+
+} lzma_stream_flags;
+
+
+/**
+ * \brief Encode Stream Header
+ *
+ * \param options Stream Header options to be encoded.
+ * options->backward_size is ignored and doesn't
+ * need to be initialized.
+ * \param out Beginning of the output buffer of
+ * LZMA_STREAM_HEADER_SIZE bytes.
+ *
+ * \return - LZMA_OK: Encoding was successful.
+ * - LZMA_OPTIONS_ERROR: options->version is not supported by
+ * this liblzma version.
+ * - LZMA_PROG_ERROR: Invalid options.
+ */
+extern LZMA_API(lzma_ret) lzma_stream_header_encode(
+ const lzma_stream_flags *options, uint8_t *out)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Encode Stream Footer
+ *
+ * \param options Stream Footer options to be encoded.
+ * \param out Beginning of the output buffer of
+ * LZMA_STREAM_HEADER_SIZE bytes.
+ *
+ * \return - LZMA_OK: Encoding was successful.
+ * - LZMA_OPTIONS_ERROR: options->version is not supported by
+ * this liblzma version.
+ * - LZMA_PROG_ERROR: Invalid options.
+ */
+extern LZMA_API(lzma_ret) lzma_stream_footer_encode(
+ const lzma_stream_flags *options, uint8_t *out)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Decode Stream Header
+ *
+ * \param options Target for the decoded Stream Header options.
+ * \param in Beginning of the input buffer of
+ * LZMA_STREAM_HEADER_SIZE bytes.
+ *
+ * options->backward_size is always set to LZMA_VLI_UNKNOWN. This is to
+ * help comparing Stream Flags from Stream Header and Stream Footer with
+ * lzma_stream_flags_compare().
+ *
+ * \return - LZMA_OK: Decoding was successful.
+ * - LZMA_FORMAT_ERROR: Magic bytes don't match, thus the given
+ * buffer cannot be Stream Header.
+ * - LZMA_DATA_ERROR: CRC32 doesn't match, thus the header
+ * is corrupt.
+ * - LZMA_OPTIONS_ERROR: Unsupported options are present
+ * in the header.
+ *
+ * \note When decoding .xz files that contain multiple Streams, it may
+ * make sense to print "file format not recognized" only if
+ * decoding of the Stream Header of the _first_ Stream gives
+ * LZMA_FORMAT_ERROR. If non-first Stream Header gives
+ * LZMA_FORMAT_ERROR, the message used for LZMA_DATA_ERROR is
+ * probably more appropriate.
+ *
+ * For example, Stream decoder in liblzma uses LZMA_DATA_ERROR if
+ * LZMA_FORMAT_ERROR is returned by lzma_stream_header_decode()
+ * when decoding non-first Stream.
+ */
+extern LZMA_API(lzma_ret) lzma_stream_header_decode(
+ lzma_stream_flags *options, const uint8_t *in)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Decode Stream Footer
+ *
+ * \param options Target for the decoded Stream Header options.
+ * \param in Beginning of the input buffer of
+ * LZMA_STREAM_HEADER_SIZE bytes.
+ *
+ * \return - LZMA_OK: Decoding was successful.
+ * - LZMA_FORMAT_ERROR: Magic bytes don't match, thus the given
+ * buffer cannot be Stream Footer.
+ * - LZMA_DATA_ERROR: CRC32 doesn't match, thus the Stream Footer
+ * is corrupt.
+ * - LZMA_OPTIONS_ERROR: Unsupported options are present
+ * in Stream Footer.
+ *
+ * \note If Stream Header was already decoded successfully, but
+ * decoding Stream Footer returns LZMA_FORMAT_ERROR, the
+ * application should probably report some other error message
+ * than "file format not recognized", since the file more likely
+ * is corrupt (possibly truncated). Stream decoder in liblzma
+ * uses LZMA_DATA_ERROR in this situation.
+ */
+extern LZMA_API(lzma_ret) lzma_stream_footer_decode(
+ lzma_stream_flags *options, const uint8_t *in)
+ lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief Compare two lzma_stream_flags structures
+ *
+ * backward_size values are compared only if both are not
+ * LZMA_VLI_UNKNOWN.
+ *
+ * \return - LZMA_OK: Both are equal. If either had backward_size set
+ * to LZMA_VLI_UNKNOWN, backward_size values were not
+ * compared or validated.
+ * - LZMA_DATA_ERROR: The structures differ.
+ * - LZMA_OPTIONS_ERROR: version in either structure is greater
+ * than the maximum supported version (currently zero).
+ * - LZMA_PROG_ERROR: Invalid value, e.g. invalid check or
+ * backward_size.
+ */
+extern LZMA_API(lzma_ret) lzma_stream_flags_compare(
+ const lzma_stream_flags *a, const lzma_stream_flags *b)
+ lzma_nothrow lzma_attr_pure;
diff --git a/Utilities/cmliblzma/liblzma/api/lzma/version.h b/Utilities/cmliblzma/liblzma/api/lzma/version.h
new file mode 100644
index 000000000..66e93965d
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/api/lzma/version.h
@@ -0,0 +1,121 @@
+/**
+ * \file lzma/version.h
+ * \brief Version number
+ */
+
+/*
+ * Author: Lasse Collin
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ *
+ * See ../lzma.h for information about liblzma as a whole.
+ */
+
+#ifndef LZMA_H_INTERNAL
+# error Never include this file directly. Use <lzma.h> instead.
+#endif
+
+
+/*
+ * Version number split into components
+ */
+#define LZMA_VERSION_MAJOR 5
+#define LZMA_VERSION_MINOR 0
+#define LZMA_VERSION_PATCH 5
+#define LZMA_VERSION_STABILITY LZMA_VERSION_STABILITY_STABLE
+
+#ifndef LZMA_VERSION_COMMIT
+# define LZMA_VERSION_COMMIT ""
+#endif
+
+
+/*
+ * Map symbolic stability levels to integers.
+ */
+#define LZMA_VERSION_STABILITY_ALPHA 0
+#define LZMA_VERSION_STABILITY_BETA 1
+#define LZMA_VERSION_STABILITY_STABLE 2
+
+
+/**
+ * \brief Compile-time version number
+ *
+ * The version number is of format xyyyzzzs where
+ * - x = major
+ * - yyy = minor
+ * - zzz = revision
+ * - s indicates stability: 0 = alpha, 1 = beta, 2 = stable
+ *
+ * The same xyyyzzz triplet is never reused with different stability levels.
+ * For example, if 5.1.0alpha has been released, there will never be 5.1.0beta
+ * or 5.1.0 stable.
+ *
+ * \note The version number of liblzma has nothing to with
+ * the version number of Igor Pavlov's LZMA SDK.
+ */
+#define LZMA_VERSION (LZMA_VERSION_MAJOR * UINT32_C(10000000) \
+ + LZMA_VERSION_MINOR * UINT32_C(10000) \
+ + LZMA_VERSION_PATCH * UINT32_C(10) \
+ + LZMA_VERSION_STABILITY)
+
+
+/*
+ * Macros to construct the compile-time version string
+ */
+#if LZMA_VERSION_STABILITY == LZMA_VERSION_STABILITY_ALPHA
+# define LZMA_VERSION_STABILITY_STRING "alpha"
+#elif LZMA_VERSION_STABILITY == LZMA_VERSION_STABILITY_BETA
+# define LZMA_VERSION_STABILITY_STRING "beta"
+#elif LZMA_VERSION_STABILITY == LZMA_VERSION_STABILITY_STABLE
+# define LZMA_VERSION_STABILITY_STRING ""
+#else
+# error Incorrect LZMA_VERSION_STABILITY
+#endif
+
+#define LZMA_VERSION_STRING_C_(major, minor, patch, stability, commit) \
+ #major "." #minor "." #patch stability commit
+
+#define LZMA_VERSION_STRING_C(major, minor, patch, stability, commit) \
+ LZMA_VERSION_STRING_C_(major, minor, patch, stability, commit)
+
+
+/**
+ * \brief Compile-time version as a string
+ *
+ * This can be for example "4.999.5alpha", "4.999.8beta", or "5.0.0" (stable
+ * versions don't have any "stable" suffix). In future, a snapshot built
+ * from source code repository may include an additional suffix, for example
+ * "4.999.8beta-21-g1d92". The commit ID won't be available in numeric form
+ * in LZMA_VERSION macro.
+ */
+#define LZMA_VERSION_STRING LZMA_VERSION_STRING_C( \
+ LZMA_VERSION_MAJOR, LZMA_VERSION_MINOR, \
+ LZMA_VERSION_PATCH, LZMA_VERSION_STABILITY_STRING, \
+ LZMA_VERSION_COMMIT)
+
+
+/* #ifndef is needed for use with windres (MinGW or Cygwin). */
+#ifndef LZMA_H_INTERNAL_RC
+
+/**
+ * \brief Run-time version number as an integer
+ *
+ * Return the value of LZMA_VERSION macro at the compile time of liblzma.
+ * This allows the application to compare if it was built against the same,
+ * older, or newer version of liblzma that is currently running.
+ */
+extern LZMA_API(uint32_t) lzma_version_number(void)
+ lzma_nothrow lzma_attr_const;
+
+
+/**
+ * \brief Run-time version as a string
+ *
+ * This function may be useful if you want to display which version of
+ * liblzma your application is currently using.
+ */
+extern LZMA_API(const char *) lzma_version_string(void)
+ lzma_nothrow lzma_attr_const;
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/api/lzma/vli.h b/Utilities/cmliblzma/liblzma/api/lzma/vli.h
new file mode 100644
index 000000000..9ad13f2e2
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/api/lzma/vli.h
@@ -0,0 +1,166 @@
+/**
+ * \file lzma/vli.h
+ * \brief Variable-length integer handling
+ *
+ * In the .xz format, most integers are encoded in a variable-length
+ * representation, which is sometimes called little endian base-128 encoding.
+ * This saves space when smaller values are more likely than bigger values.
+ *
+ * The encoding scheme encodes seven bits to every byte, using minimum
+ * number of bytes required to represent the given value. Encodings that use
+ * non-minimum number of bytes are invalid, thus every integer has exactly
+ * one encoded representation. The maximum number of bits in a VLI is 63,
+ * thus the vli argument must be less than or equal to UINT64_MAX / 2. You
+ * should use LZMA_VLI_MAX for clarity.
+ */
+
+/*
+ * Author: Lasse Collin
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ *
+ * See ../lzma.h for information about liblzma as a whole.
+ */
+
+#ifndef LZMA_H_INTERNAL
+# error Never include this file directly. Use <lzma.h> instead.
+#endif
+
+
+/**
+ * \brief Maximum supported value of a variable-length integer
+ */
+#define LZMA_VLI_MAX (UINT64_MAX / 2)
+
+/**
+ * \brief VLI value to denote that the value is unknown
+ */
+#define LZMA_VLI_UNKNOWN UINT64_MAX
+
+/**
+ * \brief Maximum supported encoded length of variable length integers
+ */
+#define LZMA_VLI_BYTES_MAX 9
+
+/**
+ * \brief VLI constant suffix
+ */
+#define LZMA_VLI_C(n) UINT64_C(n)
+
+
+/**
+ * \brief Variable-length integer type
+ *
+ * Valid VLI values are in the range [0, LZMA_VLI_MAX]. Unknown value is
+ * indicated with LZMA_VLI_UNKNOWN, which is the maximum value of the
+ * underlaying integer type.
+ *
+ * lzma_vli will be uint64_t for the foreseeable future. If a bigger size
+ * is needed in the future, it is guaranteed that 2 * LZMA_VLI_MAX will
+ * not overflow lzma_vli. This simplifies integer overflow detection.
+ */
+typedef uint64_t lzma_vli;
+
+
+/**
+ * \brief Validate a variable-length integer
+ *
+ * This is useful to test that application has given acceptable values
+ * for example in the uncompressed_size and compressed_size variables.
+ *
+ * \return True if the integer is representable as VLI or if it
+ * indicates unknown value.
+ */
+#define lzma_vli_is_valid(vli) \
+ ((vli) <= LZMA_VLI_MAX || (vli) == LZMA_VLI_UNKNOWN)
+
+
+/**
+ * \brief Encode a variable-length integer
+ *
+ * This function has two modes: single-call and multi-call. Single-call mode
+ * encodes the whole integer at once; it is an error if the output buffer is
+ * too small. Multi-call mode saves the position in *vli_pos, and thus it is
+ * possible to continue encoding if the buffer becomes full before the whole
+ * integer has been encoded.
+ *
+ * \param vli Integer to be encoded
+ * \param vli_pos How many VLI-encoded bytes have already been written
+ * out. When starting to encode a new integer in
+ * multi-call mode, *vli_pos must be set to zero.
+ * To use single-call encoding, set vli_pos to NULL.
+ * \param out Beginning of the output buffer
+ * \param out_pos The next byte will be written to out[*out_pos].
+ * \param out_size Size of the out buffer; the first byte into
+ * which no data is written to is out[out_size].
+ *
+ * \return Slightly different return values are used in multi-call and
+ * single-call modes.
+ *
+ * Single-call (vli_pos == NULL):
+ * - LZMA_OK: Integer successfully encoded.
+ * - LZMA_PROG_ERROR: Arguments are not sane. This can be due
+ * to too little output space; single-call mode doesn't use
+ * LZMA_BUF_ERROR, since the application should have checked
+ * the encoded size with lzma_vli_size().
+ *
+ * Multi-call (vli_pos != NULL):
+ * - LZMA_OK: So far all OK, but the integer is not
+ * completely written out yet.
+ * - LZMA_STREAM_END: Integer successfully encoded.
+ * - LZMA_BUF_ERROR: No output space was provided.
+ * - LZMA_PROG_ERROR: Arguments are not sane.
+ */
+extern LZMA_API(lzma_ret) lzma_vli_encode(lzma_vli vli, size_t *vli_pos,
+ uint8_t *out, size_t *out_pos, size_t out_size) lzma_nothrow;
+
+
+/**
+ * \brief Decode a variable-length integer
+ *
+ * Like lzma_vli_encode(), this function has single-call and multi-call modes.
+ *
+ * \param vli Pointer to decoded integer. The decoder will
+ * initialize it to zero when *vli_pos == 0, so
+ * application isn't required to initialize *vli.
+ * \param vli_pos How many bytes have already been decoded. When
+ * starting to decode a new integer in multi-call
+ * mode, *vli_pos must be initialized to zero. To
+ * use single-call decoding, set vli_pos to NULL.
+ * \param in Beginning of the input buffer
+ * \param in_pos The next byte will be read from in[*in_pos].
+ * \param in_size Size of the input buffer; the first byte that
+ * won't be read is in[in_size].
+ *
+ * \return Slightly different return values are used in multi-call and
+ * single-call modes.
+ *
+ * Single-call (vli_pos == NULL):
+ * - LZMA_OK: Integer successfully decoded.
+ * - LZMA_DATA_ERROR: Integer is corrupt. This includes hitting
+ * the end of the input buffer before the whole integer was
+ * decoded; providing no input at all will use LZMA_DATA_ERROR.
+ * - LZMA_PROG_ERROR: Arguments are not sane.
+ *
+ * Multi-call (vli_pos != NULL):
+ * - LZMA_OK: So far all OK, but the integer is not
+ * completely decoded yet.
+ * - LZMA_STREAM_END: Integer successfully decoded.
+ * - LZMA_DATA_ERROR: Integer is corrupt.
+ * - LZMA_BUF_ERROR: No input was provided.
+ * - LZMA_PROG_ERROR: Arguments are not sane.
+ */
+extern LZMA_API(lzma_ret) lzma_vli_decode(lzma_vli *vli, size_t *vli_pos,
+ const uint8_t *in, size_t *in_pos, size_t in_size)
+ lzma_nothrow;
+
+
+/**
+ * \brief Get the number of bytes required to encode a VLI
+ *
+ * \return Number of bytes on success (1-9). If vli isn't valid,
+ * zero is returned.
+ */
+extern LZMA_API(uint32_t) lzma_vli_size(lzma_vli vli)
+ lzma_nothrow lzma_attr_pure;
diff --git a/Utilities/cmliblzma/liblzma/check/check.c b/Utilities/cmliblzma/liblzma/check/check.c
new file mode 100644
index 000000000..979b0a818
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/check/check.c
@@ -0,0 +1,174 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file check.c
+/// \brief Single API to access different integrity checks
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "check.h"
+
+
+extern LZMA_API(lzma_bool)
+lzma_check_is_supported(lzma_check type)
+{
+ static const lzma_bool available_checks[LZMA_CHECK_ID_MAX + 1] = {
+ true, // LZMA_CHECK_NONE
+
+#ifdef HAVE_CHECK_CRC32
+ true,
+#else
+ false,
+#endif
+
+ false, // Reserved
+ false, // Reserved
+
+#ifdef HAVE_CHECK_CRC64
+ true,
+#else
+ false,
+#endif
+
+ false, // Reserved
+ false, // Reserved
+ false, // Reserved
+ false, // Reserved
+ false, // Reserved
+
+#ifdef HAVE_CHECK_SHA256
+ true,
+#else
+ false,
+#endif
+
+ false, // Reserved
+ false, // Reserved
+ false, // Reserved
+ false, // Reserved
+ false, // Reserved
+ };
+
+ if ((unsigned int)(type) > LZMA_CHECK_ID_MAX)
+ return false;
+
+ return available_checks[(unsigned int)(type)];
+}
+
+
+extern LZMA_API(uint32_t)
+lzma_check_size(lzma_check type)
+{
+ // See file-format.txt section 2.1.1.2.
+ static const uint8_t check_sizes[LZMA_CHECK_ID_MAX + 1] = {
+ 0,
+ 4, 4, 4,
+ 8, 8, 8,
+ 16, 16, 16,
+ 32, 32, 32,
+ 64, 64, 64
+ };
+
+ if ((unsigned int)(type) > LZMA_CHECK_ID_MAX)
+ return UINT32_MAX;
+
+ return check_sizes[(unsigned int)(type)];
+}
+
+
+extern void
+lzma_check_init(lzma_check_state *check, lzma_check type)
+{
+ switch (type) {
+ case LZMA_CHECK_NONE:
+ break;
+
+#ifdef HAVE_CHECK_CRC32
+ case LZMA_CHECK_CRC32:
+ check->state.crc32 = 0;
+ break;
+#endif
+
+#ifdef HAVE_CHECK_CRC64
+ case LZMA_CHECK_CRC64:
+ check->state.crc64 = 0;
+ break;
+#endif
+
+#ifdef HAVE_CHECK_SHA256
+ case LZMA_CHECK_SHA256:
+ lzma_sha256_init(check);
+ break;
+#endif
+
+ default:
+ break;
+ }
+
+ return;
+}
+
+
+extern void
+lzma_check_update(lzma_check_state *check, lzma_check type,
+ const uint8_t *buf, size_t size)
+{
+ switch (type) {
+#ifdef HAVE_CHECK_CRC32
+ case LZMA_CHECK_CRC32:
+ check->state.crc32 = lzma_crc32(buf, size, check->state.crc32);
+ break;
+#endif
+
+#ifdef HAVE_CHECK_CRC64
+ case LZMA_CHECK_CRC64:
+ check->state.crc64 = lzma_crc64(buf, size, check->state.crc64);
+ break;
+#endif
+
+#ifdef HAVE_CHECK_SHA256
+ case LZMA_CHECK_SHA256:
+ lzma_sha256_update(buf, size, check);
+ break;
+#endif
+
+ default:
+ break;
+ }
+
+ return;
+}
+
+
+extern void
+lzma_check_finish(lzma_check_state *check, lzma_check type)
+{
+ switch (type) {
+#ifdef HAVE_CHECK_CRC32
+ case LZMA_CHECK_CRC32:
+ check->buffer.u32[0] = conv32le(check->state.crc32);
+ break;
+#endif
+
+#ifdef HAVE_CHECK_CRC64
+ case LZMA_CHECK_CRC64:
+ check->buffer.u64[0] = conv64le(check->state.crc64);
+ break;
+#endif
+
+#ifdef HAVE_CHECK_SHA256
+ case LZMA_CHECK_SHA256:
+ lzma_sha256_finish(check);
+ break;
+#endif
+
+ default:
+ break;
+ }
+
+ return;
+}
diff --git a/Utilities/cmliblzma/liblzma/check/check.h b/Utilities/cmliblzma/liblzma/check/check.h
new file mode 100644
index 000000000..e100d2b85
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/check/check.h
@@ -0,0 +1,95 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file check.h
+/// \brief Internal API to different integrity check functions
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_CHECK_H
+#define LZMA_CHECK_H
+
+#include "common.h"
+
+
+// Index hashing needs the best possible hash function (preferably
+// a cryptographic hash) for maximum reliability.
+#if defined(HAVE_CHECK_SHA256)
+# define LZMA_CHECK_BEST LZMA_CHECK_SHA256
+#elif defined(HAVE_CHECK_CRC64)
+# define LZMA_CHECK_BEST LZMA_CHECK_CRC64
+#else
+# define LZMA_CHECK_BEST LZMA_CHECK_CRC32
+#endif
+
+
+/// \brief Structure to hold internal state of the check being calculated
+///
+/// \note This is not in the public API because this structure may
+/// change in future if new integrity check algorithms are added.
+typedef struct {
+ /// Buffer to hold the final result and a temporary buffer for SHA256.
+ union {
+ uint8_t u8[64];
+ uint32_t u32[16];
+ uint64_t u64[8];
+ } buffer;
+
+ /// Check-specific data
+ union {
+ uint32_t crc32;
+ uint64_t crc64;
+
+ struct {
+ /// Internal state
+ uint32_t state[8];
+
+ /// Size of the message excluding padding
+ uint64_t size;
+ } sha256;
+ } state;
+
+} lzma_check_state;
+
+
+/// lzma_crc32_table[0] is needed by LZ encoder so we need to keep
+/// the array two-dimensional.
+#ifdef HAVE_SMALL
+extern uint32_t lzma_crc32_table[1][256];
+extern void lzma_crc32_init(void);
+#else
+extern const uint32_t lzma_crc32_table[8][256];
+extern const uint64_t lzma_crc64_table[4][256];
+#endif
+
+
+/// \brief Initialize *check depending on type
+///
+/// \return LZMA_OK on success. LZMA_UNSUPPORTED_CHECK if the type is not
+/// supported by the current version or build of liblzma.
+/// LZMA_PROG_ERROR if type > LZMA_CHECK_ID_MAX.
+extern void lzma_check_init(lzma_check_state *check, lzma_check type);
+
+/// Update the check state
+extern void lzma_check_update(lzma_check_state *check, lzma_check type,
+ const uint8_t *buf, size_t size);
+
+/// Finish the check calculation and store the result to check->buffer.u8.
+extern void lzma_check_finish(lzma_check_state *check, lzma_check type);
+
+
+/// Prepare SHA-256 state for new input.
+extern void lzma_sha256_init(lzma_check_state *check);
+
+/// Update the SHA-256 hash state
+extern void lzma_sha256_update(
+ const uint8_t *buf, size_t size, lzma_check_state *check);
+
+/// Finish the SHA-256 calculation and store the result to check->buffer.u8.
+extern void lzma_sha256_finish(lzma_check_state *check);
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/check/crc32_fast.c b/Utilities/cmliblzma/liblzma/check/crc32_fast.c
new file mode 100644
index 000000000..13f65b497
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/check/crc32_fast.c
@@ -0,0 +1,86 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file crc32.c
+/// \brief CRC32 calculation
+///
+/// Calculate the CRC32 using the slice-by-eight algorithm.
+/// It is explained in this document:
+/// http://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf
+/// The code in this file is not the same as in Intel's paper, but
+/// the basic principle is identical.
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "check.h"
+#include "crc_macros.h"
+
+
+// If you make any changes, do some bench marking! Seemingly unrelated
+// changes can very easily ruin the performance (and very probably is
+// very compiler dependent).
+extern LZMA_API(uint32_t)
+lzma_crc32(const uint8_t *buf, size_t size, uint32_t crc)
+{
+ crc = ~crc;
+
+#ifdef WORDS_BIGENDIAN
+ crc = bswap32(crc);
+#endif
+
+ if (size > 8) {
+ const uint8_t * limit;
+
+ // Fix the alignment, if needed. The if statement above
+ // ensures that this won't read past the end of buf[].
+ while ((uintptr_t)(buf) & 7) {
+ crc = lzma_crc32_table[0][*buf++ ^ A(crc)] ^ S8(crc);
+ --size;
+ }
+
+ // Calculate the position where to stop.
+ limit = buf + (size & ~(size_t)(7));
+
+ // Calculate how many bytes must be calculated separately
+ // before returning the result.
+ size &= (size_t)(7);
+
+ // Calculate the CRC32 using the slice-by-eight algorithm.
+ while (buf < limit) {
+ uint32_t tmp;
+
+ crc ^= *(const uint32_t *)(buf);
+ buf += 4;
+
+ crc = lzma_crc32_table[7][A(crc)]
+ ^ lzma_crc32_table[6][B(crc)]
+ ^ lzma_crc32_table[5][C(crc)]
+ ^ lzma_crc32_table[4][D(crc)];
+
+ tmp = *(const uint32_t *)(buf);
+ buf += 4;
+
+ // At least with some compilers, it is critical for
+ // performance, that the crc variable is XORed
+ // between the two table-lookup pairs.
+ crc = lzma_crc32_table[3][A(tmp)]
+ ^ lzma_crc32_table[2][B(tmp)]
+ ^ crc
+ ^ lzma_crc32_table[1][C(tmp)]
+ ^ lzma_crc32_table[0][D(tmp)];
+ }
+ }
+
+ while (size-- != 0)
+ crc = lzma_crc32_table[0][*buf++ ^ A(crc)] ^ S8(crc);
+
+#ifdef WORDS_BIGENDIAN
+ crc = bswap32(crc);
+#endif
+
+ return ~crc;
+}
diff --git a/Utilities/cmliblzma/liblzma/check/crc32_small.c b/Utilities/cmliblzma/liblzma/check/crc32_small.c
new file mode 100644
index 000000000..5f8a32868
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/check/crc32_small.c
@@ -0,0 +1,61 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file crc32_small.c
+/// \brief CRC32 calculation (size-optimized)
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "check.h"
+
+
+uint32_t lzma_crc32_table[1][256];
+
+
+static void
+crc32_init(void)
+{
+ static const uint32_t poly32 = UINT32_C(0xEDB88320);
+
+ for (size_t b = 0; b < 256; ++b) {
+ uint32_t r = b;
+ for (size_t i = 0; i < 8; ++i) {
+ if (r & 1)
+ r = (r >> 1) ^ poly32;
+ else
+ r >>= 1;
+ }
+
+ lzma_crc32_table[0][b] = r;
+ }
+
+ return;
+}
+
+
+extern void
+lzma_crc32_init(void)
+{
+ mythread_once(crc32_init);
+ return;
+}
+
+
+extern LZMA_API(uint32_t)
+lzma_crc32(const uint8_t *buf, size_t size, uint32_t crc)
+{
+ lzma_crc32_init();
+
+ crc = ~crc;
+
+ while (size != 0) {
+ crc = lzma_crc32_table[0][*buf++ ^ (crc & 0xFF)] ^ (crc >> 8);
+ --size;
+ }
+
+ return ~crc;
+}
diff --git a/Utilities/cmliblzma/liblzma/check/crc32_table.c b/Utilities/cmliblzma/liblzma/check/crc32_table.c
new file mode 100644
index 000000000..368874eb7
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/check/crc32_table.c
@@ -0,0 +1,19 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file crc32_table.c
+/// \brief Precalculated CRC32 table with correct endianness
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "common.h"
+
+#ifdef WORDS_BIGENDIAN
+# include "crc32_table_be.h"
+#else
+# include "crc32_table_le.h"
+#endif
diff --git a/Utilities/cmliblzma/liblzma/check/crc32_table_be.h b/Utilities/cmliblzma/liblzma/check/crc32_table_be.h
new file mode 100644
index 000000000..c483cb670
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/check/crc32_table_be.h
@@ -0,0 +1,525 @@
+/* This file has been automatically generated by crc32_tablegen.c. */
+
+const uint32_t lzma_crc32_table[8][256] = {
+ {
+ 0x00000000, 0x96300777, 0x2C610EEE, 0xBA510999,
+ 0x19C46D07, 0x8FF46A70, 0x35A563E9, 0xA395649E,
+ 0x3288DB0E, 0xA4B8DC79, 0x1EE9D5E0, 0x88D9D297,
+ 0x2B4CB609, 0xBD7CB17E, 0x072DB8E7, 0x911DBF90,
+ 0x6410B71D, 0xF220B06A, 0x4871B9F3, 0xDE41BE84,
+ 0x7DD4DA1A, 0xEBE4DD6D, 0x51B5D4F4, 0xC785D383,
+ 0x56986C13, 0xC0A86B64, 0x7AF962FD, 0xECC9658A,
+ 0x4F5C0114, 0xD96C0663, 0x633D0FFA, 0xF50D088D,
+ 0xC8206E3B, 0x5E10694C, 0xE44160D5, 0x727167A2,
+ 0xD1E4033C, 0x47D4044B, 0xFD850DD2, 0x6BB50AA5,
+ 0xFAA8B535, 0x6C98B242, 0xD6C9BBDB, 0x40F9BCAC,
+ 0xE36CD832, 0x755CDF45, 0xCF0DD6DC, 0x593DD1AB,
+ 0xAC30D926, 0x3A00DE51, 0x8051D7C8, 0x1661D0BF,
+ 0xB5F4B421, 0x23C4B356, 0x9995BACF, 0x0FA5BDB8,
+ 0x9EB80228, 0x0888055F, 0xB2D90CC6, 0x24E90BB1,
+ 0x877C6F2F, 0x114C6858, 0xAB1D61C1, 0x3D2D66B6,
+ 0x9041DC76, 0x0671DB01, 0xBC20D298, 0x2A10D5EF,
+ 0x8985B171, 0x1FB5B606, 0xA5E4BF9F, 0x33D4B8E8,
+ 0xA2C90778, 0x34F9000F, 0x8EA80996, 0x18980EE1,
+ 0xBB0D6A7F, 0x2D3D6D08, 0x976C6491, 0x015C63E6,
+ 0xF4516B6B, 0x62616C1C, 0xD8306585, 0x4E0062F2,
+ 0xED95066C, 0x7BA5011B, 0xC1F40882, 0x57C40FF5,
+ 0xC6D9B065, 0x50E9B712, 0xEAB8BE8B, 0x7C88B9FC,
+ 0xDF1DDD62, 0x492DDA15, 0xF37CD38C, 0x654CD4FB,
+ 0x5861B24D, 0xCE51B53A, 0x7400BCA3, 0xE230BBD4,
+ 0x41A5DF4A, 0xD795D83D, 0x6DC4D1A4, 0xFBF4D6D3,
+ 0x6AE96943, 0xFCD96E34, 0x468867AD, 0xD0B860DA,
+ 0x732D0444, 0xE51D0333, 0x5F4C0AAA, 0xC97C0DDD,
+ 0x3C710550, 0xAA410227, 0x10100BBE, 0x86200CC9,
+ 0x25B56857, 0xB3856F20, 0x09D466B9, 0x9FE461CE,
+ 0x0EF9DE5E, 0x98C9D929, 0x2298D0B0, 0xB4A8D7C7,
+ 0x173DB359, 0x810DB42E, 0x3B5CBDB7, 0xAD6CBAC0,
+ 0x2083B8ED, 0xB6B3BF9A, 0x0CE2B603, 0x9AD2B174,
+ 0x3947D5EA, 0xAF77D29D, 0x1526DB04, 0x8316DC73,
+ 0x120B63E3, 0x843B6494, 0x3E6A6D0D, 0xA85A6A7A,
+ 0x0BCF0EE4, 0x9DFF0993, 0x27AE000A, 0xB19E077D,
+ 0x44930FF0, 0xD2A30887, 0x68F2011E, 0xFEC20669,
+ 0x5D5762F7, 0xCB676580, 0x71366C19, 0xE7066B6E,
+ 0x761BD4FE, 0xE02BD389, 0x5A7ADA10, 0xCC4ADD67,
+ 0x6FDFB9F9, 0xF9EFBE8E, 0x43BEB717, 0xD58EB060,
+ 0xE8A3D6D6, 0x7E93D1A1, 0xC4C2D838, 0x52F2DF4F,
+ 0xF167BBD1, 0x6757BCA6, 0xDD06B53F, 0x4B36B248,
+ 0xDA2B0DD8, 0x4C1B0AAF, 0xF64A0336, 0x607A0441,
+ 0xC3EF60DF, 0x55DF67A8, 0xEF8E6E31, 0x79BE6946,
+ 0x8CB361CB, 0x1A8366BC, 0xA0D26F25, 0x36E26852,
+ 0x95770CCC, 0x03470BBB, 0xB9160222, 0x2F260555,
+ 0xBE3BBAC5, 0x280BBDB2, 0x925AB42B, 0x046AB35C,
+ 0xA7FFD7C2, 0x31CFD0B5, 0x8B9ED92C, 0x1DAEDE5B,
+ 0xB0C2649B, 0x26F263EC, 0x9CA36A75, 0x0A936D02,
+ 0xA906099C, 0x3F360EEB, 0x85670772, 0x13570005,
+ 0x824ABF95, 0x147AB8E2, 0xAE2BB17B, 0x381BB60C,
+ 0x9B8ED292, 0x0DBED5E5, 0xB7EFDC7C, 0x21DFDB0B,
+ 0xD4D2D386, 0x42E2D4F1, 0xF8B3DD68, 0x6E83DA1F,
+ 0xCD16BE81, 0x5B26B9F6, 0xE177B06F, 0x7747B718,
+ 0xE65A0888, 0x706A0FFF, 0xCA3B0666, 0x5C0B0111,
+ 0xFF9E658F, 0x69AE62F8, 0xD3FF6B61, 0x45CF6C16,
+ 0x78E20AA0, 0xEED20DD7, 0x5483044E, 0xC2B30339,
+ 0x612667A7, 0xF71660D0, 0x4D476949, 0xDB776E3E,
+ 0x4A6AD1AE, 0xDC5AD6D9, 0x660BDF40, 0xF03BD837,
+ 0x53AEBCA9, 0xC59EBBDE, 0x7FCFB247, 0xE9FFB530,
+ 0x1CF2BDBD, 0x8AC2BACA, 0x3093B353, 0xA6A3B424,
+ 0x0536D0BA, 0x9306D7CD, 0x2957DE54, 0xBF67D923,
+ 0x2E7A66B3, 0xB84A61C4, 0x021B685D, 0x942B6F2A,
+ 0x37BE0BB4, 0xA18E0CC3, 0x1BDF055A, 0x8DEF022D
+ }, {
+ 0x00000000, 0x41311B19, 0x82623632, 0xC3532D2B,
+ 0x04C56C64, 0x45F4777D, 0x86A75A56, 0xC796414F,
+ 0x088AD9C8, 0x49BBC2D1, 0x8AE8EFFA, 0xCBD9F4E3,
+ 0x0C4FB5AC, 0x4D7EAEB5, 0x8E2D839E, 0xCF1C9887,
+ 0x5112C24A, 0x1023D953, 0xD370F478, 0x9241EF61,
+ 0x55D7AE2E, 0x14E6B537, 0xD7B5981C, 0x96848305,
+ 0x59981B82, 0x18A9009B, 0xDBFA2DB0, 0x9ACB36A9,
+ 0x5D5D77E6, 0x1C6C6CFF, 0xDF3F41D4, 0x9E0E5ACD,
+ 0xA2248495, 0xE3159F8C, 0x2046B2A7, 0x6177A9BE,
+ 0xA6E1E8F1, 0xE7D0F3E8, 0x2483DEC3, 0x65B2C5DA,
+ 0xAAAE5D5D, 0xEB9F4644, 0x28CC6B6F, 0x69FD7076,
+ 0xAE6B3139, 0xEF5A2A20, 0x2C09070B, 0x6D381C12,
+ 0xF33646DF, 0xB2075DC6, 0x715470ED, 0x30656BF4,
+ 0xF7F32ABB, 0xB6C231A2, 0x75911C89, 0x34A00790,
+ 0xFBBC9F17, 0xBA8D840E, 0x79DEA925, 0x38EFB23C,
+ 0xFF79F373, 0xBE48E86A, 0x7D1BC541, 0x3C2ADE58,
+ 0x054F79F0, 0x447E62E9, 0x872D4FC2, 0xC61C54DB,
+ 0x018A1594, 0x40BB0E8D, 0x83E823A6, 0xC2D938BF,
+ 0x0DC5A038, 0x4CF4BB21, 0x8FA7960A, 0xCE968D13,
+ 0x0900CC5C, 0x4831D745, 0x8B62FA6E, 0xCA53E177,
+ 0x545DBBBA, 0x156CA0A3, 0xD63F8D88, 0x970E9691,
+ 0x5098D7DE, 0x11A9CCC7, 0xD2FAE1EC, 0x93CBFAF5,
+ 0x5CD76272, 0x1DE6796B, 0xDEB55440, 0x9F844F59,
+ 0x58120E16, 0x1923150F, 0xDA703824, 0x9B41233D,
+ 0xA76BFD65, 0xE65AE67C, 0x2509CB57, 0x6438D04E,
+ 0xA3AE9101, 0xE29F8A18, 0x21CCA733, 0x60FDBC2A,
+ 0xAFE124AD, 0xEED03FB4, 0x2D83129F, 0x6CB20986,
+ 0xAB2448C9, 0xEA1553D0, 0x29467EFB, 0x687765E2,
+ 0xF6793F2F, 0xB7482436, 0x741B091D, 0x352A1204,
+ 0xF2BC534B, 0xB38D4852, 0x70DE6579, 0x31EF7E60,
+ 0xFEF3E6E7, 0xBFC2FDFE, 0x7C91D0D5, 0x3DA0CBCC,
+ 0xFA368A83, 0xBB07919A, 0x7854BCB1, 0x3965A7A8,
+ 0x4B98833B, 0x0AA99822, 0xC9FAB509, 0x88CBAE10,
+ 0x4F5DEF5F, 0x0E6CF446, 0xCD3FD96D, 0x8C0EC274,
+ 0x43125AF3, 0x022341EA, 0xC1706CC1, 0x804177D8,
+ 0x47D73697, 0x06E62D8E, 0xC5B500A5, 0x84841BBC,
+ 0x1A8A4171, 0x5BBB5A68, 0x98E87743, 0xD9D96C5A,
+ 0x1E4F2D15, 0x5F7E360C, 0x9C2D1B27, 0xDD1C003E,
+ 0x120098B9, 0x533183A0, 0x9062AE8B, 0xD153B592,
+ 0x16C5F4DD, 0x57F4EFC4, 0x94A7C2EF, 0xD596D9F6,
+ 0xE9BC07AE, 0xA88D1CB7, 0x6BDE319C, 0x2AEF2A85,
+ 0xED796BCA, 0xAC4870D3, 0x6F1B5DF8, 0x2E2A46E1,
+ 0xE136DE66, 0xA007C57F, 0x6354E854, 0x2265F34D,
+ 0xE5F3B202, 0xA4C2A91B, 0x67918430, 0x26A09F29,
+ 0xB8AEC5E4, 0xF99FDEFD, 0x3ACCF3D6, 0x7BFDE8CF,
+ 0xBC6BA980, 0xFD5AB299, 0x3E099FB2, 0x7F3884AB,
+ 0xB0241C2C, 0xF1150735, 0x32462A1E, 0x73773107,
+ 0xB4E17048, 0xF5D06B51, 0x3683467A, 0x77B25D63,
+ 0x4ED7FACB, 0x0FE6E1D2, 0xCCB5CCF9, 0x8D84D7E0,
+ 0x4A1296AF, 0x0B238DB6, 0xC870A09D, 0x8941BB84,
+ 0x465D2303, 0x076C381A, 0xC43F1531, 0x850E0E28,
+ 0x42984F67, 0x03A9547E, 0xC0FA7955, 0x81CB624C,
+ 0x1FC53881, 0x5EF42398, 0x9DA70EB3, 0xDC9615AA,
+ 0x1B0054E5, 0x5A314FFC, 0x996262D7, 0xD85379CE,
+ 0x174FE149, 0x567EFA50, 0x952DD77B, 0xD41CCC62,
+ 0x138A8D2D, 0x52BB9634, 0x91E8BB1F, 0xD0D9A006,
+ 0xECF37E5E, 0xADC26547, 0x6E91486C, 0x2FA05375,
+ 0xE836123A, 0xA9070923, 0x6A542408, 0x2B653F11,
+ 0xE479A796, 0xA548BC8F, 0x661B91A4, 0x272A8ABD,
+ 0xE0BCCBF2, 0xA18DD0EB, 0x62DEFDC0, 0x23EFE6D9,
+ 0xBDE1BC14, 0xFCD0A70D, 0x3F838A26, 0x7EB2913F,
+ 0xB924D070, 0xF815CB69, 0x3B46E642, 0x7A77FD5B,
+ 0xB56B65DC, 0xF45A7EC5, 0x370953EE, 0x763848F7,
+ 0xB1AE09B8, 0xF09F12A1, 0x33CC3F8A, 0x72FD2493
+ }, {
+ 0x00000000, 0x376AC201, 0x6ED48403, 0x59BE4602,
+ 0xDCA80907, 0xEBC2CB06, 0xB27C8D04, 0x85164F05,
+ 0xB851130E, 0x8F3BD10F, 0xD685970D, 0xE1EF550C,
+ 0x64F91A09, 0x5393D808, 0x0A2D9E0A, 0x3D475C0B,
+ 0x70A3261C, 0x47C9E41D, 0x1E77A21F, 0x291D601E,
+ 0xAC0B2F1B, 0x9B61ED1A, 0xC2DFAB18, 0xF5B56919,
+ 0xC8F23512, 0xFF98F713, 0xA626B111, 0x914C7310,
+ 0x145A3C15, 0x2330FE14, 0x7A8EB816, 0x4DE47A17,
+ 0xE0464D38, 0xD72C8F39, 0x8E92C93B, 0xB9F80B3A,
+ 0x3CEE443F, 0x0B84863E, 0x523AC03C, 0x6550023D,
+ 0x58175E36, 0x6F7D9C37, 0x36C3DA35, 0x01A91834,
+ 0x84BF5731, 0xB3D59530, 0xEA6BD332, 0xDD011133,
+ 0x90E56B24, 0xA78FA925, 0xFE31EF27, 0xC95B2D26,
+ 0x4C4D6223, 0x7B27A022, 0x2299E620, 0x15F32421,
+ 0x28B4782A, 0x1FDEBA2B, 0x4660FC29, 0x710A3E28,
+ 0xF41C712D, 0xC376B32C, 0x9AC8F52E, 0xADA2372F,
+ 0xC08D9A70, 0xF7E75871, 0xAE591E73, 0x9933DC72,
+ 0x1C259377, 0x2B4F5176, 0x72F11774, 0x459BD575,
+ 0x78DC897E, 0x4FB64B7F, 0x16080D7D, 0x2162CF7C,
+ 0xA4748079, 0x931E4278, 0xCAA0047A, 0xFDCAC67B,
+ 0xB02EBC6C, 0x87447E6D, 0xDEFA386F, 0xE990FA6E,
+ 0x6C86B56B, 0x5BEC776A, 0x02523168, 0x3538F369,
+ 0x087FAF62, 0x3F156D63, 0x66AB2B61, 0x51C1E960,
+ 0xD4D7A665, 0xE3BD6464, 0xBA032266, 0x8D69E067,
+ 0x20CBD748, 0x17A11549, 0x4E1F534B, 0x7975914A,
+ 0xFC63DE4F, 0xCB091C4E, 0x92B75A4C, 0xA5DD984D,
+ 0x989AC446, 0xAFF00647, 0xF64E4045, 0xC1248244,
+ 0x4432CD41, 0x73580F40, 0x2AE64942, 0x1D8C8B43,
+ 0x5068F154, 0x67023355, 0x3EBC7557, 0x09D6B756,
+ 0x8CC0F853, 0xBBAA3A52, 0xE2147C50, 0xD57EBE51,
+ 0xE839E25A, 0xDF53205B, 0x86ED6659, 0xB187A458,
+ 0x3491EB5D, 0x03FB295C, 0x5A456F5E, 0x6D2FAD5F,
+ 0x801B35E1, 0xB771F7E0, 0xEECFB1E2, 0xD9A573E3,
+ 0x5CB33CE6, 0x6BD9FEE7, 0x3267B8E5, 0x050D7AE4,
+ 0x384A26EF, 0x0F20E4EE, 0x569EA2EC, 0x61F460ED,
+ 0xE4E22FE8, 0xD388EDE9, 0x8A36ABEB, 0xBD5C69EA,
+ 0xF0B813FD, 0xC7D2D1FC, 0x9E6C97FE, 0xA90655FF,
+ 0x2C101AFA, 0x1B7AD8FB, 0x42C49EF9, 0x75AE5CF8,
+ 0x48E900F3, 0x7F83C2F2, 0x263D84F0, 0x115746F1,
+ 0x944109F4, 0xA32BCBF5, 0xFA958DF7, 0xCDFF4FF6,
+ 0x605D78D9, 0x5737BAD8, 0x0E89FCDA, 0x39E33EDB,
+ 0xBCF571DE, 0x8B9FB3DF, 0xD221F5DD, 0xE54B37DC,
+ 0xD80C6BD7, 0xEF66A9D6, 0xB6D8EFD4, 0x81B22DD5,
+ 0x04A462D0, 0x33CEA0D1, 0x6A70E6D3, 0x5D1A24D2,
+ 0x10FE5EC5, 0x27949CC4, 0x7E2ADAC6, 0x494018C7,
+ 0xCC5657C2, 0xFB3C95C3, 0xA282D3C1, 0x95E811C0,
+ 0xA8AF4DCB, 0x9FC58FCA, 0xC67BC9C8, 0xF1110BC9,
+ 0x740744CC, 0x436D86CD, 0x1AD3C0CF, 0x2DB902CE,
+ 0x4096AF91, 0x77FC6D90, 0x2E422B92, 0x1928E993,
+ 0x9C3EA696, 0xAB546497, 0xF2EA2295, 0xC580E094,
+ 0xF8C7BC9F, 0xCFAD7E9E, 0x9613389C, 0xA179FA9D,
+ 0x246FB598, 0x13057799, 0x4ABB319B, 0x7DD1F39A,
+ 0x3035898D, 0x075F4B8C, 0x5EE10D8E, 0x698BCF8F,
+ 0xEC9D808A, 0xDBF7428B, 0x82490489, 0xB523C688,
+ 0x88649A83, 0xBF0E5882, 0xE6B01E80, 0xD1DADC81,
+ 0x54CC9384, 0x63A65185, 0x3A181787, 0x0D72D586,
+ 0xA0D0E2A9, 0x97BA20A8, 0xCE0466AA, 0xF96EA4AB,
+ 0x7C78EBAE, 0x4B1229AF, 0x12AC6FAD, 0x25C6ADAC,
+ 0x1881F1A7, 0x2FEB33A6, 0x765575A4, 0x413FB7A5,
+ 0xC429F8A0, 0xF3433AA1, 0xAAFD7CA3, 0x9D97BEA2,
+ 0xD073C4B5, 0xE71906B4, 0xBEA740B6, 0x89CD82B7,
+ 0x0CDBCDB2, 0x3BB10FB3, 0x620F49B1, 0x55658BB0,
+ 0x6822D7BB, 0x5F4815BA, 0x06F653B8, 0x319C91B9,
+ 0xB48ADEBC, 0x83E01CBD, 0xDA5E5ABF, 0xED3498BE
+ }, {
+ 0x00000000, 0x6567BCB8, 0x8BC809AA, 0xEEAFB512,
+ 0x5797628F, 0x32F0DE37, 0xDC5F6B25, 0xB938D79D,
+ 0xEF28B4C5, 0x8A4F087D, 0x64E0BD6F, 0x018701D7,
+ 0xB8BFD64A, 0xDDD86AF2, 0x3377DFE0, 0x56106358,
+ 0x9F571950, 0xFA30A5E8, 0x149F10FA, 0x71F8AC42,
+ 0xC8C07BDF, 0xADA7C767, 0x43087275, 0x266FCECD,
+ 0x707FAD95, 0x1518112D, 0xFBB7A43F, 0x9ED01887,
+ 0x27E8CF1A, 0x428F73A2, 0xAC20C6B0, 0xC9477A08,
+ 0x3EAF32A0, 0x5BC88E18, 0xB5673B0A, 0xD00087B2,
+ 0x6938502F, 0x0C5FEC97, 0xE2F05985, 0x8797E53D,
+ 0xD1878665, 0xB4E03ADD, 0x5A4F8FCF, 0x3F283377,
+ 0x8610E4EA, 0xE3775852, 0x0DD8ED40, 0x68BF51F8,
+ 0xA1F82BF0, 0xC49F9748, 0x2A30225A, 0x4F579EE2,
+ 0xF66F497F, 0x9308F5C7, 0x7DA740D5, 0x18C0FC6D,
+ 0x4ED09F35, 0x2BB7238D, 0xC518969F, 0xA07F2A27,
+ 0x1947FDBA, 0x7C204102, 0x928FF410, 0xF7E848A8,
+ 0x3D58149B, 0x583FA823, 0xB6901D31, 0xD3F7A189,
+ 0x6ACF7614, 0x0FA8CAAC, 0xE1077FBE, 0x8460C306,
+ 0xD270A05E, 0xB7171CE6, 0x59B8A9F4, 0x3CDF154C,
+ 0x85E7C2D1, 0xE0807E69, 0x0E2FCB7B, 0x6B4877C3,
+ 0xA20F0DCB, 0xC768B173, 0x29C70461, 0x4CA0B8D9,
+ 0xF5986F44, 0x90FFD3FC, 0x7E5066EE, 0x1B37DA56,
+ 0x4D27B90E, 0x284005B6, 0xC6EFB0A4, 0xA3880C1C,
+ 0x1AB0DB81, 0x7FD76739, 0x9178D22B, 0xF41F6E93,
+ 0x03F7263B, 0x66909A83, 0x883F2F91, 0xED589329,
+ 0x546044B4, 0x3107F80C, 0xDFA84D1E, 0xBACFF1A6,
+ 0xECDF92FE, 0x89B82E46, 0x67179B54, 0x027027EC,
+ 0xBB48F071, 0xDE2F4CC9, 0x3080F9DB, 0x55E74563,
+ 0x9CA03F6B, 0xF9C783D3, 0x176836C1, 0x720F8A79,
+ 0xCB375DE4, 0xAE50E15C, 0x40FF544E, 0x2598E8F6,
+ 0x73888BAE, 0x16EF3716, 0xF8408204, 0x9D273EBC,
+ 0x241FE921, 0x41785599, 0xAFD7E08B, 0xCAB05C33,
+ 0x3BB659ED, 0x5ED1E555, 0xB07E5047, 0xD519ECFF,
+ 0x6C213B62, 0x094687DA, 0xE7E932C8, 0x828E8E70,
+ 0xD49EED28, 0xB1F95190, 0x5F56E482, 0x3A31583A,
+ 0x83098FA7, 0xE66E331F, 0x08C1860D, 0x6DA63AB5,
+ 0xA4E140BD, 0xC186FC05, 0x2F294917, 0x4A4EF5AF,
+ 0xF3762232, 0x96119E8A, 0x78BE2B98, 0x1DD99720,
+ 0x4BC9F478, 0x2EAE48C0, 0xC001FDD2, 0xA566416A,
+ 0x1C5E96F7, 0x79392A4F, 0x97969F5D, 0xF2F123E5,
+ 0x05196B4D, 0x607ED7F5, 0x8ED162E7, 0xEBB6DE5F,
+ 0x528E09C2, 0x37E9B57A, 0xD9460068, 0xBC21BCD0,
+ 0xEA31DF88, 0x8F566330, 0x61F9D622, 0x049E6A9A,
+ 0xBDA6BD07, 0xD8C101BF, 0x366EB4AD, 0x53090815,
+ 0x9A4E721D, 0xFF29CEA5, 0x11867BB7, 0x74E1C70F,
+ 0xCDD91092, 0xA8BEAC2A, 0x46111938, 0x2376A580,
+ 0x7566C6D8, 0x10017A60, 0xFEAECF72, 0x9BC973CA,
+ 0x22F1A457, 0x479618EF, 0xA939ADFD, 0xCC5E1145,
+ 0x06EE4D76, 0x6389F1CE, 0x8D2644DC, 0xE841F864,
+ 0x51792FF9, 0x341E9341, 0xDAB12653, 0xBFD69AEB,
+ 0xE9C6F9B3, 0x8CA1450B, 0x620EF019, 0x07694CA1,
+ 0xBE519B3C, 0xDB362784, 0x35999296, 0x50FE2E2E,
+ 0x99B95426, 0xFCDEE89E, 0x12715D8C, 0x7716E134,
+ 0xCE2E36A9, 0xAB498A11, 0x45E63F03, 0x208183BB,
+ 0x7691E0E3, 0x13F65C5B, 0xFD59E949, 0x983E55F1,
+ 0x2106826C, 0x44613ED4, 0xAACE8BC6, 0xCFA9377E,
+ 0x38417FD6, 0x5D26C36E, 0xB389767C, 0xD6EECAC4,
+ 0x6FD61D59, 0x0AB1A1E1, 0xE41E14F3, 0x8179A84B,
+ 0xD769CB13, 0xB20E77AB, 0x5CA1C2B9, 0x39C67E01,
+ 0x80FEA99C, 0xE5991524, 0x0B36A036, 0x6E511C8E,
+ 0xA7166686, 0xC271DA3E, 0x2CDE6F2C, 0x49B9D394,
+ 0xF0810409, 0x95E6B8B1, 0x7B490DA3, 0x1E2EB11B,
+ 0x483ED243, 0x2D596EFB, 0xC3F6DBE9, 0xA6916751,
+ 0x1FA9B0CC, 0x7ACE0C74, 0x9461B966, 0xF10605DE
+ }, {
+ 0x00000000, 0xB029603D, 0x6053C07A, 0xD07AA047,
+ 0xC0A680F5, 0x708FE0C8, 0xA0F5408F, 0x10DC20B2,
+ 0xC14B7030, 0x7162100D, 0xA118B04A, 0x1131D077,
+ 0x01EDF0C5, 0xB1C490F8, 0x61BE30BF, 0xD1975082,
+ 0x8297E060, 0x32BE805D, 0xE2C4201A, 0x52ED4027,
+ 0x42316095, 0xF21800A8, 0x2262A0EF, 0x924BC0D2,
+ 0x43DC9050, 0xF3F5F06D, 0x238F502A, 0x93A63017,
+ 0x837A10A5, 0x33537098, 0xE329D0DF, 0x5300B0E2,
+ 0x042FC1C1, 0xB406A1FC, 0x647C01BB, 0xD4556186,
+ 0xC4894134, 0x74A02109, 0xA4DA814E, 0x14F3E173,
+ 0xC564B1F1, 0x754DD1CC, 0xA537718B, 0x151E11B6,
+ 0x05C23104, 0xB5EB5139, 0x6591F17E, 0xD5B89143,
+ 0x86B821A1, 0x3691419C, 0xE6EBE1DB, 0x56C281E6,
+ 0x461EA154, 0xF637C169, 0x264D612E, 0x96640113,
+ 0x47F35191, 0xF7DA31AC, 0x27A091EB, 0x9789F1D6,
+ 0x8755D164, 0x377CB159, 0xE706111E, 0x572F7123,
+ 0x4958F358, 0xF9719365, 0x290B3322, 0x9922531F,
+ 0x89FE73AD, 0x39D71390, 0xE9ADB3D7, 0x5984D3EA,
+ 0x88138368, 0x383AE355, 0xE8404312, 0x5869232F,
+ 0x48B5039D, 0xF89C63A0, 0x28E6C3E7, 0x98CFA3DA,
+ 0xCBCF1338, 0x7BE67305, 0xAB9CD342, 0x1BB5B37F,
+ 0x0B6993CD, 0xBB40F3F0, 0x6B3A53B7, 0xDB13338A,
+ 0x0A846308, 0xBAAD0335, 0x6AD7A372, 0xDAFEC34F,
+ 0xCA22E3FD, 0x7A0B83C0, 0xAA712387, 0x1A5843BA,
+ 0x4D773299, 0xFD5E52A4, 0x2D24F2E3, 0x9D0D92DE,
+ 0x8DD1B26C, 0x3DF8D251, 0xED827216, 0x5DAB122B,
+ 0x8C3C42A9, 0x3C152294, 0xEC6F82D3, 0x5C46E2EE,
+ 0x4C9AC25C, 0xFCB3A261, 0x2CC90226, 0x9CE0621B,
+ 0xCFE0D2F9, 0x7FC9B2C4, 0xAFB31283, 0x1F9A72BE,
+ 0x0F46520C, 0xBF6F3231, 0x6F159276, 0xDF3CF24B,
+ 0x0EABA2C9, 0xBE82C2F4, 0x6EF862B3, 0xDED1028E,
+ 0xCE0D223C, 0x7E244201, 0xAE5EE246, 0x1E77827B,
+ 0x92B0E6B1, 0x2299868C, 0xF2E326CB, 0x42CA46F6,
+ 0x52166644, 0xE23F0679, 0x3245A63E, 0x826CC603,
+ 0x53FB9681, 0xE3D2F6BC, 0x33A856FB, 0x838136C6,
+ 0x935D1674, 0x23747649, 0xF30ED60E, 0x4327B633,
+ 0x102706D1, 0xA00E66EC, 0x7074C6AB, 0xC05DA696,
+ 0xD0818624, 0x60A8E619, 0xB0D2465E, 0x00FB2663,
+ 0xD16C76E1, 0x614516DC, 0xB13FB69B, 0x0116D6A6,
+ 0x11CAF614, 0xA1E39629, 0x7199366E, 0xC1B05653,
+ 0x969F2770, 0x26B6474D, 0xF6CCE70A, 0x46E58737,
+ 0x5639A785, 0xE610C7B8, 0x366A67FF, 0x864307C2,
+ 0x57D45740, 0xE7FD377D, 0x3787973A, 0x87AEF707,
+ 0x9772D7B5, 0x275BB788, 0xF72117CF, 0x470877F2,
+ 0x1408C710, 0xA421A72D, 0x745B076A, 0xC4726757,
+ 0xD4AE47E5, 0x648727D8, 0xB4FD879F, 0x04D4E7A2,
+ 0xD543B720, 0x656AD71D, 0xB510775A, 0x05391767,
+ 0x15E537D5, 0xA5CC57E8, 0x75B6F7AF, 0xC59F9792,
+ 0xDBE815E9, 0x6BC175D4, 0xBBBBD593, 0x0B92B5AE,
+ 0x1B4E951C, 0xAB67F521, 0x7B1D5566, 0xCB34355B,
+ 0x1AA365D9, 0xAA8A05E4, 0x7AF0A5A3, 0xCAD9C59E,
+ 0xDA05E52C, 0x6A2C8511, 0xBA562556, 0x0A7F456B,
+ 0x597FF589, 0xE95695B4, 0x392C35F3, 0x890555CE,
+ 0x99D9757C, 0x29F01541, 0xF98AB506, 0x49A3D53B,
+ 0x983485B9, 0x281DE584, 0xF86745C3, 0x484E25FE,
+ 0x5892054C, 0xE8BB6571, 0x38C1C536, 0x88E8A50B,
+ 0xDFC7D428, 0x6FEEB415, 0xBF941452, 0x0FBD746F,
+ 0x1F6154DD, 0xAF4834E0, 0x7F3294A7, 0xCF1BF49A,
+ 0x1E8CA418, 0xAEA5C425, 0x7EDF6462, 0xCEF6045F,
+ 0xDE2A24ED, 0x6E0344D0, 0xBE79E497, 0x0E5084AA,
+ 0x5D503448, 0xED795475, 0x3D03F432, 0x8D2A940F,
+ 0x9DF6B4BD, 0x2DDFD480, 0xFDA574C7, 0x4D8C14FA,
+ 0x9C1B4478, 0x2C322445, 0xFC488402, 0x4C61E43F,
+ 0x5CBDC48D, 0xEC94A4B0, 0x3CEE04F7, 0x8CC764CA
+ }, {
+ 0x00000000, 0xA5D35CCB, 0x0BA1C84D, 0xAE729486,
+ 0x1642919B, 0xB391CD50, 0x1DE359D6, 0xB830051D,
+ 0x6D8253EC, 0xC8510F27, 0x66239BA1, 0xC3F0C76A,
+ 0x7BC0C277, 0xDE139EBC, 0x70610A3A, 0xD5B256F1,
+ 0x9B02D603, 0x3ED18AC8, 0x90A31E4E, 0x35704285,
+ 0x8D404798, 0x28931B53, 0x86E18FD5, 0x2332D31E,
+ 0xF68085EF, 0x5353D924, 0xFD214DA2, 0x58F21169,
+ 0xE0C21474, 0x451148BF, 0xEB63DC39, 0x4EB080F2,
+ 0x3605AC07, 0x93D6F0CC, 0x3DA4644A, 0x98773881,
+ 0x20473D9C, 0x85946157, 0x2BE6F5D1, 0x8E35A91A,
+ 0x5B87FFEB, 0xFE54A320, 0x502637A6, 0xF5F56B6D,
+ 0x4DC56E70, 0xE81632BB, 0x4664A63D, 0xE3B7FAF6,
+ 0xAD077A04, 0x08D426CF, 0xA6A6B249, 0x0375EE82,
+ 0xBB45EB9F, 0x1E96B754, 0xB0E423D2, 0x15377F19,
+ 0xC08529E8, 0x65567523, 0xCB24E1A5, 0x6EF7BD6E,
+ 0xD6C7B873, 0x7314E4B8, 0xDD66703E, 0x78B52CF5,
+ 0x6C0A580F, 0xC9D904C4, 0x67AB9042, 0xC278CC89,
+ 0x7A48C994, 0xDF9B955F, 0x71E901D9, 0xD43A5D12,
+ 0x01880BE3, 0xA45B5728, 0x0A29C3AE, 0xAFFA9F65,
+ 0x17CA9A78, 0xB219C6B3, 0x1C6B5235, 0xB9B80EFE,
+ 0xF7088E0C, 0x52DBD2C7, 0xFCA94641, 0x597A1A8A,
+ 0xE14A1F97, 0x4499435C, 0xEAEBD7DA, 0x4F388B11,
+ 0x9A8ADDE0, 0x3F59812B, 0x912B15AD, 0x34F84966,
+ 0x8CC84C7B, 0x291B10B0, 0x87698436, 0x22BAD8FD,
+ 0x5A0FF408, 0xFFDCA8C3, 0x51AE3C45, 0xF47D608E,
+ 0x4C4D6593, 0xE99E3958, 0x47ECADDE, 0xE23FF115,
+ 0x378DA7E4, 0x925EFB2F, 0x3C2C6FA9, 0x99FF3362,
+ 0x21CF367F, 0x841C6AB4, 0x2A6EFE32, 0x8FBDA2F9,
+ 0xC10D220B, 0x64DE7EC0, 0xCAACEA46, 0x6F7FB68D,
+ 0xD74FB390, 0x729CEF5B, 0xDCEE7BDD, 0x793D2716,
+ 0xAC8F71E7, 0x095C2D2C, 0xA72EB9AA, 0x02FDE561,
+ 0xBACDE07C, 0x1F1EBCB7, 0xB16C2831, 0x14BF74FA,
+ 0xD814B01E, 0x7DC7ECD5, 0xD3B57853, 0x76662498,
+ 0xCE562185, 0x6B857D4E, 0xC5F7E9C8, 0x6024B503,
+ 0xB596E3F2, 0x1045BF39, 0xBE372BBF, 0x1BE47774,
+ 0xA3D47269, 0x06072EA2, 0xA875BA24, 0x0DA6E6EF,
+ 0x4316661D, 0xE6C53AD6, 0x48B7AE50, 0xED64F29B,
+ 0x5554F786, 0xF087AB4D, 0x5EF53FCB, 0xFB266300,
+ 0x2E9435F1, 0x8B47693A, 0x2535FDBC, 0x80E6A177,
+ 0x38D6A46A, 0x9D05F8A1, 0x33776C27, 0x96A430EC,
+ 0xEE111C19, 0x4BC240D2, 0xE5B0D454, 0x4063889F,
+ 0xF8538D82, 0x5D80D149, 0xF3F245CF, 0x56211904,
+ 0x83934FF5, 0x2640133E, 0x883287B8, 0x2DE1DB73,
+ 0x95D1DE6E, 0x300282A5, 0x9E701623, 0x3BA34AE8,
+ 0x7513CA1A, 0xD0C096D1, 0x7EB20257, 0xDB615E9C,
+ 0x63515B81, 0xC682074A, 0x68F093CC, 0xCD23CF07,
+ 0x189199F6, 0xBD42C53D, 0x133051BB, 0xB6E30D70,
+ 0x0ED3086D, 0xAB0054A6, 0x0572C020, 0xA0A19CEB,
+ 0xB41EE811, 0x11CDB4DA, 0xBFBF205C, 0x1A6C7C97,
+ 0xA25C798A, 0x078F2541, 0xA9FDB1C7, 0x0C2EED0C,
+ 0xD99CBBFD, 0x7C4FE736, 0xD23D73B0, 0x77EE2F7B,
+ 0xCFDE2A66, 0x6A0D76AD, 0xC47FE22B, 0x61ACBEE0,
+ 0x2F1C3E12, 0x8ACF62D9, 0x24BDF65F, 0x816EAA94,
+ 0x395EAF89, 0x9C8DF342, 0x32FF67C4, 0x972C3B0F,
+ 0x429E6DFE, 0xE74D3135, 0x493FA5B3, 0xECECF978,
+ 0x54DCFC65, 0xF10FA0AE, 0x5F7D3428, 0xFAAE68E3,
+ 0x821B4416, 0x27C818DD, 0x89BA8C5B, 0x2C69D090,
+ 0x9459D58D, 0x318A8946, 0x9FF81DC0, 0x3A2B410B,
+ 0xEF9917FA, 0x4A4A4B31, 0xE438DFB7, 0x41EB837C,
+ 0xF9DB8661, 0x5C08DAAA, 0xF27A4E2C, 0x57A912E7,
+ 0x19199215, 0xBCCACEDE, 0x12B85A58, 0xB76B0693,
+ 0x0F5B038E, 0xAA885F45, 0x04FACBC3, 0xA1299708,
+ 0x749BC1F9, 0xD1489D32, 0x7F3A09B4, 0xDAE9557F,
+ 0x62D95062, 0xC70A0CA9, 0x6978982F, 0xCCABC4E4
+ }, {
+ 0x00000000, 0xB40B77A6, 0x29119F97, 0x9D1AE831,
+ 0x13244FF4, 0xA72F3852, 0x3A35D063, 0x8E3EA7C5,
+ 0x674EEF33, 0xD3459895, 0x4E5F70A4, 0xFA540702,
+ 0x746AA0C7, 0xC061D761, 0x5D7B3F50, 0xE97048F6,
+ 0xCE9CDE67, 0x7A97A9C1, 0xE78D41F0, 0x53863656,
+ 0xDDB89193, 0x69B3E635, 0xF4A90E04, 0x40A279A2,
+ 0xA9D23154, 0x1DD946F2, 0x80C3AEC3, 0x34C8D965,
+ 0xBAF67EA0, 0x0EFD0906, 0x93E7E137, 0x27EC9691,
+ 0x9C39BDCF, 0x2832CA69, 0xB5282258, 0x012355FE,
+ 0x8F1DF23B, 0x3B16859D, 0xA60C6DAC, 0x12071A0A,
+ 0xFB7752FC, 0x4F7C255A, 0xD266CD6B, 0x666DBACD,
+ 0xE8531D08, 0x5C586AAE, 0xC142829F, 0x7549F539,
+ 0x52A563A8, 0xE6AE140E, 0x7BB4FC3F, 0xCFBF8B99,
+ 0x41812C5C, 0xF58A5BFA, 0x6890B3CB, 0xDC9BC46D,
+ 0x35EB8C9B, 0x81E0FB3D, 0x1CFA130C, 0xA8F164AA,
+ 0x26CFC36F, 0x92C4B4C9, 0x0FDE5CF8, 0xBBD52B5E,
+ 0x79750B44, 0xCD7E7CE2, 0x506494D3, 0xE46FE375,
+ 0x6A5144B0, 0xDE5A3316, 0x4340DB27, 0xF74BAC81,
+ 0x1E3BE477, 0xAA3093D1, 0x372A7BE0, 0x83210C46,
+ 0x0D1FAB83, 0xB914DC25, 0x240E3414, 0x900543B2,
+ 0xB7E9D523, 0x03E2A285, 0x9EF84AB4, 0x2AF33D12,
+ 0xA4CD9AD7, 0x10C6ED71, 0x8DDC0540, 0x39D772E6,
+ 0xD0A73A10, 0x64AC4DB6, 0xF9B6A587, 0x4DBDD221,
+ 0xC38375E4, 0x77880242, 0xEA92EA73, 0x5E999DD5,
+ 0xE54CB68B, 0x5147C12D, 0xCC5D291C, 0x78565EBA,
+ 0xF668F97F, 0x42638ED9, 0xDF7966E8, 0x6B72114E,
+ 0x820259B8, 0x36092E1E, 0xAB13C62F, 0x1F18B189,
+ 0x9126164C, 0x252D61EA, 0xB83789DB, 0x0C3CFE7D,
+ 0x2BD068EC, 0x9FDB1F4A, 0x02C1F77B, 0xB6CA80DD,
+ 0x38F42718, 0x8CFF50BE, 0x11E5B88F, 0xA5EECF29,
+ 0x4C9E87DF, 0xF895F079, 0x658F1848, 0xD1846FEE,
+ 0x5FBAC82B, 0xEBB1BF8D, 0x76AB57BC, 0xC2A0201A,
+ 0xF2EA1688, 0x46E1612E, 0xDBFB891F, 0x6FF0FEB9,
+ 0xE1CE597C, 0x55C52EDA, 0xC8DFC6EB, 0x7CD4B14D,
+ 0x95A4F9BB, 0x21AF8E1D, 0xBCB5662C, 0x08BE118A,
+ 0x8680B64F, 0x328BC1E9, 0xAF9129D8, 0x1B9A5E7E,
+ 0x3C76C8EF, 0x887DBF49, 0x15675778, 0xA16C20DE,
+ 0x2F52871B, 0x9B59F0BD, 0x0643188C, 0xB2486F2A,
+ 0x5B3827DC, 0xEF33507A, 0x7229B84B, 0xC622CFED,
+ 0x481C6828, 0xFC171F8E, 0x610DF7BF, 0xD5068019,
+ 0x6ED3AB47, 0xDAD8DCE1, 0x47C234D0, 0xF3C94376,
+ 0x7DF7E4B3, 0xC9FC9315, 0x54E67B24, 0xE0ED0C82,
+ 0x099D4474, 0xBD9633D2, 0x208CDBE3, 0x9487AC45,
+ 0x1AB90B80, 0xAEB27C26, 0x33A89417, 0x87A3E3B1,
+ 0xA04F7520, 0x14440286, 0x895EEAB7, 0x3D559D11,
+ 0xB36B3AD4, 0x07604D72, 0x9A7AA543, 0x2E71D2E5,
+ 0xC7019A13, 0x730AEDB5, 0xEE100584, 0x5A1B7222,
+ 0xD425D5E7, 0x602EA241, 0xFD344A70, 0x493F3DD6,
+ 0x8B9F1DCC, 0x3F946A6A, 0xA28E825B, 0x1685F5FD,
+ 0x98BB5238, 0x2CB0259E, 0xB1AACDAF, 0x05A1BA09,
+ 0xECD1F2FF, 0x58DA8559, 0xC5C06D68, 0x71CB1ACE,
+ 0xFFF5BD0B, 0x4BFECAAD, 0xD6E4229C, 0x62EF553A,
+ 0x4503C3AB, 0xF108B40D, 0x6C125C3C, 0xD8192B9A,
+ 0x56278C5F, 0xE22CFBF9, 0x7F3613C8, 0xCB3D646E,
+ 0x224D2C98, 0x96465B3E, 0x0B5CB30F, 0xBF57C4A9,
+ 0x3169636C, 0x856214CA, 0x1878FCFB, 0xAC738B5D,
+ 0x17A6A003, 0xA3ADD7A5, 0x3EB73F94, 0x8ABC4832,
+ 0x0482EFF7, 0xB0899851, 0x2D937060, 0x999807C6,
+ 0x70E84F30, 0xC4E33896, 0x59F9D0A7, 0xEDF2A701,
+ 0x63CC00C4, 0xD7C77762, 0x4ADD9F53, 0xFED6E8F5,
+ 0xD93A7E64, 0x6D3109C2, 0xF02BE1F3, 0x44209655,
+ 0xCA1E3190, 0x7E154636, 0xE30FAE07, 0x5704D9A1,
+ 0xBE749157, 0x0A7FE6F1, 0x97650EC0, 0x236E7966,
+ 0xAD50DEA3, 0x195BA905, 0x84414134, 0x304A3692
+ }, {
+ 0x00000000, 0x9E00AACC, 0x7D072542, 0xE3078F8E,
+ 0xFA0E4A84, 0x640EE048, 0x87096FC6, 0x1909C50A,
+ 0xB51BE5D3, 0x2B1B4F1F, 0xC81CC091, 0x561C6A5D,
+ 0x4F15AF57, 0xD115059B, 0x32128A15, 0xAC1220D9,
+ 0x2B31BB7C, 0xB53111B0, 0x56369E3E, 0xC83634F2,
+ 0xD13FF1F8, 0x4F3F5B34, 0xAC38D4BA, 0x32387E76,
+ 0x9E2A5EAF, 0x002AF463, 0xE32D7BED, 0x7D2DD121,
+ 0x6424142B, 0xFA24BEE7, 0x19233169, 0x87239BA5,
+ 0x566276F9, 0xC862DC35, 0x2B6553BB, 0xB565F977,
+ 0xAC6C3C7D, 0x326C96B1, 0xD16B193F, 0x4F6BB3F3,
+ 0xE379932A, 0x7D7939E6, 0x9E7EB668, 0x007E1CA4,
+ 0x1977D9AE, 0x87777362, 0x6470FCEC, 0xFA705620,
+ 0x7D53CD85, 0xE3536749, 0x0054E8C7, 0x9E54420B,
+ 0x875D8701, 0x195D2DCD, 0xFA5AA243, 0x645A088F,
+ 0xC8482856, 0x5648829A, 0xB54F0D14, 0x2B4FA7D8,
+ 0x324662D2, 0xAC46C81E, 0x4F414790, 0xD141ED5C,
+ 0xEDC29D29, 0x73C237E5, 0x90C5B86B, 0x0EC512A7,
+ 0x17CCD7AD, 0x89CC7D61, 0x6ACBF2EF, 0xF4CB5823,
+ 0x58D978FA, 0xC6D9D236, 0x25DE5DB8, 0xBBDEF774,
+ 0xA2D7327E, 0x3CD798B2, 0xDFD0173C, 0x41D0BDF0,
+ 0xC6F32655, 0x58F38C99, 0xBBF40317, 0x25F4A9DB,
+ 0x3CFD6CD1, 0xA2FDC61D, 0x41FA4993, 0xDFFAE35F,
+ 0x73E8C386, 0xEDE8694A, 0x0EEFE6C4, 0x90EF4C08,
+ 0x89E68902, 0x17E623CE, 0xF4E1AC40, 0x6AE1068C,
+ 0xBBA0EBD0, 0x25A0411C, 0xC6A7CE92, 0x58A7645E,
+ 0x41AEA154, 0xDFAE0B98, 0x3CA98416, 0xA2A92EDA,
+ 0x0EBB0E03, 0x90BBA4CF, 0x73BC2B41, 0xEDBC818D,
+ 0xF4B54487, 0x6AB5EE4B, 0x89B261C5, 0x17B2CB09,
+ 0x909150AC, 0x0E91FA60, 0xED9675EE, 0x7396DF22,
+ 0x6A9F1A28, 0xF49FB0E4, 0x17983F6A, 0x899895A6,
+ 0x258AB57F, 0xBB8A1FB3, 0x588D903D, 0xC68D3AF1,
+ 0xDF84FFFB, 0x41845537, 0xA283DAB9, 0x3C837075,
+ 0xDA853B53, 0x4485919F, 0xA7821E11, 0x3982B4DD,
+ 0x208B71D7, 0xBE8BDB1B, 0x5D8C5495, 0xC38CFE59,
+ 0x6F9EDE80, 0xF19E744C, 0x1299FBC2, 0x8C99510E,
+ 0x95909404, 0x0B903EC8, 0xE897B146, 0x76971B8A,
+ 0xF1B4802F, 0x6FB42AE3, 0x8CB3A56D, 0x12B30FA1,
+ 0x0BBACAAB, 0x95BA6067, 0x76BDEFE9, 0xE8BD4525,
+ 0x44AF65FC, 0xDAAFCF30, 0x39A840BE, 0xA7A8EA72,
+ 0xBEA12F78, 0x20A185B4, 0xC3A60A3A, 0x5DA6A0F6,
+ 0x8CE74DAA, 0x12E7E766, 0xF1E068E8, 0x6FE0C224,
+ 0x76E9072E, 0xE8E9ADE2, 0x0BEE226C, 0x95EE88A0,
+ 0x39FCA879, 0xA7FC02B5, 0x44FB8D3B, 0xDAFB27F7,
+ 0xC3F2E2FD, 0x5DF24831, 0xBEF5C7BF, 0x20F56D73,
+ 0xA7D6F6D6, 0x39D65C1A, 0xDAD1D394, 0x44D17958,
+ 0x5DD8BC52, 0xC3D8169E, 0x20DF9910, 0xBEDF33DC,
+ 0x12CD1305, 0x8CCDB9C9, 0x6FCA3647, 0xF1CA9C8B,
+ 0xE8C35981, 0x76C3F34D, 0x95C47CC3, 0x0BC4D60F,
+ 0x3747A67A, 0xA9470CB6, 0x4A408338, 0xD44029F4,
+ 0xCD49ECFE, 0x53494632, 0xB04EC9BC, 0x2E4E6370,
+ 0x825C43A9, 0x1C5CE965, 0xFF5B66EB, 0x615BCC27,
+ 0x7852092D, 0xE652A3E1, 0x05552C6F, 0x9B5586A3,
+ 0x1C761D06, 0x8276B7CA, 0x61713844, 0xFF719288,
+ 0xE6785782, 0x7878FD4E, 0x9B7F72C0, 0x057FD80C,
+ 0xA96DF8D5, 0x376D5219, 0xD46ADD97, 0x4A6A775B,
+ 0x5363B251, 0xCD63189D, 0x2E649713, 0xB0643DDF,
+ 0x6125D083, 0xFF257A4F, 0x1C22F5C1, 0x82225F0D,
+ 0x9B2B9A07, 0x052B30CB, 0xE62CBF45, 0x782C1589,
+ 0xD43E3550, 0x4A3E9F9C, 0xA9391012, 0x3739BADE,
+ 0x2E307FD4, 0xB030D518, 0x53375A96, 0xCD37F05A,
+ 0x4A146BFF, 0xD414C133, 0x37134EBD, 0xA913E471,
+ 0xB01A217B, 0x2E1A8BB7, 0xCD1D0439, 0x531DAEF5,
+ 0xFF0F8E2C, 0x610F24E0, 0x8208AB6E, 0x1C0801A2,
+ 0x0501C4A8, 0x9B016E64, 0x7806E1EA, 0xE6064B26
+ }
+};
diff --git a/Utilities/cmliblzma/liblzma/check/crc32_table_le.h b/Utilities/cmliblzma/liblzma/check/crc32_table_le.h
new file mode 100644
index 000000000..25f4fc443
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/check/crc32_table_le.h
@@ -0,0 +1,525 @@
+/* This file has been automatically generated by crc32_tablegen.c. */
+
+const uint32_t lzma_crc32_table[8][256] = {
+ {
+ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
+ 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
+ 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
+ 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
+ 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
+ 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
+ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
+ 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
+ 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
+ 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
+ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
+ 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
+ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
+ 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
+ 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
+ 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
+ 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
+ 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
+ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
+ 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
+ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
+ 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
+ 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
+ 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
+ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
+ 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
+ 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
+ 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
+ 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
+ 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
+ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
+ 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
+ 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
+ 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
+ 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
+ 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
+ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
+ 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
+ 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
+ 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
+ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
+ 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
+ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
+ 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
+ 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
+ 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
+ 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
+ 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
+ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
+ 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
+ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
+ 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
+ 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
+ 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
+ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
+ 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
+ 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
+ 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
+ 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
+ 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
+ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
+ 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
+ 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
+ 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
+ }, {
+ 0x00000000, 0x191B3141, 0x32366282, 0x2B2D53C3,
+ 0x646CC504, 0x7D77F445, 0x565AA786, 0x4F4196C7,
+ 0xC8D98A08, 0xD1C2BB49, 0xFAEFE88A, 0xE3F4D9CB,
+ 0xACB54F0C, 0xB5AE7E4D, 0x9E832D8E, 0x87981CCF,
+ 0x4AC21251, 0x53D92310, 0x78F470D3, 0x61EF4192,
+ 0x2EAED755, 0x37B5E614, 0x1C98B5D7, 0x05838496,
+ 0x821B9859, 0x9B00A918, 0xB02DFADB, 0xA936CB9A,
+ 0xE6775D5D, 0xFF6C6C1C, 0xD4413FDF, 0xCD5A0E9E,
+ 0x958424A2, 0x8C9F15E3, 0xA7B24620, 0xBEA97761,
+ 0xF1E8E1A6, 0xE8F3D0E7, 0xC3DE8324, 0xDAC5B265,
+ 0x5D5DAEAA, 0x44469FEB, 0x6F6BCC28, 0x7670FD69,
+ 0x39316BAE, 0x202A5AEF, 0x0B07092C, 0x121C386D,
+ 0xDF4636F3, 0xC65D07B2, 0xED705471, 0xF46B6530,
+ 0xBB2AF3F7, 0xA231C2B6, 0x891C9175, 0x9007A034,
+ 0x179FBCFB, 0x0E848DBA, 0x25A9DE79, 0x3CB2EF38,
+ 0x73F379FF, 0x6AE848BE, 0x41C51B7D, 0x58DE2A3C,
+ 0xF0794F05, 0xE9627E44, 0xC24F2D87, 0xDB541CC6,
+ 0x94158A01, 0x8D0EBB40, 0xA623E883, 0xBF38D9C2,
+ 0x38A0C50D, 0x21BBF44C, 0x0A96A78F, 0x138D96CE,
+ 0x5CCC0009, 0x45D73148, 0x6EFA628B, 0x77E153CA,
+ 0xBABB5D54, 0xA3A06C15, 0x888D3FD6, 0x91960E97,
+ 0xDED79850, 0xC7CCA911, 0xECE1FAD2, 0xF5FACB93,
+ 0x7262D75C, 0x6B79E61D, 0x4054B5DE, 0x594F849F,
+ 0x160E1258, 0x0F152319, 0x243870DA, 0x3D23419B,
+ 0x65FD6BA7, 0x7CE65AE6, 0x57CB0925, 0x4ED03864,
+ 0x0191AEA3, 0x188A9FE2, 0x33A7CC21, 0x2ABCFD60,
+ 0xAD24E1AF, 0xB43FD0EE, 0x9F12832D, 0x8609B26C,
+ 0xC94824AB, 0xD05315EA, 0xFB7E4629, 0xE2657768,
+ 0x2F3F79F6, 0x362448B7, 0x1D091B74, 0x04122A35,
+ 0x4B53BCF2, 0x52488DB3, 0x7965DE70, 0x607EEF31,
+ 0xE7E6F3FE, 0xFEFDC2BF, 0xD5D0917C, 0xCCCBA03D,
+ 0x838A36FA, 0x9A9107BB, 0xB1BC5478, 0xA8A76539,
+ 0x3B83984B, 0x2298A90A, 0x09B5FAC9, 0x10AECB88,
+ 0x5FEF5D4F, 0x46F46C0E, 0x6DD93FCD, 0x74C20E8C,
+ 0xF35A1243, 0xEA412302, 0xC16C70C1, 0xD8774180,
+ 0x9736D747, 0x8E2DE606, 0xA500B5C5, 0xBC1B8484,
+ 0x71418A1A, 0x685ABB5B, 0x4377E898, 0x5A6CD9D9,
+ 0x152D4F1E, 0x0C367E5F, 0x271B2D9C, 0x3E001CDD,
+ 0xB9980012, 0xA0833153, 0x8BAE6290, 0x92B553D1,
+ 0xDDF4C516, 0xC4EFF457, 0xEFC2A794, 0xF6D996D5,
+ 0xAE07BCE9, 0xB71C8DA8, 0x9C31DE6B, 0x852AEF2A,
+ 0xCA6B79ED, 0xD37048AC, 0xF85D1B6F, 0xE1462A2E,
+ 0x66DE36E1, 0x7FC507A0, 0x54E85463, 0x4DF36522,
+ 0x02B2F3E5, 0x1BA9C2A4, 0x30849167, 0x299FA026,
+ 0xE4C5AEB8, 0xFDDE9FF9, 0xD6F3CC3A, 0xCFE8FD7B,
+ 0x80A96BBC, 0x99B25AFD, 0xB29F093E, 0xAB84387F,
+ 0x2C1C24B0, 0x350715F1, 0x1E2A4632, 0x07317773,
+ 0x4870E1B4, 0x516BD0F5, 0x7A468336, 0x635DB277,
+ 0xCBFAD74E, 0xD2E1E60F, 0xF9CCB5CC, 0xE0D7848D,
+ 0xAF96124A, 0xB68D230B, 0x9DA070C8, 0x84BB4189,
+ 0x03235D46, 0x1A386C07, 0x31153FC4, 0x280E0E85,
+ 0x674F9842, 0x7E54A903, 0x5579FAC0, 0x4C62CB81,
+ 0x8138C51F, 0x9823F45E, 0xB30EA79D, 0xAA1596DC,
+ 0xE554001B, 0xFC4F315A, 0xD7626299, 0xCE7953D8,
+ 0x49E14F17, 0x50FA7E56, 0x7BD72D95, 0x62CC1CD4,
+ 0x2D8D8A13, 0x3496BB52, 0x1FBBE891, 0x06A0D9D0,
+ 0x5E7EF3EC, 0x4765C2AD, 0x6C48916E, 0x7553A02F,
+ 0x3A1236E8, 0x230907A9, 0x0824546A, 0x113F652B,
+ 0x96A779E4, 0x8FBC48A5, 0xA4911B66, 0xBD8A2A27,
+ 0xF2CBBCE0, 0xEBD08DA1, 0xC0FDDE62, 0xD9E6EF23,
+ 0x14BCE1BD, 0x0DA7D0FC, 0x268A833F, 0x3F91B27E,
+ 0x70D024B9, 0x69CB15F8, 0x42E6463B, 0x5BFD777A,
+ 0xDC656BB5, 0xC57E5AF4, 0xEE530937, 0xF7483876,
+ 0xB809AEB1, 0xA1129FF0, 0x8A3FCC33, 0x9324FD72
+ }, {
+ 0x00000000, 0x01C26A37, 0x0384D46E, 0x0246BE59,
+ 0x0709A8DC, 0x06CBC2EB, 0x048D7CB2, 0x054F1685,
+ 0x0E1351B8, 0x0FD13B8F, 0x0D9785D6, 0x0C55EFE1,
+ 0x091AF964, 0x08D89353, 0x0A9E2D0A, 0x0B5C473D,
+ 0x1C26A370, 0x1DE4C947, 0x1FA2771E, 0x1E601D29,
+ 0x1B2F0BAC, 0x1AED619B, 0x18ABDFC2, 0x1969B5F5,
+ 0x1235F2C8, 0x13F798FF, 0x11B126A6, 0x10734C91,
+ 0x153C5A14, 0x14FE3023, 0x16B88E7A, 0x177AE44D,
+ 0x384D46E0, 0x398F2CD7, 0x3BC9928E, 0x3A0BF8B9,
+ 0x3F44EE3C, 0x3E86840B, 0x3CC03A52, 0x3D025065,
+ 0x365E1758, 0x379C7D6F, 0x35DAC336, 0x3418A901,
+ 0x3157BF84, 0x3095D5B3, 0x32D36BEA, 0x331101DD,
+ 0x246BE590, 0x25A98FA7, 0x27EF31FE, 0x262D5BC9,
+ 0x23624D4C, 0x22A0277B, 0x20E69922, 0x2124F315,
+ 0x2A78B428, 0x2BBADE1F, 0x29FC6046, 0x283E0A71,
+ 0x2D711CF4, 0x2CB376C3, 0x2EF5C89A, 0x2F37A2AD,
+ 0x709A8DC0, 0x7158E7F7, 0x731E59AE, 0x72DC3399,
+ 0x7793251C, 0x76514F2B, 0x7417F172, 0x75D59B45,
+ 0x7E89DC78, 0x7F4BB64F, 0x7D0D0816, 0x7CCF6221,
+ 0x798074A4, 0x78421E93, 0x7A04A0CA, 0x7BC6CAFD,
+ 0x6CBC2EB0, 0x6D7E4487, 0x6F38FADE, 0x6EFA90E9,
+ 0x6BB5866C, 0x6A77EC5B, 0x68315202, 0x69F33835,
+ 0x62AF7F08, 0x636D153F, 0x612BAB66, 0x60E9C151,
+ 0x65A6D7D4, 0x6464BDE3, 0x662203BA, 0x67E0698D,
+ 0x48D7CB20, 0x4915A117, 0x4B531F4E, 0x4A917579,
+ 0x4FDE63FC, 0x4E1C09CB, 0x4C5AB792, 0x4D98DDA5,
+ 0x46C49A98, 0x4706F0AF, 0x45404EF6, 0x448224C1,
+ 0x41CD3244, 0x400F5873, 0x4249E62A, 0x438B8C1D,
+ 0x54F16850, 0x55330267, 0x5775BC3E, 0x56B7D609,
+ 0x53F8C08C, 0x523AAABB, 0x507C14E2, 0x51BE7ED5,
+ 0x5AE239E8, 0x5B2053DF, 0x5966ED86, 0x58A487B1,
+ 0x5DEB9134, 0x5C29FB03, 0x5E6F455A, 0x5FAD2F6D,
+ 0xE1351B80, 0xE0F771B7, 0xE2B1CFEE, 0xE373A5D9,
+ 0xE63CB35C, 0xE7FED96B, 0xE5B86732, 0xE47A0D05,
+ 0xEF264A38, 0xEEE4200F, 0xECA29E56, 0xED60F461,
+ 0xE82FE2E4, 0xE9ED88D3, 0xEBAB368A, 0xEA695CBD,
+ 0xFD13B8F0, 0xFCD1D2C7, 0xFE976C9E, 0xFF5506A9,
+ 0xFA1A102C, 0xFBD87A1B, 0xF99EC442, 0xF85CAE75,
+ 0xF300E948, 0xF2C2837F, 0xF0843D26, 0xF1465711,
+ 0xF4094194, 0xF5CB2BA3, 0xF78D95FA, 0xF64FFFCD,
+ 0xD9785D60, 0xD8BA3757, 0xDAFC890E, 0xDB3EE339,
+ 0xDE71F5BC, 0xDFB39F8B, 0xDDF521D2, 0xDC374BE5,
+ 0xD76B0CD8, 0xD6A966EF, 0xD4EFD8B6, 0xD52DB281,
+ 0xD062A404, 0xD1A0CE33, 0xD3E6706A, 0xD2241A5D,
+ 0xC55EFE10, 0xC49C9427, 0xC6DA2A7E, 0xC7184049,
+ 0xC25756CC, 0xC3953CFB, 0xC1D382A2, 0xC011E895,
+ 0xCB4DAFA8, 0xCA8FC59F, 0xC8C97BC6, 0xC90B11F1,
+ 0xCC440774, 0xCD866D43, 0xCFC0D31A, 0xCE02B92D,
+ 0x91AF9640, 0x906DFC77, 0x922B422E, 0x93E92819,
+ 0x96A63E9C, 0x976454AB, 0x9522EAF2, 0x94E080C5,
+ 0x9FBCC7F8, 0x9E7EADCF, 0x9C381396, 0x9DFA79A1,
+ 0x98B56F24, 0x99770513, 0x9B31BB4A, 0x9AF3D17D,
+ 0x8D893530, 0x8C4B5F07, 0x8E0DE15E, 0x8FCF8B69,
+ 0x8A809DEC, 0x8B42F7DB, 0x89044982, 0x88C623B5,
+ 0x839A6488, 0x82580EBF, 0x801EB0E6, 0x81DCDAD1,
+ 0x8493CC54, 0x8551A663, 0x8717183A, 0x86D5720D,
+ 0xA9E2D0A0, 0xA820BA97, 0xAA6604CE, 0xABA46EF9,
+ 0xAEEB787C, 0xAF29124B, 0xAD6FAC12, 0xACADC625,
+ 0xA7F18118, 0xA633EB2F, 0xA4755576, 0xA5B73F41,
+ 0xA0F829C4, 0xA13A43F3, 0xA37CFDAA, 0xA2BE979D,
+ 0xB5C473D0, 0xB40619E7, 0xB640A7BE, 0xB782CD89,
+ 0xB2CDDB0C, 0xB30FB13B, 0xB1490F62, 0xB08B6555,
+ 0xBBD72268, 0xBA15485F, 0xB853F606, 0xB9919C31,
+ 0xBCDE8AB4, 0xBD1CE083, 0xBF5A5EDA, 0xBE9834ED
+ }, {
+ 0x00000000, 0xB8BC6765, 0xAA09C88B, 0x12B5AFEE,
+ 0x8F629757, 0x37DEF032, 0x256B5FDC, 0x9DD738B9,
+ 0xC5B428EF, 0x7D084F8A, 0x6FBDE064, 0xD7018701,
+ 0x4AD6BFB8, 0xF26AD8DD, 0xE0DF7733, 0x58631056,
+ 0x5019579F, 0xE8A530FA, 0xFA109F14, 0x42ACF871,
+ 0xDF7BC0C8, 0x67C7A7AD, 0x75720843, 0xCDCE6F26,
+ 0x95AD7F70, 0x2D111815, 0x3FA4B7FB, 0x8718D09E,
+ 0x1ACFE827, 0xA2738F42, 0xB0C620AC, 0x087A47C9,
+ 0xA032AF3E, 0x188EC85B, 0x0A3B67B5, 0xB28700D0,
+ 0x2F503869, 0x97EC5F0C, 0x8559F0E2, 0x3DE59787,
+ 0x658687D1, 0xDD3AE0B4, 0xCF8F4F5A, 0x7733283F,
+ 0xEAE41086, 0x525877E3, 0x40EDD80D, 0xF851BF68,
+ 0xF02BF8A1, 0x48979FC4, 0x5A22302A, 0xE29E574F,
+ 0x7F496FF6, 0xC7F50893, 0xD540A77D, 0x6DFCC018,
+ 0x359FD04E, 0x8D23B72B, 0x9F9618C5, 0x272A7FA0,
+ 0xBAFD4719, 0x0241207C, 0x10F48F92, 0xA848E8F7,
+ 0x9B14583D, 0x23A83F58, 0x311D90B6, 0x89A1F7D3,
+ 0x1476CF6A, 0xACCAA80F, 0xBE7F07E1, 0x06C36084,
+ 0x5EA070D2, 0xE61C17B7, 0xF4A9B859, 0x4C15DF3C,
+ 0xD1C2E785, 0x697E80E0, 0x7BCB2F0E, 0xC377486B,
+ 0xCB0D0FA2, 0x73B168C7, 0x6104C729, 0xD9B8A04C,
+ 0x446F98F5, 0xFCD3FF90, 0xEE66507E, 0x56DA371B,
+ 0x0EB9274D, 0xB6054028, 0xA4B0EFC6, 0x1C0C88A3,
+ 0x81DBB01A, 0x3967D77F, 0x2BD27891, 0x936E1FF4,
+ 0x3B26F703, 0x839A9066, 0x912F3F88, 0x299358ED,
+ 0xB4446054, 0x0CF80731, 0x1E4DA8DF, 0xA6F1CFBA,
+ 0xFE92DFEC, 0x462EB889, 0x549B1767, 0xEC277002,
+ 0x71F048BB, 0xC94C2FDE, 0xDBF98030, 0x6345E755,
+ 0x6B3FA09C, 0xD383C7F9, 0xC1366817, 0x798A0F72,
+ 0xE45D37CB, 0x5CE150AE, 0x4E54FF40, 0xF6E89825,
+ 0xAE8B8873, 0x1637EF16, 0x048240F8, 0xBC3E279D,
+ 0x21E91F24, 0x99557841, 0x8BE0D7AF, 0x335CB0CA,
+ 0xED59B63B, 0x55E5D15E, 0x47507EB0, 0xFFEC19D5,
+ 0x623B216C, 0xDA874609, 0xC832E9E7, 0x708E8E82,
+ 0x28ED9ED4, 0x9051F9B1, 0x82E4565F, 0x3A58313A,
+ 0xA78F0983, 0x1F336EE6, 0x0D86C108, 0xB53AA66D,
+ 0xBD40E1A4, 0x05FC86C1, 0x1749292F, 0xAFF54E4A,
+ 0x322276F3, 0x8A9E1196, 0x982BBE78, 0x2097D91D,
+ 0x78F4C94B, 0xC048AE2E, 0xD2FD01C0, 0x6A4166A5,
+ 0xF7965E1C, 0x4F2A3979, 0x5D9F9697, 0xE523F1F2,
+ 0x4D6B1905, 0xF5D77E60, 0xE762D18E, 0x5FDEB6EB,
+ 0xC2098E52, 0x7AB5E937, 0x680046D9, 0xD0BC21BC,
+ 0x88DF31EA, 0x3063568F, 0x22D6F961, 0x9A6A9E04,
+ 0x07BDA6BD, 0xBF01C1D8, 0xADB46E36, 0x15080953,
+ 0x1D724E9A, 0xA5CE29FF, 0xB77B8611, 0x0FC7E174,
+ 0x9210D9CD, 0x2AACBEA8, 0x38191146, 0x80A57623,
+ 0xD8C66675, 0x607A0110, 0x72CFAEFE, 0xCA73C99B,
+ 0x57A4F122, 0xEF189647, 0xFDAD39A9, 0x45115ECC,
+ 0x764DEE06, 0xCEF18963, 0xDC44268D, 0x64F841E8,
+ 0xF92F7951, 0x41931E34, 0x5326B1DA, 0xEB9AD6BF,
+ 0xB3F9C6E9, 0x0B45A18C, 0x19F00E62, 0xA14C6907,
+ 0x3C9B51BE, 0x842736DB, 0x96929935, 0x2E2EFE50,
+ 0x2654B999, 0x9EE8DEFC, 0x8C5D7112, 0x34E11677,
+ 0xA9362ECE, 0x118A49AB, 0x033FE645, 0xBB838120,
+ 0xE3E09176, 0x5B5CF613, 0x49E959FD, 0xF1553E98,
+ 0x6C820621, 0xD43E6144, 0xC68BCEAA, 0x7E37A9CF,
+ 0xD67F4138, 0x6EC3265D, 0x7C7689B3, 0xC4CAEED6,
+ 0x591DD66F, 0xE1A1B10A, 0xF3141EE4, 0x4BA87981,
+ 0x13CB69D7, 0xAB770EB2, 0xB9C2A15C, 0x017EC639,
+ 0x9CA9FE80, 0x241599E5, 0x36A0360B, 0x8E1C516E,
+ 0x866616A7, 0x3EDA71C2, 0x2C6FDE2C, 0x94D3B949,
+ 0x090481F0, 0xB1B8E695, 0xA30D497B, 0x1BB12E1E,
+ 0x43D23E48, 0xFB6E592D, 0xE9DBF6C3, 0x516791A6,
+ 0xCCB0A91F, 0x740CCE7A, 0x66B96194, 0xDE0506F1
+ }, {
+ 0x00000000, 0x3D6029B0, 0x7AC05360, 0x47A07AD0,
+ 0xF580A6C0, 0xC8E08F70, 0x8F40F5A0, 0xB220DC10,
+ 0x30704BC1, 0x0D106271, 0x4AB018A1, 0x77D03111,
+ 0xC5F0ED01, 0xF890C4B1, 0xBF30BE61, 0x825097D1,
+ 0x60E09782, 0x5D80BE32, 0x1A20C4E2, 0x2740ED52,
+ 0x95603142, 0xA80018F2, 0xEFA06222, 0xD2C04B92,
+ 0x5090DC43, 0x6DF0F5F3, 0x2A508F23, 0x1730A693,
+ 0xA5107A83, 0x98705333, 0xDFD029E3, 0xE2B00053,
+ 0xC1C12F04, 0xFCA106B4, 0xBB017C64, 0x866155D4,
+ 0x344189C4, 0x0921A074, 0x4E81DAA4, 0x73E1F314,
+ 0xF1B164C5, 0xCCD14D75, 0x8B7137A5, 0xB6111E15,
+ 0x0431C205, 0x3951EBB5, 0x7EF19165, 0x4391B8D5,
+ 0xA121B886, 0x9C419136, 0xDBE1EBE6, 0xE681C256,
+ 0x54A11E46, 0x69C137F6, 0x2E614D26, 0x13016496,
+ 0x9151F347, 0xAC31DAF7, 0xEB91A027, 0xD6F18997,
+ 0x64D15587, 0x59B17C37, 0x1E1106E7, 0x23712F57,
+ 0x58F35849, 0x659371F9, 0x22330B29, 0x1F532299,
+ 0xAD73FE89, 0x9013D739, 0xD7B3ADE9, 0xEAD38459,
+ 0x68831388, 0x55E33A38, 0x124340E8, 0x2F236958,
+ 0x9D03B548, 0xA0639CF8, 0xE7C3E628, 0xDAA3CF98,
+ 0x3813CFCB, 0x0573E67B, 0x42D39CAB, 0x7FB3B51B,
+ 0xCD93690B, 0xF0F340BB, 0xB7533A6B, 0x8A3313DB,
+ 0x0863840A, 0x3503ADBA, 0x72A3D76A, 0x4FC3FEDA,
+ 0xFDE322CA, 0xC0830B7A, 0x872371AA, 0xBA43581A,
+ 0x9932774D, 0xA4525EFD, 0xE3F2242D, 0xDE920D9D,
+ 0x6CB2D18D, 0x51D2F83D, 0x167282ED, 0x2B12AB5D,
+ 0xA9423C8C, 0x9422153C, 0xD3826FEC, 0xEEE2465C,
+ 0x5CC29A4C, 0x61A2B3FC, 0x2602C92C, 0x1B62E09C,
+ 0xF9D2E0CF, 0xC4B2C97F, 0x8312B3AF, 0xBE729A1F,
+ 0x0C52460F, 0x31326FBF, 0x7692156F, 0x4BF23CDF,
+ 0xC9A2AB0E, 0xF4C282BE, 0xB362F86E, 0x8E02D1DE,
+ 0x3C220DCE, 0x0142247E, 0x46E25EAE, 0x7B82771E,
+ 0xB1E6B092, 0x8C869922, 0xCB26E3F2, 0xF646CA42,
+ 0x44661652, 0x79063FE2, 0x3EA64532, 0x03C66C82,
+ 0x8196FB53, 0xBCF6D2E3, 0xFB56A833, 0xC6368183,
+ 0x74165D93, 0x49767423, 0x0ED60EF3, 0x33B62743,
+ 0xD1062710, 0xEC660EA0, 0xABC67470, 0x96A65DC0,
+ 0x248681D0, 0x19E6A860, 0x5E46D2B0, 0x6326FB00,
+ 0xE1766CD1, 0xDC164561, 0x9BB63FB1, 0xA6D61601,
+ 0x14F6CA11, 0x2996E3A1, 0x6E369971, 0x5356B0C1,
+ 0x70279F96, 0x4D47B626, 0x0AE7CCF6, 0x3787E546,
+ 0x85A73956, 0xB8C710E6, 0xFF676A36, 0xC2074386,
+ 0x4057D457, 0x7D37FDE7, 0x3A978737, 0x07F7AE87,
+ 0xB5D77297, 0x88B75B27, 0xCF1721F7, 0xF2770847,
+ 0x10C70814, 0x2DA721A4, 0x6A075B74, 0x576772C4,
+ 0xE547AED4, 0xD8278764, 0x9F87FDB4, 0xA2E7D404,
+ 0x20B743D5, 0x1DD76A65, 0x5A7710B5, 0x67173905,
+ 0xD537E515, 0xE857CCA5, 0xAFF7B675, 0x92979FC5,
+ 0xE915E8DB, 0xD475C16B, 0x93D5BBBB, 0xAEB5920B,
+ 0x1C954E1B, 0x21F567AB, 0x66551D7B, 0x5B3534CB,
+ 0xD965A31A, 0xE4058AAA, 0xA3A5F07A, 0x9EC5D9CA,
+ 0x2CE505DA, 0x11852C6A, 0x562556BA, 0x6B457F0A,
+ 0x89F57F59, 0xB49556E9, 0xF3352C39, 0xCE550589,
+ 0x7C75D999, 0x4115F029, 0x06B58AF9, 0x3BD5A349,
+ 0xB9853498, 0x84E51D28, 0xC34567F8, 0xFE254E48,
+ 0x4C059258, 0x7165BBE8, 0x36C5C138, 0x0BA5E888,
+ 0x28D4C7DF, 0x15B4EE6F, 0x521494BF, 0x6F74BD0F,
+ 0xDD54611F, 0xE03448AF, 0xA794327F, 0x9AF41BCF,
+ 0x18A48C1E, 0x25C4A5AE, 0x6264DF7E, 0x5F04F6CE,
+ 0xED242ADE, 0xD044036E, 0x97E479BE, 0xAA84500E,
+ 0x4834505D, 0x755479ED, 0x32F4033D, 0x0F942A8D,
+ 0xBDB4F69D, 0x80D4DF2D, 0xC774A5FD, 0xFA148C4D,
+ 0x78441B9C, 0x4524322C, 0x028448FC, 0x3FE4614C,
+ 0x8DC4BD5C, 0xB0A494EC, 0xF704EE3C, 0xCA64C78C
+ }, {
+ 0x00000000, 0xCB5CD3A5, 0x4DC8A10B, 0x869472AE,
+ 0x9B914216, 0x50CD91B3, 0xD659E31D, 0x1D0530B8,
+ 0xEC53826D, 0x270F51C8, 0xA19B2366, 0x6AC7F0C3,
+ 0x77C2C07B, 0xBC9E13DE, 0x3A0A6170, 0xF156B2D5,
+ 0x03D6029B, 0xC88AD13E, 0x4E1EA390, 0x85427035,
+ 0x9847408D, 0x531B9328, 0xD58FE186, 0x1ED33223,
+ 0xEF8580F6, 0x24D95353, 0xA24D21FD, 0x6911F258,
+ 0x7414C2E0, 0xBF481145, 0x39DC63EB, 0xF280B04E,
+ 0x07AC0536, 0xCCF0D693, 0x4A64A43D, 0x81387798,
+ 0x9C3D4720, 0x57619485, 0xD1F5E62B, 0x1AA9358E,
+ 0xEBFF875B, 0x20A354FE, 0xA6372650, 0x6D6BF5F5,
+ 0x706EC54D, 0xBB3216E8, 0x3DA66446, 0xF6FAB7E3,
+ 0x047A07AD, 0xCF26D408, 0x49B2A6A6, 0x82EE7503,
+ 0x9FEB45BB, 0x54B7961E, 0xD223E4B0, 0x197F3715,
+ 0xE82985C0, 0x23755665, 0xA5E124CB, 0x6EBDF76E,
+ 0x73B8C7D6, 0xB8E41473, 0x3E7066DD, 0xF52CB578,
+ 0x0F580A6C, 0xC404D9C9, 0x4290AB67, 0x89CC78C2,
+ 0x94C9487A, 0x5F959BDF, 0xD901E971, 0x125D3AD4,
+ 0xE30B8801, 0x28575BA4, 0xAEC3290A, 0x659FFAAF,
+ 0x789ACA17, 0xB3C619B2, 0x35526B1C, 0xFE0EB8B9,
+ 0x0C8E08F7, 0xC7D2DB52, 0x4146A9FC, 0x8A1A7A59,
+ 0x971F4AE1, 0x5C439944, 0xDAD7EBEA, 0x118B384F,
+ 0xE0DD8A9A, 0x2B81593F, 0xAD152B91, 0x6649F834,
+ 0x7B4CC88C, 0xB0101B29, 0x36846987, 0xFDD8BA22,
+ 0x08F40F5A, 0xC3A8DCFF, 0x453CAE51, 0x8E607DF4,
+ 0x93654D4C, 0x58399EE9, 0xDEADEC47, 0x15F13FE2,
+ 0xE4A78D37, 0x2FFB5E92, 0xA96F2C3C, 0x6233FF99,
+ 0x7F36CF21, 0xB46A1C84, 0x32FE6E2A, 0xF9A2BD8F,
+ 0x0B220DC1, 0xC07EDE64, 0x46EAACCA, 0x8DB67F6F,
+ 0x90B34FD7, 0x5BEF9C72, 0xDD7BEEDC, 0x16273D79,
+ 0xE7718FAC, 0x2C2D5C09, 0xAAB92EA7, 0x61E5FD02,
+ 0x7CE0CDBA, 0xB7BC1E1F, 0x31286CB1, 0xFA74BF14,
+ 0x1EB014D8, 0xD5ECC77D, 0x5378B5D3, 0x98246676,
+ 0x852156CE, 0x4E7D856B, 0xC8E9F7C5, 0x03B52460,
+ 0xF2E396B5, 0x39BF4510, 0xBF2B37BE, 0x7477E41B,
+ 0x6972D4A3, 0xA22E0706, 0x24BA75A8, 0xEFE6A60D,
+ 0x1D661643, 0xD63AC5E6, 0x50AEB748, 0x9BF264ED,
+ 0x86F75455, 0x4DAB87F0, 0xCB3FF55E, 0x006326FB,
+ 0xF135942E, 0x3A69478B, 0xBCFD3525, 0x77A1E680,
+ 0x6AA4D638, 0xA1F8059D, 0x276C7733, 0xEC30A496,
+ 0x191C11EE, 0xD240C24B, 0x54D4B0E5, 0x9F886340,
+ 0x828D53F8, 0x49D1805D, 0xCF45F2F3, 0x04192156,
+ 0xF54F9383, 0x3E134026, 0xB8873288, 0x73DBE12D,
+ 0x6EDED195, 0xA5820230, 0x2316709E, 0xE84AA33B,
+ 0x1ACA1375, 0xD196C0D0, 0x5702B27E, 0x9C5E61DB,
+ 0x815B5163, 0x4A0782C6, 0xCC93F068, 0x07CF23CD,
+ 0xF6999118, 0x3DC542BD, 0xBB513013, 0x700DE3B6,
+ 0x6D08D30E, 0xA65400AB, 0x20C07205, 0xEB9CA1A0,
+ 0x11E81EB4, 0xDAB4CD11, 0x5C20BFBF, 0x977C6C1A,
+ 0x8A795CA2, 0x41258F07, 0xC7B1FDA9, 0x0CED2E0C,
+ 0xFDBB9CD9, 0x36E74F7C, 0xB0733DD2, 0x7B2FEE77,
+ 0x662ADECF, 0xAD760D6A, 0x2BE27FC4, 0xE0BEAC61,
+ 0x123E1C2F, 0xD962CF8A, 0x5FF6BD24, 0x94AA6E81,
+ 0x89AF5E39, 0x42F38D9C, 0xC467FF32, 0x0F3B2C97,
+ 0xFE6D9E42, 0x35314DE7, 0xB3A53F49, 0x78F9ECEC,
+ 0x65FCDC54, 0xAEA00FF1, 0x28347D5F, 0xE368AEFA,
+ 0x16441B82, 0xDD18C827, 0x5B8CBA89, 0x90D0692C,
+ 0x8DD55994, 0x46898A31, 0xC01DF89F, 0x0B412B3A,
+ 0xFA1799EF, 0x314B4A4A, 0xB7DF38E4, 0x7C83EB41,
+ 0x6186DBF9, 0xAADA085C, 0x2C4E7AF2, 0xE712A957,
+ 0x15921919, 0xDECECABC, 0x585AB812, 0x93066BB7,
+ 0x8E035B0F, 0x455F88AA, 0xC3CBFA04, 0x089729A1,
+ 0xF9C19B74, 0x329D48D1, 0xB4093A7F, 0x7F55E9DA,
+ 0x6250D962, 0xA90C0AC7, 0x2F987869, 0xE4C4ABCC
+ }, {
+ 0x00000000, 0xA6770BB4, 0x979F1129, 0x31E81A9D,
+ 0xF44F2413, 0x52382FA7, 0x63D0353A, 0xC5A73E8E,
+ 0x33EF4E67, 0x959845D3, 0xA4705F4E, 0x020754FA,
+ 0xC7A06A74, 0x61D761C0, 0x503F7B5D, 0xF64870E9,
+ 0x67DE9CCE, 0xC1A9977A, 0xF0418DE7, 0x56368653,
+ 0x9391B8DD, 0x35E6B369, 0x040EA9F4, 0xA279A240,
+ 0x5431D2A9, 0xF246D91D, 0xC3AEC380, 0x65D9C834,
+ 0xA07EF6BA, 0x0609FD0E, 0x37E1E793, 0x9196EC27,
+ 0xCFBD399C, 0x69CA3228, 0x582228B5, 0xFE552301,
+ 0x3BF21D8F, 0x9D85163B, 0xAC6D0CA6, 0x0A1A0712,
+ 0xFC5277FB, 0x5A257C4F, 0x6BCD66D2, 0xCDBA6D66,
+ 0x081D53E8, 0xAE6A585C, 0x9F8242C1, 0x39F54975,
+ 0xA863A552, 0x0E14AEE6, 0x3FFCB47B, 0x998BBFCF,
+ 0x5C2C8141, 0xFA5B8AF5, 0xCBB39068, 0x6DC49BDC,
+ 0x9B8CEB35, 0x3DFBE081, 0x0C13FA1C, 0xAA64F1A8,
+ 0x6FC3CF26, 0xC9B4C492, 0xF85CDE0F, 0x5E2BD5BB,
+ 0x440B7579, 0xE27C7ECD, 0xD3946450, 0x75E36FE4,
+ 0xB044516A, 0x16335ADE, 0x27DB4043, 0x81AC4BF7,
+ 0x77E43B1E, 0xD19330AA, 0xE07B2A37, 0x460C2183,
+ 0x83AB1F0D, 0x25DC14B9, 0x14340E24, 0xB2430590,
+ 0x23D5E9B7, 0x85A2E203, 0xB44AF89E, 0x123DF32A,
+ 0xD79ACDA4, 0x71EDC610, 0x4005DC8D, 0xE672D739,
+ 0x103AA7D0, 0xB64DAC64, 0x87A5B6F9, 0x21D2BD4D,
+ 0xE47583C3, 0x42028877, 0x73EA92EA, 0xD59D995E,
+ 0x8BB64CE5, 0x2DC14751, 0x1C295DCC, 0xBA5E5678,
+ 0x7FF968F6, 0xD98E6342, 0xE86679DF, 0x4E11726B,
+ 0xB8590282, 0x1E2E0936, 0x2FC613AB, 0x89B1181F,
+ 0x4C162691, 0xEA612D25, 0xDB8937B8, 0x7DFE3C0C,
+ 0xEC68D02B, 0x4A1FDB9F, 0x7BF7C102, 0xDD80CAB6,
+ 0x1827F438, 0xBE50FF8C, 0x8FB8E511, 0x29CFEEA5,
+ 0xDF879E4C, 0x79F095F8, 0x48188F65, 0xEE6F84D1,
+ 0x2BC8BA5F, 0x8DBFB1EB, 0xBC57AB76, 0x1A20A0C2,
+ 0x8816EAF2, 0x2E61E146, 0x1F89FBDB, 0xB9FEF06F,
+ 0x7C59CEE1, 0xDA2EC555, 0xEBC6DFC8, 0x4DB1D47C,
+ 0xBBF9A495, 0x1D8EAF21, 0x2C66B5BC, 0x8A11BE08,
+ 0x4FB68086, 0xE9C18B32, 0xD82991AF, 0x7E5E9A1B,
+ 0xEFC8763C, 0x49BF7D88, 0x78576715, 0xDE206CA1,
+ 0x1B87522F, 0xBDF0599B, 0x8C184306, 0x2A6F48B2,
+ 0xDC27385B, 0x7A5033EF, 0x4BB82972, 0xEDCF22C6,
+ 0x28681C48, 0x8E1F17FC, 0xBFF70D61, 0x198006D5,
+ 0x47ABD36E, 0xE1DCD8DA, 0xD034C247, 0x7643C9F3,
+ 0xB3E4F77D, 0x1593FCC9, 0x247BE654, 0x820CEDE0,
+ 0x74449D09, 0xD23396BD, 0xE3DB8C20, 0x45AC8794,
+ 0x800BB91A, 0x267CB2AE, 0x1794A833, 0xB1E3A387,
+ 0x20754FA0, 0x86024414, 0xB7EA5E89, 0x119D553D,
+ 0xD43A6BB3, 0x724D6007, 0x43A57A9A, 0xE5D2712E,
+ 0x139A01C7, 0xB5ED0A73, 0x840510EE, 0x22721B5A,
+ 0xE7D525D4, 0x41A22E60, 0x704A34FD, 0xD63D3F49,
+ 0xCC1D9F8B, 0x6A6A943F, 0x5B828EA2, 0xFDF58516,
+ 0x3852BB98, 0x9E25B02C, 0xAFCDAAB1, 0x09BAA105,
+ 0xFFF2D1EC, 0x5985DA58, 0x686DC0C5, 0xCE1ACB71,
+ 0x0BBDF5FF, 0xADCAFE4B, 0x9C22E4D6, 0x3A55EF62,
+ 0xABC30345, 0x0DB408F1, 0x3C5C126C, 0x9A2B19D8,
+ 0x5F8C2756, 0xF9FB2CE2, 0xC813367F, 0x6E643DCB,
+ 0x982C4D22, 0x3E5B4696, 0x0FB35C0B, 0xA9C457BF,
+ 0x6C636931, 0xCA146285, 0xFBFC7818, 0x5D8B73AC,
+ 0x03A0A617, 0xA5D7ADA3, 0x943FB73E, 0x3248BC8A,
+ 0xF7EF8204, 0x519889B0, 0x6070932D, 0xC6079899,
+ 0x304FE870, 0x9638E3C4, 0xA7D0F959, 0x01A7F2ED,
+ 0xC400CC63, 0x6277C7D7, 0x539FDD4A, 0xF5E8D6FE,
+ 0x647E3AD9, 0xC209316D, 0xF3E12BF0, 0x55962044,
+ 0x90311ECA, 0x3646157E, 0x07AE0FE3, 0xA1D90457,
+ 0x579174BE, 0xF1E67F0A, 0xC00E6597, 0x66796E23,
+ 0xA3DE50AD, 0x05A95B19, 0x34414184, 0x92364A30
+ }, {
+ 0x00000000, 0xCCAA009E, 0x4225077D, 0x8E8F07E3,
+ 0x844A0EFA, 0x48E00E64, 0xC66F0987, 0x0AC50919,
+ 0xD3E51BB5, 0x1F4F1B2B, 0x91C01CC8, 0x5D6A1C56,
+ 0x57AF154F, 0x9B0515D1, 0x158A1232, 0xD92012AC,
+ 0x7CBB312B, 0xB01131B5, 0x3E9E3656, 0xF23436C8,
+ 0xF8F13FD1, 0x345B3F4F, 0xBAD438AC, 0x767E3832,
+ 0xAF5E2A9E, 0x63F42A00, 0xED7B2DE3, 0x21D12D7D,
+ 0x2B142464, 0xE7BE24FA, 0x69312319, 0xA59B2387,
+ 0xF9766256, 0x35DC62C8, 0xBB53652B, 0x77F965B5,
+ 0x7D3C6CAC, 0xB1966C32, 0x3F196BD1, 0xF3B36B4F,
+ 0x2A9379E3, 0xE639797D, 0x68B67E9E, 0xA41C7E00,
+ 0xAED97719, 0x62737787, 0xECFC7064, 0x205670FA,
+ 0x85CD537D, 0x496753E3, 0xC7E85400, 0x0B42549E,
+ 0x01875D87, 0xCD2D5D19, 0x43A25AFA, 0x8F085A64,
+ 0x562848C8, 0x9A824856, 0x140D4FB5, 0xD8A74F2B,
+ 0xD2624632, 0x1EC846AC, 0x9047414F, 0x5CED41D1,
+ 0x299DC2ED, 0xE537C273, 0x6BB8C590, 0xA712C50E,
+ 0xADD7CC17, 0x617DCC89, 0xEFF2CB6A, 0x2358CBF4,
+ 0xFA78D958, 0x36D2D9C6, 0xB85DDE25, 0x74F7DEBB,
+ 0x7E32D7A2, 0xB298D73C, 0x3C17D0DF, 0xF0BDD041,
+ 0x5526F3C6, 0x998CF358, 0x1703F4BB, 0xDBA9F425,
+ 0xD16CFD3C, 0x1DC6FDA2, 0x9349FA41, 0x5FE3FADF,
+ 0x86C3E873, 0x4A69E8ED, 0xC4E6EF0E, 0x084CEF90,
+ 0x0289E689, 0xCE23E617, 0x40ACE1F4, 0x8C06E16A,
+ 0xD0EBA0BB, 0x1C41A025, 0x92CEA7C6, 0x5E64A758,
+ 0x54A1AE41, 0x980BAEDF, 0x1684A93C, 0xDA2EA9A2,
+ 0x030EBB0E, 0xCFA4BB90, 0x412BBC73, 0x8D81BCED,
+ 0x8744B5F4, 0x4BEEB56A, 0xC561B289, 0x09CBB217,
+ 0xAC509190, 0x60FA910E, 0xEE7596ED, 0x22DF9673,
+ 0x281A9F6A, 0xE4B09FF4, 0x6A3F9817, 0xA6959889,
+ 0x7FB58A25, 0xB31F8ABB, 0x3D908D58, 0xF13A8DC6,
+ 0xFBFF84DF, 0x37558441, 0xB9DA83A2, 0x7570833C,
+ 0x533B85DA, 0x9F918544, 0x111E82A7, 0xDDB48239,
+ 0xD7718B20, 0x1BDB8BBE, 0x95548C5D, 0x59FE8CC3,
+ 0x80DE9E6F, 0x4C749EF1, 0xC2FB9912, 0x0E51998C,
+ 0x04949095, 0xC83E900B, 0x46B197E8, 0x8A1B9776,
+ 0x2F80B4F1, 0xE32AB46F, 0x6DA5B38C, 0xA10FB312,
+ 0xABCABA0B, 0x6760BA95, 0xE9EFBD76, 0x2545BDE8,
+ 0xFC65AF44, 0x30CFAFDA, 0xBE40A839, 0x72EAA8A7,
+ 0x782FA1BE, 0xB485A120, 0x3A0AA6C3, 0xF6A0A65D,
+ 0xAA4DE78C, 0x66E7E712, 0xE868E0F1, 0x24C2E06F,
+ 0x2E07E976, 0xE2ADE9E8, 0x6C22EE0B, 0xA088EE95,
+ 0x79A8FC39, 0xB502FCA7, 0x3B8DFB44, 0xF727FBDA,
+ 0xFDE2F2C3, 0x3148F25D, 0xBFC7F5BE, 0x736DF520,
+ 0xD6F6D6A7, 0x1A5CD639, 0x94D3D1DA, 0x5879D144,
+ 0x52BCD85D, 0x9E16D8C3, 0x1099DF20, 0xDC33DFBE,
+ 0x0513CD12, 0xC9B9CD8C, 0x4736CA6F, 0x8B9CCAF1,
+ 0x8159C3E8, 0x4DF3C376, 0xC37CC495, 0x0FD6C40B,
+ 0x7AA64737, 0xB60C47A9, 0x3883404A, 0xF42940D4,
+ 0xFEEC49CD, 0x32464953, 0xBCC94EB0, 0x70634E2E,
+ 0xA9435C82, 0x65E95C1C, 0xEB665BFF, 0x27CC5B61,
+ 0x2D095278, 0xE1A352E6, 0x6F2C5505, 0xA386559B,
+ 0x061D761C, 0xCAB77682, 0x44387161, 0x889271FF,
+ 0x825778E6, 0x4EFD7878, 0xC0727F9B, 0x0CD87F05,
+ 0xD5F86DA9, 0x19526D37, 0x97DD6AD4, 0x5B776A4A,
+ 0x51B26353, 0x9D1863CD, 0x1397642E, 0xDF3D64B0,
+ 0x83D02561, 0x4F7A25FF, 0xC1F5221C, 0x0D5F2282,
+ 0x079A2B9B, 0xCB302B05, 0x45BF2CE6, 0x89152C78,
+ 0x50353ED4, 0x9C9F3E4A, 0x121039A9, 0xDEBA3937,
+ 0xD47F302E, 0x18D530B0, 0x965A3753, 0x5AF037CD,
+ 0xFF6B144A, 0x33C114D4, 0xBD4E1337, 0x71E413A9,
+ 0x7B211AB0, 0xB78B1A2E, 0x39041DCD, 0xF5AE1D53,
+ 0x2C8E0FFF, 0xE0240F61, 0x6EAB0882, 0xA201081C,
+ 0xA8C40105, 0x646E019B, 0xEAE10678, 0x264B06E6
+ }
+};
diff --git a/Utilities/cmliblzma/liblzma/check/crc32_tablegen.c b/Utilities/cmliblzma/liblzma/check/crc32_tablegen.c
new file mode 100644
index 000000000..31a4d2751
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/check/crc32_tablegen.c
@@ -0,0 +1,117 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file crc32_tablegen.c
+/// \brief Generate crc32_table_le.h and crc32_table_be.h
+///
+/// Compiling: gcc -std=c99 -o crc32_tablegen crc32_tablegen.c
+/// Add -DWORDS_BIGENDIAN to generate big endian table.
+/// Add -DLZ_HASH_TABLE to generate lz_encoder_hash_table.h (little endian).
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+#include "../../common/tuklib_integer.h"
+
+
+static uint32_t crc32_table[8][256];
+
+
+static void
+init_crc32_table(void)
+{
+ static const uint32_t poly32 = UINT32_C(0xEDB88320);
+
+ for (size_t s = 0; s < 8; ++s) {
+ for (size_t b = 0; b < 256; ++b) {
+ uint32_t r = s == 0 ? b : crc32_table[s - 1][b];
+
+ for (size_t i = 0; i < 8; ++i) {
+ if (r & 1)
+ r = (r >> 1) ^ poly32;
+ else
+ r >>= 1;
+ }
+
+ crc32_table[s][b] = r;
+ }
+ }
+
+#ifdef WORDS_BIGENDIAN
+ for (size_t s = 0; s < 8; ++s)
+ for (size_t b = 0; b < 256; ++b)
+ crc32_table[s][b] = bswap32(crc32_table[s][b]);
+#endif
+
+ return;
+}
+
+
+static void
+print_crc32_table(void)
+{
+ printf("/* This file has been automatically generated by "
+ "crc32_tablegen.c. */\n\n"
+ "const uint32_t lzma_crc32_table[8][256] = {\n\t{");
+
+ for (size_t s = 0; s < 8; ++s) {
+ for (size_t b = 0; b < 256; ++b) {
+ if ((b % 4) == 0)
+ printf("\n\t\t");
+
+ printf("0x%08" PRIX32, crc32_table[s][b]);
+
+ if (b != 255)
+ printf(",%s", (b+1) % 4 == 0 ? "" : " ");
+ }
+
+ if (s == 7)
+ printf("\n\t}\n};\n");
+ else
+ printf("\n\t}, {");
+ }
+
+ return;
+}
+
+
+static void
+print_lz_table(void)
+{
+ printf("/* This file has been automatically generated by "
+ "crc32_tablegen.c. */\n\n"
+ "const uint32_t lzma_lz_hash_table[256] = {");
+
+ for (size_t b = 0; b < 256; ++b) {
+ if ((b % 4) == 0)
+ printf("\n\t");
+
+ printf("0x%08" PRIX32, crc32_table[0][b]);
+
+ if (b != 255)
+ printf(",%s", (b+1) % 4 == 0 ? "" : " ");
+ }
+
+ printf("\n};\n");
+
+ return;
+}
+
+
+int
+main(void)
+{
+ init_crc32_table();
+
+#ifdef LZ_HASH_TABLE
+ print_lz_table();
+#else
+ print_crc32_table();
+#endif
+
+ return 0;
+}
diff --git a/Utilities/cmliblzma/liblzma/check/crc32_x86.S b/Utilities/cmliblzma/liblzma/check/crc32_x86.S
new file mode 100644
index 000000000..67f68a414
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/check/crc32_x86.S
@@ -0,0 +1,304 @@
+/*
+ * Speed-optimized CRC32 using slicing-by-eight algorithm
+ *
+ * This uses only i386 instructions, but it is optimized for i686 and later
+ * (including e.g. Pentium II/III/IV, Athlon XP, and Core 2). For i586
+ * (e.g. Pentium), slicing-by-four would be better, and even the C version
+ * of slicing-by-eight built with gcc -march=i586 tends to be a little bit
+ * better than this. Very few probably run this code on i586 or older x86
+ * so this shouldn't be a problem in practice.
+ *
+ * Authors: Igor Pavlov (original version)
+ * Lasse Collin (AT&T syntax, PIC support, better portability)
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ *
+ * This code needs lzma_crc32_table, which can be created using the
+ * following C code:
+
+uint32_t lzma_crc32_table[8][256];
+
+void
+init_table(void)
+{
+ // IEEE-802.3
+ static const uint32_t poly32 = UINT32_C(0xEDB88320);
+
+ // Castagnoli
+ // static const uint32_t poly32 = UINT32_C(0x82F63B78);
+
+ // Koopman
+ // static const uint32_t poly32 = UINT32_C(0xEB31D82E);
+
+ for (size_t s = 0; s < 8; ++s) {
+ for (size_t b = 0; b < 256; ++b) {
+ uint32_t r = s == 0 ? b : lzma_crc32_table[s - 1][b];
+
+ for (size_t i = 0; i < 8; ++i) {
+ if (r & 1)
+ r = (r >> 1) ^ poly32;
+ else
+ r >>= 1;
+ }
+
+ lzma_crc32_table[s][b] = r;
+ }
+ }
+}
+
+ * The prototype of the CRC32 function:
+ * extern uint32_t lzma_crc32(const uint8_t *buf, size_t size, uint32_t crc);
+ */
+
+/*
+ * On some systems, the functions need to be prefixed. The prefix is
+ * usually an underscore.
+ */
+#ifndef __USER_LABEL_PREFIX__
+# define __USER_LABEL_PREFIX__
+#endif
+#define MAKE_SYM_CAT(prefix, sym) prefix ## sym
+#define MAKE_SYM(prefix, sym) MAKE_SYM_CAT(prefix, sym)
+#define LZMA_CRC32 MAKE_SYM(__USER_LABEL_PREFIX__, lzma_crc32)
+#define LZMA_CRC32_TABLE MAKE_SYM(__USER_LABEL_PREFIX__, lzma_crc32_table)
+
+/*
+ * Solaris assembler doesn't have .p2align, and Darwin uses .align
+ * differently than GNU/Linux and Solaris.
+ */
+#if defined(__APPLE__) || defined(__MSDOS__)
+# define ALIGN(pow2, abs) .align pow2
+#else
+# define ALIGN(pow2, abs) .align abs
+#endif
+
+ .text
+ .globl LZMA_CRC32
+
+#if !defined(__APPLE__) && !defined(_WIN32) && !defined(__CYGWIN__) \
+ && !defined(__MSDOS__)
+ .type LZMA_CRC32, @function
+#endif
+
+ ALIGN(4, 16)
+LZMA_CRC32:
+ /*
+ * Register usage:
+ * %eax crc
+ * %esi buf
+ * %edi size or buf + size
+ * %ebx lzma_crc32_table
+ * %ebp Table index
+ * %ecx Temporary
+ * %edx Temporary
+ */
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ pushl %ebp
+ movl 0x14(%esp), %esi /* buf */
+ movl 0x18(%esp), %edi /* size */
+ movl 0x1C(%esp), %eax /* crc */
+
+ /*
+ * Store the address of lzma_crc32_table to %ebx. This is needed to
+ * get position-independent code (PIC).
+ *
+ * The PIC macro is defined by libtool, while __PIC__ is defined
+ * by GCC but only on some systems. Testing for both makes it simpler
+ * to test this code without libtool, and keeps the code working also
+ * when built with libtool but using something else than GCC.
+ *
+ * I understood that libtool may define PIC on Windows even though
+ * the code in Windows DLLs is not PIC in sense that it is in ELF
+ * binaries, so we need a separate check to always use the non-PIC
+ * code on Windows.
+ */
+#if (!defined(PIC) && !defined(__PIC__)) \
+ || (defined(_WIN32) || defined(__CYGWIN__))
+ /* Not PIC */
+ movl $ LZMA_CRC32_TABLE, %ebx
+#elif defined(__APPLE__)
+ /* Mach-O */
+ call .L_get_pc
+.L_pic:
+ leal .L_lzma_crc32_table$non_lazy_ptr-.L_pic(%ebx), %ebx
+ movl (%ebx), %ebx
+#else
+ /* ELF */
+ call .L_get_pc
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+ movl LZMA_CRC32_TABLE@GOT(%ebx), %ebx
+#endif
+
+ /* Complement the initial value. */
+ notl %eax
+
+ ALIGN(4, 16)
+.L_align:
+ /*
+ * Check if there is enough input to use slicing-by-eight.
+ * We need 16 bytes, because the loop pre-reads eight bytes.
+ */
+ cmpl $16, %edi
+ jb .L_rest
+
+ /* Check if we have reached alignment of eight bytes. */
+ testl $7, %esi
+ jz .L_slice
+
+ /* Calculate CRC of the next input byte. */
+ movzbl (%esi), %ebp
+ incl %esi
+ movzbl %al, %ecx
+ xorl %ecx, %ebp
+ shrl $8, %eax
+ xorl (%ebx, %ebp, 4), %eax
+ decl %edi
+ jmp .L_align
+
+ ALIGN(2, 4)
+.L_slice:
+ /*
+ * If we get here, there's at least 16 bytes of aligned input
+ * available. Make %edi multiple of eight bytes. Store the possible
+ * remainder over the "size" variable in the argument stack.
+ */
+ movl %edi, 0x18(%esp)
+ andl $-8, %edi
+ subl %edi, 0x18(%esp)
+
+ /*
+ * Let %edi be buf + size - 8 while running the main loop. This way
+ * we can compare for equality to determine when exit the loop.
+ */
+ addl %esi, %edi
+ subl $8, %edi
+
+ /* Read in the first eight aligned bytes. */
+ xorl (%esi), %eax
+ movl 4(%esi), %ecx
+ movzbl %cl, %ebp
+
+.L_loop:
+ movl 0x0C00(%ebx, %ebp, 4), %edx
+ movzbl %ch, %ebp
+ xorl 0x0800(%ebx, %ebp, 4), %edx
+ shrl $16, %ecx
+ xorl 8(%esi), %edx
+ movzbl %cl, %ebp
+ xorl 0x0400(%ebx, %ebp, 4), %edx
+ movzbl %ch, %ebp
+ xorl (%ebx, %ebp, 4), %edx
+ movzbl %al, %ebp
+
+ /*
+ * Read the next four bytes, for which the CRC is calculated
+ * on the next interation of the loop.
+ */
+ movl 12(%esi), %ecx
+
+ xorl 0x1C00(%ebx, %ebp, 4), %edx
+ movzbl %ah, %ebp
+ shrl $16, %eax
+ xorl 0x1800(%ebx, %ebp, 4), %edx
+ movzbl %ah, %ebp
+ movzbl %al, %eax
+ movl 0x1400(%ebx, %eax, 4), %eax
+ addl $8, %esi
+ xorl %edx, %eax
+ xorl 0x1000(%ebx, %ebp, 4), %eax
+
+ /* Check for end of aligned input. */
+ cmpl %edi, %esi
+ movzbl %cl, %ebp
+ jne .L_loop
+
+ /*
+ * Process the remaining eight bytes, which we have already
+ * copied to %ecx and %edx.
+ */
+ movl 0x0C00(%ebx, %ebp, 4), %edx
+ movzbl %ch, %ebp
+ xorl 0x0800(%ebx, %ebp, 4), %edx
+ shrl $16, %ecx
+ movzbl %cl, %ebp
+ xorl 0x0400(%ebx, %ebp, 4), %edx
+ movzbl %ch, %ebp
+ xorl (%ebx, %ebp, 4), %edx
+ movzbl %al, %ebp
+
+ xorl 0x1C00(%ebx, %ebp, 4), %edx
+ movzbl %ah, %ebp
+ shrl $16, %eax
+ xorl 0x1800(%ebx, %ebp, 4), %edx
+ movzbl %ah, %ebp
+ movzbl %al, %eax
+ movl 0x1400(%ebx, %eax, 4), %eax
+ addl $8, %esi
+ xorl %edx, %eax
+ xorl 0x1000(%ebx, %ebp, 4), %eax
+
+ /* Copy the number of remaining bytes to %edi. */
+ movl 0x18(%esp), %edi
+
+.L_rest:
+ /* Check for end of input. */
+ testl %edi, %edi
+ jz .L_return
+
+ /* Calculate CRC of the next input byte. */
+ movzbl (%esi), %ebp
+ incl %esi
+ movzbl %al, %ecx
+ xorl %ecx, %ebp
+ shrl $8, %eax
+ xorl (%ebx, %ebp, 4), %eax
+ decl %edi
+ jmp .L_rest
+
+.L_return:
+ /* Complement the final value. */
+ notl %eax
+
+ popl %ebp
+ popl %edi
+ popl %esi
+ popl %ebx
+ ret
+
+#if defined(PIC) || defined(__PIC__)
+ ALIGN(4, 16)
+.L_get_pc:
+ movl (%esp), %ebx
+ ret
+#endif
+
+#if defined(__APPLE__) && (defined(PIC) || defined(__PIC__))
+ /* Mach-O PIC */
+ .section __IMPORT,__pointers,non_lazy_symbol_pointers
+.L_lzma_crc32_table$non_lazy_ptr:
+ .indirect_symbol LZMA_CRC32_TABLE
+ .long 0
+
+#elif defined(_WIN32) || defined(__CYGWIN__)
+# ifdef DLL_EXPORT
+ /* This is equivalent of __declspec(dllexport). */
+ .section .drectve
+ .ascii " -export:lzma_crc32"
+# endif
+
+#elif !defined(__MSDOS__)
+ /* ELF */
+ .size LZMA_CRC32, .-LZMA_CRC32
+#endif
+
+/*
+ * This is needed to support non-executable stack. It's ugly to
+ * use __linux__ here, but I don't know a way to detect when
+ * we are using GNU assembler.
+ */
+#if defined(__ELF__) && defined(__linux__)
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/Utilities/cmliblzma/liblzma/check/crc64_fast.c b/Utilities/cmliblzma/liblzma/check/crc64_fast.c
new file mode 100644
index 000000000..1436557af
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/check/crc64_fast.c
@@ -0,0 +1,74 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file crc64.c
+/// \brief CRC64 calculation
+///
+/// Calculate the CRC64 using the slice-by-four algorithm. This is the same
+/// idea that is used in crc32_fast.c, but for CRC64 we use only four tables
+/// instead of eight to avoid increasing CPU cache usage.
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "check.h"
+#include "crc_macros.h"
+
+
+#ifdef WORDS_BIGENDIAN
+# define A1(x) ((x) >> 56)
+#else
+# define A1 A
+#endif
+
+
+// See the comments in crc32_fast.c. They aren't duplicated here.
+extern LZMA_API(uint64_t)
+lzma_crc64(const uint8_t *buf, size_t size, uint64_t crc)
+{
+ crc = ~crc;
+
+#ifdef WORDS_BIGENDIAN
+ crc = bswap64(crc);
+#endif
+
+ if (size > 4) {
+ const uint8_t *limit;
+
+ while ((uintptr_t)(buf) & 3) {
+ crc = lzma_crc64_table[0][*buf++ ^ A1(crc)] ^ S8(crc);
+ --size;
+ }
+
+ limit = buf + (size & ~(size_t)(3));
+ size &= (size_t)(3);
+
+ while (buf < limit) {
+#ifdef WORDS_BIGENDIAN
+ const uint32_t tmp = (crc >> 32)
+ ^ *(const uint32_t *)(buf);
+#else
+ const uint32_t tmp = crc ^ *(const uint32_t *)(buf);
+#endif
+ buf += 4;
+
+ crc = lzma_crc64_table[3][A(tmp)]
+ ^ lzma_crc64_table[2][B(tmp)]
+ ^ S32(crc)
+ ^ lzma_crc64_table[1][C(tmp)]
+ ^ lzma_crc64_table[0][D(tmp)];
+ }
+ }
+
+ while (size-- != 0)
+ crc = lzma_crc64_table[0][*buf++ ^ A1(crc)] ^ S8(crc);
+
+#ifdef WORDS_BIGENDIAN
+ crc = bswap64(crc);
+#endif
+
+ return ~crc;
+}
diff --git a/Utilities/cmliblzma/liblzma/check/crc64_small.c b/Utilities/cmliblzma/liblzma/check/crc64_small.c
new file mode 100644
index 000000000..55d72316b
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/check/crc64_small.c
@@ -0,0 +1,53 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file crc64_small.c
+/// \brief CRC64 calculation (size-optimized)
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "check.h"
+
+
+static uint64_t crc64_table[256];
+
+
+static void
+crc64_init(void)
+{
+ static const uint64_t poly64 = UINT64_C(0xC96C5795D7870F42);
+
+ for (size_t b = 0; b < 256; ++b) {
+ uint64_t r = b;
+ for (size_t i = 0; i < 8; ++i) {
+ if (r & 1)
+ r = (r >> 1) ^ poly64;
+ else
+ r >>= 1;
+ }
+
+ crc64_table[b] = r;
+ }
+
+ return;
+}
+
+
+extern LZMA_API(uint64_t)
+lzma_crc64(const uint8_t *buf, size_t size, uint64_t crc)
+{
+ mythread_once(crc64_init);
+
+ crc = ~crc;
+
+ while (size != 0) {
+ crc = crc64_table[*buf++ ^ (crc & 0xFF)] ^ (crc >> 8);
+ --size;
+ }
+
+ return ~crc;
+}
diff --git a/Utilities/cmliblzma/liblzma/check/crc64_table.c b/Utilities/cmliblzma/liblzma/check/crc64_table.c
new file mode 100644
index 000000000..1fbcd9470
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/check/crc64_table.c
@@ -0,0 +1,19 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file crc64_table.c
+/// \brief Precalculated CRC64 table with correct endianness
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "common.h"
+
+#ifdef WORDS_BIGENDIAN
+# include "crc64_table_be.h"
+#else
+# include "crc64_table_le.h"
+#endif
diff --git a/Utilities/cmliblzma/liblzma/check/crc64_table_be.h b/Utilities/cmliblzma/liblzma/check/crc64_table_be.h
new file mode 100644
index 000000000..ea074f397
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/check/crc64_table_be.h
@@ -0,0 +1,521 @@
+/* This file has been automatically generated by crc64_tablegen.c. */
+
+const uint64_t lzma_crc64_table[4][256] = {
+ {
+ UINT64_C(0x0000000000000000), UINT64_C(0x6F5FA703BE4C2EB3),
+ UINT64_C(0x5BA040A8573684F4), UINT64_C(0x34FFE7ABE97AAA47),
+ UINT64_C(0x335E8FFF84C3D07B), UINT64_C(0x5C0128FC3A8FFEC8),
+ UINT64_C(0x68FECF57D3F5548F), UINT64_C(0x07A168546DB97A3C),
+ UINT64_C(0x66BC1EFF0987A1F7), UINT64_C(0x09E3B9FCB7CB8F44),
+ UINT64_C(0x3D1C5E575EB12503), UINT64_C(0x5243F954E0FD0BB0),
+ UINT64_C(0x55E291008D44718C), UINT64_C(0x3ABD360333085F3F),
+ UINT64_C(0x0E42D1A8DA72F578), UINT64_C(0x611D76AB643EDBCB),
+ UINT64_C(0x4966335138A19B7D), UINT64_C(0x2639945286EDB5CE),
+ UINT64_C(0x12C673F96F971F89), UINT64_C(0x7D99D4FAD1DB313A),
+ UINT64_C(0x7A38BCAEBC624B06), UINT64_C(0x15671BAD022E65B5),
+ UINT64_C(0x2198FC06EB54CFF2), UINT64_C(0x4EC75B055518E141),
+ UINT64_C(0x2FDA2DAE31263A8A), UINT64_C(0x40858AAD8F6A1439),
+ UINT64_C(0x747A6D066610BE7E), UINT64_C(0x1B25CA05D85C90CD),
+ UINT64_C(0x1C84A251B5E5EAF1), UINT64_C(0x73DB05520BA9C442),
+ UINT64_C(0x4724E2F9E2D36E05), UINT64_C(0x287B45FA5C9F40B6),
+ UINT64_C(0x92CC66A2704237FB), UINT64_C(0xFD93C1A1CE0E1948),
+ UINT64_C(0xC96C260A2774B30F), UINT64_C(0xA633810999389DBC),
+ UINT64_C(0xA192E95DF481E780), UINT64_C(0xCECD4E5E4ACDC933),
+ UINT64_C(0xFA32A9F5A3B76374), UINT64_C(0x956D0EF61DFB4DC7),
+ UINT64_C(0xF470785D79C5960C), UINT64_C(0x9B2FDF5EC789B8BF),
+ UINT64_C(0xAFD038F52EF312F8), UINT64_C(0xC08F9FF690BF3C4B),
+ UINT64_C(0xC72EF7A2FD064677), UINT64_C(0xA87150A1434A68C4),
+ UINT64_C(0x9C8EB70AAA30C283), UINT64_C(0xF3D11009147CEC30),
+ UINT64_C(0xDBAA55F348E3AC86), UINT64_C(0xB4F5F2F0F6AF8235),
+ UINT64_C(0x800A155B1FD52872), UINT64_C(0xEF55B258A19906C1),
+ UINT64_C(0xE8F4DA0CCC207CFD), UINT64_C(0x87AB7D0F726C524E),
+ UINT64_C(0xB3549AA49B16F809), UINT64_C(0xDC0B3DA7255AD6BA),
+ UINT64_C(0xBD164B0C41640D71), UINT64_C(0xD249EC0FFF2823C2),
+ UINT64_C(0xE6B60BA416528985), UINT64_C(0x89E9ACA7A81EA736),
+ UINT64_C(0x8E48C4F3C5A7DD0A), UINT64_C(0xE11763F07BEBF3B9),
+ UINT64_C(0xD5E8845B929159FE), UINT64_C(0xBAB723582CDD774D),
+ UINT64_C(0xA187C3EBCA2BB664), UINT64_C(0xCED864E8746798D7),
+ UINT64_C(0xFA2783439D1D3290), UINT64_C(0x9578244023511C23),
+ UINT64_C(0x92D94C144EE8661F), UINT64_C(0xFD86EB17F0A448AC),
+ UINT64_C(0xC9790CBC19DEE2EB), UINT64_C(0xA626ABBFA792CC58),
+ UINT64_C(0xC73BDD14C3AC1793), UINT64_C(0xA8647A177DE03920),
+ UINT64_C(0x9C9B9DBC949A9367), UINT64_C(0xF3C43ABF2AD6BDD4),
+ UINT64_C(0xF46552EB476FC7E8), UINT64_C(0x9B3AF5E8F923E95B),
+ UINT64_C(0xAFC512431059431C), UINT64_C(0xC09AB540AE156DAF),
+ UINT64_C(0xE8E1F0BAF28A2D19), UINT64_C(0x87BE57B94CC603AA),
+ UINT64_C(0xB341B012A5BCA9ED), UINT64_C(0xDC1E17111BF0875E),
+ UINT64_C(0xDBBF7F457649FD62), UINT64_C(0xB4E0D846C805D3D1),
+ UINT64_C(0x801F3FED217F7996), UINT64_C(0xEF4098EE9F335725),
+ UINT64_C(0x8E5DEE45FB0D8CEE), UINT64_C(0xE10249464541A25D),
+ UINT64_C(0xD5FDAEEDAC3B081A), UINT64_C(0xBAA209EE127726A9),
+ UINT64_C(0xBD0361BA7FCE5C95), UINT64_C(0xD25CC6B9C1827226),
+ UINT64_C(0xE6A3211228F8D861), UINT64_C(0x89FC861196B4F6D2),
+ UINT64_C(0x334BA549BA69819F), UINT64_C(0x5C14024A0425AF2C),
+ UINT64_C(0x68EBE5E1ED5F056B), UINT64_C(0x07B442E253132BD8),
+ UINT64_C(0x00152AB63EAA51E4), UINT64_C(0x6F4A8DB580E67F57),
+ UINT64_C(0x5BB56A1E699CD510), UINT64_C(0x34EACD1DD7D0FBA3),
+ UINT64_C(0x55F7BBB6B3EE2068), UINT64_C(0x3AA81CB50DA20EDB),
+ UINT64_C(0x0E57FB1EE4D8A49C), UINT64_C(0x61085C1D5A948A2F),
+ UINT64_C(0x66A93449372DF013), UINT64_C(0x09F6934A8961DEA0),
+ UINT64_C(0x3D0974E1601B74E7), UINT64_C(0x5256D3E2DE575A54),
+ UINT64_C(0x7A2D961882C81AE2), UINT64_C(0x1572311B3C843451),
+ UINT64_C(0x218DD6B0D5FE9E16), UINT64_C(0x4ED271B36BB2B0A5),
+ UINT64_C(0x497319E7060BCA99), UINT64_C(0x262CBEE4B847E42A),
+ UINT64_C(0x12D3594F513D4E6D), UINT64_C(0x7D8CFE4CEF7160DE),
+ UINT64_C(0x1C9188E78B4FBB15), UINT64_C(0x73CE2FE4350395A6),
+ UINT64_C(0x4731C84FDC793FE1), UINT64_C(0x286E6F4C62351152),
+ UINT64_C(0x2FCF07180F8C6B6E), UINT64_C(0x4090A01BB1C045DD),
+ UINT64_C(0x746F47B058BAEF9A), UINT64_C(0x1B30E0B3E6F6C129),
+ UINT64_C(0x420F87D795576CC9), UINT64_C(0x2D5020D42B1B427A),
+ UINT64_C(0x19AFC77FC261E83D), UINT64_C(0x76F0607C7C2DC68E),
+ UINT64_C(0x715108281194BCB2), UINT64_C(0x1E0EAF2BAFD89201),
+ UINT64_C(0x2AF1488046A23846), UINT64_C(0x45AEEF83F8EE16F5),
+ UINT64_C(0x24B399289CD0CD3E), UINT64_C(0x4BEC3E2B229CE38D),
+ UINT64_C(0x7F13D980CBE649CA), UINT64_C(0x104C7E8375AA6779),
+ UINT64_C(0x17ED16D718131D45), UINT64_C(0x78B2B1D4A65F33F6),
+ UINT64_C(0x4C4D567F4F2599B1), UINT64_C(0x2312F17CF169B702),
+ UINT64_C(0x0B69B486ADF6F7B4), UINT64_C(0x6436138513BAD907),
+ UINT64_C(0x50C9F42EFAC07340), UINT64_C(0x3F96532D448C5DF3),
+ UINT64_C(0x38373B79293527CF), UINT64_C(0x57689C7A9779097C),
+ UINT64_C(0x63977BD17E03A33B), UINT64_C(0x0CC8DCD2C04F8D88),
+ UINT64_C(0x6DD5AA79A4715643), UINT64_C(0x028A0D7A1A3D78F0),
+ UINT64_C(0x3675EAD1F347D2B7), UINT64_C(0x592A4DD24D0BFC04),
+ UINT64_C(0x5E8B258620B28638), UINT64_C(0x31D482859EFEA88B),
+ UINT64_C(0x052B652E778402CC), UINT64_C(0x6A74C22DC9C82C7F),
+ UINT64_C(0xD0C3E175E5155B32), UINT64_C(0xBF9C46765B597581),
+ UINT64_C(0x8B63A1DDB223DFC6), UINT64_C(0xE43C06DE0C6FF175),
+ UINT64_C(0xE39D6E8A61D68B49), UINT64_C(0x8CC2C989DF9AA5FA),
+ UINT64_C(0xB83D2E2236E00FBD), UINT64_C(0xD762892188AC210E),
+ UINT64_C(0xB67FFF8AEC92FAC5), UINT64_C(0xD920588952DED476),
+ UINT64_C(0xEDDFBF22BBA47E31), UINT64_C(0x8280182105E85082),
+ UINT64_C(0x8521707568512ABE), UINT64_C(0xEA7ED776D61D040D),
+ UINT64_C(0xDE8130DD3F67AE4A), UINT64_C(0xB1DE97DE812B80F9),
+ UINT64_C(0x99A5D224DDB4C04F), UINT64_C(0xF6FA752763F8EEFC),
+ UINT64_C(0xC205928C8A8244BB), UINT64_C(0xAD5A358F34CE6A08),
+ UINT64_C(0xAAFB5DDB59771034), UINT64_C(0xC5A4FAD8E73B3E87),
+ UINT64_C(0xF15B1D730E4194C0), UINT64_C(0x9E04BA70B00DBA73),
+ UINT64_C(0xFF19CCDBD43361B8), UINT64_C(0x90466BD86A7F4F0B),
+ UINT64_C(0xA4B98C738305E54C), UINT64_C(0xCBE62B703D49CBFF),
+ UINT64_C(0xCC47432450F0B1C3), UINT64_C(0xA318E427EEBC9F70),
+ UINT64_C(0x97E7038C07C63537), UINT64_C(0xF8B8A48FB98A1B84),
+ UINT64_C(0xE388443C5F7CDAAD), UINT64_C(0x8CD7E33FE130F41E),
+ UINT64_C(0xB8280494084A5E59), UINT64_C(0xD777A397B60670EA),
+ UINT64_C(0xD0D6CBC3DBBF0AD6), UINT64_C(0xBF896CC065F32465),
+ UINT64_C(0x8B768B6B8C898E22), UINT64_C(0xE4292C6832C5A091),
+ UINT64_C(0x85345AC356FB7B5A), UINT64_C(0xEA6BFDC0E8B755E9),
+ UINT64_C(0xDE941A6B01CDFFAE), UINT64_C(0xB1CBBD68BF81D11D),
+ UINT64_C(0xB66AD53CD238AB21), UINT64_C(0xD935723F6C748592),
+ UINT64_C(0xEDCA9594850E2FD5), UINT64_C(0x829532973B420166),
+ UINT64_C(0xAAEE776D67DD41D0), UINT64_C(0xC5B1D06ED9916F63),
+ UINT64_C(0xF14E37C530EBC524), UINT64_C(0x9E1190C68EA7EB97),
+ UINT64_C(0x99B0F892E31E91AB), UINT64_C(0xF6EF5F915D52BF18),
+ UINT64_C(0xC210B83AB428155F), UINT64_C(0xAD4F1F390A643BEC),
+ UINT64_C(0xCC5269926E5AE027), UINT64_C(0xA30DCE91D016CE94),
+ UINT64_C(0x97F2293A396C64D3), UINT64_C(0xF8AD8E3987204A60),
+ UINT64_C(0xFF0CE66DEA99305C), UINT64_C(0x9053416E54D51EEF),
+ UINT64_C(0xA4ACA6C5BDAFB4A8), UINT64_C(0xCBF301C603E39A1B),
+ UINT64_C(0x7144229E2F3EED56), UINT64_C(0x1E1B859D9172C3E5),
+ UINT64_C(0x2AE46236780869A2), UINT64_C(0x45BBC535C6444711),
+ UINT64_C(0x421AAD61ABFD3D2D), UINT64_C(0x2D450A6215B1139E),
+ UINT64_C(0x19BAEDC9FCCBB9D9), UINT64_C(0x76E54ACA4287976A),
+ UINT64_C(0x17F83C6126B94CA1), UINT64_C(0x78A79B6298F56212),
+ UINT64_C(0x4C587CC9718FC855), UINT64_C(0x2307DBCACFC3E6E6),
+ UINT64_C(0x24A6B39EA27A9CDA), UINT64_C(0x4BF9149D1C36B269),
+ UINT64_C(0x7F06F336F54C182E), UINT64_C(0x105954354B00369D),
+ UINT64_C(0x382211CF179F762B), UINT64_C(0x577DB6CCA9D35898),
+ UINT64_C(0x6382516740A9F2DF), UINT64_C(0x0CDDF664FEE5DC6C),
+ UINT64_C(0x0B7C9E30935CA650), UINT64_C(0x642339332D1088E3),
+ UINT64_C(0x50DCDE98C46A22A4), UINT64_C(0x3F83799B7A260C17),
+ UINT64_C(0x5E9E0F301E18D7DC), UINT64_C(0x31C1A833A054F96F),
+ UINT64_C(0x053E4F98492E5328), UINT64_C(0x6A61E89BF7627D9B),
+ UINT64_C(0x6DC080CF9ADB07A7), UINT64_C(0x029F27CC24972914),
+ UINT64_C(0x3660C067CDED8353), UINT64_C(0x593F676473A1ADE0)
+ }, {
+ UINT64_C(0x0000000000000000), UINT64_C(0x0DF1D05C9279E954),
+ UINT64_C(0x1AE2A1B924F3D2A9), UINT64_C(0x171371E5B68A3BFD),
+ UINT64_C(0xB1DA4DDC62497DC1), UINT64_C(0xBC2B9D80F0309495),
+ UINT64_C(0xAB38EC6546BAAF68), UINT64_C(0xA6C93C39D4C3463C),
+ UINT64_C(0xE7AB9517EE3D2210), UINT64_C(0xEA5A454B7C44CB44),
+ UINT64_C(0xFD4934AECACEF0B9), UINT64_C(0xF0B8E4F258B719ED),
+ UINT64_C(0x5671D8CB8C745FD1), UINT64_C(0x5B8008971E0DB685),
+ UINT64_C(0x4C937972A8878D78), UINT64_C(0x4162A92E3AFE642C),
+ UINT64_C(0xCE572B2FDC7B4420), UINT64_C(0xC3A6FB734E02AD74),
+ UINT64_C(0xD4B58A96F8889689), UINT64_C(0xD9445ACA6AF17FDD),
+ UINT64_C(0x7F8D66F3BE3239E1), UINT64_C(0x727CB6AF2C4BD0B5),
+ UINT64_C(0x656FC74A9AC1EB48), UINT64_C(0x689E171608B8021C),
+ UINT64_C(0x29FCBE3832466630), UINT64_C(0x240D6E64A03F8F64),
+ UINT64_C(0x331E1F8116B5B499), UINT64_C(0x3EEFCFDD84CC5DCD),
+ UINT64_C(0x9826F3E4500F1BF1), UINT64_C(0x95D723B8C276F2A5),
+ UINT64_C(0x82C4525D74FCC958), UINT64_C(0x8F358201E685200C),
+ UINT64_C(0x9CAF565EB8F78840), UINT64_C(0x915E86022A8E6114),
+ UINT64_C(0x864DF7E79C045AE9), UINT64_C(0x8BBC27BB0E7DB3BD),
+ UINT64_C(0x2D751B82DABEF581), UINT64_C(0x2084CBDE48C71CD5),
+ UINT64_C(0x3797BA3BFE4D2728), UINT64_C(0x3A666A676C34CE7C),
+ UINT64_C(0x7B04C34956CAAA50), UINT64_C(0x76F51315C4B34304),
+ UINT64_C(0x61E662F0723978F9), UINT64_C(0x6C17B2ACE04091AD),
+ UINT64_C(0xCADE8E953483D791), UINT64_C(0xC72F5EC9A6FA3EC5),
+ UINT64_C(0xD03C2F2C10700538), UINT64_C(0xDDCDFF708209EC6C),
+ UINT64_C(0x52F87D71648CCC60), UINT64_C(0x5F09AD2DF6F52534),
+ UINT64_C(0x481ADCC8407F1EC9), UINT64_C(0x45EB0C94D206F79D),
+ UINT64_C(0xE32230AD06C5B1A1), UINT64_C(0xEED3E0F194BC58F5),
+ UINT64_C(0xF9C0911422366308), UINT64_C(0xF4314148B04F8A5C),
+ UINT64_C(0xB553E8668AB1EE70), UINT64_C(0xB8A2383A18C80724),
+ UINT64_C(0xAFB149DFAE423CD9), UINT64_C(0xA24099833C3BD58D),
+ UINT64_C(0x0489A5BAE8F893B1), UINT64_C(0x097875E67A817AE5),
+ UINT64_C(0x1E6B0403CC0B4118), UINT64_C(0x139AD45F5E72A84C),
+ UINT64_C(0x385FADBC70EF1181), UINT64_C(0x35AE7DE0E296F8D5),
+ UINT64_C(0x22BD0C05541CC328), UINT64_C(0x2F4CDC59C6652A7C),
+ UINT64_C(0x8985E06012A66C40), UINT64_C(0x8474303C80DF8514),
+ UINT64_C(0x936741D93655BEE9), UINT64_C(0x9E969185A42C57BD),
+ UINT64_C(0xDFF438AB9ED23391), UINT64_C(0xD205E8F70CABDAC5),
+ UINT64_C(0xC5169912BA21E138), UINT64_C(0xC8E7494E2858086C),
+ UINT64_C(0x6E2E7577FC9B4E50), UINT64_C(0x63DFA52B6EE2A704),
+ UINT64_C(0x74CCD4CED8689CF9), UINT64_C(0x793D04924A1175AD),
+ UINT64_C(0xF6088693AC9455A1), UINT64_C(0xFBF956CF3EEDBCF5),
+ UINT64_C(0xECEA272A88678708), UINT64_C(0xE11BF7761A1E6E5C),
+ UINT64_C(0x47D2CB4FCEDD2860), UINT64_C(0x4A231B135CA4C134),
+ UINT64_C(0x5D306AF6EA2EFAC9), UINT64_C(0x50C1BAAA7857139D),
+ UINT64_C(0x11A3138442A977B1), UINT64_C(0x1C52C3D8D0D09EE5),
+ UINT64_C(0x0B41B23D665AA518), UINT64_C(0x06B06261F4234C4C),
+ UINT64_C(0xA0795E5820E00A70), UINT64_C(0xAD888E04B299E324),
+ UINT64_C(0xBA9BFFE10413D8D9), UINT64_C(0xB76A2FBD966A318D),
+ UINT64_C(0xA4F0FBE2C81899C1), UINT64_C(0xA9012BBE5A617095),
+ UINT64_C(0xBE125A5BECEB4B68), UINT64_C(0xB3E38A077E92A23C),
+ UINT64_C(0x152AB63EAA51E400), UINT64_C(0x18DB666238280D54),
+ UINT64_C(0x0FC817878EA236A9), UINT64_C(0x0239C7DB1CDBDFFD),
+ UINT64_C(0x435B6EF52625BBD1), UINT64_C(0x4EAABEA9B45C5285),
+ UINT64_C(0x59B9CF4C02D66978), UINT64_C(0x54481F1090AF802C),
+ UINT64_C(0xF2812329446CC610), UINT64_C(0xFF70F375D6152F44),
+ UINT64_C(0xE8638290609F14B9), UINT64_C(0xE59252CCF2E6FDED),
+ UINT64_C(0x6AA7D0CD1463DDE1), UINT64_C(0x67560091861A34B5),
+ UINT64_C(0x7045717430900F48), UINT64_C(0x7DB4A128A2E9E61C),
+ UINT64_C(0xDB7D9D11762AA020), UINT64_C(0xD68C4D4DE4534974),
+ UINT64_C(0xC19F3CA852D97289), UINT64_C(0xCC6EECF4C0A09BDD),
+ UINT64_C(0x8D0C45DAFA5EFFF1), UINT64_C(0x80FD9586682716A5),
+ UINT64_C(0x97EEE463DEAD2D58), UINT64_C(0x9A1F343F4CD4C40C),
+ UINT64_C(0x3CD6080698178230), UINT64_C(0x3127D85A0A6E6B64),
+ UINT64_C(0x2634A9BFBCE45099), UINT64_C(0x2BC579E32E9DB9CD),
+ UINT64_C(0xF5A054D6CA71FB90), UINT64_C(0xF851848A580812C4),
+ UINT64_C(0xEF42F56FEE822939), UINT64_C(0xE2B325337CFBC06D),
+ UINT64_C(0x447A190AA8388651), UINT64_C(0x498BC9563A416F05),
+ UINT64_C(0x5E98B8B38CCB54F8), UINT64_C(0x536968EF1EB2BDAC),
+ UINT64_C(0x120BC1C1244CD980), UINT64_C(0x1FFA119DB63530D4),
+ UINT64_C(0x08E9607800BF0B29), UINT64_C(0x0518B02492C6E27D),
+ UINT64_C(0xA3D18C1D4605A441), UINT64_C(0xAE205C41D47C4D15),
+ UINT64_C(0xB9332DA462F676E8), UINT64_C(0xB4C2FDF8F08F9FBC),
+ UINT64_C(0x3BF77FF9160ABFB0), UINT64_C(0x3606AFA5847356E4),
+ UINT64_C(0x2115DE4032F96D19), UINT64_C(0x2CE40E1CA080844D),
+ UINT64_C(0x8A2D32257443C271), UINT64_C(0x87DCE279E63A2B25),
+ UINT64_C(0x90CF939C50B010D8), UINT64_C(0x9D3E43C0C2C9F98C),
+ UINT64_C(0xDC5CEAEEF8379DA0), UINT64_C(0xD1AD3AB26A4E74F4),
+ UINT64_C(0xC6BE4B57DCC44F09), UINT64_C(0xCB4F9B0B4EBDA65D),
+ UINT64_C(0x6D86A7329A7EE061), UINT64_C(0x6077776E08070935),
+ UINT64_C(0x7764068BBE8D32C8), UINT64_C(0x7A95D6D72CF4DB9C),
+ UINT64_C(0x690F0288728673D0), UINT64_C(0x64FED2D4E0FF9A84),
+ UINT64_C(0x73EDA3315675A179), UINT64_C(0x7E1C736DC40C482D),
+ UINT64_C(0xD8D54F5410CF0E11), UINT64_C(0xD5249F0882B6E745),
+ UINT64_C(0xC237EEED343CDCB8), UINT64_C(0xCFC63EB1A64535EC),
+ UINT64_C(0x8EA4979F9CBB51C0), UINT64_C(0x835547C30EC2B894),
+ UINT64_C(0x94463626B8488369), UINT64_C(0x99B7E67A2A316A3D),
+ UINT64_C(0x3F7EDA43FEF22C01), UINT64_C(0x328F0A1F6C8BC555),
+ UINT64_C(0x259C7BFADA01FEA8), UINT64_C(0x286DABA6487817FC),
+ UINT64_C(0xA75829A7AEFD37F0), UINT64_C(0xAAA9F9FB3C84DEA4),
+ UINT64_C(0xBDBA881E8A0EE559), UINT64_C(0xB04B584218770C0D),
+ UINT64_C(0x1682647BCCB44A31), UINT64_C(0x1B73B4275ECDA365),
+ UINT64_C(0x0C60C5C2E8479898), UINT64_C(0x0191159E7A3E71CC),
+ UINT64_C(0x40F3BCB040C015E0), UINT64_C(0x4D026CECD2B9FCB4),
+ UINT64_C(0x5A111D096433C749), UINT64_C(0x57E0CD55F64A2E1D),
+ UINT64_C(0xF129F16C22896821), UINT64_C(0xFCD82130B0F08175),
+ UINT64_C(0xEBCB50D5067ABA88), UINT64_C(0xE63A8089940353DC),
+ UINT64_C(0xCDFFF96ABA9EEA11), UINT64_C(0xC00E293628E70345),
+ UINT64_C(0xD71D58D39E6D38B8), UINT64_C(0xDAEC888F0C14D1EC),
+ UINT64_C(0x7C25B4B6D8D797D0), UINT64_C(0x71D464EA4AAE7E84),
+ UINT64_C(0x66C7150FFC244579), UINT64_C(0x6B36C5536E5DAC2D),
+ UINT64_C(0x2A546C7D54A3C801), UINT64_C(0x27A5BC21C6DA2155),
+ UINT64_C(0x30B6CDC470501AA8), UINT64_C(0x3D471D98E229F3FC),
+ UINT64_C(0x9B8E21A136EAB5C0), UINT64_C(0x967FF1FDA4935C94),
+ UINT64_C(0x816C801812196769), UINT64_C(0x8C9D504480608E3D),
+ UINT64_C(0x03A8D24566E5AE31), UINT64_C(0x0E590219F49C4765),
+ UINT64_C(0x194A73FC42167C98), UINT64_C(0x14BBA3A0D06F95CC),
+ UINT64_C(0xB2729F9904ACD3F0), UINT64_C(0xBF834FC596D53AA4),
+ UINT64_C(0xA8903E20205F0159), UINT64_C(0xA561EE7CB226E80D),
+ UINT64_C(0xE403475288D88C21), UINT64_C(0xE9F2970E1AA16575),
+ UINT64_C(0xFEE1E6EBAC2B5E88), UINT64_C(0xF31036B73E52B7DC),
+ UINT64_C(0x55D90A8EEA91F1E0), UINT64_C(0x5828DAD278E818B4),
+ UINT64_C(0x4F3BAB37CE622349), UINT64_C(0x42CA7B6B5C1BCA1D),
+ UINT64_C(0x5150AF3402696251), UINT64_C(0x5CA17F6890108B05),
+ UINT64_C(0x4BB20E8D269AB0F8), UINT64_C(0x4643DED1B4E359AC),
+ UINT64_C(0xE08AE2E860201F90), UINT64_C(0xED7B32B4F259F6C4),
+ UINT64_C(0xFA68435144D3CD39), UINT64_C(0xF799930DD6AA246D),
+ UINT64_C(0xB6FB3A23EC544041), UINT64_C(0xBB0AEA7F7E2DA915),
+ UINT64_C(0xAC199B9AC8A792E8), UINT64_C(0xA1E84BC65ADE7BBC),
+ UINT64_C(0x072177FF8E1D3D80), UINT64_C(0x0AD0A7A31C64D4D4),
+ UINT64_C(0x1DC3D646AAEEEF29), UINT64_C(0x1032061A3897067D),
+ UINT64_C(0x9F07841BDE122671), UINT64_C(0x92F654474C6BCF25),
+ UINT64_C(0x85E525A2FAE1F4D8), UINT64_C(0x8814F5FE68981D8C),
+ UINT64_C(0x2EDDC9C7BC5B5BB0), UINT64_C(0x232C199B2E22B2E4),
+ UINT64_C(0x343F687E98A88919), UINT64_C(0x39CEB8220AD1604D),
+ UINT64_C(0x78AC110C302F0461), UINT64_C(0x755DC150A256ED35),
+ UINT64_C(0x624EB0B514DCD6C8), UINT64_C(0x6FBF60E986A53F9C),
+ UINT64_C(0xC9765CD0526679A0), UINT64_C(0xC4878C8CC01F90F4),
+ UINT64_C(0xD394FD697695AB09), UINT64_C(0xDE652D35E4EC425D)
+ }, {
+ UINT64_C(0x0000000000000000), UINT64_C(0xCB6D6A914AE10B3F),
+ UINT64_C(0x96DBD42295C2177E), UINT64_C(0x5DB6BEB3DF231C41),
+ UINT64_C(0x2CB7A9452A852FFC), UINT64_C(0xE7DAC3D4606424C3),
+ UINT64_C(0xBA6C7D67BF473882), UINT64_C(0x710117F6F5A633BD),
+ UINT64_C(0xDD705D247FA5876A), UINT64_C(0x161D37B535448C55),
+ UINT64_C(0x4BAB8906EA679014), UINT64_C(0x80C6E397A0869B2B),
+ UINT64_C(0xF1C7F4615520A896), UINT64_C(0x3AAA9EF01FC1A3A9),
+ UINT64_C(0x671C2043C0E2BFE8), UINT64_C(0xAC714AD28A03B4D7),
+ UINT64_C(0xBAE1BA48FE4A0FD5), UINT64_C(0x718CD0D9B4AB04EA),
+ UINT64_C(0x2C3A6E6A6B8818AB), UINT64_C(0xE75704FB21691394),
+ UINT64_C(0x9656130DD4CF2029), UINT64_C(0x5D3B799C9E2E2B16),
+ UINT64_C(0x008DC72F410D3757), UINT64_C(0xCBE0ADBE0BEC3C68),
+ UINT64_C(0x6791E76C81EF88BF), UINT64_C(0xACFC8DFDCB0E8380),
+ UINT64_C(0xF14A334E142D9FC1), UINT64_C(0x3A2759DF5ECC94FE),
+ UINT64_C(0x4B264E29AB6AA743), UINT64_C(0x804B24B8E18BAC7C),
+ UINT64_C(0xDDFD9A0B3EA8B03D), UINT64_C(0x1690F09A7449BB02),
+ UINT64_C(0xF1DD7B3ED73AC638), UINT64_C(0x3AB011AF9DDBCD07),
+ UINT64_C(0x6706AF1C42F8D146), UINT64_C(0xAC6BC58D0819DA79),
+ UINT64_C(0xDD6AD27BFDBFE9C4), UINT64_C(0x1607B8EAB75EE2FB),
+ UINT64_C(0x4BB10659687DFEBA), UINT64_C(0x80DC6CC8229CF585),
+ UINT64_C(0x2CAD261AA89F4152), UINT64_C(0xE7C04C8BE27E4A6D),
+ UINT64_C(0xBA76F2383D5D562C), UINT64_C(0x711B98A977BC5D13),
+ UINT64_C(0x001A8F5F821A6EAE), UINT64_C(0xCB77E5CEC8FB6591),
+ UINT64_C(0x96C15B7D17D879D0), UINT64_C(0x5DAC31EC5D3972EF),
+ UINT64_C(0x4B3CC1762970C9ED), UINT64_C(0x8051ABE76391C2D2),
+ UINT64_C(0xDDE71554BCB2DE93), UINT64_C(0x168A7FC5F653D5AC),
+ UINT64_C(0x678B683303F5E611), UINT64_C(0xACE602A24914ED2E),
+ UINT64_C(0xF150BC119637F16F), UINT64_C(0x3A3DD680DCD6FA50),
+ UINT64_C(0x964C9C5256D54E87), UINT64_C(0x5D21F6C31C3445B8),
+ UINT64_C(0x00974870C31759F9), UINT64_C(0xCBFA22E189F652C6),
+ UINT64_C(0xBAFB35177C50617B), UINT64_C(0x71965F8636B16A44),
+ UINT64_C(0x2C20E135E9927605), UINT64_C(0xE74D8BA4A3737D3A),
+ UINT64_C(0xE2BBF77CAE758C71), UINT64_C(0x29D69DEDE494874E),
+ UINT64_C(0x7460235E3BB79B0F), UINT64_C(0xBF0D49CF71569030),
+ UINT64_C(0xCE0C5E3984F0A38D), UINT64_C(0x056134A8CE11A8B2),
+ UINT64_C(0x58D78A1B1132B4F3), UINT64_C(0x93BAE08A5BD3BFCC),
+ UINT64_C(0x3FCBAA58D1D00B1B), UINT64_C(0xF4A6C0C99B310024),
+ UINT64_C(0xA9107E7A44121C65), UINT64_C(0x627D14EB0EF3175A),
+ UINT64_C(0x137C031DFB5524E7), UINT64_C(0xD811698CB1B42FD8),
+ UINT64_C(0x85A7D73F6E973399), UINT64_C(0x4ECABDAE247638A6),
+ UINT64_C(0x585A4D34503F83A4), UINT64_C(0x933727A51ADE889B),
+ UINT64_C(0xCE819916C5FD94DA), UINT64_C(0x05ECF3878F1C9FE5),
+ UINT64_C(0x74EDE4717ABAAC58), UINT64_C(0xBF808EE0305BA767),
+ UINT64_C(0xE2363053EF78BB26), UINT64_C(0x295B5AC2A599B019),
+ UINT64_C(0x852A10102F9A04CE), UINT64_C(0x4E477A81657B0FF1),
+ UINT64_C(0x13F1C432BA5813B0), UINT64_C(0xD89CAEA3F0B9188F),
+ UINT64_C(0xA99DB955051F2B32), UINT64_C(0x62F0D3C44FFE200D),
+ UINT64_C(0x3F466D7790DD3C4C), UINT64_C(0xF42B07E6DA3C3773),
+ UINT64_C(0x13668C42794F4A49), UINT64_C(0xD80BE6D333AE4176),
+ UINT64_C(0x85BD5860EC8D5D37), UINT64_C(0x4ED032F1A66C5608),
+ UINT64_C(0x3FD1250753CA65B5), UINT64_C(0xF4BC4F96192B6E8A),
+ UINT64_C(0xA90AF125C60872CB), UINT64_C(0x62679BB48CE979F4),
+ UINT64_C(0xCE16D16606EACD23), UINT64_C(0x057BBBF74C0BC61C),
+ UINT64_C(0x58CD05449328DA5D), UINT64_C(0x93A06FD5D9C9D162),
+ UINT64_C(0xE2A178232C6FE2DF), UINT64_C(0x29CC12B2668EE9E0),
+ UINT64_C(0x747AAC01B9ADF5A1), UINT64_C(0xBF17C690F34CFE9E),
+ UINT64_C(0xA987360A8705459C), UINT64_C(0x62EA5C9BCDE44EA3),
+ UINT64_C(0x3F5CE22812C752E2), UINT64_C(0xF43188B9582659DD),
+ UINT64_C(0x85309F4FAD806A60), UINT64_C(0x4E5DF5DEE761615F),
+ UINT64_C(0x13EB4B6D38427D1E), UINT64_C(0xD88621FC72A37621),
+ UINT64_C(0x74F76B2EF8A0C2F6), UINT64_C(0xBF9A01BFB241C9C9),
+ UINT64_C(0xE22CBF0C6D62D588), UINT64_C(0x2941D59D2783DEB7),
+ UINT64_C(0x5840C26BD225ED0A), UINT64_C(0x932DA8FA98C4E635),
+ UINT64_C(0xCE9B164947E7FA74), UINT64_C(0x05F67CD80D06F14B),
+ UINT64_C(0xC477EFF95CEB18E3), UINT64_C(0x0F1A8568160A13DC),
+ UINT64_C(0x52AC3BDBC9290F9D), UINT64_C(0x99C1514A83C804A2),
+ UINT64_C(0xE8C046BC766E371F), UINT64_C(0x23AD2C2D3C8F3C20),
+ UINT64_C(0x7E1B929EE3AC2061), UINT64_C(0xB576F80FA94D2B5E),
+ UINT64_C(0x1907B2DD234E9F89), UINT64_C(0xD26AD84C69AF94B6),
+ UINT64_C(0x8FDC66FFB68C88F7), UINT64_C(0x44B10C6EFC6D83C8),
+ UINT64_C(0x35B01B9809CBB075), UINT64_C(0xFEDD7109432ABB4A),
+ UINT64_C(0xA36BCFBA9C09A70B), UINT64_C(0x6806A52BD6E8AC34),
+ UINT64_C(0x7E9655B1A2A11736), UINT64_C(0xB5FB3F20E8401C09),
+ UINT64_C(0xE84D819337630048), UINT64_C(0x2320EB027D820B77),
+ UINT64_C(0x5221FCF4882438CA), UINT64_C(0x994C9665C2C533F5),
+ UINT64_C(0xC4FA28D61DE62FB4), UINT64_C(0x0F9742475707248B),
+ UINT64_C(0xA3E60895DD04905C), UINT64_C(0x688B620497E59B63),
+ UINT64_C(0x353DDCB748C68722), UINT64_C(0xFE50B62602278C1D),
+ UINT64_C(0x8F51A1D0F781BFA0), UINT64_C(0x443CCB41BD60B49F),
+ UINT64_C(0x198A75F26243A8DE), UINT64_C(0xD2E71F6328A2A3E1),
+ UINT64_C(0x35AA94C78BD1DEDB), UINT64_C(0xFEC7FE56C130D5E4),
+ UINT64_C(0xA37140E51E13C9A5), UINT64_C(0x681C2A7454F2C29A),
+ UINT64_C(0x191D3D82A154F127), UINT64_C(0xD2705713EBB5FA18),
+ UINT64_C(0x8FC6E9A03496E659), UINT64_C(0x44AB83317E77ED66),
+ UINT64_C(0xE8DAC9E3F47459B1), UINT64_C(0x23B7A372BE95528E),
+ UINT64_C(0x7E011DC161B64ECF), UINT64_C(0xB56C77502B5745F0),
+ UINT64_C(0xC46D60A6DEF1764D), UINT64_C(0x0F000A3794107D72),
+ UINT64_C(0x52B6B4844B336133), UINT64_C(0x99DBDE1501D26A0C),
+ UINT64_C(0x8F4B2E8F759BD10E), UINT64_C(0x4426441E3F7ADA31),
+ UINT64_C(0x1990FAADE059C670), UINT64_C(0xD2FD903CAAB8CD4F),
+ UINT64_C(0xA3FC87CA5F1EFEF2), UINT64_C(0x6891ED5B15FFF5CD),
+ UINT64_C(0x352753E8CADCE98C), UINT64_C(0xFE4A3979803DE2B3),
+ UINT64_C(0x523B73AB0A3E5664), UINT64_C(0x9956193A40DF5D5B),
+ UINT64_C(0xC4E0A7899FFC411A), UINT64_C(0x0F8DCD18D51D4A25),
+ UINT64_C(0x7E8CDAEE20BB7998), UINT64_C(0xB5E1B07F6A5A72A7),
+ UINT64_C(0xE8570ECCB5796EE6), UINT64_C(0x233A645DFF9865D9),
+ UINT64_C(0x26CC1885F29E9492), UINT64_C(0xEDA17214B87F9FAD),
+ UINT64_C(0xB017CCA7675C83EC), UINT64_C(0x7B7AA6362DBD88D3),
+ UINT64_C(0x0A7BB1C0D81BBB6E), UINT64_C(0xC116DB5192FAB051),
+ UINT64_C(0x9CA065E24DD9AC10), UINT64_C(0x57CD0F730738A72F),
+ UINT64_C(0xFBBC45A18D3B13F8), UINT64_C(0x30D12F30C7DA18C7),
+ UINT64_C(0x6D67918318F90486), UINT64_C(0xA60AFB1252180FB9),
+ UINT64_C(0xD70BECE4A7BE3C04), UINT64_C(0x1C668675ED5F373B),
+ UINT64_C(0x41D038C6327C2B7A), UINT64_C(0x8ABD5257789D2045),
+ UINT64_C(0x9C2DA2CD0CD49B47), UINT64_C(0x5740C85C46359078),
+ UINT64_C(0x0AF676EF99168C39), UINT64_C(0xC19B1C7ED3F78706),
+ UINT64_C(0xB09A0B882651B4BB), UINT64_C(0x7BF761196CB0BF84),
+ UINT64_C(0x2641DFAAB393A3C5), UINT64_C(0xED2CB53BF972A8FA),
+ UINT64_C(0x415DFFE973711C2D), UINT64_C(0x8A30957839901712),
+ UINT64_C(0xD7862BCBE6B30B53), UINT64_C(0x1CEB415AAC52006C),
+ UINT64_C(0x6DEA56AC59F433D1), UINT64_C(0xA6873C3D131538EE),
+ UINT64_C(0xFB31828ECC3624AF), UINT64_C(0x305CE81F86D72F90),
+ UINT64_C(0xD71163BB25A452AA), UINT64_C(0x1C7C092A6F455995),
+ UINT64_C(0x41CAB799B06645D4), UINT64_C(0x8AA7DD08FA874EEB),
+ UINT64_C(0xFBA6CAFE0F217D56), UINT64_C(0x30CBA06F45C07669),
+ UINT64_C(0x6D7D1EDC9AE36A28), UINT64_C(0xA610744DD0026117),
+ UINT64_C(0x0A613E9F5A01D5C0), UINT64_C(0xC10C540E10E0DEFF),
+ UINT64_C(0x9CBAEABDCFC3C2BE), UINT64_C(0x57D7802C8522C981),
+ UINT64_C(0x26D697DA7084FA3C), UINT64_C(0xEDBBFD4B3A65F103),
+ UINT64_C(0xB00D43F8E546ED42), UINT64_C(0x7B602969AFA7E67D),
+ UINT64_C(0x6DF0D9F3DBEE5D7F), UINT64_C(0xA69DB362910F5640),
+ UINT64_C(0xFB2B0DD14E2C4A01), UINT64_C(0x3046674004CD413E),
+ UINT64_C(0x414770B6F16B7283), UINT64_C(0x8A2A1A27BB8A79BC),
+ UINT64_C(0xD79CA49464A965FD), UINT64_C(0x1CF1CE052E486EC2),
+ UINT64_C(0xB08084D7A44BDA15), UINT64_C(0x7BEDEE46EEAAD12A),
+ UINT64_C(0x265B50F53189CD6B), UINT64_C(0xED363A647B68C654),
+ UINT64_C(0x9C372D928ECEF5E9), UINT64_C(0x575A4703C42FFED6),
+ UINT64_C(0x0AECF9B01B0CE297), UINT64_C(0xC181932151EDE9A8)
+ }, {
+ UINT64_C(0x0000000000000000), UINT64_C(0xDCA12C225E8AEE1D),
+ UINT64_C(0xB8435944BC14DD3B), UINT64_C(0x64E27566E29E3326),
+ UINT64_C(0x7087B2887829BA77), UINT64_C(0xAC269EAA26A3546A),
+ UINT64_C(0xC8C4EBCCC43D674C), UINT64_C(0x1465C7EE9AB78951),
+ UINT64_C(0xE00E6511F15274EF), UINT64_C(0x3CAF4933AFD89AF2),
+ UINT64_C(0x584D3C554D46A9D4), UINT64_C(0x84EC107713CC47C9),
+ UINT64_C(0x9089D799897BCE98), UINT64_C(0x4C28FBBBD7F12085),
+ UINT64_C(0x28CA8EDD356F13A3), UINT64_C(0xF46BA2FF6BE5FDBE),
+ UINT64_C(0x4503C48DC90A304C), UINT64_C(0x99A2E8AF9780DE51),
+ UINT64_C(0xFD409DC9751EED77), UINT64_C(0x21E1B1EB2B94036A),
+ UINT64_C(0x35847605B1238A3B), UINT64_C(0xE9255A27EFA96426),
+ UINT64_C(0x8DC72F410D375700), UINT64_C(0x5166036353BDB91D),
+ UINT64_C(0xA50DA19C385844A3), UINT64_C(0x79AC8DBE66D2AABE),
+ UINT64_C(0x1D4EF8D8844C9998), UINT64_C(0xC1EFD4FADAC67785),
+ UINT64_C(0xD58A13144071FED4), UINT64_C(0x092B3F361EFB10C9),
+ UINT64_C(0x6DC94A50FC6523EF), UINT64_C(0xB1686672A2EFCDF2),
+ UINT64_C(0x8A06881B93156098), UINT64_C(0x56A7A439CD9F8E85),
+ UINT64_C(0x3245D15F2F01BDA3), UINT64_C(0xEEE4FD7D718B53BE),
+ UINT64_C(0xFA813A93EB3CDAEF), UINT64_C(0x262016B1B5B634F2),
+ UINT64_C(0x42C263D7572807D4), UINT64_C(0x9E634FF509A2E9C9),
+ UINT64_C(0x6A08ED0A62471477), UINT64_C(0xB6A9C1283CCDFA6A),
+ UINT64_C(0xD24BB44EDE53C94C), UINT64_C(0x0EEA986C80D92751),
+ UINT64_C(0x1A8F5F821A6EAE00), UINT64_C(0xC62E73A044E4401D),
+ UINT64_C(0xA2CC06C6A67A733B), UINT64_C(0x7E6D2AE4F8F09D26),
+ UINT64_C(0xCF054C965A1F50D4), UINT64_C(0x13A460B40495BEC9),
+ UINT64_C(0x774615D2E60B8DEF), UINT64_C(0xABE739F0B88163F2),
+ UINT64_C(0xBF82FE1E2236EAA3), UINT64_C(0x6323D23C7CBC04BE),
+ UINT64_C(0x07C1A75A9E223798), UINT64_C(0xDB608B78C0A8D985),
+ UINT64_C(0x2F0B2987AB4D243B), UINT64_C(0xF3AA05A5F5C7CA26),
+ UINT64_C(0x974870C31759F900), UINT64_C(0x4BE95CE149D3171D),
+ UINT64_C(0x5F8C9B0FD3649E4C), UINT64_C(0x832DB72D8DEE7051),
+ UINT64_C(0xE7CFC24B6F704377), UINT64_C(0x3B6EEE6931FAAD6A),
+ UINT64_C(0x91131E980D8418A2), UINT64_C(0x4DB232BA530EF6BF),
+ UINT64_C(0x295047DCB190C599), UINT64_C(0xF5F16BFEEF1A2B84),
+ UINT64_C(0xE194AC1075ADA2D5), UINT64_C(0x3D3580322B274CC8),
+ UINT64_C(0x59D7F554C9B97FEE), UINT64_C(0x8576D976973391F3),
+ UINT64_C(0x711D7B89FCD66C4D), UINT64_C(0xADBC57ABA25C8250),
+ UINT64_C(0xC95E22CD40C2B176), UINT64_C(0x15FF0EEF1E485F6B),
+ UINT64_C(0x019AC90184FFD63A), UINT64_C(0xDD3BE523DA753827),
+ UINT64_C(0xB9D9904538EB0B01), UINT64_C(0x6578BC676661E51C),
+ UINT64_C(0xD410DA15C48E28EE), UINT64_C(0x08B1F6379A04C6F3),
+ UINT64_C(0x6C538351789AF5D5), UINT64_C(0xB0F2AF7326101BC8),
+ UINT64_C(0xA497689DBCA79299), UINT64_C(0x783644BFE22D7C84),
+ UINT64_C(0x1CD431D900B34FA2), UINT64_C(0xC0751DFB5E39A1BF),
+ UINT64_C(0x341EBF0435DC5C01), UINT64_C(0xE8BF93266B56B21C),
+ UINT64_C(0x8C5DE64089C8813A), UINT64_C(0x50FCCA62D7426F27),
+ UINT64_C(0x44990D8C4DF5E676), UINT64_C(0x983821AE137F086B),
+ UINT64_C(0xFCDA54C8F1E13B4D), UINT64_C(0x207B78EAAF6BD550),
+ UINT64_C(0x1B1596839E91783A), UINT64_C(0xC7B4BAA1C01B9627),
+ UINT64_C(0xA356CFC72285A501), UINT64_C(0x7FF7E3E57C0F4B1C),
+ UINT64_C(0x6B92240BE6B8C24D), UINT64_C(0xB7330829B8322C50),
+ UINT64_C(0xD3D17D4F5AAC1F76), UINT64_C(0x0F70516D0426F16B),
+ UINT64_C(0xFB1BF3926FC30CD5), UINT64_C(0x27BADFB03149E2C8),
+ UINT64_C(0x4358AAD6D3D7D1EE), UINT64_C(0x9FF986F48D5D3FF3),
+ UINT64_C(0x8B9C411A17EAB6A2), UINT64_C(0x573D6D38496058BF),
+ UINT64_C(0x33DF185EABFE6B99), UINT64_C(0xEF7E347CF5748584),
+ UINT64_C(0x5E16520E579B4876), UINT64_C(0x82B77E2C0911A66B),
+ UINT64_C(0xE6550B4AEB8F954D), UINT64_C(0x3AF42768B5057B50),
+ UINT64_C(0x2E91E0862FB2F201), UINT64_C(0xF230CCA471381C1C),
+ UINT64_C(0x96D2B9C293A62F3A), UINT64_C(0x4A7395E0CD2CC127),
+ UINT64_C(0xBE18371FA6C93C99), UINT64_C(0x62B91B3DF843D284),
+ UINT64_C(0x065B6E5B1ADDE1A2), UINT64_C(0xDAFA427944570FBF),
+ UINT64_C(0xCE9F8597DEE086EE), UINT64_C(0x123EA9B5806A68F3),
+ UINT64_C(0x76DCDCD362F45BD5), UINT64_C(0xAA7DF0F13C7EB5C8),
+ UINT64_C(0xA739329F30A7E9D6), UINT64_C(0x7B981EBD6E2D07CB),
+ UINT64_C(0x1F7A6BDB8CB334ED), UINT64_C(0xC3DB47F9D239DAF0),
+ UINT64_C(0xD7BE8017488E53A1), UINT64_C(0x0B1FAC351604BDBC),
+ UINT64_C(0x6FFDD953F49A8E9A), UINT64_C(0xB35CF571AA106087),
+ UINT64_C(0x4737578EC1F59D39), UINT64_C(0x9B967BAC9F7F7324),
+ UINT64_C(0xFF740ECA7DE14002), UINT64_C(0x23D522E8236BAE1F),
+ UINT64_C(0x37B0E506B9DC274E), UINT64_C(0xEB11C924E756C953),
+ UINT64_C(0x8FF3BC4205C8FA75), UINT64_C(0x535290605B421468),
+ UINT64_C(0xE23AF612F9ADD99A), UINT64_C(0x3E9BDA30A7273787),
+ UINT64_C(0x5A79AF5645B904A1), UINT64_C(0x86D883741B33EABC),
+ UINT64_C(0x92BD449A818463ED), UINT64_C(0x4E1C68B8DF0E8DF0),
+ UINT64_C(0x2AFE1DDE3D90BED6), UINT64_C(0xF65F31FC631A50CB),
+ UINT64_C(0x0234930308FFAD75), UINT64_C(0xDE95BF2156754368),
+ UINT64_C(0xBA77CA47B4EB704E), UINT64_C(0x66D6E665EA619E53),
+ UINT64_C(0x72B3218B70D61702), UINT64_C(0xAE120DA92E5CF91F),
+ UINT64_C(0xCAF078CFCCC2CA39), UINT64_C(0x165154ED92482424),
+ UINT64_C(0x2D3FBA84A3B2894E), UINT64_C(0xF19E96A6FD386753),
+ UINT64_C(0x957CE3C01FA65475), UINT64_C(0x49DDCFE2412CBA68),
+ UINT64_C(0x5DB8080CDB9B3339), UINT64_C(0x8119242E8511DD24),
+ UINT64_C(0xE5FB5148678FEE02), UINT64_C(0x395A7D6A3905001F),
+ UINT64_C(0xCD31DF9552E0FDA1), UINT64_C(0x1190F3B70C6A13BC),
+ UINT64_C(0x757286D1EEF4209A), UINT64_C(0xA9D3AAF3B07ECE87),
+ UINT64_C(0xBDB66D1D2AC947D6), UINT64_C(0x6117413F7443A9CB),
+ UINT64_C(0x05F5345996DD9AED), UINT64_C(0xD954187BC85774F0),
+ UINT64_C(0x683C7E096AB8B902), UINT64_C(0xB49D522B3432571F),
+ UINT64_C(0xD07F274DD6AC6439), UINT64_C(0x0CDE0B6F88268A24),
+ UINT64_C(0x18BBCC8112910375), UINT64_C(0xC41AE0A34C1BED68),
+ UINT64_C(0xA0F895C5AE85DE4E), UINT64_C(0x7C59B9E7F00F3053),
+ UINT64_C(0x88321B189BEACDED), UINT64_C(0x5493373AC56023F0),
+ UINT64_C(0x3071425C27FE10D6), UINT64_C(0xECD06E7E7974FECB),
+ UINT64_C(0xF8B5A990E3C3779A), UINT64_C(0x241485B2BD499987),
+ UINT64_C(0x40F6F0D45FD7AAA1), UINT64_C(0x9C57DCF6015D44BC),
+ UINT64_C(0x362A2C073D23F174), UINT64_C(0xEA8B002563A91F69),
+ UINT64_C(0x8E69754381372C4F), UINT64_C(0x52C85961DFBDC252),
+ UINT64_C(0x46AD9E8F450A4B03), UINT64_C(0x9A0CB2AD1B80A51E),
+ UINT64_C(0xFEEEC7CBF91E9638), UINT64_C(0x224FEBE9A7947825),
+ UINT64_C(0xD6244916CC71859B), UINT64_C(0x0A85653492FB6B86),
+ UINT64_C(0x6E671052706558A0), UINT64_C(0xB2C63C702EEFB6BD),
+ UINT64_C(0xA6A3FB9EB4583FEC), UINT64_C(0x7A02D7BCEAD2D1F1),
+ UINT64_C(0x1EE0A2DA084CE2D7), UINT64_C(0xC2418EF856C60CCA),
+ UINT64_C(0x7329E88AF429C138), UINT64_C(0xAF88C4A8AAA32F25),
+ UINT64_C(0xCB6AB1CE483D1C03), UINT64_C(0x17CB9DEC16B7F21E),
+ UINT64_C(0x03AE5A028C007B4F), UINT64_C(0xDF0F7620D28A9552),
+ UINT64_C(0xBBED03463014A674), UINT64_C(0x674C2F646E9E4869),
+ UINT64_C(0x93278D9B057BB5D7), UINT64_C(0x4F86A1B95BF15BCA),
+ UINT64_C(0x2B64D4DFB96F68EC), UINT64_C(0xF7C5F8FDE7E586F1),
+ UINT64_C(0xE3A03F137D520FA0), UINT64_C(0x3F01133123D8E1BD),
+ UINT64_C(0x5BE36657C146D29B), UINT64_C(0x87424A759FCC3C86),
+ UINT64_C(0xBC2CA41CAE3691EC), UINT64_C(0x608D883EF0BC7FF1),
+ UINT64_C(0x046FFD5812224CD7), UINT64_C(0xD8CED17A4CA8A2CA),
+ UINT64_C(0xCCAB1694D61F2B9B), UINT64_C(0x100A3AB68895C586),
+ UINT64_C(0x74E84FD06A0BF6A0), UINT64_C(0xA84963F2348118BD),
+ UINT64_C(0x5C22C10D5F64E503), UINT64_C(0x8083ED2F01EE0B1E),
+ UINT64_C(0xE4619849E3703838), UINT64_C(0x38C0B46BBDFAD625),
+ UINT64_C(0x2CA57385274D5F74), UINT64_C(0xF0045FA779C7B169),
+ UINT64_C(0x94E62AC19B59824F), UINT64_C(0x484706E3C5D36C52),
+ UINT64_C(0xF92F6091673CA1A0), UINT64_C(0x258E4CB339B64FBD),
+ UINT64_C(0x416C39D5DB287C9B), UINT64_C(0x9DCD15F785A29286),
+ UINT64_C(0x89A8D2191F151BD7), UINT64_C(0x5509FE3B419FF5CA),
+ UINT64_C(0x31EB8B5DA301C6EC), UINT64_C(0xED4AA77FFD8B28F1),
+ UINT64_C(0x19210580966ED54F), UINT64_C(0xC58029A2C8E43B52),
+ UINT64_C(0xA1625CC42A7A0874), UINT64_C(0x7DC370E674F0E669),
+ UINT64_C(0x69A6B708EE476F38), UINT64_C(0xB5079B2AB0CD8125),
+ UINT64_C(0xD1E5EE4C5253B203), UINT64_C(0x0D44C26E0CD95C1E)
+ }
+};
diff --git a/Utilities/cmliblzma/liblzma/check/crc64_table_le.h b/Utilities/cmliblzma/liblzma/check/crc64_table_le.h
new file mode 100644
index 000000000..1196b31e1
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/check/crc64_table_le.h
@@ -0,0 +1,521 @@
+/* This file has been automatically generated by crc64_tablegen.c. */
+
+const uint64_t lzma_crc64_table[4][256] = {
+ {
+ UINT64_C(0x0000000000000000), UINT64_C(0xB32E4CBE03A75F6F),
+ UINT64_C(0xF4843657A840A05B), UINT64_C(0x47AA7AE9ABE7FF34),
+ UINT64_C(0x7BD0C384FF8F5E33), UINT64_C(0xC8FE8F3AFC28015C),
+ UINT64_C(0x8F54F5D357CFFE68), UINT64_C(0x3C7AB96D5468A107),
+ UINT64_C(0xF7A18709FF1EBC66), UINT64_C(0x448FCBB7FCB9E309),
+ UINT64_C(0x0325B15E575E1C3D), UINT64_C(0xB00BFDE054F94352),
+ UINT64_C(0x8C71448D0091E255), UINT64_C(0x3F5F08330336BD3A),
+ UINT64_C(0x78F572DAA8D1420E), UINT64_C(0xCBDB3E64AB761D61),
+ UINT64_C(0x7D9BA13851336649), UINT64_C(0xCEB5ED8652943926),
+ UINT64_C(0x891F976FF973C612), UINT64_C(0x3A31DBD1FAD4997D),
+ UINT64_C(0x064B62BCAEBC387A), UINT64_C(0xB5652E02AD1B6715),
+ UINT64_C(0xF2CF54EB06FC9821), UINT64_C(0x41E11855055BC74E),
+ UINT64_C(0x8A3A2631AE2DDA2F), UINT64_C(0x39146A8FAD8A8540),
+ UINT64_C(0x7EBE1066066D7A74), UINT64_C(0xCD905CD805CA251B),
+ UINT64_C(0xF1EAE5B551A2841C), UINT64_C(0x42C4A90B5205DB73),
+ UINT64_C(0x056ED3E2F9E22447), UINT64_C(0xB6409F5CFA457B28),
+ UINT64_C(0xFB374270A266CC92), UINT64_C(0x48190ECEA1C193FD),
+ UINT64_C(0x0FB374270A266CC9), UINT64_C(0xBC9D3899098133A6),
+ UINT64_C(0x80E781F45DE992A1), UINT64_C(0x33C9CD4A5E4ECDCE),
+ UINT64_C(0x7463B7A3F5A932FA), UINT64_C(0xC74DFB1DF60E6D95),
+ UINT64_C(0x0C96C5795D7870F4), UINT64_C(0xBFB889C75EDF2F9B),
+ UINT64_C(0xF812F32EF538D0AF), UINT64_C(0x4B3CBF90F69F8FC0),
+ UINT64_C(0x774606FDA2F72EC7), UINT64_C(0xC4684A43A15071A8),
+ UINT64_C(0x83C230AA0AB78E9C), UINT64_C(0x30EC7C140910D1F3),
+ UINT64_C(0x86ACE348F355AADB), UINT64_C(0x3582AFF6F0F2F5B4),
+ UINT64_C(0x7228D51F5B150A80), UINT64_C(0xC10699A158B255EF),
+ UINT64_C(0xFD7C20CC0CDAF4E8), UINT64_C(0x4E526C720F7DAB87),
+ UINT64_C(0x09F8169BA49A54B3), UINT64_C(0xBAD65A25A73D0BDC),
+ UINT64_C(0x710D64410C4B16BD), UINT64_C(0xC22328FF0FEC49D2),
+ UINT64_C(0x85895216A40BB6E6), UINT64_C(0x36A71EA8A7ACE989),
+ UINT64_C(0x0ADDA7C5F3C4488E), UINT64_C(0xB9F3EB7BF06317E1),
+ UINT64_C(0xFE5991925B84E8D5), UINT64_C(0x4D77DD2C5823B7BA),
+ UINT64_C(0x64B62BCAEBC387A1), UINT64_C(0xD7986774E864D8CE),
+ UINT64_C(0x90321D9D438327FA), UINT64_C(0x231C512340247895),
+ UINT64_C(0x1F66E84E144CD992), UINT64_C(0xAC48A4F017EB86FD),
+ UINT64_C(0xEBE2DE19BC0C79C9), UINT64_C(0x58CC92A7BFAB26A6),
+ UINT64_C(0x9317ACC314DD3BC7), UINT64_C(0x2039E07D177A64A8),
+ UINT64_C(0x67939A94BC9D9B9C), UINT64_C(0xD4BDD62ABF3AC4F3),
+ UINT64_C(0xE8C76F47EB5265F4), UINT64_C(0x5BE923F9E8F53A9B),
+ UINT64_C(0x1C4359104312C5AF), UINT64_C(0xAF6D15AE40B59AC0),
+ UINT64_C(0x192D8AF2BAF0E1E8), UINT64_C(0xAA03C64CB957BE87),
+ UINT64_C(0xEDA9BCA512B041B3), UINT64_C(0x5E87F01B11171EDC),
+ UINT64_C(0x62FD4976457FBFDB), UINT64_C(0xD1D305C846D8E0B4),
+ UINT64_C(0x96797F21ED3F1F80), UINT64_C(0x2557339FEE9840EF),
+ UINT64_C(0xEE8C0DFB45EE5D8E), UINT64_C(0x5DA24145464902E1),
+ UINT64_C(0x1A083BACEDAEFDD5), UINT64_C(0xA9267712EE09A2BA),
+ UINT64_C(0x955CCE7FBA6103BD), UINT64_C(0x267282C1B9C65CD2),
+ UINT64_C(0x61D8F8281221A3E6), UINT64_C(0xD2F6B4961186FC89),
+ UINT64_C(0x9F8169BA49A54B33), UINT64_C(0x2CAF25044A02145C),
+ UINT64_C(0x6B055FEDE1E5EB68), UINT64_C(0xD82B1353E242B407),
+ UINT64_C(0xE451AA3EB62A1500), UINT64_C(0x577FE680B58D4A6F),
+ UINT64_C(0x10D59C691E6AB55B), UINT64_C(0xA3FBD0D71DCDEA34),
+ UINT64_C(0x6820EEB3B6BBF755), UINT64_C(0xDB0EA20DB51CA83A),
+ UINT64_C(0x9CA4D8E41EFB570E), UINT64_C(0x2F8A945A1D5C0861),
+ UINT64_C(0x13F02D374934A966), UINT64_C(0xA0DE61894A93F609),
+ UINT64_C(0xE7741B60E174093D), UINT64_C(0x545A57DEE2D35652),
+ UINT64_C(0xE21AC88218962D7A), UINT64_C(0x5134843C1B317215),
+ UINT64_C(0x169EFED5B0D68D21), UINT64_C(0xA5B0B26BB371D24E),
+ UINT64_C(0x99CA0B06E7197349), UINT64_C(0x2AE447B8E4BE2C26),
+ UINT64_C(0x6D4E3D514F59D312), UINT64_C(0xDE6071EF4CFE8C7D),
+ UINT64_C(0x15BB4F8BE788911C), UINT64_C(0xA6950335E42FCE73),
+ UINT64_C(0xE13F79DC4FC83147), UINT64_C(0x521135624C6F6E28),
+ UINT64_C(0x6E6B8C0F1807CF2F), UINT64_C(0xDD45C0B11BA09040),
+ UINT64_C(0x9AEFBA58B0476F74), UINT64_C(0x29C1F6E6B3E0301B),
+ UINT64_C(0xC96C5795D7870F42), UINT64_C(0x7A421B2BD420502D),
+ UINT64_C(0x3DE861C27FC7AF19), UINT64_C(0x8EC62D7C7C60F076),
+ UINT64_C(0xB2BC941128085171), UINT64_C(0x0192D8AF2BAF0E1E),
+ UINT64_C(0x4638A2468048F12A), UINT64_C(0xF516EEF883EFAE45),
+ UINT64_C(0x3ECDD09C2899B324), UINT64_C(0x8DE39C222B3EEC4B),
+ UINT64_C(0xCA49E6CB80D9137F), UINT64_C(0x7967AA75837E4C10),
+ UINT64_C(0x451D1318D716ED17), UINT64_C(0xF6335FA6D4B1B278),
+ UINT64_C(0xB199254F7F564D4C), UINT64_C(0x02B769F17CF11223),
+ UINT64_C(0xB4F7F6AD86B4690B), UINT64_C(0x07D9BA1385133664),
+ UINT64_C(0x4073C0FA2EF4C950), UINT64_C(0xF35D8C442D53963F),
+ UINT64_C(0xCF273529793B3738), UINT64_C(0x7C0979977A9C6857),
+ UINT64_C(0x3BA3037ED17B9763), UINT64_C(0x888D4FC0D2DCC80C),
+ UINT64_C(0x435671A479AAD56D), UINT64_C(0xF0783D1A7A0D8A02),
+ UINT64_C(0xB7D247F3D1EA7536), UINT64_C(0x04FC0B4DD24D2A59),
+ UINT64_C(0x3886B22086258B5E), UINT64_C(0x8BA8FE9E8582D431),
+ UINT64_C(0xCC0284772E652B05), UINT64_C(0x7F2CC8C92DC2746A),
+ UINT64_C(0x325B15E575E1C3D0), UINT64_C(0x8175595B76469CBF),
+ UINT64_C(0xC6DF23B2DDA1638B), UINT64_C(0x75F16F0CDE063CE4),
+ UINT64_C(0x498BD6618A6E9DE3), UINT64_C(0xFAA59ADF89C9C28C),
+ UINT64_C(0xBD0FE036222E3DB8), UINT64_C(0x0E21AC88218962D7),
+ UINT64_C(0xC5FA92EC8AFF7FB6), UINT64_C(0x76D4DE52895820D9),
+ UINT64_C(0x317EA4BB22BFDFED), UINT64_C(0x8250E80521188082),
+ UINT64_C(0xBE2A516875702185), UINT64_C(0x0D041DD676D77EEA),
+ UINT64_C(0x4AAE673FDD3081DE), UINT64_C(0xF9802B81DE97DEB1),
+ UINT64_C(0x4FC0B4DD24D2A599), UINT64_C(0xFCEEF8632775FAF6),
+ UINT64_C(0xBB44828A8C9205C2), UINT64_C(0x086ACE348F355AAD),
+ UINT64_C(0x34107759DB5DFBAA), UINT64_C(0x873E3BE7D8FAA4C5),
+ UINT64_C(0xC094410E731D5BF1), UINT64_C(0x73BA0DB070BA049E),
+ UINT64_C(0xB86133D4DBCC19FF), UINT64_C(0x0B4F7F6AD86B4690),
+ UINT64_C(0x4CE50583738CB9A4), UINT64_C(0xFFCB493D702BE6CB),
+ UINT64_C(0xC3B1F050244347CC), UINT64_C(0x709FBCEE27E418A3),
+ UINT64_C(0x3735C6078C03E797), UINT64_C(0x841B8AB98FA4B8F8),
+ UINT64_C(0xADDA7C5F3C4488E3), UINT64_C(0x1EF430E13FE3D78C),
+ UINT64_C(0x595E4A08940428B8), UINT64_C(0xEA7006B697A377D7),
+ UINT64_C(0xD60ABFDBC3CBD6D0), UINT64_C(0x6524F365C06C89BF),
+ UINT64_C(0x228E898C6B8B768B), UINT64_C(0x91A0C532682C29E4),
+ UINT64_C(0x5A7BFB56C35A3485), UINT64_C(0xE955B7E8C0FD6BEA),
+ UINT64_C(0xAEFFCD016B1A94DE), UINT64_C(0x1DD181BF68BDCBB1),
+ UINT64_C(0x21AB38D23CD56AB6), UINT64_C(0x9285746C3F7235D9),
+ UINT64_C(0xD52F0E859495CAED), UINT64_C(0x6601423B97329582),
+ UINT64_C(0xD041DD676D77EEAA), UINT64_C(0x636F91D96ED0B1C5),
+ UINT64_C(0x24C5EB30C5374EF1), UINT64_C(0x97EBA78EC690119E),
+ UINT64_C(0xAB911EE392F8B099), UINT64_C(0x18BF525D915FEFF6),
+ UINT64_C(0x5F1528B43AB810C2), UINT64_C(0xEC3B640A391F4FAD),
+ UINT64_C(0x27E05A6E926952CC), UINT64_C(0x94CE16D091CE0DA3),
+ UINT64_C(0xD3646C393A29F297), UINT64_C(0x604A2087398EADF8),
+ UINT64_C(0x5C3099EA6DE60CFF), UINT64_C(0xEF1ED5546E415390),
+ UINT64_C(0xA8B4AFBDC5A6ACA4), UINT64_C(0x1B9AE303C601F3CB),
+ UINT64_C(0x56ED3E2F9E224471), UINT64_C(0xE5C372919D851B1E),
+ UINT64_C(0xA26908783662E42A), UINT64_C(0x114744C635C5BB45),
+ UINT64_C(0x2D3DFDAB61AD1A42), UINT64_C(0x9E13B115620A452D),
+ UINT64_C(0xD9B9CBFCC9EDBA19), UINT64_C(0x6A978742CA4AE576),
+ UINT64_C(0xA14CB926613CF817), UINT64_C(0x1262F598629BA778),
+ UINT64_C(0x55C88F71C97C584C), UINT64_C(0xE6E6C3CFCADB0723),
+ UINT64_C(0xDA9C7AA29EB3A624), UINT64_C(0x69B2361C9D14F94B),
+ UINT64_C(0x2E184CF536F3067F), UINT64_C(0x9D36004B35545910),
+ UINT64_C(0x2B769F17CF112238), UINT64_C(0x9858D3A9CCB67D57),
+ UINT64_C(0xDFF2A94067518263), UINT64_C(0x6CDCE5FE64F6DD0C),
+ UINT64_C(0x50A65C93309E7C0B), UINT64_C(0xE388102D33392364),
+ UINT64_C(0xA4226AC498DEDC50), UINT64_C(0x170C267A9B79833F),
+ UINT64_C(0xDCD7181E300F9E5E), UINT64_C(0x6FF954A033A8C131),
+ UINT64_C(0x28532E49984F3E05), UINT64_C(0x9B7D62F79BE8616A),
+ UINT64_C(0xA707DB9ACF80C06D), UINT64_C(0x14299724CC279F02),
+ UINT64_C(0x5383EDCD67C06036), UINT64_C(0xE0ADA17364673F59)
+ }, {
+ UINT64_C(0x0000000000000000), UINT64_C(0x54E979925CD0F10D),
+ UINT64_C(0xA9D2F324B9A1E21A), UINT64_C(0xFD3B8AB6E5711317),
+ UINT64_C(0xC17D4962DC4DDAB1), UINT64_C(0x959430F0809D2BBC),
+ UINT64_C(0x68AFBA4665EC38AB), UINT64_C(0x3C46C3D4393CC9A6),
+ UINT64_C(0x10223DEE1795ABE7), UINT64_C(0x44CB447C4B455AEA),
+ UINT64_C(0xB9F0CECAAE3449FD), UINT64_C(0xED19B758F2E4B8F0),
+ UINT64_C(0xD15F748CCBD87156), UINT64_C(0x85B60D1E9708805B),
+ UINT64_C(0x788D87A87279934C), UINT64_C(0x2C64FE3A2EA96241),
+ UINT64_C(0x20447BDC2F2B57CE), UINT64_C(0x74AD024E73FBA6C3),
+ UINT64_C(0x899688F8968AB5D4), UINT64_C(0xDD7FF16ACA5A44D9),
+ UINT64_C(0xE13932BEF3668D7F), UINT64_C(0xB5D04B2CAFB67C72),
+ UINT64_C(0x48EBC19A4AC76F65), UINT64_C(0x1C02B80816179E68),
+ UINT64_C(0x3066463238BEFC29), UINT64_C(0x648F3FA0646E0D24),
+ UINT64_C(0x99B4B516811F1E33), UINT64_C(0xCD5DCC84DDCFEF3E),
+ UINT64_C(0xF11B0F50E4F32698), UINT64_C(0xA5F276C2B823D795),
+ UINT64_C(0x58C9FC745D52C482), UINT64_C(0x0C2085E60182358F),
+ UINT64_C(0x4088F7B85E56AF9C), UINT64_C(0x14618E2A02865E91),
+ UINT64_C(0xE95A049CE7F74D86), UINT64_C(0xBDB37D0EBB27BC8B),
+ UINT64_C(0x81F5BEDA821B752D), UINT64_C(0xD51CC748DECB8420),
+ UINT64_C(0x28274DFE3BBA9737), UINT64_C(0x7CCE346C676A663A),
+ UINT64_C(0x50AACA5649C3047B), UINT64_C(0x0443B3C41513F576),
+ UINT64_C(0xF9783972F062E661), UINT64_C(0xAD9140E0ACB2176C),
+ UINT64_C(0x91D78334958EDECA), UINT64_C(0xC53EFAA6C95E2FC7),
+ UINT64_C(0x380570102C2F3CD0), UINT64_C(0x6CEC098270FFCDDD),
+ UINT64_C(0x60CC8C64717DF852), UINT64_C(0x3425F5F62DAD095F),
+ UINT64_C(0xC91E7F40C8DC1A48), UINT64_C(0x9DF706D2940CEB45),
+ UINT64_C(0xA1B1C506AD3022E3), UINT64_C(0xF558BC94F1E0D3EE),
+ UINT64_C(0x086336221491C0F9), UINT64_C(0x5C8A4FB0484131F4),
+ UINT64_C(0x70EEB18A66E853B5), UINT64_C(0x2407C8183A38A2B8),
+ UINT64_C(0xD93C42AEDF49B1AF), UINT64_C(0x8DD53B3C839940A2),
+ UINT64_C(0xB193F8E8BAA58904), UINT64_C(0xE57A817AE6757809),
+ UINT64_C(0x18410BCC03046B1E), UINT64_C(0x4CA8725E5FD49A13),
+ UINT64_C(0x8111EF70BCAD5F38), UINT64_C(0xD5F896E2E07DAE35),
+ UINT64_C(0x28C31C54050CBD22), UINT64_C(0x7C2A65C659DC4C2F),
+ UINT64_C(0x406CA61260E08589), UINT64_C(0x1485DF803C307484),
+ UINT64_C(0xE9BE5536D9416793), UINT64_C(0xBD572CA48591969E),
+ UINT64_C(0x9133D29EAB38F4DF), UINT64_C(0xC5DAAB0CF7E805D2),
+ UINT64_C(0x38E121BA129916C5), UINT64_C(0x6C0858284E49E7C8),
+ UINT64_C(0x504E9BFC77752E6E), UINT64_C(0x04A7E26E2BA5DF63),
+ UINT64_C(0xF99C68D8CED4CC74), UINT64_C(0xAD75114A92043D79),
+ UINT64_C(0xA15594AC938608F6), UINT64_C(0xF5BCED3ECF56F9FB),
+ UINT64_C(0x088767882A27EAEC), UINT64_C(0x5C6E1E1A76F71BE1),
+ UINT64_C(0x6028DDCE4FCBD247), UINT64_C(0x34C1A45C131B234A),
+ UINT64_C(0xC9FA2EEAF66A305D), UINT64_C(0x9D135778AABAC150),
+ UINT64_C(0xB177A9428413A311), UINT64_C(0xE59ED0D0D8C3521C),
+ UINT64_C(0x18A55A663DB2410B), UINT64_C(0x4C4C23F46162B006),
+ UINT64_C(0x700AE020585E79A0), UINT64_C(0x24E399B2048E88AD),
+ UINT64_C(0xD9D81304E1FF9BBA), UINT64_C(0x8D316A96BD2F6AB7),
+ UINT64_C(0xC19918C8E2FBF0A4), UINT64_C(0x9570615ABE2B01A9),
+ UINT64_C(0x684BEBEC5B5A12BE), UINT64_C(0x3CA2927E078AE3B3),
+ UINT64_C(0x00E451AA3EB62A15), UINT64_C(0x540D28386266DB18),
+ UINT64_C(0xA936A28E8717C80F), UINT64_C(0xFDDFDB1CDBC73902),
+ UINT64_C(0xD1BB2526F56E5B43), UINT64_C(0x85525CB4A9BEAA4E),
+ UINT64_C(0x7869D6024CCFB959), UINT64_C(0x2C80AF90101F4854),
+ UINT64_C(0x10C66C44292381F2), UINT64_C(0x442F15D675F370FF),
+ UINT64_C(0xB9149F60908263E8), UINT64_C(0xEDFDE6F2CC5292E5),
+ UINT64_C(0xE1DD6314CDD0A76A), UINT64_C(0xB5341A8691005667),
+ UINT64_C(0x480F903074714570), UINT64_C(0x1CE6E9A228A1B47D),
+ UINT64_C(0x20A02A76119D7DDB), UINT64_C(0x744953E44D4D8CD6),
+ UINT64_C(0x8972D952A83C9FC1), UINT64_C(0xDD9BA0C0F4EC6ECC),
+ UINT64_C(0xF1FF5EFADA450C8D), UINT64_C(0xA51627688695FD80),
+ UINT64_C(0x582DADDE63E4EE97), UINT64_C(0x0CC4D44C3F341F9A),
+ UINT64_C(0x308217980608D63C), UINT64_C(0x646B6E0A5AD82731),
+ UINT64_C(0x9950E4BCBFA93426), UINT64_C(0xCDB99D2EE379C52B),
+ UINT64_C(0x90FB71CAD654A0F5), UINT64_C(0xC41208588A8451F8),
+ UINT64_C(0x392982EE6FF542EF), UINT64_C(0x6DC0FB7C3325B3E2),
+ UINT64_C(0x518638A80A197A44), UINT64_C(0x056F413A56C98B49),
+ UINT64_C(0xF854CB8CB3B8985E), UINT64_C(0xACBDB21EEF686953),
+ UINT64_C(0x80D94C24C1C10B12), UINT64_C(0xD43035B69D11FA1F),
+ UINT64_C(0x290BBF007860E908), UINT64_C(0x7DE2C69224B01805),
+ UINT64_C(0x41A405461D8CD1A3), UINT64_C(0x154D7CD4415C20AE),
+ UINT64_C(0xE876F662A42D33B9), UINT64_C(0xBC9F8FF0F8FDC2B4),
+ UINT64_C(0xB0BF0A16F97FF73B), UINT64_C(0xE4567384A5AF0636),
+ UINT64_C(0x196DF93240DE1521), UINT64_C(0x4D8480A01C0EE42C),
+ UINT64_C(0x71C2437425322D8A), UINT64_C(0x252B3AE679E2DC87),
+ UINT64_C(0xD810B0509C93CF90), UINT64_C(0x8CF9C9C2C0433E9D),
+ UINT64_C(0xA09D37F8EEEA5CDC), UINT64_C(0xF4744E6AB23AADD1),
+ UINT64_C(0x094FC4DC574BBEC6), UINT64_C(0x5DA6BD4E0B9B4FCB),
+ UINT64_C(0x61E07E9A32A7866D), UINT64_C(0x350907086E777760),
+ UINT64_C(0xC8328DBE8B066477), UINT64_C(0x9CDBF42CD7D6957A),
+ UINT64_C(0xD073867288020F69), UINT64_C(0x849AFFE0D4D2FE64),
+ UINT64_C(0x79A1755631A3ED73), UINT64_C(0x2D480CC46D731C7E),
+ UINT64_C(0x110ECF10544FD5D8), UINT64_C(0x45E7B682089F24D5),
+ UINT64_C(0xB8DC3C34EDEE37C2), UINT64_C(0xEC3545A6B13EC6CF),
+ UINT64_C(0xC051BB9C9F97A48E), UINT64_C(0x94B8C20EC3475583),
+ UINT64_C(0x698348B826364694), UINT64_C(0x3D6A312A7AE6B799),
+ UINT64_C(0x012CF2FE43DA7E3F), UINT64_C(0x55C58B6C1F0A8F32),
+ UINT64_C(0xA8FE01DAFA7B9C25), UINT64_C(0xFC177848A6AB6D28),
+ UINT64_C(0xF037FDAEA72958A7), UINT64_C(0xA4DE843CFBF9A9AA),
+ UINT64_C(0x59E50E8A1E88BABD), UINT64_C(0x0D0C771842584BB0),
+ UINT64_C(0x314AB4CC7B648216), UINT64_C(0x65A3CD5E27B4731B),
+ UINT64_C(0x989847E8C2C5600C), UINT64_C(0xCC713E7A9E159101),
+ UINT64_C(0xE015C040B0BCF340), UINT64_C(0xB4FCB9D2EC6C024D),
+ UINT64_C(0x49C73364091D115A), UINT64_C(0x1D2E4AF655CDE057),
+ UINT64_C(0x216889226CF129F1), UINT64_C(0x7581F0B03021D8FC),
+ UINT64_C(0x88BA7A06D550CBEB), UINT64_C(0xDC53039489803AE6),
+ UINT64_C(0x11EA9EBA6AF9FFCD), UINT64_C(0x4503E72836290EC0),
+ UINT64_C(0xB8386D9ED3581DD7), UINT64_C(0xECD1140C8F88ECDA),
+ UINT64_C(0xD097D7D8B6B4257C), UINT64_C(0x847EAE4AEA64D471),
+ UINT64_C(0x794524FC0F15C766), UINT64_C(0x2DAC5D6E53C5366B),
+ UINT64_C(0x01C8A3547D6C542A), UINT64_C(0x5521DAC621BCA527),
+ UINT64_C(0xA81A5070C4CDB630), UINT64_C(0xFCF329E2981D473D),
+ UINT64_C(0xC0B5EA36A1218E9B), UINT64_C(0x945C93A4FDF17F96),
+ UINT64_C(0x6967191218806C81), UINT64_C(0x3D8E608044509D8C),
+ UINT64_C(0x31AEE56645D2A803), UINT64_C(0x65479CF41902590E),
+ UINT64_C(0x987C1642FC734A19), UINT64_C(0xCC956FD0A0A3BB14),
+ UINT64_C(0xF0D3AC04999F72B2), UINT64_C(0xA43AD596C54F83BF),
+ UINT64_C(0x59015F20203E90A8), UINT64_C(0x0DE826B27CEE61A5),
+ UINT64_C(0x218CD888524703E4), UINT64_C(0x7565A11A0E97F2E9),
+ UINT64_C(0x885E2BACEBE6E1FE), UINT64_C(0xDCB7523EB73610F3),
+ UINT64_C(0xE0F191EA8E0AD955), UINT64_C(0xB418E878D2DA2858),
+ UINT64_C(0x492362CE37AB3B4F), UINT64_C(0x1DCA1B5C6B7BCA42),
+ UINT64_C(0x5162690234AF5051), UINT64_C(0x058B1090687FA15C),
+ UINT64_C(0xF8B09A268D0EB24B), UINT64_C(0xAC59E3B4D1DE4346),
+ UINT64_C(0x901F2060E8E28AE0), UINT64_C(0xC4F659F2B4327BED),
+ UINT64_C(0x39CDD344514368FA), UINT64_C(0x6D24AAD60D9399F7),
+ UINT64_C(0x414054EC233AFBB6), UINT64_C(0x15A92D7E7FEA0ABB),
+ UINT64_C(0xE892A7C89A9B19AC), UINT64_C(0xBC7BDE5AC64BE8A1),
+ UINT64_C(0x803D1D8EFF772107), UINT64_C(0xD4D4641CA3A7D00A),
+ UINT64_C(0x29EFEEAA46D6C31D), UINT64_C(0x7D0697381A063210),
+ UINT64_C(0x712612DE1B84079F), UINT64_C(0x25CF6B4C4754F692),
+ UINT64_C(0xD8F4E1FAA225E585), UINT64_C(0x8C1D9868FEF51488),
+ UINT64_C(0xB05B5BBCC7C9DD2E), UINT64_C(0xE4B2222E9B192C23),
+ UINT64_C(0x1989A8987E683F34), UINT64_C(0x4D60D10A22B8CE39),
+ UINT64_C(0x61042F300C11AC78), UINT64_C(0x35ED56A250C15D75),
+ UINT64_C(0xC8D6DC14B5B04E62), UINT64_C(0x9C3FA586E960BF6F),
+ UINT64_C(0xA0796652D05C76C9), UINT64_C(0xF4901FC08C8C87C4),
+ UINT64_C(0x09AB957669FD94D3), UINT64_C(0x5D42ECE4352D65DE)
+ }, {
+ UINT64_C(0x0000000000000000), UINT64_C(0x3F0BE14A916A6DCB),
+ UINT64_C(0x7E17C29522D4DB96), UINT64_C(0x411C23DFB3BEB65D),
+ UINT64_C(0xFC2F852A45A9B72C), UINT64_C(0xC3246460D4C3DAE7),
+ UINT64_C(0x823847BF677D6CBA), UINT64_C(0xBD33A6F5F6170171),
+ UINT64_C(0x6A87A57F245D70DD), UINT64_C(0x558C4435B5371D16),
+ UINT64_C(0x149067EA0689AB4B), UINT64_C(0x2B9B86A097E3C680),
+ UINT64_C(0x96A8205561F4C7F1), UINT64_C(0xA9A3C11FF09EAA3A),
+ UINT64_C(0xE8BFE2C043201C67), UINT64_C(0xD7B4038AD24A71AC),
+ UINT64_C(0xD50F4AFE48BAE1BA), UINT64_C(0xEA04ABB4D9D08C71),
+ UINT64_C(0xAB18886B6A6E3A2C), UINT64_C(0x94136921FB0457E7),
+ UINT64_C(0x2920CFD40D135696), UINT64_C(0x162B2E9E9C793B5D),
+ UINT64_C(0x57370D412FC78D00), UINT64_C(0x683CEC0BBEADE0CB),
+ UINT64_C(0xBF88EF816CE79167), UINT64_C(0x80830ECBFD8DFCAC),
+ UINT64_C(0xC19F2D144E334AF1), UINT64_C(0xFE94CC5EDF59273A),
+ UINT64_C(0x43A76AAB294E264B), UINT64_C(0x7CAC8BE1B8244B80),
+ UINT64_C(0x3DB0A83E0B9AFDDD), UINT64_C(0x02BB49749AF09016),
+ UINT64_C(0x38C63AD73E7BDDF1), UINT64_C(0x07CDDB9DAF11B03A),
+ UINT64_C(0x46D1F8421CAF0667), UINT64_C(0x79DA19088DC56BAC),
+ UINT64_C(0xC4E9BFFD7BD26ADD), UINT64_C(0xFBE25EB7EAB80716),
+ UINT64_C(0xBAFE7D685906B14B), UINT64_C(0x85F59C22C86CDC80),
+ UINT64_C(0x52419FA81A26AD2C), UINT64_C(0x6D4A7EE28B4CC0E7),
+ UINT64_C(0x2C565D3D38F276BA), UINT64_C(0x135DBC77A9981B71),
+ UINT64_C(0xAE6E1A825F8F1A00), UINT64_C(0x9165FBC8CEE577CB),
+ UINT64_C(0xD079D8177D5BC196), UINT64_C(0xEF72395DEC31AC5D),
+ UINT64_C(0xEDC9702976C13C4B), UINT64_C(0xD2C29163E7AB5180),
+ UINT64_C(0x93DEB2BC5415E7DD), UINT64_C(0xACD553F6C57F8A16),
+ UINT64_C(0x11E6F50333688B67), UINT64_C(0x2EED1449A202E6AC),
+ UINT64_C(0x6FF1379611BC50F1), UINT64_C(0x50FAD6DC80D63D3A),
+ UINT64_C(0x874ED556529C4C96), UINT64_C(0xB845341CC3F6215D),
+ UINT64_C(0xF95917C370489700), UINT64_C(0xC652F689E122FACB),
+ UINT64_C(0x7B61507C1735FBBA), UINT64_C(0x446AB136865F9671),
+ UINT64_C(0x057692E935E1202C), UINT64_C(0x3A7D73A3A48B4DE7),
+ UINT64_C(0x718C75AE7CF7BBE2), UINT64_C(0x4E8794E4ED9DD629),
+ UINT64_C(0x0F9BB73B5E236074), UINT64_C(0x30905671CF490DBF),
+ UINT64_C(0x8DA3F084395E0CCE), UINT64_C(0xB2A811CEA8346105),
+ UINT64_C(0xF3B432111B8AD758), UINT64_C(0xCCBFD35B8AE0BA93),
+ UINT64_C(0x1B0BD0D158AACB3F), UINT64_C(0x2400319BC9C0A6F4),
+ UINT64_C(0x651C12447A7E10A9), UINT64_C(0x5A17F30EEB147D62),
+ UINT64_C(0xE72455FB1D037C13), UINT64_C(0xD82FB4B18C6911D8),
+ UINT64_C(0x9933976E3FD7A785), UINT64_C(0xA6387624AEBDCA4E),
+ UINT64_C(0xA4833F50344D5A58), UINT64_C(0x9B88DE1AA5273793),
+ UINT64_C(0xDA94FDC5169981CE), UINT64_C(0xE59F1C8F87F3EC05),
+ UINT64_C(0x58ACBA7A71E4ED74), UINT64_C(0x67A75B30E08E80BF),
+ UINT64_C(0x26BB78EF533036E2), UINT64_C(0x19B099A5C25A5B29),
+ UINT64_C(0xCE049A2F10102A85), UINT64_C(0xF10F7B65817A474E),
+ UINT64_C(0xB01358BA32C4F113), UINT64_C(0x8F18B9F0A3AE9CD8),
+ UINT64_C(0x322B1F0555B99DA9), UINT64_C(0x0D20FE4FC4D3F062),
+ UINT64_C(0x4C3CDD90776D463F), UINT64_C(0x73373CDAE6072BF4),
+ UINT64_C(0x494A4F79428C6613), UINT64_C(0x7641AE33D3E60BD8),
+ UINT64_C(0x375D8DEC6058BD85), UINT64_C(0x08566CA6F132D04E),
+ UINT64_C(0xB565CA530725D13F), UINT64_C(0x8A6E2B19964FBCF4),
+ UINT64_C(0xCB7208C625F10AA9), UINT64_C(0xF479E98CB49B6762),
+ UINT64_C(0x23CDEA0666D116CE), UINT64_C(0x1CC60B4CF7BB7B05),
+ UINT64_C(0x5DDA28934405CD58), UINT64_C(0x62D1C9D9D56FA093),
+ UINT64_C(0xDFE26F2C2378A1E2), UINT64_C(0xE0E98E66B212CC29),
+ UINT64_C(0xA1F5ADB901AC7A74), UINT64_C(0x9EFE4CF390C617BF),
+ UINT64_C(0x9C4505870A3687A9), UINT64_C(0xA34EE4CD9B5CEA62),
+ UINT64_C(0xE252C71228E25C3F), UINT64_C(0xDD592658B98831F4),
+ UINT64_C(0x606A80AD4F9F3085), UINT64_C(0x5F6161E7DEF55D4E),
+ UINT64_C(0x1E7D42386D4BEB13), UINT64_C(0x2176A372FC2186D8),
+ UINT64_C(0xF6C2A0F82E6BF774), UINT64_C(0xC9C941B2BF019ABF),
+ UINT64_C(0x88D5626D0CBF2CE2), UINT64_C(0xB7DE83279DD54129),
+ UINT64_C(0x0AED25D26BC24058), UINT64_C(0x35E6C498FAA82D93),
+ UINT64_C(0x74FAE74749169BCE), UINT64_C(0x4BF1060DD87CF605),
+ UINT64_C(0xE318EB5CF9EF77C4), UINT64_C(0xDC130A1668851A0F),
+ UINT64_C(0x9D0F29C9DB3BAC52), UINT64_C(0xA204C8834A51C199),
+ UINT64_C(0x1F376E76BC46C0E8), UINT64_C(0x203C8F3C2D2CAD23),
+ UINT64_C(0x6120ACE39E921B7E), UINT64_C(0x5E2B4DA90FF876B5),
+ UINT64_C(0x899F4E23DDB20719), UINT64_C(0xB694AF694CD86AD2),
+ UINT64_C(0xF7888CB6FF66DC8F), UINT64_C(0xC8836DFC6E0CB144),
+ UINT64_C(0x75B0CB09981BB035), UINT64_C(0x4ABB2A430971DDFE),
+ UINT64_C(0x0BA7099CBACF6BA3), UINT64_C(0x34ACE8D62BA50668),
+ UINT64_C(0x3617A1A2B155967E), UINT64_C(0x091C40E8203FFBB5),
+ UINT64_C(0x4800633793814DE8), UINT64_C(0x770B827D02EB2023),
+ UINT64_C(0xCA382488F4FC2152), UINT64_C(0xF533C5C265964C99),
+ UINT64_C(0xB42FE61DD628FAC4), UINT64_C(0x8B2407574742970F),
+ UINT64_C(0x5C9004DD9508E6A3), UINT64_C(0x639BE59704628B68),
+ UINT64_C(0x2287C648B7DC3D35), UINT64_C(0x1D8C270226B650FE),
+ UINT64_C(0xA0BF81F7D0A1518F), UINT64_C(0x9FB460BD41CB3C44),
+ UINT64_C(0xDEA84362F2758A19), UINT64_C(0xE1A3A228631FE7D2),
+ UINT64_C(0xDBDED18BC794AA35), UINT64_C(0xE4D530C156FEC7FE),
+ UINT64_C(0xA5C9131EE54071A3), UINT64_C(0x9AC2F254742A1C68),
+ UINT64_C(0x27F154A1823D1D19), UINT64_C(0x18FAB5EB135770D2),
+ UINT64_C(0x59E69634A0E9C68F), UINT64_C(0x66ED777E3183AB44),
+ UINT64_C(0xB15974F4E3C9DAE8), UINT64_C(0x8E5295BE72A3B723),
+ UINT64_C(0xCF4EB661C11D017E), UINT64_C(0xF045572B50776CB5),
+ UINT64_C(0x4D76F1DEA6606DC4), UINT64_C(0x727D1094370A000F),
+ UINT64_C(0x3361334B84B4B652), UINT64_C(0x0C6AD20115DEDB99),
+ UINT64_C(0x0ED19B758F2E4B8F), UINT64_C(0x31DA7A3F1E442644),
+ UINT64_C(0x70C659E0ADFA9019), UINT64_C(0x4FCDB8AA3C90FDD2),
+ UINT64_C(0xF2FE1E5FCA87FCA3), UINT64_C(0xCDF5FF155BED9168),
+ UINT64_C(0x8CE9DCCAE8532735), UINT64_C(0xB3E23D8079394AFE),
+ UINT64_C(0x64563E0AAB733B52), UINT64_C(0x5B5DDF403A195699),
+ UINT64_C(0x1A41FC9F89A7E0C4), UINT64_C(0x254A1DD518CD8D0F),
+ UINT64_C(0x9879BB20EEDA8C7E), UINT64_C(0xA7725A6A7FB0E1B5),
+ UINT64_C(0xE66E79B5CC0E57E8), UINT64_C(0xD96598FF5D643A23),
+ UINT64_C(0x92949EF28518CC26), UINT64_C(0xAD9F7FB81472A1ED),
+ UINT64_C(0xEC835C67A7CC17B0), UINT64_C(0xD388BD2D36A67A7B),
+ UINT64_C(0x6EBB1BD8C0B17B0A), UINT64_C(0x51B0FA9251DB16C1),
+ UINT64_C(0x10ACD94DE265A09C), UINT64_C(0x2FA73807730FCD57),
+ UINT64_C(0xF8133B8DA145BCFB), UINT64_C(0xC718DAC7302FD130),
+ UINT64_C(0x8604F9188391676D), UINT64_C(0xB90F185212FB0AA6),
+ UINT64_C(0x043CBEA7E4EC0BD7), UINT64_C(0x3B375FED7586661C),
+ UINT64_C(0x7A2B7C32C638D041), UINT64_C(0x45209D785752BD8A),
+ UINT64_C(0x479BD40CCDA22D9C), UINT64_C(0x789035465CC84057),
+ UINT64_C(0x398C1699EF76F60A), UINT64_C(0x0687F7D37E1C9BC1),
+ UINT64_C(0xBBB45126880B9AB0), UINT64_C(0x84BFB06C1961F77B),
+ UINT64_C(0xC5A393B3AADF4126), UINT64_C(0xFAA872F93BB52CED),
+ UINT64_C(0x2D1C7173E9FF5D41), UINT64_C(0x121790397895308A),
+ UINT64_C(0x530BB3E6CB2B86D7), UINT64_C(0x6C0052AC5A41EB1C),
+ UINT64_C(0xD133F459AC56EA6D), UINT64_C(0xEE3815133D3C87A6),
+ UINT64_C(0xAF2436CC8E8231FB), UINT64_C(0x902FD7861FE85C30),
+ UINT64_C(0xAA52A425BB6311D7), UINT64_C(0x9559456F2A097C1C),
+ UINT64_C(0xD44566B099B7CA41), UINT64_C(0xEB4E87FA08DDA78A),
+ UINT64_C(0x567D210FFECAA6FB), UINT64_C(0x6976C0456FA0CB30),
+ UINT64_C(0x286AE39ADC1E7D6D), UINT64_C(0x176102D04D7410A6),
+ UINT64_C(0xC0D5015A9F3E610A), UINT64_C(0xFFDEE0100E540CC1),
+ UINT64_C(0xBEC2C3CFBDEABA9C), UINT64_C(0x81C922852C80D757),
+ UINT64_C(0x3CFA8470DA97D626), UINT64_C(0x03F1653A4BFDBBED),
+ UINT64_C(0x42ED46E5F8430DB0), UINT64_C(0x7DE6A7AF6929607B),
+ UINT64_C(0x7F5DEEDBF3D9F06D), UINT64_C(0x40560F9162B39DA6),
+ UINT64_C(0x014A2C4ED10D2BFB), UINT64_C(0x3E41CD0440674630),
+ UINT64_C(0x83726BF1B6704741), UINT64_C(0xBC798ABB271A2A8A),
+ UINT64_C(0xFD65A96494A49CD7), UINT64_C(0xC26E482E05CEF11C),
+ UINT64_C(0x15DA4BA4D78480B0), UINT64_C(0x2AD1AAEE46EEED7B),
+ UINT64_C(0x6BCD8931F5505B26), UINT64_C(0x54C6687B643A36ED),
+ UINT64_C(0xE9F5CE8E922D379C), UINT64_C(0xD6FE2FC403475A57),
+ UINT64_C(0x97E20C1BB0F9EC0A), UINT64_C(0xA8E9ED51219381C1)
+ }, {
+ UINT64_C(0x0000000000000000), UINT64_C(0x1DEE8A5E222CA1DC),
+ UINT64_C(0x3BDD14BC445943B8), UINT64_C(0x26339EE26675E264),
+ UINT64_C(0x77BA297888B28770), UINT64_C(0x6A54A326AA9E26AC),
+ UINT64_C(0x4C673DC4CCEBC4C8), UINT64_C(0x5189B79AEEC76514),
+ UINT64_C(0xEF7452F111650EE0), UINT64_C(0xF29AD8AF3349AF3C),
+ UINT64_C(0xD4A9464D553C4D58), UINT64_C(0xC947CC137710EC84),
+ UINT64_C(0x98CE7B8999D78990), UINT64_C(0x8520F1D7BBFB284C),
+ UINT64_C(0xA3136F35DD8ECA28), UINT64_C(0xBEFDE56BFFA26BF4),
+ UINT64_C(0x4C300AC98DC40345), UINT64_C(0x51DE8097AFE8A299),
+ UINT64_C(0x77ED1E75C99D40FD), UINT64_C(0x6A03942BEBB1E121),
+ UINT64_C(0x3B8A23B105768435), UINT64_C(0x2664A9EF275A25E9),
+ UINT64_C(0x0057370D412FC78D), UINT64_C(0x1DB9BD5363036651),
+ UINT64_C(0xA34458389CA10DA5), UINT64_C(0xBEAAD266BE8DAC79),
+ UINT64_C(0x98994C84D8F84E1D), UINT64_C(0x8577C6DAFAD4EFC1),
+ UINT64_C(0xD4FE714014138AD5), UINT64_C(0xC910FB1E363F2B09),
+ UINT64_C(0xEF2365FC504AC96D), UINT64_C(0xF2CDEFA2726668B1),
+ UINT64_C(0x986015931B88068A), UINT64_C(0x858E9FCD39A4A756),
+ UINT64_C(0xA3BD012F5FD14532), UINT64_C(0xBE538B717DFDE4EE),
+ UINT64_C(0xEFDA3CEB933A81FA), UINT64_C(0xF234B6B5B1162026),
+ UINT64_C(0xD4072857D763C242), UINT64_C(0xC9E9A209F54F639E),
+ UINT64_C(0x771447620AED086A), UINT64_C(0x6AFACD3C28C1A9B6),
+ UINT64_C(0x4CC953DE4EB44BD2), UINT64_C(0x5127D9806C98EA0E),
+ UINT64_C(0x00AE6E1A825F8F1A), UINT64_C(0x1D40E444A0732EC6),
+ UINT64_C(0x3B737AA6C606CCA2), UINT64_C(0x269DF0F8E42A6D7E),
+ UINT64_C(0xD4501F5A964C05CF), UINT64_C(0xC9BE9504B460A413),
+ UINT64_C(0xEF8D0BE6D2154677), UINT64_C(0xF26381B8F039E7AB),
+ UINT64_C(0xA3EA36221EFE82BF), UINT64_C(0xBE04BC7C3CD22363),
+ UINT64_C(0x9837229E5AA7C107), UINT64_C(0x85D9A8C0788B60DB),
+ UINT64_C(0x3B244DAB87290B2F), UINT64_C(0x26CAC7F5A505AAF3),
+ UINT64_C(0x00F95917C3704897), UINT64_C(0x1D17D349E15CE94B),
+ UINT64_C(0x4C9E64D30F9B8C5F), UINT64_C(0x5170EE8D2DB72D83),
+ UINT64_C(0x7743706F4BC2CFE7), UINT64_C(0x6AADFA3169EE6E3B),
+ UINT64_C(0xA218840D981E1391), UINT64_C(0xBFF60E53BA32B24D),
+ UINT64_C(0x99C590B1DC475029), UINT64_C(0x842B1AEFFE6BF1F5),
+ UINT64_C(0xD5A2AD7510AC94E1), UINT64_C(0xC84C272B3280353D),
+ UINT64_C(0xEE7FB9C954F5D759), UINT64_C(0xF391339776D97685),
+ UINT64_C(0x4D6CD6FC897B1D71), UINT64_C(0x50825CA2AB57BCAD),
+ UINT64_C(0x76B1C240CD225EC9), UINT64_C(0x6B5F481EEF0EFF15),
+ UINT64_C(0x3AD6FF8401C99A01), UINT64_C(0x273875DA23E53BDD),
+ UINT64_C(0x010BEB384590D9B9), UINT64_C(0x1CE5616667BC7865),
+ UINT64_C(0xEE288EC415DA10D4), UINT64_C(0xF3C6049A37F6B108),
+ UINT64_C(0xD5F59A785183536C), UINT64_C(0xC81B102673AFF2B0),
+ UINT64_C(0x9992A7BC9D6897A4), UINT64_C(0x847C2DE2BF443678),
+ UINT64_C(0xA24FB300D931D41C), UINT64_C(0xBFA1395EFB1D75C0),
+ UINT64_C(0x015CDC3504BF1E34), UINT64_C(0x1CB2566B2693BFE8),
+ UINT64_C(0x3A81C88940E65D8C), UINT64_C(0x276F42D762CAFC50),
+ UINT64_C(0x76E6F54D8C0D9944), UINT64_C(0x6B087F13AE213898),
+ UINT64_C(0x4D3BE1F1C854DAFC), UINT64_C(0x50D56BAFEA787B20),
+ UINT64_C(0x3A78919E8396151B), UINT64_C(0x27961BC0A1BAB4C7),
+ UINT64_C(0x01A58522C7CF56A3), UINT64_C(0x1C4B0F7CE5E3F77F),
+ UINT64_C(0x4DC2B8E60B24926B), UINT64_C(0x502C32B8290833B7),
+ UINT64_C(0x761FAC5A4F7DD1D3), UINT64_C(0x6BF126046D51700F),
+ UINT64_C(0xD50CC36F92F31BFB), UINT64_C(0xC8E24931B0DFBA27),
+ UINT64_C(0xEED1D7D3D6AA5843), UINT64_C(0xF33F5D8DF486F99F),
+ UINT64_C(0xA2B6EA171A419C8B), UINT64_C(0xBF586049386D3D57),
+ UINT64_C(0x996BFEAB5E18DF33), UINT64_C(0x848574F57C347EEF),
+ UINT64_C(0x76489B570E52165E), UINT64_C(0x6BA611092C7EB782),
+ UINT64_C(0x4D958FEB4A0B55E6), UINT64_C(0x507B05B56827F43A),
+ UINT64_C(0x01F2B22F86E0912E), UINT64_C(0x1C1C3871A4CC30F2),
+ UINT64_C(0x3A2FA693C2B9D296), UINT64_C(0x27C12CCDE095734A),
+ UINT64_C(0x993CC9A61F3718BE), UINT64_C(0x84D243F83D1BB962),
+ UINT64_C(0xA2E1DD1A5B6E5B06), UINT64_C(0xBF0F57447942FADA),
+ UINT64_C(0xEE86E0DE97859FCE), UINT64_C(0xF3686A80B5A93E12),
+ UINT64_C(0xD55BF462D3DCDC76), UINT64_C(0xC8B57E3CF1F07DAA),
+ UINT64_C(0xD6E9A7309F3239A7), UINT64_C(0xCB072D6EBD1E987B),
+ UINT64_C(0xED34B38CDB6B7A1F), UINT64_C(0xF0DA39D2F947DBC3),
+ UINT64_C(0xA1538E481780BED7), UINT64_C(0xBCBD041635AC1F0B),
+ UINT64_C(0x9A8E9AF453D9FD6F), UINT64_C(0x876010AA71F55CB3),
+ UINT64_C(0x399DF5C18E573747), UINT64_C(0x24737F9FAC7B969B),
+ UINT64_C(0x0240E17DCA0E74FF), UINT64_C(0x1FAE6B23E822D523),
+ UINT64_C(0x4E27DCB906E5B037), UINT64_C(0x53C956E724C911EB),
+ UINT64_C(0x75FAC80542BCF38F), UINT64_C(0x6814425B60905253),
+ UINT64_C(0x9AD9ADF912F63AE2), UINT64_C(0x873727A730DA9B3E),
+ UINT64_C(0xA104B94556AF795A), UINT64_C(0xBCEA331B7483D886),
+ UINT64_C(0xED6384819A44BD92), UINT64_C(0xF08D0EDFB8681C4E),
+ UINT64_C(0xD6BE903DDE1DFE2A), UINT64_C(0xCB501A63FC315FF6),
+ UINT64_C(0x75ADFF0803933402), UINT64_C(0x6843755621BF95DE),
+ UINT64_C(0x4E70EBB447CA77BA), UINT64_C(0x539E61EA65E6D666),
+ UINT64_C(0x0217D6708B21B372), UINT64_C(0x1FF95C2EA90D12AE),
+ UINT64_C(0x39CAC2CCCF78F0CA), UINT64_C(0x24244892ED545116),
+ UINT64_C(0x4E89B2A384BA3F2D), UINT64_C(0x536738FDA6969EF1),
+ UINT64_C(0x7554A61FC0E37C95), UINT64_C(0x68BA2C41E2CFDD49),
+ UINT64_C(0x39339BDB0C08B85D), UINT64_C(0x24DD11852E241981),
+ UINT64_C(0x02EE8F674851FBE5), UINT64_C(0x1F0005396A7D5A39),
+ UINT64_C(0xA1FDE05295DF31CD), UINT64_C(0xBC136A0CB7F39011),
+ UINT64_C(0x9A20F4EED1867275), UINT64_C(0x87CE7EB0F3AAD3A9),
+ UINT64_C(0xD647C92A1D6DB6BD), UINT64_C(0xCBA943743F411761),
+ UINT64_C(0xED9ADD965934F505), UINT64_C(0xF07457C87B1854D9),
+ UINT64_C(0x02B9B86A097E3C68), UINT64_C(0x1F5732342B529DB4),
+ UINT64_C(0x3964ACD64D277FD0), UINT64_C(0x248A26886F0BDE0C),
+ UINT64_C(0x7503911281CCBB18), UINT64_C(0x68ED1B4CA3E01AC4),
+ UINT64_C(0x4EDE85AEC595F8A0), UINT64_C(0x53300FF0E7B9597C),
+ UINT64_C(0xEDCDEA9B181B3288), UINT64_C(0xF02360C53A379354),
+ UINT64_C(0xD610FE275C427130), UINT64_C(0xCBFE74797E6ED0EC),
+ UINT64_C(0x9A77C3E390A9B5F8), UINT64_C(0x879949BDB2851424),
+ UINT64_C(0xA1AAD75FD4F0F640), UINT64_C(0xBC445D01F6DC579C),
+ UINT64_C(0x74F1233D072C2A36), UINT64_C(0x691FA96325008BEA),
+ UINT64_C(0x4F2C37814375698E), UINT64_C(0x52C2BDDF6159C852),
+ UINT64_C(0x034B0A458F9EAD46), UINT64_C(0x1EA5801BADB20C9A),
+ UINT64_C(0x38961EF9CBC7EEFE), UINT64_C(0x257894A7E9EB4F22),
+ UINT64_C(0x9B8571CC164924D6), UINT64_C(0x866BFB923465850A),
+ UINT64_C(0xA05865705210676E), UINT64_C(0xBDB6EF2E703CC6B2),
+ UINT64_C(0xEC3F58B49EFBA3A6), UINT64_C(0xF1D1D2EABCD7027A),
+ UINT64_C(0xD7E24C08DAA2E01E), UINT64_C(0xCA0CC656F88E41C2),
+ UINT64_C(0x38C129F48AE82973), UINT64_C(0x252FA3AAA8C488AF),
+ UINT64_C(0x031C3D48CEB16ACB), UINT64_C(0x1EF2B716EC9DCB17),
+ UINT64_C(0x4F7B008C025AAE03), UINT64_C(0x52958AD220760FDF),
+ UINT64_C(0x74A614304603EDBB), UINT64_C(0x69489E6E642F4C67),
+ UINT64_C(0xD7B57B059B8D2793), UINT64_C(0xCA5BF15BB9A1864F),
+ UINT64_C(0xEC686FB9DFD4642B), UINT64_C(0xF186E5E7FDF8C5F7),
+ UINT64_C(0xA00F527D133FA0E3), UINT64_C(0xBDE1D8233113013F),
+ UINT64_C(0x9BD246C15766E35B), UINT64_C(0x863CCC9F754A4287),
+ UINT64_C(0xEC9136AE1CA42CBC), UINT64_C(0xF17FBCF03E888D60),
+ UINT64_C(0xD74C221258FD6F04), UINT64_C(0xCAA2A84C7AD1CED8),
+ UINT64_C(0x9B2B1FD69416ABCC), UINT64_C(0x86C59588B63A0A10),
+ UINT64_C(0xA0F60B6AD04FE874), UINT64_C(0xBD188134F26349A8),
+ UINT64_C(0x03E5645F0DC1225C), UINT64_C(0x1E0BEE012FED8380),
+ UINT64_C(0x383870E3499861E4), UINT64_C(0x25D6FABD6BB4C038),
+ UINT64_C(0x745F4D278573A52C), UINT64_C(0x69B1C779A75F04F0),
+ UINT64_C(0x4F82599BC12AE694), UINT64_C(0x526CD3C5E3064748),
+ UINT64_C(0xA0A13C6791602FF9), UINT64_C(0xBD4FB639B34C8E25),
+ UINT64_C(0x9B7C28DBD5396C41), UINT64_C(0x8692A285F715CD9D),
+ UINT64_C(0xD71B151F19D2A889), UINT64_C(0xCAF59F413BFE0955),
+ UINT64_C(0xECC601A35D8BEB31), UINT64_C(0xF1288BFD7FA74AED),
+ UINT64_C(0x4FD56E9680052119), UINT64_C(0x523BE4C8A22980C5),
+ UINT64_C(0x74087A2AC45C62A1), UINT64_C(0x69E6F074E670C37D),
+ UINT64_C(0x386F47EE08B7A669), UINT64_C(0x2581CDB02A9B07B5),
+ UINT64_C(0x03B253524CEEE5D1), UINT64_C(0x1E5CD90C6EC2440D)
+ }
+};
diff --git a/Utilities/cmliblzma/liblzma/check/crc64_tablegen.c b/Utilities/cmliblzma/liblzma/check/crc64_tablegen.c
new file mode 100644
index 000000000..fddaa7ed1
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/check/crc64_tablegen.c
@@ -0,0 +1,88 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file crc64_tablegen.c
+/// \brief Generate crc64_table_le.h and crc64_table_be.h
+///
+/// Compiling: gcc -std=c99 -o crc64_tablegen crc64_tablegen.c
+/// Add -DWORDS_BIGENDIAN to generate big endian table.
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+#include "../../common/tuklib_integer.h"
+
+
+static uint64_t crc64_table[4][256];
+
+
+extern void
+init_crc64_table(void)
+{
+ static const uint64_t poly64 = UINT64_C(0xC96C5795D7870F42);
+
+ for (size_t s = 0; s < 4; ++s) {
+ for (size_t b = 0; b < 256; ++b) {
+ uint64_t r = s == 0 ? b : crc64_table[s - 1][b];
+
+ for (size_t i = 0; i < 8; ++i) {
+ if (r & 1)
+ r = (r >> 1) ^ poly64;
+ else
+ r >>= 1;
+ }
+
+ crc64_table[s][b] = r;
+ }
+ }
+
+#ifdef WORDS_BIGENDIAN
+ for (size_t s = 0; s < 4; ++s)
+ for (size_t b = 0; b < 256; ++b)
+ crc64_table[s][b] = bswap64(crc64_table[s][b]);
+#endif
+
+ return;
+}
+
+
+static void
+print_crc64_table(void)
+{
+ printf("/* This file has been automatically generated by "
+ "crc64_tablegen.c. */\n\n"
+ "const uint64_t lzma_crc64_table[4][256] = {\n\t{");
+
+ for (size_t s = 0; s < 4; ++s) {
+ for (size_t b = 0; b < 256; ++b) {
+ if ((b % 2) == 0)
+ printf("\n\t\t");
+
+ printf("UINT64_C(0x%016" PRIX64 ")",
+ crc64_table[s][b]);
+
+ if (b != 255)
+ printf(",%s", (b+1) % 2 == 0 ? "" : " ");
+ }
+
+ if (s == 3)
+ printf("\n\t}\n};\n");
+ else
+ printf("\n\t}, {");
+ }
+
+ return;
+}
+
+
+int
+main(void)
+{
+ init_crc64_table();
+ print_crc64_table();
+ return 0;
+}
diff --git a/Utilities/cmliblzma/liblzma/check/crc64_x86.S b/Utilities/cmliblzma/liblzma/check/crc64_x86.S
new file mode 100644
index 000000000..f5bb84b97
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/check/crc64_x86.S
@@ -0,0 +1,287 @@
+/*
+ * Speed-optimized CRC64 using slicing-by-four algorithm
+ *
+ * This uses only i386 instructions, but it is optimized for i686 and later
+ * (including e.g. Pentium II/III/IV, Athlon XP, and Core 2).
+ *
+ * Authors: Igor Pavlov (original CRC32 assembly code)
+ * Lasse Collin (CRC64 adaptation of the modified CRC32 code)
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ *
+ * This code needs lzma_crc64_table, which can be created using the
+ * following C code:
+
+uint64_t lzma_crc64_table[4][256];
+
+void
+init_table(void)
+{
+ // ECMA-182
+ static const uint64_t poly64 = UINT64_C(0xC96C5795D7870F42);
+
+ for (size_t s = 0; s < 4; ++s) {
+ for (size_t b = 0; b < 256; ++b) {
+ uint64_t r = s == 0 ? b : lzma_crc64_table[s - 1][b];
+
+ for (size_t i = 0; i < 8; ++i) {
+ if (r & 1)
+ r = (r >> 1) ^ poly64;
+ else
+ r >>= 1;
+ }
+
+ lzma_crc64_table[s][b] = r;
+ }
+ }
+}
+
+ * The prototype of the CRC64 function:
+ * extern uint64_t lzma_crc64(const uint8_t *buf, size_t size, uint64_t crc);
+ */
+
+/*
+ * On some systems, the functions need to be prefixed. The prefix is
+ * usually an underscore.
+ */
+#ifndef __USER_LABEL_PREFIX__
+# define __USER_LABEL_PREFIX__
+#endif
+#define MAKE_SYM_CAT(prefix, sym) prefix ## sym
+#define MAKE_SYM(prefix, sym) MAKE_SYM_CAT(prefix, sym)
+#define LZMA_CRC64 MAKE_SYM(__USER_LABEL_PREFIX__, lzma_crc64)
+#define LZMA_CRC64_TABLE MAKE_SYM(__USER_LABEL_PREFIX__, lzma_crc64_table)
+
+/*
+ * Solaris assembler doesn't have .p2align, and Darwin uses .align
+ * differently than GNU/Linux and Solaris.
+ */
+#if defined(__APPLE__) || defined(__MSDOS__)
+# define ALIGN(pow2, abs) .align pow2
+#else
+# define ALIGN(pow2, abs) .align abs
+#endif
+
+ .text
+ .globl LZMA_CRC64
+
+#if !defined(__APPLE__) && !defined(_WIN32) && !defined(__CYGWIN__) \
+ && !defined(__MSDOS__)
+ .type LZMA_CRC64, @function
+#endif
+
+ ALIGN(4, 16)
+LZMA_CRC64:
+ /*
+ * Register usage:
+ * %eax crc LSB
+ * %edx crc MSB
+ * %esi buf
+ * %edi size or buf + size
+ * %ebx lzma_crc64_table
+ * %ebp Table index
+ * %ecx Temporary
+ */
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ pushl %ebp
+ movl 0x14(%esp), %esi /* buf */
+ movl 0x18(%esp), %edi /* size */
+ movl 0x1C(%esp), %eax /* crc LSB */
+ movl 0x20(%esp), %edx /* crc MSB */
+
+ /*
+ * Store the address of lzma_crc64_table to %ebx. This is needed to
+ * get position-independent code (PIC).
+ *
+ * The PIC macro is defined by libtool, while __PIC__ is defined
+ * by GCC but only on some systems. Testing for both makes it simpler
+ * to test this code without libtool, and keeps the code working also
+ * when built with libtool but using something else than GCC.
+ *
+ * I understood that libtool may define PIC on Windows even though
+ * the code in Windows DLLs is not PIC in sense that it is in ELF
+ * binaries, so we need a separate check to always use the non-PIC
+ * code on Windows.
+ */
+#if (!defined(PIC) && !defined(__PIC__)) \
+ || (defined(_WIN32) || defined(__CYGWIN__))
+ /* Not PIC */
+ movl $ LZMA_CRC64_TABLE, %ebx
+#elif defined(__APPLE__)
+ /* Mach-O */
+ call .L_get_pc
+.L_pic:
+ leal .L_lzma_crc64_table$non_lazy_ptr-.L_pic(%ebx), %ebx
+ movl (%ebx), %ebx
+#else
+ /* ELF */
+ call .L_get_pc
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+ movl LZMA_CRC64_TABLE@GOT(%ebx), %ebx
+#endif
+
+ /* Complement the initial value. */
+ notl %eax
+ notl %edx
+
+.L_align:
+ /*
+ * Check if there is enough input to use slicing-by-four.
+ * We need eight bytes, because the loop pre-reads four bytes.
+ */
+ cmpl $8, %edi
+ jb .L_rest
+
+ /* Check if we have reached alignment of four bytes. */
+ testl $3, %esi
+ jz .L_slice
+
+ /* Calculate CRC of the next input byte. */
+ movzbl (%esi), %ebp
+ incl %esi
+ movzbl %al, %ecx
+ xorl %ecx, %ebp
+ shrdl $8, %edx, %eax
+ xorl (%ebx, %ebp, 8), %eax
+ shrl $8, %edx
+ xorl 4(%ebx, %ebp, 8), %edx
+ decl %edi
+ jmp .L_align
+
+.L_slice:
+ /*
+ * If we get here, there's at least eight bytes of aligned input
+ * available. Make %edi multiple of four bytes. Store the possible
+ * remainder over the "size" variable in the argument stack.
+ */
+ movl %edi, 0x18(%esp)
+ andl $-4, %edi
+ subl %edi, 0x18(%esp)
+
+ /*
+ * Let %edi be buf + size - 4 while running the main loop. This way
+ * we can compare for equality to determine when exit the loop.
+ */
+ addl %esi, %edi
+ subl $4, %edi
+
+ /* Read in the first four aligned bytes. */
+ movl (%esi), %ecx
+
+.L_loop:
+ xorl %eax, %ecx
+ movzbl %cl, %ebp
+ movl 0x1800(%ebx, %ebp, 8), %eax
+ xorl %edx, %eax
+ movl 0x1804(%ebx, %ebp, 8), %edx
+ movzbl %ch, %ebp
+ xorl 0x1000(%ebx, %ebp, 8), %eax
+ xorl 0x1004(%ebx, %ebp, 8), %edx
+ shrl $16, %ecx
+ movzbl %cl, %ebp
+ xorl 0x0800(%ebx, %ebp, 8), %eax
+ xorl 0x0804(%ebx, %ebp, 8), %edx
+ movzbl %ch, %ebp
+ addl $4, %esi
+ xorl (%ebx, %ebp, 8), %eax
+ xorl 4(%ebx, %ebp, 8), %edx
+
+ /* Check for end of aligned input. */
+ cmpl %edi, %esi
+
+ /*
+ * Copy the next input byte to %ecx. It is slightly faster to
+ * read it here than at the top of the loop.
+ */
+ movl (%esi), %ecx
+ jb .L_loop
+
+ /*
+ * Process the remaining four bytes, which we have already
+ * copied to %ecx.
+ */
+ xorl %eax, %ecx
+ movzbl %cl, %ebp
+ movl 0x1800(%ebx, %ebp, 8), %eax
+ xorl %edx, %eax
+ movl 0x1804(%ebx, %ebp, 8), %edx
+ movzbl %ch, %ebp
+ xorl 0x1000(%ebx, %ebp, 8), %eax
+ xorl 0x1004(%ebx, %ebp, 8), %edx
+ shrl $16, %ecx
+ movzbl %cl, %ebp
+ xorl 0x0800(%ebx, %ebp, 8), %eax
+ xorl 0x0804(%ebx, %ebp, 8), %edx
+ movzbl %ch, %ebp
+ addl $4, %esi
+ xorl (%ebx, %ebp, 8), %eax
+ xorl 4(%ebx, %ebp, 8), %edx
+
+ /* Copy the number of remaining bytes to %edi. */
+ movl 0x18(%esp), %edi
+
+.L_rest:
+ /* Check for end of input. */
+ testl %edi, %edi
+ jz .L_return
+
+ /* Calculate CRC of the next input byte. */
+ movzbl (%esi), %ebp
+ incl %esi
+ movzbl %al, %ecx
+ xorl %ecx, %ebp
+ shrdl $8, %edx, %eax
+ xorl (%ebx, %ebp, 8), %eax
+ shrl $8, %edx
+ xorl 4(%ebx, %ebp, 8), %edx
+ decl %edi
+ jmp .L_rest
+
+.L_return:
+ /* Complement the final value. */
+ notl %eax
+ notl %edx
+
+ popl %ebp
+ popl %edi
+ popl %esi
+ popl %ebx
+ ret
+
+#if defined(PIC) || defined(__PIC__)
+ ALIGN(4, 16)
+.L_get_pc:
+ movl (%esp), %ebx
+ ret
+#endif
+
+#if defined(__APPLE__) && (defined(PIC) || defined(__PIC__))
+ /* Mach-O PIC */
+ .section __IMPORT,__pointers,non_lazy_symbol_pointers
+.L_lzma_crc64_table$non_lazy_ptr:
+ .indirect_symbol LZMA_CRC64_TABLE
+ .long 0
+
+#elif defined(_WIN32) || defined(__CYGWIN__)
+# ifdef DLL_EXPORT
+ /* This is equivalent of __declspec(dllexport). */
+ .section .drectve
+ .ascii " -export:lzma_crc64"
+# endif
+
+#elif !defined(__MSDOS__)
+ /* ELF */
+ .size LZMA_CRC64, .-LZMA_CRC64
+#endif
+
+/*
+ * This is needed to support non-executable stack. It's ugly to
+ * use __linux__ here, but I don't know a way to detect when
+ * we are using GNU assembler.
+ */
+#if defined(__ELF__) && defined(__linux__)
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/Utilities/cmliblzma/liblzma/check/crc_macros.h b/Utilities/cmliblzma/liblzma/check/crc_macros.h
new file mode 100644
index 000000000..a7c21b765
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/check/crc_macros.h
@@ -0,0 +1,30 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file crc_macros.h
+/// \brief Some endian-dependent macros for CRC32 and CRC64
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifdef WORDS_BIGENDIAN
+# define A(x) ((x) >> 24)
+# define B(x) (((x) >> 16) & 0xFF)
+# define C(x) (((x) >> 8) & 0xFF)
+# define D(x) ((x) & 0xFF)
+
+# define S8(x) ((x) << 8)
+# define S32(x) ((x) << 32)
+
+#else
+# define A(x) ((x) & 0xFF)
+# define B(x) (((x) >> 8) & 0xFF)
+# define C(x) (((x) >> 16) & 0xFF)
+# define D(x) ((x) >> 24)
+
+# define S8(x) ((x) >> 8)
+# define S32(x) ((x) >> 32)
+#endif
diff --git a/Utilities/cmliblzma/liblzma/check/sha256.c b/Utilities/cmliblzma/liblzma/check/sha256.c
new file mode 100644
index 000000000..c2c85eb23
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/check/sha256.c
@@ -0,0 +1,204 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file sha256.c
+/// \brief SHA-256
+///
+/// \todo Crypto++ has x86 ASM optimizations. They use SSE so if they
+/// are imported to liblzma, SSE instructions need to be used
+/// conditionally to keep the code working on older boxes.
+//
+// This code is based on the code found from 7-Zip, which has a modified
+// version of the SHA-256 found from Crypto++ <http://www.cryptopp.com/>.
+// The code was modified a little to fit into liblzma.
+//
+// Authors: Kevin Springle
+// Wei Dai
+// Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+// Avoid bogus warnings in transform().
+#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 2) || __GNUC__ > 4
+# pragma GCC diagnostic ignored "-Wuninitialized"
+#endif
+
+#include "check.h"
+
+// At least on x86, GCC is able to optimize this to a rotate instruction.
+#define rotr_32(num, amount) ((num) >> (amount) | (num) << (32 - (amount)))
+
+#define blk0(i) (W[i] = data[i])
+#define blk2(i) (W[i & 15] += s1(W[(i - 2) & 15]) + W[(i - 7) & 15] \
+ + s0(W[(i - 15) & 15]))
+
+#define Ch(x, y, z) (z ^ (x & (y ^ z)))
+#define Maj(x, y, z) ((x & y) | (z & (x | y)))
+
+#define a(i) T[(0 - i) & 7]
+#define b(i) T[(1 - i) & 7]
+#define c(i) T[(2 - i) & 7]
+#define d(i) T[(3 - i) & 7]
+#define e(i) T[(4 - i) & 7]
+#define f(i) T[(5 - i) & 7]
+#define g(i) T[(6 - i) & 7]
+#define h(i) T[(7 - i) & 7]
+
+#define R(i) \
+ h(i) += S1(e(i)) + Ch(e(i), f(i), g(i)) + SHA256_K[i + j] \
+ + (j ? blk2(i) : blk0(i)); \
+ d(i) += h(i); \
+ h(i) += S0(a(i)) + Maj(a(i), b(i), c(i))
+
+#define S0(x) (rotr_32(x, 2) ^ rotr_32(x, 13) ^ rotr_32(x, 22))
+#define S1(x) (rotr_32(x, 6) ^ rotr_32(x, 11) ^ rotr_32(x, 25))
+#define s0(x) (rotr_32(x, 7) ^ rotr_32(x, 18) ^ (x >> 3))
+#define s1(x) (rotr_32(x, 17) ^ rotr_32(x, 19) ^ (x >> 10))
+
+
+static const uint32_t SHA256_K[64] = {
+ 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
+ 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
+ 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
+ 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
+ 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
+ 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
+ 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
+ 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
+ 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
+ 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
+ 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
+ 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
+ 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
+ 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
+ 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
+ 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
+};
+
+
+static void
+transform(uint32_t state[], const uint32_t data[])
+{
+ uint32_t W[16];
+ uint32_t T[8];
+ unsigned int j;
+
+ // Copy state[] to working vars.
+ memcpy(T, state, sizeof(T));
+
+ // 64 operations, partially loop unrolled
+ for (j = 0; j < 64; j += 16) {
+ R( 0); R( 1); R( 2); R( 3);
+ R( 4); R( 5); R( 6); R( 7);
+ R( 8); R( 9); R(10); R(11);
+ R(12); R(13); R(14); R(15);
+ }
+
+ // Add the working vars back into state[].
+ state[0] += a(0);
+ state[1] += b(0);
+ state[2] += c(0);
+ state[3] += d(0);
+ state[4] += e(0);
+ state[5] += f(0);
+ state[6] += g(0);
+ state[7] += h(0);
+}
+
+
+static void
+process(lzma_check_state *check)
+{
+#ifdef WORDS_BIGENDIAN
+ transform(check->state.sha256.state, check->buffer.u32);
+
+#else
+ uint32_t data[16];
+ size_t i;
+
+ for (i = 0; i < 16; ++i)
+ data[i] = bswap32(check->buffer.u32[i]);
+
+ transform(check->state.sha256.state, data);
+#endif
+
+ return;
+}
+
+
+extern void
+lzma_sha256_init(lzma_check_state *check)
+{
+ static const uint32_t s[8] = {
+ 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
+ 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19,
+ };
+
+ memcpy(check->state.sha256.state, s, sizeof(s));
+ check->state.sha256.size = 0;
+
+ return;
+}
+
+
+extern void
+lzma_sha256_update(const uint8_t *buf, size_t size, lzma_check_state *check)
+{
+ // Copy the input data into a properly aligned temporary buffer.
+ // This way we can be called with arbitrarily sized buffers
+ // (no need to be multiple of 64 bytes), and the code works also
+ // on architectures that don't allow unaligned memory access.
+ while (size > 0) {
+ const size_t copy_start = check->state.sha256.size & 0x3F;
+ size_t copy_size = 64 - copy_start;
+ if (copy_size > size)
+ copy_size = size;
+
+ memcpy(check->buffer.u8 + copy_start, buf, copy_size);
+
+ buf += copy_size;
+ size -= copy_size;
+ check->state.sha256.size += copy_size;
+
+ if ((check->state.sha256.size & 0x3F) == 0)
+ process(check);
+ }
+
+ return;
+}
+
+
+extern void
+lzma_sha256_finish(lzma_check_state *check)
+{
+ size_t i;
+
+ // Add padding as described in RFC 3174 (it describes SHA-1 but
+ // the same padding style is used for SHA-256 too).
+ size_t pos = check->state.sha256.size & 0x3F;
+ check->buffer.u8[pos++] = 0x80;
+
+ while (pos != 64 - 8) {
+ if (pos == 64) {
+ process(check);
+ pos = 0;
+ }
+
+ check->buffer.u8[pos++] = 0x00;
+ }
+
+ // Convert the message size from bytes to bits.
+ check->state.sha256.size *= 8;
+
+ check->buffer.u64[(64 - 8) / 8] = conv64be(check->state.sha256.size);
+
+ process(check);
+
+ for (i = 0; i < 8; ++i)
+ check->buffer.u32[i] = conv32be(check->state.sha256.state[i]);
+
+ return;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/alone_decoder.c b/Utilities/cmliblzma/liblzma/common/alone_decoder.c
new file mode 100644
index 000000000..5f5e564ab
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/alone_decoder.c
@@ -0,0 +1,236 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file alone_decoder.c
+/// \brief Decoder for LZMA_Alone files
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "alone_decoder.h"
+#include "lzma_decoder.h"
+#include "lz_decoder.h"
+
+
+struct lzma_coder_s {
+ lzma_next_coder next;
+
+ enum {
+ SEQ_PROPERTIES,
+ SEQ_DICTIONARY_SIZE,
+ SEQ_UNCOMPRESSED_SIZE,
+ SEQ_CODER_INIT,
+ SEQ_CODE,
+ } sequence;
+
+ /// If true, reject files that are unlikely to be .lzma files.
+ /// If false, more non-.lzma files get accepted and will give
+ /// LZMA_DATA_ERROR either immediately or after a few output bytes.
+ bool picky;
+
+ /// Position in the header fields
+ size_t pos;
+
+ /// Uncompressed size decoded from the header
+ lzma_vli uncompressed_size;
+
+ /// Memory usage limit
+ uint64_t memlimit;
+
+ /// Amount of memory actually needed (only an estimate)
+ uint64_t memusage;
+
+ /// Options decoded from the header needed to initialize
+ /// the LZMA decoder
+ lzma_options_lzma options;
+};
+
+
+static lzma_ret
+alone_decode(lzma_coder *coder,
+ lzma_allocator *allocator lzma_attribute((__unused__)),
+ const uint8_t *LZMA_RESTRICT in, size_t *LZMA_RESTRICT in_pos,
+ size_t in_size, uint8_t *LZMA_RESTRICT out,
+ size_t *LZMA_RESTRICT out_pos, size_t out_size,
+ lzma_action action)
+{
+ while (*out_pos < out_size
+ && (coder->sequence == SEQ_CODE || *in_pos < in_size))
+ switch (coder->sequence) {
+ case SEQ_PROPERTIES:
+ if (lzma_lzma_lclppb_decode(&coder->options, in[*in_pos]))
+ return LZMA_FORMAT_ERROR;
+
+ coder->sequence = SEQ_DICTIONARY_SIZE;
+ ++*in_pos;
+ break;
+
+ case SEQ_DICTIONARY_SIZE:
+ coder->options.dict_size
+ |= (size_t)(in[*in_pos]) << (coder->pos * 8);
+
+ if (++coder->pos == 4) {
+ if (coder->picky && coder->options.dict_size
+ != UINT32_MAX) {
+ // A hack to ditch tons of false positives:
+ // We allow only dictionary sizes that are
+ // 2^n or 2^n + 2^(n-1). LZMA_Alone created
+ // only files with 2^n, but accepts any
+ // dictionary size.
+ uint32_t d = coder->options.dict_size - 1;
+ d |= d >> 2;
+ d |= d >> 3;
+ d |= d >> 4;
+ d |= d >> 8;
+ d |= d >> 16;
+ ++d;
+
+ if (d != coder->options.dict_size)
+ return LZMA_FORMAT_ERROR;
+ }
+
+ coder->pos = 0;
+ coder->sequence = SEQ_UNCOMPRESSED_SIZE;
+ }
+
+ ++*in_pos;
+ break;
+
+ case SEQ_UNCOMPRESSED_SIZE:
+ coder->uncompressed_size
+ |= (lzma_vli)(in[*in_pos]) << (coder->pos * 8);
+ ++*in_pos;
+ if (++coder->pos < 8)
+ break;
+
+ // Another hack to ditch false positives: Assume that
+ // if the uncompressed size is known, it must be less
+ // than 256 GiB.
+ if (coder->picky
+ && coder->uncompressed_size != LZMA_VLI_UNKNOWN
+ && coder->uncompressed_size
+ >= (LZMA_VLI_C(1) << 38))
+ return LZMA_FORMAT_ERROR;
+
+ // Calculate the memory usage so that it is ready
+ // for SEQ_CODER_INIT.
+ coder->memusage = lzma_lzma_decoder_memusage(&coder->options)
+ + LZMA_MEMUSAGE_BASE;
+
+ coder->pos = 0;
+ coder->sequence = SEQ_CODER_INIT;
+
+ // Fall through
+
+ case SEQ_CODER_INIT: {
+ lzma_ret ret;
+
+ lzma_filter_info filters[2] = {
+ { 0, &lzma_lzma_decoder_init, &coder->options },
+ { 0, NULL, NULL }
+ };
+
+ if (coder->memusage > coder->memlimit)
+ return LZMA_MEMLIMIT_ERROR;
+
+ ret = lzma_next_filter_init(&coder->next,
+ allocator, filters);
+ if (ret != LZMA_OK)
+ return ret;
+
+ // Use a hack to set the uncompressed size.
+ lzma_lz_decoder_uncompressed(coder->next.coder,
+ coder->uncompressed_size);
+
+ coder->sequence = SEQ_CODE;
+ break;
+ }
+
+ case SEQ_CODE: {
+ return coder->next.code(coder->next.coder,
+ allocator, in, in_pos, in_size,
+ out, out_pos, out_size, action);
+ }
+
+ default:
+ return LZMA_PROG_ERROR;
+ }
+
+ return LZMA_OK;
+}
+
+
+static void
+alone_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
+{
+ lzma_next_end(&coder->next, allocator);
+ lzma_free(coder, allocator);
+ return;
+}
+
+
+static lzma_ret
+alone_decoder_memconfig(lzma_coder *coder, uint64_t *memusage,
+ uint64_t *old_memlimit, uint64_t new_memlimit)
+{
+ *memusage = coder->memusage;
+ *old_memlimit = coder->memlimit;
+
+ if (new_memlimit != 0) {
+ if (new_memlimit < coder->memusage)
+ return LZMA_MEMLIMIT_ERROR;
+
+ coder->memlimit = new_memlimit;
+ }
+
+ return LZMA_OK;
+}
+
+
+extern lzma_ret
+lzma_alone_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ uint64_t memlimit, bool picky)
+{
+ lzma_next_coder_init(&lzma_alone_decoder_init, next, allocator);
+
+ if (memlimit == 0)
+ return LZMA_PROG_ERROR;
+
+ if (next->coder == NULL) {
+ next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
+ if (next->coder == NULL)
+ return LZMA_MEM_ERROR;
+
+ next->code = &alone_decode;
+ next->end = &alone_decoder_end;
+ next->memconfig = &alone_decoder_memconfig;
+ next->coder->next = LZMA_NEXT_CODER_INIT;
+ }
+
+ next->coder->sequence = SEQ_PROPERTIES;
+ next->coder->picky = picky;
+ next->coder->pos = 0;
+ next->coder->options.dict_size = 0;
+ next->coder->options.preset_dict = NULL;
+ next->coder->options.preset_dict_size = 0;
+ next->coder->uncompressed_size = 0;
+ next->coder->memlimit = memlimit;
+ next->coder->memusage = LZMA_MEMUSAGE_BASE;
+
+ return LZMA_OK;
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_alone_decoder(lzma_stream *strm, uint64_t memlimit)
+{
+ lzma_next_strm_init2(lzma_alone_decoder_init, strm, memlimit, false);
+
+ strm->internal->supported_actions[LZMA_RUN] = true;
+ strm->internal->supported_actions[LZMA_FINISH] = true;
+
+ return LZMA_OK;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/alone_decoder.h b/Utilities/cmliblzma/liblzma/common/alone_decoder.h
new file mode 100644
index 000000000..f666fc382
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/alone_decoder.h
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file alone_decoder.h
+/// \brief Decoder for LZMA_Alone files
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_ALONE_DECODER_H
+#define LZMA_ALONE_DECODER_H
+
+#include "common.h"
+
+
+extern lzma_ret lzma_alone_decoder_init(
+ lzma_next_coder *next, lzma_allocator *allocator,
+ uint64_t memlimit, bool picky);
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/common/alone_encoder.c b/Utilities/cmliblzma/liblzma/common/alone_encoder.c
new file mode 100644
index 000000000..4207b4a52
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/alone_encoder.c
@@ -0,0 +1,155 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file alone_decoder.c
+/// \brief Decoder for LZMA_Alone files
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "common.h"
+#include "lzma_encoder.h"
+
+
+#define ALONE_HEADER_SIZE (1 + 4 + 8)
+
+
+struct lzma_coder_s {
+ lzma_next_coder next;
+
+ enum {
+ SEQ_HEADER,
+ SEQ_CODE,
+ } sequence;
+
+ size_t header_pos;
+ uint8_t header[ALONE_HEADER_SIZE];
+};
+
+
+static lzma_ret
+alone_encode(lzma_coder *coder,
+ lzma_allocator *allocator lzma_attribute((__unused__)),
+ const uint8_t *LZMA_RESTRICT in, size_t *LZMA_RESTRICT in_pos,
+ size_t in_size, uint8_t *LZMA_RESTRICT out,
+ size_t *LZMA_RESTRICT out_pos, size_t out_size,
+ lzma_action action)
+{
+ while (*out_pos < out_size)
+ switch (coder->sequence) {
+ case SEQ_HEADER:
+ lzma_bufcpy(coder->header, &coder->header_pos,
+ ALONE_HEADER_SIZE,
+ out, out_pos, out_size);
+ if (coder->header_pos < ALONE_HEADER_SIZE)
+ return LZMA_OK;
+
+ coder->sequence = SEQ_CODE;
+ break;
+
+ case SEQ_CODE:
+ return coder->next.code(coder->next.coder,
+ allocator, in, in_pos, in_size,
+ out, out_pos, out_size, action);
+
+ default:
+ assert(0);
+ return LZMA_PROG_ERROR;
+ }
+
+ return LZMA_OK;
+}
+
+
+static void
+alone_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
+{
+ lzma_next_end(&coder->next, allocator);
+ lzma_free(coder, allocator);
+ return;
+}
+
+
+// At least for now, this is not used by any internal function.
+static lzma_ret
+alone_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_options_lzma *options)
+{
+ uint32_t d;
+
+ // Initialize the LZMA encoder.
+ const lzma_filter_info filters[2] = {
+ { 0, &lzma_lzma_encoder_init, (void *)(options) },
+ { 0, NULL, NULL }
+ };
+
+ lzma_next_coder_init(&alone_encoder_init, next, allocator);
+
+ if (next->coder == NULL) {
+ next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
+ if (next->coder == NULL)
+ return LZMA_MEM_ERROR;
+
+ next->code = &alone_encode;
+ next->end = &alone_encoder_end;
+ next->coder->next = LZMA_NEXT_CODER_INIT;
+ }
+
+ // Basic initializations
+ next->coder->sequence = SEQ_HEADER;
+ next->coder->header_pos = 0;
+
+ // Encode the header:
+ // - Properties (1 byte)
+ if (lzma_lzma_lclppb_encode(options, next->coder->header))
+ return LZMA_OPTIONS_ERROR;
+
+ // - Dictionary size (4 bytes)
+ if (options->dict_size < LZMA_DICT_SIZE_MIN)
+ return LZMA_OPTIONS_ERROR;
+
+ // Round up to the next 2^n or 2^n + 2^(n - 1) depending on which
+ // one is the next unless it is UINT32_MAX. While the header would
+ // allow any 32-bit integer, we do this to keep the decoder of liblzma
+ // accepting the resulting files.
+ d = options->dict_size - 1;
+ d |= d >> 2;
+ d |= d >> 3;
+ d |= d >> 4;
+ d |= d >> 8;
+ d |= d >> 16;
+ if (d != UINT32_MAX)
+ ++d;
+
+ unaligned_write32le(next->coder->header + 1, d);
+
+ // - Uncompressed size (always unknown and using EOPM)
+ memset(next->coder->header + 1 + 4, 0xFF, 8);
+
+ return lzma_next_filter_init(&next->coder->next, allocator, filters);
+}
+
+
+/*
+extern lzma_ret
+lzma_alone_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_options_alone *options)
+{
+ lzma_next_coder_init(&alone_encoder_init, next, allocator, options);
+}
+*/
+
+
+extern LZMA_API(lzma_ret)
+lzma_alone_encoder(lzma_stream *strm, const lzma_options_lzma *options)
+{
+ lzma_next_strm_init1(alone_encoder_init, strm, options);
+
+ strm->internal->supported_actions[LZMA_RUN] = true;
+ strm->internal->supported_actions[LZMA_FINISH] = true;
+
+ return LZMA_OK;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/auto_decoder.c b/Utilities/cmliblzma/liblzma/common/auto_decoder.c
new file mode 100644
index 000000000..24cf48905
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/auto_decoder.c
@@ -0,0 +1,186 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file auto_decoder.c
+/// \brief Autodetect between .xz Stream and .lzma (LZMA_Alone) formats
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "stream_decoder.h"
+#include "alone_decoder.h"
+
+
+struct lzma_coder_s {
+ /// Stream decoder or LZMA_Alone decoder
+ lzma_next_coder next;
+
+ uint64_t memlimit;
+ uint32_t flags;
+
+ enum {
+ SEQ_INIT,
+ SEQ_CODE,
+ SEQ_FINISH,
+ } sequence;
+};
+
+
+static lzma_ret
+auto_decode(lzma_coder *coder, lzma_allocator *allocator,
+ const uint8_t *LZMA_RESTRICT in, size_t *LZMA_RESTRICT in_pos,
+ size_t in_size, uint8_t *LZMA_RESTRICT out,
+ size_t *LZMA_RESTRICT out_pos, size_t out_size, lzma_action action)
+{
+ switch (coder->sequence) {
+ case SEQ_INIT:
+ if (*in_pos >= in_size)
+ return LZMA_OK;
+
+ // Update the sequence now, because we want to continue from
+ // SEQ_CODE even if we return some LZMA_*_CHECK.
+ coder->sequence = SEQ_CODE;
+
+ // Detect the file format. For now this is simple, since if
+ // it doesn't start with 0xFD (the first magic byte of the
+ // new format), it has to be LZMA_Alone, or something that
+ // we don't support at all.
+ if (in[*in_pos] == 0xFD) {
+ return_if_error(lzma_stream_decoder_init(
+ &coder->next, allocator,
+ coder->memlimit, coder->flags));
+ } else {
+ return_if_error(lzma_alone_decoder_init(&coder->next,
+ allocator, coder->memlimit, true));
+
+ // If the application wants to know about missing
+ // integrity check or about the check in general, we
+ // need to handle it here, because LZMA_Alone decoder
+ // doesn't accept any flags.
+ if (coder->flags & LZMA_TELL_NO_CHECK)
+ return LZMA_NO_CHECK;
+
+ if (coder->flags & LZMA_TELL_ANY_CHECK)
+ return LZMA_GET_CHECK;
+ }
+
+ // Fall through
+
+ case SEQ_CODE: {
+ const lzma_ret ret = coder->next.code(
+ coder->next.coder, allocator,
+ in, in_pos, in_size,
+ out, out_pos, out_size, action);
+ if (ret != LZMA_STREAM_END
+ || (coder->flags & LZMA_CONCATENATED) == 0)
+ return ret;
+
+ coder->sequence = SEQ_FINISH;
+ }
+
+ // Fall through
+
+ case SEQ_FINISH:
+ // When LZMA_DECODE_CONCATENATED was used and we were decoding
+ // LZMA_Alone file, we need to check check that there is no
+ // trailing garbage and wait for LZMA_FINISH.
+ if (*in_pos < in_size)
+ return LZMA_DATA_ERROR;
+
+ return action == LZMA_FINISH ? LZMA_STREAM_END : LZMA_OK;
+
+ default:
+ assert(0);
+ return LZMA_PROG_ERROR;
+ }
+}
+
+
+static void
+auto_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
+{
+ lzma_next_end(&coder->next, allocator);
+ lzma_free(coder, allocator);
+ return;
+}
+
+
+static lzma_check
+auto_decoder_get_check(const lzma_coder *coder)
+{
+ // It is LZMA_Alone if get_check is NULL.
+ return coder->next.get_check == NULL ? LZMA_CHECK_NONE
+ : coder->next.get_check(coder->next.coder);
+}
+
+
+static lzma_ret
+auto_decoder_memconfig(lzma_coder *coder, uint64_t *memusage,
+ uint64_t *old_memlimit, uint64_t new_memlimit)
+{
+ lzma_ret ret;
+
+ if (coder->next.memconfig != NULL) {
+ ret = coder->next.memconfig(coder->next.coder,
+ memusage, old_memlimit, new_memlimit);
+ assert(*old_memlimit == coder->memlimit);
+ } else {
+ // No coder is configured yet. Use the base value as
+ // the current memory usage.
+ *memusage = LZMA_MEMUSAGE_BASE;
+ *old_memlimit = coder->memlimit;
+ ret = LZMA_OK;
+ }
+
+ if (ret == LZMA_OK && new_memlimit != 0)
+ coder->memlimit = new_memlimit;
+
+ return ret;
+}
+
+
+static lzma_ret
+auto_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ uint64_t memlimit, uint32_t flags)
+{
+ lzma_next_coder_init(&auto_decoder_init, next, allocator);
+
+ if (memlimit == 0)
+ return LZMA_PROG_ERROR;
+
+ if (flags & ~LZMA_SUPPORTED_FLAGS)
+ return LZMA_OPTIONS_ERROR;
+
+ if (next->coder == NULL) {
+ next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
+ if (next->coder == NULL)
+ return LZMA_MEM_ERROR;
+
+ next->code = &auto_decode;
+ next->end = &auto_decoder_end;
+ next->get_check = &auto_decoder_get_check;
+ next->memconfig = &auto_decoder_memconfig;
+ next->coder->next = LZMA_NEXT_CODER_INIT;
+ }
+
+ next->coder->memlimit = memlimit;
+ next->coder->flags = flags;
+ next->coder->sequence = SEQ_INIT;
+
+ return LZMA_OK;
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_auto_decoder(lzma_stream *strm, uint64_t memlimit, uint32_t flags)
+{
+ lzma_next_strm_init2(auto_decoder_init, strm, memlimit, flags);
+
+ strm->internal->supported_actions[LZMA_RUN] = true;
+ strm->internal->supported_actions[LZMA_FINISH] = true;
+
+ return LZMA_OK;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/block_buffer_decoder.c b/Utilities/cmliblzma/liblzma/common/block_buffer_decoder.c
new file mode 100644
index 000000000..b4bd388eb
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/block_buffer_decoder.c
@@ -0,0 +1,82 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file block_buffer_decoder.c
+/// \brief Single-call .xz Block decoder
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "block_decoder.h"
+
+
+extern LZMA_API(lzma_ret)
+lzma_block_buffer_decode(lzma_block *block, lzma_allocator *allocator,
+ const uint8_t *in, size_t *in_pos, size_t in_size,
+ uint8_t *out, size_t *out_pos, size_t out_size)
+{
+ lzma_next_coder block_decoder;
+ lzma_ret ret;
+
+ if (in_pos == NULL || (in == NULL && *in_pos != in_size)
+ || *in_pos > in_size || out_pos == NULL
+ || (out == NULL && *out_pos != out_size)
+ || *out_pos > out_size)
+ return LZMA_PROG_ERROR;
+
+ // Initialize the Block decoder.
+ block_decoder = LZMA_NEXT_CODER_INIT;
+ ret = lzma_block_decoder_init(&block_decoder, allocator, block);
+
+ if (ret == LZMA_OK) {
+ // Save the positions so that we can restore them in case
+ // an error occurs.
+ const size_t in_start = *in_pos;
+ const size_t out_start = *out_pos;
+
+ // Do the actual decoding.
+ ret = block_decoder.code(block_decoder.coder, allocator,
+ in, in_pos, in_size, out, out_pos, out_size,
+ LZMA_FINISH);
+
+ if (ret == LZMA_STREAM_END) {
+ ret = LZMA_OK;
+ } else {
+ if (ret == LZMA_OK) {
+ // Either the input was truncated or the
+ // output buffer was too small.
+ assert(*in_pos == in_size
+ || *out_pos == out_size);
+
+ // If all the input was consumed, then the
+ // input is truncated, even if the output
+ // buffer is also full. This is because
+ // processing the last byte of the Block
+ // never produces output.
+ //
+ // NOTE: This assumption may break when new
+ // filters are added, if the end marker of
+ // the filter doesn't consume at least one
+ // complete byte.
+ if (*in_pos == in_size)
+ ret = LZMA_DATA_ERROR;
+ else
+ ret = LZMA_BUF_ERROR;
+ }
+
+ // Restore the positions.
+ *in_pos = in_start;
+ *out_pos = out_start;
+ }
+ }
+
+ // Free the decoder memory. This needs to be done even if
+ // initialization fails, because the internal API doesn't
+ // require the initialization function to free its memory on error.
+ lzma_next_end(&block_decoder, allocator);
+
+ return ret;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/block_buffer_encoder.c b/Utilities/cmliblzma/liblzma/common/block_buffer_encoder.c
new file mode 100644
index 000000000..136f7f573
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/block_buffer_encoder.c
@@ -0,0 +1,315 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file block_buffer_encoder.c
+/// \brief Single-call .xz Block encoder
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "block_encoder.h"
+#include "filter_encoder.h"
+#include "lzma2_encoder.h"
+#include "check.h"
+
+
+/// Estimate the maximum size of the Block Header and Check fields for
+/// a Block that uses LZMA2 uncompressed chunks. We could use
+/// lzma_block_header_size() but this is simpler.
+///
+/// Block Header Size + Block Flags + Compressed Size
+/// + Uncompressed Size + Filter Flags for LZMA2 + CRC32 + Check
+/// and round up to the next multiple of four to take Header Padding
+/// into account.
+#define HEADERS_BOUND ((1 + 1 + 2 * LZMA_VLI_BYTES_MAX + 3 + 4 \
+ + LZMA_CHECK_SIZE_MAX + 3) & ~3)
+
+
+static lzma_vli
+lzma2_bound(lzma_vli uncompressed_size)
+{
+ lzma_vli overhead;
+
+ // Prevent integer overflow in overhead calculation.
+ if (uncompressed_size > COMPRESSED_SIZE_MAX)
+ return 0;
+
+ // Calculate the exact overhead of the LZMA2 headers: Round
+ // uncompressed_size up to the next multiple of LZMA2_CHUNK_MAX,
+ // multiply by the size of per-chunk header, and add one byte for
+ // the end marker.
+ overhead = ((uncompressed_size + LZMA2_CHUNK_MAX - 1)
+ / LZMA2_CHUNK_MAX)
+ * LZMA2_HEADER_UNCOMPRESSED + 1;
+
+ // Catch the possible integer overflow.
+ if (COMPRESSED_SIZE_MAX - overhead < uncompressed_size)
+ return 0;
+
+ return uncompressed_size + overhead;
+}
+
+
+extern LZMA_API(size_t)
+lzma_block_buffer_bound(size_t uncompressed_size)
+{
+ // For now, if the data doesn't compress, we always use uncompressed
+ // chunks of LZMA2. In future we may use Subblock filter too, but
+ // but for simplicity we probably will still use the same bound
+ // calculation even though Subblock filter would have slightly less
+ // overhead.
+ lzma_vli lzma2_size = lzma2_bound(uncompressed_size);
+ if (lzma2_size == 0)
+ return 0;
+
+ // Take Block Padding into account.
+ lzma2_size = (lzma2_size + 3) & ~LZMA_VLI_C(3);
+
+#if SIZE_MAX < LZMA_VLI_MAX
+ // Catch the possible integer overflow on 32-bit systems. There's no
+ // overflow on 64-bit systems, because lzma2_bound() already takes
+ // into account the size of the headers in the Block.
+ if (SIZE_MAX - HEADERS_BOUND < lzma2_size)
+ return 0;
+#endif
+
+ return HEADERS_BOUND + lzma2_size;
+}
+
+
+static lzma_ret
+block_encode_uncompressed(lzma_block *block, const uint8_t *in, size_t in_size,
+ uint8_t *out, size_t *out_pos, size_t out_size)
+{
+ size_t in_pos = 0;
+ uint8_t control = 0x01; // Dictionary reset
+ lzma_filter *filters_orig;
+
+ // TODO: Figure out if the last filter is LZMA2 or Subblock and use
+ // that filter to encode the uncompressed chunks.
+
+ // Use LZMA2 uncompressed chunks. We wouldn't need a dictionary at
+ // all, but LZMA2 always requires a dictionary, so use the minimum
+ // value to minimize memory usage of the decoder.
+ lzma_options_lzma lzma2 = { LZMA_DICT_SIZE_MIN };
+
+ lzma_filter filters[2];
+ filters[0].id = LZMA_FILTER_LZMA2;
+ filters[0].options = &lzma2;
+ filters[1].id = LZMA_VLI_UNKNOWN;
+
+ // Set the above filter options to *block temporarily so that we can
+ // encode the Block Header.
+ filters_orig = block->filters;
+ block->filters = filters;
+
+ if (lzma_block_header_size(block) != LZMA_OK) {
+ block->filters = filters_orig;
+ return LZMA_PROG_ERROR;
+ }
+
+ // Check that there's enough output space. The caller has already
+ // set block->compressed_size to what lzma2_bound() has returned,
+ // so we can reuse that value. We know that compressed_size is a
+ // known valid VLI and header_size is a small value so their sum
+ // will never overflow.
+ assert(block->compressed_size == lzma2_bound(in_size));
+ if (out_size - *out_pos
+ < block->header_size + block->compressed_size) {
+ block->filters = filters_orig;
+ return LZMA_BUF_ERROR;
+ }
+
+ if (lzma_block_header_encode(block, out + *out_pos) != LZMA_OK) {
+ block->filters = filters_orig;
+ return LZMA_PROG_ERROR;
+ }
+
+ block->filters = filters_orig;
+ *out_pos += block->header_size;
+
+ // Encode the data using LZMA2 uncompressed chunks.
+
+ while (in_pos < in_size) {
+ size_t copy_size;
+
+ // Control byte: Indicate uncompressed chunk, of which
+ // the first resets the dictionary.
+ out[(*out_pos)++] = control;
+ control = 0x02; // No dictionary reset
+
+ // Size of the uncompressed chunk
+ copy_size = my_min(in_size - in_pos, LZMA2_CHUNK_MAX);
+ out[(*out_pos)++] = (copy_size - 1) >> 8;
+ out[(*out_pos)++] = (copy_size - 1) & 0xFF;
+
+ // The actual data
+ assert(*out_pos + copy_size <= out_size);
+ memcpy(out + *out_pos, in + in_pos, copy_size);
+
+ in_pos += copy_size;
+ *out_pos += copy_size;
+ }
+
+ // End marker
+ out[(*out_pos)++] = 0x00;
+ assert(*out_pos <= out_size);
+
+ return LZMA_OK;
+}
+
+
+static lzma_ret
+block_encode_normal(lzma_block *block, lzma_allocator *allocator,
+ const uint8_t *in, size_t in_size,
+ uint8_t *out, size_t *out_pos, size_t out_size)
+{
+ size_t out_start;
+ lzma_next_coder raw_encoder = LZMA_NEXT_CODER_INIT;
+ lzma_ret ret;
+
+ // Find out the size of the Block Header.
+ block->compressed_size = lzma2_bound(in_size);
+ if (block->compressed_size == 0)
+ return LZMA_DATA_ERROR;
+
+ block->uncompressed_size = in_size;
+ return_if_error(lzma_block_header_size(block));
+
+ // Reserve space for the Block Header and skip it for now.
+ if (out_size - *out_pos <= block->header_size)
+ return LZMA_BUF_ERROR;
+
+ out_start = *out_pos;
+ *out_pos += block->header_size;
+
+ // Limit out_size so that we stop encoding if the output would grow
+ // bigger than what uncompressed Block would be.
+ if (out_size - *out_pos > block->compressed_size)
+ out_size = *out_pos + block->compressed_size;
+
+ // TODO: In many common cases this could be optimized to use
+ // significantly less memory.
+ ret = lzma_raw_encoder_init(
+ &raw_encoder, allocator, block->filters);
+
+ if (ret == LZMA_OK) {
+ size_t in_pos = 0;
+ ret = raw_encoder.code(raw_encoder.coder, allocator,
+ in, &in_pos, in_size, out, out_pos, out_size,
+ LZMA_FINISH);
+ }
+
+ // NOTE: This needs to be run even if lzma_raw_encoder_init() failed.
+ lzma_next_end(&raw_encoder, allocator);
+
+ if (ret == LZMA_STREAM_END) {
+ // Compression was successful. Write the Block Header.
+ block->compressed_size
+ = *out_pos - (out_start + block->header_size);
+ ret = lzma_block_header_encode(block, out + out_start);
+ if (ret != LZMA_OK)
+ ret = LZMA_PROG_ERROR;
+
+ } else if (ret == LZMA_OK) {
+ // Output buffer became full.
+ ret = LZMA_BUF_ERROR;
+ }
+
+ // Reset *out_pos if something went wrong.
+ if (ret != LZMA_OK)
+ *out_pos = out_start;
+
+ return ret;
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_block_buffer_encode(lzma_block *block, lzma_allocator *allocator,
+ const uint8_t *in, size_t in_size,
+ uint8_t *out, size_t *out_pos, size_t out_size)
+{
+ size_t check_size;
+ lzma_ret ret;
+ size_t i;
+
+ // Validate the arguments.
+ if (block == NULL || (in == NULL && in_size != 0) || out == NULL
+ || out_pos == NULL || *out_pos > out_size)
+ return LZMA_PROG_ERROR;
+
+ // The contents of the structure may depend on the version so
+ // check the version before validating the contents of *block.
+ if (block->version != 0)
+ return LZMA_OPTIONS_ERROR;
+
+ if ((unsigned int)(block->check) > LZMA_CHECK_ID_MAX
+ || block->filters == NULL)
+ return LZMA_PROG_ERROR;
+
+ if (!lzma_check_is_supported(block->check))
+ return LZMA_UNSUPPORTED_CHECK;
+
+ // Size of a Block has to be a multiple of four, so limit the size
+ // here already. This way we don't need to check it again when adding
+ // Block Padding.
+ out_size -= (out_size - *out_pos) & 3;
+
+ // Get the size of the Check field.
+ check_size = lzma_check_size(block->check);
+ assert(check_size != UINT32_MAX);
+
+ // Reserve space for the Check field.
+ if (out_size - *out_pos <= check_size)
+ return LZMA_BUF_ERROR;
+
+ out_size -= check_size;
+
+ // Do the actual compression.
+ ret = block_encode_normal(block, allocator,
+ in, in_size, out, out_pos, out_size);
+ if (ret != LZMA_OK) {
+ // If the error was something else than output buffer
+ // becoming full, return the error now.
+ if (ret != LZMA_BUF_ERROR)
+ return ret;
+
+ // The data was uncompressible (at least with the options
+ // given to us) or the output buffer was too small. Use the
+ // uncompressed chunks of LZMA2 to wrap the data into a valid
+ // Block. If we haven't been given enough output space, even
+ // this may fail.
+ return_if_error(block_encode_uncompressed(block, in, in_size,
+ out, out_pos, out_size));
+ }
+
+ assert(*out_pos <= out_size);
+
+ // Block Padding. No buffer overflow here, because we already adjusted
+ // out_size so that (out_size - out_start) is a multiple of four.
+ // Thus, if the buffer is full, the loop body can never run.
+ for (i = (size_t)(block->compressed_size); i & 3; ++i) {
+ assert(*out_pos < out_size);
+ out[(*out_pos)++] = 0x00;
+ }
+
+ // If there's no Check field, we are done now.
+ if (check_size > 0) {
+ // Calculate the integrity check. We reserved space for
+ // the Check field earlier so we don't need to check for
+ // available output space here.
+ lzma_check_state check;
+ lzma_check_init(&check, block->check);
+ lzma_check_update(&check, block->check, in, in_size);
+ lzma_check_finish(&check, block->check);
+
+ memcpy(block->raw_check, check.buffer.u8, check_size);
+ memcpy(out + *out_pos, check.buffer.u8, check_size);
+ *out_pos += check_size;
+ }
+
+ return LZMA_OK;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/block_decoder.c b/Utilities/cmliblzma/liblzma/common/block_decoder.c
new file mode 100644
index 000000000..35996e7cf
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/block_decoder.c
@@ -0,0 +1,242 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file block_decoder.c
+/// \brief Decodes .xz Blocks
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "block_decoder.h"
+#include "filter_decoder.h"
+#include "check.h"
+
+
+struct lzma_coder_s {
+ enum {
+ SEQ_CODE,
+ SEQ_PADDING,
+ SEQ_CHECK,
+ } sequence;
+
+ /// The filters in the chain; initialized with lzma_raw_decoder_init().
+ lzma_next_coder next;
+
+ /// Decoding options; we also write Compressed Size and Uncompressed
+ /// Size back to this structure when the decoding has been finished.
+ lzma_block *block;
+
+ /// Compressed Size calculated while decoding
+ lzma_vli compressed_size;
+
+ /// Uncompressed Size calculated while decoding
+ lzma_vli uncompressed_size;
+
+ /// Maximum allowed Compressed Size; this takes into account the
+ /// size of the Block Header and Check fields when Compressed Size
+ /// is unknown.
+ lzma_vli compressed_limit;
+
+ /// Position when reading the Check field
+ size_t check_pos;
+
+ /// Check of the uncompressed data
+ lzma_check_state check;
+};
+
+
+static inline bool
+update_size(lzma_vli *size, lzma_vli add, lzma_vli limit)
+{
+ if (limit > LZMA_VLI_MAX)
+ limit = LZMA_VLI_MAX;
+
+ if (limit < *size || limit - *size < add)
+ return true;
+
+ *size += add;
+
+ return false;
+}
+
+
+static inline bool
+is_size_valid(lzma_vli size, lzma_vli reference)
+{
+ return reference == LZMA_VLI_UNKNOWN || reference == size;
+}
+
+
+static lzma_ret
+block_decode(lzma_coder *coder, lzma_allocator *allocator,
+ const uint8_t *LZMA_RESTRICT in, size_t *LZMA_RESTRICT in_pos,
+ size_t in_size, uint8_t *LZMA_RESTRICT out,
+ size_t *LZMA_RESTRICT out_pos, size_t out_size, lzma_action action)
+{
+ switch (coder->sequence) {
+ case SEQ_CODE: {
+ const size_t in_start = *in_pos;
+ const size_t out_start = *out_pos;
+
+ const lzma_ret ret = coder->next.code(coder->next.coder,
+ allocator, in, in_pos, in_size,
+ out, out_pos, out_size, action);
+
+ const size_t in_used = *in_pos - in_start;
+ const size_t out_used = *out_pos - out_start;
+
+ // NOTE: We compare to compressed_limit here, which prevents
+ // the total size of the Block growing past LZMA_VLI_MAX.
+ if (update_size(&coder->compressed_size, in_used,
+ coder->compressed_limit)
+ || update_size(&coder->uncompressed_size,
+ out_used,
+ coder->block->uncompressed_size))
+ return LZMA_DATA_ERROR;
+
+ lzma_check_update(&coder->check, coder->block->check,
+ out + out_start, out_used);
+
+ if (ret != LZMA_STREAM_END)
+ return ret;
+
+ // Compressed and Uncompressed Sizes are now at their final
+ // values. Verify that they match the values given to us.
+ if (!is_size_valid(coder->compressed_size,
+ coder->block->compressed_size)
+ || !is_size_valid(coder->uncompressed_size,
+ coder->block->uncompressed_size))
+ return LZMA_DATA_ERROR;
+
+ // Copy the values into coder->block. The caller
+ // may use this information to construct Index.
+ coder->block->compressed_size = coder->compressed_size;
+ coder->block->uncompressed_size = coder->uncompressed_size;
+
+ coder->sequence = SEQ_PADDING;
+ }
+
+ // Fall through
+
+ case SEQ_PADDING:
+ // Compressed Data is padded to a multiple of four bytes.
+ while (coder->compressed_size & 3) {
+ if (*in_pos >= in_size)
+ return LZMA_OK;
+
+ // We use compressed_size here just get the Padding
+ // right. The actual Compressed Size was stored to
+ // coder->block already, and won't be modified by
+ // us anymore.
+ ++coder->compressed_size;
+
+ if (in[(*in_pos)++] != 0x00)
+ return LZMA_DATA_ERROR;
+ }
+
+ if (coder->block->check == LZMA_CHECK_NONE)
+ return LZMA_STREAM_END;
+
+ lzma_check_finish(&coder->check, coder->block->check);
+ coder->sequence = SEQ_CHECK;
+
+ // Fall through
+
+ case SEQ_CHECK: {
+ const size_t check_size = lzma_check_size(coder->block->check);
+ lzma_bufcpy(in, in_pos, in_size, coder->block->raw_check,
+ &coder->check_pos, check_size);
+ if (coder->check_pos < check_size)
+ return LZMA_OK;
+
+ // Validate the Check only if we support it.
+ // coder->check.buffer may be uninitialized
+ // when the Check ID is not supported.
+ if (lzma_check_is_supported(coder->block->check)
+ && memcmp(coder->block->raw_check,
+ coder->check.buffer.u8,
+ check_size) != 0)
+ return LZMA_DATA_ERROR;
+
+ return LZMA_STREAM_END;
+ }
+ }
+
+ return LZMA_PROG_ERROR;
+}
+
+
+static void
+block_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
+{
+ lzma_next_end(&coder->next, allocator);
+ lzma_free(coder, allocator);
+ return;
+}
+
+
+extern lzma_ret
+lzma_block_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ lzma_block *block)
+{
+ lzma_next_coder_init(&lzma_block_decoder_init, next, allocator);
+
+ // Validate the options. lzma_block_unpadded_size() does that for us
+ // except for Uncompressed Size and filters. Filters are validated
+ // by the raw decoder.
+ if (lzma_block_unpadded_size(block) == 0
+ || !lzma_vli_is_valid(block->uncompressed_size))
+ return LZMA_PROG_ERROR;
+
+ // Allocate and initialize *next->coder if needed.
+ if (next->coder == NULL) {
+ next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
+ if (next->coder == NULL)
+ return LZMA_MEM_ERROR;
+
+ next->code = &block_decode;
+ next->end = &block_decoder_end;
+ next->coder->next = LZMA_NEXT_CODER_INIT;
+ }
+
+ // Basic initializations
+ next->coder->sequence = SEQ_CODE;
+ next->coder->block = block;
+ next->coder->compressed_size = 0;
+ next->coder->uncompressed_size = 0;
+
+ // If Compressed Size is not known, we calculate the maximum allowed
+ // value so that encoded size of the Block (including Block Padding)
+ // is still a valid VLI and a multiple of four.
+ next->coder->compressed_limit
+ = block->compressed_size == LZMA_VLI_UNKNOWN
+ ? (LZMA_VLI_MAX & ~LZMA_VLI_C(3))
+ - block->header_size
+ - lzma_check_size(block->check)
+ : block->compressed_size;
+
+ // Initialize the check. It's caller's problem if the Check ID is not
+ // supported, and the Block decoder cannot verify the Check field.
+ // Caller can test lzma_check_is_supported(block->check).
+ next->coder->check_pos = 0;
+ lzma_check_init(&next->coder->check, block->check);
+
+ // Initialize the filter chain.
+ return lzma_raw_decoder_init(&next->coder->next, allocator,
+ block->filters);
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_block_decoder(lzma_stream *strm, lzma_block *block)
+{
+ lzma_next_strm_init1(lzma_block_decoder_init, strm, block);
+
+ strm->internal->supported_actions[LZMA_RUN] = true;
+ strm->internal->supported_actions[LZMA_FINISH] = true;
+
+ return LZMA_OK;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/block_decoder.h b/Utilities/cmliblzma/liblzma/common/block_decoder.h
new file mode 100644
index 000000000..7da9df63f
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/block_decoder.h
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file block_decoder.h
+/// \brief Decodes .xz Blocks
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_BLOCK_DECODER_H
+#define LZMA_BLOCK_DECODER_H
+
+#include "common.h"
+
+
+extern lzma_ret lzma_block_decoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, lzma_block *block);
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/common/block_encoder.c b/Utilities/cmliblzma/liblzma/common/block_encoder.c
new file mode 100644
index 000000000..ed748273e
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/block_encoder.c
@@ -0,0 +1,217 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file block_encoder.c
+/// \brief Encodes .xz Blocks
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "block_encoder.h"
+#include "filter_encoder.h"
+#include "check.h"
+
+
+struct lzma_coder_s {
+ /// The filters in the chain; initialized with lzma_raw_decoder_init().
+ lzma_next_coder next;
+
+ /// Encoding options; we also write Unpadded Size, Compressed Size,
+ /// and Uncompressed Size back to this structure when the encoding
+ /// has been finished.
+ lzma_block *block;
+
+ enum {
+ SEQ_CODE,
+ SEQ_PADDING,
+ SEQ_CHECK,
+ } sequence;
+
+ /// Compressed Size calculated while encoding
+ lzma_vli compressed_size;
+
+ /// Uncompressed Size calculated while encoding
+ lzma_vli uncompressed_size;
+
+ /// Position in the Check field
+ size_t pos;
+
+ /// Check of the uncompressed data
+ lzma_check_state check;
+};
+
+
+static lzma_ret
+block_encode(lzma_coder *coder, lzma_allocator *allocator,
+ const uint8_t *LZMA_RESTRICT in, size_t *LZMA_RESTRICT in_pos,
+ size_t in_size, uint8_t *LZMA_RESTRICT out,
+ size_t *LZMA_RESTRICT out_pos, size_t out_size, lzma_action action)
+{
+ // Check that our amount of input stays in proper limits.
+ if (LZMA_VLI_MAX - coder->uncompressed_size < in_size - *in_pos)
+ return LZMA_DATA_ERROR;
+
+ switch (coder->sequence) {
+ case SEQ_CODE: {
+ const size_t in_start = *in_pos;
+ const size_t out_start = *out_pos;
+
+ const lzma_ret ret = coder->next.code(coder->next.coder,
+ allocator, in, in_pos, in_size,
+ out, out_pos, out_size, action);
+
+ const size_t in_used = *in_pos - in_start;
+ const size_t out_used = *out_pos - out_start;
+
+ if (COMPRESSED_SIZE_MAX - coder->compressed_size < out_used)
+ return LZMA_DATA_ERROR;
+
+ coder->compressed_size += out_used;
+
+ // No need to check for overflow because we have already
+ // checked it at the beginning of this function.
+ coder->uncompressed_size += in_used;
+
+ lzma_check_update(&coder->check, coder->block->check,
+ in + in_start, in_used);
+
+ if (ret != LZMA_STREAM_END || action == LZMA_SYNC_FLUSH)
+ return ret;
+
+ assert(*in_pos == in_size);
+ assert(action == LZMA_FINISH);
+
+ // Copy the values into coder->block. The caller
+ // may use this information to construct Index.
+ coder->block->compressed_size = coder->compressed_size;
+ coder->block->uncompressed_size = coder->uncompressed_size;
+
+ coder->sequence = SEQ_PADDING;
+ }
+
+ // Fall through
+
+ case SEQ_PADDING:
+ // Pad Compressed Data to a multiple of four bytes. We can
+ // use coder->compressed_size for this since we don't need
+ // it for anything else anymore.
+ while (coder->compressed_size & 3) {
+ if (*out_pos >= out_size)
+ return LZMA_OK;
+
+ out[*out_pos] = 0x00;
+ ++*out_pos;
+ ++coder->compressed_size;
+ }
+
+ if (coder->block->check == LZMA_CHECK_NONE)
+ return LZMA_STREAM_END;
+
+ lzma_check_finish(&coder->check, coder->block->check);
+
+ coder->sequence = SEQ_CHECK;
+
+ // Fall through
+
+ case SEQ_CHECK: {
+ const size_t check_size = lzma_check_size(coder->block->check);
+ lzma_bufcpy(coder->check.buffer.u8, &coder->pos, check_size,
+ out, out_pos, out_size);
+ if (coder->pos < check_size)
+ return LZMA_OK;
+
+ memcpy(coder->block->raw_check, coder->check.buffer.u8,
+ check_size);
+ return LZMA_STREAM_END;
+ }
+ }
+
+ return LZMA_PROG_ERROR;
+}
+
+
+static void
+block_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
+{
+ lzma_next_end(&coder->next, allocator);
+ lzma_free(coder, allocator);
+ return;
+}
+
+
+static lzma_ret
+block_encoder_update(lzma_coder *coder, lzma_allocator *allocator,
+ const lzma_filter *filters lzma_attribute((__unused__)),
+ const lzma_filter *reversed_filters)
+{
+ if (coder->sequence != SEQ_CODE)
+ return LZMA_PROG_ERROR;
+
+ return lzma_next_filter_update(
+ &coder->next, allocator, reversed_filters);
+}
+
+
+extern lzma_ret
+lzma_block_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ lzma_block *block)
+{
+ lzma_next_coder_init(&lzma_block_encoder_init, next, allocator);
+
+ if (block == NULL)
+ return LZMA_PROG_ERROR;
+
+ // The contents of the structure may depend on the version so
+ // check the version first.
+ if (block->version != 0)
+ return LZMA_OPTIONS_ERROR;
+
+ // If the Check ID is not supported, we cannot calculate the check and
+ // thus not create a proper Block.
+ if ((unsigned int)(block->check) > LZMA_CHECK_ID_MAX)
+ return LZMA_PROG_ERROR;
+
+ if (!lzma_check_is_supported(block->check))
+ return LZMA_UNSUPPORTED_CHECK;
+
+ // Allocate and initialize *next->coder if needed.
+ if (next->coder == NULL) {
+ next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
+ if (next->coder == NULL)
+ return LZMA_MEM_ERROR;
+
+ next->code = &block_encode;
+ next->end = &block_encoder_end;
+ next->update = &block_encoder_update;
+ next->coder->next = LZMA_NEXT_CODER_INIT;
+ }
+
+ // Basic initializations
+ next->coder->sequence = SEQ_CODE;
+ next->coder->block = block;
+ next->coder->compressed_size = 0;
+ next->coder->uncompressed_size = 0;
+ next->coder->pos = 0;
+
+ // Initialize the check
+ lzma_check_init(&next->coder->check, block->check);
+
+ // Initialize the requested filters.
+ return lzma_raw_encoder_init(&next->coder->next, allocator,
+ block->filters);
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_block_encoder(lzma_stream *strm, lzma_block *block)
+{
+ lzma_next_strm_init1(lzma_block_encoder_init, strm, block);
+
+ strm->internal->supported_actions[LZMA_RUN] = true;
+ strm->internal->supported_actions[LZMA_FINISH] = true;
+
+ return LZMA_OK;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/block_encoder.h b/Utilities/cmliblzma/liblzma/common/block_encoder.h
new file mode 100644
index 000000000..b9eff0be2
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/block_encoder.h
@@ -0,0 +1,47 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file block_encoder.h
+/// \brief Encodes .xz Blocks
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_BLOCK_ENCODER_H
+#define LZMA_BLOCK_ENCODER_H
+
+#include "common.h"
+
+
+/// \brief Biggest Compressed Size value that the Block encoder supports
+///
+/// The maximum size of a single Block is limited by the maximum size of
+/// a Stream, which in theory is 2^63 - 3 bytes (i.e. LZMA_VLI_MAX - 3).
+/// While the size is really big and no one should hit it in practice, we
+/// take it into account in some places anyway to catch some errors e.g. if
+/// application passes insanely big value to some function.
+///
+/// We could take into account the headers etc. to determine the exact
+/// maximum size of the Compressed Data field, but the complexity would give
+/// us nothing useful. Instead, limit the size of Compressed Data so that
+/// even with biggest possible Block Header and Check fields the total
+/// encoded size of the Block stays as a valid VLI. This doesn't guarantee
+/// that the size of the Stream doesn't grow too big, but that problem is
+/// taken care outside the Block handling code.
+///
+/// ~LZMA_VLI_C(3) is to guarantee that if we need padding at the end of
+/// the Compressed Data field, it will still stay in the proper limit.
+///
+/// This constant is in this file because it is needed in both
+/// block_encoder.c and block_buffer_encoder.c.
+#define COMPRESSED_SIZE_MAX ((LZMA_VLI_MAX - LZMA_BLOCK_HEADER_SIZE_MAX \
+ - LZMA_CHECK_SIZE_MAX) & ~LZMA_VLI_C(3))
+
+
+extern lzma_ret lzma_block_encoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, lzma_block *block);
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/common/block_header_decoder.c b/Utilities/cmliblzma/liblzma/common/block_header_decoder.c
new file mode 100644
index 000000000..f6e470e69
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/block_header_decoder.c
@@ -0,0 +1,121 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file block_header_decoder.c
+/// \brief Decodes Block Header from .xz files
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "common.h"
+#include "check.h"
+
+
+static void
+free_properties(lzma_block *block, lzma_allocator *allocator)
+{
+ size_t i;
+
+ // Free allocated filter options. The last array member is not
+ // touched after the initialization in the beginning of
+ // lzma_block_header_decode(), so we don't need to touch that here.
+ for (i = 0; i < LZMA_FILTERS_MAX; ++i) {
+ lzma_free(block->filters[i].options, allocator);
+ block->filters[i].id = LZMA_VLI_UNKNOWN;
+ block->filters[i].options = NULL;
+ }
+
+ return;
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_block_header_decode(lzma_block *block,
+ lzma_allocator *allocator, const uint8_t *in)
+{
+ const size_t filter_count = (in[1] & 3) + 1;
+ size_t in_size;
+ size_t i;
+
+ // Start after the Block Header Size and Block Flags fields.
+ size_t in_pos = 2;
+
+ // NOTE: We consider the header to be corrupt not only when the
+ // CRC32 doesn't match, but also when variable-length integers
+ // are invalid or over 63 bits, or if the header is too small
+ // to contain the claimed information.
+
+ // Initialize the filter options array. This way the caller can
+ // safely free() the options even if an error occurs in this function.
+ for (i = 0; i <= LZMA_FILTERS_MAX; ++i) {
+ block->filters[i].id = LZMA_VLI_UNKNOWN;
+ block->filters[i].options = NULL;
+ }
+
+ // Always zero for now.
+ block->version = 0;
+
+ // Validate Block Header Size and Check type. The caller must have
+ // already set these, so it is a programming error if this test fails.
+ if (lzma_block_header_size_decode(in[0]) != block->header_size
+ || (unsigned int)(block->check) > LZMA_CHECK_ID_MAX)
+ return LZMA_PROG_ERROR;
+
+ // Exclude the CRC32 field.
+ in_size = block->header_size - 4;
+
+ // Verify CRC32
+ if (lzma_crc32(in, in_size, 0) != unaligned_read32le(in + in_size))
+ return LZMA_DATA_ERROR;
+
+ // Check for unsupported flags.
+ if (in[1] & 0x3C)
+ return LZMA_OPTIONS_ERROR;
+
+ // Compressed Size
+ if (in[1] & 0x40) {
+ return_if_error(lzma_vli_decode(&block->compressed_size,
+ NULL, in, &in_pos, in_size));
+
+ // Validate Compressed Size. This checks that it isn't zero
+ // and that the total size of the Block is a valid VLI.
+ if (lzma_block_unpadded_size(block) == 0)
+ return LZMA_DATA_ERROR;
+ } else {
+ block->compressed_size = LZMA_VLI_UNKNOWN;
+ }
+
+ // Uncompressed Size
+ if (in[1] & 0x80)
+ return_if_error(lzma_vli_decode(&block->uncompressed_size,
+ NULL, in, &in_pos, in_size));
+ else
+ block->uncompressed_size = LZMA_VLI_UNKNOWN;
+
+ // Filter Flags
+ for (i = 0; i < filter_count; ++i) {
+ const lzma_ret ret = lzma_filter_flags_decode(
+ &block->filters[i], allocator,
+ in, &in_pos, in_size);
+ if (ret != LZMA_OK) {
+ free_properties(block, allocator);
+ return ret;
+ }
+ }
+
+ // Padding
+ while (in_pos < in_size) {
+ if (in[in_pos++] != 0x00) {
+ free_properties(block, allocator);
+
+ // Possibly some new field present so use
+ // LZMA_OPTIONS_ERROR instead of LZMA_DATA_ERROR.
+ return LZMA_OPTIONS_ERROR;
+ }
+ }
+
+ return LZMA_OK;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/block_header_encoder.c b/Utilities/cmliblzma/liblzma/common/block_header_encoder.c
new file mode 100644
index 000000000..650295c00
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/block_header_encoder.c
@@ -0,0 +1,137 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file block_header_encoder.c
+/// \brief Encodes Block Header for .xz files
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "common.h"
+#include "check.h"
+
+
+extern LZMA_API(lzma_ret)
+lzma_block_header_size(lzma_block *block)
+{
+ size_t i;
+
+ // Block Header Size + Block Flags + CRC32.
+ uint32_t size = 1 + 1 + 4;
+
+ if (block->version != 0)
+ return LZMA_OPTIONS_ERROR;
+
+ // Compressed Size
+ if (block->compressed_size != LZMA_VLI_UNKNOWN) {
+ const uint32_t add = lzma_vli_size(block->compressed_size);
+ if (add == 0 || block->compressed_size == 0)
+ return LZMA_PROG_ERROR;
+
+ size += add;
+ }
+
+ // Uncompressed Size
+ if (block->uncompressed_size != LZMA_VLI_UNKNOWN) {
+ const uint32_t add = lzma_vli_size(block->uncompressed_size);
+ if (add == 0)
+ return LZMA_PROG_ERROR;
+
+ size += add;
+ }
+
+ // List of Filter Flags
+ if (block->filters == NULL || block->filters[0].id == LZMA_VLI_UNKNOWN)
+ return LZMA_PROG_ERROR;
+
+ for (i = 0; block->filters[i].id != LZMA_VLI_UNKNOWN; ++i) {
+ uint32_t add;
+
+ // Don't allow too many filters.
+ if (i == LZMA_FILTERS_MAX)
+ return LZMA_PROG_ERROR;
+
+ return_if_error(lzma_filter_flags_size(&add,
+ block->filters + i));
+
+ size += add;
+ }
+
+ // Pad to a multiple of four bytes.
+ block->header_size = (size + 3) & ~UINT32_C(3);
+
+ // NOTE: We don't verify that the encoded size of the Block stays
+ // within limits. This is because it is possible that we are called
+ // with exaggerated Compressed Size (e.g. LZMA_VLI_MAX) to reserve
+ // space for Block Header, and later called again with lower,
+ // real values.
+
+ return LZMA_OK;
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_block_header_encode(const lzma_block *block, uint8_t *out)
+{
+ size_t out_size;
+ size_t out_pos = 2;
+ size_t filter_count = 0;
+
+ // Validate everything but filters.
+ if (lzma_block_unpadded_size(block) == 0
+ || !lzma_vli_is_valid(block->uncompressed_size))
+ return LZMA_PROG_ERROR;
+
+ // Indicate the size of the buffer _excluding_ the CRC32 field.
+ out_size = block->header_size - 4;
+
+ // Store the Block Header Size.
+ out[0] = out_size / 4;
+
+ // We write Block Flags in pieces.
+ out[1] = 0x00;
+
+ // Compressed Size
+ if (block->compressed_size != LZMA_VLI_UNKNOWN) {
+ return_if_error(lzma_vli_encode(block->compressed_size, NULL,
+ out, &out_pos, out_size));
+
+ out[1] |= 0x40;
+ }
+
+ // Uncompressed Size
+ if (block->uncompressed_size != LZMA_VLI_UNKNOWN) {
+ return_if_error(lzma_vli_encode(block->uncompressed_size, NULL,
+ out, &out_pos, out_size));
+
+ out[1] |= 0x80;
+ }
+
+ // Filter Flags
+ if (block->filters == NULL || block->filters[0].id == LZMA_VLI_UNKNOWN)
+ return LZMA_PROG_ERROR;
+
+ do {
+ // There can be a maximum of four filters.
+ if (filter_count == LZMA_FILTERS_MAX)
+ return LZMA_PROG_ERROR;
+
+ return_if_error(lzma_filter_flags_encode(
+ block->filters + filter_count,
+ out, &out_pos, out_size));
+
+ } while (block->filters[++filter_count].id != LZMA_VLI_UNKNOWN);
+
+ out[1] |= filter_count - 1;
+
+ // Padding
+ memzero(out + out_pos, out_size - out_pos);
+
+ // CRC32
+ unaligned_write32le(out + out_size, lzma_crc32(out, out_size, 0));
+
+ return LZMA_OK;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/block_util.c b/Utilities/cmliblzma/liblzma/common/block_util.c
new file mode 100644
index 000000000..4cd34d100
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/block_util.c
@@ -0,0 +1,95 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file block_header.c
+/// \brief Utility functions to handle lzma_block
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "common.h"
+#include "index.h"
+
+
+extern LZMA_API(lzma_ret)
+lzma_block_compressed_size(lzma_block *block, lzma_vli unpadded_size)
+{
+ uint32_t container_size;
+ lzma_vli compressed_size;
+
+ // Validate everything but Uncompressed Size and filters.
+ if (lzma_block_unpadded_size(block) == 0)
+ return LZMA_PROG_ERROR;
+
+ container_size = block->header_size
+ + lzma_check_size(block->check);
+
+ // Validate that Compressed Size will be greater than zero.
+ if (unpadded_size <= container_size)
+ return LZMA_DATA_ERROR;
+
+ // Calculate what Compressed Size is supposed to be.
+ // If Compressed Size was present in Block Header,
+ // compare that the new value matches it.
+ compressed_size = unpadded_size - container_size;
+ if (block->compressed_size != LZMA_VLI_UNKNOWN
+ && block->compressed_size != compressed_size)
+ return LZMA_DATA_ERROR;
+
+ block->compressed_size = compressed_size;
+
+ return LZMA_OK;
+}
+
+
+extern LZMA_API(lzma_vli)
+lzma_block_unpadded_size(const lzma_block *block)
+{
+ lzma_vli unpadded_size;
+
+ // Validate the values that we are interested in i.e. all but
+ // Uncompressed Size and the filters.
+ //
+ // NOTE: This function is used for validation too, so it is
+ // essential that these checks are always done even if
+ // Compressed Size is unknown.
+ if (block == NULL || block->version != 0
+ || block->header_size < LZMA_BLOCK_HEADER_SIZE_MIN
+ || block->header_size > LZMA_BLOCK_HEADER_SIZE_MAX
+ || (block->header_size & 3)
+ || !lzma_vli_is_valid(block->compressed_size)
+ || block->compressed_size == 0
+ || (unsigned int)(block->check) > LZMA_CHECK_ID_MAX)
+ return 0;
+
+ // If Compressed Size is unknown, return that we cannot know
+ // size of the Block either.
+ if (block->compressed_size == LZMA_VLI_UNKNOWN)
+ return LZMA_VLI_UNKNOWN;
+
+ // Calculate Unpadded Size and validate it.
+ unpadded_size = block->compressed_size
+ + block->header_size
+ + lzma_check_size(block->check);
+
+ assert(unpadded_size >= UNPADDED_SIZE_MIN);
+ if (unpadded_size > UNPADDED_SIZE_MAX)
+ return 0;
+
+ return unpadded_size;
+}
+
+
+extern LZMA_API(lzma_vli)
+lzma_block_total_size(const lzma_block *block)
+{
+ lzma_vli unpadded_size = lzma_block_unpadded_size(block);
+
+ if (unpadded_size != LZMA_VLI_UNKNOWN)
+ unpadded_size = vli_ceil4(unpadded_size);
+
+ return unpadded_size;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/common.c b/Utilities/cmliblzma/liblzma/common/common.c
new file mode 100644
index 000000000..2e723c8fe
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/common.c
@@ -0,0 +1,390 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file common.h
+/// \brief Common functions needed in many places in liblzma
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "common.h"
+
+
+/////////////
+// Version //
+/////////////
+
+extern LZMA_API(uint32_t)
+lzma_version_number(void)
+{
+ return LZMA_VERSION;
+}
+
+
+extern LZMA_API(const char *)
+lzma_version_string(void)
+{
+ return LZMA_VERSION_STRING;
+}
+
+
+///////////////////////
+// Memory allocation //
+///////////////////////
+
+extern void * lzma_attribute((__malloc__)) lzma_attr_alloc_size(1)
+lzma_alloc(size_t size, lzma_allocator *allocator)
+{
+ void *ptr;
+
+ // Some malloc() variants return NULL if called with size == 0.
+ if (size == 0)
+ size = 1;
+
+ if (allocator != NULL && allocator->alloc != NULL)
+ ptr = allocator->alloc(allocator->opaque, 1, size);
+ else
+ ptr = malloc(size);
+
+ return ptr;
+}
+
+
+extern void
+lzma_free(void *ptr, lzma_allocator *allocator)
+{
+ if (allocator != NULL && allocator->free != NULL)
+ allocator->free(allocator->opaque, ptr);
+ else
+ free(ptr);
+
+ return;
+}
+
+
+//////////
+// Misc //
+//////////
+
+extern size_t
+lzma_bufcpy(const uint8_t *LZMA_RESTRICT in, size_t *LZMA_RESTRICT in_pos,
+ size_t in_size, uint8_t *LZMA_RESTRICT out,
+ size_t *LZMA_RESTRICT out_pos, size_t out_size)
+{
+ const size_t in_avail = in_size - *in_pos;
+ const size_t out_avail = out_size - *out_pos;
+ const size_t copy_size = my_min(in_avail, out_avail);
+
+ memcpy(out + *out_pos, in + *in_pos, copy_size);
+
+ *in_pos += copy_size;
+ *out_pos += copy_size;
+
+ return copy_size;
+}
+
+
+extern lzma_ret
+lzma_next_filter_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter_info *filters)
+{
+ lzma_next_coder_init(filters[0].init, next, allocator);
+ next->id = filters[0].id;
+ return filters[0].init == NULL
+ ? LZMA_OK : filters[0].init(next, allocator, filters);
+}
+
+
+extern lzma_ret
+lzma_next_filter_update(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter *reversed_filters)
+{
+ // Check that the application isn't trying to change the Filter ID.
+ // End of filters is indicated with LZMA_VLI_UNKNOWN in both
+ // reversed_filters[0].id and next->id.
+ if (reversed_filters[0].id != next->id)
+ return LZMA_PROG_ERROR;
+
+ if (reversed_filters[0].id == LZMA_VLI_UNKNOWN)
+ return LZMA_OK;
+
+ assert(next->update != NULL);
+ return next->update(next->coder, allocator, NULL, reversed_filters);
+}
+
+
+extern void
+lzma_next_end(lzma_next_coder *next, lzma_allocator *allocator)
+{
+ if (next->init != (uintptr_t)(NULL)) {
+ // To avoid tiny end functions that simply call
+ // lzma_free(coder, allocator), we allow leaving next->end
+ // NULL and call lzma_free() here.
+ if (next->end != NULL)
+ next->end(next->coder, allocator);
+ else
+ lzma_free(next->coder, allocator);
+
+ // Reset the variables so the we don't accidentally think
+ // that it is an already initialized coder.
+ *next = LZMA_NEXT_CODER_INIT;
+ }
+
+ return;
+}
+
+
+//////////////////////////////////////
+// External to internal API wrapper //
+//////////////////////////////////////
+
+extern lzma_ret
+lzma_strm_init(lzma_stream *strm)
+{
+ if (strm == NULL)
+ return LZMA_PROG_ERROR;
+
+ if (strm->internal == NULL) {
+ strm->internal = lzma_alloc(sizeof(lzma_internal),
+ strm->allocator);
+ if (strm->internal == NULL)
+ return LZMA_MEM_ERROR;
+
+ strm->internal->next = LZMA_NEXT_CODER_INIT;
+ }
+
+ strm->internal->supported_actions[LZMA_RUN] = false;
+ strm->internal->supported_actions[LZMA_SYNC_FLUSH] = false;
+ strm->internal->supported_actions[LZMA_FULL_FLUSH] = false;
+ strm->internal->supported_actions[LZMA_FINISH] = false;
+ strm->internal->sequence = ISEQ_RUN;
+ strm->internal->allow_buf_error = false;
+
+ strm->total_in = 0;
+ strm->total_out = 0;
+
+ return LZMA_OK;
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_code(lzma_stream *strm, lzma_action action)
+{
+ size_t in_pos = 0;
+ size_t out_pos = 0;
+ lzma_ret ret;
+
+ // Sanity checks
+ if ((strm->next_in == NULL && strm->avail_in != 0)
+ || (strm->next_out == NULL && strm->avail_out != 0)
+ || strm->internal == NULL
+ || strm->internal->next.code == NULL
+ || (unsigned int)(action) > LZMA_FINISH
+ || !strm->internal->supported_actions[action])
+ return LZMA_PROG_ERROR;
+
+ // Check if unsupported members have been set to non-zero or non-NULL,
+ // which would indicate that some new feature is wanted.
+ if (strm->reserved_ptr1 != NULL
+ || strm->reserved_ptr2 != NULL
+ || strm->reserved_ptr3 != NULL
+ || strm->reserved_ptr4 != NULL
+ || strm->reserved_int1 != 0
+ || strm->reserved_int2 != 0
+ || strm->reserved_int3 != 0
+ || strm->reserved_int4 != 0
+ || strm->reserved_enum1 != LZMA_RESERVED_ENUM
+ || strm->reserved_enum2 != LZMA_RESERVED_ENUM)
+ return LZMA_OPTIONS_ERROR;
+
+ switch (strm->internal->sequence) {
+ case ISEQ_RUN:
+ switch (action) {
+ case LZMA_RUN:
+ break;
+
+ case LZMA_SYNC_FLUSH:
+ strm->internal->sequence = ISEQ_SYNC_FLUSH;
+ break;
+
+ case LZMA_FULL_FLUSH:
+ strm->internal->sequence = ISEQ_FULL_FLUSH;
+ break;
+
+ case LZMA_FINISH:
+ strm->internal->sequence = ISEQ_FINISH;
+ break;
+ }
+
+ break;
+
+ case ISEQ_SYNC_FLUSH:
+ // The same action must be used until we return
+ // LZMA_STREAM_END, and the amount of input must not change.
+ if (action != LZMA_SYNC_FLUSH
+ || strm->internal->avail_in != strm->avail_in)
+ return LZMA_PROG_ERROR;
+
+ break;
+
+ case ISEQ_FULL_FLUSH:
+ if (action != LZMA_FULL_FLUSH
+ || strm->internal->avail_in != strm->avail_in)
+ return LZMA_PROG_ERROR;
+
+ break;
+
+ case ISEQ_FINISH:
+ if (action != LZMA_FINISH
+ || strm->internal->avail_in != strm->avail_in)
+ return LZMA_PROG_ERROR;
+
+ break;
+
+ case ISEQ_END:
+ return LZMA_STREAM_END;
+
+ case ISEQ_ERROR:
+ default:
+ return LZMA_PROG_ERROR;
+ }
+
+ ret = strm->internal->next.code(
+ strm->internal->next.coder, strm->allocator,
+ strm->next_in, &in_pos, strm->avail_in,
+ strm->next_out, &out_pos, strm->avail_out, action);
+
+ strm->next_in += in_pos;
+ strm->avail_in -= in_pos;
+ strm->total_in += in_pos;
+
+ strm->next_out += out_pos;
+ strm->avail_out -= out_pos;
+ strm->total_out += out_pos;
+
+ strm->internal->avail_in = strm->avail_in;
+
+ switch (ret) {
+ case LZMA_OK:
+ // Don't return LZMA_BUF_ERROR when it happens the first time.
+ // This is to avoid returning LZMA_BUF_ERROR when avail_out
+ // was zero but still there was no more data left to written
+ // to next_out.
+ if (out_pos == 0 && in_pos == 0) {
+ if (strm->internal->allow_buf_error)
+ ret = LZMA_BUF_ERROR;
+ else
+ strm->internal->allow_buf_error = true;
+ } else {
+ strm->internal->allow_buf_error = false;
+ }
+ break;
+
+ case LZMA_STREAM_END:
+ if (strm->internal->sequence == ISEQ_SYNC_FLUSH
+ || strm->internal->sequence == ISEQ_FULL_FLUSH)
+ strm->internal->sequence = ISEQ_RUN;
+ else
+ strm->internal->sequence = ISEQ_END;
+
+ // Fall through
+
+ case LZMA_NO_CHECK:
+ case LZMA_UNSUPPORTED_CHECK:
+ case LZMA_GET_CHECK:
+ case LZMA_MEMLIMIT_ERROR:
+ // Something else than LZMA_OK, but not a fatal error,
+ // that is, coding may be continued (except if ISEQ_END).
+ strm->internal->allow_buf_error = false;
+ break;
+
+ default:
+ // All the other errors are fatal; coding cannot be continued.
+ assert(ret != LZMA_BUF_ERROR);
+ strm->internal->sequence = ISEQ_ERROR;
+ break;
+ }
+
+ return ret;
+}
+
+
+extern LZMA_API(void)
+lzma_end(lzma_stream *strm)
+{
+ if (strm != NULL && strm->internal != NULL) {
+ lzma_next_end(&strm->internal->next, strm->allocator);
+ lzma_free(strm->internal, strm->allocator);
+ strm->internal = NULL;
+ }
+
+ return;
+}
+
+
+extern LZMA_API(lzma_check)
+lzma_get_check(const lzma_stream *strm)
+{
+ // Return LZMA_CHECK_NONE if we cannot know the check type.
+ // It's a bug in the application if this happens.
+ if (strm->internal->next.get_check == NULL)
+ return LZMA_CHECK_NONE;
+
+ return strm->internal->next.get_check(strm->internal->next.coder);
+}
+
+
+extern LZMA_API(uint64_t)
+lzma_memusage(const lzma_stream *strm)
+{
+ uint64_t memusage;
+ uint64_t old_memlimit;
+
+ if (strm == NULL || strm->internal == NULL
+ || strm->internal->next.memconfig == NULL
+ || strm->internal->next.memconfig(
+ strm->internal->next.coder,
+ &memusage, &old_memlimit, 0) != LZMA_OK)
+ return 0;
+
+ return memusage;
+}
+
+
+extern LZMA_API(uint64_t)
+lzma_memlimit_get(const lzma_stream *strm)
+{
+ uint64_t old_memlimit;
+ uint64_t memusage;
+
+ if (strm == NULL || strm->internal == NULL
+ || strm->internal->next.memconfig == NULL
+ || strm->internal->next.memconfig(
+ strm->internal->next.coder,
+ &memusage, &old_memlimit, 0) != LZMA_OK)
+ return 0;
+
+ return old_memlimit;
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_memlimit_set(lzma_stream *strm, uint64_t new_memlimit)
+{
+ // Dummy variables to simplify memconfig functions
+ uint64_t old_memlimit;
+ uint64_t memusage;
+
+ if (strm == NULL || strm->internal == NULL
+ || strm->internal->next.memconfig == NULL)
+ return LZMA_PROG_ERROR;
+
+ if (new_memlimit != 0 && new_memlimit < LZMA_MEMUSAGE_BASE)
+ return LZMA_MEMLIMIT_ERROR;
+
+ return strm->internal->next.memconfig(strm->internal->next.coder,
+ &memusage, &old_memlimit, new_memlimit);
+}
diff --git a/Utilities/cmliblzma/liblzma/common/common.h b/Utilities/cmliblzma/liblzma/common/common.h
new file mode 100644
index 000000000..a6a28189e
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/common.h
@@ -0,0 +1,305 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file common.h
+/// \brief Definitions common to the whole liblzma library
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_COMMON_H
+#define LZMA_COMMON_H
+
+#include "sysdefs.h"
+#include "tuklib_integer.h"
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+# ifdef DLL_EXPORT
+# define LZMA_API_EXPORT __declspec(dllexport)
+# else
+# define LZMA_API_EXPORT
+# endif
+// Don't use ifdef or defined() below.
+#elif HAVE_VISIBILITY
+# define LZMA_API_EXPORT __attribute__((__visibility__("default")))
+#else
+# define LZMA_API_EXPORT
+#endif
+
+#define LZMA_API(type) LZMA_API_EXPORT type LZMA_API_CALL
+
+#include "lzma.h"
+
+// These allow helping the compiler in some often-executed branches, whose
+// result is almost always the same.
+#ifdef __GNUC__
+# define likely(expr) __builtin_expect(expr, true)
+# define unlikely(expr) __builtin_expect(expr, false)
+#else
+# define likely(expr) (expr)
+# define unlikely(expr) (expr)
+#endif
+
+
+/// Size of temporary buffers needed in some filters
+#define LZMA_BUFFER_SIZE 4096
+
+
+/// Starting value for memory usage estimates. Instead of calculating size
+/// of _every_ structure and taking into account malloc() overhead etc., we
+/// add a base size to all memory usage estimates. It's not very accurate
+/// but should be easily good enough.
+#define LZMA_MEMUSAGE_BASE (UINT64_C(1) << 15)
+
+/// Start of internal Filter ID space. These IDs must never be used
+/// in Streams.
+#define LZMA_FILTER_RESERVED_START (LZMA_VLI_C(1) << 62)
+
+
+/// Supported flags that can be passed to lzma_stream_decoder()
+/// or lzma_auto_decoder().
+#define LZMA_SUPPORTED_FLAGS \
+ ( LZMA_TELL_NO_CHECK \
+ | LZMA_TELL_UNSUPPORTED_CHECK \
+ | LZMA_TELL_ANY_CHECK \
+ | LZMA_CONCATENATED )
+
+
+/// Type of encoder/decoder specific data; the actual structure is defined
+/// differently in different coders.
+typedef struct lzma_coder_s lzma_coder;
+
+typedef struct lzma_next_coder_s lzma_next_coder;
+
+typedef struct lzma_filter_info_s lzma_filter_info;
+
+
+/// Type of a function used to initialize a filter encoder or decoder
+typedef lzma_ret (*lzma_init_function)(
+ lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter_info *filters);
+
+/// Type of a function to do some kind of coding work (filters, Stream,
+/// Block encoders/decoders etc.). Some special coders use don't use both
+/// input and output buffers, but for simplicity they still use this same
+/// function prototype.
+typedef lzma_ret (*lzma_code_function)(
+ lzma_coder *coder, lzma_allocator *allocator,
+ const uint8_t *LZMA_RESTRICT in, size_t *LZMA_RESTRICT in_pos,
+ size_t in_size, uint8_t *LZMA_RESTRICT out,
+ size_t *LZMA_RESTRICT out_pos, size_t out_size,
+ lzma_action action);
+
+/// Type of a function to free the memory allocated for the coder
+typedef void (*lzma_end_function)(
+ lzma_coder *coder, lzma_allocator *allocator);
+
+
+/// Raw coder validates and converts an array of lzma_filter structures to
+/// an array of lzma_filter_info structures. This array is used with
+/// lzma_next_filter_init to initialize the filter chain.
+struct lzma_filter_info_s {
+ /// Filter ID. This is used only by the encoder
+ /// with lzma_filters_update().
+ lzma_vli id;
+
+ /// Pointer to function used to initialize the filter.
+ /// This is NULL to indicate end of array.
+ lzma_init_function init;
+
+ /// Pointer to filter's options structure
+ void *options;
+};
+
+
+/// Hold data and function pointers of the next filter in the chain.
+struct lzma_next_coder_s {
+ /// Pointer to coder-specific data
+ lzma_coder *coder;
+
+ /// Filter ID. This is LZMA_VLI_UNKNOWN when this structure doesn't
+ /// point to a filter coder.
+ lzma_vli id;
+
+ /// "Pointer" to init function. This is never called here.
+ /// We need only to detect if we are initializing a coder
+ /// that was allocated earlier. See lzma_next_coder_init and
+ /// lzma_next_strm_init macros in this file.
+ uintptr_t init;
+
+ /// Pointer to function to do the actual coding
+ lzma_code_function code;
+
+ /// Pointer to function to free lzma_next_coder.coder. This can
+ /// be NULL; in that case, lzma_free is called to free
+ /// lzma_next_coder.coder.
+ lzma_end_function end;
+
+ /// Pointer to function to return the type of the integrity check.
+ /// Most coders won't support this.
+ lzma_check (*get_check)(const lzma_coder *coder);
+
+ /// Pointer to function to get and/or change the memory usage limit.
+ /// If new_memlimit == 0, the limit is not changed.
+ lzma_ret (*memconfig)(lzma_coder *coder, uint64_t *memusage,
+ uint64_t *old_memlimit, uint64_t new_memlimit);
+
+ /// Update the filter-specific options or the whole filter chain
+ /// in the encoder.
+ lzma_ret (*update)(lzma_coder *coder, lzma_allocator *allocator,
+ const lzma_filter *filters,
+ const lzma_filter *reversed_filters);
+};
+
+
+/// Constant to initialize lzma_next_coder structure
+static const lzma_next_coder LZMA_NEXT_CODER_INIT =
+ {
+ NULL,
+ LZMA_VLI_UNKNOWN,
+ (uintptr_t)(NULL),
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ };
+
+
+/// Internal data for lzma_strm_init, lzma_code, and lzma_end. A pointer to
+/// this is stored in lzma_stream.
+struct lzma_internal_s {
+ /// The actual coder that should do something useful
+ lzma_next_coder next;
+
+ /// Track the state of the coder. This is used to validate arguments
+ /// so that the actual coders can rely on e.g. that LZMA_SYNC_FLUSH
+ /// is used on every call to lzma_code until next.code has returned
+ /// LZMA_STREAM_END.
+ enum {
+ ISEQ_RUN,
+ ISEQ_SYNC_FLUSH,
+ ISEQ_FULL_FLUSH,
+ ISEQ_FINISH,
+ ISEQ_END,
+ ISEQ_ERROR,
+ } sequence;
+
+ /// A copy of lzma_stream avail_in. This is used to verify that the
+ /// amount of input doesn't change once e.g. LZMA_FINISH has been
+ /// used.
+ size_t avail_in;
+
+ /// Indicates which lzma_action values are allowed by next.code.
+ bool supported_actions[4];
+
+ /// If true, lzma_code will return LZMA_BUF_ERROR if no progress was
+ /// made (no input consumed and no output produced by next.code).
+ bool allow_buf_error;
+};
+
+
+/// Allocates memory
+extern void *lzma_alloc(size_t size, lzma_allocator *allocator)
+ lzma_attribute((__malloc__)) lzma_attr_alloc_size(1);
+
+/// Frees memory
+extern void lzma_free(void *ptr, lzma_allocator *allocator);
+
+
+/// Allocates strm->internal if it is NULL, and initializes *strm and
+/// strm->internal. This function is only called via lzma_next_strm_init2 macro.
+extern lzma_ret lzma_strm_init(lzma_stream *strm);
+
+/// Initializes the next filter in the chain, if any. This takes care of
+/// freeing the memory of previously initialized filter if it is different
+/// than the filter being initialized now. This way the actual filter
+/// initialization functions don't need to use lzma_next_coder_init macro.
+extern lzma_ret lzma_next_filter_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters);
+
+/// Update the next filter in the chain, if any. This checks that
+/// the application is not trying to change the Filter IDs.
+extern lzma_ret lzma_next_filter_update(
+ lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter *reversed_filters);
+
+/// Frees the memory allocated for next->coder either using next->end or,
+/// if next->end is NULL, using lzma_free.
+extern void lzma_next_end(lzma_next_coder *next, lzma_allocator *allocator);
+
+
+/// Copy as much data as possible from in[] to out[] and update *in_pos
+/// and *out_pos accordingly. Returns the number of bytes copied.
+extern size_t lzma_bufcpy(const uint8_t *LZMA_RESTRICT in, size_t *LZMA_RESTRICT in_pos,
+ size_t in_size, uint8_t *LZMA_RESTRICT out,
+ size_t *LZMA_RESTRICT out_pos, size_t out_size);
+
+
+/// \brief Return if expression doesn't evaluate to LZMA_OK
+///
+/// There are several situations where we want to return immediately
+/// with the value of expr if it isn't LZMA_OK. This macro shortens
+/// the code a little.
+#define return_if_error(expr) \
+do { \
+ const lzma_ret ret_ = (expr); \
+ if (ret_ != LZMA_OK) \
+ return ret_; \
+} while (0)
+
+
+/// If next isn't already initialized, free the previous coder. Then mark
+/// that next is _possibly_ initialized for the coder using this macro.
+/// "Possibly" means that if e.g. allocation of next->coder fails, the
+/// structure isn't actually initialized for this coder, but leaving
+/// next->init to func is still OK.
+#define lzma_next_coder_init(func, next, allocator) \
+do { \
+ if ((uintptr_t)(func) != (next)->init) \
+ lzma_next_end(next, allocator); \
+ (next)->init = (uintptr_t)(func); \
+} while (0)
+
+
+/// Initializes lzma_strm and calls func() to initialize strm->internal->next.
+/// (The function being called will use lzma_next_coder_init()). If
+/// initialization fails, memory that wasn't freed by func() is freed
+/// along strm->internal.
+#define lzma_next_strm_init1(func, strm, arg1) \
+do { \
+ lzma_ret ret_; \
+ return_if_error(lzma_strm_init(strm)); \
+ ret_ = func(&(strm)->internal->next, (strm)->allocator, arg1); \
+ if (ret_ != LZMA_OK) { \
+ lzma_end(strm); \
+ return ret_; \
+ } \
+} while (0)
+
+#define lzma_next_strm_init2(func, strm, arg1, arg2) \
+do { \
+ lzma_ret ret_; \
+ return_if_error(lzma_strm_init(strm)); \
+ ret_ = func(&(strm)->internal->next, (strm)->allocator, arg1, arg2); \
+ if (ret_ != LZMA_OK) { \
+ lzma_end(strm); \
+ return ret_; \
+ } \
+} while (0)
+
+#define lzma_next_strm_init3(func, strm, arg1, arg2, arg3) \
+do { \
+ lzma_ret ret_; \
+ return_if_error(lzma_strm_init(strm)); \
+ ret_ = func(&(strm)->internal->next, (strm)->allocator, arg1, arg2, arg3); \
+ if (ret_ != LZMA_OK) { \
+ lzma_end(strm); \
+ return ret_; \
+ } \
+} while (0)
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/common/easy_buffer_encoder.c b/Utilities/cmliblzma/liblzma/common/easy_buffer_encoder.c
new file mode 100644
index 000000000..c4be34ccf
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/easy_buffer_encoder.c
@@ -0,0 +1,27 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file easy_buffer_encoder.c
+/// \brief Easy single-call .xz Stream encoder
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "easy_preset.h"
+
+
+extern LZMA_API(lzma_ret)
+lzma_easy_buffer_encode(uint32_t preset, lzma_check check,
+ lzma_allocator *allocator, const uint8_t *in, size_t in_size,
+ uint8_t *out, size_t *out_pos, size_t out_size)
+{
+ lzma_options_easy opt_easy;
+ if (lzma_easy_preset(&opt_easy, preset))
+ return LZMA_OPTIONS_ERROR;
+
+ return lzma_stream_buffer_encode(opt_easy.filters, check,
+ allocator, in, in_size, out, out_pos, out_size);
+}
diff --git a/Utilities/cmliblzma/liblzma/common/easy_decoder_memusage.c b/Utilities/cmliblzma/liblzma/common/easy_decoder_memusage.c
new file mode 100644
index 000000000..20bcd5b71
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/easy_decoder_memusage.c
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file easy_decoder_memusage.c
+/// \brief Decoder memory usage calculation to match easy encoder presets
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "easy_preset.h"
+
+
+extern LZMA_API(uint64_t)
+lzma_easy_decoder_memusage(uint32_t preset)
+{
+ lzma_options_easy opt_easy;
+ if (lzma_easy_preset(&opt_easy, preset))
+ return UINT32_MAX;
+
+ return lzma_raw_decoder_memusage(opt_easy.filters);
+}
diff --git a/Utilities/cmliblzma/liblzma/common/easy_encoder.c b/Utilities/cmliblzma/liblzma/common/easy_encoder.c
new file mode 100644
index 000000000..d13ccd735
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/easy_encoder.c
@@ -0,0 +1,25 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file easy_encoder.c
+/// \brief Easy .xz Stream encoder initialization
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "easy_preset.h"
+#include "stream_encoder.h"
+
+
+extern LZMA_API(lzma_ret)
+lzma_easy_encoder(lzma_stream *strm, uint32_t preset, lzma_check check)
+{
+ lzma_options_easy opt_easy;
+ if (lzma_easy_preset(&opt_easy, preset))
+ return LZMA_OPTIONS_ERROR;
+
+ return lzma_stream_encoder(strm, opt_easy.filters, check);
+}
diff --git a/Utilities/cmliblzma/liblzma/common/easy_encoder_memusage.c b/Utilities/cmliblzma/liblzma/common/easy_encoder_memusage.c
new file mode 100644
index 000000000..e91057584
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/easy_encoder_memusage.c
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file easy_encoder_memusage.c
+/// \brief Easy .xz Stream encoder memory usage calculation
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "easy_preset.h"
+
+
+extern LZMA_API(uint64_t)
+lzma_easy_encoder_memusage(uint32_t preset)
+{
+ lzma_options_easy opt_easy;
+ if (lzma_easy_preset(&opt_easy, preset))
+ return UINT32_MAX;
+
+ return lzma_raw_encoder_memusage(opt_easy.filters);
+}
diff --git a/Utilities/cmliblzma/liblzma/common/easy_preset.c b/Utilities/cmliblzma/liblzma/common/easy_preset.c
new file mode 100644
index 000000000..2f9859860
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/easy_preset.c
@@ -0,0 +1,27 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file easy_preset.c
+/// \brief Preset handling for easy encoder and decoder
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "easy_preset.h"
+
+
+extern bool
+lzma_easy_preset(lzma_options_easy *opt_easy, uint32_t preset)
+{
+ if (lzma_lzma_preset(&opt_easy->opt_lzma, preset))
+ return true;
+
+ opt_easy->filters[0].id = LZMA_FILTER_LZMA2;
+ opt_easy->filters[0].options = &opt_easy->opt_lzma;
+ opt_easy->filters[1].id = LZMA_VLI_UNKNOWN;
+
+ return false;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/easy_preset.h b/Utilities/cmliblzma/liblzma/common/easy_preset.h
new file mode 100644
index 000000000..382ade894
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/easy_preset.h
@@ -0,0 +1,32 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file easy_preset.h
+/// \brief Preset handling for easy encoder and decoder
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "common.h"
+
+
+typedef struct {
+ /// We need to keep the filters array available in case
+ /// LZMA_FULL_FLUSH is used.
+ lzma_filter filters[LZMA_FILTERS_MAX + 1];
+
+ /// Options for LZMA2
+ lzma_options_lzma opt_lzma;
+
+ // Options for more filters can be added later, so this struct
+ // is not ready to be put into the public API.
+
+} lzma_options_easy;
+
+
+/// Set *easy to the settings given by the preset. Returns true on error,
+/// false on success.
+extern bool lzma_easy_preset(lzma_options_easy *easy, uint32_t preset);
diff --git a/Utilities/cmliblzma/liblzma/common/filter_buffer_decoder.c b/Utilities/cmliblzma/liblzma/common/filter_buffer_decoder.c
new file mode 100644
index 000000000..65665c17d
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/filter_buffer_decoder.c
@@ -0,0 +1,91 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file filter_buffer_decoder.c
+/// \brief Single-call raw decoding
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "filter_decoder.h"
+
+
+extern LZMA_API(lzma_ret)
+lzma_raw_buffer_decode(const lzma_filter *filters, lzma_allocator *allocator,
+ const uint8_t *in, size_t *in_pos, size_t in_size,
+ uint8_t *out, size_t *out_pos, size_t out_size)
+{
+ lzma_next_coder next = LZMA_NEXT_CODER_INIT;
+ size_t in_start;
+ size_t out_start;
+ lzma_ret ret;
+
+ // Validate what isn't validated later in filter_common.c.
+ if (in == NULL || in_pos == NULL || *in_pos > in_size || out == NULL
+ || out_pos == NULL || *out_pos > out_size)
+ return LZMA_PROG_ERROR;
+
+ // Initialize the decoer.
+ return_if_error(lzma_raw_decoder_init(&next, allocator, filters));
+
+ // Store the positions so that we can restore them if something
+ // goes wrong.
+ in_start = *in_pos;
+ out_start = *out_pos;
+
+ // Do the actual decoding and free decoder's memory.
+ ret = next.code(next.coder, allocator, in, in_pos, in_size,
+ out, out_pos, out_size, LZMA_FINISH);
+
+ if (ret == LZMA_STREAM_END) {
+ ret = LZMA_OK;
+ } else {
+ if (ret == LZMA_OK) {
+ // Either the input was truncated or the
+ // output buffer was too small.
+ assert(*in_pos == in_size || *out_pos == out_size);
+
+ if (*in_pos != in_size) {
+ // Since input wasn't consumed completely,
+ // the output buffer became full and is
+ // too small.
+ ret = LZMA_BUF_ERROR;
+
+ } else if (*out_pos != out_size) {
+ // Since output didn't became full, the input
+ // has to be truncated.
+ ret = LZMA_DATA_ERROR;
+
+ } else {
+ // All the input was consumed and output
+ // buffer is full. Now we don't immediately
+ // know the reason for the error. Try
+ // decoding one more byte. If it succeeds,
+ // then the output buffer was too small. If
+ // we cannot get a new output byte, the input
+ // is truncated.
+ uint8_t tmp[1];
+ size_t tmp_pos = 0;
+ (void)next.code(next.coder, allocator,
+ in, in_pos, in_size,
+ tmp, &tmp_pos, 1, LZMA_FINISH);
+
+ if (tmp_pos == 1)
+ ret = LZMA_BUF_ERROR;
+ else
+ ret = LZMA_DATA_ERROR;
+ }
+ }
+
+ // Restore the positions.
+ *in_pos = in_start;
+ *out_pos = out_start;
+ }
+
+ lzma_next_end(&next, allocator);
+
+ return ret;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/filter_buffer_encoder.c b/Utilities/cmliblzma/liblzma/common/filter_buffer_encoder.c
new file mode 100644
index 000000000..b23329f3e
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/filter_buffer_encoder.c
@@ -0,0 +1,57 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file filter_buffer_encoder.c
+/// \brief Single-call raw encoding
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "filter_encoder.h"
+
+
+extern LZMA_API(lzma_ret)
+lzma_raw_buffer_encode(const lzma_filter *filters, lzma_allocator *allocator,
+ const uint8_t *in, size_t in_size, uint8_t *out,
+ size_t *out_pos, size_t out_size)
+{
+ lzma_next_coder next = LZMA_NEXT_CODER_INIT;
+ size_t out_start;
+ size_t in_pos = 0;
+ lzma_ret ret;
+
+ // Validate what isn't validated later in filter_common.c.
+ if ((in == NULL && in_size != 0) || out == NULL
+ || out_pos == NULL || *out_pos > out_size)
+ return LZMA_PROG_ERROR;
+
+ // Initialize the encoder
+ return_if_error(lzma_raw_encoder_init(&next, allocator, filters));
+
+ // Store the output position so that we can restore it if
+ // something goes wrong.
+ out_start = *out_pos;
+
+ // Do the actual encoding and free coder's memory.
+ ret = next.code(next.coder, allocator, in, &in_pos, in_size,
+ out, out_pos, out_size, LZMA_FINISH);
+ lzma_next_end(&next, allocator);
+
+ if (ret == LZMA_STREAM_END) {
+ ret = LZMA_OK;
+ } else {
+ if (ret == LZMA_OK) {
+ // Output buffer was too small.
+ assert(*out_pos == out_size);
+ ret = LZMA_BUF_ERROR;
+ }
+
+ // Restore the output position.
+ *out_pos = out_start;
+ }
+
+ return ret;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/filter_common.c b/Utilities/cmliblzma/liblzma/common/filter_common.c
new file mode 100644
index 000000000..d2b9e086e
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/filter_common.c
@@ -0,0 +1,342 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file filter_common.c
+/// \brief Filter-specific stuff common for both encoder and decoder
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "filter_common.h"
+
+
+static const struct {
+ /// Filter ID
+ lzma_vli id;
+
+ /// Size of the filter-specific options structure
+ size_t options_size;
+
+ /// True if it is OK to use this filter as non-last filter in
+ /// the chain.
+ bool non_last_ok;
+
+ /// True if it is OK to use this filter as the last filter in
+ /// the chain.
+ bool last_ok;
+
+ /// True if the filter may change the size of the data (that is, the
+ /// amount of encoded output can be different than the amount of
+ /// uncompressed input).
+ bool changes_size;
+
+} features[] = {
+#if defined (HAVE_ENCODER_LZMA1) || defined(HAVE_DECODER_LZMA1)
+ {
+ LZMA_FILTER_LZMA1,
+ sizeof(lzma_options_lzma),
+ false,
+ true,
+ true,
+ },
+#endif
+#if defined(HAVE_ENCODER_LZMA2) || defined(HAVE_DECODER_LZMA2)
+ {
+ LZMA_FILTER_LZMA2,
+ sizeof(lzma_options_lzma),
+ false,
+ true,
+ true,
+ },
+#endif
+#if defined(HAVE_ENCODER_X86) || defined(HAVE_DECODER_X86)
+ {
+ LZMA_FILTER_X86,
+ sizeof(lzma_options_bcj),
+ true,
+ false,
+ false,
+ },
+#endif
+#if defined(HAVE_ENCODER_POWERPC) || defined(HAVE_DECODER_POWERPC)
+ {
+ LZMA_FILTER_POWERPC,
+ sizeof(lzma_options_bcj),
+ true,
+ false,
+ false,
+ },
+#endif
+#if defined(HAVE_ENCODER_IA64) || defined(HAVE_DECODER_IA64)
+ {
+ LZMA_FILTER_IA64,
+ sizeof(lzma_options_bcj),
+ true,
+ false,
+ false,
+ },
+#endif
+#if defined(HAVE_ENCODER_ARM) || defined(HAVE_DECODER_ARM)
+ {
+ LZMA_FILTER_ARM,
+ sizeof(lzma_options_bcj),
+ true,
+ false,
+ false,
+ },
+#endif
+#if defined(HAVE_ENCODER_ARMTHUMB) || defined(HAVE_DECODER_ARMTHUMB)
+ {
+ LZMA_FILTER_ARMTHUMB,
+ sizeof(lzma_options_bcj),
+ true,
+ false,
+ false,
+ },
+#endif
+#if defined(HAVE_ENCODER_SPARC) || defined(HAVE_DECODER_SPARC)
+ {
+ LZMA_FILTER_SPARC,
+ sizeof(lzma_options_bcj),
+ true,
+ false,
+ false,
+ },
+#endif
+#if defined(HAVE_ENCODER_DELTA) || defined(HAVE_DECODER_DELTA)
+ {
+ LZMA_FILTER_DELTA,
+ sizeof(lzma_options_delta),
+ true,
+ false,
+ false,
+ },
+#endif
+ {
+ LZMA_VLI_UNKNOWN
+ }
+};
+
+
+extern LZMA_API(lzma_ret)
+lzma_filters_copy(const lzma_filter *src, lzma_filter *dest,
+ lzma_allocator *allocator)
+{
+ size_t i;
+ lzma_ret ret;
+
+ if (src == NULL || dest == NULL)
+ return LZMA_PROG_ERROR;
+
+ for (i = 0; src[i].id != LZMA_VLI_UNKNOWN; ++i) {
+ // There must be a maximum of four filters plus
+ // the array terminator.
+ if (i == LZMA_FILTERS_MAX) {
+ ret = LZMA_OPTIONS_ERROR;
+ goto error;
+ }
+
+ dest[i].id = src[i].id;
+
+ if (src[i].options == NULL) {
+ dest[i].options = NULL;
+ } else {
+ // See if the filter is supported only when the
+ // options is not NULL. This might be convenient
+ // sometimes if the app is actually copying only
+ // a partial filter chain with a place holder ID.
+ //
+ // When options is not NULL, the Filter ID must be
+ // supported by us, because otherwise we don't know
+ // how big the options are.
+ size_t j;
+ for (j = 0; src[i].id != features[j].id; ++j) {
+ if (features[j].id == LZMA_VLI_UNKNOWN) {
+ ret = LZMA_OPTIONS_ERROR;
+ goto error;
+ }
+ }
+
+ // Allocate and copy the options.
+ dest[i].options = lzma_alloc(features[j].options_size,
+ allocator);
+ if (dest[i].options == NULL) {
+ ret = LZMA_MEM_ERROR;
+ goto error;
+ }
+
+ memcpy(dest[i].options, src[i].options,
+ features[j].options_size);
+ }
+ }
+
+ // Terminate the filter array.
+ assert(i <= LZMA_FILTERS_MAX + 1);
+ dest[i].id = LZMA_VLI_UNKNOWN;
+ dest[i].options = NULL;
+
+ return LZMA_OK;
+
+error:
+ // Free the options which we have already allocated.
+ while (i-- > 0) {
+ lzma_free(dest[i].options, allocator);
+ dest[i].options = NULL;
+ }
+
+ return ret;
+}
+
+
+static lzma_ret
+validate_chain(const lzma_filter *filters, size_t *count)
+{
+ // Number of non-last filters that may change the size of the data
+ // significantly (that is, more than 1-2 % or so).
+ size_t changes_size_count = 0;
+
+ // True if it is OK to add a new filter after the current filter.
+ bool non_last_ok = true;
+
+ // True if the last filter in the given chain is actually usable as
+ // the last filter. Only filters that support embedding End of Payload
+ // Marker can be used as the last filter in the chain.
+ bool last_ok = false;
+
+ size_t i = 0;
+
+ // There must be at least one filter.
+ if (filters == NULL || filters[0].id == LZMA_VLI_UNKNOWN)
+ return LZMA_PROG_ERROR;
+
+ do {
+ size_t j;
+ for (j = 0; filters[i].id != features[j].id; ++j)
+ if (features[j].id == LZMA_VLI_UNKNOWN)
+ return LZMA_OPTIONS_ERROR;
+
+ // If the previous filter in the chain cannot be a non-last
+ // filter, the chain is invalid.
+ if (!non_last_ok)
+ return LZMA_OPTIONS_ERROR;
+
+ non_last_ok = features[j].non_last_ok;
+ last_ok = features[j].last_ok;
+ changes_size_count += features[j].changes_size;
+
+ } while (filters[++i].id != LZMA_VLI_UNKNOWN);
+
+ // There must be 1-4 filters. The last filter must be usable as
+ // the last filter in the chain. A maximum of three filters are
+ // allowed to change the size of the data.
+ if (i > LZMA_FILTERS_MAX || !last_ok || changes_size_count > 3)
+ return LZMA_OPTIONS_ERROR;
+
+ *count = i;
+ return LZMA_OK;
+}
+
+
+extern lzma_ret
+lzma_raw_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter *options,
+ lzma_filter_find coder_find, bool is_encoder)
+{
+ lzma_filter_info filters[LZMA_FILTERS_MAX + 1];
+ size_t count;
+ size_t i;
+ lzma_ret ret;
+
+ // Do some basic validation and get the number of filters.
+ return_if_error(validate_chain(options, &count));
+
+ // Set the filter functions and copy the options pointer.
+ if (is_encoder) {
+ for (i = 0; i < count; ++i) {
+ // The order of the filters is reversed in the
+ // encoder. It allows more efficient handling
+ // of the uncompressed data.
+ const size_t j = count - i - 1;
+
+ const lzma_filter_coder *const fc
+ = coder_find(options[i].id);
+ if (fc == NULL || fc->init == NULL)
+ return LZMA_OPTIONS_ERROR;
+
+ filters[j].id = options[i].id;
+ filters[j].init = fc->init;
+ filters[j].options = options[i].options;
+ }
+ } else {
+ for (i = 0; i < count; ++i) {
+ const lzma_filter_coder *const fc
+ = coder_find(options[i].id);
+ if (fc == NULL || fc->init == NULL)
+ return LZMA_OPTIONS_ERROR;
+
+ filters[i].id = options[i].id;
+ filters[i].init = fc->init;
+ filters[i].options = options[i].options;
+ }
+ }
+
+ // Terminate the array.
+ filters[count].id = LZMA_VLI_UNKNOWN;
+ filters[count].init = NULL;
+
+ // Initialize the filters.
+ ret = lzma_next_filter_init(next, allocator, filters);
+ if (ret != LZMA_OK)
+ lzma_next_end(next, allocator);
+
+ return ret;
+}
+
+
+extern uint64_t
+lzma_raw_coder_memusage(lzma_filter_find coder_find,
+ const lzma_filter *filters)
+{
+ uint64_t total = 0;
+ size_t i = 0;
+
+ // The chain has to have at least one filter.
+ {
+ size_t tmp;
+ if (validate_chain(filters, &tmp) != LZMA_OK)
+ return UINT64_MAX;
+ }
+
+ do {
+ const lzma_filter_coder *const fc
+ = coder_find(filters[i].id);
+ if (fc == NULL)
+ return UINT64_MAX; // Unsupported Filter ID
+
+ if (fc->memusage == NULL) {
+ // This filter doesn't have a function to calculate
+ // the memory usage and validate the options. Such
+ // filters need only little memory, so we use 1 KiB
+ // as a good estimate. They also accept all possible
+ // options, so there's no need to worry about lack
+ // of validation.
+ total += 1024;
+ } else {
+ // Call the filter-specific memory usage calculation
+ // function.
+ const uint64_t usage
+ = fc->memusage(filters[i].options);
+ if (usage == UINT64_MAX)
+ return UINT64_MAX; // Invalid options
+
+ total += usage;
+ }
+ } while (filters[++i].id != LZMA_VLI_UNKNOWN);
+
+ // Add some fixed amount of extra. It's to compensate memory usage
+ // of Stream, Block etc. coders, malloc() overhead, stack etc.
+ return total + LZMA_MEMUSAGE_BASE;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/filter_common.h b/Utilities/cmliblzma/liblzma/common/filter_common.h
new file mode 100644
index 000000000..cd61fc072
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/filter_common.h
@@ -0,0 +1,48 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file filter_common.c
+/// \brief Filter-specific stuff common for both encoder and decoder
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_FILTER_COMMON_H
+#define LZMA_FILTER_COMMON_H
+
+#include "common.h"
+
+
+/// Both lzma_filter_encoder and lzma_filter_decoder begin with these members.
+typedef struct {
+ /// Filter ID
+ lzma_vli id;
+
+ /// Initializes the filter encoder and calls lzma_next_filter_init()
+ /// for filters + 1.
+ lzma_init_function init;
+
+ /// Calculates memory usage of the encoder. If the options are
+ /// invalid, UINT64_MAX is returned.
+ uint64_t (*memusage)(const void *options);
+
+} lzma_filter_coder;
+
+
+typedef const lzma_filter_coder *(*lzma_filter_find)(lzma_vli id);
+
+
+extern lzma_ret lzma_raw_coder_init(
+ lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter *filters,
+ lzma_filter_find coder_find, bool is_encoder);
+
+
+extern uint64_t lzma_raw_coder_memusage(lzma_filter_find coder_find,
+ const lzma_filter *filters);
+
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/common/filter_decoder.c b/Utilities/cmliblzma/liblzma/common/filter_decoder.c
new file mode 100644
index 000000000..cce2b30ea
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/filter_decoder.c
@@ -0,0 +1,185 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file filter_decoder.c
+/// \brief Filter ID mapping to filter-specific functions
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "filter_decoder.h"
+#include "filter_common.h"
+#include "lzma_decoder.h"
+#include "lzma2_decoder.h"
+#include "simple_decoder.h"
+#include "delta_decoder.h"
+
+
+typedef struct {
+ /// Filter ID
+ lzma_vli id;
+
+ /// Initializes the filter encoder and calls lzma_next_filter_init()
+ /// for filters + 1.
+ lzma_init_function init;
+
+ /// Calculates memory usage of the encoder. If the options are
+ /// invalid, UINT64_MAX is returned.
+ uint64_t (*memusage)(const void *options);
+
+ /// Decodes Filter Properties.
+ ///
+ /// \return - LZMA_OK: Properties decoded successfully.
+ /// - LZMA_OPTIONS_ERROR: Unsupported properties
+ /// - LZMA_MEM_ERROR: Memory allocation failed.
+ lzma_ret (*props_decode)(void **options, lzma_allocator *allocator,
+ const uint8_t *props, size_t props_size);
+
+} lzma_filter_decoder;
+
+
+static const lzma_filter_decoder decoders[] = {
+#ifdef HAVE_DECODER_LZMA1
+ {
+ LZMA_FILTER_LZMA1,
+ &lzma_lzma_decoder_init,
+ &lzma_lzma_decoder_memusage,
+ &lzma_lzma_props_decode,
+ },
+#endif
+#ifdef HAVE_DECODER_LZMA2
+ {
+ LZMA_FILTER_LZMA2,
+ &lzma_lzma2_decoder_init,
+ &lzma_lzma2_decoder_memusage,
+ &lzma_lzma2_props_decode,
+ },
+#endif
+#ifdef HAVE_DECODER_X86
+ {
+ LZMA_FILTER_X86,
+ &lzma_simple_x86_decoder_init,
+ NULL,
+ &lzma_simple_props_decode,
+ },
+#endif
+#ifdef HAVE_DECODER_POWERPC
+ {
+ LZMA_FILTER_POWERPC,
+ &lzma_simple_powerpc_decoder_init,
+ NULL,
+ &lzma_simple_props_decode,
+ },
+#endif
+#ifdef HAVE_DECODER_IA64
+ {
+ LZMA_FILTER_IA64,
+ &lzma_simple_ia64_decoder_init,
+ NULL,
+ &lzma_simple_props_decode,
+ },
+#endif
+#ifdef HAVE_DECODER_ARM
+ {
+ LZMA_FILTER_ARM,
+ &lzma_simple_arm_decoder_init,
+ NULL,
+ &lzma_simple_props_decode,
+ },
+#endif
+#ifdef HAVE_DECODER_ARMTHUMB
+ {
+ LZMA_FILTER_ARMTHUMB,
+ &lzma_simple_armthumb_decoder_init,
+ NULL,
+ &lzma_simple_props_decode,
+ },
+#endif
+#ifdef HAVE_DECODER_SPARC
+ {
+ LZMA_FILTER_SPARC,
+ &lzma_simple_sparc_decoder_init,
+ NULL,
+ &lzma_simple_props_decode,
+ },
+#endif
+#ifdef HAVE_DECODER_DELTA
+ {
+ LZMA_FILTER_DELTA,
+ &lzma_delta_decoder_init,
+ &lzma_delta_coder_memusage,
+ &lzma_delta_props_decode,
+ },
+#endif
+};
+
+
+static const lzma_filter_decoder *
+decoder_find(lzma_vli id)
+{
+ size_t i;
+ for (i = 0; i < ARRAY_SIZE(decoders); ++i)
+ if (decoders[i].id == id)
+ return decoders + i;
+
+ return NULL;
+}
+
+
+extern LZMA_API(lzma_bool)
+lzma_filter_decoder_is_supported(lzma_vli id)
+{
+ return decoder_find(id) != NULL;
+}
+
+
+extern lzma_ret
+lzma_raw_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter *options)
+{
+ return lzma_raw_coder_init(next, allocator,
+ options, (lzma_filter_find)(&decoder_find), false);
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_raw_decoder(lzma_stream *strm, const lzma_filter *options)
+{
+ lzma_next_strm_init1(lzma_raw_decoder_init, strm, options);
+
+ strm->internal->supported_actions[LZMA_RUN] = true;
+ strm->internal->supported_actions[LZMA_FINISH] = true;
+
+ return LZMA_OK;
+}
+
+
+extern LZMA_API(uint64_t)
+lzma_raw_decoder_memusage(const lzma_filter *filters)
+{
+ return lzma_raw_coder_memusage(
+ (lzma_filter_find)(&decoder_find), filters);
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_properties_decode(lzma_filter *filter, lzma_allocator *allocator,
+ const uint8_t *props, size_t props_size)
+{
+ const lzma_filter_decoder *const fd = decoder_find(filter->id);
+
+ // Make it always NULL so that the caller can always safely free() it.
+ filter->options = NULL;
+
+ if (fd == NULL)
+ return LZMA_OPTIONS_ERROR;
+
+ if (fd->props_decode == NULL)
+ return props_size == 0 ? LZMA_OK : LZMA_OPTIONS_ERROR;
+
+ return fd->props_decode(
+ &filter->options, allocator, props, props_size);
+}
diff --git a/Utilities/cmliblzma/liblzma/common/filter_decoder.h b/Utilities/cmliblzma/liblzma/common/filter_decoder.h
new file mode 100644
index 000000000..d5c68bdd4
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/filter_decoder.h
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file filter_decoder.c
+/// \brief Filter ID mapping to filter-specific functions
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_FILTER_DECODER_H
+#define LZMA_FILTER_DECODER_H
+
+#include "common.h"
+
+
+extern lzma_ret lzma_raw_decoder_init(
+ lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter *options);
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/common/filter_encoder.c b/Utilities/cmliblzma/liblzma/common/filter_encoder.c
new file mode 100644
index 000000000..9fdb10008
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/filter_encoder.c
@@ -0,0 +1,297 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file filter_decoder.c
+/// \brief Filter ID mapping to filter-specific functions
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "filter_encoder.h"
+#include "filter_common.h"
+#include "lzma_encoder.h"
+#include "lzma2_encoder.h"
+#include "simple_encoder.h"
+#include "delta_encoder.h"
+
+
+typedef struct {
+ /// Filter ID
+ lzma_vli id;
+
+ /// Initializes the filter encoder and calls lzma_next_filter_init()
+ /// for filters + 1.
+ lzma_init_function init;
+
+ /// Calculates memory usage of the encoder. If the options are
+ /// invalid, UINT64_MAX is returned.
+ uint64_t (*memusage)(const void *options);
+
+ /// Calculates the minimum sane size for Blocks (or other types of
+ /// chunks) to which the input data can be split to make
+ /// multithreaded encoding possible. If this is NULL, it is assumed
+ /// that the encoder is fast enough with single thread.
+ lzma_vli (*chunk_size)(const void *options);
+
+ /// Tells the size of the Filter Properties field. If options are
+ /// invalid, UINT32_MAX is returned. If this is NULL, props_size_fixed
+ /// is used.
+ lzma_ret (*props_size_get)(uint32_t *size, const void *options);
+ uint32_t props_size_fixed;
+
+ /// Encodes Filter Properties.
+ ///
+ /// \return - LZMA_OK: Properties encoded successfully.
+ /// - LZMA_OPTIONS_ERROR: Unsupported options
+ /// - LZMA_PROG_ERROR: Invalid options or not enough
+ /// output space
+ lzma_ret (*props_encode)(const void *options, uint8_t *out);
+
+} lzma_filter_encoder;
+
+
+static const lzma_filter_encoder encoders[] = {
+#ifdef HAVE_ENCODER_LZMA1
+ {
+ LZMA_FILTER_LZMA1,
+ &lzma_lzma_encoder_init,
+ &lzma_lzma_encoder_memusage,
+ NULL, // FIXME
+ NULL,
+ 5,
+ &lzma_lzma_props_encode,
+ },
+#endif
+#ifdef HAVE_ENCODER_LZMA2
+ {
+ LZMA_FILTER_LZMA2,
+ &lzma_lzma2_encoder_init,
+ &lzma_lzma2_encoder_memusage,
+ NULL, // FIXME
+ NULL,
+ 1,
+ &lzma_lzma2_props_encode,
+ },
+#endif
+#ifdef HAVE_ENCODER_X86
+ {
+ LZMA_FILTER_X86,
+ &lzma_simple_x86_encoder_init,
+ NULL,
+ NULL,
+ &lzma_simple_props_size,
+ 0,
+ &lzma_simple_props_encode,
+ },
+#endif
+#ifdef HAVE_ENCODER_POWERPC
+ {
+ LZMA_FILTER_POWERPC,
+ &lzma_simple_powerpc_encoder_init,
+ NULL,
+ NULL,
+ &lzma_simple_props_size,
+ 0,
+ &lzma_simple_props_encode,
+ },
+#endif
+#ifdef HAVE_ENCODER_IA64
+ {
+ LZMA_FILTER_IA64,
+ &lzma_simple_ia64_encoder_init,
+ NULL,
+ NULL,
+ &lzma_simple_props_size,
+ 0,
+ &lzma_simple_props_encode,
+ },
+#endif
+#ifdef HAVE_ENCODER_ARM
+ {
+ LZMA_FILTER_ARM,
+ &lzma_simple_arm_encoder_init,
+ NULL,
+ NULL,
+ &lzma_simple_props_size,
+ 0,
+ &lzma_simple_props_encode,
+ },
+#endif
+#ifdef HAVE_ENCODER_ARMTHUMB
+ {
+ LZMA_FILTER_ARMTHUMB,
+ &lzma_simple_armthumb_encoder_init,
+ NULL,
+ NULL,
+ &lzma_simple_props_size,
+ 0,
+ &lzma_simple_props_encode,
+ },
+#endif
+#ifdef HAVE_ENCODER_SPARC
+ {
+ LZMA_FILTER_SPARC,
+ &lzma_simple_sparc_encoder_init,
+ NULL,
+ NULL,
+ &lzma_simple_props_size,
+ 0,
+ &lzma_simple_props_encode,
+ },
+#endif
+#ifdef HAVE_ENCODER_DELTA
+ {
+ LZMA_FILTER_DELTA,
+ &lzma_delta_encoder_init,
+ &lzma_delta_coder_memusage,
+ NULL,
+ NULL,
+ 1,
+ &lzma_delta_props_encode,
+ },
+#endif
+};
+
+
+static const lzma_filter_encoder *
+encoder_find(lzma_vli id)
+{
+ size_t i;
+ for (i = 0; i < ARRAY_SIZE(encoders); ++i)
+ if (encoders[i].id == id)
+ return encoders + i;
+
+ return NULL;
+}
+
+
+extern LZMA_API(lzma_bool)
+lzma_filter_encoder_is_supported(lzma_vli id)
+{
+ return encoder_find(id) != NULL;
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_filters_update(lzma_stream *strm, const lzma_filter *filters)
+{
+ size_t i;
+ size_t count = 1;
+ lzma_filter reversed_filters[LZMA_FILTERS_MAX + 1];
+
+ if (strm->internal->next.update == NULL)
+ return LZMA_PROG_ERROR;
+
+ // Validate the filter chain.
+ if (lzma_raw_encoder_memusage(filters) == UINT64_MAX)
+ return LZMA_OPTIONS_ERROR;
+
+ // The actual filter chain in the encoder is reversed. Some things
+ // still want the normal order chain, so we provide both.
+ while (filters[count].id != LZMA_VLI_UNKNOWN)
+ ++count;
+
+ for (i = 0; i < count; ++i)
+ reversed_filters[count - i - 1] = filters[i];
+
+ reversed_filters[count].id = LZMA_VLI_UNKNOWN;
+
+ return strm->internal->next.update(strm->internal->next.coder,
+ strm->allocator, filters, reversed_filters);
+}
+
+
+extern lzma_ret
+lzma_raw_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter *options)
+{
+ return lzma_raw_coder_init(next, allocator,
+ options, (lzma_filter_find)(&encoder_find), true);
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_raw_encoder(lzma_stream *strm, const lzma_filter *options)
+{
+ lzma_next_strm_init3(lzma_raw_coder_init, strm, options,
+ (lzma_filter_find)(&encoder_find), true);
+
+ strm->internal->supported_actions[LZMA_RUN] = true;
+ strm->internal->supported_actions[LZMA_SYNC_FLUSH] = true;
+ strm->internal->supported_actions[LZMA_FINISH] = true;
+
+ return LZMA_OK;
+}
+
+
+extern LZMA_API(uint64_t)
+lzma_raw_encoder_memusage(const lzma_filter *filters)
+{
+ return lzma_raw_coder_memusage(
+ (lzma_filter_find)(&encoder_find), filters);
+}
+
+
+/*
+extern LZMA_API(lzma_vli)
+lzma_chunk_size(const lzma_filter *filters)
+{
+ lzma_vli max = 0;
+
+ for (size_t i = 0; filters[i].id != LZMA_VLI_UNKNOWN; ++i) {
+ const lzma_filter_encoder *const fe
+ = encoder_find(filters[i].id);
+ if (fe->chunk_size != NULL) {
+ const lzma_vli size
+ = fe->chunk_size(filters[i].options);
+ if (size == LZMA_VLI_UNKNOWN)
+ return LZMA_VLI_UNKNOWN;
+
+ if (size > max)
+ max = size;
+ }
+ }
+
+ return max;
+}
+*/
+
+
+extern LZMA_API(lzma_ret)
+lzma_properties_size(uint32_t *size, const lzma_filter *filter)
+{
+ const lzma_filter_encoder *const fe = encoder_find(filter->id);
+ if (fe == NULL) {
+ // Unknown filter - if the Filter ID is a proper VLI,
+ // return LZMA_OPTIONS_ERROR instead of LZMA_PROG_ERROR,
+ // because it's possible that we just don't have support
+ // compiled in for the requested filter.
+ return filter->id <= LZMA_VLI_MAX
+ ? LZMA_OPTIONS_ERROR : LZMA_PROG_ERROR;
+ }
+
+ if (fe->props_size_get == NULL) {
+ // No props_size_get() function, use props_size_fixed.
+ *size = fe->props_size_fixed;
+ return LZMA_OK;
+ }
+
+ return fe->props_size_get(size, filter->options);
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_properties_encode(const lzma_filter *filter, uint8_t *props)
+{
+ const lzma_filter_encoder *const fe = encoder_find(filter->id);
+ if (fe == NULL)
+ return LZMA_PROG_ERROR;
+
+ if (fe->props_encode == NULL)
+ return LZMA_OK;
+
+ return fe->props_encode(filter->options, props);
+}
diff --git a/Utilities/cmliblzma/liblzma/common/filter_encoder.h b/Utilities/cmliblzma/liblzma/common/filter_encoder.h
new file mode 100644
index 000000000..5bc137f64
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/filter_encoder.h
@@ -0,0 +1,27 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file filter_encoder.c
+/// \brief Filter ID mapping to filter-specific functions
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_FILTER_ENCODER_H
+#define LZMA_FILTER_ENCODER_H
+
+#include "common.h"
+
+
+// FIXME: Might become a part of the public API once finished.
+// extern lzma_vli lzma_chunk_size(const lzma_filter *filters);
+
+
+extern lzma_ret lzma_raw_encoder_init(
+ lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter *filters);
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/common/filter_flags_decoder.c b/Utilities/cmliblzma/liblzma/common/filter_flags_decoder.c
new file mode 100644
index 000000000..aa2dbd560
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/filter_flags_decoder.c
@@ -0,0 +1,48 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file filter_flags_decoder.c
+/// \brief Decodes a Filter Flags field
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "filter_decoder.h"
+
+
+extern LZMA_API(lzma_ret)
+lzma_filter_flags_decode(
+ lzma_filter *filter, lzma_allocator *allocator,
+ const uint8_t *in, size_t *in_pos, size_t in_size)
+{
+ lzma_vli props_size;
+ lzma_ret ret;
+
+ // Set the pointer to NULL so the caller can always safely free it.
+ filter->options = NULL;
+
+ // Filter ID
+ return_if_error(lzma_vli_decode(&filter->id, NULL,
+ in, in_pos, in_size));
+
+ if (filter->id >= LZMA_FILTER_RESERVED_START)
+ return LZMA_DATA_ERROR;
+
+ // Size of Properties
+ return_if_error(lzma_vli_decode(&props_size, NULL,
+ in, in_pos, in_size));
+
+ // Filter Properties
+ if (in_size - *in_pos < props_size)
+ return LZMA_DATA_ERROR;
+
+ ret = lzma_properties_decode(
+ filter, allocator, in + *in_pos, props_size);
+
+ *in_pos += props_size;
+
+ return ret;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/filter_flags_encoder.c b/Utilities/cmliblzma/liblzma/common/filter_flags_encoder.c
new file mode 100644
index 000000000..755c407f6
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/filter_flags_encoder.c
@@ -0,0 +1,57 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file filter_flags_encoder.c
+/// \brief Decodes a Filter Flags field
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "filter_encoder.h"
+
+
+extern LZMA_API(lzma_ret)
+lzma_filter_flags_size(uint32_t *size, const lzma_filter *filter)
+{
+ if (filter->id >= LZMA_FILTER_RESERVED_START)
+ return LZMA_PROG_ERROR;
+
+ return_if_error(lzma_properties_size(size, filter));
+
+ *size += lzma_vli_size(filter->id) + lzma_vli_size(*size);
+
+ return LZMA_OK;
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_filter_flags_encode(const lzma_filter *filter,
+ uint8_t *out, size_t *out_pos, size_t out_size)
+{
+ uint32_t props_size;
+
+ // Filter ID
+ if (filter->id >= LZMA_FILTER_RESERVED_START)
+ return LZMA_PROG_ERROR;
+
+ return_if_error(lzma_vli_encode(filter->id, NULL,
+ out, out_pos, out_size));
+
+ // Size of Properties
+ return_if_error(lzma_properties_size(&props_size, filter));
+ return_if_error(lzma_vli_encode(props_size, NULL,
+ out, out_pos, out_size));
+
+ // Filter Properties
+ if (out_size - *out_pos < props_size)
+ return LZMA_PROG_ERROR;
+
+ return_if_error(lzma_properties_encode(filter, out + *out_pos));
+
+ *out_pos += props_size;
+
+ return LZMA_OK;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/hardware_physmem.c b/Utilities/cmliblzma/liblzma/common/hardware_physmem.c
new file mode 100644
index 000000000..7405b658a
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/hardware_physmem.c
@@ -0,0 +1,25 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file hardware_physmem.c
+/// \brief Get the total amount of physical memory (RAM)
+//
+// Author: Jonathan Nieder
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "common.h"
+
+#include "tuklib_physmem.h"
+
+
+extern LZMA_API(uint64_t)
+lzma_physmem(void)
+{
+ // It is simpler to make lzma_physmem() a wrapper for
+ // tuklib_physmem() than to hack appropriate symbol visiblity
+ // support for the tuklib modules.
+ return tuklib_physmem();
+}
diff --git a/Utilities/cmliblzma/liblzma/common/index.c b/Utilities/cmliblzma/liblzma/common/index.c
new file mode 100644
index 000000000..26135d22c
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/index.c
@@ -0,0 +1,1276 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file index.c
+/// \brief Handling of .xz Indexes and some other Stream information
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "index.h"
+#include "stream_flags_common.h"
+
+
+/// \brief How many Records to allocate at once
+///
+/// This should be big enough to avoid making lots of tiny allocations
+/// but small enough to avoid too much unused memory at once.
+#define INDEX_GROUP_SIZE 512
+
+
+/// \brief How many Records can be allocated at once at maximum
+#define PREALLOC_MAX ((SIZE_MAX - sizeof(index_group)) / sizeof(index_record))
+
+
+/// \brief Base structure for index_stream and index_group structures
+typedef struct index_tree_node_s index_tree_node;
+struct index_tree_node_s {
+ /// Uncompressed start offset of this Stream (relative to the
+ /// beginning of the file) or Block (relative to the beginning
+ /// of the Stream)
+ lzma_vli uncompressed_base;
+
+ /// Compressed start offset of this Stream or Block
+ lzma_vli compressed_base;
+
+ index_tree_node *parent;
+ index_tree_node *left;
+ index_tree_node *right;
+};
+
+
+/// \brief AVL tree to hold index_stream or index_group structures
+typedef struct {
+ /// Root node
+ index_tree_node *root;
+
+ /// Leftmost node. Since the tree will be filled sequentially,
+ /// this won't change after the first node has been added to
+ /// the tree.
+ index_tree_node *leftmost;
+
+ /// The rightmost node in the tree. Since the tree is filled
+ /// sequentially, this is always the node where to add the new data.
+ index_tree_node *rightmost;
+
+ /// Number of nodes in the tree
+ uint32_t count;
+
+} index_tree;
+
+
+typedef struct {
+ lzma_vli uncompressed_sum;
+ lzma_vli unpadded_sum;
+} index_record;
+
+
+typedef struct {
+ /// Every Record group is part of index_stream.groups tree.
+ index_tree_node node;
+
+ /// Number of Blocks in this Stream before this group.
+ lzma_vli number_base;
+
+ /// Number of Records that can be put in records[].
+ size_t allocated;
+
+ /// Index of the last Record in use.
+ size_t last;
+
+ /// The sizes in this array are stored as cumulative sums relative
+ /// to the beginning of the Stream. This makes it possible to
+ /// use binary search in lzma_index_locate().
+ ///
+ /// Note that the cumulative summing is done specially for
+ /// unpadded_sum: The previous value is rounded up to the next
+ /// multiple of four before adding the Unpadded Size of the new
+ /// Block. The total encoded size of the Blocks in the Stream
+ /// is records[last].unpadded_sum in the last Record group of
+ /// the Stream.
+ ///
+ /// For example, if the Unpadded Sizes are 39, 57, and 81, the
+ /// stored values are 39, 97 (40 + 57), and 181 (100 + 181).
+ /// The total encoded size of these Blocks is 184.
+ ///
+ /// This is a flexible array, because it makes easy to optimize
+ /// memory usage in case someone concatenates many Streams that
+ /// have only one or few Blocks.
+ index_record records[];
+
+} index_group;
+
+
+typedef struct {
+ /// Every index_stream is a node in the tree of Sreams.
+ index_tree_node node;
+
+ /// Number of this Stream (first one is 1)
+ uint32_t number;
+
+ /// Total number of Blocks before this Stream
+ lzma_vli block_number_base;
+
+ /// Record groups of this Stream are stored in a tree.
+ /// It's a T-tree with AVL-tree balancing. There are
+ /// INDEX_GROUP_SIZE Records per node by default.
+ /// This keeps the number of memory allocations reasonable
+ /// and finding a Record is fast.
+ index_tree groups;
+
+ /// Number of Records in this Stream
+ lzma_vli record_count;
+
+ /// Size of the List of Records field in this Stream. This is used
+ /// together with record_count to calculate the size of the Index
+ /// field and thus the total size of the Stream.
+ lzma_vli index_list_size;
+
+ /// Stream Flags of this Stream. This is meaningful only if
+ /// the Stream Flags have been told us with lzma_index_stream_flags().
+ /// Initially stream_flags.version is set to UINT32_MAX to indicate
+ /// that the Stream Flags are unknown.
+ lzma_stream_flags stream_flags;
+
+ /// Amount of Stream Padding after this Stream. This defaults to
+ /// zero and can be set with lzma_index_stream_padding().
+ lzma_vli stream_padding;
+
+} index_stream;
+
+
+struct lzma_index_s {
+ /// AVL-tree containing the Stream(s). Often there is just one
+ /// Stream, but using a tree keeps lookups fast even when there
+ /// are many concatenated Streams.
+ index_tree streams;
+
+ /// Uncompressed size of all the Blocks in the Stream(s)
+ lzma_vli uncompressed_size;
+
+ /// Total size of all the Blocks in the Stream(s)
+ lzma_vli total_size;
+
+ /// Total number of Records in all Streams in this lzma_index
+ lzma_vli record_count;
+
+ /// Size of the List of Records field if all the Streams in this
+ /// lzma_index were packed into a single Stream (makes it simpler to
+ /// take many .xz files and combine them into a single Stream).
+ ///
+ /// This value together with record_count is needed to calculate
+ /// Backward Size that is stored into Stream Footer.
+ lzma_vli index_list_size;
+
+ /// How many Records to allocate at once in lzma_index_append().
+ /// This defaults to INDEX_GROUP_SIZE but can be overriden with
+ /// lzma_index_prealloc().
+ size_t prealloc;
+
+ /// Bitmask indicating what integrity check types have been used
+ /// as set by lzma_index_stream_flags(). The bit of the last Stream
+ /// is not included here, since it is possible to change it by
+ /// calling lzma_index_stream_flags() again.
+ uint32_t checks;
+};
+
+
+static void
+index_tree_init(index_tree *tree)
+{
+ tree->root = NULL;
+ tree->leftmost = NULL;
+ tree->rightmost = NULL;
+ tree->count = 0;
+ return;
+}
+
+
+/// Helper for index_tree_end()
+static void
+index_tree_node_end(index_tree_node *node, lzma_allocator *allocator,
+ void (*free_func)(void *node, lzma_allocator *allocator))
+{
+ // The tree won't ever be very huge, so recursion should be fine.
+ // 20 levels in the tree is likely quite a lot already in practice.
+ if (node->left != NULL)
+ index_tree_node_end(node->left, allocator, free_func);
+
+ if (node->right != NULL)
+ index_tree_node_end(node->right, allocator, free_func);
+
+ if (free_func != NULL)
+ free_func(node, allocator);
+
+ lzma_free(node, allocator);
+ return;
+}
+
+
+/// Free the meory allocated for a tree. If free_func is not NULL,
+/// it is called on each node before freeing the node. This is used
+/// to free the Record groups from each index_stream before freeing
+/// the index_stream itself.
+static void
+index_tree_end(index_tree *tree, lzma_allocator *allocator,
+ void (*free_func)(void *node, lzma_allocator *allocator))
+{
+ if (tree->root != NULL)
+ index_tree_node_end(tree->root, allocator, free_func);
+
+ return;
+}
+
+
+/// Add a new node to the tree. node->uncompressed_base and
+/// node->compressed_base must have been set by the caller already.
+static void
+index_tree_append(index_tree *tree, index_tree_node *node)
+{
+ uint32_t up;
+ node->parent = tree->rightmost;
+ node->left = NULL;
+ node->right = NULL;
+
+ ++tree->count;
+
+ // Handle the special case of adding the first node.
+ if (tree->root == NULL) {
+ tree->root = node;
+ tree->leftmost = node;
+ tree->rightmost = node;
+ return;
+ }
+
+ // The tree is always filled sequentially.
+ assert(tree->rightmost->uncompressed_base <= node->uncompressed_base);
+ assert(tree->rightmost->compressed_base < node->compressed_base);
+
+ // Add the new node after the rightmost node. It's the correct
+ // place due to the reason above.
+ tree->rightmost->right = node;
+ tree->rightmost = node;
+
+ // Balance the AVL-tree if needed. We don't need to keep the balance
+ // factors in nodes, because we always fill the tree sequentially,
+ // and thus know the state of the tree just by looking at the node
+ // count. From the node count we can calculate how many steps to go
+ // up in the tree to find the rotation root.
+ up = tree->count ^ (UINT32_C(1) << bsr32(tree->count));
+ if (up != 0) {
+ index_tree_node *pivot;
+
+ // Locate the root node for the rotation.
+ up = ctz32(tree->count) + 2;
+ do {
+ node = node->parent;
+ } while (--up > 0);
+
+ // Rotate left using node as the rotation root.
+ pivot = node->right;
+
+ if (node->parent == NULL) {
+ tree->root = pivot;
+ } else {
+ assert(node->parent->right == node);
+ node->parent->right = pivot;
+ }
+
+ pivot->parent = node->parent;
+
+ node->right = pivot->left;
+ if (node->right != NULL)
+ node->right->parent = node;
+
+ pivot->left = node;
+ node->parent = pivot;
+ }
+
+ return;
+}
+
+
+/// Get the next node in the tree. Return NULL if there are no more nodes.
+static void *
+index_tree_next(const index_tree_node *node)
+{
+ if (node->right != NULL) {
+ node = node->right;
+ while (node->left != NULL)
+ node = node->left;
+
+ return (void *)(node);
+ }
+
+ while (node->parent != NULL && node->parent->right == node)
+ node = node->parent;
+
+ return (void *)(node->parent);
+}
+
+
+/// Locate a node that contains the given uncompressed offset. It is
+/// caller's job to check that target is not bigger than the uncompressed
+/// size of the tree (the last node would be returned in that case still).
+static void *
+index_tree_locate(const index_tree *tree, lzma_vli target)
+{
+ const index_tree_node *result = NULL;
+ const index_tree_node *node = tree->root;
+
+ assert(tree->leftmost == NULL
+ || tree->leftmost->uncompressed_base == 0);
+
+ // Consecutive nodes may have the same uncompressed_base.
+ // We must pick the rightmost one.
+ while (node != NULL) {
+ if (node->uncompressed_base > target) {
+ node = node->left;
+ } else {
+ result = node;
+ node = node->right;
+ }
+ }
+
+ return (void *)(result);
+}
+
+
+/// Allocate and initialize a new Stream using the given base offsets.
+static index_stream *
+index_stream_init(lzma_vli compressed_base, lzma_vli uncompressed_base,
+ lzma_vli stream_number, lzma_vli block_number_base,
+ lzma_allocator *allocator)
+{
+ index_stream *s = lzma_alloc(sizeof(index_stream), allocator);
+ if (s == NULL)
+ return NULL;
+
+ s->node.uncompressed_base = uncompressed_base;
+ s->node.compressed_base = compressed_base;
+ s->node.parent = NULL;
+ s->node.left = NULL;
+ s->node.right = NULL;
+
+ s->number = stream_number;
+ s->block_number_base = block_number_base;
+
+ index_tree_init(&s->groups);
+
+ s->record_count = 0;
+ s->index_list_size = 0;
+ s->stream_flags.version = UINT32_MAX;
+ s->stream_padding = 0;
+
+ return s;
+}
+
+
+/// Free the memory allocated for a Stream and its Record groups.
+static void
+index_stream_end(void *node, lzma_allocator *allocator)
+{
+ index_stream *s = node;
+ index_tree_end(&s->groups, allocator, NULL);
+ return;
+}
+
+
+static lzma_index *
+index_init_plain(lzma_allocator *allocator)
+{
+ lzma_index *i = lzma_alloc(sizeof(lzma_index), allocator);
+ if (i != NULL) {
+ index_tree_init(&i->streams);
+ i->uncompressed_size = 0;
+ i->total_size = 0;
+ i->record_count = 0;
+ i->index_list_size = 0;
+ i->prealloc = INDEX_GROUP_SIZE;
+ i->checks = 0;
+ }
+
+ return i;
+}
+
+
+extern LZMA_API(lzma_index *)
+lzma_index_init(lzma_allocator *allocator)
+{
+ index_stream *s;
+
+ lzma_index *i = index_init_plain(allocator);
+ if (i == NULL)
+ return NULL;
+
+ s = index_stream_init(0, 0, 1, 0, allocator);
+ if (s == NULL) {
+ lzma_free(i, allocator);
+ return NULL;
+ }
+
+ index_tree_append(&i->streams, &s->node);
+
+ return i;
+}
+
+
+extern LZMA_API(void)
+lzma_index_end(lzma_index *i, lzma_allocator *allocator)
+{
+ // NOTE: If you modify this function, check also the bottom
+ // of lzma_index_cat().
+ if (i != NULL) {
+ index_tree_end(&i->streams, allocator, &index_stream_end);
+ lzma_free(i, allocator);
+ }
+
+ return;
+}
+
+
+extern void
+lzma_index_prealloc(lzma_index *i, lzma_vli records)
+{
+ if (records > PREALLOC_MAX)
+ records = PREALLOC_MAX;
+
+ i->prealloc = (size_t)(records);
+ return;
+}
+
+
+extern LZMA_API(uint64_t)
+lzma_index_memusage(lzma_vli streams, lzma_vli blocks)
+{
+ // This calculates an upper bound that is only a little bit
+ // bigger than the exact maximum memory usage with the given
+ // parameters.
+
+ // Typical malloc() overhead is 2 * sizeof(void *) but we take
+ // a little bit extra just in case. Using LZMA_MEMUSAGE_BASE
+ // instead would give too inaccurate estimate.
+ const size_t alloc_overhead = 4 * sizeof(void *);
+
+ // Amount of memory needed for each Stream base structures.
+ // We assume that every Stream has at least one Block and
+ // thus at least one group.
+ const size_t stream_base = sizeof(index_stream)
+ + sizeof(index_group) + 2 * alloc_overhead;
+
+ // Amount of memory needed per group.
+ const size_t group_base = sizeof(index_group)
+ + INDEX_GROUP_SIZE * sizeof(index_record)
+ + alloc_overhead;
+
+ // Number of groups. There may actually be more, but that overhead
+ // has been taken into account in stream_base already.
+ const lzma_vli groups
+ = (blocks + INDEX_GROUP_SIZE - 1) / INDEX_GROUP_SIZE;
+
+ // Memory used by index_stream and index_group structures.
+ const uint64_t streams_mem = streams * stream_base;
+ const uint64_t groups_mem = groups * group_base;
+
+ // Memory used by the base structure.
+ const uint64_t index_base = sizeof(lzma_index) + alloc_overhead;
+
+ // Validate the arguments and catch integer overflows.
+ // Maximum number of Streams is "only" UINT32_MAX, because
+ // that limit is used by the tree containing the Streams.
+ const uint64_t limit = UINT64_MAX - index_base;
+ if (streams == 0 || streams > UINT32_MAX || blocks > LZMA_VLI_MAX
+ || streams > limit / stream_base
+ || groups > limit / group_base
+ || limit - streams_mem < groups_mem)
+ return UINT64_MAX;
+
+ return index_base + streams_mem + groups_mem;
+}
+
+
+extern LZMA_API(uint64_t)
+lzma_index_memused(const lzma_index *i)
+{
+ return lzma_index_memusage(i->streams.count, i->record_count);
+}
+
+
+extern LZMA_API(lzma_vli)
+lzma_index_block_count(const lzma_index *i)
+{
+ return i->record_count;
+}
+
+
+extern LZMA_API(lzma_vli)
+lzma_index_stream_count(const lzma_index *i)
+{
+ return i->streams.count;
+}
+
+
+extern LZMA_API(lzma_vli)
+lzma_index_size(const lzma_index *i)
+{
+ return index_size(i->record_count, i->index_list_size);
+}
+
+
+extern LZMA_API(lzma_vli)
+lzma_index_total_size(const lzma_index *i)
+{
+ return i->total_size;
+}
+
+
+extern LZMA_API(lzma_vli)
+lzma_index_stream_size(const lzma_index *i)
+{
+ // Stream Header + Blocks + Index + Stream Footer
+ return LZMA_STREAM_HEADER_SIZE + i->total_size
+ + index_size(i->record_count, i->index_list_size)
+ + LZMA_STREAM_HEADER_SIZE;
+}
+
+
+static lzma_vli
+index_file_size(lzma_vli compressed_base, lzma_vli unpadded_sum,
+ lzma_vli record_count, lzma_vli index_list_size,
+ lzma_vli stream_padding)
+{
+ // Earlier Streams and Stream Paddings + Stream Header
+ // + Blocks + Index + Stream Footer + Stream Padding
+ //
+ // This might go over LZMA_VLI_MAX due to too big unpadded_sum
+ // when this function is used in lzma_index_append().
+ lzma_vli file_size = compressed_base + 2 * LZMA_STREAM_HEADER_SIZE
+ + stream_padding + vli_ceil4(unpadded_sum);
+ if (file_size > LZMA_VLI_MAX)
+ return LZMA_VLI_UNKNOWN;
+
+ // The same applies here.
+ file_size += index_size(record_count, index_list_size);
+ if (file_size > LZMA_VLI_MAX)
+ return LZMA_VLI_UNKNOWN;
+
+ return file_size;
+}
+
+
+extern LZMA_API(lzma_vli)
+lzma_index_file_size(const lzma_index *i)
+{
+ const index_stream *s = (const index_stream *)(i->streams.rightmost);
+ const index_group *g = (const index_group *)(s->groups.rightmost);
+ return index_file_size(s->node.compressed_base,
+ g == NULL ? 0 : g->records[g->last].unpadded_sum,
+ s->record_count, s->index_list_size,
+ s->stream_padding);
+}
+
+
+extern LZMA_API(lzma_vli)
+lzma_index_uncompressed_size(const lzma_index *i)
+{
+ return i->uncompressed_size;
+}
+
+
+extern LZMA_API(uint32_t)
+lzma_index_checks(const lzma_index *i)
+{
+ uint32_t checks = i->checks;
+
+ // Get the type of the Check of the last Stream too.
+ const index_stream *s = (const index_stream *)(i->streams.rightmost);
+ if (s->stream_flags.version != UINT32_MAX)
+ checks |= UINT32_C(1) << s->stream_flags.check;
+
+ return checks;
+}
+
+
+extern uint32_t
+lzma_index_padding_size(const lzma_index *i)
+{
+ return (LZMA_VLI_C(4) - index_size_unpadded(
+ i->record_count, i->index_list_size)) & 3;
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_index_stream_flags(lzma_index *i, const lzma_stream_flags *stream_flags)
+{
+ index_stream *s;
+
+ if (i == NULL || stream_flags == NULL)
+ return LZMA_PROG_ERROR;
+
+ // Validate the Stream Flags.
+ return_if_error(lzma_stream_flags_compare(
+ stream_flags, stream_flags));
+
+ s = (index_stream *)(i->streams.rightmost);
+ s->stream_flags = *stream_flags;
+
+ return LZMA_OK;
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_index_stream_padding(lzma_index *i, lzma_vli stream_padding)
+{
+ index_stream *s;
+ lzma_vli old_stream_padding;
+
+ if (i == NULL || stream_padding > LZMA_VLI_MAX
+ || (stream_padding & 3) != 0)
+ return LZMA_PROG_ERROR;
+
+ s = (index_stream *)(i->streams.rightmost);
+
+ // Check that the new value won't make the file grow too big.
+ old_stream_padding = s->stream_padding;
+ s->stream_padding = 0;
+ if (lzma_index_file_size(i) + stream_padding > LZMA_VLI_MAX) {
+ s->stream_padding = old_stream_padding;
+ return LZMA_DATA_ERROR;
+ }
+
+ s->stream_padding = stream_padding;
+ return LZMA_OK;
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_index_append(lzma_index *i, lzma_allocator *allocator,
+ lzma_vli unpadded_size, lzma_vli uncompressed_size)
+{
+ index_stream *s;
+ index_group *g;
+ lzma_vli compressed_base;
+ lzma_vli uncompressed_base;
+ uint32_t index_list_size_add;
+
+ // Validate.
+ if (i == NULL || unpadded_size < UNPADDED_SIZE_MIN
+ || unpadded_size > UNPADDED_SIZE_MAX
+ || uncompressed_size > LZMA_VLI_MAX)
+ return LZMA_PROG_ERROR;
+
+ s = (index_stream *)(i->streams.rightmost);
+ g = (index_group *)(s->groups.rightmost);
+
+ compressed_base = g == NULL ? 0
+ : vli_ceil4(g->records[g->last].unpadded_sum);
+ uncompressed_base = g == NULL ? 0
+ : g->records[g->last].uncompressed_sum;
+ index_list_size_add = lzma_vli_size(unpadded_size)
+ + lzma_vli_size(uncompressed_size);
+
+ // Check that the file size will stay within limits.
+ if (index_file_size(s->node.compressed_base,
+ compressed_base + unpadded_size, s->record_count + 1,
+ s->index_list_size + index_list_size_add,
+ s->stream_padding) == LZMA_VLI_UNKNOWN)
+ return LZMA_DATA_ERROR;
+
+ // The size of the Index field must not exceed the maximum value
+ // that can be stored in the Backward Size field.
+ if (index_size(i->record_count + 1,
+ i->index_list_size + index_list_size_add)
+ > LZMA_BACKWARD_SIZE_MAX)
+ return LZMA_DATA_ERROR;
+
+ if (g != NULL && g->last + 1 < g->allocated) {
+ // There is space in the last group at least for one Record.
+ ++g->last;
+ } else {
+ // We need to allocate a new group.
+ g = lzma_alloc(sizeof(index_group)
+ + i->prealloc * sizeof(index_record),
+ allocator);
+ if (g == NULL)
+ return LZMA_MEM_ERROR;
+
+ g->last = 0;
+ g->allocated = i->prealloc;
+
+ // Reset prealloc so that if the application happens to
+ // add new Records, the allocation size will be sane.
+ i->prealloc = INDEX_GROUP_SIZE;
+
+ // Set the start offsets of this group.
+ g->node.uncompressed_base = uncompressed_base;
+ g->node.compressed_base = compressed_base;
+ g->number_base = s->record_count + 1;
+
+ // Add the new group to the Stream.
+ index_tree_append(&s->groups, &g->node);
+ }
+
+ // Add the new Record to the group.
+ g->records[g->last].uncompressed_sum
+ = uncompressed_base + uncompressed_size;
+ g->records[g->last].unpadded_sum
+ = compressed_base + unpadded_size;
+
+ // Update the totals.
+ ++s->record_count;
+ s->index_list_size += index_list_size_add;
+
+ i->total_size += vli_ceil4(unpadded_size);
+ i->uncompressed_size += uncompressed_size;
+ ++i->record_count;
+ i->index_list_size += index_list_size_add;
+
+ return LZMA_OK;
+}
+
+
+/// Structure to pass info to index_cat_helper()
+typedef struct {
+ /// Uncompressed size of the destination
+ lzma_vli uncompressed_size;
+
+ /// Compressed file size of the destination
+ lzma_vli file_size;
+
+ /// Same as above but for Block numbers
+ lzma_vli block_number_add;
+
+ /// Number of Streams that were in the destination index before we
+ /// started appending new Streams from the source index. This is
+ /// used to fix the Stream numbering.
+ uint32_t stream_number_add;
+
+ /// Destination index' Stream tree
+ index_tree *streams;
+
+} index_cat_info;
+
+
+/// Add the Stream nodes from the source index to dest using recursion.
+/// Simplest iterative traversal of the source tree wouldn't work, because
+/// we update the pointers in nodes when moving them to the destination tree.
+static void
+index_cat_helper(const index_cat_info *info, index_stream *this)
+{
+ index_stream *left = (index_stream *)(this->node.left);
+ index_stream *right = (index_stream *)(this->node.right);
+
+ if (left != NULL)
+ index_cat_helper(info, left);
+
+ this->node.uncompressed_base += info->uncompressed_size;
+ this->node.compressed_base += info->file_size;
+ this->number += info->stream_number_add;
+ this->block_number_base += info->block_number_add;
+ index_tree_append(info->streams, &this->node);
+
+ if (right != NULL)
+ index_cat_helper(info, right);
+
+ return;
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_index_cat(lzma_index *LZMA_RESTRICT dest, lzma_index *LZMA_RESTRICT src,
+ lzma_allocator *allocator)
+{
+ index_cat_info info;
+ const lzma_vli dest_file_size = lzma_index_file_size(dest);
+
+ // Check that we don't exceed the file size limits.
+ if (dest_file_size + lzma_index_file_size(src) > LZMA_VLI_MAX
+ || dest->uncompressed_size + src->uncompressed_size
+ > LZMA_VLI_MAX)
+ return LZMA_DATA_ERROR;
+
+ // Check that the encoded size of the combined lzma_indexes stays
+ // within limits. In theory, this should be done only if we know
+ // that the user plans to actually combine the Streams and thus
+ // construct a single Index (probably rare). However, exceeding
+ // this limit is quite theoretical, so we do this check always
+ // to simplify things elsewhere.
+ {
+ const lzma_vli dest_size = index_size_unpadded(
+ dest->record_count, dest->index_list_size);
+ const lzma_vli src_size = index_size_unpadded(
+ src->record_count, src->index_list_size);
+ if (vli_ceil4(dest_size + src_size) > LZMA_BACKWARD_SIZE_MAX)
+ return LZMA_DATA_ERROR;
+ }
+
+ // Optimize the last group to minimize memory usage. Allocation has
+ // to be done before modifying dest or src.
+ {
+ index_stream *s = (index_stream *)(dest->streams.rightmost);
+ index_group *g = (index_group *)(s->groups.rightmost);
+ if (g != NULL && g->last + 1 < g->allocated) {
+ index_group *newg;
+
+ assert(g->node.left == NULL);
+ assert(g->node.right == NULL);
+
+ newg = lzma_alloc(sizeof(index_group)
+ + (g->last + 1)
+ * sizeof(index_record),
+ allocator);
+ if (newg == NULL)
+ return LZMA_MEM_ERROR;
+
+ newg->node = g->node;
+ newg->allocated = g->last + 1;
+ newg->last = g->last;
+ newg->number_base = g->number_base;
+
+ memcpy(newg->records, g->records, newg->allocated
+ * sizeof(index_record));
+
+ if (g->node.parent != NULL) {
+ assert(g->node.parent->right == &g->node);
+ g->node.parent->right = &newg->node;
+ }
+
+ if (s->groups.leftmost == &g->node) {
+ assert(s->groups.root == &g->node);
+ s->groups.leftmost = &newg->node;
+ s->groups.root = &newg->node;
+ }
+
+ if (s->groups.rightmost == &g->node)
+ s->groups.rightmost = &newg->node;
+
+ lzma_free(g, allocator);
+ }
+ }
+
+ // Add all the Streams from src to dest. Update the base offsets
+ // of each Stream from src.
+ info.uncompressed_size = dest->uncompressed_size;
+ info.file_size = dest_file_size;
+ info.stream_number_add = dest->streams.count;
+ info.block_number_add = dest->record_count;
+ info.streams = &dest->streams;
+
+ index_cat_helper(&info, (index_stream *)(src->streams.root));
+
+ // Update info about all the combined Streams.
+ dest->uncompressed_size += src->uncompressed_size;
+ dest->total_size += src->total_size;
+ dest->record_count += src->record_count;
+ dest->index_list_size += src->index_list_size;
+ dest->checks = lzma_index_checks(dest) | src->checks;
+
+ // There's nothing else left in src than the base structure.
+ lzma_free(src, allocator);
+
+ return LZMA_OK;
+}
+
+
+/// Duplicate an index_stream.
+static index_stream *
+index_dup_stream(const index_stream *src, lzma_allocator *allocator)
+{
+ index_stream *dest;
+ index_group *destg;
+ index_group *srcg;
+ size_t i = 0;
+
+ // Catch a somewhat theoretical integer overflow.
+ if (src->record_count > PREALLOC_MAX)
+ return NULL;
+
+ // Allocate and initialize a new Stream.
+ dest = index_stream_init(src->node.compressed_base,
+ src->node.uncompressed_base, src->number,
+ src->block_number_base, allocator);
+
+ // Return immediately if allocation failed or if there are
+ // no groups to duplicate.
+ if (dest == NULL || src->groups.leftmost == NULL)
+ return dest;
+
+ // Copy the overall information.
+ dest->record_count = src->record_count;
+ dest->index_list_size = src->index_list_size;
+ dest->stream_flags = src->stream_flags;
+ dest->stream_padding = src->stream_padding;
+
+ // Allocate memory for the Records. We put all the Records into
+ // a single group. It's simplest and also tends to make
+ // lzma_index_locate() a little bit faster with very big Indexes.
+ destg = lzma_alloc(sizeof(index_group)
+ + src->record_count * sizeof(index_record),
+ allocator);
+ if (destg == NULL) {
+ index_stream_end(dest, allocator);
+ return NULL;
+ }
+
+ // Initialize destg.
+ destg->node.uncompressed_base = 0;
+ destg->node.compressed_base = 0;
+ destg->number_base = 1;
+ destg->allocated = src->record_count;
+ destg->last = src->record_count - 1;
+
+ // Go through all the groups in src and copy the Records into destg.
+ srcg = (index_group *)(src->groups.leftmost);
+ do {
+ memcpy(destg->records + i, srcg->records,
+ (srcg->last + 1) * sizeof(index_record));
+ i += srcg->last + 1;
+ srcg = index_tree_next(&srcg->node);
+ } while (srcg != NULL);
+
+ assert(i == destg->allocated);
+
+ // Add the group to the new Stream.
+ index_tree_append(&dest->groups, &destg->node);
+
+ return dest;
+}
+
+
+extern LZMA_API(lzma_index *)
+lzma_index_dup(const lzma_index *src, lzma_allocator *allocator)
+{
+ index_stream *srcstream;
+ index_stream *deststream;
+
+ // Allocate the base structure (no initial Stream).
+ lzma_index *dest = index_init_plain(allocator);
+ if (dest == NULL)
+ return NULL;
+
+ // Copy the totals.
+ dest->uncompressed_size = src->uncompressed_size;
+ dest->total_size = src->total_size;
+ dest->record_count = src->record_count;
+ dest->index_list_size = src->index_list_size;
+
+ // Copy the Streams and the groups in them.
+ srcstream = (index_stream *)(src->streams.leftmost);
+ do {
+ deststream = index_dup_stream(srcstream, allocator);
+ if (deststream == NULL) {
+ lzma_index_end(dest, allocator);
+ return NULL;
+ }
+
+ index_tree_append(&dest->streams, &deststream->node);
+
+ srcstream = index_tree_next(&srcstream->node);
+ } while (srcstream != NULL);
+
+ return dest;
+}
+
+
+/// Indexing for lzma_index_iter.internal[]
+enum {
+ ITER_INDEX,
+ ITER_STREAM,
+ ITER_GROUP,
+ ITER_RECORD,
+ ITER_METHOD,
+};
+
+
+/// Values for lzma_index_iter.internal[ITER_METHOD].s
+enum {
+ ITER_METHOD_NORMAL,
+ ITER_METHOD_NEXT,
+ ITER_METHOD_LEFTMOST,
+};
+
+
+static void
+iter_set_info(lzma_index_iter *iter)
+{
+ const lzma_index *i = iter->internal[ITER_INDEX].p;
+ const index_stream *stream = iter->internal[ITER_STREAM].p;
+ const index_group *group = iter->internal[ITER_GROUP].p;
+ const size_t record = iter->internal[ITER_RECORD].s;
+
+ // lzma_index_iter.internal must not contain a pointer to the last
+ // group in the index, because that may be reallocated by
+ // lzma_index_cat().
+ if (group == NULL) {
+ // There are no groups.
+ assert(stream->groups.root == NULL);
+ iter->internal[ITER_METHOD].s = ITER_METHOD_LEFTMOST;
+
+ } else if (i->streams.rightmost != &stream->node
+ || stream->groups.rightmost != &group->node) {
+ // The group is not not the last group in the index.
+ iter->internal[ITER_METHOD].s = ITER_METHOD_NORMAL;
+
+ } else if (stream->groups.leftmost != &group->node) {
+ // The group isn't the only group in the Stream, thus we
+ // know that it must have a parent group i.e. it's not
+ // the root node.
+ assert(stream->groups.root != &group->node);
+ assert(group->node.parent->right == &group->node);
+ iter->internal[ITER_METHOD].s = ITER_METHOD_NEXT;
+ iter->internal[ITER_GROUP].p = group->node.parent;
+
+ } else {
+ // The Stream has only one group.
+ assert(stream->groups.root == &group->node);
+ assert(group->node.parent == NULL);
+ iter->internal[ITER_METHOD].s = ITER_METHOD_LEFTMOST;
+ iter->internal[ITER_GROUP].p = NULL;
+ }
+
+ iter->stream.number = stream->number;
+ iter->stream.block_count = stream->record_count;
+ iter->stream.compressed_offset = stream->node.compressed_base;
+ iter->stream.uncompressed_offset = stream->node.uncompressed_base;
+
+ // iter->stream.flags will be NULL if the Stream Flags haven't been
+ // set with lzma_index_stream_flags().
+ iter->stream.flags = stream->stream_flags.version == UINT32_MAX
+ ? NULL : &stream->stream_flags;
+ iter->stream.padding = stream->stream_padding;
+
+ if (stream->groups.rightmost == NULL) {
+ // Stream has no Blocks.
+ iter->stream.compressed_size = index_size(0, 0)
+ + 2 * LZMA_STREAM_HEADER_SIZE;
+ iter->stream.uncompressed_size = 0;
+ } else {
+ const index_group *g = (const index_group *)(
+ stream->groups.rightmost);
+
+ // Stream Header + Stream Footer + Index + Blocks
+ iter->stream.compressed_size = 2 * LZMA_STREAM_HEADER_SIZE
+ + index_size(stream->record_count,
+ stream->index_list_size)
+ + vli_ceil4(g->records[g->last].unpadded_sum);
+ iter->stream.uncompressed_size
+ = g->records[g->last].uncompressed_sum;
+ }
+
+ if (group != NULL) {
+ iter->block.number_in_stream = group->number_base + record;
+ iter->block.number_in_file = iter->block.number_in_stream
+ + stream->block_number_base;
+
+ iter->block.compressed_stream_offset
+ = record == 0 ? group->node.compressed_base
+ : vli_ceil4(group->records[
+ record - 1].unpadded_sum);
+ iter->block.uncompressed_stream_offset
+ = record == 0 ? group->node.uncompressed_base
+ : group->records[record - 1].uncompressed_sum;
+
+ iter->block.uncompressed_size
+ = group->records[record].uncompressed_sum
+ - iter->block.uncompressed_stream_offset;
+ iter->block.unpadded_size
+ = group->records[record].unpadded_sum
+ - iter->block.compressed_stream_offset;
+ iter->block.total_size = vli_ceil4(iter->block.unpadded_size);
+
+ iter->block.compressed_stream_offset
+ += LZMA_STREAM_HEADER_SIZE;
+
+ iter->block.compressed_file_offset
+ = iter->block.compressed_stream_offset
+ + iter->stream.compressed_offset;
+ iter->block.uncompressed_file_offset
+ = iter->block.uncompressed_stream_offset
+ + iter->stream.uncompressed_offset;
+ }
+
+ return;
+}
+
+
+extern LZMA_API(void)
+lzma_index_iter_init(lzma_index_iter *iter, const lzma_index *i)
+{
+ iter->internal[ITER_INDEX].p = i;
+ lzma_index_iter_rewind(iter);
+ return;
+}
+
+
+extern LZMA_API(void)
+lzma_index_iter_rewind(lzma_index_iter *iter)
+{
+ iter->internal[ITER_STREAM].p = NULL;
+ iter->internal[ITER_GROUP].p = NULL;
+ iter->internal[ITER_RECORD].s = 0;
+ iter->internal[ITER_METHOD].s = ITER_METHOD_NORMAL;
+ return;
+}
+
+
+extern LZMA_API(lzma_bool)
+lzma_index_iter_next(lzma_index_iter *iter, lzma_index_iter_mode mode)
+{
+ const lzma_index *i;
+ const index_stream *stream;
+ const index_group *group;
+ size_t record;
+
+ // Catch unsupported mode values.
+ if ((unsigned int)(mode) > LZMA_INDEX_ITER_NONEMPTY_BLOCK)
+ return true;
+
+ i = iter->internal[ITER_INDEX].p;
+ stream = iter->internal[ITER_STREAM].p;
+ group = NULL;
+ record = iter->internal[ITER_RECORD].s;
+
+ // If we are being asked for the next Stream, leave group to NULL
+ // so that the rest of the this function thinks that this Stream
+ // has no groups and will thus go to the next Stream.
+ if (mode != LZMA_INDEX_ITER_STREAM) {
+ // Get the pointer to the current group. See iter_set_inf()
+ // for explanation.
+ switch (iter->internal[ITER_METHOD].s) {
+ case ITER_METHOD_NORMAL:
+ group = iter->internal[ITER_GROUP].p;
+ break;
+
+ case ITER_METHOD_NEXT:
+ group = index_tree_next(iter->internal[ITER_GROUP].p);
+ break;
+
+ case ITER_METHOD_LEFTMOST:
+ group = (const index_group *)(
+ stream->groups.leftmost);
+ break;
+ }
+ }
+
+again:
+ if (stream == NULL) {
+ // We at the beginning of the lzma_index.
+ // Locate the first Stream.
+ stream = (const index_stream *)(i->streams.leftmost);
+ if (mode >= LZMA_INDEX_ITER_BLOCK) {
+ // Since we are being asked to return information
+ // about the first a Block, skip Streams that have
+ // no Blocks.
+ while (stream->groups.leftmost == NULL) {
+ stream = index_tree_next(&stream->node);
+ if (stream == NULL)
+ return true;
+ }
+ }
+
+ // Start from the first Record in the Stream.
+ group = (const index_group *)(stream->groups.leftmost);
+ record = 0;
+
+ } else if (group != NULL && record < group->last) {
+ // The next Record is in the same group.
+ ++record;
+
+ } else {
+ // This group has no more Records or this Stream has
+ // no Blocks at all.
+ record = 0;
+
+ // If group is not NULL, this Stream has at least one Block
+ // and thus at least one group. Find the next group.
+ if (group != NULL)
+ group = index_tree_next(&group->node);
+
+ if (group == NULL) {
+ // This Stream has no more Records. Find the next
+ // Stream. If we are being asked to return information
+ // about a Block, we skip empty Streams.
+ do {
+ stream = index_tree_next(&stream->node);
+ if (stream == NULL)
+ return true;
+ } while (mode >= LZMA_INDEX_ITER_BLOCK
+ && stream->groups.leftmost == NULL);
+
+ group = (const index_group *)(
+ stream->groups.leftmost);
+ }
+ }
+
+ if (mode == LZMA_INDEX_ITER_NONEMPTY_BLOCK) {
+ // We need to look for the next Block again if this Block
+ // is empty.
+ if (record == 0) {
+ if (group->node.uncompressed_base
+ == group->records[0].uncompressed_sum)
+ goto again;
+ } else if (group->records[record - 1].uncompressed_sum
+ == group->records[record].uncompressed_sum) {
+ goto again;
+ }
+ }
+
+ iter->internal[ITER_STREAM].p = stream;
+ iter->internal[ITER_GROUP].p = group;
+ iter->internal[ITER_RECORD].s = record;
+
+ iter_set_info(iter);
+
+ return false;
+}
+
+
+extern LZMA_API(lzma_bool)
+lzma_index_iter_locate(lzma_index_iter *iter, lzma_vli target)
+{
+ const index_stream *stream;
+ const index_group *group;
+ size_t left, right;
+
+ const lzma_index *i = iter->internal[ITER_INDEX].p;
+
+ // If the target is past the end of the file, return immediately.
+ if (i->uncompressed_size <= target)
+ return true;
+
+ // Locate the Stream containing the target offset.
+ stream = index_tree_locate(&i->streams, target);
+ assert(stream != NULL);
+ target -= stream->node.uncompressed_base;
+
+ // Locate the group containing the target offset.
+ group = index_tree_locate(&stream->groups, target);
+ assert(group != NULL);
+
+ // Use binary search to locate the exact Record. It is the first
+ // Record whose uncompressed_sum is greater than target.
+ // This is because we want the rightmost Record that fullfills the
+ // search criterion. It is possible that there are empty Blocks;
+ // we don't want to return them.
+ left = 0;
+ right = group->last;
+
+ while (left < right) {
+ const size_t pos = left + (right - left) / 2;
+ if (group->records[pos].uncompressed_sum <= target)
+ left = pos + 1;
+ else
+ right = pos;
+ }
+
+ iter->internal[ITER_STREAM].p = stream;
+ iter->internal[ITER_GROUP].p = group;
+ iter->internal[ITER_RECORD].s = left;
+
+ iter_set_info(iter);
+
+ return false;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/index.h b/Utilities/cmliblzma/liblzma/common/index.h
new file mode 100644
index 000000000..64e97247d
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/index.h
@@ -0,0 +1,73 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file index.h
+/// \brief Handling of Index
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_INDEX_H
+#define LZMA_INDEX_H
+
+#include "common.h"
+
+
+/// Minimum Unpadded Size
+#define UNPADDED_SIZE_MIN LZMA_VLI_C(5)
+
+/// Maximum Unpadded Size
+#define UNPADDED_SIZE_MAX (LZMA_VLI_MAX & ~LZMA_VLI_C(3))
+
+
+/// Get the size of the Index Padding field. This is needed by Index encoder
+/// and decoder, but applications should have no use for this.
+extern uint32_t lzma_index_padding_size(const lzma_index *i);
+
+
+/// Set for how many Records to allocate memory the next time
+/// lzma_index_append() needs to allocate space for a new Record.
+/// This is used only by the Index decoder.
+extern void lzma_index_prealloc(lzma_index *i, lzma_vli records);
+
+
+/// Round the variable-length integer to the next multiple of four.
+static inline lzma_vli
+vli_ceil4(lzma_vli vli)
+{
+ assert(vli <= LZMA_VLI_MAX);
+ return (vli + 3) & ~LZMA_VLI_C(3);
+}
+
+
+/// Calculate the size of the Index field excluding Index Padding
+static inline lzma_vli
+index_size_unpadded(lzma_vli count, lzma_vli index_list_size)
+{
+ // Index Indicator + Number of Records + List of Records + CRC32
+ return 1 + lzma_vli_size(count) + index_list_size + 4;
+}
+
+
+/// Calculate the size of the Index field including Index Padding
+static inline lzma_vli
+index_size(lzma_vli count, lzma_vli index_list_size)
+{
+ return vli_ceil4(index_size_unpadded(count, index_list_size));
+}
+
+
+/// Calculate the total size of the Stream
+static inline lzma_vli
+index_stream_size(lzma_vli blocks_size,
+ lzma_vli count, lzma_vli index_list_size)
+{
+ return LZMA_STREAM_HEADER_SIZE + blocks_size
+ + index_size(count, index_list_size)
+ + LZMA_STREAM_HEADER_SIZE;
+}
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/common/index_decoder.c b/Utilities/cmliblzma/liblzma/common/index_decoder.c
new file mode 100644
index 000000000..943cfd58a
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/index_decoder.c
@@ -0,0 +1,347 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file index_decoder.c
+/// \brief Decodes the Index field
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "index.h"
+#include "check.h"
+
+
+struct lzma_coder_s {
+ enum {
+ SEQ_INDICATOR,
+ SEQ_COUNT,
+ SEQ_MEMUSAGE,
+ SEQ_UNPADDED,
+ SEQ_UNCOMPRESSED,
+ SEQ_PADDING_INIT,
+ SEQ_PADDING,
+ SEQ_CRC32,
+ } sequence;
+
+ /// Memory usage limit
+ uint64_t memlimit;
+
+ /// Target Index
+ lzma_index *index;
+
+ /// Pointer give by the application, which is set after
+ /// successful decoding.
+ lzma_index **index_ptr;
+
+ /// Number of Records left to decode.
+ lzma_vli count;
+
+ /// The most recent Unpadded Size field
+ lzma_vli unpadded_size;
+
+ /// The most recent Uncompressed Size field
+ lzma_vli uncompressed_size;
+
+ /// Position in integers
+ size_t pos;
+
+ /// CRC32 of the List of Records field
+ uint32_t crc32;
+};
+
+
+static lzma_ret
+index_decode(lzma_coder *coder, lzma_allocator *allocator,
+ const uint8_t *LZMA_RESTRICT in, size_t *LZMA_RESTRICT in_pos,
+ size_t in_size,
+ uint8_t *LZMA_RESTRICT out lzma_attribute((__unused__)),
+ size_t *LZMA_RESTRICT out_pos lzma_attribute((__unused__)),
+ size_t out_size lzma_attribute((__unused__)),
+ lzma_action action lzma_attribute((__unused__)))
+{
+ // Similar optimization as in index_encoder.c
+ const size_t in_start = *in_pos;
+ lzma_ret ret = LZMA_OK;
+
+ while (*in_pos < in_size)
+ switch (coder->sequence) {
+ case SEQ_INDICATOR:
+ // Return LZMA_DATA_ERROR instead of e.g. LZMA_PROG_ERROR or
+ // LZMA_FORMAT_ERROR, because a typical usage case for Index
+ // decoder is when parsing the Stream backwards. If seeking
+ // backward from the Stream Footer gives us something that
+ // doesn't begin with Index Indicator, the file is considered
+ // corrupt, not "programming error" or "unrecognized file
+ // format". One could argue that the application should
+ // verify the Index Indicator before trying to decode the
+ // Index, but well, I suppose it is simpler this way.
+ if (in[(*in_pos)++] != 0x00)
+ return LZMA_DATA_ERROR;
+
+ coder->sequence = SEQ_COUNT;
+ break;
+
+ case SEQ_COUNT:
+ ret = lzma_vli_decode(&coder->count, &coder->pos,
+ in, in_pos, in_size);
+ if (ret != LZMA_STREAM_END)
+ goto out;
+
+ coder->pos = 0;
+ coder->sequence = SEQ_MEMUSAGE;
+
+ // Fall through
+
+ case SEQ_MEMUSAGE:
+ if (lzma_index_memusage(1, coder->count) > coder->memlimit) {
+ ret = LZMA_MEMLIMIT_ERROR;
+ goto out;
+ }
+
+ // Tell the Index handling code how many Records this
+ // Index has to allow it to allocate memory more efficiently.
+ lzma_index_prealloc(coder->index, coder->count);
+
+ ret = LZMA_OK;
+ coder->sequence = coder->count == 0
+ ? SEQ_PADDING_INIT : SEQ_UNPADDED;
+ break;
+
+ case SEQ_UNPADDED:
+ case SEQ_UNCOMPRESSED: {
+ lzma_vli *size = coder->sequence == SEQ_UNPADDED
+ ? &coder->unpadded_size
+ : &coder->uncompressed_size;
+
+ ret = lzma_vli_decode(size, &coder->pos,
+ in, in_pos, in_size);
+ if (ret != LZMA_STREAM_END)
+ goto out;
+
+ ret = LZMA_OK;
+ coder->pos = 0;
+
+ if (coder->sequence == SEQ_UNPADDED) {
+ // Validate that encoded Unpadded Size isn't too small
+ // or too big.
+ if (coder->unpadded_size < UNPADDED_SIZE_MIN
+ || coder->unpadded_size
+ > UNPADDED_SIZE_MAX)
+ return LZMA_DATA_ERROR;
+
+ coder->sequence = SEQ_UNCOMPRESSED;
+ } else {
+ // Add the decoded Record to the Index.
+ return_if_error(lzma_index_append(
+ coder->index, allocator,
+ coder->unpadded_size,
+ coder->uncompressed_size));
+
+ // Check if this was the last Record.
+ coder->sequence = --coder->count == 0
+ ? SEQ_PADDING_INIT
+ : SEQ_UNPADDED;
+ }
+
+ break;
+ }
+
+ case SEQ_PADDING_INIT:
+ coder->pos = lzma_index_padding_size(coder->index);
+ coder->sequence = SEQ_PADDING;
+
+ // Fall through
+
+ case SEQ_PADDING:
+ if (coder->pos > 0) {
+ --coder->pos;
+ if (in[(*in_pos)++] != 0x00)
+ return LZMA_DATA_ERROR;
+
+ break;
+ }
+
+ // Finish the CRC32 calculation.
+ coder->crc32 = lzma_crc32(in + in_start,
+ *in_pos - in_start, coder->crc32);
+
+ coder->sequence = SEQ_CRC32;
+
+ // Fall through
+
+ case SEQ_CRC32:
+ do {
+ if (*in_pos == in_size)
+ return LZMA_OK;
+
+ if (((coder->crc32 >> (coder->pos * 8)) & 0xFF)
+ != in[(*in_pos)++])
+ return LZMA_DATA_ERROR;
+
+ } while (++coder->pos < 4);
+
+ // Decoding was successful, now we can let the application
+ // see the decoded Index.
+ *coder->index_ptr = coder->index;
+
+ // Make index NULL so we don't free it unintentionally.
+ coder->index = NULL;
+
+ return LZMA_STREAM_END;
+
+ default:
+ assert(0);
+ return LZMA_PROG_ERROR;
+ }
+
+out:
+ // Update the CRC32,
+ coder->crc32 = lzma_crc32(in + in_start,
+ *in_pos - in_start, coder->crc32);
+
+ return ret;
+}
+
+
+static void
+index_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
+{
+ lzma_index_end(coder->index, allocator);
+ lzma_free(coder, allocator);
+ return;
+}
+
+
+static lzma_ret
+index_decoder_memconfig(lzma_coder *coder, uint64_t *memusage,
+ uint64_t *old_memlimit, uint64_t new_memlimit)
+{
+ *memusage = lzma_index_memusage(1, coder->count);
+ *old_memlimit = coder->memlimit;
+
+ if (new_memlimit != 0) {
+ if (new_memlimit < *memusage)
+ return LZMA_MEMLIMIT_ERROR;
+
+ coder->memlimit = new_memlimit;
+ }
+
+ return LZMA_OK;
+}
+
+
+static lzma_ret
+index_decoder_reset(lzma_coder *coder, lzma_allocator *allocator,
+ lzma_index **i, uint64_t memlimit)
+{
+ // Remember the pointer given by the application. We will set it
+ // to point to the decoded Index only if decoding is successful.
+ // Before that, keep it NULL so that applications can always safely
+ // pass it to lzma_index_end() no matter did decoding succeed or not.
+ coder->index_ptr = i;
+ *i = NULL;
+
+ // We always allocate a new lzma_index.
+ coder->index = lzma_index_init(allocator);
+ if (coder->index == NULL)
+ return LZMA_MEM_ERROR;
+
+ // Initialize the rest.
+ coder->sequence = SEQ_INDICATOR;
+ coder->memlimit = memlimit;
+ coder->count = 0; // Needs to be initialized due to _memconfig().
+ coder->pos = 0;
+ coder->crc32 = 0;
+
+ return LZMA_OK;
+}
+
+
+static lzma_ret
+index_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ lzma_index **i, uint64_t memlimit)
+{
+ lzma_next_coder_init(&index_decoder_init, next, allocator);
+
+ if (i == NULL || memlimit == 0)
+ return LZMA_PROG_ERROR;
+
+ if (next->coder == NULL) {
+ next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
+ if (next->coder == NULL)
+ return LZMA_MEM_ERROR;
+
+ next->code = &index_decode;
+ next->end = &index_decoder_end;
+ next->memconfig = &index_decoder_memconfig;
+ next->coder->index = NULL;
+ } else {
+ lzma_index_end(next->coder->index, allocator);
+ }
+
+ return index_decoder_reset(next->coder, allocator, i, memlimit);
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_index_decoder(lzma_stream *strm, lzma_index **i, uint64_t memlimit)
+{
+ lzma_next_strm_init2(index_decoder_init, strm, i, memlimit);
+
+ strm->internal->supported_actions[LZMA_RUN] = true;
+ strm->internal->supported_actions[LZMA_FINISH] = true;
+
+ return LZMA_OK;
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_index_buffer_decode(
+ lzma_index **i, uint64_t *memlimit, lzma_allocator *allocator,
+ const uint8_t *in, size_t *in_pos, size_t in_size)
+{
+ lzma_coder coder;
+ lzma_ret ret;
+
+ // Store the input start position so that we can restore it in case
+ // of an error.
+ const size_t in_start = *in_pos;
+
+ // Sanity checks
+ if (i == NULL || memlimit == NULL
+ || in == NULL || in_pos == NULL || *in_pos > in_size)
+ return LZMA_PROG_ERROR;
+
+ // Initialize the decoder.
+ return_if_error(index_decoder_reset(&coder, allocator, i, *memlimit));
+
+ // Do the actual decoding.
+ ret = index_decode(&coder, allocator, in, in_pos, in_size,
+ NULL, NULL, 0, LZMA_RUN);
+
+ if (ret == LZMA_STREAM_END) {
+ ret = LZMA_OK;
+ } else {
+ // Something went wrong, free the Index structure and restore
+ // the input position.
+ lzma_index_end(coder.index, allocator);
+ *in_pos = in_start;
+
+ if (ret == LZMA_OK) {
+ // The input is truncated or otherwise corrupt.
+ // Use LZMA_DATA_ERROR instead of LZMA_BUF_ERROR
+ // like lzma_vli_decode() does in single-call mode.
+ ret = LZMA_DATA_ERROR;
+
+ } else if (ret == LZMA_MEMLIMIT_ERROR) {
+ // Tell the caller how much memory would have
+ // been needed.
+ *memlimit = lzma_index_memusage(1, coder.count);
+ }
+ }
+
+ return ret;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/index_encoder.c b/Utilities/cmliblzma/liblzma/common/index_encoder.c
new file mode 100644
index 000000000..194bf2113
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/index_encoder.c
@@ -0,0 +1,257 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file index_encoder.c
+/// \brief Encodes the Index field
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "index_encoder.h"
+#include "index.h"
+#include "check.h"
+
+
+struct lzma_coder_s {
+ enum {
+ SEQ_INDICATOR,
+ SEQ_COUNT,
+ SEQ_UNPADDED,
+ SEQ_UNCOMPRESSED,
+ SEQ_NEXT,
+ SEQ_PADDING,
+ SEQ_CRC32,
+ } sequence;
+
+ /// Index being encoded
+ const lzma_index *index;
+
+ /// Iterator for the Index being encoded
+ lzma_index_iter iter;
+
+ /// Position in integers
+ size_t pos;
+
+ /// CRC32 of the List of Records field
+ uint32_t crc32;
+};
+
+
+static lzma_ret
+index_encode(lzma_coder *coder,
+ lzma_allocator *allocator lzma_attribute((__unused__)),
+ const uint8_t *LZMA_RESTRICT in lzma_attribute((__unused__)),
+ size_t *LZMA_RESTRICT in_pos lzma_attribute((__unused__)),
+ size_t in_size lzma_attribute((__unused__)),
+ uint8_t *LZMA_RESTRICT out, size_t *LZMA_RESTRICT out_pos,
+ size_t out_size,
+ lzma_action action lzma_attribute((__unused__)))
+{
+ // Position where to start calculating CRC32. The idea is that we
+ // need to call lzma_crc32() only once per call to index_encode().
+ const size_t out_start = *out_pos;
+
+ // Return value to use if we return at the end of this function.
+ // We use "goto out" to jump out of the while-switch construct
+ // instead of returning directly, because that way we don't need
+ // to copypaste the lzma_crc32() call to many places.
+ lzma_ret ret = LZMA_OK;
+
+ while (*out_pos < out_size)
+ switch (coder->sequence) {
+ case SEQ_INDICATOR:
+ out[*out_pos] = 0x00;
+ ++*out_pos;
+ coder->sequence = SEQ_COUNT;
+ break;
+
+ case SEQ_COUNT: {
+ const lzma_vli count = lzma_index_block_count(coder->index);
+ ret = lzma_vli_encode(count, &coder->pos,
+ out, out_pos, out_size);
+ if (ret != LZMA_STREAM_END)
+ goto out;
+
+ ret = LZMA_OK;
+ coder->pos = 0;
+ coder->sequence = SEQ_NEXT;
+ break;
+ }
+
+ case SEQ_NEXT:
+ if (lzma_index_iter_next(
+ &coder->iter, LZMA_INDEX_ITER_BLOCK)) {
+ // Get the size of the Index Padding field.
+ coder->pos = lzma_index_padding_size(coder->index);
+ assert(coder->pos <= 3);
+ coder->sequence = SEQ_PADDING;
+ break;
+ }
+
+ coder->sequence = SEQ_UNPADDED;
+
+ // Fall through
+
+ case SEQ_UNPADDED:
+ case SEQ_UNCOMPRESSED: {
+ const lzma_vli size = coder->sequence == SEQ_UNPADDED
+ ? coder->iter.block.unpadded_size
+ : coder->iter.block.uncompressed_size;
+
+ ret = lzma_vli_encode(size, &coder->pos,
+ out, out_pos, out_size);
+ if (ret != LZMA_STREAM_END)
+ goto out;
+
+ ret = LZMA_OK;
+ coder->pos = 0;
+
+ // Advance to SEQ_UNCOMPRESSED or SEQ_NEXT.
+ ++coder->sequence;
+ break;
+ }
+
+ case SEQ_PADDING:
+ if (coder->pos > 0) {
+ --coder->pos;
+ out[(*out_pos)++] = 0x00;
+ break;
+ }
+
+ // Finish the CRC32 calculation.
+ coder->crc32 = lzma_crc32(out + out_start,
+ *out_pos - out_start, coder->crc32);
+
+ coder->sequence = SEQ_CRC32;
+
+ // Fall through
+
+ case SEQ_CRC32:
+ // We don't use the main loop, because we don't want
+ // coder->crc32 to be touched anymore.
+ do {
+ if (*out_pos == out_size)
+ return LZMA_OK;
+
+ out[*out_pos] = (coder->crc32 >> (coder->pos * 8))
+ & 0xFF;
+ ++*out_pos;
+
+ } while (++coder->pos < 4);
+
+ return LZMA_STREAM_END;
+
+ default:
+ assert(0);
+ return LZMA_PROG_ERROR;
+ }
+
+out:
+ // Update the CRC32.
+ coder->crc32 = lzma_crc32(out + out_start,
+ *out_pos - out_start, coder->crc32);
+
+ return ret;
+}
+
+
+static void
+index_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
+{
+ lzma_free(coder, allocator);
+ return;
+}
+
+
+static void
+index_encoder_reset(lzma_coder *coder, const lzma_index *i)
+{
+ lzma_index_iter_init(&coder->iter, i);
+
+ coder->sequence = SEQ_INDICATOR;
+ coder->index = i;
+ coder->pos = 0;
+ coder->crc32 = 0;
+
+ return;
+}
+
+
+extern lzma_ret
+lzma_index_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_index *i)
+{
+ lzma_next_coder_init(&lzma_index_encoder_init, next, allocator);
+
+ if (i == NULL)
+ return LZMA_PROG_ERROR;
+
+ if (next->coder == NULL) {
+ next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
+ if (next->coder == NULL)
+ return LZMA_MEM_ERROR;
+
+ next->code = &index_encode;
+ next->end = &index_encoder_end;
+ }
+
+ index_encoder_reset(next->coder, i);
+
+ return LZMA_OK;
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_index_encoder(lzma_stream *strm, const lzma_index *i)
+{
+ lzma_next_strm_init1(lzma_index_encoder_init, strm, i);
+
+ strm->internal->supported_actions[LZMA_RUN] = true;
+ strm->internal->supported_actions[LZMA_FINISH] = true;
+
+ return LZMA_OK;
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_index_buffer_encode(const lzma_index *i,
+ uint8_t *out, size_t *out_pos, size_t out_size)
+{
+ lzma_coder coder;
+ size_t out_start;
+ lzma_ret ret;
+
+ // Validate the arguments.
+ if (i == NULL || out == NULL || out_pos == NULL || *out_pos > out_size)
+ return LZMA_PROG_ERROR;
+
+ // Don't try to encode if there's not enough output space.
+ if (out_size - *out_pos < lzma_index_size(i))
+ return LZMA_BUF_ERROR;
+
+ // The Index encoder needs just one small data structure so we can
+ // allocate it on stack.
+ index_encoder_reset(&coder, i);
+
+ // Do the actual encoding. This should never fail, but store
+ // the original *out_pos just in case.
+ out_start = *out_pos;
+ ret = index_encode(&coder, NULL, NULL, NULL, 0,
+ out, out_pos, out_size, LZMA_RUN);
+
+ if (ret == LZMA_STREAM_END) {
+ ret = LZMA_OK;
+ } else {
+ // We should never get here, but just in case, restore the
+ // output position and set the error accordingly if something
+ // goes wrong and debugging isn't enabled.
+ assert(0);
+ *out_pos = out_start;
+ ret = LZMA_PROG_ERROR;
+ }
+
+ return ret;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/index_encoder.h b/Utilities/cmliblzma/liblzma/common/index_encoder.h
new file mode 100644
index 000000000..a13c94dcd
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/index_encoder.h
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file index_encoder.h
+/// \brief Encodes the Index field
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_INDEX_ENCODER_H
+#define LZMA_INDEX_ENCODER_H
+
+#include "common.h"
+
+
+extern lzma_ret lzma_index_encoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_index *i);
+
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/common/index_hash.c b/Utilities/cmliblzma/liblzma/common/index_hash.c
new file mode 100644
index 000000000..0cf86b307
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/index_hash.c
@@ -0,0 +1,336 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file index_hash.c
+/// \brief Validates Index by using a hash function
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "common.h"
+#include "index.h"
+#include "check.h"
+
+
+typedef struct {
+ /// Sum of the Block sizes (including Block Padding)
+ lzma_vli blocks_size;
+
+ /// Sum of the Uncompressed Size fields
+ lzma_vli uncompressed_size;
+
+ /// Number of Records
+ lzma_vli count;
+
+ /// Size of the List of Index Records as bytes
+ lzma_vli index_list_size;
+
+ /// Check calculated from Unpadded Sizes and Uncompressed Sizes.
+ lzma_check_state check;
+
+} lzma_index_hash_info;
+
+
+struct lzma_index_hash_s {
+ enum {
+ SEQ_BLOCK,
+ SEQ_COUNT,
+ SEQ_UNPADDED,
+ SEQ_UNCOMPRESSED,
+ SEQ_PADDING_INIT,
+ SEQ_PADDING,
+ SEQ_CRC32,
+ } sequence;
+
+ /// Information collected while decoding the actual Blocks.
+ lzma_index_hash_info blocks;
+
+ /// Information collected from the Index field.
+ lzma_index_hash_info records;
+
+ /// Number of Records not fully decoded
+ lzma_vli remaining;
+
+ /// Unpadded Size currently being read from an Index Record.
+ lzma_vli unpadded_size;
+
+ /// Uncompressed Size currently being read from an Index Record.
+ lzma_vli uncompressed_size;
+
+ /// Position in variable-length integers when decoding them from
+ /// the List of Records.
+ size_t pos;
+
+ /// CRC32 of the Index
+ uint32_t crc32;
+};
+
+
+extern LZMA_API(lzma_index_hash *)
+lzma_index_hash_init(lzma_index_hash *index_hash, lzma_allocator *allocator)
+{
+ if (index_hash == NULL) {
+ index_hash = lzma_alloc(sizeof(lzma_index_hash), allocator);
+ if (index_hash == NULL)
+ return NULL;
+ }
+
+ index_hash->sequence = SEQ_BLOCK;
+ index_hash->blocks.blocks_size = 0;
+ index_hash->blocks.uncompressed_size = 0;
+ index_hash->blocks.count = 0;
+ index_hash->blocks.index_list_size = 0;
+ index_hash->records.blocks_size = 0;
+ index_hash->records.uncompressed_size = 0;
+ index_hash->records.count = 0;
+ index_hash->records.index_list_size = 0;
+ index_hash->unpadded_size = 0;
+ index_hash->uncompressed_size = 0;
+ index_hash->pos = 0;
+ index_hash->crc32 = 0;
+
+ // These cannot fail because LZMA_CHECK_BEST is known to be supported.
+ (void)lzma_check_init(&index_hash->blocks.check, LZMA_CHECK_BEST);
+ (void)lzma_check_init(&index_hash->records.check, LZMA_CHECK_BEST);
+
+ return index_hash;
+}
+
+
+extern LZMA_API(void)
+lzma_index_hash_end(lzma_index_hash *index_hash, lzma_allocator *allocator)
+{
+ lzma_free(index_hash, allocator);
+ return;
+}
+
+
+extern LZMA_API(lzma_vli)
+lzma_index_hash_size(const lzma_index_hash *index_hash)
+{
+ // Get the size of the Index from ->blocks instead of ->records for
+ // cases where application wants to know the Index Size before
+ // decoding the Index.
+ return index_size(index_hash->blocks.count,
+ index_hash->blocks.index_list_size);
+}
+
+
+/// Updates the sizes and the hash without any validation.
+static lzma_ret
+hash_append(lzma_index_hash_info *info, lzma_vli unpadded_size,
+ lzma_vli uncompressed_size)
+{
+ const lzma_vli sizes[2] = { unpadded_size, uncompressed_size };
+
+ info->blocks_size += vli_ceil4(unpadded_size);
+ info->uncompressed_size += uncompressed_size;
+ info->index_list_size += lzma_vli_size(unpadded_size)
+ + lzma_vli_size(uncompressed_size);
+ ++info->count;
+
+ lzma_check_update(&info->check, LZMA_CHECK_BEST,
+ (const uint8_t *)(sizes), sizeof(sizes));
+
+ return LZMA_OK;
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_index_hash_append(lzma_index_hash *index_hash, lzma_vli unpadded_size,
+ lzma_vli uncompressed_size)
+{
+ // Validate the arguments.
+ if (index_hash->sequence != SEQ_BLOCK
+ || unpadded_size < UNPADDED_SIZE_MIN
+ || unpadded_size > UNPADDED_SIZE_MAX
+ || uncompressed_size > LZMA_VLI_MAX)
+ return LZMA_PROG_ERROR;
+
+ // Update the hash.
+ return_if_error(hash_append(&index_hash->blocks,
+ unpadded_size, uncompressed_size));
+
+ // Validate the properties of *info are still in allowed limits.
+ if (index_hash->blocks.blocks_size > LZMA_VLI_MAX
+ || index_hash->blocks.uncompressed_size > LZMA_VLI_MAX
+ || index_size(index_hash->blocks.count,
+ index_hash->blocks.index_list_size)
+ > LZMA_BACKWARD_SIZE_MAX
+ || index_stream_size(index_hash->blocks.blocks_size,
+ index_hash->blocks.count,
+ index_hash->blocks.index_list_size)
+ > LZMA_VLI_MAX)
+ return LZMA_DATA_ERROR;
+
+ return LZMA_OK;
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_index_hash_decode(lzma_index_hash *index_hash, const uint8_t *in,
+ size_t *in_pos, size_t in_size)
+{
+ size_t in_start;
+ lzma_ret ret;
+
+ // Catch zero input buffer here, because in contrast to Index encoder
+ // and decoder functions, applications call this function directly
+ // instead of via lzma_code(), which does the buffer checking.
+ if (*in_pos >= in_size)
+ return LZMA_BUF_ERROR;
+
+ // NOTE: This function has many similarities to index_encode() and
+ // index_decode() functions found from index_encoder.c and
+ // index_decoder.c. See the comments especially in index_encoder.c.
+ in_start = *in_pos;
+ ret = LZMA_OK;
+
+ while (*in_pos < in_size)
+ switch (index_hash->sequence) {
+ case SEQ_BLOCK:
+ // Check the Index Indicator is present.
+ if (in[(*in_pos)++] != 0x00)
+ return LZMA_DATA_ERROR;
+
+ index_hash->sequence = SEQ_COUNT;
+ break;
+
+ case SEQ_COUNT: {
+ ret = lzma_vli_decode(&index_hash->remaining,
+ &index_hash->pos, in, in_pos, in_size);
+ if (ret != LZMA_STREAM_END)
+ goto out;
+
+ // The count must match the count of the Blocks decoded.
+ if (index_hash->remaining != index_hash->blocks.count)
+ return LZMA_DATA_ERROR;
+
+ ret = LZMA_OK;
+ index_hash->pos = 0;
+
+ // Handle the special case when there are no Blocks.
+ index_hash->sequence = index_hash->remaining == 0
+ ? SEQ_PADDING_INIT : SEQ_UNPADDED;
+ break;
+ }
+
+ case SEQ_UNPADDED:
+ case SEQ_UNCOMPRESSED: {
+ lzma_vli *size = index_hash->sequence == SEQ_UNPADDED
+ ? &index_hash->unpadded_size
+ : &index_hash->uncompressed_size;
+
+ ret = lzma_vli_decode(size, &index_hash->pos,
+ in, in_pos, in_size);
+ if (ret != LZMA_STREAM_END)
+ goto out;
+
+ ret = LZMA_OK;
+ index_hash->pos = 0;
+
+ if (index_hash->sequence == SEQ_UNPADDED) {
+ if (index_hash->unpadded_size < UNPADDED_SIZE_MIN
+ || index_hash->unpadded_size
+ > UNPADDED_SIZE_MAX)
+ return LZMA_DATA_ERROR;
+
+ index_hash->sequence = SEQ_UNCOMPRESSED;
+ } else {
+ // Update the hash.
+ return_if_error(hash_append(&index_hash->records,
+ index_hash->unpadded_size,
+ index_hash->uncompressed_size));
+
+ // Verify that we don't go over the known sizes. Note
+ // that this validation is simpler than the one used
+ // in lzma_index_hash_append(), because here we know
+ // that values in index_hash->blocks are already
+ // validated and we are fine as long as we don't
+ // exceed them in index_hash->records.
+ if (index_hash->blocks.blocks_size
+ < index_hash->records.blocks_size
+ || index_hash->blocks.uncompressed_size
+ < index_hash->records.uncompressed_size
+ || index_hash->blocks.index_list_size
+ < index_hash->records.index_list_size)
+ return LZMA_DATA_ERROR;
+
+ // Check if this was the last Record.
+ index_hash->sequence = --index_hash->remaining == 0
+ ? SEQ_PADDING_INIT : SEQ_UNPADDED;
+ }
+
+ break;
+ }
+
+ case SEQ_PADDING_INIT:
+ index_hash->pos = (LZMA_VLI_C(4) - index_size_unpadded(
+ index_hash->records.count,
+ index_hash->records.index_list_size)) & 3;
+ index_hash->sequence = SEQ_PADDING;
+
+ // Fall through
+
+ case SEQ_PADDING:
+ if (index_hash->pos > 0) {
+ --index_hash->pos;
+ if (in[(*in_pos)++] != 0x00)
+ return LZMA_DATA_ERROR;
+
+ break;
+ }
+
+ // Compare the sizes.
+ if (index_hash->blocks.blocks_size
+ != index_hash->records.blocks_size
+ || index_hash->blocks.uncompressed_size
+ != index_hash->records.uncompressed_size
+ || index_hash->blocks.index_list_size
+ != index_hash->records.index_list_size)
+ return LZMA_DATA_ERROR;
+
+ // Finish the hashes and compare them.
+ lzma_check_finish(&index_hash->blocks.check, LZMA_CHECK_BEST);
+ lzma_check_finish(&index_hash->records.check, LZMA_CHECK_BEST);
+ if (memcmp(index_hash->blocks.check.buffer.u8,
+ index_hash->records.check.buffer.u8,
+ lzma_check_size(LZMA_CHECK_BEST)) != 0)
+ return LZMA_DATA_ERROR;
+
+ // Finish the CRC32 calculation.
+ index_hash->crc32 = lzma_crc32(in + in_start,
+ *in_pos - in_start, index_hash->crc32);
+
+ index_hash->sequence = SEQ_CRC32;
+
+ // Fall through
+
+ case SEQ_CRC32:
+ do {
+ if (*in_pos == in_size)
+ return LZMA_OK;
+
+ if (((index_hash->crc32 >> (index_hash->pos * 8))
+ & 0xFF) != in[(*in_pos)++])
+ return LZMA_DATA_ERROR;
+
+ } while (++index_hash->pos < 4);
+
+ return LZMA_STREAM_END;
+
+ default:
+ assert(0);
+ return LZMA_PROG_ERROR;
+ }
+
+out:
+ // Update the CRC32,
+ index_hash->crc32 = lzma_crc32(in + in_start,
+ *in_pos - in_start, index_hash->crc32);
+
+ return ret;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/stream_buffer_decoder.c b/Utilities/cmliblzma/liblzma/common/stream_buffer_decoder.c
new file mode 100644
index 000000000..9e2e1da83
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/stream_buffer_decoder.c
@@ -0,0 +1,93 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file stream_buffer_decoder.c
+/// \brief Single-call .xz Stream decoder
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "stream_decoder.h"
+
+
+extern LZMA_API(lzma_ret)
+lzma_stream_buffer_decode(uint64_t *memlimit, uint32_t flags,
+ lzma_allocator *allocator,
+ const uint8_t *in, size_t *in_pos, size_t in_size,
+ uint8_t *out, size_t *out_pos, size_t out_size)
+{
+ lzma_next_coder stream_decoder = LZMA_NEXT_CODER_INIT;
+ lzma_ret ret;
+
+ // Sanity checks
+ if (in_pos == NULL || (in == NULL && *in_pos != in_size)
+ || *in_pos > in_size || out_pos == NULL
+ || (out == NULL && *out_pos != out_size)
+ || *out_pos > out_size)
+ return LZMA_PROG_ERROR;
+
+ // Catch flags that are not allowed in buffer-to-buffer decoding.
+ if (flags & LZMA_TELL_ANY_CHECK)
+ return LZMA_PROG_ERROR;
+
+ // Initialize the Stream decoder.
+ // TODO: We need something to tell the decoder that it can use the
+ // output buffer as workspace, and thus save significant amount of RAM.
+ ret = lzma_stream_decoder_init(
+ &stream_decoder, allocator, *memlimit, flags);
+
+ if (ret == LZMA_OK) {
+ // Save the positions so that we can restore them in case
+ // an error occurs.
+ const size_t in_start = *in_pos;
+ const size_t out_start = *out_pos;
+
+ // Do the actual decoding.
+ ret = stream_decoder.code(stream_decoder.coder, allocator,
+ in, in_pos, in_size, out, out_pos, out_size,
+ LZMA_FINISH);
+
+ if (ret == LZMA_STREAM_END) {
+ ret = LZMA_OK;
+ } else {
+ // Something went wrong, restore the positions.
+ *in_pos = in_start;
+ *out_pos = out_start;
+
+ if (ret == LZMA_OK) {
+ // Either the input was truncated or the
+ // output buffer was too small.
+ assert(*in_pos == in_size
+ || *out_pos == out_size);
+
+ // If all the input was consumed, then the
+ // input is truncated, even if the output
+ // buffer is also full. This is because
+ // processing the last byte of the Stream
+ // never produces output.
+ if (*in_pos == in_size)
+ ret = LZMA_DATA_ERROR;
+ else
+ ret = LZMA_BUF_ERROR;
+
+ } else if (ret == LZMA_MEMLIMIT_ERROR) {
+ // Let the caller know how much memory would
+ // have been needed.
+ uint64_t memusage;
+ (void)stream_decoder.memconfig(
+ stream_decoder.coder,
+ memlimit, &memusage, 0);
+ }
+ }
+ }
+
+ // Free the decoder memory. This needs to be done even if
+ // initialization fails, because the internal API doesn't
+ // require the initialization function to free its memory on error.
+ lzma_next_end(&stream_decoder, allocator);
+
+ return ret;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/stream_buffer_encoder.c b/Utilities/cmliblzma/liblzma/common/stream_buffer_encoder.c
new file mode 100644
index 000000000..8bca87f47
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/stream_buffer_encoder.c
@@ -0,0 +1,140 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file stream_buffer_encoder.c
+/// \brief Single-call .xz Stream encoder
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "index.h"
+
+
+/// Maximum size of Index that has exactly one Record.
+/// Index Indicator + Number of Records + Record + CRC32 rounded up to
+/// the next multiple of four.
+#define INDEX_BOUND ((1 + 1 + 2 * LZMA_VLI_BYTES_MAX + 4 + 3) & ~3)
+
+/// Stream Header, Stream Footer, and Index
+#define HEADERS_BOUND (2 * LZMA_STREAM_HEADER_SIZE + INDEX_BOUND)
+
+
+extern LZMA_API(size_t)
+lzma_stream_buffer_bound(size_t uncompressed_size)
+{
+ // Get the maximum possible size of a Block.
+ const size_t block_bound = lzma_block_buffer_bound(uncompressed_size);
+ if (block_bound == 0)
+ return 0;
+
+ // Catch the possible integer overflow and also prevent the size of
+ // the Stream exceeding LZMA_VLI_MAX (theoretically possible on
+ // 64-bit systems).
+ if (my_min(SIZE_MAX, LZMA_VLI_MAX) - block_bound < HEADERS_BOUND)
+ return 0;
+
+ return block_bound + HEADERS_BOUND;
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_stream_buffer_encode(lzma_filter *filters, lzma_check check,
+ lzma_allocator *allocator, const uint8_t *in, size_t in_size,
+ uint8_t *out, size_t *out_pos_ptr, size_t out_size)
+{
+ lzma_stream_flags stream_flags = { 0 };
+ lzma_block block = { 0 };
+ size_t out_pos;
+
+ // Sanity checks
+ if (filters == NULL || (unsigned int)(check) > LZMA_CHECK_ID_MAX
+ || (in == NULL && in_size != 0) || out == NULL
+ || out_pos_ptr == NULL || *out_pos_ptr > out_size)
+ return LZMA_PROG_ERROR;
+
+ if (!lzma_check_is_supported(check))
+ return LZMA_UNSUPPORTED_CHECK;
+
+ // Note for the paranoids: Index encoder prevents the Stream from
+ // getting too big and still being accepted with LZMA_OK, and Block
+ // encoder catches if the input is too big. So we don't need to
+ // separately check if the buffers are too big.
+
+ // Use a local copy. We update *out_pos_ptr only if everything
+ // succeeds.
+ out_pos = *out_pos_ptr;
+
+ // Check that there's enough space for both Stream Header and
+ // Stream Footer.
+ if (out_size - out_pos <= 2 * LZMA_STREAM_HEADER_SIZE)
+ return LZMA_BUF_ERROR;
+
+ // Reserve space for Stream Footer so we don't need to check for
+ // available space again before encoding Stream Footer.
+ out_size -= LZMA_STREAM_HEADER_SIZE;
+
+ // Encode the Stream Header.
+ stream_flags.check = check;
+
+ if (lzma_stream_header_encode(&stream_flags, out + out_pos)
+ != LZMA_OK)
+ return LZMA_PROG_ERROR;
+
+ out_pos += LZMA_STREAM_HEADER_SIZE;
+
+ // Encode a Block but only if there is at least one byte of input.
+ block.check = check;
+ block.filters = filters;
+
+ if (in_size > 0)
+ return_if_error(lzma_block_buffer_encode(&block, allocator,
+ in, in_size, out, &out_pos, out_size));
+
+ // Index
+ {
+ lzma_ret ret;
+
+ // Create an Index. It will have one Record if there was
+ // at least one byte of input to encode. Otherwise the
+ // Index will be empty.
+ lzma_index *i = lzma_index_init(allocator);
+ if (i == NULL)
+ return LZMA_MEM_ERROR;
+
+ ret = LZMA_OK;
+
+ if (in_size > 0)
+ ret = lzma_index_append(i, allocator,
+ lzma_block_unpadded_size(&block),
+ block.uncompressed_size);
+
+ // If adding the Record was successful, encode the Index
+ // and get its size which will be stored into Stream Footer.
+ if (ret == LZMA_OK) {
+ ret = lzma_index_buffer_encode(
+ i, out, &out_pos, out_size);
+
+ stream_flags.backward_size = lzma_index_size(i);
+ }
+
+ lzma_index_end(i, allocator);
+
+ if (ret != LZMA_OK)
+ return ret;
+ }
+
+ // Stream Footer. We have already reserved space for this.
+ if (lzma_stream_footer_encode(&stream_flags, out + out_pos)
+ != LZMA_OK)
+ return LZMA_PROG_ERROR;
+
+ out_pos += LZMA_STREAM_HEADER_SIZE;
+
+ // Everything went fine, make the new output position available
+ // to the application.
+ *out_pos_ptr = out_pos;
+ return LZMA_OK;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/stream_decoder.c b/Utilities/cmliblzma/liblzma/common/stream_decoder.c
new file mode 100644
index 000000000..5e9a22069
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/stream_decoder.c
@@ -0,0 +1,459 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file stream_decoder.c
+/// \brief Decodes .xz Streams
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "stream_decoder.h"
+#include "block_decoder.h"
+
+
+struct lzma_coder_s {
+ enum {
+ SEQ_STREAM_HEADER,
+ SEQ_BLOCK_HEADER,
+ SEQ_BLOCK,
+ SEQ_INDEX,
+ SEQ_STREAM_FOOTER,
+ SEQ_STREAM_PADDING,
+ } sequence;
+
+ /// Block or Metadata decoder. This takes little memory and the same
+ /// data structure can be used to decode every Block Header, so it's
+ /// a good idea to have a separate lzma_next_coder structure for it.
+ lzma_next_coder block_decoder;
+
+ /// Block options decoded by the Block Header decoder and used by
+ /// the Block decoder.
+ lzma_block block_options;
+
+ /// Stream Flags from Stream Header
+ lzma_stream_flags stream_flags;
+
+ /// Index is hashed so that it can be compared to the sizes of Blocks
+ /// with O(1) memory usage.
+ lzma_index_hash *index_hash;
+
+ /// Memory usage limit
+ uint64_t memlimit;
+
+ /// Amount of memory actually needed (only an estimate)
+ uint64_t memusage;
+
+ /// If true, LZMA_NO_CHECK is returned if the Stream has
+ /// no integrity check.
+ bool tell_no_check;
+
+ /// If true, LZMA_UNSUPPORTED_CHECK is returned if the Stream has
+ /// an integrity check that isn't supported by this liblzma build.
+ bool tell_unsupported_check;
+
+ /// If true, LZMA_GET_CHECK is returned after decoding Stream Header.
+ bool tell_any_check;
+
+ /// If true, we will decode concatenated Streams that possibly have
+ /// Stream Padding between or after them. LZMA_STREAM_END is returned
+ /// once the application isn't giving us any new input, and we aren't
+ /// in the middle of a Stream, and possible Stream Padding is a
+ /// multiple of four bytes.
+ bool concatenated;
+
+ /// When decoding concatenated Streams, this is true as long as we
+ /// are decoding the first Stream. This is needed to avoid misleading
+ /// LZMA_FORMAT_ERROR in case the later Streams don't have valid magic
+ /// bytes.
+ bool first_stream;
+
+ /// Write position in buffer[] and position in Stream Padding
+ size_t pos;
+
+ /// Buffer to hold Stream Header, Block Header, and Stream Footer.
+ /// Block Header has biggest maximum size.
+ uint8_t buffer[LZMA_BLOCK_HEADER_SIZE_MAX];
+};
+
+
+static lzma_ret
+stream_decoder_reset(lzma_coder *coder, lzma_allocator *allocator)
+{
+ // Initialize the Index hash used to verify the Index.
+ coder->index_hash = lzma_index_hash_init(coder->index_hash, allocator);
+ if (coder->index_hash == NULL)
+ return LZMA_MEM_ERROR;
+
+ // Reset the rest of the variables.
+ coder->sequence = SEQ_STREAM_HEADER;
+ coder->pos = 0;
+
+ return LZMA_OK;
+}
+
+
+static lzma_ret
+stream_decode(lzma_coder *coder, lzma_allocator *allocator,
+ const uint8_t *LZMA_RESTRICT in, size_t *LZMA_RESTRICT in_pos,
+ size_t in_size, uint8_t *LZMA_RESTRICT out,
+ size_t *LZMA_RESTRICT out_pos, size_t out_size, lzma_action action)
+{
+ // When decoding the actual Block, it may be able to produce more
+ // output even if we don't give it any new input.
+ while (true)
+ switch (coder->sequence) {
+ case SEQ_STREAM_HEADER: {
+ lzma_ret ret;
+
+ // Copy the Stream Header to the internal buffer.
+ lzma_bufcpy(in, in_pos, in_size, coder->buffer, &coder->pos,
+ LZMA_STREAM_HEADER_SIZE);
+
+ // Return if we didn't get the whole Stream Header yet.
+ if (coder->pos < LZMA_STREAM_HEADER_SIZE)
+ return LZMA_OK;
+
+ coder->pos = 0;
+
+ // Decode the Stream Header.
+ ret = lzma_stream_header_decode(
+ &coder->stream_flags, coder->buffer);
+ if (ret != LZMA_OK)
+ return ret == LZMA_FORMAT_ERROR && !coder->first_stream
+ ? LZMA_DATA_ERROR : ret;
+
+ // If we are decoding concatenated Streams, and the later
+ // Streams have invalid Header Magic Bytes, we give
+ // LZMA_DATA_ERROR instead of LZMA_FORMAT_ERROR.
+ coder->first_stream = false;
+
+ // Copy the type of the Check so that Block Header and Block
+ // decoders see it.
+ coder->block_options.check = coder->stream_flags.check;
+
+ // Even if we return LZMA_*_CHECK below, we want
+ // to continue from Block Header decoding.
+ coder->sequence = SEQ_BLOCK_HEADER;
+
+ // Detect if there's no integrity check or if it is
+ // unsupported if those were requested by the application.
+ if (coder->tell_no_check && coder->stream_flags.check
+ == LZMA_CHECK_NONE)
+ return LZMA_NO_CHECK;
+
+ if (coder->tell_unsupported_check
+ && !lzma_check_is_supported(
+ coder->stream_flags.check))
+ return LZMA_UNSUPPORTED_CHECK;
+
+ if (coder->tell_any_check)
+ return LZMA_GET_CHECK;
+ }
+
+ // Fall through
+
+ case SEQ_BLOCK_HEADER: {
+ lzma_filter filters[LZMA_FILTERS_MAX + 1];
+ uint64_t memusage;
+ lzma_ret ret;
+ size_t i;
+
+ if (*in_pos >= in_size)
+ return LZMA_OK;
+
+ if (coder->pos == 0) {
+ // Detect if it's Index.
+ if (in[*in_pos] == 0x00) {
+ coder->sequence = SEQ_INDEX;
+ break;
+ }
+
+ // Calculate the size of the Block Header. Note that
+ // Block Header decoder wants to see this byte too
+ // so don't advance *in_pos.
+ coder->block_options.header_size
+ = lzma_block_header_size_decode(
+ in[*in_pos]);
+ }
+
+ // Copy the Block Header to the internal buffer.
+ lzma_bufcpy(in, in_pos, in_size, coder->buffer, &coder->pos,
+ coder->block_options.header_size);
+
+ // Return if we didn't get the whole Block Header yet.
+ if (coder->pos < coder->block_options.header_size)
+ return LZMA_OK;
+
+ coder->pos = 0;
+
+ // Version 0 is currently the only possible version.
+ coder->block_options.version = 0;
+
+ // Set up a buffer to hold the filter chain. Block Header
+ // decoder will initialize all members of this array so
+ // we don't need to do it here.
+ coder->block_options.filters = filters;
+
+ // Decode the Block Header.
+ return_if_error(lzma_block_header_decode(&coder->block_options,
+ allocator, coder->buffer));
+
+ // Check the memory usage limit.
+ memusage = lzma_raw_decoder_memusage(filters);
+ if (memusage == UINT64_MAX) {
+ // One or more unknown Filter IDs.
+ ret = LZMA_OPTIONS_ERROR;
+ } else {
+ // Now we can set coder->memusage since we know that
+ // the filter chain is valid. We don't want
+ // lzma_memusage() to return UINT64_MAX in case of
+ // invalid filter chain.
+ coder->memusage = memusage;
+
+ if (memusage > coder->memlimit) {
+ // The chain would need too much memory.
+ ret = LZMA_MEMLIMIT_ERROR;
+ } else {
+ // Memory usage is OK.
+ // Initialize the Block decoder.
+ ret = lzma_block_decoder_init(
+ &coder->block_decoder,
+ allocator,
+ &coder->block_options);
+ }
+ }
+
+ // Free the allocated filter options since they are needed
+ // only to initialize the Block decoder.
+ for (i = 0; i < LZMA_FILTERS_MAX; ++i)
+ lzma_free(filters[i].options, allocator);
+
+ coder->block_options.filters = NULL;
+
+ // Check if memory usage calculation and Block enocoder
+ // initialization succeeded.
+ if (ret != LZMA_OK)
+ return ret;
+
+ coder->sequence = SEQ_BLOCK;
+ }
+
+ // Fall through
+
+ case SEQ_BLOCK: {
+ const lzma_ret ret = coder->block_decoder.code(
+ coder->block_decoder.coder, allocator,
+ in, in_pos, in_size, out, out_pos, out_size,
+ action);
+
+ if (ret != LZMA_STREAM_END)
+ return ret;
+
+ // Block decoded successfully. Add the new size pair to
+ // the Index hash.
+ return_if_error(lzma_index_hash_append(coder->index_hash,
+ lzma_block_unpadded_size(
+ &coder->block_options),
+ coder->block_options.uncompressed_size));
+
+ coder->sequence = SEQ_BLOCK_HEADER;
+ break;
+ }
+
+ case SEQ_INDEX: {
+ lzma_ret ret;
+
+ // If we don't have any input, don't call
+ // lzma_index_hash_decode() since it would return
+ // LZMA_BUF_ERROR, which we must not do here.
+ if (*in_pos >= in_size)
+ return LZMA_OK;
+
+ // Decode the Index and compare it to the hash calculated
+ // from the sizes of the Blocks (if any).
+ ret = lzma_index_hash_decode(coder->index_hash,
+ in, in_pos, in_size);
+ if (ret != LZMA_STREAM_END)
+ return ret;
+
+ coder->sequence = SEQ_STREAM_FOOTER;
+ }
+
+ // Fall through
+
+ case SEQ_STREAM_FOOTER: {
+ lzma_stream_flags footer_flags;
+ lzma_ret ret;
+
+ // Copy the Stream Footer to the internal buffer.
+ lzma_bufcpy(in, in_pos, in_size, coder->buffer, &coder->pos,
+ LZMA_STREAM_HEADER_SIZE);
+
+ // Return if we didn't get the whole Stream Footer yet.
+ if (coder->pos < LZMA_STREAM_HEADER_SIZE)
+ return LZMA_OK;
+
+ coder->pos = 0;
+
+ // Decode the Stream Footer. The decoder gives
+ // LZMA_FORMAT_ERROR if the magic bytes don't match,
+ // so convert that return code to LZMA_DATA_ERROR.
+ ret = lzma_stream_footer_decode(
+ &footer_flags, coder->buffer);
+ if (ret != LZMA_OK)
+ return ret == LZMA_FORMAT_ERROR
+ ? LZMA_DATA_ERROR : ret;
+
+ // Check that Index Size stored in the Stream Footer matches
+ // the real size of the Index field.
+ if (lzma_index_hash_size(coder->index_hash)
+ != footer_flags.backward_size)
+ return LZMA_DATA_ERROR;
+
+ // Compare that the Stream Flags fields are identical in
+ // both Stream Header and Stream Footer.
+ return_if_error(lzma_stream_flags_compare(
+ &coder->stream_flags, &footer_flags));
+
+ if (!coder->concatenated)
+ return LZMA_STREAM_END;
+
+ coder->sequence = SEQ_STREAM_PADDING;
+ }
+
+ // Fall through
+
+ case SEQ_STREAM_PADDING:
+ assert(coder->concatenated);
+
+ // Skip over possible Stream Padding.
+ while (true) {
+ if (*in_pos >= in_size) {
+ // Unless LZMA_FINISH was used, we cannot
+ // know if there's more input coming later.
+ if (action != LZMA_FINISH)
+ return LZMA_OK;
+
+ // Stream Padding must be a multiple of
+ // four bytes.
+ return coder->pos == 0
+ ? LZMA_STREAM_END
+ : LZMA_DATA_ERROR;
+ }
+
+ // If the byte is not zero, it probably indicates
+ // beginning of a new Stream (or the file is corrupt).
+ if (in[*in_pos] != 0x00)
+ break;
+
+ ++*in_pos;
+ coder->pos = (coder->pos + 1) & 3;
+ }
+
+ // Stream Padding must be a multiple of four bytes (empty
+ // Stream Padding is OK).
+ if (coder->pos != 0) {
+ ++*in_pos;
+ return LZMA_DATA_ERROR;
+ }
+
+ // Prepare to decode the next Stream.
+ return_if_error(stream_decoder_reset(coder, allocator));
+ break;
+
+ default:
+ assert(0);
+ return LZMA_PROG_ERROR;
+ }
+
+ // Never reached
+}
+
+
+static void
+stream_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
+{
+ lzma_next_end(&coder->block_decoder, allocator);
+ lzma_index_hash_end(coder->index_hash, allocator);
+ lzma_free(coder, allocator);
+ return;
+}
+
+
+static lzma_check
+stream_decoder_get_check(const lzma_coder *coder)
+{
+ return coder->stream_flags.check;
+}
+
+
+static lzma_ret
+stream_decoder_memconfig(lzma_coder *coder, uint64_t *memusage,
+ uint64_t *old_memlimit, uint64_t new_memlimit)
+{
+ *memusage = coder->memusage;
+ *old_memlimit = coder->memlimit;
+
+ if (new_memlimit != 0) {
+ if (new_memlimit < coder->memusage)
+ return LZMA_MEMLIMIT_ERROR;
+
+ coder->memlimit = new_memlimit;
+ }
+
+ return LZMA_OK;
+}
+
+
+extern lzma_ret
+lzma_stream_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ uint64_t memlimit, uint32_t flags)
+{
+ lzma_next_coder_init(&lzma_stream_decoder_init, next, allocator);
+
+ if (memlimit == 0)
+ return LZMA_PROG_ERROR;
+
+ if (flags & ~LZMA_SUPPORTED_FLAGS)
+ return LZMA_OPTIONS_ERROR;
+
+ if (next->coder == NULL) {
+ next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
+ if (next->coder == NULL)
+ return LZMA_MEM_ERROR;
+
+ next->code = &stream_decode;
+ next->end = &stream_decoder_end;
+ next->get_check = &stream_decoder_get_check;
+ next->memconfig = &stream_decoder_memconfig;
+
+ next->coder->block_decoder = LZMA_NEXT_CODER_INIT;
+ next->coder->index_hash = NULL;
+ }
+
+ next->coder->memlimit = memlimit;
+ next->coder->memusage = LZMA_MEMUSAGE_BASE;
+ next->coder->tell_no_check = (flags & LZMA_TELL_NO_CHECK) != 0;
+ next->coder->tell_unsupported_check
+ = (flags & LZMA_TELL_UNSUPPORTED_CHECK) != 0;
+ next->coder->tell_any_check = (flags & LZMA_TELL_ANY_CHECK) != 0;
+ next->coder->concatenated = (flags & LZMA_CONCATENATED) != 0;
+ next->coder->first_stream = true;
+
+ return stream_decoder_reset(next->coder, allocator);
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_stream_decoder(lzma_stream *strm, uint64_t memlimit, uint32_t flags)
+{
+ lzma_next_strm_init2(lzma_stream_decoder_init, strm, memlimit, flags);
+
+ strm->internal->supported_actions[LZMA_RUN] = true;
+ strm->internal->supported_actions[LZMA_FINISH] = true;
+
+ return LZMA_OK;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/stream_decoder.h b/Utilities/cmliblzma/liblzma/common/stream_decoder.h
new file mode 100644
index 000000000..e54ac28f4
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/stream_decoder.h
@@ -0,0 +1,21 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file stream_decoder.h
+/// \brief Decodes .xz Streams
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_STREAM_DECODER_H
+#define LZMA_STREAM_DECODER_H
+
+#include "common.h"
+
+extern lzma_ret lzma_stream_decoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, uint64_t memlimit, uint32_t flags);
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/common/stream_encoder.c b/Utilities/cmliblzma/liblzma/common/stream_encoder.c
new file mode 100644
index 000000000..1ba45acec
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/stream_encoder.c
@@ -0,0 +1,338 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file stream_encoder.c
+/// \brief Encodes .xz Streams
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "stream_encoder.h"
+#include "block_encoder.h"
+#include "index_encoder.h"
+
+
+struct lzma_coder_s {
+ enum {
+ SEQ_STREAM_HEADER,
+ SEQ_BLOCK_INIT,
+ SEQ_BLOCK_HEADER,
+ SEQ_BLOCK_ENCODE,
+ SEQ_INDEX_ENCODE,
+ SEQ_STREAM_FOOTER,
+ } sequence;
+
+ /// True if Block encoder has been initialized by
+ /// lzma_stream_encoder_init() or stream_encoder_update()
+ /// and thus doesn't need to be initialized in stream_encode().
+ bool block_encoder_is_initialized;
+
+ /// Block
+ lzma_next_coder block_encoder;
+
+ /// Options for the Block encoder
+ lzma_block block_options;
+
+ /// The filter chain currently in use
+ lzma_filter filters[LZMA_FILTERS_MAX + 1];
+
+ /// Index encoder. This is separate from Block encoder, because this
+ /// doesn't take much memory, and when encoding multiple Streams
+ /// with the same encoding options we avoid reallocating memory.
+ lzma_next_coder index_encoder;
+
+ /// Index to hold sizes of the Blocks
+ lzma_index *index;
+
+ /// Read position in buffer[]
+ size_t buffer_pos;
+
+ /// Total number of bytes in buffer[]
+ size_t buffer_size;
+
+ /// Buffer to hold Stream Header, Block Header, and Stream Footer.
+ /// Block Header has biggest maximum size.
+ uint8_t buffer[LZMA_BLOCK_HEADER_SIZE_MAX];
+};
+
+
+static lzma_ret
+block_encoder_init(lzma_coder *coder, lzma_allocator *allocator)
+{
+ // Prepare the Block options. Even though Block encoder doesn't need
+ // compressed_size, uncompressed_size, and header_size to be
+ // initialized, it is a good idea to do it here, because this way
+ // we catch if someone gave us Filter ID that cannot be used in
+ // Blocks/Streams.
+ coder->block_options.compressed_size = LZMA_VLI_UNKNOWN;
+ coder->block_options.uncompressed_size = LZMA_VLI_UNKNOWN;
+
+ return_if_error(lzma_block_header_size(&coder->block_options));
+
+ // Initialize the actual Block encoder.
+ return lzma_block_encoder_init(&coder->block_encoder, allocator,
+ &coder->block_options);
+}
+
+
+static lzma_ret
+stream_encode(lzma_coder *coder, lzma_allocator *allocator,
+ const uint8_t *LZMA_RESTRICT in, size_t *LZMA_RESTRICT in_pos,
+ size_t in_size, uint8_t *LZMA_RESTRICT out,
+ size_t *LZMA_RESTRICT out_pos, size_t out_size, lzma_action action)
+{
+ // Main loop
+ while (*out_pos < out_size)
+ switch (coder->sequence) {
+ case SEQ_STREAM_HEADER:
+ case SEQ_BLOCK_HEADER:
+ case SEQ_STREAM_FOOTER:
+ lzma_bufcpy(coder->buffer, &coder->buffer_pos,
+ coder->buffer_size, out, out_pos, out_size);
+ if (coder->buffer_pos < coder->buffer_size)
+ return LZMA_OK;
+
+ if (coder->sequence == SEQ_STREAM_FOOTER)
+ return LZMA_STREAM_END;
+
+ coder->buffer_pos = 0;
+ ++coder->sequence;
+ break;
+
+ case SEQ_BLOCK_INIT: {
+ if (*in_pos == in_size) {
+ // If we are requested to flush or finish the current
+ // Block, return LZMA_STREAM_END immediately since
+ // there's nothing to do.
+ if (action != LZMA_FINISH)
+ return action == LZMA_RUN
+ ? LZMA_OK : LZMA_STREAM_END;
+
+ // The application had used LZMA_FULL_FLUSH to finish
+ // the previous Block, but now wants to finish without
+ // encoding new data, or it is simply creating an
+ // empty Stream with no Blocks.
+ //
+ // Initialize the Index encoder, and continue to
+ // actually encoding the Index.
+ return_if_error(lzma_index_encoder_init(
+ &coder->index_encoder, allocator,
+ coder->index));
+ coder->sequence = SEQ_INDEX_ENCODE;
+ break;
+ }
+
+ // Initialize the Block encoder unless it was already
+ // initialized by lzma_stream_encoder_init() or
+ // stream_encoder_update().
+ if (!coder->block_encoder_is_initialized)
+ return_if_error(block_encoder_init(coder, allocator));
+
+ // Make it false so that we don't skip the initialization
+ // with the next Block.
+ coder->block_encoder_is_initialized = false;
+
+ // Encode the Block Header. This shouldn't fail since we have
+ // already initialized the Block encoder.
+ if (lzma_block_header_encode(&coder->block_options,
+ coder->buffer) != LZMA_OK)
+ return LZMA_PROG_ERROR;
+
+ coder->buffer_size = coder->block_options.header_size;
+ coder->sequence = SEQ_BLOCK_HEADER;
+ break;
+ }
+
+ case SEQ_BLOCK_ENCODE: {
+ lzma_vli unpadded_size;
+
+ static const lzma_action convert[4] = {
+ LZMA_RUN,
+ LZMA_SYNC_FLUSH,
+ LZMA_FINISH,
+ LZMA_FINISH,
+ };
+
+ const lzma_ret ret = coder->block_encoder.code(
+ coder->block_encoder.coder, allocator,
+ in, in_pos, in_size,
+ out, out_pos, out_size, convert[action]);
+ if (ret != LZMA_STREAM_END || action == LZMA_SYNC_FLUSH)
+ return ret;
+
+ // Add a new Index Record.
+ unpadded_size = lzma_block_unpadded_size(
+ &coder->block_options);
+ assert(unpadded_size != 0);
+ return_if_error(lzma_index_append(coder->index, allocator,
+ unpadded_size,
+ coder->block_options.uncompressed_size));
+
+ coder->sequence = SEQ_BLOCK_INIT;
+ break;
+ }
+
+ case SEQ_INDEX_ENCODE: {
+ const lzma_stream_flags stream_flags = {
+ 0,
+ lzma_index_size(coder->index),
+ coder->block_options.check,
+ };
+
+ // Call the Index encoder. It doesn't take any input, so
+ // those pointers can be NULL.
+ const lzma_ret ret = coder->index_encoder.code(
+ coder->index_encoder.coder, allocator,
+ NULL, NULL, 0,
+ out, out_pos, out_size, LZMA_RUN);
+ if (ret != LZMA_STREAM_END)
+ return ret;
+
+ // Encode the Stream Footer into coder->buffer.
+
+ if (lzma_stream_footer_encode(&stream_flags, coder->buffer)
+ != LZMA_OK)
+ return LZMA_PROG_ERROR;
+
+ coder->buffer_size = LZMA_STREAM_HEADER_SIZE;
+ coder->sequence = SEQ_STREAM_FOOTER;
+ break;
+ }
+
+ default:
+ assert(0);
+ return LZMA_PROG_ERROR;
+ }
+
+ return LZMA_OK;
+}
+
+
+static void
+stream_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
+{
+ size_t i;
+
+ lzma_next_end(&coder->block_encoder, allocator);
+ lzma_next_end(&coder->index_encoder, allocator);
+ lzma_index_end(coder->index, allocator);
+
+ for (i = 0; coder->filters[i].id != LZMA_VLI_UNKNOWN; ++i)
+ lzma_free(coder->filters[i].options, allocator);
+
+ lzma_free(coder, allocator);
+ return;
+}
+
+
+static lzma_ret
+stream_encoder_update(lzma_coder *coder, lzma_allocator *allocator,
+ const lzma_filter *filters,
+ const lzma_filter *reversed_filters)
+{
+ size_t i;
+
+ if (coder->sequence <= SEQ_BLOCK_INIT) {
+ lzma_ret ret;
+
+ // There is no incomplete Block waiting to be finished,
+ // thus we can change the whole filter chain. Start by
+ // trying to initialize the Block encoder with the new
+ // chain. This way we detect if the chain is valid.
+ coder->block_encoder_is_initialized = false;
+ coder->block_options.filters = (lzma_filter *)(filters);
+ ret = block_encoder_init(coder, allocator);
+ coder->block_options.filters = coder->filters;
+ if (ret != LZMA_OK)
+ return ret;
+
+ coder->block_encoder_is_initialized = true;
+
+ } else if (coder->sequence <= SEQ_BLOCK_ENCODE) {
+ // We are in the middle of a Block. Try to update only
+ // the filter-specific options.
+ return_if_error(coder->block_encoder.update(
+ coder->block_encoder.coder, allocator,
+ filters, reversed_filters));
+ } else {
+ // Trying to update the filter chain when we are already
+ // encoding Index or Stream Footer.
+ return LZMA_PROG_ERROR;
+ }
+
+ // Free the copy of the old chain and make a copy of the new chain.
+ for (i = 0; coder->filters[i].id != LZMA_VLI_UNKNOWN; ++i)
+ lzma_free(coder->filters[i].options, allocator);
+
+ return lzma_filters_copy(filters, coder->filters, allocator);
+}
+
+
+extern lzma_ret
+lzma_stream_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter *filters, lzma_check check)
+{
+ lzma_stream_flags stream_flags = { 0, 0, check };
+
+ lzma_next_coder_init(&lzma_stream_encoder_init, next, allocator);
+
+ if (filters == NULL)
+ return LZMA_PROG_ERROR;
+
+ if (next->coder == NULL) {
+ next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
+ if (next->coder == NULL)
+ return LZMA_MEM_ERROR;
+
+ next->code = &stream_encode;
+ next->end = &stream_encoder_end;
+ next->update = &stream_encoder_update;
+
+ next->coder->filters[0].id = LZMA_VLI_UNKNOWN;
+ next->coder->block_encoder = LZMA_NEXT_CODER_INIT;
+ next->coder->index_encoder = LZMA_NEXT_CODER_INIT;
+ next->coder->index = NULL;
+ }
+
+ // Basic initializations
+ next->coder->sequence = SEQ_STREAM_HEADER;
+ next->coder->block_options.version = 0;
+ next->coder->block_options.check = check;
+
+ // Initialize the Index
+ lzma_index_end(next->coder->index, allocator);
+ next->coder->index = lzma_index_init(allocator);
+ if (next->coder->index == NULL)
+ return LZMA_MEM_ERROR;
+
+ // Encode the Stream Header
+ return_if_error(lzma_stream_header_encode(
+ &stream_flags, next->coder->buffer));
+
+ next->coder->buffer_pos = 0;
+ next->coder->buffer_size = LZMA_STREAM_HEADER_SIZE;
+
+ // Initialize the Block encoder. This way we detect unsupported
+ // filter chains when initializing the Stream encoder instead of
+ // giving an error after Stream Header has already written out.
+ return stream_encoder_update(
+ next->coder, allocator, filters, NULL);
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_stream_encoder(lzma_stream *strm,
+ const lzma_filter *filters, lzma_check check)
+{
+ lzma_next_strm_init2(lzma_stream_encoder_init, strm, filters, check);
+
+ strm->internal->supported_actions[LZMA_RUN] = true;
+ strm->internal->supported_actions[LZMA_SYNC_FLUSH] = true;
+ strm->internal->supported_actions[LZMA_FULL_FLUSH] = true;
+ strm->internal->supported_actions[LZMA_FINISH] = true;
+
+ return LZMA_OK;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/stream_encoder.h b/Utilities/cmliblzma/liblzma/common/stream_encoder.h
new file mode 100644
index 000000000..46a7aed72
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/stream_encoder.h
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file stream_encoder.h
+/// \brief Encodes .xz Streams
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_STREAM_ENCODER_H
+#define LZMA_STREAM_ENCODER_H
+
+#include "common.h"
+
+
+extern lzma_ret lzma_stream_encoder_init(
+ lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter *filters, lzma_check check);
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/common/stream_flags_common.c b/Utilities/cmliblzma/liblzma/common/stream_flags_common.c
new file mode 100644
index 000000000..fbe8eb8ab
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/stream_flags_common.c
@@ -0,0 +1,47 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file stream_flags_common.c
+/// \brief Common stuff for Stream flags coders
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "stream_flags_common.h"
+
+
+const uint8_t lzma_header_magic[6] = { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00 };
+const uint8_t lzma_footer_magic[2] = { 0x59, 0x5A };
+
+
+extern LZMA_API(lzma_ret)
+lzma_stream_flags_compare(
+ const lzma_stream_flags *a, const lzma_stream_flags *b)
+{
+ // We can compare only version 0 structures.
+ if (a->version != 0 || b->version != 0)
+ return LZMA_OPTIONS_ERROR;
+
+ // Check type
+ if ((unsigned int)(a->check) > LZMA_CHECK_ID_MAX
+ || (unsigned int)(b->check) > LZMA_CHECK_ID_MAX)
+ return LZMA_PROG_ERROR;
+
+ if (a->check != b->check)
+ return LZMA_DATA_ERROR;
+
+ // Backward Sizes are compared only if they are known in both.
+ if (a->backward_size != LZMA_VLI_UNKNOWN
+ && b->backward_size != LZMA_VLI_UNKNOWN) {
+ if (!is_backward_size_valid(a) || !is_backward_size_valid(b))
+ return LZMA_PROG_ERROR;
+
+ if (a->backward_size != b->backward_size)
+ return LZMA_DATA_ERROR;
+ }
+
+ return LZMA_OK;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/stream_flags_common.h b/Utilities/cmliblzma/liblzma/common/stream_flags_common.h
new file mode 100644
index 000000000..9f3122a3b
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/stream_flags_common.h
@@ -0,0 +1,33 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file stream_flags_common.h
+/// \brief Common stuff for Stream flags coders
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_STREAM_FLAGS_COMMON_H
+#define LZMA_STREAM_FLAGS_COMMON_H
+
+#include "common.h"
+
+/// Size of the Stream Flags field
+#define LZMA_STREAM_FLAGS_SIZE 2
+
+extern const uint8_t lzma_header_magic[6];
+extern const uint8_t lzma_footer_magic[2];
+
+
+static inline bool
+is_backward_size_valid(const lzma_stream_flags *options)
+{
+ return options->backward_size >= LZMA_BACKWARD_SIZE_MIN
+ && options->backward_size <= LZMA_BACKWARD_SIZE_MAX
+ && (options->backward_size & 3) == 0;
+}
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/common/stream_flags_decoder.c b/Utilities/cmliblzma/liblzma/common/stream_flags_decoder.c
new file mode 100644
index 000000000..8cf48a4ca
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/stream_flags_decoder.c
@@ -0,0 +1,86 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file stream_flags_decoder.c
+/// \brief Decodes Stream Header and Stream Footer from .xz files
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "stream_flags_common.h"
+
+
+static bool
+stream_flags_decode(lzma_stream_flags *options, const uint8_t *in)
+{
+ // Reserved bits must be unset.
+ if (in[0] != 0x00 || (in[1] & 0xF0))
+ return true;
+
+ options->version = 0;
+ options->check = in[1] & 0x0F;
+
+ return false;
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_stream_header_decode(lzma_stream_flags *options, const uint8_t *in)
+{
+ uint32_t crc;
+
+ // Magic
+ if (memcmp(in, lzma_header_magic, sizeof(lzma_header_magic)) != 0)
+ return LZMA_FORMAT_ERROR;
+
+ // Verify the CRC32 so we can distinguish between corrupt
+ // and unsupported files.
+ crc = lzma_crc32(in + sizeof(lzma_header_magic),
+ LZMA_STREAM_FLAGS_SIZE, 0);
+ if (crc != unaligned_read32le(in + sizeof(lzma_header_magic)
+ + LZMA_STREAM_FLAGS_SIZE))
+ return LZMA_DATA_ERROR;
+
+ // Stream Flags
+ if (stream_flags_decode(options, in + sizeof(lzma_header_magic)))
+ return LZMA_OPTIONS_ERROR;
+
+ // Set Backward Size to indicate unknown value. That way
+ // lzma_stream_flags_compare() can be used to compare Stream Header
+ // and Stream Footer while keeping it useful also for comparing
+ // two Stream Footers.
+ options->backward_size = LZMA_VLI_UNKNOWN;
+
+ return LZMA_OK;
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_stream_footer_decode(lzma_stream_flags *options, const uint8_t *in)
+{
+ uint32_t crc;
+
+ // Magic
+ if (memcmp(in + sizeof(uint32_t) * 2 + LZMA_STREAM_FLAGS_SIZE,
+ lzma_footer_magic, sizeof(lzma_footer_magic)) != 0)
+ return LZMA_FORMAT_ERROR;
+
+ // CRC32
+ crc = lzma_crc32(in + sizeof(uint32_t),
+ sizeof(uint32_t) + LZMA_STREAM_FLAGS_SIZE, 0);
+ if (crc != unaligned_read32le(in))
+ return LZMA_DATA_ERROR;
+
+ // Stream Flags
+ if (stream_flags_decode(options, in + sizeof(uint32_t) * 2))
+ return LZMA_OPTIONS_ERROR;
+
+ // Backward Size
+ options->backward_size = unaligned_read32le(in + sizeof(uint32_t));
+ options->backward_size = (options->backward_size + 1) * 4;
+
+ return LZMA_OK;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/stream_flags_encoder.c b/Utilities/cmliblzma/liblzma/common/stream_flags_encoder.c
new file mode 100644
index 000000000..290339e08
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/stream_flags_encoder.c
@@ -0,0 +1,90 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file stream_flags_encoder.c
+/// \brief Encodes Stream Header and Stream Footer for .xz files
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "stream_flags_common.h"
+
+
+static bool
+stream_flags_encode(const lzma_stream_flags *options, uint8_t *out)
+{
+ if ((unsigned int)(options->check) > LZMA_CHECK_ID_MAX)
+ return true;
+
+ out[0] = 0x00;
+ out[1] = options->check;
+
+ return false;
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_stream_header_encode(const lzma_stream_flags *options, uint8_t *out)
+{
+ uint32_t crc;
+
+ assert(sizeof(lzma_header_magic) + LZMA_STREAM_FLAGS_SIZE
+ + 4 == LZMA_STREAM_HEADER_SIZE);
+
+ if (options->version != 0)
+ return LZMA_OPTIONS_ERROR;
+
+ // Magic
+ memcpy(out, lzma_header_magic, sizeof(lzma_header_magic));
+
+ // Stream Flags
+ if (stream_flags_encode(options, out + sizeof(lzma_header_magic)))
+ return LZMA_PROG_ERROR;
+
+ // CRC32 of the Stream Header
+ crc = lzma_crc32(out + sizeof(lzma_header_magic),
+ LZMA_STREAM_FLAGS_SIZE, 0);
+
+ unaligned_write32le(out + sizeof(lzma_header_magic)
+ + LZMA_STREAM_FLAGS_SIZE, crc);
+
+ return LZMA_OK;
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_stream_footer_encode(const lzma_stream_flags *options, uint8_t *out)
+{
+ uint32_t crc;
+
+ assert(2 * 4 + LZMA_STREAM_FLAGS_SIZE + sizeof(lzma_footer_magic)
+ == LZMA_STREAM_HEADER_SIZE);
+
+ if (options->version != 0)
+ return LZMA_OPTIONS_ERROR;
+
+ // Backward Size
+ if (!is_backward_size_valid(options))
+ return LZMA_PROG_ERROR;
+
+ unaligned_write32le(out + 4, options->backward_size / 4 - 1);
+
+ // Stream Flags
+ if (stream_flags_encode(options, out + 2 * 4))
+ return LZMA_PROG_ERROR;
+
+ // CRC32
+ crc = lzma_crc32(
+ out + 4, 4 + LZMA_STREAM_FLAGS_SIZE, 0);
+
+ unaligned_write32le(out, crc);
+
+ // Magic
+ memcpy(out + 2 * 4 + LZMA_STREAM_FLAGS_SIZE,
+ lzma_footer_magic, sizeof(lzma_footer_magic));
+
+ return LZMA_OK;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/vli_decoder.c b/Utilities/cmliblzma/liblzma/common/vli_decoder.c
new file mode 100644
index 000000000..1c663844f
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/vli_decoder.c
@@ -0,0 +1,86 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file vli_decoder.c
+/// \brief Decodes variable-length integers
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "common.h"
+
+
+extern LZMA_API(lzma_ret)
+lzma_vli_decode(lzma_vli *LZMA_RESTRICT vli, size_t *vli_pos,
+ const uint8_t *LZMA_RESTRICT in, size_t *LZMA_RESTRICT in_pos,
+ size_t in_size)
+{
+ // If we haven't been given vli_pos, work in single-call mode.
+ size_t vli_pos_internal = 0;
+ if (vli_pos == NULL) {
+ vli_pos = &vli_pos_internal;
+ *vli = 0;
+
+ // If there's no input, use LZMA_DATA_ERROR. This way it is
+ // easy to decode VLIs from buffers that have known size,
+ // and get the correct error code in case the buffer is
+ // too short.
+ if (*in_pos >= in_size)
+ return LZMA_DATA_ERROR;
+
+ } else {
+ // Initialize *vli when starting to decode a new integer.
+ if (*vli_pos == 0)
+ *vli = 0;
+
+ // Validate the arguments.
+ if (*vli_pos >= LZMA_VLI_BYTES_MAX
+ || (*vli >> (*vli_pos * 7)) != 0)
+ return LZMA_PROG_ERROR;;
+
+ if (*in_pos >= in_size)
+ return LZMA_BUF_ERROR;
+ }
+
+ do {
+ // Read the next byte. Use a temporary variable so that we
+ // can update *in_pos immediately.
+ const uint8_t byte = in[*in_pos];
+ ++*in_pos;
+
+ // Add the newly read byte to *vli.
+ *vli += (lzma_vli)(byte & 0x7F) << (*vli_pos * 7);
+ ++*vli_pos;
+
+ // Check if this is the last byte of a multibyte integer.
+ if ((byte & 0x80) == 0) {
+ // We don't allow using variable-length integers as
+ // padding i.e. the encoding must use the most the
+ // compact form.
+ if (byte == 0x00 && *vli_pos > 1)
+ return LZMA_DATA_ERROR;
+
+ return vli_pos == &vli_pos_internal
+ ? LZMA_OK : LZMA_STREAM_END;
+ }
+
+ // There is at least one more byte coming. If we have already
+ // read maximum number of bytes, the integer is considered
+ // corrupt.
+ //
+ // If we need bigger integers in future, old versions liblzma
+ // will confusingly indicate the file being corrupt istead of
+ // unsupported. I suppose it's still better this way, because
+ // in the foreseeable future (writing this in 2008) the only
+ // reason why files would appear having over 63-bit integers
+ // is that the files are simply corrupt.
+ if (*vli_pos == LZMA_VLI_BYTES_MAX)
+ return LZMA_DATA_ERROR;
+
+ } while (*in_pos < in_size);
+
+ return vli_pos == &vli_pos_internal ? LZMA_DATA_ERROR : LZMA_OK;
+}
diff --git a/Utilities/cmliblzma/liblzma/common/vli_encoder.c b/Utilities/cmliblzma/liblzma/common/vli_encoder.c
new file mode 100644
index 000000000..09e90cbd7
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/vli_encoder.c
@@ -0,0 +1,69 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file vli_encoder.c
+/// \brief Encodes variable-length integers
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "common.h"
+
+
+extern LZMA_API(lzma_ret)
+lzma_vli_encode(lzma_vli vli, size_t *vli_pos,
+ uint8_t *LZMA_RESTRICT out, size_t *LZMA_RESTRICT out_pos,
+ size_t out_size)
+{
+ // If we haven't been given vli_pos, work in single-call mode.
+ size_t vli_pos_internal = 0;
+ if (vli_pos == NULL) {
+ vli_pos = &vli_pos_internal;
+
+ // In single-call mode, we expect that the caller has
+ // reserved enough output space.
+ if (*out_pos >= out_size)
+ return LZMA_PROG_ERROR;
+ } else {
+ // This never happens when we are called by liblzma, but
+ // may happen if called directly from an application.
+ if (*out_pos >= out_size)
+ return LZMA_BUF_ERROR;
+ }
+
+ // Validate the arguments.
+ if (*vli_pos >= LZMA_VLI_BYTES_MAX || vli > LZMA_VLI_MAX)
+ return LZMA_PROG_ERROR;
+
+ // Shift vli so that the next bits to encode are the lowest. In
+ // single-call mode this never changes vli since *vli_pos is zero.
+ vli >>= *vli_pos * 7;
+
+ // Write the non-last bytes in a loop.
+ while (vli >= 0x80) {
+ // We don't need *vli_pos during this function call anymore,
+ // but update it here so that it is ready if we need to
+ // return before the whole integer has been decoded.
+ ++*vli_pos;
+ assert(*vli_pos < LZMA_VLI_BYTES_MAX);
+
+ // Write the next byte.
+ out[*out_pos] = (uint8_t)(vli) | 0x80;
+ vli >>= 7;
+
+ if (++*out_pos == out_size)
+ return vli_pos == &vli_pos_internal
+ ? LZMA_PROG_ERROR : LZMA_OK;
+ }
+
+ // Write the last byte.
+ out[*out_pos] = (uint8_t)(vli);
+ ++*out_pos;
+ ++*vli_pos;
+
+ return vli_pos == &vli_pos_internal ? LZMA_OK : LZMA_STREAM_END;
+
+}
diff --git a/Utilities/cmliblzma/liblzma/common/vli_size.c b/Utilities/cmliblzma/liblzma/common/vli_size.c
new file mode 100644
index 000000000..8b931e40b
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/common/vli_size.c
@@ -0,0 +1,31 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file vli_size.c
+/// \brief Calculates the encoded size of a variable-length integer
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "common.h"
+
+
+extern LZMA_API(uint32_t)
+lzma_vli_size(lzma_vli vli)
+{
+ uint32_t i = 0;
+
+ if (vli > LZMA_VLI_MAX)
+ return 0;
+
+ do {
+ vli >>= 7;
+ ++i;
+ } while (vli != 0);
+
+ assert(i <= LZMA_VLI_BYTES_MAX);
+ return i;
+}
diff --git a/Utilities/cmliblzma/liblzma/delta/delta_common.c b/Utilities/cmliblzma/liblzma/delta/delta_common.c
new file mode 100644
index 000000000..803e674a1
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/delta/delta_common.c
@@ -0,0 +1,72 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file delta_common.c
+/// \brief Common stuff for Delta encoder and decoder
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "delta_common.h"
+#include "delta_private.h"
+
+
+static void
+delta_coder_end(lzma_coder *coder, lzma_allocator *allocator)
+{
+ lzma_next_end(&coder->next, allocator);
+ lzma_free(coder, allocator);
+ return;
+}
+
+
+extern lzma_ret
+lzma_delta_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter_info *filters)
+{
+ const lzma_options_delta *opt;
+
+ // Allocate memory for the decoder if needed.
+ if (next->coder == NULL) {
+ next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
+ if (next->coder == NULL)
+ return LZMA_MEM_ERROR;
+
+ // End function is the same for encoder and decoder.
+ next->end = &delta_coder_end;
+ next->coder->next = LZMA_NEXT_CODER_INIT;
+ }
+
+ // Validate the options.
+ if (lzma_delta_coder_memusage(filters[0].options) == UINT64_MAX)
+ return LZMA_OPTIONS_ERROR;
+
+ // Set the delta distance.
+ opt = filters[0].options;
+ next->coder->distance = opt->dist;
+
+ // Initialize the rest of the variables.
+ next->coder->pos = 0;
+ memzero(next->coder->history, LZMA_DELTA_DIST_MAX);
+
+ // Initialize the next decoder in the chain, if any.
+ return lzma_next_filter_init(&next->coder->next,
+ allocator, filters + 1);
+}
+
+
+extern uint64_t
+lzma_delta_coder_memusage(const void *options)
+{
+ const lzma_options_delta *opt = options;
+
+ if (opt == NULL || opt->type != LZMA_DELTA_TYPE_BYTE
+ || opt->dist < LZMA_DELTA_DIST_MIN
+ || opt->dist > LZMA_DELTA_DIST_MAX)
+ return UINT64_MAX;
+
+ return sizeof(lzma_coder);
+}
diff --git a/Utilities/cmliblzma/liblzma/delta/delta_common.h b/Utilities/cmliblzma/liblzma/delta/delta_common.h
new file mode 100644
index 000000000..7e7e1baaf
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/delta/delta_common.h
@@ -0,0 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file delta_common.h
+/// \brief Common stuff for Delta encoder and decoder
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_DELTA_COMMON_H
+#define LZMA_DELTA_COMMON_H
+
+#include "common.h"
+
+extern uint64_t lzma_delta_coder_memusage(const void *options);
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/delta/delta_decoder.c b/Utilities/cmliblzma/liblzma/delta/delta_decoder.c
new file mode 100644
index 000000000..28df72735
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/delta/delta_decoder.c
@@ -0,0 +1,79 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file delta_decoder.c
+/// \brief Delta filter decoder
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "delta_decoder.h"
+#include "delta_private.h"
+
+
+static void
+decode_buffer(lzma_coder *coder, uint8_t *buffer, size_t size)
+{
+ size_t i;
+ const size_t distance = coder->distance;
+
+ for (i = 0; i < size; ++i) {
+ buffer[i] += coder->history[(distance + coder->pos) & 0xFF];
+ coder->history[coder->pos-- & 0xFF] = buffer[i];
+ }
+}
+
+
+static lzma_ret
+delta_decode(lzma_coder *coder, lzma_allocator *allocator,
+ const uint8_t *LZMA_RESTRICT in, size_t *LZMA_RESTRICT in_pos,
+ size_t in_size, uint8_t *LZMA_RESTRICT out,
+ size_t *LZMA_RESTRICT out_pos, size_t out_size, lzma_action action)
+{
+ const size_t out_start = *out_pos;
+ lzma_ret ret;
+
+ assert(coder->next.code != NULL);
+
+ ret = coder->next.code(coder->next.coder, allocator,
+ in, in_pos, in_size, out, out_pos, out_size,
+ action);
+
+ decode_buffer(coder, out + out_start, *out_pos - out_start);
+
+ return ret;
+}
+
+
+extern lzma_ret
+lzma_delta_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter_info *filters)
+{
+ next->code = &delta_decode;
+ return lzma_delta_coder_init(next, allocator, filters);
+}
+
+
+extern lzma_ret
+lzma_delta_props_decode(void **options, lzma_allocator *allocator,
+ const uint8_t *props, size_t props_size)
+{
+ lzma_options_delta *opt;
+
+ if (props_size != 1)
+ return LZMA_OPTIONS_ERROR;
+
+ opt = lzma_alloc(sizeof(lzma_options_delta), allocator);
+ if (opt == NULL)
+ return LZMA_MEM_ERROR;
+
+ opt->type = LZMA_DELTA_TYPE_BYTE;
+ opt->dist = props[0] + 1;
+
+ *options = opt;
+
+ return LZMA_OK;
+}
diff --git a/Utilities/cmliblzma/liblzma/delta/delta_decoder.h b/Utilities/cmliblzma/liblzma/delta/delta_decoder.h
new file mode 100644
index 000000000..ae89acc59
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/delta/delta_decoder.h
@@ -0,0 +1,25 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file delta_decoder.h
+/// \brief Delta filter decoder
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_DELTA_DECODER_H
+#define LZMA_DELTA_DECODER_H
+
+#include "delta_common.h"
+
+extern lzma_ret lzma_delta_decoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters);
+
+extern lzma_ret lzma_delta_props_decode(
+ void **options, lzma_allocator *allocator,
+ const uint8_t *props, size_t props_size);
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/delta/delta_encoder.c b/Utilities/cmliblzma/liblzma/delta/delta_encoder.c
new file mode 100644
index 000000000..a39c154f1
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/delta/delta_encoder.c
@@ -0,0 +1,124 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file delta_encoder.c
+/// \brief Delta filter encoder
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "delta_encoder.h"
+#include "delta_private.h"
+
+
+/// Copies and encodes the data at the same time. This is used when Delta
+/// is the first filter in the chain (and thus the last filter in the
+/// encoder's filter stack).
+static void
+copy_and_encode(lzma_coder *coder,
+ const uint8_t *LZMA_RESTRICT in, uint8_t *LZMA_RESTRICT out, size_t size)
+{
+ size_t i;
+ const size_t distance = coder->distance;
+
+ for (i = 0; i < size; ++i) {
+ const uint8_t tmp = coder->history[
+ (distance + coder->pos) & 0xFF];
+ coder->history[coder->pos-- & 0xFF] = in[i];
+ out[i] = in[i] - tmp;
+ }
+}
+
+
+/// Encodes the data in place. This is used when we are the last filter
+/// in the chain (and thus non-last filter in the encoder's filter stack).
+static void
+encode_in_place(lzma_coder *coder, uint8_t *buffer, size_t size)
+{
+ size_t i;
+ const size_t distance = coder->distance;
+
+ for (i = 0; i < size; ++i) {
+ const uint8_t tmp = coder->history[
+ (distance + coder->pos) & 0xFF];
+ coder->history[coder->pos-- & 0xFF] = buffer[i];
+ buffer[i] -= tmp;
+ }
+}
+
+
+static lzma_ret
+delta_encode(lzma_coder *coder, lzma_allocator *allocator,
+ const uint8_t *LZMA_RESTRICT in, size_t *LZMA_RESTRICT in_pos,
+ size_t in_size, uint8_t *LZMA_RESTRICT out,
+ size_t *LZMA_RESTRICT out_pos, size_t out_size, lzma_action action)
+{
+ lzma_ret ret;
+
+ if (coder->next.code == NULL) {
+ const size_t in_avail = in_size - *in_pos;
+ const size_t out_avail = out_size - *out_pos;
+ const size_t size = my_min(in_avail, out_avail);
+
+ copy_and_encode(coder, in + *in_pos, out + *out_pos, size);
+
+ *in_pos += size;
+ *out_pos += size;
+
+ ret = action != LZMA_RUN && *in_pos == in_size
+ ? LZMA_STREAM_END : LZMA_OK;
+
+ } else {
+ const size_t out_start = *out_pos;
+
+ ret = coder->next.code(coder->next.coder, allocator,
+ in, in_pos, in_size, out, out_pos, out_size,
+ action);
+
+ encode_in_place(coder, out + out_start, *out_pos - out_start);
+ }
+
+ return ret;
+}
+
+
+static lzma_ret
+delta_encoder_update(lzma_coder *coder, lzma_allocator *allocator,
+ const lzma_filter *filters_null lzma_attribute((__unused__)),
+ const lzma_filter *reversed_filters)
+{
+ // Delta doesn't and will never support changing the options in
+ // the middle of encoding. If the app tries to change them, we
+ // simply ignore them.
+ return lzma_next_filter_update(
+ &coder->next, allocator, reversed_filters + 1);
+}
+
+
+extern lzma_ret
+lzma_delta_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter_info *filters)
+{
+ next->code = &delta_encode;
+ next->update = &delta_encoder_update;
+ return lzma_delta_coder_init(next, allocator, filters);
+}
+
+
+extern lzma_ret
+lzma_delta_props_encode(const void *options, uint8_t *out)
+{
+ const lzma_options_delta *opt = options;
+
+ // The caller must have already validated the options, so it's
+ // LZMA_PROG_ERROR if they are invalid.
+ if (lzma_delta_coder_memusage(options) == UINT64_MAX)
+ return LZMA_PROG_ERROR;
+
+ out[0] = opt->dist - LZMA_DELTA_DIST_MIN;
+
+ return LZMA_OK;
+}
diff --git a/Utilities/cmliblzma/liblzma/delta/delta_encoder.h b/Utilities/cmliblzma/liblzma/delta/delta_encoder.h
new file mode 100644
index 000000000..a447862f2
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/delta/delta_encoder.h
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file delta_encoder.h
+/// \brief Delta filter encoder
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_DELTA_ENCODER_H
+#define LZMA_DELTA_ENCODER_H
+
+#include "delta_common.h"
+
+extern lzma_ret lzma_delta_encoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters);
+
+extern lzma_ret lzma_delta_props_encode(const void *options, uint8_t *out);
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/delta/delta_private.h b/Utilities/cmliblzma/liblzma/delta/delta_private.h
new file mode 100644
index 000000000..62b7fed86
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/delta/delta_private.h
@@ -0,0 +1,37 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file delta_private.h
+/// \brief Private common stuff for Delta encoder and decoder
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_DELTA_PRIVATE_H
+#define LZMA_DELTA_PRIVATE_H
+
+#include "delta_common.h"
+
+struct lzma_coder_s {
+ /// Next coder in the chain
+ lzma_next_coder next;
+
+ /// Delta distance
+ size_t distance;
+
+ /// Position in history[]
+ uint8_t pos;
+
+ /// Buffer to hold history of the original data
+ uint8_t history[LZMA_DELTA_DIST_MAX];
+};
+
+
+extern lzma_ret lzma_delta_coder_init(
+ lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter_info *filters);
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/liblzma.pc.in b/Utilities/cmliblzma/liblzma/liblzma.pc.in
new file mode 100644
index 000000000..7f11f1a20
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/liblzma.pc.in
@@ -0,0 +1,19 @@
+#
+# Author: Lasse Collin
+#
+# This file has been put into the public domain.
+# You can do whatever you want with this file.
+#
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: liblzma
+Description: General purpose data compression library
+URL: @PACKAGE_URL@
+Version: @PACKAGE_VERSION@
+Cflags: -I${includedir}
+Libs: -L${libdir} -llzma
+Libs.private: @PTHREAD_CFLAGS@ @PTHREAD_LIBS@
diff --git a/Utilities/cmliblzma/liblzma/liblzma_w32res.rc b/Utilities/cmliblzma/liblzma/liblzma_w32res.rc
new file mode 100644
index 000000000..773caf8b4
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/liblzma_w32res.rc
@@ -0,0 +1,14 @@
+/*
+ * Author: Lasse Collin
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ */
+
+#define MY_TYPE VFT_DLL
+#define MY_NAME "liblzma"
+#define MY_SUFFIX ".dll"
+#define MY_DESC "liblzma data compression library"
+#define PACKAGE_NAME "XZ Utils"
+#define PACKAGE_URL "http://tukaani.org/xz/"
+#include "common_w32res.rc"
diff --git a/Utilities/cmliblzma/liblzma/lz/lz_decoder.c b/Utilities/cmliblzma/liblzma/lz/lz_decoder.c
new file mode 100644
index 000000000..9fa1bdc3a
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/lz/lz_decoder.c
@@ -0,0 +1,307 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file lz_decoder.c
+/// \brief LZ out window
+///
+// Authors: Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+// liblzma supports multiple LZ77-based filters. The LZ part is shared
+// between these filters. The LZ code takes care of dictionary handling
+// and passing the data between filters in the chain. The filter-specific
+// part decodes from the input buffer to the dictionary.
+
+
+#include "lz_decoder.h"
+
+
+struct lzma_coder_s {
+ /// Dictionary (history buffer)
+ lzma_dict dict;
+
+ /// The actual LZ-based decoder e.g. LZMA
+ lzma_lz_decoder lz;
+
+ /// Next filter in the chain, if any. Note that LZMA and LZMA2 are
+ /// only allowed as the last filter, but the long-range filter in
+ /// future can be in the middle of the chain.
+ lzma_next_coder next;
+
+ /// True if the next filter in the chain has returned LZMA_STREAM_END.
+ bool next_finished;
+
+ /// True if the LZ decoder (e.g. LZMA) has detected end of payload
+ /// marker. This may become true before next_finished becomes true.
+ bool this_finished;
+
+ /// Temporary buffer needed when the LZ-based filter is not the last
+ /// filter in the chain. The output of the next filter is first
+ /// decoded into buffer[], which is then used as input for the actual
+ /// LZ-based decoder.
+ struct {
+ size_t pos;
+ size_t size;
+ uint8_t buffer[LZMA_BUFFER_SIZE];
+ } temp;
+};
+
+
+static void
+lz_decoder_reset(lzma_coder *coder)
+{
+ coder->dict.pos = 0;
+ coder->dict.full = 0;
+ coder->dict.buf[coder->dict.size - 1] = '\0';
+ coder->dict.need_reset = false;
+ return;
+}
+
+
+static lzma_ret
+decode_buffer(lzma_coder *coder,
+ const uint8_t *LZMA_RESTRICT in, size_t *LZMA_RESTRICT in_pos,
+ size_t in_size, uint8_t *LZMA_RESTRICT out,
+ size_t *LZMA_RESTRICT out_pos, size_t out_size)
+{
+ while (true) {
+ size_t copy_size;
+ size_t dict_start;
+ lzma_ret ret;
+
+ // Wrap the dictionary if needed.
+ if (coder->dict.pos == coder->dict.size)
+ coder->dict.pos = 0;
+
+ // Store the current dictionary position. It is needed to know
+ // where to start copying to the out[] buffer.
+ dict_start = coder->dict.pos;
+
+ // Calculate how much we allow coder->lz.code() to decode.
+ // It must not decode past the end of the dictionary
+ // buffer, and we don't want it to decode more than is
+ // actually needed to fill the out[] buffer.
+ coder->dict.limit = coder->dict.pos
+ + my_min(out_size - *out_pos,
+ coder->dict.size - coder->dict.pos);
+
+ // Call the coder->lz.code() to do the actual decoding.
+ ret = coder->lz.code(
+ coder->lz.coder, &coder->dict,
+ in, in_pos, in_size);
+
+ // Copy the decoded data from the dictionary to the out[]
+ // buffer.
+ copy_size = coder->dict.pos - dict_start;
+ assert(copy_size <= out_size - *out_pos);
+ memcpy(out + *out_pos, coder->dict.buf + dict_start,
+ copy_size);
+ *out_pos += copy_size;
+
+ // Reset the dictionary if so requested by coder->lz.code().
+ if (coder->dict.need_reset) {
+ lz_decoder_reset(coder);
+
+ // Since we reset dictionary, we don't check if
+ // dictionary became full.
+ if (ret != LZMA_OK || *out_pos == out_size)
+ return ret;
+ } else {
+ // Return if everything got decoded or an error
+ // occurred, or if there's no more data to decode.
+ //
+ // Note that detecting if there's something to decode
+ // is done by looking if dictionary become full
+ // instead of looking if *in_pos == in_size. This
+ // is because it is possible that all the input was
+ // consumed already but some data is pending to be
+ // written to the dictionary.
+ if (ret != LZMA_OK || *out_pos == out_size
+ || coder->dict.pos < coder->dict.size)
+ return ret;
+ }
+ }
+}
+
+
+static lzma_ret
+lz_decode(lzma_coder *coder,
+ lzma_allocator *allocator lzma_attribute((__unused__)),
+ const uint8_t *LZMA_RESTRICT in, size_t *LZMA_RESTRICT in_pos,
+ size_t in_size, uint8_t *LZMA_RESTRICT out,
+ size_t *LZMA_RESTRICT out_pos, size_t out_size,
+ lzma_action action)
+{
+ if (coder->next.code == NULL)
+ return decode_buffer(coder, in, in_pos, in_size,
+ out, out_pos, out_size);
+
+ // We aren't the last coder in the chain, we need to decode
+ // our input to a temporary buffer.
+ while (*out_pos < out_size) {
+ lzma_ret ret;
+
+ // Fill the temporary buffer if it is empty.
+ if (!coder->next_finished
+ && coder->temp.pos == coder->temp.size) {
+ coder->temp.pos = 0;
+ coder->temp.size = 0;
+
+ ret = coder->next.code(
+ coder->next.coder,
+ allocator, in, in_pos, in_size,
+ coder->temp.buffer, &coder->temp.size,
+ LZMA_BUFFER_SIZE, action);
+
+ if (ret == LZMA_STREAM_END)
+ coder->next_finished = true;
+ else if (ret != LZMA_OK || coder->temp.size == 0)
+ return ret;
+ }
+
+ if (coder->this_finished) {
+ if (coder->temp.size != 0)
+ return LZMA_DATA_ERROR;
+
+ if (coder->next_finished)
+ return LZMA_STREAM_END;
+
+ return LZMA_OK;
+ }
+
+ ret = decode_buffer(coder, coder->temp.buffer,
+ &coder->temp.pos, coder->temp.size,
+ out, out_pos, out_size);
+
+ if (ret == LZMA_STREAM_END)
+ coder->this_finished = true;
+ else if (ret != LZMA_OK)
+ return ret;
+ else if (coder->next_finished && *out_pos < out_size)
+ return LZMA_DATA_ERROR;
+ }
+
+ return LZMA_OK;
+}
+
+
+static void
+lz_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
+{
+ lzma_next_end(&coder->next, allocator);
+ lzma_free(coder->dict.buf, allocator);
+
+ if (coder->lz.end != NULL)
+ coder->lz.end(coder->lz.coder, allocator);
+ else
+ lzma_free(coder->lz.coder, allocator);
+
+ lzma_free(coder, allocator);
+ return;
+}
+
+
+extern lzma_ret
+lzma_lz_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter_info *filters,
+ lzma_ret (*lz_init)(lzma_lz_decoder *lz,
+ lzma_allocator *allocator, const void *options,
+ lzma_lz_options *lz_options))
+{
+ lzma_lz_options lz_options;
+
+ // Allocate the base structure if it isn't already allocated.
+ if (next->coder == NULL) {
+ next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
+ if (next->coder == NULL)
+ return LZMA_MEM_ERROR;
+
+ next->code = &lz_decode;
+ next->end = &lz_decoder_end;
+
+ next->coder->dict.buf = NULL;
+ next->coder->dict.size = 0;
+ next->coder->lz = LZMA_LZ_DECODER_INIT;
+ next->coder->next = LZMA_NEXT_CODER_INIT;
+ }
+
+ // Allocate and initialize the LZ-based decoder. It will also give
+ // us the dictionary size.
+ return_if_error(lz_init(&next->coder->lz, allocator,
+ filters[0].options, &lz_options));
+
+ // If the dictionary size is very small, increase it to 4096 bytes.
+ // This is to prevent constant wrapping of the dictionary, which
+ // would slow things down. The downside is that since we don't check
+ // separately for the real dictionary size, we may happily accept
+ // corrupt files.
+ if (lz_options.dict_size < 4096)
+ lz_options.dict_size = 4096;
+
+ // Make dictionary size a multipe of 16. Some LZ-based decoders like
+ // LZMA use the lowest bits lzma_dict.pos to know the alignment of the
+ // data. Aligned buffer is also good when memcpying from the
+ // dictionary to the output buffer, since applications are
+ // recommended to give aligned buffers to liblzma.
+ //
+ // Avoid integer overflow.
+ if (lz_options.dict_size > SIZE_MAX - 15)
+ return LZMA_MEM_ERROR;
+
+ lz_options.dict_size = (lz_options.dict_size + 15) & ~((size_t)(15));
+
+ // Allocate and initialize the dictionary.
+ if (next->coder->dict.size != lz_options.dict_size) {
+ lzma_free(next->coder->dict.buf, allocator);
+ next->coder->dict.buf
+ = lzma_alloc(lz_options.dict_size, allocator);
+ if (next->coder->dict.buf == NULL)
+ return LZMA_MEM_ERROR;
+
+ next->coder->dict.size = lz_options.dict_size;
+ }
+
+ lz_decoder_reset(next->coder);
+
+ // Use the preset dictionary if it was given to us.
+ if (lz_options.preset_dict != NULL
+ && lz_options.preset_dict_size > 0) {
+ // If the preset dictionary is bigger than the actual
+ // dictionary, copy only the tail.
+ const size_t copy_size = my_min(lz_options.preset_dict_size,
+ lz_options.dict_size);
+ const size_t offset = lz_options.preset_dict_size - copy_size;
+ memcpy(next->coder->dict.buf, lz_options.preset_dict + offset,
+ copy_size);
+ next->coder->dict.pos = copy_size;
+ next->coder->dict.full = copy_size;
+ }
+
+ // Miscellaneous initializations
+ next->coder->next_finished = false;
+ next->coder->this_finished = false;
+ next->coder->temp.pos = 0;
+ next->coder->temp.size = 0;
+
+ // Initialize the next filter in the chain, if any.
+ return lzma_next_filter_init(&next->coder->next, allocator,
+ filters + 1);
+}
+
+
+extern uint64_t
+lzma_lz_decoder_memusage(size_t dictionary_size)
+{
+ return sizeof(lzma_coder) + (uint64_t)(dictionary_size);
+}
+
+
+extern void
+lzma_lz_decoder_uncompressed(lzma_coder *coder, lzma_vli uncompressed_size)
+{
+ coder->lz.set_uncompressed(coder->lz.coder, uncompressed_size);
+}
diff --git a/Utilities/cmliblzma/liblzma/lz/lz_decoder.h b/Utilities/cmliblzma/liblzma/lz/lz_decoder.h
new file mode 100644
index 000000000..76011f2ad
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/lz/lz_decoder.h
@@ -0,0 +1,236 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file lz_decoder.h
+/// \brief LZ out window
+///
+// Authors: Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_LZ_DECODER_H
+#define LZMA_LZ_DECODER_H
+
+#include "common.h"
+
+
+typedef struct {
+ /// Pointer to the dictionary buffer. It can be an allocated buffer
+ /// internal to liblzma, or it can a be a buffer given by the
+ /// application when in single-call mode (not implemented yet).
+ uint8_t *buf;
+
+ /// Write position in dictionary. The next byte will be written to
+ /// buf[pos].
+ size_t pos;
+
+ /// Indicates how full the dictionary is. This is used by
+ /// dict_is_distance_valid() to detect corrupt files that would
+ /// read beyond the beginning of the dictionary.
+ size_t full;
+
+ /// Write limit
+ size_t limit;
+
+ /// Size of the dictionary
+ size_t size;
+
+ /// True when dictionary should be reset before decoding more data.
+ bool need_reset;
+
+} lzma_dict;
+
+
+typedef struct {
+ size_t dict_size;
+ const uint8_t *preset_dict;
+ size_t preset_dict_size;
+} lzma_lz_options;
+
+
+typedef struct {
+ /// Data specific to the LZ-based decoder
+ lzma_coder *coder;
+
+ /// Function to decode from in[] to *dict
+ lzma_ret (*code)(lzma_coder *LZMA_RESTRICT coder,
+ lzma_dict *LZMA_RESTRICT dict, const uint8_t *LZMA_RESTRICT in,
+ size_t *LZMA_RESTRICT in_pos, size_t in_size);
+
+ void (*reset)(lzma_coder *coder, const void *options);
+
+ /// Set the uncompressed size
+ void (*set_uncompressed)(lzma_coder *coder,
+ lzma_vli uncompressed_size);
+
+ /// Free allocated resources
+ void (*end)(lzma_coder *coder, lzma_allocator *allocator);
+
+} lzma_lz_decoder;
+
+
+static const lzma_lz_decoder LZMA_LZ_DECODER_INIT =
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ };
+
+
+extern lzma_ret lzma_lz_decoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters,
+ lzma_ret (*lz_init)(lzma_lz_decoder *lz,
+ lzma_allocator *allocator, const void *options,
+ lzma_lz_options *lz_options));
+
+extern uint64_t lzma_lz_decoder_memusage(size_t dictionary_size);
+
+extern void lzma_lz_decoder_uncompressed(
+ lzma_coder *coder, lzma_vli uncompressed_size);
+
+
+//////////////////////
+// Inline functions //
+//////////////////////
+
+/// Get a byte from the history buffer.
+static inline uint8_t
+dict_get(const lzma_dict *const dict, const uint32_t distance)
+{
+ return dict->buf[dict->pos - distance - 1
+ + (distance < dict->pos ? 0 : dict->size)];
+}
+
+
+/// Test if dictionary is empty.
+static inline bool
+dict_is_empty(const lzma_dict *const dict)
+{
+ return dict->full == 0;
+}
+
+
+/// Validate the match distance
+static inline bool
+dict_is_distance_valid(const lzma_dict *const dict, const size_t distance)
+{
+ return dict->full > distance;
+}
+
+
+/// Repeat *len bytes at distance.
+static inline bool
+dict_repeat(lzma_dict *dict, uint32_t distance, uint32_t *len)
+{
+ // Don't write past the end of the dictionary.
+ const size_t dict_avail = dict->limit - dict->pos;
+ uint32_t left = my_min(dict_avail, *len);
+ *len -= left;
+
+ // Repeat a block of data from the history. Because memcpy() is faster
+ // than copying byte by byte in a loop, the copying process gets split
+ // into three cases.
+ if (distance < left) {
+ // Source and target areas overlap, thus we can't use
+ // memcpy() nor even memmove() safely.
+ do {
+ dict->buf[dict->pos] = dict_get(dict, distance);
+ ++dict->pos;
+ } while (--left > 0);
+
+ } else if (distance < dict->pos) {
+ // The easiest and fastest case
+ memcpy(dict->buf + dict->pos,
+ dict->buf + dict->pos - distance - 1,
+ left);
+ dict->pos += left;
+
+ } else {
+ uint32_t copy_pos;
+ uint32_t copy_size;
+
+ // The bigger the dictionary, the more rare this
+ // case occurs. We need to "wrap" the dict, thus
+ // we might need two memcpy() to copy all the data.
+ assert(dict->full == dict->size);
+ copy_pos = dict->pos - distance - 1 + dict->size;
+ copy_size = dict->size - copy_pos;
+
+ if (copy_size < left) {
+ memmove(dict->buf + dict->pos, dict->buf + copy_pos,
+ copy_size);
+ dict->pos += copy_size;
+ copy_size = left - copy_size;
+ memcpy(dict->buf + dict->pos, dict->buf, copy_size);
+ dict->pos += copy_size;
+ } else {
+ memmove(dict->buf + dict->pos, dict->buf + copy_pos,
+ left);
+ dict->pos += left;
+ }
+ }
+
+ // Update how full the dictionary is.
+ if (dict->full < dict->pos)
+ dict->full = dict->pos;
+
+ return unlikely(*len != 0);
+}
+
+
+/// Puts one byte into the dictionary. Returns true if the dictionary was
+/// already full and the byte couldn't be added.
+static inline bool
+dict_put(lzma_dict *dict, uint8_t byte)
+{
+ if (unlikely(dict->pos == dict->limit))
+ return true;
+
+ dict->buf[dict->pos++] = byte;
+
+ if (dict->pos > dict->full)
+ dict->full = dict->pos;
+
+ return false;
+}
+
+
+/// Copies arbitrary amount of data into the dictionary.
+static inline void
+dict_write(lzma_dict *LZMA_RESTRICT dict, const uint8_t *LZMA_RESTRICT in,
+ size_t *LZMA_RESTRICT in_pos, size_t in_size,
+ size_t *LZMA_RESTRICT left)
+{
+ // NOTE: If we are being given more data than the size of the
+ // dictionary, it could be possible to optimize the LZ decoder
+ // so that not everything needs to go through the dictionary.
+ // This shouldn't be very common thing in practice though, and
+ // the slowdown of one extra memcpy() isn't bad compared to how
+ // much time it would have taken if the data were compressed.
+
+ if (in_size - *in_pos > *left)
+ in_size = *in_pos + *left;
+
+ *left -= lzma_bufcpy(in, in_pos, in_size,
+ dict->buf, &dict->pos, dict->limit);
+
+ if (dict->pos > dict->full)
+ dict->full = dict->pos;
+
+ return;
+}
+
+
+static inline void
+dict_reset(lzma_dict *dict)
+{
+ dict->need_reset = true;
+ return;
+}
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/lz/lz_encoder.c b/Utilities/cmliblzma/liblzma/lz/lz_encoder.c
new file mode 100644
index 000000000..1dae924b4
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/lz/lz_encoder.c
@@ -0,0 +1,594 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file lz_encoder.c
+/// \brief LZ in window
+///
+// Authors: Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "lz_encoder.h"
+#include "lz_encoder_hash.h"
+
+// See lz_encoder_hash.h. This is a bit hackish but avoids making
+// endianness a conditional in makefiles.
+#if defined(WORDS_BIGENDIAN) && !defined(HAVE_SMALL)
+# include "lz_encoder_hash_table.h"
+#endif
+
+
+struct lzma_coder_s {
+ /// LZ-based encoder e.g. LZMA
+ lzma_lz_encoder lz;
+
+ /// History buffer and match finder
+ lzma_mf mf;
+
+ /// Next coder in the chain
+ lzma_next_coder next;
+};
+
+
+/// \brief Moves the data in the input window to free space for new data
+///
+/// mf->buffer is a sliding input window, which keeps mf->keep_size_before
+/// bytes of input history available all the time. Now and then we need to
+/// "slide" the buffer to make space for the new data to the end of the
+/// buffer. At the same time, data older than keep_size_before is dropped.
+///
+static void
+move_window(lzma_mf *mf)
+{
+ uint32_t move_offset;
+ size_t move_size;
+
+ // Align the move to a multiple of 16 bytes. Some LZ-based encoders
+ // like LZMA use the lowest bits of mf->read_pos to know the
+ // alignment of the uncompressed data. We also get better speed
+ // for memmove() with aligned buffers.
+ assert(mf->read_pos > mf->keep_size_before);
+ move_offset = (mf->read_pos - mf->keep_size_before) & ~UINT32_C(15);
+
+ assert(mf->write_pos > move_offset);
+ move_size = mf->write_pos - move_offset;
+
+ assert(move_offset + move_size <= mf->size);
+
+ memmove(mf->buffer, mf->buffer + move_offset, move_size);
+
+ mf->offset += move_offset;
+ mf->read_pos -= move_offset;
+ mf->read_limit -= move_offset;
+ mf->write_pos -= move_offset;
+
+ return;
+}
+
+
+/// \brief Tries to fill the input window (mf->buffer)
+///
+/// If we are the last encoder in the chain, our input data is in in[].
+/// Otherwise we call the next filter in the chain to process in[] and
+/// write its output to mf->buffer.
+///
+/// This function must not be called once it has returned LZMA_STREAM_END.
+///
+static lzma_ret
+fill_window(lzma_coder *coder, lzma_allocator *allocator, const uint8_t *in,
+ size_t *in_pos, size_t in_size, lzma_action action)
+{
+ size_t write_pos;
+ lzma_ret ret;
+
+ assert(coder->mf.read_pos <= coder->mf.write_pos);
+
+ // Move the sliding window if needed.
+ if (coder->mf.read_pos >= coder->mf.size - coder->mf.keep_size_after)
+ move_window(&coder->mf);
+
+ // Maybe this is ugly, but lzma_mf uses uint32_t for most things
+ // (which I find cleanest), but we need size_t here when filling
+ // the history window.
+ write_pos = coder->mf.write_pos;
+ if (coder->next.code == NULL) {
+ // Not using a filter, simply memcpy() as much as possible.
+ lzma_bufcpy(in, in_pos, in_size, coder->mf.buffer,
+ &write_pos, coder->mf.size);
+
+ ret = action != LZMA_RUN && *in_pos == in_size
+ ? LZMA_STREAM_END : LZMA_OK;
+
+ } else {
+ ret = coder->next.code(coder->next.coder, allocator,
+ in, in_pos, in_size,
+ coder->mf.buffer, &write_pos,
+ coder->mf.size, action);
+ }
+
+ coder->mf.write_pos = write_pos;
+
+ // If end of stream has been reached or flushing completed, we allow
+ // the encoder to process all the input (that is, read_pos is allowed
+ // to reach write_pos). Otherwise we keep keep_size_after bytes
+ // available as prebuffer.
+ if (ret == LZMA_STREAM_END) {
+ assert(*in_pos == in_size);
+ ret = LZMA_OK;
+ coder->mf.action = action;
+ coder->mf.read_limit = coder->mf.write_pos;
+
+ } else if (coder->mf.write_pos > coder->mf.keep_size_after) {
+ // This needs to be done conditionally, because if we got
+ // only little new input, there may be too little input
+ // to do any encoding yet.
+ coder->mf.read_limit = coder->mf.write_pos
+ - coder->mf.keep_size_after;
+ }
+
+ // Restart the match finder after finished LZMA_SYNC_FLUSH.
+ if (coder->mf.pending > 0
+ && coder->mf.read_pos < coder->mf.read_limit) {
+ // Match finder may update coder->pending and expects it to
+ // start from zero, so use a temporary variable.
+ const size_t pending = coder->mf.pending;
+ coder->mf.pending = 0;
+
+ // Rewind read_pos so that the match finder can hash
+ // the pending bytes.
+ assert(coder->mf.read_pos >= pending);
+ coder->mf.read_pos -= pending;
+
+ // Call the skip function directly instead of using
+ // mf_skip(), since we don't want to touch mf->read_ahead.
+ coder->mf.skip(&coder->mf, pending);
+ }
+
+ return ret;
+}
+
+
+static lzma_ret
+lz_encode(lzma_coder *coder, lzma_allocator *allocator,
+ const uint8_t *LZMA_RESTRICT in, size_t *LZMA_RESTRICT in_pos,
+ size_t in_size,
+ uint8_t *LZMA_RESTRICT out, size_t *LZMA_RESTRICT out_pos,
+ size_t out_size, lzma_action action)
+{
+ while (*out_pos < out_size
+ && (*in_pos < in_size || action != LZMA_RUN)) {
+ lzma_ret ret;
+
+ // Read more data to coder->mf.buffer if needed.
+ if (coder->mf.action == LZMA_RUN && coder->mf.read_pos
+ >= coder->mf.read_limit)
+ return_if_error(fill_window(coder, allocator,
+ in, in_pos, in_size, action));
+
+ // Encode
+ ret = coder->lz.code(coder->lz.coder,
+ &coder->mf, out, out_pos, out_size);
+ if (ret != LZMA_OK) {
+ // Setting this to LZMA_RUN for cases when we are
+ // flushing. It doesn't matter when finishing or if
+ // an error occurred.
+ coder->mf.action = LZMA_RUN;
+ return ret;
+ }
+ }
+
+ return LZMA_OK;
+}
+
+
+static bool
+lz_encoder_prepare(lzma_mf *mf, lzma_allocator *allocator,
+ const lzma_lz_options *lz_options)
+{
+ bool is_bt;
+ uint32_t new_count;
+ uint32_t reserve;
+ uint32_t old_size;
+ uint32_t hash_bytes;
+ uint32_t hs;
+ uint32_t old_count;
+
+ // For now, the dictionary size is limited to 1.5 GiB. This may grow
+ // in the future if needed, but it needs a little more work than just
+ // changing this check.
+ if (lz_options->dict_size < LZMA_DICT_SIZE_MIN
+ || lz_options->dict_size
+ > (UINT32_C(1) << 30) + (UINT32_C(1) << 29)
+ || lz_options->nice_len > lz_options->match_len_max)
+ return true;
+
+ mf->keep_size_before = lz_options->before_size + lz_options->dict_size;
+
+ mf->keep_size_after = lz_options->after_size
+ + lz_options->match_len_max;
+
+ // To avoid constant memmove()s, allocate some extra space. Since
+ // memmove()s become more expensive when the size of the buffer
+ // increases, we reserve more space when a large dictionary is
+ // used to make the memmove() calls rarer.
+ //
+ // This works with dictionaries up to about 3 GiB. If bigger
+ // dictionary is wanted, some extra work is needed:
+ // - Several variables in lzma_mf have to be changed from uint32_t
+ // to size_t.
+ // - Memory usage calculation needs something too, e.g. use uint64_t
+ // for mf->size.
+ reserve = lz_options->dict_size / 2;
+ if (reserve > (UINT32_C(1) << 30))
+ reserve /= 2;
+
+ reserve += (lz_options->before_size + lz_options->match_len_max
+ + lz_options->after_size) / 2 + (UINT32_C(1) << 19);
+
+ old_size = mf->size;
+ mf->size = mf->keep_size_before + reserve + mf->keep_size_after;
+
+ // Deallocate the old history buffer if it exists but has different
+ // size than what is needed now.
+ if (mf->buffer != NULL && old_size != mf->size) {
+ lzma_free(mf->buffer, allocator);
+ mf->buffer = NULL;
+ }
+
+ // Match finder options
+ mf->match_len_max = lz_options->match_len_max;
+ mf->nice_len = lz_options->nice_len;
+
+ // cyclic_size has to stay smaller than 2 Gi. Note that this doesn't
+ // mean limiting dictionary size to less than 2 GiB. With a match
+ // finder that uses multibyte resolution (hashes start at e.g. every
+ // fourth byte), cyclic_size would stay below 2 Gi even when
+ // dictionary size is greater than 2 GiB.
+ //
+ // It would be possible to allow cyclic_size >= 2 Gi, but then we
+ // would need to be careful to use 64-bit types in various places
+ // (size_t could do since we would need bigger than 32-bit address
+ // space anyway). It would also require either zeroing a multigigabyte
+ // buffer at initialization (waste of time and RAM) or allow
+ // normalization in lz_encoder_mf.c to access uninitialized
+ // memory to keep the code simpler. The current way is simple and
+ // still allows pretty big dictionaries, so I don't expect these
+ // limits to change.
+ mf->cyclic_size = lz_options->dict_size + 1;
+
+ // Validate the match finder ID and setup the function pointers.
+ switch (lz_options->match_finder) {
+#ifdef HAVE_MF_HC3
+ case LZMA_MF_HC3:
+ mf->find = &lzma_mf_hc3_find;
+ mf->skip = &lzma_mf_hc3_skip;
+ break;
+#endif
+#ifdef HAVE_MF_HC4
+ case LZMA_MF_HC4:
+ mf->find = &lzma_mf_hc4_find;
+ mf->skip = &lzma_mf_hc4_skip;
+ break;
+#endif
+#ifdef HAVE_MF_BT2
+ case LZMA_MF_BT2:
+ mf->find = &lzma_mf_bt2_find;
+ mf->skip = &lzma_mf_bt2_skip;
+ break;
+#endif
+#ifdef HAVE_MF_BT3
+ case LZMA_MF_BT3:
+ mf->find = &lzma_mf_bt3_find;
+ mf->skip = &lzma_mf_bt3_skip;
+ break;
+#endif
+#ifdef HAVE_MF_BT4
+ case LZMA_MF_BT4:
+ mf->find = &lzma_mf_bt4_find;
+ mf->skip = &lzma_mf_bt4_skip;
+ break;
+#endif
+
+ default:
+ return true;
+ }
+
+ // Calculate the sizes of mf->hash and mf->son and check that
+ // nice_len is big enough for the selected match finder.
+ hash_bytes = lz_options->match_finder & 0x0F;
+ if (hash_bytes > mf->nice_len)
+ return true;
+
+ is_bt = (lz_options->match_finder & 0x10) != 0;
+
+ if (hash_bytes == 2) {
+ hs = 0xFFFF;
+ } else {
+ // Round dictionary size up to the next 2^n - 1 so it can
+ // be used as a hash mask.
+ hs = lz_options->dict_size - 1;
+ hs |= hs >> 1;
+ hs |= hs >> 2;
+ hs |= hs >> 4;
+ hs |= hs >> 8;
+ hs >>= 1;
+ hs |= 0xFFFF;
+
+ if (hs > (UINT32_C(1) << 24)) {
+ if (hash_bytes == 3)
+ hs = (UINT32_C(1) << 24) - 1;
+ else
+ hs >>= 1;
+ }
+ }
+
+ mf->hash_mask = hs;
+
+ ++hs;
+ if (hash_bytes > 2)
+ hs += HASH_2_SIZE;
+ if (hash_bytes > 3)
+ hs += HASH_3_SIZE;
+/*
+ No match finder uses this at the moment.
+ if (mf->hash_bytes > 4)
+ hs += HASH_4_SIZE;
+*/
+
+ // If the above code calculating hs is modified, make sure that
+ // this assertion stays valid (UINT32_MAX / 5 is not strictly the
+ // exact limit). If it doesn't, you need to calculate that
+ // hash_size_sum + sons_count cannot overflow.
+ assert(hs < UINT32_MAX / 5);
+
+ old_count = mf->hash_size_sum + mf->sons_count;
+ mf->hash_size_sum = hs;
+ mf->sons_count = mf->cyclic_size;
+ if (is_bt)
+ mf->sons_count *= 2;
+
+ new_count = mf->hash_size_sum + mf->sons_count;
+
+ // Deallocate the old hash array if it exists and has different size
+ // than what is needed now.
+ if (old_count != new_count) {
+ lzma_free(mf->hash, allocator);
+ mf->hash = NULL;
+ }
+
+ // Maximum number of match finder cycles
+ mf->depth = lz_options->depth;
+ if (mf->depth == 0) {
+ if (is_bt)
+ mf->depth = 16 + mf->nice_len / 2;
+ else
+ mf->depth = 4 + mf->nice_len / 4;
+ }
+
+ return false;
+}
+
+
+static bool
+lz_encoder_init(lzma_mf *mf, lzma_allocator *allocator,
+ const lzma_lz_options *lz_options)
+{
+ size_t alloc_count;
+
+ // Allocate the history buffer.
+ if (mf->buffer == NULL) {
+ mf->buffer = lzma_alloc(mf->size, allocator);
+ if (mf->buffer == NULL)
+ return true;
+ }
+
+ // Use cyclic_size as initial mf->offset. This allows
+ // avoiding a few branches in the match finders. The downside is
+ // that match finder needs to be normalized more often, which may
+ // hurt performance with huge dictionaries.
+ mf->offset = mf->cyclic_size;
+ mf->read_pos = 0;
+ mf->read_ahead = 0;
+ mf->read_limit = 0;
+ mf->write_pos = 0;
+ mf->pending = 0;
+
+ // Allocate match finder's hash array.
+ alloc_count = mf->hash_size_sum + mf->sons_count;
+
+#if UINT32_MAX >= SIZE_MAX / 4
+ // Check for integer overflow. (Huge dictionaries are not
+ // possible on 32-bit CPU.)
+ if (alloc_count > SIZE_MAX / sizeof(uint32_t))
+ return true;
+#endif
+
+ if (mf->hash == NULL) {
+ mf->hash = lzma_alloc(alloc_count * sizeof(uint32_t),
+ allocator);
+ if (mf->hash == NULL)
+ return true;
+ }
+
+ mf->son = mf->hash + mf->hash_size_sum;
+ mf->cyclic_pos = 0;
+
+ // Initialize the hash table. Since EMPTY_HASH_VALUE is zero, we
+ // can use memset().
+/*
+ for (uint32_t i = 0; i < hash_size_sum; ++i)
+ mf->hash[i] = EMPTY_HASH_VALUE;
+*/
+ memzero(mf->hash, (size_t)(mf->hash_size_sum) * sizeof(uint32_t));
+
+ // We don't need to initialize mf->son, but not doing that will
+ // make Valgrind complain in normalization (see normalize() in
+ // lz_encoder_mf.c).
+ //
+ // Skipping this initialization is *very* good when big dictionary is
+ // used but only small amount of data gets actually compressed: most
+ // of the mf->hash won't get actually allocated by the kernel, so
+ // we avoid wasting RAM and improve initialization speed a lot.
+ //memzero(mf->son, (size_t)(mf->sons_count) * sizeof(uint32_t));
+
+ // Handle preset dictionary.
+ if (lz_options->preset_dict != NULL
+ && lz_options->preset_dict_size > 0) {
+ // If the preset dictionary is bigger than the actual
+ // dictionary, use only the tail.
+ mf->write_pos = my_min(lz_options->preset_dict_size, mf->size);
+ memcpy(mf->buffer, lz_options->preset_dict
+ + lz_options->preset_dict_size - mf->write_pos,
+ mf->write_pos);
+ mf->action = LZMA_SYNC_FLUSH;
+ mf->skip(mf, mf->write_pos);
+ }
+
+ mf->action = LZMA_RUN;
+
+ return false;
+}
+
+
+extern uint64_t
+lzma_lz_encoder_memusage(const lzma_lz_options *lz_options)
+{
+ // Old buffers must not exist when calling lz_encoder_prepare().
+ lzma_mf mf = { NULL };
+
+ // Setup the size information into mf.
+ if (lz_encoder_prepare(&mf, NULL, lz_options))
+ return UINT64_MAX;
+
+ // Calculate the memory usage.
+ return (uint64_t)(mf.hash_size_sum + mf.sons_count)
+ * sizeof(uint32_t)
+ + (uint64_t)(mf.size) + sizeof(lzma_coder);
+}
+
+
+static void
+lz_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
+{
+ lzma_next_end(&coder->next, allocator);
+
+ lzma_free(coder->mf.hash, allocator);
+ lzma_free(coder->mf.buffer, allocator);
+
+ if (coder->lz.end != NULL)
+ coder->lz.end(coder->lz.coder, allocator);
+ else
+ lzma_free(coder->lz.coder, allocator);
+
+ lzma_free(coder, allocator);
+ return;
+}
+
+
+static lzma_ret
+lz_encoder_update(lzma_coder *coder, lzma_allocator *allocator,
+ const lzma_filter *filters_null lzma_attribute((__unused__)),
+ const lzma_filter *reversed_filters)
+{
+ if (coder->lz.options_update == NULL)
+ return LZMA_PROG_ERROR;
+
+ return_if_error(coder->lz.options_update(
+ coder->lz.coder, reversed_filters));
+
+ return lzma_next_filter_update(
+ &coder->next, allocator, reversed_filters + 1);
+}
+
+
+extern lzma_ret
+lzma_lz_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter_info *filters,
+ lzma_ret (*lz_init)(lzma_lz_encoder *lz,
+ lzma_allocator *allocator, const void *options,
+ lzma_lz_options *lz_options))
+{
+ lzma_lz_options lz_options;
+
+#ifdef HAVE_SMALL
+ // We need that the CRC32 table has been initialized.
+ lzma_crc32_init();
+#endif
+
+ // Allocate and initialize the base data structure.
+ if (next->coder == NULL) {
+ next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
+ if (next->coder == NULL)
+ return LZMA_MEM_ERROR;
+
+ next->code = &lz_encode;
+ next->end = &lz_encoder_end;
+ next->update = &lz_encoder_update;
+
+ next->coder->lz.coder = NULL;
+ next->coder->lz.code = NULL;
+ next->coder->lz.end = NULL;
+
+ next->coder->mf.buffer = NULL;
+ next->coder->mf.hash = NULL;
+ next->coder->mf.hash_size_sum = 0;
+ next->coder->mf.sons_count = 0;
+
+ next->coder->next = LZMA_NEXT_CODER_INIT;
+ }
+
+ // Initialize the LZ-based encoder.
+ return_if_error(lz_init(&next->coder->lz, allocator,
+ filters[0].options, &lz_options));
+
+ // Setup the size information into next->coder->mf and deallocate
+ // old buffers if they have wrong size.
+ if (lz_encoder_prepare(&next->coder->mf, allocator, &lz_options))
+ return LZMA_OPTIONS_ERROR;
+
+ // Allocate new buffers if needed, and do the rest of
+ // the initialization.
+ if (lz_encoder_init(&next->coder->mf, allocator, &lz_options))
+ return LZMA_MEM_ERROR;
+
+ // Initialize the next filter in the chain, if any.
+ return lzma_next_filter_init(&next->coder->next, allocator,
+ filters + 1);
+}
+
+
+extern LZMA_API(lzma_bool)
+lzma_mf_is_supported(lzma_match_finder mf)
+{
+ bool ret = false;
+
+#ifdef HAVE_MF_HC3
+ if (mf == LZMA_MF_HC3)
+ ret = true;
+#endif
+
+#ifdef HAVE_MF_HC4
+ if (mf == LZMA_MF_HC4)
+ ret = true;
+#endif
+
+#ifdef HAVE_MF_BT2
+ if (mf == LZMA_MF_BT2)
+ ret = true;
+#endif
+
+#ifdef HAVE_MF_BT3
+ if (mf == LZMA_MF_BT3)
+ ret = true;
+#endif
+
+#ifdef HAVE_MF_BT4
+ if (mf == LZMA_MF_BT4)
+ ret = true;
+#endif
+
+ return ret;
+}
diff --git a/Utilities/cmliblzma/liblzma/lz/lz_encoder.h b/Utilities/cmliblzma/liblzma/lz/lz_encoder.h
new file mode 100644
index 000000000..dcb4b2c5b
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/lz/lz_encoder.h
@@ -0,0 +1,328 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file lz_encoder.h
+/// \brief LZ in window and match finder API
+///
+// Authors: Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_LZ_ENCODER_H
+#define LZMA_LZ_ENCODER_H
+
+#include "common.h"
+
+
+/// A table of these is used by the LZ-based encoder to hold
+/// the length-distance pairs found by the match finder.
+typedef struct {
+ uint32_t len;
+ uint32_t dist;
+} lzma_match;
+
+
+typedef struct lzma_mf_s lzma_mf;
+struct lzma_mf_s {
+ ///////////////
+ // In Window //
+ ///////////////
+
+ /// Pointer to buffer with data to be compressed
+ uint8_t *buffer;
+
+ /// Total size of the allocated buffer (that is, including all
+ /// the extra space)
+ uint32_t size;
+
+ /// Number of bytes that must be kept available in our input history.
+ /// That is, once keep_size_before bytes have been processed,
+ /// buffer[read_pos - keep_size_before] is the oldest byte that
+ /// must be available for reading.
+ uint32_t keep_size_before;
+
+ /// Number of bytes that must be kept in buffer after read_pos.
+ /// That is, read_pos <= write_pos - keep_size_after as long as
+ /// action is LZMA_RUN; when action != LZMA_RUN, read_pos is allowed
+ /// to reach write_pos so that the last bytes get encoded too.
+ uint32_t keep_size_after;
+
+ /// Match finders store locations of matches using 32-bit integers.
+ /// To avoid adjusting several megabytes of integers every time the
+ /// input window is moved with move_window, we only adjust the
+ /// offset of the buffer. Thus, buffer[value_in_hash_table - offset]
+ /// is the byte pointed by value_in_hash_table.
+ uint32_t offset;
+
+ /// buffer[read_pos] is the next byte to run through the match
+ /// finder. This is incremented in the match finder once the byte
+ /// has been processed.
+ uint32_t read_pos;
+
+ /// Number of bytes that have been ran through the match finder, but
+ /// which haven't been encoded by the LZ-based encoder yet.
+ uint32_t read_ahead;
+
+ /// As long as read_pos is less than read_limit, there is enough
+ /// input available in buffer for at least one encoding loop.
+ ///
+ /// Because of the stateful API, read_limit may and will get greater
+ /// than read_pos quite often. This is taken into account when
+ /// calculating the value for keep_size_after.
+ uint32_t read_limit;
+
+ /// buffer[write_pos] is the first byte that doesn't contain valid
+ /// uncompressed data; that is, the next input byte will be copied
+ /// to buffer[write_pos].
+ uint32_t write_pos;
+
+ /// Number of bytes not hashed before read_pos. This is needed to
+ /// restart the match finder after LZMA_SYNC_FLUSH.
+ uint32_t pending;
+
+ //////////////////
+ // Match Finder //
+ //////////////////
+
+ /// Find matches. Returns the number of distance-length pairs written
+ /// to the matches array. This is called only via lzma_mf_find().
+ uint32_t (*find)(lzma_mf *mf, lzma_match *matches);
+
+ /// Skips num bytes. This is like find() but doesn't make the
+ /// distance-length pairs available, thus being a little faster.
+ /// This is called only via mf_skip().
+ void (*skip)(lzma_mf *mf, uint32_t num);
+
+ uint32_t *hash;
+ uint32_t *son;
+ uint32_t cyclic_pos;
+ uint32_t cyclic_size; // Must be dictionary size + 1.
+ uint32_t hash_mask;
+
+ /// Maximum number of loops in the match finder
+ uint32_t depth;
+
+ /// Maximum length of a match that the match finder will try to find.
+ uint32_t nice_len;
+
+ /// Maximum length of a match supported by the LZ-based encoder.
+ /// If the longest match found by the match finder is nice_len,
+ /// mf_find() tries to expand it up to match_len_max bytes.
+ uint32_t match_len_max;
+
+ /// When running out of input, binary tree match finders need to know
+ /// if it is due to flushing or finishing. The action is used also
+ /// by the LZ-based encoders themselves.
+ lzma_action action;
+
+ /// Number of elements in hash[]
+ uint32_t hash_size_sum;
+
+ /// Number of elements in son[]
+ uint32_t sons_count;
+};
+
+
+typedef struct {
+ /// Extra amount of data to keep available before the "actual"
+ /// dictionary.
+ size_t before_size;
+
+ /// Size of the history buffer
+ size_t dict_size;
+
+ /// Extra amount of data to keep available after the "actual"
+ /// dictionary.
+ size_t after_size;
+
+ /// Maximum length of a match that the LZ-based encoder can accept.
+ /// This is used to extend matches of length nice_len to the
+ /// maximum possible length.
+ size_t match_len_max;
+
+ /// Match finder will search matches up to this length.
+ /// This must be less than or equal to match_len_max.
+ size_t nice_len;
+
+ /// Type of the match finder to use
+ lzma_match_finder match_finder;
+
+ /// Maximum search depth
+ uint32_t depth;
+
+ /// TODO: Comment
+ const uint8_t *preset_dict;
+
+ uint32_t preset_dict_size;
+
+} lzma_lz_options;
+
+
+// The total usable buffer space at any moment outside the match finder:
+// before_size + dict_size + after_size + match_len_max
+//
+// In reality, there's some extra space allocated to prevent the number of
+// memmove() calls reasonable. The bigger the dict_size is, the bigger
+// this extra buffer will be since with bigger dictionaries memmove() would
+// also take longer.
+//
+// A single encoder loop in the LZ-based encoder may call the match finder
+// (mf_find() or mf_skip()) at most after_size times. In other words,
+// a single encoder loop may increment lzma_mf.read_pos at most after_size
+// times. Since matches are looked up to
+// lzma_mf.buffer[lzma_mf.read_pos + match_len_max - 1], the total
+// amount of extra buffer needed after dict_size becomes
+// after_size + match_len_max.
+//
+// before_size has two uses. The first one is to keep literals available
+// in cases when the LZ-based encoder has made some read ahead.
+// TODO: Maybe this could be changed by making the LZ-based encoders to
+// store the actual literals as they do with length-distance pairs.
+//
+// Algorithms such as LZMA2 first try to compress a chunk, and then check
+// if the encoded result is smaller than the uncompressed one. If the chunk
+// was uncompressible, it is better to store it in uncompressed form in
+// the output stream. To do this, the whole uncompressed chunk has to be
+// still available in the history buffer. before_size achieves that.
+
+
+typedef struct {
+ /// Data specific to the LZ-based encoder
+ lzma_coder *coder;
+
+ /// Function to encode from *dict to out[]
+ lzma_ret (*code)(lzma_coder *LZMA_RESTRICT coder,
+ lzma_mf *LZMA_RESTRICT mf, uint8_t *LZMA_RESTRICT out,
+ size_t *LZMA_RESTRICT out_pos, size_t out_size);
+
+ /// Free allocated resources
+ void (*end)(lzma_coder *coder, lzma_allocator *allocator);
+
+ /// Update the options in the middle of the encoding.
+ lzma_ret (*options_update)(lzma_coder *coder,
+ const lzma_filter *filter);
+
+} lzma_lz_encoder;
+
+
+// Basic steps:
+// 1. Input gets copied into the dictionary.
+// 2. Data in dictionary gets run through the match finder byte by byte.
+// 3. The literals and matches are encoded using e.g. LZMA.
+//
+// The bytes that have been ran through the match finder, but not encoded yet,
+// are called `read ahead'.
+
+
+/// Get pointer to the first byte not ran through the match finder
+static inline uint8_t *
+mf_ptr(const lzma_mf *mf)
+{
+ return mf->buffer + mf->read_pos;
+}
+
+
+/// Get the number of bytes that haven't been ran through the match finder yet.
+static inline uint32_t
+mf_avail(const lzma_mf *mf)
+{
+ return mf->write_pos - mf->read_pos;
+}
+
+
+/// Get the number of bytes that haven't been encoded yet (some of these
+/// bytes may have been ran through the match finder though).
+static inline uint32_t
+mf_unencoded(const lzma_mf *mf)
+{
+ return mf->write_pos - mf->read_pos + mf->read_ahead;
+}
+
+
+/// Calculate the absolute offset from the beginning of the most recent
+/// dictionary reset. Only the lowest four bits are important, so there's no
+/// problem that we don't know the 64-bit size of the data encoded so far.
+///
+/// NOTE: When moving the input window, we need to do it so that the lowest
+/// bits of dict->read_pos are not modified to keep this macro working
+/// as intended.
+static inline uint32_t
+mf_position(const lzma_mf *mf)
+{
+ return mf->read_pos - mf->read_ahead;
+}
+
+
+/// Since everything else begins with mf_, use it also for lzma_mf_find().
+#define mf_find lzma_mf_find
+
+
+/// Skip the given number of bytes. This is used when a good match was found.
+/// For example, if mf_find() finds a match of 200 bytes long, the first byte
+/// of that match was already consumed by mf_find(), and the rest 199 bytes
+/// have to be skipped with mf_skip(mf, 199).
+static inline void
+mf_skip(lzma_mf *mf, uint32_t amount)
+{
+ if (amount != 0) {
+ mf->skip(mf, amount);
+ mf->read_ahead += amount;
+ }
+}
+
+
+/// Copies at most *left number of bytes from the history buffer
+/// to out[]. This is needed by LZMA2 to encode uncompressed chunks.
+static inline void
+mf_read(lzma_mf *mf, uint8_t *out, size_t *out_pos, size_t out_size,
+ size_t *left)
+{
+ const size_t out_avail = out_size - *out_pos;
+ const size_t copy_size = my_min(out_avail, *left);
+
+ assert(mf->read_ahead == 0);
+ assert(mf->read_pos >= *left);
+
+ memcpy(out + *out_pos, mf->buffer + mf->read_pos - *left,
+ copy_size);
+
+ *out_pos += copy_size;
+ *left -= copy_size;
+ return;
+}
+
+
+extern lzma_ret lzma_lz_encoder_init(
+ lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter_info *filters,
+ lzma_ret (*lz_init)(lzma_lz_encoder *lz,
+ lzma_allocator *allocator, const void *options,
+ lzma_lz_options *lz_options));
+
+
+extern uint64_t lzma_lz_encoder_memusage(const lzma_lz_options *lz_options);
+
+
+// These are only for LZ encoder's internal use.
+extern uint32_t lzma_mf_find(
+ lzma_mf *mf, uint32_t *count, lzma_match *matches);
+
+extern uint32_t lzma_mf_hc3_find(lzma_mf *dict, lzma_match *matches);
+extern void lzma_mf_hc3_skip(lzma_mf *dict, uint32_t amount);
+
+extern uint32_t lzma_mf_hc4_find(lzma_mf *dict, lzma_match *matches);
+extern void lzma_mf_hc4_skip(lzma_mf *dict, uint32_t amount);
+
+extern uint32_t lzma_mf_bt2_find(lzma_mf *dict, lzma_match *matches);
+extern void lzma_mf_bt2_skip(lzma_mf *dict, uint32_t amount);
+
+extern uint32_t lzma_mf_bt3_find(lzma_mf *dict, lzma_match *matches);
+extern void lzma_mf_bt3_skip(lzma_mf *dict, uint32_t amount);
+
+extern uint32_t lzma_mf_bt4_find(lzma_mf *dict, lzma_match *matches);
+extern void lzma_mf_bt4_skip(lzma_mf *dict, uint32_t amount);
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/lz/lz_encoder_hash.h b/Utilities/cmliblzma/liblzma/lz/lz_encoder_hash.h
new file mode 100644
index 000000000..de17c54fc
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/lz/lz_encoder_hash.h
@@ -0,0 +1,105 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file lz_encoder_hash.h
+/// \brief Hash macros for match finders
+//
+// Author: Igor Pavlov
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_LZ_ENCODER_HASH_H
+#define LZMA_LZ_ENCODER_HASH_H
+
+#if defined(WORDS_BIGENDIAN) && !defined(HAVE_SMALL)
+ // This is to make liblzma produce the same output on big endian
+ // systems that it does on little endian systems. lz_encoder.c
+ // takes care of including the actual table.
+ extern const uint32_t lzma_lz_hash_table[256];
+# define hash_table lzma_lz_hash_table
+#else
+# include "check.h"
+# define hash_table lzma_crc32_table[0]
+#endif
+
+#define HASH_2_SIZE (UINT32_C(1) << 10)
+#define HASH_3_SIZE (UINT32_C(1) << 16)
+#define HASH_4_SIZE (UINT32_C(1) << 20)
+
+#define HASH_2_MASK (HASH_2_SIZE - 1)
+#define HASH_3_MASK (HASH_3_SIZE - 1)
+#define HASH_4_MASK (HASH_4_SIZE - 1)
+
+#define FIX_3_HASH_SIZE (HASH_2_SIZE)
+#define FIX_4_HASH_SIZE (HASH_2_SIZE + HASH_3_SIZE)
+#define FIX_5_HASH_SIZE (HASH_2_SIZE + HASH_3_SIZE + HASH_4_SIZE)
+
+// Endianness doesn't matter in hash_2_calc() (no effect on the output).
+#ifdef TUKLIB_FAST_UNALIGNED_ACCESS
+# define hash_2_calc() \
+ hash_value = *(const uint16_t *)(cur)
+#else
+# define hash_2_calc() \
+ hash_value = (uint32_t)(cur[0]) | ((uint32_t)(cur[1]) << 8)
+#endif
+
+#define hash_3_calc() \
+ temp = hash_table[cur[0]] ^ cur[1]; \
+ hash_2_value = temp & HASH_2_MASK; \
+ hash_value = (temp ^ ((uint32_t)(cur[2]) << 8)) & mf->hash_mask
+
+#define hash_4_calc() \
+ temp = hash_table[cur[0]] ^ cur[1]; \
+ hash_2_value = temp & HASH_2_MASK; \
+ hash_3_value = (temp ^ ((uint32_t)(cur[2]) << 8)) & HASH_3_MASK; \
+ hash_value = (temp ^ ((uint32_t)(cur[2]) << 8) \
+ ^ (hash_table[cur[3]] << 5)) & mf->hash_mask
+
+
+// The following are not currently used.
+
+#define hash_5_calc() \
+ const uint32_t temp = hash_table[cur[0]] ^ cur[1]; \
+ const uint32_t hash_2_value = temp & HASH_2_MASK; \
+ const uint32_t hash_3_value \
+ = (temp ^ ((uint32_t)(cur[2]) << 8)) & HASH_3_MASK; \
+ uint32_t hash_4_value = (temp ^ ((uint32_t)(cur[2]) << 8) ^ \
+ ^ hash_table[cur[3]] << 5); \
+ const uint32_t hash_value \
+ = (hash_4_value ^ (hash_table[cur[4]] << 3)) \
+ & mf->hash_mask; \
+ hash_4_value &= HASH_4_MASK
+
+/*
+#define hash_zip_calc() \
+ const uint32_t hash_value \
+ = (((uint32_t)(cur[0]) | ((uint32_t)(cur[1]) << 8)) \
+ ^ hash_table[cur[2]]) & 0xFFFF
+*/
+
+#define hash_zip_calc() \
+ const uint32_t hash_value \
+ = (((uint32_t)(cur[2]) | ((uint32_t)(cur[0]) << 8)) \
+ ^ hash_table[cur[1]]) & 0xFFFF
+
+#define mt_hash_2_calc() \
+ const uint32_t hash_2_value \
+ = (hash_table[cur[0]] ^ cur[1]) & HASH_2_MASK
+
+#define mt_hash_3_calc() \
+ const uint32_t temp = hash_table[cur[0]] ^ cur[1]; \
+ const uint32_t hash_2_value = temp & HASH_2_MASK; \
+ const uint32_t hash_3_value \
+ = (temp ^ ((uint32_t)(cur[2]) << 8)) & HASH_3_MASK
+
+#define mt_hash_4_calc() \
+ const uint32_t temp = hash_table[cur[0]] ^ cur[1]; \
+ const uint32_t hash_2_value = temp & HASH_2_MASK; \
+ const uint32_t hash_3_value \
+ = (temp ^ ((uint32_t)(cur[2]) << 8)) & HASH_3_MASK; \
+ const uint32_t hash_4_value = (temp ^ ((uint32_t)(cur[2]) << 8) ^ \
+ (hash_table[cur[3]] << 5)) & HASH_4_MASK
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/lz/lz_encoder_hash_table.h b/Utilities/cmliblzma/liblzma/lz/lz_encoder_hash_table.h
new file mode 100644
index 000000000..8c51717d7
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/lz/lz_encoder_hash_table.h
@@ -0,0 +1,68 @@
+/* This file has been automatically generated by crc32_tablegen.c. */
+
+const uint32_t lzma_lz_hash_table[256] = {
+ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
+ 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
+ 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
+ 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
+ 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
+ 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
+ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
+ 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
+ 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
+ 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
+ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
+ 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
+ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
+ 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
+ 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
+ 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
+ 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
+ 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
+ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
+ 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
+ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
+ 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
+ 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
+ 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
+ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
+ 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
+ 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
+ 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
+ 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
+ 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
+ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
+ 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
+ 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
+ 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
+ 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
+ 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
+ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
+ 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
+ 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
+ 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
+ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
+ 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
+ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
+ 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
+ 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
+ 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
+ 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
+ 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
+ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
+ 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
+ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
+ 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
+ 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
+ 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
+ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
+ 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
+ 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
+ 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
+ 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
+ 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
+ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
+ 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
+ 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
+ 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
+};
diff --git a/Utilities/cmliblzma/liblzma/lz/lz_encoder_mf.c b/Utilities/cmliblzma/liblzma/lz/lz_encoder_mf.c
new file mode 100644
index 000000000..50c3459aa
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/lz/lz_encoder_mf.c
@@ -0,0 +1,814 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file lz_encoder_mf.c
+/// \brief Match finders
+///
+// Authors: Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "lz_encoder.h"
+#include "lz_encoder_hash.h"
+
+
+/// \brief Find matches starting from the current byte
+///
+/// \return The length of the longest match found
+extern uint32_t
+lzma_mf_find(lzma_mf *mf, uint32_t *count_ptr, lzma_match *matches)
+{
+ // Call the match finder. It returns the number of length-distance
+ // pairs found.
+ // FIXME: Minimum count is zero, what _exactly_ is the maximum?
+ const uint32_t count = mf->find(mf, matches);
+
+ // Length of the longest match; assume that no matches were found
+ // and thus the maximum length is zero.
+ uint32_t len_best = 0;
+
+ if (count > 0) {
+#ifndef NDEBUG
+ uint32_t i;
+ // Validate the matches.
+ for (i = 0; i < count; ++i) {
+ assert(matches[i].len <= mf->nice_len);
+ assert(matches[i].dist < mf->read_pos);
+ assert(memcmp(mf_ptr(mf) - 1,
+ mf_ptr(mf) - matches[i].dist - 2,
+ matches[i].len) == 0);
+ }
+#endif
+
+ // The last used element in the array contains
+ // the longest match.
+ len_best = matches[count - 1].len;
+
+ // If a match of maximum search length was found, try to
+ // extend the match to maximum possible length.
+ if (len_best == mf->nice_len) {
+ uint8_t *p1;
+ uint8_t *p2;
+
+ // The limit for the match length is either the
+ // maximum match length supported by the LZ-based
+ // encoder or the number of bytes left in the
+ // dictionary, whichever is smaller.
+ uint32_t limit = mf_avail(mf) + 1;
+ if (limit > mf->match_len_max)
+ limit = mf->match_len_max;
+
+ // Pointer to the byte we just ran through
+ // the match finder.
+ p1 = mf_ptr(mf) - 1;
+
+ // Pointer to the beginning of the match. We need -1
+ // here because the match distances are zero based.
+ p2 = p1 - matches[count - 1].dist - 1;
+
+ while (len_best < limit
+ && p1[len_best] == p2[len_best])
+ ++len_best;
+ }
+ }
+
+ *count_ptr = count;
+
+ // Finally update the read position to indicate that match finder was
+ // run for this dictionary offset.
+ ++mf->read_ahead;
+
+ return len_best;
+}
+
+
+/// Hash value to indicate unused element in the hash. Since we start the
+/// positions from dict_size + 1, zero is always too far to qualify
+/// as usable match position.
+#define EMPTY_HASH_VALUE 0
+
+
+/// Normalization must be done when lzma_mf.offset + lzma_mf.read_pos
+/// reaches MUST_NORMALIZE_POS.
+#define MUST_NORMALIZE_POS UINT32_MAX
+
+
+/// \brief Normalizes hash values
+///
+/// The hash arrays store positions of match candidates. The positions are
+/// relative to an arbitrary offset that is not the same as the absolute
+/// offset in the input stream. The relative position of the current byte
+/// is lzma_mf.offset + lzma_mf.read_pos. The distances of the matches are
+/// the differences of the current read position and the position found from
+/// the hash.
+///
+/// To prevent integer overflows of the offsets stored in the hash arrays,
+/// we need to "normalize" the stored values now and then. During the
+/// normalization, we drop values that indicate distance greater than the
+/// dictionary size, thus making space for new values.
+static void
+normalize(lzma_mf *mf)
+{
+ uint32_t i;
+ uint32_t subvalue;
+ uint32_t count;
+ uint32_t *hash;
+
+ assert(mf->read_pos + mf->offset == MUST_NORMALIZE_POS);
+
+ // In future we may not want to touch the lowest bits, because there
+ // may be match finders that use larger resolution than one byte.
+ subvalue = (MUST_NORMALIZE_POS - mf->cyclic_size);
+ // & (~(UINT32_C(1) << 10) - 1);
+
+ count = mf->hash_size_sum + mf->sons_count;
+ hash = mf->hash;
+
+ for (i = 0; i < count; ++i) {
+ // If the distance is greater than the dictionary size,
+ // we can simply mark the hash element as empty.
+ //
+ // NOTE: Only the first mf->hash_size_sum elements are
+ // initialized for sure. There may be uninitialized elements
+ // in mf->son. Since we go through both mf->hash and
+ // mf->son here in normalization, Valgrind may complain
+ // that the "if" below depends on uninitialized value. In
+ // this case it is safe to ignore the warning. See also the
+ // comments in lz_encoder_init() in lz_encoder.c.
+ if (hash[i] <= subvalue)
+ hash[i] = EMPTY_HASH_VALUE;
+ else
+ hash[i] -= subvalue;
+ }
+
+ // Update offset to match the new locations.
+ mf->offset -= subvalue;
+
+ return;
+}
+
+
+/// Mark the current byte as processed from point of view of the match finder.
+static void
+move_pos(lzma_mf *mf)
+{
+ if (++mf->cyclic_pos == mf->cyclic_size)
+ mf->cyclic_pos = 0;
+
+ ++mf->read_pos;
+ assert(mf->read_pos <= mf->write_pos);
+
+ if (unlikely(mf->read_pos + mf->offset == UINT32_MAX))
+ normalize(mf);
+}
+
+
+/// When flushing, we cannot run the match finder unless there is nice_len
+/// bytes available in the dictionary. Instead, we skip running the match
+/// finder (indicating that no match was found), and count how many bytes we
+/// have ignored this way.
+///
+/// When new data is given after the flushing was completed, the match finder
+/// is restarted by rewinding mf->read_pos backwards by mf->pending. Then
+/// the missed bytes are added to the hash using the match finder's skip
+/// function (with small amount of input, it may start using mf->pending
+/// again if flushing).
+///
+/// Due to this rewinding, we don't touch cyclic_pos or test for
+/// normalization. It will be done when the match finder's skip function
+/// catches up after a flush.
+static void
+move_pending(lzma_mf *mf)
+{
+ ++mf->read_pos;
+ assert(mf->read_pos <= mf->write_pos);
+ ++mf->pending;
+}
+
+
+/// Calculate len_limit and determine if there is enough input to run
+/// the actual match finder code. Sets up "cur" and "pos". This macro
+/// is used by all find functions and binary tree skip functions. Hash
+/// chain skip function doesn't need len_limit so a simpler code is used
+/// in them.
+#define header(is_bt, len_min, ret_op) \
+ uint32_t len_limit = mf_avail(mf); \
+ if (mf->nice_len <= len_limit) { \
+ len_limit = mf->nice_len; \
+ } else if (len_limit < (len_min) \
+ || (is_bt && mf->action == LZMA_SYNC_FLUSH)) { \
+ assert(mf->action != LZMA_RUN); \
+ move_pending(mf); \
+ ret_op; \
+ } \
+ cur = mf_ptr(mf); \
+ pos = mf->read_pos + mf->offset
+
+
+/// Header for find functions. "return 0" indicates that zero matches
+/// were found.
+#define header_find(is_bt, len_min) \
+ header(is_bt, len_min, return 0)
+
+
+/// Header for a loop in a skip function. "continue" tells to skip the rest
+/// of the code in the loop.
+#define header_skip(is_bt, len_min) \
+ header(is_bt, len_min, continue)
+
+
+/// Calls hc_find_func() or bt_find_func() and calculates the total number
+/// of matches found. Updates the dictionary position and returns the number
+/// of matches found.
+#define call_find(func, len_best) \
+do { \
+ matches_count = func(len_limit, pos, cur, cur_match, mf->depth, \
+ mf->son, mf->cyclic_pos, mf->cyclic_size, \
+ matches + matches_count, len_best) \
+ - matches; \
+ move_pos(mf); \
+ return matches_count; \
+} while (0)
+
+
+////////////////
+// Hash Chain //
+////////////////
+
+#if defined(HAVE_MF_HC3) || defined(HAVE_MF_HC4)
+///
+///
+/// \param len_limit Don't look for matches longer than len_limit.
+/// \param pos lzma_mf.read_pos + lzma_mf.offset
+/// \param cur Pointer to current byte (mf_ptr(mf))
+/// \param cur_match Start position of the current match candidate
+/// \param depth Maximum length of the hash chain
+/// \param son lzma_mf.son (contains the hash chain)
+/// \param cyclic_pos
+/// \param cyclic_size
+/// \param matches Array to hold the matches.
+/// \param len_best The length of the longest match found so far.
+static lzma_match *
+hc_find_func(
+ const uint32_t len_limit,
+ const uint32_t pos,
+ const uint8_t *const cur,
+ uint32_t cur_match,
+ uint32_t depth,
+ uint32_t *const son,
+ const uint32_t cyclic_pos,
+ const uint32_t cyclic_size,
+ lzma_match *matches,
+ uint32_t len_best)
+{
+ son[cyclic_pos] = cur_match;
+
+ while (true) {
+ const uint32_t delta = pos - cur_match;
+ const uint8_t *pb;
+ if (depth-- == 0 || delta >= cyclic_size)
+ return matches;
+
+ pb = cur - delta;
+ cur_match = son[cyclic_pos - delta
+ + (delta > cyclic_pos ? cyclic_size : 0)];
+
+ if (pb[len_best] == cur[len_best] && pb[0] == cur[0]) {
+ uint32_t len = 0;
+ while (++len != len_limit)
+ if (pb[len] != cur[len])
+ break;
+
+ if (len_best < len) {
+ len_best = len;
+ matches->len = len;
+ matches->dist = delta - 1;
+ ++matches;
+
+ if (len == len_limit)
+ return matches;
+ }
+ }
+ }
+}
+
+
+#define hc_find(len_best) \
+ call_find(hc_find_func, len_best)
+
+
+#define hc_skip() \
+do { \
+ mf->son[mf->cyclic_pos] = cur_match; \
+ move_pos(mf); \
+} while (0)
+
+#endif
+
+
+#ifdef HAVE_MF_HC3
+extern uint32_t
+lzma_mf_hc3_find(lzma_mf *mf, lzma_match *matches)
+{
+ const uint8_t *cur;
+ uint32_t pos;
+ uint32_t temp, hash_value, hash_2_value; /* hash_3_calc */
+ uint32_t delta2, cur_match;
+ uint32_t len_best = 2;
+ uint32_t matches_count = 0;
+
+ header_find(false, 3);
+
+ hash_3_calc();
+
+ delta2 = pos - mf->hash[hash_2_value];
+ cur_match = mf->hash[FIX_3_HASH_SIZE + hash_value];
+
+ mf->hash[hash_2_value] = pos;
+ mf->hash[FIX_3_HASH_SIZE + hash_value] = pos;
+
+ if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) {
+ for ( ; len_best != len_limit; ++len_best)
+ if (*(cur + len_best - delta2) != cur[len_best])
+ break;
+
+ matches[0].len = len_best;
+ matches[0].dist = delta2 - 1;
+ matches_count = 1;
+
+ if (len_best == len_limit) {
+ hc_skip();
+ return 1; // matches_count
+ }
+ }
+
+ hc_find(len_best);
+}
+
+
+extern void
+lzma_mf_hc3_skip(lzma_mf *mf, uint32_t amount)
+{
+ do {
+ const uint8_t *cur;
+ uint32_t pos;
+ uint32_t temp, hash_value, hash_2_value; /* hash_3_calc */
+ uint32_t cur_match;
+
+ if (mf_avail(mf) < 3) {
+ move_pending(mf);
+ continue;
+ }
+
+ cur = mf_ptr(mf);
+ pos = mf->read_pos + mf->offset;
+
+ hash_3_calc();
+
+ cur_match = mf->hash[FIX_3_HASH_SIZE + hash_value];
+
+ mf->hash[hash_2_value] = pos;
+ mf->hash[FIX_3_HASH_SIZE + hash_value] = pos;
+
+ hc_skip();
+
+ } while (--amount != 0);
+}
+#endif
+
+
+#ifdef HAVE_MF_HC4
+extern uint32_t
+lzma_mf_hc4_find(lzma_mf *mf, lzma_match *matches)
+{
+ const uint8_t *cur;
+ uint32_t pos;
+ uint32_t temp, hash_value, hash_2_value, hash_3_value; /* hash_4_calc */
+ uint32_t delta2, delta3, cur_match;
+ uint32_t len_best = 1;
+ uint32_t matches_count = 0;
+
+ header_find(false, 4);
+
+ hash_4_calc();
+
+ delta2 = pos - mf->hash[hash_2_value];
+ delta3 = pos - mf->hash[FIX_3_HASH_SIZE + hash_3_value];
+ cur_match = mf->hash[FIX_4_HASH_SIZE + hash_value];
+
+ mf->hash[hash_2_value ] = pos;
+ mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos;
+ mf->hash[FIX_4_HASH_SIZE + hash_value] = pos;
+
+ if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) {
+ len_best = 2;
+ matches[0].len = 2;
+ matches[0].dist = delta2 - 1;
+ matches_count = 1;
+ }
+
+ if (delta2 != delta3 && delta3 < mf->cyclic_size
+ && *(cur - delta3) == *cur) {
+ len_best = 3;
+ matches[matches_count++].dist = delta3 - 1;
+ delta2 = delta3;
+ }
+
+ if (matches_count != 0) {
+ for ( ; len_best != len_limit; ++len_best)
+ if (*(cur + len_best - delta2) != cur[len_best])
+ break;
+
+ matches[matches_count - 1].len = len_best;
+
+ if (len_best == len_limit) {
+ hc_skip();
+ return matches_count;
+ }
+ }
+
+ if (len_best < 3)
+ len_best = 3;
+
+ hc_find(len_best);
+}
+
+
+extern void
+lzma_mf_hc4_skip(lzma_mf *mf, uint32_t amount)
+{
+ do {
+ const uint8_t *cur;
+ uint32_t pos;
+ uint32_t temp, hash_value, hash_2_value, hash_3_value; /* hash_4_calc */
+ uint32_t cur_match;
+
+ if (mf_avail(mf) < 4) {
+ move_pending(mf);
+ continue;
+ }
+
+ cur = mf_ptr(mf);
+ pos = mf->read_pos + mf->offset;
+
+ hash_4_calc();
+
+ cur_match = mf->hash[FIX_4_HASH_SIZE + hash_value];
+
+ mf->hash[hash_2_value] = pos;
+ mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos;
+ mf->hash[FIX_4_HASH_SIZE + hash_value] = pos;
+
+ hc_skip();
+
+ } while (--amount != 0);
+}
+#endif
+
+
+/////////////////
+// Binary Tree //
+/////////////////
+
+#if defined(HAVE_MF_BT2) || defined(HAVE_MF_BT3) || defined(HAVE_MF_BT4)
+static lzma_match *
+bt_find_func(
+ const uint32_t len_limit,
+ const uint32_t pos,
+ const uint8_t *const cur,
+ uint32_t cur_match,
+ uint32_t depth,
+ uint32_t *const son,
+ const uint32_t cyclic_pos,
+ const uint32_t cyclic_size,
+ lzma_match *matches,
+ uint32_t len_best)
+{
+ uint32_t *ptr0 = son + (cyclic_pos << 1) + 1;
+ uint32_t *ptr1 = son + (cyclic_pos << 1);
+
+ uint32_t len0 = 0;
+ uint32_t len1 = 0;
+
+ while (true) {
+ uint32_t *pair;
+ const uint8_t *pb;
+ uint32_t len;
+
+ const uint32_t delta = pos - cur_match;
+ if (depth-- == 0 || delta >= cyclic_size) {
+ *ptr0 = EMPTY_HASH_VALUE;
+ *ptr1 = EMPTY_HASH_VALUE;
+ return matches;
+ }
+
+ pair = son + ((cyclic_pos - delta
+ + (delta > cyclic_pos ? cyclic_size : 0))
+ << 1);
+
+ pb = cur - delta;
+ len = my_min(len0, len1);
+
+ if (pb[len] == cur[len]) {
+ while (++len != len_limit)
+ if (pb[len] != cur[len])
+ break;
+
+ if (len_best < len) {
+ len_best = len;
+ matches->len = len;
+ matches->dist = delta - 1;
+ ++matches;
+
+ if (len == len_limit) {
+ *ptr1 = pair[0];
+ *ptr0 = pair[1];
+ return matches;
+ }
+ }
+ }
+
+ if (pb[len] < cur[len]) {
+ *ptr1 = cur_match;
+ ptr1 = pair + 1;
+ cur_match = *ptr1;
+ len1 = len;
+ } else {
+ *ptr0 = cur_match;
+ ptr0 = pair;
+ cur_match = *ptr0;
+ len0 = len;
+ }
+ }
+}
+
+
+static void
+bt_skip_func(
+ const uint32_t len_limit,
+ const uint32_t pos,
+ const uint8_t *const cur,
+ uint32_t cur_match,
+ uint32_t depth,
+ uint32_t *const son,
+ const uint32_t cyclic_pos,
+ const uint32_t cyclic_size)
+{
+ uint32_t *ptr0 = son + (cyclic_pos << 1) + 1;
+ uint32_t *ptr1 = son + (cyclic_pos << 1);
+
+ uint32_t len0 = 0;
+ uint32_t len1 = 0;
+
+ while (true) {
+ uint32_t *pair;
+ const uint8_t *pb;
+ uint32_t len;
+
+ const uint32_t delta = pos - cur_match;
+ if (depth-- == 0 || delta >= cyclic_size) {
+ *ptr0 = EMPTY_HASH_VALUE;
+ *ptr1 = EMPTY_HASH_VALUE;
+ return;
+ }
+
+ pair = son + ((cyclic_pos - delta
+ + (delta > cyclic_pos ? cyclic_size : 0))
+ << 1);
+ pb = cur - delta;
+ len = my_min(len0, len1);
+
+ if (pb[len] == cur[len]) {
+ while (++len != len_limit)
+ if (pb[len] != cur[len])
+ break;
+
+ if (len == len_limit) {
+ *ptr1 = pair[0];
+ *ptr0 = pair[1];
+ return;
+ }
+ }
+
+ if (pb[len] < cur[len]) {
+ *ptr1 = cur_match;
+ ptr1 = pair + 1;
+ cur_match = *ptr1;
+ len1 = len;
+ } else {
+ *ptr0 = cur_match;
+ ptr0 = pair;
+ cur_match = *ptr0;
+ len0 = len;
+ }
+ }
+}
+
+
+#define bt_find(len_best) \
+ call_find(bt_find_func, len_best)
+
+#define bt_skip() \
+do { \
+ bt_skip_func(len_limit, pos, cur, cur_match, mf->depth, \
+ mf->son, mf->cyclic_pos, \
+ mf->cyclic_size); \
+ move_pos(mf); \
+} while (0)
+
+#endif
+
+
+#ifdef HAVE_MF_BT2
+extern uint32_t
+lzma_mf_bt2_find(lzma_mf *mf, lzma_match *matches)
+{
+ const uint8_t *cur;
+ uint32_t pos;
+ uint32_t hash_value; /* hash_2_calc */
+ uint32_t cur_match;
+ uint32_t matches_count = 0;
+
+ header_find(true, 2);
+
+ hash_2_calc();
+
+ cur_match = mf->hash[hash_value];
+ mf->hash[hash_value] = pos;
+
+ bt_find(1);
+}
+
+
+extern void
+lzma_mf_bt2_skip(lzma_mf *mf, uint32_t amount)
+{
+ do {
+ const uint8_t *cur;
+ uint32_t pos;
+ uint32_t hash_value; /* hash_2_calc */
+ uint32_t cur_match;
+
+ header_skip(true, 2);
+
+ hash_2_calc();
+
+ cur_match = mf->hash[hash_value];
+ mf->hash[hash_value] = pos;
+
+ bt_skip();
+
+ } while (--amount != 0);
+}
+#endif
+
+
+#ifdef HAVE_MF_BT3
+extern uint32_t
+lzma_mf_bt3_find(lzma_mf *mf, lzma_match *matches)
+{
+ const uint8_t *cur;
+ uint32_t pos;
+ uint32_t temp, hash_value, hash_2_value; /* hash_3_calc */
+ uint32_t delta2, cur_match;
+ uint32_t len_best = 2;
+ uint32_t matches_count = 0;
+
+ header_find(true, 3);
+
+ hash_3_calc();
+
+ delta2 = pos - mf->hash[hash_2_value];
+ cur_match = mf->hash[FIX_3_HASH_SIZE + hash_value];
+
+ mf->hash[hash_2_value] = pos;
+ mf->hash[FIX_3_HASH_SIZE + hash_value] = pos;
+
+ if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) {
+ for ( ; len_best != len_limit; ++len_best)
+ if (*(cur + len_best - delta2) != cur[len_best])
+ break;
+
+ matches[0].len = len_best;
+ matches[0].dist = delta2 - 1;
+ matches_count = 1;
+
+ if (len_best == len_limit) {
+ bt_skip();
+ return 1; // matches_count
+ }
+ }
+
+ bt_find(len_best);
+}
+
+
+extern void
+lzma_mf_bt3_skip(lzma_mf *mf, uint32_t amount)
+{
+ do {
+ const uint8_t *cur;
+ uint32_t pos;
+ uint32_t temp, hash_value, hash_2_value; /* hash_3_calc */
+ uint32_t cur_match;
+
+ header_skip(true, 3);
+
+ hash_3_calc();
+
+ cur_match = mf->hash[FIX_3_HASH_SIZE + hash_value];
+
+ mf->hash[hash_2_value] = pos;
+ mf->hash[FIX_3_HASH_SIZE + hash_value] = pos;
+
+ bt_skip();
+
+ } while (--amount != 0);
+}
+#endif
+
+
+#ifdef HAVE_MF_BT4
+extern uint32_t
+lzma_mf_bt4_find(lzma_mf *mf, lzma_match *matches)
+{
+ const uint8_t *cur;
+ uint32_t pos;
+ uint32_t temp, hash_value, hash_2_value, hash_3_value; /* hash_4_calc */
+ uint32_t delta2, delta3, cur_match;
+ uint32_t len_best = 1;
+ uint32_t matches_count = 0;
+
+ header_find(true, 4);
+
+ hash_4_calc();
+
+ delta2 = pos - mf->hash[hash_2_value];
+ delta3 = pos - mf->hash[FIX_3_HASH_SIZE + hash_3_value];
+ cur_match = mf->hash[FIX_4_HASH_SIZE + hash_value];
+
+ mf->hash[hash_2_value] = pos;
+ mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos;
+ mf->hash[FIX_4_HASH_SIZE + hash_value] = pos;
+
+ if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) {
+ len_best = 2;
+ matches[0].len = 2;
+ matches[0].dist = delta2 - 1;
+ matches_count = 1;
+ }
+
+ if (delta2 != delta3 && delta3 < mf->cyclic_size
+ && *(cur - delta3) == *cur) {
+ len_best = 3;
+ matches[matches_count++].dist = delta3 - 1;
+ delta2 = delta3;
+ }
+
+ if (matches_count != 0) {
+ for ( ; len_best != len_limit; ++len_best)
+ if (*(cur + len_best - delta2) != cur[len_best])
+ break;
+
+ matches[matches_count - 1].len = len_best;
+
+ if (len_best == len_limit) {
+ bt_skip();
+ return matches_count;
+ }
+ }
+
+ if (len_best < 3)
+ len_best = 3;
+
+ bt_find(len_best);
+}
+
+
+extern void
+lzma_mf_bt4_skip(lzma_mf *mf, uint32_t amount)
+{
+ do {
+ const uint8_t *cur;
+ uint32_t pos;
+ uint32_t temp, hash_value, hash_2_value, hash_3_value; /* hash_4_calc */
+ uint32_t cur_match;
+
+ header_skip(true, 4);
+
+ hash_4_calc();
+
+ cur_match = mf->hash[FIX_4_HASH_SIZE + hash_value];
+
+ mf->hash[hash_2_value] = pos;
+ mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos;
+ mf->hash[FIX_4_HASH_SIZE + hash_value] = pos;
+
+ bt_skip();
+
+ } while (--amount != 0);
+}
+#endif
diff --git a/Utilities/cmliblzma/liblzma/lzma/fastpos.h b/Utilities/cmliblzma/liblzma/lzma/fastpos.h
new file mode 100644
index 000000000..5a834d68d
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/lzma/fastpos.h
@@ -0,0 +1,142 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file fastpos.h
+/// \brief Kind of two-bit version of bit scan reverse
+///
+// Authors: Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_FASTPOS_H
+#define LZMA_FASTPOS_H
+
+// LZMA encodes match distances (positions) by storing the highest two
+// bits using a six-bit value [0, 63], and then the missing lower bits.
+// Dictionary size is also stored using this encoding in the new .lzma
+// file format header.
+//
+// fastpos.h provides a way to quickly find out the correct six-bit
+// values. The following table gives some examples of this encoding:
+//
+// pos return
+// 0 0
+// 1 1
+// 2 2
+// 3 3
+// 4 4
+// 5 4
+// 6 5
+// 7 5
+// 8 6
+// 11 6
+// 12 7
+// ... ...
+// 15 7
+// 16 8
+// 17 8
+// ... ...
+// 23 8
+// 24 9
+// 25 9
+// ... ...
+//
+//
+// Provided functions or macros
+// ----------------------------
+//
+// get_pos_slot(pos) is the basic version. get_pos_slot_2(pos)
+// assumes that pos >= FULL_DISTANCES, thus the result is at least
+// FULL_DISTANCES_BITS * 2. Using get_pos_slot(pos) instead of
+// get_pos_slot_2(pos) would give the same result, but get_pos_slot_2(pos)
+// should be tiny bit faster due to the assumption being made.
+//
+//
+// Size vs. speed
+// --------------
+//
+// With some CPUs that have fast BSR (bit scan reverse) instruction, the
+// size optimized version is slightly faster than the bigger table based
+// approach. Such CPUs include Intel Pentium Pro, Pentium II, Pentium III
+// and Core 2 (possibly others). AMD K7 seems to have slower BSR, but that
+// would still have speed roughly comparable to the table version. Older
+// x86 CPUs like the original Pentium have very slow BSR; on those systems
+// the table version is a lot faster.
+//
+// On some CPUs, the table version is a lot faster when using position
+// dependent code, but with position independent code the size optimized
+// version is slightly faster. This occurs at least on 32-bit SPARC (no
+// ASM optimizations).
+//
+// I'm making the table version the default, because that has good speed
+// on all systems I have tried. The size optimized version is sometimes
+// slightly faster, but sometimes it is a lot slower.
+
+#include "config.h"
+
+#ifdef HAVE_SMALL
+# define get_pos_slot(pos) ((pos) <= 4 ? (pos) : get_pos_slot_2(pos))
+
+static inline uint32_t
+get_pos_slot_2(uint32_t pos)
+{
+ const uint32_t i = bsr32(pos);
+ return (i + i) + ((pos >> (i - 1)) & 1);
+}
+
+
+#else
+
+#define FASTPOS_BITS 13
+
+extern const uint8_t lzma_fastpos[1 << FASTPOS_BITS];
+
+
+#define fastpos_shift(extra, n) \
+ ((extra) + (n) * (FASTPOS_BITS - 1))
+
+#define fastpos_limit(extra, n) \
+ (UINT32_C(1) << (FASTPOS_BITS + fastpos_shift(extra, n)))
+
+#define fastpos_result(pos, extra, n) \
+ lzma_fastpos[(pos) >> fastpos_shift(extra, n)] \
+ + 2 * fastpos_shift(extra, n)
+
+
+static inline uint32_t
+get_pos_slot(uint32_t pos)
+{
+ // If it is small enough, we can pick the result directly from
+ // the precalculated table.
+ if (pos < fastpos_limit(0, 0))
+ return lzma_fastpos[pos];
+
+ if (pos < fastpos_limit(0, 1))
+ return fastpos_result(pos, 0, 1);
+
+ return fastpos_result(pos, 0, 2);
+}
+
+
+#ifdef FULL_DISTANCES_BITS
+static inline uint32_t
+get_pos_slot_2(uint32_t pos)
+{
+ assert(pos >= FULL_DISTANCES);
+
+ if (pos < fastpos_limit(FULL_DISTANCES_BITS - 1, 0))
+ return fastpos_result(pos, FULL_DISTANCES_BITS - 1, 0);
+
+ if (pos < fastpos_limit(FULL_DISTANCES_BITS - 1, 1))
+ return fastpos_result(pos, FULL_DISTANCES_BITS - 1, 1);
+
+ return fastpos_result(pos, FULL_DISTANCES_BITS - 1, 2);
+}
+#endif
+
+#endif
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/lzma/fastpos_table.c b/Utilities/cmliblzma/liblzma/lzma/fastpos_table.c
new file mode 100644
index 000000000..6a3ceac0e
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/lzma/fastpos_table.c
@@ -0,0 +1,519 @@
+/* This file has been automatically generated by fastpos_tablegen.c. */
+
+#include "common.h"
+#include "fastpos.h"
+
+const uint8_t lzma_fastpos[1 << FASTPOS_BITS] = {
+ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,
+ 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25
+};
diff --git a/Utilities/cmliblzma/liblzma/lzma/fastpos_tablegen.c b/Utilities/cmliblzma/liblzma/lzma/fastpos_tablegen.c
new file mode 100644
index 000000000..c97e6f411
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/lzma/fastpos_tablegen.c
@@ -0,0 +1,56 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file fastpos_tablegen.c
+/// \brief Generates the lzma_fastpos[] lookup table
+///
+// Authors: Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include "fastpos.h"
+
+
+int
+main(void)
+{
+ uint8_t fastpos[1 << FASTPOS_BITS];
+
+ const uint8_t fast_slots = 2 * FASTPOS_BITS;
+ uint32_t c = 2;
+
+ fastpos[0] = 0;
+ fastpos[1] = 1;
+
+ for (uint8_t slot_fast = 2; slot_fast < fast_slots; ++slot_fast) {
+ const uint32_t k = 1 << ((slot_fast >> 1) - 1);
+ for (uint32_t j = 0; j < k; ++j, ++c)
+ fastpos[c] = slot_fast;
+ }
+
+ printf("/* This file has been automatically generated "
+ "by fastpos_tablegen.c. */\n\n"
+ "#include \"common.h\"\n"
+ "#include \"fastpos.h\"\n\n"
+ "const uint8_t lzma_fastpos[1 << FASTPOS_BITS] = {");
+
+ for (size_t i = 0; i < (1 << FASTPOS_BITS); ++i) {
+ if (i % 16 == 0)
+ printf("\n\t");
+
+ printf("%3u", (unsigned int)(fastpos[i]));
+
+ if (i != (1 << FASTPOS_BITS) - 1)
+ printf(",");
+ }
+
+ printf("\n};\n");
+
+ return 0;
+}
diff --git a/Utilities/cmliblzma/liblzma/lzma/lzma2_decoder.c b/Utilities/cmliblzma/liblzma/lzma/lzma2_decoder.c
new file mode 100644
index 000000000..bd2a73782
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/lzma/lzma2_decoder.c
@@ -0,0 +1,305 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file lzma2_decoder.c
+/// \brief LZMA2 decoder
+///
+// Authors: Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "lzma2_decoder.h"
+#include "lz_decoder.h"
+#include "lzma_decoder.h"
+
+
+struct lzma_coder_s {
+ enum sequence {
+ SEQ_CONTROL,
+ SEQ_UNCOMPRESSED_1,
+ SEQ_UNCOMPRESSED_2,
+ SEQ_COMPRESSED_0,
+ SEQ_COMPRESSED_1,
+ SEQ_PROPERTIES,
+ SEQ_LZMA,
+ SEQ_COPY,
+ } sequence;
+
+ /// Sequence after the size fields have been decoded.
+ enum sequence next_sequence;
+
+ /// LZMA decoder
+ lzma_lz_decoder lzma;
+
+ /// Uncompressed size of LZMA chunk
+ size_t uncompressed_size;
+
+ /// Compressed size of the chunk (naturally equals to uncompressed
+ /// size of uncompressed chunk)
+ size_t compressed_size;
+
+ /// True if properties are needed. This is false before the
+ /// first LZMA chunk.
+ bool need_properties;
+
+ /// True if dictionary reset is needed. This is false before the
+ /// first chunk (LZMA or uncompressed).
+ bool need_dictionary_reset;
+
+ lzma_options_lzma options;
+};
+
+
+static lzma_ret
+lzma2_decode(lzma_coder *LZMA_RESTRICT coder, lzma_dict *LZMA_RESTRICT dict,
+ const uint8_t *LZMA_RESTRICT in, size_t *LZMA_RESTRICT in_pos,
+ size_t in_size)
+{
+ // With SEQ_LZMA it is possible that no new input is needed to do
+ // some progress. The rest of the sequences assume that there is
+ // at least one byte of input.
+ while (*in_pos < in_size || coder->sequence == SEQ_LZMA)
+ switch (coder->sequence) {
+ case SEQ_CONTROL: {
+ const uint32_t control = in[*in_pos];
+ ++*in_pos;
+
+ // End marker
+ if (control == 0x00)
+ return LZMA_STREAM_END;
+
+ if (control >= 0xE0 || control == 1) {
+ // Dictionary reset implies that next LZMA chunk has
+ // to set new properties.
+ coder->need_properties = true;
+ coder->need_dictionary_reset = true;
+ } else if (coder->need_dictionary_reset) {
+ return LZMA_DATA_ERROR;
+ }
+
+ if (control >= 0x80) {
+ // LZMA chunk. The highest five bits of the
+ // uncompressed size are taken from the control byte.
+ coder->uncompressed_size = (control & 0x1F) << 16;
+ coder->sequence = SEQ_UNCOMPRESSED_1;
+
+ // See if there are new properties or if we need to
+ // reset the state.
+ if (control >= 0xC0) {
+ // When there are new properties, state reset
+ // is done at SEQ_PROPERTIES.
+ coder->need_properties = false;
+ coder->next_sequence = SEQ_PROPERTIES;
+
+ } else if (coder->need_properties) {
+ return LZMA_DATA_ERROR;
+
+ } else {
+ coder->next_sequence = SEQ_LZMA;
+
+ // If only state reset is wanted with old
+ // properties, do the resetting here for
+ // simplicity.
+ if (control >= 0xA0)
+ coder->lzma.reset(coder->lzma.coder,
+ &coder->options);
+ }
+ } else {
+ // Invalid control values
+ if (control > 2)
+ return LZMA_DATA_ERROR;
+
+ // It's uncompressed chunk
+ coder->sequence = SEQ_COMPRESSED_0;
+ coder->next_sequence = SEQ_COPY;
+ }
+
+ if (coder->need_dictionary_reset) {
+ // Finish the dictionary reset and let the caller
+ // flush the dictionary to the actual output buffer.
+ coder->need_dictionary_reset = false;
+ dict_reset(dict);
+ return LZMA_OK;
+ }
+
+ break;
+ }
+
+ case SEQ_UNCOMPRESSED_1:
+ coder->uncompressed_size += (uint32_t)(in[(*in_pos)++]) << 8;
+ coder->sequence = SEQ_UNCOMPRESSED_2;
+ break;
+
+ case SEQ_UNCOMPRESSED_2:
+ coder->uncompressed_size += in[(*in_pos)++] + 1;
+ coder->sequence = SEQ_COMPRESSED_0;
+ coder->lzma.set_uncompressed(coder->lzma.coder,
+ coder->uncompressed_size);
+ break;
+
+ case SEQ_COMPRESSED_0:
+ coder->compressed_size = (uint32_t)(in[(*in_pos)++]) << 8;
+ coder->sequence = SEQ_COMPRESSED_1;
+ break;
+
+ case SEQ_COMPRESSED_1:
+ coder->compressed_size += in[(*in_pos)++] + 1;
+ coder->sequence = coder->next_sequence;
+ break;
+
+ case SEQ_PROPERTIES:
+ if (lzma_lzma_lclppb_decode(&coder->options, in[(*in_pos)++]))
+ return LZMA_DATA_ERROR;
+
+ coder->lzma.reset(coder->lzma.coder, &coder->options);
+
+ coder->sequence = SEQ_LZMA;
+ break;
+
+ case SEQ_LZMA: {
+ // Store the start offset so that we can update
+ // coder->compressed_size later.
+ const size_t in_start = *in_pos;
+
+ // Decode from in[] to *dict.
+ const lzma_ret ret = coder->lzma.code(coder->lzma.coder,
+ dict, in, in_pos, in_size);
+
+ // Validate and update coder->compressed_size.
+ const size_t in_used = *in_pos - in_start;
+ if (in_used > coder->compressed_size)
+ return LZMA_DATA_ERROR;
+
+ coder->compressed_size -= in_used;
+
+ // Return if we didn't finish the chunk, or an error occurred.
+ if (ret != LZMA_STREAM_END)
+ return ret;
+
+ // The LZMA decoder must have consumed the whole chunk now.
+ // We don't need to worry about uncompressed size since it
+ // is checked by the LZMA decoder.
+ if (coder->compressed_size != 0)
+ return LZMA_DATA_ERROR;
+
+ coder->sequence = SEQ_CONTROL;
+ break;
+ }
+
+ case SEQ_COPY: {
+ // Copy from input to the dictionary as is.
+ dict_write(dict, in, in_pos, in_size, &coder->compressed_size);
+ if (coder->compressed_size != 0)
+ return LZMA_OK;
+
+ coder->sequence = SEQ_CONTROL;
+ break;
+ }
+
+ default:
+ assert(0);
+ return LZMA_PROG_ERROR;
+ }
+
+ return LZMA_OK;
+}
+
+
+static void
+lzma2_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
+{
+ assert(coder->lzma.end == NULL);
+ lzma_free(coder->lzma.coder, allocator);
+
+ lzma_free(coder, allocator);
+
+ return;
+}
+
+
+static lzma_ret
+lzma2_decoder_init(lzma_lz_decoder *lz, lzma_allocator *allocator,
+ const void *opt, lzma_lz_options *lz_options)
+{
+ const lzma_options_lzma *options = opt;
+
+ if (lz->coder == NULL) {
+ lz->coder = lzma_alloc(sizeof(lzma_coder), allocator);
+ if (lz->coder == NULL)
+ return LZMA_MEM_ERROR;
+
+ lz->code = &lzma2_decode;
+ lz->end = &lzma2_decoder_end;
+
+ lz->coder->lzma = LZMA_LZ_DECODER_INIT;
+ }
+
+ lz->coder->sequence = SEQ_CONTROL;
+ lz->coder->need_properties = true;
+ lz->coder->need_dictionary_reset = options->preset_dict == NULL
+ || options->preset_dict_size == 0;
+
+ return lzma_lzma_decoder_create(&lz->coder->lzma,
+ allocator, options, lz_options);
+}
+
+
+extern lzma_ret
+lzma_lzma2_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter_info *filters)
+{
+ // LZMA2 can only be the last filter in the chain. This is enforced
+ // by the raw_decoder initialization.
+ assert(filters[1].init == NULL);
+
+ return lzma_lz_decoder_init(next, allocator, filters,
+ &lzma2_decoder_init);
+}
+
+
+extern uint64_t
+lzma_lzma2_decoder_memusage(const void *options)
+{
+ return sizeof(lzma_coder)
+ + lzma_lzma_decoder_memusage_nocheck(options);
+}
+
+
+extern lzma_ret
+lzma_lzma2_props_decode(void **options, lzma_allocator *allocator,
+ const uint8_t *props, size_t props_size)
+{
+ lzma_options_lzma *opt;
+
+ if (props_size != 1)
+ return LZMA_OPTIONS_ERROR;
+
+ // Check that reserved bits are unset.
+ if (props[0] & 0xC0)
+ return LZMA_OPTIONS_ERROR;
+
+ // Decode the dictionary size.
+ if (props[0] > 40)
+ return LZMA_OPTIONS_ERROR;
+
+ opt = lzma_alloc(sizeof(lzma_options_lzma), allocator);
+ if (opt == NULL)
+ return LZMA_MEM_ERROR;
+
+ if (props[0] == 40) {
+ opt->dict_size = UINT32_MAX;
+ } else {
+ opt->dict_size = 2 | (props[0] & 1);
+ opt->dict_size <<= props[0] / 2 + 11;
+ }
+
+ opt->preset_dict = NULL;
+ opt->preset_dict_size = 0;
+
+ *options = opt;
+
+ return LZMA_OK;
+}
diff --git a/Utilities/cmliblzma/liblzma/lzma/lzma2_decoder.h b/Utilities/cmliblzma/liblzma/lzma/lzma2_decoder.h
new file mode 100644
index 000000000..fac4ac487
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/lzma/lzma2_decoder.h
@@ -0,0 +1,28 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file lzma2_decoder.h
+/// \brief LZMA2 decoder
+///
+// Authors: Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_LZMA2_DECODER_H
+#define LZMA_LZMA2_DECODER_H
+
+#include "common.h"
+
+extern lzma_ret lzma_lzma2_decoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters);
+
+extern uint64_t lzma_lzma2_decoder_memusage(const void *options);
+
+extern lzma_ret lzma_lzma2_props_decode(
+ void **options, lzma_allocator *allocator,
+ const uint8_t *props, size_t props_size);
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/lzma/lzma2_encoder.c b/Utilities/cmliblzma/liblzma/lzma/lzma2_encoder.c
new file mode 100644
index 000000000..a3651a7c6
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/lzma/lzma2_encoder.c
@@ -0,0 +1,399 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file lzma2_encoder.c
+/// \brief LZMA2 encoder
+///
+// Authors: Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "lz_encoder.h"
+#include "lzma_encoder.h"
+#include "fastpos.h"
+#include "lzma2_encoder.h"
+
+
+struct lzma_coder_s {
+ enum {
+ SEQ_INIT,
+ SEQ_LZMA_ENCODE,
+ SEQ_LZMA_COPY,
+ SEQ_UNCOMPRESSED_HEADER,
+ SEQ_UNCOMPRESSED_COPY,
+ } sequence;
+
+ /// LZMA encoder
+ lzma_coder *lzma;
+
+ /// LZMA options currently in use.
+ lzma_options_lzma opt_cur;
+
+ bool need_properties;
+ bool need_state_reset;
+ bool need_dictionary_reset;
+
+ /// Uncompressed size of a chunk
+ size_t uncompressed_size;
+
+ /// Compressed size of a chunk (excluding headers); this is also used
+ /// to indicate the end of buf[] in SEQ_LZMA_COPY.
+ size_t compressed_size;
+
+ /// Read position in buf[]
+ size_t buf_pos;
+
+ /// Buffer to hold the chunk header and LZMA compressed data
+ uint8_t buf[LZMA2_HEADER_MAX + LZMA2_CHUNK_MAX];
+};
+
+
+static void
+lzma2_header_lzma(lzma_coder *coder)
+{
+ size_t pos;
+ size_t size;
+
+ assert(coder->uncompressed_size > 0);
+ assert(coder->uncompressed_size <= LZMA2_UNCOMPRESSED_MAX);
+ assert(coder->compressed_size > 0);
+ assert(coder->compressed_size <= LZMA2_CHUNK_MAX);
+
+ if (coder->need_properties) {
+ pos = 0;
+
+ if (coder->need_dictionary_reset)
+ coder->buf[pos] = 0x80 + (3 << 5);
+ else
+ coder->buf[pos] = 0x80 + (2 << 5);
+ } else {
+ pos = 1;
+
+ if (coder->need_state_reset)
+ coder->buf[pos] = 0x80 + (1 << 5);
+ else
+ coder->buf[pos] = 0x80;
+ }
+
+ // Set the start position for copying.
+ coder->buf_pos = pos;
+
+ // Uncompressed size
+ size = coder->uncompressed_size - 1;
+ coder->buf[pos++] += size >> 16;
+ coder->buf[pos++] = (size >> 8) & 0xFF;
+ coder->buf[pos++] = size & 0xFF;
+
+ // Compressed size
+ size = coder->compressed_size - 1;
+ coder->buf[pos++] = size >> 8;
+ coder->buf[pos++] = size & 0xFF;
+
+ // Properties, if needed
+ if (coder->need_properties)
+ lzma_lzma_lclppb_encode(&coder->opt_cur, coder->buf + pos);
+
+ coder->need_properties = false;
+ coder->need_state_reset = false;
+ coder->need_dictionary_reset = false;
+
+ // The copying code uses coder->compressed_size to indicate the end
+ // of coder->buf[], so we need add the maximum size of the header here.
+ coder->compressed_size += LZMA2_HEADER_MAX;
+
+ return;
+}
+
+
+static void
+lzma2_header_uncompressed(lzma_coder *coder)
+{
+ assert(coder->uncompressed_size > 0);
+ assert(coder->uncompressed_size <= LZMA2_CHUNK_MAX);
+
+ // If this is the first chunk, we need to include dictionary
+ // reset indicator.
+ if (coder->need_dictionary_reset)
+ coder->buf[0] = 1;
+ else
+ coder->buf[0] = 2;
+
+ coder->need_dictionary_reset = false;
+
+ // "Compressed" size
+ coder->buf[1] = (coder->uncompressed_size - 1) >> 8;
+ coder->buf[2] = (coder->uncompressed_size - 1) & 0xFF;
+
+ // Set the start position for copying.
+ coder->buf_pos = 0;
+ return;
+}
+
+
+static lzma_ret
+lzma2_encode(lzma_coder *LZMA_RESTRICT coder, lzma_mf *LZMA_RESTRICT mf,
+ uint8_t *LZMA_RESTRICT out, size_t *LZMA_RESTRICT out_pos,
+ size_t out_size)
+{
+ while (*out_pos < out_size)
+ switch (coder->sequence) {
+ case SEQ_INIT:
+ // If there's no input left and we are flushing or finishing,
+ // don't start a new chunk.
+ if (mf_unencoded(mf) == 0) {
+ // Write end of payload marker if finishing.
+ if (mf->action == LZMA_FINISH)
+ out[(*out_pos)++] = 0;
+
+ return mf->action == LZMA_RUN
+ ? LZMA_OK : LZMA_STREAM_END;
+ }
+
+ if (coder->need_state_reset)
+ return_if_error(lzma_lzma_encoder_reset(
+ coder->lzma, &coder->opt_cur));
+
+ coder->uncompressed_size = 0;
+ coder->compressed_size = 0;
+ coder->sequence = SEQ_LZMA_ENCODE;
+
+ // Fall through
+
+ case SEQ_LZMA_ENCODE: {
+ uint32_t read_start;
+ lzma_ret ret;
+
+ // Calculate how much more uncompressed data this chunk
+ // could accept.
+ const uint32_t left = LZMA2_UNCOMPRESSED_MAX
+ - coder->uncompressed_size;
+ uint32_t limit;
+
+ if (left < mf->match_len_max) {
+ // Must flush immediately since the next LZMA symbol
+ // could make the uncompressed size of the chunk too
+ // big.
+ limit = 0;
+ } else {
+ // Calculate maximum read_limit that is OK from point
+ // of view of LZMA2 chunk size.
+ limit = mf->read_pos - mf->read_ahead
+ + left - mf->match_len_max;
+ }
+
+ // Save the start position so that we can update
+ // coder->uncompressed_size.
+ read_start = mf->read_pos - mf->read_ahead;
+
+ // Call the LZMA encoder until the chunk is finished.
+ ret = lzma_lzma_encode(coder->lzma, mf,
+ coder->buf + LZMA2_HEADER_MAX,
+ &coder->compressed_size,
+ LZMA2_CHUNK_MAX, limit);
+
+ coder->uncompressed_size += mf->read_pos - mf->read_ahead
+ - read_start;
+
+ assert(coder->compressed_size <= LZMA2_CHUNK_MAX);
+ assert(coder->uncompressed_size <= LZMA2_UNCOMPRESSED_MAX);
+
+ if (ret != LZMA_STREAM_END)
+ return LZMA_OK;
+
+ // See if the chunk compressed. If it didn't, we encode it
+ // as uncompressed chunk. This saves a few bytes of space
+ // and makes decoding faster.
+ if (coder->compressed_size >= coder->uncompressed_size) {
+ coder->uncompressed_size += mf->read_ahead;
+ assert(coder->uncompressed_size
+ <= LZMA2_UNCOMPRESSED_MAX);
+ mf->read_ahead = 0;
+ lzma2_header_uncompressed(coder);
+ coder->need_state_reset = true;
+ coder->sequence = SEQ_UNCOMPRESSED_HEADER;
+ break;
+ }
+
+ // The chunk did compress at least by one byte, so we store
+ // the chunk as LZMA.
+ lzma2_header_lzma(coder);
+
+ coder->sequence = SEQ_LZMA_COPY;
+ }
+
+ // Fall through
+
+ case SEQ_LZMA_COPY:
+ // Copy the compressed chunk along its headers to the
+ // output buffer.
+ lzma_bufcpy(coder->buf, &coder->buf_pos,
+ coder->compressed_size,
+ out, out_pos, out_size);
+ if (coder->buf_pos != coder->compressed_size)
+ return LZMA_OK;
+
+ coder->sequence = SEQ_INIT;
+ break;
+
+ case SEQ_UNCOMPRESSED_HEADER:
+ // Copy the three-byte header to indicate uncompressed chunk.
+ lzma_bufcpy(coder->buf, &coder->buf_pos,
+ LZMA2_HEADER_UNCOMPRESSED,
+ out, out_pos, out_size);
+ if (coder->buf_pos != LZMA2_HEADER_UNCOMPRESSED)
+ return LZMA_OK;
+
+ coder->sequence = SEQ_UNCOMPRESSED_COPY;
+
+ // Fall through
+
+ case SEQ_UNCOMPRESSED_COPY:
+ // Copy the uncompressed data as is from the dictionary
+ // to the output buffer.
+ mf_read(mf, out, out_pos, out_size, &coder->uncompressed_size);
+ if (coder->uncompressed_size != 0)
+ return LZMA_OK;
+
+ coder->sequence = SEQ_INIT;
+ break;
+ }
+
+ return LZMA_OK;
+}
+
+
+static void
+lzma2_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
+{
+ lzma_free(coder->lzma, allocator);
+ lzma_free(coder, allocator);
+ return;
+}
+
+
+static lzma_ret
+lzma2_encoder_options_update(lzma_coder *coder, const lzma_filter *filter)
+{
+ lzma_options_lzma *opt;
+
+ // New options can be set only when there is no incomplete chunk.
+ // This is the case at the beginning of the raw stream and right
+ // after LZMA_SYNC_FLUSH.
+ if (filter->options == NULL || coder->sequence != SEQ_INIT)
+ return LZMA_PROG_ERROR;
+
+ // Look if there are new options. At least for now,
+ // only lc/lp/pb can be changed.
+ opt = filter->options;
+ if (coder->opt_cur.lc != opt->lc || coder->opt_cur.lp != opt->lp
+ || coder->opt_cur.pb != opt->pb) {
+ // Validate the options.
+ if (opt->lc > LZMA_LCLP_MAX || opt->lp > LZMA_LCLP_MAX
+ || opt->lc + opt->lp > LZMA_LCLP_MAX
+ || opt->pb > LZMA_PB_MAX)
+ return LZMA_OPTIONS_ERROR;
+
+ // The new options will be used when the encoder starts
+ // a new LZMA2 chunk.
+ coder->opt_cur.lc = opt->lc;
+ coder->opt_cur.lp = opt->lp;
+ coder->opt_cur.pb = opt->pb;
+ coder->need_properties = true;
+ coder->need_state_reset = true;
+ }
+
+ return LZMA_OK;
+}
+
+
+static lzma_ret
+lzma2_encoder_init(lzma_lz_encoder *lz, lzma_allocator *allocator,
+ const void *options, lzma_lz_options *lz_options)
+{
+ if (options == NULL)
+ return LZMA_PROG_ERROR;
+
+ if (lz->coder == NULL) {
+ lz->coder = lzma_alloc(sizeof(lzma_coder), allocator);
+ if (lz->coder == NULL)
+ return LZMA_MEM_ERROR;
+
+ lz->code = &lzma2_encode;
+ lz->end = &lzma2_encoder_end;
+ lz->options_update = &lzma2_encoder_options_update;
+
+ lz->coder->lzma = NULL;
+ }
+
+ lz->coder->opt_cur = *(const lzma_options_lzma *)(options);
+
+ lz->coder->sequence = SEQ_INIT;
+ lz->coder->need_properties = true;
+ lz->coder->need_state_reset = false;
+ lz->coder->need_dictionary_reset
+ = lz->coder->opt_cur.preset_dict == NULL
+ || lz->coder->opt_cur.preset_dict_size == 0;
+
+ // Initialize LZMA encoder
+ return_if_error(lzma_lzma_encoder_create(&lz->coder->lzma, allocator,
+ &lz->coder->opt_cur, lz_options));
+
+ // Make sure that we will always have enough history available in
+ // case we need to use uncompressed chunks. They are used when the
+ // compressed size of a chunk is not smaller than the uncompressed
+ // size, so we need to have at least LZMA2_COMPRESSED_MAX bytes
+ // history available.
+ if (lz_options->before_size + lz_options->dict_size < LZMA2_CHUNK_MAX)
+ lz_options->before_size
+ = LZMA2_CHUNK_MAX - lz_options->dict_size;
+
+ return LZMA_OK;
+}
+
+
+extern lzma_ret
+lzma_lzma2_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter_info *filters)
+{
+ return lzma_lz_encoder_init(
+ next, allocator, filters, &lzma2_encoder_init);
+}
+
+
+extern uint64_t
+lzma_lzma2_encoder_memusage(const void *options)
+{
+ const uint64_t lzma_mem = lzma_lzma_encoder_memusage(options);
+ if (lzma_mem == UINT64_MAX)
+ return UINT64_MAX;
+
+ return sizeof(lzma_coder) + lzma_mem;
+}
+
+
+extern lzma_ret
+lzma_lzma2_props_encode(const void *options, uint8_t *out)
+{
+ const lzma_options_lzma *const opt = options;
+ uint32_t d = my_max(opt->dict_size, LZMA_DICT_SIZE_MIN);
+
+ // Round up to the next 2^n - 1 or 2^n + 2^(n - 1) - 1 depending
+ // on which one is the next:
+ --d;
+ d |= d >> 2;
+ d |= d >> 3;
+ d |= d >> 4;
+ d |= d >> 8;
+ d |= d >> 16;
+
+ // Get the highest two bits using the proper encoding:
+ if (d == UINT32_MAX)
+ out[0] = 40;
+ else
+ out[0] = get_pos_slot(d + 1) - 24;
+
+ return LZMA_OK;
+}
diff --git a/Utilities/cmliblzma/liblzma/lzma/lzma2_encoder.h b/Utilities/cmliblzma/liblzma/lzma/lzma2_encoder.h
new file mode 100644
index 000000000..ca19ef469
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/lzma/lzma2_encoder.h
@@ -0,0 +1,41 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file lzma2_encoder.h
+/// \brief LZMA2 encoder
+///
+// Authors: Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_LZMA2_ENCODER_H
+#define LZMA_LZMA2_ENCODER_H
+
+#include "common.h"
+
+
+/// Maximum number of bytes of actual data per chunk (no headers)
+#define LZMA2_CHUNK_MAX (UINT32_C(1) << 16)
+
+/// Maximum uncompressed size of LZMA chunk (no headers)
+#define LZMA2_UNCOMPRESSED_MAX (UINT32_C(1) << 21)
+
+/// Maximum size of LZMA2 headers
+#define LZMA2_HEADER_MAX 6
+
+/// Size of a header for uncompressed chunk
+#define LZMA2_HEADER_UNCOMPRESSED 3
+
+
+extern lzma_ret lzma_lzma2_encoder_init(
+ lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter_info *filters);
+
+extern uint64_t lzma_lzma2_encoder_memusage(const void *options);
+
+extern lzma_ret lzma_lzma2_props_encode(const void *options, uint8_t *out);
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/lzma/lzma_common.h b/Utilities/cmliblzma/liblzma/lzma/lzma_common.h
new file mode 100644
index 000000000..36267dc88
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/lzma/lzma_common.h
@@ -0,0 +1,226 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file lzma_common.h
+/// \brief Private definitions common to LZMA encoder and decoder
+///
+// Authors: Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_LZMA_COMMON_H
+#define LZMA_LZMA_COMMON_H
+
+#include "common.h"
+#include "range_common.h"
+
+
+///////////////////
+// Miscellaneous //
+///////////////////
+
+/// Maximum number of position states. A position state is the lowest pos bits
+/// number of bits of the current uncompressed offset. In some places there
+/// are different sets of probabilities for different pos states.
+#define POS_STATES_MAX (1 << LZMA_PB_MAX)
+
+
+/// Validates lc, lp, and pb.
+static inline bool
+is_lclppb_valid(const lzma_options_lzma *options)
+{
+ return options->lc <= LZMA_LCLP_MAX && options->lp <= LZMA_LCLP_MAX
+ && options->lc + options->lp <= LZMA_LCLP_MAX
+ && options->pb <= LZMA_PB_MAX;
+}
+
+
+///////////
+// State //
+///////////
+
+/// This enum is used to track which events have occurred most recently and
+/// in which order. This information is used to predict the next event.
+///
+/// Events:
+/// - Literal: One 8-bit byte
+/// - Match: Repeat a chunk of data at some distance
+/// - Long repeat: Multi-byte match at a recently seen distance
+/// - Short repeat: One-byte repeat at a recently seen distance
+///
+/// The event names are in from STATE_oldest_older_previous. REP means
+/// either short or long repeated match, and NONLIT means any non-literal.
+typedef enum {
+ STATE_LIT_LIT,
+ STATE_MATCH_LIT_LIT,
+ STATE_REP_LIT_LIT,
+ STATE_SHORTREP_LIT_LIT,
+ STATE_MATCH_LIT,
+ STATE_REP_LIT,
+ STATE_SHORTREP_LIT,
+ STATE_LIT_MATCH,
+ STATE_LIT_LONGREP,
+ STATE_LIT_SHORTREP,
+ STATE_NONLIT_MATCH,
+ STATE_NONLIT_REP,
+} lzma_lzma_state;
+
+
+/// Total number of states
+#define STATES 12
+
+/// The lowest 7 states indicate that the previous state was a literal.
+#define LIT_STATES 7
+
+
+/// Indicate that the latest state was a literal.
+#define update_literal(state) \
+ state = ((state) <= STATE_SHORTREP_LIT_LIT \
+ ? STATE_LIT_LIT \
+ : ((state) <= STATE_LIT_SHORTREP \
+ ? (state) - 3 \
+ : (state) - 6))
+
+/// Indicate that the latest state was a match.
+#define update_match(state) \
+ state = ((state) < LIT_STATES ? STATE_LIT_MATCH : STATE_NONLIT_MATCH)
+
+/// Indicate that the latest state was a long repeated match.
+#define update_long_rep(state) \
+ state = ((state) < LIT_STATES ? STATE_LIT_LONGREP : STATE_NONLIT_REP)
+
+/// Indicate that the latest state was a short match.
+#define update_short_rep(state) \
+ state = ((state) < LIT_STATES ? STATE_LIT_SHORTREP : STATE_NONLIT_REP)
+
+/// Test if the previous state was a literal.
+#define is_literal_state(state) \
+ ((state) < LIT_STATES)
+
+
+/////////////
+// Literal //
+/////////////
+
+/// Each literal coder is divided in three sections:
+/// - 0x001-0x0FF: Without match byte
+/// - 0x101-0x1FF: With match byte; match bit is 0
+/// - 0x201-0x2FF: With match byte; match bit is 1
+///
+/// Match byte is used when the previous LZMA symbol was something else than
+/// a literal (that is, it was some kind of match).
+#define LITERAL_CODER_SIZE 0x300
+
+/// Maximum number of literal coders
+#define LITERAL_CODERS_MAX (1 << LZMA_LCLP_MAX)
+
+/// Locate the literal coder for the next literal byte. The choice depends on
+/// - the lowest literal_pos_bits bits of the position of the current
+/// byte; and
+/// - the highest literal_context_bits bits of the previous byte.
+#define literal_subcoder(probs, lc, lp_mask, pos, prev_byte) \
+ ((probs)[(((pos) & lp_mask) << lc) + ((prev_byte) >> (8 - lc))])
+
+
+static inline void
+literal_init(probability (*probs)[LITERAL_CODER_SIZE],
+ uint32_t lc, uint32_t lp)
+{
+ uint32_t coders;
+ uint32_t i, j;
+
+ assert(lc + lp <= LZMA_LCLP_MAX);
+
+ coders = 1U << (lc + lp);
+
+ for (i = 0; i < coders; ++i)
+ for (j = 0; j < LITERAL_CODER_SIZE; ++j)
+ bit_reset(probs[i][j]);
+
+ return;
+}
+
+
+//////////////////
+// Match length //
+//////////////////
+
+// Minimum length of a match is two bytes.
+#define MATCH_LEN_MIN 2
+
+// Match length is encoded with 4, 5, or 10 bits.
+//
+// Length Bits
+// 2-9 4 = Choice=0 + 3 bits
+// 10-17 5 = Choice=1 + Choice2=0 + 3 bits
+// 18-273 10 = Choice=1 + Choice2=1 + 8 bits
+#define LEN_LOW_BITS 3
+#define LEN_LOW_SYMBOLS (1 << LEN_LOW_BITS)
+#define LEN_MID_BITS 3
+#define LEN_MID_SYMBOLS (1 << LEN_MID_BITS)
+#define LEN_HIGH_BITS 8
+#define LEN_HIGH_SYMBOLS (1 << LEN_HIGH_BITS)
+#define LEN_SYMBOLS (LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS + LEN_HIGH_SYMBOLS)
+
+// Maximum length of a match is 273 which is a result of the encoding
+// described above.
+#define MATCH_LEN_MAX (MATCH_LEN_MIN + LEN_SYMBOLS - 1)
+
+
+////////////////////
+// Match distance //
+////////////////////
+
+// Different set of probabilities is used for match distances that have very
+// short match length: Lengths of 2, 3, and 4 bytes have a separate set of
+// probabilities for each length. The matches with longer length use a shared
+// set of probabilities.
+#define LEN_TO_POS_STATES 4
+
+// Macro to get the index of the appropriate probability array.
+#define get_len_to_pos_state(len) \
+ ((len) < LEN_TO_POS_STATES + MATCH_LEN_MIN \
+ ? (len) - MATCH_LEN_MIN \
+ : LEN_TO_POS_STATES - 1)
+
+// The highest two bits of a match distance (pos slot) are encoded using six
+// bits. See fastpos.h for more explanation.
+#define POS_SLOT_BITS 6
+#define POS_SLOTS (1 << POS_SLOT_BITS)
+
+// Match distances up to 127 are fully encoded using probabilities. Since
+// the highest two bits (pos slot) are always encoded using six bits, the
+// distances 0-3 don't need any additional bits to encode, since the pos
+// slot itself is the same as the actual distance. START_POS_MODEL_INDEX
+// indicates the first pos slot where at least one additional bit is needed.
+#define START_POS_MODEL_INDEX 4
+
+// Match distances greater than 127 are encoded in three pieces:
+// - pos slot: the highest two bits
+// - direct bits: 2-26 bits below the highest two bits
+// - alignment bits: four lowest bits
+//
+// Direct bits don't use any probabilities.
+//
+// The pos slot value of 14 is for distances 128-191 (see the table in
+// fastpos.h to understand why).
+#define END_POS_MODEL_INDEX 14
+
+// Pos slots that indicate a distance <= 127.
+#define FULL_DISTANCES_BITS (END_POS_MODEL_INDEX / 2)
+#define FULL_DISTANCES (1 << FULL_DISTANCES_BITS)
+
+// For match distances greater than 127, only the highest two bits and the
+// lowest four bits (alignment) is encoded using probabilities.
+#define ALIGN_BITS 4
+#define ALIGN_TABLE_SIZE (1 << ALIGN_BITS)
+#define ALIGN_MASK (ALIGN_TABLE_SIZE - 1)
+
+// LZMA remembers the four most recent match distances. Reusing these distances
+// tends to take less space than re-encoding the actual distance value.
+#define REP_DISTANCES 4
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/lzma/lzma_decoder.c b/Utilities/cmliblzma/liblzma/lzma/lzma_decoder.c
new file mode 100644
index 000000000..3c0f39331
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/lzma/lzma_decoder.c
@@ -0,0 +1,1075 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file lzma_decoder.c
+/// \brief LZMA decoder
+///
+// Authors: Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "lz_decoder.h"
+#include "lzma_common.h"
+#include "lzma_decoder.h"
+#include "range_decoder.h"
+
+
+#ifdef HAVE_SMALL
+
+// Macros for (somewhat) size-optimized code.
+#define seq_4(seq) seq
+
+#define seq_6(seq) seq
+
+#define seq_8(seq) seq
+
+#define seq_len(seq) \
+ seq ## _CHOICE, \
+ seq ## _CHOICE2, \
+ seq ## _BITTREE
+
+#define len_decode(target, ld, pos_state, seq) \
+do { \
+case seq ## _CHOICE: \
+ rc_if_0(ld.choice, seq ## _CHOICE) { \
+ rc_update_0(ld.choice); \
+ probs = ld.low[pos_state];\
+ limit = LEN_LOW_SYMBOLS; \
+ target = MATCH_LEN_MIN; \
+ } else { \
+ rc_update_1(ld.choice); \
+case seq ## _CHOICE2: \
+ rc_if_0(ld.choice2, seq ## _CHOICE2) { \
+ rc_update_0(ld.choice2); \
+ probs = ld.mid[pos_state]; \
+ limit = LEN_MID_SYMBOLS; \
+ target = MATCH_LEN_MIN + LEN_LOW_SYMBOLS; \
+ } else { \
+ rc_update_1(ld.choice2); \
+ probs = ld.high; \
+ limit = LEN_HIGH_SYMBOLS; \
+ target = MATCH_LEN_MIN + LEN_LOW_SYMBOLS \
+ + LEN_MID_SYMBOLS; \
+ } \
+ } \
+ symbol = 1; \
+case seq ## _BITTREE: \
+ do { \
+ rc_bit(probs[symbol], , , seq ## _BITTREE); \
+ } while (symbol < limit); \
+ target += symbol - limit; \
+} while (0)
+
+#else // HAVE_SMALL
+
+// Unrolled versions
+#define seq_4(seq) \
+ seq ## 0, \
+ seq ## 1, \
+ seq ## 2, \
+ seq ## 3
+
+#define seq_6(seq) \
+ seq ## 0, \
+ seq ## 1, \
+ seq ## 2, \
+ seq ## 3, \
+ seq ## 4, \
+ seq ## 5
+
+#define seq_8(seq) \
+ seq ## 0, \
+ seq ## 1, \
+ seq ## 2, \
+ seq ## 3, \
+ seq ## 4, \
+ seq ## 5, \
+ seq ## 6, \
+ seq ## 7
+
+#define seq_len(seq) \
+ seq ## _CHOICE, \
+ seq ## _LOW0, \
+ seq ## _LOW1, \
+ seq ## _LOW2, \
+ seq ## _CHOICE2, \
+ seq ## _MID0, \
+ seq ## _MID1, \
+ seq ## _MID2, \
+ seq ## _HIGH0, \
+ seq ## _HIGH1, \
+ seq ## _HIGH2, \
+ seq ## _HIGH3, \
+ seq ## _HIGH4, \
+ seq ## _HIGH5, \
+ seq ## _HIGH6, \
+ seq ## _HIGH7
+
+#define len_decode(target, ld, pos_state, seq) \
+do { \
+ symbol = 1; \
+case seq ## _CHOICE: \
+ rc_if_0(ld.choice, seq ## _CHOICE) { \
+ rc_update_0(ld.choice); \
+ rc_bit_case(ld.low[pos_state][symbol], 0, 0, seq ## _LOW0); \
+ rc_bit_case(ld.low[pos_state][symbol], 0, 0, seq ## _LOW1); \
+ rc_bit_case(ld.low[pos_state][symbol], 0, 0, seq ## _LOW2); \
+ target = symbol - LEN_LOW_SYMBOLS + MATCH_LEN_MIN; \
+ } else { \
+ rc_update_1(ld.choice); \
+case seq ## _CHOICE2: \
+ rc_if_0(ld.choice2, seq ## _CHOICE2) { \
+ rc_update_0(ld.choice2); \
+ rc_bit_case(ld.mid[pos_state][symbol], 0, 0, \
+ seq ## _MID0); \
+ rc_bit_case(ld.mid[pos_state][symbol], 0, 0, \
+ seq ## _MID1); \
+ rc_bit_case(ld.mid[pos_state][symbol], 0, 0, \
+ seq ## _MID2); \
+ target = symbol - LEN_MID_SYMBOLS \
+ + MATCH_LEN_MIN + LEN_LOW_SYMBOLS; \
+ } else { \
+ rc_update_1(ld.choice2); \
+ rc_bit_case(ld.high[symbol], 0, 0, seq ## _HIGH0); \
+ rc_bit_case(ld.high[symbol], 0, 0, seq ## _HIGH1); \
+ rc_bit_case(ld.high[symbol], 0, 0, seq ## _HIGH2); \
+ rc_bit_case(ld.high[symbol], 0, 0, seq ## _HIGH3); \
+ rc_bit_case(ld.high[symbol], 0, 0, seq ## _HIGH4); \
+ rc_bit_case(ld.high[symbol], 0, 0, seq ## _HIGH5); \
+ rc_bit_case(ld.high[symbol], 0, 0, seq ## _HIGH6); \
+ rc_bit_case(ld.high[symbol], 0, 0, seq ## _HIGH7); \
+ target = symbol - LEN_HIGH_SYMBOLS \
+ + MATCH_LEN_MIN \
+ + LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS; \
+ } \
+ } \
+} while (0)
+
+#endif // HAVE_SMALL
+
+
+/// Length decoder probabilities; see comments in lzma_common.h.
+typedef struct {
+ probability choice;
+ probability choice2;
+ probability low[POS_STATES_MAX][LEN_LOW_SYMBOLS];
+ probability mid[POS_STATES_MAX][LEN_MID_SYMBOLS];
+ probability high[LEN_HIGH_SYMBOLS];
+} lzma_length_decoder;
+
+
+struct lzma_coder_s {
+ ///////////////////
+ // Probabilities //
+ ///////////////////
+
+ /// Literals; see comments in lzma_common.h.
+ probability literal[LITERAL_CODERS_MAX][LITERAL_CODER_SIZE];
+
+ /// If 1, it's a match. Otherwise it's a single 8-bit literal.
+ probability is_match[STATES][POS_STATES_MAX];
+
+ /// If 1, it's a repeated match. The distance is one of rep0 .. rep3.
+ probability is_rep[STATES];
+
+ /// If 0, distance of a repeated match is rep0.
+ /// Otherwise check is_rep1.
+ probability is_rep0[STATES];
+
+ /// If 0, distance of a repeated match is rep1.
+ /// Otherwise check is_rep2.
+ probability is_rep1[STATES];
+
+ /// If 0, distance of a repeated match is rep2. Otherwise it is rep3.
+ probability is_rep2[STATES];
+
+ /// If 1, the repeated match has length of one byte. Otherwise
+ /// the length is decoded from rep_len_decoder.
+ probability is_rep0_long[STATES][POS_STATES_MAX];
+
+ /// Probability tree for the highest two bits of the match distance.
+ /// There is a separate probability tree for match lengths of
+ /// 2 (i.e. MATCH_LEN_MIN), 3, 4, and [5, 273].
+ probability pos_slot[LEN_TO_POS_STATES][POS_SLOTS];
+
+ /// Probability trees for additional bits for match distance when the
+ /// distance is in the range [4, 127].
+ probability pos_special[FULL_DISTANCES - END_POS_MODEL_INDEX];
+
+ /// Probability tree for the lowest four bits of a match distance
+ /// that is equal to or greater than 128.
+ probability pos_align[ALIGN_TABLE_SIZE];
+
+ /// Length of a normal match
+ lzma_length_decoder match_len_decoder;
+
+ /// Length of a repeated match
+ lzma_length_decoder rep_len_decoder;
+
+ ///////////////////
+ // Decoder state //
+ ///////////////////
+
+ // Range coder
+ lzma_range_decoder rc;
+
+ // Types of the most recently seen LZMA symbols
+ lzma_lzma_state state;
+
+ uint32_t rep0; ///< Distance of the latest match
+ uint32_t rep1; ///< Distance of second latest match
+ uint32_t rep2; ///< Distance of third latest match
+ uint32_t rep3; ///< Distance of fourth latest match
+
+ uint32_t pos_mask; // (1U << pb) - 1
+ uint32_t literal_context_bits;
+ uint32_t literal_pos_mask;
+
+ /// Uncompressed size as bytes, or LZMA_VLI_UNKNOWN if end of
+ /// payload marker is expected.
+ lzma_vli uncompressed_size;
+
+ ////////////////////////////////
+ // State of incomplete symbol //
+ ////////////////////////////////
+
+ /// Position where to continue the decoder loop
+ enum {
+ SEQ_NORMALIZE,
+ SEQ_IS_MATCH,
+ seq_8(SEQ_LITERAL),
+ seq_8(SEQ_LITERAL_MATCHED),
+ SEQ_LITERAL_WRITE,
+ SEQ_IS_REP,
+ seq_len(SEQ_MATCH_LEN),
+ seq_6(SEQ_POS_SLOT),
+ SEQ_POS_MODEL,
+ SEQ_DIRECT,
+ seq_4(SEQ_ALIGN),
+ SEQ_EOPM,
+ SEQ_IS_REP0,
+ SEQ_SHORTREP,
+ SEQ_IS_REP0_LONG,
+ SEQ_IS_REP1,
+ SEQ_IS_REP2,
+ seq_len(SEQ_REP_LEN),
+ SEQ_COPY,
+ } sequence;
+
+ /// Base of the current probability tree
+ probability *probs;
+
+ /// Symbol being decoded. This is also used as an index variable in
+ /// bittree decoders: probs[symbol]
+ uint32_t symbol;
+
+ /// Used as a loop termination condition on bittree decoders and
+ /// direct bits decoder.
+ uint32_t limit;
+
+ /// Matched literal decoder: 0x100 or 0 to help avoiding branches.
+ /// Bittree reverse decoders: Offset of the next bit: 1 << offset
+ uint32_t offset;
+
+ /// If decoding a literal: match byte.
+ /// If decoding a match: length of the match.
+ uint32_t len;
+};
+
+
+static lzma_ret
+lzma_decode(lzma_coder *LZMA_RESTRICT coder, lzma_dict *LZMA_RESTRICT dictptr,
+ const uint8_t *LZMA_RESTRICT in,
+ size_t *LZMA_RESTRICT in_pos, size_t in_size)
+{
+ ///////////////
+ // Variables //
+ ///////////////
+
+ // Making local copies of often-used variables improves both
+ // speed and readability.
+
+ lzma_dict dict = *dictptr;
+
+ const size_t dict_start = dict.pos;
+
+ // Range decoder
+ rc_to_local(coder->rc, *in_pos);
+
+ // State
+ uint32_t state = coder->state;
+ uint32_t rep0 = coder->rep0;
+ uint32_t rep1 = coder->rep1;
+ uint32_t rep2 = coder->rep2;
+ uint32_t rep3 = coder->rep3;
+
+ const uint32_t pos_mask = coder->pos_mask;
+
+ // These variables are actually needed only if we last time ran
+ // out of input in the middle of the decoder loop.
+ probability *probs = coder->probs;
+ uint32_t symbol = coder->symbol;
+ uint32_t limit = coder->limit;
+ uint32_t offset = coder->offset;
+ uint32_t len = coder->len;
+
+ const uint32_t literal_pos_mask = coder->literal_pos_mask;
+ const uint32_t literal_context_bits = coder->literal_context_bits;
+
+ // Temporary variables
+ uint32_t pos_state = dict.pos & pos_mask;
+
+ lzma_ret ret = LZMA_OK;
+
+ // If uncompressed size is known, there must be no end of payload
+ // marker.
+ const bool no_eopm = coder->uncompressed_size
+ != LZMA_VLI_UNKNOWN;
+ if (no_eopm && coder->uncompressed_size < dict.limit - dict.pos)
+ dict.limit = dict.pos + (size_t)(coder->uncompressed_size);
+
+ ////////////////////
+ // Initialization //
+ ////////////////////
+
+ if (!rc_read_init(&coder->rc, in, in_pos, in_size))
+ return LZMA_OK;
+
+ rc = coder->rc;
+ rc_in_pos = *in_pos;
+
+ // The main decoder loop. The "switch" is used to restart the decoder at
+ // correct location. Once restarted, the "switch" is no longer used.
+ switch (coder->sequence)
+ while (true) {
+ // Calculate new pos_state. This is skipped on the first loop
+ // since we already calculated it when setting up the local
+ // variables.
+ pos_state = dict.pos & pos_mask;
+
+ case SEQ_NORMALIZE:
+ case SEQ_IS_MATCH:
+ if (unlikely(no_eopm && dict.pos == dict.limit))
+ break;
+
+ rc_if_0(coder->is_match[state][pos_state], SEQ_IS_MATCH) {
+ static const lzma_lzma_state next_state[] = {
+ STATE_LIT_LIT,
+ STATE_LIT_LIT,
+ STATE_LIT_LIT,
+ STATE_LIT_LIT,
+ STATE_MATCH_LIT_LIT,
+ STATE_REP_LIT_LIT,
+ STATE_SHORTREP_LIT_LIT,
+ STATE_MATCH_LIT,
+ STATE_REP_LIT,
+ STATE_SHORTREP_LIT,
+ STATE_MATCH_LIT,
+ STATE_REP_LIT
+ };
+
+ rc_update_0(coder->is_match[state][pos_state]);
+
+ // It's a literal i.e. a single 8-bit byte.
+
+ probs = literal_subcoder(coder->literal,
+ literal_context_bits, literal_pos_mask,
+ dict.pos, dict_get(&dict, 0));
+ symbol = 1;
+
+ if (is_literal_state(state)) {
+ // Decode literal without match byte.
+#ifdef HAVE_SMALL
+ case SEQ_LITERAL:
+ do {
+ rc_bit(probs[symbol], , , SEQ_LITERAL);
+ } while (symbol < (1 << 8));
+#else
+ rc_bit_case(probs[symbol], 0, 0, SEQ_LITERAL0);
+ rc_bit_case(probs[symbol], 0, 0, SEQ_LITERAL1);
+ rc_bit_case(probs[symbol], 0, 0, SEQ_LITERAL2);
+ rc_bit_case(probs[symbol], 0, 0, SEQ_LITERAL3);
+ rc_bit_case(probs[symbol], 0, 0, SEQ_LITERAL4);
+ rc_bit_case(probs[symbol], 0, 0, SEQ_LITERAL5);
+ rc_bit_case(probs[symbol], 0, 0, SEQ_LITERAL6);
+ rc_bit_case(probs[symbol], 0, 0, SEQ_LITERAL7);
+#endif
+ } else {
+#ifndef HAVE_SMALL
+ uint32_t match_bit;
+ uint32_t subcoder_index;
+#endif
+
+ // Decode literal with match byte.
+ //
+ // We store the byte we compare against
+ // ("match byte") to "len" to minimize the
+ // number of variables we need to store
+ // between decoder calls.
+ len = dict_get(&dict, rep0) << 1;
+
+ // The usage of "offset" allows omitting some
+ // branches, which should give tiny speed
+ // improvement on some CPUs. "offset" gets
+ // set to zero if match_bit didn't match.
+ offset = 0x100;
+
+#ifdef HAVE_SMALL
+ case SEQ_LITERAL_MATCHED:
+ do {
+ const uint32_t match_bit
+ = len & offset;
+ const uint32_t subcoder_index
+ = offset + match_bit
+ + symbol;
+
+ rc_bit(probs[subcoder_index],
+ offset &= ~match_bit,
+ offset &= match_bit,
+ SEQ_LITERAL_MATCHED);
+
+ // It seems to be faster to do this
+ // here instead of putting it to the
+ // beginning of the loop and then
+ // putting the "case" in the middle
+ // of the loop.
+ len <<= 1;
+
+ } while (symbol < (1 << 8));
+#else
+ // Unroll the loop.
+
+# define d(seq) \
+ case seq: \
+ match_bit = len & offset; \
+ subcoder_index = offset + match_bit + symbol; \
+ rc_bit(probs[subcoder_index], \
+ offset &= ~match_bit, \
+ offset &= match_bit, \
+ seq)
+
+ d(SEQ_LITERAL_MATCHED0);
+ len <<= 1;
+ d(SEQ_LITERAL_MATCHED1);
+ len <<= 1;
+ d(SEQ_LITERAL_MATCHED2);
+ len <<= 1;
+ d(SEQ_LITERAL_MATCHED3);
+ len <<= 1;
+ d(SEQ_LITERAL_MATCHED4);
+ len <<= 1;
+ d(SEQ_LITERAL_MATCHED5);
+ len <<= 1;
+ d(SEQ_LITERAL_MATCHED6);
+ len <<= 1;
+ d(SEQ_LITERAL_MATCHED7);
+# undef d
+#endif
+ }
+
+ //update_literal(state);
+ // Use a lookup table to update to literal state,
+ // since compared to other state updates, this would
+ // need two branches.
+ state = next_state[state];
+
+ case SEQ_LITERAL_WRITE:
+ if (unlikely(dict_put(&dict, symbol))) {
+ coder->sequence = SEQ_LITERAL_WRITE;
+ goto out;
+ }
+
+ continue;
+ }
+
+ // Instead of a new byte we are going to get a byte range
+ // (distance and length) which will be repeated from our
+ // output history.
+
+ rc_update_1(coder->is_match[state][pos_state]);
+
+ case SEQ_IS_REP:
+ rc_if_0(coder->is_rep[state], SEQ_IS_REP) {
+ // Not a repeated match
+ rc_update_0(coder->is_rep[state]);
+ update_match(state);
+
+ // The latest three match distances are kept in
+ // memory in case there are repeated matches.
+ rep3 = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+
+ // Decode the length of the match.
+ len_decode(len, coder->match_len_decoder,
+ pos_state, SEQ_MATCH_LEN);
+
+ // Prepare to decode the highest two bits of the
+ // match distance.
+ probs = coder->pos_slot[get_len_to_pos_state(len)];
+ symbol = 1;
+
+#ifdef HAVE_SMALL
+ case SEQ_POS_SLOT:
+ do {
+ rc_bit(probs[symbol], , , SEQ_POS_SLOT);
+ } while (symbol < POS_SLOTS);
+#else
+ rc_bit_case(probs[symbol], 0, 0, SEQ_POS_SLOT0);
+ rc_bit_case(probs[symbol], 0, 0, SEQ_POS_SLOT1);
+ rc_bit_case(probs[symbol], 0, 0, SEQ_POS_SLOT2);
+ rc_bit_case(probs[symbol], 0, 0, SEQ_POS_SLOT3);
+ rc_bit_case(probs[symbol], 0, 0, SEQ_POS_SLOT4);
+ rc_bit_case(probs[symbol], 0, 0, SEQ_POS_SLOT5);
+#endif
+ // Get rid of the highest bit that was needed for
+ // indexing of the probability array.
+ symbol -= POS_SLOTS;
+ assert(symbol <= 63);
+
+ if (symbol < START_POS_MODEL_INDEX) {
+ // Match distances [0, 3] have only two bits.
+ rep0 = symbol;
+ } else {
+ // Decode the lowest [1, 29] bits of
+ // the match distance.
+ limit = (symbol >> 1) - 1;
+ assert(limit >= 1 && limit <= 30);
+ rep0 = 2 + (symbol & 1);
+
+ if (symbol < END_POS_MODEL_INDEX) {
+ // Prepare to decode the low bits for
+ // a distance of [4, 127].
+ assert(limit <= 5);
+ rep0 <<= limit;
+ assert(rep0 <= 96);
+ // -1 is fine, because we start
+ // decoding at probs[1], not probs[0].
+ // NOTE: This violates the C standard,
+ // since we are doing pointer
+ // arithmetic past the beginning of
+ // the array.
+ assert((int32_t)(rep0 - symbol - 1)
+ >= -1);
+ assert((int32_t)(rep0 - symbol - 1)
+ <= 82);
+ probs = coder->pos_special + rep0
+ - symbol - 1;
+ symbol = 1;
+ offset = 0;
+ case SEQ_POS_MODEL:
+#ifdef HAVE_SMALL
+ do {
+ rc_bit(probs[symbol], ,
+ rep0 += 1 << offset,
+ SEQ_POS_MODEL);
+ } while (++offset < limit);
+#else
+ switch (limit) {
+ case 5:
+ assert(offset == 0);
+ rc_bit(probs[symbol], 0,
+ rep0 += 1,
+ SEQ_POS_MODEL);
+ ++offset;
+ --limit;
+ case 4:
+ rc_bit(probs[symbol], 0,
+ rep0 += 1 << offset,
+ SEQ_POS_MODEL);
+ ++offset;
+ --limit;
+ case 3:
+ rc_bit(probs[symbol], 0,
+ rep0 += 1 << offset,
+ SEQ_POS_MODEL);
+ ++offset;
+ --limit;
+ case 2:
+ rc_bit(probs[symbol], 0,
+ rep0 += 1 << offset,
+ SEQ_POS_MODEL);
+ ++offset;
+ --limit;
+ case 1:
+ // We need "symbol" only for
+ // indexing the probability
+ // array, thus we can use
+ // rc_bit_last() here to omit
+ // the unneeded updating of
+ // "symbol".
+ rc_bit_last(probs[symbol], 0,
+ rep0 += 1 << offset,
+ SEQ_POS_MODEL);
+ }
+#endif
+ } else {
+ // The distance is >= 128. Decode the
+ // lower bits without probabilities
+ // except the lowest four bits.
+ assert(symbol >= 14);
+ assert(limit >= 6);
+ limit -= ALIGN_BITS;
+ assert(limit >= 2);
+ case SEQ_DIRECT:
+ // Not worth manual unrolling
+ do {
+ rc_direct(rep0, SEQ_DIRECT);
+ } while (--limit > 0);
+
+ // Decode the lowest four bits using
+ // probabilities.
+ rep0 <<= ALIGN_BITS;
+ symbol = 1;
+#ifdef HAVE_SMALL
+ offset = 0;
+ case SEQ_ALIGN:
+ do {
+ rc_bit(coder->pos_align[
+ symbol], ,
+ rep0 += 1 << offset,
+ SEQ_ALIGN);
+ } while (++offset < ALIGN_BITS);
+#else
+ case SEQ_ALIGN0:
+ rc_bit(coder->pos_align[symbol], 0,
+ rep0 += 1, SEQ_ALIGN0);
+ case SEQ_ALIGN1:
+ rc_bit(coder->pos_align[symbol], 0,
+ rep0 += 2, SEQ_ALIGN1);
+ case SEQ_ALIGN2:
+ rc_bit(coder->pos_align[symbol], 0,
+ rep0 += 4, SEQ_ALIGN2);
+ case SEQ_ALIGN3:
+ // Like in SEQ_POS_MODEL, we don't
+ // need "symbol" for anything else
+ // than indexing the probability array.
+ rc_bit_last(coder->pos_align[symbol], 0,
+ rep0 += 8, SEQ_ALIGN3);
+#endif
+
+ if (rep0 == UINT32_MAX) {
+ // End of payload marker was
+ // found. It must not be
+ // present if uncompressed
+ // size is known.
+ if (coder->uncompressed_size
+ != LZMA_VLI_UNKNOWN) {
+ ret = LZMA_DATA_ERROR;
+ goto out;
+ }
+
+ case SEQ_EOPM:
+ // LZMA1 stream with
+ // end-of-payload marker.
+ rc_normalize(SEQ_EOPM);
+ ret = LZMA_STREAM_END;
+ goto out;
+ }
+ }
+ }
+
+ // Validate the distance we just decoded.
+ if (unlikely(!dict_is_distance_valid(&dict, rep0))) {
+ ret = LZMA_DATA_ERROR;
+ goto out;
+ }
+
+ } else {
+ rc_update_1(coder->is_rep[state]);
+
+ // Repeated match
+ //
+ // The match distance is a value that we have had
+ // earlier. The latest four match distances are
+ // available as rep0, rep1, rep2 and rep3. We will
+ // now decode which of them is the new distance.
+ //
+ // There cannot be a match if we haven't produced
+ // any output, so check that first.
+ if (unlikely(!dict_is_distance_valid(&dict, 0))) {
+ ret = LZMA_DATA_ERROR;
+ goto out;
+ }
+
+ case SEQ_IS_REP0:
+ rc_if_0(coder->is_rep0[state], SEQ_IS_REP0) {
+ rc_update_0(coder->is_rep0[state]);
+ // The distance is rep0.
+
+ case SEQ_IS_REP0_LONG:
+ rc_if_0(coder->is_rep0_long[state][pos_state],
+ SEQ_IS_REP0_LONG) {
+ rc_update_0(coder->is_rep0_long[
+ state][pos_state]);
+
+ update_short_rep(state);
+
+ case SEQ_SHORTREP:
+ if (unlikely(dict_put(&dict, dict_get(
+ &dict, rep0)))) {
+ coder->sequence = SEQ_SHORTREP;
+ goto out;
+ }
+
+ continue;
+ }
+
+ // Repeating more than one byte at
+ // distance of rep0.
+ rc_update_1(coder->is_rep0_long[
+ state][pos_state]);
+
+ } else {
+ rc_update_1(coder->is_rep0[state]);
+
+ case SEQ_IS_REP1:
+ // The distance is rep1, rep2 or rep3. Once
+ // we find out which one of these three, it
+ // is stored to rep0 and rep1, rep2 and rep3
+ // are updated accordingly.
+ rc_if_0(coder->is_rep1[state], SEQ_IS_REP1) {
+ uint32_t distance;
+
+ rc_update_0(coder->is_rep1[state]);
+
+ distance = rep1;
+ rep1 = rep0;
+ rep0 = distance;
+
+ } else {
+ rc_update_1(coder->is_rep1[state]);
+ case SEQ_IS_REP2:
+ rc_if_0(coder->is_rep2[state],
+ SEQ_IS_REP2) {
+ uint32_t distance;
+
+ rc_update_0(coder->is_rep2[
+ state]);
+
+ distance = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+ rep0 = distance;
+
+ } else {
+ uint32_t distance;
+
+ rc_update_1(coder->is_rep2[
+ state]);
+
+ distance = rep3;
+ rep3 = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+ rep0 = distance;
+ }
+ }
+ }
+
+ update_long_rep(state);
+
+ // Decode the length of the repeated match.
+ len_decode(len, coder->rep_len_decoder,
+ pos_state, SEQ_REP_LEN);
+ }
+
+ /////////////////////////////////
+ // Repeat from history buffer. //
+ /////////////////////////////////
+
+ // The length is always between these limits. There is no way
+ // to trigger the algorithm to set len outside this range.
+ assert(len >= MATCH_LEN_MIN);
+ assert(len <= MATCH_LEN_MAX);
+
+ case SEQ_COPY:
+ // Repeat len bytes from distance of rep0.
+ if (unlikely(dict_repeat(&dict, rep0, &len))) {
+ coder->sequence = SEQ_COPY;
+ goto out;
+ }
+ }
+
+ rc_normalize(SEQ_NORMALIZE);
+ coder->sequence = SEQ_IS_MATCH;
+
+out:
+ // Save state
+
+ // NOTE: Must not copy dict.limit.
+ dictptr->pos = dict.pos;
+ dictptr->full = dict.full;
+
+ rc_from_local(coder->rc, *in_pos);
+
+ coder->state = state;
+ coder->rep0 = rep0;
+ coder->rep1 = rep1;
+ coder->rep2 = rep2;
+ coder->rep3 = rep3;
+
+ coder->probs = probs;
+ coder->symbol = symbol;
+ coder->limit = limit;
+ coder->offset = offset;
+ coder->len = len;
+
+ // Update the remaining amount of uncompressed data if uncompressed
+ // size was known.
+ if (coder->uncompressed_size != LZMA_VLI_UNKNOWN) {
+ coder->uncompressed_size -= dict.pos - dict_start;
+
+ // Since there cannot be end of payload marker if the
+ // uncompressed size was known, we check here if we
+ // finished decoding.
+ if (coder->uncompressed_size == 0 && ret == LZMA_OK
+ && coder->sequence != SEQ_NORMALIZE)
+ ret = coder->sequence == SEQ_IS_MATCH
+ ? LZMA_STREAM_END : LZMA_DATA_ERROR;
+ }
+
+ // We can do an additional check in the range decoder to catch some
+ // corrupted files.
+ if (ret == LZMA_STREAM_END) {
+ if (!rc_is_finished(coder->rc))
+ ret = LZMA_DATA_ERROR;
+
+ // Reset the range decoder so that it is ready to reinitialize
+ // for a new LZMA2 chunk.
+ rc_reset(coder->rc);
+ }
+
+ return ret;
+}
+
+
+
+static void
+lzma_decoder_uncompressed(lzma_coder *coder, lzma_vli uncompressed_size)
+{
+ coder->uncompressed_size = uncompressed_size;
+}
+
+/*
+extern void
+lzma_lzma_decoder_uncompressed(void *coder_ptr, lzma_vli uncompressed_size)
+{
+ // This is hack.
+ (*(lzma_coder **)(coder))->uncompressed_size = uncompressed_size;
+}
+*/
+
+static void
+lzma_decoder_reset(lzma_coder *coder, const void *opt)
+{
+ uint32_t i, j, pos_state;
+ uint32_t num_pos_states;
+
+ const lzma_options_lzma *options = opt;
+
+ // NOTE: We assume that lc/lp/pb are valid since they were
+ // successfully decoded with lzma_lzma_decode_properties().
+
+ // Calculate pos_mask. We don't need pos_bits as is for anything.
+ coder->pos_mask = (1U << options->pb) - 1;
+
+ // Initialize the literal decoder.
+ literal_init(coder->literal, options->lc, options->lp);
+
+ coder->literal_context_bits = options->lc;
+ coder->literal_pos_mask = (1U << options->lp) - 1;
+
+ // State
+ coder->state = STATE_LIT_LIT;
+ coder->rep0 = 0;
+ coder->rep1 = 0;
+ coder->rep2 = 0;
+ coder->rep3 = 0;
+ coder->pos_mask = (1U << options->pb) - 1;
+
+ // Range decoder
+ rc_reset(coder->rc);
+
+ // Bit and bittree decoders
+ for (i = 0; i < STATES; ++i) {
+ for (j = 0; j <= coder->pos_mask; ++j) {
+ bit_reset(coder->is_match[i][j]);
+ bit_reset(coder->is_rep0_long[i][j]);
+ }
+
+ bit_reset(coder->is_rep[i]);
+ bit_reset(coder->is_rep0[i]);
+ bit_reset(coder->is_rep1[i]);
+ bit_reset(coder->is_rep2[i]);
+ }
+
+ for (i = 0; i < LEN_TO_POS_STATES; ++i)
+ bittree_reset(coder->pos_slot[i], POS_SLOT_BITS);
+
+ for (i = 0; i < FULL_DISTANCES - END_POS_MODEL_INDEX; ++i)
+ bit_reset(coder->pos_special[i]);
+
+ bittree_reset(coder->pos_align, ALIGN_BITS);
+
+ // Len decoders (also bit/bittree)
+ num_pos_states = 1U << options->pb;
+ bit_reset(coder->match_len_decoder.choice);
+ bit_reset(coder->match_len_decoder.choice2);
+ bit_reset(coder->rep_len_decoder.choice);
+ bit_reset(coder->rep_len_decoder.choice2);
+
+ for (pos_state = 0; pos_state < num_pos_states; ++pos_state) {
+ bittree_reset(coder->match_len_decoder.low[pos_state],
+ LEN_LOW_BITS);
+ bittree_reset(coder->match_len_decoder.mid[pos_state],
+ LEN_MID_BITS);
+
+ bittree_reset(coder->rep_len_decoder.low[pos_state],
+ LEN_LOW_BITS);
+ bittree_reset(coder->rep_len_decoder.mid[pos_state],
+ LEN_MID_BITS);
+ }
+
+ bittree_reset(coder->match_len_decoder.high, LEN_HIGH_BITS);
+ bittree_reset(coder->rep_len_decoder.high, LEN_HIGH_BITS);
+
+ coder->sequence = SEQ_IS_MATCH;
+ coder->probs = NULL;
+ coder->symbol = 0;
+ coder->limit = 0;
+ coder->offset = 0;
+ coder->len = 0;
+
+ return;
+}
+
+
+extern lzma_ret
+lzma_lzma_decoder_create(lzma_lz_decoder *lz, lzma_allocator *allocator,
+ const void *opt, lzma_lz_options *lz_options)
+{
+ const lzma_options_lzma *options = opt;
+
+ if (lz->coder == NULL) {
+ lz->coder = lzma_alloc(sizeof(lzma_coder), allocator);
+ if (lz->coder == NULL)
+ return LZMA_MEM_ERROR;
+
+ lz->code = &lzma_decode;
+ lz->reset = &lzma_decoder_reset;
+ lz->set_uncompressed = &lzma_decoder_uncompressed;
+ }
+
+ // All dictionary sizes are OK here. LZ decoder will take care of
+ // the special cases.
+ lz_options->dict_size = options->dict_size;
+ lz_options->preset_dict = options->preset_dict;
+ lz_options->preset_dict_size = options->preset_dict_size;
+
+ return LZMA_OK;
+}
+
+
+/// Allocate and initialize LZMA decoder. This is used only via LZ
+/// initialization (lzma_lzma_decoder_init() passes function pointer to
+/// the LZ initialization).
+static lzma_ret
+lzma_decoder_init(lzma_lz_decoder *lz, lzma_allocator *allocator,
+ const void *options, lzma_lz_options *lz_options)
+{
+ if (!is_lclppb_valid(options))
+ return LZMA_PROG_ERROR;
+
+ return_if_error(lzma_lzma_decoder_create(
+ lz, allocator, options, lz_options));
+
+ lzma_decoder_reset(lz->coder, options);
+ lzma_decoder_uncompressed(lz->coder, LZMA_VLI_UNKNOWN);
+
+ return LZMA_OK;
+}
+
+
+extern lzma_ret
+lzma_lzma_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter_info *filters)
+{
+ // LZMA can only be the last filter in the chain. This is enforced
+ // by the raw_decoder initialization.
+ assert(filters[1].init == NULL);
+
+ return lzma_lz_decoder_init(next, allocator, filters,
+ &lzma_decoder_init);
+}
+
+
+extern bool
+lzma_lzma_lclppb_decode(lzma_options_lzma *options, uint8_t byte)
+{
+ if (byte > (4 * 5 + 4) * 9 + 8)
+ return true;
+
+ // See the file format specification to understand this.
+ options->pb = byte / (9 * 5);
+ byte -= options->pb * 9 * 5;
+ options->lp = byte / 9;
+ options->lc = byte - options->lp * 9;
+
+ return options->lc + options->lp > LZMA_LCLP_MAX;
+}
+
+
+extern uint64_t
+lzma_lzma_decoder_memusage_nocheck(const void *options)
+{
+ const lzma_options_lzma *const opt = options;
+ return sizeof(lzma_coder) + lzma_lz_decoder_memusage(opt->dict_size);
+}
+
+
+extern uint64_t
+lzma_lzma_decoder_memusage(const void *options)
+{
+ if (!is_lclppb_valid(options))
+ return UINT64_MAX;
+
+ return lzma_lzma_decoder_memusage_nocheck(options);
+}
+
+
+extern lzma_ret
+lzma_lzma_props_decode(void **options, lzma_allocator *allocator,
+ const uint8_t *props, size_t props_size)
+{
+ lzma_options_lzma *opt;
+
+ if (props_size != 5)
+ return LZMA_OPTIONS_ERROR;
+
+ opt = lzma_alloc(sizeof(lzma_options_lzma), allocator);
+ if (opt == NULL)
+ return LZMA_MEM_ERROR;
+
+ if (lzma_lzma_lclppb_decode(opt, props[0]))
+ goto error;
+
+ // All dictionary sizes are accepted, including zero. LZ decoder
+ // will automatically use a dictionary at least a few KiB even if
+ // a smaller dictionary is requested.
+ opt->dict_size = unaligned_read32le(props + 1);
+
+ opt->preset_dict = NULL;
+ opt->preset_dict_size = 0;
+
+ *options = opt;
+
+ return LZMA_OK;
+
+error:
+ lzma_free(opt, allocator);
+ return LZMA_OPTIONS_ERROR;
+}
diff --git a/Utilities/cmliblzma/liblzma/lzma/lzma_decoder.h b/Utilities/cmliblzma/liblzma/lzma/lzma_decoder.h
new file mode 100644
index 000000000..a463a76fc
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/lzma/lzma_decoder.h
@@ -0,0 +1,52 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file lzma_decoder.h
+/// \brief LZMA decoder API
+///
+// Authors: Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_LZMA_DECODER_H
+#define LZMA_LZMA_DECODER_H
+
+#include "common.h"
+
+
+/// Allocates and initializes LZMA decoder
+extern lzma_ret lzma_lzma_decoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters);
+
+extern uint64_t lzma_lzma_decoder_memusage(const void *options);
+
+extern lzma_ret lzma_lzma_props_decode(
+ void **options, lzma_allocator *allocator,
+ const uint8_t *props, size_t props_size);
+
+
+/// \brief Decodes the LZMA Properties byte (lc/lp/pb)
+///
+/// \return true if error occurred, false on success
+///
+extern bool lzma_lzma_lclppb_decode(
+ lzma_options_lzma *options, uint8_t byte);
+
+
+#ifdef LZMA_LZ_DECODER_H
+/// Allocate and setup function pointers only. This is used by LZMA1 and
+/// LZMA2 decoders.
+extern lzma_ret lzma_lzma_decoder_create(
+ lzma_lz_decoder *lz, lzma_allocator *allocator,
+ const void *opt, lzma_lz_options *lz_options);
+
+/// Gets memory usage without validating lc/lp/pb. This is used by LZMA2
+/// decoder, because raw LZMA2 decoding doesn't need lc/lp/pb.
+extern uint64_t lzma_lzma_decoder_memusage_nocheck(const void *options);
+
+#endif
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/lzma/lzma_encoder.c b/Utilities/cmliblzma/liblzma/lzma/lzma_encoder.c
new file mode 100644
index 000000000..e8738f411
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/lzma/lzma_encoder.c
@@ -0,0 +1,695 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file lzma_encoder.c
+/// \brief LZMA encoder
+///
+// Authors: Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "lzma2_encoder.h"
+#include "lzma_encoder_private.h"
+#include "fastpos.h"
+
+
+/////////////
+// Literal //
+/////////////
+
+static inline void
+literal_matched(lzma_range_encoder *rc, probability *subcoder,
+ uint32_t match_byte, uint32_t symbol)
+{
+ uint32_t offset = 0x100;
+ symbol += UINT32_C(1) << 8;
+
+ do {
+ uint32_t match_bit;
+ uint32_t subcoder_index;
+ uint32_t bit;
+
+ match_byte <<= 1;
+ match_bit = match_byte & offset;
+ subcoder_index = offset + match_bit + (symbol >> 8);
+ bit = (symbol >> 7) & 1;
+ rc_bit(rc, &subcoder[subcoder_index], bit);
+
+ symbol <<= 1;
+ offset &= ~(match_byte ^ symbol);
+
+ } while (symbol < (UINT32_C(1) << 16));
+}
+
+
+static inline void
+literal(lzma_coder *coder, lzma_mf *mf, uint32_t position)
+{
+ // Locate the literal byte to be encoded and the subcoder.
+ const uint8_t cur_byte = mf->buffer[
+ mf->read_pos - mf->read_ahead];
+ probability *subcoder = literal_subcoder(coder->literal,
+ coder->literal_context_bits, coder->literal_pos_mask,
+ position, mf->buffer[mf->read_pos - mf->read_ahead - 1]);
+
+ if (is_literal_state(coder->state)) {
+ // Previous LZMA-symbol was a literal. Encode a normal
+ // literal without a match byte.
+ rc_bittree(&coder->rc, subcoder, 8, cur_byte);
+ } else {
+ // Previous LZMA-symbol was a match. Use the last byte of
+ // the match as a "match byte". That is, compare the bits
+ // of the current literal and the match byte.
+ const uint8_t match_byte = mf->buffer[
+ mf->read_pos - coder->reps[0] - 1
+ - mf->read_ahead];
+ literal_matched(&coder->rc, subcoder, match_byte, cur_byte);
+ }
+
+ update_literal(coder->state);
+}
+
+
+//////////////////
+// Match length //
+//////////////////
+
+static void
+length_update_prices(lzma_length_encoder *lc, const uint32_t pos_state)
+{
+ uint32_t a0, a1, b0, b1;
+ uint32_t *prices;
+ uint32_t i;
+
+ const uint32_t table_size = lc->table_size;
+ lc->counters[pos_state] = table_size;
+
+ a0 = rc_bit_0_price(lc->choice);
+ a1 = rc_bit_1_price(lc->choice);
+ b0 = a1 + rc_bit_0_price(lc->choice2);
+ b1 = a1 + rc_bit_1_price(lc->choice2);
+ prices = lc->prices[pos_state];
+
+ for (i = 0; i < table_size && i < LEN_LOW_SYMBOLS; ++i)
+ prices[i] = a0 + rc_bittree_price(lc->low[pos_state],
+ LEN_LOW_BITS, i);
+
+ for (; i < table_size && i < LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS; ++i)
+ prices[i] = b0 + rc_bittree_price(lc->mid[pos_state],
+ LEN_MID_BITS, i - LEN_LOW_SYMBOLS);
+
+ for (; i < table_size; ++i)
+ prices[i] = b1 + rc_bittree_price(lc->high, LEN_HIGH_BITS,
+ i - LEN_LOW_SYMBOLS - LEN_MID_SYMBOLS);
+
+ return;
+}
+
+
+static inline void
+length(lzma_range_encoder *rc, lzma_length_encoder *lc,
+ const uint32_t pos_state, uint32_t len, const bool fast_mode)
+{
+ assert(len <= MATCH_LEN_MAX);
+ len -= MATCH_LEN_MIN;
+
+ if (len < LEN_LOW_SYMBOLS) {
+ rc_bit(rc, &lc->choice, 0);
+ rc_bittree(rc, lc->low[pos_state], LEN_LOW_BITS, len);
+ } else {
+ rc_bit(rc, &lc->choice, 1);
+ len -= LEN_LOW_SYMBOLS;
+
+ if (len < LEN_MID_SYMBOLS) {
+ rc_bit(rc, &lc->choice2, 0);
+ rc_bittree(rc, lc->mid[pos_state], LEN_MID_BITS, len);
+ } else {
+ rc_bit(rc, &lc->choice2, 1);
+ len -= LEN_MID_SYMBOLS;
+ rc_bittree(rc, lc->high, LEN_HIGH_BITS, len);
+ }
+ }
+
+ // Only getoptimum uses the prices so don't update the table when
+ // in fast mode.
+ if (!fast_mode)
+ if (--lc->counters[pos_state] == 0)
+ length_update_prices(lc, pos_state);
+}
+
+
+///////////
+// Match //
+///////////
+
+static inline void
+match(lzma_coder *coder, const uint32_t pos_state,
+ const uint32_t distance, const uint32_t len)
+{
+ uint32_t pos_slot;
+ uint32_t len_to_pos_state;
+
+ update_match(coder->state);
+
+ length(&coder->rc, &coder->match_len_encoder, pos_state, len,
+ coder->fast_mode);
+
+ pos_slot = get_pos_slot(distance);
+ len_to_pos_state = get_len_to_pos_state(len);
+ rc_bittree(&coder->rc, coder->pos_slot[len_to_pos_state],
+ POS_SLOT_BITS, pos_slot);
+
+ if (pos_slot >= START_POS_MODEL_INDEX) {
+ const uint32_t footer_bits = (pos_slot >> 1) - 1;
+ const uint32_t base = (2 | (pos_slot & 1)) << footer_bits;
+ const uint32_t pos_reduced = distance - base;
+
+ if (pos_slot < END_POS_MODEL_INDEX) {
+ // Careful here: base - pos_slot - 1 can be -1, but
+ // rc_bittree_reverse starts at probs[1], not probs[0].
+ rc_bittree_reverse(&coder->rc,
+ coder->pos_special + base - pos_slot - 1,
+ footer_bits, pos_reduced);
+ } else {
+ rc_direct(&coder->rc, pos_reduced >> ALIGN_BITS,
+ footer_bits - ALIGN_BITS);
+ rc_bittree_reverse(
+ &coder->rc, coder->pos_align,
+ ALIGN_BITS, pos_reduced & ALIGN_MASK);
+ ++coder->align_price_count;
+ }
+ }
+
+ coder->reps[3] = coder->reps[2];
+ coder->reps[2] = coder->reps[1];
+ coder->reps[1] = coder->reps[0];
+ coder->reps[0] = distance;
+ ++coder->match_price_count;
+}
+
+
+////////////////////
+// Repeated match //
+////////////////////
+
+static inline void
+rep_match(lzma_coder *coder, const uint32_t pos_state,
+ const uint32_t rep, const uint32_t len)
+{
+ if (rep == 0) {
+ rc_bit(&coder->rc, &coder->is_rep0[coder->state], 0);
+ rc_bit(&coder->rc,
+ &coder->is_rep0_long[coder->state][pos_state],
+ len != 1);
+ } else {
+ const uint32_t distance = coder->reps[rep];
+ rc_bit(&coder->rc, &coder->is_rep0[coder->state], 1);
+
+ if (rep == 1) {
+ rc_bit(&coder->rc, &coder->is_rep1[coder->state], 0);
+ } else {
+ rc_bit(&coder->rc, &coder->is_rep1[coder->state], 1);
+ rc_bit(&coder->rc, &coder->is_rep2[coder->state],
+ rep - 2);
+
+ if (rep == 3)
+ coder->reps[3] = coder->reps[2];
+
+ coder->reps[2] = coder->reps[1];
+ }
+
+ coder->reps[1] = coder->reps[0];
+ coder->reps[0] = distance;
+ }
+
+ if (len == 1) {
+ update_short_rep(coder->state);
+ } else {
+ length(&coder->rc, &coder->rep_len_encoder, pos_state, len,
+ coder->fast_mode);
+ update_long_rep(coder->state);
+ }
+}
+
+
+//////////
+// Main //
+//////////
+
+static void
+encode_symbol(lzma_coder *coder, lzma_mf *mf,
+ uint32_t back, uint32_t len, uint32_t position)
+{
+ const uint32_t pos_state = position & coder->pos_mask;
+
+ if (back == UINT32_MAX) {
+ // Literal i.e. eight-bit byte
+ assert(len == 1);
+ rc_bit(&coder->rc,
+ &coder->is_match[coder->state][pos_state], 0);
+ literal(coder, mf, position);
+ } else {
+ // Some type of match
+ rc_bit(&coder->rc,
+ &coder->is_match[coder->state][pos_state], 1);
+
+ if (back < REP_DISTANCES) {
+ // It's a repeated match i.e. the same distance
+ // has been used earlier.
+ rc_bit(&coder->rc, &coder->is_rep[coder->state], 1);
+ rep_match(coder, pos_state, back, len);
+ } else {
+ // Normal match
+ rc_bit(&coder->rc, &coder->is_rep[coder->state], 0);
+ match(coder, pos_state, back - REP_DISTANCES, len);
+ }
+ }
+
+ assert(mf->read_ahead >= len);
+ mf->read_ahead -= len;
+}
+
+
+static bool
+encode_init(lzma_coder *coder, lzma_mf *mf)
+{
+ assert(mf_position(mf) == 0);
+
+ if (mf->read_pos == mf->read_limit) {
+ if (mf->action == LZMA_RUN)
+ return false; // We cannot do anything.
+
+ // We are finishing (we cannot get here when flushing).
+ assert(mf->write_pos == mf->read_pos);
+ assert(mf->action == LZMA_FINISH);
+ } else {
+ // Do the actual initialization. The first LZMA symbol must
+ // always be a literal.
+ mf_skip(mf, 1);
+ mf->read_ahead = 0;
+ rc_bit(&coder->rc, &coder->is_match[0][0], 0);
+ rc_bittree(&coder->rc, coder->literal[0], 8, mf->buffer[0]);
+ }
+
+ // Initialization is done (except if empty file).
+ coder->is_initialized = true;
+
+ return true;
+}
+
+
+static void
+encode_eopm(lzma_coder *coder, uint32_t position)
+{
+ const uint32_t pos_state = position & coder->pos_mask;
+ rc_bit(&coder->rc, &coder->is_match[coder->state][pos_state], 1);
+ rc_bit(&coder->rc, &coder->is_rep[coder->state], 0);
+ match(coder, pos_state, UINT32_MAX, MATCH_LEN_MIN);
+}
+
+
+/// Number of bytes that a single encoding loop in lzma_lzma_encode() can
+/// consume from the dictionary. This limit comes from lzma_lzma_optimum()
+/// and may need to be updated if that function is significantly modified.
+#define LOOP_INPUT_MAX (OPTS + 1)
+
+
+extern lzma_ret
+lzma_lzma_encode(lzma_coder *LZMA_RESTRICT coder, lzma_mf *LZMA_RESTRICT mf,
+ uint8_t *LZMA_RESTRICT out, size_t *LZMA_RESTRICT out_pos,
+ size_t out_size, uint32_t limit)
+{
+ uint32_t position;
+
+ // Initialize the stream if no data has been encoded yet.
+ if (!coder->is_initialized && !encode_init(coder, mf))
+ return LZMA_OK;
+
+ // Get the lowest bits of the uncompressed offset from the LZ layer.
+ position = mf_position(mf);
+
+ while (true) {
+ uint32_t len;
+ uint32_t back;
+
+ // Encode pending bits, if any. Calling this before encoding
+ // the next symbol is needed only with plain LZMA, since
+ // LZMA2 always provides big enough buffer to flush
+ // everything out from the range encoder. For the same reason,
+ // rc_encode() never returns true when this function is used
+ // as part of LZMA2 encoder.
+ if (rc_encode(&coder->rc, out, out_pos, out_size)) {
+ assert(limit == UINT32_MAX);
+ return LZMA_OK;
+ }
+
+ // With LZMA2 we need to take care that compressed size of
+ // a chunk doesn't get too big.
+ // FIXME? Check if this could be improved.
+ if (limit != UINT32_MAX
+ && (mf->read_pos - mf->read_ahead >= limit
+ || *out_pos + rc_pending(&coder->rc)
+ >= LZMA2_CHUNK_MAX
+ - LOOP_INPUT_MAX))
+ break;
+
+ // Check that there is some input to process.
+ if (mf->read_pos >= mf->read_limit) {
+ if (mf->action == LZMA_RUN)
+ return LZMA_OK;
+
+ if (mf->read_ahead == 0)
+ break;
+ }
+
+ // Get optimal match (repeat position and length).
+ // Value ranges for pos:
+ // - [0, REP_DISTANCES): repeated match
+ // - [REP_DISTANCES, UINT32_MAX):
+ // match at (pos - REP_DISTANCES)
+ // - UINT32_MAX: not a match but a literal
+ // Value ranges for len:
+ // - [MATCH_LEN_MIN, MATCH_LEN_MAX]
+
+ if (coder->fast_mode)
+ lzma_lzma_optimum_fast(coder, mf, &back, &len);
+ else
+ lzma_lzma_optimum_normal(
+ coder, mf, &back, &len, position);
+
+ encode_symbol(coder, mf, back, len, position);
+
+ position += len;
+ }
+
+ if (!coder->is_flushed) {
+ coder->is_flushed = true;
+
+ // We don't support encoding plain LZMA streams without EOPM,
+ // and LZMA2 doesn't use EOPM at LZMA level.
+ if (limit == UINT32_MAX)
+ encode_eopm(coder, position);
+
+ // Flush the remaining bytes from the range encoder.
+ rc_flush(&coder->rc);
+
+ // Copy the remaining bytes to the output buffer. If there
+ // isn't enough output space, we will copy out the remaining
+ // bytes on the next call to this function by using
+ // the rc_encode() call in the encoding loop above.
+ if (rc_encode(&coder->rc, out, out_pos, out_size)) {
+ assert(limit == UINT32_MAX);
+ return LZMA_OK;
+ }
+ }
+
+ // Make it ready for the next LZMA2 chunk.
+ coder->is_flushed = false;
+
+ return LZMA_STREAM_END;
+}
+
+
+static lzma_ret
+lzma_encode(lzma_coder *LZMA_RESTRICT coder, lzma_mf *LZMA_RESTRICT mf,
+ uint8_t *LZMA_RESTRICT out, size_t *LZMA_RESTRICT out_pos,
+ size_t out_size)
+{
+ // Plain LZMA has no support for sync-flushing.
+ if (unlikely(mf->action == LZMA_SYNC_FLUSH))
+ return LZMA_OPTIONS_ERROR;
+
+ return lzma_lzma_encode(coder, mf, out, out_pos, out_size, UINT32_MAX);
+}
+
+
+////////////////////
+// Initialization //
+////////////////////
+
+static bool
+is_options_valid(const lzma_options_lzma *options)
+{
+ // Validate some of the options. LZ encoder validates nice_len too
+ // but we need a valid value here earlier.
+ return is_lclppb_valid(options)
+ && options->nice_len >= MATCH_LEN_MIN
+ && options->nice_len <= MATCH_LEN_MAX
+ && (options->mode == LZMA_MODE_FAST
+ || options->mode == LZMA_MODE_NORMAL);
+}
+
+
+static void
+set_lz_options(lzma_lz_options *lz_options, const lzma_options_lzma *options)
+{
+ // LZ encoder initialization does the validation for these so we
+ // don't need to validate here.
+ lz_options->before_size = OPTS;
+ lz_options->dict_size = options->dict_size;
+ lz_options->after_size = LOOP_INPUT_MAX;
+ lz_options->match_len_max = MATCH_LEN_MAX;
+ lz_options->nice_len = options->nice_len;
+ lz_options->match_finder = options->mf;
+ lz_options->depth = options->depth;
+ lz_options->preset_dict = options->preset_dict;
+ lz_options->preset_dict_size = options->preset_dict_size;
+ return;
+}
+
+
+static void
+length_encoder_reset(lzma_length_encoder *lencoder,
+ const uint32_t num_pos_states, const bool fast_mode)
+{
+ size_t pos_state;
+
+ bit_reset(lencoder->choice);
+ bit_reset(lencoder->choice2);
+
+ for (pos_state = 0; pos_state < num_pos_states; ++pos_state) {
+ bittree_reset(lencoder->low[pos_state], LEN_LOW_BITS);
+ bittree_reset(lencoder->mid[pos_state], LEN_MID_BITS);
+ }
+
+ bittree_reset(lencoder->high, LEN_HIGH_BITS);
+
+ if (!fast_mode)
+ for (pos_state = 0; pos_state < num_pos_states;
+ ++pos_state)
+ length_update_prices(lencoder, pos_state);
+
+ return;
+}
+
+
+extern lzma_ret
+lzma_lzma_encoder_reset(lzma_coder *coder, const lzma_options_lzma *options)
+{
+ size_t i, j;
+
+ if (!is_options_valid(options))
+ return LZMA_OPTIONS_ERROR;
+
+ coder->pos_mask = (1U << options->pb) - 1;
+ coder->literal_context_bits = options->lc;
+ coder->literal_pos_mask = (1U << options->lp) - 1;
+
+ // Range coder
+ rc_reset(&coder->rc);
+
+ // State
+ coder->state = STATE_LIT_LIT;
+ for (i = 0; i < REP_DISTANCES; ++i)
+ coder->reps[i] = 0;
+
+ literal_init(coder->literal, options->lc, options->lp);
+
+ // Bit encoders
+ for (i = 0; i < STATES; ++i) {
+ for (j = 0; j <= coder->pos_mask; ++j) {
+ bit_reset(coder->is_match[i][j]);
+ bit_reset(coder->is_rep0_long[i][j]);
+ }
+
+ bit_reset(coder->is_rep[i]);
+ bit_reset(coder->is_rep0[i]);
+ bit_reset(coder->is_rep1[i]);
+ bit_reset(coder->is_rep2[i]);
+ }
+
+ for (i = 0; i < FULL_DISTANCES - END_POS_MODEL_INDEX; ++i)
+ bit_reset(coder->pos_special[i]);
+
+ // Bit tree encoders
+ for (i = 0; i < LEN_TO_POS_STATES; ++i)
+ bittree_reset(coder->pos_slot[i], POS_SLOT_BITS);
+
+ bittree_reset(coder->pos_align, ALIGN_BITS);
+
+ // Length encoders
+ length_encoder_reset(&coder->match_len_encoder,
+ 1U << options->pb, coder->fast_mode);
+
+ length_encoder_reset(&coder->rep_len_encoder,
+ 1U << options->pb, coder->fast_mode);
+
+ // Price counts are incremented every time appropriate probabilities
+ // are changed. price counts are set to zero when the price tables
+ // are updated, which is done when the appropriate price counts have
+ // big enough value, and lzma_mf.read_ahead == 0 which happens at
+ // least every OPTS (a few thousand) possible price count increments.
+ //
+ // By resetting price counts to UINT32_MAX / 2, we make sure that the
+ // price tables will be initialized before they will be used (since
+ // the value is definitely big enough), and that it is OK to increment
+ // price counts without risk of integer overflow (since UINT32_MAX / 2
+ // is small enough). The current code doesn't increment price counts
+ // before initializing price tables, but it maybe done in future if
+ // we add support for saving the state between LZMA2 chunks.
+ coder->match_price_count = UINT32_MAX / 2;
+ coder->align_price_count = UINT32_MAX / 2;
+
+ coder->opts_end_index = 0;
+ coder->opts_current_index = 0;
+
+ return LZMA_OK;
+}
+
+
+extern lzma_ret
+lzma_lzma_encoder_create(lzma_coder **coder_ptr, lzma_allocator *allocator,
+ const lzma_options_lzma *options, lzma_lz_options *lz_options)
+{
+ lzma_coder *coder;
+ uint32_t log_size = 0;
+
+ // Allocate lzma_coder if it wasn't already allocated.
+ if (*coder_ptr == NULL) {
+ *coder_ptr = lzma_alloc(sizeof(lzma_coder), allocator);
+ if (*coder_ptr == NULL)
+ return LZMA_MEM_ERROR;
+ }
+
+ coder = *coder_ptr;
+
+ // Set compression mode. We haven't validates the options yet,
+ // but it's OK here, since nothing bad happens with invalid
+ // options in the code below, and they will get rejected by
+ // lzma_lzma_encoder_reset() call at the end of this function.
+ switch (options->mode) {
+ case LZMA_MODE_FAST:
+ coder->fast_mode = true;
+ break;
+
+ case LZMA_MODE_NORMAL: {
+ coder->fast_mode = false;
+
+ // Set dist_table_size.
+ // Round the dictionary size up to next 2^n.
+ while ((UINT32_C(1) << log_size) < options->dict_size)
+ ++log_size;
+
+ coder->dist_table_size = log_size * 2;
+
+ // Length encoders' price table size
+ coder->match_len_encoder.table_size
+ = options->nice_len + 1 - MATCH_LEN_MIN;
+ coder->rep_len_encoder.table_size
+ = options->nice_len + 1 - MATCH_LEN_MIN;
+ break;
+ }
+
+ default:
+ return LZMA_OPTIONS_ERROR;
+ }
+
+ // We don't need to write the first byte as literal if there is
+ // a non-empty preset dictionary. encode_init() wouldn't even work
+ // if there is a non-empty preset dictionary, because encode_init()
+ // assumes that position is zero and previous byte is also zero.
+ coder->is_initialized = options->preset_dict != NULL
+ && options->preset_dict_size > 0;
+ coder->is_flushed = false;
+
+ set_lz_options(lz_options, options);
+
+ return lzma_lzma_encoder_reset(coder, options);
+}
+
+
+static lzma_ret
+lzma_encoder_init(lzma_lz_encoder *lz, lzma_allocator *allocator,
+ const void *options, lzma_lz_options *lz_options)
+{
+ lz->code = &lzma_encode;
+ return lzma_lzma_encoder_create(
+ &lz->coder, allocator, options, lz_options);
+}
+
+
+extern lzma_ret
+lzma_lzma_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter_info *filters)
+{
+ return lzma_lz_encoder_init(
+ next, allocator, filters, &lzma_encoder_init);
+}
+
+
+extern uint64_t
+lzma_lzma_encoder_memusage(const void *options)
+{
+ lzma_lz_options lz_options;
+ uint64_t lz_memusage;
+
+ if (!is_options_valid(options))
+ return UINT64_MAX;
+
+ set_lz_options(&lz_options, options);
+
+ lz_memusage = lzma_lz_encoder_memusage(&lz_options);
+ if (lz_memusage == UINT64_MAX)
+ return UINT64_MAX;
+
+ return (uint64_t)(sizeof(lzma_coder)) + lz_memusage;
+}
+
+
+extern bool
+lzma_lzma_lclppb_encode(const lzma_options_lzma *options, uint8_t *byte)
+{
+ if (!is_lclppb_valid(options))
+ return true;
+
+ *byte = (options->pb * 5 + options->lp) * 9 + options->lc;
+ assert(*byte <= (4 * 5 + 4) * 9 + 8);
+
+ return false;
+}
+
+
+#ifdef HAVE_ENCODER_LZMA1
+extern lzma_ret
+lzma_lzma_props_encode(const void *options, uint8_t *out)
+{
+ const lzma_options_lzma *const opt = options;
+
+ if (lzma_lzma_lclppb_encode(opt, out))
+ return LZMA_PROG_ERROR;
+
+ unaligned_write32le(out + 1, opt->dict_size);
+
+ return LZMA_OK;
+}
+#endif
+
+
+extern LZMA_API(lzma_bool)
+lzma_mode_is_supported(lzma_mode mode)
+{
+ return mode == LZMA_MODE_FAST || mode == LZMA_MODE_NORMAL;
+}
diff --git a/Utilities/cmliblzma/liblzma/lzma/lzma_encoder.h b/Utilities/cmliblzma/liblzma/lzma/lzma_encoder.h
new file mode 100644
index 000000000..abb8d8b46
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/lzma/lzma_encoder.h
@@ -0,0 +1,54 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file lzma_encoder.h
+/// \brief LZMA encoder API
+///
+// Authors: Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_LZMA_ENCODER_H
+#define LZMA_LZMA_ENCODER_H
+
+#include "common.h"
+
+
+extern lzma_ret lzma_lzma_encoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters);
+
+
+extern uint64_t lzma_lzma_encoder_memusage(const void *options);
+
+extern lzma_ret lzma_lzma_props_encode(const void *options, uint8_t *out);
+
+
+/// Encodes lc/lp/pb into one byte. Returns false on success and true on error.
+extern bool lzma_lzma_lclppb_encode(
+ const lzma_options_lzma *options, uint8_t *byte);
+
+
+#ifdef LZMA_LZ_ENCODER_H
+
+/// Initializes raw LZMA encoder; this is used by LZMA2.
+extern lzma_ret lzma_lzma_encoder_create(
+ lzma_coder **coder_ptr, lzma_allocator *allocator,
+ const lzma_options_lzma *options, lzma_lz_options *lz_options);
+
+
+/// Resets an already initialized LZMA encoder; this is used by LZMA2.
+extern lzma_ret lzma_lzma_encoder_reset(
+ lzma_coder *coder, const lzma_options_lzma *options);
+
+
+extern lzma_ret lzma_lzma_encode(lzma_coder *LZMA_RESTRICT coder,
+ lzma_mf *LZMA_RESTRICT mf, uint8_t *LZMA_RESTRICT out,
+ size_t *LZMA_RESTRICT out_pos, size_t out_size,
+ uint32_t read_limit);
+
+#endif
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/lzma/lzma_encoder_optimum_fast.c b/Utilities/cmliblzma/liblzma/lzma/lzma_encoder_optimum_fast.c
new file mode 100644
index 000000000..f98312643
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/lzma/lzma_encoder_optimum_fast.c
@@ -0,0 +1,185 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file lzma_encoder_optimum_fast.c
+//
+// Author: Igor Pavlov
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "lzma_encoder_private.h"
+
+
+#define change_pair(small_dist, big_dist) \
+ (((big_dist) >> 7) > (small_dist))
+
+
+extern void
+lzma_lzma_optimum_fast(lzma_coder *LZMA_RESTRICT coder, lzma_mf *LZMA_RESTRICT mf,
+ uint32_t *LZMA_RESTRICT back_res, uint32_t *LZMA_RESTRICT len_res)
+{
+ const uint8_t *buf;
+ uint32_t buf_avail;
+ uint32_t i;
+ uint32_t rep_len = 0;
+ uint32_t rep_index = 0;
+ uint32_t back_main = 0;
+ uint32_t limit;
+
+ const uint32_t nice_len = mf->nice_len;
+
+ uint32_t len_main;
+ uint32_t matches_count;
+ if (mf->read_ahead == 0) {
+ len_main = mf_find(mf, &matches_count, coder->matches);
+ } else {
+ assert(mf->read_ahead == 1);
+ len_main = coder->longest_match_length;
+ matches_count = coder->matches_count;
+ }
+
+ buf = mf_ptr(mf) - 1;
+ buf_avail = my_min(mf_avail(mf) + 1, MATCH_LEN_MAX);
+
+ if (buf_avail < 2) {
+ // There's not enough input left to encode a match.
+ *back_res = UINT32_MAX;
+ *len_res = 1;
+ return;
+ }
+
+ // Look for repeated matches; scan the previous four match distances
+ for (i = 0; i < REP_DISTANCES; ++i) {
+ uint32_t len;
+
+ // Pointer to the beginning of the match candidate
+ const uint8_t *const buf_back = buf - coder->reps[i] - 1;
+
+ // If the first two bytes (2 == MATCH_LEN_MIN) do not match,
+ // this rep is not useful.
+ if (not_equal_16(buf, buf_back))
+ continue;
+
+ // The first two bytes matched.
+ // Calculate the length of the match.
+ for (len = 2; len < buf_avail
+ && buf[len] == buf_back[len]; ++len) ;
+
+ // If we have found a repeated match that is at least
+ // nice_len long, return it immediately.
+ if (len >= nice_len) {
+ *back_res = i;
+ *len_res = len;
+ mf_skip(mf, len - 1);
+ return;
+ }
+
+ if (len > rep_len) {
+ rep_index = i;
+ rep_len = len;
+ }
+ }
+
+ // We didn't find a long enough repeated match. Encode it as a normal
+ // match if the match length is at least nice_len.
+ if (len_main >= nice_len) {
+ *back_res = coder->matches[matches_count - 1].dist
+ + REP_DISTANCES;
+ *len_res = len_main;
+ mf_skip(mf, len_main - 1);
+ return;
+ }
+
+ if (len_main >= 2) {
+ back_main = coder->matches[matches_count - 1].dist;
+
+ while (matches_count > 1 && len_main ==
+ coder->matches[matches_count - 2].len + 1) {
+ if (!change_pair(coder->matches[
+ matches_count - 2].dist,
+ back_main))
+ break;
+
+ --matches_count;
+ len_main = coder->matches[matches_count - 1].len;
+ back_main = coder->matches[matches_count - 1].dist;
+ }
+
+ if (len_main == 2 && back_main >= 0x80)
+ len_main = 1;
+ }
+
+ if (rep_len >= 2) {
+ if (rep_len + 1 >= len_main
+ || (rep_len + 2 >= len_main
+ && back_main > (UINT32_C(1) << 9))
+ || (rep_len + 3 >= len_main
+ && back_main > (UINT32_C(1) << 15))) {
+ *back_res = rep_index;
+ *len_res = rep_len;
+ mf_skip(mf, rep_len - 1);
+ return;
+ }
+ }
+
+ if (len_main < 2 || buf_avail <= 2) {
+ *back_res = UINT32_MAX;
+ *len_res = 1;
+ return;
+ }
+
+ // Get the matches for the next byte. If we find a better match,
+ // the current byte is encoded as a literal.
+ coder->longest_match_length = mf_find(mf,
+ &coder->matches_count, coder->matches);
+
+ if (coder->longest_match_length >= 2) {
+ const uint32_t new_dist = coder->matches[
+ coder->matches_count - 1].dist;
+
+ if ((coder->longest_match_length >= len_main
+ && new_dist < back_main)
+ || (coder->longest_match_length == len_main + 1
+ && !change_pair(back_main, new_dist))
+ || (coder->longest_match_length > len_main + 1)
+ || (coder->longest_match_length + 1 >= len_main
+ && len_main >= 3
+ && change_pair(new_dist, back_main))) {
+ *back_res = UINT32_MAX;
+ *len_res = 1;
+ return;
+ }
+ }
+
+ // In contrast to LZMA SDK, dictionary could not have been moved
+ // between mf_find() calls, thus it is safe to just increment
+ // the old buf pointer instead of recalculating it with mf_ptr().
+ ++buf;
+
+ limit = len_main - 1;
+
+ for (i = 0; i < REP_DISTANCES; ++i) {
+ uint32_t len;
+
+ const uint8_t *const buf_back = buf - coder->reps[i] - 1;
+
+ if (not_equal_16(buf, buf_back))
+ continue;
+
+ for (len = 2; len < limit
+ && buf[len] == buf_back[len]; ++len) ;
+
+ if (len >= limit) {
+ *back_res = UINT32_MAX;
+ *len_res = 1;
+ return;
+ }
+ }
+
+ *back_res = back_main + REP_DISTANCES;
+ *len_res = len_main;
+ mf_skip(mf, len_main - 2);
+ return;
+}
diff --git a/Utilities/cmliblzma/liblzma/lzma/lzma_encoder_optimum_normal.c b/Utilities/cmliblzma/liblzma/lzma/lzma_encoder_optimum_normal.c
new file mode 100644
index 000000000..d3a63485c
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/lzma/lzma_encoder_optimum_normal.c
@@ -0,0 +1,925 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file lzma_encoder_optimum_normal.c
+//
+// Author: Igor Pavlov
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "lzma_encoder_private.h"
+#include "fastpos.h"
+
+
+////////////
+// Prices //
+////////////
+
+static uint32_t
+get_literal_price(const lzma_coder *const coder, const uint32_t pos,
+ const uint32_t prev_byte, const bool match_mode,
+ uint32_t match_byte, uint32_t symbol)
+{
+ const probability *const subcoder = literal_subcoder(coder->literal,
+ coder->literal_context_bits, coder->literal_pos_mask,
+ pos, prev_byte);
+
+ uint32_t price = 0;
+
+ if (!match_mode) {
+ price = rc_bittree_price(subcoder, 8, symbol);
+ } else {
+ uint32_t offset = 0x100;
+ symbol += UINT32_C(1) << 8;
+
+ do {
+ uint32_t match_bit;
+ uint32_t subcoder_index;
+ uint32_t bit;
+
+ match_byte <<= 1;
+
+ match_bit = match_byte & offset;
+ subcoder_index = offset + match_bit + (symbol >> 8);
+ bit = (symbol >> 7) & 1;
+ price += rc_bit_price(subcoder[subcoder_index], bit);
+
+ symbol <<= 1;
+ offset &= ~(match_byte ^ symbol);
+
+ } while (symbol < (UINT32_C(1) << 16));
+ }
+
+ return price;
+}
+
+
+static inline uint32_t
+get_len_price(const lzma_length_encoder *const lencoder,
+ const uint32_t len, const uint32_t pos_state)
+{
+ // NOTE: Unlike the other price tables, length prices are updated
+ // in lzma_encoder.c
+ return lencoder->prices[pos_state][len - MATCH_LEN_MIN];
+}
+
+
+static inline uint32_t
+get_short_rep_price(const lzma_coder *const coder,
+ const lzma_lzma_state state, const uint32_t pos_state)
+{
+ return rc_bit_0_price(coder->is_rep0[state])
+ + rc_bit_0_price(coder->is_rep0_long[state][pos_state]);
+}
+
+
+static inline uint32_t
+get_pure_rep_price(const lzma_coder *const coder, const uint32_t rep_index,
+ const lzma_lzma_state state, uint32_t pos_state)
+{
+ uint32_t price;
+
+ if (rep_index == 0) {
+ price = rc_bit_0_price(coder->is_rep0[state]);
+ price += rc_bit_1_price(coder->is_rep0_long[state][pos_state]);
+ } else {
+ price = rc_bit_1_price(coder->is_rep0[state]);
+
+ if (rep_index == 1) {
+ price += rc_bit_0_price(coder->is_rep1[state]);
+ } else {
+ price += rc_bit_1_price(coder->is_rep1[state]);
+ price += rc_bit_price(coder->is_rep2[state],
+ rep_index - 2);
+ }
+ }
+
+ return price;
+}
+
+
+static inline uint32_t
+get_rep_price(const lzma_coder *const coder, const uint32_t rep_index,
+ const uint32_t len, const lzma_lzma_state state,
+ const uint32_t pos_state)
+{
+ return get_len_price(&coder->rep_len_encoder, len, pos_state)
+ + get_pure_rep_price(coder, rep_index, state, pos_state);
+}
+
+
+static inline uint32_t
+get_pos_len_price(const lzma_coder *const coder, const uint32_t pos,
+ const uint32_t len, const uint32_t pos_state)
+{
+ const uint32_t len_to_pos_state = get_len_to_pos_state(len);
+ uint32_t price;
+
+ if (pos < FULL_DISTANCES) {
+ price = coder->distances_prices[len_to_pos_state][pos];
+ } else {
+ const uint32_t pos_slot = get_pos_slot_2(pos);
+ price = coder->pos_slot_prices[len_to_pos_state][pos_slot]
+ + coder->align_prices[pos & ALIGN_MASK];
+ }
+
+ price += get_len_price(&coder->match_len_encoder, len, pos_state);
+
+ return price;
+}
+
+
+static void
+fill_distances_prices(lzma_coder *coder)
+{
+ uint32_t len_to_pos_state;
+ uint32_t pos_slot;
+ uint32_t i;
+
+ for (len_to_pos_state = 0;
+ len_to_pos_state < LEN_TO_POS_STATES;
+ ++len_to_pos_state) {
+
+ uint32_t *const pos_slot_prices
+ = coder->pos_slot_prices[len_to_pos_state];
+
+ // Price to encode the pos_slot.
+ for (pos_slot = 0;
+ pos_slot < coder->dist_table_size; ++pos_slot)
+ pos_slot_prices[pos_slot] = rc_bittree_price(
+ coder->pos_slot[len_to_pos_state],
+ POS_SLOT_BITS, pos_slot);
+
+ // For matches with distance >= FULL_DISTANCES, add the price
+ // of the direct bits part of the match distance. (Align bits
+ // are handled by fill_align_prices()).
+ for (pos_slot = END_POS_MODEL_INDEX;
+ pos_slot < coder->dist_table_size; ++pos_slot)
+ pos_slot_prices[pos_slot] += rc_direct_price(
+ ((pos_slot >> 1) - 1) - ALIGN_BITS);
+
+ // Distances in the range [0, 3] are fully encoded with
+ // pos_slot, so they are used for coder->distances_prices
+ // as is.
+ for (i = 0; i < START_POS_MODEL_INDEX; ++i)
+ coder->distances_prices[len_to_pos_state][i]
+ = pos_slot_prices[i];
+ }
+
+ // Distances in the range [4, 127] depend on pos_slot and pos_special.
+ // We do this in a loop separate from the above loop to avoid
+ // redundant calls to get_pos_slot().
+ for (i = START_POS_MODEL_INDEX; i < FULL_DISTANCES; ++i) {
+ const uint32_t pos_slot = get_pos_slot(i);
+ const uint32_t footer_bits = ((pos_slot >> 1) - 1);
+ const uint32_t base = (2 | (pos_slot & 1)) << footer_bits;
+ const uint32_t price = rc_bittree_reverse_price(
+ coder->pos_special + base - pos_slot - 1,
+ footer_bits, i - base);
+
+ for (len_to_pos_state = 0;
+ len_to_pos_state < LEN_TO_POS_STATES;
+ ++len_to_pos_state)
+ coder->distances_prices[len_to_pos_state][i]
+ = price + coder->pos_slot_prices[
+ len_to_pos_state][pos_slot];
+ }
+
+ coder->match_price_count = 0;
+ return;
+}
+
+
+static void
+fill_align_prices(lzma_coder *coder)
+{
+ uint32_t i;
+ for (i = 0; i < ALIGN_TABLE_SIZE; ++i)
+ coder->align_prices[i] = rc_bittree_reverse_price(
+ coder->pos_align, ALIGN_BITS, i);
+
+ coder->align_price_count = 0;
+ return;
+}
+
+
+/////////////
+// Optimal //
+/////////////
+
+static inline void
+make_literal(lzma_optimal *optimal)
+{
+ optimal->back_prev = UINT32_MAX;
+ optimal->prev_1_is_literal = false;
+}
+
+
+static inline void
+make_short_rep(lzma_optimal *optimal)
+{
+ optimal->back_prev = 0;
+ optimal->prev_1_is_literal = false;
+}
+
+
+#define is_short_rep(optimal) \
+ ((optimal).back_prev == 0)
+
+
+static void
+backward(lzma_coder *LZMA_RESTRICT coder, uint32_t *LZMA_RESTRICT len_res,
+ uint32_t *LZMA_RESTRICT back_res, uint32_t cur)
+{
+ uint32_t pos_mem = coder->opts[cur].pos_prev;
+ uint32_t back_mem = coder->opts[cur].back_prev;
+
+ coder->opts_end_index = cur;
+
+ do {
+ const uint32_t pos_prev = pos_mem;
+ const uint32_t back_cur = back_mem;
+
+ if (coder->opts[cur].prev_1_is_literal) {
+ make_literal(&coder->opts[pos_mem]);
+ coder->opts[pos_mem].pos_prev = pos_mem - 1;
+
+ if (coder->opts[cur].prev_2) {
+ coder->opts[pos_mem - 1].prev_1_is_literal
+ = false;
+ coder->opts[pos_mem - 1].pos_prev
+ = coder->opts[cur].pos_prev_2;
+ coder->opts[pos_mem - 1].back_prev
+ = coder->opts[cur].back_prev_2;
+ }
+ }
+
+ back_mem = coder->opts[pos_prev].back_prev;
+ pos_mem = coder->opts[pos_prev].pos_prev;
+
+ coder->opts[pos_prev].back_prev = back_cur;
+ coder->opts[pos_prev].pos_prev = cur;
+ cur = pos_prev;
+
+ } while (cur != 0);
+
+ coder->opts_current_index = coder->opts[0].pos_prev;
+ *len_res = coder->opts[0].pos_prev;
+ *back_res = coder->opts[0].back_prev;
+
+ return;
+}
+
+
+//////////
+// Main //
+//////////
+
+static inline uint32_t
+helper1(lzma_coder *LZMA_RESTRICT coder, lzma_mf *LZMA_RESTRICT mf,
+ uint32_t *LZMA_RESTRICT back_res, uint32_t *LZMA_RESTRICT len_res,
+ uint32_t position)
+{
+ uint32_t buf_avail;
+ const uint8_t *buf;
+ uint32_t rep_lens[REP_DISTANCES];
+ uint32_t rep_max_index = 0;
+ uint32_t i;
+
+ uint8_t current_byte;
+ uint8_t match_byte;
+
+ uint32_t pos_state;
+ uint32_t match_price;
+ uint32_t rep_match_price;
+ uint32_t len_end;
+ uint32_t len;
+
+ uint32_t normal_match_price;
+
+ const uint32_t nice_len = mf->nice_len;
+
+ uint32_t len_main;
+ uint32_t matches_count;
+
+ if (mf->read_ahead == 0) {
+ len_main = mf_find(mf, &matches_count, coder->matches);
+ } else {
+ assert(mf->read_ahead == 1);
+ len_main = coder->longest_match_length;
+ matches_count = coder->matches_count;
+ }
+
+ buf_avail = my_min(mf_avail(mf) + 1, MATCH_LEN_MAX);
+ if (buf_avail < 2) {
+ *back_res = UINT32_MAX;
+ *len_res = 1;
+ return UINT32_MAX;
+ }
+
+ buf = mf_ptr(mf) - 1;
+
+ for (i = 0; i < REP_DISTANCES; ++i) {
+ uint32_t len_test;
+
+ const uint8_t *const buf_back = buf - coder->reps[i] - 1;
+
+ if (not_equal_16(buf, buf_back)) {
+ rep_lens[i] = 0;
+ continue;
+ }
+
+ for (len_test = 2; len_test < buf_avail
+ && buf[len_test] == buf_back[len_test];
+ ++len_test) ;
+
+ rep_lens[i] = len_test;
+ if (len_test > rep_lens[rep_max_index])
+ rep_max_index = i;
+ }
+
+ if (rep_lens[rep_max_index] >= nice_len) {
+ *back_res = rep_max_index;
+ *len_res = rep_lens[rep_max_index];
+ mf_skip(mf, *len_res - 1);
+ return UINT32_MAX;
+ }
+
+
+ if (len_main >= nice_len) {
+ *back_res = coder->matches[matches_count - 1].dist
+ + REP_DISTANCES;
+ *len_res = len_main;
+ mf_skip(mf, len_main - 1);
+ return UINT32_MAX;
+ }
+
+ current_byte = *buf;
+ match_byte = *(buf - coder->reps[0] - 1);
+
+ if (len_main < 2 && current_byte != match_byte
+ && rep_lens[rep_max_index] < 2) {
+ *back_res = UINT32_MAX;
+ *len_res = 1;
+ return UINT32_MAX;
+ }
+
+ coder->opts[0].state = coder->state;
+
+ pos_state = position & coder->pos_mask;
+
+ coder->opts[1].price = rc_bit_0_price(
+ coder->is_match[coder->state][pos_state])
+ + get_literal_price(coder, position, buf[-1],
+ !is_literal_state(coder->state),
+ match_byte, current_byte);
+
+ make_literal(&coder->opts[1]);
+
+ match_price = rc_bit_1_price(
+ coder->is_match[coder->state][pos_state]);
+ rep_match_price = match_price
+ + rc_bit_1_price(coder->is_rep[coder->state]);
+
+ if (match_byte == current_byte) {
+ const uint32_t short_rep_price = rep_match_price
+ + get_short_rep_price(
+ coder, coder->state, pos_state);
+
+ if (short_rep_price < coder->opts[1].price) {
+ coder->opts[1].price = short_rep_price;
+ make_short_rep(&coder->opts[1]);
+ }
+ }
+
+ len_end = my_max(len_main, rep_lens[rep_max_index]);
+
+ if (len_end < 2) {
+ *back_res = coder->opts[1].back_prev;
+ *len_res = 1;
+ return UINT32_MAX;
+ }
+
+ coder->opts[1].pos_prev = 0;
+
+ for (i = 0; i < REP_DISTANCES; ++i)
+ coder->opts[0].backs[i] = coder->reps[i];
+
+ len = len_end;
+ do {
+ coder->opts[len].price = RC_INFINITY_PRICE;
+ } while (--len >= 2);
+
+
+ for (i = 0; i < REP_DISTANCES; ++i) {
+ uint32_t price;
+
+ uint32_t rep_len = rep_lens[i];
+ if (rep_len < 2)
+ continue;
+
+ price = rep_match_price + get_pure_rep_price(
+ coder, i, coder->state, pos_state);
+
+ do {
+ const uint32_t cur_and_len_price = price
+ + get_len_price(
+ &coder->rep_len_encoder,
+ rep_len, pos_state);
+
+ if (cur_and_len_price < coder->opts[rep_len].price) {
+ coder->opts[rep_len].price = cur_and_len_price;
+ coder->opts[rep_len].pos_prev = 0;
+ coder->opts[rep_len].back_prev = i;
+ coder->opts[rep_len].prev_1_is_literal = false;
+ }
+ } while (--rep_len >= 2);
+ }
+
+
+ normal_match_price = match_price
+ + rc_bit_0_price(coder->is_rep[coder->state]);
+
+ len = rep_lens[0] >= 2 ? rep_lens[0] + 1 : 2;
+ if (len <= len_main) {
+ uint32_t i = 0;
+ while (len > coder->matches[i].len)
+ ++i;
+
+ for(; ; ++len) {
+ const uint32_t dist = coder->matches[i].dist;
+ const uint32_t cur_and_len_price = normal_match_price
+ + get_pos_len_price(coder,
+ dist, len, pos_state);
+
+ if (cur_and_len_price < coder->opts[len].price) {
+ coder->opts[len].price = cur_and_len_price;
+ coder->opts[len].pos_prev = 0;
+ coder->opts[len].back_prev
+ = dist + REP_DISTANCES;
+ coder->opts[len].prev_1_is_literal = false;
+ }
+
+ if (len == coder->matches[i].len)
+ if (++i == matches_count)
+ break;
+ }
+ }
+
+ return len_end;
+}
+
+
+static inline uint32_t
+helper2(lzma_coder *coder, uint32_t *reps, const uint8_t *buf,
+ uint32_t len_end, uint32_t position, const uint32_t cur,
+ const uint32_t nice_len, const uint32_t buf_avail_full)
+{
+ uint32_t matches_count = coder->matches_count;
+ uint32_t new_len = coder->longest_match_length;
+ uint32_t pos_prev = coder->opts[cur].pos_prev;
+ lzma_lzma_state state;
+ uint32_t buf_avail;
+ uint32_t rep_index;
+ uint32_t i;
+
+ uint32_t cur_price;
+ uint8_t current_byte;
+ uint8_t match_byte;
+ uint32_t pos_state;
+ uint32_t cur_and_1_price;
+ bool next_is_literal = false;
+ uint32_t match_price;
+ uint32_t rep_match_price;
+ uint32_t start_len = 2;
+
+ if (coder->opts[cur].prev_1_is_literal) {
+ --pos_prev;
+
+ if (coder->opts[cur].prev_2) {
+ state = coder->opts[coder->opts[cur].pos_prev_2].state;
+
+ if (coder->opts[cur].back_prev_2 < REP_DISTANCES)
+ update_long_rep(state);
+ else
+ update_match(state);
+
+ } else {
+ state = coder->opts[pos_prev].state;
+ }
+
+ update_literal(state);
+
+ } else {
+ state = coder->opts[pos_prev].state;
+ }
+
+ if (pos_prev == cur - 1) {
+ if (is_short_rep(coder->opts[cur]))
+ update_short_rep(state);
+ else
+ update_literal(state);
+ } else {
+ uint32_t pos;
+ if (coder->opts[cur].prev_1_is_literal
+ && coder->opts[cur].prev_2) {
+ pos_prev = coder->opts[cur].pos_prev_2;
+ pos = coder->opts[cur].back_prev_2;
+ update_long_rep(state);
+ } else {
+ pos = coder->opts[cur].back_prev;
+ if (pos < REP_DISTANCES)
+ update_long_rep(state);
+ else
+ update_match(state);
+ }
+
+ if (pos < REP_DISTANCES) {
+ uint32_t i;
+
+ reps[0] = coder->opts[pos_prev].backs[pos];
+
+ for (i = 1; i <= pos; ++i)
+ reps[i] = coder->opts[pos_prev].backs[i - 1];
+
+ for (; i < REP_DISTANCES; ++i)
+ reps[i] = coder->opts[pos_prev].backs[i];
+
+ } else {
+ reps[0] = pos - REP_DISTANCES;
+
+ for (i = 1; i < REP_DISTANCES; ++i)
+ reps[i] = coder->opts[pos_prev].backs[i - 1];
+ }
+ }
+
+ coder->opts[cur].state = state;
+
+ for (i = 0; i < REP_DISTANCES; ++i)
+ coder->opts[cur].backs[i] = reps[i];
+
+ cur_price = coder->opts[cur].price;
+
+ current_byte = *buf;
+ match_byte = *(buf - reps[0] - 1);
+
+ pos_state = position & coder->pos_mask;
+
+ cur_and_1_price = cur_price
+ + rc_bit_0_price(coder->is_match[state][pos_state])
+ + get_literal_price(coder, position, buf[-1],
+ !is_literal_state(state), match_byte, current_byte);
+
+ if (cur_and_1_price < coder->opts[cur + 1].price) {
+ coder->opts[cur + 1].price = cur_and_1_price;
+ coder->opts[cur + 1].pos_prev = cur;
+ make_literal(&coder->opts[cur + 1]);
+ next_is_literal = true;
+ }
+
+ match_price = cur_price
+ + rc_bit_1_price(coder->is_match[state][pos_state]);
+ rep_match_price = match_price
+ + rc_bit_1_price(coder->is_rep[state]);
+
+ if (match_byte == current_byte
+ && !(coder->opts[cur + 1].pos_prev < cur
+ && coder->opts[cur + 1].back_prev == 0)) {
+
+ const uint32_t short_rep_price = rep_match_price
+ + get_short_rep_price(coder, state, pos_state);
+
+ if (short_rep_price <= coder->opts[cur + 1].price) {
+ coder->opts[cur + 1].price = short_rep_price;
+ coder->opts[cur + 1].pos_prev = cur;
+ make_short_rep(&coder->opts[cur + 1]);
+ next_is_literal = true;
+ }
+ }
+
+ if (buf_avail_full < 2)
+ return len_end;
+
+ buf_avail = my_min(buf_avail_full, nice_len);
+
+ if (!next_is_literal && match_byte != current_byte) { // speed optimization
+ // try literal + rep0
+ const uint8_t *const buf_back = buf - reps[0] - 1;
+ const uint32_t limit = my_min(buf_avail_full, nice_len + 1);
+
+ uint32_t len_test = 1;
+ while (len_test < limit && buf[len_test] == buf_back[len_test])
+ ++len_test;
+
+ --len_test;
+
+ if (len_test >= 2) {
+ uint32_t pos_state_next;
+ uint32_t next_rep_match_price;
+ uint32_t offset;
+ uint32_t cur_and_len_price;
+
+ lzma_lzma_state state_2 = state;
+ update_literal(state_2);
+
+ pos_state_next = (position + 1) & coder->pos_mask;
+ next_rep_match_price = cur_and_1_price
+ + rc_bit_1_price(coder->is_match[state_2][pos_state_next])
+ + rc_bit_1_price(coder->is_rep[state_2]);
+
+ //for (; len_test >= 2; --len_test) {
+ offset = cur + 1 + len_test;
+
+ while (len_end < offset)
+ coder->opts[++len_end].price = RC_INFINITY_PRICE;
+
+ cur_and_len_price = next_rep_match_price
+ + get_rep_price(coder, 0, len_test,
+ state_2, pos_state_next);
+
+ if (cur_and_len_price < coder->opts[offset].price) {
+ coder->opts[offset].price = cur_and_len_price;
+ coder->opts[offset].pos_prev = cur + 1;
+ coder->opts[offset].back_prev = 0;
+ coder->opts[offset].prev_1_is_literal = true;
+ coder->opts[offset].prev_2 = false;
+ }
+ //}
+ }
+ }
+
+
+ for (rep_index = 0; rep_index < REP_DISTANCES; ++rep_index) {
+ uint32_t len_test, len_test_2, len_test_temp;
+ uint32_t price, limit;
+
+ const uint8_t *const buf_back = buf - reps[rep_index] - 1;
+ if (not_equal_16(buf, buf_back))
+ continue;
+
+ for (len_test = 2; len_test < buf_avail
+ && buf[len_test] == buf_back[len_test];
+ ++len_test) ;
+
+ while (len_end < cur + len_test)
+ coder->opts[++len_end].price = RC_INFINITY_PRICE;
+
+ len_test_temp = len_test;
+ price = rep_match_price + get_pure_rep_price(
+ coder, rep_index, state, pos_state);
+
+ do {
+ const uint32_t cur_and_len_price = price
+ + get_len_price(&coder->rep_len_encoder,
+ len_test, pos_state);
+
+ if (cur_and_len_price < coder->opts[cur + len_test].price) {
+ coder->opts[cur + len_test].price = cur_and_len_price;
+ coder->opts[cur + len_test].pos_prev = cur;
+ coder->opts[cur + len_test].back_prev = rep_index;
+ coder->opts[cur + len_test].prev_1_is_literal = false;
+ }
+ } while (--len_test >= 2);
+
+ len_test = len_test_temp;
+
+ if (rep_index == 0)
+ start_len = len_test + 1;
+
+
+ len_test_2 = len_test + 1;
+ limit = my_min(buf_avail_full,
+ len_test_2 + nice_len);
+ for (; len_test_2 < limit
+ && buf[len_test_2] == buf_back[len_test_2];
+ ++len_test_2) ;
+
+ len_test_2 -= len_test + 1;
+
+ if (len_test_2 >= 2) {
+ uint32_t pos_state_next;
+ uint32_t cur_and_len_literal_price;
+ uint32_t next_rep_match_price;
+ uint32_t offset;
+ uint32_t cur_and_len_price;
+
+ lzma_lzma_state state_2 = state;
+ update_long_rep(state_2);
+
+ pos_state_next = (position + len_test) & coder->pos_mask;
+
+ cur_and_len_literal_price = price
+ + get_len_price(&coder->rep_len_encoder,
+ len_test, pos_state)
+ + rc_bit_0_price(coder->is_match[state_2][pos_state_next])
+ + get_literal_price(coder, position + len_test,
+ buf[len_test - 1], true,
+ buf_back[len_test], buf[len_test]);
+
+ update_literal(state_2);
+
+ pos_state_next = (position + len_test + 1) & coder->pos_mask;
+
+ next_rep_match_price = cur_and_len_literal_price
+ + rc_bit_1_price(coder->is_match[state_2][pos_state_next])
+ + rc_bit_1_price(coder->is_rep[state_2]);
+
+ //for(; len_test_2 >= 2; len_test_2--) {
+ offset = cur + len_test + 1 + len_test_2;
+
+ while (len_end < offset)
+ coder->opts[++len_end].price = RC_INFINITY_PRICE;
+
+ cur_and_len_price = next_rep_match_price
+ + get_rep_price(coder, 0, len_test_2,
+ state_2, pos_state_next);
+
+ if (cur_and_len_price < coder->opts[offset].price) {
+ coder->opts[offset].price = cur_and_len_price;
+ coder->opts[offset].pos_prev = cur + len_test + 1;
+ coder->opts[offset].back_prev = 0;
+ coder->opts[offset].prev_1_is_literal = true;
+ coder->opts[offset].prev_2 = true;
+ coder->opts[offset].pos_prev_2 = cur;
+ coder->opts[offset].back_prev_2 = rep_index;
+ }
+ //}
+ }
+ }
+
+
+ //for (uint32_t len_test = 2; len_test <= new_len; ++len_test)
+ if (new_len > buf_avail) {
+ new_len = buf_avail;
+
+ matches_count = 0;
+ while (new_len > coder->matches[matches_count].len)
+ ++matches_count;
+
+ coder->matches[matches_count++].len = new_len;
+ }
+
+
+ if (new_len >= start_len) {
+ uint32_t len_test;
+ uint32_t i = 0;
+
+ const uint32_t normal_match_price = match_price
+ + rc_bit_0_price(coder->is_rep[state]);
+
+ while (len_end < cur + new_len)
+ coder->opts[++len_end].price = RC_INFINITY_PRICE;
+
+ while (start_len > coder->matches[i].len)
+ ++i;
+
+ for (len_test = start_len; ; ++len_test) {
+ const uint32_t cur_back = coder->matches[i].dist;
+ uint32_t cur_and_len_price = normal_match_price
+ + get_pos_len_price(coder,
+ cur_back, len_test, pos_state);
+
+ if (cur_and_len_price < coder->opts[cur + len_test].price) {
+ coder->opts[cur + len_test].price = cur_and_len_price;
+ coder->opts[cur + len_test].pos_prev = cur;
+ coder->opts[cur + len_test].back_prev
+ = cur_back + REP_DISTANCES;
+ coder->opts[cur + len_test].prev_1_is_literal = false;
+ }
+
+ if (len_test == coder->matches[i].len) {
+ // Try Match + Literal + Rep0
+ const uint8_t *const buf_back = buf - cur_back - 1;
+ uint32_t len_test_2 = len_test + 1;
+ const uint32_t limit = my_min(buf_avail_full,
+ len_test_2 + nice_len);
+
+ for (; len_test_2 < limit &&
+ buf[len_test_2] == buf_back[len_test_2];
+ ++len_test_2) ;
+
+ len_test_2 -= len_test + 1;
+
+ if (len_test_2 >= 2) {
+ uint32_t pos_state_next;
+ uint32_t cur_and_len_literal_price;
+ uint32_t next_rep_match_price;
+ uint32_t offset;
+
+ lzma_lzma_state state_2 = state;
+ update_match(state_2);
+ pos_state_next = (position + len_test) & coder->pos_mask;
+
+ cur_and_len_literal_price = cur_and_len_price
+ + rc_bit_0_price(
+ coder->is_match[state_2][pos_state_next])
+ + get_literal_price(coder,
+ position + len_test,
+ buf[len_test - 1],
+ true,
+ buf_back[len_test],
+ buf[len_test]);
+
+ update_literal(state_2);
+ pos_state_next = (pos_state_next + 1) & coder->pos_mask;
+
+ next_rep_match_price
+ = cur_and_len_literal_price
+ + rc_bit_1_price(
+ coder->is_match[state_2][pos_state_next])
+ + rc_bit_1_price(coder->is_rep[state_2]);
+
+ // for(; len_test_2 >= 2; --len_test_2) {
+ offset = cur + len_test + 1 + len_test_2;
+
+ while (len_end < offset)
+ coder->opts[++len_end].price = RC_INFINITY_PRICE;
+
+ cur_and_len_price = next_rep_match_price
+ + get_rep_price(coder, 0, len_test_2,
+ state_2, pos_state_next);
+
+ if (cur_and_len_price < coder->opts[offset].price) {
+ coder->opts[offset].price = cur_and_len_price;
+ coder->opts[offset].pos_prev = cur + len_test + 1;
+ coder->opts[offset].back_prev = 0;
+ coder->opts[offset].prev_1_is_literal = true;
+ coder->opts[offset].prev_2 = true;
+ coder->opts[offset].pos_prev_2 = cur;
+ coder->opts[offset].back_prev_2
+ = cur_back + REP_DISTANCES;
+ }
+ //}
+ }
+
+ if (++i == matches_count)
+ break;
+ }
+ }
+ }
+
+ return len_end;
+}
+
+
+extern void
+lzma_lzma_optimum_normal(lzma_coder *LZMA_RESTRICT coder, lzma_mf *LZMA_RESTRICT mf,
+ uint32_t *LZMA_RESTRICT back_res, uint32_t *LZMA_RESTRICT len_res,
+ uint32_t position)
+{
+ uint32_t reps[REP_DISTANCES];
+ uint32_t len_end;
+ uint32_t cur;
+
+ // If we have symbols pending, return the next pending symbol.
+ if (coder->opts_end_index != coder->opts_current_index) {
+ assert(mf->read_ahead > 0);
+ *len_res = coder->opts[coder->opts_current_index].pos_prev
+ - coder->opts_current_index;
+ *back_res = coder->opts[coder->opts_current_index].back_prev;
+ coder->opts_current_index = coder->opts[
+ coder->opts_current_index].pos_prev;
+ return;
+ }
+
+ // Update the price tables. In LZMA SDK <= 4.60 (and possibly later)
+ // this was done in both initialization function and in the main loop.
+ // In liblzma they were moved into this single place.
+ if (mf->read_ahead == 0) {
+ if (coder->match_price_count >= (1 << 7))
+ fill_distances_prices(coder);
+
+ if (coder->align_price_count >= ALIGN_TABLE_SIZE)
+ fill_align_prices(coder);
+ }
+
+ // TODO: This needs quite a bit of cleaning still. But splitting
+ // the original function into two pieces makes it at least a little
+ // more readable, since those two parts don't share many variables.
+
+ len_end = helper1(coder, mf, back_res, len_res, position);
+ if (len_end == UINT32_MAX)
+ return;
+
+
+ memcpy(reps, coder->reps, sizeof(reps));
+
+ for (cur = 1; cur < len_end; ++cur) {
+ assert(cur < OPTS);
+
+ coder->longest_match_length = mf_find(
+ mf, &coder->matches_count, coder->matches);
+
+ if (coder->longest_match_length >= mf->nice_len)
+ break;
+
+ len_end = helper2(coder, reps, mf_ptr(mf) - 1, len_end,
+ position + cur, cur, mf->nice_len,
+ my_min(mf_avail(mf) + 1, OPTS - 1 - cur));
+ }
+
+ backward(coder, len_res, back_res, cur);
+ return;
+}
diff --git a/Utilities/cmliblzma/liblzma/lzma/lzma_encoder_presets.c b/Utilities/cmliblzma/liblzma/lzma/lzma_encoder_presets.c
new file mode 100644
index 000000000..8af9b9fc4
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/lzma/lzma_encoder_presets.c
@@ -0,0 +1,63 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file lzma_encoder_presets.c
+/// \brief Encoder presets
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "common.h"
+
+
+extern LZMA_API(lzma_bool)
+lzma_lzma_preset(lzma_options_lzma *options, uint32_t preset)
+{
+ static const uint8_t dict_size_values[] = { 18, 20, 21, 22, 22, 23, 23, 24, 25, 26 };
+ static const uint8_t depth_values[] = { 4, 8, 24, 48 };
+
+ const uint32_t level = preset & LZMA_PRESET_LEVEL_MASK;
+ const uint32_t flags = preset & ~LZMA_PRESET_LEVEL_MASK;
+ const uint32_t supported_flags = LZMA_PRESET_EXTREME;
+
+ if (level > 9 || (flags & ~supported_flags))
+ return true;
+
+ options->preset_dict = NULL;
+ options->preset_dict_size = 0;
+
+ options->lc = LZMA_LC_DEFAULT;
+ options->lp = LZMA_LP_DEFAULT;
+ options->pb = LZMA_PB_DEFAULT;
+
+ options->dict_size = UINT32_C(1) << dict_size_values[level];
+
+ if (level <= 3) {
+ options->mode = LZMA_MODE_FAST;
+ options->mf = level == 0 ? LZMA_MF_HC3 : LZMA_MF_HC4;
+ options->nice_len = level <= 1 ? 128 : 273;
+ options->depth = depth_values[level];
+ } else {
+ options->mode = LZMA_MODE_NORMAL;
+ options->mf = LZMA_MF_BT4;
+ options->nice_len = level == 4 ? 16 : level == 5 ? 32 : 64;
+ options->depth = 0;
+ }
+
+ if (flags & LZMA_PRESET_EXTREME) {
+ options->mode = LZMA_MODE_NORMAL;
+ options->mf = LZMA_MF_BT4;
+ if (level == 3 || level == 5) {
+ options->nice_len = 192;
+ options->depth = 0;
+ } else {
+ options->nice_len = 273;
+ options->depth = 512;
+ }
+ }
+
+ return false;
+}
diff --git a/Utilities/cmliblzma/liblzma/lzma/lzma_encoder_private.h b/Utilities/cmliblzma/liblzma/lzma/lzma_encoder_private.h
new file mode 100644
index 000000000..04fb29e90
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/lzma/lzma_encoder_private.h
@@ -0,0 +1,148 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file lzma_encoder_private.h
+/// \brief Private definitions for LZMA encoder
+///
+// Authors: Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_LZMA_ENCODER_PRIVATE_H
+#define LZMA_LZMA_ENCODER_PRIVATE_H
+
+#include "lz_encoder.h"
+#include "range_encoder.h"
+#include "lzma_common.h"
+#include "lzma_encoder.h"
+
+
+// Macro to compare if the first two bytes in two buffers differ. This is
+// needed in lzma_lzma_optimum_*() to test if the match is at least
+// MATCH_LEN_MIN bytes. Unaligned access gives tiny gain so there's no
+// reason to not use it when it is supported.
+#ifdef TUKLIB_FAST_UNALIGNED_ACCESS
+# define not_equal_16(a, b) \
+ (*(const uint16_t *)(a) != *(const uint16_t *)(b))
+#else
+# define not_equal_16(a, b) \
+ ((a)[0] != (b)[0] || (a)[1] != (b)[1])
+#endif
+
+
+// Optimal - Number of entries in the optimum array.
+#define OPTS (1 << 12)
+
+
+typedef struct {
+ probability choice;
+ probability choice2;
+ probability low[POS_STATES_MAX][LEN_LOW_SYMBOLS];
+ probability mid[POS_STATES_MAX][LEN_MID_SYMBOLS];
+ probability high[LEN_HIGH_SYMBOLS];
+
+ uint32_t prices[POS_STATES_MAX][LEN_SYMBOLS];
+ uint32_t table_size;
+ uint32_t counters[POS_STATES_MAX];
+
+} lzma_length_encoder;
+
+
+typedef struct {
+ lzma_lzma_state state;
+
+ bool prev_1_is_literal;
+ bool prev_2;
+
+ uint32_t pos_prev_2;
+ uint32_t back_prev_2;
+
+ uint32_t price;
+ uint32_t pos_prev; // pos_next;
+ uint32_t back_prev;
+
+ uint32_t backs[REP_DISTANCES];
+
+} lzma_optimal;
+
+
+struct lzma_coder_s {
+ /// Range encoder
+ lzma_range_encoder rc;
+
+ /// State
+ lzma_lzma_state state;
+
+ /// The four most recent match distances
+ uint32_t reps[REP_DISTANCES];
+
+ /// Array of match candidates
+ lzma_match matches[MATCH_LEN_MAX + 1];
+
+ /// Number of match candidates in matches[]
+ uint32_t matches_count;
+
+ /// Variable to hold the length of the longest match between calls
+ /// to lzma_lzma_optimum_*().
+ uint32_t longest_match_length;
+
+ /// True if using getoptimumfast
+ bool fast_mode;
+
+ /// True if the encoder has been initialized by encoding the first
+ /// byte as a literal.
+ bool is_initialized;
+
+ /// True if the range encoder has been flushed, but not all bytes
+ /// have been written to the output buffer yet.
+ bool is_flushed;
+
+ uint32_t pos_mask; ///< (1 << pos_bits) - 1
+ uint32_t literal_context_bits;
+ uint32_t literal_pos_mask;
+
+ // These are the same as in lzma_decoder.c. See comments there.
+ probability literal[LITERAL_CODERS_MAX][LITERAL_CODER_SIZE];
+ probability is_match[STATES][POS_STATES_MAX];
+ probability is_rep[STATES];
+ probability is_rep0[STATES];
+ probability is_rep1[STATES];
+ probability is_rep2[STATES];
+ probability is_rep0_long[STATES][POS_STATES_MAX];
+ probability pos_slot[LEN_TO_POS_STATES][POS_SLOTS];
+ probability pos_special[FULL_DISTANCES - END_POS_MODEL_INDEX];
+ probability pos_align[ALIGN_TABLE_SIZE];
+
+ // These are the same as in lzma_decoder.c except that the encoders
+ // include also price tables.
+ lzma_length_encoder match_len_encoder;
+ lzma_length_encoder rep_len_encoder;
+
+ // Price tables
+ uint32_t pos_slot_prices[LEN_TO_POS_STATES][POS_SLOTS];
+ uint32_t distances_prices[LEN_TO_POS_STATES][FULL_DISTANCES];
+ uint32_t dist_table_size;
+ uint32_t match_price_count;
+
+ uint32_t align_prices[ALIGN_TABLE_SIZE];
+ uint32_t align_price_count;
+
+ // Optimal
+ uint32_t opts_end_index;
+ uint32_t opts_current_index;
+ lzma_optimal opts[OPTS];
+};
+
+
+extern void lzma_lzma_optimum_fast(
+ lzma_coder *LZMA_RESTRICT coder, lzma_mf *LZMA_RESTRICT mf,
+ uint32_t *LZMA_RESTRICT back_res, uint32_t *LZMA_RESTRICT len_res);
+
+extern void lzma_lzma_optimum_normal(lzma_coder *LZMA_RESTRICT coder,
+ lzma_mf *LZMA_RESTRICT mf, uint32_t *LZMA_RESTRICT back_res,
+ uint32_t *LZMA_RESTRICT len_res, uint32_t position);
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/rangecoder/price.h b/Utilities/cmliblzma/liblzma/rangecoder/price.h
new file mode 100644
index 000000000..8ae02ca74
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/rangecoder/price.h
@@ -0,0 +1,92 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file price.h
+/// \brief Probability price calculation
+//
+// Author: Igor Pavlov
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_PRICE_H
+#define LZMA_PRICE_H
+
+
+#define RC_MOVE_REDUCING_BITS 4
+#define RC_BIT_PRICE_SHIFT_BITS 4
+#define RC_PRICE_TABLE_SIZE (RC_BIT_MODEL_TOTAL >> RC_MOVE_REDUCING_BITS)
+
+#define RC_INFINITY_PRICE (UINT32_C(1) << 30)
+
+
+/// Lookup table for the inline functions defined in this file.
+extern const uint8_t lzma_rc_prices[RC_PRICE_TABLE_SIZE];
+
+
+static inline uint32_t
+rc_bit_price(const probability prob, const uint32_t bit)
+{
+ return lzma_rc_prices[(prob ^ ((UINT32_C(0) - bit)
+ & (RC_BIT_MODEL_TOTAL - 1))) >> RC_MOVE_REDUCING_BITS];
+}
+
+
+static inline uint32_t
+rc_bit_0_price(const probability prob)
+{
+ return lzma_rc_prices[prob >> RC_MOVE_REDUCING_BITS];
+}
+
+
+static inline uint32_t
+rc_bit_1_price(const probability prob)
+{
+ return lzma_rc_prices[(prob ^ (RC_BIT_MODEL_TOTAL - 1))
+ >> RC_MOVE_REDUCING_BITS];
+}
+
+
+static inline uint32_t
+rc_bittree_price(const probability *const probs,
+ const uint32_t bit_levels, uint32_t symbol)
+{
+ uint32_t price = 0;
+ symbol += UINT32_C(1) << bit_levels;
+
+ do {
+ const uint32_t bit = symbol & 1;
+ symbol >>= 1;
+ price += rc_bit_price(probs[symbol], bit);
+ } while (symbol != 1);
+
+ return price;
+}
+
+
+static inline uint32_t
+rc_bittree_reverse_price(const probability *const probs,
+ uint32_t bit_levels, uint32_t symbol)
+{
+ uint32_t price = 0;
+ uint32_t model_index = 1;
+
+ do {
+ const uint32_t bit = symbol & 1;
+ symbol >>= 1;
+ price += rc_bit_price(probs[model_index], bit);
+ model_index = (model_index << 1) + bit;
+ } while (--bit_levels != 0);
+
+ return price;
+}
+
+
+static inline uint32_t
+rc_direct_price(const uint32_t bits)
+{
+ return bits << RC_BIT_PRICE_SHIFT_BITS;
+}
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/rangecoder/price_table.c b/Utilities/cmliblzma/liblzma/rangecoder/price_table.c
new file mode 100644
index 000000000..ac64bf62c
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/rangecoder/price_table.c
@@ -0,0 +1,22 @@
+/* This file has been automatically generated by price_tablegen.c. */
+
+#include "range_encoder.h"
+
+const uint8_t lzma_rc_prices[RC_PRICE_TABLE_SIZE] = {
+ 128, 103, 91, 84, 78, 73, 69, 66,
+ 63, 61, 58, 56, 54, 52, 51, 49,
+ 48, 46, 45, 44, 43, 42, 41, 40,
+ 39, 38, 37, 36, 35, 34, 34, 33,
+ 32, 31, 31, 30, 29, 29, 28, 28,
+ 27, 26, 26, 25, 25, 24, 24, 23,
+ 23, 22, 22, 22, 21, 21, 20, 20,
+ 19, 19, 19, 18, 18, 17, 17, 17,
+ 16, 16, 16, 15, 15, 15, 14, 14,
+ 14, 13, 13, 13, 12, 12, 12, 11,
+ 11, 11, 11, 10, 10, 10, 10, 9,
+ 9, 9, 9, 8, 8, 8, 8, 7,
+ 7, 7, 7, 6, 6, 6, 6, 5,
+ 5, 5, 5, 5, 4, 4, 4, 4,
+ 3, 3, 3, 3, 3, 2, 2, 2,
+ 2, 2, 2, 1, 1, 1, 1, 1
+};
diff --git a/Utilities/cmliblzma/liblzma/rangecoder/price_tablegen.c b/Utilities/cmliblzma/liblzma/rangecoder/price_tablegen.c
new file mode 100644
index 000000000..bf08ce39d
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/rangecoder/price_tablegen.c
@@ -0,0 +1,87 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file price_tablegen.c
+/// \brief Probability price table generator
+///
+/// Compiling: gcc -std=c99 -o price_tablegen price_tablegen.c
+///
+// Authors: Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <inttypes.h>
+#include <stdio.h>
+#include "range_common.h"
+#include "price.h"
+
+
+static uint32_t rc_prices[RC_PRICE_TABLE_SIZE];
+
+
+static void
+init_price_table(void)
+{
+ for (uint32_t i = (UINT32_C(1) << RC_MOVE_REDUCING_BITS) / 2;
+ i < RC_BIT_MODEL_TOTAL;
+ i += (UINT32_C(1) << RC_MOVE_REDUCING_BITS)) {
+ const uint32_t cycles_bits = RC_BIT_PRICE_SHIFT_BITS;
+ uint32_t w = i;
+ uint32_t bit_count = 0;
+
+ for (uint32_t j = 0; j < cycles_bits; ++j) {
+ w *= w;
+ bit_count <<= 1;
+
+ while (w >= (UINT32_C(1) << 16)) {
+ w >>= 1;
+ ++bit_count;
+ }
+ }
+
+ rc_prices[i >> RC_MOVE_REDUCING_BITS]
+ = (RC_BIT_MODEL_TOTAL_BITS << cycles_bits)
+ - 15 - bit_count;
+ }
+
+ return;
+}
+
+
+static void
+print_price_table(void)
+{
+ printf("/* This file has been automatically generated by "
+ "price_tablegen.c. */\n\n"
+ "#include \"range_encoder.h\"\n\n"
+ "const uint8_t lzma_rc_prices["
+ "RC_PRICE_TABLE_SIZE] = {");
+
+ const size_t array_size = sizeof(lzma_rc_prices)
+ / sizeof(lzma_rc_prices[0]);
+ for (size_t i = 0; i < array_size; ++i) {
+ if (i % 8 == 0)
+ printf("\n\t");
+
+ printf("%4" PRIu32, rc_prices[i]);
+
+ if (i != array_size - 1)
+ printf(",");
+ }
+
+ printf("\n};\n");
+
+ return;
+}
+
+
+int
+main(void)
+{
+ init_price_table();
+ print_price_table();
+ return 0;
+}
diff --git a/Utilities/cmliblzma/liblzma/rangecoder/range_common.h b/Utilities/cmliblzma/liblzma/rangecoder/range_common.h
new file mode 100644
index 000000000..f15623ea6
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/rangecoder/range_common.h
@@ -0,0 +1,74 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file range_common.h
+/// \brief Common things for range encoder and decoder
+///
+// Authors: Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_RANGE_COMMON_H
+#define LZMA_RANGE_COMMON_H
+
+#include "common.h"
+
+
+///////////////
+// Constants //
+///////////////
+
+#define RC_SHIFT_BITS 8
+#define RC_TOP_BITS 24
+#define RC_TOP_VALUE (UINT32_C(1) << RC_TOP_BITS)
+#define RC_BIT_MODEL_TOTAL_BITS 11
+#define RC_BIT_MODEL_TOTAL (UINT32_C(1) << RC_BIT_MODEL_TOTAL_BITS)
+#define RC_MOVE_BITS 5
+
+
+////////////
+// Macros //
+////////////
+
+// Resets the probability so that both 0 and 1 have probability of 50 %
+#define bit_reset(prob) \
+ prob = RC_BIT_MODEL_TOTAL >> 1
+
+// This does the same for a complete bit tree.
+// (A tree represented as an array.)
+#define bittree_reset(probs, bit_levels) \
+ do { \
+ uint32_t bt_i; \
+ for (bt_i = 0; bt_i < (1 << (bit_levels)); ++bt_i) \
+ bit_reset((probs)[bt_i]); \
+ } while (0)
+
+
+//////////////////////
+// Type definitions //
+//////////////////////
+
+/// \brief Type of probabilities used with range coder
+///
+/// This needs to be at least 12-bit integer, so uint16_t is a logical choice.
+/// However, on some architecture and compiler combinations, a bigger type
+/// may give better speed, because the probability variables are accessed
+/// a lot. On the other hand, bigger probability type increases cache
+/// footprint, since there are 2 to 14 thousand probability variables in
+/// LZMA (assuming the limit of lc + lp <= 4; with lc + lp <= 12 there
+/// would be about 1.5 million variables).
+///
+/// With malicious files, the initialization speed of the LZMA decoder can
+/// become important. In that case, smaller probability variables mean that
+/// there is less bytes to write to RAM, which makes initialization faster.
+/// With big probability type, the initialization can become so slow that it
+/// can be a problem e.g. for email servers doing virus scanning.
+///
+/// I will be sticking to uint16_t unless some specific architectures
+/// are *much* faster (20-50 %) with uint32_t.
+typedef uint16_t probability;
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/rangecoder/range_decoder.h b/Utilities/cmliblzma/liblzma/rangecoder/range_decoder.h
new file mode 100644
index 000000000..199e7b5a6
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/rangecoder/range_decoder.h
@@ -0,0 +1,179 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file range_decoder.h
+/// \brief Range Decoder
+///
+// Authors: Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_RANGE_DECODER_H
+#define LZMA_RANGE_DECODER_H
+
+#include "range_common.h"
+
+
+typedef struct {
+ uint32_t range;
+ uint32_t code;
+ uint32_t init_bytes_left;
+} lzma_range_decoder;
+
+
+/// Reads the first five bytes to initialize the range decoder.
+static inline bool
+rc_read_init(lzma_range_decoder *rc, const uint8_t *LZMA_RESTRICT in,
+ size_t *LZMA_RESTRICT in_pos, size_t in_size)
+{
+ while (rc->init_bytes_left > 0) {
+ if (*in_pos == in_size)
+ return false;
+
+ rc->code = (rc->code << 8) | in[*in_pos];
+ ++*in_pos;
+ --rc->init_bytes_left;
+ }
+
+ return true;
+}
+
+
+/// Makes local copies of range decoder and *in_pos variables. Doing this
+/// improves speed significantly. The range decoder macros expect also
+/// variables `in' and `in_size' to be defined.
+#define rc_to_local(range_decoder, in_pos) \
+ lzma_range_decoder rc = range_decoder; \
+ size_t rc_in_pos = (in_pos); \
+ uint32_t rc_bound
+
+
+/// Stores the local copes back to the range decoder structure.
+#define rc_from_local(range_decoder, in_pos) \
+do { \
+ range_decoder = rc; \
+ in_pos = rc_in_pos; \
+} while (0)
+
+
+/// Resets the range decoder structure.
+#define rc_reset(range_decoder) \
+do { \
+ (range_decoder).range = UINT32_MAX; \
+ (range_decoder).code = 0; \
+ (range_decoder).init_bytes_left = 5; \
+} while (0)
+
+
+/// When decoding has been properly finished, rc.code is always zero unless
+/// the input stream is corrupt. So checking this can catch some corrupt
+/// files especially if they don't have any other integrity check.
+#define rc_is_finished(range_decoder) \
+ ((range_decoder).code == 0)
+
+
+/// Read the next input byte if needed. If more input is needed but there is
+/// no more input available, "goto out" is used to jump out of the main
+/// decoder loop.
+#define rc_normalize(seq) \
+do { \
+ if (rc.range < RC_TOP_VALUE) { \
+ if (unlikely(rc_in_pos == in_size)) { \
+ coder->sequence = seq; \
+ goto out; \
+ } \
+ rc.range <<= RC_SHIFT_BITS; \
+ rc.code = (rc.code << RC_SHIFT_BITS) | in[rc_in_pos++]; \
+ } \
+} while (0)
+
+
+/// Start decoding a bit. This must be used together with rc_update_0()
+/// and rc_update_1():
+///
+/// rc_if_0(prob, seq) {
+/// rc_update_0(prob);
+/// // Do something
+/// } else {
+/// rc_update_1(prob);
+/// // Do something else
+/// }
+///
+#define rc_if_0(prob, seq) \
+ rc_normalize(seq); \
+ rc_bound = (rc.range >> RC_BIT_MODEL_TOTAL_BITS) * (prob); \
+ if (rc.code < rc_bound)
+
+
+/// Update the range decoder state and the used probability variable to
+/// match a decoded bit of 0.
+#define rc_update_0(prob) \
+do { \
+ rc.range = rc_bound; \
+ prob += (RC_BIT_MODEL_TOTAL - (prob)) >> RC_MOVE_BITS; \
+} while (0)
+
+
+/// Update the range decoder state and the used probability variable to
+/// match a decoded bit of 1.
+#define rc_update_1(prob) \
+do { \
+ rc.range -= rc_bound; \
+ rc.code -= rc_bound; \
+ prob -= (prob) >> RC_MOVE_BITS; \
+} while (0)
+
+
+/// Decodes one bit and runs action0 or action1 depending on the decoded bit.
+/// This macro is used as the last step in bittree reverse decoders since
+/// those don't use "symbol" for anything else than indexing the probability
+/// arrays.
+#define rc_bit_last(prob, action0, action1, seq) \
+do { \
+ rc_if_0(prob, seq) { \
+ rc_update_0(prob); \
+ action0; \
+ } else { \
+ rc_update_1(prob); \
+ action1; \
+ } \
+} while (0)
+
+
+/// Decodes one bit, updates "symbol", and runs action0 or action1 depending
+/// on the decoded bit.
+#define rc_bit(prob, action0, action1, seq) \
+ rc_bit_last(prob, \
+ symbol <<= 1; action0, \
+ symbol = (symbol << 1) + 1; action1, \
+ seq);
+
+
+/// Like rc_bit() but add "case seq:" as a prefix. This makes the unrolled
+/// loops more readable because the code isn't littered with "case"
+/// statements. On the other hand this also makes it less readable, since
+/// spotting the places where the decoder loop may be restarted is less
+/// obvious.
+#define rc_bit_case(prob, action0, action1, seq) \
+ case seq: rc_bit(prob, action0, action1, seq)
+
+
+/// Decode a bit without using a probability.
+#define rc_direct(dest, seq) \
+do { \
+ rc_normalize(seq); \
+ rc.range >>= 1; \
+ rc.code -= rc.range; \
+ rc_bound = UINT32_C(0) - (rc.code >> 31); \
+ rc.code += rc.range & rc_bound; \
+ dest = (dest << 1) + (rc_bound + 1); \
+} while (0)
+
+
+// NOTE: No macros are provided for bittree decoding. It seems to be simpler
+// to just write them open in the code.
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/rangecoder/range_encoder.h b/Utilities/cmliblzma/liblzma/rangecoder/range_encoder.h
new file mode 100644
index 000000000..e9614f252
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/rangecoder/range_encoder.h
@@ -0,0 +1,232 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file range_encoder.h
+/// \brief Range Encoder
+///
+// Authors: Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_RANGE_ENCODER_H
+#define LZMA_RANGE_ENCODER_H
+
+#include "range_common.h"
+#include "price.h"
+
+
+/// Maximum number of symbols that can be put pending into lzma_range_encoder
+/// structure between calls to lzma_rc_encode(). For LZMA, 52+5 is enough
+/// (match with big distance and length followed by range encoder flush).
+#define RC_SYMBOLS_MAX 58
+
+
+typedef struct {
+ uint64_t low;
+ uint64_t cache_size;
+ uint32_t range;
+ uint8_t cache;
+
+ /// Number of symbols in the tables
+ size_t count;
+
+ /// rc_encode()'s position in the tables
+ size_t pos;
+
+ /// Symbols to encode
+ enum {
+ RC_BIT_0,
+ RC_BIT_1,
+ RC_DIRECT_0,
+ RC_DIRECT_1,
+ RC_FLUSH,
+ } symbols[RC_SYMBOLS_MAX];
+
+ /// Probabilities associated with RC_BIT_0 or RC_BIT_1
+ probability *probs[RC_SYMBOLS_MAX];
+
+} lzma_range_encoder;
+
+
+static inline void
+rc_reset(lzma_range_encoder *rc)
+{
+ rc->low = 0;
+ rc->cache_size = 1;
+ rc->range = UINT32_MAX;
+ rc->cache = 0;
+ rc->count = 0;
+ rc->pos = 0;
+}
+
+
+static inline void
+rc_bit(lzma_range_encoder *rc, probability *prob, uint32_t bit)
+{
+ rc->symbols[rc->count] = bit;
+ rc->probs[rc->count] = prob;
+ ++rc->count;
+}
+
+
+static inline void
+rc_bittree(lzma_range_encoder *rc, probability *probs,
+ uint32_t bit_count, uint32_t symbol)
+{
+ uint32_t model_index = 1;
+
+ do {
+ const uint32_t bit = (symbol >> --bit_count) & 1;
+ rc_bit(rc, &probs[model_index], bit);
+ model_index = (model_index << 1) + bit;
+ } while (bit_count != 0);
+}
+
+
+static inline void
+rc_bittree_reverse(lzma_range_encoder *rc, probability *probs,
+ uint32_t bit_count, uint32_t symbol)
+{
+ uint32_t model_index = 1;
+
+ do {
+ const uint32_t bit = symbol & 1;
+ symbol >>= 1;
+ rc_bit(rc, &probs[model_index], bit);
+ model_index = (model_index << 1) + bit;
+ } while (--bit_count != 0);
+}
+
+
+static inline void
+rc_direct(lzma_range_encoder *rc,
+ uint32_t value, uint32_t bit_count)
+{
+ do {
+ rc->symbols[rc->count++]
+ = RC_DIRECT_0 + ((value >> --bit_count) & 1);
+ } while (bit_count != 0);
+}
+
+
+static inline void
+rc_flush(lzma_range_encoder *rc)
+{
+ size_t i;
+ for (i = 0; i < 5; ++i)
+ rc->symbols[rc->count++] = RC_FLUSH;
+}
+
+
+static inline bool
+rc_shift_low(lzma_range_encoder *rc,
+ uint8_t *out, size_t *out_pos, size_t out_size)
+{
+ if ((uint32_t)(rc->low) < (uint32_t)(0xFF000000)
+ || (uint32_t)(rc->low >> 32) != 0) {
+ do {
+ if (*out_pos == out_size)
+ return true;
+
+ out[*out_pos] = rc->cache + (uint8_t)(rc->low >> 32);
+ ++*out_pos;
+ rc->cache = 0xFF;
+
+ } while (--rc->cache_size != 0);
+
+ rc->cache = (rc->low >> 24) & 0xFF;
+ }
+
+ ++rc->cache_size;
+ rc->low = (rc->low & 0x00FFFFFF) << RC_SHIFT_BITS;
+
+ return false;
+}
+
+
+static inline bool
+rc_encode(lzma_range_encoder *rc,
+ uint8_t *out, size_t *out_pos, size_t out_size)
+{
+ assert(rc->count <= RC_SYMBOLS_MAX);
+
+ while (rc->pos < rc->count) {
+ // Normalize
+ if (rc->range < RC_TOP_VALUE) {
+ if (rc_shift_low(rc, out, out_pos, out_size))
+ return true;
+
+ rc->range <<= RC_SHIFT_BITS;
+ }
+
+ // Encode a bit
+ switch (rc->symbols[rc->pos]) {
+ case RC_BIT_0: {
+ probability prob = *rc->probs[rc->pos];
+ rc->range = (rc->range >> RC_BIT_MODEL_TOTAL_BITS)
+ * prob;
+ prob += (RC_BIT_MODEL_TOTAL - prob) >> RC_MOVE_BITS;
+ *rc->probs[rc->pos] = prob;
+ break;
+ }
+
+ case RC_BIT_1: {
+ probability prob = *rc->probs[rc->pos];
+ const uint32_t bound = prob * (rc->range
+ >> RC_BIT_MODEL_TOTAL_BITS);
+ rc->low += bound;
+ rc->range -= bound;
+ prob -= prob >> RC_MOVE_BITS;
+ *rc->probs[rc->pos] = prob;
+ break;
+ }
+
+ case RC_DIRECT_0:
+ rc->range >>= 1;
+ break;
+
+ case RC_DIRECT_1:
+ rc->range >>= 1;
+ rc->low += rc->range;
+ break;
+
+ case RC_FLUSH:
+ // Prevent further normalizations.
+ rc->range = UINT32_MAX;
+
+ // Flush the last five bytes (see rc_flush()).
+ do {
+ if (rc_shift_low(rc, out, out_pos, out_size))
+ return true;
+ } while (++rc->pos < rc->count);
+
+ // Reset the range encoder so we are ready to continue
+ // encoding if we weren't finishing the stream.
+ rc_reset(rc);
+ return false;
+
+ default:
+ assert(0);
+ break;
+ }
+
+ ++rc->pos;
+ }
+
+ rc->count = 0;
+ rc->pos = 0;
+
+ return false;
+}
+
+
+static inline uint64_t
+rc_pending(const lzma_range_encoder *rc)
+{
+ return rc->cache_size + 5 - 1;
+}
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/simple/arm.c b/Utilities/cmliblzma/liblzma/simple/arm.c
new file mode 100644
index 000000000..8dcba39fd
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/simple/arm.c
@@ -0,0 +1,69 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file arm.c
+/// \brief Filter for ARM binaries
+///
+// Authors: Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "simple_private.h"
+
+
+static size_t
+arm_code(lzma_simple *simple lzma_attribute((__unused__)),
+ uint32_t now_pos, bool is_encoder,
+ uint8_t *buffer, size_t size)
+{
+ size_t i;
+ for (i = 0; i + 4 <= size; i += 4) {
+ if (buffer[i + 3] == 0xEB) {
+ uint32_t dest;
+ uint32_t src = (buffer[i + 2] << 16)
+ | (buffer[i + 1] << 8)
+ | (buffer[i + 0]);
+ src <<= 2;
+
+ if (is_encoder)
+ dest = now_pos + (uint32_t)(i) + 8 + src;
+ else
+ dest = src - (now_pos + (uint32_t)(i) + 8);
+
+ dest >>= 2;
+ buffer[i + 2] = (dest >> 16);
+ buffer[i + 1] = (dest >> 8);
+ buffer[i + 0] = dest;
+ }
+ }
+
+ return i;
+}
+
+
+static lzma_ret
+arm_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter_info *filters, bool is_encoder)
+{
+ return lzma_simple_coder_init(next, allocator, filters,
+ &arm_code, 0, 4, 4, is_encoder);
+}
+
+
+extern lzma_ret
+lzma_simple_arm_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter_info *filters)
+{
+ return arm_coder_init(next, allocator, filters, true);
+}
+
+
+extern lzma_ret
+lzma_simple_arm_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter_info *filters)
+{
+ return arm_coder_init(next, allocator, filters, false);
+}
diff --git a/Utilities/cmliblzma/liblzma/simple/armthumb.c b/Utilities/cmliblzma/liblzma/simple/armthumb.c
new file mode 100644
index 000000000..4b890a395
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/simple/armthumb.c
@@ -0,0 +1,74 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file armthumb.c
+/// \brief Filter for ARM-Thumb binaries
+///
+// Authors: Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "simple_private.h"
+
+
+static size_t
+armthumb_code(lzma_simple *simple lzma_attribute((__unused__)),
+ uint32_t now_pos, bool is_encoder,
+ uint8_t *buffer, size_t size)
+{
+ size_t i;
+ for (i = 0; i + 4 <= size; i += 2) {
+ if ((buffer[i + 1] & 0xF8) == 0xF0
+ && (buffer[i + 3] & 0xF8) == 0xF8) {
+ uint32_t dest;
+ uint32_t src = ((buffer[i + 1] & 0x7) << 19)
+ | (buffer[i + 0] << 11)
+ | ((buffer[i + 3] & 0x7) << 8)
+ | (buffer[i + 2]);
+
+ src <<= 1;
+
+ if (is_encoder)
+ dest = now_pos + (uint32_t)(i) + 4 + src;
+ else
+ dest = src - (now_pos + (uint32_t)(i) + 4);
+
+ dest >>= 1;
+ buffer[i + 1] = 0xF0 | ((dest >> 19) & 0x7);
+ buffer[i + 0] = (dest >> 11);
+ buffer[i + 3] = 0xF8 | ((dest >> 8) & 0x7);
+ buffer[i + 2] = (dest);
+ i += 2;
+ }
+ }
+
+ return i;
+}
+
+
+static lzma_ret
+armthumb_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter_info *filters, bool is_encoder)
+{
+ return lzma_simple_coder_init(next, allocator, filters,
+ &armthumb_code, 0, 4, 2, is_encoder);
+}
+
+
+extern lzma_ret
+lzma_simple_armthumb_encoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters)
+{
+ return armthumb_coder_init(next, allocator, filters, true);
+}
+
+
+extern lzma_ret
+lzma_simple_armthumb_decoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters)
+{
+ return armthumb_coder_init(next, allocator, filters, false);
+}
diff --git a/Utilities/cmliblzma/liblzma/simple/ia64.c b/Utilities/cmliblzma/liblzma/simple/ia64.c
new file mode 100644
index 000000000..c537caca1
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/simple/ia64.c
@@ -0,0 +1,116 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file ia64.c
+/// \brief Filter for IA64 (Itanium) binaries
+///
+// Authors: Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "simple_private.h"
+
+
+static size_t
+ia64_code(lzma_simple *simple lzma_attribute((__unused__)),
+ uint32_t now_pos, bool is_encoder,
+ uint8_t *buffer, size_t size)
+{
+ static const uint32_t BRANCH_TABLE[32] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 4, 4, 6, 6, 0, 0, 7, 7,
+ 4, 4, 0, 0, 4, 4, 0, 0
+ };
+
+ size_t i;
+ for (i = 0; i + 16 <= size; i += 16) {
+ size_t slot;
+
+ const uint32_t instr_template = buffer[i] & 0x1F;
+ const uint32_t mask = BRANCH_TABLE[instr_template];
+ uint32_t bit_pos = 5;
+
+ for (slot = 0; slot < 3; ++slot, bit_pos += 41) {
+ const size_t byte_pos = (bit_pos >> 3);
+ const uint32_t bit_res = bit_pos & 0x7;
+ uint64_t instruction = 0;
+ uint64_t inst_norm;
+ size_t j;
+
+ if (((mask >> slot) & 1) == 0)
+ continue;
+
+ for (j = 0; j < 6; ++j)
+ instruction += (uint64_t)(
+ buffer[i + j + byte_pos])
+ << (8 * j);
+
+ inst_norm = instruction >> bit_res;
+
+ if (((inst_norm >> 37) & 0xF) == 0x5
+ && ((inst_norm >> 9) & 0x7) == 0
+ /* && (inst_norm & 0x3F)== 0 */
+ ) {
+ uint32_t dest;
+ size_t j;
+
+ uint32_t src = (uint32_t)(
+ (inst_norm >> 13) & 0xFFFFF);
+ src |= ((inst_norm >> 36) & 1) << 20;
+
+ src <<= 4;
+
+ if (is_encoder)
+ dest = now_pos + (uint32_t)(i) + src;
+ else
+ dest = src - (now_pos + (uint32_t)(i));
+
+ dest >>= 4;
+
+ inst_norm &= ~((uint64_t)(0x8FFFFF) << 13);
+ inst_norm |= (uint64_t)(dest & 0xFFFFF) << 13;
+ inst_norm |= (uint64_t)(dest & 0x100000)
+ << (36 - 20);
+
+ instruction &= (1 << bit_res) - 1;
+ instruction |= (inst_norm << bit_res);
+
+ for (j = 0; j < 6; j++)
+ buffer[i + j + byte_pos] = (uint8_t)(
+ instruction
+ >> (8 * j));
+ }
+ }
+ }
+
+ return i;
+}
+
+
+static lzma_ret
+ia64_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter_info *filters, bool is_encoder)
+{
+ return lzma_simple_coder_init(next, allocator, filters,
+ &ia64_code, 0, 16, 16, is_encoder);
+}
+
+
+extern lzma_ret
+lzma_simple_ia64_encoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters)
+{
+ return ia64_coder_init(next, allocator, filters, true);
+}
+
+
+extern lzma_ret
+lzma_simple_ia64_decoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters)
+{
+ return ia64_coder_init(next, allocator, filters, false);
+}
diff --git a/Utilities/cmliblzma/liblzma/simple/powerpc.c b/Utilities/cmliblzma/liblzma/simple/powerpc.c
new file mode 100644
index 000000000..6f8351176
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/simple/powerpc.c
@@ -0,0 +1,73 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file powerpc.c
+/// \brief Filter for PowerPC (big endian) binaries
+///
+// Authors: Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "simple_private.h"
+
+
+static size_t
+powerpc_code(lzma_simple *simple lzma_attribute((__unused__)),
+ uint32_t now_pos, bool is_encoder,
+ uint8_t *buffer, size_t size)
+{
+ size_t i;
+ for (i = 0; i + 4 <= size; i += 4) {
+ // PowerPC branch 6(48) 24(Offset) 1(Abs) 1(Link)
+ if ((buffer[i] >> 2) == 0x12
+ && ((buffer[i + 3] & 3) == 1)) {
+
+ const uint32_t src = ((buffer[i + 0] & 3) << 24)
+ | (buffer[i + 1] << 16)
+ | (buffer[i + 2] << 8)
+ | (buffer[i + 3] & (~3));
+
+ uint32_t dest;
+ if (is_encoder)
+ dest = now_pos + (uint32_t)(i) + src;
+ else
+ dest = src - (now_pos + (uint32_t)(i));
+
+ buffer[i + 0] = 0x48 | ((dest >> 24) & 0x03);
+ buffer[i + 1] = (dest >> 16);
+ buffer[i + 2] = (dest >> 8);
+ buffer[i + 3] &= 0x03;
+ buffer[i + 3] |= dest;
+ }
+ }
+
+ return i;
+}
+
+
+static lzma_ret
+powerpc_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter_info *filters, bool is_encoder)
+{
+ return lzma_simple_coder_init(next, allocator, filters,
+ &powerpc_code, 0, 4, 4, is_encoder);
+}
+
+
+extern lzma_ret
+lzma_simple_powerpc_encoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters)
+{
+ return powerpc_coder_init(next, allocator, filters, true);
+}
+
+
+extern lzma_ret
+lzma_simple_powerpc_decoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters)
+{
+ return powerpc_coder_init(next, allocator, filters, false);
+}
diff --git a/Utilities/cmliblzma/liblzma/simple/simple_coder.c b/Utilities/cmliblzma/liblzma/simple/simple_coder.c
new file mode 100644
index 000000000..f3bbdd7a7
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/simple/simple_coder.c
@@ -0,0 +1,283 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file simple_coder.c
+/// \brief Wrapper for simple filters
+///
+/// Simple filters don't change the size of the data i.e. number of bytes
+/// in equals the number of bytes out.
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "simple_private.h"
+
+
+/// Copied or encodes/decodes more data to out[].
+static lzma_ret
+copy_or_code(lzma_coder *coder, lzma_allocator *allocator,
+ const uint8_t *LZMA_RESTRICT in, size_t *LZMA_RESTRICT in_pos,
+ size_t in_size, uint8_t *LZMA_RESTRICT out,
+ size_t *LZMA_RESTRICT out_pos, size_t out_size, lzma_action action)
+{
+ assert(!coder->end_was_reached);
+
+ if (coder->next.code == NULL) {
+ lzma_bufcpy(in, in_pos, in_size, out, out_pos, out_size);
+
+ // Check if end of stream was reached.
+ if (coder->is_encoder && action == LZMA_FINISH
+ && *in_pos == in_size)
+ coder->end_was_reached = true;
+
+ } else {
+ // Call the next coder in the chain to provide us some data.
+ const lzma_ret ret = coder->next.code(
+ coder->next.coder, allocator,
+ in, in_pos, in_size,
+ out, out_pos, out_size, action);
+
+ if (ret == LZMA_STREAM_END) {
+ assert(!coder->is_encoder
+ || action == LZMA_FINISH);
+ coder->end_was_reached = true;
+
+ } else if (ret != LZMA_OK) {
+ return ret;
+ }
+ }
+
+ return LZMA_OK;
+}
+
+
+static size_t
+call_filter(lzma_coder *coder, uint8_t *buffer, size_t size)
+{
+ const size_t filtered = coder->filter(coder->simple,
+ coder->now_pos, coder->is_encoder,
+ buffer, size);
+ coder->now_pos += filtered;
+ return filtered;
+}
+
+
+static lzma_ret
+simple_code(lzma_coder *coder, lzma_allocator *allocator,
+ const uint8_t *LZMA_RESTRICT in, size_t *LZMA_RESTRICT in_pos,
+ size_t in_size, uint8_t *LZMA_RESTRICT out,
+ size_t *LZMA_RESTRICT out_pos, size_t out_size, lzma_action action)
+{
+ size_t out_avail;
+ size_t buf_avail;
+
+ // TODO: Add partial support for LZMA_SYNC_FLUSH. We can support it
+ // in cases when the filter is able to filter everything. With most
+ // simple filters it can be done at offset that is a multiple of 2,
+ // 4, or 16. With x86 filter, it needs good luck, and thus cannot
+ // be made to work predictably.
+ if (action == LZMA_SYNC_FLUSH)
+ return LZMA_OPTIONS_ERROR;
+
+ // Flush already filtered data from coder->buffer[] to out[].
+ if (coder->pos < coder->filtered) {
+ lzma_bufcpy(coder->buffer, &coder->pos, coder->filtered,
+ out, out_pos, out_size);
+
+ // If we couldn't flush all the filtered data, return to
+ // application immediately.
+ if (coder->pos < coder->filtered)
+ return LZMA_OK;
+
+ if (coder->end_was_reached) {
+ assert(coder->filtered == coder->size);
+ return LZMA_STREAM_END;
+ }
+ }
+
+ // If we get here, there is no filtered data left in the buffer.
+ coder->filtered = 0;
+
+ assert(!coder->end_was_reached);
+
+ // If there is more output space left than there is unfiltered data
+ // in coder->buffer[], flush coder->buffer[] to out[], and copy/code
+ // more data to out[] hopefully filling it completely. Then filter
+ // the data in out[]. This step is where most of the data gets
+ // filtered if the buffer sizes used by the application are reasonable.
+ out_avail = out_size - *out_pos;
+ buf_avail = coder->size - coder->pos;
+ if (out_avail > buf_avail || buf_avail == 0) {
+ size_t size;
+ size_t filtered;
+ size_t unfiltered;
+
+ // Store the old position so that we know from which byte
+ // to start filtering.
+ const size_t out_start = *out_pos;
+
+ // Flush data from coder->buffer[] to out[], but don't reset
+ // coder->pos and coder->size yet. This way the coder can be
+ // restarted if the next filter in the chain returns e.g.
+ // LZMA_MEM_ERROR.
+ memcpy(out + *out_pos, coder->buffer + coder->pos, buf_avail);
+ *out_pos += buf_avail;
+
+ // Copy/Encode/Decode more data to out[].
+ {
+ const lzma_ret ret = copy_or_code(coder, allocator,
+ in, in_pos, in_size,
+ out, out_pos, out_size, action);
+ assert(ret != LZMA_STREAM_END);
+ if (ret != LZMA_OK)
+ return ret;
+ }
+
+ // Filter out[].
+ size = *out_pos - out_start;
+ filtered = call_filter(coder, out + out_start, size);
+
+ unfiltered = size - filtered;
+ assert(unfiltered <= coder->allocated / 2);
+
+ // Now we can update coder->pos and coder->size, because
+ // the next coder in the chain (if any) was successful.
+ coder->pos = 0;
+ coder->size = unfiltered;
+
+ if (coder->end_was_reached) {
+ // The last byte has been copied to out[] already.
+ // They are left as is.
+ coder->size = 0;
+
+ } else if (unfiltered > 0) {
+ // There is unfiltered data left in out[]. Copy it to
+ // coder->buffer[] and rewind *out_pos appropriately.
+ *out_pos -= unfiltered;
+ memcpy(coder->buffer, out + *out_pos, unfiltered);
+ }
+ } else if (coder->pos > 0) {
+ memmove(coder->buffer, coder->buffer + coder->pos, buf_avail);
+ coder->size -= coder->pos;
+ coder->pos = 0;
+ }
+
+ assert(coder->pos == 0);
+
+ // If coder->buffer[] isn't empty, try to fill it by copying/decoding
+ // more data. Then filter coder->buffer[] and copy the successfully
+ // filtered data to out[]. It is probable, that some filtered and
+ // unfiltered data will be left to coder->buffer[].
+ if (coder->size > 0) {
+ {
+ const lzma_ret ret = copy_or_code(coder, allocator,
+ in, in_pos, in_size,
+ coder->buffer, &coder->size,
+ coder->allocated, action);
+ assert(ret != LZMA_STREAM_END);
+ if (ret != LZMA_OK)
+ return ret;
+ }
+
+ coder->filtered = call_filter(
+ coder, coder->buffer, coder->size);
+
+ // Everything is considered to be filtered if coder->buffer[]
+ // contains the last bytes of the data.
+ if (coder->end_was_reached)
+ coder->filtered = coder->size;
+
+ // Flush as much as possible.
+ lzma_bufcpy(coder->buffer, &coder->pos, coder->filtered,
+ out, out_pos, out_size);
+ }
+
+ // Check if we got everything done.
+ if (coder->end_was_reached && coder->pos == coder->size)
+ return LZMA_STREAM_END;
+
+ return LZMA_OK;
+}
+
+
+static void
+simple_coder_end(lzma_coder *coder, lzma_allocator *allocator)
+{
+ lzma_next_end(&coder->next, allocator);
+ lzma_free(coder->simple, allocator);
+ lzma_free(coder, allocator);
+ return;
+}
+
+
+static lzma_ret
+simple_coder_update(lzma_coder *coder, lzma_allocator *allocator,
+ const lzma_filter *filters_null lzma_attribute((__unused__)),
+ const lzma_filter *reversed_filters)
+{
+ // No update support, just call the next filter in the chain.
+ return lzma_next_filter_update(
+ &coder->next, allocator, reversed_filters + 1);
+}
+
+
+extern lzma_ret
+lzma_simple_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter_info *filters,
+ size_t (*filter)(lzma_simple *simple, uint32_t now_pos,
+ bool is_encoder, uint8_t *buffer, size_t size),
+ size_t simple_size, size_t unfiltered_max,
+ uint32_t alignment, bool is_encoder)
+{
+ // Allocate memory for the lzma_coder structure if needed.
+ if (next->coder == NULL) {
+ // Here we allocate space also for the temporary buffer. We
+ // need twice the size of unfiltered_max, because then it
+ // is always possible to filter at least unfiltered_max bytes
+ // more data in coder->buffer[] if it can be filled completely.
+ next->coder = lzma_alloc(sizeof(lzma_coder)
+ + 2 * unfiltered_max, allocator);
+ if (next->coder == NULL)
+ return LZMA_MEM_ERROR;
+
+ next->code = &simple_code;
+ next->end = &simple_coder_end;
+ next->update = &simple_coder_update;
+
+ next->coder->next = LZMA_NEXT_CODER_INIT;
+ next->coder->filter = filter;
+ next->coder->allocated = 2 * unfiltered_max;
+
+ // Allocate memory for filter-specific data structure.
+ if (simple_size > 0) {
+ next->coder->simple = lzma_alloc(
+ simple_size, allocator);
+ if (next->coder->simple == NULL)
+ return LZMA_MEM_ERROR;
+ } else {
+ next->coder->simple = NULL;
+ }
+ }
+
+ if (filters[0].options != NULL) {
+ const lzma_options_bcj *simple = filters[0].options;
+ next->coder->now_pos = simple->start_offset;
+ if (next->coder->now_pos & (alignment - 1))
+ return LZMA_OPTIONS_ERROR;
+ } else {
+ next->coder->now_pos = 0;
+ }
+
+ // Reset variables.
+ next->coder->is_encoder = is_encoder;
+ next->coder->end_was_reached = false;
+ next->coder->pos = 0;
+ next->coder->filtered = 0;
+ next->coder->size = 0;
+
+ return lzma_next_filter_init(
+ &next->coder->next, allocator, filters + 1);
+}
diff --git a/Utilities/cmliblzma/liblzma/simple/simple_coder.h b/Utilities/cmliblzma/liblzma/simple/simple_coder.h
new file mode 100644
index 000000000..0952fad33
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/simple/simple_coder.h
@@ -0,0 +1,60 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file simple_coder.h
+/// \brief Wrapper for simple filters
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_SIMPLE_CODER_H
+#define LZMA_SIMPLE_CODER_H
+
+#include "common.h"
+
+
+extern lzma_ret lzma_simple_x86_encoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters);
+
+extern lzma_ret lzma_simple_x86_decoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters);
+
+
+extern lzma_ret lzma_simple_powerpc_encoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters);
+
+extern lzma_ret lzma_simple_powerpc_decoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters);
+
+
+extern lzma_ret lzma_simple_ia64_encoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters);
+
+extern lzma_ret lzma_simple_ia64_decoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters);
+
+
+extern lzma_ret lzma_simple_arm_encoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters);
+
+extern lzma_ret lzma_simple_arm_decoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters);
+
+
+extern lzma_ret lzma_simple_armthumb_encoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters);
+
+extern lzma_ret lzma_simple_armthumb_decoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters);
+
+
+extern lzma_ret lzma_simple_sparc_encoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters);
+
+extern lzma_ret lzma_simple_sparc_decoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters);
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/simple/simple_decoder.c b/Utilities/cmliblzma/liblzma/simple/simple_decoder.c
new file mode 100644
index 000000000..034e158ff
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/simple/simple_decoder.c
@@ -0,0 +1,41 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file simple_decoder.c
+/// \brief Properties decoder for simple filters
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "simple_decoder.h"
+
+
+extern lzma_ret
+lzma_simple_props_decode(void **options, lzma_allocator *allocator,
+ const uint8_t *props, size_t props_size)
+{
+ lzma_options_bcj *opt;
+
+ if (props_size == 0)
+ return LZMA_OK;
+
+ if (props_size != 4)
+ return LZMA_OPTIONS_ERROR;
+
+ opt = lzma_alloc(sizeof(lzma_options_bcj), allocator);
+ if (opt == NULL)
+ return LZMA_MEM_ERROR;
+
+ opt->start_offset = unaligned_read32le(props);
+
+ // Don't leave an options structure allocated if start_offset is zero.
+ if (opt->start_offset == 0)
+ lzma_free(opt, allocator);
+ else
+ *options = opt;
+
+ return LZMA_OK;
+}
diff --git a/Utilities/cmliblzma/liblzma/simple/simple_decoder.h b/Utilities/cmliblzma/liblzma/simple/simple_decoder.h
new file mode 100644
index 000000000..b8bf590f7
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/simple/simple_decoder.h
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file simple_decoder.h
+/// \brief Properties decoder for simple filters
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_SIMPLE_DECODER_H
+#define LZMA_SIMPLE_DECODER_H
+
+#include "simple_coder.h"
+
+extern lzma_ret lzma_simple_props_decode(
+ void **options, lzma_allocator *allocator,
+ const uint8_t *props, size_t props_size);
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/simple/simple_encoder.c b/Utilities/cmliblzma/liblzma/simple/simple_encoder.c
new file mode 100644
index 000000000..8aa463bed
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/simple/simple_encoder.c
@@ -0,0 +1,38 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file simple_encoder.c
+/// \brief Properties encoder for simple filters
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "simple_encoder.h"
+
+
+extern lzma_ret
+lzma_simple_props_size(uint32_t *size, const void *options)
+{
+ const lzma_options_bcj *const opt = options;
+ *size = (opt == NULL || opt->start_offset == 0) ? 0 : 4;
+ return LZMA_OK;
+}
+
+
+extern lzma_ret
+lzma_simple_props_encode(const void *options, uint8_t *out)
+{
+ const lzma_options_bcj *const opt = options;
+
+ // The default start offset is zero, so we don't need to store any
+ // options unless the start offset is non-zero.
+ if (opt == NULL || opt->start_offset == 0)
+ return LZMA_OK;
+
+ unaligned_write32le(out, opt->start_offset);
+
+ return LZMA_OK;
+}
diff --git a/Utilities/cmliblzma/liblzma/simple/simple_encoder.h b/Utilities/cmliblzma/liblzma/simple/simple_encoder.h
new file mode 100644
index 000000000..1cee4823a
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/simple/simple_encoder.h
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file simple_encoder.c
+/// \brief Properties encoder for simple filters
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_SIMPLE_ENCODER_H
+#define LZMA_SIMPLE_ENCODER_H
+
+#include "simple_coder.h"
+
+
+extern lzma_ret lzma_simple_props_size(uint32_t *size, const void *options);
+
+extern lzma_ret lzma_simple_props_encode(const void *options, uint8_t *out);
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/simple/simple_private.h b/Utilities/cmliblzma/liblzma/simple/simple_private.h
new file mode 100644
index 000000000..fcf9f7c19
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/simple/simple_private.h
@@ -0,0 +1,75 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file simple_private.h
+/// \brief Private definitions for so called simple filters
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_SIMPLE_PRIVATE_H
+#define LZMA_SIMPLE_PRIVATE_H
+
+#include "simple_coder.h"
+
+
+typedef struct lzma_simple_s lzma_simple;
+
+struct lzma_coder_s {
+ /// Next filter in the chain
+ lzma_next_coder next;
+
+ /// True if the next coder in the chain has returned LZMA_STREAM_END.
+ bool end_was_reached;
+
+ /// True if filter() should encode the data; false to decode.
+ /// Currently all simple filters use the same function for encoding
+ /// and decoding, because the difference between encoders and decoders
+ /// is very small.
+ bool is_encoder;
+
+ /// Pointer to filter-specific function, which does
+ /// the actual filtering.
+ size_t (*filter)(lzma_simple *simple, uint32_t now_pos,
+ bool is_encoder, uint8_t *buffer, size_t size);
+
+ /// Pointer to filter-specific data, or NULL if filter doesn't need
+ /// any extra data.
+ lzma_simple *simple;
+
+ /// The lowest 32 bits of the current position in the data. Most
+ /// filters need this to do conversions between absolute and relative
+ /// addresses.
+ uint32_t now_pos;
+
+ /// Size of the memory allocated for the buffer.
+ size_t allocated;
+
+ /// Flushing position in the temporary buffer. buffer[pos] is the
+ /// next byte to be copied to out[].
+ size_t pos;
+
+ /// buffer[filtered] is the first unfiltered byte. When pos is smaller
+ /// than filtered, there is unflushed filtered data in the buffer.
+ size_t filtered;
+
+ /// Total number of bytes (both filtered and unfiltered) currently
+ /// in the temporary buffer.
+ size_t size;
+
+ /// Temporary buffer
+ uint8_t buffer[];
+};
+
+
+extern lzma_ret lzma_simple_coder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters,
+ size_t (*filter)(lzma_simple *simple, uint32_t now_pos,
+ bool is_encoder, uint8_t *buffer, size_t size),
+ size_t simple_size, size_t unfiltered_max,
+ uint32_t alignment, bool is_encoder);
+
+#endif
diff --git a/Utilities/cmliblzma/liblzma/simple/sparc.c b/Utilities/cmliblzma/liblzma/simple/sparc.c
new file mode 100644
index 000000000..0ddd2ac9d
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/simple/sparc.c
@@ -0,0 +1,82 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file sparc.c
+/// \brief Filter for SPARC binaries
+///
+// Authors: Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "simple_private.h"
+
+
+static size_t
+sparc_code(lzma_simple *simple lzma_attribute((__unused__)),
+ uint32_t now_pos, bool is_encoder,
+ uint8_t *buffer, size_t size)
+{
+ size_t i;
+ for (i = 0; i + 4 <= size; i += 4) {
+
+ if ((buffer[i] == 0x40 && (buffer[i + 1] & 0xC0) == 0x00)
+ || (buffer[i] == 0x7F
+ && (buffer[i + 1] & 0xC0) == 0xC0)) {
+
+ uint32_t dest;
+
+ uint32_t src = ((uint32_t)buffer[i + 0] << 24)
+ | ((uint32_t)buffer[i + 1] << 16)
+ | ((uint32_t)buffer[i + 2] << 8)
+ | ((uint32_t)buffer[i + 3]);
+
+ src <<= 2;
+
+ if (is_encoder)
+ dest = now_pos + (uint32_t)(i) + src;
+ else
+ dest = src - (now_pos + (uint32_t)(i));
+
+ dest >>= 2;
+
+ dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF)
+ | (dest & 0x3FFFFF)
+ | 0x40000000;
+
+ buffer[i + 0] = (uint8_t)(dest >> 24);
+ buffer[i + 1] = (uint8_t)(dest >> 16);
+ buffer[i + 2] = (uint8_t)(dest >> 8);
+ buffer[i + 3] = (uint8_t)(dest);
+ }
+ }
+
+ return i;
+}
+
+
+static lzma_ret
+sparc_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter_info *filters, bool is_encoder)
+{
+ return lzma_simple_coder_init(next, allocator, filters,
+ &sparc_code, 0, 4, 4, is_encoder);
+}
+
+
+extern lzma_ret
+lzma_simple_sparc_encoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters)
+{
+ return sparc_coder_init(next, allocator, filters, true);
+}
+
+
+extern lzma_ret
+lzma_simple_sparc_decoder_init(lzma_next_coder *next,
+ lzma_allocator *allocator, const lzma_filter_info *filters)
+{
+ return sparc_coder_init(next, allocator, filters, false);
+}
diff --git a/Utilities/cmliblzma/liblzma/simple/x86.c b/Utilities/cmliblzma/liblzma/simple/x86.c
new file mode 100644
index 000000000..101d8edff
--- /dev/null
+++ b/Utilities/cmliblzma/liblzma/simple/x86.c
@@ -0,0 +1,161 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file x86.c
+/// \brief Filter for x86 binaries (BCJ filter)
+///
+// Authors: Igor Pavlov
+// Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "simple_private.h"
+
+
+#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
+
+
+struct lzma_simple_s {
+ uint32_t prev_mask;
+ uint32_t prev_pos;
+};
+
+
+static size_t
+x86_code(lzma_simple *simple, uint32_t now_pos, bool is_encoder,
+ uint8_t *buffer, size_t size)
+{
+ static const bool MASK_TO_ALLOWED_STATUS[8]
+ = { true, true, true, false, true, false, false, false };
+
+ static const uint32_t MASK_TO_BIT_NUMBER[8]
+ = { 0, 1, 2, 2, 3, 3, 3, 3 };
+
+ uint32_t prev_mask = simple->prev_mask;
+ uint32_t prev_pos = simple->prev_pos;
+
+ size_t limit;
+ size_t buffer_pos;
+
+ if (size < 5)
+ return 0;
+
+ if (now_pos - prev_pos > 5)
+ prev_pos = now_pos - 5;
+
+ limit = size - 5;
+ buffer_pos = 0;
+
+ while (buffer_pos <= limit) {
+ uint32_t offset;
+ uint32_t i;
+
+ uint8_t b = buffer[buffer_pos];
+ if (b != 0xE8 && b != 0xE9) {
+ ++buffer_pos;
+ continue;
+ }
+
+ offset = now_pos + (uint32_t)(buffer_pos)
+ - prev_pos;
+ prev_pos = now_pos + (uint32_t)(buffer_pos);
+
+ if (offset > 5) {
+ prev_mask = 0;
+ } else {
+ for (i = 0; i < offset; ++i) {
+ prev_mask &= 0x77;
+ prev_mask <<= 1;
+ }
+ }
+
+ b = buffer[buffer_pos + 4];
+
+ if (Test86MSByte(b)
+ && MASK_TO_ALLOWED_STATUS[(prev_mask >> 1) & 0x7]
+ && (prev_mask >> 1) < 0x10) {
+
+ uint32_t src = ((uint32_t)(b) << 24)
+ | ((uint32_t)(buffer[buffer_pos + 3]) << 16)
+ | ((uint32_t)(buffer[buffer_pos + 2]) << 8)
+ | (buffer[buffer_pos + 1]);
+
+ uint32_t dest;
+ while (true) {
+ uint32_t i;
+
+ if (is_encoder)
+ dest = src + (now_pos + (uint32_t)(
+ buffer_pos) + 5);
+ else
+ dest = src - (now_pos + (uint32_t)(
+ buffer_pos) + 5);
+
+ if (prev_mask == 0)
+ break;
+
+ i = MASK_TO_BIT_NUMBER[prev_mask >> 1];
+
+ b = (uint8_t)(dest >> (24 - i * 8));
+
+ if (!Test86MSByte(b))
+ break;
+
+ src = dest ^ ((1 << (32 - i * 8)) - 1);
+ }
+
+ buffer[buffer_pos + 4]
+ = (uint8_t)(~(((dest >> 24) & 1) - 1));
+ buffer[buffer_pos + 3] = (uint8_t)(dest >> 16);
+ buffer[buffer_pos + 2] = (uint8_t)(dest >> 8);
+ buffer[buffer_pos + 1] = (uint8_t)(dest);
+ buffer_pos += 5;
+ prev_mask = 0;
+
+ } else {
+ ++buffer_pos;
+ prev_mask |= 1;
+ if (Test86MSByte(b))
+ prev_mask |= 0x10;
+ }
+ }
+
+ simple->prev_mask = prev_mask;
+ simple->prev_pos = prev_pos;
+
+ return buffer_pos;
+}
+
+
+static lzma_ret
+x86_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter_info *filters, bool is_encoder)
+{
+ const lzma_ret ret = lzma_simple_coder_init(next, allocator, filters,
+ &x86_code, sizeof(lzma_simple), 5, 1, is_encoder);
+
+ if (ret == LZMA_OK) {
+ next->coder->simple->prev_mask = 0;
+ next->coder->simple->prev_pos = (uint32_t)(-5);
+ }
+
+ return ret;
+}
+
+
+extern lzma_ret
+lzma_simple_x86_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter_info *filters)
+{
+ return x86_coder_init(next, allocator, filters, true);
+}
+
+
+extern lzma_ret
+lzma_simple_x86_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_filter_info *filters)
+{
+ return x86_coder_init(next, allocator, filters, false);
+}
diff --git a/Utilities/cmzlib/CMakeLists.txt b/Utilities/cmzlib/CMakeLists.txt
index f161056e5..0be48f107 100644
--- a/Utilities/cmzlib/CMakeLists.txt
+++ b/Utilities/cmzlib/CMakeLists.txt
@@ -1,5 +1,13 @@
PROJECT(CMZLIB)
+# Disable warnings to avoid changing 3rd party code.
+if(CMAKE_C_COMPILER_ID MATCHES
+ "^(GNU|Clang|AppleClang|XL|VisualAge|SunPro|MIPSpro|HP|Intel)$")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w")
+elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall")
+endif()
+
INCLUDE_DIRECTORIES(
"${CMZLIB_SOURCE_DIR}"
"${CMZLIB_SOURCE_DIR}/.."
@@ -18,12 +26,10 @@ IF(WIN32)
IF(BUILD_SHARED_LIBS)
SET(ZLIB_DLL 1)
IF(NOT UNIX)
- IF(NOT BORLAND)
- IF(NOT MINGW)
- SET(ZLIB_SRCS ${ZLIB_SRCS} zlib.def zlib.rc )
- ENDIF(NOT MINGW)
- ENDIF(NOT BORLAND)
- ENDIF(NOT UNIX)
+ IF(NOT MINGW)
+ SET(ZLIB_SRCS ${ZLIB_SRCS} zlib.def zlib.rc )
+ ENDIF(NOT MINGW)
+ ENDIF(NOT UNIX)
ENDIF(BUILD_SHARED_LIBS)
ENDIF(WIN32)
diff --git a/Utilities/cmzlib/zconf.h b/Utilities/cmzlib/zconf.h
index 6eb52d133..7a3b6fdc1 100644
--- a/Utilities/cmzlib/zconf.h
+++ b/Utilities/cmzlib/zconf.h
@@ -237,7 +237,7 @@
# endif
#endif
-#if defined (__BEOS__) && !defined (__HAIKU__)
+#if defined (__BEOS__)
# ifdef ZLIB_DLL
# ifdef ZLIB_INTERNAL
# define ZEXPORT __declspec(dllexport)
diff --git a/Utilities/cmzlib/zutil.h b/Utilities/cmzlib/zutil.h
index 74ef1f89f..3053cd8ee 100644
--- a/Utilities/cmzlib/zutil.h
+++ b/Utilities/cmzlib/zutil.h
@@ -147,12 +147,6 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
# define OS_CODE 0x0f
#endif
-/* Haiku defines both __HAIKU__ and __BEOS__ (for now) */
-/* many BeOS workarounds are no longer needed in Haiku */
-#if defined(__HAIKU__) && defined(__BEOS__)
-#undef __BEOS__
-#endif
-
#if defined(_BEOS_) || defined(RISCOS)
# define fdopen(fd,mode) NULL /* No fdopen() */
#endif
diff --git a/Utilities/xml/docbook-4.5/ChangeLog b/Utilities/xml/docbook-4.5/ChangeLog
deleted file mode 100644
index 06f59ce5c..000000000
--- a/Utilities/xml/docbook-4.5/ChangeLog
+++ /dev/null
@@ -1,106 +0,0 @@
-2006-10-03 13:23 nwalsh
-
- * trunk/docbook/sgml/catalog.xml, trunk/docbook/sgml/docbook.cat,
- trunk/docbook/sgml/docbook.dcl, trunk/docbook/sgml/docbook.dtd,
- calstblx.dtd, catalog.xml, dbcentx.mod, dbgenent.mod,
- dbhierx.mod, dbnotnx.mod, dbpoolx.mod, docbook.cat,
- docbookx.dtd, htmltblx.mod: DocBook V4.5 released
-
-2006-06-02 11:28 nwalsh
-
- * calstblx.dtd, catalog.xml, dbcentx.mod, dbgenent.mod,
- dbhierx.mod, dbnotnx.mod, dbpoolx.mod, docbook.cat,
- docbookx.dtd, freshmeat.xsl, htmltblx.mod: Changed copyright
- dates and version numbers
-
-2006-05-30 20:58 nwalsh
-
- * htmltblx.mod: Supply tag omission markers in SGML; suppress
- xml:lang in SGML
-
-2006-03-07 13:11 nwalsh
-
- * trunk/docbook/sgml/catalog.xml, trunk/docbook/sgml/docbook.cat,
- trunk/docbook/sgml/docbook.dcl, trunk/docbook/sgml/docbook.dtd,
- calstblx.dtd, catalog.xml, dbcentx.mod, dbgenent.mod,
- dbhierx.mod, dbnotnx.mod, dbpoolx.mod, docbook.cat,
- docbookx.dtd, freshmeat.xsl, htmltblx.mod: Change version
- numbers to 4.5CR2
-
-2006-03-07 13:03 nwalsh
-
- * dbpoolx.mod: Allow citebiblioid anywhere the other citation
- elements are allowed
-
-2006-02-16 21:12 nwalsh
-
- * calstblx.dtd, catalog.xml, dbcentx.mod, dbgenent.mod,
- dbhierx.mod, dbnotnx.mod, dbpoolx.mod, docbook.cat,
- docbookx.dtd, freshmeat.xsl, htmltblx.mod: DocBook V4.5 released
-
-2005-06-29 10:59 nwalsh
-
- * trunk/docbook/sgml/docbook.dtd, docbookx.dtd: DocBook V4.5CR1
- Released
-
-2005-06-29 10:58 nwalsh
-
- * trunk/docbook/sgml/catalog.xml, trunk/docbook/sgml/docbook.cat,
- trunk/docbook/sgml/docbook.dcl, calstblx.dtd, catalog.xml,
- dbcentx.mod, dbgenent.mod, dbhierx.mod, dbnotnx.mod,
- dbpoolx.mod, docbook.cat, htmltblx.mod: Updated version number
-
-2005-06-29 10:53 nwalsh
-
- * freshmeat.xsl: Tweaked freshmeat changes
-
-2005-06-24 21:09 nwalsh
-
- * calstblx.dtd, dbhierx.mod, dbpoolx.mod, htmltblx.mod,
- soextblx.dtd: Added doc: structured comments
-
-2005-05-05 11:41 nwalsh
-
- * trunk/docbook/sgml/docbook.dtd, docbookx.dtd: DocBook V4.5b1
- Released
-
-2005-05-05 11:40 nwalsh
-
- * trunk/docbook/sgml/catalog.xml, trunk/docbook/sgml/docbook.cat,
- trunk/docbook/sgml/docbook.dcl, calstblx.dtd, catalog.xml,
- dbcentx.mod, dbgenent.mod, dbhierx.mod, dbnotnx.mod,
- dbpoolx.mod, docbook.cat, htmltblx.mod: Updated version number
-
-2005-05-05 11:37 nwalsh
-
- * freshmeat.xsl: Prepare for 4.5b1
-
-2005-05-05 10:59 nwalsh
-
- * dbpoolx.mod: RFE 1055480: Make revnumber optional
-
-2005-05-05 10:54 nwalsh
-
- * dbpoolx.mod, htmltblx.mod: Allow common attributes on HTML table
- elements
-
-2005-05-05 10:48 nwalsh
-
- * dbpoolx.mod: Added termdef
-
-2005-05-05 10:39 nwalsh
-
- * dbpoolx.mod: Added mathphrase
-
-2005-05-05 10:33 nwalsh
-
- * dbhierx.mod: RFE 1070458: Allow colophon in article
-
-2005-05-05 10:32 nwalsh
-
- * dbpoolx.mod: RFE 1070770: Allow procedure in example
-
-2005-05-05 10:21 nwalsh
-
- * dbpoolx.mod: Add isrn to list of biblioid class attribute values
-
diff --git a/Utilities/xml/docbook-4.5/README b/Utilities/xml/docbook-4.5/README
deleted file mode 100644
index 6fc60c4bf..000000000
--- a/Utilities/xml/docbook-4.5/README
+++ /dev/null
@@ -1,8 +0,0 @@
-README for the DocBook XML DTD
-
-For more information about DocBook, please see
-
- http://www.oasis-open.org/docbook/
-
-Please send all questions, comments, concerns, and bug reports to the
-DocBook mailing list: docbook@lists.oasis-open.org
diff --git a/Utilities/xml/docbook-4.5/calstblx.dtd b/Utilities/xml/docbook-4.5/calstblx.dtd
deleted file mode 100644
index fac58d77e..000000000
--- a/Utilities/xml/docbook-4.5/calstblx.dtd
+++ /dev/null
@@ -1,215 +0,0 @@
-<!-- ...................................................................... -->
-<!-- DocBook CALS Table Model V4.5 ........................................ -->
-<!-- File calstblx.mod .................................................... -->
-
-<!-- Copyright 1992-2002 HaL Computer Systems, Inc.,
- O'Reilly & Associates, Inc., ArborText, Inc., Fujitsu Software
- Corporation, Norman Walsh, Sun Microsystems, Inc., and the
- Organization for the Advancement of Structured Information
- Standards (OASIS).
-
- This DTD is based on the CALS Table Model
- PUBLIC "-//USA-DOD//DTD Table Model 951010//EN"
-
- $Id: calstblx.dtd 6340 2006-10-03 13:23:24Z nwalsh $
-
- Permission to use, copy, modify and distribute the DocBook DTD
- and its accompanying documentation for any purpose and without fee
- is hereby granted in perpetuity, provided that the above copyright
- notice and this paragraph appear in all copies. The copyright
- holders make no representation about the suitability of the DTD for
- any purpose. It is provided "as is" without expressed or implied
- warranty.
-
- If you modify the DocBook DTD in any way, except for declaring and
- referencing additional sets of general entities and declaring
- additional notations, label your DTD as a variant of DocBook. See
- the maintenance documentation for more information.
-
- Please direct all questions, bug reports, or suggestions for
- changes to the docbook@lists.oasis-open.org mailing list. For more
- information, see http://www.oasis-open.org/docbook/.
--->
-
-<!-- ...................................................................... -->
-
-<!-- This module contains the definitions for the CALS Table Model
- converted to XML. It has been modified slightly for use in the
- combined HTML/CALS models supported by DocBook V4.5.
--->
-
-<!-- These definitions are not directly related to the table model, but are
- used in the default CALS table model and are usually defined elsewhere
- (and prior to the inclusion of this table module) in a CALS DTD. -->
-
-<!ENTITY % bodyatt "">
-<!ENTITY % secur "">
-
-<!-- no if zero(s),
- yes if any other digits value -->
-
-<!ENTITY % yesorno 'CDATA'>
-<!ENTITY % titles 'title?'>
-
-<!-- default for use in entry content -->
-
-<!ENTITY % paracon '#PCDATA'>
-
-<!--
-The parameter entities as defined below provide the CALS table model
-as published (as part of the Example DTD) in MIL-HDBK-28001.
-
-These following declarations provide the CALS-compliant default definitions
-for these entities. However, these entities can and should be redefined
-(by giving the appropriate parameter entity declaration(s) prior to the
-reference to this Table Model declaration set entity) to fit the needs
-of the current application.
--->
-
-<!ENTITY % tbl.table.name "(table|chart)">
-<!ENTITY % tbl.table-titles.mdl "%titles;,">
-<!ENTITY % tbl.table-main.mdl "(tgroup+|graphic+)">
-<!ENTITY % tbl.table.mdl "%tbl.table-titles.mdl; %tbl.table-main.mdl;">
-<!ENTITY % tbl.table.att '
- tabstyle CDATA #IMPLIED
- tocentry %yesorno; #IMPLIED
- shortentry %yesorno; #IMPLIED
- orient (port|land) #IMPLIED
- pgwide %yesorno; #IMPLIED '>
-<!ENTITY % tbl.tgroup.mdl "colspec*,spanspec*,thead?,tfoot?,tbody">
-<!ENTITY % tbl.tgroup.att '
- tgroupstyle CDATA #IMPLIED '>
-<!ENTITY % tbl.hdft.mdl "colspec*,row+">
-<!ENTITY % tbl.row.mdl "(entry|entrytbl)+">
-<!ENTITY % tbl.entrytbl.mdl "colspec*,spanspec*,thead?,tbody">
-<!ENTITY % tbl.entry.mdl "(para|warning|caution|note|legend|%paracon;)*">
-
-<!ENTITY % tbl.frame.attval "top|bottom|topbot|all|sides|none">
-<!ENTITY % tbl.tbody.mdl "row+">
-
-<!-- ===== Element and attribute declarations follow. ===== -->
-
-<!--doc:A formal table in a document.-->
-<!ELEMENT table %ho; (%tbl.table.mdl;)>
-
-<!ATTLIST table
- frame (%tbl.frame.attval;) #IMPLIED
- colsep %yesorno; #IMPLIED
- rowsep %yesorno; #IMPLIED
- %tbl.table.att;
- %bodyatt;
- %secur;
->
-
-<!--doc:A wrapper for the main content of a table, or part of a table.-->
-<!ELEMENT tgroup %ho; (%tbl.tgroup.mdl;) >
-
-<!ATTLIST tgroup
- cols CDATA #REQUIRED
- %tbl.tgroup.att;
- colsep %yesorno; #IMPLIED
- rowsep %yesorno; #IMPLIED
- align (left|right|center|justify|char) #IMPLIED
- char CDATA #IMPLIED
- charoff CDATA #IMPLIED
- %secur;
->
-
-<!--doc:Specifications for a column in a table.-->
-<!ELEMENT colspec %ho; EMPTY >
-
-<!ATTLIST colspec
- colnum CDATA #IMPLIED
- colname CDATA #IMPLIED
- colwidth CDATA #IMPLIED
- colsep %yesorno; #IMPLIED
- rowsep %yesorno; #IMPLIED
- align (left|right|center|justify|char) #IMPLIED
- char CDATA #IMPLIED
- charoff CDATA #IMPLIED
->
-
-<!--doc:Formatting information for a spanned column in a table.-->
-<!ELEMENT spanspec %ho; EMPTY >
-
-<!ATTLIST spanspec
- namest CDATA #REQUIRED
- nameend CDATA #REQUIRED
- spanname CDATA #REQUIRED
- colsep %yesorno; #IMPLIED
- rowsep %yesorno; #IMPLIED
- align (left|right|center|justify|char) #IMPLIED
- char CDATA #IMPLIED
- charoff CDATA #IMPLIED
->
-
-<!--doc:A table header consisting of one or more rows.-->
-<!ELEMENT thead %ho; (%tbl.hdft.mdl;)>
-<!ATTLIST thead
- valign (top|middle|bottom) #IMPLIED
- %secur;
->
-
-<!--doc:A table footer consisting of one or more rows.-->
-<!ELEMENT tfoot %ho; (%tbl.hdft.mdl;)>
-<!ATTLIST tfoot
- valign (top|middle|bottom) #IMPLIED
- %secur;
->
-
-<!--doc:A wrapper for the rows of a table or informal table.-->
-<!ELEMENT tbody %ho; (%tbl.tbody.mdl;)>
-
-<!ATTLIST tbody
- valign (top|middle|bottom) #IMPLIED
- %secur;
->
-
-<!--doc:A row in a table.-->
-<!ELEMENT row %ho; (%tbl.row.mdl;)>
-
-<!ATTLIST row
- rowsep %yesorno; #IMPLIED
- valign (top|middle|bottom) #IMPLIED
- %secur;
->
-
-<!--doc:A subtable appearing in place of an Entry in a table.-->
-<!ELEMENT entrytbl %ho; (%tbl.entrytbl.mdl;)>
-
-<!ATTLIST entrytbl
- cols CDATA #REQUIRED
- %tbl.tgroup.att;
- colname CDATA #IMPLIED
- spanname CDATA #IMPLIED
- namest CDATA #IMPLIED
- nameend CDATA #IMPLIED
- colsep %yesorno; #IMPLIED
- rowsep %yesorno; #IMPLIED
- align (left|right|center|justify|char) #IMPLIED
- char CDATA #IMPLIED
- charoff CDATA #IMPLIED
- %secur;
->
-
-<!--doc:A cell in a table.-->
-<!ELEMENT entry %ho; (%tbl.entry.mdl;)*>
-
-<!ATTLIST entry
- colname CDATA #IMPLIED
- namest CDATA #IMPLIED
- nameend CDATA #IMPLIED
- spanname CDATA #IMPLIED
- morerows CDATA #IMPLIED
- colsep %yesorno; #IMPLIED
- rowsep %yesorno; #IMPLIED
- align (left|right|center|justify|char) #IMPLIED
- char CDATA #IMPLIED
- charoff CDATA #IMPLIED
- rotate %yesorno; #IMPLIED
- valign (top|middle|bottom) #IMPLIED
- %secur;
->
-
-<!-- End of DocBook CALS Table Model V4.5 ................................. -->
-<!-- ...................................................................... -->
diff --git a/Utilities/xml/docbook-4.5/catalog.xml b/Utilities/xml/docbook-4.5/catalog.xml
deleted file mode 100644
index f75c1d764..000000000
--- a/Utilities/xml/docbook-4.5/catalog.xml
+++ /dev/null
@@ -1,124 +0,0 @@
-<?xml version='1.0'?>
-<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="public">
-
-<!-- ...................................................................... -->
-<!-- XML Catalog data for DocBook XML V4.5 ................................ -->
-<!-- File catalog.xml ..................................................... -->
-
-<!-- Please direct all questions, bug reports, or suggestions for
- changes to the docbook@lists.oasis-open.org mailing list. For more
- information, see http://www.oasis-open.org/.
- -->
-
-<!-- This is the catalog data file for DocBook V4.5. It is provided as
- a convenience in building your own catalog files. You need not use
- the filenames listed here, and need not use the filename method of
- identifying storage objects at all. See the documentation for
- detailed information on the files associated with the DocBook DTD.
- See XML Catalogs at http://www.oasis-open.org/committees/entity/ for
- detailed information on supplying and using catalog data.
- -->
-
-<!-- ...................................................................... -->
-<!-- DocBook driver file .................................................. -->
-
-<public publicId="-//OASIS//DTD DocBook XML V4.5//EN"
- uri="docbookx.dtd"/>
-
-<system systemId="http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
- uri="docbookx.dtd"/>
-
-<system systemId="http://docbook.org/xml/4.5/docbookx.dtd"
- uri="docbookx.dtd"/>
-
-<!-- ...................................................................... -->
-<!-- DocBook modules ...................................................... -->
-
-<public publicId="-//OASIS//DTD DocBook CALS Table Model V4.5//EN"
- uri="calstblx.dtd"/>
-
-<public publicId="-//OASIS//ELEMENTS DocBook XML HTML Tables V4.5//EN"
- uri="htmltblx.mod"/>
-
-<public publicId="-//OASIS//DTD XML Exchange Table Model 19990315//EN"
- uri="soextblx.dtd"/>
-
-<public publicId="-//OASIS//ELEMENTS DocBook Information Pool V4.5//EN"
- uri="dbpoolx.mod"/>
-
-<public publicId="-//OASIS//ELEMENTS DocBook Document Hierarchy V4.5//EN"
- uri="dbhierx.mod"/>
-
-<public publicId="-//OASIS//ENTITIES DocBook Additional General Entities V4.5//EN"
- uri="dbgenent.mod"/>
-
-<public publicId="-//OASIS//ENTITIES DocBook Notations V4.5//EN"
- uri="dbnotnx.mod"/>
-
-<public publicId="-//OASIS//ENTITIES DocBook Character Entities V4.5//EN"
- uri="dbcentx.mod"/>
-
-<!-- ...................................................................... -->
-<!-- ISO entity sets ...................................................... -->
-
-<public publicId="ISO 8879:1986//ENTITIES Diacritical Marks//EN//XML"
- uri="ent/isodia.ent"/>
-
-<public publicId="ISO 8879:1986//ENTITIES Numeric and Special Graphic//EN//XML"
- uri="ent/isonum.ent"/>
-
-<public publicId="ISO 8879:1986//ENTITIES Publishing//EN//XML"
- uri="ent/isopub.ent"/>
-
-<public publicId="ISO 8879:1986//ENTITIES General Technical//EN//XML"
- uri="ent/isotech.ent"/>
-
-<public publicId="ISO 8879:1986//ENTITIES Added Latin 1//EN//XML"
- uri="ent/isolat1.ent"/>
-
-<public publicId="ISO 8879:1986//ENTITIES Added Latin 2//EN//XML"
- uri="ent/isolat2.ent"/>
-
-<public publicId="ISO 8879:1986//ENTITIES Greek Letters//EN//XML"
- uri="ent/isogrk1.ent"/>
-
-<public publicId="ISO 8879:1986//ENTITIES Monotoniko Greek//EN//XML"
- uri="ent/isogrk2.ent"/>
-
-<public publicId="ISO 8879:1986//ENTITIES Greek Symbols//EN//XML"
- uri="ent/isogrk3.ent"/>
-
-<public publicId="ISO 8879:1986//ENTITIES Alternative Greek Symbols//EN//XML"
- uri="ent/isogrk4.ent"/>
-
-<public publicId="ISO 8879:1986//ENTITIES Added Math Symbols: Arrow Relations//EN//XML"
- uri="ent/isoamsa.ent"/>
-
-<public publicId="ISO 8879:1986//ENTITIES Added Math Symbols: Binary Operators//EN//XML"
- uri="ent/isoamsb.ent"/>
-
-<public publicId="ISO 8879:1986//ENTITIES Added Math Symbols: Delimiters//EN//XML"
- uri="ent/isoamsc.ent"/>
-
-<public publicId="ISO 8879:1986//ENTITIES Added Math Symbols: Negated Relations//EN//XML"
- uri="ent/isoamsn.ent"/>
-
-<public publicId="ISO 8879:1986//ENTITIES Added Math Symbols: Ordinary//EN//XML"
- uri="ent/isoamso.ent"/>
-
-<public publicId="ISO 8879:1986//ENTITIES Added Math Symbols: Relations//EN//XML"
- uri="ent/isoamsr.ent"/>
-
-<public publicId="ISO 8879:1986//ENTITIES Box and Line Drawing//EN//XML"
- uri="ent/isobox.ent"/>
-
-<public publicId="ISO 8879:1986//ENTITIES Russian Cyrillic//EN//XML"
- uri="ent/isocyr1.ent"/>
-
-<public publicId="ISO 8879:1986//ENTITIES Non-Russian Cyrillic//EN//XML"
- uri="ent/isocyr2.ent"/>
-
-<!-- End of catalog data for DocBook XML V4.5 ............................. -->
-<!-- ...................................................................... -->
-
-</catalog>
diff --git a/Utilities/xml/docbook-4.5/dbcentx.mod b/Utilities/xml/docbook-4.5/dbcentx.mod
deleted file mode 100644
index 60de99f86..000000000
--- a/Utilities/xml/docbook-4.5/dbcentx.mod
+++ /dev/null
@@ -1,384 +0,0 @@
-<!-- ...................................................................... -->
-<!-- DocBook character entities module V4.5 ............................... -->
-<!-- File dbcentx.mod ..................................................... -->
-
-<!-- Copyright 1992-2004 HaL Computer Systems, Inc.,
- O'Reilly & Associates, Inc., ArborText, Inc., Fujitsu Software
- Corporation, Norman Walsh, Sun Microsystems, Inc., and the
- Organization for the Advancement of Structured Information
- Standards (OASIS).
-
- $Id: dbcentx.mod 6340 2006-10-03 13:23:24Z nwalsh $
-
- Permission to use, copy, modify and distribute the DocBook DTD
- and its accompanying documentation for any purpose and without fee
- is hereby granted in perpetuity, provided that the above copyright
- notice and this paragraph appear in all copies. The copyright
- holders make no representation about the suitability of the DTD for
- any purpose. It is provided "as is" without expressed or implied
- warranty.
-
- If you modify the DocBook DTD in any way, except for declaring and
- referencing additional sets of general entities and declaring
- additional notations, label your DTD as a variant of DocBook. See
- the maintenance documentation for more information.
-
- Please direct all questions, bug reports, or suggestions for
- changes to the docbook@lists.oasis-open.org mailing list. For more
- information, see http://www.oasis-open.org/docbook/.
--->
-
-<!-- ...................................................................... -->
-
-<!-- This module contains the entity declarations for the standard ISO
- entity sets used by DocBook.
-
- In DTD driver files referring to this module, please use an entity
- declaration that uses the public identifier shown below:
-
- <!ENTITY % dbcent PUBLIC
- "-//OASIS//ENTITIES DocBook Character Entities V4.5//EN"
- "dbcentx.mod">
- %dbcent;
-
- See the documentation for detailed information on the parameter
- entity and module scheme used in DocBook, customizing DocBook and
- planning for interchange, and changes made since the last release
- of DocBook.
--->
-
-<!-- ...................................................................... -->
-
-<![%sgml.features;[
-
-<!ENTITY % ISOamsa.module "INCLUDE">
-<![ %ISOamsa.module; [
-<!ENTITY % ISOamsa PUBLIC
-"ISO 8879:1986//ENTITIES Added Math Symbols: Arrow Relations//EN">
-<!--end of ISOamsa.module-->]]>
-
-<!ENTITY % ISOamsb.module "INCLUDE">
-<![ %ISOamsb.module; [
-<!ENTITY % ISOamsb PUBLIC
-"ISO 8879:1986//ENTITIES Added Math Symbols: Binary Operators//EN">
-<!--end of ISOamsb.module-->]]>
-
-<!ENTITY % ISOamsc.module "INCLUDE">
-<![ %ISOamsc.module; [
-<!ENTITY % ISOamsc PUBLIC
-"ISO 8879:1986//ENTITIES Added Math Symbols: Delimiters//EN">
-<!--end of ISOamsc.module-->]]>
-
-<!ENTITY % ISOamsn.module "INCLUDE">
-<![ %ISOamsn.module; [
-<!ENTITY % ISOamsn PUBLIC
-"ISO 8879:1986//ENTITIES Added Math Symbols: Negated Relations//EN">
-<!--end of ISOamsn.module-->]]>
-
-<!ENTITY % ISOamso.module "INCLUDE">
-<![ %ISOamso.module; [
-<!ENTITY % ISOamso PUBLIC
-"ISO 8879:1986//ENTITIES Added Math Symbols: Ordinary//EN">
-<!--end of ISOamso.module-->]]>
-
-<!ENTITY % ISOamsr.module "INCLUDE">
-<![ %ISOamsr.module; [
-<!ENTITY % ISOamsr PUBLIC
-"ISO 8879:1986//ENTITIES Added Math Symbols: Relations//EN">
-<!--end of ISOamsr.module-->]]>
-
-<!ENTITY % ISObox.module "INCLUDE">
-<![ %ISObox.module; [
-<!ENTITY % ISObox PUBLIC
-"ISO 8879:1986//ENTITIES Box and Line Drawing//EN">
-<!--end of ISObox.module-->]]>
-
-<!ENTITY % ISOcyr1.module "INCLUDE">
-<![ %ISOcyr1.module; [
-<!ENTITY % ISOcyr1 PUBLIC
-"ISO 8879:1986//ENTITIES Russian Cyrillic//EN">
-<!--end of ISOcyr1.module-->]]>
-
-<!ENTITY % ISOcyr2.module "INCLUDE">
-<![ %ISOcyr2.module; [
-<!ENTITY % ISOcyr2 PUBLIC
-"ISO 8879:1986//ENTITIES Non-Russian Cyrillic//EN">
-<!--end of ISOcyr2.module-->]]>
-
-<!ENTITY % ISOdia.module "INCLUDE">
-<![ %ISOdia.module; [
-<!ENTITY % ISOdia PUBLIC
-"ISO 8879:1986//ENTITIES Diacritical Marks//EN">
-<!--end of ISOdia.module-->]]>
-
-<!ENTITY % ISOgrk1.module "INCLUDE">
-<![ %ISOgrk1.module; [
-<!ENTITY % ISOgrk1 PUBLIC
-"ISO 8879:1986//ENTITIES Greek Letters//EN">
-<!--end of ISOgrk1.module-->]]>
-
-<!ENTITY % ISOgrk2.module "INCLUDE">
-<![ %ISOgrk2.module; [
-<!ENTITY % ISOgrk2 PUBLIC
-"ISO 8879:1986//ENTITIES Monotoniko Greek//EN">
-<!--end of ISOgrk2.module-->]]>
-
-<!ENTITY % ISOgrk3.module "INCLUDE">
-<![ %ISOgrk3.module; [
-<!ENTITY % ISOgrk3 PUBLIC
-"ISO 8879:1986//ENTITIES Greek Symbols//EN">
-<!--end of ISOgrk3.module-->]]>
-
-<!ENTITY % ISOgrk4.module "INCLUDE">
-<![ %ISOgrk4.module; [
-<!ENTITY % ISOgrk4 PUBLIC
-"ISO 8879:1986//ENTITIES Alternative Greek Symbols//EN">
-<!--end of ISOgrk4.module-->]]>
-
-<!ENTITY % ISOlat1.module "INCLUDE">
-<![ %ISOlat1.module; [
-<!ENTITY % ISOlat1 PUBLIC
-"ISO 8879:1986//ENTITIES Added Latin 1//EN">
-<!--end of ISOlat1.module-->]]>
-
-<!ENTITY % ISOlat2.module "INCLUDE">
-<![ %ISOlat2.module; [
-<!ENTITY % ISOlat2 PUBLIC
-"ISO 8879:1986//ENTITIES Added Latin 2//EN">
-<!--end of ISOlat2.module-->]]>
-
-<!ENTITY % ISOnum.module "INCLUDE">
-<![ %ISOnum.module; [
-<!ENTITY % ISOnum PUBLIC
-"ISO 8879:1986//ENTITIES Numeric and Special Graphic//EN">
-<!--end of ISOnum.module-->]]>
-
-<!ENTITY % ISOpub.module "INCLUDE">
-<![ %ISOpub.module; [
-<!ENTITY % ISOpub PUBLIC
-"ISO 8879:1986//ENTITIES Publishing//EN">
-<!--end of ISOpub.module-->]]>
-
-<!ENTITY % ISOtech.module "INCLUDE">
-<![ %ISOtech.module; [
-<!ENTITY % ISOtech PUBLIC
-"ISO 8879:1986//ENTITIES General Technical//EN">
-<!--end of ISOtech.module-->]]>
-
-<!--end of sgml.features-->]]>
-
-<![%xml.features;[
-
-<!ENTITY % ISOamsa.module "INCLUDE">
-<![%ISOamsa.module;[
-<!ENTITY % ISOamsa PUBLIC
-"ISO 8879:1986//ENTITIES Added Math Symbols: Arrow Relations//EN//XML"
-"ent/isoamsa.ent">
-<!--end of ISOamsa.module-->]]>
-
-<!ENTITY % ISOamsb.module "INCLUDE">
-<![%ISOamsb.module;[
-<!ENTITY % ISOamsb PUBLIC
-"ISO 8879:1986//ENTITIES Added Math Symbols: Binary Operators//EN//XML"
-"ent/isoamsb.ent">
-<!--end of ISOamsb.module-->]]>
-
-<!ENTITY % ISOamsc.module "INCLUDE">
-<![%ISOamsc.module;[
-<!ENTITY % ISOamsc PUBLIC
-"ISO 8879:1986//ENTITIES Added Math Symbols: Delimiters//EN//XML"
-"ent/isoamsc.ent">
-<!--end of ISOamsc.module-->]]>
-
-<!ENTITY % ISOamsn.module "INCLUDE">
-<![%ISOamsn.module;[
-<!ENTITY % ISOamsn PUBLIC
-"ISO 8879:1986//ENTITIES Added Math Symbols: Negated Relations//EN//XML"
-"ent/isoamsn.ent">
-<!--end of ISOamsn.module-->]]>
-
-<!ENTITY % ISOamso.module "INCLUDE">
-<![%ISOamso.module;[
-<!ENTITY % ISOamso PUBLIC
-"ISO 8879:1986//ENTITIES Added Math Symbols: Ordinary//EN//XML"
-"ent/isoamso.ent">
-<!--end of ISOamso.module-->]]>
-
-<!ENTITY % ISOamsr.module "INCLUDE">
-<![%ISOamsr.module;[
-<!ENTITY % ISOamsr PUBLIC
-"ISO 8879:1986//ENTITIES Added Math Symbols: Relations//EN//XML"
-"ent/isoamsr.ent">
-<!--end of ISOamsr.module-->]]>
-
-<!ENTITY % ISObox.module "INCLUDE">
-<![%ISObox.module;[
-<!ENTITY % ISObox PUBLIC
-"ISO 8879:1986//ENTITIES Box and Line Drawing//EN//XML"
-"ent/isobox.ent">
-<!--end of ISObox.module-->]]>
-
-<!ENTITY % ISOcyr1.module "INCLUDE">
-<![%ISOcyr1.module;[
-<!ENTITY % ISOcyr1 PUBLIC
-"ISO 8879:1986//ENTITIES Russian Cyrillic//EN//XML"
-"ent/isocyr1.ent">
-<!--end of ISOcyr1.module-->]]>
-
-<!ENTITY % ISOcyr2.module "INCLUDE">
-<![%ISOcyr2.module;[
-<!ENTITY % ISOcyr2 PUBLIC
-"ISO 8879:1986//ENTITIES Non-Russian Cyrillic//EN//XML"
-"ent/isocyr2.ent">
-<!--end of ISOcyr2.module-->]]>
-
-<!ENTITY % ISOdia.module "INCLUDE">
-<![%ISOdia.module;[
-<!ENTITY % ISOdia PUBLIC
-"ISO 8879:1986//ENTITIES Diacritical Marks//EN//XML"
-"ent/isodia.ent">
-<!--end of ISOdia.module-->]]>
-
-<!ENTITY % ISOgrk1.module "INCLUDE">
-<![%ISOgrk1.module;[
-<!ENTITY % ISOgrk1 PUBLIC
-"ISO 8879:1986//ENTITIES Greek Letters//EN//XML"
-"ent/isogrk1.ent">
-<!--end of ISOgrk1.module-->]]>
-
-<!ENTITY % ISOgrk2.module "INCLUDE">
-<![%ISOgrk2.module;[
-<!ENTITY % ISOgrk2 PUBLIC
-"ISO 8879:1986//ENTITIES Monotoniko Greek//EN//XML"
-"ent/isogrk2.ent">
-<!--end of ISOgrk2.module-->]]>
-
-<!ENTITY % ISOgrk3.module "INCLUDE">
-<![%ISOgrk3.module;[
-<!ENTITY % ISOgrk3 PUBLIC
-"ISO 8879:1986//ENTITIES Greek Symbols//EN//XML"
-"ent/isogrk3.ent">
-<!--end of ISOgrk3.module-->]]>
-
-<!ENTITY % ISOgrk4.module "INCLUDE">
-<![%ISOgrk4.module;[
-<!ENTITY % ISOgrk4 PUBLIC
-"ISO 8879:1986//ENTITIES Alternative Greek Symbols//EN//XML"
-"ent/isogrk4.ent">
-<!--end of ISOgrk4.module-->]]>
-
-<!ENTITY % ISOlat1.module "INCLUDE">
-<![%ISOlat1.module;[
-<!ENTITY % ISOlat1 PUBLIC
-"ISO 8879:1986//ENTITIES Added Latin 1//EN//XML"
-"ent/isolat1.ent">
-<!--end of ISOlat1.module-->]]>
-
-<!ENTITY % ISOlat2.module "INCLUDE">
-<![%ISOlat2.module;[
-<!ENTITY % ISOlat2 PUBLIC
-"ISO 8879:1986//ENTITIES Added Latin 2//EN//XML"
-"ent/isolat2.ent">
-<!--end of ISOlat2.module-->]]>
-
-<!ENTITY % ISOnum.module "INCLUDE">
-<![%ISOnum.module;[
-<!ENTITY % ISOnum PUBLIC
-"ISO 8879:1986//ENTITIES Numeric and Special Graphic//EN//XML"
-"ent/isonum.ent">
-<!--end of ISOnum.module-->]]>
-
-<!ENTITY % ISOpub.module "INCLUDE">
-<![%ISOpub.module;[
-<!ENTITY % ISOpub PUBLIC
-"ISO 8879:1986//ENTITIES Publishing//EN//XML"
-"ent/isopub.ent">
-<!--end of ISOpub.module-->]]>
-
-<!ENTITY % ISOtech.module "INCLUDE">
-<![%ISOtech.module;[
-<!ENTITY % ISOtech PUBLIC
-"ISO 8879:1986//ENTITIES General Technical//EN//XML"
-"ent/isotech.ent">
-<!--end of ISOtech.module-->]]>
-
-<!--end of xml.features-->]]>
-
-<![ %ISOamsa.module; [
-%ISOamsa;
-]]>
-
-<![ %ISOamsb.module; [
-%ISOamsb;
-]]>
-
-<![ %ISOamsc.module; [
-%ISOamsc;
-]]>
-
-<![ %ISOamsn.module; [
-%ISOamsn;
-]]>
-
-<![ %ISOamso.module; [
-%ISOamso;
-]]>
-
-<![ %ISOamsr.module; [
-%ISOamsr;
-]]>
-
-<![ %ISObox.module; [
-%ISObox;
-]]>
-
-<![ %ISOcyr1.module; [
-%ISOcyr1;
-]]>
-
-<![ %ISOcyr2.module; [
-%ISOcyr2;
-]]>
-
-<![ %ISOdia.module; [
-%ISOdia;
-]]>
-
-<![ %ISOgrk1.module; [
-%ISOgrk1;
-]]>
-
-<![ %ISOgrk2.module; [
-%ISOgrk2;
-]]>
-
-<![ %ISOgrk3.module; [
-%ISOgrk3;
-]]>
-
-<![ %ISOgrk4.module; [
-%ISOgrk4;
-]]>
-
-<![ %ISOlat1.module; [
-%ISOlat1;
-]]>
-
-<![ %ISOlat2.module; [
-%ISOlat2;
-]]>
-
-<![ %ISOnum.module; [
-%ISOnum;
-]]>
-
-<![ %ISOpub.module; [
-%ISOpub;
-]]>
-
-<![ %ISOtech.module; [
-%ISOtech;
-]]>
-
-<!-- End of DocBook character entity sets module V4.5 ..................... -->
-<!-- ...................................................................... -->
diff --git a/Utilities/xml/docbook-4.5/dbgenent.mod b/Utilities/xml/docbook-4.5/dbgenent.mod
deleted file mode 100644
index ff5ba90d1..000000000
--- a/Utilities/xml/docbook-4.5/dbgenent.mod
+++ /dev/null
@@ -1,41 +0,0 @@
-<!-- ...................................................................... -->
-<!-- DocBook additional general entities V4.5 ............................. -->
-
-<!-- Copyright 1992-2004 HaL Computer Systems, Inc.,
- O'Reilly & Associates, Inc., ArborText, Inc., Fujitsu Software
- Corporation, Norman Walsh, Sun Microsystems, Inc., and the
- Organization for the Advancement of Structured Information
- Standards (OASIS).
-
- In DTD driver files referring to this module, please use an entity
- declaration that uses the public identifier shown below:
-
- <!ENTITY % dbgenent PUBLIC
- "-//OASIS//ENTITIES DocBook Additional General Entities V4.5//EN"
- "dbgenent.mod">
- %dbgenent;
--->
-
-<!-- File dbgenent.mod .................................................... -->
-
-<!-- You can edit this file to add the following:
-
- o General entity declarations of any kind. For example:
-
- <!ENTITY productname "WinWidget"> (small boilerplate)
- <!ENTITY legal-notice SYSTEM "notice.sgm"> (large boilerplate)
-
- o Notation declarations. For example:
-
- <!NOTATION chicken-scratch SYSTEM>
-
- o Declarations for and references to external parameter entities
- containing collections of any of the above. For example:
-
- <!ENTITY % all-titles PUBLIC "-//DocTools//ELEMENTS Book Titles//EN"
- "booktitles.ent">
- %all-titles;
--->
-
-<!-- End of DocBook additional general entities V4.5 ...................... -->
-<!-- ...................................................................... -->
diff --git a/Utilities/xml/docbook-4.5/dbhierx.mod b/Utilities/xml/docbook-4.5/dbhierx.mod
deleted file mode 100644
index 5f839f567..000000000
--- a/Utilities/xml/docbook-4.5/dbhierx.mod
+++ /dev/null
@@ -1,2193 +0,0 @@
-<!-- ...................................................................... -->
-<!-- DocBook document hierarchy module V4.5 ............................... -->
-<!-- File dbhierx.mod ..................................................... -->
-
-<!-- Copyright 1992-2004 HaL Computer Systems, Inc.,
- O'Reilly & Associates, Inc., ArborText, Inc., Fujitsu Software
- Corporation, Norman Walsh, Sun Microsystems, Inc., and the
- Organization for the Advancement of Structured Information
- Standards (OASIS).
-
- $Id: dbhierx.mod 6340 2006-10-03 13:23:24Z nwalsh $
-
- Permission to use, copy, modify and distribute the DocBook DTD
- and its accompanying documentation for any purpose and without fee
- is hereby granted in perpetuity, provided that the above copyright
- notice and this paragraph appear in all copies. The copyright
- holders make no representation about the suitability of the DTD for
- any purpose. It is provided "as is" without expressed or implied
- warranty.
-
- If you modify the DocBook DTD in any way, except for declaring and
- referencing additional sets of general entities and declaring
- additional notations, label your DTD as a variant of DocBook. See
- the maintenance documentation for more information.
-
- Please direct all questions, bug reports, or suggestions for
- changes to the docbook@lists.oasis-open.org mailing list. For more
- information, see http://www.oasis-open.org/docbook/.
--->
-
-<!-- ...................................................................... -->
-
-<!-- This module contains the definitions for the overall document
- hierarchies of DocBook documents. It covers computer documentation
- manuals and manual fragments, as well as reference entries (such as
- man pages) and technical journals or anthologies containing
- articles.
-
- This module depends on the DocBook information pool module. All
- elements and entities referenced but not defined here are assumed
- to be defined in the information pool module.
-
- In DTD driver files referring to this module, please use an entity
- declaration that uses the public identifier shown below:
-
- <!ENTITY % dbhier PUBLIC
- "-//OASIS//ELEMENTS DocBook Document Hierarchy V4.5//EN"
- "dbhierx.mod">
- %dbhier;
-
- See the documentation for detailed information on the parameter
- entity and module scheme used in DocBook, customizing DocBook and
- planning for interchange, and changes made since the last release
- of DocBook.
--->
-
-<!-- ...................................................................... -->
-<!-- Entities for module inclusions ....................................... -->
-
-<!ENTITY % dbhier.redecl.module "IGNORE">
-<!ENTITY % dbhier.redecl2.module "IGNORE">
-
-<!-- ...................................................................... -->
-<!-- Entities for element classes ......................................... -->
-
-<!ENTITY % local.appendix.class "">
-<!ENTITY % appendix.class "appendix %local.appendix.class;">
-
-<!ENTITY % local.article.class "">
-<!ENTITY % article.class "article %local.article.class;">
-
-<!ENTITY % local.book.class "">
-<!ENTITY % book.class "book %local.book.class;">
-
-<!ENTITY % local.chapter.class "">
-<!ENTITY % chapter.class "chapter %local.chapter.class;">
-
-<!ENTITY % local.index.class "">
-<!ENTITY % index.class "index|setindex %local.index.class;">
-
-<!ENTITY % local.refentry.class "">
-<!ENTITY % refentry.class "refentry %local.refentry.class;">
-
-<!ENTITY % local.section.class "">
-<!ENTITY % section.class "section %local.section.class;">
-
-<!ENTITY % local.nav.class "">
-<!ENTITY % nav.class "toc|lot|index|glossary|bibliography
- %local.nav.class;">
-
-<!-- Redeclaration placeholder ............................................ -->
-
-<!-- For redeclaring entities that are declared after this point while
- retaining their references to the entities that are declared before
- this point -->
-
-<![%dbhier.redecl.module;[
-<!-- Defining rdbhier here makes some buggy XML parsers happy. -->
-<!ENTITY % rdbhier "">
-%rdbhier;
-<!--end of dbhier.redecl.module-->]]>
-
-<!-- ...................................................................... -->
-<!-- Entities for element mixtures ........................................ -->
-
-<!ENTITY % local.divcomponent.mix "">
-<!ENTITY % divcomponent.mix
- "%list.class; |%admon.class;
- |%linespecific.class; |%synop.class;
- |%para.class; |%informal.class;
- |%formal.class; |%compound.class;
- |%genobj.class; |%descobj.class;
- |%ndxterm.class; |beginpage
- %forms.hook;
- %local.divcomponent.mix;">
-
-<!ENTITY % local.refcomponent.mix "">
-<!ENTITY % refcomponent.mix
- "%list.class; |%admon.class;
- |%linespecific.class; |%synop.class;
- |%para.class; |%informal.class;
- |%formal.class; |%compound.class;
- |%genobj.class; |%descobj.class;
- |%ndxterm.class; |beginpage
- %forms.hook;
- %local.refcomponent.mix;">
-
-<!ENTITY % local.indexdivcomponent.mix "">
-<!ENTITY % indexdivcomponent.mix
- "itemizedlist|orderedlist|variablelist|simplelist
- |%linespecific.class; |%synop.class;
- |%para.class; |%informal.class;
- |anchor|remark
- |%link.char.class;
- |beginpage
- %local.indexdivcomponent.mix;">
-
-<!ENTITY % local.refname.char.mix "">
-<!ENTITY % refname.char.mix
- "#PCDATA
- |%tech.char.class;
- %local.refname.char.mix;">
-
-<!ENTITY % local.partcontent.mix "">
-<!ENTITY % partcontent.mix
- "%appendix.class;|%chapter.class;|%nav.class;|%article.class;
- |preface|%refentry.class;|reference %local.partcontent.mix;">
-
-<!ENTITY % local.refinline.char.mix "">
-<!ENTITY % refinline.char.mix
- "#PCDATA
- |%xref.char.class; |%gen.char.class;
- |%link.char.class; |%tech.char.class;
- |%base.char.class; |%docinfo.char.class;
- |%other.char.class;
- |%ndxterm.class; |beginpage
- %local.refinline.char.mix;">
-
-<!ENTITY % local.refclass.char.mix "">
-<!ENTITY % refclass.char.mix
- "#PCDATA
- |application
- %local.refclass.char.mix;">
-
-<!-- Redeclaration placeholder 2 .......................................... -->
-
-<!-- For redeclaring entities that are declared after this point while
- retaining their references to the entities that are declared before
- this point -->
-
-<![%dbhier.redecl2.module;[
-<!-- Defining rdbhier2 here makes some buggy XML parsers happy. -->
-<!ENTITY % rdbhier2 "">
-%rdbhier2;
-<!--end of dbhier.redecl2.module-->]]>
-
-<!-- ...................................................................... -->
-<!-- Entities for content models .......................................... -->
-
-<!ENTITY % div.title.content
- "title, subtitle?, titleabbrev?">
-
-<!ENTITY % bookcomponent.title.content
- "title, subtitle?, titleabbrev?">
-
-<!ENTITY % sect.title.content
- "title, subtitle?, titleabbrev?">
-
-<!ENTITY % refsect.title.content
- "title, subtitle?, titleabbrev?">
-
-<!ENTITY % bookcomponent.content
- "((%divcomponent.mix;)+,
- (sect1*|(%refentry.class;)*|simplesect*|(%section.class;)*))
- | (sect1+|(%refentry.class;)+|simplesect+|(%section.class;)+)">
-
-<!-- ...................................................................... -->
-<!-- Set and SetInfo ...................................................... -->
-
-<!ENTITY % set.content.module "INCLUDE">
-<![%set.content.module;[
-<!ENTITY % set.module "INCLUDE">
-<![%set.module;[
-<!ENTITY % local.set.attrib "">
-<!ENTITY % set.role.attrib "%role.attrib;">
-
-<!ENTITY % set.element "INCLUDE">
-<![%set.element;[
-<!--doc:A collection of books.-->
-<!ELEMENT set %ho; ((%div.title.content;)?, setinfo?, toc?, (set|%book.class;)+,
- setindex?)
- %ubiq.inclusion;>
-<!--end of set.element-->]]>
-
-<!-- FPI: SGML formal public identifier -->
-
-
-<!ENTITY % set.attlist "INCLUDE">
-<![%set.attlist;[
-<!ATTLIST set
- fpi CDATA #IMPLIED
- %status.attrib;
- %common.attrib;
- %set.role.attrib;
- %local.set.attrib;
->
-<!--end of set.attlist-->]]>
-<!--end of set.module-->]]>
-
-<!ENTITY % setinfo.module "INCLUDE">
-<![%setinfo.module;[
-<!ENTITY % local.setinfo.attrib "">
-<!ENTITY % setinfo.role.attrib "%role.attrib;">
-
-<!ENTITY % setinfo.element "INCLUDE">
-<![%setinfo.element;[
-<!--doc:Meta-information for a Set.-->
-<!ELEMENT setinfo %ho; ((%info.class;)+)
- %beginpage.exclusion;>
-<!--end of setinfo.element-->]]>
-
-<!-- Contents: IDs of the ToC, Books, and SetIndex that comprise
- the set, in the order of their appearance -->
-
-
-<!ENTITY % setinfo.attlist "INCLUDE">
-<![%setinfo.attlist;[
-<!ATTLIST setinfo
- contents IDREFS #IMPLIED
- %common.attrib;
- %setinfo.role.attrib;
- %local.setinfo.attrib;
->
-<!--end of setinfo.attlist-->]]>
-<!--end of setinfo.module-->]]>
-<!--end of set.content.module-->]]>
-
-<!-- ...................................................................... -->
-<!-- Book and BookInfo .................................................... -->
-
-<!ENTITY % book.content.module "INCLUDE">
-<![%book.content.module;[
-<!ENTITY % book.module "INCLUDE">
-<![%book.module;[
-
-<!ENTITY % local.book.attrib "">
-<!ENTITY % book.role.attrib "%role.attrib;">
-
-<!ENTITY % book.element "INCLUDE">
-<![%book.element;[
-<!--doc:A book.-->
-<!ELEMENT book %ho; ((%div.title.content;)?, bookinfo?,
- (dedication | toc | lot
- | glossary | bibliography | preface
- | %chapter.class; | reference | part
- | %article.class;
- | %appendix.class;
- | %index.class;
- | colophon)*)
- %ubiq.inclusion;>
-<!--end of book.element-->]]>
-
-<!-- FPI: SGML formal public identifier -->
-
-
-<!ENTITY % book.attlist "INCLUDE">
-<![%book.attlist;[
-<!ATTLIST book fpi CDATA #IMPLIED
- %label.attrib;
- %status.attrib;
- %common.attrib;
- %book.role.attrib;
- %local.book.attrib;
->
-<!--end of book.attlist-->]]>
-<!--end of book.module-->]]>
-
-<!ENTITY % bookinfo.module "INCLUDE">
-<![%bookinfo.module;[
-<!ENTITY % local.bookinfo.attrib "">
-<!ENTITY % bookinfo.role.attrib "%role.attrib;">
-
-<!ENTITY % bookinfo.element "INCLUDE">
-<![%bookinfo.element;[
-<!--doc:Meta-information for a Book.-->
-<!ELEMENT bookinfo %ho; ((%info.class;)+)
- %beginpage.exclusion;>
-<!--end of bookinfo.element-->]]>
-
-<!-- Contents: IDs of the ToC, LoTs, Prefaces, Parts, Chapters,
- Appendixes, References, GLossary, Bibliography, and indexes
- comprising the Book, in the order of their appearance -->
-
-
-<!ENTITY % bookinfo.attlist "INCLUDE">
-<![%bookinfo.attlist;[
-<!ATTLIST bookinfo
- contents IDREFS #IMPLIED
- %common.attrib;
- %bookinfo.role.attrib;
- %local.bookinfo.attrib;
->
-<!--end of bookinfo.attlist-->]]>
-<!--end of bookinfo.module-->]]>
-<!--end of book.content.module-->]]>
-
-<!-- ...................................................................... -->
-<!-- Dedication, ToC, and LoT ............................................. -->
-
-<!ENTITY % dedication.module "INCLUDE">
-<![%dedication.module;[
-<!ENTITY % local.dedication.attrib "">
-<!ENTITY % dedication.role.attrib "%role.attrib;">
-
-<!ENTITY % dedication.element "INCLUDE">
-<![%dedication.element;[
-<!--doc:A wrapper for the dedication section of a book.-->
-<!ELEMENT dedication %ho; ((%sect.title.content;)?, (%legalnotice.mix;)+)>
-<!--end of dedication.element-->]]>
-
-<!ENTITY % dedication.attlist "INCLUDE">
-<![%dedication.attlist;[
-<!ATTLIST dedication
- %status.attrib;
- %common.attrib;
- %dedication.role.attrib;
- %local.dedication.attrib;
->
-<!--end of dedication.attlist-->]]>
-<!--end of dedication.module-->]]>
-
-<!ENTITY % colophon.module "INCLUDE">
-<![ %colophon.module; [
-<!ENTITY % local.colophon.attrib "">
-<!ENTITY % colophon.role.attrib "%role.attrib;">
-
-<!ENTITY % colophon.element "INCLUDE">
-<![ %colophon.element; [
-<!--doc:Text at the back of a book describing facts about its production.-->
-<!ELEMENT colophon %ho; ((%sect.title.content;)?, (%textobject.mix;)+)>
-<!--end of colophon.element-->]]>
-
-<!ENTITY % colophon.attlist "INCLUDE">
-<![ %colophon.attlist; [
-<!ATTLIST colophon
- %status.attrib;
- %common.attrib;
- %colophon.role.attrib;
- %local.colophon.attrib;>
-<!--end of colophon.attlist-->]]>
-<!--end of colophon.module-->]]>
-
-<!ENTITY % toc.content.module "INCLUDE">
-<![%toc.content.module;[
-<!ENTITY % toc.module "INCLUDE">
-<![%toc.module;[
-<!ENTITY % local.toc.attrib "">
-<!ENTITY % toc.role.attrib "%role.attrib;">
-
-<!ENTITY % toc.element "INCLUDE">
-<![%toc.element;[
-<!--doc:A table of contents.-->
-<!ELEMENT toc %ho; (beginpage?,
- (%bookcomponent.title.content;)?,
- tocfront*,
- (tocpart | tocchap)*, tocback*)>
-<!--end of toc.element-->]]>
-
-<!ENTITY % toc.attlist "INCLUDE">
-<![%toc.attlist;[
-<!ATTLIST toc
- %pagenum.attrib;
- %common.attrib;
- %toc.role.attrib;
- %local.toc.attrib;
->
-<!--end of toc.attlist-->]]>
-<!--end of toc.module-->]]>
-
-<!ENTITY % tocfront.module "INCLUDE">
-<![%tocfront.module;[
-<!ENTITY % local.tocfront.attrib "">
-<!ENTITY % tocfront.role.attrib "%role.attrib;">
-
-<!ENTITY % tocfront.element "INCLUDE">
-<![%tocfront.element;[
-<!--doc:An entry in a table of contents for a front matter component.-->
-<!ELEMENT tocfront %ho; (%para.char.mix;)*>
-<!--end of tocfront.element-->]]>
-
-<!-- to element that this entry represents -->
-
-
-<!ENTITY % tocfront.attlist "INCLUDE">
-<![%tocfront.attlist;[
-<!ATTLIST tocfront
- %label.attrib;
- %linkend.attrib; %pagenum.attrib;
- %common.attrib;
- %tocfront.role.attrib;
- %local.tocfront.attrib;
->
-<!--end of tocfront.attlist-->]]>
-<!--end of tocfront.module-->]]>
-
-<!ENTITY % tocentry.module "INCLUDE">
-<![%tocentry.module;[
-<!ENTITY % local.tocentry.attrib "">
-<!ENTITY % tocentry.role.attrib "%role.attrib;">
-
-<!ENTITY % tocentry.element "INCLUDE">
-<![%tocentry.element;[
-<!--doc:A component title in a table of contents.-->
-<!ELEMENT tocentry %ho; (%para.char.mix;)*>
-<!--end of tocentry.element-->]]>
-
-<!-- to element that this entry represents -->
-
-
-<!ENTITY % tocentry.attlist "INCLUDE">
-<![%tocentry.attlist;[
-<!ATTLIST tocentry
- %linkend.attrib; %pagenum.attrib;
- %common.attrib;
- %tocentry.role.attrib;
- %local.tocentry.attrib;
->
-<!--end of tocentry.attlist-->]]>
-<!--end of tocentry.module-->]]>
-
-<!ENTITY % tocpart.module "INCLUDE">
-<![%tocpart.module;[
-<!ENTITY % local.tocpart.attrib "">
-<!ENTITY % tocpart.role.attrib "%role.attrib;">
-
-<!ENTITY % tocpart.element "INCLUDE">
-<![%tocpart.element;[
-<!--doc:An entry in a table of contents for a part of a book.-->
-<!ELEMENT tocpart %ho; (tocentry+, tocchap*)>
-<!--end of tocpart.element-->]]>
-
-<!ENTITY % tocpart.attlist "INCLUDE">
-<![%tocpart.attlist;[
-<!ATTLIST tocpart
- %common.attrib;
- %tocpart.role.attrib;
- %local.tocpart.attrib;
->
-<!--end of tocpart.attlist-->]]>
-<!--end of tocpart.module-->]]>
-
-<!ENTITY % tocchap.module "INCLUDE">
-<![%tocchap.module;[
-<!ENTITY % local.tocchap.attrib "">
-<!ENTITY % tocchap.role.attrib "%role.attrib;">
-
-<!ENTITY % tocchap.element "INCLUDE">
-<![%tocchap.element;[
-<!--doc:An entry in a table of contents for a component in the body of a document.-->
-<!ELEMENT tocchap %ho; (tocentry+, toclevel1*)>
-<!--end of tocchap.element-->]]>
-
-<!ENTITY % tocchap.attlist "INCLUDE">
-<![%tocchap.attlist;[
-<!ATTLIST tocchap
- %label.attrib;
- %common.attrib;
- %tocchap.role.attrib;
- %local.tocchap.attrib;
->
-<!--end of tocchap.attlist-->]]>
-<!--end of tocchap.module-->]]>
-
-<!ENTITY % toclevel1.module "INCLUDE">
-<![%toclevel1.module;[
-<!ENTITY % local.toclevel1.attrib "">
-<!ENTITY % toclevel1.role.attrib "%role.attrib;">
-
-<!ENTITY % toclevel1.element "INCLUDE">
-<![%toclevel1.element;[
-<!--doc:A top-level entry within a table of contents entry for a chapter-like component.-->
-<!ELEMENT toclevel1 %ho; (tocentry+, toclevel2*)>
-<!--end of toclevel1.element-->]]>
-
-<!ENTITY % toclevel1.attlist "INCLUDE">
-<![%toclevel1.attlist;[
-<!ATTLIST toclevel1
- %common.attrib;
- %toclevel1.role.attrib;
- %local.toclevel1.attrib;
->
-<!--end of toclevel1.attlist-->]]>
-<!--end of toclevel1.module-->]]>
-
-<!ENTITY % toclevel2.module "INCLUDE">
-<![%toclevel2.module;[
-<!ENTITY % local.toclevel2.attrib "">
-<!ENTITY % toclevel2.role.attrib "%role.attrib;">
-
-<!ENTITY % toclevel2.element "INCLUDE">
-<![%toclevel2.element;[
-<!--doc:A second-level entry within a table of contents entry for a chapter-like component.-->
-<!ELEMENT toclevel2 %ho; (tocentry+, toclevel3*)>
-<!--end of toclevel2.element-->]]>
-
-<!ENTITY % toclevel2.attlist "INCLUDE">
-<![%toclevel2.attlist;[
-<!ATTLIST toclevel2
- %common.attrib;
- %toclevel2.role.attrib;
- %local.toclevel2.attrib;
->
-<!--end of toclevel2.attlist-->]]>
-<!--end of toclevel2.module-->]]>
-
-<!ENTITY % toclevel3.module "INCLUDE">
-<![%toclevel3.module;[
-<!ENTITY % local.toclevel3.attrib "">
-<!ENTITY % toclevel3.role.attrib "%role.attrib;">
-
-<!ENTITY % toclevel3.element "INCLUDE">
-<![%toclevel3.element;[
-<!--doc:A third-level entry within a table of contents entry for a chapter-like component.-->
-<!ELEMENT toclevel3 %ho; (tocentry+, toclevel4*)>
-<!--end of toclevel3.element-->]]>
-
-<!ENTITY % toclevel3.attlist "INCLUDE">
-<![%toclevel3.attlist;[
-<!ATTLIST toclevel3
- %common.attrib;
- %toclevel3.role.attrib;
- %local.toclevel3.attrib;
->
-<!--end of toclevel3.attlist-->]]>
-<!--end of toclevel3.module-->]]>
-
-<!ENTITY % toclevel4.module "INCLUDE">
-<![%toclevel4.module;[
-<!ENTITY % local.toclevel4.attrib "">
-<!ENTITY % toclevel4.role.attrib "%role.attrib;">
-
-<!ENTITY % toclevel4.element "INCLUDE">
-<![%toclevel4.element;[
-<!--doc:A fourth-level entry within a table of contents entry for a chapter-like component.-->
-<!ELEMENT toclevel4 %ho; (tocentry+, toclevel5*)>
-<!--end of toclevel4.element-->]]>
-
-<!ENTITY % toclevel4.attlist "INCLUDE">
-<![%toclevel4.attlist;[
-<!ATTLIST toclevel4
- %common.attrib;
- %toclevel4.role.attrib;
- %local.toclevel4.attrib;
->
-<!--end of toclevel4.attlist-->]]>
-<!--end of toclevel4.module-->]]>
-
-<!ENTITY % toclevel5.module "INCLUDE">
-<![%toclevel5.module;[
-<!ENTITY % local.toclevel5.attrib "">
-<!ENTITY % toclevel5.role.attrib "%role.attrib;">
-
-<!ENTITY % toclevel5.element "INCLUDE">
-<![%toclevel5.element;[
-<!--doc:A fifth-level entry within a table of contents entry for a chapter-like component.-->
-<!ELEMENT toclevel5 %ho; (tocentry+)>
-<!--end of toclevel5.element-->]]>
-
-<!ENTITY % toclevel5.attlist "INCLUDE">
-<![%toclevel5.attlist;[
-<!ATTLIST toclevel5
- %common.attrib;
- %toclevel5.role.attrib;
- %local.toclevel5.attrib;
->
-<!--end of toclevel5.attlist-->]]>
-<!--end of toclevel5.module-->]]>
-
-<!ENTITY % tocback.module "INCLUDE">
-<![%tocback.module;[
-<!ENTITY % local.tocback.attrib "">
-<!ENTITY % tocback.role.attrib "%role.attrib;">
-
-<!ENTITY % tocback.element "INCLUDE">
-<![%tocback.element;[
-<!--doc:An entry in a table of contents for a back matter component.-->
-<!ELEMENT tocback %ho; (%para.char.mix;)*>
-<!--end of tocback.element-->]]>
-
-<!-- to element that this entry represents -->
-
-
-<!ENTITY % tocback.attlist "INCLUDE">
-<![%tocback.attlist;[
-<!ATTLIST tocback
- %label.attrib;
- %linkend.attrib; %pagenum.attrib;
- %common.attrib;
- %tocback.role.attrib;
- %local.tocback.attrib;
->
-<!--end of tocback.attlist-->]]>
-<!--end of tocback.module-->]]>
-<!--end of toc.content.module-->]]>
-
-<!ENTITY % lot.content.module "INCLUDE">
-<![%lot.content.module;[
-<!ENTITY % lot.module "INCLUDE">
-<![%lot.module;[
-<!ENTITY % local.lot.attrib "">
-<!ENTITY % lot.role.attrib "%role.attrib;">
-
-<!ENTITY % lot.element "INCLUDE">
-<![%lot.element;[
-<!--doc:A list of the titles of formal objects (as tables or figures) in a document.-->
-<!ELEMENT lot %ho; (beginpage?, (%bookcomponent.title.content;)?, lotentry*)>
-<!--end of lot.element-->]]>
-
-<!ENTITY % lot.attlist "INCLUDE">
-<![%lot.attlist;[
-<!ATTLIST lot
- %label.attrib;
- %common.attrib;
- %lot.role.attrib;
- %local.lot.attrib;
->
-<!--end of lot.attlist-->]]>
-<!--end of lot.module-->]]>
-
-<!ENTITY % lotentry.module "INCLUDE">
-<![%lotentry.module;[
-<!ENTITY % local.lotentry.attrib "">
-<!ENTITY % lotentry.role.attrib "%role.attrib;">
-
-<!ENTITY % lotentry.element "INCLUDE">
-<![%lotentry.element;[
-<!--doc:An entry in a list of titles.-->
-<!ELEMENT lotentry %ho; (%para.char.mix;)*>
-<!--end of lotentry.element-->]]>
-
-<!-- SrcCredit: Information about the source of the entry,
- as for a list of illustrations -->
-<!-- linkend: to element that this entry represents-->
-<!ENTITY % lotentry.attlist "INCLUDE">
-<![%lotentry.attlist;[
-<!ATTLIST lotentry
- %linkend.attrib;
- %pagenum.attrib;
- srccredit CDATA #IMPLIED
- %common.attrib;
- %lotentry.role.attrib;
- %local.lotentry.attrib;
->
-<!--end of lotentry.attlist-->]]>
-<!--end of lotentry.module-->]]>
-<!--end of lot.content.module-->]]>
-
-<!-- ...................................................................... -->
-<!-- Appendix, Chapter, Part, Preface, Reference, PartIntro ............... -->
-
-<!ENTITY % appendix.module "INCLUDE">
-<![%appendix.module;[
-<!ENTITY % local.appendix.attrib "">
-<!ENTITY % appendix.role.attrib "%role.attrib;">
-
-<!ENTITY % appendix.element "INCLUDE">
-<![%appendix.element;[
-<!--doc:An appendix in a Book or Article.-->
-<!ELEMENT appendix %ho; (beginpage?,
- appendixinfo?,
- (%bookcomponent.title.content;),
- (%nav.class;)*,
- tocchap?,
- (%bookcomponent.content;),
- (%nav.class;)*)
- %ubiq.inclusion;>
-<!--end of appendix.element-->]]>
-
-<!ENTITY % appendix.attlist "INCLUDE">
-<![%appendix.attlist;[
-<!ATTLIST appendix
- %label.attrib;
- %status.attrib;
- %common.attrib;
- %appendix.role.attrib;
- %local.appendix.attrib;
->
-<!--end of appendix.attlist-->]]>
-<!--end of appendix.module-->]]>
-
-<!ENTITY % chapter.module "INCLUDE">
-<![%chapter.module;[
-<!ENTITY % local.chapter.attrib "">
-<!ENTITY % chapter.role.attrib "%role.attrib;">
-
-<!ENTITY % chapter.element "INCLUDE">
-<![%chapter.element;[
-<!--doc:A chapter, as of a book.-->
-<!ELEMENT chapter %ho; (beginpage?,
- chapterinfo?,
- (%bookcomponent.title.content;),
- (%nav.class;)*,
- tocchap?,
- (%bookcomponent.content;),
- (%nav.class;)*)
- %ubiq.inclusion;>
-<!--end of chapter.element-->]]>
-
-<!ENTITY % chapter.attlist "INCLUDE">
-<![%chapter.attlist;[
-<!ATTLIST chapter
- %label.attrib;
- %status.attrib;
- %common.attrib;
- %chapter.role.attrib;
- %local.chapter.attrib;
->
-<!--end of chapter.attlist-->]]>
-<!--end of chapter.module-->]]>
-
-<!ENTITY % part.module "INCLUDE">
-<![%part.module;[
-
-<!-- Note that Part was to have its content model reduced in V4.5. This
-change will not be made after all. -->
-
-<!ENTITY % local.part.attrib "">
-<!ENTITY % part.role.attrib "%role.attrib;">
-
-<!ENTITY % part.element "INCLUDE">
-<![%part.element;[
-<!--doc:A division in a book.-->
-<!ELEMENT part %ho; (beginpage?,
- partinfo?, (%bookcomponent.title.content;), partintro?,
- (%partcontent.mix;)+)
- %ubiq.inclusion;>
-<!--end of part.element-->]]>
-
-<!ENTITY % part.attlist "INCLUDE">
-<![%part.attlist;[
-<!ATTLIST part
- %label.attrib;
- %status.attrib;
- %common.attrib;
- %part.role.attrib;
- %local.part.attrib;
->
-<!--end of part.attlist-->]]>
-<!--ELEMENT PartIntro (defined below)-->
-<!--end of part.module-->]]>
-
-<!ENTITY % preface.module "INCLUDE">
-<![%preface.module;[
-<!ENTITY % local.preface.attrib "">
-<!ENTITY % preface.role.attrib "%role.attrib;">
-
-<!ENTITY % preface.element "INCLUDE">
-<![%preface.element;[
-<!--doc:Introductory matter preceding the first chapter of a book.-->
-<!ELEMENT preface %ho; (beginpage?,
- prefaceinfo?,
- (%bookcomponent.title.content;),
- (%nav.class;)*,
- tocchap?,
- (%bookcomponent.content;),
- (%nav.class;)*)
- %ubiq.inclusion;>
-<!--end of preface.element-->]]>
-
-<!ENTITY % preface.attlist "INCLUDE">
-<![%preface.attlist;[
-<!ATTLIST preface
- %status.attrib;
- %common.attrib;
- %preface.role.attrib;
- %local.preface.attrib;
->
-<!--end of preface.attlist-->]]>
-<!--end of preface.module-->]]>
-
-<!ENTITY % reference.module "INCLUDE">
-<![%reference.module;[
-<!ENTITY % local.reference.attrib "">
-<!ENTITY % reference.role.attrib "%role.attrib;">
-
-<!ENTITY % reference.element "INCLUDE">
-<![%reference.element;[
-<!--doc:A collection of reference entries.-->
-<!ELEMENT reference %ho; (beginpage?,
- referenceinfo?,
- (%bookcomponent.title.content;), partintro?,
- (%refentry.class;)+)
- %ubiq.inclusion;>
-<!--end of reference.element-->]]>
-
-<!ENTITY % reference.attlist "INCLUDE">
-<![%reference.attlist;[
-<!ATTLIST reference
- %label.attrib;
- %status.attrib;
- %common.attrib;
- %reference.role.attrib;
- %local.reference.attrib;
->
-<!--end of reference.attlist-->]]>
-<!--ELEMENT PartIntro (defined below)-->
-<!--end of reference.module-->]]>
-
-<!ENTITY % partintro.module "INCLUDE">
-<![%partintro.module;[
-<!ENTITY % local.partintro.attrib "">
-<!ENTITY % partintro.role.attrib "%role.attrib;">
-
-<!ENTITY % partintro.element "INCLUDE">
-<![%partintro.element;[
-<!--doc:An introduction to the contents of a part.-->
-<!ELEMENT partintro %ho; ((%div.title.content;)?, (%bookcomponent.content;))
- %ubiq.inclusion;>
-<!--end of partintro.element-->]]>
-
-<!ENTITY % partintro.attlist "INCLUDE">
-<![%partintro.attlist;[
-<!ATTLIST partintro
- %label.attrib;
- %common.attrib;
- %partintro.role.attrib;
- %local.partintro.attrib;
->
-<!--end of partintro.attlist-->]]>
-<!--end of partintro.module-->]]>
-
-<!-- ...................................................................... -->
-<!-- Other Info elements .................................................. -->
-
-<!ENTITY % appendixinfo.module "INCLUDE">
-<![ %appendixinfo.module; [
-<!ENTITY % local.appendixinfo.attrib "">
-<!ENTITY % appendixinfo.role.attrib "%role.attrib;">
-
-<!ENTITY % appendixinfo.element "INCLUDE">
-<![ %appendixinfo.element; [
-<!--doc:Meta-information for an Appendix.-->
-<!ELEMENT appendixinfo %ho; ((%info.class;)+)
- %beginpage.exclusion;>
-<!--end of appendixinfo.element-->]]>
-
-<!ENTITY % appendixinfo.attlist "INCLUDE">
-<![ %appendixinfo.attlist; [
-<!ATTLIST appendixinfo
- %common.attrib;
- %appendixinfo.role.attrib;
- %local.appendixinfo.attrib;
->
-<!--end of appendixinfo.attlist-->]]>
-<!--end of appendixinfo.module-->]]>
-
-<!ENTITY % bibliographyinfo.module "INCLUDE">
-<![ %bibliographyinfo.module; [
-<!ENTITY % local.bibliographyinfo.attrib "">
-<!ENTITY % bibliographyinfo.role.attrib "%role.attrib;">
-
-<!ENTITY % bibliographyinfo.element "INCLUDE">
-<![ %bibliographyinfo.element; [
-<!--doc:Meta-information for a Bibliography.-->
-<!ELEMENT bibliographyinfo %ho; ((%info.class;)+)
- %beginpage.exclusion;>
-<!--end of bibliographyinfo.element-->]]>
-
-<!ENTITY % bibliographyinfo.attlist "INCLUDE">
-<![ %bibliographyinfo.attlist; [
-<!ATTLIST bibliographyinfo
- %common.attrib;
- %bibliographyinfo.role.attrib;
- %local.bibliographyinfo.attrib;
->
-<!--end of bibliographyinfo.attlist-->]]>
-<!--end of bibliographyinfo.module-->]]>
-
-<!ENTITY % chapterinfo.module "INCLUDE">
-<![ %chapterinfo.module; [
-<!ENTITY % local.chapterinfo.attrib "">
-<!ENTITY % chapterinfo.role.attrib "%role.attrib;">
-
-<!ENTITY % chapterinfo.element "INCLUDE">
-<![ %chapterinfo.element; [
-<!--doc:Meta-information for a Chapter.-->
-<!ELEMENT chapterinfo %ho; ((%info.class;)+)
- %beginpage.exclusion;>
-<!--end of chapterinfo.element-->]]>
-
-<!ENTITY % chapterinfo.attlist "INCLUDE">
-<![ %chapterinfo.attlist; [
-<!ATTLIST chapterinfo
- %common.attrib;
- %chapterinfo.role.attrib;
- %local.chapterinfo.attrib;
->
-<!--end of chapterinfo.attlist-->]]>
-<!--end of chapterinfo.module-->]]>
-
-<!ENTITY % glossaryinfo.module "INCLUDE">
-<![ %glossaryinfo.module; [
-<!ENTITY % local.glossaryinfo.attrib "">
-<!ENTITY % glossaryinfo.role.attrib "%role.attrib;">
-
-<!ENTITY % glossaryinfo.element "INCLUDE">
-<![ %glossaryinfo.element; [
-<!--doc:Meta-information for a Glossary.-->
-<!ELEMENT glossaryinfo %ho; ((%info.class;)+)
- %beginpage.exclusion;>
-<!--end of glossaryinfo.element-->]]>
-
-<!ENTITY % glossaryinfo.attlist "INCLUDE">
-<![ %glossaryinfo.attlist; [
-<!ATTLIST glossaryinfo
- %common.attrib;
- %glossaryinfo.role.attrib;
- %local.glossaryinfo.attrib;
->
-<!--end of glossaryinfo.attlist-->]]>
-<!--end of glossaryinfo.module-->]]>
-
-<!ENTITY % indexinfo.module "INCLUDE">
-<![ %indexinfo.module; [
-<!ENTITY % local.indexinfo.attrib "">
-<!ENTITY % indexinfo.role.attrib "%role.attrib;">
-
-<!ENTITY % indexinfo.element "INCLUDE">
-<![ %indexinfo.element; [
-<!--doc:Meta-information for an Index.-->
-<!ELEMENT indexinfo %ho; ((%info.class;)+)>
-<!--end of indexinfo.element-->]]>
-
-<!ENTITY % indexinfo.attlist "INCLUDE">
-<![ %indexinfo.attlist; [
-<!ATTLIST indexinfo
- %common.attrib;
- %indexinfo.role.attrib;
- %local.indexinfo.attrib;
->
-<!--end of indexinfo.attlist-->]]>
-<!--end of indexinfo.module-->]]>
-
-<!ENTITY % setindexinfo.module "INCLUDE">
-<![ %setindexinfo.module; [
-<!ENTITY % local.setindexinfo.attrib "">
-<!ENTITY % setindexinfo.role.attrib "%role.attrib;">
-
-<!ENTITY % setindexinfo.element "INCLUDE">
-<![ %setindexinfo.element; [
-<!--doc:Meta-information for a SetIndex.-->
-<!ELEMENT setindexinfo %ho; ((%info.class;)+)
- %beginpage.exclusion;>
-<!--end of setindexinfo.element-->]]>
-
-<!ENTITY % setindexinfo.attlist "INCLUDE">
-<![ %setindexinfo.attlist; [
-<!ATTLIST setindexinfo
- %common.attrib;
- %setindexinfo.role.attrib;
- %local.setindexinfo.attrib;
->
-<!--end of setindexinfo.attlist-->]]>
-<!--end of setindexinfo.module-->]]>
-
-<!ENTITY % partinfo.module "INCLUDE">
-<![ %partinfo.module; [
-<!ENTITY % local.partinfo.attrib "">
-<!ENTITY % partinfo.role.attrib "%role.attrib;">
-
-<!ENTITY % partinfo.element "INCLUDE">
-<![ %partinfo.element; [
-<!--doc:Meta-information for a Part.-->
-<!ELEMENT partinfo %ho; ((%info.class;)+)
- %beginpage.exclusion;>
-<!--end of partinfo.element-->]]>
-
-<!ENTITY % partinfo.attlist "INCLUDE">
-<![ %partinfo.attlist; [
-<!ATTLIST partinfo
- %common.attrib;
- %partinfo.role.attrib;
- %local.partinfo.attrib;
->
-<!--end of partinfo.attlist-->]]>
-<!--end of partinfo.module-->]]>
-
-<!ENTITY % prefaceinfo.module "INCLUDE">
-<![ %prefaceinfo.module; [
-<!ENTITY % local.prefaceinfo.attrib "">
-<!ENTITY % prefaceinfo.role.attrib "%role.attrib;">
-
-<!ENTITY % prefaceinfo.element "INCLUDE">
-<![ %prefaceinfo.element; [
-<!--doc:Meta-information for a Preface.-->
-<!ELEMENT prefaceinfo %ho; ((%info.class;)+)
- %beginpage.exclusion;>
-<!--end of prefaceinfo.element-->]]>
-
-<!ENTITY % prefaceinfo.attlist "INCLUDE">
-<![ %prefaceinfo.attlist; [
-<!ATTLIST prefaceinfo
- %common.attrib;
- %prefaceinfo.role.attrib;
- %local.prefaceinfo.attrib;
->
-<!--end of prefaceinfo.attlist-->]]>
-<!--end of prefaceinfo.module-->]]>
-
-<!ENTITY % refentryinfo.module "INCLUDE">
-<![ %refentryinfo.module; [
-<!ENTITY % local.refentryinfo.attrib "">
-<!ENTITY % refentryinfo.role.attrib "%role.attrib;">
-
-<!ENTITY % refentryinfo.element "INCLUDE">
-<![ %refentryinfo.element; [
-<!--doc:Meta-information for a Refentry.-->
-<!ELEMENT refentryinfo %ho; ((%info.class;)+)
- %beginpage.exclusion;>
-<!--end of refentryinfo.element-->]]>
-
-<!ENTITY % refentryinfo.attlist "INCLUDE">
-<![ %refentryinfo.attlist; [
-<!ATTLIST refentryinfo
- %common.attrib;
- %refentryinfo.role.attrib;
- %local.refentryinfo.attrib;
->
-<!--end of refentryinfo.attlist-->]]>
-<!--end of refentryinfo.module-->]]>
-
-<!ENTITY % refsectioninfo.module "INCLUDE">
-<![ %refsectioninfo.module; [
-<!ENTITY % local.refsectioninfo.attrib "">
-<!ENTITY % refsectioninfo.role.attrib "%role.attrib;">
-
-<!ENTITY % refsectioninfo.element "INCLUDE">
-<![ %refsectioninfo.element; [
-<!--doc:Meta-information for a refsection.-->
-<!ELEMENT refsectioninfo %ho; ((%info.class;)+)
- %beginpage.exclusion;>
-<!--end of refsectioninfo.element-->]]>
-
-<!ENTITY % refsectioninfo.attlist "INCLUDE">
-<![ %refsectioninfo.attlist; [
-<!ATTLIST refsectioninfo
- %common.attrib;
- %refsectioninfo.role.attrib;
- %local.refsectioninfo.attrib;
->
-<!--end of refsectioninfo.attlist-->]]>
-<!--end of refsectioninfo.module-->]]>
-
-<!ENTITY % refsect1info.module "INCLUDE">
-<![ %refsect1info.module; [
-<!ENTITY % local.refsect1info.attrib "">
-<!ENTITY % refsect1info.role.attrib "%role.attrib;">
-
-<!ENTITY % refsect1info.element "INCLUDE">
-<![ %refsect1info.element; [
-<!--doc:Meta-information for a RefSect1.-->
-<!ELEMENT refsect1info %ho; ((%info.class;)+)
- %beginpage.exclusion;>
-<!--end of refsect1info.element-->]]>
-
-<!ENTITY % refsect1info.attlist "INCLUDE">
-<![ %refsect1info.attlist; [
-<!ATTLIST refsect1info
- %common.attrib;
- %refsect1info.role.attrib;
- %local.refsect1info.attrib;
->
-<!--end of refsect1info.attlist-->]]>
-<!--end of refsect1info.module-->]]>
-
-<!ENTITY % refsect2info.module "INCLUDE">
-<![ %refsect2info.module; [
-<!ENTITY % local.refsect2info.attrib "">
-<!ENTITY % refsect2info.role.attrib "%role.attrib;">
-
-<!ENTITY % refsect2info.element "INCLUDE">
-<![ %refsect2info.element; [
-<!--doc:Meta-information for a RefSect2.-->
-<!ELEMENT refsect2info %ho; ((%info.class;)+)
- %beginpage.exclusion;>
-<!--end of refsect2info.element-->]]>
-
-<!ENTITY % refsect2info.attlist "INCLUDE">
-<![ %refsect2info.attlist; [
-<!ATTLIST refsect2info
- %common.attrib;
- %refsect2info.role.attrib;
- %local.refsect2info.attrib;
->
-<!--end of refsect2info.attlist-->]]>
-<!--end of refsect2info.module-->]]>
-
-<!ENTITY % refsect3info.module "INCLUDE">
-<![ %refsect3info.module; [
-<!ENTITY % local.refsect3info.attrib "">
-<!ENTITY % refsect3info.role.attrib "%role.attrib;">
-
-<!ENTITY % refsect3info.element "INCLUDE">
-<![ %refsect3info.element; [
-<!--doc:Meta-information for a RefSect3.-->
-<!ELEMENT refsect3info %ho; ((%info.class;)+)
- %beginpage.exclusion;>
-<!--end of refsect3info.element-->]]>
-
-<!ENTITY % refsect3info.attlist "INCLUDE">
-<![ %refsect3info.attlist; [
-<!ATTLIST refsect3info
- %common.attrib;
- %refsect3info.role.attrib;
- %local.refsect3info.attrib;
->
-<!--end of refsect3info.attlist-->]]>
-<!--end of refsect3info.module-->]]>
-
-<!ENTITY % refsynopsisdivinfo.module "INCLUDE">
-<![ %refsynopsisdivinfo.module; [
-<!ENTITY % local.refsynopsisdivinfo.attrib "">
-<!ENTITY % refsynopsisdivinfo.role.attrib "%role.attrib;">
-
-<!ENTITY % refsynopsisdivinfo.element "INCLUDE">
-<![ %refsynopsisdivinfo.element; [
-<!--doc:Meta-information for a RefSynopsisDiv.-->
-<!ELEMENT refsynopsisdivinfo %ho; ((%info.class;)+)
- %beginpage.exclusion;>
-<!--end of refsynopsisdivinfo.element-->]]>
-
-<!ENTITY % refsynopsisdivinfo.attlist "INCLUDE">
-<![ %refsynopsisdivinfo.attlist; [
-<!ATTLIST refsynopsisdivinfo
- %common.attrib;
- %refsynopsisdivinfo.role.attrib;
- %local.refsynopsisdivinfo.attrib;
->
-<!--end of refsynopsisdivinfo.attlist-->]]>
-<!--end of refsynopsisdivinfo.module-->]]>
-
-<!ENTITY % referenceinfo.module "INCLUDE">
-<![ %referenceinfo.module; [
-<!ENTITY % local.referenceinfo.attrib "">
-<!ENTITY % referenceinfo.role.attrib "%role.attrib;">
-
-<!ENTITY % referenceinfo.element "INCLUDE">
-<![ %referenceinfo.element; [
-<!--doc:Meta-information for a Reference.-->
-<!ELEMENT referenceinfo %ho; ((%info.class;)+)
- %beginpage.exclusion;>
-<!--end of referenceinfo.element-->]]>
-
-<!ENTITY % referenceinfo.attlist "INCLUDE">
-<![ %referenceinfo.attlist; [
-<!ATTLIST referenceinfo
- %common.attrib;
- %referenceinfo.role.attrib;
- %local.referenceinfo.attrib;
->
-<!--end of referenceinfo.attlist-->]]>
-<!--end of referenceinfo.module-->]]>
-
-<!ENTITY % local.sect1info.attrib "">
-<!ENTITY % sect1info.role.attrib "%role.attrib;">
-
-<!ENTITY % sect1info.element "INCLUDE">
-<![%sect1info.element;[
-<!--doc:Meta-information for a Sect1.-->
-<!ELEMENT sect1info %ho; ((%info.class;)+)
- %beginpage.exclusion;>
-<!--end of sect1info.element-->]]>
-
-<!ENTITY % sect1info.attlist "INCLUDE">
-<![%sect1info.attlist;[
-<!ATTLIST sect1info
- %common.attrib;
- %sect1info.role.attrib;
- %local.sect1info.attrib;
->
-<!--end of sect1info.attlist-->]]>
-
-<!ENTITY % local.sect2info.attrib "">
-<!ENTITY % sect2info.role.attrib "%role.attrib;">
-
-<!ENTITY % sect2info.element "INCLUDE">
-<![%sect2info.element;[
-<!--doc:Meta-information for a Sect2.-->
-<!ELEMENT sect2info %ho; ((%info.class;)+)
- %beginpage.exclusion;>
-<!--end of sect2info.element-->]]>
-
-<!ENTITY % sect2info.attlist "INCLUDE">
-<![%sect2info.attlist;[
-<!ATTLIST sect2info
- %common.attrib;
- %sect2info.role.attrib;
- %local.sect2info.attrib;
->
-<!--end of sect2info.attlist-->]]>
-
-<!ENTITY % local.sect3info.attrib "">
-<!ENTITY % sect3info.role.attrib "%role.attrib;">
-
-<!ENTITY % sect3info.element "INCLUDE">
-<![%sect3info.element;[
-<!--doc:Meta-information for a Sect3.-->
-<!ELEMENT sect3info %ho; ((%info.class;)+)
- %beginpage.exclusion;>
-<!--end of sect3info.element-->]]>
-
-<!ENTITY % sect3info.attlist "INCLUDE">
-<![%sect3info.attlist;[
-<!ATTLIST sect3info
- %common.attrib;
- %sect3info.role.attrib;
- %local.sect3info.attrib;
->
-<!--end of sect3info.attlist-->]]>
-
-<!ENTITY % local.sect4info.attrib "">
-<!ENTITY % sect4info.role.attrib "%role.attrib;">
-
-<!ENTITY % sect4info.element "INCLUDE">
-<![%sect4info.element;[
-<!--doc:Meta-information for a Sect4.-->
-<!ELEMENT sect4info %ho; ((%info.class;)+)
- %beginpage.exclusion;>
-<!--end of sect4info.element-->]]>
-
-<!ENTITY % sect4info.attlist "INCLUDE">
-<![%sect4info.attlist;[
-<!ATTLIST sect4info
- %common.attrib;
- %sect4info.role.attrib;
- %local.sect4info.attrib;
->
-<!--end of sect4info.attlist-->]]>
-
-<!ENTITY % local.sect5info.attrib "">
-<!ENTITY % sect5info.role.attrib "%role.attrib;">
-
-<!ENTITY % sect5info.element "INCLUDE">
-<![%sect5info.element;[
-<!--doc:Meta-information for a Sect5.-->
-<!ELEMENT sect5info %ho; ((%info.class;)+)
- %beginpage.exclusion;>
-<!--end of sect5info.element-->]]>
-
-<!ENTITY % sect5info.attlist "INCLUDE">
-<![%sect5info.attlist;[
-<!ATTLIST sect5info
- %common.attrib;
- %sect5info.role.attrib;
- %local.sect5info.attrib;
->
-<!--end of sect5info.attlist-->]]>
-
-<!-- ...................................................................... -->
-<!-- Section (parallel to Sect*) ......................................... -->
-
-<!ENTITY % section.content.module "INCLUDE">
-<![ %section.content.module; [
-<!ENTITY % section.module "INCLUDE">
-<![ %section.module; [
-<!ENTITY % local.section.attrib "">
-<!ENTITY % section.role.attrib "%role.attrib;">
-
-<!ENTITY % section.element "INCLUDE">
-<![ %section.element; [
-<!--doc:A recursive section.-->
-<!ELEMENT section %ho; (sectioninfo?,
- (%sect.title.content;),
- (%nav.class;)*,
- (((%divcomponent.mix;)+,
- ((%refentry.class;)*|(%section.class;)*|simplesect*))
- | (%refentry.class;)+|(%section.class;)+|simplesect+),
- (%nav.class;)*)
- %ubiq.inclusion;>
-<!--end of section.element-->]]>
-
-<!ENTITY % section.attlist "INCLUDE">
-<![ %section.attlist; [
-<!ATTLIST section
- %label.attrib;
- %status.attrib;
- %common.attrib;
- %section.role.attrib;
- %local.section.attrib;
->
-<!--end of section.attlist-->]]>
-<!--end of section.module-->]]>
-
-<!ENTITY % sectioninfo.module "INCLUDE">
-<![ %sectioninfo.module; [
-<!ENTITY % sectioninfo.role.attrib "%role.attrib;">
-<!ENTITY % local.sectioninfo.attrib "">
-
-<!ENTITY % sectioninfo.element "INCLUDE">
-<![ %sectioninfo.element; [
-<!--doc:Meta-information for a recursive section.-->
-<!ELEMENT sectioninfo %ho; ((%info.class;)+)
- %beginpage.exclusion;>
-<!--end of sectioninfo.element-->]]>
-
-<!ENTITY % sectioninfo.attlist "INCLUDE">
-<![ %sectioninfo.attlist; [
-<!ATTLIST sectioninfo
- %common.attrib;
- %sectioninfo.role.attrib;
- %local.sectioninfo.attrib;
->
-<!--end of sectioninfo.attlist-->]]>
-<!--end of sectioninfo.module-->]]>
-<!--end of section.content.module-->]]>
-
-<!-- ...................................................................... -->
-<!-- Sect1, Sect2, Sect3, Sect4, Sect5 .................................... -->
-
-<!ENTITY % sect1.module "INCLUDE">
-<![%sect1.module;[
-<!ENTITY % local.sect1.attrib "">
-<!ENTITY % sect1.role.attrib "%role.attrib;">
-
-<!ENTITY % sect1.element "INCLUDE">
-<![%sect1.element;[
-<!--doc:A top-level section of document.-->
-<!ELEMENT sect1 %ho; (sect1info?, (%sect.title.content;), (%nav.class;)*,
- (((%divcomponent.mix;)+,
- ((%refentry.class;)* | sect2* | simplesect*))
- | (%refentry.class;)+ | sect2+ | simplesect+), (%nav.class;)*)
- %ubiq.inclusion;>
-<!--end of sect1.element-->]]>
-
-<!-- Renderas: Indicates the format in which the heading should
- appear -->
-
-
-<!ENTITY % sect1.attlist "INCLUDE">
-<![%sect1.attlist;[
-<!ATTLIST sect1
- renderas (sect2
- |sect3
- |sect4
- |sect5) #IMPLIED
- %label.attrib;
- %status.attrib;
- %common.attrib;
- %sect1.role.attrib;
- %local.sect1.attrib;
->
-<!--end of sect1.attlist-->]]>
-<!--end of sect1.module-->]]>
-
-<!ENTITY % sect2.module "INCLUDE">
-<![%sect2.module;[
-<!ENTITY % local.sect2.attrib "">
-<!ENTITY % sect2.role.attrib "%role.attrib;">
-
-<!ENTITY % sect2.element "INCLUDE">
-<![%sect2.element;[
-<!--doc:A subsection within a Sect1.-->
-<!ELEMENT sect2 %ho; (sect2info?, (%sect.title.content;), (%nav.class;)*,
- (((%divcomponent.mix;)+,
- ((%refentry.class;)* | sect3* | simplesect*))
- | (%refentry.class;)+ | sect3+ | simplesect+), (%nav.class;)*)>
-<!--end of sect2.element-->]]>
-
-<!-- Renderas: Indicates the format in which the heading should
- appear -->
-
-
-<!ENTITY % sect2.attlist "INCLUDE">
-<![%sect2.attlist;[
-<!ATTLIST sect2
- renderas (sect1
- |sect3
- |sect4
- |sect5) #IMPLIED
- %label.attrib;
- %status.attrib;
- %common.attrib;
- %sect2.role.attrib;
- %local.sect2.attrib;
->
-<!--end of sect2.attlist-->]]>
-<!--end of sect2.module-->]]>
-
-<!ENTITY % sect3.module "INCLUDE">
-<![%sect3.module;[
-<!ENTITY % local.sect3.attrib "">
-<!ENTITY % sect3.role.attrib "%role.attrib;">
-
-<!ENTITY % sect3.element "INCLUDE">
-<![%sect3.element;[
-<!--doc:A subsection within a Sect2.-->
-<!ELEMENT sect3 %ho; (sect3info?, (%sect.title.content;), (%nav.class;)*,
- (((%divcomponent.mix;)+,
- ((%refentry.class;)* | sect4* | simplesect*))
- | (%refentry.class;)+ | sect4+ | simplesect+), (%nav.class;)*)>
-<!--end of sect3.element-->]]>
-
-<!-- Renderas: Indicates the format in which the heading should
- appear -->
-
-
-<!ENTITY % sect3.attlist "INCLUDE">
-<![%sect3.attlist;[
-<!ATTLIST sect3
- renderas (sect1
- |sect2
- |sect4
- |sect5) #IMPLIED
- %label.attrib;
- %status.attrib;
- %common.attrib;
- %sect3.role.attrib;
- %local.sect3.attrib;
->
-<!--end of sect3.attlist-->]]>
-<!--end of sect3.module-->]]>
-
-<!ENTITY % sect4.module "INCLUDE">
-<![%sect4.module;[
-<!ENTITY % local.sect4.attrib "">
-<!ENTITY % sect4.role.attrib "%role.attrib;">
-
-<!ENTITY % sect4.element "INCLUDE">
-<![%sect4.element;[
-<!--doc:A subsection within a Sect3.-->
-<!ELEMENT sect4 %ho; (sect4info?, (%sect.title.content;), (%nav.class;)*,
- (((%divcomponent.mix;)+,
- ((%refentry.class;)* | sect5* | simplesect*))
- | (%refentry.class;)+ | sect5+ | simplesect+), (%nav.class;)*)>
-<!--end of sect4.element-->]]>
-
-<!-- Renderas: Indicates the format in which the heading should
- appear -->
-
-
-<!ENTITY % sect4.attlist "INCLUDE">
-<![%sect4.attlist;[
-<!ATTLIST sect4
- renderas (sect1
- |sect2
- |sect3
- |sect5) #IMPLIED
- %label.attrib;
- %status.attrib;
- %common.attrib;
- %sect4.role.attrib;
- %local.sect4.attrib;
->
-<!--end of sect4.attlist-->]]>
-<!--end of sect4.module-->]]>
-
-<!ENTITY % sect5.module "INCLUDE">
-<![%sect5.module;[
-<!ENTITY % local.sect5.attrib "">
-<!ENTITY % sect5.role.attrib "%role.attrib;">
-
-<!ENTITY % sect5.element "INCLUDE">
-<![%sect5.element;[
-<!--doc:A subsection within a Sect4.-->
-<!ELEMENT sect5 %ho; (sect5info?, (%sect.title.content;), (%nav.class;)*,
- (((%divcomponent.mix;)+, ((%refentry.class;)* | simplesect*))
- | (%refentry.class;)+ | simplesect+), (%nav.class;)*)>
-<!--end of sect5.element-->]]>
-
-<!-- Renderas: Indicates the format in which the heading should
- appear -->
-
-
-<!ENTITY % sect5.attlist "INCLUDE">
-<![%sect5.attlist;[
-<!ATTLIST sect5
- renderas (sect1
- |sect2
- |sect3
- |sect4) #IMPLIED
- %label.attrib;
- %status.attrib;
- %common.attrib;
- %sect5.role.attrib;
- %local.sect5.attrib;
->
-<!--end of sect5.attlist-->]]>
-<!--end of sect5.module-->]]>
-
-<!ENTITY % simplesect.module "INCLUDE">
-<![%simplesect.module;[
-<!ENTITY % local.simplesect.attrib "">
-<!ENTITY % simplesect.role.attrib "%role.attrib;">
-
-<!ENTITY % simplesect.element "INCLUDE">
-<![%simplesect.element;[
-<!--doc:A section of a document with no subdivisions.-->
-<!ELEMENT simplesect %ho; ((%sect.title.content;), (%divcomponent.mix;)+)
- %ubiq.inclusion;>
-<!--end of simplesect.element-->]]>
-
-<!ENTITY % simplesect.attlist "INCLUDE">
-<![%simplesect.attlist;[
-<!ATTLIST simplesect
- %common.attrib;
- %simplesect.role.attrib;
- %local.simplesect.attrib;
->
-<!--end of simplesect.attlist-->]]>
-<!--end of simplesect.module-->]]>
-
-<!-- ...................................................................... -->
-<!-- Bibliography ......................................................... -->
-
-<!ENTITY % bibliography.content.module "INCLUDE">
-<![%bibliography.content.module;[
-<!ENTITY % bibliography.module "INCLUDE">
-<![%bibliography.module;[
-<!ENTITY % local.bibliography.attrib "">
-<!ENTITY % bibliography.role.attrib "%role.attrib;">
-
-<!ENTITY % bibliography.element "INCLUDE">
-<![%bibliography.element;[
-<!--doc:A bibliography.-->
-<!ELEMENT bibliography %ho; (bibliographyinfo?,
- (%bookcomponent.title.content;)?,
- (%component.mix;)*,
- (bibliodiv+ | (biblioentry|bibliomixed)+))>
-<!--end of bibliography.element-->]]>
-
-<!ENTITY % bibliography.attlist "INCLUDE">
-<![%bibliography.attlist;[
-<!ATTLIST bibliography
- %status.attrib;
- %common.attrib;
- %bibliography.role.attrib;
- %local.bibliography.attrib;
->
-<!--end of bibliography.attlist-->]]>
-<!--end of bibliography.module-->]]>
-
-<!ENTITY % bibliodiv.module "INCLUDE">
-<![%bibliodiv.module;[
-<!ENTITY % local.bibliodiv.attrib "">
-<!ENTITY % bibliodiv.role.attrib "%role.attrib;">
-
-<!ENTITY % bibliodiv.element "INCLUDE">
-<![%bibliodiv.element;[
-<!--doc:A section of a Bibliography.-->
-<!ELEMENT bibliodiv %ho; ((%sect.title.content;)?, (%component.mix;)*,
- (biblioentry|bibliomixed)+)>
-<!--end of bibliodiv.element-->]]>
-
-<!ENTITY % bibliodiv.attlist "INCLUDE">
-<![%bibliodiv.attlist;[
-<!ATTLIST bibliodiv
- %status.attrib;
- %common.attrib;
- %bibliodiv.role.attrib;
- %local.bibliodiv.attrib;
->
-<!--end of bibliodiv.attlist-->]]>
-<!--end of bibliodiv.module-->]]>
-<!--end of bibliography.content.module-->]]>
-
-<!-- ...................................................................... -->
-<!-- Glossary ............................................................. -->
-
-<!ENTITY % glossary.content.module "INCLUDE">
-<![%glossary.content.module;[
-<!ENTITY % glossary.module "INCLUDE">
-<![%glossary.module;[
-<!ENTITY % local.glossary.attrib "">
-<!ENTITY % glossary.role.attrib "%role.attrib;">
-
-<!ENTITY % glossary.element "INCLUDE">
-<![%glossary.element;[
-<!--doc:A glossary.-->
-<!ELEMENT glossary %ho; (glossaryinfo?,
- (%bookcomponent.title.content;)?,
- (%component.mix;)*,
- (glossdiv+ | glossentry+), bibliography?)>
-<!--end of glossary.element-->]]>
-
-<!ENTITY % glossary.attlist "INCLUDE">
-<![%glossary.attlist;[
-<!ATTLIST glossary
- %status.attrib;
- %common.attrib;
- %glossary.role.attrib;
- %local.glossary.attrib;
->
-<!--end of glossary.attlist-->]]>
-<!--end of glossary.module-->]]>
-
-<!ENTITY % glossdiv.module "INCLUDE">
-<![%glossdiv.module;[
-<!ENTITY % local.glossdiv.attrib "">
-<!ENTITY % glossdiv.role.attrib "%role.attrib;">
-
-<!ENTITY % glossdiv.element "INCLUDE">
-<![%glossdiv.element;[
-<!--doc:A division in a Glossary.-->
-<!ELEMENT glossdiv %ho; ((%sect.title.content;), (%component.mix;)*,
- glossentry+)>
-<!--end of glossdiv.element-->]]>
-
-<!ENTITY % glossdiv.attlist "INCLUDE">
-<![%glossdiv.attlist;[
-<!ATTLIST glossdiv
- %status.attrib;
- %common.attrib;
- %glossdiv.role.attrib;
- %local.glossdiv.attrib;
->
-<!--end of glossdiv.attlist-->]]>
-<!--end of glossdiv.module-->]]>
-<!--end of glossary.content.module-->]]>
-
-<!-- ...................................................................... -->
-<!-- Index and SetIndex ................................................... -->
-
-<!ENTITY % index.content.module "INCLUDE">
-<![%index.content.module;[
-<!ENTITY % indexes.module "INCLUDE">
-<![%indexes.module;[
-<!ENTITY % local.indexes.attrib "">
-<!ENTITY % indexes.role.attrib "%role.attrib;">
-
-<!ENTITY % index.element "INCLUDE">
-<![%index.element;[
-<!--doc:An index.-->
-<!ELEMENT index %ho; (indexinfo?,
- (%bookcomponent.title.content;)?,
- (%component.mix;)*,
- (indexdiv* | indexentry*))
- %ndxterm.exclusion;>
-<!--end of index.element-->]]>
-
-<!ENTITY % index.attlist "INCLUDE">
-<![%index.attlist;[
-<!ATTLIST index
- type CDATA #IMPLIED
- %common.attrib;
- %indexes.role.attrib;
- %local.indexes.attrib;
->
-<!--end of index.attlist-->]]>
-
-<!ENTITY % setindex.element "INCLUDE">
-<![%setindex.element;[
-<!--doc:An index to a set of books.-->
-<!ELEMENT setindex %ho; (setindexinfo?,
- (%bookcomponent.title.content;)?,
- (%component.mix;)*,
- (indexdiv* | indexentry*))
- %ndxterm.exclusion;>
-<!--end of setindex.element-->]]>
-
-<!ENTITY % setindex.attlist "INCLUDE">
-<![%setindex.attlist;[
-<!ATTLIST setindex
- %common.attrib;
- %indexes.role.attrib;
- %local.indexes.attrib;
->
-<!--end of setindex.attlist-->]]>
-<!--end of indexes.module-->]]>
-
-<!ENTITY % indexdiv.module "INCLUDE">
-<![%indexdiv.module;[
-
-<!-- SegmentedList in this content is useful for marking up permuted
- indices. -->
-
-<!ENTITY % local.indexdiv.attrib "">
-<!ENTITY % indexdiv.role.attrib "%role.attrib;">
-
-<!ENTITY % indexdiv.element "INCLUDE">
-<![%indexdiv.element;[
-<!--doc:A division in an index.-->
-<!ELEMENT indexdiv %ho; ((%sect.title.content;)?, ((%indexdivcomponent.mix;)*,
- (indexentry+ | segmentedlist)))>
-<!--end of indexdiv.element-->]]>
-
-<!ENTITY % indexdiv.attlist "INCLUDE">
-<![%indexdiv.attlist;[
-<!ATTLIST indexdiv
- %common.attrib;
- %indexdiv.role.attrib;
- %local.indexdiv.attrib;
->
-<!--end of indexdiv.attlist-->]]>
-<!--end of indexdiv.module-->]]>
-
-<!ENTITY % indexentry.module "INCLUDE">
-<![%indexentry.module;[
-<!-- Index entries appear in the index, not the text. -->
-
-<!ENTITY % local.indexentry.attrib "">
-<!ENTITY % indexentry.role.attrib "%role.attrib;">
-
-<!ENTITY % indexentry.element "INCLUDE">
-<![%indexentry.element;[
-<!--doc:An entry in an index.-->
-<!ELEMENT indexentry %ho; (primaryie, (seeie|seealsoie)*,
- (secondaryie, (seeie|seealsoie|tertiaryie)*)*)>
-<!--end of indexentry.element-->]]>
-
-<!ENTITY % indexentry.attlist "INCLUDE">
-<![%indexentry.attlist;[
-<!ATTLIST indexentry
- %common.attrib;
- %indexentry.role.attrib;
- %local.indexentry.attrib;
->
-<!--end of indexentry.attlist-->]]>
-<!--end of indexentry.module-->]]>
-
-<!ENTITY % primsecterie.module "INCLUDE">
-<![%primsecterie.module;[
-<!ENTITY % local.primsecterie.attrib "">
-<!ENTITY % primsecterie.role.attrib "%role.attrib;">
-
-<!ENTITY % primaryie.element "INCLUDE">
-<![%primaryie.element;[
-<!--doc:A primary term in an index entry, not in the text.-->
-<!ELEMENT primaryie %ho; (%ndxterm.char.mix;)*>
-<!--end of primaryie.element-->]]>
-
-<!-- to IndexTerms that these entries represent -->
-
-<!ENTITY % primaryie.attlist "INCLUDE">
-<![%primaryie.attlist;[
-<!ATTLIST primaryie
- %linkends.attrib; %common.attrib;
- %primsecterie.role.attrib;
- %local.primsecterie.attrib;
->
-<!--end of primaryie.attlist-->]]>
-
-<!ENTITY % secondaryie.element "INCLUDE">
-<![%secondaryie.element;[
-<!--doc:A secondary term in an index entry, rather than in the text.-->
-<!ELEMENT secondaryie %ho; (%ndxterm.char.mix;)*>
-<!--end of secondaryie.element-->]]>
-
-<!-- to IndexTerms that these entries represent -->
-
-<!ENTITY % secondaryie.attlist "INCLUDE">
-<![%secondaryie.attlist;[
-<!ATTLIST secondaryie
- %linkends.attrib; %common.attrib;
- %primsecterie.role.attrib;
- %local.primsecterie.attrib;
->
-<!--end of secondaryie.attlist-->]]>
-
-<!ENTITY % tertiaryie.element "INCLUDE">
-<![%tertiaryie.element;[
-<!--doc:A tertiary term in an index entry, rather than in the text.-->
-<!ELEMENT tertiaryie %ho; (%ndxterm.char.mix;)*>
-<!--end of tertiaryie.element-->]]>
-
-<!-- to IndexTerms that these entries represent -->
-
-<!ENTITY % tertiaryie.attlist "INCLUDE">
-<![%tertiaryie.attlist;[
-<!ATTLIST tertiaryie
- %linkends.attrib; %common.attrib;
- %primsecterie.role.attrib;
- %local.primsecterie.attrib;
->
-<!--end of tertiaryie.attlist-->]]>
-
-<!--end of primsecterie.module-->]]>
-
-<!ENTITY % seeie.module "INCLUDE">
-<![%seeie.module;[
-<!ENTITY % local.seeie.attrib "">
-<!ENTITY % seeie.role.attrib "%role.attrib;">
-
-<!ENTITY % seeie.element "INCLUDE">
-<![%seeie.element;[
-<!--doc:A See entry in an index, rather than in the text.-->
-<!ELEMENT seeie %ho; (%ndxterm.char.mix;)*>
-<!--end of seeie.element-->]]>
-
-<!-- to IndexEntry to look up -->
-
-
-<!ENTITY % seeie.attlist "INCLUDE">
-<![%seeie.attlist;[
-<!ATTLIST seeie
- %linkend.attrib; %common.attrib;
- %seeie.role.attrib;
- %local.seeie.attrib;
->
-<!--end of seeie.attlist-->]]>
-<!--end of seeie.module-->]]>
-
-<!ENTITY % seealsoie.module "INCLUDE">
-<![%seealsoie.module;[
-<!ENTITY % local.seealsoie.attrib "">
-<!ENTITY % seealsoie.role.attrib "%role.attrib;">
-
-<!ENTITY % seealsoie.element "INCLUDE">
-<![%seealsoie.element;[
-<!--doc:A See also entry in an index, rather than in the text.-->
-<!ELEMENT seealsoie %ho; (%ndxterm.char.mix;)*>
-<!--end of seealsoie.element-->]]>
-
-<!-- to related IndexEntries -->
-
-
-<!ENTITY % seealsoie.attlist "INCLUDE">
-<![%seealsoie.attlist;[
-<!ATTLIST seealsoie
- %linkends.attrib; %common.attrib;
- %seealsoie.role.attrib;
- %local.seealsoie.attrib;
->
-<!--end of seealsoie.attlist-->]]>
-<!--end of seealsoie.module-->]]>
-<!--end of index.content.module-->]]>
-
-<!-- ...................................................................... -->
-<!-- RefEntry ............................................................. -->
-
-<!ENTITY % refentry.content.module "INCLUDE">
-<![%refentry.content.module;[
-<!ENTITY % refentry.module "INCLUDE">
-<![%refentry.module;[
-<!ENTITY % local.refentry.attrib "">
-<!ENTITY % refentry.role.attrib "%role.attrib;">
-
-<!ENTITY % refentry.element "INCLUDE">
-<![%refentry.element;[
-<!--doc:A reference page (originally a UNIX man-style reference page).-->
-<!ELEMENT refentry %ho; (beginpage?,
- (%ndxterm.class;)*,
- refentryinfo?, refmeta?, (remark|%link.char.class;)*,
- refnamediv+, refsynopsisdiv?, (refsect1+|refsection+))
- %ubiq.inclusion;>
-<!--end of refentry.element-->]]>
-
-<!ENTITY % refentry.attlist "INCLUDE">
-<![%refentry.attlist;[
-<!ATTLIST refentry
- %status.attrib;
- %common.attrib;
- %refentry.role.attrib;
- %local.refentry.attrib;
->
-<!--end of refentry.attlist-->]]>
-<!--end of refentry.module-->]]>
-
-<!ENTITY % refmeta.module "INCLUDE">
-<![%refmeta.module;[
-<!ENTITY % local.refmeta.attrib "">
-<!ENTITY % refmeta.role.attrib "%role.attrib;">
-
-<!ENTITY % refmeta.element "INCLUDE">
-<![%refmeta.element;[
-<!--doc:Meta-information for a reference entry.-->
-<!ELEMENT refmeta %ho; ((%ndxterm.class;)*,
- refentrytitle, manvolnum?, refmiscinfo*,
- (%ndxterm.class;)*)
- %beginpage.exclusion;>
-<!--end of refmeta.element-->]]>
-
-<!ENTITY % refmeta.attlist "INCLUDE">
-<![%refmeta.attlist;[
-<!ATTLIST refmeta
- %common.attrib;
- %refmeta.role.attrib;
- %local.refmeta.attrib;
->
-<!--end of refmeta.attlist-->]]>
-<!--end of refmeta.module-->]]>
-
-<!ENTITY % refmiscinfo.module "INCLUDE">
-<![%refmiscinfo.module;[
-<!ENTITY % local.refmiscinfo.attrib "">
-<!ENTITY % refmiscinfo.role.attrib "%role.attrib;">
-
-<!ENTITY % refmiscinfo.element "INCLUDE">
-<![%refmiscinfo.element;[
-<!--doc:Meta-information for a reference entry other than the title and volume number.-->
-<!ELEMENT refmiscinfo %ho; (%docinfo.char.mix;)*>
-<!--end of refmiscinfo.element-->]]>
-
-<!-- Class: Freely assignable parameter; no default -->
-
-
-<!ENTITY % refmiscinfo.attlist "INCLUDE">
-<![%refmiscinfo.attlist;[
-<!ATTLIST refmiscinfo
- class CDATA #IMPLIED
- %common.attrib;
- %refmiscinfo.role.attrib;
- %local.refmiscinfo.attrib;
->
-<!--end of refmiscinfo.attlist-->]]>
-<!--end of refmiscinfo.module-->]]>
-
-<!ENTITY % refnamediv.module "INCLUDE">
-<![%refnamediv.module;[
-<!ENTITY % local.refnamediv.attrib "">
-<!ENTITY % refnamediv.role.attrib "%role.attrib;">
-
-<!ENTITY % refnamediv.element "INCLUDE">
-<![%refnamediv.element;[
-<!--doc:The name, purpose, and classification of a reference page.-->
-<!ELEMENT refnamediv %ho; (refdescriptor?, refname+, refpurpose, refclass*,
- (remark|%link.char.class;)*)>
-<!--end of refnamediv.element-->]]>
-
-<!ENTITY % refnamediv.attlist "INCLUDE">
-<![%refnamediv.attlist;[
-<!ATTLIST refnamediv
- %common.attrib;
- %refnamediv.role.attrib;
- %local.refnamediv.attrib;
->
-<!--end of refnamediv.attlist-->]]>
-<!--end of refnamediv.module-->]]>
-
-<!ENTITY % refdescriptor.module "INCLUDE">
-<![%refdescriptor.module;[
-<!ENTITY % local.refdescriptor.attrib "">
-<!ENTITY % refdescriptor.role.attrib "%role.attrib;">
-
-<!ENTITY % refdescriptor.element "INCLUDE">
-<![%refdescriptor.element;[
-<!--doc:A description of the topic of a reference page.-->
-<!ELEMENT refdescriptor %ho; (%refname.char.mix;)*>
-<!--end of refdescriptor.element-->]]>
-
-<!ENTITY % refdescriptor.attlist "INCLUDE">
-<![%refdescriptor.attlist;[
-<!ATTLIST refdescriptor
- %common.attrib;
- %refdescriptor.role.attrib;
- %local.refdescriptor.attrib;
->
-<!--end of refdescriptor.attlist-->]]>
-<!--end of refdescriptor.module-->]]>
-
-<!ENTITY % refname.module "INCLUDE">
-<![%refname.module;[
-<!ENTITY % local.refname.attrib "">
-<!ENTITY % refname.role.attrib "%role.attrib;">
-
-<!ENTITY % refname.element "INCLUDE">
-<![%refname.element;[
-<!--doc:The name of (one of) the subject(s) of a reference page.-->
-<!ELEMENT refname %ho; (%refname.char.mix;)*>
-<!--end of refname.element-->]]>
-
-<!ENTITY % refname.attlist "INCLUDE">
-<![%refname.attlist;[
-<!ATTLIST refname
- %common.attrib;
- %refname.role.attrib;
- %local.refname.attrib;
->
-<!--end of refname.attlist-->]]>
-<!--end of refname.module-->]]>
-
-<!ENTITY % refpurpose.module "INCLUDE">
-<![%refpurpose.module;[
-<!ENTITY % local.refpurpose.attrib "">
-<!ENTITY % refpurpose.role.attrib "%role.attrib;">
-
-<!ENTITY % refpurpose.element "INCLUDE">
-<![%refpurpose.element;[
-<!--doc:A short (one sentence) synopsis of the topic of a reference page.-->
-<!ELEMENT refpurpose %ho; (%refinline.char.mix;)*>
-<!--end of refpurpose.element-->]]>
-
-<!ENTITY % refpurpose.attlist "INCLUDE">
-<![%refpurpose.attlist;[
-<!ATTLIST refpurpose
- %common.attrib;
- %refpurpose.role.attrib;
- %local.refpurpose.attrib;
->
-<!--end of refpurpose.attlist-->]]>
-<!--end of refpurpose.module-->]]>
-
-<!ENTITY % refclass.module "INCLUDE">
-<![%refclass.module;[
-<!ENTITY % local.refclass.attrib "">
-<!ENTITY % refclass.role.attrib "%role.attrib;">
-
-<!ENTITY % refclass.element "INCLUDE">
-<![%refclass.element;[
-<!--doc:The scope or other indication of applicability of a reference entry.-->
-<!ELEMENT refclass %ho; (%refclass.char.mix;)*>
-<!--end of refclass.element-->]]>
-
-<!ENTITY % refclass.attlist "INCLUDE">
-<![%refclass.attlist;[
-<!ATTLIST refclass
- %common.attrib;
- %refclass.role.attrib;
- %local.refclass.attrib;
->
-<!--end of refclass.attlist-->]]>
-<!--end of refclass.module-->]]>
-
-<!ENTITY % refsynopsisdiv.module "INCLUDE">
-<![%refsynopsisdiv.module;[
-<!ENTITY % local.refsynopsisdiv.attrib "">
-<!ENTITY % refsynopsisdiv.role.attrib "%role.attrib;">
-
-<!ENTITY % refsynopsisdiv.element "INCLUDE">
-<![%refsynopsisdiv.element;[
-<!--doc:A syntactic synopsis of the subject of the reference page.-->
-<!ELEMENT refsynopsisdiv %ho; (refsynopsisdivinfo?, (%refsect.title.content;)?,
- (((%refcomponent.mix;)+, refsect2*) | (refsect2+)))>
-<!--end of refsynopsisdiv.element-->]]>
-
-<!ENTITY % refsynopsisdiv.attlist "INCLUDE">
-<![%refsynopsisdiv.attlist;[
-<!ATTLIST refsynopsisdiv
- %common.attrib;
- %refsynopsisdiv.role.attrib;
- %local.refsynopsisdiv.attrib;
->
-<!--end of refsynopsisdiv.attlist-->]]>
-<!--end of refsynopsisdiv.module-->]]>
-
-<!ENTITY % refsection.module "INCLUDE">
-<![%refsection.module;[
-<!ENTITY % local.refsection.attrib "">
-<!ENTITY % refsection.role.attrib "%role.attrib;">
-
-<!ENTITY % refsection.element "INCLUDE">
-<![%refsection.element;[
-<!--doc:A recursive section in a refentry.-->
-<!ELEMENT refsection %ho; (refsectioninfo?, (%refsect.title.content;),
- (((%refcomponent.mix;)+, refsection*) | refsection+))>
-<!--end of refsection.element-->]]>
-
-<!ENTITY % refsection.attlist "INCLUDE">
-<![%refsection.attlist;[
-<!ATTLIST refsection
- %status.attrib;
- %common.attrib;
- %refsection.role.attrib;
- %local.refsection.attrib;
->
-<!--end of refsection.attlist-->]]>
-<!--end of refsection.module-->]]>
-
-<!ENTITY % refsect1.module "INCLUDE">
-<![%refsect1.module;[
-<!ENTITY % local.refsect1.attrib "">
-<!ENTITY % refsect1.role.attrib "%role.attrib;">
-
-<!ENTITY % refsect1.element "INCLUDE">
-<![%refsect1.element;[
-<!--doc:A major subsection of a reference entry.-->
-<!ELEMENT refsect1 %ho; (refsect1info?, (%refsect.title.content;),
- (((%refcomponent.mix;)+, refsect2*) | refsect2+))>
-<!--end of refsect1.element-->]]>
-
-<!ENTITY % refsect1.attlist "INCLUDE">
-<![%refsect1.attlist;[
-<!ATTLIST refsect1
- %status.attrib;
- %common.attrib;
- %refsect1.role.attrib;
- %local.refsect1.attrib;
->
-<!--end of refsect1.attlist-->]]>
-<!--end of refsect1.module-->]]>
-
-<!ENTITY % refsect2.module "INCLUDE">
-<![%refsect2.module;[
-<!ENTITY % local.refsect2.attrib "">
-<!ENTITY % refsect2.role.attrib "%role.attrib;">
-
-<!ENTITY % refsect2.element "INCLUDE">
-<![%refsect2.element;[
-<!--doc:A subsection of a RefSect1.-->
-<!ELEMENT refsect2 %ho; (refsect2info?, (%refsect.title.content;),
- (((%refcomponent.mix;)+, refsect3*) | refsect3+))>
-<!--end of refsect2.element-->]]>
-
-<!ENTITY % refsect2.attlist "INCLUDE">
-<![%refsect2.attlist;[
-<!ATTLIST refsect2
- %status.attrib;
- %common.attrib;
- %refsect2.role.attrib;
- %local.refsect2.attrib;
->
-<!--end of refsect2.attlist-->]]>
-<!--end of refsect2.module-->]]>
-
-<!ENTITY % refsect3.module "INCLUDE">
-<![%refsect3.module;[
-<!ENTITY % local.refsect3.attrib "">
-<!ENTITY % refsect3.role.attrib "%role.attrib;">
-
-<!ENTITY % refsect3.element "INCLUDE">
-<![%refsect3.element;[
-<!--doc:A subsection of a RefSect2.-->
-<!ELEMENT refsect3 %ho; (refsect3info?, (%refsect.title.content;),
- (%refcomponent.mix;)+)>
-<!--end of refsect3.element-->]]>
-
-<!ENTITY % refsect3.attlist "INCLUDE">
-<![%refsect3.attlist;[
-<!ATTLIST refsect3
- %status.attrib;
- %common.attrib;
- %refsect3.role.attrib;
- %local.refsect3.attrib;
->
-<!--end of refsect3.attlist-->]]>
-<!--end of refsect3.module-->]]>
-<!--end of refentry.content.module-->]]>
-
-<!-- ...................................................................... -->
-<!-- Article .............................................................. -->
-
-<!ENTITY % article.module "INCLUDE">
-<![%article.module;[
-<!-- An Article is a chapter-level, stand-alone document that is often,
- but need not be, collected into a Book. -->
-
-<!ENTITY % local.article.attrib "">
-<!ENTITY % article.role.attrib "%role.attrib;">
-
-<!ENTITY % article.element "INCLUDE">
-<![%article.element;[
-<!--doc:An article.-->
-<!ELEMENT article %ho; ((%div.title.content;)?, articleinfo?, tocchap?, lot*,
- (%bookcomponent.content;),
- (%nav.class;|%appendix.class;|colophon|ackno)*)
- %ubiq.inclusion;>
-<!--end of article.element-->]]>
-
-<!-- Class: Indicates the type of a particular article;
- all articles have the same structure and general purpose.
- No default. -->
-<!-- ParentBook: ID of the enclosing Book -->
-
-
-<!ENTITY % article.attlist "INCLUDE">
-<![%article.attlist;[
-<!ATTLIST article
- class (journalarticle
- |productsheet
- |whitepaper
- |techreport
- |specification
- |faq) #IMPLIED
- parentbook IDREF #IMPLIED
- %status.attrib;
- %common.attrib;
- %article.role.attrib;
- %local.article.attrib;
->
-<!--end of article.attlist-->]]>
-<!--end of article.module-->]]>
-
-<!-- End of DocBook document hierarchy module V4.5 ........................ -->
-<!-- ...................................................................... -->
diff --git a/Utilities/xml/docbook-4.5/dbnotnx.mod b/Utilities/xml/docbook-4.5/dbnotnx.mod
deleted file mode 100644
index 2416049bf..000000000
--- a/Utilities/xml/docbook-4.5/dbnotnx.mod
+++ /dev/null
@@ -1,101 +0,0 @@
-<!-- ...................................................................... -->
-<!-- DocBook notations module V4.5 ........................................ -->
-<!-- File dbnotnx.mod ..................................................... -->
-
-<!-- Copyright 1992-2004 HaL Computer Systems, Inc.,
- O'Reilly & Associates, Inc., ArborText, Inc., Fujitsu Software
- Corporation, Norman Walsh, Sun Microsystems, Inc., and the
- Organization for the Advancement of Structured Information
- Standards (OASIS).
-
- $Id: dbnotnx.mod 6340 2006-10-03 13:23:24Z nwalsh $
-
- Permission to use, copy, modify and distribute the DocBook DTD
- and its accompanying documentation for any purpose and without fee
- is hereby granted in perpetuity, provided that the above copyright
- notice and this paragraph appear in all copies. The copyright
- holders make no representation about the suitability of the DTD for
- any purpose. It is provided "as is" without expressed or implied
- warranty.
-
- If you modify the DocBook DTD in any way, except for declaring and
- referencing additional sets of general entities and declaring
- additional notations, label your DTD as a variant of DocBook. See
- the maintenance documentation for more information.
-
- Please direct all questions, bug reports, or suggestions for
- changes to the docbook@lists.oasis-open.org mailing list. For more
- information, see http://www.oasis-open.org/docbook/.
--->
-
-<!-- ...................................................................... -->
-
-<!-- This module contains the notation declarations used by DocBook.
-
- In DTD driver files referring to this module, please use an entity
- declaration that uses the public identifier shown below:
-
- <!ENTITY % dbnotn PUBLIC
- "-//OASIS//ENTITIES DocBook Notations V4.5//EN"
- "dbnotnx.mod">
- %dbnotn;
-
- See the documentation for detailed information on the parameter
- entity and module scheme used in DocBook, customizing DocBook and
- planning for interchange, and changes made since the last release
- of DocBook.
--->
-
-<!ENTITY % local.notation.class "">
-<!ENTITY % notation.class
- "BMP| CGM-CHAR | CGM-BINARY | CGM-CLEAR | DITROFF | DVI
- | EPS | EQN | FAX | GIF | GIF87a | GIF89a
- | JPG | JPEG | IGES | PCX
- | PIC | PNG | PS | SGML | TBL | TEX | TIFF | WMF | WPG
- | SVG | PDF | SWF
- | linespecific
- %local.notation.class;">
-
-<!NOTATION BMP PUBLIC
-"+//ISBN 0-7923-94.2-1::Graphic Notation//NOTATION Microsoft Windows bitmap//EN">
-<!NOTATION CGM-CHAR PUBLIC "ISO 8632/2//NOTATION Character encoding//EN">
-<!NOTATION CGM-BINARY PUBLIC "ISO 8632/3//NOTATION Binary encoding//EN">
-<!NOTATION CGM-CLEAR PUBLIC "ISO 8632/4//NOTATION Clear text encoding//EN">
-<!NOTATION DITROFF SYSTEM "DITROFF">
-<!NOTATION DVI SYSTEM "DVI">
-<!NOTATION EPS PUBLIC
-"+//ISBN 0-201-18127-4::Adobe//NOTATION PostScript Language Ref. Manual//EN">
-<!NOTATION EQN SYSTEM "EQN">
-<!NOTATION FAX PUBLIC
-"-//USA-DOD//NOTATION CCITT Group 4 Facsimile Type 1 Untiled Raster//EN">
-<!NOTATION GIF SYSTEM "GIF">
-<!NOTATION GIF87a PUBLIC
-"-//CompuServe//NOTATION Graphics Interchange Format 87a//EN">
-
-<!NOTATION GIF89a PUBLIC
-"-//CompuServe//NOTATION Graphics Interchange Format 89a//EN">
-<!NOTATION JPG SYSTEM "JPG">
-<!NOTATION JPEG SYSTEM "JPG">
-<!NOTATION IGES PUBLIC
-"-//USA-DOD//NOTATION (ASME/ANSI Y14.26M-1987) Initial Graphics Exchange Specification//EN">
-<!NOTATION PCX PUBLIC
-"+//ISBN 0-7923-94.2-1::Graphic Notation//NOTATION ZSoft PCX bitmap//EN">
-<!NOTATION PIC SYSTEM "PIC">
-<!NOTATION PNG SYSTEM "http://www.w3.org/TR/REC-png">
-<!NOTATION PS SYSTEM "PS">
-<!NOTATION SGML PUBLIC
-"ISO 8879:1986//NOTATION Standard Generalized Markup Language//EN">
-<!NOTATION TBL SYSTEM "TBL">
-<!NOTATION TEX PUBLIC
-"+//ISBN 0-201-13448-9::Knuth//NOTATION The TeXbook//EN">
-<!NOTATION TIFF SYSTEM "TIFF">
-<!NOTATION WMF PUBLIC
-"+//ISBN 0-7923-94.2-1::Graphic Notation//NOTATION Microsoft Windows Metafile//EN">
-<!NOTATION WPG SYSTEM "WPG"> <!--WordPerfect Graphic format-->
-<!NOTATION SVG SYSTEM "http://www.w3.org/TR/SVG/">
-<!NOTATION PDF SYSTEM "http://www.adobe.com/products/acrobat/adobepdf.html">
-<!NOTATION SWF SYSTEM "http://www.macromedia.com/software/flash">
-<!NOTATION linespecific SYSTEM "linespecific">
-
-<!-- End of DocBook notations module V4.5 ................................. -->
-<!-- ...................................................................... -->
diff --git a/Utilities/xml/docbook-4.5/dbpoolx.mod b/Utilities/xml/docbook-4.5/dbpoolx.mod
deleted file mode 100644
index 53b07044a..000000000
--- a/Utilities/xml/docbook-4.5/dbpoolx.mod
+++ /dev/null
@@ -1,8701 +0,0 @@
-<!-- ...................................................................... -->
-<!-- DocBook XML information pool module V4.5 ............................. -->
-<!-- File dbpoolx.mod ..................................................... -->
-
-<!-- Copyright 1992-2004 HaL Computer Systems, Inc.,
- O'Reilly & Associates, Inc., ArborText, Inc., Fujitsu Software
- Corporation, Norman Walsh, Sun Microsystems, Inc., and the
- Organization for the Advancement of Structured Information
- Standards (OASIS).
-
- $Id: dbpoolx.mod 6340 2006-10-03 13:23:24Z nwalsh $
-
- Permission to use, copy, modify and distribute the DocBook XML DTD
- and its accompanying documentation for any purpose and without fee
- is hereby granted in perpetuity, provided that the above copyright
- notice and this paragraph appear in all copies. The copyright
- holders make no representation about the suitability of the DTD for
- any purpose. It is provided "as is" without expressed or implied
- warranty.
-
- If you modify the DocBook XML DTD in any way, except for declaring and
- referencing additional sets of general entities and declaring
- additional notations, label your DTD as a variant of DocBook. See
- the maintenance documentation for more information.
-
- Please direct all questions, bug reports, or suggestions for
- changes to the docbook@lists.oasis-open.org mailing list. For more
- information, see http://www.oasis-open.org/docbook/.
--->
-
-<!-- ...................................................................... -->
-
-<!-- This module contains the definitions for the objects, inline
- elements, and so on that are available to be used as the main
- content of DocBook documents. Some elements are useful for general
- publishing, and others are useful specifically for computer
- documentation.
-
- This module has the following dependencies on other modules:
-
- o It assumes that a %notation.class; entity is defined by the
- driver file or other high-level module. This entity is
- referenced in the NOTATION attributes for the graphic-related and
- ModeSpec elements.
-
- o It assumes that an appropriately parameterized table module is
- available for use with the table-related elements.
-
- In DTD driver files referring to this module, please use an entity
- declaration that uses the public identifier shown below:
-
- <!ENTITY % dbpool PUBLIC
- "-//OASIS//ELEMENTS DocBook XML Information Pool V4.5//EN"
- "dbpoolx.mod">
- %dbpool;
-
- See the documentation for detailed information on the parameter
- entity and module scheme used in DocBook, customizing DocBook and
- planning for interchange, and changes made since the last release
- of DocBook.
--->
-
-<!-- ...................................................................... -->
-<!-- Forms entities ....................................................... -->
-<!-- These PEs provide the hook by which the forms module can be inserted -->
-<!-- into the DTD. -->
-<!ENTITY % forminlines.hook "">
-<!ENTITY % forms.hook "">
-
-<!-- ...................................................................... -->
-<!-- General-purpose semantics entities ................................... -->
-
-<!ENTITY % yesorno.attvals "CDATA">
-
-<!-- ...................................................................... -->
-<!-- Entities for module inclusions ....................................... -->
-
-<!ENTITY % dbpool.redecl.module "IGNORE">
-
-<!-- ...................................................................... -->
-<!-- Entities for element classes and mixtures ............................ -->
-
-<!-- "Ubiquitous" classes: ndxterm.class and beginpage -->
-
-<!ENTITY % local.ndxterm.class "">
-<!ENTITY % ndxterm.class
- "indexterm %local.ndxterm.class;">
-
-<!-- Object-level classes ................................................. -->
-
-<!ENTITY % local.list.class "">
-<!ENTITY % list.class
- "calloutlist|glosslist|bibliolist|itemizedlist|orderedlist|segmentedlist
- |simplelist|variablelist %local.list.class;">
-
-<!ENTITY % local.admon.class "">
-<!ENTITY % admon.class
- "caution|important|note|tip|warning %local.admon.class;">
-
-<!ENTITY % local.linespecific.class "">
-<!ENTITY % linespecific.class
- "literallayout|programlisting|programlistingco|screen
- |screenco|screenshot %local.linespecific.class;">
-
-<!ENTITY % local.method.synop.class "">
-<!ENTITY % method.synop.class
- "constructorsynopsis
- |destructorsynopsis
- |methodsynopsis %local.method.synop.class;">
-
-<!ENTITY % local.synop.class "">
-<!ENTITY % synop.class
- "synopsis|cmdsynopsis|funcsynopsis
- |classsynopsis|fieldsynopsis
- |%method.synop.class; %local.synop.class;">
-
-<!ENTITY % local.para.class "">
-<!ENTITY % para.class
- "formalpara|para|simpara %local.para.class;">
-
-<!ENTITY % local.informal.class "">
-<!ENTITY % informal.class
- "address|blockquote
- |graphic|graphicco|mediaobject|mediaobjectco
- |informalequation
- |informalexample
- |informalfigure
- |informaltable %local.informal.class;">
-
-<!ENTITY % local.formal.class "">
-<!ENTITY % formal.class
- "equation|example|figure|table %local.formal.class;">
-
-<!-- The DocBook TC may produce an official EBNF module for DocBook. -->
-<!-- This PE provides the hook by which it can be inserted into the DTD. -->
-<!ENTITY % ebnf.block.hook "">
-
-<!ENTITY % local.compound.class "">
-<!ENTITY % compound.class
- "msgset|procedure|sidebar|qandaset|task
- %ebnf.block.hook;
- %local.compound.class;">
-
-<!ENTITY % local.genobj.class "">
-<!ENTITY % genobj.class
- "anchor|bridgehead|remark|highlights
- %local.genobj.class;">
-
-<!ENTITY % local.descobj.class "">
-<!ENTITY % descobj.class
- "abstract|authorblurb|epigraph
- %local.descobj.class;">
-
-<!-- Character-level classes .............................................. -->
-
-<!ENTITY % local.xref.char.class "">
-<!ENTITY % xref.char.class
- "footnoteref|xref|biblioref %local.xref.char.class;">
-
-<!ENTITY % local.gen.char.class "">
-<!ENTITY % gen.char.class
- "abbrev|acronym|citation|citerefentry|citetitle|citebiblioid|emphasis
- |firstterm|foreignphrase|glossterm|termdef|footnote|phrase
- |orgname|quote|trademark|wordasword
- |personname %local.gen.char.class;">
-
-<!ENTITY % local.link.char.class "">
-<!ENTITY % link.char.class
- "link|olink|ulink %local.link.char.class;">
-
-<!-- The DocBook TC may produce an official EBNF module for DocBook. -->
-<!-- This PE provides the hook by which it can be inserted into the DTD. -->
-<!ENTITY % ebnf.inline.hook "">
-
-<!ENTITY % local.tech.char.class "">
-<!ENTITY % tech.char.class
- "action|application
- |classname|methodname|interfacename|exceptionname
- |ooclass|oointerface|ooexception
- |package
- |command|computeroutput
- |database|email|envar|errorcode|errorname|errortype|errortext|filename
- |function|guibutton|guiicon|guilabel|guimenu|guimenuitem
- |guisubmenu|hardware|interface|keycap
- |keycode|keycombo|keysym|literal|code|constant|markup|medialabel
- |menuchoice|mousebutton|option|optional|parameter
- |prompt|property|replaceable|returnvalue|sgmltag|structfield
- |structname|symbol|systemitem|uri|token|type|userinput|varname
- %ebnf.inline.hook;
- %local.tech.char.class;">
-
-<!ENTITY % local.base.char.class "">
-<!ENTITY % base.char.class
- "anchor %local.base.char.class;">
-
-<!ENTITY % local.docinfo.char.class "">
-<!ENTITY % docinfo.char.class
- "author|authorinitials|corpauthor|corpcredit|modespec|othercredit
- |productname|productnumber|revhistory
- %local.docinfo.char.class;">
-
-<!ENTITY % local.other.char.class "">
-<!ENTITY % other.char.class
- "remark|subscript|superscript %local.other.char.class;">
-
-<!ENTITY % local.inlineobj.char.class "">
-<!ENTITY % inlineobj.char.class
- "inlinegraphic|inlinemediaobject|inlineequation %local.inlineobj.char.class;">
-
-<!-- ...................................................................... -->
-<!-- Entities for content models .......................................... -->
-
-<!ENTITY % formalobject.title.content "title, titleabbrev?">
-
-<!-- Redeclaration placeholder ............................................ -->
-
-<!-- For redeclaring entities that are declared after this point while
- retaining their references to the entities that are declared before
- this point -->
-
-<![%dbpool.redecl.module;[
-<!-- Defining rdbpool here makes some buggy XML parsers happy. -->
-<!ENTITY % rdbpool "">
-%rdbpool;
-<!--end of dbpool.redecl.module-->]]>
-
-<!-- Object-level mixtures ................................................ -->
-
-<!--
- list admn line synp para infm form cmpd gen desc
-Component mixture X X X X X X X X X X
-Sidebar mixture X X X X X X X a X
-Footnote mixture X X X X X
-Example mixture X X X X X
-Highlights mixture X X X
-Paragraph mixture X X X X
-Admonition mixture X X X X X X b c
-Figure mixture X X X
-Table entry mixture X X X X d
-Glossary def mixture X X X X X e
-Legal notice mixture X X X X f
-
-a. Just Procedure; not Sidebar itself or MsgSet.
-b. No MsgSet.
-c. No Highlights.
-d. Just Graphic; no other informal objects.
-e. No Anchor, BridgeHead, or Highlights.
-f. Just BlockQuote; no other informal objects.
--->
-
-<!ENTITY % local.component.mix "">
-<!ENTITY % component.mix
- "%list.class; |%admon.class;
- |%linespecific.class; |%synop.class;
- |%para.class; |%informal.class;
- |%formal.class; |%compound.class;
- |%genobj.class; |%descobj.class;
- |%ndxterm.class; |beginpage
- %forms.hook;
- %local.component.mix;">
-
-<!ENTITY % local.sidebar.mix "">
-<!ENTITY % sidebar.mix
- "%list.class; |%admon.class;
- |%linespecific.class; |%synop.class;
- |%para.class; |%informal.class;
- |%formal.class; |procedure
- |%genobj.class;
- |%ndxterm.class; |beginpage
- %forms.hook;
- %local.sidebar.mix;">
-
-<!ENTITY % local.qandaset.mix "">
-<!ENTITY % qandaset.mix
- "%list.class; |%admon.class;
- |%linespecific.class; |%synop.class;
- |%para.class; |%informal.class;
- |%formal.class; |procedure
- |%genobj.class;
- |%ndxterm.class;
- %forms.hook;
- %local.qandaset.mix;">
-
-<!ENTITY % local.revdescription.mix "">
-<!ENTITY % revdescription.mix
- "%list.class; |%admon.class;
- |%linespecific.class; |%synop.class;
- |%para.class; |%informal.class;
- |%formal.class; |procedure
- |%genobj.class;
- |%ndxterm.class;
- %local.revdescription.mix;">
-
-<!ENTITY % local.footnote.mix "">
-<!ENTITY % footnote.mix
- "%list.class;
- |%linespecific.class; |%synop.class;
- |%para.class; |%informal.class;
- %local.footnote.mix;">
-
-<!ENTITY % local.example.mix "">
-<!ENTITY % example.mix
- "%list.class;
- |%linespecific.class; |%synop.class;
- |%para.class; |%informal.class;
- |%ndxterm.class; |beginpage
- |procedure
- %forms.hook;
- %local.example.mix;">
-
-<!ENTITY % local.highlights.mix "">
-<!ENTITY % highlights.mix
- "%list.class; |%admon.class;
- |%para.class;
- |%ndxterm.class;
- %local.highlights.mix;">
-
-<!-- %formal.class; is explicitly excluded from many contexts in which
- paragraphs are used -->
-<!ENTITY % local.para.mix "">
-<!ENTITY % para.mix
- "%list.class; |%admon.class;
- |%linespecific.class;
- |%informal.class;
- |%formal.class;
- %local.para.mix;">
-
-<!ENTITY % local.admon.mix "">
-<!ENTITY % admon.mix
- "%list.class;
- |%linespecific.class; |%synop.class;
- |%para.class; |%informal.class;
- |%formal.class; |procedure|sidebar
- |anchor|bridgehead|remark
- |%ndxterm.class; |beginpage
- %forms.hook;
- %local.admon.mix;">
-
-<!ENTITY % local.figure.mix "">
-<!ENTITY % figure.mix
- "%linespecific.class; |%synop.class;
- |%informal.class;
- |%ndxterm.class; |beginpage
- %forms.hook;
- %local.figure.mix;">
-
-<!ENTITY % local.tabentry.mix "">
-<!ENTITY % tabentry.mix
- "%list.class; |%admon.class;
- |%linespecific.class;
- |%para.class; |graphic|mediaobject
- %forms.hook;
- %local.tabentry.mix;">
-
-<!ENTITY % local.glossdef.mix "">
-<!ENTITY % glossdef.mix
- "%list.class;
- |%linespecific.class; |%synop.class;
- |%para.class; |%informal.class;
- |%formal.class;
- |remark
- |%ndxterm.class; |beginpage
- %local.glossdef.mix;">
-
-<!ENTITY % local.legalnotice.mix "">
-<!ENTITY % legalnotice.mix
- "%list.class; |%admon.class;
- |%linespecific.class;
- |%para.class; |blockquote
- |%ndxterm.class; |beginpage
- %local.legalnotice.mix;">
-
-<!ENTITY % local.textobject.mix "">
-<!ENTITY % textobject.mix
- "%list.class; |%admon.class;
- |%linespecific.class;
- |%para.class; |blockquote
- %local.textobject.mix;">
-
-<!ENTITY % local.mediaobject.mix "">
-<!ENTITY % mediaobject.mix
- "videoobject|audioobject|imageobject|imageobjectco|textobject %local.mediaobject.mix;">
-
-<!ENTITY % local.listpreamble.mix "">
-<!ENTITY % listpreamble.mix
- " %admon.class;
- |%linespecific.class; |%synop.class;
- |%para.class; |%informal.class;
- |%genobj.class; |%descobj.class;
- |%ndxterm.class; |beginpage
- %forms.hook;
- %local.listpreamble.mix;">
-
-<!-- Character-level mixtures ............................................. -->
-
-<![%sgml.features;[
-<!ENTITY % local.ubiq.mix "">
-<!ENTITY % ubiq.mix "%ndxterm.class;|beginpage %local.ubiq.mix;">
-
-<!ENTITY % ubiq.exclusion "-(%ubiq.mix)">
-<!ENTITY % ubiq.inclusion "+(%ubiq.mix)">
-
-<!ENTITY % footnote.exclusion "-(footnote|%formal.class;)">
-<!ENTITY % highlights.exclusion "-(%ubiq.mix;|%formal.class;)">
-<!ENTITY % admon.exclusion "-(%admon.class;)">
-<!ENTITY % formal.exclusion "-(%formal.class;)">
-<!ENTITY % acronym.exclusion "-(acronym)">
-<!ENTITY % beginpage.exclusion "-(beginpage)">
-<!ENTITY % ndxterm.exclusion "-(%ndxterm.class;)">
-<!ENTITY % blockquote.exclusion "-(epigraph)">
-<!ENTITY % remark.exclusion "-(remark|%ubiq.mix;)">
-<!ENTITY % glossterm.exclusion "-(glossterm)">
-<!ENTITY % links.exclusion "-(link|olink|ulink|xref|biblioref)">
-]]><!-- sgml.features -->
-
-<!-- not [sgml.features[ -->
-<!ENTITY % local.ubiq.mix "">
-<!ENTITY % ubiq.mix "">
-
-<!ENTITY % ubiq.exclusion "">
-<!ENTITY % ubiq.inclusion "">
-
-<!ENTITY % footnote.exclusion "">
-<!ENTITY % highlights.exclusion "">
-<!ENTITY % admon.exclusion "">
-<!ENTITY % formal.exclusion "">
-<!ENTITY % acronym.exclusion "">
-<!ENTITY % beginpage.exclusion "">
-<!ENTITY % ndxterm.exclusion "">
-<!ENTITY % blockquote.exclusion "">
-<!ENTITY % remark.exclusion "">
-<!ENTITY % glossterm.exclusion "">
-<!ENTITY % links.exclusion "">
-<!-- ]] not sgml.features -->
-
-<!--
- #PCD xref word link cptr base dnfo othr inob (synop)
-para.char.mix X X X X X X X X X
-title.char.mix X X X X X X X X X
-ndxterm.char.mix X X X X X X X X a
-cptr.char.mix X X X X X a
-smallcptr.char.mix X b a
-word.char.mix X c X X X a
-docinfo.char.mix X d X b X a
-
-a. Just InlineGraphic; no InlineEquation.
-b. Just Replaceable; no other computer terms.
-c. Just Emphasis and Trademark; no other word elements.
-d. Just Acronym, Emphasis, and Trademark; no other word elements.
--->
-
-<!ENTITY % local.para.char.mix "">
-<!ENTITY % para.char.mix
- "#PCDATA
- |%xref.char.class; |%gen.char.class;
- |%link.char.class; |%tech.char.class;
- |%base.char.class; |%docinfo.char.class;
- |%other.char.class; |%inlineobj.char.class;
- |%synop.class;
- |%ndxterm.class; |beginpage
- %forminlines.hook;
- %local.para.char.mix;">
-
-<!ENTITY % local.title.char.mix "">
-<!ENTITY % title.char.mix
- "#PCDATA
- |%xref.char.class; |%gen.char.class;
- |%link.char.class; |%tech.char.class;
- |%base.char.class; |%docinfo.char.class;
- |%other.char.class; |%inlineobj.char.class;
- |%ndxterm.class;
- %local.title.char.mix;">
-
-<!ENTITY % local.ndxterm.char.mix "">
-<!ENTITY % ndxterm.char.mix
- "#PCDATA
- |%xref.char.class; |%gen.char.class;
- |%link.char.class; |%tech.char.class;
- |%base.char.class; |%docinfo.char.class;
- |%other.char.class; |inlinegraphic|inlinemediaobject
- %local.ndxterm.char.mix;">
-
-<!ENTITY % local.cptr.char.mix "">
-<!ENTITY % cptr.char.mix
- "#PCDATA
- |%link.char.class; |%tech.char.class;
- |%base.char.class;
- |%other.char.class; |inlinegraphic|inlinemediaobject
- |%ndxterm.class; |beginpage
- %local.cptr.char.mix;">
-
-<!ENTITY % local.smallcptr.char.mix "">
-<!ENTITY % smallcptr.char.mix
- "#PCDATA
- |replaceable
- |inlinegraphic|inlinemediaobject
- |%ndxterm.class; |beginpage
- %local.smallcptr.char.mix;">
-
-<!ENTITY % local.word.char.mix "">
-<!ENTITY % word.char.mix
- "#PCDATA
- |acronym|emphasis|trademark
- |%link.char.class;
- |%base.char.class;
- |%other.char.class; |inlinegraphic|inlinemediaobject
- |%ndxterm.class; |beginpage
- %local.word.char.mix;">
-
-<!ENTITY % local.docinfo.char.mix "">
-<!ENTITY % docinfo.char.mix
- "#PCDATA
- |%link.char.class;
- |emphasis|trademark
- |replaceable
- |%other.char.class; |inlinegraphic|inlinemediaobject
- |%ndxterm.class;
- %local.docinfo.char.mix;">
-<!--ENTITY % bibliocomponent.mix (see Bibliographic section, below)-->
-<!--ENTITY % person.ident.mix (see Bibliographic section, below)-->
-
-<!-- ...................................................................... -->
-<!-- Entities for attributes and attribute components ..................... -->
-
-<!-- Effectivity attributes ............................................... -->
-
-
-<!-- Arch: Computer or chip architecture to which element applies; no
- default -->
-
-<!ENTITY % arch.attrib
- "arch CDATA #IMPLIED">
-
-<!-- Condition: General-purpose effectivity attribute -->
-
-<!ENTITY % condition.attrib
- "condition CDATA #IMPLIED">
-
-<!-- Conformance: Standards conformance characteristics -->
-
-<!ENTITY % conformance.attrib
- "conformance NMTOKENS #IMPLIED">
-
-
-<!-- OS: Operating system to which element applies; no default -->
-
-<!ENTITY % os.attrib
- "os CDATA #IMPLIED">
-
-
-<!-- Revision: Editorial revision to which element belongs; no default -->
-
-<!ENTITY % revision.attrib
- "revision CDATA #IMPLIED">
-
-<!-- Security: Security classification; no default -->
-
-<!ENTITY % security.attrib
- "security CDATA #IMPLIED">
-
-<!-- UserLevel: Level of user experience to which element applies; no
- default -->
-
-<!ENTITY % userlevel.attrib
- "userlevel CDATA #IMPLIED">
-
-<!-- Vendor: Computer vendor to which element applies; no default -->
-
-<!ENTITY % vendor.attrib
- "vendor CDATA #IMPLIED">
-
-<!-- Wordsize: Computer word size (32 bit, 64 bit, etc.); no default -->
-
-<!ENTITY % wordsize.attrib
- "wordsize CDATA #IMPLIED">
-
-<!ENTITY % local.effectivity.attrib "">
-<!ENTITY % effectivity.attrib
- "%arch.attrib;
- %condition.attrib;
- %conformance.attrib;
- %os.attrib;
- %revision.attrib;
- %security.attrib;
- %userlevel.attrib;
- %vendor.attrib;
- %wordsize.attrib;
- %local.effectivity.attrib;"
->
-
-<!-- Common attributes .................................................... -->
-
-
-<!-- Id: Unique identifier of element; no default -->
-
-<!ENTITY % id.attrib
- "id ID #IMPLIED">
-
-
-<!-- Id: Unique identifier of element; a value must be supplied; no
- default -->
-
-<!ENTITY % idreq.attrib
- "id ID #REQUIRED">
-
-
-<!-- Lang: Indicator of language in which element is written, for
- translation, character set management, etc.; no default -->
-
-<!ENTITY % lang.attrib
- "lang CDATA #IMPLIED">
-
-
-<!-- Remap: Previous role of element before conversion; no default -->
-
-<!ENTITY % remap.attrib
- "remap CDATA #IMPLIED">
-
-
-<!-- Role: New role of element in local environment; no default -->
-
-<!ENTITY % role.attrib
- "role CDATA #IMPLIED">
-
-
-<!-- XRefLabel: Alternate labeling string for XRef text generation;
- default is usually title or other appropriate label text already
- contained in element -->
-
-<!ENTITY % xreflabel.attrib
- "xreflabel CDATA #IMPLIED">
-
-
-<!-- RevisionFlag: Revision status of element; default is that element
- wasn't revised -->
-
-<!ENTITY % revisionflag.attrib
- "revisionflag (changed
- |added
- |deleted
- |off) #IMPLIED">
-
-<!ENTITY % local.common.attrib "">
-
-<!-- dir: Bidirectional override -->
-
-<!ENTITY % dir.attrib
- "dir (ltr
- |rtl
- |lro
- |rlo) #IMPLIED">
-
-<!-- xml:base: base URI -->
-
-<![%sgml.features;[
-<!ENTITY % xml-base.attrib "">
-]]>
-<!ENTITY % xml-base.attrib
- "xml:base CDATA #IMPLIED">
-
-<!-- Role is included explicitly on each element -->
-
-<!ENTITY % common.attrib
- "%id.attrib;
- %lang.attrib;
- %remap.attrib;
- %xreflabel.attrib;
- %revisionflag.attrib;
- %effectivity.attrib;
- %dir.attrib;
- %xml-base.attrib;
- %local.common.attrib;"
->
-
-<!-- Role is included explicitly on each element -->
-
-<!ENTITY % idreq.common.attrib
- "%idreq.attrib;
- %lang.attrib;
- %remap.attrib;
- %xreflabel.attrib;
- %revisionflag.attrib;
- %effectivity.attrib;
- %dir.attrib;
- %xml-base.attrib;
- %local.common.attrib;"
->
-
-<!-- Semi-common attributes and other attribute entities .................. -->
-
-<!ENTITY % local.graphics.attrib "">
-
-<!-- EntityRef: Name of an external entity containing the content
- of the graphic -->
-<!-- FileRef: Filename, qualified by a pathname if desired,
- designating the file containing the content of the graphic -->
-<!-- Format: Notation of the element content, if any -->
-<!-- SrcCredit: Information about the source of the Graphic -->
-<!-- Width: Same as CALS reprowid (desired width) -->
-<!-- Depth: Same as CALS reprodep (desired depth) -->
-<!-- Align: Same as CALS hplace with 'none' removed; #IMPLIED means
- application-specific -->
-<!-- Scale: Conflation of CALS hscale and vscale -->
-<!-- Scalefit: Same as CALS scalefit -->
-
-<!ENTITY % graphics.attrib
- "
- entityref ENTITY #IMPLIED
- fileref CDATA #IMPLIED
- format (%notation.class;) #IMPLIED
- srccredit CDATA #IMPLIED
- width CDATA #IMPLIED
- contentwidth CDATA #IMPLIED
- depth CDATA #IMPLIED
- contentdepth CDATA #IMPLIED
- align (left
- |right
- |center) #IMPLIED
- valign (top
- |middle
- |bottom) #IMPLIED
- scale CDATA #IMPLIED
- scalefit %yesorno.attvals;
- #IMPLIED
- %local.graphics.attrib;"
->
-
-<!ENTITY % local.keyaction.attrib "">
-
-<!-- Action: Key combination type; default is unspecified if one
- child element, Simul if there is more than one; if value is
- Other, the OtherAction attribute must have a nonempty value -->
-<!-- OtherAction: User-defined key combination type -->
-
-<!ENTITY % keyaction.attrib
- "
- action (click
- |double-click
- |press
- |seq
- |simul
- |other) #IMPLIED
- otheraction CDATA #IMPLIED
- %local.keyaction.attrib;"
->
-
-
-<!-- Label: Identifying number or string; default is usually the
- appropriate number or string autogenerated by a formatter -->
-
-<!ENTITY % label.attrib
- "label CDATA #IMPLIED">
-
-
-<!-- xml:space: whitespace treatment -->
-
-<![%sgml.features;[
-<!ENTITY % xml-space.attrib "">
-]]>
-<!ENTITY % xml-space.attrib
- "xml:space (preserve) #IMPLIED">
-
-<!-- Format: whether element is assumed to contain significant white
- space -->
-
-<!ENTITY % linespecific.attrib
- "format NOTATION
- (linespecific) 'linespecific'
- %xml-space.attrib;
- linenumbering (numbered|unnumbered) #IMPLIED
- continuation (continues|restarts) #IMPLIED
- startinglinenumber CDATA #IMPLIED
- language CDATA #IMPLIED">
-
-<!-- Linkend: link to related information; no default -->
-
-<!ENTITY % linkend.attrib
- "linkend IDREF #IMPLIED">
-
-
-<!-- Linkend: required link to related information -->
-
-<!ENTITY % linkendreq.attrib
- "linkend IDREF #REQUIRED">
-
-
-<!-- Linkends: link to one or more sets of related information; no
- default -->
-
-<!ENTITY % linkends.attrib
- "linkends IDREFS #IMPLIED">
-
-
-<!ENTITY % local.mark.attrib "">
-<!ENTITY % mark.attrib
- "mark CDATA #IMPLIED
- %local.mark.attrib;"
->
-
-
-<!-- MoreInfo: whether element's content has an associated RefEntry -->
-
-<!ENTITY % moreinfo.attrib
- "moreinfo (refentry|none) 'none'">
-
-
-<!-- Pagenum: number of page on which element appears; no default -->
-
-<!ENTITY % pagenum.attrib
- "pagenum CDATA #IMPLIED">
-
-<!ENTITY % local.status.attrib "">
-
-<!-- Status: Editorial or publication status of the element
- it applies to, such as "in review" or "approved for distribution" -->
-
-<!ENTITY % status.attrib
- "status CDATA #IMPLIED
- %local.status.attrib;"
->
-
-
-<!-- Width: width of the longest line in the element to which it
- pertains, in number of characters -->
-
-<!ENTITY % width.attrib
- "width CDATA #IMPLIED">
-
-<!-- ...................................................................... -->
-<!-- Title elements ....................................................... -->
-
-<!ENTITY % title.module "INCLUDE">
-<![%title.module;[
-<!ENTITY % local.title.attrib "">
-<!ENTITY % title.role.attrib "%role.attrib;">
-
-<!ENTITY % title.element "INCLUDE">
-<![%title.element;[
-<!--doc:The text of the title of a section of a document or of a formal block-level element.-->
-<!ELEMENT title %ho; (%title.char.mix;)*>
-<!--end of title.element-->]]>
-
-<!ENTITY % title.attlist "INCLUDE">
-<![%title.attlist;[
-<!ATTLIST title
- %pagenum.attrib;
- %common.attrib;
- %title.role.attrib;
- %local.title.attrib;
->
-<!--end of title.attlist-->]]>
-<!--end of title.module-->]]>
-
-<!ENTITY % titleabbrev.module "INCLUDE">
-<![%titleabbrev.module;[
-<!ENTITY % local.titleabbrev.attrib "">
-<!ENTITY % titleabbrev.role.attrib "%role.attrib;">
-
-<!ENTITY % titleabbrev.element "INCLUDE">
-<![%titleabbrev.element;[
-<!--doc:The abbreviation of a Title.-->
-<!ELEMENT titleabbrev %ho; (%title.char.mix;)*>
-<!--end of titleabbrev.element-->]]>
-
-<!ENTITY % titleabbrev.attlist "INCLUDE">
-<![%titleabbrev.attlist;[
-<!ATTLIST titleabbrev
- %common.attrib;
- %titleabbrev.role.attrib;
- %local.titleabbrev.attrib;
->
-<!--end of titleabbrev.attlist-->]]>
-<!--end of titleabbrev.module-->]]>
-
-<!ENTITY % subtitle.module "INCLUDE">
-<![%subtitle.module;[
-<!ENTITY % local.subtitle.attrib "">
-<!ENTITY % subtitle.role.attrib "%role.attrib;">
-
-<!ENTITY % subtitle.element "INCLUDE">
-<![%subtitle.element;[
-<!--doc:The subtitle of a document.-->
-<!ELEMENT subtitle %ho; (%title.char.mix;)*>
-<!--end of subtitle.element-->]]>
-
-<!ENTITY % subtitle.attlist "INCLUDE">
-<![%subtitle.attlist;[
-<!ATTLIST subtitle
- %common.attrib;
- %subtitle.role.attrib;
- %local.subtitle.attrib;
->
-<!--end of subtitle.attlist-->]]>
-<!--end of subtitle.module-->]]>
-
-<!-- ...................................................................... -->
-<!-- Bibliographic entities and elements .................................. -->
-
-<!-- The bibliographic elements are typically used in the document
- hierarchy. They do not appear in content models of information
- pool elements. See also the document information elements,
- below. -->
-
-<!ENTITY % local.person.ident.mix "">
-<!ENTITY % person.ident.mix
- "honorific|firstname|surname|lineage|othername|affiliation
- |authorblurb|contrib %local.person.ident.mix;">
-
-<!ENTITY % local.bibliocomponent.mix "">
-<!ENTITY % bibliocomponent.mix
- "abbrev|abstract|address|artpagenums|author
- |authorgroup|authorinitials|bibliomisc|biblioset
- |collab|confgroup|contractnum|contractsponsor
- |copyright|corpauthor|corpname|corpcredit|date|edition
- |editor|invpartnumber|isbn|issn|issuenum|orgname
- |biblioid|citebiblioid|bibliosource|bibliorelation|bibliocoverage
- |othercredit|pagenums|printhistory|productname
- |productnumber|pubdate|publisher|publishername
- |pubsnumber|releaseinfo|revhistory|seriesvolnums
- |subtitle|title|titleabbrev|volumenum|citetitle
- |personname|%person.ident.mix;
- |%ndxterm.class;
- %local.bibliocomponent.mix;">
-
-<!-- I don't think this is well placed, but it needs to be here because of -->
-<!-- the reference to bibliocomponent.mix -->
-<!ENTITY % local.info.class "">
-<!ENTITY % info.class
- "graphic | mediaobject | legalnotice | modespec
- | subjectset | keywordset | itermset | %bibliocomponent.mix;
- %local.info.class;">
-
-
-<!-- BiblioList ........................ -->
-
-<!ENTITY % bibliolist.module "INCLUDE">
-<![%bibliolist.module;[
-<!ENTITY % local.bibliolist.attrib "">
-<!ENTITY % bibliolist.role.attrib "%role.attrib;">
-
-<!ENTITY % bibliolist.element "INCLUDE">
-<![%bibliolist.element;[
-<!--doc:A wrapper for a set of bibliography entries.-->
-<!ELEMENT bibliolist %ho; (blockinfo?, (%formalobject.title.content;)?,
- (biblioentry|bibliomixed)+)>
-<!--end of bibliolist.element-->]]>
-
-<!ENTITY % bibliolist.attlist "INCLUDE">
-<![%bibliolist.attlist;[
-<!ATTLIST bibliolist
- %common.attrib;
- %bibliolist.role.attrib;
- %local.bibliolist.attrib;
->
-<!--end of bibliolist.attlist-->]]>
-<!--end of bibliolist.module-->]]>
-
-<!ENTITY % biblioentry.module "INCLUDE">
-<![%biblioentry.module;[
-<!ENTITY % local.biblioentry.attrib "">
-<!ENTITY % biblioentry.role.attrib "%role.attrib;">
-
-<!ENTITY % biblioentry.element "INCLUDE">
-<![%biblioentry.element;[
-<!--doc:An entry in a Bibliography.-->
-<!ELEMENT biblioentry %ho; ((articleinfo | (%bibliocomponent.mix;))+)
- %ubiq.exclusion;>
-<!--end of biblioentry.element-->]]>
-
-<!ENTITY % biblioentry.attlist "INCLUDE">
-<![%biblioentry.attlist;[
-<!ATTLIST biblioentry
- %common.attrib;
- %biblioentry.role.attrib;
- %local.biblioentry.attrib;
->
-<!--end of biblioentry.attlist-->]]>
-<!--end of biblioentry.module-->]]>
-
-<!ENTITY % bibliomixed.module "INCLUDE">
-<![%bibliomixed.module;[
-<!ENTITY % local.bibliomixed.attrib "">
-<!ENTITY % bibliomixed.role.attrib "%role.attrib;">
-
-<!ENTITY % bibliomixed.element "INCLUDE">
-<![%bibliomixed.element;[
-<!--doc:An entry in a Bibliography.-->
-<!ELEMENT bibliomixed %ho; (#PCDATA | %bibliocomponent.mix; | bibliomset)*
- %ubiq.exclusion;>
-<!--end of bibliomixed.element-->]]>
-
-<!ENTITY % bibliomixed.attlist "INCLUDE">
-<![%bibliomixed.attlist;[
-<!ATTLIST bibliomixed
- %common.attrib;
- %bibliomixed.role.attrib;
- %local.bibliomixed.attrib;
->
-<!--end of bibliomixed.attlist-->]]>
-<!--end of bibliomixed.module-->]]>
-
-<!ENTITY % articleinfo.module "INCLUDE">
-<![%articleinfo.module;[
-<!ENTITY % local.articleinfo.attrib "">
-<!ENTITY % articleinfo.role.attrib "%role.attrib;">
-
-<!ENTITY % articleinfo.element "INCLUDE">
-<![%articleinfo.element;[
-<!--doc:Meta-information for an Article.-->
-<!ELEMENT articleinfo %ho; ((%info.class;)+)
- %beginpage.exclusion;>
-<!--end of articleinfo.element-->]]>
-
-<!ENTITY % articleinfo.attlist "INCLUDE">
-<![%articleinfo.attlist;[
-<!ATTLIST articleinfo
- %common.attrib;
- %articleinfo.role.attrib;
- %local.articleinfo.attrib;
->
-<!--end of articleinfo.attlist-->]]>
-<!--end of articleinfo.module-->]]>
-
-<!ENTITY % biblioset.module "INCLUDE">
-<![%biblioset.module;[
-<!ENTITY % local.biblioset.attrib "">
-<!ENTITY % biblioset.role.attrib "%role.attrib;">
-
-<!ENTITY % biblioset.element "INCLUDE">
-<![%biblioset.element;[
-<!--doc:A "raw" container for related bibliographic information.-->
-<!ELEMENT biblioset %ho; ((%bibliocomponent.mix;)+)
- %ubiq.exclusion;>
-<!--end of biblioset.element-->]]>
-
-<!-- Relation: Relationship of elements contained within BiblioSet -->
-
-
-<!ENTITY % biblioset.attlist "INCLUDE">
-<![%biblioset.attlist;[
-<!ATTLIST biblioset
- relation CDATA #IMPLIED
- %common.attrib;
- %biblioset.role.attrib;
- %local.biblioset.attrib;
->
-<!--end of biblioset.attlist-->]]>
-<!--end of biblioset.module-->]]>
-
-<!ENTITY % bibliomset.module "INCLUDE">
-<![%bibliomset.module;[
-<!ENTITY % bibliomset.role.attrib "%role.attrib;">
-<!ENTITY % local.bibliomset.attrib "">
-
-<!ENTITY % bibliomset.element "INCLUDE">
-<![%bibliomset.element;[
-<!--doc:A "cooked" container for related bibliographic information.-->
-<!ELEMENT bibliomset %ho; (#PCDATA | %bibliocomponent.mix; | bibliomset)*
- %ubiq.exclusion;>
-<!--end of bibliomset.element-->]]>
-
-<!-- Relation: Relationship of elements contained within BiblioMSet -->
-
-
-<!ENTITY % bibliomset.attlist "INCLUDE">
-<![%bibliomset.attlist;[
-<!ATTLIST bibliomset
- relation CDATA #IMPLIED
- %common.attrib;
- %bibliomset.role.attrib;
- %local.bibliomset.attrib;
->
-<!--end of bibliomset.attlist-->]]>
-<!--end of bibliomset.module-->]]>
-
-<!ENTITY % bibliomisc.module "INCLUDE">
-<![%bibliomisc.module;[
-<!ENTITY % local.bibliomisc.attrib "">
-<!ENTITY % bibliomisc.role.attrib "%role.attrib;">
-
-<!ENTITY % bibliomisc.element "INCLUDE">
-<![%bibliomisc.element;[
-<!--doc:Untyped bibliographic information.-->
-<!ELEMENT bibliomisc %ho; (%para.char.mix;)*>
-<!--end of bibliomisc.element-->]]>
-
-<!ENTITY % bibliomisc.attlist "INCLUDE">
-<![%bibliomisc.attlist;[
-<!ATTLIST bibliomisc
- %common.attrib;
- %bibliomisc.role.attrib;
- %local.bibliomisc.attrib;
->
-<!--end of bibliomisc.attlist-->]]>
-<!--end of bibliomisc.module-->]]>
-
-<!-- ...................................................................... -->
-<!-- Subject, Keyword, and ITermSet elements .............................. -->
-
-<!ENTITY % subjectset.content.module "INCLUDE">
-<![%subjectset.content.module;[
-<!ENTITY % subjectset.module "INCLUDE">
-<![%subjectset.module;[
-<!ENTITY % local.subjectset.attrib "">
-<!ENTITY % subjectset.role.attrib "%role.attrib;">
-
-<!ENTITY % subjectset.element "INCLUDE">
-<![%subjectset.element;[
-<!--doc:A set of terms describing the subject matter of a document.-->
-<!ELEMENT subjectset %ho; (subject+)>
-<!--end of subjectset.element-->]]>
-
-<!-- Scheme: Controlled vocabulary employed in SubjectTerms -->
-
-
-<!ENTITY % subjectset.attlist "INCLUDE">
-<![%subjectset.attlist;[
-<!ATTLIST subjectset
- scheme NMTOKEN #IMPLIED
- %common.attrib;
- %subjectset.role.attrib;
- %local.subjectset.attrib;
->
-<!--end of subjectset.attlist-->]]>
-<!--end of subjectset.module-->]]>
-
-<!ENTITY % subject.module "INCLUDE">
-<![%subject.module;[
-<!ENTITY % local.subject.attrib "">
-<!ENTITY % subject.role.attrib "%role.attrib;">
-
-<!ENTITY % subject.element "INCLUDE">
-<![%subject.element;[
-<!--doc:One of a group of terms describing the subject matter of a document.-->
-<!ELEMENT subject %ho; (subjectterm+)>
-<!--end of subject.element-->]]>
-
-<!-- Weight: Ranking of this group of SubjectTerms relative
- to others, 0 is low, no highest value specified -->
-
-
-<!ENTITY % subject.attlist "INCLUDE">
-<![%subject.attlist;[
-<!ATTLIST subject
- weight CDATA #IMPLIED
- %common.attrib;
- %subject.role.attrib;
- %local.subject.attrib;
->
-<!--end of subject.attlist-->]]>
-<!--end of subject.module-->]]>
-
-<!ENTITY % subjectterm.module "INCLUDE">
-<![%subjectterm.module;[
-<!ENTITY % local.subjectterm.attrib "">
-<!ENTITY % subjectterm.role.attrib "%role.attrib;">
-
-<!ENTITY % subjectterm.element "INCLUDE">
-<![%subjectterm.element;[
-<!--doc:A term in a group of terms describing the subject matter of a document.-->
-<!ELEMENT subjectterm %ho; (#PCDATA)>
-<!--end of subjectterm.element-->]]>
-
-<!ENTITY % subjectterm.attlist "INCLUDE">
-<![%subjectterm.attlist;[
-<!ATTLIST subjectterm
- %common.attrib;
- %subjectterm.role.attrib;
- %local.subjectterm.attrib;
->
-<!--end of subjectterm.attlist-->]]>
-<!--end of subjectterm.module-->]]>
-<!--end of subjectset.content.module-->]]>
-
-<!ENTITY % keywordset.content.module "INCLUDE">
-<![%keywordset.content.module;[
-<!ENTITY % keywordset.module "INCLUDE">
-<![%keywordset.module;[
-<!ENTITY % local.keywordset.attrib "">
-<!ENTITY % keywordset.role.attrib "%role.attrib;">
-
-<!ENTITY % keywordset.element "INCLUDE">
-<![%keywordset.element;[
-<!--doc:A set of keywords describing the content of a document.-->
-<!ELEMENT keywordset %ho; (keyword+)>
-<!--end of keywordset.element-->]]>
-
-<!ENTITY % keywordset.attlist "INCLUDE">
-<![%keywordset.attlist;[
-<!ATTLIST keywordset
- %common.attrib;
- %keywordset.role.attrib;
- %local.keywordset.attrib;
->
-<!--end of keywordset.attlist-->]]>
-<!--end of keywordset.module-->]]>
-
-<!ENTITY % keyword.module "INCLUDE">
-<![%keyword.module;[
-<!ENTITY % local.keyword.attrib "">
-<!ENTITY % keyword.role.attrib "%role.attrib;">
-
-<!ENTITY % keyword.element "INCLUDE">
-<![%keyword.element;[
-<!--doc:One of a set of keywords describing the content of a document.-->
-<!ELEMENT keyword %ho; (#PCDATA)>
-<!--end of keyword.element-->]]>
-
-<!ENTITY % keyword.attlist "INCLUDE">
-<![%keyword.attlist;[
-<!ATTLIST keyword
- %common.attrib;
- %keyword.role.attrib;
- %local.keyword.attrib;
->
-<!--end of keyword.attlist-->]]>
-<!--end of keyword.module-->]]>
-<!--end of keywordset.content.module-->]]>
-
-<!ENTITY % itermset.module "INCLUDE">
-<![%itermset.module;[
-<!ENTITY % local.itermset.attrib "">
-<!ENTITY % itermset.role.attrib "%role.attrib;">
-
-<!ENTITY % itermset.element "INCLUDE">
-<![%itermset.element;[
-<!--doc:A set of index terms in the meta-information of a document.-->
-<!ELEMENT itermset %ho; (indexterm+)>
-<!--end of itermset.element-->]]>
-
-<!ENTITY % itermset.attlist "INCLUDE">
-<![%itermset.attlist;[
-<!ATTLIST itermset
- %common.attrib;
- %itermset.role.attrib;
- %local.itermset.attrib;
->
-<!--end of itermset.attlist-->]]>
-<!--end of itermset.module-->]]>
-
-<!-- Bibliographic info for "blocks" -->
-
-<!ENTITY % blockinfo.module "INCLUDE">
-<![ %blockinfo.module; [
-<!ENTITY % local.blockinfo.attrib "">
-<!ENTITY % blockinfo.role.attrib "%role.attrib;">
-
-<!ENTITY % blockinfo.element "INCLUDE">
-<![ %blockinfo.element; [
-<!--doc:Meta-information for a block element.-->
-<!ELEMENT blockinfo %ho; ((%info.class;)+)
- %beginpage.exclusion;>
-<!--end of blockinfo.element-->]]>
-
-<!ENTITY % blockinfo.attlist "INCLUDE">
-<![ %blockinfo.attlist; [
-<!ATTLIST blockinfo
- %common.attrib;
- %blockinfo.role.attrib;
- %local.blockinfo.attrib;
->
-<!--end of blockinfo.attlist-->]]>
-<!--end of blockinfo.module-->]]>
-
-<!-- ...................................................................... -->
-<!-- Compound (section-ish) elements ...................................... -->
-
-<!-- Message set ...................... -->
-
-<!ENTITY % msgset.content.module "INCLUDE">
-<![%msgset.content.module;[
-<!ENTITY % msgset.module "INCLUDE">
-<![%msgset.module;[
-<!ENTITY % local.msgset.attrib "">
-<!ENTITY % msgset.role.attrib "%role.attrib;">
-
-<!ENTITY % msgset.element "INCLUDE">
-<![%msgset.element;[
-<!--doc:A detailed set of messages, usually error messages.-->
-<!ELEMENT msgset %ho; (blockinfo?, (%formalobject.title.content;)?,
- (msgentry+|simplemsgentry+))>
-<!--end of msgset.element-->]]>
-
-<!ENTITY % msgset.attlist "INCLUDE">
-<![%msgset.attlist;[
-<!ATTLIST msgset
- %common.attrib;
- %msgset.role.attrib;
- %local.msgset.attrib;
->
-<!--end of msgset.attlist-->]]>
-<!--end of msgset.module-->]]>
-
-<!ENTITY % msgentry.module "INCLUDE">
-<![%msgentry.module;[
-<!ENTITY % local.msgentry.attrib "">
-<!ENTITY % msgentry.role.attrib "%role.attrib;">
-
-<!ENTITY % msgentry.element "INCLUDE">
-<![%msgentry.element;[
-<!--doc:A wrapper for an entry in a message set.-->
-<!ELEMENT msgentry %ho; (msg+, msginfo?, msgexplan*)>
-<!--end of msgentry.element-->]]>
-
-<!ENTITY % msgentry.attlist "INCLUDE">
-<![%msgentry.attlist;[
-<!ATTLIST msgentry
- %common.attrib;
- %msgentry.role.attrib;
- %local.msgentry.attrib;
->
-<!--end of msgentry.attlist-->]]>
-<!--end of msgentry.module-->]]>
-
-<!ENTITY % simplemsgentry.module "INCLUDE">
-<![ %simplemsgentry.module; [
-<!ENTITY % local.simplemsgentry.attrib "">
-<!ENTITY % simplemsgentry.role.attrib "%role.attrib;">
-
-<!ENTITY % simplemsgentry.element "INCLUDE">
-<![ %simplemsgentry.element; [
-<!--doc:A wrapper for a simpler entry in a message set.-->
-<!ELEMENT simplemsgentry %ho; (msgtext, msgexplan+)>
-<!--end of simplemsgentry.element-->]]>
-
-<!ENTITY % simplemsgentry.attlist "INCLUDE">
-<![ %simplemsgentry.attlist; [
-<!ATTLIST simplemsgentry
- audience CDATA #IMPLIED
- level CDATA #IMPLIED
- origin CDATA #IMPLIED
- %common.attrib;
- %simplemsgentry.role.attrib;
- %local.simplemsgentry.attrib;
->
-<!--end of simplemsgentry.attlist-->]]>
-<!--end of simplemsgentry.module-->]]>
-
-<!ENTITY % msg.module "INCLUDE">
-<![%msg.module;[
-<!ENTITY % local.msg.attrib "">
-<!ENTITY % msg.role.attrib "%role.attrib;">
-
-<!ENTITY % msg.element "INCLUDE">
-<![%msg.element;[
-<!--doc:A message in a message set.-->
-<!ELEMENT msg %ho; (title?, msgmain, (msgsub | msgrel)*)>
-<!--end of msg.element-->]]>
-
-<!ENTITY % msg.attlist "INCLUDE">
-<![%msg.attlist;[
-<!ATTLIST msg
- %common.attrib;
- %msg.role.attrib;
- %local.msg.attrib;
->
-<!--end of msg.attlist-->]]>
-<!--end of msg.module-->]]>
-
-<!ENTITY % msgmain.module "INCLUDE">
-<![%msgmain.module;[
-<!ENTITY % local.msgmain.attrib "">
-<!ENTITY % msgmain.role.attrib "%role.attrib;">
-
-<!ENTITY % msgmain.element "INCLUDE">
-<![%msgmain.element;[
-<!--doc:The primary component of a message in a message set.-->
-<!ELEMENT msgmain %ho; (title?, msgtext)>
-<!--end of msgmain.element-->]]>
-
-<!ENTITY % msgmain.attlist "INCLUDE">
-<![%msgmain.attlist;[
-<!ATTLIST msgmain
- %common.attrib;
- %msgmain.role.attrib;
- %local.msgmain.attrib;
->
-<!--end of msgmain.attlist-->]]>
-<!--end of msgmain.module-->]]>
-
-<!ENTITY % msgsub.module "INCLUDE">
-<![%msgsub.module;[
-<!ENTITY % local.msgsub.attrib "">
-<!ENTITY % msgsub.role.attrib "%role.attrib;">
-
-<!ENTITY % msgsub.element "INCLUDE">
-<![%msgsub.element;[
-<!--doc:A subcomponent of a message in a message set.-->
-<!ELEMENT msgsub %ho; (title?, msgtext)>
-<!--end of msgsub.element-->]]>
-
-<!ENTITY % msgsub.attlist "INCLUDE">
-<![%msgsub.attlist;[
-<!ATTLIST msgsub
- %common.attrib;
- %msgsub.role.attrib;
- %local.msgsub.attrib;
->
-<!--end of msgsub.attlist-->]]>
-<!--end of msgsub.module-->]]>
-
-<!ENTITY % msgrel.module "INCLUDE">
-<![%msgrel.module;[
-<!ENTITY % local.msgrel.attrib "">
-<!ENTITY % msgrel.role.attrib "%role.attrib;">
-
-<!ENTITY % msgrel.element "INCLUDE">
-<![%msgrel.element;[
-<!--doc:A related component of a message in a message set.-->
-<!ELEMENT msgrel %ho; (title?, msgtext)>
-<!--end of msgrel.element-->]]>
-
-<!ENTITY % msgrel.attlist "INCLUDE">
-<![%msgrel.attlist;[
-<!ATTLIST msgrel
- %common.attrib;
- %msgrel.role.attrib;
- %local.msgrel.attrib;
->
-<!--end of msgrel.attlist-->]]>
-<!--end of msgrel.module-->]]>
-
-<!-- MsgText (defined in the Inlines section, below)-->
-
-<!ENTITY % msginfo.module "INCLUDE">
-<![%msginfo.module;[
-<!ENTITY % local.msginfo.attrib "">
-<!ENTITY % msginfo.role.attrib "%role.attrib;">
-
-<!ENTITY % msginfo.element "INCLUDE">
-<![%msginfo.element;[
-<!--doc:Information about a message in a message set.-->
-<!ELEMENT msginfo %ho; ((msglevel | msgorig | msgaud)*)>
-<!--end of msginfo.element-->]]>
-
-<!ENTITY % msginfo.attlist "INCLUDE">
-<![%msginfo.attlist;[
-<!ATTLIST msginfo
- %common.attrib;
- %msginfo.role.attrib;
- %local.msginfo.attrib;
->
-<!--end of msginfo.attlist-->]]>
-<!--end of msginfo.module-->]]>
-
-<!ENTITY % msglevel.module "INCLUDE">
-<![%msglevel.module;[
-<!ENTITY % local.msglevel.attrib "">
-<!ENTITY % msglevel.role.attrib "%role.attrib;">
-
-<!ENTITY % msglevel.element "INCLUDE">
-<![%msglevel.element;[
-<!--doc:The level of importance or severity of a message in a message set.-->
-<!ELEMENT msglevel %ho; (%smallcptr.char.mix;)*>
-<!--end of msglevel.element-->]]>
-
-<!ENTITY % msglevel.attlist "INCLUDE">
-<![%msglevel.attlist;[
-<!ATTLIST msglevel
- %common.attrib;
- %msglevel.role.attrib;
- %local.msglevel.attrib;
->
-<!--end of msglevel.attlist-->]]>
-<!--end of msglevel.module-->]]>
-
-<!ENTITY % msgorig.module "INCLUDE">
-<![%msgorig.module;[
-<!ENTITY % local.msgorig.attrib "">
-<!ENTITY % msgorig.role.attrib "%role.attrib;">
-
-<!ENTITY % msgorig.element "INCLUDE">
-<![%msgorig.element;[
-<!--doc:The origin of a message in a message set.-->
-<!ELEMENT msgorig %ho; (%smallcptr.char.mix;)*>
-<!--end of msgorig.element-->]]>
-
-<!ENTITY % msgorig.attlist "INCLUDE">
-<![%msgorig.attlist;[
-<!ATTLIST msgorig
- %common.attrib;
- %msgorig.role.attrib;
- %local.msgorig.attrib;
->
-<!--end of msgorig.attlist-->]]>
-<!--end of msgorig.module-->]]>
-
-<!ENTITY % msgaud.module "INCLUDE">
-<![%msgaud.module;[
-<!ENTITY % local.msgaud.attrib "">
-<!ENTITY % msgaud.role.attrib "%role.attrib;">
-
-<!ENTITY % msgaud.element "INCLUDE">
-<![%msgaud.element;[
-<!--doc:The audience to which a message in a message set is relevant.-->
-<!ELEMENT msgaud %ho; (%para.char.mix;)*>
-<!--end of msgaud.element-->]]>
-
-<!ENTITY % msgaud.attlist "INCLUDE">
-<![%msgaud.attlist;[
-<!ATTLIST msgaud
- %common.attrib;
- %msgaud.role.attrib;
- %local.msgaud.attrib;
->
-<!--end of msgaud.attlist-->]]>
-<!--end of msgaud.module-->]]>
-
-<!ENTITY % msgexplan.module "INCLUDE">
-<![%msgexplan.module;[
-<!ENTITY % local.msgexplan.attrib "">
-<!ENTITY % msgexplan.role.attrib "%role.attrib;">
-
-<!ENTITY % msgexplan.element "INCLUDE">
-<![%msgexplan.element;[
-<!--doc:Explanatory material relating to a message in a message set.-->
-<!ELEMENT msgexplan %ho; (title?, (%component.mix;)+)>
-<!--end of msgexplan.element-->]]>
-
-<!ENTITY % msgexplan.attlist "INCLUDE">
-<![%msgexplan.attlist;[
-<!ATTLIST msgexplan
- %common.attrib;
- %msgexplan.role.attrib;
- %local.msgexplan.attrib;
->
-<!--end of msgexplan.attlist-->]]>
-<!--end of msgexplan.module-->]]>
-<!--end of msgset.content.module-->]]>
-
-<!ENTITY % task.content.module "INCLUDE">
-<![%task.content.module;[
-<!ENTITY % task.module "INCLUDE">
-<![%task.module;[
-<!ENTITY % local.task.attrib "">
-<!ENTITY % task.role.attrib "%role.attrib;">
-
-<!ENTITY % task.element "INCLUDE">
-<![%task.element;[
-<!--doc:A task to be completed.-->
-<!ELEMENT task %ho; (blockinfo?,(%ndxterm.class;)*,
- (%formalobject.title.content;),
- tasksummary?,
- taskprerequisites?,
- procedure,
- example*,
- taskrelated?)>
-<!--end of task.element-->]]>
-
-<!ENTITY % task.attlist "INCLUDE">
-<![%task.attlist;[
-<!ATTLIST task
- %common.attrib;
- %task.role.attrib;
- %local.task.attrib;
->
-<!--end of task.attlist-->]]>
-<!--end of task.module-->]]>
-
-<!ENTITY % tasksummary.module "INCLUDE">
-<![%tasksummary.module;[
-<!ENTITY % local.tasksummary.attrib "">
-<!ENTITY % tasksummary.role.attrib "%role.attrib;">
-
-<!ENTITY % tasksummary.element "INCLUDE">
-<![%tasksummary.element;[
-<!--doc:A summary of a task.-->
-<!ELEMENT tasksummary %ho; (blockinfo?,
- (%formalobject.title.content;)?,
- (%component.mix;)+)>
-<!--end of tasksummary.element-->]]>
-
-<!ENTITY % tasksummary.attlist "INCLUDE">
-<![%tasksummary.attlist;[
-<!ATTLIST tasksummary
- %common.attrib;
- %tasksummary.role.attrib;
- %local.tasksummary.attrib;
->
-<!--end of tasksummary.attlist-->]]>
-<!--end of tasksummary.module-->]]>
-
-<!ENTITY % taskprerequisites.module "INCLUDE">
-<![%taskprerequisites.module;[
-<!ENTITY % local.taskprerequisites.attrib "">
-<!ENTITY % taskprerequisites.role.attrib "%role.attrib;">
-
-<!ENTITY % taskprerequisites.element "INCLUDE">
-<![%taskprerequisites.element;[
-<!--doc:The prerequisites for a task.-->
-<!ELEMENT taskprerequisites %ho; (blockinfo?,
- (%formalobject.title.content;)?,
- (%component.mix;)+)>
-<!--end of taskprerequisites.element-->]]>
-
-<!ENTITY % taskprerequisites.attlist "INCLUDE">
-<![%taskprerequisites.attlist;[
-<!ATTLIST taskprerequisites
- %common.attrib;
- %taskprerequisites.role.attrib;
- %local.taskprerequisites.attrib;
->
-<!--end of taskprerequisites.attlist-->]]>
-<!--end of taskprerequisites.module-->]]>
-
-<!ENTITY % taskrelated.module "INCLUDE">
-<![%taskrelated.module;[
-<!ENTITY % local.taskrelated.attrib "">
-<!ENTITY % taskrelated.role.attrib "%role.attrib;">
-
-<!ENTITY % taskrelated.element "INCLUDE">
-<![%taskrelated.element;[
-<!--doc:Information related to a task.-->
-<!ELEMENT taskrelated %ho; (blockinfo?,
- (%formalobject.title.content;)?,
- (%component.mix;)+)>
-<!--end of taskrelated.element-->]]>
-
-<!ENTITY % taskrelated.attlist "INCLUDE">
-<![%taskrelated.attlist;[
-<!ATTLIST taskrelated
- %common.attrib;
- %taskrelated.role.attrib;
- %local.taskrelated.attrib;
->
-<!--end of taskrelated.attlist-->]]>
-<!--end of taskrelated.module-->]]>
-<!--end of task.content.module-->]]>
-
-<!-- QandASet ........................ -->
-<!ENTITY % qandaset.content.module "INCLUDE">
-<![ %qandaset.content.module; [
-<!ENTITY % qandaset.module "INCLUDE">
-<![ %qandaset.module; [
-<!ENTITY % local.qandaset.attrib "">
-<!ENTITY % qandaset.role.attrib "%role.attrib;">
-
-<!ENTITY % qandaset.element "INCLUDE">
-<![ %qandaset.element; [
-<!--doc:A question-and-answer set.-->
-<!ELEMENT qandaset %ho; (blockinfo?, (%formalobject.title.content;)?,
- (%qandaset.mix;)*,
- (qandadiv+|qandaentry+))>
-<!--end of qandaset.element-->]]>
-
-<!ENTITY % qandaset.attlist "INCLUDE">
-<![ %qandaset.attlist; [
-<!ATTLIST qandaset
- defaultlabel (qanda|number|none) #IMPLIED
- %common.attrib;
- %qandaset.role.attrib;
- %local.qandaset.attrib;>
-<!--end of qandaset.attlist-->]]>
-<!--end of qandaset.module-->]]>
-
-<!ENTITY % qandadiv.module "INCLUDE">
-<![ %qandadiv.module; [
-<!ENTITY % local.qandadiv.attrib "">
-<!ENTITY % qandadiv.role.attrib "%role.attrib;">
-
-<!ENTITY % qandadiv.element "INCLUDE">
-<![ %qandadiv.element; [
-<!--doc:A titled division in a QandASet.-->
-<!ELEMENT qandadiv %ho; (blockinfo?, (%formalobject.title.content;)?,
- (%qandaset.mix;)*,
- (qandadiv+|qandaentry+))>
-<!--end of qandadiv.element-->]]>
-
-<!ENTITY % qandadiv.attlist "INCLUDE">
-<![ %qandadiv.attlist; [
-<!ATTLIST qandadiv
- %common.attrib;
- %qandadiv.role.attrib;
- %local.qandadiv.attrib;>
-<!--end of qandadiv.attlist-->]]>
-<!--end of qandadiv.module-->]]>
-
-<!ENTITY % qandaentry.module "INCLUDE">
-<![ %qandaentry.module; [
-<!ENTITY % local.qandaentry.attrib "">
-<!ENTITY % qandaentry.role.attrib "%role.attrib;">
-
-<!ENTITY % qandaentry.element "INCLUDE">
-<![ %qandaentry.element; [
-<!--doc:A question/answer set within a QandASet.-->
-<!ELEMENT qandaentry %ho; (blockinfo?, revhistory?, question, answer*)>
-<!--end of qandaentry.element-->]]>
-
-<!ENTITY % qandaentry.attlist "INCLUDE">
-<![ %qandaentry.attlist; [
-<!ATTLIST qandaentry
- %common.attrib;
- %qandaentry.role.attrib;
- %local.qandaentry.attrib;>
-<!--end of qandaentry.attlist-->]]>
-<!--end of qandaentry.module-->]]>
-
-<!ENTITY % question.module "INCLUDE">
-<![ %question.module; [
-<!ENTITY % local.question.attrib "">
-<!ENTITY % question.role.attrib "%role.attrib;">
-
-<!ENTITY % question.element "INCLUDE">
-<![ %question.element; [
-<!--doc:A question in a QandASet.-->
-<!ELEMENT question %ho; (label?, (%qandaset.mix;)+)>
-<!--end of question.element-->]]>
-
-<!ENTITY % question.attlist "INCLUDE">
-<![ %question.attlist; [
-<!ATTLIST question
- %common.attrib;
- %question.role.attrib;
- %local.question.attrib;
->
-<!--end of question.attlist-->]]>
-<!--end of question.module-->]]>
-
-<!ENTITY % answer.module "INCLUDE">
-<![ %answer.module; [
-<!ENTITY % local.answer.attrib "">
-<!ENTITY % answer.role.attrib "%role.attrib;">
-
-<!ENTITY % answer.element "INCLUDE">
-<![ %answer.element; [
-<!--doc:An answer to a question posed in a QandASet.-->
-<!ELEMENT answer %ho; (label?, (%qandaset.mix;)*, qandaentry*)>
-<!--end of answer.element-->]]>
-
-<!ENTITY % answer.attlist "INCLUDE">
-<![ %answer.attlist; [
-<!ATTLIST answer
- %common.attrib;
- %answer.role.attrib;
- %local.answer.attrib;
->
-<!--end of answer.attlist-->]]>
-<!--end of answer.module-->]]>
-
-<!ENTITY % label.module "INCLUDE">
-<![ %label.module; [
-<!ENTITY % local.label.attrib "">
-<!ENTITY % label.role.attrib "%role.attrib;">
-
-<!ENTITY % label.element "INCLUDE">
-<![ %label.element; [
-<!--doc:A label on a Question or Answer.-->
-<!ELEMENT label %ho; (%word.char.mix;)*>
-<!--end of label.element-->]]>
-
-<!ENTITY % label.attlist "INCLUDE">
-<![ %label.attlist; [
-<!ATTLIST label
- %common.attrib;
- %label.role.attrib;
- %local.label.attrib;
->
-<!--end of label.attlist-->]]>
-<!--end of label.module-->]]>
-<!--end of qandaset.content.module-->]]>
-
-<!-- Procedure ........................ -->
-
-<!ENTITY % procedure.content.module "INCLUDE">
-<![%procedure.content.module;[
-<!ENTITY % procedure.module "INCLUDE">
-<![%procedure.module;[
-<!ENTITY % local.procedure.attrib "">
-<!ENTITY % procedure.role.attrib "%role.attrib;">
-
-<!ENTITY % procedure.element "INCLUDE">
-<![%procedure.element;[
-<!--doc:A list of operations to be performed in a well-defined sequence.-->
-<!ELEMENT procedure %ho; (blockinfo?, (%formalobject.title.content;)?,
- (%component.mix;)*, step+)>
-<!--end of procedure.element-->]]>
-
-<!ENTITY % procedure.attlist "INCLUDE">
-<![%procedure.attlist;[
-<!ATTLIST procedure
- %common.attrib;
- %procedure.role.attrib;
- %local.procedure.attrib;
->
-<!--end of procedure.attlist-->]]>
-<!--end of procedure.module-->]]>
-
-<!ENTITY % step.module "INCLUDE">
-<![%step.module;[
-<!ENTITY % local.step.attrib "">
-<!ENTITY % step.role.attrib "%role.attrib;">
-
-<!ENTITY % step.element "INCLUDE">
-<![%step.element;[
-<!--doc:A unit of action in a procedure.-->
-<!ELEMENT step %ho; (title?, (((%component.mix;)+, ((substeps|stepalternatives), (%component.mix;)*)?)
- | ((substeps|stepalternatives), (%component.mix;)*)))>
-<!--end of step.element-->]]>
-
-<!-- Performance: Whether the Step must be performed -->
-<!-- not #REQUIRED! -->
-
-
-<!ENTITY % step.attlist "INCLUDE">
-<![%step.attlist;[
-<!ATTLIST step
- performance (optional
- |required) "required"
- %common.attrib;
- %step.role.attrib;
- %local.step.attrib;
->
-<!--end of step.attlist-->]]>
-<!--end of step.module-->]]>
-
-<!ENTITY % substeps.module "INCLUDE">
-<![%substeps.module;[
-<!ENTITY % local.substeps.attrib "">
-<!ENTITY % substeps.role.attrib "%role.attrib;">
-
-<!ENTITY % substeps.element "INCLUDE">
-<![%substeps.element;[
-<!--doc:A wrapper for steps that occur within steps in a procedure.-->
-<!ELEMENT substeps %ho; (step+)>
-<!--end of substeps.element-->]]>
-
-<!-- Performance: whether entire set of substeps must be performed -->
-<!-- not #REQUIRED! -->
-
-<!ENTITY % substeps.attlist "INCLUDE">
-<![%substeps.attlist;[
-<!ATTLIST substeps
- performance (optional
- |required) "required"
- %common.attrib;
- %substeps.role.attrib;
- %local.substeps.attrib;
->
-<!--end of substeps.attlist-->]]>
-<!--end of substeps.module-->]]>
-
-<!ENTITY % stepalternatives.module "INCLUDE">
-<![%stepalternatives.module;[
-<!ENTITY % local.stepalternatives.attrib "">
-<!ENTITY % stepalternatives.role.attrib "%role.attrib;">
-
-<!ENTITY % stepalternatives.element "INCLUDE">
-<![%stepalternatives.element;[
-<!--doc:Alternative steps in a procedure.-->
-<!ELEMENT stepalternatives %ho; (step+)>
-<!--end of stepalternatives.element-->]]>
-
-<!-- Performance: Whether (one of) the alternatives must be performed -->
-<!-- not #REQUIRED! -->
-
-<!ENTITY % stepalternatives.attlist "INCLUDE">
-<![%stepalternatives.attlist;[
-<!ATTLIST stepalternatives
- performance (optional
- |required) "required"
- %common.attrib;
- %stepalternatives.role.attrib;
- %local.stepalternatives.attrib;
->
-<!--end of stepalternatives.attlist-->]]>
-<!--end of stepalternatives.module-->]]>
-<!--end of procedure.content.module-->]]>
-
-<!-- Sidebar .......................... -->
-
-<!ENTITY % sidebar.content.model "INCLUDE">
-<![ %sidebar.content.model; [
-
-<!ENTITY % sidebarinfo.module "INCLUDE">
-<![ %sidebarinfo.module; [
-<!ENTITY % local.sidebarinfo.attrib "">
-<!ENTITY % sidebarinfo.role.attrib "%role.attrib;">
-
-<!ENTITY % sidebarinfo.element "INCLUDE">
-<![ %sidebarinfo.element; [
-<!--doc:Meta-information for a Sidebar.-->
-<!ELEMENT sidebarinfo %ho; ((%info.class;)+)
- %beginpage.exclusion;>
-<!--end of sidebarinfo.element-->]]>
-
-<!ENTITY % sidebarinfo.attlist "INCLUDE">
-<![ %sidebarinfo.attlist; [
-<!ATTLIST sidebarinfo
- %common.attrib;
- %sidebarinfo.role.attrib;
- %local.sidebarinfo.attrib;
->
-<!--end of sidebarinfo.attlist-->]]>
-<!--end of sidebarinfo.module-->]]>
-
-<!ENTITY % sidebar.module "INCLUDE">
-<![%sidebar.module;[
-<!ENTITY % local.sidebar.attrib "">
-<!ENTITY % sidebar.role.attrib "%role.attrib;">
-
-<!ENTITY % sidebar.element "INCLUDE">
-<![%sidebar.element;[
-<!--doc:A portion of a document that is isolated from the main narrative flow.-->
-<!ELEMENT sidebar %ho; (sidebarinfo?,
- (%formalobject.title.content;)?,
- (%sidebar.mix;)+)>
-<!--end of sidebar.element-->]]>
-
-<!ENTITY % sidebar.attlist "INCLUDE">
-<![%sidebar.attlist;[
-<!ATTLIST sidebar
- %common.attrib;
- %sidebar.role.attrib;
- %local.sidebar.attrib;
->
-<!--end of sidebar.attlist-->]]>
-<!--end of sidebar.module-->]]>
-<!--end of sidebar.content.model-->]]>
-
-<!-- ...................................................................... -->
-<!-- Paragraph-related elements ........................................... -->
-
-<!ENTITY % abstract.module "INCLUDE">
-<![%abstract.module;[
-<!ENTITY % local.abstract.attrib "">
-<!ENTITY % abstract.role.attrib "%role.attrib;">
-
-<!ENTITY % abstract.element "INCLUDE">
-<![%abstract.element;[
-<!--doc:A summary.-->
-<!ELEMENT abstract %ho; (title?, (%para.class;)+)>
-<!--end of abstract.element-->]]>
-
-<!ENTITY % abstract.attlist "INCLUDE">
-<![%abstract.attlist;[
-<!ATTLIST abstract
- %common.attrib;
- %abstract.role.attrib;
- %local.abstract.attrib;
->
-<!--end of abstract.attlist-->]]>
-<!--end of abstract.module-->]]>
-
-<!ENTITY % authorblurb.module "INCLUDE">
-<![%authorblurb.module;[
-<!ENTITY % local.authorblurb.attrib "">
-<!ENTITY % authorblurb.role.attrib "%role.attrib;">
-
-<!ENTITY % authorblurb.element "INCLUDE">
-<![%authorblurb.element;[
-<!--doc:A short description or note about an author.-->
-<!ELEMENT authorblurb %ho; (title?, (%para.class;)+)>
-<!--end of authorblurb.element-->]]>
-
-<!ENTITY % authorblurb.attlist "INCLUDE">
-<![%authorblurb.attlist;[
-<!ATTLIST authorblurb
- %common.attrib;
- %authorblurb.role.attrib;
- %local.authorblurb.attrib;
->
-<!--end of authorblurb.attlist-->]]>
-<!--end of authorblurb.module-->]]>
-
-<!ENTITY % personblurb.module "INCLUDE">
-<![%personblurb.module;[
-<!ENTITY % local.personblurb.attrib "">
-<!ENTITY % personblurb.role.attrib "%role.attrib;">
-
-<!ENTITY % personblurb.element "INCLUDE">
-<![%personblurb.element;[
-<!--doc:A short description or note about a person.-->
-<!ELEMENT personblurb %ho; (title?, (%para.class;)+)>
-<!--end of personblurb.element-->]]>
-
-<!ENTITY % personblurb.attlist "INCLUDE">
-<![%personblurb.attlist;[
-<!ATTLIST personblurb
- %common.attrib;
- %personblurb.role.attrib;
- %local.personblurb.attrib;
->
-<!--end of personblurb.attlist-->]]>
-<!--end of personblurb.module-->]]>
-
-<!ENTITY % blockquote.module "INCLUDE">
-<![%blockquote.module;[
-
-<!ENTITY % local.blockquote.attrib "">
-<!ENTITY % blockquote.role.attrib "%role.attrib;">
-
-<!ENTITY % blockquote.element "INCLUDE">
-<![%blockquote.element;[
-<!--doc:A quotation set off from the main text.-->
-<!ELEMENT blockquote %ho; (blockinfo?, title?, attribution?, (%component.mix;)+)
- %blockquote.exclusion;>
-<!--end of blockquote.element-->]]>
-
-<!ENTITY % blockquote.attlist "INCLUDE">
-<![%blockquote.attlist;[
-<!ATTLIST blockquote
- %common.attrib;
- %blockquote.role.attrib;
- %local.blockquote.attrib;
->
-<!--end of blockquote.attlist-->]]>
-<!--end of blockquote.module-->]]>
-
-<!ENTITY % attribution.module "INCLUDE">
-<![%attribution.module;[
-<!ENTITY % local.attribution.attrib "">
-<!ENTITY % attribution.role.attrib "%role.attrib;">
-
-<!ENTITY % attribution.element "INCLUDE">
-<![%attribution.element;[
-<!--doc:The source of a block quote or epigraph.-->
-<!ELEMENT attribution %ho; (%para.char.mix;)*>
-<!--end of attribution.element-->]]>
-
-<!ENTITY % attribution.attlist "INCLUDE">
-<![%attribution.attlist;[
-<!ATTLIST attribution
- %common.attrib;
- %attribution.role.attrib;
- %local.attribution.attrib;
->
-<!--end of attribution.attlist-->]]>
-<!--end of attribution.module-->]]>
-
-<!ENTITY % bridgehead.module "INCLUDE">
-<![%bridgehead.module;[
-<!ENTITY % local.bridgehead.attrib "">
-<!ENTITY % bridgehead.role.attrib "%role.attrib;">
-
-<!ENTITY % bridgehead.element "INCLUDE">
-<![%bridgehead.element;[
-<!--doc:A free-floating heading.-->
-<!ELEMENT bridgehead %ho; (%title.char.mix;)*>
-<!--end of bridgehead.element-->]]>
-
-<!-- Renderas: Indicates the format in which the BridgeHead
- should appear -->
-
-
-<!ENTITY % bridgehead.attlist "INCLUDE">
-<![%bridgehead.attlist;[
-<!ATTLIST bridgehead
- renderas (other
- |sect1
- |sect2
- |sect3
- |sect4
- |sect5) #IMPLIED
- %common.attrib;
- %bridgehead.role.attrib;
- %local.bridgehead.attrib;
->
-<!--end of bridgehead.attlist-->]]>
-<!--end of bridgehead.module-->]]>
-
-<!ENTITY % remark.module "INCLUDE">
-<![%remark.module;[
-<!ENTITY % local.remark.attrib "">
-<!ENTITY % remark.role.attrib "%role.attrib;">
-
-<!ENTITY % remark.element "INCLUDE">
-<![%remark.element;[
-<!--doc:A remark (or comment) intended for presentation in a draft manuscript.-->
-<!ELEMENT remark %ho; (%para.char.mix;)*
- %remark.exclusion;>
-<!--end of remark.element-->]]>
-
-<!ENTITY % remark.attlist "INCLUDE">
-<![%remark.attlist;[
-<!ATTLIST remark
- %common.attrib;
- %remark.role.attrib;
- %local.remark.attrib;
->
-<!--end of remark.attlist-->]]>
-<!--end of remark.module-->]]>
-
-<!ENTITY % epigraph.module "INCLUDE">
-<![%epigraph.module;[
-<!ENTITY % local.epigraph.attrib "">
-<!ENTITY % epigraph.role.attrib "%role.attrib;">
-
-<!ENTITY % epigraph.element "INCLUDE">
-<![%epigraph.element;[
-<!--doc:A short inscription at the beginning of a document or component.-->
-<!ELEMENT epigraph %ho; (attribution?, ((%para.class;)|literallayout)+)>
-<!--end of epigraph.element-->]]>
-
-<!ENTITY % epigraph.attlist "INCLUDE">
-<![%epigraph.attlist;[
-<!ATTLIST epigraph
- %common.attrib;
- %epigraph.role.attrib;
- %local.epigraph.attrib;
->
-<!--end of epigraph.attlist-->]]>
-<!-- Attribution (defined above)-->
-<!--end of epigraph.module-->]]>
-
-<!ENTITY % footnote.module "INCLUDE">
-<![%footnote.module;[
-<!ENTITY % local.footnote.attrib "">
-<!ENTITY % footnote.role.attrib "%role.attrib;">
-
-<!ENTITY % footnote.element "INCLUDE">
-<![%footnote.element;[
-<!--doc:A footnote.-->
-<!ELEMENT footnote %ho; ((%footnote.mix;)+)
- %footnote.exclusion;>
-<!--end of footnote.element-->]]>
-
-<!ENTITY % footnote.attlist "INCLUDE">
-<![%footnote.attlist;[
-<!ATTLIST footnote
- %label.attrib;
- %common.attrib;
- %footnote.role.attrib;
- %local.footnote.attrib;
->
-<!--end of footnote.attlist-->]]>
-<!--end of footnote.module-->]]>
-
-<!ENTITY % highlights.module "INCLUDE">
-<![%highlights.module;[
-<!ENTITY % local.highlights.attrib "">
-<!ENTITY % highlights.role.attrib "%role.attrib;">
-
-<!ENTITY % highlights.element "INCLUDE">
-<![%highlights.element;[
-<!--doc:A summary of the main points of the discussed component.-->
-<!ELEMENT highlights %ho; ((%highlights.mix;)+)
- %highlights.exclusion;>
-<!--end of highlights.element-->]]>
-
-<!ENTITY % highlights.attlist "INCLUDE">
-<![%highlights.attlist;[
-<!ATTLIST highlights
- %common.attrib;
- %highlights.role.attrib;
- %local.highlights.attrib;
->
-<!--end of highlights.attlist-->]]>
-<!--end of highlights.module-->]]>
-
-<!ENTITY % formalpara.module "INCLUDE">
-<![%formalpara.module;[
-<!ENTITY % local.formalpara.attrib "">
-<!ENTITY % formalpara.role.attrib "%role.attrib;">
-
-<!ENTITY % formalpara.element "INCLUDE">
-<![%formalpara.element;[
-<!--doc:A paragraph with a title.-->
-<!ELEMENT formalpara %ho; (title, (%ndxterm.class;)*, para)>
-<!--end of formalpara.element-->]]>
-
-<!ENTITY % formalpara.attlist "INCLUDE">
-<![%formalpara.attlist;[
-<!ATTLIST formalpara
- %common.attrib;
- %formalpara.role.attrib;
- %local.formalpara.attrib;
->
-<!--end of formalpara.attlist-->]]>
-<!--end of formalpara.module-->]]>
-
-<!ENTITY % para.module "INCLUDE">
-<![%para.module;[
-<!ENTITY % local.para.attrib "">
-<!ENTITY % para.role.attrib "%role.attrib;">
-
-<!ENTITY % para.element "INCLUDE">
-<![%para.element;[
-<!--doc:A paragraph.-->
-<!ELEMENT para %ho; (%para.char.mix; | %para.mix;)*>
-<!--end of para.element-->]]>
-
-<!ENTITY % para.attlist "INCLUDE">
-<![%para.attlist;[
-<!ATTLIST para
- %common.attrib;
- %para.role.attrib;
- %local.para.attrib;
->
-<!--end of para.attlist-->]]>
-<!--end of para.module-->]]>
-
-<!ENTITY % simpara.module "INCLUDE">
-<![%simpara.module;[
-<!ENTITY % local.simpara.attrib "">
-<!ENTITY % simpara.role.attrib "%role.attrib;">
-
-<!ENTITY % simpara.element "INCLUDE">
-<![%simpara.element;[
-<!--doc:A paragraph that contains only text and inline markup, no block elements.-->
-<!ELEMENT simpara %ho; (%para.char.mix;)*>
-<!--end of simpara.element-->]]>
-
-<!ENTITY % simpara.attlist "INCLUDE">
-<![%simpara.attlist;[
-<!ATTLIST simpara
- %common.attrib;
- %simpara.role.attrib;
- %local.simpara.attrib;
->
-<!--end of simpara.attlist-->]]>
-<!--end of simpara.module-->]]>
-
-<!ENTITY % admon.module "INCLUDE">
-<![%admon.module;[
-<!ENTITY % local.admon.attrib "">
-<!ENTITY % admon.role.attrib "%role.attrib;">
-
-
-<!ENTITY % caution.element "INCLUDE">
-<![%caution.element;[
-<!--doc:A note of caution.-->
-<!ELEMENT caution %ho; (title?, (%admon.mix;)+)
- %admon.exclusion;>
-<!--end of caution.element-->]]>
-
-<!ENTITY % caution.attlist "INCLUDE">
-<![%caution.attlist;[
-<!ATTLIST caution
- %common.attrib;
- %admon.role.attrib;
- %local.admon.attrib;
->
-<!--end of caution.attlist-->]]>
-
-
-<!ENTITY % important.element "INCLUDE">
-<![%important.element;[
-<!--doc:An admonition set off from the text.-->
-<!ELEMENT important %ho; (title?, (%admon.mix;)+)
- %admon.exclusion;>
-<!--end of important.element-->]]>
-
-<!ENTITY % important.attlist "INCLUDE">
-<![%important.attlist;[
-<!ATTLIST important
- %common.attrib;
- %admon.role.attrib;
- %local.admon.attrib;
->
-<!--end of important.attlist-->]]>
-
-
-<!ENTITY % note.element "INCLUDE">
-<![%note.element;[
-<!--doc:A message set off from the text.-->
-<!ELEMENT note %ho; (title?, (%admon.mix;)+)
- %admon.exclusion;>
-<!--end of note.element-->]]>
-
-<!ENTITY % note.attlist "INCLUDE">
-<![%note.attlist;[
-<!ATTLIST note
- %common.attrib;
- %admon.role.attrib;
- %local.admon.attrib;
->
-<!--end of note.attlist-->]]>
-
-<!ENTITY % tip.element "INCLUDE">
-<![%tip.element;[
-<!--doc:A suggestion to the user, set off from the text.-->
-<!ELEMENT tip %ho; (title?, (%admon.mix;)+)
- %admon.exclusion;>
-<!--end of tip.element-->]]>
-
-<!ENTITY % tip.attlist "INCLUDE">
-<![%tip.attlist;[
-<!ATTLIST tip
- %common.attrib;
- %admon.role.attrib;
- %local.admon.attrib;
->
-<!--end of tip.attlist-->]]>
-
-
-<!ENTITY % warning.element "INCLUDE">
-<![%warning.element;[
-<!--doc:An admonition set off from the text.-->
-<!ELEMENT warning %ho; (title?, (%admon.mix;)+)
- %admon.exclusion;>
-<!--end of warning.element-->]]>
-
-<!ENTITY % warning.attlist "INCLUDE">
-<![%warning.attlist;[
-<!ATTLIST warning
- %common.attrib;
- %admon.role.attrib;
- %local.admon.attrib;
->
-<!--end of warning.attlist-->]]>
-
-<!--end of admon.module-->]]>
-
-<!-- ...................................................................... -->
-<!-- Lists ................................................................ -->
-
-<!-- GlossList ........................ -->
-
-<!ENTITY % glosslist.module "INCLUDE">
-<![%glosslist.module;[
-<!ENTITY % local.glosslist.attrib "">
-<!ENTITY % glosslist.role.attrib "%role.attrib;">
-
-<!ENTITY % glosslist.element "INCLUDE">
-<![%glosslist.element;[
-<!--doc:A wrapper for a set of GlossEntrys.-->
-<!ELEMENT glosslist %ho; (blockinfo?, (%formalobject.title.content;)?, glossentry+)>
-<!--end of glosslist.element-->]]>
-
-<!ENTITY % glosslist.attlist "INCLUDE">
-<![%glosslist.attlist;[
-<!ATTLIST glosslist
- %common.attrib;
- %glosslist.role.attrib;
- %local.glosslist.attrib;
->
-<!--end of glosslist.attlist-->]]>
-<!--end of glosslist.module-->]]>
-
-<!ENTITY % glossentry.content.module "INCLUDE">
-<![%glossentry.content.module;[
-<!ENTITY % glossentry.module "INCLUDE">
-<![%glossentry.module;[
-<!ENTITY % local.glossentry.attrib "">
-<!ENTITY % glossentry.role.attrib "%role.attrib;">
-
-<!ENTITY % glossentry.element "INCLUDE">
-<![%glossentry.element;[
-<!--doc:An entry in a Glossary or GlossList.-->
-<!ELEMENT glossentry %ho; (glossterm, acronym?, abbrev?,
- (%ndxterm.class;)*,
- revhistory?, (glosssee|glossdef+))>
-<!--end of glossentry.element-->]]>
-
-<!-- SortAs: String by which the GlossEntry is to be sorted
- (alphabetized) in lieu of its proper content -->
-
-
-<!ENTITY % glossentry.attlist "INCLUDE">
-<![%glossentry.attlist;[
-<!ATTLIST glossentry
- sortas CDATA #IMPLIED
- %common.attrib;
- %glossentry.role.attrib;
- %local.glossentry.attrib;
->
-<!--end of glossentry.attlist-->]]>
-<!--end of glossentry.module-->]]>
-
-<!-- GlossTerm (defined in the Inlines section, below)-->
-<!ENTITY % glossdef.module "INCLUDE">
-<![%glossdef.module;[
-<!ENTITY % local.glossdef.attrib "">
-<!ENTITY % glossdef.role.attrib "%role.attrib;">
-
-<!ENTITY % glossdef.element "INCLUDE">
-<![%glossdef.element;[
-<!--doc:A definition in a GlossEntry.-->
-<!ELEMENT glossdef %ho; ((%glossdef.mix;)+, glossseealso*)>
-<!--end of glossdef.element-->]]>
-
-<!-- Subject: List of subjects; keywords for the definition -->
-
-
-<!ENTITY % glossdef.attlist "INCLUDE">
-<![%glossdef.attlist;[
-<!ATTLIST glossdef
- subject CDATA #IMPLIED
- %common.attrib;
- %glossdef.role.attrib;
- %local.glossdef.attrib;
->
-<!--end of glossdef.attlist-->]]>
-<!--end of glossdef.module-->]]>
-
-<!ENTITY % glosssee.module "INCLUDE">
-<![%glosssee.module;[
-<!ENTITY % local.glosssee.attrib "">
-<!ENTITY % glosssee.role.attrib "%role.attrib;">
-
-<!ENTITY % glosssee.element "INCLUDE">
-<![%glosssee.element;[
-<!--doc:A cross-reference from one GlossEntry to another.-->
-<!ELEMENT glosssee %ho; (%para.char.mix;)*>
-<!--end of glosssee.element-->]]>
-
-<!-- OtherTerm: Reference to the GlossEntry whose GlossTerm
- should be displayed at the point of the GlossSee -->
-
-
-<!ENTITY % glosssee.attlist "INCLUDE">
-<![%glosssee.attlist;[
-<!ATTLIST glosssee
- otherterm IDREF #IMPLIED
- %common.attrib;
- %glosssee.role.attrib;
- %local.glosssee.attrib;
->
-<!--end of glosssee.attlist-->]]>
-<!--end of glosssee.module-->]]>
-
-<!ENTITY % glossseealso.module "INCLUDE">
-<![%glossseealso.module;[
-<!ENTITY % local.glossseealso.attrib "">
-<!ENTITY % glossseealso.role.attrib "%role.attrib;">
-
-<!ENTITY % glossseealso.element "INCLUDE">
-<![%glossseealso.element;[
-<!--doc:A cross-reference from one GlossEntry to another.-->
-<!ELEMENT glossseealso %ho; (%para.char.mix;)*>
-<!--end of glossseealso.element-->]]>
-
-<!-- OtherTerm: Reference to the GlossEntry whose GlossTerm
- should be displayed at the point of the GlossSeeAlso -->
-
-
-<!ENTITY % glossseealso.attlist "INCLUDE">
-<![%glossseealso.attlist;[
-<!ATTLIST glossseealso
- otherterm IDREF #IMPLIED
- %common.attrib;
- %glossseealso.role.attrib;
- %local.glossseealso.attrib;
->
-<!--end of glossseealso.attlist-->]]>
-<!--end of glossseealso.module-->]]>
-<!--end of glossentry.content.module-->]]>
-
-<!-- ItemizedList and OrderedList ..... -->
-
-<!ENTITY % itemizedlist.module "INCLUDE">
-<![%itemizedlist.module;[
-<!ENTITY % local.itemizedlist.attrib "">
-<!ENTITY % itemizedlist.role.attrib "%role.attrib;">
-
-<!ENTITY % itemizedlist.element "INCLUDE">
-<![%itemizedlist.element;[
-<!--doc:A list in which each entry is marked with a bullet or other dingbat.-->
-<!ELEMENT itemizedlist %ho; (blockinfo?, (%formalobject.title.content;)?,
- (%listpreamble.mix;)*, listitem+)>
-
-<!--end of itemizedlist.element-->]]>
-
-<!-- Spacing: Whether the vertical space in the list should be
- compressed -->
-<!-- Mark: Keyword, e.g., bullet, dash, checkbox, none;
- list of keywords and defaults are implementation specific -->
-
-
-<!ENTITY % itemizedlist.attlist "INCLUDE">
-<![%itemizedlist.attlist;[
-<!ATTLIST itemizedlist
- spacing (normal
- |compact) #IMPLIED
- %mark.attrib;
- %common.attrib;
- %itemizedlist.role.attrib;
- %local.itemizedlist.attrib;
->
-<!--end of itemizedlist.attlist-->]]>
-<!--end of itemizedlist.module-->]]>
-
-<!ENTITY % orderedlist.module "INCLUDE">
-<![%orderedlist.module;[
-<!ENTITY % local.orderedlist.attrib "">
-<!ENTITY % orderedlist.role.attrib "%role.attrib;">
-
-<!ENTITY % orderedlist.element "INCLUDE">
-<![%orderedlist.element;[
-<!--doc:A list in which each entry is marked with a sequentially incremented label.-->
-<!ELEMENT orderedlist %ho; (blockinfo?, (%formalobject.title.content;)?,
- (%listpreamble.mix;)*, listitem+)>
-
-<!--end of orderedlist.element-->]]>
-
-<!-- Numeration: Style of ListItem numbered; default is expected
- to be Arabic -->
-<!-- InheritNum: Specifies for a nested list that the numbering
- of ListItems should include the number of the item
- within which they are nested (e.g., 1a and 1b within 1,
- rather than a and b) -->
-<!-- Continuation: Where list numbering begins afresh (Restarts,
- the default) or continues that of the immediately preceding
- list (Continues) -->
-<!-- Spacing: Whether the vertical space in the list should be
- compressed -->
-
-
-<!ENTITY % orderedlist.attlist "INCLUDE">
-<![%orderedlist.attlist;[
-<!ATTLIST orderedlist
- numeration (arabic
- |upperalpha
- |loweralpha
- |upperroman
- |lowerroman) #IMPLIED
- inheritnum (inherit
- |ignore) "ignore"
- continuation (continues
- |restarts) "restarts"
- spacing (normal
- |compact) #IMPLIED
- %common.attrib;
- %orderedlist.role.attrib;
- %local.orderedlist.attrib;
->
-<!--end of orderedlist.attlist-->]]>
-<!--end of orderedlist.module-->]]>
-
-<!ENTITY % listitem.module "INCLUDE">
-<![%listitem.module;[
-<!ENTITY % local.listitem.attrib "">
-<!ENTITY % listitem.role.attrib "%role.attrib;">
-
-<!ENTITY % listitem.element "INCLUDE">
-<![%listitem.element;[
-<!--doc:A wrapper for the elements of a list item.-->
-<!ELEMENT listitem %ho; ((%component.mix;)+)>
-<!--end of listitem.element-->]]>
-
-<!-- Override: Indicates the mark to be used for this ListItem
- instead of the default mark or the mark specified by
- the Mark attribute on the enclosing ItemizedList -->
-
-
-<!ENTITY % listitem.attlist "INCLUDE">
-<![%listitem.attlist;[
-<!ATTLIST listitem
- override CDATA #IMPLIED
- %common.attrib;
- %listitem.role.attrib;
- %local.listitem.attrib;
->
-<!--end of listitem.attlist-->]]>
-<!--end of listitem.module-->]]>
-
-<!-- SegmentedList .................... -->
-<!ENTITY % segmentedlist.content.module "INCLUDE">
-<![%segmentedlist.content.module;[
-<!ENTITY % segmentedlist.module "INCLUDE">
-<![%segmentedlist.module;[
-<!ENTITY % local.segmentedlist.attrib "">
-<!ENTITY % segmentedlist.role.attrib "%role.attrib;">
-
-<!ENTITY % segmentedlist.element "INCLUDE">
-<![%segmentedlist.element;[
-<!--doc:A segmented list, a list of sets of elements.-->
-<!ELEMENT segmentedlist %ho; ((%formalobject.title.content;)?,
- segtitle+,
- seglistitem+)>
-<!--end of segmentedlist.element-->]]>
-
-<!ENTITY % segmentedlist.attlist "INCLUDE">
-<![%segmentedlist.attlist;[
-<!ATTLIST segmentedlist
- %common.attrib;
- %segmentedlist.role.attrib;
- %local.segmentedlist.attrib;
->
-<!--end of segmentedlist.attlist-->]]>
-<!--end of segmentedlist.module-->]]>
-
-<!ENTITY % segtitle.module "INCLUDE">
-<![%segtitle.module;[
-<!ENTITY % local.segtitle.attrib "">
-<!ENTITY % segtitle.role.attrib "%role.attrib;">
-
-<!ENTITY % segtitle.element "INCLUDE">
-<![%segtitle.element;[
-<!--doc:The title of an element of a list item in a segmented list.-->
-<!ELEMENT segtitle %ho; (%title.char.mix;)*>
-<!--end of segtitle.element-->]]>
-
-<!ENTITY % segtitle.attlist "INCLUDE">
-<![%segtitle.attlist;[
-<!ATTLIST segtitle
- %common.attrib;
- %segtitle.role.attrib;
- %local.segtitle.attrib;
->
-<!--end of segtitle.attlist-->]]>
-<!--end of segtitle.module-->]]>
-
-<!ENTITY % seglistitem.module "INCLUDE">
-<![%seglistitem.module;[
-<!ENTITY % local.seglistitem.attrib "">
-<!ENTITY % seglistitem.role.attrib "%role.attrib;">
-
-<!ENTITY % seglistitem.element "INCLUDE">
-<![%seglistitem.element;[
-<!--doc:A list item in a segmented list.-->
-<!ELEMENT seglistitem %ho; (seg+)>
-<!--end of seglistitem.element-->]]>
-
-<!ENTITY % seglistitem.attlist "INCLUDE">
-<![%seglistitem.attlist;[
-<!ATTLIST seglistitem
- %common.attrib;
- %seglistitem.role.attrib;
- %local.seglistitem.attrib;
->
-<!--end of seglistitem.attlist-->]]>
-<!--end of seglistitem.module-->]]>
-
-<!ENTITY % seg.module "INCLUDE">
-<![%seg.module;[
-<!ENTITY % local.seg.attrib "">
-<!ENTITY % seg.role.attrib "%role.attrib;">
-
-<!ENTITY % seg.element "INCLUDE">
-<![%seg.element;[
-<!--doc:An element of a list item in a segmented list.-->
-<!ELEMENT seg %ho; (%para.char.mix;)*>
-<!--end of seg.element-->]]>
-
-<!ENTITY % seg.attlist "INCLUDE">
-<![%seg.attlist;[
-<!ATTLIST seg
- %common.attrib;
- %seg.role.attrib;
- %local.seg.attrib;
->
-<!--end of seg.attlist-->]]>
-<!--end of seg.module-->]]>
-<!--end of segmentedlist.content.module-->]]>
-
-<!-- SimpleList ....................... -->
-
-<!ENTITY % simplelist.content.module "INCLUDE">
-<![%simplelist.content.module;[
-<!ENTITY % simplelist.module "INCLUDE">
-<![%simplelist.module;[
-<!ENTITY % local.simplelist.attrib "">
-<!ENTITY % simplelist.role.attrib "%role.attrib;">
-
-<!ENTITY % simplelist.element "INCLUDE">
-<![%simplelist.element;[
-<!--doc:An undecorated list of single words or short phrases.-->
-<!ELEMENT simplelist %ho; (member+)>
-<!--end of simplelist.element-->]]>
-
-<!-- Columns: The number of columns the array should contain -->
-<!-- Type: How the Members of the SimpleList should be
- formatted: Inline (members separated with commas etc.
- inline), Vert (top to bottom in n Columns), or Horiz (in
- the direction of text flow) in n Columns. If Column
- is 1 or implied, Type=Vert and Type=Horiz give the same
- results. -->
-
-
-<!ENTITY % simplelist.attlist "INCLUDE">
-<![%simplelist.attlist;[
-<!ATTLIST simplelist
- columns CDATA #IMPLIED
- type (inline
- |vert
- |horiz) "vert"
- %common.attrib;
- %simplelist.role.attrib;
- %local.simplelist.attrib;
->
-<!--end of simplelist.attlist-->]]>
-<!--end of simplelist.module-->]]>
-
-<!ENTITY % member.module "INCLUDE">
-<![%member.module;[
-<!ENTITY % local.member.attrib "">
-<!ENTITY % member.role.attrib "%role.attrib;">
-
-<!ENTITY % member.element "INCLUDE">
-<![%member.element;[
-<!--doc:An element of a simple list.-->
-<!ELEMENT member %ho; (%para.char.mix;)*>
-<!--end of member.element-->]]>
-
-<!ENTITY % member.attlist "INCLUDE">
-<![%member.attlist;[
-<!ATTLIST member
- %common.attrib;
- %member.role.attrib;
- %local.member.attrib;
->
-<!--end of member.attlist-->]]>
-<!--end of member.module-->]]>
-<!--end of simplelist.content.module-->]]>
-
-<!-- VariableList ..................... -->
-
-<!ENTITY % variablelist.content.module "INCLUDE">
-<![%variablelist.content.module;[
-<!ENTITY % variablelist.module "INCLUDE">
-<![%variablelist.module;[
-<!ENTITY % local.variablelist.attrib "">
-<!ENTITY % variablelist.role.attrib "%role.attrib;">
-
-<!ENTITY % variablelist.element "INCLUDE">
-<![%variablelist.element;[
-<!--doc:A list in which each entry is composed of a set of one or more terms and an associated description.-->
-<!ELEMENT variablelist %ho; (blockinfo?, (%formalobject.title.content;)?,
- (%listpreamble.mix;)*, varlistentry+)>
-<!--end of variablelist.element-->]]>
-
-<!-- TermLength: Length beyond which the presentation engine
- may consider the Term too long and select an alternate
- presentation of the Term and, or, its associated ListItem. -->
-
-
-<!ENTITY % variablelist.attlist "INCLUDE">
-<![%variablelist.attlist;[
-<!ATTLIST variablelist
- termlength CDATA #IMPLIED
- spacing (normal
- |compact) #IMPLIED
- %common.attrib;
- %variablelist.role.attrib;
- %local.variablelist.attrib;
->
-<!--end of variablelist.attlist-->]]>
-<!--end of variablelist.module-->]]>
-
-<!ENTITY % varlistentry.module "INCLUDE">
-<![%varlistentry.module;[
-<!ENTITY % local.varlistentry.attrib "">
-<!ENTITY % varlistentry.role.attrib "%role.attrib;">
-
-<!ENTITY % varlistentry.element "INCLUDE">
-<![%varlistentry.element;[
-<!--doc:A wrapper for a set of terms and the associated description in a variable list.-->
-<!ELEMENT varlistentry %ho; (term+, listitem)>
-<!--end of varlistentry.element-->]]>
-
-<!ENTITY % varlistentry.attlist "INCLUDE">
-<![%varlistentry.attlist;[
-<!ATTLIST varlistentry
- %common.attrib;
- %varlistentry.role.attrib;
- %local.varlistentry.attrib;
->
-<!--end of varlistentry.attlist-->]]>
-<!--end of varlistentry.module-->]]>
-
-<!ENTITY % term.module "INCLUDE">
-<![%term.module;[
-<!ENTITY % local.term.attrib "">
-<!ENTITY % term.role.attrib "%role.attrib;">
-
-<!ENTITY % term.element "INCLUDE">
-<![%term.element;[
-<!--doc:The word or phrase being defined or described in a variable list.-->
-<!ELEMENT term %ho; (%para.char.mix;)*>
-<!--end of term.element-->]]>
-
-<!ENTITY % term.attlist "INCLUDE">
-<![%term.attlist;[
-<!ATTLIST term
- %common.attrib;
- %term.role.attrib;
- %local.term.attrib;
->
-<!--end of term.attlist-->]]>
-<!--end of term.module-->]]>
-
-<!-- ListItem (defined above)-->
-<!--end of variablelist.content.module-->]]>
-
-<!-- CalloutList ...................... -->
-
-<!ENTITY % calloutlist.content.module "INCLUDE">
-<![%calloutlist.content.module;[
-<!ENTITY % calloutlist.module "INCLUDE">
-<![%calloutlist.module;[
-<!ENTITY % local.calloutlist.attrib "">
-<!ENTITY % calloutlist.role.attrib "%role.attrib;">
-
-<!ENTITY % calloutlist.element "INCLUDE">
-<![%calloutlist.element;[
-<!--doc:A list of Callouts.-->
-<!ELEMENT calloutlist %ho; ((%formalobject.title.content;)?, callout+)>
-<!--end of calloutlist.element-->]]>
-
-<!ENTITY % calloutlist.attlist "INCLUDE">
-<![%calloutlist.attlist;[
-<!ATTLIST calloutlist
- %common.attrib;
- %calloutlist.role.attrib;
- %local.calloutlist.attrib;
->
-<!--end of calloutlist.attlist-->]]>
-<!--end of calloutlist.module-->]]>
-
-<!ENTITY % callout.module "INCLUDE">
-<![%callout.module;[
-<!ENTITY % local.callout.attrib "">
-<!ENTITY % callout.role.attrib "%role.attrib;">
-
-<!ENTITY % callout.element "INCLUDE">
-<![%callout.element;[
-<!--doc:A &ldquo;called out&rdquo; description of a marked Area.-->
-<!ELEMENT callout %ho; ((%component.mix;)+)>
-<!--end of callout.element-->]]>
-
-<!-- AreaRefs: IDs of one or more Areas or AreaSets described
- by this Callout -->
-
-
-<!ENTITY % callout.attlist "INCLUDE">
-<![%callout.attlist;[
-<!ATTLIST callout
- arearefs IDREFS #REQUIRED
- %common.attrib;
- %callout.role.attrib;
- %local.callout.attrib;
->
-<!--end of callout.attlist-->]]>
-<!--end of callout.module-->]]>
-<!--end of calloutlist.content.module-->]]>
-
-<!-- ...................................................................... -->
-<!-- Objects .............................................................. -->
-
-<!-- Examples etc. .................... -->
-
-<!ENTITY % example.module "INCLUDE">
-<![%example.module;[
-<!ENTITY % local.example.attrib "">
-<!ENTITY % example.role.attrib "%role.attrib;">
-
-<!ENTITY % example.element "INCLUDE">
-<![%example.element;[
-<!--doc:A formal example, with a title.-->
-<!ELEMENT example %ho; (blockinfo?, (%formalobject.title.content;), (%example.mix;)+)
- %formal.exclusion;>
-<!--end of example.element-->]]>
-
-<!ENTITY % example.attlist "INCLUDE">
-<![%example.attlist;[
-<!ATTLIST example
- floatstyle CDATA #IMPLIED
- %label.attrib;
- %width.attrib;
- %common.attrib;
- %example.role.attrib;
- %local.example.attrib;
->
-<!--end of example.attlist-->]]>
-<!--end of example.module-->]]>
-
-<!ENTITY % informalexample.module "INCLUDE">
-<![%informalexample.module;[
-<!ENTITY % local.informalexample.attrib "">
-<!ENTITY % informalexample.role.attrib "%role.attrib;">
-
-<!ENTITY % informalexample.element "INCLUDE">
-<![%informalexample.element;[
-<!--doc:A displayed example without a title.-->
-<!ELEMENT informalexample %ho; (blockinfo?, (%example.mix;)+)>
-<!--end of informalexample.element-->]]>
-
-<!ENTITY % informalexample.attlist "INCLUDE">
-<![%informalexample.attlist;[
-<!ATTLIST informalexample
- floatstyle CDATA #IMPLIED
- %width.attrib;
- %common.attrib;
- %informalexample.role.attrib;
- %local.informalexample.attrib;
->
-<!--end of informalexample.attlist-->]]>
-<!--end of informalexample.module-->]]>
-
-<!ENTITY % programlistingco.module "INCLUDE">
-<![%programlistingco.module;[
-<!ENTITY % local.programlistingco.attrib "">
-<!ENTITY % programlistingco.role.attrib "%role.attrib;">
-
-<!ENTITY % programlistingco.element "INCLUDE">
-<![%programlistingco.element;[
-<!--doc:A program listing with associated areas used in callouts.-->
-<!ELEMENT programlistingco %ho; (areaspec, programlisting, calloutlist*)>
-<!--end of programlistingco.element-->]]>
-
-<!ENTITY % programlistingco.attlist "INCLUDE">
-<![%programlistingco.attlist;[
-<!ATTLIST programlistingco
- %common.attrib;
- %programlistingco.role.attrib;
- %local.programlistingco.attrib;
->
-<!--end of programlistingco.attlist-->]]>
-<!-- CalloutList (defined above in Lists)-->
-<!--end of informalexample.module-->]]>
-
-<!ENTITY % areaspec.content.module "INCLUDE">
-<![%areaspec.content.module;[
-<!ENTITY % areaspec.module "INCLUDE">
-<![%areaspec.module;[
-<!ENTITY % local.areaspec.attrib "">
-<!ENTITY % areaspec.role.attrib "%role.attrib;">
-
-<!ENTITY % areaspec.element "INCLUDE">
-<![%areaspec.element;[
-<!--doc:A collection of regions in a graphic or code example.-->
-<!ELEMENT areaspec %ho; ((area|areaset)+)>
-<!--end of areaspec.element-->]]>
-
-<!-- Units: global unit of measure in which coordinates in
- this spec are expressed:
-
- - CALSPair "x1,y1 x2,y2": lower-left and upper-right
- coordinates in a rectangle describing repro area in which
- graphic is placed, where X and Y dimensions are each some
- number 0..10000 (taken from CALS graphic attributes)
-
- - LineColumn "line column": line number and column number
- at which to start callout text in "linespecific" content
-
- - LineRange "startline endline": whole lines from startline
- to endline in "linespecific" content
-
- - LineColumnPair "line1 col1 line2 col2": starting and ending
- points of area in "linespecific" content that starts at
- first position and ends at second position (including the
- beginnings of any intervening lines)
-
- - Other: directive to look at value of OtherUnits attribute
- to get implementation-specific keyword
-
- The default is implementation-specific; usually dependent on
- the parent element (GraphicCO gets CALSPair, ProgramListingCO
- and ScreenCO get LineColumn) -->
-<!-- OtherUnits: User-defined units -->
-
-
-<!ENTITY % areaspec.attlist "INCLUDE">
-<![%areaspec.attlist;[
-<!ATTLIST areaspec
- units (calspair
- |linecolumn
- |linerange
- |linecolumnpair
- |other) #IMPLIED
- otherunits NMTOKEN #IMPLIED
- %common.attrib;
- %areaspec.role.attrib;
- %local.areaspec.attrib;
->
-<!--end of areaspec.attlist-->]]>
-<!--end of areaspec.module-->]]>
-
-<!ENTITY % area.module "INCLUDE">
-<![%area.module;[
-<!ENTITY % local.area.attrib "">
-<!ENTITY % area.role.attrib "%role.attrib;">
-
-<!ENTITY % area.element "INCLUDE">
-<![%area.element;[
-<!--doc:A region defined for a Callout in a graphic or code example.-->
-<!ELEMENT area %ho; EMPTY>
-<!--end of area.element-->]]>
-
-<!-- bug number/symbol override or initialization -->
-<!-- to any related information -->
-<!-- Units: unit of measure in which coordinates in this
- area are expressed; inherits from AreaSet and AreaSpec -->
-<!-- OtherUnits: User-defined units -->
-
-
-<!ENTITY % area.attlist "INCLUDE">
-<![%area.attlist;[
-<!ATTLIST area
- %label.attrib;
- %linkends.attrib;
- units (calspair
- |linecolumn
- |linerange
- |linecolumnpair
- |other) #IMPLIED
- otherunits NMTOKEN #IMPLIED
- coords CDATA #REQUIRED
- %idreq.common.attrib;
- %area.role.attrib;
- %local.area.attrib;
->
-<!--end of area.attlist-->]]>
-<!--end of area.module-->]]>
-
-<!ENTITY % areaset.module "INCLUDE">
-<![%areaset.module;[
-<!ENTITY % local.areaset.attrib "">
-<!ENTITY % areaset.role.attrib "%role.attrib;">
-
-<!ENTITY % areaset.element "INCLUDE">
-<![%areaset.element;[
-<!--doc:A set of related areas in a graphic or code example.-->
-<!ELEMENT areaset %ho; (area+)>
-<!--end of areaset.element-->]]>
-
-<!-- bug number/symbol override or initialization -->
-<!-- Units: unit of measure in which coordinates in this
- area are expressed; inherits from AreaSpec -->
-
-
-<!ENTITY % areaset.attlist "INCLUDE">
-<![%areaset.attlist;[
-<!ATTLIST areaset
- %label.attrib;
- units (calspair
- |linecolumn
- |linerange
- |linecolumnpair
- |other) #IMPLIED
- otherunits NMTOKEN #IMPLIED
- coords CDATA #REQUIRED
- %idreq.common.attrib;
- %areaset.role.attrib;
- %local.areaset.attrib;
->
-<!--end of areaset.attlist-->]]>
-<!--end of areaset.module-->]]>
-<!--end of areaspec.content.module-->]]>
-
-<!ENTITY % programlisting.module "INCLUDE">
-<![%programlisting.module;[
-<!ENTITY % local.programlisting.attrib "">
-<!ENTITY % programlisting.role.attrib "%role.attrib;">
-
-<!ENTITY % programlisting.element "INCLUDE">
-<![%programlisting.element;[
-<!--doc:A literal listing of all or part of a program.-->
-<!ELEMENT programlisting %ho; (%para.char.mix;|co|coref|lineannotation|textobject)*>
-<!--end of programlisting.element-->]]>
-
-<!ENTITY % programlisting.attlist "INCLUDE">
-<![%programlisting.attlist;[
-<!ATTLIST programlisting
- %width.attrib;
- %linespecific.attrib;
- %common.attrib;
- %programlisting.role.attrib;
- %local.programlisting.attrib;
->
-<!--end of programlisting.attlist-->]]>
-<!--end of programlisting.module-->]]>
-
-<!ENTITY % literallayout.module "INCLUDE">
-<![%literallayout.module;[
-<!ENTITY % local.literallayout.attrib "">
-<!ENTITY % literallayout.role.attrib "%role.attrib;">
-
-<!ENTITY % literallayout.element "INCLUDE">
-<![%literallayout.element;[
-<!--doc:A block of text in which line breaks and white space are to be reproduced faithfully.-->
-<!ELEMENT literallayout %ho; (%para.char.mix;|co|coref|textobject|lineannotation)*>
-<!--end of literallayout.element-->]]>
-
-<!ENTITY % literallayout.attlist "INCLUDE">
-<![%literallayout.attlist;[
-<!ATTLIST literallayout
- %width.attrib;
- %linespecific.attrib;
- class (monospaced|normal) "normal"
- %common.attrib;
- %literallayout.role.attrib;
- %local.literallayout.attrib;
->
-<!--end of literallayout.attlist-->]]>
-<!-- LineAnnotation (defined in the Inlines section, below)-->
-<!--end of literallayout.module-->]]>
-
-<!ENTITY % screenco.module "INCLUDE">
-<![%screenco.module;[
-<!ENTITY % local.screenco.attrib "">
-<!ENTITY % screenco.role.attrib "%role.attrib;">
-
-<!ENTITY % screenco.element "INCLUDE">
-<![%screenco.element;[
-<!--doc:A screen with associated areas used in callouts.-->
-<!ELEMENT screenco %ho; (areaspec, screen, calloutlist*)>
-<!--end of screenco.element-->]]>
-
-<!ENTITY % screenco.attlist "INCLUDE">
-<![%screenco.attlist;[
-<!ATTLIST screenco
- %common.attrib;
- %screenco.role.attrib;
- %local.screenco.attrib;
->
-<!--end of screenco.attlist-->]]>
-<!-- AreaSpec (defined above)-->
-<!-- CalloutList (defined above in Lists)-->
-<!--end of screenco.module-->]]>
-
-<!ENTITY % screen.module "INCLUDE">
-<![%screen.module;[
-<!ENTITY % local.screen.attrib "">
-<!ENTITY % screen.role.attrib "%role.attrib;">
-
-<!ENTITY % screen.element "INCLUDE">
-<![%screen.element;[
-<!--doc:Text that a user sees or might see on a computer screen.-->
-<!ELEMENT screen %ho; (%para.char.mix;|co|coref|textobject|lineannotation)*>
-<!--end of screen.element-->]]>
-
-<!ENTITY % screen.attlist "INCLUDE">
-<![%screen.attlist;[
-<!ATTLIST screen
- %width.attrib;
- %linespecific.attrib;
- %common.attrib;
- %screen.role.attrib;
- %local.screen.attrib;
->
-<!--end of screen.attlist-->]]>
-<!--end of screen.module-->]]>
-
-<!ENTITY % screenshot.content.module "INCLUDE">
-<![%screenshot.content.module;[
-<!ENTITY % screenshot.module "INCLUDE">
-<![%screenshot.module;[
-<!ENTITY % local.screenshot.attrib "">
-<!ENTITY % screenshot.role.attrib "%role.attrib;">
-
-<!ENTITY % screenshot.element "INCLUDE">
-<![%screenshot.element;[
-<!--doc:A representation of what the user sees or might see on a computer screen.-->
-<!ELEMENT screenshot %ho; (screeninfo?,
- (graphic|graphicco
- |mediaobject|mediaobjectco))>
-<!--end of screenshot.element-->]]>
-
-<!ENTITY % screenshot.attlist "INCLUDE">
-<![%screenshot.attlist;[
-<!ATTLIST screenshot
- %common.attrib;
- %screenshot.role.attrib;
- %local.screenshot.attrib;
->
-<!--end of screenshot.attlist-->]]>
-<!--end of screenshot.module-->]]>
-
-<!ENTITY % screeninfo.module "INCLUDE">
-<![%screeninfo.module;[
-<!ENTITY % local.screeninfo.attrib "">
-<!ENTITY % screeninfo.role.attrib "%role.attrib;">
-
-<!ENTITY % screeninfo.element "INCLUDE">
-<![%screeninfo.element;[
-<!--doc:Information about how a screen shot was produced.-->
-<!ELEMENT screeninfo %ho; (%para.char.mix;)*
- %ubiq.exclusion;>
-<!--end of screeninfo.element-->]]>
-
-<!ENTITY % screeninfo.attlist "INCLUDE">
-<![%screeninfo.attlist;[
-<!ATTLIST screeninfo
- %common.attrib;
- %screeninfo.role.attrib;
- %local.screeninfo.attrib;
->
-<!--end of screeninfo.attlist-->]]>
-<!--end of screeninfo.module-->]]>
-<!--end of screenshot.content.module-->]]>
-
-<!-- Figures etc. ..................... -->
-
-<!ENTITY % figure.module "INCLUDE">
-<![%figure.module;[
-<!ENTITY % local.figure.attrib "">
-<!ENTITY % figure.role.attrib "%role.attrib;">
-
-<!ENTITY % figure.element "INCLUDE">
-<![%figure.element;[
-<!--doc:A formal figure, generally an illustration, with a title.-->
-<!ELEMENT figure %ho; (blockinfo?, (%formalobject.title.content;),
- (%figure.mix; | %link.char.class;)+)>
-<!--end of figure.element-->]]>
-
-<!-- Float: Whether the Figure is supposed to be rendered
- where convenient (yes (1) value) or at the place it occurs
- in the text (no (0) value, the default) -->
-
-
-<!ENTITY % figure.attlist "INCLUDE">
-<![%figure.attlist;[
-<!ATTLIST figure
- float %yesorno.attvals; '0'
- floatstyle CDATA #IMPLIED
- pgwide %yesorno.attvals; #IMPLIED
- %label.attrib;
- %common.attrib;
- %figure.role.attrib;
- %local.figure.attrib;
->
-<!--end of figure.attlist-->]]>
-<!--end of figure.module-->]]>
-
-<!ENTITY % informalfigure.module "INCLUDE">
-<![ %informalfigure.module; [
-<!ENTITY % local.informalfigure.attrib "">
-<!ENTITY % informalfigure.role.attrib "%role.attrib;">
-
-<!ENTITY % informalfigure.element "INCLUDE">
-<![ %informalfigure.element; [
-<!--doc:A untitled figure.-->
-<!ELEMENT informalfigure %ho; (blockinfo?, (%figure.mix; | %link.char.class;)+)>
-<!--end of informalfigure.element-->]]>
-
-<!ENTITY % informalfigure.attlist "INCLUDE">
-<![ %informalfigure.attlist; [
-<!--
-Float: Whether the Figure is supposed to be rendered
-where convenient (yes (1) value) or at the place it occurs
-in the text (no (0) value, the default)
--->
-<!ATTLIST informalfigure
- float %yesorno.attvals; "0"
- floatstyle CDATA #IMPLIED
- pgwide %yesorno.attvals; #IMPLIED
- %label.attrib;
- %common.attrib;
- %informalfigure.role.attrib;
- %local.informalfigure.attrib;
->
-<!--end of informalfigure.attlist-->]]>
-<!--end of informalfigure.module-->]]>
-
-<!ENTITY % graphicco.module "INCLUDE">
-<![%graphicco.module;[
-<!ENTITY % local.graphicco.attrib "">
-<!ENTITY % graphicco.role.attrib "%role.attrib;">
-
-<!ENTITY % graphicco.element "INCLUDE">
-<![%graphicco.element;[
-<!--doc:A graphic that contains callout areas.-->
-<!ELEMENT graphicco %ho; (areaspec, graphic, calloutlist*)>
-<!--end of graphicco.element-->]]>
-
-<!ENTITY % graphicco.attlist "INCLUDE">
-<![%graphicco.attlist;[
-<!ATTLIST graphicco
- %common.attrib;
- %graphicco.role.attrib;
- %local.graphicco.attrib;
->
-<!--end of graphicco.attlist-->]]>
-<!-- AreaSpec (defined above in Examples)-->
-<!-- CalloutList (defined above in Lists)-->
-<!--end of graphicco.module-->]]>
-
-<!-- Graphical data can be the content of Graphic, or you can reference
- an external file either as an entity (Entitref) or a filename
- (Fileref). -->
-
-<!ENTITY % graphic.module "INCLUDE">
-<![%graphic.module;[
-<!ENTITY % local.graphic.attrib "">
-<!ENTITY % graphic.role.attrib "%role.attrib;">
-
-<!ENTITY % graphic.element "INCLUDE">
-<![%graphic.element;[
-<!--doc:A displayed graphical object (not an inline).-->
-<!ELEMENT graphic %ho; EMPTY>
-<!--end of graphic.element-->]]>
-
-<!ENTITY % graphic.attlist "INCLUDE">
-<![%graphic.attlist;[
-<!ATTLIST graphic
- %graphics.attrib;
- %common.attrib;
- %graphic.role.attrib;
- %local.graphic.attrib;
->
-<!--end of graphic.attlist-->]]>
-<!--end of graphic.module-->]]>
-
-<!ENTITY % inlinegraphic.module "INCLUDE">
-<![%inlinegraphic.module;[
-<!ENTITY % local.inlinegraphic.attrib "">
-<!ENTITY % inlinegraphic.role.attrib "%role.attrib;">
-
-<!ENTITY % inlinegraphic.element "INCLUDE">
-<![%inlinegraphic.element;[
-<!--doc:An object containing or pointing to graphical data that will be rendered inline.-->
-<!ELEMENT inlinegraphic %ho; EMPTY>
-<!--end of inlinegraphic.element-->]]>
-
-<!ENTITY % inlinegraphic.attlist "INCLUDE">
-<![%inlinegraphic.attlist;[
-<!ATTLIST inlinegraphic
- %graphics.attrib;
- %common.attrib;
- %inlinegraphic.role.attrib;
- %local.inlinegraphic.attrib;
->
-<!--end of inlinegraphic.attlist-->]]>
-<!--end of inlinegraphic.module-->]]>
-
-<!ENTITY % mediaobject.content.module "INCLUDE">
-<![ %mediaobject.content.module; [
-
-<!ENTITY % mediaobject.module "INCLUDE">
-<![ %mediaobject.module; [
-<!ENTITY % local.mediaobject.attrib "">
-<!ENTITY % mediaobject.role.attrib "%role.attrib;">
-
-<!ENTITY % mediaobject.element "INCLUDE">
-<![ %mediaobject.element; [
-<!--doc:A displayed media object (video, audio, image, etc.).-->
-<!ELEMENT mediaobject %ho; (objectinfo?,
- (%mediaobject.mix;)+,
- caption?)>
-<!--end of mediaobject.element-->]]>
-
-<!ENTITY % mediaobject.attlist "INCLUDE">
-<![ %mediaobject.attlist; [
-<!ATTLIST mediaobject
- %common.attrib;
- %mediaobject.role.attrib;
- %local.mediaobject.attrib;
->
-<!--end of mediaobject.attlist-->]]>
-<!--end of mediaobject.module-->]]>
-
-<!ENTITY % inlinemediaobject.module "INCLUDE">
-<![ %inlinemediaobject.module; [
-<!ENTITY % local.inlinemediaobject.attrib "">
-<!ENTITY % inlinemediaobject.role.attrib "%role.attrib;">
-
-<!ENTITY % inlinemediaobject.element "INCLUDE">
-<![ %inlinemediaobject.element; [
-<!--doc:An inline media object (video, audio, image, and so on).-->
-<!ELEMENT inlinemediaobject %ho; (objectinfo?,
- (%mediaobject.mix;)+)>
-<!--end of inlinemediaobject.element-->]]>
-
-<!ENTITY % inlinemediaobject.attlist "INCLUDE">
-<![ %inlinemediaobject.attlist; [
-<!ATTLIST inlinemediaobject
- %common.attrib;
- %inlinemediaobject.role.attrib;
- %local.inlinemediaobject.attrib;
->
-<!--end of inlinemediaobject.attlist-->]]>
-<!--end of inlinemediaobject.module-->]]>
-
-<!ENTITY % videoobject.module "INCLUDE">
-<![ %videoobject.module; [
-<!ENTITY % local.videoobject.attrib "">
-<!ENTITY % videoobject.role.attrib "%role.attrib;">
-
-<!ENTITY % videoobject.element "INCLUDE">
-<![ %videoobject.element; [
-<!--doc:A wrapper for video data and its associated meta-information.-->
-<!ELEMENT videoobject %ho; (objectinfo?, videodata)>
-<!--end of videoobject.element-->]]>
-
-<!ENTITY % videoobject.attlist "INCLUDE">
-<![ %videoobject.attlist; [
-<!ATTLIST videoobject
- %common.attrib;
- %videoobject.role.attrib;
- %local.videoobject.attrib;
->
-<!--end of videoobject.attlist-->]]>
-<!--end of videoobject.module-->]]>
-
-<!ENTITY % audioobject.module "INCLUDE">
-<![ %audioobject.module; [
-<!ENTITY % local.audioobject.attrib "">
-<!ENTITY % audioobject.role.attrib "%role.attrib;">
-
-<!ENTITY % audioobject.element "INCLUDE">
-<![ %audioobject.element; [
-<!--doc:A wrapper for audio data and its associated meta-information.-->
-<!ELEMENT audioobject %ho; (objectinfo?, audiodata)>
-<!--end of audioobject.element-->]]>
-
-<!ENTITY % audioobject.attlist "INCLUDE">
-<![ %audioobject.attlist; [
-<!ATTLIST audioobject
- %common.attrib;
- %audioobject.role.attrib;
- %local.audioobject.attrib;
->
-<!--end of audioobject.attlist-->]]>
-<!--end of audioobject.module-->]]>
-
-<!ENTITY % imageobject.module "INCLUDE">
-<![ %imageobject.module; [
-<!ENTITY % local.imageobject.attrib "">
-<!ENTITY % imageobject.role.attrib "%role.attrib;">
-
-<!ENTITY % imageobject.element "INCLUDE">
-<![ %imageobject.element; [
-<!--doc:A wrapper for image data and its associated meta-information.-->
-<!ELEMENT imageobject %ho; (objectinfo?, imagedata)>
-<!--end of imageobject.element-->]]>
-
-<!ENTITY % imageobject.attlist "INCLUDE">
-<![ %imageobject.attlist; [
-<!ATTLIST imageobject
- %common.attrib;
- %imageobject.role.attrib;
- %local.imageobject.attrib;
->
-<!--end of imageobject.attlist-->]]>
-<!--end of imageobject.module-->]]>
-
-<!ENTITY % textobject.module "INCLUDE">
-<![ %textobject.module; [
-<!ENTITY % local.textobject.attrib "">
-<!ENTITY % textobject.role.attrib "%role.attrib;">
-
-<!ENTITY % textobject.element "INCLUDE">
-<![ %textobject.element; [
-<!--doc:A wrapper for a text description of an object and its associated meta-information.-->
-<!ELEMENT textobject %ho; (objectinfo?, (phrase|textdata|(%textobject.mix;)+))>
-<!--end of textobject.element-->]]>
-
-<!ENTITY % textobject.attlist "INCLUDE">
-<![ %textobject.attlist; [
-<!ATTLIST textobject
- %common.attrib;
- %textobject.role.attrib;
- %local.textobject.attrib;
->
-<!--end of textobject.attlist-->]]>
-<!--end of textobject.module-->]]>
-
-<!ENTITY % objectinfo.module "INCLUDE">
-<![ %objectinfo.module; [
-<!ENTITY % local.objectinfo.attrib "">
-<!ENTITY % objectinfo.role.attrib "%role.attrib;">
-
-<!ENTITY % objectinfo.element "INCLUDE">
-<![ %objectinfo.element; [
-<!--doc:Meta-information for an object.-->
-<!ELEMENT objectinfo %ho; ((%info.class;)+)
- %beginpage.exclusion;>
-<!--end of objectinfo.element-->]]>
-
-<!ENTITY % objectinfo.attlist "INCLUDE">
-<![ %objectinfo.attlist; [
-<!ATTLIST objectinfo
- %common.attrib;
- %objectinfo.role.attrib;
- %local.objectinfo.attrib;
->
-<!--end of objectinfo.attlist-->]]>
-<!--end of objectinfo.module-->]]>
-
-<!--EntityRef: Name of an external entity containing the content
- of the object data-->
-<!--FileRef: Filename, qualified by a pathname if desired,
- designating the file containing the content of the object data-->
-<!--Format: Notation of the element content, if any-->
-<!--SrcCredit: Information about the source of the image-->
-<!ENTITY % local.objectdata.attrib "">
-<!ENTITY % objectdata.attrib
- "
- entityref ENTITY #IMPLIED
- fileref CDATA #IMPLIED
- format (%notation.class;)
- #IMPLIED
- srccredit CDATA #IMPLIED
- %local.objectdata.attrib;"
->
-
-<!ENTITY % videodata.module "INCLUDE">
-<![ %videodata.module; [
-<!ENTITY % local.videodata.attrib "">
-<!ENTITY % videodata.role.attrib "%role.attrib;">
-
-<!ENTITY % videodata.element "INCLUDE">
-<![ %videodata.element; [
-<!--doc:Pointer to external video data.-->
-<!ELEMENT videodata %ho; EMPTY>
-<!--end of videodata.element-->]]>
-
-<!ENTITY % videodata.attlist "INCLUDE">
-<![ %videodata.attlist; [
-
-<!--Width: Same as CALS reprowid (desired width)-->
-<!--Depth: Same as CALS reprodep (desired depth)-->
-<!--Align: Same as CALS hplace with 'none' removed; #IMPLIED means
- application-specific-->
-<!--Scale: Conflation of CALS hscale and vscale-->
-<!--Scalefit: Same as CALS scalefit-->
-<!ATTLIST videodata
- width CDATA #IMPLIED
- contentwidth CDATA #IMPLIED
- depth CDATA #IMPLIED
- contentdepth CDATA #IMPLIED
- align (left
- |right
- |center) #IMPLIED
- valign (top
- |middle
- |bottom) #IMPLIED
- scale CDATA #IMPLIED
- scalefit %yesorno.attvals;
- #IMPLIED
- %objectdata.attrib;
- %common.attrib;
- %videodata.role.attrib;
- %local.videodata.attrib;
->
-<!--end of videodata.attlist-->]]>
-<!--end of videodata.module-->]]>
-
-<!ENTITY % audiodata.module "INCLUDE">
-<![ %audiodata.module; [
-<!ENTITY % local.audiodata.attrib "">
-<!ENTITY % audiodata.role.attrib "%role.attrib;">
-
-<!ENTITY % audiodata.element "INCLUDE">
-<![ %audiodata.element; [
-<!--doc:Pointer to external audio data.-->
-<!ELEMENT audiodata %ho; EMPTY>
-<!--end of audiodata.element-->]]>
-
-<!ENTITY % audiodata.attlist "INCLUDE">
-<![ %audiodata.attlist; [
-<!ATTLIST audiodata
- %objectdata.attrib;
- %common.attrib;
- %audiodata.role.attrib;
- %local.audiodata.attrib;
->
-<!--end of audiodata.attlist-->]]>
-<!--end of audiodata.module-->]]>
-
-<!ENTITY % imagedata.module "INCLUDE">
-<![ %imagedata.module; [
-<!ENTITY % local.imagedata.attrib "">
-<!ENTITY % imagedata.role.attrib "%role.attrib;">
-
-<!ENTITY % imagedata.element "INCLUDE">
-<![ %imagedata.element; [
-<!--doc:Pointer to external image data.-->
-<!ELEMENT imagedata %ho; EMPTY>
-<!--end of imagedata.element-->]]>
-
-<!ENTITY % imagedata.attlist "INCLUDE">
-<![ %imagedata.attlist; [
-
-<!--Width: Same as CALS reprowid (desired width)-->
-<!--Depth: Same as CALS reprodep (desired depth)-->
-<!--Align: Same as CALS hplace with 'none' removed; #IMPLIED means
- application-specific-->
-<!--Scale: Conflation of CALS hscale and vscale-->
-<!--Scalefit: Same as CALS scalefit-->
-<!ATTLIST imagedata
- width CDATA #IMPLIED
- contentwidth CDATA #IMPLIED
- depth CDATA #IMPLIED
- contentdepth CDATA #IMPLIED
- align (left
- |right
- |center) #IMPLIED
- valign (top
- |middle
- |bottom) #IMPLIED
- scale CDATA #IMPLIED
- scalefit %yesorno.attvals;
- #IMPLIED
- %objectdata.attrib;
- %common.attrib;
- %imagedata.role.attrib;
- %local.imagedata.attrib;
->
-<!--end of imagedata.attlist-->]]>
-<!--end of imagedata.module-->]]>
-
-<!ENTITY % textdata.module "INCLUDE">
-<![ %textdata.module; [
-<!ENTITY % local.textdata.attrib "">
-<!ENTITY % textdata.role.attrib "%role.attrib;">
-
-<!ENTITY % textdata.element "INCLUDE">
-<![ %textdata.element; [
-<!--doc:Pointer to external text data.-->
-<!ELEMENT textdata %ho; EMPTY>
-<!--end of textdata.element-->]]>
-
-<!ENTITY % textdata.attlist "INCLUDE">
-<![ %textdata.attlist; [
-<!ATTLIST textdata
- encoding CDATA #IMPLIED
- %objectdata.attrib;
- %common.attrib;
- %textdata.role.attrib;
- %local.textdata.attrib;
->
-<!--end of textdata.attlist-->]]>
-<!--end of textdata.module-->]]>
-
-<!ENTITY % mediaobjectco.module "INCLUDE">
-<![ %mediaobjectco.module; [
-<!ENTITY % local.mediaobjectco.attrib "">
-<!ENTITY % mediaobjectco.role.attrib "%role.attrib;">
-
-<!ENTITY % mediaobjectco.element "INCLUDE">
-<![ %mediaobjectco.element; [
-<!--doc:A media object that contains callouts.-->
-<!ELEMENT mediaobjectco %ho; (objectinfo?, imageobjectco,
- (imageobjectco|textobject)*)>
-<!--end of mediaobjectco.element-->]]>
-
-<!ENTITY % mediaobjectco.attlist "INCLUDE">
-<![ %mediaobjectco.attlist; [
-<!ATTLIST mediaobjectco
- %common.attrib;
- %mediaobjectco.role.attrib;
- %local.mediaobjectco.attrib;
->
-<!--end of mediaobjectco.attlist-->]]>
-<!--end of mediaobjectco.module-->]]>
-
-<!ENTITY % imageobjectco.module "INCLUDE">
-<![ %imageobjectco.module; [
-<!ENTITY % local.imageobjectco.attrib "">
-<!ENTITY % imageobjectco.role.attrib "%role.attrib;">
-
-<!ENTITY % imageobjectco.element "INCLUDE">
-<![ %imageobjectco.element; [
-<!--doc:A wrapper for an image object with callouts.-->
-<!ELEMENT imageobjectco %ho; (areaspec, imageobject, calloutlist*)>
-<!--end of imageobjectco.element-->]]>
-
-<!ENTITY % imageobjectco.attlist "INCLUDE">
-<![ %imageobjectco.attlist; [
-<!ATTLIST imageobjectco
- %common.attrib;
- %imageobjectco.role.attrib;
- %local.imageobjectco.attrib;
->
-<!--end of imageobjectco.attlist-->]]>
-<!--end of imageobjectco.module-->]]>
-<!--end of mediaobject.content.module-->]]>
-
-<!-- Equations ........................ -->
-
-<!-- This PE provides a mechanism for replacing equation content, -->
-<!-- perhaps adding a new or different model (e.g., MathML) -->
-<!ENTITY % equation.content "(alt?, (graphic+|mediaobject+|mathphrase+))">
-<!ENTITY % inlineequation.content "(alt?, (graphic+|inlinemediaobject+|mathphrase+))">
-
-<!ENTITY % equation.module "INCLUDE">
-<![%equation.module;[
-<!ENTITY % local.equation.attrib "">
-<!ENTITY % equation.role.attrib "%role.attrib;">
-
-<!ENTITY % equation.element "INCLUDE">
-<![%equation.element;[
-<!--doc:A displayed mathematical equation.-->
-<!ELEMENT equation %ho; (blockinfo?, (%formalobject.title.content;)?,
- (informalequation | %equation.content;))>
-<!--end of equation.element-->]]>
-
-<!ENTITY % equation.attlist "INCLUDE">
-<![%equation.attlist;[
-<!ATTLIST equation
- floatstyle CDATA #IMPLIED
- %label.attrib;
- %common.attrib;
- %equation.role.attrib;
- %local.equation.attrib;
->
-<!--end of equation.attlist-->]]>
-<!--end of equation.module-->]]>
-
-<!ENTITY % informalequation.module "INCLUDE">
-<![%informalequation.module;[
-<!ENTITY % local.informalequation.attrib "">
-<!ENTITY % informalequation.role.attrib "%role.attrib;">
-
-<!ENTITY % informalequation.element "INCLUDE">
-<![%informalequation.element;[
-<!--doc:A displayed mathematical equation without a title.-->
-<!ELEMENT informalequation %ho; (blockinfo?, %equation.content;) >
-<!--end of informalequation.element-->]]>
-
-<!ENTITY % informalequation.attlist "INCLUDE">
-<![%informalequation.attlist;[
-<!ATTLIST informalequation
- floatstyle CDATA #IMPLIED
- %common.attrib;
- %informalequation.role.attrib;
- %local.informalequation.attrib;
->
-<!--end of informalequation.attlist-->]]>
-<!--end of informalequation.module-->]]>
-
-<!ENTITY % inlineequation.module "INCLUDE">
-<![%inlineequation.module;[
-<!ENTITY % local.inlineequation.attrib "">
-<!ENTITY % inlineequation.role.attrib "%role.attrib;">
-
-<!ENTITY % inlineequation.element "INCLUDE">
-<![%inlineequation.element;[
-<!--doc:A mathematical equation or expression occurring inline.-->
-<!ELEMENT inlineequation %ho; (%inlineequation.content;)>
-<!--end of inlineequation.element-->]]>
-
-<!ENTITY % inlineequation.attlist "INCLUDE">
-<![%inlineequation.attlist;[
-<!ATTLIST inlineequation
- %common.attrib;
- %inlineequation.role.attrib;
- %local.inlineequation.attrib;
->
-<!--end of inlineequation.attlist-->]]>
-<!--end of inlineequation.module-->]]>
-
-<!ENTITY % alt.module "INCLUDE">
-<![%alt.module;[
-<!ENTITY % local.alt.attrib "">
-<!ENTITY % alt.role.attrib "%role.attrib;">
-
-<!ENTITY % alt.element "INCLUDE">
-<![%alt.element;[
-<!--doc:Text representation for a graphical element.-->
-<!ELEMENT alt %ho; (#PCDATA)>
-<!--end of alt.element-->]]>
-
-<!ENTITY % alt.attlist "INCLUDE">
-<![%alt.attlist;[
-<!ATTLIST alt
- %common.attrib;
- %alt.role.attrib;
- %local.alt.attrib;
->
-<!--end of alt.attlist-->]]>
-<!--end of alt.module-->]]>
-
-<!ENTITY % mathphrase.module "INCLUDE">
-<![%mathphrase.module;[
-<!ENTITY % local.mathphrase.attrib "">
-<!ENTITY % mathphrase.role.attrib "%role.attrib;">
-
-<!ENTITY % mathphrase.element "INCLUDE">
-<![%mathphrase.element;[
-<!--doc:A mathematical phrase, an expression that can be represented with ordinary text and a small amount of markup.-->
-<!ELEMENT mathphrase %ho; (#PCDATA|subscript|superscript|emphasis)*>
-<!--end of mathphrase.element-->]]>
-
-<!ENTITY % mathphrase.attlist "INCLUDE">
-<![%mathphrase.attlist;[
-<!ATTLIST mathphrase
- %common.attrib;
- %mathphrase.role.attrib;
- %local.mathphrase.attrib;
->
-<!--end of mathphrase.attlist-->]]>
-<!--end of mathphrase.module-->]]>
-
-<!-- Tables ........................... -->
-
-<!ENTITY % table.module "INCLUDE">
-<![%table.module;[
-
-<!-- Choose a table model. CALS or OASIS XML Exchange -->
-
-<!ENTITY % cals.table.module "INCLUDE">
-<![%cals.table.module;[
-<!ENTITY % exchange.table.module "IGNORE">
-]]>
-<!ENTITY % exchange.table.module "INCLUDE">
-
-<!-- Do we allow the HTML table model as well? -->
-<!ENTITY % allow.html.tables "INCLUDE">
-<![%allow.html.tables;[
- <!-- ====================================================== -->
- <!-- xhtmltbl.mod defines HTML tables and sets parameter
- entities so that, when the CALS table module is read,
- we end up allowing any table to be CALS or HTML.
- i.e. This include must come first! -->
- <!-- ====================================================== -->
-
-<!ENTITY % htmltbl
- PUBLIC "-//OASIS//ELEMENTS DocBook XML HTML Tables V4.5//EN"
- "htmltblx.mod">
-%htmltbl;
-<!--end of allow.html.tables-->]]>
-
-<!ENTITY % tables.role.attrib "%role.attrib;">
-
-<![%cals.table.module;[
-<!-- Add label and role attributes to table and informaltable -->
-<!ENTITY % bodyatt "
- floatstyle CDATA #IMPLIED
- rowheader (firstcol|norowheader) #IMPLIED
- %label.attrib;"
->
-
-<!-- Add common attributes to Table, TGroup, TBody, THead, TFoot, Row,
- EntryTbl, and Entry (and InformalTable element). -->
-<!ENTITY % secur
- "%common.attrib;
- %tables.role.attrib;">
-
-<!ENTITY % common.table.attribs
- "%bodyatt;
- %secur;">
-
-<!-- Content model for Table. -->
-<!ENTITY % tbl.table.mdl
- "(blockinfo?, (%formalobject.title.content;), (%ndxterm.class;)*,
- textobject*,
- (graphic+|mediaobject+|tgroup+))">
-
-<!-- Allow either objects or inlines; beware of REs between elements. -->
-<!ENTITY % tbl.entry.mdl "%para.char.mix; | %tabentry.mix;">
-
-<!-- Reference CALS Table Model -->
-<!ENTITY % tablemodel
- PUBLIC "-//OASIS//DTD DocBook CALS Table Model V4.5//EN"
- "calstblx.dtd">
-]]>
-
-<![%exchange.table.module;[
-<!-- Add common attributes and the Label attribute to Table and -->
-<!-- InformalTable. -->
-<!ENTITY % bodyatt
- "%common.attrib;
- rowheader (firstcol|norowheader) #IMPLIED
- %label.attrib;
- %tables.role.attrib;">
-
-<!ENTITY % common.table.attribs
- "%bodyatt;">
-
-<!-- Add common attributes to TGroup, ColSpec, TBody, THead, Row, Entry -->
-
-<!ENTITY % tbl.tgroup.att "%common.attrib;">
-<!ENTITY % tbl.colspec.att "%common.attrib;">
-<!ENTITY % tbl.tbody.att "%common.attrib;">
-<!ENTITY % tbl.thead.att "%common.attrib;">
-<!ENTITY % tbl.row.att "%common.attrib;">
-<!ENTITY % tbl.entry.att "%common.attrib;">
-
-<!-- Content model for Table. -->
-<!ENTITY % tbl.table.mdl
- "(blockinfo?, (%formalobject.title.content;), (%ndxterm.class;)*,
- textobject*,
- (graphic+|mediaobject+|tgroup+))">
-
-<!-- Allow either objects or inlines; beware of REs between elements. -->
-<!ENTITY % tbl.entry.mdl "(%para.char.mix; | %tabentry.mix;)*">
-
-<!-- Reference OASIS Exchange Table Model -->
-<!ENTITY % tablemodel
- PUBLIC "-//OASIS//DTD XML Exchange Table Model 19990315//EN"
- "soextblx.dtd">
-]]>
-
-%tablemodel;
-
-<!--end of table.module-->]]>
-
-<!ENTITY % informaltable.module "INCLUDE">
-<![%informaltable.module;[
-
-<!-- Note that InformalTable is dependent on some of the entity
- declarations that customize Table. -->
-
-<!ENTITY % local.informaltable.attrib "">
-
-<!-- the following entity may have been declared by the XHTML table module -->
-<!ENTITY % informal.tbl.table.mdl "textobject*, (graphic+|mediaobject+|tgroup+)">
-
-<!ENTITY % informaltable.element "INCLUDE">
-<![%informaltable.element;[
-<!--doc:A table without a title.-->
-<!ELEMENT informaltable %ho; (blockinfo?, (%informal.tbl.table.mdl;))>
-<!--end of informaltable.element-->]]>
-
-<!-- Frame, Colsep, and Rowsep must be repeated because
- they are not in entities in the table module. -->
-<!-- includes TabStyle, ToCentry, ShortEntry,
- Orient, PgWide -->
-<!-- includes Label -->
-<!-- includes common attributes -->
-
-<!ENTITY % informaltable.attlist "INCLUDE">
-<![%informaltable.attlist;[
-<!ATTLIST informaltable
- frame (%tbl.frame.attval;) #IMPLIED
- colsep %yesorno.attvals; #IMPLIED
- rowsep %yesorno.attvals; #IMPLIED
- %common.table.attribs;
- %tbl.table.att;
- %local.informaltable.attrib;
->
-<!--end of informaltable.attlist-->]]>
-<!--end of informaltable.module-->]]>
-
-<!ENTITY % caption.module "INCLUDE">
-<![ %caption.module; [
-<!ENTITY % local.caption.attrib "">
-<!ENTITY % caption.role.attrib "%role.attrib;">
-
-<!ENTITY % caption.element "INCLUDE">
-<![ %caption.element; [
-<!--doc:A caption.-->
-<!ELEMENT caption %ho; (#PCDATA | %textobject.mix;)*>
-<!--end of caption.element-->]]>
-
-<!ENTITY % caption.attlist "INCLUDE">
-<![ %caption.attlist; [
-<!-- attrs comes from HTML tables ... -->
-
-<![ %allow.html.tables; [
-<!-- common.attrib, but without ID because ID is in attrs -->
-<!ENTITY % caption.attlist.content "
- %caption.role.attrib;
- %attrs;
- align (top|bottom|left|right) #IMPLIED
- %local.caption.attrib;
-">
-]]>
-<!ENTITY % caption.attlist.content "
- %common.attrib;
- %caption.role.attrib;
- %local.caption.attrib;
-">
-
-<!ATTLIST caption %caption.attlist.content;>
-
-<!--end of caption.attlist-->]]>
-<!--end of caption.module-->]]>
-
-<!-- ...................................................................... -->
-<!-- Synopses ............................................................. -->
-
-<!-- Synopsis ......................... -->
-
-<!ENTITY % synopsis.module "INCLUDE">
-<![%synopsis.module;[
-<!ENTITY % local.synopsis.attrib "">
-<!ENTITY % synopsis.role.attrib "%role.attrib;">
-
-<!ENTITY % synopsis.element "INCLUDE">
-<![%synopsis.element;[
-<!--doc:A general-purpose element for representing the syntax of commands or functions.-->
-<!ELEMENT synopsis %ho; (%para.char.mix;|graphic|mediaobject|co|coref|textobject|lineannotation)*>
-<!--end of synopsis.element-->]]>
-
-<!ENTITY % synopsis.attlist "INCLUDE">
-<![%synopsis.attlist;[
-<!ATTLIST synopsis
- %label.attrib;
- %linespecific.attrib;
- %common.attrib;
- %synopsis.role.attrib;
- %local.synopsis.attrib;
->
-<!--end of synopsis.attlist-->]]>
-
-<!-- LineAnnotation (defined in the Inlines section, below)-->
-<!--end of synopsis.module-->]]>
-
-<!-- CmdSynopsis ...................... -->
-
-<!ENTITY % cmdsynopsis.content.module "INCLUDE">
-<![%cmdsynopsis.content.module;[
-<!ENTITY % cmdsynopsis.module "INCLUDE">
-<![%cmdsynopsis.module;[
-<!ENTITY % local.cmdsynopsis.attrib "">
-<!ENTITY % cmdsynopsis.role.attrib "%role.attrib;">
-
-<!ENTITY % cmdsynopsis.element "INCLUDE">
-<![%cmdsynopsis.element;[
-<!--doc:A syntax summary for a software command.-->
-<!ELEMENT cmdsynopsis %ho; ((command | arg | group | sbr)+, synopfragment*)>
-<!--end of cmdsynopsis.element-->]]>
-
-<!-- Sepchar: Character that should separate command and all
- top-level arguments; alternate value might be e.g., &Delta; -->
-
-
-<!ENTITY % cmdsynopsis.attlist "INCLUDE">
-<![%cmdsynopsis.attlist;[
-<!ATTLIST cmdsynopsis
- %label.attrib;
- sepchar CDATA " "
- cmdlength CDATA #IMPLIED
- %common.attrib;
- %cmdsynopsis.role.attrib;
- %local.cmdsynopsis.attrib;
->
-<!--end of cmdsynopsis.attlist-->]]>
-<!--end of cmdsynopsis.module-->]]>
-
-<!ENTITY % arg.module "INCLUDE">
-<![%arg.module;[
-<!ENTITY % local.arg.attrib "">
-<!ENTITY % arg.role.attrib "%role.attrib;">
-
-<!ENTITY % arg.element "INCLUDE">
-<![%arg.element;[
-<!--doc:An argument in a CmdSynopsis.-->
-<!ELEMENT arg %ho; (#PCDATA
- | arg
- | group
- | option
- | synopfragmentref
- | replaceable
- | sbr)*>
-<!--end of arg.element-->]]>
-
-<!-- Choice: Whether Arg must be supplied: Opt (optional to
- supply, e.g. [arg]; the default), Req (required to supply,
- e.g. {arg}), or Plain (required to supply, e.g. arg) -->
-<!-- Rep: whether Arg is repeatable: Norepeat (e.g. arg without
- ellipsis; the default), or Repeat (e.g. arg...) -->
-
-
-<!ENTITY % arg.attlist "INCLUDE">
-<![%arg.attlist;[
-<!ATTLIST arg
- choice (opt
- |req
- |plain) 'opt'
- rep (norepeat
- |repeat) 'norepeat'
- %common.attrib;
- %arg.role.attrib;
- %local.arg.attrib;
->
-<!--end of arg.attlist-->]]>
-<!--end of arg.module-->]]>
-
-<!ENTITY % group.module "INCLUDE">
-<![%group.module;[
-
-<!ENTITY % local.group.attrib "">
-<!ENTITY % group.role.attrib "%role.attrib;">
-
-<!ENTITY % group.element "INCLUDE">
-<![%group.element;[
-<!--doc:A group of elements in a CmdSynopsis.-->
-<!ELEMENT group %ho; ((arg | group | option | synopfragmentref
- | replaceable | sbr)+)>
-<!--end of group.element-->]]>
-
-<!-- Choice: Whether Group must be supplied: Opt (optional to
- supply, e.g. [g1|g2|g3]; the default), Req (required to
- supply, e.g. {g1|g2|g3}), Plain (required to supply,
- e.g. g1|g2|g3), OptMult (can supply zero or more, e.g.
- [[g1|g2|g3]]), or ReqMult (must supply one or more, e.g.
- {{g1|g2|g3}}) -->
-<!-- Rep: whether Group is repeatable: Norepeat (e.g. group
- without ellipsis; the default), or Repeat (e.g. group...) -->
-
-
-<!ENTITY % group.attlist "INCLUDE">
-<![%group.attlist;[
-<!ATTLIST group
- choice (opt
- |req
- |plain) 'opt'
- rep (norepeat
- |repeat) 'norepeat'
- %common.attrib;
- %group.role.attrib;
- %local.group.attrib;
->
-<!--end of group.attlist-->]]>
-<!--end of group.module-->]]>
-
-<!ENTITY % sbr.module "INCLUDE">
-<![%sbr.module;[
-<!ENTITY % local.sbr.attrib "">
-<!-- Synopsis break -->
-<!ENTITY % sbr.role.attrib "%role.attrib;">
-
-<!ENTITY % sbr.element "INCLUDE">
-<![%sbr.element;[
-<!--doc:An explicit line break in a command synopsis.-->
-<!ELEMENT sbr %ho; EMPTY>
-<!--end of sbr.element-->]]>
-
-<!ENTITY % sbr.attlist "INCLUDE">
-<![%sbr.attlist;[
-<!ATTLIST sbr
- %common.attrib;
- %sbr.role.attrib;
- %local.sbr.attrib;
->
-<!--end of sbr.attlist-->]]>
-<!--end of sbr.module-->]]>
-
-<!ENTITY % synopfragmentref.module "INCLUDE">
-<![%synopfragmentref.module;[
-<!ENTITY % local.synopfragmentref.attrib "">
-<!ENTITY % synopfragmentref.role.attrib "%role.attrib;">
-
-<!ENTITY % synopfragmentref.element "INCLUDE">
-<![%synopfragmentref.element;[
-<!--doc:A reference to a fragment of a command synopsis.-->
-<!ELEMENT synopfragmentref %ho; (#PCDATA)>
-<!--end of synopfragmentref.element-->]]>
-
-<!-- to SynopFragment of complex synopsis
- material for separate referencing -->
-
-
-<!ENTITY % synopfragmentref.attlist "INCLUDE">
-<![%synopfragmentref.attlist;[
-<!ATTLIST synopfragmentref
- %linkendreq.attrib; %common.attrib;
- %synopfragmentref.role.attrib;
- %local.synopfragmentref.attrib;
->
-<!--end of synopfragmentref.attlist-->]]>
-<!--end of synopfragmentref.module-->]]>
-
-<!ENTITY % synopfragment.module "INCLUDE">
-<![%synopfragment.module;[
-<!ENTITY % local.synopfragment.attrib "">
-<!ENTITY % synopfragment.role.attrib "%role.attrib;">
-
-<!ENTITY % synopfragment.element "INCLUDE">
-<![%synopfragment.element;[
-<!--doc:A portion of a CmdSynopsis broken out from the main body of the synopsis.-->
-<!ELEMENT synopfragment %ho; ((arg | group)+)>
-<!--end of synopfragment.element-->]]>
-
-<!ENTITY % synopfragment.attlist "INCLUDE">
-<![%synopfragment.attlist;[
-<!ATTLIST synopfragment
- %idreq.common.attrib;
- %synopfragment.role.attrib;
- %local.synopfragment.attrib;
->
-<!--end of synopfragment.attlist-->]]>
-<!--end of synopfragment.module-->]]>
-
-<!-- Command (defined in the Inlines section, below)-->
-<!-- Option (defined in the Inlines section, below)-->
-<!-- Replaceable (defined in the Inlines section, below)-->
-<!--end of cmdsynopsis.content.module-->]]>
-
-<!-- FuncSynopsis ..................... -->
-
-<!ENTITY % funcsynopsis.content.module "INCLUDE">
-<![%funcsynopsis.content.module;[
-<!ENTITY % funcsynopsis.module "INCLUDE">
-<![%funcsynopsis.module;[
-
-<!ENTITY % local.funcsynopsis.attrib "">
-<!ENTITY % funcsynopsis.role.attrib "%role.attrib;">
-
-<!ENTITY % funcsynopsis.element "INCLUDE">
-<![%funcsynopsis.element;[
-<!--doc:The syntax summary for a function definition.-->
-<!ELEMENT funcsynopsis %ho; ((funcsynopsisinfo | funcprototype)+)>
-<!--end of funcsynopsis.element-->]]>
-
-<!ENTITY % funcsynopsis.attlist "INCLUDE">
-<![%funcsynopsis.attlist;[
-<!ATTLIST funcsynopsis
- %label.attrib;
- %common.attrib;
- %funcsynopsis.role.attrib;
- %local.funcsynopsis.attrib;
->
-<!--end of funcsynopsis.attlist-->]]>
-<!--end of funcsynopsis.module-->]]>
-
-<!ENTITY % funcsynopsisinfo.module "INCLUDE">
-<![%funcsynopsisinfo.module;[
-<!ENTITY % local.funcsynopsisinfo.attrib "">
-<!ENTITY % funcsynopsisinfo.role.attrib "%role.attrib;">
-
-<!ENTITY % funcsynopsisinfo.element "INCLUDE">
-<![%funcsynopsisinfo.element;[
-<!--doc:Information supplementing the FuncDefs of a FuncSynopsis.-->
-<!ELEMENT funcsynopsisinfo %ho; (%cptr.char.mix;|textobject|lineannotation)*>
-<!--end of funcsynopsisinfo.element-->]]>
-
-<!ENTITY % funcsynopsisinfo.attlist "INCLUDE">
-<![%funcsynopsisinfo.attlist;[
-<!ATTLIST funcsynopsisinfo
- %linespecific.attrib;
- %common.attrib;
- %funcsynopsisinfo.role.attrib;
- %local.funcsynopsisinfo.attrib;
->
-<!--end of funcsynopsisinfo.attlist-->]]>
-<!--end of funcsynopsisinfo.module-->]]>
-
-<!ENTITY % funcprototype.module "INCLUDE">
-<![%funcprototype.module;[
-<!ENTITY % local.funcprototype.attrib "">
-<!ENTITY % funcprototype.role.attrib "%role.attrib;">
-
-<!ENTITY % funcprototype.element "INCLUDE">
-<![%funcprototype.element;[
-<!--doc:The prototype of a function.-->
-<!ELEMENT funcprototype %ho; (modifier*,
- funcdef,
- (void|varargs|(paramdef+, varargs?)),
- modifier*)>
-
-<!--end of funcprototype.element-->]]>
-
-<!ENTITY % funcprototype.attlist "INCLUDE">
-<![%funcprototype.attlist;[
-<!ATTLIST funcprototype
- %common.attrib;
- %funcprototype.role.attrib;
- %local.funcprototype.attrib;
->
-<!--end of funcprototype.attlist-->]]>
-<!--end of funcprototype.module-->]]>
-
-<!ENTITY % funcdef.module "INCLUDE">
-<![%funcdef.module;[
-<!ENTITY % local.funcdef.attrib "">
-<!ENTITY % funcdef.role.attrib "%role.attrib;">
-
-<!ENTITY % funcdef.element "INCLUDE">
-<![%funcdef.element;[
-<!--doc:A function (subroutine) name and its return type.-->
-<!ELEMENT funcdef %ho; (#PCDATA
- | type
- | replaceable
- | function)*>
-<!--end of funcdef.element-->]]>
-
-<!ENTITY % funcdef.attlist "INCLUDE">
-<![%funcdef.attlist;[
-<!ATTLIST funcdef
- %common.attrib;
- %funcdef.role.attrib;
- %local.funcdef.attrib;
->
-<!--end of funcdef.attlist-->]]>
-<!--end of funcdef.module-->]]>
-
-<!ENTITY % void.module "INCLUDE">
-<![%void.module;[
-<!ENTITY % local.void.attrib "">
-<!ENTITY % void.role.attrib "%role.attrib;">
-
-<!ENTITY % void.element "INCLUDE">
-<![%void.element;[
-<!--doc:An empty element in a function synopsis indicating that the function in question takes no arguments.-->
-<!ELEMENT void %ho; EMPTY>
-<!--end of void.element-->]]>
-
-<!ENTITY % void.attlist "INCLUDE">
-<![%void.attlist;[
-<!ATTLIST void
- %common.attrib;
- %void.role.attrib;
- %local.void.attrib;
->
-<!--end of void.attlist-->]]>
-<!--end of void.module-->]]>
-
-<!ENTITY % varargs.module "INCLUDE">
-<![%varargs.module;[
-<!ENTITY % local.varargs.attrib "">
-<!ENTITY % varargs.role.attrib "%role.attrib;">
-
-<!ENTITY % varargs.element "INCLUDE">
-<![%varargs.element;[
-<!--doc:An empty element in a function synopsis indicating a variable number of arguments.-->
-<!ELEMENT varargs %ho; EMPTY>
-<!--end of varargs.element-->]]>
-
-<!ENTITY % varargs.attlist "INCLUDE">
-<![%varargs.attlist;[
-<!ATTLIST varargs
- %common.attrib;
- %varargs.role.attrib;
- %local.varargs.attrib;
->
-<!--end of varargs.attlist-->]]>
-<!--end of varargs.module-->]]>
-
-<!-- Processing assumes that only one Parameter will appear in a
- ParamDef, and that FuncParams will be used at most once, for
- providing information on the "inner parameters" for parameters that
- are pointers to functions. -->
-
-<!ENTITY % paramdef.module "INCLUDE">
-<![%paramdef.module;[
-<!ENTITY % local.paramdef.attrib "">
-<!ENTITY % paramdef.role.attrib "%role.attrib;">
-
-<!ENTITY % paramdef.element "INCLUDE">
-<![%paramdef.element;[
-<!--doc:Information about a function parameter in a programming language.-->
-<!ELEMENT paramdef %ho; (#PCDATA
- | initializer
- | type
- | replaceable
- | parameter
- | funcparams)*>
-<!--end of paramdef.element-->]]>
-
-<!ENTITY % paramdef.attlist "INCLUDE">
-<![%paramdef.attlist;[
-<!ATTLIST paramdef
- choice (opt
- |req) #IMPLIED
- %common.attrib;
- %paramdef.role.attrib;
- %local.paramdef.attrib;
->
-<!--end of paramdef.attlist-->]]>
-<!--end of paramdef.module-->]]>
-
-<!ENTITY % funcparams.module "INCLUDE">
-<![%funcparams.module;[
-<!ENTITY % local.funcparams.attrib "">
-<!ENTITY % funcparams.role.attrib "%role.attrib;">
-
-<!ENTITY % funcparams.element "INCLUDE">
-<![%funcparams.element;[
-<!--doc:Parameters for a function referenced through a function pointer in a synopsis.-->
-<!ELEMENT funcparams %ho; (%cptr.char.mix;)*>
-<!--end of funcparams.element-->]]>
-
-<!ENTITY % funcparams.attlist "INCLUDE">
-<![%funcparams.attlist;[
-<!ATTLIST funcparams
- %common.attrib;
- %funcparams.role.attrib;
- %local.funcparams.attrib;
->
-<!--end of funcparams.attlist-->]]>
-<!--end of funcparams.module-->]]>
-
-<!-- LineAnnotation (defined in the Inlines section, below)-->
-<!-- Replaceable (defined in the Inlines section, below)-->
-<!-- Function (defined in the Inlines section, below)-->
-<!-- Parameter (defined in the Inlines section, below)-->
-<!--end of funcsynopsis.content.module-->]]>
-
-<!-- ClassSynopsis ..................... -->
-
-<!ENTITY % classsynopsis.content.module "INCLUDE">
-<![%classsynopsis.content.module;[
-
-<!ENTITY % classsynopsis.module "INCLUDE">
-<![%classsynopsis.module;[
-<!ENTITY % local.classsynopsis.attrib "">
-<!ENTITY % classsynopsis.role.attrib "%role.attrib;">
-
-<!ENTITY % classsynopsis.element "INCLUDE">
-<![%classsynopsis.element;[
-<!--doc:The syntax summary for a class definition.-->
-<!ELEMENT classsynopsis %ho; ((ooclass|oointerface|ooexception)+,
- (classsynopsisinfo
- |fieldsynopsis|%method.synop.class;)*)>
-<!--end of classsynopsis.element-->]]>
-
-<!ENTITY % classsynopsis.attlist "INCLUDE">
-<![%classsynopsis.attlist;[
-<!ATTLIST classsynopsis
- language CDATA #IMPLIED
- class (class|interface) "class"
- %common.attrib;
- %classsynopsis.role.attrib;
- %local.classsynopsis.attrib;
->
-<!--end of classsynopsis.attlist-->]]>
-<!--end of classsynopsis.module-->]]>
-
-<!ENTITY % classsynopsisinfo.module "INCLUDE">
-<![ %classsynopsisinfo.module; [
-<!ENTITY % local.classsynopsisinfo.attrib "">
-<!ENTITY % classsynopsisinfo.role.attrib "%role.attrib;">
-
-<!ENTITY % classsynopsisinfo.element "INCLUDE">
-<![ %classsynopsisinfo.element; [
-<!--doc:Information supplementing the contents of a ClassSynopsis.-->
-<!ELEMENT classsynopsisinfo %ho; (%cptr.char.mix;|textobject|lineannotation)*>
-<!--end of classsynopsisinfo.element-->]]>
-
-<!ENTITY % classsynopsisinfo.attlist "INCLUDE">
-<![ %classsynopsisinfo.attlist; [
-<!ATTLIST classsynopsisinfo
- %linespecific.attrib;
- %common.attrib;
- %classsynopsisinfo.role.attrib;
- %local.classsynopsisinfo.attrib;
->
-<!--end of classsynopsisinfo.attlist-->]]>
-<!--end of classsynopsisinfo.module-->]]>
-
-<!ENTITY % ooclass.module "INCLUDE">
-<![%ooclass.module;[
-<!ENTITY % local.ooclass.attrib "">
-<!ENTITY % ooclass.role.attrib "%role.attrib;">
-
-<!ENTITY % ooclass.element "INCLUDE">
-<![%ooclass.element;[
-<!--doc:A class in an object-oriented programming language.-->
-<!ELEMENT ooclass %ho; ((modifier|package)*, classname)>
-<!--end of ooclass.element-->]]>
-
-<!ENTITY % ooclass.attlist "INCLUDE">
-<![%ooclass.attlist;[
-<!ATTLIST ooclass
- %common.attrib;
- %ooclass.role.attrib;
- %local.ooclass.attrib;
->
-<!--end of ooclass.attlist-->]]>
-<!--end of ooclass.module-->]]>
-
-<!ENTITY % oointerface.module "INCLUDE">
-<![%oointerface.module;[
-<!ENTITY % local.oointerface.attrib "">
-<!ENTITY % oointerface.role.attrib "%role.attrib;">
-
-<!ENTITY % oointerface.element "INCLUDE">
-<![%oointerface.element;[
-<!--doc:An interface in an object-oriented programming language.-->
-<!ELEMENT oointerface %ho; ((modifier|package)*, interfacename)>
-<!--end of oointerface.element-->]]>
-
-<!ENTITY % oointerface.attlist "INCLUDE">
-<![%oointerface.attlist;[
-<!ATTLIST oointerface
- %common.attrib;
- %oointerface.role.attrib;
- %local.oointerface.attrib;
->
-<!--end of oointerface.attlist-->]]>
-<!--end of oointerface.module-->]]>
-
-<!ENTITY % ooexception.module "INCLUDE">
-<![%ooexception.module;[
-<!ENTITY % local.ooexception.attrib "">
-<!ENTITY % ooexception.role.attrib "%role.attrib;">
-
-<!ENTITY % ooexception.element "INCLUDE">
-<![%ooexception.element;[
-<!--doc:An exception in an object-oriented programming language.-->
-<!ELEMENT ooexception %ho; ((modifier|package)*, exceptionname)>
-<!--end of ooexception.element-->]]>
-
-<!ENTITY % ooexception.attlist "INCLUDE">
-<![%ooexception.attlist;[
-<!ATTLIST ooexception
- %common.attrib;
- %ooexception.role.attrib;
- %local.ooexception.attrib;
->
-<!--end of ooexception.attlist-->]]>
-<!--end of ooexception.module-->]]>
-
-<!ENTITY % modifier.module "INCLUDE">
-<![%modifier.module;[
-<!ENTITY % local.modifier.attrib "">
-<!ENTITY % modifier.role.attrib "%role.attrib;">
-
-<!ENTITY % modifier.element "INCLUDE">
-<![%modifier.element;[
-<!--doc:Modifiers in a synopsis.-->
-<!ELEMENT modifier %ho; (%smallcptr.char.mix;)*>
-<!--end of modifier.element-->]]>
-
-<!ENTITY % modifier.attlist "INCLUDE">
-<![%modifier.attlist;[
-<!ATTLIST modifier
- %common.attrib;
- %modifier.role.attrib;
- %local.modifier.attrib;
->
-<!--end of modifier.attlist-->]]>
-<!--end of modifier.module-->]]>
-
-<!ENTITY % interfacename.module "INCLUDE">
-<![%interfacename.module;[
-<!ENTITY % local.interfacename.attrib "">
-<!ENTITY % interfacename.role.attrib "%role.attrib;">
-
-<!ENTITY % interfacename.element "INCLUDE">
-<![%interfacename.element;[
-<!--doc:The name of an interface.-->
-<!ELEMENT interfacename %ho; (%cptr.char.mix;)*>
-<!--end of interfacename.element-->]]>
-
-<!ENTITY % interfacename.attlist "INCLUDE">
-<![%interfacename.attlist;[
-<!ATTLIST interfacename
- %common.attrib;
- %interfacename.role.attrib;
- %local.interfacename.attrib;
->
-<!--end of interfacename.attlist-->]]>
-<!--end of interfacename.module-->]]>
-
-<!ENTITY % exceptionname.module "INCLUDE">
-<![%exceptionname.module;[
-<!ENTITY % local.exceptionname.attrib "">
-<!ENTITY % exceptionname.role.attrib "%role.attrib;">
-
-<!ENTITY % exceptionname.element "INCLUDE">
-<![%exceptionname.element;[
-<!--doc:The name of an exception.-->
-<!ELEMENT exceptionname %ho; (%smallcptr.char.mix;)*>
-<!--end of exceptionname.element-->]]>
-
-<!ENTITY % exceptionname.attlist "INCLUDE">
-<![%exceptionname.attlist;[
-<!ATTLIST exceptionname
- %common.attrib;
- %exceptionname.role.attrib;
- %local.exceptionname.attrib;
->
-<!--end of exceptionname.attlist-->]]>
-<!--end of exceptionname.module-->]]>
-
-<!ENTITY % fieldsynopsis.module "INCLUDE">
-<![%fieldsynopsis.module;[
-<!ENTITY % local.fieldsynopsis.attrib "">
-<!ENTITY % fieldsynopsis.role.attrib "%role.attrib;">
-
-<!ENTITY % fieldsynopsis.element "INCLUDE">
-<![%fieldsynopsis.element;[
-<!--doc:The name of a field in a class definition.-->
-<!ELEMENT fieldsynopsis %ho; (modifier*, type?, varname, initializer?)>
-<!--end of fieldsynopsis.element-->]]>
-
-<!ENTITY % fieldsynopsis.attlist "INCLUDE">
-<![%fieldsynopsis.attlist;[
-<!ATTLIST fieldsynopsis
- language CDATA #IMPLIED
- %common.attrib;
- %fieldsynopsis.role.attrib;
- %local.fieldsynopsis.attrib;
->
-<!--end of fieldsynopsis.attlist-->]]>
-<!--end of fieldsynopsis.module-->]]>
-
-<!ENTITY % initializer.module "INCLUDE">
-<![%initializer.module;[
-<!ENTITY % local.initializer.attrib "">
-<!ENTITY % initializer.role.attrib "%role.attrib;">
-
-<!ENTITY % initializer.element "INCLUDE">
-<![%initializer.element;[
-<!--doc:The initializer for a FieldSynopsis.-->
-<!ELEMENT initializer %ho; (%smallcptr.char.mix;)*>
-<!--end of initializer.element-->]]>
-
-<!ENTITY % initializer.attlist "INCLUDE">
-<![%initializer.attlist;[
-<!ATTLIST initializer
- %common.attrib;
- %initializer.role.attrib;
- %local.initializer.attrib;
->
-<!--end of initializer.attlist-->]]>
-<!--end of initializer.module-->]]>
-
-<!ENTITY % constructorsynopsis.module "INCLUDE">
-<![%constructorsynopsis.module;[
-<!ENTITY % local.constructorsynopsis.attrib "">
-<!ENTITY % constructorsynopsis.role.attrib "%role.attrib;">
-
-<!ENTITY % constructorsynopsis.element "INCLUDE">
-<![%constructorsynopsis.element;[
-<!--doc:A syntax summary for a constructor.-->
-<!ELEMENT constructorsynopsis %ho; (modifier*,
- methodname?,
- (methodparam+|void?),
- exceptionname*)>
-<!--end of constructorsynopsis.element-->]]>
-
-<!ENTITY % constructorsynopsis.attlist "INCLUDE">
-<![%constructorsynopsis.attlist;[
-<!ATTLIST constructorsynopsis
- language CDATA #IMPLIED
- %common.attrib;
- %constructorsynopsis.role.attrib;
- %local.constructorsynopsis.attrib;
->
-<!--end of constructorsynopsis.attlist-->]]>
-<!--end of constructorsynopsis.module-->]]>
-
-<!ENTITY % destructorsynopsis.module "INCLUDE">
-<![%destructorsynopsis.module;[
-<!ENTITY % local.destructorsynopsis.attrib "">
-<!ENTITY % destructorsynopsis.role.attrib "%role.attrib;">
-
-<!ENTITY % destructorsynopsis.element "INCLUDE">
-<![%destructorsynopsis.element;[
-<!--doc:A syntax summary for a destructor.-->
-<!ELEMENT destructorsynopsis %ho; (modifier*,
- methodname?,
- (methodparam+|void?),
- exceptionname*)>
-<!--end of destructorsynopsis.element-->]]>
-
-<!ENTITY % destructorsynopsis.attlist "INCLUDE">
-<![%destructorsynopsis.attlist;[
-<!ATTLIST destructorsynopsis
- language CDATA #IMPLIED
- %common.attrib;
- %destructorsynopsis.role.attrib;
- %local.destructorsynopsis.attrib;
->
-<!--end of destructorsynopsis.attlist-->]]>
-<!--end of destructorsynopsis.module-->]]>
-
-<!ENTITY % methodsynopsis.module "INCLUDE">
-<![%methodsynopsis.module;[
-<!ENTITY % local.methodsynopsis.attrib "">
-<!ENTITY % methodsynopsis.role.attrib "%role.attrib;">
-
-<!ENTITY % methodsynopsis.element "INCLUDE">
-<![%methodsynopsis.element;[
-<!--doc:A syntax summary for a method.-->
-<!ELEMENT methodsynopsis %ho; (modifier*,
- (type|void)?,
- methodname,
- (methodparam+|void?),
- exceptionname*,
- modifier*)>
-<!--end of methodsynopsis.element-->]]>
-
-<!ENTITY % methodsynopsis.attlist "INCLUDE">
-<![%methodsynopsis.attlist;[
-<!ATTLIST methodsynopsis
- language CDATA #IMPLIED
- %common.attrib;
- %methodsynopsis.role.attrib;
- %local.methodsynopsis.attrib;
->
-<!--end of methodsynopsis.attlist-->]]>
-<!--end of methodsynopsis.module-->]]>
-
-<!ENTITY % methodname.module "INCLUDE">
-<![%methodname.module;[
-<!ENTITY % local.methodname.attrib "">
-<!ENTITY % methodname.role.attrib "%role.attrib;">
-
-<!ENTITY % methodname.element "INCLUDE">
-<![%methodname.element;[
-<!--doc:The name of a method.-->
-<!ELEMENT methodname %ho; (%smallcptr.char.mix;)*>
-<!--end of methodname.element-->]]>
-
-<!ENTITY % methodname.attlist "INCLUDE">
-<![%methodname.attlist;[
-<!ATTLIST methodname
- %common.attrib;
- %methodname.role.attrib;
- %local.methodname.attrib;
->
-<!--end of methodname.attlist-->]]>
-<!--end of methodname.module-->]]>
-
-<!ENTITY % methodparam.module "INCLUDE">
-<![%methodparam.module;[
-<!ENTITY % local.methodparam.attrib "">
-<!ENTITY % methodparam.role.attrib "%role.attrib;">
-
-<!ENTITY % methodparam.element "INCLUDE">
-<![%methodparam.element;[
-<!--doc:Parameters to a method.-->
-<!ELEMENT methodparam %ho; (modifier*,
- type?,
- ((parameter,initializer?)|funcparams),
- modifier*)>
-<!--end of methodparam.element-->]]>
-
-<!ENTITY % methodparam.attlist "INCLUDE">
-<![%methodparam.attlist;[
-<!ATTLIST methodparam
- choice (opt
- |req
- |plain) "req"
- rep (norepeat
- |repeat) "norepeat"
- %common.attrib;
- %methodparam.role.attrib;
- %local.methodparam.attrib;
->
-<!--end of methodparam.attlist-->]]>
-<!--end of methodparam.module-->]]>
-<!--end of classsynopsis.content.module-->]]>
-
-<!-- ...................................................................... -->
-<!-- Document information entities and elements ........................... -->
-
-<!-- The document information elements include some elements that are
- currently used only in the document hierarchy module. They are
- defined here so that they will be available for use in customized
- document hierarchies. -->
-
-<!-- .................................. -->
-
-<!ENTITY % docinfo.content.module "INCLUDE">
-<![%docinfo.content.module;[
-
-<!-- Ackno ............................ -->
-
-<!ENTITY % ackno.module "INCLUDE">
-<![%ackno.module;[
-<!ENTITY % local.ackno.attrib "">
-<!ENTITY % ackno.role.attrib "%role.attrib;">
-
-<!ENTITY % ackno.element "INCLUDE">
-<![%ackno.element;[
-<!--doc:Acknowledgements in an Article.-->
-<!ELEMENT ackno %ho; (%docinfo.char.mix;)*>
-<!--end of ackno.element-->]]>
-
-<!ENTITY % ackno.attlist "INCLUDE">
-<![%ackno.attlist;[
-<!ATTLIST ackno
- %common.attrib;
- %ackno.role.attrib;
- %local.ackno.attrib;
->
-<!--end of ackno.attlist-->]]>
-<!--end of ackno.module-->]]>
-
-<!-- Address .......................... -->
-
-<!ENTITY % address.content.module "INCLUDE">
-<![%address.content.module;[
-<!ENTITY % address.module "INCLUDE">
-<![%address.module;[
-<!ENTITY % local.address.attrib "">
-<!ENTITY % address.role.attrib "%role.attrib;">
-
-<!ENTITY % address.element "INCLUDE">
-<![%address.element;[
-<!--doc:A real-world address, generally a postal address.-->
-<!ELEMENT address %ho; (#PCDATA|personname|%person.ident.mix;
- |street|pob|postcode|city|state|country|phone
- |fax|email|otheraddr)*>
-<!--end of address.element-->]]>
-
-<!ENTITY % address.attlist "INCLUDE">
-<![%address.attlist;[
-<!ATTLIST address
- %linespecific.attrib;
- %common.attrib;
- %address.role.attrib;
- %local.address.attrib;
->
-<!--end of address.attlist-->]]>
-<!--end of address.module-->]]>
-
- <!ENTITY % street.module "INCLUDE">
- <![%street.module;[
- <!ENTITY % local.street.attrib "">
- <!ENTITY % street.role.attrib "%role.attrib;">
-
-<!ENTITY % street.element "INCLUDE">
-<![%street.element;[
-<!--doc:A street address in an address.-->
-<!ELEMENT street %ho; (%docinfo.char.mix;)*>
-<!--end of street.element-->]]>
-
-<!ENTITY % street.attlist "INCLUDE">
-<![%street.attlist;[
-<!ATTLIST street
- %common.attrib;
- %street.role.attrib;
- %local.street.attrib;
->
-<!--end of street.attlist-->]]>
- <!--end of street.module-->]]>
-
- <!ENTITY % pob.module "INCLUDE">
- <![%pob.module;[
- <!ENTITY % local.pob.attrib "">
- <!ENTITY % pob.role.attrib "%role.attrib;">
-
-<!ENTITY % pob.element "INCLUDE">
-<![%pob.element;[
-<!--doc:A post office box in an address.-->
-<!ELEMENT pob %ho; (%docinfo.char.mix;)*>
-<!--end of pob.element-->]]>
-
-<!ENTITY % pob.attlist "INCLUDE">
-<![%pob.attlist;[
-<!ATTLIST pob
- %common.attrib;
- %pob.role.attrib;
- %local.pob.attrib;
->
-<!--end of pob.attlist-->]]>
- <!--end of pob.module-->]]>
-
- <!ENTITY % postcode.module "INCLUDE">
- <![%postcode.module;[
- <!ENTITY % local.postcode.attrib "">
- <!ENTITY % postcode.role.attrib "%role.attrib;">
-
-<!ENTITY % postcode.element "INCLUDE">
-<![%postcode.element;[
-<!--doc:A postal code in an address.-->
-<!ELEMENT postcode %ho; (%docinfo.char.mix;)*>
-<!--end of postcode.element-->]]>
-
-<!ENTITY % postcode.attlist "INCLUDE">
-<![%postcode.attlist;[
-<!ATTLIST postcode
- %common.attrib;
- %postcode.role.attrib;
- %local.postcode.attrib;
->
-<!--end of postcode.attlist-->]]>
- <!--end of postcode.module-->]]>
-
- <!ENTITY % city.module "INCLUDE">
- <![%city.module;[
- <!ENTITY % local.city.attrib "">
- <!ENTITY % city.role.attrib "%role.attrib;">
-
-<!ENTITY % city.element "INCLUDE">
-<![%city.element;[
-<!--doc:The name of a city in an address.-->
-<!ELEMENT city %ho; (%docinfo.char.mix;)*>
-<!--end of city.element-->]]>
-
-<!ENTITY % city.attlist "INCLUDE">
-<![%city.attlist;[
-<!ATTLIST city
- %common.attrib;
- %city.role.attrib;
- %local.city.attrib;
->
-<!--end of city.attlist-->]]>
- <!--end of city.module-->]]>
-
- <!ENTITY % state.module "INCLUDE">
- <![%state.module;[
- <!ENTITY % local.state.attrib "">
- <!ENTITY % state.role.attrib "%role.attrib;">
-
-<!ENTITY % state.element "INCLUDE">
-<![%state.element;[
-<!--doc:A state or province in an address.-->
-<!ELEMENT state %ho; (%docinfo.char.mix;)*>
-<!--end of state.element-->]]>
-
-<!ENTITY % state.attlist "INCLUDE">
-<![%state.attlist;[
-<!ATTLIST state
- %common.attrib;
- %state.role.attrib;
- %local.state.attrib;
->
-<!--end of state.attlist-->]]>
- <!--end of state.module-->]]>
-
- <!ENTITY % country.module "INCLUDE">
- <![%country.module;[
- <!ENTITY % local.country.attrib "">
- <!ENTITY % country.role.attrib "%role.attrib;">
-
-<!ENTITY % country.element "INCLUDE">
-<![%country.element;[
-<!--doc:The name of a country.-->
-<!ELEMENT country %ho; (%docinfo.char.mix;)*>
-<!--end of country.element-->]]>
-
-<!ENTITY % country.attlist "INCLUDE">
-<![%country.attlist;[
-<!ATTLIST country
- %common.attrib;
- %country.role.attrib;
- %local.country.attrib;
->
-<!--end of country.attlist-->]]>
- <!--end of country.module-->]]>
-
- <!ENTITY % phone.module "INCLUDE">
- <![%phone.module;[
- <!ENTITY % local.phone.attrib "">
- <!ENTITY % phone.role.attrib "%role.attrib;">
-
-<!ENTITY % phone.element "INCLUDE">
-<![%phone.element;[
-<!--doc:A telephone number.-->
-<!ELEMENT phone %ho; (%docinfo.char.mix;)*>
-<!--end of phone.element-->]]>
-
-<!ENTITY % phone.attlist "INCLUDE">
-<![%phone.attlist;[
-<!ATTLIST phone
- %common.attrib;
- %phone.role.attrib;
- %local.phone.attrib;
->
-<!--end of phone.attlist-->]]>
- <!--end of phone.module-->]]>
-
- <!ENTITY % fax.module "INCLUDE">
- <![%fax.module;[
- <!ENTITY % local.fax.attrib "">
- <!ENTITY % fax.role.attrib "%role.attrib;">
-
-<!ENTITY % fax.element "INCLUDE">
-<![%fax.element;[
-<!--doc:A fax number.-->
-<!ELEMENT fax %ho; (%docinfo.char.mix;)*>
-<!--end of fax.element-->]]>
-
-<!ENTITY % fax.attlist "INCLUDE">
-<![%fax.attlist;[
-<!ATTLIST fax
- %common.attrib;
- %fax.role.attrib;
- %local.fax.attrib;
->
-<!--end of fax.attlist-->]]>
- <!--end of fax.module-->]]>
-
- <!-- Email (defined in the Inlines section, below)-->
-
- <!ENTITY % otheraddr.module "INCLUDE">
- <![%otheraddr.module;[
- <!ENTITY % local.otheraddr.attrib "">
- <!ENTITY % otheraddr.role.attrib "%role.attrib;">
-
-<!ENTITY % otheraddr.element "INCLUDE">
-<![%otheraddr.element;[
-<!--doc:Uncategorized information in address.-->
-<!ELEMENT otheraddr %ho; (%docinfo.char.mix;)*>
-<!--end of otheraddr.element-->]]>
-
-<!ENTITY % otheraddr.attlist "INCLUDE">
-<![%otheraddr.attlist;[
-<!ATTLIST otheraddr
- %common.attrib;
- %otheraddr.role.attrib;
- %local.otheraddr.attrib;
->
-<!--end of otheraddr.attlist-->]]>
- <!--end of otheraddr.module-->]]>
-<!--end of address.content.module-->]]>
-
-<!-- Affiliation ...................... -->
-
-<!ENTITY % affiliation.content.module "INCLUDE">
-<![%affiliation.content.module;[
-<!ENTITY % affiliation.module "INCLUDE">
-<![%affiliation.module;[
-<!ENTITY % local.affiliation.attrib "">
-<!ENTITY % affiliation.role.attrib "%role.attrib;">
-
-<!ENTITY % affiliation.element "INCLUDE">
-<![%affiliation.element;[
-<!--doc:The institutional affiliation of an individual.-->
-<!ELEMENT affiliation %ho; (shortaffil?, jobtitle*, orgname?, orgdiv*,
- address*)>
-<!--end of affiliation.element-->]]>
-
-<!ENTITY % affiliation.attlist "INCLUDE">
-<![%affiliation.attlist;[
-<!ATTLIST affiliation
- %common.attrib;
- %affiliation.role.attrib;
- %local.affiliation.attrib;
->
-<!--end of affiliation.attlist-->]]>
-<!--end of affiliation.module-->]]>
-
- <!ENTITY % shortaffil.module "INCLUDE">
- <![%shortaffil.module;[
- <!ENTITY % local.shortaffil.attrib "">
- <!ENTITY % shortaffil.role.attrib "%role.attrib;">
-
-<!ENTITY % shortaffil.element "INCLUDE">
-<![%shortaffil.element;[
-<!--doc:A brief description of an affiliation.-->
-<!ELEMENT shortaffil %ho; (%docinfo.char.mix;)*>
-<!--end of shortaffil.element-->]]>
-
-<!ENTITY % shortaffil.attlist "INCLUDE">
-<![%shortaffil.attlist;[
-<!ATTLIST shortaffil
- %common.attrib;
- %shortaffil.role.attrib;
- %local.shortaffil.attrib;
->
-<!--end of shortaffil.attlist-->]]>
- <!--end of shortaffil.module-->]]>
-
- <!ENTITY % jobtitle.module "INCLUDE">
- <![%jobtitle.module;[
- <!ENTITY % local.jobtitle.attrib "">
- <!ENTITY % jobtitle.role.attrib "%role.attrib;">
-
-<!ENTITY % jobtitle.element "INCLUDE">
-<![%jobtitle.element;[
-<!--doc:The title of an individual in an organization.-->
-<!ELEMENT jobtitle %ho; (%docinfo.char.mix;)*>
-<!--end of jobtitle.element-->]]>
-
-<!ENTITY % jobtitle.attlist "INCLUDE">
-<![%jobtitle.attlist;[
-<!ATTLIST jobtitle
- %common.attrib;
- %jobtitle.role.attrib;
- %local.jobtitle.attrib;
->
-<!--end of jobtitle.attlist-->]]>
- <!--end of jobtitle.module-->]]>
-
- <!-- OrgName (defined elsewhere in this section)-->
-
- <!ENTITY % orgdiv.module "INCLUDE">
- <![%orgdiv.module;[
- <!ENTITY % local.orgdiv.attrib "">
- <!ENTITY % orgdiv.role.attrib "%role.attrib;">
-
-<!ENTITY % orgdiv.element "INCLUDE">
-<![%orgdiv.element;[
-<!--doc:A division of an organization.-->
-<!ELEMENT orgdiv %ho; (%docinfo.char.mix;)*>
-<!--end of orgdiv.element-->]]>
-
-<!ENTITY % orgdiv.attlist "INCLUDE">
-<![%orgdiv.attlist;[
-<!ATTLIST orgdiv
- %common.attrib;
- %orgdiv.role.attrib;
- %local.orgdiv.attrib;
->
-<!--end of orgdiv.attlist-->]]>
- <!--end of orgdiv.module-->]]>
-
- <!-- Address (defined elsewhere in this section)-->
-<!--end of affiliation.content.module-->]]>
-
-<!-- ArtPageNums ...................... -->
-
-<!ENTITY % artpagenums.module "INCLUDE">
-<![%artpagenums.module;[
-<!ENTITY % local.artpagenums.attrib "">
-<!ENTITY % artpagenums.role.attrib "%role.attrib;">
-
-<!ENTITY % artpagenums.element "INCLUDE">
-<![%artpagenums.element;[
-<!--doc:The page numbers of an article as published.-->
-<!ELEMENT artpagenums %ho; (%docinfo.char.mix;)*>
-<!--end of artpagenums.element-->]]>
-
-<!ENTITY % artpagenums.attlist "INCLUDE">
-<![%artpagenums.attlist;[
-<!ATTLIST artpagenums
- %common.attrib;
- %artpagenums.role.attrib;
- %local.artpagenums.attrib;
->
-<!--end of artpagenums.attlist-->]]>
-<!--end of artpagenums.module-->]]>
-
-<!-- PersonName -->
-
-<!ENTITY % personname.module "INCLUDE">
-<![%personname.module;[
-<!ENTITY % local.personname.attrib "">
-<!ENTITY % personname.role.attrib "%role.attrib;">
-
-<!ENTITY % personname.element "INCLUDE">
-<![%personname.element;[
-<!--doc:The personal name of an individual.-->
-<!ELEMENT personname %ho; ((honorific|firstname|surname|lineage|othername)+)>
-<!--end of personname.element-->]]>
-
-<!ENTITY % personname.attlist "INCLUDE">
-<![%personname.attlist;[
-<!ATTLIST personname
- %common.attrib;
- %personname.role.attrib;
- %local.personname.attrib;
->
-<!--end of personname.attlist-->]]>
-<!--end of personname.module-->]]>
-
-<!-- Author ........................... -->
-
-<!ENTITY % author.module "INCLUDE">
-<![%author.module;[
-<!ENTITY % local.author.attrib "">
-<!ENTITY % author.role.attrib "%role.attrib;">
-
-<!ENTITY % author.element "INCLUDE">
-<![%author.element;[
-<!--doc:The name of an individual author.-->
-<!ELEMENT author %ho; ((personname|(%person.ident.mix;)+),(personblurb|email|address)*)>
-<!--end of author.element-->]]>
-
-<!ENTITY % author.attlist "INCLUDE">
-<![%author.attlist;[
-<!ATTLIST author
- %common.attrib;
- %author.role.attrib;
- %local.author.attrib;
->
-<!--end of author.attlist-->]]>
-<!--(see "Personal identity elements" for %person.ident.mix;)-->
-<!--end of author.module-->]]>
-
-<!-- AuthorGroup ...................... -->
-
-<!ENTITY % authorgroup.content.module "INCLUDE">
-<![%authorgroup.content.module;[
-<!ENTITY % authorgroup.module "INCLUDE">
-<![%authorgroup.module;[
-<!ENTITY % local.authorgroup.attrib "">
-<!ENTITY % authorgroup.role.attrib "%role.attrib;">
-
-<!ENTITY % authorgroup.element "INCLUDE">
-<![%authorgroup.element;[
-<!--doc:Wrapper for author information when a document has multiple authors or collabarators.-->
-<!ELEMENT authorgroup %ho; ((author|editor|collab|corpauthor|corpcredit|othercredit)+)>
-<!--end of authorgroup.element-->]]>
-
-<!ENTITY % authorgroup.attlist "INCLUDE">
-<![%authorgroup.attlist;[
-<!ATTLIST authorgroup
- %common.attrib;
- %authorgroup.role.attrib;
- %local.authorgroup.attrib;
->
-<!--end of authorgroup.attlist-->]]>
-<!--end of authorgroup.module-->]]>
-
- <!-- Author (defined elsewhere in this section)-->
- <!-- Editor (defined elsewhere in this section)-->
-
- <!ENTITY % collab.content.module "INCLUDE">
- <![%collab.content.module;[
- <!ENTITY % collab.module "INCLUDE">
- <![%collab.module;[
- <!ENTITY % local.collab.attrib "">
- <!ENTITY % collab.role.attrib "%role.attrib;">
-
-<!ENTITY % collab.element "INCLUDE">
-<![%collab.element;[
-<!--doc:Identifies a collaborator.-->
-<!ELEMENT collab %ho; (collabname, affiliation*)>
-<!--end of collab.element-->]]>
-
-<!ENTITY % collab.attlist "INCLUDE">
-<![%collab.attlist;[
-<!ATTLIST collab
- %common.attrib;
- %collab.role.attrib;
- %local.collab.attrib;
->
-<!--end of collab.attlist-->]]>
- <!--end of collab.module-->]]>
-
- <!ENTITY % collabname.module "INCLUDE">
- <![%collabname.module;[
- <!ENTITY % local.collabname.attrib "">
- <!ENTITY % collabname.role.attrib "%role.attrib;">
-
-<!ENTITY % collabname.element "INCLUDE">
-<![%collabname.element;[
-<!--doc:The name of a collaborator.-->
-<!ELEMENT collabname %ho; (%docinfo.char.mix;)*>
-<!--end of collabname.element-->]]>
-
-<!ENTITY % collabname.attlist "INCLUDE">
-<![%collabname.attlist;[
-<!ATTLIST collabname
- %common.attrib;
- %collabname.role.attrib;
- %local.collabname.attrib;
->
-<!--end of collabname.attlist-->]]>
- <!--end of collabname.module-->]]>
-
- <!-- Affiliation (defined elsewhere in this section)-->
- <!--end of collab.content.module-->]]>
-
- <!-- CorpAuthor (defined elsewhere in this section)-->
- <!-- OtherCredit (defined elsewhere in this section)-->
-
-<!--end of authorgroup.content.module-->]]>
-
-<!-- AuthorInitials ................... -->
-
-<!ENTITY % authorinitials.module "INCLUDE">
-<![%authorinitials.module;[
-<!ENTITY % local.authorinitials.attrib "">
-<!ENTITY % authorinitials.role.attrib "%role.attrib;">
-
-<!ENTITY % authorinitials.element "INCLUDE">
-<![%authorinitials.element;[
-<!--doc:The initials or other short identifier for an author.-->
-<!ELEMENT authorinitials %ho; (%docinfo.char.mix;)*>
-<!--end of authorinitials.element-->]]>
-
-<!ENTITY % authorinitials.attlist "INCLUDE">
-<![%authorinitials.attlist;[
-<!ATTLIST authorinitials
- %common.attrib;
- %authorinitials.role.attrib;
- %local.authorinitials.attrib;
->
-<!--end of authorinitials.attlist-->]]>
-<!--end of authorinitials.module-->]]>
-
-<!-- ConfGroup ........................ -->
-
-<!ENTITY % confgroup.content.module "INCLUDE">
-<![%confgroup.content.module;[
-<!ENTITY % confgroup.module "INCLUDE">
-<![%confgroup.module;[
-<!ENTITY % local.confgroup.attrib "">
-<!ENTITY % confgroup.role.attrib "%role.attrib;">
-
-<!ENTITY % confgroup.element "INCLUDE">
-<![%confgroup.element;[
-<!--doc:A wrapper for document meta-information about a conference.-->
-<!ELEMENT confgroup %ho; ((confdates|conftitle|confnum|address|confsponsor)*)>
-<!--end of confgroup.element-->]]>
-
-<!ENTITY % confgroup.attlist "INCLUDE">
-<![%confgroup.attlist;[
-<!ATTLIST confgroup
- %common.attrib;
- %confgroup.role.attrib;
- %local.confgroup.attrib;
->
-<!--end of confgroup.attlist-->]]>
-<!--end of confgroup.module-->]]>
-
- <!ENTITY % confdates.module "INCLUDE">
- <![%confdates.module;[
- <!ENTITY % local.confdates.attrib "">
- <!ENTITY % confdates.role.attrib "%role.attrib;">
-
-<!ENTITY % confdates.element "INCLUDE">
-<![%confdates.element;[
-<!--doc:The dates of a conference for which a document was written.-->
-<!ELEMENT confdates %ho; (%docinfo.char.mix;)*>
-<!--end of confdates.element-->]]>
-
-<!ENTITY % confdates.attlist "INCLUDE">
-<![%confdates.attlist;[
-<!ATTLIST confdates
- %common.attrib;
- %confdates.role.attrib;
- %local.confdates.attrib;
->
-<!--end of confdates.attlist-->]]>
- <!--end of confdates.module-->]]>
-
- <!ENTITY % conftitle.module "INCLUDE">
- <![%conftitle.module;[
- <!ENTITY % local.conftitle.attrib "">
- <!ENTITY % conftitle.role.attrib "%role.attrib;">
-
-<!ENTITY % conftitle.element "INCLUDE">
-<![%conftitle.element;[
-<!--doc:The title of a conference for which a document was written.-->
-<!ELEMENT conftitle %ho; (%docinfo.char.mix;)*>
-<!--end of conftitle.element-->]]>
-
-<!ENTITY % conftitle.attlist "INCLUDE">
-<![%conftitle.attlist;[
-<!ATTLIST conftitle
- %common.attrib;
- %conftitle.role.attrib;
- %local.conftitle.attrib;
->
-<!--end of conftitle.attlist-->]]>
- <!--end of conftitle.module-->]]>
-
- <!ENTITY % confnum.module "INCLUDE">
- <![%confnum.module;[
- <!ENTITY % local.confnum.attrib "">
- <!ENTITY % confnum.role.attrib "%role.attrib;">
-
-<!ENTITY % confnum.element "INCLUDE">
-<![%confnum.element;[
-<!--doc:An identifier, frequently numerical, associated with a conference for which a document was written.-->
-<!ELEMENT confnum %ho; (%docinfo.char.mix;)*>
-<!--end of confnum.element-->]]>
-
-<!ENTITY % confnum.attlist "INCLUDE">
-<![%confnum.attlist;[
-<!ATTLIST confnum
- %common.attrib;
- %confnum.role.attrib;
- %local.confnum.attrib;
->
-<!--end of confnum.attlist-->]]>
- <!--end of confnum.module-->]]>
-
- <!-- Address (defined elsewhere in this section)-->
-
- <!ENTITY % confsponsor.module "INCLUDE">
- <![%confsponsor.module;[
- <!ENTITY % local.confsponsor.attrib "">
- <!ENTITY % confsponsor.role.attrib "%role.attrib;">
-
-<!ENTITY % confsponsor.element "INCLUDE">
-<![%confsponsor.element;[
-<!--doc:The sponsor of a conference for which a document was written.-->
-<!ELEMENT confsponsor %ho; (%docinfo.char.mix;)*>
-<!--end of confsponsor.element-->]]>
-
-<!ENTITY % confsponsor.attlist "INCLUDE">
-<![%confsponsor.attlist;[
-<!ATTLIST confsponsor
- %common.attrib;
- %confsponsor.role.attrib;
- %local.confsponsor.attrib;
->
-<!--end of confsponsor.attlist-->]]>
- <!--end of confsponsor.module-->]]>
-<!--end of confgroup.content.module-->]]>
-
-<!-- ContractNum ...................... -->
-
-<!ENTITY % contractnum.module "INCLUDE">
-<![%contractnum.module;[
-<!ENTITY % local.contractnum.attrib "">
-<!ENTITY % contractnum.role.attrib "%role.attrib;">
-
-<!ENTITY % contractnum.element "INCLUDE">
-<![%contractnum.element;[
-<!--doc:The contract number of a document.-->
-<!ELEMENT contractnum %ho; (%docinfo.char.mix;)*>
-<!--end of contractnum.element-->]]>
-
-<!ENTITY % contractnum.attlist "INCLUDE">
-<![%contractnum.attlist;[
-<!ATTLIST contractnum
- %common.attrib;
- %contractnum.role.attrib;
- %local.contractnum.attrib;
->
-<!--end of contractnum.attlist-->]]>
-<!--end of contractnum.module-->]]>
-
-<!-- ContractSponsor .................. -->
-
-<!ENTITY % contractsponsor.module "INCLUDE">
-<![%contractsponsor.module;[
-<!ENTITY % local.contractsponsor.attrib "">
-<!ENTITY % contractsponsor.role.attrib "%role.attrib;">
-
-<!ENTITY % contractsponsor.element "INCLUDE">
-<![%contractsponsor.element;[
-<!--doc:The sponsor of a contract.-->
-<!ELEMENT contractsponsor %ho; (%docinfo.char.mix;)*>
-<!--end of contractsponsor.element-->]]>
-
-<!ENTITY % contractsponsor.attlist "INCLUDE">
-<![%contractsponsor.attlist;[
-<!ATTLIST contractsponsor
- %common.attrib;
- %contractsponsor.role.attrib;
- %local.contractsponsor.attrib;
->
-<!--end of contractsponsor.attlist-->]]>
-<!--end of contractsponsor.module-->]]>
-
-<!-- Copyright ........................ -->
-
-<!ENTITY % copyright.content.module "INCLUDE">
-<![%copyright.content.module;[
-<!ENTITY % copyright.module "INCLUDE">
-<![%copyright.module;[
-<!ENTITY % local.copyright.attrib "">
-<!ENTITY % copyright.role.attrib "%role.attrib;">
-
-<!ENTITY % copyright.element "INCLUDE">
-<![%copyright.element;[
-<!--doc:Copyright information about a document.-->
-<!ELEMENT copyright %ho; (year+, holder*)>
-<!--end of copyright.element-->]]>
-
-<!ENTITY % copyright.attlist "INCLUDE">
-<![%copyright.attlist;[
-<!ATTLIST copyright
- %common.attrib;
- %copyright.role.attrib;
- %local.copyright.attrib;
->
-<!--end of copyright.attlist-->]]>
-<!--end of copyright.module-->]]>
-
- <!ENTITY % year.module "INCLUDE">
- <![%year.module;[
- <!ENTITY % local.year.attrib "">
- <!ENTITY % year.role.attrib "%role.attrib;">
-
-<!ENTITY % year.element "INCLUDE">
-<![%year.element;[
-<!--doc:The year of publication of a document.-->
-<!ELEMENT year %ho; (%docinfo.char.mix;)*>
-<!--end of year.element-->]]>
-
-<!ENTITY % year.attlist "INCLUDE">
-<![%year.attlist;[
-<!ATTLIST year
- %common.attrib;
- %year.role.attrib;
- %local.year.attrib;
->
-<!--end of year.attlist-->]]>
- <!--end of year.module-->]]>
-
- <!ENTITY % holder.module "INCLUDE">
- <![%holder.module;[
- <!ENTITY % local.holder.attrib "">
- <!ENTITY % holder.role.attrib "%role.attrib;">
-
-<!ENTITY % holder.element "INCLUDE">
-<![%holder.element;[
-<!--doc:The name of the individual or organization that holds a copyright.-->
-<!ELEMENT holder %ho; (%docinfo.char.mix;)*>
-<!--end of holder.element-->]]>
-
-<!ENTITY % holder.attlist "INCLUDE">
-<![%holder.attlist;[
-<!ATTLIST holder
- %common.attrib;
- %holder.role.attrib;
- %local.holder.attrib;
->
-<!--end of holder.attlist-->]]>
- <!--end of holder.module-->]]>
-<!--end of copyright.content.module-->]]>
-
-<!-- CorpAuthor ....................... -->
-
-<!ENTITY % corpauthor.module "INCLUDE">
-<![%corpauthor.module;[
-<!ENTITY % local.corpauthor.attrib "">
-<!ENTITY % corpauthor.role.attrib "%role.attrib;">
-
-<!ENTITY % corpauthor.element "INCLUDE">
-<![%corpauthor.element;[
-<!--doc:A corporate author, as opposed to an individual.-->
-<!ELEMENT corpauthor %ho; (%docinfo.char.mix;)*>
-<!--end of corpauthor.element-->]]>
-
-<!ENTITY % corpauthor.attlist "INCLUDE">
-<![%corpauthor.attlist;[
-<!ATTLIST corpauthor
- %common.attrib;
- %corpauthor.role.attrib;
- %local.corpauthor.attrib;
->
-<!--end of corpauthor.attlist-->]]>
-<!--end of corpauthor.module-->]]>
-
-<!-- CorpCredit ...................... -->
-
-<!ENTITY % corpcredit.module "INCLUDE">
-<![%corpcredit.module;[
-<!ENTITY % local.corpcredit.attrib "">
-<!ENTITY % corpcredit.role.attrib "%role.attrib;">
-
-<!ENTITY % corpcredit.element "INCLUDE">
-<![%corpcredit.element;[
-<!--doc:A corporation or organization credited in a document.-->
-<!ELEMENT corpcredit %ho; (%docinfo.char.mix;)*>
-<!--end of corpcredit.element-->]]>
-
-<!ENTITY % corpcredit.attlist "INCLUDE">
-<![%corpcredit.attlist;[
-<!ATTLIST corpcredit
- class (graphicdesigner
- |productioneditor
- |copyeditor
- |technicaleditor
- |translator
- |other) #IMPLIED
- %common.attrib;
- %corpcredit.role.attrib;
- %local.corpcredit.attrib;
->
-<!--end of corpcredit.attlist-->]]>
-<!--end of corpcredit.module-->]]>
-
-<!-- CorpName ......................... -->
-
-<!ENTITY % corpname.module "INCLUDE">
-<![%corpname.module;[
-<!ENTITY % local.corpname.attrib "">
-
-<!ENTITY % corpname.element "INCLUDE">
-<![%corpname.element;[
-<!--doc:The name of a corporation.-->
-<!ELEMENT corpname %ho; (%docinfo.char.mix;)*>
-<!--end of corpname.element-->]]>
-<!ENTITY % corpname.role.attrib "%role.attrib;">
-
-<!ENTITY % corpname.attlist "INCLUDE">
-<![%corpname.attlist;[
-<!ATTLIST corpname
- %common.attrib;
- %corpname.role.attrib;
- %local.corpname.attrib;
->
-<!--end of corpname.attlist-->]]>
-<!--end of corpname.module-->]]>
-
-<!-- Date ............................. -->
-
-<!ENTITY % date.module "INCLUDE">
-<![%date.module;[
-<!ENTITY % local.date.attrib "">
-<!ENTITY % date.role.attrib "%role.attrib;">
-
-<!ENTITY % date.element "INCLUDE">
-<![%date.element;[
-<!--doc:The date of publication or revision of a document.-->
-<!ELEMENT date %ho; (%docinfo.char.mix;)*>
-<!--end of date.element-->]]>
-
-<!ENTITY % date.attlist "INCLUDE">
-<![%date.attlist;[
-<!ATTLIST date
- %common.attrib;
- %date.role.attrib;
- %local.date.attrib;
->
-<!--end of date.attlist-->]]>
-<!--end of date.module-->]]>
-
-<!-- Edition .......................... -->
-
-<!ENTITY % edition.module "INCLUDE">
-<![%edition.module;[
-<!ENTITY % local.edition.attrib "">
-<!ENTITY % edition.role.attrib "%role.attrib;">
-
-<!ENTITY % edition.element "INCLUDE">
-<![%edition.element;[
-<!--doc:The name or number of an edition of a document.-->
-<!ELEMENT edition %ho; (%docinfo.char.mix;)*>
-<!--end of edition.element-->]]>
-
-<!ENTITY % edition.attlist "INCLUDE">
-<![%edition.attlist;[
-<!ATTLIST edition
- %common.attrib;
- %edition.role.attrib;
- %local.edition.attrib;
->
-<!--end of edition.attlist-->]]>
-<!--end of edition.module-->]]>
-
-<!-- Editor ........................... -->
-
-<!ENTITY % editor.module "INCLUDE">
-<![%editor.module;[
-<!ENTITY % local.editor.attrib "">
-<!ENTITY % editor.role.attrib "%role.attrib;">
-
-<!ENTITY % editor.element "INCLUDE">
-<![%editor.element;[
-<!--doc:The name of the editor of a document.-->
-<!ELEMENT editor %ho; ((personname|(%person.ident.mix;)+),(personblurb|email|address)*)>
-<!--end of editor.element-->]]>
-
-<!ENTITY % editor.attlist "INCLUDE">
-<![%editor.attlist;[
-<!ATTLIST editor
- %common.attrib;
- %editor.role.attrib;
- %local.editor.attrib;
->
-<!--end of editor.attlist-->]]>
- <!--(see "Personal identity elements" for %person.ident.mix;)-->
-<!--end of editor.module-->]]>
-
-<!-- ISBN ............................. -->
-
-<!ENTITY % isbn.module "INCLUDE">
-<![%isbn.module;[
-<!ENTITY % local.isbn.attrib "">
-<!ENTITY % isbn.role.attrib "%role.attrib;">
-
-<!ENTITY % isbn.element "INCLUDE">
-<![%isbn.element;[
-<!--doc:The International Standard Book Number of a document.-->
-<!ELEMENT isbn %ho; (%docinfo.char.mix;)*>
-<!--end of isbn.element-->]]>
-
-<!ENTITY % isbn.attlist "INCLUDE">
-<![%isbn.attlist;[
-<!ATTLIST isbn
- %common.attrib;
- %isbn.role.attrib;
- %local.isbn.attrib;
->
-<!--end of isbn.attlist-->]]>
-<!--end of isbn.module-->]]>
-
-<!-- ISSN ............................. -->
-
-<!ENTITY % issn.module "INCLUDE">
-<![%issn.module;[
-<!ENTITY % local.issn.attrib "">
-<!ENTITY % issn.role.attrib "%role.attrib;">
-
-<!ENTITY % issn.element "INCLUDE">
-<![%issn.element;[
-<!--doc:The International Standard Serial Number of a periodical.-->
-<!ELEMENT issn %ho; (%docinfo.char.mix;)*>
-<!--end of issn.element-->]]>
-
-<!ENTITY % issn.attlist "INCLUDE">
-<![%issn.attlist;[
-<!ATTLIST issn
- %common.attrib;
- %issn.role.attrib;
- %local.issn.attrib;
->
-<!--end of issn.attlist-->]]>
-<!--end of issn.module-->]]>
-
-<!-- BiblioId ................. -->
-<!ENTITY % biblio.class.attrib
- "class (uri
- |doi
- |isbn
- |isrn
- |issn
- |libraryofcongress
- |pubnumber
- |other) #IMPLIED
- otherclass CDATA #IMPLIED"
->
-
-<!ENTITY % biblioid.module "INCLUDE">
-<![%biblioid.module;[
-<!ENTITY % local.biblioid.attrib "">
-<!ENTITY % biblioid.role.attrib "%role.attrib;">
-
-<!ENTITY % biblioid.element "INCLUDE">
-<![%biblioid.element;[
-<!--doc:An identifier for a document.-->
-<!ELEMENT biblioid %ho; (%docinfo.char.mix;)*>
-<!--end of biblioid.element-->]]>
-
-<!ENTITY % biblioid.attlist "INCLUDE">
-<![%biblioid.attlist;[
-<!ATTLIST biblioid
- %biblio.class.attrib;
- %common.attrib;
- %biblioid.role.attrib;
- %local.biblioid.attrib;
->
-<!--end of biblioid.attlist-->]]>
-<!--end of biblioid.module-->]]>
-
-<!-- CiteBiblioId ................. -->
-
-<!ENTITY % citebiblioid.module "INCLUDE">
-<![%citebiblioid.module;[
-<!ENTITY % local.citebiblioid.attrib "">
-<!ENTITY % citebiblioid.role.attrib "%role.attrib;">
-
-<!ENTITY % citebiblioid.element "INCLUDE">
-<![%citebiblioid.element;[
-<!--doc:A citation of a bibliographic identifier.-->
-<!ELEMENT citebiblioid %ho; (%docinfo.char.mix;)*>
-<!--end of citebiblioid.element-->]]>
-
-<!ENTITY % citebiblioid.attlist "INCLUDE">
-<![%citebiblioid.attlist;[
-<!ATTLIST citebiblioid
- %biblio.class.attrib;
- %common.attrib;
- %citebiblioid.role.attrib;
- %local.citebiblioid.attrib;
->
-<!--end of citebiblioid.attlist-->]]>
-<!--end of citebiblioid.module-->]]>
-
-<!-- BiblioSource ................. -->
-
-<!ENTITY % bibliosource.module "INCLUDE">
-<![%bibliosource.module;[
-<!ENTITY % local.bibliosource.attrib "">
-<!ENTITY % bibliosource.role.attrib "%role.attrib;">
-
-<!ENTITY % bibliosource.element "INCLUDE">
-<![%bibliosource.element;[
-<!--doc:The source of a document.-->
-<!ELEMENT bibliosource %ho; (%docinfo.char.mix;)*>
-<!--end of bibliosource.element-->]]>
-
-<!ENTITY % bibliosource.attlist "INCLUDE">
-<![%bibliosource.attlist;[
-<!ATTLIST bibliosource
- %biblio.class.attrib;
- %common.attrib;
- %bibliosource.role.attrib;
- %local.bibliosource.attrib;
->
-<!--end of bibliosource.attlist-->]]>
-<!--end of bibliosource.module-->]]>
-
-<!-- BiblioRelation ................. -->
-
-<!ENTITY % bibliorelation.module "INCLUDE">
-<![%bibliorelation.module;[
-<!ENTITY % local.bibliorelation.attrib "">
-<!ENTITY % local.bibliorelation.types "">
-
-<!ENTITY % bibliorelation.type.attrib
- "type (isversionof
- |hasversion
- |isreplacedby
- |replaces
- |isrequiredby
- |requires
- |ispartof
- |haspart
- |isreferencedby
- |references
- |isformatof
- |hasformat
- |othertype
- %local.bibliorelation.types;) #IMPLIED
- othertype CDATA #IMPLIED
-">
-
-<!ENTITY % bibliorelation.role.attrib "%role.attrib;">
-
-<!ENTITY % bibliorelation.element "INCLUDE">
-<![%bibliorelation.element;[
-<!--doc:The relationship of a document to another.-->
-<!ELEMENT bibliorelation %ho; (%docinfo.char.mix;)*>
-<!--end of bibliorelation.element-->]]>
-
-<!ENTITY % bibliorelation.attlist "INCLUDE">
-<![%bibliorelation.attlist;[
-<!ATTLIST bibliorelation
- %biblio.class.attrib;
- %bibliorelation.type.attrib;
- %common.attrib;
- %bibliorelation.role.attrib;
- %local.bibliorelation.attrib;
->
-<!--end of bibliorelation.attlist-->]]>
-<!--end of bibliorelation.module-->]]>
-
-<!-- BiblioCoverage ................. -->
-
-<!ENTITY % bibliocoverage.module "INCLUDE">
-<![%bibliocoverage.module;[
-<!ENTITY % local.bibliocoverage.attrib "">
-<!ENTITY % bibliocoverage.role.attrib "%role.attrib;">
-
-<!ENTITY % bibliocoverage.element "INCLUDE">
-<![%bibliocoverage.element;[
-<!--doc:The spatial or temporal coverage of a document.-->
-<!ELEMENT bibliocoverage %ho; (%docinfo.char.mix;)*>
-<!--end of bibliocoverage.element-->]]>
-
-<!ENTITY % bibliocoverage.attlist "INCLUDE">
-<![%bibliocoverage.attlist;[
-<!ATTLIST bibliocoverage
- spatial (dcmipoint|iso3166|dcmibox|tgn|otherspatial) #IMPLIED
- otherspatial CDATA #IMPLIED
- temporal (dcmiperiod|w3c-dtf|othertemporal) #IMPLIED
- othertemporal CDATA #IMPLIED
- %common.attrib;
- %bibliocoverage.role.attrib;
- %local.bibliocoverage.attrib;
->
-<!--end of bibliocoverage.attlist-->]]>
-<!--end of bibliocoverage.module-->]]>
-
-<!-- InvPartNumber .................... -->
-
-<!ENTITY % invpartnumber.module "INCLUDE">
-<![%invpartnumber.module;[
-<!ENTITY % local.invpartnumber.attrib "">
-<!ENTITY % invpartnumber.role.attrib "%role.attrib;">
-
-<!ENTITY % invpartnumber.element "INCLUDE">
-<![%invpartnumber.element;[
-<!--doc:An inventory part number.-->
-<!ELEMENT invpartnumber %ho; (%docinfo.char.mix;)*>
-<!--end of invpartnumber.element-->]]>
-
-<!ENTITY % invpartnumber.attlist "INCLUDE">
-<![%invpartnumber.attlist;[
-<!ATTLIST invpartnumber
- %common.attrib;
- %invpartnumber.role.attrib;
- %local.invpartnumber.attrib;
->
-<!--end of invpartnumber.attlist-->]]>
-<!--end of invpartnumber.module-->]]>
-
-<!-- IssueNum ......................... -->
-
-<!ENTITY % issuenum.module "INCLUDE">
-<![%issuenum.module;[
-<!ENTITY % local.issuenum.attrib "">
-<!ENTITY % issuenum.role.attrib "%role.attrib;">
-
-<!ENTITY % issuenum.element "INCLUDE">
-<![%issuenum.element;[
-<!--doc:The number of an issue of a journal.-->
-<!ELEMENT issuenum %ho; (%docinfo.char.mix;)*>
-<!--end of issuenum.element-->]]>
-
-<!ENTITY % issuenum.attlist "INCLUDE">
-<![%issuenum.attlist;[
-<!ATTLIST issuenum
- %common.attrib;
- %issuenum.role.attrib;
- %local.issuenum.attrib;
->
-<!--end of issuenum.attlist-->]]>
-<!--end of issuenum.module-->]]>
-
-<!-- LegalNotice ...................... -->
-
-<!ENTITY % legalnotice.module "INCLUDE">
-<![%legalnotice.module;[
-<!ENTITY % local.legalnotice.attrib "">
-<!ENTITY % legalnotice.role.attrib "%role.attrib;">
-
-<!ENTITY % legalnotice.element "INCLUDE">
-<![%legalnotice.element;[
-<!--doc:A statement of legal obligations or requirements.-->
-<!ELEMENT legalnotice %ho; (blockinfo?, title?, (%legalnotice.mix;)+)
- %formal.exclusion;>
-<!--end of legalnotice.element-->]]>
-
-<!ENTITY % legalnotice.attlist "INCLUDE">
-<![%legalnotice.attlist;[
-<!ATTLIST legalnotice
- %common.attrib;
- %legalnotice.role.attrib;
- %local.legalnotice.attrib;
->
-<!--end of legalnotice.attlist-->]]>
-<!--end of legalnotice.module-->]]>
-
-<!-- ModeSpec ......................... -->
-
-<!ENTITY % modespec.module "INCLUDE">
-<![%modespec.module;[
-<!ENTITY % local.modespec.attrib "">
-<!ENTITY % modespec.role.attrib "%role.attrib;">
-
-<!ENTITY % modespec.element "INCLUDE">
-<![%modespec.element;[
-<!--doc:Application-specific information necessary for the completion of an OLink.-->
-<!ELEMENT modespec %ho; (%docinfo.char.mix;)*
- %ubiq.exclusion;>
-<!--end of modespec.element-->]]>
-
-<!-- Application: Type of action required for completion
- of the links to which the ModeSpec is relevant (e.g.,
- retrieval query) -->
-
-
-<!ENTITY % modespec.attlist "INCLUDE">
-<![%modespec.attlist;[
-<!ATTLIST modespec
- application NOTATION
- (%notation.class;) #IMPLIED
- %common.attrib;
- %modespec.role.attrib;
- %local.modespec.attrib;
->
-<!--end of modespec.attlist-->]]>
-<!--end of modespec.module-->]]>
-
-<!-- OrgName .......................... -->
-
-<!ENTITY % orgname.module "INCLUDE">
-<![%orgname.module;[
-<!ENTITY % local.orgname.attrib "">
-<!ENTITY % orgname.role.attrib "%role.attrib;">
-
-<!ENTITY % orgname.element "INCLUDE">
-<![%orgname.element;[
-<!--doc:The name of an organization other than a corporation.-->
-<!ELEMENT orgname %ho; (%docinfo.char.mix;)*>
-<!--end of orgname.element-->]]>
-
-<!ENTITY % orgname.attlist "INCLUDE">
-<![%orgname.attlist;[
-<!ATTLIST orgname
- %common.attrib;
- class (corporation|nonprofit|consortium|informal|other) #IMPLIED
- otherclass CDATA #IMPLIED
- %orgname.role.attrib;
- %local.orgname.attrib;
->
-<!--end of orgname.attlist-->]]>
-<!--end of orgname.module-->]]>
-
-<!-- OtherCredit ...................... -->
-
-<!ENTITY % othercredit.module "INCLUDE">
-<![%othercredit.module;[
-<!ENTITY % local.othercredit.attrib "">
-<!ENTITY % othercredit.role.attrib "%role.attrib;">
-
-<!ENTITY % othercredit.element "INCLUDE">
-<![%othercredit.element;[
-<!--doc:A person or entity, other than an author or editor, credited in a document.-->
-<!ELEMENT othercredit %ho; ((personname|(%person.ident.mix;)+),
- (personblurb|email|address)*)>
-<!--end of othercredit.element-->]]>
-
-<!ENTITY % othercredit.attlist "INCLUDE">
-<![%othercredit.attlist;[
-<!ATTLIST othercredit
- class (graphicdesigner
- |productioneditor
- |copyeditor
- |technicaleditor
- |translator
- |other) #IMPLIED
- %common.attrib;
- %othercredit.role.attrib;
- %local.othercredit.attrib;
->
-<!--end of othercredit.attlist-->]]>
- <!--(see "Personal identity elements" for %person.ident.mix;)-->
-<!--end of othercredit.module-->]]>
-
-<!-- PageNums ......................... -->
-
-<!ENTITY % pagenums.module "INCLUDE">
-<![%pagenums.module;[
-<!ENTITY % local.pagenums.attrib "">
-<!ENTITY % pagenums.role.attrib "%role.attrib;">
-
-<!ENTITY % pagenums.element "INCLUDE">
-<![%pagenums.element;[
-<!--doc:The numbers of the pages in a book, for use in a bibliographic entry.-->
-<!ELEMENT pagenums %ho; (%docinfo.char.mix;)*>
-<!--end of pagenums.element-->]]>
-
-<!ENTITY % pagenums.attlist "INCLUDE">
-<![%pagenums.attlist;[
-<!ATTLIST pagenums
- %common.attrib;
- %pagenums.role.attrib;
- %local.pagenums.attrib;
->
-<!--end of pagenums.attlist-->]]>
-<!--end of pagenums.module-->]]>
-
-<!-- Personal identity elements ....... -->
-
-<!-- These elements are used only within Author, Editor, and
-OtherCredit. -->
-
-<!ENTITY % person.ident.module "INCLUDE">
-<![%person.ident.module;[
- <!ENTITY % contrib.module "INCLUDE">
- <![%contrib.module;[
- <!ENTITY % local.contrib.attrib "">
- <!ENTITY % contrib.role.attrib "%role.attrib;">
-
-<!ENTITY % contrib.element "INCLUDE">
-<![%contrib.element;[
-<!--doc:A summary of the contributions made to a document by a credited source.-->
-<!ELEMENT contrib %ho; (%docinfo.char.mix;)*>
-<!--end of contrib.element-->]]>
-
-<!ENTITY % contrib.attlist "INCLUDE">
-<![%contrib.attlist;[
-<!ATTLIST contrib
- %common.attrib;
- %contrib.role.attrib;
- %local.contrib.attrib;
->
-<!--end of contrib.attlist-->]]>
- <!--end of contrib.module-->]]>
-
- <!ENTITY % firstname.module "INCLUDE">
- <![%firstname.module;[
- <!ENTITY % local.firstname.attrib "">
- <!ENTITY % firstname.role.attrib "%role.attrib;">
-
-<!ENTITY % firstname.element "INCLUDE">
-<![%firstname.element;[
-<!--doc:The first name of a person.-->
-<!ELEMENT firstname %ho; (%docinfo.char.mix;)*>
-<!--end of firstname.element-->]]>
-
-<!ENTITY % firstname.attlist "INCLUDE">
-<![%firstname.attlist;[
-<!ATTLIST firstname
- %common.attrib;
- %firstname.role.attrib;
- %local.firstname.attrib;
->
-<!--end of firstname.attlist-->]]>
- <!--end of firstname.module-->]]>
-
- <!ENTITY % honorific.module "INCLUDE">
- <![%honorific.module;[
- <!ENTITY % local.honorific.attrib "">
- <!ENTITY % honorific.role.attrib "%role.attrib;">
-
-<!ENTITY % honorific.element "INCLUDE">
-<![%honorific.element;[
-<!--doc:The title of a person.-->
-<!ELEMENT honorific %ho; (%docinfo.char.mix;)*>
-<!--end of honorific.element-->]]>
-
-<!ENTITY % honorific.attlist "INCLUDE">
-<![%honorific.attlist;[
-<!ATTLIST honorific
- %common.attrib;
- %honorific.role.attrib;
- %local.honorific.attrib;
->
-<!--end of honorific.attlist-->]]>
- <!--end of honorific.module-->]]>
-
- <!ENTITY % lineage.module "INCLUDE">
- <![%lineage.module;[
- <!ENTITY % local.lineage.attrib "">
- <!ENTITY % lineage.role.attrib "%role.attrib;">
-
-<!ENTITY % lineage.element "INCLUDE">
-<![%lineage.element;[
-<!--doc:The portion of a person's name indicating a relationship to ancestors.-->
-<!ELEMENT lineage %ho; (%docinfo.char.mix;)*>
-<!--end of lineage.element-->]]>
-
-<!ENTITY % lineage.attlist "INCLUDE">
-<![%lineage.attlist;[
-<!ATTLIST lineage
- %common.attrib;
- %lineage.role.attrib;
- %local.lineage.attrib;
->
-<!--end of lineage.attlist-->]]>
- <!--end of lineage.module-->]]>
-
- <!ENTITY % othername.module "INCLUDE">
- <![%othername.module;[
- <!ENTITY % local.othername.attrib "">
- <!ENTITY % othername.role.attrib "%role.attrib;">
-
-<!ENTITY % othername.element "INCLUDE">
-<![%othername.element;[
-<!--doc:A component of a persons name that is not a first name, surname, or lineage.-->
-<!ELEMENT othername %ho; (%docinfo.char.mix;)*>
-<!--end of othername.element-->]]>
-
-<!ENTITY % othername.attlist "INCLUDE">
-<![%othername.attlist;[
-<!ATTLIST othername
- %common.attrib;
- %othername.role.attrib;
- %local.othername.attrib;
->
-<!--end of othername.attlist-->]]>
- <!--end of othername.module-->]]>
-
- <!ENTITY % surname.module "INCLUDE">
- <![%surname.module;[
- <!ENTITY % local.surname.attrib "">
- <!ENTITY % surname.role.attrib "%role.attrib;">
-
-<!ENTITY % surname.element "INCLUDE">
-<![%surname.element;[
-<!--doc:A family name; in western cultures the last name.-->
-<!ELEMENT surname %ho; (%docinfo.char.mix;)*>
-<!--end of surname.element-->]]>
-
-<!ENTITY % surname.attlist "INCLUDE">
-<![%surname.attlist;[
-<!ATTLIST surname
- %common.attrib;
- %surname.role.attrib;
- %local.surname.attrib;
->
-<!--end of surname.attlist-->]]>
- <!--end of surname.module-->]]>
-<!--end of person.ident.module-->]]>
-
-<!-- PrintHistory ..................... -->
-
-<!ENTITY % printhistory.module "INCLUDE">
-<![%printhistory.module;[
-<!ENTITY % local.printhistory.attrib "">
-<!ENTITY % printhistory.role.attrib "%role.attrib;">
-
-<!ENTITY % printhistory.element "INCLUDE">
-<![%printhistory.element;[
-<!--doc:The printing history of a document.-->
-<!ELEMENT printhistory %ho; ((%para.class;)+)>
-<!--end of printhistory.element-->]]>
-
-<!ENTITY % printhistory.attlist "INCLUDE">
-<![%printhistory.attlist;[
-<!ATTLIST printhistory
- %common.attrib;
- %printhistory.role.attrib;
- %local.printhistory.attrib;
->
-<!--end of printhistory.attlist-->]]>
-<!--end of printhistory.module-->]]>
-
-<!-- ProductName ...................... -->
-
-<!ENTITY % productname.module "INCLUDE">
-<![%productname.module;[
-<!ENTITY % local.productname.attrib "">
-<!ENTITY % productname.role.attrib "%role.attrib;">
-
-<!ENTITY % productname.element "INCLUDE">
-<![%productname.element;[
-<!--doc:The formal name of a product.-->
-<!ELEMENT productname %ho; (%para.char.mix;)*>
-<!--end of productname.element-->]]>
-
-<!-- Class: More precisely identifies the item the element names -->
-
-
-<!ENTITY % productname.attlist "INCLUDE">
-<![%productname.attlist;[
-<!ATTLIST productname
- class (service
- |trade
- |registered
- |copyright) 'trade'
- %common.attrib;
- %productname.role.attrib;
- %local.productname.attrib;
->
-<!--end of productname.attlist-->]]>
-<!--end of productname.module-->]]>
-
-<!-- ProductNumber .................... -->
-
-<!ENTITY % productnumber.module "INCLUDE">
-<![%productnumber.module;[
-<!ENTITY % local.productnumber.attrib "">
-<!ENTITY % productnumber.role.attrib "%role.attrib;">
-
-<!ENTITY % productnumber.element "INCLUDE">
-<![%productnumber.element;[
-<!--doc:A number assigned to a product.-->
-<!ELEMENT productnumber %ho; (%docinfo.char.mix;)*>
-<!--end of productnumber.element-->]]>
-
-<!ENTITY % productnumber.attlist "INCLUDE">
-<![%productnumber.attlist;[
-<!ATTLIST productnumber
- %common.attrib;
- %productnumber.role.attrib;
- %local.productnumber.attrib;
->
-<!--end of productnumber.attlist-->]]>
-<!--end of productnumber.module-->]]>
-
-<!-- PubDate .......................... -->
-
-<!ENTITY % pubdate.module "INCLUDE">
-<![%pubdate.module;[
-<!ENTITY % local.pubdate.attrib "">
-<!ENTITY % pubdate.role.attrib "%role.attrib;">
-
-<!ENTITY % pubdate.element "INCLUDE">
-<![%pubdate.element;[
-<!--doc:The date of publication of a document.-->
-<!ELEMENT pubdate %ho; (%docinfo.char.mix;)*>
-<!--end of pubdate.element-->]]>
-
-<!ENTITY % pubdate.attlist "INCLUDE">
-<![%pubdate.attlist;[
-<!ATTLIST pubdate
- %common.attrib;
- %pubdate.role.attrib;
- %local.pubdate.attrib;
->
-<!--end of pubdate.attlist-->]]>
-<!--end of pubdate.module-->]]>
-
-<!-- Publisher ........................ -->
-
-<!ENTITY % publisher.content.module "INCLUDE">
-<![%publisher.content.module;[
-<!ENTITY % publisher.module "INCLUDE">
-<![%publisher.module;[
-<!ENTITY % local.publisher.attrib "">
-<!ENTITY % publisher.role.attrib "%role.attrib;">
-
-<!ENTITY % publisher.element "INCLUDE">
-<![%publisher.element;[
-<!--doc:The publisher of a document.-->
-<!ELEMENT publisher %ho; (publishername, address*)>
-<!--end of publisher.element-->]]>
-
-<!ENTITY % publisher.attlist "INCLUDE">
-<![%publisher.attlist;[
-<!ATTLIST publisher
- %common.attrib;
- %publisher.role.attrib;
- %local.publisher.attrib;
->
-<!--end of publisher.attlist-->]]>
-<!--end of publisher.module-->]]>
-
- <!ENTITY % publishername.module "INCLUDE">
- <![%publishername.module;[
- <!ENTITY % local.publishername.attrib "">
- <!ENTITY % publishername.role.attrib "%role.attrib;">
-
-<!ENTITY % publishername.element "INCLUDE">
-<![%publishername.element;[
-<!--doc:The name of the publisher of a document.-->
-<!ELEMENT publishername %ho; (%docinfo.char.mix;)*>
-<!--end of publishername.element-->]]>
-
-<!ENTITY % publishername.attlist "INCLUDE">
-<![%publishername.attlist;[
-<!ATTLIST publishername
- %common.attrib;
- %publishername.role.attrib;
- %local.publishername.attrib;
->
-<!--end of publishername.attlist-->]]>
- <!--end of publishername.module-->]]>
-
- <!-- Address (defined elsewhere in this section)-->
-<!--end of publisher.content.module-->]]>
-
-<!-- PubsNumber ....................... -->
-
-<!ENTITY % pubsnumber.module "INCLUDE">
-<![%pubsnumber.module;[
-<!ENTITY % local.pubsnumber.attrib "">
-<!ENTITY % pubsnumber.role.attrib "%role.attrib;">
-
-<!ENTITY % pubsnumber.element "INCLUDE">
-<![%pubsnumber.element;[
-<!--doc:A number assigned to a publication other than an ISBN or ISSN or inventory part number.-->
-<!ELEMENT pubsnumber %ho; (%docinfo.char.mix;)*>
-<!--end of pubsnumber.element-->]]>
-
-<!ENTITY % pubsnumber.attlist "INCLUDE">
-<![%pubsnumber.attlist;[
-<!ATTLIST pubsnumber
- %common.attrib;
- %pubsnumber.role.attrib;
- %local.pubsnumber.attrib;
->
-<!--end of pubsnumber.attlist-->]]>
-<!--end of pubsnumber.module-->]]>
-
-<!-- ReleaseInfo ...................... -->
-
-<!ENTITY % releaseinfo.module "INCLUDE">
-<![%releaseinfo.module;[
-<!ENTITY % local.releaseinfo.attrib "">
-<!ENTITY % releaseinfo.role.attrib "%role.attrib;">
-
-<!ENTITY % releaseinfo.element "INCLUDE">
-<![%releaseinfo.element;[
-<!--doc:Information about a particular release of a document.-->
-<!ELEMENT releaseinfo %ho; (%docinfo.char.mix;)*>
-<!--end of releaseinfo.element-->]]>
-
-<!ENTITY % releaseinfo.attlist "INCLUDE">
-<![%releaseinfo.attlist;[
-<!ATTLIST releaseinfo
- %common.attrib;
- %releaseinfo.role.attrib;
- %local.releaseinfo.attrib;
->
-<!--end of releaseinfo.attlist-->]]>
-<!--end of releaseinfo.module-->]]>
-
-<!-- RevHistory ....................... -->
-
-<!ENTITY % revhistory.content.module "INCLUDE">
-<![%revhistory.content.module;[
-<!ENTITY % revhistory.module "INCLUDE">
-<![%revhistory.module;[
-<!ENTITY % local.revhistory.attrib "">
-<!ENTITY % revhistory.role.attrib "%role.attrib;">
-
-<!ENTITY % revhistory.element "INCLUDE">
-<![%revhistory.element;[
-<!--doc:A history of the revisions to a document.-->
-<!ELEMENT revhistory %ho; (revision+)>
-<!--end of revhistory.element-->]]>
-
-<!ENTITY % revhistory.attlist "INCLUDE">
-<![%revhistory.attlist;[
-<!ATTLIST revhistory
- %common.attrib;
- %revhistory.role.attrib;
- %local.revhistory.attrib;
->
-<!--end of revhistory.attlist-->]]>
-<!--end of revhistory.module-->]]>
-
-<!ENTITY % revision.module "INCLUDE">
-<![%revision.module;[
-<!ENTITY % local.revision.attrib "">
-<!ENTITY % revision.role.attrib "%role.attrib;">
-
-<!ENTITY % revision.element "INCLUDE">
-<![%revision.element;[
-<!--doc:An entry describing a single revision in the history of the revisions to a document.-->
-<!ELEMENT revision %ho; (revnumber?, date, (author|authorinitials)*,
- (revremark|revdescription)?)>
-<!--end of revision.element-->]]>
-
-<!ENTITY % revision.attlist "INCLUDE">
-<![%revision.attlist;[
-<!ATTLIST revision
- %common.attrib;
- %revision.role.attrib;
- %local.revision.attrib;
->
-<!--end of revision.attlist-->]]>
-<!--end of revision.module-->]]>
-
-<!ENTITY % revnumber.module "INCLUDE">
-<![%revnumber.module;[
-<!ENTITY % local.revnumber.attrib "">
-<!ENTITY % revnumber.role.attrib "%role.attrib;">
-
-<!ENTITY % revnumber.element "INCLUDE">
-<![%revnumber.element;[
-<!--doc:A document revision number.-->
-<!ELEMENT revnumber %ho; (%docinfo.char.mix;)*>
-<!--end of revnumber.element-->]]>
-
-<!ENTITY % revnumber.attlist "INCLUDE">
-<![%revnumber.attlist;[
-<!ATTLIST revnumber
- %common.attrib;
- %revnumber.role.attrib;
- %local.revnumber.attrib;
->
-<!--end of revnumber.attlist-->]]>
-<!--end of revnumber.module-->]]>
-
-<!-- Date (defined elsewhere in this section)-->
-<!-- AuthorInitials (defined elsewhere in this section)-->
-
-<!ENTITY % revremark.module "INCLUDE">
-<![%revremark.module;[
-<!ENTITY % local.revremark.attrib "">
-<!ENTITY % revremark.role.attrib "%role.attrib;">
-
-<!ENTITY % revremark.element "INCLUDE">
-<![%revremark.element;[
-<!--doc:A description of a revision to a document.-->
-<!ELEMENT revremark %ho; (%docinfo.char.mix;)*>
-<!--end of revremark.element-->]]>
-
-<!ENTITY % revremark.attlist "INCLUDE">
-<![%revremark.attlist;[
-<!ATTLIST revremark
- %common.attrib;
- %revremark.role.attrib;
- %local.revremark.attrib;
->
-<!--end of revremark.attlist-->]]>
-<!--end of revremark.module-->]]>
-
-<!ENTITY % revdescription.module "INCLUDE">
-<![ %revdescription.module; [
-<!ENTITY % local.revdescription.attrib "">
-<!ENTITY % revdescription.role.attrib "%role.attrib;">
-
-<!ENTITY % revdescription.element "INCLUDE">
-<![ %revdescription.element; [
-<!--doc:A extended description of a revision to a document.-->
-<!ELEMENT revdescription %ho; ((%revdescription.mix;)+)>
-<!--end of revdescription.element-->]]>
-
-<!ENTITY % revdescription.attlist "INCLUDE">
-<![ %revdescription.attlist; [
-<!ATTLIST revdescription
- %common.attrib;
- %revdescription.role.attrib;
- %local.revdescription.attrib;
->
-<!--end of revdescription.attlist-->]]>
-<!--end of revdescription.module-->]]>
-<!--end of revhistory.content.module-->]]>
-
-<!-- SeriesVolNums .................... -->
-
-<!ENTITY % seriesvolnums.module "INCLUDE">
-<![%seriesvolnums.module;[
-<!ENTITY % local.seriesvolnums.attrib "">
-<!ENTITY % seriesvolnums.role.attrib "%role.attrib;">
-
-<!ENTITY % seriesvolnums.element "INCLUDE">
-<![%seriesvolnums.element;[
-<!--doc:Numbers of the volumes in a series of books.-->
-<!ELEMENT seriesvolnums %ho; (%docinfo.char.mix;)*>
-<!--end of seriesvolnums.element-->]]>
-
-<!ENTITY % seriesvolnums.attlist "INCLUDE">
-<![%seriesvolnums.attlist;[
-<!ATTLIST seriesvolnums
- %common.attrib;
- %seriesvolnums.role.attrib;
- %local.seriesvolnums.attrib;
->
-<!--end of seriesvolnums.attlist-->]]>
-<!--end of seriesvolnums.module-->]]>
-
-<!-- VolumeNum ........................ -->
-
-<!ENTITY % volumenum.module "INCLUDE">
-<![%volumenum.module;[
-<!ENTITY % local.volumenum.attrib "">
-<!ENTITY % volumenum.role.attrib "%role.attrib;">
-
-<!ENTITY % volumenum.element "INCLUDE">
-<![%volumenum.element;[
-<!--doc:The volume number of a document in a set (as of books in a set or articles in a journal).-->
-<!ELEMENT volumenum %ho; (%docinfo.char.mix;)*>
-<!--end of volumenum.element-->]]>
-
-<!ENTITY % volumenum.attlist "INCLUDE">
-<![%volumenum.attlist;[
-<!ATTLIST volumenum
- %common.attrib;
- %volumenum.role.attrib;
- %local.volumenum.attrib;
->
-<!--end of volumenum.attlist-->]]>
-<!--end of volumenum.module-->]]>
-
-<!-- .................................. -->
-
-<!--end of docinfo.content.module-->]]>
-
-<!-- ...................................................................... -->
-<!-- Inline, link, and ubiquitous elements ................................ -->
-
-<!-- Technical and computer terms ......................................... -->
-
-<!ENTITY % accel.module "INCLUDE">
-<![%accel.module;[
-<!ENTITY % local.accel.attrib "">
-<!ENTITY % accel.role.attrib "%role.attrib;">
-
-<!ENTITY % accel.element "INCLUDE">
-<![%accel.element;[
-<!--doc:A graphical user interface (GUI) keyboard shortcut.-->
-<!ELEMENT accel %ho; (%smallcptr.char.mix;)*>
-<!--end of accel.element-->]]>
-
-<!ENTITY % accel.attlist "INCLUDE">
-<![%accel.attlist;[
-<!ATTLIST accel
- %common.attrib;
- %accel.role.attrib;
- %local.accel.attrib;
->
-<!--end of accel.attlist-->]]>
-<!--end of accel.module-->]]>
-
-<!ENTITY % action.module "INCLUDE">
-<![%action.module;[
-<!ENTITY % local.action.attrib "">
-<!ENTITY % action.role.attrib "%role.attrib;">
-
-<!ENTITY % action.element "INCLUDE">
-<![%action.element;[
-<!--doc:A response to a user event.-->
-<!ELEMENT action %ho; (%cptr.char.mix;)*>
-<!--end of action.element-->]]>
-
-<!ENTITY % action.attlist "INCLUDE">
-<![%action.attlist;[
-<!ATTLIST action
- %moreinfo.attrib;
- %common.attrib;
- %action.role.attrib;
- %local.action.attrib;
->
-<!--end of action.attlist-->]]>
-<!--end of action.module-->]]>
-
-<!ENTITY % application.module "INCLUDE">
-<![%application.module;[
-<!ENTITY % local.application.attrib "">
-<!ENTITY % application.role.attrib "%role.attrib;">
-
-<!ENTITY % application.element "INCLUDE">
-<![%application.element;[
-<!--doc:The name of a software program.-->
-<!ELEMENT application %ho; (%para.char.mix;)*>
-<!--end of application.element-->]]>
-
-<!ENTITY % application.attlist "INCLUDE">
-<![%application.attlist;[
-<!ATTLIST application
- class (hardware
- |software) #IMPLIED
- %moreinfo.attrib;
- %common.attrib;
- %application.role.attrib;
- %local.application.attrib;
->
-<!--end of application.attlist-->]]>
-<!--end of application.module-->]]>
-
-<!ENTITY % classname.module "INCLUDE">
-<![%classname.module;[
-<!ENTITY % local.classname.attrib "">
-<!ENTITY % classname.role.attrib "%role.attrib;">
-
-<!ENTITY % classname.element "INCLUDE">
-<![%classname.element;[
-<!--doc:The name of a class, in the object-oriented programming sense.-->
-<!ELEMENT classname %ho; (%smallcptr.char.mix;)*>
-<!--end of classname.element-->]]>
-
-<!ENTITY % classname.attlist "INCLUDE">
-<![%classname.attlist;[
-<!ATTLIST classname
- %common.attrib;
- %classname.role.attrib;
- %local.classname.attrib;
->
-<!--end of classname.attlist-->]]>
-<!--end of classname.module-->]]>
-
-<!ENTITY % package.module "INCLUDE">
-<![%package.module;[
-<!ENTITY % local.package.attrib "">
-<!ENTITY % package.role.attrib "%role.attrib;">
-
-<!ENTITY % package.element "INCLUDE">
-<![%package.element;[
-<!--doc:A package.-->
-<!ELEMENT package %ho; (%smallcptr.char.mix;)*>
-<!--end of package.element-->]]>
-
-<!ENTITY % package.attlist "INCLUDE">
-<![%package.attlist;[
-<!ATTLIST package
- %common.attrib;
- %package.role.attrib;
- %local.package.attrib;
->
-<!--end of package.attlist-->]]>
-<!--end of package.module-->]]>
-
-<!ENTITY % co.module "INCLUDE">
-<![%co.module;[
-<!ENTITY % local.co.attrib "">
-<!-- CO is a callout area of the LineColumn unit type (a single character
- position); the position is directly indicated by the location of CO. -->
-<!ENTITY % co.role.attrib "%role.attrib;">
-
-<!ENTITY % co.element "INCLUDE">
-<![%co.element;[
-<!--doc:The location of a callout embedded in text.-->
-<!ELEMENT co %ho; EMPTY>
-<!--end of co.element-->]]>
-
-<!-- bug number/symbol override or initialization -->
-<!-- to any related information -->
-
-
-<!ENTITY % co.attlist "INCLUDE">
-<![%co.attlist;[
-<!ATTLIST co
- %label.attrib;
- %linkends.attrib;
- %idreq.common.attrib;
- %co.role.attrib;
- %local.co.attrib;
->
-<!--end of co.attlist-->]]>
-<!--end of co.module-->]]>
-
-<!ENTITY % coref.module "INCLUDE">
-<![%coref.module;[
-<!ENTITY % local.coref.attrib "">
-<!-- COREF is a reference to a CO -->
-<!ENTITY % coref.role.attrib "%role.attrib;">
-
-<!ENTITY % coref.element "INCLUDE">
-<![%coref.element;[
-<!--doc:A cross reference to a co.-->
-<!ELEMENT coref %ho; EMPTY>
-<!--end of coref.element-->]]>
-
-<!-- bug number/symbol override or initialization -->
-<!-- to any related information -->
-
-<!ENTITY % coref.attlist "INCLUDE">
-<![%coref.attlist;[
-<!ATTLIST coref
- %label.attrib;
- %linkendreq.attrib;
- %common.attrib;
- %coref.role.attrib;
- %local.coref.attrib;
->
-<!--end of coref.attlist-->]]>
-<!--end of coref.module-->]]>
-
-<!ENTITY % command.module "INCLUDE">
-<![%command.module;[
-<!ENTITY % local.command.attrib "">
-<!ENTITY % command.role.attrib "%role.attrib;">
-
-<!ENTITY % command.element "INCLUDE">
-<![%command.element;[
-<!--doc:The name of an executable program or other software command.-->
-<!ELEMENT command %ho; (%cptr.char.mix;)*>
-<!--end of command.element-->]]>
-
-<!ENTITY % command.attlist "INCLUDE">
-<![%command.attlist;[
-<!ATTLIST command
- %moreinfo.attrib;
- %common.attrib;
- %command.role.attrib;
- %local.command.attrib;
->
-<!--end of command.attlist-->]]>
-<!--end of command.module-->]]>
-
-<!ENTITY % computeroutput.module "INCLUDE">
-<![%computeroutput.module;[
-<!ENTITY % local.computeroutput.attrib "">
-<!ENTITY % computeroutput.role.attrib "%role.attrib;">
-
-<!ENTITY % computeroutput.element "INCLUDE">
-<![%computeroutput.element;[
-<!--doc:Data, generally text, displayed or presented by a computer.-->
-<!ELEMENT computeroutput %ho; (%cptr.char.mix;|co)*>
-<!--end of computeroutput.element-->]]>
-
-<!ENTITY % computeroutput.attlist "INCLUDE">
-<![%computeroutput.attlist;[
-<!ATTLIST computeroutput
- %moreinfo.attrib;
- %common.attrib;
- %computeroutput.role.attrib;
- %local.computeroutput.attrib;
->
-<!--end of computeroutput.attlist-->]]>
-<!--end of computeroutput.module-->]]>
-
-<!ENTITY % database.module "INCLUDE">
-<![%database.module;[
-<!ENTITY % local.database.attrib "">
-<!ENTITY % database.role.attrib "%role.attrib;">
-
-<!ENTITY % database.element "INCLUDE">
-<![%database.element;[
-<!--doc:The name of a database, or part of a database.-->
-<!ELEMENT database %ho; (%cptr.char.mix;)*>
-<!--end of database.element-->]]>
-
-<!-- Class: Type of database the element names; no default -->
-
-
-<!ENTITY % database.attlist "INCLUDE">
-<![%database.attlist;[
-<!ATTLIST database
- class (name
- |table
- |field
- |key1
- |key2
- |record
- |index
- |view
- |primarykey
- |secondarykey
- |foreignkey
- |altkey
- |procedure
- |datatype
- |constraint
- |rule
- |user
- |group) #IMPLIED
- %moreinfo.attrib;
- %common.attrib;
- %database.role.attrib;
- %local.database.attrib;
->
-<!--end of database.attlist-->]]>
-<!--end of database.module-->]]>
-
-<!ENTITY % email.module "INCLUDE">
-<![%email.module;[
-<!ENTITY % local.email.attrib "">
-<!ENTITY % email.role.attrib "%role.attrib;">
-
-<!ENTITY % email.element "INCLUDE">
-<![%email.element;[
-<!--doc:An email address.-->
-<!ELEMENT email %ho; (%docinfo.char.mix;)*>
-<!--end of email.element-->]]>
-
-<!ENTITY % email.attlist "INCLUDE">
-<![%email.attlist;[
-<!ATTLIST email
- %common.attrib;
- %email.role.attrib;
- %local.email.attrib;
->
-<!--end of email.attlist-->]]>
-<!--end of email.module-->]]>
-
-<!ENTITY % envar.module "INCLUDE">
-<![%envar.module;[
-<!ENTITY % local.envar.attrib "">
-<!ENTITY % envar.role.attrib "%role.attrib;">
-
-<!ENTITY % envar.element "INCLUDE">
-<![%envar.element;[
-<!--doc:A software environment variable.-->
-<!ELEMENT envar %ho; (%smallcptr.char.mix;)*>
-<!--end of envar.element-->]]>
-
-<!ENTITY % envar.attlist "INCLUDE">
-<![%envar.attlist;[
-<!ATTLIST envar
- %common.attrib;
- %envar.role.attrib;
- %local.envar.attrib;
->
-<!--end of envar.attlist-->]]>
-<!--end of envar.module-->]]>
-
-
-<!ENTITY % errorcode.module "INCLUDE">
-<![%errorcode.module;[
-<!ENTITY % local.errorcode.attrib "">
-<!ENTITY % errorcode.role.attrib "%role.attrib;">
-
-<!ENTITY % errorcode.element "INCLUDE">
-<![%errorcode.element;[
-<!--doc:An error code.-->
-<!ELEMENT errorcode %ho; (%smallcptr.char.mix;)*>
-<!--end of errorcode.element-->]]>
-
-<!ENTITY % errorcode.attlist "INCLUDE">
-<![%errorcode.attlist;[
-<!ATTLIST errorcode
- %moreinfo.attrib;
- %common.attrib;
- %errorcode.role.attrib;
- %local.errorcode.attrib;
->
-<!--end of errorcode.attlist-->]]>
-<!--end of errorcode.module-->]]>
-
-<!ENTITY % errorname.module "INCLUDE">
-<![%errorname.module;[
-<!ENTITY % local.errorname.attrib "">
-<!ENTITY % errorname.role.attrib "%role.attrib;">
-
-<!ENTITY % errorname.element "INCLUDE">
-<![%errorname.element;[
-<!--doc:An error name.-->
-<!ELEMENT errorname %ho; (%smallcptr.char.mix;)*>
-<!--end of errorname.element-->]]>
-
-<!ENTITY % errorname.attlist "INCLUDE">
-<![%errorname.attlist;[
-<!ATTLIST errorname
- %common.attrib;
- %errorname.role.attrib;
- %local.errorname.attrib;
->
-<!--end of errorname.attlist-->]]>
-<!--end of errorname.module-->]]>
-
-<!ENTITY % errortext.module "INCLUDE">
-<![%errortext.module;[
-<!ENTITY % local.errortext.attrib "">
-<!ENTITY % errortext.role.attrib "%role.attrib;">
-
-<!ENTITY % errortext.element "INCLUDE">
-<![%errortext.element;[
-<!--doc:An error message..-->
-<!ELEMENT errortext %ho; (%smallcptr.char.mix;)*>
-<!--end of errortext.element-->]]>
-
-<!ENTITY % errortext.attlist "INCLUDE">
-<![%errortext.attlist;[
-<!ATTLIST errortext
- %common.attrib;
- %errortext.role.attrib;
- %local.errortext.attrib;
->
-<!--end of errortext.attlist-->]]>
-<!--end of errortext.module-->]]>
-
-<!ENTITY % errortype.module "INCLUDE">
-<![%errortype.module;[
-<!ENTITY % local.errortype.attrib "">
-<!ENTITY % errortype.role.attrib "%role.attrib;">
-
-<!ENTITY % errortype.element "INCLUDE">
-<![%errortype.element;[
-<!--doc:The classification of an error message.-->
-<!ELEMENT errortype %ho; (%smallcptr.char.mix;)*>
-<!--end of errortype.element-->]]>
-
-<!ENTITY % errortype.attlist "INCLUDE">
-<![%errortype.attlist;[
-<!ATTLIST errortype
- %common.attrib;
- %errortype.role.attrib;
- %local.errortype.attrib;
->
-<!--end of errortype.attlist-->]]>
-<!--end of errortype.module-->]]>
-
-<!ENTITY % filename.module "INCLUDE">
-<![%filename.module;[
-<!ENTITY % local.filename.attrib "">
-<!ENTITY % filename.role.attrib "%role.attrib;">
-
-<!ENTITY % filename.element "INCLUDE">
-<![%filename.element;[
-<!--doc:The name of a file.-->
-<!ELEMENT filename %ho; (%cptr.char.mix;)*>
-<!--end of filename.element-->]]>
-
-<!-- Class: Type of filename the element names; no default -->
-<!-- Path: Search path (possibly system-specific) in which
- file can be found -->
-
-
-<!ENTITY % filename.attlist "INCLUDE">
-<![%filename.attlist;[
-<!ATTLIST filename
- class (headerfile
- |partition
- |devicefile
- |libraryfile
- |directory
- |extension
- |symlink) #IMPLIED
- path CDATA #IMPLIED
- %moreinfo.attrib;
- %common.attrib;
- %filename.role.attrib;
- %local.filename.attrib;
->
-<!--end of filename.attlist-->]]>
-<!--end of filename.module-->]]>
-
-<!ENTITY % function.module "INCLUDE">
-<![%function.module;[
-<!ENTITY % local.function.attrib "">
-<!ENTITY % function.role.attrib "%role.attrib;">
-
-<!ENTITY % function.element "INCLUDE">
-<![%function.element;[
-<!--doc:The name of a function or subroutine, as in a programming language.-->
-<!ELEMENT function %ho; (%cptr.char.mix;)*>
-<!--end of function.element-->]]>
-
-<!ENTITY % function.attlist "INCLUDE">
-<![%function.attlist;[
-<!ATTLIST function
- %moreinfo.attrib;
- %common.attrib;
- %function.role.attrib;
- %local.function.attrib;
->
-<!--end of function.attlist-->]]>
-<!--end of function.module-->]]>
-
-<!ENTITY % guibutton.module "INCLUDE">
-<![%guibutton.module;[
-<!ENTITY % local.guibutton.attrib "">
-<!ENTITY % guibutton.role.attrib "%role.attrib;">
-
-<!ENTITY % guibutton.element "INCLUDE">
-<![%guibutton.element;[
-<!--doc:The text on a button in a GUI.-->
-<!ELEMENT guibutton %ho; (%smallcptr.char.mix;|accel|superscript|subscript)*>
-<!--end of guibutton.element-->]]>
-
-<!ENTITY % guibutton.attlist "INCLUDE">
-<![%guibutton.attlist;[
-<!ATTLIST guibutton
- %moreinfo.attrib;
- %common.attrib;
- %guibutton.role.attrib;
- %local.guibutton.attrib;
->
-<!--end of guibutton.attlist-->]]>
-<!--end of guibutton.module-->]]>
-
-<!ENTITY % guiicon.module "INCLUDE">
-<![%guiicon.module;[
-<!ENTITY % local.guiicon.attrib "">
-<!ENTITY % guiicon.role.attrib "%role.attrib;">
-
-<!ENTITY % guiicon.element "INCLUDE">
-<![%guiicon.element;[
-<!--doc:Graphic and/or text appearing as a icon in a GUI.-->
-<!ELEMENT guiicon %ho; (%smallcptr.char.mix;|accel|superscript|subscript)*>
-<!--end of guiicon.element-->]]>
-
-<!ENTITY % guiicon.attlist "INCLUDE">
-<![%guiicon.attlist;[
-<!ATTLIST guiicon
- %moreinfo.attrib;
- %common.attrib;
- %guiicon.role.attrib;
- %local.guiicon.attrib;
->
-<!--end of guiicon.attlist-->]]>
-<!--end of guiicon.module-->]]>
-
-<!ENTITY % guilabel.module "INCLUDE">
-<![%guilabel.module;[
-<!ENTITY % local.guilabel.attrib "">
-<!ENTITY % guilabel.role.attrib "%role.attrib;">
-
-<!ENTITY % guilabel.element "INCLUDE">
-<![%guilabel.element;[
-<!--doc:The text of a label in a GUI.-->
-<!ELEMENT guilabel %ho; (%smallcptr.char.mix;|accel|superscript|subscript)*>
-<!--end of guilabel.element-->]]>
-
-<!ENTITY % guilabel.attlist "INCLUDE">
-<![%guilabel.attlist;[
-<!ATTLIST guilabel
- %moreinfo.attrib;
- %common.attrib;
- %guilabel.role.attrib;
- %local.guilabel.attrib;
->
-<!--end of guilabel.attlist-->]]>
-<!--end of guilabel.module-->]]>
-
-<!ENTITY % guimenu.module "INCLUDE">
-<![%guimenu.module;[
-<!ENTITY % local.guimenu.attrib "">
-<!ENTITY % guimenu.role.attrib "%role.attrib;">
-
-<!ENTITY % guimenu.element "INCLUDE">
-<![%guimenu.element;[
-<!--doc:The name of a menu in a GUI.-->
-<!ELEMENT guimenu %ho; (%smallcptr.char.mix;|accel|superscript|subscript)*>
-<!--end of guimenu.element-->]]>
-
-<!ENTITY % guimenu.attlist "INCLUDE">
-<![%guimenu.attlist;[
-<!ATTLIST guimenu
- %moreinfo.attrib;
- %common.attrib;
- %guimenu.role.attrib;
- %local.guimenu.attrib;
->
-<!--end of guimenu.attlist-->]]>
-<!--end of guimenu.module-->]]>
-
-<!ENTITY % guimenuitem.module "INCLUDE">
-<![%guimenuitem.module;[
-<!ENTITY % local.guimenuitem.attrib "">
-<!ENTITY % guimenuitem.role.attrib "%role.attrib;">
-
-<!ENTITY % guimenuitem.element "INCLUDE">
-<![%guimenuitem.element;[
-<!--doc:The name of a terminal menu item in a GUI.-->
-<!ELEMENT guimenuitem %ho; (%smallcptr.char.mix;|accel|superscript|subscript)*>
-<!--end of guimenuitem.element-->]]>
-
-<!ENTITY % guimenuitem.attlist "INCLUDE">
-<![%guimenuitem.attlist;[
-<!ATTLIST guimenuitem
- %moreinfo.attrib;
- %common.attrib;
- %guimenuitem.role.attrib;
- %local.guimenuitem.attrib;
->
-<!--end of guimenuitem.attlist-->]]>
-<!--end of guimenuitem.module-->]]>
-
-<!ENTITY % guisubmenu.module "INCLUDE">
-<![%guisubmenu.module;[
-<!ENTITY % local.guisubmenu.attrib "">
-<!ENTITY % guisubmenu.role.attrib "%role.attrib;">
-
-<!ENTITY % guisubmenu.element "INCLUDE">
-<![%guisubmenu.element;[
-<!--doc:The name of a submenu in a GUI.-->
-<!ELEMENT guisubmenu %ho; (%smallcptr.char.mix;|accel|superscript|subscript)*>
-<!--end of guisubmenu.element-->]]>
-
-<!ENTITY % guisubmenu.attlist "INCLUDE">
-<![%guisubmenu.attlist;[
-<!ATTLIST guisubmenu
- %moreinfo.attrib;
- %common.attrib;
- %guisubmenu.role.attrib;
- %local.guisubmenu.attrib;
->
-<!--end of guisubmenu.attlist-->]]>
-<!--end of guisubmenu.module-->]]>
-
-<!ENTITY % hardware.module "INCLUDE">
-<![%hardware.module;[
-<!ENTITY % local.hardware.attrib "">
-<!ENTITY % hardware.role.attrib "%role.attrib;">
-
-<!ENTITY % hardware.element "INCLUDE">
-<![%hardware.element;[
-<!--doc:A physical part of a computer system.-->
-<!ELEMENT hardware %ho; (%cptr.char.mix;)*>
-<!--end of hardware.element-->]]>
-
-<!ENTITY % hardware.attlist "INCLUDE">
-<![%hardware.attlist;[
-<!ATTLIST hardware
- %moreinfo.attrib;
- %common.attrib;
- %hardware.role.attrib;
- %local.hardware.attrib;
->
-<!--end of hardware.attlist-->]]>
-<!--end of hardware.module-->]]>
-
-<!ENTITY % interface.module "INCLUDE">
-<![%interface.module;[
-<!ENTITY % local.interface.attrib "">
-<!ENTITY % interface.role.attrib "%role.attrib;">
-
-<!ENTITY % interface.element "INCLUDE">
-<![%interface.element;[
-<!--doc:An element of a GUI.-->
-<!ELEMENT interface %ho; (%smallcptr.char.mix;|accel)*>
-<!--end of interface.element-->]]>
-
-<!-- Class: Type of the Interface item; no default -->
-
-
-<!ENTITY % interface.attlist "INCLUDE">
-<![%interface.attlist;[
-<!ATTLIST interface
- %moreinfo.attrib;
- %common.attrib;
- %interface.role.attrib;
- %local.interface.attrib;
->
-<!--end of interface.attlist-->]]>
-<!--end of interface.module-->]]>
-
-<!ENTITY % keycap.module "INCLUDE">
-<![%keycap.module;[
-<!ENTITY % local.keycap.attrib "">
-<!ENTITY % keycap.role.attrib "%role.attrib;">
-
-<!ENTITY % keycap.element "INCLUDE">
-<![%keycap.element;[
-<!--doc:The text printed on a key on a keyboard.-->
-<!ELEMENT keycap %ho; (%cptr.char.mix;)*>
-<!--end of keycap.element-->]]>
-
-<!ENTITY % keycap.attlist "INCLUDE">
-<![%keycap.attlist;[
-<!ATTLIST keycap
- function (alt
- |control
- |shift
- |meta
- |escape
- |enter
- |tab
- |backspace
- |command
- |option
- |space
- |delete
- |insert
- |up
- |down
- |left
- |right
- |home
- |end
- |pageup
- |pagedown
- |other) #IMPLIED
- otherfunction CDATA #IMPLIED
- %moreinfo.attrib;
- %common.attrib;
- %keycap.role.attrib;
- %local.keycap.attrib;
->
-<!--end of keycap.attlist-->]]>
-<!--end of keycap.module-->]]>
-
-<!ENTITY % keycode.module "INCLUDE">
-<![%keycode.module;[
-<!ENTITY % local.keycode.attrib "">
-<!ENTITY % keycode.role.attrib "%role.attrib;">
-
-<!ENTITY % keycode.element "INCLUDE">
-<![%keycode.element;[
-<!--doc:The internal, frequently numeric, identifier for a key on a keyboard.-->
-<!ELEMENT keycode %ho; (%smallcptr.char.mix;)*>
-<!--end of keycode.element-->]]>
-
-<!ENTITY % keycode.attlist "INCLUDE">
-<![%keycode.attlist;[
-<!ATTLIST keycode
- %common.attrib;
- %keycode.role.attrib;
- %local.keycode.attrib;
->
-<!--end of keycode.attlist-->]]>
-<!--end of keycode.module-->]]>
-
-<!ENTITY % keycombo.module "INCLUDE">
-<![%keycombo.module;[
-<!ENTITY % local.keycombo.attrib "">
-<!ENTITY % keycombo.role.attrib "%role.attrib;">
-
-<!ENTITY % keycombo.element "INCLUDE">
-<![%keycombo.element;[
-<!--doc:A combination of input actions.-->
-<!ELEMENT keycombo %ho; ((keycap|keycombo|keysym|mousebutton)+)>
-<!--end of keycombo.element-->]]>
-
-<!ENTITY % keycombo.attlist "INCLUDE">
-<![%keycombo.attlist;[
-<!ATTLIST keycombo
- %keyaction.attrib;
- %moreinfo.attrib;
- %common.attrib;
- %keycombo.role.attrib;
- %local.keycombo.attrib;
->
-<!--end of keycombo.attlist-->]]>
-<!--end of keycombo.module-->]]>
-
-<!ENTITY % keysym.module "INCLUDE">
-<![%keysym.module;[
-<!ENTITY % local.keysym.attrib "">
-<!ENTITY % keysysm.role.attrib "%role.attrib;">
-
-<!ENTITY % keysym.element "INCLUDE">
-<![%keysym.element;[
-<!--doc:The symbolic name of a key on a keyboard.-->
-<!ELEMENT keysym %ho; (%smallcptr.char.mix;)*>
-<!--end of keysym.element-->]]>
-
-<!ENTITY % keysym.attlist "INCLUDE">
-<![%keysym.attlist;[
-<!ATTLIST keysym
- %common.attrib;
- %keysysm.role.attrib;
- %local.keysym.attrib;
->
-<!--end of keysym.attlist-->]]>
-<!--end of keysym.module-->]]>
-
-<!ENTITY % lineannotation.module "INCLUDE">
-<![%lineannotation.module;[
-<!ENTITY % local.lineannotation.attrib "">
-<!ENTITY % lineannotation.role.attrib "%role.attrib;">
-
-<!ENTITY % lineannotation.element "INCLUDE">
-<![%lineannotation.element;[
-<!--doc:A comment on a line in a verbatim listing.-->
-<!ELEMENT lineannotation %ho; (%para.char.mix;)*>
-<!--end of lineannotation.element-->]]>
-
-<!ENTITY % lineannotation.attlist "INCLUDE">
-<![%lineannotation.attlist;[
-<!ATTLIST lineannotation
- %common.attrib;
- %lineannotation.role.attrib;
- %local.lineannotation.attrib;
->
-<!--end of lineannotation.attlist-->]]>
-<!--end of lineannotation.module-->]]>
-
-<!ENTITY % literal.module "INCLUDE">
-<![%literal.module;[
-<!ENTITY % local.literal.attrib "">
-<!ENTITY % literal.role.attrib "%role.attrib;">
-
-<!ENTITY % literal.element "INCLUDE">
-<![%literal.element;[
-<!--doc:Inline text that is some literal value.-->
-<!ELEMENT literal %ho; (%cptr.char.mix;)*>
-<!--end of literal.element-->]]>
-
-<!ENTITY % literal.attlist "INCLUDE">
-<![%literal.attlist;[
-<!ATTLIST literal
- %moreinfo.attrib;
- %common.attrib;
- %literal.role.attrib;
- %local.literal.attrib;
->
-<!--end of literal.attlist-->]]>
-<!--end of literal.module-->]]>
-
-<!ENTITY % code.module "INCLUDE">
-<![%code.module;[
-<!ENTITY % local.code.attrib "">
-<!ENTITY % code.role.attrib "%role.attrib;">
-
-<!ENTITY % code.element "INCLUDE">
-<![%code.element;[
-<!--doc:An inline code fragment.-->
-<!ELEMENT code %ho; (%cptr.char.mix;)*>
-<!--end of code.element-->]]>
-
-<!ENTITY % code.attlist "INCLUDE">
-<![%code.attlist;[
-<!ATTLIST code
- language CDATA #IMPLIED
- %common.attrib;
- %code.role.attrib;
- %local.code.attrib;
->
-<!--end of code.attlist-->]]>
-<!--end of code.module-->]]>
-
-<!ENTITY % constant.module "INCLUDE">
-<![ %constant.module; [
-<!ENTITY % local.constant.attrib "">
-<!ENTITY % constant.role.attrib "%role.attrib;">
-
-<!ENTITY % constant.element "INCLUDE">
-<![ %constant.element; [
-<!--doc:A programming or system constant.-->
-<!ELEMENT constant %ho; (%smallcptr.char.mix;)*>
-<!--end of constant.element-->]]>
-
-<!ENTITY % constant.attlist "INCLUDE">
-<![ %constant.attlist; [
-<!ATTLIST constant
- class (limit) #IMPLIED
- %common.attrib;
- %constant.role.attrib;
- %local.constant.attrib;
->
-<!--end of constant.attlist-->]]>
-<!--end of constant.module-->]]>
-
-<!ENTITY % varname.module "INCLUDE">
-<![ %varname.module; [
-<!ENTITY % local.varname.attrib "">
-<!ENTITY % varname.role.attrib "%role.attrib;">
-
-<!ENTITY % varname.element "INCLUDE">
-<![ %varname.element; [
-<!--doc:The name of a variable.-->
-<!ELEMENT varname %ho; (%smallcptr.char.mix;)*>
-<!--end of varname.element-->]]>
-
-<!ENTITY % varname.attlist "INCLUDE">
-<![ %varname.attlist; [
-<!ATTLIST varname
- %common.attrib;
- %varname.role.attrib;
- %local.varname.attrib;
->
-<!--end of varname.attlist-->]]>
-<!--end of varname.module-->]]>
-
-<!ENTITY % markup.module "INCLUDE">
-<![%markup.module;[
-<!ENTITY % local.markup.attrib "">
-<!ENTITY % markup.role.attrib "%role.attrib;">
-
-<!ENTITY % markup.element "INCLUDE">
-<![%markup.element;[
-<!--doc:A string of formatting markup in text that is to be represented literally.-->
-<!ELEMENT markup %ho; (%smallcptr.char.mix;)*>
-<!--end of markup.element-->]]>
-
-<!ENTITY % markup.attlist "INCLUDE">
-<![%markup.attlist;[
-<!ATTLIST markup
- %common.attrib;
- %markup.role.attrib;
- %local.markup.attrib;
->
-<!--end of markup.attlist-->]]>
-<!--end of markup.module-->]]>
-
-<!ENTITY % medialabel.module "INCLUDE">
-<![%medialabel.module;[
-<!ENTITY % local.medialabel.attrib "">
-<!ENTITY % medialabel.role.attrib "%role.attrib;">
-
-<!ENTITY % medialabel.element "INCLUDE">
-<![%medialabel.element;[
-<!--doc:A name that identifies the physical medium on which some information resides.-->
-<!ELEMENT medialabel %ho; (%smallcptr.char.mix;)*>
-<!--end of medialabel.element-->]]>
-
-<!-- Class: Type of medium named by the element; no default -->
-
-
-<!ENTITY % medialabel.attlist "INCLUDE">
-<![%medialabel.attlist;[
-<!ATTLIST medialabel
- class (cartridge
- |cdrom
- |disk
- |tape) #IMPLIED
- %common.attrib;
- %medialabel.role.attrib;
- %local.medialabel.attrib;
->
-<!--end of medialabel.attlist-->]]>
-<!--end of medialabel.module-->]]>
-
-<!ENTITY % menuchoice.content.module "INCLUDE">
-<![%menuchoice.content.module;[
-<!ENTITY % menuchoice.module "INCLUDE">
-<![%menuchoice.module;[
-<!ENTITY % local.menuchoice.attrib "">
-<!ENTITY % menuchoice.role.attrib "%role.attrib;">
-
-<!ENTITY % menuchoice.element "INCLUDE">
-<![%menuchoice.element;[
-<!--doc:A selection or series of selections from a menu.-->
-<!ELEMENT menuchoice %ho; (shortcut?, (guibutton|guiicon|guilabel
- |guimenu|guimenuitem|guisubmenu|interface)+)>
-<!--end of menuchoice.element-->]]>
-
-<!ENTITY % menuchoice.attlist "INCLUDE">
-<![%menuchoice.attlist;[
-<!ATTLIST menuchoice
- %moreinfo.attrib;
- %common.attrib;
- %menuchoice.role.attrib;
- %local.menuchoice.attrib;
->
-<!--end of menuchoice.attlist-->]]>
-<!--end of menuchoice.module-->]]>
-
-<!ENTITY % shortcut.module "INCLUDE">
-<![%shortcut.module;[
-<!-- See also KeyCombo -->
-<!ENTITY % local.shortcut.attrib "">
-<!ENTITY % shortcut.role.attrib "%role.attrib;">
-
-<!ENTITY % shortcut.element "INCLUDE">
-<![%shortcut.element;[
-<!--doc:A key combination for an action that is also accessible through a menu.-->
-<!ELEMENT shortcut %ho; ((keycap|keycombo|keysym|mousebutton)+)>
-<!--end of shortcut.element-->]]>
-
-<!ENTITY % shortcut.attlist "INCLUDE">
-<![%shortcut.attlist;[
-<!ATTLIST shortcut
- %keyaction.attrib;
- %moreinfo.attrib;
- %common.attrib;
- %shortcut.role.attrib;
- %local.shortcut.attrib;
->
-<!--end of shortcut.attlist-->]]>
-<!--end of shortcut.module-->]]>
-<!--end of menuchoice.content.module-->]]>
-
-<!ENTITY % mousebutton.module "INCLUDE">
-<![%mousebutton.module;[
-<!ENTITY % local.mousebutton.attrib "">
-<!ENTITY % mousebutton.role.attrib "%role.attrib;">
-
-<!ENTITY % mousebutton.element "INCLUDE">
-<![%mousebutton.element;[
-<!--doc:The conventional name of a mouse button.-->
-<!ELEMENT mousebutton %ho; (%smallcptr.char.mix;)*>
-<!--end of mousebutton.element-->]]>
-
-<!ENTITY % mousebutton.attlist "INCLUDE">
-<![%mousebutton.attlist;[
-<!ATTLIST mousebutton
- %moreinfo.attrib;
- %common.attrib;
- %mousebutton.role.attrib;
- %local.mousebutton.attrib;
->
-<!--end of mousebutton.attlist-->]]>
-<!--end of mousebutton.module-->]]>
-
-<!ENTITY % msgtext.module "INCLUDE">
-<![%msgtext.module;[
-<!ENTITY % local.msgtext.attrib "">
-<!ENTITY % msgtext.role.attrib "%role.attrib;">
-
-<!ENTITY % msgtext.element "INCLUDE">
-<![%msgtext.element;[
-<!--doc:The actual text of a message component in a message set.-->
-<!ELEMENT msgtext %ho; ((%component.mix;)+)>
-<!--end of msgtext.element-->]]>
-
-<!ENTITY % msgtext.attlist "INCLUDE">
-<![%msgtext.attlist;[
-<!ATTLIST msgtext
- %common.attrib;
- %msgtext.role.attrib;
- %local.msgtext.attrib;
->
-<!--end of msgtext.attlist-->]]>
-<!--end of msgtext.module-->]]>
-
-<!ENTITY % option.module "INCLUDE">
-<![%option.module;[
-<!ENTITY % local.option.attrib "">
-<!ENTITY % option.role.attrib "%role.attrib;">
-
-<!ENTITY % option.element "INCLUDE">
-<![%option.element;[
-<!--doc:An option for a software command.-->
-<!ELEMENT option %ho; (%cptr.char.mix;)*>
-<!--end of option.element-->]]>
-
-<!ENTITY % option.attlist "INCLUDE">
-<![%option.attlist;[
-<!ATTLIST option
- %common.attrib;
- %option.role.attrib;
- %local.option.attrib;
->
-<!--end of option.attlist-->]]>
-<!--end of option.module-->]]>
-
-<!ENTITY % optional.module "INCLUDE">
-<![%optional.module;[
-<!ENTITY % local.optional.attrib "">
-<!ENTITY % optional.role.attrib "%role.attrib;">
-
-<!ENTITY % optional.element "INCLUDE">
-<![%optional.element;[
-<!--doc:Optional information.-->
-<!ELEMENT optional %ho; (%cptr.char.mix;)*>
-<!--end of optional.element-->]]>
-
-<!ENTITY % optional.attlist "INCLUDE">
-<![%optional.attlist;[
-<!ATTLIST optional
- %common.attrib;
- %optional.role.attrib;
- %local.optional.attrib;
->
-<!--end of optional.attlist-->]]>
-<!--end of optional.module-->]]>
-
-<!ENTITY % parameter.module "INCLUDE">
-<![%parameter.module;[
-<!ENTITY % local.parameter.attrib "">
-<!ENTITY % parameter.role.attrib "%role.attrib;">
-
-<!ENTITY % parameter.element "INCLUDE">
-<![%parameter.element;[
-<!--doc:A value or a symbolic reference to a value.-->
-<!ELEMENT parameter %ho; (%cptr.char.mix;)*>
-<!--end of parameter.element-->]]>
-
-<!-- Class: Type of the Parameter; no default -->
-
-
-<!ENTITY % parameter.attlist "INCLUDE">
-<![%parameter.attlist;[
-<!ATTLIST parameter
- class (command
- |function
- |option) #IMPLIED
- %moreinfo.attrib;
- %common.attrib;
- %parameter.role.attrib;
- %local.parameter.attrib;
->
-<!--end of parameter.attlist-->]]>
-<!--end of parameter.module-->]]>
-
-<!ENTITY % prompt.module "INCLUDE">
-<![%prompt.module;[
-<!ENTITY % local.prompt.attrib "">
-<!ENTITY % prompt.role.attrib "%role.attrib;">
-
-<!ENTITY % prompt.element "INCLUDE">
-<![%prompt.element;[
-<!--doc:A character or string indicating the start of an input field in a computer display.-->
-<!ELEMENT prompt %ho; (%smallcptr.char.mix;|co)*>
-<!--end of prompt.element-->]]>
-
-<!ENTITY % prompt.attlist "INCLUDE">
-<![%prompt.attlist;[
-<!ATTLIST prompt
- %moreinfo.attrib;
- %common.attrib;
- %prompt.role.attrib;
- %local.prompt.attrib;
->
-<!--end of prompt.attlist-->]]>
-<!--end of prompt.module-->]]>
-
-<!ENTITY % property.module "INCLUDE">
-<![%property.module;[
-<!ENTITY % local.property.attrib "">
-<!ENTITY % property.role.attrib "%role.attrib;">
-
-<!ENTITY % property.element "INCLUDE">
-<![%property.element;[
-<!--doc:A unit of data associated with some part of a computer system.-->
-<!ELEMENT property %ho; (%cptr.char.mix;)*>
-<!--end of property.element-->]]>
-
-<!ENTITY % property.attlist "INCLUDE">
-<![%property.attlist;[
-<!ATTLIST property
- %moreinfo.attrib;
- %common.attrib;
- %property.role.attrib;
- %local.property.attrib;
->
-<!--end of property.attlist-->]]>
-<!--end of property.module-->]]>
-
-<!ENTITY % replaceable.module "INCLUDE">
-<![%replaceable.module;[
-<!ENTITY % local.replaceable.attrib "">
-<!ENTITY % replaceable.role.attrib "%role.attrib;">
-
-<!ENTITY % replaceable.element "INCLUDE">
-<![%replaceable.element;[
-<!--doc:Content that may or must be replaced by the user.-->
-<!ELEMENT replaceable %ho; (#PCDATA
- | %link.char.class;
- | optional
- | %base.char.class;
- | %other.char.class;
- | inlinegraphic
- | inlinemediaobject
- | co)*>
-<!--end of replaceable.element-->]]>
-
-<!-- Class: Type of information the element represents; no
- default -->
-
-
-<!ENTITY % replaceable.attlist "INCLUDE">
-<![%replaceable.attlist;[
-<!ATTLIST replaceable
- class (command
- |function
- |option
- |parameter) #IMPLIED
- %common.attrib;
- %replaceable.role.attrib;
- %local.replaceable.attrib;
->
-<!--end of replaceable.attlist-->]]>
-<!--end of replaceable.module-->]]>
-
-<!ENTITY % returnvalue.module "INCLUDE">
-<![%returnvalue.module;[
-<!ENTITY % local.returnvalue.attrib "">
-<!ENTITY % returnvalue.role.attrib "%role.attrib;">
-
-<!ENTITY % returnvalue.element "INCLUDE">
-<![%returnvalue.element;[
-<!--doc:The value returned by a function.-->
-<!ELEMENT returnvalue %ho; (%smallcptr.char.mix;)*>
-<!--end of returnvalue.element-->]]>
-
-<!ENTITY % returnvalue.attlist "INCLUDE">
-<![%returnvalue.attlist;[
-<!ATTLIST returnvalue
- %common.attrib;
- %returnvalue.role.attrib;
- %local.returnvalue.attrib;
->
-<!--end of returnvalue.attlist-->]]>
-<!--end of returnvalue.module-->]]>
-
-<!ENTITY % sgmltag.module "INCLUDE">
-<![%sgmltag.module;[
-<!ENTITY % local.sgmltag.attrib "">
-<!ENTITY % sgmltag.role.attrib "%role.attrib;">
-
-<!ENTITY % sgmltag.element "INCLUDE">
-<![%sgmltag.element;[
-<!--doc:A component of SGML markup.-->
-<!ELEMENT sgmltag %ho; (%smallcptr.char.mix;)*>
-<!--end of sgmltag.element-->]]>
-
-<!-- Class: Type of SGML construct the element names; no default -->
-
-
-<!ENTITY % sgmltag.attlist "INCLUDE">
-<![%sgmltag.attlist;[
-<!ATTLIST sgmltag
- class (attribute
- |attvalue
- |element
- |endtag
- |emptytag
- |genentity
- |numcharref
- |paramentity
- |pi
- |xmlpi
- |starttag
- |sgmlcomment
- |prefix
- |namespace
- |localname) #IMPLIED
- namespace CDATA #IMPLIED
- %common.attrib;
- %sgmltag.role.attrib;
- %local.sgmltag.attrib;
->
-<!--end of sgmltag.attlist-->]]>
-<!--end of sgmltag.module-->]]>
-
-<!ENTITY % structfield.module "INCLUDE">
-<![%structfield.module;[
-<!ENTITY % local.structfield.attrib "">
-<!ENTITY % structfield.role.attrib "%role.attrib;">
-
-<!ENTITY % structfield.element "INCLUDE">
-<![%structfield.element;[
-<!--doc:A field in a structure (in the programming language sense).-->
-<!ELEMENT structfield %ho; (%smallcptr.char.mix;)*>
-<!--end of structfield.element-->]]>
-
-<!ENTITY % structfield.attlist "INCLUDE">
-<![%structfield.attlist;[
-<!ATTLIST structfield
- %common.attrib;
- %structfield.role.attrib;
- %local.structfield.attrib;
->
-<!--end of structfield.attlist-->]]>
-<!--end of structfield.module-->]]>
-
-<!ENTITY % structname.module "INCLUDE">
-<![%structname.module;[
-<!ENTITY % local.structname.attrib "">
-<!ENTITY % structname.role.attrib "%role.attrib;">
-
-<!ENTITY % structname.element "INCLUDE">
-<![%structname.element;[
-<!--doc:The name of a structure (in the programming language sense).-->
-<!ELEMENT structname %ho; (%smallcptr.char.mix;)*>
-<!--end of structname.element-->]]>
-
-<!ENTITY % structname.attlist "INCLUDE">
-<![%structname.attlist;[
-<!ATTLIST structname
- %common.attrib;
- %structname.role.attrib;
- %local.structname.attrib;
->
-<!--end of structname.attlist-->]]>
-<!--end of structname.module-->]]>
-
-<!ENTITY % symbol.module "INCLUDE">
-<![%symbol.module;[
-<!ENTITY % local.symbol.attrib "">
-<!ENTITY % symbol.role.attrib "%role.attrib;">
-
-<!ENTITY % symbol.element "INCLUDE">
-<![%symbol.element;[
-<!--doc:A name that is replaced by a value before processing.-->
-<!ELEMENT symbol %ho; (%smallcptr.char.mix;)*>
-<!--end of symbol.element-->]]>
-
-<!-- Class: Type of symbol; no default -->
-
-
-<!ENTITY % symbol.attlist "INCLUDE">
-<![%symbol.attlist;[
-<!ATTLIST symbol
- class (limit) #IMPLIED
- %common.attrib;
- %symbol.role.attrib;
- %local.symbol.attrib;
->
-<!--end of symbol.attlist-->]]>
-<!--end of symbol.module-->]]>
-
-<!ENTITY % systemitem.module "INCLUDE">
-<![%systemitem.module;[
-<!ENTITY % local.systemitem.attrib "">
-<!ENTITY % systemitem.role.attrib "%role.attrib;">
-
-<!ENTITY % systemitem.element "INCLUDE">
-<![%systemitem.element;[
-<!--doc:A system-related item or term.-->
-<!ELEMENT systemitem %ho; (%cptr.char.mix; | acronym | co)*>
-<!--end of systemitem.element-->]]>
-
-<!-- Class: Type of system item the element names; no default -->
-
-<!ENTITY % systemitem.attlist "INCLUDE">
-<![%systemitem.attlist;[
-<!ATTLIST systemitem
- class (constant
- |daemon
- |domainname
- |etheraddress
- |event
- |eventhandler
- |filesystem
- |fqdomainname
- |groupname
- |ipaddress
- |library
- |macro
- |netmask
- |newsgroup
- |osname
- |protocol
- |resource
- |systemname
- |username
- |process
- |server
- |service) #IMPLIED
- %moreinfo.attrib;
- %common.attrib;
- %systemitem.role.attrib;
- %local.systemitem.attrib;
->
-<!--end of systemitem.attlist-->]]>
-<!--end of systemitem.module-->]]>
-
-<!ENTITY % uri.module "INCLUDE">
-<![%uri.module;[
-<!ENTITY % local.uri.attrib "">
-<!ENTITY % uri.role.attrib "%role.attrib;">
-
-<!ENTITY % uri.element "INCLUDE">
-<![%uri.element;[
-<!--doc:A Uniform Resource Identifier.-->
-<!ELEMENT uri %ho; (%smallcptr.char.mix;)*>
-<!--end of uri.element-->]]>
-
-<!-- Type: Type of URI; no default -->
-
-<!ENTITY % uri.attlist "INCLUDE">
-<![%uri.attlist;[
-<!ATTLIST uri
- type CDATA #IMPLIED
- %common.attrib;
- %uri.role.attrib;
- %local.uri.attrib;
->
-<!--end of uri.attlist-->]]>
-<!--end of uri.module-->]]>
-
-<!ENTITY % token.module "INCLUDE">
-<![%token.module;[
-<!ENTITY % local.token.attrib "">
-<!ENTITY % token.role.attrib "%role.attrib;">
-
-<!ENTITY % token.element "INCLUDE">
-<![%token.element;[
-<!--doc:A unit of information.-->
-<!ELEMENT token %ho; (%smallcptr.char.mix;)*>
-<!--end of token.element-->]]>
-
-<!ENTITY % token.attlist "INCLUDE">
-<![%token.attlist;[
-<!ATTLIST token
- %common.attrib;
- %token.role.attrib;
- %local.token.attrib;
->
-<!--end of token.attlist-->]]>
-<!--end of token.module-->]]>
-
-<!ENTITY % type.module "INCLUDE">
-<![%type.module;[
-<!ENTITY % local.type.attrib "">
-<!ENTITY % type.role.attrib "%role.attrib;">
-
-<!ENTITY % type.element "INCLUDE">
-<![%type.element;[
-<!--doc:The classification of a value.-->
-<!ELEMENT type %ho; (%smallcptr.char.mix;)*>
-<!--end of type.element-->]]>
-
-<!ENTITY % type.attlist "INCLUDE">
-<![%type.attlist;[
-<!ATTLIST type
- %common.attrib;
- %type.role.attrib;
- %local.type.attrib;
->
-<!--end of type.attlist-->]]>
-<!--end of type.module-->]]>
-
-<!ENTITY % userinput.module "INCLUDE">
-<![%userinput.module;[
-<!ENTITY % local.userinput.attrib "">
-<!ENTITY % userinput.role.attrib "%role.attrib;">
-
-<!ENTITY % userinput.element "INCLUDE">
-<![%userinput.element;[
-<!--doc:Data entered by the user.-->
-<!ELEMENT userinput %ho; (%cptr.char.mix;|co)*>
-<!--end of userinput.element-->]]>
-
-<!ENTITY % userinput.attlist "INCLUDE">
-<![%userinput.attlist;[
-<!ATTLIST userinput
- %moreinfo.attrib;
- %common.attrib;
- %userinput.role.attrib;
- %local.userinput.attrib;
->
-<!--end of userinput.attlist-->]]>
-<!--end of userinput.module-->]]>
-
-<!ENTITY % termdef.module "INCLUDE">
-<![%termdef.module;[
-<!ENTITY % local.termdef.attrib "">
-<!ENTITY % termdef.role.attrib "%role.attrib;">
-
-<!ENTITY % termdef.element "INCLUDE">
-<![%termdef.element;[
-<!--doc:An inline definition of a term.-->
-<!ELEMENT termdef %ho; (%para.char.mix;)*>
-<!--end of termdef.element-->]]>
-
-<!ENTITY % termdef.attlist "INCLUDE">
-<![%termdef.attlist;[
-<!ATTLIST termdef
- %common.attrib;
- %termdef.role.attrib;
- %local.termdef.attrib;
->
-<!--end of termdef.attlist-->]]>
-<!--end of termdef.module-->]]>
-
-<!-- General words and phrases ............................................ -->
-
-<!ENTITY % abbrev.module "INCLUDE">
-<![%abbrev.module;[
-<!ENTITY % local.abbrev.attrib "">
-<!ENTITY % abbrev.role.attrib "%role.attrib;">
-
-<!ENTITY % abbrev.element "INCLUDE">
-<![%abbrev.element;[
-<!--doc:An abbreviation, especially one followed by a period.-->
-<!ELEMENT abbrev %ho; (%word.char.mix;)*>
-<!--end of abbrev.element-->]]>
-
-<!ENTITY % abbrev.attlist "INCLUDE">
-<![%abbrev.attlist;[
-<!ATTLIST abbrev
- %common.attrib;
- %abbrev.role.attrib;
- %local.abbrev.attrib;
->
-<!--end of abbrev.attlist-->]]>
-<!--end of abbrev.module-->]]>
-
-<!ENTITY % acronym.module "INCLUDE">
-<![%acronym.module;[
-<!ENTITY % local.acronym.attrib "">
-<!ENTITY % acronym.role.attrib "%role.attrib;">
-
-<!ENTITY % acronym.element "INCLUDE">
-<![%acronym.element;[
-<!--doc:An often pronounceable word made from the initial (or selected) letters of a name or phrase.-->
-<!ELEMENT acronym %ho; (%word.char.mix;)*
- %acronym.exclusion;>
-<!--end of acronym.element-->]]>
-
-<!ENTITY % acronym.attlist "INCLUDE">
-<![%acronym.attlist;[
-<!ATTLIST acronym
- %common.attrib;
- %acronym.role.attrib;
- %local.acronym.attrib;
->
-<!--end of acronym.attlist-->]]>
-<!--end of acronym.module-->]]>
-
-<!ENTITY % citation.module "INCLUDE">
-<![%citation.module;[
-<!ENTITY % local.citation.attrib "">
-<!ENTITY % citation.role.attrib "%role.attrib;">
-
-<!ENTITY % citation.element "INCLUDE">
-<![%citation.element;[
-<!--doc:An inline bibliographic reference to another published work.-->
-<!ELEMENT citation %ho; (%para.char.mix;)*>
-<!--end of citation.element-->]]>
-
-<!ENTITY % citation.attlist "INCLUDE">
-<![%citation.attlist;[
-<!ATTLIST citation
- %common.attrib;
- %citation.role.attrib;
- %local.citation.attrib;
->
-<!--end of citation.attlist-->]]>
-<!--end of citation.module-->]]>
-
-<!ENTITY % citerefentry.module "INCLUDE">
-<![%citerefentry.module;[
-<!ENTITY % local.citerefentry.attrib "">
-<!ENTITY % citerefentry.role.attrib "%role.attrib;">
-
-<!ENTITY % citerefentry.element "INCLUDE">
-<![%citerefentry.element;[
-<!--doc:A citation to a reference page.-->
-<!ELEMENT citerefentry %ho; (refentrytitle, manvolnum?)>
-<!--end of citerefentry.element-->]]>
-
-<!ENTITY % citerefentry.attlist "INCLUDE">
-<![%citerefentry.attlist;[
-<!ATTLIST citerefentry
- %common.attrib;
- %citerefentry.role.attrib;
- %local.citerefentry.attrib;
->
-<!--end of citerefentry.attlist-->]]>
-<!--end of citerefentry.module-->]]>
-
-<!ENTITY % refentrytitle.module "INCLUDE">
-<![%refentrytitle.module;[
-<!ENTITY % local.refentrytitle.attrib "">
-<!ENTITY % refentrytitle.role.attrib "%role.attrib;">
-
-<!ENTITY % refentrytitle.element "INCLUDE">
-<![%refentrytitle.element;[
-<!--doc:The title of a reference page.-->
-<!ELEMENT refentrytitle %ho; (%para.char.mix;)*>
-<!--end of refentrytitle.element-->]]>
-
-<!ENTITY % refentrytitle.attlist "INCLUDE">
-<![%refentrytitle.attlist;[
-<!ATTLIST refentrytitle
- %common.attrib;
- %refentrytitle.role.attrib;
- %local.refentrytitle.attrib;
->
-<!--end of refentrytitle.attlist-->]]>
-<!--end of refentrytitle.module-->]]>
-
-<!ENTITY % manvolnum.module "INCLUDE">
-<![%manvolnum.module;[
-<!ENTITY % local.manvolnum.attrib "">
-<!ENTITY % namvolnum.role.attrib "%role.attrib;">
-
-<!ENTITY % manvolnum.element "INCLUDE">
-<![%manvolnum.element;[
-<!--doc:A reference volume number.-->
-<!ELEMENT manvolnum %ho; (%word.char.mix;)*>
-<!--end of manvolnum.element-->]]>
-
-<!ENTITY % manvolnum.attlist "INCLUDE">
-<![%manvolnum.attlist;[
-<!ATTLIST manvolnum
- %common.attrib;
- %namvolnum.role.attrib;
- %local.manvolnum.attrib;
->
-<!--end of manvolnum.attlist-->]]>
-<!--end of manvolnum.module-->]]>
-
-<!ENTITY % citetitle.module "INCLUDE">
-<![%citetitle.module;[
-<!ENTITY % local.citetitle.attrib "">
-<!ENTITY % citetitle.role.attrib "%role.attrib;">
-
-<!ENTITY % citetitle.element "INCLUDE">
-<![%citetitle.element;[
-<!--doc:The title of a cited work.-->
-<!ELEMENT citetitle %ho; (%para.char.mix;)*>
-<!--end of citetitle.element-->]]>
-
-<!-- Pubwork: Genre of published work cited; no default -->
-
-
-<!ENTITY % citetitle.attlist "INCLUDE">
-<![%citetitle.attlist;[
-<!ATTLIST citetitle
- pubwork (article
- |book
- |chapter
- |part
- |refentry
- |section
- |journal
- |series
- |set
- |manuscript
- |cdrom
- |dvd
- |wiki
- |gopher
- |bbs
- |emailmessage
- |webpage
- |newsposting) #IMPLIED
- %common.attrib;
- %citetitle.role.attrib;
- %local.citetitle.attrib;
->
-<!--end of citetitle.attlist-->]]>
-<!--end of citetitle.module-->]]>
-
-<!ENTITY % emphasis.module "INCLUDE">
-<![%emphasis.module;[
-<!ENTITY % local.emphasis.attrib "">
-<!ENTITY % emphasis.role.attrib "%role.attrib;">
-
-<!ENTITY % emphasis.element "INCLUDE">
-<![%emphasis.element;[
-<!--doc:Emphasized text.-->
-<!ELEMENT emphasis %ho; (%para.char.mix;)*>
-<!--end of emphasis.element-->]]>
-
-<!ENTITY % emphasis.attlist "INCLUDE">
-<![%emphasis.attlist;[
-<!ATTLIST emphasis
- %common.attrib;
- %emphasis.role.attrib;
- %local.emphasis.attrib;
->
-<!--end of emphasis.attlist-->]]>
-<!--end of emphasis.module-->]]>
-
-<!ENTITY % foreignphrase.module "INCLUDE">
-<![%foreignphrase.module;[
-<!ENTITY % local.foreignphrase.attrib "">
-<!ENTITY % foreignphrase.role.attrib "%role.attrib;">
-
-<!ENTITY % foreignphrase.element "INCLUDE">
-<![%foreignphrase.element;[
-<!--doc:A word or phrase in a language other than the primary language of the document.-->
-<!ELEMENT foreignphrase %ho; (%para.char.mix;)*>
-<!--end of foreignphrase.element-->]]>
-
-<!ENTITY % foreignphrase.attlist "INCLUDE">
-<![%foreignphrase.attlist;[
-<!ATTLIST foreignphrase
- %common.attrib;
- %foreignphrase.role.attrib;
- %local.foreignphrase.attrib;
->
-<!--end of foreignphrase.attlist-->]]>
-<!--end of foreignphrase.module-->]]>
-
-<!ENTITY % glossterm.module "INCLUDE">
-<![%glossterm.module;[
-<!ENTITY % local.glossterm.attrib "">
-<!ENTITY % glossterm.role.attrib "%role.attrib;">
-
-<!ENTITY % glossterm.element "INCLUDE">
-<![%glossterm.element;[
-<!--doc:A glossary term.-->
-<!ELEMENT glossterm %ho; (%para.char.mix;)*
- %glossterm.exclusion;>
-<!--end of glossterm.element-->]]>
-
-<!-- to GlossEntry if Glossterm used in text -->
-<!-- BaseForm: Provides the form of GlossTerm to be used
- for indexing -->
-
-<!ENTITY % glossterm.attlist "INCLUDE">
-<![%glossterm.attlist;[
-<!ATTLIST glossterm
- baseform CDATA #IMPLIED
- %linkend.attrib;
- %common.attrib;
- %glossterm.role.attrib;
- %local.glossterm.attrib;
->
-<!--end of glossterm.attlist-->]]>
-<!--end of glossterm.module-->]]>
-
-<!ENTITY % firstterm.module "INCLUDE">
-<![%firstterm.module;[
-<!ENTITY % local.firstterm.attrib "">
-<!ENTITY % firstterm.role.attrib "%role.attrib;">
-
-<!ENTITY % firstterm.element "INCLUDE">
-<![%firstterm.element;[
-<!--doc:The first occurrence of a term.-->
-<!ELEMENT firstterm %ho; (%para.char.mix;)*
- %glossterm.exclusion;>
-<!--end of firstterm.element-->]]>
-
-<!-- to GlossEntry or other explanation -->
-
-
-<!ENTITY % firstterm.attlist "INCLUDE">
-<![%firstterm.attlist;[
-<!ATTLIST firstterm
- baseform CDATA #IMPLIED
- %linkend.attrib;
- %common.attrib;
- %firstterm.role.attrib;
- %local.firstterm.attrib;
->
-<!--end of firstterm.attlist-->]]>
-<!--end of firstterm.module-->]]>
-
-<!ENTITY % phrase.module "INCLUDE">
-<![%phrase.module;[
-<!ENTITY % local.phrase.attrib "">
-<!ENTITY % phrase.role.attrib "%role.attrib;">
-
-<!ENTITY % phrase.element "INCLUDE">
-<![%phrase.element;[
-<!--doc:A span of text.-->
-<!ELEMENT phrase %ho; (%para.char.mix;)*>
-<!--end of phrase.element-->]]>
-
-<!ENTITY % phrase.attlist "INCLUDE">
-<![%phrase.attlist;[
-<!ATTLIST phrase
- %common.attrib;
- %phrase.role.attrib;
- %local.phrase.attrib;
->
-<!--end of phrase.attlist-->]]>
-<!--end of phrase.module-->]]>
-
-<!ENTITY % quote.module "INCLUDE">
-<![%quote.module;[
-<!ENTITY % local.quote.attrib "">
-<!ENTITY % quote.role.attrib "%role.attrib;">
-
-<!ENTITY % quote.element "INCLUDE">
-<![%quote.element;[
-<!--doc:An inline quotation.-->
-<!ELEMENT quote %ho; (%para.char.mix;)*>
-<!--end of quote.element-->]]>
-
-<!ENTITY % quote.attlist "INCLUDE">
-<![%quote.attlist;[
-<!ATTLIST quote
- %common.attrib;
- %quote.role.attrib;
- %local.quote.attrib;
->
-<!--end of quote.attlist-->]]>
-<!--end of quote.module-->]]>
-
-<!ENTITY % ssscript.module "INCLUDE">
-<![%ssscript.module;[
-<!ENTITY % local.ssscript.attrib "">
-<!ENTITY % ssscript.role.attrib "%role.attrib;">
-
-<!ENTITY % subscript.element "INCLUDE">
-<![%subscript.element;[
-<!--doc:A subscript (as in H{^2}O, the molecular formula for water).-->
-<!ELEMENT subscript %ho; (#PCDATA
- | %link.char.class;
- | emphasis
- | replaceable
- | symbol
- | inlinegraphic
- | inlinemediaobject
- | %base.char.class;
- | %other.char.class;)*
- %ubiq.exclusion;>
-<!--end of subscript.element-->]]>
-
-<!ENTITY % subscript.attlist "INCLUDE">
-<![%subscript.attlist;[
-<!ATTLIST subscript
- %common.attrib;
- %ssscript.role.attrib;
- %local.ssscript.attrib;
->
-<!--end of subscript.attlist-->]]>
-
-<!ENTITY % superscript.element "INCLUDE">
-<![%superscript.element;[
-<!--doc:A superscript (as in x^2, the mathematical notation for x multiplied by itself).-->
-<!ELEMENT superscript %ho; (#PCDATA
- | %link.char.class;
- | emphasis
- | replaceable
- | symbol
- | inlinegraphic
- | inlinemediaobject
- | %base.char.class;
- | %other.char.class;)*
- %ubiq.exclusion;>
-<!--end of superscript.element-->]]>
-
-<!ENTITY % superscript.attlist "INCLUDE">
-<![%superscript.attlist;[
-<!ATTLIST superscript
- %common.attrib;
- %ssscript.role.attrib;
- %local.ssscript.attrib;
->
-<!--end of superscript.attlist-->]]>
-<!--end of ssscript.module-->]]>
-
-<!ENTITY % trademark.module "INCLUDE">
-<![%trademark.module;[
-<!ENTITY % local.trademark.attrib "">
-<!ENTITY % trademark.role.attrib "%role.attrib;">
-
-<!ENTITY % trademark.element "INCLUDE">
-<![%trademark.element;[
-<!--doc:A trademark.-->
-<!ELEMENT trademark %ho; (#PCDATA
- | %link.char.class;
- | %tech.char.class;
- | %base.char.class;
- | %other.char.class;
- | inlinegraphic
- | inlinemediaobject
- | emphasis)*>
-<!--end of trademark.element-->]]>
-
-<!-- Class: More precisely identifies the item the element names -->
-
-
-<!ENTITY % trademark.attlist "INCLUDE">
-<![%trademark.attlist;[
-<!ATTLIST trademark
- class (service
- |trade
- |registered
- |copyright) 'trade'
- %common.attrib;
- %trademark.role.attrib;
- %local.trademark.attrib;
->
-<!--end of trademark.attlist-->]]>
-<!--end of trademark.module-->]]>
-
-<!ENTITY % wordasword.module "INCLUDE">
-<![%wordasword.module;[
-<!ENTITY % local.wordasword.attrib "">
-<!ENTITY % wordasword.role.attrib "%role.attrib;">
-
-<!ENTITY % wordasword.element "INCLUDE">
-<![%wordasword.element;[
-<!--doc:A word meant specifically as a word and not representing anything else.-->
-<!ELEMENT wordasword %ho; (%word.char.mix;)*>
-<!--end of wordasword.element-->]]>
-
-<!ENTITY % wordasword.attlist "INCLUDE">
-<![%wordasword.attlist;[
-<!ATTLIST wordasword
- %common.attrib;
- %wordasword.role.attrib;
- %local.wordasword.attrib;
->
-<!--end of wordasword.attlist-->]]>
-<!--end of wordasword.module-->]]>
-
-<!-- Links and cross-references ........................................... -->
-
-<!ENTITY % link.module "INCLUDE">
-<![%link.module;[
-<!ENTITY % local.link.attrib "">
-<!ENTITY % link.role.attrib "%role.attrib;">
-
-<!ENTITY % link.element "INCLUDE">
-<![%link.element;[
-<!--doc:A hypertext link.-->
-<!ELEMENT link %ho; (%para.char.mix;)*
- %links.exclusion;>
-<!--end of link.element-->]]>
-
-<!-- Endterm: ID of element containing text that is to be
- fetched from elsewhere in the document to appear as
- the content of this element -->
-<!-- to linked-to object -->
-<!-- Type: Freely assignable parameter -->
-
-
-<!ENTITY % link.attlist "INCLUDE">
-<![%link.attlist;[
-<!ATTLIST link
- endterm IDREF #IMPLIED
- xrefstyle CDATA #IMPLIED
- type CDATA #IMPLIED
- %linkendreq.attrib;
- %common.attrib;
- %link.role.attrib;
- %local.link.attrib;
->
-<!--end of link.attlist-->]]>
-<!--end of link.module-->]]>
-
-<!ENTITY % olink.module "INCLUDE">
-<![%olink.module;[
-<!ENTITY % local.olink.attrib "">
-<!ENTITY % olink.role.attrib "%role.attrib;">
-
-<!ENTITY % olink.element "INCLUDE">
-<![%olink.element;[
-<!--doc:A link that addresses its target indirectly, through an entity.-->
-<!ELEMENT olink %ho; (%para.char.mix;)*
- %links.exclusion;>
-<!--end of olink.element-->]]>
-
-<!-- TargetDocEnt: Name of an entity to be the target of the link -->
-<!-- LinkMode: ID of a ModeSpec containing instructions for
- operating on the entity named by TargetDocEnt -->
-<!-- LocalInfo: Information that may be passed to ModeSpec -->
-<!-- Type: Freely assignable parameter -->
-
-
-<!ENTITY % olink.attlist "INCLUDE">
-<![%olink.attlist;[
-<!ATTLIST olink
- targetdocent ENTITY #IMPLIED
- linkmode IDREF #IMPLIED
- localinfo CDATA #IMPLIED
- type CDATA #IMPLIED
- targetdoc CDATA #IMPLIED
- targetptr CDATA #IMPLIED
- xrefstyle CDATA #IMPLIED
- %common.attrib;
- %olink.role.attrib;
- %local.olink.attrib;
->
-<!--end of olink.attlist-->]]>
-<!--end of olink.module-->]]>
-
-<!ENTITY % ulink.module "INCLUDE">
-<![%ulink.module;[
-<!ENTITY % local.ulink.attrib "">
-<!ENTITY % ulink.role.attrib "%role.attrib;">
-
-<!ENTITY % ulink.element "INCLUDE">
-<![%ulink.element;[
-<!--doc:A link that addresses its target by means of a URL (Uniform Resource Locator).-->
-<!ELEMENT ulink %ho; (%para.char.mix;)*
- %links.exclusion;>
-<!--end of ulink.element-->]]>
-
-<!-- URL: uniform resource locator; the target of the ULink -->
-<!-- Type: Freely assignable parameter -->
-
-
-<!ENTITY % ulink.attlist "INCLUDE">
-<![%ulink.attlist;[
-<!ATTLIST ulink
- url CDATA #REQUIRED
- type CDATA #IMPLIED
- xrefstyle CDATA #IMPLIED
- %common.attrib;
- %ulink.role.attrib;
- %local.ulink.attrib;
->
-<!--end of ulink.attlist-->]]>
-<!--end of ulink.module-->]]>
-
-<!ENTITY % footnoteref.module "INCLUDE">
-<![%footnoteref.module;[
-<!ENTITY % local.footnoteref.attrib "">
-<!ENTITY % footnoteref.role.attrib "%role.attrib;">
-
-<!ENTITY % footnoteref.element "INCLUDE">
-<![%footnoteref.element;[
-<!--doc:A cross reference to a footnote (a footnote mark).-->
-<!ELEMENT footnoteref %ho; EMPTY>
-<!--end of footnoteref.element-->]]>
-
-<!-- to footnote content supplied elsewhere -->
-
-
-<!ENTITY % footnoteref.attlist "INCLUDE">
-<![%footnoteref.attlist;[
-<!ATTLIST footnoteref
- %linkendreq.attrib; %label.attrib;
- %common.attrib;
- %footnoteref.role.attrib;
- %local.footnoteref.attrib;
->
-<!--end of footnoteref.attlist-->]]>
-<!--end of footnoteref.module-->]]>
-
-<!ENTITY % xref.module "INCLUDE">
-<![%xref.module;[
-<!ENTITY % local.xref.attrib "">
-<!ENTITY % xref.role.attrib "%role.attrib;">
-
-<!ENTITY % xref.element "INCLUDE">
-<![%xref.element;[
-<!--doc:A cross reference to another part of the document.-->
-<!ELEMENT xref %ho; EMPTY>
-<!--end of xref.element-->]]>
-
-<!-- Endterm: ID of element containing text that is to be
- fetched from elsewhere in the document to appear as
- the content of this element -->
-<!-- to linked-to object -->
-
-
-<!ENTITY % xref.attlist "INCLUDE">
-<![%xref.attlist;[
-<!ATTLIST xref
- endterm IDREF #IMPLIED
- xrefstyle CDATA #IMPLIED
- %common.attrib;
- %linkendreq.attrib;
- %xref.role.attrib;
- %local.xref.attrib;
->
-<!--end of xref.attlist-->]]>
-<!--end of xref.module-->]]>
-
-<!ENTITY % biblioref.module "INCLUDE">
-<![%biblioref.module;[
-<!ENTITY % local.biblioref.attrib "">
-<!ENTITY % biblioref.role.attrib "%role.attrib;">
-
-<!ENTITY % biblioref.element "INCLUDE">
-<![%biblioref.element;[
-<!--doc:A cross reference to a bibliographic entry.-->
-<!ELEMENT biblioref %ho; EMPTY>
-<!--end of biblioref.element-->]]>
-
-<!ENTITY % biblioref.attlist "INCLUDE">
-<![%biblioref.attlist;[
-<!ATTLIST biblioref
- endterm IDREF #IMPLIED
- xrefstyle CDATA #IMPLIED
- units CDATA #IMPLIED
- begin CDATA #IMPLIED
- end CDATA #IMPLIED
- %common.attrib;
- %linkendreq.attrib;
- %biblioref.role.attrib;
- %local.biblioref.attrib;
->
-<!--end of biblioref.attlist-->]]>
-<!--end of biblioref.module-->]]>
-
-<!-- Ubiquitous elements .................................................. -->
-
-<!ENTITY % anchor.module "INCLUDE">
-<![%anchor.module;[
-<!ENTITY % local.anchor.attrib "">
-<!ENTITY % anchor.role.attrib "%role.attrib;">
-
-<!ENTITY % anchor.element "INCLUDE">
-<![%anchor.element;[
-<!--doc:A spot in the document.-->
-<!ELEMENT anchor %ho; EMPTY>
-<!--end of anchor.element-->]]>
-
-<!-- required -->
-<!-- replaces Lang -->
-
-
-<!ENTITY % anchor.attlist "INCLUDE">
-<![%anchor.attlist;[
-<!ATTLIST anchor
- %idreq.attrib; %pagenum.attrib; %remap.attrib;
- %xreflabel.attrib;
- %revisionflag.attrib;
- %effectivity.attrib;
- %anchor.role.attrib;
- %local.anchor.attrib;
->
-<!--end of anchor.attlist-->]]>
-<!--end of anchor.module-->]]>
-
-<!ENTITY % beginpage.module "INCLUDE">
-<![%beginpage.module;[
-<!ENTITY % local.beginpage.attrib "">
-<!ENTITY % beginpage.role.attrib "%role.attrib;">
-
-<!ENTITY % beginpage.element "INCLUDE">
-<![%beginpage.element;[
-<!--doc:The location of a page break in a print version of the document.-->
-<!ELEMENT beginpage %ho; EMPTY>
-<!--end of beginpage.element-->]]>
-
-<!-- PageNum: Number of page that begins at this point -->
-
-
-<!ENTITY % beginpage.attlist "INCLUDE">
-<![%beginpage.attlist;[
-<!ATTLIST beginpage
- %pagenum.attrib;
- %common.attrib;
- %beginpage.role.attrib;
- %local.beginpage.attrib;
->
-<!--end of beginpage.attlist-->]]>
-<!--end of beginpage.module-->]]>
-
-<!-- IndexTerms appear in the text flow for generating or linking an
- index. -->
-
-<!ENTITY % indexterm.content.module "INCLUDE">
-<![%indexterm.content.module;[
-<!ENTITY % indexterm.module "INCLUDE">
-<![%indexterm.module;[
-<!ENTITY % local.indexterm.attrib "">
-<!ENTITY % indexterm.role.attrib "%role.attrib;">
-
-<!ENTITY % indexterm.element "INCLUDE">
-<![%indexterm.element;[
-<!--doc:A wrapper for terms to be indexed.-->
-<!ELEMENT indexterm %ho; (primary?, ((secondary, ((tertiary, (see|seealso+)?)
- | see | seealso+)?) | see | seealso+)?)
- %ubiq.exclusion;>
-<!--end of indexterm.element-->]]>
-
-<!-- Scope: Indicates which generated indices the IndexTerm
- should appear in: Global (whole document set), Local (this
- document only), or All (both) -->
-<!-- Significance: Whether this IndexTerm is the most pertinent
- of its series (Preferred) or not (Normal, the default) -->
-<!-- Class: Indicates type of IndexTerm; default is Singular,
- or EndOfRange if StartRef is supplied; StartOfRange value
- must be supplied explicitly on starts of ranges -->
-<!-- StartRef: ID of the IndexTerm that starts the indexing
- range ended by this IndexTerm -->
-<!-- Zone: IDs of the elements to which the IndexTerm applies,
- and indicates that the IndexTerm applies to those entire
- elements rather than the point at which the IndexTerm
- occurs -->
-
-
-<!ENTITY % indexterm.attlist "INCLUDE">
-<![%indexterm.attlist;[
-<!ATTLIST indexterm
- %pagenum.attrib;
- scope (all
- |global
- |local) #IMPLIED
- significance (preferred
- |normal) "normal"
- class (singular
- |startofrange
- |endofrange) #IMPLIED
- startref IDREF #IMPLIED
- zone IDREFS #IMPLIED
- type CDATA #IMPLIED
- %common.attrib;
- %indexterm.role.attrib;
- %local.indexterm.attrib;
->
-<!--end of indexterm.attlist-->]]>
-<!--end of indexterm.module-->]]>
-
-<!ENTITY % primsecter.module "INCLUDE">
-<![%primsecter.module;[
-<!ENTITY % local.primsecter.attrib "">
-<!ENTITY % primsecter.role.attrib "%role.attrib;">
-
-
-<!ENTITY % primary.element "INCLUDE">
-<![%primary.element;[
-<!--doc:The primary word or phrase under which an index term should be sorted.-->
-<!ELEMENT primary %ho; (%ndxterm.char.mix;)*>
-<!--end of primary.element-->]]>
-<!-- SortAs: Alternate sort string for index sorting, e.g.,
- "fourteen" for an element containing "14" -->
-
-<!ENTITY % primary.attlist "INCLUDE">
-<![%primary.attlist;[
-<!ATTLIST primary
- sortas CDATA #IMPLIED
- %common.attrib;
- %primsecter.role.attrib;
- %local.primsecter.attrib;
->
-<!--end of primary.attlist-->]]>
-
-
-<!ENTITY % secondary.element "INCLUDE">
-<![%secondary.element;[
-<!--doc:A secondary word or phrase in an index term.-->
-<!ELEMENT secondary %ho; (%ndxterm.char.mix;)*>
-<!--end of secondary.element-->]]>
-<!-- SortAs: Alternate sort string for index sorting, e.g.,
- "fourteen" for an element containing "14" -->
-
-<!ENTITY % secondary.attlist "INCLUDE">
-<![%secondary.attlist;[
-<!ATTLIST secondary
- sortas CDATA #IMPLIED
- %common.attrib;
- %primsecter.role.attrib;
- %local.primsecter.attrib;
->
-<!--end of secondary.attlist-->]]>
-
-
-<!ENTITY % tertiary.element "INCLUDE">
-<![%tertiary.element;[
-<!--doc:A tertiary word or phrase in an index term.-->
-<!ELEMENT tertiary %ho; (%ndxterm.char.mix;)*>
-<!--end of tertiary.element-->]]>
-<!-- SortAs: Alternate sort string for index sorting, e.g.,
- "fourteen" for an element containing "14" -->
-
-<!ENTITY % tertiary.attlist "INCLUDE">
-<![%tertiary.attlist;[
-<!ATTLIST tertiary
- sortas CDATA #IMPLIED
- %common.attrib;
- %primsecter.role.attrib;
- %local.primsecter.attrib;
->
-<!--end of tertiary.attlist-->]]>
-
-<!--end of primsecter.module-->]]>
-
-<!ENTITY % seeseealso.module "INCLUDE">
-<![%seeseealso.module;[
-<!ENTITY % local.seeseealso.attrib "">
-<!ENTITY % seeseealso.role.attrib "%role.attrib;">
-
-<!ENTITY % see.element "INCLUDE">
-<![%see.element;[
-<!--doc:Part of an index term directing the reader instead to another entry in the index.-->
-<!ELEMENT see %ho; (%ndxterm.char.mix;)*>
-<!--end of see.element-->]]>
-
-<!ENTITY % see.attlist "INCLUDE">
-<![%see.attlist;[
-<!ATTLIST see
- %common.attrib;
- %seeseealso.role.attrib;
- %local.seeseealso.attrib;
->
-<!--end of see.attlist-->]]>
-
-<!ENTITY % seealso.element "INCLUDE">
-<![%seealso.element;[
-<!--doc:Part of an index term directing the reader also to another entry in the index.-->
-<!ELEMENT seealso %ho; (%ndxterm.char.mix;)*>
-<!--end of seealso.element-->]]>
-
-<!ENTITY % seealso.attlist "INCLUDE">
-<![%seealso.attlist;[
-<!ATTLIST seealso
- %common.attrib;
- %seeseealso.role.attrib;
- %local.seeseealso.attrib;
->
-<!--end of seealso.attlist-->]]>
-<!--end of seeseealso.module-->]]>
-<!--end of indexterm.content.module-->]]>
-
-<!-- End of DocBook XML information pool module V4.5 ...................... -->
-<!-- ...................................................................... -->
diff --git a/Utilities/xml/docbook-4.5/docbook.cat b/Utilities/xml/docbook-4.5/docbook.cat
deleted file mode 100644
index 25ac4dff0..000000000
--- a/Utilities/xml/docbook-4.5/docbook.cat
+++ /dev/null
@@ -1,113 +0,0 @@
- -- ...................................................................... --
- -- Catalog data for DocBook XML V4.5 .................................... --
- -- File docbook.cat ..................................................... --
-
- -- Please direct all questions, bug reports, or suggestions for
- changes to the docbook@lists.oasis-open.org mailing list. For more
- information, see http://www.oasis-open.org/.
- --
-
- -- This is the catalog data file for DocBook XML V4.5. It is provided as
- a convenience in building your own catalog files. You need not use
- the filenames listed here, and need not use the filename method of
- identifying storage objects at all. See the documentation for
- detailed information on the files associated with the DocBook DTD.
- See SGML Open Technical Resolution 9401 for detailed information
- on supplying and using catalog data.
- --
-
- -- ...................................................................... --
- -- DocBook driver file .................................................. --
-
-PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
- "docbookx.dtd"
-
- -- ...................................................................... --
- -- DocBook modules ...................................................... --
-
-PUBLIC "-//OASIS//DTD DocBook CALS Table Model V4.5//EN"
- "calstblx.dtd"
-
-PUBLIC "-//OASIS//ELEMENTS DocBook XML HTML Tables V4.5//EN"
- "htmltblx.mod"
-
-PUBLIC "-//OASIS//DTD XML Exchange Table Model 19990315//EN"
- "soextblx.dtd"
-
-PUBLIC "-//OASIS//ELEMENTS DocBook Information Pool V4.5//EN"
- "dbpoolx.mod"
-
-PUBLIC "-//OASIS//ELEMENTS DocBook Document Hierarchy V4.5//EN"
- "dbhierx.mod"
-
-PUBLIC "-//OASIS//ENTITIES DocBook Additional General Entities V4.5//EN"
- "dbgenent.mod"
-
-PUBLIC "-//OASIS//ENTITIES DocBook Notations V4.5//EN"
- "dbnotnx.mod"
-
-PUBLIC "-//OASIS//ENTITIES DocBook Character Entities V4.5//EN"
- "dbcentx.mod"
-
- -- ...................................................................... --
- -- ISO entity sets ...................................................... --
-
-PUBLIC "ISO 8879:1986//ENTITIES Diacritical Marks//EN//XML"
- "ent/isodia.ent"
-
-PUBLIC "ISO 8879:1986//ENTITIES Numeric and Special Graphic//EN//XML"
- "ent/isonum.ent"
-
-PUBLIC "ISO 8879:1986//ENTITIES Publishing//EN//XML"
- "ent/isopub.ent"
-
-PUBLIC "ISO 8879:1986//ENTITIES General Technical//EN//XML"
- "ent/isotech.ent"
-
-PUBLIC "ISO 8879:1986//ENTITIES Added Latin 1//EN//XML"
- "ent/isolat1.ent"
-
-PUBLIC "ISO 8879:1986//ENTITIES Added Latin 2//EN//XML"
- "ent/isolat2.ent"
-
-PUBLIC "ISO 8879:1986//ENTITIES Greek Letters//EN//XML"
- "ent/isogrk1.ent"
-
-PUBLIC "ISO 8879:1986//ENTITIES Monotoniko Greek//EN//XML"
- "ent/isogrk2.ent"
-
-PUBLIC "ISO 8879:1986//ENTITIES Greek Symbols//EN//XML"
- "ent/isogrk3.ent"
-
-PUBLIC "ISO 8879:1986//ENTITIES Alternative Greek Symbols//EN//XML"
- "ent/isogrk4.ent"
-
-PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Arrow Relations//EN//XML"
- "ent/isoamsa.ent"
-
-PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Binary Operators//EN//XML"
- "ent/isoamsb.ent"
-
-PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Delimiters//EN//XML"
- "ent/isoamsc.ent"
-
-PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Negated Relations//EN//XML"
- "ent/isoamsn.ent"
-
-PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Ordinary//EN//XML"
- "ent/isoamso.ent"
-
-PUBLIC "ISO 8879:1986//ENTITIES Added Math Symbols: Relations//EN//XML"
- "ent/isoamsr.ent"
-
-PUBLIC "ISO 8879:1986//ENTITIES Box and Line Drawing//EN//XML"
- "ent/isobox.ent"
-
-PUBLIC "ISO 8879:1986//ENTITIES Russian Cyrillic//EN//XML"
- "ent/isocyr1.ent"
-
-PUBLIC "ISO 8879:1986//ENTITIES Non-Russian Cyrillic//EN//XML"
- "ent/isocyr2.ent"
-
- -- End of catalog data for DocBook XML V4.5 ............................. --
- -- ...................................................................... --
diff --git a/Utilities/xml/docbook-4.5/docbookx.dtd b/Utilities/xml/docbook-4.5/docbookx.dtd
deleted file mode 100644
index 8b43c59b6..000000000
--- a/Utilities/xml/docbook-4.5/docbookx.dtd
+++ /dev/null
@@ -1,170 +0,0 @@
-<!-- ...................................................................... -->
-<!-- DocBook XML DTD V4.5 ................................................. -->
-<!-- File docbookx.dtd .................................................... -->
-
-<!-- Copyright 1992-2006 HaL Computer Systems, Inc.,
- O'Reilly & Associates, Inc., ArborText, Inc., Fujitsu Software
- Corporation, Norman Walsh, Sun Microsystems, Inc., and the
- Organization for the Advancement of Structured Information
- Standards (OASIS).
-
- See also http://docbook.org/specs/
-
- $Id: docbookx.dtd 6340 2006-10-03 13:23:24Z nwalsh $
-
- Permission to use, copy, modify and distribute the DocBook XML DTD
- and its accompanying documentation for any purpose and without fee
- is hereby granted in perpetuity, provided that the above copyright
- notice and this paragraph appear in all copies. The copyright
- holders make no representation about the suitability of the DTD for
- any purpose. It is provided "as is" without expressed or implied
- warranty.
-
- If you modify the DocBook DTD in any way, except for declaring and
- referencing additional sets of general entities and declaring
- additional notations, label your DTD as a variant of DocBook. See
- the maintenance documentation for more information.
-
- Please direct all questions, bug reports, or suggestions for
- changes to the docbook@lists.oasis-open.org mailing list. For more
- information, see http://www.oasis-open.org/docbook/.
--->
-
-<!-- ...................................................................... -->
-
-<!-- This is the driver file for V4.5 of the DocBook DTD.
- Please use the following formal public identifier to identify it:
-
- "-//OASIS//DTD DocBook XML V4.5//EN"
-
- For example, if your document's top-level element is Book, and
- you are using DocBook directly, use the FPI in the DOCTYPE
- declaration:
-
- <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
- "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
- [...]>
-
- Or, if you have a higher-level driver file that customizes DocBook,
- use the FPI in the parameter entity declaration:
-
- <!ENTITY % DocBookDTD PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
- "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
- %DocBookDTD;
-
- See the documentation for detailed information on the parameter
- entity and module scheme used in DocBook, customizing DocBook and
- planning for interchange, and changes made since the last release
- of DocBook.
--->
-
-<!-- ...................................................................... -->
-<!-- Enable SGML features ................................................. -->
-
-<!ENTITY % sgml.features "IGNORE">
-<![%sgml.features;[
-<!ENTITY % xml.features "IGNORE">
-]]>
-<!ENTITY % xml.features "INCLUDE">
-
-<![%sgml.features;[
-<![%xml.features;[
-
-<!-- ERROR: Exactly one of xml.features and sgml.features must be turned on! -->
-<!ENTITY % dbnotn SYSTEM "http://www.oasis-open.org/docbook/xml/configerror.txt">
-<!ENTITY % dbcent SYSTEM "http://www.oasis-open.org/docbook/xml/configerror.txt">
-<!ENTITY % dbpool SYSTEM "http://www.oasis-open.org/docbook/xml/configerror.txt">
-<!ENTITY % dbhier SYSTEM "http://www.oasis-open.org/docbook/xml/configerror.txt">
-<!ENTITY % dbgenent SYSTEM "http://www.oasis-open.org/docbook/xml/configerror.txt">
-
-]]>
-]]>
-
-<![%sgml.features;[
-<!ENTITY % ho "- O">
-<!ENTITY % hh "- -">
-]]>
-
-<![%xml.features;[
-<!ENTITY % ho "">
-<!ENTITY % hh "">
-]]>
-
-<!-- ...................................................................... -->
-<!-- Notation declarations ................................................ -->
-
-<!ENTITY % dbnotn.module "INCLUDE">
-<![%dbnotn.module;[
-<!ENTITY % dbnotn PUBLIC
-"-//OASIS//ENTITIES DocBook Notations V4.5//EN"
-"dbnotnx.mod">
-%dbnotn;
-]]>
-
-<!-- ...................................................................... -->
-<!-- ISO character entity sets ............................................ -->
-
-<!ENTITY % dbcent.module "INCLUDE">
-<![%dbcent.module;[
-
-<!ENTITY % dbcent.euro "INCLUDE">
-<![%dbcent.euro;[
-<![%sgml.features;[
-<!ENTITY euro SDATA "[euro ]"><!-- euro sign -->
-]]>
-<![%xml.features;[
-<!ENTITY euro "&#x20AC;"><!-- euro sign, U+20AC NEW -->
-]]>
-]]>
-
-<!ENTITY % dbcent PUBLIC
-"-//OASIS//ENTITIES DocBook Character Entities V4.5//EN"
-"dbcentx.mod">
-%dbcent;
-]]>
-
-<!-- ...................................................................... -->
-<!-- DTD modules .......................................................... -->
-
-<!-- Information pool .............. -->
-
-<!ENTITY % dbpool.module "INCLUDE">
-<![ %dbpool.module; [
-<!ENTITY % dbpool PUBLIC
-"-//OASIS//ELEMENTS DocBook Information Pool V4.5//EN"
-"dbpoolx.mod">
-%dbpool;
-]]>
-
-<!-- Redeclaration placeholder ..... -->
-
-<!ENTITY % intermod.redecl.module "IGNORE">
-<![%intermod.redecl.module;[
-<!-- Defining rdbmods here makes some buggy XML parsers happy. -->
-<!ENTITY % rdbmods "">
-%rdbmods;
-<!--end of intermod.redecl.module-->]]>
-
-<!-- Document hierarchy ............ -->
-
-<!ENTITY % dbhier.module "INCLUDE">
-<![ %dbhier.module; [
-<!ENTITY % dbhier PUBLIC
-"-//OASIS//ELEMENTS DocBook Document Hierarchy V4.5//EN"
-"dbhierx.mod">
-%dbhier;
-]]>
-
-<!-- ...................................................................... -->
-<!-- Other general entities ............................................... -->
-
-<!ENTITY % dbgenent.module "INCLUDE">
-<![ %dbgenent.module; [
-<!ENTITY % dbgenent PUBLIC
-"-//OASIS//ENTITIES DocBook Additional General Entities V4.5//EN"
-"dbgenent.mod">
-%dbgenent;
-]]>
-
-<!-- End of DocBook XML DTD V4.5 .......................................... -->
-<!-- ...................................................................... -->
diff --git a/Utilities/xml/docbook-4.5/ent/README b/Utilities/xml/docbook-4.5/ent/README
deleted file mode 100644
index c0da542a6..000000000
--- a/Utilities/xml/docbook-4.5/ent/README
+++ /dev/null
@@ -1,14 +0,0 @@
-XML Entity Declarations for Characters
-
-The character entity sets distributed with DocBook XML are direct
-copies of the official entities located at
-
- http://www.w3.org/2003/entities/
-
-They are distributed for historical compatibility and user convenience.
-The DocBook Technical Committee no longer attempts to maintain these
-definitions and will periodically update them from the W3C site if and
-as they are updated there.
-
-Please direct all questions or comments about the entities to the
-individuals or working groups who maintain the official sets.
diff --git a/Utilities/xml/docbook-4.5/ent/isoamsa.ent b/Utilities/xml/docbook-4.5/ent/isoamsa.ent
deleted file mode 100644
index dac3e6242..000000000
--- a/Utilities/xml/docbook-4.5/ent/isoamsa.ent
+++ /dev/null
@@ -1,97 +0,0 @@
-
-<!--
- File isoamsa.ent produced by the XSL script entities.xsl
- from input data in unicode.xml.
-
- Please report any errors to David Carlisle
- via the public W3C list www-math@w3.org.
-
- The numeric character values assigned to each entity
- (should) match the Unicode assignments in Unicode 4.0.
-
- Entity names in this file are derived from files carrying the
- following notice:
-
- (C) International Organization for Standardization 1986
- Permission to copy in any form is granted for use with
- conforming SGML systems and applications as defined in
- ISO 8879, provided this notice is included in all copies.
-
--->
-
-
-<!--
- Version: $Id: isoamsa.ent,v 1.2 2003/12/08 15:14:43 davidc Exp $
-
- Public identifier: ISO 8879:1986//ENTITIES Added Math Symbols: Arrow Relations//EN//XML
- System identifier: http://www.w3.org/2003/entities/iso8879/isoamsa.ent
-
- The public identifier should always be used verbatim.
- The system identifier may be changed to suit local requirements.
-
- Typical invocation:
-
- <!ENTITY % isoamsa PUBLIC
- "ISO 8879:1986//ENTITIES Added Math Symbols: Arrow Relations//EN//XML"
- "http://www.w3.org/2003/entities/iso8879/isoamsa.ent"
- >
- %isoamsa;
-
--->
-
-<!ENTITY cularr "&#x021B6;" ><!--ANTICLOCKWISE TOP SEMICIRCLE ARROW -->
-<!ENTITY curarr "&#x021B7;" ><!--CLOCKWISE TOP SEMICIRCLE ARROW -->
-<!ENTITY dArr "&#x021D3;" ><!--DOWNWARDS DOUBLE ARROW -->
-<!ENTITY darr2 "&#x021CA;" ><!--DOWNWARDS PAIRED ARROWS -->
-<!ENTITY dharl "&#x021C3;" ><!--DOWNWARDS HARPOON WITH BARB LEFTWARDS -->
-<!ENTITY dharr "&#x021C2;" ><!--DOWNWARDS HARPOON WITH BARB RIGHTWARDS -->
-<!ENTITY dlarr "&#x02199;" ><!--SOUTH WEST ARROW -->
-<!ENTITY drarr "&#x02198;" ><!--SOUTH EAST ARROW -->
-<!ENTITY hArr "&#x021D4;" ><!--LEFT RIGHT DOUBLE ARROW -->
-<!ENTITY harr "&#x02194;" ><!--LEFT RIGHT ARROW -->
-<!ENTITY harrw "&#x021AD;" ><!--LEFT RIGHT WAVE ARROW -->
-<!ENTITY lAarr "&#x021DA;" ><!--LEFTWARDS TRIPLE ARROW -->
-<!ENTITY Larr "&#x0219E;" ><!--LEFTWARDS TWO HEADED ARROW -->
-<!ENTITY larr2 "&#x021C7;" ><!--LEFTWARDS PAIRED ARROWS -->
-<!ENTITY larrhk "&#x021A9;" ><!--LEFTWARDS ARROW WITH HOOK -->
-<!ENTITY larrlp "&#x021AB;" ><!--LEFTWARDS ARROW WITH LOOP -->
-<!ENTITY larrtl "&#x021A2;" ><!--LEFTWARDS ARROW WITH TAIL -->
-<!ENTITY lhard "&#x021BD;" ><!--LEFTWARDS HARPOON WITH BARB DOWNWARDS -->
-<!ENTITY lharu "&#x021BC;" ><!--LEFTWARDS HARPOON WITH BARB UPWARDS -->
-<!ENTITY lrarr2 "&#x021C6;" ><!--LEFTWARDS ARROW OVER RIGHTWARDS ARROW -->
-<!ENTITY lrhar2 "&#x021CB;" ><!--LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON -->
-<!ENTITY lsh "&#x021B0;" ><!--UPWARDS ARROW WITH TIP LEFTWARDS -->
-<!ENTITY map "&#x021A6;" ><!--RIGHTWARDS ARROW FROM BAR -->
-<!ENTITY mumap "&#x022B8;" ><!--MULTIMAP -->
-<!ENTITY nearr "&#x02197;" ><!--NORTH EAST ARROW -->
-<!ENTITY nhArr "&#x021CE;" ><!--LEFT RIGHT DOUBLE ARROW WITH STROKE -->
-<!ENTITY nharr "&#x021AE;" ><!--LEFT RIGHT ARROW WITH STROKE -->
-<!ENTITY nlArr "&#x021CD;" ><!--LEFTWARDS DOUBLE ARROW WITH STROKE -->
-<!ENTITY nlarr "&#x0219A;" ><!--LEFTWARDS ARROW WITH STROKE -->
-<!ENTITY nrArr "&#x021CF;" ><!--RIGHTWARDS DOUBLE ARROW WITH STROKE -->
-<!ENTITY nrarr "&#x0219B;" ><!--RIGHTWARDS ARROW WITH STROKE -->
-<!ENTITY nwarr "&#x02196;" ><!--NORTH WEST ARROW -->
-<!ENTITY olarr "&#x021BA;" ><!--ANTICLOCKWISE OPEN CIRCLE ARROW -->
-<!ENTITY orarr "&#x021BB;" ><!--CLOCKWISE OPEN CIRCLE ARROW -->
-<!ENTITY rAarr "&#x021DB;" ><!--RIGHTWARDS TRIPLE ARROW -->
-<!ENTITY Rarr "&#x021A0;" ><!--RIGHTWARDS TWO HEADED ARROW -->
-<!ENTITY rarr2 "&#x021C9;" ><!--RIGHTWARDS PAIRED ARROWS -->
-<!ENTITY rarrhk "&#x021AA;" ><!--RIGHTWARDS ARROW WITH HOOK -->
-<!ENTITY rarrlp "&#x021AC;" ><!--RIGHTWARDS ARROW WITH LOOP -->
-<!ENTITY rarrtl "&#x021A3;" ><!--RIGHTWARDS ARROW WITH TAIL -->
-<!ENTITY rarrw "&#x0219D;" ><!--RIGHTWARDS WAVE ARROW -->
-<!ENTITY rhard "&#x021C1;" ><!--RIGHTWARDS HARPOON WITH BARB DOWNWARDS -->
-<!ENTITY rharu "&#x021C0;" ><!--RIGHTWARDS HARPOON WITH BARB UPWARDS -->
-<!ENTITY rlarr2 "&#x021C4;" ><!--RIGHTWARDS ARROW OVER LEFTWARDS ARROW -->
-<!ENTITY rlhar2 "&#x021CC;" ><!--RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON -->
-<!ENTITY rsh "&#x021B1;" ><!--UPWARDS ARROW WITH TIP RIGHTWARDS -->
-<!ENTITY uArr "&#x021D1;" ><!--UPWARDS DOUBLE ARROW -->
-<!ENTITY uarr2 "&#x021C8;" ><!--UPWARDS PAIRED ARROWS -->
-<!ENTITY uharl "&#x021BF;" ><!--UPWARDS HARPOON WITH BARB LEFTWARDS -->
-<!ENTITY uharr "&#x021BE;" ><!--UPWARDS HARPOON WITH BARB RIGHTWARDS -->
-<!ENTITY vArr "&#x021D5;" ><!--UP DOWN DOUBLE ARROW -->
-<!ENTITY varr "&#x02195;" ><!--UP DOWN ARROW -->
-<!ENTITY xhArr "&#x027FA;" ><!--LONG LEFT RIGHT DOUBLE ARROW -->
-<!ENTITY xharr "&#x027F7;" ><!--LONG LEFT RIGHT ARROW -->
-<!ENTITY xlArr "&#x027F8;" ><!--LONG LEFTWARDS DOUBLE ARROW -->
-<!ENTITY xrArr "&#x027F9;" ><!--LONG RIGHTWARDS DOUBLE ARROW -->
diff --git a/Utilities/xml/docbook-4.5/ent/isoamsb.ent b/Utilities/xml/docbook-4.5/ent/isoamsb.ent
deleted file mode 100644
index 4065b66c4..000000000
--- a/Utilities/xml/docbook-4.5/ent/isoamsb.ent
+++ /dev/null
@@ -1,83 +0,0 @@
-
-<!--
- File isoamsb.ent produced by the XSL script entities.xsl
- from input data in unicode.xml.
-
- Please report any errors to David Carlisle
- via the public W3C list www-math@w3.org.
-
- The numeric character values assigned to each entity
- (should) match the Unicode assignments in Unicode 4.0.
-
- Entity names in this file are derived from files carrying the
- following notice:
-
- (C) International Organization for Standardization 1986
- Permission to copy in any form is granted for use with
- conforming SGML systems and applications as defined in
- ISO 8879, provided this notice is included in all copies.
-
--->
-
-
-<!--
- Version: $Id: isoamsb.ent,v 1.2 2003/12/08 15:14:43 davidc Exp $
-
- Public identifier: ISO 8879:1986//ENTITIES Added Math Symbols: Binary Operators//EN//XML
- System identifier: http://www.w3.org/2003/entities/iso8879/isoamsb.ent
-
- The public identifier should always be used verbatim.
- The system identifier may be changed to suit local requirements.
-
- Typical invocation:
-
- <!ENTITY % isoamsb PUBLIC
- "ISO 8879:1986//ENTITIES Added Math Symbols: Binary Operators//EN//XML"
- "http://www.w3.org/2003/entities/iso8879/isoamsb.ent"
- >
- %isoamsb;
-
--->
-
-<!ENTITY amalg "&#x02A3F;" ><!--AMALGAMATION OR COPRODUCT -->
-<!ENTITY Barwed "&#x02306;" ><!--PERSPECTIVE -->
-<!ENTITY barwed "&#x02305;" ><!--PROJECTIVE -->
-<!ENTITY Cap "&#x022D2;" ><!--DOUBLE INTERSECTION -->
-<!ENTITY coprod "&#x02210;" ><!--N-ARY COPRODUCT -->
-<!ENTITY Cup "&#x022D3;" ><!--DOUBLE UNION -->
-<!ENTITY cuvee "&#x022CE;" ><!--CURLY LOGICAL OR -->
-<!ENTITY cuwed "&#x022CF;" ><!--CURLY LOGICAL AND -->
-<!ENTITY diam "&#x022C4;" ><!--DIAMOND OPERATOR -->
-<!ENTITY divonx "&#x022C7;" ><!--DIVISION TIMES -->
-<!ENTITY intcal "&#x022BA;" ><!--INTERCALATE -->
-<!ENTITY lthree "&#x022CB;" ><!--LEFT SEMIDIRECT PRODUCT -->
-<!ENTITY ltimes "&#x022C9;" ><!--LEFT NORMAL FACTOR SEMIDIRECT PRODUCT -->
-<!ENTITY minusb "&#x0229F;" ><!--SQUARED MINUS -->
-<!ENTITY oast "&#x0229B;" ><!--CIRCLED ASTERISK OPERATOR -->
-<!ENTITY ocir "&#x0229A;" ><!--CIRCLED RING OPERATOR -->
-<!ENTITY odash "&#x0229D;" ><!--CIRCLED DASH -->
-<!ENTITY odot "&#x02299;" ><!--CIRCLED DOT OPERATOR -->
-<!ENTITY ominus "&#x02296;" ><!--CIRCLED MINUS -->
-<!ENTITY oplus "&#x02295;" ><!--CIRCLED PLUS -->
-<!ENTITY osol "&#x02298;" ><!--CIRCLED DIVISION SLASH -->
-<!ENTITY otimes "&#x02297;" ><!--CIRCLED TIMES -->
-<!ENTITY plusb "&#x0229E;" ><!--SQUARED PLUS -->
-<!ENTITY plusdo "&#x02214;" ><!--DOT PLUS -->
-<!ENTITY prod "&#x0220F;" ><!--N-ARY PRODUCT -->
-<!ENTITY rthree "&#x022CC;" ><!--RIGHT SEMIDIRECT PRODUCT -->
-<!ENTITY rtimes "&#x022CA;" ><!--RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT -->
-<!ENTITY sdot "&#x022C5;" ><!--DOT OPERATOR -->
-<!ENTITY sdotb "&#x022A1;" ><!--SQUARED DOT OPERATOR -->
-<!ENTITY setmn "&#x02216;" ><!--SET MINUS -->
-<!ENTITY sqcap "&#x02293;" ><!--SQUARE CAP -->
-<!ENTITY sqcup "&#x02294;" ><!--SQUARE CUP -->
-<!ENTITY ssetmn "&#x02216;" ><!--SET MINUS -->
-<!ENTITY sstarf "&#x022C6;" ><!--STAR OPERATOR -->
-<!ENTITY sum "&#x02211;" ><!--N-ARY SUMMATION -->
-<!ENTITY timesb "&#x022A0;" ><!--SQUARED TIMES -->
-<!ENTITY top "&#x022A4;" ><!--DOWN TACK -->
-<!ENTITY uplus "&#x0228E;" ><!--MULTISET UNION -->
-<!ENTITY wreath "&#x02240;" ><!--WREATH PRODUCT -->
-<!ENTITY xcirc "&#x025EF;" ><!--LARGE CIRCLE -->
-<!ENTITY xdtri "&#x025BD;" ><!--WHITE DOWN-POINTING TRIANGLE -->
-<!ENTITY xutri "&#x025B3;" ><!--WHITE UP-POINTING TRIANGLE -->
diff --git a/Utilities/xml/docbook-4.5/ent/isoamsc.ent b/Utilities/xml/docbook-4.5/ent/isoamsc.ent
deleted file mode 100644
index 2fad41752..000000000
--- a/Utilities/xml/docbook-4.5/ent/isoamsc.ent
+++ /dev/null
@@ -1,51 +0,0 @@
-
-<!--
- File isoamsc.ent produced by the XSL script entities.xsl
- from input data in unicode.xml.
-
- Please report any errors to David Carlisle
- via the public W3C list www-math@w3.org.
-
- The numeric character values assigned to each entity
- (should) match the Unicode assignments in Unicode 4.0.
-
- Entity names in this file are derived from files carrying the
- following notice:
-
- (C) International Organization for Standardization 1986
- Permission to copy in any form is granted for use with
- conforming SGML systems and applications as defined in
- ISO 8879, provided this notice is included in all copies.
-
--->
-
-
-<!--
- Version: $Id: isoamsc.ent,v 1.2 2003/12/08 15:14:43 davidc Exp $
-
- Public identifier: ISO 8879:1986//ENTITIES Added Math Symbols: Delimiters//EN//XML
- System identifier: http://www.w3.org/2003/entities/iso8879/isoamsc.ent
-
- The public identifier should always be used verbatim.
- The system identifier may be changed to suit local requirements.
-
- Typical invocation:
-
- <!ENTITY % isoamsc PUBLIC
- "ISO 8879:1986//ENTITIES Added Math Symbols: Delimiters//EN//XML"
- "http://www.w3.org/2003/entities/iso8879/isoamsc.ent"
- >
- %isoamsc;
-
--->
-
-<!ENTITY dlcorn "&#x0231E;" ><!--BOTTOM LEFT CORNER -->
-<!ENTITY drcorn "&#x0231F;" ><!--BOTTOM RIGHT CORNER -->
-<!ENTITY lceil "&#x02308;" ><!--LEFT CEILING -->
-<!ENTITY lfloor "&#x0230A;" ><!--LEFT FLOOR -->
-<!ENTITY lpargt "&#x029A0;" ><!--SPHERICAL ANGLE OPENING LEFT -->
-<!ENTITY rceil "&#x02309;" ><!--RIGHT CEILING -->
-<!ENTITY rfloor "&#x0230B;" ><!--RIGHT FLOOR -->
-<!ENTITY rpargt "&#x02994;" ><!--RIGHT ARC GREATER-THAN BRACKET -->
-<!ENTITY ulcorn "&#x0231C;" ><!--TOP LEFT CORNER -->
-<!ENTITY urcorn "&#x0231D;" ><!--TOP RIGHT CORNER -->
diff --git a/Utilities/xml/docbook-4.5/ent/isoamsn.ent b/Utilities/xml/docbook-4.5/ent/isoamsn.ent
deleted file mode 100644
index ddca8d14c..000000000
--- a/Utilities/xml/docbook-4.5/ent/isoamsn.ent
+++ /dev/null
@@ -1,103 +0,0 @@
-
-<!--
- File isoamsn.ent produced by the XSL script entities.xsl
- from input data in unicode.xml.
-
- Please report any errors to David Carlisle
- via the public W3C list www-math@w3.org.
-
- The numeric character values assigned to each entity
- (should) match the Unicode assignments in Unicode 4.0.
-
- References to the VARIANT SELECTOR 1 character (&#x0FE00;)
- should match the uses listed in Unicode Technical Report 25.
-
- Entity names in this file are derived from files carrying the
- following notice:
-
- (C) International Organization for Standardization 1986
- Permission to copy in any form is granted for use with
- conforming SGML systems and applications as defined in
- ISO 8879, provided this notice is included in all copies.
-
--->
-
-
-<!--
- Version: $Id: isoamsn.ent,v 1.2 2003/12/08 15:14:43 davidc Exp $
-
- Public identifier: ISO 8879:1986//ENTITIES Added Math Symbols: Negated Relations//EN//XML
- System identifier: http://www.w3.org/2003/entities/iso8879/isoamsn.ent
-
- The public identifier should always be used verbatim.
- The system identifier may be changed to suit local requirements.
-
- Typical invocation:
-
- <!ENTITY % isoamsn PUBLIC
- "ISO 8879:1986//ENTITIES Added Math Symbols: Negated Relations//EN//XML"
- "http://www.w3.org/2003/entities/iso8879/isoamsn.ent"
- >
- %isoamsn;
-
--->
-
-<!ENTITY gnap "&#x02A8A;" ><!--GREATER-THAN AND NOT APPROXIMATE -->
-<!ENTITY gnE "&#x02269;" ><!--GREATER-THAN BUT NOT EQUAL TO -->
-<!ENTITY gne "&#x02A88;" ><!--GREATER-THAN AND SINGLE-LINE NOT EQUAL TO -->
-<!ENTITY gnsim "&#x022E7;" ><!--GREATER-THAN BUT NOT EQUIVALENT TO -->
-<!ENTITY gvnE "&#x02269;&#x0FE00;" ><!--GREATER-THAN BUT NOT EQUAL TO - with vertical stroke -->
-<!ENTITY lnap "&#x02A89;" ><!--LESS-THAN AND NOT APPROXIMATE -->
-<!ENTITY lnE "&#x02268;" ><!--LESS-THAN BUT NOT EQUAL TO -->
-<!ENTITY lne "&#x02A87;" ><!--LESS-THAN AND SINGLE-LINE NOT EQUAL TO -->
-<!ENTITY lnsim "&#x022E6;" ><!--LESS-THAN BUT NOT EQUIVALENT TO -->
-<!ENTITY lvnE "&#x02268;&#x0FE00;" ><!--LESS-THAN BUT NOT EQUAL TO - with vertical stroke -->
-<!ENTITY nap "&#x02249;" ><!--NOT ALMOST EQUAL TO -->
-<!ENTITY ncong "&#x02247;" ><!--NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO -->
-<!ENTITY nequiv "&#x02262;" ><!--NOT IDENTICAL TO -->
-<!ENTITY ngE "&#x02267;&#x00338;" ><!--GREATER-THAN OVER EQUAL TO with slash -->
-<!ENTITY nge "&#x02271;" ><!--NEITHER GREATER-THAN NOR EQUAL TO -->
-<!ENTITY nges "&#x02A7E;&#x00338;" ><!--GREATER-THAN OR SLANTED EQUAL TO with slash -->
-<!ENTITY ngt "&#x0226F;" ><!--NOT GREATER-THAN -->
-<!ENTITY nlE "&#x02266;&#x00338;" ><!--LESS-THAN OVER EQUAL TO with slash -->
-<!ENTITY nle "&#x02270;" ><!--NEITHER LESS-THAN NOR EQUAL TO -->
-<!ENTITY nles "&#x02A7D;&#x00338;" ><!--LESS-THAN OR SLANTED EQUAL TO with slash -->
-<!ENTITY nlt "&#x0226E;" ><!--NOT LESS-THAN -->
-<!ENTITY nltri "&#x022EA;" ><!--NOT NORMAL SUBGROUP OF -->
-<!ENTITY nltrie "&#x022EC;" ><!--NOT NORMAL SUBGROUP OF OR EQUAL TO -->
-<!ENTITY nmid "&#x02224;" ><!--DOES NOT DIVIDE -->
-<!ENTITY npar "&#x02226;" ><!--NOT PARALLEL TO -->
-<!ENTITY npr "&#x02280;" ><!--DOES NOT PRECEDE -->
-<!ENTITY npre "&#x02AAF;&#x00338;" ><!--PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash -->
-<!ENTITY nrtri "&#x022EB;" ><!--DOES NOT CONTAIN AS NORMAL SUBGROUP -->
-<!ENTITY nrtrie "&#x022ED;" ><!--DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL -->
-<!ENTITY nsc "&#x02281;" ><!--DOES NOT SUCCEED -->
-<!ENTITY nsce "&#x02AB0;&#x00338;" ><!--SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash -->
-<!ENTITY nsim "&#x02241;" ><!--NOT TILDE -->
-<!ENTITY nsime "&#x02244;" ><!--NOT ASYMPTOTICALLY EQUAL TO -->
-<!ENTITY nsmid "&#x02224;" ><!--DOES NOT DIVIDE -->
-<!ENTITY nspar "&#x02226;" ><!--NOT PARALLEL TO -->
-<!ENTITY nsub "&#x02284;" ><!--NOT A SUBSET OF -->
-<!ENTITY nsubE "&#x02AC5;&#x00338;" ><!--SUBSET OF ABOVE EQUALS SIGN with slash -->
-<!ENTITY nsube "&#x02288;" ><!--NEITHER A SUBSET OF NOR EQUAL TO -->
-<!ENTITY nsup "&#x02285;" ><!--NOT A SUPERSET OF -->
-<!ENTITY nsupE "&#x02AC6;&#x00338;" ><!--SUPERSET OF ABOVE EQUALS SIGN with slash -->
-<!ENTITY nsupe "&#x02289;" ><!--NEITHER A SUPERSET OF NOR EQUAL TO -->
-<!ENTITY nVDash "&#x022AF;" ><!--NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE -->
-<!ENTITY nVdash "&#x022AE;" ><!--DOES NOT FORCE -->
-<!ENTITY nvDash "&#x022AD;" ><!--NOT TRUE -->
-<!ENTITY nvdash "&#x022AC;" ><!--DOES NOT PROVE -->
-<!ENTITY prnap "&#x02AB9;" ><!--PRECEDES ABOVE NOT ALMOST EQUAL TO -->
-<!ENTITY prnE "&#x02AB5;" ><!--PRECEDES ABOVE NOT EQUAL TO -->
-<!ENTITY prnsim "&#x022E8;" ><!--PRECEDES BUT NOT EQUIVALENT TO -->
-<!ENTITY scnap "&#x02ABA;" ><!--SUCCEEDS ABOVE NOT ALMOST EQUAL TO -->
-<!ENTITY scnE "&#x02AB6;" ><!--SUCCEEDS ABOVE NOT EQUAL TO -->
-<!ENTITY scnsim "&#x022E9;" ><!--SUCCEEDS BUT NOT EQUIVALENT TO -->
-<!ENTITY subnE "&#x02ACB;" ><!--SUBSET OF ABOVE NOT EQUAL TO -->
-<!ENTITY subne "&#x0228A;" ><!--SUBSET OF WITH NOT EQUAL TO -->
-<!ENTITY supnE "&#x02ACC;" ><!--SUPERSET OF ABOVE NOT EQUAL TO -->
-<!ENTITY supne "&#x0228B;" ><!--SUPERSET OF WITH NOT EQUAL TO -->
-<!ENTITY vsubnE "&#x02ACB;&#x0FE00;" ><!--SUBSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members -->
-<!ENTITY vsubne "&#x0228A;&#x0FE00;" ><!--SUBSET OF WITH NOT EQUAL TO - variant with stroke through bottom members -->
-<!ENTITY vsupnE "&#x02ACC;&#x0FE00;" ><!--SUPERSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members -->
-<!ENTITY vsupne "&#x0228B;&#x0FE00;" ><!--SUPERSET OF WITH NOT EQUAL TO - variant with stroke through bottom members -->
diff --git a/Utilities/xml/docbook-4.5/ent/isoamso.ent b/Utilities/xml/docbook-4.5/ent/isoamso.ent
deleted file mode 100644
index 278e4b409..000000000
--- a/Utilities/xml/docbook-4.5/ent/isoamso.ent
+++ /dev/null
@@ -1,59 +0,0 @@
-
-<!--
- File isoamso.ent produced by the XSL script entities.xsl
- from input data in unicode.xml.
-
- Please report any errors to David Carlisle
- via the public W3C list www-math@w3.org.
-
- The numeric character values assigned to each entity
- (should) match the Unicode assignments in Unicode 4.0.
-
- Entity names in this file are derived from files carrying the
- following notice:
-
- (C) International Organization for Standardization 1986
- Permission to copy in any form is granted for use with
- conforming SGML systems and applications as defined in
- ISO 8879, provided this notice is included in all copies.
-
--->
-
-
-<!--
- Version: $Id: isoamso.ent,v 1.2 2003/12/08 15:14:43 davidc Exp $
-
- Public identifier: ISO 8879:1986//ENTITIES Added Math Symbols: Ordinary//EN//XML
- System identifier: http://www.w3.org/2003/entities/iso8879/isoamso.ent
-
- The public identifier should always be used verbatim.
- The system identifier may be changed to suit local requirements.
-
- Typical invocation:
-
- <!ENTITY % isoamso PUBLIC
- "ISO 8879:1986//ENTITIES Added Math Symbols: Ordinary//EN//XML"
- "http://www.w3.org/2003/entities/iso8879/isoamso.ent"
- >
- %isoamso;
-
--->
-
-<!ENTITY ang "&#x02220;" ><!--ANGLE -->
-<!ENTITY angmsd "&#x02221;" ><!--MEASURED ANGLE -->
-<!ENTITY beth "&#x02136;" ><!--BET SYMBOL -->
-<!ENTITY bprime "&#x02035;" ><!--REVERSED PRIME -->
-<!ENTITY comp "&#x02201;" ><!--COMPLEMENT -->
-<!ENTITY daleth "&#x02138;" ><!--DALET SYMBOL -->
-<!ENTITY ell "&#x02113;" ><!--SCRIPT SMALL L -->
-<!ENTITY empty "&#x02205;" ><!--EMPTY SET -->
-<!ENTITY gimel "&#x02137;" ><!--GIMEL SYMBOL -->
-<!ENTITY inodot "&#x00131;" ><!--LATIN SMALL LETTER DOTLESS I -->
-<!ENTITY jnodot "&#x0006A;" ><!--LATIN SMALL LETTER J -->
-<!ENTITY nexist "&#x02204;" ><!--THERE DOES NOT EXIST -->
-<!ENTITY oS "&#x024C8;" ><!--CIRCLED LATIN CAPITAL LETTER S -->
-<!ENTITY planck "&#x0210F;" ><!--PLANCK CONSTANT OVER TWO PI -->
-<!ENTITY real "&#x0211C;" ><!--BLACK-LETTER CAPITAL R -->
-<!ENTITY sbsol "&#x0FE68;" ><!--SMALL REVERSE SOLIDUS -->
-<!ENTITY vprime "&#x02032;" ><!--PRIME -->
-<!ENTITY weierp "&#x02118;" ><!--SCRIPT CAPITAL P -->
diff --git a/Utilities/xml/docbook-4.5/ent/isoamsr.ent b/Utilities/xml/docbook-4.5/ent/isoamsr.ent
deleted file mode 100644
index 18e64bffd..000000000
--- a/Utilities/xml/docbook-4.5/ent/isoamsr.ent
+++ /dev/null
@@ -1,125 +0,0 @@
-
-<!--
- File isoamsr.ent produced by the XSL script entities.xsl
- from input data in unicode.xml.
-
- Please report any errors to David Carlisle
- via the public W3C list www-math@w3.org.
-
- The numeric character values assigned to each entity
- (should) match the Unicode assignments in Unicode 4.0.
-
- Entity names in this file are derived from files carrying the
- following notice:
-
- (C) International Organization for Standardization 1986
- Permission to copy in any form is granted for use with
- conforming SGML systems and applications as defined in
- ISO 8879, provided this notice is included in all copies.
-
--->
-
-
-<!--
- Version: $Id: isoamsr.ent,v 1.2 2003/12/08 15:14:43 davidc Exp $
-
- Public identifier: ISO 8879:1986//ENTITIES Added Math Symbols: Relations//EN//XML
- System identifier: http://www.w3.org/2003/entities/iso8879/isoamsr.ent
-
- The public identifier should always be used verbatim.
- The system identifier may be changed to suit local requirements.
-
- Typical invocation:
-
- <!ENTITY % isoamsr PUBLIC
- "ISO 8879:1986//ENTITIES Added Math Symbols: Relations//EN//XML"
- "http://www.w3.org/2003/entities/iso8879/isoamsr.ent"
- >
- %isoamsr;
-
--->
-
-<!ENTITY ape "&#x0224A;" ><!--ALMOST EQUAL OR EQUAL TO -->
-<!ENTITY asymp "&#x02248;" ><!--ALMOST EQUAL TO -->
-<!ENTITY bcong "&#x0224C;" ><!--ALL EQUAL TO -->
-<!ENTITY bepsi "&#x003F6;" ><!--GREEK REVERSED LUNATE EPSILON SYMBOL -->
-<!ENTITY bowtie "&#x022C8;" ><!--BOWTIE -->
-<!ENTITY bsim "&#x0223D;" ><!--REVERSED TILDE -->
-<!ENTITY bsime "&#x022CD;" ><!--REVERSED TILDE EQUALS -->
-<!ENTITY bump "&#x0224E;" ><!--GEOMETRICALLY EQUIVALENT TO -->
-<!ENTITY bumpe "&#x0224F;" ><!--DIFFERENCE BETWEEN -->
-<!ENTITY cire "&#x02257;" ><!--RING EQUAL TO -->
-<!ENTITY colone "&#x02254;" ><!--COLON EQUALS -->
-<!ENTITY cuepr "&#x022DE;" ><!--EQUAL TO OR PRECEDES -->
-<!ENTITY cuesc "&#x022DF;" ><!--EQUAL TO OR SUCCEEDS -->
-<!ENTITY cupre "&#x0227C;" ><!--PRECEDES OR EQUAL TO -->
-<!ENTITY dashv "&#x022A3;" ><!--LEFT TACK -->
-<!ENTITY ecir "&#x02256;" ><!--RING IN EQUAL TO -->
-<!ENTITY ecolon "&#x02255;" ><!--EQUALS COLON -->
-<!ENTITY eDot "&#x02251;" ><!--GEOMETRICALLY EQUAL TO -->
-<!ENTITY efDot "&#x02252;" ><!--APPROXIMATELY EQUAL TO OR THE IMAGE OF -->
-<!ENTITY egs "&#x02A96;" ><!--SLANTED EQUAL TO OR GREATER-THAN -->
-<!ENTITY els "&#x02A95;" ><!--SLANTED EQUAL TO OR LESS-THAN -->
-<!ENTITY erDot "&#x02253;" ><!--IMAGE OF OR APPROXIMATELY EQUAL TO -->
-<!ENTITY esdot "&#x02250;" ><!--APPROACHES THE LIMIT -->
-<!ENTITY fork "&#x022D4;" ><!--PITCHFORK -->
-<!ENTITY frown "&#x02322;" ><!--FROWN -->
-<!ENTITY gap "&#x02A86;" ><!--GREATER-THAN OR APPROXIMATE -->
-<!ENTITY gE "&#x02267;" ><!--GREATER-THAN OVER EQUAL TO -->
-<!ENTITY gEl "&#x02A8C;" ><!--GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN -->
-<!ENTITY gel "&#x022DB;" ><!--GREATER-THAN EQUAL TO OR LESS-THAN -->
-<!ENTITY ges "&#x02A7E;" ><!--GREATER-THAN OR SLANTED EQUAL TO -->
-<!ENTITY Gg "&#x022D9;" ><!--VERY MUCH GREATER-THAN -->
-<!ENTITY gl "&#x02277;" ><!--GREATER-THAN OR LESS-THAN -->
-<!ENTITY gsdot "&#x022D7;" ><!--GREATER-THAN WITH DOT -->
-<!ENTITY gsim "&#x02273;" ><!--GREATER-THAN OR EQUIVALENT TO -->
-<!ENTITY Gt "&#x0226B;" ><!--MUCH GREATER-THAN -->
-<!ENTITY lap "&#x02A85;" ><!--LESS-THAN OR APPROXIMATE -->
-<!ENTITY ldot "&#x022D6;" ><!--LESS-THAN WITH DOT -->
-<!ENTITY lE "&#x02266;" ><!--LESS-THAN OVER EQUAL TO -->
-<!ENTITY lEg "&#x02A8B;" ><!--LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN -->
-<!ENTITY leg "&#x022DA;" ><!--LESS-THAN EQUAL TO OR GREATER-THAN -->
-<!ENTITY les "&#x02A7D;" ><!--LESS-THAN OR SLANTED EQUAL TO -->
-<!ENTITY lg "&#x02276;" ><!--LESS-THAN OR GREATER-THAN -->
-<!ENTITY Ll "&#x022D8;" ><!--VERY MUCH LESS-THAN -->
-<!ENTITY lsim "&#x02272;" ><!--LESS-THAN OR EQUIVALENT TO -->
-<!ENTITY Lt "&#x0226A;" ><!--MUCH LESS-THAN -->
-<!ENTITY ltrie "&#x022B4;" ><!--NORMAL SUBGROUP OF OR EQUAL TO -->
-<!ENTITY mid "&#x02223;" ><!--DIVIDES -->
-<!ENTITY models "&#x022A7;" ><!--MODELS -->
-<!ENTITY pr "&#x0227A;" ><!--PRECEDES -->
-<!ENTITY prap "&#x02AB7;" ><!--PRECEDES ABOVE ALMOST EQUAL TO -->
-<!ENTITY pre "&#x02AAF;" ><!--PRECEDES ABOVE SINGLE-LINE EQUALS SIGN -->
-<!ENTITY prsim "&#x0227E;" ><!--PRECEDES OR EQUIVALENT TO -->
-<!ENTITY rtrie "&#x022B5;" ><!--CONTAINS AS NORMAL SUBGROUP OR EQUAL TO -->
-<!ENTITY samalg "&#x02210;" ><!--N-ARY COPRODUCT -->
-<!ENTITY sc "&#x0227B;" ><!--SUCCEEDS -->
-<!ENTITY scap "&#x02AB8;" ><!--SUCCEEDS ABOVE ALMOST EQUAL TO -->
-<!ENTITY sccue "&#x0227D;" ><!--SUCCEEDS OR EQUAL TO -->
-<!ENTITY sce "&#x02AB0;" ><!--SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN -->
-<!ENTITY scsim "&#x0227F;" ><!--SUCCEEDS OR EQUIVALENT TO -->
-<!ENTITY sfrown "&#x02322;" ><!--FROWN -->
-<!ENTITY smid "&#x02223;" ><!--DIVIDES -->
-<!ENTITY smile "&#x02323;" ><!--SMILE -->
-<!ENTITY spar "&#x02225;" ><!--PARALLEL TO -->
-<!ENTITY sqsub "&#x0228F;" ><!--SQUARE IMAGE OF -->
-<!ENTITY sqsube "&#x02291;" ><!--SQUARE IMAGE OF OR EQUAL TO -->
-<!ENTITY sqsup "&#x02290;" ><!--SQUARE ORIGINAL OF -->
-<!ENTITY sqsupe "&#x02292;" ><!--SQUARE ORIGINAL OF OR EQUAL TO -->
-<!ENTITY ssmile "&#x02323;" ><!--SMILE -->
-<!ENTITY Sub "&#x022D0;" ><!--DOUBLE SUBSET -->
-<!ENTITY subE "&#x02AC5;" ><!--SUBSET OF ABOVE EQUALS SIGN -->
-<!ENTITY Sup "&#x022D1;" ><!--DOUBLE SUPERSET -->
-<!ENTITY supE "&#x02AC6;" ><!--SUPERSET OF ABOVE EQUALS SIGN -->
-<!ENTITY thkap "&#x02248;" ><!--ALMOST EQUAL TO -->
-<!ENTITY thksim "&#x0223C;" ><!--TILDE OPERATOR -->
-<!ENTITY trie "&#x0225C;" ><!--DELTA EQUAL TO -->
-<!ENTITY twixt "&#x0226C;" ><!--BETWEEN -->
-<!ENTITY Vdash "&#x022A9;" ><!--FORCES -->
-<!ENTITY vDash "&#x022A8;" ><!--TRUE -->
-<!ENTITY vdash "&#x022A2;" ><!--RIGHT TACK -->
-<!ENTITY veebar "&#x022BB;" ><!--XOR -->
-<!ENTITY vltri "&#x022B2;" ><!--NORMAL SUBGROUP OF -->
-<!ENTITY vprop "&#x0221D;" ><!--PROPORTIONAL TO -->
-<!ENTITY vrtri "&#x022B3;" ><!--CONTAINS AS NORMAL SUBGROUP -->
-<!ENTITY Vvdash "&#x022AA;" ><!--TRIPLE VERTICAL BAR RIGHT TURNSTILE -->
diff --git a/Utilities/xml/docbook-4.5/ent/isobox.ent b/Utilities/xml/docbook-4.5/ent/isobox.ent
deleted file mode 100644
index 9ae27d4fa..000000000
--- a/Utilities/xml/docbook-4.5/ent/isobox.ent
+++ /dev/null
@@ -1,81 +0,0 @@
-
-<!--
- File isobox.ent produced by the XSL script entities.xsl
- from input data in unicode.xml.
-
- Please report any errors to David Carlisle
- via the public W3C list www-math@w3.org.
-
- The numeric character values assigned to each entity
- (should) match the Unicode assignments in Unicode 4.0.
-
- Entity names in this file are derived from files carrying the
- following notice:
-
- (C) International Organization for Standardization 1986
- Permission to copy in any form is granted for use with
- conforming SGML systems and applications as defined in
- ISO 8879, provided this notice is included in all copies.
-
--->
-
-
-<!--
- Version: $Id: isobox.ent,v 1.2 2003/12/08 15:14:43 davidc Exp $
-
- Public identifier: ISO 8879:1986//ENTITIES Box and Line Drawing//EN//XML
- System identifier: http://www.w3.org/2003/entities/iso8879/isobox.ent
-
- The public identifier should always be used verbatim.
- The system identifier may be changed to suit local requirements.
-
- Typical invocation:
-
- <!ENTITY % isobox PUBLIC
- "ISO 8879:1986//ENTITIES Box and Line Drawing//EN//XML"
- "http://www.w3.org/2003/entities/iso8879/isobox.ent"
- >
- %isobox;
-
--->
-
-<!ENTITY boxDL "&#x02557;" ><!--BOX DRAWINGS DOUBLE DOWN AND LEFT -->
-<!ENTITY boxDl "&#x02556;" ><!--BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE -->
-<!ENTITY boxdL "&#x02555;" ><!--BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE -->
-<!ENTITY boxdl "&#x02510;" ><!--BOX DRAWINGS LIGHT DOWN AND LEFT -->
-<!ENTITY boxDR "&#x02554;" ><!--BOX DRAWINGS DOUBLE DOWN AND RIGHT -->
-<!ENTITY boxDr "&#x02553;" ><!--BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE -->
-<!ENTITY boxdR "&#x02552;" ><!--BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE -->
-<!ENTITY boxdr "&#x0250C;" ><!--BOX DRAWINGS LIGHT DOWN AND RIGHT -->
-<!ENTITY boxH "&#x02550;" ><!--BOX DRAWINGS DOUBLE HORIZONTAL -->
-<!ENTITY boxh "&#x02500;" ><!--BOX DRAWINGS LIGHT HORIZONTAL -->
-<!ENTITY boxHD "&#x02566;" ><!--BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL -->
-<!ENTITY boxHd "&#x02564;" ><!--BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE -->
-<!ENTITY boxhD "&#x02565;" ><!--BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE -->
-<!ENTITY boxhd "&#x0252C;" ><!--BOX DRAWINGS LIGHT DOWN AND HORIZONTAL -->
-<!ENTITY boxHU "&#x02569;" ><!--BOX DRAWINGS DOUBLE UP AND HORIZONTAL -->
-<!ENTITY boxHu "&#x02567;" ><!--BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE -->
-<!ENTITY boxhU "&#x02568;" ><!--BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE -->
-<!ENTITY boxhu "&#x02534;" ><!--BOX DRAWINGS LIGHT UP AND HORIZONTAL -->
-<!ENTITY boxUL "&#x0255D;" ><!--BOX DRAWINGS DOUBLE UP AND LEFT -->
-<!ENTITY boxUl "&#x0255C;" ><!--BOX DRAWINGS UP DOUBLE AND LEFT SINGLE -->
-<!ENTITY boxuL "&#x0255B;" ><!--BOX DRAWINGS UP SINGLE AND LEFT DOUBLE -->
-<!ENTITY boxul "&#x02518;" ><!--BOX DRAWINGS LIGHT UP AND LEFT -->
-<!ENTITY boxUR "&#x0255A;" ><!--BOX DRAWINGS DOUBLE UP AND RIGHT -->
-<!ENTITY boxUr "&#x02559;" ><!--BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE -->
-<!ENTITY boxuR "&#x02558;" ><!--BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE -->
-<!ENTITY boxur "&#x02514;" ><!--BOX DRAWINGS LIGHT UP AND RIGHT -->
-<!ENTITY boxV "&#x02551;" ><!--BOX DRAWINGS DOUBLE VERTICAL -->
-<!ENTITY boxv "&#x02502;" ><!--BOX DRAWINGS LIGHT VERTICAL -->
-<!ENTITY boxVH "&#x0256C;" ><!--BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL -->
-<!ENTITY boxVh "&#x0256B;" ><!--BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE -->
-<!ENTITY boxvH "&#x0256A;" ><!--BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE -->
-<!ENTITY boxvh "&#x0253C;" ><!--BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL -->
-<!ENTITY boxVL "&#x02563;" ><!--BOX DRAWINGS DOUBLE VERTICAL AND LEFT -->
-<!ENTITY boxVl "&#x02562;" ><!--BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE -->
-<!ENTITY boxvL "&#x02561;" ><!--BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE -->
-<!ENTITY boxvl "&#x02524;" ><!--BOX DRAWINGS LIGHT VERTICAL AND LEFT -->
-<!ENTITY boxVR "&#x02560;" ><!--BOX DRAWINGS DOUBLE VERTICAL AND RIGHT -->
-<!ENTITY boxVr "&#x0255F;" ><!--BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE -->
-<!ENTITY boxvR "&#x0255E;" ><!--BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE -->
-<!ENTITY boxvr "&#x0251C;" ><!--BOX DRAWINGS LIGHT VERTICAL AND RIGHT -->
diff --git a/Utilities/xml/docbook-4.5/ent/isocyr1.ent b/Utilities/xml/docbook-4.5/ent/isocyr1.ent
deleted file mode 100644
index 364b6d841..000000000
--- a/Utilities/xml/docbook-4.5/ent/isocyr1.ent
+++ /dev/null
@@ -1,108 +0,0 @@
-
-<!--
- File isocyr1.ent produced by the XSL script entities.xsl
- from input data in unicode.xml.
-
- Please report any errors to David Carlisle
- via the public W3C list www-math@w3.org.
-
- The numeric character values assigned to each entity
- (should) match the Unicode assignments in Unicode 4.0.
-
- Entity names in this file are derived from files carrying the
- following notice:
-
- (C) International Organization for Standardization 1986
- Permission to copy in any form is granted for use with
- conforming SGML systems and applications as defined in
- ISO 8879, provided this notice is included in all copies.
-
--->
-
-
-<!--
- Version: $Id: isocyr1.ent,v 1.2 2003/12/08 15:14:43 davidc Exp $
-
- Public identifier: ISO 8879:1986//ENTITIES Russian Cyrillic//EN//XML
- System identifier: http://www.w3.org/2003/entities/iso8879/isocyr1.ent
-
- The public identifier should always be used verbatim.
- The system identifier may be changed to suit local requirements.
-
- Typical invocation:
-
- <!ENTITY % isocyr1 PUBLIC
- "ISO 8879:1986//ENTITIES Russian Cyrillic//EN//XML"
- "http://www.w3.org/2003/entities/iso8879/isocyr1.ent"
- >
- %isocyr1;
-
--->
-
-<!ENTITY Acy "&#x00410;" ><!--CYRILLIC CAPITAL LETTER A -->
-<!ENTITY acy "&#x00430;" ><!--CYRILLIC SMALL LETTER A -->
-<!ENTITY Bcy "&#x00411;" ><!--CYRILLIC CAPITAL LETTER BE -->
-<!ENTITY bcy "&#x00431;" ><!--CYRILLIC SMALL LETTER BE -->
-<!ENTITY CHcy "&#x00427;" ><!--CYRILLIC CAPITAL LETTER CHE -->
-<!ENTITY chcy "&#x00447;" ><!--CYRILLIC SMALL LETTER CHE -->
-<!ENTITY Dcy "&#x00414;" ><!--CYRILLIC CAPITAL LETTER DE -->
-<!ENTITY dcy "&#x00434;" ><!--CYRILLIC SMALL LETTER DE -->
-<!ENTITY Ecy "&#x0042D;" ><!--CYRILLIC CAPITAL LETTER E -->
-<!ENTITY ecy "&#x0044D;" ><!--CYRILLIC SMALL LETTER E -->
-<!ENTITY Fcy "&#x00424;" ><!--CYRILLIC CAPITAL LETTER EF -->
-<!ENTITY fcy "&#x00444;" ><!--CYRILLIC SMALL LETTER EF -->
-<!ENTITY Gcy "&#x00413;" ><!--CYRILLIC CAPITAL LETTER GHE -->
-<!ENTITY gcy "&#x00433;" ><!--CYRILLIC SMALL LETTER GHE -->
-<!ENTITY HARDcy "&#x0042A;" ><!--CYRILLIC CAPITAL LETTER HARD SIGN -->
-<!ENTITY hardcy "&#x0044A;" ><!--CYRILLIC SMALL LETTER HARD SIGN -->
-<!ENTITY Icy "&#x00418;" ><!--CYRILLIC CAPITAL LETTER I -->
-<!ENTITY icy "&#x00438;" ><!--CYRILLIC SMALL LETTER I -->
-<!ENTITY IEcy "&#x00415;" ><!--CYRILLIC CAPITAL LETTER IE -->
-<!ENTITY iecy "&#x00435;" ><!--CYRILLIC SMALL LETTER IE -->
-<!ENTITY IOcy "&#x00401;" ><!--CYRILLIC CAPITAL LETTER IO -->
-<!ENTITY iocy "&#x00451;" ><!--CYRILLIC SMALL LETTER IO -->
-<!ENTITY Jcy "&#x00419;" ><!--CYRILLIC CAPITAL LETTER SHORT I -->
-<!ENTITY jcy "&#x00439;" ><!--CYRILLIC SMALL LETTER SHORT I -->
-<!ENTITY Kcy "&#x0041A;" ><!--CYRILLIC CAPITAL LETTER KA -->
-<!ENTITY kcy "&#x0043A;" ><!--CYRILLIC SMALL LETTER KA -->
-<!ENTITY KHcy "&#x00425;" ><!--CYRILLIC CAPITAL LETTER HA -->
-<!ENTITY khcy "&#x00445;" ><!--CYRILLIC SMALL LETTER HA -->
-<!ENTITY Lcy "&#x0041B;" ><!--CYRILLIC CAPITAL LETTER EL -->
-<!ENTITY lcy "&#x0043B;" ><!--CYRILLIC SMALL LETTER EL -->
-<!ENTITY Mcy "&#x0041C;" ><!--CYRILLIC CAPITAL LETTER EM -->
-<!ENTITY mcy "&#x0043C;" ><!--CYRILLIC SMALL LETTER EM -->
-<!ENTITY Ncy "&#x0041D;" ><!--CYRILLIC CAPITAL LETTER EN -->
-<!ENTITY ncy "&#x0043D;" ><!--CYRILLIC SMALL LETTER EN -->
-<!ENTITY numero "&#x02116;" ><!--NUMERO SIGN -->
-<!ENTITY Ocy "&#x0041E;" ><!--CYRILLIC CAPITAL LETTER O -->
-<!ENTITY ocy "&#x0043E;" ><!--CYRILLIC SMALL LETTER O -->
-<!ENTITY Pcy "&#x0041F;" ><!--CYRILLIC CAPITAL LETTER PE -->
-<!ENTITY pcy "&#x0043F;" ><!--CYRILLIC SMALL LETTER PE -->
-<!ENTITY Rcy "&#x00420;" ><!--CYRILLIC CAPITAL LETTER ER -->
-<!ENTITY rcy "&#x00440;" ><!--CYRILLIC SMALL LETTER ER -->
-<!ENTITY Scy "&#x00421;" ><!--CYRILLIC CAPITAL LETTER ES -->
-<!ENTITY scy "&#x00441;" ><!--CYRILLIC SMALL LETTER ES -->
-<!ENTITY SHCHcy "&#x00429;" ><!--CYRILLIC CAPITAL LETTER SHCHA -->
-<!ENTITY shchcy "&#x00449;" ><!--CYRILLIC SMALL LETTER SHCHA -->
-<!ENTITY SHcy "&#x00428;" ><!--CYRILLIC CAPITAL LETTER SHA -->
-<!ENTITY shcy "&#x00448;" ><!--CYRILLIC SMALL LETTER SHA -->
-<!ENTITY SOFTcy "&#x0042C;" ><!--CYRILLIC CAPITAL LETTER SOFT SIGN -->
-<!ENTITY softcy "&#x0044C;" ><!--CYRILLIC SMALL LETTER SOFT SIGN -->
-<!ENTITY Tcy "&#x00422;" ><!--CYRILLIC CAPITAL LETTER TE -->
-<!ENTITY tcy "&#x00442;" ><!--CYRILLIC SMALL LETTER TE -->
-<!ENTITY TScy "&#x00426;" ><!--CYRILLIC CAPITAL LETTER TSE -->
-<!ENTITY tscy "&#x00446;" ><!--CYRILLIC SMALL LETTER TSE -->
-<!ENTITY Ucy "&#x00423;" ><!--CYRILLIC CAPITAL LETTER U -->
-<!ENTITY ucy "&#x00443;" ><!--CYRILLIC SMALL LETTER U -->
-<!ENTITY Vcy "&#x00412;" ><!--CYRILLIC CAPITAL LETTER VE -->
-<!ENTITY vcy "&#x00432;" ><!--CYRILLIC SMALL LETTER VE -->
-<!ENTITY YAcy "&#x0042F;" ><!--CYRILLIC CAPITAL LETTER YA -->
-<!ENTITY yacy "&#x0044F;" ><!--CYRILLIC SMALL LETTER YA -->
-<!ENTITY Ycy "&#x0042B;" ><!--CYRILLIC CAPITAL LETTER YERU -->
-<!ENTITY ycy "&#x0044B;" ><!--CYRILLIC SMALL LETTER YERU -->
-<!ENTITY YUcy "&#x0042E;" ><!--CYRILLIC CAPITAL LETTER YU -->
-<!ENTITY yucy "&#x0044E;" ><!--CYRILLIC SMALL LETTER YU -->
-<!ENTITY Zcy "&#x00417;" ><!--CYRILLIC CAPITAL LETTER ZE -->
-<!ENTITY zcy "&#x00437;" ><!--CYRILLIC SMALL LETTER ZE -->
-<!ENTITY ZHcy "&#x00416;" ><!--CYRILLIC CAPITAL LETTER ZHE -->
-<!ENTITY zhcy "&#x00436;" ><!--CYRILLIC SMALL LETTER ZHE -->
diff --git a/Utilities/xml/docbook-4.5/ent/isocyr2.ent b/Utilities/xml/docbook-4.5/ent/isocyr2.ent
deleted file mode 100644
index 6432d74c4..000000000
--- a/Utilities/xml/docbook-4.5/ent/isocyr2.ent
+++ /dev/null
@@ -1,67 +0,0 @@
-
-<!--
- File isocyr2.ent produced by the XSL script entities.xsl
- from input data in unicode.xml.
-
- Please report any errors to David Carlisle
- via the public W3C list www-math@w3.org.
-
- The numeric character values assigned to each entity
- (should) match the Unicode assignments in Unicode 4.0.
-
- Entity names in this file are derived from files carrying the
- following notice:
-
- (C) International Organization for Standardization 1986
- Permission to copy in any form is granted for use with
- conforming SGML systems and applications as defined in
- ISO 8879, provided this notice is included in all copies.
-
--->
-
-
-<!--
- Version: $Id: isocyr2.ent,v 1.2 2003/12/08 15:14:43 davidc Exp $
-
- Public identifier: ISO 8879:1986//ENTITIES Non-Russian Cyrillic//EN//XML
- System identifier: http://www.w3.org/2003/entities/iso8879/isocyr2.ent
-
- The public identifier should always be used verbatim.
- The system identifier may be changed to suit local requirements.
-
- Typical invocation:
-
- <!ENTITY % isocyr2 PUBLIC
- "ISO 8879:1986//ENTITIES Non-Russian Cyrillic//EN//XML"
- "http://www.w3.org/2003/entities/iso8879/isocyr2.ent"
- >
- %isocyr2;
-
--->
-
-<!ENTITY DJcy "&#x00402;" ><!--CYRILLIC CAPITAL LETTER DJE -->
-<!ENTITY djcy "&#x00452;" ><!--CYRILLIC SMALL LETTER DJE -->
-<!ENTITY DScy "&#x00405;" ><!--CYRILLIC CAPITAL LETTER DZE -->
-<!ENTITY dscy "&#x00455;" ><!--CYRILLIC SMALL LETTER DZE -->
-<!ENTITY DZcy "&#x0040F;" ><!--CYRILLIC CAPITAL LETTER DZHE -->
-<!ENTITY dzcy "&#x0045F;" ><!--CYRILLIC SMALL LETTER DZHE -->
-<!ENTITY GJcy "&#x00403;" ><!--CYRILLIC CAPITAL LETTER GJE -->
-<!ENTITY gjcy "&#x00453;" ><!--CYRILLIC SMALL LETTER GJE -->
-<!ENTITY Iukcy "&#x00406;" ><!--CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I -->
-<!ENTITY iukcy "&#x00456;" ><!--CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I -->
-<!ENTITY Jsercy "&#x00408;" ><!--CYRILLIC CAPITAL LETTER JE -->
-<!ENTITY jsercy "&#x00458;" ><!--CYRILLIC SMALL LETTER JE -->
-<!ENTITY Jukcy "&#x00404;" ><!--CYRILLIC CAPITAL LETTER UKRAINIAN IE -->
-<!ENTITY jukcy "&#x00454;" ><!--CYRILLIC SMALL LETTER UKRAINIAN IE -->
-<!ENTITY KJcy "&#x0040C;" ><!--CYRILLIC CAPITAL LETTER KJE -->
-<!ENTITY kjcy "&#x0045C;" ><!--CYRILLIC SMALL LETTER KJE -->
-<!ENTITY LJcy "&#x00409;" ><!--CYRILLIC CAPITAL LETTER LJE -->
-<!ENTITY ljcy "&#x00459;" ><!--CYRILLIC SMALL LETTER LJE -->
-<!ENTITY NJcy "&#x0040A;" ><!--CYRILLIC CAPITAL LETTER NJE -->
-<!ENTITY njcy "&#x0045A;" ><!--CYRILLIC SMALL LETTER NJE -->
-<!ENTITY TSHcy "&#x0040B;" ><!--CYRILLIC CAPITAL LETTER TSHE -->
-<!ENTITY tshcy "&#x0045B;" ><!--CYRILLIC SMALL LETTER TSHE -->
-<!ENTITY Ubrcy "&#x0040E;" ><!--CYRILLIC CAPITAL LETTER SHORT U -->
-<!ENTITY ubrcy "&#x0045E;" ><!--CYRILLIC SMALL LETTER SHORT U -->
-<!ENTITY YIcy "&#x00407;" ><!--CYRILLIC CAPITAL LETTER YI -->
-<!ENTITY yicy "&#x00457;" ><!--CYRILLIC SMALL LETTER YI -->
diff --git a/Utilities/xml/docbook-4.5/ent/isodia.ent b/Utilities/xml/docbook-4.5/ent/isodia.ent
deleted file mode 100644
index b49c30947..000000000
--- a/Utilities/xml/docbook-4.5/ent/isodia.ent
+++ /dev/null
@@ -1,55 +0,0 @@
-
-<!--
- File isodia.ent produced by the XSL script entities.xsl
- from input data in unicode.xml.
-
- Please report any errors to David Carlisle
- via the public W3C list www-math@w3.org.
-
- The numeric character values assigned to each entity
- (should) match the Unicode assignments in Unicode 4.0.
-
- Entity names in this file are derived from files carrying the
- following notice:
-
- (C) International Organization for Standardization 1986
- Permission to copy in any form is granted for use with
- conforming SGML systems and applications as defined in
- ISO 8879, provided this notice is included in all copies.
-
--->
-
-
-<!--
- Version: $Id: isodia.ent,v 1.2 2003/12/08 15:14:43 davidc Exp $
-
- Public identifier: ISO 8879:1986//ENTITIES Diacritical Marks//EN//XML
- System identifier: http://www.w3.org/2003/entities/iso8879/isodia.ent
-
- The public identifier should always be used verbatim.
- The system identifier may be changed to suit local requirements.
-
- Typical invocation:
-
- <!ENTITY % isodia PUBLIC
- "ISO 8879:1986//ENTITIES Diacritical Marks//EN//XML"
- "http://www.w3.org/2003/entities/iso8879/isodia.ent"
- >
- %isodia;
-
--->
-
-<!ENTITY acute "&#x000B4;" ><!--ACUTE ACCENT -->
-<!ENTITY breve "&#x002D8;" ><!--BREVE -->
-<!ENTITY caron "&#x002C7;" ><!--CARON -->
-<!ENTITY cedil "&#x000B8;" ><!--CEDILLA -->
-<!ENTITY circ "&#x002C6;" ><!--MODIFIER LETTER CIRCUMFLEX ACCENT -->
-<!ENTITY dblac "&#x002DD;" ><!--DOUBLE ACUTE ACCENT -->
-<!ENTITY die "&#x000A8;" ><!--DIAERESIS -->
-<!ENTITY dot "&#x002D9;" ><!--DOT ABOVE -->
-<!ENTITY grave "&#x00060;" ><!--GRAVE ACCENT -->
-<!ENTITY macr "&#x000AF;" ><!--MACRON -->
-<!ENTITY ogon "&#x002DB;" ><!--OGONEK -->
-<!ENTITY ring "&#x002DA;" ><!--RING ABOVE -->
-<!ENTITY tilde "&#x002DC;" ><!--SMALL TILDE -->
-<!ENTITY uml "&#x000A8;" ><!--DIAERESIS -->
diff --git a/Utilities/xml/docbook-4.5/ent/isogrk1.ent b/Utilities/xml/docbook-4.5/ent/isogrk1.ent
deleted file mode 100644
index 7826f8109..000000000
--- a/Utilities/xml/docbook-4.5/ent/isogrk1.ent
+++ /dev/null
@@ -1,90 +0,0 @@
-
-<!--
- File isogrk1.ent produced by the XSL script entities.xsl
- from input data in unicode.xml.
-
- Please report any errors to David Carlisle
- via the public W3C list www-math@w3.org.
-
- The numeric character values assigned to each entity
- (should) match the Unicode assignments in Unicode 4.0.
-
- Entity names in this file are derived from files carrying the
- following notice:
-
- (C) International Organization for Standardization 1986
- Permission to copy in any form is granted for use with
- conforming SGML systems and applications as defined in
- ISO 8879, provided this notice is included in all copies.
-
--->
-
-
-<!--
- Version: $Id: isogrk1.ent,v 1.2 2003/12/08 15:14:43 davidc Exp $
-
- Public identifier: ISO 8879:1986//ENTITIES Greek Letters//EN//XML
- System identifier: http://www.w3.org/2003/entities/iso8879/isogrk1.ent
-
- The public identifier should always be used verbatim.
- The system identifier may be changed to suit local requirements.
-
- Typical invocation:
-
- <!ENTITY % isogrk1 PUBLIC
- "ISO 8879:1986//ENTITIES Greek Letters//EN//XML"
- "http://www.w3.org/2003/entities/iso8879/isogrk1.ent"
- >
- %isogrk1;
-
--->
-
-<!ENTITY Agr "&#x00391;" ><!--GREEK CAPITAL LETTER ALPHA -->
-<!ENTITY agr "&#x003B1;" ><!--GREEK SMALL LETTER ALPHA -->
-<!ENTITY Bgr "&#x00392;" ><!--GREEK CAPITAL LETTER BETA -->
-<!ENTITY bgr "&#x003B2;" ><!--GREEK SMALL LETTER BETA -->
-<!ENTITY Dgr "&#x00394;" ><!--GREEK CAPITAL LETTER DELTA -->
-<!ENTITY dgr "&#x003B4;" ><!--GREEK SMALL LETTER DELTA -->
-<!ENTITY EEgr "&#x00397;" ><!--GREEK CAPITAL LETTER ETA -->
-<!ENTITY eegr "&#x003B7;" ><!--GREEK SMALL LETTER ETA -->
-<!ENTITY Egr "&#x00395;" ><!--GREEK CAPITAL LETTER EPSILON -->
-<!ENTITY egr "&#x003B5;" ><!--GREEK SMALL LETTER EPSILON -->
-<!ENTITY Ggr "&#x00393;" ><!--GREEK CAPITAL LETTER GAMMA -->
-<!ENTITY ggr "&#x003B3;" ><!--GREEK SMALL LETTER GAMMA -->
-<!ENTITY Igr "&#x00399;" ><!--GREEK CAPITAL LETTER IOTA -->
-<!ENTITY igr "&#x003B9;" ><!--GREEK SMALL LETTER IOTA -->
-<!ENTITY Kgr "&#x0039A;" ><!--GREEK CAPITAL LETTER KAPPA -->
-<!ENTITY kgr "&#x003BA;" ><!--GREEK SMALL LETTER KAPPA -->
-<!ENTITY KHgr "&#x003A7;" ><!--GREEK CAPITAL LETTER CHI -->
-<!ENTITY khgr "&#x003C7;" ><!--GREEK SMALL LETTER CHI -->
-<!ENTITY Lgr "&#x0039B;" ><!--GREEK CAPITAL LETTER LAMDA -->
-<!ENTITY lgr "&#x003BB;" ><!--GREEK SMALL LETTER LAMDA -->
-<!ENTITY Mgr "&#x0039C;" ><!--GREEK CAPITAL LETTER MU -->
-<!ENTITY mgr "&#x003BC;" ><!--GREEK SMALL LETTER MU -->
-<!ENTITY Ngr "&#x0039D;" ><!--GREEK CAPITAL LETTER NU -->
-<!ENTITY ngr "&#x003BD;" ><!--GREEK SMALL LETTER NU -->
-<!ENTITY Ogr "&#x0039F;" ><!--GREEK CAPITAL LETTER OMICRON -->
-<!ENTITY ogr "&#x003BF;" ><!--GREEK SMALL LETTER OMICRON -->
-<!ENTITY OHgr "&#x003A9;" ><!--GREEK CAPITAL LETTER OMEGA -->
-<!ENTITY ohgr "&#x003C9;" ><!--GREEK SMALL LETTER OMEGA -->
-<!ENTITY Pgr "&#x003A0;" ><!--GREEK CAPITAL LETTER PI -->
-<!ENTITY pgr "&#x003C0;" ><!--GREEK SMALL LETTER PI -->
-<!ENTITY PHgr "&#x003A6;" ><!--GREEK CAPITAL LETTER PHI -->
-<!ENTITY phgr "&#x003C6;" ><!--GREEK SMALL LETTER PHI -->
-<!ENTITY PSgr "&#x003A8;" ><!--GREEK CAPITAL LETTER PSI -->
-<!ENTITY psgr "&#x003C8;" ><!--GREEK SMALL LETTER PSI -->
-<!ENTITY Rgr "&#x003A1;" ><!--GREEK CAPITAL LETTER RHO -->
-<!ENTITY rgr "&#x003C1;" ><!--GREEK SMALL LETTER RHO -->
-<!ENTITY sfgr "&#x003C2;" ><!--GREEK SMALL LETTER FINAL SIGMA -->
-<!ENTITY Sgr "&#x003A3;" ><!--GREEK CAPITAL LETTER SIGMA -->
-<!ENTITY sgr "&#x003C3;" ><!--GREEK SMALL LETTER SIGMA -->
-<!ENTITY Tgr "&#x003A4;" ><!--GREEK CAPITAL LETTER TAU -->
-<!ENTITY tgr "&#x003C4;" ><!--GREEK SMALL LETTER TAU -->
-<!ENTITY THgr "&#x00398;" ><!--GREEK CAPITAL LETTER THETA -->
-<!ENTITY thgr "&#x003B8;" ><!--GREEK SMALL LETTER THETA -->
-<!ENTITY Ugr "&#x003A5;" ><!--GREEK CAPITAL LETTER UPSILON -->
-<!ENTITY ugr "&#x003C5;" ><!--GREEK SMALL LETTER UPSILON -->
-<!ENTITY Xgr "&#x0039E;" ><!--GREEK CAPITAL LETTER XI -->
-<!ENTITY xgr "&#x003BE;" ><!--GREEK SMALL LETTER XI -->
-<!ENTITY Zgr "&#x00396;" ><!--GREEK CAPITAL LETTER ZETA -->
-<!ENTITY zgr "&#x003B6;" ><!--GREEK SMALL LETTER ZETA -->
diff --git a/Utilities/xml/docbook-4.5/ent/isogrk2.ent b/Utilities/xml/docbook-4.5/ent/isogrk2.ent
deleted file mode 100644
index 726b7dd70..000000000
--- a/Utilities/xml/docbook-4.5/ent/isogrk2.ent
+++ /dev/null
@@ -1,61 +0,0 @@
-
-<!--
- File isogrk2.ent produced by the XSL script entities.xsl
- from input data in unicode.xml.
-
- Please report any errors to David Carlisle
- via the public W3C list www-math@w3.org.
-
- The numeric character values assigned to each entity
- (should) match the Unicode assignments in Unicode 4.0.
-
- Entity names in this file are derived from files carrying the
- following notice:
-
- (C) International Organization for Standardization 1986
- Permission to copy in any form is granted for use with
- conforming SGML systems and applications as defined in
- ISO 8879, provided this notice is included in all copies.
-
--->
-
-
-<!--
- Version: $Id: isogrk2.ent,v 1.2 2003/12/08 15:14:43 davidc Exp $
-
- Public identifier: ISO 8879:1986//ENTITIES Monotoniko Greek//EN//XML
- System identifier: http://www.w3.org/2003/entities/iso8879/isogrk2.ent
-
- The public identifier should always be used verbatim.
- The system identifier may be changed to suit local requirements.
-
- Typical invocation:
-
- <!ENTITY % isogrk2 PUBLIC
- "ISO 8879:1986//ENTITIES Monotoniko Greek//EN//XML"
- "http://www.w3.org/2003/entities/iso8879/isogrk2.ent"
- >
- %isogrk2;
-
--->
-
-<!ENTITY Aacgr "&#x00386;" ><!--GREEK CAPITAL LETTER ALPHA WITH TONOS -->
-<!ENTITY aacgr "&#x003AC;" ><!--GREEK SMALL LETTER ALPHA WITH TONOS -->
-<!ENTITY Eacgr "&#x00388;" ><!--GREEK CAPITAL LETTER EPSILON WITH TONOS -->
-<!ENTITY eacgr "&#x003AD;" ><!--GREEK SMALL LETTER EPSILON WITH TONOS -->
-<!ENTITY EEacgr "&#x00389;" ><!--GREEK CAPITAL LETTER ETA WITH TONOS -->
-<!ENTITY eeacgr "&#x003AE;" ><!--GREEK SMALL LETTER ETA WITH TONOS -->
-<!ENTITY Iacgr "&#x0038A;" ><!--GREEK CAPITAL LETTER IOTA WITH TONOS -->
-<!ENTITY iacgr "&#x003AF;" ><!--GREEK SMALL LETTER IOTA WITH TONOS -->
-<!ENTITY idiagr "&#x00390;" ><!--GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS -->
-<!ENTITY Idigr "&#x003AA;" ><!--GREEK CAPITAL LETTER IOTA WITH DIALYTIKA -->
-<!ENTITY idigr "&#x003CA;" ><!--GREEK SMALL LETTER IOTA WITH DIALYTIKA -->
-<!ENTITY Oacgr "&#x0038C;" ><!--GREEK CAPITAL LETTER OMICRON WITH TONOS -->
-<!ENTITY oacgr "&#x003CC;" ><!--GREEK SMALL LETTER OMICRON WITH TONOS -->
-<!ENTITY OHacgr "&#x0038F;" ><!--GREEK CAPITAL LETTER OMEGA WITH TONOS -->
-<!ENTITY ohacgr "&#x003CE;" ><!--GREEK SMALL LETTER OMEGA WITH TONOS -->
-<!ENTITY Uacgr "&#x0038E;" ><!--GREEK CAPITAL LETTER UPSILON WITH TONOS -->
-<!ENTITY uacgr "&#x003CD;" ><!--GREEK SMALL LETTER UPSILON WITH TONOS -->
-<!ENTITY udiagr "&#x003B0;" ><!--GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS -->
-<!ENTITY Udigr "&#x003AB;" ><!--GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA -->
-<!ENTITY udigr "&#x003CB;" ><!--GREEK SMALL LETTER UPSILON WITH DIALYTIKA -->
diff --git a/Utilities/xml/docbook-4.5/ent/isogrk3.ent b/Utilities/xml/docbook-4.5/ent/isogrk3.ent
deleted file mode 100644
index 28b5c2766..000000000
--- a/Utilities/xml/docbook-4.5/ent/isogrk3.ent
+++ /dev/null
@@ -1,84 +0,0 @@
-
-<!--
- File isogrk3.ent produced by the XSL script entities.xsl
- from input data in unicode.xml.
-
- Please report any errors to David Carlisle
- via the public W3C list www-math@w3.org.
-
- The numeric character values assigned to each entity
- (should) match the Unicode assignments in Unicode 4.0.
-
- Entity names in this file are derived from files carrying the
- following notice:
-
- (C) International Organization for Standardization 1986
- Permission to copy in any form is granted for use with
- conforming SGML systems and applications as defined in
- ISO 8879, provided this notice is included in all copies.
-
--->
-
-
-<!--
- Version: $Id: isogrk3.ent,v 1.2 2003/12/08 15:14:43 davidc Exp $
-
- Public identifier: ISO 8879:1986//ENTITIES Greek Symbols//EN//XML
- System identifier: http://www.w3.org/2003/entities/iso8879/isogrk3.ent
-
- The public identifier should always be used verbatim.
- The system identifier may be changed to suit local requirements.
-
- Typical invocation:
-
- <!ENTITY % isogrk3 PUBLIC
- "ISO 8879:1986//ENTITIES Greek Symbols//EN//XML"
- "http://www.w3.org/2003/entities/iso8879/isogrk3.ent"
- >
- %isogrk3;
-
--->
-
-<!ENTITY alpha "&#x003B1;" ><!--GREEK SMALL LETTER ALPHA -->
-<!ENTITY beta "&#x003B2;" ><!--GREEK SMALL LETTER BETA -->
-<!ENTITY chi "&#x003C7;" ><!--GREEK SMALL LETTER CHI -->
-<!ENTITY Delta "&#x00394;" ><!--GREEK CAPITAL LETTER DELTA -->
-<!ENTITY delta "&#x003B4;" ><!--GREEK SMALL LETTER DELTA -->
-<!ENTITY epsi "&#x003F5;" ><!--GREEK LUNATE EPSILON SYMBOL -->
-<!ENTITY epsis "&#x003F5;" ><!--GREEK LUNATE EPSILON SYMBOL -->
-<!ENTITY epsiv "&#x003B5;" ><!--GREEK SMALL LETTER EPSILON -->
-<!ENTITY eta "&#x003B7;" ><!--GREEK SMALL LETTER ETA -->
-<!ENTITY Gamma "&#x00393;" ><!--GREEK CAPITAL LETTER GAMMA -->
-<!ENTITY gamma "&#x003B3;" ><!--GREEK SMALL LETTER GAMMA -->
-<!ENTITY gammad "&#x003DD;" ><!--GREEK SMALL LETTER DIGAMMA -->
-<!ENTITY iota "&#x003B9;" ><!--GREEK SMALL LETTER IOTA -->
-<!ENTITY kappa "&#x003BA;" ><!--GREEK SMALL LETTER KAPPA -->
-<!ENTITY kappav "&#x003F0;" ><!--GREEK KAPPA SYMBOL -->
-<!ENTITY Lambda "&#x0039B;" ><!--GREEK CAPITAL LETTER LAMDA -->
-<!ENTITY lambda "&#x003BB;" ><!--GREEK SMALL LETTER LAMDA -->
-<!ENTITY mu "&#x003BC;" ><!--GREEK SMALL LETTER MU -->
-<!ENTITY nu "&#x003BD;" ><!--GREEK SMALL LETTER NU -->
-<!ENTITY Omega "&#x003A9;" ><!--GREEK CAPITAL LETTER OMEGA -->
-<!ENTITY omega "&#x003C9;" ><!--GREEK SMALL LETTER OMEGA -->
-<!ENTITY Phi "&#x003A6;" ><!--GREEK CAPITAL LETTER PHI -->
-<!ENTITY phis "&#x003D5;" ><!--GREEK PHI SYMBOL -->
-<!ENTITY phiv "&#x003C6;" ><!--GREEK SMALL LETTER PHI -->
-<!ENTITY Pi "&#x003A0;" ><!--GREEK CAPITAL LETTER PI -->
-<!ENTITY pi "&#x003C0;" ><!--GREEK SMALL LETTER PI -->
-<!ENTITY piv "&#x003D6;" ><!--GREEK PI SYMBOL -->
-<!ENTITY Psi "&#x003A8;" ><!--GREEK CAPITAL LETTER PSI -->
-<!ENTITY psi "&#x003C8;" ><!--GREEK SMALL LETTER PSI -->
-<!ENTITY rho "&#x003C1;" ><!--GREEK SMALL LETTER RHO -->
-<!ENTITY rhov "&#x003F1;" ><!--GREEK RHO SYMBOL -->
-<!ENTITY Sigma "&#x003A3;" ><!--GREEK CAPITAL LETTER SIGMA -->
-<!ENTITY sigma "&#x003C3;" ><!--GREEK SMALL LETTER SIGMA -->
-<!ENTITY sigmav "&#x003C2;" ><!--GREEK SMALL LETTER FINAL SIGMA -->
-<!ENTITY tau "&#x003C4;" ><!--GREEK SMALL LETTER TAU -->
-<!ENTITY Theta "&#x00398;" ><!--GREEK CAPITAL LETTER THETA -->
-<!ENTITY thetas "&#x003B8;" ><!--GREEK SMALL LETTER THETA -->
-<!ENTITY thetav "&#x003D1;" ><!--GREEK THETA SYMBOL -->
-<!ENTITY Upsi "&#x003D2;" ><!--GREEK UPSILON WITH HOOK SYMBOL -->
-<!ENTITY upsi "&#x003C5;" ><!--GREEK SMALL LETTER UPSILON -->
-<!ENTITY Xi "&#x0039E;" ><!--GREEK CAPITAL LETTER XI -->
-<!ENTITY xi "&#x003BE;" ><!--GREEK SMALL LETTER XI -->
-<!ENTITY zeta "&#x003B6;" ><!--GREEK SMALL LETTER ZETA -->
diff --git a/Utilities/xml/docbook-4.5/ent/isogrk4.ent b/Utilities/xml/docbook-4.5/ent/isogrk4.ent
deleted file mode 100644
index 27c6a514f..000000000
--- a/Utilities/xml/docbook-4.5/ent/isogrk4.ent
+++ /dev/null
@@ -1,84 +0,0 @@
-
-<!--
- File isogrk4.ent produced by the XSL script entities.xsl
- from input data in unicode.xml.
-
- Please report any errors to David Carlisle
- via the public W3C list www-math@w3.org.
-
- The numeric character values assigned to each entity
- (should) match the Unicode assignments in Unicode 4.0.
-
- Entity names in this file are derived from files carrying the
- following notice:
-
- (C) International Organization for Standardization 1986
- Permission to copy in any form is granted for use with
- conforming SGML systems and applications as defined in
- ISO 8879, provided this notice is included in all copies.
-
--->
-
-
-<!--
- Version: $Id: isogrk4.ent,v 1.2 2003/12/08 15:14:43 davidc Exp $
-
- Public identifier: ISO 8879:1986//ENTITIES Alternative Greek Symbols//EN//XML
- System identifier: http://www.w3.org/2003/entities/iso8879/isogrk4.ent
-
- The public identifier should always be used verbatim.
- The system identifier may be changed to suit local requirements.
-
- Typical invocation:
-
- <!ENTITY % isogrk4 PUBLIC
- "ISO 8879:1986//ENTITIES Alternative Greek Symbols//EN//XML"
- "http://www.w3.org/2003/entities/iso8879/isogrk4.ent"
- >
- %isogrk4;
-
--->
-
-<!ENTITY b.alpha "&#x1D6C2;" ><!--MATHEMATICAL BOLD SMALL ALPHA -->
-<!ENTITY b.beta "&#x1D6C3;" ><!--MATHEMATICAL BOLD SMALL BETA -->
-<!ENTITY b.chi "&#x1D6D8;" ><!--MATHEMATICAL BOLD SMALL CHI -->
-<!ENTITY b.Delta "&#x1D6AB;" ><!--MATHEMATICAL BOLD CAPITAL DELTA -->
-<!ENTITY b.delta "&#x1D6C5;" ><!--MATHEMATICAL BOLD SMALL DELTA -->
-<!ENTITY b.epsi "&#x1D6C6;" ><!--MATHEMATICAL BOLD SMALL EPSILON -->
-<!ENTITY b.epsiv "&#x1D6DC;" ><!--MATHEMATICAL BOLD EPSILON SYMBOL -->
-<!ENTITY b.eta "&#x1D6C8;" ><!--MATHEMATICAL BOLD SMALL ETA -->
-<!ENTITY b.Gamma "&#x1D6AA;" ><!--MATHEMATICAL BOLD CAPITAL GAMMA -->
-<!ENTITY b.gamma "&#x1D6C4;" ><!--MATHEMATICAL BOLD SMALL GAMMA -->
-<!ENTITY b.Gammad "&#x003DC;" ><!--GREEK LETTER DIGAMMA -->
-<!ENTITY b.gammad "&#x003DD;" ><!--GREEK SMALL LETTER DIGAMMA -->
-<!ENTITY b.iota "&#x1D6CA;" ><!--MATHEMATICAL BOLD SMALL IOTA -->
-<!ENTITY b.kappa "&#x1D6CB;" ><!--MATHEMATICAL BOLD SMALL KAPPA -->
-<!ENTITY b.kappav "&#x1D6DE;" ><!--MATHEMATICAL BOLD KAPPA SYMBOL -->
-<!ENTITY b.Lambda "&#x1D6B2;" ><!--MATHEMATICAL BOLD CAPITAL LAMDA -->
-<!ENTITY b.lambda "&#x1D6CC;" ><!--MATHEMATICAL BOLD SMALL LAMDA -->
-<!ENTITY b.mu "&#x1D6CD;" ><!--MATHEMATICAL BOLD SMALL MU -->
-<!ENTITY b.nu "&#x1D6CE;" ><!--MATHEMATICAL BOLD SMALL NU -->
-<!ENTITY b.Omega "&#x1D6C0;" ><!--MATHEMATICAL BOLD CAPITAL OMEGA -->
-<!ENTITY b.omega "&#x1D6DA;" ><!--MATHEMATICAL BOLD SMALL OMEGA -->
-<!ENTITY b.Phi "&#x1D6BD;" ><!--MATHEMATICAL BOLD CAPITAL PHI -->
-<!ENTITY b.phi "&#x1D6D7;" ><!--MATHEMATICAL BOLD SMALL PHI -->
-<!ENTITY b.phiv "&#x1D6DF;" ><!--MATHEMATICAL BOLD PHI SYMBOL -->
-<!ENTITY b.Pi "&#x1D6B7;" ><!--MATHEMATICAL BOLD CAPITAL PI -->
-<!ENTITY b.pi "&#x1D6D1;" ><!--MATHEMATICAL BOLD SMALL PI -->
-<!ENTITY b.piv "&#x1D6E1;" ><!--MATHEMATICAL BOLD PI SYMBOL -->
-<!ENTITY b.Psi "&#x1D6BF;" ><!--MATHEMATICAL BOLD CAPITAL PSI -->
-<!ENTITY b.psi "&#x1D6D9;" ><!--MATHEMATICAL BOLD SMALL PSI -->
-<!ENTITY b.rho "&#x1D6D2;" ><!--MATHEMATICAL BOLD SMALL RHO -->
-<!ENTITY b.rhov "&#x1D6E0;" ><!--MATHEMATICAL BOLD RHO SYMBOL -->
-<!ENTITY b.Sigma "&#x1D6BA;" ><!--MATHEMATICAL BOLD CAPITAL SIGMA -->
-<!ENTITY b.sigma "&#x1D6D4;" ><!--MATHEMATICAL BOLD SMALL SIGMA -->
-<!ENTITY b.sigmav "&#x1D6D3;" ><!--MATHEMATICAL BOLD SMALL FINAL SIGMA -->
-<!ENTITY b.tau "&#x1D6D5;" ><!--MATHEMATICAL BOLD SMALL TAU -->
-<!ENTITY b.Theta "&#x1D6AF;" ><!--MATHEMATICAL BOLD CAPITAL THETA -->
-<!ENTITY b.thetas "&#x1D6C9;" ><!--MATHEMATICAL BOLD SMALL THETA -->
-<!ENTITY b.thetav "&#x1D6DD;" ><!--MATHEMATICAL BOLD THETA SYMBOL -->
-<!ENTITY b.Upsi "&#x1D6BC;" ><!--MATHEMATICAL BOLD CAPITAL UPSILON -->
-<!ENTITY b.upsi "&#x1D6D6;" ><!--MATHEMATICAL BOLD SMALL UPSILON -->
-<!ENTITY b.Xi "&#x1D6B5;" ><!--MATHEMATICAL BOLD CAPITAL XI -->
-<!ENTITY b.xi "&#x1D6CF;" ><!--MATHEMATICAL BOLD SMALL XI -->
-<!ENTITY b.zeta "&#x1D6C7;" ><!--MATHEMATICAL BOLD SMALL ZETA -->
diff --git a/Utilities/xml/docbook-4.5/ent/isolat1.ent b/Utilities/xml/docbook-4.5/ent/isolat1.ent
deleted file mode 100644
index 381bd0900..000000000
--- a/Utilities/xml/docbook-4.5/ent/isolat1.ent
+++ /dev/null
@@ -1,103 +0,0 @@
-
-<!--
- File isolat1.ent produced by the XSL script entities.xsl
- from input data in unicode.xml.
-
- Please report any errors to David Carlisle
- via the public W3C list www-math@w3.org.
-
- The numeric character values assigned to each entity
- (should) match the Unicode assignments in Unicode 4.0.
-
- Entity names in this file are derived from files carrying the
- following notice:
-
- (C) International Organization for Standardization 1986
- Permission to copy in any form is granted for use with
- conforming SGML systems and applications as defined in
- ISO 8879, provided this notice is included in all copies.
-
--->
-
-
-<!--
- Version: $Id: isolat1.ent,v 1.2 2003/12/08 15:14:43 davidc Exp $
-
- Public identifier: ISO 8879:1986//ENTITIES Added Latin 1//EN//XML
- System identifier: http://www.w3.org/2003/entities/iso8879/isolat1.ent
-
- The public identifier should always be used verbatim.
- The system identifier may be changed to suit local requirements.
-
- Typical invocation:
-
- <!ENTITY % isolat1 PUBLIC
- "ISO 8879:1986//ENTITIES Added Latin 1//EN//XML"
- "http://www.w3.org/2003/entities/iso8879/isolat1.ent"
- >
- %isolat1;
-
--->
-
-<!ENTITY Aacute "&#x000C1;" ><!--LATIN CAPITAL LETTER A WITH ACUTE -->
-<!ENTITY aacute "&#x000E1;" ><!--LATIN SMALL LETTER A WITH ACUTE -->
-<!ENTITY Acirc "&#x000C2;" ><!--LATIN CAPITAL LETTER A WITH CIRCUMFLEX -->
-<!ENTITY acirc "&#x000E2;" ><!--LATIN SMALL LETTER A WITH CIRCUMFLEX -->
-<!ENTITY AElig "&#x000C6;" ><!--LATIN CAPITAL LETTER AE -->
-<!ENTITY aelig "&#x000E6;" ><!--LATIN SMALL LETTER AE -->
-<!ENTITY Agrave "&#x000C0;" ><!--LATIN CAPITAL LETTER A WITH GRAVE -->
-<!ENTITY agrave "&#x000E0;" ><!--LATIN SMALL LETTER A WITH GRAVE -->
-<!ENTITY Aring "&#x000C5;" ><!--LATIN CAPITAL LETTER A WITH RING ABOVE -->
-<!ENTITY aring "&#x000E5;" ><!--LATIN SMALL LETTER A WITH RING ABOVE -->
-<!ENTITY Atilde "&#x000C3;" ><!--LATIN CAPITAL LETTER A WITH TILDE -->
-<!ENTITY atilde "&#x000E3;" ><!--LATIN SMALL LETTER A WITH TILDE -->
-<!ENTITY Auml "&#x000C4;" ><!--LATIN CAPITAL LETTER A WITH DIAERESIS -->
-<!ENTITY auml "&#x000E4;" ><!--LATIN SMALL LETTER A WITH DIAERESIS -->
-<!ENTITY Ccedil "&#x000C7;" ><!--LATIN CAPITAL LETTER C WITH CEDILLA -->
-<!ENTITY ccedil "&#x000E7;" ><!--LATIN SMALL LETTER C WITH CEDILLA -->
-<!ENTITY Eacute "&#x000C9;" ><!--LATIN CAPITAL LETTER E WITH ACUTE -->
-<!ENTITY eacute "&#x000E9;" ><!--LATIN SMALL LETTER E WITH ACUTE -->
-<!ENTITY Ecirc "&#x000CA;" ><!--LATIN CAPITAL LETTER E WITH CIRCUMFLEX -->
-<!ENTITY ecirc "&#x000EA;" ><!--LATIN SMALL LETTER E WITH CIRCUMFLEX -->
-<!ENTITY Egrave "&#x000C8;" ><!--LATIN CAPITAL LETTER E WITH GRAVE -->
-<!ENTITY egrave "&#x000E8;" ><!--LATIN SMALL LETTER E WITH GRAVE -->
-<!ENTITY ETH "&#x000D0;" ><!--LATIN CAPITAL LETTER ETH -->
-<!ENTITY eth "&#x000F0;" ><!--LATIN SMALL LETTER ETH -->
-<!ENTITY Euml "&#x000CB;" ><!--LATIN CAPITAL LETTER E WITH DIAERESIS -->
-<!ENTITY euml "&#x000EB;" ><!--LATIN SMALL LETTER E WITH DIAERESIS -->
-<!ENTITY Iacute "&#x000CD;" ><!--LATIN CAPITAL LETTER I WITH ACUTE -->
-<!ENTITY iacute "&#x000ED;" ><!--LATIN SMALL LETTER I WITH ACUTE -->
-<!ENTITY Icirc "&#x000CE;" ><!--LATIN CAPITAL LETTER I WITH CIRCUMFLEX -->
-<!ENTITY icirc "&#x000EE;" ><!--LATIN SMALL LETTER I WITH CIRCUMFLEX -->
-<!ENTITY Igrave "&#x000CC;" ><!--LATIN CAPITAL LETTER I WITH GRAVE -->
-<!ENTITY igrave "&#x000EC;" ><!--LATIN SMALL LETTER I WITH GRAVE -->
-<!ENTITY Iuml "&#x000CF;" ><!--LATIN CAPITAL LETTER I WITH DIAERESIS -->
-<!ENTITY iuml "&#x000EF;" ><!--LATIN SMALL LETTER I WITH DIAERESIS -->
-<!ENTITY Ntilde "&#x000D1;" ><!--LATIN CAPITAL LETTER N WITH TILDE -->
-<!ENTITY ntilde "&#x000F1;" ><!--LATIN SMALL LETTER N WITH TILDE -->
-<!ENTITY Oacute "&#x000D3;" ><!--LATIN CAPITAL LETTER O WITH ACUTE -->
-<!ENTITY oacute "&#x000F3;" ><!--LATIN SMALL LETTER O WITH ACUTE -->
-<!ENTITY Ocirc "&#x000D4;" ><!--LATIN CAPITAL LETTER O WITH CIRCUMFLEX -->
-<!ENTITY ocirc "&#x000F4;" ><!--LATIN SMALL LETTER O WITH CIRCUMFLEX -->
-<!ENTITY Ograve "&#x000D2;" ><!--LATIN CAPITAL LETTER O WITH GRAVE -->
-<!ENTITY ograve "&#x000F2;" ><!--LATIN SMALL LETTER O WITH GRAVE -->
-<!ENTITY Oslash "&#x000D8;" ><!--LATIN CAPITAL LETTER O WITH STROKE -->
-<!ENTITY oslash "&#x000F8;" ><!--LATIN SMALL LETTER O WITH STROKE -->
-<!ENTITY Otilde "&#x000D5;" ><!--LATIN CAPITAL LETTER O WITH TILDE -->
-<!ENTITY otilde "&#x000F5;" ><!--LATIN SMALL LETTER O WITH TILDE -->
-<!ENTITY Ouml "&#x000D6;" ><!--LATIN CAPITAL LETTER O WITH DIAERESIS -->
-<!ENTITY ouml "&#x000F6;" ><!--LATIN SMALL LETTER O WITH DIAERESIS -->
-<!ENTITY szlig "&#x000DF;" ><!--LATIN SMALL LETTER SHARP S -->
-<!ENTITY THORN "&#x000DE;" ><!--LATIN CAPITAL LETTER THORN -->
-<!ENTITY thorn "&#x000FE;" ><!--LATIN SMALL LETTER THORN -->
-<!ENTITY Uacute "&#x000DA;" ><!--LATIN CAPITAL LETTER U WITH ACUTE -->
-<!ENTITY uacute "&#x000FA;" ><!--LATIN SMALL LETTER U WITH ACUTE -->
-<!ENTITY Ucirc "&#x000DB;" ><!--LATIN CAPITAL LETTER U WITH CIRCUMFLEX -->
-<!ENTITY ucirc "&#x000FB;" ><!--LATIN SMALL LETTER U WITH CIRCUMFLEX -->
-<!ENTITY Ugrave "&#x000D9;" ><!--LATIN CAPITAL LETTER U WITH GRAVE -->
-<!ENTITY ugrave "&#x000F9;" ><!--LATIN SMALL LETTER U WITH GRAVE -->
-<!ENTITY Uuml "&#x000DC;" ><!--LATIN CAPITAL LETTER U WITH DIAERESIS -->
-<!ENTITY uuml "&#x000FC;" ><!--LATIN SMALL LETTER U WITH DIAERESIS -->
-<!ENTITY Yacute "&#x000DD;" ><!--LATIN CAPITAL LETTER Y WITH ACUTE -->
-<!ENTITY yacute "&#x000FD;" ><!--LATIN SMALL LETTER Y WITH ACUTE -->
-<!ENTITY yuml "&#x000FF;" ><!--LATIN SMALL LETTER Y WITH DIAERESIS -->
diff --git a/Utilities/xml/docbook-4.5/ent/isolat2.ent b/Utilities/xml/docbook-4.5/ent/isolat2.ent
deleted file mode 100644
index e91ffdbee..000000000
--- a/Utilities/xml/docbook-4.5/ent/isolat2.ent
+++ /dev/null
@@ -1,162 +0,0 @@
-
-<!--
- File isolat2.ent produced by the XSL script entities.xsl
- from input data in unicode.xml.
-
- Please report any errors to David Carlisle
- via the public W3C list www-math@w3.org.
-
- The numeric character values assigned to each entity
- (should) match the Unicode assignments in Unicode 4.0.
-
- Entity names in this file are derived from files carrying the
- following notice:
-
- (C) International Organization for Standardization 1986
- Permission to copy in any form is granted for use with
- conforming SGML systems and applications as defined in
- ISO 8879, provided this notice is included in all copies.
-
--->
-
-
-<!--
- Version: $Id: isolat2.ent,v 1.2 2003/12/08 15:14:43 davidc Exp $
-
- Public identifier: ISO 8879:1986//ENTITIES Added Latin 2//EN//XML
- System identifier: http://www.w3.org/2003/entities/iso8879/isolat2.ent
-
- The public identifier should always be used verbatim.
- The system identifier may be changed to suit local requirements.
-
- Typical invocation:
-
- <!ENTITY % isolat2 PUBLIC
- "ISO 8879:1986//ENTITIES Added Latin 2//EN//XML"
- "http://www.w3.org/2003/entities/iso8879/isolat2.ent"
- >
- %isolat2;
-
--->
-
-<!ENTITY Abreve "&#x00102;" ><!--LATIN CAPITAL LETTER A WITH BREVE -->
-<!ENTITY abreve "&#x00103;" ><!--LATIN SMALL LETTER A WITH BREVE -->
-<!ENTITY Amacr "&#x00100;" ><!--LATIN CAPITAL LETTER A WITH MACRON -->
-<!ENTITY amacr "&#x00101;" ><!--LATIN SMALL LETTER A WITH MACRON -->
-<!ENTITY Aogon "&#x00104;" ><!--LATIN CAPITAL LETTER A WITH OGONEK -->
-<!ENTITY aogon "&#x00105;" ><!--LATIN SMALL LETTER A WITH OGONEK -->
-<!ENTITY Cacute "&#x00106;" ><!--LATIN CAPITAL LETTER C WITH ACUTE -->
-<!ENTITY cacute "&#x00107;" ><!--LATIN SMALL LETTER C WITH ACUTE -->
-<!ENTITY Ccaron "&#x0010C;" ><!--LATIN CAPITAL LETTER C WITH CARON -->
-<!ENTITY ccaron "&#x0010D;" ><!--LATIN SMALL LETTER C WITH CARON -->
-<!ENTITY Ccirc "&#x00108;" ><!--LATIN CAPITAL LETTER C WITH CIRCUMFLEX -->
-<!ENTITY ccirc "&#x00109;" ><!--LATIN SMALL LETTER C WITH CIRCUMFLEX -->
-<!ENTITY Cdot "&#x0010A;" ><!--LATIN CAPITAL LETTER C WITH DOT ABOVE -->
-<!ENTITY cdot "&#x0010B;" ><!--LATIN SMALL LETTER C WITH DOT ABOVE -->
-<!ENTITY Dcaron "&#x0010E;" ><!--LATIN CAPITAL LETTER D WITH CARON -->
-<!ENTITY dcaron "&#x0010F;" ><!--LATIN SMALL LETTER D WITH CARON -->
-<!ENTITY Dstrok "&#x00110;" ><!--LATIN CAPITAL LETTER D WITH STROKE -->
-<!ENTITY dstrok "&#x00111;" ><!--LATIN SMALL LETTER D WITH STROKE -->
-<!ENTITY Ecaron "&#x0011A;" ><!--LATIN CAPITAL LETTER E WITH CARON -->
-<!ENTITY ecaron "&#x0011B;" ><!--LATIN SMALL LETTER E WITH CARON -->
-<!ENTITY Edot "&#x00116;" ><!--LATIN CAPITAL LETTER E WITH DOT ABOVE -->
-<!ENTITY edot "&#x00117;" ><!--LATIN SMALL LETTER E WITH DOT ABOVE -->
-<!ENTITY Emacr "&#x00112;" ><!--LATIN CAPITAL LETTER E WITH MACRON -->
-<!ENTITY emacr "&#x00113;" ><!--LATIN SMALL LETTER E WITH MACRON -->
-<!ENTITY ENG "&#x0014A;" ><!--LATIN CAPITAL LETTER ENG -->
-<!ENTITY eng "&#x0014B;" ><!--LATIN SMALL LETTER ENG -->
-<!ENTITY Eogon "&#x00118;" ><!--LATIN CAPITAL LETTER E WITH OGONEK -->
-<!ENTITY eogon "&#x00119;" ><!--LATIN SMALL LETTER E WITH OGONEK -->
-<!ENTITY gacute "&#x001F5;" ><!--LATIN SMALL LETTER G WITH ACUTE -->
-<!ENTITY Gbreve "&#x0011E;" ><!--LATIN CAPITAL LETTER G WITH BREVE -->
-<!ENTITY gbreve "&#x0011F;" ><!--LATIN SMALL LETTER G WITH BREVE -->
-<!ENTITY Gcedil "&#x00122;" ><!--LATIN CAPITAL LETTER G WITH CEDILLA -->
-<!ENTITY Gcirc "&#x0011C;" ><!--LATIN CAPITAL LETTER G WITH CIRCUMFLEX -->
-<!ENTITY gcirc "&#x0011D;" ><!--LATIN SMALL LETTER G WITH CIRCUMFLEX -->
-<!ENTITY Gdot "&#x00120;" ><!--LATIN CAPITAL LETTER G WITH DOT ABOVE -->
-<!ENTITY gdot "&#x00121;" ><!--LATIN SMALL LETTER G WITH DOT ABOVE -->
-<!ENTITY Hcirc "&#x00124;" ><!--LATIN CAPITAL LETTER H WITH CIRCUMFLEX -->
-<!ENTITY hcirc "&#x00125;" ><!--LATIN SMALL LETTER H WITH CIRCUMFLEX -->
-<!ENTITY Hstrok "&#x00126;" ><!--LATIN CAPITAL LETTER H WITH STROKE -->
-<!ENTITY hstrok "&#x00127;" ><!--LATIN SMALL LETTER H WITH STROKE -->
-<!ENTITY Idot "&#x00130;" ><!--LATIN CAPITAL LETTER I WITH DOT ABOVE -->
-<!ENTITY IJlig "&#x00132;" ><!--LATIN CAPITAL LIGATURE IJ -->
-<!ENTITY ijlig "&#x00133;" ><!--LATIN SMALL LIGATURE IJ -->
-<!ENTITY Imacr "&#x0012A;" ><!--LATIN CAPITAL LETTER I WITH MACRON -->
-<!ENTITY imacr "&#x0012B;" ><!--LATIN SMALL LETTER I WITH MACRON -->
-<!ENTITY inodot "&#x00131;" ><!--LATIN SMALL LETTER DOTLESS I -->
-<!ENTITY Iogon "&#x0012E;" ><!--LATIN CAPITAL LETTER I WITH OGONEK -->
-<!ENTITY iogon "&#x0012F;" ><!--LATIN SMALL LETTER I WITH OGONEK -->
-<!ENTITY Itilde "&#x00128;" ><!--LATIN CAPITAL LETTER I WITH TILDE -->
-<!ENTITY itilde "&#x00129;" ><!--LATIN SMALL LETTER I WITH TILDE -->
-<!ENTITY Jcirc "&#x00134;" ><!--LATIN CAPITAL LETTER J WITH CIRCUMFLEX -->
-<!ENTITY jcirc "&#x00135;" ><!--LATIN SMALL LETTER J WITH CIRCUMFLEX -->
-<!ENTITY Kcedil "&#x00136;" ><!--LATIN CAPITAL LETTER K WITH CEDILLA -->
-<!ENTITY kcedil "&#x00137;" ><!--LATIN SMALL LETTER K WITH CEDILLA -->
-<!ENTITY kgreen "&#x00138;" ><!--LATIN SMALL LETTER KRA -->
-<!ENTITY Lacute "&#x00139;" ><!--LATIN CAPITAL LETTER L WITH ACUTE -->
-<!ENTITY lacute "&#x0013A;" ><!--LATIN SMALL LETTER L WITH ACUTE -->
-<!ENTITY Lcaron "&#x0013D;" ><!--LATIN CAPITAL LETTER L WITH CARON -->
-<!ENTITY lcaron "&#x0013E;" ><!--LATIN SMALL LETTER L WITH CARON -->
-<!ENTITY Lcedil "&#x0013B;" ><!--LATIN CAPITAL LETTER L WITH CEDILLA -->
-<!ENTITY lcedil "&#x0013C;" ><!--LATIN SMALL LETTER L WITH CEDILLA -->
-<!ENTITY Lmidot "&#x0013F;" ><!--LATIN CAPITAL LETTER L WITH MIDDLE DOT -->
-<!ENTITY lmidot "&#x00140;" ><!--LATIN SMALL LETTER L WITH MIDDLE DOT -->
-<!ENTITY Lstrok "&#x00141;" ><!--LATIN CAPITAL LETTER L WITH STROKE -->
-<!ENTITY lstrok "&#x00142;" ><!--LATIN SMALL LETTER L WITH STROKE -->
-<!ENTITY Nacute "&#x00143;" ><!--LATIN CAPITAL LETTER N WITH ACUTE -->
-<!ENTITY nacute "&#x00144;" ><!--LATIN SMALL LETTER N WITH ACUTE -->
-<!ENTITY napos "&#x00149;" ><!--LATIN SMALL LETTER N PRECEDED BY APOSTROPHE -->
-<!ENTITY Ncaron "&#x00147;" ><!--LATIN CAPITAL LETTER N WITH CARON -->
-<!ENTITY ncaron "&#x00148;" ><!--LATIN SMALL LETTER N WITH CARON -->
-<!ENTITY Ncedil "&#x00145;" ><!--LATIN CAPITAL LETTER N WITH CEDILLA -->
-<!ENTITY ncedil "&#x00146;" ><!--LATIN SMALL LETTER N WITH CEDILLA -->
-<!ENTITY Odblac "&#x00150;" ><!--LATIN CAPITAL LETTER O WITH DOUBLE ACUTE -->
-<!ENTITY odblac "&#x00151;" ><!--LATIN SMALL LETTER O WITH DOUBLE ACUTE -->
-<!ENTITY OElig "&#x00152;" ><!--LATIN CAPITAL LIGATURE OE -->
-<!ENTITY oelig "&#x00153;" ><!--LATIN SMALL LIGATURE OE -->
-<!ENTITY Omacr "&#x0014C;" ><!--LATIN CAPITAL LETTER O WITH MACRON -->
-<!ENTITY omacr "&#x0014D;" ><!--LATIN SMALL LETTER O WITH MACRON -->
-<!ENTITY Racute "&#x00154;" ><!--LATIN CAPITAL LETTER R WITH ACUTE -->
-<!ENTITY racute "&#x00155;" ><!--LATIN SMALL LETTER R WITH ACUTE -->
-<!ENTITY Rcaron "&#x00158;" ><!--LATIN CAPITAL LETTER R WITH CARON -->
-<!ENTITY rcaron "&#x00159;" ><!--LATIN SMALL LETTER R WITH CARON -->
-<!ENTITY Rcedil "&#x00156;" ><!--LATIN CAPITAL LETTER R WITH CEDILLA -->
-<!ENTITY rcedil "&#x00157;" ><!--LATIN SMALL LETTER R WITH CEDILLA -->
-<!ENTITY Sacute "&#x0015A;" ><!--LATIN CAPITAL LETTER S WITH ACUTE -->
-<!ENTITY sacute "&#x0015B;" ><!--LATIN SMALL LETTER S WITH ACUTE -->
-<!ENTITY Scaron "&#x00160;" ><!--LATIN CAPITAL LETTER S WITH CARON -->
-<!ENTITY scaron "&#x00161;" ><!--LATIN SMALL LETTER S WITH CARON -->
-<!ENTITY Scedil "&#x0015E;" ><!--LATIN CAPITAL LETTER S WITH CEDILLA -->
-<!ENTITY scedil "&#x0015F;" ><!--LATIN SMALL LETTER S WITH CEDILLA -->
-<!ENTITY Scirc "&#x0015C;" ><!--LATIN CAPITAL LETTER S WITH CIRCUMFLEX -->
-<!ENTITY scirc "&#x0015D;" ><!--LATIN SMALL LETTER S WITH CIRCUMFLEX -->
-<!ENTITY Tcaron "&#x00164;" ><!--LATIN CAPITAL LETTER T WITH CARON -->
-<!ENTITY tcaron "&#x00165;" ><!--LATIN SMALL LETTER T WITH CARON -->
-<!ENTITY Tcedil "&#x00162;" ><!--LATIN CAPITAL LETTER T WITH CEDILLA -->
-<!ENTITY tcedil "&#x00163;" ><!--LATIN SMALL LETTER T WITH CEDILLA -->
-<!ENTITY Tstrok "&#x00166;" ><!--LATIN CAPITAL LETTER T WITH STROKE -->
-<!ENTITY tstrok "&#x00167;" ><!--LATIN SMALL LETTER T WITH STROKE -->
-<!ENTITY Ubreve "&#x0016C;" ><!--LATIN CAPITAL LETTER U WITH BREVE -->
-<!ENTITY ubreve "&#x0016D;" ><!--LATIN SMALL LETTER U WITH BREVE -->
-<!ENTITY Udblac "&#x00170;" ><!--LATIN CAPITAL LETTER U WITH DOUBLE ACUTE -->
-<!ENTITY udblac "&#x00171;" ><!--LATIN SMALL LETTER U WITH DOUBLE ACUTE -->
-<!ENTITY Umacr "&#x0016A;" ><!--LATIN CAPITAL LETTER U WITH MACRON -->
-<!ENTITY umacr "&#x0016B;" ><!--LATIN SMALL LETTER U WITH MACRON -->
-<!ENTITY Uogon "&#x00172;" ><!--LATIN CAPITAL LETTER U WITH OGONEK -->
-<!ENTITY uogon "&#x00173;" ><!--LATIN SMALL LETTER U WITH OGONEK -->
-<!ENTITY Uring "&#x0016E;" ><!--LATIN CAPITAL LETTER U WITH RING ABOVE -->
-<!ENTITY uring "&#x0016F;" ><!--LATIN SMALL LETTER U WITH RING ABOVE -->
-<!ENTITY Utilde "&#x00168;" ><!--LATIN CAPITAL LETTER U WITH TILDE -->
-<!ENTITY utilde "&#x00169;" ><!--LATIN SMALL LETTER U WITH TILDE -->
-<!ENTITY Wcirc "&#x00174;" ><!--LATIN CAPITAL LETTER W WITH CIRCUMFLEX -->
-<!ENTITY wcirc "&#x00175;" ><!--LATIN SMALL LETTER W WITH CIRCUMFLEX -->
-<!ENTITY Ycirc "&#x00176;" ><!--LATIN CAPITAL LETTER Y WITH CIRCUMFLEX -->
-<!ENTITY ycirc "&#x00177;" ><!--LATIN SMALL LETTER Y WITH CIRCUMFLEX -->
-<!ENTITY Yuml "&#x00178;" ><!--LATIN CAPITAL LETTER Y WITH DIAERESIS -->
-<!ENTITY Zacute "&#x00179;" ><!--LATIN CAPITAL LETTER Z WITH ACUTE -->
-<!ENTITY zacute "&#x0017A;" ><!--LATIN SMALL LETTER Z WITH ACUTE -->
-<!ENTITY Zcaron "&#x0017D;" ><!--LATIN CAPITAL LETTER Z WITH CARON -->
-<!ENTITY zcaron "&#x0017E;" ><!--LATIN SMALL LETTER Z WITH CARON -->
-<!ENTITY Zdot "&#x0017B;" ><!--LATIN CAPITAL LETTER Z WITH DOT ABOVE -->
-<!ENTITY zdot "&#x0017C;" ><!--LATIN SMALL LETTER Z WITH DOT ABOVE -->
diff --git a/Utilities/xml/docbook-4.5/ent/isonum.ent b/Utilities/xml/docbook-4.5/ent/isonum.ent
deleted file mode 100644
index 884c0c4d0..000000000
--- a/Utilities/xml/docbook-4.5/ent/isonum.ent
+++ /dev/null
@@ -1,117 +0,0 @@
-
-<!--
- File isonum.ent produced by the XSL script entities.xsl
- from input data in unicode.xml.
-
- Please report any errors to David Carlisle
- via the public W3C list www-math@w3.org.
-
- The numeric character values assigned to each entity
- (should) match the Unicode assignments in Unicode 4.0.
-
- Entity names in this file are derived from files carrying the
- following notice:
-
- (C) International Organization for Standardization 1986
- Permission to copy in any form is granted for use with
- conforming SGML systems and applications as defined in
- ISO 8879, provided this notice is included in all copies.
-
--->
-
-
-<!--
- Version: $Id: isonum.ent,v 1.2 2003/12/08 15:14:43 davidc Exp $
-
- Public identifier: ISO 8879:1986//ENTITIES Numeric and Special Graphic//EN//XML
- System identifier: http://www.w3.org/2003/entities/iso8879/isonum.ent
-
- The public identifier should always be used verbatim.
- The system identifier may be changed to suit local requirements.
-
- Typical invocation:
-
- <!ENTITY % isonum PUBLIC
- "ISO 8879:1986//ENTITIES Numeric and Special Graphic//EN//XML"
- "http://www.w3.org/2003/entities/iso8879/isonum.ent"
- >
- %isonum;
-
--->
-
-<!ENTITY amp "&#38;#38;" ><!--AMPERSAND -->
-<!ENTITY apos "&#x00027;" ><!--APOSTROPHE -->
-<!ENTITY ast "&#x0002A;" ><!--ASTERISK -->
-<!ENTITY brvbar "&#x000A6;" ><!--BROKEN BAR -->
-<!ENTITY bsol "&#x0005C;" ><!--REVERSE SOLIDUS -->
-<!ENTITY cent "&#x000A2;" ><!--CENT SIGN -->
-<!ENTITY colon "&#x0003A;" ><!--COLON -->
-<!ENTITY comma "&#x0002C;" ><!--COMMA -->
-<!ENTITY commat "&#x00040;" ><!--COMMERCIAL AT -->
-<!ENTITY copy "&#x000A9;" ><!--COPYRIGHT SIGN -->
-<!ENTITY curren "&#x000A4;" ><!--CURRENCY SIGN -->
-<!ENTITY darr "&#x02193;" ><!--DOWNWARDS ARROW -->
-<!ENTITY deg "&#x000B0;" ><!--DEGREE SIGN -->
-<!ENTITY divide "&#x000F7;" ><!--DIVISION SIGN -->
-<!ENTITY dollar "&#x00024;" ><!--DOLLAR SIGN -->
-<!ENTITY equals "&#x0003D;" ><!--EQUALS SIGN -->
-<!ENTITY excl "&#x00021;" ><!--EXCLAMATION MARK -->
-<!ENTITY frac12 "&#x000BD;" ><!--VULGAR FRACTION ONE HALF -->
-<!ENTITY frac14 "&#x000BC;" ><!--VULGAR FRACTION ONE QUARTER -->
-<!ENTITY frac18 "&#x0215B;" ><!--VULGAR FRACTION ONE EIGHTH -->
-<!ENTITY frac34 "&#x000BE;" ><!--VULGAR FRACTION THREE QUARTERS -->
-<!ENTITY frac38 "&#x0215C;" ><!--VULGAR FRACTION THREE EIGHTHS -->
-<!ENTITY frac58 "&#x0215D;" ><!--VULGAR FRACTION FIVE EIGHTHS -->
-<!ENTITY frac78 "&#x0215E;" ><!--VULGAR FRACTION SEVEN EIGHTHS -->
-<!ENTITY gt "&#x0003E;" ><!--GREATER-THAN SIGN -->
-<!ENTITY half "&#x000BD;" ><!--VULGAR FRACTION ONE HALF -->
-<!ENTITY horbar "&#x02015;" ><!--HORIZONTAL BAR -->
-<!ENTITY hyphen "&#x02010;" ><!--HYPHEN -->
-<!ENTITY iexcl "&#x000A1;" ><!--INVERTED EXCLAMATION MARK -->
-<!ENTITY iquest "&#x000BF;" ><!--INVERTED QUESTION MARK -->
-<!ENTITY laquo "&#x000AB;" ><!--LEFT-POINTING DOUBLE ANGLE QUOTATION MARK -->
-<!ENTITY larr "&#x02190;" ><!--LEFTWARDS ARROW -->
-<!ENTITY lcub "&#x0007B;" ><!--LEFT CURLY BRACKET -->
-<!ENTITY ldquo "&#x0201C;" ><!--LEFT DOUBLE QUOTATION MARK -->
-<!ENTITY lowbar "&#x0005F;" ><!--LOW LINE -->
-<!ENTITY lpar "&#x00028;" ><!--LEFT PARENTHESIS -->
-<!ENTITY lsqb "&#x0005B;" ><!--LEFT SQUARE BRACKET -->
-<!ENTITY lsquo "&#x02018;" ><!--LEFT SINGLE QUOTATION MARK -->
-<!ENTITY lt "&#38;#60;" ><!--LESS-THAN SIGN -->
-<!ENTITY micro "&#x000B5;" ><!--MICRO SIGN -->
-<!ENTITY middot "&#x000B7;" ><!--MIDDLE DOT -->
-<!ENTITY nbsp "&#x000A0;" ><!--NO-BREAK SPACE -->
-<!ENTITY not "&#x000AC;" ><!--NOT SIGN -->
-<!ENTITY num "&#x00023;" ><!--NUMBER SIGN -->
-<!ENTITY ohm "&#x02126;" ><!--OHM SIGN -->
-<!ENTITY ordf "&#x000AA;" ><!--FEMININE ORDINAL INDICATOR -->
-<!ENTITY ordm "&#x000BA;" ><!--MASCULINE ORDINAL INDICATOR -->
-<!ENTITY para "&#x000B6;" ><!--PILCROW SIGN -->
-<!ENTITY percnt "&#x00025;" ><!--PERCENT SIGN -->
-<!ENTITY period "&#x0002E;" ><!--FULL STOP -->
-<!ENTITY plus "&#x0002B;" ><!--PLUS SIGN -->
-<!ENTITY plusmn "&#x000B1;" ><!--PLUS-MINUS SIGN -->
-<!ENTITY pound "&#x000A3;" ><!--POUND SIGN -->
-<!ENTITY quest "&#x0003F;" ><!--QUESTION MARK -->
-<!ENTITY quot "&#x00022;" ><!--QUOTATION MARK -->
-<!ENTITY raquo "&#x000BB;" ><!--RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK -->
-<!ENTITY rarr "&#x02192;" ><!--RIGHTWARDS ARROW -->
-<!ENTITY rcub "&#x0007D;" ><!--RIGHT CURLY BRACKET -->
-<!ENTITY rdquo "&#x0201D;" ><!--RIGHT DOUBLE QUOTATION MARK -->
-<!ENTITY reg "&#x000AE;" ><!--REGISTERED SIGN -->
-<!ENTITY rpar "&#x00029;" ><!--RIGHT PARENTHESIS -->
-<!ENTITY rsqb "&#x0005D;" ><!--RIGHT SQUARE BRACKET -->
-<!ENTITY rsquo "&#x02019;" ><!--RIGHT SINGLE QUOTATION MARK -->
-<!ENTITY sect "&#x000A7;" ><!--SECTION SIGN -->
-<!ENTITY semi "&#x0003B;" ><!--SEMICOLON -->
-<!ENTITY shy "&#x000AD;" ><!--SOFT HYPHEN -->
-<!ENTITY sol "&#x0002F;" ><!--SOLIDUS -->
-<!ENTITY sung "&#x0266A;" ><!--EIGHTH NOTE -->
-<!ENTITY sup1 "&#x000B9;" ><!--SUPERSCRIPT ONE -->
-<!ENTITY sup2 "&#x000B2;" ><!--SUPERSCRIPT TWO -->
-<!ENTITY sup3 "&#x000B3;" ><!--SUPERSCRIPT THREE -->
-<!ENTITY times "&#x000D7;" ><!--MULTIPLICATION SIGN -->
-<!ENTITY trade "&#x02122;" ><!--TRADE MARK SIGN -->
-<!ENTITY uarr "&#x02191;" ><!--UPWARDS ARROW -->
-<!ENTITY verbar "&#x0007C;" ><!--VERTICAL LINE -->
-<!ENTITY yen "&#x000A5;" ><!--YEN SIGN -->
diff --git a/Utilities/xml/docbook-4.5/ent/isopub.ent b/Utilities/xml/docbook-4.5/ent/isopub.ent
deleted file mode 100644
index a11787828..000000000
--- a/Utilities/xml/docbook-4.5/ent/isopub.ent
+++ /dev/null
@@ -1,125 +0,0 @@
-
-<!--
- File isopub.ent produced by the XSL script entities.xsl
- from input data in unicode.xml.
-
- Please report any errors to David Carlisle
- via the public W3C list www-math@w3.org.
-
- The numeric character values assigned to each entity
- (should) match the Unicode assignments in Unicode 4.0.
-
- Entity names in this file are derived from files carrying the
- following notice:
-
- (C) International Organization for Standardization 1986
- Permission to copy in any form is granted for use with
- conforming SGML systems and applications as defined in
- ISO 8879, provided this notice is included in all copies.
-
--->
-
-
-<!--
- Version: $Id: isopub.ent,v 1.2 2003/12/08 15:14:43 davidc Exp $
-
- Public identifier: ISO 8879:1986//ENTITIES Publishing//EN//XML
- System identifier: http://www.w3.org/2003/entities/iso8879/isopub.ent
-
- The public identifier should always be used verbatim.
- The system identifier may be changed to suit local requirements.
-
- Typical invocation:
-
- <!ENTITY % isopub PUBLIC
- "ISO 8879:1986//ENTITIES Publishing//EN//XML"
- "http://www.w3.org/2003/entities/iso8879/isopub.ent"
- >
- %isopub;
-
--->
-
-<!ENTITY blank "&#x02423;" ><!--OPEN BOX -->
-<!ENTITY blk12 "&#x02592;" ><!--MEDIUM SHADE -->
-<!ENTITY blk14 "&#x02591;" ><!--LIGHT SHADE -->
-<!ENTITY blk34 "&#x02593;" ><!--DARK SHADE -->
-<!ENTITY block "&#x02588;" ><!--FULL BLOCK -->
-<!ENTITY bull "&#x02022;" ><!--BULLET -->
-<!ENTITY caret "&#x02041;" ><!--CARET INSERTION POINT -->
-<!ENTITY check "&#x02713;" ><!--CHECK MARK -->
-<!ENTITY cir "&#x025CB;" ><!--WHITE CIRCLE -->
-<!ENTITY clubs "&#x02663;" ><!--BLACK CLUB SUIT -->
-<!ENTITY copysr "&#x02117;" ><!--SOUND RECORDING COPYRIGHT -->
-<!ENTITY cross "&#x02717;" ><!--BALLOT X -->
-<!ENTITY Dagger "&#x02021;" ><!--DOUBLE DAGGER -->
-<!ENTITY dagger "&#x02020;" ><!--DAGGER -->
-<!ENTITY dash "&#x02010;" ><!--HYPHEN -->
-<!ENTITY diams "&#x02666;" ><!--BLACK DIAMOND SUIT -->
-<!ENTITY dlcrop "&#x0230D;" ><!--BOTTOM LEFT CROP -->
-<!ENTITY drcrop "&#x0230C;" ><!--BOTTOM RIGHT CROP -->
-<!ENTITY dtri "&#x025BF;" ><!--WHITE DOWN-POINTING SMALL TRIANGLE -->
-<!ENTITY dtrif "&#x025BE;" ><!--BLACK DOWN-POINTING SMALL TRIANGLE -->
-<!ENTITY emsp "&#x02003;" ><!--EM SPACE -->
-<!ENTITY emsp13 "&#x02004;" ><!--THREE-PER-EM SPACE -->
-<!ENTITY emsp14 "&#x02005;" ><!--FOUR-PER-EM SPACE -->
-<!ENTITY ensp "&#x02002;" ><!--EN SPACE -->
-<!ENTITY female "&#x02640;" ><!--FEMALE SIGN -->
-<!ENTITY ffilig "&#x0FB03;" ><!--LATIN SMALL LIGATURE FFI -->
-<!ENTITY fflig "&#x0FB00;" ><!--LATIN SMALL LIGATURE FF -->
-<!ENTITY ffllig "&#x0FB04;" ><!--LATIN SMALL LIGATURE FFL -->
-<!ENTITY filig "&#x0FB01;" ><!--LATIN SMALL LIGATURE FI -->
-<!ENTITY flat "&#x0266D;" ><!--MUSIC FLAT SIGN -->
-<!ENTITY fllig "&#x0FB02;" ><!--LATIN SMALL LIGATURE FL -->
-<!ENTITY frac13 "&#x02153;" ><!--VULGAR FRACTION ONE THIRD -->
-<!ENTITY frac15 "&#x02155;" ><!--VULGAR FRACTION ONE FIFTH -->
-<!ENTITY frac16 "&#x02159;" ><!--VULGAR FRACTION ONE SIXTH -->
-<!ENTITY frac23 "&#x02154;" ><!--VULGAR FRACTION TWO THIRDS -->
-<!ENTITY frac25 "&#x02156;" ><!--VULGAR FRACTION TWO FIFTHS -->
-<!ENTITY frac35 "&#x02157;" ><!--VULGAR FRACTION THREE FIFTHS -->
-<!ENTITY frac45 "&#x02158;" ><!--VULGAR FRACTION FOUR FIFTHS -->
-<!ENTITY frac56 "&#x0215A;" ><!--VULGAR FRACTION FIVE SIXTHS -->
-<!ENTITY hairsp "&#x0200A;" ><!--HAIR SPACE -->
-<!ENTITY hearts "&#x02665;" ><!--BLACK HEART SUIT -->
-<!ENTITY hellip "&#x02026;" ><!--HORIZONTAL ELLIPSIS -->
-<!ENTITY hybull "&#x02043;" ><!--HYPHEN BULLET -->
-<!ENTITY incare "&#x02105;" ><!--CARE OF -->
-<!ENTITY ldquor "&#x0201E;" ><!--DOUBLE LOW-9 QUOTATION MARK -->
-<!ENTITY lhblk "&#x02584;" ><!--LOWER HALF BLOCK -->
-<!ENTITY loz "&#x025CA;" ><!--LOZENGE -->
-<!ENTITY lozf "&#x029EB;" ><!--BLACK LOZENGE -->
-<!ENTITY lsquor "&#x0201A;" ><!--SINGLE LOW-9 QUOTATION MARK -->
-<!ENTITY ltri "&#x025C3;" ><!--WHITE LEFT-POINTING SMALL TRIANGLE -->
-<!ENTITY ltrif "&#x025C2;" ><!--BLACK LEFT-POINTING SMALL TRIANGLE -->
-<!ENTITY male "&#x02642;" ><!--MALE SIGN -->
-<!ENTITY malt "&#x02720;" ><!--MALTESE CROSS -->
-<!ENTITY marker "&#x025AE;" ><!--BLACK VERTICAL RECTANGLE -->
-<!ENTITY mdash "&#x02014;" ><!--EM DASH -->
-<!ENTITY mldr "&#x02026;" ><!--HORIZONTAL ELLIPSIS -->
-<!ENTITY natur "&#x0266E;" ><!--MUSIC NATURAL SIGN -->
-<!ENTITY ndash "&#x02013;" ><!--EN DASH -->
-<!ENTITY nldr "&#x02025;" ><!--TWO DOT LEADER -->
-<!ENTITY numsp "&#x02007;" ><!--FIGURE SPACE -->
-<!ENTITY phone "&#x0260E;" ><!--BLACK TELEPHONE -->
-<!ENTITY puncsp "&#x02008;" ><!--PUNCTUATION SPACE -->
-<!ENTITY rdquor "&#x0201D;" ><!--RIGHT DOUBLE QUOTATION MARK -->
-<!ENTITY rect "&#x025AD;" ><!--WHITE RECTANGLE -->
-<!ENTITY rsquor "&#x02019;" ><!--RIGHT SINGLE QUOTATION MARK -->
-<!ENTITY rtri "&#x025B9;" ><!--WHITE RIGHT-POINTING SMALL TRIANGLE -->
-<!ENTITY rtrif "&#x025B8;" ><!--BLACK RIGHT-POINTING SMALL TRIANGLE -->
-<!ENTITY rx "&#x0211E;" ><!--PRESCRIPTION TAKE -->
-<!ENTITY sext "&#x02736;" ><!--SIX POINTED BLACK STAR -->
-<!ENTITY sharp "&#x0266F;" ><!--MUSIC SHARP SIGN -->
-<!ENTITY spades "&#x02660;" ><!--BLACK SPADE SUIT -->
-<!ENTITY squ "&#x025A1;" ><!--WHITE SQUARE -->
-<!ENTITY squf "&#x025AA;" ><!--BLACK SMALL SQUARE -->
-<!ENTITY star "&#x02606;" ><!--WHITE STAR -->
-<!ENTITY starf "&#x02605;" ><!--BLACK STAR -->
-<!ENTITY target "&#x02316;" ><!--POSITION INDICATOR -->
-<!ENTITY telrec "&#x02315;" ><!--TELEPHONE RECORDER -->
-<!ENTITY thinsp "&#x02009;" ><!--THIN SPACE -->
-<!ENTITY uhblk "&#x02580;" ><!--UPPER HALF BLOCK -->
-<!ENTITY ulcrop "&#x0230F;" ><!--TOP LEFT CROP -->
-<!ENTITY urcrop "&#x0230E;" ><!--TOP RIGHT CROP -->
-<!ENTITY utri "&#x025B5;" ><!--WHITE UP-POINTING SMALL TRIANGLE -->
-<!ENTITY utrif "&#x025B4;" ><!--BLACK UP-POINTING SMALL TRIANGLE -->
-<!ENTITY vellip "&#x022EE;" ><!--VERTICAL ELLIPSIS -->
diff --git a/Utilities/xml/docbook-4.5/ent/isotech.ent b/Utilities/xml/docbook-4.5/ent/isotech.ent
deleted file mode 100644
index 07e81008d..000000000
--- a/Utilities/xml/docbook-4.5/ent/isotech.ent
+++ /dev/null
@@ -1,103 +0,0 @@
-
-<!--
- File isotech.ent produced by the XSL script entities.xsl
- from input data in unicode.xml.
-
- Please report any errors to David Carlisle
- via the public W3C list www-math@w3.org.
-
- The numeric character values assigned to each entity
- (should) match the Unicode assignments in Unicode 4.0.
-
- Entity names in this file are derived from files carrying the
- following notice:
-
- (C) International Organization for Standardization 1986
- Permission to copy in any form is granted for use with
- conforming SGML systems and applications as defined in
- ISO 8879, provided this notice is included in all copies.
-
--->
-
-
-<!--
- Version: $Id: isotech.ent,v 1.2 2003/12/08 15:14:43 davidc Exp $
-
- Public identifier: ISO 8879:1986//ENTITIES General Technical//EN//XML
- System identifier: http://www.w3.org/2003/entities/iso8879/isotech.ent
-
- The public identifier should always be used verbatim.
- The system identifier may be changed to suit local requirements.
-
- Typical invocation:
-
- <!ENTITY % isotech PUBLIC
- "ISO 8879:1986//ENTITIES General Technical//EN//XML"
- "http://www.w3.org/2003/entities/iso8879/isotech.ent"
- >
- %isotech;
-
--->
-
-<!ENTITY aleph "&#x02135;" ><!--ALEF SYMBOL -->
-<!ENTITY and "&#x02227;" ><!--LOGICAL AND -->
-<!ENTITY ang90 "&#x0221F;" ><!--RIGHT ANGLE -->
-<!ENTITY angsph "&#x02222;" ><!--SPHERICAL ANGLE -->
-<!ENTITY angst "&#x0212B;" ><!--ANGSTROM SIGN -->
-<!ENTITY ap "&#x02248;" ><!--ALMOST EQUAL TO -->
-<!ENTITY becaus "&#x02235;" ><!--BECAUSE -->
-<!ENTITY bernou "&#x0212C;" ><!--SCRIPT CAPITAL B -->
-<!ENTITY bottom "&#x022A5;" ><!--UP TACK -->
-<!ENTITY cap "&#x02229;" ><!--INTERSECTION -->
-<!ENTITY compfn "&#x02218;" ><!--RING OPERATOR -->
-<!ENTITY cong "&#x02245;" ><!--APPROXIMATELY EQUAL TO -->
-<!ENTITY conint "&#x0222E;" ><!--CONTOUR INTEGRAL -->
-<!ENTITY cup "&#x0222A;" ><!--UNION -->
-<!ENTITY Dot "&#x000A8;" ><!--DIAERESIS -->
-<!ENTITY DotDot " &#x020DC;" ><!--COMBINING FOUR DOTS ABOVE -->
-<!ENTITY equiv "&#x02261;" ><!--IDENTICAL TO -->
-<!ENTITY exist "&#x02203;" ><!--THERE EXISTS -->
-<!ENTITY fnof "&#x00192;" ><!--LATIN SMALL LETTER F WITH HOOK -->
-<!ENTITY forall "&#x02200;" ><!--FOR ALL -->
-<!ENTITY ge "&#x02265;" ><!--GREATER-THAN OR EQUAL TO -->
-<!ENTITY hamilt "&#x0210B;" ><!--SCRIPT CAPITAL H -->
-<!ENTITY iff "&#x021D4;" ><!--LEFT RIGHT DOUBLE ARROW -->
-<!ENTITY infin "&#x0221E;" ><!--INFINITY -->
-<!ENTITY int "&#x0222B;" ><!--INTEGRAL -->
-<!ENTITY isin "&#x02208;" ><!--ELEMENT OF -->
-<!ENTITY lagran "&#x02112;" ><!--SCRIPT CAPITAL L -->
-<!ENTITY lang "&#x02329;" ><!--LEFT-POINTING ANGLE BRACKET -->
-<!ENTITY lArr "&#x021D0;" ><!--LEFTWARDS DOUBLE ARROW -->
-<!ENTITY le "&#x02264;" ><!--LESS-THAN OR EQUAL TO -->
-<!ENTITY lowast "&#x02217;" ><!--ASTERISK OPERATOR -->
-<!ENTITY minus "&#x02212;" ><!--MINUS SIGN -->
-<!ENTITY mnplus "&#x02213;" ><!--MINUS-OR-PLUS SIGN -->
-<!ENTITY nabla "&#x02207;" ><!--NABLA -->
-<!ENTITY ne "&#x02260;" ><!--NOT EQUAL TO -->
-<!ENTITY ni "&#x0220B;" ><!--CONTAINS AS MEMBER -->
-<!ENTITY notin "&#x02209;" ><!--NOT AN ELEMENT OF -->
-<!ENTITY or "&#x02228;" ><!--LOGICAL OR -->
-<!ENTITY order "&#x02134;" ><!--SCRIPT SMALL O -->
-<!ENTITY par "&#x02225;" ><!--PARALLEL TO -->
-<!ENTITY part "&#x02202;" ><!--PARTIAL DIFFERENTIAL -->
-<!ENTITY permil "&#x02030;" ><!--PER MILLE SIGN -->
-<!ENTITY perp "&#x022A5;" ><!--UP TACK -->
-<!ENTITY phmmat "&#x02133;" ><!--SCRIPT CAPITAL M -->
-<!ENTITY Prime "&#x02033;" ><!--DOUBLE PRIME -->
-<!ENTITY prime "&#x02032;" ><!--PRIME -->
-<!ENTITY prop "&#x0221D;" ><!--PROPORTIONAL TO -->
-<!ENTITY radic "&#x0221A;" ><!--SQUARE ROOT -->
-<!ENTITY rang "&#x0232A;" ><!--RIGHT-POINTING ANGLE BRACKET -->
-<!ENTITY rArr "&#x021D2;" ><!--RIGHTWARDS DOUBLE ARROW -->
-<!ENTITY sim "&#x0223C;" ><!--TILDE OPERATOR -->
-<!ENTITY sime "&#x02243;" ><!--ASYMPTOTICALLY EQUAL TO -->
-<!ENTITY square "&#x025A1;" ><!--WHITE SQUARE -->
-<!ENTITY sub "&#x02282;" ><!--SUBSET OF -->
-<!ENTITY sube "&#x02286;" ><!--SUBSET OF OR EQUAL TO -->
-<!ENTITY sup "&#x02283;" ><!--SUPERSET OF -->
-<!ENTITY supe "&#x02287;" ><!--SUPERSET OF OR EQUAL TO -->
-<!ENTITY tdot " &#x020DB;" ><!--COMBINING THREE DOTS ABOVE -->
-<!ENTITY there4 "&#x02234;" ><!--THEREFORE -->
-<!ENTITY tprime "&#x02034;" ><!--TRIPLE PRIME -->
-<!ENTITY Verbar "&#x02016;" ><!--DOUBLE VERTICAL LINE -->
-<!ENTITY wedgeq "&#x02259;" ><!--ESTIMATES -->
diff --git a/Utilities/xml/docbook-4.5/htmltblx.mod b/Utilities/xml/docbook-4.5/htmltblx.mod
deleted file mode 100644
index cdaefed41..000000000
--- a/Utilities/xml/docbook-4.5/htmltblx.mod
+++ /dev/null
@@ -1,245 +0,0 @@
-<!-- ...................................................................... -->
-<!-- DocBook XML HTML Table Module V4.5 ................................... -->
-<!-- File htmltblx.mod .................................................... -->
-
-<!-- Copyright 2003-2006 ArborText, Inc., Norman Walsh, Sun Microsystems,
- Inc., and the Organization for the Advancement of Structured Information
- Standards (OASIS).
-
- $Id: htmltblx.mod 6340 2006-10-03 13:23:24Z nwalsh $
-
- Permission to use, copy, modify and distribute the DocBook XML DTD
- and its accompanying documentation for any purpose and without fee
- is hereby granted in perpetuity, provided that the above copyright
- notice and this paragraph appear in all copies. The copyright
- holders make no representation about the suitability of the DTD for
- any purpose. It is provided "as is" without expressed or implied
- warranty.
-
- If you modify the DocBook XML DTD in any way, except for declaring and
- referencing additional sets of general entities and declaring
- additional notations, label your DTD as a variant of DocBook. See
- the maintenance documentation for more information.
-
- Please direct all questions, bug reports, or suggestions for
- changes to the docbook@lists.oasis-open.org mailing list. For more
- information, see http://www.oasis-open.org/docbook/.
--->
-
-<!-- ...................................................................... -->
-
-<!-- This module contains the definitions for elements that are
- isomorphic to the HTML elements. One could argue we should
- instead have based ourselves on the XHTML Table Module, but the
- HTML one is more like what browsers are likely to accept today
- and users are likely to use.
-
- This module has been developed for use with the DocBook V4.5
- "union table model" in which elements and attlists common to both
- models are defined (as the union) in the CALS table module by
- setting various parameter entities appropriately in this file.
-
- In DTD driver files referring to this module, please use an entity
- declaration that uses the public identifier shown below:
-
- <!ENTITY % htmltbl PUBLIC
- "-//OASIS//ELEMENTS DocBook XML HTML Tables V4.5//EN"
- "htmltblx.mod">
- %htmltbl;
-
- See the documentation for detailed information on the parameter
- entity and module scheme used in DocBook, customizing DocBook and
- planning for interchange, and changes made since the last release
- of DocBook.
--->
-
-<!--======================= XHTML Tables =======================================-->
-
-<!ENTITY % html.coreattrs
- "%common.attrib;
- class CDATA #IMPLIED
- style CDATA #IMPLIED
- title CDATA #IMPLIED"
- >
-
-<!-- Does not contain lang or dir because they are in %common.attribs -->
-<![%sgml.features;[
-<!ENTITY % i18n "">
-]]>
-<!ENTITY % i18n
- "xml:lang NMTOKEN #IMPLIED"
- >
-
-<!ENTITY % events
- "onclick CDATA #IMPLIED
- ondblclick CDATA #IMPLIED
- onmousedown CDATA #IMPLIED
- onmouseup CDATA #IMPLIED
- onmouseover CDATA #IMPLIED
- onmousemove CDATA #IMPLIED
- onmouseout CDATA #IMPLIED
- onkeypress CDATA #IMPLIED
- onkeydown CDATA #IMPLIED
- onkeyup CDATA #IMPLIED"
- >
-
-<!ENTITY % attrs "%html.coreattrs; %i18n; %events;">
-
-<!ENTITY % cellhalign
- "align (left|center|right|justify|char) #IMPLIED
- char CDATA #IMPLIED
- charoff CDATA #IMPLIED"
- >
-
-<!ENTITY % cellvalign
- "valign (top|middle|bottom|baseline) #IMPLIED"
- >
-
-<!--doc:A group of columns in an HTML table.-->
-<!ELEMENT colgroup %ho; (col)*>
-<!--doc:Specifications for a column in an HTML table.-->
-<!ELEMENT col %ho; EMPTY>
-<!--doc:A row in an HTML table.-->
-<!ELEMENT tr %ho; (th|td)+>
-<!--doc:A table header entry in an HTML table.-->
-<!ELEMENT th %ho; (%para.char.mix; | %tabentry.mix; | table | informaltable)*>
-<!--doc:A table ntry in an HTML table.-->
-<!ELEMENT td %ho; (%para.char.mix; | %tabentry.mix; | table | informaltable)*>
-
-<!ATTLIST colgroup
- %attrs;
- span CDATA "1"
- width CDATA #IMPLIED
- %cellhalign;
- %cellvalign;
- >
-
-<!ATTLIST col
- %attrs;
- span CDATA "1"
- width CDATA #IMPLIED
- %cellhalign;
- %cellvalign;
- >
-
-<!ATTLIST tr
- %attrs;
- %cellhalign;
- %cellvalign;
- bgcolor CDATA #IMPLIED
- >
-
-<!ATTLIST th
- %attrs;
- abbr CDATA #IMPLIED
- axis CDATA #IMPLIED
- headers IDREFS #IMPLIED
- scope (row|col|rowgroup|colgroup) #IMPLIED
- rowspan CDATA "1"
- colspan CDATA "1"
- %cellhalign;
- %cellvalign;
- nowrap (nowrap) #IMPLIED
- bgcolor CDATA #IMPLIED
- width CDATA #IMPLIED
- height CDATA #IMPLIED
- >
-
-<!ATTLIST td
- %attrs;
- abbr CDATA #IMPLIED
- axis CDATA #IMPLIED
- headers IDREFS #IMPLIED
- scope (row|col|rowgroup|colgroup) #IMPLIED
- rowspan CDATA "1"
- colspan CDATA "1"
- %cellhalign;
- %cellvalign;
- nowrap (nowrap) #IMPLIED
- bgcolor CDATA #IMPLIED
- width CDATA #IMPLIED
- height CDATA #IMPLIED
- >
-
-<!-- ====================================================== -->
-<!-- Set up to read in the CALS model configured to
- merge with the XHTML table model -->
-<!-- ====================================================== -->
-
-<!ENTITY % tables.role.attrib "%role.attrib;">
-
-<!-- Add label and role attributes to table and informaltable -->
-<!ENTITY % bodyatt "
- floatstyle CDATA #IMPLIED
- rowheader (firstcol|norowheader) #IMPLIED
- %label.attrib;"
->
-
-<!-- Add common attributes to Table, TGroup, TBody, THead, TFoot, Row,
- EntryTbl, and Entry (and InformalTable element). -->
-
-<!ENTITY % secur "
- %common.attrib;
- class CDATA #IMPLIED
- style CDATA #IMPLIED
- title CDATA #IMPLIED
- %i18n;
- %events;
- %tables.role.attrib;">
-
-<!ENTITY % common.table.attribs
- "%bodyatt;
- %secur;">
-
-<!-- Content model for Table (that also allows HTML tables) -->
-<!ENTITY % tbl.table.mdl
- "((blockinfo?,
- (%formalobject.title.content;),
- (%ndxterm.class;)*,
- textobject*,
- (graphic+|mediaobject+|tgroup+))
- |(caption, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+)))">
-
-<!ENTITY % informal.tbl.table.mdl
- "(textobject*,
- (graphic+|mediaobject+|tgroup+))
- | ((col*|colgroup*), thead?, tfoot?, (tbody+|tr+))">
-
-<!-- Attributes for Table (including HTML ones) -->
-
-<!-- N.B. rules = (none | groups | rows | cols | all) but it can't be spec'd -->
-<!-- that way because 'all' already occurs in a different enumeration in -->
-<!-- CALS tables (frame). -->
-
-<!ENTITY % tbl.table.att '
- tabstyle CDATA #IMPLIED
- tocentry %yesorno.attvals; #IMPLIED
- shortentry %yesorno.attvals; #IMPLIED
- orient (port|land) #IMPLIED
- pgwide %yesorno.attvals; #IMPLIED
- summary CDATA #IMPLIED
- width CDATA #IMPLIED
- border CDATA #IMPLIED
- rules CDATA #IMPLIED
- cellspacing CDATA #IMPLIED
- cellpadding CDATA #IMPLIED
- align (left|center|right) #IMPLIED
- bgcolor CDATA #IMPLIED
-'>
-
-<!ENTITY % tbl.frame.attval "void|above|below|hsides|lhs|rhs|vsides|box|border|
-top|bottom|topbot|all|sides|none">
-
-<!-- Allow either objects or inlines; beware of REs between elements. -->
-<!ENTITY % tbl.entry.mdl "%para.char.mix; | %tabentry.mix;">
-
-<!-- thead, tfoot, and tbody are defined in both table models,
- so we set up parameter entities to define union models for them
- -->
-
-<!ENTITY % tbl.hdft.mdl "(tr+|(colspec*,row+))">
-<!ENTITY % tbl.tbody.mdl "(tr+|row+)">
-<!ENTITY % tbl.valign.attval "top|middle|bottom|baseline">
-
-<!-- End of DocBook XML HTML Table Module V4.5 ............................ -->
-<!-- ...................................................................... -->
diff --git a/Utilities/xml/docbook-4.5/soextblx.dtd b/Utilities/xml/docbook-4.5/soextblx.dtd
deleted file mode 100644
index 4a92e1162..000000000
--- a/Utilities/xml/docbook-4.5/soextblx.dtd
+++ /dev/null
@@ -1,321 +0,0 @@
-<!-- XML EXCHANGE TABLE MODEL DECLARATION MODULE -->
-
-<!-- This set of declarations defines the XML version of the Exchange
- Table Model as of the date shown in the Formal Public Identifier
- (FPI) for this entity.
-
- This set of declarations may be referred to using a public external
- entity declaration and reference as shown in the following three
- lines:
-
- <!ENTITY % calstblx
- PUBLIC "-//OASIS//DTD XML Exchange Table Model 19990315//EN">
- %calstblx;
-
- If various parameter entities used within this set of declarations
- are to be given non-default values, the appropriate declarations
- should be given before calling in this package (i.e., before the
- "%calstblx;" reference).
--->
-
-<!-- The motivation for this XML version of the Exchange Table Model
- is simply to create an XML version of the SGML Exchange Table
- Model. By design, no effort has been made to "improve" the model.
-
- This XML version incorporates the logical bare minimum changes
- necessary to make the Exchange Table Model a valid XML DTD.
-
- It has been modified slightly for use in the combined HTML/CALS models
- supported by DocBook V4.3 and later.
--->
-
-<!-- The XML version of the Exchange Table Model differs from
- the SGML version in the following ways:
-
- The following parameter entities have been removed:
-
- - tbl.table.excep, tbl.hdft.excep, tbl.row.excep, tbl.entry.excep
- There are no exceptions in XML. The following normative statement
- is made in lieu of exceptions: the exchange table model explicitly
- forbids a table from occurring within another table. If the
- content model of an entry includes a table element, then this
- cannot be enforced by the DTD, but it is a deviation from the
- exchange table model to include a table within a table.
-
- - tbl.hdft.name, tbl.hdft.mdl, tbl.hdft.excep, tbl.hdft.att
- The motivation for these elements was to change the table
- header/footer elements. Since XML does not allow element declarations
- to contain name groups, and the exchange table model does not
- allow a table to contain footers, the continued presence of these
- attributes seems unnecessary.
-
- The following parameter entity has been added:
-
- - tbl.thead.att
- This entity parameterizes the attributes on thead. It replaces
- the tbl.hdft.att parameter entity.
-
- Other miscellaneous changes:
-
- - Tag ommission indicators have been removed
- - Comments have been removed from declarations
- - NUMBER attributes have been changed to NMTOKEN
- - NUTOKEN attributes have been to changed to NMTOKEN
- - Removed the grouping characters around the content model
- parameter entry for the 'entry' element. This is necessary
- so that an entry can contain #PCDATA and be defined as an
- optional, repeatable OR group beginning with #PCDATA.
--->
-
-<!-- This entity includes a set of element and attribute declarations
- that partially defines the Exchange table model. However, the model
- is not well-defined without the accompanying natural language
- description of the semantics (meanings) of these various elements,
- attributes, and attribute values. The semantic writeup, also available
- from SGML Open, should be used in conjunction with this entity.
--->
-
-<!-- In order to use the Exchange table model, various parameter entity
- declarations are required. A brief description is as follows:
-
- ENTITY NAME WHERE USED WHAT IT IS
-
- %yesorno In ATTLIST of: An attribute declared value
- almost all elements for a "boolean" attribute
-
- %paracon In content model of: The "text" (logical content)
- <entry> of the model group for <entry>
-
- %titles In content model of: The "title" part of the model
- table element group for the table element
-
- %tbl.table.name In declaration of: The name of the "table"
- table element element
-
- %tbl.table-titles.mdl In content model of: The model group for the title
- table elements part of the content model for
- table element
-
- %tbl.table.mdl In content model of: The model group for the content
- table elements model for table element,
- often (and by default) defined
- in terms of %tbl.table-titles.mdl
- and tgroup
-
- %tbl.table.att In ATTLIST of: Additional attributes on the
- table element table element
-
- %bodyatt In ATTLIST of: Additional attributes on the
- table element table element (for backward
- compatibility with the SGML
- model)
-
- %tbl.tgroup.mdl In content model of: The model group for the content
- <tgroup> model for <tgroup>
-
- %tbl.tgroup.att In ATTLIST of: Additional attributes on the
- <tgroup> <tgroup> element
-
- %tbl.thead.att In ATTLIST of: Additional attributes on the
- <thead> <thead> element
-
- %tbl.tbody.att In ATTLIST of: Additional attributes on the
- <tbody> <tbody> element
-
- %tbl.colspec.att In ATTLIST of: Additional attributes on the
- <colspec> <colspec> element
-
- %tbl.row.mdl In content model of: The model group for the content
- <row> model for <row>
-
- %tbl.row.att In ATTLIST of: Additional attributes on the
- <row> <row> element
-
- %tbl.entry.mdl In content model of: The model group for the content
- <entry> model for <entry>
-
- %tbl.entry.att In ATTLIST of: Additional attributes on the
- <entry> <entry> element
-
- This set of declarations will use the default definitions shown below
- for any of these parameter entities that are not declared before this
- set of declarations is referenced.
--->
-
-<!-- These definitions are not directly related to the table model, but are
- used in the default CALS table model and may be defined elsewhere (and
- prior to the inclusion of this table module) in the referencing DTD. -->
-
-<!ENTITY % yesorno 'NMTOKEN'> <!-- no if zero(s), yes if any other value -->
-<!ENTITY % titles 'title?'>
-<!ENTITY % pcd "#PCDATA">
-<!ENTITY % paracon '%pcd;'> <!-- default for use in entry content -->
-
-<!--
-The parameter entities as defined below change and simplify the CALS table
-model as published (as part of the Example DTD) in MIL-HDBK-28001. The
-resulting simplified DTD has support from the SGML Open vendors and is
-therefore more interoperable among different systems.
-
-These following declarations provide the Exchange default definitions
-for these entities. However, these entities can be redefined (by giving
-the appropriate parameter entity declaration(s) prior to the reference
-to this Table Model declaration set entity) to fit the needs of the
-current application.
-
-Note, however, that changes may have significant effect on the ability to
-interchange table information. These changes may manifest themselves
-in useability, presentation, and possible structure information degradation.
--->
-
-<!ENTITY % tbl.table.name "table">
-<!ENTITY % tbl.table-titles.mdl "%titles;,">
-<!ENTITY % tbl.table-main.mdl "tgroup+">
-<!ENTITY % tbl.table.mdl "%tbl.table-titles.mdl; %tbl.table-main.mdl;">
-<!ENTITY % tbl.table.att "
- pgwide %yesorno; #IMPLIED ">
-<!ENTITY % bodyatt "">
-<!ENTITY % tbl.tgroup.mdl "colspec*,thead?,tbody">
-<!ENTITY % tbl.tgroup.att "">
-<!ENTITY % tbl.thead.att "">
-<!ENTITY % tbl.tbody.att "">
-<!ENTITY % tbl.colspec.att "">
-<!ENTITY % tbl.row.mdl "entry+">
-<!ENTITY % tbl.row.att "">
-<!ENTITY % tbl.entry.mdl "(%paracon;)*">
-<!ENTITY % tbl.entry.att "">
-
-<!ENTITY % tbl.frame.attval "top|bottom|topbot|all|sides|none">
-<!ENTITY % tbl.tbody.mdl "row+">
-
-<!-- ===== Element and attribute declarations follow. ===== -->
-
-<!--
- Default declarations previously defined in this entity and
- referenced below include:
- ENTITY % tbl.table.name "table"
- ENTITY % tbl.table-titles.mdl "%titles;,"
- ENTITY % tbl.table.mdl "%tbl.table-titles; tgroup+"
- ENTITY % tbl.table.att "
- pgwide %yesorno; #IMPLIED "
--->
-
-<!--doc:???-->
-<!ELEMENT %tbl.table.name; (%tbl.table.mdl;)>
-
-<!ATTLIST %tbl.table.name;
- frame (%tbl.frame.attval;) #IMPLIED
- colsep %yesorno; #IMPLIED
- rowsep %yesorno; #IMPLIED
- %tbl.table.att;
- %bodyatt;
->
-
-<!--
- Default declarations previously defined in this entity and
- referenced below include:
- ENTITY % tbl.tgroup.mdl "colspec*,thead?,tbody"
- ENTITY % tbl.tgroup.att ""
--->
-
-<!--doc:A wrapper for the main content of a table, or part of a table.-->
-<!ELEMENT tgroup (%tbl.tgroup.mdl;) >
-
-<!ATTLIST tgroup
- cols NMTOKEN #REQUIRED
- colsep %yesorno; #IMPLIED
- rowsep %yesorno; #IMPLIED
- align (left|right|center|justify|char) #IMPLIED
- %tbl.tgroup.att;
->
-
-<!--
- Default declarations previously defined in this entity and
- referenced below include:
- ENTITY % tbl.colspec.att ""
--->
-
-<!--doc:Specifications for a column in a table.-->
-<!ELEMENT colspec EMPTY >
-
-<!ATTLIST colspec
- colnum NMTOKEN #IMPLIED
- colname NMTOKEN #IMPLIED
- colwidth CDATA #IMPLIED
- colsep %yesorno; #IMPLIED
- rowsep %yesorno; #IMPLIED
- align (left|right|center|justify|char) #IMPLIED
- char CDATA #IMPLIED
- charoff NMTOKEN #IMPLIED
- %tbl.colspec.att;
->
-
-<!--
- Default declarations previously defined in this entity and
- referenced below include:
- ENTITY % tbl.thead.att ""
--->
-
-<!--doc:A table header consisting of one or more rows.-->
-<!ELEMENT thead (row+)>
-
-<!ATTLIST thead
- valign (top|middle|bottom) #IMPLIED
- %tbl.thead.att;
->
-
-<!--
- Default declarations previously defined in this entity and
- referenced below include:
- ENTITY % tbl.tbody.att ""
--->
-
-<!--doc:A wrapper for the rows of a table or informal table.-->
-<!ELEMENT tbody (%tbl.tbody.mdl;)>
-
-<!ATTLIST tbody
- valign (top|middle|bottom) #IMPLIED
- %tbl.tbody.att;
->
-
-<!--
- Default declarations previously defined in this entity and
- referenced below include:
- ENTITY % tbl.row.mdl "entry+"
- ENTITY % tbl.row.att ""
--->
-
-<!--doc:A row in a table.-->
-<!ELEMENT row (%tbl.row.mdl;)>
-
-<!ATTLIST row
- rowsep %yesorno; #IMPLIED
- valign (top|middle|bottom) #IMPLIED
- %tbl.row.att;
->
-
-
-<!--
- Default declarations previously defined in this entity and
- referenced below include:
- ENTITY % paracon "#PCDATA"
- ENTITY % tbl.entry.mdl "(%paracon;)*"
- ENTITY % tbl.entry.att ""
--->
-
-<!--doc:A cell in a table.-->
-<!ELEMENT entry (%tbl.entry.mdl;)*>
-
-<!ATTLIST entry
- colname NMTOKEN #IMPLIED
- namest NMTOKEN #IMPLIED
- nameend NMTOKEN #IMPLIED
- morerows NMTOKEN #IMPLIED
- colsep %yesorno; #IMPLIED
- rowsep %yesorno; #IMPLIED
- align (left|right|center|justify|char) #IMPLIED
- char CDATA #IMPLIED
- charoff NMTOKEN #IMPLIED
- valign (top|middle|bottom) #IMPLIED
- %tbl.entry.att;
->
diff --git a/Utilities/xml/xhtml1/xhtml-lat1.ent b/Utilities/xml/xhtml1/xhtml-lat1.ent
deleted file mode 100644
index ffee223eb..000000000
--- a/Utilities/xml/xhtml1/xhtml-lat1.ent
+++ /dev/null
@@ -1,196 +0,0 @@
-<!-- Portions (C) International Organization for Standardization 1986
- Permission to copy in any form is granted for use with
- conforming SGML systems and applications as defined in
- ISO 8879, provided this notice is included in all copies.
--->
-<!-- Character entity set. Typical invocation:
- <!ENTITY % HTMLlat1 PUBLIC
- "-//W3C//ENTITIES Latin 1 for XHTML//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent">
- %HTMLlat1;
--->
-
-<!ENTITY nbsp "&#160;"> <!-- no-break space = non-breaking space,
- U+00A0 ISOnum -->
-<!ENTITY iexcl "&#161;"> <!-- inverted exclamation mark, U+00A1 ISOnum -->
-<!ENTITY cent "&#162;"> <!-- cent sign, U+00A2 ISOnum -->
-<!ENTITY pound "&#163;"> <!-- pound sign, U+00A3 ISOnum -->
-<!ENTITY curren "&#164;"> <!-- currency sign, U+00A4 ISOnum -->
-<!ENTITY yen "&#165;"> <!-- yen sign = yuan sign, U+00A5 ISOnum -->
-<!ENTITY brvbar "&#166;"> <!-- broken bar = broken vertical bar,
- U+00A6 ISOnum -->
-<!ENTITY sect "&#167;"> <!-- section sign, U+00A7 ISOnum -->
-<!ENTITY uml "&#168;"> <!-- diaeresis = spacing diaeresis,
- U+00A8 ISOdia -->
-<!ENTITY copy "&#169;"> <!-- copyright sign, U+00A9 ISOnum -->
-<!ENTITY ordf "&#170;"> <!-- feminine ordinal indicator, U+00AA ISOnum -->
-<!ENTITY laquo "&#171;"> <!-- left-pointing double angle quotation mark
- = left pointing guillemet, U+00AB ISOnum -->
-<!ENTITY not "&#172;"> <!-- not sign = angled dash,
- U+00AC ISOnum -->
-<!ENTITY shy "&#173;"> <!-- soft hyphen = discretionary hyphen,
- U+00AD ISOnum -->
-<!ENTITY reg "&#174;"> <!-- registered sign = registered trade mark sign,
- U+00AE ISOnum -->
-<!ENTITY macr "&#175;"> <!-- macron = spacing macron = overline
- = APL overbar, U+00AF ISOdia -->
-<!ENTITY deg "&#176;"> <!-- degree sign, U+00B0 ISOnum -->
-<!ENTITY plusmn "&#177;"> <!-- plus-minus sign = plus-or-minus sign,
- U+00B1 ISOnum -->
-<!ENTITY sup2 "&#178;"> <!-- superscript two = superscript digit two
- = squared, U+00B2 ISOnum -->
-<!ENTITY sup3 "&#179;"> <!-- superscript three = superscript digit three
- = cubed, U+00B3 ISOnum -->
-<!ENTITY acute "&#180;"> <!-- acute accent = spacing acute,
- U+00B4 ISOdia -->
-<!ENTITY micro "&#181;"> <!-- micro sign, U+00B5 ISOnum -->
-<!ENTITY para "&#182;"> <!-- pilcrow sign = paragraph sign,
- U+00B6 ISOnum -->
-<!ENTITY middot "&#183;"> <!-- middle dot = Georgian comma
- = Greek middle dot, U+00B7 ISOnum -->
-<!ENTITY cedil "&#184;"> <!-- cedilla = spacing cedilla, U+00B8 ISOdia -->
-<!ENTITY sup1 "&#185;"> <!-- superscript one = superscript digit one,
- U+00B9 ISOnum -->
-<!ENTITY ordm "&#186;"> <!-- masculine ordinal indicator,
- U+00BA ISOnum -->
-<!ENTITY raquo "&#187;"> <!-- right-pointing double angle quotation mark
- = right pointing guillemet, U+00BB ISOnum -->
-<!ENTITY frac14 "&#188;"> <!-- vulgar fraction one quarter
- = fraction one quarter, U+00BC ISOnum -->
-<!ENTITY frac12 "&#189;"> <!-- vulgar fraction one half
- = fraction one half, U+00BD ISOnum -->
-<!ENTITY frac34 "&#190;"> <!-- vulgar fraction three quarters
- = fraction three quarters, U+00BE ISOnum -->
-<!ENTITY iquest "&#191;"> <!-- inverted question mark
- = turned question mark, U+00BF ISOnum -->
-<!ENTITY Agrave "&#192;"> <!-- latin capital letter A with grave
- = latin capital letter A grave,
- U+00C0 ISOlat1 -->
-<!ENTITY Aacute "&#193;"> <!-- latin capital letter A with acute,
- U+00C1 ISOlat1 -->
-<!ENTITY Acirc "&#194;"> <!-- latin capital letter A with circumflex,
- U+00C2 ISOlat1 -->
-<!ENTITY Atilde "&#195;"> <!-- latin capital letter A with tilde,
- U+00C3 ISOlat1 -->
-<!ENTITY Auml "&#196;"> <!-- latin capital letter A with diaeresis,
- U+00C4 ISOlat1 -->
-<!ENTITY Aring "&#197;"> <!-- latin capital letter A with ring above
- = latin capital letter A ring,
- U+00C5 ISOlat1 -->
-<!ENTITY AElig "&#198;"> <!-- latin capital letter AE
- = latin capital ligature AE,
- U+00C6 ISOlat1 -->
-<!ENTITY Ccedil "&#199;"> <!-- latin capital letter C with cedilla,
- U+00C7 ISOlat1 -->
-<!ENTITY Egrave "&#200;"> <!-- latin capital letter E with grave,
- U+00C8 ISOlat1 -->
-<!ENTITY Eacute "&#201;"> <!-- latin capital letter E with acute,
- U+00C9 ISOlat1 -->
-<!ENTITY Ecirc "&#202;"> <!-- latin capital letter E with circumflex,
- U+00CA ISOlat1 -->
-<!ENTITY Euml "&#203;"> <!-- latin capital letter E with diaeresis,
- U+00CB ISOlat1 -->
-<!ENTITY Igrave "&#204;"> <!-- latin capital letter I with grave,
- U+00CC ISOlat1 -->
-<!ENTITY Iacute "&#205;"> <!-- latin capital letter I with acute,
- U+00CD ISOlat1 -->
-<!ENTITY Icirc "&#206;"> <!-- latin capital letter I with circumflex,
- U+00CE ISOlat1 -->
-<!ENTITY Iuml "&#207;"> <!-- latin capital letter I with diaeresis,
- U+00CF ISOlat1 -->
-<!ENTITY ETH "&#208;"> <!-- latin capital letter ETH, U+00D0 ISOlat1 -->
-<!ENTITY Ntilde "&#209;"> <!-- latin capital letter N with tilde,
- U+00D1 ISOlat1 -->
-<!ENTITY Ograve "&#210;"> <!-- latin capital letter O with grave,
- U+00D2 ISOlat1 -->
-<!ENTITY Oacute "&#211;"> <!-- latin capital letter O with acute,
- U+00D3 ISOlat1 -->
-<!ENTITY Ocirc "&#212;"> <!-- latin capital letter O with circumflex,
- U+00D4 ISOlat1 -->
-<!ENTITY Otilde "&#213;"> <!-- latin capital letter O with tilde,
- U+00D5 ISOlat1 -->
-<!ENTITY Ouml "&#214;"> <!-- latin capital letter O with diaeresis,
- U+00D6 ISOlat1 -->
-<!ENTITY times "&#215;"> <!-- multiplication sign, U+00D7 ISOnum -->
-<!ENTITY Oslash "&#216;"> <!-- latin capital letter O with stroke
- = latin capital letter O slash,
- U+00D8 ISOlat1 -->
-<!ENTITY Ugrave "&#217;"> <!-- latin capital letter U with grave,
- U+00D9 ISOlat1 -->
-<!ENTITY Uacute "&#218;"> <!-- latin capital letter U with acute,
- U+00DA ISOlat1 -->
-<!ENTITY Ucirc "&#219;"> <!-- latin capital letter U with circumflex,
- U+00DB ISOlat1 -->
-<!ENTITY Uuml "&#220;"> <!-- latin capital letter U with diaeresis,
- U+00DC ISOlat1 -->
-<!ENTITY Yacute "&#221;"> <!-- latin capital letter Y with acute,
- U+00DD ISOlat1 -->
-<!ENTITY THORN "&#222;"> <!-- latin capital letter THORN,
- U+00DE ISOlat1 -->
-<!ENTITY szlig "&#223;"> <!-- latin small letter sharp s = ess-zed,
- U+00DF ISOlat1 -->
-<!ENTITY agrave "&#224;"> <!-- latin small letter a with grave
- = latin small letter a grave,
- U+00E0 ISOlat1 -->
-<!ENTITY aacute "&#225;"> <!-- latin small letter a with acute,
- U+00E1 ISOlat1 -->
-<!ENTITY acirc "&#226;"> <!-- latin small letter a with circumflex,
- U+00E2 ISOlat1 -->
-<!ENTITY atilde "&#227;"> <!-- latin small letter a with tilde,
- U+00E3 ISOlat1 -->
-<!ENTITY auml "&#228;"> <!-- latin small letter a with diaeresis,
- U+00E4 ISOlat1 -->
-<!ENTITY aring "&#229;"> <!-- latin small letter a with ring above
- = latin small letter a ring,
- U+00E5 ISOlat1 -->
-<!ENTITY aelig "&#230;"> <!-- latin small letter ae
- = latin small ligature ae, U+00E6 ISOlat1 -->
-<!ENTITY ccedil "&#231;"> <!-- latin small letter c with cedilla,
- U+00E7 ISOlat1 -->
-<!ENTITY egrave "&#232;"> <!-- latin small letter e with grave,
- U+00E8 ISOlat1 -->
-<!ENTITY eacute "&#233;"> <!-- latin small letter e with acute,
- U+00E9 ISOlat1 -->
-<!ENTITY ecirc "&#234;"> <!-- latin small letter e with circumflex,
- U+00EA ISOlat1 -->
-<!ENTITY euml "&#235;"> <!-- latin small letter e with diaeresis,
- U+00EB ISOlat1 -->
-<!ENTITY igrave "&#236;"> <!-- latin small letter i with grave,
- U+00EC ISOlat1 -->
-<!ENTITY iacute "&#237;"> <!-- latin small letter i with acute,
- U+00ED ISOlat1 -->
-<!ENTITY icirc "&#238;"> <!-- latin small letter i with circumflex,
- U+00EE ISOlat1 -->
-<!ENTITY iuml "&#239;"> <!-- latin small letter i with diaeresis,
- U+00EF ISOlat1 -->
-<!ENTITY eth "&#240;"> <!-- latin small letter eth, U+00F0 ISOlat1 -->
-<!ENTITY ntilde "&#241;"> <!-- latin small letter n with tilde,
- U+00F1 ISOlat1 -->
-<!ENTITY ograve "&#242;"> <!-- latin small letter o with grave,
- U+00F2 ISOlat1 -->
-<!ENTITY oacute "&#243;"> <!-- latin small letter o with acute,
- U+00F3 ISOlat1 -->
-<!ENTITY ocirc "&#244;"> <!-- latin small letter o with circumflex,
- U+00F4 ISOlat1 -->
-<!ENTITY otilde "&#245;"> <!-- latin small letter o with tilde,
- U+00F5 ISOlat1 -->
-<!ENTITY ouml "&#246;"> <!-- latin small letter o with diaeresis,
- U+00F6 ISOlat1 -->
-<!ENTITY divide "&#247;"> <!-- division sign, U+00F7 ISOnum -->
-<!ENTITY oslash "&#248;"> <!-- latin small letter o with stroke,
- = latin small letter o slash,
- U+00F8 ISOlat1 -->
-<!ENTITY ugrave "&#249;"> <!-- latin small letter u with grave,
- U+00F9 ISOlat1 -->
-<!ENTITY uacute "&#250;"> <!-- latin small letter u with acute,
- U+00FA ISOlat1 -->
-<!ENTITY ucirc "&#251;"> <!-- latin small letter u with circumflex,
- U+00FB ISOlat1 -->
-<!ENTITY uuml "&#252;"> <!-- latin small letter u with diaeresis,
- U+00FC ISOlat1 -->
-<!ENTITY yacute "&#253;"> <!-- latin small letter y with acute,
- U+00FD ISOlat1 -->
-<!ENTITY thorn "&#254;"> <!-- latin small letter thorn,
- U+00FE ISOlat1 -->
-<!ENTITY yuml "&#255;"> <!-- latin small letter y with diaeresis,
- U+00FF ISOlat1 -->
diff --git a/Utilities/xml/xhtml1/xhtml-special.ent b/Utilities/xml/xhtml1/xhtml-special.ent
deleted file mode 100644
index 3a83fb656..000000000
--- a/Utilities/xml/xhtml1/xhtml-special.ent
+++ /dev/null
@@ -1,80 +0,0 @@
-<!-- Special characters for XHTML -->
-
-<!-- Character entity set. Typical invocation:
- <!ENTITY % HTMLspecial PUBLIC
- "-//W3C//ENTITIES Special for XHTML//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent">
- %HTMLspecial;
--->
-
-<!-- Portions (C) International Organization for Standardization 1986:
- Permission to copy in any form is granted for use with
- conforming SGML systems and applications as defined in
- ISO 8879, provided this notice is included in all copies.
--->
-
-<!-- Relevant ISO entity set is given unless names are newly introduced.
- New names (i.e., not in ISO 8879 list) do not clash with any
- existing ISO 8879 entity names. ISO 10646 character numbers
- are given for each character, in hex. values are decimal
- conversions of the ISO 10646 values and refer to the document
- character set. Names are Unicode names.
--->
-
-<!-- C0 Controls and Basic Latin -->
-<!ENTITY quot "&#34;"> <!-- quotation mark, U+0022 ISOnum -->
-<!ENTITY amp "&#38;#38;"> <!-- ampersand, U+0026 ISOnum -->
-<!ENTITY lt "&#38;#60;"> <!-- less-than sign, U+003C ISOnum -->
-<!ENTITY gt "&#62;"> <!-- greater-than sign, U+003E ISOnum -->
-<!ENTITY apos "&#39;"> <!-- apostrophe = APL quote, U+0027 ISOnum -->
-
-<!-- Latin Extended-A -->
-<!ENTITY OElig "&#338;"> <!-- latin capital ligature OE,
- U+0152 ISOlat2 -->
-<!ENTITY oelig "&#339;"> <!-- latin small ligature oe, U+0153 ISOlat2 -->
-<!-- ligature is a misnomer, this is a separate character in some languages -->
-<!ENTITY Scaron "&#352;"> <!-- latin capital letter S with caron,
- U+0160 ISOlat2 -->
-<!ENTITY scaron "&#353;"> <!-- latin small letter s with caron,
- U+0161 ISOlat2 -->
-<!ENTITY Yuml "&#376;"> <!-- latin capital letter Y with diaeresis,
- U+0178 ISOlat2 -->
-
-<!-- Spacing Modifier Letters -->
-<!ENTITY circ "&#710;"> <!-- modifier letter circumflex accent,
- U+02C6 ISOpub -->
-<!ENTITY tilde "&#732;"> <!-- small tilde, U+02DC ISOdia -->
-
-<!-- General Punctuation -->
-<!ENTITY ensp "&#8194;"> <!-- en space, U+2002 ISOpub -->
-<!ENTITY emsp "&#8195;"> <!-- em space, U+2003 ISOpub -->
-<!ENTITY thinsp "&#8201;"> <!-- thin space, U+2009 ISOpub -->
-<!ENTITY zwnj "&#8204;"> <!-- zero width non-joiner,
- U+200C NEW RFC 2070 -->
-<!ENTITY zwj "&#8205;"> <!-- zero width joiner, U+200D NEW RFC 2070 -->
-<!ENTITY lrm "&#8206;"> <!-- left-to-right mark, U+200E NEW RFC 2070 -->
-<!ENTITY rlm "&#8207;"> <!-- right-to-left mark, U+200F NEW RFC 2070 -->
-<!ENTITY ndash "&#8211;"> <!-- en dash, U+2013 ISOpub -->
-<!ENTITY mdash "&#8212;"> <!-- em dash, U+2014 ISOpub -->
-<!ENTITY lsquo "&#8216;"> <!-- left single quotation mark,
- U+2018 ISOnum -->
-<!ENTITY rsquo "&#8217;"> <!-- right single quotation mark,
- U+2019 ISOnum -->
-<!ENTITY sbquo "&#8218;"> <!-- single low-9 quotation mark, U+201A NEW -->
-<!ENTITY ldquo "&#8220;"> <!-- left double quotation mark,
- U+201C ISOnum -->
-<!ENTITY rdquo "&#8221;"> <!-- right double quotation mark,
- U+201D ISOnum -->
-<!ENTITY bdquo "&#8222;"> <!-- double low-9 quotation mark, U+201E NEW -->
-<!ENTITY dagger "&#8224;"> <!-- dagger, U+2020 ISOpub -->
-<!ENTITY Dagger "&#8225;"> <!-- double dagger, U+2021 ISOpub -->
-<!ENTITY permil "&#8240;"> <!-- per mille sign, U+2030 ISOtech -->
-<!ENTITY lsaquo "&#8249;"> <!-- single left-pointing angle quotation mark,
- U+2039 ISO proposed -->
-<!-- lsaquo is proposed but not yet ISO standardized -->
-<!ENTITY rsaquo "&#8250;"> <!-- single right-pointing angle quotation mark,
- U+203A ISO proposed -->
-<!-- rsaquo is proposed but not yet ISO standardized -->
-
-<!-- Currency Symbols -->
-<!ENTITY euro "&#8364;"> <!-- euro sign, U+20AC NEW -->
diff --git a/Utilities/xml/xhtml1/xhtml-symbol.ent b/Utilities/xml/xhtml1/xhtml-symbol.ent
deleted file mode 100644
index d0c77eebc..000000000
--- a/Utilities/xml/xhtml1/xhtml-symbol.ent
+++ /dev/null
@@ -1,237 +0,0 @@
-<!-- Mathematical, Greek and Symbolic characters for XHTML -->
-
-<!-- Character entity set. Typical invocation:
- <!ENTITY % HTMLsymbol PUBLIC
- "-//W3C//ENTITIES Symbols for XHTML//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent">
- %HTMLsymbol;
--->
-
-<!-- Portions (C) International Organization for Standardization 1986:
- Permission to copy in any form is granted for use with
- conforming SGML systems and applications as defined in
- ISO 8879, provided this notice is included in all copies.
--->
-
-<!-- Relevant ISO entity set is given unless names are newly introduced.
- New names (i.e., not in ISO 8879 list) do not clash with any
- existing ISO 8879 entity names. ISO 10646 character numbers
- are given for each character, in hex. values are decimal
- conversions of the ISO 10646 values and refer to the document
- character set. Names are Unicode names.
--->
-
-<!-- Latin Extended-B -->
-<!ENTITY fnof "&#402;"> <!-- latin small letter f with hook = function
- = florin, U+0192 ISOtech -->
-
-<!-- Greek -->
-<!ENTITY Alpha "&#913;"> <!-- greek capital letter alpha, U+0391 -->
-<!ENTITY Beta "&#914;"> <!-- greek capital letter beta, U+0392 -->
-<!ENTITY Gamma "&#915;"> <!-- greek capital letter gamma,
- U+0393 ISOgrk3 -->
-<!ENTITY Delta "&#916;"> <!-- greek capital letter delta,
- U+0394 ISOgrk3 -->
-<!ENTITY Epsilon "&#917;"> <!-- greek capital letter epsilon, U+0395 -->
-<!ENTITY Zeta "&#918;"> <!-- greek capital letter zeta, U+0396 -->
-<!ENTITY Eta "&#919;"> <!-- greek capital letter eta, U+0397 -->
-<!ENTITY Theta "&#920;"> <!-- greek capital letter theta,
- U+0398 ISOgrk3 -->
-<!ENTITY Iota "&#921;"> <!-- greek capital letter iota, U+0399 -->
-<!ENTITY Kappa "&#922;"> <!-- greek capital letter kappa, U+039A -->
-<!ENTITY Lambda "&#923;"> <!-- greek capital letter lamda,
- U+039B ISOgrk3 -->
-<!ENTITY Mu "&#924;"> <!-- greek capital letter mu, U+039C -->
-<!ENTITY Nu "&#925;"> <!-- greek capital letter nu, U+039D -->
-<!ENTITY Xi "&#926;"> <!-- greek capital letter xi, U+039E ISOgrk3 -->
-<!ENTITY Omicron "&#927;"> <!-- greek capital letter omicron, U+039F -->
-<!ENTITY Pi "&#928;"> <!-- greek capital letter pi, U+03A0 ISOgrk3 -->
-<!ENTITY Rho "&#929;"> <!-- greek capital letter rho, U+03A1 -->
-<!-- there is no Sigmaf, and no U+03A2 character either -->
-<!ENTITY Sigma "&#931;"> <!-- greek capital letter sigma,
- U+03A3 ISOgrk3 -->
-<!ENTITY Tau "&#932;"> <!-- greek capital letter tau, U+03A4 -->
-<!ENTITY Upsilon "&#933;"> <!-- greek capital letter upsilon,
- U+03A5 ISOgrk3 -->
-<!ENTITY Phi "&#934;"> <!-- greek capital letter phi,
- U+03A6 ISOgrk3 -->
-<!ENTITY Chi "&#935;"> <!-- greek capital letter chi, U+03A7 -->
-<!ENTITY Psi "&#936;"> <!-- greek capital letter psi,
- U+03A8 ISOgrk3 -->
-<!ENTITY Omega "&#937;"> <!-- greek capital letter omega,
- U+03A9 ISOgrk3 -->
-
-<!ENTITY alpha "&#945;"> <!-- greek small letter alpha,
- U+03B1 ISOgrk3 -->
-<!ENTITY beta "&#946;"> <!-- greek small letter beta, U+03B2 ISOgrk3 -->
-<!ENTITY gamma "&#947;"> <!-- greek small letter gamma,
- U+03B3 ISOgrk3 -->
-<!ENTITY delta "&#948;"> <!-- greek small letter delta,
- U+03B4 ISOgrk3 -->
-<!ENTITY epsilon "&#949;"> <!-- greek small letter epsilon,
- U+03B5 ISOgrk3 -->
-<!ENTITY zeta "&#950;"> <!-- greek small letter zeta, U+03B6 ISOgrk3 -->
-<!ENTITY eta "&#951;"> <!-- greek small letter eta, U+03B7 ISOgrk3 -->
-<!ENTITY theta "&#952;"> <!-- greek small letter theta,
- U+03B8 ISOgrk3 -->
-<!ENTITY iota "&#953;"> <!-- greek small letter iota, U+03B9 ISOgrk3 -->
-<!ENTITY kappa "&#954;"> <!-- greek small letter kappa,
- U+03BA ISOgrk3 -->
-<!ENTITY lambda "&#955;"> <!-- greek small letter lamda,
- U+03BB ISOgrk3 -->
-<!ENTITY mu "&#956;"> <!-- greek small letter mu, U+03BC ISOgrk3 -->
-<!ENTITY nu "&#957;"> <!-- greek small letter nu, U+03BD ISOgrk3 -->
-<!ENTITY xi "&#958;"> <!-- greek small letter xi, U+03BE ISOgrk3 -->
-<!ENTITY omicron "&#959;"> <!-- greek small letter omicron, U+03BF NEW -->
-<!ENTITY pi "&#960;"> <!-- greek small letter pi, U+03C0 ISOgrk3 -->
-<!ENTITY rho "&#961;"> <!-- greek small letter rho, U+03C1 ISOgrk3 -->
-<!ENTITY sigmaf "&#962;"> <!-- greek small letter final sigma,
- U+03C2 ISOgrk3 -->
-<!ENTITY sigma "&#963;"> <!-- greek small letter sigma,
- U+03C3 ISOgrk3 -->
-<!ENTITY tau "&#964;"> <!-- greek small letter tau, U+03C4 ISOgrk3 -->
-<!ENTITY upsilon "&#965;"> <!-- greek small letter upsilon,
- U+03C5 ISOgrk3 -->
-<!ENTITY phi "&#966;"> <!-- greek small letter phi, U+03C6 ISOgrk3 -->
-<!ENTITY chi "&#967;"> <!-- greek small letter chi, U+03C7 ISOgrk3 -->
-<!ENTITY psi "&#968;"> <!-- greek small letter psi, U+03C8 ISOgrk3 -->
-<!ENTITY omega "&#969;"> <!-- greek small letter omega,
- U+03C9 ISOgrk3 -->
-<!ENTITY thetasym "&#977;"> <!-- greek theta symbol,
- U+03D1 NEW -->
-<!ENTITY upsih "&#978;"> <!-- greek upsilon with hook symbol,
- U+03D2 NEW -->
-<!ENTITY piv "&#982;"> <!-- greek pi symbol, U+03D6 ISOgrk3 -->
-
-<!-- General Punctuation -->
-<!ENTITY bull "&#8226;"> <!-- bullet = black small circle,
- U+2022 ISOpub -->
-<!-- bullet is NOT the same as bullet operator, U+2219 -->
-<!ENTITY hellip "&#8230;"> <!-- horizontal ellipsis = three dot leader,
- U+2026 ISOpub -->
-<!ENTITY prime "&#8242;"> <!-- prime = minutes = feet, U+2032 ISOtech -->
-<!ENTITY Prime "&#8243;"> <!-- double prime = seconds = inches,
- U+2033 ISOtech -->
-<!ENTITY oline "&#8254;"> <!-- overline = spacing overscore,
- U+203E NEW -->
-<!ENTITY frasl "&#8260;"> <!-- fraction slash, U+2044 NEW -->
-
-<!-- Letterlike Symbols -->
-<!ENTITY weierp "&#8472;"> <!-- script capital P = power set
- = Weierstrass p, U+2118 ISOamso -->
-<!ENTITY image "&#8465;"> <!-- black-letter capital I = imaginary part,
- U+2111 ISOamso -->
-<!ENTITY real "&#8476;"> <!-- black-letter capital R = real part symbol,
- U+211C ISOamso -->
-<!ENTITY trade "&#8482;"> <!-- trade mark sign, U+2122 ISOnum -->
-<!ENTITY alefsym "&#8501;"> <!-- alef symbol = first transfinite cardinal,
- U+2135 NEW -->
-<!-- alef symbol is NOT the same as hebrew letter alef,
- U+05D0 although the same glyph could be used to depict both characters -->
-
-<!-- Arrows -->
-<!ENTITY larr "&#8592;"> <!-- leftwards arrow, U+2190 ISOnum -->
-<!ENTITY uarr "&#8593;"> <!-- upwards arrow, U+2191 ISOnum-->
-<!ENTITY rarr "&#8594;"> <!-- rightwards arrow, U+2192 ISOnum -->
-<!ENTITY darr "&#8595;"> <!-- downwards arrow, U+2193 ISOnum -->
-<!ENTITY harr "&#8596;"> <!-- left right arrow, U+2194 ISOamsa -->
-<!ENTITY crarr "&#8629;"> <!-- downwards arrow with corner leftwards
- = carriage return, U+21B5 NEW -->
-<!ENTITY lArr "&#8656;"> <!-- leftwards double arrow, U+21D0 ISOtech -->
-<!-- Unicode does not say that lArr is the same as the 'is implied by' arrow
- but also does not have any other character for that function. So lArr can
- be used for 'is implied by' as ISOtech suggests -->
-<!ENTITY uArr "&#8657;"> <!-- upwards double arrow, U+21D1 ISOamsa -->
-<!ENTITY rArr "&#8658;"> <!-- rightwards double arrow,
- U+21D2 ISOtech -->
-<!-- Unicode does not say this is the 'implies' character but does not have
- another character with this function so rArr can be used for 'implies'
- as ISOtech suggests -->
-<!ENTITY dArr "&#8659;"> <!-- downwards double arrow, U+21D3 ISOamsa -->
-<!ENTITY hArr "&#8660;"> <!-- left right double arrow,
- U+21D4 ISOamsa -->
-
-<!-- Mathematical Operators -->
-<!ENTITY forall "&#8704;"> <!-- for all, U+2200 ISOtech -->
-<!ENTITY part "&#8706;"> <!-- partial differential, U+2202 ISOtech -->
-<!ENTITY exist "&#8707;"> <!-- there exists, U+2203 ISOtech -->
-<!ENTITY empty "&#8709;"> <!-- empty set = null set, U+2205 ISOamso -->
-<!ENTITY nabla "&#8711;"> <!-- nabla = backward difference,
- U+2207 ISOtech -->
-<!ENTITY isin "&#8712;"> <!-- element of, U+2208 ISOtech -->
-<!ENTITY notin "&#8713;"> <!-- not an element of, U+2209 ISOtech -->
-<!ENTITY ni "&#8715;"> <!-- contains as member, U+220B ISOtech -->
-<!ENTITY prod "&#8719;"> <!-- n-ary product = product sign,
- U+220F ISOamsb -->
-<!-- prod is NOT the same character as U+03A0 'greek capital letter pi' though
- the same glyph might be used for both -->
-<!ENTITY sum "&#8721;"> <!-- n-ary summation, U+2211 ISOamsb -->
-<!-- sum is NOT the same character as U+03A3 'greek capital letter sigma'
- though the same glyph might be used for both -->
-<!ENTITY minus "&#8722;"> <!-- minus sign, U+2212 ISOtech -->
-<!ENTITY lowast "&#8727;"> <!-- asterisk operator, U+2217 ISOtech -->
-<!ENTITY radic "&#8730;"> <!-- square root = radical sign,
- U+221A ISOtech -->
-<!ENTITY prop "&#8733;"> <!-- proportional to, U+221D ISOtech -->
-<!ENTITY infin "&#8734;"> <!-- infinity, U+221E ISOtech -->
-<!ENTITY ang "&#8736;"> <!-- angle, U+2220 ISOamso -->
-<!ENTITY and "&#8743;"> <!-- logical and = wedge, U+2227 ISOtech -->
-<!ENTITY or "&#8744;"> <!-- logical or = vee, U+2228 ISOtech -->
-<!ENTITY cap "&#8745;"> <!-- intersection = cap, U+2229 ISOtech -->
-<!ENTITY cup "&#8746;"> <!-- union = cup, U+222A ISOtech -->
-<!ENTITY int "&#8747;"> <!-- integral, U+222B ISOtech -->
-<!ENTITY there4 "&#8756;"> <!-- therefore, U+2234 ISOtech -->
-<!ENTITY sim "&#8764;"> <!-- tilde operator = varies with = similar to,
- U+223C ISOtech -->
-<!-- tilde operator is NOT the same character as the tilde, U+007E,
- although the same glyph might be used to represent both -->
-<!ENTITY cong "&#8773;"> <!-- approximately equal to, U+2245 ISOtech -->
-<!ENTITY asymp "&#8776;"> <!-- almost equal to = asymptotic to,
- U+2248 ISOamsr -->
-<!ENTITY ne "&#8800;"> <!-- not equal to, U+2260 ISOtech -->
-<!ENTITY equiv "&#8801;"> <!-- identical to, U+2261 ISOtech -->
-<!ENTITY le "&#8804;"> <!-- less-than or equal to, U+2264 ISOtech -->
-<!ENTITY ge "&#8805;"> <!-- greater-than or equal to,
- U+2265 ISOtech -->
-<!ENTITY sub "&#8834;"> <!-- subset of, U+2282 ISOtech -->
-<!ENTITY sup "&#8835;"> <!-- superset of, U+2283 ISOtech -->
-<!ENTITY nsub "&#8836;"> <!-- not a subset of, U+2284 ISOamsn -->
-<!ENTITY sube "&#8838;"> <!-- subset of or equal to, U+2286 ISOtech -->
-<!ENTITY supe "&#8839;"> <!-- superset of or equal to,
- U+2287 ISOtech -->
-<!ENTITY oplus "&#8853;"> <!-- circled plus = direct sum,
- U+2295 ISOamsb -->
-<!ENTITY otimes "&#8855;"> <!-- circled times = vector product,
- U+2297 ISOamsb -->
-<!ENTITY perp "&#8869;"> <!-- up tack = orthogonal to = perpendicular,
- U+22A5 ISOtech -->
-<!ENTITY sdot "&#8901;"> <!-- dot operator, U+22C5 ISOamsb -->
-<!-- dot operator is NOT the same character as U+00B7 middle dot -->
-
-<!-- Miscellaneous Technical -->
-<!ENTITY lceil "&#8968;"> <!-- left ceiling = APL upstile,
- U+2308 ISOamsc -->
-<!ENTITY rceil "&#8969;"> <!-- right ceiling, U+2309 ISOamsc -->
-<!ENTITY lfloor "&#8970;"> <!-- left floor = APL downstile,
- U+230A ISOamsc -->
-<!ENTITY rfloor "&#8971;"> <!-- right floor, U+230B ISOamsc -->
-<!ENTITY lang "&#9001;"> <!-- left-pointing angle bracket = bra,
- U+2329 ISOtech -->
-<!-- lang is NOT the same character as U+003C 'less than sign'
- or U+2039 'single left-pointing angle quotation mark' -->
-<!ENTITY rang "&#9002;"> <!-- right-pointing angle bracket = ket,
- U+232A ISOtech -->
-<!-- rang is NOT the same character as U+003E 'greater than sign'
- or U+203A 'single right-pointing angle quotation mark' -->
-
-<!-- Geometric Shapes -->
-<!ENTITY loz "&#9674;"> <!-- lozenge, U+25CA ISOpub -->
-
-<!-- Miscellaneous Symbols -->
-<!ENTITY spades "&#9824;"> <!-- black spade suit, U+2660 ISOpub -->
-<!-- black here seems to mean filled as opposed to hollow -->
-<!ENTITY clubs "&#9827;"> <!-- black club suit = shamrock,
- U+2663 ISOpub -->
-<!ENTITY hearts "&#9829;"> <!-- black heart suit = valentine,
- U+2665 ISOpub -->
-<!ENTITY diams "&#9830;"> <!-- black diamond suit, U+2666 ISOpub -->
diff --git a/Utilities/xml/xhtml1/xhtml1-strict.dtd b/Utilities/xml/xhtml1/xhtml1-strict.dtd
deleted file mode 100644
index e48fbea6e..000000000
--- a/Utilities/xml/xhtml1/xhtml1-strict.dtd
+++ /dev/null
@@ -1,977 +0,0 @@
-<!--
- Extensible HTML version 1.0 Strict DTD
-
- This is the same as HTML 4 Strict except for
- changes due to the differences between XML and SGML.
-
- Namespace = http://www.w3.org/1999/xhtml
-
- For further information, see: http://www.w3.org/TR/xhtml1
-
- Copyright (c) 1998-2002 W3C (MIT, INRIA, Keio),
- All Rights Reserved.
-
- This DTD module is identified by the PUBLIC and SYSTEM identifiers:
-
- PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
-
- $Revision: 1.1 $
- $Date: 2002/08/01 13:56:03 $
-
--->
-
-<!--================ Character mnemonic entities =========================-->
-
-<!ENTITY % HTMLlat1 PUBLIC
- "-//W3C//ENTITIES Latin 1 for XHTML//EN"
- "xhtml-lat1.ent">
-%HTMLlat1;
-
-<!ENTITY % HTMLsymbol PUBLIC
- "-//W3C//ENTITIES Symbols for XHTML//EN"
- "xhtml-symbol.ent">
-%HTMLsymbol;
-
-<!ENTITY % HTMLspecial PUBLIC
- "-//W3C//ENTITIES Special for XHTML//EN"
- "xhtml-special.ent">
-%HTMLspecial;
-
-<!--================== Imported Names ====================================-->
-
-<!ENTITY % ContentType "CDATA">
- <!-- media type, as per [RFC2045] -->
-
-<!ENTITY % ContentTypes "CDATA">
- <!-- comma-separated list of media types, as per [RFC2045] -->
-
-<!ENTITY % Charset "CDATA">
- <!-- a character encoding, as per [RFC2045] -->
-
-<!ENTITY % Charsets "CDATA">
- <!-- a space separated list of character encodings, as per [RFC2045] -->
-
-<!ENTITY % LanguageCode "NMTOKEN">
- <!-- a language code, as per [RFC3066] -->
-
-<!ENTITY % Character "CDATA">
- <!-- a single character, as per section 2.2 of [XML] -->
-
-<!ENTITY % Number "CDATA">
- <!-- one or more digits -->
-
-<!ENTITY % LinkTypes "CDATA">
- <!-- space-separated list of link types -->
-
-<!ENTITY % MediaDesc "CDATA">
- <!-- single or comma-separated list of media descriptors -->
-
-<!ENTITY % URI "CDATA">
- <!-- a Uniform Resource Identifier, see [RFC2396] -->
-
-<!ENTITY % UriList "CDATA">
- <!-- a space separated list of Uniform Resource Identifiers -->
-
-<!ENTITY % Datetime "CDATA">
- <!-- date and time information. ISO date format -->
-
-<!ENTITY % Script "CDATA">
- <!-- script expression -->
-
-<!ENTITY % StyleSheet "CDATA">
- <!-- style sheet data -->
-
-<!ENTITY % Text "CDATA">
- <!-- used for titles etc. -->
-
-<!ENTITY % Length "CDATA">
- <!-- nn for pixels or nn% for percentage length -->
-
-<!ENTITY % MultiLength "CDATA">
- <!-- pixel, percentage, or relative -->
-
-<!ENTITY % Pixels "CDATA">
- <!-- integer representing length in pixels -->
-
-<!-- these are used for image maps -->
-
-<!ENTITY % Shape "(rect|circle|poly|default)">
-
-<!ENTITY % Coords "CDATA">
- <!-- comma separated list of lengths -->
-
-<!--=================== Generic Attributes ===============================-->
-
-<!-- core attributes common to most elements
- id document-wide unique id
- class space separated list of classes
- style associated style info
- title advisory title/amplification
--->
-<!ENTITY % coreattrs
- "id ID #IMPLIED
- class CDATA #IMPLIED
- style %StyleSheet; #IMPLIED
- title %Text; #IMPLIED"
- >
-
-<!-- internationalization attributes
- lang language code (backwards compatible)
- xml:lang language code (as per XML 1.0 spec)
- dir direction for weak/neutral text
--->
-<!ENTITY % i18n
- "lang %LanguageCode; #IMPLIED
- xml:lang %LanguageCode; #IMPLIED
- dir (ltr|rtl) #IMPLIED"
- >
-
-<!-- attributes for common UI events
- onclick a pointer button was clicked
- ondblclick a pointer button was double clicked
- onmousedown a pointer button was pressed down
- onmouseup a pointer button was released
- onmousemove a pointer was moved onto the element
- onmouseout a pointer was moved away from the element
- onkeypress a key was pressed and released
- onkeydown a key was pressed down
- onkeyup a key was released
--->
-<!ENTITY % events
- "onclick %Script; #IMPLIED
- ondblclick %Script; #IMPLIED
- onmousedown %Script; #IMPLIED
- onmouseup %Script; #IMPLIED
- onmouseover %Script; #IMPLIED
- onmousemove %Script; #IMPLIED
- onmouseout %Script; #IMPLIED
- onkeypress %Script; #IMPLIED
- onkeydown %Script; #IMPLIED
- onkeyup %Script; #IMPLIED"
- >
-
-<!-- attributes for elements that can get the focus
- accesskey accessibility key character
- tabindex position in tabbing order
- onfocus the element got the focus
- onblur the element lost the focus
--->
-<!ENTITY % focus
- "accesskey %Character; #IMPLIED
- tabindex %Number; #IMPLIED
- onfocus %Script; #IMPLIED
- onblur %Script; #IMPLIED"
- >
-
-<!ENTITY % attrs "%coreattrs; %i18n; %events;">
-
-<!--=================== Text Elements ====================================-->
-
-<!ENTITY % special.pre
- "br | span | bdo | map">
-
-
-<!ENTITY % special
- "%special.pre; | object | img ">
-
-<!ENTITY % fontstyle "tt | i | b | big | small ">
-
-<!ENTITY % phrase "em | strong | dfn | code | q |
- samp | kbd | var | cite | abbr | acronym | sub | sup ">
-
-<!ENTITY % inline.forms "input | select | textarea | label | button">
-
-<!-- these can occur at block or inline level -->
-<!ENTITY % misc.inline "ins | del | script">
-
-<!-- these can only occur at block level -->
-<!ENTITY % misc "noscript | %misc.inline;">
-
-<!ENTITY % inline "a | %special; | %fontstyle; | %phrase; | %inline.forms;">
-
-<!-- %Inline; covers inline or "text-level" elements -->
-<!ENTITY % Inline "(#PCDATA | %inline; | %misc.inline;)*">
-
-<!--================== Block level elements ==============================-->
-
-<!ENTITY % heading "h1|h2|h3|h4|h5|h6">
-<!ENTITY % lists "ul | ol | dl">
-<!ENTITY % blocktext "pre | hr | blockquote | address">
-
-<!ENTITY % block
- "p | %heading; | div | %lists; | %blocktext; | fieldset | table">
-
-<!ENTITY % Block "(%block; | form | %misc;)*">
-
-<!-- %Flow; mixes block and inline and is used for list items etc. -->
-<!ENTITY % Flow "(#PCDATA | %block; | form | %inline; | %misc;)*">
-
-<!--================== Content models for exclusions =====================-->
-
-<!-- a elements use %Inline; excluding a -->
-
-<!ENTITY % a.content
- "(#PCDATA | %special; | %fontstyle; | %phrase; | %inline.forms; | %misc.inline;)*">
-
-<!-- pre uses %Inline excluding big, small, sup or sup -->
-
-<!ENTITY % pre.content
- "(#PCDATA | a | %fontstyle; | %phrase; | %special.pre; | %misc.inline;
- | %inline.forms;)*">
-
-<!-- form uses %Block; excluding form -->
-
-<!ENTITY % form.content "(%block; | %misc;)*">
-
-<!-- button uses %Flow; but excludes a, form and form controls -->
-
-<!ENTITY % button.content
- "(#PCDATA | p | %heading; | div | %lists; | %blocktext; |
- table | %special; | %fontstyle; | %phrase; | %misc;)*">
-
-<!--================ Document Structure ==================================-->
-
-<!-- the namespace URI designates the document profile -->
-
-<!ELEMENT html (head, body)>
-<!ATTLIST html
- %i18n;
- id ID #IMPLIED
- xmlns %URI; #FIXED 'http://www.w3.org/1999/xhtml'
- >
-
-<!--================ Document Head =======================================-->
-
-<!ENTITY % head.misc "(script|style|meta|link|object)*">
-
-<!-- content model is %head.misc; combined with a single
- title and an optional base element in any order -->
-
-<!ELEMENT head (%head.misc;,
- ((title, %head.misc;, (base, %head.misc;)?) |
- (base, %head.misc;, (title, %head.misc;))))>
-
-<!ATTLIST head
- %i18n;
- id ID #IMPLIED
- profile %URI; #IMPLIED
- >
-
-<!-- The title element is not considered part of the flow of text.
- It should be displayed, for example as the page header or
- window title. Exactly one title is required per document.
- -->
-<!ELEMENT title (#PCDATA)>
-<!ATTLIST title
- %i18n;
- id ID #IMPLIED
- >
-
-<!-- document base URI -->
-
-<!ELEMENT base EMPTY>
-<!ATTLIST base
- href %URI; #REQUIRED
- id ID #IMPLIED
- >
-
-<!-- generic metainformation -->
-<!ELEMENT meta EMPTY>
-<!ATTLIST meta
- %i18n;
- id ID #IMPLIED
- http-equiv CDATA #IMPLIED
- name CDATA #IMPLIED
- content CDATA #REQUIRED
- scheme CDATA #IMPLIED
- >
-
-<!--
- Relationship values can be used in principle:
-
- a) for document specific toolbars/menus when used
- with the link element in document head e.g.
- start, contents, previous, next, index, end, help
- b) to link to a separate style sheet (rel="stylesheet")
- c) to make a link to a script (rel="script")
- d) by stylesheets to control how collections of
- html nodes are rendered into printed documents
- e) to make a link to a printable version of this document
- e.g. a PostScript or PDF version (rel="alternate" media="print")
--->
-
-<!ELEMENT link EMPTY>
-<!ATTLIST link
- %attrs;
- charset %Charset; #IMPLIED
- href %URI; #IMPLIED
- hreflang %LanguageCode; #IMPLIED
- type %ContentType; #IMPLIED
- rel %LinkTypes; #IMPLIED
- rev %LinkTypes; #IMPLIED
- media %MediaDesc; #IMPLIED
- >
-
-<!-- style info, which may include CDATA sections -->
-<!ELEMENT style (#PCDATA)>
-<!ATTLIST style
- %i18n;
- id ID #IMPLIED
- type %ContentType; #REQUIRED
- media %MediaDesc; #IMPLIED
- title %Text; #IMPLIED
- xml:space (preserve) #FIXED 'preserve'
- >
-
-<!-- script statements, which may include CDATA sections -->
-<!ELEMENT script (#PCDATA)>
-<!ATTLIST script
- id ID #IMPLIED
- charset %Charset; #IMPLIED
- type %ContentType; #REQUIRED
- src %URI; #IMPLIED
- defer (defer) #IMPLIED
- xml:space (preserve) #FIXED 'preserve'
- >
-
-<!-- alternate content container for non script-based rendering -->
-
-<!ELEMENT noscript %Block;>
-<!ATTLIST noscript
- %attrs;
- >
-
-<!--=================== Document Body ====================================-->
-
-<!ELEMENT body %Block;>
-<!ATTLIST body
- %attrs;
- onload %Script; #IMPLIED
- onunload %Script; #IMPLIED
- >
-
-<!ELEMENT div %Flow;> <!-- generic language/style container -->
-<!ATTLIST div
- %attrs;
- >
-
-<!--=================== Paragraphs =======================================-->
-
-<!ELEMENT p %Inline;>
-<!ATTLIST p
- %attrs;
- >
-
-<!--=================== Headings =========================================-->
-
-<!--
- There are six levels of headings from h1 (the most important)
- to h6 (the least important).
--->
-
-<!ELEMENT h1 %Inline;>
-<!ATTLIST h1
- %attrs;
- >
-
-<!ELEMENT h2 %Inline;>
-<!ATTLIST h2
- %attrs;
- >
-
-<!ELEMENT h3 %Inline;>
-<!ATTLIST h3
- %attrs;
- >
-
-<!ELEMENT h4 %Inline;>
-<!ATTLIST h4
- %attrs;
- >
-
-<!ELEMENT h5 %Inline;>
-<!ATTLIST h5
- %attrs;
- >
-
-<!ELEMENT h6 %Inline;>
-<!ATTLIST h6
- %attrs;
- >
-
-<!--=================== Lists ============================================-->
-
-<!-- Unordered list -->
-
-<!ELEMENT ul (li)+>
-<!ATTLIST ul
- %attrs;
- >
-
-<!-- Ordered (numbered) list -->
-
-<!ELEMENT ol (li)+>
-<!ATTLIST ol
- %attrs;
- >
-
-<!-- list item -->
-
-<!ELEMENT li %Flow;>
-<!ATTLIST li
- %attrs;
- >
-
-<!-- definition lists - dt for term, dd for its definition -->
-
-<!ELEMENT dl (dt|dd)+>
-<!ATTLIST dl
- %attrs;
- >
-
-<!ELEMENT dt %Inline;>
-<!ATTLIST dt
- %attrs;
- >
-
-<!ELEMENT dd %Flow;>
-<!ATTLIST dd
- %attrs;
- >
-
-<!--=================== Address ==========================================-->
-
-<!-- information on author -->
-
-<!ELEMENT address %Inline;>
-<!ATTLIST address
- %attrs;
- >
-
-<!--=================== Horizontal Rule ==================================-->
-
-<!ELEMENT hr EMPTY>
-<!ATTLIST hr
- %attrs;
- >
-
-<!--=================== Preformatted Text ================================-->
-
-<!-- content is %Inline; excluding "img|object|big|small|sub|sup" -->
-
-<!ELEMENT pre %pre.content;>
-<!ATTLIST pre
- %attrs;
- xml:space (preserve) #FIXED 'preserve'
- >
-
-<!--=================== Block-like Quotes ================================-->
-
-<!ELEMENT blockquote %Block;>
-<!ATTLIST blockquote
- %attrs;
- cite %URI; #IMPLIED
- >
-
-<!--=================== Inserted/Deleted Text ============================-->
-
-<!--
- ins/del are allowed in block and inline content, but its
- inappropriate to include block content within an ins element
- occurring in inline content.
--->
-<!ELEMENT ins %Flow;>
-<!ATTLIST ins
- %attrs;
- cite %URI; #IMPLIED
- datetime %Datetime; #IMPLIED
- >
-
-<!ELEMENT del %Flow;>
-<!ATTLIST del
- %attrs;
- cite %URI; #IMPLIED
- datetime %Datetime; #IMPLIED
- >
-
-<!--================== The Anchor Element ================================-->
-
-<!-- content is %Inline; except that anchors shouldn't be nested -->
-
-<!ELEMENT a %a.content;>
-<!ATTLIST a
- %attrs;
- %focus;
- charset %Charset; #IMPLIED
- type %ContentType; #IMPLIED
- name NMTOKEN #IMPLIED
- href %URI; #IMPLIED
- hreflang %LanguageCode; #IMPLIED
- rel %LinkTypes; #IMPLIED
- rev %LinkTypes; #IMPLIED
- shape %Shape; "rect"
- coords %Coords; #IMPLIED
- >
-
-<!--===================== Inline Elements ================================-->
-
-<!ELEMENT span %Inline;> <!-- generic language/style container -->
-<!ATTLIST span
- %attrs;
- >
-
-<!ELEMENT bdo %Inline;> <!-- I18N BiDi over-ride -->
-<!ATTLIST bdo
- %coreattrs;
- %events;
- lang %LanguageCode; #IMPLIED
- xml:lang %LanguageCode; #IMPLIED
- dir (ltr|rtl) #REQUIRED
- >
-
-<!ELEMENT br EMPTY> <!-- forced line break -->
-<!ATTLIST br
- %coreattrs;
- >
-
-<!ELEMENT em %Inline;> <!-- emphasis -->
-<!ATTLIST em %attrs;>
-
-<!ELEMENT strong %Inline;> <!-- strong emphasis -->
-<!ATTLIST strong %attrs;>
-
-<!ELEMENT dfn %Inline;> <!-- definitional -->
-<!ATTLIST dfn %attrs;>
-
-<!ELEMENT code %Inline;> <!-- program code -->
-<!ATTLIST code %attrs;>
-
-<!ELEMENT samp %Inline;> <!-- sample -->
-<!ATTLIST samp %attrs;>
-
-<!ELEMENT kbd %Inline;> <!-- something user would type -->
-<!ATTLIST kbd %attrs;>
-
-<!ELEMENT var %Inline;> <!-- variable -->
-<!ATTLIST var %attrs;>
-
-<!ELEMENT cite %Inline;> <!-- citation -->
-<!ATTLIST cite %attrs;>
-
-<!ELEMENT abbr %Inline;> <!-- abbreviation -->
-<!ATTLIST abbr %attrs;>
-
-<!ELEMENT acronym %Inline;> <!-- acronym -->
-<!ATTLIST acronym %attrs;>
-
-<!ELEMENT q %Inline;> <!-- inlined quote -->
-<!ATTLIST q
- %attrs;
- cite %URI; #IMPLIED
- >
-
-<!ELEMENT sub %Inline;> <!-- subscript -->
-<!ATTLIST sub %attrs;>
-
-<!ELEMENT sup %Inline;> <!-- superscript -->
-<!ATTLIST sup %attrs;>
-
-<!ELEMENT tt %Inline;> <!-- fixed pitch font -->
-<!ATTLIST tt %attrs;>
-
-<!ELEMENT i %Inline;> <!-- italic font -->
-<!ATTLIST i %attrs;>
-
-<!ELEMENT b %Inline;> <!-- bold font -->
-<!ATTLIST b %attrs;>
-
-<!ELEMENT big %Inline;> <!-- bigger font -->
-<!ATTLIST big %attrs;>
-
-<!ELEMENT small %Inline;> <!-- smaller font -->
-<!ATTLIST small %attrs;>
-
-<!--==================== Object ======================================-->
-<!--
- object is used to embed objects as part of HTML pages.
- param elements should precede other content. Parameters
- can also be expressed as attribute/value pairs on the
- object element itself when brevity is desired.
--->
-
-<!ELEMENT object (#PCDATA | param | %block; | form | %inline; | %misc;)*>
-<!ATTLIST object
- %attrs;
- declare (declare) #IMPLIED
- classid %URI; #IMPLIED
- codebase %URI; #IMPLIED
- data %URI; #IMPLIED
- type %ContentType; #IMPLIED
- codetype %ContentType; #IMPLIED
- archive %UriList; #IMPLIED
- standby %Text; #IMPLIED
- height %Length; #IMPLIED
- width %Length; #IMPLIED
- usemap %URI; #IMPLIED
- name NMTOKEN #IMPLIED
- tabindex %Number; #IMPLIED
- >
-
-<!--
- param is used to supply a named property value.
- In XML it would seem natural to follow RDF and support an
- abbreviated syntax where the param elements are replaced
- by attribute value pairs on the object start tag.
--->
-<!ELEMENT param EMPTY>
-<!ATTLIST param
- id ID #IMPLIED
- name CDATA #IMPLIED
- value CDATA #IMPLIED
- valuetype (data|ref|object) "data"
- type %ContentType; #IMPLIED
- >
-
-<!--=================== Images ===========================================-->
-
-<!--
- To avoid accessibility problems for people who aren't
- able to see the image, you should provide a text
- description using the alt and longdesc attributes.
- In addition, avoid the use of server-side image maps.
- Note that in this DTD there is no name attribute. That
- is only available in the transitional and frameset DTD.
--->
-
-<!ELEMENT img EMPTY>
-<!ATTLIST img
- %attrs;
- src %URI; #REQUIRED
- alt %Text; #REQUIRED
- longdesc %URI; #IMPLIED
- height %Length; #IMPLIED
- width %Length; #IMPLIED
- usemap %URI; #IMPLIED
- ismap (ismap) #IMPLIED
- >
-
-<!-- usemap points to a map element which may be in this document
- or an external document, although the latter is not widely supported -->
-
-<!--================== Client-side image maps ============================-->
-
-<!-- These can be placed in the same document or grouped in a
- separate document although this isn't yet widely supported -->
-
-<!ELEMENT map ((%block; | form | %misc;)+ | area+)>
-<!ATTLIST map
- %i18n;
- %events;
- id ID #REQUIRED
- class CDATA #IMPLIED
- style %StyleSheet; #IMPLIED
- title %Text; #IMPLIED
- name NMTOKEN #IMPLIED
- >
-
-<!ELEMENT area EMPTY>
-<!ATTLIST area
- %attrs;
- %focus;
- shape %Shape; "rect"
- coords %Coords; #IMPLIED
- href %URI; #IMPLIED
- nohref (nohref) #IMPLIED
- alt %Text; #REQUIRED
- >
-
-<!--================ Forms ===============================================-->
-<!ELEMENT form %form.content;> <!-- forms shouldn't be nested -->
-
-<!ATTLIST form
- %attrs;
- action %URI; #REQUIRED
- method (get|post) "get"
- enctype %ContentType; "application/x-www-form-urlencoded"
- onsubmit %Script; #IMPLIED
- onreset %Script; #IMPLIED
- accept %ContentTypes; #IMPLIED
- accept-charset %Charsets; #IMPLIED
- >
-
-<!--
- Each label must not contain more than ONE field
- Label elements shouldn't be nested.
--->
-<!ELEMENT label %Inline;>
-<!ATTLIST label
- %attrs;
- for IDREF #IMPLIED
- accesskey %Character; #IMPLIED
- onfocus %Script; #IMPLIED
- onblur %Script; #IMPLIED
- >
-
-<!ENTITY % InputType
- "(text | password | checkbox |
- radio | submit | reset |
- file | hidden | image | button)"
- >
-
-<!-- the name attribute is required for all but submit & reset -->
-
-<!ELEMENT input EMPTY> <!-- form control -->
-<!ATTLIST input
- %attrs;
- %focus;
- type %InputType; "text"
- name CDATA #IMPLIED
- value CDATA #IMPLIED
- checked (checked) #IMPLIED
- disabled (disabled) #IMPLIED
- readonly (readonly) #IMPLIED
- size CDATA #IMPLIED
- maxlength %Number; #IMPLIED
- src %URI; #IMPLIED
- alt CDATA #IMPLIED
- usemap %URI; #IMPLIED
- onselect %Script; #IMPLIED
- onchange %Script; #IMPLIED
- accept %ContentTypes; #IMPLIED
- >
-
-<!ELEMENT select (optgroup|option)+> <!-- option selector -->
-<!ATTLIST select
- %attrs;
- name CDATA #IMPLIED
- size %Number; #IMPLIED
- multiple (multiple) #IMPLIED
- disabled (disabled) #IMPLIED
- tabindex %Number; #IMPLIED
- onfocus %Script; #IMPLIED
- onblur %Script; #IMPLIED
- onchange %Script; #IMPLIED
- >
-
-<!ELEMENT optgroup (option)+> <!-- option group -->
-<!ATTLIST optgroup
- %attrs;
- disabled (disabled) #IMPLIED
- label %Text; #REQUIRED
- >
-
-<!ELEMENT option (#PCDATA)> <!-- selectable choice -->
-<!ATTLIST option
- %attrs;
- selected (selected) #IMPLIED
- disabled (disabled) #IMPLIED
- label %Text; #IMPLIED
- value CDATA #IMPLIED
- >
-
-<!ELEMENT textarea (#PCDATA)> <!-- multi-line text field -->
-<!ATTLIST textarea
- %attrs;
- %focus;
- name CDATA #IMPLIED
- rows %Number; #REQUIRED
- cols %Number; #REQUIRED
- disabled (disabled) #IMPLIED
- readonly (readonly) #IMPLIED
- onselect %Script; #IMPLIED
- onchange %Script; #IMPLIED
- >
-
-<!--
- The fieldset element is used to group form fields.
- Only one legend element should occur in the content
- and if present should only be preceded by whitespace.
--->
-<!ELEMENT fieldset (#PCDATA | legend | %block; | form | %inline; | %misc;)*>
-<!ATTLIST fieldset
- %attrs;
- >
-
-<!ELEMENT legend %Inline;> <!-- fieldset label -->
-<!ATTLIST legend
- %attrs;
- accesskey %Character; #IMPLIED
- >
-
-<!--
- Content is %Flow; excluding a, form and form controls
--->
-<!ELEMENT button %button.content;> <!-- push button -->
-<!ATTLIST button
- %attrs;
- %focus;
- name CDATA #IMPLIED
- value CDATA #IMPLIED
- type (button|submit|reset) "submit"
- disabled (disabled) #IMPLIED
- >
-
-<!--======================= Tables =======================================-->
-
-<!-- Derived from IETF HTML table standard, see [RFC1942] -->
-
-<!--
- The border attribute sets the thickness of the frame around the
- table. The default units are screen pixels.
-
- The frame attribute specifies which parts of the frame around
- the table should be rendered. The values are not the same as
- CALS to avoid a name clash with the valign attribute.
--->
-<!ENTITY % TFrame "(void|above|below|hsides|lhs|rhs|vsides|box|border)">
-
-<!--
- The rules attribute defines which rules to draw between cells:
-
- If rules is absent then assume:
- "none" if border is absent or border="0" otherwise "all"
--->
-
-<!ENTITY % TRules "(none | groups | rows | cols | all)">
-
-<!-- horizontal alignment attributes for cell contents
-
- char alignment char, e.g. char=':'
- charoff offset for alignment char
--->
-<!ENTITY % cellhalign
- "align (left|center|right|justify|char) #IMPLIED
- char %Character; #IMPLIED
- charoff %Length; #IMPLIED"
- >
-
-<!-- vertical alignment attributes for cell contents -->
-<!ENTITY % cellvalign
- "valign (top|middle|bottom|baseline) #IMPLIED"
- >
-
-<!ELEMENT table
- (caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))>
-<!ELEMENT caption %Inline;>
-<!ELEMENT thead (tr)+>
-<!ELEMENT tfoot (tr)+>
-<!ELEMENT tbody (tr)+>
-<!ELEMENT colgroup (col)*>
-<!ELEMENT col EMPTY>
-<!ELEMENT tr (th|td)+>
-<!ELEMENT th %Flow;>
-<!ELEMENT td %Flow;>
-
-<!ATTLIST table
- %attrs;
- summary %Text; #IMPLIED
- width %Length; #IMPLIED
- border %Pixels; #IMPLIED
- frame %TFrame; #IMPLIED
- rules %TRules; #IMPLIED
- cellspacing %Length; #IMPLIED
- cellpadding %Length; #IMPLIED
- >
-
-<!ATTLIST caption
- %attrs;
- >
-
-<!--
-colgroup groups a set of col elements. It allows you to group
-several semantically related columns together.
--->
-<!ATTLIST colgroup
- %attrs;
- span %Number; "1"
- width %MultiLength; #IMPLIED
- %cellhalign;
- %cellvalign;
- >
-
-<!--
- col elements define the alignment properties for cells in
- one or more columns.
-
- The width attribute specifies the width of the columns, e.g.
-
- width=64 width in screen pixels
- width=0.5* relative width of 0.5
-
- The span attribute causes the attributes of one
- col element to apply to more than one column.
--->
-<!ATTLIST col
- %attrs;
- span %Number; "1"
- width %MultiLength; #IMPLIED
- %cellhalign;
- %cellvalign;
- >
-
-<!--
- Use thead to duplicate headers when breaking table
- across page boundaries, or for static headers when
- tbody sections are rendered in scrolling panel.
-
- Use tfoot to duplicate footers when breaking table
- across page boundaries, or for static footers when
- tbody sections are rendered in scrolling panel.
-
- Use multiple tbody sections when rules are needed
- between groups of table rows.
--->
-<!ATTLIST thead
- %attrs;
- %cellhalign;
- %cellvalign;
- >
-
-<!ATTLIST tfoot
- %attrs;
- %cellhalign;
- %cellvalign;
- >
-
-<!ATTLIST tbody
- %attrs;
- %cellhalign;
- %cellvalign;
- >
-
-<!ATTLIST tr
- %attrs;
- %cellhalign;
- %cellvalign;
- >
-
-
-<!-- Scope is simpler than headers attribute for common tables -->
-<!ENTITY % Scope "(row|col|rowgroup|colgroup)">
-
-<!-- th is for headers, td for data and for cells acting as both -->
-
-<!ATTLIST th
- %attrs;
- abbr %Text; #IMPLIED
- axis CDATA #IMPLIED
- headers IDREFS #IMPLIED
- scope %Scope; #IMPLIED
- rowspan %Number; "1"
- colspan %Number; "1"
- %cellhalign;
- %cellvalign;
- >
-
-<!ATTLIST td
- %attrs;
- abbr %Text; #IMPLIED
- axis CDATA #IMPLIED
- headers IDREFS #IMPLIED
- scope %Scope; #IMPLIED
- rowspan %Number; "1"
- colspan %Number; "1"
- %cellhalign;
- %cellvalign;
- >
diff --git a/bootstrap b/bootstrap
index 9784d5d4e..b3f06a138 100755
--- a/bootstrap
+++ b/bootstrap
@@ -23,6 +23,21 @@ cmake_version_component()
"
}
+# Install destination extraction function.
+cmake_install_dest_default()
+{
+ cat "${cmake_source_dir}/Source/CMakeInstallDestinations.cmake" | sed -n '
+/^ *set(CMAKE_'"${1}"'_DIR_DEFAULT.*) # '"${2}"'$/ {
+ s/^ *set(CMAKE_'"${1}"'_DIR_DEFAULT *"\([^"]*\)").*$/\1/
+ s/${CMake_VERSION_MAJOR}/'"${cmake_version_major}"'/
+ s/${CMake_VERSION_MINOR}/'"${cmake_version_minor}"'/
+ s/${CMake_VERSION_PATCH}/'"${cmake_version_patch}"'/
+ p
+ q
+}
+'
+}
+
cmake_toupper()
{
echo "$1" | sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'
@@ -38,22 +53,36 @@ cmake_version_major="`cmake_version_component MAJOR`"
cmake_version_minor="`cmake_version_component MINOR`"
cmake_version_patch="`cmake_version_component PATCH`"
cmake_version="${cmake_version_major}.${cmake_version_minor}.${cmake_version_patch}"
-cmake_version_tweak="`cmake_version_component TWEAK`"
-if [ "$cmake_version_tweak" != "0" ]; then
- cmake_version="${cmake_version}.${cmake_version_tweak}"
+cmake_version_rc="`cmake_version_component RC`"
+if [ "$cmake_version_rc" != "" ]; then
+ cmake_version="${cmake_version}-rc${cmake_version_rc}"
fi
-cmake_data_dir="share/cmake-${cmake_version_major}.${cmake_version_minor}"
-cmake_doc_dir="doc/cmake-${cmake_version_major}.${cmake_version_minor}"
-cmake_man_dir="man"
+cmake_copyright="`grep '^Copyright .* Kitware' "${cmake_source_dir}/Copyright.txt"`"
+
+cmake_data_dir_keyword="OTHER"
+cmake_doc_dir_keyword="OTHER"
+cmake_man_dir_keyword="OTHER"
+cmake_xdgdata_dir_keyword="OTHER"
+cmake_data_dir=""
+cmake_doc_dir=""
+cmake_man_dir=""
+cmake_xdgdata_dir=""
cmake_init_file=""
cmake_bootstrap_system_libs=""
cmake_bootstrap_qt_gui=""
cmake_bootstrap_qt_qmake=""
+cmake_sphinx_man=""
+cmake_sphinx_html=""
+cmake_sphinx_qthelp=""
+cmake_sphinx_build=""
+cmake_sphinx_flags=""
# Determine whether this is a Cygwin environment.
if echo "${cmake_system}" | grep CYGWIN >/dev/null 2>&1; then
cmake_system_cygwin=true
+ cmake_doc_dir_keyword="CYGWIN"
+ cmake_man_dir_keyword="CYGWIN"
else
cmake_system_cygwin=false
fi
@@ -75,6 +104,8 @@ fi
# Determine whether this is BeOS
if echo "${cmake_system}" | grep BeOS >/dev/null 2>&1; then
cmake_system_beos=true
+ cmake_doc_dir_keyword="HAIKU"
+ cmake_man_dir_keyword="HAIKU"
else
cmake_system_beos=false
fi
@@ -82,6 +113,8 @@ fi
# Determine whether this is Haiku
if echo "${cmake_system}" | grep Haiku >/dev/null 2>&1; then
cmake_system_haiku=true
+ cmake_doc_dir_keyword="HAIKU"
+ cmake_man_dir_keyword="HAIKU"
else
cmake_system_haiku=false
fi
@@ -93,17 +126,32 @@ else
cmake_system_openvms=false
fi
+# Determine whether this is HP-UX
+if echo "${cmake_system}" | grep HP-UX >/dev/null 2>&1; then
+ cmake_system_hpux=true
+else
+ cmake_system_hpux=false
+fi
+
# Determine whether this is Linux
if echo "${cmake_system}" | grep Linux >/dev/null 2>&1; then
cmake_system_linux=true
- # find out if it is a HP PA-RISC machine
+else
+ cmake_system_linux=false
+ fi
+
+# Determine whether this is a PA-RISC machine
+# This only works for Linux or HP-UX, not other PA-RISC OSs (BSD maybe?). Also
+# may falsely detect parisc on HP-UX m68k
+cmake_machine_parisc=false
+if ${cmake_system_linux}; then
if uname -m | grep parisc >/dev/null 2>&1; then
cmake_machine_parisc=true
- else
- cmake_machine_parisc=false
fi
-else
- cmake_system_linux=false
+elif ${cmake_system_hpux}; then
+ if uname -m | grep ia64 >/dev/null 2>&1; then : ; else
+ cmake_machine_parisc=true
+ fi
fi
# Choose the generator to use for bootstrapping.
@@ -160,12 +208,16 @@ if ${cmake_system_mingw}; then
fi
elif ${cmake_system_haiku}; then
cmake_default_prefix=`finddir B_COMMON_DIRECTORY`
- cmake_man_dir="documentation/man"
- cmake_doc_dir="documentation/doc/cmake-${cmake_version}"
else
cmake_default_prefix="/usr/local"
fi
+# Lookup default install destinations.
+cmake_data_dir_default="`cmake_install_dest_default DATA ${cmake_data_dir_keyword}`"
+cmake_doc_dir_default="`cmake_install_dest_default DOC ${cmake_doc_dir_keyword}`"
+cmake_man_dir_default="`cmake_install_dest_default MAN ${cmake_man_dir_keyword}`"
+cmake_xdgdata_dir_default="`cmake_install_dest_default XDGDATA ${cmake_xdgdata_dir_keyword}`"
+
CMAKE_KNOWN_C_COMPILERS="cc gcc xlc icc tcc"
CMAKE_KNOWN_CXX_COMPILERS="aCC xlC CC g++ c++ icc como "
CMAKE_KNOWN_MAKE_PROCESSORS="gmake make"
@@ -193,40 +245,47 @@ CMAKE_UNUSED_SOURCES="\
"
CMAKE_CXX_SOURCES="\
- cmStandardIncludes \
cmake \
cmakemain \
- cmakewizard \
+ cmcmd \
cmCommandArgumentLexer \
cmCommandArgumentParser \
cmCommandArgumentParserHelper \
+ cmCommonTargetGenerator \
+ cmCPackPropertiesGenerator \
cmDefinitions \
cmDepends \
cmDependsC \
cmDocumentationFormatter \
- cmDocumentationFormatterText \
cmPolicies \
cmProperty \
cmPropertyMap \
cmPropertyDefinition \
cmPropertyDefinitionMap \
- cmMakeDepend \
cmMakefile \
+ cmExportBuildFileGenerator \
cmExportFileGenerator \
cmExportInstallFileGenerator \
cmExportTryCompileFileGenerator \
cmExportSet \
cmExportSetMap \
- cmInstallDirectoryGenerator \
+ cmExternalMakefileProjectGenerator \
+ cmGeneratorExpressionEvaluationFile \
cmGeneratedFileStream \
cmGeneratorTarget \
+ cmGeneratorExpressionContext \
cmGeneratorExpressionDAGChecker \
cmGeneratorExpressionEvaluator \
cmGeneratorExpressionLexer \
+ cmGeneratorExpressionNode \
cmGeneratorExpressionParser \
cmGeneratorExpression \
+ cmGlobalCommonGenerator \
cmGlobalGenerator \
+ cmInstallDirectoryGenerator \
+ cmLocalCommonGenerator \
cmLocalGenerator \
+ cmInstalledFile \
cmInstallGenerator \
cmInstallExportGenerator \
cmInstallFilesGenerator \
@@ -235,6 +294,7 @@ CMAKE_CXX_SOURCES="\
cmScriptGenerator \
cmSourceFile \
cmSourceFileLocation \
+ cmState \
cmSystemTools \
cmTestGenerator \
cmVersion \
@@ -245,16 +305,16 @@ CMAKE_CXX_SOURCES="\
cmMakefileLibraryTargetGenerator \
cmMakefileTargetGenerator \
cmMakefileUtilityTargetGenerator \
+ cmOutputConverter \
cmOSXBundleGenerator \
cmNewLineStyle \
cmBootstrapCommands1 \
cmBootstrapCommands2 \
- cmCommands \
+ cmCommandsForBootstrap \
cmTarget \
cmTest \
cmCustomCommand \
cmCustomCommandGenerator \
- cmDocumentVariables \
cmCacheManager \
cmListFileCache \
cmComputeLinkDepends \
@@ -265,18 +325,12 @@ CMAKE_CXX_SOURCES="\
cmExprLexer \
cmExprParser \
cmExprParserHelper \
- cmGlobalNinjaGenerator \
- cmLocalNinjaGenerator \
- cmNinjaTargetGenerator \
- cmNinjaNormalTargetGenerator \
- cmNinjaUtilityTargetGenerator \
"
if ${cmake_system_mingw}; then
CMAKE_CXX_SOURCES="${CMAKE_CXX_SOURCES}\
cmGlobalMSYSMakefileGenerator \
- cmGlobalMinGWMakefileGenerator \
- cmWin32ProcessExecution"
+ cmGlobalMinGWMakefileGenerator"
fi
CMAKE_C_SOURCES="\
@@ -285,18 +339,24 @@ CMAKE_C_SOURCES="\
if ${cmake_system_mingw}; then
KWSYS_C_SOURCES="\
+ EncodingC \
ProcessWin32 \
String \
- System"
+ System \
+ Terminal"
else
KWSYS_C_SOURCES="\
+ EncodingC \
ProcessUNIX \
String \
- System"
+ System \
+ Terminal"
fi
KWSYS_CXX_SOURCES="\
Directory \
+ EncodingCXX \
+ FStream \
Glob \
RegularExpression \
SystemTools"
@@ -304,19 +364,17 @@ KWSYS_CXX_SOURCES="\
KWSYS_FILES="\
auto_ptr.hxx \
Directory.hxx \
+ Encoding.h \
+ Encoding.hxx \
+ FStream.hxx \
Glob.hxx \
Process.h \
RegularExpression.hxx \
String.h \
String.hxx \
System.h \
- SystemTools.hxx"
-
-KWSYS_IOS_FILES="
- fstream \
- iosfwd \
- iostream \
- sstream"
+ SystemTools.hxx \
+ Terminal.h"
# Display CMake bootstrap usage
cmake_usage()
@@ -340,10 +398,14 @@ Configuration:
--no-system-curl use cmake-provided curl library (default)
--system-expat use system-installed expat library
--no-system-expat use cmake-provided expat library (default)
+ --system-jsoncpp use system-installed jsoncpp library
+ --no-system-jsoncpp use cmake-provided jsoncpp library (default)
--system-zlib use system-installed zlib library
--no-system-zlib use cmake-provided zlib library (default)
--system-bzip2 use system-installed bzip2 library
--no-system-bzip2 use cmake-provided bzip2 library (default)
+ --system-liblzma use system-installed liblzma library
+ --no-system-liblzma use cmake-provided liblzma library (default)
--system-libarchive use system-installed libarchive library
--no-system-libarchive use cmake-provided libarchive library (default)
@@ -351,15 +413,23 @@ Configuration:
--no-qt-gui do not build the Qt-based GUI (default)
--qt-qmake=<qmake> use <qmake> as the qmake executable to find Qt
+ --sphinx-man build man pages with Sphinx
+ --sphinx-html build html help with Sphinx
+ --sphinx-qthelp build qch help with Sphinx
+ --sphinx-build=<sb> use <sb> as the sphinx-build executable
+ --sphinx-flags=<flags> pass <flags> to sphinx-build executable
+
Directory and file names:
--prefix=PREFIX install files in tree rooted at PREFIX
['"${cmake_default_prefix}"']
--datadir=DIR install data files in PREFIX/DIR
- ['"${cmake_data_dir}"']
+ ['"${cmake_data_dir_default}"']
--docdir=DIR install documentation files in PREFIX/DIR
- ['"${cmake_doc_dir}"']
+ ['"${cmake_doc_dir_default}"']
--mandir=DIR install man pages files in PREFIX/DIR/manN
- ['"${cmake_man_dir}"']
+ ['"${cmake_man_dir_default}"']
+ --xdgdatadir=DIR install XDG specific files in PREFIX/DIR
+ ['"${cmake_xdgdata_dir_default}"']
'
exit 10
}
@@ -367,7 +437,7 @@ Directory and file names:
# Display CMake bootstrap usage
cmake_version_display()
{
- echo "CMake ${cmake_version}, Copyright 2000-2012 Kitware, Inc."
+ echo "CMake ${cmake_version}, ${cmake_copyright}"
}
# Display CMake bootstrap error, display the log file and exit
@@ -387,6 +457,18 @@ cmake_error()
exit ${res}
}
+cmake_generate_file ()
+{
+ OUTFILE="$1"
+ CONTENT="$2"
+ echo "$CONTENT" > "$OUTFILE.tmp"
+ if "${_diff}" "$OUTFILE.tmp" "$OUTFILE" > /dev/null 2> /dev/null ; then
+ rm -f "$OUTFILE.tmp"
+ else
+ mv -f "$OUTFILE.tmp" "$OUTFILE"
+ fi
+}
+
# Replace KWSYS_NAMESPACE with cmsys
cmake_replace_string ()
{
@@ -424,30 +506,8 @@ cmake_kwsys_config_replace_string ()
s/@KWSYS_LFS_AVAILABLE@/${KWSYS_LFS_AVAILABLE}/g;
s/@KWSYS_LFS_REQUESTED@/${KWSYS_LFS_REQUESTED}/g;
s/@KWSYS_NAME_IS_KWSYS@/${KWSYS_NAME_IS_KWSYS}/g;
- s/@KWSYS_IOS_USE_ANSI@/${KWSYS_IOS_USE_ANSI}/g;
- s/@KWSYS_IOS_HAVE_STD@/${KWSYS_IOS_HAVE_STD}/g;
- s/@KWSYS_IOS_USE_SSTREAM@/${KWSYS_IOS_USE_SSTREAM}/g;
- s/@KWSYS_IOS_USE_STRSTREAM_H@/${KWSYS_IOS_USE_STRSTREAM_H}/g;
- s/@KWSYS_IOS_USE_STRSTREA_H@/${KWSYS_IOS_USE_STRSTREA_H}/g;
- s/@KWSYS_IOS_HAVE_BINARY@/${KWSYS_IOS_HAVE_BINARY}/g;
- s/@KWSYS_STL_HAVE_STD@/${KWSYS_STL_HAVE_STD}/g;
- s/@KWSYS_STL_STRING_HAVE_ISTREAM@/${KWSYS_STL_STRING_HAVE_ISTREAM}/g;
- s/@KWSYS_STL_STRING_HAVE_OSTREAM@/${KWSYS_STL_STRING_HAVE_OSTREAM}/g;
- s/@KWSYS_STL_STRING_HAVE_NEQ_CHAR@/${KWSYS_STL_STRING_HAVE_NEQ_CHAR}/g;
- s/@KWSYS_STL_HAS_ITERATOR_TRAITS@/${KWSYS_STL_HAS_ITERATOR_TRAITS}/g;
- s/@KWSYS_STL_HAS_ITERATOR_CATEGORY@/${KWSYS_STL_HAS_ITERATOR_CATEGORY}/g;
- s/@KWSYS_STL_HAS___ITERATOR_CATEGORY@/${KWSYS_STL_HAS___ITERATOR_CATEGORY}/g;
- s/@KWSYS_STL_HAS_ALLOCATOR_TEMPLATE@/${KWSYS_STL_HAS_ALLOCATOR_TEMPLATE}/g;
- s/@KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE@/${KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE}/g;
- s/@KWSYS_STL_HAS_ALLOCATOR_REBIND@/${KWSYS_STL_HAS_ALLOCATOR_REBIND}/g;
- s/@KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT@/${KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT}/g;
- s/@KWSYS_STL_HAS_ALLOCATOR_OBJECTS@/${KWSYS_STL_HAS_ALLOCATOR_OBJECTS}/g;
- s/@KWSYS_CXX_HAS_CSTDDEF@/${KWSYS_CXX_HAS_CSTDDEF}/g;
- s/@KWSYS_CXX_HAS_NULL_TEMPLATE_ARGS@/${KWSYS_CXX_HAS_NULL_TEMPLATE_ARGS}/g;
- s/@KWSYS_CXX_HAS_MEMBER_TEMPLATES@/${KWSYS_CXX_HAS_MEMBER_TEMPLATES}/g;
- s/@KWSYS_CXX_HAS_FULL_SPECIALIZATION@/${KWSYS_CXX_HAS_FULL_SPECIALIZATION}/g;
- s/@KWSYS_CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP@/${KWSYS_CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP}/g;
- s/@KWSYS_STAT_HAS_ST_MTIM@/${KWSYS_STAT_HAS_ST_MTIM}/g;}" >> "${OUTFILE}${_tmp}"
+ s/@KWSYS_STL_HAS_WSTRING@/${KWSYS_STL_HAS_WSTRING}/g;
+ }" >> "${OUTFILE}${_tmp}"
if [ -f "${OUTFILE}${_tmp}" ]; then
if "${_diff}" "${OUTFILE}" "${OUTFILE}${_tmp}" > /dev/null 2> /dev/null ; then
#echo "Files are the same"
@@ -526,7 +586,7 @@ cmake_try_run ()
echo "Test produced non-zero return code"
return 3
fi
- echo "Test succeded"
+ echo "Test succeeded"
return 0
}
@@ -570,18 +630,24 @@ while test $# != 0; do
--datadir=*) cmake_data_dir=`cmake_arg "$1"` ;;
--docdir=*) cmake_doc_dir=`cmake_arg "$1"` ;;
--mandir=*) cmake_man_dir=`cmake_arg "$1"` ;;
+ --xdgdatadir=*) cmake_xdgdata_dir=`cmake_arg "$1"` ;;
--init=*) cmake_init_file=`cmake_arg "$1"` ;;
--system-libs) cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARIES=1" ;;
--no-system-libs) cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARIES=0" ;;
- --system-bzip2|--system-curl|--system-expat|--system-libarchive|--system-zlib)
+ --system-bzip2|--system-curl|--system-expat|--system-jsoncpp|--system-libarchive|--system-zlib|--system-liblzma)
lib=`cmake_arg "$1" "--system-"`
cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARY_`cmake_toupper $lib`=1" ;;
- --no-system-bzip2|--no-system-curl|--no-system-expat|--no-system-libarchive|--no-system-zlib)
+ --no-system-bzip2|--no-system-curl|--no-system-expat|--no-system-jsoncpp|--no-system-libarchive|--no-system-zlib|--no-system-liblzma)
lib=`cmake_arg "$1" "--no-system-"`
cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARY_`cmake_toupper $lib`=0" ;;
--qt-gui) cmake_bootstrap_qt_gui="1" ;;
--no-qt-gui) cmake_bootstrap_qt_gui="0" ;;
--qt-qmake=*) cmake_bootstrap_qt_qmake=`cmake_arg "$1"` ;;
+ --sphinx-man) cmake_sphinx_man="1" ;;
+ --sphinx-html) cmake_sphinx_html="1" ;;
+ --sphinx-qthelp) cmake_sphinx_qthelp="1" ;;
+ --sphinx-build=*) cmake_sphinx_build=`cmake_arg "$1"` ;;
+ --sphinx-flags=*) cmake_sphinx_flags=`cmake_arg "$1"` ;;
--help) cmake_usage ;;
--version) cmake_version_display ; exit 2 ;;
--verbose) cmake_verbose=TRUE ;;
@@ -651,13 +717,6 @@ if [ ! -d "cmsys" ]; then
cmake_error 4 "Cannot create directory ${cmake_bootstrap_dir}/cmsys"
fi
-for a in stl ios; do
- [ -d "cmsys/${a}" ] || mkdir "cmsys/${a}"
- if [ ! -d "cmsys/${a}" ]; then
- cmake_error 5 "Cannot create directory ${cmake_bootstrap_dir}/cmsys/${a}"
- fi
-done
-
# Delete all the bootstrap files
rm -f "${cmake_bootstrap_dir}/cmake_bootstrap.log"
rm -f "${cmake_bootstrap_dir}/cmConfigure.h${_tmp}"
@@ -688,14 +747,13 @@ if ${cmake_system_haiku}; then
cmake_ld_flags="${LDFLAGS} -lroot -lbe"
fi
-if ${cmake_system_linux}; then
- # avoid binutils problem with large binaries, e.g. when building CMake in debug mode
- # See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50230
- if ${cmake_machine_parisc}; then
- # if -O[s23] is given the effect is inverted, so do not use the flag then
- if [ "`echo "${CXXFLAGS}" | sed -r '/^(.* )?(-O[s234])( .*)?$/s/.*/-Os/'`" != "-Os" ]; then
- cmake_ld_flags="${LDFLAGS} -Wl,--unique=.text.*"
- fi
+# Workaround for short jump tables on PA-RISC
+if ${cmake_machine_parisc}; then
+ if ${cmake_c_compiler_is_gnu}; then
+ cmake_c_flags="${CFLAGS} -mlong-calls"
+ fi
+ if ${cmake_cxx_compiler_is_gnu}; then
+ cmake_cxx_flags="${CXXFLAGS} -mlong-calls"
fi
fi
@@ -1035,8 +1093,8 @@ if [ "x${cmake_cxx_compiler_is_gnu}" != "x1" ]; then
cmake_test_flags=
# If we are on HP-UX, check for -Ae for the C compiler.
- cmake_test_flags="-Ae"
if [ "x${cmake_system}" = "xHP-UX" ]; then
+ cmake_test_flags="-Ae"
TMPFILE=`cmake_tmp_file`
echo '
int main(int argc, char** argv) { (void)argc; (void)argv; return 0; }
@@ -1057,46 +1115,73 @@ if [ "x${cmake_cxx_compiler_is_gnu}" != "x1" ]; then
echo "${cmake_c_compiler} does not need ${cmake_test_flags}"
fi
rm -f "${TMPFILE}.c"
+ echo '
+ #include <iostream>
+ int main(int argc, char** argv) {
+ for(int i=0; i < 1; ++i);
+ for(int i=0; i < 1; ++i);
+ (void)argc; (void)argv; return 0; }
+' > ${TMPFILE}.cxx
+ cmake_need_AAstd98=0
+ cmake_test_flags="-AA +hpxstd98"
+ if cmake_try_run "${cmake_cxx_compiler}" "${cmake_cxx_flags}" "${TMPFILE}.cxx" >> cmake_bootstrap.log 2>&1; then
+ :
+ else
+ if cmake_try_run "${cmake_cxx_compiler}" \
+ "${cmake_cxx_flags} ${cmake_test_flags}" "${TMPFILE}.cxx" >> cmake_bootstrap.log 2>&1; then
+ cmake_need_AAstd98=1
+ fi
+ fi
+ if [ "x${cmake_need_AAstd98}" = "x1" ]; then
+ cmake_cxx_flags="${cmake_cxx_flags} ${cmake_test_flags}"
+ echo "${cmake_cxx_compiler} needs ${cmake_test_flags}"
+ else
+ echo "${cmake_cxx_compiler} does not need ${cmake_test_flags}"
+ fi
fi
cmake_test_flags=
fi
+
+if [ "x${cmake_cxx_compiler_is_gnu}" != "x1" ]; then
+ # Are we SolarisStudio?
+
+ TMPFILE=`cmake_tmp_file`
+ echo '
+ #if defined(__SUNPRO_CC)
+ #include <iostream>
+ int main() { std::cout << "This is SolarisStudio" << std::endl; return 0;}
+ #endif
+ ' > ${TMPFILE}.cxx
+ cmake_cxx_compiler_is_solarisstudio=0
+ if cmake_try_run "${cmake_cxx_compiler}" \
+ "${cmake_cxx_flags} " "${TMPFILE}.cxx" >> cmake_bootstrap.log 2>&1; then
+ cmake_cxx_compiler_is_solarisstudio=1
+ fi
+ if [ "x${cmake_cxx_compiler_is_solarisstudio}" = "x1" ]; then
+ echo "${cmake_cxx_compiler} is SolarisStudio compiler"
+ else
+ echo "${cmake_cxx_compiler} is not SolarisStudio compiler"
+ fi
+ rm -f "${TMPFILE}.cxx"
+
+ if [ "x${cmake_cxx_compiler_is_solarisstudio}" = "x1" ]; then
+ cmake_cxx_flags="${cmake_cxx_flags} -library=stlport4"
+ fi
+fi
+
+
# Test for kwsys features
KWSYS_NAME_IS_KWSYS=0
KWSYS_BUILD_SHARED=0
KWSYS_LFS_AVAILABLE=0
KWSYS_LFS_REQUESTED=0
-KWSYS_IOS_USE_STRSTREAM_H=0
-KWSYS_IOS_USE_STRSTREA_H=0
-KWSYS_IOS_HAVE_STD=0
-KWSYS_IOS_USE_SSTREAM=0
-KWSYS_IOS_USE_ANSI=0
-KWSYS_IOS_HAVE_BINARY=0
-KWSYS_STL_HAVE_STD=0
-KWSYS_STAT_HAS_ST_MTIM=0
-KWSYS_STL_STRING_HAVE_NEQ_CHAR=0
-KWSYS_STL_HAS_ITERATOR_TRAITS=0
-KWSYS_STL_HAS_ITERATOR_CATEGORY=0
-KWSYS_STL_HAS___ITERATOR_CATEGORY=0
-KWSYS_STL_HAS_ALLOCATOR_TEMPLATE=0
-KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE=0
-KWSYS_STL_HAS_ALLOCATOR_REBIND=0
-KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT=0
-KWSYS_STL_HAS_ALLOCATOR_OBJECTS=0
+KWSYS_STL_HAS_WSTRING=0
KWSYS_CXX_HAS_SETENV=0
KWSYS_CXX_HAS_UNSETENV=0
KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H=0
KWSYS_CXX_HAS_UTIMENSAT=0
KWSYS_CXX_HAS_UTIMES=0
-KWSYS_CXX_HAS_CSTDDEF=0
-KWSYS_CXX_HAS_NULL_TEMPLATE_ARGS=0
-KWSYS_CXX_HAS_MEMBER_TEMPLATES=0
-KWSYS_CXX_HAS_FULL_SPECIALIZATION=0
-KWSYS_CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP=0
-
-# Hardcode these kwsys features. They work on all known UNIX compilers anyway.
-KWSYS_STL_STRING_HAVE_ISTREAM=1
-KWSYS_STL_STRING_HAVE_OSTREAM=1
if cmake_try_run "${cmake_cxx_compiler}" \
"${cmake_cxx_flags} -DTEST_KWSYS_CXX_HAS_SETENV" \
@@ -1126,210 +1211,12 @@ else
fi
if cmake_try_run "${cmake_cxx_compiler}" \
- "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAVE_STD" \
+ "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAS_WSTRING" \
"${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
- KWSYS_STL_HAVE_STD=1
- echo "${cmake_cxx_compiler} has STL in std:: namespace"
+ KWSYS_STL_HAS_WSTRING=1
+ echo "${cmake_cxx_compiler} has stl wstring"
else
- echo "${cmake_cxx_compiler} does not have STL in std:: namespace"
-fi
-
-if cmake_try_run "${cmake_cxx_compiler}" \
- "${cmake_cxx_flags} -DTEST_KWSYS_IOS_USE_ANSI" \
- "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
- KWSYS_IOS_USE_ANSI=1
- echo "${cmake_cxx_compiler} has ANSI streams"
-else
- echo "${cmake_cxx_compiler} does not have ANSI streams"
-fi
-
-if [ "x$KWSYS_IOS_USE_ANSI" = "x1" ]; then
- if cmake_try_run "${cmake_cxx_compiler}" \
- "${cmake_cxx_flags} -DTEST_KWSYS_IOS_HAVE_STD" \
- "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
- KWSYS_IOS_HAVE_STD=1
- echo "${cmake_cxx_compiler} has streams in std:: namespace"
- else
- echo "${cmake_cxx_compiler} does not have streams in std:: namespace"
- fi
- if cmake_try_run "${cmake_cxx_compiler}" \
- "${cmake_cxx_flags} -DTEST_KWSYS_IOS_USE_SSTREAM" \
- "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
- KWSYS_IOS_USE_SSTREAM=1
- echo "${cmake_cxx_compiler} has sstream"
- else
- echo "${cmake_cxx_compiler} does not have sstream"
- fi
-fi
-
-if [ "x$KWSYS_IOS_USE_SSTREAM" = "x0" ]; then
- if cmake_try_run "${cmake_cxx_compiler}" \
- "${cmake_cxx_flags} -DTEST_KWSYS_IOS_USE_STRSTREAM_H" \
- "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
- KWSYS_IOS_USE_STRSTREAM_H=1
- echo "${cmake_cxx_compiler} has strstream.h"
- else
- echo "${cmake_cxx_compiler} does not have strstream.h"
- fi
- if [ "x$KWSYS_IOS_USE_STRSTREAM_H" = "x0" ]; then
- if cmake_try_run "${cmake_cxx_compiler}" \
- "${cmake_cxx_flags} -DTEST_KWSYS_IOS_USE_STRSTREA_H" \
- "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
- KWSYS_IOS_USE_STRSTREA_H=1
- echo "${cmake_cxx_compiler} has strstrea.h"
- else
- echo "${cmake_cxx_compiler} does not have strstrea.h"
- fi
- fi
-fi
-
-if cmake_try_run "${cmake_cxx_compiler}" \
- "${cmake_cxx_flags} -DTEST_KWSYS_STL_STRING_HAVE_NEQ_CHAR -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD}" \
- "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
- KWSYS_STL_STRING_HAVE_NEQ_CHAR=1
- echo "${cmake_cxx_compiler} has operator!=(string, char*)"
-else
- echo "${cmake_cxx_compiler} does not have operator!=(string, char*)"
-fi
-
-if cmake_try_run "${cmake_cxx_compiler}" \
- "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAS_ITERATOR_TRAITS -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD}" \
- "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
- KWSYS_STL_HAS_ITERATOR_TRAITS=1
- echo "${cmake_cxx_compiler} has stl iterator_traits"
-else
- echo "${cmake_cxx_compiler} does not have stl iterator_traits"
-fi
-
-if [ "x${KWSYS_STL_HAS_ITERATOR_TRAITS}" = "x0" ]; then
- if cmake_try_run "${cmake_cxx_compiler}" \
- "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAS_ITERATOR_CATEGORY -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD}" \
- "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
- KWSYS_STL_HAS_ITERATOR_CATEGORY=1
- echo "${cmake_cxx_compiler} has old iterator_category"
- else
- echo "${cmake_cxx_compiler} does not have old iterator_category"
- fi
- if [ "x${KWSYS_STL_HAS_ITERATOR_CATEGORY}" = "x0" ]; then
- if cmake_try_run "${cmake_cxx_compiler}" \
- "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAS___ITERATOR_CATEGORY -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD}" \
- "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
- KWSYS_STL_HAS___ITERATOR_CATEGORY=1
- echo "${cmake_cxx_compiler} has old __iterator_category"
- else
- echo "${cmake_cxx_compiler} does not have old __iterator_category"
- fi
- fi
-fi
-
-if cmake_try_run "${cmake_cxx_compiler}" \
- "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAS_ALLOCATOR_TEMPLATE -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD}" \
- "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
- KWSYS_STL_HAS_ALLOCATOR_TEMPLATE=1
- echo "${cmake_cxx_compiler} has standard template allocator"
-else
- echo "${cmake_cxx_compiler} does not have standard template allocator"
-fi
-
-if [ "x${KWSYS_STL_HAS_ALLOCATOR_TEMPLATE}" = "x1" ]; then
- if cmake_try_run "${cmake_cxx_compiler}" \
- "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAS_ALLOCATOR_REBIND -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD}" \
- "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
- KWSYS_STL_HAS_ALLOCATOR_REBIND=1
- echo "${cmake_cxx_compiler} has allocator<>::rebind<>"
- else
- echo "${cmake_cxx_compiler} does not have allocator<>::rebind<>"
- fi
-
- if cmake_try_run "${cmake_cxx_compiler}" \
- "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD}" \
- "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
- KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT=1
- echo "${cmake_cxx_compiler} has non-standard allocator<>::max_size argument"
- else
- echo "${cmake_cxx_compiler} does not have non-standard allocator<>::max_size argument"
- fi
-else
- if cmake_try_run "${cmake_cxx_compiler}" \
- "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD}" \
- "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
- KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE=1
- echo "${cmake_cxx_compiler} has old non-template allocator"
- else
- echo "${cmake_cxx_compiler} does not have old non-template allocator"
- fi
-fi
-
-if cmake_try_run "${cmake_cxx_compiler}" \
- "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAS_ALLOCATOR_OBJECTS -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD}" \
- "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
- KWSYS_STL_HAS_ALLOCATOR_OBJECTS=1
- echo "${cmake_cxx_compiler} has stl containers supporting allocator objects"
-else
- echo "${cmake_cxx_compiler} does not have stl containers supporting allocator objects"
-fi
-
-if cmake_try_run "${cmake_cxx_compiler}" \
- "${cmake_cxx_flags} -DTEST_KWSYS_CXX_HAS_CSTDDEF" \
- "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
- KWSYS_CXX_HAS_CSTDDEF=1
- echo "${cmake_cxx_compiler} has header cstddef"
-else
- echo "${cmake_cxx_compiler} does not have header cstddef"
-fi
-
-if cmake_try_run "${cmake_cxx_compiler}" \
- "${cmake_cxx_flags} -DTEST_KWSYS_CXX_HAS_NULL_TEMPLATE_ARGS" \
- "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
- echo "${cmake_cxx_compiler} does not require template friends to use <>"
-else
- KWSYS_CXX_HAS_NULL_TEMPLATE_ARGS=1
- echo "${cmake_cxx_compiler} requires template friends to use <>"
-fi
-
-if cmake_try_run "${cmake_cxx_compiler}" \
- "${cmake_cxx_flags} -DTEST_KWSYS_CXX_HAS_MEMBER_TEMPLATES" \
- "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
- KWSYS_CXX_HAS_MEMBER_TEMPLATES=1
- echo "${cmake_cxx_compiler} supports member templates"
-else
- echo "${cmake_cxx_compiler} does not support member templates"
-fi
-
-if cmake_try_run "${cmake_cxx_compiler}" \
- "${cmake_cxx_flags} -DTEST_KWSYS_CXX_HAS_FULL_SPECIALIZATION" \
- "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
- KWSYS_CXX_HAS_FULL_SPECIALIZATION=1
- echo "${cmake_cxx_compiler} has standard template specialization syntax"
-else
- echo "${cmake_cxx_compiler} does not have standard template specialization syntax"
-fi
-
-if cmake_try_run "${cmake_cxx_compiler}" \
- "${cmake_cxx_flags} -DTEST_KWSYS_CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP" \
- "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
- KWSYS_CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP=1
- echo "${cmake_cxx_compiler} has argument dependent lookup"
-else
- echo "${cmake_cxx_compiler} does not have argument dependent lookup"
-fi
-
-if cmake_try_run "${cmake_cxx_compiler}" \
- "${cmake_cxx_flags} -DTEST_KWSYS_STAT_HAS_ST_MTIM" \
- "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
- KWSYS_STAT_HAS_ST_MTIM=1
- echo "${cmake_cxx_compiler} has struct stat with st_mtim member"
-else
- echo "${cmake_cxx_compiler} does not have struct stat with st_mtim member"
-fi
-
-if cmake_try_run "${cmake_cxx_compiler}" \
- "${cmake_cxx_flags} -DTEST_KWSYS_IOS_HAVE_BINARY -DKWSYS_IOS_USE_ANSI=${KWSYS_IOS_USE_ANSI} -DKWSYS_IOS_HAVE_STD=${KWSYS_IOS_HAVE_STD}" \
- "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
- KWSYS_IOS_HAVE_BINARY=1
- echo "${cmake_cxx_compiler} has ios::binary openmode"
-else
- echo "${cmake_cxx_compiler} does not have ios::binary openmode"
+ echo "${cmake_cxx_compiler} does not have stl wstring"
fi
# Just to be safe, let us store compiler and flags to the header file
@@ -1359,51 +1246,24 @@ cmake_compiler_settings_comment="/*
cmake_report cmConfigure.h${_tmp} "${cmake_compiler_settings_comment}"
-if [ "x$KWSYS_STL_HAVE_STD" = "x1" ]; then
- cmake_report cmConfigure.h${_tmp} "/* #undef CMAKE_NO_STD_NAMESPACE */"
-else
- cmake_report cmConfigure.h${_tmp} "#define CMAKE_NO_STD_NAMESPACE 1"
-fi
-
-if [ "x$KWSYS_IOS_USE_ANSI" = "x1" ]; then
- cmake_report cmConfigure.h${_tmp} "/* #undef CMAKE_NO_ANSI_STREAM_HEADERS */"
-else
- cmake_report cmConfigure.h${_tmp} "#define CMAKE_NO_ANSI_STREAM_HEADERS 1"
-fi
-
-if [ "x$KWSYS_IOS_USE_SSTREAM" = "x1" ]; then
- cmake_report cmConfigure.h${_tmp} "/* #undef CMAKE_NO_ANSI_STRING_STREAM */"
-else
- cmake_report cmConfigure.h${_tmp} "#define CMAKE_NO_ANSI_STRING_STREAM 1"
-fi
-
-# Test for ansi FOR scope
-if cmake_try_run "${cmake_cxx_compiler}" \
- "${cmake_cxx_flags}" \
- "${cmake_source_dir}/Modules/TestForAnsiForScope.cxx" >> cmake_bootstrap.log 2>&1; then
- cmake_report cmConfigure.h${_tmp} "/* #undef CMAKE_NO_ANSI_FOR_SCOPE */"
- echo "${cmake_cxx_compiler} has ANSI for scoping"
-else
- cmake_report cmConfigure.h${_tmp} "#define CMAKE_NO_ANSI_FOR_SCOPE 1"
- echo "${cmake_cxx_compiler} does not have ANSI for scoping"
-fi
-
# When bootstrapping on MinGW with MSYS we must convert the source
# directory to a windows path.
if ${cmake_system_mingw}; then
- cmake_root_dir=`cd "${cmake_source_dir}"; pwd -W`
+ CMAKE_BOOTSTRAP_SOURCE_DIR=`cd "${cmake_source_dir}"; pwd -W`
+ CMAKE_BOOTSTRAP_BINARY_DIR=`cd "${cmake_binary_dir}"; pwd -W`
else
- cmake_root_dir="${cmake_source_dir}"
+ CMAKE_BOOTSTRAP_SOURCE_DIR="${cmake_source_dir}"
+ CMAKE_BOOTSTRAP_BINARY_DIR="${cmake_binary_dir}"
fi
# Write CMake version
cmake_report cmVersionConfig.h${_tmp} "#define CMake_VERSION_MAJOR ${cmake_version_major}"
cmake_report cmVersionConfig.h${_tmp} "#define CMake_VERSION_MINOR ${cmake_version_minor}"
cmake_report cmVersionConfig.h${_tmp} "#define CMake_VERSION_PATCH ${cmake_version_patch}"
-cmake_report cmVersionConfig.h${_tmp} "#define CMake_VERSION_TWEAK ${cmake_version_tweak}"
cmake_report cmVersionConfig.h${_tmp} "#define CMake_VERSION \"${cmake_version}\""
-cmake_report cmConfigure.h${_tmp} "#define CMAKE_ROOT_DIR \"${cmake_root_dir}\""
-cmake_report cmConfigure.h${_tmp} "#define CMAKE_DATA_DIR \"/${cmake_data_dir}\""
+cmake_report cmConfigure.h${_tmp} "#define CMAKE_BOOTSTRAP_SOURCE_DIR \"${CMAKE_BOOTSTRAP_SOURCE_DIR}\""
+cmake_report cmConfigure.h${_tmp} "#define CMAKE_BOOTSTRAP_BINARY_DIR \"${CMAKE_BOOTSTRAP_BINARY_DIR}\""
+cmake_report cmConfigure.h${_tmp} "#define CMAKE_DATA_DIR \"/bootstrap-not-insalled\""
cmake_report cmConfigure.h${_tmp} "#define CMAKE_BOOTSTRAP"
# Regenerate configured headers
@@ -1430,21 +1290,7 @@ for a in ${KWSYS_FILES}; do
"${cmake_bootstrap_dir}/cmsys/${a}" KWSYS_NAMESPACE cmsys
done
-for a in ${KWSYS_IOS_FILES}; do
- cmake_replace_string "${cmake_source_dir}/Source/kwsys/kwsys_ios_${a}.h.in" \
- "${cmake_bootstrap_dir}/cmsys/ios/${a}" KWSYS_NAMESPACE cmsys
-done
-
-cmake_replace_string "${cmake_source_dir}/Source/kwsys/kwsys_stl.hxx.in" \
- "${cmake_bootstrap_dir}/cmsys/stl/stl.hxx_a" KWSYS_STL_HEADER_EXTRA ""
-
-cmake_replace_string "${cmake_bootstrap_dir}/cmsys/stl/stl.hxx_a" \
- "${cmake_bootstrap_dir}/cmsys/stl/stl.hxx_b" KWSYS_NAMESPACE cmsys
-
-for a in string vector set map algorithm; do
- cmake_replace_string "${cmake_bootstrap_dir}/cmsys/stl/stl.hxx_b" \
- "${cmake_bootstrap_dir}/cmsys/stl/${a}" KWSYS_STL_HEADER ${a}
-done
+cmake_generate_file "${cmake_bootstrap_dir}/cmThirdParty.h" ""
# Generate Makefile
dep="cmConfigure.h cmsys/*.hxx cmsys/*.h `cmake_escape \"${cmake_source_dir}\"`/Source/*.h"
@@ -1476,6 +1322,9 @@ if [ "x${cmake_cxx_flags}" != "x" ]; then
fi
cmake_c_flags_String="-DKWSYS_STRING_C"
+if ${cmake_system_mingw}; then
+ cmake_c_flags_EncodingC="-DKWSYS_ENCODING_DEFAULT_CODEPAGE=CP_ACP"
+fi
cmake_cxx_flags_SystemTools="
-DKWSYS_CXX_HAS_SETENV=${KWSYS_CXX_HAS_SETENV}
-DKWSYS_CXX_HAS_UNSETENV=${KWSYS_CXX_HAS_UNSETENV}
@@ -1484,9 +1333,9 @@ cmake_cxx_flags_SystemTools="
-DKWSYS_CXX_HAS_UTIMES=${KWSYS_CXX_HAS_UTIMES}
"
cmake_c_flags="${cmake_c_flags}-I`cmake_escape \"${cmake_bootstrap_dir}\"` -I`cmake_escape \"${cmake_source_dir}/Source\"` \
- -I`cmake_escape \"${cmake_bootstrap_dir}\"`"
+ -I`cmake_escape \"${cmake_source_dir}/Utilities\"`"
cmake_cxx_flags="${cmake_cxx_flags} -I`cmake_escape \"${cmake_bootstrap_dir}\"` -I`cmake_escape \"${cmake_source_dir}/Source\"` \
- -I`cmake_escape \"${cmake_bootstrap_dir}\"`"
+ -I`cmake_escape \"${cmake_source_dir}/Utilities\"`"
echo "cmake: ${objs}" > "${cmake_bootstrap_dir}/Makefile"
echo " ${cmake_cxx_compiler} ${cmake_ld_flags} ${cmake_cxx_flags} ${objs} -o cmake" >> "${cmake_bootstrap_dir}/Makefile"
for a in ${CMAKE_CXX_SOURCES}; do
@@ -1526,6 +1375,7 @@ set (CMAKE_INSTALL_PREFIX "'"${cmake_prefix_dir}"'" CACHE PATH "Install path pre
set (CMAKE_DOC_DIR "'"${cmake_doc_dir}"'" CACHE PATH "Install location for documentation (relative to prefix)." FORCE)
set (CMAKE_MAN_DIR "'"${cmake_man_dir}"'" CACHE PATH "Install location for man pages (relative to prefix)." FORCE)
set (CMAKE_DATA_DIR "'"${cmake_data_dir}"'" CACHE PATH "Install location for data (relative to prefix)." FORCE)
+set (CMAKE_XDGDATA_DIR "'"${cmake_xdgdata_dir}"'" CACHE PATH "Install location for XDG specific files (relative to prefix)." FORCE)
' > "${cmake_bootstrap_dir}/InitialCacheFlags.cmake"
# Add configuration settings given as command-line options.
@@ -1539,6 +1389,31 @@ if [ "x${cmake_bootstrap_qt_qmake}" != "x" ]; then
set (QT_QMAKE_EXECUTABLE "'"${cmake_bootstrap_qt_qmake}"'" CACHE FILEPATH "Location of Qt qmake" FORCE)
' >> "${cmake_bootstrap_dir}/InitialCacheFlags.cmake"
fi
+if [ "x${cmake_sphinx_man}" != "x" ]; then
+ echo '
+set (SPHINX_MAN "'"${cmake_sphinx_man}"'" CACHE BOOL "Build man pages with Sphinx" FORCE)
+' >> "${cmake_bootstrap_dir}/InitialCacheFlags.cmake"
+fi
+if [ "x${cmake_sphinx_html}" != "x" ]; then
+ echo '
+set (SPHINX_HTML "'"${cmake_sphinx_html}"'" CACHE BOOL "Build html help with Sphinx" FORCE)
+' >> "${cmake_bootstrap_dir}/InitialCacheFlags.cmake"
+fi
+if [ "x${cmake_sphinx_qthelp}" != "x" ]; then
+ echo '
+set (SPHINX_QTHELP "'"${cmake_sphinx_qthelp}"'" CACHE BOOL "Build qch help with Sphinx" FORCE)
+' >> "${cmake_bootstrap_dir}/InitialCacheFlags.cmake"
+fi
+if [ "x${cmake_sphinx_build}" != "x" ]; then
+ echo '
+set (SPHINX_EXECUTABLE "'"${cmake_sphinx_build}"'" CACHE FILEPATH "Location of Qt sphinx-build" FORCE)
+' >> "${cmake_bootstrap_dir}/InitialCacheFlags.cmake"
+fi
+if [ "x${cmake_sphinx_flags}" != "x" ]; then
+ echo '
+set (SPHINX_FLAGS [==['"${cmake_sphinx_flags}"']==] CACHE STRING "Flags to pass to sphinx-build" FORCE)
+' >> "${cmake_bootstrap_dir}/InitialCacheFlags.cmake"
+fi
# Add user-specified settings. Handle relative-path case for
# specification of cmake_init_file.
diff --git a/cmake_uninstall.cmake.in b/cmake_uninstall.cmake.in
index 7cd7fc1c9..d81f62a21 100644
--- a/cmake_uninstall.cmake.in
+++ b/cmake_uninstall.cmake.in
@@ -3,7 +3,7 @@ if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
endif()
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
-string(REGEX REPLACE "\n" ";" files "${files}")
+string(REPLACE "\n" ";" files "${files}")
foreach(file ${files})
message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
if(EXISTS "$ENV{DESTDIR}${file}")